diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2019-12-11 17:05:30 -0500 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2019-12-11 17:05:30 -0500 |
commit | 5935917ce59e2e613ac7a4b54ed49a7b9f8f28ac (patch) | |
tree | b89e6f02a9c226b1e6e94ddf8b3de73afd64a761 /src/backend/executor/nodeAppend.c | |
parent | 6ef77cf46e81f45716ec981cb08781d426181378 (diff) | |
download | postgresql-5935917ce59e2e613ac7a4b54ed49a7b9f8f28ac.tar.gz postgresql-5935917ce59e2e613ac7a4b54ed49a7b9f8f28ac.zip |
Allow executor startup pruning to prune all child nodes.
Previously, if the startup pruning logic proved that all child nodes
of an Append or MergeAppend could be pruned, we still kept one, just
to keep EXPLAIN from failing. The previous commit removed the
ruleutils.c limitation that required this kluge, so drop it. That
results in less-confusing EXPLAIN output, as per a complaint from
Yuzuko Hosoya.
David Rowley
Discussion: https://postgr.es/m/001001d4f44b$2a2cca50$7e865ef0$@lab.ntt.co.jp
Diffstat (limited to 'src/backend/executor/nodeAppend.c')
-rw-r--r-- | src/backend/executor/nodeAppend.c | 42 |
1 files changed, 11 insertions, 31 deletions
diff --git a/src/backend/executor/nodeAppend.c b/src/backend/executor/nodeAppend.c index 5ff986ac7d3..8b12a24cd5e 100644 --- a/src/backend/executor/nodeAppend.c +++ b/src/backend/executor/nodeAppend.c @@ -78,7 +78,6 @@ struct ParallelAppendState }; #define INVALID_SUBPLAN_INDEX -1 -#define NO_MATCHING_SUBPLANS -2 static TupleTableSlot *ExecAppend(PlanState *pstate); static bool choose_next_subplan_locally(AppendState *node); @@ -141,23 +140,6 @@ ExecInitAppend(Append *node, EState *estate, int eflags) validsubplans = ExecFindInitialMatchingSubPlans(prunestate, list_length(node->appendplans)); - /* - * 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)) - { - appendstate->as_whichplan = NO_MATCHING_SUBPLANS; - - /* Mark the first as valid so that it's initialized below */ - validsubplans = bms_make_singleton(0); - } - nplans = bms_num_members(validsubplans); } else @@ -169,14 +151,12 @@ ExecInitAppend(Append *node, EState *estate, int eflags) } /* - * If no runtime pruning is required, we can fill as_valid_subplans - * immediately, preventing later calls to ExecFindMatchingSubPlans. + * When no run-time pruning is required and there's at least one + * subplan, we can fill as_valid_subplans immediately, preventing + * later calls to ExecFindMatchingSubPlans. */ - if (!prunestate->do_exec_prune) - { - Assert(nplans > 0); + if (!prunestate->do_exec_prune && nplans > 0) appendstate->as_valid_subplans = bms_add_range(NULL, 0, nplans - 1); - } } else { @@ -255,6 +235,10 @@ ExecAppend(PlanState *pstate) if (node->as_whichplan < 0) { + /* Nothing to do if there are no subplans */ + if (node->as_nplans == 0) + return ExecClearTuple(node->ps.ps_ResultTupleSlot); + /* * If no subplan has been chosen, we must choose one before * proceeding. @@ -262,10 +246,6 @@ ExecAppend(PlanState *pstate) if (node->as_whichplan == INVALID_SUBPLAN_INDEX && !node->choose_next_subplan(node)) return ExecClearTuple(node->ps.ps_ResultTupleSlot); - - /* Nothing to do if there are no matching subplans */ - else if (node->as_whichplan == NO_MATCHING_SUBPLANS) - return ExecClearTuple(node->ps.ps_ResultTupleSlot); } for (;;) @@ -460,7 +440,7 @@ choose_next_subplan_locally(AppendState *node) int nextplan; /* We should never be called when there are no subplans */ - Assert(whichplan != NO_MATCHING_SUBPLANS); + Assert(node->as_nplans > 0); /* * If first call then have the bms member function choose the first valid @@ -511,7 +491,7 @@ choose_next_subplan_for_leader(AppendState *node) Assert(ScanDirectionIsForward(node->ps.state->es_direction)); /* We should never be called when there are no subplans */ - Assert(node->as_whichplan != NO_MATCHING_SUBPLANS); + Assert(node->as_nplans > 0); LWLockAcquire(&pstate->pa_lock, LW_EXCLUSIVE); @@ -592,7 +572,7 @@ choose_next_subplan_for_worker(AppendState *node) Assert(ScanDirectionIsForward(node->ps.state->es_direction)); /* We should never be called when there are no subplans */ - Assert(node->as_whichplan != NO_MATCHING_SUBPLANS); + Assert(node->as_nplans > 0); LWLockAcquire(&pstate->pa_lock, LW_EXCLUSIVE); |