opensrv_clickhouse/types/column/
ip.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::marker::PhantomData;
16use std::net::Ipv4Addr;
17use std::net::Ipv6Addr;
18use std::sync::Arc;
19
20use super::column_data::ColumnData;
21use super::ColumnFrom;
22use crate::binary::Encoder;
23use crate::binary::ReadEx;
24use crate::errors::Result;
25use crate::types::column::column_data::BoxColumnData;
26use crate::types::column::nullable::NullableColumnData;
27use crate::types::column::ColumnWrapper;
28use crate::types::SqlType;
29use crate::types::Value;
30use crate::types::ValueRef;
31
32pub(crate) trait IpVersion: Copy + Sync + Send + 'static {
33    fn sql_type() -> SqlType;
34    fn size() -> usize;
35    fn push(inner: &mut Vec<u8>, value: Value);
36    fn get(inner: &[u8], index: usize) -> ValueRef;
37}
38
39#[derive(Copy, Clone)]
40pub(crate) struct Ipv4;
41
42#[derive(Copy, Clone)]
43pub(crate) struct Ipv6;
44
45#[derive(Copy, Clone)]
46pub(crate) struct Uuid;
47
48impl IpVersion for Ipv4 {
49    #[inline(always)]
50    fn sql_type() -> SqlType {
51        SqlType::Ipv4
52    }
53
54    #[inline(always)]
55    fn size() -> usize {
56        4
57    }
58
59    #[inline(always)]
60    fn push(inner: &mut Vec<u8>, value: Value) {
61        if let Value::Ipv4(v) = value {
62            inner.extend(v);
63        } else {
64            panic!();
65        }
66    }
67
68    #[inline(always)]
69    fn get(inner: &[u8], index: usize) -> ValueRef {
70        let mut v: [u8; 4] = Default::default();
71        v.copy_from_slice(&inner[index * 4..(index + 1) * 4]);
72        ValueRef::Ipv4(v)
73    }
74}
75
76impl IpVersion for Ipv6 {
77    #[inline(always)]
78    fn sql_type() -> SqlType {
79        SqlType::Ipv6
80    }
81
82    #[inline(always)]
83    fn size() -> usize {
84        16
85    }
86
87    #[inline(always)]
88    fn push(inner: &mut Vec<u8>, value: Value) {
89        if let Value::Ipv6(v) = value {
90            inner.extend(v);
91        } else {
92            panic!();
93        }
94    }
95
96    #[inline(always)]
97    fn get(inner: &[u8], index: usize) -> ValueRef {
98        let mut v: [u8; 16] = Default::default();
99        v.copy_from_slice(&inner[index * 16..(index + 1) * 16]);
100        ValueRef::Ipv6(v)
101    }
102}
103
104impl IpVersion for Uuid {
105    #[inline(always)]
106    fn sql_type() -> SqlType {
107        SqlType::Uuid
108    }
109
110    #[inline(always)]
111    fn size() -> usize {
112        16
113    }
114
115    #[inline(always)]
116    fn push(inner: &mut Vec<u8>, value: Value) {
117        if let Value::Uuid(v) = value {
118            inner.extend(v);
119        } else {
120            panic!();
121        }
122    }
123
124    #[inline(always)]
125    fn get(inner: &[u8], index: usize) -> ValueRef {
126        let mut v: [u8; 16] = Default::default();
127        v.copy_from_slice(&inner[index * 16..(index + 1) * 16]);
128        ValueRef::Uuid(v)
129    }
130}
131
132impl ColumnFrom for Vec<Ipv4Addr> {
133    fn column_from<W: ColumnWrapper>(data: Self) -> W::Wrapper {
134        let mut inner = Vec::with_capacity(data.len());
135        for ip in data {
136            let mut buffer = ip.octets();
137            buffer.reverse();
138            inner.extend(buffer);
139        }
140
141        W::wrap(IpColumnData::<Ipv4> {
142            inner,
143            phantom: PhantomData,
144        })
145    }
146}
147
148impl ColumnFrom for Vec<Ipv6Addr> {
149    fn column_from<W: ColumnWrapper>(data: Self) -> W::Wrapper {
150        let mut inner = Vec::with_capacity(data.len());
151        for ip in data {
152            inner.extend(ip.octets());
153        }
154
155        W::wrap(IpColumnData::<Ipv6> {
156            inner,
157            phantom: PhantomData,
158        })
159    }
160}
161
162impl ColumnFrom for Vec<uuid::Uuid> {
163    fn column_from<W: ColumnWrapper>(data: Self) -> W::Wrapper {
164        let mut inner = Vec::with_capacity(data.len());
165        for uuid in data {
166            let mut buffer = *uuid.as_bytes();
167            buffer[..8].reverse();
168            buffer[8..].reverse();
169            inner.extend(buffer);
170        }
171
172        W::wrap(IpColumnData::<Uuid> {
173            inner,
174            phantom: PhantomData,
175        })
176    }
177}
178
179impl ColumnFrom for Vec<Option<Ipv4Addr>> {
180    fn column_from<W: ColumnWrapper>(source: Self) -> <W as ColumnWrapper>::Wrapper {
181        let n = source.len();
182        let mut inner: Vec<u8> = Vec::with_capacity(n * 4);
183        let mut nulls: Vec<u8> = Vec::with_capacity(n);
184
185        for ip in source {
186            match ip {
187                None => {
188                    inner.extend([0; 4]);
189                    nulls.push(1);
190                }
191                Some(ip) => {
192                    let mut buffer = ip.octets();
193                    buffer.reverse();
194                    inner.extend(buffer);
195                    nulls.push(0);
196                }
197            }
198        }
199
200        let inner = Arc::new(IpColumnData::<Ipv4> {
201            inner,
202            phantom: PhantomData,
203        });
204
205        let data = NullableColumnData { inner, nulls };
206
207        W::wrap(data)
208    }
209}
210
211impl ColumnFrom for Vec<Option<Ipv6Addr>> {
212    fn column_from<W: ColumnWrapper>(source: Self) -> <W as ColumnWrapper>::Wrapper {
213        let n = source.len();
214        let mut inner: Vec<u8> = Vec::with_capacity(n * 16);
215        let mut nulls: Vec<u8> = Vec::with_capacity(n);
216
217        for ip in source {
218            match ip {
219                None => {
220                    inner.extend([0; 16]);
221                    nulls.push(1);
222                }
223                Some(ip) => {
224                    inner.extend(ip.octets());
225                    nulls.push(0);
226                }
227            }
228        }
229
230        let inner = Arc::new(IpColumnData::<Ipv6> {
231            inner,
232            phantom: PhantomData,
233        });
234
235        let data = NullableColumnData { inner, nulls };
236
237        W::wrap(data)
238    }
239}
240
241impl ColumnFrom for Vec<Option<uuid::Uuid>> {
242    fn column_from<W: ColumnWrapper>(source: Self) -> <W as ColumnWrapper>::Wrapper {
243        let n = source.len();
244        let mut inner: Vec<u8> = Vec::with_capacity(n * 16);
245        let mut nulls: Vec<u8> = Vec::with_capacity(n);
246
247        for uuid in source {
248            match uuid {
249                None => {
250                    inner.extend([0; 16]);
251                    nulls.push(1);
252                }
253                Some(uuid) => {
254                    let mut buffer = *uuid.as_bytes();
255                    buffer[..8].reverse();
256                    buffer[8..].reverse();
257                    inner.extend(buffer);
258                    nulls.push(0);
259                }
260            }
261        }
262
263        let inner = Arc::new(IpColumnData::<Uuid> {
264            inner,
265            phantom: PhantomData,
266        });
267
268        let data = NullableColumnData { inner, nulls };
269
270        W::wrap(data)
271    }
272}
273
274pub(crate) struct IpColumnData<V: IpVersion> {
275    pub(crate) inner: Vec<u8>,
276    pub(crate) phantom: PhantomData<V>,
277}
278
279impl<V: IpVersion> IpColumnData<V> {
280    pub fn with_capacity(capacity: usize) -> Self {
281        Self {
282            inner: vec![0; capacity * V::size()],
283            phantom: PhantomData,
284        }
285    }
286
287    pub(crate) fn load<R: ReadEx>(reader: &mut R, size: usize) -> Result<Self> {
288        let mut inner = vec![0; size * V::size()];
289        reader.read_bytes(inner.as_mut())?;
290
291        Ok(Self {
292            inner,
293            phantom: PhantomData,
294        })
295    }
296}
297
298impl<V: IpVersion> ColumnData for IpColumnData<V> {
299    fn sql_type(&self) -> SqlType {
300        V::sql_type()
301    }
302
303    fn save(&self, encoder: &mut Encoder, start: usize, end: usize) {
304        let start_index = start * V::size();
305        let end_index = end * V::size();
306
307        let slice: &[u8] = self.inner.as_ref();
308        encoder.write_bytes(&slice[start_index..end_index]);
309    }
310
311    fn len(&self) -> usize {
312        self.inner.len() / V::size()
313    }
314
315    fn push(&mut self, value: Value) {
316        V::push(&mut self.inner, value)
317    }
318
319    fn at(&self, index: usize) -> ValueRef {
320        V::get(&self.inner, index)
321    }
322
323    fn clone_instance(&self) -> BoxColumnData {
324        Box::new(Self {
325            inner: self.inner.clone(),
326            phantom: PhantomData,
327        })
328    }
329
330    unsafe fn get_internal(&self, pointers: &[*mut *const u8], level: u8) -> Result<()> {
331        assert_eq!(level, 0);
332        *pointers[0] = &self.inner as *const Vec<u8> as *const u8;
333        Ok(())
334    }
335}