1use crate::ast::Qail;
2use uuid::Uuid;
3
4pub(crate) fn escape_sql_literal_body(value: &str) -> String {
6 value.replace('\0', "").replace('\'', "''")
7}
8
9#[derive(Debug, Clone, Copy, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
11pub enum IntervalUnit {
12 Second,
14 Minute,
16 Hour,
18 Day,
20 Week,
22 Month,
24 Year,
26}
27
28impl std::fmt::Display for IntervalUnit {
29 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
30 match self {
31 IntervalUnit::Second => write!(f, "seconds"),
32 IntervalUnit::Minute => write!(f, "minutes"),
33 IntervalUnit::Hour => write!(f, "hours"),
34 IntervalUnit::Day => write!(f, "days"),
35 IntervalUnit::Week => write!(f, "weeks"),
36 IntervalUnit::Month => write!(f, "months"),
37 IntervalUnit::Year => write!(f, "years"),
38 }
39 }
40}
41
42#[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)]
44pub enum Value {
45 Null,
47 Bool(bool),
49 Int(i64),
51 Float(f64),
53 String(String),
55 Param(usize),
57 NamedParam(String),
59 Function(String),
61 Array(Vec<Value>),
63 Subquery(Box<Qail>),
65 Column(String),
67 Uuid(Uuid),
69 NullUuid,
71 Interval {
73 amount: i64,
75 unit: IntervalUnit,
77 },
78 Timestamp(String),
80 Bytes(Vec<u8>),
82 Expr(Box<crate::ast::Expr>),
84 Vector(Vec<f32>),
86 Json(String),
88}
89
90impl std::fmt::Display for Value {
91 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
92 match self {
93 Value::Null => write!(f, "NULL"),
94 Value::Bool(b) => write!(f, "{}", b),
95 Value::Int(n) => write!(f, "{}", n),
96 Value::Float(n) => write!(f, "{}", n),
97 Value::String(s) => write!(f, "'{}'", escape_sql_literal_body(s)),
98 Value::Param(n) => write!(f, "${}", n),
99 Value::NamedParam(name) => write!(f, ":{}", name),
100 Value::Function(s) => write!(f, "{}", s),
101 Value::Array(arr) => {
102 write!(f, "(")?;
103 for (i, v) in arr.iter().enumerate() {
104 if i > 0 {
105 write!(f, ", ")?;
106 }
107 write!(f, "{}", v)?;
108 }
109 write!(f, ")")
110 }
111 Value::Subquery(_) => write!(f, "(SUBQUERY)"),
112 Value::Column(s) => write!(f, "{}", s),
113 Value::Uuid(u) => write!(f, "'{}'", u),
114 Value::NullUuid => write!(f, "NULL"),
115 Value::Interval { amount, unit } => write!(f, "INTERVAL '{} {}'", amount, unit),
116 Value::Timestamp(ts) => write!(f, "'{}'", escape_sql_literal_body(ts)),
117 Value::Bytes(bytes) => {
118 write!(f, "'\\x")?;
119 for byte in bytes {
120 write!(f, "{:02x}", byte)?;
121 }
122 write!(f, "'")
123 }
124 Value::Expr(expr) => write!(f, "{}", expr),
125 Value::Vector(v) => {
126 write!(f, "[")?;
127 for (i, val) in v.iter().enumerate() {
128 if i > 0 {
129 write!(f, ", ")?;
130 }
131 write!(f, "{}", val)?;
132 }
133 write!(f, "]")
134 }
135 Value::Json(json) => write!(f, "'{}'::jsonb", escape_sql_literal_body(json)),
136 }
137 }
138}
139
140impl From<bool> for Value {
141 fn from(b: bool) -> Self {
142 Value::Bool(b)
143 }
144}
145
146impl From<i32> for Value {
147 fn from(n: i32) -> Self {
148 Value::Int(n as i64)
149 }
150}
151
152impl From<i64> for Value {
153 fn from(n: i64) -> Self {
154 Value::Int(n)
155 }
156}
157
158impl From<f64> for Value {
159 fn from(n: f64) -> Self {
160 Value::Float(n)
161 }
162}
163
164impl From<&str> for Value {
165 fn from(s: &str) -> Self {
166 Value::String(s.to_string())
167 }
168}
169
170impl From<String> for Value {
171 fn from(s: String) -> Self {
172 Value::String(s)
173 }
174}
175
176impl From<Uuid> for Value {
177 fn from(u: Uuid) -> Self {
178 Value::Uuid(u)
179 }
180}
181
182impl From<Option<Uuid>> for Value {
183 fn from(opt: Option<Uuid>) -> Self {
184 match opt {
185 Some(u) => Value::Uuid(u),
186 None => Value::NullUuid,
187 }
188 }
189}
190
191impl From<Option<String>> for Value {
192 fn from(opt: Option<String>) -> Self {
193 match opt {
194 Some(s) => Value::String(s),
195 None => Value::Null,
196 }
197 }
198}
199
200impl<'a> From<Option<&'a str>> for Value {
201 fn from(opt: Option<&'a str>) -> Self {
202 match opt {
203 Some(s) => Value::String(s.to_string()),
204 None => Value::Null,
205 }
206 }
207}
208
209impl From<Option<i64>> for Value {
210 fn from(opt: Option<i64>) -> Self {
211 match opt {
212 Some(n) => Value::Int(n),
213 None => Value::Null,
214 }
215 }
216}
217
218impl From<Option<i32>> for Value {
219 fn from(opt: Option<i32>) -> Self {
220 match opt {
221 Some(n) => Value::Int(n as i64),
222 None => Value::Null,
223 }
224 }
225}
226
227impl From<Option<bool>> for Value {
228 fn from(opt: Option<bool>) -> Self {
229 match opt {
230 Some(b) => Value::Bool(b),
231 None => Value::Null,
232 }
233 }
234}
235
236impl From<crate::ast::Expr> for Value {
246 fn from(expr: crate::ast::Expr) -> Self {
247 Value::Expr(Box::new(expr))
248 }
249}