From 9dd646b49ce2385fdf950f459879ded116ef4bb0 Mon Sep 17 00:00:00 2001
From: Andres Freund <andres@anarazel.de>
Date: Wed, 16 Aug 2017 01:03:51 -0700
Subject: [PATCH 01/16] Rely on executor utils to build targetlist for DML
 RETURNING.

---
 src/backend/executor/nodeModifyTable.c | 10 ++++------
 1 file changed, 4 insertions(+), 6 deletions(-)

diff --git a/src/backend/executor/nodeModifyTable.c b/src/backend/executor/nodeModifyTable.c
index e12721a9b6..57946e1591 100644
--- a/src/backend/executor/nodeModifyTable.c
+++ b/src/backend/executor/nodeModifyTable.c
@@ -1793,7 +1793,6 @@ ExecInitModifyTable(ModifyTable *node, EState *estate, int eflags)
 	int			nplans = list_length(node->plans);
 	ResultRelInfo *saved_resultRelInfo;
 	ResultRelInfo *resultRelInfo;
-	TupleDesc	tupDesc;
 	Plan	   *subplan;
 	ListCell   *l;
 	int			i;
@@ -2027,12 +2026,11 @@ ExecInitModifyTable(ModifyTable *node, EState *estate, int eflags)
 		 * Initialize result tuple slot and assign its rowtype using the first
 		 * RETURNING list.  We assume the rest will look the same.
 		 */
-		tupDesc = ExecTypeFromTL((List *) linitial(node->returningLists),
-								 false);
+		mtstate->ps.plan->targetlist = (List *) linitial(node->returningLists);
 
 		/* Set up a slot for the output of the RETURNING projection(s) */
 		ExecInitResultTupleSlot(estate, &mtstate->ps);
-		ExecAssignResultType(&mtstate->ps, tupDesc);
+		ExecAssignResultTypeFromTL(&mtstate->ps);
 		slot = mtstate->ps.ps_ResultTupleSlot;
 
 		/* Need an econtext too */
@@ -2084,9 +2082,9 @@ ExecInitModifyTable(ModifyTable *node, EState *estate, int eflags)
 		 * We still must construct a dummy result tuple type, because InitPlan
 		 * expects one (maybe should change that?).
 		 */
-		tupDesc = ExecTypeFromTL(NIL, false);
+		mtstate->ps.plan->targetlist = NIL;
 		ExecInitResultTupleSlot(estate, &mtstate->ps);
-		ExecAssignResultType(&mtstate->ps, tupDesc);
+		ExecAssignResultTypeFromTL(&mtstate->ps);
 
 		mtstate->ps.ps_ExprContext = NULL;
 	}
-- 
2.14.1.2.g4274c698f4.dirty

