Skip to content

fix(editor): stop treating a trailing comment as a second SQL statement - #1900

Merged
datlechin merged 2 commits into
mainfrom
fix/comment-only-statements
Jul 17, 2026
Merged

fix(editor): stop treating a trailing comment as a second SQL statement#1900
datlechin merged 2 commits into
mainfrom
fix/comment-only-statements

Conversation

@datlechin

Copy link
Copy Markdown
Member

Fixes #1895.

Root cause

SQLStatementScanner.allStatements keeps every segment that is non-empty after a whitespace trim, and comment text trims to a non-empty string. The scanner tracks comments to find the right split points but never asks whether a segment contains an executable token. That misfires in three places, not just the trailing one the issue named:

  • SELECT 1; -- note splits into two statements, the run takes the multi-statement path, and the comment is sent to the server, producing the spurious "Statement 2/2 failed" error.
  • SELECT 1; /* x */; SELECT 2 produces three statements.
  • A buffer that is entirely one comment with no semicolon produces one statement via a fast path that bypassed the state machine entirely.

QueryClassifier.isMultiStatement counts the same way, so the execution gate and the AI chat and MCP tools rejected SELECT 1; -- note as "multi-statement" before it even ran.

Context: TablePlus fixed this exact bug in 2019 (TablePlus#485), DBeaver in 24.0.4 (dbeaver#26416), DataGrip never had it. ClickHouse is the one server that hard-errors on comment-only text (code 62), and its own clickhouse-client drops trailing comments client-side.

Fix

The SQLFileParser approach (hasStatementContent) transplanted into the scanner's existing state machine: one boolean tracked in the same character loop, passed as a third closure parameter. allStatements and allStatementsPreservingSemicolons skip segments without content; the cursor APIs ignore the flag, so autocomplete still sees raw comment segments and keeps suppressing suggestions inside comments.

  • /*! versioned comments count as content in every dialect, so MySQL dump statements like /*!40101 SET ... */; still execute.
  • The no-semicolon fast path is removed so a comment-only buffer goes through the same loop; the trailing branch emits byte-identical text and offset for that case.
  • The content marker is an else of the semicolon check, so a boundary semicolon never marks the segment it closes.
  • In-statement comments are untouched. Only whole segments that are pure comment and whitespace are dropped.

Running a comment-only buffer, selection, or cursor-in-comment statement is now a no-op through the pre-existing guard !statements.isEmpty checks at every call site, matching DataGrip and DBeaver. No production file changes besides the scanner.

CI enablement (second commit)

The new cursor-API regression tests live in SQLStatementScannerLocatedTests, which was on the CI quarantine list since the test gate landed (#1481). It was benched because of one broken precondition: largeInput generates 9,889 characters and asserts > 10_000, failing since March while quarantine hid it. The second commit bumps the generated input to 300 statements (about 14,800 characters) and removes the suite from the quarantine list. All 17 tests in the suite pass.

Testing

  • 12 new scanner cases (trailing line and block comments, middle comment-only segment, comment-only whole input, mixed multi-line, unclosed trailing block comment, bare trailing dashes, versioned comments kept per dialect, in-statement comments preserved, ;; still dropped, semicolon-preserving variant).
  • 2 cursor-API regression guards proving the raw comment segment still reaches autocomplete.
  • New QueryClassifier.isMultiStatement suite and an ExecutionGateTests case proving the gate no longer denies trailing-comment SQL.
  • Full runs of the four affected suites pass via xcodebuild test; swiftlint lint --strict reports nothing new on changed files.

Follow-ups deliberately not in this PR: the scanner does not recognize # or // line comments (a trailing # note on ClickHouse can still error, a pre-existing splitting gap), and MCPConnectionBridge passes a trailing comment through to single-exec drivers.

@datlechin
datlechin merged commit 11b523f into main Jul 17, 2026
2 of 3 checks passed
@datlechin
datlechin deleted the fix/comment-only-statements branch July 17, 2026 05:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

SQLStatementScanner turns a trailing comment after the last semicolon into a phantom statement

1 participant