From f7da9b2db27efc4b16d89251b5965a45327813bf Mon Sep 17 00:00:00 2001 From: Aliaksandr Valialkin Date: Mon, 25 Nov 2019 16:13:13 +0200 Subject: [PATCH] app/vmselect/promql: allow nested parens --- app/vmselect/promql/exec_test.go | 29 +++++++++++++++++++++++++++++ app/vmselect/promql/parser.go | 8 ++++++-- app/vmselect/promql/parser_test.go | 2 ++ 3 files changed, 37 insertions(+), 2 deletions(-) diff --git a/app/vmselect/promql/exec_test.go b/app/vmselect/promql/exec_test.go index 16a95c3f0b..424d0c244c 100644 --- a/app/vmselect/promql/exec_test.go +++ b/app/vmselect/promql/exec_test.go @@ -4204,6 +4204,35 @@ func TestExecSuccess(t *testing.T) { resultExpected := []netstorage.Result{r1, r2} f(q, resultExpected) }) + t.Run(`((1),(2,3))`, func(t *testing.T) { + t.Parallel() + q := `(( + alias(1, "x1"), + ),( + alias(2, "x2"), + alias(3, "x3"), + ))` + r1 := netstorage.Result{ + MetricName: metricNameExpected, + Values: []float64{1, 1, 1, 1, 1, 1}, + Timestamps: timestampsExpected, + } + r1.MetricName.MetricGroup = []byte("x1") + r2 := netstorage.Result{ + MetricName: metricNameExpected, + Values: []float64{2, 2, 2, 2, 2, 2}, + Timestamps: timestampsExpected, + } + r2.MetricName.MetricGroup = []byte("x2") + r3 := netstorage.Result{ + MetricName: metricNameExpected, + Values: []float64{3, 3, 3, 3, 3, 3}, + Timestamps: timestampsExpected, + } + r3.MetricName.MetricGroup = []byte("x3") + resultExpected := []netstorage.Result{r1, r2, r3} + f(q, resultExpected) + }) t.Run(`union(more-than-two)`, func(t *testing.T) { t.Parallel() q := `union( diff --git a/app/vmselect/promql/parser.go b/app/vmselect/promql/parser.go index dffd367729..28a75ed91e 100644 --- a/app/vmselect/promql/parser.go +++ b/app/vmselect/promql/parser.go @@ -116,13 +116,17 @@ func removeParensExpr(e expr) expr { return fe } if pe, ok := e.(*parensExpr); ok { + args := *pe + for i, arg := range args { + args[i] = removeParensExpr(arg) + } if len(*pe) == 1 { - return removeParensExpr((*pe)[0]) + return args[0] } // Treat parensExpr as a function with empty name, i.e. union() fe := &funcExpr{ Name: "", - Args: *pe, + Args: args, } return fe } diff --git a/app/vmselect/promql/parser_test.go b/app/vmselect/promql/parser_test.go index 1ef8554cbb..1fab9189e9 100644 --- a/app/vmselect/promql/parser_test.go +++ b/app/vmselect/promql/parser_test.go @@ -252,6 +252,8 @@ func TestParsePromQLSuccess(t *testing.T) { another(`(-foo + ((bar) / (baz))) + ((23))`, `((0 - foo) + (bar / baz)) + 23`) another(`(FOO + ((Bar) / (baZ))) + ((23))`, `(FOO + (Bar / baZ)) + 23`) same(`(foo, bar)`) + another(`((foo, bar),(baz))`, `((foo, bar), baz)`) + same(`(foo, (bar, baz), ((x, y), (z, y), xx))`) another(`1+(foo, bar,)`, `1 + (foo, bar)`) another(`((foo(bar,baz)), (1+(2)+(3,4)+()))`, `(foo(bar, baz), (3 + (3, 4)) + ())`) same(`()`)