darpan-e6 opened a new pull request, #4950:
URL: https://github.com/apache/calcite/pull/4950

   ## Summary
   
   Fixes [CALCITE-7533](https://issues.apache.org/jira/browse/CALCITE-7533).
   
   The parser rejects a parenthesized query expression as the body of a `WITH` 
clause, even though this is permitted by SQL:2016 (`<query expression body>` → 
`( <query expression body> )`) and accepted by PostgreSQL.
   
   Example failing query:
   ```sql
   SELECT * FROM (
     WITH q AS (SELECT 1 AS id)
     (SELECT id FROM q) UNION ALL (SELECT id FROM q)
   ) t
   ```
   
   Error:
   ```
   SqlParseException: Encountered "(" at line 1, column 46.
   Was expecting one of:
       "SELECT" ... "TABLE" ... "VALUE" ... "VALUES" ... "," ...
   ```
   
   ## Root cause
   
   In `Parser.jj`, the `Query` production only accepts `LeafQuery` (i.e. 
`SELECT` / `VALUES` / `TABLE`) as the body after a `WithList`. The parallel 
`QueryOrExpr` rule already uses `LeafQueryOrExpr` after `WithList`, and 
`AddSetOpQuery` (used for the 2nd…Nth set-op operands) also uses 
`LeafQueryOrExpr`. So the parser accepts `… UNION ALL (SELECT 1)` but rejects 
`(SELECT 1) UNION ALL …` when it appears as the first operand after `WITH`.
   
   Without `WITH`, the same shape parses fine via `ExprOrJoinOrOrderedQuery`'s 
alt-2 (`TableRef1`) path.
   
   ## Fix
   
   Branch `Query` so the post-`WithList` body uses `LeafQueryOrExpr` (mirroring 
`QueryOrExpr`), while the no-`WITH` path keeps `LeafQuery`. This preserves 
`Query`'s first-set (`{SELECT, VALUE, VALUES, TABLE}`), so the `LOOKAHEAD(2)` 
decision in `ExprOrJoinOrOrderedQuery` is unchanged and existing parses (e.g. 
`(SELECT 1) UNION ALL (SELECT 2)`) take the same path and produce the same tree.
   
   ### Note on permissiveness
   
   Using `LeafQueryOrExpr` after `WithList` inherits the same looseness 
`QueryOrExpr` already has: a non-query body such as `WITH q AS (SELECT 1) 1+2` 
will now parse successfully and be rejected by the validator (rather than 
rejected at parse time). This is consistent with Calcite's existing "parse 
permissively, validate strictly" approach for `WITH` — `QueryOrExpr` exhibits 
the same behavior today, so this isn't a new failure mode, just a new place it 
surfaces.
   
   ## Test plan
   
   - [x] `SqlParserTest.testWithParenthesizedBody` covers the reported query.
   - [x] All existing `testWith*` tests pass across `CoreSqlParserTest`, 
`SqlUnParserTest`, and `ExtensionSqlParserTest` (66 tests, 0 failures) — 
confirms no regression in the WITH grammar or unparse behavior, and that the 
LOOKAHEAD boundary in `ExprOrJoinOrOrderedQuery` is unchanged.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to