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

Commit 73b7f48

Browse files
committed
Improve run-time partition pruning to handle any stable expression.
The initial coding of the run-time-pruning feature only coped with cases where the partition key(s) are compared to Params. That is a bit silly; we can allow it to work with any non-Var-containing stable expression, as long as we take special care with expressions containing PARAM_EXEC Params. The code is hardly any longer this way, and it's considerably clearer (IMO at least). Per gripe from Pavel Stehule. David Rowley, whacked around a bit by me Discussion: https://postgr.es/m/CAFj8pRBjrufA3ocDm8o4LPGNye9Y+pm1b9kCwode4X04CULG3g@mail.gmail.com
1 parent c83e202 commit 73b7f48

File tree

11 files changed

+461
-271
lines changed

11 files changed

+461
-271
lines changed

src/backend/executor/execPartition.c

+130-118
Large diffs are not rendered by default.

src/backend/executor/nodeAppend.c

+25-28
Original file line numberDiff line numberDiff line change
@@ -133,29 +133,27 @@ ExecInitAppend(Append *node, EState *estate, int eflags)
133133
{
134134
PartitionPruneState *prunestate;
135135

136+
/* We may need an expression context to evaluate partition exprs */
136137
ExecAssignExprContext(estate, &appendstate->ps);
137138

138139
prunestate = ExecSetupPartitionPruneState(&appendstate->ps,
139140
node->part_prune_infos);
140141

141-
/*
142-
* When there are external params matching the partition key we may be
143-
* able to prune away Append subplans now.
144-
*/
145-
if (!bms_is_empty(prunestate->extparams))
142+
/* Perform an initial partition prune, if required. */
143+
if (prunestate->do_initial_prune)
146144
{
147-
/* Determine which subplans match the external params */
145+
/* Determine which subplans survive initial pruning */
148146
validsubplans = ExecFindInitialMatchingSubPlans(prunestate,
149147
list_length(node->appendplans));
150148

151149
/*
152-
* If no subplans match the given parameters then we must handle
153-
* this case in a special way. The problem here is that code in
154-
* explain.c requires an Append to have at least one subplan in
155-
* order for it to properly determine the Vars in that subplan's
156-
* targetlist. We sidestep this issue by just initializing the
157-
* first subplan and setting as_whichplan to NO_MATCHING_SUBPLANS
158-
* to indicate that we don't need to scan any subnodes.
150+
* The case where no subplans survive pruning must be handled
151+
* specially. The problem here is that code in explain.c requires
152+
* an Append to have at least one subplan in order for it to
153+
* properly determine the Vars in that subplan's targetlist. We
154+
* sidestep this issue by just initializing the first subplan and
155+
* setting as_whichplan to NO_MATCHING_SUBPLANS to indicate that
156+
* we don't really need to scan any subnodes.
159157
*/
160158
if (bms_is_empty(validsubplans))
161159
{
@@ -175,22 +173,21 @@ ExecInitAppend(Append *node, EState *estate, int eflags)
175173
}
176174

177175
/*
178-
* If there's no exec params then no further pruning can be done, we
179-
* can just set the valid subplans to all remaining subplans.
176+
* If no runtime pruning is required, we can fill as_valid_subplans
177+
* immediately, preventing later calls to ExecFindMatchingSubPlans.
180178
*/
181-
if (bms_is_empty(prunestate->execparams))
179+
if (!prunestate->do_exec_prune)
182180
appendstate->as_valid_subplans = bms_add_range(NULL, 0, nplans - 1);
183181

184182
appendstate->as_prune_state = prunestate;
185-
186183
}
187184
else
188185
{
189186
nplans = list_length(node->appendplans);
190187

191188
/*
192189
* When run-time partition pruning is not enabled we can just mark all
193-
* subplans as valid, they must also all be initialized.
190+
* subplans as valid; they must also all be initialized.
194191
*/
195192
appendstate->as_valid_subplans = validsubplans =
196193
bms_add_range(NULL, 0, nplans - 1);
@@ -341,13 +338,13 @@ ExecReScanAppend(AppendState *node)
341338
int i;
342339

343340
/*
344-
* If any of the parameters being used for partition pruning have changed,
345-
* then we'd better unset the valid subplans so that they are reselected
346-
* for the new parameter values.
341+
* If any PARAM_EXEC Params used in pruning expressions have changed, then
342+
* we'd better unset the valid subplans so that they are reselected for
343+
* the new parameter values.
347344
*/
348345
if (node->as_prune_state &&
349346
bms_overlap(node->ps.chgParam,
350-
node->as_prune_state->execparams))
347+
node->as_prune_state->execparamids))
351348
{
352349
bms_free(node->as_valid_subplans);
353350
node->as_valid_subplans = NULL;
@@ -531,9 +528,9 @@ choose_next_subplan_for_leader(AppendState *node)
531528
node->as_whichplan = node->as_nplans - 1;
532529

533530
/*
534-
* If we've yet to determine the valid subplans for these parameters
535-
* then do so now. If run-time pruning is disabled then the valid
536-
* subplans will always be set to all subplans.
531+
* If we've yet to determine the valid subplans then do so now. If
532+
* run-time pruning is disabled then the valid subplans will always be
533+
* set to all subplans.
537534
*/
538535
if (node->as_valid_subplans == NULL)
539536
{
@@ -606,9 +603,9 @@ choose_next_subplan_for_worker(AppendState *node)
606603
node->as_pstate->pa_finished[node->as_whichplan] = true;
607604

608605
/*
609-
* If we've yet to determine the valid subplans for these parameters then
610-
* do so now. If run-time pruning is disabled then the valid subplans
611-
* will always be set to all subplans.
606+
* If we've yet to determine the valid subplans then do so now. If
607+
* run-time pruning is disabled then the valid subplans will always be set
608+
* to all subplans.
612609
*/
613610
else if (node->as_valid_subplans == NULL)
614611
{

src/backend/nodes/copyfuncs.c

+5-2
Original file line numberDiff line numberDiff line change
@@ -2175,10 +2175,13 @@ _copyPartitionPruneInfo(const PartitionPruneInfo *from)
21752175
COPY_NODE_FIELD(pruning_steps);
21762176
COPY_BITMAPSET_FIELD(present_parts);
21772177
COPY_SCALAR_FIELD(nparts);
2178+
COPY_SCALAR_FIELD(nexprs);
21782179
COPY_POINTER_FIELD(subnode_map, from->nparts * sizeof(int));
21792180
COPY_POINTER_FIELD(subpart_map, from->nparts * sizeof(int));
2180-
COPY_BITMAPSET_FIELD(extparams);
2181-
COPY_BITMAPSET_FIELD(execparams);
2181+
COPY_POINTER_FIELD(hasexecparam, from->nexprs * sizeof(bool));
2182+
COPY_SCALAR_FIELD(do_initial_prune);
2183+
COPY_SCALAR_FIELD(do_exec_prune);
2184+
COPY_BITMAPSET_FIELD(execparamids);
21822185

21832186
return newnode;
21842187
}

src/backend/nodes/outfuncs.c

+8-2
Original file line numberDiff line numberDiff line change
@@ -1742,6 +1742,7 @@ _outPartitionPruneInfo(StringInfo str, const PartitionPruneInfo *node)
17421742
WRITE_NODE_FIELD(pruning_steps);
17431743
WRITE_BITMAPSET_FIELD(present_parts);
17441744
WRITE_INT_FIELD(nparts);
1745+
WRITE_INT_FIELD(nexprs);
17451746

17461747
appendStringInfoString(str, " :subnode_map");
17471748
for (i = 0; i < node->nparts; i++)
@@ -1751,8 +1752,13 @@ _outPartitionPruneInfo(StringInfo str, const PartitionPruneInfo *node)
17511752
for (i = 0; i < node->nparts; i++)
17521753
appendStringInfo(str, " %d", node->subpart_map[i]);
17531754

1754-
WRITE_BITMAPSET_FIELD(extparams);
1755-
WRITE_BITMAPSET_FIELD(execparams);
1755+
appendStringInfoString(str, " :hasexecparam");
1756+
for (i = 0; i < node->nexprs; i++)
1757+
appendStringInfo(str, " %s", booltostr(node->hasexecparam[i]));
1758+
1759+
WRITE_BOOL_FIELD(do_initial_prune);
1760+
WRITE_BOOL_FIELD(do_exec_prune);
1761+
WRITE_BITMAPSET_FIELD(execparamids);
17561762
}
17571763

17581764
/*****************************************************************************

src/backend/nodes/readfuncs.c

+5-2
Original file line numberDiff line numberDiff line change
@@ -1363,10 +1363,13 @@ _readPartitionPruneInfo(void)
13631363
READ_NODE_FIELD(pruning_steps);
13641364
READ_BITMAPSET_FIELD(present_parts);
13651365
READ_INT_FIELD(nparts);
1366+
READ_INT_FIELD(nexprs);
13661367
READ_INT_ARRAY(subnode_map, local_node->nparts);
13671368
READ_INT_ARRAY(subpart_map, local_node->nparts);
1368-
READ_BITMAPSET_FIELD(extparams);
1369-
READ_BITMAPSET_FIELD(execparams);
1369+
READ_BOOL_ARRAY(hasexecparam, local_node->nexprs);
1370+
READ_BOOL_FIELD(do_initial_prune);
1371+
READ_BOOL_FIELD(do_exec_prune);
1372+
READ_BITMAPSET_FIELD(execparamids);
13701373

13711374
READ_DONE();
13721375
}

0 commit comments

Comments
 (0)