promql_rs/
ast.rs

1use std::{str::FromStr, time::Duration};
2
3use crate::function::*;
4
5/// The enumaration of all expression types.
6#[derive(Debug)]
7pub enum Expr {
8    AggregateExpr(AggregateExpr),
9    BinaryExpr(BinaryExpr),
10    FunctionCall(FunctionCall),
11    MatrixSelector(MatrixSelector),
12    SubqueryExpr(SubqueryExpr),
13    NumberLiteral(NumberLiteral),
14    ParenExpr(ParenExpr),
15    StringLiteral(StringLiteral),
16    UnaryExpr(UnaryExpr),
17    VectorSelector(VectorSelector),
18}
19
20impl Expr {
21    /// Returns the [`ValueType`] that the expression evaluates to. Normally,
22    /// an expression evaluates to a fixed value type. However, in the case of
23    /// [`BinaryExpr`], the value type depends on the value types of its two
24    /// operands. If both operands are scalars, the expression evaluates to a
25    /// scalar. Otherwise, it evaluates to a vector.
26    ///
27    /// For more information, see
28    /// <https://prometheus.io/docs/prometheus/latest/querying/basics/#expression-types>.
29    pub fn get_type(&self) -> ValueType {
30        match self {
31            Expr::AggregateExpr(_) => ValueType::Vector,
32            Expr::FunctionCall(call) => call.func.return_type,
33            Expr::MatrixSelector(_) => ValueType::Matrix,
34            Expr::SubqueryExpr(_) => ValueType::Matrix,
35            Expr::NumberLiteral(_) => ValueType::Scalar,
36            Expr::ParenExpr(p) => p.expr.get_type(),
37            Expr::StringLiteral(_) => ValueType::String,
38            Expr::UnaryExpr(u) => u.rhs.get_type(),
39            Expr::VectorSelector(_) => ValueType::Vector,
40            Expr::BinaryExpr(b) => {
41                if b.lhs.get_type() == ValueType::Scalar && b.rhs.get_type() == ValueType::Scalar {
42                    ValueType::Scalar
43                } else {
44                    ValueType::Vector
45                }
46            }
47        }
48    }
49}
50
51/// The enumaration of all value types.
52#[derive(Debug, Clone, Copy, PartialEq)]
53pub enum ValueType {
54    /// A set of time series containing a single sample for each time series,
55    /// all sharing the same timestamp.
56    Vector,
57    /// Also called a range vector, a set of time series containing a range of
58    /// data points over time for each time series.
59    Matrix,
60    /// A simple numeric floating point value.
61    Scalar,
62    /// A simple string value.
63    String,
64}
65
66/// Aggregation operators can be used to aggregate the elements of a single
67/// vector, resulting in a new vector of fewer elements with aggregated values.
68#[derive(Debug, PartialEq)]
69pub enum AggregateOp {
70    /// Calculate the average over dimensions.
71    Avg,
72    /// Smallest k elements by sample value.
73    Bottomk,
74    /// Count number of elements in the vector.
75    Count,
76    /// Count number of elements with the same value.
77    CountValues,
78    /// All values in the resulting vector are 1.
79    Group,
80    /// Select maximum over dimensions.
81    Max,
82    /// Select minimum over dimensions.
83    Min,
84    /// Calculate polulation standard deviation over dimensions.
85    Stddev,
86    /// Calculate population sstandard variance over dimensions.
87    Stdvar,
88    /// Calculate φ-quantile (0 ≤ φ ≤ 1) over dimensions.
89    Quantile,
90    /// Calculate sum over dimensions.
91    Sum,
92    /// Largest k elements by sample value.
93    Topk,
94}
95
96impl FromStr for AggregateOp {
97    type Err = String;
98
99    fn from_str(s: &str) -> Result<Self, Self::Err> {
100        match s {
101            "avg" => Ok(AggregateOp::Avg),
102            "bottomk" => Ok(AggregateOp::Bottomk),
103            "count" => Ok(AggregateOp::Count),
104            "count_values" => Ok(AggregateOp::CountValues),
105            "group" => Ok(AggregateOp::Group),
106            "max" => Ok(AggregateOp::Max),
107            "min" => Ok(AggregateOp::Min),
108            "stddev" => Ok(AggregateOp::Stddev),
109            "stdvar" => Ok(AggregateOp::Stdvar),
110            "quantile" => Ok(AggregateOp::Quantile),
111            "sum" => Ok(AggregateOp::Sum),
112            "topk" => Ok(AggregateOp::Topk),
113            _ => Err(format!("Unknown aggregate operator: {}", s)),
114        }
115    }
116}
117
118/// The aggregation modifier can be used to indicate the aggregation operators
119/// to use or exclude certain dimensions.
120#[derive(Debug, PartialEq)]
121pub enum AggregateModifier {
122    None,
123    /// The `by` modifier drops labels that are not listed.
124    By(Vec<String>),
125    /// The `without` modifier removes the listed labels from the result vector.
126    /// All other labels are preserved.
127    Without(Vec<String>),
128}
129
130impl Default for AggregateModifier {
131    fn default() -> Self {
132        AggregateModifier::None
133    }
134}
135
136impl AggregateModifier {
137    pub fn from_str_and_vec(s: &str, v: Vec<String>) -> Result<Self, String> {
138        match s {
139            "by" => Ok(AggregateModifier::By(v)),
140            "without" => Ok(AggregateModifier::Without(v)),
141            _ => Err(format!("Unknown aggregate modifier: {}", s)),
142        }
143    }
144}
145
146/// An aggregation expression.
147#[derive(Debug)]
148pub struct AggregateExpr {
149    pub op: AggregateOp,
150    pub expr: Box<Expr>,
151    /// The `param` is only required for `count_values`, `quantile`, `topk`,
152    /// and `bottomk`.
153    pub param: Option<Box<Expr>>,
154    pub modifier: AggregateModifier,
155}
156
157/// Binary operators can do logical and arithmetic operations or comparisons.
158#[derive(Debug, PartialEq)]
159pub enum BinaryOp {
160    /// Addition.
161    Add,
162    /// Subtraction.
163    Sub,
164    /// Multiplication.
165    Mul,
166    /// Division.
167    Div,
168    /// Modulo.
169    Mod,
170    /// Exponentiation.
171    Pow,
172    /// Equal.
173    Eq,
174    /// Not equal.
175    Ne,
176    /// Greater than.
177    Gt,
178    /// Less than.
179    Lt,
180    /// Greater than or equal.
181    Ge,
182    /// Less than or equal.
183    Le,
184    /// Logical and (intersection).
185    And,
186    /// Logical or (union).
187    Or,
188    /// Logical unless (complement).
189    Unless,
190    /// Arc tangent.
191    Atan2,
192}
193
194impl FromStr for BinaryOp {
195    type Err = String;
196
197    fn from_str(s: &str) -> Result<Self, Self::Err> {
198        match s {
199            "+" => Ok(BinaryOp::Add),
200            "-" => Ok(BinaryOp::Sub),
201            "*" => Ok(BinaryOp::Mul),
202            "/" => Ok(BinaryOp::Div),
203            "%" => Ok(BinaryOp::Mod),
204            "^" => Ok(BinaryOp::Pow),
205            "==" => Ok(BinaryOp::Eq),
206            "!=" => Ok(BinaryOp::Ne),
207            ">" => Ok(BinaryOp::Gt),
208            "<" => Ok(BinaryOp::Lt),
209            ">=" => Ok(BinaryOp::Ge),
210            "<=" => Ok(BinaryOp::Le),
211            "and" => Ok(BinaryOp::And),
212            "or" => Ok(BinaryOp::Or),
213            "unless" => Ok(BinaryOp::Unless),
214            "atan2" => Ok(BinaryOp::Atan2),
215            _ => Err(format!("Unknown binary operator: {}", s)),
216        }
217    }
218}
219
220/// Describes the cardinality relashionship of two vectors in a binary
221/// operation.
222#[derive(Debug, PartialEq)]
223pub enum VectorMatchCardinality {
224    OneToOne,
225    OneToMany,
226    ManyToOne,
227    ManyToMany,
228}
229
230impl Default for VectorMatchCardinality {
231    fn default() -> Self {
232        VectorMatchCardinality::OneToOne
233    }
234}
235
236impl VectorMatchCardinality {
237    pub fn from_str(s: &str) -> Result<Self, String> {
238        match s {
239            "group_right" => Ok(VectorMatchCardinality::OneToMany),
240            "group_left" => Ok(VectorMatchCardinality::ManyToOne),
241            _ => Err(format!("Unknown vector match cardinality: {}", s)),
242        }
243    }
244}
245
246/// Describes how two vectors in a binary operation are supposed to be grouped.
247#[derive(Debug, PartialEq)]
248pub enum VectorMatchGrouping {
249    None,
250    On(Vec<String>),
251    Ignoring(Vec<String>),
252}
253
254impl Default for VectorMatchGrouping {
255    fn default() -> Self {
256        VectorMatchGrouping::None
257    }
258}
259
260impl VectorMatchGrouping {
261    pub fn from_str_and_vec(s: &str, v: Vec<String>) -> Result<Self, String> {
262        match s {
263            "on" => Ok(VectorMatchGrouping::On(v)),
264            "ignoring" => Ok(VectorMatchGrouping::Ignoring(v)),
265            _ => Err(format!("Unknown vector match grouping: {}", s)),
266        }
267    }
268}
269
270/// Describes how elements from two vectors in a binary operation are supposed
271/// to be matched.
272#[derive(Debug, PartialEq)]
273pub struct VectorMatching {
274    pub cardinality: VectorMatchCardinality,
275    pub grouping: VectorMatchGrouping,
276    pub include: Vec<String>,
277}
278
279impl Default for VectorMatching {
280    fn default() -> Self {
281        VectorMatching {
282            cardinality: VectorMatchCardinality::default(),
283            grouping: VectorMatchGrouping::default(),
284            include: Vec::new(),
285        }
286    }
287}
288
289/// A binary expression.
290#[derive(Debug)]
291pub struct BinaryExpr {
292    pub op: BinaryOp,
293    pub lhs: Box<Expr>,
294    pub rhs: Box<Expr>,
295    /// If a comparison operator, return `0` or `1` rather than filtering.
296    pub return_bool: bool,
297    /// The matching behavior for the oepration if both operands are vectors.
298    pub vector_matching: VectorMatching,
299}
300
301/// A function call expression.
302#[derive(Debug)]
303pub struct FunctionCall {
304    pub func: &'static Function,
305    pub args: Vec<Expr>,
306}
307
308/// A matrix selector expression.
309#[derive(Debug)]
310pub struct MatrixSelector {
311    pub vector_selector: Box<Expr>,
312    pub range: Duration,
313}
314
315/// The `@` modifier allows changing the evaluation time for individual instant
316/// and range vectors in a query. The time supplied is a UNIX timestamp or
317/// `start()`/`end()`.
318#[derive(Debug, PartialEq)]
319pub enum AtModifier {
320    None,
321    Start,
322    End,
323    Timestamp(u64),
324}
325
326/// A subquery expression.
327#[derive(Debug)]
328pub struct SubqueryExpr {
329    pub expr: Box<Expr>,
330    pub range: Duration,
331    pub step: Duration,
332    pub offset: Duration,
333    pub at: AtModifier,
334}
335
336/// Number literals can be written as literal integer (octal, decimal, or
337/// hexadecimal) or floating-point numbers.
338#[derive(Debug)]
339pub struct NumberLiteral {
340    pub value: f64,
341}
342
343/// A paren expression.
344#[derive(Debug)]
345pub struct ParenExpr {
346    pub expr: Box<Expr>,
347}
348
349/// Strings may be specified as literals in single quotes or double quotes.
350///
351/// In single or double quotes a backslash begins an escape sequence, which may
352/// be followed by a, b, f, n, r, t, v or \. Specific characters can be provided
353/// using octal (\nnn) or hexadecimal (\xnn, \unnnn and \Unnnnnnnn).
354#[derive(Debug)]
355pub struct StringLiteral {
356    pub value: String,
357}
358
359/// Unary operators.
360#[derive(Debug, PartialEq)]
361pub enum UnaryOp {
362    Pos,
363    Neg,
364}
365
366impl FromStr for UnaryOp {
367    type Err = String;
368
369    fn from_str(s: &str) -> Result<Self, Self::Err> {
370        match s {
371            "+" => Ok(UnaryOp::Pos),
372            "-" => Ok(UnaryOp::Neg),
373            _ => Err(format!("Unknown unary operator: {}", s)),
374        }
375    }
376}
377
378/// An unary expression. Unary operations are only supported for scalars.
379#[derive(Debug)]
380pub struct UnaryExpr {
381    pub op: UnaryOp,
382    pub rhs: Box<Expr>,
383}
384
385/// Match operators are used to compare a label value in a selector with a
386/// literal value or a regular expression.
387#[derive(Debug, PartialEq)]
388pub enum MatchOp {
389    Equal,
390    NotEqual,
391    Regex,
392    NNotRegex,
393}
394
395impl FromStr for MatchOp {
396    type Err = String;
397
398    fn from_str(s: &str) -> Result<Self, Self::Err> {
399        match s {
400            "=" => Ok(MatchOp::Equal),
401            "!=" => Ok(MatchOp::NotEqual),
402            "=~" => Ok(MatchOp::Regex),
403            "!~" => Ok(MatchOp::NNotRegex),
404            _ => Err(format!("Unknown match operator: {}", s)),
405        }
406    }
407}
408
409/// The matching of a label.
410#[derive(Debug, PartialEq)]
411pub struct LabelMatcher {
412    pub op: MatchOp,
413    pub name: String,
414    pub value: String,
415}
416
417/// A vector selector expression.
418#[derive(Debug)]
419pub struct VectorSelector {
420    pub metric: String,
421    pub label_matchers: Vec<LabelMatcher>,
422    pub original_offset: Duration,
423    pub offset: Duration,
424    pub at: AtModifier,
425}