Skip to main content

qail_core/ast/
values.rs

1use crate::ast::Qail;
2use serde::{Deserialize, Serialize};
3use uuid::Uuid;
4
5/// Time interval unit for duration expressions
6#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
7pub enum IntervalUnit {
8    Second,
9    Minute,
10    Hour,
11    Day,
12    Week,
13    Month,
14    Year,
15}
16
17impl std::fmt::Display for IntervalUnit {
18    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
19        match self {
20            IntervalUnit::Second => write!(f, "seconds"),
21            IntervalUnit::Minute => write!(f, "minutes"),
22            IntervalUnit::Hour => write!(f, "hours"),
23            IntervalUnit::Day => write!(f, "days"),
24            IntervalUnit::Week => write!(f, "weeks"),
25            IntervalUnit::Month => write!(f, "months"),
26            IntervalUnit::Year => write!(f, "years"),
27        }
28    }
29}
30
31/// A value in a condition.
32#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
33pub enum Value {
34    Null,
35    Bool(bool),
36    Int(i64),
37    Float(f64),
38    String(String),
39    Param(usize),
40    /// Named parameter reference (:name, :id, etc.)
41    NamedParam(String),
42    Function(String),
43    Array(Vec<Value>),
44    Subquery(Box<Qail>),
45    Column(String),
46    Uuid(Uuid),
47    NullUuid,
48    /// Time interval (e.g., 24 hours, 7 days)
49    Interval { amount: i64, unit: IntervalUnit },
50    Timestamp(String),
51    /// Binary data (bytea)
52    Bytes(Vec<u8>),
53    /// AST Expression (for complex expression comparisons like col > NOW() - INTERVAL)
54    Expr(Box<crate::ast::Expr>),
55    /// Vector embedding for similarity search (Qdrant)
56    Vector(Vec<f32>),
57    Json(String),
58}
59
60impl std::fmt::Display for Value {
61    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
62        match self {
63            Value::Null => write!(f, "NULL"),
64            Value::Bool(b) => write!(f, "{}", b),
65            Value::Int(n) => write!(f, "{}", n),
66            Value::Float(n) => write!(f, "{}", n),
67            Value::String(s) => write!(f, "'{}'", s),
68            Value::Param(n) => write!(f, "${}", n),
69            Value::NamedParam(name) => write!(f, ":{}", name),
70            Value::Function(s) => write!(f, "{}", s),
71            Value::Array(arr) => {
72                write!(f, "(")?;
73                for (i, v) in arr.iter().enumerate() {
74                    if i > 0 {
75                        write!(f, ", ")?;
76                    }
77                    write!(f, "{}", v)?;
78                }
79                write!(f, ")")
80            }
81            Value::Subquery(_) => write!(f, "(SUBQUERY)"),
82            Value::Column(s) => write!(f, "{}", s),
83            Value::Uuid(u) => write!(f, "'{}'", u),
84            Value::NullUuid => write!(f, "NULL"),
85            Value::Interval { amount, unit } => write!(f, "INTERVAL '{} {}'", amount, unit),
86            Value::Timestamp(ts) => write!(f, "'{}'", ts),
87            Value::Bytes(bytes) => {
88                write!(f, "'\\x")?;
89                for byte in bytes {
90                    write!(f, "{:02x}", byte)?;
91                }
92                write!(f, "'")
93            }
94            Value::Expr(expr) => write!(f, "{}", expr),
95            Value::Vector(v) => {
96                write!(f, "[")?;
97                for (i, val) in v.iter().enumerate() {
98                    if i > 0 { write!(f, ", ")?; }
99                    write!(f, "{}", val)?;
100                }
101                write!(f, "]")
102            }
103            Value::Json(json) => write!(f, "'{}'::jsonb", json.replace('\'', "''")),
104        }
105    }
106}
107
108impl From<bool> for Value {
109    fn from(b: bool) -> Self {
110        Value::Bool(b)
111    }
112}
113
114impl From<i32> for Value {
115    fn from(n: i32) -> Self {
116        Value::Int(n as i64)
117    }
118}
119
120impl From<i64> for Value {
121    fn from(n: i64) -> Self {
122        Value::Int(n)
123    }
124}
125
126impl From<f64> for Value {
127    fn from(n: f64) -> Self {
128        Value::Float(n)
129    }
130}
131
132impl From<&str> for Value {
133    fn from(s: &str) -> Self {
134        Value::String(s.to_string())
135    }
136}
137
138impl From<String> for Value {
139    fn from(s: String) -> Self {
140        Value::String(s)
141    }
142}
143
144impl From<Uuid> for Value {
145    fn from(u: Uuid) -> Self {
146        Value::Uuid(u)
147    }
148}
149
150impl From<Option<Uuid>> for Value {
151    fn from(opt: Option<Uuid>) -> Self {
152        match opt {
153            Some(u) => Value::Uuid(u),
154            None => Value::NullUuid,
155        }
156    }
157}
158
159impl From<Option<String>> for Value {
160    fn from(opt: Option<String>) -> Self {
161        match opt {
162            Some(s) => Value::String(s),
163            None => Value::Null,
164        }
165    }
166}
167
168impl<'a> From<Option<&'a str>> for Value {
169    fn from(opt: Option<&'a str>) -> Self {
170        match opt {
171            Some(s) => Value::String(s.to_string()),
172            None => Value::Null,
173        }
174    }
175}
176
177impl From<Option<i64>> for Value {
178    fn from(opt: Option<i64>) -> Self {
179        match opt {
180            Some(n) => Value::Int(n),
181            None => Value::Null,
182        }
183    }
184}
185
186impl From<Option<i32>> for Value {
187    fn from(opt: Option<i32>) -> Self {
188        match opt {
189            Some(n) => Value::Int(n as i64),
190            None => Value::Null,
191        }
192    }
193}
194
195impl From<Option<bool>> for Value {
196    fn from(opt: Option<bool>) -> Self {
197        match opt {
198            Some(b) => Value::Bool(b),
199            None => Value::Null,
200        }
201    }
202}