Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 26 additions & 32 deletions src/backend/cdb/cdbpath.c
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,9 @@ cdbpath_cost_motion(PlannerInfo *root, CdbMotionPath *motionpath)
* If no motion is needed, the caller's subpath is returned unchanged.
* Else if require_existing_order is true, NULL is returned if the
* motion would not preserve an ordering at least as strong as the
* specified ordering; also NULL is returned if pathkeys is NIL
* specified ordering or if path has parameterization relids,
* which generally may indicate we can't add motion;
* also NULL is returned if pathkeys is NIL
* meaning the caller is just checking and doesn't want to add motion.
* Else a CdbMotionPath is returned having either the specified pathkeys
* (if given and the motion uses Merge Receive), or the pathkeys
Expand Down Expand Up @@ -136,14 +138,25 @@ cdbpath_create_motion_path(PlannerInfo *root,
return subpath;
}

/* singleQE-->entry? Don't move. Slice's QE will run on entry db. */
if (CdbPathLocus_IsSingleQE(subpath->locus))
/* No motion needed if subpath can run anywhere giving same output. */
if (CdbPathLocus_IsGeneral(subpath->locus))
{
/*
* If the subpath requires parameters, we cannot generate Motion atop of it.
* general-->(entry|singleqe), no motion is needed, can run
* directly on any of the common segments
*/
if (!bms_is_empty(PATH_REQ_OUTER(subpath)))
return NULL;
subpath->locus.numsegments = numsegments;
return subpath;
}

/* Fail if caller refuses motion. */
if (require_existing_order &&
!pathkeys)
return NULL;

/* singleQE-->entry? Don't move. Slice's QE will run on entry db. */
if (CdbPathLocus_IsSingleQE(subpath->locus))
{
/*
* Create CdbMotionPath node to indicate that the slice must be
* dispatched to a singleton gang running on the entry db. We
Expand Down Expand Up @@ -175,11 +188,6 @@ cdbpath_create_motion_path(PlannerInfo *root,

if (CdbPathLocus_IsSegmentGeneral(subpath->locus))
{
/*
* If the subpath requires parameters, we cannot generate Motion atop of it.
*/
if (!bms_is_empty(PATH_REQ_OUTER(subpath)))
return NULL;
/*
* Data is only available on segments, to distingush it with
* CdbLocusType_General, adding a motion to indicated this
Expand Down Expand Up @@ -210,22 +218,6 @@ cdbpath_create_motion_path(PlannerInfo *root,
return (Path *) pathnode;
}

/* No motion needed if subpath can run anywhere giving same output. */
if (CdbPathLocus_IsGeneral(subpath->locus))
{
/*
* general-->(entry|singleqe), no motion is needed, can run
* directly on any of the common segments
*/
subpath->locus.numsegments = numsegments;
return subpath;
}

/* Fail if caller refuses motion. */
if (require_existing_order &&
!pathkeys)
return NULL;

/* replicated-->singleton would give redundant copies of the rows. */
if (CdbPathLocus_IsReplicated(subpath->locus))
goto invalid_motion_request;
Expand Down Expand Up @@ -314,11 +306,6 @@ cdbpath_create_motion_path(PlannerInfo *root,
/* Does subpath produce same multiset of rows on every qExec of its gang? */
else if (CdbPathLocus_IsReplicated(subpath->locus))
{
/*
* If the subpath requires parameters, we cannot generate Motion atop of it.
*/
if (!bms_is_empty(PATH_REQ_OUTER(subpath)))
return NULL;
/* No-op if replicated-->replicated. */
if (CdbPathLocus_IsReplicated(locus))
{
Expand Down Expand Up @@ -401,6 +388,7 @@ cdbpath_create_motion_path(PlannerInfo *root,
/* Unexpected source or destination locus. */
invalid_motion_request:
Assert(0);
elog(WARNING, "cdbpath_create_motion_path can't apply valid motion");
return NULL;
} /* cdbpath_create_motion_path */

Expand Down Expand Up @@ -900,6 +888,11 @@ cdbpath_distkeys_from_preds(PlannerInfo *root,
* mergeclause_list is a List of RestrictInfo. Its members are
* the equijoin predicates between the outer and inner rel.
* It comes from select_mergejoin_clauses() in joinpath.c.
*
* Besides ordering logic,
* outer_require_existing_order and inner_require_existing_order
* indicates path has parameterization relids, so we can decide
* can we add a motion node atop of processing node
*/

typedef struct
Expand Down Expand Up @@ -2098,6 +2091,7 @@ turn_volatile_seggen_to_singleqe(PlannerInfo *root, Path *path, Node *node)
CdbPathLocus_MakeSingleQE(&singleQE,
CdbPathLocus_NumSegments(path->locus));
mpath = cdbpath_create_motion_path(root, path, NIL, false, singleQE);
Insist(mpath);
ppath = create_projection_path_with_quals(root, mpath->parent, mpath, NIL);
ppath->force = true;
return (Path *) ppath;
Expand Down
1 change: 1 addition & 0 deletions src/backend/optimizer/path/allpaths.c
Original file line number Diff line number Diff line change
Expand Up @@ -437,6 +437,7 @@ bring_to_singleQE(PlannerInfo *root, RelOptInfo *rel, List *outer_quals)
NIL, // DESTROY pathkeys
false,
target_locus);
Insist(path);

path = (Path *) create_material_path(root, rel, path);

Expand Down
1 change: 1 addition & 0 deletions src/backend/optimizer/util/pathnode.c
Original file line number Diff line number Diff line change
Expand Up @@ -1581,6 +1581,7 @@ set_append_path_locus(PlannerInfo *root, Path *pathnode, RelOptInfo *rel,
else
{
subpath = cdbpath_create_motion_path(root, subpath, subpath->pathkeys, false, targetlocus);
Insist(subpath);
}

pathnode->sameslice_relids = bms_union(pathnode->sameslice_relids, subpath->sameslice_relids);
Expand Down