diff --git a/src/backend/optimizer/path/joinpath.c b/src/backend/optimizer/path/joinpath.c index 41b60d0..58078b5 100644 --- a/src/backend/optimizer/path/joinpath.c +++ b/src/backend/optimizer/path/joinpath.c @@ -1450,10 +1450,15 @@ hash_inner_and_outer(PlannerInfo *root, * If the joinrel is parallel-safe, we may be able to consider a * partial hash join. However, we can't handle JOIN_UNIQUE_OUTER, * because the outer path will be partial, and therefore we won't be - * able to properly guarantee uniqueness. Also, the resulting path + * able to properly guarantee uniqueness. Similarly we can't handle + * JOIN_FULL and JOIN_RIGHT because they can produce false null + * extended rows as outer path is partial. Also, the resulting path * must not be parameterized. */ - if (joinrel->consider_parallel && jointype != JOIN_UNIQUE_OUTER && + if (joinrel->consider_parallel && + jointype != JOIN_UNIQUE_OUTER && + jointype != JOIN_FULL && + jointype != JOIN_RIGHT && outerrel->partial_pathlist != NIL && bms_is_empty(joinrel->lateral_relids)) { diff --git a/src/test/regress/expected/join.out b/src/test/regress/expected/join.out index cafbc5e..e2028d4 100644 --- a/src/test/regress/expected/join.out +++ b/src/test/regress/expected/join.out @@ -5260,3 +5260,30 @@ ERROR: invalid reference to FROM-clause entry for table "xx1" LINE 1: ...xx1 using lateral (select * from int4_tbl where f1 = x1) ss; ^ HINT: There is an entry for table "xx1", but it cannot be referenced from this part of the query. +-- avoid parallel full and right join path. +create table mytab(x int,x1 char(20),x2 varchar(9)); +create table mytab1(y int,y1 char(20),y2 varchar(9)); +insert into mytab values (generate_series(1,200000),'aaaaaaaaaaaaaaaa','aaaaaaaaa'); +insert into mytab1 values (generate_series(1,100000),'aaaaaaaaaaaaaaaa','aaaaaaaaa'); +analyze mytab; +analyze mytab1; +select count(*) FROM mytab right outer join mytab1 ON mytab.x = mytab1.y; + count +-------- + 100000 +(1 row) + +select count(*) FROM mytab full outer join mytab1 ON mytab.x = mytab1.y; + count +-------- + 200000 +(1 row) + +select count(*) FROM mytab left outer join mytab1 ON mytab.x = mytab1.y; + count +-------- + 200000 +(1 row) + +drop table mytab; +drop table mytab1; diff --git a/src/test/regress/sql/join.sql b/src/test/regress/sql/join.sql index 3430f91..52d29c4 100644 --- a/src/test/regress/sql/join.sql +++ b/src/test/regress/sql/join.sql @@ -1696,3 +1696,17 @@ update xx1 set x2 = f1 from xx1, lateral (select * from int4_tbl where f1 = x1) delete from xx1 using (select * from int4_tbl where f1 = x1) ss; delete from xx1 using (select * from int4_tbl where f1 = xx1.x1) ss; delete from xx1 using lateral (select * from int4_tbl where f1 = x1) ss; + +-- avoid parallel full and right join path. +create table mytab(x int,x1 char(20),x2 varchar(9)); +create table mytab1(y int,y1 char(20),y2 varchar(9)); +insert into mytab values (generate_series(1,200000),'aaaaaaaaaaaaaaaa','aaaaaaaaa'); +insert into mytab1 values (generate_series(1,100000),'aaaaaaaaaaaaaaaa','aaaaaaaaa'); +analyze mytab; +analyze mytab1; +select count(*) FROM mytab right outer join mytab1 ON mytab.x = mytab1.y; +select count(*) FROM mytab full outer join mytab1 ON mytab.x = mytab1.y; +select count(*) FROM mytab left outer join mytab1 ON mytab.x = mytab1.y; + +drop table mytab; +drop table mytab1;