diff --git a/CHANGELOG.md b/CHANGELOG.md index 8cab7e1683..3235bc723c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ ### Bugfixes - [3013](https://github.com/influxdb/influxdb/issues/3013): Panic error with inserting values with commas +- [#2956](https://github.com/influxdb/influxdb/issues/2956): Type mismatch in derivative - [#2908](https://github.com/influxdb/influxdb/issues/2908): Field mismatch error messages need to be updated - [#2931](https://github.com/influxdb/influxdb/pull/2931): Services and reporting should wait until cluster has leader. - [#2943](https://github.com/influxdb/influxdb/issues/2943): Ensure default retention policies are fully replicated diff --git a/influxql/engine.go b/influxql/engine.go index 7f4bb8c37e..7ebdb57e18 100644 --- a/influxql/engine.go +++ b/influxql/engine.go @@ -3,6 +3,7 @@ package influxql import ( "bytes" "errors" + "fmt" "hash/fnv" "math" "sort" @@ -408,7 +409,8 @@ func (m *MapReduceJob) processRawQueryDerivative(lastValueFromPreviousChunk *raw // Calculate the derivative of successive points by dividing the difference // of each value by the elapsed time normalized to the interval - diff := v.Values.(float64) - lastValueFromPreviousChunk.Values.(float64) + diff := i64tof64(v.Values) - i64tof64(lastValueFromPreviousChunk.Values) + elapsed := v.Time - lastValueFromPreviousChunk.Time value := 0.0 @@ -468,7 +470,7 @@ func (m *MapReduceJob) processDerivative(results [][]interface{}) [][]interface{ } elapsed := cur[0].(time.Time).Sub(prev[0].(time.Time)) - diff := cur[1].(float64) - prev[1].(float64) + diff := i64tof64(cur[1]) - i64tof64(prev[1]) value := 0.0 if elapsed > 0 { value = float64(diff) / (float64(elapsed) / float64(m.derivativeInterval())) @@ -930,6 +932,16 @@ func (e *Executor) execute(out chan *Row) { close(out) } +func i64tof64(v interface{}) float64 { + switch v.(type) { + case int64: + return float64(v.(int64)) + case float64: + return v.(float64) + } + panic(fmt.Sprintf("expected either int64 or float64, got %v", v)) +} + // Row represents a single row returned from the execution of a statement. type Row struct { Name string `json:"name,omitempty"` diff --git a/influxql/engine_test.go b/influxql/engine_test.go index fc9dd14fb6..9cdd696c64 100644 --- a/influxql/engine_test.go +++ b/influxql/engine_test.go @@ -206,6 +206,36 @@ func TestProcessDerivative(t *testing.T) { }, }, }, + { + name: "float derivatives", + fn: "derivative", + interval: "1d", + in: [][]interface{}{ + []interface{}{ + time.Unix(0, 0), 1.0, + }, + []interface{}{ + time.Unix(0, 0).Add(24 * time.Hour), int64(3), + }, + []interface{}{ + time.Unix(0, 0).Add(48 * time.Hour), int64(5), + }, + []interface{}{ + time.Unix(0, 0).Add(72 * time.Hour), int64(9), + }, + }, + exp: [][]interface{}{ + []interface{}{ + time.Unix(0, 0).Add(24 * time.Hour), 2.0, + }, + []interface{}{ + time.Unix(0, 0).Add(48 * time.Hour), 2.0, + }, + []interface{}{ + time.Unix(0, 0).Add(72 * time.Hour), 4.0, + }, + }, + }, } for _, test := range tests {