clickhouse_native_client/column/
map.rs1use super::{
7 Column,
8 ColumnArray,
9 ColumnRef,
10};
11use crate::{
12 types::Type,
13 Error,
14 Result,
15};
16use bytes::BytesMut;
17use std::sync::Arc;
18
19pub struct ColumnMap {
21 type_: Type,
22 data: ColumnRef, }
24
25impl ColumnMap {
26 pub fn new(type_: Type) -> Self {
32 let (key_type, value_type) = match &type_ {
34 Type::Map { key_type, value_type } => {
35 (key_type.as_ref().clone(), value_type.as_ref().clone())
36 }
37 _ => panic!("ColumnMap requires Map type"),
38 };
39
40 let tuple_type =
42 Type::Tuple { item_types: vec![key_type, value_type] };
43 let array_type = Type::Array { item_type: Box::new(tuple_type) };
44
45 let data: ColumnRef = Arc::new(ColumnArray::new(array_type));
47
48 Self { type_, data }
49 }
50
51 pub fn from_array(type_: Type, data: ColumnRef) -> Self {
53 Self { type_, data }
54 }
55
56 pub fn data<T: Column + 'static>(&self) -> &T {
64 self.data
65 .as_any()
66 .downcast_ref::<T>()
67 .expect("Failed to downcast data column to requested type")
68 }
69
70 pub fn data_mut<T: Column + 'static>(&mut self) -> &mut T {
78 Arc::get_mut(&mut self.data)
79 .expect("Cannot get mutable reference to shared data column")
80 .as_any_mut()
81 .downcast_mut::<T>()
82 .expect("Failed to downcast data column to requested type")
83 }
84
85 pub fn data_ref(&self) -> ColumnRef {
87 self.data.clone()
88 }
89
90 pub fn as_array(&self) -> Option<&ColumnArray> {
92 self.data.as_any().downcast_ref::<ColumnArray>()
93 }
94
95 pub fn at(&self, index: usize) -> Result<ColumnRef> {
98 self.data.slice(index, 1)
100 }
101
102 pub fn len(&self) -> usize {
104 self.data.size()
105 }
106
107 pub fn is_empty(&self) -> bool {
109 self.data.size() == 0
110 }
111}
112
113impl Column for ColumnMap {
114 fn column_type(&self) -> &Type {
115 &self.type_
116 }
117
118 fn size(&self) -> usize {
119 self.data.size()
120 }
121
122 fn clear(&mut self) {
123 let new_col = ColumnMap::new(self.type_.clone());
125 self.data = new_col.data;
126 }
127
128 fn reserve(&mut self, _new_cap: usize) {
129 }
132
133 fn append_column(&mut self, other: ColumnRef) -> Result<()> {
134 let _other =
135 other.as_any().downcast_ref::<ColumnMap>().ok_or_else(|| {
136 Error::TypeMismatch {
137 expected: self.type_.name(),
138 actual: other.column_type().name(),
139 }
140 })?;
141
142 Err(Error::Protocol(
144 "append_column not fully supported for Map".to_string(),
145 ))
146 }
147
148 fn load_prefix(&mut self, buffer: &mut &[u8], rows: usize) -> Result<()> {
149 let data_mut = Arc::get_mut(&mut self.data).ok_or_else(|| {
153 Error::Protocol(
154 "Cannot load prefix for shared map column".to_string(),
155 )
156 })?;
157 data_mut.load_prefix(buffer, rows)
158 }
159
160 fn load_from_buffer(
161 &mut self,
162 buffer: &mut &[u8],
163 rows: usize,
164 ) -> Result<()> {
165 let mut new_col = ColumnMap::new(self.type_.clone());
167
168 if let Some(array) = Arc::get_mut(&mut new_col.data) {
170 if let Some(array_mut) =
171 array.as_any_mut().downcast_mut::<ColumnArray>()
172 {
173 array_mut.load_from_buffer(buffer, rows)?;
174 self.data = new_col.data;
175 return Ok(());
176 }
177 }
178
179 Err(Error::Protocol(
180 "Failed to load Map column from buffer".to_string(),
181 ))
182 }
183
184 fn save_prefix(&self, buffer: &mut BytesMut) -> Result<()> {
185 self.data.save_prefix(buffer)
189 }
190
191 fn save_to_buffer(&self, buffer: &mut BytesMut) -> Result<()> {
192 self.data.save_to_buffer(buffer)
193 }
194
195 fn clone_empty(&self) -> ColumnRef {
196 Arc::new(ColumnMap::new(self.type_.clone()))
197 }
198
199 fn slice(&self, begin: usize, len: usize) -> Result<ColumnRef> {
200 let sliced_data = self.data.slice(begin, len)?;
202
203 Ok(Arc::new(ColumnMap {
206 type_: self.type_.clone(),
207 data: sliced_data,
208 }))
209 }
210
211 fn as_any(&self) -> &dyn std::any::Any {
212 self
213 }
214
215 fn as_any_mut(&mut self) -> &mut dyn std::any::Any {
216 self
217 }
218}
219
220impl Clone for ColumnMap {
222 fn clone(&self) -> Self {
223 Self { type_: self.type_.clone(), data: self.data.clone() }
224 }
225}
226
227#[cfg(test)]
228#[cfg_attr(coverage_nightly, coverage(off))]
229mod tests {
230 use super::*;
231 use crate::types::TypeCode;
232
233 #[test]
234 fn test_map_creation() {
235 let map_type = Type::Map {
237 key_type: Box::new(Type::Simple(TypeCode::String)),
238 value_type: Box::new(Type::Simple(TypeCode::UInt32)),
239 };
240
241 let col = ColumnMap::new(map_type);
242 assert_eq!(col.len(), 0);
243 assert!(col.is_empty());
244 }
245
246 #[test]
247 fn test_map_underlying_array() {
248 let map_type = Type::Map {
249 key_type: Box::new(Type::Simple(TypeCode::String)),
250 value_type: Box::new(Type::Simple(TypeCode::UInt32)),
251 };
252
253 let col = ColumnMap::new(map_type);
254 let array = col.as_array();
255
256 assert!(array.is_some());
258 assert_eq!(array.unwrap().size(), 0);
259 }
260
261 #[test]
262 fn test_map_clone() {
263 let map_type = Type::Map {
264 key_type: Box::new(Type::Simple(TypeCode::String)),
265 value_type: Box::new(Type::Simple(TypeCode::UInt32)),
266 };
267
268 let col1 = ColumnMap::new(map_type);
269 let col2 = col1.clone();
270
271 assert_eq!(col1.len(), col2.len());
272 }
273}