diff --git a/influxql/iterator.gen.go b/influxql/iterator.gen.go index d8c3bffead..573912c80a 100644 --- a/influxql/iterator.gen.go +++ b/influxql/iterator.gen.go @@ -1744,7 +1744,7 @@ func (itr *integerReduceSliceIterator) reduce() []IntegerPoint { // integerReduceSliceFunc is the function called by a IntegerPoint slice reducer. type integerReduceSliceFunc func(a []IntegerPoint, opt *reduceOptions) []IntegerPoint -// integerReduceIterator executes a function to modify an existing point for every +// integerTransformIterator executes a function to modify an existing point for every // output of the input iterator. type integerTransformIterator struct { input IntegerIterator @@ -1768,6 +1768,30 @@ func (itr *integerTransformIterator) Next() *IntegerPoint { // new point if possible. type integerTransformFunc func(p *IntegerPoint) *IntegerPoint +// integerFloatTransformIterator executes a function to modify an existing point for every +// output of the input iterator. +type integerFloatTransformIterator struct { + input IntegerIterator + fn integerFloatTransformFunc +} + +// Close closes the iterator and all child iterators. +func (itr *integerFloatTransformIterator) Close() error { return itr.input.Close() } + +// Next returns the minimum value for the next available interval. +func (itr *integerFloatTransformIterator) Next() *FloatPoint { + p := itr.input.Next() + if p != nil { + return itr.fn(p) + } + return nil +} + +// integerFloatTransformFunc creates or modifies a point. +// The point passed in may be modified and returned rather than allocating a +// new point if possible. +type integerFloatTransformFunc func(p *IntegerPoint) *FloatPoint + // integerReduceIterator executes a function to modify an existing point for every // output of the input iterator. type integerBoolTransformIterator struct { diff --git a/influxql/select.go b/influxql/select.go index e0d916a267..952172947a 100644 --- a/influxql/select.go +++ b/influxql/select.go @@ -534,6 +534,34 @@ func buildTransformIterator(lhs Iterator, rhs Iterator, op Token, ic IteratorCre return p }, }, nil + case func(int64, int64) float64: + left, ok := lhs.(IntegerIterator) + if !ok { + return nil, fmt.Errorf("type mismatch on LHS, unable to use %T as a IntegerIterator", lhs) + } + right, ok := rhs.(IntegerIterator) + 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 + } + 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, + } + }, + }, nil case func(int64, int64) int64: left, ok := lhs.(IntegerIterator) if !ok { @@ -712,11 +740,11 @@ func integerBinaryExprFunc(op Token) interface{} { case MUL: return func(lhs, rhs int64) int64 { return lhs * rhs } case DIV: - return func(lhs, rhs int64) int64 { + return func(lhs, rhs int64) float64 { if rhs == 0 { - return int64(0) + return float64(0) } - return lhs / rhs + return float64(lhs) / float64(rhs) } case EQ: return func(lhs, rhs int64) bool { return lhs == rhs } diff --git a/influxql/select_test.go b/influxql/select_test.go index cf7772486e..d5d81dfa0f 100644 --- a/influxql/select_test.go +++ b/influxql/select_test.go @@ -1493,9 +1493,9 @@ func TestSelect_BinaryExpr_Integer(t *testing.T) { Name: "two variable binary division", Statement: `SELECT value / value FROM cpu`, Points: [][]influxql.Point{ - {&influxql.IntegerPoint{Name: "cpu", Time: 0 * Second, Value: 1}}, - {&influxql.IntegerPoint{Name: "cpu", Time: 5 * Second, Value: 1}}, - {&influxql.IntegerPoint{Name: "cpu", Time: 9 * Second, Value: 1}}, + {&influxql.FloatPoint{Name: "cpu", Time: 0 * Second, Value: 1}}, + {&influxql.FloatPoint{Name: "cpu", Time: 5 * Second, Value: 1}}, + {&influxql.FloatPoint{Name: "cpu", Time: 9 * Second, Value: 1}}, }, }, } {