Merge pull request #7937 from influxdata/js-7895-incorrect-calculations-math-with-aggregates

Fix incorrect math when aggregates that emit different times are used
pull/7938/head^2 v1.2.1-rc1
Jonathan A. Sternberg 2017-02-02 16:02:27 -06:00 committed by GitHub
commit d5ac69be6f
4 changed files with 763 additions and 374 deletions

View File

@ -7,6 +7,7 @@
- [#7910](https://github.com/influxdata/influxdb/issues/7910): Fix EvalType when a parenthesis expression is used.
- [#7929](https://github.com/influxdata/influxdb/issues/7929): Fix series tag iteration segfault. (#7922)
- [#7906](https://github.com/influxdata/influxdb/issues/7906): Anchors not working as expected with case-insensitive regex
- [#7895](https://github.com/influxdata/influxdb/issues/7895): Fix incorrect math when aggregates that emit different times are used.
## v1.2.0 [2017-01-24]

View File

@ -1684,6 +1684,15 @@ func TestServer_Query_SelectGroupByTimeDerivative(t *testing.T) {
cpu value=15 1278010021000000000
cpu value=20 1278010022000000000
cpu value=25 1278010023000000000
cpu0,host=server01 ticks=10,total=100 1278010020000000000
cpu0,host=server01 ticks=30,total=100 1278010021000000000
cpu0,host=server01 ticks=32,total=100 1278010022000000000
cpu0,host=server01 ticks=47,total=100 1278010023000000000
cpu0,host=server02 ticks=40,total=100 1278010020000000000
cpu0,host=server02 ticks=45,total=100 1278010021000000000
cpu0,host=server02 ticks=84,total=100 1278010022000000000
cpu0,host=server02 ticks=101,total=100 1278010023000000000
`)},
}
@ -1789,6 +1798,11 @@ cpu value=25 1278010023000000000
command: `SELECT derivative(percentile(value, 50), 4s) from db0.rp0.cpu where time >= '2010-07-01 18:47:00' and time <= '2010-07-01 18:47:03' group by time(2s)`,
exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu","columns":["time","derivative"],"values":[["2010-07-01T18:47:02Z",20]]}]}]}`,
},
&Query{
name: "calculate derivative of ticks divided by aggregate",
command: `SELECT non_negative_derivative(mean(ticks), 1s) / last(total) * 100 AS usage FROM db0.rp0.cpu0 WHERE time >= '2010-07-01 18:47:00' AND time <= '2010-07-01 18:47:03' GROUP BY host, time(1s)`,
exp: `{"results":[{"statement_id":0,"series":[{"name":"cpu0","tags":{"host":"server01"},"columns":["time","usage"],"values":[["2010-07-01T18:47:00Z",null],["2010-07-01T18:47:01Z",20],["2010-07-01T18:47:02Z",2],["2010-07-01T18:47:03Z",15]]},{"name":"cpu0","tags":{"host":"server02"},"columns":["time","usage"],"values":[["2010-07-01T18:47:00Z",null],["2010-07-01T18:47:01Z",5],["2010-07-01T18:47:02Z",39],["2010-07-01T18:47:03Z",17]]}]}]}`,
},
}...)
for i, query := range test.queries {

File diff suppressed because it is too large Load Diff

View File

@ -1259,30 +1259,10 @@ func (itr *{{$k.name}}{{if ne $k.Name $v.Name}}{{$v.Name}}{{end}}ExprIterator) C
func (itr *{{$k.name}}{{if ne $k.Name $v.Name}}{{$v.Name}}{{end}}ExprIterator) Next() (*{{$v.Name}}Point, error) {
for {
a, err := itr.left.Next()
if err != nil {
a, b, err := itr.next()
if err != nil || (a == nil && b == nil) {
return nil, err
}
b, err := itr.right.Next()
if err != nil {
return nil, err
}
if a == nil && b == nil {
return nil, nil
} else if itr.points == nil && (a == nil || b == nil ) {
return nil, nil
}
if a != nil && b != nil {
if a.Time > b.Time {
itr.left.unread(a)
a = nil
} else if a.Time < b.Time {
itr.right.unread(b)
b = nil
}
}
if a == nil || a.Nil {
if itr.points == nil {
@ -1336,6 +1316,48 @@ func (itr *{{$k.name}}{{if ne $k.Name $v.Name}}{{$v.Name}}{{end}}ExprIterator) N
}
}
// next returns the next points within each iterator. If the iterators are
// uneven, it organizes them so only matching points are returned.
func (itr *{{$k.name}}{{if ne $k.Name $v.Name}}{{$v.Name}}{{end}}ExprIterator) next() (a, b *{{$k.Name}}Point, err error) {
// Retrieve the next value for both the left and right.
a, err = itr.left.Next()
if err != nil {
return nil, nil, err
}
b, err = itr.right.Next()
if err != nil {
return nil, nil, err
}
// If we have a point from both, make sure that they match each other.
if a != nil && b != nil {
if a.Name > b.Name {
itr.left.unread(a)
return nil, b, nil
} else if a.Name < b.Name {
itr.right.unread(b)
return a, nil, nil
}
if ltags, rtags := a.Tags.ID(), b.Tags.ID(); ltags > rtags {
itr.left.unread(a)
return nil, b, nil
} else if ltags < rtags {
itr.right.unread(b)
return a, nil, nil
}
if a.Time > b.Time {
itr.left.unread(a)
return nil, b, nil
} else if a.Time < b.Time {
itr.right.unread(b)
return a, nil, nil
}
}
return a, b, nil
}
// {{$k.name}}{{if ne $k.Name $v.Name}}{{$v.Name}}{{end}}ExprFunc creates or modifies a point by combining two
// points. The point passed in may be modified and returned rather than
// allocating a new point if possible. One of the points may be nil, but at