test(buzz-db): detect SET( at a token boundary in UPDATE and DO UPDATE

Match the SET keyword at identifier boundaries in plain UPDATEs and in
ON CONFLICT ... DO UPDATE, so the multi-column SET(a, b) = ... spelling
without a space is parsed like SET (a, b). Add no-space fixtures for a
channels tuple UPDATE and an approval DO UPDATE SET(note) upsert.

Signed-off-by: Elrond <28d6302a099e5225b02c4155ac4236e4912603df2ab08dbfc2f4fef08ce598c8@buzz.block.builderlab.xyz>
This commit is contained in:
Elrond
2026-10-16 15:50:55 -04:00
committed by Luke Tornquist
parent 927a94a1eb
commit 36af50e01a

View File

@@ -2264,11 +2264,10 @@ fn sql_update_sets<'a>(source: &'a str, table: &str) -> Vec<(&'a str, &'a str)>
.into_iter()
.filter_map(|rest| {
let rest = rest.split(['"', ';']).next()?.trim_start();
rest.strip_prefix("set ").or_else(|| {
// UPDATE table [AS] alias SET ...
let (alias, set) = rest.split_once(" set ")?;
(alias.split_whitespace().count() <= 2).then_some(set)
})
// UPDATE table [[AS] alias] SET ..., including SET(a, b) = ...
let set = *sql_token_suffixes(rest, "set").first()?;
let alias = &rest[..rest.len() - set.len() - "set".len()];
(alias.split_whitespace().count() <= 2).then_some(set.trim_start())
});
let conflict_updates = sql_table_suffixes(source, "insert into", table)
.into_iter()
@@ -2722,6 +2721,7 @@ fn single_table_policy_rejects_implicit_community_insert_columns() {
fn single_table_policy_checks_tuple_assignments() {
for (sql, reason) in [
("UPDATE channels SET (name, community_id) = ($1, $2) WHERE id = $3", "channels.community_id UPDATE"),
("UPDATE channels SET(name, community_id) = ($1, $2) WHERE id = $3", "channels.community_id UPDATE"),
("UPDATE communities SET (icon, deletion_state) = (NULL, 'active') WHERE id = $1 AND deletion_state = 'active'", "lifecycle UPDATE"),
("UPDATE community_deletion_requests SET (stage, community_id) = ($1, $2) WHERE id = $3", "identity/provenance UPDATE"),
("UPDATE community_deletion_requests SET (inventory_digest, inventory_manifest) = (NULL, NULL) WHERE id = $1", "inventory_frozen_at IS NULL"),
@@ -2808,6 +2808,7 @@ fn single_table_policy_rejects_approval_mutations() {
"DELETE FROM community_deletion_approvals WHERE request_id = $1",
"INSERT INTO community_deletion_approvals (request_id, note) VALUES ($1, $2) ON CONFLICT (request_id) DO UPDATE SET note = EXCLUDED.note",
"INSERT INTO community_deletion_approvals (request_id, note) VALUES ($1, $2) ON CONFLICT(request_id) DO UPDATE SET note = EXCLUDED.note",
"INSERT INTO community_deletion_approvals (request_id, note) VALUES ($1, $2) ON CONFLICT(request_id) DO UPDATE SET(note) = ROW(EXCLUDED.note)",
] {
let source = format!("async fn bypass() {{ query(\"{sql}\"); }}");
assert_eq!(