Merge pull request #3541 from DanielMorsing/validateFields
check if fields are valid during parse.pull/3560/head
commit
affd0b1ca2
|
@ -14,6 +14,7 @@
|
|||
- [#3420](https://github.com/influxdb/influxdb/pull/3420): Catch opentsdb malformed tags. Thanks @nathanielc.
|
||||
- [#3404](https://github.com/influxdb/influxdb/pull/3404): Added support for escaped single quotes in query string. Thanks @jhorwit2
|
||||
- [#3414](https://github.com/influxdb/influxdb/issues/3414): Shard mappers perform query re-writing
|
||||
- [#3525](https://github.com/influxdb/influxdb/pull/3525): check if fields are valid during parse time.
|
||||
|
||||
## v0.9.2 [2015-07-24]
|
||||
|
||||
|
|
|
@ -1471,11 +1471,18 @@ func (p *Parser) parseFields() (Fields, error) {
|
|||
func (p *Parser) parseField() (*Field, error) {
|
||||
f := &Field{}
|
||||
|
||||
_, pos, _ := p.scanIgnoreWhitespace()
|
||||
p.unscan()
|
||||
// Parse the expression first.
|
||||
expr, err := p.ParseExpr()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var c validateField
|
||||
Walk(&c, expr)
|
||||
if c.foundInvalid {
|
||||
return nil, fmt.Errorf("invalid operator %s in SELECT clause at line %d, char %d; operator is intended for WHERE clause", c.badToken, pos.Line+1, pos.Char+1)
|
||||
}
|
||||
f.Expr = expr
|
||||
|
||||
// Parse the alias if the current and next tokens are "WS AS".
|
||||
|
@ -1491,6 +1498,30 @@ func (p *Parser) parseField() (*Field, error) {
|
|||
return f, nil
|
||||
}
|
||||
|
||||
// validateField checks if the Expr is a valid field. We disallow all binary expression
|
||||
// that return a boolean
|
||||
type validateField struct {
|
||||
foundInvalid bool
|
||||
badToken Token
|
||||
}
|
||||
|
||||
func (c *validateField) Visit(n Node) Visitor {
|
||||
e, ok := n.(*BinaryExpr)
|
||||
if !ok {
|
||||
return c
|
||||
}
|
||||
|
||||
switch e.Op {
|
||||
case EQ, NEQ, EQREGEX,
|
||||
NEQREGEX, LT, LTE, GT, GTE,
|
||||
AND, OR:
|
||||
c.foundInvalid = true
|
||||
c.badToken = e.Op
|
||||
return nil
|
||||
}
|
||||
return c
|
||||
}
|
||||
|
||||
// parseAlias parses the "AS (IDENT|STRING)" alias for fields and dimensions.
|
||||
func (p *Parser) parseAlias() (string, error) {
|
||||
// Check if the next token is "AS". If not, then unscan and exit.
|
||||
|
|
|
@ -1244,6 +1244,9 @@ func TestParser_ParseStatement(t *testing.T) {
|
|||
{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 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`},
|
||||
{s: `SELECT s =~ /foo/ FROM cpu`, err: `invalid operator =~ in SELECT clause at line 1, char 8; operator is intended for WHERE clause`},
|
||||
{s: `DELETE`, err: `found EOF, expected FROM at line 1, char 8`},
|
||||
{s: `DELETE FROM`, err: `found EOF, expected identifier at line 1, char 13`},
|
||||
{s: `DELETE FROM myseries WHERE`, err: `found EOF, expected identifier, string, number, bool at line 1, char 28`},
|
||||
|
|
Loading…
Reference in New Issue