The friendly arity diagnostic (diagnostic.insert_arity_mismatch / insert_arity_mismatch_form_b, ADR-0033 §8.1 / Amendment 5) fires in advanced mode for wrong-count insert … values (…) tuples, but not in simple mode for the equivalent inputs.
with no column list, all 4 column(s) need a value but 3 value(s) are given
insert into Customers values ('Alice')
diags: [] → generic expected \,``
all 3 column(s) need a value but 1 value(s) are given
insert into Customers (Name, Email) values ('a', 'b', 'c')
diags: [] → generic expected \)``
the column list names 2 column(s) but 3 value(s) are given
Root cause (hypothesis)
In simple mode the dispatch/grammar routes these to a structural Mismatch (the typed-slot path rejects the tuple — simple-mode Form B serial-skip changes the expected value count), so input_diagnostics_in_mode returns [] (the diagnostic pass runs only on a successful Match). In advanced mode the wrong-arity tuple takes the type-blind fallback, structurally Matches, and the diagnostic fires on the matched path.
The friendly message is computed by dml_insert_arity_diagnostics (src/dsl/walker/mod.rs:1465); the unit tests for it (insert_arity_mismatch_*, insert_form_b_arity_mismatch_*) all run in advanced mode via the diag_keys helper, which is why the simple-mode gap was never caught.
Expected
Simple-mode learners (the primary audience) should get the same friendly "N values for M columns" message as advanced mode, rather than a raw expected \,`/`)``.
Context
Surfaced during the fix for #2 (between-values hint). #2 made the simple-mode hint accurate (it surfaces the real parse error instead of a misleading "submit with Enter"); this issue is about making it friendly in simple mode too.
### Observed
The friendly arity diagnostic (`diagnostic.insert_arity_mismatch` / `insert_arity_mismatch_form_b`, ADR-0033 §8.1 / Amendment 5) fires in **advanced mode** for wrong-count `insert … values (…)` tuples, but **not in simple mode** for the equivalent inputs.
Probed behaviour (schema `Customers(id serial, Name, Age, SerNo)` and `Customers(id serial, Name, Email)`):
| Input | Simple mode | Advanced mode |
|---|---|---|
| `insert into Customers values ('Oli', 52, 3)` | `diags: []` → generic `expected \`)\`` | `with no column list, all 4 column(s) need a value but 3 value(s) are given` |
| `insert into Customers values ('Alice')` | `diags: []` → generic `expected \`,\`` | `all 3 column(s) need a value but 1 value(s) are given` |
| `insert into Customers (Name, Email) values ('a', 'b', 'c')` | `diags: []` → generic `expected \`)\`` | `the column list names 2 column(s) but 3 value(s) are given` |
### Root cause (hypothesis)
In simple mode the dispatch/grammar routes these to a structural **Mismatch** (the typed-slot path rejects the tuple — simple-mode Form B serial-skip changes the expected value count), so `input_diagnostics_in_mode` returns `[]` (the diagnostic pass runs only on a successful `Match`). In advanced mode the wrong-arity tuple takes the type-blind fallback, structurally Matches, and the diagnostic fires on the matched path.
The friendly message is computed by `dml_insert_arity_diagnostics` (`src/dsl/walker/mod.rs:1465`); the unit tests for it (`insert_arity_mismatch_*`, `insert_form_b_arity_mismatch_*`) all run in **advanced** mode via the `diag_keys` helper, which is why the simple-mode gap was never caught.
### Expected
Simple-mode learners (the primary audience) should get the same friendly "N values for M columns" message as advanced mode, rather than a raw `expected \`,\`/\`)\``.
### Context
Surfaced during the fix for #2 (between-values hint). #2 made the simple-mode hint *accurate* (it surfaces the real parse error instead of a misleading "submit with Enter"); this issue is about making it *friendly* in simple mode too.
Simple-mode wrong-count inserts now reach the same friendly arity diagnostic that advanced mode shows, at typing time — instead of a bare expected \,`/`)``.
Root cause confirmed. Simple-mode insert and advanced-mode insert use different grammar nodes. Advanced routes a wrong-count VALUES tuple to a type-blind fallback (tuple_value_list) so it structurally matches and dml_insert_arity_diagnostics fires; the simple-mode DSL value list (column_value_list) built a fixed-length typed Seq, so a wrong-count tuple Mismatched and the diagnostic never ran. (The issue #1 submit-time teaching note was a workaround for exactly this gap.)
Fix — unified onto the one ADR-0027 model (structural parse + ERROR diagnostic), advanced untouched:
Grammar: a tuple_value_list-style gate (dsl_insert_value_list) routes a wrong-count DSL insert tuple to the shared type-blind fallback so it matches and the diagnostic fires. Gated to simple mode — in advanced the DSL node stays strict, so advanced behaviour is byte-for-byte unchanged (verified empirically). count_tuple_values + insert_target_columns are now shared by both grammars.
Diagnostic is mode-aware: advanced Form B expects all columns; simple Form B/C expects the user-fillable columns (serial/shortid auto-fill, ADR-0018 §3). It now counts the DSL Form A role (insert_first_item) and scans the keyword-less Form C tuple. New catalog keys diagnostic.insert_arity_mismatch_form_b_simple (names the fillable and auto-generated columns) and diagnostic.insert_arity_mismatch_all_auto.
Submit safety: a wrong-count DSL insert now parses Ok + carries the ERROR diagnostic (the [ERR] verdict), so a unified Ok-arm pre-flight (dsl_insert_count_mismatch_notes) blocks dispatch and shows the teaching note — the bad insert never reaches the worker. The issue #1 Err-arm note retires.
Scope guard: arity-diagnostic UX parity only — no consolidation of value-handling, execution, or auto-fill (ADR-0036's deliberate mode-distinctness stands; the per-mode count difference is a consequence of the auto-fill difference).
Documented as ADR-0036 Amendment 2 (cross-ref ADR-0033 §8.1) + README index + requirements.md H1a. Tests: simple Form A/B/C + all-auto arity diagnostics, execution-safety (no dispatch) for Form A/B, advanced-unchanged guard, typing-surface verdict assertions; full suite 2051 passing / 0 failing / 1 ignored, clippy clean.
Fixed in `10e5197`.
Simple-mode wrong-count inserts now reach the same friendly arity diagnostic that advanced mode shows, at typing time — instead of a bare `expected \`,\`/\`)\``.
**Root cause confirmed.** Simple-mode `insert` and advanced-mode `insert` use different grammar nodes. Advanced routes a wrong-count `VALUES` tuple to a type-blind fallback (`tuple_value_list`) so it structurally matches and `dml_insert_arity_diagnostics` fires; the simple-mode DSL value list (`column_value_list`) built a fixed-length typed `Seq`, so a wrong-count tuple Mismatched and the diagnostic never ran. (The issue #1 submit-time teaching note was a workaround for exactly this gap.)
**Fix — unified onto the one ADR-0027 model (structural parse + ERROR diagnostic), advanced untouched:**
1. **Grammar:** a `tuple_value_list`-style gate (`dsl_insert_value_list`) routes a wrong-count DSL insert tuple to the shared type-blind fallback so it matches and the diagnostic fires. **Gated to simple mode** — in advanced the DSL node stays strict, so advanced behaviour is byte-for-byte unchanged (verified empirically). `count_tuple_values` + `insert_target_columns` are now shared by both grammars.
2. **Diagnostic is mode-aware:** advanced Form B expects all columns; simple Form B/C expects the **user-fillable** columns (`serial`/`shortid` auto-fill, ADR-0018 §3). It now counts the DSL Form A role (`insert_first_item`) and scans the keyword-less Form C tuple. New catalog keys `diagnostic.insert_arity_mismatch_form_b_simple` (names the fillable *and* auto-generated columns) and `diagnostic.insert_arity_mismatch_all_auto`.
3. **Submit safety:** a wrong-count DSL insert now parses `Ok` + carries the ERROR diagnostic (the `[ERR]` verdict), so a unified Ok-arm pre-flight (`dsl_insert_count_mismatch_notes`) **blocks dispatch** and shows the teaching note — the bad insert never reaches the worker. The issue #1 Err-arm note retires.
**Scope guard:** arity-diagnostic UX parity only — no consolidation of value-handling, execution, or auto-fill (ADR-0036's deliberate mode-distinctness stands; the per-mode count difference is a *consequence* of the auto-fill difference).
Documented as **ADR-0036 Amendment 2** (cross-ref ADR-0033 §8.1) + README index + requirements.md H1a. Tests: simple Form A/B/C + all-auto arity diagnostics, execution-safety (no dispatch) for Form A/B, advanced-unchanged guard, typing-surface verdict assertions; full suite 2051 passing / 0 failing / 1 ignored, clippy clean.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Observed
The friendly arity diagnostic (
diagnostic.insert_arity_mismatch/insert_arity_mismatch_form_b, ADR-0033 §8.1 / Amendment 5) fires in advanced mode for wrong-countinsert … values (…)tuples, but not in simple mode for the equivalent inputs.Probed behaviour (schema
Customers(id serial, Name, Age, SerNo)andCustomers(id serial, Name, Email)):insert into Customers values ('Oli', 52, 3)diags: []→ genericexpected \)``with no column list, all 4 column(s) need a value but 3 value(s) are giveninsert into Customers values ('Alice')diags: []→ genericexpected \,``all 3 column(s) need a value but 1 value(s) are giveninsert into Customers (Name, Email) values ('a', 'b', 'c')diags: []→ genericexpected \)``the column list names 2 column(s) but 3 value(s) are givenRoot cause (hypothesis)
In simple mode the dispatch/grammar routes these to a structural Mismatch (the typed-slot path rejects the tuple — simple-mode Form B serial-skip changes the expected value count), so
input_diagnostics_in_modereturns[](the diagnostic pass runs only on a successfulMatch). In advanced mode the wrong-arity tuple takes the type-blind fallback, structurally Matches, and the diagnostic fires on the matched path.The friendly message is computed by
dml_insert_arity_diagnostics(src/dsl/walker/mod.rs:1465); the unit tests for it (insert_arity_mismatch_*,insert_form_b_arity_mismatch_*) all run in advanced mode via thediag_keyshelper, which is why the simple-mode gap was never caught.Expected
Simple-mode learners (the primary audience) should get the same friendly "N values for M columns" message as advanced mode, rather than a raw
expected \,`/`)``.Context
Surfaced during the fix for #2 (between-values hint). #2 made the simple-mode hint accurate (it surfaces the real parse error instead of a misleading "submit with Enter"); this issue is about making it friendly in simple mode too.
Fixed in
10e5197.Simple-mode wrong-count inserts now reach the same friendly arity diagnostic that advanced mode shows, at typing time — instead of a bare
expected \,`/`)``.Root cause confirmed. Simple-mode
insertand advanced-modeinsertuse different grammar nodes. Advanced routes a wrong-countVALUEStuple to a type-blind fallback (tuple_value_list) so it structurally matches anddml_insert_arity_diagnosticsfires; the simple-mode DSL value list (column_value_list) built a fixed-length typedSeq, so a wrong-count tuple Mismatched and the diagnostic never ran. (The issue #1 submit-time teaching note was a workaround for exactly this gap.)Fix — unified onto the one ADR-0027 model (structural parse + ERROR diagnostic), advanced untouched:
tuple_value_list-style gate (dsl_insert_value_list) routes a wrong-count DSL insert tuple to the shared type-blind fallback so it matches and the diagnostic fires. Gated to simple mode — in advanced the DSL node stays strict, so advanced behaviour is byte-for-byte unchanged (verified empirically).count_tuple_values+insert_target_columnsare now shared by both grammars.serial/shortidauto-fill, ADR-0018 §3). It now counts the DSL Form A role (insert_first_item) and scans the keyword-less Form C tuple. New catalog keysdiagnostic.insert_arity_mismatch_form_b_simple(names the fillable and auto-generated columns) anddiagnostic.insert_arity_mismatch_all_auto.Ok+ carries the ERROR diagnostic (the[ERR]verdict), so a unified Ok-arm pre-flight (dsl_insert_count_mismatch_notes) blocks dispatch and shows the teaching note — the bad insert never reaches the worker. The issue #1 Err-arm note retires.Scope guard: arity-diagnostic UX parity only — no consolidation of value-handling, execution, or auto-fill (ADR-0036's deliberate mode-distinctness stands; the per-mode count difference is a consequence of the auto-fill difference).
Documented as ADR-0036 Amendment 2 (cross-ref ADR-0033 §8.1) + README index + requirements.md H1a. Tests: simple Form A/B/C + all-auto arity diagnostics, execution-safety (no dispatch) for Form A/B, advanced-unchanged guard, typing-surface verdict assertions; full suite 2051 passing / 0 failing / 1 ignored, clippy clean.