opensrv_clickhouse/types/column/
tuple.rs

1// Copyright 2021 Datafuse Labs.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use std::sync::Arc;
16
17use chrono_tz::Tz;
18
19use crate::binary::Encoder;
20use crate::binary::ReadEx;
21use crate::errors::Result;
22use crate::types::column::column_data::ArcColumnData;
23use crate::types::column::column_data::BoxColumnData;
24use crate::types::column::ArcColumnWrapper;
25use crate::types::column::ColumnData;
26use crate::types::column::ColumnFrom;
27use crate::types::column::ColumnWrapper;
28use crate::types::SqlType;
29use crate::types::Value;
30use crate::types::ValueRef;
31
32pub struct TupleColumnData {
33    pub inner: Vec<ArcColumnData>,
34}
35
36impl TupleColumnData {
37    pub(crate) fn load<R: ReadEx>(
38        reader: &mut R,
39        inner_types: Vec<&str>,
40        rows: usize,
41        tz: Tz,
42    ) -> Result<Self> {
43        let inner = inner_types
44            .into_iter()
45            .map(|type_name| {
46                <dyn ColumnData>::load_data::<ArcColumnWrapper, _>(reader, type_name, rows, tz)
47                    .unwrap()
48            })
49            .collect();
50        Ok(Self { inner })
51    }
52}
53
54impl ColumnFrom for Vec<ArcColumnData> {
55    fn column_from<W: ColumnWrapper>(inner: Self) -> W::Wrapper {
56        W::wrap(TupleColumnData { inner })
57    }
58}
59
60impl ColumnData for TupleColumnData {
61    fn sql_type(&self) -> SqlType {
62        SqlType::Tuple(self.inner.iter().map(|c| c.sql_type().into()).collect())
63    }
64
65    fn save(&self, encoder: &mut Encoder, start: usize, end: usize) {
66        self.inner.iter().for_each(|c| c.save(encoder, start, end));
67    }
68
69    fn len(&self) -> usize {
70        self.inner[0].len()
71    }
72
73    fn push(&mut self, value: Value) {
74        if let Value::Tuple(vs) = value {
75            vs.iter().zip(self.inner.iter_mut()).for_each(|(v, c)| {
76                let inner_column = Arc::get_mut(c).unwrap();
77                inner_column.push(v.clone());
78            });
79        } else {
80            panic!("value should be a tuple");
81        }
82    }
83
84    fn at(&self, index: usize) -> ValueRef {
85        ValueRef::Tuple(Arc::new(self.inner.iter().map(|c| c.at(index)).collect()))
86    }
87
88    fn clone_instance(&self) -> BoxColumnData {
89        Box::new(Self {
90            inner: self.inner.clone(),
91        })
92    }
93
94    fn cast_to(&self, _this: &ArcColumnData, target: &SqlType) -> Option<ArcColumnData> {
95        if let SqlType::Tuple(target_types) = target {
96            if target_types.len() == self.inner.len() {
97                let mut new_inner = Vec::with_capacity(self.inner.len());
98                for (i, c) in self.inner.iter().enumerate() {
99                    let target_type = target_types[i];
100                    let new_c = c.cast_to(c, target_type);
101                    if let Some(new_c) = new_c {
102                        new_inner.push(new_c);
103                    } else {
104                        return None;
105                    }
106                }
107                return Some(Arc::new(TupleColumnData { inner: new_inner }));
108            }
109        }
110        None
111    }
112}