v3-0001-delta.patch
text/plain
Filename: v3-0001-delta.patch
Type: text/plain
Part: 0
Patch
Same data as JSON:
GET /api/v1/attachments/:id/patch
the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes.
API reference →
Format: unified
Series: patch v3-0001
| File | + | − |
|---|---|---|
| src/backend/executor/execPartition.c | 151 | 177 |
| src/backend/optimizer/plan/createplan.c | 17 | 7 |
| src/backend/partitioning/partprune.c | 42 | 33 |
| src/include/executor/execPartition.h | 1 | 12 |
| src/include/partitioning/partprune.h | 1 | 0 |
diff --git a/src/backend/executor/execPartition.c b/src/backend/executor/execPartition.c
index dac789d414..f81ff672ca 100644
--- a/src/backend/executor/execPartition.c
+++ b/src/backend/executor/execPartition.c
@@ -48,7 +48,7 @@ static char *ExecBuildSlotPartitionKeyDescription(Relation rel,
bool *isnull,
int maxfieldlen);
static List *adjust_partition_tlist(List *tlist, TupleConversionMap *map);
-static void find_matching_subplans_recurse(PartitionPruningData *pprune,
+static void find_matching_subplans_recurse(PartitionPruneState *prunestate,
PartitionedRelPruningData *prelprune,
bool initial_prune,
Bitmapset **validsubplans);
@@ -1396,14 +1396,10 @@ adjust_partition_tlist(List *tlist, TupleConversionMap *map)
*
* 'partitionpruneinfo' is a PartitionPruneInfo as generated by
* make_partition_pruneinfo. Here we build a PartitionPruneState containing a
- * PartitionPruningData for each partitionpruneinfo->prune_infos, in
- * turn, a PartitionedRelPruningData is created for each
- * PartitionedRelPruneInfo stored in each 'prune_infos'. This two-level system
- * is required in order to support run-time pruning with UNION ALL parents
- * containing one or more partitioned tables as children. The data stored in
- * each PartitionedRelPruningData can be re-used each time we re-evaluate
- * which partitions match the pruning steps provided in each
- * PartitionedRelPruneInfo.
+ * PartitionedRelPruningData for each PartitionedRelPruneInfo
+ * in partitionpruneinfo->prune_infos. The data stored in each
+ * PartitionedRelPruningData can be re-used each time we re-evaluate which
+ * partitions match the pruning steps provided in each PartitionedRelPruneInfo.
*/
PartitionPruneState *
ExecCreatePartitionPruneState(PlanState *planstate,
@@ -1422,8 +1418,8 @@ ExecCreatePartitionPruneState(PlanState *planstate,
* Allocate the data structure
*/
prunestate = (PartitionPruneState *)
- palloc(offsetof(PartitionPruneState, partprunedata) +
- sizeof(PartitionPruningData *) * n_part_hierarchies);
+ palloc(offsetof(PartitionPruneState, partrelprunedata) +
+ sizeof(PartitionedRelPruningData) * n_part_hierarchies);
prunestate->num_partprunedata = n_part_hierarchies;
prunestate->do_initial_prune = false; /* may be set below */
@@ -1445,125 +1441,109 @@ ExecCreatePartitionPruneState(PlanState *planstate,
i = 0;
foreach(lc, partitionpruneinfo->prune_infos)
{
- ListCell *lc2;
- List *partrelpruneinfos = lfirst_node(List, lc);
- PartitionPruningData *prunedata;
- int npartrelpruneinfos = list_length(partrelpruneinfos);
- int j;
+ PartitionedRelPruneInfo *pinfo = castNode(PartitionedRelPruneInfo, lfirst(lc));
+ PartitionedRelPruningData *prelprune = &prunestate->partrelprunedata[i];
+ PartitionPruneContext *context = &prelprune->context;
+ PartitionDesc partdesc;
+ PartitionKey partkey;
+ int partnatts;
+ int n_steps;
+ ListCell *lc3;
- prunedata = palloc(offsetof(PartitionPruningData, partrelprunedata) +
- npartrelpruneinfos * sizeof(PartitionedRelPruningData));
- prunestate->partprunedata[i] = prunedata;
- prunedata->num_partrelprunedata = npartrelpruneinfos;
+ /*
+ * 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.
+ */
+ prelprune->subplan_map = palloc(sizeof(int) * pinfo->nparts);
+ memcpy(prelprune->subplan_map, pinfo->subplan_map,
+ sizeof(int) * pinfo->nparts);
- j = 0;
- foreach(lc2, partrelpruneinfos)
+ /* We can use the subpart_map verbatim, since we never modify it */
+ prelprune->subpart_map = pinfo->subpart_map;
+
+ /* present_parts is also subject to later modification */
+ prelprune->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.
+ */
+ 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)
{
- PartitionedRelPruneInfo *pinfo = castNode(PartitionedRelPruneInfo, lfirst(lc2));
- PartitionedRelPruningData *prelprune = &prunedata->partrelprunedata[j];
- PartitionPruneContext *context = &prelprune->context;
- PartitionDesc partdesc;
- PartitionKey partkey;
- int partnatts;
- int n_steps;
- ListCell *lc3;
+ PartitionPruneStepOp *step = (PartitionPruneStepOp *) lfirst(lc3);
+ ListCell *lc4;
+ int keyno;
- /*
- * 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.
- */
- prelprune->subplan_map = palloc(sizeof(int) * pinfo->nparts);
- memcpy(prelprune->subplan_map, pinfo->subplan_map,
- sizeof(int) * pinfo->nparts);
+ /* not needed for other step kinds */
+ if (!IsA(step, PartitionPruneStepOp))
+ continue;
- /* We can use the subpart_map verbatim, since we never modify it */
- prelprune->subpart_map = pinfo->subpart_map;
+ Assert(list_length(step->exprs) <= partnatts);
- /* present_parts is also subject to later modification */
- prelprune->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.
- */
- 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)
+ keyno = 0;
+ foreach(lc4, step->exprs)
{
- PartitionPruneStepOp *step = (PartitionPruneStepOp *) lfirst(lc3);
- ListCell *lc4;
- int keyno;
+ Expr *expr = (Expr *) lfirst(lc4);
- /* not needed for other step kinds */
- if (!IsA(step, PartitionPruneStepOp))
- continue;
-
- Assert(list_length(step->exprs) <= partnatts);
-
- keyno = 0;
- foreach(lc4, step->exprs)
+ /* not needed for Consts */
+ if (!IsA(expr, Const))
{
- Expr *expr = (Expr *) lfirst(lc4);
+ int stateidx = PruneCxtStateIdx(partnatts,
+ step->step.step_id,
+ keyno);
- /* 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++;
+ context->exprstates[stateidx] =
+ ExecInitExpr(expr, context->planstate);
}
+ keyno++;
}
-
- /* Array is not modified at runtime, so just point to plan's copy */
- context->exprhasexecparam = pinfo->hasexecparam;
-
- prelprune->pruning_steps = pinfo->pruning_steps;
- prelprune->do_initial_prune = pinfo->do_initial_prune;
- prelprune->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
- * partitioning decisions at this plan node.
- */
- prunestate->execparamids = bms_add_members(prunestate->execparamids,
- pinfo->execparamids);
-
- j++;
}
+
+ /* Array is not modified at runtime, so just point to plan's copy */
+ context->exprhasexecparam = pinfo->hasexecparam;
+
+ prelprune->pruning_steps = pinfo->pruning_steps;
+ prelprune->do_initial_prune = pinfo->do_initial_prune;
+ prelprune->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
+ * partitioning decisions at this plan node.
+ */
+ prunestate->execparamids = bms_add_members(prunestate->execparamids,
+ pinfo->execparamids);
+
i++;
}
return prunestate;
@@ -1579,17 +1559,14 @@ ExecCreatePartitionPruneState(PlanState *planstate,
void
ExecDestroyPartitionPruneState(PartitionPruneState *prunestate)
{
- PartitionPruningData **partprunedata = prunestate->partprunedata;
+ PartitionedRelPruningData *partrelprunedata = prunestate->partrelprunedata;
int i;
for (i = 0; i < prunestate->num_partprunedata; i++)
{
- PartitionPruningData *pprune = partprunedata[i];
- PartitionedRelPruningData *prunedata = pprune->partrelprunedata;
- int j;
+ PartitionedRelPruningData prunedata = partrelprunedata[i];
- for (j = 0; j < pprune->num_partrelprunedata; j++)
- relation_close(prunedata[j].context.partrel, NoLock);
+ relation_close(prunedata.context.partrel, NoLock);
}
}
@@ -1623,14 +1600,16 @@ ExecFindInitialMatchingSubPlans(PartitionPruneState *prunestate, int nsubplans)
for (i = 0; i < prunestate->num_partprunedata; i++)
{
- PartitionPruningData *pprune;
PartitionedRelPruningData *prelprune;
- pprune = prunestate->partprunedata[i];
- prelprune = &pprune->partrelprunedata[0];
+ prelprune = &prunestate->partrelprunedata[i];
+
+ /* Only call find_matching_subplans_recurse on root table. */
+ if (prelprune->context.partrel->rd_rel->relispartition)
+ continue;
/* Perform pruning without using PARAM_EXEC Params */
- find_matching_subplans_recurse(pprune, prelprune, true, &result);
+ find_matching_subplans_recurse(prunestate, prelprune, true, &result);
/* Expression eval may have used space in node's ps_ExprContext too */
ResetExprContext(prelprune->context.planstate->ps_ExprContext);
@@ -1681,58 +1660,50 @@ ExecFindInitialMatchingSubPlans(PartitionPruneState *prunestate, int nsubplans)
* 'present_parts'.
*/
- for (i = 0; i < prunestate->num_partprunedata; i++)
+ for (i = prunestate->num_partprunedata - 1; i >= 0; i--)
{
- int j;
- PartitionPruningData *prunedata;
+ PartitionedRelPruningData *pprune;
+ int nparts;
+ int k;
- prunedata = prunestate->partprunedata[i];
+ pprune = &prunestate->partrelprunedata[i];
+ nparts = pprune->context.nparts;
+ /* We just rebuild present_parts from scratch */
+ bms_free(pprune->present_parts);
+ pprune->present_parts = NULL;
- for (j = prunedata->num_partrelprunedata - 1; j >= 0; j--)
+ for (k = 0; k < nparts; k++)
{
- PartitionedRelPruningData *pprune;
- int nparts;
- int k;
+ int oldidx = pprune->subplan_map[k];
+ int subidx;
- pprune = &prunedata->partrelprunedata[j];
- nparts = pprune->context.nparts;
- /* We just rebuild present_parts from scratch */
- bms_free(pprune->present_parts);
- pprune->present_parts = NULL;
-
- for (k = 0; k < nparts; k++)
+ /*
+ * If this partition existed as a subplan then change the
+ * old subplan index to the new subplan index. The new
+ * index may become -1 if the partition was pruned above,
+ * or it may just come earlier in the subplan list due to
+ * some subplans being removed earlier in the list. If
+ * it's a subpartition, add it to present_parts unless
+ * it's entirely pruned.
+ */
+ if (oldidx >= 0)
{
- int oldidx = pprune->subplan_map[k];
- int subidx;
+ Assert(oldidx < nsubplans);
+ pprune->subplan_map[k] = new_subplan_indexes[oldidx];
- /*
- * If this partition existed as a subplan then change the
- * old subplan index to the new subplan index. The new
- * index may become -1 if the partition was pruned above,
- * or it may just come earlier in the subplan list due to
- * some subplans being removed earlier in the list. If
- * it's a subpartition, add it to present_parts unless
- * it's entirely pruned.
- */
- if (oldidx >= 0)
- {
- Assert(oldidx < nsubplans);
- pprune->subplan_map[k] = new_subplan_indexes[oldidx];
+ if (new_subplan_indexes[oldidx] >= 0)
+ pprune->present_parts =
+ bms_add_member(pprune->present_parts, k);
+ }
+ else if ((subidx = pprune->subpart_map[k]) >= 0)
+ {
+ PartitionedRelPruningData *subprune;
- if (new_subplan_indexes[oldidx] >= 0)
- pprune->present_parts =
- bms_add_member(pprune->present_parts, k);
- }
- else if ((subidx = pprune->subpart_map[k]) >= 0)
- {
- PartitionedRelPruningData *subprune;
+ subprune = &prunestate->partrelprunedata[subidx];
- subprune = &prunedata->partrelprunedata[subidx];
-
- if (!bms_is_empty(subprune->present_parts))
- pprune->present_parts =
- bms_add_member(pprune->present_parts, k);
- }
+ if (!bms_is_empty(subprune->present_parts))
+ pprune->present_parts =
+ bms_add_member(pprune->present_parts, k);
}
}
}
@@ -1764,18 +1735,21 @@ ExecFindMatchingSubPlans(PartitionPruneState *prunestate)
for (i = 0; i < prunestate->num_partprunedata; i++)
{
- PartitionPruningData *pprune;
PartitionedRelPruningData *prelprune;
- pprune = prunestate->partprunedata[i];
- prelprune = &pprune->partrelprunedata[0];
+ prelprune = &prunestate->partrelprunedata[i];
- find_matching_subplans_recurse(pprune, prelprune, false, &result);
+ /* Only call find_matching_subplans_recurse on root table. */
+ if (prelprune->context.partrel->rd_rel->relispartition)
+ continue;
+
+ find_matching_subplans_recurse(prunestate, prelprune, false, &result);
/* Expression eval may have used space in node's ps_ExprContext too */
ResetExprContext(prelprune->context.planstate->ps_ExprContext);
}
+
MemoryContextSwitchTo(oldcontext);
/* Copy result out of the temp context before we reset it */
@@ -1797,7 +1771,7 @@ ExecFindMatchingSubPlans(PartitionPruneState *prunestate)
* Adds valid (non-prunable) subplan IDs to *validsubplans
*/
static void
-find_matching_subplans_recurse(PartitionPruningData *pprune,
+find_matching_subplans_recurse(PartitionPruneState *prunestate,
PartitionedRelPruningData *prelprune,
bool initial_prune,
Bitmapset **validsubplans)
@@ -1841,8 +1815,8 @@ find_matching_subplans_recurse(PartitionPruningData *pprune,
int partidx = prelprune->subpart_map[i];
if (partidx >= 0)
- find_matching_subplans_recurse(pprune,
- &pprune->partrelprunedata[partidx],
+ find_matching_subplans_recurse(prunestate,
+ &prunestate->partrelprunedata[partidx],
initial_prune, validsubplans);
else
{
diff --git a/src/backend/optimizer/plan/createplan.c b/src/backend/optimizer/plan/createplan.c
index f9e6ad3ab7..c7872661c4 100644
--- a/src/backend/optimizer/plan/createplan.c
+++ b/src/backend/optimizer/plan/createplan.c
@@ -1033,6 +1033,7 @@ create_append_plan(PlannerInfo *root, AppendPath *best_path)
ListCell *subpaths;
RelOptInfo *rel = best_path->path.parent;
PartitionPruneInfo *partpruneinfo = NULL;
+ List *flattened_partitioned_rels = NIL;
/*
* The subpaths list could be empty, if every child was proven empty by
@@ -1083,6 +1084,9 @@ create_append_plan(PlannerInfo *root, AppendPath *best_path)
prunequal = extract_actual_clauses(rel->baserestrictinfo, false);
+ flattened_partitioned_rels =
+ flatten_partitioned_rels(best_path->partitioned_rels);
+
if (best_path->path.param_info)
{
List *prmquals = best_path->path.param_info->ppi_clauses;
@@ -1098,6 +1102,7 @@ create_append_plan(PlannerInfo *root, AppendPath *best_path)
partpruneinfo =
make_partition_pruneinfo(root, rel,
best_path->partitioned_rels,
+ flattened_partitioned_rels,
best_path->subpaths, prunequal);
}
@@ -1109,7 +1114,7 @@ create_append_plan(PlannerInfo *root, AppendPath *best_path)
*/
plan = make_append(subplans, best_path->first_partial_path,
- tlist, best_path->partitioned_rels,
+ tlist, flattened_partitioned_rels,
partpruneinfo);
copy_generic_path_info(&plan->plan, (Path *) best_path);
@@ -1135,6 +1140,7 @@ create_merge_append_plan(PlannerInfo *root, MergeAppendPath *best_path)
ListCell *subpaths;
RelOptInfo *rel = best_path->path.parent;
PartitionPruneInfo *partpruneinfo = NULL;
+ List *flattened_partitioned_rels = NIL;
/*
* We don't have the actual creation of the MergeAppend node split out
@@ -1233,6 +1239,9 @@ create_merge_append_plan(PlannerInfo *root, MergeAppendPath *best_path)
prunequal = extract_actual_clauses(rel->baserestrictinfo, false);
+ flattened_partitioned_rels =
+ flatten_partitioned_rels(best_path->partitioned_rels);
+
if (best_path->path.param_info)
{
@@ -1247,12 +1256,12 @@ create_merge_append_plan(PlannerInfo *root, MergeAppendPath *best_path)
if (prunequal != NIL)
partpruneinfo = make_partition_pruneinfo(root, rel,
- best_path->partitioned_rels,
- best_path->subpaths, prunequal);
+ best_path->partitioned_rels,
+ flattened_partitioned_rels,
+ best_path->subpaths, prunequal);
}
- node->partitioned_rels =
- flatten_partitioned_rels(best_path->partitioned_rels);
+ node->partitioned_rels = flattened_partitioned_rels;
node->mergeplans = subplans;
node->part_prune_info = partpruneinfo;
@@ -5006,7 +5015,7 @@ bitmap_subplan_mark_shared(Plan *plan)
/*
* flatten_partitioned_rels
* Convert List of Lists into a single List with all elements from the
-* sub-lists.
+ * sub-lists.
*/
static List *
flatten_partitioned_rels(List *partitioned_rels)
@@ -5380,8 +5389,9 @@ make_append(List *appendplans, int first_partial_plan,
plan->righttree = NULL;
node->appendplans = appendplans;
node->first_partial_plan = first_partial_plan;
- node->partitioned_rels = flatten_partitioned_rels(partitioned_rels);
+ node->partitioned_rels = partitioned_rels;
node->part_prune_info = partpruneinfo;
+
return node;
}
diff --git a/src/backend/partitioning/partprune.c b/src/backend/partitioning/partprune.c
index 9ce216c28b..490eb4090d 100644
--- a/src/backend/partitioning/partprune.c
+++ b/src/backend/partitioning/partprune.c
@@ -114,6 +114,7 @@ typedef struct PruneStepResult
static List *make_partitionedrel_pruneinfo(PlannerInfo *root,
RelOptInfo *parentrel,
int *relid_subplan_map,
+ int *relid_subpart_map,
List *partitioned_rels, List *prunequal,
Bitmapset **matchedsubplans);
static List *gen_partprune_steps(RelOptInfo *rel, List *clauses,
@@ -195,12 +196,15 @@ static bool partkey_datum_from_expr(PartitionPruneContext *context,
*/
PartitionPruneInfo *
make_partition_pruneinfo(PlannerInfo *root, RelOptInfo *parentrel,
- List *partitioned_rels, List *subpaths,
+ List *partitioned_rels,
+ List *flattened_partitioned_rels,
+ List *subpaths,
List *prunequal)
{
PartitionPruneInfo *pruneinfo;
Bitmapset *allmatchedsubplans = NULL;
int *relid_subplan_map;
+ int *relid_subpart_map;
ListCell *lc;
List *prunerelinfos;
int i;
@@ -230,6 +234,38 @@ make_partition_pruneinfo(PlannerInfo *root, RelOptInfo *parentrel,
relid_subplan_map[pathrel->relid] = i++;
}
+ /*
+ * Construct a temporary array to map from planner relids to index of the
+ * partitioned_rel. For convenience, we use 1-based indexes here, so that
+ * zero can represent an un-filled array entry.
+ *
+ * Also, since we're going to flatten the list before putting it into the
+ * plan, use indexes into the flattened list in the mapping arrays of
+ * resulting PartitionedRelPruneInfo nodes, instead of indexes into
+ * individual sub-lists.
+ */
+ relid_subpart_map = palloc0(sizeof(int) * root->simple_rel_array_size);
+
+ /*
+ * relid_subpart_map maps relid of a non-leaf partition to the index in
+ * 'partitioned_rels' of that rel (which will also be the index in the
+ * returned PartitionedRelPruneInfo list of the info for that partition).
+ */
+ i = 1;
+ foreach(lc, flattened_partitioned_rels)
+ {
+ Index rti = lfirst_int(lc);
+
+ Assert(rti < root->simple_rel_array_size);
+ /* No duplicates please */
+ Assert(relid_subpart_map[rti] == 0);
+ /* Same rel cannot be both leaf and non-leaf */
+ Assert(relid_subplan_map[rti] == 0);
+
+ relid_subpart_map[rti] = i++;
+ }
+
+
Assert(partitioned_rels->type == T_List);
prunerelinfos = NIL;
@@ -243,19 +279,22 @@ make_partition_pruneinfo(PlannerInfo *root, RelOptInfo *parentrel,
prelinfolist = make_partitionedrel_pruneinfo(root, parentrel,
relid_subplan_map,
+ relid_subpart_map,
rels, prunequal,
&matchedsubplans);
/* When pruning is possible, record the matched subplans */
if (prelinfolist != NIL)
{
- prunerelinfos = lappend(prunerelinfos, prelinfolist);
+ prunerelinfos = list_concat(prunerelinfos,
+ list_copy(prelinfolist));
allmatchedsubplans = bms_join(matchedsubplans,
allmatchedsubplans);
}
}
pfree(relid_subplan_map);
+ pfree(relid_subpart_map);
/*
* if none of the partition hierarchies had any useful run-time pruning
@@ -310,45 +349,17 @@ make_partition_pruneinfo(PlannerInfo *root, RelOptInfo *parentrel,
*/
static List *
make_partitionedrel_pruneinfo(PlannerInfo *root, RelOptInfo *parentrel,
- int *relid_subplan_map,
+ int *relid_subplan_map, int *relid_subpart_map,
List *partitioned_rels, List *prunequal,
Bitmapset **matchedsubplans)
{
RelOptInfo *targetpart = NULL;
List *prelinfolist = NIL;
bool doruntimeprune = false;
- bool hascontradictingquals = false;
ListCell *lc;
- int *relid_subpart_map;
Bitmapset *subplansfound = NULL;
int i;
- /*
- * Construct a temporary array to map from planner relids to index of the
- * partitioned_rel. For convenience, we use 1-based indexes here, so that
- * zero can represent an un-filled array entry.
- */
- relid_subpart_map = palloc0(sizeof(int) * root->simple_rel_array_size);
-
- /*
- * relid_subpart_map maps relid of a non-leaf partition to the index in
- * 'partitioned_rels' of that rel (which will also be the index in the
- * returned PartitionedRelPruneInfo list of the info for that partition).
- */
- i = 1;
- foreach(lc, partitioned_rels)
- {
- Index rti = lfirst_int(lc);
-
- Assert(rti < root->simple_rel_array_size);
- /* No duplicates please */
- Assert(relid_subpart_map[rti] == 0);
- /* Same rel cannot be both leaf and non-leaf */
- Assert(relid_subplan_map[rti] == 0);
-
- relid_subpart_map[rti] = i++;
- }
-
/* We now build a PartitionedRelPruneInfo for each partitioned rel */
foreach(lc, partitioned_rels)
{
@@ -477,8 +488,6 @@ make_partitionedrel_pruneinfo(PlannerInfo *root, RelOptInfo *parentrel,
prelinfolist = lappend(prelinfolist, prelinfo);
}
- pfree(relid_subpart_map);
-
if (!doruntimeprune)
return NIL;
diff --git a/src/include/executor/execPartition.h b/src/include/executor/execPartition.h
index 4327fd4cb1..5b6acac4f0 100644
--- a/src/include/executor/execPartition.h
+++ b/src/include/executor/execPartition.h
@@ -147,17 +147,6 @@ typedef struct PartitionedRelPruningData
bool do_exec_prune;
} PartitionedRelPruningData;
-/*
- * PartitionPruningData - Encapsulates an array of PartitionedRelPruningData
- * which belong to a single partition hierarchy containing 1 or more
- * partitions.
- */
-typedef struct PartitionPruningData
-{
- int num_partrelprunedata;
- PartitionedRelPruningData partrelprunedata[FLEXIBLE_ARRAY_MEMBER];
-} PartitionPruningData;
-
/*-----------------------
* PartitionPruneState - State object required for plan nodes to perform
* run-time partition pruning.
@@ -198,7 +187,7 @@ typedef struct PartitionPruneState
Bitmapset *execparamids;
Bitmapset *other_subplans;
MemoryContext prune_context;
- PartitionPruningData *partprunedata[FLEXIBLE_ARRAY_MEMBER];
+ PartitionedRelPruningData partrelprunedata[FLEXIBLE_ARRAY_MEMBER];
} PartitionPruneState;
extern PartitionTupleRouting *ExecSetupPartitionTupleRouting(ModifyTableState *mtstate,
diff --git a/src/include/partitioning/partprune.h b/src/include/partitioning/partprune.h
index df3bcb737d..79398d1cc1 100644
--- a/src/include/partitioning/partprune.h
+++ b/src/include/partitioning/partprune.h
@@ -77,6 +77,7 @@ typedef struct PartitionPruneContext
extern PartitionPruneInfo *make_partition_pruneinfo(PlannerInfo *root,
RelOptInfo *parentrel,
List *partitioned_rels,
+ List *flattened_partitioned_rels,
List *subpaths, List *prunequal);
extern Relids prune_append_rel_partitions(RelOptInfo *rel);
extern Bitmapset *get_matching_partitions(PartitionPruneContext *context,