docs: Clarify that subquery ORDER BY is ignored by order-sensitive aggregates#37537
Conversation
…gregates PostgreSQL honors an ORDER BY in a subquery that feeds an order-sensitive aggregate (array_agg, string_agg, ...) as an executor artifact, so a query like `array_agg(i) FROM (SELECT ... ORDER BY ...)` comes out sorted. This behavior is not guaranteed by the SQL standard, and Materialize does not reproduce it: a nested query is an unordered relation, and its ORDER BY is dropped unless combined with a row-limiting clause. Aggregation order must be requested with the in-aggregate `agg(value ORDER BY ...)` form. Document the divergence at the drop site in plan_nested_query, and replace the shared boilerplate across array_agg, string_agg, list_agg, jsonb_agg, and jsonb_object_agg. It previously claimed both "as if sorted in ascending order" and "not guaranteed any order"; it now states that the aggregation order is unspecified without an in-aggregate ORDER BY. Also remove reference examples that documented the implementation-defined ascending order as if it were guaranteed. CLU-160 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
225a1ef to
cac3d5e
Compare
|
|
||
| This function always executes on the data from `value` as if it were sorted in ascending order before the function call. Any specified ordering is | ||
| ignored. If you need to perform aggregation in a specific order, you must specify `ORDER BY` within the aggregate function call itself. Otherwise incoming rows are not guaranteed any order. | ||
| Any `ORDER BY` applied to the input rows, for example in a feeding subquery, is |
There was a problem hiding this comment.
Q: Is the first sentence more
Any ORDER BY applied before the aggregate function is evaluated (such as in an input subquery) is ignored.
(or does this broaden it too much?)
There was a problem hiding this comment.
Went with your phrasing, thanks. Broadening it is correct: it's not just subqueries, any ORDER BY on an unordered input (a CTE, a view, etc.) gets dropped the same way. Pushed in 2a64898.
| This function always executes on the data from `value` as if it were sorted in ascending order before the function call. Any specified ordering is | ||
| ignored. If you need to perform aggregation in a specific order, you must specify `ORDER BY` within the aggregate function call itself. Otherwise incoming rows are not guaranteed any order. | ||
| Any `ORDER BY` applied to the input rows, for example in a feeding subquery, is | ||
| ignored. The order in which values are aggregated is otherwise unspecified. To |
There was a problem hiding this comment.
Maybe just combine the two last sentences to (?)
Unless ORDER BY is included in the aggregate function call itself, the order in which the values are aggregated is unspecified.
There was a problem hiding this comment.
Oh ... we can also single source this in a
doc/user/content/headless/blah.md
and just include it via `{{% include-headless "/headless/blah" %}}
There was a problem hiding this comment.
Good idea, done both. Merged the two sentences per your suggestion, and pulled the whole paragraph into doc/user/content/headless/aggregate-input-order-ignored.md, included from all five function docs instead of duplicating it five times. Pushed in 2a64898.
Address review feedback on MaterializeInc#37537: five function docs carried an identical paragraph explaining that ORDER BY on the aggregate's input is ignored. Fold it into a headless partial and tighten the wording per review suggestion.
|
Thanks for the review! |
PostgreSQL honors an
ORDER BYin a subquery that feeds an order-sensitive aggregate (array_agg,string_agg, ...) as an executor artifact, soarray_agg(i) FROM (SELECT ... ORDER BY ...)comes out sorted.This is not guaranteed by the SQL standard, and Materialize does not reproduce it: a nested query is an unordered relation whose
ORDER BYis dropped unless combined with a row-limiting clause.Aggregation order must be requested with the in-aggregate
agg(value ORDER BY ...)form.This documents the divergence at the drop site in
plan_nested_query, and replaces the shared boilerplate acrossarray_agg,string_agg,list_agg,jsonb_agg, andjsonb_object_agg.It previously claimed both "as if sorted in ascending order" and "not guaranteed any order"; it now states the aggregation order is unspecified without an in-aggregate
ORDER BY.Reference examples that documented the implementation-defined ascending order as if guaranteed are removed.
No behavior change.
CLU-160