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)
 
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

Definition at line 23 of file execPartition.h.

Function Documentation

◆ ExecCleanupTupleRouting()

void ExecCleanupTupleRouting ( ModifyTableState mtstate,
PartitionTupleRouting proute 
)

Definition at line 1236 of file execPartition.c.

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

◆ ExecDoInitialPruning()

void ExecDoInitialPruning ( EState estate)

Definition at line 1819 of file execPartition.c.

1820{
1821 ListCell *lc;
1822
1823 foreach(lc, estate->es_part_prune_infos)
1824 {
1826 PartitionPruneState *prunestate;
1827 Bitmapset *validsubplans = NULL;
1828 Bitmapset *all_leafpart_rtis = NULL;
1829 Bitmapset *validsubplan_rtis = NULL;
1830
1831 /* Create and save the PartitionPruneState. */
1832 prunestate = CreatePartitionPruneState(estate, pruneinfo,
1833 &all_leafpart_rtis);
1835 prunestate);
1836
1837 /*
1838 * Perform initial pruning steps, if any, and save the result
1839 * bitmapset or NULL as described in the header comment.
1840 */
1841 if (prunestate->do_initial_prune)
1842 validsubplans = ExecFindMatchingSubPlans(prunestate, true,
1843 &validsubplan_rtis);
1844 else
1845 validsubplan_rtis = all_leafpart_rtis;
1846
1848 validsubplan_rtis);
1850 validsubplans);
1851 }
1852}
Bitmapset * bms_add_members(Bitmapset *a, const Bitmapset *b)
Definition: bitmapset.c:917
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:666
Bitmapset * es_unpruned_relids
Definition: execnodes.h:669
List * es_part_prune_states
Definition: execnodes.h:667
List * es_part_prune_results
Definition: execnodes.h:668

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

Referenced by InitPlan().

◆ ExecFindMatchingSubPlans()

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

Definition at line 2493 of file execPartition.c.

2496{
2497 Bitmapset *result = NULL;
2498 MemoryContext oldcontext;
2499 int i;
2500
2501 /*
2502 * Either we're here on the initial prune done during pruning
2503 * initialization, or we're at a point where PARAM_EXEC Params can be
2504 * evaluated *and* there are steps in which to do so.
2505 */
2506 Assert(initial_prune || prunestate->do_exec_prune);
2507 Assert(validsubplan_rtis != NULL || !initial_prune);
2508
2509 /*
2510 * Switch to a temp context to avoid leaking memory in the executor's
2511 * query-lifespan memory context.
2512 */
2513 oldcontext = MemoryContextSwitchTo(prunestate->prune_context);
2514
2515 /*
2516 * For each hierarchy, do the pruning tests, and add nondeletable
2517 * subplans' indexes to "result".
2518 */
2519 for (i = 0; i < prunestate->num_partprunedata; i++)
2520 {
2521 PartitionPruningData *prunedata = prunestate->partprunedata[i];
2523
2524 /*
2525 * We pass the zeroth item, belonging to the root table of the
2526 * hierarchy, and find_matching_subplans_recurse() takes care of
2527 * recursing to other (lower-level) parents as needed.
2528 */
2529 pprune = &prunedata->partrelprunedata[0];
2530 find_matching_subplans_recurse(prunedata, pprune, initial_prune,
2531 &result, validsubplan_rtis);
2532
2533 /*
2534 * Expression eval may have used space in ExprContext too. Avoid
2535 * accessing exec_context during initial pruning, as it is not valid
2536 * at that stage.
2537 */
2538 if (!initial_prune && pprune->exec_pruning_steps)
2540 }
2541
2542 /* Add in any subplans that partition pruning didn't account for */
2543 result = bms_add_members(result, prunestate->other_subplans);
2544
2545 MemoryContextSwitchTo(oldcontext);
2546
2547 /* Copy result out of the temp context before we reset it */
2548 result = bms_copy(result);
2549 if (validsubplan_rtis)
2550 *validsubplan_rtis = bms_copy(*validsubplan_rtis);
2551
2552 MemoryContextReset(prunestate->prune_context);
2553
2554 return result;
2555}
Bitmapset * bms_copy(const Bitmapset *a)
Definition: bitmapset.c:122
static void find_matching_subplans_recurse(PartitionPruningData *prunedata, PartitionedRelPruningData *pprune, bool initial_prune, Bitmapset **validsubplans, Bitmapset **validsubplan_rtis)
#define ResetExprContext(econtext)
Definition: executor.h:644
Assert(PointerIsAligned(start, uint64))
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:87
PartitionPruneContext exec_context
Definition: execPartition.h:74

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(), ExecDoInitialPruning(), and ExecMergeAppend().

