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

Lines changed: 130 additions & 118 deletions
Large diffs are not rendered by default.

src/backend/executor/nodeAppend.c

Lines changed: 25 additions & 28 deletions
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

Lines changed: 5 additions & 2 deletions
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

Lines changed: 8 additions & 2 deletions
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

Lines changed: 5 additions & 2 deletions
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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy