From: Robert Haas Date: Fri, 28 Apr 2017 18:48:38 +0000 (-0400) Subject: Fix VALIDATE CONSTRAINT to consider NO INHERIT attribute. X-Git-Tag: REL_10_BETA1~137 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=6a4dda44e02bfd5148c13b00d8f81045a2e17f2c;p=postgresql Fix VALIDATE CONSTRAINT to consider NO INHERIT attribute. Currently, trying to validate a NO INHERIT constraint on the parent will search for the constraint in child tables (where it is not supposed to exist), wrongly causing a "constraint does not exist" error. Amit Langote, per a report from Hans Buschmann. Discussion: http://postgr.es/m/20170421184012.24362.19@wrigleys.postgresql.org --- diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index 4df17c0efc..cdcb94929a 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -7704,9 +7704,10 @@ ATExecValidateConstraint(Relation rel, char *constrName, bool recurse, /* * If we're recursing, the parent has already done this, so skip - * it. + * it. Also, if the constraint is a NO INHERIT constraint, we + * shouldn't try to look for it in the children. */ - if (!recursing) + if (!recursing && !con->connoinherit) children = find_all_inheritors(RelationGetRelid(rel), lockmode, NULL); diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out index 375a0f618a..41df9f0759 100644 --- a/src/test/regress/expected/alter_table.out +++ b/src/test/regress/expected/alter_table.out @@ -367,6 +367,26 @@ NOTICE: merging constraint "identity" with inherited definition ALTER TABLE tmp3 VALIDATE CONSTRAINT identity; NOTICE: boo: 16 NOTICE: boo: 20 +-- A NO INHERIT constraint should not be looked for in children during VALIDATE CONSTRAINT +create table parent_noinh_convalid (a int); +create table child_noinh_convalid () inherits (parent_noinh_convalid); +insert into parent_noinh_convalid values (1); +insert into child_noinh_convalid values (1); +alter table parent_noinh_convalid add constraint check_a_is_2 check (a = 2) no inherit not valid; +-- fail, because of the row in parent +alter table parent_noinh_convalid validate constraint check_a_is_2; +ERROR: check constraint "check_a_is_2" is violated by some row +delete from only parent_noinh_convalid; +-- ok (parent itself contains no violating rows) +alter table parent_noinh_convalid validate constraint check_a_is_2; +select convalidated from pg_constraint where conrelid = 'parent_noinh_convalid'::regclass and conname = 'check_a_is_2'; + convalidated +-------------- + t +(1 row) + +-- cleanup +drop table parent_noinh_convalid, child_noinh_convalid; -- Try (and fail) to create constraint from tmp5(a) to tmp4(a) - unique constraint on -- tmp4 is a,b ALTER TABLE tmp5 add constraint tmpconstr foreign key(a) references tmp4(a) match full; diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql index 85c848f620..24d1d4d23b 100644 --- a/src/test/regress/sql/alter_table.sql +++ b/src/test/regress/sql/alter_table.sql @@ -307,6 +307,21 @@ ALTER TABLE tmp7 ADD CONSTRAINT identity CHECK (b = boo(b)); ALTER TABLE tmp3 ADD CONSTRAINT IDENTITY check (b = boo(b)) NOT VALID; ALTER TABLE tmp3 VALIDATE CONSTRAINT identity; +-- A NO INHERIT constraint should not be looked for in children during VALIDATE CONSTRAINT +create table parent_noinh_convalid (a int); +create table child_noinh_convalid () inherits (parent_noinh_convalid); +insert into parent_noinh_convalid values (1); +insert into child_noinh_convalid values (1); +alter table parent_noinh_convalid add constraint check_a_is_2 check (a = 2) no inherit not valid; +-- fail, because of the row in parent +alter table parent_noinh_convalid validate constraint check_a_is_2; +delete from only parent_noinh_convalid; +-- ok (parent itself contains no violating rows) +alter table parent_noinh_convalid validate constraint check_a_is_2; +select convalidated from pg_constraint where conrelid = 'parent_noinh_convalid'::regclass and conname = 'check_a_is_2'; +-- cleanup +drop table parent_noinh_convalid, child_noinh_convalid; + -- Try (and fail) to create constraint from tmp5(a) to tmp4(a) - unique constraint on -- tmp4 is a,b