Repository navigation
feat(core-spec): allow NULLS FIRST and NULLS LAST in window ORDER BY - #577
Conversation
The window syntax had no way to say where NULLs go, and engines differ on it, so an author could not write an ordering that gives the same rows everywhere. Add the clause to the grammar with its meaning and an example. The placement when the clause is omitted is left out of this change (apache#498). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
christianeu-db
left a comment
There was a problem hiding this comment.
Thanks for putting this together and identifying the spec gap!
If we have a default, I'd lean towards either the nulls_are_small or nulls_are_large approaches - those make nulls feel more like a regular value. I don't have a strong preference between either one of those schemes.
| function_name(args) OVER ( | ||
| [PARTITION BY partition_expr, ...] | ||
| [ORDER BY order_expr [ASC|DESC], ...] | ||
| [ORDER BY order_expr [ASC|DESC] [NULLS FIRST|NULLS LAST], ...] |
There was a problem hiding this comment.
nit: [NULLS FIRST | NULLS LAST] reads fine, but a grouped form like [NULLS { FIRST | LAST }] makes the pairing explicit
It also might be worth spelling the ordering out as separate productions, roughly how the SQL standard models a sort specification:
<sort specification> ::= <sort key> [ <ordering spec> ] [ <null ordering> ]
<ordering spec> ::= ASC | DESC
<null ordering> ::= NULLS FIRST | NULLS LAST
That makes the three choices (key, direction, null placement) visibly independent and gives us one place to describe each
There was a problem hiding this comment.
Done in 3f05af1: the clause is now [NULLS {FIRST|LAST}], and the three parts of an ORDER BY item are listed separately below the block. I kept the SQL-style syntax block rather than productions, since the rest of the document writes syntax that way (the only production is FieldExpr). Happy to switch to productions if you prefer.
| ) | ||
| ``` | ||
|
|
||
| `NULLS FIRST` sorts NULL values of that `order_expr` before non-NULL values, and `NULLS LAST` after them, with either `ASC` or `DESC`: |
There was a problem hiding this comment.
The text is a bit ambiguous. It reads as though NULL placement composes with the sort direction - a plausible interpretation is that NULLS FIRST means NULLs come first for ASC and last for DESC. But the two are independent: null placement is fixed regardless of direction.
Maybe something closer to:
NULLS { FIRST | LAST } specifies whether NULL values are ordered before or after non-NULL values, regardless of the sort direction. For example, RANK() OVER (ORDER BY revenue DESC NULLS LAST) ranks non-NULL revenues from high to low and places NULL revenues last.
There was a problem hiding this comment.
Agreed, done in 3f05af1: NULL placement is now stated per order_expr and independent of the sort direction, and the example uses your wording.
…ection Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Thanks for the review. The default stays out of this PR; the question is open on dev@: https://lists.apache.org/thread/z2jr7q4pllsk5nkzv7d18ro8844n5tgy. Your preference for nulls_are_small or nulls_are_large would help there, so it is on the list before a vote. |
jbonofre
left a comment
There was a problem hiding this comment.
Thanks @ekut! The clause is the right fix for the portability gap in #498, and it's purely additive, so existing expressions stay valid.
See also my comments on the dev@ mailing list. A couple of notes for us:
- #498 suggests a compliance-suite case with NULLs in the ordering column. That could go in a separate PR.
- The existing examples using ORDER BY order_date have no clause. They may need revisit once the default is decided on dev@
LGTM!
apache/ossie#577 added the clause to the spec's window syntax, so a model that writes it must load. It passes through as written; without it NULLs still sort last in both directions. WITHIN GROUP keeps rejecting it, as the spec's syntax there has none. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Adds
NULLS FIRST | NULLS LASTto the windowORDER BYgrammar, as @christianeu-db suggested in #498. Engines disagree on where NULLs sort by default (table in #498), so without the clause an author cannot write an ordering that gives the same rows everywhere. Parsers of window expressions need to accept the clause.Where NULLs sort when the clause is omitted is left out of this change and raised on the dev list: https://lists.apache.org/thread/z2jr7q4pllsk5nkzv7d18ro8844n5tgy