From 05bd0fc53da936f7cd5afb1c08788e0b3e210ed8 Mon Sep 17 00:00:00 2001 From: Philip O'Toole Date: Mon, 15 Jun 2015 11:40:21 -0700 Subject: [PATCH] Check database existence during normalization Statements were only being normalized if a default database was included in the query (usually via the query param 'db'). However if no default database was included, and none was an explicit part of the measurement name, no database-existence check was run. This result in a later panic with wildcard expansion. --- cmd/influxd/run/server_test.go | 12 +++++++++++- tsdb/query_executor.go | 27 +++++++++++++++------------ 2 files changed, 26 insertions(+), 13 deletions(-) diff --git a/cmd/influxd/run/server_test.go b/cmd/influxd/run/server_test.go index 6485526daf..d4d2846db8 100644 --- a/cmd/influxd/run/server_test.go +++ b/cmd/influxd/run/server_test.go @@ -847,7 +847,7 @@ func TestServer_Query_Common(t *testing.T) { &Query{ name: "selecting a from a non-existent database should error", command: `SELECT value FROM db1.rp0.cpu`, - exp: `{"results":[{"error":"database not found"}]}`, + exp: `{"results":[{"error":"database not found: db1"}]}`, }, &Query{ name: "selecting a from a non-existent retention policy should error", @@ -870,6 +870,16 @@ func TestServer_Query_Common(t *testing.T) { command: `SELECT idontexist FROM db0.rp0.cpu`, exp: `{"results":[{"error":"unknown field or tag name in select clause: idontexist"}]}`, }, + &Query{ + name: "selecting wildcard without specifying a database should error", + command: `SELECT * FROM cpu`, + exp: `{"results":[{"error":"database name required"}]}`, + }, + &Query{ + name: "selecting explicit field without specifying a database should error", + command: `SELECT value FROM cpu`, + exp: `{"results":[{"error":"database name required"}]}`, + }, }...) if err := test.init(s); err != nil { diff --git a/tsdb/query_executor.go b/tsdb/query_executor.go index 6085fa75b9..d7b7da077c 100644 --- a/tsdb/query_executor.go +++ b/tsdb/query_executor.go @@ -134,8 +134,9 @@ func (q *QueryExecutor) ExecuteQuery(query *influxql.Query, database string, chu var i int var stmt influxql.Statement for i, stmt = range query.Statements { - // If a default database wasn't passed in by the caller, - // try to get it from the statement. + // If a default database wasn't passed in by the caller, check the statement. + // Some types of statements have an associated default database, even if it + // is not explicitly included. defaultDB := database if defaultDB == "" { if s, ok := stmt.(influxql.HasDefaultDatabase); ok { @@ -143,12 +144,10 @@ func (q *QueryExecutor) ExecuteQuery(query *influxql.Query, database string, chu } } - // If we have a default database, normalize the statement with it. - if defaultDB != "" { - if err := q.normalizeStatement(stmt, defaultDB); err != nil { - results <- &influxql.Result{Err: err} - break - } + // Normalize each statement. + if err := q.normalizeStatement(stmt, defaultDB); err != nil { + results <- &influxql.Result{Err: err} + break } var res *influxql.Result @@ -905,19 +904,23 @@ func (q *QueryExecutor) normalizeStatement(stmt influxql.Statement, defaultDatab return } -// normalizeMeasurement inserts the default database or policy into all measurement names. +// normalizeMeasurement inserts the default database or policy into all measurement names, +// if required. func (q *QueryExecutor) normalizeMeasurement(m *influxql.Measurement, defaultDatabase string) error { - if defaultDatabase == "" { - return errors.New("no default database specified") - } if m.Name == "" && m.Regex == nil { return errors.New("invalid measurement") } + // Measurement does not have an explicit database? Insert default. if m.Database == "" { m.Database = defaultDatabase } + // The database must now be specified by this point. + if m.Database == "" { + return errors.New("database name required") + } + // Find database. di, err := q.MetaStore.Database(m.Database) if err != nil {