clickhouse_arrow/native/convert/
std_deserialize.rs

1use std::any::TypeId;
2use std::collections::{BTreeMap, HashMap};
3use std::hash::Hash;
4
5use indexmap::IndexMap;
6
7use super::*;
8
9impl FromSql for bool {
10    fn from_sql(type_: &Type, value: Value) -> Result<Self> {
11        if !matches!(type_, Type::UInt8) {
12            return Err(unexpected_type(type_));
13        }
14        match value {
15            Value::UInt8(x) => Ok(x != 0),
16            _ => Err(unexpected_type(type_)),
17        }
18    }
19}
20
21impl FromSql for u8 {
22    fn from_sql(type_: &Type, value: Value) -> Result<Self> {
23        if !matches!(type_, Type::UInt8) {
24            return Err(unexpected_type(type_));
25        }
26        match value {
27            Value::UInt8(x) => Ok(x),
28            _ => Err(unexpected_type(type_)),
29        }
30    }
31}
32
33impl FromSql for u16 {
34    fn from_sql(type_: &Type, value: Value) -> Result<Self> {
35        if !matches!(type_, Type::UInt16) {
36            return Err(unexpected_type(type_));
37        }
38        match value {
39            Value::UInt16(x) => Ok(x),
40            _ => Err(unexpected_type(type_)),
41        }
42    }
43}
44
45impl FromSql for u32 {
46    fn from_sql(type_: &Type, value: Value) -> Result<Self> {
47        if !matches!(type_, Type::UInt32) {
48            return Err(unexpected_type(type_));
49        }
50        match value {
51            Value::UInt32(x) => Ok(x),
52            _ => Err(unexpected_type(type_)),
53        }
54    }
55}
56
57impl FromSql for u64 {
58    fn from_sql(type_: &Type, value: Value) -> Result<Self> {
59        if !matches!(type_, Type::UInt64) {
60            return Err(unexpected_type(type_));
61        }
62        match value {
63            Value::UInt64(x) => Ok(x),
64            _ => Err(unexpected_type(type_)),
65        }
66    }
67}
68
69impl FromSql for u128 {
70    fn from_sql(type_: &Type, value: Value) -> Result<Self> {
71        if !matches!(type_, Type::UInt128) {
72            return Err(unexpected_type(type_));
73        }
74        match value {
75            Value::UInt128(x) => Ok(x),
76            _ => Err(unexpected_type(type_)),
77        }
78    }
79}
80
81impl FromSql for i8 {
82    fn from_sql(type_: &Type, value: Value) -> Result<Self> {
83        if !matches!(type_, Type::Int8) {
84            return Err(unexpected_type(type_));
85        }
86        match value {
87            Value::Int8(x) => Ok(x),
88            _ => Err(unexpected_type(type_)),
89        }
90    }
91}
92
93impl FromSql for i16 {
94    fn from_sql(type_: &Type, value: Value) -> Result<Self> {
95        if !matches!(type_, Type::Int16) {
96            return Err(unexpected_type(type_));
97        }
98        match value {
99            Value::Int16(x) => Ok(x),
100            _ => Err(unexpected_type(type_)),
101        }
102    }
103}
104
105impl FromSql for i32 {
106    fn from_sql(type_: &Type, value: Value) -> Result<Self> {
107        if !matches!(type_, Type::Int32) {
108            return Err(unexpected_type(type_));
109        }
110        match value {
111            Value::Int32(x) => Ok(x),
112            _ => Err(unexpected_type(type_)),
113        }
114    }
115}
116
117impl FromSql for i64 {
118    fn from_sql(type_: &Type, value: Value) -> Result<Self> {
119        if !matches!(type_, Type::Int64) {
120            return Err(unexpected_type(type_));
121        }
122        match value {
123            Value::Int64(x) => Ok(x),
124            _ => Err(unexpected_type(type_)),
125        }
126    }
127}
128
129impl FromSql for i128 {
130    fn from_sql(type_: &Type, value: Value) -> Result<Self> {
131        if !matches!(type_, Type::Int128) {
132            return Err(unexpected_type(type_));
133        }
134        match value {
135            Value::Int128(x) => Ok(x),
136            _ => Err(unexpected_type(type_)),
137        }
138    }
139}
140
141impl FromSql for f32 {
142    fn from_sql(type_: &Type, value: Value) -> Result<Self> {
143        if !matches!(type_, Type::Float32) {
144            return Err(unexpected_type(type_));
145        }
146        match value {
147            Value::Float32(x) => Ok(x),
148            _ => Err(unexpected_type(type_)),
149        }
150    }
151}
152
153impl FromSql for f64 {
154    fn from_sql(type_: &Type, value: Value) -> Result<Self> {
155        if !matches!(type_, Type::Float64) {
156            return Err(unexpected_type(type_));
157        }
158        match value {
159            Value::Float64(x) => Ok(x),
160            _ => Err(unexpected_type(type_)),
161        }
162    }
163}
164
165impl FromSql for String {
166    fn from_sql(type_: &Type, value: Value) -> Result<Self> {
167        if !matches!(
168            type_,
169            Type::String
170                | Type::FixedSizedString(_)
171                | Type::Binary
172                | Type::FixedSizedBinary(_)
173                | Type::Object
174        ) {
175            return Err(unexpected_type(type_));
176        }
177        match value {
178            Value::String(x) => Ok(String::from_utf8(x)?),
179            Value::Object(x) => Ok(String::from_utf8(x)?),
180            _ => Err(unexpected_type(type_)),
181        }
182    }
183}
184
185impl<T: FromSql + 'static> FromSql for Vec<T> {
186    fn from_sql(type_: &Type, value: Value) -> Result<Self> {
187        let subtype = match type_ {
188            Type::Array(x) => x,
189            x => return Err(unexpected_type(x)),
190        }
191        .strip_low_cardinality();
192        match value {
193            Value::String(x) if *subtype == Type::UInt8 || *subtype == Type::Int8 => {
194                let type_id = TypeId::of::<T>();
195                if type_id != TypeId::of::<u8>() && type_id != TypeId::of::<i8>() {
196                    return Err(unexpected_type(subtype));
197                }
198                assert_eq!(size_of::<T>(), 1);
199                Ok(unsafe { std::mem::transmute::<Vec<u8>, Vec<T>>(x) })
200            }
201            Value::Array(x) => {
202                Ok(x.into_iter().map(|x| T::from_sql(subtype, x)).collect::<Result<Vec<_>>>()?)
203            }
204            _ => Err(unexpected_type(type_)),
205        }
206    }
207}
208
209impl<T: FromSql + Hash + Eq, Y: FromSql, S: ::std::hash::BuildHasher + Default> FromSql
210    for HashMap<T, Y, S>
211{
212    fn from_sql(type_: &Type, value: Value) -> Result<Self> {
213        let (x_type, y_type) = match type_ {
214            Type::Map(x_type, y_type) => {
215                (x_type.strip_low_cardinality(), y_type.strip_low_cardinality())
216            }
217            x => return Err(unexpected_type(x)),
218        };
219        match value {
220            Value::Map(x, y) => {
221                let mut out = HashMap::default();
222                for (x, y) in x.into_iter().zip(y.into_iter()) {
223                    drop(out.insert(T::from_sql(x_type, x)?, Y::from_sql(y_type, y)?));
224                }
225                Ok(out)
226            }
227            _ => Err(unexpected_type(type_)),
228        }
229    }
230}
231
232impl<T: FromSql + Ord, Y: FromSql> FromSql for BTreeMap<T, Y> {
233    fn from_sql(type_: &Type, value: Value) -> Result<Self> {
234        let (x_type, y_type) = match type_ {
235            Type::Map(x_type, y_type) => {
236                (x_type.strip_low_cardinality(), y_type.strip_low_cardinality())
237            }
238            x => return Err(unexpected_type(x)),
239        };
240        match value {
241            Value::Map(x, y) => {
242                let mut out = BTreeMap::new();
243                for (x, y) in x.into_iter().zip(y.into_iter()) {
244                    drop(out.insert(T::from_sql(x_type, x)?, Y::from_sql(y_type, y)?));
245                }
246                Ok(out)
247            }
248            _ => Err(unexpected_type(type_)),
249        }
250    }
251}
252
253impl<T: FromSql + Hash + Eq, Y: FromSql, S: ::std::hash::BuildHasher + Default> FromSql
254    for IndexMap<T, Y, S>
255{
256    fn from_sql(type_: &Type, value: Value) -> Result<Self> {
257        let (x_type, y_type) = match type_ {
258            Type::Map(x_type, y_type) => {
259                (x_type.strip_low_cardinality(), y_type.strip_low_cardinality())
260            }
261            x => return Err(unexpected_type(x)),
262        };
263        match value {
264            Value::Map(x, y) => {
265                let mut out = IndexMap::<T, Y, S>::with_capacity_and_hasher(x.len(), S::default());
266                for (x, y) in x.into_iter().zip(y.into_iter()) {
267                    drop(out.insert(T::from_sql(x_type, x)?, Y::from_sql(y_type, y)?));
268                }
269                Ok(out)
270            }
271            _ => Err(unexpected_type(type_)),
272        }
273    }
274}
275
276#[cfg(feature = "serde")]
277impl FromSql for serde_json::Value {
278    fn from_sql(type_: &Type, value: Value) -> Result<Self> {
279        if !matches!(type_, Type::Object | Type::String) {
280            return Err(unexpected_type(type_));
281        }
282        match value {
283            Value::Object(x) => {
284                Ok(serde_json::from_slice(&x)
285                    .map_err(|e| Error::DeserializeError(e.to_string()))?)
286            }
287            _ => Err(unexpected_type(type_)),
288        }
289    }
290}
291
292impl<T: FromSql> FromSql for Option<T> {
293    fn from_sql(type_: &Type, value: Value) -> Result<Self> {
294        let subtype = match type_ {
295            Type::Nullable(x) => x.strip_low_cardinality(),
296            x => return Err(unexpected_type(x)),
297        };
298        match value {
299            Value::Null => Ok(None),
300            x => Ok(Some(T::from_sql(subtype, x)?)),
301        }
302    }
303}
304
305impl<T: FromSql + Default + Copy, const N: usize> FromSql for [T; N] {
306    fn from_sql(type_: &Type, value: Value) -> Result<Self> {
307        let subtype = match type_ {
308            Type::Array(x) => x.strip_low_cardinality(),
309            x => return Err(unexpected_type(x)),
310        };
311        match value {
312            Value::Array(x) => {
313                if x.len() != N {
314                    return Err(Error::DeserializeError(format!(
315                        "invalid length for array: {} expected {}",
316                        x.len(),
317                        N
318                    )));
319                }
320                let mut out = [T::default(); N];
321                for (i, value) in x.into_iter().enumerate() {
322                    out[i] = T::from_sql(subtype, value)?;
323                }
324                Ok(out)
325            }
326            _ => Err(unexpected_type(type_)),
327        }
328    }
329}
330
331impl<T: FromSql> FromSql for Box<T> {
332    fn from_sql(type_: &Type, value: Value) -> Result<Self> {
333        Ok(Box::new(T::from_sql(type_, value)?))
334    }
335}
336
337macro_rules! tuple_impls {
338    ($($len:expr => ($($n:tt $name:ident)+))+) => {
339        $(
340            impl<$($name: FromSql),+> FromSql for ($($name,)+) {
341                fn from_sql(type_: &Type, value: Value) -> Result<Self> {
342                    let subtype = match type_ {
343                        Type::Tuple(x) => &**x,
344                        x => return Err(unexpected_type(x)),
345                    };
346                    let Value::Tuple(values) = value else { return Err(unexpected_type(type_)) };
347                    if values.len() != subtype.len() {
348                        return Err(Error::DeserializeError(format!("unexpected type: mismatch tuple length expected {}, got {}", subtype.len(), values.len())));
349                    }
350                    if values.len() != $len {
351                        return Err(Error::DeserializeError(format!("unexpected type: mismatch tuple length expected {}, got {}", $len, values.len())));
352                    }
353                    let mut deque = ::std::collections::VecDeque::from(values);
354                    Ok((
355                        $(
356                            $name::from_sql(subtype[$n].strip_low_cardinality(), deque.pop_front().unwrap())?,
357                        )+
358                    ))
359                }
360            }
361        )+
362    }
363}
364
365tuple_impls! {
366    1 => (0 T0)
367    2 => (0 T0 1 T1)
368    3 => (0 T0 1 T1 2 T2)
369    4 => (0 T0 1 T1 2 T2 3 T3)
370    5 => (0 T0 1 T1 2 T2 3 T3 4 T4)
371    6 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5)
372    7 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6)
373    8 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7)
374    9 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8)
375    10 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9)
376    11 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10)
377    12 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11)
378    13 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11 12 T12)
379    14 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11 12 T12 13 T13)
380    15 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11 12 T12 13 T13 14 T14)
381    16 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11 12 T12 13 T13 14 T14 15 T15)
382}