Files
rdbms-playground/docs/plans/20260526-adr-0035-sql-ddl-4i.md
T
claude@clouddev1 1afcf4ed29 feat: ADR-0035 4i(d) — merge shared-entry-word completions
In advanced mode an entry word like `create`/`drop` has several candidate
nodes (the SQL forms + the DSL fallback), but the walker commits to one,
so completion offered only that node's continuations — `drop ` showed
just `table`, and `drop rel` dead-ended at an empty list even though the
DSL drops parse via fallback.

At the entry-word boundary (advanced mode), walk every candidate, keep the
viable (Incomplete) ones, and union their next-keyword continuations:
`drop ` → table·index·column·relationship·constraint; `drop rel` →
relationship; `create ` → table·unique·index. Deeper positions keep the
committed walk untouched (no change to insert/update/delete/select).

Each continuation is classified by producing category (Both/Advanced/
Simple) and block-ordered Both → Advanced → Simple, so they read as
contiguous groups (the foundation for the 4i(e) colour, landing next).
CompletionProbe carries a parallel expected_modes; the parse path is
unchanged (the merge is completion-only).

Tests: completion merge + partial + block-order cases; the two tests that
encoded the old single-node behaviour updated. Full suite 1911 passing /
0 failing / 1 ignored; clippy clean.
2026-05-26 11:36:18 +00:00

8.1 KiB

Plan: ADR-0035 Phase 4, sub-phase 4i — verification sweep (completes Phase 4)

The closing sub-phase. Canonical scope: ADR-0035 §13 4i. Items:

  • (a) Refresh the CREATE TABLE help/usage skeleton for the 4a.2 DEFAULT/CHECK/composite-UNIQUE, 4a.3 table-CHECK, and 4b FK forms (the only help/usage debt — 4d/4e/4f/4g/4h carry their own).
  • (b) describe display of table-level constraints (composite UNIQUE + table CHECK, incl. named CHECKs from 4g).
  • (c) 4b self-ref FK pre-submit indicator: stop false-flagging a references <self> parent as unknown.
  • (d) shared-entry-word completion merge.
  • (e) visually distinguish simple- vs advanced-mode completions.
  • staples: typing-surface + matrix coverage, engine-neutral error pass, undo-parity (one step per statement).

User-chosen sequencing (2026-05-26): the (d)/(e) design conversation first, then build. (d)/(e) are designed (below); (a)/(b)/(c) + staples follow.

1. Baseline

  • HEAD ca64434; 1909 passing / 0 failing / 0 skipped / 1 ignored; clippy clean.

2. (d) + (e) — settled design (user-confirmed 2026-05-26)

(d) Shared-entry-word completion merge

Bug: in advanced mode the walker's decide() (walker/mod.rs) commits one candidate node for a shared entry word, so only that node's continuations reach completion — drop offers only table, and drop rel returns empty, even though the DSL drops parse via fallback.

Fix: in completion_probe_in_mode, for an advanced-mode shared entry word (the entry word resolves to >1 candidate), walk each candidate node speculatively (the existing scratch/walk_one_command machinery on a fresh context), extract each one's expected continuations (the same WalkOutcomeexpected match the single-walk path uses), and union them. Simple mode is unchanged (its single DSL node already offers all DSL continuations; SQL isn't offered). A candidate that mismatches the current input contributes an empty set, so as the input disambiguates (drop table …) the union naturally narrows to the surviving candidate.

(e) Visual simple-vs-advanced distinction

Each merged continuation is classified by which categories produced it — a new ModeClass:

  • Both — produced by ≥1 Advanced and ≥1 Simple candidate (a continuation valid either way, e.g. drop table).
  • Advanced — only Advanced candidates (SQL-only, e.g. create index).
  • Simple — only Simple candidates (DSL-only, e.g. drop relationship).

Colour + order apply only when the candidate list is mixed (>1 distinct ModeClass) — the only place the signal is informative; a single-mode list (deep inside any command) keeps today's token-kind colours, no mode tint (avoids redundant noise duplicating the mode indicator). When mixed:

  • Colour: Both → today's token-kind colour (neutral); Advancedtheme.mode_advanced (orange); Simpletheme.mode_simple (cyan). These two mode colours already exist (used by the mode indicator).
  • Order (user refinement): group the continuations into contiguous colour blocks in the order BothAdvancedSimple, so Advanced sits between the other two and each colour reads as one block rather than interleaving.

