feat: H1a CROSS JOIN ON teaching message; advanced-SQL gaps re-verified (ADR-0042)
Empirically re-checking ADR §3's advanced-SQL "gaps" reversed two of three — the code survey that produced the list was wrong: - INSERT…SELECT column-count: already handled (verdict=Error, "the column list names N column(s) but M value(s) are given"; insert_select_arity_mismatch_fires). - RETURNING scope: already handled (completion offers the table's columns; `returning <unknown>` → unknown_column diagnostic). The one genuine residual is fixed: `select … cross join b on …` rejected the ON with a bare "expected end of input". Add parse.cross_join_no_on — "a CROSS JOIN has no ON clause — it pairs every row; for a join condition use `JOIN … ON`, or filter with `WHERE`" — rendered when the failing token is `on` and the most recent consumed join is a CROSS join (a precise signature: every other join requires `on`, so `on` is expected there, not a failure). Render-only in format_walker_error; two misfire guards locked (plain join still asks for ON; a stray `on` with no join does not fire). ADR-0042 §3 corrected + Implementation-outcome records the advanced-SQL re-check and the user-confirmed low-priority residual (submit-time expression first-set at non-projection positions, where typing-time completion already offers the right candidates). Full suite green (lib 1578 / it 388 / typing_surface_matrix 192); clippy clean.
This commit is contained in:
@@ -184,14 +184,12 @@ must not be re-built — `cte_arity_mismatch` and
|
||||
`compound_arity_mismatch` (`en-US.yaml:590-591`); for these the work
|
||||
is matrix coverage and, for CTE, auditing whether the diagnostic is
|
||||
*positioned at the CTE name* (easiest to fix) rather than the body.
|
||||
The genuine **absences** the pass adds are: `RETURNING` column
|
||||
scope, `CROSS JOIN` rejecting an `ON` clause, and INSERT…SELECT
|
||||
projection/target column-count (verified absent from the catalog
|
||||
2026-06-03). Each gets a matrix entry; fixes land as walker
|
||||
diagnostics or `parse.custom.*` messages following the existing
|
||||
patterns. The `:` one-shot escape (a simple-mode line run once in
|
||||
advanced mode) is part of the advanced surface and gets at least one
|
||||
near-miss matrix entry.
|
||||
The remaining items were re-checked empirically at implementation
|
||||
time (2026-06-05) and **most turned out already handled** — see the
|
||||
Implementation-outcome section's advanced-SQL paragraph for the
|
||||
corrected picture. The `:` one-shot escape (a simple-mode line run
|
||||
once in advanced mode) is part of the advanced surface and is
|
||||
covered by the mode-aware usage threading (G3).
|
||||
|
||||
This stays clear of ADR-0019 §OOS-2 (advanced-SQL *engine-error*
|
||||
sanitisation): §OOS-2 reworks errors raised by *executing* SQL;
|
||||
@@ -260,6 +258,40 @@ in `tests/it/parse_error_pedagogy.rs`:
|
||||
- **G4** — `with` borrowed `select`'s usage; it gains its own
|
||||
`parse.usage.with` CTE template.
|
||||
|
||||
**Advanced-SQL pedagogy (§3) — empirical re-check (2026-06-05).**
|
||||
§3 (drafted from a code survey) listed `RETURNING` scope,
|
||||
`CROSS JOIN … ON`, and INSERT…SELECT column-count as absences.
|
||||
Verifying each against the running app **reversed two of three**:
|
||||
|
||||
- **INSERT…SELECT column-count** is *already handled* — a count
|
||||
mismatch fires `verdict = Error` with "the column list names N
|
||||
column(s) but M value(s) are given" (walker test
|
||||
`insert_select_arity_mismatch_fires`). Not a gap.
|
||||
- **RETURNING scope** is *already handled* — at a bare `returning`
|
||||
position completion offers the table's columns; `returning
|
||||
<unknown>` fires the `unknown_column` diagnostic. Not a gap.
|
||||
- **`CROSS JOIN … ON`** *was* a genuine residual: the grammar
|
||||
rejects the `on` but the structural error said only "expected end
|
||||
of input". **Fixed** — `parse.cross_join_no_on` renders "a CROSS
|
||||
JOIN has no ON clause — …" when the failing token is `on` and the
|
||||
most recent consumed join is a CROSS join (a precise signature:
|
||||
every other join requires `on`, so there `on` is expected, not a
|
||||
failure). Render-only, no grammar change; two misfire guards
|
||||
(plain join still asks for `on`; a stray `on` with no join does
|
||||
not fire). The CTE/compound arity diagnostics noted above remain
|
||||
present and correct.
|
||||
|
||||
**Known low-priority residual (user-confirmed to defer).** At
|
||||
*submit* time, an incomplete expression position that is not a
|
||||
SELECT projection (bare `where `, `returning `, `having `, `set
|
||||
col=`) still renders the raw ~14-item expression first-set; only the
|
||||
SELECT projection is glossed (G2, keyed on the `distinct`+`all`
|
||||
quantifier pair). This is low-impact because *typing*-time
|
||||
completion already offers the correct candidates (columns,
|
||||
functions, expression keywords) at those positions. Generalising the
|
||||
gloss was considered and deferred — the payoff is small and a
|
||||
broader render-side collapse adds misfire surface.
|
||||
|
||||
Coverage: the matrix covers, in both modes, every entry word's bare
|
||||
/ missing-clause / wrong-token near-misses, the app-lifecycle
|
||||
trailing-junk cases, **and** the committed *multi-form* variants
|
||||
|
||||
Reference in New Issue
Block a user