-
Notifications
You must be signed in to change notification settings - Fork 25.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ESQL Support IN operator for Date nanos #119772
ESQL Support IN operator for Date nanos #119772
Conversation
Hi @not-napoleon, I've created a changelog YAML for you. |
Conflicts: x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/predicate/operator/comparison/In.java
Pinging @elastic/es-analytical-engine (Team:Analytics) |
…os-in-operator' into esql-date-nanos-in-operator
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Small notes, except for the check to prevent mixing millis and nonos values in the IN list:
This used to work, but no longer with these checks:
FROM employees
| EVAL x = NULL
| WHERE birth_date IN (TO_DATETIME("1958-02-19T00:00:00Z"), x)
(I think we should add this test, both for DATETIME
s and DATE_NANOS
.)
I can write:
FROM date_nanos
| WHERE MV_FIRST(nanos) == TO_DATETIME("2023-10-23T12:27:28.948")
, but not:
FROM date_nanos
| WHERE MV_FIRST(nanos) IN (TO_DATETIME("2023-10-23T12:27:28.948"), TO_DATE_NANOS("2023-10-23T12:27:28.948"))
IMO we should make DATETIME
and DATE_NANOS
compatible and document the pitfalls. I expect it to be more useful for current/future dates, than dangerous with pre-epoch dates.
@@ -283,7 +321,7 @@ public EvalOperator.ExpressionEvaluator.Factory toEvaluator(ToEvaluator toEvalua | |||
if (commonType == INTEGER) { | |||
return new InIntEvaluator.Factory(source(), lhs, factories); | |||
} | |||
if (commonType == LONG || commonType == DATETIME || commonType == UNSIGNED_LONG) { | |||
if (commonType == LONG || commonType == DATETIME || commonType == DATE_NANOS || commonType == UNSIGNED_LONG) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Optional:
if (commonType == LONG || commonType == DATETIME || commonType == DATE_NANOS || commonType == UNSIGNED_LONG) { | |
if (commonType == LONG || commonType.isDate() || commonType == UNSIGNED_LONG) { |
Boolean compResult = DateUtils.compareNanosToMillis(lhs, rhs[i]) == 0; | ||
if (compResult == Boolean.TRUE) { | ||
return true; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we don't need the boxing. Comparisons.eq()
used in other methods can return null
(though not sure if at the respective call sites this can actually occur).
Boolean compResult = DateUtils.compareNanosToMillis(lhs, rhs[i]) == 0; | |
if (compResult == Boolean.TRUE) { | |
return true; | |
} | |
if (DateUtils.compareNanosToMillis(lhs, rhs[i]) == 0) { | |
return true; | |
} |
You're right. I missed the null case, and we didn't have tests for it. I fixed it and added tests.
Yes, but you could write
They are compatible, in almost every situation. Even this operator correctly handles the mixed case. The only thing we don't support right now (other than the remaining open work) is exactly having both millisecond dates and nanosecond dates in the match list for the IN. So far, we've managed to achieve that without any need for autocasting. I have a couple of concerns with applying autocasting here. The largest is that the results are not the same. Imagine a clause like This gets even worse because equals does not display this behavior (since it correctly compares millisecond dates that are out of the nanosecond range), so Bear in mind that currently, in all the released versions of Elasticsearch, it is not possible to have nanosecond in an |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Lgtm
Do we document this behaviour with pre-epoch values anywhere? |
💚 Backport successful
|
Add support for using nanosecond dates with the IN operator. This behavior should be consistent with equals, and support comparisons between milliseconds and nanoseconds the same as the binary comparison operators support it. Resolves elastic#118578 --------- Co-authored-by: elasticsearchmachine <[email protected]>
* ESQL Support IN operator for Date nanos (#119772) Add support for using nanosecond dates with the IN operator. This behavior should be consistent with equals, and support comparisons between milliseconds and nanoseconds the same as the binary comparison operators support it. Resolves #118578 --------- Co-authored-by: elasticsearchmachine <[email protected]> * remove use of future java functions --------- Co-authored-by: elasticsearchmachine <[email protected]>
Apparently I missed linking those docs. Fixed in #120124. I also made it explicit that it will return null for out of range values. |
This adds appropriate ignore annotations for the date tests I added in #119772 to not run the tests against very old versions. Should be a no-op for main, but fix some tests in 8.x BWC. Still, I'd rather keep the tests in sync, so I'm applying this to main first. It's not set for auto-backport because I'll need to add the unmutes to the backport.
This adds appropriate ignore annotations for the date tests I added in elastic#119772 to not run the tests against very old versions. Should be a no-op for main, but fix some tests in 8.x BWC. Still, I'd rather keep the tests in sync, so I'm applying this to main first. It's not set for auto-backport because I'll need to add the unmutes to the backport.
Add support for using nanosecond dates with the
IN
operator. This behavior should be consistent with equals, and support comparisons between milliseconds and nanoseconds the same as the binary comparison operators support it.Resolves #118578