Skip to main content

nodedb_query/expr/
types.rs

1// SPDX-License-Identifier: Apache-2.0
2
3//! SqlExpr AST node definitions.
4
5use nodedb_types::Value;
6
7/// A serializable SQL expression that can be evaluated against a document.
8#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)]
9pub enum SqlExpr {
10    /// Column reference: extract field value from the document.
11    Column(String),
12    /// Literal value.
13    Literal(Value),
14    /// Binary operation: left op right.
15    BinaryOp {
16        left: Box<SqlExpr>,
17        op: BinaryOp,
18        right: Box<SqlExpr>,
19    },
20    /// Unary negation: -expr or NOT expr.
21    Negate(Box<SqlExpr>),
22    /// Scalar function call.
23    Function { name: String, args: Vec<SqlExpr> },
24    /// CAST(expr AS type).
25    Cast {
26        expr: Box<SqlExpr>,
27        to_type: CastType,
28    },
29    /// CASE WHEN cond1 THEN val1 ... ELSE default END.
30    Case {
31        operand: Option<Box<SqlExpr>>,
32        when_thens: Vec<(SqlExpr, SqlExpr)>,
33        else_expr: Option<Box<SqlExpr>>,
34    },
35    /// COALESCE(expr1, expr2, ...): first non-null value.
36    Coalesce(Vec<SqlExpr>),
37    /// NULLIF(expr1, expr2): returns NULL if expr1 = expr2, else expr1.
38    NullIf(Box<SqlExpr>, Box<SqlExpr>),
39    /// IS NULL / IS NOT NULL.
40    IsNull { expr: Box<SqlExpr>, negated: bool },
41    /// OLD column reference: extract field value from the pre-update document.
42    /// Used in TRANSITION CHECK predicates. Resolves against the OLD row
43    /// when evaluated via `eval_with_old()`. Returns NULL in normal `eval()`.
44    OldColumn(String),
45    /// `EXCLUDED.col` reference from `INSERT ... ON CONFLICT DO UPDATE`:
46    /// the column value from the row proposed for insertion that
47    /// triggered the conflict. Resolves against the incoming row when
48    /// evaluated via `eval_with_excluded()`. Returns NULL in plain
49    /// `eval()` / `eval_with_old()`.
50    ExcludedColumn(String),
51}
52
53/// Binary operators.
54#[derive(
55    Debug,
56    Clone,
57    Copy,
58    PartialEq,
59    Eq,
60    serde::Serialize,
61    serde::Deserialize,
62    zerompk::ToMessagePack,
63    zerompk::FromMessagePack,
64)]
65#[msgpack(c_enum)]
66pub enum BinaryOp {
67    Add,
68    Sub,
69    Mul,
70    Div,
71    Mod,
72    Eq,
73    NotEq,
74    Gt,
75    GtEq,
76    Lt,
77    LtEq,
78    And,
79    Or,
80    Concat,
81}
82
83/// Target types for CAST.
84#[derive(
85    Debug,
86    Clone,
87    PartialEq,
88    Eq,
89    serde::Serialize,
90    serde::Deserialize,
91    zerompk::ToMessagePack,
92    zerompk::FromMessagePack,
93)]
94#[msgpack(c_enum)]
95pub enum CastType {
96    Int,
97    Float,
98    String,
99    Bool,
100}
101
102/// A computed projection column: alias + expression.
103#[derive(
104    Debug,
105    Clone,
106    serde::Serialize,
107    serde::Deserialize,
108    zerompk::ToMessagePack,
109    zerompk::FromMessagePack,
110)]
111pub struct ComputedColumn {
112    pub alias: String,
113    pub expr: SqlExpr,
114}