PostgreSQL Source Code git master
Loading...
Searching...
No Matches
execPartition.h File Reference
Include dependency graph for execPartition.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  PartitionedRelPruningData
 
struct  PartitionPruningData
 
struct  PartitionPruneState
 

Typedefs

typedef struct PartitionDispatchDataPartitionDispatch
 
typedef struct PartitionTupleRouting PartitionTupleRouting
 
typedef struct PartitionedRelPruningData PartitionedRelPruningData
 
typedef struct PartitionPruningData PartitionPruningData
 
typedef struct PartitionPruneState PartitionPruneState
 

Functions

PartitionTupleRoutingExecSetupPartitionTupleRouting (EState *estate, Relation rel)
 
ResultRelInfoExecFindPartition (ModifyTableState *mtstate, ResultRelInfo *rootResultRelInfo, PartitionTupleRouting *proute, TupleTableSlot *slot, EState *estate)
 
void ExecCleanupTupleRouting (ModifyTableState *mtstate, PartitionTupleRouting *proute)
 
void ExecDoInitialPruning (EState *estate)
 
PartitionPruneStateExecInitPartitionExecPruning (PlanState *planstate, int n_total_subplans, int part_prune_index, Bitmapset *relids, Bitmapset **initially_valid_subplans)
 
BitmapsetExecFindMatchingSubPlans (PartitionPruneState *prunestate, bool initial_prune, Bitmapset **validsubplan_rtis)
 

Typedef Documentation

◆ PartitionDispatch

Definition at line 22 of file execPartition.h.

◆ PartitionedRelPruningData

◆ PartitionPruneState

◆ PartitionPruningData

◆ PartitionTupleRouting

Function Documentation

◆ ExecCleanupTupleRouting()

void ExecCleanupTupleRouting ( ModifyTableState mtstate,
PartitionTupleRouting proute 
)
extern

Definition at line 1411 of file execPartition.c.

1413{
1414 int i;
1415
1416 /*
1417 * Remember, proute->partition_dispatch_info[0] corresponds to the root
1418 * partitioned table, which we must not try to close, because it is the
1419 * main target table of the query that will be closed by callers such as
1420 * ExecEndPlan() or DoCopy(). Also, tupslot is NULL for the root
1421 * partitioned table.
1422 */
1423 for (i = 1; i < proute->num_dispatch; i++)
1424 {
1426
1428
1429 if (pd->tupslot)
1431 }
1432
1433 for (i = 0; i < proute->num_partitions; i++)
1434 {
1435 ResultRelInfo *resultRelInfo = proute->partitions[i];
1436
1437 /* Allow any FDWs to shut down */
1438 if (resultRelInfo->ri_FdwRoutine != NULL &&
1439 resultRelInfo->ri_FdwRoutine->EndForeignInsert != NULL)
1440 resultRelInfo->ri_FdwRoutine->EndForeignInsert(mtstate->ps.state,
1441 resultRelInfo);
1442
1443 /*
1444 * Close it if it's not one of the result relations borrowed from the
1445 * owning ModifyTableState; those will be closed by ExecEndPlan().
1446 */
1447 if (proute->is_borrowed_rel[i])
1448 continue;
1449
1450 ExecCloseIndices(resultRelInfo);
1451 table_close(resultRelInfo->ri_RelationDesc, NoLock);
1452 }
1453}
void ExecCloseIndices(ResultRelInfo *resultRelInfo)
void ExecDropSingleTupleTableSlot(TupleTableSlot *slot)
int i
Definition isn.c:77
#define NoLock
Definition lockdefs.h:34
static int fb(int x)
EndForeignInsert_function EndForeignInsert
Definition fdwapi.h:239
TupleTableSlot * tupslot
PartitionDispatch * partition_dispatch_info
ResultRelInfo ** partitions
EState * state
Definition execnodes.h:1170
Relation ri_RelationDesc
Definition execnodes.h:483
struct FdwRoutine * ri_FdwRoutine
Definition execnodes.h:536
void table_close(Relation relation, LOCKMODE lockmode)
Definition table.c:126

