SCRIPTING: Support BucketAggScript return null (#32811)

* As explained in #32790, `BucketAggregationScript` must support `null` as a return value
* Closes #32790
This commit is contained in:
Armin Braun 2018-08-13 20:08:26 +02:00 committed by GitHub
parent 106a4a6a48
commit d412230cda
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 47 additions and 9 deletions

View File

@ -147,7 +147,7 @@ public class ExpressionScriptEngine extends AbstractComponent implements ScriptE
}
return new BucketAggregationScript(parameters) {
@Override
public double execute() {
public Double execute() {
getParams().forEach((name, value) -> {
ReplaceableConstDoubleValues placeholder = functionValuesMap.get(name);
if (placeholder == null) {

View File

@ -46,7 +46,7 @@ public abstract class BucketAggregationScript {
return params;
}
public abstract double execute();
public abstract Double execute();
public interface Factory {
BucketAggregationScript newInstance(Map<String, Object> params);

View File

@ -110,13 +110,17 @@ public class BucketScriptPipelineAggregator extends PipelineAggregator {
if (skipBucket) {
newBuckets.add(bucket);
} else {
double returned = factory.newInstance(vars).execute();
final List<InternalAggregation> aggs = StreamSupport.stream(bucket.getAggregations().spliterator(), false).map(
Double returned = factory.newInstance(vars).execute();
if (returned == null) {
newBuckets.add(bucket);
} else {
final List<InternalAggregation> aggs = StreamSupport.stream(bucket.getAggregations().spliterator(), false).map(
(p) -> (InternalAggregation) p).collect(Collectors.toList());
aggs.add(new InternalSimpleValue(name(), returned, formatter, new ArrayList<>(), metaData()));
InternalMultiBucketAggregation.InternalBucket newBucket = originalAgg.createBucket(new InternalAggregations(aggs),
aggs.add(new InternalSimpleValue(name(), returned, formatter, new ArrayList<>(), metaData()));
InternalMultiBucketAggregation.InternalBucket newBucket = originalAgg.createBucket(new InternalAggregations(aggs),
bucket);
newBuckets.add(newBucket);
newBuckets.add(newBucket);
}
}
}
return originalAgg.create(newBuckets);

View File

@ -117,6 +117,8 @@ public class BucketScriptIT extends ESIntegTestCase {
return value0 + value1 + value2;
});
scripts.put("return null", vars -> null);
return scripts;
}
}
@ -478,6 +480,33 @@ public class BucketScriptIT extends ESIntegTestCase {
}
}
public void testInlineScriptReturnNull() {
SearchResponse response = client()
.prepareSearch("idx")
.addAggregation(
histogram("histo")
.field(FIELD_1_NAME).interval(interval)
.subAggregation(
bucketScript(
"nullField",
new Script(ScriptType.INLINE, CustomScriptPlugin.NAME, "return null", Collections.emptyMap())
)
)
).execute().actionGet();
assertSearchResponse(response);
Histogram histo = response.getAggregations().get("histo");
assertThat(histo, notNullValue());
assertThat(histo.getName(), equalTo("histo"));
List<? extends Histogram.Bucket> buckets = histo.getBuckets();
for (int i = 0; i < buckets.size(); ++i) {
Histogram.Bucket bucket = buckets.get(i);
assertNull(bucket.getAggregations().get("nullField"));
}
}
public void testStoredScript() {
assertAcked(client().admin().cluster().preparePutStoredScript()
.setId("my_script")

View File

@ -111,8 +111,13 @@ public class MockScriptEngine implements ScriptEngine {
} else if (context.instanceClazz.equals(BucketAggregationScript.class)) {
BucketAggregationScript.Factory factory = parameters -> new BucketAggregationScript(parameters) {
@Override
public double execute() {
return ((Number) script.apply(getParams())).doubleValue();
public Double execute() {
Object ret = script.apply(getParams());
if (ret == null) {
return null;
} else {
return ((Number) ret).doubleValue();
}
}
};
return context.factoryClazz.cast(factory);