diff --git a/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/evaluator/predicate/operator/logical/NotEvaluator.java b/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/predicate/logical/NotEvaluator.java similarity index 98% rename from x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/evaluator/predicate/operator/logical/NotEvaluator.java rename to x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/predicate/logical/NotEvaluator.java index 255c162df3495..48a18bca990e7 100644 --- a/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/evaluator/predicate/operator/logical/NotEvaluator.java +++ b/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/predicate/logical/NotEvaluator.java @@ -2,7 +2,7 @@ // or more contributor license agreements. Licensed under the Elastic License // 2.0; you may not use this file except in compliance with the Elastic License // 2.0. -package org.elasticsearch.xpack.esql.evaluator.predicate.operator.logical; +package org.elasticsearch.xpack.esql.expression.predicate.logical; import java.lang.IllegalArgumentException; import java.lang.Override; diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/evaluator/EvalMapper.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/evaluator/EvalMapper.java index f33f047bf727a..d054a8cecb072 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/evaluator/EvalMapper.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/evaluator/EvalMapper.java @@ -17,7 +17,6 @@ import org.elasticsearch.compute.data.Page; import org.elasticsearch.compute.data.Vector; import org.elasticsearch.compute.operator.DriverContext; -import org.elasticsearch.compute.operator.EvalOperator; import org.elasticsearch.compute.operator.EvalOperator.ExpressionEvaluator; import org.elasticsearch.core.Releasables; import org.elasticsearch.xpack.esql.core.QlIllegalArgumentException; @@ -28,9 +27,6 @@ import org.elasticsearch.xpack.esql.evaluator.mapper.EvaluatorMapper; import org.elasticsearch.xpack.esql.evaluator.mapper.ExpressionMapper; import org.elasticsearch.xpack.esql.expression.predicate.logical.BinaryLogic; -import org.elasticsearch.xpack.esql.expression.predicate.logical.Not; -import org.elasticsearch.xpack.esql.expression.predicate.nulls.IsNotNull; -import org.elasticsearch.xpack.esql.expression.predicate.nulls.IsNull; import org.elasticsearch.xpack.esql.expression.predicate.operator.comparison.InsensitiveEqualsMapper; import org.elasticsearch.xpack.esql.planner.EsPhysicalOperationProviders.ShardContext; import org.elasticsearch.xpack.esql.planner.Layout; @@ -42,11 +38,8 @@ public final class EvalMapper { private static final List> MAPPERS = List.of( new InsensitiveEqualsMapper(), new BooleanLogic(), - new Nots(), new Attributes(), - new Literals(), - new IsNotNulls(), - new IsNulls() + new Literals() ); private EvalMapper() {} @@ -174,18 +167,6 @@ public void close() { } } - static class Nots extends ExpressionMapper { - @Override - public ExpressionEvaluator.Factory map(FoldContext foldCtx, Not not, Layout layout, List shardContexts) { - var expEval = toEvaluator(foldCtx, not.field(), layout, shardContexts); - return dvrCtx -> new org.elasticsearch.xpack.esql.evaluator.predicate.operator.logical.NotEvaluator( - not.source(), - expEval.get(dvrCtx), - dvrCtx - ); - } - } - static class Attributes extends ExpressionMapper { @Override public ExpressionEvaluator.Factory map(FoldContext foldCtx, Attribute attr, Layout layout, List shardContexts) { @@ -276,101 +257,4 @@ private static Block block(Literal lit, BlockFactory blockFactory, int positions return BlockUtils.constantBlock(blockFactory, value, positions); } } - - static class IsNulls extends ExpressionMapper { - - @Override - public ExpressionEvaluator.Factory map(FoldContext foldCtx, IsNull isNull, Layout layout, List shardContexts) { - var field = toEvaluator(foldCtx, isNull.field(), layout, shardContexts); - return new IsNullEvaluatorFactory(field); - } - - record IsNullEvaluatorFactory(EvalOperator.ExpressionEvaluator.Factory field) implements ExpressionEvaluator.Factory { - @Override - public ExpressionEvaluator get(DriverContext context) { - return new IsNullEvaluator(context, field.get(context)); - } - - @Override - public String toString() { - return "IsNullEvaluator[field=" + field + ']'; - } - } - - record IsNullEvaluator(DriverContext driverContext, EvalOperator.ExpressionEvaluator field) implements ExpressionEvaluator { - @Override - public Block eval(Page page) { - try (Block fieldBlock = field.eval(page)) { - if (fieldBlock.asVector() != null) { - return driverContext.blockFactory().newConstantBooleanBlockWith(false, page.getPositionCount()); - } - try (var builder = driverContext.blockFactory().newBooleanVectorFixedBuilder(page.getPositionCount())) { - for (int p = 0; p < page.getPositionCount(); p++) { - builder.appendBoolean(p, fieldBlock.isNull(p)); - } - return builder.build().asBlock(); - } - } - } - - @Override - public void close() { - Releasables.closeExpectNoException(field); - } - - @Override - public String toString() { - return "IsNullEvaluator[field=" + field + ']'; - } - } - } - - static class IsNotNulls extends ExpressionMapper { - - @Override - public ExpressionEvaluator.Factory map(FoldContext foldCtx, IsNotNull isNotNull, Layout layout, List shardContexts) { - return new IsNotNullEvaluatorFactory(toEvaluator(foldCtx, isNotNull.field(), layout, shardContexts)); - } - - record IsNotNullEvaluatorFactory(EvalOperator.ExpressionEvaluator.Factory field) implements ExpressionEvaluator.Factory { - @Override - public ExpressionEvaluator get(DriverContext context) { - return new IsNotNullEvaluator(context, field.get(context)); - } - - @Override - public String toString() { - return "IsNotNullEvaluator[field=" + field + ']'; - } - } - - record IsNotNullEvaluator(DriverContext driverContext, EvalOperator.ExpressionEvaluator field) - implements - EvalOperator.ExpressionEvaluator { - @Override - public Block eval(Page page) { - try (Block fieldBlock = field.eval(page)) { - if (fieldBlock.asVector() != null) { - return driverContext.blockFactory().newConstantBooleanBlockWith(true, page.getPositionCount()); - } - try (var builder = driverContext.blockFactory().newBooleanVectorFixedBuilder(page.getPositionCount())) { - for (int p = 0; p < page.getPositionCount(); p++) { - builder.appendBoolean(p, fieldBlock.isNull(p) == false); - } - return builder.build().asBlock(); - } - } - } - - @Override - public void close() { - Releasables.closeExpectNoException(field); - } - - @Override - public String toString() { - return "IsNotNullEvaluator[field=" + field + ']'; - } - } - } } diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/evaluator/predicate/operator/logical/Not.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/evaluator/predicate/operator/logical/Not.java deleted file mode 100644 index f46c499315cb6..0000000000000 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/evaluator/predicate/operator/logical/Not.java +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -package org.elasticsearch.xpack.esql.evaluator.predicate.operator.logical; - -import org.elasticsearch.compute.ann.Evaluator; - -public class Not { - @Evaluator - static boolean process(boolean v) { - return false == v; - } -} diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/predicate/logical/Not.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/predicate/logical/Not.java index 9f14e291fe7a7..8ac9ad35effb5 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/predicate/logical/Not.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/predicate/logical/Not.java @@ -8,6 +8,9 @@ import org.elasticsearch.common.io.stream.NamedWriteableRegistry; import org.elasticsearch.common.io.stream.StreamInput; +import org.elasticsearch.compute.ann.Evaluator; +import org.elasticsearch.compute.operator.DriverContext; +import org.elasticsearch.compute.operator.EvalOperator; import org.elasticsearch.xpack.esql.capabilities.TranslationAware; import org.elasticsearch.xpack.esql.core.QlIllegalArgumentException; import org.elasticsearch.xpack.esql.core.expression.Expression; @@ -18,6 +21,7 @@ import org.elasticsearch.xpack.esql.core.tree.NodeInfo; import org.elasticsearch.xpack.esql.core.tree.Source; import org.elasticsearch.xpack.esql.core.type.DataType; +import org.elasticsearch.xpack.esql.evaluator.mapper.EvaluatorMapper; import org.elasticsearch.xpack.esql.optimizer.rules.physical.local.LucenePushdownPredicates; import org.elasticsearch.xpack.esql.planner.TranslatorHandler; @@ -26,7 +30,7 @@ import static org.elasticsearch.xpack.esql.core.expression.TypeResolutions.ParamOrdinal.DEFAULT; import static org.elasticsearch.xpack.esql.core.expression.TypeResolutions.isBoolean; -public class Not extends UnaryScalarFunction implements Negatable, TranslationAware { +public class Not extends UnaryScalarFunction implements EvaluatorMapper, Negatable, TranslationAware { public static final NamedWriteableRegistry.Entry ENTRY = new NamedWriteableRegistry.Entry(Expression.class, "Not", Not::new); public Not(Source source, Expression child) { @@ -77,6 +81,16 @@ private static Boolean apply(Object input) { return ((Boolean) input).booleanValue() ? Boolean.FALSE : Boolean.TRUE; } + @Override + public EvalOperator.ExpressionEvaluator.Factory toEvaluator(ToEvaluator toEvaluator) { + return new NotEvaluatorFactory(source(), toEvaluator.apply(field())); + } + + @Evaluator + static boolean process(boolean v) { + return false == v; + } + @Override protected Expression canonicalize() { if (field() instanceof Negatable) { @@ -108,4 +122,18 @@ public Translatable translatable(LucenePushdownPredicates pushdownPredicates) { public Query asQuery(LucenePushdownPredicates pushdownPredicates, TranslatorHandler handler) { return handler.asQuery(pushdownPredicates, field()).negate(source()); } + + record NotEvaluatorFactory(Source source, EvalOperator.ExpressionEvaluator.Factory field) + implements + EvalOperator.ExpressionEvaluator.Factory { + @Override + public EvalOperator.ExpressionEvaluator get(DriverContext context) { + return new NotEvaluator(source, field.get(context), context); + } + + @Override + public String toString() { + return "NotEvaluator[field=" + field + ']'; + } + } } diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/predicate/nulls/IsNotNull.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/predicate/nulls/IsNotNull.java index 5c7492b0a64dd..ce5a660000d09 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/predicate/nulls/IsNotNull.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/predicate/nulls/IsNotNull.java @@ -8,6 +8,11 @@ import org.elasticsearch.common.io.stream.NamedWriteableRegistry; import org.elasticsearch.common.io.stream.StreamInput; +import org.elasticsearch.compute.data.Block; +import org.elasticsearch.compute.data.Page; +import org.elasticsearch.compute.operator.DriverContext; +import org.elasticsearch.compute.operator.EvalOperator; +import org.elasticsearch.core.Releasables; import org.elasticsearch.xpack.esql.capabilities.TranslationAware; import org.elasticsearch.xpack.esql.core.expression.Expression; import org.elasticsearch.xpack.esql.core.expression.FoldContext; @@ -19,12 +24,13 @@ import org.elasticsearch.xpack.esql.core.tree.NodeInfo; import org.elasticsearch.xpack.esql.core.tree.Source; import org.elasticsearch.xpack.esql.core.type.DataType; +import org.elasticsearch.xpack.esql.evaluator.mapper.EvaluatorMapper; import org.elasticsearch.xpack.esql.optimizer.rules.physical.local.LucenePushdownPredicates; import org.elasticsearch.xpack.esql.planner.TranslatorHandler; import java.io.IOException; -public class IsNotNull extends UnaryScalarFunction implements Negatable, TranslationAware { +public class IsNotNull extends UnaryScalarFunction implements EvaluatorMapper, Negatable, TranslationAware { public static final NamedWriteableRegistry.Entry ENTRY = new NamedWriteableRegistry.Entry( Expression.class, "IsNotNull", @@ -59,6 +65,12 @@ public Object fold(FoldContext ctx) { return DataType.isNull(field().dataType()) == false && field().fold(ctx) != null; } + @Override + public EvalOperator.ExpressionEvaluator.Factory toEvaluator(ToEvaluator toEvaluator) { + return new IsNotNullEvaluatorFactory(toEvaluator.apply(field())); + + } + @Override public Nullability nullable() { return Nullability.FALSE; @@ -83,4 +95,45 @@ public Translatable translatable(LucenePushdownPredicates pushdownPredicates) { public Query asQuery(LucenePushdownPredicates pushdownPredicates, TranslatorHandler handler) { return new ExistsQuery(source(), handler.nameOf(field())); } + + record IsNotNullEvaluatorFactory(EvalOperator.ExpressionEvaluator.Factory field) implements EvalOperator.ExpressionEvaluator.Factory { + @Override + public EvalOperator.ExpressionEvaluator get(DriverContext context) { + return new IsNotNullEvaluator(context, field.get(context)); + } + + @Override + public String toString() { + return "IsNotNullEvaluator[field=" + field + ']'; + } + } + + record IsNotNullEvaluator(DriverContext driverContext, EvalOperator.ExpressionEvaluator field) + implements + EvalOperator.ExpressionEvaluator { + @Override + public Block eval(Page page) { + try (Block fieldBlock = field.eval(page)) { + if (fieldBlock.asVector() != null) { + return driverContext.blockFactory().newConstantBooleanBlockWith(true, page.getPositionCount()); + } + try (var builder = driverContext.blockFactory().newBooleanVectorFixedBuilder(page.getPositionCount())) { + for (int p = 0; p < page.getPositionCount(); p++) { + builder.appendBoolean(p, fieldBlock.isNull(p) == false); + } + return builder.build().asBlock(); + } + } + } + + @Override + public void close() { + Releasables.closeExpectNoException(field); + } + + @Override + public String toString() { + return "IsNotNullEvaluator[field=" + field + ']'; + } + } } diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/predicate/nulls/IsNull.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/predicate/nulls/IsNull.java index b41b20b673b86..fd17a7014e40b 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/predicate/nulls/IsNull.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/predicate/nulls/IsNull.java @@ -8,6 +8,11 @@ import org.elasticsearch.common.io.stream.NamedWriteableRegistry; import org.elasticsearch.common.io.stream.StreamInput; +import org.elasticsearch.compute.data.Block; +import org.elasticsearch.compute.data.Page; +import org.elasticsearch.compute.operator.DriverContext; +import org.elasticsearch.compute.operator.EvalOperator; +import org.elasticsearch.core.Releasables; import org.elasticsearch.xpack.esql.capabilities.TranslationAware; import org.elasticsearch.xpack.esql.core.expression.Expression; import org.elasticsearch.xpack.esql.core.expression.FoldContext; @@ -20,12 +25,13 @@ import org.elasticsearch.xpack.esql.core.tree.NodeInfo; import org.elasticsearch.xpack.esql.core.tree.Source; import org.elasticsearch.xpack.esql.core.type.DataType; +import org.elasticsearch.xpack.esql.evaluator.mapper.EvaluatorMapper; import org.elasticsearch.xpack.esql.optimizer.rules.physical.local.LucenePushdownPredicates; import org.elasticsearch.xpack.esql.planner.TranslatorHandler; import java.io.IOException; -public class IsNull extends UnaryScalarFunction implements Negatable, TranslationAware { +public class IsNull extends UnaryScalarFunction implements EvaluatorMapper, Negatable, TranslationAware { public static final NamedWriteableRegistry.Entry ENTRY = new NamedWriteableRegistry.Entry(Expression.class, "IsNull", IsNull::new); public IsNull(Source source, Expression field) { @@ -56,6 +62,11 @@ public Object fold(FoldContext ctx) { return DataType.isNull(field().dataType()) || field().fold(ctx) == null; } + @Override + public EvalOperator.ExpressionEvaluator.Factory toEvaluator(ToEvaluator toEvaluator) { + return new IsNullEvaluatorFactory(toEvaluator.apply(field())); + } + @Override public Nullability nullable() { return Nullability.FALSE; @@ -86,4 +97,45 @@ protected static Translatable isTranslatable(Expression field, LucenePushdownPre public Query asQuery(LucenePushdownPredicates pushdownPredicates, TranslatorHandler handler) { return new NotQuery(source(), new ExistsQuery(source(), handler.nameOf(field()))); } + + record IsNullEvaluatorFactory(EvalOperator.ExpressionEvaluator.Factory field) implements EvalOperator.ExpressionEvaluator.Factory { + @Override + public EvalOperator.ExpressionEvaluator get(DriverContext context) { + return new IsNullEvaluator(context, field.get(context)); + } + + @Override + public String toString() { + return "IsNullEvaluator[field=" + field + ']'; + } + } + + record IsNullEvaluator(DriverContext driverContext, EvalOperator.ExpressionEvaluator field) + implements + EvalOperator.ExpressionEvaluator { + @Override + public Block eval(Page page) { + try (Block fieldBlock = field.eval(page)) { + if (fieldBlock.asVector() != null) { + return driverContext.blockFactory().newConstantBooleanBlockWith(false, page.getPositionCount()); + } + try (var builder = driverContext.blockFactory().newBooleanVectorFixedBuilder(page.getPositionCount())) { + for (int p = 0; p < page.getPositionCount(); p++) { + builder.appendBoolean(p, fieldBlock.isNull(p)); + } + return builder.build().asBlock(); + } + } + } + + @Override + public void close() { + Releasables.closeExpectNoException(field); + } + + @Override + public String toString() { + return "IsNullEvaluator[field=" + field + ']'; + } + } }