promql_parser/parser/
function.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 std::collections::{HashMap, HashSet};
16use std::fmt;
17
18use lazy_static::lazy_static;
19
20use crate::parser::value::ValueType;
21use crate::parser::{Expr, Prettier};
22use crate::util::join_vector;
23
24/// called by func in Call
25#[derive(Debug, Clone, PartialEq, Eq)]
26#[cfg_attr(feature = "ser", derive(serde::Serialize))]
27pub struct FunctionArgs {
28    pub args: Vec<Box<Expr>>,
29}
30
31impl FunctionArgs {
32    pub fn empty_args() -> Self {
33        Self { args: vec![] }
34    }
35
36    pub fn new_args(expr: Expr) -> Self {
37        Self {
38            args: vec![Box::new(expr)],
39        }
40    }
41
42    pub fn append_args(mut self: FunctionArgs, expr: Expr) -> Self {
43        self.args.push(Box::new(expr));
44        self
45    }
46
47    pub fn is_empty(&self) -> bool {
48        self.args.is_empty()
49    }
50
51    pub fn len(&self) -> usize {
52        self.args.len()
53    }
54
55    pub fn first(&self) -> Option<Box<Expr>> {
56        self.args.first().cloned()
57    }
58
59    pub fn last(&self) -> Option<Box<Expr>> {
60        self.args.last().cloned()
61    }
62}
63
64impl fmt::Display for FunctionArgs {
65    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
66        write!(f, "{}", join_vector(&self.args, ", ", false))
67    }
68}
69
70impl Prettier for FunctionArgs {
71    fn pretty(&self, level: usize, max: usize) -> String {
72        let mut v = vec![];
73        for ex in &self.args {
74            v.push(ex.pretty(level, max));
75        }
76        v.join(",\n")
77    }
78}
79
80/// Functions is a list of all functions supported by PromQL, including their types.
81#[derive(Debug, Clone, PartialEq, Eq)]
82#[cfg_attr(feature = "ser", derive(serde::Serialize))]
83#[cfg_attr(feature = "ser", serde(rename_all = "camelCase"))]
84pub struct Function {
85    pub name: &'static str,
86    pub arg_types: Vec<ValueType>,
87    #[cfg_attr(
88        feature = "ser",
89        serde(serialize_with = "Function::serialize_variadic")
90    )]
91    pub variadic: bool,
92    pub return_type: ValueType,
93}
94
95impl Function {
96    pub fn new(
97        name: &'static str,
98        arg_types: Vec<ValueType>,
99        variadic: bool,
100        return_type: ValueType,
101    ) -> Self {
102        Self {
103            name,
104            arg_types,
105            variadic,
106            return_type,
107        }
108    }
109
110    #[cfg(feature = "ser")]
111    pub(crate) fn serialize_variadic<S>(variadic: &bool, serializer: S) -> Result<S::Ok, S::Error>
112    where
113        S: serde::Serializer,
114    {
115        if *variadic {
116            serializer.serialize_i8(1)
117        } else {
118            serializer.serialize_i8(0)
119        }
120    }
121}
122
123macro_rules! map {
124    // if variadic args, then the last is the variadic one
125    ($(($name:literal, $arg:expr, $ret:expr)),*) => (
126        {
127            let mut m: HashMap<&'static str, Function> = HashMap::new();
128            $(
129                let variadic = FUNCTIONS_WITH_VARIADIC_ARGS.contains($name);
130                let func = Function::new($name, $arg, variadic, $ret);
131                m.insert($name, func);
132            )*
133            m
134        }
135    );
136}
137
138lazy_static! {
139    static ref FUNCTIONS_WITH_VARIADIC_ARGS: HashSet<&'static str> = HashSet::from([
140        "days_in_month",
141        "day_of_year",
142        "day_of_month",
143        "day_of_week",
144        "year",
145        "month",
146        "hour",
147        "minute",
148        "label_join",
149        "sort_by_label",
150        "sort_by_label_desc",
151        "round",
152    ]);
153    static ref FUNCTIONS: HashMap<&'static str, Function> = map!(
154        ("abs", vec![ValueType::Vector], ValueType::Vector),
155        ("absent", vec![ValueType::Vector], ValueType::Vector),
156        (
157            "absent_over_time",
158            vec![ValueType::Matrix],
159            ValueType::Vector
160        ),
161        ("acos", vec![ValueType::Vector], ValueType::Vector),
162        ("acosh", vec![ValueType::Vector], ValueType::Vector),
163        ("asin", vec![ValueType::Vector], ValueType::Vector),
164        ("asinh", vec![ValueType::Vector], ValueType::Vector),
165        ("atan", vec![ValueType::Vector], ValueType::Vector),
166        ("atanh", vec![ValueType::Vector], ValueType::Vector),
167        ("avg_over_time", vec![ValueType::Matrix], ValueType::Vector),
168        ("ceil", vec![ValueType::Vector], ValueType::Vector),
169        ("changes", vec![ValueType::Matrix], ValueType::Vector),
170        (
171            "clamp",
172            vec![ValueType::Vector, ValueType::Scalar, ValueType::Scalar],
173            ValueType::Vector
174        ),
175        (
176            "clamp_max",
177            vec![ValueType::Vector, ValueType::Scalar],
178            ValueType::Vector
179        ),
180        (
181            "clamp_min",
182            vec![ValueType::Vector, ValueType::Scalar],
183            ValueType::Vector
184        ),
185        ("cos", vec![ValueType::Vector], ValueType::Vector),
186        ("cosh", vec![ValueType::Vector], ValueType::Vector),
187        (
188            "count_over_time",
189            vec![ValueType::Matrix],
190            ValueType::Vector
191        ),
192        ("days_in_month", vec![ValueType::Vector], ValueType::Vector),
193        ("day_of_month", vec![ValueType::Vector], ValueType::Vector),
194        ("day_of_week", vec![ValueType::Vector], ValueType::Vector),
195        ("day_of_year", vec![ValueType::Vector], ValueType::Vector),
196        ("deg", vec![ValueType::Vector], ValueType::Vector),
197        ("delta", vec![ValueType::Matrix], ValueType::Vector),
198        ("deriv", vec![ValueType::Matrix], ValueType::Vector),
199        ("exp", vec![ValueType::Vector], ValueType::Vector),
200        ("floor", vec![ValueType::Vector], ValueType::Vector),
201        (
202            "histogram_count",
203            vec![ValueType::Vector],
204            ValueType::Vector
205        ),
206        ("histogram_sum", vec![ValueType::Vector], ValueType::Vector),
207        (
208            "histogram_fraction",
209            vec![ValueType::Scalar, ValueType::Scalar, ValueType::Vector],
210            ValueType::Vector
211        ),
212        (
213            "histogram_quantile",
214            vec![ValueType::Scalar, ValueType::Vector],
215            ValueType::Vector
216        ),
217        (
218            "holt_winters",
219            vec![ValueType::Matrix, ValueType::Scalar, ValueType::Scalar],
220            ValueType::Vector
221        ),
222        ("hour", vec![ValueType::Vector], ValueType::Vector),
223        ("idelta", vec![ValueType::Matrix], ValueType::Vector),
224        ("increase", vec![ValueType::Matrix], ValueType::Vector),
225        ("irate", vec![ValueType::Matrix], ValueType::Vector),
226        (
227            "label_replace",
228            vec![
229                ValueType::Vector,
230                ValueType::String,
231                ValueType::String,
232                ValueType::String,
233                ValueType::String,
234            ],
235            ValueType::Vector
236        ),
237        (
238            "label_join",
239            vec![
240                ValueType::Vector,
241                ValueType::String,
242                ValueType::String,
243                ValueType::String,
244            ],
245            ValueType::Vector
246        ),
247        ("last_over_time", vec![ValueType::Matrix], ValueType::Vector),
248        ("ln", vec![ValueType::Vector], ValueType::Vector),
249        ("log10", vec![ValueType::Vector], ValueType::Vector),
250        ("log2", vec![ValueType::Vector], ValueType::Vector),
251        ("max_over_time", vec![ValueType::Matrix], ValueType::Vector),
252        ("min_over_time", vec![ValueType::Matrix], ValueType::Vector),
253        ("minute", vec![ValueType::Vector], ValueType::Vector),
254        ("month", vec![ValueType::Vector], ValueType::Vector),
255        ("pi", vec![], ValueType::Scalar),
256        (
257            "predict_linear",
258            vec![ValueType::Matrix, ValueType::Scalar],
259            ValueType::Vector
260        ),
261        (
262            "present_over_time",
263            vec![ValueType::Matrix],
264            ValueType::Vector
265        ),
266        (
267            "quantile_over_time",
268            vec![ValueType::Scalar, ValueType::Matrix],
269            ValueType::Vector
270        ),
271        ("rad", vec![ValueType::Vector], ValueType::Vector),
272        ("rate", vec![ValueType::Matrix], ValueType::Vector),
273        ("resets", vec![ValueType::Matrix], ValueType::Vector),
274        (
275            "round",
276            vec![ValueType::Vector, ValueType::Scalar],
277            ValueType::Vector
278        ),
279        ("scalar", vec![ValueType::Vector], ValueType::Scalar),
280        ("sgn", vec![ValueType::Vector], ValueType::Vector),
281        ("sin", vec![ValueType::Vector], ValueType::Vector),
282        ("sinh", vec![ValueType::Vector], ValueType::Vector),
283        ("sort", vec![ValueType::Vector], ValueType::Vector),
284        ("sort_desc", vec![ValueType::Vector], ValueType::Vector),
285        (
286            "sort_by_label",
287            vec![ValueType::Vector, ValueType::String, ValueType::String],
288            ValueType::Vector
289        ),
290        (
291            "sort_by_label_desc",
292            vec![ValueType::Vector, ValueType::String, ValueType::String],
293            ValueType::Vector
294        ),
295        ("sqrt", vec![ValueType::Vector], ValueType::Vector),
296        (
297            "stddev_over_time",
298            vec![ValueType::Matrix],
299            ValueType::Vector
300        ),
301        (
302            "stdvar_over_time",
303            vec![ValueType::Matrix],
304            ValueType::Vector
305        ),
306        ("sum_over_time", vec![ValueType::Matrix], ValueType::Vector),
307        ("tan", vec![ValueType::Vector], ValueType::Vector),
308        ("tanh", vec![ValueType::Vector], ValueType::Vector),
309        ("time", vec![], ValueType::Scalar),
310        ("timestamp", vec![ValueType::Vector], ValueType::Vector),
311        ("vector", vec![ValueType::Scalar], ValueType::Vector),
312        ("year", vec![ValueType::Vector], ValueType::Vector)
313    );
314}
315
316/// get_function returns a predefined Function object for the given name.
317pub(crate) fn get_function(name: &str) -> Option<Function> {
318    FUNCTIONS.get(name).cloned()
319}
320
321#[cfg(test)]
322mod tests {
323    use super::*;
324    use crate::parser::*;
325
326    #[test]
327    fn test_function_equality() {
328        let func = "month";
329        assert!(get_function(func).is_some());
330        assert_eq!(get_function(func), get_function(func));
331    }
332
333    #[test]
334    fn test_function_args_equality() {
335        assert_eq!(FunctionArgs::empty_args(), FunctionArgs::empty_args());
336
337        let arg1 = Expr::NumberLiteral(NumberLiteral::new(1.0));
338        let arg2 = Expr::StringLiteral(StringLiteral {
339            val: "prometheus".into(),
340        });
341        let args1 = FunctionArgs::new_args(arg1).append_args(arg2);
342
343        let arg1 = Expr::NumberLiteral(NumberLiteral::new(0.5 + 0.5));
344        let arg2 = Expr::StringLiteral(StringLiteral {
345            val: String::from("prometheus"),
346        });
347        let args2 = FunctionArgs::new_args(arg1).append_args(arg2);
348
349        assert_eq!(args1, args2);
350    }
351
352    #[test]
353    fn test_args_display() {
354        let cases = vec![
355            (
356                FunctionArgs::new_args(Expr::from(VectorSelector::from("up"))),
357                "up",
358            ),
359            (
360                FunctionArgs::empty_args()
361                    .append_args(Expr::from("src1"))
362                    .append_args(Expr::from("src2"))
363                    .append_args(Expr::from("src3")),
364                r#""src1", "src2", "src3""#,
365            ),
366        ];
367
368        for (args, expect) in cases {
369            assert_eq!(expect, args.to_string())
370        }
371    }
372}