From ff2dc72833149d16e6df78bc145cc4f703d0d40a Mon Sep 17 00:00:00 2001 From: li-judong Date: Thu, 14 Dec 2023 10:48:52 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E5=90=8C=E5=90=8D=E5=A4=9A?= =?UTF-8?q?=E8=A1=A8=E6=9B=B4=E6=96=B0CORE=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/common/backend/parser/analyze.cpp | 31 +++++++++++----------- src/test/regress/expected/multi_update.out | 21 +++++++++++++++ src/test/regress/sql/multi_update.sql | 11 ++++++++ 3 files changed, 47 insertions(+), 16 deletions(-) diff --git a/src/common/backend/parser/analyze.cpp b/src/common/backend/parser/analyze.cpp index cb3296e42..3781823d2 100644 --- a/src/common/backend/parser/analyze.cpp +++ b/src/common/backend/parser/analyze.cpp @@ -3946,30 +3946,29 @@ static void MergeTargetList(List** targetLists, RangeTblEntry* rte1, int rtindex targetLists[rtindex2 - 1] = NULL; } -static void transformMultiTargetList(List* target_rangetblentry, List** targetLists) +static void transformMultiTargetList(List* target_rangetblentry, List** targetLists, List* result_relations) { - int rtindex1 = 1, rtindex2 = 1; - ListCell* l1; - ListCell* l2; - if (list_length(target_rangetblentry) <= 1) { return; } - foreach (l1, target_rangetblentry) { - RangeTblEntry* rte1 = (RangeTblEntry*)lfirst(l1); - rtindex2 = 0; - l2 = lnext(l1); - rtindex2 = rtindex1 + 1; - while (l2 != NULL) { - RangeTblEntry* rte2 = (RangeTblEntry*)lfirst(l2); + ListCell *l1 = NULL; + ListCell *l2 = NULL; + forboth (l1, target_rangetblentry, l2, result_relations) { + RangeTblEntry* rte1 = (RangeTblEntry*)lfirst(l1); + int rtindex1 = lfirst_int(l2); + ListCell *l3 = lnext(l1); + ListCell *l4 = lnext(l2); + + while (l3 && l4) { + RangeTblEntry* rte2 = (RangeTblEntry*)lfirst(l3); + int rtindex2 = lfirst_int(l4); if (rte2->relid == rte1->relid) { MergeTargetList(targetLists, rte1, rtindex1, rte2, rtindex2); } - rtindex2++; - l2 = lnext(l2); + l3 = lnext(l3); + l4 = lnext(l4); } - rtindex1++; } } @@ -4395,7 +4394,7 @@ static List* transformUpdateTargetList(ParseState* pstate, List* qryTlist, List* * If there are actually the same result relations by different alias * or synonym in multiple update, merge their targetLists. */ - transformMultiTargetList(pstate->p_target_rangetblentry, new_tle); + transformMultiTargetList(pstate->p_target_rangetblentry, new_tle, resultRelations); if (targetRelationNum == 1) { int i = linitial_int(resultRelations); diff --git a/src/test/regress/expected/multi_update.out b/src/test/regress/expected/multi_update.out index 8940c0e04..52c02736a 100644 --- a/src/test/regress/expected/multi_update.out +++ b/src/test/regress/expected/multi_update.out @@ -34,6 +34,27 @@ SUBPARTITION { ( subpartition_name ) | FOR ( subpartition_value [, ...] ) } NOTICE: UPDATE Multiple-Relation Syntax is only avaliable in CENTRALIZED mode and B-format database! NOTICE: 'partition_clause' is only avaliable in CENTRALIZED mode! +-- issue +CREATE TEMPORARY TABLE t0 ( c54 INT , c9 INT ) ; +INSERT INTO t0 VALUES ( 25 , -8 ) , ( -88 , -77 ) ; +UPDATE t0 , ( SELECT t2 . c54 AS c17 FROM t0 , t0 AS t1 LEFT OUTER JOIN t0 AS t2 USING ( c9 , c54 ) ) AS t3 JOIN t0 AS t4 ON t4 . c9 = t4 . c54 NATURAL INNER JOIN t0 AS t5 SET t4 . c54 = -32 WHERE t4 . c54 = ( SELECT c54 AS c4 FROM t0 LIMIT 1 ) ; +WITH t6 AS ( SELECT c54 AS c12 FROM t0 ) SELECT t0 . c9 AS c9 FROM t0 CROSS JOIN t0 AS t7 WHERE t0 . c54 = -33 ; + c9 +---- +(0 rows) + +drop table t0; +create table t0(c1 int, c2 int, c3 int, c4 int); +insert into t0 values(25, -8, -88, -8),(-88, -77, 25, -8); +update t0 a, t0 b set b.c1=10, a.c2=200, b.c3=20, a.c4=100; +select * from t0; + c1 | c2 | c3 | c4 +----+-----+----+----- + 10 | 200 | 20 | 100 + 10 | 200 | 20 | 100 +(2 rows) + +drop table t0; -- three relation drop table if exists t_t_mutil_t1; NOTICE: table "t_t_mutil_t1" does not exist, skipping diff --git a/src/test/regress/sql/multi_update.sql b/src/test/regress/sql/multi_update.sql index d464bd63d..e0ad8720f 100644 --- a/src/test/regress/sql/multi_update.sql +++ b/src/test/regress/sql/multi_update.sql @@ -1,6 +1,17 @@ create database multiupdate DBCOMPATIBILITY = 'B'; \c multiupdate; \h update +-- issue +CREATE TEMPORARY TABLE t0 ( c54 INT , c9 INT ) ; +INSERT INTO t0 VALUES ( 25 , -8 ) , ( -88 , -77 ) ; +UPDATE t0 , ( SELECT t2 . c54 AS c17 FROM t0 , t0 AS t1 LEFT OUTER JOIN t0 AS t2 USING ( c9 , c54 ) ) AS t3 JOIN t0 AS t4 ON t4 . c9 = t4 . c54 NATURAL INNER JOIN t0 AS t5 SET t4 . c54 = -32 WHERE t4 . c54 = ( SELECT c54 AS c4 FROM t0 LIMIT 1 ) ; +WITH t6 AS ( SELECT c54 AS c12 FROM t0 ) SELECT t0 . c9 AS c9 FROM t0 CROSS JOIN t0 AS t7 WHERE t0 . c54 = -33 ; +drop table t0; +create table t0(c1 int, c2 int, c3 int, c4 int); +insert into t0 values(25, -8, -88, -8),(-88, -77, 25, -8); +update t0 a, t0 b set b.c1=10, a.c2=200, b.c3=20, a.c4=100; +select * from t0; +drop table t0; -- three relation drop table if exists t_t_mutil_t1; drop table if exists t_t_mutil_t2;