Context
EXPLAIN ANALYZE in SQLPilot executes the underlying query to gather actual cost/timing data.
Problem
src/stores/resultStore.ts:118-136 (executeExplainAnalyze) runs api.executeQuery(connectionId, EXPLAIN ANALYZE ${sql}, database). EXPLAIN ANALYZE actually executes the query (it's EXPLAIN ANALYZE SELECT plus actual execution, returning actual time=…, rows=…, loops=…). For EXPLAIN ANALYZE DELETE FROM users WHERE 1=1, the DELETE runs. EXPLAIN (non-ANALYZE) is safe — only plans. But the UI doesn't distinguish; user clicks one button (Explain) and a dropdown (QueryToolbar.tsx:103-111) selects ANALYZE. No production-safety confirm dialog — DESTRUCTIVE_PATTERN is checked only by resultStore.executeQuery, not by executeExplain/executeExplainAnalyze. No read_only enforcement (admin F1 pattern). The user opens a query tab on production, types DELETE FROM important_table WHERE created_at < '2020-01-01', clicks EXPLAIN ANALYZE — table is wiped.
Files
- src/stores/resultStore.ts:118-136 (executeExplainAnalyze)
- src/components/editor/QueryToolbar.tsx:103-111 (dropdown)
Repro
- Connect to production DB
- Open query tab, type
DELETE FROM users WHERE 1=1
- Click Explain → EXPLAIN ANALYZE
- The DELETE runs against the production database without confirmation
Expected
Clicking EXPLAIN ANALYZE on DELETE FROM users WHERE 1=1 shows a warning "EXPLAIN ANALYZE executes the query — falling back to EXPLAIN" and only plans, doesn't delete. Production connection always confirms. Read-only profile rejects.
Proposed fix
(1) Detect destructive SQL (UPDATE|INSERT|DELETE|REPLACE|TRUNCATE|DROP|ALTER — extended beyond editor's current DESTRUCTIVE_PATTERN) in executeExplainAnalyze. If detected, refuse to run ANALYZE and fall back to plain EXPLAIN, with a warning. (2) Apply production-safety check (isProductionConnection + confirm dialog) regardless of destructive pattern. (3) Apply read_only profile check via a new explain_query Tauri command (F11). (4) Update the QueryToolbar dropdown label to "Run EXPLAIN ANALYZE (executes the query)" so the user knows the cost. Scope: M.
Acceptance
Clicking EXPLAIN ANALYZE on DELETE FROM users WHERE 1=1 shows a warning "EXPLAIN ANALYZE executes the query — falling back to EXPLAIN" and only plans, doesn't delete. Production connection always confirms. Read-only profile rejects.
Needs human verify
yes
Doc drift
partial — DESIGN_REQUIREMENTS FR-2.2.5 doesn't address EXPLAIN ANALYZE safety
Context
EXPLAIN ANALYZE in SQLPilot executes the underlying query to gather actual cost/timing data.
Problem
src/stores/resultStore.ts:118-136 (executeExplainAnalyze) runs
api.executeQuery(connectionId,EXPLAIN ANALYZE ${sql}, database). EXPLAIN ANALYZE actually executes the query (it's EXPLAIN ANALYZE SELECT plus actual execution, returning actual time=…, rows=…, loops=…). ForEXPLAIN ANALYZE DELETE FROM users WHERE 1=1, the DELETE runs. EXPLAIN (non-ANALYZE) is safe — only plans. But the UI doesn't distinguish; user clicks one button (Explain) and a dropdown (QueryToolbar.tsx:103-111) selects ANALYZE. No production-safety confirm dialog — DESTRUCTIVE_PATTERN is checked only by resultStore.executeQuery, not by executeExplain/executeExplainAnalyze. No read_only enforcement (admin F1 pattern). The user opens a query tab on production, typesDELETE FROM important_table WHERE created_at < '2020-01-01', clicks EXPLAIN ANALYZE — table is wiped.Files
Repro
DELETE FROM users WHERE 1=1Expected
Clicking EXPLAIN ANALYZE on
DELETE FROM users WHERE 1=1shows a warning "EXPLAIN ANALYZE executes the query — falling back to EXPLAIN" and only plans, doesn't delete. Production connection always confirms. Read-only profile rejects.Proposed fix
(1) Detect destructive SQL (
UPDATE|INSERT|DELETE|REPLACE|TRUNCATE|DROP|ALTER— extended beyond editor's current DESTRUCTIVE_PATTERN) in executeExplainAnalyze. If detected, refuse to run ANALYZE and fall back to plain EXPLAIN, with a warning. (2) Apply production-safety check (isProductionConnection + confirm dialog) regardless of destructive pattern. (3) Apply read_only profile check via a new explain_query Tauri command (F11). (4) Update the QueryToolbar dropdown label to "Run EXPLAIN ANALYZE (executes the query)" so the user knows the cost. Scope: M.Acceptance
Clicking EXPLAIN ANALYZE on
DELETE FROM users WHERE 1=1shows a warning "EXPLAIN ANALYZE executes the query — falling back to EXPLAIN" and only plans, doesn't delete. Production connection always confirms. Read-only profile rejects.Needs human verify
yes
Doc drift
partial — DESIGN_REQUIREMENTS FR-2.2.5 doesn't address EXPLAIN ANALYZE safety