diff options
Diffstat (limited to 'src/backend/optimizer/plan/createplan.c')
-rw-r--r-- | src/backend/optimizer/plan/createplan.c | 32 |
1 files changed, 27 insertions, 5 deletions
diff --git a/src/backend/optimizer/plan/createplan.c b/src/backend/optimizer/plan/createplan.c index 452cf0dfae4..af18c5b4307 100644 --- a/src/backend/optimizer/plan/createplan.c +++ b/src/backend/optimizer/plan/createplan.c @@ -78,7 +78,8 @@ static Plan *create_gating_plan(PlannerInfo *root, Path *path, Plan *plan, List *gating_quals); static Plan *create_join_plan(PlannerInfo *root, JoinPath *best_path); static Plan *create_append_plan(PlannerInfo *root, AppendPath *best_path); -static Plan *create_merge_append_plan(PlannerInfo *root, MergeAppendPath *best_path); +static Plan *create_merge_append_plan(PlannerInfo *root, MergeAppendPath *best_path, + int flags); static Result *create_result_plan(PlannerInfo *root, ResultPath *best_path); static Material *create_material_plan(PlannerInfo *root, MaterialPath *best_path, int flags); @@ -372,7 +373,8 @@ create_plan_recurse(PlannerInfo *root, Path *best_path, int flags) break; case T_MergeAppend: plan = create_merge_append_plan(root, - (MergeAppendPath *) best_path); + (MergeAppendPath *) best_path, + flags); break; case T_Result: if (IsA(best_path, ProjectionPath)) @@ -1025,11 +1027,14 @@ create_append_plan(PlannerInfo *root, AppendPath *best_path) * Returns a Plan node. */ static Plan * -create_merge_append_plan(PlannerInfo *root, MergeAppendPath *best_path) +create_merge_append_plan(PlannerInfo *root, MergeAppendPath *best_path, + int flags) { MergeAppend *node = makeNode(MergeAppend); Plan *plan = &node->plan; List *tlist = build_path_tlist(root, &best_path->path); + int orig_tlist_length = list_length(tlist); + bool tlist_was_changed; List *pathkeys = best_path->path.pathkeys; List *subplans = NIL; ListCell *subpaths; @@ -1046,7 +1051,12 @@ create_merge_append_plan(PlannerInfo *root, MergeAppendPath *best_path) plan->lefttree = NULL; plan->righttree = NULL; - /* Compute sort column info, and adjust MergeAppend's tlist as needed */ + /* + * Compute sort column info, and adjust MergeAppend's tlist as needed. + * Because we pass adjust_tlist_in_place = true, we may ignore the + * function result; it must be the same plan node. However, we then need + * to detect whether any tlist entries were added. + */ (void) prepare_sort_from_pathkeys(plan, pathkeys, best_path->path.parent->relids, NULL, @@ -1056,6 +1066,7 @@ create_merge_append_plan(PlannerInfo *root, MergeAppendPath *best_path) &node->sortOperators, &node->collations, &node->nullsFirst); + tlist_was_changed = (orig_tlist_length != list_length(plan->targetlist)); /* * Now prepare the child plans. We must apply prepare_sort_from_pathkeys @@ -1120,7 +1131,18 @@ create_merge_append_plan(PlannerInfo *root, MergeAppendPath *best_path) node->mergeplans = subplans; - return (Plan *) node; + /* + * If prepare_sort_from_pathkeys added sort columns, but we were told to + * produce either the exact tlist or a narrow tlist, we should get rid of + * the sort columns again. We must inject a projection node to do so. + */ + if (tlist_was_changed && (flags & (CP_EXACT_TLIST | CP_SMALL_TLIST))) + { + tlist = list_truncate(list_copy(plan->targetlist), orig_tlist_length); + return inject_projection_plan(plan, tlist); + } + else + return plan; } /* |