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);
}
}
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)
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;