a7db7dd2da
ADR-0030 §3 commissioned a focused ADR for the full SELECT grammar (the "SELECT — full" phase). ADR-0032 records the decisions; docs/plans/20260520-adr-0032-phase-2.md is the implementation plan walking the work. Phase 2's grammar surface: - Five JOIN flavours (INNER, LEFT, RIGHT, FULL OUTER, CROSS). NATURAL/USING/comma-FROM explicitly OOS. - All four set ops (UNION, UNION ALL, INTERSECT, EXCEPT). - WITH and WITH RECURSIVE CTEs, with optional (col-list) renaming. - Scalar subqueries, IN (SELECT …), [NOT] EXISTS as additive primary branches in sql_expr (redeems ADR-0031 §7 OOS-1). - Qualified column refs t.c / alias.c as a name_or_call tail (redeems ADR-0031 §7 OOS-2). - LIMIT n [OFFSET m]; legacy `LIMIT m, n` OOS. - DISTINCT/ALL, t.* projection, bare-alias projection (lifts Phase-1 §4.2's autonomous decision). Walker-capability honesty (§10): ADR-0030 §8's "ambient assistance comes for free" holds for grammar recursion (reuses ADR-0026's Subgrammar + depth cap unchanged) but not for completion scope. Phase 2 adds a new Node::ScopedSubgrammar variant alongside the existing Node::Subgrammar (DSL Expr and sql_expr recursion untouched), a from_scope_stack of ScopeFrames holding from_scope / cte_bindings / projection_aliases, qualified-prefix completion narrowing, and a post-walk fixup pass that re-resolves projection-list identifier highlighting/validity once FROM is parsed (the projection-before-FROM problem). CTE column resolution (§10.3): SELECT * and explicit-projection CTE bodies both yield real column completion past cte_alias.| via a body-projection derivation rule that runs at the body's ScopedSubgrammar exit and writes derived columns back into the binding. Diagnostics (§11): every Phase-2 validation case classified against ADR-0027's ERROR/WARNING guideline. Five new diagnostic.* catalog keys for parse-time-detectable cases (unknown_qualifier, ambiguous_column, projection_alias_misplaced, cte_arity_mismatch, compound_arity_mismatch) plus eight engine.* translation keys. A MatchedPath-walking predicate-warnings variant closes the Phase-1 carry-over gap where SQL WHERE expressions emitted no LIKE-on-numeric / = NULL / type-mismatch warnings — ADR-0027 Amendment 1 finally extends to the SQL surface. Result-column type resolution (§12): rusqlite 0.39.0 exposes column_table_name / column_origin_name / column_database_name behind a `column_metadata` feature; verified. Bare column refs recover their playground type — partially lifts Phase-1 §4.5's bool→0/1 deferral. The implementation plan breaks Phase 2 into seven sub-phases (2a–2g) with explicit exit gates per sub-phase and a cross-cut verification matrix that names every "X comes for free" claim from ADR-0030/0031/0032. The Phase-1 SQL-expression predicate-warning gap is a named row, preventing an analogous silent gap from shipping. The plan encodes the user's standing authorization for the implementer to walk uninterrupted between gates and commit with standard messages — escalation discipline preserved for design ambiguities and real blockers. Pushes remain user-only. New docs/plans/ directory sets a pattern for future phase plans. Status: Accepted.
Architecture Decision Records
This directory contains the project's ADRs, recorded per ADR-0000.
Index
- ADR-0000 — Record architecture decisions
- ADR-0001 — Language and TUI framework
- ADR-0002 — Database engine
- ADR-0003 — Input modes and command dispatch
- ADR-0004 — Project file format
- ADR-0005 — Column type vocabulary
- ADR-0006 — Undo snapshots and replay log
- ADR-0007 — Sharing and export
- ADR-0008 — Testing approach
- ADR-0009 — DSL command syntax conventions
- ADR-0010 — Database access via a dedicated worker thread
- ADR-0011 — Foreign-key column type compatibility
- ADR-0012 — Internal metadata for user-facing column types
- ADR-0013 — Relationships, naming, and the rebuild-table strategy
- ADR-0014 — Data operations, value literals, and the auto-show pattern
- ADR-0015 — Project storage runtime
- ADR-0016 — Pretty table rendering for data and structure views
- ADR-0017 — Column type-change compatibility
- ADR-0018 — Auto-fill contracts for
serialandshortidcolumns - ADR-0019 — Friendly error layer (H1) and i18n message catalog
- ADR-0020 — Tokenization layer for the DSL parser
- ADR-0021 — Parser-as-source-of-truth for H1a (per-command usage in parse errors)
- ADR-0022 — Ambient typing assistance: colour, hint panel, completion (I3 + I4)
- ADR-0023 — Unified declarative grammar tree — direction (superseded for execution detail by ADR-0024)
- ADR-0024 — Unified grammar tree: execution plan — Accepted, the executable spec — implemented (Phases A–F; Phase F shipped "minimal",
parser.rsretained as the router — see the ADR's Phase F implementation note) - ADR-0025 — Indexes — Accepted,
add index/drop index, persistence, rebuild-table preservation, and items-list display (C3index portion +S2) - ADR-0026 — Complex WHERE expressions — Accepted, stratified recursive expression grammar (
AND/OR/NOT, comparisons,LIKE,IS NULL,IN,BETWEEN) forupdate/delete/show datafilters;show datagainswhere+limit; adds theSubgrammarnode and a recursiveExprAST (C5a) - ADR-0027 — Input-field validity indicator — Accepted, a debounced
[ERR]/[WRN]marker at the input row's right edge, backed by a walker diagnostics-severity model (parse-outcome + schema-existence); advisory, never blocks submission (S6); Amendment 1 adds aLIKE-on-numeric-column WARNING - ADR-0028 — Query plans (
EXPLAIN QUERY PLAN) — Accepted, anexplainprefix command overshow data/update/delete; an annotated, span-styled plan tree; introduces theOutputLinestyled-runs mechanism (ADR-0016's deferred per-span styling) (QA1/QA2) - ADR-0029 — Column constraints (NOT NULL / UNIQUE / CHECK / DEFAULT) — Accepted, the four column-level constraints declared in the column-spec suffix (
create table/add column) and modified on existing columns viaadd constraint …/drop constraint …; a pre-flight dry-run guards populated columns;CHECKreuses the ADR-0026 expression grammar viaSubgrammar(C3) - ADR-0030 — Advanced mode: the standard-SQL surface — Accepted, SQL added as grammar within the unified grammar tree (ADR-0024), not a separate batch parser — so SQL gets the same completion / highlighting / hints / parse-errors as the DSL; mode gates the SQL forms; DDL routes through the typed
Commandexecutor (metadata + type vocabulary preserved), DML andSELECTexecute as validated SQL; engine-neutral posture, the DSL→SQL teaching echo; supersedes ADR-0001'ssqlparser-rsreservation; phased plan (Q1/Q2/Q4) - ADR-0031 — The SQL expression grammar — Accepted, the stratified SQL expression grammar fragment commissioned by ADR-0030 §3: a single precedence ladder (
OR/AND/NOT, the comparison/LIKE/IN/BETWEEN/IS NULLpredicate set, arithmetic incl.||, function calls,CASE) — the superset of ADR-0026's DSLWHEREgrammar, authored as a parallel fragment so simple mode is untouched; pure validation, builds no AST (consumers run/store SQL as text per ADR-0030 §4/§6); reuses ADR-0026'sSubgrammarrecursion + depth cap unchanged; subquery expressions and qualified column refs deferred to ADR-0030 Phase 2 - ADR-0032 — The full SQL
SELECTgrammar — Accepted, the Phase-2 grammar commissioned by ADR-0030 §3: fullSELECTwithINNER/LEFT/RIGHT/FULL OUTER/CROSSjoins,GROUP BY/HAVING, all four set ops (UNION/UNION ALL/INTERSECT/EXCEPT),WITHandWITH RECURSIVECTEs,LIMIT … OFFSET,DISTINCT,t.*, and bare-alias projection (lifting Phase-1 §4.2); additive extensions to ADR-0031'ssql_exprfor scalar subqueries,IN (SELECT …),[NOT] EXISTS, and qualified column refs (redeeming ADR-0031 §7 OOS-1/OOS-2); grammar-recursion viaSubgrammar(&SQL_SELECT_COMPOUND)reuses ADR-0026'sMAX_SUBGRAMMAR_DEPTH = 64cap unchanged; softens ADR-0030 §8's "ambient assistance comes for free" claim: completion scope needs newWalkContextaccumulators (afrom_scope_stackofScopeFrames holdingfrom_scope/cte_bindings/projection_aliases), a new walker node variantNode::ScopedSubgrammar(&Node)as the push/pop trigger (existingNode::Subgrammarunchanged so DSLExprandsql_exprrecursion are unaffected), qualified-prefix completion narrowing, body-projection-derived CTE column resolution (soSELECT *and explicit-projection CTE bodies both yield real column completion pastcte_alias.|), and a post-walk fixup pass that re-resolves projection-list identifier highlighting/validity onceFROMis parsed (the projection-before-FROM problem); classifies every Phase-2 validation case against ADR-0027's ERROR/WARNING guideline (§11): five newdiagnostic.*keys for parse-time-detectable cases (unknown qualifier, ambiguous column, projection-alias misplaced, CTE/compound arity mismatch) plus eightengine.*translation keys; a MatchedPath-walking predicate-warnings variant that closes the Phase-1 gap where SQLWHEREexpressions emitted noLIKE-on-numeric /= NULL/ type-mismatch warnings (ADR-0027 Amendment 1 finally extends to the SQL surface); adds a worker-side post-prepare type-resolution pass via engine column-origin metadata so bare column refs recover their playground type (partially lifting Phase-1 §4.5, the bool→0/1 case) —Cargo.tomlgainscolumn_metadatato rusqlite features (verified against pinned 0.39.0);__rdbms_*rejection extended to every new table-source slot