fix #405. Percentile shouldn't crash for small number of values

pull/310/head
John Shahid 2014-04-04 13:37:48 -04:00
parent 7fc300d1b4
commit 06f4cdde31
3 changed files with 35 additions and 10 deletions

View File

@ -364,4 +364,5 @@
- [Issue #398](https://github.com/influxdb/influxdb/issues/398). Support now() and NOW() in the query lang
- [Issue #403](https://github.com/influxdb/influxdb/issues/403). Filtering should work with join queries
- [Issue #404](https://github.com/influxdb/influxdb/issues/404). Filtering with invalid condition shouldn't crash the server
- [Issue #405](https://github.com/influxdb/influxdb/issues/405). Percentile shouldn't crash for small number of values
- Close leveldb databases properly if we couldn't create a new Shard. See leveldb\_shard\_datastore\_test:131

View File

@ -806,22 +806,22 @@ func (self *PercentileAggregator) ColumnNames() []string {
}
func (self *PercentileAggregator) GetValues(series string, group interface{}) [][]*protocol.FieldValue {
returnValues := [][]*protocol.FieldValue{}
values := self.float_values[series][group]
if len(values) == 0 {
returnValues = append(returnValues, []*protocol.FieldValue{self.defaultValue})
}
sort.Float64s(values)
length := len(values)
index := int(math.Floor(float64(length)*self.percentile/100.0+0.5)) - 1
point := values[index]
returnValues = append(returnValues, []*protocol.FieldValue{
&protocol.FieldValue{DoubleValue: &point},
})
return returnValues
if index < 0 || index >= len(values) {
return [][]*protocol.FieldValue{
[]*protocol.FieldValue{self.defaultValue},
}
}
point := values[index]
return [][]*protocol.FieldValue{
[]*protocol.FieldValue{&protocol.FieldValue{DoubleValue: &point}},
}
}
func NewPercentileAggregator(_ *parser.SelectQuery, value *parser.Value, defaultValue *parser.Value) (Aggregator, error) {

View File

@ -868,6 +868,30 @@ func (self *EngineSuite) TestPercentileQueryWithGroupByTime(c *C) {
]`)
}
// issue #405
func (self *EngineSuite) TestLowPercentileForOnePointShouldNotCrash(c *C) {
// make the mock coordinator return some data
self.createEngine(c, `[
{
"points": [
{ "values": [{ "int64_value": 1 }], "timestamp": 1381346701000000 }
],
"name": "foo",
"fields": ["column_one"]
}
]`)
self.runQuery("select percentile(column_one, 40) from foo group by time(1m)", c, `[
{
"points": [
{ "values": [{ "double_value": 0 }], "timestamp": 1381346700000000}
],
"name": "foo",
"fields": ["percentile"]
}
]`)
}
func (self *EngineSuite) TestCountDistinct(c *C) {
// make the mock coordinator return some data
self.createEngine(c, `[