Skip to content

Commit

Permalink
Aggregations: Prevent negative intervals in date_histogram
Browse files Browse the repository at this point in the history
Negative settings for interval in date_histogram could lead to OOM errors in conjunction
with min_doc_count=0. This fix raises exceptions in the histogram builder and the
 TimeZoneRounding classes so that the query fails before this can happen.

Closes #9634
Closes #9690
  • Loading branch information
Christoph Büscher committed Feb 13, 2015
1 parent 2869c02 commit 242b69c
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 3 deletions.
Expand Up @@ -19,6 +19,7 @@

package org.elasticsearch.common.rounding;

import org.elasticsearch.ElasticsearchIllegalArgumentException;
import org.elasticsearch.common.io.stream.StreamInput;
import org.elasticsearch.common.io.stream.StreamOutput;
import org.elasticsearch.common.unit.TimeValue;
Expand Down Expand Up @@ -63,6 +64,8 @@ public Builder(DateTimeUnit unit) {

public Builder(TimeValue interval) {
this.unit = null;
if (interval.millis() < 1)
throw new ElasticsearchIllegalArgumentException("Zero or negative time interval not supported");
this.interval = interval.millis();
}

Expand Down Expand Up @@ -309,6 +312,8 @@ static class UTCIntervalTimeZoneRounding extends TimeZoneRounding {
}

UTCIntervalTimeZoneRounding(long interval) {
if (interval < 1)
throw new ElasticsearchIllegalArgumentException("Zero or negative time interval not supported");
this.interval = interval;
}

Expand Down Expand Up @@ -356,6 +361,8 @@ static class TimeIntervalTimeZoneRounding extends TimeZoneRounding {
}

TimeIntervalTimeZoneRounding(long interval, DateTimeZone preTz, DateTimeZone postTz) {
if (interval < 1)
throw new ElasticsearchIllegalArgumentException("Zero or negative time interval not supported");
this.interval = interval;
this.preTz = preTz;
this.postTz = postTz;
Expand Down Expand Up @@ -414,6 +421,8 @@ static class DayIntervalTimeZoneRounding extends TimeZoneRounding {
}

DayIntervalTimeZoneRounding(long interval, DateTimeZone preTz, DateTimeZone postTz) {
if (interval < 1)
throw new ElasticsearchIllegalArgumentException("Zero or negative time interval not supported");
this.interval = interval;
this.preTz = preTz;
this.postTz = postTz;
Expand Down
Expand Up @@ -118,7 +118,7 @@ public AggregatorFactory parse(String aggregationName, XContentParser parser, Se
}
}

if (interval < 0) {
if (interval < 1) {
throw new SearchParseException(context, "Missing required field [interval] for histogram aggregation [" + aggregationName + "]");
}

Expand Down
Expand Up @@ -19,6 +19,7 @@
package org.elasticsearch.search.aggregations.bucket;

import org.elasticsearch.action.index.IndexRequestBuilder;
import org.elasticsearch.action.search.SearchPhaseExecutionException;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.common.joda.Joda;
import org.elasticsearch.common.settings.ImmutableSettings;
Expand All @@ -43,13 +44,13 @@
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.concurrent.TimeUnit;

import static org.elasticsearch.common.xcontent.XContentFactory.jsonBuilder;
import static org.elasticsearch.index.query.QueryBuilders.matchAllQuery;
import static org.elasticsearch.search.aggregations.AggregationBuilders.*;
import static org.elasticsearch.test.hamcrest.ElasticsearchAssertions.assertSearchResponse;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.*;
import static org.hamcrest.core.IsNull.notNullValue;

/**
Expand Down Expand Up @@ -1261,4 +1262,18 @@ public void testIssue6965() {
assertThat(bucket.getKeyAsNumber().longValue(), equalTo(key.getMillis()));
assertThat(bucket.getDocCount(), equalTo(3l));
}

/**
* see issue #9634, negative interval in date_histogram should raise exception
*/
public void testExeptionOnNegativerInterval() {
try {
client().prepareSearch("idx")
.addAggregation(dateHistogram("histo").field("date").interval(-TimeUnit.DAYS.toMillis(1)).minDocCount(0)).execute()
.actionGet();
fail();
} catch (SearchPhaseExecutionException e) {
assertThat(e.getMessage(), containsString("IllegalArgumentException"));
}
}
}
Expand Up @@ -20,6 +20,7 @@

import com.carrotsearch.hppc.LongOpenHashSet;
import org.elasticsearch.action.index.IndexRequestBuilder;
import org.elasticsearch.action.search.SearchPhaseExecutionException;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.search.aggregations.Aggregator.SubAggCollectionMode;
import org.elasticsearch.search.aggregations.bucket.filter.Filter;
Expand Down Expand Up @@ -941,4 +942,17 @@ public void singleValuedField_WithExtendedBounds() throws Exception {
}
}

/**
* see issue #9634, negative interval in histogram should raise exception
*/
public void testExeptionOnNegativerInterval() {
try {
client().prepareSearch("empty_bucket_idx")
.addAggregation(histogram("histo").field(SINGLE_VALUED_FIELD_NAME).interval(-1).minDocCount(0)).execute().actionGet();
fail();
} catch (SearchPhaseExecutionException e) {
assertThat(e.getMessage(), containsString("Missing required field [interval]"));
}
}

}

0 comments on commit 242b69c

Please sign in to comment.