diff --git a/influxql/scanner_test.go b/influxql/scanner_test.go index c44de8622c..44d620a0f9 100644 --- a/influxql/scanner_test.go +++ b/influxql/scanner_test.go @@ -104,18 +104,24 @@ func TestScanner_Scan(t *testing.T) { {s: `DESC`, tok: influxql.DESC}, {s: `DROP`, tok: influxql.DROP}, {s: `EXPLAIN`, tok: influxql.EXPLAIN}, + {s: `FIELD`, tok: influxql.FIELD}, {s: `FROM`, tok: influxql.FROM}, {s: `INNER`, tok: influxql.INNER}, {s: `INSERT`, tok: influxql.INSERT}, {s: `INTO`, tok: influxql.INTO}, {s: `JOIN`, tok: influxql.JOIN}, + {s: `KEYS`, tok: influxql.KEYS}, {s: `LIMIT`, tok: influxql.LIMIT}, {s: `LIST`, tok: influxql.LIST}, + {s: `MEASUREMENT`, tok: influxql.MEASUREMENT}, + {s: `MEASUREMENTS`, tok: influxql.MEASUREMENTS}, {s: `MERGE`, tok: influxql.MERGE}, {s: `ORDER`, tok: influxql.ORDER}, {s: `QUERIES`, tok: influxql.QUERIES}, {s: `SELECT`, tok: influxql.SELECT}, {s: `SERIES`, tok: influxql.SERIES}, + {s: `TAG`, tok: influxql.TAG}, + {s: `VALUES`, tok: influxql.VALUES}, {s: `WHERE`, tok: influxql.WHERE}, {s: `explain`, tok: influxql.EXPLAIN}, // case insensitive } @@ -185,3 +191,149 @@ func TestScanner_Scan_Multi(t *testing.T) { } } } + +// Test LIST MEASUREMENTS WHERE +func TestScanner_Scan_LIST_MEASUREMENTS_WHERE(t *testing.T) { + type result struct { + tok influxql.Token + pos influxql.Pos + lit string + } + exp := []result{ + {tok: influxql.LIST, pos: influxql.Pos{Line: 0, Char: 0}, lit: ""}, + {tok: influxql.WS, pos: influxql.Pos{Line: 0, Char: 4}, lit: " "}, + {tok: influxql.MEASUREMENTS, pos: influxql.Pos{Line: 0, Char: 5}, lit: ""}, + {tok: influxql.WS, pos: influxql.Pos{Line: 0, Char: 17}, lit: " "}, + {tok: influxql.WHERE, pos: influxql.Pos{Line: 0, Char: 18}, lit: ""}, + {tok: influxql.WS, pos: influxql.Pos{Line: 0, Char: 23}, lit: " "}, + {tok: influxql.IDENT, pos: influxql.Pos{Line: 0, Char: 24}, lit: "service"}, + {tok: influxql.WS, pos: influxql.Pos{Line: 0, Char: 31}, lit: " "}, + {tok: influxql.EQ, pos: influxql.Pos{Line: 0, Char: 32}, lit: ""}, + {tok: influxql.WS, pos: influxql.Pos{Line: 0, Char: 33}, lit: " "}, + {tok: influxql.STRING, pos: influxql.Pos{Line: 0, Char: 34}, lit: "redis"}, + {tok: influxql.EOF, pos: influxql.Pos{Line: 0, Char: 41}, lit: ""}, + } + + // Create a scanner. + v := `LIST MEASUREMENTS WHERE service = 'redis'` + s := influxql.NewScanner(strings.NewReader(v)) + + // Continually scan until we reach the end. + var act []result + for { + tok, pos, lit := s.Scan() + act = append(act, result{tok, pos, lit}) + if tok == influxql.EOF { + break + } + } + + // Verify the token counts match. + if len(exp) != len(act) { + t.Fatalf("token count mismatch: exp=%d, got=%d", len(exp), len(act)) + } + + // Verify each token matches. + for i := range exp { + if !reflect.DeepEqual(exp[i], act[i]) { + t.Fatalf("%d. token mismatch:\n\nexp=%#v\n\ngot=%#v", i, exp[i], act[i]) + } + } +} + +// Test LIST SERIES WHERE +func TestScanner_Scan_LIST_SERIES_WHERE(t *testing.T) { + type result struct { + tok influxql.Token + pos influxql.Pos + lit string + } + exp := []result{ + {tok: influxql.LIST, pos: influxql.Pos{Line: 0, Char: 0}, lit: ""}, + {tok: influxql.WS, pos: influxql.Pos{Line: 0, Char: 4}, lit: " "}, + {tok: influxql.SERIES, pos: influxql.Pos{Line: 0, Char: 5}, lit: ""}, + {tok: influxql.WS, pos: influxql.Pos{Line: 0, Char: 11}, lit: " "}, + {tok: influxql.WHERE, pos: influxql.Pos{Line: 0, Char: 12}, lit: ""}, + {tok: influxql.WS, pos: influxql.Pos{Line: 0, Char: 17}, lit: " "}, + {tok: influxql.IDENT, pos: influxql.Pos{Line: 0, Char: 18}, lit: "service42"}, + {tok: influxql.EQ, pos: influxql.Pos{Line: 0, Char: 27}, lit: ""}, + {tok: influxql.STRING, pos: influxql.Pos{Line: 0, Char: 28}, lit: "redis"}, + {tok: influxql.EOF, pos: influxql.Pos{Line: 0, Char: 35}, lit: ""}, + } + + // Create a scanner. + v := `LIST SERIES WHERE service42="redis"` + s := influxql.NewScanner(strings.NewReader(v)) + + // Continually scan until we reach the end. + var act []result + for { + tok, pos, lit := s.Scan() + act = append(act, result{tok, pos, lit}) + if tok == influxql.EOF { + break + } + } + + // Verify the token counts match. + if len(exp) != len(act) { + t.Fatalf("token count mismatch: exp=%d, got=%d", len(exp), len(act)) + } + + // Verify each token matches. + for i := range exp { + if !reflect.DeepEqual(exp[i], act[i]) { + t.Fatalf("%d. token mismatch:\n\nexp=%#v\n\ngot=%#v", i, exp[i], act[i]) + } + } +} + +// Test LIST TAG KEYS FROM +func TestScanner_Scan_LIST_TAG_KEYS_FROM(t *testing.T) { + type result struct { + tok influxql.Token + pos influxql.Pos + lit string + } + exp := []result{ + {tok: influxql.LIST, pos: influxql.Pos{Line: 0, Char: 0}, lit: ""}, + {tok: influxql.WS, pos: influxql.Pos{Line: 0, Char: 4}, lit: " "}, + {tok: influxql.TAG, pos: influxql.Pos{Line: 0, Char: 5}, lit: ""}, + {tok: influxql.WS, pos: influxql.Pos{Line: 0, Char: 8}, lit: " "}, + {tok: influxql.KEYS, pos: influxql.Pos{Line: 0, Char: 9}, lit: ""}, + {tok: influxql.WS, pos: influxql.Pos{Line: 0, Char: 13}, lit: " "}, + {tok: influxql.FROM, pos: influxql.Pos{Line: 0, Char: 14}, lit: ""}, + {tok: influxql.WS, pos: influxql.Pos{Line: 0, Char: 18}, lit: " "}, + {tok: influxql.IDENT, pos: influxql.Pos{Line: 0, Char: 19}, lit: "temperature"}, + {tok: influxql.COMMA, pos: influxql.Pos{Line: 0, Char: 30}, lit: ""}, + {tok: influxql.WS, pos: influxql.Pos{Line: 0, Char: 31}, lit: " "}, + {tok: influxql.IDENT, pos: influxql.Pos{Line: 0, Char: 32}, lit: "wind_speed"}, + {tok: influxql.EOF, pos: influxql.Pos{Line: 0, Char: 43}, lit: ""}, + } + + // Create a scanner. + v := `LIST TAG KEYS FROM temperature, wind_speed` + s := influxql.NewScanner(strings.NewReader(v)) + + // Continually scan until we reach the end. + var act []result + for { + tok, pos, lit := s.Scan() + act = append(act, result{tok, pos, lit}) + if tok == influxql.EOF { + break + } + } + + // Verify the token counts match. + if len(exp) != len(act) { + t.Fatalf("token count mismatch: exp=%d, got=%d", len(exp), len(act)) + } + + // Verify each token matches. + for i := range exp { + if !reflect.DeepEqual(exp[i], act[i]) { + t.Fatalf("%d. token mismatch:\n\nexp=%#v\n\ngot=%#v", i, exp[i], act[i]) + } + } +} diff --git a/influxql/token.go b/influxql/token.go index 6ca1b8cf6b..f7daf81934 100644 --- a/influxql/token.go +++ b/influxql/token.go @@ -59,20 +59,26 @@ const ( DESC DROP EXPLAIN + FIELD FROM GROUP INNER INSERT INTO JOIN + KEYS LIMIT LIST + MEASUREMENT + MEASUREMENTS MERGE ORDER QUERIES QUERY SELECT SERIES + TAG + VALUES WHERE keyword_end ) @@ -108,30 +114,36 @@ var tokens = [...]string{ COMMA: ",", SEMICOLON: ";", - AS: "AS", - ASC: "ASC", - BY: "BY", - CREATE: "CREATE", - CONTINUOUS: "CONTINUOUS", - DELETE: "DELETE", - DESC: "DESC", - DROP: "DROP", - EXPLAIN: "EXPLAIN", - FROM: "FROM", - GROUP: "GROUP", - INNER: "INNER", - INSERT: "INSERT", - INTO: "INTO", - JOIN: "JOIN", - LIMIT: "LIMIT", - LIST: "LIST", - MERGE: "MERGE", - ORDER: "ORDER", - QUERIES: "QUERIES", - QUERY: "QUERY", - SELECT: "SELECT", - SERIES: "SERIES", - WHERE: "WHERE", + AS: "AS", + ASC: "ASC", + BY: "BY", + CREATE: "CREATE", + CONTINUOUS: "CONTINUOUS", + DELETE: "DELETE", + DESC: "DESC", + DROP: "DROP", + EXPLAIN: "EXPLAIN", + FIELD: "FIELD", + FROM: "FROM", + GROUP: "GROUP", + INNER: "INNER", + INSERT: "INSERT", + INTO: "INTO", + JOIN: "JOIN", + KEYS: "KEYS", + LIMIT: "LIMIT", + LIST: "LIST", + MEASUREMENT: "MEASUREMENT", + MEASUREMENTS: "MEASUREMENTS", + MERGE: "MERGE", + ORDER: "ORDER", + QUERIES: "QUERIES", + QUERY: "QUERY", + SELECT: "SELECT", + SERIES: "SERIES", + TAG: "TAG", + VALUES: "VALUES", + WHERE: "WHERE", } var keywords map[string]Token