Skip to content

Commit 6dfd530

Browse files
committed
preserve parens if op prioiry not the same
1 parent 627ade1 commit 6dfd530

File tree

4 files changed

+47
-24
lines changed

4 files changed

+47
-24
lines changed

optimizer_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ func TestPushdownBinaryOpFilters(t *testing.T) {
5050
f(`foo * ignoring(x) bar`, `{a="b"}`, `foo{a="b"} * ignoring(x) bar{a="b"}`)
5151
f(`foo{f1!~"x"} UNLEss bar{f2=~"y.+"}`, `{a="b",x=~"y"}`, `foo{a="b",f1!~"x",x=~"y"} unless bar{a="b",f2=~"y.+",x=~"y"}`)
5252
f(`a / sum(x)`, `{a="b",c=~"foo|bar"}`, `a{a="b",c=~"foo|bar"} / sum(x)`)
53-
f(`round(rate(x[5m] offset -1h)) + 123 / {a="b"}`, `{x!="y"}`, `round(rate(x{x!="y"}[5m] offset -1h)) + 123 / {a="b",x!="y"}`)
53+
f(`round(rate(x[5m] offset -1h)) + 123 / {a="b"}`, `{x!="y"}`, `round(rate(x{x!="y"}[5m] offset -1h)) + (123 / {a="b",x!="y"})`)
5454
f(`scalar(foo)+bar`, `{a="b"}`, `scalar(foo) + bar{a="b"}`)
5555
f(`vector(foo)`, `{a="b"}`, `vector(foo{a="b"})`)
5656
f(`{a="b"} + on() group_left() {c="d"}`, `{a="b"}`, `{a="b"} + on() group_left() {c="d"}`)

parser.go

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1977,13 +1977,9 @@ func (be *BinaryOpExpr) appendModifiers(dst []byte) []byte {
19771977
func needBinaryOpArgParens(arg Expr, parentOp string) bool {
19781978
switch t := arg.(type) {
19791979
case *BinaryOpExpr:
1980-
// Parens are required when the child op has lower priority than the parent op,
1981-
// since removing them would change the evaluation order.
1982-
if binaryOpPriority(t.Op) < binaryOpPriority(parentOp) {
1983-
return true
1984-
}
1985-
1986-
if parentOp != "+" && parentOp != "-" && parentOp != "*" && parentOp != "/" {
1980+
// Parens are required when the child op priority not equal to parent o one.
1981+
// For example, a + b / c - d should be a + (b / c) - d.
1982+
if binaryOpPriority(t.Op) != binaryOpPriority(parentOp) {
19871983
return true
19881984
}
19891985

@@ -2005,6 +2001,8 @@ func isBinaryOpLeafSimple(arg Expr) bool {
20052001
return true
20062002
case *MetricExpr:
20072003
metricName := t.getMetricName()
2004+
// Parens should be added if metric name equals to a reserved word, such as group_left
2005+
// For example, a + group_left should become a + (group_left). Otherwise, query won't be parsed.
20082006
return !isReservedBinaryOpIdent(metricName)
20092007
case *BinaryOpExpr:
20102008
if t.GroupModifier.Op != "" || t.KeepMetricNames || t.JoinModifier.Op != "" {

parser_test.go

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -397,8 +397,8 @@ func TestParseSuccess(t *testing.T) {
397397
another(`group_left / (sum(1, 2))`, `group_left / sum(1, 2)`)
398398

399399
// parensExpr
400-
another(`(-foo + ((bar) / (baz))) + ((23))`, `0 - foo + bar / baz + 23`)
401-
another(`(FOO + ((Bar) / (baZ))) + ((23))`, `FOO + Bar / baZ + 23`)
400+
another(`(-foo + ((bar) / (baz))) + ((23))`, `0 - foo + (bar / baz) + 23`)
401+
another(`(FOO + ((Bar) / (baZ))) + ((23))`, `FOO + (Bar / baZ) + 23`)
402402
same(`(foo, bar)`)
403403
another(`((foo, bar),(baz))`, `((foo, bar), baz)`)
404404
same(`(foo, (bar, baz), ((x, y), (z, y), xx))`)
@@ -488,7 +488,7 @@ func TestParseSuccess(t *testing.T) {
488488
another(`with (foo(bar) = {__name__!="bar"}) foo(x)`, `{__name__!="bar"}`)
489489
another(`with (foo(bar) = bar{__name__="bar"}) foo(x)`, `x`)
490490
another(`with (foo\-bar(baz) = baz + baz) foo\-bar((x,y))`, `(x, y) + (x, y)`)
491-
another(`with (foo\-bar(baz) = baz + baz) foo\-bar(x*y)`, `x * y + x * y`)
491+
another(`with (foo\-bar(baz) = baz + baz) foo\-bar(x*y)`, `(x * y) + (x * y)`)
492492
another(`with (foo\-bar(baz) = baz + baz) foo\-bar(x\*y)`, `x\*y + x\*y`)
493493
another(`with (foo\-bar(b\ az) = b\ az + b\ az) foo\-bar(x\*y)`, `x\*y + x\*y`)
494494

@@ -572,7 +572,7 @@ func TestParseSuccess(t *testing.T) {
572572
// Verify nested with exprs
573573
another(`with (f(x) = (with(x=y) x) + x) f(z)`, `y + z`)
574574
another(`with (x=foo) clamp_min(a, with (y=x) y)`, `clamp_min(a, foo)`)
575-
another(`with (x=foo) a * x + (with (y=x) y) / y`, `a * foo + foo / y`)
575+
another(`with (x=foo) a * x + (with (y=x) y) / y`, `(a * foo) + (foo / y)`)
576576
another(`with (x = with (y = foo) y + x) x/x`, `(foo + x) / (foo + x)`)
577577
another(`with (
578578
x = {foo="bar"},
@@ -583,7 +583,7 @@ func TestParseSuccess(t *testing.T) {
583583
)
584584
z(foo) / changes(x)
585585
)
586-
f(a)`, `(a + foo * m{foo="bar",y="1"}) / changes(a)`)
586+
f(a)`, `(a + (foo * m{foo="bar",y="1"})) / changes(a)`)
587587

588588
// complex withExpr
589589
another(`WITH (
@@ -601,7 +601,7 @@ func TestParseSuccess(t *testing.T) {
601601
f(x, y) = x2(x) + x*y + x2(y)
602602
)
603603
f(a, 3)
604-
`, `a ^ 2 + a * 3 + 9`)
604+
`, `(a ^ 2) + (a * 3) + 9`)
605605
another(`WITH (
606606
x2(x) = x^2,
607607
f(x, y) = x2(x) + x*y + x2(y)
@@ -633,7 +633,7 @@ func TestParseSuccess(t *testing.T) {
633633
another(`with (rate(a,b)=a+b) rate(1,2)`, `3`)
634634
another(`with (now=now(), sum=sum()) x`, `x`)
635635
another(`with (rate(a) = b) c`, `c`)
636-
another(`rate(x) + with (rate(a,b)=a*b) rate(2,b)`, `rate(x) + 2 * b`)
636+
another(`rate(x) + with (rate(a,b)=a*b) rate(2,b)`, `rate(x) + (2 * b)`)
637637
another(`with (sum(a,b)=a+b) sum(c,d)`, `c + d`)
638638

639639
// $__interval and $__rate_interval must be replaced with 1i

prettifier_test.go

Lines changed: 34 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -258,7 +258,7 @@ x + sum(y)`)
258258
`WITH (
259259
x = a{b="c"} + WITH (q = we{rt="z"}) q,
260260
)
261-
abc / x + WITH (rt = 234 + 234) 2 * rt + poasdfklkjlkjfdsfjklfdfdsfdsfddfsfd`)
261+
(abc / x) + WITH (rt = 234 + 234) (2 * rt) + poasdfklkjlkjfdsfjklfdfdsfdsfddfsfd`)
262262

263263
// duration replacement in WITH expression
264264
another(`WITH(BAR=1m,x(BAZ)=sum(rate({a="b"}[BAR:BAZ])) offset BAR) x`, `WITH (BAR = 1m, x(BAZ) = sum(rate({a="b"}[BAR:BAZ])) offset BAR) x`)
@@ -284,19 +284,44 @@ abc / x + WITH (rt = 234 + 234) 2 * rt + poasdfklkjlkjfdsfjklfdfdsfdsfddfsfd`)
284284

285285
// see https://github.com/VictoriaMetrics/metricsql/issues/54
286286
another(`(1 - (node_memory_MemFree_bytes + node_memory_Cached_bytes + node_memory_Buffers_bytes + node_memory_SReclaimable_bytes) / node_memory_MemTotal_bytes) * 100`,
287-
`(
287+
`
288+
(
288289
1
289290
-
290291
(
291-
node_memory_MemFree_bytes + node_memory_Cached_bytes
292-
+
293-
node_memory_Buffers_bytes
294-
+
295-
node_memory_SReclaimable_bytes
292+
(
293+
node_memory_MemFree_bytes + node_memory_Cached_bytes
294+
+
295+
node_memory_Buffers_bytes
296+
+
297+
node_memory_SReclaimable_bytes
298+
)
299+
/
300+
node_memory_MemTotal_bytes
296301
)
297-
/
298-
node_memory_MemTotal_bytes
299302
)
300303
*
301304
100`)
305+
306+
`
307+
(
308+
1
309+
-
310+
(
311+
(
312+
(
313+
(node_memory_MemFree_bytes + node_memory_Cached_bytes)
314+
+
315+
node_memory_Buffers_bytes
316+
)
317+
+
318+
node_memory_SReclaimable_bytes
319+
)
320+
/
321+
node_memory_MemTotal_bytes
322+
)
323+
)
324+
*
325+
100
326+
`
302327
}

0 commit comments

Comments
 (0)