Files
five/_FiveSql2/src
CharlesKWON 325fe51656 fix(fivesql2): DML transaction + constraint ordering
Three correctness bugs in the DML executor that the 4.7 audit
surfaced:

1. RunInsert logged the transaction BEFORE dbAppend() and validation.
   LogRecord captured the PREVIOUS row's RecNo, and a CHECK/FK
   violation that rolled back via dbDelete() still left a spurious
   INSERT entry in the log pointing at the wrong record. Move
   LogRecord to after all field puts and all validators pass, so
   the log only records committed INSERTs at the correct RecNo.

2. RunUpdate (fallback path) skipped CHECK and FK validation entirely
   — only RunInsert validated. An UPDATE could violate the same
   constraints INSERT protects against. Add the same validator calls
   after FieldPut, with a captured aPrevVals snapshot so the in-
   memory record can roll back cleanly on failure. Gated by
   SqlLoadConstraints to skip the validator (and its recursive
   five_SQL) for tables without SQL-level metadata — tables created
   via plain dbCreate see no change.

3. RunDelete had no transaction logging at all — a BEGIN / DELETE /
   ROLLBACK cycle silently lost the row. Add LogRecord("DELETE")
   before dbDelete so undo can re-surface it. (A full FK-cascade
   check on delete would require parent→child scanning; deferred.)

The fast-path SqlBulkUpdate branch still bypasses per-record
validation by design (documented) — it's gated by
`! ::oTxn:IsActive()`, so txn-active queries always take the
validated fallback.

FiveSql2 43/43 (including SAVEPOINT + ROLLBACK TO and all four CHECK/
FK tests), Harbour compat 56/56, Go test ALL PASS.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-18 23:24:14 +09:00
..