From 5852d1949f1efef3aa7eeecc3e33e605f3c82b86 Mon Sep 17 00:00:00 2001 From: openGaussDev Date: Mon, 7 Mar 2022 15:51:43 +0800 Subject: [PATCH] Fix the bug sublink pullup in SWCB contains subquerys Offering: openGaussDev More detail: Match-id-dac69c0ec0d9bb19b1464709d932ca87a889f67f --- .../optimizer/prep/prepjointree.cpp | 35 +++++++++++++ src/test/regress/expected/sw_bugfix-2.out | 51 +++++++++++++++++++ src/test/regress/expected/sw_icbc.out | 14 ++--- src/test/regress/sql/sw_bugfix-2.sql | 21 ++++++++ 4 files changed, 115 insertions(+), 6 deletions(-) mode change 100644 => 100755 src/test/regress/expected/sw_bugfix-2.out mode change 100644 => 100755 src/test/regress/expected/sw_icbc.out diff --git a/src/gausskernel/optimizer/prep/prepjointree.cpp b/src/gausskernel/optimizer/prep/prepjointree.cpp index 01993edef..ff6b31939 100755 --- a/src/gausskernel/optimizer/prep/prepjointree.cpp +++ b/src/gausskernel/optimizer/prep/prepjointree.cpp @@ -107,8 +107,10 @@ static Node *pull_up_sublinks_targetlist(PlannerInfo *root, Node *node, Node *jtnode, Relids *relids, Node **newTargetList, Node *whereQuals); + #ifndef ENABLE_MULTIPLE_NODES static bool find_rownum_in_quals(PlannerInfo *root); +static bool contains_swctes(const PlannerInfo *root); #endif /* @@ -154,6 +156,34 @@ void replace_empty_jointree(Query *parse) parse->jointree->fromlist = list_make1(rtr); } +#ifndef ENABLE_MULTIPLE_NODES +/* + * helper function to check if SWCB ctes contaisn in current SubQuery, normally help us to + * idenfity if it is OK to appy SWCB related optimization steps + */ +static bool contains_swctes(const PlannerInfo *root) +{ + if (root->parse == NULL || root->parse->cteList == NIL) { + return false; + } + + List *cteList = root->parse->cteList; + ListCell *lc = NULL; + bool found = false; + foreach(lc, cteList) { + CommonTableExpr *cte = (CommonTableExpr *)lfirst(lc); + + /* check if cte from parse->ctelist is a swcb converted */ + if (cte->swoptions != NULL) { + found = true; + break; + } + } + + return found; +} +#endif + /* * pull_up_sublinks * Attempt to pull up ANY and EXISTS SubLinks to be treated as @@ -192,6 +222,11 @@ void pull_up_sublinks(PlannerInfo* root) if (find_rownum_in_quals(root)) { return; } + + /* check existance of SWCB converted */ + if (contains_swctes(root)) { + return; + } #endif /* Begin recursion through the jointree */ diff --git a/src/test/regress/expected/sw_bugfix-2.out b/src/test/regress/expected/sw_bugfix-2.out old mode 100644 new mode 100755 index 2767ea5d0..fc9981c42 --- a/src/test/regress/expected/sw_bugfix-2.out +++ b/src/test/regress/expected/sw_bugfix-2.out @@ -1084,6 +1084,57 @@ select t1.id,t1.pid,t1.name from test_hcb_ptb t1 start with not exists(select * 1 | 0 | 中国 (6 rows) +-- test sublibk pull is no allowed in swcb converted cases +explain (costs off) +select id,pid,level +from test_hcb_ptb +where exists ( + select id + from test_place t + where t.id=test_hcb_ptb.id +) +start with id=151 connect by prior pid=id; + QUERY PLAN +------------------------------------------------------------------------------------------- + CTE Scan on tmp_reuslt + Filter: (alternatives: SubPlan 2 or hashed SubPlan 3) + CTE tmp_reuslt + -> StartWith Operator + Start With pseudo atts: RUITR, array_key_9 + -> Recursive Union + -> Seq Scan on test_hcb_ptb + Filter: (id = 151) + -> Hash Join + Hash Cond: (swtest.test_hcb_ptb.id = tmp_reuslt."test_hcb_ptb@pid") + -> Seq Scan on test_hcb_ptb + -> Hash + -> WorkTable Scan on tmp_reuslt + SubPlan 2 + -> Seq Scan on test_place t + Filter: (id = tmp_reuslt."test_hcb_ptb@id") + SubPlan 3 + -> Seq Scan on test_place t +(18 rows) + +select id,pid,level +from test_hcb_ptb +where exists ( + select id + from test_place t + where t.id=test_hcb_ptb.id +) +start with id=151 connect by prior pid=id; + id | pid | level +-----+-----+------- + 151 | 141 | 1 + 141 | 131 | 2 + 131 | 121 | 3 + 121 | 111 | 4 + 111 | 11 | 5 + 11 | 1 | 6 + 1 | 0 | 7 +(7 rows) + drop table test_place; -- test where quals pushdown drop table if exists brand_sw3 cascade; diff --git a/src/test/regress/expected/sw_icbc.out b/src/test/regress/expected/sw_icbc.out old mode 100644 new mode 100755 index d20a601a8..421b67d4a --- a/src/test/regress/expected/sw_icbc.out +++ b/src/test/regress/expected/sw_icbc.out @@ -452,8 +452,8 @@ where not exists (select 1 from t1 where test.id = t1.id) start with test.id = 1 connect by prior test.id = test.pid; QUERY PLAN ------------------------------------------------------------------------------------------------- - Hash Anti Join (cost=19.42..22.29 rows=82 width=40) - Hash Cond: (tmp_reuslt."test@id" = t1.id) + CTE Scan on tmp_reuslt (cost=18.22..121.28 rows=46 width=40) + Filter: (NOT (alternatives: SubPlan 2 or hashed SubPlan 3)) CTE tmp_reuslt -> StartWith Operator (cost=0.00..18.22 rows=91 width=10) Start With pseudo atts: RUITR, array_key_1 @@ -465,10 +465,12 @@ start with test.id = 1 connect by prior test.id = test.pid; -> Seq Scan on t1 test (cost=0.00..1.09 rows=9 width=10) -> Hash (cost=0.20..0.20 rows=10 width=4) -> WorkTable Scan on tmp_reuslt (cost=0.00..0.20 rows=10 width=4) - -> CTE Scan on tmp_reuslt (cost=0.00..1.82 rows=91 width=40) - -> Hash (cost=1.09..1.09 rows=9 width=4) - -> Seq Scan on t1 (cost=0.00..1.09 rows=9 width=4) -(16 rows) + SubPlan 2 + -> Seq Scan on t1 (cost=0.00..1.11 rows=1 width=0) + Filter: (tmp_reuslt."test@id" = id) + SubPlan 3 + -> Seq Scan on t1 (cost=0.00..1.09 rows=9 width=4) +(18 rows) --multiple tables case explain (costs off) select * from t1, t2 where t1.id = t2.id start with t1.id = t2.id and t1.id = 1 connect by prior t1.id = t1.pid; diff --git a/src/test/regress/sql/sw_bugfix-2.sql b/src/test/regress/sql/sw_bugfix-2.sql index bd1d52850..c23ed8ae9 100644 --- a/src/test/regress/sql/sw_bugfix-2.sql +++ b/src/test/regress/sql/sw_bugfix-2.sql @@ -393,6 +393,27 @@ drop table t_customer; -- test correlated sublink create table test_place as select id, name, tex from test_hcb_ptb; select t1.id,t1.pid,t1.name from test_hcb_ptb t1 start with not exists(select * from test_place where id=t1.id and id !=141) connect by prior pid=id; + +-- test sublibk pull is no allowed in swcb converted cases +explain (costs off) +select id,pid,level +from test_hcb_ptb +where exists ( + select id + from test_place t + where t.id=test_hcb_ptb.id +) +start with id=151 connect by prior pid=id; + +select id,pid,level +from test_hcb_ptb +where exists ( + select id + from test_place t + where t.id=test_hcb_ptb.id +) +start with id=151 connect by prior pid=id; + drop table test_place; -- test where quals pushdown