Prevent incorrectly using delete instead of uplete (#5331)

* implement check and test it by modifying PostLike::remove

* revert change in PostLike::remove
This commit is contained in:
dullbananas 2025-01-21 07:52:18 -07:00 committed by GitHub
parent edb063f288
commit 6f05254aae
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 42 additions and 1 deletions

View file

@ -889,3 +889,41 @@ CALL r.create_inbox_combined_trigger ('person_post_mention');
CALL r.create_inbox_combined_trigger ('private_message');
-- Prevent using delete instead of uplete on action tables
CREATE FUNCTION r.require_uplete ()
RETURNS TRIGGER
LANGUAGE plpgsql
AS $$
BEGIN
IF pg_trigger_depth() = 1 AND NOT starts_with (current_query(), '/**/') THEN
RAISE 'using delete instead of uplete is not allowed for this table';
END IF;
RETURN NULL;
END
$$;
CREATE TRIGGER require_uplete
BEFORE DELETE ON comment_actions
FOR EACH STATEMENT
EXECUTE FUNCTION r.require_uplete ();
CREATE TRIGGER require_uplete
BEFORE DELETE ON community_actions
FOR EACH STATEMENT
EXECUTE FUNCTION r.require_uplete ();
CREATE TRIGGER require_uplete
BEFORE DELETE ON instance_actions
FOR EACH STATEMENT
EXECUTE FUNCTION r.require_uplete ();
CREATE TRIGGER require_uplete
BEFORE DELETE ON person_actions
FOR EACH STATEMENT
EXECUTE FUNCTION r.require_uplete ();
CREATE TRIGGER require_uplete
BEFORE DELETE ON post_actions
FOR EACH STATEMENT
EXECUTE FUNCTION r.require_uplete ();

View file

@ -121,6 +121,9 @@ impl QueryFragment<Pg> for UpleteQuery {
fn walk_ast<'b>(&'b self, mut out: AstPass<'_, 'b, Pg>) -> Result<(), Error> {
assert_ne!(self.set_null_columns.len(), 0, "`set_null` was not called");
// This is checked by require_uplete triggers
out.push_sql("/**/");
// Declare `update_keys` and `delete_keys` CTEs, which select primary keys
for (prefix, subquery) in [
("WITH update_keys", &self.update_subquery),
@ -357,7 +360,7 @@ mod tests {
let update_count = "SELECT count(*) FROM update_result";
let delete_count = "SELECT count(*) FROM delete_result";
format!(r#"WITH {with_queries} SELECT ({update_count}), ({delete_count}) -- binds: []"#)
format!(r#"/**/WITH {with_queries} SELECT ({update_count}), ({delete_count}) -- binds: []"#)
}
#[test]