summaryrefslogtreecommitdiff
path: root/src/backend/optimizer/plan/planner.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/optimizer/plan/planner.c')
-rw-r--r--src/backend/optimizer/plan/planner.c17
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))
{