diff --git a/CHANGELOG.md b/CHANGELOG.md index f680e887614..442e9dfe8b5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -154,6 +154,7 @@ - [Issue #90](https://github.com/influxdb/influxdb/issues/90). Group by multiple columns panic - [Issue #89](https://github.com/influxdb/influxdb/issues/89). 'Group by' combined with 'where' not working +- [Issue #106](https://github.com/influxdb/influxdb/issues/106). Don't panic if we only see one point and can't calculate derivative ### Deprecated diff --git a/src/engine/aggregator.go b/src/engine/aggregator.go index 7b110be98f0..387b2f23780 100644 --- a/src/engine/aggregator.go +++ b/src/engine/aggregator.go @@ -225,15 +225,18 @@ func (self *DerivativeAggregator) GetValues(series string, group interface{}) [] oldValue := self.firstValues[series][group] newValue := self.lastValues[series][group] - // if an old value exist, then compute the derivative and insert it in the points slice - deltaT := float64(*newValue.Timestamp-*oldValue.Timestamp) / float64(time.Second/time.Microsecond) - deltaV := *newValue.Values[self.fieldIndex].DoubleValue - *oldValue.Values[self.fieldIndex].DoubleValue - derivative := deltaV / deltaT - return [][]*protocol.FieldValue{ - []*protocol.FieldValue{ - &protocol.FieldValue{DoubleValue: &derivative}, - }, + if newValue != nil { + // if an old value exist, then compute the derivative and insert it in the points slice + deltaT := float64(*newValue.Timestamp-*oldValue.Timestamp) / float64(time.Second/time.Microsecond) + deltaV := *newValue.Values[self.fieldIndex].DoubleValue - *oldValue.Values[self.fieldIndex].DoubleValue + derivative := deltaV / deltaT + return [][]*protocol.FieldValue{ + []*protocol.FieldValue{ + &protocol.FieldValue{DoubleValue: &derivative}, + }, + } } + return [][]*protocol.FieldValue{} } func NewDerivativeAggregator(q *parser.Query, v *parser.Value) (Aggregator, error) { diff --git a/src/engine/engine_test.go b/src/engine/engine_test.go index f0ee9978278..d091ae2683d 100644 --- a/src/engine/engine_test.go +++ b/src/engine/engine_test.go @@ -1116,6 +1116,26 @@ func (self *EngineSuite) TestDerivativeQuery(c *C) { ]`) } +func (self *EngineSuite) TestDerivativeQueryWithOnePoint(c *C) { + engine := createEngine(c, `[ + { + "points": [ + { "values": [{ "int64_value": 1 }], "timestamp": 1381347700000000, "sequence_number": 1 } + ], + "name": "foo", + "fields": ["column_one"] + } + ]`) + + runQuery(engine, "select derivative(column_one) from foo", c, `[ + { + "points": [], + "name": "foo", + "fields": ["derivative"] + } + ]`) +} + func (self *EngineSuite) TestDistinctQuery(c *C) { engine := createEngine(c, `[ { diff --git a/src/integration/benchmark_test.go b/src/integration/benchmark_test.go index 7ec808373a3..c2825c6e8fe 100644 --- a/src/integration/benchmark_test.go +++ b/src/integration/benchmark_test.go @@ -592,6 +592,28 @@ func (self *IntegrationSuite) TestHttpPostWithTime(c *C) { c.Assert(values["val2"], Equals, 2.0) } +// test for issue #106 +func (self *IntegrationSuite) TestIssue106(c *C) { + err := self.server.WriteData(` +[ + { + "name": "test_issue_106", + "columns": ["time", "a"], + "points":[ + [1386262529794, 2] + ] + } +]`, "time_precision=m") + c.Assert(err, IsNil) + bs, err := self.server.RunQuery("select derivative(a) from test_issue_106") + c.Assert(err, IsNil) + data := []*h.SerializedSeries{} + err = json.Unmarshal(bs, &data) + c.Assert(data, HasLen, 1) + c.Assert(data[0].Columns, HasLen, 3) + c.Assert(data[0].Points, HasLen, 0) +} + // test for issue #41 func (self *IntegrationSuite) TestDbDelete(c *C) { err := self.server.WriteData(`