Merge pull request #7328 from influxdata/js-7315-prevent-manual-use-of-system-sources

Prevent manual use of system queries
pull/7372/head
Jonathan A. Sternberg 2016-09-23 10:23:56 -05:00 committed by GitHub
commit 927535e964
4 changed files with 82 additions and 1 deletions

View File

@ -18,6 +18,7 @@
- [#7285](https://github.com/influxdata/influxdb/issues/7285): Correctly use password-type field in Admin UI. Thanks @dandv!
- [#2792](https://github.com/influxdata/influxdb/issues/2792): Exceeding max retention policy duration gives incorrect error message
- [#7226](https://github.com/influxdata/influxdb/issues/7226): Fix database locked up when deleting shards
- [#7315](https://github.com/influxdata/influxdb/issues/7315): Prevent users from manually using system queries since incorrect use would result in a panic.
## v1.0.0 [2016-09-07]

View File

@ -409,7 +409,6 @@ func IsSystemName(name string) bool {
case "_fieldKeys",
"_measurements",
"_series",
"_tagKey",
"_tagKeys",
"_tags":
return true

View File

@ -199,6 +199,7 @@ func (e *QueryExecutor) executeQuery(query *Query, opt ExecutionOptions, closing
}
var i int
LOOP:
for ; i < len(query.Statements); i++ {
ctx.StatementID = i
stmt := query.Statements[i]
@ -211,6 +212,36 @@ func (e *QueryExecutor) executeQuery(query *Query, opt ExecutionOptions, closing
}
}
// Do not let queries manually use the system measurements. If we find
// one, return an error. This prevents a person from using the
// measurement incorrectly and causing a panic.
if stmt, ok := stmt.(*SelectStatement); ok {
for _, s := range stmt.Sources {
switch s := s.(type) {
case *Measurement:
if IsSystemName(s.Name) {
command := "the appropriate meta command"
switch s.Name {
case "_fieldKeys":
command = "SHOW FIELD KEYS"
case "_measurements":
command = "SHOW MEASUREMENTS"
case "_series":
command = "SHOW SERIES"
case "_tagKeys":
command = "SHOW TAG KEYS"
case "_tags":
command = "SHOW TAG VALUES"
}
results <- &Result{
Err: fmt.Errorf("unable to use system source '%s': use %s instead", s.Name, command),
}
break LOOP
}
}
}
}
// Rewrite statements, if necessary.
// This can occur on meta read statements which convert to SELECT statements.
newStmt, err := RewriteStatement(stmt)

View File

@ -283,6 +283,56 @@ func TestQueryExecutor_Panic(t *testing.T) {
}
}
func TestQueryExecutor_InvalidSource(t *testing.T) {
e := NewQueryExecutor()
e.StatementExecutor = &StatementExecutor{
ExecuteStatementFn: func(stmt influxql.Statement, ctx influxql.ExecutionContext) error {
return errors.New("statement executed unexpectedly")
},
}
for i, tt := range []struct {
q string
err string
}{
{
q: `SELECT fieldKey, fieldType FROM _fieldKeys`,
err: `unable to use system source '_fieldKeys': use SHOW FIELD KEYS instead`,
},
{
q: `SELECT "name" FROM _measurements`,
err: `unable to use system source '_measurements': use SHOW MEASUREMENTS instead`,
},
{
q: `SELECT "key" FROM _series`,
err: `unable to use system source '_series': use SHOW SERIES instead`,
},
{
q: `SELECT tagKey FROM _tagKeys`,
err: `unable to use system source '_tagKeys': use SHOW TAG KEYS instead`,
},
{
q: `SELECT "key", value FROM _tags`,
err: `unable to use system source '_tags': use SHOW TAG VALUES instead`,
},
} {
q, err := influxql.ParseQuery(tt.q)
if err != nil {
t.Errorf("%d. unable to parse: %s", i, tt.q)
continue
}
results := e.ExecuteQuery(q, influxql.ExecutionOptions{}, nil)
result := <-results
if len(result.Series) != 0 {
t.Errorf("%d. expected %d rows, got %d", 0, i, len(result.Series))
}
if result.Err == nil || result.Err.Error() != tt.err {
t.Errorf("%d. unexpected error: %s", i, result.Err)
}
}
}
func discardOutput(results <-chan *influxql.Result) {
for range results {
// Read all results and discard.