fix math operations

pull/5196/head
Ben Johnson 2016-01-25 10:36:04 -07:00
parent b4cb770a7f
commit 6204350d65
5 changed files with 75 additions and 5 deletions

View File

@ -3698,3 +3698,24 @@ func (v *NowValuer) Value(key string) (interface{}, bool) {
}
return nil, false
}
// ContainsVarRef returns true if expr is a VarRef or contains one.
func ContainsVarRef(expr Expr) bool {
var v containsVarRefVisitor
Walk(&v, expr)
return v.contains
}
type containsVarRefVisitor struct {
contains bool
}
func (v containsVarRefVisitor) Visit(n Node) Visitor {
switch n.(type) {
case *Call:
return nil
case *VarRef:
v.contains = true
}
return v
}

View File

@ -64,7 +64,7 @@ func Select(stmt *SelectStatement, ic IteratorCreator) ([]Iterator, error) {
}
}
return buildExprIterators(fields, ic, opt)
return buildFieldIterators(fields, ic, opt)
}
// buildAuxIterators creates a set of iterators from a single combined auxilary iterator.
@ -107,19 +107,20 @@ func buildAuxIterators(fields Fields, ic IteratorCreator, opt IteratorOptions) (
return itrs, nil
}
// buildExprIterators creates an iterator for each field expression.
func buildExprIterators(fields Fields, ic IteratorCreator, opt IteratorOptions) ([]Iterator, error) {
// buildFieldIterators creates an iterator for each field expression.
func buildFieldIterators(fields Fields, ic IteratorCreator, opt IteratorOptions) ([]Iterator, error) {
// Create iterators from fields against the iterator creator.
itrs := make([]Iterator, len(fields))
if err := func() error {
hasAuxFields := false
var input Iterator
for i, f := range fields {
// Build iterators for calls first and save the iterator.
// We do this so we can keep the ordering provided by the user, but
// still build the Call's iterator first.
if _, ok := f.Expr.(*Call); !ok {
if ContainsVarRef(f.Expr) {
hasAuxFields = true
continue
}

View File

@ -734,11 +734,19 @@ func (e *Engine) createVarRefSeriesIterator(ref *influxql.VarRef, mm *tsdb.Measu
if len(opt.Aux) > 0 {
aux = make([]cursorAt, len(opt.Aux))
for i := range aux {
// Create cursor from field.
cur := e.buildCursor(mm.Name, seriesKey, opt.Aux[i], opt)
if cur != nil {
aux[i] = newBufCursor(cur)
continue
}
// If field doesn't exist, use the tag value.
// However, if the tag value is blank then return a null.
if v := tags.Value(opt.Aux[i]); v == "" {
aux[i] = &stringNilLiteralCursor{}
} else {
aux[i] = &stringLiteralCursor{value: tags.Value(opt.Aux[i])}
aux[i] = &stringLiteralCursor{value: v}
}
}
}

View File

@ -423,6 +423,14 @@ func (c *floatLiteralCursor) peek() (t int64, v interface{}) { return tsdb.EOF,
func (c *floatLiteralCursor) next() (t int64, v interface{}) { return tsdb.EOF, c.value }
func (c *floatLiteralCursor) nextAt(seek int64) interface{} { return c.value }
// floatNilLiteralCursor represents a cursor that always returns a typed nil value.
// It doesn't not have a time value so it can only be used with nextAt().
type floatNilLiteralCursor struct{}
func (c *floatNilLiteralCursor) peek() (t int64, v interface{}) { return tsdb.EOF, (*float64)(nil) }
func (c *floatNilLiteralCursor) next() (t int64, v interface{}) { return tsdb.EOF, (*float64)(nil) }
func (c *floatNilLiteralCursor) nextAt(seek int64) interface{} { return (*float64)(nil) }
type integerIterator struct {
cur integerCursor
aux []cursorAt
@ -751,6 +759,14 @@ func (c *integerLiteralCursor) peek() (t int64, v interface{}) { return tsdb.EOF
func (c *integerLiteralCursor) next() (t int64, v interface{}) { return tsdb.EOF, c.value }
func (c *integerLiteralCursor) nextAt(seek int64) interface{} { return c.value }
// integerNilLiteralCursor represents a cursor that always returns a typed nil value.
// It doesn't not have a time value so it can only be used with nextAt().
type integerNilLiteralCursor struct{}
func (c *integerNilLiteralCursor) peek() (t int64, v interface{}) { return tsdb.EOF, (*int64)(nil) }
func (c *integerNilLiteralCursor) next() (t int64, v interface{}) { return tsdb.EOF, (*int64)(nil) }
func (c *integerNilLiteralCursor) nextAt(seek int64) interface{} { return (*int64)(nil) }
type stringIterator struct {
cur stringCursor
aux []cursorAt
@ -1079,6 +1095,14 @@ func (c *stringLiteralCursor) peek() (t int64, v interface{}) { return tsdb.EOF,
func (c *stringLiteralCursor) next() (t int64, v interface{}) { return tsdb.EOF, c.value }
func (c *stringLiteralCursor) nextAt(seek int64) interface{} { return c.value }
// stringNilLiteralCursor represents a cursor that always returns a typed nil value.
// It doesn't not have a time value so it can only be used with nextAt().
type stringNilLiteralCursor struct{}
func (c *stringNilLiteralCursor) peek() (t int64, v interface{}) { return tsdb.EOF, (*string)(nil) }
func (c *stringNilLiteralCursor) next() (t int64, v interface{}) { return tsdb.EOF, (*string)(nil) }
func (c *stringNilLiteralCursor) nextAt(seek int64) interface{} { return (*string)(nil) }
type booleanIterator struct {
cur booleanCursor
aux []cursorAt
@ -1407,4 +1431,12 @@ func (c *booleanLiteralCursor) peek() (t int64, v interface{}) { return tsdb.EOF
func (c *booleanLiteralCursor) next() (t int64, v interface{}) { return tsdb.EOF, c.value }
func (c *booleanLiteralCursor) nextAt(seek int64) interface{} { return c.value }
// booleanNilLiteralCursor represents a cursor that always returns a typed nil value.
// It doesn't not have a time value so it can only be used with nextAt().
type booleanNilLiteralCursor struct{}
func (c *booleanNilLiteralCursor) peek() (t int64, v interface{}) { return tsdb.EOF, (*bool)(nil) }
func (c *booleanNilLiteralCursor) next() (t int64, v interface{}) { return tsdb.EOF, (*bool)(nil) }
func (c *booleanNilLiteralCursor) nextAt(seek int64) interface{} { return (*bool)(nil) }
var _ = fmt.Print

View File

@ -423,6 +423,14 @@ func (c *{{.name}}LiteralCursor) next() (t int64, v interface{}) { return tsdb.E
func (c *{{.name}}LiteralCursor) nextAt(seek int64) interface{} { return c.value }
// {{.name}}NilLiteralCursor represents a cursor that always returns a typed nil value.
// It doesn't not have a time value so it can only be used with nextAt().
type {{.name}}NilLiteralCursor struct {}
func (c *{{.name}}NilLiteralCursor) peek() (t int64, v interface{}) { return tsdb.EOF, (*{{.Type}})(nil) }
func (c *{{.name}}NilLiteralCursor) next() (t int64, v interface{}) { return tsdb.EOF, (*{{.Type}})(nil) }
func (c *{{.name}}NilLiteralCursor) nextAt(seek int64) interface{} { return (*{{.Type}})(nil) }
{{end}}
var _ = fmt.Print