move all aggregate validations to the parser validation from map/reduce functions
parent
c5358dcd2a
commit
d060f3aba9
|
@ -1091,6 +1091,23 @@ func (s *SelectStatement) validateAggregates(tr targetRequirement) error {
|
|||
return fmt.Errorf("invalid number of arguments for %s, expected %d, got %d", c.Name, exp, got)
|
||||
}
|
||||
}
|
||||
// derivative can take a nested aggregate function, everything else expects
|
||||
// a variable reference as the first arg
|
||||
if !strings.HasSuffix(c.Name, "derivative") {
|
||||
switch fc := c.Args[0].(type) {
|
||||
case *VarRef:
|
||||
case *Distinct:
|
||||
if c.Name != "count" {
|
||||
return fmt.Errorf("expected field argument in %s()", c.Name)
|
||||
}
|
||||
case *Call:
|
||||
if fc.Name != "distinct" {
|
||||
return fmt.Errorf("expected field argument in %s()", c.Name)
|
||||
}
|
||||
default:
|
||||
return fmt.Errorf("expected field argument in %s()", c.Name)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -451,7 +451,7 @@ func TestSelectStatement_IsRawQuerySet(t *testing.T) {
|
|||
isRaw: false,
|
||||
},
|
||||
{
|
||||
stmt: "select mean(*) from foo group by *",
|
||||
stmt: "select mean(value) from foo group by *",
|
||||
isRaw: false,
|
||||
},
|
||||
}
|
||||
|
|
|
@ -12,7 +12,6 @@ import (
|
|||
"math"
|
||||
"math/rand"
|
||||
"sort"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// Iterator represents a forward-only iterator over a set of points.
|
||||
|
@ -40,39 +39,6 @@ func InitializeMapFunc(c *Call) (MapFunc, error) {
|
|||
return MapRawQuery, nil
|
||||
}
|
||||
|
||||
// Ensure that there is either a single argument or if for percentile, two
|
||||
if c.Name == "percentile" {
|
||||
if len(c.Args) != 2 {
|
||||
return nil, fmt.Errorf("expected two arguments for %s()", c.Name)
|
||||
}
|
||||
} else if strings.HasSuffix(c.Name, "derivative") {
|
||||
// derivatives require a field name and optional duration
|
||||
if len(c.Args) == 0 {
|
||||
return nil, fmt.Errorf("expected field name argument for %s()", c.Name)
|
||||
}
|
||||
} else if len(c.Args) != 1 {
|
||||
return nil, fmt.Errorf("expected one argument for %s()", c.Name)
|
||||
}
|
||||
|
||||
// derivative can take a nested aggregate function, everything else expects
|
||||
// a variable reference as the first arg
|
||||
if !strings.HasSuffix(c.Name, "derivative") {
|
||||
// Ensure the argument is appropriate for the aggregate function.
|
||||
switch fc := c.Args[0].(type) {
|
||||
case *VarRef:
|
||||
case *Distinct:
|
||||
if c.Name != "count" {
|
||||
return nil, fmt.Errorf("expected field argument in %s()", c.Name)
|
||||
}
|
||||
case *Call:
|
||||
if fc.Name != "distinct" {
|
||||
return nil, fmt.Errorf("expected field argument in %s()", c.Name)
|
||||
}
|
||||
default:
|
||||
return nil, fmt.Errorf("expected field argument in %s()", c.Name)
|
||||
}
|
||||
}
|
||||
|
||||
// Retrieve map function by name.
|
||||
switch c.Name {
|
||||
case "count":
|
||||
|
|
|
@ -86,55 +86,12 @@ func TestMapMean(t *testing.T) {
|
|||
}
|
||||
}
|
||||
}
|
||||
func TestInitializeMapFuncPercentile(t *testing.T) {
|
||||
// No args
|
||||
c := &Call{
|
||||
Name: "percentile",
|
||||
Args: []Expr{},
|
||||
}
|
||||
_, err := InitializeMapFunc(c)
|
||||
if err == nil {
|
||||
t.Errorf("InitializeMapFunc(%v) expected error. got nil", c)
|
||||
}
|
||||
|
||||
if exp := "expected two arguments for percentile()"; err.Error() != exp {
|
||||
t.Errorf("InitializeMapFunc(%v) mismatch. exp %v got %v", c, exp, err.Error())
|
||||
}
|
||||
|
||||
// No percentile arg
|
||||
c = &Call{
|
||||
Name: "percentile",
|
||||
Args: []Expr{
|
||||
&VarRef{Val: "field1"},
|
||||
},
|
||||
}
|
||||
|
||||
_, err = InitializeMapFunc(c)
|
||||
if err == nil {
|
||||
t.Errorf("InitializeMapFunc(%v) expected error. got nil", c)
|
||||
}
|
||||
|
||||
if exp := "expected two arguments for percentile()"; err.Error() != exp {
|
||||
t.Errorf("InitializeMapFunc(%v) mismatch. exp %v got %v", c, exp, err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
func TestInitializeMapFuncDerivative(t *testing.T) {
|
||||
|
||||
for _, fn := range []string{"derivative", "non_negative_derivative"} {
|
||||
// No args should fail
|
||||
c := &Call{
|
||||
Name: fn,
|
||||
Args: []Expr{},
|
||||
}
|
||||
|
||||
_, err := InitializeMapFunc(c)
|
||||
if err == nil {
|
||||
t.Errorf("InitializeMapFunc(%v) expected error. got nil", c)
|
||||
}
|
||||
|
||||
// Single field arg should return MapEcho
|
||||
c = &Call{
|
||||
c := &Call{
|
||||
Name: fn,
|
||||
Args: []Expr{
|
||||
&VarRef{Val: " field1"},
|
||||
|
@ -142,7 +99,7 @@ func TestInitializeMapFuncDerivative(t *testing.T) {
|
|||
},
|
||||
}
|
||||
|
||||
_, err = InitializeMapFunc(c)
|
||||
_, err := InitializeMapFunc(c)
|
||||
if err != nil {
|
||||
t.Errorf("InitializeMapFunc(%v) unexpected error. got %v", c, err)
|
||||
}
|
||||
|
|
|
@ -1330,7 +1330,6 @@ func TestParser_ParseStatement(t *testing.T) {
|
|||
{s: `SELECT field1 FROM 12`, err: `found 12, expected identifier at line 1, char 20`},
|
||||
{s: `SELECT 1000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000 FROM myseries`, err: `unable to parse number at line 1, char 8`},
|
||||
{s: `SELECT 10.5h FROM myseries`, err: `found h, expected FROM at line 1, char 12`},
|
||||
{s: `SELECT derivative(field1), field1 FROM myseries`, err: `mixing aggregate and non-aggregate queries is not supported`},
|
||||
{s: `SELECT distinct(field1), sum(field1) FROM myseries`, err: `aggregate function distinct() can not be combined with other functions or fields`},
|
||||
{s: `SELECT distinct(field1), field2 FROM myseries`, err: `aggregate function distinct() can not be combined with other functions or fields`},
|
||||
{s: `SELECT distinct(field1, field2) FROM myseries`, err: `distinct function can only have one argument`},
|
||||
|
@ -1341,8 +1340,12 @@ func TestParser_ParseStatement(t *testing.T) {
|
|||
{s: `SELECT count(distinct field1, field2) FROM myseries`, err: `count(distinct <field>) can only have one argument`},
|
||||
{s: `select count(distinct(too, many, arguments)) from myseries`, err: `count(distinct <field>) can only have one argument`},
|
||||
{s: `select count() from myseries`, err: `invalid number of arguments for count, expected 1, got 0`},
|
||||
{s: `SELECT derivative(), field1 FROM myseries`, err: `mixing aggregate and non-aggregate queries is not supported`},
|
||||
{s: `select derivative() from myseries`, err: `invalid number of arguments for derivative, expected at least 1 but no more than 2, got 0`},
|
||||
{s: `select derivative(mean(value), 1h, 3) from myseries`, err: `invalid number of arguments for derivative, expected at least 1 but no more than 2, got 3`},
|
||||
{s: `SELECT non_negative_derivative(), field1 FROM myseries`, err: `mixing aggregate and non-aggregate queries is not supported`},
|
||||
{s: `select non_negative_derivative() from myseries`, err: `invalid number of arguments for non_negative_derivative, expected at least 1 but no more than 2, got 0`},
|
||||
{s: `select non_negative_derivative(mean(value), 1h, 3) from myseries`, err: `invalid number of arguments for non_negative_derivative, expected at least 1 but no more than 2, got 3`},
|
||||
{s: `SELECT field1 from myseries WHERE host =~ 'asd' LIMIT 1`, err: `found asd, expected regex at line 1, char 42`},
|
||||
{s: `SELECT value > 2 FROM cpu`, err: `invalid operator > in SELECT clause at line 1, char 8; operator is intended for WHERE clause`},
|
||||
{s: `SELECT value = 2 FROM cpu`, err: `invalid operator = in SELECT clause at line 1, char 8; operator is intended for WHERE clause`},
|
||||
|
|
|
@ -625,13 +625,13 @@ func TestStatementExecutor_ExecuteStatement_CreateContinuousQuery(t *testing.T)
|
|||
t.Fatalf("unexpected database: %s", database)
|
||||
} else if name != "cq0" {
|
||||
t.Fatalf("unexpected name: %s", name)
|
||||
} else if query != `CREATE CONTINUOUS QUERY cq0 ON db0 BEGIN SELECT count(*) INTO db1 FROM db0 GROUP BY time(1h) END` {
|
||||
} else if query != `CREATE CONTINUOUS QUERY cq0 ON db0 BEGIN SELECT count(field1) INTO db1 FROM db0 GROUP BY time(1h) END` {
|
||||
t.Fatalf("unexpected query: %s", query)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
stmt := influxql.MustParseStatement(`CREATE CONTINUOUS QUERY cq0 ON db0 BEGIN SELECT count(*) INTO db1 FROM db0 GROUP BY time(1h) END`)
|
||||
stmt := influxql.MustParseStatement(`CREATE CONTINUOUS QUERY cq0 ON db0 BEGIN SELECT count(field1) INTO db1 FROM db0 GROUP BY time(1h) END`)
|
||||
if res := e.ExecuteStatement(stmt); res.Err != nil {
|
||||
t.Fatal(res.Err)
|
||||
} else if res.Series != nil {
|
||||
|
@ -646,7 +646,7 @@ func TestStatementExecutor_ExecuteStatement_CreateContinuousQuery_Err(t *testing
|
|||
return errors.New("marker")
|
||||
}
|
||||
|
||||
stmt := influxql.MustParseStatement(`CREATE CONTINUOUS QUERY cq0 ON db0 BEGIN SELECT count(*) INTO db1 FROM db0 GROUP BY time(1h) END`)
|
||||
stmt := influxql.MustParseStatement(`CREATE CONTINUOUS QUERY cq0 ON db0 BEGIN SELECT count(field1) INTO db1 FROM db0 GROUP BY time(1h) END`)
|
||||
if res := e.ExecuteStatement(stmt); res.Err == nil || res.Err.Error() != "marker" {
|
||||
t.Fatalf("unexpected error: %s", res.Err)
|
||||
}
|
||||
|
@ -693,14 +693,14 @@ func TestStatementExecutor_ExecuteStatement_ShowContinuousQueries(t *testing.T)
|
|||
{
|
||||
Name: "db0",
|
||||
ContinuousQueries: []meta.ContinuousQueryInfo{
|
||||
{Name: "cq0", Query: "SELECT count(*) INTO db1 FROM db0"},
|
||||
{Name: "cq1", Query: "SELECT count(*) INTO db2 FROM db0"},
|
||||
{Name: "cq0", Query: "SELECT count(field1) INTO db1 FROM db0"},
|
||||
{Name: "cq1", Query: "SELECT count(field1) INTO db2 FROM db0"},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "db1",
|
||||
ContinuousQueries: []meta.ContinuousQueryInfo{
|
||||
{Name: "cq2", Query: "SELECT count(*) INTO db3 FROM db1"},
|
||||
{Name: "cq2", Query: "SELECT count(field1) INTO db3 FROM db1"},
|
||||
},
|
||||
},
|
||||
}, nil
|
||||
|
@ -714,15 +714,15 @@ func TestStatementExecutor_ExecuteStatement_ShowContinuousQueries(t *testing.T)
|
|||
Name: "db0",
|
||||
Columns: []string{"name", "query"},
|
||||
Values: [][]interface{}{
|
||||
{"cq0", "SELECT count(*) INTO db1 FROM db0"},
|
||||
{"cq1", "SELECT count(*) INTO db2 FROM db0"},
|
||||
{"cq0", "SELECT count(field1) INTO db1 FROM db0"},
|
||||
{"cq1", "SELECT count(field1) INTO db2 FROM db0"},
|
||||
},
|
||||
},
|
||||
{
|
||||
Name: "db1",
|
||||
Columns: []string{"name", "query"},
|
||||
Values: [][]interface{}{
|
||||
{"cq2", "SELECT count(*) INTO db3 FROM db1"},
|
||||
{"cq2", "SELECT count(field1) INTO db3 FROM db1"},
|
||||
},
|
||||
},
|
||||
}) {
|
||||
|
@ -755,7 +755,7 @@ func TestStatementExecutor_ExecuteStatement_Unsupported(t *testing.T) {
|
|||
|
||||
// Execute a SELECT statement.
|
||||
NewStatementExecutor().ExecuteStatement(
|
||||
influxql.MustParseStatement(`SELECT count(*) FROM db0`),
|
||||
influxql.MustParseStatement(`SELECT count(field1) FROM db0`),
|
||||
)
|
||||
}()
|
||||
|
||||
|
|
Loading…
Reference in New Issue