From 5aabed7f5006a27b85a38f3131025035a3eb0ce0 Mon Sep 17 00:00:00 2001 From: cc_db_dev Date: Mon, 30 Oct 2023 16:16:43 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8Dinner=20unique=E5=A4=84?= =?UTF-8?q?=E7=90=86createpath=E7=BC=BA=E9=99=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 在query_dop开启(大于1)的情况下,createMergejoinPath/createNestloopPath等路径 生成跟query_dop=1的情况为不同的函数,inner unique相关逻辑没有处理,导致执行时宕机 现将该变量正确赋值 --- src/gausskernel/optimizer/path/costsize.cpp | 6 +- .../optimizer/path/streampath_base.cpp | 3 + src/test/regress/expected/xc_FQS_join.out | 103 ++++++++++++++++++ src/test/regress/sql/xc_FQS_join.sql | 30 +++++ 4 files changed, 140 insertions(+), 2 deletions(-) diff --git a/src/gausskernel/optimizer/path/costsize.cpp b/src/gausskernel/optimizer/path/costsize.cpp index f7b8fc88f..b58afdacd 100755 --- a/src/gausskernel/optimizer/path/costsize.cpp +++ b/src/gausskernel/optimizer/path/costsize.cpp @@ -3501,9 +3501,11 @@ void final_cost_mergejoin( * all the joinclauses are merge clauses, this means we don't ever need to * back up the merge, and so we can skip mark/restore overhead. */ + Assert(extra->inner_unique == path->jpath.inner_unique); if (u_sess->attr.attr_sql.enable_inner_unique_opt) { - if ((path->jpath.jointype == JOIN_SEMI || path->jpath.jointype == JOIN_ANTI || extra->inner_unique) && - (list_length(path->jpath.joinrestrictinfo) == list_length(path->path_mergeclauses))) + if ((path->jpath.jointype == JOIN_SEMI || path->jpath.jointype == JOIN_ANTI + || (extra->inner_unique && path->jpath.inner_unique)) + && (list_length(path->jpath.joinrestrictinfo) == list_length(path->path_mergeclauses))) path->skip_mark_restore = true; else path->skip_mark_restore = false; diff --git a/src/gausskernel/optimizer/path/streampath_base.cpp b/src/gausskernel/optimizer/path/streampath_base.cpp index af8d4d505..5bf2d10f0 100755 --- a/src/gausskernel/optimizer/path/streampath_base.cpp +++ b/src/gausskernel/optimizer/path/streampath_base.cpp @@ -1116,6 +1116,7 @@ Path* HashJoinPathGen::createHashJoinPath() pathnode->jpath.path.pathkeys = NIL; pathnode->jpath.path.dop = m_dop; pathnode->jpath.jointype = m_jointype; + pathnode->jpath.inner_unique = m_extra->inner_unique; pathnode->jpath.outerjoinpath = m_outerStreamPath; pathnode->jpath.innerjoinpath = m_innerStreamPath; pathnode->jpath.joinrestrictinfo = m_joinRestrictinfo; @@ -1365,6 +1366,7 @@ Path* NestLoopPathGen::createNestloopPath() } pathnode->path.dop = m_dop; pathnode->jointype = m_jointype; + pathnode->inner_unique = m_extra->inner_unique; pathnode->outerjoinpath = m_outerStreamPath; pathnode->innerjoinpath = m_innerStreamPath; pathnode->joinrestrictinfo = m_joinClauses; @@ -1552,6 +1554,7 @@ Path* MergeJoinPathGen::createMergejoinPath() m_root, m_rel, m_outerStreamPath, m_innerStreamPath, m_extra->sjinfo, m_requiredOuter, &m_joinRestrictinfo); pathnode->jpath.path.pathkeys = m_pathkeys; pathnode->jpath.jointype = m_jointype; + pathnode->jpath.inner_unique = m_extra->inner_unique; pathnode->jpath.outerjoinpath = m_outerStreamPath; pathnode->jpath.innerjoinpath = m_innerStreamPath; pathnode->jpath.joinrestrictinfo = m_joinRestrictinfo; diff --git a/src/test/regress/expected/xc_FQS_join.out b/src/test/regress/expected/xc_FQS_join.out index 310c574cf..3976f4bae 100755 --- a/src/test/regress/expected/xc_FQS_join.out +++ b/src/test/regress/expected/xc_FQS_join.out @@ -1139,3 +1139,106 @@ SELECT 1 drop table t1; drop table rt1; +--test inner unique + smp +set query_dop=32; +set enable_inner_unique_opt=true; +set enable_material=off; +create table test_a(a int, b int); +create table test_b(c int, d int); +insert into test_a values(1,2),(1,3),(1,4); +insert into test_b values(1,2),(1,2),(1,3),(1,3),(1,4),(1,4); +create unique index test_inner_idx on test_a(b); +--merge join +explain (verbose ,costs off) +select /*+ mergejoin(test_a test_b) leading((test_b test_a)) indexscan(test_a test_inner_idx)*/ * from test_a,test_b where b=d; + QUERY PLAN +-------------------------------------------------------- + Merge Join + Output: test_a.a, test_a.b, test_b.c, test_b.d + Inner Unique: true + Merge Cond: (test_b.d = test_a.b) + -> Sort + Output: test_b.c, test_b.d + Sort Key: test_b.d + -> Seq Scan on public.test_b + Output: test_b.c, test_b.d + -> Index Scan using test_inner_idx on public.test_a + Output: test_a.a, test_a.b +(11 rows) + +select /*+ mergejoin(test_a test_b) leading((test_b test_a)) indexscan(test_a test_inner_idx)*/ * from test_a,test_b where b=d; + a | b | c | d +---+---+---+--- + 1 | 2 | 1 | 2 + 1 | 2 | 1 | 2 + 1 | 3 | 1 | 3 + 1 | 3 | 1 | 3 + 1 | 4 | 1 | 4 + 1 | 4 | 1 | 4 +(6 rows) + +--hash join +explain (verbose ,costs off) +select /*+ hashjoin(test_a test_b) leading((test_b test_a)) indexscan(test_a test_inner_idx)*/ * from test_a,test_b where b=d order by a,b; + QUERY PLAN +-------------------------------------------------------------------- + Sort + Output: test_a.a, test_a.b, test_b.c, test_b.d + Sort Key: test_a.a, test_a.b + -> Hash Join + Output: test_a.a, test_a.b, test_b.c, test_b.d + Inner Unique: true + Hash Cond: (test_b.d = test_a.b) + -> Seq Scan on public.test_b + Output: test_b.c, test_b.d + -> Hash + Output: test_a.a, test_a.b + -> Index Scan using test_inner_idx on public.test_a + Output: test_a.a, test_a.b +(13 rows) + +select /*+ hashjoin(test_a test_b) leading((test_b test_a)) indexscan(test_a test_inner_idx)*/ * from test_a,test_b where b=d order by a,b; + a | b | c | d +---+---+---+--- + 1 | 2 | 1 | 2 + 1 | 2 | 1 | 2 + 1 | 3 | 1 | 3 + 1 | 3 | 1 | 3 + 1 | 4 | 1 | 4 + 1 | 4 | 1 | 4 +(6 rows) + +--nestloop +explain (verbose ,costs off) +select /*+ nestloop(test_a test_b) leading((test_b test_a)) indexscan(test_a test_inner_idx)*/ * from test_a,test_b where b=d order by a,b; + QUERY PLAN +-------------------------------------------------------------- + Sort + Output: test_a.a, test_a.b, test_b.c, test_b.d + Sort Key: test_a.a, test_a.b + -> Nested Loop + Output: test_a.a, test_a.b, test_b.c, test_b.d + Inner Unique: true + -> Seq Scan on public.test_b + Output: test_b.c, test_b.d + -> Index Scan using test_inner_idx on public.test_a + Output: test_a.a, test_a.b + Index Cond: (test_a.b = test_b.d) +(11 rows) + +select /*+ nestloop(test_a test_b) leading((test_b test_a)) indexscan(test_a test_inner_idx)*/ * from test_a,test_b where b=d order by a,b; + a | b | c | d +---+---+---+--- + 1 | 2 | 1 | 2 + 1 | 2 | 1 | 2 + 1 | 3 | 1 | 3 + 1 | 3 | 1 | 3 + 1 | 4 | 1 | 4 + 1 | 4 | 1 | 4 +(6 rows) + +drop table test_a; +drop table test_b; +reset query_dop; +reset enable_inner_unique_opt; +reset enable_material; diff --git a/src/test/regress/sql/xc_FQS_join.sql b/src/test/regress/sql/xc_FQS_join.sql index f61e5cdec..bc33eb6d4 100644 --- a/src/test/regress/sql/xc_FQS_join.sql +++ b/src/test/regress/sql/xc_FQS_join.sql @@ -286,3 +286,33 @@ SELECT 1 drop table t1; drop table rt1; +--test inner unique + smp +set query_dop=32; +set enable_inner_unique_opt=true; +set enable_material=off; +create table test_a(a int, b int); +create table test_b(c int, d int); +insert into test_a values(1,2),(1,3),(1,4); +insert into test_b values(1,2),(1,2),(1,3),(1,3),(1,4),(1,4); +create unique index test_inner_idx on test_a(b); + +--merge join +explain (verbose ,costs off) +select /*+ mergejoin(test_a test_b) leading((test_b test_a)) indexscan(test_a test_inner_idx)*/ * from test_a,test_b where b=d; +select /*+ mergejoin(test_a test_b) leading((test_b test_a)) indexscan(test_a test_inner_idx)*/ * from test_a,test_b where b=d; + +--hash join +explain (verbose ,costs off) +select /*+ hashjoin(test_a test_b) leading((test_b test_a)) indexscan(test_a test_inner_idx)*/ * from test_a,test_b where b=d order by a,b; +select /*+ hashjoin(test_a test_b) leading((test_b test_a)) indexscan(test_a test_inner_idx)*/ * from test_a,test_b where b=d order by a,b; + +--nestloop +explain (verbose ,costs off) +select /*+ nestloop(test_a test_b) leading((test_b test_a)) indexscan(test_a test_inner_idx)*/ * from test_a,test_b where b=d order by a,b; +select /*+ nestloop(test_a test_b) leading((test_b test_a)) indexscan(test_a test_inner_idx)*/ * from test_a,test_b where b=d order by a,b; + +drop table test_a; +drop table test_b; +reset query_dop; +reset enable_inner_unique_opt; +reset enable_material;