修复inner unique处理createpath缺陷
在query_dop开启(大于1)的情况下,createMergejoinPath/createNestloopPath等路径 生成跟query_dop=1的情况为不同的函数,inner unique相关逻辑没有处理,导致执行时宕机 现将该变量正确赋值
This commit is contained in:
@ -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;
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
|
||||
Reference in New Issue
Block a user