ATPrepAddPrimaryKey: ignore non-PK constraints
authorAlvaro Herrera <alvherre@alvh.no-ip.org>
Fri, 1 Sep 2023 12:21:27 +0000 (14:21 +0200)
committerAlvaro Herrera <alvherre@alvh.no-ip.org>
Fri, 1 Sep 2023 12:21:27 +0000 (14:21 +0200)
Because of lack of test coverage, this function added by b0e96f311985
wasn't ignoring constraint types other than primary keys, which it
should have.  Add some lines to a test for it.

Reported-by: Richard Guo <guofenglinux@gmail.com>
Discussion: https://postgr.es/m/CAMbWs48bc-k_-1fh0dZpAhp_LiR5MfEX9haystmoBboR_4czCQ@mail.gmail.com

src/backend/commands/tablecmds.c
src/test/regress/expected/inherit.out
src/test/regress/sql/inherit.sql

index d097da3c78e09b15d6196eb2eb4e391093ebaaae..03397746724d1d6cccce73679556755ac44fe6c7 100644 (file)
@@ -8907,7 +8907,14 @@ ATPrepAddPrimaryKey(List **wqueue, Relation rel, AlterTableCmd *cmd,
    List       *children;
    List       *newconstrs = NIL;
    ListCell   *lc;
-   IndexStmt  *stmt;
+   IndexStmt  *indexstmt;
+
+   /* No work if not creating a primary key */
+   if (!IsA(cmd->def, IndexStmt))
+       return;
+   indexstmt = castNode(IndexStmt, cmd->def);
+   if (!indexstmt->primary)
+       return;
 
    /* No work if no legacy inheritance children are present */
    if (rel->rd_rel->relkind != RELKIND_RELATION ||
@@ -8916,8 +8923,7 @@ ATPrepAddPrimaryKey(List **wqueue, Relation rel, AlterTableCmd *cmd,
 
    children = find_inheritance_children(RelationGetRelid(rel), lockmode);
 
-   stmt = castNode(IndexStmt, cmd->def);
-   foreach(lc, stmt->indexParams)
+   foreach(lc, indexstmt->indexParams)
    {
        IndexElem  *elem = lfirst_node(IndexElem, lc);
        Constraint *nnconstr;
index dae61b9a0b17dbe78be5ad4baf34ec650030bbce..59583e1e417c4ec89038acdfa38b0341e8ff2316 100644 (file)
@@ -2309,7 +2309,30 @@ alter table inh_child inherit inh_parent;        -- nope
 ERROR:  column "a" in child table must be marked NOT NULL
 alter table inh_child alter a set not null;
 alter table inh_child inherit inh_parent;      -- now it works
-drop table inh_parent, inh_child;
+-- don't interfere with other types of constraints
+alter table inh_parent add constraint inh_parent_excl exclude ((1) with =);
+alter table inh_parent add constraint inh_parent_uq unique (a);
+alter table inh_parent add constraint inh_parent_fk foreign key (a) references inh_parent (a);
+create table inh_child2 () inherits (inh_parent);
+create table inh_child3 (like inh_parent);
+alter table inh_child3 inherit inh_parent;
+select conrelid::regclass, conname, contype, coninhcount, conislocal
+ from pg_constraint
+ where conrelid::regclass::text in ('inh_parent', 'inh_child', 'inh_child2', 'inh_child3')
+ order by 2, 1;
+  conrelid  |        conname        | contype | coninhcount | conislocal 
+------------+-----------------------+---------+-------------+------------
+ inh_child2 | inh_child2_a_not_null | n       |           1 | f
+ inh_child3 | inh_child3_a_not_null | n       |           1 | t
+ inh_child  | inh_child_a_not_null  | n       |           1 | t
+ inh_child  | inh_child_pkey        | p       |           0 | t
+ inh_parent | inh_parent_excl       | x       |           0 | t
+ inh_parent | inh_parent_fk         | f       |           0 | t
+ inh_parent | inh_parent_pkey       | p       |           0 | t
+ inh_parent | inh_parent_uq         | u       |           0 | t
+(8 rows)
+
+drop table inh_parent, inh_child, inh_child2, inh_child3;
 --
 -- test multi inheritance tree
 --
index 9ceaec1d78eb01d4ddf3eb11159a72bf54392eb3..abe8602682c6a5aee5e8939320f7de928fdb2e7c 100644 (file)
@@ -846,7 +846,20 @@ create table inh_child (a int primary key);
 alter table inh_child inherit inh_parent;      -- nope
 alter table inh_child alter a set not null;
 alter table inh_child inherit inh_parent;      -- now it works
-drop table inh_parent, inh_child;
+
+-- don't interfere with other types of constraints
+alter table inh_parent add constraint inh_parent_excl exclude ((1) with =);
+alter table inh_parent add constraint inh_parent_uq unique (a);
+alter table inh_parent add constraint inh_parent_fk foreign key (a) references inh_parent (a);
+create table inh_child2 () inherits (inh_parent);
+create table inh_child3 (like inh_parent);
+alter table inh_child3 inherit inh_parent;
+select conrelid::regclass, conname, contype, coninhcount, conislocal
+ from pg_constraint
+ where conrelid::regclass::text in ('inh_parent', 'inh_child', 'inh_child2', 'inh_child3')
+ order by 2, 1;
+
+drop table inh_parent, inh_child, inh_child2, inh_child3;
 
 --
 -- test multi inheritance tree