clickhouse_client/query/sql/
mod.rs

1//! SQL
2
3#[cfg(test)]
4mod tests;
5
6use ethnum::{I256, U256};
7use time::{Date, OffsetDateTime};
8use uuid::Uuid;
9
10use crate::value::{
11    time::{DateExt, DateTimeExt},
12    Value,
13};
14
15impl Value {
16    /// Converts a [Value] to a SQL string
17    pub fn to_sql_string(&self) -> String {
18        /// Implements the nullable variant for formatting
19        macro_rules! impl_nullable {
20            ($VAL:expr, $VAR:ident) => {
21                match $VAL {
22                    Some(v) => Value::$VAR(v).to_sql_string(),
23                    None => "NULL".to_string(),
24                }
25            };
26        }
27
28        match self {
29            Value::UInt8(v) => v.to_string(),
30            Value::UInt16(v) => v.to_string(),
31            Value::UInt32(v) => v.to_string(),
32            Value::UInt64(v) => v.to_string(),
33            Value::UInt128(v) => v.to_string(),
34            Value::UInt256(_) => {
35                let u256 = self.clone().try_into::<U256>().unwrap();
36                u256.to_string()
37            }
38            Value::Int8(v) => v.to_string(),
39            Value::Int16(v) => v.to_string(),
40            Value::Int32(v) => v.to_string(),
41            Value::Int64(v) => v.to_string(),
42            Value::Int128(v) => v.to_string(),
43            Value::Int256(_) => {
44                let i256 = self.clone().try_into::<I256>().unwrap();
45                i256.to_string()
46            }
47            Value::Float32(v) => v.to_string(),
48            Value::Float64(v) => v.to_string(),
49            Value::Bool(v) => match v {
50                false => "0".to_string(),
51                true => "1".to_string(),
52            },
53            Value::String(v) => format!("'{}'", v),
54            Value::UUID(_) => {
55                // UUID string uses a 8-4-4-4-12 representation
56                let uuid = self.clone().try_into::<Uuid>().unwrap();
57                let uuid_str = uuid.as_hyphenated().to_string();
58                format!("'{uuid_str}'")
59            }
60            Value::Date(_) | Value::Date32(_) => {
61                let date = self.clone().try_into::<Date>().unwrap();
62                let date_str = date.format_yyyy_mm_dd();
63                format!("'{date_str}'")
64            }
65            Value::DateTime(_) => {
66                let dt = self.clone().try_into::<OffsetDateTime>().unwrap();
67                let dt_str = dt.format_yyyy_mm_dd_hh_mm_ss();
68                format!("'{dt_str}'")
69            }
70            Value::DateTime64(_) => {
71                let dt = self.clone().try_into::<OffsetDateTime>().unwrap();
72                let dt_str = dt.format_yyyy_mm_dd_hh_mm_ss_ns();
73                format!("'{dt_str}'")
74            }
75            Value::Enum8(v) => v.to_string(),
76            Value::Enum16(v) => v.to_string(),
77            Value::Array(values) => format!(
78                "[{}]",
79                values
80                    .iter()
81                    .map(|v| v.to_sql_string())
82                    .collect::<Vec<_>>()
83                    .join(", ")
84            ),
85            Value::Tuple(values) => format!(
86                "({})",
87                values
88                    .iter()
89                    .map(|v| v.to_sql_string())
90                    .collect::<Vec<_>>()
91                    .join(", ")
92            ),
93            Value::Map(values) => format!(
94                "{{{}}}",
95                values
96                    .iter()
97                    .map(|(k, v)| format!("'{}': {}", k, v.to_sql_string()))
98                    .collect::<Vec<_>>()
99                    .join(", ")
100            ),
101            Value::Nested(values) => format!(
102                "{{{}}}",
103                values
104                    .iter()
105                    .map(|(k, v)| format!("'{}': {}", k, v.to_sql_string()))
106                    .collect::<Vec<_>>()
107                    .join(", ")
108            ),
109            Value::NullableUInt8(v) => impl_nullable!(*v, UInt8),
110            Value::NullableUInt16(v) => impl_nullable!(*v, UInt16),
111            Value::NullableUInt32(v) => impl_nullable!(*v, UInt32),
112            Value::NullableUInt64(v) => impl_nullable!(*v, UInt64),
113            Value::NullableUInt128(v) => impl_nullable!(*v, UInt128),
114            Value::NullableUInt256(v) => impl_nullable!(*v, UInt256),
115            Value::NullableInt8(v) => impl_nullable!(*v, Int8),
116            Value::NullableInt16(v) => impl_nullable!(*v, Int16),
117            Value::NullableInt32(v) => impl_nullable!(*v, Int32),
118            Value::NullableInt64(v) => impl_nullable!(*v, Int64),
119            Value::NullableInt128(v) => impl_nullable!(*v, Int128),
120            Value::NullableInt256(v) => impl_nullable!(*v, Int256),
121            Value::NullableFloat32(v) => impl_nullable!(*v, Float32),
122            Value::NullableFloat64(v) => impl_nullable!(*v, Float64),
123            Value::NullableBool(v) => impl_nullable!(*v, Bool),
124            Value::NullableString(v) => impl_nullable!(v.clone(), String),
125            Value::NullableUUID(v) => impl_nullable!(*v, UUID),
126            Value::NullableDate(v) => impl_nullable!(*v, Date),
127            Value::NullableDate32(v) => impl_nullable!(*v, Date32),
128            Value::NullableDateTime(v) => impl_nullable!(*v, DateTime),
129            Value::NullableDateTime64(v) => impl_nullable!(*v, DateTime64),
130            Value::NullableEnum8(v) => impl_nullable!(*v, Enum8),
131            Value::NullableEnum16(v) => impl_nullable!(*v, Enum16),
132        }
133    }
134}