diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/AbstractScalarFunctionTestCase.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/AbstractScalarFunctionTestCase.java index 9d4687568ca9d..958b706a3f260 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/AbstractScalarFunctionTestCase.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/AbstractScalarFunctionTestCase.java @@ -104,7 +104,6 @@ public final void testEvaluate() { assertTypeResolutionFailure(expression); return; } - assumeTrue("Expected type must be representable to build an evaluator", DataType.isRepresentable(testCase.expectedType())); logger.info( "Test Values: " + testCase.getData().stream().map(TestCaseSupplier.TypedData::toString).collect(Collectors.joining(",")) ); @@ -209,7 +208,6 @@ private void testEvaluateBlock(BlockFactory inputBlockFactory, DriverContext con return; } assumeTrue("Can't build evaluator", testCase.canBuildEvaluator()); - assumeTrue("Expected type must be representable to build an evaluator", DataType.isRepresentable(testCase.expectedType())); int positions = between(1, 1024); List data = testCase.getData(); Page onePositionPage = row(testCase.getDataValues()); @@ -275,7 +273,6 @@ public final void testEvaluateInManyThreads() throws ExecutionException, Interru return; } assumeTrue("Can't build evaluator", testCase.canBuildEvaluator()); - assumeTrue("Expected type must be representable to build an evaluator", DataType.isRepresentable(testCase.expectedType())); int count = 10_000; int threads = 5; var evalSupplier = evaluator(expression); @@ -338,14 +335,13 @@ public final void testFactoryToString() { assertThat(factory.toString(), testCase.evaluatorToString()); } - public final void testFold() { + public void testFold() { Expression expression = buildLiteralExpression(testCase); if (testCase.getExpectedTypeError() != null) { assertTypeResolutionFailure(expression); return; } assertFalse("expected resolved", expression.typeResolved().unresolved()); - assumeTrue("Can't build evaluator", testCase.canBuildEvaluator()); Expression nullOptimized = new FoldNull().rule(expression); assertThat(nullOptimized.dataType(), equalTo(testCase.expectedType())); assertTrue(nullOptimized.foldable()); diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/TestCaseSupplier.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/TestCaseSupplier.java index 2004fa3a1cdb0..575c80a52ae9b 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/TestCaseSupplier.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/TestCaseSupplier.java @@ -278,6 +278,9 @@ private static TestCaseSupplier testCaseSupplier( for (String warning : warnings.apply(lhsTyped, rhsTyped)) { testCase = testCase.withWarning(warning); } + if (DataType.isRepresentable(expectedType) == false) { + testCase = testCase.withoutEvaluator(); + } return testCase; }); } @@ -1438,7 +1441,7 @@ public static TestCase typeError(List data, String expectedTypeError) foldingExceptionClass, foldingExceptionMessage, extra, - data.stream().allMatch(d -> d.forceLiteral || DataType.isRepresentable(d.type)) + true ); } diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/grouping/CategorizeTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/grouping/CategorizeTests.java index d29ac635e4bb7..68bafd2af9960 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/grouping/CategorizeTests.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/grouping/CategorizeTests.java @@ -58,4 +58,9 @@ public static Iterable parameters() { protected Expression build(Source source, List args) { return new Categorize(source, args.get(0)); } + + @Override + public void testFold() { + // Cannot be folded + } } diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToDatePeriodTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToDatePeriodTests.java index c7e18e453df0c..ef71f404eda02 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToDatePeriodTests.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToDatePeriodTests.java @@ -50,7 +50,7 @@ public static Iterable parameters() { matchesPattern("LiteralsEvaluator.*"), DATE_PERIOD, equalTo(field) - ); + ).withoutEvaluator(); })); for (EsqlDataTypeConverter.INTERVALS interval : DATE_PERIODS) { @@ -67,7 +67,7 @@ public static Iterable parameters() { matchesPattern("LiteralsEvaluator.*"), DATE_PERIOD, equalTo(result) - ); + ).withoutEvaluator(); })); } } diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToDoubleTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToDoubleTests.java index b68306d6cac80..6fcd61bf15d0d 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToDoubleTests.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToDoubleTests.java @@ -126,7 +126,7 @@ public static Iterable parameters() { ); TestCaseSupplier.unary( suppliers, - evaluatorName.apply("Integer"), + evaluatorName.apply("Int"), List.of(new TestCaseSupplier.TypedDataSupplier("counter", () -> randomInt(1000), DataType.COUNTER_INTEGER)), DataType.DOUBLE, l -> ((Integer) l).doubleValue(), diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToLongTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToLongTests.java index c7101ab730aba..49daeba43f13d 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToLongTests.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToLongTests.java @@ -230,7 +230,7 @@ public static Iterable parameters() { ); TestCaseSupplier.unary( suppliers, - evaluatorName.apply("Integer"), + evaluatorName.apply("Int"), List.of(new TestCaseSupplier.TypedDataSupplier("counter", ESTestCase::randomInt, DataType.COUNTER_INTEGER)), DataType.LONG, l -> ((Integer) l).longValue(), diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToTimeDurationTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToTimeDurationTests.java index b3f666ec6c5c2..00555f5c668cd 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToTimeDurationTests.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/convert/ToTimeDurationTests.java @@ -50,7 +50,7 @@ public static Iterable parameters() { matchesPattern("LiteralsEvaluator.*"), TIME_DURATION, equalTo(field) - ); + ).withoutEvaluator(); })); for (EsqlDataTypeConverter.INTERVALS interval : TIME_DURATIONS) { @@ -66,7 +66,7 @@ public static Iterable parameters() { matchesPattern("LiteralsEvaluator.*"), TIME_DURATION, equalTo(result) - ); + ).withoutEvaluator(); })); } } diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/date/DateTruncTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/date/DateTruncTests.java index 2403900064645..93970f64df845 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/date/DateTruncTests.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/function/scalar/date/DateTruncTests.java @@ -136,10 +136,10 @@ private static TestCaseSupplier randomSecond() { + pad(randomIntBetween(0, 59)); return new TestCaseSupplier.TestCase( List.of( - new TestCaseSupplier.TypedData(Duration.ofSeconds(1), DataType.TIME_DURATION, "interval"), + new TestCaseSupplier.TypedData(Duration.ofSeconds(1), DataType.TIME_DURATION, "interval").forceLiteral(), new TestCaseSupplier.TypedData(toMillis(dateFragment + ".38Z"), DataType.DATETIME, "date") ), - "DateTruncDatetimeEvaluator[date=Attribute[channel=1], interval=Attribute[channel=0]]", + Matchers.startsWith("DateTruncDatetimeEvaluator[fieldVal=Attribute[channel=0], rounding=Rounding["), DataType.DATETIME, equalTo(toMillis(dateFragment + ".00Z")) ); diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/predicate/operator/arithmetic/NegTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/predicate/operator/arithmetic/NegTests.java index 3b789f3022cfc..5bfaccfbd9347 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/predicate/operator/arithmetic/NegTests.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/predicate/operator/arithmetic/NegTests.java @@ -10,7 +10,6 @@ import com.carrotsearch.randomizedtesting.annotations.Name; import com.carrotsearch.randomizedtesting.annotations.ParametersFactory; -import org.elasticsearch.compute.data.Block; import org.elasticsearch.xpack.esql.VerificationException; import org.elasticsearch.xpack.esql.core.expression.Expression; import org.elasticsearch.xpack.esql.core.expression.Literal; @@ -18,6 +17,7 @@ import org.elasticsearch.xpack.esql.core.type.DataType; import org.elasticsearch.xpack.esql.expression.function.AbstractScalarFunctionTestCase; import org.elasticsearch.xpack.esql.expression.function.TestCaseSupplier; +import org.hamcrest.Matchers; import java.time.Duration; import java.time.Period; @@ -25,7 +25,6 @@ import java.util.List; import java.util.function.Supplier; -import static org.elasticsearch.compute.data.BlockUtils.toJavaObject; import static org.elasticsearch.xpack.esql.EsqlTestUtils.randomLiteral; import static org.hamcrest.Matchers.equalTo; @@ -97,19 +96,19 @@ public static Iterable parameters() { suppliers.addAll(List.of(new TestCaseSupplier("Duration", List.of(DataType.TIME_DURATION), () -> { Duration arg = (Duration) randomLiteral(DataType.TIME_DURATION).value(); return new TestCaseSupplier.TestCase( - List.of(new TestCaseSupplier.TypedData(arg, DataType.TIME_DURATION, "arg")), - "No evaluator since this expression is only folded", + List.of(new TestCaseSupplier.TypedData(arg, DataType.TIME_DURATION, "arg").forceLiteral()), + Matchers.startsWith("LiteralsEvaluator[lit="), DataType.TIME_DURATION, equalTo(arg.negated()) - ); + ).withoutEvaluator(); }), new TestCaseSupplier("Period", List.of(DataType.DATE_PERIOD), () -> { Period arg = (Period) randomLiteral(DataType.DATE_PERIOD).value(); return new TestCaseSupplier.TestCase( - List.of(new TestCaseSupplier.TypedData(arg, DataType.DATE_PERIOD, "arg")), - "No evaluator since this expression is only folded", + List.of(new TestCaseSupplier.TypedData(arg, DataType.DATE_PERIOD, "arg").forceLiteral()), + Matchers.startsWith("LiteralsEvaluator[lit="), DataType.DATE_PERIOD, equalTo(arg.negated()) - ); + ).withoutEvaluator(); }))); return parameterSuppliersFromTypedDataWithDefaultChecks(false, suppliers, (v, p) -> "numeric, date_period or time_duration"); } @@ -126,25 +125,25 @@ public void testEdgeCases() { if (testCaseType == DataType.DATE_PERIOD) { Period maxPeriod = Period.of(Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE); Period negatedMaxPeriod = Period.of(-Integer.MAX_VALUE, -Integer.MAX_VALUE, -Integer.MAX_VALUE); - assertEquals(negatedMaxPeriod, process(maxPeriod)); + assertEquals(negatedMaxPeriod, foldTemporalAmount(maxPeriod)); Period minPeriod = Period.of(Integer.MIN_VALUE, Integer.MIN_VALUE, Integer.MIN_VALUE); VerificationException e = expectThrows( VerificationException.class, "Expected exception when negating minimal date period.", - () -> process(minPeriod) + () -> foldTemporalAmount(minPeriod) ); assertEquals(e.getMessage(), "arithmetic exception in expression []: [integer overflow]"); } else if (testCaseType == DataType.TIME_DURATION) { Duration maxDuration = Duration.ofSeconds(Long.MAX_VALUE, 0); Duration negatedMaxDuration = Duration.ofSeconds(-Long.MAX_VALUE, 0); - assertEquals(negatedMaxDuration, process(maxDuration)); + assertEquals(negatedMaxDuration, foldTemporalAmount(maxDuration)); Duration minDuration = Duration.ofSeconds(Long.MIN_VALUE, 0); VerificationException e = expectThrows( VerificationException.class, "Expected exception when negating minimal time duration.", - () -> process(minDuration) + () -> foldTemporalAmount(minDuration) ); assertEquals( e.getMessage(), @@ -153,16 +152,9 @@ public void testEdgeCases() { } } - private Object process(Object val) { - if (testCase.canBuildEvaluator()) { - Neg neg = new Neg(Source.EMPTY, field("val", typeOf(val))); - try (Block block = evaluator(neg).get(driverContext()).eval(row(List.of(val)))) { - return toJavaObject(block, 0); - } - } else { // just fold if type is not representable - Neg neg = new Neg(Source.EMPTY, new Literal(Source.EMPTY, val, typeOf(val))); - return neg.fold(); - } + private Object foldTemporalAmount(Object val) { + Neg neg = new Neg(Source.EMPTY, new Literal(Source.EMPTY, val, typeOf(val))); + return neg.fold(); } private static DataType typeOf(Object val) { diff --git a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/predicate/operator/arithmetic/SubTests.java b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/predicate/operator/arithmetic/SubTests.java index bce5dea30f849..3a7d4e6482d72 100644 --- a/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/predicate/operator/arithmetic/SubTests.java +++ b/x-pack/plugin/esql/src/test/java/org/elasticsearch/xpack/esql/expression/predicate/operator/arithmetic/SubTests.java @@ -169,12 +169,12 @@ public static Iterable parameters() { return new TestCaseSupplier.TestCase( List.of( new TestCaseSupplier.TypedData(lhs, DataType.DATE_PERIOD, "lhs"), - new TestCaseSupplier.TypedData(rhs, DataType.DATE_PERIOD, "rhs") + new TestCaseSupplier.TypedData(rhs, DataType.DATE_PERIOD, "rhs").forceLiteral() ), "Only folding possible, so there's no evaluator", DataType.DATE_PERIOD, equalTo(lhs.minus(rhs)) - ); + ).withoutEvaluator(); })); suppliers.add(new TestCaseSupplier("Datetime - Duration", List.of(DataType.DATETIME, DataType.TIME_DURATION), () -> { long lhs = (Long) randomLiteral(DataType.DATETIME).value(); @@ -196,12 +196,12 @@ public static Iterable parameters() { return new TestCaseSupplier.TestCase( List.of( new TestCaseSupplier.TypedData(lhs, DataType.TIME_DURATION, "lhs"), - new TestCaseSupplier.TypedData(rhs, DataType.TIME_DURATION, "rhs") + new TestCaseSupplier.TypedData(rhs, DataType.TIME_DURATION, "rhs").forceLiteral() ), "Only folding possible, so there's no evaluator", DataType.TIME_DURATION, equalTo(lhs.minus(rhs)) - ); + ).withoutEvaluator(); })); // exact math arithmetic exceptions @@ -250,7 +250,12 @@ public static Iterable parameters() { return original.getData().get(nullPosition == 0 ? 1 : 0).type(); } return original.expectedType(); - }, (nullPosition, nullData, original) -> nullData.isForceLiteral() ? equalTo("LiteralsEvaluator[lit=null]") : original); + }, (nullPosition, nullData, original) -> { + if (DataType.isTemporalAmount(nullData.type())) { + return equalTo("LiteralsEvaluator[lit=null]"); + } + return original; + }); suppliers.add(new TestCaseSupplier("MV", List.of(DataType.INTEGER, DataType.INTEGER), () -> { // Ensure we don't have an overflow