Skip to content

Disambiguate SETTINGS placement around paren-wrapped set-op legs#3

Merged
odemkovych merged 2 commits into
mainfrom
feat/paren-wrapped-select-query
Jun 16, 2026
Merged

Disambiguate SETTINGS placement around paren-wrapped set-op legs#3
odemkovych merged 2 commits into
mainfrom
feat/paren-wrapped-select-query

Conversation

@odemkovych

Copy link
Copy Markdown

Track paren-wrapping on SelectQuery directly so the four placements of
SETTINGS around a paren-bounded set-op leg become distinct, round-trippable
AST shapes. SELECT 1 UNION ALL (SELECT 2 SETTINGS x=1) (per-leg) and
SELECT 1 UNION ALL (SELECT 2) SETTINGS x=1 (chain-level on the leg)
previously collapsed to byte-identical ASTs; chain-level SETTINGS on a
paren-wrapped chain (e.g. (SELECT 1 UNION ALL SELECT 2) SETTINGS x=1)
failed to parse at all. After this change each form parses to a distinct
shape and re-formats to itself byte-for-byte.

SelectQuery gains two additive fields — HasParen bool and
OuterSettings *SettingsClause — populated by parseSelectQuery when it
itself consumes the wrapping parens. The dispatcher now routes a leading
( to parseSelectQuery so top-level wrapped chains parse end-to-end.
parseCTEStmt is updated to consume the CTE-body parens at its own layer
(mirroring parseSubQuery), so inner CTE SelectQueries keep HasParen=false
and every pre-existing format/beautify golden stays byte-identical.

Test suite gains TestParser_With_ChainSettingsDisambiguation plus four
new fixtures (output/format/beautify goldens each) covering the four
placements. JSON goldens regenerate uniformly with two added lines per
SelectQuery rendering; format and beautify goldens are unchanged on
every pre-existing fixture.

@odemkovych odemkovych self-assigned this Jun 16, 2026
Track paren-wrapping on SelectQuery directly so the four placements of
SETTINGS around a paren-bounded set-op leg become distinct, round-trippable
AST shapes. SELECT 1 UNION ALL (SELECT 2 SETTINGS x=1) (per-leg) and
SELECT 1 UNION ALL (SELECT 2) SETTINGS x=1 (chain-level on the leg)
previously collapsed to byte-identical ASTs; chain-level SETTINGS on a
paren-wrapped chain (e.g. (SELECT 1 UNION ALL SELECT 2) SETTINGS x=1)
failed to parse at all. After this change each form parses to a distinct
shape and re-formats to itself byte-for-byte.

SelectQuery gains two additive fields — HasParen bool and
OuterSettings *SettingsClause — populated by parseSelectQuery when it
itself consumes the wrapping parens. The dispatcher now routes a leading
`(` to parseSelectQuery so top-level wrapped chains parse end-to-end.
parseCTEStmt is updated to consume the CTE-body parens at its own layer
(mirroring parseSubQuery), so inner CTE SelectQueries keep HasParen=false
and every pre-existing format/beautify golden stays byte-identical.

Test suite gains TestParser_With_ChainSettingsDisambiguation plus four
new fixtures (output/format/beautify goldens each) covering the four
placements. JSON goldens regenerate uniformly with two added lines per
SelectQuery rendering; format and beautify goldens are unchanged on
every pre-existing fixture.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@odemkovych odemkovych force-pushed the feat/paren-wrapped-select-query branch from 45b475a to 4e145f7 Compare June 16, 2026 15:41
@odemkovych odemkovych merged commit 50bdd90 into main Jun 16, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

1 participant