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