*
  *
  * IDENTIFICATION
- *   $PostgreSQL: pgsql/src/backend/optimizer/plan/createplan.c,v 1.237 2008/01/01 19:45:50 momjian Exp $
+ *   $PostgreSQL: pgsql/src/backend/optimizer/plan/createplan.c,v 1.237.2.1 2008/04/17 21:22:23 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.226.2.3 2008/04/01 00:48:44 tgl Exp $
+ *   $PostgreSQL: pgsql/src/backend/optimizer/plan/planner.c,v 1.226.2.4 2008/04/17 21:22:23 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.106.2.1 2008/04/17 21:22:23 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,