diff --git a/src/gausskernel/runtime/opfusion/opfusion_insert.cpp b/src/gausskernel/runtime/opfusion/opfusion_insert.cpp index b7f46337b..abb385533 100644 --- a/src/gausskernel/runtime/opfusion/opfusion_insert.cpp +++ b/src/gausskernel/runtime/opfusion/opfusion_insert.cpp @@ -246,6 +246,23 @@ Datum ComputePartKeyExprTuple(Relation rel, EState *estate, TupleTableSlot *slot return val; } +static void ExecReleaseResource(Tuple tuple, TupleTableSlot *slot, ResultRelInfo *result_rel_info, EState *estate, + Relation bucket_rel, Relation rel, Partition part, Relation partRel) +{ + tableam_tops_free_tuple(tuple); + (void)ExecClearTuple(slot); + ExecCloseIndices(result_rel_info); + ExecDoneStepInFusion(estate); + if (bucket_rel != NULL) { + bucketCloseRelation(bucket_rel); + } + if (RELATION_IS_PARTITIONED(rel) && part != NULL) { + partitionClose(rel, part, RowExclusiveLock); + releaseDummyRelation(&partRel); + } +} + + unsigned long InsertFusion::ExecInsert(Relation rel, ResultRelInfo* result_rel_info) { /******************* @@ -270,6 +287,8 @@ unsigned long InsertFusion::ExecInsert(Relation rel, ResultRelInfo* result_rel_i m_c_local.m_estate->esfRelations = NULL; partOid = heapTupleGetPartitionId(rel, tuple, false, m_c_local.m_estate->es_plannedstmt->hasIgnore); if (m_c_local.m_estate->es_plannedstmt->hasIgnore && partOid == InvalidOid) { + ExecReleaseResource(tuple, m_local.m_reslot, result_rel_info, m_c_local.m_estate, bucket_rel, rel, part, + partRel); return 0; } part = partitionOpen(rel, partOid, RowExclusiveLock); @@ -301,6 +320,8 @@ unsigned long InsertFusion::ExecInsert(Relation rel, ResultRelInfo* result_rel_i */ if(!ExecConstraints(result_rel_info, m_local.m_reslot, m_c_local.m_estate, true)) { if (u_sess->utils_cxt.sql_ignore_strategy_val != SQL_OVERWRITE_NULL) { + ExecReleaseResource(tuple, m_local.m_reslot, result_rel_info, m_c_local.m_estate, bucket_rel, rel, part, + partRel); return 0; } tuple = ReplaceTupleNullCol(RelationGetDescr(result_rel_info->ri_RelationDesc), m_local.m_reslot); @@ -336,20 +357,8 @@ unsigned long InsertFusion::ExecInsert(Relation rel, ResultRelInfo* result_rel_i &conflictInfo, &conflictPartOid, &conflictBucketid)) { ereport(WARNING, (errmsg("duplicate key value violates unique constraint in table \"%s\"", RelationGetRelationName(target_rel)))); - - /* clear before ended */ - tableam_tops_free_tuple(tuple); - (void)ExecClearTuple(m_local.m_reslot); - ExecCloseIndices(result_rel_info); - ExecDoneStepInFusion(m_c_local.m_estate); - if (bucket_rel != NULL) { - bucketCloseRelation(bucket_rel); - } - if (RELATION_IS_PARTITIONED(rel)) { - partitionClose(rel, part, RowExclusiveLock); - releaseDummyRelation(&partRel); - } - + ExecReleaseResource(tuple, m_local.m_reslot, result_rel_info, m_c_local.m_estate, bucket_rel, rel, part, + partRel); return 0; } @@ -386,25 +395,10 @@ unsigned long InsertFusion::ExecInsert(Relation rel, ResultRelInfo* result_rel_i if (result_rel_info->ri_WithCheckOptions != NIL) ExecWithCheckOptions(result_rel_info, m_local.m_reslot, m_c_local.m_estate); - tableam_tops_free_tuple(tuple); - - (void)ExecClearTuple(m_local.m_reslot); - /**************** * step 3: done * ****************/ - ExecCloseIndices(result_rel_info); - - - ExecDoneStepInFusion(m_c_local.m_estate); - - if (bucket_rel != NULL) { - bucketCloseRelation(bucket_rel); - } - if (RELATION_IS_PARTITIONED(rel)) { - partitionClose(rel, part, RowExclusiveLock); - releaseDummyRelation(&partRel); - } + ExecReleaseResource(tuple, m_local.m_reslot, result_rel_info, m_c_local.m_estate, bucket_rel, rel, part, partRel); return 1; } diff --git a/src/gausskernel/runtime/opfusion/opfusion_update.cpp b/src/gausskernel/runtime/opfusion/opfusion_update.cpp index b13f32a89..7834ba592 100644 --- a/src/gausskernel/runtime/opfusion/opfusion_update.cpp +++ b/src/gausskernel/runtime/opfusion/opfusion_update.cpp @@ -356,7 +356,7 @@ lreplace: if (rel->rd_att->constr) { if (!ExecConstraints(result_rel_info, m_local.m_reslot, m_c_local.m_estate)) { if (u_sess->utils_cxt.sql_ignore_strategy_val != SQL_OVERWRITE_NULL) { - return 0; + break; } tup = ReplaceTupleNullCol(RelationGetDescr(result_rel_info->ri_RelationDesc), m_local.m_reslot); /* Double check constraints in case that new val in column with not null constraints diff --git a/src/test/regress/expected/ignore/ignore_unique_constraints.out b/src/test/regress/expected/ignore/ignore_unique_constraints.out index 69482dd38..c16336a91 100644 --- a/src/test/regress/expected/ignore/ignore_unique_constraints.out +++ b/src/test/regress/expected/ignore/ignore_unique_constraints.out @@ -365,6 +365,24 @@ select * from t_ignore; 2 (2 rows) +-- test for insert table with primary key +drop table if exists t_pri_key_insert; +NOTICE: table "t_pri_key_insert" does not exist, skipping +create table t_pri_key_insert(id int primary key); +NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "t_pri_key_insert_pkey" for table "t_pri_key_insert" +insert /*+ ignore_error */ into t_pri_key_insert values(null); +WARNING: null value in column "id" violates not-null constraint +DETAIL: Failing row contains (null). +insert /*+ ignore_error */ into t_pri_key_insert values(1); +insert /*+ ignore_error */ into t_pri_key_insert values(1); +WARNING: duplicate key value violates unique constraint in table "t_pri_key_insert" +select * from t_pri_key_insert; + id +---- + 1 +(1 row) + +drop table t_pri_key_insert; -- 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 @@ -372,6 +390,9 @@ 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; +update /*+ ignore_error */ t_pri_key_update set c1 = null where c1 = 2; +WARNING: null value in column "c1" violates not-null constraint +DETAIL: Failing row contains (null, 999). select * from t_pri_key_update; c1 | c2 ----+----- diff --git a/src/test/regress/sql/ignore/ignore_unique_constraints.sql b/src/test/regress/sql/ignore/ignore_unique_constraints.sql index 87f457a0d..3cadd4340 100644 --- a/src/test/regress/sql/ignore/ignore_unique_constraints.sql +++ b/src/test/regress/sql/ignore/ignore_unique_constraints.sql @@ -177,11 +177,21 @@ insert into t_ignore values(2); update /*+ ignore_error */ t_ignore set num = 1 where num = 2; select * from t_ignore; +-- test for insert table with primary key +drop table if exists t_pri_key_insert; +create table t_pri_key_insert(id int primary key); +insert /*+ ignore_error */ into t_pri_key_insert values(null); +insert /*+ ignore_error */ into t_pri_key_insert values(1); +insert /*+ ignore_error */ into t_pri_key_insert values(1); +select * from t_pri_key_insert; +drop table t_pri_key_insert; + -- 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; +update /*+ ignore_error */ t_pri_key_update set c1 = null where c1 = 2; select * from t_pri_key_update; drop table t_pri_key_update;