pathnode->parent = rel;
pathnode->param_info = get_baserel_parampathinfo(root, rel,
required_outer);
+ pathnode->parallel_safe = rel->consider_parallel;
pathnode->pathkeys = NIL; /* seqscan has unordered result */
cost_seqscan(pathnode, root, rel, pathnode->param_info);
pathnode->parent = rel;
pathnode->param_info = get_baserel_parampathinfo(root, rel,
required_outer);
+ pathnode->parallel_safe = rel->consider_parallel;
pathnode->pathkeys = NIL; /* samplescan has unordered result */
cost_samplescan(pathnode, root, rel, pathnode->param_info);
pathnode->path.parent = rel;
pathnode->path.param_info = get_baserel_parampathinfo(root, rel,
required_outer);
+ pathnode->path.parallel_safe = rel->consider_parallel;
pathnode->path.pathkeys = pathkeys;
/* Convert clauses to indexquals the executor can handle */
pathnode->path.parent = rel;
pathnode->path.param_info = get_baserel_parampathinfo(root, rel,
required_outer);
+ pathnode->path.parallel_safe = rel->consider_parallel;
pathnode->path.pathkeys = NIL; /* always unordered */
pathnode->bitmapqual = bitmapqual;
pathnode->path.pathtype = T_BitmapAnd;
pathnode->path.parent = rel;
pathnode->path.param_info = NULL; /* not used in bitmap trees */
+ pathnode->path.parallel_safe = rel->consider_parallel;
pathnode->path.pathkeys = NIL; /* always unordered */
pathnode->bitmapquals = bitmapquals;
pathnode->path.pathtype = T_BitmapOr;
pathnode->path.parent = rel;
pathnode->path.param_info = NULL; /* not used in bitmap trees */
+ pathnode->path.parallel_safe = rel->consider_parallel;
pathnode->path.pathkeys = NIL; /* always unordered */
pathnode->bitmapquals = bitmapquals;
pathnode->path.parent = rel;
pathnode->path.param_info = get_baserel_parampathinfo(root, rel,
required_outer);
+ pathnode->path.parallel_safe = rel->consider_parallel;
pathnode->path.pathkeys = NIL; /* always unordered */
pathnode->tidquals = tidquals;
pathnode->path.parent = rel;
pathnode->path.param_info = get_appendrel_parampathinfo(rel,
required_outer);
+ pathnode->path.parallel_safe = rel->consider_parallel;
pathnode->path.pathkeys = NIL; /* result is always considered
* unsorted */
pathnode->subpaths = subpaths;
pathnode->path.parent = rel;
pathnode->path.param_info = get_appendrel_parampathinfo(rel,
required_outer);
+ pathnode->path.parallel_safe = rel->consider_parallel;
pathnode->path.pathkeys = pathkeys;
pathnode->subpaths = subpaths;
* This is only used for the case of a query with an empty jointree.
*/
ResultPath *
-create_result_path(List *quals)
+create_result_path(RelOptInfo *emptyjoinrel, List *quals)
{
ResultPath *pathnode = makeNode(ResultPath);
pathnode->path.pathtype = T_Result;
pathnode->path.parent = NULL;
pathnode->path.param_info = NULL; /* there are no other rels... */
+ pathnode->path.parallel_safe = emptyjoinrel->consider_parallel;
pathnode->path.pathkeys = NIL;
pathnode->quals = quals;
pathnode->path.pathtype = T_Material;
pathnode->path.parent = rel;
pathnode->path.param_info = subpath->param_info;
+ pathnode->path.parallel_safe = rel->consider_parallel;
pathnode->path.pathkeys = subpath->pathkeys;
pathnode->subpath = subpath;
pathnode->path.pathtype = T_Unique;
pathnode->path.parent = rel;
pathnode->path.param_info = subpath->param_info;
+ pathnode->path.parallel_safe = rel->consider_parallel;
/*
* Assume the output is unsorted, since we don't necessarily have pathkeys
{
GatherPath *pathnode = makeNode(GatherPath);
+ Assert(subpath->parallel_safe);
+
pathnode->path.pathtype = T_Gather;
pathnode->path.parent = rel;
pathnode->path.param_info = get_baserel_parampathinfo(root, rel,
required_outer);
- pathnode->path.pathkeys = NIL; /* Gather has unordered result */
+ pathnode->path.parallel_safe = false;
+
+ /*
+ * Without the single-copy flag, a Gather node will destroy the result
+ * ordering. See create_single_copy_gather_path.
+ */
+ pathnode->path.pathkeys = NIL;
pathnode->subpath = subpath;
pathnode->num_workers = nworkers;
+ pathnode->single_copy = false;
+
+ cost_gather(pathnode, root, rel, pathnode->path.param_info);
+
+ return pathnode;
+}
+
+/*
+ * create_single_copy_gather_path
+ *
+ * Creates a path corresponding to a single-copy gather operation,
+ * returning the pathnode.
+ */
+GatherPath *
+create_single_copy_gather_path(PlannerInfo *root, RelOptInfo *rel,
+ Path *subpath, Relids required_outer)
+{
+ GatherPath *pathnode = makeNode(GatherPath);
+
+ Assert(subpath->parallel_safe);
+
+ pathnode->path.pathtype = T_Gather;
+ pathnode->path.parent = rel;
+ pathnode->path.param_info = get_baserel_parampathinfo(root, rel,
+ required_outer);
+ pathnode->path.parallel_safe = false;
+
+ /* Subplan is run-once, so we'll preserve its ordering. */
+ pathnode->path.pathkeys = subpath->pathkeys;
+
+ pathnode->subpath = subpath;
+ pathnode->num_workers = 1;
+ pathnode->single_copy = true;
cost_gather(pathnode, root, rel, pathnode->path.param_info);
pathnode->parent = rel;
pathnode->param_info = get_baserel_parampathinfo(root, rel,
required_outer);
+ pathnode->parallel_safe = rel->consider_parallel;
pathnode->pathkeys = pathkeys;
cost_subqueryscan(pathnode, root, rel, pathnode->param_info);
pathnode->parent = rel;
pathnode->param_info = get_baserel_parampathinfo(root, rel,
required_outer);
+ pathnode->parallel_safe = rel->consider_parallel;
pathnode->pathkeys = pathkeys;
cost_functionscan(pathnode, root, rel, pathnode->param_info);
pathnode->parent = rel;
pathnode->param_info = get_baserel_parampathinfo(root, rel,
required_outer);
+ pathnode->parallel_safe = rel->consider_parallel;
pathnode->pathkeys = NIL; /* result is always unordered */
cost_valuesscan(pathnode, root, rel, pathnode->param_info);
pathnode->parent = rel;
pathnode->param_info = get_baserel_parampathinfo(root, rel,
required_outer);
+ pathnode->parallel_safe = rel->consider_parallel;
pathnode->pathkeys = NIL; /* XXX for now, result is always unordered */
cost_ctescan(pathnode, root, rel, pathnode->param_info);
pathnode->parent = rel;
pathnode->param_info = get_baserel_parampathinfo(root, rel,
required_outer);
+ pathnode->parallel_safe = rel->consider_parallel;
pathnode->pathkeys = NIL; /* result is always unordered */
/* Cost is the same as for a regular CTE scan */
pathnode->path.parent = rel;
pathnode->path.param_info = get_baserel_parampathinfo(root, rel,
required_outer);
+ pathnode->path.parallel_safe = rel->consider_parallel;
pathnode->path.rows = rows;
pathnode->path.startup_cost = startup_cost;
pathnode->path.total_cost = total_cost;
sjinfo,
required_outer,
&restrict_clauses);
+ pathnode->path.parallel_safe = joinrel->consider_parallel;
pathnode->path.pathkeys = pathkeys;
pathnode->jointype = jointype;
pathnode->outerjoinpath = outer_path;
sjinfo,
required_outer,
&restrict_clauses);
+ pathnode->jpath.path.parallel_safe = joinrel->consider_parallel;
pathnode->jpath.path.pathkeys = pathkeys;
pathnode->jpath.jointype = jointype;
pathnode->jpath.outerjoinpath = outer_path;
sjinfo,
required_outer,
&restrict_clauses);
+ pathnode->jpath.path.parallel_safe = joinrel->consider_parallel;
/*
* A hashjoin never has pathkeys, since its output ordering is