opensrv_clickhouse/types/column/
numeric.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::convert;
16use std::mem;
17use std::sync::Arc;
18
19use micromarshal::Marshal;
20use micromarshal::Unmarshal;
21
22use super::column_data::BoxColumnData;
23use super::column_data::ColumnData;
24use super::list::List;
25use super::ColumnFrom;
26use crate::binary::Encoder;
27use crate::binary::ReadEx;
28use crate::errors::Result;
29use crate::types::column::array::ArrayColumnData;
30use crate::types::column::nullable::NullableColumnData;
31use crate::types::column::ArcColumnWrapper;
32use crate::types::column::ColumnWrapper;
33use crate::types::HasSqlType;
34use crate::types::SqlType;
35use crate::types::StatBuffer;
36use crate::types::Value;
37use crate::types::ValueRef;
38
39pub struct VectorColumnData<T>
40where
41    T: StatBuffer
42        + Unmarshal<T>
43        + Marshal
44        + Copy
45        + convert::Into<Value>
46        + convert::From<Value>
47        + Sync
48        + HasSqlType
49        + 'static,
50{
51    pub(crate) data: List<T>,
52}
53
54impl<T> ColumnFrom for Vec<T>
55where
56    T: StatBuffer
57        + Unmarshal<T>
58        + Marshal
59        + Copy
60        + convert::Into<Value>
61        + convert::From<Value>
62        + Send
63        + Sync
64        + HasSqlType
65        + 'static,
66{
67    fn column_from<W: ColumnWrapper>(source: Self) -> W::Wrapper {
68        let mut data = List::with_capacity(source.len());
69        for s in source {
70            data.push(s);
71        }
72        W::wrap(VectorColumnData { data })
73    }
74}
75
76impl<T> ColumnFrom for Vec<Option<T>>
77where
78    Value: convert::From<T>,
79    T: StatBuffer
80        + Unmarshal<T>
81        + Marshal
82        + Copy
83        + convert::Into<Value>
84        + convert::From<Value>
85        + Send
86        + Sync
87        + HasSqlType
88        + 'static,
89{
90    fn column_from<W: ColumnWrapper>(source: Self) -> W::Wrapper {
91        let fake: Vec<T> = Vec::with_capacity(source.len());
92        let inner = Vec::column_from::<ArcColumnWrapper>(fake);
93
94        let mut data = NullableColumnData {
95            inner,
96            nulls: Vec::with_capacity(source.len()),
97        };
98
99        for value in source {
100            data.push(value.into());
101        }
102
103        W::wrap(data)
104    }
105}
106
107impl<T> ColumnFrom for Vec<Vec<T>>
108where
109    Value: convert::From<T>,
110    T: StatBuffer
111        + Unmarshal<T>
112        + Marshal
113        + Copy
114        + convert::Into<Value>
115        + convert::From<Value>
116        + Send
117        + Sync
118        + HasSqlType
119        + 'static,
120{
121    fn column_from<W: ColumnWrapper>(source: Self) -> W::Wrapper {
122        let fake: Vec<T> = Vec::with_capacity(source.len());
123        let inner = Vec::column_from::<ArcColumnWrapper>(fake);
124        let sql_type = inner.sql_type();
125
126        let mut data = ArrayColumnData {
127            inner,
128            offsets: List::with_capacity(source.len()),
129        };
130
131        for array in source {
132            data.push(to_array(sql_type.clone(), array));
133        }
134
135        W::wrap(data)
136    }
137}
138
139fn to_array<T>(sql_type: SqlType, vs: Vec<T>) -> Value
140where
141    Value: convert::From<T>,
142    T: StatBuffer
143        + Unmarshal<T>
144        + Marshal
145        + Copy
146        + convert::Into<Value>
147        + convert::From<Value>
148        + Send
149        + Sync
150        + HasSqlType
151        + 'static,
152{
153    let mut inner = Vec::with_capacity(vs.len());
154    for v in vs {
155        let value: Value = v.into();
156        inner.push(value)
157    }
158    Value::Array(sql_type.into(), Arc::new(inner))
159}
160
161impl<T> VectorColumnData<T>
162where
163    T: StatBuffer
164        + Unmarshal<T>
165        + Marshal
166        + Copy
167        + convert::Into<Value>
168        + convert::From<Value>
169        + Sync
170        + HasSqlType
171        + 'static,
172{
173    pub fn with_capacity(capacity: usize) -> VectorColumnData<T> {
174        VectorColumnData {
175            data: List::with_capacity(capacity),
176        }
177    }
178
179    pub(crate) fn load<R: ReadEx>(reader: &mut R, size: usize) -> Result<VectorColumnData<T>> {
180        let mut data = List::with_capacity(size);
181        unsafe {
182            data.set_len(size);
183        }
184        reader.read_bytes(data.as_mut())?;
185        Ok(Self { data })
186    }
187}
188
189impl<T> ColumnData for VectorColumnData<T>
190where
191    T: StatBuffer
192        + Unmarshal<T>
193        + Marshal
194        + Copy
195        + convert::Into<Value>
196        + convert::From<Value>
197        + Send
198        + Sync
199        + HasSqlType
200        + 'static,
201{
202    fn sql_type(&self) -> SqlType {
203        T::sql_type()
204    }
205
206    fn save(&self, encoder: &mut Encoder, start: usize, end: usize) {
207        save_data::<T>(self.data.as_ref(), encoder, start, end);
208    }
209
210    fn len(&self) -> usize {
211        self.data.len()
212    }
213
214    fn push(&mut self, value: Value) {
215        self.data.push(T::from(value));
216    }
217
218    fn at(&self, index: usize) -> ValueRef {
219        let v: Value = self.data.at(index).into();
220        match v {
221            Value::UInt8(x) => ValueRef::UInt8(x),
222            Value::UInt16(x) => ValueRef::UInt16(x),
223            Value::UInt32(x) => ValueRef::UInt32(x),
224            Value::UInt64(x) => ValueRef::UInt64(x),
225
226            Value::Int8(x) => ValueRef::Int8(x),
227            Value::Int16(x) => ValueRef::Int16(x),
228            Value::Int32(x) => ValueRef::Int32(x),
229            Value::Int64(x) => ValueRef::Int64(x),
230
231            Value::Float32(x) => ValueRef::Float32(x),
232            Value::Float64(x) => ValueRef::Float64(x),
233
234            _ => panic!("can't convert value to value_ref."),
235        }
236    }
237
238    fn clone_instance(&self) -> BoxColumnData {
239        Box::new(Self {
240            data: self.data.clone(),
241        })
242    }
243
244    unsafe fn get_internal(&self, pointers: &[*mut *const u8], level: u8) -> Result<()> {
245        assert_eq!(level, 0);
246        *pointers[0] = self.data.as_ptr() as *const u8;
247        *(pointers[1] as *mut usize) = self.len();
248        Ok(())
249    }
250}
251
252pub(crate) fn save_data<T>(data: &[u8], encoder: &mut Encoder, start: usize, end: usize) {
253    let start_index = start * mem::size_of::<T>();
254    let end_index = end * mem::size_of::<T>();
255    encoder.write_bytes(&data[start_index..end_index]);
256}