1use std::{collections::HashSet, ffi::c_void};
2
3use odbc_sys::{CDataType, Date, Numeric, Time, Timestamp};
4
5use crate::{
6 Bit, DataType, Error,
7 buffers::columnar::Resize,
8 columnar_bulk_inserter::BoundInputSlice,
9 error::TooLargeBufferSize,
10 handles::{CData, CDataMut, HasDataType, StatementRef},
11 parameter::WithDataType,
12};
13
14use super::{
15 BinColumn, BinColumnView, BufferDesc, CharColumn, ColumnarBuffer, Indicator, Item,
16 NullableSlice, NullableSliceMut, TextColumn, TextColumnView, WCharColumn,
17 bin_column::BinColumnSliceMut,
18 column_with_indicator::{
19 OptBitColumn, OptDateColumn, OptF32Column, OptF64Column, OptI8Column, OptI16Column,
20 OptI32Column, OptI64Column, OptTimeColumn, OptTimestampColumn, OptU8Column,
21 },
22 columnar::ColumnBuffer,
23 text_column::TextColumnSliceMut,
24};
25
26const DEFAULT_TIME_PRECISION: i16 = 7;
31
32#[derive(Debug)]
34pub enum AnyBuffer {
35 Binary(BinColumn),
37 Text(CharColumn),
40 WText(WCharColumn),
42 Date(Vec<Date>),
43 Time(Vec<Time>),
44 Timestamp(Vec<Timestamp>),
45 F64(Vec<f64>),
46 F32(Vec<f32>),
47 I8(Vec<i8>),
48 I16(Vec<i16>),
49 I32(Vec<i32>),
50 I64(Vec<i64>),
51 U8(Vec<u8>),
52 Bit(Vec<Bit>),
53 Numeric(WithDataType<Vec<Numeric>>),
54 NullableDate(OptDateColumn),
55 NullableTime(OptTimeColumn),
56 NullableTimestamp(OptTimestampColumn),
57 NullableF64(OptF64Column),
58 NullableF32(OptF32Column),
59 NullableI8(OptI8Column),
60 NullableI16(OptI16Column),
61 NullableI32(OptI32Column),
62 NullableI64(OptI64Column),
63 NullableU8(OptU8Column),
64 NullableBit(OptBitColumn),
65}
66
67impl AnyBuffer {
68 pub fn try_from_desc(max_rows: usize, desc: BufferDesc) -> Result<Self, TooLargeBufferSize> {
70 let fallible_allocations = true;
71 Self::impl_from_desc(max_rows, desc, fallible_allocations)
72 }
73
74 pub fn from_desc(max_rows: usize, desc: BufferDesc) -> Self {
76 let fallible_allocations = false;
77 Self::impl_from_desc(max_rows, desc, fallible_allocations).unwrap()
78 }
79
80 fn impl_from_desc(
82 max_rows: usize,
83 desc: BufferDesc,
84 fallible_allocations: bool,
85 ) -> Result<Self, TooLargeBufferSize> {
86 let buffer = match desc {
87 BufferDesc::Binary { length } => {
88 if fallible_allocations {
89 AnyBuffer::Binary(BinColumn::try_new(max_rows, length)?)
90 } else {
91 AnyBuffer::Binary(BinColumn::new(max_rows, length))
92 }
93 }
94 BufferDesc::Text { max_str_len } => {
95 if fallible_allocations {
96 AnyBuffer::Text(TextColumn::try_new(max_rows, max_str_len)?)
97 } else {
98 AnyBuffer::Text(TextColumn::new(max_rows, max_str_len))
99 }
100 }
101 BufferDesc::WText { max_str_len } => {
102 if fallible_allocations {
103 AnyBuffer::WText(TextColumn::try_new(max_rows, max_str_len)?)
104 } else {
105 AnyBuffer::WText(TextColumn::new(max_rows, max_str_len))
106 }
107 }
108 BufferDesc::Date { nullable: false } => {
109 AnyBuffer::Date(vec![Date::default(); max_rows])
110 }
111 BufferDesc::Time { nullable: false } => {
112 AnyBuffer::Time(vec![Time::default(); max_rows])
113 }
114 BufferDesc::Timestamp { nullable: false } => {
115 AnyBuffer::Timestamp(vec![Timestamp::default(); max_rows])
116 }
117 BufferDesc::F64 { nullable: false } => AnyBuffer::F64(vec![f64::default(); max_rows]),
118 BufferDesc::F32 { nullable: false } => AnyBuffer::F32(vec![f32::default(); max_rows]),
119 BufferDesc::I8 { nullable: false } => AnyBuffer::I8(vec![i8::default(); max_rows]),
120 BufferDesc::I16 { nullable: false } => AnyBuffer::I16(vec![i16::default(); max_rows]),
121 BufferDesc::I32 { nullable: false } => AnyBuffer::I32(vec![i32::default(); max_rows]),
122 BufferDesc::I64 { nullable: false } => AnyBuffer::I64(vec![i64::default(); max_rows]),
123 BufferDesc::U8 { nullable: false } => AnyBuffer::U8(vec![u8::default(); max_rows]),
124 BufferDesc::Bit { nullable: false } => AnyBuffer::Bit(vec![Bit::default(); max_rows]),
125 BufferDesc::Numeric { precision, scale } => AnyBuffer::Numeric(WithDataType::new(
126 vec![Numeric::default(); max_rows],
127 DataType::Numeric { precision, scale },
128 )),
129 BufferDesc::Date { nullable: true } => {
130 AnyBuffer::NullableDate(OptDateColumn::new(max_rows))
131 }
132 BufferDesc::Time { nullable: true } => {
133 AnyBuffer::NullableTime(OptTimeColumn::new(max_rows))
134 }
135 BufferDesc::Timestamp { nullable: true } => {
136 AnyBuffer::NullableTimestamp(OptTimestampColumn::new(max_rows))
137 }
138 BufferDesc::F64 { nullable: true } => {
139 AnyBuffer::NullableF64(OptF64Column::new(max_rows))
140 }
141 BufferDesc::F32 { nullable: true } => {
142 AnyBuffer::NullableF32(OptF32Column::new(max_rows))
143 }
144 BufferDesc::I8 { nullable: true } => AnyBuffer::NullableI8(OptI8Column::new(max_rows)),
145 BufferDesc::I16 { nullable: true } => {
146 AnyBuffer::NullableI16(OptI16Column::new(max_rows))
147 }
148 BufferDesc::I32 { nullable: true } => {
149 AnyBuffer::NullableI32(OptI32Column::new(max_rows))
150 }
151 BufferDesc::I64 { nullable: true } => {
152 AnyBuffer::NullableI64(OptI64Column::new(max_rows))
153 }
154 BufferDesc::U8 { nullable: true } => AnyBuffer::NullableU8(OptU8Column::new(max_rows)),
155 BufferDesc::Bit { nullable: true } => {
156 AnyBuffer::NullableBit(OptBitColumn::new(max_rows))
157 }
158 };
159 Ok(buffer)
160 }
161
162 fn inner(&self) -> &dyn CData {
163 match self {
164 AnyBuffer::Binary(col) => col,
165 AnyBuffer::Text(col) => col,
166 AnyBuffer::WText(col) => col,
167 AnyBuffer::F64(col) => col,
168 AnyBuffer::F32(col) => col,
169 AnyBuffer::Date(col) => col,
170 AnyBuffer::Time(col) => col,
171 AnyBuffer::Timestamp(col) => col,
172 AnyBuffer::I8(col) => col,
173 AnyBuffer::I16(col) => col,
174 AnyBuffer::I32(col) => col,
175 AnyBuffer::I64(col) => col,
176 AnyBuffer::Bit(col) => col,
177 AnyBuffer::U8(col) => col,
178 AnyBuffer::Numeric(col) => col,
179 AnyBuffer::NullableF64(col) => col,
180 AnyBuffer::NullableF32(col) => col,
181 AnyBuffer::NullableDate(col) => col,
182 AnyBuffer::NullableTime(col) => col,
183 AnyBuffer::NullableTimestamp(col) => col,
184 AnyBuffer::NullableI8(col) => col,
185 AnyBuffer::NullableI16(col) => col,
186 AnyBuffer::NullableI32(col) => col,
187 AnyBuffer::NullableI64(col) => col,
188 AnyBuffer::NullableBit(col) => col,
189 AnyBuffer::NullableU8(col) => col,
190 }
191 }
192
193 fn inner_mut(&mut self) -> &mut dyn AnyBufferVariantMut {
194 match self {
195 AnyBuffer::Binary(col) => col,
196 AnyBuffer::Text(col) => col,
197 AnyBuffer::WText(col) => col,
198 AnyBuffer::F64(col) => col,
199 AnyBuffer::F32(col) => col,
200 AnyBuffer::Date(col) => col,
201 AnyBuffer::Time(col) => col,
202 AnyBuffer::Timestamp(col) => col,
203 AnyBuffer::I8(col) => col,
204 AnyBuffer::I16(col) => col,
205 AnyBuffer::I32(col) => col,
206 AnyBuffer::I64(col) => col,
207 AnyBuffer::Bit(col) => col,
208 AnyBuffer::U8(col) => col,
209 AnyBuffer::Numeric(col) => &mut col.value,
210 AnyBuffer::NullableF64(col) => col,
211 AnyBuffer::NullableF32(col) => col,
212 AnyBuffer::NullableDate(col) => col,
213 AnyBuffer::NullableTime(col) => col,
214 AnyBuffer::NullableTimestamp(col) => col,
215 AnyBuffer::NullableI8(col) => col,
216 AnyBuffer::NullableI16(col) => col,
217 AnyBuffer::NullableI32(col) => col,
218 AnyBuffer::NullableI64(col) => col,
219 AnyBuffer::NullableBit(col) => col,
220 AnyBuffer::NullableU8(col) => col,
221 }
222 }
223}
224
225trait AnyBufferVariantMut: CDataMut + Resize {}
229
230impl<T> AnyBufferVariantMut for T where T: CDataMut + Resize {}
231
232unsafe impl CData for AnyBuffer {
233 fn cdata_type(&self) -> CDataType {
234 self.inner().cdata_type()
235 }
236
237 fn indicator_ptr(&self) -> *const isize {
238 self.inner().indicator_ptr()
239 }
240
241 fn value_ptr(&self) -> *const c_void {
242 self.inner().value_ptr()
243 }
244
245 fn buffer_length(&self) -> isize {
246 self.inner().buffer_length()
247 }
248}
249
250unsafe impl CDataMut for AnyBuffer {
251 fn mut_indicator_ptr(&mut self) -> *mut isize {
252 self.inner_mut().mut_indicator_ptr()
253 }
254
255 fn mut_value_ptr(&mut self) -> *mut c_void {
256 self.inner_mut().mut_value_ptr()
257 }
258}
259
260impl HasDataType for AnyBuffer {
261 fn data_type(&self) -> DataType {
262 match self {
263 AnyBuffer::Binary(col) => col.data_type(),
264 AnyBuffer::Text(col) => col.data_type(),
265 AnyBuffer::WText(col) => col.data_type(),
266 AnyBuffer::Date(_) | AnyBuffer::NullableDate(_) => DataType::Date,
267 AnyBuffer::Time(_) | AnyBuffer::NullableTime(_) => DataType::Time {
268 precision: DEFAULT_TIME_PRECISION,
269 },
270 AnyBuffer::Timestamp(_) | AnyBuffer::NullableTimestamp(_) => DataType::Timestamp {
271 precision: DEFAULT_TIME_PRECISION,
272 },
273 AnyBuffer::F64(_) | AnyBuffer::NullableF64(_) => DataType::Double,
274 AnyBuffer::F32(_) | AnyBuffer::NullableF32(_) => DataType::Real,
275 AnyBuffer::I8(_) | AnyBuffer::NullableI8(_) => DataType::TinyInt,
276 AnyBuffer::I16(_) | AnyBuffer::NullableI16(_) => DataType::SmallInt,
277 AnyBuffer::I32(_) | AnyBuffer::NullableI32(_) => DataType::Integer,
278 AnyBuffer::I64(_) | AnyBuffer::NullableI64(_) => DataType::BigInt,
279 AnyBuffer::U8(_) | AnyBuffer::NullableU8(_) => DataType::SmallInt,
283 AnyBuffer::Bit(_) | AnyBuffer::NullableBit(_) => DataType::Bit,
284 AnyBuffer::Numeric(col) => col.data_type(),
285 }
286 }
287}
288
289pub type ColumnarAnyBuffer = ColumnarBuffer<AnyBuffer>;
292
293impl ColumnarAnyBuffer {
294 pub fn from_descs(capacity: usize, descs: impl IntoIterator<Item = BufferDesc>) -> Self {
296 let mut column_index = 0;
297 let columns = descs
298 .into_iter()
299 .map(move |desc| {
300 let buffer = AnyBuffer::from_desc(capacity, desc);
301 column_index += 1;
302 (column_index, buffer)
303 })
304 .collect();
305 unsafe { ColumnarBuffer::new_unchecked(capacity, columns) }
306 }
307
308 pub fn try_from_descs(
313 capacity: usize,
314 descs: impl IntoIterator<Item = BufferDesc>,
315 ) -> Result<Self, Error> {
316 let mut column_index = 0;
317 let columns = descs
318 .into_iter()
319 .map(move |desc| {
320 let buffer = AnyBuffer::try_from_desc(capacity, desc)
321 .map_err(|source| source.add_context(column_index))?;
322 column_index += 1;
323 Ok::<_, Error>((column_index, buffer))
324 })
325 .collect::<Result<_, _>>()?;
326 Ok(unsafe { ColumnarBuffer::new_unchecked(capacity, columns) })
327 }
328
329 pub fn from_descs_and_indices(
334 max_rows: usize,
335 description: impl Iterator<Item = (u16, BufferDesc)>,
336 ) -> ColumnarBuffer<AnyBuffer> {
337 let columns: Vec<_> = description
338 .map(|(col_index, buffer_desc)| {
339 (col_index, AnyBuffer::from_desc(max_rows, buffer_desc))
340 })
341 .collect();
342
343 let mut indices = HashSet::new();
345 if columns
346 .iter()
347 .any(move |&(col_index, _)| !indices.insert(col_index))
348 {
349 panic!("Column indices must be unique.")
350 }
351
352 ColumnarBuffer::new(columns)
353 }
354}
355
356#[derive(Debug, Clone, Copy)]
362pub enum AnySlice<'a> {
363 Text(TextColumnView<'a, u8>),
365 WText(TextColumnView<'a, u16>),
367 Binary(BinColumnView<'a>),
368 Date(&'a [Date]),
369 Time(&'a [Time]),
370 Timestamp(&'a [Timestamp]),
371 F64(&'a [f64]),
372 F32(&'a [f32]),
373 I8(&'a [i8]),
374 I16(&'a [i16]),
375 I32(&'a [i32]),
376 I64(&'a [i64]),
377 U8(&'a [u8]),
378 Bit(&'a [Bit]),
379 Numeric(&'a [Numeric]),
380 NullableDate(NullableSlice<'a, Date>),
381 NullableTime(NullableSlice<'a, Time>),
382 NullableTimestamp(NullableSlice<'a, Timestamp>),
383 NullableF64(NullableSlice<'a, f64>),
384 NullableF32(NullableSlice<'a, f32>),
385 NullableI8(NullableSlice<'a, i8>),
386 NullableI16(NullableSlice<'a, i16>),
387 NullableI32(NullableSlice<'a, i32>),
388 NullableI64(NullableSlice<'a, i64>),
389 NullableU8(NullableSlice<'a, u8>),
390 NullableBit(NullableSlice<'a, Bit>),
391 NullableNumeric(NullableSlice<'a, Numeric>),
392}
393
394impl<'a> AnySlice<'a> {
395 pub fn as_text_view(self) -> Option<TextColumnView<'a, u8>> {
398 if let Self::Text(view) = self {
399 Some(view)
400 } else {
401 None
402 }
403 }
404
405 pub fn as_w_text_view(self) -> Option<TextColumnView<'a, u16>> {
408 if let Self::WText(view) = self {
409 Some(view)
410 } else {
411 None
412 }
413 }
414
415 pub fn as_bin_view(self) -> Option<BinColumnView<'a>> {
418 if let Self::Binary(view) = self {
419 Some(view)
420 } else {
421 None
422 }
423 }
424
425 pub fn as_slice<I: Item>(self) -> Option<&'a [I]> {
427 I::as_slice(self)
428 }
429
430 pub fn as_nullable_slice<I: Item>(self) -> Option<NullableSlice<'a, I>> {
432 I::as_nullable_slice(self)
433 }
434}
435
436unsafe impl<'a> BoundInputSlice<'a> for AnyBuffer {
437 type SliceMut = AnySliceMut<'a>;
438
439 unsafe fn as_view_mut(
440 &'a mut self,
441 parameter_index: u16,
442 stmt: StatementRef<'a>,
443 ) -> Self::SliceMut {
444 let num_rows = self.capacity();
445 unsafe {
446 match self {
447 AnyBuffer::Binary(column) => {
448 AnySliceMut::Binary(column.as_view_mut(parameter_index, stmt))
449 }
450 AnyBuffer::Text(column) => {
451 AnySliceMut::Text(column.as_view_mut(parameter_index, stmt))
452 }
453 AnyBuffer::WText(column) => {
454 AnySliceMut::WText(column.as_view_mut(parameter_index, stmt))
455 }
456 AnyBuffer::Date(column) => AnySliceMut::Date(column),
457 AnyBuffer::Time(column) => AnySliceMut::Time(column),
458 AnyBuffer::Timestamp(column) => AnySliceMut::Timestamp(column),
459 AnyBuffer::F64(column) => AnySliceMut::F64(column),
460 AnyBuffer::F32(column) => AnySliceMut::F32(column),
461 AnyBuffer::I8(column) => AnySliceMut::I8(column),
462 AnyBuffer::I16(column) => AnySliceMut::I16(column),
463 AnyBuffer::I32(column) => AnySliceMut::I32(column),
464 AnyBuffer::I64(column) => AnySliceMut::I64(column),
465 AnyBuffer::U8(column) => AnySliceMut::U8(column),
466 AnyBuffer::Bit(column) => AnySliceMut::Bit(column),
467 AnyBuffer::Numeric(column) => AnySliceMut::Numeric(&mut column.value),
468 AnyBuffer::NullableDate(column) => {
469 AnySliceMut::NullableDate(column.writer_n(num_rows))
470 }
471 AnyBuffer::NullableTime(column) => {
472 AnySliceMut::NullableTime(column.writer_n(num_rows))
473 }
474 AnyBuffer::NullableTimestamp(column) => {
475 AnySliceMut::NullableTimestamp(column.writer_n(num_rows))
476 }
477 AnyBuffer::NullableF64(column) => {
478 AnySliceMut::NullableF64(column.writer_n(num_rows))
479 }
480 AnyBuffer::NullableF32(column) => {
481 AnySliceMut::NullableF32(column.writer_n(num_rows))
482 }
483 AnyBuffer::NullableI8(column) => AnySliceMut::NullableI8(column.writer_n(num_rows)),
484 AnyBuffer::NullableI16(column) => {
485 AnySliceMut::NullableI16(column.writer_n(num_rows))
486 }
487 AnyBuffer::NullableI32(column) => {
488 AnySliceMut::NullableI32(column.writer_n(num_rows))
489 }
490 AnyBuffer::NullableI64(column) => {
491 AnySliceMut::NullableI64(column.writer_n(num_rows))
492 }
493 AnyBuffer::NullableU8(column) => AnySliceMut::NullableU8(column.writer_n(num_rows)),
494 AnyBuffer::NullableBit(column) => {
495 AnySliceMut::NullableBit(column.writer_n(num_rows))
496 }
497 }
498 }
499 }
500}
501
502pub enum AnySliceMut<'a> {
505 Text(TextColumnSliceMut<'a, u8>),
506 WText(TextColumnSliceMut<'a, u16>),
508 Binary(BinColumnSliceMut<'a>),
509 Date(&'a mut [Date]),
510 Time(&'a mut [Time]),
511 Timestamp(&'a mut [Timestamp]),
512 F64(&'a mut [f64]),
513 F32(&'a mut [f32]),
514 I8(&'a mut [i8]),
515 I16(&'a mut [i16]),
516 I32(&'a mut [i32]),
517 I64(&'a mut [i64]),
518 U8(&'a mut [u8]),
519 Bit(&'a mut [Bit]),
520 Numeric(&'a mut [Numeric]),
521 NullableDate(NullableSliceMut<'a, Date>),
522 NullableTime(NullableSliceMut<'a, Time>),
523 NullableTimestamp(NullableSliceMut<'a, Timestamp>),
524 NullableF64(NullableSliceMut<'a, f64>),
525 NullableF32(NullableSliceMut<'a, f32>),
526 NullableI8(NullableSliceMut<'a, i8>),
527 NullableI16(NullableSliceMut<'a, i16>),
528 NullableI32(NullableSliceMut<'a, i32>),
529 NullableI64(NullableSliceMut<'a, i64>),
530 NullableU8(NullableSliceMut<'a, u8>),
531 NullableBit(NullableSliceMut<'a, Bit>),
532}
533
534impl<'a> AnySliceMut<'a> {
535 pub fn as_bin_view(self) -> Option<BinColumnSliceMut<'a>> {
538 if let Self::Binary(view) = self {
539 Some(view)
540 } else {
541 None
542 }
543 }
544
545 pub fn as_text_view(self) -> Option<TextColumnSliceMut<'a, u8>> {
548 if let Self::Text(view) = self {
549 Some(view)
550 } else {
551 None
552 }
553 }
554
555 pub fn as_w_text_view(self) -> Option<TextColumnSliceMut<'a, u16>> {
558 if let Self::WText(view) = self {
559 Some(view)
560 } else {
561 None
562 }
563 }
564
565 pub fn as_slice<I: Item>(self) -> Option<&'a mut [I]> {
567 I::as_slice_mut(self)
568 }
569
570 pub fn as_nullable_slice<I: Item>(self) -> Option<NullableSliceMut<'a, I>> {
572 I::as_nullable_slice_mut(self)
573 }
574}
575
576unsafe impl ColumnBuffer for AnyBuffer {
577 type View<'a> = AnySlice<'a>;
578
579 fn capacity(&self) -> usize {
580 match self {
581 AnyBuffer::Binary(col) => col.capacity(),
582 AnyBuffer::Text(col) => col.capacity(),
583 AnyBuffer::WText(col) => col.capacity(),
584 AnyBuffer::Date(col) => col.capacity(),
585 AnyBuffer::Time(col) => col.capacity(),
586 AnyBuffer::Timestamp(col) => col.capacity(),
587 AnyBuffer::F64(col) => col.capacity(),
588 AnyBuffer::F32(col) => col.capacity(),
589 AnyBuffer::I8(col) => col.capacity(),
590 AnyBuffer::I16(col) => col.capacity(),
591 AnyBuffer::I32(col) => col.capacity(),
592 AnyBuffer::I64(col) => col.capacity(),
593 AnyBuffer::U8(col) => col.capacity(),
594 AnyBuffer::Bit(col) => col.capacity(),
595 AnyBuffer::Numeric(col) => col.capacity(),
596 AnyBuffer::NullableDate(col) => col.capacity(),
597 AnyBuffer::NullableTime(col) => col.capacity(),
598 AnyBuffer::NullableTimestamp(col) => col.capacity(),
599 AnyBuffer::NullableF64(col) => col.capacity(),
600 AnyBuffer::NullableF32(col) => col.capacity(),
601 AnyBuffer::NullableI8(col) => col.capacity(),
602 AnyBuffer::NullableI16(col) => col.capacity(),
603 AnyBuffer::NullableI32(col) => col.capacity(),
604 AnyBuffer::NullableI64(col) => col.capacity(),
605 AnyBuffer::NullableU8(col) => col.capacity(),
606 AnyBuffer::NullableBit(col) => col.capacity(),
607 }
608 }
609
610 fn view(&self, valid_rows: usize) -> AnySlice<'_> {
611 match self {
612 AnyBuffer::Binary(col) => AnySlice::Binary(col.view(valid_rows)),
613 AnyBuffer::Text(col) => AnySlice::Text(col.view(valid_rows)),
614 AnyBuffer::WText(col) => AnySlice::WText(col.view(valid_rows)),
615 AnyBuffer::Date(col) => AnySlice::Date(&col[0..valid_rows]),
616 AnyBuffer::Time(col) => AnySlice::Time(&col[0..valid_rows]),
617 AnyBuffer::Timestamp(col) => AnySlice::Timestamp(&col[0..valid_rows]),
618 AnyBuffer::F64(col) => AnySlice::F64(&col[0..valid_rows]),
619 AnyBuffer::F32(col) => AnySlice::F32(&col[0..valid_rows]),
620 AnyBuffer::I8(col) => AnySlice::I8(&col[0..valid_rows]),
621 AnyBuffer::I16(col) => AnySlice::I16(&col[0..valid_rows]),
622 AnyBuffer::I32(col) => AnySlice::I32(&col[0..valid_rows]),
623 AnyBuffer::I64(col) => AnySlice::I64(&col[0..valid_rows]),
624 AnyBuffer::U8(col) => AnySlice::U8(&col[0..valid_rows]),
625 AnyBuffer::Bit(col) => AnySlice::Bit(&col[0..valid_rows]),
626 AnyBuffer::Numeric(col) => AnySlice::Numeric(&col.value[0..valid_rows]),
627 AnyBuffer::NullableDate(col) => AnySlice::NullableDate(col.iter(valid_rows)),
628 AnyBuffer::NullableTime(col) => AnySlice::NullableTime(col.iter(valid_rows)),
629 AnyBuffer::NullableTimestamp(col) => AnySlice::NullableTimestamp(col.iter(valid_rows)),
630 AnyBuffer::NullableF64(col) => AnySlice::NullableF64(col.iter(valid_rows)),
631 AnyBuffer::NullableF32(col) => AnySlice::NullableF32(col.iter(valid_rows)),
632 AnyBuffer::NullableI8(col) => AnySlice::NullableI8(col.iter(valid_rows)),
633 AnyBuffer::NullableI16(col) => AnySlice::NullableI16(col.iter(valid_rows)),
634 AnyBuffer::NullableI32(col) => AnySlice::NullableI32(col.iter(valid_rows)),
635 AnyBuffer::NullableI64(col) => AnySlice::NullableI64(col.iter(valid_rows)),
636 AnyBuffer::NullableU8(col) => AnySlice::NullableU8(col.iter(valid_rows)),
637 AnyBuffer::NullableBit(col) => AnySlice::NullableBit(col.iter(valid_rows)),
638 }
639 }
640
641 fn has_truncated_values(&self, num_rows: usize) -> Option<Indicator> {
642 match self {
643 AnyBuffer::Binary(col) => col.has_truncated_values(num_rows),
644 AnyBuffer::Text(col) => col.has_truncated_values(num_rows),
645 AnyBuffer::WText(col) => col.has_truncated_values(num_rows),
646 _ => None,
647 }
648 }
649}
650
651impl Resize for AnyBuffer {
652 fn resize(&mut self, new_capacity: usize) {
653 self.inner_mut().resize(new_capacity);
654 }
655}
656
657#[cfg(test)]
658mod tests {
659 use crate::buffers::{AnySlice, AnySliceMut, ColumnBuffer, Resize};
660
661 use super::AnyBuffer;
662
663 #[test]
664 fn any_buffer_is_resize() {
665 let mut buffer = AnyBuffer::I32(vec![1, 2]);
667
668 buffer.resize(4);
670
671 assert_eq!(buffer.view(4).as_slice(), Some([1i32, 2, 0, 0].as_slice()));
674 assert_eq!(buffer.capacity(), 4);
676 }
677
678 #[test]
679 fn slice_should_only_contain_part_of_the_buffer() {
680 let buffer = AnyBuffer::I32(vec![1, 2, 3]);
681
682 let view = buffer.view(2);
683
684 assert_eq!(Some([1, 2].as_slice()), view.as_slice::<i32>());
685 }
686
687 #[test]
688 fn slice_should_be_none_if_types_mismatch() {
689 let buffer = [1, 2, 3];
690 let view = AnySlice::I32(&buffer);
691 assert_eq!(None, view.as_slice::<i16>());
692 }
693
694 #[test]
695 fn slice_mut_should_be_none_if_types_mismatch() {
696 let mut buffer = [1, 2, 3];
697 let view = AnySliceMut::I32(&mut buffer);
698 assert_eq!(None, view.as_slice::<i16>());
699 }
700
701 #[test]
702 fn nullable_slice_should_be_none_if_buffer_is_non_nullable() {
703 let buffer = [1, 2, 3];
704 let view = AnySlice::I32(&buffer);
705 assert!(view.as_nullable_slice::<i32>().is_none());
706 }
707
708 #[test]
709 fn nullable_slice_mut_should_be_none_if_buffer_is_non_nullable() {
710 let mut buffer = [1, 2, 3];
711 let view = AnySliceMut::I32(&mut buffer);
712 assert!(view.as_nullable_slice::<i32>().is_none());
713 }
714}