Skip to content

Commit

Permalink
Add option to include space to series mappings in list series query.
Browse files Browse the repository at this point in the history
Fixes #867. Close #927. Updated lexer and parser to work, added code to
coordinator to insert spaces if requested. Now the user can request the
shard spaces. `list series include spaces`
  • Loading branch information
pauldix authored and jvshahid committed Sep 11, 2014
1 parent e19faf7 commit f0c0abd
Show file tree
Hide file tree
Showing 8 changed files with 135 additions and 12 deletions.
6 changes: 6 additions & 0 deletions cluster/cluster_configuration.go
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,12 @@ func (self *ClusterConfiguration) GetShardSpaces() []*ShardSpace {
return spaces
}

func (self *ClusterConfiguration) GetShardSpacesForDatabase(database string) []*ShardSpace {
self.shardLock.RLock()
defer self.shardLock.RUnlock()
return self.databaseShardSpaces[database]
}

// called by the server, this will wake up every 10 mintues to see if it should
// create a shard for the next window of time. This way shards get created before
// a bunch of writes stream in and try to create it all at the same time.
Expand Down
38 changes: 31 additions & 7 deletions coordinator/coordinator.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,8 @@ func (self *Coordinator) runListContinuousQueries(user common.User, db string, p
func (self *Coordinator) runListSeriesQuery(querySpec *parser.QuerySpec, p engine.Processor) error {
allSeries := self.clusterConfiguration.MetaStore.GetSeriesForDatabase(querySpec.Database())
matchingSeries := allSeries
if q := querySpec.Query().GetListSeriesQuery(); q.HasRegex() {
q := querySpec.Query().GetListSeriesQuery()
if q.HasRegex() {
matchingSeries = nil
regex := q.GetRegex()
for _, s := range allSeries {
Expand All @@ -117,12 +118,35 @@ func (self *Coordinator) runListSeriesQuery(querySpec *parser.QuerySpec, p engin
}
}
name := "list_series_result"
fields := []string{"name"}
points := make([]*protocol.Point, len(matchingSeries), len(matchingSeries))

for i, s := range matchingSeries {
fieldValues := []*protocol.FieldValue{{StringValue: proto.String(s)}}
points[i] = &protocol.Point{Values: fieldValues}
var fields []string
points := make([]*protocol.Point, len(matchingSeries))

if q.IncludeSpaces {
fields = []string{"name", "space"}
spaces := self.clusterConfiguration.GetShardSpacesForDatabase(querySpec.Database())

for i, s := range matchingSeries {
spaceName := ""
for _, sp := range spaces {
if sp.MatchesSeries(s) {
spaceName = sp.Name
break
}
}
fieldValues := []*protocol.FieldValue{
{StringValue: proto.String(s)},
{StringValue: proto.String(spaceName)},
}
points[i] = &protocol.Point{Values: fieldValues}
}
} else {
fields = []string{"name"}
for i, s := range matchingSeries {
fieldValues := []*protocol.FieldValue{
{StringValue: proto.String(s)},
}
points[i] = &protocol.Point{Values: fieldValues}
}
}

seriesResult := &protocol.Series{Name: &name, Fields: fields, Points: points}
Expand Down
45 changes: 45 additions & 0 deletions integration/single_server_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"net/http"
"os"
"strconv"
"strings"

influxdb "github.com/influxdb/influxdb/client"
. "github.com/influxdb/influxdb/integration/helpers"
Expand Down Expand Up @@ -142,6 +143,50 @@ func (self *SingleServerSuite) TestListSeriesRegex(c *C) {
c.Assert(maps, HasLen, 3)
}

func (self *SingleServerSuite) TestListSeriesWithSpace(c *C) {
db := "test_list_series_with_space"
client := self.server.GetClient("", c)
c.Assert(client.CreateDatabase(db), IsNil)
client = self.server.GetClient(db, c)
space := &influxdb.ShardSpace{Name: "space1", Regex: "/^space1.*/"}
c.Assert(client.CreateShardSpace(db, space), IsNil)
space.Name = "space2"
space.Regex = "/^space2.*/"
c.Assert(client.CreateShardSpace(db, space), IsNil)
space.Name = "space3"
space.Regex = "/^space3.*/"
c.Assert(client.CreateShardSpace(db, space), IsNil)

user := self.server.GetClientWithUser(db, "root", "root", c)
series := make([]*influxdb.Series, 0)

seriesCount := 50
for i := 1; i <= seriesCount; i++ {
n := fmt.Sprintf("space%d.%d", i%3+1, i)
series = append(series, &influxdb.Series{Name: n, Columns: []string{"val"}, Points: [][]interface{}{{1}}})
}
c.Assert(user.WriteSeries(series), IsNil)

s, err := user.Query("list series include spaces")
c.Assert(err, IsNil)
c.Assert(s, HasLen, 1)
points := ToMap(s[0])
c.Assert(len(points), Equals, seriesCount)
for _, p := range points {
name := p["name"].(string)
space := p["space"].(string)
for _, s := range []string{"space1", "space2", "space3", "unknown"} {
if s == "unknown" {
c.Errorf("unknown name %s", name)
}
if strings.HasPrefix(name, s) {
c.Assert(space, Equals, s)
break
}
}
}
}

// pr #483
func (self *SingleServerSuite) TestConflictStatusCode(c *C) {
client := self.server.GetClient("", c)
Expand Down
11 changes: 8 additions & 3 deletions parser/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,9 @@ const (
)

type ListQuery struct {
Type ListType
value *Value
Type ListType
value *Value
IncludeSpaces bool
}

type DropQuery struct {
Expand Down Expand Up @@ -621,7 +622,11 @@ func parseSingleQuery(q *C.query) (*Query, error) {
return nil, err
}
}
return &Query{ListQuery: &ListQuery{Type: t, value: value}, qType: ListSeries}, nil
includeSpaces := false
if q.list_series_query.include_spaces != 0 {
includeSpaces = true
}
return &Query{ListQuery: &ListQuery{Type: t, value: value, IncludeSpaces: includeSpaces}, qType: ListSeries}, nil
}

if q.list_continuous_queries_query != 0 {
Expand Down
24 changes: 24 additions & 0 deletions parser/parser_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,7 @@ func (self *QueryParserSuite) TestParseListSeries(c *C) {
listSeriesQuery := queries[0].GetListSeriesQuery()
c.Assert(listSeriesQuery, NotNil)
c.Assert(listSeriesQuery.HasRegex(), Equals, false)
c.Assert(listSeriesQuery.IncludeSpaces, Equals, false)

// test the case sensitive and case insensitive list series
for i := 0; i < 2; i++ {
Expand All @@ -302,9 +303,32 @@ func (self *QueryParserSuite) TestParseListSeries(c *C) {
regularExpression, _ = regexp.Compile("^foo.*")
}
c.Assert(listSeriesQuery.GetRegex(), DeepEquals, regularExpression)
c.Assert(listSeriesQuery.IncludeSpaces, Equals, false)
}
}

func (self *QueryParserSuite) TestParseListSeriesInludeSpaces(c *C) {
queries, err := ParseQuery("list series include spaces")
c.Assert(err, IsNil)
c.Assert(queries, HasLen, 1)
c.Assert(queries[0].IsListQuery(), Equals, true)
listSeriesQuery := queries[0].GetListSeriesQuery()
c.Assert(listSeriesQuery, NotNil)
c.Assert(listSeriesQuery.HasRegex(), Equals, false)
c.Assert(listSeriesQuery.IncludeSpaces, Equals, true)

queries, err = ParseQuery("list series /foo.*/ include spaces")
c.Assert(err, IsNil)
c.Assert(queries, HasLen, 1)
c.Assert(queries[0].IsListQuery(), Equals, true)
listSeriesQuery = queries[0].GetListSeriesQuery()
c.Assert(listSeriesQuery, NotNil)
c.Assert(listSeriesQuery.HasRegex(), Equals, true)
c.Assert(listSeriesQuery.IncludeSpaces, Equals, true)
regularExpression, _ := regexp.Compile("foo.*")
c.Assert(listSeriesQuery.GetRegex(), DeepEquals, regularExpression)
}

// issue #267
func (self *QueryParserSuite) TestParseSelectWithWeirdCharacters(c *C) {
q, err := ParseSelectQuery("select a from \"/blah ( ) ; : ! @ # $ \n \t,foo\\\"=bar/baz\"")
Expand Down
4 changes: 3 additions & 1 deletion parser/query.lex
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ static int yycolumn = 1;
%option bison-locations
%option noyywrap
%s FROM_CLAUSE REGEX_CONDITION
%x LIST_SERIES
%s LIST_SERIES
%x IN_REGEX
%x IN_TABLE_NAME
%x IN_SIMPLE_NAME
Expand Down Expand Up @@ -64,6 +64,8 @@ static int yycolumn = 1;
strcat(yylval->string, yytext);
}

"include" { return INCLUDE; }
"spaces" { return SPACES; }
"where" { BEGIN(INITIAL); return WHERE; }
"as" { return AS; }
"select" { return SELECT; }
Expand Down
18 changes: 17 additions & 1 deletion parser/query.yacc
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ value *create_expression_value(char *operator, size_t size, ...) {
%lex-param {void *scanner}

// define types of tokens (terminals)
%token SELECT DELETE FROM WHERE EQUAL GROUP BY LIMIT ORDER ASC DESC MERGE INNER JOIN AS LIST SERIES INTO CONTINUOUS_QUERIES CONTINUOUS_QUERY DROP DROP_SERIES EXPLAIN UNKNOWN
%token SELECT DELETE FROM WHERE EQUAL GROUP BY LIMIT ORDER ASC DESC MERGE INNER JOIN AS LIST SERIES INTO CONTINUOUS_QUERIES CONTINUOUS_QUERY DROP DROP_SERIES EXPLAIN UNKNOWN INCLUDE SPACES
%token <string> STRING_VALUE INT_VALUE FLOAT_VALUE BOOLEAN_VALUE TABLE_NAME SIMPLE_NAME INTO_NAME REGEX_OP
%token <string> NEGATION_REGEX_OP REGEX_STRING INSENSITIVE_REGEX_STRING DURATION

Expand Down Expand Up @@ -162,6 +162,22 @@ QUERY:
$$->drop_query = $1;
}
|
LIST SERIES INCLUDE SPACES
{
$$ = calloc(1, sizeof(query));
$$->list_series_query = calloc(1, sizeof(list_series_query));
$$->list_series_query->include_spaces = TRUE;
}
|
LIST SERIES REGEX_VALUE INCLUDE SPACES
{
$$ = calloc(1, sizeof(query));
$$->list_series_query = calloc(1, sizeof(list_series_query));
$$->list_series_query->has_regex = TRUE;
$$->list_series_query->include_spaces = TRUE;
$$->list_series_query->regex = $3;
}
|
LIST SERIES
{
$$ = calloc(1, sizeof(query));
Expand Down
1 change: 1 addition & 0 deletions parser/query_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ typedef struct {

typedef struct {
char has_regex;
char include_spaces;
value *regex;
} list_series_query;

Expand Down

0 comments on commit f0c0abd

Please sign in to comment.