References FdwRoutine::EndForeignInsert, ExecCloseIndices(), ExecDropSingleTupleTableSlot(), fb(), i, PartitionTupleRouting::is_borrowed_rel, NoLock, PartitionTupleRouting::num_dispatch, PartitionTupleRouting::num_partitions, PartitionTupleRouting::partition_dispatch_info, PartitionTupleRouting::partitions, ModifyTableState::ps, PartitionDispatchData::reldesc, ResultRelInfo::ri_FdwRoutine, ResultRelInfo::ri_RelationDesc, PlanState::state, table_close(), and PartitionDispatchData::tupslot.

Referenced by CopyFrom(), ExecEndModifyTable(), and finish_edata().

◆ ExecDoInitialPruning()

void ExecDoInitialPruning ( EState estate)
extern

Definition at line 1994 of file execPartition.c.

1995{
1996 ListCell *lc;
1997
1998 foreach(lc, estate->es_part_prune_infos)
1999 {
2005
2006 /* Create and save the PartitionPruneState. */
2010 prunestate);
2011
2012 /*
2013 * Perform initial pruning steps, if any, and save the result
2014 * bitmapset or NULL as described in the header comment.
2015 */
2016 if (prunestate->do_initial_prune)
2019 else
2021
2026 }
2027}
Bitmapset * bms_add_members(Bitmapset *a, const Bitmapset *b)
Definition bitmapset.c:901
Bitmapset * ExecFindMatchingSubPlans(PartitionPruneState *prunestate, bool initial_prune, Bitmapset **validsubplan_rtis)
static PartitionPruneState * CreatePartitionPruneState(EState *estate, PartitionPruneInfo *pruneinfo, Bitmapset **all_leafpart_rtis)
List * lappend(List *list, void *datum)
Definition list.c:339
#define lfirst_node(type, lc)
Definition pg_list.h:176
List * es_part_prune_infos
Definition execnodes.h:673
Bitmapset * es_unpruned_relids
Definition execnodes.h:676
List * es_part_prune_states
Definition execnodes.h:674
List * es_part_prune_results
Definition execnodes.h:675

References bms_add_members(), CreatePartitionPruneState(), EState::es_part_prune_infos, EState::es_part_prune_results, EState::es_part_prune_states, EState::es_unpruned_relids, ExecFindMatchingSubPlans(), fb(), lappend(), and lfirst_node.

Referenced by InitPlan().

◆ ExecFindMatchingSubPlans()

Bitmapset * ExecFindMatchingSubPlans ( PartitionPruneState prunestate,
bool  initial_prune,
Bitmapset **  validsubplan_rtis 
)
extern

Definition at line 2666 of file execPartition.c.

2669{
2670 Bitmapset *result = NULL;
2671 MemoryContext oldcontext;
2672 int i;
2673
2674 /*
2675 * Either we're here on the initial prune done during pruning
2676 * initialization, or we're at a point where PARAM_EXEC Params can be
2677 * evaluated *and* there are steps in which to do so.
2678 */
2679 Assert(initial_prune || prunestate->do_exec_prune);
2681
2682 /*
2683 * Switch to a temp context to avoid leaking memory in the executor's
2684 * query-lifespan memory context.
2685 */
2686 oldcontext = MemoryContextSwitchTo(prunestate->prune_context);
2687
2688 /*
2689 * For each hierarchy, do the pruning tests, and add nondeletable
2690 * subplans' indexes to "result".
2691 */
2692 for (i = 0; i < prunestate->num_partprunedata; i++)
2693 {
2694 PartitionPruningData *prunedata = prunestate->partprunedata[i];
2696
2697 /*
2698 * We pass the zeroth item, belonging to the root table of the
2699 * hierarchy, and find_matching_subplans_recurse() takes care of
2700 * recursing to other (lower-level) parents as needed.
2701 */
2702 pprune = &prunedata->partrelprunedata[0];
2704 &result, validsubplan_rtis);
2705
2706 /*
2707 * Expression eval may have used space in ExprContext too. Avoid
2708 * accessing exec_context during initial pruning, as it is not valid
2709 * at that stage.
2710 */
2711 if (!initial_prune && pprune->exec_pruning_steps)
2712 ResetExprContext(pprune->exec_context.exprcontext);
2713 }
2714
2715 /* Add in any subplans that partition pruning didn't account for */
2716 result = bms_add_members(result, prunestate->other_subplans);
2717
2718 MemoryContextSwitchTo(oldcontext);
2719
2720 /* Copy result out of the temp context before we reset it */
2721 result = bms_copy(result);
2724
2725 MemoryContextReset(prunestate->prune_context);
2726
2727 return result;
2728}
Bitmapset * bms_copy(const Bitmapset *a)
Definition bitmapset.c:122
#define Assert(condition)
Definition c.h:885
static void find_matching_subplans_recurse(PartitionPruningData *prunedata, PartitionedRelPruningData *pprune, bool initial_prune, Bitmapset **validsubplans, Bitmapset **validsubplan_rtis)
#define ResetExprContext(econtext)
Definition executor.h:650
void MemoryContextReset(MemoryContext context)
Definition mcxt.c:403
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition palloc.h:124

