]> granicus.if.org Git - postgresql/commitdiff
Assign constraint name when cloning FK definition for partitions
authorMichael Paquier <michael@paquier.xyz>
Sat, 6 Oct 2018 05:59:36 +0000 (14:59 +0900)
committerMichael Paquier <michael@paquier.xyz>
Sat, 6 Oct 2018 05:59:36 +0000 (14:59 +0900)
This is for example used when attaching a partition to a partitioned
table which includes foreign keys, and in this case the constraint name
has been missing in the data cloned.  This could lead to hard crashes,
as when validating the foreign key constraint, the constraint name is
always expected.  Particularly, when using log_min_messages >= DEBUG1, a
log message would be generated with this unassigned constraint name,
leading to an assertion failure on HEAD.

While on it, rename a variable in ATExecAttachPartition which was
declared twice with the same name.

Author: Michael Paquier
Reviewed-by: Álvaro Herrera
Discussion: https://postgr.es/m/20181005042236.GG1629@paquier.xyz
Backpatch-through: 11

src/backend/catalog/pg_constraint.c
src/backend/commands/tablecmds.c

index 6781b00c6e6a3674ccdd4851b2df173b7892b6e3..2063abb8aeb6a4c55e83188f05e6198e02ac9850 100644 (file)
@@ -574,6 +574,7 @@ CloneForeignKeyConstraints(Oid parentId, Oid relationId, List **cloned)
 
                fkconstraint = makeNode(Constraint);
                /* for now this is all we need */
+               fkconstraint->conname = pstrdup(NameStr(constrForm->conname));
                fkconstraint->fk_upd_action = constrForm->confupdtype;
                fkconstraint->fk_del_action = constrForm->confdeltype;
                fkconstraint->deferrable = constrForm->condeferrable;
index c145385f8435010d9a93d29ef92ce9a6e9050f47..7df1fc2a76523dbdc7fd1f09d2c00e03fe086d77 100644 (file)
@@ -14275,21 +14275,21 @@ ATExecAttachPartition(List **wqueue, Relation rel, PartitionCmd *cmd)
                                                           RelationGetRelid(attachrel), &cloned);
        foreach(l, cloned)
        {
-               ClonedConstraint *cloned = lfirst(l);
+               ClonedConstraint *clonedcon = lfirst(l);
                NewConstraint *newcon;
                Relation        clonedrel;
                AlteredTableInfo *parttab;
 
-               clonedrel = relation_open(cloned->relid, NoLock);
+               clonedrel = relation_open(clonedcon->relid, NoLock);
                parttab = ATGetQueueEntry(wqueue, clonedrel);
 
                newcon = (NewConstraint *) palloc0(sizeof(NewConstraint));
-               newcon->name = cloned->constraint->conname;
+               newcon->name = clonedcon->constraint->conname;
                newcon->contype = CONSTR_FOREIGN;
-               newcon->refrelid = cloned->refrelid;
-               newcon->refindid = cloned->conindid;
-               newcon->conid = cloned->conid;
-               newcon->qual = (Node *) cloned->constraint;
+               newcon->refrelid = clonedcon->refrelid;
+               newcon->refindid = clonedcon->conindid;
+               newcon->conid = clonedcon->conid;
+               newcon->qual = (Node *) clonedcon->constraint;
 
                parttab->constraints = lappend(parttab->constraints, newcon);