diff --git a/expr/parse.go b/expr/parse.go index 8c3e379a8e..ce6bc59675 100644 --- a/expr/parse.go +++ b/expr/parse.go @@ -81,7 +81,7 @@ type MetricRequest struct { func ParseMany(targets []string) ([]*expr, error) { var out []*expr for _, target := range targets { - e, leftover, err := Parse(target) + e, leftover, err := Parse(target, false) if err != nil { return nil, err } @@ -95,7 +95,7 @@ func ParseMany(targets []string) ([]*expr, error) { // Parses an expression string and turns it into an expression // also returns any leftover data that could not be parsed -func Parse(e string) (*expr, string, error) { +func Parse(e string, keyvalue bool) (*expr, string, error) { // skip whitespace for len(e) > 1 && e[0] == ' ' { e = e[1:] @@ -122,7 +122,7 @@ func Parse(e string) (*expr, string, error) { return &expr{str: val, etype: etString}, e, err } - name, e := parseName(e) + name, e := parseName(e, keyvalue) if name == "" { return nil, e, ErrMissingArg @@ -167,7 +167,7 @@ func parseArgList(e string) (string, []*expr, map[string]*expr, string, error) { for { var arg *expr var err error - arg, e, err = Parse(e) + arg, e, err = Parse(e, true) if err != nil { return "", nil, nil, e, err } @@ -179,7 +179,7 @@ func parseArgList(e string) (string, []*expr, map[string]*expr, string, error) { // we now know we're parsing a key-value pair if arg.etype == etName && e[0] == '=' { e = e[1:] - argCont, eCont, errCont := Parse(e) + argCont, eCont, errCont := Parse(e, true) if errCont != nil { return "", nil, nil, eCont, errCont } @@ -261,14 +261,14 @@ func parseConst(s string) (*expr, string, error) { return &expr{int: v, str: s[:i], etype: etInt}, s[i:], err } -func parseName(s string) (string, string) { +func parseName(s string, keyvalue bool) (string, string) { var i int FOR: for braces := 0; i < len(s); i++ { - if isNameChar(s[i]) { + if isNameChar(s[i]) || (!keyvalue && s[i] == 61) { continue } diff --git a/expr/parse_test.go b/expr/parse_test.go index b4bf6d7935..f5519ce941 100644 --- a/expr/parse_test.go +++ b/expr/parse_test.go @@ -28,6 +28,11 @@ func TestParse(t *testing.T) { &expr{str: "metric.*.foo"}, nil, }, + { + "a.b.c;tagkey1=tagvalue1;tagkey2=tagvalue2", + &expr{str: "a.b.c;tagkey1=tagvalue1;tagkey2=tagvalue2"}, + nil, + }, { "func(metric)", &expr{ @@ -330,7 +335,7 @@ func TestParse(t *testing.T) { } for _, tt := range tests { - e, _, err := Parse(tt.s) + e, _, err := Parse(tt.s, false) if err != tt.err { t.Errorf("case %+v expected err %v, got %v", tt.s, tt.err, err) continue