From 22652359d3fb8ce1ce2c7c1ec220674a736a07f9 Mon Sep 17 00:00:00 2001 From: Owen Williams Date: Fri, 8 Dec 2023 14:15:32 -0500 Subject: [PATCH] Code was already working, added working tests --- promql/parser/generated_parser.y | 23 +- promql/parser/generated_parser.y.go | 5 + promql/parser/parse.go | 2 + promql/parser/parse_test.go | 7110 ++++++++++++++------------- 4 files changed, 3572 insertions(+), 3568 deletions(-) diff --git a/promql/parser/generated_parser.y b/promql/parser/generated_parser.y index c10a7a5990..5f5e2a1d73 100644 --- a/promql/parser/generated_parser.y +++ b/promql/parser/generated_parser.y @@ -586,10 +586,7 @@ label_matcher : IDENTIFIER match_op STRING | string_identifier match_op STRING { $$ = yylex.(*parser).newLabelMatcher($1, $2, $3); } | string_identifier - { - // metric name matcher! - $$ = yylex.(*parser).newMetricNameMatcher($1); - } + { $$ = yylex.(*parser).newMetricNameMatcher($1); } | IDENTIFIER match_op error { yylex.(*parser).unexpected("label matching", "string"); $$ = nil} | IDENTIFIER error @@ -612,10 +609,7 @@ metric : metric_identifier label_set metric_identifier: AVG | BOTTOMK | BY | COUNT | COUNT_VALUES | GROUP | IDENTIFIER | LAND | LOR | LUNLESS | MAX | METRIC_IDENTIFIER | MIN | OFFSET | QUANTILE | STDDEV | STDVAR | SUM | TOPK | WITHOUT | START | END; label_set : LEFT_BRACE label_set_list RIGHT_BRACE - { - // LEFT_BRACE label_set_list RIGHT_BRACE - $$ = labels.New($2...) - } + { $$ = labels.New($2...) } | LEFT_BRACE label_set_list COMMA RIGHT_BRACE { $$ = labels.New($2...) } | LEFT_BRACE RIGHT_BRACE @@ -634,17 +628,7 @@ label_set_list : label_set_list COMMA label_set_item ; label_set_item : IDENTIFIER EQL STRING - { - // ident eq string - $$ = labels.Label{Name: $1.Val, Value: yylex.(*parser).unquoteString($3.Val) } } - // | STRING EQL STRING - // { - // // string eq string - // $$ = labels.Label{Name: yylex.(*parser).unquoteString($3.Val), Value: yylex.(*parser).unquoteString($3.Val) } } - // | STRING - // { - // // looks good? - // $$ = labels.Label{Name: labels.MetricName, Value: yylex.(*parser).unquoteString($1.Val) } } + { $$ = labels.Label{Name: $1.Val, Value: yylex.(*parser).unquoteString($3.Val) } } | IDENTIFIER EQL error { yylex.(*parser).unexpected("label set", "string"); $$ = labels.Label{}} | IDENTIFIER error @@ -925,7 +909,6 @@ string_literal : STRING string_identifier : STRING { - // string_identifier $$ = Item{ Typ: METRIC_IDENTIFIER, Pos: $1.PositionRange().Start, diff --git a/promql/parser/generated_parser.y.go b/promql/parser/generated_parser.y.go index 54d6773106..dde640cc87 100644 --- a/promql/parser/generated_parser.y.go +++ b/promql/parser/generated_parser.y.go @@ -1404,7 +1404,10 @@ yydefault: case 85: yyDollar = yyS[yypt-3 : yypt+1] { + // label_matchers + // name := yylex.(*parser).findNameMatcher($2) yyVAL.node = &VectorSelector{ + // Name: name, LabelMatchers: yyDollar[2].matchers, PosRange: mergeRanges(&yyDollar[1].item, &yyDollar[3].item), } @@ -1412,7 +1415,9 @@ yydefault: case 86: yyDollar = yyS[yypt-4 : yypt+1] { + // name := yylex.(*parser).findNameMatcher($2) yyVAL.node = &VectorSelector{ + // Name: name, LabelMatchers: yyDollar[2].matchers, PosRange: mergeRanges(&yyDollar[1].item, &yyDollar[4].item), } diff --git a/promql/parser/parse.go b/promql/parser/parse.go index c176f4531f..12939b24e6 100644 --- a/promql/parser/parse.go +++ b/promql/parser/parse.go @@ -403,6 +403,8 @@ func (p *parser) newBinaryExpression(lhs Node, op Item, modifiers, rhs Node) *Bi } func (p *parser) assembleVectorSelector(vs *VectorSelector) { + // If the metric name was set outside the braces, add a matcher for it. + // If the metric name was inside the braces we don't need to do anything. if vs.Name != "" { nameMatcher, err := labels.NewMatcher(labels.MatchEqual, labels.MetricName, vs.Name) if err != nil { diff --git a/promql/parser/parse_test.go b/promql/parser/parse_test.go index 47c15ac6cc..2d764511e5 100644 --- a/promql/parser/parse_test.go +++ b/promql/parser/parse_test.go @@ -15,8 +15,11 @@ package parser import ( "errors" + "fmt" "math" + "strings" "testing" + "time" "github.com/prometheus/common/model" "github.com/stretchr/testify/require" @@ -34,3565 +37,3579 @@ var testExpr = []struct { errMsg string // If not empty the parsing error has to contain this string. }{ // Scalars and scalar-to-scalar operations. - // { - // input: "1", - // expected: &NumberLiteral{ - // Val: 1, - // PosRange: posrange.PositionRange{Start: 0, End: 1}, - // }, - // }, - // { - // input: "+Inf", - // expected: &NumberLiteral{ - // Val: math.Inf(1), - // PosRange: posrange.PositionRange{Start: 0, End: 4}, - // }, - // }, - // { - // input: "-Inf", - // expected: &NumberLiteral{ - // Val: math.Inf(-1), - // PosRange: posrange.PositionRange{Start: 0, End: 4}, - // }, - // }, - // { - // input: ".5", - // expected: &NumberLiteral{ - // Val: 0.5, - // PosRange: posrange.PositionRange{Start: 0, End: 2}, - // }, - // }, - // { - // input: "5.", - // expected: &NumberLiteral{ - // Val: 5, - // PosRange: posrange.PositionRange{Start: 0, End: 2}, - // }, - // }, - // { - // input: "123.4567", - // expected: &NumberLiteral{ - // Val: 123.4567, - // PosRange: posrange.PositionRange{Start: 0, End: 8}, - // }, - // }, - // { - // input: "5e-3", - // expected: &NumberLiteral{ - // Val: 0.005, - // PosRange: posrange.PositionRange{Start: 0, End: 4}, - // }, - // }, - // { - // input: "5e3", - // expected: &NumberLiteral{ - // Val: 5000, - // PosRange: posrange.PositionRange{Start: 0, End: 3}, - // }, - // }, - // { - // input: "0xc", - // expected: &NumberLiteral{ - // Val: 12, - // PosRange: posrange.PositionRange{Start: 0, End: 3}, - // }, - // }, - // { - // input: "0755", - // expected: &NumberLiteral{ - // Val: 493, - // PosRange: posrange.PositionRange{Start: 0, End: 4}, - // }, - // }, - // { - // input: "+5.5e-3", - // expected: &NumberLiteral{ - // Val: 0.0055, - // PosRange: posrange.PositionRange{Start: 0, End: 7}, - // }, - // }, - // { - // input: "-0755", - // expected: &NumberLiteral{ - // Val: -493, - // PosRange: posrange.PositionRange{Start: 0, End: 5}, - // }, - // }, - // { - // input: "1 + 1", - // expected: &BinaryExpr{ - // Op: ADD, - // LHS: &NumberLiteral{ - // Val: 1, - // PosRange: posrange.PositionRange{Start: 0, End: 1}, - // }, - // RHS: &NumberLiteral{ - // Val: 1, - // PosRange: posrange.PositionRange{Start: 4, End: 5}, - // }, - // }, - // }, - // { - // input: "1 - 1", - // expected: &BinaryExpr{ - // Op: SUB, - // LHS: &NumberLiteral{ - // Val: 1, - // PosRange: posrange.PositionRange{Start: 0, End: 1}, - // }, - // RHS: &NumberLiteral{ - // Val: 1, - // PosRange: posrange.PositionRange{Start: 4, End: 5}, - // }, - // }, - // }, - // { - // input: "1 * 1", - // expected: &BinaryExpr{ - // Op: MUL, - // LHS: &NumberLiteral{ - // Val: 1, - // PosRange: posrange.PositionRange{Start: 0, End: 1}, - // }, - // RHS: &NumberLiteral{ - // Val: 1, - // PosRange: posrange.PositionRange{Start: 4, End: 5}, - // }, - // }, - // }, - // { - // input: "1 % 1", - // expected: &BinaryExpr{ - // Op: MOD, - // LHS: &NumberLiteral{ - // Val: 1, - // PosRange: posrange.PositionRange{Start: 0, End: 1}, - // }, - // RHS: &NumberLiteral{ - // Val: 1, - // PosRange: posrange.PositionRange{Start: 4, End: 5}, - // }, - // }, - // }, - // { - // input: "1 / 1", - // expected: &BinaryExpr{ - // Op: DIV, - // LHS: &NumberLiteral{ - // Val: 1, - // PosRange: posrange.PositionRange{Start: 0, End: 1}, - // }, - // RHS: &NumberLiteral{ - // Val: 1, - // PosRange: posrange.PositionRange{Start: 4, End: 5}, - // }, - // }, - // }, - // { - // input: "1 == bool 1", - // expected: &BinaryExpr{ - // Op: EQLC, - // LHS: &NumberLiteral{ - // Val: 1, - // PosRange: posrange.PositionRange{Start: 0, End: 1}, - // }, - // RHS: &NumberLiteral{ - // Val: 1, - // PosRange: posrange.PositionRange{Start: 10, End: 11}, - // }, - // ReturnBool: true, - // }, - // }, - // { - // input: "1 != bool 1", - // expected: &BinaryExpr{ - // Op: NEQ, - // LHS: &NumberLiteral{ - // Val: 1, - // PosRange: posrange.PositionRange{Start: 0, End: 1}, - // }, - // RHS: &NumberLiteral{ - // Val: 1, - // PosRange: posrange.PositionRange{Start: 10, End: 11}, - // }, - // ReturnBool: true, - // }, - // }, - // { - // input: "1 > bool 1", - // expected: &BinaryExpr{ - // Op: GTR, - // LHS: &NumberLiteral{ - // Val: 1, - // PosRange: posrange.PositionRange{Start: 0, End: 1}, - // }, - // RHS: &NumberLiteral{ - // Val: 1, - // PosRange: posrange.PositionRange{Start: 9, End: 10}, - // }, - // ReturnBool: true, - // }, - // }, - // { - // input: "1 >= bool 1", - // expected: &BinaryExpr{ - // Op: GTE, - // LHS: &NumberLiteral{ - // Val: 1, - // PosRange: posrange.PositionRange{Start: 0, End: 1}, - // }, - // RHS: &NumberLiteral{ - // Val: 1, - // PosRange: posrange.PositionRange{Start: 10, End: 11}, - // }, - // ReturnBool: true, - // }, - // }, - // { - // input: "1 < bool 1", - // expected: &BinaryExpr{ - // Op: LSS, - // LHS: &NumberLiteral{ - // Val: 1, - // PosRange: posrange.PositionRange{Start: 0, End: 1}, - // }, - // RHS: &NumberLiteral{ - // Val: 1, - // PosRange: posrange.PositionRange{Start: 9, End: 10}, - // }, - // ReturnBool: true, - // }, - // }, - // { - // input: "1 <= bool 1", - // expected: &BinaryExpr{ - // Op: LTE, - // LHS: &NumberLiteral{ - // Val: 1, - // PosRange: posrange.PositionRange{Start: 0, End: 1}, - // }, - // RHS: &NumberLiteral{ - // Val: 1, - // PosRange: posrange.PositionRange{Start: 10, End: 11}, - // }, - // ReturnBool: true, - // }, - // }, - // { - // input: "-1^2", - // expected: &UnaryExpr{ - // Op: SUB, - // Expr: &BinaryExpr{ - // Op: POW, - // LHS: &NumberLiteral{ - // Val: 1, - // PosRange: posrange.PositionRange{Start: 1, End: 2}, - // }, - // RHS: &NumberLiteral{ - // Val: 2, - // PosRange: posrange.PositionRange{Start: 3, End: 4}, - // }, - // }, - // }, - // }, - // { - // input: "-1*2", - // expected: &BinaryExpr{ - // Op: MUL, - // LHS: &NumberLiteral{ - // Val: -1, - // PosRange: posrange.PositionRange{Start: 0, End: 2}, - // }, - // RHS: &NumberLiteral{ - // Val: 2, - // PosRange: posrange.PositionRange{Start: 3, End: 4}, - // }, - // }, - // }, - // { - // input: "-1+2", - // expected: &BinaryExpr{ - // Op: ADD, - // LHS: &NumberLiteral{ - // Val: -1, - // PosRange: posrange.PositionRange{Start: 0, End: 2}, - // }, - // RHS: &NumberLiteral{ - // Val: 2, - // PosRange: posrange.PositionRange{Start: 3, End: 4}, - // }, - // }, - // }, - // { - // input: "-1^-2", - // expected: &UnaryExpr{ - // Op: SUB, - // Expr: &BinaryExpr{ - // Op: POW, - // LHS: &NumberLiteral{ - // Val: 1, - // PosRange: posrange.PositionRange{Start: 1, End: 2}, - // }, - // RHS: &NumberLiteral{ - // Val: -2, - // PosRange: posrange.PositionRange{Start: 3, End: 5}, - // }, - // }, - // }, - // }, - // { - // input: "+1 + -2 * 1", - // expected: &BinaryExpr{ - // Op: ADD, - // LHS: &NumberLiteral{ - // Val: 1, - // PosRange: posrange.PositionRange{Start: 0, End: 2}, - // }, - // RHS: &BinaryExpr{ - // Op: MUL, - // LHS: &NumberLiteral{ - // Val: -2, - // PosRange: posrange.PositionRange{Start: 5, End: 7}, - // }, - // RHS: &NumberLiteral{ - // Val: 1, - // PosRange: posrange.PositionRange{Start: 10, End: 11}, - // }, - // }, - // }, - // }, - // { - // input: "1 + 2/(3*1)", - // expected: &BinaryExpr{ - // Op: ADD, - // LHS: &NumberLiteral{ - // Val: 1, - // PosRange: posrange.PositionRange{Start: 0, End: 1}, - // }, - // RHS: &BinaryExpr{ - // Op: DIV, - // LHS: &NumberLiteral{ - // Val: 2, - // PosRange: posrange.PositionRange{Start: 4, End: 5}, - // }, - // RHS: &ParenExpr{ - // Expr: &BinaryExpr{ - // Op: MUL, - // LHS: &NumberLiteral{ - // Val: 3, - // PosRange: posrange.PositionRange{Start: 7, End: 8}, - // }, - // RHS: &NumberLiteral{ - // Val: 1, - // PosRange: posrange.PositionRange{Start: 9, End: 10}, - // }, - // }, - // PosRange: posrange.PositionRange{Start: 6, End: 11}, - // }, - // }, - // }, - // }, - // { - // input: "1 < bool 2 - 1 * 2", - // expected: &BinaryExpr{ - // Op: LSS, - // ReturnBool: true, - // LHS: &NumberLiteral{ - // Val: 1, - // PosRange: posrange.PositionRange{Start: 0, End: 1}, - // }, - // RHS: &BinaryExpr{ - // Op: SUB, - // LHS: &NumberLiteral{ - // Val: 2, - // PosRange: posrange.PositionRange{Start: 9, End: 10}, - // }, - // RHS: &BinaryExpr{ - // Op: MUL, - // LHS: &NumberLiteral{ - // Val: 1, - // PosRange: posrange.PositionRange{Start: 13, End: 14}, - // }, - // RHS: &NumberLiteral{ - // Val: 2, - // PosRange: posrange.PositionRange{Start: 17, End: 18}, - // }, - // }, - // }, - // }, - // }, - // { - // input: "-some_metric", - // expected: &UnaryExpr{ - // Op: SUB, - // Expr: &VectorSelector{ - // Name: "some_metric", - // LabelMatchers: []*labels.Matcher{ - // MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "some_metric"), - // }, - // PosRange: posrange.PositionRange{ - // Start: 1, - // End: 12, - // }, - // }, - // }, - // }, - // { - // input: "+some_metric", - // expected: &UnaryExpr{ - // Op: ADD, - // Expr: &VectorSelector{ - // Name: "some_metric", - // LabelMatchers: []*labels.Matcher{ - // MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "some_metric"), - // }, - // PosRange: posrange.PositionRange{ - // Start: 1, - // End: 12, - // }, - // }, - // }, - // }, - // { - // input: " +some_metric", - // expected: &UnaryExpr{ - // Op: ADD, - // Expr: &VectorSelector{ - // Name: "some_metric", - // LabelMatchers: []*labels.Matcher{ - // MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "some_metric"), - // }, - // PosRange: posrange.PositionRange{ - // Start: 2, - // End: 13, - // }, - // }, - // StartPos: 1, - // }, - // }, - // { - // input: ` +{"some_metric"}`, - // expected: &UnaryExpr{ - // Op: ADD, - // Expr: &VectorSelector{ - // Name: "some_metric", - // LabelMatchers: []*labels.Matcher{ - // MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "some_metric"), - // }, - // PosRange: posrange.PositionRange{ - // Start: 2, - // End: 17, - // }, - // }, - // StartPos: 1, - // }, - // }, - // { - // input: "", - // fail: true, - // errMsg: "no expression found in input", - // }, - // { - // input: "# just a comment\n\n", - // fail: true, - // errMsg: "no expression found in input", - // }, - // { - // input: "1+", - // fail: true, - // errMsg: "unexpected end of input", - // }, - // { - // input: ".", - // fail: true, - // errMsg: "unexpected character: '.'", - // }, - // { - // input: "2.5.", - // fail: true, - // errMsg: "unexpected character: '.'", - // }, - // { - // input: "100..4", - // fail: true, - // errMsg: `unexpected number ".4"`, - // }, - // { - // input: "0deadbeef", - // fail: true, - // errMsg: "bad number or duration syntax: \"0de\"", - // }, - // { - // input: "1 /", - // fail: true, - // errMsg: "unexpected end of input", - // }, - // { - // input: "*1", - // fail: true, - // errMsg: "unexpected ", - // }, - // { - // input: "(1))", - // fail: true, - // errMsg: "unexpected right parenthesis ')'", - // }, - // { - // input: "((1)", - // fail: true, - // errMsg: "unclosed left parenthesis", - // }, - // { - // input: "999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999", - // fail: true, - // errMsg: "out of range", - // }, - // { - // input: "(", - // fail: true, - // errMsg: "unclosed left parenthesis", - // }, - // { - // input: "1 and 1", - // fail: true, - // errMsg: "set operator \"and\" not allowed in binary scalar expression", - // }, - // { - // input: "1 == 1", - // fail: true, - // errMsg: "1:3: parse error: comparisons between scalars must use BOOL modifier", - // }, - // { - // input: "1 or 1", - // fail: true, - // errMsg: "set operator \"or\" not allowed in binary scalar expression", - // }, - // { - // input: "1 unless 1", - // fail: true, - // errMsg: "set operator \"unless\" not allowed in binary scalar expression", - // }, - // { - // input: "1 !~ 1", - // fail: true, - // errMsg: `unexpected character after '!': '~'`, - // }, - // { - // input: "1 =~ 1", - // fail: true, - // errMsg: `unexpected character after '=': '~'`, - // }, - // { - // input: `-"string"`, - // fail: true, - // errMsg: `unary expression only allowed on expressions of type scalar or instant vector, got "string"`, - // }, - // { - // input: `-test[5m]`, - // fail: true, - // errMsg: `unary expression only allowed on expressions of type scalar or instant vector, got "range vector"`, - // }, - // { - // input: `*test`, - // fail: true, - // errMsg: "unexpected ", - // }, - // { - // input: "1 offset 1d", - // fail: true, - // errMsg: "1:1: parse error: offset modifier must be preceded by an instant vector selector or range vector selector or a subquery", - // }, - // { - // input: "foo offset 1s offset 2s", - // fail: true, - // errMsg: "offset may not be set multiple times", - // }, - // { - // input: "a - on(b) ignoring(c) d", - // fail: true, - // errMsg: "1:11: parse error: unexpected ", - // }, - // // Vector binary operations. - // { - // input: "foo * bar", - // expected: &BinaryExpr{ - // Op: MUL, - // LHS: &VectorSelector{ - // Name: "foo", - // LabelMatchers: []*labels.Matcher{ - // MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "foo"), - // }, - // PosRange: posrange.PositionRange{ - // Start: 0, - // End: 3, - // }, - // }, - // RHS: &VectorSelector{ - // Name: "bar", - // LabelMatchers: []*labels.Matcher{ - // MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "bar"), - // }, - // PosRange: posrange.PositionRange{ - // Start: 6, - // End: 9, - // }, - // }, - // VectorMatching: &VectorMatching{Card: CardOneToOne}, - // }, - // }, - // { - // input: "foo * sum", - // expected: &BinaryExpr{ - // Op: MUL, - // LHS: &VectorSelector{ - // Name: "foo", - // LabelMatchers: []*labels.Matcher{ - // MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "foo"), - // }, - // PosRange: posrange.PositionRange{ - // Start: 0, - // End: 3, - // }, - // }, - // RHS: &VectorSelector{ - // Name: "sum", - // LabelMatchers: []*labels.Matcher{ - // MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "sum"), - // }, - // PosRange: posrange.PositionRange{ - // Start: 6, - // End: 9, - // }, - // }, - // VectorMatching: &VectorMatching{Card: CardOneToOne}, - // }, - // }, - // { - // input: "foo == 1", - // expected: &BinaryExpr{ - // Op: EQLC, - // LHS: &VectorSelector{ - // Name: "foo", - // LabelMatchers: []*labels.Matcher{ - // MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "foo"), - // }, - // PosRange: posrange.PositionRange{ - // Start: 0, - // End: 3, - // }, - // }, - // RHS: &NumberLiteral{ - // Val: 1, - // PosRange: posrange.PositionRange{Start: 7, End: 8}, - // }, - // }, - // }, - // { - // input: "foo == bool 1", - // expected: &BinaryExpr{ - // Op: EQLC, - // LHS: &VectorSelector{ - // Name: "foo", - // LabelMatchers: []*labels.Matcher{ - // MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "foo"), - // }, - // PosRange: posrange.PositionRange{ - // Start: 0, - // End: 3, - // }, - // }, - // RHS: &NumberLiteral{ - // Val: 1, - // PosRange: posrange.PositionRange{Start: 12, End: 13}, - // }, - // ReturnBool: true, - // }, - // }, - // { - // input: "2.5 / bar", - // expected: &BinaryExpr{ - // Op: DIV, - // LHS: &NumberLiteral{ - // Val: 2.5, - // PosRange: posrange.PositionRange{Start: 0, End: 3}, - // }, - // RHS: &VectorSelector{ - // Name: "bar", - // LabelMatchers: []*labels.Matcher{ - // MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "bar"), - // }, - // PosRange: posrange.PositionRange{ - // Start: 6, - // End: 9, - // }, - // }, - // }, - // }, - // { - // input: "foo and bar", - // expected: &BinaryExpr{ - // Op: LAND, - // LHS: &VectorSelector{ - // Name: "foo", - // LabelMatchers: []*labels.Matcher{ - // MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "foo"), - // }, - // PosRange: posrange.PositionRange{ - // Start: 0, - // End: 3, - // }, - // }, - // RHS: &VectorSelector{ - // Name: "bar", - // LabelMatchers: []*labels.Matcher{ - // MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "bar"), - // }, - // PosRange: posrange.PositionRange{ - // Start: 8, - // End: 11, - // }, - // }, - // VectorMatching: &VectorMatching{Card: CardManyToMany}, - // }, - // }, - // { - // input: "foo or bar", - // expected: &BinaryExpr{ - // Op: LOR, - // LHS: &VectorSelector{ - // Name: "foo", - // LabelMatchers: []*labels.Matcher{ - // MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "foo"), - // }, - // PosRange: posrange.PositionRange{ - // Start: 0, - // End: 3, - // }, - // }, - // RHS: &VectorSelector{ - // Name: "bar", - // LabelMatchers: []*labels.Matcher{ - // MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "bar"), - // }, - // PosRange: posrange.PositionRange{ - // Start: 7, - // End: 10, - // }, - // }, - // VectorMatching: &VectorMatching{Card: CardManyToMany}, - // }, - // }, - // { - // input: "foo unless bar", - // expected: &BinaryExpr{ - // Op: LUNLESS, - // LHS: &VectorSelector{ - // Name: "foo", - // LabelMatchers: []*labels.Matcher{ - // MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "foo"), - // }, - // PosRange: posrange.PositionRange{ - // Start: 0, - // End: 3, - // }, - // }, - // RHS: &VectorSelector{ - // Name: "bar", - // LabelMatchers: []*labels.Matcher{ - // MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "bar"), - // }, - // PosRange: posrange.PositionRange{ - // Start: 11, - // End: 14, - // }, - // }, - // VectorMatching: &VectorMatching{Card: CardManyToMany}, - // }, - // }, - // { - // // Test and/or precedence and reassigning of operands. - // input: "foo + bar or bla and blub", - // expected: &BinaryExpr{ - // Op: LOR, - // LHS: &BinaryExpr{ - // Op: ADD, - // LHS: &VectorSelector{ - // Name: "foo", - // LabelMatchers: []*labels.Matcher{ - // MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "foo"), - // }, - // PosRange: posrange.PositionRange{ - // Start: 0, - // End: 3, - // }, - // }, - // RHS: &VectorSelector{ - // Name: "bar", - // LabelMatchers: []*labels.Matcher{ - // MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "bar"), - // }, - // PosRange: posrange.PositionRange{ - // Start: 6, - // End: 9, - // }, - // }, - // VectorMatching: &VectorMatching{Card: CardOneToOne}, - // }, - // RHS: &BinaryExpr{ - // Op: LAND, - // LHS: &VectorSelector{ - // Name: "bla", - // LabelMatchers: []*labels.Matcher{ - // MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "bla"), - // }, - // PosRange: posrange.PositionRange{ - // Start: 13, - // End: 16, - // }, - // }, - // RHS: &VectorSelector{ - // Name: "blub", - // LabelMatchers: []*labels.Matcher{ - // MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "blub"), - // }, - // PosRange: posrange.PositionRange{ - // Start: 21, - // End: 25, - // }, - // }, - // VectorMatching: &VectorMatching{Card: CardManyToMany}, - // }, - // VectorMatching: &VectorMatching{Card: CardManyToMany}, - // }, - // }, - // { - // // Test and/or/unless precedence. - // input: "foo and bar unless baz or qux", - // expected: &BinaryExpr{ - // Op: LOR, - // LHS: &BinaryExpr{ - // Op: LUNLESS, - // LHS: &BinaryExpr{ - // Op: LAND, - // LHS: &VectorSelector{ - // Name: "foo", - // LabelMatchers: []*labels.Matcher{ - // MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "foo"), - // }, - // PosRange: posrange.PositionRange{ - // Start: 0, - // End: 3, - // }, - // }, - // RHS: &VectorSelector{ - // Name: "bar", - // LabelMatchers: []*labels.Matcher{ - // MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "bar"), - // }, - // PosRange: posrange.PositionRange{ - // Start: 8, - // End: 11, - // }, - // }, - // VectorMatching: &VectorMatching{Card: CardManyToMany}, - // }, - // RHS: &VectorSelector{ - // Name: "baz", - // LabelMatchers: []*labels.Matcher{ - // MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "baz"), - // }, - // PosRange: posrange.PositionRange{ - // Start: 19, - // End: 22, - // }, - // }, - // VectorMatching: &VectorMatching{Card: CardManyToMany}, - // }, - // RHS: &VectorSelector{ - // Name: "qux", - // LabelMatchers: []*labels.Matcher{ - // MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "qux"), - // }, - // PosRange: posrange.PositionRange{ - // Start: 26, - // End: 29, - // }, - // }, - // VectorMatching: &VectorMatching{Card: CardManyToMany}, - // }, - // }, - // { - // // Test precedence and reassigning of operands. - // input: "bar + on(foo) bla / on(baz, buz) group_right(test) blub", - // expected: &BinaryExpr{ - // Op: ADD, - // LHS: &VectorSelector{ - // Name: "bar", - // LabelMatchers: []*labels.Matcher{ - // MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "bar"), - // }, - // PosRange: posrange.PositionRange{ - // Start: 0, - // End: 3, - // }, - // }, - // RHS: &BinaryExpr{ - // Op: DIV, - // LHS: &VectorSelector{ - // Name: "bla", - // LabelMatchers: []*labels.Matcher{ - // MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "bla"), - // }, - // PosRange: posrange.PositionRange{ - // Start: 14, - // End: 17, - // }, - // }, - // RHS: &VectorSelector{ - // Name: "blub", - // LabelMatchers: []*labels.Matcher{ - // MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "blub"), - // }, - // PosRange: posrange.PositionRange{ - // Start: 51, - // End: 55, - // }, - // }, - // VectorMatching: &VectorMatching{ - // Card: CardOneToMany, - // MatchingLabels: []string{"baz", "buz"}, - // On: true, - // Include: []string{"test"}, - // }, - // }, - // VectorMatching: &VectorMatching{ - // Card: CardOneToOne, - // MatchingLabels: []string{"foo"}, - // On: true, - // }, - // }, - // }, - // { - // input: "foo * on(test,blub) bar", - // expected: &BinaryExpr{ - // Op: MUL, - // LHS: &VectorSelector{ - // Name: "foo", - // LabelMatchers: []*labels.Matcher{ - // MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "foo"), - // }, - // PosRange: posrange.PositionRange{ - // Start: 0, - // End: 3, - // }, - // }, - // RHS: &VectorSelector{ - // Name: "bar", - // LabelMatchers: []*labels.Matcher{ - // MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "bar"), - // }, - // PosRange: posrange.PositionRange{ - // Start: 20, - // End: 23, - // }, - // }, - // VectorMatching: &VectorMatching{ - // Card: CardOneToOne, - // MatchingLabels: []string{"test", "blub"}, - // On: true, - // }, - // }, - // }, - // { - // input: "foo * on(test,blub) group_left bar", - // expected: &BinaryExpr{ - // Op: MUL, - // LHS: &VectorSelector{ - // Name: "foo", - // LabelMatchers: []*labels.Matcher{ - // MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "foo"), - // }, - // PosRange: posrange.PositionRange{ - // Start: 0, - // End: 3, - // }, - // }, - // RHS: &VectorSelector{ - // Name: "bar", - // LabelMatchers: []*labels.Matcher{ - // MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "bar"), - // }, - // PosRange: posrange.PositionRange{ - // Start: 31, - // End: 34, - // }, - // }, - // VectorMatching: &VectorMatching{ - // Card: CardManyToOne, - // MatchingLabels: []string{"test", "blub"}, - // On: true, - // }, - // }, - // }, - // { - // input: "foo and on(test,blub) bar", - // expected: &BinaryExpr{ - // Op: LAND, - // LHS: &VectorSelector{ - // Name: "foo", - // LabelMatchers: []*labels.Matcher{ - // MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "foo"), - // }, - // PosRange: posrange.PositionRange{ - // Start: 0, - // End: 3, - // }, - // }, - // RHS: &VectorSelector{ - // Name: "bar", - // LabelMatchers: []*labels.Matcher{ - // MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "bar"), - // }, - // PosRange: posrange.PositionRange{ - // Start: 22, - // End: 25, - // }, - // }, - // VectorMatching: &VectorMatching{ - // Card: CardManyToMany, - // MatchingLabels: []string{"test", "blub"}, - // On: true, - // }, - // }, - // }, - // { - // input: "foo and on() bar", - // expected: &BinaryExpr{ - // Op: LAND, - // LHS: &VectorSelector{ - // Name: "foo", - // LabelMatchers: []*labels.Matcher{ - // MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "foo"), - // }, - // PosRange: posrange.PositionRange{ - // Start: 0, - // End: 3, - // }, - // }, - // RHS: &VectorSelector{ - // Name: "bar", - // LabelMatchers: []*labels.Matcher{ - // MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "bar"), - // }, - // PosRange: posrange.PositionRange{ - // Start: 13, - // End: 16, - // }, - // }, - // VectorMatching: &VectorMatching{ - // Card: CardManyToMany, - // MatchingLabels: []string{}, - // On: true, - // }, - // }, - // }, - // { - // input: "foo and ignoring(test,blub) bar", - // expected: &BinaryExpr{ - // Op: LAND, - // LHS: &VectorSelector{ - // Name: "foo", - // LabelMatchers: []*labels.Matcher{ - // MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "foo"), - // }, - // PosRange: posrange.PositionRange{ - // Start: 0, - // End: 3, - // }, - // }, - // RHS: &VectorSelector{ - // Name: "bar", - // LabelMatchers: []*labels.Matcher{ - // MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "bar"), - // }, - // PosRange: posrange.PositionRange{ - // Start: 28, - // End: 31, - // }, - // }, - // VectorMatching: &VectorMatching{ - // Card: CardManyToMany, - // MatchingLabels: []string{"test", "blub"}, - // }, - // }, - // }, - // { - // input: "foo and ignoring() bar", - // expected: &BinaryExpr{ - // Op: LAND, - // LHS: &VectorSelector{ - // Name: "foo", - // LabelMatchers: []*labels.Matcher{ - // MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "foo"), - // }, - // PosRange: posrange.PositionRange{ - // Start: 0, - // End: 3, - // }, - // }, - // RHS: &VectorSelector{ - // Name: "bar", - // LabelMatchers: []*labels.Matcher{ - // MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "bar"), - // }, - // PosRange: posrange.PositionRange{ - // Start: 19, - // End: 22, - // }, - // }, - // VectorMatching: &VectorMatching{ - // Card: CardManyToMany, - // MatchingLabels: []string{}, - // }, - // }, - // }, - // { - // input: "foo unless on(bar) baz", - // expected: &BinaryExpr{ - // Op: LUNLESS, - // LHS: &VectorSelector{ - // Name: "foo", - // LabelMatchers: []*labels.Matcher{ - // MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "foo"), - // }, - // PosRange: posrange.PositionRange{ - // Start: 0, - // End: 3, - // }, - // }, - // RHS: &VectorSelector{ - // Name: "baz", - // LabelMatchers: []*labels.Matcher{ - // MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "baz"), - // }, - // PosRange: posrange.PositionRange{ - // Start: 19, - // End: 22, - // }, - // }, - // VectorMatching: &VectorMatching{ - // Card: CardManyToMany, - // MatchingLabels: []string{"bar"}, - // On: true, - // }, - // }, - // }, - // { - // input: "foo / on(test,blub) group_left(bar) bar", - // expected: &BinaryExpr{ - // Op: DIV, - // LHS: &VectorSelector{ - // Name: "foo", - // LabelMatchers: []*labels.Matcher{ - // MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "foo"), - // }, - // PosRange: posrange.PositionRange{ - // Start: 0, - // End: 3, - // }, - // }, - // RHS: &VectorSelector{ - // Name: "bar", - // LabelMatchers: []*labels.Matcher{ - // MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "bar"), - // }, - // PosRange: posrange.PositionRange{ - // Start: 36, - // End: 39, - // }, - // }, - // VectorMatching: &VectorMatching{ - // Card: CardManyToOne, - // MatchingLabels: []string{"test", "blub"}, - // On: true, - // Include: []string{"bar"}, - // }, - // }, - // }, - // { - // input: "foo / ignoring(test,blub) group_left(blub) bar", - // expected: &BinaryExpr{ - // Op: DIV, - // LHS: &VectorSelector{ - // Name: "foo", - // LabelMatchers: []*labels.Matcher{ - // MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "foo"), - // }, - // PosRange: posrange.PositionRange{ - // Start: 0, - // End: 3, - // }, - // }, - // RHS: &VectorSelector{ - // Name: "bar", - // LabelMatchers: []*labels.Matcher{ - // MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "bar"), - // }, - // PosRange: posrange.PositionRange{ - // Start: 43, - // End: 46, - // }, - // }, - // VectorMatching: &VectorMatching{ - // Card: CardManyToOne, - // MatchingLabels: []string{"test", "blub"}, - // Include: []string{"blub"}, - // }, - // }, - // }, - // { - // input: "foo / ignoring(test,blub) group_left(bar) bar", - // expected: &BinaryExpr{ - // Op: DIV, - // LHS: &VectorSelector{ - // Name: "foo", - // LabelMatchers: []*labels.Matcher{ - // MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "foo"), - // }, - // PosRange: posrange.PositionRange{ - // Start: 0, - // End: 3, - // }, - // }, - // RHS: &VectorSelector{ - // Name: "bar", - // LabelMatchers: []*labels.Matcher{ - // MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "bar"), - // }, - // PosRange: posrange.PositionRange{ - // Start: 42, - // End: 45, - // }, - // }, - // VectorMatching: &VectorMatching{ - // Card: CardManyToOne, - // MatchingLabels: []string{"test", "blub"}, - // Include: []string{"bar"}, - // }, - // }, - // }, - // { - // input: "foo - on(test,blub) group_right(bar,foo) bar", - // expected: &BinaryExpr{ - // Op: SUB, - // LHS: &VectorSelector{ - // Name: "foo", - // LabelMatchers: []*labels.Matcher{ - // MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "foo"), - // }, - // PosRange: posrange.PositionRange{ - // Start: 0, - // End: 3, - // }, - // }, - // RHS: &VectorSelector{ - // Name: "bar", - // LabelMatchers: []*labels.Matcher{ - // MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "bar"), - // }, - // PosRange: posrange.PositionRange{ - // Start: 41, - // End: 44, - // }, - // }, - // VectorMatching: &VectorMatching{ - // Card: CardOneToMany, - // MatchingLabels: []string{"test", "blub"}, - // Include: []string{"bar", "foo"}, - // On: true, - // }, - // }, - // }, - // { - // input: "foo - ignoring(test,blub) group_right(bar,foo) bar", - // expected: &BinaryExpr{ - // Op: SUB, - // LHS: &VectorSelector{ - // Name: "foo", - // LabelMatchers: []*labels.Matcher{ - // MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "foo"), - // }, - // PosRange: posrange.PositionRange{ - // Start: 0, - // End: 3, - // }, - // }, - // RHS: &VectorSelector{ - // Name: "bar", - // LabelMatchers: []*labels.Matcher{ - // MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "bar"), - // }, - // PosRange: posrange.PositionRange{ - // Start: 47, - // End: 50, - // }, - // }, - // VectorMatching: &VectorMatching{ - // Card: CardOneToMany, - // MatchingLabels: []string{"test", "blub"}, - // Include: []string{"bar", "foo"}, - // }, - // }, - // }, - // { - // input: "foo and 1", - // fail: true, - // errMsg: "set operator \"and\" not allowed in binary scalar expression", - // }, - // { - // input: "1 and foo", - // fail: true, - // errMsg: "set operator \"and\" not allowed in binary scalar expression", - // }, - // { - // input: "foo or 1", - // fail: true, - // errMsg: "set operator \"or\" not allowed in binary scalar expression", - // }, - // { - // input: "1 or foo", - // fail: true, - // errMsg: "set operator \"or\" not allowed in binary scalar expression", - // }, - // { - // input: "foo unless 1", - // fail: true, - // errMsg: "set operator \"unless\" not allowed in binary scalar expression", - // }, - // { - // input: "1 unless foo", - // fail: true, - // errMsg: "set operator \"unless\" not allowed in binary scalar expression", - // }, - // { - // input: "1 or on(bar) foo", - // fail: true, - // errMsg: "vector matching only allowed between instant vectors", - // }, - // { - // input: "foo == on(bar) 10", - // fail: true, - // errMsg: "vector matching only allowed between instant vectors", - // }, - // { - // input: "foo + group_left(baz) bar", - // fail: true, - // errMsg: "unexpected ", - // }, - // { - // input: "foo and on(bar) group_left(baz) bar", - // fail: true, - // errMsg: "no grouping allowed for \"and\" operation", - // }, - // { - // input: "foo and on(bar) group_right(baz) bar", - // fail: true, - // errMsg: "no grouping allowed for \"and\" operation", - // }, - // { - // input: "foo or on(bar) group_left(baz) bar", - // fail: true, - // errMsg: "no grouping allowed for \"or\" operation", - // }, - // { - // input: "foo or on(bar) group_right(baz) bar", - // fail: true, - // errMsg: "no grouping allowed for \"or\" operation", - // }, - // { - // input: "foo unless on(bar) group_left(baz) bar", - // fail: true, - // errMsg: "no grouping allowed for \"unless\" operation", - // }, - // { - // input: "foo unless on(bar) group_right(baz) bar", - // fail: true, - // errMsg: "no grouping allowed for \"unless\" operation", - // }, - // { - // input: `http_requests{group="production"} + on(instance) group_left(job,instance) cpu_count{type="smp"}`, - // fail: true, - // errMsg: "label \"instance\" must not occur in ON and GROUP clause at once", - // }, - // { - // input: "foo + bool bar", - // fail: true, - // errMsg: "bool modifier can only be used on comparison operators", - // }, - // { - // input: "foo + bool 10", - // fail: true, - // errMsg: "bool modifier can only be used on comparison operators", - // }, - // { - // input: "foo and bool 10", - // fail: true, - // errMsg: "bool modifier can only be used on comparison operators", - // }, - // // Test Vector selector. - // { - // input: "foo", - // expected: &VectorSelector{ - // Name: "foo", - // LabelMatchers: []*labels.Matcher{ - // MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "foo"), - // }, - // PosRange: posrange.PositionRange{ - // Start: 0, - // End: 3, - // }, - // }, - // }, - // { - // input: "min", - // expected: &VectorSelector{ - // Name: "min", - // LabelMatchers: []*labels.Matcher{ - // MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "min"), - // }, - // PosRange: posrange.PositionRange{ - // Start: 0, - // End: 3, - // }, - // }, - // }, - // { - // input: "foo offset 5m", - // expected: &VectorSelector{ - // Name: "foo", - // OriginalOffset: 5 * time.Minute, - // LabelMatchers: []*labels.Matcher{ - // MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "foo"), - // }, - // PosRange: posrange.PositionRange{ - // Start: 0, - // End: 13, - // }, - // }, - // }, - // { - // input: "foo offset -7m", - // expected: &VectorSelector{ - // Name: "foo", - // OriginalOffset: -7 * time.Minute, - // LabelMatchers: []*labels.Matcher{ - // MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "foo"), - // }, - // PosRange: posrange.PositionRange{ - // Start: 0, - // End: 14, - // }, - // }, - // }, - // { - // input: `foo OFFSET 1h30m`, - // expected: &VectorSelector{ - // Name: "foo", - // OriginalOffset: 90 * time.Minute, - // LabelMatchers: []*labels.Matcher{ - // MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "foo"), - // }, - // PosRange: posrange.PositionRange{ - // Start: 0, - // End: 16, - // }, - // }, - // }, - // { - // input: `foo OFFSET 1m30ms`, - // expected: &VectorSelector{ - // Name: "foo", - // OriginalOffset: time.Minute + 30*time.Millisecond, - // LabelMatchers: []*labels.Matcher{ - // MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "foo"), - // }, - // PosRange: posrange.PositionRange{ - // Start: 0, - // End: 17, - // }, - // }, - // }, - // { - // input: `foo @ 1603774568`, - // expected: &VectorSelector{ - // Name: "foo", - // Timestamp: makeInt64Pointer(1603774568000), - // LabelMatchers: []*labels.Matcher{ - // MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "foo"), - // }, - // PosRange: posrange.PositionRange{ - // Start: 0, - // End: 16, - // }, - // }, - // }, - // { - // input: `foo @ -100`, - // expected: &VectorSelector{ - // Name: "foo", - // Timestamp: makeInt64Pointer(-100000), - // LabelMatchers: []*labels.Matcher{ - // MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "foo"), - // }, - // PosRange: posrange.PositionRange{ - // Start: 0, - // End: 10, - // }, - // }, - // }, - // { - // input: `foo @ .3`, - // expected: &VectorSelector{ - // Name: "foo", - // Timestamp: makeInt64Pointer(300), - // LabelMatchers: []*labels.Matcher{ - // MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "foo"), - // }, - // PosRange: posrange.PositionRange{ - // Start: 0, - // End: 8, - // }, - // }, - // }, - // { - // input: `foo @ 3.`, - // expected: &VectorSelector{ - // Name: "foo", - // Timestamp: makeInt64Pointer(3000), - // LabelMatchers: []*labels.Matcher{ - // MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "foo"), - // }, - // PosRange: posrange.PositionRange{ - // Start: 0, - // End: 8, - // }, - // }, - // }, - // { - // input: `foo @ 3.33`, - // expected: &VectorSelector{ - // Name: "foo", - // Timestamp: makeInt64Pointer(3330), - // LabelMatchers: []*labels.Matcher{ - // MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "foo"), - // }, - // PosRange: posrange.PositionRange{ - // Start: 0, - // End: 10, - // }, - // }, - // }, - // { // Rounding off. - // input: `foo @ 3.3333`, - // expected: &VectorSelector{ - // Name: "foo", - // Timestamp: makeInt64Pointer(3333), - // LabelMatchers: []*labels.Matcher{ - // MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "foo"), - // }, - // PosRange: posrange.PositionRange{ - // Start: 0, - // End: 12, - // }, - // }, - // }, - // { // Rounding off. - // input: `foo @ 3.3335`, - // expected: &VectorSelector{ - // Name: "foo", - // Timestamp: makeInt64Pointer(3334), - // LabelMatchers: []*labels.Matcher{ - // MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "foo"), - // }, - // PosRange: posrange.PositionRange{ - // Start: 0, - // End: 12, - // }, - // }, - // }, - // { - // input: `foo @ 3e2`, - // expected: &VectorSelector{ - // Name: "foo", - // Timestamp: makeInt64Pointer(300000), - // LabelMatchers: []*labels.Matcher{ - // MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "foo"), - // }, - // PosRange: posrange.PositionRange{ - // Start: 0, - // End: 9, - // }, - // }, - // }, - // { - // input: `foo @ 3e-1`, - // expected: &VectorSelector{ - // Name: "foo", - // Timestamp: makeInt64Pointer(300), - // LabelMatchers: []*labels.Matcher{ - // MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "foo"), - // }, - // PosRange: posrange.PositionRange{ - // Start: 0, - // End: 10, - // }, - // }, - // }, - // { - // input: `foo @ 0xA`, - // expected: &VectorSelector{ - // Name: "foo", - // Timestamp: makeInt64Pointer(10000), - // LabelMatchers: []*labels.Matcher{ - // MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "foo"), - // }, - // PosRange: posrange.PositionRange{ - // Start: 0, - // End: 9, - // }, - // }, - // }, - // { - // input: `foo @ -3.3e1`, - // expected: &VectorSelector{ - // Name: "foo", - // Timestamp: makeInt64Pointer(-33000), - // LabelMatchers: []*labels.Matcher{ - // MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "foo"), - // }, - // PosRange: posrange.PositionRange{ - // Start: 0, - // End: 12, - // }, - // }, - // }, - // { - // input: `foo @ +Inf`, - // fail: true, - // errMsg: "1:1: parse error: timestamp out of bounds for @ modifier: +Inf", - // }, - // { - // input: `foo @ -Inf`, - // fail: true, - // errMsg: "1:1: parse error: timestamp out of bounds for @ modifier: -Inf", - // }, - // { - // input: `foo @ NaN`, - // fail: true, - // errMsg: "1:1: parse error: timestamp out of bounds for @ modifier: NaN", - // }, - // { - // input: fmt.Sprintf(`foo @ %f`, float64(math.MaxInt64)+1), - // fail: true, - // errMsg: fmt.Sprintf("1:1: parse error: timestamp out of bounds for @ modifier: %f", float64(math.MaxInt64)+1), - // }, - // { - // input: fmt.Sprintf(`foo @ %f`, float64(math.MinInt64)-1), - // fail: true, - // errMsg: fmt.Sprintf("1:1: parse error: timestamp out of bounds for @ modifier: %f", float64(math.MinInt64)-1), - // }, - // { - // input: `foo:bar{a="bc"}`, - // expected: &VectorSelector{ - // Name: "foo:bar", - // LabelMatchers: []*labels.Matcher{ - // MustLabelMatcher(labels.MatchEqual, "a", "bc"), - // MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "foo:bar"), - // }, - // PosRange: posrange.PositionRange{ - // Start: 0, - // End: 15, - // }, - // }, - // }, + { + input: "1", + expected: &NumberLiteral{ + Val: 1, + PosRange: posrange.PositionRange{Start: 0, End: 1}, + }, + }, + { + input: "+Inf", + expected: &NumberLiteral{ + Val: math.Inf(1), + PosRange: posrange.PositionRange{Start: 0, End: 4}, + }, + }, + { + input: "-Inf", + expected: &NumberLiteral{ + Val: math.Inf(-1), + PosRange: posrange.PositionRange{Start: 0, End: 4}, + }, + }, + { + input: ".5", + expected: &NumberLiteral{ + Val: 0.5, + PosRange: posrange.PositionRange{Start: 0, End: 2}, + }, + }, + { + input: "5.", + expected: &NumberLiteral{ + Val: 5, + PosRange: posrange.PositionRange{Start: 0, End: 2}, + }, + }, + { + input: "123.4567", + expected: &NumberLiteral{ + Val: 123.4567, + PosRange: posrange.PositionRange{Start: 0, End: 8}, + }, + }, + { + input: "5e-3", + expected: &NumberLiteral{ + Val: 0.005, + PosRange: posrange.PositionRange{Start: 0, End: 4}, + }, + }, + { + input: "5e3", + expected: &NumberLiteral{ + Val: 5000, + PosRange: posrange.PositionRange{Start: 0, End: 3}, + }, + }, + { + input: "0xc", + expected: &NumberLiteral{ + Val: 12, + PosRange: posrange.PositionRange{Start: 0, End: 3}, + }, + }, + { + input: "0755", + expected: &NumberLiteral{ + Val: 493, + PosRange: posrange.PositionRange{Start: 0, End: 4}, + }, + }, + { + input: "+5.5e-3", + expected: &NumberLiteral{ + Val: 0.0055, + PosRange: posrange.PositionRange{Start: 0, End: 7}, + }, + }, + { + input: "-0755", + expected: &NumberLiteral{ + Val: -493, + PosRange: posrange.PositionRange{Start: 0, End: 5}, + }, + }, + { + input: "1 + 1", + expected: &BinaryExpr{ + Op: ADD, + LHS: &NumberLiteral{ + Val: 1, + PosRange: posrange.PositionRange{Start: 0, End: 1}, + }, + RHS: &NumberLiteral{ + Val: 1, + PosRange: posrange.PositionRange{Start: 4, End: 5}, + }, + }, + }, + { + input: "1 - 1", + expected: &BinaryExpr{ + Op: SUB, + LHS: &NumberLiteral{ + Val: 1, + PosRange: posrange.PositionRange{Start: 0, End: 1}, + }, + RHS: &NumberLiteral{ + Val: 1, + PosRange: posrange.PositionRange{Start: 4, End: 5}, + }, + }, + }, + { + input: "1 * 1", + expected: &BinaryExpr{ + Op: MUL, + LHS: &NumberLiteral{ + Val: 1, + PosRange: posrange.PositionRange{Start: 0, End: 1}, + }, + RHS: &NumberLiteral{ + Val: 1, + PosRange: posrange.PositionRange{Start: 4, End: 5}, + }, + }, + }, + { + input: "1 % 1", + expected: &BinaryExpr{ + Op: MOD, + LHS: &NumberLiteral{ + Val: 1, + PosRange: posrange.PositionRange{Start: 0, End: 1}, + }, + RHS: &NumberLiteral{ + Val: 1, + PosRange: posrange.PositionRange{Start: 4, End: 5}, + }, + }, + }, + { + input: "1 / 1", + expected: &BinaryExpr{ + Op: DIV, + LHS: &NumberLiteral{ + Val: 1, + PosRange: posrange.PositionRange{Start: 0, End: 1}, + }, + RHS: &NumberLiteral{ + Val: 1, + PosRange: posrange.PositionRange{Start: 4, End: 5}, + }, + }, + }, + { + input: "1 == bool 1", + expected: &BinaryExpr{ + Op: EQLC, + LHS: &NumberLiteral{ + Val: 1, + PosRange: posrange.PositionRange{Start: 0, End: 1}, + }, + RHS: &NumberLiteral{ + Val: 1, + PosRange: posrange.PositionRange{Start: 10, End: 11}, + }, + ReturnBool: true, + }, + }, + { + input: "1 != bool 1", + expected: &BinaryExpr{ + Op: NEQ, + LHS: &NumberLiteral{ + Val: 1, + PosRange: posrange.PositionRange{Start: 0, End: 1}, + }, + RHS: &NumberLiteral{ + Val: 1, + PosRange: posrange.PositionRange{Start: 10, End: 11}, + }, + ReturnBool: true, + }, + }, + { + input: "1 > bool 1", + expected: &BinaryExpr{ + Op: GTR, + LHS: &NumberLiteral{ + Val: 1, + PosRange: posrange.PositionRange{Start: 0, End: 1}, + }, + RHS: &NumberLiteral{ + Val: 1, + PosRange: posrange.PositionRange{Start: 9, End: 10}, + }, + ReturnBool: true, + }, + }, + { + input: "1 >= bool 1", + expected: &BinaryExpr{ + Op: GTE, + LHS: &NumberLiteral{ + Val: 1, + PosRange: posrange.PositionRange{Start: 0, End: 1}, + }, + RHS: &NumberLiteral{ + Val: 1, + PosRange: posrange.PositionRange{Start: 10, End: 11}, + }, + ReturnBool: true, + }, + }, + { + input: "1 < bool 1", + expected: &BinaryExpr{ + Op: LSS, + LHS: &NumberLiteral{ + Val: 1, + PosRange: posrange.PositionRange{Start: 0, End: 1}, + }, + RHS: &NumberLiteral{ + Val: 1, + PosRange: posrange.PositionRange{Start: 9, End: 10}, + }, + ReturnBool: true, + }, + }, + { + input: "1 <= bool 1", + expected: &BinaryExpr{ + Op: LTE, + LHS: &NumberLiteral{ + Val: 1, + PosRange: posrange.PositionRange{Start: 0, End: 1}, + }, + RHS: &NumberLiteral{ + Val: 1, + PosRange: posrange.PositionRange{Start: 10, End: 11}, + }, + ReturnBool: true, + }, + }, + { + input: "-1^2", + expected: &UnaryExpr{ + Op: SUB, + Expr: &BinaryExpr{ + Op: POW, + LHS: &NumberLiteral{ + Val: 1, + PosRange: posrange.PositionRange{Start: 1, End: 2}, + }, + RHS: &NumberLiteral{ + Val: 2, + PosRange: posrange.PositionRange{Start: 3, End: 4}, + }, + }, + }, + }, + { + input: "-1*2", + expected: &BinaryExpr{ + Op: MUL, + LHS: &NumberLiteral{ + Val: -1, + PosRange: posrange.PositionRange{Start: 0, End: 2}, + }, + RHS: &NumberLiteral{ + Val: 2, + PosRange: posrange.PositionRange{Start: 3, End: 4}, + }, + }, + }, + { + input: "-1+2", + expected: &BinaryExpr{ + Op: ADD, + LHS: &NumberLiteral{ + Val: -1, + PosRange: posrange.PositionRange{Start: 0, End: 2}, + }, + RHS: &NumberLiteral{ + Val: 2, + PosRange: posrange.PositionRange{Start: 3, End: 4}, + }, + }, + }, + { + input: "-1^-2", + expected: &UnaryExpr{ + Op: SUB, + Expr: &BinaryExpr{ + Op: POW, + LHS: &NumberLiteral{ + Val: 1, + PosRange: posrange.PositionRange{Start: 1, End: 2}, + }, + RHS: &NumberLiteral{ + Val: -2, + PosRange: posrange.PositionRange{Start: 3, End: 5}, + }, + }, + }, + }, + { + input: "+1 + -2 * 1", + expected: &BinaryExpr{ + Op: ADD, + LHS: &NumberLiteral{ + Val: 1, + PosRange: posrange.PositionRange{Start: 0, End: 2}, + }, + RHS: &BinaryExpr{ + Op: MUL, + LHS: &NumberLiteral{ + Val: -2, + PosRange: posrange.PositionRange{Start: 5, End: 7}, + }, + RHS: &NumberLiteral{ + Val: 1, + PosRange: posrange.PositionRange{Start: 10, End: 11}, + }, + }, + }, + }, + { + input: "1 + 2/(3*1)", + expected: &BinaryExpr{ + Op: ADD, + LHS: &NumberLiteral{ + Val: 1, + PosRange: posrange.PositionRange{Start: 0, End: 1}, + }, + RHS: &BinaryExpr{ + Op: DIV, + LHS: &NumberLiteral{ + Val: 2, + PosRange: posrange.PositionRange{Start: 4, End: 5}, + }, + RHS: &ParenExpr{ + Expr: &BinaryExpr{ + Op: MUL, + LHS: &NumberLiteral{ + Val: 3, + PosRange: posrange.PositionRange{Start: 7, End: 8}, + }, + RHS: &NumberLiteral{ + Val: 1, + PosRange: posrange.PositionRange{Start: 9, End: 10}, + }, + }, + PosRange: posrange.PositionRange{Start: 6, End: 11}, + }, + }, + }, + }, + { + input: "1 < bool 2 - 1 * 2", + expected: &BinaryExpr{ + Op: LSS, + ReturnBool: true, + LHS: &NumberLiteral{ + Val: 1, + PosRange: posrange.PositionRange{Start: 0, End: 1}, + }, + RHS: &BinaryExpr{ + Op: SUB, + LHS: &NumberLiteral{ + Val: 2, + PosRange: posrange.PositionRange{Start: 9, End: 10}, + }, + RHS: &BinaryExpr{ + Op: MUL, + LHS: &NumberLiteral{ + Val: 1, + PosRange: posrange.PositionRange{Start: 13, End: 14}, + }, + RHS: &NumberLiteral{ + Val: 2, + PosRange: posrange.PositionRange{Start: 17, End: 18}, + }, + }, + }, + }, + }, + { + input: "-some_metric", + expected: &UnaryExpr{ + Op: SUB, + Expr: &VectorSelector{ + Name: "some_metric", + LabelMatchers: []*labels.Matcher{ + MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "some_metric"), + }, + PosRange: posrange.PositionRange{ + Start: 1, + End: 12, + }, + }, + }, + }, + { + input: "+some_metric", + expected: &UnaryExpr{ + Op: ADD, + Expr: &VectorSelector{ + Name: "some_metric", + LabelMatchers: []*labels.Matcher{ + MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "some_metric"), + }, + PosRange: posrange.PositionRange{ + Start: 1, + End: 12, + }, + }, + }, + }, + { + input: " +some_metric", + expected: &UnaryExpr{ + Op: ADD, + Expr: &VectorSelector{ + Name: "some_metric", + LabelMatchers: []*labels.Matcher{ + MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "some_metric"), + }, + PosRange: posrange.PositionRange{ + Start: 2, + End: 13, + }, + }, + StartPos: 1, + }, + }, + { + input: ` +{"some_metric"}`, + expected: &UnaryExpr{ + Op: ADD, + Expr: &VectorSelector{ + LabelMatchers: []*labels.Matcher{ + MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "some_metric"), + }, + PosRange: posrange.PositionRange{ + Start: 2, + End: 17, + }, + }, + StartPos: 1, + }, + }, + { + input: "", + fail: true, + errMsg: "no expression found in input", + }, + { + input: "# just a comment\n\n", + fail: true, + errMsg: "no expression found in input", + }, + { + input: "1+", + fail: true, + errMsg: "unexpected end of input", + }, + { + input: ".", + fail: true, + errMsg: "unexpected character: '.'", + }, + { + input: "2.5.", + fail: true, + errMsg: "unexpected character: '.'", + }, + { + input: "100..4", + fail: true, + errMsg: `unexpected number ".4"`, + }, + { + input: "0deadbeef", + fail: true, + errMsg: "bad number or duration syntax: \"0de\"", + }, + { + input: "1 /", + fail: true, + errMsg: "unexpected end of input", + }, + { + input: "*1", + fail: true, + errMsg: "unexpected ", + }, + { + input: "(1))", + fail: true, + errMsg: "unexpected right parenthesis ')'", + }, + { + input: "((1)", + fail: true, + errMsg: "unclosed left parenthesis", + }, + { + input: "999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999", + fail: true, + errMsg: "out of range", + }, + { + input: "(", + fail: true, + errMsg: "unclosed left parenthesis", + }, + { + input: "1 and 1", + fail: true, + errMsg: "set operator \"and\" not allowed in binary scalar expression", + }, + { + input: "1 == 1", + fail: true, + errMsg: "1:3: parse error: comparisons between scalars must use BOOL modifier", + }, + { + input: "1 or 1", + fail: true, + errMsg: "set operator \"or\" not allowed in binary scalar expression", + }, + { + input: "1 unless 1", + fail: true, + errMsg: "set operator \"unless\" not allowed in binary scalar expression", + }, + { + input: "1 !~ 1", + fail: true, + errMsg: `unexpected character after '!': '~'`, + }, + { + input: "1 =~ 1", + fail: true, + errMsg: `unexpected character after '=': '~'`, + }, + { + input: `-"string"`, + fail: true, + errMsg: `unary expression only allowed on expressions of type scalar or instant vector, got "string"`, + }, + { + input: `-test[5m]`, + fail: true, + errMsg: `unary expression only allowed on expressions of type scalar or instant vector, got "range vector"`, + }, + { + input: `*test`, + fail: true, + errMsg: "unexpected ", + }, + { + input: "1 offset 1d", + fail: true, + errMsg: "1:1: parse error: offset modifier must be preceded by an instant vector selector or range vector selector or a subquery", + }, + { + input: "foo offset 1s offset 2s", + fail: true, + errMsg: "offset may not be set multiple times", + }, + { + input: "a - on(b) ignoring(c) d", + fail: true, + errMsg: "1:11: parse error: unexpected ", + }, + // Vector binary operations. + { + input: "foo * bar", + expected: &BinaryExpr{ + Op: MUL, + LHS: &VectorSelector{ + Name: "foo", + LabelMatchers: []*labels.Matcher{ + MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "foo"), + }, + PosRange: posrange.PositionRange{ + Start: 0, + End: 3, + }, + }, + RHS: &VectorSelector{ + Name: "bar", + LabelMatchers: []*labels.Matcher{ + MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "bar"), + }, + PosRange: posrange.PositionRange{ + Start: 6, + End: 9, + }, + }, + VectorMatching: &VectorMatching{Card: CardOneToOne}, + }, + }, + { + input: "foo * sum", + expected: &BinaryExpr{ + Op: MUL, + LHS: &VectorSelector{ + Name: "foo", + LabelMatchers: []*labels.Matcher{ + MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "foo"), + }, + PosRange: posrange.PositionRange{ + Start: 0, + End: 3, + }, + }, + RHS: &VectorSelector{ + Name: "sum", + LabelMatchers: []*labels.Matcher{ + MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "sum"), + }, + PosRange: posrange.PositionRange{ + Start: 6, + End: 9, + }, + }, + VectorMatching: &VectorMatching{Card: CardOneToOne}, + }, + }, + { + input: "foo == 1", + expected: &BinaryExpr{ + Op: EQLC, + LHS: &VectorSelector{ + Name: "foo", + LabelMatchers: []*labels.Matcher{ + MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "foo"), + }, + PosRange: posrange.PositionRange{ + Start: 0, + End: 3, + }, + }, + RHS: &NumberLiteral{ + Val: 1, + PosRange: posrange.PositionRange{Start: 7, End: 8}, + }, + }, + }, + { + input: "foo == bool 1", + expected: &BinaryExpr{ + Op: EQLC, + LHS: &VectorSelector{ + Name: "foo", + LabelMatchers: []*labels.Matcher{ + MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "foo"), + }, + PosRange: posrange.PositionRange{ + Start: 0, + End: 3, + }, + }, + RHS: &NumberLiteral{ + Val: 1, + PosRange: posrange.PositionRange{Start: 12, End: 13}, + }, + ReturnBool: true, + }, + }, + { + input: "2.5 / bar", + expected: &BinaryExpr{ + Op: DIV, + LHS: &NumberLiteral{ + Val: 2.5, + PosRange: posrange.PositionRange{Start: 0, End: 3}, + }, + RHS: &VectorSelector{ + Name: "bar", + LabelMatchers: []*labels.Matcher{ + MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "bar"), + }, + PosRange: posrange.PositionRange{ + Start: 6, + End: 9, + }, + }, + }, + }, + { + input: "foo and bar", + expected: &BinaryExpr{ + Op: LAND, + LHS: &VectorSelector{ + Name: "foo", + LabelMatchers: []*labels.Matcher{ + MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "foo"), + }, + PosRange: posrange.PositionRange{ + Start: 0, + End: 3, + }, + }, + RHS: &VectorSelector{ + Name: "bar", + LabelMatchers: []*labels.Matcher{ + MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "bar"), + }, + PosRange: posrange.PositionRange{ + Start: 8, + End: 11, + }, + }, + VectorMatching: &VectorMatching{Card: CardManyToMany}, + }, + }, + { + input: "foo or bar", + expected: &BinaryExpr{ + Op: LOR, + LHS: &VectorSelector{ + Name: "foo", + LabelMatchers: []*labels.Matcher{ + MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "foo"), + }, + PosRange: posrange.PositionRange{ + Start: 0, + End: 3, + }, + }, + RHS: &VectorSelector{ + Name: "bar", + LabelMatchers: []*labels.Matcher{ + MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "bar"), + }, + PosRange: posrange.PositionRange{ + Start: 7, + End: 10, + }, + }, + VectorMatching: &VectorMatching{Card: CardManyToMany}, + }, + }, + { + input: "foo unless bar", + expected: &BinaryExpr{ + Op: LUNLESS, + LHS: &VectorSelector{ + Name: "foo", + LabelMatchers: []*labels.Matcher{ + MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "foo"), + }, + PosRange: posrange.PositionRange{ + Start: 0, + End: 3, + }, + }, + RHS: &VectorSelector{ + Name: "bar", + LabelMatchers: []*labels.Matcher{ + MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "bar"), + }, + PosRange: posrange.PositionRange{ + Start: 11, + End: 14, + }, + }, + VectorMatching: &VectorMatching{Card: CardManyToMany}, + }, + }, + { + // Test and/or precedence and reassigning of operands. + input: "foo + bar or bla and blub", + expected: &BinaryExpr{ + Op: LOR, + LHS: &BinaryExpr{ + Op: ADD, + LHS: &VectorSelector{ + Name: "foo", + LabelMatchers: []*labels.Matcher{ + MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "foo"), + }, + PosRange: posrange.PositionRange{ + Start: 0, + End: 3, + }, + }, + RHS: &VectorSelector{ + Name: "bar", + LabelMatchers: []*labels.Matcher{ + MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "bar"), + }, + PosRange: posrange.PositionRange{ + Start: 6, + End: 9, + }, + }, + VectorMatching: &VectorMatching{Card: CardOneToOne}, + }, + RHS: &BinaryExpr{ + Op: LAND, + LHS: &VectorSelector{ + Name: "bla", + LabelMatchers: []*labels.Matcher{ + MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "bla"), + }, + PosRange: posrange.PositionRange{ + Start: 13, + End: 16, + }, + }, + RHS: &VectorSelector{ + Name: "blub", + LabelMatchers: []*labels.Matcher{ + MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "blub"), + }, + PosRange: posrange.PositionRange{ + Start: 21, + End: 25, + }, + }, + VectorMatching: &VectorMatching{Card: CardManyToMany}, + }, + VectorMatching: &VectorMatching{Card: CardManyToMany}, + }, + }, + { + // Test and/or/unless precedence. + input: "foo and bar unless baz or qux", + expected: &BinaryExpr{ + Op: LOR, + LHS: &BinaryExpr{ + Op: LUNLESS, + LHS: &BinaryExpr{ + Op: LAND, + LHS: &VectorSelector{ + Name: "foo", + LabelMatchers: []*labels.Matcher{ + MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "foo"), + }, + PosRange: posrange.PositionRange{ + Start: 0, + End: 3, + }, + }, + RHS: &VectorSelector{ + Name: "bar", + LabelMatchers: []*labels.Matcher{ + MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "bar"), + }, + PosRange: posrange.PositionRange{ + Start: 8, + End: 11, + }, + }, + VectorMatching: &VectorMatching{Card: CardManyToMany}, + }, + RHS: &VectorSelector{ + Name: "baz", + LabelMatchers: []*labels.Matcher{ + MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "baz"), + }, + PosRange: posrange.PositionRange{ + Start: 19, + End: 22, + }, + }, + VectorMatching: &VectorMatching{Card: CardManyToMany}, + }, + RHS: &VectorSelector{ + Name: "qux", + LabelMatchers: []*labels.Matcher{ + MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "qux"), + }, + PosRange: posrange.PositionRange{ + Start: 26, + End: 29, + }, + }, + VectorMatching: &VectorMatching{Card: CardManyToMany}, + }, + }, + { + // Test precedence and reassigning of operands. + input: "bar + on(foo) bla / on(baz, buz) group_right(test) blub", + expected: &BinaryExpr{ + Op: ADD, + LHS: &VectorSelector{ + Name: "bar", + LabelMatchers: []*labels.Matcher{ + MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "bar"), + }, + PosRange: posrange.PositionRange{ + Start: 0, + End: 3, + }, + }, + RHS: &BinaryExpr{ + Op: DIV, + LHS: &VectorSelector{ + Name: "bla", + LabelMatchers: []*labels.Matcher{ + MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "bla"), + }, + PosRange: posrange.PositionRange{ + Start: 14, + End: 17, + }, + }, + RHS: &VectorSelector{ + Name: "blub", + LabelMatchers: []*labels.Matcher{ + MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "blub"), + }, + PosRange: posrange.PositionRange{ + Start: 51, + End: 55, + }, + }, + VectorMatching: &VectorMatching{ + Card: CardOneToMany, + MatchingLabels: []string{"baz", "buz"}, + On: true, + Include: []string{"test"}, + }, + }, + VectorMatching: &VectorMatching{ + Card: CardOneToOne, + MatchingLabels: []string{"foo"}, + On: true, + }, + }, + }, + { + input: "foo * on(test,blub) bar", + expected: &BinaryExpr{ + Op: MUL, + LHS: &VectorSelector{ + Name: "foo", + LabelMatchers: []*labels.Matcher{ + MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "foo"), + }, + PosRange: posrange.PositionRange{ + Start: 0, + End: 3, + }, + }, + RHS: &VectorSelector{ + Name: "bar", + LabelMatchers: []*labels.Matcher{ + MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "bar"), + }, + PosRange: posrange.PositionRange{ + Start: 20, + End: 23, + }, + }, + VectorMatching: &VectorMatching{ + Card: CardOneToOne, + MatchingLabels: []string{"test", "blub"}, + On: true, + }, + }, + }, + { + input: "foo * on(test,blub) group_left bar", + expected: &BinaryExpr{ + Op: MUL, + LHS: &VectorSelector{ + Name: "foo", + LabelMatchers: []*labels.Matcher{ + MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "foo"), + }, + PosRange: posrange.PositionRange{ + Start: 0, + End: 3, + }, + }, + RHS: &VectorSelector{ + Name: "bar", + LabelMatchers: []*labels.Matcher{ + MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "bar"), + }, + PosRange: posrange.PositionRange{ + Start: 31, + End: 34, + }, + }, + VectorMatching: &VectorMatching{ + Card: CardManyToOne, + MatchingLabels: []string{"test", "blub"}, + On: true, + }, + }, + }, + { + input: "foo and on(test,blub) bar", + expected: &BinaryExpr{ + Op: LAND, + LHS: &VectorSelector{ + Name: "foo", + LabelMatchers: []*labels.Matcher{ + MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "foo"), + }, + PosRange: posrange.PositionRange{ + Start: 0, + End: 3, + }, + }, + RHS: &VectorSelector{ + Name: "bar", + LabelMatchers: []*labels.Matcher{ + MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "bar"), + }, + PosRange: posrange.PositionRange{ + Start: 22, + End: 25, + }, + }, + VectorMatching: &VectorMatching{ + Card: CardManyToMany, + MatchingLabels: []string{"test", "blub"}, + On: true, + }, + }, + }, + { + input: "foo and on() bar", + expected: &BinaryExpr{ + Op: LAND, + LHS: &VectorSelector{ + Name: "foo", + LabelMatchers: []*labels.Matcher{ + MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "foo"), + }, + PosRange: posrange.PositionRange{ + Start: 0, + End: 3, + }, + }, + RHS: &VectorSelector{ + Name: "bar", + LabelMatchers: []*labels.Matcher{ + MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "bar"), + }, + PosRange: posrange.PositionRange{ + Start: 13, + End: 16, + }, + }, + VectorMatching: &VectorMatching{ + Card: CardManyToMany, + MatchingLabels: []string{}, + On: true, + }, + }, + }, + { + input: "foo and ignoring(test,blub) bar", + expected: &BinaryExpr{ + Op: LAND, + LHS: &VectorSelector{ + Name: "foo", + LabelMatchers: []*labels.Matcher{ + MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "foo"), + }, + PosRange: posrange.PositionRange{ + Start: 0, + End: 3, + }, + }, + RHS: &VectorSelector{ + Name: "bar", + LabelMatchers: []*labels.Matcher{ + MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "bar"), + }, + PosRange: posrange.PositionRange{ + Start: 28, + End: 31, + }, + }, + VectorMatching: &VectorMatching{ + Card: CardManyToMany, + MatchingLabels: []string{"test", "blub"}, + }, + }, + }, + { + input: "foo and ignoring() bar", + expected: &BinaryExpr{ + Op: LAND, + LHS: &VectorSelector{ + Name: "foo", + LabelMatchers: []*labels.Matcher{ + MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "foo"), + }, + PosRange: posrange.PositionRange{ + Start: 0, + End: 3, + }, + }, + RHS: &VectorSelector{ + Name: "bar", + LabelMatchers: []*labels.Matcher{ + MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "bar"), + }, + PosRange: posrange.PositionRange{ + Start: 19, + End: 22, + }, + }, + VectorMatching: &VectorMatching{ + Card: CardManyToMany, + MatchingLabels: []string{}, + }, + }, + }, + { + input: "foo unless on(bar) baz", + expected: &BinaryExpr{ + Op: LUNLESS, + LHS: &VectorSelector{ + Name: "foo", + LabelMatchers: []*labels.Matcher{ + MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "foo"), + }, + PosRange: posrange.PositionRange{ + Start: 0, + End: 3, + }, + }, + RHS: &VectorSelector{ + Name: "baz", + LabelMatchers: []*labels.Matcher{ + MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "baz"), + }, + PosRange: posrange.PositionRange{ + Start: 19, + End: 22, + }, + }, + VectorMatching: &VectorMatching{ + Card: CardManyToMany, + MatchingLabels: []string{"bar"}, + On: true, + }, + }, + }, + { + input: "foo / on(test,blub) group_left(bar) bar", + expected: &BinaryExpr{ + Op: DIV, + LHS: &VectorSelector{ + Name: "foo", + LabelMatchers: []*labels.Matcher{ + MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "foo"), + }, + PosRange: posrange.PositionRange{ + Start: 0, + End: 3, + }, + }, + RHS: &VectorSelector{ + Name: "bar", + LabelMatchers: []*labels.Matcher{ + MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "bar"), + }, + PosRange: posrange.PositionRange{ + Start: 36, + End: 39, + }, + }, + VectorMatching: &VectorMatching{ + Card: CardManyToOne, + MatchingLabels: []string{"test", "blub"}, + On: true, + Include: []string{"bar"}, + }, + }, + }, + { + input: "foo / ignoring(test,blub) group_left(blub) bar", + expected: &BinaryExpr{ + Op: DIV, + LHS: &VectorSelector{ + Name: "foo", + LabelMatchers: []*labels.Matcher{ + MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "foo"), + }, + PosRange: posrange.PositionRange{ + Start: 0, + End: 3, + }, + }, + RHS: &VectorSelector{ + Name: "bar", + LabelMatchers: []*labels.Matcher{ + MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "bar"), + }, + PosRange: posrange.PositionRange{ + Start: 43, + End: 46, + }, + }, + VectorMatching: &VectorMatching{ + Card: CardManyToOne, + MatchingLabels: []string{"test", "blub"}, + Include: []string{"blub"}, + }, + }, + }, + { + input: "foo / ignoring(test,blub) group_left(bar) bar", + expected: &BinaryExpr{ + Op: DIV, + LHS: &VectorSelector{ + Name: "foo", + LabelMatchers: []*labels.Matcher{ + MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "foo"), + }, + PosRange: posrange.PositionRange{ + Start: 0, + End: 3, + }, + }, + RHS: &VectorSelector{ + Name: "bar", + LabelMatchers: []*labels.Matcher{ + MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "bar"), + }, + PosRange: posrange.PositionRange{ + Start: 42, + End: 45, + }, + }, + VectorMatching: &VectorMatching{ + Card: CardManyToOne, + MatchingLabels: []string{"test", "blub"}, + Include: []string{"bar"}, + }, + }, + }, + { + input: "foo - on(test,blub) group_right(bar,foo) bar", + expected: &BinaryExpr{ + Op: SUB, + LHS: &VectorSelector{ + Name: "foo", + LabelMatchers: []*labels.Matcher{ + MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "foo"), + }, + PosRange: posrange.PositionRange{ + Start: 0, + End: 3, + }, + }, + RHS: &VectorSelector{ + Name: "bar", + LabelMatchers: []*labels.Matcher{ + MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "bar"), + }, + PosRange: posrange.PositionRange{ + Start: 41, + End: 44, + }, + }, + VectorMatching: &VectorMatching{ + Card: CardOneToMany, + MatchingLabels: []string{"test", "blub"}, + Include: []string{"bar", "foo"}, + On: true, + }, + }, + }, + { + input: "foo - ignoring(test,blub) group_right(bar,foo) bar", + expected: &BinaryExpr{ + Op: SUB, + LHS: &VectorSelector{ + Name: "foo", + LabelMatchers: []*labels.Matcher{ + MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "foo"), + }, + PosRange: posrange.PositionRange{ + Start: 0, + End: 3, + }, + }, + RHS: &VectorSelector{ + Name: "bar", + LabelMatchers: []*labels.Matcher{ + MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "bar"), + }, + PosRange: posrange.PositionRange{ + Start: 47, + End: 50, + }, + }, + VectorMatching: &VectorMatching{ + Card: CardOneToMany, + MatchingLabels: []string{"test", "blub"}, + Include: []string{"bar", "foo"}, + }, + }, + }, + { + input: "foo and 1", + fail: true, + errMsg: "set operator \"and\" not allowed in binary scalar expression", + }, + { + input: "1 and foo", + fail: true, + errMsg: "set operator \"and\" not allowed in binary scalar expression", + }, + { + input: "foo or 1", + fail: true, + errMsg: "set operator \"or\" not allowed in binary scalar expression", + }, + { + input: "1 or foo", + fail: true, + errMsg: "set operator \"or\" not allowed in binary scalar expression", + }, + { + input: "foo unless 1", + fail: true, + errMsg: "set operator \"unless\" not allowed in binary scalar expression", + }, + { + input: "1 unless foo", + fail: true, + errMsg: "set operator \"unless\" not allowed in binary scalar expression", + }, + { + input: "1 or on(bar) foo", + fail: true, + errMsg: "vector matching only allowed between instant vectors", + }, + { + input: "foo == on(bar) 10", + fail: true, + errMsg: "vector matching only allowed between instant vectors", + }, + { + input: "foo + group_left(baz) bar", + fail: true, + errMsg: "unexpected ", + }, + { + input: "foo and on(bar) group_left(baz) bar", + fail: true, + errMsg: "no grouping allowed for \"and\" operation", + }, + { + input: "foo and on(bar) group_right(baz) bar", + fail: true, + errMsg: "no grouping allowed for \"and\" operation", + }, + { + input: "foo or on(bar) group_left(baz) bar", + fail: true, + errMsg: "no grouping allowed for \"or\" operation", + }, + { + input: "foo or on(bar) group_right(baz) bar", + fail: true, + errMsg: "no grouping allowed for \"or\" operation", + }, + { + input: "foo unless on(bar) group_left(baz) bar", + fail: true, + errMsg: "no grouping allowed for \"unless\" operation", + }, + { + input: "foo unless on(bar) group_right(baz) bar", + fail: true, + errMsg: "no grouping allowed for \"unless\" operation", + }, + { + input: `http_requests{group="production"} + on(instance) group_left(job,instance) cpu_count{type="smp"}`, + fail: true, + errMsg: "label \"instance\" must not occur in ON and GROUP clause at once", + }, + { + input: "foo + bool bar", + fail: true, + errMsg: "bool modifier can only be used on comparison operators", + }, + { + input: "foo + bool 10", + fail: true, + errMsg: "bool modifier can only be used on comparison operators", + }, + { + input: "foo and bool 10", + fail: true, + errMsg: "bool modifier can only be used on comparison operators", + }, + // Test Vector selector. + { + input: "foo", + expected: &VectorSelector{ + Name: "foo", + LabelMatchers: []*labels.Matcher{ + MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "foo"), + }, + PosRange: posrange.PositionRange{ + Start: 0, + End: 3, + }, + }, + }, + { + input: "min", + expected: &VectorSelector{ + Name: "min", + LabelMatchers: []*labels.Matcher{ + MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "min"), + }, + PosRange: posrange.PositionRange{ + Start: 0, + End: 3, + }, + }, + }, + { + input: "foo offset 5m", + expected: &VectorSelector{ + Name: "foo", + OriginalOffset: 5 * time.Minute, + LabelMatchers: []*labels.Matcher{ + MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "foo"), + }, + PosRange: posrange.PositionRange{ + Start: 0, + End: 13, + }, + }, + }, + { + input: "foo offset -7m", + expected: &VectorSelector{ + Name: "foo", + OriginalOffset: -7 * time.Minute, + LabelMatchers: []*labels.Matcher{ + MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "foo"), + }, + PosRange: posrange.PositionRange{ + Start: 0, + End: 14, + }, + }, + }, + { + input: `foo OFFSET 1h30m`, + expected: &VectorSelector{ + Name: "foo", + OriginalOffset: 90 * time.Minute, + LabelMatchers: []*labels.Matcher{ + MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "foo"), + }, + PosRange: posrange.PositionRange{ + Start: 0, + End: 16, + }, + }, + }, + { + input: `foo OFFSET 1m30ms`, + expected: &VectorSelector{ + Name: "foo", + OriginalOffset: time.Minute + 30*time.Millisecond, + LabelMatchers: []*labels.Matcher{ + MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "foo"), + }, + PosRange: posrange.PositionRange{ + Start: 0, + End: 17, + }, + }, + }, + { + input: `foo @ 1603774568`, + expected: &VectorSelector{ + Name: "foo", + Timestamp: makeInt64Pointer(1603774568000), + LabelMatchers: []*labels.Matcher{ + MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "foo"), + }, + PosRange: posrange.PositionRange{ + Start: 0, + End: 16, + }, + }, + }, + { + input: `foo @ -100`, + expected: &VectorSelector{ + Name: "foo", + Timestamp: makeInt64Pointer(-100000), + LabelMatchers: []*labels.Matcher{ + MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "foo"), + }, + PosRange: posrange.PositionRange{ + Start: 0, + End: 10, + }, + }, + }, + { + input: `foo @ .3`, + expected: &VectorSelector{ + Name: "foo", + Timestamp: makeInt64Pointer(300), + LabelMatchers: []*labels.Matcher{ + MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "foo"), + }, + PosRange: posrange.PositionRange{ + Start: 0, + End: 8, + }, + }, + }, + { + input: `foo @ 3.`, + expected: &VectorSelector{ + Name: "foo", + Timestamp: makeInt64Pointer(3000), + LabelMatchers: []*labels.Matcher{ + MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "foo"), + }, + PosRange: posrange.PositionRange{ + Start: 0, + End: 8, + }, + }, + }, + { + input: `foo @ 3.33`, + expected: &VectorSelector{ + Name: "foo", + Timestamp: makeInt64Pointer(3330), + LabelMatchers: []*labels.Matcher{ + MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "foo"), + }, + PosRange: posrange.PositionRange{ + Start: 0, + End: 10, + }, + }, + }, + { // Rounding off. + input: `foo @ 3.3333`, + expected: &VectorSelector{ + Name: "foo", + Timestamp: makeInt64Pointer(3333), + LabelMatchers: []*labels.Matcher{ + MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "foo"), + }, + PosRange: posrange.PositionRange{ + Start: 0, + End: 12, + }, + }, + }, + { // Rounding off. + input: `foo @ 3.3335`, + expected: &VectorSelector{ + Name: "foo", + Timestamp: makeInt64Pointer(3334), + LabelMatchers: []*labels.Matcher{ + MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "foo"), + }, + PosRange: posrange.PositionRange{ + Start: 0, + End: 12, + }, + }, + }, + { + input: `foo @ 3e2`, + expected: &VectorSelector{ + Name: "foo", + Timestamp: makeInt64Pointer(300000), + LabelMatchers: []*labels.Matcher{ + MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "foo"), + }, + PosRange: posrange.PositionRange{ + Start: 0, + End: 9, + }, + }, + }, + { + input: `foo @ 3e-1`, + expected: &VectorSelector{ + Name: "foo", + Timestamp: makeInt64Pointer(300), + LabelMatchers: []*labels.Matcher{ + MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "foo"), + }, + PosRange: posrange.PositionRange{ + Start: 0, + End: 10, + }, + }, + }, + { + input: `foo @ 0xA`, + expected: &VectorSelector{ + Name: "foo", + Timestamp: makeInt64Pointer(10000), + LabelMatchers: []*labels.Matcher{ + MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "foo"), + }, + PosRange: posrange.PositionRange{ + Start: 0, + End: 9, + }, + }, + }, + { + input: `foo @ -3.3e1`, + expected: &VectorSelector{ + Name: "foo", + Timestamp: makeInt64Pointer(-33000), + LabelMatchers: []*labels.Matcher{ + MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "foo"), + }, + PosRange: posrange.PositionRange{ + Start: 0, + End: 12, + }, + }, + }, + { + input: `foo @ +Inf`, + fail: true, + errMsg: "1:1: parse error: timestamp out of bounds for @ modifier: +Inf", + }, + { + input: `foo @ -Inf`, + fail: true, + errMsg: "1:1: parse error: timestamp out of bounds for @ modifier: -Inf", + }, + { + input: `foo @ NaN`, + fail: true, + errMsg: "1:1: parse error: timestamp out of bounds for @ modifier: NaN", + }, + { + input: fmt.Sprintf(`foo @ %f`, float64(math.MaxInt64)+1), + fail: true, + errMsg: fmt.Sprintf("1:1: parse error: timestamp out of bounds for @ modifier: %f", float64(math.MaxInt64)+1), + }, + { + input: fmt.Sprintf(`foo @ %f`, float64(math.MinInt64)-1), + fail: true, + errMsg: fmt.Sprintf("1:1: parse error: timestamp out of bounds for @ modifier: %f", float64(math.MinInt64)-1), + }, + { + input: `foo:bar{a="bc"}`, + expected: &VectorSelector{ + Name: "foo:bar", + LabelMatchers: []*labels.Matcher{ + MustLabelMatcher(labels.MatchEqual, "a", "bc"), + MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "foo:bar"), + }, + PosRange: posrange.PositionRange{ + Start: 0, + End: 15, + }, + }, + }, { input: `{"foo"}`, expected: &VectorSelector{ - Name: "foo", + // When a metric is named inside the braces, the Name field is not set. + LabelMatchers: []*labels.Matcher{ + MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "foo"), + }, + PosRange: posrange.PositionRange{ + Start: 0, + End: 7, + }, + }, + }, + { + input: `{"foo", a="bc"}`, + expected: &VectorSelector{ + // When a metric is named inside the braces, the Name field is not set. LabelMatchers: []*labels.Matcher{ MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "foo"), MustLabelMatcher(labels.MatchEqual, "a", "bc"), }, + PosRange: posrange.PositionRange{ + Start: 0, + End: 15, + }, + }, + }, + { + input: `foo{NaN='bc'}`, + expected: &VectorSelector{ + Name: "foo", + LabelMatchers: []*labels.Matcher{ + MustLabelMatcher(labels.MatchEqual, "NaN", "bc"), + MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "foo"), + }, + PosRange: posrange.PositionRange{ + Start: 0, + End: 13, + }, + }, + }, + { + input: `foo{bar='}'}`, + expected: &VectorSelector{ + Name: "foo", + LabelMatchers: []*labels.Matcher{ + MustLabelMatcher(labels.MatchEqual, "bar", "}"), + MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "foo"), + }, + PosRange: posrange.PositionRange{ + Start: 0, + End: 12, + }, + }, + }, + { + input: `foo{a="b", foo!="bar", test=~"test", bar!~"baz"}`, + expected: &VectorSelector{ + Name: "foo", + LabelMatchers: []*labels.Matcher{ + MustLabelMatcher(labels.MatchEqual, "a", "b"), + MustLabelMatcher(labels.MatchNotEqual, "foo", "bar"), + MustLabelMatcher(labels.MatchRegexp, "test", "test"), + MustLabelMatcher(labels.MatchNotRegexp, "bar", "baz"), + MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "foo"), + }, + PosRange: posrange.PositionRange{ + Start: 0, + End: 48, + }, + }, + }, + { + // Metric name in the middle of selector list is fine. + input: `{a="b", foo!="bar", "foo", test=~"test", bar!~"baz"}`, + expected: &VectorSelector{ + LabelMatchers: []*labels.Matcher{ + MustLabelMatcher(labels.MatchEqual, "a", "b"), + MustLabelMatcher(labels.MatchNotEqual, "foo", "bar"), + MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "foo"), + MustLabelMatcher(labels.MatchRegexp, "test", "test"), + MustLabelMatcher(labels.MatchNotRegexp, "bar", "baz"), + }, + PosRange: posrange.PositionRange{ + Start: 0, + End: 52, + }, + }, + }, + { + input: `foo{a="b", foo!="bar", test=~"test", bar!~"baz",}`, + expected: &VectorSelector{ + Name: "foo", + LabelMatchers: []*labels.Matcher{ + MustLabelMatcher(labels.MatchEqual, "a", "b"), + MustLabelMatcher(labels.MatchNotEqual, "foo", "bar"), + MustLabelMatcher(labels.MatchRegexp, "test", "test"), + MustLabelMatcher(labels.MatchNotRegexp, "bar", "baz"), + MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "foo"), + }, + PosRange: posrange.PositionRange{ + Start: 0, + End: 49, + }, + }, + }, + { + input: `{`, + fail: true, + errMsg: "unexpected end of input inside braces", + }, + { + input: `}`, + fail: true, + errMsg: "unexpected character: '}'", + }, + { + input: `some{`, + fail: true, + errMsg: "unexpected end of input inside braces", + }, + { + input: `some}`, + fail: true, + errMsg: "unexpected character: '}'", + }, + { + input: `some_metric{a=b}`, + fail: true, + errMsg: "unexpected identifier \"b\" in label matching, expected string", + }, + { + input: `some_metric{a:b="b"}`, + fail: true, + errMsg: "unexpected character inside braces: ':'", + }, + { + input: `foo{a*"b"}`, + fail: true, + errMsg: "unexpected character inside braces: '*'", + }, + { + input: `foo{a>="b"}`, + fail: true, + // TODO(fabxc): willingly lexing wrong tokens allows for more precise error + // messages from the parser - consider if this is an option. + errMsg: "unexpected character inside braces: '>'", + }, + { + input: "some_metric{a=\"\xff\"}", + fail: true, + errMsg: "1:15: parse error: invalid UTF-8 rune", + }, + { + input: `foo{gibberish}`, + fail: true, + errMsg: `unexpected "}" in label matching, expected label matching operator`, + }, + { + input: `foo{1}`, + fail: true, + errMsg: "unexpected character inside braces: '1'", + }, + { + input: `{}`, + fail: true, + errMsg: "vector selector must contain at least one non-empty matcher", + }, + { + input: `{x=""}`, + fail: true, + errMsg: "vector selector must contain at least one non-empty matcher", + }, + { + input: `{x=~".*"}`, + fail: true, + errMsg: "vector selector must contain at least one non-empty matcher", + }, + { + input: `{x!~".+"}`, + fail: true, + errMsg: "vector selector must contain at least one non-empty matcher", + }, + { + input: `{x!="a"}`, + fail: true, + errMsg: "vector selector must contain at least one non-empty matcher", + }, + { + input: `foo{__name__="bar"}`, + fail: true, + errMsg: `metric name must not be set twice: "foo" or "bar"`, + }, + { + input: `foo{__name__= =}`, + fail: true, + errMsg: `1:15: parse error: unexpected "=" in label matching, expected string`, + }, + { + input: `foo{,}`, + fail: true, + errMsg: `unexpected "," in label matching, expected identifier or "}"`, + }, + { + input: `foo{__name__ == "bar"}`, + fail: true, + errMsg: `1:15: parse error: unexpected "=" in label matching, expected string`, + }, + { + input: `foo{__name__="bar" lol}`, + fail: true, + errMsg: `unexpected identifier "lol" in label matching, expected "," or "}"`, + }, + // Test matrix selector. + { + input: "test[5s]", + expected: &MatrixSelector{ + VectorSelector: &VectorSelector{ + Name: "test", + LabelMatchers: []*labels.Matcher{ + MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "test"), + }, + PosRange: posrange.PositionRange{ + Start: 0, + End: 4, + }, + }, + Range: 5 * time.Second, + EndPos: 8, + }, + }, + { + input: "test[5m]", + expected: &MatrixSelector{ + VectorSelector: &VectorSelector{ + Name: "test", + LabelMatchers: []*labels.Matcher{ + MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "test"), + }, + PosRange: posrange.PositionRange{ + Start: 0, + End: 4, + }, + }, + Range: 5 * time.Minute, + EndPos: 8, + }, + }, + { + input: `foo[5m30s]`, + expected: &MatrixSelector{ + VectorSelector: &VectorSelector{ + Name: "foo", + LabelMatchers: []*labels.Matcher{ + MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "foo"), + }, + PosRange: posrange.PositionRange{ + Start: 0, + End: 3, + }, + }, + Range: 5*time.Minute + 30*time.Second, + EndPos: 10, + }, + }, + { + input: "test[5h] OFFSET 5m", + expected: &MatrixSelector{ + VectorSelector: &VectorSelector{ + Name: "test", + OriginalOffset: 5 * time.Minute, + LabelMatchers: []*labels.Matcher{ + MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "test"), + }, + PosRange: posrange.PositionRange{ + Start: 0, + End: 4, + }, + }, + Range: 5 * time.Hour, + EndPos: 18, + }, + }, + { + input: "test[5d] OFFSET 10s", + expected: &MatrixSelector{ + VectorSelector: &VectorSelector{ + Name: "test", + OriginalOffset: 10 * time.Second, + LabelMatchers: []*labels.Matcher{ + MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "test"), + }, + PosRange: posrange.PositionRange{ + Start: 0, + End: 4, + }, + }, + Range: 5 * 24 * time.Hour, + EndPos: 19, + }, + }, + { + input: "test[5w] offset 2w", + expected: &MatrixSelector{ + VectorSelector: &VectorSelector{ + Name: "test", + OriginalOffset: 14 * 24 * time.Hour, + LabelMatchers: []*labels.Matcher{ + MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "test"), + }, + PosRange: posrange.PositionRange{ + Start: 0, + End: 4, + }, + }, + Range: 5 * 7 * 24 * time.Hour, + EndPos: 18, + }, + }, + { + input: `test{a="b"}[5y] OFFSET 3d`, + expected: &MatrixSelector{ + VectorSelector: &VectorSelector{ + Name: "test", + OriginalOffset: 3 * 24 * time.Hour, + LabelMatchers: []*labels.Matcher{ + MustLabelMatcher(labels.MatchEqual, "a", "b"), + MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "test"), + }, + PosRange: posrange.PositionRange{ + Start: 0, + End: 11, + }, + }, + Range: 5 * 365 * 24 * time.Hour, + EndPos: 25, + }, + }, + { + input: `test{a="b"}[5y] @ 1603774699`, + expected: &MatrixSelector{ + VectorSelector: &VectorSelector{ + Name: "test", + Timestamp: makeInt64Pointer(1603774699000), + LabelMatchers: []*labels.Matcher{ + MustLabelMatcher(labels.MatchEqual, "a", "b"), + MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "test"), + }, + PosRange: posrange.PositionRange{ + Start: 0, + End: 11, + }, + }, + Range: 5 * 365 * 24 * time.Hour, + EndPos: 28, + }, + }, + { + input: `foo[5mm]`, + fail: true, + errMsg: "bad duration syntax: \"5mm\"", + }, + { + input: `foo[5m1]`, + fail: true, + errMsg: "bad duration syntax: \"5m1\"", + }, + { + input: `foo[5m:1m1]`, + fail: true, + errMsg: "bad number or duration syntax: \"1m1\"", + }, + { + input: `foo[5y1hs]`, + fail: true, + errMsg: "unknown unit \"hs\" in duration \"5y1hs\"", + }, + { + input: `foo[5m1h]`, + fail: true, + errMsg: "not a valid duration string: \"5m1h\"", + }, + { + input: `foo[5m1m]`, + fail: true, + errMsg: "not a valid duration string: \"5m1m\"", + }, + { + input: `foo[0m]`, + fail: true, + errMsg: "duration must be greater than 0", + }, + { + input: `foo["5m"]`, + fail: true, + }, + { + input: `foo[]`, + fail: true, + errMsg: "missing unit character in duration", + }, + { + input: `foo[1]`, + fail: true, + errMsg: "missing unit character in duration", + }, + { + input: `some_metric[5m] OFFSET 1`, + fail: true, + errMsg: "unexpected number \"1\" in offset, expected duration", + }, + { + input: `some_metric[5m] OFFSET 1mm`, + fail: true, + errMsg: "bad number or duration syntax: \"1mm\"", + }, + { + input: `some_metric[5m] OFFSET`, + fail: true, + errMsg: "unexpected end of input in offset, expected duration", + }, + { + input: `some_metric OFFSET 1m[5m]`, + fail: true, + errMsg: "1:22: parse error: no offset modifiers allowed before range", + }, + { + input: `some_metric[5m] @ 1m`, + fail: true, + errMsg: "1:19: parse error: unexpected duration \"1m\" in @, expected timestamp", + }, + { + input: `some_metric[5m] @`, + fail: true, + errMsg: "1:18: parse error: unexpected end of input in @, expected timestamp", + }, + { + input: `some_metric @ 1234 [5m]`, + fail: true, + errMsg: "1:20: parse error: no @ modifiers allowed before range", + }, + { + input: `(foo + bar)[5m]`, + fail: true, + errMsg: "1:12: parse error: ranges only allowed for vector selectors", + }, + // Test aggregation. + { + input: "sum by (foo)(some_metric)", + expected: &AggregateExpr{ + Op: SUM, + Expr: &VectorSelector{ + Name: "some_metric", + LabelMatchers: []*labels.Matcher{ + MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "some_metric"), + }, + PosRange: posrange.PositionRange{ + Start: 13, + End: 24, + }, + }, + Grouping: []string{"foo"}, + PosRange: posrange.PositionRange{ + Start: 0, + End: 25, + }, + }, + }, + { + input: "avg by (foo)(some_metric)", + expected: &AggregateExpr{ + Op: AVG, + Expr: &VectorSelector{ + Name: "some_metric", + LabelMatchers: []*labels.Matcher{ + MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "some_metric"), + }, + PosRange: posrange.PositionRange{ + Start: 13, + End: 24, + }, + }, + Grouping: []string{"foo"}, + PosRange: posrange.PositionRange{ + Start: 0, + End: 25, + }, + }, + }, + { + input: "max by (foo)(some_metric)", + expected: &AggregateExpr{ + Op: MAX, + Expr: &VectorSelector{ + Name: "some_metric", + LabelMatchers: []*labels.Matcher{ + MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "some_metric"), + }, + PosRange: posrange.PositionRange{ + Start: 13, + End: 24, + }, + }, + Grouping: []string{"foo"}, + PosRange: posrange.PositionRange{ + Start: 0, + End: 25, + }, + }, + }, + { + input: "sum without (foo) (some_metric)", + expected: &AggregateExpr{ + Op: SUM, + Without: true, + Expr: &VectorSelector{ + Name: "some_metric", + LabelMatchers: []*labels.Matcher{ + MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "some_metric"), + }, + PosRange: posrange.PositionRange{ + Start: 19, + End: 30, + }, + }, + Grouping: []string{"foo"}, + PosRange: posrange.PositionRange{ + Start: 0, + End: 31, + }, + }, + }, + { + input: "sum (some_metric) without (foo)", + expected: &AggregateExpr{ + Op: SUM, + Without: true, + Expr: &VectorSelector{ + Name: "some_metric", + LabelMatchers: []*labels.Matcher{ + MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "some_metric"), + }, + PosRange: posrange.PositionRange{ + Start: 5, + End: 16, + }, + }, + Grouping: []string{"foo"}, + PosRange: posrange.PositionRange{ + Start: 0, + End: 31, + }, + }, + }, + { + input: "stddev(some_metric)", + expected: &AggregateExpr{ + Op: STDDEV, + Expr: &VectorSelector{ + Name: "some_metric", + LabelMatchers: []*labels.Matcher{ + MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "some_metric"), + }, + PosRange: posrange.PositionRange{ + Start: 7, + End: 18, + }, + }, + PosRange: posrange.PositionRange{ + Start: 0, + End: 19, + }, + }, + }, + { + input: "stdvar by (foo)(some_metric)", + expected: &AggregateExpr{ + Op: STDVAR, + Expr: &VectorSelector{ + Name: "some_metric", + LabelMatchers: []*labels.Matcher{ + MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "some_metric"), + }, + PosRange: posrange.PositionRange{ + Start: 16, + End: 27, + }, + }, + Grouping: []string{"foo"}, + PosRange: posrange.PositionRange{ + Start: 0, + End: 28, + }, + }, + }, + { + input: "sum by ()(some_metric)", + expected: &AggregateExpr{ + Op: SUM, + Expr: &VectorSelector{ + Name: "some_metric", + LabelMatchers: []*labels.Matcher{ + MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "some_metric"), + }, + PosRange: posrange.PositionRange{ + Start: 10, + End: 21, + }, + }, + Grouping: []string{}, + PosRange: posrange.PositionRange{ + Start: 0, + End: 22, + }, + }, + }, + { + input: "sum by (foo,bar,)(some_metric)", + expected: &AggregateExpr{ + Op: SUM, + Expr: &VectorSelector{ + Name: "some_metric", + LabelMatchers: []*labels.Matcher{ + MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "some_metric"), + }, + PosRange: posrange.PositionRange{ + Start: 18, + End: 29, + }, + }, + Grouping: []string{"foo", "bar"}, + PosRange: posrange.PositionRange{ + Start: 0, + End: 30, + }, + }, + }, + { + input: "sum by (foo,)(some_metric)", + expected: &AggregateExpr{ + Op: SUM, + Expr: &VectorSelector{ + Name: "some_metric", + LabelMatchers: []*labels.Matcher{ + MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "some_metric"), + }, + PosRange: posrange.PositionRange{ + Start: 14, + End: 25, + }, + }, + Grouping: []string{"foo"}, + PosRange: posrange.PositionRange{ + Start: 0, + End: 26, + }, + }, + }, + { + input: "topk(5, some_metric)", + expected: &AggregateExpr{ + Op: TOPK, + Expr: &VectorSelector{ + Name: "some_metric", + LabelMatchers: []*labels.Matcher{ + MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "some_metric"), + }, + PosRange: posrange.PositionRange{ + Start: 8, + End: 19, + }, + }, + Param: &NumberLiteral{ + Val: 5, + PosRange: posrange.PositionRange{ + Start: 5, + End: 6, + }, + }, + PosRange: posrange.PositionRange{ + Start: 0, + End: 20, + }, + }, + }, + { + input: `count_values("value", some_metric)`, + expected: &AggregateExpr{ + Op: COUNT_VALUES, + Expr: &VectorSelector{ + Name: "some_metric", + LabelMatchers: []*labels.Matcher{ + MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "some_metric"), + }, + PosRange: posrange.PositionRange{ + Start: 22, + End: 33, + }, + }, + Param: &StringLiteral{ + Val: "value", + PosRange: posrange.PositionRange{ + Start: 13, + End: 20, + }, + }, + PosRange: posrange.PositionRange{ + Start: 0, + End: 34, + }, + }, + }, + { + // Test usage of keywords as label names. + input: "sum without(and, by, avg, count, alert, annotations)(some_metric)", + expected: &AggregateExpr{ + Op: SUM, + Without: true, + Expr: &VectorSelector{ + Name: "some_metric", + LabelMatchers: []*labels.Matcher{ + MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "some_metric"), + }, + PosRange: posrange.PositionRange{ + Start: 53, + End: 64, + }, + }, + Grouping: []string{"and", "by", "avg", "count", "alert", "annotations"}, + PosRange: posrange.PositionRange{ + Start: 0, + End: 65, + }, + }, + }, + { + input: "sum without(==)(some_metric)", + fail: true, + errMsg: "unexpected in grouping opts, expected label", + }, + { + input: "sum without(,)(some_metric)", + fail: true, + errMsg: `unexpected "," in grouping opts, expected label`, + }, + { + input: "sum without(foo,,)(some_metric)", + fail: true, + errMsg: `unexpected "," in grouping opts, expected label`, + }, + { + input: `sum some_metric by (test)`, + fail: true, + errMsg: "unexpected identifier \"some_metric\"", + }, + { + input: `sum (some_metric) by test`, + fail: true, + errMsg: "unexpected identifier \"test\" in grouping opts", + }, + { + input: `sum (some_metric) by test`, + fail: true, + errMsg: "unexpected identifier \"test\" in grouping opts", + }, + { + input: `sum () by (test)`, + fail: true, + errMsg: "no arguments for aggregate expression provided", + }, + { + input: "MIN keep_common (some_metric)", + fail: true, + errMsg: "1:5: parse error: unexpected identifier \"keep_common\"", + }, + { + input: "MIN (some_metric) keep_common", + fail: true, + errMsg: `unexpected identifier "keep_common"`, + }, + { + input: `sum (some_metric) without (test) by (test)`, + fail: true, + errMsg: "unexpected ", + }, + { + input: `sum without (test) (some_metric) by (test)`, + fail: true, + errMsg: "unexpected ", + }, + { + input: `topk(some_metric)`, + fail: true, + errMsg: "wrong number of arguments for aggregate expression provided, expected 2, got 1", + }, + { + input: `topk(some_metric,)`, + fail: true, + errMsg: "trailing commas not allowed in function call args", + }, + { + input: `topk(some_metric, other_metric)`, + fail: true, + errMsg: "1:6: parse error: expected type scalar in aggregation parameter, got instant vector", + }, + { + input: `count_values(5, other_metric)`, + fail: true, + errMsg: "1:14: parse error: expected type string in aggregation parameter, got scalar", + }, + { + input: `rate(some_metric[5m]) @ 1234`, + fail: true, + errMsg: "1:1: parse error: @ modifier must be preceded by an instant vector selector or range vector selector or a subquery", + }, + // Test function calls. + { + input: "time()", + expected: &Call{ + Func: MustGetFunction("time"), + Args: Expressions{}, PosRange: posrange.PositionRange{ Start: 0, End: 6, }, }, }, - // { - // input: `{"foo", a="bc"}`, - // expected: &VectorSelector{ - // Name: "foo:bar", - // LabelMatchers: []*labels.Matcher{ - // MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "foo"), - // MustLabelMatcher(labels.MatchEqual, "a", "bc"), - // }, - // PosRange: posrange.PositionRange{ - // Start: 0, - // End: 15, - // }, - // }, - // }, + { + input: `floor(some_metric{foo!="bar"})`, + expected: &Call{ + Func: MustGetFunction("floor"), + Args: Expressions{ + &VectorSelector{ + Name: "some_metric", + LabelMatchers: []*labels.Matcher{ + MustLabelMatcher(labels.MatchNotEqual, "foo", "bar"), + MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "some_metric"), + }, + PosRange: posrange.PositionRange{ + Start: 6, + End: 29, + }, + }, + }, + PosRange: posrange.PositionRange{ + Start: 0, + End: 30, + }, + }, + }, + { + input: "rate(some_metric[5m])", + expected: &Call{ + Func: MustGetFunction("rate"), + Args: Expressions{ + &MatrixSelector{ + VectorSelector: &VectorSelector{ + Name: "some_metric", + LabelMatchers: []*labels.Matcher{ + MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "some_metric"), + }, + PosRange: posrange.PositionRange{ + Start: 5, + End: 16, + }, + }, + Range: 5 * time.Minute, + EndPos: 20, + }, + }, + PosRange: posrange.PositionRange{ + Start: 0, + End: 21, + }, + }, + }, + { + input: "round(some_metric)", + expected: &Call{ + Func: MustGetFunction("round"), + Args: Expressions{ + &VectorSelector{ + Name: "some_metric", + LabelMatchers: []*labels.Matcher{ + MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "some_metric"), + }, + PosRange: posrange.PositionRange{ + Start: 6, + End: 17, + }, + }, + }, + PosRange: posrange.PositionRange{ + Start: 0, + End: 18, + }, + }, + }, + { + input: "round(some_metric, 5)", + expected: &Call{ + Func: MustGetFunction("round"), + Args: Expressions{ + &VectorSelector{ + Name: "some_metric", + LabelMatchers: []*labels.Matcher{ + MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "some_metric"), + }, + PosRange: posrange.PositionRange{ + Start: 6, + End: 17, + }, + }, + &NumberLiteral{ + Val: 5, + PosRange: posrange.PositionRange{ + Start: 19, + End: 20, + }, + }, + }, + PosRange: posrange.PositionRange{ + Start: 0, + End: 21, + }, + }, + }, + { + input: "floor()", + fail: true, + errMsg: "expected 1 argument(s) in call to \"floor\", got 0", + }, + { + input: "floor(some_metric, other_metric)", + fail: true, + errMsg: "expected 1 argument(s) in call to \"floor\", got 2", + }, + { + input: "floor(some_metric, 1)", + fail: true, + errMsg: "expected 1 argument(s) in call to \"floor\", got 2", + }, + { + input: "floor(1)", + fail: true, + errMsg: "expected type instant vector in call to function \"floor\", got scalar", + }, + { + input: "hour(some_metric, some_metric, some_metric)", + fail: true, + errMsg: "expected at most 1 argument(s) in call to \"hour\", got 3", + }, + { + input: "time(some_metric)", + fail: true, + errMsg: "expected 0 argument(s) in call to \"time\", got 1", + }, + { + input: "non_existent_function_far_bar()", + fail: true, + errMsg: "unknown function with name \"non_existent_function_far_bar\"", + }, + { + input: "rate(some_metric)", + fail: true, + errMsg: "expected type range vector in call to function \"rate\", got instant vector", + }, + { + input: "label_replace(a, `b`, `c\xff`, `d`, `.*`)", + fail: true, + errMsg: "1:23: parse error: invalid UTF-8 rune", + }, + // Fuzzing regression tests. + { + input: "-=", + fail: true, + errMsg: `unexpected "="`, + }, + { + input: "++-++-+-+-<", + fail: true, + errMsg: `unexpected `, + }, + { + input: "e-+=/(0)", + fail: true, + errMsg: `unexpected "="`, + }, + { + input: "a>b()", + fail: true, + errMsg: `unknown function`, + }, + { + input: "rate(avg)", + fail: true, + errMsg: `expected type range vector`, + }, + { + // This is testing that we are not re-rendering the expression string for each error, which would timeout. + input: "(" + strings.Repeat("-{}-1", 10000) + ")" + strings.Repeat("[1m:]", 1000), + fail: true, + errMsg: `1:3: parse error: vector selector must contain at least one non-empty matcher`, + }, + { + input: "sum(sum)", + expected: &AggregateExpr{ + Op: SUM, + Expr: &VectorSelector{ + Name: "sum", + LabelMatchers: []*labels.Matcher{ + MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "sum"), + }, + PosRange: posrange.PositionRange{ + Start: 4, + End: 7, + }, + }, + PosRange: posrange.PositionRange{ + Start: 0, + End: 8, + }, + }, + }, + { + input: "a + sum", + expected: &BinaryExpr{ + Op: ADD, + LHS: &VectorSelector{ + Name: "a", + LabelMatchers: []*labels.Matcher{ + MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "a"), + }, + PosRange: posrange.PositionRange{ + Start: 0, + End: 1, + }, + }, + RHS: &VectorSelector{ + Name: "sum", + LabelMatchers: []*labels.Matcher{ + MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "sum"), + }, + PosRange: posrange.PositionRange{ + Start: 4, + End: 7, + }, + }, + VectorMatching: &VectorMatching{}, + }, + }, + // String quoting and escape sequence interpretation tests. + { + input: `"double-quoted string \" with escaped quote"`, + expected: &StringLiteral{ + Val: "double-quoted string \" with escaped quote", + PosRange: posrange.PositionRange{Start: 0, End: 44}, + }, + }, + { + input: `'single-quoted string \' with escaped quote'`, + expected: &StringLiteral{ + Val: "single-quoted string ' with escaped quote", + PosRange: posrange.PositionRange{Start: 0, End: 44}, + }, + }, + { + input: "`backtick-quoted string`", + expected: &StringLiteral{ + Val: "backtick-quoted string", + PosRange: posrange.PositionRange{Start: 0, End: 24}, + }, + }, + { + input: `"\a\b\f\n\r\t\v\\\" - \xFF\377\u1234\U00010111\U0001011111☺"`, + expected: &StringLiteral{ + Val: "\a\b\f\n\r\t\v\\\" - \xFF\377\u1234\U00010111\U0001011111☺", + PosRange: posrange.PositionRange{Start: 0, End: 62}, + }, + }, + { + input: `'\a\b\f\n\r\t\v\\\' - \xFF\377\u1234\U00010111\U0001011111☺'`, + expected: &StringLiteral{ + Val: "\a\b\f\n\r\t\v\\' - \xFF\377\u1234\U00010111\U0001011111☺", + PosRange: posrange.PositionRange{Start: 0, End: 62}, + }, + }, + { + input: "`" + `\a\b\f\n\r\t\v\\\"\' - \xFF\377\u1234\U00010111\U0001011111☺` + "`", + expected: &StringLiteral{ + Val: `\a\b\f\n\r\t\v\\\"\' - \xFF\377\u1234\U00010111\U0001011111☺`, + PosRange: posrange.PositionRange{Start: 0, End: 64}, + }, + }, + { + input: "`\\``", + fail: true, + errMsg: "unterminated raw string", + }, + { + input: `"\`, + fail: true, + errMsg: "escape sequence not terminated", + }, + { + input: `"\c"`, + fail: true, + errMsg: "unknown escape sequence U+0063 'c'", + }, + { + input: `"\x."`, + fail: true, + errMsg: "illegal character U+002E '.' in escape sequence", + }, + // Subquery. + { + input: `foo{bar="baz"}[10m:6s]`, + expected: &SubqueryExpr{ + Expr: &VectorSelector{ + Name: "foo", + LabelMatchers: []*labels.Matcher{ + MustLabelMatcher(labels.MatchEqual, "bar", "baz"), + MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "foo"), + }, + PosRange: posrange.PositionRange{ + Start: 0, + End: 14, + }, + }, + Range: 10 * time.Minute, + Step: 6 * time.Second, + EndPos: 22, + }, + }, + { + input: `foo{bar="baz"}[10m5s:1h6ms]`, + expected: &SubqueryExpr{ + Expr: &VectorSelector{ + Name: "foo", + LabelMatchers: []*labels.Matcher{ + MustLabelMatcher(labels.MatchEqual, "bar", "baz"), + MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "foo"), + }, + PosRange: posrange.PositionRange{ + Start: 0, + End: 14, + }, + }, + Range: 10*time.Minute + 5*time.Second, + Step: time.Hour + 6*time.Millisecond, + EndPos: 27, + }, + }, + { + input: `foo[10m:]`, + expected: &SubqueryExpr{ + Expr: &VectorSelector{ + Name: "foo", + LabelMatchers: []*labels.Matcher{ + MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "foo"), + }, + PosRange: posrange.PositionRange{ + Start: 0, + End: 3, + }, + }, + Range: 10 * time.Minute, + EndPos: 9, + }, + }, + { + input: `min_over_time(rate(foo{bar="baz"}[2s])[5m:5s])`, + expected: &Call{ + Func: MustGetFunction("min_over_time"), + Args: Expressions{ + &SubqueryExpr{ + Expr: &Call{ + Func: MustGetFunction("rate"), + Args: Expressions{ + &MatrixSelector{ + VectorSelector: &VectorSelector{ + Name: "foo", + LabelMatchers: []*labels.Matcher{ + MustLabelMatcher(labels.MatchEqual, "bar", "baz"), + MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "foo"), + }, + PosRange: posrange.PositionRange{ + Start: 19, + End: 33, + }, + }, + Range: 2 * time.Second, + EndPos: 37, + }, + }, + PosRange: posrange.PositionRange{ + Start: 14, + End: 38, + }, + }, + Range: 5 * time.Minute, + Step: 5 * time.Second, - // { - // input: `foo{NaN='bc'}`, - // expected: &VectorSelector{ - // Name: "foo", - // LabelMatchers: []*labels.Matcher{ - // MustLabelMatcher(labels.MatchEqual, "NaN", "bc"), - // MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "foo"), - // }, - // PosRange: posrange.PositionRange{ - // Start: 0, - // End: 13, - // }, - // }, - // }, - // { - // input: `foo{bar='}'}`, - // expected: &VectorSelector{ - // Name: "foo", - // LabelMatchers: []*labels.Matcher{ - // MustLabelMatcher(labels.MatchEqual, "bar", "}"), - // MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "foo"), - // }, - // PosRange: posrange.PositionRange{ - // Start: 0, - // End: 12, - // }, - // }, - // }, - // { - // input: `foo{a="b", foo!="bar", test=~"test", bar!~"baz"}`, - // expected: &VectorSelector{ - // Name: "foo", - // LabelMatchers: []*labels.Matcher{ - // MustLabelMatcher(labels.MatchEqual, "a", "b"), - // MustLabelMatcher(labels.MatchNotEqual, "foo", "bar"), - // MustLabelMatcher(labels.MatchRegexp, "test", "test"), - // MustLabelMatcher(labels.MatchNotRegexp, "bar", "baz"), - // MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "foo"), - // }, - // PosRange: posrange.PositionRange{ - // Start: 0, - // End: 48, - // }, - // }, - // }, - // { - // input: `foo{a="b", foo!="bar", test=~"test", bar!~"baz",}`, - // expected: &VectorSelector{ - // Name: "foo", - // LabelMatchers: []*labels.Matcher{ - // MustLabelMatcher(labels.MatchEqual, "a", "b"), - // MustLabelMatcher(labels.MatchNotEqual, "foo", "bar"), - // MustLabelMatcher(labels.MatchRegexp, "test", "test"), - // MustLabelMatcher(labels.MatchNotRegexp, "bar", "baz"), - // MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "foo"), - // }, - // PosRange: posrange.PositionRange{ - // Start: 0, - // End: 49, - // }, - // }, - // }, - // { - // input: `{`, - // fail: true, - // errMsg: "unexpected end of input inside braces", - // }, - // { - // input: `}`, - // fail: true, - // errMsg: "unexpected character: '}'", - // }, - // { - // input: `some{`, - // fail: true, - // errMsg: "unexpected end of input inside braces", - // }, - // { - // input: `some}`, - // fail: true, - // errMsg: "unexpected character: '}'", - // }, - // { - // input: `some_metric{a=b}`, - // fail: true, - // errMsg: "unexpected identifier \"b\" in label matching, expected string", - // }, - // { - // input: `some_metric{a:b="b"}`, - // fail: true, - // errMsg: "unexpected character inside braces: ':'", - // }, - // { - // input: `foo{a*"b"}`, - // fail: true, - // errMsg: "unexpected character inside braces: '*'", - // }, - // { - // input: `foo{a>="b"}`, - // fail: true, - // // TODO(fabxc): willingly lexing wrong tokens allows for more precise error - // // messages from the parser - consider if this is an option. - // errMsg: "unexpected character inside braces: '>'", - // }, - // { - // input: "some_metric{a=\"\xff\"}", - // fail: true, - // errMsg: "1:15: parse error: invalid UTF-8 rune", - // }, - // { - // input: `foo{gibberish}`, - // fail: true, - // errMsg: `unexpected "}" in label matching, expected label matching operator`, - // }, - // { - // input: `foo{1}`, - // fail: true, - // errMsg: "unexpected character inside braces: '1'", - // }, - // { - // input: `{}`, - // fail: true, - // errMsg: "vector selector must contain at least one non-empty matcher", - // }, - // { - // input: `{x=""}`, - // fail: true, - // errMsg: "vector selector must contain at least one non-empty matcher", - // }, - // { - // input: `{x=~".*"}`, - // fail: true, - // errMsg: "vector selector must contain at least one non-empty matcher", - // }, - // { - // input: `{x!~".+"}`, - // fail: true, - // errMsg: "vector selector must contain at least one non-empty matcher", - // }, - // { - // input: `{x!="a"}`, - // fail: true, - // errMsg: "vector selector must contain at least one non-empty matcher", - // }, - // { - // input: `foo{__name__="bar"}`, - // fail: true, - // errMsg: `metric name must not be set twice: "foo" or "bar"`, - // }, - // { - // input: `foo{__name__= =}`, - // fail: true, - // errMsg: `1:15: parse error: unexpected "=" in label matching, expected string`, - // }, - // { - // input: `foo{,}`, - // fail: true, - // errMsg: `unexpected "," in label matching, expected identifier or "}"`, - // }, - // { - // input: `foo{__name__ == "bar"}`, - // fail: true, - // errMsg: `1:15: parse error: unexpected "=" in label matching, expected string`, - // }, - // { - // input: `foo{__name__="bar" lol}`, - // fail: true, - // errMsg: `unexpected identifier "lol" in label matching, expected "," or "}"`, - // }, - // // Test matrix selector. - // { - // input: "test[5s]", - // expected: &MatrixSelector{ - // VectorSelector: &VectorSelector{ - // Name: "test", - // LabelMatchers: []*labels.Matcher{ - // MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "test"), - // }, - // PosRange: posrange.PositionRange{ - // Start: 0, - // End: 4, - // }, - // }, - // Range: 5 * time.Second, - // EndPos: 8, - // }, - // }, - // { - // input: "test[5m]", - // expected: &MatrixSelector{ - // VectorSelector: &VectorSelector{ - // Name: "test", - // LabelMatchers: []*labels.Matcher{ - // MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "test"), - // }, - // PosRange: posrange.PositionRange{ - // Start: 0, - // End: 4, - // }, - // }, - // Range: 5 * time.Minute, - // EndPos: 8, - // }, - // }, - // { - // input: `foo[5m30s]`, - // expected: &MatrixSelector{ - // VectorSelector: &VectorSelector{ - // Name: "foo", - // LabelMatchers: []*labels.Matcher{ - // MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "foo"), - // }, - // PosRange: posrange.PositionRange{ - // Start: 0, - // End: 3, - // }, - // }, - // Range: 5*time.Minute + 30*time.Second, - // EndPos: 10, - // }, - // }, - // { - // input: "test[5h] OFFSET 5m", - // expected: &MatrixSelector{ - // VectorSelector: &VectorSelector{ - // Name: "test", - // OriginalOffset: 5 * time.Minute, - // LabelMatchers: []*labels.Matcher{ - // MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "test"), - // }, - // PosRange: posrange.PositionRange{ - // Start: 0, - // End: 4, - // }, - // }, - // Range: 5 * time.Hour, - // EndPos: 18, - // }, - // }, - // { - // input: "test[5d] OFFSET 10s", - // expected: &MatrixSelector{ - // VectorSelector: &VectorSelector{ - // Name: "test", - // OriginalOffset: 10 * time.Second, - // LabelMatchers: []*labels.Matcher{ - // MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "test"), - // }, - // PosRange: posrange.PositionRange{ - // Start: 0, - // End: 4, - // }, - // }, - // Range: 5 * 24 * time.Hour, - // EndPos: 19, - // }, - // }, - // { - // input: "test[5w] offset 2w", - // expected: &MatrixSelector{ - // VectorSelector: &VectorSelector{ - // Name: "test", - // OriginalOffset: 14 * 24 * time.Hour, - // LabelMatchers: []*labels.Matcher{ - // MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "test"), - // }, - // PosRange: posrange.PositionRange{ - // Start: 0, - // End: 4, - // }, - // }, - // Range: 5 * 7 * 24 * time.Hour, - // EndPos: 18, - // }, - // }, - // { - // input: `test{a="b"}[5y] OFFSET 3d`, - // expected: &MatrixSelector{ - // VectorSelector: &VectorSelector{ - // Name: "test", - // OriginalOffset: 3 * 24 * time.Hour, - // LabelMatchers: []*labels.Matcher{ - // MustLabelMatcher(labels.MatchEqual, "a", "b"), - // MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "test"), - // }, - // PosRange: posrange.PositionRange{ - // Start: 0, - // End: 11, - // }, - // }, - // Range: 5 * 365 * 24 * time.Hour, - // EndPos: 25, - // }, - // }, - // { - // input: `test{a="b"}[5y] @ 1603774699`, - // expected: &MatrixSelector{ - // VectorSelector: &VectorSelector{ - // Name: "test", - // Timestamp: makeInt64Pointer(1603774699000), - // LabelMatchers: []*labels.Matcher{ - // MustLabelMatcher(labels.MatchEqual, "a", "b"), - // MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "test"), - // }, - // PosRange: posrange.PositionRange{ - // Start: 0, - // End: 11, - // }, - // }, - // Range: 5 * 365 * 24 * time.Hour, - // EndPos: 28, - // }, - // }, - // { - // input: `foo[5mm]`, - // fail: true, - // errMsg: "bad duration syntax: \"5mm\"", - // }, - // { - // input: `foo[5m1]`, - // fail: true, - // errMsg: "bad duration syntax: \"5m1\"", - // }, - // { - // input: `foo[5m:1m1]`, - // fail: true, - // errMsg: "bad number or duration syntax: \"1m1\"", - // }, - // { - // input: `foo[5y1hs]`, - // fail: true, - // errMsg: "unknown unit \"hs\" in duration \"5y1hs\"", - // }, - // { - // input: `foo[5m1h]`, - // fail: true, - // errMsg: "not a valid duration string: \"5m1h\"", - // }, - // { - // input: `foo[5m1m]`, - // fail: true, - // errMsg: "not a valid duration string: \"5m1m\"", - // }, - // { - // input: `foo[0m]`, - // fail: true, - // errMsg: "duration must be greater than 0", - // }, - // { - // input: `foo["5m"]`, - // fail: true, - // }, - // { - // input: `foo[]`, - // fail: true, - // errMsg: "missing unit character in duration", - // }, - // { - // input: `foo[1]`, - // fail: true, - // errMsg: "missing unit character in duration", - // }, - // { - // input: `some_metric[5m] OFFSET 1`, - // fail: true, - // errMsg: "unexpected number \"1\" in offset, expected duration", - // }, - // { - // input: `some_metric[5m] OFFSET 1mm`, - // fail: true, - // errMsg: "bad number or duration syntax: \"1mm\"", - // }, - // { - // input: `some_metric[5m] OFFSET`, - // fail: true, - // errMsg: "unexpected end of input in offset, expected duration", - // }, - // { - // input: `some_metric OFFSET 1m[5m]`, - // fail: true, - // errMsg: "1:22: parse error: no offset modifiers allowed before range", - // }, - // { - // input: `some_metric[5m] @ 1m`, - // fail: true, - // errMsg: "1:19: parse error: unexpected duration \"1m\" in @, expected timestamp", - // }, - // { - // input: `some_metric[5m] @`, - // fail: true, - // errMsg: "1:18: parse error: unexpected end of input in @, expected timestamp", - // }, - // { - // input: `some_metric @ 1234 [5m]`, - // fail: true, - // errMsg: "1:20: parse error: no @ modifiers allowed before range", - // }, - // { - // input: `(foo + bar)[5m]`, - // fail: true, - // errMsg: "1:12: parse error: ranges only allowed for vector selectors", - // }, - // // Test aggregation. - // { - // input: "sum by (foo)(some_metric)", - // expected: &AggregateExpr{ - // Op: SUM, - // Expr: &VectorSelector{ - // Name: "some_metric", - // LabelMatchers: []*labels.Matcher{ - // MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "some_metric"), - // }, - // PosRange: posrange.PositionRange{ - // Start: 13, - // End: 24, - // }, - // }, - // Grouping: []string{"foo"}, - // PosRange: posrange.PositionRange{ - // Start: 0, - // End: 25, - // }, - // }, - // }, - // { - // input: "avg by (foo)(some_metric)", - // expected: &AggregateExpr{ - // Op: AVG, - // Expr: &VectorSelector{ - // Name: "some_metric", - // LabelMatchers: []*labels.Matcher{ - // MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "some_metric"), - // }, - // PosRange: posrange.PositionRange{ - // Start: 13, - // End: 24, - // }, - // }, - // Grouping: []string{"foo"}, - // PosRange: posrange.PositionRange{ - // Start: 0, - // End: 25, - // }, - // }, - // }, - // { - // input: "max by (foo)(some_metric)", - // expected: &AggregateExpr{ - // Op: MAX, - // Expr: &VectorSelector{ - // Name: "some_metric", - // LabelMatchers: []*labels.Matcher{ - // MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "some_metric"), - // }, - // PosRange: posrange.PositionRange{ - // Start: 13, - // End: 24, - // }, - // }, - // Grouping: []string{"foo"}, - // PosRange: posrange.PositionRange{ - // Start: 0, - // End: 25, - // }, - // }, - // }, - // { - // input: "sum without (foo) (some_metric)", - // expected: &AggregateExpr{ - // Op: SUM, - // Without: true, - // Expr: &VectorSelector{ - // Name: "some_metric", - // LabelMatchers: []*labels.Matcher{ - // MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "some_metric"), - // }, - // PosRange: posrange.PositionRange{ - // Start: 19, - // End: 30, - // }, - // }, - // Grouping: []string{"foo"}, - // PosRange: posrange.PositionRange{ - // Start: 0, - // End: 31, - // }, - // }, - // }, - // { - // input: "sum (some_metric) without (foo)", - // expected: &AggregateExpr{ - // Op: SUM, - // Without: true, - // Expr: &VectorSelector{ - // Name: "some_metric", - // LabelMatchers: []*labels.Matcher{ - // MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "some_metric"), - // }, - // PosRange: posrange.PositionRange{ - // Start: 5, - // End: 16, - // }, - // }, - // Grouping: []string{"foo"}, - // PosRange: posrange.PositionRange{ - // Start: 0, - // End: 31, - // }, - // }, - // }, - // { - // input: "stddev(some_metric)", - // expected: &AggregateExpr{ - // Op: STDDEV, - // Expr: &VectorSelector{ - // Name: "some_metric", - // LabelMatchers: []*labels.Matcher{ - // MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "some_metric"), - // }, - // PosRange: posrange.PositionRange{ - // Start: 7, - // End: 18, - // }, - // }, - // PosRange: posrange.PositionRange{ - // Start: 0, - // End: 19, - // }, - // }, - // }, - // { - // input: "stdvar by (foo)(some_metric)", - // expected: &AggregateExpr{ - // Op: STDVAR, - // Expr: &VectorSelector{ - // Name: "some_metric", - // LabelMatchers: []*labels.Matcher{ - // MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "some_metric"), - // }, - // PosRange: posrange.PositionRange{ - // Start: 16, - // End: 27, - // }, - // }, - // Grouping: []string{"foo"}, - // PosRange: posrange.PositionRange{ - // Start: 0, - // End: 28, - // }, - // }, - // }, - // { - // input: "sum by ()(some_metric)", - // expected: &AggregateExpr{ - // Op: SUM, - // Expr: &VectorSelector{ - // Name: "some_metric", - // LabelMatchers: []*labels.Matcher{ - // MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "some_metric"), - // }, - // PosRange: posrange.PositionRange{ - // Start: 10, - // End: 21, - // }, - // }, - // Grouping: []string{}, - // PosRange: posrange.PositionRange{ - // Start: 0, - // End: 22, - // }, - // }, - // }, - // { - // input: "sum by (foo,bar,)(some_metric)", - // expected: &AggregateExpr{ - // Op: SUM, - // Expr: &VectorSelector{ - // Name: "some_metric", - // LabelMatchers: []*labels.Matcher{ - // MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "some_metric"), - // }, - // PosRange: posrange.PositionRange{ - // Start: 18, - // End: 29, - // }, - // }, - // Grouping: []string{"foo", "bar"}, - // PosRange: posrange.PositionRange{ - // Start: 0, - // End: 30, - // }, - // }, - // }, - // { - // input: "sum by (foo,)(some_metric)", - // expected: &AggregateExpr{ - // Op: SUM, - // Expr: &VectorSelector{ - // Name: "some_metric", - // LabelMatchers: []*labels.Matcher{ - // MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "some_metric"), - // }, - // PosRange: posrange.PositionRange{ - // Start: 14, - // End: 25, - // }, - // }, - // Grouping: []string{"foo"}, - // PosRange: posrange.PositionRange{ - // Start: 0, - // End: 26, - // }, - // }, - // }, - // { - // input: "topk(5, some_metric)", - // expected: &AggregateExpr{ - // Op: TOPK, - // Expr: &VectorSelector{ - // Name: "some_metric", - // LabelMatchers: []*labels.Matcher{ - // MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "some_metric"), - // }, - // PosRange: posrange.PositionRange{ - // Start: 8, - // End: 19, - // }, - // }, - // Param: &NumberLiteral{ - // Val: 5, - // PosRange: posrange.PositionRange{ - // Start: 5, - // End: 6, - // }, - // }, - // PosRange: posrange.PositionRange{ - // Start: 0, - // End: 20, - // }, - // }, - // }, - // { - // input: `count_values("value", some_metric)`, - // expected: &AggregateExpr{ - // Op: COUNT_VALUES, - // Expr: &VectorSelector{ - // Name: "some_metric", - // LabelMatchers: []*labels.Matcher{ - // MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "some_metric"), - // }, - // PosRange: posrange.PositionRange{ - // Start: 22, - // End: 33, - // }, - // }, - // Param: &StringLiteral{ - // Val: "value", - // PosRange: posrange.PositionRange{ - // Start: 13, - // End: 20, - // }, - // }, - // PosRange: posrange.PositionRange{ - // Start: 0, - // End: 34, - // }, - // }, - // }, - // { - // // Test usage of keywords as label names. - // input: "sum without(and, by, avg, count, alert, annotations)(some_metric)", - // expected: &AggregateExpr{ - // Op: SUM, - // Without: true, - // Expr: &VectorSelector{ - // Name: "some_metric", - // LabelMatchers: []*labels.Matcher{ - // MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "some_metric"), - // }, - // PosRange: posrange.PositionRange{ - // Start: 53, - // End: 64, - // }, - // }, - // Grouping: []string{"and", "by", "avg", "count", "alert", "annotations"}, - // PosRange: posrange.PositionRange{ - // Start: 0, - // End: 65, - // }, - // }, - // }, - // { - // input: "sum without(==)(some_metric)", - // fail: true, - // errMsg: "unexpected in grouping opts, expected label", - // }, - // { - // input: "sum without(,)(some_metric)", - // fail: true, - // errMsg: `unexpected "," in grouping opts, expected label`, - // }, - // { - // input: "sum without(foo,,)(some_metric)", - // fail: true, - // errMsg: `unexpected "," in grouping opts, expected label`, - // }, - // { - // input: `sum some_metric by (test)`, - // fail: true, - // errMsg: "unexpected identifier \"some_metric\"", - // }, - // { - // input: `sum (some_metric) by test`, - // fail: true, - // errMsg: "unexpected identifier \"test\" in grouping opts", - // }, - // { - // input: `sum (some_metric) by test`, - // fail: true, - // errMsg: "unexpected identifier \"test\" in grouping opts", - // }, - // { - // input: `sum () by (test)`, - // fail: true, - // errMsg: "no arguments for aggregate expression provided", - // }, - // { - // input: "MIN keep_common (some_metric)", - // fail: true, - // errMsg: "1:5: parse error: unexpected identifier \"keep_common\"", - // }, - // { - // input: "MIN (some_metric) keep_common", - // fail: true, - // errMsg: `unexpected identifier "keep_common"`, - // }, - // { - // input: `sum (some_metric) without (test) by (test)`, - // fail: true, - // errMsg: "unexpected ", - // }, - // { - // input: `sum without (test) (some_metric) by (test)`, - // fail: true, - // errMsg: "unexpected ", - // }, - // { - // input: `topk(some_metric)`, - // fail: true, - // errMsg: "wrong number of arguments for aggregate expression provided, expected 2, got 1", - // }, - // { - // input: `topk(some_metric,)`, - // fail: true, - // errMsg: "trailing commas not allowed in function call args", - // }, - // { - // input: `topk(some_metric, other_metric)`, - // fail: true, - // errMsg: "1:6: parse error: expected type scalar in aggregation parameter, got instant vector", - // }, - // { - // input: `count_values(5, other_metric)`, - // fail: true, - // errMsg: "1:14: parse error: expected type string in aggregation parameter, got scalar", - // }, - // { - // input: `rate(some_metric[5m]) @ 1234`, - // fail: true, - // errMsg: "1:1: parse error: @ modifier must be preceded by an instant vector selector or range vector selector or a subquery", - // }, - // // Test function calls. - // { - // input: "time()", - // expected: &Call{ - // Func: MustGetFunction("time"), - // Args: Expressions{}, - // PosRange: posrange.PositionRange{ - // Start: 0, - // End: 6, - // }, - // }, - // }, - // { - // input: `floor(some_metric{foo!="bar"})`, - // expected: &Call{ - // Func: MustGetFunction("floor"), - // Args: Expressions{ - // &VectorSelector{ - // Name: "some_metric", - // LabelMatchers: []*labels.Matcher{ - // MustLabelMatcher(labels.MatchNotEqual, "foo", "bar"), - // MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "some_metric"), - // }, - // PosRange: posrange.PositionRange{ - // Start: 6, - // End: 29, - // }, - // }, - // }, - // PosRange: posrange.PositionRange{ - // Start: 0, - // End: 30, - // }, - // }, - // }, - // { - // input: "rate(some_metric[5m])", - // expected: &Call{ - // Func: MustGetFunction("rate"), - // Args: Expressions{ - // &MatrixSelector{ - // VectorSelector: &VectorSelector{ - // Name: "some_metric", - // LabelMatchers: []*labels.Matcher{ - // MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "some_metric"), - // }, - // PosRange: posrange.PositionRange{ - // Start: 5, - // End: 16, - // }, - // }, - // Range: 5 * time.Minute, - // EndPos: 20, - // }, - // }, - // PosRange: posrange.PositionRange{ - // Start: 0, - // End: 21, - // }, - // }, - // }, - // { - // input: "round(some_metric)", - // expected: &Call{ - // Func: MustGetFunction("round"), - // Args: Expressions{ - // &VectorSelector{ - // Name: "some_metric", - // LabelMatchers: []*labels.Matcher{ - // MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "some_metric"), - // }, - // PosRange: posrange.PositionRange{ - // Start: 6, - // End: 17, - // }, - // }, - // }, - // PosRange: posrange.PositionRange{ - // Start: 0, - // End: 18, - // }, - // }, - // }, - // { - // input: "round(some_metric, 5)", - // expected: &Call{ - // Func: MustGetFunction("round"), - // Args: Expressions{ - // &VectorSelector{ - // Name: "some_metric", - // LabelMatchers: []*labels.Matcher{ - // MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "some_metric"), - // }, - // PosRange: posrange.PositionRange{ - // Start: 6, - // End: 17, - // }, - // }, - // &NumberLiteral{ - // Val: 5, - // PosRange: posrange.PositionRange{ - // Start: 19, - // End: 20, - // }, - // }, - // }, - // PosRange: posrange.PositionRange{ - // Start: 0, - // End: 21, - // }, - // }, - // }, - // { - // input: "floor()", - // fail: true, - // errMsg: "expected 1 argument(s) in call to \"floor\", got 0", - // }, - // { - // input: "floor(some_metric, other_metric)", - // fail: true, - // errMsg: "expected 1 argument(s) in call to \"floor\", got 2", - // }, - // { - // input: "floor(some_metric, 1)", - // fail: true, - // errMsg: "expected 1 argument(s) in call to \"floor\", got 2", - // }, - // { - // input: "floor(1)", - // fail: true, - // errMsg: "expected type instant vector in call to function \"floor\", got scalar", - // }, - // { - // input: "hour(some_metric, some_metric, some_metric)", - // fail: true, - // errMsg: "expected at most 1 argument(s) in call to \"hour\", got 3", - // }, - // { - // input: "time(some_metric)", - // fail: true, - // errMsg: "expected 0 argument(s) in call to \"time\", got 1", - // }, - // { - // input: "non_existent_function_far_bar()", - // fail: true, - // errMsg: "unknown function with name \"non_existent_function_far_bar\"", - // }, - // { - // input: "rate(some_metric)", - // fail: true, - // errMsg: "expected type range vector in call to function \"rate\", got instant vector", - // }, - // { - // input: "label_replace(a, `b`, `c\xff`, `d`, `.*`)", - // fail: true, - // errMsg: "1:23: parse error: invalid UTF-8 rune", - // }, - // // Fuzzing regression tests. - // { - // input: "-=", - // fail: true, - // errMsg: `unexpected "="`, - // }, - // { - // input: "++-++-+-+-<", - // fail: true, - // errMsg: `unexpected `, - // }, - // { - // input: "e-+=/(0)", - // fail: true, - // errMsg: `unexpected "="`, - // }, - // { - // input: "a>b()", - // fail: true, - // errMsg: `unknown function`, - // }, - // { - // input: "rate(avg)", - // fail: true, - // errMsg: `expected type range vector`, - // }, - // { - // // This is testing that we are not re-rendering the expression string for each error, which would timeout. - // input: "(" + strings.Repeat("-{}-1", 10000) + ")" + strings.Repeat("[1m:]", 1000), - // fail: true, - // errMsg: `1:3: parse error: vector selector must contain at least one non-empty matcher`, - // }, - // { - // input: "sum(sum)", - // expected: &AggregateExpr{ - // Op: SUM, - // Expr: &VectorSelector{ - // Name: "sum", - // LabelMatchers: []*labels.Matcher{ - // MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "sum"), - // }, - // PosRange: posrange.PositionRange{ - // Start: 4, - // End: 7, - // }, - // }, - // PosRange: posrange.PositionRange{ - // Start: 0, - // End: 8, - // }, - // }, - // }, - // { - // input: "a + sum", - // expected: &BinaryExpr{ - // Op: ADD, - // LHS: &VectorSelector{ - // Name: "a", - // LabelMatchers: []*labels.Matcher{ - // MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "a"), - // }, - // PosRange: posrange.PositionRange{ - // Start: 0, - // End: 1, - // }, - // }, - // RHS: &VectorSelector{ - // Name: "sum", - // LabelMatchers: []*labels.Matcher{ - // MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "sum"), - // }, - // PosRange: posrange.PositionRange{ - // Start: 4, - // End: 7, - // }, - // }, - // VectorMatching: &VectorMatching{}, - // }, - // }, - // // String quoting and escape sequence interpretation tests. - // { - // input: `"double-quoted string \" with escaped quote"`, - // expected: &StringLiteral{ - // Val: "double-quoted string \" with escaped quote", - // PosRange: posrange.PositionRange{Start: 0, End: 44}, - // }, - // }, - // { - // input: `'single-quoted string \' with escaped quote'`, - // expected: &StringLiteral{ - // Val: "single-quoted string ' with escaped quote", - // PosRange: posrange.PositionRange{Start: 0, End: 44}, - // }, - // }, - // { - // input: "`backtick-quoted string`", - // expected: &StringLiteral{ - // Val: "backtick-quoted string", - // PosRange: posrange.PositionRange{Start: 0, End: 24}, - // }, - // }, - // { - // input: `"\a\b\f\n\r\t\v\\\" - \xFF\377\u1234\U00010111\U0001011111☺"`, - // expected: &StringLiteral{ - // Val: "\a\b\f\n\r\t\v\\\" - \xFF\377\u1234\U00010111\U0001011111☺", - // PosRange: posrange.PositionRange{Start: 0, End: 62}, - // }, - // }, - // { - // input: `'\a\b\f\n\r\t\v\\\' - \xFF\377\u1234\U00010111\U0001011111☺'`, - // expected: &StringLiteral{ - // Val: "\a\b\f\n\r\t\v\\' - \xFF\377\u1234\U00010111\U0001011111☺", - // PosRange: posrange.PositionRange{Start: 0, End: 62}, - // }, - // }, - // { - // input: "`" + `\a\b\f\n\r\t\v\\\"\' - \xFF\377\u1234\U00010111\U0001011111☺` + "`", - // expected: &StringLiteral{ - // Val: `\a\b\f\n\r\t\v\\\"\' - \xFF\377\u1234\U00010111\U0001011111☺`, - // PosRange: posrange.PositionRange{Start: 0, End: 64}, - // }, - // }, - // { - // input: "`\\``", - // fail: true, - // errMsg: "unterminated raw string", - // }, - // { - // input: `"\`, - // fail: true, - // errMsg: "escape sequence not terminated", - // }, - // { - // input: `"\c"`, - // fail: true, - // errMsg: "unknown escape sequence U+0063 'c'", - // }, - // { - // input: `"\x."`, - // fail: true, - // errMsg: "illegal character U+002E '.' in escape sequence", - // }, - // // Subquery. - // { - // input: `foo{bar="baz"}[10m:6s]`, - // expected: &SubqueryExpr{ - // Expr: &VectorSelector{ - // Name: "foo", - // LabelMatchers: []*labels.Matcher{ - // MustLabelMatcher(labels.MatchEqual, "bar", "baz"), - // MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "foo"), - // }, - // PosRange: posrange.PositionRange{ - // Start: 0, - // End: 14, - // }, - // }, - // Range: 10 * time.Minute, - // Step: 6 * time.Second, - // EndPos: 22, - // }, - // }, - // { - // input: `foo{bar="baz"}[10m5s:1h6ms]`, - // expected: &SubqueryExpr{ - // Expr: &VectorSelector{ - // Name: "foo", - // LabelMatchers: []*labels.Matcher{ - // MustLabelMatcher(labels.MatchEqual, "bar", "baz"), - // MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "foo"), - // }, - // PosRange: posrange.PositionRange{ - // Start: 0, - // End: 14, - // }, - // }, - // Range: 10*time.Minute + 5*time.Second, - // Step: time.Hour + 6*time.Millisecond, - // EndPos: 27, - // }, - // }, - // { - // input: `foo[10m:]`, - // expected: &SubqueryExpr{ - // Expr: &VectorSelector{ - // Name: "foo", - // LabelMatchers: []*labels.Matcher{ - // MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "foo"), - // }, - // PosRange: posrange.PositionRange{ - // Start: 0, - // End: 3, - // }, - // }, - // Range: 10 * time.Minute, - // EndPos: 9, - // }, - // }, - // { - // input: `min_over_time(rate(foo{bar="baz"}[2s])[5m:5s])`, - // expected: &Call{ - // Func: MustGetFunction("min_over_time"), - // Args: Expressions{ - // &SubqueryExpr{ - // Expr: &Call{ - // Func: MustGetFunction("rate"), - // Args: Expressions{ - // &MatrixSelector{ - // VectorSelector: &VectorSelector{ - // Name: "foo", - // LabelMatchers: []*labels.Matcher{ - // MustLabelMatcher(labels.MatchEqual, "bar", "baz"), - // MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "foo"), - // }, - // PosRange: posrange.PositionRange{ - // Start: 19, - // End: 33, - // }, - // }, - // Range: 2 * time.Second, - // EndPos: 37, - // }, - // }, - // PosRange: posrange.PositionRange{ - // Start: 14, - // End: 38, - // }, - // }, - // Range: 5 * time.Minute, - // Step: 5 * time.Second, - - // EndPos: 45, - // }, - // }, - // PosRange: posrange.PositionRange{ - // Start: 0, - // End: 46, - // }, - // }, - // }, - // { - // input: `min_over_time(rate(foo{bar="baz"}[2s])[5m:])[4m:3s]`, - // expected: &SubqueryExpr{ - // Expr: &Call{ - // Func: MustGetFunction("min_over_time"), - // Args: Expressions{ - // &SubqueryExpr{ - // Expr: &Call{ - // Func: MustGetFunction("rate"), - // Args: Expressions{ - // &MatrixSelector{ - // VectorSelector: &VectorSelector{ - // Name: "foo", - // LabelMatchers: []*labels.Matcher{ - // MustLabelMatcher(labels.MatchEqual, "bar", "baz"), - // MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "foo"), - // }, - // PosRange: posrange.PositionRange{ - // Start: 19, - // End: 33, - // }, - // }, - // Range: 2 * time.Second, - // EndPos: 37, - // }, - // }, - // PosRange: posrange.PositionRange{ - // Start: 14, - // End: 38, - // }, - // }, - // Range: 5 * time.Minute, - // EndPos: 43, - // }, - // }, - // PosRange: posrange.PositionRange{ - // Start: 0, - // End: 44, - // }, - // }, - // Range: 4 * time.Minute, - // Step: 3 * time.Second, - // EndPos: 51, - // }, - // }, - // { - // input: `min_over_time(rate(foo{bar="baz"}[2s])[5m:] offset 4m)[4m:3s]`, - // expected: &SubqueryExpr{ - // Expr: &Call{ - // Func: MustGetFunction("min_over_time"), - // Args: Expressions{ - // &SubqueryExpr{ - // Expr: &Call{ - // Func: MustGetFunction("rate"), - // Args: Expressions{ - // &MatrixSelector{ - // VectorSelector: &VectorSelector{ - // Name: "foo", - // LabelMatchers: []*labels.Matcher{ - // MustLabelMatcher(labels.MatchEqual, "bar", "baz"), - // MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "foo"), - // }, - // PosRange: posrange.PositionRange{ - // Start: 19, - // End: 33, - // }, - // }, - // Range: 2 * time.Second, - // EndPos: 37, - // }, - // }, - // PosRange: posrange.PositionRange{ - // Start: 14, - // End: 38, - // }, - // }, - // Range: 5 * time.Minute, - // OriginalOffset: 4 * time.Minute, - // EndPos: 53, - // }, - // }, - // PosRange: posrange.PositionRange{ - // Start: 0, - // End: 54, - // }, - // }, - // Range: 4 * time.Minute, - // Step: 3 * time.Second, - // EndPos: 61, - // }, - // }, - // { - // input: `min_over_time(rate(foo{bar="baz"}[2s])[5m:] @ 1603775091)[4m:3s]`, - // expected: &SubqueryExpr{ - // Expr: &Call{ - // Func: MustGetFunction("min_over_time"), - // Args: Expressions{ - // &SubqueryExpr{ - // Expr: &Call{ - // Func: MustGetFunction("rate"), - // Args: Expressions{ - // &MatrixSelector{ - // VectorSelector: &VectorSelector{ - // Name: "foo", - // LabelMatchers: []*labels.Matcher{ - // MustLabelMatcher(labels.MatchEqual, "bar", "baz"), - // MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "foo"), - // }, - // PosRange: posrange.PositionRange{ - // Start: 19, - // End: 33, - // }, - // }, - // Range: 2 * time.Second, - // EndPos: 37, - // }, - // }, - // PosRange: posrange.PositionRange{ - // Start: 14, - // End: 38, - // }, - // }, - // Range: 5 * time.Minute, - // Timestamp: makeInt64Pointer(1603775091000), - // EndPos: 56, - // }, - // }, - // PosRange: posrange.PositionRange{ - // Start: 0, - // End: 57, - // }, - // }, - // Range: 4 * time.Minute, - // Step: 3 * time.Second, - // EndPos: 64, - // }, - // }, - // { - // input: `min_over_time(rate(foo{bar="baz"}[2s])[5m:] @ -160377509)[4m:3s]`, - // expected: &SubqueryExpr{ - // Expr: &Call{ - // Func: MustGetFunction("min_over_time"), - // Args: Expressions{ - // &SubqueryExpr{ - // Expr: &Call{ - // Func: MustGetFunction("rate"), - // Args: Expressions{ - // &MatrixSelector{ - // VectorSelector: &VectorSelector{ - // Name: "foo", - // LabelMatchers: []*labels.Matcher{ - // MustLabelMatcher(labels.MatchEqual, "bar", "baz"), - // MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "foo"), - // }, - // PosRange: posrange.PositionRange{ - // Start: 19, - // End: 33, - // }, - // }, - // Range: 2 * time.Second, - // EndPos: 37, - // }, - // }, - // PosRange: posrange.PositionRange{ - // Start: 14, - // End: 38, - // }, - // }, - // Range: 5 * time.Minute, - // Timestamp: makeInt64Pointer(-160377509000), - // EndPos: 56, - // }, - // }, - // PosRange: posrange.PositionRange{ - // Start: 0, - // End: 57, - // }, - // }, - // Range: 4 * time.Minute, - // Step: 3 * time.Second, - // EndPos: 64, - // }, - // }, - // { - // input: "sum without(and, by, avg, count, alert, annotations)(some_metric) [30m:10s]", - // expected: &SubqueryExpr{ - // Expr: &AggregateExpr{ - // Op: SUM, - // Without: true, - // Expr: &VectorSelector{ - // Name: "some_metric", - // LabelMatchers: []*labels.Matcher{ - // MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "some_metric"), - // }, - // PosRange: posrange.PositionRange{ - // Start: 53, - // End: 64, - // }, - // }, - // Grouping: []string{"and", "by", "avg", "count", "alert", "annotations"}, - // PosRange: posrange.PositionRange{ - // Start: 0, - // End: 65, - // }, - // }, - // Range: 30 * time.Minute, - // Step: 10 * time.Second, - // EndPos: 75, - // }, - // }, - // { - // input: `some_metric OFFSET 1m [10m:5s]`, - // expected: &SubqueryExpr{ - // Expr: &VectorSelector{ - // Name: "some_metric", - // LabelMatchers: []*labels.Matcher{ - // MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "some_metric"), - // }, - // PosRange: posrange.PositionRange{ - // Start: 0, - // End: 21, - // }, - // OriginalOffset: 1 * time.Minute, - // }, - // Range: 10 * time.Minute, - // Step: 5 * time.Second, - // EndPos: 30, - // }, - // }, - // { - // input: `some_metric @ 123 [10m:5s]`, - // expected: &SubqueryExpr{ - // Expr: &VectorSelector{ - // Name: "some_metric", - // LabelMatchers: []*labels.Matcher{ - // MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "some_metric"), - // }, - // PosRange: posrange.PositionRange{ - // Start: 0, - // End: 17, - // }, - // Timestamp: makeInt64Pointer(123000), - // }, - // Range: 10 * time.Minute, - // Step: 5 * time.Second, - // EndPos: 26, - // }, - // }, - // { - // input: `some_metric @ 123 offset 1m [10m:5s]`, - // expected: &SubqueryExpr{ - // Expr: &VectorSelector{ - // Name: "some_metric", - // LabelMatchers: []*labels.Matcher{ - // MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "some_metric"), - // }, - // PosRange: posrange.PositionRange{ - // Start: 0, - // End: 27, - // }, - // Timestamp: makeInt64Pointer(123000), - // OriginalOffset: 1 * time.Minute, - // }, - // Range: 10 * time.Minute, - // Step: 5 * time.Second, - // EndPos: 36, - // }, - // }, - // { - // input: `some_metric offset 1m @ 123 [10m:5s]`, - // expected: &SubqueryExpr{ - // Expr: &VectorSelector{ - // Name: "some_metric", - // LabelMatchers: []*labels.Matcher{ - // MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "some_metric"), - // }, - // PosRange: posrange.PositionRange{ - // Start: 0, - // End: 27, - // }, - // Timestamp: makeInt64Pointer(123000), - // OriginalOffset: 1 * time.Minute, - // }, - // Range: 10 * time.Minute, - // Step: 5 * time.Second, - // EndPos: 36, - // }, - // }, - // { - // input: `some_metric[10m:5s] offset 1m @ 123`, - // expected: &SubqueryExpr{ - // Expr: &VectorSelector{ - // Name: "some_metric", - // LabelMatchers: []*labels.Matcher{ - // MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "some_metric"), - // }, - // PosRange: posrange.PositionRange{ - // Start: 0, - // End: 11, - // }, - // }, - // Timestamp: makeInt64Pointer(123000), - // OriginalOffset: 1 * time.Minute, - // Range: 10 * time.Minute, - // Step: 5 * time.Second, - // EndPos: 35, - // }, - // }, - // { - // input: `(foo + bar{nm="val"})[5m:]`, - // expected: &SubqueryExpr{ - // Expr: &ParenExpr{ - // Expr: &BinaryExpr{ - // Op: ADD, - // VectorMatching: &VectorMatching{ - // Card: CardOneToOne, - // }, - // LHS: &VectorSelector{ - // Name: "foo", - // LabelMatchers: []*labels.Matcher{ - // MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "foo"), - // }, - // PosRange: posrange.PositionRange{ - // Start: 1, - // End: 4, - // }, - // }, - // RHS: &VectorSelector{ - // Name: "bar", - // LabelMatchers: []*labels.Matcher{ - // MustLabelMatcher(labels.MatchEqual, "nm", "val"), - // MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "bar"), - // }, - // PosRange: posrange.PositionRange{ - // Start: 7, - // End: 20, - // }, - // }, - // }, - // PosRange: posrange.PositionRange{ - // Start: 0, - // End: 21, - // }, - // }, - // Range: 5 * time.Minute, - // EndPos: 26, - // }, - // }, - // { - // input: `(foo + bar{nm="val"})[5m:] offset 10m`, - // expected: &SubqueryExpr{ - // Expr: &ParenExpr{ - // Expr: &BinaryExpr{ - // Op: ADD, - // VectorMatching: &VectorMatching{ - // Card: CardOneToOne, - // }, - // LHS: &VectorSelector{ - // Name: "foo", - // LabelMatchers: []*labels.Matcher{ - // MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "foo"), - // }, - // PosRange: posrange.PositionRange{ - // Start: 1, - // End: 4, - // }, - // }, - // RHS: &VectorSelector{ - // Name: "bar", - // LabelMatchers: []*labels.Matcher{ - // MustLabelMatcher(labels.MatchEqual, "nm", "val"), - // MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "bar"), - // }, - // PosRange: posrange.PositionRange{ - // Start: 7, - // End: 20, - // }, - // }, - // }, - // PosRange: posrange.PositionRange{ - // Start: 0, - // End: 21, - // }, - // }, - // Range: 5 * time.Minute, - // OriginalOffset: 10 * time.Minute, - // EndPos: 37, - // }, - // }, - // { - // input: `(foo + bar{nm="val"} @ 1234)[5m:] @ 1603775019`, - // expected: &SubqueryExpr{ - // Expr: &ParenExpr{ - // Expr: &BinaryExpr{ - // Op: ADD, - // VectorMatching: &VectorMatching{ - // Card: CardOneToOne, - // }, - // LHS: &VectorSelector{ - // Name: "foo", - // LabelMatchers: []*labels.Matcher{ - // MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "foo"), - // }, - // PosRange: posrange.PositionRange{ - // Start: 1, - // End: 4, - // }, - // }, - // RHS: &VectorSelector{ - // Name: "bar", - // LabelMatchers: []*labels.Matcher{ - // MustLabelMatcher(labels.MatchEqual, "nm", "val"), - // MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "bar"), - // }, - // Timestamp: makeInt64Pointer(1234000), - // PosRange: posrange.PositionRange{ - // Start: 7, - // End: 27, - // }, - // }, - // }, - // PosRange: posrange.PositionRange{ - // Start: 0, - // End: 28, - // }, - // }, - // Range: 5 * time.Minute, - // Timestamp: makeInt64Pointer(1603775019000), - // EndPos: 46, - // }, - // }, - // { - // input: "test[5d] OFFSET 10s [10m:5s]", - // fail: true, - // errMsg: "1:1: parse error: subquery is only allowed on instant vector, got matrix", - // }, - // { - // input: `(foo + bar{nm="val"})[5m:][10m:5s]`, - // fail: true, - // errMsg: `1:1: parse error: subquery is only allowed on instant vector, got matrix`, - // }, - // { - // input: "rate(food[1m])[1h] offset 1h", - // fail: true, - // errMsg: `1:15: parse error: ranges only allowed for vector selectors`, - // }, - // { - // input: "rate(food[1m])[1h] @ 100", - // fail: true, - // errMsg: `1:15: parse error: ranges only allowed for vector selectors`, - // }, - // // Preprocessors. - // { - // input: `foo @ start()`, - // expected: &VectorSelector{ - // Name: "foo", - // StartOrEnd: START, - // LabelMatchers: []*labels.Matcher{ - // MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "foo"), - // }, - // PosRange: posrange.PositionRange{ - // Start: 0, - // End: 13, - // }, - // }, - // }, - // { - // input: `foo @ end()`, - // expected: &VectorSelector{ - // Name: "foo", - // StartOrEnd: END, - // LabelMatchers: []*labels.Matcher{ - // MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "foo"), - // }, - // PosRange: posrange.PositionRange{ - // Start: 0, - // End: 11, - // }, - // }, - // }, - // { - // input: `test[5y] @ start()`, - // expected: &MatrixSelector{ - // VectorSelector: &VectorSelector{ - // Name: "test", - // StartOrEnd: START, - // LabelMatchers: []*labels.Matcher{ - // MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "test"), - // }, - // PosRange: posrange.PositionRange{ - // Start: 0, - // End: 4, - // }, - // }, - // Range: 5 * 365 * 24 * time.Hour, - // EndPos: 18, - // }, - // }, - // { - // input: `test[5y] @ end()`, - // expected: &MatrixSelector{ - // VectorSelector: &VectorSelector{ - // Name: "test", - // StartOrEnd: END, - // LabelMatchers: []*labels.Matcher{ - // MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "test"), - // }, - // PosRange: posrange.PositionRange{ - // Start: 0, - // End: 4, - // }, - // }, - // Range: 5 * 365 * 24 * time.Hour, - // EndPos: 16, - // }, - // }, - // { - // input: `foo[10m:6s] @ start()`, - // expected: &SubqueryExpr{ - // Expr: &VectorSelector{ - // Name: "foo", - // LabelMatchers: []*labels.Matcher{ - // MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "foo"), - // }, - // PosRange: posrange.PositionRange{ - // Start: 0, - // End: 3, - // }, - // }, - // Range: 10 * time.Minute, - // Step: 6 * time.Second, - // StartOrEnd: START, - // EndPos: 21, - // }, - // }, - // { - // input: `foo[10m:6s] @ end()`, - // expected: &SubqueryExpr{ - // Expr: &VectorSelector{ - // Name: "foo", - // LabelMatchers: []*labels.Matcher{ - // MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "foo"), - // }, - // PosRange: posrange.PositionRange{ - // Start: 0, - // End: 3, - // }, - // }, - // Range: 10 * time.Minute, - // Step: 6 * time.Second, - // StartOrEnd: END, - // EndPos: 19, - // }, - // }, - // { - // input: `start()`, - // fail: true, - // errMsg: `1:6: parse error: unexpected "("`, - // }, - // { - // input: `end()`, - // fail: true, - // errMsg: `1:4: parse error: unexpected "("`, - // }, - // // Check that start and end functions do not mask metrics. - // { - // input: `start`, - // expected: &VectorSelector{ - // Name: "start", - // LabelMatchers: []*labels.Matcher{ - // MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "start"), - // }, - // PosRange: posrange.PositionRange{ - // Start: 0, - // End: 5, - // }, - // }, - // }, - // { - // input: `end`, - // expected: &VectorSelector{ - // Name: "end", - // LabelMatchers: []*labels.Matcher{ - // MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "end"), - // }, - // PosRange: posrange.PositionRange{ - // Start: 0, - // End: 3, - // }, - // }, - // }, - // { - // input: `start{end="foo"}`, - // expected: &VectorSelector{ - // Name: "start", - // LabelMatchers: []*labels.Matcher{ - // MustLabelMatcher(labels.MatchEqual, "end", "foo"), - // MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "start"), - // }, - // PosRange: posrange.PositionRange{ - // Start: 0, - // End: 16, - // }, - // }, - // }, - // { - // input: `end{start="foo"}`, - // expected: &VectorSelector{ - // Name: "end", - // LabelMatchers: []*labels.Matcher{ - // MustLabelMatcher(labels.MatchEqual, "start", "foo"), - // MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "end"), - // }, - // PosRange: posrange.PositionRange{ - // Start: 0, - // End: 16, - // }, - // }, - // }, - // { - // input: `foo unless on(start) bar`, - // expected: &BinaryExpr{ - // Op: LUNLESS, - // LHS: &VectorSelector{ - // Name: "foo", - // LabelMatchers: []*labels.Matcher{ - // MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "foo"), - // }, - // PosRange: posrange.PositionRange{ - // Start: 0, - // End: 3, - // }, - // }, - // RHS: &VectorSelector{ - // Name: "bar", - // LabelMatchers: []*labels.Matcher{ - // MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "bar"), - // }, - // PosRange: posrange.PositionRange{ - // Start: 21, - // End: 24, - // }, - // }, - // VectorMatching: &VectorMatching{ - // Card: CardManyToMany, - // MatchingLabels: []string{"start"}, - // On: true, - // }, - // }, - // }, - // { - // input: `foo unless on(end) bar`, - // expected: &BinaryExpr{ - // Op: LUNLESS, - // LHS: &VectorSelector{ - // Name: "foo", - // LabelMatchers: []*labels.Matcher{ - // MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "foo"), - // }, - // PosRange: posrange.PositionRange{ - // Start: 0, - // End: 3, - // }, - // }, - // RHS: &VectorSelector{ - // Name: "bar", - // LabelMatchers: []*labels.Matcher{ - // MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "bar"), - // }, - // PosRange: posrange.PositionRange{ - // Start: 19, - // End: 22, - // }, - // }, - // VectorMatching: &VectorMatching{ - // Card: CardManyToMany, - // MatchingLabels: []string{"end"}, - // On: true, - // }, - // }, - // }, + EndPos: 45, + }, + }, + PosRange: posrange.PositionRange{ + Start: 0, + End: 46, + }, + }, + }, + { + input: `min_over_time(rate(foo{bar="baz"}[2s])[5m:])[4m:3s]`, + expected: &SubqueryExpr{ + Expr: &Call{ + Func: MustGetFunction("min_over_time"), + Args: Expressions{ + &SubqueryExpr{ + Expr: &Call{ + Func: MustGetFunction("rate"), + Args: Expressions{ + &MatrixSelector{ + VectorSelector: &VectorSelector{ + Name: "foo", + LabelMatchers: []*labels.Matcher{ + MustLabelMatcher(labels.MatchEqual, "bar", "baz"), + MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "foo"), + }, + PosRange: posrange.PositionRange{ + Start: 19, + End: 33, + }, + }, + Range: 2 * time.Second, + EndPos: 37, + }, + }, + PosRange: posrange.PositionRange{ + Start: 14, + End: 38, + }, + }, + Range: 5 * time.Minute, + EndPos: 43, + }, + }, + PosRange: posrange.PositionRange{ + Start: 0, + End: 44, + }, + }, + Range: 4 * time.Minute, + Step: 3 * time.Second, + EndPos: 51, + }, + }, + { + input: `min_over_time(rate(foo{bar="baz"}[2s])[5m:] offset 4m)[4m:3s]`, + expected: &SubqueryExpr{ + Expr: &Call{ + Func: MustGetFunction("min_over_time"), + Args: Expressions{ + &SubqueryExpr{ + Expr: &Call{ + Func: MustGetFunction("rate"), + Args: Expressions{ + &MatrixSelector{ + VectorSelector: &VectorSelector{ + Name: "foo", + LabelMatchers: []*labels.Matcher{ + MustLabelMatcher(labels.MatchEqual, "bar", "baz"), + MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "foo"), + }, + PosRange: posrange.PositionRange{ + Start: 19, + End: 33, + }, + }, + Range: 2 * time.Second, + EndPos: 37, + }, + }, + PosRange: posrange.PositionRange{ + Start: 14, + End: 38, + }, + }, + Range: 5 * time.Minute, + OriginalOffset: 4 * time.Minute, + EndPos: 53, + }, + }, + PosRange: posrange.PositionRange{ + Start: 0, + End: 54, + }, + }, + Range: 4 * time.Minute, + Step: 3 * time.Second, + EndPos: 61, + }, + }, + { + input: `min_over_time(rate(foo{bar="baz"}[2s])[5m:] @ 1603775091)[4m:3s]`, + expected: &SubqueryExpr{ + Expr: &Call{ + Func: MustGetFunction("min_over_time"), + Args: Expressions{ + &SubqueryExpr{ + Expr: &Call{ + Func: MustGetFunction("rate"), + Args: Expressions{ + &MatrixSelector{ + VectorSelector: &VectorSelector{ + Name: "foo", + LabelMatchers: []*labels.Matcher{ + MustLabelMatcher(labels.MatchEqual, "bar", "baz"), + MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "foo"), + }, + PosRange: posrange.PositionRange{ + Start: 19, + End: 33, + }, + }, + Range: 2 * time.Second, + EndPos: 37, + }, + }, + PosRange: posrange.PositionRange{ + Start: 14, + End: 38, + }, + }, + Range: 5 * time.Minute, + Timestamp: makeInt64Pointer(1603775091000), + EndPos: 56, + }, + }, + PosRange: posrange.PositionRange{ + Start: 0, + End: 57, + }, + }, + Range: 4 * time.Minute, + Step: 3 * time.Second, + EndPos: 64, + }, + }, + { + input: `min_over_time(rate(foo{bar="baz"}[2s])[5m:] @ -160377509)[4m:3s]`, + expected: &SubqueryExpr{ + Expr: &Call{ + Func: MustGetFunction("min_over_time"), + Args: Expressions{ + &SubqueryExpr{ + Expr: &Call{ + Func: MustGetFunction("rate"), + Args: Expressions{ + &MatrixSelector{ + VectorSelector: &VectorSelector{ + Name: "foo", + LabelMatchers: []*labels.Matcher{ + MustLabelMatcher(labels.MatchEqual, "bar", "baz"), + MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "foo"), + }, + PosRange: posrange.PositionRange{ + Start: 19, + End: 33, + }, + }, + Range: 2 * time.Second, + EndPos: 37, + }, + }, + PosRange: posrange.PositionRange{ + Start: 14, + End: 38, + }, + }, + Range: 5 * time.Minute, + Timestamp: makeInt64Pointer(-160377509000), + EndPos: 56, + }, + }, + PosRange: posrange.PositionRange{ + Start: 0, + End: 57, + }, + }, + Range: 4 * time.Minute, + Step: 3 * time.Second, + EndPos: 64, + }, + }, + { + input: "sum without(and, by, avg, count, alert, annotations)(some_metric) [30m:10s]", + expected: &SubqueryExpr{ + Expr: &AggregateExpr{ + Op: SUM, + Without: true, + Expr: &VectorSelector{ + Name: "some_metric", + LabelMatchers: []*labels.Matcher{ + MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "some_metric"), + }, + PosRange: posrange.PositionRange{ + Start: 53, + End: 64, + }, + }, + Grouping: []string{"and", "by", "avg", "count", "alert", "annotations"}, + PosRange: posrange.PositionRange{ + Start: 0, + End: 65, + }, + }, + Range: 30 * time.Minute, + Step: 10 * time.Second, + EndPos: 75, + }, + }, + { + input: `some_metric OFFSET 1m [10m:5s]`, + expected: &SubqueryExpr{ + Expr: &VectorSelector{ + Name: "some_metric", + LabelMatchers: []*labels.Matcher{ + MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "some_metric"), + }, + PosRange: posrange.PositionRange{ + Start: 0, + End: 21, + }, + OriginalOffset: 1 * time.Minute, + }, + Range: 10 * time.Minute, + Step: 5 * time.Second, + EndPos: 30, + }, + }, + { + input: `some_metric @ 123 [10m:5s]`, + expected: &SubqueryExpr{ + Expr: &VectorSelector{ + Name: "some_metric", + LabelMatchers: []*labels.Matcher{ + MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "some_metric"), + }, + PosRange: posrange.PositionRange{ + Start: 0, + End: 17, + }, + Timestamp: makeInt64Pointer(123000), + }, + Range: 10 * time.Minute, + Step: 5 * time.Second, + EndPos: 26, + }, + }, + { + input: `some_metric @ 123 offset 1m [10m:5s]`, + expected: &SubqueryExpr{ + Expr: &VectorSelector{ + Name: "some_metric", + LabelMatchers: []*labels.Matcher{ + MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "some_metric"), + }, + PosRange: posrange.PositionRange{ + Start: 0, + End: 27, + }, + Timestamp: makeInt64Pointer(123000), + OriginalOffset: 1 * time.Minute, + }, + Range: 10 * time.Minute, + Step: 5 * time.Second, + EndPos: 36, + }, + }, + { + input: `some_metric offset 1m @ 123 [10m:5s]`, + expected: &SubqueryExpr{ + Expr: &VectorSelector{ + Name: "some_metric", + LabelMatchers: []*labels.Matcher{ + MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "some_metric"), + }, + PosRange: posrange.PositionRange{ + Start: 0, + End: 27, + }, + Timestamp: makeInt64Pointer(123000), + OriginalOffset: 1 * time.Minute, + }, + Range: 10 * time.Minute, + Step: 5 * time.Second, + EndPos: 36, + }, + }, + { + input: `some_metric[10m:5s] offset 1m @ 123`, + expected: &SubqueryExpr{ + Expr: &VectorSelector{ + Name: "some_metric", + LabelMatchers: []*labels.Matcher{ + MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "some_metric"), + }, + PosRange: posrange.PositionRange{ + Start: 0, + End: 11, + }, + }, + Timestamp: makeInt64Pointer(123000), + OriginalOffset: 1 * time.Minute, + Range: 10 * time.Minute, + Step: 5 * time.Second, + EndPos: 35, + }, + }, + { + input: `(foo + bar{nm="val"})[5m:]`, + expected: &SubqueryExpr{ + Expr: &ParenExpr{ + Expr: &BinaryExpr{ + Op: ADD, + VectorMatching: &VectorMatching{ + Card: CardOneToOne, + }, + LHS: &VectorSelector{ + Name: "foo", + LabelMatchers: []*labels.Matcher{ + MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "foo"), + }, + PosRange: posrange.PositionRange{ + Start: 1, + End: 4, + }, + }, + RHS: &VectorSelector{ + Name: "bar", + LabelMatchers: []*labels.Matcher{ + MustLabelMatcher(labels.MatchEqual, "nm", "val"), + MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "bar"), + }, + PosRange: posrange.PositionRange{ + Start: 7, + End: 20, + }, + }, + }, + PosRange: posrange.PositionRange{ + Start: 0, + End: 21, + }, + }, + Range: 5 * time.Minute, + EndPos: 26, + }, + }, + { + input: `(foo + bar{nm="val"})[5m:] offset 10m`, + expected: &SubqueryExpr{ + Expr: &ParenExpr{ + Expr: &BinaryExpr{ + Op: ADD, + VectorMatching: &VectorMatching{ + Card: CardOneToOne, + }, + LHS: &VectorSelector{ + Name: "foo", + LabelMatchers: []*labels.Matcher{ + MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "foo"), + }, + PosRange: posrange.PositionRange{ + Start: 1, + End: 4, + }, + }, + RHS: &VectorSelector{ + Name: "bar", + LabelMatchers: []*labels.Matcher{ + MustLabelMatcher(labels.MatchEqual, "nm", "val"), + MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "bar"), + }, + PosRange: posrange.PositionRange{ + Start: 7, + End: 20, + }, + }, + }, + PosRange: posrange.PositionRange{ + Start: 0, + End: 21, + }, + }, + Range: 5 * time.Minute, + OriginalOffset: 10 * time.Minute, + EndPos: 37, + }, + }, + { + input: `(foo + bar{nm="val"} @ 1234)[5m:] @ 1603775019`, + expected: &SubqueryExpr{ + Expr: &ParenExpr{ + Expr: &BinaryExpr{ + Op: ADD, + VectorMatching: &VectorMatching{ + Card: CardOneToOne, + }, + LHS: &VectorSelector{ + Name: "foo", + LabelMatchers: []*labels.Matcher{ + MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "foo"), + }, + PosRange: posrange.PositionRange{ + Start: 1, + End: 4, + }, + }, + RHS: &VectorSelector{ + Name: "bar", + LabelMatchers: []*labels.Matcher{ + MustLabelMatcher(labels.MatchEqual, "nm", "val"), + MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "bar"), + }, + Timestamp: makeInt64Pointer(1234000), + PosRange: posrange.PositionRange{ + Start: 7, + End: 27, + }, + }, + }, + PosRange: posrange.PositionRange{ + Start: 0, + End: 28, + }, + }, + Range: 5 * time.Minute, + Timestamp: makeInt64Pointer(1603775019000), + EndPos: 46, + }, + }, + { + input: "test[5d] OFFSET 10s [10m:5s]", + fail: true, + errMsg: "1:1: parse error: subquery is only allowed on instant vector, got matrix", + }, + { + input: `(foo + bar{nm="val"})[5m:][10m:5s]`, + fail: true, + errMsg: `1:1: parse error: subquery is only allowed on instant vector, got matrix`, + }, + { + input: "rate(food[1m])[1h] offset 1h", + fail: true, + errMsg: `1:15: parse error: ranges only allowed for vector selectors`, + }, + { + input: "rate(food[1m])[1h] @ 100", + fail: true, + errMsg: `1:15: parse error: ranges only allowed for vector selectors`, + }, + // Preprocessors. + { + input: `foo @ start()`, + expected: &VectorSelector{ + Name: "foo", + StartOrEnd: START, + LabelMatchers: []*labels.Matcher{ + MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "foo"), + }, + PosRange: posrange.PositionRange{ + Start: 0, + End: 13, + }, + }, + }, + { + input: `foo @ end()`, + expected: &VectorSelector{ + Name: "foo", + StartOrEnd: END, + LabelMatchers: []*labels.Matcher{ + MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "foo"), + }, + PosRange: posrange.PositionRange{ + Start: 0, + End: 11, + }, + }, + }, + { + input: `test[5y] @ start()`, + expected: &MatrixSelector{ + VectorSelector: &VectorSelector{ + Name: "test", + StartOrEnd: START, + LabelMatchers: []*labels.Matcher{ + MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "test"), + }, + PosRange: posrange.PositionRange{ + Start: 0, + End: 4, + }, + }, + Range: 5 * 365 * 24 * time.Hour, + EndPos: 18, + }, + }, + { + input: `test[5y] @ end()`, + expected: &MatrixSelector{ + VectorSelector: &VectorSelector{ + Name: "test", + StartOrEnd: END, + LabelMatchers: []*labels.Matcher{ + MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "test"), + }, + PosRange: posrange.PositionRange{ + Start: 0, + End: 4, + }, + }, + Range: 5 * 365 * 24 * time.Hour, + EndPos: 16, + }, + }, + { + input: `foo[10m:6s] @ start()`, + expected: &SubqueryExpr{ + Expr: &VectorSelector{ + Name: "foo", + LabelMatchers: []*labels.Matcher{ + MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "foo"), + }, + PosRange: posrange.PositionRange{ + Start: 0, + End: 3, + }, + }, + Range: 10 * time.Minute, + Step: 6 * time.Second, + StartOrEnd: START, + EndPos: 21, + }, + }, + { + input: `foo[10m:6s] @ end()`, + expected: &SubqueryExpr{ + Expr: &VectorSelector{ + Name: "foo", + LabelMatchers: []*labels.Matcher{ + MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "foo"), + }, + PosRange: posrange.PositionRange{ + Start: 0, + End: 3, + }, + }, + Range: 10 * time.Minute, + Step: 6 * time.Second, + StartOrEnd: END, + EndPos: 19, + }, + }, + { + input: `start()`, + fail: true, + errMsg: `1:6: parse error: unexpected "("`, + }, + { + input: `end()`, + fail: true, + errMsg: `1:4: parse error: unexpected "("`, + }, + // Check that start and end functions do not mask metrics. + { + input: `start`, + expected: &VectorSelector{ + Name: "start", + LabelMatchers: []*labels.Matcher{ + MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "start"), + }, + PosRange: posrange.PositionRange{ + Start: 0, + End: 5, + }, + }, + }, + { + input: `end`, + expected: &VectorSelector{ + Name: "end", + LabelMatchers: []*labels.Matcher{ + MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "end"), + }, + PosRange: posrange.PositionRange{ + Start: 0, + End: 3, + }, + }, + }, + { + input: `start{end="foo"}`, + expected: &VectorSelector{ + Name: "start", + LabelMatchers: []*labels.Matcher{ + MustLabelMatcher(labels.MatchEqual, "end", "foo"), + MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "start"), + }, + PosRange: posrange.PositionRange{ + Start: 0, + End: 16, + }, + }, + }, + { + input: `end{start="foo"}`, + expected: &VectorSelector{ + Name: "end", + LabelMatchers: []*labels.Matcher{ + MustLabelMatcher(labels.MatchEqual, "start", "foo"), + MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "end"), + }, + PosRange: posrange.PositionRange{ + Start: 0, + End: 16, + }, + }, + }, + { + input: `foo unless on(start) bar`, + expected: &BinaryExpr{ + Op: LUNLESS, + LHS: &VectorSelector{ + Name: "foo", + LabelMatchers: []*labels.Matcher{ + MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "foo"), + }, + PosRange: posrange.PositionRange{ + Start: 0, + End: 3, + }, + }, + RHS: &VectorSelector{ + Name: "bar", + LabelMatchers: []*labels.Matcher{ + MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "bar"), + }, + PosRange: posrange.PositionRange{ + Start: 21, + End: 24, + }, + }, + VectorMatching: &VectorMatching{ + Card: CardManyToMany, + MatchingLabels: []string{"start"}, + On: true, + }, + }, + }, + { + input: `foo unless on(end) bar`, + expected: &BinaryExpr{ + Op: LUNLESS, + LHS: &VectorSelector{ + Name: "foo", + LabelMatchers: []*labels.Matcher{ + MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "foo"), + }, + PosRange: posrange.PositionRange{ + Start: 0, + End: 3, + }, + }, + RHS: &VectorSelector{ + Name: "bar", + LabelMatchers: []*labels.Matcher{ + MustLabelMatcher(labels.MatchEqual, model.MetricNameLabel, "bar"), + }, + PosRange: posrange.PositionRange{ + Start: 19, + End: 22, + }, + }, + VectorMatching: &VectorMatching{ + Card: CardManyToMany, + MatchingLabels: []string{"end"}, + On: true, + }, + }, + }, } func makeInt64Pointer(val int64) *int64 { @@ -3601,9 +3618,6 @@ func makeInt64Pointer(val int64) *int64 { return valp } - -//{"foo", a="bc"} - func TestParseExpressions(t *testing.T) { for _, test := range testExpr { t.Run(test.input, func(t *testing.T) {