mirror of https://github.com/citusdata/citus.git
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: 80ba4bb383538a2ee846fece6a7b8da9518b6866pull/6282/head
parent
317dda6af1
commit
9e2b96caa5
|
@ -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.
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -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)
|
||||
|
|
@ -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
|
|
@ -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;
|
|
@ -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;
|
Loading…
Reference in New Issue