From 2e87af9604e882a4d8e33131dfc9295c3eeda670 Mon Sep 17 00:00:00 2001
From: Amul Sul <amul.sul@enterprisedb.com>
Date: Wed, 26 Feb 2025 15:49:11 +0530
Subject: [PATCH v15 1/9] refactor: re-add ATExecAlterChildConstr

ATExecAlterChildConstr was removed in commit
80d7f990496b1c7be61d9a00a2635b7d96b96197, but it is needed in the
next patches to recurse over child constraints.
---
 src/backend/commands/tablecmds.c | 82 ++++++++++++++++++++------------
 1 file changed, 52 insertions(+), 30 deletions(-)

diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index ce7d115667e..12bb71c50e1 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -397,6 +397,9 @@ static bool ATExecAlterConstraintInternal(ATAlterConstraint *cmdcon, Relation co
 static void AlterConstrTriggerDeferrability(Oid conoid, Relation tgrel, Relation rel,
 											bool deferrable, bool initdeferred,
 											List **otherrelids);
+static void ATExecAlterChildConstr(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);
@@ -11995,41 +11998,13 @@ ATExecAlterConstraintInternal(ATAlterConstraint *cmdcon, Relation conrel,
 	/*
 	 * 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(cmdcon, conrel, tgrel, childrel, childtup,
-										  recurse, otherrelids, lockmode);
-			table_close(childrel, NoLock);
-		}
-
-		systable_endscan(pscan);
-	}
+		ATExecAlterChildConstr(cmdcon, conrel, tgrel, rel, contuple,
+							   recurse, otherrelids, lockmode);
 
 	return changed;
 }
@@ -12099,6 +12074,53 @@ 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(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(cmdcon, conrel, tgrel, childrel, childtup,
+									  recurse, otherrelids, lockmode);
+		table_close(childrel, NoLock);
+	}
+
+	systable_endscan(pscan);
+}
+
 /*
  * ALTER TABLE VALIDATE CONSTRAINT
  *
-- 
2.43.5

