PostgreSQL Source Code  git master
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)
 
PartitionPruneStateExecInitPartitionPruning (PlanState *planstate, int n_total_subplans, PartitionPruneInfo *pruneinfo, Bitmapset **initially_valid_subplans)
 
BitmapsetExecFindMatchingSubPlans (PartitionPruneState *prunestate, bool initial_prune)
 

Typedef Documentation

◆ PartitionDispatch

Definition at line 22 of file execPartition.h.

◆ PartitionedRelPruningData

◆ PartitionPruneState

◆ PartitionPruningData

◆ PartitionTupleRouting

Definition at line 22 of file execPartition.h.

Function Documentation

◆ ExecCleanupTupleRouting()

void ExecCleanupTupleRouting ( ModifyTableState mtstate,
PartitionTupleRouting proute 
)

Definition at line 1231 of file execPartition.c.

1233 {
1234  int i;
1235 
1236  /*
1237  * Remember, proute->partition_dispatch_info[0] corresponds to the root
1238  * partitioned table, which we must not try to close, because it is the
1239  * main target table of the query that will be closed by callers such as
1240  * ExecEndPlan() or DoCopy(). Also, tupslot is NULL for the root
1241  * partitioned table.
1242  */
1243  for (i = 1; i < proute->num_dispatch; i++)
1244  {
1246 
1247  table_close(pd->reldesc, NoLock);
1248 
1249  if (pd->tupslot)
1251  }
1252 
1253  for (i = 0; i < proute->num_partitions; i++)
1254  {
1255  ResultRelInfo *resultRelInfo = proute->partitions[i];
1256 
1257  /* Allow any FDWs to shut down */
1258  if (resultRelInfo->ri_FdwRoutine != NULL &&
1259  resultRelInfo->ri_FdwRoutine->EndForeignInsert != NULL)
1260  resultRelInfo->ri_FdwRoutine->EndForeignInsert(mtstate->ps.state,
1261  resultRelInfo);
1262 
1263  /*
1264  * Close it if it's not one of the result relations borrowed from the
1265  * owning ModifyTableState; those will be closed by ExecEndPlan().
1266  */
1267  if (proute->is_borrowed_rel[i])
1268  continue;
1269 
1270  ExecCloseIndices(resultRelInfo);
1271  table_close(resultRelInfo->ri_RelationDesc, NoLock);
1272  }
1273 }
void ExecCloseIndices(ResultRelInfo *resultRelInfo)
Definition: execIndexing.c:231
void ExecDropSingleTupleTableSlot(TupleTableSlot *slot)
Definition: execTuples.c:1341
int i
Definition: isn.c:73
#define NoLock
Definition: lockdefs.h:34
EndForeignInsert_function EndForeignInsert
Definition: fdwapi.h:239
PlanState ps
Definition: execnodes.h:1355
TupleTableSlot * tupslot
PartitionDispatch * partition_dispatch_info
Definition: execPartition.c:94
ResultRelInfo ** partitions
Definition: execPartition.c:98
EState * state
Definition: execnodes.h:1119
Relation ri_RelationDesc
Definition: execnodes.h:456
struct FdwRoutine * ri_FdwRoutine
Definition: execnodes.h:503
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:126

References FdwRoutine::EndForeignInsert, ExecCloseIndices(), ExecDropSingleTupleTableSlot(), 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().

◆ ExecFindMatchingSubPlans()

Bitmapset* ExecFindMatchingSubPlans ( PartitionPruneState prunestate,
bool  initial_prune 
)

Definition at line 2291 of file execPartition.c.

