Surfaced while reviewing #40, but it predates that change (traces back to v0.9.5). A PartiQL DELETE or UPDATE extracts the key from the WHERE clause but does not evaluate the remaining non-key predicates before acting.
Repro: DELETE FROM "t" WHERE pk = 'a' AND NOT begins_with(name, 'x') deletes the row keyed pk='a' even when name begins with x, i.e. when the filter should have excluded it. The same applies to UPDATE ... WHERE.
This is a data-correctness bug: a statement that should be a no-op (or should touch fewer rows) mutates data. The executor's DELETE/UPDATE paths use the key-equality extractor and skip the matches_where pass that SELECT runs.
Fix: evaluate the full condition set against each candidate row before deleting or updating it, as the SELECT path already does.
Surfaced while reviewing #40, but it predates that change (traces back to v0.9.5). A PartiQL
DELETEorUPDATEextracts the key from theWHEREclause but does not evaluate the remaining non-key predicates before acting.Repro:
DELETE FROM "t" WHERE pk = 'a' AND NOT begins_with(name, 'x')deletes the row keyedpk='a'even whennamebegins withx, i.e. when the filter should have excluded it. The same applies toUPDATE ... WHERE.This is a data-correctness bug: a statement that should be a no-op (or should touch fewer rows) mutates data. The executor's DELETE/UPDATE paths use the key-equality extractor and skip the
matches_wherepass thatSELECTruns.Fix: evaluate the full condition set against each candidate row before deleting or updating it, as the SELECT path already does.