From 844ce4731ef72ce805b0f8e211bd555f919fcdfa Mon Sep 17 00:00:00 2001 From: Aliaksandr Valialkin Date: Tue, 25 Jun 2019 20:24:17 +0300 Subject: [PATCH] app/vmselect/promql: suppress error when template func is used inside modifier list. Just leave it as is Fixes https://github.com/VictoriaMetrics/VictoriaMetrics/issues/78 --- app/vmselect/promql/parser.go | 16 +++++++++++++++- app/vmselect/promql/parser_test.go | 12 +++++++++--- 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/app/vmselect/promql/parser.go b/app/vmselect/promql/parser.go index fddfd8c69..6c72690d0 100644 --- a/app/vmselect/promql/parser.go +++ b/app/vmselect/promql/parser.go @@ -811,7 +811,9 @@ func expandModifierArgs(was []*withArgExpr, args []string) ([]string, error) { continue } if len(wa.Args) > 0 { - return nil, fmt.Errorf("cannot use func %q instead of %q in %s", wa.Name, arg, args) + // Template funcs cannot be used inside modifier list. Leave the arg as is. + dstArgs = append(dstArgs, arg) + continue } me, ok := wa.Expr.(*metricExpr) if ok { @@ -851,6 +853,10 @@ func expandModifierArgs(was []*withArgExpr, args []string) ([]string, error) { func expandWithExprExt(was []*withArgExpr, wa *withArgExpr, args []expr) (expr, error) { if len(wa.Args) != len(args) { + if args == nil { + // Just return metricExpr with the wa.Name name. + return newMetricExpr(wa.Name), nil + } return nil, fmt.Errorf("invalid number of args for %q; got %d; want %d", wa.Name, len(args), len(wa.Args)) } wasNew := make([]*withArgExpr, 0, len(was)+len(args)) @@ -869,6 +875,14 @@ func expandWithExprExt(was []*withArgExpr, wa *withArgExpr, args []expr) (expr, return expandWithExpr(wasNew, wa.Expr) } +func newMetricExpr(name string) *metricExpr { + return &metricExpr{ + TagFilters: []storage.TagFilter{{ + Value: []byte(name), + }}, + } +} + func extractStringValue(token string) (string, error) { if !isStringPrefix(token) { return "", fmt.Errorf(`stringExpr must contain only string literals; got %q`, token) diff --git a/app/vmselect/promql/parser_test.go b/app/vmselect/promql/parser_test.go index 8f4d35089..cc90abf19 100644 --- a/app/vmselect/promql/parser_test.go +++ b/app/vmselect/promql/parser_test.go @@ -118,6 +118,10 @@ func TestParsePromQLSuccess(t *testing.T) { same("with") same("WITH") same("With") + same("alias") + same(`alias{foo="bar"}`) + same(`aLIas{alias="aa"}`) + another(`al\ias`, `alias`) // identifiers with with escape chars same(`foo\ bar`) same(`foo\-bar\{{baz\+bar="aa"}`) @@ -345,8 +349,11 @@ func TestParsePromQLSuccess(t *testing.T) { another(`with (x="a", y=x) y+"bc"`, `"abc"`) another(`with (x="a", y="b"+x) "we"+y+"z"+f()`, `"webaz" + f()`) another(`with (f(x) = m{foo=x+"y", bar="y"+x, baz=x} + x) f("qwe")`, `m{foo="qwey", bar="yqwe", baz="qwe"} + "qwe"`) + another(`with (f(a)=a) f`, `f`) + another(`with (f\q(a)=a) f\q`, `fq`) // Verify withExpr for aggr func modifiers + another(`with (f(x) = x, y = sum(m) by (f)) y`, `sum(m) by (f)`) another(`with (f(x) = sum(m) by (x)) f(foo)`, `sum(m) by (foo)`) another(`with (f(x) = sum(m) by (x)) f((foo, bar, foo))`, `sum(m) by (foo, bar)`) another(`with (f(x) = sum(m) without (x,y)) f((a, b))`, `sum(m) without (a, b, y)`) @@ -671,7 +678,7 @@ func TestParsePromQLError(t *testing.T) { f(`with (x=m) f(b, a{x})`) f(`with (x=m) sum(a{x})`) f(`with (x=m) (a{x})`) - f(`with (f(a)=a) f`) + f(`with (f(a)=a) f(1, 2)`) f(`with (f(x)=x{foo="bar"}) f(1)`) f(`with (f(x)=x{foo="bar"}) f(m + n)`) f(`with (f = with`) @@ -681,8 +688,7 @@ func TestParsePromQLError(t *testing.T) { f(`with (f(,)=x) x`) f(`with (x(a) = {b="c"}) foo{x}`) f(`with (f(x) = m{foo=xx}) f("qwe")`) - f(`a + with(f(x)=x) f`) - f(`with (f(x) = x, y = sum(m) by (f)) y`) + f(`a + with(f(x)=x) f(1,2)`) f(`with (f(x) = sum(m) by (x)) f({foo="bar"})`) f(`with (f(x) = sum(m) by (x)) f((xx(), {foo="bar"}))`) f(`with (f(x) = m + on (x) n) f(xx())`)