From 35317b0ebfcc962ab558617964e42685ec087907 Mon Sep 17 00:00:00 2001 From: Ignacio Vera Date: Tue, 19 Oct 2021 07:17:11 +0200 Subject: [PATCH] guard geoline aggregation from parents aggegator that emit empty buckets (#79129) This change prevents an AIOOBE that might happen with the provided bucket to build the aggregation is bigger that the max bucket that contains data. --- .../aggregations/GeoLineAggregator.java | 4 +- .../rest-api-spec/test/60_geo_line.yml | 134 ++++++++++++++++++ 2 files changed, 136 insertions(+), 2 deletions(-) diff --git a/x-pack/plugin/spatial/src/main/java/org/elasticsearch/xpack/spatial/search/aggregations/GeoLineAggregator.java b/x-pack/plugin/spatial/src/main/java/org/elasticsearch/xpack/spatial/search/aggregations/GeoLineAggregator.java index dc5fb472d87a6..58eb7c1bd42e2 100644 --- a/x-pack/plugin/spatial/src/main/java/org/elasticsearch/xpack/spatial/search/aggregations/GeoLineAggregator.java +++ b/x-pack/plugin/spatial/src/main/java/org/elasticsearch/xpack/spatial/search/aggregations/GeoLineAggregator.java @@ -85,7 +85,7 @@ public void collect(int doc, long bucket) throws IOException { @Override public InternalAggregation buildAggregation(long bucket) { - if (valuesSources == null) { + if (valuesSources == null || bucket >= counts.size()) { return buildEmptyAggregation(); } boolean complete = counts.get(bucket) <= size; @@ -98,7 +98,7 @@ public InternalAggregation buildAggregation(long bucket) { @Override public InternalAggregation buildEmptyAggregation() { - return new InternalGeoLine(name, null, null, metadata(), true, includeSorts, sortOrder, size); + return new InternalGeoLine(name, new long[0], new double[0], metadata(), true, includeSorts, sortOrder, size); } @Override diff --git a/x-pack/plugin/spatial/src/yamlRestTest/resources/rest-api-spec/test/60_geo_line.yml b/x-pack/plugin/spatial/src/yamlRestTest/resources/rest-api-spec/test/60_geo_line.yml index f156e4db9586f..f62eb6f10bec5 100644 --- a/x-pack/plugin/spatial/src/yamlRestTest/resources/rest-api-spec/test/60_geo_line.yml +++ b/x-pack/plugin/spatial/src/yamlRestTest/resources/rest-api-spec/test/60_geo_line.yml @@ -49,3 +49,137 @@ - match: { aggregations.trace.geometry.coordinates.1: [4.91235, 52.374081] } - match: { aggregations.trace.geometry.coordinates.2: [4.914722, 52.371667] } - is_true: aggregations.trace.properties.complete + +--- +"Test empty buckets": + - do: + indices.create: + index: test1 + body: + mappings: + properties: + location: + type: geo_point + date: + type: date + entity: + type: keyword + + - do: + indices.create: + index: test2 + body: + mappings: + properties: + location: + type: geo_point + date: + type: date + entity: + type: keyword + + - do: + bulk: + refresh: true + body: + - index: + _index: test1 + _id: 1 + - '{ "date" : "2020-01-01T01:00:00.0Z", "entity" : "e1", "location" : { "lat" : 50.3, "lon" : 0.13 }}' + - index: + _index: test1 + _id: 2 + - '{ "date" : "2020-01-01T01:00:01.0Z", "entity" : "e1", "location" : { "lat" : 50.4, "lon" : 0.13 } }' + - index: + _index: test1 + _id: 3 + - '{ "date" : "2020-01-01T01:00:03.0Z", "entity" : "e1", "location" : { "lat" : 50.5, "lon" : 0.13 }}' + - index: + _index: test2 + _id: 1 + - '{ "date" : "2020-01-02T02:00:01.0Z", "entity" : "e2", "location" : { "lat" : 51.3, "lon" : 0.13 }}' + - index: + _index: test2 + _id: 2 + - '{ "date" : "2020-01-02T02:00:02.0Z", "entity" : "e2", "location" : { "lat" : 51.4, "lon" : 0.13 }}' + - index: + _index: test2 + _id: 3 + - '{ "date" : "2020-01-02T02:00:03.0Z", "entity" : "e2", "location" : { "lat" : 51.5, "lon" : 0.13 }}' + + - do: + search: + index: test1,test2 + body: + size: 6 + aggs: + tracks: + filters: + filters: + 1: + term: + entity: e3 + 2: + term: + entity: e4 + aggs: + path: + geo_line: + point: + field: location + sort: + field: date + + - match: { hits.total.value: 6 } + - match: { aggregations.tracks.buckets.1.doc_count: 0 } + - match: { aggregations.tracks.buckets.1.path.type: "Feature" } + - match: { aggregations.tracks.buckets.1.path.geometry.type: "LineString" } + - length: { aggregations.tracks.buckets.1.path.geometry.coordinates: 0 } + - match: { aggregations.tracks.buckets.1.path.properties.complete: true } + - match: { aggregations.tracks.buckets.2.doc_count: 0 } + - match: { aggregations.tracks.buckets.2.path.type: "Feature" } + - match: { aggregations.tracks.buckets.2.path.geometry.type: "LineString" } + - length: { aggregations.tracks.buckets.2.path.geometry.coordinates: 0 } + - match: { aggregations.tracks.buckets.2.path.properties.complete: true } + + + - do: + search: + index: test1,test2 + body: + size: 6 + aggs: + tracks: + filters: + filters: + 1: + term: + entity: e1 + 2: + term: + entity: e2 + aggs: + path: + geo_line: + point: + field: location + sort: + field: date + + - match: { hits.total.value: 6 } + - match: { aggregations.tracks.buckets.1.doc_count: 3 } + - match: { aggregations.tracks.buckets.1.path.type: "Feature" } + - match: { aggregations.tracks.buckets.1.path.geometry.type: "LineString" } + - length: { aggregations.tracks.buckets.1.path.geometry.coordinates: 3 } + - match: { aggregations.tracks.buckets.1.path.geometry.coordinates.0: [0.13,50.3] } + - match: { aggregations.tracks.buckets.1.path.geometry.coordinates.1: [0.13,50.4] } + - match: { aggregations.tracks.buckets.1.path.geometry.coordinates.2: [0.13,50.5] } + - match: { aggregations.tracks.buckets.1.path.properties.complete: true } + - match: { aggregations.tracks.buckets.2.doc_count: 3 } + - match: { aggregations.tracks.buckets.2.path.type: "Feature" } + - match: { aggregations.tracks.buckets.2.path.geometry.type: "LineString" } + - length: { aggregations.tracks.buckets.2.path.geometry.coordinates: 3 } + - match: { aggregations.tracks.buckets.2.path.geometry.coordinates.0: [0.13,51.3] } + - match: { aggregations.tracks.buckets.2.path.geometry.coordinates.1: [0.13,51.4] } + - match: { aggregations.tracks.buckets.2.path.geometry.coordinates.2: [0.13,51.5] } + - match: { aggregations.tracks.buckets.2.path.properties.complete: true }