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        ("histogram_avg", vec![ValueType::Vector], ValueType::Vector),
208        (
209            "histogram_fraction",
210            vec![ValueType::Scalar, ValueType::Scalar, ValueType::Vector],
211            ValueType::Vector
212        ),
213        (
214            "histogram_quantile",
215            vec![ValueType::Scalar, ValueType::Vector],
216            ValueType::Vector
217        ),
218        (
219            "holt_winters",
220            vec![ValueType::Matrix, ValueType::Scalar, ValueType::Scalar],
221            ValueType::Vector
222        ),
223        ("hour", vec![ValueType::Vector], ValueType::Vector),
224        ("idelta", vec![ValueType::Matrix], ValueType::Vector),
225        ("increase", vec![ValueType::Matrix], ValueType::Vector),
226        ("irate", vec![ValueType::Matrix], ValueType::Vector),
227        (
228            "label_replace",
229            vec![
230                ValueType::Vector,
231                ValueType::String,
232                ValueType::String,
233                ValueType::String,
234                ValueType::String,
235            ],
236            ValueType::Vector
237        ),
238        (
239            "label_join",
240            vec![
241                ValueType::Vector,
242                ValueType::String,
243                ValueType::String,
244                ValueType::String,
245            ],
246            ValueType::Vector
247        ),
248        ("last_over_time", vec![ValueType::Matrix], ValueType::Vector),
249        ("ln", vec![ValueType::Vector], ValueType::Vector),
250        ("log10", vec![ValueType::Vector], ValueType::Vector),
251        ("log2", vec![ValueType::Vector], ValueType::Vector),
252        ("max_over_time", vec![ValueType::Matrix], ValueType::Vector),
253        ("min_over_time", vec![ValueType::Matrix], ValueType::Vector),
254        ("minute", vec![ValueType::Vector], ValueType::Vector),
255        ("month", vec![ValueType::Vector], ValueType::Vector),
256        ("pi", vec![], ValueType::Scalar),
257        (
258            "predict_linear",
259            vec![ValueType::Matrix, ValueType::Scalar],
260            ValueType::Vector
261        ),
262        (
263            "present_over_time",
264            vec![ValueType::Matrix],
265            ValueType::Vector
266        ),
267        (
268            "quantile_over_time",
269            vec![ValueType::Scalar, ValueType::Matrix],
270            ValueType::Vector
271        ),
272        ("rad", vec![ValueType::Vector], ValueType::Vector),
273        ("rate", vec![ValueType::Matrix], ValueType::Vector),
274        ("resets", vec![ValueType::Matrix], ValueType::Vector),
275        (
276            "round",
277            vec![ValueType::Vector, ValueType::Scalar],
278            ValueType::Vector
279        ),
280        ("scalar", vec![ValueType::Vector], ValueType::Scalar),
281        ("sgn", vec![ValueType::Vector], ValueType::Vector),
282        ("sin", vec![ValueType::Vector], ValueType::Vector),
283        ("sinh", vec![ValueType::Vector], ValueType::Vector),
284        ("sort", vec![ValueType::Vector], ValueType::Vector),
285        ("sort_desc", vec![ValueType::Vector], ValueType::Vector),
286        (
287            "sort_by_label",
288            vec![ValueType::Vector, ValueType::String, ValueType::String],
289            ValueType::Vector
290        ),
291        (
292            "sort_by_label_desc",
293            vec![ValueType::Vector, ValueType::String, ValueType::String],
294            ValueType::Vector
295        ),
296        ("sqrt", vec![ValueType::Vector], ValueType::Vector),
297        (
298            "stddev_over_time",
299            vec![ValueType::Matrix],
300            ValueType::Vector
301        ),
302        (
303            "stdvar_over_time",
304            vec![ValueType::Matrix],
305            ValueType::Vector
306        ),
307        ("sum_over_time", vec![ValueType::Matrix], ValueType::Vector),
308        ("tan", vec![ValueType::Vector], ValueType::Vector),
309        ("tanh", vec![ValueType::Vector], ValueType::Vector),
310        ("time", vec![], ValueType::Scalar),
311        ("timestamp", vec![ValueType::Vector], ValueType::Vector),
312        ("vector", vec![ValueType::Scalar], ValueType::Vector),
313        ("year", vec![ValueType::Vector], ValueType::Vector)
314    );
315}
316
317/// get_function returns a predefined Function object for the given name.
318pub(crate) fn get_function(name: &str) -> Option<Function> {
319    FUNCTIONS.get(name).cloned()
320}
321
322#[cfg(test)]
323mod tests {
324    use super::*;
325    use crate::parser::*;
326
327    #[test]
328    fn test_function_equality() {
329        let func = "month";
330        assert!(get_function(func).is_some());
331        assert_eq!(get_function(func), get_function(func));
332    }
333
334    #[test]
335    fn test_function_args_equality() {
336        assert_eq!(FunctionArgs::empty_args(), FunctionArgs::empty_args());
337
338        let arg1 = Expr::NumberLiteral(NumberLiteral::new(1.0));
339        let arg2 = Expr::StringLiteral(StringLiteral {
340            val: "prometheus".into(),
341        });
342        let args1 = FunctionArgs::new_args(arg1).append_args(arg2);
343
344        let arg1 = Expr::NumberLiteral(NumberLiteral::new(0.5 + 0.5));
345        let arg2 = Expr::StringLiteral(StringLiteral {
346            val: String::from("prometheus"),
347        });
348        let args2 = FunctionArgs::new_args(arg1).append_args(arg2);
349
350        assert_eq!(args1, args2);
351    }
352
353    #[test]
354    fn test_args_display() {
355        let cases = vec![
356            (
357                FunctionArgs::new_args(Expr::from(VectorSelector::from("up"))),
358                "up",
359            ),
360            (
361                FunctionArgs::empty_args()
362                    .append_args(Expr::from("src1"))
363                    .append_args(Expr::from("src2"))
364                    .append_args(Expr::from("src3")),
365                r#""src1", "src2", "src3""#,
366            ),
367        ];
368
369        for (args, expect) in cases {
370            assert_eq!(expect, args.to_string())
371        }
372    }
373}