diff options
Diffstat (limited to 'src/backend/optimizer/plan/planner.c')
-rw-r--r-- | src/backend/optimizer/plan/planner.c | 17 |
1 files changed, 11 insertions, 6 deletions
diff --git a/src/backend/optimizer/plan/planner.c b/src/backend/optimizer/plan/planner.c index 0847e787c39..670776b032b 100644 --- a/src/backend/optimizer/plan/planner.c +++ b/src/backend/optimizer/plan/planner.c @@ -1379,10 +1379,12 @@ grouping_planner(PlannerInfo *root, double tuple_fraction) { /* * If the top-level plan node is one that cannot do expression - * evaluation, we must insert a Result node to project the + * evaluation and its existing target list isn't already what + * we need, we must insert a Result node to project the * desired tlist. */ - if (!is_projection_capable_plan(result_plan)) + if (!is_projection_capable_plan(result_plan) && + !tlist_same_exprs(sub_tlist, result_plan->targetlist)) { result_plan = (Plan *) make_result(root, sub_tlist, @@ -1542,10 +1544,13 @@ grouping_planner(PlannerInfo *root, double tuple_fraction) * If the top-level plan node is one that cannot do expression * evaluation, we must insert a Result node to project the desired * tlist. (In some cases this might not really be required, but - * it's not worth trying to avoid it.) Note that on second and - * subsequent passes through the following loop, the top-level - * node will be a WindowAgg which we know can project; so we only - * need to check once. + * it's not worth trying to avoid it. In particular, think not to + * skip adding the Result if the initial window_tlist matches the + * top-level plan node's output, because we might change the tlist + * inside the following loop.) Note that on second and subsequent + * passes through the following loop, the top-level node will be a + * WindowAgg which we know can project; so we only need to check + * once. */ if (!is_projection_capable_plan(result_plan)) { |