mirror of
https://github.com/postgres/postgres.git
synced 2025-07-05 07:21:24 +03:00
Push target list evaluation through Gather Merge.
We already do this for Gather, but it got overlooked for Gather Merge. Amit Kapila, with review and minor revisions by Rushabh Lathia and by me. Discussion: http://postgr.es/m/CAA4eK1KUC5Uyu7qaifxrjpHxbSeoQh3yzwN3bThnJsmJcZ-qtA@mail.gmail.com
This commit is contained in:
@ -5060,7 +5060,8 @@ create_ordered_paths(PlannerInfo *root,
|
||||
path = (Path *)
|
||||
create_gather_merge_path(root, ordered_rel,
|
||||
path,
|
||||
target, root->sort_pathkeys, NULL,
|
||||
path->pathtarget,
|
||||
root->sort_pathkeys, NULL,
|
||||
&total_groups);
|
||||
|
||||
/* Add projection step if needed */
|
||||
|
@ -2368,9 +2368,9 @@ create_projection_path(PlannerInfo *root,
|
||||
* knows that the given path isn't referenced elsewhere and so can be modified
|
||||
* in-place.
|
||||
*
|
||||
* If the input path is a GatherPath, we try to push the new target down to
|
||||
* its input as well; this is a yet more invasive modification of the input
|
||||
* path, which create_projection_path() can't do.
|
||||
* If the input path is a GatherPath or GatherMergePath, we try to push the
|
||||
* new target down to its input as well; this is a yet more invasive
|
||||
* modification of the input path, which create_projection_path() can't do.
|
||||
*
|
||||
* Note that we mustn't change the source path's parent link; so when it is
|
||||
* add_path'd to "rel" things will be a bit inconsistent. So far that has
|
||||
@ -2407,31 +2407,44 @@ apply_projection_to_path(PlannerInfo *root,
|
||||
(target->cost.per_tuple - oldcost.per_tuple) * path->rows;
|
||||
|
||||
/*
|
||||
* If the path happens to be a Gather path, we'd like to arrange for the
|
||||
* subpath to return the required target list so that workers can help
|
||||
* project. But if there is something that is not parallel-safe in the
|
||||
* target expressions, then we can't.
|
||||
* If the path happens to be a Gather or GatherMerge path, we'd like to
|
||||
* arrange for the subpath to return the required target list so that
|
||||
* workers can help project. But if there is something that is not
|
||||
* parallel-safe in the target expressions, then we can't.
|
||||
*/
|
||||
if (IsA(path, GatherPath) &&
|
||||
if ((IsA(path, GatherPath) || IsA(path, GatherMergePath)) &&
|
||||
is_parallel_safe(root, (Node *) target->exprs))
|
||||
{
|
||||
GatherPath *gpath = (GatherPath *) path;
|
||||
|
||||
/*
|
||||
* We always use create_projection_path here, even if the subpath is
|
||||
* projection-capable, so as to avoid modifying the subpath in place.
|
||||
* It seems unlikely at present that there could be any other
|
||||
* references to the subpath, but better safe than sorry.
|
||||
*
|
||||
* Note that we don't change the GatherPath's cost estimates; it might
|
||||
* Note that we don't change the parallel path's cost estimates; it might
|
||||
* be appropriate to do so, to reflect the fact that the bulk of the
|
||||
* target evaluation will happen in workers.
|
||||
*/
|
||||
gpath->subpath = (Path *)
|
||||
create_projection_path(root,
|
||||
gpath->subpath->parent,
|
||||
gpath->subpath,
|
||||
target);
|
||||
if (IsA(path, GatherPath))
|
||||
{
|
||||
GatherPath *gpath = (GatherPath *) path;
|
||||
|
||||
gpath->subpath = (Path *)
|
||||
create_projection_path(root,
|
||||
gpath->subpath->parent,
|
||||
gpath->subpath,
|
||||
target);
|
||||
}
|
||||
else
|
||||
{
|
||||
GatherMergePath *gmpath = (GatherMergePath *) path;
|
||||
|
||||
gmpath->subpath = (Path *)
|
||||
create_projection_path(root,
|
||||
gmpath->subpath->parent,
|
||||
gmpath->subpath,
|
||||
target);
|
||||
}
|
||||
}
|
||||
else if (path->parallel_safe &&
|
||||
!is_parallel_safe(root, (Node *) target->exprs))
|
||||
|
Reference in New Issue
Block a user