-- -- UPGRADE_DISTRIBUTED_TRIGGERS_BEFORE -- -- PRE PG15, Renaming the parent triggers on partitioned tables doesn't -- recurse to renaming the child triggers on the partitions as well. -- -- this test is relevant only for pg14-15 upgrade -- SHOW server_version \gset SELECT substring(:'server_version', '\d+')::int = 14 AS server_version_eq_14 \gset \if :server_version_eq_14 \else \q \endif CREATE SCHEMA upgrade_distributed_triggers; SET search_path TO upgrade_distributed_triggers, public; SET citus.shard_count TO 4; SET citus.enable_unsafe_triggers TO true; SELECT run_command_on_workers('ALTER SYSTEM SET citus.enable_unsafe_triggers TO true;'); run_command_on_workers --------------------------------------------------------------------- (localhost,10201,t,"ALTER SYSTEM") (localhost,10202,t,"ALTER SYSTEM") (2 rows) SELECT run_command_on_workers('SELECT pg_reload_conf();'); run_command_on_workers --------------------------------------------------------------------- (localhost,10201,t,t) (localhost,10202,t,t) (2 rows) CREATE TABLE sale( sale_date date not null, state_code text, product_sku text, units integer) PARTITION BY list (state_code); ALTER TABLE sale ADD CONSTRAINT sale_pk PRIMARY KEY (state_code, sale_date); CREATE TABLE sale_newyork PARTITION OF sale FOR VALUES IN ('NY'); CREATE TABLE record_sale( operation_type text not null, product_sku text, state_code text, units integer, PRIMARY KEY(state_code, product_sku, operation_type, units)); SELECT create_distributed_table('sale', 'state_code'); create_distributed_table --------------------------------------------------------------------- (1 row) CREATE TABLE sale_california PARTITION OF sale FOR VALUES IN ('CA'); SELECT create_distributed_table('record_sale', 'state_code', colocate_with := 'sale'); create_distributed_table --------------------------------------------------------------------- (1 row) CREATE OR REPLACE FUNCTION record_sale() RETURNS trigger AS $$ BEGIN INSERT INTO upgrade_distributed_triggers.record_sale(operation_type, product_sku, state_code, units) VALUES (TG_OP, NEW.product_sku, NEW.state_code, NEW.units); RETURN NULL; END; $$ LANGUAGE plpgsql; -- will rename this trigger CREATE TRIGGER record_sale_trigger AFTER INSERT OR UPDATE OR DELETE ON sale FOR EACH ROW EXECUTE FUNCTION upgrade_distributed_triggers.record_sale(); -- will rename this trigger CREATE TRIGGER another_trigger AFTER INSERT OR UPDATE OR DELETE ON sale FOR EACH ROW EXECUTE FUNCTION upgrade_distributed_triggers.record_sale(); -- won't rename this trigger CREATE TRIGGER not_renamed_trigger AFTER INSERT OR UPDATE OR DELETE ON sale FOR EACH ROW EXECUTE FUNCTION upgrade_distributed_triggers.record_sale(); -- Trigger function should appear on workers SELECT proname from pg_proc WHERE oid='upgrade_distributed_triggers.record_sale'::regproc; proname --------------------------------------------------------------------- record_sale (1 row) SELECT run_command_on_workers($$SELECT count(*) FROM pg_proc WHERE oid='upgrade_distributed_triggers.record_sale'::regproc$$); run_command_on_workers --------------------------------------------------------------------- (localhost,10201,t,1) (localhost,10202,t,1) (2 rows) -- Trigger should appear on workers SELECT tgrelid::regclass::text, tgname FROM pg_trigger WHERE tgname like 'record_sale_trigger%' ORDER BY 1,2; tgrelid | tgname --------------------------------------------------------------------- sale | record_sale_trigger sale_california | record_sale_trigger sale_newyork | record_sale_trigger (3 rows) SELECT run_command_on_workers($$SELECT count(*) FROM pg_trigger WHERE tgname like 'record_sale_trigger%';$$); run_command_on_workers --------------------------------------------------------------------- (localhost,10201,t,9) (localhost,10202,t,9) (2 rows) CREATE VIEW sale_triggers AS SELECT tgname, tgrelid::regclass, tgenabled FROM pg_trigger WHERE tgrelid::regclass::text like 'sale%' ORDER BY 1, 2; SELECT * FROM sale_triggers ORDER BY 1, 2; tgname | tgrelid | tgenabled --------------------------------------------------------------------- another_trigger | sale | O another_trigger | sale_newyork | O another_trigger | sale_california | O not_renamed_trigger | sale | O not_renamed_trigger | sale_newyork | O not_renamed_trigger | sale_california | O record_sale_trigger | sale | O record_sale_trigger | sale_newyork | O record_sale_trigger | sale_california | O truncate_trigger_xxxxxxx | sale | O truncate_trigger_xxxxxxx | sale_newyork | O truncate_trigger_xxxxxxx | sale_california | O (12 rows) -- rename the triggers - note that it doesn't rename the -- triggers on the partitions ALTER TRIGGER record_sale_trigger ON sale RENAME TO renamed_record_sale_trigger; SELECT tgrelid::regclass::text, tgname FROM pg_trigger WHERE tgname like 'record_sale_trigger%' ORDER BY 1,2; tgrelid | tgname --------------------------------------------------------------------- sale_california | record_sale_trigger sale_newyork | record_sale_trigger (2 rows) SELECT tgrelid::regclass::text, tgname FROM pg_trigger WHERE tgname like 'renamed_record_sale_trigger%' ORDER BY 1,2; tgrelid | tgname --------------------------------------------------------------------- sale | renamed_record_sale_trigger (1 row) SELECT run_command_on_workers($$SELECT count(*) FROM pg_trigger WHERE tgname like 'record_sale_trigger%';$$); run_command_on_workers --------------------------------------------------------------------- (localhost,10201,t,6) (localhost,10202,t,6) (2 rows) SELECT run_command_on_workers($$SELECT count(*) FROM pg_trigger WHERE tgname like 'renamed_record_sale_trigger%';$$); run_command_on_workers --------------------------------------------------------------------- (localhost,10201,t,3) (localhost,10202,t,3) (2 rows) ALTER TRIGGER another_trigger ON sale RENAME TO another_renamed_trigger; SELECT * FROM sale_triggers ORDER BY 1, 2; tgname | tgrelid | tgenabled --------------------------------------------------------------------- another_renamed_trigger | sale | O another_trigger | sale_newyork | O another_trigger | sale_california | O not_renamed_trigger | sale | O not_renamed_trigger | sale_newyork | O not_renamed_trigger | sale_california | O record_sale_trigger | sale_newyork | O record_sale_trigger | sale_california | O renamed_record_sale_trigger | sale | O truncate_trigger_xxxxxxx | sale | O truncate_trigger_xxxxxxx | sale_newyork | O truncate_trigger_xxxxxxx | sale_california | O (12 rows) -- although the child triggers haven't been renamed to -- another_renamed_trigger, they are dropped when the parent is dropped DROP TRIGGER another_renamed_trigger ON sale; SELECT * FROM sale_triggers ORDER BY 1, 2; tgname | tgrelid | tgenabled --------------------------------------------------------------------- not_renamed_trigger | sale | O not_renamed_trigger | sale_newyork | O not_renamed_trigger | sale_california | O record_sale_trigger | sale_newyork | O record_sale_trigger | sale_california | O renamed_record_sale_trigger | sale | O truncate_trigger_xxxxxxx | sale | O truncate_trigger_xxxxxxx | sale_newyork | O truncate_trigger_xxxxxxx | sale_california | O (9 rows) SELECT tgrelid::regclass::text, tgname FROM pg_trigger WHERE tgname like 'another_renamed_trigger%' ORDER BY 1,2; tgrelid | tgname --------------------------------------------------------------------- (0 rows) SELECT tgrelid::regclass::text, tgname FROM pg_trigger WHERE tgname like 'another_trigger%' ORDER BY 1,2; tgrelid | tgname --------------------------------------------------------------------- (0 rows) SELECT run_command_on_workers($$SELECT count(*) FROM pg_trigger WHERE tgname like 'another_renamed_trigger%';$$); run_command_on_workers --------------------------------------------------------------------- (localhost,10201,t,0) (localhost,10202,t,0) (2 rows) SELECT run_command_on_workers($$SELECT count(*) FROM pg_trigger WHERE tgname like 'another_trigger%';$$); run_command_on_workers --------------------------------------------------------------------- (localhost,10201,t,0) (localhost,10202,t,0) (2 rows) CREATE TRIGGER another_trigger AFTER INSERT OR UPDATE OR DELETE ON sale FOR EACH ROW EXECUTE FUNCTION upgrade_distributed_triggers.record_sale(); ALTER TRIGGER another_trigger ON sale RENAME TO another_renamed_trigger; SELECT * FROM sale_triggers ORDER BY 1, 2; tgname | tgrelid | tgenabled --------------------------------------------------------------------- another_renamed_trigger | sale | O another_trigger | sale_newyork | O another_trigger | sale_california | O not_renamed_trigger | sale | O not_renamed_trigger | sale_newyork | O not_renamed_trigger | sale_california | O record_sale_trigger | sale_newyork | O record_sale_trigger | sale_california | O renamed_record_sale_trigger | sale | O truncate_trigger_xxxxxxx | sale | O truncate_trigger_xxxxxxx | sale_newyork | O truncate_trigger_xxxxxxx | sale_california | O (12 rows)