diff --git a/src/common/backend/parser/analyze.cpp b/src/common/backend/parser/analyze.cpp index f1446d05a..0549c770c 100644 --- a/src/common/backend/parser/analyze.cpp +++ b/src/common/backend/parser/analyze.cpp @@ -899,6 +899,10 @@ static void transformLimitSortClause(ParseState* pstate, void* stmt, Query* qry, rlist = forDel ? transformSortClause(pstate, ((DeleteStmt*)stmt)->sortClause, &qry->targetList, true, false) : transformUpdateSortClause(pstate, (UpdateStmt*)stmt, qry); + /* + * For update statement, the effective range of sort clause is not optimized. For delete statement, + * sorting is performed only when limit or returning clause takes effect. + */ if (qry->limitCount != NULL) { /* flag for discriminating rownum */ Const *flag = makeNode(Const); @@ -907,8 +911,10 @@ static void transformLimitSortClause(ParseState* pstate, void* stmt, Query* qry, flag->consttype = INT8OID; flag->consttypmod = -1; qry->limitOffset = (Node*)flag; + qry->sortClause = rlist; + } else if (!forDel || qry->returningList != NULL) { + qry->sortClause = rlist; } - qry->sortClause = rlist; } static void CheckUDRelations(ParseState* pstate, List* sortClause, Node* limitClause, List* returningList, @@ -3662,18 +3668,15 @@ static void MergeTargetList(List** targetLists, RangeTblEntry* rte1, int rtindex RangeTblEntry* rte2, int rtindex2) { ListCell* l = NULL; - ListCell* l_pre = NULL; foreach (l, targetLists[rtindex2 - 1]) { TargetEntry* tle = (TargetEntry*)lfirst(l); tle->rtindex = (Index)rtindex1; rte1->updatedCols = bms_add_member(rte1->updatedCols, tle->resno - FirstLowInvalidHeapAttributeNumber); rte2->updatedCols = bms_del_member(rte2->updatedCols, tle->resno - FirstLowInvalidHeapAttributeNumber); - targetLists[rtindex1 - 1] = lappend(targetLists[rtindex1 - 1], tle); - targetLists[rtindex2 - 1] = list_delete_cell(targetLists[rtindex2 - 1], l, l_pre); - - l_pre = l; } + targetLists[rtindex1 - 1] = list_concat(targetLists[rtindex1 - 1], targetLists[rtindex2 - 1]); + targetLists[rtindex2 - 1] = NULL; } static void transformMultiTargetList(List* target_rangetblentry, List** targetLists) @@ -4135,6 +4138,7 @@ static List* transformUpdateTargetList(ParseState* pstate, List* qryTlist, List* tlist = list_concat(tlist, new_tle[i]); } } + pfree(new_tle); return tlist; } diff --git a/src/test/regress/expected/multi_update.out b/src/test/regress/expected/multi_update.out index 07f7f39e6..6d99bfac5 100644 --- a/src/test/regress/expected/multi_update.out +++ b/src/test/regress/expected/multi_update.out @@ -1241,6 +1241,12 @@ select * from t_t_mutil_t1; 2 | 1 (2 rows) +rollback; +begin; +update t_t_mutil_t1 t1, t_t_mutil_t1 t2, t_t_mutil_t1 t3 set t2.col2 = 3, t3.col1 = 2; +rollback; +begin; +update t_t_mutil_t2 t1, t_t_mutil_t2 t2, t_t_mutil_t2 t3 set t1.col1 = 3, t3.col2 = 2, t2.col3 = 3; rollback; CREATE SYNONYM s_t_mutil_t1 FOR t_t_mutil_t1; CREATE SYNONYM s_t_mutil_t2 FOR t_t_mutil_t1; diff --git a/src/test/regress/sql/multi_update.sql b/src/test/regress/sql/multi_update.sql index 39f9b18f7..f580ba4f8 100644 --- a/src/test/regress/sql/multi_update.sql +++ b/src/test/regress/sql/multi_update.sql @@ -559,6 +559,13 @@ begin; update t_t_mutil_t1 t1,t_t_mutil_t2 t2 set t2.col2 = 3, t1.col1 = 2; select * from t_t_mutil_t1; rollback; +begin; +update t_t_mutil_t1 t1, t_t_mutil_t1 t2, t_t_mutil_t1 t3 set t2.col2 = 3, t3.col1 = 2; +rollback; +begin; +update t_t_mutil_t2 t1, t_t_mutil_t2 t2, t_t_mutil_t2 t3 set t1.col1 = 3, t3.col2 = 2, t2.col3 = 3; +rollback; + CREATE SYNONYM s_t_mutil_t1 FOR t_t_mutil_t1; CREATE SYNONYM s_t_mutil_t2 FOR t_t_mutil_t1; begin;