grammar: admit WITH inside subqueries / CTE bodies (ADR-0032 §10.3)
ADR-0032 §10.3 says cte_bindings lives on the scope frame, with inner subqueries free to declare their own CTEs that shadow outer ones. The grammar didn't actually admit nested WITH inside SQL_SELECT_COMPOUND — a real ADR-vs-implementation gap. Closes the gap by making SQL_SELECT_COMPOUND a Choice between a WITH-prefixed form and a plain form. The naive Optional-prefix approach silently broke the paren-vs-subquery dispatch in sql_expr.rs's PAREN_GROUP: Optional matches 0 bytes, committing the Seq, so SELECT_CORE's NoMatch on `(a + b)` became Failed and the Choice couldn't fall through to or_expr. The Choice-fronted form keeps the fast NoMatch on non-WITH non-SELECT first tokens. Side effect: scalar subquery / IN / EXISTS / derived-table bodies now admit a leading WITH too, which matches standard SQL. Updated two tests that were guarding the old `(WITH …)` rejection behavior. Added one new harvest test exercising nested-WITH inside a CTE body — the harvest's `expand_binding` mechanism already handled the data correctly; the grammar gap was the sole blocker. Test totals: 1414 → 1415 passing (+1 nested-with-in-cte test). Clippy clean.
This commit is contained in:
@@ -706,17 +706,16 @@ mod tests {
|
||||
|
||||
#[test]
|
||||
fn scalar_subquery_dispatches_against_paren_group() {
|
||||
// Both `(or_expr)` and `(SELECT …)` start with `(`.
|
||||
// The ADR factors the `(` and the first inside token
|
||||
// discriminates — `SELECT` → subquery, anything else
|
||||
// → expression. (Per ADR-0032 §1 / §9, subqueries
|
||||
// recurse through `SQL_SELECT_COMPOUND` which omits
|
||||
// the outer `WITH` — so `(WITH …)` is NOT admitted as
|
||||
// a scalar subquery; that form is only valid at
|
||||
// statement top-level.)
|
||||
// Both `(or_expr)` and `(SELECT …)` / `(WITH …)` start
|
||||
// with `(`. The ADR factors the `(` and the first inside
|
||||
// token discriminates — `SELECT` / `WITH` → subquery,
|
||||
// anything else → expression. Per ADR-0032 §10.3, a
|
||||
// subquery body may declare its own CTEs (shadowing
|
||||
// outer ones), so `(WITH …)` IS admitted as a scalar
|
||||
// subquery shape.
|
||||
good("(a + 1)");
|
||||
good("(select 1)");
|
||||
bad("(with x as (select 1) select * from x)");
|
||||
good("(with x as (select 1) select * from x)");
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
Reference in New Issue
Block a user