98a74b23d34a1454ee6df53d495a77030631395a
Sub-phase 2b checkpoint 2 — closes the recursion loop between sql_expr.rs and sql_select.rs so subquery expressions and qualified column refs become structurally valid in every SQL context where they belong. sql_expr.rs: - §5 qualified-ref tail. `name_or_call` gains a `.identifier` suffix as a Choice sibling of the function-call `(args)` tail. The leading identifier is still matched once (per ADR-0031 §1's factoring); the optional tail dispatches between the two suffixes by their first character (`.` vs `(`). - §6.1 scalar subquery as primary. The `(or_expr)` and `(SELECT …)` branches share the leading `(`; the first inside token (`SELECT` → subquery, anything else → expression) discriminates. The subquery recurses through `Node::ScopedSubgrammar(&sql_select::SQL_SELECT_COMPOUND)`. - §6.2 IN (subquery) predicate. Sibling of the existing IN-value-list; same `(` factoring, same dispatch. - §6.3 [NOT] EXISTS primary. Bare `EXISTS (compound_select)` lives in `primary`; `NOT EXISTS` falls out via the existing `not_expr := NOT not_expr` tier above `primary`. sql_select.rs: - CTE body recursion rewires `Node::Subgrammar` → `Node::ScopedSubgrammar`, matching §10.2. The top-level statement's COMPOUND embedding stays plain Subgrammar — the implicit bottom frame is the right scope for a statement- level SELECT. Structural side-effect — const-eval cycle workaround: Closing the sql_expr ⇄ sql_select reference loop made Rust's const-evaluator follow the cycle through every `const Node` that transitively reaches it. Mirroring sql_expr.rs's existing pattern, composition Nodes in sql_select.rs (Seq / Choice / Optional / Repeated / Lookahead) are now `static Node` and appear in slice positions through `Node::Subgrammar(&NAME)` wraps; only leaf items (Punct, Word, Ident) remain `const`. Same workaround applies to data.rs's SELECT_PROJ_LIST / SELECT_PROJECTION chain and the inlined `SQL_EXPR` reference. Statics resolve lazily at link time, so the cycle is valid; const-eval is not, and the named `const SQL_EXPR` alias is gone in both files (replaced with the inline `Node::Subgrammar (&sql_expr::SQL_OR_EXPR)` expression at every use site). Test coverage: - sql_expr.rs gains 11 new tests for qualified refs, scalar subquery, IN-subquery, EXISTS / NOT EXISTS, nested subqueries, and the existing IN-value-list form (regression). - sql_select.rs gains 7 new tests for qualified refs in WHERE, scalar subqueries in WHERE / projection, IN / EXISTS / NOT EXISTS in WHERE, nested subqueries, and qualified refs inside CTE bodies. - All 70 prior sql_select tests still pass; the 2a baseline is preserved. `(WITH x AS (…) SELECT * FROM x)` is explicitly NOT admitted as a scalar subquery — ADR-0032 §1 / §9 wire subqueries to SQL_SELECT_COMPOUND, which omits the outer with_clause. WITH remains a statement-level-only construct. Documented in the relevant test. Test totals: 1333 → 1351 passing, 0 failed, 1 ignored (unchanged). Clippy clean.
Description
No description provided