index 40eb58341c1c4722ecb729f9525152f82eb57716..02dd9724924c775283ef93b07093fd0d558abb32 100644 (file)
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);
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);
}
}
index c96285d1bb60e08c021ae5693146e021876743aa..7487ea0b820c5da5641c9d05b35ff15956809972 100644 (file)
@@ -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)
index 20376c03fae2ea9f8a7f47f0c24843de771ad396..9b019d31ed71ed1a28f82c89c6f807013f759021 100644 (file)
@@ -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;