Skip to main content

featherdb_query/expr/
subquery.rs

1//! Subquery types and comparison operators
2
3use super::BinaryOp;
4use featherdb_core::Value;
5
6/// Subquery type classification
7#[derive(Debug, Clone, PartialEq, Eq)]
8pub enum SubqueryType {
9    /// Returns single value: WHERE x = (SELECT ...)
10    Scalar,
11    /// WHERE EXISTS (SELECT ...)
12    Exists,
13    /// WHERE x IN (SELECT ...)
14    In,
15    /// WHERE x > ANY (SELECT ...)
16    Any,
17    /// WHERE x > ALL (SELECT ...)
18    All,
19}
20
21/// Comparison operator for ANY/ALL subqueries
22#[derive(Debug, Clone, Copy, PartialEq, Eq)]
23pub enum SubqueryCompareOp {
24    Eq,
25    Ne,
26    Lt,
27    Le,
28    Gt,
29    Ge,
30}
31
32impl SubqueryCompareOp {
33    /// Convert from BinaryOp
34    pub fn from_binary_op(op: &BinaryOp) -> Option<Self> {
35        match op {
36            BinaryOp::Eq => Some(SubqueryCompareOp::Eq),
37            BinaryOp::Ne => Some(SubqueryCompareOp::Ne),
38            BinaryOp::Lt => Some(SubqueryCompareOp::Lt),
39            BinaryOp::Le => Some(SubqueryCompareOp::Le),
40            BinaryOp::Gt => Some(SubqueryCompareOp::Gt),
41            BinaryOp::Ge => Some(SubqueryCompareOp::Ge),
42            _ => None,
43        }
44    }
45
46    /// Compare two values using this operator
47    pub fn compare(&self, left: &Value, right: &Value) -> bool {
48        match self {
49            SubqueryCompareOp::Eq => left == right,
50            SubqueryCompareOp::Ne => left != right,
51            SubqueryCompareOp::Lt => left < right,
52            SubqueryCompareOp::Le => left <= right,
53            SubqueryCompareOp::Gt => left > right,
54            SubqueryCompareOp::Ge => left >= right,
55        }
56    }
57}
58
59#[cfg(test)]
60mod tests {
61    use super::*;
62
63    #[test]
64    fn test_subquery_compare_op_from_binary_op() {
65        assert_eq!(
66            SubqueryCompareOp::from_binary_op(&BinaryOp::Eq),
67            Some(SubqueryCompareOp::Eq)
68        );
69        assert_eq!(
70            SubqueryCompareOp::from_binary_op(&BinaryOp::Ne),
71            Some(SubqueryCompareOp::Ne)
72        );
73        assert_eq!(
74            SubqueryCompareOp::from_binary_op(&BinaryOp::Lt),
75            Some(SubqueryCompareOp::Lt)
76        );
77        assert_eq!(
78            SubqueryCompareOp::from_binary_op(&BinaryOp::Le),
79            Some(SubqueryCompareOp::Le)
80        );
81        assert_eq!(
82            SubqueryCompareOp::from_binary_op(&BinaryOp::Gt),
83            Some(SubqueryCompareOp::Gt)
84        );
85        assert_eq!(
86            SubqueryCompareOp::from_binary_op(&BinaryOp::Ge),
87            Some(SubqueryCompareOp::Ge)
88        );
89        assert_eq!(SubqueryCompareOp::from_binary_op(&BinaryOp::And), None);
90    }
91
92    #[test]
93    fn test_subquery_compare_op_compare() {
94        assert!(SubqueryCompareOp::Eq.compare(&Value::Integer(5), &Value::Integer(5)));
95        assert!(!SubqueryCompareOp::Ne.compare(&Value::Integer(5), &Value::Integer(5)));
96        assert!(SubqueryCompareOp::Lt.compare(&Value::Integer(3), &Value::Integer(5)));
97        assert!(SubqueryCompareOp::Le.compare(&Value::Integer(5), &Value::Integer(5)));
98        assert!(SubqueryCompareOp::Gt.compare(&Value::Integer(7), &Value::Integer(5)));
99        assert!(SubqueryCompareOp::Ge.compare(&Value::Integer(5), &Value::Integer(5)));
100    }
101}