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:
claude@clouddev1
2026-05-27 21:25:02 +00:00
parent 338dc8a4cf
commit 9a23e28f30
3 changed files with 78 additions and 8 deletions
+28 -8
View File
@@ -31,7 +31,9 @@ use rdbms_playground::app::App;
use rdbms_playground::db::{Database, DbError, DeleteResult, InsertResult, UpdateResult};
use rdbms_playground::dsl::parser::parse_command_in_mode;
use rdbms_playground::dsl::walker::Severity;
use rdbms_playground::dsl::{ColumnSpec, Command, ReferentialAction, Type, parse_command};
use rdbms_playground::dsl::{
ColumnSpec, Command, ReferentialAction, RowFilter, Type, parse_command,
};
use rdbms_playground::event::AppEvent;
use rdbms_playground::mode::Mode;
use rdbms_playground::persistence::Persistence;
@@ -513,18 +515,36 @@ fn e2e_single_dml_statement_with_trailing_semicolon_parses() {
}
#[test]
fn e2e_update_all_rows_in_advanced_does_not_fall_back_to_dsl() {
// ADR-0033 Amendment 3 counter-example: the SQL `UPDATE`'s
// `SET <expr>` absorbs `--all-rows` (as `42 - -all - rows`), so
// the SQL shape matches and there is no DSL fall-back. (Harmless
// at execution — the engine treats `--all-rows` as a line
// comment.)
fn e2e_update_all_rows_in_advanced_falls_back_to_dsl() {
// ADR-0033 Amendment 4 reverses Amendment 3's counter-example: the
// SQL `UPDATE`'s `SET` expression must NOT consume the DSL flag
// `--all-rows`. An adjacent `--` is not two minus operators — the
// playground has no `--` line comment — so the SQL shape fails and
// dispatch falls back to the DSL `Update { AllRows }`, mirroring
// `delete … --all-rows`.
assert!(
matches!(
parse_command_in_mode("update Orders set total = 42 --all-rows", Mode::Advanced),
Ok(Command::Update { filter: RowFilter::AllRows, .. })
),
"advanced `update … --all-rows` falls back to the DSL Update",
);
// Legitimate spaced arithmetic is unaffected — the dashes are not
// adjacent, so this stays a SQL UPDATE (total = 42 - (-3) = 45).
assert!(
matches!(
parse_command_in_mode("update Orders set total = 42 - -3", Mode::Advanced),
Ok(Command::SqlUpdate { .. })
),
"advanced `update … --all-rows` stays SQL (no DSL fall-back)",
"spaced `42 - -3` stays a SQL UPDATE",
);
// An adjacent `--` before a number is no longer silently accepted as
// arithmetic; with no `--all-rows` flag to fall back to, it is a
// parse error (acceptable per Amendment 4 — contrived input, and the
// playground does not support `--` comments).
assert!(
parse_command_in_mode("update Orders set total = 42--3", Mode::Advanced).is_err(),
"adjacent `42--3` is a parse error (no `--` comment support)",
);
}