References Assert, bms_add_members(), bms_copy(), fb(), find_matching_subplans_recurse(), i, MemoryContextReset(), MemoryContextSwitchTo(), and ResetExprContext.

Referenced by choose_next_subplan_for_leader(), choose_next_subplan_for_worker(), choose_next_subplan_locally(), ExecAppendAsyncBegin(), ExecDoInitialPruning(), and ExecMergeAppend().

◆ ExecFindPartition()

ResultRelInfo * ExecFindPartition ( ModifyTableState mtstate,
ResultRelInfo rootResultRelInfo,
PartitionTupleRouting proute,
TupleTableSlot slot,
EState estate 
)
extern

Definition at line 267 of file execPartition.c.

271{
274 bool isnull[PARTITION_MAX_KEYS];
275 Relation rel;
277 PartitionDesc partdesc;
279 TupleTableSlot *ecxt_scantuple_saved = ecxt->ecxt_scantuple;
280 TupleTableSlot *rootslot = slot;
284
285 /* use per-tuple context here to avoid leaking memory */
287
288 /*
289 * First check the root table's partition constraint, if any. No point in
290 * routing the tuple if it doesn't belong in the root table itself.
291 */
292 if (rootResultRelInfo->ri_RelationDesc->rd_rel->relispartition)
293 ExecPartitionCheck(rootResultRelInfo, slot, estate, true);
294
295 /* start with the root partitioned table */
296 dispatch = pd[0];
297 while (dispatch != NULL)
298 {
299 int partidx = -1;
300 bool is_leaf;
301
303
304 rel = dispatch->reldesc;
305 partdesc = dispatch->partdesc;
306
307 /*
308 * Extract partition key from tuple. Expression evaluation machinery
309 * that FormPartitionKeyDatum() invokes expects ecxt_scantuple to
310 * point to the correct tuple slot. The slot might have changed from
311 * what was used for the parent table if the table of the current
312 * partitioning level has different tuple descriptor from the parent.
313 * So update ecxt_scantuple accordingly.
314 */
315 ecxt->ecxt_scantuple = slot;
316 FormPartitionKeyDatum(dispatch, slot, estate, values, isnull);
317
318 /*
319 * If this partitioned table has no partitions or no partition for
320 * these values, error out.
321 */
322 if (partdesc->nparts == 0 ||
324 {
325 char *val_desc;
326
328 values, isnull, 64);
332 errmsg("no partition of relation \"%s\" found for row",
334 val_desc ?
335 errdetail("Partition key of the failing row contains %s.",
336 val_desc) : 0,
337 errtable(rel)));
338 }
339
340 is_leaf = partdesc->is_leaf[partidx];
341 if (is_leaf)
342 {
343 /*
344 * We've reached the leaf -- hurray, we're done. Look to see if
345 * we've already got a ResultRelInfo for this partition.
346 */
347 if (likely(dispatch->indexes[partidx] >= 0))
348 {
349 /* ResultRelInfo already built */
350 Assert(dispatch->indexes[partidx] < proute->num_partitions);
351 rri = proute->partitions[dispatch->indexes[partidx]];
352 }
353 else
354 {
355 /*
356 * If the partition is known in the owning ModifyTableState
357 * node, we can re-use that ResultRelInfo instead of creating
358 * a new one with ExecInitPartitionInfo().
359 */
361 partdesc->oids[partidx],
362 true, false);
363 if (rri)
364 {
365 ModifyTable *node = (ModifyTable *) mtstate->ps.plan;
366
367 /* Verify this ResultRelInfo allows INSERTs */
369 node ? node->onConflictAction : ONCONFLICT_NONE,
370 NIL);
371
372 /*
373 * Initialize information needed to insert this and
374 * subsequent tuples routed to this partition.
375 */
376 ExecInitRoutingInfo(mtstate, estate, proute, dispatch,
377 rri, partidx, true);
378 }
379 else
380 {
381 /* We need to create a new one. */
382 rri = ExecInitPartitionInfo(mtstate, estate, proute,
383 dispatch,
384 rootResultRelInfo, partidx);
385 }
386 }
387 Assert(rri != NULL);
388
389 /* Signal to terminate the loop */
390 dispatch = NULL;
391 }
392 else
393 {
394 /*
395 * Partition is a sub-partitioned table; get the PartitionDispatch
396 */
397 if (likely(dispatch->indexes[partidx] >= 0))
398 {
399 /* Already built. */
400 Assert(dispatch->indexes[partidx] < proute->num_dispatch);
401
402 rri = proute->nonleaf_partitions[dispatch->indexes[partidx]];
403
404 /*
405 * Move down to the next partition level and search again
406 * until we find a leaf partition that matches this tuple
407 */
408 dispatch = pd[dispatch->indexes[partidx]];
409 }
410 else
411 {
412 /* Not yet built. Do that now. */
414
415 /*
416 * Create the new PartitionDispatch. We pass the current one
417 * in as the parent PartitionDispatch
418 */
420 proute,
421 partdesc->oids[partidx],
423 mtstate->rootResultRelInfo);
424 Assert(dispatch->indexes[partidx] >= 0 &&
425 dispatch->indexes[partidx] < proute->num_dispatch);
426
427 rri = proute->nonleaf_partitions[dispatch->indexes[partidx]];
429 }
430
431 /*
432 * Convert the tuple to the new parent's layout, if different from
433 * the previous parent.
434 */
435 if (dispatch->tupslot)
436 {
437 AttrMap *map = dispatch->tupmap;
439
440 myslot = dispatch->tupslot;
441 slot = execute_attr_map_slot(map, slot, myslot);
442
443 if (tempslot != NULL)
445 }
446 }
447
448 /*
449 * If this partition is the default one, we must check its partition
450 * constraint now, which may have changed concurrently due to
451 * partitions being added to the parent.
452 *
453 * (We do this here, and do not rely on ExecInsert doing it, because
454 * we don't want to miss doing it for non-leaf partitions.)
455 */
456 if (partidx == partdesc->boundinfo->default_index)
457 {
458 /*
459 * The tuple must match the partition's layout for the constraint
460 * expression to be evaluated successfully. If the partition is
461 * sub-partitioned, that would already be the case due to the code
462 * above, but for a leaf partition the tuple still matches the
463 * parent's layout.
464 *
465 * Note that we have a map to convert from root to current
466 * partition, but not from immediate parent to current partition.
467 * So if we have to convert, do it from the root slot; if not, use
468 * the root slot as-is.
469 */
470 if (is_leaf)
471 {
473
474 if (map)
476 rri->ri_PartitionTupleSlot);
477 else
478 slot = rootslot;
479 }
480
481 ExecPartitionCheck(rri, slot, estate, true);
482 }
483 }
484
485 /* Release the tuple in the lowest parent's dedicated slot. */
486 if (myslot != NULL)
488 /* and restore ecxt's scantuple */
489 ecxt->ecxt_scantuple = ecxt_scantuple_saved;
491
492 return rri;
493}
static Datum values[MAXATTR]
Definition bootstrap.c:147
#define likely(x)
Definition c.h:423
#define OidIsValid(objectId)
Definition c.h:800
int errcode(int sqlerrcode)
Definition elog.c:874
int errmsg(const char *fmt,...)
Definition elog.c:1093
int errdetail(const char *fmt,...) pg_attribute_printf(1
#define ERROR
Definition elog.h:39
#define ereport(elevel,...)
Definition elog.h:150
void CheckValidResultRel(ResultRelInfo *resultRelInfo, CmdType operation, OnConflictAction onConflictAction, List *mergeActions)
Definition execMain.c:1054
bool ExecPartitionCheck(ResultRelInfo *resultRelInfo, TupleTableSlot *slot, EState *estate, bool emitError)
Definition execMain.c:1860
static PartitionDispatch ExecInitPartitionDispatchInfo(EState *estate, PartitionTupleRouting *proute, Oid partoid, PartitionDispatch parent_pd, int partidx, ResultRelInfo *rootResultRelInfo)
static ResultRelInfo * ExecInitPartitionInfo(ModifyTableState *mtstate, EState *estate, PartitionTupleRouting *proute, PartitionDispatch dispatch, ResultRelInfo *rootResultRelInfo, int partidx)
static void ExecInitRoutingInfo(ModifyTableState *mtstate, EState *estate, PartitionTupleRouting *proute, PartitionDispatch dispatch, ResultRelInfo *partRelInfo, int partidx, bool is_borrowed_rel)
static char * ExecBuildSlotPartitionKeyDescription(Relation rel, const Datum *values, const bool *isnull, int maxfieldlen)
static void FormPartitionKeyDatum(PartitionDispatch pd, TupleTableSlot *slot, EState *estate, Datum *values, bool *isnull)
static int get_partition_for_tuple(PartitionDispatch pd, const Datum *values, const bool *isnull)
TupleConversionMap * ExecGetRootToChildMap(ResultRelInfo *resultRelInfo, EState *estate)
Definition execUtils.c:1326
#define GetPerTupleExprContext(estate)
Definition executor.h:656
#define GetPerTupleMemoryContext(estate)
Definition executor.h:661
#define CHECK_FOR_INTERRUPTS()
Definition miscadmin.h:123
ResultRelInfo * ExecLookupResultRelByOid(ModifyTableState *node, Oid resultoid, bool missing_ok, bool update_cache)
@ ONCONFLICT_NONE
Definition nodes.h:428
@ CMD_INSERT
Definition nodes.h:277
#define PARTITION_MAX_KEYS
#define NIL
Definition pg_list.h:68
uint64_t Datum
Definition postgres.h:70
#define RelationGetRelid(relation)
Definition rel.h:514
#define RelationGetRelationName(relation)
Definition rel.h:548
int errtable(Relation rel)
Definition relcache.c:6044
ResultRelInfo * rootResultRelInfo
Definition execnodes.h:1419
PartitionBoundInfo boundinfo
Definition partdesc.h:38
ResultRelInfo ** nonleaf_partitions
Plan * plan
Definition execnodes.h:1168
Form_pg_class rd_rel
Definition rel.h:111
AttrMap * attrMap
Definition tupconvert.h:28
TupleTableSlot * execute_attr_map_slot(AttrMap *attrMap, TupleTableSlot *in_slot, TupleTableSlot *out_slot)
Definition tupconvert.c:193
static TupleTableSlot * ExecClearTuple(TupleTableSlot *slot)
Definition tuptable.h:457

References Assert, TupleConversionMap::attrMap, PartitionDescData::boundinfo, CHECK_FOR_INTERRUPTS, CheckValidResultRel(), CMD_INSERT, PartitionBoundInfoData::default_index, ereport, errcode(), errdetail(), errmsg(), ERROR, errtable(), ExecBuildSlotPartitionKeyDescription(), ExecClearTuple(), ExecGetRootToChildMap(), ExecInitPartitionDispatchInfo(), ExecInitPartitionInfo(), ExecInitRoutingInfo(), ExecLookupResultRelByOid(), ExecPartitionCheck(), execute_attr_map_slot(), fb(), FormPartitionKeyDatum(), get_partition_for_tuple(), GetPerTupleExprContext, GetPerTupleMemoryContext, PartitionDescData::is_leaf, likely, MemoryContextSwitchTo(), NIL, PartitionTupleRouting::nonleaf_partitions, PartitionDescData::nparts, PartitionTupleRouting::num_dispatch, PartitionTupleRouting::num_partitions, OidIsValid, PartitionDescData::oids, ONCONFLICT_NONE, ModifyTable::onConflictAction, PartitionTupleRouting::partition_dispatch_info, PARTITION_MAX_KEYS, PartitionTupleRouting::partitions, PlanState::plan, ModifyTableState::ps, RelationData::rd_rel, RelationGetRelationName, RelationGetRelid, ResultRelInfo::ri_RelationDesc, ModifyTableState::rootResultRelInfo, and values.

Referenced by apply_handle_tuple_routing(), CopyFrom(), and ExecPrepareTupleRouting().

◆ ExecInitPartitionExecPruning()

PartitionPruneState * ExecInitPartitionExecPruning ( PlanState planstate,
int  n_total_subplans,
int  part_prune_index,
Bitmapset relids,
Bitmapset **  initially_valid_subplans 
)
extern

Definition at line 2050 of file execPartition.c.

2055{
2057 EState *estate = planstate->state;
2059
2060 /* Obtain the pruneinfo we need. */
2062 part_prune_index);
2063
2064 /* Its relids better match the plan node's or the planner messed up. */
2065 if (!bms_equal(relids, pruneinfo->relids))
2066 elog(ERROR, "wrong pruneinfo with relids=%s found at part_prune_index=%d contained in plan node with relids=%s",
2067 bmsToString(pruneinfo->relids), part_prune_index,
2068 bmsToString(relids));
2069
2070 /*
2071 * The PartitionPruneState would have been created by
2072 * ExecDoInitialPruning() and stored as the part_prune_index'th element of
2073 * EState.es_part_prune_states.
2074 */
2075 prunestate = list_nth(estate->es_part_prune_states, part_prune_index);
2077
2078 /* Use the result of initial pruning done by ExecDoInitialPruning(). */
2079 if (prunestate->do_initial_prune)
2081 estate->es_part_prune_results,
2082 part_prune_index);
2083 else
2084 {
2085 /* No pruning, so we'll need to initialize all subplans */
2088 n_total_subplans - 1);
2089 }
2090
2091 /*
2092 * The exec pruning state must also be initialized, if needed, before it
2093 * can be used for pruning during execution.
2094 *
2095 * This also re-sequences subplan indexes contained in prunestate to
2096 * account for any that were removed due to initial pruning; refer to the
2097 * condition in InitExecPartitionPruneContexts() that is used to determine
2098 * whether to do this. If no exec pruning needs to be done, we would thus
2099 * leave the maps to be in an invalid state, but that's ok since that data
2100 * won't be consulted again (cf initial Assert in
2101 * ExecFindMatchingSubPlans).
2102 */
2103 if (prunestate->do_exec_prune)
2107
2108 return prunestate;
2109}
bool bms_equal(const Bitmapset *a, const Bitmapset *b)
Definition bitmapset.c:142
Bitmapset * bms_add_range(Bitmapset *a, int lower, int upper)
Definition bitmapset.c:1003
#define elog(elevel,...)
Definition elog.h:226
static void InitExecPartitionPruneContexts(PartitionPruneState *prunestate, PlanState *parent_plan, Bitmapset *initially_valid_subplans, int n_total_subplans)
char * bmsToString(const Bitmapset *bms)
Definition outfuncs.c:819
static void * list_nth(const List *list, int n)
Definition pg_list.h:299
#define list_nth_node(type, list, n)
Definition pg_list.h:327

