fix: X4 — advanced-mode SQL INSERT auto-fills omitted non-PK serial (MAX+1)
A Form-A advanced-mode INSERT that omitted a non-PK serial column left it silently NULL (the column is INTEGER UNIQUE, not NOT NULL, so SQLite permits it), while simple-mode do_insert auto-fills it with MAX+1. That violated ADR-0018 §1's "auto-generated on every path" contract and was the unprincipled serial-vs-shortid asymmetry the ADR set out to remove (advanced mode already auto-fills shortid). Fix (decision: advanced mode matches simple mode): the advanced-mode auto-fill reconstruction — renamed plan_shortid_autofill → plan_autogen_autofill — now also fills an omitted non-PK serial with MAX(col)+1 … MAX+n per row (single- and multi-row), reading MAX once under the worker's single-writer serialisation. PK serial stays on the rowid alias; Form B (no column list) still supplies every column. Honours ADR-0018 §1/§5; no ADR amendment needed (the contract already said "every path"). requirements.md X4 marked resolved. Tests: 1949 passing (+1), 0 failed, 0 skipped, 1 ignored; clippy clean.
This commit is contained in:
+17
-13
@@ -576,19 +576,23 @@ handoff-14 cleanup; 449 after B2/C2.)
|
||||
- [~] **X3** Accessibility: TUI screen-reader support is
|
||||
best-effort and not a v1 commitment; revisit if user need
|
||||
emerges.
|
||||
- [~] **X4** Auto-fill semantics differ between simple and advanced
|
||||
mode — **possible bug, to investigate** (raised 2026-05-26). The
|
||||
simple-mode insert (`do_insert`, `db.rs`) auto-fills an omitted
|
||||
**non-PK `serial`** column with `MAX(col)+1` *and* generates
|
||||
`shortid`s; the advanced-mode SQL insert (`plan_shortid_autofill`)
|
||||
auto-fills **only `shortid`** and does **not** do non-PK `serial`
|
||||
MAX+1. The `shortid` distinction is intentional; the non-PK-`serial`
|
||||
gap looks unintended (no obvious reason advanced mode should skip
|
||||
filling a `serial`). Decide whether advanced mode should match
|
||||
simple mode's serial auto-fill (likely yes) or whether the
|
||||
difference is deliberate, and align ADR-0018 accordingly. Left
|
||||
untouched by the ADR-0036 value-validation work (which is surgical
|
||||
and does not change auto-fill).
|
||||
- [x] **X4** Auto-fill semantics differ between simple and advanced
|
||||
mode — **resolved 2026-05-27** (raised 2026-05-26). Was: simple-mode
|
||||
`do_insert` auto-fills an omitted **non-PK `serial`** column with
|
||||
`MAX(col)+1`, but the advanced-mode SQL insert auto-filled **only
|
||||
`shortid`**, leaving an omitted non-PK serial **silently NULL** —
|
||||
violating ADR-0018 §1's "auto-generated on every path" contract (the
|
||||
column is `INTEGER UNIQUE`, not `NOT NULL`, so SQLite permits the
|
||||
NULL). Confirmed by characterization, escalated, and fixed (decision:
|
||||
advanced mode matches simple mode): the advanced-mode auto-fill
|
||||
reconstruction (`db.rs`, renamed `plan_shortid_autofill` →
|
||||
**`plan_autogen_autofill`**) now also fills an omitted non-PK serial
|
||||
with `MAX+1` per row (single- and multi-row), mirroring `do_insert`
|
||||
and the existing shortid fill. PK serial is excluded (rowid alias);
|
||||
Form B (no column list) still supplies every column. Covered by
|
||||
`tests/sql_insert.rs::sql_insert_autofills_omitted_nonpk_serial`.
|
||||
Honours ADR-0018 §1/§5; no ADR amendment needed (the contract already
|
||||
said "every path"). ADR-0036 was correct that it did not touch this.
|
||||
- [~] **X5** Framework cohesion / restructuring — **strategic,
|
||||
revisit later** (raised 2026-05-26). The grammar/execution
|
||||
framework (lexer → walker `Node`s → unified grammar tree → typed
|
||||
|
||||
Reference in New Issue
Block a user