Fix #267. Allow series names to be escaped
parent
e671755ad4
commit
d454a8ec54
|
@ -315,29 +315,6 @@ func (self *ApiSuite) TestQueryWithSecondsPrecision(c *C) {
|
|||
c.Assert(int(series[0].Points[0][0].(float64)), Equals, 1381346631)
|
||||
}
|
||||
|
||||
func (self *ApiSuite) TestWritingToSeriesWithUnderscore(c *C) {
|
||||
for _, name := range []string{"1foo", "_foo"} {
|
||||
|
||||
data := fmt.Sprintf(`
|
||||
[
|
||||
{
|
||||
"points": [
|
||||
[1382131686, "1"]
|
||||
],
|
||||
"name": "%s",
|
||||
"columns": ["time", "column_one"]
|
||||
}
|
||||
]
|
||||
`, name)
|
||||
|
||||
addr := self.formatUrl("/db/db1/series?time_precision=s&u=dbuser&p=password")
|
||||
resp, err := libhttp.Post(addr, "application/json", bytes.NewBufferString(data))
|
||||
c.Assert(err, IsNil)
|
||||
c.Assert(resp.StatusCode, Equals, libhttp.StatusBadRequest)
|
||||
c.Assert(self.coordinator.series, HasLen, 0)
|
||||
}
|
||||
}
|
||||
|
||||
func (self *ApiSuite) TestQueryWithInvalidPrecision(c *C) {
|
||||
query := "select * from foo where column_one == 'some_value';"
|
||||
query = url.QueryEscape(query)
|
||||
|
|
|
@ -3,7 +3,6 @@ package common
|
|||
import (
|
||||
"fmt"
|
||||
"protocol"
|
||||
"regexp"
|
||||
)
|
||||
|
||||
var (
|
||||
|
@ -19,14 +18,7 @@ const (
|
|||
SecondPrecision
|
||||
)
|
||||
|
||||
var VALID_TABLE_NAMES *regexp.Regexp
|
||||
|
||||
func init() {
|
||||
var err error
|
||||
VALID_TABLE_NAMES, err = regexp.Compile("^[a-zA-Z][a-zA-Z0-9._-]*$")
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
func removeField(fields []string, name string) []string {
|
||||
|
@ -57,10 +49,6 @@ type ApiSeries interface {
|
|||
}
|
||||
|
||||
func ConvertToDataStoreSeries(s ApiSeries, precision TimePrecision) (*protocol.Series, error) {
|
||||
if !VALID_TABLE_NAMES.MatchString(s.GetName()) {
|
||||
return nil, fmt.Errorf("%s is not a valid series name", s.GetName())
|
||||
}
|
||||
|
||||
points := []*protocol.Point{}
|
||||
for _, point := range s.GetPoints() {
|
||||
values := []*protocol.FieldValue{}
|
||||
|
|
|
@ -517,19 +517,6 @@ func (self *CoordinatorImpl) InterpolateValuesAndCommit(query string, db string,
|
|||
}
|
||||
sequenceMap := make(map[sequenceKey]int)
|
||||
r, _ := regexp.Compile(`\[.*?\]`)
|
||||
replaceInvalidCharacters := func(r rune) rune {
|
||||
switch {
|
||||
case (r >= 'A' && r <= 'Z') || (r >= 'a' && r <= 'z') || (r >= '0' && r <= '9'):
|
||||
return r
|
||||
case r == '_' || r == '-' || r == '.':
|
||||
return r
|
||||
case r == ' ':
|
||||
return '_'
|
||||
case r == '/':
|
||||
return '.'
|
||||
}
|
||||
return -1
|
||||
}
|
||||
|
||||
if r.MatchString(targetName) {
|
||||
for _, point := range series.Points {
|
||||
|
@ -539,16 +526,14 @@ func (self *CoordinatorImpl) InterpolateValuesAndCommit(query string, db string,
|
|||
return point.GetFieldValueAsString(fieldIndex)
|
||||
})
|
||||
|
||||
sanitizedTargetName := strings.Map(replaceInvalidCharacters, targetNameWithValues)
|
||||
|
||||
if assignSequenceNumbers {
|
||||
key := sequenceKey{sanitizedTargetName, *point.Timestamp}
|
||||
key := sequenceKey{targetNameWithValues, *point.Timestamp}
|
||||
sequenceMap[key] += 1
|
||||
sequenceNumber := uint64(sequenceMap[key])
|
||||
point.SequenceNumber = &sequenceNumber
|
||||
}
|
||||
|
||||
newSeries := &protocol.Series{Name: &sanitizedTargetName, Fields: series.Fields, Points: []*protocol.Point{point}}
|
||||
newSeries := &protocol.Series{Name: &targetNameWithValues, Fields: series.Fields, Points: []*protocol.Point{point}}
|
||||
if e := self.CommitSeriesData(db, []*protocol.Series{newSeries}); e != nil {
|
||||
log.Error("Couldn't write data for continuous query: ", e)
|
||||
}
|
||||
|
|
|
@ -1416,3 +1416,22 @@ func (self *DataTestSuite) ListSeries(c *C) (Fun, Fun) {
|
|||
c.Assert(names["another_query"], Equals, true)
|
||||
}
|
||||
}
|
||||
|
||||
// For issue #267 - allow all characters in series name - https://github.com/influxdb/influxdb/issues/267
|
||||
func (self *SingleServerSuite) SeriesNameWithWeirdCharacters(c *C) (Fun, Fun) {
|
||||
return func(client Client) {
|
||||
data := `[
|
||||
{
|
||||
"name": "/blah ( ) ; : ! @ # $ \n \t,foo\"=bar/baz",
|
||||
"columns": ["value"],
|
||||
"points": [[1]]
|
||||
}
|
||||
]`
|
||||
client.WriteJsonData(data, c, "s")
|
||||
}, func(client Client) {
|
||||
data := client.RunQuery("select value from \"/blah ( ) ; : ! @ # $ \n \t,foo\\\"=bar/baz\"", c)
|
||||
c.Assert(data, HasLen, 1)
|
||||
c.Assert(data[0].Points, HasLen, 1)
|
||||
c.Assert(data[0].Name, Equals, "/blah ( ) ; : ! @ # $ \n \t,foo\"=bar/baz")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,9 +2,9 @@ package parser
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
. "launchpad.net/gocheck"
|
||||
"testing"
|
||||
"time"
|
||||
. "launchpad.net/gocheck"
|
||||
)
|
||||
|
||||
// Hook up gocheck into the gotest runner.
|
||||
|
@ -265,6 +265,14 @@ func (self *QueryParserSuite) TestParseListSeries(c *C) {
|
|||
c.Assert(queries[0].IsListQuery(), Equals, true)
|
||||
}
|
||||
|
||||
// issue #267
|
||||
func (self *QueryParserSuite) TestParseSelectWithWeirdCharacters(c *C) {
|
||||
q, err := ParseSelectQuery("select a from \"/blah ( ) ; : ! @ # $ \n \t,foo\\\"=bar/baz\"")
|
||||
c.Assert(err, IsNil)
|
||||
c.Assert(q.GetFromClause().Names[0].Name.Name, Equals, "/blah ( ) ; : ! @ # $ \n \t,foo\"=bar/baz")
|
||||
c.Assert(q.GetColumnNames(), HasLen, 1)
|
||||
}
|
||||
|
||||
// issue #150
|
||||
func (self *QueryParserSuite) TestParseSelectWithDivisionThatLooksLikeRegex(c *C) {
|
||||
q, err := ParseSelectQuery("select a/2, b/2 from x")
|
||||
|
|
|
@ -22,6 +22,7 @@ static int yycolumn = 1;
|
|||
%option noyywrap
|
||||
%s FROM_CLAUSE REGEX_CONDITION
|
||||
%x IN_REGEX
|
||||
%x IN_TABLE_NAME
|
||||
%%
|
||||
|
||||
; { return *yytext; }
|
||||
|
@ -100,6 +101,20 @@ true|false { yylval->string = strdup(yy
|
|||
|
||||
[a-zA-Z0-9_][a-zA-Z0-9._-]* { yylval->string = strdup(yytext); return TABLE_NAME; }
|
||||
|
||||
\" { BEGIN(IN_TABLE_NAME); yylval->string=calloc(1, sizeof(char)); }
|
||||
<IN_TABLE_NAME>\\\" {
|
||||
yylval->string = realloc(yylval->string, strlen(yylval->string) + 1);
|
||||
strcat(yylval->string, "\"");
|
||||
}
|
||||
<IN_TABLE_NAME>\" {
|
||||
BEGIN(INITIAL);
|
||||
return TABLE_NAME;
|
||||
}
|
||||
<IN_TABLE_NAME>[^\\"]* {
|
||||
yylval->string=realloc(yylval->string, strlen(yylval->string) + strlen(yytext) + 1);
|
||||
strcat(yylval->string, yytext);
|
||||
}
|
||||
|
||||
[:\[a-zA-Z0-9_][:\[\]a-zA-Z0-9._-]* { yylval->string = strdup(yytext); return INTO_NAME; }
|
||||
|
||||
\'[^\']*\' {
|
||||
|
|
Loading…
Reference in New Issue