Add pg14->pg15 upgrade test for dist. triggers on part. tables (#6265)

PRE PG15, Renaming the parent triggers on partitioned tables doesn't
recurse to renaming the child triggers on the partitions as well.
In PG15, Renaming triggers on partitioned tables
recurses to renaming the triggers on the partitions as well.

Add an upgrade test to make sure we are not breaking anything
with distributed triggers on distributed partitioned tables.

Relevant PG commit:
80ba4bb383538a2ee846fece6a7b8da9518b6866
pull/6282/head
Naisila Puka 2022-09-01 12:32:44 +03:00 committed by GitHub
parent 317dda6af1
commit 9e2b96caa5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 689 additions and 1 deletions

View File

@ -1,4 +1,4 @@
test: upgrade_basic_after upgrade_type_after upgrade_ref2ref_after upgrade_distributed_function_after upgrade_rebalance_strategy_after upgrade_list_citus_objects upgrade_autoconverted_after upgrade_citus_stat_activity upgrade_citus_locks
test: upgrade_basic_after upgrade_type_after upgrade_ref2ref_after upgrade_distributed_function_after upgrade_rebalance_strategy_after upgrade_list_citus_objects upgrade_autoconverted_after upgrade_citus_stat_activity upgrade_citus_locks upgrade_distributed_triggers_after
# This attempts dropping citus extension (and rollbacks), so please do
# not run in parallel with any other tests.

View File

@ -8,6 +8,7 @@ test: upgrade_distributed_function_before upgrade_rebalance_strategy_before
test: upgrade_autoconverted_before
test: upgrade_citus_stat_activity
test: upgrade_citus_locks
test: upgrade_distributed_triggers_before
# upgrade_columnar_before renames public schema to citus_schema, so let's
# run this test as the last one.

View File

@ -0,0 +1,226 @@
--
-- UPGRADE_DISTRIBUTED_TRIGGERS_AFTER
--
-- In PG15, Renaming triggers on partitioned tables
-- recurses to renaming the triggers on the partitions as well.
-- Relevant PG commit:
-- 80ba4bb383538a2ee846fece6a7b8da9518b6866
--
-- this test is relevant only for pg14-15 upgrade
--
SHOW server_version \gset
SELECT substring(:'server_version', '\d+')::int = 15 AS server_version_eq_15
\gset
\if :server_version_eq_15
\else
\q
\endif
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)
-- after PG15 upgrade, all child triggers have the same name with the parent triggers
-- check that the workers are also updated
SELECT * FROM sale_triggers ORDER BY 1, 2;
tgname | tgrelid | tgenabled
---------------------------------------------------------------------
another_renamed_trigger | sale | O
another_renamed_trigger | sale_newyork | O
another_renamed_trigger | sale_california | O
not_renamed_trigger | sale | O
not_renamed_trigger | sale_newyork | O
not_renamed_trigger | sale_california | O
renamed_record_sale_trigger | sale | O
renamed_record_sale_trigger | sale_newyork | O
renamed_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)
SELECT tgrelid::regclass::text, tgname FROM pg_trigger WHERE tgname like 'record_sale_trigger%' ORDER BY 1,2;
tgrelid | tgname
---------------------------------------------------------------------
(0 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
sale_california | renamed_record_sale_trigger
sale_newyork | renamed_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,0)
(localhost,10202,t,0)
(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,9)
(localhost,10202,t,9)
(2 rows)
-- create another partition to verify that all is safe and sound
CREATE TABLE sale_alabama PARTITION OF sale FOR VALUES IN ('AL');
SELECT * FROM sale_triggers ORDER BY 1, 2;
tgname | tgrelid | tgenabled
---------------------------------------------------------------------
another_renamed_trigger | sale | O
another_renamed_trigger | sale_newyork | O
another_renamed_trigger | sale_california | O
another_renamed_trigger | sale_alabama | O
not_renamed_trigger | sale | O
not_renamed_trigger | sale_newyork | O
not_renamed_trigger | sale_california | O
not_renamed_trigger | sale_alabama | O
renamed_record_sale_trigger | sale | O
renamed_record_sale_trigger | sale_newyork | O
renamed_record_sale_trigger | sale_california | O
renamed_record_sale_trigger | sale_alabama | O
truncate_trigger_xxxxxxx | sale | O
truncate_trigger_xxxxxxx | sale_newyork | O
truncate_trigger_xxxxxxx | sale_california | O
truncate_trigger_xxxxxxx | sale_alabama | O
(16 rows)
SELECT tgrelid::regclass::text, tgname FROM pg_trigger WHERE tgname like 'record_sale_trigger%' ORDER BY 1,2;
tgrelid | tgname
---------------------------------------------------------------------
(0 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
sale_alabama | renamed_record_sale_trigger
sale_california | renamed_record_sale_trigger
sale_newyork | renamed_record_sale_trigger
(4 rows)
SELECT run_command_on_workers($$SELECT count(*) FROM pg_trigger WHERE tgname like 'record_sale_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 'renamed_record_sale_trigger%';$$);
run_command_on_workers
---------------------------------------------------------------------
(localhost,10201,t,12)
(localhost,10202,t,12)
(2 rows)
-- drop a trigger to verify that all is safe and sound
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
not_renamed_trigger | sale_alabama | O
renamed_record_sale_trigger | sale | O
renamed_record_sale_trigger | sale_newyork | O
renamed_record_sale_trigger | sale_california | O
renamed_record_sale_trigger | sale_alabama | O
truncate_trigger_xxxxxxx | sale | O
truncate_trigger_xxxxxxx | sale_newyork | O
truncate_trigger_xxxxxxx | sale_california | O
truncate_trigger_xxxxxxx | sale_alabama | O
(12 rows)
-- rename a trigger - note that it also renames the triggers on the partitions
ALTER TRIGGER "renamed_record_sale_trigger" ON "sale" RENAME TO "final_renamed_record_sale_trigger";
SELECT * FROM sale_triggers ORDER BY 1, 2;
tgname | tgrelid | tgenabled
---------------------------------------------------------------------
final_renamed_record_sale_trigger | sale | O
final_renamed_record_sale_trigger | sale_newyork | O
final_renamed_record_sale_trigger | sale_california | O
final_renamed_record_sale_trigger | sale_alabama | O
not_renamed_trigger | sale | O
not_renamed_trigger | sale_newyork | O
not_renamed_trigger | sale_california | O
not_renamed_trigger | sale_alabama | O
truncate_trigger_xxxxxxx | sale | O
truncate_trigger_xxxxxxx | sale_newyork | O
truncate_trigger_xxxxxxx | sale_california | O
truncate_trigger_xxxxxxx | sale_alabama | O
(12 rows)
SELECT tgrelid::regclass::text, tgname FROM pg_trigger WHERE tgname like 'renamed_record_sale_trigger%' ORDER BY 1,2;
tgrelid | tgname
---------------------------------------------------------------------
(0 rows)
SELECT tgrelid::regclass::text, tgname FROM pg_trigger WHERE tgname like 'final_renamed_record_sale_trigger%' ORDER BY 1,2;
tgrelid | tgname
---------------------------------------------------------------------
sale | final_renamed_record_sale_trigger
sale_alabama | final_renamed_record_sale_trigger
sale_california | final_renamed_record_sale_trigger
sale_newyork | final_renamed_record_sale_trigger
(4 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,0)
(localhost,10202,t,0)
(2 rows)
SELECT run_command_on_workers($$SELECT count(*) FROM pg_trigger WHERE tgname like 'final_renamed_record_sale_trigger%';$$);
run_command_on_workers
---------------------------------------------------------------------
(localhost,10201,t,12)
(localhost,10202,t,12)
(2 rows)
DROP TRIGGER final_renamed_record_sale_trigger ON sale;
-- create another trigger and rename it
CREATE TRIGGER yet_another_trigger
AFTER INSERT OR UPDATE OR DELETE ON sale
FOR EACH ROW EXECUTE FUNCTION upgrade_distributed_triggers.record_sale();
ALTER TRIGGER "yet_another_trigger" ON "sale" RENAME TO "renamed_yet_another_trigger";
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
not_renamed_trigger | sale_alabama | O
renamed_yet_another_trigger | sale | O
renamed_yet_another_trigger | sale_newyork | O
renamed_yet_another_trigger | sale_california | O
renamed_yet_another_trigger | sale_alabama | O
truncate_trigger_xxxxxxx | sale | O
truncate_trigger_xxxxxxx | sale_newyork | O
truncate_trigger_xxxxxxx | sale_california | O
truncate_trigger_xxxxxxx | sale_alabama | O
(12 rows)
DROP SCHEMA upgrade_distributed_triggers CASCADE;
NOTICE: drop cascades to 4 other objects
DETAIL: drop cascades to function record_sale()
drop cascades to table sale
drop cascades to table record_sale
drop cascades to view sale_triggers

View File

@ -0,0 +1,16 @@
--
-- UPGRADE_DISTRIBUTED_TRIGGERS_AFTER
--
-- In PG15, Renaming triggers on partitioned tables
-- recurses to renaming the triggers on the partitions as well.
-- Relevant PG commit:
-- 80ba4bb383538a2ee846fece6a7b8da9518b6866
--
-- this test is relevant only for pg14-15 upgrade
--
SHOW server_version \gset
SELECT substring(:'server_version', '\d+')::int = 15 AS server_version_eq_15
\gset
\if :server_version_eq_15
\else
\q

View File

@ -0,0 +1,243 @@
--
-- 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)

View File

@ -0,0 +1,14 @@
--
-- 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

View File

@ -0,0 +1,72 @@
--
-- UPGRADE_DISTRIBUTED_TRIGGERS_AFTER
--
-- In PG15, Renaming triggers on partitioned tables
-- recurses to renaming the triggers on the partitions as well.
-- Relevant PG commit:
-- 80ba4bb383538a2ee846fece6a7b8da9518b6866
--
-- this test is relevant only for pg14-15 upgrade
--
SHOW server_version \gset
SELECT substring(:'server_version', '\d+')::int = 15 AS server_version_eq_15
\gset
\if :server_version_eq_15
\else
\q
\endif
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;');
SELECT run_command_on_workers('SELECT pg_reload_conf();');
-- after PG15 upgrade, all child triggers have the same name with the parent triggers
-- check that the workers are also updated
SELECT * FROM sale_triggers ORDER BY 1, 2;
SELECT tgrelid::regclass::text, tgname FROM pg_trigger WHERE tgname like 'record_sale_trigger%' ORDER BY 1,2;
SELECT tgrelid::regclass::text, tgname FROM pg_trigger WHERE tgname like 'renamed_record_sale_trigger%' ORDER BY 1,2;
SELECT run_command_on_workers($$SELECT count(*) FROM pg_trigger WHERE tgname like 'record_sale_trigger%';$$);
SELECT run_command_on_workers($$SELECT count(*) FROM pg_trigger WHERE tgname like 'renamed_record_sale_trigger%';$$);
-- create another partition to verify that all is safe and sound
CREATE TABLE sale_alabama PARTITION OF sale FOR VALUES IN ('AL');
SELECT * FROM sale_triggers ORDER BY 1, 2;
SELECT tgrelid::regclass::text, tgname FROM pg_trigger WHERE tgname like 'record_sale_trigger%' ORDER BY 1,2;
SELECT tgrelid::regclass::text, tgname FROM pg_trigger WHERE tgname like 'renamed_record_sale_trigger%' ORDER BY 1,2;
SELECT run_command_on_workers($$SELECT count(*) FROM pg_trigger WHERE tgname like 'record_sale_trigger%';$$);
SELECT run_command_on_workers($$SELECT count(*) FROM pg_trigger WHERE tgname like 'renamed_record_sale_trigger%';$$);
-- drop a trigger to verify that all is safe and sound
DROP TRIGGER another_renamed_trigger ON sale;
SELECT * FROM sale_triggers ORDER BY 1, 2;
-- rename a trigger - note that it also renames the triggers on the partitions
ALTER TRIGGER "renamed_record_sale_trigger" ON "sale" RENAME TO "final_renamed_record_sale_trigger";
SELECT * FROM sale_triggers ORDER BY 1, 2;
SELECT tgrelid::regclass::text, tgname FROM pg_trigger WHERE tgname like 'renamed_record_sale_trigger%' ORDER BY 1,2;
SELECT tgrelid::regclass::text, tgname FROM pg_trigger WHERE tgname like 'final_renamed_record_sale_trigger%' ORDER BY 1,2;
SELECT run_command_on_workers($$SELECT count(*) FROM pg_trigger WHERE tgname like 'renamed_record_sale_trigger%';$$);
SELECT run_command_on_workers($$SELECT count(*) FROM pg_trigger WHERE tgname like 'final_renamed_record_sale_trigger%';$$);
DROP TRIGGER final_renamed_record_sale_trigger ON sale;
-- create another trigger and rename it
CREATE TRIGGER yet_another_trigger
AFTER INSERT OR UPDATE OR DELETE ON sale
FOR EACH ROW EXECUTE FUNCTION upgrade_distributed_triggers.record_sale();
ALTER TRIGGER "yet_another_trigger" ON "sale" RENAME TO "renamed_yet_another_trigger";
SELECT * FROM sale_triggers ORDER BY 1, 2;
DROP SCHEMA upgrade_distributed_triggers CASCADE;

View File

@ -0,0 +1,116 @@
--
-- 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;');
SELECT run_command_on_workers('SELECT pg_reload_conf();');
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 TABLE sale_california PARTITION OF sale FOR VALUES IN ('CA');
SELECT create_distributed_table('record_sale', 'state_code', colocate_with := 'sale');
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;
SELECT run_command_on_workers($$SELECT count(*) FROM pg_proc WHERE oid='upgrade_distributed_triggers.record_sale'::regproc$$);
-- Trigger should appear on workers
SELECT tgrelid::regclass::text, tgname FROM pg_trigger WHERE tgname like 'record_sale_trigger%' ORDER BY 1,2;
SELECT run_command_on_workers($$SELECT count(*) FROM pg_trigger WHERE tgname like 'record_sale_trigger%';$$);
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;
-- 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;
SELECT tgrelid::regclass::text, tgname FROM pg_trigger WHERE tgname like 'renamed_record_sale_trigger%' ORDER BY 1,2;
SELECT run_command_on_workers($$SELECT count(*) FROM pg_trigger WHERE tgname like 'record_sale_trigger%';$$);
SELECT run_command_on_workers($$SELECT count(*) FROM pg_trigger WHERE tgname like 'renamed_record_sale_trigger%';$$);
ALTER TRIGGER another_trigger ON sale RENAME TO another_renamed_trigger;
SELECT * FROM sale_triggers ORDER BY 1, 2;
-- 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;
SELECT tgrelid::regclass::text, tgname FROM pg_trigger WHERE tgname like 'another_renamed_trigger%' ORDER BY 1,2;
SELECT tgrelid::regclass::text, tgname FROM pg_trigger WHERE tgname like 'another_trigger%' ORDER BY 1,2;
SELECT run_command_on_workers($$SELECT count(*) FROM pg_trigger WHERE tgname like 'another_renamed_trigger%';$$);
SELECT run_command_on_workers($$SELECT count(*) FROM pg_trigger WHERE tgname like 'another_trigger%';$$);
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;