diff --git a/replaceable_schema.sql b/replaceable_schema.sql index 7e0ae2e66..5d225a6a4 100644 --- a/replaceable_schema.sql +++ b/replaceable_schema.sql @@ -36,62 +36,42 @@ BEGIN END $$; --- Create functions that select both old and new rows in a trigger. Column 1 is `-1` if old and `1` if new, --- which can be used with `sum` to get the number to add to a count. Column 2 is the original row as a composite --- value. A separate function is called in each `IF` statement to prevent an error from referencing transition --- tables that don't exist. All of this could be one function, but that would require using `RETURN QUERY EXECUTE` --- instead of calls to separate functions because of PostgreSQL's limited polymorphism. Parsing and planning dynamic --- queries at runtime is worse for performance. -CREATE PROCEDURE r.combine_transition_tables_function (table_name text) -LANGUAGE plpgsql -AS $a$ +-- Selects both old and new rows in a trigger and allows using `sum(count_diff)` to get the number to add to a count +CREATE FUNCTION r.combine_transition_tables (tg_op text) + RETURNS SETOF record + LANGUAGE plpgsql + AS $$ BEGIN - EXECUTE replace($b$ - CREATE FUNCTION r.get_old_thing_rows () - RETURNS SETOF record - LANGUAGE plpgsql - AS $$ - BEGIN - RETURN QUERY SELECT -1, old_table FROM old_table; - RETURN; - END - $$; - CREATE FUNCTION r.get_new_thing_rows () - RETURNS SETOF record - LANGUAGE plpgsql - AS $$ - BEGIN - RETURN QUERY SELECT 1, new_table FROM new_table; - RETURN; - END - $$; - CREATE FUNCTION r.combine_thing_transition_tables (tg_op text) - RETURNS SETOF record - LANGUAGE plpgsql - AS $$ - BEGIN - IF (TG_OP IN ('UPDATE', 'DELETE')) THEN - RETURN QUERY SELECT * FROM r.get_old_thing_rows () AS (count_diff bigint, thing thing); - END IF; - IF (TG_OP IN ('UPDATE', 'INSERT')) THEN - RETURN QUERY SELECT * FROM r.get_new_thing_rows () AS (count_diff bigint, thing thing); - END IF; - RETURN; - END - $$; - $b$, 'thing', table_name); + IF (TG_OP = 'UPDATE') THEN + RETURN QUERY + SELECT + -1 AS count_diff, + old_table AS affected_row + FROM + old_table + UNION ALL + SELECT + 1 AS count_diff, + new_table AS affected_row + FROM + new_table; + ELSIF (TG_OP = 'INSERT') THEN + RETURN QUERY + SELECT + 1 AS count_diff, + * + FROM + new_table; + ELSE + RETURN QUERY + SELECT + -1 AS count_diff, + * + FROM + old_table; + END IF; END -$a$; - -CALL r.combine_transition_tables_function('comment'); - -CALL r.combine_transition_tables_function('community'); - -CALL r.combine_transition_tables_function('community_follower'); - -CALL r.combine_transition_tables_function('person'); - -CALL r.combine_transition_tables_function('post'); +$$; -- Creates triggers for all operation types, which can't be 1 trigger when transition tables are used CREATE PROCEDURE r.create_triggers (table_name text, function_name text) @@ -168,7 +148,7 @@ BEGIN sum(count_diff) FILTER (WHERE (thing_like).score = 1) AS upvotes, sum(count_diff) FILTER (WHERE (thing_like).score != 1) AS downvotes FROM - r.combine_thing_transition_tables (TG_OP) + r.combine_transition_tables (TG_OP) AS (count_diff bigint, thing_like thing_like) GROUP BY @@ -218,7 +198,7 @@ BEGIN (comment).local, sum(count_diff) AS comments FROM - r.combine_comment_transition_tables (TG_OP) + r.combine_transition_tables (TG_OP) AS (count_diff bigint, comment comment) WHERE @@ -321,7 +301,7 @@ BEGIN (post).local, sum(count_diff) AS posts FROM - r.combine_post_transition_tables (TG_OP) + r.combine_transition_tables (TG_OP) AS (count_diff bigint, post post) WHERE @@ -377,7 +357,7 @@ BEGIN SELECT sum(count_diff) AS communities FROM - r.combine_community_transition_tables (TG_OP) + r.combine_transition_tables (TG_OP) AS (count_diff bigint, community community) WHERE (community).local AND NOT ((community).deleted OR (community).removed)) AS diff; RETURN NULL; @@ -399,7 +379,7 @@ BEGIN SELECT sum(count_diff) AS users FROM - r.combine_person_transition_tables (TG_OP) + r.combine_transition_tables (TG_OP) AS (count_diff bigint, person person) WHERE (person).local) AS diff; RETURN NULL; @@ -470,7 +450,7 @@ BEGIN (community_follower).community_id, sum(count_diff) AS subscribers FROM - r.combine_community_follower_transition_tables (TG_OP) + r.combine_transition_tables (TG_OP) AS (count_diff bigint, community_follower community_follower) WHERE ( SELECT