-
Notifications
You must be signed in to change notification settings - Fork 3.2k
feat(whaleflow): add trace store schema migration #2816
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -267,7 +267,7 @@ impl StateStore { | |||||||||||||||||||||
|
|
||||||||||||||||||||||
| fn init_schema(&self) -> Result<()> { | ||||||||||||||||||||||
| let conn = self.conn()?; | ||||||||||||||||||||||
| let user_version: u32 = conn.query_row("PRAGMA user_version;", [], |row| row.get(0))?; | ||||||||||||||||||||||
| let mut user_version: u32 = conn.query_row("PRAGMA user_version;", [], |row| row.get(0))?; | ||||||||||||||||||||||
| if user_version == 0 { | ||||||||||||||||||||||
| conn.execute_batch( | ||||||||||||||||||||||
| r#" | ||||||||||||||||||||||
|
|
@@ -376,6 +376,104 @@ impl StateStore { | |||||||||||||||||||||
| "#, | ||||||||||||||||||||||
| ) | ||||||||||||||||||||||
| .context("failed to initialize thread schema")?; | ||||||||||||||||||||||
| user_version = 1; | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| if user_version < 2 { | ||||||||||||||||||||||
| conn.execute_batch( | ||||||||||||||||||||||
| r#" | ||||||||||||||||||||||
| BEGIN; | ||||||||||||||||||||||
| CREATE TABLE IF NOT EXISTS workflow_runs ( | ||||||||||||||||||||||
| id TEXT PRIMARY KEY, | ||||||||||||||||||||||
| workflow_id TEXT NOT NULL, | ||||||||||||||||||||||
| goal TEXT NOT NULL, | ||||||||||||||||||||||
| status TEXT NOT NULL, | ||||||||||||||||||||||
| input_hash TEXT, | ||||||||||||||||||||||
| started_at INTEGER NOT NULL, | ||||||||||||||||||||||
| completed_at INTEGER, | ||||||||||||||||||||||
| metadata_json TEXT NOT NULL DEFAULT '{}' | ||||||||||||||||||||||
| ); | ||||||||||||||||||||||
| CREATE INDEX IF NOT EXISTS idx_workflow_runs_status_started_at | ||||||||||||||||||||||
| ON workflow_runs(status, started_at DESC); | ||||||||||||||||||||||
| CREATE INDEX IF NOT EXISTS idx_workflow_runs_workflow_started_at | ||||||||||||||||||||||
| ON workflow_runs(workflow_id, started_at DESC); | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| CREATE TABLE IF NOT EXISTS branch_runs ( | ||||||||||||||||||||||
| id TEXT PRIMARY KEY, | ||||||||||||||||||||||
| workflow_run_id TEXT NOT NULL, | ||||||||||||||||||||||
| branch_id TEXT NOT NULL, | ||||||||||||||||||||||
| node_id TEXT NOT NULL, | ||||||||||||||||||||||
| status TEXT NOT NULL, | ||||||||||||||||||||||
| started_at INTEGER NOT NULL, | ||||||||||||||||||||||
| completed_at INTEGER, | ||||||||||||||||||||||
| result_json TEXT NOT NULL DEFAULT '{}', | ||||||||||||||||||||||
| FOREIGN KEY(workflow_run_id) REFERENCES workflow_runs(id) ON DELETE CASCADE | ||||||||||||||||||||||
| ); | ||||||||||||||||||||||
| CREATE INDEX IF NOT EXISTS idx_branch_runs_workflow_run_id | ||||||||||||||||||||||
| ON branch_runs(workflow_run_id); | ||||||||||||||||||||||
| CREATE INDEX IF NOT EXISTS idx_branch_runs_branch_id | ||||||||||||||||||||||
| ON branch_runs(branch_id); | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| CREATE TABLE IF NOT EXISTS leaf_runs ( | ||||||||||||||||||||||
| id TEXT PRIMARY KEY, | ||||||||||||||||||||||
| workflow_run_id TEXT NOT NULL, | ||||||||||||||||||||||
| branch_run_id TEXT, | ||||||||||||||||||||||
| leaf_id TEXT NOT NULL, | ||||||||||||||||||||||
| task_id TEXT NOT NULL, | ||||||||||||||||||||||
| input_hash TEXT, | ||||||||||||||||||||||
| status TEXT NOT NULL, | ||||||||||||||||||||||
| output_json TEXT NOT NULL DEFAULT '{}', | ||||||||||||||||||||||
| artifacts_json TEXT NOT NULL DEFAULT '[]', | ||||||||||||||||||||||
| started_at INTEGER NOT NULL, | ||||||||||||||||||||||
| completed_at INTEGER, | ||||||||||||||||||||||
| FOREIGN KEY(workflow_run_id) REFERENCES workflow_runs(id) ON DELETE CASCADE, | ||||||||||||||||||||||
| FOREIGN KEY(branch_run_id) REFERENCES branch_runs(id) ON DELETE SET NULL | ||||||||||||||||||||||
| ); | ||||||||||||||||||||||
| CREATE INDEX IF NOT EXISTS idx_leaf_runs_workflow_run_id | ||||||||||||||||||||||
| ON leaf_runs(workflow_run_id); | ||||||||||||||||||||||
| CREATE INDEX IF NOT EXISTS idx_leaf_runs_replay_lookup | ||||||||||||||||||||||
| ON leaf_runs(workflow_run_id, leaf_id, input_hash); | ||||||||||||||||||||||
|
Comment on lines
+431
to
+434
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The index Additionally, there is a missing index on the foreign key
Suggested change
|
||||||||||||||||||||||
|
|
||||||||||||||||||||||
| CREATE TABLE IF NOT EXISTS control_node_runs ( | ||||||||||||||||||||||
| id TEXT PRIMARY KEY, | ||||||||||||||||||||||
| workflow_run_id TEXT NOT NULL, | ||||||||||||||||||||||
| node_id TEXT NOT NULL, | ||||||||||||||||||||||
| kind TEXT NOT NULL, | ||||||||||||||||||||||
| status TEXT NOT NULL, | ||||||||||||||||||||||
| selected_children_json TEXT NOT NULL DEFAULT '[]', | ||||||||||||||||||||||
| result_json TEXT NOT NULL DEFAULT '{}', | ||||||||||||||||||||||
| started_at INTEGER NOT NULL, | ||||||||||||||||||||||
| completed_at INTEGER, | ||||||||||||||||||||||
| FOREIGN KEY(workflow_run_id) REFERENCES workflow_runs(id) ON DELETE CASCADE | ||||||||||||||||||||||
| ); | ||||||||||||||||||||||
| CREATE INDEX IF NOT EXISTS idx_control_node_runs_workflow_run_id | ||||||||||||||||||||||
| ON control_node_runs(workflow_run_id); | ||||||||||||||||||||||
| CREATE INDEX IF NOT EXISTS idx_control_node_runs_node_id | ||||||||||||||||||||||
| ON control_node_runs(node_id); | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| CREATE TABLE IF NOT EXISTS teacher_candidates ( | ||||||||||||||||||||||
| id TEXT PRIMARY KEY, | ||||||||||||||||||||||
| workflow_run_id TEXT NOT NULL, | ||||||||||||||||||||||
| control_node_run_id TEXT NOT NULL, | ||||||||||||||||||||||
| candidate_id TEXT NOT NULL, | ||||||||||||||||||||||
| branch_run_id TEXT, | ||||||||||||||||||||||
| score REAL, | ||||||||||||||||||||||
| passed INTEGER, | ||||||||||||||||||||||
| rationale_json TEXT NOT NULL DEFAULT '{}', | ||||||||||||||||||||||
| created_at INTEGER NOT NULL, | ||||||||||||||||||||||
| FOREIGN KEY(workflow_run_id) REFERENCES workflow_runs(id) ON DELETE CASCADE, | ||||||||||||||||||||||
| FOREIGN KEY(control_node_run_id) REFERENCES control_node_runs(id) ON DELETE CASCADE, | ||||||||||||||||||||||
| FOREIGN KEY(branch_run_id) REFERENCES branch_runs(id) ON DELETE SET NULL | ||||||||||||||||||||||
| ); | ||||||||||||||||||||||
| CREATE INDEX IF NOT EXISTS idx_teacher_candidates_workflow_run_id | ||||||||||||||||||||||
| ON teacher_candidates(workflow_run_id); | ||||||||||||||||||||||
| CREATE INDEX IF NOT EXISTS idx_teacher_candidates_control_node_run_id | ||||||||||||||||||||||
| ON teacher_candidates(control_node_run_id); | ||||||||||||||||||||||
|
Comment on lines
+467
to
+470
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There is a missing index on the foreign key
Suggested change
|
||||||||||||||||||||||
|
|
||||||||||||||||||||||
| PRAGMA user_version = 2; | ||||||||||||||||||||||
| COMMIT; | ||||||||||||||||||||||
| "#, | ||||||||||||||||||||||
| ) | ||||||||||||||||||||||
| .context("failed to initialize workflow trace schema")?; | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
| Ok(()) | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
SQLite does not enforce foreign key constraints by default. To ensure that
ON DELETE CASCADEandON DELETE SET NULLactions are actually executed for these new tables (and existing ones),PRAGMA foreign_keys = ON;must be enabled on every database connection opened by the application (typically inside theconn()helper). Without this, orphaned rows will accumulate silently when parent records are deleted.