diff --git a/src/backend/executor/nodeDML.c b/src/backend/executor/nodeDML.c index af912775e12d..84835b850c12 100644 --- a/src/backend/executor/nodeDML.c +++ b/src/backend/executor/nodeDML.c @@ -219,13 +219,20 @@ ExecInitDML(DML *node, EState *estate, int eflags) */ estate->es_result_relation_info = estate->es_result_relations; + /* + * Functions which are settings up the projection of child node + * use plan's targetlist to get types of modifying tuples. So + * set this field here and restore before end of initialization + */ + node->plan.targetlist = node->targetListProj; + CmdType operation = estate->es_plannedstmt->commandType; ResultRelInfo *resultRelInfo = estate->es_result_relation_info; ExecInitResultTupleSlot(estate, &dmlstate->ps); dmlstate->ps.targetlist = (List *) - ExecInitExpr((Expr *) node->plan.targetlist, + ExecInitExpr((Expr *) node->targetListProj, (PlanState *) dmlstate); Plan *outerPlan = outerPlan(node); @@ -261,6 +268,9 @@ ExecInitDML(DML *node, EState *estate, int eflags) TupleTableSlot *childResultSlot = outerPlanState(dmlstate)->ps_ResultTupleSlot; ExecAssignProjectionInfo(&dmlstate->ps, childResultSlot->tts_tupleDescriptor); + /* restore targetlist to emply list as DML node doesn't output */ + node->plan.targetlist = NULL; + /* * Initialize slot to insert/delete using output relation descriptor. */ @@ -271,7 +281,7 @@ ExecInitDML(DML *node, EState *estate, int eflags) * the junk filter doesn't need to do anything special there about them */ - dmlstate->junkfilter = ExecInitJunkFilter(node->plan.targetlist, + dmlstate->junkfilter = ExecInitJunkFilter(node->targetListProj, dmlstate->ps.state->es_result_relation_info->ri_RelationDesc->rd_att->tdhasoid, dmlstate->cleanedUpSlot); diff --git a/src/backend/gpopt/translate/CTranslatorDXLToPlStmt.cpp b/src/backend/gpopt/translate/CTranslatorDXLToPlStmt.cpp index 0bd321cc028e..98b3e2c975fa 100644 --- a/src/backend/gpopt/translate/CTranslatorDXLToPlStmt.cpp +++ b/src/backend/gpopt/translate/CTranslatorDXLToPlStmt.cpp @@ -4238,7 +4238,7 @@ CTranslatorDXLToPlStmt::TranslateDXLDml( GPOS_ASSERT(0 != dml->actionColIdx); - plan->targetlist = dml_target_list; + dml->targetListProj = dml_target_list; plan->lefttree = child_plan; plan->nMotionNodes = child_plan->nMotionNodes; diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c index d14dd2013d82..3e1db5a14bf1 100644 --- a/src/backend/nodes/copyfuncs.c +++ b/src/backend/nodes/copyfuncs.c @@ -1339,6 +1339,7 @@ _copyDML(const DML *from) COPY_SCALAR_FIELD(tupleoidColIdx); COPY_SCALAR_FIELD(tableoidColIdx); COPY_SCALAR_FIELD(canSetTag); + COPY_NODE_FIELD(targetListProj); return newnode; } diff --git a/src/backend/nodes/outfuncs.c b/src/backend/nodes/outfuncs.c index 3674f6bfdfb3..bdb52de16146 100644 --- a/src/backend/nodes/outfuncs.c +++ b/src/backend/nodes/outfuncs.c @@ -1219,6 +1219,7 @@ _outDML(StringInfo str, const DML *node) WRITE_INT_FIELD(tupleoidColIdx); WRITE_INT_FIELD(tableoidColIdx); WRITE_BOOL_FIELD(canSetTag); + WRITE_NODE_FIELD(targetListProj); _outPlanInfo(str, (Plan *) node); } diff --git a/src/backend/nodes/readfast.c b/src/backend/nodes/readfast.c index 8dcb032b8694..c89f2efb7e47 100644 --- a/src/backend/nodes/readfast.c +++ b/src/backend/nodes/readfast.c @@ -2240,6 +2240,7 @@ _readDML(void) READ_INT_FIELD(tupleoidColIdx); READ_INT_FIELD(tableoidColIdx); READ_BOOL_FIELD(canSetTag); + READ_NODE_FIELD(targetListProj); readPlanInfo((Plan *)local_node); diff --git a/src/include/nodes/plannodes.h b/src/include/nodes/plannodes.h index 21e8e8c88b1b..933720126a33 100644 --- a/src/include/nodes/plannodes.h +++ b/src/include/nodes/plannodes.h @@ -1330,6 +1330,7 @@ typedef struct DML AttrNumber tupleoidColIdx; /* index of tuple oid column into the target list */ AttrNumber tableoidColIdx; /* index of table oid column into the target list */ bool canSetTag; /* calculate processed tuples */ + List *targetListProj; /* projection of target list of child node */ } DML; /* diff --git a/src/test/regress/expected/partition_pruning_optimizer.out b/src/test/regress/expected/partition_pruning_optimizer.out index 55c8f29f2818..e9081c1187c6 100644 --- a/src/test/regress/expected/partition_pruning_optimizer.out +++ b/src/test/regress/expected/partition_pruning_optimizer.out @@ -3492,7 +3492,6 @@ explain (verbose, costs off) delete from test_1_prt_extra where j = 2; QUERY PLAN --------------------------------------------------------------------------------------------------------------------- Delete - Output: "outer".ColRef_0009, test_1_prt_extra.ctid -> Result Output: test_1_prt_extra.ctid, test_1_prt_extra.gp_segment_id, 0 -> Seq Scan on partition_pruning.test_1_prt_extra @@ -3500,7 +3499,7 @@ explain (verbose, costs off) delete from test_1_prt_extra where j = 2; Filter: (test_1_prt_extra.j = 2) Optimizer: Pivotal Optimizer (GPORCA) Settings: enable_bitmapscan=on, enable_hashjoin=off, enable_indexscan=on, enable_mergejoin=on, enable_seqscan=off -(9 rows) +(8 rows) delete from test_1_prt_extra where j = 2; -- Check that deletion performed correctly @@ -3558,7 +3557,6 @@ HINT: For non-partitioned tables, run analyze (). For QUERY PLAN ------------------------------------------------------------------------------------------------------------------- Delete - Output: "outer".ColRef_0025, test.ctid, test.tableoid -> Result Output: test.ctid, test.tableoid, test.gp_segment_id, 0 -> Hash Anti Join @@ -3578,7 +3576,7 @@ HINT: For non-partitioned tables, run analyze (). For Output: test_in_predicate.i, test_in_predicate.j Optimizer: Pivotal Optimizer (GPORCA) Settings: enable_bitmapscan=on, enable_hashjoin=off, enable_indexscan=on, enable_mergejoin=on, enable_seqscan=off -(21 rows) +(20 rows) delete from test where not exists( select 1 from test_in_predicate where test.i = test_in_predicate.i and test.j = test_in_predicate.j @@ -3635,7 +3633,6 @@ explain (verbose, costs off) update test_1_prt_extra set k = 10 where j = 2; QUERY PLAN ----------------------------------------------------------------------------------------------------------------------------------------------- Update - Output: test_1_prt_extra.i, test_1_prt_extra.j, test_1_prt_extra.k, (DMLAction), test_1_prt_extra.ctid -> Split Output: test_1_prt_extra.i, test_1_prt_extra.j, test_1_prt_extra.k, test_1_prt_extra.ctid, test_1_prt_extra.gp_segment_id, DMLAction -> Result @@ -3645,7 +3642,7 @@ explain (verbose, costs off) update test_1_prt_extra set k = 10 where j = 2; Filter: (test_1_prt_extra.j = 2) Optimizer: Pivotal Optimizer (GPORCA) Settings: enable_bitmapscan=on, enable_hashjoin=off, enable_indexscan=on, enable_mergejoin=on, enable_seqscan=off -(11 rows) +(10 rows) update test_1_prt_extra set k = 10 where j = 2; -- Check that update performed correctly and tuple moved to correct partition @@ -3704,7 +3701,6 @@ HINT: For non-partitioned tables, run analyze (). For QUERY PLAN ------------------------------------------------------------------------------------------------------------------- Update - Output: test.i, test.j, test.k, (DMLAction), test.ctid, test.tableoid -> Split Output: test.i, test.j, test.k, test.ctid, test.tableoid, test.gp_segment_id, DMLAction -> Result @@ -3726,7 +3722,7 @@ HINT: For non-partitioned tables, run analyze (). For Output: test_in_predicate.i, test_in_predicate.j Optimizer: Pivotal Optimizer (GPORCA) Settings: enable_bitmapscan=on, enable_hashjoin=off, enable_indexscan=on, enable_mergejoin=on, enable_seqscan=off -(23 rows) +(22 rows) update test set k = 10 where not exists( select 1 from test_in_predicate where test.i = test_in_predicate.i and test.j = test_in_predicate.j diff --git a/src/test/regress/expected/qp_dropped_cols_optimizer.out b/src/test/regress/expected/qp_dropped_cols_optimizer.out index 198ca1294e8b..f75a8d7780d0 100644 --- a/src/test/regress/expected/qp_dropped_cols_optimizer.out +++ b/src/test/regress/expected/qp_dropped_cols_optimizer.out @@ -16572,7 +16572,6 @@ EXPLAIN (COSTS OFF, VERBOSE) UPDATE t_part SET c1 = 3; QUERY PLAN ---------------------------------------------------------------------------------------------------------------------------------------- Update - Output: t_part.c1, t_part.c2, t_part.c3, t_part.c4, (DMLAction), t_part.ctid, t_part.tableoid -> Redistribute Motion 3:3 (slice1; segments: 3) Output: t_part.c1, t_part.c2, t_part.c3, t_part.c4, t_part.ctid, t_part.tableoid, t_part.gp_segment_id, (DMLAction) Hash Key: t_part.c1 @@ -16587,7 +16586,7 @@ EXPLAIN (COSTS OFF, VERBOSE) UPDATE t_part SET c1 = 3; -> Dynamic Seq Scan on public.t_part (dynamic scan id: 1) Output: t_part.c1, t_part.c2, t_part.c3, t_part.c4, t_part.ctid, t_part.tableoid, t_part.gp_segment_id Optimizer: Pivotal Optimizer (GPORCA) -(16 rows) +(15 rows) UPDATE t_part SET c1 = 3; SELECT * FROM t_part_1_prt_p2;