From 178aec5cddf09bfd9bb13a3e8b733d8c5adf6d96 Mon Sep 17 00:00:00 2001 From: William Bernbaum Date: Wed, 26 Aug 2026 08:16:06 -0700 Subject: [PATCH v1 04/16] Push a deduplication below the joins for DISTINCT DISTINCT tells the planner the same thing GROUP BY does: the query cannot tell duplicate rows apart, so let it serve as the clause eager aggregation groups on. DISTINCT ON does not qualify, since it keeps a particular row from each group. --- src/backend/optimizer/plan/initsplan.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/src/backend/optimizer/plan/initsplan.c b/src/backend/optimizer/plan/initsplan.c index 85fc5651cb1..f21946813c7 100644 --- a/src/backend/optimizer/plan/initsplan.c +++ b/src/backend/optimizer/plan/initsplan.c @@ -701,13 +701,17 @@ setup_eager_aggregation(PlannerInfo *root) return; /* - * Don't apply eager aggregation if there are no available GROUP BY - * clauses. + * Identify the clauses that determine which rows the query can tell + * apart. DISTINCT serves the same purpose as GROUP BY here. DISTINCT ON + * does not, since it keeps a particular row from each group. */ - if (!root->processed_groupClause) - return; + if (root->processed_groupClause) + root->eager_group_clause = root->processed_groupClause; + else if (root->parse->distinctClause && !root->parse->hasDistinctOn) + root->eager_group_clause = root->processed_distinctClause; - root->eager_group_clause = root->processed_groupClause; + if (root->eager_group_clause == NIL) + return; /* * For now we don't try to support grouping sets. @@ -757,10 +761,10 @@ setup_eager_aggregation(PlannerInfo *root) create_agg_clause_infos(root); /* - * If there are no suitable aggregate expressions, we cannot apply eager - * aggregation. + * If the query has aggregates, at least one must be suitable. With no + * aggregates, what gets pushed down is a plain deduplication. */ - if (root->agg_clause_list == NIL) + if (root->parse->hasAggs && root->agg_clause_list == NIL) return; /*