2293 {
2294  Bitmapset *result = NULL;
2295  MemoryContext oldcontext;
2296  int i;
2297 
2298  /*
2299  * Either we're here on the initial prune done during pruning
2300  * initialization, or we're at a point where PARAM_EXEC Params can be
2301  * evaluated *and* there are steps in which to do so.
2302  */
2303  Assert(initial_prune || prunestate->do_exec_prune);
2304 
2305  /*
2306  * Switch to a temp context to avoid leaking memory in the executor's
2307  * query-lifespan memory context.
2308  */
2309  oldcontext = MemoryContextSwitchTo(prunestate->prune_context);
2310 
2311  /*
2312  * For each hierarchy, do the pruning tests, and add nondeletable
2313  * subplans' indexes to "result".
2314  */
2315  for (i = 0; i < prunestate->num_partprunedata; i++)
2316  {
2317  PartitionPruningData *prunedata = prunestate->partprunedata[i];
2318  PartitionedRelPruningData *pprune;
2319 
2320  /*
2321  * We pass the zeroth item, belonging to the root table of the
2322  * hierarchy, and find_matching_subplans_recurse() takes care of
2323  * recursing to other (lower-level) parents as needed.
2324  */
2325  pprune = &prunedata->partrelprunedata[0];
2326  find_matching_subplans_recurse(prunedata, pprune, initial_prune,
2327  &result);
2328 
2329  /* Expression eval may have used space in ExprContext too */
2330  if (pprune->exec_pruning_steps)
2332  }
2333 
2334  /* Add in any subplans that partition pruning didn't account for */
2335  result = bms_add_members(result, prunestate->other_subplans);
2336 
2337  MemoryContextSwitchTo(oldcontext);
2338 
2339  /* Copy result out of the temp context before we reset it */
2340  result = bms_copy(result);
2341 
2342  MemoryContextReset(prunestate->prune_context);
2343 
2344  return result;
2345 }
Bitmapset * bms_add_members(Bitmapset *a, const Bitmapset *b)
Definition: bitmapset.c:917
Bitmapset * bms_copy(const Bitmapset *a)
Definition: bitmapset.c:122
#define Assert(condition)
Definition: c.h:858
static void find_matching_subplans_recurse(PartitionPruningData *prunedata, PartitionedRelPruningData *pprune, bool initial_prune, Bitmapset **validsubplans)
#define ResetExprContext(econtext)
Definition: executor.h:544
void MemoryContextReset(MemoryContext context)
Definition: mcxt.c:383
MemoryContextSwitchTo(old_ctx)
ExprContext * exprcontext
Definition: partprune.h:60
PartitionPruningData * partprunedata[FLEXIBLE_ARRAY_MEMBER]
Bitmapset * other_subplans
MemoryContext prune_context
PartitionedRelPruningData partrelprunedata[FLEXIBLE_ARRAY_MEMBER]
Definition: execPartition.h:81
PartitionPruneContext exec_context
Definition: execPartition.h:68

References Assert, bms_add_members(), bms_copy(), PartitionPruneState::do_exec_prune, PartitionedRelPruningData::exec_context, PartitionedRelPruningData::exec_pruning_steps, PartitionPruneContext::exprcontext, find_matching_subplans_recurse(), i, MemoryContextReset(), MemoryContextSwitchTo(), PartitionPruneState::num_partprunedata, PartitionPruneState::other_subplans, PartitionPruneState::partprunedata, PartitionPruningData::partrelprunedata, PartitionPruneState::prune_context, and ResetExprContext.

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

◆ ExecFindPartition()

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

Definition at line 262 of file execPartition.c.

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

References Assert, TupleConversionMap::attrMap, PartitionDescData::boundinfo, CHECK_FOR_INTERRUPTS, CheckValidResultRel(), CMD_INSERT, PartitionBoundInfoData::default_index, ExprContext::ecxt_scantuple, ereport, errcode(), errdetail(), errmsg(), ERROR, errtable(), ExecBuildSlotPartitionKeyDescription(), ExecClearTuple(), ExecGetRootToChildMap(), ExecInitPartitionDispatchInfo(), ExecInitPartitionInfo(), ExecInitRoutingInfo(), ExecLookupResultRelByOid(), ExecPartitionCheck(), execute_attr_map_slot(), FormPartitionKeyDatum(), get_partition_for_tuple(), GetPerTupleExprContext, GetPerTupleMemoryContext, PartitionDispatchData::indexes, PartitionDescData::is_leaf, likely, MemoryContextSwitchTo(), NIL, PartitionTupleRouting::nonleaf_partitions, PartitionDescData::nparts, PartitionTupleRouting::num_dispatch, PartitionTupleRouting::num_partitions, OidIsValid, PartitionDescData::oids, PartitionDispatchData::partdesc, PartitionTupleRouting::partition_dispatch_info, PARTITION_MAX_KEYS, PartitionTupleRouting::partitions, RelationData::rd_rel, RelationGetRelationName, RelationGetRelid, PartitionDispatchData::reldesc, ResultRelInfo::ri_PartitionTupleSlot, ResultRelInfo::ri_RelationDesc, ModifyTableState::rootResultRelInfo, PartitionDispatchData::tupmap, PartitionDispatchData::tupslot, and values.

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

