Skip to content

Commit a2b2b26

Browse files
mjmbischoffelasticsearchmachineivancea
authored
Updating EvaluatorImplementer to add generated evaluators for MvContains (#135723)
Updating EvaluatorImplementer so the evaluators generated for MvContains. Added allNullsIsNull flag to Evaluator, to control generated logic --------- Co-authored-by: elasticsearchmachine <[email protected]> Co-authored-by: Iván Cea Fontenla <[email protected]>
1 parent cee397e commit a2b2b26

File tree

9 files changed

+645
-532
lines changed

9 files changed

+645
-532
lines changed

x-pack/plugin/esql/compute/ann/src/main/java/org/elasticsearch/compute/ann/Evaluator.java

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,4 +42,11 @@
4242
* into a warning and turn into a null value.
4343
*/
4444
Class<? extends Exception>[] warnExceptions() default {};
45+
46+
/**
47+
* Automatically evaluate each position to null if it is null on all the
48+
* blocks. Setting this to {@code false} requires block parameters, like
49+
* {@code static boolean process(@Position int position, LongBlock field1, LongBlock field2)}
50+
*/
51+
boolean allNullsIsNull() default true;
4552
}

x-pack/plugin/esql/compute/gen/src/main/java/org/elasticsearch/compute/gen/EvaluatorImplementer.java