◆ ExecFindPartition()

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

Definition at line 265 of file execPartition.c.

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

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().

◆ ExecInitPartitionExecPruning()

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

Definition at line 1875 of file execPartition.c.

1880{
1881 PartitionPruneState *prunestate;
1882 EState *estate = planstate->state;
1883 PartitionPruneInfo *pruneinfo;
1884
1885 /* Obtain the pruneinfo we need. */
1887 part_prune_index);
1888
1889 /* Its relids better match the plan node's or the planner messed up. */
1890 if (!bms_equal(relids, pruneinfo->relids))
1891 elog(ERROR, "wrong pruneinfo with relids=%s found at part_prune_index=%d contained in plan node with relids=%s",
1892 bmsToString(pruneinfo->relids), part_prune_index,
1893 bmsToString(relids));
1894
1895 /*
1896 * The PartitionPruneState would have been created by
1897 * ExecDoInitialPruning() and stored as the part_prune_index'th element of
1898 * EState.es_part_prune_states.
1899 */
1900 prunestate = list_nth(estate->es_part_prune_states, part_prune_index);
1901 Assert(prunestate != NULL);
1902
1903 /* Use the result of initial pruning done by ExecDoInitialPruning(). */
1904 if (prunestate->do_initial_prune)
1905 *initially_valid_subplans = list_nth_node(Bitmapset,
1906 estate->es_part_prune_results,
1907 part_prune_index);
1908 else
1909 {
1910 /* No pruning, so we'll need to initialize all subplans */
1911 Assert(n_total_subplans > 0);
1912 *initially_valid_subplans = bms_add_range(NULL, 0,
1913 n_total_subplans - 1);
1914 }
1915
1916 /*
1917 * The exec pruning state must also be initialized, if needed, before it
1918 * can be used for pruning during execution.
1919 *
1920 * This also re-sequences subplan indexes contained in prunestate to
1921 * account for any that were removed due to initial pruning; refer to the
1922 * condition in InitExecPartitionPruneContexts() that is used to determine
1923 * whether to do this. If no exec pruning needs to be done, we would thus
1924 * leave the maps to be in an invalid state, but that's ok since that data
1925 * won't be consulted again (cf initial Assert in
1926 * ExecFindMatchingSubPlans).
1927 */
1928 if (prunestate->do_exec_prune)
1929 InitExecPartitionPruneContexts(prunestate, planstate,
1930 *initially_valid_subplans,
1931 n_total_subplans);
1932
1933 return prunestate;
1934}
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:1019
#define elog(elevel,...)
Definition: elog.h:225
static void InitExecPartitionPruneContexts(PartitionPruneState *prunestate, PlanState *parent_plan, Bitmapset *initially_valid_subplans, int n_total_subplans)
char * bmsToString(const Bitmapset *bms)
Definition: outfuncs.c:814
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
Bitmapset * relids
Definition: plannodes.h:1590

References Assert(), bms_add_range(), bms_equal(), bmsToString(), PartitionPruneState::do_exec_prune, PartitionPruneState::do_initial_prune, elog, ERROR, EState::es_part_prune_infos, EState::es_part_prune_results, EState::es_part_prune_states, InitExecPartitionPruneContexts(), list_nth(), list_nth_node, PartitionPruneInfo::relids, and PlanState::state.

Referenced by ExecInitAppend(), and ExecInitMergeAppend().

◆ ExecSetupPartitionTupleRouting()

PartitionTupleRouting * ExecSetupPartitionTupleRouting ( EState estate,
Relation  rel 
)

Definition at line 218 of file execPartition.c.

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