diff --git a/influxql/iterator_test.go b/influxql/iterator_test.go index e3c84adc80..f77576764d 100644 --- a/influxql/iterator_test.go +++ b/influxql/iterator_test.go @@ -495,6 +495,114 @@ func TestSortedMergeIterator_Cast_Float(t *testing.T) { } } +// Ensure limit iterators work with limit and offset. +func TestLimitIterator_Float(t *testing.T) { + input := &FloatIterator{Points: []influxql.FloatPoint{ + {Name: "cpu", Time: 0, Value: 1}, + {Name: "cpu", Time: 5, Value: 3}, + {Name: "cpu", Time: 10, Value: 5}, + {Name: "mem", Time: 5, Value: 3}, + {Name: "mem", Time: 7, Value: 8}, + }} + + itr := influxql.NewLimitIterator(input, influxql.IteratorOptions{ + Limit: 1, + Offset: 1, + }) + + if a := Iterators([]influxql.Iterator{itr}).ReadAll(); !deep.Equal(a, [][]influxql.Point{ + {&influxql.FloatPoint{Name: "cpu", Time: 5, Value: 3}}, + {&influxql.FloatPoint{Name: "mem", Time: 7, Value: 8}}, + }) { + t.Fatalf("unexpected points: %s", spew.Sdump(a)) + } + + if !input.Closed { + t.Error("iterator not closed") + } +} + +// Ensure limit iterators work with limit and offset. +func TestLimitIterator_Integer(t *testing.T) { + input := &IntegerIterator{Points: []influxql.IntegerPoint{ + {Name: "cpu", Time: 0, Value: 1}, + {Name: "cpu", Time: 5, Value: 3}, + {Name: "cpu", Time: 10, Value: 5}, + {Name: "mem", Time: 5, Value: 3}, + {Name: "mem", Time: 7, Value: 8}, + }} + + itr := influxql.NewLimitIterator(input, influxql.IteratorOptions{ + Limit: 1, + Offset: 1, + }) + + if a := Iterators([]influxql.Iterator{itr}).ReadAll(); !deep.Equal(a, [][]influxql.Point{ + {&influxql.IntegerPoint{Name: "cpu", Time: 5, Value: 3}}, + {&influxql.IntegerPoint{Name: "mem", Time: 7, Value: 8}}, + }) { + t.Fatalf("unexpected points: %s", spew.Sdump(a)) + } + + if !input.Closed { + t.Error("iterator not closed") + } +} + +// Ensure limit iterators work with limit and offset. +func TestLimitIterator_String(t *testing.T) { + input := &StringIterator{Points: []influxql.StringPoint{ + {Name: "cpu", Time: 0, Value: "a"}, + {Name: "cpu", Time: 5, Value: "b"}, + {Name: "cpu", Time: 10, Value: "c"}, + {Name: "mem", Time: 5, Value: "d"}, + {Name: "mem", Time: 7, Value: "e"}, + }} + + itr := influxql.NewLimitIterator(input, influxql.IteratorOptions{ + Limit: 1, + Offset: 1, + }) + + if a := Iterators([]influxql.Iterator{itr}).ReadAll(); !deep.Equal(a, [][]influxql.Point{ + {&influxql.StringPoint{Name: "cpu", Time: 5, Value: "b"}}, + {&influxql.StringPoint{Name: "mem", Time: 7, Value: "e"}}, + }) { + t.Fatalf("unexpected points: %s", spew.Sdump(a)) + } + + if !input.Closed { + t.Error("iterator not closed") + } +} + +// Ensure limit iterators work with limit and offset. +func TestLimitIterator_Boolean(t *testing.T) { + input := &BooleanIterator{Points: []influxql.BooleanPoint{ + {Name: "cpu", Time: 0, Value: true}, + {Name: "cpu", Time: 5, Value: false}, + {Name: "cpu", Time: 10, Value: true}, + {Name: "mem", Time: 5, Value: false}, + {Name: "mem", Time: 7, Value: true}, + }} + + itr := influxql.NewLimitIterator(input, influxql.IteratorOptions{ + Limit: 1, + Offset: 1, + }) + + if a := Iterators([]influxql.Iterator{itr}).ReadAll(); !deep.Equal(a, [][]influxql.Point{ + {&influxql.BooleanPoint{Name: "cpu", Time: 5, Value: false}}, + {&influxql.BooleanPoint{Name: "mem", Time: 7, Value: true}}, + }) { + t.Fatalf("unexpected points: %s", spew.Sdump(a)) + } + + if !input.Closed { + t.Error("iterator not closed") + } +} + // Ensure auxilary iterators can be created for auxilary fields. func TestFloatAuxIterator(t *testing.T) { itr := influxql.NewAuxIterator( diff --git a/influxql/select_test.go b/influxql/select_test.go index 9bcd18bc67..395518563d 100644 --- a/influxql/select_test.go +++ b/influxql/select_test.go @@ -725,10 +725,17 @@ func TestSelect_Raw(t *testing.T) { func TestSelect_BinaryExpr_Float(t *testing.T) { var ic IteratorCreator ic.CreateIteratorFn = func(opt influxql.IteratorOptions) (influxql.Iterator, error) { + makeAuxFields := func(value float64) []interface{} { + aux := make([]interface{}, len(opt.Aux)) + for i := range aux { + aux[i] = value + } + return aux + } return &FloatIterator{Points: []influxql.FloatPoint{ - {Name: "cpu", Time: 0 * Second, Value: 20, Aux: []interface{}{float64(20)}}, - {Name: "cpu", Time: 5 * Second, Value: 10, Aux: []interface{}{float64(10)}}, - {Name: "cpu", Time: 9 * Second, Value: 19, Aux: []interface{}{float64(19)}}, + {Name: "cpu", Time: 0 * Second, Value: 20, Aux: makeAuxFields(20)}, + {Name: "cpu", Time: 5 * Second, Value: 10, Aux: makeAuxFields(10)}, + {Name: "cpu", Time: 9 * Second, Value: 19, Aux: makeAuxFields(19)}, }}, nil } @@ -755,6 +762,15 @@ func TestSelect_BinaryExpr_Float(t *testing.T) { {&influxql.FloatPoint{Name: "cpu", Time: 9 * Second, Value: 21}}, }, }, + { + Name: "two variable binary add", + Statement: `SELECT value + value FROM cpu`, + Points: [][]influxql.Point{ + {&influxql.FloatPoint{Name: "cpu", Time: 0 * Second, Value: 40}}, + {&influxql.FloatPoint{Name: "cpu", Time: 5 * Second, Value: 20}}, + {&influxql.FloatPoint{Name: "cpu", Time: 9 * Second, Value: 38}}, + }, + }, { Name: "rhs binary multiply", Statement: `SELECT value * 2 FROM cpu`, @@ -773,6 +789,15 @@ func TestSelect_BinaryExpr_Float(t *testing.T) { {&influxql.FloatPoint{Name: "cpu", Time: 9 * Second, Value: 38}}, }, }, + { + Name: "two variable binary multiply", + Statement: `SELECT value * value FROM cpu`, + Points: [][]influxql.Point{ + {&influxql.FloatPoint{Name: "cpu", Time: 0 * Second, Value: 400}}, + {&influxql.FloatPoint{Name: "cpu", Time: 5 * Second, Value: 100}}, + {&influxql.FloatPoint{Name: "cpu", Time: 9 * Second, Value: 361}}, + }, + }, { Name: "rhs binary subtract", Statement: `SELECT value - 2 FROM cpu`, @@ -791,6 +816,15 @@ func TestSelect_BinaryExpr_Float(t *testing.T) { {&influxql.FloatPoint{Name: "cpu", Time: 9 * Second, Value: -17}}, }, }, + { + Name: "two variable binary subtract", + Statement: `SELECT value - value FROM cpu`, + Points: [][]influxql.Point{ + {&influxql.FloatPoint{Name: "cpu", Time: 0 * Second, Value: 0}}, + {&influxql.FloatPoint{Name: "cpu", Time: 5 * Second, Value: 0}}, + {&influxql.FloatPoint{Name: "cpu", Time: 9 * Second, Value: 0}}, + }, + }, { Name: "rhs binary division", Statement: `SELECT value / 2 FROM cpu`, @@ -809,6 +843,15 @@ func TestSelect_BinaryExpr_Float(t *testing.T) { {&influxql.FloatPoint{Name: "cpu", Time: 9 * Second, Value: 2}}, }, }, + { + Name: "two variable binary division", + Statement: `SELECT value / value FROM cpu`, + Points: [][]influxql.Point{ + {&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}}, + }, + }, } { itrs, err := influxql.Select(MustParseSelectStatement(test.Statement), &ic) if err != nil { @@ -823,10 +866,17 @@ func TestSelect_BinaryExpr_Float(t *testing.T) { func TestSelect_BinaryExpr_Integer(t *testing.T) { var ic IteratorCreator ic.CreateIteratorFn = func(opt influxql.IteratorOptions) (influxql.Iterator, error) { + makeAuxFields := func(value int64) []interface{} { + aux := make([]interface{}, len(opt.Aux)) + for i := range aux { + aux[i] = value + } + return aux + } return &IntegerIterator{Points: []influxql.IntegerPoint{ - {Name: "cpu", Time: 0 * Second, Value: 20, Aux: []interface{}{int64(20)}}, - {Name: "cpu", Time: 5 * Second, Value: 10, Aux: []interface{}{int64(10)}}, - {Name: "cpu", Time: 9 * Second, Value: 19, Aux: []interface{}{int64(19)}}, + {Name: "cpu", Time: 0 * Second, Value: 20, Aux: makeAuxFields(20)}, + {Name: "cpu", Time: 5 * Second, Value: 10, Aux: makeAuxFields(10)}, + {Name: "cpu", Time: 9 * Second, Value: 19, Aux: makeAuxFields(19)}, }}, nil } @@ -853,6 +903,15 @@ func TestSelect_BinaryExpr_Integer(t *testing.T) { {&influxql.IntegerPoint{Name: "cpu", Time: 9 * Second, Value: 21}}, }, }, + { + Name: "two variable binary add", + Statement: `SELECT value + value FROM cpu`, + Points: [][]influxql.Point{ + {&influxql.IntegerPoint{Name: "cpu", Time: 0 * Second, Value: 40}}, + {&influxql.IntegerPoint{Name: "cpu", Time: 5 * Second, Value: 20}}, + {&influxql.IntegerPoint{Name: "cpu", Time: 9 * Second, Value: 38}}, + }, + }, { Name: "rhs binary multiply", Statement: `SELECT value * 2 FROM cpu`, @@ -871,6 +930,15 @@ func TestSelect_BinaryExpr_Integer(t *testing.T) { {&influxql.IntegerPoint{Name: "cpu", Time: 9 * Second, Value: 38}}, }, }, + { + Name: "two variable binary multiply", + Statement: `SELECT value * value FROM cpu`, + Points: [][]influxql.Point{ + {&influxql.IntegerPoint{Name: "cpu", Time: 0 * Second, Value: 400}}, + {&influxql.IntegerPoint{Name: "cpu", Time: 5 * Second, Value: 100}}, + {&influxql.IntegerPoint{Name: "cpu", Time: 9 * Second, Value: 361}}, + }, + }, { Name: "rhs binary subtract", Statement: `SELECT value - 2 FROM cpu`, @@ -889,6 +957,15 @@ func TestSelect_BinaryExpr_Integer(t *testing.T) { {&influxql.IntegerPoint{Name: "cpu", Time: 9 * Second, Value: -17}}, }, }, + { + Name: "two variable binary subtract", + Statement: `SELECT value - value FROM cpu`, + Points: [][]influxql.Point{ + {&influxql.IntegerPoint{Name: "cpu", Time: 0 * Second, Value: 0}}, + {&influxql.IntegerPoint{Name: "cpu", Time: 5 * Second, Value: 0}}, + {&influxql.IntegerPoint{Name: "cpu", Time: 9 * Second, Value: 0}}, + }, + }, { Name: "rhs binary division", Statement: `SELECT value / 2 FROM cpu`, @@ -907,6 +984,15 @@ func TestSelect_BinaryExpr_Integer(t *testing.T) { {&influxql.IntegerPoint{Name: "cpu", Time: 9 * Second, Value: 2}}, }, }, + { + 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}}, + }, + }, } { itrs, err := influxql.Select(MustParseSelectStatement(test.Statement), &ic) if err != nil {