Skip to content

fix(splitter): do not split EXPLAIN from the explained statement#759

Merged
psteinroe merged 1 commit into
supabase-community:mainfrom
amogiska:fix-explain-statement-splitting
Jun 11, 2026
Merged

fix(splitter): do not split EXPLAIN from the explained statement#759
psteinroe merged 1 commit into
supabase-community:mainfrom
amogiska:fix-explain-statement-splitting

Conversation

@amogiska

@amogiska amogiska commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

What kind of change does this PR introduce?

Bug fix.

What is the current behavior?

The statement splitter treats the statement after an EXPLAIN prefix as a new statement, so EXPLAIN SELECT 1 is split into two statements (EXPLAIN + SELECT 1):

splitStatements('EXPLAIN SELECT 1')
// => [{ sql: 'EXPLAIN' }, { sql: 'SELECT 1' }]

Downstream, lint() then reports valid SQL as invalid — the bare EXPLAIN fragment fails to parse with Invalid statement: syntax error at end of input — and consumers that execute the split statements send a broken bare EXPLAIN to Postgres. All EXPLAIN forms are affected (EXPLAIN ANALYZE, EXPLAIN (ANALYZE, BUFFERS), etc.).

This is the same mis-split class previously fixed for UNION (#321) and GRANT (#417).

What is the new behavior?

EXPLAIN is handled as a statement prefix: a dedicated explain() splitter function consumes the prefix — the parenthesized option list or the legacy [ANALYZE | ANALYSE] [VERBOSE] modifiers — and then delegates to the splitter function of the explained statement, mirroring how statement() dispatches. Covered forms include EXPLAIN SELECT/INSERT/UPDATE/DELETE, EXPLAIN WITH ... SELECT, EXPLAIN CREATE TABLE AS, EXPLAIN VALUES, and multi-statement sources (EXPLAIN SELECT 1; SELECT 2 splits at the semicolon).

EXPLAIN_KW is deliberately not added to STATEMENT_START_TOKENS: explain is an unreserved keyword and remains valid as an identifier mid-statement (e.g. SELECT explain FROM t), which a break-on-EXPLAIN rule in unknown() would mis-split. A regression test covers this.

Additional context

Found while integrating @postgres-language-server/wasm for SQL editing/execution at ClickHouse, where this surfaced both as lint false positives and as broken EXPLAIN execution.

@amogiska amogiska marked this pull request as ready for review June 10, 2026 18:27
@psteinroe

Copy link
Copy Markdown
Collaborator

thanks for the contribution! can you share more about your use case at clickhouse? happy to make the language server work for you!

@psteinroe psteinroe merged commit 30b9684 into supabase-community:main Jun 11, 2026
9 checks passed
@lneves12

lneves12 commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

@psteinroe hey! Clickhouse released recently a managed Postgres offering. We are using it inside our SQL Editor. Thank you for the great work so far!

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.

3 participants