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:
@@ -356,6 +356,21 @@ fn walk_punct(
|
||||
) -> NodeWalkResult {
|
||||
let bytes = source.as_bytes();
|
||||
if position < bytes.len() && bytes[position] == ch as u8 {
|
||||
// ADR-0033 Amendment 4: a `-` does not match when it begins an
|
||||
// adjacent `--`. The playground supports no `--` line comment, and
|
||||
// `--` is the DSL flag marker (e.g. `--all-rows`); treating `--`
|
||||
// as two minus operators silently mis-parsed `set x = 42
|
||||
// --all-rows` as arithmetic over phantom columns `all`/`rows`.
|
||||
// Refusing here makes the SQL expression stop, so the SQL shape
|
||||
// fails and dispatch falls back to the DSL flag. Spaced `- -3` is
|
||||
// unaffected (the dashes are not adjacent). `Node::Punct('-')` is
|
||||
// used only by the SQL expression grammar, so this is scoped to it.
|
||||
if ch == '-' && bytes.get(position + 1) == Some(&b'-') {
|
||||
return NodeWalkResult::NoMatch {
|
||||
position,
|
||||
expected: vec![Expectation::Punct(ch)],
|
||||
};
|
||||
}
|
||||
path.push(MatchedItem {
|
||||
kind: MatchedKind::Punct(ch),
|
||||
text: ch.to_string(),
|
||||
|
||||
Reference in New Issue
Block a user