Skip to content

fix(sqlite): don't execute a second smuggled-in statement during column inference - #1012

Merged
ZhuchkaTriplesix merged 1 commit into
devfrom
issue/1005-sqlite-infer-columns-multi-statement
Sep 27, 2026
Merged

ZhuchkaTriplesix merged 1 commit into
devfrom
issue/1005-sqlite-infer-columns-multi-statement

Conversation

@ZhuchkaTriplesix

Copy link
Copy Markdown
Member

Summary

Fixes #1005: SqliteConnection.inferQueryColumns probes zero-row queries by wrapping the user's SQL in CREATE TEMP VIEW ... AS <sql> via Database.execute, which (unlike rawQuery) runs every statement it's given. A query like SELECT * FROM t WHERE 0; DELETE FROM t reaches this path precisely because rawQuery only ran the first statement and got zero rows back — so the probe would then execute the DELETE for real as a "harmless" side effect of inferring column names for the grid.

Fix

Added sqliteHasMultipleStatements (lib/core/database/sqlite_sql.dart), a small string/quoted-identifier/comment-aware scanner that detects a real second statement after a top-level ;. inferQueryColumns now skips the TEMP VIEW probe entirely when the text has more than one statement, falling back to the existing single-table schema lookup instead (which never executes the query text).

Test plan

  • Unit tests for sqliteHasMultipleStatements (single statement w/ trailing ;/;;, real second statement, semicolons inside strings/quoted identifiers/comments not counted)
  • Regression test reproducing the original bug: confirms a DELETE smuggled after a WHERE 0 no longer runs via inferQueryColumns. Verified this test fails without the fix (temporarily disabled the new check, confirmed the DELETE runs, restored the fix).
  • flutter analyze — no issues
  • Full flutter test suite (1865 tests) — all passing

…mn inference (Closes #1005)

SqliteConnection.inferQueryColumns probes zero-row queries by wrapping the
user's SQL in `CREATE TEMP VIEW ... AS <sql>` via Database.execute, which
(unlike rawQuery) runs every statement it's given. A query like
`SELECT * FROM t WHERE 0; DELETE FROM t` reaches this path precisely
because rawQuery only ran the first statement and got zero rows back —
so the probe would then execute the DELETE for real as a "harmless"
side effect of inferring column names.

Added sqliteHasMultipleStatements, a small scanner (string/quoted-identifier
and comment aware) that detects a real second statement after a top-level
`;`, and skip the TEMP VIEW probe entirely when it's true, falling back to
the existing single-table schema lookup instead.
@github-actions github-actions Bot added bug Something isn't working sqlite SQLite database driver and workspace data-grid Interactive data grid, cell editor, filtering, groupings labels Sep 27, 2026
@ZhuchkaTriplesix
ZhuchkaTriplesix merged commit 20381f2 into dev Sep 27, 2026
4 checks passed
@ZhuchkaTriplesix
ZhuchkaTriplesix deleted the issue/1005-sqlite-infer-columns-multi-statement branch September 28, 2026 08:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working data-grid Interactive data grid, cell editor, filtering, groupings sqlite SQLite database driver and workspace

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant