Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit d47cbf4

Browse files
committed
Perform runtime initial pruning outside ExecInitNode()
This commit builds on the prior change that moved PartitionPruneInfos out of individual plan nodes into a list in PlannedStmt, making it possible to initialize PartitionPruneStates without traversing the plan tree and perform runtime initial pruning before ExecInitNode() initializes the plan trees. These tasks are now handled in a new routine, ExecDoInitialPruning(), which is called by InitPlan() before calling ExecInitNode() on various plan trees. ExecDoInitialPruning() performs the initial pruning and saves the result -- a Bitmapset of indexes for surviving child subnodes -- in es_part_prune_results, a list in EState. PartitionPruneStates created for initial pruning are stored in es_part_prune_states, another list in EState, for later use during exec pruning. Both lists are parallel to es_part_prune_infos, which holds the PartitionPruneInfos from PlannedStmt, enabling shared indexing. PartitionPruneStates initialized in ExecDoInitialPruning() now include only the PartitionPruneContexts for initial pruning steps. Exec pruning contexts are initialized later in ExecInitPartitionExecPruning() when the parent plan node is initialized, as the exec pruning step expressions depend on the parent node's PlanState. The existing function PartitionPruneFixSubPlanMap() has been repurposed for this initialization to avoid duplicating a similar loop structure for finding PartitionedRelPruningData to initialize exec pruning contexts for. It has been renamed to InitExecPruningContexts() to reflect its new primary responsibility. The original logic to "fix subplan maps" remains intact but is now encapsulated within the renamed function. This commit removes two obsolete Asserts in partkey_datum_from_expr(). The ExprContext used for pruning expression evaluation is now independent of the parent PlanState, making these Asserts unnecessary. By centralizing pruning logic and decoupling it from the plan initialization step (ExecInitNode()), this change sets the stage for future patches that will use the result of initial pruning to save the overhead of redundant processing for pruned partitions. Reviewed-by: Robert Haas <robertmhaas@gmail.com> Reviewed-by: Tomas Vondra <tomas@vondra.me> Discussion: https://postgr.es/m/CA+HiwqFGkMSge6TgC9KQzde0ohpAycLQuV7ooitEEpbKB0O_mg@mail.gmail.com
1 parent f41d846 commit d47cbf4

File tree

8 files changed

+271
-114
lines changed

8 files changed

+271
-114
lines changed

src/backend/executor/execMain.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
#include "commands/matview.h"
4747
#include "commands/trigger.h"
4848
#include "executor/executor.h"
49+
#include "executor/execPartition.h"
4950
#include "executor/nodeSubplan.h"
5051
#include "foreign/fdwapi.h"
5152
#include "mb/pg_wchar.h"
@@ -855,6 +856,17 @@ InitPlan(QueryDesc *queryDesc, int eflags)
855856
estate->es_plannedstmt = plannedstmt;
856857
estate->es_part_prune_infos = plannedstmt->partPruneInfos;
857858

859+
/*
860+
* Perform runtime "initial" pruning to identify which child subplans,
861+
* corresponding to the children of plan nodes that contain
862+
* PartitionPruneInfo such as Append, will not be executed. The results,
863+
* which are bitmapsets of indexes of the child subplans that will be
864+
* executed, are saved in es_part_prune_results. These results correspond
865+
* to each PartitionPruneInfo entry, and the es_part_prune_results list is
866+
* parallel to es_part_prune_infos.
867+
*/
868+
ExecDoInitialPruning(estate);
869+
858870
/*
859871
* Next, build the ExecRowMark array from the PlanRowMark(s), if any.
860872
*/

src/backend/executor/execPartition.c

Lines changed: 223 additions & 91 deletions
Large diffs are not rendered by default.

src/backend/executor/nodeAppend.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -144,11 +144,11 @@ ExecInitAppend(Append *node, EState *estate, int eflags)
144144
* subplans to initialize (validsubplans) by taking into account the
145145
* result of performing initial pruning if any.
146146
*/
147-
prunestate = ExecInitPartitionPruning(&appendstate->ps,
148-
list_length(node->appendplans),
149-
node->part_prune_index,
150-
node->apprelids,
151-
&validsubplans);
147+
prunestate = ExecInitPartitionExecPruning(&appendstate->ps,
148+
list_length(node->appendplans),
149+
node->part_prune_index,
150+
node->apprelids,
151+
&validsubplans);
152152
appendstate->as_prune_state = prunestate;
153153
nplans = bms_num_members(validsubplans);
154154

src/backend/executor/nodeMergeAppend.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -92,11 +92,11 @@ ExecInitMergeAppend(MergeAppend *node, EState *estate, int eflags)
9292
* subplans to initialize (validsubplans) by taking into account the
9393
* result of performing initial pruning if any.
9494
*/
95-
prunestate = ExecInitPartitionPruning(&mergestate->ps,
96-
list_length(node->mergeplans),
97-
node->part_prune_index,
98-
node->apprelids,
99-
&validsubplans);
95+
prunestate = ExecInitPartitionExecPruning(&mergestate->ps,
96+
list_length(node->mergeplans),
97+
node->part_prune_index,
98+
node->apprelids,
99+
&validsubplans);
100100
mergestate->ms_prune_state = prunestate;
101101
nplans = bms_num_members(validsubplans);
102102

