summaryrefslogtreecommitdiff
path: root/src/backend/executor
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/executor')
-rw-r--r--src/backend/executor/execPartition.c206
1 files changed, 121 insertions, 85 deletions
diff --git a/src/backend/executor/execPartition.c b/src/backend/executor/execPartition.c
index 0595d6bf1d6..306f695de16 100644
--- a/src/backend/executor/execPartition.c
+++ b/src/backend/executor/execPartition.c
@@ -78,6 +78,10 @@ static char *ExecBuildSlotPartitionKeyDescription(Relation rel,
bool *isnull,
int maxfieldlen);
static List *adjust_partition_tlist(List *tlist, TupleConversionMap *map);
+static void ExecInitPruningContext(PartitionPruneContext *context,
+ Oid reloid,
+ List *pruning_steps,
+ PlanState *planstate);
static void find_matching_subplans_recurse(PartitionPruningData *prunedata,
PartitionedRelPruningData *pprune,
bool initial_prune,
@@ -1525,18 +1529,13 @@ ExecCreatePartitionPruneState(PlanState *planstate,
{
PartitionedRelPruneInfo *pinfo = lfirst_node(PartitionedRelPruneInfo, lc2);
PartitionedRelPruningData *pprune = &prunedata->partrelprunedata[j];
- PartitionPruneContext *context = &pprune->context;
- PartitionDesc partdesc;
- PartitionKey partkey;
- int partnatts;
- int n_steps;
- ListCell *lc3;
/*
* We must copy the subplan_map rather than pointing directly to
* the plan's version, as we may end up making modifications to it
* later.
*/
+ pprune->nparts = pinfo->nparts;
pprune->subplan_map = palloc(sizeof(int) * pinfo->nparts);
memcpy(pprune->subplan_map, pinfo->subplan_map,
sizeof(int) * pinfo->nparts);
@@ -1548,76 +1547,28 @@ ExecCreatePartitionPruneState(PlanState *planstate,
pprune->present_parts = bms_copy(pinfo->present_parts);
/*
- * We need to hold a pin on the partitioned table's relcache entry
- * so that we can rely on its copies of the table's partition key
- * and partition descriptor. We need not get a lock though; one
- * should have been acquired already by InitPlan or
- * ExecLockNonLeafAppendTables.
+ * Initialize pruning contexts as needed.
*/
- context->partrel = relation_open(pinfo->reloid, NoLock);
-
- partkey = RelationGetPartitionKey(context->partrel);
- partdesc = RelationGetPartitionDesc(context->partrel);
- n_steps = list_length(pinfo->pruning_steps);
-
- context->strategy = partkey->strategy;
- context->partnatts = partnatts = partkey->partnatts;
- context->nparts = pinfo->nparts;
- context->boundinfo = partdesc->boundinfo;
- context->partcollation = partkey->partcollation;
- context->partsupfunc = partkey->partsupfunc;
-
- /* We'll look up type-specific support functions as needed */
- context->stepcmpfuncs = (FmgrInfo *)
- palloc0(sizeof(FmgrInfo) * n_steps * partnatts);
-
- context->ppccontext = CurrentMemoryContext;
- context->planstate = planstate;
-
- /* Initialize expression state for each expression we need */
- context->exprstates = (ExprState **)
- palloc0(sizeof(ExprState *) * n_steps * partnatts);
- foreach(lc3, pinfo->pruning_steps)
+ pprune->initial_pruning_steps = pinfo->initial_pruning_steps;
+ if (pinfo->initial_pruning_steps)
{
- PartitionPruneStepOp *step = (PartitionPruneStepOp *) lfirst(lc3);
- ListCell *lc4;
- int keyno;
-
- /* not needed for other step kinds */
- if (!IsA(step, PartitionPruneStepOp))
- continue;
-
- Assert(list_length(step->exprs) <= partnatts);
-
- keyno = 0;
- foreach(lc4, step->exprs)
- {
- Expr *expr = (Expr *) lfirst(lc4);
-
- /* not needed for Consts */
- if (!IsA(expr, Const))
- {
- int stateidx = PruneCxtStateIdx(partnatts,
- step->step.step_id,
- keyno);
-
- context->exprstates[stateidx] =
- ExecInitExpr(expr, context->planstate);
- }
- keyno++;
- }
+ ExecInitPruningContext(&pprune->initial_context,
+ pinfo->reloid,
+ pinfo->initial_pruning_steps,
+ planstate);
+ /* Record whether initial pruning is needed at any level */
+ prunestate->do_initial_prune = true;
+ }
+ pprune->exec_pruning_steps = pinfo->exec_pruning_steps;
+ if (pinfo->exec_pruning_steps)
+ {
+ ExecInitPruningContext(&pprune->exec_context,
+ pinfo->reloid,
+ pinfo->exec_pruning_steps,
+ planstate);
+ /* Record whether exec pruning is needed at any level */
+ prunestate->do_exec_prune = true;
}
-
- /* Array is not modified at runtime, so just point to plan's copy */
- context->exprhasexecparam = pinfo->hasexecparam;
-
- pprune->pruning_steps = pinfo->pruning_steps;
- pprune->do_initial_prune = pinfo->do_initial_prune;
- pprune->do_exec_prune = pinfo->do_exec_prune;
-
- /* Record if pruning would be useful at any level */
- prunestate->do_initial_prune |= pinfo->do_initial_prune;
- prunestate->do_exec_prune |= pinfo->do_exec_prune;
/*
* Accumulate the IDs of all PARAM_EXEC Params affecting the
@@ -1654,7 +1605,90 @@ ExecDestroyPartitionPruneState(PartitionPruneState *prunestate)
int j;
for (j = 0; j < prunedata->num_partrelprunedata; j++)
- relation_close(pprune[j].context.partrel, NoLock);
+ {
+ if (pprune[j].initial_pruning_steps)
+ relation_close(pprune[j].initial_context.partrel, NoLock);
+ if (pprune[j].exec_pruning_steps)
+ relation_close(pprune[j].exec_context.partrel, NoLock);
+ }
+ }
+}
+
+/*
+ * Initialize a PartitionPruneContext for the given list of pruning steps.
+ */
+static void
+ExecInitPruningContext(PartitionPruneContext *context,
+ Oid reloid,
+ List *pruning_steps,
+ PlanState *planstate)
+{
+ PartitionKey partkey;
+ PartitionDesc partdesc;
+ int n_steps;
+ int partnatts;
+ ListCell *lc;
+
+ /*
+ * We need to hold a pin on the partitioned table's relcache entry
+ * so that we can rely on its copies of the table's partition key
+ * and partition descriptor. We need not get a lock though; one
+ * should have been acquired already by InitPlan or
+ * ExecLockNonLeafAppendTables.
+ */
+ context->partrel = relation_open(reloid, NoLock);
+
+ partkey = RelationGetPartitionKey(context->partrel);
+ partdesc = RelationGetPartitionDesc(context->partrel);
+
+ n_steps = list_length(pruning_steps);
+
+ context->strategy = partkey->strategy;
+ context->partnatts = partnatts = partkey->partnatts;
+ context->nparts = partdesc->nparts;
+ context->boundinfo = partdesc->boundinfo;
+ context->partcollation = partkey->partcollation;
+ context->partsupfunc = partkey->partsupfunc;
+
+ /* We'll look up type-specific support functions as needed */
+ context->stepcmpfuncs = (FmgrInfo *)
+ palloc0(sizeof(FmgrInfo) * n_steps * partnatts);
+
+ context->ppccontext = CurrentMemoryContext;
+ context->planstate = planstate;
+
+ /* Initialize expression state for each expression we need */
+ context->exprstates = (ExprState **)
+ palloc0(sizeof(ExprState *) * n_steps * partnatts);
+ foreach(lc, pruning_steps)
+ {
+ PartitionPruneStepOp *step = (PartitionPruneStepOp *) lfirst(lc);
+ ListCell *lc2;
+ int keyno;
+
+ /* not needed for other step kinds */
+ if (!IsA(step, PartitionPruneStepOp))
+ continue;
+
+ Assert(list_length(step->exprs) <= partnatts);
+
+ keyno = 0;
+ foreach(lc2, step->exprs)
+ {
+ Expr *expr = (Expr *) lfirst(lc2);
+
+ /* not needed for Consts */
+ if (!IsA(expr, Const))
+ {
+ int stateidx = PruneCxtStateIdx(partnatts,
+ step->step.step_id,
+ keyno);
+
+ context->exprstates[stateidx] =
+ ExecInitExpr(expr, context->planstate);
+ }
+ keyno++;
+ }
}
}
@@ -1702,7 +1736,8 @@ ExecFindInitialMatchingSubPlans(PartitionPruneState *prunestate, int nsubplans)
find_matching_subplans_recurse(prunedata, pprune, true, &result);
/* Expression eval may have used space in node's ps_ExprContext too */
- ResetExprContext(pprune->context.planstate->ps_ExprContext);
+ if (pprune->initial_pruning_steps)
+ ResetExprContext(pprune->initial_context.planstate->ps_ExprContext);
}
MemoryContextSwitchTo(oldcontext);
@@ -1769,7 +1804,7 @@ ExecFindInitialMatchingSubPlans(PartitionPruneState *prunestate, int nsubplans)
for (j = prunedata->num_partrelprunedata - 1; j >= 0; j--)
{
PartitionedRelPruningData *pprune = &prunedata->partrelprunedata[j];
- int nparts = pprune->context.nparts;
+ int nparts = pprune->nparts;
int k;
/* We just rebuild present_parts from scratch */
@@ -1854,7 +1889,8 @@ ExecFindMatchingSubPlans(PartitionPruneState *prunestate)
find_matching_subplans_recurse(prunedata, pprune, false, &result);
/* Expression eval may have used space in node's ps_ExprContext too */
- ResetExprContext(pprune->context.planstate->ps_ExprContext);
+ if (pprune->exec_pruning_steps)
+ ResetExprContext(pprune->exec_context.planstate->ps_ExprContext);
}
MemoryContextSwitchTo(oldcontext);
@@ -1890,15 +1926,15 @@ find_matching_subplans_recurse(PartitionPruningData *prunedata,
check_stack_depth();
/* Only prune if pruning would be useful at this level. */
- if (initial_prune ? pprune->do_initial_prune : pprune->do_exec_prune)
+ if (initial_prune && pprune->initial_pruning_steps)
{
- PartitionPruneContext *context = &pprune->context;
-
- /* Set whether we can evaluate PARAM_EXEC Params or not */
- context->evalexecparams = !initial_prune;
-
- partset = get_matching_partitions(context,
- pprune->pruning_steps);
+ partset = get_matching_partitions(&pprune->initial_context,
+ pprune->initial_pruning_steps);
+ }
+ else if (!initial_prune && pprune->exec_pruning_steps)
+ {
+ partset = get_matching_partitions(&pprune->exec_context,
+ pprune->exec_pruning_steps);
}
else
{