fix #2286: parse error on CREATE CONTINUOUS QUERY

pull/2326/head
David Norton 2015-04-17 16:33:22 -04:00
parent 7e1303f8ae
commit 86db3574ad
4 changed files with 27 additions and 9 deletions

View File

@ -12,6 +12,7 @@
- [#2190](https://github.com/influxdb/influxdb/pull/2190): Implement failover to other data nodes for distributed queries
- [#2324](https://github.com/influxdb/influxdb/issues/2324): Race in Broker.Close()/Broker.RunContinousQueryProcessing()
- [#2325](https://github.com/influxdb/influxdb/pull/2325): Cluster open fixes
- [#2326](https://github.com/influxdb/influxdb/pull/2326): Fix parse error in CREATE CONTINUOUS QUERY
## v0.9.0-rc25 [2015-04-15]

View File

@ -1282,13 +1282,13 @@ func runTestsData(t *testing.T, testName string, nodes Cluster, database, retent
// Continuous query control.
{
name: "create continuous query",
query: `CREATE CONTINUOUS QUERY myquery ON %DB% BEGIN SELECT count(value) INTO measure1 FROM myseries GROUP BY time(10m) END`,
query: `CREATE CONTINUOUS QUERY "my.query" ON %DB% BEGIN SELECT count(value) INTO measure1 FROM myseries GROUP BY time(10m) END`,
queryOne: true,
expected: `{"results":[{}]}`,
},
{
query: `SHOW CONTINUOUS QUERIES`,
expected: `{"results":[{"series":[{"name":"%DB%","columns":["name","query"],"values":[["myquery","CREATE CONTINUOUS QUERY myquery ON %DB% BEGIN SELECT count(value) INTO \"%DB%\".\"%RP%\".measure1 FROM \"%DB%\".\"%RP%\".myseries GROUP BY time(10m) END"]]}]}]}`,
expected: `{"results":[{"series":[{"name":"%DB%","columns":["name","query"],"values":[["my.query","CREATE CONTINUOUS QUERY \"my.query\" ON %DB% BEGIN SELECT count(value) INTO \"%DB%\".\"%RP%\".measure1 FROM \"%DB%\".\"%RP%\".myseries GROUP BY time(10m) END"]]}]}]}`,
},
}

View File

@ -1281,7 +1281,7 @@ type CreateContinuousQueryStatement struct {
// String returns a string representation of the statement.
func (s *CreateContinuousQueryStatement) String() string {
return fmt.Sprintf("CREATE CONTINUOUS QUERY %s ON %s BEGIN %s END", s.Name, s.Database, s.Source.String())
return fmt.Sprintf("CREATE CONTINUOUS QUERY %s ON %s BEGIN %s END", QuoteIdent(s.Name), QuoteIdent(s.Database), s.Source.String())
}
// DefaultDatabase returns the default database from the statement.

View File

@ -614,6 +614,20 @@ func TestParser_ParseStatement(t *testing.T) {
},
},
{
s: `create continuous query "this.is-a.test" on segments begin select * into measure1 from cpu_load_short end`,
stmt: &influxql.CreateContinuousQueryStatement{
Name: "this.is-a.test",
Database: "segments",
Source: &influxql.SelectStatement{
IsRawQuery: true,
Fields: []*influxql.Field{{Expr: &influxql.Wildcard{}}},
Target: &influxql.Target{Measurement: &influxql.Measurement{Name: "measure1"}},
Sources: []influxql.Source{&influxql.Measurement{Name: "cpu_load_short"}},
},
},
},
// CREATE CONTINUOUS QUERY ... INTO <retention-policy>.<measurement>
{
s: `CREATE CONTINUOUS QUERY myquery ON testdb BEGIN SELECT count() INTO "1h.policy1"."cpu.load" FROM myseries GROUP BY time(5m) END`,
@ -647,7 +661,8 @@ func TestParser_ParseStatement(t *testing.T) {
Name: "myquery",
Database: "testdb",
Source: &influxql.SelectStatement{
Fields: []*influxql.Field{{Expr: &influxql.Call{Name: "value"}}},
IsRawQuery: true,
Fields: []*influxql.Field{{Expr: &influxql.VarRef{Val: "value"}}},
Target: &influxql.Target{
Measurement: &influxql.Measurement{RetentionPolicy: "policy1", Name: "value"},
},
@ -663,8 +678,9 @@ func TestParser_ParseStatement(t *testing.T) {
Name: "myquery",
Database: "testdb",
Source: &influxql.SelectStatement{
Fields: []*influxql.Field{{Expr: &influxql.Call{Name: "transmit_rx"}},
{Expr: &influxql.Call{Name: "transmit_tx"}}},
IsRawQuery: true,
Fields: []*influxql.Field{{Expr: &influxql.VarRef{Val: "transmit_rx"}},
{Expr: &influxql.VarRef{Val: "transmit_tx"}}},
Target: &influxql.Target{
Measurement: &influxql.Measurement{RetentionPolicy: "policy1", Name: "network"},
},
@ -1035,13 +1051,14 @@ func TestParser_ParseStatement(t *testing.T) {
// We are memoizing a field so for testing we need to...
if s, ok := tt.stmt.(*influxql.SelectStatement); ok {
s.GroupByInterval()
}
if !reflect.DeepEqual(tt.err, errstring(err)) {
t.Errorf("%d. %q: error mismatch:\n exp=%s\n got=%s\n\n", i, tt.s, tt.err, err)
} else if st, ok := stmt.(*influxql.CreateContinuousQueryStatement); ok { // if it's a CQ, there is a non-exported field that gets memoized during parsing that needs to be set
if st != nil && st.Source != nil {
tt.stmt.(*influxql.CreateContinuousQueryStatement).Source.GroupByInterval()
}
}
if !reflect.DeepEqual(tt.err, errstring(err)) {
t.Errorf("%d. %q: error mismatch:\n exp=%s\n got=%s\n\n", i, tt.s, tt.err, err)
} else if tt.err == "" && !reflect.DeepEqual(tt.stmt, stmt) {
t.Logf("exp=%s\ngot=%s\n", mustMarshalJSON(tt.stmt), mustMarshalJSON(stmt))
t.Errorf("%d. %q\n\nstmt mismatch:\n\nexp=%#v\n\ngot=%#v\n\n", i, tt.s, tt.stmt, stmt)