From d7407c41a72e7db954da6ce3e0a8f55a4c1747bc Mon Sep 17 00:00:00 2001 From: Richard Guo Date: Thu, 16 Apr 2020 15:53:33 +0000 Subject: [PATCH] Fix incremental sort crash. --- src/backend/optimizer/plan/planner.c | 31 +++++++++++++++++++++++++++++++ src/backend/optimizer/prep/prepunion.c | 6 +++--- src/include/optimizer/planner.h | 4 ++++ 3 files changed, 38 insertions(+), 3 deletions(-) diff --git a/src/backend/optimizer/plan/planner.c b/src/backend/optimizer/plan/planner.c index b31c524..fa57133 100644 --- a/src/backend/optimizer/plan/planner.c +++ b/src/backend/optimizer/plan/planner.c @@ -5422,6 +5422,37 @@ mark_partial_aggref(Aggref *agg, AggSplit aggsplit) } } +/* select_pathkeys_for_union_unique + * Choose the pathkeys in right order for Sort and Unique. + * + * Since 'Sort and Unique' is to unique-ify the result of a UNION by sorting + * on all columns, we adjust the sort order to match with result ordering + * requirements. Thus we can avoid the final Sort node. + */ +List * +select_pathkeys_for_union_unique(PlannerInfo *root, + List *groupList, + List *tlist) +{ + List *processed_tlist; + List *sort_pathkeys; + List *pathkeys; + + processed_tlist = + postprocess_setop_tlist(copyObject(tlist), root->parse->targetList); + + sort_pathkeys = make_pathkeys_for_sortclauses(root, + root->parse->sortClause, + processed_tlist); + + pathkeys = make_pathkeys_for_sortclauses(root, groupList, tlist); + + pathkeys = list_concat(sort_pathkeys, + list_difference_ptr(pathkeys, sort_pathkeys)); + + return pathkeys; +} + /* * postprocess_setop_tlist * Fix up targetlist returned by plan_set_operations(). diff --git a/src/backend/optimizer/prep/prepunion.c b/src/backend/optimizer/prep/prepunion.c index 951aed8..c31cee8 100644 --- a/src/backend/optimizer/prep/prepunion.c +++ b/src/backend/optimizer/prep/prepunion.c @@ -977,9 +977,9 @@ make_union_unique(SetOperationStmt *op, Path *path, List *tlist, create_sort_path(root, result_rel, path, - make_pathkeys_for_sortclauses(root, - groupList, - tlist), + select_pathkeys_for_union_unique(root, + groupList, + tlist), -1.0); path = (Path *) create_upper_unique_path(root, result_rel, diff --git a/src/include/optimizer/planner.h b/src/include/optimizer/planner.h index beb7dbb..159698a 100644 --- a/src/include/optimizer/planner.h +++ b/src/include/optimizer/planner.h @@ -53,6 +53,10 @@ extern bool limit_needed(Query *parse); extern void mark_partial_aggref(Aggref *agg, AggSplit aggsplit); +extern List *select_pathkeys_for_union_unique(PlannerInfo *root, + List *groupList, + List *tlist); + extern Path *get_cheapest_fractional_path(RelOptInfo *rel, double tuple_fraction); -- 2.7.4