aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/backend/optimizer/path/joinpath.c25
-rw-r--r--src/test/regress/expected/select_parallel.out30
-rw-r--r--src/test/regress/sql/select_parallel.sql10
3 files changed, 65 insertions, 0 deletions
diff --git a/src/backend/optimizer/path/joinpath.c b/src/backend/optimizer/path/joinpath.c
index 40eb58341c1..02dd9724924 100644
--- a/src/backend/optimizer/path/joinpath.c
+++ b/src/backend/optimizer/path/joinpath.c
@@ -2021,11 +2021,31 @@ consider_parallel_nestloop(PlannerInfo *root,
JoinPathExtraData *extra)
{
JoinType save_jointype = jointype;
+ Path *inner_cheapest_total = innerrel->cheapest_total_path;
+ Path *matpath = NULL;
ListCell *lc1;
if (jointype == JOIN_UNIQUE_INNER)
jointype = JOIN_INNER;
+ /*
+ * Consider materializing the cheapest inner path, unless: 1) we're doing
+ * JOIN_UNIQUE_INNER, because in this case we have to unique-ify the
+ * cheapest inner path, 2) enable_material is off, 3) the cheapest inner
+ * path is not parallel-safe, 4) the cheapest inner path is parameterized
+ * by the outer rel, or 5) the cheapest inner path materializes its output
+ * anyway.
+ */
+ if (save_jointype != JOIN_UNIQUE_INNER &&
+ enable_material && inner_cheapest_total->parallel_safe &&
+ !PATH_PARAM_BY_REL(inner_cheapest_total, outerrel) &&
+ !ExecMaterializesOutput(inner_cheapest_total->pathtype))
+ {
+ matpath = (Path *)
+ create_material_path(innerrel, inner_cheapest_total);
+ Assert(matpath->parallel_safe);
+ }
+
foreach(lc1, outerrel->partial_pathlist)
{
Path *outerpath = (Path *) lfirst(lc1);
@@ -2082,6 +2102,11 @@ consider_parallel_nestloop(PlannerInfo *root,
try_partial_nestloop_path(root, joinrel, outerpath, mpath,
pathkeys, jointype, extra);
}
+
+ /* Also consider materialized form of the cheapest inner path */
+ if (matpath != NULL)
+ try_partial_nestloop_path(root, joinrel, outerpath, matpath,
+ pathkeys, jointype, extra);
}
}
diff --git a/src/test/regress/expected/select_parallel.out b/src/test/regress/expected/select_parallel.out
index c96285d1bb6..7487ea0b820 100644
--- a/src/test/regress/expected/select_parallel.out
+++ b/src/test/regress/expected/select_parallel.out
@@ -653,6 +653,36 @@ select count(*) from tenk1, tenk2 where tenk1.unique1 = tenk2.unique1;
reset enable_hashjoin;
reset enable_nestloop;
+-- test parallel nestloop join path with materialization of the inner path
+alter table tenk2 set (parallel_workers = 0);
+explain (costs off)
+ select * from tenk1 t1, tenk2 t2 where t1.two > t2.two;
+ QUERY PLAN
+-------------------------------------------
+ Gather
+ Workers Planned: 4
+ -> Nested Loop
+ Join Filter: (t1.two > t2.two)
+ -> Parallel Seq Scan on tenk1 t1
+ -> Materialize
+ -> Seq Scan on tenk2 t2
+(7 rows)
+
+-- the joinrel is not parallel-safe due to the OFFSET clause in the subquery
+explain (costs off)
+ select * from tenk1 t1, (select * from tenk2 t2 offset 0) t2 where t1.two > t2.two;
+ QUERY PLAN
+-------------------------------------------
+ Nested Loop
+ Join Filter: (t1.two > t2.two)
+ -> Gather
+ Workers Planned: 4
+ -> Parallel Seq Scan on tenk1 t1
+ -> Materialize
+ -> Seq Scan on tenk2 t2
+(7 rows)
+
+alter table tenk2 reset (parallel_workers);
-- test gather merge
set enable_hashagg = false;
explain (costs off)
diff --git a/src/test/regress/sql/select_parallel.sql b/src/test/regress/sql/select_parallel.sql
index 20376c03fae..9b019d31ed7 100644
--- a/src/test/regress/sql/select_parallel.sql
+++ b/src/test/regress/sql/select_parallel.sql
@@ -266,6 +266,16 @@ select count(*) from tenk1, tenk2 where tenk1.unique1 = tenk2.unique1;
reset enable_hashjoin;
reset enable_nestloop;
+-- test parallel nestloop join path with materialization of the inner path
+alter table tenk2 set (parallel_workers = 0);
+explain (costs off)
+ select * from tenk1 t1, tenk2 t2 where t1.two > t2.two;
+
+-- the joinrel is not parallel-safe due to the OFFSET clause in the subquery
+explain (costs off)
+ select * from tenk1 t1, (select * from tenk2 t2 offset 0) t2 where t1.two > t2.two;
+alter table tenk2 reset (parallel_workers);
+
-- test gather merge
set enable_hashagg = false;