diff --git a/x-pack/plugin/esql/compute/ann/src/main/java/org/elasticsearch/compute/ann/Evaluator.java b/x-pack/plugin/esql/compute/ann/src/main/java/org/elasticsearch/compute/ann/Evaluator.java index ab77a8f5b1973..93da3d7abf74d 100644 --- a/x-pack/plugin/esql/compute/ann/src/main/java/org/elasticsearch/compute/ann/Evaluator.java +++ b/x-pack/plugin/esql/compute/ann/src/main/java/org/elasticsearch/compute/ann/Evaluator.java @@ -42,4 +42,11 @@ * into a warning and turn into a null value. */ Class[] warnExceptions() default {}; + + /** + * Automatically evaluate each position to null if it is null on all the + * blocks. Setting this to {@code false} requires block parameters, like + * {@code static boolean process(@Position int position, LongBlock field1, LongBlock field2)} + */ + boolean allNullsIsNull() default true; } diff --git a/x-pack/plugin/esql/compute/gen/src/main/java/org/elasticsearch/compute/gen/EvaluatorImplementer.java b/x-pack/plugin/esql/compute/gen/src/main/java/org/elasticsearch/compute/gen/EvaluatorImplementer.java index 20915c56ef206..bba578f45f5b0 100644 --- a/x-pack/plugin/esql/compute/gen/src/main/java/org/elasticsearch/compute/gen/EvaluatorImplementer.java +++ b/x-pack/plugin/esql/compute/gen/src/main/java/org/elasticsearch/compute/gen/EvaluatorImplementer.java @@ -51,13 +51,15 @@ public class EvaluatorImplementer { private final ProcessFunction processFunction; private final ClassName implementation; private final boolean processOutputsMultivalued; + private final boolean allNullsIsNull; public EvaluatorImplementer( Elements elements, javax.lang.model.util.Types types, ExecutableElement processFunction, String extraName, - List warnExceptions + List warnExceptions, + boolean allNullsIsNull ) { this.declarationType = (TypeElement) processFunction.getEnclosingElement(); this.processFunction = new ProcessFunction(types, processFunction, warnExceptions); @@ -66,7 +68,8 @@ public EvaluatorImplementer( elements.getPackageOf(declarationType).toString(), declarationType.getSimpleName() + extraName + "Evaluator" ); - this.processOutputsMultivalued = this.processFunction.hasBlockType && (this.processFunction.builderArg != null); + this.processOutputsMultivalued = this.processFunction.hasBlockType; + this.allNullsIsNull = allNullsIsNull; } public JavaFile sourceFile() { @@ -131,7 +134,7 @@ private MethodSpec ctor() { MethodSpec.Builder builder = MethodSpec.constructorBuilder().addModifiers(Modifier.PUBLIC); builder.addParameter(SOURCE, "source"); builder.addStatement("this.source = source"); - processFunction.args.stream().forEach(a -> a.implementCtor(builder)); + processFunction.args.forEach(a -> a.implementCtor(builder)); builder.addParameter(DRIVER_CONTEXT, "driverContext"); builder.addStatement("this.driverContext = driverContext"); return builder.build(); @@ -140,15 +143,15 @@ private MethodSpec ctor() { private MethodSpec eval() { MethodSpec.Builder builder = MethodSpec.methodBuilder("eval").addAnnotation(Override.class); builder.addModifiers(Modifier.PUBLIC).returns(BLOCK).addParameter(PAGE, "page"); - processFunction.args.stream().forEach(a -> a.evalToBlock(builder)); + processFunction.args.forEach(a -> a.evalToBlock(builder)); String invokeBlockEval = invokeRealEval(true); if (processOutputsMultivalued) { builder.addStatement(invokeBlockEval); } else { - processFunction.args.stream().forEach(a -> a.resolveVectors(builder, invokeBlockEval)); + processFunction.args.forEach(a -> a.resolveVectors(builder, invokeBlockEval)); builder.addStatement(invokeRealEval(false)); } - processFunction.args.stream().forEach(a -> a.closeEvalToBlock(builder)); + processFunction.args.forEach(a -> a.closeEvalToBlock(builder)); return builder.build(); } @@ -157,7 +160,7 @@ private String invokeRealEval(boolean blockStyle) { String params = processFunction.args.stream() .map(a -> a.paramName(blockStyle)) - .filter(a -> a != null) + .filter(Objects::nonNull) .collect(Collectors.joining(", ")); if (params.length() > 0) { builder.append(", "); @@ -189,23 +192,23 @@ private MethodSpec realEval(boolean blockStyle) { buildFromFactory(builderType) ); { - processFunction.args.stream().forEach(a -> { + processFunction.args.forEach(a -> { if (a.paramName(blockStyle) != null) { builder.addParameter(a.dataType(blockStyle), a.paramName(blockStyle)); } }); - processFunction.args.stream().forEach(a -> a.createScratch(builder)); + processFunction.args.forEach(a -> a.createScratch(builder)); builder.beginControlFlow("position: for (int p = 0; p < positionCount; p++)"); { if (blockStyle) { if (processOutputsMultivalued == false) { - processFunction.args.stream().forEach(a -> a.skipNull(builder)); - } else { + processFunction.args.forEach(a -> a.skipNull(builder)); + } else if (allNullsIsNull) { builder.addStatement("boolean allBlocksAreNulls = true"); // allow block type inputs to be null - processFunction.args.stream().forEach(a -> a.allBlocksAreNull(builder)); + processFunction.args.forEach(a -> a.allBlocksAreNull(builder)); builder.beginControlFlow("if (allBlocksAreNulls)"); { @@ -214,25 +217,30 @@ private MethodSpec realEval(boolean blockStyle) { } builder.endControlFlow(); } + } else { + assert allNullsIsNull : "allNullsIsNull == false is only supported for block style."; } - processFunction.args.stream().forEach(a -> a.read(builder, blockStyle)); + processFunction.args.forEach(a -> a.read(builder, blockStyle)); StringBuilder pattern = new StringBuilder(); List args = new ArrayList<>(); pattern.append("$T.$N("); args.add(declarationType); args.add(processFunction.function.getSimpleName()); - processFunction.args.stream().forEach(a -> { - if (args.size() > 2) { - pattern.append(", "); - } - a.buildInvocation(pattern, args, blockStyle); - }); + pattern.append(processFunction.args.stream().map(argument -> { + var invocation = new StringBuilder(); + argument.buildInvocation(invocation, args, blockStyle); + return invocation.toString(); + }).collect(Collectors.joining(", "))); pattern.append(")"); String builtPattern; if (processFunction.builderArg == null) { - builtPattern = vectorize ? "result.$L(p, " + pattern + ")" : "result.$L(" + pattern + ")"; - args.add(0, processFunction.appendMethod()); + if (vectorize) { + builtPattern = "result.$L(p, " + pattern + ")"; + } else { + builtPattern = "result.$L(" + pattern + ")"; + } + args.addFirst(processFunction.appendMethod()); } else { builtPattern = pattern.toString(); } @@ -246,7 +254,7 @@ private MethodSpec realEval(boolean blockStyle) { String catchPattern = "catch (" + processFunction.warnExceptions.stream().map(m -> "$T").collect(Collectors.joining(" | ")) + " e)"; - builder.nextControlFlow(catchPattern, processFunction.warnExceptions.stream().map(m -> TypeName.get(m)).toArray()); + builder.nextControlFlow(catchPattern, processFunction.warnExceptions.stream().map(TypeName::get).toArray()); builder.addStatement("warnings().registerException(e)"); builder.addStatement("result.appendNull()"); builder.endControlFlow(); @@ -282,7 +290,7 @@ private TypeSpec factory() { builder.addModifiers(Modifier.STATIC); builder.addField(SOURCE, "source", Modifier.PRIVATE, Modifier.FINAL); - processFunction.args.stream().forEach(a -> a.declareFactoryField(builder)); + processFunction.args.forEach(a -> a.declareFactoryField(builder)); builder.addMethod(processFunction.factoryCtor()); builder.addMethod(processFunction.factoryGet(implementation)); @@ -371,7 +379,7 @@ MethodSpec factoryCtor() { MethodSpec.Builder builder = MethodSpec.constructorBuilder().addModifiers(Modifier.PUBLIC); builder.addParameter(SOURCE, "source"); builder.addStatement("this.source = source"); - args.stream().forEach(a -> a.implementFactoryCtor(builder)); + args.forEach(a -> a.implementFactoryCtor(builder)); return builder.build(); } diff --git a/x-pack/plugin/esql/compute/gen/src/main/java/org/elasticsearch/compute/gen/EvaluatorProcessor.java b/x-pack/plugin/esql/compute/gen/src/main/java/org/elasticsearch/compute/gen/EvaluatorProcessor.java index 1df89e974d19d..88c67f5d40c63 100644 --- a/x-pack/plugin/esql/compute/gen/src/main/java/org/elasticsearch/compute/gen/EvaluatorProcessor.java +++ b/x-pack/plugin/esql/compute/gen/src/main/java/org/elasticsearch/compute/gen/EvaluatorProcessor.java @@ -82,7 +82,8 @@ public boolean process(Set set, RoundEnvironment roundEnv env.getTypeUtils(), (ExecutableElement) evaluatorMethod, evaluatorAnn.extraName(), - warnExceptionsTypes + warnExceptionsTypes, + evaluatorAnn.allNullsIsNull() ).sourceFile(), env ); diff --git a/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/multivalue/MvContainsBooleanEvaluator.java b/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/multivalue/MvContainsBooleanEvaluator.java new file mode 100644 index 0000000000000..8c58c72d51da8 --- /dev/null +++ b/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/multivalue/MvContainsBooleanEvaluator.java @@ -0,0 +1,116 @@ +// 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.expression.function.scalar.multivalue; + +import java.lang.Override; +import java.lang.String; +import org.apache.lucene.util.RamUsageEstimator; +import org.elasticsearch.compute.data.Block; +import org.elasticsearch.compute.data.BooleanBlock; +import org.elasticsearch.compute.data.Page; +import org.elasticsearch.compute.operator.DriverContext; +import org.elasticsearch.compute.operator.EvalOperator; +import org.elasticsearch.compute.operator.Warnings; +import org.elasticsearch.core.Releasables; +import org.elasticsearch.xpack.esql.core.tree.Source; + +/** + * {@link EvalOperator.ExpressionEvaluator} implementation for {@link MvContains}. + * This class is generated. Edit {@code EvaluatorImplementer} instead. + */ +public final class MvContainsBooleanEvaluator implements EvalOperator.ExpressionEvaluator { + private static final long BASE_RAM_BYTES_USED = RamUsageEstimator.shallowSizeOfInstance(MvContainsBooleanEvaluator.class); + + private final Source source; + + private final EvalOperator.ExpressionEvaluator field1; + + private final EvalOperator.ExpressionEvaluator field2; + + private final DriverContext driverContext; + + private Warnings warnings; + + public MvContainsBooleanEvaluator(Source source, EvalOperator.ExpressionEvaluator field1, + EvalOperator.ExpressionEvaluator field2, DriverContext driverContext) { + this.source = source; + this.field1 = field1; + this.field2 = field2; + this.driverContext = driverContext; + } + + @Override + public Block eval(Page page) { + try (BooleanBlock field1Block = (BooleanBlock) field1.eval(page)) { + try (BooleanBlock field2Block = (BooleanBlock) field2.eval(page)) { + return eval(page.getPositionCount(), field1Block, field2Block); + } + } + } + + @Override + public long baseRamBytesUsed() { + long baseRamBytesUsed = BASE_RAM_BYTES_USED; + baseRamBytesUsed += field1.baseRamBytesUsed(); + baseRamBytesUsed += field2.baseRamBytesUsed(); + return baseRamBytesUsed; + } + + public BooleanBlock eval(int positionCount, BooleanBlock field1Block, BooleanBlock field2Block) { + try(BooleanBlock.Builder result = driverContext.blockFactory().newBooleanBlockBuilder(positionCount)) { + position: for (int p = 0; p < positionCount; p++) { + result.appendBoolean(MvContains.process(p, field1Block, field2Block)); + } + return result.build(); + } + } + + @Override + public String toString() { + return "MvContainsBooleanEvaluator[" + "field1=" + field1 + ", field2=" + field2 + "]"; + } + + @Override + public void close() { + Releasables.closeExpectNoException(field1, field2); + } + + private Warnings warnings() { + if (warnings == null) { + this.warnings = Warnings.createWarnings( + driverContext.warningsMode(), + source.source().getLineNumber(), + source.source().getColumnNumber(), + source.text() + ); + } + return warnings; + } + + static class Factory implements EvalOperator.ExpressionEvaluator.Factory { + private final Source source; + + private final EvalOperator.ExpressionEvaluator.Factory field1; + + private final EvalOperator.ExpressionEvaluator.Factory field2; + + public Factory(Source source, EvalOperator.ExpressionEvaluator.Factory field1, + EvalOperator.ExpressionEvaluator.Factory field2) { + this.source = source; + this.field1 = field1; + this.field2 = field2; + } + + @Override + public MvContainsBooleanEvaluator get(DriverContext context) { + return new MvContainsBooleanEvaluator(source, field1.get(context), field2.get(context), context); + } + + @Override + public String toString() { + return "MvContainsBooleanEvaluator[" + "field1=" + field1 + ", field2=" + field2 + "]"; + } + } +} diff --git a/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/multivalue/MvContainsBytesRefEvaluator.java b/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/multivalue/MvContainsBytesRefEvaluator.java new file mode 100644 index 0000000000000..91a3be7f0fff5 --- /dev/null +++ b/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/multivalue/MvContainsBytesRefEvaluator.java @@ -0,0 +1,118 @@ +// 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.expression.function.scalar.multivalue; + +import java.lang.Override; +import java.lang.String; +import org.apache.lucene.util.RamUsageEstimator; +import org.elasticsearch.compute.data.Block; +import org.elasticsearch.compute.data.BooleanBlock; +import org.elasticsearch.compute.data.BytesRefBlock; +import org.elasticsearch.compute.data.Page; +import org.elasticsearch.compute.operator.DriverContext; +import org.elasticsearch.compute.operator.EvalOperator; +import org.elasticsearch.compute.operator.Warnings; +import org.elasticsearch.core.Releasables; +import org.elasticsearch.xpack.esql.core.tree.Source; + +/** + * {@link EvalOperator.ExpressionEvaluator} implementation for {@link MvContains}. + * This class is generated. Edit {@code EvaluatorImplementer} instead. + */ +public final class MvContainsBytesRefEvaluator implements EvalOperator.ExpressionEvaluator { + private static final long BASE_RAM_BYTES_USED = RamUsageEstimator.shallowSizeOfInstance(MvContainsBytesRefEvaluator.class); + + private final Source source; + + private final EvalOperator.ExpressionEvaluator field1; + + private final EvalOperator.ExpressionEvaluator field2; + + private final DriverContext driverContext; + + private Warnings warnings; + + public MvContainsBytesRefEvaluator(Source source, EvalOperator.ExpressionEvaluator field1, + EvalOperator.ExpressionEvaluator field2, DriverContext driverContext) { + this.source = source; + this.field1 = field1; + this.field2 = field2; + this.driverContext = driverContext; + } + + @Override + public Block eval(Page page) { + try (BytesRefBlock field1Block = (BytesRefBlock) field1.eval(page)) { + try (BytesRefBlock field2Block = (BytesRefBlock) field2.eval(page)) { + return eval(page.getPositionCount(), field1Block, field2Block); + } + } + } + + @Override + public long baseRamBytesUsed() { + long baseRamBytesUsed = BASE_RAM_BYTES_USED; + baseRamBytesUsed += field1.baseRamBytesUsed(); + baseRamBytesUsed += field2.baseRamBytesUsed(); + return baseRamBytesUsed; + } + + public BooleanBlock eval(int positionCount, BytesRefBlock field1Block, + BytesRefBlock field2Block) { + try(BooleanBlock.Builder result = driverContext.blockFactory().newBooleanBlockBuilder(positionCount)) { + position: for (int p = 0; p < positionCount; p++) { + result.appendBoolean(MvContains.process(p, field1Block, field2Block)); + } + return result.build(); + } + } + + @Override + public String toString() { + return "MvContainsBytesRefEvaluator[" + "field1=" + field1 + ", field2=" + field2 + "]"; + } + + @Override + public void close() { + Releasables.closeExpectNoException(field1, field2); + } + + private Warnings warnings() { + if (warnings == null) { + this.warnings = Warnings.createWarnings( + driverContext.warningsMode(), + source.source().getLineNumber(), + source.source().getColumnNumber(), + source.text() + ); + } + return warnings; + } + + static class Factory implements EvalOperator.ExpressionEvaluator.Factory { + private final Source source; + + private final EvalOperator.ExpressionEvaluator.Factory field1; + + private final EvalOperator.ExpressionEvaluator.Factory field2; + + public Factory(Source source, EvalOperator.ExpressionEvaluator.Factory field1, + EvalOperator.ExpressionEvaluator.Factory field2) { + this.source = source; + this.field1 = field1; + this.field2 = field2; + } + + @Override + public MvContainsBytesRefEvaluator get(DriverContext context) { + return new MvContainsBytesRefEvaluator(source, field1.get(context), field2.get(context), context); + } + + @Override + public String toString() { + return "MvContainsBytesRefEvaluator[" + "field1=" + field1 + ", field2=" + field2 + "]"; + } + } +} diff --git a/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/multivalue/MvContainsDoubleEvaluator.java b/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/multivalue/MvContainsDoubleEvaluator.java new file mode 100644 index 0000000000000..b54186e203035 --- /dev/null +++ b/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/multivalue/MvContainsDoubleEvaluator.java @@ -0,0 +1,117 @@ +// 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.expression.function.scalar.multivalue; + +import java.lang.Override; +import java.lang.String; +import org.apache.lucene.util.RamUsageEstimator; +import org.elasticsearch.compute.data.Block; +import org.elasticsearch.compute.data.BooleanBlock; +import org.elasticsearch.compute.data.DoubleBlock; +import org.elasticsearch.compute.data.Page; +import org.elasticsearch.compute.operator.DriverContext; +import org.elasticsearch.compute.operator.EvalOperator; +import org.elasticsearch.compute.operator.Warnings; +import org.elasticsearch.core.Releasables; +import org.elasticsearch.xpack.esql.core.tree.Source; + +/** + * {@link EvalOperator.ExpressionEvaluator} implementation for {@link MvContains}. + * This class is generated. Edit {@code EvaluatorImplementer} instead. + */ +public final class MvContainsDoubleEvaluator implements EvalOperator.ExpressionEvaluator { + private static final long BASE_RAM_BYTES_USED = RamUsageEstimator.shallowSizeOfInstance(MvContainsDoubleEvaluator.class); + + private final Source source; + + private final EvalOperator.ExpressionEvaluator field1; + + private final EvalOperator.ExpressionEvaluator field2; + + private final DriverContext driverContext; + + private Warnings warnings; + + public MvContainsDoubleEvaluator(Source source, EvalOperator.ExpressionEvaluator field1, + EvalOperator.ExpressionEvaluator field2, DriverContext driverContext) { + this.source = source; + this.field1 = field1; + this.field2 = field2; + this.driverContext = driverContext; + } + + @Override + public Block eval(Page page) { + try (DoubleBlock field1Block = (DoubleBlock) field1.eval(page)) { + try (DoubleBlock field2Block = (DoubleBlock) field2.eval(page)) { + return eval(page.getPositionCount(), field1Block, field2Block); + } + } + } + + @Override + public long baseRamBytesUsed() { + long baseRamBytesUsed = BASE_RAM_BYTES_USED; + baseRamBytesUsed += field1.baseRamBytesUsed(); + baseRamBytesUsed += field2.baseRamBytesUsed(); + return baseRamBytesUsed; + } + + public BooleanBlock eval(int positionCount, DoubleBlock field1Block, DoubleBlock field2Block) { + try(BooleanBlock.Builder result = driverContext.blockFactory().newBooleanBlockBuilder(positionCount)) { + position: for (int p = 0; p < positionCount; p++) { + result.appendBoolean(MvContains.process(p, field1Block, field2Block)); + } + return result.build(); + } + } + + @Override + public String toString() { + return "MvContainsDoubleEvaluator[" + "field1=" + field1 + ", field2=" + field2 + "]"; + } + + @Override + public void close() { + Releasables.closeExpectNoException(field1, field2); + } + + private Warnings warnings() { + if (warnings == null) { + this.warnings = Warnings.createWarnings( + driverContext.warningsMode(), + source.source().getLineNumber(), + source.source().getColumnNumber(), + source.text() + ); + } + return warnings; + } + + static class Factory implements EvalOperator.ExpressionEvaluator.Factory { + private final Source source; + + private final EvalOperator.ExpressionEvaluator.Factory field1; + + private final EvalOperator.ExpressionEvaluator.Factory field2; + + public Factory(Source source, EvalOperator.ExpressionEvaluator.Factory field1, + EvalOperator.ExpressionEvaluator.Factory field2) { + this.source = source; + this.field1 = field1; + this.field2 = field2; + } + + @Override + public MvContainsDoubleEvaluator get(DriverContext context) { + return new MvContainsDoubleEvaluator(source, field1.get(context), field2.get(context), context); + } + + @Override + public String toString() { + return "MvContainsDoubleEvaluator[" + "field1=" + field1 + ", field2=" + field2 + "]"; + } + } +} diff --git a/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/multivalue/MvContainsIntEvaluator.java b/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/multivalue/MvContainsIntEvaluator.java new file mode 100644 index 0000000000000..99956e9ccaf02 --- /dev/null +++ b/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/multivalue/MvContainsIntEvaluator.java @@ -0,0 +1,117 @@ +// 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.expression.function.scalar.multivalue; + +import java.lang.Override; +import java.lang.String; +import org.apache.lucene.util.RamUsageEstimator; +import org.elasticsearch.compute.data.Block; +import org.elasticsearch.compute.data.BooleanBlock; +import org.elasticsearch.compute.data.IntBlock; +import org.elasticsearch.compute.data.Page; +import org.elasticsearch.compute.operator.DriverContext; +import org.elasticsearch.compute.operator.EvalOperator; +import org.elasticsearch.compute.operator.Warnings; +import org.elasticsearch.core.Releasables; +import org.elasticsearch.xpack.esql.core.tree.Source; + +/** + * {@link EvalOperator.ExpressionEvaluator} implementation for {@link MvContains}. + * This class is generated. Edit {@code EvaluatorImplementer} instead. + */ +public final class MvContainsIntEvaluator implements EvalOperator.ExpressionEvaluator { + private static final long BASE_RAM_BYTES_USED = RamUsageEstimator.shallowSizeOfInstance(MvContainsIntEvaluator.class); + + private final Source source; + + private final EvalOperator.ExpressionEvaluator field1; + + private final EvalOperator.ExpressionEvaluator field2; + + private final DriverContext driverContext; + + private Warnings warnings; + + public MvContainsIntEvaluator(Source source, EvalOperator.ExpressionEvaluator field1, + EvalOperator.ExpressionEvaluator field2, DriverContext driverContext) { + this.source = source; + this.field1 = field1; + this.field2 = field2; + this.driverContext = driverContext; + } + + @Override + public Block eval(Page page) { + try (IntBlock field1Block = (IntBlock) field1.eval(page)) { + try (IntBlock field2Block = (IntBlock) field2.eval(page)) { + return eval(page.getPositionCount(), field1Block, field2Block); + } + } + } + + @Override + public long baseRamBytesUsed() { + long baseRamBytesUsed = BASE_RAM_BYTES_USED; + baseRamBytesUsed += field1.baseRamBytesUsed(); + baseRamBytesUsed += field2.baseRamBytesUsed(); + return baseRamBytesUsed; + } + + public BooleanBlock eval(int positionCount, IntBlock field1Block, IntBlock field2Block) { + try(BooleanBlock.Builder result = driverContext.blockFactory().newBooleanBlockBuilder(positionCount)) { + position: for (int p = 0; p < positionCount; p++) { + result.appendBoolean(MvContains.process(p, field1Block, field2Block)); + } + return result.build(); + } + } + + @Override + public String toString() { + return "MvContainsIntEvaluator[" + "field1=" + field1 + ", field2=" + field2 + "]"; + } + + @Override + public void close() { + Releasables.closeExpectNoException(field1, field2); + } + + private Warnings warnings() { + if (warnings == null) { + this.warnings = Warnings.createWarnings( + driverContext.warningsMode(), + source.source().getLineNumber(), + source.source().getColumnNumber(), + source.text() + ); + } + return warnings; + } + + static class Factory implements EvalOperator.ExpressionEvaluator.Factory { + private final Source source; + + private final EvalOperator.ExpressionEvaluator.Factory field1; + + private final EvalOperator.ExpressionEvaluator.Factory field2; + + public Factory(Source source, EvalOperator.ExpressionEvaluator.Factory field1, + EvalOperator.ExpressionEvaluator.Factory field2) { + this.source = source; + this.field1 = field1; + this.field2 = field2; + } + + @Override + public MvContainsIntEvaluator get(DriverContext context) { + return new MvContainsIntEvaluator(source, field1.get(context), field2.get(context), context); + } + + @Override + public String toString() { + return "MvContainsIntEvaluator[" + "field1=" + field1 + ", field2=" + field2 + "]"; + } + } +} diff --git a/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/multivalue/MvContainsLongEvaluator.java b/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/multivalue/MvContainsLongEvaluator.java new file mode 100644 index 0000000000000..2bb747caf596f --- /dev/null +++ b/x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/multivalue/MvContainsLongEvaluator.java @@ -0,0 +1,117 @@ +// 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.expression.function.scalar.multivalue; + +import java.lang.Override; +import java.lang.String; +import org.apache.lucene.util.RamUsageEstimator; +import org.elasticsearch.compute.data.Block; +import org.elasticsearch.compute.data.BooleanBlock; +import org.elasticsearch.compute.data.LongBlock; +import org.elasticsearch.compute.data.Page; +import org.elasticsearch.compute.operator.DriverContext; +import org.elasticsearch.compute.operator.EvalOperator; +import org.elasticsearch.compute.operator.Warnings; +import org.elasticsearch.core.Releasables; +import org.elasticsearch.xpack.esql.core.tree.Source; + +/** + * {@link EvalOperator.ExpressionEvaluator} implementation for {@link MvContains}. + * This class is generated. Edit {@code EvaluatorImplementer} instead. + */ +public final class MvContainsLongEvaluator implements EvalOperator.ExpressionEvaluator { + private static final long BASE_RAM_BYTES_USED = RamUsageEstimator.shallowSizeOfInstance(MvContainsLongEvaluator.class); + + private final Source source; + + private final EvalOperator.ExpressionEvaluator field1; + + private final EvalOperator.ExpressionEvaluator field2; + + private final DriverContext driverContext; + + private Warnings warnings; + + public MvContainsLongEvaluator(Source source, EvalOperator.ExpressionEvaluator field1, + EvalOperator.ExpressionEvaluator field2, DriverContext driverContext) { + this.source = source; + this.field1 = field1; + this.field2 = field2; + this.driverContext = driverContext; + } + + @Override + public Block eval(Page page) { + try (LongBlock field1Block = (LongBlock) field1.eval(page)) { + try (LongBlock field2Block = (LongBlock) field2.eval(page)) { + return eval(page.getPositionCount(), field1Block, field2Block); + } + } + } + + @Override + public long baseRamBytesUsed() { + long baseRamBytesUsed = BASE_RAM_BYTES_USED; + baseRamBytesUsed += field1.baseRamBytesUsed(); + baseRamBytesUsed += field2.baseRamBytesUsed(); + return baseRamBytesUsed; + } + + public BooleanBlock eval(int positionCount, LongBlock field1Block, LongBlock field2Block) { + try(BooleanBlock.Builder result = driverContext.blockFactory().newBooleanBlockBuilder(positionCount)) { + position: for (int p = 0; p < positionCount; p++) { + result.appendBoolean(MvContains.process(p, field1Block, field2Block)); + } + return result.build(); + } + } + + @Override + public String toString() { + return "MvContainsLongEvaluator[" + "field1=" + field1 + ", field2=" + field2 + "]"; + } + + @Override + public void close() { + Releasables.closeExpectNoException(field1, field2); + } + + private Warnings warnings() { + if (warnings == null) { + this.warnings = Warnings.createWarnings( + driverContext.warningsMode(), + source.source().getLineNumber(), + source.source().getColumnNumber(), + source.text() + ); + } + return warnings; + } + + static class Factory implements EvalOperator.ExpressionEvaluator.Factory { + private final Source source; + + private final EvalOperator.ExpressionEvaluator.Factory field1; + + private final EvalOperator.ExpressionEvaluator.Factory field2; + + public Factory(Source source, EvalOperator.ExpressionEvaluator.Factory field1, + EvalOperator.ExpressionEvaluator.Factory field2) { + this.source = source; + this.field1 = field1; + this.field2 = field2; + } + + @Override + public MvContainsLongEvaluator get(DriverContext context) { + return new MvContainsLongEvaluator(source, field1.get(context), field2.get(context), context); + } + + @Override + public String toString() { + return "MvContainsLongEvaluator[" + "field1=" + field1 + ", field2=" + field2 + "]"; + } + } +} diff --git a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/multivalue/MvContains.java b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/multivalue/MvContains.java index 16690f4a28859..d83aa0edd8e83 100644 --- a/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/multivalue/MvContains.java +++ b/x-pack/plugin/esql/src/main/java/org/elasticsearch/xpack/esql/expression/function/scalar/multivalue/MvContains.java @@ -8,9 +8,10 @@ package org.elasticsearch.xpack.esql.expression.function.scalar.multivalue; import org.apache.lucene.util.BytesRef; -import org.apache.lucene.util.RamUsageEstimator; import org.elasticsearch.common.io.stream.NamedWriteableRegistry; import org.elasticsearch.common.io.stream.StreamInput; +import org.elasticsearch.compute.ann.Evaluator; +import org.elasticsearch.compute.ann.Position; import org.elasticsearch.compute.data.Block; import org.elasticsearch.compute.data.BooleanBlock; import org.elasticsearch.compute.data.BytesRefBlock; @@ -18,11 +19,8 @@ import org.elasticsearch.compute.data.ElementType; import org.elasticsearch.compute.data.IntBlock; import org.elasticsearch.compute.data.LongBlock; -import org.elasticsearch.compute.data.Page; -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.EsqlIllegalArgumentException; import org.elasticsearch.xpack.esql.core.expression.Expression; import org.elasticsearch.xpack.esql.core.expression.FoldContext; @@ -212,29 +210,29 @@ public ExpressionEvaluator.Factory toEvaluator(ToEvaluator toEvaluator) { }; } - // @Evaluator(extraName = "Int") see end of file. - static void process(BooleanBlock.Builder builder, int position, IntBlock field1, IntBlock field2) { - appendTo(builder, containsAll(field1, field2, position, IntBlock::getInt)); + @Evaluator(extraName = "Int", allNullsIsNull = false) + static boolean process(@Position int position, IntBlock field1, IntBlock field2) { + return containsAll(field1, field2, position, IntBlock::getInt); } - // @Evaluator(extraName = "Boolean") see end of file. - static void process(BooleanBlock.Builder builder, int position, BooleanBlock field1, BooleanBlock field2) { - appendTo(builder, containsAll(field1, field2, position, BooleanBlock::getBoolean)); + @Evaluator(extraName = "Boolean", allNullsIsNull = false) + static boolean process(@Position int position, BooleanBlock field1, BooleanBlock field2) { + return containsAll(field1, field2, position, BooleanBlock::getBoolean); } - // @Evaluator(extraName = "Long") see end of file. - static void process(BooleanBlock.Builder builder, int position, LongBlock field1, LongBlock field2) { - appendTo(builder, containsAll(field1, field2, position, LongBlock::getLong)); + @Evaluator(extraName = "Long", allNullsIsNull = false) + static boolean process(@Position int position, LongBlock field1, LongBlock field2) { + return containsAll(field1, field2, position, LongBlock::getLong); } - // @Evaluator(extraName = "Double") see end of file. - static void process(BooleanBlock.Builder builder, int position, DoubleBlock field1, DoubleBlock field2) { - appendTo(builder, containsAll(field1, field2, position, DoubleBlock::getDouble)); + @Evaluator(extraName = "Double", allNullsIsNull = false) + static boolean process(@Position int position, DoubleBlock field1, DoubleBlock field2) { + return containsAll(field1, field2, position, DoubleBlock::getDouble); } - // @Evaluator(extraName = "BytesRef") see end of file. - static void process(BooleanBlock.Builder builder, int position, BytesRefBlock field1, BytesRefBlock field2) { - appendTo(builder, containsAll(field1, field2, position, (block, index) -> { + @Evaluator(extraName = "BytesRef", allNullsIsNull = false) + static boolean process(@Position int position, BytesRefBlock field1, BytesRefBlock field2) { + return containsAll(field1, field2, position, (block, index) -> { var ref = new BytesRef(); // we pass in a reference, but sometimes we only get a return value, see ConstantBytesRefVector.getBytesRef ref = block.getBytesRef(index, ref); @@ -243,15 +241,7 @@ static void process(BooleanBlock.Builder builder, int position, BytesRefBlock fi return null; } return ref; - })); - } - - static void appendTo(BooleanBlock.Builder builder, Boolean bool) { - if (bool == null) { - builder.appendNull(); - } else { - builder.beginPositionEntry().appendBoolean(bool).endPositionEntry(); - } + }); } /** @@ -263,7 +253,7 @@ static void appendTo(BooleanBlock.Builder builder, Boolean bool) { * @param subset block containing values that should be present in the other block. * @return {@code true} if the given blocks are a superset and subset to each other, {@code false} if not. */ - static Boolean containsAll( + static boolean containsAll( BlockType superset, BlockType subset, final int position, @@ -316,482 +306,4 @@ static boolean hasValue( interface ValueExtractor { Type extractValue(BlockType block, int position); } - - /** - * Evaluator that always returns true for all values in the block (~column) - */ - public static final class ConstantBooleanTrueEvaluator implements ExpressionEvaluator.Factory { - @Override - public ExpressionEvaluator get(DriverContext driverContext) { - return new ExpressionEvaluator() { - @Override - public Block eval(Page page) { - return driverContext.blockFactory().newConstantBooleanBlockWith(true, page.getPositionCount()); - } - - @Override - public void close() {} - - @Override - public String toString() { - return "ConstantBooleanTrueEvaluator"; - } - - @Override - public long baseRamBytesUsed() { - return 0; - } - }; - } - - @Override - public String toString() { - return "ConstantBooleanTrueEvaluator"; - } - } - - /** - * Currently {@code EvaluatorImplementer} generates: - * if (allBlocksAreNulls) { - * result.appendNull(); - * continue position; - * } - * when all params are null, this violates our contract of always returning a boolean. - * It should probably also generate the warnings method conditionally - omitted here. - * TODO extend code generation to handle this case - */ - public static class MvContainsBooleanEvaluator implements EvalOperator.ExpressionEvaluator { - private static final long BASE_RAM_BYTES_USED = RamUsageEstimator.shallowSizeOfInstance(MvContainsBooleanEvaluator.class); - private final EvalOperator.ExpressionEvaluator field1; - private final EvalOperator.ExpressionEvaluator field2; - private final DriverContext driverContext; - - public MvContainsBooleanEvaluator( - EvalOperator.ExpressionEvaluator field1, - EvalOperator.ExpressionEvaluator field2, - DriverContext driverContext - ) { - this.field1 = field1; - this.field2 = field2; - this.driverContext = driverContext; - } - - @Override - public Block eval(Page page) { - try (BooleanBlock field1Block = (BooleanBlock) field1.eval(page)) { - try (BooleanBlock field2Block = (BooleanBlock) field2.eval(page)) { - return eval(page.getPositionCount(), field1Block, field2Block); - } - } - } - - public BooleanBlock eval(int positionCount, BooleanBlock field1Block, BooleanBlock field2Block) { - try (BooleanBlock.Builder result = driverContext.blockFactory().newBooleanBlockBuilder(positionCount)) { - for (int p = 0; p < positionCount; p++) { - MvContains.process(result, p, field1Block, field2Block); - } - return result.build(); - } - } - - @Override - public String toString() { - return "MvContainsBooleanEvaluator[" + "field1=" + field1 + ", field2=" + field2 + "]"; - } - - @Override - public void close() { - Releasables.closeExpectNoException(field1, field2); - } - - @Override - public long baseRamBytesUsed() { - long baseRamBytesUsed = BASE_RAM_BYTES_USED; - baseRamBytesUsed += field1.baseRamBytesUsed(); - baseRamBytesUsed += field2.baseRamBytesUsed(); - return baseRamBytesUsed; - } - - public static class Factory implements EvalOperator.ExpressionEvaluator.Factory { - private final Source source; - private final EvalOperator.ExpressionEvaluator.Factory field1; - private final EvalOperator.ExpressionEvaluator.Factory field2; - - public Factory( - Source source, - EvalOperator.ExpressionEvaluator.Factory field1, - EvalOperator.ExpressionEvaluator.Factory field2 - ) { - this.source = source; - this.field1 = field1; - this.field2 = field2; - } - - @Override - public MvContainsBooleanEvaluator get(DriverContext context) { - return new MvContainsBooleanEvaluator(field1.get(context), field2.get(context), context); - } - - @Override - public String toString() { - return "MvContainsBooleanEvaluator[" + "field1=" + field1 + ", field2=" + field2 + "]"; - } - } - } - - /** - * Currently {@code EvaluatorImplementer} generates: - * if (allBlocksAreNulls) { - * result.appendNull(); - * continue position; - * } - * when all params are null, this violates our contract of always returning a boolean. - * It should probably also generate the warnings method conditionally - omitted here. - * TODO extend code generation to handle this case - */ - public static class MvContainsBytesRefEvaluator implements EvalOperator.ExpressionEvaluator { - private static final long BASE_RAM_BYTES_USED = RamUsageEstimator.shallowSizeOfInstance(MvContainsBytesRefEvaluator.class); - private final EvalOperator.ExpressionEvaluator field1; - private final EvalOperator.ExpressionEvaluator field2; - private final DriverContext driverContext; - - public MvContainsBytesRefEvaluator( - EvalOperator.ExpressionEvaluator field1, - EvalOperator.ExpressionEvaluator field2, - DriverContext driverContext - ) { - this.field1 = field1; - this.field2 = field2; - this.driverContext = driverContext; - } - - @Override - public Block eval(Page page) { - try (BytesRefBlock field1Block = (BytesRefBlock) field1.eval(page)) { - try (BytesRefBlock field2Block = (BytesRefBlock) field2.eval(page)) { - return eval(page.getPositionCount(), field1Block, field2Block); - } - } - } - - public BooleanBlock eval(int positionCount, BytesRefBlock field1Block, BytesRefBlock field2Block) { - try (BooleanBlock.Builder result = driverContext.blockFactory().newBooleanBlockBuilder(positionCount)) { - for (int p = 0; p < positionCount; p++) { - MvContains.process(result, p, field1Block, field2Block); - } - return result.build(); - } - } - - @Override - public String toString() { - return "MvContainsBytesRefEvaluator[" + "field1=" + field1 + ", field2=" + field2 + "]"; - } - - @Override - public void close() { - Releasables.closeExpectNoException(field1, field2); - } - - @Override - public long baseRamBytesUsed() { - long baseRamBytesUsed = BASE_RAM_BYTES_USED; - baseRamBytesUsed += field1.baseRamBytesUsed(); - baseRamBytesUsed += field2.baseRamBytesUsed(); - return baseRamBytesUsed; - } - - public static class Factory implements EvalOperator.ExpressionEvaluator.Factory { - private final Source source; - private final EvalOperator.ExpressionEvaluator.Factory field1; - private final EvalOperator.ExpressionEvaluator.Factory field2; - - public Factory( - Source source, - EvalOperator.ExpressionEvaluator.Factory field1, - EvalOperator.ExpressionEvaluator.Factory field2 - ) { - this.source = source; - this.field1 = field1; - this.field2 = field2; - } - - @Override - public MvContainsBytesRefEvaluator get(DriverContext context) { - return new MvContainsBytesRefEvaluator(field1.get(context), field2.get(context), context); - } - - @Override - public String toString() { - return "MvContainsBytesRefEvaluator[" + "field1=" + field1 + ", field2=" + field2 + "]"; - } - } - } - - /** - * Currently {@code EvaluatorImplementer} generates: - * if (allBlocksAreNulls) { - * result.appendNull(); - * continue position; - * } - * when all params are null, this violates our contract of always returning a boolean. - * It should probably also generate the warnings method conditionally - omitted here. - * TODO extend code generation to handle this case - */ - public static class MvContainsDoubleEvaluator implements EvalOperator.ExpressionEvaluator { - private static final long BASE_RAM_BYTES_USED = RamUsageEstimator.shallowSizeOfInstance(MvContainsDoubleEvaluator.class); - private final EvalOperator.ExpressionEvaluator field1; - private final EvalOperator.ExpressionEvaluator field2; - private final DriverContext driverContext; - - public MvContainsDoubleEvaluator( - EvalOperator.ExpressionEvaluator field1, - EvalOperator.ExpressionEvaluator field2, - DriverContext driverContext - ) { - this.field1 = field1; - this.field2 = field2; - this.driverContext = driverContext; - } - - @Override - public Block eval(Page page) { - try (DoubleBlock field1Block = (DoubleBlock) field1.eval(page)) { - try (DoubleBlock field2Block = (DoubleBlock) field2.eval(page)) { - return eval(page.getPositionCount(), field1Block, field2Block); - } - } - } - - public BooleanBlock eval(int positionCount, DoubleBlock field1Block, DoubleBlock field2Block) { - try (BooleanBlock.Builder result = driverContext.blockFactory().newBooleanBlockBuilder(positionCount)) { - for (int p = 0; p < positionCount; p++) { - MvContains.process(result, p, field1Block, field2Block); - } - return result.build(); - } - } - - @Override - public String toString() { - return "MvContainsDoubleEvaluator[" + "field1=" + field1 + ", field2=" + field2 + "]"; - } - - @Override - public void close() { - Releasables.closeExpectNoException(field1, field2); - } - - @Override - public long baseRamBytesUsed() { - long baseRamBytesUsed = BASE_RAM_BYTES_USED; - baseRamBytesUsed += field1.baseRamBytesUsed(); - baseRamBytesUsed += field2.baseRamBytesUsed(); - return baseRamBytesUsed; - } - - public static class Factory implements EvalOperator.ExpressionEvaluator.Factory { - private final Source source; - private final EvalOperator.ExpressionEvaluator.Factory field1; - private final EvalOperator.ExpressionEvaluator.Factory field2; - - public Factory( - Source source, - EvalOperator.ExpressionEvaluator.Factory field1, - EvalOperator.ExpressionEvaluator.Factory field2 - ) { - this.source = source; - this.field1 = field1; - this.field2 = field2; - } - - @Override - public MvContainsDoubleEvaluator get(DriverContext context) { - return new MvContainsDoubleEvaluator(field1.get(context), field2.get(context), context); - } - - @Override - public String toString() { - return "MvContainsDoubleEvaluator[" + "field1=" + field1 + ", field2=" + field2 + "]"; - } - } - } - - /** - * Currently {@code EvaluatorImplementer} generates: - * if (allBlocksAreNulls) { - * result.appendNull(); - * continue position; - * } - * when all params are null, this violates our contract of always returning a boolean. - * It should probably also generate the warnings method conditionally - omitted here. - * TODO extend code generation to handle this case - */ - public static class MvContainsIntEvaluator implements EvalOperator.ExpressionEvaluator { - private static final long BASE_RAM_BYTES_USED = RamUsageEstimator.shallowSizeOfInstance(MvContainsIntEvaluator.class); - private final EvalOperator.ExpressionEvaluator field1; - private final EvalOperator.ExpressionEvaluator field2; - private final DriverContext driverContext; - - public MvContainsIntEvaluator( - EvalOperator.ExpressionEvaluator field1, - EvalOperator.ExpressionEvaluator field2, - DriverContext driverContext - ) { - this.field1 = field1; - this.field2 = field2; - this.driverContext = driverContext; - } - - @Override - public Block eval(Page page) { - try (IntBlock field1Block = (IntBlock) field1.eval(page)) { - try (IntBlock field2Block = (IntBlock) field2.eval(page)) { - return eval(page.getPositionCount(), field1Block, field2Block); - } - } - } - - public BooleanBlock eval(int positionCount, IntBlock field1Block, IntBlock field2Block) { - try (BooleanBlock.Builder result = driverContext.blockFactory().newBooleanBlockBuilder(positionCount)) { - for (int p = 0; p < positionCount; p++) { - MvContains.process(result, p, field1Block, field2Block); - } - return result.build(); - } - } - - @Override - public String toString() { - return "MvContainsIntEvaluator[" + "field1=" + field1 + ", field2=" + field2 + "]"; - } - - @Override - public void close() { - Releasables.closeExpectNoException(field1, field2); - } - - @Override - public long baseRamBytesUsed() { - long baseRamBytesUsed = BASE_RAM_BYTES_USED; - baseRamBytesUsed += field1.baseRamBytesUsed(); - baseRamBytesUsed += field2.baseRamBytesUsed(); - return baseRamBytesUsed; - } - - public static class Factory implements EvalOperator.ExpressionEvaluator.Factory { - private final Source source; - private final EvalOperator.ExpressionEvaluator.Factory field1; - private final EvalOperator.ExpressionEvaluator.Factory field2; - - public Factory( - Source source, - EvalOperator.ExpressionEvaluator.Factory field1, - EvalOperator.ExpressionEvaluator.Factory field2 - ) { - this.source = source; - this.field1 = field1; - this.field2 = field2; - } - - @Override - public MvContainsIntEvaluator get(DriverContext context) { - return new MvContainsIntEvaluator(field1.get(context), field2.get(context), context); - } - - @Override - public String toString() { - return "MvContainsIntEvaluator[" + "field1=" + field1 + ", field2=" + field2 + "]"; - } - } - } - - /** - * Currently {@code EvaluatorImplementer} generates: - * if (allBlocksAreNulls) { - * result.appendNull(); - * continue position; - * } - * when all params are null, this violates our contract of always returning a boolean. - * It should probably also generate the warnings method conditionally - omitted here. - * TODO extend code generation to handle this case - */ - public static class MvContainsLongEvaluator implements EvalOperator.ExpressionEvaluator { - private static final long BASE_RAM_BYTES_USED = RamUsageEstimator.shallowSizeOfInstance(MvContainsLongEvaluator.class); - private final EvalOperator.ExpressionEvaluator field1; - private final EvalOperator.ExpressionEvaluator field2; - private final DriverContext driverContext; - - public MvContainsLongEvaluator( - EvalOperator.ExpressionEvaluator field1, - EvalOperator.ExpressionEvaluator field2, - DriverContext driverContext - ) { - this.field1 = field1; - this.field2 = field2; - this.driverContext = driverContext; - } - - @Override - public Block eval(Page page) { - try (LongBlock field1Block = (LongBlock) field1.eval(page)) { - try (LongBlock field2Block = (LongBlock) field2.eval(page)) { - return eval(page.getPositionCount(), field1Block, field2Block); - } - } - } - - public BooleanBlock eval(int positionCount, LongBlock field1Block, LongBlock field2Block) { - try (BooleanBlock.Builder result = driverContext.blockFactory().newBooleanBlockBuilder(positionCount)) { - for (int p = 0; p < positionCount; p++) { - MvContains.process(result, p, field1Block, field2Block); - } - return result.build(); - } - } - - @Override - public String toString() { - return "MvContainsLongEvaluator[" + "field1=" + field1 + ", field2=" + field2 + "]"; - } - - @Override - public void close() { - Releasables.closeExpectNoException(field1, field2); - } - - @Override - public long baseRamBytesUsed() { - long baseRamBytesUsed = BASE_RAM_BYTES_USED; - baseRamBytesUsed += field1.baseRamBytesUsed(); - baseRamBytesUsed += field2.baseRamBytesUsed(); - return baseRamBytesUsed; - } - - public static class Factory implements EvalOperator.ExpressionEvaluator.Factory { - private final Source source; - private final EvalOperator.ExpressionEvaluator.Factory field1; - private final EvalOperator.ExpressionEvaluator.Factory field2; - - public Factory( - Source source, - EvalOperator.ExpressionEvaluator.Factory field1, - EvalOperator.ExpressionEvaluator.Factory field2 - ) { - this.source = source; - this.field1 = field1; - this.field2 = field2; - } - - @Override - public MvContainsLongEvaluator get(DriverContext context) { - return new MvContainsLongEvaluator(field1.get(context), field2.get(context), context); - } - - @Override - public String toString() { - return "MvContainsLongEvaluator[" + "field1=" + field1 + ", field2=" + field2 + "]"; - } - } - } }