influxql: add LIST USERS statement

pull/1324/head
David Norton 2015-01-14 11:53:17 -05:00
parent fd8e8a108d
commit 9e3ca7b569
7 changed files with 67 additions and 22 deletions

View File

@ -108,6 +108,9 @@ LIST FIELD KEYS FROM cpu
-- but you can't do this
LIST FIELD VALUES
-- we don't index field values, so this query should be invalid.
-- list all users
LIST USERS
```
Note that `FROM` and `WHERE` are optional clauses in all of the list series queries.

View File

@ -123,6 +123,7 @@ statement = alter_retention_policy_stmt |
list_series_stmt |
list_tag_key_stmt |
list_tag_value_stmt |
list_users_stmt |
revoke_stmt |
select_stmt .
```
@ -307,6 +308,19 @@ list_retention_policies = "LIST RETENTION POLICIES" db_name .
LIST RETENTION POLICIES mydb;
```
### LIST USERS
```
list_users_stmt = "LIST USERES" .
```
#### Example:
```sql
-- list all users
LIST USERS;
```
## Clauses
```

View File

@ -68,6 +68,7 @@ func (_ *ListMeasurementsStatement) node() {}
func (_ *ListSeriesStatement) node() {}
func (_ *ListTagKeysStatement) node() {}
func (_ *ListTagValuesStatement) node() {}
func (_ *ListUsersStatement) node() {}
func (_ *RevokeStatement) node() {}
func (_ *SelectStatement) node() {}
@ -140,6 +141,7 @@ func (_ *ListRetentionPoliciesStatement) stmt() {}
func (_ *ListSeriesStatement) stmt() {}
func (_ *ListTagKeysStatement) stmt() {}
func (_ *ListTagValuesStatement) stmt() {}
func (_ *ListUsersStatement) stmt() {}
func (_ *RevokeStatement) stmt() {}
func (_ *SelectStatement) stmt() {}
@ -897,6 +899,14 @@ func (s *ListTagValuesStatement) String() string {
return buf.String()
}
// ListUsersStatement represents a command for listing users.
type ListUsersStatement struct{}
// String retuns a string representation of the ListUsersStatement.
func (s *ListUsersStatement) String() string {
return "LIST USERS"
}
// ListFieldKeyStatement represents a command for listing field keys.
type ListFieldKeysStatement struct {
// Data source that fields are extracted from.

View File

@ -89,36 +89,39 @@ func (p *Parser) ParseStatement() (Statement, error) {
// This function assumes the LIST token has already been consumed.
func (p *Parser) parseListStatement() (Statement, error) {
tok, pos, lit := p.scanIgnoreWhitespace()
if tok == SERIES {
return p.parseListSeriesStatement()
} else if tok == CONTINUOUS {
switch tok {
case CONTINUOUS:
return p.parseListContinuousQueriesStatement()
} else if tok == DATABASES {
case DATABASES:
return p.parseListDatabasesStatement()
} else if tok == MEASUREMENTS {
return p.parseListMeasurementsStatement()
} else if tok == TAG {
if tok, pos, lit := p.scanIgnoreWhitespace(); tok == KEYS {
return p.parseListTagKeysStatement()
} else if tok == VALUES {
return p.parseListTagValuesStatement()
} else {
return nil, newParseError(tokstr(tok, lit), []string{"KEYS", "VALUES"}, pos)
}
} else if tok == FIELD {
if tok, pos, lit := p.scanIgnoreWhitespace(); tok == KEYS {
case FIELD:
tok, pos, lit := p.scanIgnoreWhitespace()
if tok == KEYS {
return p.parseListFieldKeysStatement()
} else if tok == VALUES {
return p.parseListFieldValuesStatement()
} else {
return nil, newParseError(tokstr(tok, lit), []string{"KEYS", "VALUES"}, pos)
}
} else if tok == RETENTION {
if tok, pos, lit := p.scanIgnoreWhitespace(); tok == POLICIES {
return nil, newParseError(tokstr(tok, lit), []string{"KEYS", "VALUES"}, pos)
case MEASUREMENTS:
return p.parseListMeasurementsStatement()
case RETENTION:
tok, pos, lit := p.scanIgnoreWhitespace()
if tok == POLICIES {
return p.parseListRetentionPoliciesStatement()
} else {
return nil, newParseError(tokstr(tok, lit), []string{"POLICIES"}, pos)
}
return nil, newParseError(tokstr(tok, lit), []string{"POLICIES"}, pos)
case SERIES:
return p.parseListSeriesStatement()
case TAG:
tok, pos, lit := p.scanIgnoreWhitespace()
if tok == KEYS {
return p.parseListTagKeysStatement()
} else if tok == VALUES {
return p.parseListTagValuesStatement()
}
return nil, newParseError(tokstr(tok, lit), []string{"KEYS", "VALUES"}, pos)
case USERS:
return p.parseListUsersStatement()
}
return nil, newParseError(tokstr(tok, lit), []string{"SERIES", "CONTINUOUS", "MEASUREMENTS", "TAG", "FIELD", "RETENTION"}, pos)
@ -747,6 +750,12 @@ func (p *Parser) parseListTagValuesStatement() (*ListTagValuesStatement, error)
return stmt, nil
}
// parseListUsersStatement parses a string and returns a ListUsersStatement.
// This function assumes the "LIST USERS" tokens have been consumed.
func (p *Parser) parseListUsersStatement() (*ListUsersStatement, error) {
return &ListUsersStatement{}, nil
}
// parseListFieldKeysStatement parses a string and returns a ListSeriesStatement.
// This function assumes the "LIST FIELD KEYS" tokens have already been consumed.
func (p *Parser) parseListFieldKeysStatement() (*ListFieldKeysStatement, error) {

View File

@ -241,6 +241,12 @@ func TestParser_ParseStatement(t *testing.T) {
},
},
// LIST USERS
{
s: `LIST USERS`,
stmt: &influxql.ListUsersStatement{},
},
// LIST FIELD KEYS
{
s: `LIST FIELD KEYS FROM src WHERE region = 'uswest' ORDER BY ASC, field1, field2 DESC LIMIT 10`,

View File

@ -144,6 +144,7 @@ func TestScanner_Scan(t *testing.T) {
{s: `TAG`, tok: influxql.TAG},
{s: `TO`, tok: influxql.TO},
{s: `USER`, tok: influxql.USER},
{s: `USERS`, tok: influxql.USERS},
{s: `VALUES`, tok: influxql.VALUES},
{s: `WHERE`, tok: influxql.WHERE},
{s: `WITH`, tok: influxql.WITH},

View File

@ -99,6 +99,7 @@ const (
TAG
TO
USER
USERS
VALUES
WHERE
WITH
@ -187,6 +188,7 @@ var tokens = [...]string{
TAG: "TAG",
TO: "TO",
USER: "USER",
USERS: "USERS",
VALUES: "VALUES",
WHERE: "WHERE",
WITH: "WITH",