diff options
Diffstat (limited to 'src/backend/optimizer')
-rw-r--r-- | src/backend/optimizer/plan/planmain.c | 4 | ||||
-rw-r--r-- | src/backend/optimizer/plan/planner.c | 31 | ||||
-rw-r--r-- | src/backend/optimizer/prep/prepunion.c | 32 |
3 files changed, 53 insertions, 14 deletions
diff --git a/src/backend/optimizer/plan/planmain.c b/src/backend/optimizer/plan/planmain.c index 3776cf9b347..d25a5509b4c 100644 --- a/src/backend/optimizer/plan/planmain.c +++ b/src/backend/optimizer/plan/planmain.c @@ -14,7 +14,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/optimizer/plan/planmain.c,v 1.106 2008/01/11 04:02:18 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/optimizer/plan/planmain.c,v 1.107 2008/07/31 22:47:56 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -288,7 +288,7 @@ query_planner(PlannerInfo *root, List *tlist, * levels of sort --- and, therefore, certainly need to read all the * tuples --- unless ORDER BY is a subset of GROUP BY. */ - if (parse->groupClause && parse->sortClause && + if (root->group_pathkeys && root->sort_pathkeys && !pathkeys_contained_in(root->sort_pathkeys, root->group_pathkeys)) tuple_fraction = 0.0; } diff --git a/src/backend/optimizer/plan/planner.c b/src/backend/optimizer/plan/planner.c index 9248022d8b3..6ebbc5b7bc3 100644 --- a/src/backend/optimizer/plan/planner.c +++ b/src/backend/optimizer/plan/planner.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/optimizer/plan/planner.c,v 1.234 2008/07/10 02:14:03 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/optimizer/plan/planner.c,v 1.235 2008/07/31 22:47:56 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -826,6 +826,7 @@ grouping_planner(PlannerInfo *root, double tuple_fraction) /* * Calculate pathkeys that represent result ordering requirements */ + Assert(parse->distinctClause == NIL); sort_pathkeys = make_pathkeys_for_sortclauses(root, parse->sortClause, tlist, @@ -864,17 +865,29 @@ grouping_planner(PlannerInfo *root, double tuple_fraction) * Calculate pathkeys that represent grouping/ordering requirements. * Stash them in PlannerInfo so that query_planner can canonicalize * them after EquivalenceClasses have been formed. + * + * Note: for the moment, DISTINCT is always implemented via sort/uniq, + * and we set the sort_pathkeys to be the more rigorous of the + * DISTINCT and ORDER BY requirements. This should be changed + * someday, but DISTINCT ON is a bit of a problem ... */ root->group_pathkeys = make_pathkeys_for_sortclauses(root, parse->groupClause, tlist, false); - root->sort_pathkeys = - make_pathkeys_for_sortclauses(root, - parse->sortClause, - tlist, - false); + if (list_length(parse->distinctClause) > list_length(parse->sortClause)) + root->sort_pathkeys = + make_pathkeys_for_sortclauses(root, + parse->distinctClause, + tlist, + false); + else + root->sort_pathkeys = + make_pathkeys_for_sortclauses(root, + parse->sortClause, + tlist, + false); /* * Will need actual number of aggregates for estimating costs. @@ -903,9 +916,9 @@ grouping_planner(PlannerInfo *root, double tuple_fraction) * by ORDER BY --- but that might just leave us failing to exploit an * available sort order at all. Needs more thought...) */ - if (parse->groupClause) + if (root->group_pathkeys) root->query_pathkeys = root->group_pathkeys; - else if (parse->sortClause) + else if (root->sort_pathkeys) root->query_pathkeys = root->sort_pathkeys; else root->query_pathkeys = NIL; @@ -1172,7 +1185,7 @@ grouping_planner(PlannerInfo *root, double tuple_fraction) * If we were not able to make the plan come out in the right order, add * an explicit sort step. */ - if (parse->sortClause) + if (sort_pathkeys) { if (!pathkeys_contained_in(sort_pathkeys, current_pathkeys)) { diff --git a/src/backend/optimizer/prep/prepunion.c b/src/backend/optimizer/prep/prepunion.c index ed18cf5e3fe..b30cedee9fc 100644 --- a/src/backend/optimizer/prep/prepunion.c +++ b/src/backend/optimizer/prep/prepunion.c @@ -22,7 +22,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/optimizer/prep/prepunion.c,v 1.147 2008/06/19 00:46:04 alvherre Exp $ + * $PostgreSQL: pgsql/src/backend/optimizer/prep/prepunion.c,v 1.148 2008/07/31 22:47:56 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -69,6 +69,7 @@ static List *generate_setop_tlist(List *colTypes, int flag, static List *generate_append_tlist(List *colTypes, bool flag, List *input_plans, List *refnames_tlist); +static List *generate_setop_sortlist(List *targetlist); static void expand_inherited_rtentry(PlannerInfo *root, RangeTblEntry *rte, Index rti); static void make_inh_translation_lists(Relation oldrelation, @@ -319,7 +320,7 @@ generate_union_plan(SetOperationStmt *op, PlannerInfo *root, { List *sortList; - sortList = addAllTargetsToSortList(NULL, NIL, tlist, false); + sortList = generate_setop_sortlist(tlist); if (sortList) { plan = (Plan *) make_sort_from_sortclauses(root, sortList, plan); @@ -384,7 +385,7 @@ generate_nonunion_plan(SetOperationStmt *op, PlannerInfo *root, * Sort the child results, then add a SetOp plan node to generate the * correct output. */ - sortList = addAllTargetsToSortList(NULL, NIL, tlist, false); + sortList = generate_setop_sortlist(tlist); if (sortList == NIL) /* nothing to sort on? */ { @@ -675,6 +676,31 @@ generate_append_tlist(List *colTypes, bool flag, return tlist; } +/* + * generate_setop_sortlist + * Build a SortClause list enumerating all the non-resjunk tlist entries, + * using default ordering properties. + */ +static List * +generate_setop_sortlist(List *targetlist) +{ + List *sortlist = NIL; + ListCell *l; + + foreach(l, targetlist) + { + TargetEntry *tle = (TargetEntry *) lfirst(l); + + if (!tle->resjunk) + sortlist = addTargetToSortList(NULL, tle, + sortlist, targetlist, + SORTBY_DEFAULT, + SORTBY_NULLS_DEFAULT, + NIL, false); + } + return sortlist; +} + /* * find_all_inheritors - |