◆ ExecInitPartitionPruning()

PartitionPruneState* ExecInitPartitionPruning ( PlanState planstate,
int  n_total_subplans,
PartitionPruneInfo pruneinfo,
Bitmapset **  initially_valid_subplans 
)

Definition at line 1799 of file execPartition.c.

1803 {
1804  PartitionPruneState *prunestate;
1805  EState *estate = planstate->state;
1806 
1807  /* We may need an expression context to evaluate partition exprs */
1808  ExecAssignExprContext(estate, planstate);
1809 
1810  /* Create the working data structure for pruning */
1811  prunestate = CreatePartitionPruneState(planstate, pruneinfo);
1812 
1813  /*
1814  * Perform an initial partition prune pass, if required.
1815  */
1816  if (prunestate->do_initial_prune)
1817  *initially_valid_subplans = ExecFindMatchingSubPlans(prunestate, true);
1818  else
1819  {
1820  /* No pruning, so we'll need to initialize all subplans */
1821  Assert(n_total_subplans > 0);
1822  *initially_valid_subplans = bms_add_range(NULL, 0,
1823  n_total_subplans - 1);
1824  }
1825 
1826  /*
1827  * Re-sequence subplan indexes contained in prunestate to account for any
1828  * that were removed above due to initial pruning. No need to do this if
1829  * no steps were removed.
1830  */
1831  if (bms_num_members(*initially_valid_subplans) < n_total_subplans)
1832  {
1833  /*
1834  * We can safely skip this when !do_exec_prune, even though that
1835  * leaves invalid data in prunestate, because that data won't be
1836  * consulted again (cf initial Assert in ExecFindMatchingSubPlans).
1837  */
1838  if (prunestate->do_exec_prune)
1839  PartitionPruneFixSubPlanMap(prunestate,
1840  *initially_valid_subplans,
1841  n_total_subplans);
1842  }
1843 
1844  return prunestate;
1845 }
int bms_num_members(const Bitmapset *a)
Definition: bitmapset.c:751
Bitmapset * bms_add_range(Bitmapset *a, int lower, int upper)
Definition: bitmapset.c:1019
static PartitionPruneState * CreatePartitionPruneState(PlanState *planstate, PartitionPruneInfo *pruneinfo)
Bitmapset * ExecFindMatchingSubPlans(PartitionPruneState *prunestate, bool initial_prune)
static void PartitionPruneFixSubPlanMap(PartitionPruneState *prunestate, Bitmapset *initially_valid_subplans, int n_total_subplans)
void ExecAssignExprContext(EState *estate, PlanState *planstate)
Definition: execUtils.c:483

References Assert, bms_add_range(), bms_num_members(), CreatePartitionPruneState(), PartitionPruneState::do_exec_prune, PartitionPruneState::do_initial_prune, ExecAssignExprContext(), ExecFindMatchingSubPlans(), PartitionPruneFixSubPlanMap(), and PlanState::state.

Referenced by ExecInitAppend(), and ExecInitMergeAppend().

◆ ExecSetupPartitionTupleRouting()

PartitionTupleRouting* ExecSetupPartitionTupleRouting ( EState estate,
Relation  rel 
)

Definition at line 215 of file execPartition.c.

216 {
217  PartitionTupleRouting *proute;
218 
219  /*
220  * Here we attempt to expend as little effort as possible in setting up
221  * the PartitionTupleRouting. Each partition's ResultRelInfo is built on
222  * demand, only when we actually need to route a tuple to that partition.
223  * The reason for this is that a common case is for INSERT to insert a
224  * single tuple into a partitioned table and this must be fast.
225  */
227  proute->partition_root = rel;
228  proute->memcxt = CurrentMemoryContext;
229  /* Rest of members initialized by zeroing */
230 
231  /*
232  * Initialize this table's PartitionDispatch object. Here we pass in the
233  * parent as NULL as we don't need to care about any parent of the target
234  * partitioned table.
235  */
236  ExecInitPartitionDispatchInfo(estate, proute, RelationGetRelid(rel),
237  NULL, 0, NULL);
238 
239  return proute;
240 }
void * palloc0(Size size)
Definition: mcxt.c:1346
MemoryContext CurrentMemoryContext
Definition: mcxt.c:143
MemoryContext memcxt

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

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