fix SHOW SERIES

pull/1401/head
David Norton 2015-01-28 11:50:14 -05:00
parent 3ad3abaf64
commit 204aad21d3
2 changed files with 143 additions and 12 deletions

View File

@ -9,11 +9,13 @@ import (
"net/http/httptest"
"net/url"
"os"
"reflect"
"strings"
"testing"
"github.com/influxdb/influxdb"
"github.com/influxdb/influxdb/httpd"
"github.com/influxdb/influxdb/influxql"
"github.com/influxdb/influxdb/messaging"
)
@ -778,6 +780,7 @@ func TestHandler_serveShowSeries(t *testing.T) {
srvr := OpenServer(NewMessagingClient())
srvr.CreateDatabase("foo")
srvr.CreateRetentionPolicy("foo", influxdb.NewRetentionPolicy("bar"))
srvr.SetDefaultRetentionPolicy("foo", "bar")
s := NewHTTPServer(srvr)
defer s.Close()
@ -796,17 +799,120 @@ func TestHandler_serveShowSeries(t *testing.T) {
var tests = []struct {
q string
r string
r *influxdb.Results
err string
}{
// SHOW SERIES
{
q: `SHOW SERIES`,
r: `{"results":[{"rows":[{"name":"cpu","columns":["host","region"],"values":[[["server01",""]],[["server01","uswest"]],[["server01","useast"]],[["server02","useast"]]]},{"name":"gpu","columns":["host","region"],"values":[[["server02","useast"]]]}]}]}`,
r: &influxdb.Results{
Results: []*influxdb.Result{
&influxdb.Result{
Rows: []*influxql.Row{
&influxql.Row{
Name: "cpu",
Columns: []string{"host", "region"},
Values: [][]interface{}{
str2iface([]string{"server01", ""}),
str2iface([]string{"server01", "uswest"}),
str2iface([]string{"server01", "useast"}),
str2iface([]string{"server02", "useast"}),
},
},
&influxql.Row{
Name: "gpu",
Columns: []string{"host", "region"},
Values: [][]interface{}{
str2iface([]string{"server02", "useast"}),
},
},
},
},
},
},
},
// SHOW SERIES ... LIMIT
// {
// q: `SHOW SERIES LIMIT 1`,
// r: &influxdb.Results{
// Results: []*influxdb.Result{
// &influxdb.Result{
// Rows: []*influxql.Row{
// &influxql.Row{
// Name: "cpu",
// Columns: []string{"host", "region"},
// Values: [][]interface{}{
// str2iface([]string{"server01", ""}),
// str2iface([]string{"server01", "uswest"}),
// str2iface([]string{"server01", "useast"}),
// str2iface([]string{"server02", "useast"}),
// },
// },
// },
// },
// },
// },
// },
// SHOW SERIES FROM
{
q: `SHOW SERIES from cpu where region = 'uswest'`,
r: `{"results":[{"rows":[{"name":"cpu","columns":["host","region"],"values":[[["server01","uswest"]]]}]}]}`,
q: `SHOW SERIES FROM cpu`,
r: &influxdb.Results{
Results: []*influxdb.Result{
&influxdb.Result{
Rows: []*influxql.Row{
&influxql.Row{
Name: "cpu",
Columns: []string{"host", "region"},
Values: [][]interface{}{
str2iface([]string{"server01", ""}),
str2iface([]string{"server01", "uswest"}),
str2iface([]string{"server01", "useast"}),
str2iface([]string{"server02", "useast"}),
},
},
},
},
},
},
},
// SHOW SERIES WHERE
{
q: `SHOW SERIES WHERE region = 'uswest'`,
r: &influxdb.Results{
Results: []*influxdb.Result{
&influxdb.Result{
Rows: []*influxql.Row{
&influxql.Row{
Name: "cpu",
Columns: []string{"host", "region"},
Values: [][]interface{}{
str2iface([]string{"server01", "uswest"}),
},
},
},
},
},
},
},
// SHOW SERIES FROM ... WHERE
{
q: `SHOW SERIES FROM cpu WHERE region = 'useast'`,
r: &influxdb.Results{
Results: []*influxdb.Result{
&influxdb.Result{
Rows: []*influxql.Row{
&influxql.Row{
Name: "cpu",
Columns: []string{"host", "region"},
Values: [][]interface{}{
str2iface([]string{"server01", "useast"}),
str2iface([]string{"server02", "useast"}),
},
},
},
},
},
},
},
}
@ -824,18 +930,28 @@ func TestHandler_serveShowSeries(t *testing.T) {
if err := json.Unmarshal([]byte(body), r); err != nil {
t.Logf("query #%d: %s", i, tt.q)
t.Log(body)
t.Error("error marshaling result: ", err)
t.Error(err)
}
if body != tt.r {
t.Errorf("result mismatch\n exp: %s\n got: %s\n", tt.r, body)
if !reflect.DeepEqual(tt.err, errstring(r.Err)) {
t.Errorf("%d. %s: error mismatch:\n exp=%s\n got=%s\n\n", i, tt.q, tt.err, r.Err)
} else if tt.err == "" && !reflect.DeepEqual(tt.r, r) {
t.Log(body)
t.Log("")
b, _ := json.Marshal(tt.r)
t.Log(string(b))
if body == string(b) {
t.Log("****** strings are equal")
}
t.Errorf("%d. %s: result mismatch:\n\nexp=%#v\n\ngot=%#v\n\n", i, tt.q, tt.r, r)
}
}
}
// str2iface converts an array of strings to an array of interfaces.
func str2iface(strs []string) []interface{} {
a := make([]interface{}, len(strs))
a := make([]interface{}, 0, len(strs))
for _, s := range strs {
a = append(a, interface{}(s))
}

View File

@ -1754,9 +1754,10 @@ func (s *Server) executeDropUserStatement(q *influxql.DropUserStatement, user *U
}
func (s *Server) executeShowSeriesStatement(stmt *influxql.ShowSeriesStatement, database string, user *User) *Result {
// Find the database.
s.mu.RLock()
defer s.mu.RUnlock()
// Find the database.
db := s.databases[database]
if db == nil {
return &Result{Err: ErrDatabaseNotFound}
@ -1767,7 +1768,11 @@ func (s *Server) executeShowSeriesStatement(stmt *influxql.ShowSeriesStatement,
if stmt.Source != nil {
// TODO: handle multiple measurement sources
if m, ok := stmt.Source.(*influxql.Measurement); ok {
measurements = append(measurements, m.Name)
segments, err := influxql.SplitIdent(m.Name)
if err != nil {
return &Result{Err: err}
}
measurements = append(measurements, segments[2])
} else {
return &Result{Err: ErrMeasurementNotFound}
}
@ -1776,6 +1781,11 @@ func (s *Server) executeShowSeriesStatement(stmt *influxql.ShowSeriesStatement,
measurements = db.MeasurementNames()
}
// If OFFSET is past the end of the array, return empty results.
if stmt.Offset > len(measurements)-1 {
return &Result{}
}
// Sort measurement names so results are always in the same order.
sort.Strings(measurements)
@ -1799,6 +1809,11 @@ func (s *Server) executeShowSeriesStatement(stmt *influxql.ShowSeriesStatement,
filters := map[uint32]influxql.Expr{}
ids, _, _ = m.walkWhereForSeriesIds(stmt.Condition, filters)
// If no series matched, then go to the next measurement.
if len(ids) == 0 {
continue
}
// TODO: check return of walkWhereForSeriesIds for fields
} else {
// No WHERE clause so get all series IDs for this measurement.
@ -1814,13 +1829,13 @@ func (s *Server) executeShowSeriesStatement(stmt *influxql.ShowSeriesStatement,
// Loop through series IDs getting matching tag sets.
for _, id := range ids {
if s, ok := m.seriesByID[id]; ok {
values := make([]string, 0, len(r.Columns))
values := make([]interface{}, 0, len(r.Columns))
for _, column := range r.Columns {
values = append(values, s.Tags[column])
}
// Add the tag values to the row.
r.Values = append(r.Values, []interface{}{values})
r.Values = append(r.Values, values)
}
}