From e2f7454452c289779f2b7d58deb5194b666ebda5 Mon Sep 17 00:00:00 2001 From: Peter Smith 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