Skip to main content

promql_parser/parser/
parse.rs

1// Copyright 2023 Greptime Team
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use crate::parser::{lex, Expr, INVALID_QUERY_INFO};
16
17/// Parse the given query literal to an AST (which is [`Expr`] in this crate).
18pub fn parse(input: &str) -> Result<Expr, String> {
19    match lex::lexer(input) {
20        Err(e) => Err(e),
21        Ok(lexer) => {
22            // NOTE: the errs is ignored so far.
23            let (res, _errs) = crate::promql_y::parse(&lexer);
24            res.ok_or_else(|| String::from(INVALID_QUERY_INFO))?
25        }
26    }
27}
28
29/// cases in original prometheus is a huge slices which are constructed more than 3000 lines,
30/// and it is hard to split them based on the original order. So here is the Note:
31///
32/// - all cases SHOULD be covered, and the same literal float and literal
33///   string SHOULD be the same with the original prometheus.
34/// - all cases will be split into different blocks based on the type of parsed Expr.
35#[cfg(test)]
36mod tests {
37    use regex::Regex;
38
39    use crate::parser;
40    use crate::parser::function::get_function;
41    use crate::parser::{
42        token, AtModifier as At, BinModifier, Expr, FunctionArgs, LabelModifier, Offset,
43        VectorMatchCardinality, VectorSelector, INVALID_QUERY_INFO,
44    };
45    use crate::util::duration;
46    use crate::{
47        label::{Labels, MatchOp, Matcher, Matchers, METRIC_NAME},
48        util::duration::{DAY_DURATION, HOUR_DURATION, MINUTE_DURATION, YEAR_DURATION},
49    };
50    use std::time::Duration;
51    use std::vec;
52
53    struct Case {
54        input: String,
55        expected: Result<Expr, String>,
56    }
57
58    impl Case {
59        fn new(input: &str, expected: Result<Expr, String>) -> Self {
60            Case {
61                input: String::from(input),
62                expected,
63            }
64        }
65
66        fn new_result_cases(cases: Vec<(&str, Result<Expr, String>)>) -> Vec<Case> {
67            cases
68                .into_iter()
69                .map(|(input, expected)| Case::new(input, expected))
70                .collect()
71        }
72
73        fn new_expr_cases(cases: Vec<(&str, Expr)>) -> Vec<Case> {
74            cases
75                .into_iter()
76                .map(|(input, expected)| Case::new(input, Ok(expected)))
77                .collect()
78        }
79
80        fn new_fail_cases(cases: Vec<(&str, &str)>) -> Vec<Case> {
81            cases
82                .into_iter()
83                .map(|(input, expected)| Case::new(input, Err(expected.into())))
84                .collect()
85        }
86    }
87
88    fn assert_cases(cases: Vec<Case>) {
89        for Case { input, expected } in cases {
90            assert_eq!(expected, crate::parser::parse(&input));
91        }
92    }
93
94    #[test]
95    fn test_number_literal() {
96        let cases = vec![
97            ("1", Expr::from(1.0)),
98            ("Inf", Expr::from(f64::INFINITY)),
99            ("+Inf", Expr::from(f64::INFINITY)),
100            ("-Inf", Expr::from(f64::NEG_INFINITY)),
101            (".5", Expr::from(0.5)),
102            ("5.", Expr::from(5.0)),
103            ("123.4567", Expr::from(123.4567)),
104            ("5e-3", Expr::from(0.005)),
105            ("5e3", Expr::from(5000.0)),
106            ("0xc", Expr::from(12.0)),
107            ("0755", Expr::from(493.0)),
108            ("08", Expr::from(8.0)),
109            ("+5.5e-3", Expr::from(0.0055)),
110            ("-0755", Expr::from(-493.0)),
111
112            // for abnormal input
113            ("NaN", Expr::from(f64::NAN)),
114            (
115                "999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999",
116                Expr::from(f64::INFINITY)
117            ),
118        ];
119        assert_cases(Case::new_expr_cases(cases));
120    }
121
122    #[test]
123    fn test_string_literal() {
124        let cases = vec![
125            (
126                "\"double-quoted string \\\" with escaped quote\"",
127                Expr::from("double-quoted string \" with escaped quote"),
128            ),
129            (
130                r#""double-quoted raw string \" with escaped quote""#,
131                Expr::from(r#"double-quoted raw string " with escaped quote"#),
132            ),
133            (
134                r#"'single-quoted string \' with escaped quote'"#,
135                Expr::from("single-quoted string ' with escaped quote"),
136            ),
137            (
138                "`backtick-quoted string`",
139                Expr::from("backtick-quoted string"),
140            ),
141            // \a is not valid character in rust, use \u{7} instead
142            (
143                r#""\a\b\f\n\r\t\v\\\" - \xFF\377\u1234\U00010111\U0001011111☺""#,
144                Expr::from("\u{7}\u{8}\u{c}\n\r\t\u{b}\\\" - ÿÿሴ𐄑𐄑11☺"),
145            ),
146            (
147                r"'\a\b\f\n\r\t\v\\\' - \xFF\377\u1234\U00010111\U0001011111☺'",
148                Expr::from("\u{7}\u{8}\u{c}\n\r\t\u{b}\\' - ÿÿሴ𐄑𐄑11☺"),
149            ),
150            // no escape in ` quoted string
151            (
152                r"`\a\b\f\n\r\t\v\\ - \xFF\377\u1234\U00010111\U0001011111☺`",
153                Expr::from(r"\a\b\f\n\r\t\v\\ - \xFF\377\u1234\U00010111\U0001011111☺"),
154            ),
155        ];
156        assert_cases(Case::new_expr_cases(cases));
157
158        let fail_cases = vec![
159            (r"`\\``", "unterminated quoted string `"),
160            (r#""\"#, "escape sequence not terminated"),
161            (r#""\c""#, "unknown escape sequence 'c'"),
162            // (r#""\x.""#, ""),
163        ];
164        assert_cases(Case::new_fail_cases(fail_cases));
165    }
166
167    #[test]
168    fn test_duration_literal() {
169        let cases = vec![
170            ("1ms", Expr::from(Duration::from_millis(1).as_secs_f64())),
171            ("1s", Expr::from(Duration::from_secs(1).as_secs_f64())),
172            ("1m", Expr::from(MINUTE_DURATION.as_secs_f64())),
173            ("1h", Expr::from(HOUR_DURATION.as_secs_f64())),
174            ("1d", Expr::from(DAY_DURATION.as_secs_f64())),
175            ("1y", Expr::from(YEAR_DURATION.as_secs_f64())),
176            (
177                "1y2d4h8m16s32ms",
178                Expr::from(
179                    (YEAR_DURATION
180                        + DAY_DURATION * 2
181                        + HOUR_DURATION * 4
182                        + MINUTE_DURATION * 8
183                        + Duration::from_secs(16)
184                        + Duration::from_millis(32))
185                    .as_secs_f64(),
186                ),
187            ),
188        ];
189        assert_cases(Case::new_expr_cases(cases));
190    }
191
192    #[test]
193    fn test_vector_binary_expr() {
194        let cases = vec![
195            (
196                "1 + 1",
197                Expr::new_binary_expr(Expr::from(1.0), token::T_ADD, None, Expr::from(1.0)),
198            ),
199            (
200                "1 - 1",
201                Expr::new_binary_expr(Expr::from(1.0), token::T_SUB, None, Expr::from(1.0)),
202            ),
203            (
204                "1 * 1",
205                Expr::new_binary_expr(Expr::from(1.0), token::T_MUL, None, Expr::from(1.0)),
206            ),
207            (
208                "1 / 1",
209                Expr::new_binary_expr(Expr::from(1.0), token::T_DIV, None, Expr::from(1.0)),
210            ),
211            (
212                "1 % 1",
213                Expr::new_binary_expr(Expr::from(1.0), token::T_MOD, None, Expr::from(1.0)),
214            ),
215            (
216                "1 == bool 1",
217                Expr::new_binary_expr(
218                    Expr::from(1.0),
219                    token::T_EQLC,
220                    Some(BinModifier::default().with_return_bool(true)),
221                    Expr::from(1.0),
222                ),
223            ),
224            (
225                "1 != bool 1",
226                Expr::new_binary_expr(
227                    Expr::from(1.0),
228                    token::T_NEQ,
229                    Some(BinModifier::default().with_return_bool(true)),
230                    Expr::from(1.0),
231                ),
232            ),
233            (
234                "1 > bool 1",
235                Expr::new_binary_expr(
236                    Expr::from(1.0),
237                    token::T_GTR,
238                    Some(BinModifier::default().with_return_bool(true)),
239                    Expr::from(1.0),
240                ),
241            ),
242            (
243                "1 >= bool 1",
244                Expr::new_binary_expr(
245                    Expr::from(1.0),
246                    token::T_GTE,
247                    Some(BinModifier::default().with_return_bool(true)),
248                    Expr::from(1.0),
249                ),
250            ),
251            (
252                "1 < bool 1",
253                Expr::new_binary_expr(
254                    Expr::from(1.0),
255                    token::T_LSS,
256                    Some(BinModifier::default().with_return_bool(true)),
257                    Expr::from(1.0),
258                ),
259            ),
260            (
261                "1 <= bool 1",
262                Expr::new_binary_expr(
263                    Expr::from(1.0),
264                    token::T_LTE,
265                    Some(BinModifier::default().with_return_bool(true)),
266                    Expr::from(1.0),
267                ),
268            ),
269            (
270                "-1^2",
271                Expr::new_binary_expr(Expr::from(1.0), token::T_POW, None, Expr::from(2.0))
272                    .map(|ex| -ex),
273            ),
274            (
275                "-1*2",
276                Expr::new_binary_expr(Expr::from(-1.0), token::T_MUL, None, Expr::from(2.0)),
277            ),
278            (
279                "-1+2",
280                Expr::new_binary_expr(Expr::from(-1.0), token::T_ADD, None, Expr::from(2.0)),
281            ),
282            (
283                "-1^-2",
284                Expr::new_binary_expr(Expr::from(1.0), token::T_POW, None, Expr::from(-2.0))
285                    .map(|ex| -ex),
286            ),
287            (
288                "+1 + -2 * 1",
289                Expr::new_binary_expr(Expr::from(-2.0), token::T_MUL, None, Expr::from(1.0))
290                    .and_then(|ex| Expr::new_binary_expr(Expr::from(1.0), token::T_ADD, None, ex)),
291            ),
292            (
293                "1 + 2/(3*1)",
294                Expr::new_binary_expr(Expr::from(3.0), token::T_MUL, None, Expr::from(1.0))
295                    .and_then(Expr::new_paren_expr)
296                    .and_then(|ex| Expr::new_binary_expr(Expr::from(2.0), token::T_DIV, None, ex))
297                    .and_then(|ex| Expr::new_binary_expr(Expr::from(1.0), token::T_ADD, None, ex)),
298            ),
299            (
300                "1 < bool 2 - 1 * 2",
301                Expr::new_binary_expr(Expr::from(1.0), token::T_MUL, None, Expr::from(2.0))
302                    .and_then(|ex| Expr::new_binary_expr(Expr::from(2.0), token::T_SUB, None, ex))
303                    .and_then(|ex| {
304                        Expr::new_binary_expr(
305                            Expr::from(1.0),
306                            token::T_LSS,
307                            Some(BinModifier::default().with_return_bool(true)),
308                            ex,
309                        )
310                    }),
311            ),
312            (
313                "foo * bar",
314                Expr::new_binary_expr(
315                    Expr::from(VectorSelector::from("foo")),
316                    token::T_MUL,
317                    None,
318                    Expr::from(VectorSelector::from("bar")),
319                ),
320            ),
321            (
322                "foo * sum",
323                Expr::new_binary_expr(
324                    Expr::from(VectorSelector::from("foo")),
325                    token::T_MUL,
326                    None,
327                    Expr::from(VectorSelector::from("sum")),
328                ),
329            ),
330            (
331                "foo == 1",
332                Expr::new_binary_expr(
333                    Expr::from(VectorSelector::from("foo")),
334                    token::T_EQLC,
335                    None,
336                    Expr::from(1.0),
337                ),
338            ),
339            (
340                "foo == bool 1",
341                Expr::new_binary_expr(
342                    Expr::from(VectorSelector::from("foo")),
343                    token::T_EQLC,
344                    Some(BinModifier::default().with_return_bool(true)),
345                    Expr::from(1.0),
346                ),
347            ),
348            (
349                "2.5 / bar",
350                Expr::new_binary_expr(
351                    Expr::from(2.5),
352                    token::T_DIV,
353                    None,
354                    Expr::from(VectorSelector::from("bar")),
355                ),
356            ),
357            (
358                "foo and bar",
359                Expr::new_binary_expr(
360                    Expr::from(VectorSelector::from("foo")),
361                    token::T_LAND,
362                    Some(BinModifier::default().with_card(VectorMatchCardinality::ManyToMany)),
363                    Expr::from(VectorSelector::from("bar")),
364                ),
365            ),
366            (
367                "foo or bar",
368                Expr::new_binary_expr(
369                    Expr::from(VectorSelector::from("foo")),
370                    token::T_LOR,
371                    Some(BinModifier::default().with_card(VectorMatchCardinality::ManyToMany)),
372                    Expr::from(VectorSelector::from("bar")),
373                ),
374            ),
375            (
376                "foo unless bar",
377                Expr::new_binary_expr(
378                    Expr::from(VectorSelector::from("foo")),
379                    token::T_LUNLESS,
380                    Some(BinModifier::default().with_card(VectorMatchCardinality::ManyToMany)),
381                    Expr::from(VectorSelector::from("bar")),
382                ),
383            ),
384            (
385                // Test and/or precedence and reassigning of operands.
386                "foo + bar or bla and blub",
387                {
388                    let lhs = Expr::new_binary_expr(
389                        Expr::from(VectorSelector::from("foo")),
390                        token::T_ADD,
391                        None,
392                        Expr::from(VectorSelector::from("bar")),
393                    );
394                    let rhs = Expr::new_binary_expr(
395                        Expr::from(VectorSelector::from("bla")),
396                        token::T_LAND,
397                        Some(BinModifier::default().with_card(VectorMatchCardinality::ManyToMany)),
398                        Expr::from(VectorSelector::from("blub")),
399                    );
400                    Expr::new_binary_expr(
401                        lhs.unwrap(),
402                        token::T_LOR,
403                        Some(BinModifier::default().with_card(VectorMatchCardinality::ManyToMany)),
404                        rhs.unwrap(),
405                    )
406                },
407            ),
408            (
409                // Test and/or/unless precedence.
410                "foo and bar unless baz or qux",
411                Expr::new_binary_expr(
412                    Expr::from(VectorSelector::from("foo")),
413                    token::T_LAND,
414                    Some(BinModifier::default().with_card(VectorMatchCardinality::ManyToMany)),
415                    Expr::from(VectorSelector::from("bar")),
416                )
417                .and_then(|ex| {
418                    Expr::new_binary_expr(
419                        ex,
420                        token::T_LUNLESS,
421                        Some(BinModifier::default().with_card(VectorMatchCardinality::ManyToMany)),
422                        Expr::from(VectorSelector::from("baz")),
423                    )
424                })
425                .and_then(|ex| {
426                    Expr::new_binary_expr(
427                        ex,
428                        token::T_LOR,
429                        Some(BinModifier::default().with_card(VectorMatchCardinality::ManyToMany)),
430                        Expr::from(VectorSelector::from("qux")),
431                    )
432                }),
433            ),
434            (
435                // Test precedence and reassigning of operands.
436                "bar + on(foo) bla / on(baz, buz) group_right(test) blub",
437                Expr::new_binary_expr(
438                    Expr::from(VectorSelector::from("bla")),
439                    token::T_DIV,
440                    Some(
441                        BinModifier::default()
442                            .with_card(VectorMatchCardinality::one_to_many(vec!["test"]))
443                            .with_matching(Some(LabelModifier::include(vec!["baz", "buz"]))),
444                    ),
445                    Expr::from(VectorSelector::from("blub")),
446                )
447                .and_then(|ex| {
448                    Expr::new_binary_expr(
449                        Expr::from(VectorSelector::from("bar")),
450                        token::T_ADD,
451                        Some(
452                            BinModifier::default()
453                                .with_matching(Some(LabelModifier::include(vec!["foo"]))),
454                        ),
455                        ex,
456                    )
457                }),
458            ),
459            (
460                "foo * on(test,blub) bar",
461                Expr::new_binary_expr(
462                    Expr::from(VectorSelector::from("foo")),
463                    token::T_MUL,
464                    Some(
465                        BinModifier::default()
466                            .with_matching(Some(LabelModifier::include(vec!["test", "blub"]))),
467                    ),
468                    Expr::from(VectorSelector::from("bar")),
469                ),
470            ),
471            (
472                "foo * on(test,blub) group_left bar",
473                Expr::new_binary_expr(
474                    Expr::from(VectorSelector::from("foo")),
475                    token::T_MUL,
476                    Some(
477                        BinModifier::default()
478                            .with_matching(Some(LabelModifier::include(vec!["test", "blub"])))
479                            .with_card(VectorMatchCardinality::many_to_one(vec![])),
480                    ),
481                    Expr::from(VectorSelector::from("bar")),
482                ),
483            ),
484            ("foo and on(test,blub) bar", {
485                let matching = LabelModifier::include(vec!["test", "blub"]);
486                let card = VectorMatchCardinality::ManyToMany;
487                Expr::new_binary_expr(
488                    Expr::from(VectorSelector::from("foo")),
489                    token::T_LAND,
490                    Some(
491                        BinModifier::default()
492                            .with_matching(Some(matching))
493                            .with_card(card),
494                    ),
495                    Expr::from(VectorSelector::from("bar")),
496                )
497            }),
498            ("foo and on() bar", {
499                let matching = LabelModifier::include(vec![]);
500                let card = VectorMatchCardinality::ManyToMany;
501                Expr::new_binary_expr(
502                    Expr::from(VectorSelector::from("foo")),
503                    token::T_LAND,
504                    Some(
505                        BinModifier::default()
506                            .with_matching(Some(matching))
507                            .with_card(card),
508                    ),
509                    Expr::from(VectorSelector::from("bar")),
510                )
511            }),
512            ("foo and ignoring(test,blub) bar", {
513                let matching = LabelModifier::exclude(vec!["test", "blub"]);
514                let card = VectorMatchCardinality::ManyToMany;
515                Expr::new_binary_expr(
516                    Expr::from(VectorSelector::from("foo")),
517                    token::T_LAND,
518                    Some(
519                        BinModifier::default()
520                            .with_matching(Some(matching))
521                            .with_card(card),
522                    ),
523                    Expr::from(VectorSelector::from("bar")),
524                )
525            }),
526            ("foo and ignoring() bar", {
527                let matching = LabelModifier::exclude(vec![]);
528                let card = VectorMatchCardinality::ManyToMany;
529                Expr::new_binary_expr(
530                    Expr::from(VectorSelector::from("foo")),
531                    token::T_LAND,
532                    Some(
533                        BinModifier::default()
534                            .with_matching(Some(matching))
535                            .with_card(card),
536                    ),
537                    Expr::from(VectorSelector::from("bar")),
538                )
539            }),
540            ("foo unless on(bar) baz", {
541                let matching = LabelModifier::include(vec!["bar"]);
542                let card = VectorMatchCardinality::ManyToMany;
543                Expr::new_binary_expr(
544                    Expr::from(VectorSelector::from("foo")),
545                    token::T_LUNLESS,
546                    Some(
547                        BinModifier::default()
548                            .with_matching(Some(matching))
549                            .with_card(card),
550                    ),
551                    Expr::from(VectorSelector::from("baz")),
552                )
553            }),
554            (
555                "foo / on(test,blub) group_left(bar) bar",
556                Expr::new_binary_expr(
557                    Expr::from(VectorSelector::from("foo")),
558                    token::T_DIV,
559                    Some(
560                        BinModifier::default()
561                            .with_matching(Some(LabelModifier::include(vec!["test", "blub"])))
562                            .with_card(VectorMatchCardinality::many_to_one(vec!["bar"])),
563                    ),
564                    Expr::from(VectorSelector::from("bar")),
565                ),
566            ),
567            (
568                "foo / ignoring(test,blub) group_left(blub) bar",
569                Expr::new_binary_expr(
570                    Expr::from(VectorSelector::from("foo")),
571                    token::T_DIV,
572                    Some(
573                        BinModifier::default()
574                            .with_matching(Some(LabelModifier::exclude(vec!["test", "blub"])))
575                            .with_card(VectorMatchCardinality::many_to_one(vec!["blub"])),
576                    ),
577                    Expr::from(VectorSelector::from("bar")),
578                ),
579            ),
580            (
581                "foo / ignoring(test,blub) group_left(bar) bar",
582                Expr::new_binary_expr(
583                    Expr::from(VectorSelector::from("foo")),
584                    token::T_DIV,
585                    Some(
586                        BinModifier::default()
587                            .with_matching(Some(LabelModifier::exclude(vec!["test", "blub"])))
588                            .with_card(VectorMatchCardinality::many_to_one(vec!["bar"])),
589                    ),
590                    Expr::from(VectorSelector::from("bar")),
591                ),
592            ),
593            (
594                "foo - on(test,blub) group_right(bar,foo) bar",
595                Expr::new_binary_expr(
596                    Expr::from(VectorSelector::from("foo")),
597                    token::T_SUB,
598                    Some(
599                        BinModifier::default()
600                            .with_matching(Some(LabelModifier::include(vec!["test", "blub"])))
601                            .with_card(VectorMatchCardinality::one_to_many(vec!["bar", "foo"])),
602                    ),
603                    Expr::from(VectorSelector::from("bar")),
604                ),
605            ),
606            (
607                "foo - ignoring(test,blub) group_right(bar,foo) bar",
608                Expr::new_binary_expr(
609                    Expr::from(VectorSelector::from("foo")),
610                    token::T_SUB,
611                    Some(
612                        BinModifier::default()
613                            .with_matching(Some(LabelModifier::exclude(vec!["test", "blub"])))
614                            .with_card(VectorMatchCardinality::one_to_many(vec!["bar", "foo"])),
615                    ),
616                    Expr::from(VectorSelector::from("bar")),
617                ),
618            ),
619            (
620                "a + sum",
621                Expr::new_binary_expr(
622                    Expr::from(VectorSelector::from("a")),
623                    token::T_ADD,
624                    None,
625                    Expr::from(VectorSelector::from("sum")),
626                ),
627            ),
628            // cases from https://prometheus.io/docs/prometheus/latest/querying/operators
629            (
630                r#"method_code:http_errors:rate5m{code="500"} / ignoring(code) method:http_requests:rate5m"#,
631                {
632                    let name = String::from("method_code:http_errors:rate5m");
633                    let matchers = Matchers::one(Matcher::new(MatchOp::Equal, "code", "500"));
634                    let lhs = Expr::new_vector_selector(Some(name), matchers).unwrap();
635                    Expr::new_binary_expr(
636                        lhs,
637                        token::T_DIV,
638                        Some(
639                            BinModifier::default()
640                                .with_matching(Some(LabelModifier::exclude(vec!["code"]))),
641                        ),
642                        Expr::from(VectorSelector::from("method:http_requests:rate5m")),
643                    )
644                },
645            ),
646            (
647                r#"method_code:http_errors:rate5m / ignoring(code) group_left method:http_requests:rate5m"#,
648                Expr::new_binary_expr(
649                    Expr::from(VectorSelector::from("method_code:http_errors:rate5m")),
650                    token::T_DIV,
651                    Some(
652                        BinModifier::default()
653                            .with_matching(Some(LabelModifier::exclude(vec!["code"])))
654                            .with_card(VectorMatchCardinality::ManyToOne(Labels::new(vec![]))),
655                    ),
656                    Expr::from(VectorSelector::from("method:http_requests:rate5m")),
657                ),
658            ),
659        ];
660        assert_cases(Case::new_result_cases(cases));
661
662        let fail_cases = vec![
663            (
664                "foo and 1",
665                "set operator 'and' not allowed in binary scalar expression",
666            ),
667            (
668                "1 and foo",
669                "set operator 'and' not allowed in binary scalar expression",
670            ),
671            (
672                "foo or 1",
673                "set operator 'or' not allowed in binary scalar expression",
674            ),
675            (
676                "1 or foo",
677                "set operator 'or' not allowed in binary scalar expression",
678            ),
679            (
680                "foo unless 1",
681                "set operator 'unless' not allowed in binary scalar expression",
682            ),
683            (
684                "1 unless foo",
685                "set operator 'unless' not allowed in binary scalar expression",
686            ),
687            (
688                "1 or on(bar) foo",
689                "set operator 'or' not allowed in binary scalar expression",
690            ),
691            (
692                "foo == on(bar) 10",
693                "vector matching only allowed between vectors",
694            ),
695            // NOTE: group modifier CAN NOT be used without on/ignoring modifier
696            ("foo + group_left(baz) bar", "unexpected <group_left>"),
697            (
698                "foo and on(bar) group_left(baz) bar",
699                "no grouping allowed for 'and' operation",
700            ),
701            (
702                "foo and on(bar) group_right(baz) bar",
703                "no grouping allowed for 'and' operation",
704            ),
705            (
706                "foo or on(bar) group_left(baz) bar",
707                "no grouping allowed for 'or' operation",
708            ),
709            (
710                "foo or on(bar) group_right(baz) bar",
711                "no grouping allowed for 'or' operation",
712            ),
713            (
714                "foo unless on(bar) group_left(baz) bar",
715                "no grouping allowed for 'unless' operation",
716            ),
717            (
718                "foo unless on(bar) group_right(baz) bar",
719                "no grouping allowed for 'unless' operation",
720            ),
721            (
722                r#"http_requests{group="production"} + on(instance) group_left(job,instance) cpu_count{type="smp"}"#,
723                "label 'instance' must not occur in ON and GROUP clause at once",
724            ),
725            (
726                "foo + bool bar",
727                "bool modifier can only be used on comparison operators",
728            ),
729            (
730                "foo + bool 10",
731                "bool modifier can only be used on comparison operators",
732            ),
733            (
734                "foo and bool 10",
735                "bool modifier can only be used on comparison operators",
736            ),
737            (
738                "1 and 1",
739                "set operator 'and' not allowed in binary scalar expression",
740            ),
741            (
742                "1 == 1",
743                "comparisons between scalars must use BOOL modifier",
744            ),
745            (
746                "1 or 1",
747                "set operator 'or' not allowed in binary scalar expression",
748            ),
749            (
750                "1 unless 1",
751                "set operator 'unless' not allowed in binary scalar expression",
752            ),
753        ];
754        assert_cases(Case::new_fail_cases(fail_cases));
755    }
756
757    #[test]
758    fn test_unary_expr() {
759        let cases = vec![
760            (
761                "-some_metric",
762                Expr::new_unary_expr(Expr::from(VectorSelector::from("some_metric"))).unwrap(),
763            ),
764            (
765                "+some_metric",
766                Expr::from(VectorSelector::from("some_metric")),
767            ),
768            (
769                " +some_metric",
770                Expr::from(VectorSelector::from("some_metric")),
771            ),
772        ];
773        assert_cases(Case::new_expr_cases(cases));
774
775        let cases = vec![
776            (r#"-"string""#, "unary expression only allowed on expressions of type scalar or vector, got: string"),
777            ("-test[5m]", "unary expression only allowed on expressions of type scalar or vector, got: matrix"),
778            (r#"-"foo""#, "unary expression only allowed on expressions of type scalar or vector, got: string"),
779        ];
780        assert_cases(Case::new_fail_cases(cases));
781    }
782
783    #[test]
784    fn test_vector_selector() {
785        let cases = vec![
786            ("foo", Ok(Expr::from(VectorSelector::from("foo")))),
787            ("min", Ok(Expr::from(VectorSelector::from("min")))),
788            (
789                "foo offset 5m",
790                Expr::from(VectorSelector::from("foo"))
791                    .offset_expr(Offset::Pos(Duration::from_secs(60 * 5))),
792            ),
793            (
794                "foo offset -7m",
795                Expr::from(VectorSelector::from("foo"))
796                    .offset_expr(Offset::Neg(Duration::from_secs(60 * 7))),
797            ),
798            (
799                "foo OFFSET 1h30m",
800                Expr::from(VectorSelector::from("foo"))
801                    .offset_expr(Offset::Pos(Duration::from_secs(60 * 90))),
802            ),
803            (
804                "foo OFFSET 1h30ms",
805                Expr::from(VectorSelector::from("foo")).offset_expr(Offset::Pos(
806                    Duration::from_secs(60 * 60) + Duration::from_millis(30),
807                )),
808            ),
809            (
810                "foo @ 1603774568",
811                Expr::from(VectorSelector::from("foo"))
812                    .at_expr(At::try_from(1603774568f64).unwrap()),
813            ),
814            (
815                "foo @ -100",
816                Expr::from(VectorSelector::from("foo")).at_expr(At::try_from(-100f64).unwrap()),
817            ),
818            (
819                "foo @ .3",
820                Expr::from(VectorSelector::from("foo")).at_expr(At::try_from(0.3f64).unwrap()),
821            ),
822            (
823                "foo @ 3.",
824                Expr::from(VectorSelector::from("foo")).at_expr(At::try_from(3.0f64).unwrap()),
825            ),
826            (
827                "foo @ 3.33",
828                Expr::from(VectorSelector::from("foo")).at_expr(At::try_from(3.33f64).unwrap()),
829            ),
830            (
831                "foo @ 3.3333",
832                Expr::from(VectorSelector::from("foo")).at_expr(At::try_from(3.333f64).unwrap()),
833            ),
834            (
835                "foo @ 3.3335",
836                Expr::from(VectorSelector::from("foo")).at_expr(At::try_from(3.334f64).unwrap()),
837            ),
838            (
839                "foo @ 3e2",
840                Expr::from(VectorSelector::from("foo")).at_expr(At::try_from(300f64).unwrap()),
841            ),
842            (
843                "foo @ 3e-1",
844                Expr::from(VectorSelector::from("foo")).at_expr(At::try_from(0.3f64).unwrap()),
845            ),
846            (
847                "foo @ 0xA",
848                Expr::from(VectorSelector::from("foo")).at_expr(At::try_from(10f64).unwrap()),
849            ),
850            (
851                "foo @ -3.3e1",
852                Expr::from(VectorSelector::from("foo")).at_expr(At::try_from(-33f64).unwrap()),
853            ),
854            (r#"foo:bar{a="bc"}"#, {
855                let matchers = Matchers::one(Matcher::new(MatchOp::Equal, "a", "bc"));
856                Expr::new_vector_selector(Some(String::from("foo:bar")), matchers)
857            }),
858            (r#"foo{NaN='bc'}"#, {
859                let matchers = Matchers::one(Matcher::new(MatchOp::Equal, "NaN", "bc"));
860                Expr::new_vector_selector(Some(String::from("foo")), matchers)
861            }),
862            (r#"foo{bar='}'}"#, {
863                let matchers = Matchers::one(Matcher::new(MatchOp::Equal, "bar", "}"));
864                Expr::new_vector_selector(Some(String::from("foo")), matchers)
865            }),
866            (r#"foo{a="b", foo!="bar", test=~"test", bar!~"baz"}"#, {
867                let matchers = Matchers::new(vec![
868                    Matcher::new(MatchOp::Equal, "a", "b"),
869                    Matcher::new(MatchOp::NotEqual, "foo", "bar"),
870                    Matcher::new_matcher(
871                        token::T_EQL_REGEX,
872                        String::from("test"),
873                        String::from("test"),
874                    )
875                    .unwrap(),
876                    Matcher::new_matcher(
877                        token::T_NEQ_REGEX,
878                        String::from("bar"),
879                        String::from("baz"),
880                    )
881                    .unwrap(),
882                ]);
883                Expr::new_vector_selector(Some(String::from("foo")), matchers)
884            }),
885            (r#"foo{a="b", foo!="bar", test=~"test", bar!~"baz",}"#, {
886                let name = String::from("foo");
887                let matchers = Matchers::new(vec![
888                    Matcher::new(MatchOp::Equal, "a", "b"),
889                    Matcher::new(MatchOp::NotEqual, "foo", "bar"),
890                    Matcher::new_matcher(
891                        token::T_EQL_REGEX,
892                        String::from("test"),
893                        String::from("test"),
894                    )
895                    .unwrap(),
896                    Matcher::new_matcher(
897                        token::T_NEQ_REGEX,
898                        String::from("bar"),
899                        String::from("baz"),
900                    )
901                    .unwrap(),
902                ]);
903                Expr::new_vector_selector(Some(name), matchers)
904            }),
905            // the following multiple __name__ matcher test cases are not from prometheus
906            (r#"{__name__="foo",__name__="bar"}"#, {
907                let matchers = Matchers::new(vec![
908                    Matcher::new(MatchOp::Equal, METRIC_NAME, "foo"),
909                    Matcher::new(MatchOp::Equal, METRIC_NAME, "bar"),
910                ]);
911                Expr::new_vector_selector(None, matchers)
912            }),
913            (r#"{__name__=~"foo.+",__name__=~".*bar"}"#, {
914                let matchers = Matchers::new(vec![
915                    Matcher::new_matcher(
916                        token::T_EQL_REGEX,
917                        String::from(METRIC_NAME),
918                        String::from("foo.+"),
919                    )
920                    .unwrap(),
921                    Matcher::new_matcher(
922                        token::T_EQL_REGEX,
923                        String::from(METRIC_NAME),
924                        String::from(".*bar"),
925                    )
926                    .unwrap(),
927                ]);
928                Expr::new_vector_selector(None, matchers)
929            }),
930            (r#"foo:bar{a=~"bc{9}"}"#, {
931                let matchers = Matchers::one(Matcher::new(
932                    MatchOp::Re(Regex::new("^(?:bc{9})$").unwrap()),
933                    "a",
934                    "bc{9}",
935                ));
936                Expr::new_vector_selector(Some(String::from("foo:bar")), matchers)
937            }),
938            (r#"foo:bar{a=~"bc{abc}"}"#, {
939                let matchers = Matchers::one(Matcher::new(
940                    MatchOp::Re(Regex::new("^(?:bc\\{abc})$").unwrap()),
941                    "a",
942                    "bc{abc}",
943                ));
944                Expr::new_vector_selector(Some(String::from("foo:bar")), matchers)
945            }),
946        ];
947        assert_cases(Case::new_result_cases(cases));
948
949        let fail_cases = vec![
950            ("foo @ +Inf", "timestamp out of bounds for @ modifier: inf"),
951            ("foo @ -Inf", "timestamp out of bounds for @ modifier: -inf"),
952            ("foo @ NaN", "timestamp out of bounds for @ modifier: NaN"),
953            ("{", "unexpected end of input inside braces"),
954            ("}", "unexpected right brace '}'"),
955            ("some{", "unexpected end of input inside braces"),
956            ("some}", "unexpected right brace '}'"),
957            (
958                "some_metric{a=b}",
959                "unexpected identifier 'b' in label matching, expected string",
960            ),
961            (
962                r#"some_metric{a:b="b"}"#,
963                "unexpected character inside braces: ':'",
964            ),
965            (r#"foo{a*"b"}"#, "unexpected character inside braces: '*'"),
966            (r#"foo{a>="b"}"#, "unexpected character inside braces: '>'"),
967            // (
968            //     r#"some_metric{a="\xff"}"#,
969            //     "1:15: parse error: invalid UTF-8 rune",
970            // ),
971            (
972                "foo{gibberish}",
973                "invalid label matcher, expected label matching operator after 'gibberish'",
974            ),
975            ("foo{1}", "unexpected character inside braces: '1'"),
976            (
977                "{}",
978                "vector selector must contain at least one non-empty matcher",
979            ),
980            (
981                r#"{x=""}"#,
982                "vector selector must contain at least one non-empty matcher",
983            ),
984            (
985                r#"{x=~".*"}"#,
986                "vector selector must contain at least one non-empty matcher",
987            ),
988            (
989                r#"{x!~".+"}"#,
990                "vector selector must contain at least one non-empty matcher",
991            ),
992            (
993                r#"{x!="a"}"#,
994                "vector selector must contain at least one non-empty matcher",
995            ),
996            (
997                r#"foo{__name__="bar"}"#,
998                "metric name must not be set twice: 'foo' or 'bar'",
999            ),
1000            (
1001                "foo{__name__= =}",
1002                "unexpected '=' in label matching, expected string",
1003            ),
1004            (
1005                "foo{,}",
1006                r#"unexpected ',' in label matching, expected identifier or right_brace"#,
1007            ),
1008            (
1009                r#"foo{__name__ == "bar"}"#,
1010                "unexpected '=' in label matching, expected string",
1011            ),
1012            (
1013                r#"foo{__name__="bar" lol}"#,
1014                // "invalid label matcher, expected label matching operator after 'lol'",
1015                INVALID_QUERY_INFO,
1016            ),
1017        ];
1018        assert_cases(Case::new_fail_cases(fail_cases));
1019
1020        let fail_cases = vec![
1021            {
1022                let num = f64::MAX - 1f64;
1023                let input = format!("foo @ {num}");
1024                let expected = Err(format!("timestamp out of bounds for @ modifier: {num}"));
1025                Case { input, expected }
1026            },
1027            {
1028                let num = f64::MIN - 1f64;
1029                let input = format!("foo @ {num}");
1030                let expected = Err(format!("timestamp out of bounds for @ modifier: {num}"));
1031                Case { input, expected }
1032            },
1033        ];
1034        assert_cases(fail_cases);
1035    }
1036
1037    #[test]
1038    fn test_matrix_selector() {
1039        let cases = vec![
1040            (
1041                "test[5s]",
1042                Expr::new_matrix_selector(
1043                    Expr::from(VectorSelector::from("test")),
1044                    Duration::from_secs(5),
1045                ),
1046            ),
1047            (
1048                "test[5m]",
1049                Expr::new_matrix_selector(
1050                    Expr::from(VectorSelector::from("test")),
1051                    duration::MINUTE_DURATION * 5,
1052                ),
1053            ),
1054            (
1055                "test[5m30s]",
1056                Expr::new_matrix_selector(
1057                    Expr::from(VectorSelector::from("test")),
1058                    Duration::from_secs(330),
1059                ),
1060            ),
1061            (
1062                "test[5h] OFFSET 5m",
1063                Expr::new_matrix_selector(
1064                    Expr::from(VectorSelector::from("test")),
1065                    duration::HOUR_DURATION * 5,
1066                )
1067                .and_then(|ex| ex.offset_expr(Offset::Pos(duration::MINUTE_DURATION * 5))),
1068            ),
1069            (
1070                "test[5d] OFFSET 10s",
1071                Expr::new_matrix_selector(
1072                    Expr::from(VectorSelector::from("test")),
1073                    duration::DAY_DURATION * 5,
1074                )
1075                .and_then(|ex| ex.offset_expr(Offset::Pos(Duration::from_secs(10)))),
1076            ),
1077            (
1078                "test[5w] offset 2w",
1079                Expr::new_matrix_selector(
1080                    Expr::from(VectorSelector::from("test")),
1081                    duration::WEEK_DURATION * 5,
1082                )
1083                .and_then(|ex| ex.offset_expr(Offset::Pos(duration::WEEK_DURATION * 2))),
1084            ),
1085            (r#"test{a="b"}[5y] OFFSET 3d"#, {
1086                Expr::new_vector_selector(
1087                    Some(String::from("test")),
1088                    Matchers::one(Matcher::new(MatchOp::Equal, "a", "b")),
1089                )
1090                .and_then(|ex| Expr::new_matrix_selector(ex, duration::YEAR_DURATION * 5))
1091                .and_then(|ex| ex.offset_expr(Offset::Pos(duration::DAY_DURATION * 3)))
1092            }),
1093            (r#"test{a="b"}[5y] @ 1603774699"#, {
1094                Expr::new_vector_selector(
1095                    Some(String::from("test")),
1096                    Matchers::one(Matcher::new(MatchOp::Equal, "a", "b")),
1097                )
1098                .and_then(|ex| Expr::new_matrix_selector(ex, duration::YEAR_DURATION * 5))
1099                .and_then(|ex| ex.at_expr(At::try_from(1603774699_f64).unwrap()))
1100            }),
1101            ("foo[1]", {
1102                Expr::new_matrix_selector(
1103                    Expr::from(VectorSelector::from("foo")),
1104                    Duration::from_secs(1),
1105                )
1106            }),
1107            ("some_metric[5m] OFFSET 1", {
1108                Expr::new_matrix_selector(
1109                    Expr::from(VectorSelector::from("some_metric")),
1110                    duration::MINUTE_DURATION * 5,
1111                )
1112                .and_then(|ex| ex.offset_expr(Offset::Pos(Duration::from_secs(1))))
1113            }),
1114            ("some_metric[5m] @ 1m", {
1115                Expr::new_matrix_selector(
1116                    Expr::from(VectorSelector::from("some_metric")),
1117                    duration::MINUTE_DURATION * 5,
1118                )
1119                .and_then(|ex| {
1120                    ex.at_expr(At::try_from(duration::MINUTE_DURATION.as_secs_f64()).unwrap())
1121                })
1122            }),
1123        ];
1124
1125        assert_cases(Case::new_result_cases(cases));
1126
1127        let fail_cases = vec![
1128            ("foo[5mm]", "bad number or duration syntax: 5mm"),
1129            ("foo[5m1]", "bad number or duration syntax: 5m1]"),
1130            ("foo[5m:1m1]", "bad number or duration syntax: 1m1]"),
1131            ("foo[5y1hs]", "not a valid duration string: 5y1hs"),
1132            ("foo[5m1h]", "not a valid duration string: 5m1h"),
1133            ("foo[5m1m]", "not a valid duration string: 5m1m"),
1134            ("foo[0m]", "duration must be greater than 0"),
1135            (
1136                r#"foo["5m"]"#,
1137                r#"unexpected character inside brackets: '"'"#,
1138            ),
1139            (r#"foo[]"#, "missing unit character in duration"),
1140            (
1141                "some_metric[5m] OFFSET 1mm",
1142                "bad number or duration syntax: 1mm",
1143            ),
1144            (
1145                "some_metric[5m] OFFSET",
1146                "unexpected end of input in offset, expected duration",
1147            ),
1148            (
1149                "some_metric OFFSET 1m[5m]",
1150                "no offset modifiers allowed before range",
1151            ),
1152            (
1153                "some_metric[5m] @",
1154                "unexpected end of input in @, expected timestamp",
1155            ),
1156            (
1157                "some_metric @ 1234 [5m]",
1158                "no @ modifiers allowed before range",
1159            ),
1160            (
1161                "(foo + bar)[5m]",
1162                "ranges only allowed for vector selectors",
1163            ),
1164        ];
1165        assert_cases(Case::new_fail_cases(fail_cases));
1166    }
1167
1168    #[test]
1169    fn test_aggregation_expr() {
1170        let cases = vec![
1171            ("sum by (foo) (some_metric)", {
1172                let ex = Expr::from(VectorSelector::from("some_metric"));
1173                let modifier = LabelModifier::include(vec!["foo"]);
1174                Expr::new_aggregate_expr(token::T_SUM, Some(modifier), FunctionArgs::new_args(ex))
1175            }),
1176            ("avg by (foo)(some_metric)", {
1177                let ex = Expr::from(VectorSelector::from("some_metric"));
1178                let modifier = LabelModifier::include(vec!["foo"]);
1179                Expr::new_aggregate_expr(token::T_AVG, Some(modifier), FunctionArgs::new_args(ex))
1180            }),
1181            ("max by (foo)(some_metric)", {
1182                let modifier = LabelModifier::include(vec!["foo"]);
1183                let ex = Expr::from(VectorSelector::from("some_metric"));
1184                Expr::new_aggregate_expr(token::T_MAX, Some(modifier), FunctionArgs::new_args(ex))
1185            }),
1186            ("sum without (foo) (some_metric)", {
1187                let modifier = LabelModifier::exclude(vec!["foo"]);
1188                let ex = Expr::from(VectorSelector::from("some_metric"));
1189                Expr::new_aggregate_expr(token::T_SUM, Some(modifier), FunctionArgs::new_args(ex))
1190            }),
1191            ("sum (some_metric) without (foo)", {
1192                let modifier = LabelModifier::exclude(vec!["foo"]);
1193                let ex = Expr::from(VectorSelector::from("some_metric"));
1194                Expr::new_aggregate_expr(token::T_SUM, Some(modifier), FunctionArgs::new_args(ex))
1195            }),
1196            ("stddev(some_metric)", {
1197                let ex = Expr::from(VectorSelector::from("some_metric"));
1198                Expr::new_aggregate_expr(token::T_STDDEV, None, FunctionArgs::new_args(ex))
1199            }),
1200            ("stdvar by (foo)(some_metric)", {
1201                let modifier = LabelModifier::include(vec!["foo"]);
1202                let ex = Expr::from(VectorSelector::from("some_metric"));
1203                Expr::new_aggregate_expr(
1204                    token::T_STDVAR,
1205                    Some(modifier),
1206                    FunctionArgs::new_args(ex),
1207                )
1208            }),
1209            ("sum by ()(some_metric)", {
1210                let modifier = LabelModifier::include(vec![]);
1211                let ex = Expr::from(VectorSelector::from("some_metric"));
1212                Expr::new_aggregate_expr(token::T_SUM, Some(modifier), FunctionArgs::new_args(ex))
1213            }),
1214            ("sum by (foo,bar,)(some_metric)", {
1215                let modifier = LabelModifier::include(vec!["foo", "bar"]);
1216                let ex = Expr::from(VectorSelector::from("some_metric"));
1217                Expr::new_aggregate_expr(token::T_SUM, Some(modifier), FunctionArgs::new_args(ex))
1218            }),
1219            ("sum by (foo,)(some_metric)", {
1220                let modifier = LabelModifier::include(vec!["foo"]);
1221                let ex = Expr::from(VectorSelector::from("some_metric"));
1222                Expr::new_aggregate_expr(token::T_SUM, Some(modifier), FunctionArgs::new_args(ex))
1223            }),
1224            ("topk(5, some_metric)", {
1225                let ex = Expr::from(VectorSelector::from("some_metric"));
1226                let param = Expr::from(5.0);
1227                let args = FunctionArgs::new_args(param).append_args(ex);
1228                Expr::new_aggregate_expr(token::T_TOPK, None, args)
1229            }),
1230            (r#"count_values("value", some_metric)"#, {
1231                let ex = Expr::from(VectorSelector::from("some_metric"));
1232                let param = Expr::from("value");
1233                let args = FunctionArgs::new_args(param).append_args(ex);
1234                Expr::new_aggregate_expr(token::T_COUNT_VALUES, None, args)
1235            }),
1236            (
1237                "sum without(and, by, avg, count, alert, annotations)(some_metric)",
1238                {
1239                    let modifier = LabelModifier::exclude(vec![
1240                        "and",
1241                        "by",
1242                        "avg",
1243                        "count",
1244                        "alert",
1245                        "annotations",
1246                    ]);
1247                    let ex = Expr::from(VectorSelector::from("some_metric"));
1248                    Expr::new_aggregate_expr(
1249                        token::T_SUM,
1250                        Some(modifier),
1251                        FunctionArgs::new_args(ex),
1252                    )
1253                },
1254            ),
1255            ("sum(sum)", {
1256                let ex = Expr::from(VectorSelector::from("sum"));
1257                Expr::new_aggregate_expr(token::T_SUM, None, FunctionArgs::new_args(ex))
1258            }),
1259            ("limitk by (group) (-1, http_requests)", {
1260                let ex = Expr::from(VectorSelector::from("http_requests"));
1261                let modifier = LabelModifier::include(vec!["group"]);
1262                let param = Expr::from(-1.0);
1263                let args = FunctionArgs::new_args(param).append_args(ex);
1264                Expr::new_aggregate_expr(token::T_LIMITK, Some(modifier), args)
1265            }),
1266            ("limitk by (group) (1, http_requests)", {
1267                let ex = Expr::from(VectorSelector::from("http_requests"));
1268                let modifier = LabelModifier::include(vec!["group"]);
1269                let param = Expr::from(1.0);
1270                let args = FunctionArgs::new_args(param).append_args(ex);
1271                Expr::new_aggregate_expr(token::T_LIMITK, Some(modifier), args)
1272            }),
1273            ("limit_ratio(-1.1, http_requests)", {
1274                let ex = Expr::from(VectorSelector::from("http_requests"));
1275                let param = Expr::from(-1.1);
1276                let args = FunctionArgs::new_args(param).append_args(ex);
1277                Expr::new_aggregate_expr(token::T_LIMIT_RATIO, None, args)
1278            }),
1279            ("limit_ratio(0.2, http_requests)", {
1280                let ex = Expr::from(VectorSelector::from("http_requests"));
1281                let param = Expr::from(0.2);
1282                let args = FunctionArgs::new_args(param).append_args(ex);
1283                Expr::new_aggregate_expr(token::T_LIMIT_RATIO, None, args)
1284            }),
1285        ];
1286        assert_cases(Case::new_result_cases(cases));
1287
1288        let fail_cases = vec![
1289            ("sum without(==)(some_metric)", INVALID_QUERY_INFO),
1290            ("sum without(,)(some_metric)", INVALID_QUERY_INFO),
1291            ("sum without(foo,,)(some_metric)", INVALID_QUERY_INFO),
1292            ("sum some_metric by (test)", INVALID_QUERY_INFO),
1293            ("sum (some_metric) by test", INVALID_QUERY_INFO),
1294            (
1295                "sum () by (test)",
1296                "no arguments for aggregate expression 'sum' provided",
1297            ),
1298            ("MIN keep_common (some_metric)", INVALID_QUERY_INFO),
1299            ("MIN (some_metric) keep_common", INVALID_QUERY_INFO),
1300            ("sum (some_metric) without (test) by (test)", INVALID_QUERY_INFO),
1301            ("sum without (test) (some_metric) by (test)", INVALID_QUERY_INFO),
1302            (
1303                "topk(some_metric)",
1304                "wrong number of arguments for aggregate expression provided, expected 2, got 1",
1305            ),
1306            (
1307                "topk(some_metric,)",
1308                "trailing commas not allowed in function call args",
1309            ),
1310            (
1311                "topk(some_metric, other_metric)",
1312                "expected type scalar in aggregation expression, got vector",
1313            ),
1314            (
1315                "count_values(5, other_metric)",
1316                "expected type string in aggregation expression, got scalar",
1317            ),
1318            (
1319                "rate(some_metric[5m]) @ 1234",
1320                "@ modifier must be preceded by an vector selector or matrix selector or a subquery"
1321            ),
1322        ];
1323        assert_cases(Case::new_fail_cases(fail_cases));
1324    }
1325
1326    #[test]
1327    fn test_function_call() {
1328        let cases = vec![
1329            (
1330                "time()",
1331                Expr::new_call(get_function("time").unwrap(), FunctionArgs::empty_args()),
1332            ),
1333            (r#"floor(some_metric{foo!="bar"})"#, {
1334                let name = String::from("some_metric");
1335                let matchers = Matchers::one(Matcher::new(MatchOp::NotEqual, "foo", "bar"));
1336                let ex = Expr::new_vector_selector(Some(name), matchers).unwrap();
1337                Expr::new_call(get_function("floor").unwrap(), FunctionArgs::new_args(ex))
1338            }),
1339            ("rate(some_metric[5m])", {
1340                Expr::new_matrix_selector(
1341                    Expr::from(VectorSelector::from("some_metric")),
1342                    duration::MINUTE_DURATION * 5,
1343                )
1344                .and_then(|ex| {
1345                    Expr::new_call(get_function("rate").unwrap(), FunctionArgs::new_args(ex))
1346                })
1347            }),
1348            ("round(some_metric)", {
1349                let ex = Expr::from(VectorSelector::from("some_metric"));
1350                Expr::new_call(get_function("round").unwrap(), FunctionArgs::new_args(ex))
1351            }),
1352            ("round(some_metric, 5)", {
1353                let ex = Expr::from(VectorSelector::from("some_metric"));
1354                Expr::new_call(
1355                    get_function("round").unwrap(),
1356                    FunctionArgs::new_args(ex).append_args(Expr::from(5.0)),
1357                )
1358            }),
1359            ("double_exponential_smoothing(some_metric[5m], 0.5, 0.1)", {
1360                Expr::new_matrix_selector(
1361                    Expr::from(VectorSelector::from("some_metric")),
1362                    duration::MINUTE_DURATION * 5,
1363                )
1364                .and_then(|ex| {
1365                    Expr::new_call(
1366                        get_function("double_exponential_smoothing").unwrap(),
1367                        FunctionArgs::new_args(ex)
1368                            .append_args(Expr::from(0.5))
1369                            .append_args(Expr::from(0.1)),
1370                    )
1371                })
1372            }),
1373            ("holt_winters(some_metric[5m], 0.5, 0.1)", {
1374                Expr::new_matrix_selector(
1375                    Expr::from(VectorSelector::from("some_metric")),
1376                    duration::MINUTE_DURATION * 5,
1377                )
1378                .and_then(|ex| {
1379                    Expr::new_call(
1380                        get_function("holt_winters").unwrap(),
1381                        FunctionArgs::new_args(ex)
1382                            .append_args(Expr::from(0.5))
1383                            .append_args(Expr::from(0.1)),
1384                    )
1385                })
1386            }),
1387            // cases from https://prometheus.io/docs/prometheus/latest/querying/functions
1388            (r#"absent(nonexistent{job="myjob"})"#, {
1389                let name = String::from("nonexistent");
1390                let matchers = Matchers::one(Matcher::new(MatchOp::Equal, "job", "myjob"));
1391                let ex = Expr::new_vector_selector(Some(name), matchers).unwrap();
1392                Expr::new_call(get_function("absent").unwrap(), FunctionArgs::new_args(ex))
1393            }),
1394            (r#"absent(nonexistent{job="myjob",instance=~".*"})"#, {
1395                let name = String::from("nonexistent");
1396                let matchers = Matchers::new(vec![
1397                    Matcher::new(MatchOp::Equal, "job", "myjob"),
1398                    Matcher::new(
1399                        MatchOp::Re(Regex::new("^(?:.*)$").unwrap()),
1400                        "instance",
1401                        ".*",
1402                    ),
1403                ]);
1404                Expr::new_vector_selector(Some(name), matchers).and_then(|ex| {
1405                    Expr::new_call(get_function("absent").unwrap(), FunctionArgs::new_args(ex))
1406                })
1407            }),
1408            (r#"absent(sum(nonexistent{job="myjob"}))"#, {
1409                let name = String::from("nonexistent");
1410                let matchers = Matchers::one(Matcher::new(MatchOp::Equal, "job", "myjob"));
1411                Expr::new_vector_selector(Some(name), matchers)
1412                    .and_then(|ex| {
1413                        Expr::new_aggregate_expr(token::T_SUM, None, FunctionArgs::new_args(ex))
1414                    })
1415                    .and_then(|ex| {
1416                        Expr::new_call(get_function("absent").unwrap(), FunctionArgs::new_args(ex))
1417                    })
1418            }),
1419            (r#"absent_over_time(nonexistent{job="myjob"}[1h])"#, {
1420                let name = String::from("nonexistent");
1421                let matchers = Matchers::one(Matcher::new(MatchOp::Equal, "job", "myjob"));
1422                Expr::new_vector_selector(Some(name), matchers)
1423                    .and_then(|ex| Expr::new_matrix_selector(ex, duration::HOUR_DURATION))
1424                    .and_then(|ex| {
1425                        Expr::new_call(
1426                            get_function("absent_over_time").unwrap(),
1427                            FunctionArgs::new_args(ex),
1428                        )
1429                    })
1430            }),
1431            (
1432                r#"absent_over_time(nonexistent{job="myjob",instance=~".*"}[1h])"#,
1433                {
1434                    let name = String::from("nonexistent");
1435                    let matchers = Matchers::new(vec![
1436                        Matcher::new(MatchOp::Equal, "job", "myjob"),
1437                        Matcher::new(
1438                            MatchOp::Re(Regex::new("^(?:.*)$").unwrap()),
1439                            "instance",
1440                            ".*",
1441                        ),
1442                    ]);
1443                    Expr::new_vector_selector(Some(name), matchers)
1444                        .and_then(|ex| Expr::new_matrix_selector(ex, duration::HOUR_DURATION))
1445                        .and_then(|ex| {
1446                            Expr::new_call(
1447                                get_function("absent_over_time").unwrap(),
1448                                FunctionArgs::new_args(ex),
1449                            )
1450                        })
1451                },
1452            ),
1453            (r#"delta(cpu_temp_celsius{host="zeus"}[2h])"#, {
1454                let name = String::from("cpu_temp_celsius");
1455                let matchers = Matchers::one(Matcher::new(MatchOp::Equal, "host", "zeus"));
1456                Expr::new_vector_selector(Some(name), matchers)
1457                    .and_then(|ex| Expr::new_matrix_selector(ex, duration::HOUR_DURATION * 2))
1458                    .and_then(|ex| {
1459                        Expr::new_call(get_function("delta").unwrap(), FunctionArgs::new_args(ex))
1460                    })
1461            }),
1462            (
1463                r#"histogram_count(rate(http_request_duration_seconds[10m]))"#,
1464                Expr::new_matrix_selector(
1465                    Expr::from(VectorSelector::from("http_request_duration_seconds")),
1466                    duration::MINUTE_DURATION * 10,
1467                )
1468                .and_then(|ex| {
1469                    Expr::new_call(get_function("rate").unwrap(), FunctionArgs::new_args(ex))
1470                })
1471                .and_then(|ex| {
1472                    Expr::new_call(
1473                        get_function("histogram_count").unwrap(),
1474                        FunctionArgs::new_args(ex),
1475                    )
1476                }),
1477            ),
1478            (
1479                r#"histogram_sum(rate(http_request_duration_seconds[10m])) / histogram_count(rate(http_request_duration_seconds[10m]))"#,
1480                {
1481                    let rate = Expr::new_matrix_selector(
1482                        Expr::from(VectorSelector::from("http_request_duration_seconds")),
1483                        duration::MINUTE_DURATION * 10,
1484                    )
1485                    .and_then(|ex| {
1486                        Expr::new_call(get_function("rate").unwrap(), FunctionArgs::new_args(ex))
1487                    })
1488                    .unwrap();
1489                    let lhs = Expr::new_call(
1490                        get_function("histogram_sum").unwrap(),
1491                        FunctionArgs::new_args(rate.clone()),
1492                    )
1493                    .unwrap();
1494                    let rhs = Expr::new_call(
1495                        get_function("histogram_count").unwrap(),
1496                        FunctionArgs::new_args(rate),
1497                    )
1498                    .unwrap();
1499                    Expr::new_binary_expr(lhs, token::T_DIV, None, rhs)
1500                },
1501            ),
1502            (
1503                r#"histogram_fraction(0, 0.2, rate(http_request_duration_seconds[1h]))"#,
1504                Expr::new_matrix_selector(
1505                    Expr::from(VectorSelector::from("http_request_duration_seconds")),
1506                    duration::HOUR_DURATION,
1507                )
1508                .and_then(|ex| {
1509                    Expr::new_call(get_function("rate").unwrap(), FunctionArgs::new_args(ex))
1510                })
1511                .and_then(|ex| {
1512                    Expr::new_call(
1513                        get_function("histogram_fraction").unwrap(),
1514                        FunctionArgs::new_args(Expr::from(0.0_f64))
1515                            .append_args(Expr::from(0.2))
1516                            .append_args(ex),
1517                    )
1518                }),
1519            ),
1520            (
1521                r#"histogram_avg(rate(http_request_duration_seconds[10m]))"#,
1522                Expr::new_matrix_selector(
1523                    Expr::from(VectorSelector::from("http_request_duration_seconds")),
1524                    duration::MINUTE_DURATION * 10,
1525                )
1526                .and_then(|ex| {
1527                    Expr::new_call(get_function("rate").unwrap(), FunctionArgs::new_args(ex))
1528                })
1529                .and_then(|ex| {
1530                    Expr::new_call(
1531                        get_function("histogram_avg").unwrap(),
1532                        FunctionArgs::new_args(ex),
1533                    )
1534                }),
1535            ),
1536            (
1537                r#"histogram_quantile(0.9, rate(http_request_duration_seconds_bucket[10m]))"#,
1538                Expr::new_matrix_selector(
1539                    Expr::from(VectorSelector::from("http_request_duration_seconds_bucket")),
1540                    duration::MINUTE_DURATION * 10,
1541                )
1542                .and_then(|ex| {
1543                    Expr::new_call(get_function("rate").unwrap(), FunctionArgs::new_args(ex))
1544                })
1545                .and_then(|ex| {
1546                    Expr::new_call(
1547                        get_function("histogram_quantile").unwrap(),
1548                        FunctionArgs::new_args(Expr::from(0.9_f64)).append_args(ex),
1549                    )
1550                }),
1551            ),
1552            (
1553                r#"histogram_quantile(0.9, sum by (job, le) (rate(http_request_duration_seconds_bucket[10m])))"#,
1554                Expr::new_matrix_selector(
1555                    Expr::from(VectorSelector::from("http_request_duration_seconds_bucket")),
1556                    duration::MINUTE_DURATION * 10,
1557                )
1558                .and_then(|ex| {
1559                    Expr::new_call(get_function("rate").unwrap(), FunctionArgs::new_args(ex))
1560                })
1561                .and_then(|ex| {
1562                    Expr::new_aggregate_expr(
1563                        token::T_SUM,
1564                        Some(LabelModifier::include(vec!["job", "le"])),
1565                        FunctionArgs::new_args(ex),
1566                    )
1567                })
1568                .and_then(|ex| {
1569                    Expr::new_call(
1570                        get_function("histogram_quantile").unwrap(),
1571                        FunctionArgs::new_args(Expr::from(0.9_f64)).append_args(ex),
1572                    )
1573                }),
1574            ),
1575            (
1576                r#"histogram_stddev(rate(http_request_duration_seconds[10m]))"#,
1577                Expr::new_matrix_selector(
1578                    Expr::from(VectorSelector::from("http_request_duration_seconds")),
1579                    duration::MINUTE_DURATION * 10,
1580                )
1581                .and_then(|ex| {
1582                    Expr::new_call(get_function("rate").unwrap(), FunctionArgs::new_args(ex))
1583                })
1584                .and_then(|ex| {
1585                    Expr::new_call(
1586                        get_function("histogram_stddev").unwrap(),
1587                        FunctionArgs::new_args(ex),
1588                    )
1589                }),
1590            ),
1591            (
1592                r#"histogram_stdvar(rate(http_request_duration_seconds[10m]))"#,
1593                Expr::new_matrix_selector(
1594                    Expr::from(VectorSelector::from("http_request_duration_seconds")),
1595                    duration::MINUTE_DURATION * 10,
1596                )
1597                .and_then(|ex| {
1598                    Expr::new_call(get_function("rate").unwrap(), FunctionArgs::new_args(ex))
1599                })
1600                .and_then(|ex| {
1601                    Expr::new_call(
1602                        get_function("histogram_stdvar").unwrap(),
1603                        FunctionArgs::new_args(ex),
1604                    )
1605                }),
1606            ),
1607            (r#"increase(http_requests_total{job="api-server"}[5m])"#, {
1608                let name = String::from("http_requests_total");
1609                let matchers = Matchers::one(Matcher::new(MatchOp::Equal, "job", "api-server"));
1610                Expr::new_vector_selector(Some(name), matchers)
1611                    .and_then(|ex| Expr::new_matrix_selector(ex, duration::MINUTE_DURATION * 5))
1612                    .and_then(|ex| {
1613                        Expr::new_call(
1614                            get_function("increase").unwrap(),
1615                            FunctionArgs::new_args(ex),
1616                        )
1617                    })
1618            }),
1619            (r#"irate(http_requests_total{job="api-server"}[5m])"#, {
1620                let name = String::from("http_requests_total");
1621                let matchers = Matchers::one(Matcher::new(MatchOp::Equal, "job", "api-server"));
1622                Expr::new_vector_selector(Some(name), matchers)
1623                    .and_then(|ex| Expr::new_matrix_selector(ex, duration::MINUTE_DURATION * 5))
1624                    .and_then(|ex| {
1625                        Expr::new_call(get_function("irate").unwrap(), FunctionArgs::new_args(ex))
1626                    })
1627            }),
1628            (
1629                r#"label_join(up{job="api-server",src1="a",src2="b",src3="c"}, "foo", ",", "src1", "src2", "src3")"#,
1630                {
1631                    let name = String::from("up");
1632                    let matchers = Matchers::new(vec![
1633                        Matcher::new(MatchOp::Equal, "job", "api-server"),
1634                        Matcher::new(MatchOp::Equal, "src1", "a"),
1635                        Matcher::new(MatchOp::Equal, "src2", "b"),
1636                        Matcher::new(MatchOp::Equal, "src3", "c"),
1637                    ]);
1638                    Expr::new_vector_selector(Some(name), matchers).and_then(|ex| {
1639                        Expr::new_call(
1640                            get_function("label_join").unwrap(),
1641                            FunctionArgs::new_args(ex)
1642                                .append_args(Expr::from("foo"))
1643                                .append_args(Expr::from(","))
1644                                .append_args(Expr::from("src1"))
1645                                .append_args(Expr::from("src2"))
1646                                .append_args(Expr::from("src3")),
1647                        )
1648                    })
1649                },
1650            ),
1651            (
1652                r#"label_replace(up{job="api-server",service="a:c"}, "foo", "$1", "service", "(.*):.*")"#,
1653                {
1654                    let name = String::from("up");
1655                    let matchers = Matchers::new(vec![
1656                        Matcher::new(MatchOp::Equal, "job", "api-server"),
1657                        Matcher::new(MatchOp::Equal, "service", "a:c"),
1658                    ]);
1659                    Expr::new_vector_selector(Some(name), matchers).and_then(|ex| {
1660                        Expr::new_call(
1661                            get_function("label_replace").unwrap(),
1662                            FunctionArgs::new_args(ex)
1663                                .append_args(Expr::from("foo"))
1664                                .append_args(Expr::from("$1"))
1665                                .append_args(Expr::from("service"))
1666                                .append_args(Expr::from("(.*):.*")),
1667                        )
1668                    })
1669                },
1670            ),
1671            (
1672                r#"sort_by_label(sum(up{job="api-server",src1="a",src2="b",src3="c"}) by (job), "src1","src2")"#,
1673                {
1674                    let name = String::from("up");
1675                    let matchers = Matchers::new(vec![
1676                        Matcher::new(MatchOp::Equal, "job", "api-server"),
1677                        Matcher::new(MatchOp::Equal, "src1", "a"),
1678                        Matcher::new(MatchOp::Equal, "src2", "b"),
1679                        Matcher::new(MatchOp::Equal, "src3", "c"),
1680                    ]);
1681
1682                    Expr::new_vector_selector(Some(name), matchers)
1683                        .and_then(|ex| {
1684                            let modifier = LabelModifier::include(vec!["job"]);
1685                            Expr::new_aggregate_expr(
1686                                token::T_SUM,
1687                                Some(modifier),
1688                                FunctionArgs::new_args(ex),
1689                            )
1690                        })
1691                        .and_then(|ex| {
1692                            Expr::new_call(
1693                                get_function("sort_by_label").unwrap(),
1694                                FunctionArgs::new_args(ex)
1695                                    .append_args(Expr::from("src1"))
1696                                    .append_args(Expr::from("src2")),
1697                            )
1698                        })
1699                },
1700            ),
1701            (
1702                r#"sort_by_label_desc(sum(up{job="api-server",src1="a",src2="b",src3="c"}) by (job), "src1","src2")"#,
1703                {
1704                    let name = String::from("up");
1705                    let matchers = Matchers::new(vec![
1706                        Matcher::new(MatchOp::Equal, "job", "api-server"),
1707                        Matcher::new(MatchOp::Equal, "src1", "a"),
1708                        Matcher::new(MatchOp::Equal, "src2", "b"),
1709                        Matcher::new(MatchOp::Equal, "src3", "c"),
1710                    ]);
1711
1712                    Expr::new_vector_selector(Some(name), matchers)
1713                        .and_then(|ex| {
1714                            let modifier = LabelModifier::include(vec!["job"]);
1715                            Expr::new_aggregate_expr(
1716                                token::T_SUM,
1717                                Some(modifier),
1718                                FunctionArgs::new_args(ex),
1719                            )
1720                        })
1721                        .and_then(|ex| {
1722                            Expr::new_call(
1723                                get_function("sort_by_label_desc").unwrap(),
1724                                FunctionArgs::new_args(ex)
1725                                    .append_args(Expr::from("src1"))
1726                                    .append_args(Expr::from("src2")),
1727                            )
1728                        })
1729                },
1730            ),
1731            // special cases
1732            (
1733                r#"exp(+Inf)"#,
1734                Expr::new_call(
1735                    get_function("exp").unwrap(),
1736                    FunctionArgs::new_args(Expr::from(f64::INFINITY)),
1737                ),
1738            ),
1739            (
1740                r#"exp(NaN)"#,
1741                Expr::new_call(
1742                    get_function("exp").unwrap(),
1743                    FunctionArgs::new_args(Expr::from(f64::NAN)),
1744                ),
1745            ),
1746            (
1747                r#"ln(+Inf)"#,
1748                Expr::new_call(
1749                    get_function("ln").unwrap(),
1750                    FunctionArgs::new_args(Expr::from(f64::INFINITY)),
1751                ),
1752            ),
1753            (
1754                r#"ln(NaN)"#,
1755                Expr::new_call(
1756                    get_function("ln").unwrap(),
1757                    FunctionArgs::new_args(Expr::from(f64::NAN)),
1758                ),
1759            ),
1760            (
1761                r#"ln(0)"#,
1762                Expr::new_call(
1763                    get_function("ln").unwrap(),
1764                    FunctionArgs::new_args(Expr::from(0.0)),
1765                ),
1766            ),
1767            (
1768                r#"ln(-1)"#,
1769                Expr::new_call(
1770                    get_function("ln").unwrap(),
1771                    FunctionArgs::new_args(Expr::from(-1.0)),
1772                ),
1773            ),
1774            (
1775                r#"log2(+Inf)"#,
1776                Expr::new_call(
1777                    get_function("log2").unwrap(),
1778                    FunctionArgs::new_args(Expr::from(f64::INFINITY)),
1779                ),
1780            ),
1781            (
1782                r#"log2(NaN)"#,
1783                Expr::new_call(
1784                    get_function("log2").unwrap(),
1785                    FunctionArgs::new_args(Expr::from(f64::NAN)),
1786                ),
1787            ),
1788            (
1789                r#"log2(0)"#,
1790                Expr::new_call(
1791                    get_function("log2").unwrap(),
1792                    FunctionArgs::new_args(Expr::from(0.0)),
1793                ),
1794            ),
1795            (
1796                r#"log2(-1)"#,
1797                Expr::new_call(
1798                    get_function("log2").unwrap(),
1799                    FunctionArgs::new_args(Expr::from(-1.0)),
1800                ),
1801            ),
1802            (
1803                r#"log10(+Inf)"#,
1804                Expr::new_call(
1805                    get_function("log10").unwrap(),
1806                    FunctionArgs::new_args(Expr::from(f64::INFINITY)),
1807                ),
1808            ),
1809            (
1810                r#"log10(NaN)"#,
1811                Expr::new_call(
1812                    get_function("log10").unwrap(),
1813                    FunctionArgs::new_args(Expr::from(f64::NAN)),
1814                ),
1815            ),
1816            (
1817                r#"log10(0)"#,
1818                Expr::new_call(
1819                    get_function("log10").unwrap(),
1820                    FunctionArgs::new_args(Expr::from(0.0)),
1821                ),
1822            ),
1823            (
1824                r#"log10(-1)"#,
1825                Expr::new_call(
1826                    get_function("log10").unwrap(),
1827                    FunctionArgs::new_args(Expr::from(-1.0)),
1828                ),
1829            ),
1830        ];
1831
1832        assert_cases(Case::new_result_cases(cases));
1833
1834        let fail_cases = vec![
1835            (
1836                "floor()",
1837                "expected 1 argument(s) in call to 'floor', got 0",
1838            ),
1839            (
1840                "floor(some_metric, other_metric)",
1841                "expected 1 argument(s) in call to 'floor', got 2",
1842            ),
1843            (
1844                "floor(some_metric, 1)",
1845                "expected 1 argument(s) in call to 'floor', got 2",
1846            ),
1847            (
1848                "floor(1)",
1849                "expected type vector in call to function 'floor', got scalar",
1850            ),
1851            (
1852                "hour(some_metric, some_metric, some_metric)",
1853                "expected at most 1 argument(s) in call to 'hour', got 3",
1854            ),
1855            (
1856                "time(some_metric)",
1857                "expected 0 argument(s) in call to 'time', got 1",
1858            ),
1859            (
1860                "non_existent_function_far_bar()",
1861                "unknown function with name 'non_existent_function_far_bar'",
1862            ),
1863            (
1864                "rate(some_metric)",
1865                "expected type matrix in call to function 'rate', got vector",
1866            ),
1867            (
1868                "ln(1)",
1869                "expected type vector in call to function 'ln', got scalar",
1870            ),
1871            ("ln()", "expected 1 argument(s) in call to 'ln', got 0"),
1872            (
1873                "exp(1)",
1874                "expected type vector in call to function 'exp', got scalar",
1875            ),
1876            ("exp()", "expected 1 argument(s) in call to 'exp', got 0"),
1877            (
1878                "label_join()",
1879                "expected at least 3 argument(s) in call to 'label_join', got 0",
1880            ),
1881            (
1882                "sort_by_label()",
1883                "expected at least 2 argument(s) in call to 'sort_by_label', got 0",
1884            ),
1885            (
1886                "sort_by_label_desc()",
1887                "expected at least 2 argument(s) in call to 'sort_by_label_desc', got 0",
1888            ),
1889            (
1890                "sort_by_label(sum(up) by (instance))",
1891                "expected at least 2 argument(s) in call to 'sort_by_label', got 1",
1892            ),
1893            (
1894                "sort_by_label_desc(sum(up) by (instance))",
1895                "expected at least 2 argument(s) in call to 'sort_by_label_desc', got 1",
1896            ),
1897            // (r#"label_replace(a, `b`, `c\xff`, `d`, `.*`)"#, ""),
1898        ];
1899        assert_cases(Case::new_fail_cases(fail_cases));
1900    }
1901
1902    #[test]
1903    fn test_subquery() {
1904        let cases = vec![
1905            (r#"foo{bar="baz"}[10m:6s]"#, {
1906                let matchers = Matchers::one(Matcher::new(MatchOp::Equal, "bar", "baz"));
1907                Expr::new_vector_selector(Some(String::from("foo")), matchers).and_then(|ex| {
1908                    Expr::new_subquery_expr(
1909                        ex,
1910                        duration::MINUTE_DURATION * 10,
1911                        Some(duration::SECOND_DURATION * 6),
1912                    )
1913                })
1914            }),
1915            (r#"foo{bar="baz"}[10m5s:1h6ms]"#, {
1916                let matchers = Matchers::one(Matcher::new(MatchOp::Equal, "bar", "baz"));
1917                Expr::new_vector_selector(Some(String::from("foo")), matchers).and_then(|ex| {
1918                    Expr::new_subquery_expr(
1919                        ex,
1920                        duration::MINUTE_DURATION * 10 + duration::SECOND_DURATION * 5,
1921                        Some(duration::HOUR_DURATION + duration::MILLI_DURATION * 6),
1922                    )
1923                })
1924            }),
1925            ("foo[10m:]", {
1926                let ex = Expr::from(VectorSelector::from("foo"));
1927                Expr::new_subquery_expr(ex, duration::MINUTE_DURATION * 10, None)
1928            }),
1929            (r#"min_over_time(rate(foo{bar="baz"}[2s])[5m:5s])"#, {
1930                let matchers = Matchers::one(Matcher::new(MatchOp::Equal, "bar", "baz"));
1931                Expr::new_vector_selector(Some(String::from("foo")), matchers)
1932                    .and_then(|ex| Expr::new_matrix_selector(ex, Duration::from_secs(2)))
1933                    .and_then(|ex| {
1934                        Expr::new_call(get_function("rate").unwrap(), FunctionArgs::new_args(ex))
1935                    })
1936                    .and_then(|ex| {
1937                        Expr::new_subquery_expr(
1938                            ex,
1939                            duration::MINUTE_DURATION * 5,
1940                            Some(Duration::from_secs(5)),
1941                        )
1942                    })
1943                    .and_then(|ex| {
1944                        Expr::new_call(
1945                            get_function("min_over_time").unwrap(),
1946                            FunctionArgs::new_args(ex),
1947                        )
1948                    })
1949            }),
1950            (r#"min_over_time(rate(foo{bar="baz"}[2s])[5m:])[4m:3s]"#, {
1951                let matchers = Matchers::one(Matcher::new(MatchOp::Equal, "bar", "baz"));
1952                Expr::new_vector_selector(Some(String::from("foo")), matchers)
1953                    .and_then(|ex| Expr::new_matrix_selector(ex, Duration::from_secs(2)))
1954                    .and_then(|ex| {
1955                        Expr::new_call(get_function("rate").unwrap(), FunctionArgs::new_args(ex))
1956                    })
1957                    .and_then(|ex| Expr::new_subquery_expr(ex, duration::MINUTE_DURATION * 5, None))
1958                    .and_then(|ex| {
1959                        Expr::new_call(
1960                            get_function("min_over_time").unwrap(),
1961                            FunctionArgs::new_args(ex),
1962                        )
1963                    })
1964                    .and_then(|ex| {
1965                        Expr::new_subquery_expr(
1966                            ex,
1967                            duration::MINUTE_DURATION * 4,
1968                            Some(Duration::from_secs(3)),
1969                        )
1970                    })
1971            }),
1972            (
1973                r#"min_over_time(rate(foo{bar="baz"}[2s])[5m:] offset 4m)[4m:3s]"#,
1974                {
1975                    let matchers = Matchers::one(Matcher::new(MatchOp::Equal, "bar", "baz"));
1976                    Expr::new_vector_selector(Some(String::from("foo")), matchers)
1977                        .and_then(|ex| Expr::new_matrix_selector(ex, Duration::from_secs(2)))
1978                        .and_then(|ex| {
1979                            Expr::new_call(
1980                                get_function("rate").unwrap(),
1981                                FunctionArgs::new_args(ex),
1982                            )
1983                        })
1984                        .and_then(|ex| {
1985                            Expr::new_subquery_expr(ex, duration::MINUTE_DURATION * 5, None)
1986                        })
1987                        .and_then(|ex| ex.offset_expr(Offset::Pos(duration::MINUTE_DURATION * 4)))
1988                        .and_then(|ex| {
1989                            Expr::new_call(
1990                                get_function("min_over_time").unwrap(),
1991                                FunctionArgs::new_args(ex),
1992                            )
1993                        })
1994                        .and_then(|ex| {
1995                            Expr::new_subquery_expr(
1996                                ex,
1997                                duration::MINUTE_DURATION * 4,
1998                                Some(Duration::from_secs(3)),
1999                            )
2000                        })
2001                },
2002            ),
2003            (
2004                r#"min_over_time(rate(foo{bar="baz"}[2s])[5m:] @ 1603775091)[4m:3s]"#,
2005                {
2006                    let matchers = Matchers::one(Matcher::new(MatchOp::Equal, "bar", "baz"));
2007                    Expr::new_vector_selector(Some(String::from("foo")), matchers)
2008                        .and_then(|ex| Expr::new_matrix_selector(ex, Duration::from_secs(2)))
2009                        .and_then(|ex| {
2010                            Expr::new_call(
2011                                get_function("rate").unwrap(),
2012                                FunctionArgs::new_args(ex),
2013                            )
2014                        })
2015                        .and_then(|ex| {
2016                            Expr::new_subquery_expr(ex, duration::MINUTE_DURATION * 5, None)
2017                        })
2018                        .and_then(|ex| ex.at_expr(At::try_from(1603775091_f64).unwrap()))
2019                        .and_then(|ex| {
2020                            Expr::new_call(
2021                                get_function("min_over_time").unwrap(),
2022                                FunctionArgs::new_args(ex),
2023                            )
2024                        })
2025                        .and_then(|ex| {
2026                            Expr::new_subquery_expr(
2027                                ex,
2028                                duration::MINUTE_DURATION * 4,
2029                                Some(Duration::from_secs(3)),
2030                            )
2031                        })
2032                },
2033            ),
2034            (
2035                r#"min_over_time(rate(foo{bar="baz"}[2s])[5m:] @ -160377509)[4m:3s]"#,
2036                {
2037                    let matchers = Matchers::one(Matcher::new(MatchOp::Equal, "bar", "baz"));
2038                    Expr::new_vector_selector(Some(String::from("foo")), matchers)
2039                        .and_then(|ex| Expr::new_matrix_selector(ex, Duration::from_secs(2)))
2040                        .and_then(|ex| {
2041                            Expr::new_call(
2042                                get_function("rate").unwrap(),
2043                                FunctionArgs::new_args(ex),
2044                            )
2045                        })
2046                        .and_then(|ex| {
2047                            Expr::new_subquery_expr(ex, duration::MINUTE_DURATION * 5, None)
2048                        })
2049                        .and_then(|ex| ex.at_expr(At::try_from(-160377509_f64).unwrap()))
2050                        .and_then(|ex| {
2051                            Expr::new_call(
2052                                get_function("min_over_time").unwrap(),
2053                                FunctionArgs::new_args(ex),
2054                            )
2055                        })
2056                        .and_then(|ex| {
2057                            Expr::new_subquery_expr(
2058                                ex,
2059                                duration::MINUTE_DURATION * 4,
2060                                Some(Duration::from_secs(3)),
2061                            )
2062                        })
2063                },
2064            ),
2065            (
2066                "sum without(and, by, avg, count, alert, annotations)(some_metric) [30m:10s]",
2067                {
2068                    let ex = Expr::from(VectorSelector::from("some_metric"));
2069                    Expr::new_aggregate_expr(
2070                        token::T_SUM,
2071                        Some(LabelModifier::exclude(vec![
2072                            "and",
2073                            "by",
2074                            "avg",
2075                            "count",
2076                            "alert",
2077                            "annotations",
2078                        ])),
2079                        FunctionArgs::new_args(ex),
2080                    )
2081                    .and_then(|ex| {
2082                        Expr::new_subquery_expr(
2083                            ex,
2084                            duration::MINUTE_DURATION * 30,
2085                            Some(Duration::from_secs(10)),
2086                        )
2087                    })
2088                },
2089            ),
2090            (
2091                "some_metric OFFSET 1m [10m:5s]",
2092                Expr::from(VectorSelector::from("some_metric"))
2093                    .offset_expr(Offset::Pos(duration::MINUTE_DURATION))
2094                    .and_then(|ex| {
2095                        Expr::new_subquery_expr(
2096                            ex,
2097                            duration::MINUTE_DURATION * 10,
2098                            Some(Duration::from_secs(5)),
2099                        )
2100                    }),
2101            ),
2102            (
2103                "some_metric @ 123 [10m:5s]",
2104                Expr::from(VectorSelector::from("some_metric"))
2105                    .at_expr(At::try_from(123_f64).unwrap())
2106                    .and_then(|ex| {
2107                        Expr::new_subquery_expr(
2108                            ex,
2109                            duration::MINUTE_DURATION * 10,
2110                            Some(Duration::from_secs(5)),
2111                        )
2112                    }),
2113            ),
2114            (
2115                "some_metric @ 123 offset 1m [10m:5s]",
2116                Expr::from(VectorSelector::from("some_metric"))
2117                    .at_expr(At::try_from(123_f64).unwrap())
2118                    .and_then(|ex| ex.offset_expr(Offset::Pos(duration::MINUTE_DURATION)))
2119                    .and_then(|ex| {
2120                        Expr::new_subquery_expr(
2121                            ex,
2122                            duration::MINUTE_DURATION * 10,
2123                            Some(Duration::from_secs(5)),
2124                        )
2125                    }),
2126            ),
2127            (
2128                "some_metric offset 1m @ 123 [10m:5s]",
2129                Expr::from(VectorSelector::from("some_metric"))
2130                    .at_expr(At::try_from(123_f64).unwrap())
2131                    .and_then(|ex| ex.offset_expr(Offset::Pos(duration::MINUTE_DURATION)))
2132                    .and_then(|ex| {
2133                        Expr::new_subquery_expr(
2134                            ex,
2135                            duration::MINUTE_DURATION * 10,
2136                            Some(Duration::from_secs(5)),
2137                        )
2138                    }),
2139            ),
2140            (
2141                "some_metric[10m:5s] offset 1m @ 123",
2142                Expr::new_subquery_expr(
2143                    Expr::from(VectorSelector::from("some_metric")),
2144                    duration::MINUTE_DURATION * 10,
2145                    Some(Duration::from_secs(5)),
2146                )
2147                .and_then(|ex| ex.at_expr(At::try_from(123_f64).unwrap()))
2148                .and_then(|ex| ex.offset_expr(Offset::Pos(duration::MINUTE_DURATION))),
2149            ),
2150            (r#"(foo + bar{nm="val"})[5m:]"#, {
2151                let matchers = Matchers::one(Matcher::new(MatchOp::Equal, "nm", "val"));
2152                Expr::new_binary_expr(
2153                    Expr::from(VectorSelector::from("foo")),
2154                    token::T_ADD,
2155                    None,
2156                    Expr::new_vector_selector(Some(String::from("bar")), matchers).unwrap(),
2157                )
2158                .and_then(Expr::new_paren_expr)
2159                .and_then(|ex| Expr::new_subquery_expr(ex, duration::MINUTE_DURATION * 5, None))
2160            }),
2161            (r#"(foo + bar{nm="val"})[5m:] offset 10m"#, {
2162                let matchers = Matchers::one(Matcher::new(MatchOp::Equal, "nm", "val"));
2163                Expr::new_binary_expr(
2164                    Expr::from(VectorSelector::from("foo")),
2165                    token::T_ADD,
2166                    None,
2167                    Expr::new_vector_selector(Some(String::from("bar")), matchers).unwrap(),
2168                )
2169                .and_then(Expr::new_paren_expr)
2170                .and_then(|ex| Expr::new_subquery_expr(ex, duration::MINUTE_DURATION * 5, None))
2171                .and_then(|ex| ex.offset_expr(Offset::Pos(duration::MINUTE_DURATION * 10)))
2172            }),
2173            (r#"(foo + bar{nm="val"} @ 1234)[5m:] @ 1603775019"#, {
2174                let matchers = Matchers::one(Matcher::new(MatchOp::Equal, "nm", "val"));
2175                let rhs = Expr::new_vector_selector(Some(String::from("bar")), matchers)
2176                    .and_then(|ex| ex.at_expr(At::try_from(1234_f64).unwrap()))
2177                    .unwrap();
2178
2179                Expr::new_binary_expr(
2180                    Expr::from(VectorSelector::from("foo")),
2181                    token::T_ADD,
2182                    None,
2183                    rhs,
2184                )
2185                .and_then(Expr::new_paren_expr)
2186                .and_then(|ex| Expr::new_subquery_expr(ex, duration::MINUTE_DURATION * 5, None))
2187                .and_then(|ex| ex.at_expr(At::try_from(1603775019_f64).unwrap()))
2188            }),
2189        ];
2190        assert_cases(Case::new_result_cases(cases));
2191
2192        let fail_cases = vec![
2193            (
2194                "test[5d] OFFSET 10s [10m:5s]",
2195                "subquery is only allowed on vector, got matrix instead",
2196            ),
2197            (
2198                r#"(foo + bar{nm="val"})[5m:][10m:5s]"#,
2199                "subquery is only allowed on vector, got matrix instead",
2200            ),
2201            (
2202                "rate(food[1m])[1h] offset 1h",
2203                "ranges only allowed for vector selectors",
2204            ),
2205            (
2206                "rate(food[1m])[1h] @ 100",
2207                "ranges only allowed for vector selectors",
2208            ),
2209        ];
2210        assert_cases(Case::new_fail_cases(fail_cases));
2211    }
2212
2213    #[test]
2214    fn test_preprocessors() {
2215        let cases = vec![
2216            (
2217                "foo @ start()",
2218                Expr::from(VectorSelector::from("foo")).at_expr(At::Start),
2219            ),
2220            (
2221                "foo @ end()",
2222                Expr::from(VectorSelector::from("foo")).at_expr(At::End),
2223            ),
2224            (
2225                "test[5y] @ start()",
2226                Expr::new_matrix_selector(
2227                    Expr::from(VectorSelector::from("test")),
2228                    duration::YEAR_DURATION * 5,
2229                )
2230                .and_then(|ex| ex.at_expr(At::Start)),
2231            ),
2232            (
2233                "test[5y] @ end()",
2234                Expr::new_matrix_selector(
2235                    Expr::from(VectorSelector::from("test")),
2236                    duration::YEAR_DURATION * 5,
2237                )
2238                .and_then(|ex| ex.at_expr(At::End)),
2239            ),
2240            (
2241                "foo[10m:6s] @ start()",
2242                Expr::new_subquery_expr(
2243                    Expr::from(VectorSelector::from("foo")),
2244                    duration::MINUTE_DURATION * 10,
2245                    Some(Duration::from_secs(6)),
2246                )
2247                .and_then(|ex| ex.at_expr(At::Start)),
2248            ),
2249            // Check that start and end functions do not mask metrics.
2250            ("start", Ok(Expr::from(VectorSelector::from("start")))),
2251            ("end", Ok(Expr::from(VectorSelector::from("end")))),
2252            (r#"start{end="foo"}"#, {
2253                let name = String::from("start");
2254                let matchers = Matchers::one(Matcher::new(MatchOp::Equal, "end", "foo"));
2255                Expr::new_vector_selector(Some(name), matchers)
2256            }),
2257            (r#"end{start="foo"}"#, {
2258                let name = String::from("end");
2259                let matchers = Matchers::one(Matcher::new(MatchOp::Equal, "start", "foo"));
2260                Expr::new_vector_selector(Some(name), matchers)
2261            }),
2262            ("foo unless on(start) bar", {
2263                let modifier = BinModifier::default()
2264                    .with_matching(Some(LabelModifier::include(vec!["start"])))
2265                    .with_card(VectorMatchCardinality::ManyToMany);
2266                Expr::new_binary_expr(
2267                    Expr::from(VectorSelector::from("foo")),
2268                    token::T_LUNLESS,
2269                    Some(modifier),
2270                    Expr::from(VectorSelector::from("bar")),
2271                )
2272            }),
2273            ("foo unless on(end) bar", {
2274                let modifier = BinModifier::default()
2275                    .with_matching(Some(LabelModifier::include(vec!["end"])))
2276                    .with_card(VectorMatchCardinality::ManyToMany);
2277                Expr::new_binary_expr(
2278                    Expr::from(VectorSelector::from("foo")),
2279                    token::T_LUNLESS,
2280                    Some(modifier),
2281                    Expr::from(VectorSelector::from("bar")),
2282                )
2283            }),
2284        ];
2285        assert_cases(Case::new_result_cases(cases));
2286
2287        let cases = vec![
2288            ("start()", INVALID_QUERY_INFO),
2289            ("end()", INVALID_QUERY_INFO),
2290        ];
2291        assert_cases(Case::new_fail_cases(cases));
2292    }
2293
2294    #[test]
2295    fn test_corner_fail_cases() {
2296        let fail_cases = vec![
2297            ("", "no expression found in input"),
2298            (
2299                "# just a comment\n\n",
2300                "no expression found in input",
2301            ),
2302            ("1+", INVALID_QUERY_INFO),
2303            (".", "unexpected character: '.'"),
2304            ("2.5.", "bad number or duration syntax: 2.5."),
2305            ("100..4", "bad number or duration syntax: 100.."),
2306            ("0deadbeef", "bad number or duration syntax: 0de"),
2307            ("1 /", INVALID_QUERY_INFO),
2308            ("*1", INVALID_QUERY_INFO),
2309            ("(1))", "unexpected right parenthesis ')'"),
2310            ("((1)", "unclosed left parenthesis"),
2311            ("(", "unclosed left parenthesis"),
2312            ("1 !~ 1", "unexpected character after '!': '~'"),
2313            ("1 =~ 1", "unexpected character after '=': '~'"),
2314            ("*test", INVALID_QUERY_INFO),
2315            (
2316                "1 offset 1d",
2317                "offset modifier must be preceded by an vector selector or matrix selector or a subquery"
2318            ),
2319            (
2320                "foo offset 1s offset 2s",
2321                "offset may not be set multiple times"
2322            ),
2323            ("a - on(b) ignoring(c) d", INVALID_QUERY_INFO),
2324
2325            // Fuzzing regression tests.
2326            ("-=", INVALID_QUERY_INFO),
2327            ("++-++-+-+-<", INVALID_QUERY_INFO),
2328            ("e-+=/(0)", INVALID_QUERY_INFO),
2329            ("a>b()", "unknown function with name 'b'"),
2330            (
2331                "rate(avg)",
2332                "expected type matrix in call to function 'rate', got vector"
2333            ),
2334        ];
2335        assert_cases(Case::new_fail_cases(fail_cases));
2336
2337        let fail_cases = vec![
2338            // This is testing that we are not re-rendering the expression string for each error, which would timeout.
2339            {
2340                let input = "(".to_string() + &"-{}-1".repeat(10_000) + ")" + &"[1m:]".repeat(1000);
2341                let expected =
2342                    Err("vector selector must contain at least one non-empty matcher".into());
2343                Case { input, expected }
2344            },
2345        ];
2346        assert_cases(fail_cases);
2347    }
2348
2349    #[test]
2350    fn test_or_filters() {
2351        let cases = vec![
2352            (r#"foo{label1="1" or label1="2"}"#, {
2353                let matchers = Matchers::new(vec![]).with_or_matchers(vec![
2354                    vec![Matcher::new(MatchOp::Equal, "label1", "1")],
2355                    vec![Matcher::new(MatchOp::Equal, "label1", "2")],
2356                ]);
2357                Expr::new_vector_selector(Some(String::from("foo")), matchers)
2358            }),
2359            (r#"foo{label1="1" OR label1="2"}"#, {
2360                let matchers = Matchers::new(vec![]).with_or_matchers(vec![
2361                    vec![Matcher::new(MatchOp::Equal, "label1", "1")],
2362                    vec![Matcher::new(MatchOp::Equal, "label1", "2")],
2363                ]);
2364                Expr::new_vector_selector(Some(String::from("foo")), matchers)
2365            }),
2366            (r#"foo{label1="1" Or label1="2"}"#, {
2367                let matchers = Matchers::new(vec![]).with_or_matchers(vec![
2368                    vec![Matcher::new(MatchOp::Equal, "label1", "1")],
2369                    vec![Matcher::new(MatchOp::Equal, "label1", "2")],
2370                ]);
2371                Expr::new_vector_selector(Some(String::from("foo")), matchers)
2372            }),
2373            (r#"foo{label1="1" oR label1="2"}"#, {
2374                let matchers = Matchers::new(vec![]).with_or_matchers(vec![
2375                    vec![Matcher::new(MatchOp::Equal, "label1", "1")],
2376                    vec![Matcher::new(MatchOp::Equal, "label1", "2")],
2377                ]);
2378                Expr::new_vector_selector(Some(String::from("foo")), matchers)
2379            }),
2380            (r#"foo{label1="1" or or="or"}"#, {
2381                let matchers = Matchers::new(vec![]).with_or_matchers(vec![
2382                    vec![Matcher::new(MatchOp::Equal, "label1", "1")],
2383                    vec![Matcher::new(MatchOp::Equal, "or", "or")],
2384                ]);
2385                Expr::new_vector_selector(Some(String::from("foo")), matchers)
2386            }),
2387            (
2388                r#"foo{label1="1" or label1="2" or label1="3" or label1="4"}"#,
2389                {
2390                    let matchers = Matchers::new(vec![]).with_or_matchers(vec![
2391                        vec![Matcher::new(MatchOp::Equal, "label1", "1")],
2392                        vec![Matcher::new(MatchOp::Equal, "label1", "2")],
2393                        vec![Matcher::new(MatchOp::Equal, "label1", "3")],
2394                        vec![Matcher::new(MatchOp::Equal, "label1", "4")],
2395                    ]);
2396                    Expr::new_vector_selector(Some(String::from("foo")), matchers)
2397                },
2398            ),
2399            (
2400                r#"foo{label1="1" or label1="2" or label1="3", label2="4"}"#,
2401                {
2402                    let matchers = Matchers::new(vec![]).with_or_matchers(vec![
2403                        vec![Matcher::new(MatchOp::Equal, "label1", "1")],
2404                        vec![Matcher::new(MatchOp::Equal, "label1", "2")],
2405                        vec![
2406                            Matcher::new(MatchOp::Equal, "label1", "3"),
2407                            Matcher::new(MatchOp::Equal, "label2", "4"),
2408                        ],
2409                    ]);
2410                    Expr::new_vector_selector(Some(String::from("foo")), matchers)
2411                },
2412            ),
2413            (
2414                r#"foo{label1="1", label2="2" or label1="3" or label1="4"}"#,
2415                {
2416                    let matchers = Matchers::new(vec![]).with_or_matchers(vec![
2417                        vec![
2418                            Matcher::new(MatchOp::Equal, "label1", "1"),
2419                            Matcher::new(MatchOp::Equal, "label2", "2"),
2420                        ],
2421                        vec![Matcher::new(MatchOp::Equal, "label1", "3")],
2422                        vec![Matcher::new(MatchOp::Equal, "label1", "4")],
2423                    ]);
2424                    Expr::new_vector_selector(Some(String::from("foo")), matchers)
2425                },
2426            ),
2427        ];
2428        assert_cases(Case::new_result_cases(cases));
2429
2430        let display_cases = [
2431            r#"a{label1="1"}"#,
2432            r#"a{label1="1" or label2="2"}"#,
2433            r#"a{label1="1" or label2="2" or label3="3" or label4="4"}"#,
2434            r#"a{label1="1", label2="2" or label3="3" or label4="4"}"#,
2435            r#"a{label1="1", label2="2" or label3="3", label4="4"}"#,
2436        ];
2437        display_cases
2438            .iter()
2439            .for_each(|expr| assert_eq!(parser::parse(expr).unwrap().to_string(), *expr));
2440
2441        let or_insensitive_cases = [
2442            r#"a{label1="1" or label2="2"}"#,
2443            r#"a{label1="1" OR label2="2"}"#,
2444            r#"a{label1="1" Or label2="2"}"#,
2445            r#"a{label1="1" oR label2="2"}"#,
2446        ];
2447
2448        or_insensitive_cases.iter().for_each(|expr| {
2449            assert_eq!(
2450                parser::parse(expr).unwrap().to_string(),
2451                r#"a{label1="1" or label2="2"}"#
2452            )
2453        });
2454
2455        let fail_cases = vec![
2456            (
2457                r#"foo{or}"#,
2458                r#"invalid label matcher, expected label matching operator after 'or'"#,
2459            ),
2460            (r#"foo{label1="1" or}"#, INVALID_QUERY_INFO),
2461            (r#"foo{or label1="1"}"#, INVALID_QUERY_INFO),
2462            (r#"foo{label1="1" or or label2="2"}"#, INVALID_QUERY_INFO),
2463        ];
2464        assert_cases(Case::new_fail_cases(fail_cases));
2465    }
2466
2467    #[test]
2468    fn test_prom3_string_identifier() {
2469        let case = r#"{"some.metric"}"#;
2470        assert_eq!(
2471            parser::parse(case).unwrap(),
2472            parser::parse(r#"{__name__="some.metric"}"#).unwrap()
2473        );
2474
2475        let case = r#"some_metric{"service.name"="api-server"}"#;
2476        assert_eq!(
2477            parser::parse(case).unwrap(),
2478            Expr::new_vector_selector(
2479                Some("some_metric".to_string()),
2480                Matchers::one(Matcher::new(MatchOp::Equal, "service.name", "api-server"))
2481            )
2482            .unwrap()
2483        );
2484
2485        let case = r#"sum by ("foo")(some_metric{})"#;
2486        assert_eq!(
2487            parser::parse(case).unwrap(),
2488            parser::parse(r#"sum by (foo)(some_metric{})"#).unwrap()
2489        );
2490
2491        let case = r#"test{host=~"10\\.0\\.160\\.237:808|nonexistence"}"#;
2492        parser::parse(case).unwrap();
2493        assert!(parser::parse(case).is_ok());
2494    }
2495}