From 491cbeebdb840ca1fdd9b8791456d7abc7ccdc36 Mon Sep 17 00:00:00 2001 From: teooooozhang Date: Thu, 1 Sep 2022 21:02:59 +0800 Subject: [PATCH] =?UTF-8?q?issue=E4=BF=AE=E5=A4=8D=EF=BC=9Aignore=5Fhint?= =?UTF-8?q?=E5=9C=A8update=E6=97=B6=E5=94=AF=E4=B8=80=E7=BA=A6=E6=9D=9F?= =?UTF-8?q?=E6=A3=80=E6=9F=A5=E9=94=99=E8=AF=AF=E9=97=AE=E9=A2=98=E5=A4=84?= =?UTF-8?q?=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../runtime/executor/nodeModifyTable.cpp | 33 ++++++++++----- .../runtime/opfusion/opfusion_update.cpp | 9 ++-- .../ignore/ignore_unique_constraints.out | 42 +++++++++++++++++++ .../sql/ignore/ignore_unique_constraints.sql | 21 ++++++++++ 4 files changed, 92 insertions(+), 13 deletions(-) diff --git a/src/gausskernel/runtime/executor/nodeModifyTable.cpp b/src/gausskernel/runtime/executor/nodeModifyTable.cpp index f7218ae85..3ea7730df 100644 --- a/src/gausskernel/runtime/executor/nodeModifyTable.cpp +++ b/src/gausskernel/runtime/executor/nodeModifyTable.cpp @@ -2141,10 +2141,13 @@ lreplace: estate->es_plannedstmt->hasIgnore && !ExecCheckIndexConstraints(slot, estate, result_relation_desc, partition, &isgpi, bucketid, &conflictInfo, &conflictPartOid, &conflictBucketid)) { - ereport(WARNING, - (errmsg("duplicate key value violates unique constraint in table \"%s\"", - RelationGetRelationName(result_relation_desc)))); - return NULL; + // check whether the conflicted info is the update tuple. If not, report warning and return. + if (!ItemPointerEquals(&conflictInfo.conflictTid, tupleid)) { + ereport(WARNING, + (errmsg("duplicate key value violates unique constraint in table \"%s\"", + RelationGetRelationName(result_relation_desc)))); + return NULL; + } } /* @@ -2434,9 +2437,14 @@ lreplace: if (can_ignore && !ExecCheckIndexConstraints(slot, estate, fake_relation, partition, &isgpi, bucketid, &conflictInfo, &conflictPartOid, &conflictBucketid)) { - ereport(WARNING, (errmsg("duplicate key value violates unique constraint in table \"%s\"", - RelationGetRelationName(result_relation_desc)))); - return NULL; + // check whether the conflicted info is the update tuple. If not, report warning and return. + bool is_same_pointer = ItemPointerEquals(&conflictInfo.conflictTid, tupleid); + if (!is_same_pointer || oldPartitionOid != conflictPartOid) { + ereport(WARNING, + (errmsg("duplicate key value violates unique constraint in table \"%s\"", + RelationGetRelationName(result_relation_desc)))); + return NULL; + } } if (result_relation_desc->rd_isblockchain) { @@ -2646,9 +2654,14 @@ lreplace: if (can_ignore && !ExecCheckIndexConstraints(slot, estate, fake_insert_relation, insert_partition, &isgpi, bucketid, &conflictInfo, &conflictPartOid, &conflictBucketid)) { - ereport(WARNING, (errmsg("duplicate key value violates unique constraint in table \"%s\"", - RelationGetRelationName(result_relation_desc)))); - return NULL; + // check whether the conflicted info is the update tuple. If not, report warning and return. + bool is_same_pointer = ItemPointerEquals(&conflictInfo.conflictTid, tupleid); + if (!is_same_pointer || oldPartitionOid != conflictPartOid) { + ereport(WARNING, + (errmsg("duplicate key value violates unique constraint in table \"%s\"", + RelationGetRelationName(result_relation_desc)))); + return NULL; + } } /* delete the old tuple */ diff --git a/src/gausskernel/runtime/opfusion/opfusion_update.cpp b/src/gausskernel/runtime/opfusion/opfusion_update.cpp index d01044340..400d04c1f 100644 --- a/src/gausskernel/runtime/opfusion/opfusion_update.cpp +++ b/src/gausskernel/runtime/opfusion/opfusion_update.cpp @@ -372,9 +372,12 @@ lreplace: if (m_c_local.m_estate->es_plannedstmt && m_c_local.m_estate->es_plannedstmt->hasIgnore && !ExecCheckIndexConstraints(m_local.m_reslot, m_c_local.m_estate, ledger_dest_rel, part, &isgpi, bucketid, &conflictInfo, &conflictPartOid, &conflictBucketid)) { - ereport(WARNING, (errmsg("duplicate key value violates unique constraint in table \"%s\"", - RelationGetRelationName(ledger_dest_rel)))); - break; + // check whether the conflicted info is the update tuple. If not, report warning and return. + if (!ItemPointerEquals(&((HeapTuple)tup)->t_self, &conflictInfo.conflictTid)) { + ereport(WARNING, (errmsg("duplicate key value violates unique constraint in table \"%s\"", + RelationGetRelationName(ledger_dest_rel)))); + break; + } } bool update_indexes = false; diff --git a/src/test/regress/expected/ignore/ignore_unique_constraints.out b/src/test/regress/expected/ignore/ignore_unique_constraints.out index 5c015ed88..69482dd38 100644 --- a/src/test/regress/expected/ignore/ignore_unique_constraints.out +++ b/src/test/regress/expected/ignore/ignore_unique_constraints.out @@ -365,6 +365,48 @@ select * from t_ignore; 2 (2 rows) +-- test for update table with primary key +drop table if exists t_pri_key_update; +NOTICE: table "t_pri_key_update" does not exist, skipping +create table t_pri_key_update(c1 int primary key, c2 int); +NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "t_pri_key_update_pkey" for table "t_pri_key_update" +insert into t_pri_key_update values(1, 101), (2, 201); +update /*+ ignore_error */ t_pri_key_update set c2 = 999 where c1 = 2; +select * from t_pri_key_update; + c1 | c2 +----+----- + 1 | 101 + 2 | 999 +(2 rows) + +drop table t_pri_key_update; +create table t_pri_key_update_partition (c1 int primary key, c2 int) + partition by list(c2) +( +partition p1 values (1), +partition p2 values (10), +partition p3 values (100), +partition p4 values (500) +); +NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "t_pri_key_update_partition_pkey" for table "t_pri_key_update_partition" +insert into t_pri_key_update_partition values (1, 1), (10, 10), (100, 100); +select * from t_pri_key_update_partition; + c1 | c2 +-----+----- + 100 | 100 + 10 | 10 + 1 | 1 +(3 rows) + +update /*+ ignore_error */ t_pri_key_update_partition set c2 = 500 where c1 = 10; +select * from t_pri_key_update_partition; + c1 | c2 +-----+----- + 10 | 500 + 100 | 100 + 1 | 1 +(3 rows) + -- test for column orientation table: not supported drop table if exists t_column_orien cascade; NOTICE: table "t_column_orien" does not exist, skipping diff --git a/src/test/regress/sql/ignore/ignore_unique_constraints.sql b/src/test/regress/sql/ignore/ignore_unique_constraints.sql index e11dc7b1c..87f457a0d 100644 --- a/src/test/regress/sql/ignore/ignore_unique_constraints.sql +++ b/src/test/regress/sql/ignore/ignore_unique_constraints.sql @@ -177,6 +177,27 @@ insert into t_ignore values(2); update /*+ ignore_error */ t_ignore set num = 1 where num = 2; select * from t_ignore; +-- test for update table with primary key +drop table if exists t_pri_key_update; +create table t_pri_key_update(c1 int primary key, c2 int); +insert into t_pri_key_update values(1, 101), (2, 201); +update /*+ ignore_error */ t_pri_key_update set c2 = 999 where c1 = 2; +select * from t_pri_key_update; +drop table t_pri_key_update; + +create table t_pri_key_update_partition (c1 int primary key, c2 int) + partition by list(c2) +( +partition p1 values (1), +partition p2 values (10), +partition p3 values (100), +partition p4 values (500) +); +insert into t_pri_key_update_partition values (1, 1), (10, 10), (100, 100); +select * from t_pri_key_update_partition; +update /*+ ignore_error */ t_pri_key_update_partition set c2 = 500 where c1 = 10; +select * from t_pri_key_update_partition; + -- test for column orientation table: not supported drop table if exists t_column_orien cascade; create table t_column_orien(c1 int primary key) with (orientation=column);