From dde36ab9cc8c3cce4538e27ebac9f6e547606327 Mon Sep 17 00:00:00 2001 From: chenxiaobin19 <1025221611@qq.com> Date: Sat, 25 Mar 2023 15:20:34 +0800 Subject: [PATCH] =?UTF-8?q?fixed=20de3bfd2=20from=20https://gitee.com/chen?= =?UTF-8?q?xiaobin19/openGauss-server/pulls/3264=20=E4=BF=AE=E5=A4=8Dopfus?= =?UTF-8?q?ion=E6=9B=B4=E6=96=B0=E5=B8=A6checkoption=E8=A7=86=E5=9B=BE?= =?UTF-8?q?=E6=97=B6=E5=AF=B9=E8=B1=A1=E6=9C=AA=E5=85=B3=E9=97=AD=E5=92=8C?= =?UTF-8?q?=E6=A0=A1=E9=AA=8C=E5=A4=B1=E6=95=88=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../runtime/opfusion/opfusion_insert.cpp | 6 +++- .../runtime/opfusion/opfusion_update.cpp | 15 +++++--- src/test/regress/expected/updatable_views.out | 35 +++++++++++++++++++ src/test/regress/sql/updatable_views.sql | 18 ++++++++++ 4 files changed, 69 insertions(+), 5 deletions(-) diff --git a/src/gausskernel/runtime/opfusion/opfusion_insert.cpp b/src/gausskernel/runtime/opfusion/opfusion_insert.cpp index fc0dc4d69e..4f8fa3f0cb 100644 --- a/src/gausskernel/runtime/opfusion/opfusion_insert.cpp +++ b/src/gausskernel/runtime/opfusion/opfusion_insert.cpp @@ -406,9 +406,10 @@ bool InsertFusion::execute(long max_rows, char* completionTag) refreshParameterIfNecessary(); ModifyTable* node = (ModifyTable*)(m_global->m_planstmt->planTree); + PlanState* ps = NULL; if (node->withCheckOptionLists != NIL) { Plan* plan = (Plan*)linitial(node->plans); - PlanState* ps = ExecInitNode(plan, m_c_local.m_estate, 0); + ps = ExecInitNode(plan, m_c_local.m_estate, 0); List* wcoList = (List*)linitial(node->withCheckOptionLists); List* wcoExprs = NIL; ListCell* ll = NULL; @@ -433,6 +434,9 @@ bool InsertFusion::execute(long max_rows, char* completionTag) /**************** * step 3: done * ****************/ + if (ps != NULL) { + ExecEndNode(ps); + } success = true; m_local.m_isCompleted = true; if (m_local.m_ledger_hash_exist && !IsConnFromApp()) { diff --git a/src/gausskernel/runtime/opfusion/opfusion_update.cpp b/src/gausskernel/runtime/opfusion/opfusion_update.cpp index a04c7ee698..8404b1dd40 100644 --- a/src/gausskernel/runtime/opfusion/opfusion_update.cpp +++ b/src/gausskernel/runtime/opfusion/opfusion_update.cpp @@ -554,13 +554,16 @@ lreplace: m_local.m_ledger_hash_exist = true; m_local.m_ledger_relhash += res_hash; } + + /* Check any WITH CHECK OPTION constraints */ + if (result_rel_info->ri_WithCheckOptions != NIL) { + ExecWithCheckOptions(result_rel_info, m_local.m_reslot, m_c_local.m_estate); + } + bms_free(modifiedIdxAttrs); list_free_ext(recheck_indexes); } - if (result_rel_info->ri_WithCheckOptions != NIL) - ExecWithCheckOptions(result_rel_info, m_local.m_reslot, m_c_local.m_estate); - tableam_tops_free_tuple(tup); (void)ExecClearTuple(m_local.m_reslot); @@ -607,9 +610,10 @@ bool UpdateFusion::execute(long max_rows, char *completionTag) } ModifyTable* node = (ModifyTable*)(m_global->m_planstmt->planTree); + PlanState* ps = NULL; if (node->withCheckOptionLists != NIL) { Plan* plan = (Plan*)linitial(node->plans); - PlanState* ps = ExecInitNode(plan, m_c_local.m_estate, 0); + ps = ExecInitNode(plan, m_c_local.m_estate, 0); List* wcoList = (List*)linitial(node->withCheckOptionLists); List* wcoExprs = NIL; ListCell* ll = NULL; @@ -632,6 +636,9 @@ bool UpdateFusion::execute(long max_rows, char *completionTag) /* *************** * step 3: done * * ************** */ + if (ps != NULL) { + ExecEndNode(ps); + } success = true; if (m_local.m_ledger_hash_exist && !IsConnFromApp()) { errorno = snprintf_s(completionTag, COMPLETION_TAG_BUFSIZE, COMPLETION_TAG_BUFSIZE - 1, diff --git a/src/test/regress/expected/updatable_views.out b/src/test/regress/expected/updatable_views.out index ae07c665a1..3404210b77 100644 --- a/src/test/regress/expected/updatable_views.out +++ b/src/test/regress/expected/updatable_views.out @@ -2437,5 +2437,40 @@ DETAIL: Failing row contains (0, null). insert into rw_view2 values (10); -- fail ERROR: new row violates WITH CHECK OPTION for view "rw_view2" DETAIL: Failing row contains (10, null). +CREATE TABLE base_tbl (a int primary key, b int DEFAULT 10); +NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "base_tbl_pkey" for table "base_tbl" +INSERT INTO base_tbl VALUES (1,2), (2,3); +CREATE VIEW ro_view1 AS SELECT * FROM base_tbl WHERE a < 10 WITH CHECK OPTION; +INSERT INTO ro_view1 VALUES(3,4); +explain (costs off) UPDATE ro_view1 SET b = 5 WHERE a = 3; + QUERY PLAN +-------------------------------------------------- + [Bypass] + Update on base_tbl + -> Index Scan using base_tbl_pkey on base_tbl + Index Cond: ((a < 10) AND (a = 3)) +(4 rows) + +UPDATE ro_view1 SET b = 5 WHERE a = 3; +drop table if exists base_tbl cascade; +NOTICE: drop cascades to view ro_view1 +CREATE TABLE base_tbl (a int primary key, b int DEFAULT 10); +NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "base_tbl_pkey" for table "base_tbl" +INSERT INTO base_tbl VALUES (1,2), (8,2), (9,0); +CREATE VIEW ro_view1 AS SELECT * FROM base_tbl WHERE a < 10 WITH CHECK OPTION; +set enable_seqscan = off; +set enable_bitmapscan = off; +explain (costs off) UPDATE ro_view1 SET a = a + b; + QUERY PLAN +-------------------------------------------------- + [Bypass] + Update on base_tbl + -> Index Scan using base_tbl_pkey on base_tbl + Index Cond: (a < 10) +(4 rows) + +UPDATE ro_view1 SET a = a + b; +ERROR: new row violates WITH CHECK OPTION for view "ro_view1" +DETAIL: Failing row contains (10, 2). \c regression drop database updatable_views_db; diff --git a/src/test/regress/sql/updatable_views.sql b/src/test/regress/sql/updatable_views.sql index d38b0a0a10..f97fce2c9a 100644 --- a/src/test/regress/sql/updatable_views.sql +++ b/src/test/regress/sql/updatable_views.sql @@ -1246,5 +1246,23 @@ alter view rw_view2 as select * from rw_view1 where id < 10 with cascaded check insert into rw_view2 values (0); -- fail insert into rw_view2 values (10); -- fail +CREATE TABLE base_tbl (a int primary key, b int DEFAULT 10); +INSERT INTO base_tbl VALUES (1,2), (2,3); +CREATE VIEW ro_view1 AS SELECT * FROM base_tbl WHERE a < 10 WITH CHECK OPTION; +INSERT INTO ro_view1 VALUES(3,4); + +explain (costs off) UPDATE ro_view1 SET b = 5 WHERE a = 3; +UPDATE ro_view1 SET b = 5 WHERE a = 3; + +drop table if exists base_tbl cascade; +CREATE TABLE base_tbl (a int primary key, b int DEFAULT 10); +INSERT INTO base_tbl VALUES (1,2), (8,2), (9,0); +CREATE VIEW ro_view1 AS SELECT * FROM base_tbl WHERE a < 10 WITH CHECK OPTION; + +set enable_seqscan = off; +set enable_bitmapscan = off; +explain (costs off) UPDATE ro_view1 SET a = a + b; +UPDATE ro_view1 SET a = a + b; + \c regression drop database updatable_views_db; \ No newline at end of file -- Gitee