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) | 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}