Merge pull request #6510 from influxdata/js-5890-return-time-with-selector
Return the time with a selector when there is no group by intervalpull/6523/head
commit
8f876d0f3c
|
@ -52,6 +52,7 @@
|
|||
- [#6468](https://github.com/influxdata/influxdb/issues/6468): Panic with truncated wal segments
|
||||
- [#6480](https://github.com/influxdata/influxdb/issues/6480): Fix SHOW statements' rewriting bug
|
||||
- [#6505](https://github.com/influxdata/influxdb/issues/6505): Add regex literal to InfluxQL spec for FROM clause.
|
||||
- [#5890](https://github.com/influxdata/influxdb/issues/5890): Return the time with a selector when there is no group by interval.
|
||||
|
||||
## v0.12.2 [2016-04-20]
|
||||
|
||||
|
|
|
@ -2615,19 +2615,19 @@ func TestServer_Query_Aggregates_IntMany(t *testing.T) {
|
|||
name: "first - int",
|
||||
params: url.Values{"db": []string{"db0"}},
|
||||
command: `SELECT FIRST(value) FROM intmany`,
|
||||
exp: `{"results":[{"series":[{"name":"intmany","columns":["time","first"],"values":[["1970-01-01T00:00:00Z",2]]}]}]}`,
|
||||
exp: `{"results":[{"series":[{"name":"intmany","columns":["time","first"],"values":[["2000-01-01T00:00:00Z",2]]}]}]}`,
|
||||
},
|
||||
&Query{
|
||||
name: "first - int - epoch ms",
|
||||
params: url.Values{"db": []string{"db0"}, "epoch": []string{"ms"}},
|
||||
command: `SELECT FIRST(value) FROM intmany`,
|
||||
exp: fmt.Sprintf(`{"results":[{"series":[{"name":"intmany","columns":["time","first"],"values":[[%d,2]]}]}]}`, mustParseTime(time.RFC3339Nano, "1970-01-01T00:00:00Z").UnixNano()/int64(time.Millisecond)),
|
||||
exp: fmt.Sprintf(`{"results":[{"series":[{"name":"intmany","columns":["time","first"],"values":[[%d,2]]}]}]}`, mustParseTime(time.RFC3339Nano, "2000-01-01T00:00:00Z").UnixNano()/int64(time.Millisecond)),
|
||||
},
|
||||
&Query{
|
||||
name: "last - int",
|
||||
params: url.Values{"db": []string{"db0"}},
|
||||
command: `SELECT LAST(value) FROM intmany`,
|
||||
exp: `{"results":[{"series":[{"name":"intmany","columns":["time","last"],"values":[["1970-01-01T00:00:00Z",9]]}]}]}`,
|
||||
exp: `{"results":[{"series":[{"name":"intmany","columns":["time","last"],"values":[["2000-01-01T00:01:10Z",9]]}]}]}`,
|
||||
},
|
||||
&Query{
|
||||
name: "spread - int",
|
||||
|
@ -2995,13 +2995,13 @@ func TestServer_Query_Aggregates_FloatMany(t *testing.T) {
|
|||
name: "first - float",
|
||||
params: url.Values{"db": []string{"db0"}},
|
||||
command: `SELECT FIRST(value) FROM floatmany`,
|
||||
exp: `{"results":[{"series":[{"name":"floatmany","columns":["time","first"],"values":[["1970-01-01T00:00:00Z",2]]}]}]}`,
|
||||
exp: `{"results":[{"series":[{"name":"floatmany","columns":["time","first"],"values":[["2000-01-01T00:00:00Z",2]]}]}]}`,
|
||||
},
|
||||
&Query{
|
||||
name: "last - float",
|
||||
params: url.Values{"db": []string{"db0"}},
|
||||
command: `SELECT LAST(value) FROM floatmany`,
|
||||
exp: `{"results":[{"series":[{"name":"floatmany","columns":["time","last"],"values":[["1970-01-01T00:00:00Z",9]]}]}]}`,
|
||||
exp: `{"results":[{"series":[{"name":"floatmany","columns":["time","last"],"values":[["2000-01-01T00:01:10Z",9]]}]}]}`,
|
||||
},
|
||||
&Query{
|
||||
name: "spread - float",
|
||||
|
@ -3826,14 +3826,14 @@ func TestServer_Query_Aggregates_IdenticalTime(t *testing.T) {
|
|||
name: "last from multiple series with identical timestamp",
|
||||
params: url.Values{"db": []string{"db0"}},
|
||||
command: `SELECT last(value) FROM "series"`,
|
||||
exp: `{"results":[{"series":[{"name":"series","columns":["time","last"],"values":[["1970-01-01T00:00:00Z",5]]}]}]}`,
|
||||
exp: `{"results":[{"series":[{"name":"series","columns":["time","last"],"values":[["2000-01-01T00:00:00Z",5]]}]}]}`,
|
||||
repeat: 100,
|
||||
},
|
||||
&Query{
|
||||
name: "first from multiple series with identical timestamp",
|
||||
params: url.Values{"db": []string{"db0"}},
|
||||
command: `SELECT first(value) FROM "series"`,
|
||||
exp: `{"results":[{"series":[{"name":"series","columns":["time","first"],"values":[["1970-01-01T00:00:00Z",5]]}]}]}`,
|
||||
exp: `{"results":[{"series":[{"name":"series","columns":["time","first"],"values":[["2000-01-01T00:00:00Z",5]]}]}]}`,
|
||||
repeat: 100,
|
||||
},
|
||||
}...)
|
||||
|
|
|
@ -78,7 +78,18 @@ func Select(stmt *SelectStatement, ic IteratorCreator, sopt *SelectOptions) ([]I
|
|||
}
|
||||
}
|
||||
|
||||
return buildFieldIterators(fields, ic, opt)
|
||||
// Determine if there is one call and it is a selector.
|
||||
selector := false
|
||||
if len(info.calls) == 1 {
|
||||
for call := range info.calls {
|
||||
switch call.Name {
|
||||
case "first", "last", "min", "max", "percentile":
|
||||
selector = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return buildFieldIterators(fields, ic, opt, selector)
|
||||
}
|
||||
|
||||
// buildAuxIterators creates a set of iterators from a single combined auxilary iterator.
|
||||
|
@ -117,7 +128,7 @@ func buildAuxIterators(fields Fields, ic IteratorCreator, opt IteratorOptions) (
|
|||
case *VarRef:
|
||||
itrs[i] = aitr.Iterator(expr.Val)
|
||||
case *BinaryExpr:
|
||||
itr, err := buildExprIterator(expr, aitr, opt)
|
||||
itr, err := buildExprIterator(expr, aitr, opt, false)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error constructing iterator for field '%s': %s", f.String(), err)
|
||||
}
|
||||
|
@ -140,7 +151,7 @@ func buildAuxIterators(fields Fields, ic IteratorCreator, opt IteratorOptions) (
|
|||
}
|
||||
|
||||
// buildFieldIterators creates an iterator for each field expression.
|
||||
func buildFieldIterators(fields Fields, ic IteratorCreator, opt IteratorOptions) ([]Iterator, error) {
|
||||
func buildFieldIterators(fields Fields, ic IteratorCreator, opt IteratorOptions, selector bool) ([]Iterator, error) {
|
||||
// Create iterators from fields against the iterator creator.
|
||||
itrs := make([]Iterator, len(fields))
|
||||
|
||||
|
@ -158,7 +169,7 @@ func buildFieldIterators(fields Fields, ic IteratorCreator, opt IteratorOptions)
|
|||
}
|
||||
|
||||
expr := Reduce(f.Expr, nil)
|
||||
itr, err := buildExprIterator(expr, ic, opt)
|
||||
itr, err := buildExprIterator(expr, ic, opt, selector)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -185,7 +196,7 @@ func buildFieldIterators(fields Fields, ic IteratorCreator, opt IteratorOptions)
|
|||
}
|
||||
|
||||
expr := Reduce(f.Expr, nil)
|
||||
itr, err := buildExprIterator(expr, aitr, opt)
|
||||
itr, err := buildExprIterator(expr, aitr, opt, false)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -210,7 +221,7 @@ func buildFieldIterators(fields Fields, ic IteratorCreator, opt IteratorOptions)
|
|||
}
|
||||
|
||||
// buildExprIterator creates an iterator for an expression.
|
||||
func buildExprIterator(expr Expr, ic IteratorCreator, opt IteratorOptions) (Iterator, error) {
|
||||
func buildExprIterator(expr Expr, ic IteratorCreator, opt IteratorOptions, selector bool) (Iterator, error) {
|
||||
opt.Expr = expr
|
||||
|
||||
switch expr := expr.(type) {
|
||||
|
@ -221,7 +232,7 @@ func buildExprIterator(expr Expr, ic IteratorCreator, opt IteratorOptions) (Iter
|
|||
|
||||
switch expr.Name {
|
||||
case "distinct":
|
||||
input, err := buildExprIterator(expr.Args[0].(*VarRef), ic, opt)
|
||||
input, err := buildExprIterator(expr.Args[0].(*VarRef), ic, opt, selector)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -239,7 +250,7 @@ func buildExprIterator(expr Expr, ic IteratorCreator, opt IteratorOptions) (Iter
|
|||
}
|
||||
}
|
||||
|
||||
input, err := buildExprIterator(expr.Args[0], ic, opt)
|
||||
input, err := buildExprIterator(expr.Args[0], ic, opt, selector)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -273,7 +284,7 @@ func buildExprIterator(expr Expr, ic IteratorCreator, opt IteratorOptions) (Iter
|
|||
switch arg := expr.Args[0].(type) {
|
||||
case *Call:
|
||||
if arg.Name == "distinct" {
|
||||
input, err := buildExprIterator(arg, ic, opt)
|
||||
input, err := buildExprIterator(arg, ic, opt, selector)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -284,20 +295,20 @@ func buildExprIterator(expr Expr, ic IteratorCreator, opt IteratorOptions) (Iter
|
|||
case "min", "max", "sum", "first", "last", "mean":
|
||||
return ic.CreateIterator(opt)
|
||||
case "median":
|
||||
input, err := buildExprIterator(expr.Args[0].(*VarRef), ic, opt)
|
||||
input, err := buildExprIterator(expr.Args[0].(*VarRef), ic, opt, false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return newMedianIterator(input, opt)
|
||||
case "stddev":
|
||||
input, err := buildExprIterator(expr.Args[0].(*VarRef), ic, opt)
|
||||
input, err := buildExprIterator(expr.Args[0].(*VarRef), ic, opt, false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return newStddevIterator(input, opt)
|
||||
case "spread":
|
||||
// OPTIMIZE(benbjohnson): convert to map/reduce
|
||||
input, err := buildExprIterator(expr.Args[0].(*VarRef), ic, opt)
|
||||
input, err := buildExprIterator(expr.Args[0].(*VarRef), ic, opt, false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -320,7 +331,7 @@ func buildExprIterator(expr Expr, ic IteratorCreator, opt IteratorOptions) (Iter
|
|||
}
|
||||
}
|
||||
|
||||
input, err := buildExprIterator(expr.Args[0].(*VarRef), ic, opt)
|
||||
input, err := buildExprIterator(expr.Args[0].(*VarRef), ic, opt, false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -344,14 +355,14 @@ func buildExprIterator(expr Expr, ic IteratorCreator, opt IteratorOptions) (Iter
|
|||
}
|
||||
}
|
||||
|
||||
input, err := buildExprIterator(expr.Args[0].(*VarRef), ic, opt)
|
||||
input, err := buildExprIterator(expr.Args[0].(*VarRef), ic, opt, false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
n := expr.Args[len(expr.Args)-1].(*IntegerLiteral)
|
||||
return newBottomIterator(input, opt, n, tags)
|
||||
case "percentile":
|
||||
input, err := buildExprIterator(expr.Args[0].(*VarRef), ic, opt)
|
||||
input, err := buildExprIterator(expr.Args[0].(*VarRef), ic, opt, false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -372,11 +383,13 @@ func buildExprIterator(expr Expr, ic IteratorCreator, opt IteratorOptions) (Iter
|
|||
return nil, err
|
||||
}
|
||||
|
||||
if expr.Name != "top" && expr.Name != "bottom" {
|
||||
itr = NewIntervalIterator(itr, opt)
|
||||
}
|
||||
if !opt.Interval.IsZero() && opt.Fill != NoFill {
|
||||
itr = NewFillIterator(itr, expr, opt)
|
||||
if !selector || !opt.Interval.IsZero() {
|
||||
if expr.Name != "top" && expr.Name != "bottom" {
|
||||
itr = NewIntervalIterator(itr, opt)
|
||||
}
|
||||
if !opt.Interval.IsZero() && opt.Fill != NoFill {
|
||||
itr = NewFillIterator(itr, expr, opt)
|
||||
}
|
||||
}
|
||||
if opt.InterruptCh != nil {
|
||||
itr = NewInterruptIterator(itr, opt.InterruptCh)
|
||||
|
@ -392,31 +405,31 @@ func buildExprIterator(expr Expr, ic IteratorCreator, opt IteratorOptions) (Iter
|
|||
return nil, fmt.Errorf("unable to construct an iterator from two literals: LHS: %T, RHS: %T", lhs, rhs)
|
||||
}
|
||||
|
||||
lhs, err := buildExprIterator(expr.LHS, ic, opt)
|
||||
lhs, err := buildExprIterator(expr.LHS, ic, opt, false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return buildRHSTransformIterator(lhs, rhs, expr.Op, ic, opt)
|
||||
} else if lhs, ok := expr.LHS.(Literal); ok {
|
||||
rhs, err := buildExprIterator(expr.RHS, ic, opt)
|
||||
rhs, err := buildExprIterator(expr.RHS, ic, opt, false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return buildLHSTransformIterator(lhs, rhs, expr.Op, ic, opt)
|
||||
} else {
|
||||
// We have two iterators. Combine them into a single iterator.
|
||||
lhs, err := buildExprIterator(expr.LHS, ic, opt)
|
||||
lhs, err := buildExprIterator(expr.LHS, ic, opt, false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
rhs, err := buildExprIterator(expr.RHS, ic, opt)
|
||||
rhs, err := buildExprIterator(expr.RHS, ic, opt, false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return buildTransformIterator(lhs, rhs, expr.Op, ic, opt)
|
||||
}
|
||||
case *ParenExpr:
|
||||
return buildExprIterator(expr.Expr, ic, opt)
|
||||
return buildExprIterator(expr.Expr, ic, opt, selector)
|
||||
default:
|
||||
return nil, fmt.Errorf("invalid expression type: %T", expr)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue