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,