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) | Value::Object(x) => Ok(String::from_utf8(x)?),
179            _ => Err(unexpected_type(type_)),
180        }
181    }
182}
183
184impl<T: FromSql + 'static> FromSql for Vec<T> {
185    fn from_sql(type_: &Type, value: Value) -> Result<Self> {
186        let subtype = match type_ {
187            Type::Array(x) => x,
188            x => return Err(unexpected_type(x)),
189        }
190        .strip_low_cardinality();
191        match value {
192            Value::String(x) if *subtype == Type::UInt8 || *subtype == Type::Int8 => {
193                let type_id = TypeId::of::<T>();
194                if type_id != TypeId::of::<u8>() && type_id != TypeId::of::<i8>() {
195                    return Err(unexpected_type(subtype));
196                }
197                assert_eq!(size_of::<T>(), 1);
198                Ok(unsafe { std::mem::transmute::<Vec<u8>, Vec<T>>(x) })
199            }
200            Value::Array(x) => {
201                Ok(x.into_iter().map(|x| T::from_sql(subtype, x)).collect::<Result<Vec<_>>>()?)
202            }
203            _ => Err(unexpected_type(type_)),
204        }
205    }
206}
207
208impl<T: FromSql + Hash + Eq, Y: FromSql, S: ::std::hash::BuildHasher + Default> FromSql
209    for HashMap<T, Y, S>
210{
211    fn from_sql(type_: &Type, value: Value) -> Result<Self> {
212        let (x_type, y_type) = match type_ {
213            Type::Map(x_type, y_type) => {
214                (x_type.strip_low_cardinality(), y_type.strip_low_cardinality())
215            }
216            x => return Err(unexpected_type(x)),
217        };
218        match value {
219            Value::Map(x, y) => {
220                let mut out = HashMap::default();
221                for (x, y) in x.into_iter().zip(y.into_iter()) {
222                    drop(out.insert(T::from_sql(x_type, x)?, Y::from_sql(y_type, y)?));
223                }
224                Ok(out)
225            }
226            _ => Err(unexpected_type(type_)),
227        }
228    }
229}
230
231impl<T: FromSql + Ord, Y: FromSql> FromSql for BTreeMap<T, Y> {
232    fn from_sql(type_: &Type, value: Value) -> Result<Self> {
233        let (x_type, y_type) = match type_ {
234            Type::Map(x_type, y_type) => {
235                (x_type.strip_low_cardinality(), y_type.strip_low_cardinality())
236            }
237            x => return Err(unexpected_type(x)),
238        };
239        match value {
240            Value::Map(x, y) => {
241                let mut out = BTreeMap::new();
242                for (x, y) in x.into_iter().zip(y.into_iter()) {
243                    drop(out.insert(T::from_sql(x_type, x)?, Y::from_sql(y_type, y)?));
244                }
245                Ok(out)
246            }
247            _ => Err(unexpected_type(type_)),
248        }
249    }
250}
251
252impl<T: FromSql + Hash + Eq, Y: FromSql, S: ::std::hash::BuildHasher + Default> FromSql
253    for IndexMap<T, Y, S>
254{
255    fn from_sql(type_: &Type, value: Value) -> Result<Self> {
256        let (x_type, y_type) = match type_ {
257            Type::Map(x_type, y_type) => {
258                (x_type.strip_low_cardinality(), y_type.strip_low_cardinality())
259            }
260            x => return Err(unexpected_type(x)),
261        };
262        match value {
263            Value::Map(x, y) => {
264                let mut out = IndexMap::<T, Y, S>::with_capacity_and_hasher(x.len(), S::default());
265                for (x, y) in x.into_iter().zip(y.into_iter()) {
266                    drop(out.insert(T::from_sql(x_type, x)?, Y::from_sql(y_type, y)?));
267                }
268                Ok(out)
269            }
270            _ => Err(unexpected_type(type_)),
271        }
272    }
273}
274
275#[cfg(feature = "serde")]
276impl FromSql for serde_json::Value {
277    fn from_sql(type_: &Type, value: Value) -> Result<Self> {
278        if !matches!(type_, Type::Object | Type::String) {
279            return Err(unexpected_type(type_));
280        }
281        match value {
282            Value::Object(x) => {
283                Ok(serde_json::from_slice(&x)
284                    .map_err(|e| Error::DeserializeError(e.to_string()))?)
285            }
286            _ => Err(unexpected_type(type_)),
287        }
288    }
289}
290
291impl<T: FromSql> FromSql for Option<T> {
292    fn from_sql(type_: &Type, value: Value) -> Result<Self> {
293        let subtype = match type_ {
294            Type::Nullable(x) => x.strip_low_cardinality(),
295            x => return Err(unexpected_type(x)),
296        };
297        match value {
298            Value::Null => Ok(None),
299            x => Ok(Some(T::from_sql(subtype, x)?)),
300        }
301    }
302}
303
304impl<T: FromSql + Default + Copy, const N: usize> FromSql for [T; N] {
305    fn from_sql(type_: &Type, value: Value) -> Result<Self> {
306        let subtype = match type_ {
307            Type::Array(x) => x.strip_low_cardinality(),
308            x => return Err(unexpected_type(x)),
309        };
310        match value {
311            Value::Array(x) => {
312                if x.len() != N {
313                    return Err(Error::DeserializeError(format!(
314                        "invalid length for array: {} expected {}",
315                        x.len(),
316                        N
317                    )));
318                }
319                let mut out = [T::default(); N];
320                for (i, value) in x.into_iter().enumerate() {
321                    out[i] = T::from_sql(subtype, value)?;
322                }
323                Ok(out)
324            }
325            _ => Err(unexpected_type(type_)),
326        }
327    }
328}
329
330impl<T: FromSql> FromSql for Box<T> {
331    fn from_sql(type_: &Type, value: Value) -> Result<Self> {
332        Ok(Box::new(T::from_sql(type_, value)?))
333    }
334}
335
336macro_rules! tuple_impls {
337    ($($len:expr => ($($n:tt $name:ident)+))+) => {
338        $(
339            impl<$($name: FromSql),+> FromSql for ($($name,)+) {
340                fn from_sql(type_: &Type, value: Value) -> Result<Self> {
341                    let subtype = match type_ {
342                        Type::Tuple(x) => &**x,
343                        x => return Err(unexpected_type(x)),
344                    };
345                    let Value::Tuple(values) = value else { return Err(unexpected_type(type_)) };
346                    if values.len() != subtype.len() {
347                        return Err(Error::DeserializeError(format!("unexpected type: mismatch tuple length expected {}, got {}", subtype.len(), values.len())));
348                    }
349                    if values.len() != $len {
350                        return Err(Error::DeserializeError(format!("unexpected type: mismatch tuple length expected {}, got {}", $len, values.len())));
351                    }
352                    let mut deque = ::std::collections::VecDeque::from(values);
353                    Ok((
354                        $(
355                            $name::from_sql(subtype[$n].strip_low_cardinality(), deque.pop_front().unwrap())?,
356                        )+
357                    ))
358                }
359            }
360        )+
361    }
362}
363
364tuple_impls! {
365    1 => (0 T0)
366    2 => (0 T0 1 T1)
367    3 => (0 T0 1 T1 2 T2)
368    4 => (0 T0 1 T1 2 T2 3 T3)
369    5 => (0 T0 1 T1 2 T2 3 T3 4 T4)
370    6 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5)
371    7 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6)
372    8 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7)
373    9 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8)
374    10 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9)
375    11 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10)
376    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)
377    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)
378    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)
379    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)
380    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)
381}