Skip to content

Commit c78248c

Browse files
committed
Department of second thoughts: fix newly-added code in planner.c to make real
sure that DISTINCT ON does what it's supposed to, ie, sort by the full ORDER BY list before unique-ifying. The error seems masked in simple cases by the fact that query_planner won't return query pathkeys that only partially match the requested sort order, but I wouldn't want to bet that it couldn't be exposed in some way or other.
1 parent 2965400 commit c78248c

File tree

1 file changed

+30
-8
lines changed

1 file changed

+30
-8
lines changed

src/backend/optimizer/plan/planner.c

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/optimizer/plan/planner.c,v 1.238 2008/08/05 02:43:17 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/optimizer/plan/planner.c,v 1.239 2008/08/05 16:03:10 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -1304,11 +1304,24 @@ grouping_planner(PlannerInfo *root, double tuple_fraction)
13041304
/*
13051305
* Use a Unique node to implement DISTINCT. Add an explicit sort
13061306
* if we couldn't make the path come out the way the Unique node
1307-
* needs it. If we do have to sort, sort by the more rigorous
1308-
* of DISTINCT and ORDER BY, to avoid a second sort below.
1307+
* needs it. If we do have to sort, always sort by the more
1308+
* rigorous of DISTINCT and ORDER BY, to avoid a second sort
1309+
* below. However, for regular DISTINCT, don't sort now if we
1310+
* don't have to --- sorting afterwards will likely be cheaper,
1311+
* and also has the possibility of optimizing via LIMIT. But
1312+
* for DISTINCT ON, we *must* force the final sort now, else
1313+
* it won't have the desired behavior.
13091314
*/
1310-
if (!pathkeys_contained_in(root->distinct_pathkeys,
1311-
current_pathkeys))
1315+
List *needed_pathkeys;
1316+
1317+
if (parse->hasDistinctOn &&
1318+
list_length(root->distinct_pathkeys) <
1319+
list_length(root->sort_pathkeys))
1320+
needed_pathkeys = root->sort_pathkeys;
1321+
else
1322+
needed_pathkeys = root->distinct_pathkeys;
1323+
1324+
if (!pathkeys_contained_in(needed_pathkeys, current_pathkeys))
13121325
{
13131326
if (list_length(root->distinct_pathkeys) >=
13141327
list_length(root->sort_pathkeys))
@@ -1961,6 +1974,7 @@ choose_hashed_distinct(PlannerInfo *root,
19611974
int numDistinctCols = list_length(root->parse->distinctClause);
19621975
Size hashentrysize;
19631976
List *current_pathkeys;
1977+
List *needed_pathkeys;
19641978
Path hashed_p;
19651979
Path sorted_p;
19661980

@@ -2002,13 +2016,21 @@ choose_hashed_distinct(PlannerInfo *root,
20022016
cost_sort(&hashed_p, root, root->sort_pathkeys, hashed_p.total_cost,
20032017
dNumDistinctRows, input_plan->plan_width, limit_tuples);
20042018

2005-
/* Now for the GROUP case ... */
2019+
/*
2020+
* Now for the GROUP case. See comments in grouping_planner about the
2021+
* sorting choices here --- this code should match that code.
2022+
*/
20062023
sorted_p.startup_cost = input_plan->startup_cost;
20072024
sorted_p.total_cost = input_plan->total_cost;
20082025
current_pathkeys = input_pathkeys;
2009-
if (!pathkeys_contained_in(root->distinct_pathkeys, current_pathkeys))
2026+
if (root->parse->hasDistinctOn &&
2027+
list_length(root->distinct_pathkeys) <
2028+
list_length(root->sort_pathkeys))
2029+
needed_pathkeys = root->sort_pathkeys;
2030+
else
2031+
needed_pathkeys = root->distinct_pathkeys;
2032+
if (!pathkeys_contained_in(needed_pathkeys, current_pathkeys))
20102033
{
2011-
/* We don't want to sort twice */
20122034
if (list_length(root->distinct_pathkeys) >=
20132035
list_length(root->sort_pathkeys))
20142036
current_pathkeys = root->distinct_pathkeys;

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy