From e2f7454452c289779f2b7d58deb5194b666ebda5 Mon Sep 17 00:00:00 2001
From: Peter Smith <peter.b.smith@fujitsu.com>
Date: Fri, 17 Jul 2026 14:05:58 +1000
Subject: [PATCH v1] Add C function get_partition_root

---
 src/backend/catalog/partition.c        | 29 ++++++++++++++++++++++++++
 src/backend/catalog/pg_depend.c        |  5 ++---
 src/backend/utils/adt/partitionfuncs.c | 14 +------------
 src/include/catalog/partition.h        |  1 +
 4 files changed, 33 insertions(+), 16 deletions(-)

diff --git a/src/backend/catalog/partition.c b/src/backend/catalog/partition.c
index 28f3cade6ff..ef5c4437d7f 100644
--- a/src/backend/catalog/partition.c
+++ b/src/backend/catalog/partition.c
@@ -118,6 +118,35 @@ get_partition_parent_worker(Relation inhRel, Oid relid, bool *detach_pending)
 	return result;
 }
 
+/*
+ * get_partition_root
+ *		Obtain root partitioned table OID of the specified relation
+ *
+ * If there are no ancestors, return the input relid.
+ *
+ * Note: This should only be called when it is known that the relation is a
+ * partition (see function get_partition_ancestors).
+ */
+Oid
+get_partition_root(Oid relid)
+{
+	Oid root_relid;
+	List *ancestors;
+
+	/* Fetch the list of ancestors */
+	ancestors = get_partition_ancestors(relid);
+
+	/* If input relid is already top-most parent, just return it */
+	if (ancestors == NIL)
+		return relid;
+
+	root_relid = llast_oid(ancestors);
+	list_free(ancestors);
+
+	Assert(OidIsValid(root_relid));
+	return root_relid;
+}
+
 /*
  * get_partition_ancestors
  *		Obtain ancestors of given relation
diff --git a/src/backend/catalog/pg_depend.c b/src/backend/catalog/pg_depend.c
index 9a7a401aced..34753f44d07 100644
--- a/src/backend/catalog/pg_depend.c
+++ b/src/backend/catalog/pg_depend.c
@@ -1157,15 +1157,14 @@ getIdentitySequence(Relation rel, AttrNumber attnum, bool missing_ok)
 	 */
 	if (RelationGetForm(rel)->relispartition)
 	{
-		List	   *ancestors = get_partition_ancestors(relid);
+		Oid			root_relid = get_partition_root(relid);
 		const char *attname = get_attname(relid, attnum, false);
 
-		relid = llast_oid(ancestors);
+		relid = root_relid;
 		attnum = get_attnum(relid, attname);
 		if (attnum == InvalidAttrNumber)
 			elog(ERROR, "cache lookup failed for attribute \"%s\" of relation %u",
 				 attname, relid);
-		list_free(ancestors);
 	}
 
 	seqlist = getOwnedSequences_internal(relid, attnum, DEPENDENCY_INTERNAL);
diff --git a/src/backend/utils/adt/partitionfuncs.c b/src/backend/utils/adt/partitionfuncs.c
index e9db027aa2e..8ff3efdd3bc 100644
--- a/src/backend/utils/adt/partitionfuncs.c
+++ b/src/backend/utils/adt/partitionfuncs.c
@@ -165,23 +165,11 @@ pg_partition_root(PG_FUNCTION_ARGS)
 {
 	Oid			relid = PG_GETARG_OID(0);
 	Oid			rootrelid;
-	List	   *ancestors;
 
 	if (!check_rel_can_be_partition(relid))
 		PG_RETURN_NULL();
 
-	/* fetch the list of ancestors */
-	ancestors = get_partition_ancestors(relid);
-
-	/*
-	 * If the input relation is already the top-most parent, just return
-	 * itself.
-	 */
-	if (ancestors == NIL)
-		PG_RETURN_OID(relid);
-
-	rootrelid = llast_oid(ancestors);
-	list_free(ancestors);
+	rootrelid = get_partition_root(relid);
 
 	/*
 	 * "rootrelid" must contain a valid OID, given that the input relation is
diff --git a/src/include/catalog/partition.h b/src/include/catalog/partition.h
index a93cf081dd2..d2b2c242d70 100644
--- a/src/include/catalog/partition.h
+++ b/src/include/catalog/partition.h
@@ -21,6 +21,7 @@
 
 extern Oid	get_partition_parent(Oid relid, bool even_if_detached);
 extern List *get_partition_ancestors(Oid relid);
+extern Oid	get_partition_root(Oid relid);
 extern Oid	index_get_partition(Relation partition, Oid indexId);
 extern List *map_partition_varattnos(List *expr, int fromrel_varno,
 									 Relation to_rel, Relation from_rel);
-- 
2.47.3