References Assert, bms_add_range(), bms_equal(), bmsToString(), elog, ERROR, EState::es_part_prune_infos, EState::es_part_prune_results, EState::es_part_prune_states, fb(), InitExecPartitionPruneContexts(), list_nth(), list_nth_node, and PlanState::state.

Referenced by ExecInitAppend(), and ExecInitMergeAppend().

◆ ExecSetupPartitionTupleRouting()

PartitionTupleRouting * ExecSetupPartitionTupleRouting ( EState estate,
Relation  rel 
)
extern

Definition at line 220 of file execPartition.c.

221{
222 PartitionTupleRouting *proute;
223
224 /*
225 * Here we attempt to expend as little effort as possible in setting up
226 * the PartitionTupleRouting. Each partition's ResultRelInfo is built on
227 * demand, only when we actually need to route a tuple to that partition.
228 * The reason for this is that a common case is for INSERT to insert a
229 * single tuple into a partitioned table and this must be fast.
230 */
232 proute->partition_root = rel;
234 /* Rest of members initialized by zeroing */
235
236 /*
237 * Initialize this table's PartitionDispatch object. Here we pass in the
238 * parent as NULL as we don't need to care about any parent of the target
239 * partitioned table.
240 */
242 NULL, 0, NULL);
243
244 return proute;
245}
#define palloc0_object(type)
Definition fe_memutils.h:75
MemoryContext CurrentMemoryContext
Definition mcxt.c:160

References CurrentMemoryContext, ExecInitPartitionDispatchInfo(), fb(), PartitionTupleRouting::memcxt, palloc0_object, PartitionTupleRouting::partition_root, and RelationGetRelid.

Referenced by apply_handle_tuple_routing(), CopyFrom(), ExecCrossPartitionUpdate(), ExecInitMerge(), and ExecInitModifyTable().