Skip to content

Commit

Permalink
Fix the dollar sign so it properly handles reserved keywords
Browse files Browse the repository at this point in the history
The dollar sign would sometimes be accepted as whitespace if it was
immediately followed by a reserved keyword or an invalid character. It
now reads these properly as a bound parameter rather than ignoring the
dollar sign.
  • Loading branch information
jsternberg committed Sep 2, 2016
1 parent c6763fc commit 04c59b8
Show file tree
Hide file tree
Showing 5 changed files with 24 additions and 15 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG.md
Expand Up @@ -16,7 +16,8 @@
- [#1834](https://github.com/influxdata/influxdb/issues/1834): Drop time when used as a tag or field key.
- [#7152](https://github.com/influxdata/influxdb/issues/7152): Decrement number of measurements only once when deleting the last series from a measurement.
- [#7177](https://github.com/influxdata/influxdb/issues/7177): Fix base64 encoding issue with /debug/vars stats.
- [#7196](https://github.com/influxdata/influxdb/ssues/7196): Fix mmap dereferencing, fixes #7183, #7180
- [#7196](https://github.com/influxdata/influxdb/issues/7196): Fix mmap dereferencing, fixes #7183, #7180
- [#7013](https://github.com/influxdata/influxdb/issues/7013): Fix the dollar sign so it properly handles reserved keywords.

## v1.0.0 [unreleased]

Expand Down
9 changes: 7 additions & 2 deletions influxql/parser.go
Expand Up @@ -2409,9 +2409,14 @@ func (p *Parser) parseUnaryExpr() (Expr, error) {
}
return &RegexLiteral{Val: re}, nil
case BOUNDPARAM:
v, ok := p.params[lit]
k := strings.TrimPrefix(lit, "$")
if len(k) == 0 {
return nil, errors.New("empty bound parameter")
}

v, ok := p.params[k]
if !ok {
return nil, fmt.Errorf("missing parameter: %s", lit)
return nil, fmt.Errorf("missing parameter: %s", k)
}

switch v := v.(type) {
Expand Down
2 changes: 2 additions & 0 deletions influxql/parser_test.go
Expand Up @@ -2308,6 +2308,8 @@ func TestParser_ParseStatement(t *testing.T) {
{s: `SET PASSWORD FOR dejan`, err: `found EOF, expected = at line 1, char 24`},
{s: `SET PASSWORD FOR dejan =`, err: `found EOF, expected string at line 1, char 25`},
{s: `SET PASSWORD FOR dejan = bla`, err: `found bla, expected string at line 1, char 26`},
{s: `$SHOW$DATABASES`, err: `found $SHOW, expected SELECT, DELETE, SHOW, CREATE, DROP, GRANT, REVOKE, ALTER, SET, KILL at line 1, char 1`},
{s: `SELECT * FROM cpu WHERE "tagkey" = $$`, err: `empty bound parameter`},
}

for i, tt := range tests {
Expand Down
21 changes: 11 additions & 10 deletions influxql/scanner.go
Expand Up @@ -32,7 +32,7 @@ func (s *Scanner) Scan() (tok Token, pos Pos, lit string) {
return s.scanWhitespace()
} else if isLetter(ch0) || ch0 == '_' {
s.r.unread()
return s.scanIdent()
return s.scanIdent(true)
} else if isDigit(ch0) {
return s.scanNumber()
}
Expand All @@ -43,7 +43,7 @@ func (s *Scanner) Scan() (tok Token, pos Pos, lit string) {
return EOF, pos, ""
case '"':
s.r.unread()
return s.scanIdent()
return s.scanIdent(true)
case '\'':
return s.scanString()
case '.':
Expand All @@ -54,11 +54,11 @@ func (s *Scanner) Scan() (tok Token, pos Pos, lit string) {
}
return DOT, pos, ""
case '$':
tok, _, lit := s.scanIdent()
if tok == IDENT {
tok = BOUNDPARAM
tok, _, lit = s.scanIdent(false)
if tok != IDENT {
return tok, pos, "$" + lit
}
return tok, pos, lit
return BOUNDPARAM, pos, "$" + lit
case '+', '-':
return s.scanNumber()
case '*':
Expand Down Expand Up @@ -135,7 +135,7 @@ func (s *Scanner) scanWhitespace() (tok Token, pos Pos, lit string) {
return WS, pos, buf.String()
}

func (s *Scanner) scanIdent() (tok Token, pos Pos, lit string) {
func (s *Scanner) scanIdent(lookup bool) (tok Token, pos Pos, lit string) {
// Save the starting position of the identifier.
_, pos = s.r.read()
s.r.unread()
Expand All @@ -161,10 +161,11 @@ func (s *Scanner) scanIdent() (tok Token, pos Pos, lit string) {
lit = buf.String()

// If the literal matches a keyword then return that keyword.
if tok = Lookup(lit); tok != IDENT {
return tok, pos, ""
if lookup {
if tok = Lookup(lit); tok != IDENT {
return tok, pos, ""
}
}

return IDENT, pos, lit
}

Expand Down
4 changes: 2 additions & 2 deletions influxql/scanner_test.go
Expand Up @@ -70,8 +70,8 @@ func TestScanner_Scan(t *testing.T) {
{s: `"foo\"bar\""`, tok: influxql.IDENT, lit: `foo"bar"`},
{s: `test"`, tok: influxql.BADSTRING, lit: "", pos: influxql.Pos{Line: 0, Char: 3}},
{s: `"test`, tok: influxql.BADSTRING, lit: `test`},
{s: `$host`, tok: influxql.BOUNDPARAM, lit: `host`},
{s: `$"host param"`, tok: influxql.BOUNDPARAM, lit: `host param`},
{s: `$host`, tok: influxql.BOUNDPARAM, lit: `$host`},
{s: `$"host param"`, tok: influxql.BOUNDPARAM, lit: `$host param`},

{s: `true`, tok: influxql.TRUE},
{s: `false`, tok: influxql.FALSE},
Expand Down

0 comments on commit 04c59b8

Please sign in to comment.