3. Architecture & change list (d/e)

  • src/dsl/walker/outcome.rs (or CompletionProbe): add a parallel expected_modes: Vec<ModeClass> (same length/order as expected), defaulting to all Both (so the single-walk path is neutral). New ModeClass enum (likely in completion.rs, re-exported).
  • src/dsl/walker/mod.rs completion_probe_in_mode: factor the expected-extraction (lines 333-356) into a helper; add the advanced-mode multi-candidate branch that walks each candidate (mode Advanced), classifies each expectation by the producing category, and fills expected + expected_modes.
  • src/completion.rs: Candidate gains mode: ModeClass; the keyword-building (Expectation::Word) carries the parallel ModeClass through prefix filtering; when the keyword set is mixed, block-order by ModeClass (Both→Advanced→Simple) within the keyword group; non-keyword kinds and single-mode lists are all Both.
  • src/ui.rs render_candidate_line (≈907): when the candidate list contains >1 ModeClass, colour each by its ModeClass (Both=kind-colour, Advanced=mode_advanced, Simple=mode_simple); otherwise unchanged.
  • Tests: tests/typing_surface/drop (advanced) offers table·index·column·relationship·constraint; drop relrelationship; create table (Both) + index (Advanced); block-order assertion (Both then Advanced then Simple); simple mode unchanged. A ui.rs snapshot for the mixed-mode coloured hint line.

4. (a)/(b)/(c) — outline (build after d/e)

  • (a) Extend the sql_create_table help/usage strings (friendly/strings/en-US.yaml) for DEFAULT/CHECK/composite-UNIQUE (4a.2), table-CHECK (4a.3), and inline + table-level FOREIGN KEY (4b). Catalog-lockstep + vocab-audit guard wording.
  • (b) describe (do_describe_table / the structure renderer): show table-level composite UNIQUE and table CHECK constraints (named CHECKs show their name). Tier-2 snapshot + Tier-3 describe assertions.
  • (c) The pre-submit schema-existence diagnostic: treat a FK parent equal to the in-statement CREATE TABLE target as valid (self-ref), so the [ERR]/[WRN] indicator stops lying. Tier-1/typing-surface test.

5. Phase 2/3 — candidates & selection (d/e)

Settled via the design conversation (§2). The merge alternative ("modify decide/walk to merge in the core parser") was rejected — it would change the shared parser used everywhere; doing the merge in the completion-only completion_probe_in_mode is lower-risk. The colour alternatives (always-by-mode; marker tag; defer) were presented to the user, who chose mode-colour-when-mixed + block ordering.

6. Devil's Advocate review of this plan

  • Forks escalated? The (e) visual treatment was put to the user with four options + previews; they chose option 1 with the block-ordering refinement. (d)'s behaviour is ADR/handoff-specified. ✓
  • Core-parser risk? The merge lives in completion_probe_in_mode (completion-only), not walk/decide — the parse path is untouched, so no risk to execution/dispatch. ✓
  • Simple mode unaffected? The merge branch is advanced-only; simple-mode completion keeps the single-DSL-node path. A test pins it. ✓
  • Noise? Colour/order apply only when the list is genuinely mixed; single-mode lists are visually unchanged. ✓
  • Perf? Completion walks each candidate per keystroke — candidates per entry word are few (≤ ~3), and completion is already a per-keystroke walk; negligible. ✓
  • Ordering vs existing kind-order? Block-ordering applies within the keyword group (where shared-entry continuations live); the identifiers-first kind ordering is preserved. ✓

7. Implementation sequence (test-first)

  1. (d) mergeModeClass + expected_modes; the advanced-mode multi-candidate walk + union in completion_probe_in_mode; thread through completion.rs (functional merge, classes computed but not yet coloured). Typing-surface tests (merge + simple-mode-unchanged) → green.
  2. (e) order + colour — block-ordering when mixed; render_candidate_line colours by ModeClass. Ordering test + a UI snapshot → green.
  3. (c) self-ref FK indicator → test-first.
  4. (b) describe table-level constraints → snapshot/e2e.
  5. (a) CREATE TABLE help/usage skeleton + catalog lockstep.
  6. Staples — typing-surface/matrix sweep, engine-neutral error pass, undo-parity spot-check.
  7. Full sweep + finished-slice /runda → commit proposal(s).

8. Exit gate

All §13 4i items done or explicitly deferred-with-user-confirmation; all tiers green, zero skips; no regression from 1909; clippy clean; written-DA / /runda PASS; ADR-0035 §13 4i + README + requirements lockstep. 4i completes ADR-0035 Phase 4 — flip the ADR Status from "4i pending".