Skip to content

fix(pg/parser): BYT-9315 — parenthesized multi-join in pg_get_viewdef output [stack 1/3]#105

Merged
rebelice merged 2 commits into
mainfrom
junyi/byt-9315-fix-postgresql-grammar-to-accept-multi-join-syntax-in-sql
Apr 22, 2026
Merged

fix(pg/parser): BYT-9315 — parenthesized multi-join in pg_get_viewdef output [stack 1/3]#105
rebelice merged 2 commits into
mainfrom
junyi/byt-9315-fix-postgresql-grammar-to-accept-multi-join-syntax-in-sql

Conversation

@rebelice
Copy link
Copy Markdown
Collaborator

Summary

Fixes BYT-9315: a customer's view had a pg_get_viewdef() output of shape SELECT * FROM ((a JOIN b ON TRUE) JOIN c ON TRUE) which omni parser rejected. The failure cascaded through catalog.Exec and killed SQL review for every statement against the instance (originally surfaced as BYT-9308).

Root cause: parseParenTableRef used a 1-token peek that couldn't distinguish ((SELECT ...)) (nested subquery) from ((a JOIN b)) (nested joined_table) — both start with ((.

Three structural fixes in pg/parser/select.go:

  • parenBeginsSubquery (T3 snapshot scan) — walks the matched paren block, classifies outer as subquery vs joined_table by depth-1 content + set-op / JOIN continuation after nested close.
  • parseJoinedTable (T6/T7 hybrid) — separates "parse joined_table inside '(' ... ')'" from generic parseTableRef, enforces JoinExpr root.
  • parseSelectWithParens (T5 left-factoring) — removed cur == '(' { recurse } short-circuit, lets parseSelectClause's set-op precedence handle nested paren operands.

Net effect: +17 PG official regress statements pass (0 new failures). FROM-clause ( parity with PG 17 across all dispatch shapes audited.

This is the foundation PR. Followed by:

  • [stack 2/3] pg-paren-dispatch starmap — oracle harness + audit + CI fence
  • [stack 3/3] KB-1/2/3 closure + Class A systematic silent-accept cleanup

Test plan

  • `go test ./pg/parser/ -count=1` green
  • `go test ./pg/pgregress/ -count=1` green (+17 fixed)
  • New `pg/parser/paren_multi_join_test.go` with 4 test functions, 18 cases including the customer's exact SQL
  • AST shape verified: `((a JOIN b) JOIN c)` produces left-nested JoinExpr matching PG
  • No new dependencies, no behavior change to other parser paths

🤖 Generated with Claude Code

rebelice and others added 2 commits April 21, 2026 15:06
…bquery

Root cause: parseParenTableRef's 1-token peek couldn't distinguish
'((SELECT ...))' nested subquery from '((a JOIN b))' nested joined_table.
Code routed all '((' to subquery, breaking pg_get_viewdef() output like
'SELECT * FROM ((a JOIN b ON TRUE) JOIN c ON TRUE)' and cascading
through catalog.Exec → SQL review dead for the whole instance.

Three changes:

1. parenBeginsSubquery (T3 snapshot scan) — walks the matched paren
   block, classifies outer as subquery vs joined_table based on
   depth-1 content + set-op / JOIN continuation after nested close.
2. parseJoinedTable (T6/T7 hybrid nonterminal) — separates parsing
   joined_table inside '(' ... ')' from generic parseTableRef,
   enforces JoinExpr root so '(a)' / '((a))' / '((SELECT 1) x)'
   reject per PG grammar.
3. parseSelectWithParens (T5 left-factoring) — removed
   `cur == '(' { recurse }` short-circuit. Always delegates to
   parseSelectNoParens so parseSelectClause's set-op precedence
   climbing handles '((SELECT 1) UNION (SELECT 2))' correctly.

Effect on pg/pgregress: +17 PG official regress statements now pass
(0 new failures). FROM-clause edge-case parity with PG 17 across all
'(' dispatch shapes audited.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…seline)

Lands the starmap artifacts that will drive Phase 1-5:
- docs/plans/2026-04-21-pg-paren-dispatch.md — global plan (Codex-approved, 2 rounds)
- pg/parser/PAREN_AUDIT.{md,json} — 94 dispatch sites classified
- pg/parser/SCENARIOS-pg-paren-dispatch.md — 228 scenarios, 6 phases

Phase 0 (this commit's predecessor) is marked [x] in SCENARIOS.
Phases 1-5 execute via pg-paren-dispatch-driver / -worker skills.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@rebelice rebelice merged commit 9065100 into main Apr 22, 2026
1 check passed
rebelice added a commit that referenced this pull request Apr 22, 2026
… CI fence (#106)

Stacked on #105. Adds PG 17 testcontainer oracle harness, 188 hand-curated probes, fuzz harness, PAREN_AUDIT (94 sites), CI workflow, audit lint. See PR for full description.

🤖 Generated with [Claude Code](https://claude.com/claude-code)
rebelice added a commit that referenced this pull request Apr 22, 2026
…leanup (#107)

Stacked on #105 #106. Closes oracle-discovered KB-1/KB-2/KB-3, audits + fixes 27+ Class A silent-accept sites, lands G1-GATE lint enforcement. See PR for full description.

🤖 Generated with [Claude Code](https://claude.com/claude-code)
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.

1 participant