Make binary expressions with either point being nil return a nil point

This also fixes integer to float and float/integer to boolean binary
expressions to correctly work with nil points at all.

Related to #5973.
pull/6005/head
Jonathan A. Sternberg 2016-03-14 13:26:38 -04:00
parent 5182b59ee4
commit 94916082c9
4 changed files with 575 additions and 219 deletions

View File

@ -802,6 +802,35 @@ func (itr *floatReduceFloatIterator) reduce() []FloatPoint {
return a
}
// floatExprIterator executes a function to modify an existing point
// for every output of the input iterator.
type floatExprIterator struct {
left *bufFloatIterator
right *bufFloatIterator
fn floatExprFunc
}
func (itr *floatExprIterator) Close() error {
itr.left.Close()
itr.right.Close()
return nil
}
func (itr *floatExprIterator) Next() *FloatPoint {
a := itr.left.Next()
b := itr.right.Next()
if a == nil && b == nil {
return nil
}
return itr.fn(a, b)
}
// 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
// least one of the points will be non-nil.
type floatExprFunc func(a *FloatPoint, b *FloatPoint) *FloatPoint
// floatReduceIntegerIterator executes a reducer for every interval and buffers the result.
type floatReduceIntegerIterator struct {
input *bufFloatIterator
@ -896,6 +925,35 @@ func (itr *floatReduceIntegerIterator) reduce() []IntegerPoint {
return a
}
// floatIntegerExprIterator executes a function to modify an existing point
// for every output of the input iterator.
type floatIntegerExprIterator struct {
left *bufFloatIterator
right *bufFloatIterator
fn floatIntegerExprFunc
}
func (itr *floatIntegerExprIterator) Close() error {
itr.left.Close()
itr.right.Close()
return nil
}
func (itr *floatIntegerExprIterator) Next() *IntegerPoint {
a := itr.left.Next()
b := itr.right.Next()
if a == nil && b == nil {
return nil
}
return itr.fn(a, b)
}
// 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
// least one of the points will be non-nil.
type floatIntegerExprFunc func(a *FloatPoint, b *FloatPoint) *IntegerPoint
// floatReduceStringIterator executes a reducer for every interval and buffers the result.
type floatReduceStringIterator struct {
input *bufFloatIterator
@ -990,6 +1048,35 @@ func (itr *floatReduceStringIterator) reduce() []StringPoint {
return a
}
// floatStringExprIterator executes a function to modify an existing point
// for every output of the input iterator.
type floatStringExprIterator struct {
left *bufFloatIterator
right *bufFloatIterator
fn floatStringExprFunc
}
func (itr *floatStringExprIterator) Close() error {
itr.left.Close()
itr.right.Close()
return nil
}
func (itr *floatStringExprIterator) Next() *StringPoint {
a := itr.left.Next()
b := itr.right.Next()
if a == nil && b == nil {
return nil
}
return itr.fn(a, b)
}
// 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
// least one of the points will be non-nil.
type floatStringExprFunc func(a *FloatPoint, b *FloatPoint) *StringPoint
// floatReduceBooleanIterator executes a reducer for every interval and buffers the result.
type floatReduceBooleanIterator struct {
input *bufFloatIterator
@ -1084,6 +1171,35 @@ func (itr *floatReduceBooleanIterator) reduce() []BooleanPoint {
return a
}
// floatBooleanExprIterator executes a function to modify an existing point
// for every output of the input iterator.
type floatBooleanExprIterator struct {
left *bufFloatIterator
right *bufFloatIterator
fn floatBooleanExprFunc
}
func (itr *floatBooleanExprIterator) Close() error {
itr.left.Close()
itr.right.Close()
return nil
}
func (itr *floatBooleanExprIterator) Next() *BooleanPoint {
a := itr.left.Next()
b := itr.right.Next()
if a == nil && b == nil {
return nil
}
return itr.fn(a, b)
}
// 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
// least one of the points will be non-nil.
type floatBooleanExprFunc func(a *FloatPoint, b *FloatPoint) *BooleanPoint
// floatTransformIterator executes a function to modify an existing point for every
// output of the input iterator.
type floatTransformIterator struct {
@ -1132,35 +1248,6 @@ func (itr *floatBoolTransformIterator) Next() *BooleanPoint {
// new point if possible.
type floatBoolTransformFunc func(p *FloatPoint) *BooleanPoint
// floatCombineTransformIterator executes a function to modify an existing point for every
// output of the input iterator.
type floatCombineTransformIterator struct {
left *bufFloatIterator
right *bufFloatIterator
fn floatCombineTransformFunc
}
func (itr *floatCombineTransformIterator) Close() error {
itr.left.Close()
itr.right.Close()
return nil
}
func (itr *floatCombineTransformIterator) Next() *FloatPoint {
a := itr.left.Next()
b := itr.right.Next()
if a == nil && b == nil {
return nil
}
return itr.fn(a, b)
}
// floatCombineTransformFunc 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 least one of the points will be non-nil.
type floatCombineTransformFunc func(a *FloatPoint, b *FloatPoint) *FloatPoint
// floatDedupeIterator only outputs unique points.
// This differs from the DistinctIterator in that it compares all aux fields too.
// This iterator is relatively inefficient and should only be used on small
@ -2032,6 +2119,35 @@ func (itr *integerReduceFloatIterator) reduce() []FloatPoint {
return a
}
// integerFloatExprIterator executes a function to modify an existing point
// for every output of the input iterator.
type integerFloatExprIterator struct {
left *bufIntegerIterator
right *bufIntegerIterator
fn integerFloatExprFunc
}
func (itr *integerFloatExprIterator) Close() error {
itr.left.Close()
itr.right.Close()
return nil
}
func (itr *integerFloatExprIterator) Next() *FloatPoint {
a := itr.left.Next()
b := itr.right.Next()
if a == nil && b == nil {
return nil
}
return itr.fn(a, b)
}
// 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
// least one of the points will be non-nil.
type integerFloatExprFunc func(a *IntegerPoint, b *IntegerPoint) *FloatPoint
// integerReduceIntegerIterator executes a reducer for every interval and buffers the result.
type integerReduceIntegerIterator struct {
input *bufIntegerIterator
@ -2126,6 +2242,35 @@ func (itr *integerReduceIntegerIterator) reduce() []IntegerPoint {
return a
}
// integerExprIterator executes a function to modify an existing point
// for every output of the input iterator.
type integerExprIterator struct {
left *bufIntegerIterator
right *bufIntegerIterator
fn integerExprFunc
}
func (itr *integerExprIterator) Close() error {
itr.left.Close()
itr.right.Close()
return nil
}
func (itr *integerExprIterator) Next() *IntegerPoint {
a := itr.left.Next()
b := itr.right.Next()
if a == nil && b == nil {
return nil
}
return itr.fn(a, b)
}
// 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
// least one of the points will be non-nil.
type integerExprFunc func(a *IntegerPoint, b *IntegerPoint) *IntegerPoint
// integerReduceStringIterator executes a reducer for every interval and buffers the result.
type integerReduceStringIterator struct {
input *bufIntegerIterator
@ -2220,6 +2365,35 @@ func (itr *integerReduceStringIterator) reduce() []StringPoint {
return a
}
// integerStringExprIterator executes a function to modify an existing point
// for every output of the input iterator.
type integerStringExprIterator struct {
left *bufIntegerIterator
right *bufIntegerIterator
fn integerStringExprFunc
}
func (itr *integerStringExprIterator) Close() error {
itr.left.Close()
itr.right.Close()
return nil
}
func (itr *integerStringExprIterator) Next() *StringPoint {
a := itr.left.Next()
b := itr.right.Next()
if a == nil && b == nil {
return nil
}
return itr.fn(a, b)
}
// 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
// least one of the points will be non-nil.
type integerStringExprFunc func(a *IntegerPoint, b *IntegerPoint) *StringPoint
// integerReduceBooleanIterator executes a reducer for every interval and buffers the result.
type integerReduceBooleanIterator struct {
input *bufIntegerIterator
@ -2314,6 +2488,35 @@ func (itr *integerReduceBooleanIterator) reduce() []BooleanPoint {
return a
}
// integerBooleanExprIterator executes a function to modify an existing point
// for every output of the input iterator.
type integerBooleanExprIterator struct {
left *bufIntegerIterator
right *bufIntegerIterator
fn integerBooleanExprFunc
}
func (itr *integerBooleanExprIterator) Close() error {
itr.left.Close()
itr.right.Close()
return nil
}
func (itr *integerBooleanExprIterator) Next() *BooleanPoint {
a := itr.left.Next()
b := itr.right.Next()
if a == nil && b == nil {
return nil
}
return itr.fn(a, b)
}
// 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
// least one of the points will be non-nil.
type integerBooleanExprFunc func(a *IntegerPoint, b *IntegerPoint) *BooleanPoint
// integerTransformIterator executes a function to modify an existing point for every
// output of the input iterator.
type integerTransformIterator struct {
@ -2362,35 +2565,6 @@ func (itr *integerBoolTransformIterator) Next() *BooleanPoint {
// new point if possible.
type integerBoolTransformFunc func(p *IntegerPoint) *BooleanPoint
// integerCombineTransformIterator executes a function to modify an existing point for every
// output of the input iterator.
type integerCombineTransformIterator struct {
left *bufIntegerIterator
right *bufIntegerIterator
fn integerCombineTransformFunc
}
func (itr *integerCombineTransformIterator) Close() error {
itr.left.Close()
itr.right.Close()
return nil
}
func (itr *integerCombineTransformIterator) Next() *IntegerPoint {
a := itr.left.Next()
b := itr.right.Next()
if a == nil && b == nil {
return nil
}
return itr.fn(a, b)
}
// integerCombineTransformFunc 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 least one of the points will be non-nil.
type integerCombineTransformFunc func(a *IntegerPoint, b *IntegerPoint) *IntegerPoint
// integerDedupeIterator only outputs unique points.
// This differs from the DistinctIterator in that it compares all aux fields too.
// This iterator is relatively inefficient and should only be used on small
@ -3262,6 +3436,35 @@ func (itr *stringReduceFloatIterator) reduce() []FloatPoint {
return a
}
// stringFloatExprIterator executes a function to modify an existing point
// for every output of the input iterator.
type stringFloatExprIterator struct {
left *bufStringIterator
right *bufStringIterator
fn stringFloatExprFunc
}
func (itr *stringFloatExprIterator) Close() error {
itr.left.Close()
itr.right.Close()
return nil
}
func (itr *stringFloatExprIterator) Next() *FloatPoint {
a := itr.left.Next()
b := itr.right.Next()
if a == nil && b == nil {
return nil
}
return itr.fn(a, b)
}
// 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
// least one of the points will be non-nil.
type stringFloatExprFunc func(a *StringPoint, b *StringPoint) *FloatPoint
// stringReduceIntegerIterator executes a reducer for every interval and buffers the result.
type stringReduceIntegerIterator struct {
input *bufStringIterator
@ -3356,6 +3559,35 @@ func (itr *stringReduceIntegerIterator) reduce() []IntegerPoint {
return a
}
// stringIntegerExprIterator executes a function to modify an existing point
// for every output of the input iterator.
type stringIntegerExprIterator struct {
left *bufStringIterator
right *bufStringIterator
fn stringIntegerExprFunc
}
func (itr *stringIntegerExprIterator) Close() error {
itr.left.Close()
itr.right.Close()
return nil
}
func (itr *stringIntegerExprIterator) Next() *IntegerPoint {
a := itr.left.Next()
b := itr.right.Next()
if a == nil && b == nil {
return nil
}
return itr.fn(a, b)
}
// 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
// least one of the points will be non-nil.
type stringIntegerExprFunc func(a *StringPoint, b *StringPoint) *IntegerPoint
// stringReduceStringIterator executes a reducer for every interval and buffers the result.
type stringReduceStringIterator struct {
input *bufStringIterator
@ -3450,6 +3682,35 @@ func (itr *stringReduceStringIterator) reduce() []StringPoint {
return a
}
// stringExprIterator executes a function to modify an existing point
// for every output of the input iterator.
type stringExprIterator struct {
left *bufStringIterator
right *bufStringIterator
fn stringExprFunc
}
func (itr *stringExprIterator) Close() error {
itr.left.Close()
itr.right.Close()
return nil
}
func (itr *stringExprIterator) Next() *StringPoint {
a := itr.left.Next()
b := itr.right.Next()
if a == nil && b == nil {
return nil
}
return itr.fn(a, b)
}
// 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
// least one of the points will be non-nil.
type stringExprFunc func(a *StringPoint, b *StringPoint) *StringPoint
// stringReduceBooleanIterator executes a reducer for every interval and buffers the result.
type stringReduceBooleanIterator struct {
input *bufStringIterator
@ -3544,6 +3805,35 @@ func (itr *stringReduceBooleanIterator) reduce() []BooleanPoint {
return a
}
// stringBooleanExprIterator executes a function to modify an existing point
// for every output of the input iterator.
type stringBooleanExprIterator struct {
left *bufStringIterator
right *bufStringIterator
fn stringBooleanExprFunc
}
func (itr *stringBooleanExprIterator) Close() error {
itr.left.Close()
itr.right.Close()
return nil
}
func (itr *stringBooleanExprIterator) Next() *BooleanPoint {
a := itr.left.Next()
b := itr.right.Next()
if a == nil && b == nil {
return nil
}
return itr.fn(a, b)
}
// 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
// least one of the points will be non-nil.
type stringBooleanExprFunc func(a *StringPoint, b *StringPoint) *BooleanPoint
// stringTransformIterator executes a function to modify an existing point for every
// output of the input iterator.
type stringTransformIterator struct {
@ -3592,35 +3882,6 @@ func (itr *stringBoolTransformIterator) Next() *BooleanPoint {
// new point if possible.
type stringBoolTransformFunc func(p *StringPoint) *BooleanPoint
// stringCombineTransformIterator executes a function to modify an existing point for every
// output of the input iterator.
type stringCombineTransformIterator struct {
left *bufStringIterator
right *bufStringIterator
fn stringCombineTransformFunc
}
func (itr *stringCombineTransformIterator) Close() error {
itr.left.Close()
itr.right.Close()
return nil
}
func (itr *stringCombineTransformIterator) Next() *StringPoint {
a := itr.left.Next()
b := itr.right.Next()
if a == nil && b == nil {
return nil
}
return itr.fn(a, b)
}
// stringCombineTransformFunc 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 least one of the points will be non-nil.
type stringCombineTransformFunc func(a *StringPoint, b *StringPoint) *StringPoint
// stringDedupeIterator only outputs unique points.
// This differs from the DistinctIterator in that it compares all aux fields too.
// This iterator is relatively inefficient and should only be used on small
@ -4492,6 +4753,35 @@ func (itr *booleanReduceFloatIterator) reduce() []FloatPoint {
return a
}
// booleanFloatExprIterator executes a function to modify an existing point
// for every output of the input iterator.
type booleanFloatExprIterator struct {
left *bufBooleanIterator
right *bufBooleanIterator
fn booleanFloatExprFunc
}
func (itr *booleanFloatExprIterator) Close() error {
itr.left.Close()
itr.right.Close()
return nil
}
func (itr *booleanFloatExprIterator) Next() *FloatPoint {
a := itr.left.Next()
b := itr.right.Next()
if a == nil && b == nil {
return nil
}
return itr.fn(a, b)
}
// 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
// least one of the points will be non-nil.
type booleanFloatExprFunc func(a *BooleanPoint, b *BooleanPoint) *FloatPoint
// booleanReduceIntegerIterator executes a reducer for every interval and buffers the result.
type booleanReduceIntegerIterator struct {
input *bufBooleanIterator
@ -4586,6 +4876,35 @@ func (itr *booleanReduceIntegerIterator) reduce() []IntegerPoint {
return a
}
// booleanIntegerExprIterator executes a function to modify an existing point
// for every output of the input iterator.
type booleanIntegerExprIterator struct {
left *bufBooleanIterator
right *bufBooleanIterator
fn booleanIntegerExprFunc
}
func (itr *booleanIntegerExprIterator) Close() error {
itr.left.Close()
itr.right.Close()
return nil
}
func (itr *booleanIntegerExprIterator) Next() *IntegerPoint {
a := itr.left.Next()
b := itr.right.Next()
if a == nil && b == nil {
return nil
}
return itr.fn(a, b)
}
// 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
// least one of the points will be non-nil.
type booleanIntegerExprFunc func(a *BooleanPoint, b *BooleanPoint) *IntegerPoint
// booleanReduceStringIterator executes a reducer for every interval and buffers the result.
type booleanReduceStringIterator struct {
input *bufBooleanIterator
@ -4680,6 +4999,35 @@ func (itr *booleanReduceStringIterator) reduce() []StringPoint {
return a
}
// booleanStringExprIterator executes a function to modify an existing point
// for every output of the input iterator.
type booleanStringExprIterator struct {
left *bufBooleanIterator
right *bufBooleanIterator
fn booleanStringExprFunc
}
func (itr *booleanStringExprIterator) Close() error {
itr.left.Close()
itr.right.Close()
return nil
}
func (itr *booleanStringExprIterator) Next() *StringPoint {
a := itr.left.Next()
b := itr.right.Next()
if a == nil && b == nil {
return nil
}
return itr.fn(a, b)
}
// 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
// least one of the points will be non-nil.
type booleanStringExprFunc func(a *BooleanPoint, b *BooleanPoint) *StringPoint
// booleanReduceBooleanIterator executes a reducer for every interval and buffers the result.
type booleanReduceBooleanIterator struct {
input *bufBooleanIterator
@ -4774,6 +5122,35 @@ func (itr *booleanReduceBooleanIterator) reduce() []BooleanPoint {
return a
}
// booleanExprIterator executes a function to modify an existing point
// for every output of the input iterator.
type booleanExprIterator struct {
left *bufBooleanIterator
right *bufBooleanIterator
fn booleanExprFunc
}
func (itr *booleanExprIterator) Close() error {
itr.left.Close()
itr.right.Close()
return nil
}
func (itr *booleanExprIterator) Next() *BooleanPoint {
a := itr.left.Next()
b := itr.right.Next()
if a == nil && b == nil {
return nil
}
return itr.fn(a, b)
}
// 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
// least one of the points will be non-nil.
type booleanExprFunc func(a *BooleanPoint, b *BooleanPoint) *BooleanPoint
// booleanTransformIterator executes a function to modify an existing point for every
// output of the input iterator.
type booleanTransformIterator struct {
@ -4822,35 +5199,6 @@ func (itr *booleanBoolTransformIterator) Next() *BooleanPoint {
// new point if possible.
type booleanBoolTransformFunc func(p *BooleanPoint) *BooleanPoint
// booleanCombineTransformIterator executes a function to modify an existing point for every
// output of the input iterator.
type booleanCombineTransformIterator struct {
left *bufBooleanIterator
right *bufBooleanIterator
fn booleanCombineTransformFunc
}
func (itr *booleanCombineTransformIterator) Close() error {
itr.left.Close()
itr.right.Close()
return nil
}
func (itr *booleanCombineTransformIterator) Next() *BooleanPoint {
a := itr.left.Next()
b := itr.right.Next()
if a == nil && b == nil {
return nil
}
return itr.fn(a, b)
}
// booleanCombineTransformFunc 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 least one of the points will be non-nil.
type booleanCombineTransformFunc func(a *BooleanPoint, b *BooleanPoint) *BooleanPoint
// booleanDedupeIterator only outputs unique points.
// This differs from the DistinctIterator in that it compares all aux fields too.
// This iterator is relatively inefficient and should only be used on small

View File

@ -802,6 +802,35 @@ func (itr *{{$k.name}}Reduce{{$v.Name}}Iterator) reduce() []{{$v.Name}}Point {
return a
}
// {{$k.name}}{{if ne $k.Name $v.Name}}{{$v.Name}}{{end}}ExprIterator executes a function to modify an existing point
// for every output of the input iterator.
type {{$k.name}}{{if ne $k.Name $v.Name}}{{$v.Name}}{{end}}ExprIterator struct {
left *buf{{$k.Name}}Iterator
right *buf{{$k.Name}}Iterator
fn {{$k.name}}{{if ne $k.Name $v.Name}}{{$v.Name}}{{end}}ExprFunc
}
func (itr *{{$k.name}}{{if ne $k.Name $v.Name}}{{$v.Name}}{{end}}ExprIterator) Close() error {
itr.left.Close()
itr.right.Close()
return nil
}
func (itr *{{$k.name}}{{if ne $k.Name $v.Name}}{{$v.Name}}{{end}}ExprIterator) Next() *{{$v.Name}}Point {
a := itr.left.Next()
b := itr.right.Next()
if a == nil && b == nil {
return nil
}
return itr.fn(a, b)
}
// {{$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
// least one of the points will be non-nil.
type {{$k.name}}{{if ne $k.Name $v.Name}}{{$v.Name}}{{end}}ExprFunc func(a *{{$k.Name}}Point, b *{{$k.Name}}Point) *{{$v.Name}}Point
{{end}}
// {{$k.name}}TransformIterator executes a function to modify an existing point for every
@ -852,35 +881,6 @@ func (itr *{{$k.name}}BoolTransformIterator) Next() *BooleanPoint {
// new point if possible.
type {{$k.name}}BoolTransformFunc func(p *{{$k.Name}}Point) *BooleanPoint
// {{$k.name}}CombineTransformIterator executes a function to modify an existing point for every
// output of the input iterator.
type {{$k.name}}CombineTransformIterator struct {
left *buf{{$k.Name}}Iterator
right *buf{{$k.Name}}Iterator
fn {{$k.name}}CombineTransformFunc
}
func (itr *{{$k.name}}CombineTransformIterator) Close() error {
itr.left.Close()
itr.right.Close()
return nil
}
func (itr *{{$k.name}}CombineTransformIterator) Next() *{{$k.Name}}Point {
a := itr.left.Next()
b := itr.right.Next()
if a == nil && b == nil {
return nil
}
return itr.fn(a, b)
}
// {{$k.name}}CombineTransformFunc 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 least one of the points will be non-nil.
type {{$k.name}}CombineTransformFunc func(a *{{$k.Name}}Point, b *{{$k.Name}}Point) *{{$k.Name}}Point
// {{$k.name}}DedupeIterator only outputs unique points.
// This differs from the DistinctIterator in that it compares all aux fields too.
// This iterator is relatively inefficient and should only be used on small

View File

@ -538,25 +538,26 @@ func buildTransformIterator(lhs Iterator, rhs Iterator, op Token, ic IteratorCre
default:
return nil, fmt.Errorf("type mismatch on RHS, unable to use %T as a FloatIterator", rhs)
}
return &floatCombineTransformIterator{
return &floatExprIterator{
left: newBufFloatIterator(left),
right: newBufFloatIterator(right),
fn: func(a *FloatPoint, b *FloatPoint) *FloatPoint {
if a != nil && b != nil {
if !a.Nil || !b.Nil {
if !a.Nil && !b.Nil {
a.Value = fn(a.Value, b.Value)
a.Nil = false
return a
} else if a.Nil {
return a
} else {
return b
}
return a
} else if a != nil {
if !a.Nil {
a.Value = fn(a.Value, 0)
}
a.Value = float64(0)
a.Nil = true
return a
} else {
if !b.Nil {
b.Value = fn(0, b.Value)
}
b.Value = float64(0)
b.Nil = true
return b
}
},
@ -570,23 +571,22 @@ func buildTransformIterator(lhs Iterator, rhs Iterator, op Token, ic IteratorCre
if !ok {
return nil, fmt.Errorf("type mismatch on RHS, unable to use %T as a IntegerIterator", rhs)
}
return &integerFloatTransformIterator{
input: left,
fn: func(p *IntegerPoint) *FloatPoint {
if p == nil {
return nil
return &integerFloatExprIterator{
left: newBufIntegerIterator(left),
right: newBufIntegerIterator(right),
fn: func(a *IntegerPoint, b *IntegerPoint) *FloatPoint {
p := &FloatPoint{
Name: a.Name,
Tags: a.Tags,
Time: a.Time,
Aux: a.Aux,
}
p2 := right.Next()
if p2 == nil {
return nil
}
return &FloatPoint{
Name: p.Name,
Tags: p.Tags,
Time: p.Time,
Value: fn(p.Value, p2.Value),
Aux: p.Aux,
if (a != nil && b != nil) && (!a.Nil && !b.Nil) {
p.Value = fn(a.Value, b.Value)
} else {
p.Nil = true
}
return p
},
}, nil
case func(int64, int64) int64:
@ -598,18 +598,28 @@ func buildTransformIterator(lhs Iterator, rhs Iterator, op Token, ic IteratorCre
if !ok {
return nil, fmt.Errorf("type mismatch on RHS, unable to use %T as a IntegerIterator", rhs)
}
return &integerTransformIterator{
input: left,
fn: func(p *IntegerPoint) *IntegerPoint {
if p == nil {
return nil
return &integerExprIterator{
left: newBufIntegerIterator(left),
right: newBufIntegerIterator(right),
fn: func(a *IntegerPoint, b *IntegerPoint) *IntegerPoint {
if a != nil && b != nil {
if !a.Nil && !b.Nil {
a.Value = fn(a.Value, b.Value)
return a
} else if a.Nil {
return a
} else {
return b
}
} else if a != nil {
a.Value = int64(0)
a.Nil = true
return a
} else {
b.Value = int64(0)
b.Nil = true
return b
}
p2 := right.Next()
if p2 == nil {
return nil
}
p.Value = fn(p.Value, p2.Value)
return p
},
}, nil
case func(float64, float64) bool:
@ -632,23 +642,22 @@ func buildTransformIterator(lhs Iterator, rhs Iterator, op Token, ic IteratorCre
default:
return nil, fmt.Errorf("type mismatch on RHS, unable to use %T as a FloatIterator", rhs)
}
return &floatBoolTransformIterator{
input: left,
fn: func(p *FloatPoint) *BooleanPoint {
if p == nil {
return nil
return &floatBooleanExprIterator{
left: newBufFloatIterator(left),
right: newBufFloatIterator(right),
fn: func(a *FloatPoint, b *FloatPoint) *BooleanPoint {
p := &BooleanPoint{
Name: a.Name,
Tags: a.Tags,
Time: a.Time,
Aux: a.Aux,
}
p2 := right.Next()
if p2 == nil {
return nil
}
return &BooleanPoint{
Name: p.Name,
Tags: p.Tags,
Time: p.Time,
Value: fn(p.Value, p2.Value),
Aux: p.Aux,
if (a != nil && b != nil) && (!a.Nil && !b.Nil) {
p.Value = fn(a.Value, b.Value)
} else {
p.Nil = true
}
return p
},
}, nil
case func(int64, int64) bool:
@ -660,23 +669,22 @@ func buildTransformIterator(lhs Iterator, rhs Iterator, op Token, ic IteratorCre
if !ok {
return nil, fmt.Errorf("type mismatch on LHS, unable to use %T as a IntegerIterator", rhs)
}
return &integerBoolTransformIterator{
input: left,
fn: func(p *IntegerPoint) *BooleanPoint {
if p == nil {
return nil
return &integerBooleanExprIterator{
left: newBufIntegerIterator(left),
right: newBufIntegerIterator(right),
fn: func(a *IntegerPoint, b *IntegerPoint) *BooleanPoint {
p := &BooleanPoint{
Name: a.Name,
Tags: a.Tags,
Time: a.Time,
Aux: a.Aux,
}
p2 := right.Next()
if p2 == nil {
return nil
}
return &BooleanPoint{
Name: p.Name,
Tags: p.Tags,
Time: p.Time,
Value: fn(p.Value, p2.Value),
Aux: p.Aux,
if (a != nil && b != nil) && (!a.Nil && !b.Nil) {
p.Value = fn(a.Value, b.Value)
} else {
p.Nil = true
}
return p
},
}, nil
}

View File

@ -1592,36 +1592,36 @@ func TestSelect_BinaryExpr_NilValues(t *testing.T) {
Name: "nil binary add",
Statement: `SELECT total + value FROM cpu`,
Points: [][]influxql.Point{
{&influxql.FloatPoint{Name: "cpu", Time: 0 * Second, Value: 20}},
{&influxql.FloatPoint{Name: "cpu", Time: 0 * Second, Nil: true}},
{&influxql.FloatPoint{Name: "cpu", Time: 5 * Second, Value: 25}},
{&influxql.FloatPoint{Name: "cpu", Time: 9 * Second, Value: 5}},
{&influxql.FloatPoint{Name: "cpu", Time: 9 * Second, Nil: true}},
},
},
{
Name: "nil binary subtract",
Statement: `SELECT total - value FROM cpu`,
Points: [][]influxql.Point{
{&influxql.FloatPoint{Name: "cpu", Time: 0 * Second, Value: 20}},
{&influxql.FloatPoint{Name: "cpu", Time: 0 * Second, Nil: true}},
{&influxql.FloatPoint{Name: "cpu", Time: 5 * Second, Value: -5}},
{&influxql.FloatPoint{Name: "cpu", Time: 9 * Second, Value: -5}},
{&influxql.FloatPoint{Name: "cpu", Time: 9 * Second, Nil: true}},
},
},
{
Name: "nil binary multiply",
Statement: `SELECT total * value FROM cpu`,
Points: [][]influxql.Point{
{&influxql.FloatPoint{Name: "cpu", Time: 0 * Second, Value: 0}},
{&influxql.FloatPoint{Name: "cpu", Time: 0 * Second, Nil: true}},
{&influxql.FloatPoint{Name: "cpu", Time: 5 * Second, Value: 150}},
{&influxql.FloatPoint{Name: "cpu", Time: 9 * Second, Value: 0}},
{&influxql.FloatPoint{Name: "cpu", Time: 9 * Second, Nil: true}},
},
},
{
Name: "nil binary division",
Statement: `SELECT total / value FROM cpu`,
Points: [][]influxql.Point{
{&influxql.FloatPoint{Name: "cpu", Time: 0 * Second, Value: 0}},
{&influxql.FloatPoint{Name: "cpu", Time: 0 * Second, Nil: true}},
{&influxql.FloatPoint{Name: "cpu", Time: 5 * Second, Value: float64(10) / float64(15)}},
{&influxql.FloatPoint{Name: "cpu", Time: 9 * Second, Value: 0}},
{&influxql.FloatPoint{Name: "cpu", Time: 9 * Second, Nil: true}},
},
},
} {