restq/ast/
expr.rs

1use crate::ast::{ColumnName, Function, Operator, Value};
2use serde::{Deserialize, Serialize};
3use sqlparser::ast as sql;
4use std::fmt;
5
6//TODO: Should be able to do math operations
7// such as: *, +, -, /, %
8#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]
9pub enum Expr {
10    Column(ColumnName),
11    Function(Function),
12    Value(Value),
13    MultiValue(Vec<Value>),
14    BinaryOperation(Box<BinaryOperation>),
15    /// The expressions is explicitly
16    /// grouped in a parenthesis
17    Nested(Box<Expr>),
18}
19
20#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]
21pub struct ExprRename {
22    pub expr: Expr,
23    pub rename: Option<String>,
24}
25
26#[derive(Debug, PartialEq, Clone, Serialize, Deserialize)]
27pub struct BinaryOperation {
28    pub left: Expr,
29    pub operator: Operator,
30    pub right: Expr,
31}
32
33impl Into<sql::Expr> for &Expr {
34    fn into(self) -> sql::Expr {
35        match self {
36            Expr::Column(column) => {
37                sql::Expr::Identifier(sql::Ident::new(&column.name))
38            }
39            Expr::Function(function) => {
40                sql::Expr::Function(Into::into(function))
41            }
42            Expr::Value(value) => sql::Expr::Value(Into::into(value)),
43            Expr::MultiValue(values) => sql::Expr::Tuple(
44                values
45                    .into_iter()
46                    .map(|v| sql::Expr::Value(Into::into(v)))
47                    .collect(),
48            ),
49            //TODO: add the special case matching for the operator
50            //In, NotIn, Like, NotLike
51            Expr::BinaryOperation(binop) => sql::Expr::BinaryOp {
52                left: Box::new(Into::into(&binop.left)),
53                op: Into::into(&binop.operator),
54                right: Box::new(Into::into(&binop.right)),
55            },
56            Expr::Nested(expr) => {
57                sql::Expr::Nested(Box::new(Into::into(expr.as_ref())))
58            }
59        }
60    }
61}
62
63impl fmt::Display for Expr {
64    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
65        match self {
66            Expr::Column(column) => column.fmt(f),
67            Expr::Function(function) => function.fmt(f),
68            Expr::Value(value) => value.fmt(f),
69            Expr::MultiValue(values) => {
70                write!(f, "[")?;
71                for (i, value) in values.iter().enumerate() {
72                    if i > 0 {
73                        write!(f, ",")?;
74                    }
75                    value.fmt(f)?;
76                }
77                write!(f, "]")
78            }
79            Expr::BinaryOperation(bop) => bop.fmt(f),
80            Expr::Nested(expr) => write!(f, "({})", expr),
81        }
82    }
83}
84
85impl fmt::Display for BinaryOperation {
86    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
87        if self.operator.needs_separator() {
88            write!(f, "{}={}.{}", self.left, self.operator, self.right)
89        } else {
90            write!(f, "{}{}{}", self.left, self.operator, self.right)
91        }
92    }
93}
94
95impl fmt::Display for ExprRename {
96    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
97        self.expr.fmt(f)?;
98        if let Some(rename) = &self.rename {
99            write!(f, "=>{}", rename)?;
100        }
101        Ok(())
102    }
103}