Eine aufbereitete Darstellung der Quelle

 
     
 
 
Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 

Benutzer

Quelle  partitionfuncs.c

  Sprache: C
 

/*-------------------------------------------------------------------------
 *
 * partitionfuncs.c
 *   Functions for accessing partition-related metadata
 *
 * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group
 * Portions Copyright (c) 1994, Regents of the University of California
 *
 *
 * IDENTIFICATION
 *   src/backend/utils/adt/partitionfuncs.c
 *
 *-------------------------------------------------------------------------
 */


#include "postgres.h"

#include "access/htup_details.h"
#include "catalog/partition.h"
#include "catalog/pg_class.h"
#include "catalog/pg_inherits.h"
#include "funcapi.h"
#include "utils/fmgrprotos.h"
#include "utils/lsyscache.h"
#include "utils/syscache.h"

/*
 * Checks if a given relation can be part of a partition tree.  Returns
 * false if the relation cannot be processed, in which case it is up to
 * the caller to decide what to do, by either raising an error or doing
 * something else.
 */

static bool
check_rel_can_be_partition(Oid relid)
{
 char  relkind;
 bool  relispartition;

 /* Check if relation exists */
 if (!SearchSysCacheExists1(RELOID, ObjectIdGetDatum(relid)))
  return false;

 relkind = get_rel_relkind(relid);
 relispartition = get_rel_relispartition(relid);

 /* Only allow relation types that can appear in partition trees. */
 if (!relispartition && !RELKIND_HAS_PARTITIONS(relkind))
  return false;

 return true;
}

/*
 * pg_partition_tree
 *
 * Produce a view with one row per member of a partition tree, beginning
 * from the top-most parent given by the caller.  This gives information
 * about each partition, its immediate partitioned parent, if it is
 * a leaf partition and its level in the hierarchy.
 */

Datum
pg_partition_tree(PG_FUNCTION_ARGS)
{
#define PG_PARTITION_TREE_COLS 4
 Oid   rootrelid = PG_GETARG_OID(0);
 FuncCallContext *funcctx;
 List    *partitions;

 /* stuff done only on the first call of the function */
 if (SRF_IS_FIRSTCALL())
 {
  MemoryContext oldcxt;
  TupleDesc tupdesc;

  /* create a function context for cross-call persistence */
  funcctx = SRF_FIRSTCALL_INIT();

  if (!check_rel_can_be_partition(rootrelid))
   SRF_RETURN_DONE(funcctx);

  /* switch to memory context appropriate for multiple function calls */
  oldcxt = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);

  /*
   * Find all members of inheritance set.  We only need AccessShareLock
   * on the children for the partition information lookup.
 */

  partitions = find_all_inheritors(rootrelid, AccessShareLock, NULL);

  if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
   elog(ERROR, "return type must be a row type");
  funcctx->tuple_desc = tupdesc;

  /* The only state we need is the partition list */
  funcctx->user_fctx = partitions;

  MemoryContextSwitchTo(oldcxt);
 }

 /* stuff done on every call of the function */
 funcctx = SRF_PERCALL_SETUP();
 partitions = (List *) funcctx->user_fctx;

 if (funcctx->call_cntr < list_length(partitions))
 {
  Datum  result;
  Datum  values[PG_PARTITION_TREE_COLS] = {0};
  bool  nulls[PG_PARTITION_TREE_COLS] = {0};
  HeapTuple tuple;
  Oid   parentid = InvalidOid;
  Oid   relid = list_nth_oid(partitions, funcctx->call_cntr);
  char  relkind = get_rel_relkind(relid);
  int   level = 0;
  List    *ancestors = get_partition_ancestors(relid);
  ListCell   *lc;

  /*
   * Form tuple with appropriate data.
 */


  /* relid */
  values[0] = ObjectIdGetDatum(relid);

  /* parentid */
  if (ancestors != NIL)
   parentid = linitial_oid(ancestors);
  if (OidIsValid(parentid))
   values[1] = ObjectIdGetDatum(parentid);
  else
   nulls[1] = true;

  /* isleaf */
  values[2] = BoolGetDatum(!RELKIND_HAS_PARTITIONS(relkind));

  /* level */
  if (relid != rootrelid)
  {
   foreach(lc, ancestors)
   {
    level++;
    if (lfirst_oid(lc) == rootrelid)
     break;
   }
  }
  values[3] = Int32GetDatum(level);

  tuple = heap_form_tuple(funcctx->tuple_desc, values, nulls);
  result = HeapTupleGetDatum(tuple);
  SRF_RETURN_NEXT(funcctx, result);
 }

 /* done when there are no more elements left */
 SRF_RETURN_DONE(funcctx);
}

/*
 * pg_partition_root
 *
 * Returns the top-most parent of the partition tree to which a given
 * relation belongs, or NULL if it's not (or cannot be) part of any
 * partition tree.
 */

Datum
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" must contain a valid OID, given that the input relation is
  * a valid partition tree member as checked above.
 */

 Assert(OidIsValid(rootrelid));
 PG_RETURN_OID(rootrelid);
}

/*
 * pg_partition_ancestors
 *
 * Produces a view with one row per ancestor of the given partition,
 * including the input relation itself.
 */

Datum
pg_partition_ancestors(PG_FUNCTION_ARGS)
{
 Oid   relid = PG_GETARG_OID(0);
 FuncCallContext *funcctx;
 List    *ancestors;

 if (SRF_IS_FIRSTCALL())
 {
  MemoryContext oldcxt;

  funcctx = SRF_FIRSTCALL_INIT();

  if (!check_rel_can_be_partition(relid))
   SRF_RETURN_DONE(funcctx);

  oldcxt = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);

  ancestors = get_partition_ancestors(relid);
  ancestors = lcons_oid(relid, ancestors);

  /* The only state we need is the ancestors list */
  funcctx->user_fctx = ancestors;

  MemoryContextSwitchTo(oldcxt);
 }

 funcctx = SRF_PERCALL_SETUP();
 ancestors = (List *) funcctx->user_fctx;

 if (funcctx->call_cntr < list_length(ancestors))
 {
  Oid   resultrel = list_nth_oid(ancestors, funcctx->call_cntr);

  SRF_RETURN_NEXT(funcctx, ObjectIdGetDatum(resultrel));
 }

 SRF_RETURN_DONE(funcctx);
}

Messung V0.5 in Prozent
C=91 H=98 G=94

¤ Dauer der Verarbeitung: 0.13 Sekunden  (vorverarbeitet am  2026-08-08) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.






                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Open Source Software

     Quellcodebibliothek
     Eigene Quellcodes
     Fremde Quellcodes
     Suchen

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik

Statistik
#Sources=141584
#Domains=752002