create_subqueryscan_path(root, rel, subpath,
pathkeys, required_outer));
}
+
+ /* If consider_parallel is false, there should be no partial paths. */
+ Assert(sub_final_rel->consider_parallel ||
+ sub_final_rel->partial_pathlist == NIL);
+
+ /* Same for partial paths. */
+ foreach(lc, sub_final_rel->partial_pathlist)
+ {
+ Path *subpath = (Path *) lfirst(lc);
+ List *pathkeys;
+
+ /* Convert subpath's pathkeys to outer representation */
+ pathkeys = convert_subquery_pathkeys(root,
+ rel,
+ subpath->pathkeys,
+ make_tlist_from_pathtarget(subpath->pathtarget));
+
+ /* Generate outer path using this subpath */
+ add_partial_path(rel, (Path *)
+ create_subqueryscan_path(root, rel, subpath,
+ pathkeys, required_outer));
+ }
}
/*
add_path(final_rel, path);
}
+ /*
+ * Generate partial paths for final_rel, too, if outer query levels might
+ * be able to make use of them.
+ */
+ if (final_rel->consider_parallel && root->query_level > 1 &&
+ !limit_needed(parse))
+ {
+ Assert(!parse->rowMarks && parse->commandType == CMD_SELECT);
+ foreach(lc, current_rel->partial_pathlist)
+ {
+ Path *partial_path = (Path *) lfirst(lc);
+
+ add_partial_path(final_rel, partial_path);
+ }
+ }
+
/*
* If there is an FDW that's responsible for all baserels of the query,
* let it consider adding ForeignPaths.
path->parallel_safe = false;
}
+ /*
+ * Forget about any partial paths and clear consider_parallel, too;
+ * they're not usable if we attached an initPlan.
+ */
+ final_rel->partial_pathlist = NIL;
+ final_rel->consider_parallel = false;
+
/* We needn't do set_cheapest() here, caller will do it */
}
{
SubqueryScan *sscan = (SubqueryScan *) plan;
RelOptInfo *rel;
+ Bitmapset *subquery_params;
- /* We must run SS_finalize_plan on the subquery */
+ /* We must run finalize_plan on the subquery */
rel = find_base_rel(root, sscan->scan.scanrelid);
- SS_finalize_plan(rel->subroot, sscan->subplan);
+ subquery_params = rel->subroot->outer_params;
+ if (gather_param >= 0)
+ subquery_params = bms_add_member(bms_copy(subquery_params),
+ gather_param);
+ finalize_plan(rel->subroot, sscan->subplan, gather_param,
+ subquery_params, NULL);
/* Now we can add its extParams to the parent's params */
context.paramids = bms_add_members(context.paramids,
ERROR: invalid input syntax for integer: "BAAAAA"
CONTEXT: parallel worker
ROLLBACK TO SAVEPOINT settings;
+-- test interaction with set-returning functions
+SAVEPOINT settings;
+-- multiple subqueries under a single Gather node
+-- must set parallel_setup_cost > 0 to discourage multiple Gather nodes
+SET LOCAL parallel_setup_cost = 10;
+EXPLAIN (COSTS OFF)
+SELECT unique1 FROM tenk1 WHERE fivethous = tenthous + 1
+UNION ALL
+SELECT unique1 FROM tenk1 WHERE fivethous = tenthous + 1;
+ QUERY PLAN
+----------------------------------------------------
+ Gather
+ Workers Planned: 4
+ -> Parallel Append
+ -> Parallel Seq Scan on tenk1
+ Filter: (fivethous = (tenthous + 1))
+ -> Parallel Seq Scan on tenk1 tenk1_1
+ Filter: (fivethous = (tenthous + 1))
+(7 rows)
+
+ROLLBACK TO SAVEPOINT settings;
+-- can't use multiple subqueries under a single Gather node due to initPlans
+EXPLAIN (COSTS OFF)
+SELECT unique1 FROM tenk1 WHERE fivethous =
+ (SELECT unique1 FROM tenk1 WHERE fivethous = 1 LIMIT 1)
+UNION ALL
+SELECT unique1 FROM tenk1 WHERE fivethous =
+ (SELECT unique2 FROM tenk1 WHERE fivethous = 1 LIMIT 1)
+ORDER BY 1;
+ QUERY PLAN
+--------------------------------------------------------------------
+ Sort
+ Sort Key: tenk1.unique1
+ -> Append
+ -> Gather
+ Workers Planned: 4
+ Params Evaluated: $1
+ InitPlan 1 (returns $1)
+ -> Limit
+ -> Gather
+ Workers Planned: 4
+ -> Parallel Seq Scan on tenk1 tenk1_2
+ Filter: (fivethous = 1)
+ -> Parallel Seq Scan on tenk1
+ Filter: (fivethous = $1)
+ -> Gather
+ Workers Planned: 4
+ Params Evaluated: $3
+ InitPlan 2 (returns $3)
+ -> Limit
+ -> Gather
+ Workers Planned: 4
+ -> Parallel Seq Scan on tenk1 tenk1_3
+ Filter: (fivethous = 1)
+ -> Parallel Seq Scan on tenk1 tenk1_1
+ Filter: (fivethous = $3)
+(25 rows)
+
+-- test interaction with SRFs
+SELECT * FROM information_schema.foreign_data_wrapper_options
+ORDER BY 1, 2, 3;
+ foreign_data_wrapper_catalog | foreign_data_wrapper_name | option_name | option_value
+------------------------------+---------------------------+-------------+--------------
+(0 rows)
+
rollback;
select stringu1::int2 from tenk1 where unique1 = 1;
ROLLBACK TO SAVEPOINT settings;
+-- test interaction with set-returning functions
+SAVEPOINT settings;
+
+-- multiple subqueries under a single Gather node
+-- must set parallel_setup_cost > 0 to discourage multiple Gather nodes
+SET LOCAL parallel_setup_cost = 10;
+EXPLAIN (COSTS OFF)
+SELECT unique1 FROM tenk1 WHERE fivethous = tenthous + 1
+UNION ALL
+SELECT unique1 FROM tenk1 WHERE fivethous = tenthous + 1;
+ROLLBACK TO SAVEPOINT settings;
+
+-- can't use multiple subqueries under a single Gather node due to initPlans
+EXPLAIN (COSTS OFF)
+SELECT unique1 FROM tenk1 WHERE fivethous =
+ (SELECT unique1 FROM tenk1 WHERE fivethous = 1 LIMIT 1)
+UNION ALL
+SELECT unique1 FROM tenk1 WHERE fivethous =
+ (SELECT unique2 FROM tenk1 WHERE fivethous = 1 LIMIT 1)
+ORDER BY 1;
+
+-- test interaction with SRFs
+SELECT * FROM information_schema.foreign_data_wrapper_options
+ORDER BY 1, 2, 3;
+
rollback;