Lines changed: 32 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -51,13 +51,15 @@ public class EvaluatorImplementer {
5151
private final ProcessFunction processFunction;
5252
private final ClassName implementation;
5353
private final boolean processOutputsMultivalued;
54+
private final boolean allNullsIsNull;
5455

5556
public EvaluatorImplementer(
5657
Elements elements,
5758
javax.lang.model.util.Types types,
5859
ExecutableElement processFunction,
5960
String extraName,
60-
List<TypeMirror> warnExceptions
61+
List<TypeMirror> warnExceptions,
62+
boolean allNullsIsNull
6163
) {
6264
this.declarationType = (TypeElement) processFunction.getEnclosingElement();
6365
this.processFunction = new ProcessFunction(types, processFunction, warnExceptions);
@@ -66,7 +68,8 @@ public EvaluatorImplementer(
6668
elements.getPackageOf(declarationType).toString(),
6769
declarationType.getSimpleName() + extraName + "Evaluator"
6870
);
69-
this.processOutputsMultivalued = this.processFunction.hasBlockType && (this.processFunction.builderArg != null);
71+
this.processOutputsMultivalued = this.processFunction.hasBlockType;
72+
this.allNullsIsNull = allNullsIsNull;
7073
}
7174

7275
public JavaFile sourceFile() {
@@ -131,7 +134,7 @@ private MethodSpec ctor() {
131134
MethodSpec.Builder builder = MethodSpec.constructorBuilder().addModifiers(Modifier.PUBLIC);
132135
builder.addParameter(SOURCE, "source");
133136
builder.addStatement("this.source = source");
134-
processFunction.args.stream().forEach(a -> a.implementCtor(builder));
137+
processFunction.args.forEach(a -> a.implementCtor(builder));
135138
builder.addParameter(DRIVER_CONTEXT, "driverContext");
136139
builder.addStatement("this.driverContext = driverContext");
137140
return builder.build();
@@ -140,15 +143,15 @@ private MethodSpec ctor() {
140143
private MethodSpec eval() {
141144
MethodSpec.Builder builder = MethodSpec.methodBuilder("eval").addAnnotation(Override.class);
142145
builder.addModifiers(Modifier.PUBLIC).returns(BLOCK).addParameter(PAGE, "page");
143-
processFunction.args.stream().forEach(a -> a.evalToBlock(builder));
146+
processFunction.args.forEach(a -> a.evalToBlock(builder));
144147
String invokeBlockEval = invokeRealEval(true);
145148
if (processOutputsMultivalued) {
146149
builder.addStatement(invokeBlockEval);
147150
} else {
148-
processFunction.args.stream().forEach(a -> a.resolveVectors(builder, invokeBlockEval));
151+
processFunction.args.forEach(a -> a.resolveVectors(builder, invokeBlockEval));
149152
builder.addStatement(invokeRealEval(false));
150153
}
151-
processFunction.args.stream().forEach(a -> a.closeEvalToBlock(builder));
154+
processFunction.args.forEach(a -> a.closeEvalToBlock(builder));
152155
return builder.build();
153156
}
154157

@@ -157,7 +160,7 @@ private String invokeRealEval(boolean blockStyle) {
157160

158161
String params = processFunction.args.stream()
159162
.map(a -> a.paramName(blockStyle))
160-
.filter(a -> a != null)
163+
.filter(Objects::nonNull)
161164
.collect(Collectors.joining(", "));
162165
if (params.length() > 0) {
163166
builder.append(", ");
@@ -189,23 +192,23 @@ private MethodSpec realEval(boolean blockStyle) {
189192
buildFromFactory(builderType)
190193
);
191194
{
192-
processFunction.args.stream().forEach(a -> {
195+
processFunction.args.forEach(a -> {
193196
if (a.paramName(blockStyle) != null) {
194197
builder.addParameter(a.dataType(blockStyle), a.paramName(blockStyle));
195198
}
196199
});
197200

198-
processFunction.args.stream().forEach(a -> a.createScratch(builder));
201+
processFunction.args.forEach(a -> a.createScratch(builder));
199202

200203
builder.beginControlFlow("position: for (int p = 0; p < positionCount; p++)");
201204
{
202205
if (blockStyle) {
203206
if (processOutputsMultivalued == false) {
204-
processFunction.args.stream().forEach(a -> a.skipNull(builder));
205-
} else {
207+
processFunction.args.forEach(a -> a.skipNull(builder));
208+
} else if (allNullsIsNull) {
206209
builder.addStatement("boolean allBlocksAreNulls = true");
207210
// allow block type inputs to be null
208-
processFunction.args.stream().forEach(a -> a.allBlocksAreNull(builder));
211+
processFunction.args.forEach(a -> a.allBlocksAreNull(builder));
209212

210213
builder.beginControlFlow("if (allBlocksAreNulls)");
211214
{
@@ -214,25 +217,30 @@ private MethodSpec realEval(boolean blockStyle) {
214217
}
215218
builder.endControlFlow();
216219
}
220+
} else {
221+
assert allNullsIsNull : "allNullsIsNull == false is only supported for block style.";
217222
}
218-
processFunction.args.stream().forEach(a -> a.read(builder, blockStyle));
223+
processFunction.args.forEach(a -> a.read(builder, blockStyle));
219224

220225
StringBuilder pattern = new StringBuilder();
221226
List<Object> args = new ArrayList<>();
222227
pattern.append("$T.$N(");
223228
args.add(declarationType);
224229
args.add(processFunction.function.getSimpleName());
225-
processFunction.args.stream().forEach(a -> {
226-
if (args.size() > 2) {
227-
pattern.append(", ");
228-
}
229-
a.buildInvocation(pattern, args, blockStyle);
230-
});
230+
pattern.append(processFunction.args.stream().map(argument -> {
231+
var invocation = new StringBuilder();
232+
argument.buildInvocation(invocation, args, blockStyle);
233+
return invocation.toString();
234+
}).collect(Collectors.joining(", ")));
231235
pattern.append(")");
232236
String builtPattern;
233237
if (processFunction.builderArg == null) {
234-
builtPattern = vectorize ? "result.$L(p, " + pattern + ")" : "result.$L(" + pattern + ")";
235-
args.add(0, processFunction.appendMethod());
238+
if (vectorize) {
239+
builtPattern = "result.$L(p, " + pattern + ")";
240+
} else {
241+
builtPattern = "result.$L(" + pattern + ")";
242+
}
243+
args.addFirst(processFunction.appendMethod());
236244
} else {
237245
builtPattern = pattern.toString();
238246
}
@@ -246,7 +254,7 @@ private MethodSpec realEval(boolean blockStyle) {
246254
String catchPattern = "catch ("
247255
+ processFunction.warnExceptions.stream().map(m -> "$T").collect(Collectors.joining(" | "))
248256
+ " e)";
249-
builder.nextControlFlow(catchPattern, processFunction.warnExceptions.stream().map(m -> TypeName.get(m)).toArray());
257+
builder.nextControlFlow(catchPattern, processFunction.warnExceptions.stream().map(TypeName::get).toArray());
250258
builder.addStatement("warnings().registerException(e)");
251259
builder.addStatement("result.appendNull()");
252260
builder.endControlFlow();
@@ -282,7 +290,7 @@ private TypeSpec factory() {
282290
builder.addModifiers(Modifier.STATIC);
283291

284292
builder.addField(SOURCE, "source", Modifier.PRIVATE, Modifier.FINAL);
285-
processFunction.args.stream().forEach(a -> a.declareFactoryField(builder));
293+
processFunction.args.forEach(a -> a.declareFactoryField(builder));
286294

287295
builder.addMethod(processFunction.factoryCtor());
288296
builder.addMethod(processFunction.factoryGet(implementation));
@@ -371,7 +379,7 @@ MethodSpec factoryCtor() {
371379
MethodSpec.Builder builder = MethodSpec.constructorBuilder().addModifiers(Modifier.PUBLIC);
372380
builder.addParameter(SOURCE, "source");
373381
builder.addStatement("this.source = source");
374-
args.stream().forEach(a -> a.implementFactoryCtor(builder));
382+
args.forEach(a -> a.implementFactoryCtor(builder));
375383
return builder.build();
376384
}
377385

x-pack/plugin/esql/compute/gen/src/main/java/org/elasticsearch/compute/gen/EvaluatorProcessor.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,8 @@ public boolean process(Set<? extends TypeElement> set, RoundEnvironment roundEnv
8282
env.getTypeUtils(),
8383
(ExecutableElement) evaluatorMethod,
8484
evaluatorAnn.extraName(),
85-
warnExceptionsTypes
85+
warnExceptionsTypes,
86+
evaluatorAnn.allNullsIsNull()
8687
).sourceFile(),
8788
env
8889
);

x-pack/plugin/esql/src/main/generated/org/elasticsearch/xpack/esql/expression/function/scalar/multivalue/MvContainsBooleanEvaluator.java

Lines changed: 116 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)