From b93d4de9ed4f9783d7e28f6f54c42f41623d65ca Mon Sep 17 00:00:00 2001 From: openGaussDev Date: Fri, 4 Mar 2022 12:56:56 +0800 Subject: [PATCH] Workaround for single connect-by cases Offering: openGaussDev More detail: If no rownum or level qual is present, do not create connect-by-level filter. Signed-off-by:peijisheng peijisheng@huawei.com Match-id-400310ecf9513b47303f71f69da642d4b44d762b --- src/common/backend/parser/parse_startwith.cpp | 8 ++-- .../runtime/executor/nodeStartWithOp.cpp | 2 +- src/test/regress/expected/sw_bugfix-2.out | 46 +++++++++++-------- 3 files changed, 32 insertions(+), 24 deletions(-) diff --git a/src/common/backend/parser/parse_startwith.cpp b/src/common/backend/parser/parse_startwith.cpp index 36ba6938a..1ab1ac9fb 100644 --- a/src/common/backend/parser/parse_startwith.cpp +++ b/src/common/backend/parser/parse_startwith.cpp @@ -1091,10 +1091,12 @@ static void transformStartWithClause(StartWithTransformContext *context, SelectS raw_expression_tree_walker((Node*)context->connectByExpr, (bool (*)())pseudo_level_rownum_walker, (Node*)context->connectByExpr); checkConnectByExprValidity((Node*)connectByExpr); + StartWithWalker(context, connectByExpr); context->relInfoList = context->pstate->p_start_info; - context->connect_by_type = CONNECT_BY_LEVEL; - context->connectByLevelExpr = connectByExpr; - context->connectByOtherExpr = NULL; + if (context->connect_by_type != CONNECT_BY_PRIOR) { + context->connectByLevelExpr = connectByExpr; + context->connectByOtherExpr = NULL; + } } /* transform start with ... connect by's expr */ diff --git a/src/gausskernel/runtime/executor/nodeStartWithOp.cpp b/src/gausskernel/runtime/executor/nodeStartWithOp.cpp index 8d0ce77e1..e556d3608 100644 --- a/src/gausskernel/runtime/executor/nodeStartWithOp.cpp +++ b/src/gausskernel/runtime/executor/nodeStartWithOp.cpp @@ -383,7 +383,7 @@ bool CheckCycleExeception(StartWithOpState *node, TupleTableSlot *slot) Assert (IsA(rustate, RecursiveUnionState)); - if (IsConnectByLevelStartWithPlan(swplan)) { + if (IsConnectByLevelStartWithPlan(swplan) || node->sw_keyAttnum == 0) { /* for connect by level case, we do not do cycle check */ return false; } diff --git a/src/test/regress/expected/sw_bugfix-2.out b/src/test/regress/expected/sw_bugfix-2.out index 473e29f60..2767ea5d0 100644 --- a/src/test/regress/expected/sw_bugfix-2.out +++ b/src/test/regress/expected/sw_bugfix-2.out @@ -484,17 +484,18 @@ select t1.id, t1.pid, t1.name from t1 start with not id=1 connect by prior pid=i explain select trim(t1.name) from test_hcb_ptb t1 connect by trim(t1.name) is not null; QUERY PLAN -------------------------------------------------------------------------------------------------- - CTE Scan on tmp_reuslt (cost=13471.92..22689.36 rows=409664 width=178) + CTE Scan on tmp_reuslt (cost=13473.52..22690.96 rows=409664 width=178) CTE tmp_reuslt - -> StartWith Operator (cost=0.00..13471.92 rows=409664 width=102) + -> StartWith Operator (cost=0.00..13473.52 rows=409664 width=102) Start With pseudo atts: RUITR - -> Recursive Union (cost=0.00..13471.92 rows=409664 width=102) + -> Recursive Union (cost=0.00..13473.52 rows=409664 width=102) -> Seq Scan on test_hcb_ptb t1 (cost=0.00..2.64 rows=64 width=102) - -> Nested Loop (cost=0.00..527.60 rows=40960 width=102) + -> Nested Loop (cost=0.00..527.76 rows=40960 width=102) -> WorkTable Scan on tmp_reuslt (cost=0.00..12.80 rows=640 width=0) - -> Materialize (cost=0.00..2.96 rows=64 width=102) - -> Seq Scan on test_hcb_ptb t1 (cost=0.00..2.64 rows=64 width=102) -(10 rows) + -> Materialize (cost=0.00..3.12 rows=64 width=102) + -> Seq Scan on test_hcb_ptb t1 (cost=0.00..2.80 rows=64 width=102) + Filter: (btrim((name)::text) IS NOT NULL) +(11 rows) /* fix create table as with start with */ create table ct as select t1.id,t1.pid,t1.name,level from test_hcb_ptb t1 start with id=141 connect by prior id=pid; @@ -1252,21 +1253,23 @@ explain performance select * from sw_dummy connect by level < 50; drop table sw_dummy; --test null pointers in connect by walker explain select * from t1 connect by exists(select distinct (select id from t1)); - QUERY PLAN -------------------------------------------------------------------------------------------- - CTE Scan on tmp_reuslt (cost=293.65..455.83 rows=8109 width=40) + QUERY PLAN +------------------------------------------------------------------------------------------------- + CTE Scan on tmp_reuslt (cost=293.75..455.93 rows=8109 width=40) CTE tmp_reuslt - -> StartWith Operator (cost=0.00..293.64 rows=8109 width=10) + -> StartWith Operator (cost=0.00..293.75 rows=8109 width=10) Start With pseudo atts: RUITR - -> Recursive Union (cost=0.00..293.64 rows=8109 width=10) + -> Recursive Union (cost=0.00..293.75 rows=8109 width=10) -> Seq Scan on t1 (cost=0.00..1.09 rows=9 width=10) - -> Nested Loop (cost=0.00..13.04 rows=810 width=10) - -> WorkTable Scan on tmp_reuslt (cost=0.00..1.80 rows=90 width=0) - -> Materialize (cost=0.00..1.14 rows=9 width=10) - -> Seq Scan on t1 (cost=0.00..1.09 rows=9 width=10) - InitPlan 2 (returns $2) - -> Result (cost=0.00..0.01 rows=1 width=0) -(12 rows) + -> Result (cost=0.01..13.05 rows=810 width=10) + One-Time Filter: $1 + InitPlan 1 (returns $1) + -> Result (cost=0.00..0.01 rows=1 width=0) + -> Nested Loop (cost=0.00..13.04 rows=810 width=10) + -> WorkTable Scan on tmp_reuslt (cost=0.00..1.80 rows=90 width=0) + -> Materialize (cost=0.00..1.14 rows=9 width=10) + -> Seq Scan on t1 (cost=0.00..1.09 rows=9 width=10) +(14 rows) --test join + where for start with .. connect by select t1.id,t1.pid,t2.id from test_hcb_ptb t1 join test_hcb_ptb t2 on t1.id=t2.id where t1.id>1 start with t1.id=141 connect by prior t2.id=t1.pid; @@ -1357,4 +1360,7 @@ WHERE true CONNECT BY EXISTS ( test_hcb_ptb as ref_7 ) LIMIT 169; -ERROR: Unsupported subquery found in connect by clause. + c0 +---- +(0 rows) +