]> granicus.if.org Git - postgresql/commitdiff
Department of second thoughts: the rule that ORDER BY and DISTINCT are
authorTom Lane <tgl@sss.pgh.pa.us>
Fri, 28 Mar 2008 02:00:11 +0000 (02:00 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Fri, 28 Mar 2008 02:00:11 +0000 (02:00 +0000)
useless for an ungrouped-aggregate query holds regardless of whether
optimize_minmax_aggregates succeeds.  So we might as well apply the
optimization in any case.

I'll leave 8.3 as it was, since this version is a tad more invasive
than my earlier patch.

src/backend/optimizer/plan/planner.c

index 6d6978dcf5bf616fc359284bdd51cd5cb74abe91..27d7b3dea26e6c80d03eb536360618b186b19fc7 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/optimizer/plan/planner.c,v 1.228 2008/03/27 19:06:14 tgl Exp $
+ *       $PostgreSQL: pgsql/src/backend/optimizer/plan/planner.c,v 1.229 2008/03/28 02:00:11 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -835,6 +835,21 @@ grouping_planner(PlannerInfo *root, double tuple_fraction)
 
                MemSet(&agg_counts, 0, sizeof(AggClauseCounts));
 
+               /*
+                * If the query involves ungrouped aggregation, then it can produce
+                * at most one row, so we can ignore any ORDER BY or DISTINCT
+                * request.  This isn't all that exciting as an optimization, but it
+                * prevents a corner case when optimize_minmax_aggregates succeeds:
+                * if ORDER BY or DISTINCT were present we'd try, and fail, to match
+                * the EquivalenceClasses we're about to build with the modified
+                * targetlist entries it will create.
+                */
+               if (parse->hasAggs && parse->groupClause == NIL)
+               {
+                       parse->sortClause = NIL;
+                       parse->distinctClause = NIL;
+               }
+
                /* Preprocess targetlist */
                tlist = preprocess_targetlist(root, tlist);
 
@@ -950,17 +965,6 @@ grouping_planner(PlannerInfo *root, double tuple_fraction)
                         * right tlist, and it has no sort order.
                         */
                        current_pathkeys = NIL;
-                       /*
-                        * In fact, since we don't optimize grouped aggregates, it
-                        * needs no sort order --- there must be exactly one output row,
-                        * and so any ORDER BY or DISTINCT attached to the query is
-                        * useless and can be dropped.  Aside from saving useless cycles,
-                        * this protects us against problems with matching the hacked-up
-                        * tlist entries to sort clauses.
-                        */
-                       Assert(!parse->groupClause);
-                       parse->sortClause = NULL;
-                       parse->distinctClause = NULL;
                }
                else
                {