src/backend/partitioning/partprune.c

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3783,13 +3783,8 @@ partkey_datum_from_expr(PartitionPruneContext *context,
37833783
/*
37843784
* We should never see a non-Const in a step unless the caller has
37853785
* passed a valid ExprContext.
3786-
*
3787-
* When context->planstate is valid, context->exprcontext is same as
3788-
* context->planstate->ps_ExprContext.
37893786
*/
3790-
Assert(context->planstate != NULL || context->exprcontext != NULL);
3791-
Assert(context->planstate == NULL ||
3792-
(context->exprcontext == context->planstate->ps_ExprContext));
3787+
Assert(context->exprcontext != NULL);
37933788

37943789
exprstate = context->exprstates[stateidx];
37953790
ectx = context->exprcontext;

src/include/executor/execPartition.h

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,9 @@ extern void ExecCleanupTupleRouting(ModifyTableState *mtstate,
4242
* PartitionedRelPruneInfo (see plannodes.h); though note that here,
4343
* subpart_map contains indexes into PartitionPruningData.partrelprunedata[].
4444
*
45+
* partrel Partitioned table Relation; obtained by
46+
* ExecGetRangeTableRelation(estate, rti), where
47+
* rti is PartitionedRelPruneInfo.rtindex.
4548
* nparts Length of subplan_map[] and subpart_map[].
4649
* subplan_map Subplan index by partition index, or -1.
4750
* subpart_map Subpart index by partition index, or -1.
@@ -58,6 +61,7 @@ extern void ExecCleanupTupleRouting(ModifyTableState *mtstate,
5861
*/
5962
typedef struct PartitionedRelPruningData
6063
{
64+
Relation partrel;
6165
int nparts;
6266
int *subplan_map;
6367
int *subpart_map;
@@ -90,6 +94,8 @@ typedef struct PartitionPruningData
9094
* the clauses being unable to match to any tuple that the subplan could
9195
* possibly produce.
9296
*
97+
* econtext Standalone ExprContext to evaluate expressions in
98+
* the pruning steps
9399
* execparamids Contains paramids of PARAM_EXEC Params found within
94100
* any of the partprunedata structs. Pruning must be
95101
* done again each time the value of one of these
@@ -112,6 +118,7 @@ typedef struct PartitionPruningData
112118
*/
113119
typedef struct PartitionPruneState
114120
{
121+
ExprContext *econtext;
115122
Bitmapset *execparamids;
116123
Bitmapset *other_subplans;
117124
MemoryContext prune_context;
@@ -121,11 +128,12 @@ typedef struct PartitionPruneState
121128
PartitionPruningData *partprunedata[FLEXIBLE_ARRAY_MEMBER];
122129
} PartitionPruneState;
123130

124-
extern PartitionPruneState *ExecInitPartitionPruning(PlanState *planstate,
125-
int n_total_subplans,
126-
int part_prune_index,
127-
Bitmapset *relids,
128-
Bitmapset **initially_valid_subplans);
131+
extern void ExecDoInitialPruning(EState *estate);
132+
extern PartitionPruneState *ExecInitPartitionExecPruning(PlanState *planstate,
133+
int n_total_subplans,
134+
int part_prune_index,
135+
Bitmapset *relids,
136+
Bitmapset **initially_valid_subplans);
129137
extern Bitmapset *ExecFindMatchingSubPlans(PartitionPruneState *prunestate,
130138
bool initial_prune);
131139

src/include/nodes/execnodes.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -656,6 +656,8 @@ typedef struct EState
656656
List *es_rteperminfos; /* List of RTEPermissionInfo */
657657
PlannedStmt *es_plannedstmt; /* link to top of plan tree */
658658
List *es_part_prune_infos; /* List of PartitionPruneInfo */
659+
List *es_part_prune_states; /* List of PartitionPruneState */
660+
List *es_part_prune_results; /* List of Bitmapset */
659661
const char *es_sourceText; /* Source text from QueryDesc */
660662

661663
JunkFilter *es_junkFilter; /* top-level junk filter, if any */

src/include/nodes/plannodes.h

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -281,7 +281,11 @@ typedef struct Append
281281
*/
282282
int first_partial_plan;
283283

284-
/* Index to PlannerInfo.partPruneInfos or -1 if no run-time pruning */
284+
/*
285+
* Index into PlannedStmt.partPruneInfos and parallel lists in EState:
286+
* es_part_prune_states and es_part_prune_results. Set to -1 if no
287+
* run-time pruning is used.
288+
*/
285289
int part_prune_index;
286290
} Append;
287291

@@ -316,7 +320,11 @@ typedef struct MergeAppend
316320
/* NULLS FIRST/LAST directions */
317321
bool *nullsFirst pg_node_attr(array_size(numCols));
318322

319-
/* Index to PlannerInfo.partPruneInfos or -1 if no run-time pruning */
323+
/*
324+
* Index into PlannedStmt.partPruneInfos and parallel lists in EState:
325+
* es_part_prune_states and es_part_prune_results. Set to -1 if no
326+
* run-time pruning is used.
327+
*/
320328
int part_prune_index;
321329
} MergeAppend;
322330

0 commit comments

Comments
 (0)