fix: update … --all-rows falls back to the DSL instead of misparsing (ADR-0033 Am4)
Advanced-mode `update T set x = 42 --all-rows` parsed the `--all-rows`
DSL flag as the arithmetic `42 - -all - rows` over phantom columns
`all`/`rows` (Amendment 3's counter-example), masked only by the engine's
`--` comment leniency. The playground supports no `--` line comment, so
this was a misparse (ADR-0027: flag input known to fail at runtime).
Fix: walk_punct refuses a `-` that begins an adjacent `--`. Only the SQL
expression uses Node::Punct('-'), so this is scoped to it. The SET
expression then stops, the SQL UPDATE shape fails, and dispatch falls
back to the DSL Update { AllRows } — symmetry with delete … --all-rows.
Behaviour: `42 --all-rows` → DSL Update{AllRows}; spaced `42 - -3` stays
SqlUpdate (= 45, preserved); adjacent `42--3` → parse error (contrived;
no `--` comment support).
Tests: inverted parse test (+ arithmetic-preserved + adjacent-error
assertions); new full-pipeline update_all_rows_flag_in_advanced_updates_every_row.
Suite 1963/0/1; clippy clean.
This commit is contained in:
@@ -488,3 +488,38 @@ fn advanced_update_set_expression_still_parses_via_sql_expr() {
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// =================================================================
|
||||
// ADR-0033 Amendment 4 — `update … --all-rows` falls back to the DSL
|
||||
// =================================================================
|
||||
|
||||
#[test]
|
||||
fn update_all_rows_flag_in_advanced_updates_every_row() {
|
||||
// `update … --all-rows` falls back to the DSL Update { AllRows } in
|
||||
// advanced mode (run_replay parses each line in advanced mode) and
|
||||
// updates every row — the full pipeline end to end, not just the
|
||||
// parse-level dispatch (covered in tests/sql_dml_e2e.rs).
|
||||
let (project, db, _dir) = open_project_db();
|
||||
let rt = rt();
|
||||
create_cols(&db, &rt, "t", &[("id", Type::Int), ("v", Type::Int)], &["id"]);
|
||||
seed(&db, &rt, "insert into t (id, v) values (1, 1), (2, 2)", "t");
|
||||
std::fs::write(
|
||||
project.path().join("allrows.commands"),
|
||||
"update t set v = 9 --all-rows\n",
|
||||
)
|
||||
.expect("write script");
|
||||
let events = rt.block_on(run_replay(&db, project.path(), "allrows.commands"));
|
||||
assert!(
|
||||
matches!(events.last(), Some(AppEvent::ReplayCompleted { count: 1, .. })),
|
||||
"the --all-rows update replays through the DSL fall-back; events: {events:?}"
|
||||
);
|
||||
let rows = rt
|
||||
.block_on(db.query_data("t".to_string(), None, None, None))
|
||||
.expect("query")
|
||||
.rows;
|
||||
assert_eq!(rows.len(), 2, "both rows present");
|
||||
assert!(
|
||||
rows.iter().all(|r| r[1].as_deref() == Some("9")),
|
||||
"every row's v set to 9 (all-rows update); rows: {rows:?}"
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user