Skip to content

Commit

Permalink
Allow derivative() function to be used with ORDER BY desc
Browse files Browse the repository at this point in the history
The derivative function had an arbitrary limitation that would cause it
to set the value to zero if the previous value was after the next value.
This caused all `ORDER BY desc` queries with `derivative()` to always
return zero values.

Fixes #4675.
  • Loading branch information
jsternberg committed Apr 20, 2016
1 parent 7ca9992 commit 095de6a
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 10 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
- [#3166](https://github.com/influxdata/influxdb/issues/3166): Sort the series keys inside of a tag set so output is deterministic.
- [#1856](https://github.com/influxdata/influxdb/issues/1856): Add `elapsed` function that returns the time delta between subsequent points.
- [#5502](https://github.com/influxdata/influxdb/issues/5502): Add checksum verification to TSM inspect tool
- [#4675](https://github.com/influxdata/influxdb/issues/4675): Allow derivative() function to be used with ORDER BY desc.

### Bugfixes

Expand Down
12 changes: 2 additions & 10 deletions influxql/functions.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,11 +98,7 @@ func (r *FloatDerivativeReducer) Emit() []FloatPoint {
if !r.ascending {
elapsed = -elapsed
}

value := 0.0
if elapsed > 0 {
value = diff / (float64(elapsed) / float64(r.interval.Duration))
}
value := diff / (float64(elapsed) / float64(r.interval.Duration))

// Drop negative values for non-negative derivatives.
if r.isNonNegative && diff < 0 {
Expand Down Expand Up @@ -149,11 +145,7 @@ func (r *IntegerDerivativeReducer) Emit() []FloatPoint {
if !r.ascending {
elapsed = -elapsed
}

value := 0.0
if elapsed > 0 {
value = diff / (float64(elapsed) / float64(r.interval.Duration))
}
value := diff / (float64(elapsed) / float64(r.interval.Duration))

// Drop negative values for non-negative derivatives.
if r.isNonNegative && diff < 0 {
Expand Down
48 changes: 48 additions & 0 deletions influxql/select_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1895,6 +1895,54 @@ func TestSelect_Derivative_Integer(t *testing.T) {
}
}

func TestSelect_Derivative_Desc_Float(t *testing.T) {
var ic IteratorCreator
ic.CreateIteratorFn = func(opt influxql.IteratorOptions) (influxql.Iterator, error) {
return &FloatIterator{Points: []influxql.FloatPoint{
{Name: "cpu", Time: 12 * Second, Value: 3},
{Name: "cpu", Time: 8 * Second, Value: 19},
{Name: "cpu", Time: 4 * Second, Value: 10},
{Name: "cpu", Time: 0 * Second, Value: 20},
}}, nil
}

// Execute selection.
itrs, err := influxql.Select(MustParseSelectStatement(`SELECT derivative(value, 1s) FROM cpu WHERE time >= '1970-01-01T00:00:00Z' AND time < '1970-01-01T00:00:16Z' ORDER BY desc`), &ic, nil)
if err != nil {
t.Fatal(err)
} else if a := Iterators(itrs).ReadAll(); !deep.Equal(a, [][]influxql.Point{
{&influxql.FloatPoint{Name: "cpu", Time: 8 * Second, Value: 4}},
{&influxql.FloatPoint{Name: "cpu", Time: 4 * Second, Value: -2.25}},
{&influxql.FloatPoint{Name: "cpu", Time: 0 * Second, Value: 2.5}},
}) {
t.Fatalf("unexpected points: %s", spew.Sdump(a))
}
}

func TestSelect_Derivative_Desc_Integer(t *testing.T) {
var ic IteratorCreator
ic.CreateIteratorFn = func(opt influxql.IteratorOptions) (influxql.Iterator, error) {
return &IntegerIterator{Points: []influxql.IntegerPoint{
{Name: "cpu", Time: 12 * Second, Value: 3},
{Name: "cpu", Time: 8 * Second, Value: 19},
{Name: "cpu", Time: 4 * Second, Value: 10},
{Name: "cpu", Time: 0 * Second, Value: 20},
}}, nil
}

// Execute selection.
itrs, err := influxql.Select(MustParseSelectStatement(`SELECT derivative(value, 1s) FROM cpu WHERE time >= '1970-01-01T00:00:00Z' AND time < '1970-01-01T00:00:16Z' ORDER BY desc`), &ic, nil)
if err != nil {
t.Fatal(err)
} else if a := Iterators(itrs).ReadAll(); !deep.Equal(a, [][]influxql.Point{
{&influxql.FloatPoint{Name: "cpu", Time: 8 * Second, Value: 4}},
{&influxql.FloatPoint{Name: "cpu", Time: 4 * Second, Value: -2.25}},
{&influxql.FloatPoint{Name: "cpu", Time: 0 * Second, Value: 2.5}},
}) {
t.Fatalf("unexpected points: %s", spew.Sdump(a))
}
}

func TestSelect_Difference_Float(t *testing.T) {
var ic IteratorCreator
ic.CreateIteratorFn = func(opt influxql.IteratorOptions) (influxql.Iterator, error) {
Expand Down

0 comments on commit 095de6a

Please sign in to comment.