mirror of
https://github.com/postgres/postgres.git
synced 2025-09-03 15:22:11 +03:00
Preserve firing-on state when cloning row triggers to partitions
When triggers are cloned from partitioned tables to their partitions,
the 'tgenabled' flag (origin/replica/always/disable) was not propagated.
Make it so that the flag on the trigger on partition is initially set to
the same value as on the partitioned table.
Add a test case to verify the behavior.
Backpatch to 11, where this appeared in commit 86f575948c
.
Author: Álvaro Herrera <alvherre@alvh.no-ip.org>
Reported-by: Justin Pryzby <pryzby@telsasoft.com>
Discussion: https://postgr.es/m/20200930223450.GA14848@telsasoft.com
This commit is contained in:
@@ -2661,6 +2661,62 @@ select tgrelid::regclass, tgname, tgenabled from pg_trigger
|
||||
(2 rows)
|
||||
|
||||
drop table parent, child1;
|
||||
-- Verify that firing state propagates correctly on creation, too
|
||||
CREATE TABLE trgfire (i int) PARTITION BY RANGE (i);
|
||||
CREATE TABLE trgfire1 PARTITION OF trgfire FOR VALUES FROM (1) TO (10);
|
||||
CREATE OR REPLACE FUNCTION tgf() RETURNS trigger LANGUAGE plpgsql
|
||||
AS $$ begin raise exception 'except'; end $$;
|
||||
CREATE TRIGGER tg AFTER INSERT ON trgfire FOR EACH ROW EXECUTE FUNCTION tgf();
|
||||
INSERT INTO trgfire VALUES (1);
|
||||
ERROR: except
|
||||
CONTEXT: PL/pgSQL function tgf() line 1 at RAISE
|
||||
ALTER TABLE trgfire DISABLE TRIGGER tg;
|
||||
INSERT INTO trgfire VALUES (1);
|
||||
CREATE TABLE trgfire2 PARTITION OF trgfire FOR VALUES FROM (10) TO (20);
|
||||
INSERT INTO trgfire VALUES (11);
|
||||
CREATE TABLE trgfire3 (LIKE trgfire);
|
||||
ALTER TABLE trgfire ATTACH PARTITION trgfire3 FOR VALUES FROM (20) TO (30);
|
||||
INSERT INTO trgfire VALUES (21);
|
||||
CREATE TABLE trgfire4 PARTITION OF trgfire FOR VALUES FROM (30) TO (40) PARTITION BY LIST (i);
|
||||
CREATE TABLE trgfire4_30 PARTITION OF trgfire4 FOR VALUES IN (30);
|
||||
INSERT INTO trgfire VALUES (30);
|
||||
CREATE TABLE trgfire5 (LIKE trgfire) PARTITION BY LIST (i);
|
||||
CREATE TABLE trgfire5_40 PARTITION OF trgfire5 FOR VALUES IN (40);
|
||||
ALTER TABLE trgfire ATTACH PARTITION trgfire5 FOR VALUES FROM (40) TO (50);
|
||||
INSERT INTO trgfire VALUES (40);
|
||||
SELECT tgrelid::regclass, tgenabled FROM pg_trigger
|
||||
WHERE tgrelid::regclass IN (SELECT oid from pg_class where relname LIKE 'trgfire%')
|
||||
ORDER BY tgrelid::regclass::text;
|
||||
tgrelid | tgenabled
|
||||
-------------+-----------
|
||||
trgfire | D
|
||||
trgfire1 | D
|
||||
trgfire2 | D
|
||||
trgfire3 | D
|
||||
trgfire4 | D
|
||||
trgfire4_30 | D
|
||||
trgfire5 | D
|
||||
trgfire5_40 | D
|
||||
(8 rows)
|
||||
|
||||
ALTER TABLE trgfire ENABLE TRIGGER tg;
|
||||
INSERT INTO trgfire VALUES (1);
|
||||
ERROR: except
|
||||
CONTEXT: PL/pgSQL function tgf() line 1 at RAISE
|
||||
INSERT INTO trgfire VALUES (11);
|
||||
ERROR: except
|
||||
CONTEXT: PL/pgSQL function tgf() line 1 at RAISE
|
||||
INSERT INTO trgfire VALUES (21);
|
||||
ERROR: except
|
||||
CONTEXT: PL/pgSQL function tgf() line 1 at RAISE
|
||||
INSERT INTO trgfire VALUES (30);
|
||||
ERROR: except
|
||||
CONTEXT: PL/pgSQL function tgf() line 1 at RAISE
|
||||
INSERT INTO trgfire VALUES (40);
|
||||
ERROR: except
|
||||
CONTEXT: PL/pgSQL function tgf() line 1 at RAISE
|
||||
DROP TABLE trgfire;
|
||||
DROP FUNCTION tgf();
|
||||
--
|
||||
-- Test the interaction between transition tables and both kinds of
|
||||
-- inheritance. We'll dump the contents of the transition tables in a
|
||||
|
@@ -1836,6 +1836,38 @@ select tgrelid::regclass, tgname, tgenabled from pg_trigger
|
||||
order by tgrelid::regclass::text;
|
||||
drop table parent, child1;
|
||||
|
||||
-- Verify that firing state propagates correctly on creation, too
|
||||
CREATE TABLE trgfire (i int) PARTITION BY RANGE (i);
|
||||
CREATE TABLE trgfire1 PARTITION OF trgfire FOR VALUES FROM (1) TO (10);
|
||||
CREATE OR REPLACE FUNCTION tgf() RETURNS trigger LANGUAGE plpgsql
|
||||
AS $$ begin raise exception 'except'; end $$;
|
||||
CREATE TRIGGER tg AFTER INSERT ON trgfire FOR EACH ROW EXECUTE FUNCTION tgf();
|
||||
INSERT INTO trgfire VALUES (1);
|
||||
ALTER TABLE trgfire DISABLE TRIGGER tg;
|
||||
INSERT INTO trgfire VALUES (1);
|
||||
CREATE TABLE trgfire2 PARTITION OF trgfire FOR VALUES FROM (10) TO (20);
|
||||
INSERT INTO trgfire VALUES (11);
|
||||
CREATE TABLE trgfire3 (LIKE trgfire);
|
||||
ALTER TABLE trgfire ATTACH PARTITION trgfire3 FOR VALUES FROM (20) TO (30);
|
||||
INSERT INTO trgfire VALUES (21);
|
||||
CREATE TABLE trgfire4 PARTITION OF trgfire FOR VALUES FROM (30) TO (40) PARTITION BY LIST (i);
|
||||
CREATE TABLE trgfire4_30 PARTITION OF trgfire4 FOR VALUES IN (30);
|
||||
INSERT INTO trgfire VALUES (30);
|
||||
CREATE TABLE trgfire5 (LIKE trgfire) PARTITION BY LIST (i);
|
||||
CREATE TABLE trgfire5_40 PARTITION OF trgfire5 FOR VALUES IN (40);
|
||||
ALTER TABLE trgfire ATTACH PARTITION trgfire5 FOR VALUES FROM (40) TO (50);
|
||||
INSERT INTO trgfire VALUES (40);
|
||||
SELECT tgrelid::regclass, tgenabled FROM pg_trigger
|
||||
WHERE tgrelid::regclass IN (SELECT oid from pg_class where relname LIKE 'trgfire%')
|
||||
ORDER BY tgrelid::regclass::text;
|
||||
ALTER TABLE trgfire ENABLE TRIGGER tg;
|
||||
INSERT INTO trgfire VALUES (1);
|
||||
INSERT INTO trgfire VALUES (11);
|
||||
INSERT INTO trgfire VALUES (21);
|
||||
INSERT INTO trgfire VALUES (30);
|
||||
INSERT INTO trgfire VALUES (40);
|
||||
DROP TABLE trgfire;
|
||||
DROP FUNCTION tgf();
|
||||
|
||||
--
|
||||
-- Test the interaction between transition tables and both kinds of
|
||||
|
Reference in New Issue
Block a user