aboutsummaryrefslogtreecommitdiff
path: root/src/backend/executor/nodeGather.c
diff options
context:
space:
mode:
authorRobert Haas <rhaas@postgresql.org>2017-11-25 10:49:17 -0500
committerRobert Haas <rhaas@postgresql.org>2017-11-25 10:49:17 -0500
commitb10967eddf964f8c0a11060cf3f366bbdd1235f6 (patch)
tree71c573073d45393095a2a2386999ae430b234b63 /src/backend/executor/nodeGather.c
parent0f2458ff5f970cade04313f1a10fe01d02f888b7 (diff)
downloadpostgresql-b10967eddf964f8c0a11060cf3f366bbdd1235f6.tar.gz
postgresql-b10967eddf964f8c0a11060cf3f366bbdd1235f6.zip
Avoid projecting tuples unnecessarily in Gather and Gather Merge.
It's most often the case that the target list for the Gather (Merge) node matches the target list supplied by the underlying plan node; when this is so, we can avoid the overhead of projecting. This depends on commit f455e1125e2588d4cd4fc663c6a10da4e003a3b5 for proper functioning. Idea by Andres Freund. Patch by me. Review by Amit Kapila. Discussion: http://postgr.es/m/CA+TgmoZ0ZL=cesZFq8c9NnfK6bqy-wwUd3_74iYGodYrSoQ7Fw@mail.gmail.com
Diffstat (limited to 'src/backend/executor/nodeGather.c')
-rw-r--r--src/backend/executor/nodeGather.c16
1 files changed, 10 insertions, 6 deletions
diff --git a/src/backend/executor/nodeGather.c b/src/backend/executor/nodeGather.c
index 30885e6f5c2..212612b5351 100644
--- a/src/backend/executor/nodeGather.c
+++ b/src/backend/executor/nodeGather.c
@@ -104,12 +104,6 @@ ExecInitGather(Gather *node, EState *estate, int eflags)
outerPlanState(gatherstate) = ExecInitNode(outerNode, estate, eflags);
/*
- * Initialize result tuple type and projection info.
- */
- ExecAssignResultTypeFromTL(&gatherstate->ps);
- ExecAssignProjectionInfo(&gatherstate->ps, NULL);
-
- /*
* Initialize funnel slot to same tuple descriptor as outer plan.
*/
if (!ExecContextForcesOids(outerPlanState(gatherstate), &hasoid))
@@ -117,6 +111,12 @@ ExecInitGather(Gather *node, EState *estate, int eflags)
tupDesc = ExecTypeFromTL(outerNode->targetlist, hasoid);
ExecSetSlotDescriptor(gatherstate->funnel_slot, tupDesc);
+ /*
+ * Initialize result tuple type and projection info.
+ */
+ ExecAssignResultTypeFromTL(&gatherstate->ps);
+ ExecConditionalAssignProjectionInfo(&gatherstate->ps, tupDesc, OUTER_VAR);
+
return gatherstate;
}
@@ -221,6 +221,10 @@ ExecGather(PlanState *pstate)
if (TupIsNull(slot))
return NULL;
+ /* If no projection is required, we're done. */
+ if (node->ps.ps_ProjInfo == NULL)
+ return slot;
+
/*
* Form the result tuple using ExecProject(), and return it.
*/