feat: support explain over advanced-mode SQL queries
explain now wraps the advanced SQL commands — select, with (CTE), insert, update, delete — in addition to the DSL show data/update/ delete it already covered, rendering through the same plan tree (ADR-0039, closing the ADR-0030 OOS-2 gap). Implemented as a second Advanced `explain` CommandNode under the shared entry word, reusing the established shared-word dispatch (SQL-first, DSL-fallback) rather than new grammar machinery. build_explain_sql slices the inner SQL off the source and reuses the existing SQL builders; do_explain_plan runs EXPLAIN QUERY PLAN over the carried text verbatim (never executes, so safe for destructive verbs). Advanced explain update/delete now route through SQL with an identical plan; DSL-explain tests pinned to simple mode. Help and usage text now list the advanced explain forms.
This commit is contained in:
@@ -2,11 +2,8 @@
|
||||
|
||||
## Status
|
||||
|
||||
**Accepted** — decision recorded 2026-05-27. **Implementation deferred**
|
||||
as a follow-up to the ADR-0037/ADR-0038 teaching-echo effort: the
|
||||
decision below is settled, but the full design has not been `/runda`'d
|
||||
or built, and is *not* part of that pass. **Supersedes ADR-0030 §13
|
||||
OOS-2.**
|
||||
**Accepted** — decision recorded 2026-05-27. **Implemented 2026-05-30**
|
||||
(issue #7; see Implementation below). **Supersedes ADR-0030 §13 OOS-2.**
|
||||
|
||||
## Context
|
||||
|
||||
@@ -51,6 +48,49 @@ modes, unchanged. **Supersedes ADR-0030 §13 OOS-2.**
|
||||
|
||||
Built test-first when picked up.
|
||||
|
||||
## Implementation (2026-05-30)
|
||||
|
||||
Built as designed, with the mode-gating and DSL/SQL disambiguation
|
||||
handled by the **existing shared-entry-word dispatch** rather than any
|
||||
new grammar machinery:
|
||||
|
||||
- **Two `explain` CommandNodes under one entry word.** The original
|
||||
`data::EXPLAIN` (`Simple`, DSL inner) is unchanged. A new
|
||||
`data::EXPLAIN_SQL` (`Advanced`) carries `EXPLAIN_SQL_SHAPE` — a
|
||||
`Choice` over `select` / `with` / `insert` / `update` / `delete`,
|
||||
each `[Word, Subgrammar(&SQL_*_SHAPE)]` reusing the standalone SQL
|
||||
command shapes. Both register under `explain` in `REGISTRY`, exactly
|
||||
mirroring the `insert`/`update`/`delete` shared-word pattern
|
||||
(ADR-0033 §2). The walker's `decide` then does all the work: advanced
|
||||
mode tries `EXPLAIN_SQL` first and falls back to the DSL `EXPLAIN`
|
||||
when no SQL branch matches (`explain show data …`, or a DSL-only
|
||||
`--all-rows`); simple mode reaches only the DSL node. **`with` (CTE)
|
||||
is included** — it builds a `Command::Select`, in scope per the
|
||||
decision's AST naming.
|
||||
- **Rejected `DynamicSubgrammar` mode-gating.** A factory reading
|
||||
`ctx.mode` would be memoised wrongly: the dynamic-resolution cache
|
||||
key omits `mode`, so a node resolved in one mode would be served back
|
||||
in the other. The two-CommandNode route avoids this and stays on the
|
||||
established dispatch path.
|
||||
- **Clean inner SQL.** `build_explain_sql` slices the inner SQL text
|
||||
from the source starting at the inner entry keyword's span (so the
|
||||
carried text excludes `explain`), then delegates to the existing
|
||||
`build_select` / `build_sql_*` builders. Their metadata extraction
|
||||
(target table, etc.) reads the path by role, which is offset-
|
||||
independent, so wrapping is transparent.
|
||||
- **Execution.** `do_explain_plan` gains arms for
|
||||
`Select` / `SqlInsert` / `SqlUpdate` / `SqlDelete` that run
|
||||
`EXPLAIN QUERY PLAN` over the carried SQL text verbatim, no bound
|
||||
params (grammar-as-text). `display_sql` is the user's text as written
|
||||
(the DSL path canonicalises only because it *synthesises* SQL). The
|
||||
ADR-0028 renderer is reused unchanged.
|
||||
- **Behaviour note.** In advanced mode `explain update …` /
|
||||
`explain delete …` now route through the SQL path (previously the
|
||||
DSL inner). The plan is identical (§6/§7 parity), and the SQL grammar
|
||||
accepts the full SQL syntax the DSL grammar rejected. DSL-explain
|
||||
tests were pinned to simple mode; advanced SQL wrapping has its own
|
||||
tests.
|
||||
|
||||
## Out of scope
|
||||
|
||||
- **EXPLAIN of DDL** (`CREATE` / `ALTER` / `DROP`). `EXPLAIN QUERY PLAN`
|
||||
|
||||
Reference in New Issue
Block a user