From 38738277a439a41456627e1e8c1b1bcad6ba33bc Mon Sep 17 00:00:00 2001 From: Peter Smith Date: Wed, 29 Jul 2026 12:58:05 +1000 Subject: [PATCH v2] Add C function get_partition_root Adds a C equivalent of the existing SQL function pg_get_partition_root. Author: Peter Smith Reviewed-by: shveta malik Discussion: https://www.postgresql.org/message-id/flat/CAJpy0uDrs7ag3QwU7QgDNXOo9trLxgq881Qu1TgzuJVwsNpnHA%40mail.gmail.com#2438fc93ce2aa09eabdda0b16af3f5c9 --- src/backend/catalog/partition.c | 33 ++++++++++++++++++++++++++ src/backend/catalog/pg_depend.c | 5 ++-- src/backend/utils/adt/partitionfuncs.c | 14 +---------- src/include/catalog/partition.h | 1 + 4 files changed, 37 insertions(+), 16 deletions(-) diff --git a/src/backend/catalog/partition.c b/src/backend/catalog/partition.c index 28f3cade6ff..f518043bdfd 100644 --- a/src/backend/catalog/partition.c +++ b/src/backend/catalog/partition.c @@ -29,6 +29,7 @@ #include "utils/fmgroids.h" #include "utils/partcache.h" #include "utils/rel.h" +#include "utils/lsyscache.h" #include "utils/syscache.h" static Oid get_partition_parent_worker(Relation inhRel, Oid relid, @@ -118,6 +119,38 @@ 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 + * + * Note: This should only be called when it is known that the relation is a + * partition or partitioned table. + */ +Oid +get_partition_root(Oid relid) +{ + Oid root_relid; + List *ancestors; + + /* Fetch the list of ancestors */ + ancestors = get_partition_ancestors(relid); + + if (ancestors) + { + /* By definition, the last ancestor is the top-most parent */ + root_relid = llast_oid(ancestors); + list_free(ancestors); + } + else + { + /* No ancestors means relid was already the top-most parent */ + Assert(RELKIND_HAS_PARTITIONS(get_rel_relkind(relid))); + root_relid = 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