{"record":{"id":"745ebdc5f8615fdb","repo":"tursodatabase/turso","slug":"query-was-interrupted","errorCode":null,"errorMessage":"query was interrupted","messagePattern":"query was interrupted","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"perf/join-benchmark/main.rs","lineNumber":172,"sourceCode":"                .with_context(|| format!(\"read query file {}\", path.display()))?,\n        });\n    }\n    Ok(queries)\n}\n\nfn set_timeout(statement: &mut turso_core::Statement, timeout_seconds: u64) {\n    let timeout = (timeout_seconds != 0).then(|| Duration::from_secs(timeout_seconds));\n    statement.set_query_timeout_override(Some(timeout));\n}\n\nfn execute(database: &Database, statement: &mut turso_core::Statement) -> Result<u64> {\n    let mut result_rows = 0_u64;\n    loop {\n        match statement.step()? {\n            StepResult::Row => result_rows = result_rows.saturating_add(1),\n            StepResult::IO | StepResult::Yield | StepResult::Sleep { .. } => database.io.step()?,\n            StepResult::Done => return Ok(result_rows),\n            StepResult::Interrupt => bail!(\"query was interrupted\"),\n            StepResult::Busy => bail!(\"database was busy\"),\n        }\n    }\n}\n\nfn print_plan(connection: &Arc<turso_core::Connection>, query: &Query) -> Result<()> {\n    let sql = format!(\"EXPLAIN QUERY PLAN FORMAT=JSON {}\", query.sql);\n    let rows = connection.prepare(sql)?.run_collect_rows()?;\n    let Some(Value::Text(plan)) = rows.first().and_then(|row| row.first()) else {\n        bail!(\"query {} did not return a JSON plan\", query.name);\n    };\n    let plan: JsonValue = serde_json::from_str(plan.as_str())?;\n    println!(\"{}\", json!({\"query\": query.name, \"plan\": plan}));\n    Ok(())\n}\n","sourceCodeStart":154,"sourceCodeEnd":188,"githubUrl":"https://github.com/tursodatabase/turso/blob/492c4a71cd7c2649e7df83da1471b74f4b1c7aa9/perf/join-benchmark/main.rs#L154-L188","documentation":"The benchmark's execute loop steps a prepared statement to completion. A StepResult::Interrupt means the database was interrupted (interrupt flag set) while the query was running, so the benchmark bails out instead of returning partial row counts.","triggerScenarios":"statement.step() returns StepResult::Interrupt during a long join query — the database/connection interrupt flag was set, e.g. by a deadline/timeout mechanism or an external interrupt request.","commonSituations":"Query exceeding an imposed time limit with interrupt wired to a timer; Ctrl-C handling that flags the database; long-running join hitting a harness timeout.","solutions":["Increase the benchmark time budget/timeout so the query finishes before the interrupt fires.","Optimize or disable the offending query (check indexes/join order) to make it complete within the limit.","Check what sets the interrupt flag (signal handler, deadline task) and whether it fires prematurely.","Retry the run; if it's consistently interrupted, profile the query for a pathological plan."],"exampleFix":"// before\nlet deadline = Instant::now() + Duration::from_secs(5);\n// after\nlet deadline = Instant::now() + Duration::from_secs(60);","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"match execute(&database, &mut statement) {\n    Err(e) if e.to_string().contains(\"query was interrupted\") => {\n        eprintln!(\"query exceeded time budget: {e}\");\n        // raise budget or skip query\n    }\n    other => other?,\n}","preventionTips":["Set per-query time budgets larger than the slowest expected query","Check what wires interrupts (deadline timers, signal handlers) and test thresholds","Profile queries that are repeatedly interrupted for pathological plans"],"tags":["rust","benchmark","interrupt","query-execution"],"backgroundTag":"request-timeout","analyzedSha":"492c4a71cd7c2649e7df83da1471b74f4b1c7aa9","analyzedAt":"2026-09-13T18:13:59.796Z","contentChangedAt":"2026-09-13T18:13:59.796Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}