Aggregation: Fix AggregationPath.subPath() to not throw ArrayStoreException

Aggregation.subPath() always threw an ArrayStoreException because we were trying to pass a List into System.arraycopy(). This change fixes that bug and adds a test to prevent regression
This commit is contained in:
Colin Goodheart-Smithe 2015-08-21 12:40:58 +01:00
parent 71cbcea3c2
commit 38085cf90a
2 changed files with 41 additions and 10 deletions

View File

@ -186,9 +186,8 @@ public class AggregationPath {
} }
public AggregationPath subPath(int offset, int length) { public AggregationPath subPath(int offset, int length) {
PathElement[] subTokens = new PathElement[length]; List<PathElement> subTokens = new ArrayList<>(pathElements.subList(offset, offset + length));
System.arraycopy(pathElements, offset, subTokens, 0, length); return new AggregationPath(subTokens);
return new AggregationPath(pathElements);
} }
/** /**

View File

@ -22,11 +22,13 @@ import com.google.common.base.Strings;
import org.elasticsearch.ElasticsearchException; import org.elasticsearch.ElasticsearchException;
import org.elasticsearch.action.index.IndexRequestBuilder; import org.elasticsearch.action.index.IndexRequestBuilder;
import org.elasticsearch.action.search.SearchPhaseExecutionException;
import org.elasticsearch.action.search.SearchResponse; import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.index.mapper.internal.FieldNamesFieldMapper; import org.elasticsearch.index.mapper.internal.FieldNamesFieldMapper;
import org.elasticsearch.index.mapper.internal.IndexFieldMapper; import org.elasticsearch.index.mapper.internal.IndexFieldMapper;
import org.elasticsearch.index.query.QueryBuilders; import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.script.Script; import org.elasticsearch.script.Script;
import org.elasticsearch.search.aggregations.AggregationExecutionException;
import org.elasticsearch.search.aggregations.Aggregator.SubAggCollectionMode; import org.elasticsearch.search.aggregations.Aggregator.SubAggCollectionMode;
import org.elasticsearch.search.aggregations.bucket.filter.Filter; import org.elasticsearch.search.aggregations.bucket.filter.Filter;
import org.elasticsearch.search.aggregations.bucket.histogram.Histogram; import org.elasticsearch.search.aggregations.bucket.histogram.Histogram;
@ -995,6 +997,36 @@ public class StringTermsIT extends AbstractTermsTestCase {
} }
} }
@Test
public void singleValuedField_OrderedByIllegalAgg() throws Exception {
boolean asc = true;
try {
client()
.prepareSearch("idx")
.setTypes("type")
.addAggregation(
terms("terms").executionHint(randomExecutionHint()).field(SINGLE_VALUED_FIELD_NAME)
.collectMode(randomFrom(SubAggCollectionMode.values()))
.order(Terms.Order.aggregation("inner_terms>avg", asc))
.subAggregation(terms("inner_terms").field(MULTI_VALUED_FIELD_NAME).subAggregation(avg("avg").field("i"))))
.execute().actionGet();
fail("Expected an exception");
} catch (SearchPhaseExecutionException e) {
ElasticsearchException[] rootCauses = e.guessRootCauses();
if (rootCauses.length == 1) {
ElasticsearchException rootCause = rootCauses[0];
if (rootCause instanceof AggregationExecutionException) {
AggregationExecutionException aggException = (AggregationExecutionException) rootCause;
assertThat(aggException.getMessage(), Matchers.startsWith("Invalid terms aggregation order path"));
} else {
throw e;
}
} else {
throw e;
}
}
}
@Test @Test
public void singleValuedField_OrderedBySingleBucketSubAggregationAsc() throws Exception { public void singleValuedField_OrderedBySingleBucketSubAggregationAsc() throws Exception {
boolean asc = randomBoolean(); boolean asc = randomBoolean();