clickhouse_readonly/column/
numeric.rs

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