summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/backend/optimizer/path/joinpath.c21
-rw-r--r--src/test/regress/expected/join.out27
-rw-r--r--src/test/regress/sql/join.sql20
3 files changed, 62 insertions, 6 deletions
diff --git a/src/backend/optimizer/path/joinpath.c b/src/backend/optimizer/path/joinpath.c
index 3b9407eb2eb..ea5b6415186 100644
--- a/src/backend/optimizer/path/joinpath.c
+++ b/src/backend/optimizer/path/joinpath.c
@@ -2260,10 +2260,20 @@ hash_inner_and_outer(PlannerInfo *root,
/*
* If the joinrel is parallel-safe, we may be able to consider a
- * partial hash join. However, the resulting path must not be
- * parameterized.
+ * partial hash join.
+ *
+ * However, we can't handle JOIN_RIGHT_SEMI, because the hash table is
+ * either a shared hash table or a private hash table per backend. In
+ * the shared case, there is no concurrency protection for the match
+ * flags, so multiple workers could inspect and set the flags
+ * concurrently, potentially producing incorrect results. In the
+ * private case, each worker has its own copy of the hash table, so no
+ * single process has all the match flags.
+ *
+ * Also, the resulting path must not be parameterized.
*/
if (joinrel->consider_parallel &&
+ jointype != JOIN_RIGHT_SEMI &&
outerrel->partial_pathlist != NIL &&
bms_is_empty(joinrel->lateral_relids))
{
@@ -2294,13 +2304,12 @@ hash_inner_and_outer(PlannerInfo *root,
* Normally, given that the joinrel is parallel-safe, the cheapest
* total inner path will also be parallel-safe, but if not, we'll
* have to search for the cheapest safe, unparameterized inner
- * path. If full, right, right-semi or right-anti join, we can't
- * use parallelism (building the hash table in each backend)
- * because no one process has all the match bits.
+ * path. If full, right, or right-anti join, we can't use
+ * parallelism (building the hash table in each backend) because
+ * no one process has all the match bits.
*/
if (jointype == JOIN_FULL ||
jointype == JOIN_RIGHT ||
- jointype == JOIN_RIGHT_SEMI ||
jointype == JOIN_RIGHT_ANTI)
cheapest_safe_inner = NULL;
else if (cheapest_total_inner->parallel_safe)
diff --git a/src/test/regress/expected/join.out b/src/test/regress/expected/join.out
index d10095de70f..0e82ca1867a 100644
--- a/src/test/regress/expected/join.out
+++ b/src/test/regress/expected/join.out
@@ -3081,6 +3081,33 @@ select * from tbl_rs t1 join
(6 rows)
--
+-- regression test for bug with parallel-hash-right-semi join
+--
+begin;
+-- encourage use of parallel plans
+set local parallel_setup_cost=0;
+set local parallel_tuple_cost=0;
+set local min_parallel_table_scan_size=0;
+set local max_parallel_workers_per_gather=4;
+-- ensure we don't get parallel hash right semi join
+explain (costs off)
+select * from tenk1 t1
+where exists (select 1 from tenk1 t2 where fivethous = t1.fivethous)
+and t1.fivethous < 5;
+ QUERY PLAN
+--------------------------------------------------
+ Gather
+ Workers Planned: 4
+ -> Parallel Hash Semi Join
+ Hash Cond: (t1.fivethous = t2.fivethous)
+ -> Parallel Seq Scan on tenk1 t1
+ Filter: (fivethous < 5)
+ -> Parallel Hash
+ -> Parallel Seq Scan on tenk1 t2
+(8 rows)
+
+rollback;
+--
-- regression test for bug #13908 (hash join with skew tuples & nbatch increase)
--
set work_mem to '64kB';
diff --git a/src/test/regress/sql/join.sql b/src/test/regress/sql/join.sql
index b1732453e8d..c6b8b09a381 100644
--- a/src/test/regress/sql/join.sql
+++ b/src/test/regress/sql/join.sql
@@ -760,6 +760,26 @@ select * from tbl_rs t1 join
on true;
--
+-- regression test for bug with parallel-hash-right-semi join
+--
+
+begin;
+
+-- encourage use of parallel plans
+set local parallel_setup_cost=0;
+set local parallel_tuple_cost=0;
+set local min_parallel_table_scan_size=0;
+set local max_parallel_workers_per_gather=4;
+
+-- ensure we don't get parallel hash right semi join
+explain (costs off)
+select * from tenk1 t1
+where exists (select 1 from tenk1 t2 where fivethous = t1.fivethous)
+and t1.fivethous < 5;
+
+rollback;
+
+--
-- regression test for bug #13908 (hash join with skew tuples & nbatch increase)
--