diff --git a/src/gausskernel/optimizer/plan/planner.cpp b/src/gausskernel/optimizer/plan/planner.cpp index a7834ba73..09362b621 100755 --- a/src/gausskernel/optimizer/plan/planner.cpp +++ b/src/gausskernel/optimizer/plan/planner.cpp @@ -4975,7 +4975,9 @@ static void preprocess_rowmarks(PlannerInfo* root) PlanRowMark* newrc = NULL; i++; - if (!bms_is_member(i, rels)) + if (rte->rtekind == RTE_JOIN || rte->rtekind == RTE_REMOTE_DUMMY) + continue; + if (!bms_is_member(i, rels) && list_length(parse->resultRelations) <= 1) continue; newrc = makeNode(PlanRowMark); diff --git a/src/gausskernel/optimizer/plan/setrefs.cpp b/src/gausskernel/optimizer/plan/setrefs.cpp index 9a693c11f..33a9da095 100644 --- a/src/gausskernel/optimizer/plan/setrefs.cpp +++ b/src/gausskernel/optimizer/plan/setrefs.cpp @@ -1059,7 +1059,11 @@ static void fix_assign_targetlists(ModifyTable* plan, Plan* subplan, List* resul int new_resno = 1; foreach (lctl, subplan->targetlist) { TargetEntry* tle = (TargetEntry*)lfirst(lctl); - if (rtindex == tle->rtindex || tle->rtindex == 0) { + if (tle->rtindex == 0) { + tle = (TargetEntry*)copyObject((void*)tle); + tle->resno = new_resno++; + temp[i] = lappend(temp[i], tle); + } else if (rtindex == tle->rtindex) { tle->resno = new_resno++; temp[i] = lappend(temp[i], tle); } diff --git a/src/gausskernel/runtime/executor/execMain.cpp b/src/gausskernel/runtime/executor/execMain.cpp index 6925df315..0650753f0 100755 --- a/src/gausskernel/runtime/executor/execMain.cpp +++ b/src/gausskernel/runtime/executor/execMain.cpp @@ -3274,6 +3274,9 @@ void EvalPlanQualFetchRowMarksUHeap(EPQState *epqstate) elog(ERROR, "EvalPlanQual doesn't support locking rowmarks"); } + if (epqstate->estate->es_result_relation_info->ri_RangeTableIndex == erm->rti) { + continue; + } /* clear any leftover test tuple for this rel */ slot = EvalPlanQualUSlot(epqstate, erm->relation, erm->rti); ExecClearTuple(slot); @@ -3428,6 +3431,9 @@ void EvalPlanQualFetchRowMarks(EPQState *epqstate) (errcode(ERRCODE_FEATURE_NOT_SUPPORTED), errmsg("EvalPlanQual doesn't support locking rowmarks"))); } + if (epqstate->estate->es_result_relation_info->ri_RangeTableIndex == erm->rti) { + continue; + } /* clear any leftover test tuple for this rel */ EvalPlanQualSetTuple(epqstate, erm->rti, NULL); @@ -3567,7 +3573,18 @@ void EvalPlanQualFetchRowMarks(EPQState *epqstate) TupleTableSlot *EvalPlanQualNext(EPQState *epqstate) { MemoryContext old_context = MemoryContextSwitchTo(epqstate->estate->es_query_cxt); - TupleTableSlot *slot = FetchPlanSlot(epqstate->planstate, epqstate->projInfos); + int resultRelation = epqstate->estate->result_rel_index; + ExprContext* origExprContext = NULL; + + TupleTableSlot *slot = ExecProcNode(epqstate->planstate); + /* for multiple modify, fetch the current read slot corresponding to the result relation. */ + if (resultRelation > 0) { + origExprContext = epqstate->projInfos[resultRelation]->pi_exprContext; + epqstate->projInfos[resultRelation]->pi_exprContext = epqstate->planstate->ps_ExprContext; + + slot = ExecProject(epqstate->projInfos[resultRelation], NULL); + epqstate->projInfos[resultRelation]->pi_exprContext = origExprContext; + } (void)MemoryContextSwitchTo(old_context); return slot; @@ -3610,6 +3627,8 @@ void EvalPlanQualBegin(EPQState *epqstate, EState *parentestate, bool isUHeap) * first ExecProcNode will take care of actually doing the rescan. */ planstate->chgParam = bms_add_member(planstate->chgParam, epqstate->epqParam); + estate->result_rel_index = parentestate->result_rel_index; + estate->es_result_relation_info = parentestate->es_result_relation_info; } } @@ -3739,6 +3758,7 @@ static void EvalPlanQualStart(EPQState *epqstate, EState *parentestate, Plan *pl * and leaves us ready to start processing tuples. */ epqstate->planstate = ExecInitNode(planTree, estate, 0); + estate->es_result_relation_info = parentestate->es_result_relation_info; (void)MemoryContextSwitchTo(old_context); } diff --git a/src/gausskernel/runtime/executor/nodeModifyTable.cpp b/src/gausskernel/runtime/executor/nodeModifyTable.cpp index dad26fd4d..8c4216711 100644 --- a/src/gausskernel/runtime/executor/nodeModifyTable.cpp +++ b/src/gausskernel/runtime/executor/nodeModifyTable.cpp @@ -3473,7 +3473,8 @@ TupleTableSlot* ExecModifyTable(ModifyTableState* node) } } - EvalPlanQualSetSlot(&node->mt_epqstate, plan_slot); + if (estate->result_rel_index == 0) + EvalPlanQualSetSlot(&node->mt_epqstate, plan_slot); slot = plan_slot; slot->tts_tupleDescriptor->tdTableAmType = result_rel_info->ri_RelationDesc->rd_tam_type; diff --git a/src/test/regress/expected/multi_delete.out b/src/test/regress/expected/multi_delete.out index 5539d0839..a9926ee7d 100644 --- a/src/test/regress/expected/multi_delete.out +++ b/src/test/regress/expected/multi_delete.out @@ -251,7 +251,7 @@ explain(verbose) delete/*+nestloop(a b)*/ from t_t_mutil_t1 a,t_t_mutil_t2 b whe -------------------------------------------------------------------------------------------- Delete on MULTI-RELATION (cost=0.00..69341.37 rows=23091 width=12) -> Nested Loop (cost=0.00..69341.37 rows=23091 width=12) - Output: a.ctid + Output: a.ctid, a.ctid, b.ctid Join Filter: (a.col2 = b.col2) -> Seq Scan on public.t_t_mutil_t1 a (cost=0.00..31.49 rows=2149 width=10) Output: a.ctid, a.col2 @@ -266,7 +266,7 @@ explain(verbose) delete/*+hashjoin(a b)*/ from t_t_mutil_t1 a,t_t_mutil_t2 b whe -------------------------------------------------------------------------------------------- Delete on MULTI-RELATION (cost=58.35..355.67 rows=23091 width=12) -> Hash Join (cost=58.35..355.67 rows=23091 distinct=[200, 200] width=12) - Output: a.ctid + Output: a.ctid, a.ctid, b.ctid Hash Cond: (a.col2 = b.col2) -> Seq Scan on public.t_t_mutil_t1 a (cost=0.00..31.49 rows=2149 width=10) Output: a.ctid, a.col2 @@ -281,7 +281,7 @@ explain(verbose) delete/*+mergejoin(a b)*/ from t_t_mutil_t1 a,t_t_mutil_t2 b wh -------------------------------------------------------------------------------------------- Delete on MULTI-RELATION (cost=300.86..657.97 rows=23091 width=12) -> Merge Join (cost=300.86..657.97 rows=23091 width=12) - Output: a.ctid + Output: a.ctid, a.ctid, b.ctid Merge Cond: (a.col2 = b.col2) -> Sort (cost=150.43..155.80 rows=2149 width=10) Output: a.ctid, a.col2 diff --git a/src/test/regress/expected/multi_update.out b/src/test/regress/expected/multi_update.out index 4efc77c74..cb416fbf3 100644 --- a/src/test/regress/expected/multi_update.out +++ b/src/test/regress/expected/multi_update.out @@ -289,7 +289,7 @@ explain(verbose) update/*+nestloop(a b)*/ t_t_mutil_t1 a,t_t_mutil_t2 b set b.co -------------------------------------------------------------------------------------------- Update on MULTI-RELATION (cost=0.00..69341.37 rows=23091 width=20) -> Nested Loop (cost=0.00..69341.37 rows=23091 width=20) - Output: a.col1, 4, a.ctid + Output: a.col1, 4, a.ctid, a.ctid, b.ctid Join Filter: (a.col1 = b.col1) -> Seq Scan on public.t_t_mutil_t1 a (cost=0.00..31.49 rows=2149 width=10) Output: a.col1, a.ctid @@ -304,7 +304,7 @@ explain(verbose) update/*+hashjoin(a b)*/ t_t_mutil_t1 a,t_t_mutil_t2 b set b.co -------------------------------------------------------------------------------------------- Update on MULTI-RELATION (cost=58.35..355.67 rows=23091 width=20) -> Hash Join (cost=58.35..355.67 rows=23091 distinct=[200, 200] width=20) - Output: a.col1, 4, a.ctid + Output: a.col1, 4, a.ctid, a.ctid, b.ctid Hash Cond: (a.col1 = b.col1) -> Seq Scan on public.t_t_mutil_t1 a (cost=0.00..31.49 rows=2149 width=10) Output: a.col1, a.ctid @@ -319,7 +319,7 @@ explain(verbose) update/*+mergejoin(a b)*/ t_t_mutil_t1 a,t_t_mutil_t2 b set b.c -------------------------------------------------------------------------------------------- Update on MULTI-RELATION (cost=300.86..657.97 rows=23091 width=20) -> Merge Join (cost=300.86..657.97 rows=23091 width=20) - Output: a.col1, 4, a.ctid + Output: a.col1, 4, a.ctid, a.ctid, b.ctid Merge Cond: (a.col1 = b.col1) -> Sort (cost=150.43..155.80 rows=2149 width=10) Output: a.col1, a.ctid @@ -1218,5 +1218,15 @@ insert into settest07 values(1,'开席'); create table settest01(id int,rowid number); insert into settest01 values(3,5); update settest01 a,settest07 b set b.c2=4 where a.id>b.c1; +drop table if exists t_t_mutil_t1; +drop table if exists t_t_mutil_t2; +drop table if exists t_t_mutil_t3; +create table t_t_mutil_t1(col1 int,col2 int); +create table t_t_mutil_t2(col1 int,col2 int,col3 int); +create table t_t_mutil_t3(col1 int,col2 int); +insert into t_t_mutil_t1 values(1,1),(1,1); +insert into t_t_mutil_t2 values(1,1),(1,2); +insert into t_t_mutil_t3 values(1,1),(1,3); +update t_t_mutil_t1 a,t_t_mutil_t2 b,t_t_mutil_t3 c set b.col2=5,a.col2=4 where a.col1=b.col1 and b.col1=c.col1; \c regression drop database multiupdate; diff --git a/src/test/regress/sql/multi_update.sql b/src/test/regress/sql/multi_update.sql index a7a0e39da..3c4f39672 100644 --- a/src/test/regress/sql/multi_update.sql +++ b/src/test/regress/sql/multi_update.sql @@ -542,5 +542,15 @@ create table settest01(id int,rowid number); insert into settest01 values(3,5); update settest01 a,settest07 b set b.c2=4 where a.id>b.c1; +drop table if exists t_t_mutil_t1; +drop table if exists t_t_mutil_t2; +drop table if exists t_t_mutil_t3; +create table t_t_mutil_t1(col1 int,col2 int); +create table t_t_mutil_t2(col1 int,col2 int,col3 int); +create table t_t_mutil_t3(col1 int,col2 int); +insert into t_t_mutil_t1 values(1,1),(1,1); +insert into t_t_mutil_t2 values(1,1),(1,2); +insert into t_t_mutil_t3 values(1,1),(1,3); +update t_t_mutil_t1 a,t_t_mutil_t2 b,t_t_mutil_t3 c set b.col2=5,a.col2=4 where a.col1=b.col1 and b.col1=c.col1; \c regression drop database multiupdate; \ No newline at end of file