1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-28 23:42:10 +03:00

Create action triggers when partitions are detached

Detaching a partition from a partitioned table that's constrained by
foreign keys requires additional action triggers on the referenced side;
otherwise, DELETE/UPDATE actions there fail to notice rows in the table
that was partition, and so are incorrectly allowed through.  With this
commit, those triggers are now created.  Conversely, when a table that
has a foreign key is attached as a partition to a table that also has
the same foreign key, those action triggers are no longer needed, so we
remove them.

Add a minimal test case verifying (part of) this.

Authors: Amit Langote, Álvaro Herrera
Discussion: https://postgr.es/m/f2b8ead5-4131-d5a8-8016-2ea0a31250af@lab.ntt.co.jp
This commit is contained in:
Alvaro Herrera
2019-01-21 19:59:07 -03:00
parent 1755440935
commit 0464fdf07f
3 changed files with 113 additions and 5 deletions

View File

@ -1921,7 +1921,31 @@ alter table fkpart0.fk_part_56 drop constraint fk_part_a_fkey;
ERROR: cannot drop inherited constraint "fk_part_a_fkey" of relation "fk_part_56"
alter table fkpart0.fk_part_56_5 drop constraint fk_part_a_fkey;
ERROR: cannot drop inherited constraint "fk_part_a_fkey" of relation "fk_part_56_5"
-- verify that attaching and detaching partitions maintains the right set of
-- triggers
create schema fkpart1
create table pkey (a int primary key)
create table fk_part (a int) partition by list (a)
create table fk_part_1 partition of fk_part for values in (1) partition by list (a)
create table fk_part_1_1 partition of fk_part_1 for values in (1);
alter table fkpart1.fk_part add foreign key (a) references fkpart1.pkey;
insert into fkpart1.fk_part values (1); -- should fail
ERROR: insert or update on table "fk_part_1_1" violates foreign key constraint "fk_part_a_fkey"
DETAIL: Key (a)=(1) is not present in table "pkey".
insert into fkpart1.pkey values (1);
insert into fkpart1.fk_part values (1);
delete from fkpart1.pkey where a = 1; -- should fail
ERROR: update or delete on table "pkey" violates foreign key constraint "fk_part_a_fkey" on table "fk_part"
DETAIL: Key (a)=(1) is still referenced from table "fk_part".
alter table fkpart1.fk_part detach partition fkpart1.fk_part_1;
create table fkpart1.fk_part_1_2 partition of fkpart1.fk_part_1 for values in (2);
insert into fkpart1.fk_part_1 values (2); -- should fail
ERROR: insert or update on table "fk_part_1_2" violates foreign key constraint "fk_part_a_fkey"
DETAIL: Key (a)=(2) is not present in table "pkey".
delete from fkpart1.pkey where a = 1;
ERROR: update or delete on table "pkey" violates foreign key constraint "fk_part_a_fkey" on table "fk_part_1"
DETAIL: Key (a)=(1) is still referenced from table "fk_part_1".
\set VERBOSITY terse \\ -- suppress cascade details
drop schema fkpart0 cascade;
NOTICE: drop cascades to 2 other objects
drop schema fkpart0, fkpart1 cascade;
NOTICE: drop cascades to 5 other objects
\set VERBOSITY default

View File

@ -1375,6 +1375,23 @@ create table fkpart0.fk_part_56_5 partition of fkpart0.fk_part_56
alter table fkpart0.fk_part_56 drop constraint fk_part_a_fkey;
alter table fkpart0.fk_part_56_5 drop constraint fk_part_a_fkey;
-- verify that attaching and detaching partitions maintains the right set of
-- triggers
create schema fkpart1
create table pkey (a int primary key)
create table fk_part (a int) partition by list (a)
create table fk_part_1 partition of fk_part for values in (1) partition by list (a)
create table fk_part_1_1 partition of fk_part_1 for values in (1);
alter table fkpart1.fk_part add foreign key (a) references fkpart1.pkey;
insert into fkpart1.fk_part values (1); -- should fail
insert into fkpart1.pkey values (1);
insert into fkpart1.fk_part values (1);
delete from fkpart1.pkey where a = 1; -- should fail
alter table fkpart1.fk_part detach partition fkpart1.fk_part_1;
create table fkpart1.fk_part_1_2 partition of fkpart1.fk_part_1 for values in (2);
insert into fkpart1.fk_part_1 values (2); -- should fail
delete from fkpart1.pkey where a = 1;
\set VERBOSITY terse \\ -- suppress cascade details
drop schema fkpart0 cascade;
drop schema fkpart0, fkpart1 cascade;
\set VERBOSITY default