diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2018-06-10 15:22:25 -0400 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2018-06-10 15:22:32 -0400 |
commit | 73b7f48f78d27b1baf1a6541cbaae0fe6bd6186d (patch) | |
tree | c5e92bd3ae8eed8d8cf3519c10b12982d44bcfa8 /src/backend/executor/nodeAppend.c | |
parent | c83e2029909c5411ca11fd841851016f1f9810e6 (diff) | |
download | postgresql-73b7f48f78d27b1baf1a6541cbaae0fe6bd6186d.tar.gz postgresql-73b7f48f78d27b1baf1a6541cbaae0fe6bd6186d.zip |
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
Diffstat (limited to 'src/backend/executor/nodeAppend.c')
-rw-r--r-- | src/backend/executor/nodeAppend.c | 53 |
1 files changed, 25 insertions, 28 deletions
diff --git a/src/backend/executor/nodeAppend.c b/src/backend/executor/nodeAppend.c index 6bc3e470bf7..6dd53e90ba8 100644 --- a/src/backend/executor/nodeAppend.c +++ b/src/backend/executor/nodeAppend.c @@ -133,29 +133,27 @@ ExecInitAppend(Append *node, EState *estate, int eflags) { PartitionPruneState *prunestate; + /* We may need an expression context to evaluate partition exprs */ ExecAssignExprContext(estate, &appendstate->ps); prunestate = ExecSetupPartitionPruneState(&appendstate->ps, node->part_prune_infos); - /* - * When there are external params matching the partition key we may be - * able to prune away Append subplans now. - */ - if (!bms_is_empty(prunestate->extparams)) + /* Perform an initial partition prune, if required. */ + if (prunestate->do_initial_prune) { - /* Determine which subplans match the external params */ + /* Determine which subplans survive initial pruning */ validsubplans = ExecFindInitialMatchingSubPlans(prunestate, list_length(node->appendplans)); /* - * If no subplans match the given parameters then we must handle - * this case in a special way. The problem here is that code in - * explain.c requires an Append to have at least one subplan in - * order for it to properly determine the Vars in that subplan's - * targetlist. We sidestep this issue by just initializing the - * first subplan and setting as_whichplan to NO_MATCHING_SUBPLANS - * to indicate that we don't need to scan any subnodes. + * The case where no subplans survive pruning must be handled + * specially. The problem here is that code in explain.c requires + * an Append to have at least one subplan in order for it to + * properly determine the Vars in that subplan's targetlist. We + * sidestep this issue by just initializing the first subplan and + * setting as_whichplan to NO_MATCHING_SUBPLANS to indicate that + * we don't really need to scan any subnodes. */ if (bms_is_empty(validsubplans)) { @@ -175,14 +173,13 @@ ExecInitAppend(Append *node, EState *estate, int eflags) } /* - * If there's no exec params then no further pruning can be done, we - * can just set the valid subplans to all remaining subplans. + * If no runtime pruning is required, we can fill as_valid_subplans + * immediately, preventing later calls to ExecFindMatchingSubPlans. */ - if (bms_is_empty(prunestate->execparams)) + if (!prunestate->do_exec_prune) appendstate->as_valid_subplans = bms_add_range(NULL, 0, nplans - 1); appendstate->as_prune_state = prunestate; - } else { @@ -190,7 +187,7 @@ ExecInitAppend(Append *node, EState *estate, int eflags) /* * When run-time partition pruning is not enabled we can just mark all - * subplans as valid, they must also all be initialized. + * subplans as valid; they must also all be initialized. */ appendstate->as_valid_subplans = validsubplans = bms_add_range(NULL, 0, nplans - 1); @@ -341,13 +338,13 @@ ExecReScanAppend(AppendState *node) int i; /* - * If any of the parameters being used for partition pruning have changed, - * then we'd better unset the valid subplans so that they are reselected - * for the new parameter values. + * If any PARAM_EXEC Params used in pruning expressions have changed, then + * we'd better unset the valid subplans so that they are reselected for + * the new parameter values. */ if (node->as_prune_state && bms_overlap(node->ps.chgParam, - node->as_prune_state->execparams)) + node->as_prune_state->execparamids)) { bms_free(node->as_valid_subplans); node->as_valid_subplans = NULL; @@ -531,9 +528,9 @@ choose_next_subplan_for_leader(AppendState *node) node->as_whichplan = node->as_nplans - 1; /* - * If we've yet to determine the valid subplans for these parameters - * then do so now. If run-time pruning is disabled then the valid - * subplans will always be set to all subplans. + * If we've yet to determine the valid subplans then do so now. If + * run-time pruning is disabled then the valid subplans will always be + * set to all subplans. */ if (node->as_valid_subplans == NULL) { @@ -606,9 +603,9 @@ choose_next_subplan_for_worker(AppendState *node) node->as_pstate->pa_finished[node->as_whichplan] = true; /* - * If we've yet to determine the valid subplans for these parameters then - * do so now. If run-time pruning is disabled then the valid subplans - * will always be set to all subplans. + * If we've yet to determine the valid subplans then do so now. If + * run-time pruning is disabled then the valid subplans will always be set + * to all subplans. */ else if (node->as_valid_subplans == NULL) { |