PostgreSQL Source Code git master
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
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 23 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
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:236
void ExecDropSingleTupleTableSlot(TupleTableSlot *slot)
Definition: execTuples.c:1441
int i
Definition: isn.c:72
#define NoLock
Definition: lockdefs.h:34
EndForeignInsert_function EndForeignInsert
Definition: fdwapi.h:239
PlanState ps
Definition: execnodes.h:1363
TupleTableSlot * tupslot
PartitionDispatch * partition_dispatch_info
Definition: execPartition.c:94
ResultRelInfo ** partitions
Definition: execPartition.c:98
EState * state
Definition: execnodes.h:1127
Relation ri_RelationDesc
Definition: execnodes.h:459
struct FdwRoutine * ri_FdwRoutine
Definition: execnodes.h:509
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 2301 of file execPartition.c.

2303{
2304 Bitmapset *result = NULL;
2305 MemoryContext oldcontext;
2306 int i;
2307
2308 /*
2309 * Either we're here on the initial prune done during pruning
2310 * initialization, or we're at a point where PARAM_EXEC Params can be
2311 * evaluated *and* there are steps in which to do so.
2312 */
2313 Assert(initial_prune || prunestate->do_exec_prune);
2314
2315 /*
2316 * Switch to a temp context to avoid leaking memory in the executor's
2317 * query-lifespan memory context.
2318 */
2319 oldcontext = MemoryContextSwitchTo(prunestate->prune_context);
2320
2321 /*
2322 * For each hierarchy, do the pruning tests, and add nondeletable
2323 * subplans' indexes to "result".
2324 */
2325 for (i = 0; i < prunestate->num_partprunedata; i++)
2326 {
2327 PartitionPruningData *prunedata = prunestate->partprunedata[i];
2329
2330 /*
2331 * We pass the zeroth item, belonging to the root table of the
2332 * hierarchy, and find_matching_subplans_recurse() takes care of
2333 * recursing to other (lower-level) parents as needed.
2334 */
2335 pprune = &prunedata->partrelprunedata[0];
2336 find_matching_subplans_recurse(prunedata, pprune, initial_prune,
2337 &result);
2338
2339 /* Expression eval may have used space in ExprContext too */
2340 if (pprune->exec_pruning_steps)
2342 }
2343
2344 /* Add in any subplans that partition pruning didn't account for */
2345 result = bms_add_members(result, prunestate->other_subplans);
2346
2347 MemoryContextSwitchTo(oldcontext);
2348
2349 /* Copy result out of the temp context before we reset it */
2350 result = bms_copy(result);
2351
2352 MemoryContextReset(prunestate->prune_context);
2353
2354 return result;
2355}
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:812
static void find_matching_subplans_recurse(PartitionPruningData *prunedata, PartitionedRelPruningData *pprune, bool initial_prune, Bitmapset **validsubplans)
#define ResetExprContext(econtext)
Definition: executor.h:557
void MemoryContextReset(MemoryContext context)
Definition: mcxt.c:383
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:124
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);
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,
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:151
#define likely(x)
Definition: c.h:329
#define OidIsValid(objectId)
Definition: c.h:729
int errdetail(const char *fmt,...)
Definition: elog.c:1203
int errcode(int sqlerrcode)
Definition: elog.c:853
int errmsg(const char *fmt,...)
Definition: elog.c:1070
#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:1801
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:1277
#define GetPerTupleExprContext(estate)
Definition: executor.h:563
#define GetPerTupleMemoryContext(estate)
Definition: executor.h:568
#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:5968
Definition: attmap.h:35
TupleTableSlot * ecxt_scantuple
Definition: execnodes.h:258
ResultRelInfo * rootResultRelInfo
Definition: execnodes.h:1376
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:591
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}
Bitmapset * bms_add_range(Bitmapset *a, int lower, int upper)
Definition: bitmapset.c:1019
int bms_num_members(const Bitmapset *a)
Definition: bitmapset.c:751
Bitmapset * ExecFindMatchingSubPlans(PartitionPruneState *prunestate, bool initial_prune)
static PartitionPruneState * CreatePartitionPruneState(PlanState *planstate, PartitionPruneInfo *pruneinfo)
static void PartitionPruneFixSubPlanMap(PartitionPruneState *prunestate, Bitmapset *initially_valid_subplans, int n_total_subplans)
void ExecAssignExprContext(EState *estate, PlanState *planstate)
Definition: execUtils.c:485

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;
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 */
237 NULL, 0, NULL);
238
239 return proute;
240}
void * palloc0(Size size)
Definition: mcxt.c:1347
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().