Skip to main content

nodedb_sql/
types_expr.rs

1// SPDX-License-Identifier: Apache-2.0
2
3//! SQL value / expression / operator types.
4//!
5//! Re-exported from `types` so downstream `use crate::types::*` continues
6//! to resolve these symbols without change.
7
8use nodedb_types::datetime::NdbDateTime;
9
10use crate::types::SqlPlan;
11
12/// SQL value literal.
13#[derive(Debug, Clone, PartialEq)]
14pub enum SqlValue {
15    Int(i64),
16    Float(f64),
17    /// Arbitrary-precision decimal (exact arithmetic, no float rounding).
18    Decimal(rust_decimal::Decimal),
19    String(String),
20    Bool(bool),
21    Null,
22    Bytes(Vec<u8>),
23    Array(Vec<SqlValue>),
24    /// Typed naive timestamp literal: `TIMESTAMP '...'` or `'...'::TIMESTAMP`.
25    Timestamp(NdbDateTime),
26    /// Typed timezone-aware timestamp literal: `TIMESTAMPTZ '...'` or `'...'::TIMESTAMPTZ`.
27    Timestamptz(NdbDateTime),
28}
29
30/// SQL-side payload-bitmap predicate atom. Mirrors `nodedb_types::PayloadAtom`
31/// but holds `SqlValue` (not `nodedb_types::Value`) so the planner can build
32/// it without a sql→types translation step. The convert layer lowers
33/// `SqlPayloadAtom` to `nodedb_types::PayloadAtom` before crossing the bridge.
34#[derive(Debug, Clone, PartialEq)]
35pub enum SqlPayloadAtom {
36    Eq(String, SqlValue),
37    In(String, Vec<SqlValue>),
38    Range {
39        field: String,
40        low: Option<SqlValue>,
41        low_inclusive: bool,
42        high: Option<SqlValue>,
43        high_inclusive: bool,
44    },
45}
46
47/// SQL expression tree.
48#[derive(Debug, Clone)]
49pub enum SqlExpr {
50    /// Column reference, optionally qualified: `name` or `users.name`
51    Column { table: Option<String>, name: String },
52    /// Literal value.
53    Literal(SqlValue),
54    /// Binary operation: `a + b`, `x > 5`
55    BinaryOp {
56        left: Box<SqlExpr>,
57        op: BinaryOp,
58        right: Box<SqlExpr>,
59    },
60    /// Unary operation: `-x`, `NOT flag`
61    UnaryOp { op: UnaryOp, expr: Box<SqlExpr> },
62    /// Function call: `COUNT(*)`, `vector_distance(field, ARRAY[...])`
63    Function {
64        name: String,
65        args: Vec<SqlExpr>,
66        distinct: bool,
67    },
68    /// CASE WHEN ... THEN ... ELSE ... END
69    Case {
70        operand: Option<Box<SqlExpr>>,
71        when_then: Vec<(SqlExpr, SqlExpr)>,
72        else_expr: Option<Box<SqlExpr>>,
73    },
74    /// CAST(expr AS type)
75    Cast { expr: Box<SqlExpr>, to_type: String },
76    /// Subquery expression (IN, EXISTS, scalar)
77    Subquery(Box<SqlPlan>),
78    /// Wildcard `*`
79    Wildcard,
80    /// `IS NULL` / `IS NOT NULL`
81    IsNull { expr: Box<SqlExpr>, negated: bool },
82    /// `expr IN (values)`
83    InList {
84        expr: Box<SqlExpr>,
85        list: Vec<SqlExpr>,
86        negated: bool,
87    },
88    /// `expr BETWEEN low AND high`
89    Between {
90        expr: Box<SqlExpr>,
91        low: Box<SqlExpr>,
92        high: Box<SqlExpr>,
93        negated: bool,
94    },
95    /// `expr LIKE pattern` / `expr ILIKE pattern`
96    Like {
97        expr: Box<SqlExpr>,
98        pattern: Box<SqlExpr>,
99        negated: bool,
100        /// `true` for ILIKE (case-insensitive match), `false` for LIKE.
101        case_insensitive: bool,
102    },
103    /// Array literal: `ARRAY[1.0, 2.0, 3.0]`
104    ArrayLiteral(Vec<SqlExpr>),
105}
106
107/// Binary operators.
108#[derive(Debug, Clone, Copy, PartialEq, Eq)]
109pub enum BinaryOp {
110    // Arithmetic
111    Add,
112    Sub,
113    Mul,
114    Div,
115    Mod,
116    // Comparison
117    Eq,
118    Ne,
119    Gt,
120    Ge,
121    Lt,
122    Le,
123    // Logical
124    And,
125    Or,
126    // String
127    Concat,
128}
129
130/// Unary operators.
131#[derive(Debug, Clone, Copy, PartialEq, Eq)]
132pub enum UnaryOp {
133    Neg,
134    Not,
135}
136
137/// SQL data type for schema resolution.
138#[derive(Debug, Clone, PartialEq, Eq)]
139pub enum SqlDataType {
140    Int64,
141    Float64,
142    String,
143    Bool,
144    Bytes,
145    /// Naive (no-timezone) timestamp.
146    Timestamp,
147    /// Timezone-aware timestamp.
148    Timestamptz,
149    Decimal,
150    Uuid,
151    Vector(usize),
152    Geometry,
153}