clickhouse_native_client/column/
tuple.rs1use super::{
8 Column,
9 ColumnRef,
10};
11use crate::{
12 types::Type,
13 Error,
14 Result,
15};
16use bytes::BytesMut;
17use std::sync::Arc;
18
19pub struct ColumnTuple {
21 type_: Type,
22 columns: Vec<ColumnRef>,
23}
24
25impl ColumnTuple {
26 pub fn new(type_: Type, columns: Vec<ColumnRef>) -> Self {
28 Self { type_, columns }
29 }
30
31 pub fn column_count(&self) -> usize {
33 self.columns.len()
34 }
35
36 pub fn column_at(&self, index: usize) -> ColumnRef {
38 self.columns[index].clone()
39 }
40
41 pub fn column_at_mut(&mut self, index: usize) -> &mut dyn Column {
43 Arc::get_mut(&mut self.columns[index])
44 .expect("Cannot get mutable reference to shared column")
45 }
46
47 pub fn len(&self) -> usize {
50 if self.columns.is_empty() {
51 0
52 } else {
53 self.columns[0].size()
54 }
55 }
56
57 pub fn is_empty(&self) -> bool {
59 self.len() == 0
60 }
61}
62
63impl Column for ColumnTuple {
64 fn column_type(&self) -> &Type {
65 &self.type_
66 }
67
68 fn size(&self) -> usize {
69 self.len()
70 }
71
72 fn clear(&mut self) {
73 for col in &mut self.columns {
74 let col_mut = Arc::get_mut(col)
75 .expect("Cannot clear shared tuple column - column has multiple references");
76 col_mut.clear();
77 }
78 }
79
80 fn reserve(&mut self, new_cap: usize) {
81 for col in &mut self.columns {
82 let col_mut = Arc::get_mut(col)
83 .expect("Cannot reserve on shared tuple column - column has multiple references");
84 col_mut.reserve(new_cap);
85 }
86 }
87
88 fn append_column(&mut self, other: ColumnRef) -> Result<()> {
89 let other =
90 other.as_any().downcast_ref::<ColumnTuple>().ok_or_else(|| {
91 Error::TypeMismatch {
92 expected: self.type_.name(),
93 actual: other.column_type().name(),
94 }
95 })?;
96
97 if self.columns.len() != other.columns.len() {
98 return Err(Error::TypeMismatch {
99 expected: format!("Tuple with {} columns", self.columns.len()),
100 actual: format!("Tuple with {} columns", other.columns.len()),
101 });
102 }
103
104 for (i, col) in self.columns.iter_mut().enumerate() {
105 let col_mut = Arc::get_mut(col)
106 .ok_or_else(|| Error::Protocol(
107 "Cannot append to shared tuple column - column has multiple references".to_string()
108 ))?;
109 col_mut.append_column(other.columns[i].clone())?;
110 }
111
112 Ok(())
113 }
114
115 fn load_prefix(&mut self, buffer: &mut &[u8], rows: usize) -> Result<()> {
116 for col in &mut self.columns {
118 let col_mut = Arc::get_mut(col).ok_or_else(|| {
119 Error::Protocol(
120 "Cannot load prefix for shared tuple column".to_string(),
121 )
122 })?;
123 col_mut.load_prefix(buffer, rows)?;
124 }
125 Ok(())
126 }
127
128 fn load_from_buffer(
129 &mut self,
130 buffer: &mut &[u8],
131 rows: usize,
132 ) -> Result<()> {
133 for col in &mut self.columns {
134 let col_mut = Arc::get_mut(col)
135 .ok_or_else(|| Error::Protocol(
136 "Cannot load into shared tuple column - column has multiple references".to_string()
137 ))?;
138 col_mut.load_from_buffer(buffer, rows)?;
139 }
140 Ok(())
141 }
142
143 fn save_prefix(&self, buffer: &mut BytesMut) -> Result<()> {
144 for col in &self.columns {
146 col.save_prefix(buffer)?;
147 }
148 Ok(())
149 }
150
151 fn save_to_buffer(&self, buffer: &mut BytesMut) -> Result<()> {
152 for col in &self.columns {
153 col.save_to_buffer(buffer)?;
154 }
155 Ok(())
156 }
157
158 fn clone_empty(&self) -> ColumnRef {
159 let empty_cols: Vec<ColumnRef> =
160 self.columns.iter().map(|c| c.clone_empty()).collect();
161 Arc::new(ColumnTuple::new(self.type_.clone(), empty_cols))
162 }
163
164 fn slice(&self, begin: usize, len: usize) -> Result<ColumnRef> {
165 if begin + len > self.size() {
166 return Err(Error::InvalidArgument(format!(
167 "Slice out of bounds: begin={}, len={}, size={}",
168 begin,
169 len,
170 self.size()
171 )));
172 }
173
174 let sliced_cols: Result<Vec<ColumnRef>> =
175 self.columns.iter().map(|col| col.slice(begin, len)).collect();
176
177 Ok(Arc::new(ColumnTuple::new(self.type_.clone(), sliced_cols?)))
178 }
179
180 fn as_any(&self) -> &dyn std::any::Any {
181 self
182 }
183
184 fn as_any_mut(&mut self) -> &mut dyn std::any::Any {
185 self
186 }
187}
188
189#[cfg(test)]
190#[cfg_attr(coverage_nightly, coverage(off))]
191mod tests {
192 use super::*;
193 use crate::{
194 column::{
195 ColumnString,
196 ColumnUInt64,
197 },
198 types::Type,
199 };
200
201 #[test]
202 fn test_tuple_creation() {
203 let types = vec![Type::uint64(), Type::string()];
204 let tuple_type = Type::tuple(types);
205
206 let col1 = Arc::new(ColumnUInt64::new()) as ColumnRef;
207 let col2 = Arc::new(ColumnString::new(Type::string())) as ColumnRef;
208
209 let tuple = ColumnTuple::new(tuple_type, vec![col1, col2]);
210
211 assert_eq!(tuple.column_count(), 2);
212 assert_eq!(tuple.size(), 0);
213 }
214
215 #[test]
216 fn test_tuple_slice() {
217 let types = vec![Type::uint64(), Type::string()];
218 let tuple_type = Type::tuple(types);
219
220 let mut col1 = ColumnUInt64::new();
221 col1.append(1);
222 col1.append(2);
223 col1.append(3);
224
225 let mut col2 = ColumnString::new(Type::string());
226 col2.append("a");
227 col2.append("b");
228 col2.append("c");
229
230 let tuple = ColumnTuple::new(
231 tuple_type,
232 vec![Arc::new(col1) as ColumnRef, Arc::new(col2) as ColumnRef],
233 );
234
235 let sliced = tuple.slice(1, 2).unwrap();
236 assert_eq!(sliced.size(), 2);
237
238 let sliced_tuple =
239 sliced.as_any().downcast_ref::<ColumnTuple>().unwrap();
240 let col_ref = sliced_tuple.column_at(0);
241 let sliced_col1 =
242 col_ref.as_any().downcast_ref::<ColumnUInt64>().unwrap();
243 assert_eq!(sliced_col1.at(0), 2);
244 assert_eq!(sliced_col1.at(1), 3);
245 }
246}