diff --git a/CHANGELOG.md b/CHANGELOG.md index 6708fd2d77..557c5d9461 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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] diff --git a/cmd/influxd/run/server_test.go b/cmd/influxd/run/server_test.go index 74d63977de..79e976dac8 100644 --- a/cmd/influxd/run/server_test.go +++ b/cmd/influxd/run/server_test.go @@ -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 { diff --git a/influxql/iterator.gen.go b/influxql/iterator.gen.go index 9ebb5d712b..665b2f838d 100644 --- a/influxql/iterator.gen.go +++ b/influxql/iterator.gen.go @@ -1258,30 +1258,10 @@ func (itr *floatExprIterator) Close() error { func (itr *floatExprIterator) Next() (*FloatPoint, 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 { @@ -1322,6 +1302,48 @@ func (itr *floatExprIterator) Next() (*FloatPoint, error) { } } +// next returns the next points within each iterator. If the iterators are +// uneven, it organizes them so only matching points are returned. +func (itr *floatExprIterator) next() (a, b *FloatPoint, 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 +} + // floatExprFunc 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 @@ -1598,30 +1620,10 @@ func (itr *floatIntegerExprIterator) Close() error { func (itr *floatIntegerExprIterator) Next() (*IntegerPoint, 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 { @@ -1666,6 +1668,48 @@ func (itr *floatIntegerExprIterator) Next() (*IntegerPoint, error) { } } +// next returns the next points within each iterator. If the iterators are +// uneven, it organizes them so only matching points are returned. +func (itr *floatIntegerExprIterator) next() (a, b *FloatPoint, 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 +} + // floatIntegerExprFunc 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 @@ -1942,30 +1986,10 @@ func (itr *floatStringExprIterator) Close() error { func (itr *floatStringExprIterator) Next() (*StringPoint, 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 { @@ -2010,6 +2034,48 @@ func (itr *floatStringExprIterator) Next() (*StringPoint, error) { } } +// next returns the next points within each iterator. If the iterators are +// uneven, it organizes them so only matching points are returned. +func (itr *floatStringExprIterator) next() (a, b *FloatPoint, 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 +} + // floatStringExprFunc 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 @@ -2286,30 +2352,10 @@ func (itr *floatBooleanExprIterator) Close() error { func (itr *floatBooleanExprIterator) Next() (*BooleanPoint, 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 { @@ -2354,6 +2400,48 @@ func (itr *floatBooleanExprIterator) Next() (*BooleanPoint, error) { } } +// next returns the next points within each iterator. If the iterators are +// uneven, it organizes them so only matching points are returned. +func (itr *floatBooleanExprIterator) next() (a, b *FloatPoint, 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 +} + // floatBooleanExprFunc 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 @@ -3798,30 +3886,10 @@ func (itr *integerFloatExprIterator) Close() error { func (itr *integerFloatExprIterator) Next() (*FloatPoint, 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 { @@ -3866,6 +3934,48 @@ func (itr *integerFloatExprIterator) Next() (*FloatPoint, error) { } } +// next returns the next points within each iterator. If the iterators are +// uneven, it organizes them so only matching points are returned. +func (itr *integerFloatExprIterator) next() (a, b *IntegerPoint, 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 +} + // integerFloatExprFunc 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 @@ -4142,30 +4252,10 @@ func (itr *integerExprIterator) Close() error { func (itr *integerExprIterator) Next() (*IntegerPoint, 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 { @@ -4206,6 +4296,48 @@ func (itr *integerExprIterator) Next() (*IntegerPoint, error) { } } +// next returns the next points within each iterator. If the iterators are +// uneven, it organizes them so only matching points are returned. +func (itr *integerExprIterator) next() (a, b *IntegerPoint, 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 +} + // integerExprFunc 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 @@ -4482,30 +4614,10 @@ func (itr *integerStringExprIterator) Close() error { func (itr *integerStringExprIterator) Next() (*StringPoint, 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 { @@ -4550,6 +4662,48 @@ func (itr *integerStringExprIterator) Next() (*StringPoint, error) { } } +// next returns the next points within each iterator. If the iterators are +// uneven, it organizes them so only matching points are returned. +func (itr *integerStringExprIterator) next() (a, b *IntegerPoint, 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 +} + // integerStringExprFunc 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 @@ -4826,30 +4980,10 @@ func (itr *integerBooleanExprIterator) Close() error { func (itr *integerBooleanExprIterator) Next() (*BooleanPoint, 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 { @@ -4894,6 +5028,48 @@ func (itr *integerBooleanExprIterator) Next() (*BooleanPoint, error) { } } +// next returns the next points within each iterator. If the iterators are +// uneven, it organizes them so only matching points are returned. +func (itr *integerBooleanExprIterator) next() (a, b *IntegerPoint, 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 +} + // integerBooleanExprFunc 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 @@ -6323,30 +6499,10 @@ func (itr *stringFloatExprIterator) Close() error { func (itr *stringFloatExprIterator) Next() (*FloatPoint, 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 { @@ -6391,6 +6547,48 @@ func (itr *stringFloatExprIterator) Next() (*FloatPoint, error) { } } +// next returns the next points within each iterator. If the iterators are +// uneven, it organizes them so only matching points are returned. +func (itr *stringFloatExprIterator) next() (a, b *StringPoint, 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 +} + // stringFloatExprFunc 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 @@ -6667,30 +6865,10 @@ func (itr *stringIntegerExprIterator) Close() error { func (itr *stringIntegerExprIterator) Next() (*IntegerPoint, 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 { @@ -6735,6 +6913,48 @@ func (itr *stringIntegerExprIterator) Next() (*IntegerPoint, error) { } } +// next returns the next points within each iterator. If the iterators are +// uneven, it organizes them so only matching points are returned. +func (itr *stringIntegerExprIterator) next() (a, b *StringPoint, 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 +} + // stringIntegerExprFunc 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 @@ -7011,30 +7231,10 @@ func (itr *stringExprIterator) Close() error { func (itr *stringExprIterator) Next() (*StringPoint, 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 { @@ -7075,6 +7275,48 @@ func (itr *stringExprIterator) Next() (*StringPoint, error) { } } +// next returns the next points within each iterator. If the iterators are +// uneven, it organizes them so only matching points are returned. +func (itr *stringExprIterator) next() (a, b *StringPoint, 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 +} + // stringExprFunc 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 @@ -7351,30 +7593,10 @@ func (itr *stringBooleanExprIterator) Close() error { func (itr *stringBooleanExprIterator) Next() (*BooleanPoint, 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 { @@ -7419,6 +7641,48 @@ func (itr *stringBooleanExprIterator) Next() (*BooleanPoint, error) { } } +// next returns the next points within each iterator. If the iterators are +// uneven, it organizes them so only matching points are returned. +func (itr *stringBooleanExprIterator) next() (a, b *StringPoint, 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 +} + // stringBooleanExprFunc 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 @@ -8848,30 +9112,10 @@ func (itr *booleanFloatExprIterator) Close() error { func (itr *booleanFloatExprIterator) Next() (*FloatPoint, 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 { @@ -8916,6 +9160,48 @@ func (itr *booleanFloatExprIterator) Next() (*FloatPoint, error) { } } +// next returns the next points within each iterator. If the iterators are +// uneven, it organizes them so only matching points are returned. +func (itr *booleanFloatExprIterator) next() (a, b *BooleanPoint, 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 +} + // booleanFloatExprFunc 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 @@ -9192,30 +9478,10 @@ func (itr *booleanIntegerExprIterator) Close() error { func (itr *booleanIntegerExprIterator) Next() (*IntegerPoint, 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 { @@ -9260,6 +9526,48 @@ func (itr *booleanIntegerExprIterator) Next() (*IntegerPoint, error) { } } +// next returns the next points within each iterator. If the iterators are +// uneven, it organizes them so only matching points are returned. +func (itr *booleanIntegerExprIterator) next() (a, b *BooleanPoint, 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 +} + // booleanIntegerExprFunc 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 @@ -9536,30 +9844,10 @@ func (itr *booleanStringExprIterator) Close() error { func (itr *booleanStringExprIterator) Next() (*StringPoint, 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 { @@ -9604,6 +9892,48 @@ func (itr *booleanStringExprIterator) Next() (*StringPoint, error) { } } +// next returns the next points within each iterator. If the iterators are +// uneven, it organizes them so only matching points are returned. +func (itr *booleanStringExprIterator) next() (a, b *BooleanPoint, 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 +} + // booleanStringExprFunc 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 @@ -9880,30 +10210,10 @@ func (itr *booleanExprIterator) Close() error { func (itr *booleanExprIterator) Next() (*BooleanPoint, 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 { @@ -9944,6 +10254,48 @@ func (itr *booleanExprIterator) Next() (*BooleanPoint, error) { } } +// next returns the next points within each iterator. If the iterators are +// uneven, it organizes them so only matching points are returned. +func (itr *booleanExprIterator) next() (a, b *BooleanPoint, 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 +} + // booleanExprFunc 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 diff --git a/influxql/iterator.gen.go.tmpl b/influxql/iterator.gen.go.tmpl index ce12a9b326..61d32c46af 100644 --- a/influxql/iterator.gen.go.tmpl +++ b/influxql/iterator.gen.go.tmpl @@ -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