diff --git a/src/backend/optimizer/util/pathnode.c b/src/backend/optimizer/util/pathnode.c index b8ea316..c80e316 100644 --- a/src/backend/optimizer/util/pathnode.c +++ b/src/backend/optimizer/util/pathnode.c @@ -2202,7 +2202,7 @@ Path * apply_projection_to_path(PlannerInfo *root, RelOptInfo *rel, Path *path, - PathTarget *target) + PathTarget * target) { QualCost oldcost; @@ -2222,6 +2222,19 @@ apply_projection_to_path(PlannerInfo *root, path->total_cost += target->cost.startup - oldcost.startup + (target->cost.per_tuple - oldcost.per_tuple) * path->rows; + /* + * If the path happens to be a Gather path, and the subpath is + * projection-capable, then insert the pathtarget there, too, so that the + * workers can help with projection. But if there is something that is + * not parallel-safe in the target expressions, then we can't. + */ + if (IsA(path, GatherPath)) + { + if (is_projection_capable_path(((GatherPath *) path)->subpath) && + !has_parallel_hazard((Node *) target->exprs, false)) + ((GatherPath *) path)->subpath->pathtarget = target; + } + return path; }