From 66a4d12f54bb371a494a2e62e233455e96732687 Mon Sep 17 00:00:00 2001 From: Mark Tozzi Date: Thu, 15 Aug 2024 08:50:31 -0400 Subject: [PATCH] [ESQL] date nanos binary comparisons (#111908) resolves #109992 Nothing fancy here. Nanosecond dates are still longs, and we can just compare them as longs. Please note that, as mentioned in the linked issue, this only supports comparing date nanos to other date nanos, and not comparing to millisecond dates. With the cast functions added in #111850, users can explicitly cast to millisecond dates (or longs) to compare nanos to other things. --- .../predicate/operator/comparison/Equals.java | 1 + .../operator/comparison/GreaterThan.java | 1 + .../operator/comparison/GreaterThanOrEqual.java | 1 + .../predicate/operator/comparison/LessThan.java | 1 + .../operator/comparison/LessThanOrEqual.java | 1 + .../operator/comparison/NotEquals.java | 1 + .../operator/comparison/EqualsTests.java | 17 +++++++++++++++-- .../comparison/GreaterThanOrEqualTests.java | 17 +++++++++++++++-- .../operator/comparison/GreaterThanTests.java | 17 +++++++++++++++-- .../comparison/LessThanOrEqualTests.java | 17 +++++++++++++++-- .../operator/comparison/LessThanTests.java | 17 +++++++++++++++-- .../operator/comparison/NotEqualsTests.java | 17 +++++++++++++++-- 12 files changed, 96 insertions(+), 12 deletions(-) diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/predicate/operator/comparison/Equals.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/predicate/operator/comparison/Equals.java index 32e15deb07b4e..614d9aa3ec920 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/predicate/operator/comparison/Equals.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/predicate/operator/comparison/Equals.java @@ -35,6 +35,7 @@ public class Equals extends EsqlBinaryComparison implements Negatable parameters() { ) ); // Datetime - // TODO: I'm surprised this passes. Shouldn't there be a cast from DateTime to Long? suppliers.addAll( TestCaseSupplier.forBinaryNotCasting( "EqualsLongsEvaluator", @@ -131,6 +130,20 @@ public static Iterable parameters() { ) ); + suppliers.addAll( + TestCaseSupplier.forBinaryNotCasting( + "EqualsLongsEvaluator", + "lhs", + "rhs", + Object::equals, + DataType.BOOLEAN, + TestCaseSupplier.dateNanosCases(), + TestCaseSupplier.dateNanosCases(), + List.of(), + false + ) + ); + suppliers.addAll( TestCaseSupplier.stringCases( Object::equals, @@ -204,7 +217,7 @@ public static Iterable parameters() { } private static String typeErrorString = - "boolean, cartesian_point, cartesian_shape, datetime, double, geo_point, geo_shape, integer, ip, keyword, long, text, " + "boolean, cartesian_point, cartesian_shape, datetime, date_nanos, double, geo_point, geo_shape, integer, ip, keyword, long, text, " + "unsigned_long or version"; @Override diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/predicate/operator/comparison/GreaterThanOrEqualTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/predicate/operator/comparison/GreaterThanOrEqualTests.java index 5435a7f629d43..a4d1bf69796e0 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/predicate/operator/comparison/GreaterThanOrEqualTests.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/predicate/operator/comparison/GreaterThanOrEqualTests.java @@ -106,7 +106,6 @@ public static Iterable parameters() { ) ); // Datetime - // TODO: I'm surprised this passes. Shouldn't there be a cast from DateTime to Long? suppliers.addAll( TestCaseSupplier.forBinaryNotCasting( "GreaterThanOrEqualLongsEvaluator", @@ -121,6 +120,20 @@ public static Iterable parameters() { ) ); + suppliers.addAll( + TestCaseSupplier.forBinaryNotCasting( + "GreaterThanOrEqualLongsEvaluator", + "lhs", + "rhs", + (l, r) -> ((Number) l).longValue() >= ((Number) r).longValue(), + DataType.BOOLEAN, + TestCaseSupplier.dateNanosCases(), + TestCaseSupplier.dateNanosCases(), + List.of(), + false + ) + ); + suppliers.addAll( TestCaseSupplier.stringCases( (l, r) -> ((BytesRef) l).compareTo((BytesRef) r) >= 0, @@ -137,7 +150,7 @@ public static Iterable parameters() { o, v, t, - (l, p) -> "datetime, double, integer, ip, keyword, long, text, unsigned_long or version" + (l, p) -> "date_nanos, datetime, double, integer, ip, keyword, long, text, unsigned_long or version" ) ) ); diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/predicate/operator/comparison/GreaterThanTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/predicate/operator/comparison/GreaterThanTests.java index 75c22c34623b9..d3fede5c2e2ce 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/predicate/operator/comparison/GreaterThanTests.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/predicate/operator/comparison/GreaterThanTests.java @@ -106,7 +106,6 @@ public static Iterable parameters() { ) ); // Datetime - // TODO: I'm surprised this passes. Shouldn't there be a cast from DateTime to Long? suppliers.addAll( TestCaseSupplier.forBinaryNotCasting( "GreaterThanLongsEvaluator", @@ -121,6 +120,20 @@ public static Iterable parameters() { ) ); + suppliers.addAll( + TestCaseSupplier.forBinaryNotCasting( + "GreaterThanLongsEvaluator", + "lhs", + "rhs", + (l, r) -> ((Number) l).longValue() > ((Number) r).longValue(), + DataType.BOOLEAN, + TestCaseSupplier.dateNanosCases(), + TestCaseSupplier.dateNanosCases(), + List.of(), + false + ) + ); + suppliers.addAll( TestCaseSupplier.stringCases( (l, r) -> ((BytesRef) l).compareTo((BytesRef) r) > 0, @@ -137,7 +150,7 @@ public static Iterable parameters() { o, v, t, - (l, p) -> "datetime, double, integer, ip, keyword, long, text, unsigned_long or version" + (l, p) -> "date_nanos, datetime, double, integer, ip, keyword, long, text, unsigned_long or version" ) ) ); diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/predicate/operator/comparison/LessThanOrEqualTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/predicate/operator/comparison/LessThanOrEqualTests.java index b65c6a753e14d..3b8270c1576fd 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/predicate/operator/comparison/LessThanOrEqualTests.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/predicate/operator/comparison/LessThanOrEqualTests.java @@ -106,7 +106,6 @@ public static Iterable parameters() { ) ); // Datetime - // TODO: I'm surprised this passes. Shouldn't there be a cast from DateTime to Long? suppliers.addAll( TestCaseSupplier.forBinaryNotCasting( "LessThanOrEqualLongsEvaluator", @@ -121,6 +120,20 @@ public static Iterable parameters() { ) ); + suppliers.addAll( + TestCaseSupplier.forBinaryNotCasting( + "LessThanOrEqualLongsEvaluator", + "lhs", + "rhs", + (l, r) -> ((Number) l).longValue() <= ((Number) r).longValue(), + DataType.BOOLEAN, + TestCaseSupplier.dateNanosCases(), + TestCaseSupplier.dateNanosCases(), + List.of(), + false + ) + ); + suppliers.addAll( TestCaseSupplier.stringCases( (l, r) -> ((BytesRef) l).compareTo((BytesRef) r) <= 0, @@ -137,7 +150,7 @@ public static Iterable parameters() { o, v, t, - (l, p) -> "datetime, double, integer, ip, keyword, long, text, unsigned_long or version" + (l, p) -> "date_nanos, datetime, double, integer, ip, keyword, long, text, unsigned_long or version" ) ) ); diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/predicate/operator/comparison/LessThanTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/predicate/operator/comparison/LessThanTests.java index 88c79d506e0c7..647988fe35326 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/predicate/operator/comparison/LessThanTests.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/predicate/operator/comparison/LessThanTests.java @@ -106,7 +106,20 @@ public static Iterable parameters() { ) ); // Datetime - // TODO: I'm surprised this passes. Shouldn't there be a cast from DateTime to Long? + suppliers.addAll( + TestCaseSupplier.forBinaryNotCasting( + "LessThanLongsEvaluator", + "lhs", + "rhs", + (l, r) -> ((Number) l).longValue() < ((Number) r).longValue(), + DataType.BOOLEAN, + TestCaseSupplier.dateCases(), + TestCaseSupplier.dateCases(), + List.of(), + false + ) + ); + suppliers.addAll( TestCaseSupplier.forBinaryNotCasting( "LessThanLongsEvaluator", @@ -137,7 +150,7 @@ public static Iterable parameters() { o, v, t, - (l, p) -> "datetime, double, integer, ip, keyword, long, text, unsigned_long or version" + (l, p) -> "date_nanos, datetime, double, integer, ip, keyword, long, text, unsigned_long or version" ) ) ); diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/predicate/operator/comparison/NotEqualsTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/predicate/operator/comparison/NotEqualsTests.java index 06585f7c1a49d..53676a43b16a0 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/predicate/operator/comparison/NotEqualsTests.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/predicate/operator/comparison/NotEqualsTests.java @@ -115,7 +115,6 @@ public static Iterable parameters() { ) ); // Datetime - // TODO: I'm surprised this passes. Shouldn't there be a cast from DateTime to Long? suppliers.addAll( TestCaseSupplier.forBinaryNotCasting( "NotEqualsLongsEvaluator", @@ -129,6 +128,20 @@ public static Iterable parameters() { false ) ); + // Datetime + suppliers.addAll( + TestCaseSupplier.forBinaryNotCasting( + "NotEqualsLongsEvaluator", + "lhs", + "rhs", + (l, r) -> false == l.equals(r), + DataType.BOOLEAN, + TestCaseSupplier.dateNanosCases(), + TestCaseSupplier.dateNanosCases(), + List.of(), + false + ) + ); suppliers.addAll( TestCaseSupplier.stringCases( (l, r) -> false == l.equals(r), @@ -198,7 +211,7 @@ public static Iterable parameters() { } private static String typeErrorString = - "boolean, cartesian_point, cartesian_shape, datetime, double, geo_point, geo_shape, integer, ip, keyword, long, text, " + "boolean, cartesian_point, cartesian_shape, datetime, date_nanos, double, geo_point, geo_shape, integer, ip, keyword, long, text, " + "unsigned_long or version"; @Override