*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/optimizer/plan/createplan.c,v 1.239 2008/04/13 20:51:20 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/optimizer/plan/createplan.c,v 1.240 2008/04/17 21:22:14 tgl Exp $
*
*-------------------------------------------------------------------------
*/
static Sort *make_sort(PlannerInfo *root, Plan *lefttree, int numCols,
AttrNumber *sortColIdx, Oid *sortOperators, bool *nullsFirst,
double limit_tuples);
+static Material *make_material(Plan *lefttree);
/*
* add any such expressions to the subplan's tlist.
*
* The subplan may have a "physical" tlist if it is a simple scan plan.
- * This should be left as-is if we don't need to add any expressions;
+ * If we're going to sort, this should be reduced to the regular tlist,
+ * so that we don't sort more data than we need to. For hashing, the
+ * tlist should be left as-is if we don't need to add any expressions;
* but if we do have to add expressions, then a projection step will be
- * needed at runtime anyway, and so we may as well remove unneeded items.
+ * needed at runtime anyway, so we may as well remove unneeded items.
* Therefore newtlist starts from build_relation_tlist() not just a
* copy of the subplan's tlist; and we don't install it into the subplan
- * unless stuff has to be added.
+ * unless we are sorting or stuff has to be added.
*
* To find the correct list of values to unique-ify, we look in the
* information saved for IN expressions. If this code is ever used in
}
}
- if (newitems)
+ if (newitems || best_path->umethod == UNIQUE_PATH_SORT)
{
/*
* If the top plan node can't do projections, we need to add a Result
sortColIdx, sortOperators, nullsFirst, -1.0);
}
-Material *
+static Material *
make_material(Plan *lefttree)
{
Material *node = makeNode(Material);
*
*
* IDENTIFICATION
- * $PostgreSQL: pgsql/src/backend/optimizer/plan/planner.c,v 1.231 2008/04/01 00:48:33 tgl Exp $
+ * $PostgreSQL: pgsql/src/backend/optimizer/plan/planner.c,v 1.232 2008/04/17 21:22:14 tgl Exp $
*
*-------------------------------------------------------------------------
*/
* Normal case --- create a plan according to query_planner's
* results.
*/
+ bool need_sort_for_grouping = false;
+
result_plan = create_plan(root, best_path);
current_pathkeys = best_path->pathkeys;
+ /* Detect if we'll need an explicit sort for grouping */
+ if (parse->groupClause && !use_hashed_grouping &&
+ !pathkeys_contained_in(group_pathkeys, current_pathkeys))
+ {
+ need_sort_for_grouping = true;
+ /*
+ * Always override query_planner's tlist, so that we don't
+ * sort useless data from a "physical" tlist.
+ */
+ need_tlist_eval = true;
+ }
+
/*
* create_plan() returns a plan with just a "flat" tlist of
* required Vars. Usually we need to insert the sub_tlist as the
if (parse->groupClause)
{
- if (!pathkeys_contained_in(group_pathkeys,
- current_pathkeys))
+ if (need_sort_for_grouping)
{
result_plan = (Plan *)
make_sort_from_groupcols(root,
* Add an explicit sort if we couldn't make the path come out
* the way the GROUP node needs it.
*/
- if (!pathkeys_contained_in(group_pathkeys, current_pathkeys))
+ if (need_sort_for_grouping)
{
result_plan = (Plan *)
make_sort_from_groupcols(root,
* Portions Copyright (c) 1996-2008, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California
*
- * $PostgreSQL: pgsql/src/include/optimizer/planmain.h,v 1.106 2008/01/01 19:45:58 momjian Exp $
+ * $PostgreSQL: pgsql/src/include/optimizer/planmain.h,v 1.107 2008/04/17 21:22:14 tgl Exp $
*
*-------------------------------------------------------------------------
*/
int numGroupCols, AttrNumber *grpColIdx, Oid *grpOperators,
double numGroups,
Plan *lefttree);
-extern Material *make_material(Plan *lefttree);
extern Plan *materialize_finished_plan(Plan *subplan);
extern Unique *make_unique(Plan *lefttree, List *distinctList);
extern Limit *make_limit(Plan *lefttree, Node *limitOffset, Node *limitCount,