Skip to content

Commit 7a8e9f2

Browse files
committed
Comment on why planagg.c punts "MIN(x ORDER BY y)".
1 parent 4a87f30 commit 7a8e9f2

File tree

1 file changed

+16
-2
lines changed

1 file changed

+16
-2
lines changed

src/backend/optimizer/plan/planagg.c

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -314,15 +314,29 @@ find_minmax_aggs_walker(Node *node, List **context)
314314
ListCell *l;
315315

316316
Assert(aggref->agglevelsup == 0);
317-
if (list_length(aggref->args) != 1 || aggref->aggorder != NIL)
317+
if (list_length(aggref->args) != 1)
318318
return true; /* it couldn't be MIN/MAX */
319+
/*
320+
* ORDER BY is usually irrelevant for MIN/MAX, but it can change the
321+
* outcome if the aggsortop's operator class recognizes non-identical
322+
* values as equal. For example, 4.0 and 4.00 are equal according to
323+
* numeric_ops, yet distinguishable. If MIN() receives more than one
324+
* value equal to 4.0 and no value less than 4.0, it is unspecified
325+
* which of those equal values MIN() returns. An ORDER BY expression
326+
* that differs for each of those equal values of the argument
327+
* expression makes the result predictable once again. This is a
328+
* niche requirement, and we do not implement it with subquery paths.
329+
*/
330+
if (aggref->aggorder != NIL)
331+
return true;
319332
/* note: we do not care if DISTINCT is mentioned ... */
320-
curTarget = (TargetEntry *) linitial(aggref->args);
321333

322334
aggsortop = fetch_agg_sort_op(aggref->aggfnoid);
323335
if (!OidIsValid(aggsortop))
324336
return true; /* not a MIN/MAX aggregate */
325337

338+
curTarget = (TargetEntry *) linitial(aggref->args);
339+
326340
if (contain_mutable_functions((Node *) curTarget->expr))
327341
return true; /* not potentially indexable */
328342

0 commit comments

Comments
 (0)