diff --git a/src/backend/executor/execMain.c b/src/backend/executor/execMain.c index eaf6f31a15..00a1f158d8 100644 --- a/src/backend/executor/execMain.c +++ b/src/backend/executor/execMain.c @@ -824,7 +824,6 @@ InitPlan(QueryDesc *queryDesc, int eflags) ExecInitRangeTable(estate, rangeTable, plannedstmt->permInfos); estate->es_plannedstmt = plannedstmt; - estate->es_part_prune_infos = plannedstmt->partPruneInfos; /* * Next, build the ExecRowMark array from the PlanRowMark(s), if any. diff --git a/src/backend/executor/execParallel.c b/src/backend/executor/execParallel.c index aa3f283453..cc2b8ccab7 100644 --- a/src/backend/executor/execParallel.c +++ b/src/backend/executor/execParallel.c @@ -183,7 +183,6 @@ ExecSerializePlan(Plan *plan, EState *estate) pstmt->dependsOnRole = false; pstmt->parallelModeNeeded = false; pstmt->planTree = plan; - pstmt->partPruneInfos = estate->es_part_prune_infos; pstmt->rtable = estate->es_range_table; pstmt->permInfos = estate->es_rteperminfos; pstmt->resultRelations = NIL; diff --git a/src/backend/executor/execPartition.c b/src/backend/executor/execPartition.c index 9799968a42..eb8a87fd63 100644 --- a/src/backend/executor/execPartition.c +++ b/src/backend/executor/execPartition.c @@ -1778,9 +1778,6 @@ adjust_partition_colnos_using_map(List *colnos, AttrMap *attrMap) * Initialize data structure needed for run-time partition pruning and * do initial pruning if needed * - * 'root_parent_relids' identifies the relation to which both the parent plan - * and the PartitionPruneInfo given by 'part_prune_index' belong. - * * On return, *initially_valid_subplans is assigned the set of indexes of * child subplans that must be initialized along with the parent plan node. * Initial pruning is performed here if needed and in that case only the @@ -1793,24 +1790,11 @@ adjust_partition_colnos_using_map(List *colnos, AttrMap *attrMap) PartitionPruneState * ExecInitPartitionPruning(PlanState *planstate, int n_total_subplans, - int part_prune_index, - Bitmapset *root_parent_relids, + PartitionPruneInfo *pruneinfo, Bitmapset **initially_valid_subplans) { PartitionPruneState *prunestate; EState *estate = planstate->state; - PartitionPruneInfo *pruneinfo; - - /* Obtain the pruneinfo we need, and make sure it's the right one */ - pruneinfo = list_nth(estate->es_part_prune_infos, part_prune_index); - if (!bms_equal(root_parent_relids, pruneinfo->root_parent_relids)) - ereport(ERROR, - errcode(ERRCODE_INTERNAL_ERROR), - errmsg_internal("mismatching PartitionPruneInfo found at part_prune_index %d", - part_prune_index), - errdetail_internal("plan node relids %s, pruneinfo relids %s", - bmsToString(root_parent_relids), - bmsToString(pruneinfo->root_parent_relids))); /* We may need an expression context to evaluate partition exprs */ ExecAssignExprContext(estate, planstate); diff --git a/src/backend/executor/execUtils.c b/src/backend/executor/execUtils.c index 872cbd454d..25aba9a243 100644 --- a/src/backend/executor/execUtils.c +++ b/src/backend/executor/execUtils.c @@ -123,7 +123,6 @@ CreateExecutorState(void) estate->es_rowmarks = NULL; estate->es_rteperminfos = NIL; estate->es_plannedstmt = NULL; - estate->es_part_prune_infos = NIL; estate->es_junkFilter = NULL; diff --git a/src/backend/executor/nodeAppend.c b/src/backend/executor/nodeAppend.c index c185b11c67..609df6b9e6 100644 --- a/src/backend/executor/nodeAppend.c +++ b/src/backend/executor/nodeAppend.c @@ -134,7 +134,7 @@ ExecInitAppend(Append *node, EState *estate, int eflags) appendstate->as_begun = false; /* If run-time partition pruning is enabled, then set that up now */ - if (node->part_prune_index >= 0) + if (node->part_prune_info != NULL) { PartitionPruneState *prunestate; @@ -145,8 +145,7 @@ ExecInitAppend(Append *node, EState *estate, int eflags) */ prunestate = ExecInitPartitionPruning(&appendstate->ps, list_length(node->appendplans), - node->part_prune_index, - node->apprelids, + node->part_prune_info, &validsubplans); appendstate->as_prune_state = prunestate; nplans = bms_num_members(validsubplans); diff --git a/src/backend/executor/nodeMergeAppend.c b/src/backend/executor/nodeMergeAppend.c index 399b39c598..21b5726e6e 100644 --- a/src/backend/executor/nodeMergeAppend.c +++ b/src/backend/executor/nodeMergeAppend.c @@ -82,7 +82,7 @@ ExecInitMergeAppend(MergeAppend *node, EState *estate, int eflags) mergestate->ps.ExecProcNode = ExecMergeAppend; /* If run-time partition pruning is enabled, then set that up now */ - if (node->part_prune_index >= 0) + if (node->part_prune_info != NULL) { PartitionPruneState *prunestate; @@ -93,8 +93,7 @@ ExecInitMergeAppend(MergeAppend *node, EState *estate, int eflags) */ prunestate = ExecInitPartitionPruning(&mergestate->ps, list_length(node->mergeplans), - node->part_prune_index, - node->apprelids, + node->part_prune_info, &validsubplans); mergestate->ms_prune_state = prunestate; nplans = bms_num_members(validsubplans); diff --git a/src/backend/optimizer/plan/createplan.c b/src/backend/optimizer/plan/createplan.c index 910ffbf1e1..4bb38160b3 100644 --- a/src/backend/optimizer/plan/createplan.c +++ b/src/backend/optimizer/plan/createplan.c @@ -1203,6 +1203,7 @@ create_append_plan(PlannerInfo *root, AppendPath *best_path, int flags) ListCell *subpaths; int nasyncplans = 0; RelOptInfo *rel = best_path->path.parent; + PartitionPruneInfo *partpruneinfo = NULL; int nodenumsortkeys = 0; AttrNumber *nodeSortColIdx = NULL; Oid *nodeSortOperators = NULL; @@ -1353,9 +1354,6 @@ create_append_plan(PlannerInfo *root, AppendPath *best_path, int flags) subplans = lappend(subplans, subplan); } - /* Set below if we find quals that we can use to run-time prune */ - plan->part_prune_index = -1; - /* * If any quals exist, they may be useful to perform further partition * pruning during execution. Gather information needed by the executor to @@ -1379,14 +1377,16 @@ create_append_plan(PlannerInfo *root, AppendPath *best_path, int flags) } if (prunequal != NIL) - plan->part_prune_index = make_partition_pruneinfo(root, rel, - best_path->subpaths, - prunequal); + partpruneinfo = + make_partition_pruneinfo(root, rel, + best_path->subpaths, + prunequal); } plan->appendplans = subplans; plan->nasyncplans = nasyncplans; plan->first_partial_plan = best_path->first_partial_path; + plan->part_prune_info = partpruneinfo; copy_generic_path_info(&plan->plan, (Path *) best_path); @@ -1425,6 +1425,7 @@ create_merge_append_plan(PlannerInfo *root, MergeAppendPath *best_path, List *subplans = NIL; ListCell *subpaths; RelOptInfo *rel = best_path->path.parent; + PartitionPruneInfo *partpruneinfo = NULL; /* * We don't have the actual creation of the MergeAppend node split out @@ -1517,9 +1518,6 @@ create_merge_append_plan(PlannerInfo *root, MergeAppendPath *best_path, subplans = lappend(subplans, subplan); } - /* Set below if we find quals that we can use to run-time prune */ - node->part_prune_index = -1; - /* * If any quals exist, they may be useful to perform further partition * pruning during execution. Gather information needed by the executor to @@ -1535,13 +1533,13 @@ create_merge_append_plan(PlannerInfo *root, MergeAppendPath *best_path, Assert(best_path->path.param_info == NULL); if (prunequal != NIL) - node->part_prune_index = make_partition_pruneinfo(root, rel, - best_path->subpaths, - prunequal); + partpruneinfo = make_partition_pruneinfo(root, rel, + best_path->subpaths, + prunequal); } node->mergeplans = subplans; - + node->part_prune_info = partpruneinfo; /* * If prepare_sort_from_pathkeys added sort columns, but we were told to diff --git a/src/backend/optimizer/plan/planner.c b/src/backend/optimizer/plan/planner.c index 502ccbcea2..1e4dd27dba 100644 --- a/src/backend/optimizer/plan/planner.c +++ b/src/backend/optimizer/plan/planner.c @@ -522,7 +522,6 @@ standard_planner(Query *parse, const char *query_string, int cursorOptions, result->dependsOnRole = glob->dependsOnRole; result->parallelModeNeeded = glob->parallelModeNeeded; result->planTree = top_plan; - result->partPruneInfos = glob->partPruneInfos; result->rtable = glob->finalrtable; result->permInfos = glob->finalrteperminfos; result->resultRelations = glob->resultRelations; diff --git a/src/backend/optimizer/plan/setrefs.c b/src/backend/optimizer/plan/setrefs.c index 1812db7f2f..f6f8a79354 100644 --- a/src/backend/optimizer/plan/setrefs.c +++ b/src/backend/optimizer/plan/setrefs.c @@ -350,29 +350,6 @@ set_plan_references(PlannerInfo *root, Plan *plan) palloc0(list_length(glob->subplans) * sizeof(bool)); } - /* Also fix up the information in PartitionPruneInfos. */ - foreach(lc, root->partPruneInfos) - { - PartitionPruneInfo *pruneinfo = lfirst(lc); - ListCell *l; - - pruneinfo->root_parent_relids = - offset_relid_set(pruneinfo->root_parent_relids, rtoffset); - foreach(l, pruneinfo->prune_infos) - { - List *prune_infos = lfirst(l); - ListCell *l2; - - foreach(l2, prune_infos) - { - PartitionedRelPruneInfo *pinfo = lfirst(l2); - - /* RT index of the table to which the pinfo belongs. */ - pinfo->rtindex += rtoffset; - } - } - } - /* Now fix the Plan tree */ result = set_plan_refs(root, plan, rtoffset); @@ -1728,29 +1705,6 @@ set_customscan_references(PlannerInfo *root, cscan->custom_relids = offset_relid_set(cscan->custom_relids, rtoffset); } -/* - * register_partpruneinfo - * Subroutine for set_append_references and set_mergeappend_references - * - * Add the PartitionPruneInfo from root->partPruneInfos at the given index - * into PlannerGlobal->partPruneInfos and return its index there. - */ -static int -register_partpruneinfo(PlannerInfo *root, int part_prune_index) -{ - PlannerGlobal *glob = root->glob; - PartitionPruneInfo *pruneinfo; - - Assert(part_prune_index >= 0 && - part_prune_index < list_length(root->partPruneInfos)); - pruneinfo = list_nth_node(PartitionPruneInfo, root->partPruneInfos, - part_prune_index); - - glob->partPruneInfos = lappend(glob->partPruneInfos, pruneinfo); - - return list_length(glob->partPruneInfos) - 1; -} - /* * set_append_references * Do set_plan_references processing on an Append @@ -1803,12 +1757,21 @@ set_append_references(PlannerInfo *root, aplan->apprelids = offset_relid_set(aplan->apprelids, rtoffset); - /* - * Add PartitionPruneInfo, if any, to PlannerGlobal and update the index. - */ - if (aplan->part_prune_index >= 0) - aplan->part_prune_index = - register_partpruneinfo(root, aplan->part_prune_index); + if (aplan->part_prune_info) + { + foreach(l, aplan->part_prune_info->prune_infos) + { + List *prune_infos = lfirst(l); + ListCell *l2; + + foreach(l2, prune_infos) + { + PartitionedRelPruneInfo *pinfo = lfirst(l2); + + pinfo->rtindex += rtoffset; + } + } + } /* We don't need to recurse to lefttree or righttree ... */ Assert(aplan->plan.lefttree == NULL); @@ -1870,12 +1833,21 @@ set_mergeappend_references(PlannerInfo *root, mplan->apprelids = offset_relid_set(mplan->apprelids, rtoffset); - /* - * Add PartitionPruneInfo, if any, to PlannerGlobal and update the index. - */ - if (mplan->part_prune_index >= 0) - mplan->part_prune_index = - register_partpruneinfo(root, mplan->part_prune_index); + if (mplan->part_prune_info) + { + foreach(l, mplan->part_prune_info->prune_infos) + { + List *prune_infos = lfirst(l); + ListCell *l2; + + foreach(l2, prune_infos) + { + PartitionedRelPruneInfo *pinfo = lfirst(l2); + + pinfo->rtindex += rtoffset; + } + } + } /* We don't need to recurse to lefttree or righttree ... */ Assert(mplan->plan.lefttree == NULL); diff --git a/src/backend/partitioning/partprune.c b/src/backend/partitioning/partprune.c index 0fb1035127..7179b22a05 100644 --- a/src/backend/partitioning/partprune.c +++ b/src/backend/partitioning/partprune.c @@ -210,20 +210,16 @@ static void partkey_datum_from_expr(PartitionPruneContext *context, /* * make_partition_pruneinfo - * Checks if the given set of quals can be used to build pruning steps - * that the executor can use to prune away unneeded partitions. If - * suitable quals are found then a PartitionPruneInfo is built and tagged - * onto the PlannerInfo's partPruneInfos list. - * - * The return value is the 0-based index of the item added to the - * partPruneInfos list or -1 if nothing was added. + * Builds a PartitionPruneInfo which can be used in the executor to allow + * additional partition pruning to take place. Returns NULL when + * partition pruning would be useless. * * 'parentrel' is the RelOptInfo for an appendrel, and 'subpaths' is the list * of scan paths for its child rels. * 'prunequal' is a list of potential pruning quals (i.e., restriction * clauses that are applicable to the appendrel). */ -int +PartitionPruneInfo * make_partition_pruneinfo(PlannerInfo *root, RelOptInfo *parentrel, List *subpaths, List *prunequal) @@ -337,11 +333,10 @@ make_partition_pruneinfo(PlannerInfo *root, RelOptInfo *parentrel, * quals, then we can just not bother with run-time pruning. */ if (prunerelinfos == NIL) - return -1; + return NULL; /* Else build the result data structure */ pruneinfo = makeNode(PartitionPruneInfo); - pruneinfo->root_parent_relids = parentrel->relids; pruneinfo->prune_infos = prunerelinfos; /* @@ -364,9 +359,7 @@ make_partition_pruneinfo(PlannerInfo *root, RelOptInfo *parentrel, else pruneinfo->other_subplans = NULL; - root->partPruneInfos = lappend(root->partPruneInfos, pruneinfo); - - return list_length(root->partPruneInfos) - 1; + return pruneinfo; } /* diff --git a/src/include/catalog/catversion.h b/src/include/catalog/catversion.h index 44d7e521bd..a091f2ca26 100644 --- a/src/include/catalog/catversion.h +++ b/src/include/catalog/catversion.h @@ -57,6 +57,6 @@ */ /* yyyymmddN */ -#define CATALOG_VERSION_NO 202304211 +#define CATALOG_VERSION_NO 202305041 #endif diff --git a/src/include/executor/execPartition.h b/src/include/executor/execPartition.h index ee487e42dd..15ec869ac8 100644 --- a/src/include/executor/execPartition.h +++ b/src/include/executor/execPartition.h @@ -123,9 +123,9 @@ typedef struct PartitionPruneState extern PartitionPruneState *ExecInitPartitionPruning(PlanState *planstate, int n_total_subplans, - int part_prune_index, - Bitmapset *root_parent_relids, + PartitionPruneInfo *pruneinfo, Bitmapset **initially_valid_subplans); extern Bitmapset *ExecFindMatchingSubPlans(PartitionPruneState *prunestate, bool initial_prune); + #endif /* EXECPARTITION_H */ diff --git a/src/include/nodes/execnodes.h b/src/include/nodes/execnodes.h index 695ff056ba..61b3517906 100644 --- a/src/include/nodes/execnodes.h +++ b/src/include/nodes/execnodes.h @@ -623,7 +623,6 @@ typedef struct EState * ExecRowMarks, or NULL if none */ List *es_rteperminfos; /* List of RTEPermissionInfo */ PlannedStmt *es_plannedstmt; /* link to top of plan tree */ - List *es_part_prune_infos; /* PlannedStmt.partPruneInfos */ const char *es_sourceText; /* Source text from QueryDesc */ JunkFilter *es_junkFilter; /* top-level junk filter, if any */ diff --git a/src/include/nodes/pathnodes.h b/src/include/nodes/pathnodes.h index cf28416da8..7d4f24d250 100644 --- a/src/include/nodes/pathnodes.h +++ b/src/include/nodes/pathnodes.h @@ -125,9 +125,6 @@ typedef struct PlannerGlobal /* "flat" list of AppendRelInfos */ List *appendRelations; - /* List of PartitionPruneInfo contained in the plan */ - List *partPruneInfos; - /* OIDs of relations the plan depends on */ List *relationOids; @@ -547,9 +544,6 @@ struct PlannerInfo /* Does this query modify any partition key columns? */ bool partColsUpdated; - - /* PartitionPruneInfos added in this query's plan. */ - List *partPruneInfos; }; diff --git a/src/include/nodes/plannodes.h b/src/include/nodes/plannodes.h index 659bd05c0c..1b787fe031 100644 --- a/src/include/nodes/plannodes.h +++ b/src/include/nodes/plannodes.h @@ -70,9 +70,6 @@ typedef struct PlannedStmt struct Plan *planTree; /* tree of Plan nodes */ - List *partPruneInfos; /* List of PartitionPruneInfo contained in the - * plan */ - List *rtable; /* list of RangeTblEntry nodes */ List *permInfos; /* list of RTEPermissionInfo nodes for rtable @@ -276,8 +273,8 @@ typedef struct Append */ int first_partial_plan; - /* Index to PlannerInfo.partPruneInfos or -1 if no run-time pruning */ - int part_prune_index; + /* Info for run-time subplan pruning; NULL if we're not doing that */ + struct PartitionPruneInfo *part_prune_info; } Append; /* ---------------- @@ -311,8 +308,8 @@ typedef struct MergeAppend /* NULLS FIRST/LAST directions */ bool *nullsFirst pg_node_attr(array_size(numCols)); - /* Index to PlannerInfo.partPruneInfos or -1 if no run-time pruning */ - int part_prune_index; + /* Info for run-time subplan pruning; NULL if we're not doing that */ + struct PartitionPruneInfo *part_prune_info; } MergeAppend; /* ---------------- @@ -1414,8 +1411,6 @@ typedef struct PlanRowMark * Then, since an Append-type node could have multiple partitioning * hierarchies among its children, we have an unordered List of those Lists. * - * root_parent_relids RelOptInfo.relids of the relation to which the parent - * plan node and this PartitionPruneInfo node belong * prune_infos List of Lists containing PartitionedRelPruneInfo nodes, * one sublist per run-time-prunable partition hierarchy * appearing in the parent plan node's subplans. @@ -1428,7 +1423,6 @@ typedef struct PartitionPruneInfo pg_node_attr(no_equal, no_query_jumble) NodeTag type; - Bitmapset *root_parent_relids; List *prune_infos; Bitmapset *other_subplans; } PartitionPruneInfo; diff --git a/src/include/partitioning/partprune.h b/src/include/partitioning/partprune.h index c0d6889d47..8636e04e37 100644 --- a/src/include/partitioning/partprune.h +++ b/src/include/partitioning/partprune.h @@ -70,10 +70,10 @@ typedef struct PartitionPruneContext #define PruneCxtStateIdx(partnatts, step_id, keyno) \ ((partnatts) * (step_id) + (keyno)) -extern int make_partition_pruneinfo(struct PlannerInfo *root, - struct RelOptInfo *parentrel, - List *subpaths, - List *prunequal); +extern PartitionPruneInfo *make_partition_pruneinfo(struct PlannerInfo *root, + struct RelOptInfo *parentrel, + List *subpaths, + List *prunequal); extern Bitmapset *prune_append_rel_partitions(struct RelOptInfo *rel); extern Bitmapset *get_matching_partitions(PartitionPruneContext *context, List *pruning_steps);