Duplicate parsing bug in ALTER RETENTION POLICY

Return an error when we encounter the same option twice in ALTER
RETENTION POLICY and remove the `maxNumOptions` number from the parsing
loop. The `maxNumOptions` number would need to be modified if another
option was added to the parsing loop and it didn't correctly prevent
duplicate options from being reported as an error anyway.
pull/7294/head
Jonathan A. Sternberg 2016-09-12 10:08:34 -05:00
parent 07e3ceb855
commit dbb8c5570c
3 changed files with 13 additions and 3 deletions

View File

@ -20,6 +20,7 @@
- [#7196](https://github.com/influxdata/influxdb/issues/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. - [#7013](https://github.com/influxdata/influxdb/issues/7013): Fix the dollar sign so it properly handles reserved keywords.
- [#7297](https://github.com/influxdata/influxdb/issues/7297): Use consistent column output from the CLI for column formatted responses. - [#7297](https://github.com/influxdata/influxdb/issues/7297): Use consistent column output from the CLI for column formatted responses.
- [#7231](https://github.com/influxdata/influxdb/issues/7231): Duplicate parsing bug in ALTER RETENTION POLICY.
## v1.0.0 [2016-09-08] ## v1.0.0 [2016-09-08]

View File

@ -475,10 +475,17 @@ func (p *Parser) parseAlterRetentionPolicyStatement() (*AlterRetentionPolicyStat
stmt.Database = ident stmt.Database = ident
// Loop through option tokens (DURATION, REPLICATION, SHARD DURATION, DEFAULT, etc.). // Loop through option tokens (DURATION, REPLICATION, SHARD DURATION, DEFAULT, etc.).
maxNumOptions := 4 found := make(map[Token]struct{})
Loop: Loop:
for i := 0; i < maxNumOptions; i++ { for {
tok, pos, lit := p.scanIgnoreWhitespace() tok, pos, lit := p.scanIgnoreWhitespace()
if _, ok := found[tok]; ok {
return nil, &ParseError{
Message: fmt.Sprintf("found duplicate %s option", tok),
Pos: pos,
}
}
switch tok { switch tok {
case DURATION: case DURATION:
d, err := p.parseDuration() d, err := p.parseDuration()
@ -506,12 +513,13 @@ Loop:
case DEFAULT: case DEFAULT:
stmt.Default = true stmt.Default = true
default: default:
if i < 1 { if len(found) == 0 {
return nil, newParseError(tokstr(tok, lit), []string{"DURATION", "REPLICATION", "SHARD", "DEFAULT"}, pos) return nil, newParseError(tokstr(tok, lit), []string{"DURATION", "REPLICATION", "SHARD", "DEFAULT"}, pos)
} }
p.unscan() p.unscan()
break Loop break Loop
} }
found[tok] = struct{}{}
} }
return stmt, nil return stmt, nil

View File

@ -2345,6 +2345,7 @@ func TestParser_ParseStatement(t *testing.T) {
{s: `ALTER RETENTION POLICY`, err: `found EOF, expected identifier at line 1, char 24`}, {s: `ALTER RETENTION POLICY`, err: `found EOF, expected identifier at line 1, char 24`},
{s: `ALTER RETENTION POLICY policy1`, err: `found EOF, expected ON at line 1, char 32`}, {s: `ALTER RETENTION POLICY policy1 ON`, err: `found EOF, expected identifier at line 1, char 35`}, {s: `ALTER RETENTION POLICY policy1`, err: `found EOF, expected ON at line 1, char 32`}, {s: `ALTER RETENTION POLICY policy1 ON`, err: `found EOF, expected identifier at line 1, char 35`},
{s: `ALTER RETENTION POLICY policy1 ON testdb`, err: `found EOF, expected DURATION, REPLICATION, SHARD, DEFAULT at line 1, char 42`}, {s: `ALTER RETENTION POLICY policy1 ON testdb`, err: `found EOF, expected DURATION, REPLICATION, SHARD, DEFAULT at line 1, char 42`},
{s: `ALTER RETENTION POLICY policy1 ON testdb REPLICATION 1 REPLICATION 2`, err: `found duplicate REPLICATION option at line 1, char 56`},
{s: `SET`, err: `found EOF, expected PASSWORD at line 1, char 5`}, {s: `SET`, err: `found EOF, expected PASSWORD at line 1, char 5`},
{s: `SET PASSWORD`, err: `found EOF, expected FOR at line 1, char 14`}, {s: `SET PASSWORD`, err: `found EOF, expected FOR at line 1, char 14`},
{s: `SET PASSWORD something`, err: `found something, expected FOR at line 1, char 14`}, {s: `SET PASSWORD something`, err: `found something, expected FOR at line 1, char 14`},