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 22, 2016
1 parent b14ae2f commit 9b6d5df
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 10 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
- [#6444](https://github.com/influxdata/influxdb/pull/6444): Allow setting the config path through an environment variable and default config path.
- [#3558](https://github.com/influxdata/influxdb/issues/3558): Support field math inside a WHERE clause.
- [#6429](https://github.com/influxdata/influxdb/issues/6429): Log slow queries if they pass a configurable threshold.
- [#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
52 changes: 52 additions & 0 deletions influxql/select_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1975,6 +1975,58 @@ 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, err := Iterators(itrs).ReadAll(); err != nil {
t.Errorf("unexpected error: %s", err)
} else if !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, err := Iterators(itrs).ReadAll(); err != nil {
t.Errorf("unexpected error: %s", err)
} else if !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 9b6d5df

Please sign in to comment.