Alvaro Herrera <alvhe...@alvh.no-ip.org> 于2025年5月28日周三 20:26写道:

> On 2025-May-28, Tender Wang wrote:
>
> > I dided the codes, in QueueFKConstraintValidation(),  we add three
> > newconstraint for the
> > fk rel, because the pk rel is partition table.
> >
> > During phase 3 of AlterTable, in ATRewriteTables(),
> > call validateForeignKeyConstraint() three times.
> > The first time the pk rel is pk, and it's ok.
> > The second time the pk rel is only pk_1, and the type(1) is not in pk_1,
> so
> > an error is reported.
> >
> > In this case, the two children newconstraint  should not be added to the
> > queue.
>
> Yeah, I reached the same conclusion and this is the preliminary fix I
> had written for it.  I don't like that I had to duplicate a few lines of
> code, but maybe it's not too bad.  Also the comments need to be
> clarified a bit more.
>

If the child table is still a partitioned table, the patch seems not work.

I figure out a quick fix as the attached. I add a bool argument into
the QueueFKConstraintValidation().
If it is true, it means we recursively call QueueFKConstraintValidation(),
then we don't add the newconstraint to the  queue.

I'm not sure about this fix. Any thoughts?

-- 
Thanks,
Tender Wang
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index 54ad38247aa..e11242e9b69 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -431,7 +431,7 @@ static ObjectAddress ATExecValidateConstraint(List **wqueue,
                                                                                
          Relation rel, char *constrName,
                                                                                
          bool recurse, bool recursing, LOCKMODE lockmode);
 static void QueueFKConstraintValidation(List **wqueue, Relation conrel, 
Relation rel,
-                                                                               
HeapTuple contuple, LOCKMODE lockmode);
+                                                                               
HeapTuple contuple, LOCKMODE lockmode, bool recursing);
 static void QueueCheckConstraintValidation(List **wqueue, Relation conrel, 
Relation rel,
                                                                                
   char *constrName, HeapTuple contuple,
                                                                                
   bool recurse, bool recursing, LOCKMODE lockmode);
@@ -11867,7 +11867,7 @@ AttachPartitionForeignKey(List **wqueue,
 
                /* Use the same lock as for AT_ValidateConstraint */
                QueueFKConstraintValidation(wqueue, conrel, partition, 
partcontup,
-                                                                       
ShareUpdateExclusiveLock);
+                                                                       
ShareUpdateExclusiveLock, false);
                ReleaseSysCache(partcontup);
                table_close(conrel, RowExclusiveLock);
        }
@@ -12919,7 +12919,7 @@ ATExecValidateConstraint(List **wqueue, Relation rel, 
char *constrName,
        {
                if (con->contype == CONSTRAINT_FOREIGN)
                {
-                       QueueFKConstraintValidation(wqueue, conrel, rel, tuple, 
lockmode);
+                       QueueFKConstraintValidation(wqueue, conrel, rel, tuple, 
lockmode, false);
                }
                else if (con->contype == CONSTRAINT_CHECK)
                {
@@ -12953,7 +12953,7 @@ ATExecValidateConstraint(List **wqueue, Relation rel, 
char *constrName,
  */
 static void
 QueueFKConstraintValidation(List **wqueue, Relation conrel, Relation rel,
-                                                       HeapTuple contuple, 
LOCKMODE lockmode)
+                                                       HeapTuple contuple, 
LOCKMODE lockmode, bool recursing)
 {
        Form_pg_constraint con;
        AlteredTableInfo *tab;
@@ -12983,8 +12983,11 @@ QueueFKConstraintValidation(List **wqueue, Relation 
conrel, Relation rel,
                newcon->qual = (Node *) fkconstraint;
 
                /* Find or create work queue entry for this table */
-               tab = ATGetQueueEntry(wqueue, rel);
-               tab->constraints = lappend(tab->constraints, newcon);
+               if (!recursing)
+               {
+                       tab = ATGetQueueEntry(wqueue, rel);
+                       tab->constraints = lappend(tab->constraints, newcon);
+               }
        }
 
        /*
@@ -13024,7 +13027,7 @@ QueueFKConstraintValidation(List **wqueue, Relation 
conrel, Relation rel,
                        childrel = table_open(childcon->conrelid, lockmode);
 
                        QueueFKConstraintValidation(wqueue, conrel, childrel, 
childtup,
-                                                                               
lockmode);
+                                                                               
lockmode, true);
                        table_close(childrel, NoLock);
                }
 

Reply via email to