clickhouse_arrow/native/convert/
std_deserialize.rs1use 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}