proof_of_sql/sql/logical_plans/
expr.rs

1use super::LogicalPlanError;
2use crate::base::database::{ColumnRef, LiteralValue};
3use alloc::boxed::Box;
4use serde::{Deserialize, Serialize};
5use sqlparser::ast;
6
7/// Enum of column expressions that are either provable or supported in postprocessing
8#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
9pub enum Expr {
10    /// Column
11    Column(ColumnRef),
12    /// A constant expression
13    Literal(LiteralValue),
14    /// Binary operation
15    Binary {
16        /// Left hand side of the binary operation
17        left: Box<Expr>,
18        /// Right hand side of the binary operation
19        right: Box<Expr>,
20        /// Binary operator
21        op: BinaryOperator,
22    },
23    /// NOT expression
24    Not(Box<Expr>),
25}
26
27/// Enum of binary operators we support
28#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
29pub enum BinaryOperator {
30    /// Equals
31    Eq,
32    /// Not equals
33    NotEq,
34    /// Greater than
35    Gt,
36    /// Less than
37    Lt,
38    /// Greater than or equals
39    GtEq,
40    /// Less than or equals
41    LtEq,
42    /// Logical AND
43    And,
44    /// Logical OR
45    Or,
46    /// Plus
47    Plus,
48    /// Minus
49    Minus,
50    /// Multiply
51    Multiply,
52    /// Divide
53    Divide,
54}
55
56impl TryFrom<ast::BinaryOperator> for BinaryOperator {
57    type Error = LogicalPlanError;
58
59    fn try_from(op: ast::BinaryOperator) -> Result<Self, Self::Error> {
60        match op {
61            ast::BinaryOperator::Eq => Ok(BinaryOperator::Eq),
62            ast::BinaryOperator::NotEq => Ok(BinaryOperator::NotEq),
63            ast::BinaryOperator::Gt => Ok(BinaryOperator::Gt),
64            ast::BinaryOperator::Lt => Ok(BinaryOperator::Lt),
65            ast::BinaryOperator::GtEq => Ok(BinaryOperator::GtEq),
66            ast::BinaryOperator::LtEq => Ok(BinaryOperator::LtEq),
67            ast::BinaryOperator::And => Ok(BinaryOperator::And),
68            ast::BinaryOperator::Or => Ok(BinaryOperator::Or),
69            ast::BinaryOperator::Plus => Ok(BinaryOperator::Plus),
70            ast::BinaryOperator::Minus => Ok(BinaryOperator::Minus),
71            ast::BinaryOperator::Multiply => Ok(BinaryOperator::Multiply),
72            ast::BinaryOperator::Divide => Ok(BinaryOperator::Divide),
73            _ => Err(LogicalPlanError::UnsupportedBinaryOperator { op }),
74        }
75    }
76}
77
78#[cfg(test)]
79mod tests {
80    use super::*;
81
82    // Binary operators
83    #[test]
84    fn we_can_convert_supported_sqlparser_binary_operators() {
85        // Let's test all our supported binary operators.
86        let test_cases = vec![
87            (ast::BinaryOperator::Eq, BinaryOperator::Eq),
88            (ast::BinaryOperator::NotEq, BinaryOperator::NotEq),
89            (ast::BinaryOperator::Gt, BinaryOperator::Gt),
90            (ast::BinaryOperator::Lt, BinaryOperator::Lt),
91            (ast::BinaryOperator::GtEq, BinaryOperator::GtEq),
92            (ast::BinaryOperator::LtEq, BinaryOperator::LtEq),
93            (ast::BinaryOperator::And, BinaryOperator::And),
94            (ast::BinaryOperator::Or, BinaryOperator::Or),
95            (ast::BinaryOperator::Plus, BinaryOperator::Plus),
96            (ast::BinaryOperator::Minus, BinaryOperator::Minus),
97            (ast::BinaryOperator::Multiply, BinaryOperator::Multiply),
98            (ast::BinaryOperator::Divide, BinaryOperator::Divide),
99        ];
100
101        for (sql_op, expected) in test_cases {
102            let result = BinaryOperator::try_from(sql_op).unwrap();
103            assert_eq!(result, expected);
104        }
105    }
106
107    #[test]
108    fn we_cannot_convert_unsupported_sqlparser_binary_operators() {
109        // Let's test an unsupported operator.
110        let unsupported_op = ast::BinaryOperator::Spaceship;
111        let result = BinaryOperator::try_from(unsupported_op);
112        assert!(matches!(
113            result,
114            Err(LogicalPlanError::UnsupportedBinaryOperator { .. })
115        ));
116    }
117}