feat: ADR-0036 Phase 1 — validate advanced-mode INSERT literals + show the value
Capture literal VALUES at parse onto Command::SqlInsert (no grammar change, no reparse); validate them against column types before the still-verbatim insert (reusing impl_value_for for DSL-parity wording); read them in the error enricher so a constraint error names the real value. Execution, auto-fill, and command identity unchanged. Adds run_sql_insert_with_literals (runtime path); run_sql_insert stays the no-capture raw entry. Proven: malformed date 2025/01/15 now refused in advanced-mode SQL; replayed UNIQUE shows the real value. Tests +3 (expression runs, multi-row, natural order) + 2 flipped/strengthened. 1930 pass / 0 fail / 0 skip; clippy clean.
This commit is contained in:
@@ -340,17 +340,18 @@ fn replay_constraint_failure_shows_real_names_not_placeholders() {
|
||||
let AppEvent::ReplayFailed { error, .. } = failed else {
|
||||
unreachable!()
|
||||
};
|
||||
// No unsubstituted placeholders (the safety net + enrichment).
|
||||
// No unsubstituted placeholders.
|
||||
assert!(
|
||||
!error.contains("{table}") && !error.contains("{column}") && !error.contains("{value}"),
|
||||
"no unsubstituted placeholders; got: {error}"
|
||||
);
|
||||
// The real table + column are shown (resolved from the engine
|
||||
// message). The offending value is NOT shown: replay parses in
|
||||
// advanced mode → `SqlInsert`, whose values are raw SQL text (ADR-0033
|
||||
// verbatim execution), not retained typed values — so it degrades to
|
||||
// the neutral "that value" rather than leaking `{value}`.
|
||||
// The real table + column are shown (from the engine message), and —
|
||||
// since ADR-0036 Phase 1 retains the captured literal on the SQL
|
||||
// INSERT command — the **real offending value** is shown too (it used
|
||||
// to degrade to the neutral "that value" because `SqlInsert` discarded
|
||||
// its literals).
|
||||
assert!(error.contains("T.email"), "names the real table.column; got: {error}");
|
||||
assert!(error.contains("a@b.com"), "shows the real offending value; got: {error}");
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
Reference in New Issue
Block a user