1use crate::bit_iterator::BitSliceIterator;
22use arrow_buffer::buffer::{BooleanBuffer, NullBuffer};
23use arrow_buffer::{
24 ArrowNativeType, Buffer, IntervalDayTime, IntervalMonthDayNano, MutableBuffer, bit_util, i256,
25};
26use arrow_schema::{ArrowError, DataType, UnionMode};
27use std::mem;
28use std::ops::Range;
29use std::sync::Arc;
30
31use crate::{equal, validate_binary_view, validate_string_view};
32
33#[inline]
34pub(crate) fn contains_nulls(
35 null_bit_buffer: Option<&NullBuffer>,
36 offset: usize,
37 len: usize,
38) -> bool {
39 match null_bit_buffer {
40 Some(buffer) => {
41 match BitSliceIterator::new(buffer.validity(), buffer.offset() + offset, len).next() {
42 Some((start, end)) => start != 0 || end != len,
43 None => len != 0, }
45 }
46 None => false, }
48}
49
50#[inline]
51pub(crate) fn count_nulls(
52 null_bit_buffer: Option<&NullBuffer>,
53 offset: usize,
54 len: usize,
55) -> usize {
56 if let Some(buf) = null_bit_buffer {
57 let buffer = buf.buffer();
58 len - buffer.count_set_bits_offset(offset + buf.offset(), len)
59 } else {
60 0
61 }
62}
63
64#[inline]
66pub(crate) fn new_buffers(data_type: &DataType, capacity: usize) -> [MutableBuffer; 2] {
67 let empty_buffer = MutableBuffer::new(0);
68 match data_type {
69 DataType::Null => [empty_buffer, MutableBuffer::new(0)],
70 DataType::Boolean => {
71 let bytes = bit_util::ceil(capacity, 8);
72 let buffer = MutableBuffer::new(bytes);
73 [buffer, empty_buffer]
74 }
75 DataType::UInt8
76 | DataType::UInt16
77 | DataType::UInt32
78 | DataType::UInt64
79 | DataType::Int8
80 | DataType::Int16
81 | DataType::Int32
82 | DataType::Int64
83 | DataType::Float16
84 | DataType::Float32
85 | DataType::Float64
86 | DataType::Decimal32(_, _)
87 | DataType::Decimal64(_, _)
88 | DataType::Decimal128(_, _)
89 | DataType::Decimal256(_, _)
90 | DataType::Date32
91 | DataType::Time32(_)
92 | DataType::Date64
93 | DataType::Time64(_)
94 | DataType::Duration(_)
95 | DataType::Timestamp(_, _)
96 | DataType::Interval(_) => [
97 MutableBuffer::new(capacity * data_type.primitive_width().unwrap()),
98 empty_buffer,
99 ],
100 DataType::Utf8 | DataType::Binary => {
101 let mut buffer = MutableBuffer::new((1 + capacity) * mem::size_of::<i32>());
102 buffer.push(0i32);
104 [buffer, MutableBuffer::new(capacity * mem::size_of::<u8>())]
105 }
106 DataType::LargeUtf8 | DataType::LargeBinary => {
107 let mut buffer = MutableBuffer::new((1 + capacity) * mem::size_of::<i64>());
108 buffer.push(0i64);
110 [buffer, MutableBuffer::new(capacity * mem::size_of::<u8>())]
111 }
112 DataType::BinaryView | DataType::Utf8View => [
113 MutableBuffer::new(capacity * mem::size_of::<u128>()),
114 empty_buffer,
115 ],
116 DataType::List(_) | DataType::Map(_, _) => {
117 let mut buffer = MutableBuffer::new((1 + capacity) * mem::size_of::<i32>());
119 buffer.push(0i32);
120 [buffer, empty_buffer]
121 }
122 DataType::ListView(_) => [
123 MutableBuffer::new(capacity * mem::size_of::<i32>()),
124 MutableBuffer::new(capacity * mem::size_of::<i32>()),
125 ],
126 DataType::LargeList(_) => {
127 let mut buffer = MutableBuffer::new((1 + capacity) * mem::size_of::<i64>());
129 buffer.push(0i64);
130 [buffer, empty_buffer]
131 }
132 DataType::LargeListView(_) => [
133 MutableBuffer::new(capacity * mem::size_of::<i64>()),
134 MutableBuffer::new(capacity * mem::size_of::<i64>()),
135 ],
136 DataType::FixedSizeBinary(size) => {
137 if *size < 0 {
138 panic!("cannot construct buffers from FixedSizeBinary({size})");
139 }
140 [MutableBuffer::new(capacity * *size as usize), empty_buffer]
141 }
142 DataType::Dictionary(k, _) => [
143 MutableBuffer::new(capacity * k.primitive_width().unwrap()),
144 empty_buffer,
145 ],
146 DataType::FixedSizeList(_, _) | DataType::Struct(_) | DataType::RunEndEncoded(_, _) => {
147 [empty_buffer, MutableBuffer::new(0)]
148 }
149 DataType::Union(_, mode) => {
150 let type_ids = MutableBuffer::new(capacity * mem::size_of::<i8>());
151 match mode {
152 UnionMode::Sparse => [type_ids, empty_buffer],
153 UnionMode::Dense => {
154 let offsets = MutableBuffer::new(capacity * mem::size_of::<i32>());
155 [type_ids, offsets]
156 }
157 }
158 }
159 }
160}
161
162#[derive(Debug, Clone)]
208pub struct ArrayData {
209 data_type: DataType,
211
212 len: usize,
214
215 offset: usize,
222
223 buffers: Vec<Buffer>,
236
237 child_data: Vec<ArrayData>,
249
250 nulls: Option<NullBuffer>,
258}
259
260pub type ArrayDataRef = Arc<ArrayData>;
262
263fn checked_len_plus_offset(
264 data_type: &DataType,
265 len: usize,
266 offset: usize,
267) -> Result<usize, ArrowError> {
268 len.checked_add(offset).ok_or_else(|| {
269 ArrowError::InvalidArgumentError(format!(
270 "Length {len} with offset {offset} overflows usize for {data_type}"
271 ))
272 })
273}
274
275fn utf8_span<'a, T: ArrowNativeType>(
279 offsets: &[T],
280 values: &'a [u8],
281) -> Option<(usize, usize, &'a str)> {
282 let first = offsets.first()?.to_usize()?;
283 let last = offsets.last()?.to_usize()?;
284 let values_str = std::str::from_utf8(values.get(first..last)?).ok()?;
285 Some((first, last, values_str))
286}
287
288impl ArrayData {
289 pub unsafe fn new_unchecked(
306 data_type: DataType,
307 len: usize,
308 null_count: Option<usize>,
309 null_bit_buffer: Option<Buffer>,
310 offset: usize,
311 buffers: Vec<Buffer>,
312 child_data: Vec<ArrayData>,
313 ) -> Self {
314 let builder = Self::inner_new_builder(
315 data_type,
316 len,
317 null_count,
318 null_bit_buffer,
319 offset,
320 buffers,
321 child_data,
322 );
323
324 unsafe { builder.build_unchecked() }
326 }
327
328 pub fn try_new(
342 data_type: DataType,
343 len: usize,
344 null_bit_buffer: Option<Buffer>,
345 offset: usize,
346 buffers: Vec<Buffer>,
347 child_data: Vec<ArrayData>,
348 ) -> Result<Self, ArrowError> {
349 let builder = Self::inner_new_builder(
350 data_type,
351 len,
352 None,
353 null_bit_buffer,
354 offset,
355 buffers,
356 child_data,
357 );
358
359 assert!(!builder.skip_validation.get());
360
361 builder.build()
366 }
367
368 fn inner_new_builder(
369 data_type: DataType,
370 len: usize,
371 null_count: Option<usize>,
372 null_bit_buffer: Option<Buffer>,
373 offset: usize,
374 buffers: Vec<Buffer>,
375 child_data: Vec<ArrayData>,
376 ) -> ArrayDataBuilder {
377 ArrayDataBuilder {
378 data_type,
379 len,
380 null_count,
381 null_bit_buffer,
382 nulls: None,
383 offset,
384 buffers,
385 child_data,
386 align_buffers: false,
387 skip_validation: UnsafeFlag::new(),
388 }
389 }
390
391 pub fn into_parts(
397 self,
398 ) -> (
399 DataType,
400 usize,
401 Option<NullBuffer>,
402 usize,
403 Vec<Buffer>,
404 Vec<ArrayData>,
405 ) {
406 let Self {
407 data_type,
408 len,
409 nulls,
410 offset,
411 buffers,
412 child_data,
413 } = self;
414
415 (data_type, len, nulls, offset, buffers, child_data)
416 }
417
418 #[inline]
420 pub const fn builder(data_type: DataType) -> ArrayDataBuilder {
421 ArrayDataBuilder::new(data_type)
422 }
423
424 #[inline]
426 pub const fn data_type(&self) -> &DataType {
427 &self.data_type
428 }
429
430 pub fn buffers(&self) -> &[Buffer] {
432 &self.buffers
433 }
434
435 pub fn child_data(&self) -> &[ArrayData] {
443 &self.child_data[..]
444 }
445
446 #[inline]
448 pub fn is_null(&self, i: usize) -> bool {
449 match &self.nulls {
450 Some(v) => v.is_null(i),
451 None => false,
452 }
453 }
454
455 #[inline]
459 pub fn nulls(&self) -> Option<&NullBuffer> {
460 self.nulls.as_ref()
461 }
462
463 #[inline]
465 pub fn is_valid(&self, i: usize) -> bool {
466 !self.is_null(i)
467 }
468
469 #[inline]
471 pub const fn len(&self) -> usize {
472 self.len
473 }
474
475 #[inline]
477 pub const fn is_empty(&self) -> bool {
478 self.len == 0
479 }
480
481 #[inline]
533 pub const fn offset(&self) -> usize {
534 self.offset
535 }
536
537 #[inline]
539 pub fn null_count(&self) -> usize {
540 self.nulls
541 .as_ref()
542 .map(|x| x.null_count())
543 .unwrap_or_default()
544 }
545
546 pub fn get_buffer_memory_size(&self) -> usize {
558 let mut size = 0;
559 for buffer in &self.buffers {
560 size += buffer.capacity();
561 }
562 if let Some(bitmap) = &self.nulls {
563 size += bitmap.buffer().capacity()
564 }
565 for child in &self.child_data {
566 size += child.get_buffer_memory_size();
567 }
568 size
569 }
570
571 pub fn get_slice_memory_size(&self) -> Result<usize, ArrowError> {
586 let mut result: usize = 0;
587 let layout = layout(&self.data_type);
588
589 for spec in &layout.buffers {
590 match spec {
591 BufferSpec::FixedWidth { byte_width, .. } => {
592 let len = match self.data_type {
595 DataType::Utf8
596 | DataType::LargeUtf8
597 | DataType::Binary
598 | DataType::LargeBinary
599 | DataType::List(_)
600 | DataType::LargeList(_)
601 | DataType::Map(_, _) => self.len + 1,
602 _ => self.len,
603 };
604 let buffer_size = len.checked_mul(*byte_width).ok_or_else(|| {
605 ArrowError::ComputeError(
606 "Integer overflow computing buffer size".to_string(),
607 )
608 })?;
609 result += buffer_size;
610 }
611 BufferSpec::VariableWidth => {
612 let buffer_len = match self.data_type {
613 DataType::Utf8 | DataType::Binary => {
614 let offsets = self.typed_offsets::<i32>()?;
615 (offsets[self.len] - offsets[0]) as usize
616 }
617 DataType::LargeUtf8 | DataType::LargeBinary => {
618 let offsets = self.typed_offsets::<i64>()?;
619 (offsets[self.len] - offsets[0]) as usize
620 }
621 _ => {
622 return Err(ArrowError::NotYetImplemented(format!(
623 "Invalid data type for VariableWidth buffer. Expected Utf8, LargeUtf8, Binary or LargeBinary. Got {}",
624 self.data_type
625 )));
626 }
627 };
628 result += buffer_len;
629 }
630 BufferSpec::BitMap => {
631 let buffer_size = bit_util::ceil(self.len, 8);
632 result += buffer_size;
633 }
634 BufferSpec::AlwaysNull => {
635 }
637 }
638 }
639
640 if layout.variadic {
641 for buffer in self.buffers.iter().skip(layout.buffers.len()) {
643 result += buffer.capacity();
644 }
645 }
646
647 if self.nulls().is_some() {
648 result += bit_util::ceil(self.len, 8);
649 }
650
651 for child in &self.child_data {
652 result += child.get_slice_memory_size()?;
653 }
654 Ok(result)
655 }
656
657 pub fn get_array_memory_size(&self) -> usize {
666 let mut size = mem::size_of_val(self);
667
668 for buffer in &self.buffers {
670 size += mem::size_of::<Buffer>();
671 size += buffer.capacity();
672 }
673 if let Some(nulls) = &self.nulls {
674 size += nulls.buffer().capacity();
675 }
676 for child in &self.child_data {
677 size += child.get_array_memory_size();
678 }
679
680 size
681 }
682
683 pub fn slice(&self, offset: usize, length: usize) -> ArrayData {
691 self.clone().sliced(offset, length)
692 }
693
694 pub fn sliced(mut self, offset: usize, length: usize) -> Self {
702 self.slice_in_place(offset, length);
703 self
704 }
705
706 fn slice_in_place(&mut self, offset: usize, length: usize) {
707 let end = offset
708 .checked_add(length)
709 .expect("offset + length overflow");
710 assert!(end <= self.len());
711
712 if let DataType::Struct(_) = self.data_type() {
713 let child_offset = self.offset + offset;
718 for child in &mut self.child_data {
719 child.slice_in_place(child_offset, length);
720 }
721 self.offset = 0;
722 } else {
723 self.offset += offset;
724 }
725 self.len = length;
726 self.nulls = self.nulls.as_ref().map(|x| x.slice(offset, length));
729 }
730
731 pub fn buffer<T: ArrowNativeType>(&self, buffer: usize) -> &[T] {
738 &self.buffers()[buffer].typed_data()[self.offset..]
739 }
740
741 pub fn new_null(data_type: &DataType, len: usize) -> Self {
747 let bit_len = bit_util::ceil(len, 8);
748 let zeroed = |len: usize| Buffer::from(MutableBuffer::from_len_zeroed(len));
749
750 let (buffers, child_data, has_nulls) = match data_type.primitive_width() {
751 Some(width) => (vec![zeroed(width * len)], vec![], true),
752 None => match data_type {
753 DataType::Null => (vec![], vec![], false),
754 DataType::Boolean => (vec![zeroed(bit_len)], vec![], true),
755 DataType::Binary | DataType::Utf8 => {
756 (vec![zeroed((len + 1) * 4), zeroed(0)], vec![], true)
757 }
758 DataType::BinaryView | DataType::Utf8View => (vec![zeroed(len * 16)], vec![], true),
759 DataType::LargeBinary | DataType::LargeUtf8 => {
760 (vec![zeroed((len + 1) * 8), zeroed(0)], vec![], true)
761 }
762 DataType::FixedSizeBinary(i) => {
763 if *i < 0 {
764 panic!("cannot construct null data from FixedSizeBinary({i})");
765 }
766 (vec![zeroed(*i as usize * len)], vec![], true)
767 }
768 DataType::List(f) | DataType::Map(f, _) => (
769 vec![zeroed((len + 1) * 4)],
770 vec![ArrayData::new_empty(f.data_type())],
771 true,
772 ),
773 DataType::LargeList(f) => (
774 vec![zeroed((len + 1) * 8)],
775 vec![ArrayData::new_empty(f.data_type())],
776 true,
777 ),
778 DataType::ListView(f) => (
779 vec![zeroed(len * 4), zeroed(len * 4)],
780 vec![ArrayData::new_empty(f.data_type())],
781 true,
782 ),
783 DataType::LargeListView(f) => (
784 vec![zeroed(len * 8), zeroed(len * 8)],
785 vec![ArrayData::new_empty(f.data_type())],
786 true,
787 ),
788 DataType::FixedSizeList(f, list_len) => (
789 vec![],
790 vec![ArrayData::new_null(f.data_type(), *list_len as usize * len)],
791 true,
792 ),
793 DataType::Struct(fields) => (
794 vec![],
795 fields
796 .iter()
797 .map(|f| Self::new_null(f.data_type(), len))
798 .collect(),
799 true,
800 ),
801 DataType::Dictionary(k, v) => (
802 vec![zeroed(k.primitive_width().unwrap() * len)],
803 vec![ArrayData::new_empty(v.as_ref())],
804 true,
805 ),
806 DataType::Union(f, mode) => match f.iter().next() {
807 None => {
811 assert_eq!(
812 len, 0,
813 "cannot construct null data from an empty union of length {len}, a slot has no type id to carry"
814 );
815 let buffers = match mode {
816 UnionMode::Sparse => vec![zeroed(0)],
817 UnionMode::Dense => vec![zeroed(0), zeroed(0)],
818 };
819 (buffers, vec![], false)
820 }
821 Some((id, _)) => {
822 let ids = Buffer::from_iter(std::iter::repeat_n(id, len));
823 let buffers = match mode {
824 UnionMode::Sparse => vec![ids],
825 UnionMode::Dense => {
826 let end_offset = i32::from_usize(len).unwrap();
827 vec![ids, Buffer::from_iter(0_i32..end_offset)]
828 }
829 };
830
831 let children = f
832 .iter()
833 .enumerate()
834 .map(|(idx, (_, f))| {
835 if idx == 0 || *mode == UnionMode::Sparse {
836 Self::new_null(f.data_type(), len)
837 } else {
838 Self::new_empty(f.data_type())
839 }
840 })
841 .collect();
842
843 (buffers, children, false)
844 }
845 },
846 DataType::RunEndEncoded(r, v) => {
847 if len == 0 {
848 let runs = ArrayData::new_empty(r.data_type());
850 let values = ArrayData::new_empty(v.data_type());
851 (vec![], vec![runs, values], false)
852 } else {
853 let runs = match r.data_type() {
854 DataType::Int16 => {
855 let i = i16::from_usize(len).expect("run overflow");
856 Buffer::from_slice_ref([i])
857 }
858 DataType::Int32 => {
859 let i = i32::from_usize(len).expect("run overflow");
860 Buffer::from_slice_ref([i])
861 }
862 DataType::Int64 => {
863 let i = i64::from_usize(len).expect("run overflow");
864 Buffer::from_slice_ref([i])
865 }
866 dt => unreachable!("Invalid run ends data type {dt}"),
867 };
868
869 let builder = ArrayData::builder(r.data_type().clone())
870 .len(1)
871 .buffers(vec![runs]);
872
873 let runs = unsafe { builder.build_unchecked() };
876 (
877 vec![],
878 vec![runs, ArrayData::new_null(v.data_type(), 1)],
879 false,
880 )
881 }
882 }
883 DataType::Int8
885 | DataType::Int16
886 | DataType::Int32
887 | DataType::Int64
888 | DataType::UInt8
889 | DataType::UInt16
890 | DataType::UInt32
891 | DataType::UInt64
892 | DataType::Float16
893 | DataType::Float32
894 | DataType::Float64
895 | DataType::Timestamp(_, _)
896 | DataType::Date32
897 | DataType::Date64
898 | DataType::Time32(_)
899 | DataType::Time64(_)
900 | DataType::Duration(_)
901 | DataType::Interval(_)
902 | DataType::Decimal32(_, _)
903 | DataType::Decimal64(_, _)
904 | DataType::Decimal128(_, _)
905 | DataType::Decimal256(_, _) => unreachable!("{data_type}"),
906 },
907 };
908
909 let mut builder = ArrayDataBuilder::new(data_type.clone())
910 .len(len)
911 .buffers(buffers)
912 .child_data(child_data);
913
914 if has_nulls {
915 builder = builder.nulls(Some(NullBuffer::new_null(len)))
916 }
917
918 unsafe { builder.build_unchecked() }
921 }
922
923 pub fn new_empty(data_type: &DataType) -> Self {
925 Self::new_null(data_type, 0)
926 }
927
928 pub fn align_buffers(&mut self) {
937 let layout = layout(&self.data_type);
938 for (buffer, spec) in self.buffers.iter_mut().zip(&layout.buffers) {
939 if let BufferSpec::FixedWidth { alignment, .. } = spec
940 && buffer.as_ptr().align_offset(*alignment) != 0
941 {
942 *buffer = Buffer::from_slice_ref(buffer.as_ref());
943 }
944 }
945 for data in &mut self.child_data {
947 data.align_buffers()
948 }
949 }
950
951 pub fn validate(&self) -> Result<(), ArrowError> {
962 let len_plus_offset = checked_len_plus_offset(&self.data_type, self.len, self.offset)?;
964
965 let layout = layout(&self.data_type);
967
968 if !layout.can_contain_null_mask && self.nulls.is_some() {
969 return Err(ArrowError::InvalidArgumentError(format!(
970 "Arrays of type {:?} cannot contain a null bitmask",
971 self.data_type,
972 )));
973 }
974
975 if self.buffers.len() < layout.buffers.len()
977 || (!layout.variadic && self.buffers.len() != layout.buffers.len())
978 {
979 return Err(ArrowError::InvalidArgumentError(format!(
980 "Expected {} buffers in array of type {:?}, got {}",
981 layout.buffers.len(),
982 self.data_type,
983 self.buffers.len(),
984 )));
985 }
986
987 for (i, (buffer, spec)) in self.buffers.iter().zip(layout.buffers.iter()).enumerate() {
988 match spec {
989 BufferSpec::FixedWidth {
990 byte_width,
991 alignment,
992 } => {
993 let min_buffer_size = len_plus_offset.saturating_mul(*byte_width);
994
995 if buffer.len() < min_buffer_size {
996 return Err(ArrowError::InvalidArgumentError(format!(
997 "Need at least {} bytes in buffers[{}] in array of type {:?}, but got {}",
998 min_buffer_size,
999 i,
1000 self.data_type,
1001 buffer.len()
1002 )));
1003 }
1004
1005 let align_offset = buffer.as_ptr().align_offset(*alignment);
1006 if align_offset != 0 {
1007 return Err(ArrowError::InvalidArgumentError(format!(
1008 "Misaligned buffers[{i}] in array of type {:?}, offset from expected alignment of {alignment} by {}",
1009 self.data_type,
1010 align_offset.min(alignment - align_offset)
1011 )));
1012 }
1013 }
1014 BufferSpec::VariableWidth => {
1015 }
1019 BufferSpec::BitMap => {
1020 let min_buffer_size = bit_util::ceil(len_plus_offset, 8);
1021 if buffer.len() < min_buffer_size {
1022 return Err(ArrowError::InvalidArgumentError(format!(
1023 "Need at least {} bytes for bitmap in buffers[{}] in array of type {:?}, but got {}",
1024 min_buffer_size,
1025 i,
1026 self.data_type,
1027 buffer.len()
1028 )));
1029 }
1030 }
1031 BufferSpec::AlwaysNull => {
1032 }
1034 }
1035 }
1036
1037 if let Some(nulls) = self.nulls() {
1039 if nulls.null_count() > self.len {
1040 return Err(ArrowError::InvalidArgumentError(format!(
1041 "null_count {} for an array exceeds length of {} elements",
1042 nulls.null_count(),
1043 self.len
1044 )));
1045 }
1046
1047 if nulls.len() != self.len {
1048 return Err(ArrowError::InvalidArgumentError(format!(
1049 "null buffer incorrect size. got {} expected {}",
1050 nulls.len(),
1051 self.len
1052 )));
1053 }
1054 }
1055
1056 self.validate_child_data()?;
1057
1058 match &self.data_type {
1060 DataType::Utf8 | DataType::Binary => {
1061 self.validate_offsets::<i32>(self.buffers[1].len())?;
1062 }
1063 DataType::LargeUtf8 | DataType::LargeBinary => {
1064 self.validate_offsets::<i64>(self.buffers[1].len())?;
1065 }
1066 DataType::Dictionary(key_type, _value_type) => {
1067 if !DataType::is_dictionary_key_type(key_type) {
1069 return Err(ArrowError::InvalidArgumentError(format!(
1070 "Dictionary key type must be integer, but was {key_type}"
1071 )));
1072 }
1073 }
1074 DataType::RunEndEncoded(run_ends_type, _) => {
1075 if run_ends_type.is_nullable() {
1076 return Err(ArrowError::InvalidArgumentError(
1077 "The nullable should be set to false for the field defining run_ends array.".to_string()
1078 ));
1079 }
1080 if !DataType::is_run_ends_type(run_ends_type.data_type()) {
1081 return Err(ArrowError::InvalidArgumentError(format!(
1082 "RunArray run_ends types must be Int16, Int32 or Int64, but was {}",
1083 run_ends_type.data_type()
1084 )));
1085 }
1086 }
1087 DataType::Map(f, _) if f.is_nullable() => {
1088 return Err(ArrowError::InvalidArgumentError(
1089 "The nullable should be set to false for the map entries field.".to_string(),
1090 ));
1091 }
1092 _ => {}
1093 }
1094
1095 Ok(())
1096 }
1097
1098 fn typed_offsets<T: ArrowNativeType + num_traits::Num>(&self) -> Result<&[T], ArrowError> {
1105 if self.len == 0 && self.buffer_at(0)?.is_empty() {
1107 return Ok(&[]);
1108 }
1109
1110 let len = checked_len_plus_offset(&self.data_type, self.len, 1)?;
1111
1112 self.typed_buffer(0, len)
1113 }
1114
1115 fn typed_buffer<T: ArrowNativeType + num_traits::Num>(
1117 &self,
1118 idx: usize,
1119 len: usize,
1120 ) -> Result<&[T], ArrowError> {
1121 let buffer = self.buffer_at(idx)?;
1122
1123 let required_elements = checked_len_plus_offset(&self.data_type, len, self.offset)?;
1124 let byte_width = mem::size_of::<T>();
1125 let required_len = required_elements.checked_mul(byte_width).ok_or_else(|| {
1126 ArrowError::InvalidArgumentError(format!(
1127 "Buffer {idx} of {} byte length overflow: {} elements of {} bytes exceeds usize",
1128 self.data_type, required_elements, byte_width
1129 ))
1130 })?;
1131
1132 if buffer.len() < required_len {
1133 return Err(ArrowError::InvalidArgumentError(format!(
1134 "Buffer {} of {} isn't large enough. Expected {} bytes got {}",
1135 idx,
1136 self.data_type,
1137 required_len,
1138 buffer.len()
1139 )));
1140 }
1141
1142 Ok(&buffer.typed_data::<T>()[self.offset..required_elements])
1143 }
1144
1145 fn validate_offsets<T: ArrowNativeType + num_traits::Num + std::fmt::Display>(
1148 &self,
1149 values_length: usize,
1150 ) -> Result<(), ArrowError> {
1151 let offsets = self.typed_offsets::<T>()?;
1153 if offsets.is_empty() {
1154 return Ok(());
1155 }
1156
1157 let first_offset = offsets[0].to_usize().ok_or_else(|| {
1158 ArrowError::InvalidArgumentError(format!(
1159 "Error converting offset[0] ({}) to usize for {}",
1160 offsets[0], self.data_type
1161 ))
1162 })?;
1163
1164 let last_offset = offsets[self.len].to_usize().ok_or_else(|| {
1165 ArrowError::InvalidArgumentError(format!(
1166 "Error converting offset[{}] ({}) to usize for {}",
1167 self.len, offsets[self.len], self.data_type
1168 ))
1169 })?;
1170
1171 if first_offset > values_length {
1172 return Err(ArrowError::InvalidArgumentError(format!(
1173 "First offset {} of {} is larger than values length {}",
1174 first_offset, self.data_type, values_length,
1175 )));
1176 }
1177
1178 if last_offset > values_length {
1179 return Err(ArrowError::InvalidArgumentError(format!(
1180 "Last offset {} of {} is larger than values length {}",
1181 last_offset, self.data_type, values_length,
1182 )));
1183 }
1184
1185 if first_offset > last_offset {
1186 return Err(ArrowError::InvalidArgumentError(format!(
1187 "First offset {} in {} is smaller than last offset {}",
1188 first_offset, self.data_type, last_offset,
1189 )));
1190 }
1191
1192 Ok(())
1193 }
1194
1195 fn validate_offsets_and_sizes<T: ArrowNativeType + num_traits::Num + std::fmt::Display>(
1198 &self,
1199 values_length: usize,
1200 ) -> Result<(), ArrowError> {
1201 let offsets: &[T] = self.typed_buffer(0, self.len)?;
1202 let sizes: &[T] = self.typed_buffer(1, self.len)?;
1203 if offsets.len() != sizes.len() {
1204 return Err(ArrowError::ComputeError(format!(
1205 "ListView offsets len {} does not match sizes len {}",
1206 offsets.len(),
1207 sizes.len()
1208 )));
1209 }
1210
1211 for i in 0..sizes.len() {
1212 let size = sizes[i].to_usize().ok_or_else(|| {
1213 ArrowError::InvalidArgumentError(format!(
1214 "Error converting size[{}] ({}) to usize for {}",
1215 i, sizes[i], self.data_type
1216 ))
1217 })?;
1218 let offset = offsets[i].to_usize().ok_or_else(|| {
1219 ArrowError::InvalidArgumentError(format!(
1220 "Error converting offset[{}] ({}) to usize for {}",
1221 i, offsets[i], self.data_type
1222 ))
1223 })?;
1224 if size
1225 .checked_add(offset)
1226 .expect("Offset and size have exceeded the usize boundary")
1227 > values_length
1228 {
1229 return Err(ArrowError::InvalidArgumentError(format!(
1230 "Size {} at index {} is larger than the remaining values for {}",
1231 size, i, self.data_type
1232 )));
1233 }
1234 }
1235 Ok(())
1236 }
1237
1238 fn validate_child_data(&self) -> Result<(), ArrowError> {
1240 match &self.data_type {
1241 DataType::List(field) => {
1242 let values_data = self.get_single_valid_child_data(field.data_type())?;
1243 self.validate_offsets::<i32>(values_data.len)?;
1244 }
1245 DataType::LargeList(field) => {
1246 let values_data = self.get_single_valid_child_data(field.data_type())?;
1247 self.validate_offsets::<i64>(values_data.len)?;
1248 }
1249 DataType::Map(field, _) => {
1250 let DataType::Struct(entries_fields) = field.data_type() else {
1251 return Err(ArrowError::InvalidArgumentError(format!(
1252 "Map field should be a entries struct data type, got {:?} instead",
1253 field.data_type()
1254 )));
1255 };
1256 if entries_fields.len() != 2 {
1257 return Err(ArrowError::InvalidArgumentError(format!(
1258 "Map entries data type should be a struct containing 2 fields, got {} fields",
1259 entries_fields.len()
1260 )));
1261 }
1262
1263 if entries_fields[0].is_nullable() {
1265 return Err(ArrowError::InvalidArgumentError(
1266 "Map key field must not be nullable".to_string(),
1267 ));
1268 }
1269 let values_data = self.get_single_valid_child_data(field.data_type())?;
1270 self.validate_offsets::<i32>(values_data.len)?;
1271 }
1272 DataType::ListView(field) => {
1273 let values_data = self.get_single_valid_child_data(field.data_type())?;
1274 self.validate_offsets_and_sizes::<i32>(values_data.len)?;
1275 }
1276 DataType::LargeListView(field) => {
1277 let values_data = self.get_single_valid_child_data(field.data_type())?;
1278 self.validate_offsets_and_sizes::<i64>(values_data.len)?;
1279 }
1280 DataType::FixedSizeList(field, list_size) => {
1281 let values_data = self.get_single_valid_child_data(field.data_type())?;
1282
1283 let list_size: usize = (*list_size).try_into().map_err(|_| {
1284 ArrowError::InvalidArgumentError(format!(
1285 "{} has a negative list_size {}",
1286 self.data_type, list_size
1287 ))
1288 })?;
1289
1290 let len_plus_offset =
1291 checked_len_plus_offset(&self.data_type, self.len, self.offset)?;
1292 let expected_values_len = len_plus_offset
1293 .checked_mul(list_size)
1294 .expect("integer overflow computing expected number of expected values in FixedListSize");
1295
1296 if values_data.len < expected_values_len {
1297 return Err(ArrowError::InvalidArgumentError(format!(
1298 "Values length {} is less than the length + offset ({}) multiplied by the value size ({}) for {}",
1299 values_data.len, len_plus_offset, list_size, self.data_type
1300 )));
1301 }
1302 }
1303 DataType::Struct(fields) => {
1304 self.validate_num_child_data(fields.len())?;
1305 let len_plus_offset =
1306 checked_len_plus_offset(&self.data_type, self.len, self.offset)?;
1307 for (i, field) in fields.iter().enumerate() {
1308 let field_data = self.get_valid_child_data(i, field.data_type())?;
1309
1310 if field_data.len < len_plus_offset {
1312 return Err(ArrowError::InvalidArgumentError(format!(
1313 "{} child array #{} for field {} has length smaller than expected for struct array ({} < {})",
1314 self.data_type,
1315 i,
1316 field.name(),
1317 field_data.len,
1318 len_plus_offset
1319 )));
1320 }
1321 }
1322 }
1323 DataType::RunEndEncoded(run_ends_field, values_field) => {
1324 self.validate_num_child_data(2)?;
1325 let run_ends_data = self.get_valid_child_data(0, run_ends_field.data_type())?;
1326 let values_data = self.get_valid_child_data(1, values_field.data_type())?;
1327 if run_ends_data.len != values_data.len {
1328 return Err(ArrowError::InvalidArgumentError(format!(
1329 "The run_ends array length should be the same as values array length. Run_ends array length is {}, values array length is {}",
1330 run_ends_data.len, values_data.len
1331 )));
1332 }
1333 if run_ends_data.nulls.is_some() {
1334 return Err(ArrowError::InvalidArgumentError(
1335 "Found null values in run_ends array. The run_ends array should not have null values.".to_string(),
1336 ));
1337 }
1338 }
1339 DataType::Union(fields, mode) => {
1340 self.validate_num_child_data(fields.len())?;
1341
1342 for (i, (_, field)) in fields.iter().enumerate() {
1343 let field_data = self.get_valid_child_data(i, field.data_type())?;
1344
1345 if mode == &UnionMode::Sparse {
1346 let len_plus_offset =
1347 checked_len_plus_offset(&self.data_type, self.len, self.offset)?;
1348 if field_data.len < len_plus_offset {
1349 return Err(ArrowError::InvalidArgumentError(format!(
1350 "Sparse union child array #{} has length smaller than expected for union array ({} < {})",
1351 i, field_data.len, len_plus_offset
1352 )));
1353 }
1354 }
1355 }
1356 }
1357 DataType::Dictionary(_key_type, value_type) => {
1358 self.get_single_valid_child_data(value_type)?;
1359 }
1360 _ => {
1361 if !self.child_data.is_empty() {
1363 return Err(ArrowError::InvalidArgumentError(format!(
1364 "Expected no child arrays for type {} but got {}",
1365 self.data_type,
1366 self.child_data.len()
1367 )));
1368 }
1369 }
1370 }
1371 Ok(())
1372 }
1373
1374 fn get_single_valid_child_data(
1378 &self,
1379 expected_type: &DataType,
1380 ) -> Result<&ArrayData, ArrowError> {
1381 self.validate_num_child_data(1)?;
1382 self.get_valid_child_data(0, expected_type)
1383 }
1384
1385 fn buffer_at(&self, idx: usize) -> Result<&Buffer, ArrowError> {
1390 self.buffers.get(idx).ok_or_else(|| {
1391 ArrowError::InvalidArgumentError(format!(
1392 "{} should contain at least {} buffer(s), had {}",
1393 self.data_type,
1394 idx + 1,
1395 self.buffers.len()
1396 ))
1397 })
1398 }
1399
1400 fn child_at(&self, idx: usize) -> Result<&ArrayData, ArrowError> {
1405 self.child_data.get(idx).ok_or_else(|| {
1406 ArrowError::InvalidArgumentError(format!(
1407 "{} should contain at least {} child data array(s), had {}",
1408 self.data_type,
1409 idx + 1,
1410 self.child_data.len()
1411 ))
1412 })
1413 }
1414
1415 fn validate_num_child_data(&self, expected_len: usize) -> Result<(), ArrowError> {
1417 if self.child_data.len() != expected_len {
1418 Err(ArrowError::InvalidArgumentError(format!(
1419 "Value data for {} should contain {} child data array(s), had {}",
1420 self.data_type,
1421 expected_len,
1422 self.child_data.len()
1423 )))
1424 } else {
1425 Ok(())
1426 }
1427 }
1428
1429 fn get_valid_child_data(
1432 &self,
1433 i: usize,
1434 expected_type: &DataType,
1435 ) -> Result<&ArrayData, ArrowError> {
1436 let values_data = self.child_data.get(i).ok_or_else(|| {
1437 ArrowError::InvalidArgumentError(format!(
1438 "{} did not have enough child arrays. Expected at least {} but had only {}",
1439 self.data_type,
1440 i + 1,
1441 self.child_data.len()
1442 ))
1443 })?;
1444
1445 if expected_type != &values_data.data_type {
1446 return Err(ArrowError::InvalidArgumentError(format!(
1447 "Child type mismatch for {}. Expected {} but child data had {}",
1448 self.data_type, expected_type, values_data.data_type
1449 )));
1450 }
1451
1452 values_data.validate()?;
1453 Ok(values_data)
1454 }
1455
1456 pub fn validate_data(&self) -> Result<(), ArrowError> {
1472 self.validate()?;
1473
1474 self.validate_nulls()?;
1475 self.validate_values()?;
1476 Ok(())
1477 }
1478
1479 pub fn validate_full(&self) -> Result<(), ArrowError> {
1484 self.validate_data()?;
1485 self.child_data
1487 .iter()
1488 .enumerate()
1489 .try_for_each(|(i, child_data)| {
1490 child_data.validate_full().map_err(|e| {
1491 ArrowError::InvalidArgumentError(format!(
1492 "{} child #{} invalid: {}",
1493 self.data_type, i, e
1494 ))
1495 })
1496 })?;
1497 Ok(())
1498 }
1499
1500 pub fn validate_nulls(&self) -> Result<(), ArrowError> {
1510 if let Some(nulls) = &self.nulls {
1511 let actual = nulls.len() - nulls.inner().count_set_bits();
1512 if actual != nulls.null_count() {
1513 return Err(ArrowError::InvalidArgumentError(format!(
1514 "null_count value ({}) doesn't match actual number of nulls in array ({})",
1515 nulls.null_count(),
1516 actual
1517 )));
1518 }
1519 }
1520
1521 match &self.data_type {
1526 DataType::List(f) | DataType::LargeList(f) | DataType::Map(f, _) => {
1527 if !f.is_nullable() {
1528 let child = &self.child_data[0];
1529 self.validate_non_nullable(None, child, child.nulls())?
1530 }
1531 }
1532 DataType::FixedSizeList(field, len) => {
1533 let child = &self.child_data[0];
1534 if !field.is_nullable() {
1535 let element_len = *len as usize;
1536 let child_nulls = child.nulls().map(|nulls| {
1537 nulls.slice(self.offset * element_len, self.len * element_len)
1538 });
1539 let expanded = self.nulls.as_ref().map(|nulls| nulls.expand(element_len));
1540 self.validate_non_nullable(expanded.as_ref(), child, child_nulls.as_ref())?;
1541 }
1542 }
1543 DataType::Struct(fields) => {
1544 for (field, child) in fields.iter().zip(&self.child_data) {
1545 if !field.is_nullable() {
1546 let child_nulls = child
1547 .nulls()
1548 .map(|nulls| nulls.slice(self.offset, self.len));
1549 self.validate_non_nullable(self.nulls(), child, child_nulls.as_ref())?
1550 }
1551 }
1552 }
1553 _ => {}
1554 }
1555
1556 Ok(())
1557 }
1558
1559 fn validate_non_nullable(
1561 &self,
1562 mask: Option<&NullBuffer>,
1563 child: &ArrayData,
1564 child_nulls: Option<&NullBuffer>,
1565 ) -> Result<(), ArrowError> {
1566 let Some(mask) = mask else {
1567 return match child_nulls.map(NullBuffer::null_count).unwrap_or_default() {
1568 0 => Ok(()),
1569 _ => Err(ArrowError::InvalidArgumentError(format!(
1570 "non-nullable child of type {} contains nulls not present in parent {}",
1571 child.data_type, self.data_type
1572 ))),
1573 };
1574 };
1575
1576 match child_nulls {
1577 Some(nulls) if !mask.contains(nulls) => Err(ArrowError::InvalidArgumentError(format!(
1578 "non-nullable child of type {} contains nulls not present in parent",
1579 child.data_type
1580 ))),
1581 _ => Ok(()),
1582 }
1583 }
1584
1585 pub fn validate_values(&self) -> Result<(), ArrowError> {
1591 match &self.data_type {
1592 DataType::Utf8 => self.validate_utf8::<i32>(),
1593 DataType::LargeUtf8 => self.validate_utf8::<i64>(),
1594 DataType::Binary => self.validate_offsets_full::<i32>(self.buffer_at(1)?.len()),
1595 DataType::LargeBinary => self.validate_offsets_full::<i64>(self.buffer_at(1)?.len()),
1596 DataType::BinaryView => {
1597 let views = self.typed_buffer::<u128>(0, self.len)?;
1598 validate_binary_view(views, &self.buffers[1..])
1599 }
1600 DataType::Utf8View => {
1601 let views = self.typed_buffer::<u128>(0, self.len)?;
1602 validate_string_view(views, &self.buffers[1..])
1603 }
1604 DataType::List(_) | DataType::Map(_, _) => {
1605 let child = self.child_at(0)?;
1606 self.validate_offsets_full::<i32>(child.len)
1607 }
1608 DataType::LargeList(_) => {
1609 let child = self.child_at(0)?;
1610 self.validate_offsets_full::<i64>(child.len)
1611 }
1612 DataType::Union(fields, mode) => {
1613 let mut child_lens: Vec<Option<usize>> = vec![None; 128];
1614 for (index, (type_id, _)) in fields.iter().enumerate() {
1615 let child = self.child_at(index)?;
1616 child_lens[type_id as usize] = Some(child.len());
1617 }
1618
1619 let type_ids = self.typed_buffer::<i8>(0, self.len)?;
1621 for (index, &type_id) in type_ids.iter().enumerate() {
1622 if type_id < 0 {
1623 return Err(ArrowError::InvalidArgumentError(format!(
1624 "Type id values cannot be negative, got {type_id} at index {index}"
1625 )));
1626 }
1627 let type_id = type_id as usize;
1628 if child_lens[type_id].is_none() {
1629 return Err(ArrowError::InvalidArgumentError(format!(
1630 "Type id values must match one of the field type ids, got {type_id} at index {index}"
1631 )));
1632 }
1633 }
1634
1635 if mode == &UnionMode::Dense {
1637 let offsets = self.typed_buffer::<i32>(1, self.len)?;
1638
1639 if type_ids
1640 .iter()
1641 .zip(offsets.iter())
1642 .any(|(&type_id, &offset)| {
1643 offset < 0 || offset as usize >= child_lens[type_id as usize].unwrap()
1644 })
1645 {
1646 return Err(ArrowError::InvalidArgumentError(
1647 "Offsets must be non-negative and within the length of the child array"
1648 .to_string(),
1649 ));
1650 }
1651 }
1652
1653 Ok(())
1654 }
1655 DataType::Dictionary(key_type, _value_type) => {
1656 let dictionary_length = self.child_at(0)?.len;
1657 let dictionary_length = i64::try_from(dictionary_length).map_err(|_| {
1658 ArrowError::InvalidArgumentError(format!(
1659 "Dictionary of {dictionary_length} values is too long for an i64"
1660 ))
1661 })?;
1662 let max_value = dictionary_length - 1;
1663 match key_type.as_ref() {
1664 DataType::UInt8 => self.check_bounds::<u8>(max_value),
1665 DataType::UInt16 => self.check_bounds::<u16>(max_value),
1666 DataType::UInt32 => self.check_bounds::<u32>(max_value),
1667 DataType::UInt64 => self.check_bounds::<u64>(max_value),
1668 DataType::Int8 => self.check_bounds::<i8>(max_value),
1669 DataType::Int16 => self.check_bounds::<i16>(max_value),
1670 DataType::Int32 => self.check_bounds::<i32>(max_value),
1671 DataType::Int64 => self.check_bounds::<i64>(max_value),
1672 _ => Err(ArrowError::InvalidArgumentError(format!(
1673 "Dictionary key type must be an integer, got {key_type}"
1674 ))),
1675 }
1676 }
1677 DataType::RunEndEncoded(run_ends, _values) => {
1678 let len_plus_offset =
1679 checked_len_plus_offset(&self.data_type, self.len, self.offset)?;
1680 let run_ends_data = self.child_at(0)?;
1681 match run_ends.data_type() {
1682 DataType::Int16 => {
1683 run_ends_data.check_run_ends::<i16>(self.len, len_plus_offset)
1684 }
1685 DataType::Int32 => {
1686 run_ends_data.check_run_ends::<i32>(self.len, len_plus_offset)
1687 }
1688 DataType::Int64 => {
1689 run_ends_data.check_run_ends::<i64>(self.len, len_plus_offset)
1690 }
1691 data_type => Err(ArrowError::InvalidArgumentError(format!(
1692 "Run end type must be Int16, Int32 or Int64, got {data_type}"
1693 ))),
1694 }
1695 }
1696 _ => {
1697 Ok(())
1699 }
1700 }
1701 }
1702
1703 fn validate_each_offset<T, V>(&self, offset_limit: usize, validate: V) -> Result<(), ArrowError>
1714 where
1715 T: ArrowNativeType + TryInto<usize> + num_traits::Num + std::fmt::Display,
1716 V: Fn(usize, Range<usize>) -> Result<(), ArrowError>,
1717 {
1718 self.typed_offsets::<T>()?
1719 .iter()
1720 .enumerate()
1721 .map(|(i, x)| {
1722 let r = x.to_usize().ok_or_else(|| {
1724 ArrowError::InvalidArgumentError(format!(
1725 "Offset invariant failure: Could not convert offset {x} to usize at position {i}"))}
1726 );
1727 match r {
1729 Ok(n) if n <= offset_limit => Ok((i, n)),
1730 Ok(_) => Err(ArrowError::InvalidArgumentError(format!(
1731 "Offset invariant failure: offset at position {i} out of bounds: {x} > {offset_limit}"))
1732 ),
1733 Err(e) => Err(e),
1734 }
1735 })
1736 .scan(0_usize, |start, end| {
1737 match end {
1739 Ok((i, end)) if *start <= end => {
1740 let range = Some(Ok((i, *start..end)));
1741 *start = end;
1742 range
1743 }
1744 Ok((i, end)) => Some(Err(ArrowError::InvalidArgumentError(format!(
1745 "Offset invariant failure: non-monotonic offset at slot {}: {} > {}",
1746 i - 1, start, end))
1747 )),
1748 Err(err) => Some(Err(err)),
1749 }
1750 })
1751 .skip(1) .try_for_each(|res: Result<(usize, Range<usize>), ArrowError>| {
1753 let (item_index, range) = res?;
1754 validate(item_index-1, range)
1755 })
1756 }
1757
1758 fn validate_utf8<T>(&self) -> Result<(), ArrowError>
1762 where
1763 T: ArrowNativeType + TryInto<usize> + num_traits::Num + std::fmt::Display,
1764 {
1765 let values_buffer = &self.buffer_at(1)?.as_slice();
1766 let offsets = self.typed_offsets::<T>()?;
1767 if let Some((first, last, values_str)) = utf8_span(offsets, values_buffer) {
1768 self.validate_each_offset::<T, _>(values_buffer.len(), |string_index, range| {
1769 if range.end > last {
1773 return Ok(());
1774 }
1775 let (start, end) = (range.start - first, range.end - first);
1776 if !values_str.is_char_boundary(start) || !values_str.is_char_boundary(end) {
1777 return Err(ArrowError::InvalidArgumentError(format!(
1778 "incomplete utf-8 byte sequence from index {string_index}"
1779 )));
1780 }
1781 Ok(())
1782 })
1783 } else {
1784 self.validate_each_offset::<T, _>(values_buffer.len(), |string_index, range| {
1786 std::str::from_utf8(&values_buffer[range.clone()]).map_err(|e| {
1787 ArrowError::InvalidArgumentError(format!(
1788 "Invalid UTF8 sequence at string index {string_index} ({range:?}): {e}"
1789 ))
1790 })?;
1791 Ok(())
1792 })
1793 }
1794 }
1795
1796 fn validate_offsets_full<T>(&self, offset_limit: usize) -> Result<(), ArrowError>
1799 where
1800 T: ArrowNativeType + TryInto<usize> + num_traits::Num + std::fmt::Display,
1801 {
1802 self.validate_each_offset::<T, _>(offset_limit, |_string_index, _range| {
1803 Ok(())
1806 })
1807 }
1808
1809 fn check_bounds<T>(&self, max_value: i64) -> Result<(), ArrowError>
1812 where
1813 T: ArrowNativeType + TryInto<i64> + num_traits::Num + std::fmt::Display,
1814 {
1815 let indexes: &[T] = self.typed_buffer::<T>(0, self.len)?;
1818
1819 indexes.iter().enumerate().try_for_each(|(i, &dict_index)| {
1820 if self.is_null(i) {
1822 return Ok(());
1823 }
1824 let dict_index: i64 = dict_index.try_into().map_err(|_| {
1825 ArrowError::InvalidArgumentError(format!(
1826 "Value at position {i} out of bounds: {dict_index} (can not convert to i64)"
1827 ))
1828 })?;
1829
1830 if dict_index < 0 || dict_index > max_value {
1831 return Err(ArrowError::InvalidArgumentError(format!(
1832 "Value at position {i} out of bounds: {dict_index} (should be in [0, {max_value}])"
1833 )));
1834 }
1835 Ok(())
1836 })
1837 }
1838
1839 fn check_run_ends<T>(
1841 &self,
1842 parent_len: usize,
1843 parent_len_plus_offset: usize,
1844 ) -> Result<(), ArrowError>
1845 where
1846 T: ArrowNativeType + TryInto<i64> + num_traits::Num + std::fmt::Display,
1847 {
1848 let values = self.typed_buffer::<T>(0, self.len)?;
1849 let mut prev_value = 0_i64;
1850 values.iter().enumerate().try_for_each(|(ix, &inp_value)| {
1851 let value: i64 = inp_value.try_into().map_err(|_| {
1852 ArrowError::InvalidArgumentError(format!(
1853 "Value at position {ix} out of bounds: {inp_value} (can not convert to i64)"
1854 ))
1855 })?;
1856 if value <= 0_i64 {
1857 return Err(ArrowError::InvalidArgumentError(format!(
1858 "The values in run_ends array should be strictly positive. Found value {value} at index {ix} that does not match the criteria."
1859 )));
1860 }
1861 if ix > 0 && value <= prev_value {
1862 return Err(ArrowError::InvalidArgumentError(format!(
1863 "The values in run_ends array should be strictly increasing. Found value {value} at index {ix} with previous value {prev_value} that does not match the criteria."
1864 )));
1865 }
1866
1867 prev_value = value;
1868 Ok(())
1869 })?;
1870
1871 if parent_len > 0 && prev_value.as_usize() < parent_len_plus_offset {
1872 return Err(ArrowError::InvalidArgumentError(format!(
1873 "The offset + length of array should be less or equal to last value in the run_ends array. The last value of run_ends array is {prev_value} and offset + length of array is {parent_len_plus_offset}."
1874 )));
1875 }
1876 Ok(())
1877 }
1878
1879 pub fn ptr_eq(&self, other: &Self) -> bool {
1883 if self.offset != other.offset
1884 || self.len != other.len
1885 || self.data_type != other.data_type
1886 || self.buffers.len() != other.buffers.len()
1887 || self.child_data.len() != other.child_data.len()
1888 {
1889 return false;
1890 }
1891
1892 match (&self.nulls, &other.nulls) {
1893 (Some(a), Some(b)) if !a.inner().ptr_eq(b.inner()) => return false,
1894 (Some(_), None) | (None, Some(_)) => return false,
1895 _ => {}
1896 }
1897
1898 if !self
1899 .buffers
1900 .iter()
1901 .zip(other.buffers.iter())
1902 .all(|(a, b)| a.as_ptr() == b.as_ptr())
1903 {
1904 return false;
1905 }
1906
1907 self.child_data
1908 .iter()
1909 .zip(other.child_data.iter())
1910 .all(|(a, b)| a.ptr_eq(b))
1911 }
1912
1913 pub fn into_builder(self) -> ArrayDataBuilder {
1915 self.into()
1916 }
1917
1918 #[cfg(feature = "pool")]
1925 pub fn claim(&self, pool: &dyn arrow_buffer::MemoryPool) {
1926 for buffer in &self.buffers {
1928 buffer.claim(pool);
1929 }
1930
1931 if let Some(nulls) = &self.nulls {
1933 nulls.claim(pool);
1934 }
1935
1936 for child in &self.child_data {
1938 child.claim(pool);
1939 }
1940 }
1941}
1942
1943pub fn layout(data_type: &DataType) -> DataTypeLayout {
1946 use arrow_schema::IntervalUnit::*;
1949
1950 match data_type {
1951 DataType::Null => DataTypeLayout {
1952 buffers: vec![],
1953 can_contain_null_mask: false,
1954 variadic: false,
1955 },
1956 DataType::Boolean => DataTypeLayout {
1957 buffers: vec![BufferSpec::BitMap],
1958 can_contain_null_mask: true,
1959 variadic: false,
1960 },
1961 DataType::Int8 => DataTypeLayout::new_fixed_width::<i8>(),
1962 DataType::Int16 => DataTypeLayout::new_fixed_width::<i16>(),
1963 DataType::Int32 => DataTypeLayout::new_fixed_width::<i32>(),
1964 DataType::Int64 => DataTypeLayout::new_fixed_width::<i64>(),
1965 DataType::UInt8 => DataTypeLayout::new_fixed_width::<u8>(),
1966 DataType::UInt16 => DataTypeLayout::new_fixed_width::<u16>(),
1967 DataType::UInt32 => DataTypeLayout::new_fixed_width::<u32>(),
1968 DataType::UInt64 => DataTypeLayout::new_fixed_width::<u64>(),
1969 DataType::Float16 => DataTypeLayout::new_fixed_width::<half::f16>(),
1970 DataType::Float32 => DataTypeLayout::new_fixed_width::<f32>(),
1971 DataType::Float64 => DataTypeLayout::new_fixed_width::<f64>(),
1972 DataType::Timestamp(_, _) => DataTypeLayout::new_fixed_width::<i64>(),
1973 DataType::Date32 => DataTypeLayout::new_fixed_width::<i32>(),
1974 DataType::Date64 => DataTypeLayout::new_fixed_width::<i64>(),
1975 DataType::Time32(_) => DataTypeLayout::new_fixed_width::<i32>(),
1976 DataType::Time64(_) => DataTypeLayout::new_fixed_width::<i64>(),
1977 DataType::Interval(YearMonth) => DataTypeLayout::new_fixed_width::<i32>(),
1978 DataType::Interval(DayTime) => DataTypeLayout::new_fixed_width::<IntervalDayTime>(),
1979 DataType::Interval(MonthDayNano) => {
1980 DataTypeLayout::new_fixed_width::<IntervalMonthDayNano>()
1981 }
1982 DataType::Duration(_) => DataTypeLayout::new_fixed_width::<i64>(),
1983 DataType::Decimal32(_, _) => DataTypeLayout::new_fixed_width::<i32>(),
1984 DataType::Decimal64(_, _) => DataTypeLayout::new_fixed_width::<i64>(),
1985 DataType::Decimal128(_, _) => DataTypeLayout::new_fixed_width::<i128>(),
1986 DataType::Decimal256(_, _) => DataTypeLayout::new_fixed_width::<i256>(),
1987 DataType::FixedSizeBinary(size) => {
1988 let spec = BufferSpec::FixedWidth {
1989 byte_width: (*size).try_into().unwrap(),
1990 alignment: mem::align_of::<u8>(),
1991 };
1992 DataTypeLayout {
1993 buffers: vec![spec],
1994 can_contain_null_mask: true,
1995 variadic: false,
1996 }
1997 }
1998 DataType::Binary => DataTypeLayout::new_binary::<i32>(),
1999 DataType::LargeBinary => DataTypeLayout::new_binary::<i64>(),
2000 DataType::Utf8 => DataTypeLayout::new_binary::<i32>(),
2001 DataType::LargeUtf8 => DataTypeLayout::new_binary::<i64>(),
2002 DataType::BinaryView | DataType::Utf8View => DataTypeLayout::new_view(),
2003 DataType::FixedSizeList(_, _) => DataTypeLayout::new_nullable_empty(), DataType::List(_) => DataTypeLayout::new_fixed_width::<i32>(),
2005 DataType::ListView(_) => DataTypeLayout::new_list_view::<i32>(),
2006 DataType::LargeListView(_) => DataTypeLayout::new_list_view::<i64>(),
2007 DataType::LargeList(_) => DataTypeLayout::new_fixed_width::<i64>(),
2008 DataType::Map(_, _) => DataTypeLayout::new_fixed_width::<i32>(),
2009 DataType::Struct(_) => DataTypeLayout::new_nullable_empty(), DataType::RunEndEncoded(_, _) => DataTypeLayout::new_empty(), DataType::Union(_, mode) => {
2012 let type_ids = BufferSpec::FixedWidth {
2013 byte_width: mem::size_of::<i8>(),
2014 alignment: mem::align_of::<i8>(),
2015 };
2016
2017 DataTypeLayout {
2018 buffers: match mode {
2019 UnionMode::Sparse => {
2020 vec![type_ids]
2021 }
2022 UnionMode::Dense => {
2023 vec![
2024 type_ids,
2025 BufferSpec::FixedWidth {
2026 byte_width: mem::size_of::<i32>(),
2027 alignment: mem::align_of::<i32>(),
2028 },
2029 ]
2030 }
2031 },
2032 can_contain_null_mask: false,
2033 variadic: false,
2034 }
2035 }
2036 DataType::Dictionary(key_type, _value_type) => layout(key_type),
2037 }
2038}
2039
2040#[derive(Debug, PartialEq, Eq)]
2042pub struct DataTypeLayout {
2044 pub buffers: Vec<BufferSpec>,
2046
2047 pub can_contain_null_mask: bool,
2049
2050 pub variadic: bool,
2054}
2055
2056impl DataTypeLayout {
2057 pub fn new_fixed_width<T>() -> Self {
2059 Self {
2060 buffers: vec![BufferSpec::FixedWidth {
2061 byte_width: mem::size_of::<T>(),
2062 alignment: mem::align_of::<T>(),
2063 }],
2064 can_contain_null_mask: true,
2065 variadic: false,
2066 }
2067 }
2068
2069 pub fn new_nullable_empty() -> Self {
2072 Self {
2073 buffers: vec![],
2074 can_contain_null_mask: true,
2075 variadic: false,
2076 }
2077 }
2078
2079 pub fn new_empty() -> Self {
2082 Self {
2083 buffers: vec![],
2084 can_contain_null_mask: false,
2085 variadic: false,
2086 }
2087 }
2088
2089 pub fn new_binary<T>() -> Self {
2093 Self {
2094 buffers: vec![
2095 BufferSpec::FixedWidth {
2097 byte_width: mem::size_of::<T>(),
2098 alignment: mem::align_of::<T>(),
2099 },
2100 BufferSpec::VariableWidth,
2102 ],
2103 can_contain_null_mask: true,
2104 variadic: false,
2105 }
2106 }
2107
2108 pub fn new_view() -> Self {
2110 Self {
2111 buffers: vec![BufferSpec::FixedWidth {
2112 byte_width: mem::size_of::<u128>(),
2113 alignment: mem::align_of::<u128>(),
2114 }],
2115 can_contain_null_mask: true,
2116 variadic: true,
2117 }
2118 }
2119
2120 pub fn new_list_view<T>() -> Self {
2122 Self {
2123 buffers: vec![
2124 BufferSpec::FixedWidth {
2125 byte_width: mem::size_of::<T>(),
2126 alignment: mem::align_of::<T>(),
2127 },
2128 BufferSpec::FixedWidth {
2129 byte_width: mem::size_of::<T>(),
2130 alignment: mem::align_of::<T>(),
2131 },
2132 ],
2133 can_contain_null_mask: true,
2134 variadic: false,
2135 }
2136 }
2137}
2138
2139#[derive(Debug, PartialEq, Eq)]
2141pub enum BufferSpec {
2142 FixedWidth {
2153 byte_width: usize,
2155 alignment: usize,
2157 },
2158 VariableWidth,
2160 BitMap,
2166 AlwaysNull,
2169}
2170
2171impl PartialEq for ArrayData {
2172 fn eq(&self, other: &Self) -> bool {
2173 equal::equal(self, other)
2174 }
2175}
2176
2177#[derive(Debug, Clone)]
2196#[doc(hidden)]
2197pub struct UnsafeFlag(bool);
2198
2199impl UnsafeFlag {
2200 #[inline]
2204 pub const fn new() -> Self {
2205 Self(false)
2206 }
2207
2208 #[inline]
2218 pub unsafe fn set(&mut self, val: bool) {
2219 self.0 = val;
2220 }
2221
2222 #[inline]
2224 pub fn get(&self) -> bool {
2225 self.0
2226 }
2227}
2228
2229impl Default for UnsafeFlag {
2231 fn default() -> Self {
2232 Self::new()
2233 }
2234}
2235
2236#[derive(Debug)]
2238pub struct ArrayDataBuilder {
2239 data_type: DataType,
2240 len: usize,
2241 null_count: Option<usize>,
2242 null_bit_buffer: Option<Buffer>,
2243 nulls: Option<NullBuffer>,
2244 offset: usize,
2245 buffers: Vec<Buffer>,
2246 child_data: Vec<ArrayData>,
2247 align_buffers: bool,
2251 skip_validation: UnsafeFlag,
2261}
2262
2263impl ArrayDataBuilder {
2264 #[inline]
2265 pub const fn new(data_type: DataType) -> Self {
2267 Self {
2268 data_type,
2269 len: 0,
2270 null_count: None,
2271 null_bit_buffer: None,
2272 nulls: None,
2273 offset: 0,
2274 buffers: vec![],
2275 child_data: vec![],
2276 align_buffers: false,
2277 skip_validation: UnsafeFlag::new(),
2278 }
2279 }
2280
2281 pub fn data_type(self, data_type: DataType) -> Self {
2283 Self { data_type, ..self }
2284 }
2285
2286 #[inline]
2287 pub const fn len(mut self, n: usize) -> Self {
2289 self.len = n;
2290 self
2291 }
2292
2293 pub fn nulls(mut self, nulls: Option<NullBuffer>) -> Self {
2295 self.nulls = nulls;
2296 self.null_count = None;
2297 self.null_bit_buffer = None;
2298 self
2299 }
2300
2301 pub fn null_count(mut self, null_count: usize) -> Self {
2303 self.null_count = Some(null_count);
2304 self
2305 }
2306
2307 pub fn null_bit_buffer(mut self, buf: Option<Buffer>) -> Self {
2309 self.nulls = None;
2310 self.null_bit_buffer = buf;
2311 self
2312 }
2313
2314 #[inline]
2316 pub const fn offset(mut self, n: usize) -> Self {
2317 self.offset = n;
2318 self
2319 }
2320
2321 pub fn buffers(mut self, v: Vec<Buffer>) -> Self {
2323 self.buffers = v;
2324 self
2325 }
2326
2327 pub fn add_buffer(mut self, b: Buffer) -> Self {
2329 self.buffers.push(b);
2330 self
2331 }
2332
2333 pub fn add_buffers<I: IntoIterator<Item = Buffer>>(mut self, bs: I) -> Self {
2335 self.buffers.extend(bs);
2336 self
2337 }
2338
2339 pub fn child_data(mut self, v: Vec<ArrayData>) -> Self {
2341 self.child_data = v;
2342 self
2343 }
2344
2345 pub fn add_child_data(mut self, r: ArrayData) -> Self {
2347 self.child_data.push(r);
2348 self
2349 }
2350
2351 pub unsafe fn build_unchecked(self) -> ArrayData {
2367 unsafe { self.skip_validation(true) }.build().unwrap()
2368 }
2369
2370 pub fn build(self) -> Result<ArrayData, ArrowError> {
2379 let Self {
2380 data_type,
2381 len,
2382 null_count,
2383 null_bit_buffer,
2384 nulls,
2385 offset,
2386 buffers,
2387 child_data,
2388 align_buffers,
2389 skip_validation,
2390 } = self;
2391
2392 let validate = !skip_validation.get() || cfg!(feature = "force_validate");
2394 if validate && let Some(buffer) = null_bit_buffer.as_ref() {
2395 let len_plus_offset = checked_len_plus_offset(&data_type, len, offset)?;
2397 let needed_len = bit_util::ceil(len_plus_offset, 8);
2398 if buffer.len() < needed_len {
2399 return Err(ArrowError::InvalidArgumentError(format!(
2400 "null_bit_buffer size too small. got {} needed {}",
2401 buffer.len(),
2402 needed_len
2403 )));
2404 }
2405 }
2406
2407 let nulls = nulls
2408 .or_else(|| {
2409 let buffer = null_bit_buffer?;
2410 let buffer = BooleanBuffer::new(buffer, offset, len);
2411 Some(match null_count {
2412 Some(n) => {
2413 unsafe { NullBuffer::new_unchecked(buffer, n) }
2415 }
2416 None => NullBuffer::new(buffer),
2417 })
2418 })
2419 .filter(|b| b.null_count() != 0);
2420
2421 let mut data = ArrayData {
2422 data_type,
2423 len,
2424 offset,
2425 buffers,
2426 child_data,
2427 nulls,
2428 };
2429
2430 if align_buffers {
2431 data.align_buffers();
2432 }
2433
2434 if validate {
2435 data.validate_data()?;
2436 }
2437 Ok(data)
2438 }
2439
2440 pub fn align_buffers(mut self, align_buffers: bool) -> Self {
2456 self.align_buffers = align_buffers;
2457 self
2458 }
2459
2460 pub unsafe fn skip_validation(mut self, skip_validation: bool) -> Self {
2474 unsafe {
2475 self.skip_validation.set(skip_validation);
2476 }
2477 self
2478 }
2479}
2480
2481impl From<ArrayData> for ArrayDataBuilder {
2482 fn from(d: ArrayData) -> Self {
2483 Self {
2484 data_type: d.data_type,
2485 len: d.len,
2486 offset: d.offset,
2487 buffers: d.buffers,
2488 child_data: d.child_data,
2489 nulls: d.nulls,
2490 null_bit_buffer: None,
2491 null_count: None,
2492 align_buffers: false,
2493 skip_validation: UnsafeFlag::new(),
2494 }
2495 }
2496}
2497
2498pub(crate) fn get_fixed_size_binary_width(data_type: &DataType) -> usize {
2503 match data_type {
2504 DataType::FixedSizeBinary(i) => {
2505 if *i < 0 {
2506 panic!("cannot compare FixedSizeBinary({})", *i);
2507 }
2508 *i as usize
2509 }
2510 _ => unreachable!(),
2511 }
2512}
2513
2514#[cfg(test)]
2515mod tests {
2516 use arrow_schema::UnionFields;
2517
2518 use super::*;
2519 use crate::ByteView;
2520 use crate::transform::MutableArrayData;
2521 use arrow_buffer::{OffsetBuffer, ScalarBuffer};
2522 use arrow_schema::{Field, Fields};
2523
2524 fn make_i32_buffer(n: usize) -> Buffer {
2528 Buffer::from_slice_ref(vec![42i32; n])
2529 }
2530
2531 fn make_f32_buffer(n: usize) -> Buffer {
2533 Buffer::from_slice_ref(vec![42f32; n])
2534 }
2535
2536 #[test]
2537 fn test_builder() {
2538 let v = (0..25).collect::<Vec<i32>>();
2540 let b1 = Buffer::from_slice_ref(&v);
2541 let arr_data = ArrayData::builder(DataType::Int32)
2542 .len(20)
2543 .offset(5)
2544 .add_buffer(b1)
2545 .null_bit_buffer(Some(Buffer::from([
2546 0b01011111, 0b10110101, 0b01100011, 0b00011110,
2547 ])))
2548 .build()
2549 .unwrap();
2550
2551 assert_eq!(20, arr_data.len());
2552 assert_eq!(10, arr_data.null_count());
2553 assert_eq!(5, arr_data.offset());
2554 assert_eq!(1, arr_data.buffers().len());
2555 assert_eq!(
2556 Buffer::from_slice_ref(&v).as_slice(),
2557 arr_data.buffers()[0].as_slice()
2558 );
2559 }
2560
2561 #[test]
2562 fn test_builder_with_child_data() {
2563 let child_arr_data = ArrayData::try_new(
2564 DataType::Int32,
2565 5,
2566 None,
2567 0,
2568 vec![Buffer::from_slice_ref([1i32, 2, 3, 4, 5])],
2569 vec![],
2570 )
2571 .unwrap();
2572
2573 let field = Arc::new(Field::new("x", DataType::Int32, true));
2574 let data_type = DataType::Struct(vec![field].into());
2575
2576 let arr_data = ArrayData::builder(data_type)
2577 .len(5)
2578 .offset(0)
2579 .add_child_data(child_arr_data.clone())
2580 .build()
2581 .unwrap();
2582
2583 assert_eq!(5, arr_data.len());
2584 assert_eq!(1, arr_data.child_data().len());
2585 assert_eq!(child_arr_data, arr_data.child_data()[0]);
2586 }
2587
2588 #[test]
2589 fn test_struct_validation_accounts_for_parent_offset() {
2590 let data_type =
2591 DataType::Struct(Fields::from(vec![Field::new("x", DataType::Int32, false)]));
2592 let child = ArrayData::builder(DataType::Int32)
2593 .len(5)
2594 .add_buffer(Buffer::from_slice_ref([0, 1, 2, 3, 4]))
2595 .build()
2596 .unwrap();
2597
2598 let err = ArrayData::builder(data_type)
2600 .len(5)
2601 .offset(1)
2602 .add_child_data(child)
2603 .build()
2604 .unwrap_err()
2605 .to_string();
2606
2607 assert!(err.contains(
2608 "child array #0 for field x has length smaller than expected for struct array (5 < 6)"
2609 ));
2610 }
2611
2612 #[test]
2613 fn test_struct_non_nullable_child_nulls_account_for_parent_offset() {
2614 let build = |parent_nulls| {
2615 let child = ArrayData::builder(DataType::Int32)
2616 .len(5)
2617 .add_buffer(Buffer::from_slice_ref([0, 1, 2, 3, 4]))
2618 .nulls(Some(NullBuffer::new(BooleanBuffer::from(vec![
2619 true, true, false, true, true,
2620 ]))))
2621 .build()
2622 .unwrap();
2623
2624 ArrayData::builder(DataType::Struct(Fields::from(vec![Field::new(
2625 "x",
2626 DataType::Int32,
2627 false,
2628 )])))
2629 .len(4)
2630 .offset(1)
2631 .nulls(Some(NullBuffer::new(BooleanBuffer::from(parent_nulls))))
2632 .add_child_data(child)
2633 .build()
2634 };
2635
2636 assert!(build(vec![true, false, true, true]).is_ok());
2637 assert!(build(vec![true, true, false, true]).is_err());
2638 }
2639
2640 #[test]
2641 fn test_fixed_size_list_non_nullable_child_nulls_account_for_parent_offset() {
2642 for child_offset in [0, 1] {
2643 let child = ArrayData::builder(DataType::Int32)
2644 .len(6)
2645 .offset(child_offset)
2646 .add_buffer(Buffer::from_slice_ref([0i32; 7]))
2647 .nulls(Some(NullBuffer::from(vec![
2648 true, true, false, false, true, true,
2649 ])))
2650 .build()
2651 .unwrap();
2652 let build = |parent_nulls| {
2653 ArrayData::builder(DataType::FixedSizeList(
2654 Arc::new(Field::new("item", DataType::Int32, false)),
2655 2,
2656 ))
2657 .offset(1)
2658 .len(2)
2659 .nulls(Some(NullBuffer::from(parent_nulls)))
2660 .add_child_data(child.clone())
2661 .build()
2662 };
2663
2664 assert!(build(vec![false, true]).is_ok());
2666 assert!(build(vec![true, false]).is_err());
2667 }
2668 }
2669
2670 #[test]
2671 fn test_fixed_size_list_non_nullable_child_nulls_without_parent_nulls() {
2672 let child = ArrayData::builder(DataType::Int32)
2673 .len(6)
2674 .add_buffer(Buffer::from_slice_ref([0i32; 6]))
2675 .nulls(Some(NullBuffer::from(vec![
2676 false, false, true, true, false, false,
2677 ])))
2678 .build()
2679 .unwrap();
2680 let build = |offset, len, size| {
2681 ArrayData::builder(DataType::FixedSizeList(
2682 Arc::new(Field::new("item", DataType::Int32, false)),
2683 size,
2684 ))
2685 .offset(offset)
2686 .len(len)
2687 .add_child_data(child.clone())
2688 .build()
2689 };
2690
2691 assert!(build(1, 1, 2).is_ok());
2693 assert!(build(0, 1, 2).is_err());
2694 assert!(build(2, 1, 2).is_err());
2695 assert!(build(3, 0, 2).is_ok());
2696 assert!(build(1, 2, 0).is_ok());
2697 }
2698
2699 #[test]
2700 fn test_fixed_size_list_validation_accounts_for_parent_offset() {
2701 for nulls in [None, Some(NullBuffer::new_null(4))] {
2702 let child = ArrayData::builder(DataType::Int32)
2703 .len(4)
2704 .add_buffer(Buffer::from_slice_ref([0i32; 4]))
2705 .nulls(nulls)
2706 .build()
2707 .unwrap();
2708 let err = ArrayData::builder(DataType::FixedSizeList(
2709 Arc::new(Field::new("item", DataType::Int32, false)),
2710 2,
2711 ))
2712 .offset(1)
2713 .len(2)
2714 .add_child_data(child)
2715 .build()
2716 .unwrap_err()
2717 .to_string();
2718 assert!(err.contains("Values length 4 is less than"));
2719 }
2720 }
2721
2722 #[test]
2723 fn test_struct_equal_accounts_for_parent_offset() {
2724 let data_type =
2725 DataType::Struct(Fields::from(vec![Field::new("x", DataType::Int32, false)]));
2726
2727 let child1 = ArrayData::builder(DataType::Int32)
2728 .len(5)
2729 .add_buffer(Buffer::from_slice_ref([0, 1, 2, 3, 4]))
2730 .build()
2731 .unwrap();
2732 let child2 = child1.slice(1, 4);
2733
2734 let data1 = ArrayData::builder(data_type.clone())
2736 .len(4)
2737 .offset(1)
2738 .add_child_data(child1)
2739 .build()
2740 .unwrap();
2741 let data2 = ArrayData::builder(data_type)
2742 .len(4)
2743 .add_child_data(child2)
2744 .build()
2745 .unwrap();
2746
2747 assert_eq!(data1, data2);
2748 }
2749
2750 #[test]
2751 fn test_extend_struct_accounts_for_parent_offset() {
2752 let data_type =
2753 DataType::Struct(Fields::from(vec![Field::new("x", DataType::Int32, false)]));
2754 let child = ArrayData::builder(DataType::Int32)
2755 .len(5)
2756 .add_buffer(Buffer::from_slice_ref([0, 1, 2, 3, 4]))
2757 .build()
2758 .unwrap();
2759
2760 let data = ArrayData::builder(data_type)
2761 .len(4)
2762 .offset(1)
2763 .add_child_data(child)
2764 .build()
2765 .unwrap();
2766
2767 let mut mutable = MutableArrayData::new(vec![&data], false, data.len());
2768 mutable.try_extend(0, 0, data.len()).unwrap();
2769 let output = mutable.freeze();
2770
2771 assert_eq!(output.child_data()[0].buffer::<i32>(0), &[1, 2, 3, 4]);
2772 }
2773
2774 #[test]
2775 fn test_extend_fixed_size_list_accounts_for_parent_offset() {
2776 let field = Arc::new(Field::new("item", DataType::Int32, false));
2777 let child = ArrayData::builder(DataType::Int32)
2778 .len(6)
2779 .add_buffer(Buffer::from_slice_ref([0, 1, 2, 3, 4, 5]))
2780 .build()
2781 .unwrap();
2782
2783 let data = ArrayData::builder(DataType::FixedSizeList(field, 2))
2784 .len(2)
2785 .offset(1)
2786 .add_child_data(child)
2787 .build()
2788 .unwrap();
2789
2790 let mut mutable = MutableArrayData::new(vec![&data], false, data.len());
2791 mutable.try_extend(0, 0, data.len()).unwrap();
2792 let output = mutable.freeze();
2793
2794 assert_eq!(output.child_data()[0].buffer::<i32>(0), &[2, 3, 4, 5]);
2795 }
2796
2797 #[test]
2798 fn test_extend_sparse_union_accounts_for_parent_offset() {
2799 let fields = UnionFields::try_new(
2800 [0, 1],
2801 [
2802 Field::new("a", DataType::Int32, false),
2803 Field::new("b", DataType::Int32, false),
2804 ],
2805 )
2806 .unwrap();
2807 let child_a = ArrayData::builder(DataType::Int32)
2808 .len(3)
2809 .add_buffer(Buffer::from_slice_ref([10, 20, 30]))
2810 .build()
2811 .unwrap();
2812 let child_b = ArrayData::builder(DataType::Int32)
2813 .len(3)
2814 .add_buffer(Buffer::from_slice_ref([100, 200, 300]))
2815 .build()
2816 .unwrap();
2817
2818 let data = ArrayData::builder(DataType::Union(fields, UnionMode::Sparse))
2821 .len(2)
2822 .offset(1)
2823 .add_buffer(Buffer::from_slice_ref([0i8, 1, 0]))
2824 .add_child_data(child_a)
2825 .add_child_data(child_b)
2826 .build()
2827 .unwrap();
2828
2829 let mut mutable = MutableArrayData::new(vec![&data], false, data.len());
2830 mutable.try_extend(0, 0, data.len()).unwrap();
2831 let output = mutable.freeze();
2832
2833 assert_eq!(output.buffer::<i8>(0), &[1, 0]);
2834 assert_eq!(output.child_data()[0].buffer::<i32>(0), &[20, 30]);
2835 assert_eq!(output.child_data()[1].buffer::<i32>(0), &[200, 300]);
2836 }
2837
2838 #[test]
2839 fn test_null_count() {
2840 let mut bit_v: [u8; 2] = [0; 2];
2841 bit_util::set_bit(&mut bit_v, 0);
2842 bit_util::set_bit(&mut bit_v, 3);
2843 bit_util::set_bit(&mut bit_v, 10);
2844 let arr_data = ArrayData::builder(DataType::Int32)
2845 .len(16)
2846 .add_buffer(make_i32_buffer(16))
2847 .null_bit_buffer(Some(Buffer::from(bit_v)))
2848 .build()
2849 .unwrap();
2850 assert_eq!(13, arr_data.null_count());
2851
2852 let mut bit_v: [u8; 2] = [0; 2];
2854 bit_util::set_bit(&mut bit_v, 0);
2855 bit_util::set_bit(&mut bit_v, 3);
2856 bit_util::set_bit(&mut bit_v, 10);
2857 let arr_data = ArrayData::builder(DataType::Int32)
2858 .len(12)
2859 .offset(2)
2860 .add_buffer(make_i32_buffer(14)) .null_bit_buffer(Some(Buffer::from(bit_v)))
2862 .build()
2863 .unwrap();
2864 assert_eq!(10, arr_data.null_count());
2865 }
2866
2867 #[test]
2868 fn test_null_buffer_ref() {
2869 let mut bit_v: [u8; 2] = [0; 2];
2870 bit_util::set_bit(&mut bit_v, 0);
2871 bit_util::set_bit(&mut bit_v, 3);
2872 bit_util::set_bit(&mut bit_v, 10);
2873 let arr_data = ArrayData::builder(DataType::Int32)
2874 .len(16)
2875 .add_buffer(make_i32_buffer(16))
2876 .null_bit_buffer(Some(Buffer::from(bit_v)))
2877 .build()
2878 .unwrap();
2879 assert!(arr_data.nulls().is_some());
2880 assert_eq!(&bit_v, arr_data.nulls().unwrap().validity());
2881 }
2882
2883 #[test]
2884 fn test_slice() {
2885 let mut bit_v: [u8; 2] = [0; 2];
2886 bit_util::set_bit(&mut bit_v, 0);
2887 bit_util::set_bit(&mut bit_v, 3);
2888 bit_util::set_bit(&mut bit_v, 10);
2889 let data = ArrayData::builder(DataType::Int32)
2890 .len(16)
2891 .add_buffer(make_i32_buffer(16))
2892 .null_bit_buffer(Some(Buffer::from(bit_v)))
2893 .build()
2894 .unwrap();
2895 let new_data = data.slice(1, 15);
2896 assert_eq!(data.len() - 1, new_data.len());
2897 assert_eq!(1, new_data.offset());
2898 assert_eq!(data.null_count(), new_data.null_count());
2899
2900 let new_data = new_data.slice(1, 14);
2902 assert_eq!(data.len() - 2, new_data.len());
2903 assert_eq!(2, new_data.offset());
2904 assert_eq!(data.null_count() - 1, new_data.null_count());
2905 }
2906
2907 #[test]
2908 #[should_panic(expected = "offset + length overflow")]
2909 fn test_slice_panics_on_offset_length_overflow() {
2910 let data = ArrayData::builder(DataType::Int32)
2911 .len(4)
2912 .add_buffer(make_i32_buffer(4))
2913 .build()
2914 .unwrap();
2915 let sliced = data.slice(1, 3);
2916
2917 sliced.slice(1, usize::MAX);
2918 }
2919
2920 #[test]
2921 fn test_sliced() {
2922 for nulls in [
2923 None,
2924 Some(NullBuffer::from(vec![true, false, true, false, true])),
2925 ] {
2926 let data = ArrayData::builder(DataType::Int32)
2927 .len(5)
2928 .offset(1)
2929 .add_buffer(make_i32_buffer(6))
2930 .nulls(nulls)
2931 .build()
2932 .unwrap();
2933
2934 for offset in 0..=data.len() {
2935 for length in 0..=data.len() - offset {
2936 let owned = data.clone();
2937 let buffers = owned.buffers().as_ptr();
2938 let sliced = owned.sliced(offset, length);
2939 assert_eq!(sliced, data.slice(offset, length));
2940 assert_eq!(sliced.len(), length);
2941 assert_eq!(sliced.offset(), 1 + offset);
2942 assert_eq!(sliced.buffers().as_ptr(), buffers);
2943 assert_eq!(sliced.buffers()[0].as_ptr(), data.buffers()[0].as_ptr());
2944 if let Some(nulls) = data.nulls() {
2945 assert_eq!(
2946 sliced.nulls().unwrap().iter().collect::<Vec<_>>(),
2947 nulls.iter().skip(offset).take(length).collect::<Vec<_>>()
2948 );
2949 }
2950 sliced.validate_full().unwrap();
2951 }
2952 }
2953 }
2954
2955 let empty = ArrayData::new_empty(&DataType::Int32);
2956 assert_eq!(empty.clone().sliced(0, 0), empty);
2957 }
2958
2959 #[test]
2960 fn test_sliced_nested_struct() {
2961 let child = ArrayData::builder(DataType::Int32)
2962 .len(8)
2963 .offset(1)
2964 .add_buffer(make_i32_buffer(9))
2965 .nulls(Some(NullBuffer::from(vec![
2966 true, false, true, false, true, true, false, true,
2967 ])))
2968 .build()
2969 .unwrap();
2970 let inner = ArrayData::builder(DataType::Struct(Fields::from(vec![Field::new(
2971 "x",
2972 DataType::Int32,
2973 true,
2974 )])))
2975 .len(6)
2976 .offset(1)
2977 .nulls(Some(NullBuffer::from(vec![
2978 true, false, true, true, false, true,
2979 ])))
2980 .add_child_data(child)
2981 .build()
2982 .unwrap();
2983 let data = ArrayData::builder(DataType::Struct(Fields::from(vec![Field::new(
2984 "inner",
2985 inner.data_type().clone(),
2986 true,
2987 )])))
2988 .len(4)
2989 .offset(1)
2990 .nulls(Some(NullBuffer::from(vec![false, true, false, true])))
2991 .add_child_data(inner)
2992 .build()
2993 .unwrap();
2994
2995 for (offset, length) in [(0, 4), (1, 2), (4, 0), (0, 0)] {
2996 let owned = data.clone();
2997 let children = owned.child_data().as_ptr();
2998 let grandchildren = owned.child_data()[0].child_data().as_ptr();
2999 let buffers = owned.child_data()[0].child_data()[0].buffers().as_ptr();
3000 let sliced = owned.sliced(offset, length);
3001 let inner = &sliced.child_data()[0];
3002 let child = &inner.child_data()[0];
3003 assert_eq!(sliced, data.slice(offset, length));
3004 assert_eq!(sliced.offset(), 0);
3005 assert_eq!(inner.offset(), 0);
3006 assert_eq!(child.offset(), 3 + offset);
3007 assert_eq!(sliced.child_data().as_ptr(), children);
3008 assert_eq!(inner.child_data().as_ptr(), grandchildren);
3009 assert_eq!(child.buffers().as_ptr(), buffers);
3010 sliced.validate_full().unwrap();
3011 }
3012
3013 let sliced = data.sliced(1, 2).sliced(1, 1);
3014 assert_eq!(sliced.null_count(), 1);
3015 assert_eq!(sliced.child_data()[0].null_count(), 0);
3016 assert_eq!(sliced.child_data()[0].child_data()[0].offset(), 5);
3017 assert_eq!(sliced.child_data()[0].child_data()[0].null_count(), 0);
3018 }
3019
3020 #[test]
3021 fn test_sliced_list_preserves_children() {
3022 let child = ArrayData::builder(DataType::Int32)
3023 .len(6)
3024 .offset(1)
3025 .add_buffer(make_i32_buffer(7))
3026 .nulls(Some(NullBuffer::from(vec![
3027 true, false, true, false, true, true,
3028 ])))
3029 .build()
3030 .unwrap();
3031 let data = ArrayData::builder(DataType::List(Arc::new(Field::new(
3032 "item",
3033 DataType::Int32,
3034 true,
3035 ))))
3036 .len(4)
3037 .offset(1)
3038 .add_buffer(Buffer::from_slice_ref([0i32, 1, 2, 3, 4, 5]))
3039 .nulls(Some(NullBuffer::from(vec![false, true, false, true])))
3040 .add_child_data(child)
3041 .build()
3042 .unwrap();
3043 let buffers = data.buffers().as_ptr();
3044 let children = data.child_data().as_ptr();
3045 let child_buffers = data.child_data()[0].buffers().as_ptr();
3046 let expected = data.slice(1, 2);
3047 let sliced = data.sliced(1, 2);
3048 assert_eq!(sliced, expected);
3049 assert_eq!(sliced.offset(), 2);
3050 assert_eq!(sliced.child_data()[0].len(), 6);
3051 assert_eq!(sliced.child_data()[0].offset(), 1);
3052 assert_eq!(sliced.buffers().as_ptr(), buffers);
3053 assert_eq!(sliced.child_data().as_ptr(), children);
3054 assert_eq!(sliced.child_data()[0].buffers().as_ptr(), child_buffers);
3055 sliced.validate_full().unwrap();
3056 }
3057
3058 #[test]
3059 #[should_panic(expected = "offset + length overflow")]
3060 fn test_sliced_panics_on_offset_length_overflow() {
3061 ArrayData::new_null(&DataType::Int32, 4).sliced(1, usize::MAX);
3062 }
3063
3064 #[test]
3065 #[should_panic(expected = "end <= self.len()")]
3066 fn test_sliced_panics_on_offset_out_of_bounds() {
3067 ArrayData::new_null(&DataType::Int32, 4).sliced(5, 0);
3068 }
3069
3070 #[test]
3071 #[should_panic(expected = "end <= self.len()")]
3072 fn test_sliced_panics_on_length_out_of_bounds() {
3073 ArrayData::new_null(&DataType::Int32, 4).sliced(3, 2);
3074 }
3075
3076 #[test]
3077 fn test_typed_offsets_length_overflow() {
3078 let data = ArrayData {
3079 data_type: DataType::Binary,
3080 len: usize::MAX,
3081 offset: 0,
3082 buffers: vec![Buffer::from_slice_ref([0_i32])],
3083 child_data: vec![],
3084 nulls: None,
3085 };
3086 let err = data.typed_offsets::<i32>().unwrap_err();
3087
3088 assert_eq!(
3089 err.to_string(),
3090 format!(
3091 "Invalid argument error: Length {} with offset 1 overflows usize for Binary",
3092 usize::MAX
3093 )
3094 );
3095 }
3096
3097 #[test]
3098 fn test_validate_typed_buffer_length_overflow() {
3099 let data = ArrayData {
3100 data_type: DataType::Binary,
3101 len: 0,
3102 offset: 2,
3103 buffers: vec![Buffer::from_slice_ref([0_i32])],
3104 child_data: vec![],
3105 nulls: None,
3106 };
3107 let err = data.typed_buffer::<i32>(0, usize::MAX).unwrap_err();
3108
3109 assert_eq!(
3110 err.to_string(),
3111 format!(
3112 "Invalid argument error: Length {} with offset 2 overflows usize for Binary",
3113 usize::MAX
3114 )
3115 );
3116 }
3117
3118 fn try_new_binary_length_offset_overflow() -> Result<ArrayData, ArrowError> {
3120 ArrayData::try_new(
3121 DataType::Binary,
3122 usize::MAX,
3123 None,
3124 1,
3125 vec![
3126 Buffer::from_slice_ref([0_i32]),
3127 Buffer::from_iter(std::iter::empty::<u8>()),
3128 ],
3129 vec![],
3130 )
3131 }
3132
3133 #[cfg(not(feature = "force_validate"))]
3134 #[test]
3135 fn test_try_new_length_offset_overflow() {
3136 let err = try_new_binary_length_offset_overflow().unwrap_err();
3137
3138 assert_eq!(
3139 err.to_string(),
3140 format!(
3141 "Invalid argument error: Length {} with offset 1 overflows usize for Binary",
3142 usize::MAX
3143 )
3144 );
3145 }
3146
3147 #[cfg(feature = "force_validate")]
3148 #[test]
3149 #[should_panic(
3150 expected = "Length 18446744073709551615 with offset 1 overflows usize for Binary"
3151 )]
3152 fn test_try_new_length_offset_overflow_force_validate() {
3153 try_new_binary_length_offset_overflow().unwrap();
3154 }
3155
3156 #[test]
3157 fn test_equality() {
3158 let int_data = ArrayData::builder(DataType::Int32)
3159 .len(1)
3160 .add_buffer(make_i32_buffer(1))
3161 .build()
3162 .unwrap();
3163
3164 let float_data = ArrayData::builder(DataType::Float32)
3165 .len(1)
3166 .add_buffer(make_f32_buffer(1))
3167 .build()
3168 .unwrap();
3169 assert_ne!(int_data, float_data);
3170 assert!(!int_data.ptr_eq(&float_data));
3171 assert!(int_data.ptr_eq(&int_data));
3172
3173 let int_data_clone = int_data.clone();
3174 assert_eq!(int_data, int_data_clone);
3175 assert!(int_data.ptr_eq(&int_data_clone));
3176 assert!(int_data_clone.ptr_eq(&int_data));
3177
3178 let int_data_slice = int_data_clone.slice(1, 0);
3179 assert!(int_data_slice.ptr_eq(&int_data_slice));
3180 assert!(!int_data.ptr_eq(&int_data_slice));
3181 assert!(!int_data_slice.ptr_eq(&int_data));
3182
3183 let data_buffer = Buffer::from_slice_ref(b"abcdef");
3184 let offsets_buffer = Buffer::from_slice_ref([0_i32, 2_i32, 2_i32, 5_i32]);
3185 let string_data = ArrayData::try_new(
3186 DataType::Utf8,
3187 3,
3188 Some(Buffer::from_iter(vec![true, false, true])),
3189 0,
3190 vec![offsets_buffer, data_buffer],
3191 vec![],
3192 )
3193 .unwrap();
3194
3195 assert_ne!(float_data, string_data);
3196 assert!(!float_data.ptr_eq(&string_data));
3197
3198 assert!(string_data.ptr_eq(&string_data));
3199
3200 let string_data_cloned = string_data.clone();
3201 assert!(string_data_cloned.ptr_eq(&string_data));
3202 assert!(string_data.ptr_eq(&string_data_cloned));
3203
3204 let string_data_slice = string_data.slice(1, 2);
3205 assert!(string_data_slice.ptr_eq(&string_data_slice));
3206 assert!(!string_data_slice.ptr_eq(&string_data))
3207 }
3208
3209 #[test]
3210 fn test_slice_memory_size_view_payload_buffers() {
3211 for data_type in [DataType::Utf8View, DataType::BinaryView] {
3212 let inline_only = ArrayData::builder(data_type.clone())
3213 .len(2)
3214 .add_buffer(Buffer::from_vec(vec![0_u128; 2]))
3215 .build()
3216 .unwrap();
3217 assert_eq!(
3218 inline_only.get_slice_memory_size().unwrap(),
3219 2 * mem::size_of::<u128>()
3220 );
3221
3222 let mut first_payload = Vec::with_capacity(32);
3223 first_payload.extend_from_slice(b"first payload");
3224 let first_view =
3225 ByteView::new(first_payload.len().try_into().unwrap(), &first_payload[..4])
3226 .as_u128();
3227 let first_payload = Buffer::from_vec(first_payload);
3228 assert!(first_payload.capacity() > first_payload.len());
3229 let first_payload_capacity = first_payload.capacity();
3230
3231 let mut second_payload = Vec::with_capacity(64);
3232 second_payload.extend_from_slice(b"second payload");
3233 let second_view = ByteView::new(
3234 second_payload.len().try_into().unwrap(),
3235 &second_payload[..4],
3236 )
3237 .with_buffer_index(1)
3238 .as_u128();
3239 let second_payload = Buffer::from_vec(second_payload);
3240 assert!(second_payload.capacity() > second_payload.len());
3241 let second_payload_capacity = second_payload.capacity();
3242
3243 let data = ArrayData::builder(data_type)
3244 .len(3)
3245 .add_buffer(Buffer::from_vec(vec![first_view, 0_u128, second_view]))
3246 .add_buffer(first_payload)
3247 .add_buffer(second_payload)
3248 .build()
3249 .unwrap();
3250 let sliced = data.slice(1, 1);
3251
3252 assert_eq!(
3253 sliced.get_slice_memory_size().unwrap(),
3254 mem::size_of::<u128>() + first_payload_capacity + second_payload_capacity
3255 );
3256 }
3257 }
3258
3259 #[test]
3260 fn test_slice_memory_size_utf8_offset_buffer_len_plus_one() {
3261 let data_buffer = Buffer::from_slice_ref(b"helloworld");
3263 let offsets_buffer = Buffer::from_slice_ref([0_i32, 5_i32, 10_i32]);
3266 let array = ArrayData::try_new(
3267 DataType::Utf8,
3268 2,
3269 None,
3270 0,
3271 vec![offsets_buffer, data_buffer],
3272 vec![],
3273 )
3274 .unwrap();
3275 assert_eq!(array.get_slice_memory_size().unwrap(), 22); }
3277
3278 #[test]
3279 fn test_slice_memory_size_binary_offset_buffer_len_plus_one() {
3280 let data_buffer = Buffer::from_slice_ref([0u8, 1, 2, 3, 4]);
3283 let offsets_buffer = Buffer::from_slice_ref([0_i32, 2_i32, 5_i32]);
3285 let array = ArrayData::try_new(
3286 DataType::Binary,
3287 2,
3288 None,
3289 0,
3290 vec![offsets_buffer, data_buffer],
3291 vec![],
3292 )
3293 .unwrap();
3294 assert_eq!(array.get_slice_memory_size().unwrap(), 17); }
3296
3297 #[test]
3298 fn test_slice_memory_size() {
3299 let mut bit_v: [u8; 2] = [0; 2];
3300 bit_util::set_bit(&mut bit_v, 0);
3301 bit_util::set_bit(&mut bit_v, 3);
3302 bit_util::set_bit(&mut bit_v, 10);
3303 let data = ArrayData::builder(DataType::Int32)
3304 .len(16)
3305 .add_buffer(make_i32_buffer(16))
3306 .null_bit_buffer(Some(Buffer::from(bit_v)))
3307 .build()
3308 .unwrap();
3309 let new_data = data.slice(1, 14);
3310 assert_eq!(
3311 data.get_slice_memory_size().unwrap() - 8,
3312 new_data.get_slice_memory_size().unwrap()
3313 );
3314 let data_buffer = Buffer::from_slice_ref(b"abcdef");
3315 let offsets_buffer = Buffer::from_slice_ref([0_i32, 2_i32, 2_i32, 5_i32]);
3316 let string_data = ArrayData::try_new(
3317 DataType::Utf8,
3318 3,
3319 Some(Buffer::from_iter(vec![true, false, true])),
3320 0,
3321 vec![offsets_buffer, data_buffer],
3322 vec![],
3323 )
3324 .unwrap();
3325 let string_data_slice = string_data.slice(1, 2);
3326 assert_eq!(
3328 string_data.get_slice_memory_size().unwrap() - 6,
3329 string_data_slice.get_slice_memory_size().unwrap()
3330 );
3331 }
3332
3333 #[test]
3334 fn test_builder_rejects_short_null_bit_buffer() {
3335 for (len, offset) in [(8000, 0), (8, 1)] {
3336 let err = ArrayData::builder(DataType::Int32)
3337 .len(len)
3338 .offset(offset)
3339 .add_buffer(make_i32_buffer(len + offset))
3340 .null_bit_buffer(Some(Buffer::from([0_u8])))
3341 .build()
3342 .unwrap_err();
3343 assert_eq!(
3344 err.to_string(),
3345 format!(
3346 "Invalid argument error: null_bit_buffer size too small. got 1 needed {}",
3347 bit_util::ceil(len + offset, 8)
3348 )
3349 );
3350 }
3351 }
3352
3353 #[test]
3354 fn test_builder_null_bit_buffer_length_overflow() {
3355 let err = ArrayData::builder(DataType::Int32)
3356 .len(usize::MAX)
3357 .offset(1)
3358 .null_bit_buffer(Some(Buffer::default()))
3359 .build()
3360 .unwrap_err();
3361 assert_eq!(
3362 err.to_string(),
3363 format!(
3364 "Invalid argument error: Length {} with offset 1 overflows usize for Int32",
3365 usize::MAX
3366 )
3367 );
3368 }
3369
3370 #[test]
3371 fn test_builder_accepts_valid_null_bit_buffer() {
3372 for (len, offset) in [(8, 0), (7, 1)] {
3373 let data = ArrayData::builder(DataType::Int32)
3374 .len(len)
3375 .offset(offset)
3376 .add_buffer(make_i32_buffer(len + offset))
3377 .null_bit_buffer(Some(Buffer::from([0_u8])))
3378 .build()
3379 .unwrap();
3380 assert_eq!(data.len(), len);
3381 assert_eq!(data.offset(), offset);
3382 assert_eq!(data.null_count(), len);
3383 }
3384 }
3385
3386 #[test]
3387 fn test_count_nulls() {
3388 let buffer = Buffer::from([0b00010110, 0b10011111]);
3389 let buffer = NullBuffer::new(BooleanBuffer::new(buffer, 0, 16));
3390 let count = count_nulls(Some(&buffer), 0, 16);
3391 assert_eq!(count, 7);
3392
3393 let count = count_nulls(Some(&buffer), 4, 8);
3394 assert_eq!(count, 3);
3395 }
3396
3397 #[test]
3398 fn test_contains_nulls() {
3399 let buffer: Buffer =
3400 MutableBuffer::from_iter([false, false, false, true, true, false]).into();
3401 let buffer = NullBuffer::new(BooleanBuffer::new(buffer, 0, 6));
3402 assert!(contains_nulls(Some(&buffer), 0, 6));
3403 assert!(contains_nulls(Some(&buffer), 0, 3));
3404 assert!(!contains_nulls(Some(&buffer), 3, 2));
3405 assert!(!contains_nulls(Some(&buffer), 0, 0));
3406 }
3407
3408 #[test]
3409 fn test_alignment() {
3410 let buffer = Buffer::from_vec(vec![1_i32, 2_i32, 3_i32]);
3411 let sliced = buffer.slice(1);
3412
3413 let mut data = ArrayData {
3414 data_type: DataType::Int32,
3415 len: 0,
3416 offset: 0,
3417 buffers: vec![buffer],
3418 child_data: vec![],
3419 nulls: None,
3420 };
3421 data.validate_full().unwrap();
3422
3423 data.buffers[0] = sliced;
3425 let err = data.validate().unwrap_err();
3426
3427 assert_eq!(
3428 err.to_string(),
3429 "Invalid argument error: Misaligned buffers[0] in array of type Int32, offset from expected alignment of 4 by 1"
3430 );
3431
3432 data.align_buffers();
3433 data.validate_full().unwrap();
3434 }
3435
3436 #[test]
3437 fn test_alignment_struct() {
3438 let buffer = Buffer::from_vec(vec![1_i32, 2_i32, 3_i32]);
3439 let sliced = buffer.slice(1);
3440
3441 let child_data = ArrayData {
3442 data_type: DataType::Int32,
3443 len: 0,
3444 offset: 0,
3445 buffers: vec![buffer],
3446 child_data: vec![],
3447 nulls: None,
3448 };
3449
3450 let schema = DataType::Struct(Fields::from(vec![Field::new("a", DataType::Int32, false)]));
3451 let mut data = ArrayData {
3452 data_type: schema,
3453 len: 0,
3454 offset: 0,
3455 buffers: vec![],
3456 child_data: vec![child_data],
3457 nulls: None,
3458 };
3459 data.validate_full().unwrap();
3460
3461 data.child_data[0].buffers[0] = sliced;
3463 let err = data.validate().unwrap_err();
3464
3465 assert_eq!(
3466 err.to_string(),
3467 "Invalid argument error: Misaligned buffers[0] in array of type Int32, offset from expected alignment of 4 by 1"
3468 );
3469
3470 data.align_buffers();
3471 data.validate_full().unwrap();
3472 }
3473
3474 #[test]
3475 fn test_null_view_types() {
3476 let array_len = 32;
3477 let array = ArrayData::new_null(&DataType::BinaryView, array_len);
3478 assert_eq!(array.len(), array_len);
3479 for i in 0..array.len() {
3480 assert!(array.is_null(i));
3481 }
3482
3483 let array = ArrayData::new_null(&DataType::Utf8View, array_len);
3484 assert_eq!(array.len(), array_len);
3485 for i in 0..array.len() {
3486 assert!(array.is_null(i));
3487 }
3488
3489 let array = ArrayData::new_null(
3490 &DataType::ListView(Arc::new(Field::new_list_field(DataType::Int32, true))),
3491 array_len,
3492 );
3493 assert_eq!(array.len(), array_len);
3494 for i in 0..array.len() {
3495 assert!(array.is_null(i));
3496 }
3497
3498 let array = ArrayData::new_null(
3499 &DataType::LargeListView(Arc::new(Field::new_list_field(DataType::Int32, true))),
3500 array_len,
3501 );
3502 assert_eq!(array.len(), array_len);
3503 for i in 0..array.len() {
3504 assert!(array.is_null(i));
3505 }
3506 }
3507
3508 #[test]
3510 fn test_dont_panic_on_bad_input_when_using_try_new() {
3511 let empty_bytes = Buffer::default();
3512
3513 let array_data = ArrayData::try_new(
3514 DataType::Utf8,
3515 1, None,
3517 0,
3518 vec![Buffer::from_vec(vec![0i32, 2i32]), empty_bytes],
3520 vec![],
3521 );
3522
3523 let res = array_data.expect_err("should get error");
3524
3525 assert_eq!(
3526 res.to_string(),
3527 "Invalid argument error: Last offset 2 of Utf8 is larger than values length 0"
3528 );
3529 }
3530
3531 #[test]
3534 #[cfg(not(feature = "force_validate"))]
3535 fn test_validate_values_rejects_a_non_integer_dictionary_key() {
3536 let values = valid_non_nullable_int32_array_data(2);
3537 let data_type = DataType::Dictionary(Box::new(DataType::Utf8), Box::new(DataType::Int32));
3538 let dictionary = unsafe {
3539 ArrayData::builder(data_type)
3540 .len(1)
3541 .add_child_data(values)
3542 .build_unchecked()
3543 };
3544
3545 let err = dictionary.validate_values().expect_err("should get error");
3546 assert_eq!(
3547 err.to_string(),
3548 "Invalid argument error: Dictionary key type must be an integer, got Utf8"
3549 );
3550 }
3551
3552 #[test]
3553 #[cfg(not(feature = "force_validate"))]
3554 fn test_validate_values_rejects_a_non_integer_run_end() {
3555 let data_type = DataType::RunEndEncoded(
3556 Arc::new(Field::new(
3557 Field::REE_RUN_ENDS_FIELD_DEFAULT_NAME,
3558 DataType::Utf8,
3559 false,
3560 )),
3561 Arc::new(Field::new(
3562 Field::REE_VALUES_FIELD_DEFAULT_NAME,
3563 DataType::Int32,
3564 true,
3565 )),
3566 );
3567 let run_end_encoded = unsafe {
3568 ArrayData::builder(data_type)
3569 .len(1)
3570 .add_child_data(valid_non_nullable_int32_array_data(1))
3571 .add_child_data(valid_non_nullable_int32_array_data(1))
3572 .build_unchecked()
3573 };
3574
3575 let err = run_end_encoded
3576 .validate_values()
3577 .expect_err("should get error");
3578 assert_eq!(
3579 err.to_string(),
3580 "Invalid argument error: Run end type must be Int16, Int32 or Int64, got Utf8"
3581 );
3582 }
3583
3584 fn run_array_test_children() -> (DataType, Vec<ArrayData>) {
3587 let dt = DataType::RunEndEncoded(
3588 Arc::new(Field::new(
3589 Field::REE_RUN_ENDS_FIELD_DEFAULT_NAME,
3590 DataType::Int32,
3591 false,
3592 )),
3593 Arc::new(Field::new(
3594 Field::REE_VALUES_FIELD_DEFAULT_NAME,
3595 DataType::Float32,
3596 true,
3597 )),
3598 );
3599
3600 let runs = ArrayData::builder(DataType::Int32)
3601 .len(2)
3602 .add_buffer(vec![1_i32, 3].into())
3603 .build()
3604 .unwrap();
3605 let values = ArrayData::builder(DataType::Float32)
3606 .len(2)
3607 .add_buffer(vec![1.5_f32, 2.5].into())
3608 .build()
3609 .unwrap();
3610
3611 (dt, vec![runs, values])
3612 }
3613
3614 #[test]
3615 fn test_run_array_validates_last_run() {
3616 let (dt, children) = run_array_test_children();
3617
3618 let err = ArrayDataBuilder::new(dt)
3619 .len(4)
3620 .offset(0)
3621 .child_data(children)
3622 .build()
3623 .unwrap_err();
3624 assert_eq!(
3625 err.to_string(),
3626 "Invalid argument error: The offset + length of array should be less or equal to last value in the run_ends array. The last value of run_ends array is 3 and offset + length of array is 4."
3627 );
3628 }
3629
3630 #[test]
3631 fn test_run_array_empty_validates() {
3632 let (dt, children) = run_array_test_children();
3633
3634 let data = ArrayDataBuilder::new(dt)
3635 .len(0)
3636 .offset(4)
3637 .child_data(children)
3638 .build()
3639 .unwrap();
3640 assert_eq!(data.len(), 0);
3641 }
3642
3643 #[test]
3646 fn test_run_array_validates_last_run_with_offset() {
3647 let (dt, children) = run_array_test_children();
3648
3649 let err = ArrayDataBuilder::new(dt)
3650 .len(2)
3651 .offset(2)
3652 .child_data(children)
3653 .build()
3654 .unwrap_err();
3655 assert_eq!(
3656 err.to_string(),
3657 "Invalid argument error: The offset + length of array should be less or equal to last value in the run_ends array. The last value of run_ends array is 3 and offset + length of array is 4."
3658 );
3659 }
3660
3661 #[test]
3664 fn test_run_array_sliced_validates() {
3665 let (dt, children) = run_array_test_children();
3666
3667 let data = ArrayDataBuilder::new(dt)
3668 .len(2)
3669 .offset(1)
3670 .child_data(children)
3671 .build()
3672 .unwrap();
3673 assert_eq!(data.len(), 2);
3674 assert_eq!(data.offset(), 1);
3675 }
3676
3677 #[test]
3679 #[cfg(not(feature = "force_validate"))]
3680 fn test_validate_values_rejects_missing_child_data() {
3681 let int32 = Box::new(DataType::Int32);
3682 let field = || Arc::new(Field::new("f", DataType::Int32, true));
3683 let data_types = [
3684 DataType::Dictionary(int32.clone(), int32.clone()),
3685 DataType::List(field()),
3686 DataType::LargeList(field()),
3687 DataType::RunEndEncoded(field(), field()),
3688 ];
3689
3690 for data_type in data_types {
3691 let data = unsafe {
3692 ArrayData::builder(data_type.clone())
3693 .len(1)
3694 .build_unchecked()
3695 };
3696 let err = data.validate_values().expect_err("should get error");
3697 assert_eq!(
3698 err.to_string(),
3699 format!(
3700 "Invalid argument error: {data_type} should contain at least 1 child data array(s), had 0"
3701 )
3702 );
3703 }
3704 }
3705
3706 #[test]
3708 #[cfg(not(feature = "force_validate"))]
3709 fn test_validate_values_rejects_missing_buffers() {
3710 let cases = [
3712 (DataType::Utf8, 1),
3713 (DataType::LargeUtf8, 1),
3714 (DataType::Binary, 1),
3715 (DataType::LargeBinary, 1),
3716 (DataType::BinaryView, 0),
3717 (DataType::Utf8View, 0),
3718 ];
3719
3720 for (data_type, missing) in cases {
3721 let data = unsafe {
3722 ArrayData::builder(data_type.clone())
3723 .len(1)
3724 .build_unchecked()
3725 };
3726 let err = data.validate_values().expect_err("should get error");
3727 assert_eq!(
3728 err.to_string(),
3729 format!(
3730 "Invalid argument error: {data_type} should contain at least {} buffer(s), had 0",
3731 missing + 1
3732 )
3733 );
3734 }
3735 }
3736
3737 #[test]
3739 #[cfg(not(feature = "force_validate"))]
3740 fn test_validate_values_rejects_a_short_dictionary_keys_buffer() {
3741 let data_type = DataType::Dictionary(Box::new(DataType::Int32), Box::new(DataType::Int32));
3742 let dictionary = unsafe {
3743 ArrayData::builder(data_type)
3744 .len(4)
3745 .add_buffer(Buffer::from_slice_ref([1_i32, 0]))
3746 .add_child_data(valid_non_nullable_int32_array_data(2))
3747 .build_unchecked()
3748 };
3749
3750 let err = dictionary.validate_values().expect_err("should get error");
3751 assert_eq!(
3752 err.to_string(),
3753 "Invalid argument error: Buffer 0 of Dictionary(Int32, Int32) isn't large enough. Expected 16 bytes got 8"
3754 );
3755 }
3756
3757 #[test]
3758 fn should_fail_validation_when_having_map_field_type_is_not_struct() {
3759 let map_field = Field::new("key", DataType::Int32, false);
3760
3761 let map_field_data = valid_non_nullable_int32_array_data(2);
3762
3763 let results = test_both_builder_and_array_data(
3764 DataType::Map(map_field.into(), false),
3765 1,
3766 None,
3767 0,
3768 vec![
3769 OffsetBuffer::<i32>::from_lengths(vec![2])
3770 .into_inner()
3771 .into(),
3772 ],
3773 vec![map_field_data],
3774 );
3775
3776 for result in results {
3777 let array_data_err = result.expect_err("should fail for non struct field");
3778
3779 match array_data_err {
3780 ArrowError::InvalidArgumentError(msg) => {
3781 assert_eq!(
3782 msg,
3783 "Map field should be a entries struct data type, got Int32 instead"
3784 )
3785 }
3786 _ => panic!("unexpected error type {array_data_err}"),
3787 }
3788 }
3789 }
3790
3791 #[test]
3792 fn should_fail_validation_when_having_map_entries_only_have_1_field() {
3793 let struct_data_type = DataType::Struct(Fields::from(vec![Field::new(
3794 Field::MAP_KEY_FIELD_DEFAULT_NAME,
3795 DataType::Int32,
3796 false,
3797 )]));
3798
3799 let key_array_data = valid_non_nullable_int32_array_data(2);
3800
3801 let struct_data = {
3802 let builder = ArrayDataBuilder::new(struct_data_type.clone())
3803 .len(2)
3804 .nulls(None)
3805 .child_data(vec![key_array_data]);
3806
3807 builder.build().unwrap()
3808 };
3809
3810 let results = test_both_builder_and_array_data(
3811 DataType::Map(
3812 Field::new(
3813 Field::MAP_ENTRIES_FIELD_DEFAULT_NAME,
3814 struct_data_type,
3815 false,
3816 )
3817 .into(),
3818 false,
3819 ),
3820 1,
3821 None,
3822 0,
3823 vec![
3824 OffsetBuffer::<i32>::from_lengths(vec![2])
3825 .into_inner()
3826 .into(),
3827 ],
3828 vec![struct_data],
3829 );
3830
3831 for result in results {
3832 let array_data_err = result.expect_err("should fail for nullable key");
3833
3834 match array_data_err {
3835 ArrowError::InvalidArgumentError(msg) => {
3836 assert_eq!(
3837 msg,
3838 "Map entries data type should be a struct containing 2 fields, got 1 fields"
3839 )
3840 }
3841 _ => panic!("unexpected error type {array_data_err}"),
3842 }
3843 }
3844 }
3845
3846 #[test]
3847 fn should_fail_validation_when_having_map_entries_have_3_fields() {
3848 let struct_data_type = DataType::Struct(Fields::from(vec![
3849 Field::new(Field::MAP_KEY_FIELD_DEFAULT_NAME, DataType::Int32, false),
3850 Field::new(Field::MAP_VALUE_FIELD_DEFAULT_NAME, DataType::Utf8, true),
3851 Field::new("other", DataType::Int32, true),
3852 ]));
3853
3854 let key_array_data = valid_non_nullable_int32_array_data(2);
3855
3856 let values_array_data = valid_string_array_data(2);
3857
3858 let other_array_data = key_array_data.clone();
3859
3860 let struct_data = {
3861 let builder = ArrayDataBuilder::new(struct_data_type.clone())
3862 .len(2)
3863 .nulls(None)
3864 .child_data(vec![key_array_data, values_array_data, other_array_data]);
3865
3866 builder.build().unwrap()
3867 };
3868
3869 let results = test_both_builder_and_array_data(
3870 DataType::Map(
3871 Field::new(
3872 Field::MAP_ENTRIES_FIELD_DEFAULT_NAME,
3873 struct_data_type,
3874 false,
3875 )
3876 .into(),
3877 false,
3878 ),
3879 1,
3880 None,
3881 0,
3882 vec![
3883 OffsetBuffer::<i32>::from_lengths(vec![2])
3884 .into_inner()
3885 .into(),
3886 ],
3887 vec![struct_data],
3888 );
3889
3890 for result in results {
3891 let array_data_err = result.expect_err("should fail for nullable key");
3892
3893 match array_data_err {
3894 ArrowError::InvalidArgumentError(msg) => {
3895 assert_eq!(
3896 msg,
3897 "Map entries data type should be a struct containing 2 fields, got 3 fields"
3898 )
3899 }
3900 _ => panic!("unexpected error type {array_data_err}"),
3901 }
3902 }
3903 }
3904
3905 #[test]
3906 fn should_fail_validation_when_having_nullable_map_keys() {
3907 let struct_data_type = DataType::Struct(Fields::from(vec![
3908 Field::new(Field::MAP_KEY_FIELD_DEFAULT_NAME, DataType::Int32, true),
3909 Field::new(Field::MAP_VALUE_FIELD_DEFAULT_NAME, DataType::Utf8, true),
3910 ]));
3911
3912 let key_array_data = valid_non_nullable_int32_array_data(2);
3913 let values_array_data = valid_string_array_data(2);
3914
3915 let struct_data = {
3916 let builder = ArrayDataBuilder::new(struct_data_type.clone())
3917 .len(2)
3918 .nulls(None)
3919 .child_data(vec![key_array_data, values_array_data]);
3920
3921 builder.build().unwrap()
3922 };
3923
3924 let results = test_both_builder_and_array_data(
3925 DataType::Map(
3926 Field::new(
3927 Field::MAP_ENTRIES_FIELD_DEFAULT_NAME,
3928 struct_data_type,
3929 false,
3930 )
3931 .into(),
3932 false,
3933 ),
3934 1,
3935 None,
3936 0,
3937 vec![
3938 OffsetBuffer::<i32>::from_lengths(vec![2])
3939 .into_inner()
3940 .into(),
3941 ],
3942 vec![struct_data],
3943 );
3944
3945 for result in results {
3946 let array_data_err = result.expect_err("should fail for nullable key");
3947
3948 match array_data_err {
3949 ArrowError::InvalidArgumentError(msg) => {
3950 assert_eq!(msg, "Map key field must not be nullable")
3951 }
3952 _ => panic!("unexpected error type {array_data_err}"),
3953 }
3954 }
3955 }
3956
3957 #[test]
3958 fn should_fail_validation_when_having_entries_is_nullable_for_map() {
3959 let struct_data_type = DataType::Struct(Fields::from(vec![
3960 Field::new(Field::MAP_KEY_FIELD_DEFAULT_NAME, DataType::Int32, false),
3961 Field::new(Field::MAP_VALUE_FIELD_DEFAULT_NAME, DataType::Utf8, true),
3962 ]));
3963
3964 let key_array_data = valid_non_nullable_int32_array_data(2);
3965
3966 let values_array_data = valid_string_array_data(2);
3967
3968 let struct_data = {
3969 let builder = ArrayDataBuilder::new(struct_data_type.clone())
3970 .len(2)
3971 .nulls(None)
3972 .child_data(vec![key_array_data, values_array_data]);
3973
3974 builder.build().unwrap()
3975 };
3976
3977 let results = test_both_builder_and_array_data(
3978 DataType::Map(
3979 Field::new(
3980 Field::MAP_ENTRIES_FIELD_DEFAULT_NAME,
3981 struct_data_type,
3982 true,
3983 )
3984 .into(),
3985 false,
3986 ),
3987 1,
3988 None,
3989 0,
3990 vec![
3991 OffsetBuffer::<i32>::from_lengths(vec![2])
3992 .into_inner()
3993 .into(),
3994 ],
3995 vec![struct_data],
3996 );
3997
3998 for result in results {
3999 let array_data_err = result.expect_err("should fail for nullable entries");
4000
4001 match array_data_err {
4002 ArrowError::InvalidArgumentError(msg) => assert_eq!(
4003 msg,
4004 "The nullable should be set to false for the map entries field."
4005 ),
4006 _ => panic!("unexpected error type {array_data_err}"),
4007 }
4008 }
4009 }
4010
4011 #[test]
4012 fn should_allow_to_create_map_from_data() {
4013 let struct_data_type = DataType::Struct(Fields::from(vec![
4014 Field::new(Field::MAP_KEY_FIELD_DEFAULT_NAME, DataType::Int32, false),
4015 Field::new(Field::MAP_VALUE_FIELD_DEFAULT_NAME, DataType::Utf8, true),
4016 ]));
4017
4018 let key_array_data = valid_non_nullable_int32_array_data(2);
4019 let values_array_data = valid_string_array_data(2);
4020
4021 let struct_data = {
4022 let builder = ArrayDataBuilder::new(struct_data_type.clone())
4023 .len(2)
4024 .nulls(None)
4025 .child_data(vec![key_array_data, values_array_data]);
4026
4027 builder.build().unwrap()
4028 };
4029
4030 let results = test_both_builder_and_array_data(
4031 DataType::Map(
4032 Field::new(
4033 Field::MAP_ENTRIES_FIELD_DEFAULT_NAME,
4034 struct_data_type,
4035 false,
4036 )
4037 .into(),
4038 false,
4039 ),
4040 1,
4041 None,
4042 0,
4043 vec![
4044 OffsetBuffer::<i32>::from_lengths(vec![2])
4045 .into_inner()
4046 .into(),
4047 ],
4048 vec![struct_data],
4049 );
4050
4051 for result in results {
4052 result.expect("should be able to create map ArrayData");
4053 }
4054 }
4055
4056 fn valid_string_array_data(length: usize) -> ArrayData {
4057 let offsets = OffsetBuffer::<i32>::from_lengths(vec![0; length])
4058 .into_inner()
4059 .into_inner();
4060 let empty_bytes = Buffer::default();
4061
4062 let builder = ArrayDataBuilder::new(DataType::Utf8)
4063 .len(length)
4064 .buffers(vec![offsets, empty_bytes])
4065 .nulls(None);
4066
4067 builder.build().unwrap()
4068 }
4069
4070 fn valid_non_nullable_int32_array_data(length: usize) -> ArrayData {
4071 let builder = ArrayDataBuilder::new(DataType::Int32)
4072 .len(length)
4073 .nulls(None)
4074 .buffers(vec![
4075 ScalarBuffer::<i32>::from(vec![1; length]).into_inner(),
4076 ]);
4077
4078 builder.build().unwrap()
4079 }
4080
4081 #[test]
4082 fn empty_and_null_map_array_should_pass_validation() {
4083 let dt = DataType::Map(
4084 Field::new(
4085 Field::MAP_ENTRIES_FIELD_DEFAULT_NAME,
4086 DataType::Struct(Fields::from(vec![
4087 Field::new(Field::MAP_KEY_FIELD_DEFAULT_NAME, DataType::Int32, false),
4088 Field::new(Field::MAP_VALUE_FIELD_DEFAULT_NAME, DataType::Utf8, true),
4089 ])),
4090 false,
4091 )
4092 .into(),
4093 false,
4094 );
4095
4096 ArrayData::new_empty(&dt).validate_full().unwrap();
4097 ArrayData::new_null(&dt, 1).validate_full().unwrap();
4098 }
4099
4100 #[test]
4101 fn null_buffer_offset_is_independent_of_data_offset() {
4102 let int_data = ArrayData::builder(DataType::UInt32)
4104 .offset(50)
4105 .len(50)
4106 .add_buffer(Buffer::from_vec(vec![0_u32; 100]))
4107 .build()
4108 .unwrap();
4109 int_data.validate().unwrap();
4110
4111 let nulls = NullBuffer::new(BooleanBuffer::from(vec![false; 100]).slice(0, 50));
4113 let with_sliced_nulls = int_data
4114 .clone()
4115 .into_builder()
4116 .nulls(Some(nulls))
4117 .build()
4118 .unwrap();
4119 with_sliced_nulls.validate().unwrap();
4120
4121 let nulls = NullBuffer::new(BooleanBuffer::from(vec![false; 50]));
4124 let with_unsliced_nulls = int_data.into_builder().nulls(Some(nulls)).build().unwrap();
4125 with_unsliced_nulls.validate().unwrap();
4126 assert_eq!(with_unsliced_nulls.null_count(), 50);
4127 }
4128
4129 fn test_both_builder_and_array_data(
4130 data_type: DataType,
4131 len: usize,
4132 null_bit_buffer: Option<Buffer>,
4133 offset: usize,
4134 buffers: Vec<Buffer>,
4135 child_data: Vec<ArrayData>,
4136 ) -> [Result<ArrayData, ArrowError>; 2] {
4137 let from_builder_res = ArrayData::builder(data_type.clone())
4138 .len(len)
4139 .add_buffers(buffers.clone())
4140 .null_bit_buffer(null_bit_buffer.clone())
4141 .offset(offset)
4142 .child_data(child_data.clone())
4143 .build();
4144
4145 let from_try_new_res =
4146 ArrayData::try_new(data_type, len, null_bit_buffer, offset, buffers, child_data);
4147
4148 [from_builder_res, from_try_new_res]
4149 }
4150
4151 #[test]
4152 fn test_new_null_empty_union() {
4153 for mode in [UnionMode::Sparse, UnionMode::Dense] {
4154 let data_type = DataType::Union(UnionFields::empty(), mode);
4155 let data = ArrayData::new_null(&data_type, 0);
4156 data.validate_full()
4157 .expect("an empty union of length zero is valid");
4158 assert_eq!(data.len(), 0);
4159 assert!(data.child_data().is_empty());
4160 }
4161 }
4162
4163 #[test]
4164 #[should_panic(expected = "cannot construct null data from an empty union")]
4165 fn test_new_null_empty_union_with_slots() {
4166 let data_type = DataType::Union(UnionFields::empty(), UnionMode::Dense);
4167 let _ = ArrayData::new_null(&data_type, 1);
4168 }
4169
4170 #[test]
4171 fn test_union_validate_type_ids() {
4172 let dt = DataType::Union(
4173 UnionFields::try_new(
4174 vec![5],
4175 vec![Arc::new(Field::new("a", DataType::Int32, true))],
4176 )
4177 .unwrap(),
4178 UnionMode::Sparse,
4179 );
4180
4181 let child = ArrayData::builder(DataType::Int32)
4182 .len(2)
4183 .add_buffer(make_i32_buffer(2))
4184 .build()
4185 .unwrap();
4186
4187 let err = ArrayDataBuilder::new(dt)
4188 .len(2)
4189 .offset(0)
4190 .buffers(vec![vec![5_i8, 2].into()])
4191 .child_data(vec![child])
4192 .build()
4193 .unwrap_err();
4194 assert_eq!(
4195 err.to_string(),
4196 "Invalid argument error: Type id values must match one of the field type ids, got 2 at index 1"
4197 );
4198 }
4199
4200 #[test]
4201 fn test_union_validate_dense_offsets() {
4202 let dt = DataType::Union(
4203 UnionFields::try_new(
4204 vec![5],
4205 vec![Arc::new(Field::new("a", DataType::Int32, true))],
4206 )
4207 .unwrap(),
4208 UnionMode::Dense,
4209 );
4210
4211 let child = ArrayData::builder(DataType::Int32)
4212 .len(2)
4213 .add_buffer(make_i32_buffer(2))
4214 .build()
4215 .unwrap();
4216
4217 let err = ArrayDataBuilder::new(dt.clone())
4218 .len(2)
4219 .buffers(vec![vec![5_i8, 5].into(), vec![0_i32, 10].into()])
4221 .child_data(vec![child.clone()])
4222 .build()
4223 .unwrap_err();
4224 assert_eq!(
4225 err.to_string(),
4226 "Invalid argument error: Offsets must be non-negative and within the length of the child array"
4227 );
4228
4229 let err = ArrayDataBuilder::new(dt)
4230 .len(2)
4231 .buffers(vec![vec![5_i8, 5].into(), vec![0_i32, -1].into()])
4233 .child_data(vec![child])
4234 .build()
4235 .unwrap_err();
4236 assert_eq!(
4237 err.to_string(),
4238 "Invalid argument error: Offsets must be non-negative and within the length of the child array"
4239 );
4240 }
4241}