refactor: re-add ATExecAlterChildConstr()
authorPeter Eisentraut <peter@eisentraut.org>
Tue, 11 Mar 2025 07:40:42 +0000 (08:40 +0100)
committerPeter Eisentraut <peter@eisentraut.org>
Tue, 11 Mar 2025 07:43:35 +0000 (08:43 +0100)
ATExecAlterChildConstr() was removed in commit 80d7f990496, but it is
needed in some subsequent patches for the NOT ENFORCED feature, to
recurse over child constraints.  This adds it back in slightly altered
form.

Author: Amul Sul <amul.sul@enterprisedb.com>
Reviewed-by: Alexandra Wang <alexandra.wang.oss@gmail.com>
Discussion: https://www.postgresql.org/message-id/flat/CAAJ_b962c5AcYW9KUt_R_ER5qs3fUGbe4az-SP-vuwPS-w-AGA%40mail.gmail.com

src/backend/commands/tablecmds.c

index 1f87098255990f296df41c29c0156ae35d3b668e..e9b95018199a5b24742ca58609fd7361875ef0a5 100644 (file)
@@ -398,6 +398,10 @@ static bool ATExecAlterConstraintInternal(List **wqueue, ATAlterConstraint *cmdc
 static void AlterConstrTriggerDeferrability(Oid conoid, Relation tgrel, Relation rel,
                                            bool deferrable, bool initdeferred,
                                            List **otherrelids);
+static void ATExecAlterChildConstr(List **wqueue, ATAlterConstraint *cmdcon,
+                                  Relation conrel, Relation tgrel, Relation rel,
+                                  HeapTuple contuple, bool recurse, List **otherrelids,
+                                  LOCKMODE lockmode);
 static ObjectAddress ATExecValidateConstraint(List **wqueue,
                                              Relation rel, char *constrName,
                                              bool recurse, bool recursing, LOCKMODE lockmode);
@@ -12031,41 +12035,13 @@ ATExecAlterConstraintInternal(List **wqueue, ATAlterConstraint *cmdcon,
    /*
     * If the table at either end of the constraint is partitioned, we need to
     * handle every constraint that is a child of this one.
-    *
-    * Note that this doesn't handle recursion the normal way, viz. by
-    * scanning the list of child relations and recursing; instead it uses the
-    * conparentid relationships.  This may need to be reconsidered.
     */
    if (recurse && changed &&
        (rel->rd_rel->relkind == RELKIND_PARTITIONED_TABLE ||
         (OidIsValid(refrelid) &&
          get_rel_relkind(refrelid) == RELKIND_PARTITIONED_TABLE)))
-   {
-       ScanKeyData pkey;
-       SysScanDesc pscan;
-       HeapTuple   childtup;
-
-       ScanKeyInit(&pkey,
-                   Anum_pg_constraint_conparentid,
-                   BTEqualStrategyNumber, F_OIDEQ,
-                   ObjectIdGetDatum(currcon->oid));
-
-       pscan = systable_beginscan(conrel, ConstraintParentIndexId,
-                                  true, NULL, 1, &pkey);
-
-       while (HeapTupleIsValid(childtup = systable_getnext(pscan)))
-       {
-           Form_pg_constraint childcon = (Form_pg_constraint) GETSTRUCT(childtup);
-           Relation    childrel;
-
-           childrel = table_open(childcon->conrelid, lockmode);
-           ATExecAlterConstraintInternal(wqueue, cmdcon, conrel, tgrel, childrel,
-                                         childtup, recurse, otherrelids, lockmode);
-           table_close(childrel, NoLock);
-       }
-
-       systable_endscan(pscan);
-   }
+       ATExecAlterChildConstr(wqueue, cmdcon, conrel, tgrel, rel, contuple,
+                              recurse, otherrelids, lockmode);
 
    /*
     * Update the catalog for inheritability.  No work if the constraint is
@@ -12203,6 +12179,54 @@ AlterConstrTriggerDeferrability(Oid conoid, Relation tgrel, Relation rel,
    systable_endscan(tgscan);
 }
 
+/*
+ * Invokes ATExecAlterConstraintInternal for each constraint that is a child of
+ * the specified constraint.
+ *
+ * Note that this doesn't handle recursion the normal way, viz. by scanning the
+ * list of child relations and recursing; instead it uses the conparentid
+ * relationships.  This may need to be reconsidered.
+ *
+ * The arguments to this function have the same meaning as the arguments to
+ * ATExecAlterConstraintInternal.
+ */
+static void
+ATExecAlterChildConstr(List **wqueue, ATAlterConstraint *cmdcon,
+                      Relation conrel, Relation tgrel, Relation rel,
+                      HeapTuple contuple, bool recurse, List **otherrelids,
+                      LOCKMODE lockmode)
+{
+   Form_pg_constraint currcon;
+   Oid         conoid;
+   ScanKeyData pkey;
+   SysScanDesc pscan;
+   HeapTuple   childtup;
+
+   currcon = (Form_pg_constraint) GETSTRUCT(contuple);
+   conoid = currcon->oid;
+
+   ScanKeyInit(&pkey,
+               Anum_pg_constraint_conparentid,
+               BTEqualStrategyNumber, F_OIDEQ,
+               ObjectIdGetDatum(conoid));
+
+   pscan = systable_beginscan(conrel, ConstraintParentIndexId,
+                              true, NULL, 1, &pkey);
+
+   while (HeapTupleIsValid(childtup = systable_getnext(pscan)))
+   {
+       Form_pg_constraint childcon = (Form_pg_constraint) GETSTRUCT(childtup);
+       Relation    childrel;
+
+       childrel = table_open(childcon->conrelid, lockmode);
+       ATExecAlterConstraintInternal(wqueue, cmdcon, conrel, tgrel, childrel,
+                                     childtup, recurse, otherrelids, lockmode);
+       table_close(childrel, NoLock);
+   }
+
+   systable_endscan(pscan);
+}
+
 /*
  * ALTER TABLE VALIDATE CONSTRAINT
  *