ADR-0027: existing-cases sweep + docs (step F)
Sweep: input_verdict tests confirm the schema-existence check fires across the identifier-taking commands — unknown table on drop / show / add column, unknown column on drop column / update — and that known references stay clean. The Step B check is grammar-generic, so this is verification + coverage rather than new code. Docs: requirements.md S6 -> [x], baseline 1096; CLAUDE.md deferred list reconciled (C5a and S6 are done — removed); ADR-0026's as-built note updated (step 5 shipped via ADR-0027); ADR-0027 gains an As-built notes section recording the post-walk diagnostics realization, the pre-rendered message, the timeout-based debounce, coarse WARNING spans, and the deferred highlight/hint wiring.
This commit is contained in:
@@ -229,6 +229,66 @@ ADR-0026's expression diagnostics (type mismatch, `= NULL`)
|
||||
land with that ADR's implementation and feed the WARNING
|
||||
severity.
|
||||
|
||||
## As-built notes (2026-05-19)
|
||||
|
||||
All five build-order steps are implemented, and — because
|
||||
ADR-0026 deferred its own step 5 — the ADR-0026 §7
|
||||
expression diagnostics (type mismatch, `= NULL`) were folded
|
||||
in here as the WARNING severity's first triggers. Realization
|
||||
choices and deviations from the sketch above:
|
||||
|
||||
- **Diagnostics are computed post-walk, not emitted during
|
||||
the walk.** §2 says "diagnostics are emitted there [in the
|
||||
walker]". As built, the walk produces the `MatchedPath` and
|
||||
the `Command` as before; `walk()` then runs two post-walk
|
||||
passes — `schema_existence_diagnostics` over the matched
|
||||
path, and `expr_warnings` over the built `Expr` — and
|
||||
stores the result in `WalkResult::diagnostics`. This keeps
|
||||
diagnostics off the walker's speculative-rollback paths
|
||||
(a `Choice` branch that matches an ident then rolls back
|
||||
would otherwise leak a diagnostic); the post-walk passes
|
||||
see only the surviving terminals. Same single schema-aware
|
||||
context, one logical pass later.
|
||||
- **`Diagnostic` carries a pre-rendered `message: String`,**
|
||||
not the `{severity, span, message_key}` of §2. Each
|
||||
diagnostic source catalog-translates at creation. This
|
||||
sidesteps the awkwardness of a parse-style message having
|
||||
no single static key, and the model stays "roughly
|
||||
`{severity, span, message}`".
|
||||
- **The parse outcome is not a synthetic `Diagnostic`.** The
|
||||
indicator reads it straight from `WalkOutcome` (§2's
|
||||
"highest severity across the outcome *and* the
|
||||
diagnostics"); `diagnostics` carries only the schema-aware
|
||||
findings layered on a structurally-valid parse. Schema-
|
||||
existence therefore runs only on a `Match`.
|
||||
- **`MatchedKind::Ident` gained an `IdentSource` field** so
|
||||
the post-walk schema check can tell a table reference from
|
||||
a column reference from an invented name without
|
||||
hard-coding role strings.
|
||||
- **The debounce uses `tokio::time::timeout` per event-loop
|
||||
iteration,** not `tokio::select!` — it keeps the existing
|
||||
~100-line event-handler body un-reindented. `recv` is
|
||||
time-boxed only while a recompute is owed; an idle session
|
||||
still blocks plainly. Any event resets the window (not
|
||||
only keystrokes) — a slight over-reset, harmless in
|
||||
practice.
|
||||
- **WARNING spans are coarse** — the whole WHERE clause. The
|
||||
`Expr` AST carries no source spans, and the indicator
|
||||
reads only severity. Precise per-literal spans (for a
|
||||
future warning-highlight overlay) are a refinement.
|
||||
- **Highlight / hint integration beyond the indicator** —
|
||||
§2 notes highlighting and the hint panel "read the
|
||||
individual diagnostics". The indicator and the model
|
||||
ship; routing diagnostic spans into the per-byte highlight
|
||||
overlay, and diagnostic messages into the hint panel
|
||||
beyond the existing parse-error path, is a follow-up (the
|
||||
build order did not enumerate it as a step).
|
||||
- **Debounce timing is not unit-tested** — it is async
|
||||
event-loop glue. `App::input_validity_verdict` (the pure
|
||||
verdict) and the indicator rendering are covered;
|
||||
`input_verdict` has a parse-outcome / schema-existence /
|
||||
expression-warning / existing-cases-sweep test set.
|
||||
|
||||
## See also
|
||||
|
||||
- ADR-0003 — input modes; the input field and its mode
|
||||
|
||||
Reference in New Issue
Block a user