quill_sql/utils/
scalar.rs

1use crate::catalog::DataType;
2use crate::error::{QuillSQLError, QuillSQLResult};
3use std::cmp::Ordering;
4
5#[derive(Debug, Clone)]
6pub enum ScalarValue {
7    Boolean(Option<bool>),
8    Int8(Option<i8>),
9    Int16(Option<i16>),
10    Int32(Option<i32>),
11    Int64(Option<i64>),
12    UInt8(Option<u8>),
13    UInt16(Option<u16>),
14    UInt32(Option<u32>),
15    UInt64(Option<u64>),
16    Float32(Option<f32>),
17    Float64(Option<f64>),
18    Varchar(Option<String>),
19}
20
21impl ScalarValue {
22    pub fn new_empty(data_type: DataType) -> Self {
23        match data_type {
24            DataType::Boolean => Self::Boolean(None),
25            DataType::Int8 => Self::Int8(None),
26            DataType::Int16 => Self::Int16(None),
27            DataType::Int32 => Self::Int32(None),
28            DataType::Int64 => Self::Int64(None),
29            DataType::UInt8 => Self::UInt8(None),
30            DataType::UInt16 => Self::UInt16(None),
31            DataType::UInt32 => Self::UInt32(None),
32            DataType::UInt64 => Self::UInt64(None),
33            DataType::Float32 => Self::Float32(None),
34            DataType::Float64 => Self::Float64(None),
35            DataType::Varchar(_) => Self::Varchar(None),
36        }
37    }
38
39    pub fn data_type(&self) -> DataType {
40        match self {
41            ScalarValue::Boolean(_) => DataType::Boolean,
42            ScalarValue::Int8(_) => DataType::Int8,
43            ScalarValue::Int16(_) => DataType::Int16,
44            ScalarValue::Int32(_) => DataType::Int32,
45            ScalarValue::Int64(_) => DataType::Int64,
46            ScalarValue::UInt8(_) => DataType::UInt8,
47            ScalarValue::UInt16(_) => DataType::UInt16,
48            ScalarValue::UInt32(_) => DataType::UInt32,
49            ScalarValue::UInt64(_) => DataType::UInt64,
50            ScalarValue::Float32(_) => DataType::Float32,
51            ScalarValue::Float64(_) => DataType::Float64,
52            ScalarValue::Varchar(_) => DataType::Varchar(None),
53        }
54    }
55
56    pub fn is_null(&self) -> bool {
57        match self {
58            ScalarValue::Boolean(v) => v.is_none(),
59            ScalarValue::Int8(v) => v.is_none(),
60            ScalarValue::Int16(v) => v.is_none(),
61            ScalarValue::Int32(v) => v.is_none(),
62            ScalarValue::Int64(v) => v.is_none(),
63            ScalarValue::UInt8(v) => v.is_none(),
64            ScalarValue::UInt16(v) => v.is_none(),
65            ScalarValue::UInt32(v) => v.is_none(),
66            ScalarValue::UInt64(v) => v.is_none(),
67            ScalarValue::Float32(v) => v.is_none(),
68            ScalarValue::Float64(v) => v.is_none(),
69            ScalarValue::Varchar(v) => v.is_none(),
70        }
71    }
72
73    /// Try to cast this value to a ScalarValue of type `data_type`
74    pub fn cast_to(&self, data_type: &DataType) -> QuillSQLResult<Self> {
75        let error =
76            QuillSQLError::NotSupport(format!("Failed to cast {:?} to {} type", self, data_type));
77
78        if &self.data_type() == data_type {
79            return Ok(self.clone());
80        }
81
82        match data_type {
83            DataType::Int8 => {
84                let data = match self {
85                    ScalarValue::Int64(v) => Ok(v.map(|v| v as i8)),
86                    _ => Err(error),
87                };
88                data.map(ScalarValue::Int8)
89            }
90            DataType::Int16 => {
91                let data = match self {
92                    ScalarValue::Int8(v) => Ok(v.map(|v| v as i16)),
93                    ScalarValue::Int64(v) => Ok(v.map(|v| v as i16)),
94                    _ => Err(error),
95                };
96                data.map(ScalarValue::Int16)
97            }
98            DataType::Int32 => {
99                let data = match self {
100                    ScalarValue::Int8(v) => Ok(v.map(|v| v as i32)),
101                    ScalarValue::Int64(v) => Ok(v.map(|v| v as i32)),
102                    _ => Err(error),
103                };
104                data.map(ScalarValue::Int32)
105            }
106            DataType::Int64 => {
107                let data = match self {
108                    ScalarValue::Int8(v) => Ok(v.map(|v| v as i64)),
109                    ScalarValue::Int32(v) => Ok(v.map(|v| v as i64)),
110                    _ => Err(error),
111                };
112                data.map(ScalarValue::Int64)
113            }
114            DataType::UInt8 => {
115                let data = match self {
116                    ScalarValue::Int8(v) => Ok(v.map(|v| v as u8)),
117                    ScalarValue::Int64(v) => Ok(v.map(|v| v as u8)),
118                    _ => Err(error),
119                };
120                data.map(ScalarValue::UInt8)
121            }
122            DataType::UInt16 => {
123                let data = match self {
124                    ScalarValue::Int8(v) => Ok(v.map(|v| v as u16)),
125                    ScalarValue::Int64(v) => Ok(v.map(|v| v as u16)),
126                    _ => Err(error),
127                };
128                data.map(ScalarValue::UInt16)
129            }
130            DataType::UInt32 => {
131                let data = match self {
132                    ScalarValue::Int8(v) => Ok(v.map(|v| v as u32)),
133                    ScalarValue::Int64(v) => Ok(v.map(|v| v as u32)),
134                    _ => Err(error),
135                };
136                data.map(ScalarValue::UInt32)
137            }
138            DataType::UInt64 => {
139                let data = match self {
140                    ScalarValue::Int8(v) => Ok(v.map(|v| v as u64)),
141                    ScalarValue::Int64(v) => Ok(v.map(|v| v as u64)),
142                    _ => Err(error),
143                };
144                data.map(ScalarValue::UInt64)
145            }
146            DataType::Float32 => {
147                let data = match self {
148                    ScalarValue::Int8(v) => Ok(v.map(|v| v as f32)),
149                    ScalarValue::Int64(v) => Ok(v.map(|v| v as f32)),
150                    ScalarValue::Float64(v) => Ok(v.map(|v| v as f32)),
151                    _ => Err(error),
152                };
153                data.map(ScalarValue::Float32)
154            }
155            DataType::Float64 => {
156                let data = match self {
157                    ScalarValue::Int8(v) => Ok(v.map(|v| v as f64)),
158                    ScalarValue::Int32(v) => Ok(v.map(|v| v as f64)),
159                    ScalarValue::Int64(v) => Ok(v.map(|v| v as f64)),
160                    _ => Err(error),
161                };
162                data.map(ScalarValue::Float64)
163            }
164            DataType::Varchar(_) => {
165                match self {
166                    // If already a string, keep it and optionally truncate to the target length
167                    ScalarValue::Varchar(v) => Ok(ScalarValue::Varchar(v.clone())),
168                    // Simple numeric to string example kept for minimal compatibility
169                    ScalarValue::Int8(v) => Ok(ScalarValue::Varchar(v.map(|v| v.to_string()))),
170                    _ => Err(error),
171                }
172            }
173            _ => Err(error),
174        }
175    }
176
177    pub fn as_boolean(&self) -> QuillSQLResult<Option<bool>> {
178        match self {
179            ScalarValue::Boolean(v) => Ok(*v),
180            _ => Err(QuillSQLError::Internal(format!(
181                "Cannot treat {:?} as boolean",
182                self
183            ))),
184        }
185    }
186
187    pub fn wrapping_add(&self, other: Self) -> QuillSQLResult<Self> {
188        use ScalarValue::*;
189        match (self, other.clone()) {
190            (Int8(Some(a)), Int8(Some(b))) => Ok(Int8(Some(a.wrapping_add(b)))),
191            (Int16(Some(a)), Int16(Some(b))) => Ok(Int16(Some(a.wrapping_add(b)))),
192            (Int32(Some(a)), Int32(Some(b))) => Ok(Int32(Some(a.wrapping_add(b)))),
193            (Int64(Some(a)), Int64(Some(b))) => Ok(Int64(Some(a.wrapping_add(b)))),
194            (UInt8(Some(a)), UInt8(Some(b))) => Ok(UInt8(Some(a.wrapping_add(b)))),
195            (UInt16(Some(a)), UInt16(Some(b))) => Ok(UInt16(Some(a.wrapping_add(b)))),
196            (UInt32(Some(a)), UInt32(Some(b))) => Ok(UInt32(Some(a.wrapping_add(b)))),
197            (UInt64(Some(a)), UInt64(Some(b))) => Ok(UInt64(Some(a.wrapping_add(b)))),
198            (Float32(Some(a)), Float32(Some(b))) => Ok(Float32(Some(a + b))),
199            (Float64(Some(a)), Float64(Some(b))) => Ok(Float64(Some(a + b))),
200            (Int8(None), _)
201            | (Int16(None), _)
202            | (Int32(None), _)
203            | (Int64(None), _)
204            | (UInt8(None), _)
205            | (UInt16(None), _)
206            | (UInt32(None), _)
207            | (UInt64(None), _)
208            | (Float32(None), _)
209            | (Float64(None), _) => Ok(self.clone()),
210            _ => Err(QuillSQLError::Execution(format!(
211                "Unsupported addition between {:?} and {:?}",
212                self, other
213            ))),
214        }
215    }
216
217    pub fn wrapping_sub(&self, other: Self) -> QuillSQLResult<Self> {
218        use ScalarValue::*;
219        match (self, other.clone()) {
220            (Int8(Some(a)), Int8(Some(b))) => Ok(Int8(Some(a.wrapping_sub(b)))),
221            (Int16(Some(a)), Int16(Some(b))) => Ok(Int16(Some(a.wrapping_sub(b)))),
222            (Int32(Some(a)), Int32(Some(b))) => Ok(Int32(Some(a.wrapping_sub(b)))),
223            (Int64(Some(a)), Int64(Some(b))) => Ok(Int64(Some(a.wrapping_sub(b)))),
224            (UInt8(Some(a)), UInt8(Some(b))) => Ok(UInt8(Some(a.wrapping_sub(b)))),
225            (UInt16(Some(a)), UInt16(Some(b))) => Ok(UInt16(Some(a.wrapping_sub(b)))),
226            (UInt32(Some(a)), UInt32(Some(b))) => Ok(UInt32(Some(a.wrapping_sub(b)))),
227            (UInt64(Some(a)), UInt64(Some(b))) => Ok(UInt64(Some(a.wrapping_sub(b)))),
228            (Float32(Some(a)), Float32(Some(b))) => Ok(Float32(Some(a - b))),
229            (Float64(Some(a)), Float64(Some(b))) => Ok(Float64(Some(a - b))),
230            (Int8(None), _)
231            | (Int16(None), _)
232            | (Int32(None), _)
233            | (Int64(None), _)
234            | (UInt8(None), _)
235            | (UInt16(None), _)
236            | (UInt32(None), _)
237            | (UInt64(None), _)
238            | (Float32(None), _)
239            | (Float64(None), _) => Ok(self.clone()),
240            _ => Err(QuillSQLError::Execution(format!(
241                "Unsupported subtraction between {:?} and {:?}",
242                self, other
243            ))),
244        }
245    }
246
247    pub fn wrapping_mul(&self, other: Self) -> QuillSQLResult<Self> {
248        use ScalarValue::*;
249        match (self, other.clone()) {
250            (Int32(Some(a)), Int32(Some(b))) => Ok(Int32(Some(a.wrapping_mul(b)))),
251            (Int64(Some(a)), Int64(Some(b))) => Ok(Int64(Some(a.wrapping_mul(b)))),
252            (UInt32(Some(a)), UInt32(Some(b))) => Ok(UInt32(Some(a.wrapping_mul(b)))),
253            (UInt64(Some(a)), UInt64(Some(b))) => Ok(UInt64(Some(a.wrapping_mul(b)))),
254            (Float32(Some(a)), Float32(Some(b))) => Ok(Float32(Some(a * b))),
255            (Float64(Some(a)), Float64(Some(b))) => Ok(Float64(Some(a * b))),
256            (Int8(Some(a)), Int8(Some(b))) => Ok(Int8(Some(a.wrapping_mul(b)))),
257            (Int16(Some(a)), Int16(Some(b))) => Ok(Int16(Some(a.wrapping_mul(b)))),
258            (UInt8(Some(a)), UInt8(Some(b))) => Ok(UInt8(Some(a.wrapping_mul(b)))),
259            (UInt16(Some(a)), UInt16(Some(b))) => Ok(UInt16(Some(a.wrapping_mul(b)))),
260            (Int8(None), _)
261            | (Int16(None), _)
262            | (Int32(None), _)
263            | (Int64(None), _)
264            | (UInt8(None), _)
265            | (UInt16(None), _)
266            | (UInt32(None), _)
267            | (UInt64(None), _)
268            | (Float32(None), _)
269            | (Float64(None), _) => Ok(self.clone()),
270            _ => Err(QuillSQLError::Execution(format!(
271                "Unsupported multiplication between {:?} and {:?}",
272                self, other
273            ))),
274        }
275    }
276
277    pub fn wrapping_div(&self, other: Self) -> QuillSQLResult<Self> {
278        use ScalarValue::*;
279        match (self, other.clone()) {
280            (Int8(Some(a)), Int8(Some(b))) => Ok(Int8(Some(a.wrapping_div(b)))),
281            (Int16(Some(a)), Int16(Some(b))) => Ok(Int16(Some(a.wrapping_div(b)))),
282            (Int32(Some(a)), Int32(Some(b))) => Ok(Int32(Some(a.wrapping_div(b)))),
283            (Int64(Some(a)), Int64(Some(b))) => Ok(Int64(Some(a.wrapping_div(b)))),
284            (UInt8(Some(a)), UInt8(Some(b))) => Ok(UInt8(Some(a.wrapping_div(b)))),
285            (UInt16(Some(a)), UInt16(Some(b))) => Ok(UInt16(Some(a.wrapping_div(b)))),
286            (UInt32(Some(a)), UInt32(Some(b))) => Ok(UInt32(Some(a.wrapping_div(b)))),
287            (UInt64(Some(a)), UInt64(Some(b))) => Ok(UInt64(Some(a.wrapping_div(b)))),
288            (Float32(Some(a)), Float32(Some(b))) => Ok(Float32(Some(a / b))),
289            (Float64(Some(a)), Float64(Some(b))) => Ok(Float64(Some(a / b))),
290            (Int8(None), _)
291            | (Int16(None), _)
292            | (Int32(None), _)
293            | (Int64(None), _)
294            | (UInt8(None), _)
295            | (UInt16(None), _)
296            | (UInt32(None), _)
297            | (UInt64(None), _)
298            | (Float32(None), _)
299            | (Float64(None), _) => Ok(self.clone()),
300            _ => Err(QuillSQLError::Execution(format!(
301                "Unsupported division between {:?} and {:?}",
302                self, other
303            ))),
304        }
305    }
306
307    pub fn from_string(string: &String, data_type: DataType) -> QuillSQLResult<Self> {
308        let is_null = string.eq_ignore_ascii_case("null");
309        match data_type {
310            DataType::Boolean => {
311                let v = if is_null {
312                    None
313                } else {
314                    let v = string
315                        .parse::<bool>()
316                        .map_err(|_| QuillSQLError::Internal("Parse bool failed".to_string()))?;
317                    Some(v)
318                };
319                Ok(ScalarValue::Boolean(v))
320            }
321            DataType::Int8 => {
322                let v = if is_null {
323                    None
324                } else {
325                    let v = string
326                        .parse::<i8>()
327                        .map_err(|_| QuillSQLError::Internal("Parse i8 failed".to_string()))?;
328                    Some(v)
329                };
330                Ok(ScalarValue::Int8(v))
331            }
332            DataType::Int16 => {
333                let v = if is_null {
334                    None
335                } else {
336                    let v = string
337                        .parse::<i16>()
338                        .map_err(|_| QuillSQLError::Internal("Parse i16 failed".to_string()))?;
339                    Some(v)
340                };
341                Ok(ScalarValue::Int16(v))
342            }
343            DataType::Int32 => {
344                let v = if is_null {
345                    None
346                } else {
347                    let v = string
348                        .parse::<i32>()
349                        .map_err(|_| QuillSQLError::Internal("Parse i32 failed".to_string()))?;
350                    Some(v)
351                };
352                Ok(ScalarValue::Int32(v))
353            }
354            DataType::Int64 => {
355                let v = if is_null {
356                    None
357                } else {
358                    let v = string
359                        .parse::<i64>()
360                        .map_err(|_| QuillSQLError::Internal("Parse i64 failed".to_string()))?;
361                    Some(v)
362                };
363                Ok(ScalarValue::Int64(v))
364            }
365            DataType::UInt8 => {
366                let v = if is_null {
367                    None
368                } else {
369                    let v = string
370                        .parse::<u8>()
371                        .map_err(|_| QuillSQLError::Internal("Parse u8 failed".to_string()))?;
372                    Some(v)
373                };
374                Ok(ScalarValue::UInt8(v))
375            }
376            DataType::UInt16 => {
377                let v = if is_null {
378                    None
379                } else {
380                    let v = string
381                        .parse::<u16>()
382                        .map_err(|_| QuillSQLError::Internal("Parse u16 failed".to_string()))?;
383                    Some(v)
384                };
385                Ok(ScalarValue::UInt16(v))
386            }
387            DataType::UInt32 => {
388                let v = if is_null {
389                    None
390                } else {
391                    let v = string
392                        .parse::<u32>()
393                        .map_err(|_| QuillSQLError::Internal("Parse u32 failed".to_string()))?;
394                    Some(v)
395                };
396                Ok(ScalarValue::UInt32(v))
397            }
398            DataType::UInt64 => {
399                let v = if is_null {
400                    None
401                } else {
402                    let v = string
403                        .parse::<u64>()
404                        .map_err(|_| QuillSQLError::Internal("Parse u64 failed".to_string()))?;
405                    Some(v)
406                };
407                Ok(ScalarValue::UInt64(v))
408            }
409            DataType::Float32 => {
410                let v = if is_null {
411                    None
412                } else {
413                    let v = string
414                        .parse::<f32>()
415                        .map_err(|_| QuillSQLError::Internal("Parse f32 failed".to_string()))?;
416                    Some(v)
417                };
418                Ok(ScalarValue::Float32(v))
419            }
420            DataType::Float64 => {
421                let v = if is_null {
422                    None
423                } else {
424                    let v = string
425                        .parse::<f64>()
426                        .map_err(|_| QuillSQLError::Internal("Parse f64 failed".to_string()))?;
427                    Some(v)
428                };
429                Ok(ScalarValue::Float64(v))
430            }
431            DataType::Varchar(_) => {
432                let v = if is_null { None } else { Some(string.clone()) };
433                Ok(ScalarValue::Varchar(v))
434            }
435        }
436    }
437}
438
439impl PartialEq for ScalarValue {
440    fn eq(&self, other: &Self) -> bool {
441        use ScalarValue::*;
442        match (self, other) {
443            (Boolean(v1), Boolean(v2)) => v1.eq(v2),
444            (Boolean(_), _) => false,
445            (Int8(v1), Int8(v2)) => v1.eq(v2),
446            (Int8(_), _) => false,
447            (Int16(v1), Int16(v2)) => v1.eq(v2),
448            (Int16(_), _) => false,
449            (Int32(v1), Int32(v2)) => v1.eq(v2),
450            (Int32(_), _) => false,
451            (Int64(v1), Int64(v2)) => v1.eq(v2),
452            (Int64(_), _) => false,
453            (UInt8(v1), UInt8(v2)) => v1.eq(v2),
454            (UInt8(_), _) => false,
455            (UInt16(v1), UInt16(v2)) => v1.eq(v2),
456            (UInt16(_), _) => false,
457            (UInt32(v1), UInt32(v2)) => v1.eq(v2),
458            (UInt32(_), _) => false,
459            (UInt64(v1), UInt64(v2)) => v1.eq(v2),
460            (UInt64(_), _) => false,
461            (Float32(v1), Float32(v2)) => match (v1, v2) {
462                (Some(f1), Some(f2)) => f1.to_bits() == f2.to_bits(),
463                _ => v1.eq(v2),
464            },
465            (Float32(_), _) => false,
466            (Float64(v1), Float64(v2)) => match (v1, v2) {
467                (Some(f1), Some(f2)) => f1.to_bits() == f2.to_bits(),
468                _ => v1.eq(v2),
469            },
470            (Float64(_), _) => false,
471            (Varchar(v1), Varchar(v2)) => v1.eq(v2),
472            (Varchar(_), _) => false,
473        }
474    }
475}
476
477impl Eq for ScalarValue {}
478
479impl PartialOrd for ScalarValue {
480    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
481        use ScalarValue::*;
482        match (self, other) {
483            (Boolean(v1), Boolean(v2)) => v1.partial_cmp(v2),
484            (Boolean(_), _) => None,
485            (Int8(v1), Int8(v2)) => v1.partial_cmp(v2),
486            (Int8(_), _) => None,
487            (Int16(v1), Int16(v2)) => v1.partial_cmp(v2),
488            (Int16(_), _) => None,
489            (Int32(v1), Int32(v2)) => v1.partial_cmp(v2),
490            (Int32(_), _) => None,
491            (Int64(v1), Int64(v2)) => v1.partial_cmp(v2),
492            (Int64(_), _) => None,
493            (UInt8(v1), UInt8(v2)) => v1.partial_cmp(v2),
494            (UInt8(_), _) => None,
495            (UInt16(v1), UInt16(v2)) => v1.partial_cmp(v2),
496            (UInt16(_), _) => None,
497            (UInt32(v1), UInt32(v2)) => v1.partial_cmp(v2),
498            (UInt32(_), _) => None,
499            (UInt64(v1), UInt64(v2)) => v1.partial_cmp(v2),
500            (UInt64(_), _) => None,
501            (Float32(v1), Float32(v2)) => match (v1, v2) {
502                (Some(f1), Some(f2)) => Some(f1.total_cmp(f2)),
503                _ => v1.partial_cmp(v2),
504            },
505            (Float32(_), _) => None,
506            (Float64(v1), Float64(v2)) => match (v1, v2) {
507                (Some(f1), Some(f2)) => Some(f1.total_cmp(f2)),
508                _ => v1.partial_cmp(v2),
509            },
510            (Float64(_), _) => None,
511            (Varchar(v1), Varchar(v2)) => v1.partial_cmp(v2),
512            (Varchar(_), _) => None,
513        }
514    }
515}
516
517impl std::hash::Hash for ScalarValue {
518    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
519        use ScalarValue::*;
520        match self {
521            Boolean(v) => v.hash(state),
522            Float32(v) => v.map(Fl).hash(state),
523            Float64(v) => v.map(Fl).hash(state),
524            Int8(v) => v.hash(state),
525            Int16(v) => v.hash(state),
526            Int32(v) => v.hash(state),
527            Int64(v) => v.hash(state),
528            UInt8(v) => v.hash(state),
529            UInt16(v) => v.hash(state),
530            UInt32(v) => v.hash(state),
531            UInt64(v) => v.hash(state),
532            Varchar(v) => v.hash(state),
533        }
534    }
535}
536
537//Float wrapper over f32/f64. Just because we cannot build std::hash::Hash for floats directly we have to do it through type wrapper
538struct Fl<T>(T);
539
540macro_rules! hash_float_value {
541    ($(($t:ty, $i:ty)),+) => {
542        $(impl std::hash::Hash for Fl<$t> {
543            #[inline]
544            fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
545                state.write(&<$i>::from_ne_bytes(self.0.to_ne_bytes()).to_ne_bytes())
546            }
547        })+
548    };
549}
550
551hash_float_value!((f64, u64), (f32, u32));
552
553impl std::fmt::Display for ScalarValue {
554    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
555        match self {
556            ScalarValue::Boolean(None) => write!(f, "NULL"),
557            ScalarValue::Boolean(Some(v)) => write!(f, "{v}"),
558            ScalarValue::Int8(None) => write!(f, "NULL"),
559            ScalarValue::Int8(Some(v)) => write!(f, "{v}"),
560            ScalarValue::Int16(None) => write!(f, "NULL"),
561            ScalarValue::Int16(Some(v)) => write!(f, "{v}"),
562            ScalarValue::Int32(None) => write!(f, "NULL"),
563            ScalarValue::Int32(Some(v)) => write!(f, "{v}"),
564            ScalarValue::Int64(None) => write!(f, "NULL"),
565            ScalarValue::Int64(Some(v)) => write!(f, "{v}"),
566            ScalarValue::UInt8(None) => write!(f, "NULL"),
567            ScalarValue::UInt8(Some(v)) => write!(f, "{v}"),
568            ScalarValue::UInt16(None) => write!(f, "NULL"),
569            ScalarValue::UInt16(Some(v)) => write!(f, "{v}"),
570            ScalarValue::UInt32(None) => write!(f, "NULL"),
571            ScalarValue::UInt32(Some(v)) => write!(f, "{v}"),
572            ScalarValue::UInt64(None) => write!(f, "NULL"),
573            ScalarValue::UInt64(Some(v)) => write!(f, "{v}"),
574            ScalarValue::Float32(None) => write!(f, "NULL"),
575            ScalarValue::Float32(Some(v)) => write!(f, "{v}"),
576            ScalarValue::Float64(None) => write!(f, "NULL"),
577            ScalarValue::Float64(Some(v)) => write!(f, "{v}"),
578            ScalarValue::Varchar(None) => write!(f, "NULL"),
579            ScalarValue::Varchar(Some(v)) => write!(f, "{v}"),
580        }
581    }
582}
583
584macro_rules! impl_from_for_scalar {
585    ($ty:ty, $scalar:tt) => {
586        impl From<$ty> for ScalarValue {
587            fn from(value: $ty) -> Self {
588                ScalarValue::$scalar(Some(value))
589            }
590        }
591
592        impl From<Option<$ty>> for ScalarValue {
593            fn from(value: Option<$ty>) -> Self {
594                ScalarValue::$scalar(value)
595            }
596        }
597    };
598}
599
600impl_from_for_scalar!(bool, Boolean);
601impl_from_for_scalar!(i8, Int8);
602impl_from_for_scalar!(i16, Int16);
603impl_from_for_scalar!(i32, Int32);
604impl_from_for_scalar!(i64, Int64);
605impl_from_for_scalar!(u8, UInt8);
606impl_from_for_scalar!(u16, UInt16);
607impl_from_for_scalar!(u32, UInt32);
608impl_from_for_scalar!(u64, UInt64);
609impl_from_for_scalar!(f32, Float32);
610impl_from_for_scalar!(f64, Float64);
611impl_from_for_scalar!(String, Varchar);