From 2e4094dad86bd0d2a55bf6a47ae9c75068afadc4 Mon Sep 17 00:00:00 2001
From: Tom Lane <tgl@sss.pgh.pa.us>
Date: Fri, 28 Mar 2008 02:00:11 +0000
Subject: [PATCH] Department of second thoughts: the rule that ORDER BY and
 DISTINCT are 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 | 28 ++++++++++++++++------------
 1 file changed, 16 insertions(+), 12 deletions(-)

diff --git a/src/backend/optimizer/plan/planner.c b/src/backend/optimizer/plan/planner.c
index 6d6978dcf5b..27d7b3dea26 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.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
 		{
-- 
GitLab