1/*-------------------------------------------------------------------------
4 * Functions for accessing partition-related metadata
6 * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group
7 * Portions Copyright (c) 1994, Regents of the University of California
11 * src/backend/utils/adt/partitionfuncs.c
13 *-------------------------------------------------------------------------
23#include "utils/fmgrprotos.h"
28 * Checks if a given relation can be part of a partition tree. Returns
29 * false if the relation cannot be processed, in which case it is up to
30 * the caller to decide what to do, by either raising an error or doing
39 /* Check if relation exists */
46 /* Only allow relation types that can appear in partition trees. */
47 if (!relispartition && !RELKIND_HAS_PARTITIONS(relkind))
56 * Produce a view with one row per member of a partition tree, beginning
57 * from the top-most parent given by the caller. This gives information
58 * about each partition, its immediate partitioned parent, if it is
59 * a leaf partition and its level in the hierarchy.
64#define PG_PARTITION_TREE_COLS 4
69 /* stuff done only on the first call of the function */
75 /* create a function context for cross-call persistence */
81 /* switch to memory context appropriate for multiple function calls */
85 * Find all members of inheritance set. We only need AccessShareLock
86 * on the children for the partition information lookup.
91 elog(
ERROR,
"return type must be a row type");
94 /* The only state we need is the partition list */
100 /* stuff done on every call of the function */
118 * Form tuple with appropriate data.
125 if (ancestors !=
NIL)
136 if (relid != rootrelid)
138 foreach(lc, ancestors)
152 /* done when there are no more elements left */
159 * Returns the top-most parent of the partition tree to which a given
160 * relation belongs, or NULL if it's not (or cannot be) part of any
173 /* fetch the list of ancestors */
177 * If the input relation is already the top-most parent, just return
180 if (ancestors ==
NIL)
187 * "rootrelid" must contain a valid OID, given that the input relation is
188 * a valid partition tree member as checked above.
195 * pg_partition_ancestors
197 * Produces a view with one row per ancestor of the given partition,
198 * including the input relation itself.
221 /* The only state we need is the ancestors list */
static Datum values[MAXATTR]
#define OidIsValid(objectId)
TypeFuncClass get_call_result_type(FunctionCallInfo fcinfo, Oid *resultTypeId, TupleDesc *resultTupleDesc)
#define SRF_IS_FIRSTCALL()
#define SRF_PERCALL_SETUP()
#define SRF_RETURN_NEXT(_funcctx, _result)
#define SRF_FIRSTCALL_INIT()
static Datum HeapTupleGetDatum(const HeapTupleData *tuple)
#define SRF_RETURN_DONE(_funcctx)
Assert(PointerIsAligned(start, uint64))
HeapTuple heap_form_tuple(TupleDesc tupleDescriptor, const Datum *values, const bool *isnull)
if(TABLE==NULL||TABLE_index==NULL)
List * lcons_oid(Oid datum, List *list)
void list_free(List *list)
bool get_rel_relispartition(Oid relid)
char get_rel_relkind(Oid relid)
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
List * get_partition_ancestors(Oid relid)
Datum pg_partition_tree(PG_FUNCTION_ARGS)
#define PG_PARTITION_TREE_COLS
Datum pg_partition_root(PG_FUNCTION_ARGS)
static bool check_rel_can_be_partition(Oid relid)
Datum pg_partition_ancestors(PG_FUNCTION_ARGS)
List * find_all_inheritors(Oid parentrelId, LOCKMODE lockmode, List **numparents)
static int list_length(const List *l)
static Oid list_nth_oid(const List *list, int n)
static Datum BoolGetDatum(bool X)
static Datum ObjectIdGetDatum(Oid X)
static Datum Int32GetDatum(int32 X)
MemoryContext multi_call_memory_ctx
#define SearchSysCacheExists1(cacheId, key1)