Fix query compilation so multiple nested distinct calls is allowable
When refactoring the query engine, I thought calling `count(distinct(value))` multiple times was disallowed and so the refactor made it so that wasn't possible. It turns out that this pattern is allowed because since the distinct is nested, it is aggregated anyway and can be combined with other aggregates. This removes the erroneously placed restriction.pull/9145/head
parent
0b18a6faf4
commit
db60a83d5a
|
@ -16,6 +16,7 @@
|
|||
- [#9058](https://github.com/influxdata/influxdb/issues/9058): Fix space required after regex operator. Thanks @stop-start!
|
||||
- [#9109](https://github.com/influxdata/influxdb/issues/9109): Fix: panic: sync: WaitGroup is reused before previous Wait has returned
|
||||
- [#9163](https://github.com/influxdata/influxdb/pull/9163): Fix race condition in the merge iterator close method.
|
||||
- [#9144](https://github.com/influxdata/influxdb/issues/9144): Fix query compilation so multiple nested distinct calls is allowable
|
||||
|
||||
## v1.4.2 [2017-11-15]
|
||||
|
||||
|
|
|
@ -250,7 +250,7 @@ func (c *compiledField) compileExpr(expr influxql.Expr) error {
|
|||
case "sample":
|
||||
return c.compileSample(expr.Args)
|
||||
case "distinct":
|
||||
return c.compileDistinct(expr.Args)
|
||||
return c.compileDistinct(expr.Args, false)
|
||||
case "top", "bottom":
|
||||
return c.compileTopBottom(expr)
|
||||
case "derivative", "non_negative_derivative":
|
||||
|
@ -276,7 +276,7 @@ func (c *compiledField) compileExpr(expr influxql.Expr) error {
|
|||
case *influxql.Distinct:
|
||||
call := expr.NewCall()
|
||||
c.global.FunctionCalls = append(c.global.FunctionCalls, call)
|
||||
return c.compileDistinct(call.Args)
|
||||
return c.compileDistinct(call.Args, false)
|
||||
case *influxql.BinaryExpr:
|
||||
// Disallow wildcards in binary expressions. RewriteFields, which expands
|
||||
// wildcards, is too complicated if we allow wildcards inside of expressions.
|
||||
|
@ -349,10 +349,10 @@ func (c *compiledField) compileFunction(expr *influxql.Call) error {
|
|||
if expr.Name == "count" {
|
||||
// If we have count(), the argument may be a distinct() call.
|
||||
if arg0, ok := expr.Args[0].(*influxql.Call); ok && arg0.Name == "distinct" {
|
||||
return c.compileDistinct(arg0.Args)
|
||||
return c.compileDistinct(arg0.Args, true)
|
||||
} else if arg0, ok := expr.Args[0].(*influxql.Distinct); ok {
|
||||
call := arg0.NewCall()
|
||||
return c.compileDistinct(call.Args)
|
||||
return c.compileDistinct(call.Args, true)
|
||||
}
|
||||
}
|
||||
return c.compileSymbol(expr.Name, expr.Args[0])
|
||||
|
@ -591,7 +591,7 @@ func (c *compiledField) compileHoltWinters(args []influxql.Expr, withFit bool) e
|
|||
return c.compileExpr(call)
|
||||
}
|
||||
|
||||
func (c *compiledField) compileDistinct(args []influxql.Expr) error {
|
||||
func (c *compiledField) compileDistinct(args []influxql.Expr, nested bool) error {
|
||||
if len(args) == 0 {
|
||||
return errors.New("distinct function requires at least one argument")
|
||||
} else if len(args) != 1 {
|
||||
|
@ -601,7 +601,9 @@ func (c *compiledField) compileDistinct(args []influxql.Expr) error {
|
|||
if _, ok := args[0].(*influxql.VarRef); !ok {
|
||||
return errors.New("expected field argument in distinct()")
|
||||
}
|
||||
c.global.HasDistinct = true
|
||||
if !nested {
|
||||
c.global.HasDistinct = true
|
||||
}
|
||||
c.global.OnlySelectors = false
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -80,6 +80,7 @@ func TestCompile_Success(t *testing.T) {
|
|||
`SELECT max(value) FROM (SELECT value + total FROM cpu) WHERE time >= now() - 1m GROUP BY time(10s)`,
|
||||
`SELECT value FROM cpu WHERE time >= '2000-01-01T00:00:00Z' AND time <= '2000-01-01T01:00:00Z'`,
|
||||
`SELECT value FROM (SELECT value FROM cpu) ORDER BY time DESC`,
|
||||
`SELECT count(distinct(value)), max(value) FROM cpu`,
|
||||
} {
|
||||
t.Run(tt, func(t *testing.T) {
|
||||
stmt, err := influxql.ParseStatement(tt)
|
||||
|
@ -121,7 +122,6 @@ func TestCompile_Failures(t *testing.T) {
|
|||
{s: `SELECT mean() FROM cpu`, err: `invalid number of arguments for mean, expected 1, got 0`},
|
||||
{s: `SELECT mean(value, host) FROM cpu`, err: `invalid number of arguments for mean, expected 1, got 2`},
|
||||
{s: `SELECT distinct(value), max(value) FROM cpu`, err: `aggregate function distinct() cannot be combined with other functions or fields`},
|
||||
{s: `SELECT count(distinct(value)), max(value) FROM cpu`, err: `aggregate function distinct() cannot be combined with other functions or fields`},
|
||||
{s: `SELECT count(distinct()) FROM cpu`, err: `distinct function requires at least one argument`},
|
||||
{s: `SELECT count(distinct(value, host)) FROM cpu`, err: `distinct function can only have one argument`},
|
||||
{s: `SELECT count(distinct(2)) FROM cpu`, err: `expected field argument in distinct()`},
|
||||
|
|
Loading…
Reference in New Issue