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
275impl ArrayData {
276 pub unsafe fn new_unchecked(
293 data_type: DataType,
294 len: usize,
295 null_count: Option<usize>,
296 null_bit_buffer: Option<Buffer>,
297 offset: usize,
298 buffers: Vec<Buffer>,
299 child_data: Vec<ArrayData>,
300 ) -> Self {
301 let builder = Self::inner_new_builder(
302 data_type,
303 len,
304 null_count,
305 null_bit_buffer,
306 offset,
307 buffers,
308 child_data,
309 );
310
311 unsafe { builder.build_unchecked() }
313 }
314
315 pub fn try_new(
329 data_type: DataType,
330 len: usize,
331 null_bit_buffer: Option<Buffer>,
332 offset: usize,
333 buffers: Vec<Buffer>,
334 child_data: Vec<ArrayData>,
335 ) -> Result<Self, ArrowError> {
336 if let Some(null_bit_buffer) = null_bit_buffer.as_ref() {
340 let len_plus_offset = checked_len_plus_offset(&data_type, len, offset)?;
341 let needed_len = bit_util::ceil(len_plus_offset, 8);
342 if null_bit_buffer.len() < needed_len {
343 return Err(ArrowError::InvalidArgumentError(format!(
344 "null_bit_buffer size too small. got {} needed {}",
345 null_bit_buffer.len(),
346 needed_len
347 )));
348 }
349 }
350
351 let builder = Self::inner_new_builder(
352 data_type,
353 len,
354 None,
355 null_bit_buffer,
356 offset,
357 buffers,
358 child_data,
359 );
360
361 assert!(!builder.skip_validation.get());
362
363 builder.build()
368 }
369
370 fn inner_new_builder(
371 data_type: DataType,
372 len: usize,
373 null_count: Option<usize>,
374 null_bit_buffer: Option<Buffer>,
375 offset: usize,
376 buffers: Vec<Buffer>,
377 child_data: Vec<ArrayData>,
378 ) -> ArrayDataBuilder {
379 ArrayDataBuilder {
380 data_type,
381 len,
382 null_count,
383 null_bit_buffer,
384 nulls: None,
385 offset,
386 buffers,
387 child_data,
388 align_buffers: false,
389 skip_validation: UnsafeFlag::new(),
390 }
391 }
392
393 pub fn into_parts(
399 self,
400 ) -> (
401 DataType,
402 usize,
403 Option<NullBuffer>,
404 usize,
405 Vec<Buffer>,
406 Vec<ArrayData>,
407 ) {
408 let Self {
409 data_type,
410 len,
411 nulls,
412 offset,
413 buffers,
414 child_data,
415 } = self;
416
417 (data_type, len, nulls, offset, buffers, child_data)
418 }
419
420 #[inline]
422 pub const fn builder(data_type: DataType) -> ArrayDataBuilder {
423 ArrayDataBuilder::new(data_type)
424 }
425
426 #[inline]
428 pub const fn data_type(&self) -> &DataType {
429 &self.data_type
430 }
431
432 pub fn buffers(&self) -> &[Buffer] {
434 &self.buffers
435 }
436
437 pub fn child_data(&self) -> &[ArrayData] {
445 &self.child_data[..]
446 }
447
448 #[inline]
450 pub fn is_null(&self, i: usize) -> bool {
451 match &self.nulls {
452 Some(v) => v.is_null(i),
453 None => false,
454 }
455 }
456
457 #[inline]
461 pub fn nulls(&self) -> Option<&NullBuffer> {
462 self.nulls.as_ref()
463 }
464
465 #[inline]
467 pub fn is_valid(&self, i: usize) -> bool {
468 !self.is_null(i)
469 }
470
471 #[inline]
473 pub const fn len(&self) -> usize {
474 self.len
475 }
476
477 #[inline]
479 pub const fn is_empty(&self) -> bool {
480 self.len == 0
481 }
482
483 #[inline]
535 pub const fn offset(&self) -> usize {
536 self.offset
537 }
538
539 #[inline]
541 pub fn null_count(&self) -> usize {
542 self.nulls
543 .as_ref()
544 .map(|x| x.null_count())
545 .unwrap_or_default()
546 }
547
548 pub fn get_buffer_memory_size(&self) -> usize {
560 let mut size = 0;
561 for buffer in &self.buffers {
562 size += buffer.capacity();
563 }
564 if let Some(bitmap) = &self.nulls {
565 size += bitmap.buffer().capacity()
566 }
567 for child in &self.child_data {
568 size += child.get_buffer_memory_size();
569 }
570 size
571 }
572
573 pub fn get_slice_memory_size(&self) -> Result<usize, ArrowError> {
588 let mut result: usize = 0;
589 let layout = layout(&self.data_type);
590
591 for spec in &layout.buffers {
592 match spec {
593 BufferSpec::FixedWidth { byte_width, .. } => {
594 let len = match self.data_type {
597 DataType::Utf8
598 | DataType::LargeUtf8
599 | DataType::Binary
600 | DataType::LargeBinary
601 | DataType::List(_)
602 | DataType::LargeList(_)
603 | DataType::Map(_, _) => self.len + 1,
604 _ => self.len,
605 };
606 let buffer_size = len.checked_mul(*byte_width).ok_or_else(|| {
607 ArrowError::ComputeError(
608 "Integer overflow computing buffer size".to_string(),
609 )
610 })?;
611 result += buffer_size;
612 }
613 BufferSpec::VariableWidth => {
614 let buffer_len = match self.data_type {
615 DataType::Utf8 | DataType::Binary => {
616 let offsets = self.typed_offsets::<i32>()?;
617 (offsets[self.len] - offsets[0]) as usize
618 }
619 DataType::LargeUtf8 | DataType::LargeBinary => {
620 let offsets = self.typed_offsets::<i64>()?;
621 (offsets[self.len] - offsets[0]) as usize
622 }
623 _ => {
624 return Err(ArrowError::NotYetImplemented(format!(
625 "Invalid data type for VariableWidth buffer. Expected Utf8, LargeUtf8, Binary or LargeBinary. Got {}",
626 self.data_type
627 )));
628 }
629 };
630 result += buffer_len;
631 }
632 BufferSpec::BitMap => {
633 let buffer_size = bit_util::ceil(self.len, 8);
634 result += buffer_size;
635 }
636 BufferSpec::AlwaysNull => {
637 }
639 }
640 }
641
642 if layout.variadic {
643 for buffer in self.buffers.iter().skip(layout.buffers.len()) {
645 result += buffer.capacity();
646 }
647 }
648
649 if self.nulls().is_some() {
650 result += bit_util::ceil(self.len, 8);
651 }
652
653 for child in &self.child_data {
654 result += child.get_slice_memory_size()?;
655 }
656 Ok(result)
657 }
658
659 pub fn get_array_memory_size(&self) -> usize {
668 let mut size = mem::size_of_val(self);
669
670 for buffer in &self.buffers {
672 size += mem::size_of::<Buffer>();
673 size += buffer.capacity();
674 }
675 if let Some(nulls) = &self.nulls {
676 size += nulls.buffer().capacity();
677 }
678 for child in &self.child_data {
679 size += child.get_array_memory_size();
680 }
681
682 size
683 }
684
685 pub fn slice(&self, offset: usize, length: usize) -> ArrayData {
693 let end = offset
694 .checked_add(length)
695 .expect("offset + length overflow");
696 assert!(end <= self.len());
697
698 if let DataType::Struct(_) = self.data_type() {
699 let child_offset = self.offset + offset;
704 ArrayData {
705 data_type: self.data_type().clone(),
706 len: length,
707 offset: 0,
708 buffers: self.buffers.clone(),
709 child_data: self
710 .child_data()
711 .iter()
712 .map(|data| data.slice(child_offset, length))
713 .collect(),
714 nulls: self.nulls.as_ref().map(|x| x.slice(offset, length)),
717 }
718 } else {
719 let mut new_data = self.clone();
720
721 new_data.len = length;
722 new_data.offset = offset + self.offset;
723 new_data.nulls = self.nulls.as_ref().map(|x| x.slice(offset, length));
724
725 new_data
726 }
727 }
728
729 pub fn buffer<T: ArrowNativeType>(&self, buffer: usize) -> &[T] {
736 &self.buffers()[buffer].typed_data()[self.offset..]
737 }
738
739 pub fn new_null(data_type: &DataType, len: usize) -> Self {
745 let bit_len = bit_util::ceil(len, 8);
746 let zeroed = |len: usize| Buffer::from(MutableBuffer::from_len_zeroed(len));
747
748 let (buffers, child_data, has_nulls) = match data_type.primitive_width() {
749 Some(width) => (vec![zeroed(width * len)], vec![], true),
750 None => match data_type {
751 DataType::Null => (vec![], vec![], false),
752 DataType::Boolean => (vec![zeroed(bit_len)], vec![], true),
753 DataType::Binary | DataType::Utf8 => {
754 (vec![zeroed((len + 1) * 4), zeroed(0)], vec![], true)
755 }
756 DataType::BinaryView | DataType::Utf8View => (vec![zeroed(len * 16)], vec![], true),
757 DataType::LargeBinary | DataType::LargeUtf8 => {
758 (vec![zeroed((len + 1) * 8), zeroed(0)], vec![], true)
759 }
760 DataType::FixedSizeBinary(i) => {
761 if *i < 0 {
762 panic!("cannot construct null data from FixedSizeBinary({i})");
763 }
764 (vec![zeroed(*i as usize * len)], vec![], true)
765 }
766 DataType::List(f) | DataType::Map(f, _) => (
767 vec![zeroed((len + 1) * 4)],
768 vec![ArrayData::new_empty(f.data_type())],
769 true,
770 ),
771 DataType::LargeList(f) => (
772 vec![zeroed((len + 1) * 8)],
773 vec![ArrayData::new_empty(f.data_type())],
774 true,
775 ),
776 DataType::ListView(f) => (
777 vec![zeroed(len * 4), zeroed(len * 4)],
778 vec![ArrayData::new_empty(f.data_type())],
779 true,
780 ),
781 DataType::LargeListView(f) => (
782 vec![zeroed(len * 8), zeroed(len * 8)],
783 vec![ArrayData::new_empty(f.data_type())],
784 true,
785 ),
786 DataType::FixedSizeList(f, list_len) => (
787 vec![],
788 vec![ArrayData::new_null(f.data_type(), *list_len as usize * len)],
789 true,
790 ),
791 DataType::Struct(fields) => (
792 vec![],
793 fields
794 .iter()
795 .map(|f| Self::new_null(f.data_type(), len))
796 .collect(),
797 true,
798 ),
799 DataType::Dictionary(k, v) => (
800 vec![zeroed(k.primitive_width().unwrap() * len)],
801 vec![ArrayData::new_empty(v.as_ref())],
802 true,
803 ),
804 DataType::Union(f, mode) => {
805 let (id, _) = f.iter().next().unwrap();
806 let ids = Buffer::from_iter(std::iter::repeat_n(id, len));
807 let buffers = match mode {
808 UnionMode::Sparse => vec![ids],
809 UnionMode::Dense => {
810 let end_offset = i32::from_usize(len).unwrap();
811 vec![ids, Buffer::from_iter(0_i32..end_offset)]
812 }
813 };
814
815 let children = f
816 .iter()
817 .enumerate()
818 .map(|(idx, (_, f))| {
819 if idx == 0 || *mode == UnionMode::Sparse {
820 Self::new_null(f.data_type(), len)
821 } else {
822 Self::new_empty(f.data_type())
823 }
824 })
825 .collect();
826
827 (buffers, children, false)
828 }
829 DataType::RunEndEncoded(r, v) => {
830 if len == 0 {
831 let runs = ArrayData::new_empty(r.data_type());
833 let values = ArrayData::new_empty(v.data_type());
834 (vec![], vec![runs, values], false)
835 } else {
836 let runs = match r.data_type() {
837 DataType::Int16 => {
838 let i = i16::from_usize(len).expect("run overflow");
839 Buffer::from_slice_ref([i])
840 }
841 DataType::Int32 => {
842 let i = i32::from_usize(len).expect("run overflow");
843 Buffer::from_slice_ref([i])
844 }
845 DataType::Int64 => {
846 let i = i64::from_usize(len).expect("run overflow");
847 Buffer::from_slice_ref([i])
848 }
849 dt => unreachable!("Invalid run ends data type {dt}"),
850 };
851
852 let builder = ArrayData::builder(r.data_type().clone())
853 .len(1)
854 .buffers(vec![runs]);
855
856 let runs = unsafe { builder.build_unchecked() };
859 (
860 vec![],
861 vec![runs, ArrayData::new_null(v.data_type(), 1)],
862 false,
863 )
864 }
865 }
866 DataType::Int8
868 | DataType::Int16
869 | DataType::Int32
870 | DataType::Int64
871 | DataType::UInt8
872 | DataType::UInt16
873 | DataType::UInt32
874 | DataType::UInt64
875 | DataType::Float16
876 | DataType::Float32
877 | DataType::Float64
878 | DataType::Timestamp(_, _)
879 | DataType::Date32
880 | DataType::Date64
881 | DataType::Time32(_)
882 | DataType::Time64(_)
883 | DataType::Duration(_)
884 | DataType::Interval(_)
885 | DataType::Decimal32(_, _)
886 | DataType::Decimal64(_, _)
887 | DataType::Decimal128(_, _)
888 | DataType::Decimal256(_, _) => unreachable!("{data_type}"),
889 },
890 };
891
892 let mut builder = ArrayDataBuilder::new(data_type.clone())
893 .len(len)
894 .buffers(buffers)
895 .child_data(child_data);
896
897 if has_nulls {
898 builder = builder.nulls(Some(NullBuffer::new_null(len)))
899 }
900
901 unsafe { builder.build_unchecked() }
904 }
905
906 pub fn new_empty(data_type: &DataType) -> Self {
908 Self::new_null(data_type, 0)
909 }
910
911 pub fn align_buffers(&mut self) {
920 let layout = layout(&self.data_type);
921 for (buffer, spec) in self.buffers.iter_mut().zip(&layout.buffers) {
922 if let BufferSpec::FixedWidth { alignment, .. } = spec
923 && buffer.as_ptr().align_offset(*alignment) != 0
924 {
925 *buffer = Buffer::from_slice_ref(buffer.as_ref());
926 }
927 }
928 for data in &mut self.child_data {
930 data.align_buffers()
931 }
932 }
933
934 pub fn validate(&self) -> Result<(), ArrowError> {
945 let len_plus_offset = checked_len_plus_offset(&self.data_type, self.len, self.offset)?;
947
948 let layout = layout(&self.data_type);
950
951 if !layout.can_contain_null_mask && self.nulls.is_some() {
952 return Err(ArrowError::InvalidArgumentError(format!(
953 "Arrays of type {:?} cannot contain a null bitmask",
954 self.data_type,
955 )));
956 }
957
958 if self.buffers.len() < layout.buffers.len()
960 || (!layout.variadic && self.buffers.len() != layout.buffers.len())
961 {
962 return Err(ArrowError::InvalidArgumentError(format!(
963 "Expected {} buffers in array of type {:?}, got {}",
964 layout.buffers.len(),
965 self.data_type,
966 self.buffers.len(),
967 )));
968 }
969
970 for (i, (buffer, spec)) in self.buffers.iter().zip(layout.buffers.iter()).enumerate() {
971 match spec {
972 BufferSpec::FixedWidth {
973 byte_width,
974 alignment,
975 } => {
976 let min_buffer_size = len_plus_offset.saturating_mul(*byte_width);
977
978 if buffer.len() < min_buffer_size {
979 return Err(ArrowError::InvalidArgumentError(format!(
980 "Need at least {} bytes in buffers[{}] in array of type {:?}, but got {}",
981 min_buffer_size,
982 i,
983 self.data_type,
984 buffer.len()
985 )));
986 }
987
988 let align_offset = buffer.as_ptr().align_offset(*alignment);
989 if align_offset != 0 {
990 return Err(ArrowError::InvalidArgumentError(format!(
991 "Misaligned buffers[{i}] in array of type {:?}, offset from expected alignment of {alignment} by {}",
992 self.data_type,
993 align_offset.min(alignment - align_offset)
994 )));
995 }
996 }
997 BufferSpec::VariableWidth => {
998 }
1002 BufferSpec::BitMap => {
1003 let min_buffer_size = bit_util::ceil(len_plus_offset, 8);
1004 if buffer.len() < min_buffer_size {
1005 return Err(ArrowError::InvalidArgumentError(format!(
1006 "Need at least {} bytes for bitmap in buffers[{}] in array of type {:?}, but got {}",
1007 min_buffer_size,
1008 i,
1009 self.data_type,
1010 buffer.len()
1011 )));
1012 }
1013 }
1014 BufferSpec::AlwaysNull => {
1015 }
1017 }
1018 }
1019
1020 if let Some(nulls) = self.nulls() {
1022 if nulls.null_count() > self.len {
1023 return Err(ArrowError::InvalidArgumentError(format!(
1024 "null_count {} for an array exceeds length of {} elements",
1025 nulls.null_count(),
1026 self.len
1027 )));
1028 }
1029
1030 let actual_len = nulls.validity().len();
1031 let needed_len = bit_util::ceil(len_plus_offset, 8);
1032 if actual_len < needed_len {
1033 return Err(ArrowError::InvalidArgumentError(format!(
1034 "null_bit_buffer size too small. got {actual_len} needed {needed_len}",
1035 )));
1036 }
1037
1038 if nulls.len() != self.len {
1039 return Err(ArrowError::InvalidArgumentError(format!(
1040 "null buffer incorrect size. got {} expected {}",
1041 nulls.len(),
1042 self.len
1043 )));
1044 }
1045 }
1046
1047 self.validate_child_data()?;
1048
1049 match &self.data_type {
1051 DataType::Utf8 | DataType::Binary => {
1052 self.validate_offsets::<i32>(self.buffers[1].len())?;
1053 }
1054 DataType::LargeUtf8 | DataType::LargeBinary => {
1055 self.validate_offsets::<i64>(self.buffers[1].len())?;
1056 }
1057 DataType::Dictionary(key_type, _value_type) => {
1058 if !DataType::is_dictionary_key_type(key_type) {
1060 return Err(ArrowError::InvalidArgumentError(format!(
1061 "Dictionary key type must be integer, but was {key_type}"
1062 )));
1063 }
1064 }
1065 DataType::RunEndEncoded(run_ends_type, _) => {
1066 if run_ends_type.is_nullable() {
1067 return Err(ArrowError::InvalidArgumentError(
1068 "The nullable should be set to false for the field defining run_ends array.".to_string()
1069 ));
1070 }
1071 if !DataType::is_run_ends_type(run_ends_type.data_type()) {
1072 return Err(ArrowError::InvalidArgumentError(format!(
1073 "RunArray run_ends types must be Int16, Int32 or Int64, but was {}",
1074 run_ends_type.data_type()
1075 )));
1076 }
1077 }
1078 DataType::Map(f, _) if f.is_nullable() => {
1079 return Err(ArrowError::InvalidArgumentError(
1080 "The nullable should be set to false for the map entries field.".to_string(),
1081 ));
1082 }
1083 _ => {}
1084 }
1085
1086 Ok(())
1087 }
1088
1089 fn typed_offsets<T: ArrowNativeType + num_traits::Num>(&self) -> Result<&[T], ArrowError> {
1096 if self.len == 0 && self.buffer_at(0)?.is_empty() {
1098 return Ok(&[]);
1099 }
1100
1101 let len = checked_len_plus_offset(&self.data_type, self.len, 1)?;
1102
1103 self.typed_buffer(0, len)
1104 }
1105
1106 fn typed_buffer<T: ArrowNativeType + num_traits::Num>(
1108 &self,
1109 idx: usize,
1110 len: usize,
1111 ) -> Result<&[T], ArrowError> {
1112 let buffer = self.buffer_at(idx)?;
1113
1114 let required_elements = checked_len_plus_offset(&self.data_type, len, self.offset)?;
1115 let byte_width = mem::size_of::<T>();
1116 let required_len = required_elements.checked_mul(byte_width).ok_or_else(|| {
1117 ArrowError::InvalidArgumentError(format!(
1118 "Buffer {idx} of {} byte length overflow: {} elements of {} bytes exceeds usize",
1119 self.data_type, required_elements, byte_width
1120 ))
1121 })?;
1122
1123 if buffer.len() < required_len {
1124 return Err(ArrowError::InvalidArgumentError(format!(
1125 "Buffer {} of {} isn't large enough. Expected {} bytes got {}",
1126 idx,
1127 self.data_type,
1128 required_len,
1129 buffer.len()
1130 )));
1131 }
1132
1133 Ok(&buffer.typed_data::<T>()[self.offset..required_elements])
1134 }
1135
1136 fn validate_offsets<T: ArrowNativeType + num_traits::Num + std::fmt::Display>(
1139 &self,
1140 values_length: usize,
1141 ) -> Result<(), ArrowError> {
1142 let offsets = self.typed_offsets::<T>()?;
1144 if offsets.is_empty() {
1145 return Ok(());
1146 }
1147
1148 let first_offset = offsets[0].to_usize().ok_or_else(|| {
1149 ArrowError::InvalidArgumentError(format!(
1150 "Error converting offset[0] ({}) to usize for {}",
1151 offsets[0], self.data_type
1152 ))
1153 })?;
1154
1155 let last_offset = offsets[self.len].to_usize().ok_or_else(|| {
1156 ArrowError::InvalidArgumentError(format!(
1157 "Error converting offset[{}] ({}) to usize for {}",
1158 self.len, offsets[self.len], self.data_type
1159 ))
1160 })?;
1161
1162 if first_offset > values_length {
1163 return Err(ArrowError::InvalidArgumentError(format!(
1164 "First offset {} of {} is larger than values length {}",
1165 first_offset, self.data_type, values_length,
1166 )));
1167 }
1168
1169 if last_offset > values_length {
1170 return Err(ArrowError::InvalidArgumentError(format!(
1171 "Last offset {} of {} is larger than values length {}",
1172 last_offset, self.data_type, values_length,
1173 )));
1174 }
1175
1176 if first_offset > last_offset {
1177 return Err(ArrowError::InvalidArgumentError(format!(
1178 "First offset {} in {} is smaller than last offset {}",
1179 first_offset, self.data_type, last_offset,
1180 )));
1181 }
1182
1183 Ok(())
1184 }
1185
1186 fn validate_offsets_and_sizes<T: ArrowNativeType + num_traits::Num + std::fmt::Display>(
1189 &self,
1190 values_length: usize,
1191 ) -> Result<(), ArrowError> {
1192 let offsets: &[T] = self.typed_buffer(0, self.len)?;
1193 let sizes: &[T] = self.typed_buffer(1, self.len)?;
1194 if offsets.len() != sizes.len() {
1195 return Err(ArrowError::ComputeError(format!(
1196 "ListView offsets len {} does not match sizes len {}",
1197 offsets.len(),
1198 sizes.len()
1199 )));
1200 }
1201
1202 for i in 0..sizes.len() {
1203 let size = sizes[i].to_usize().ok_or_else(|| {
1204 ArrowError::InvalidArgumentError(format!(
1205 "Error converting size[{}] ({}) to usize for {}",
1206 i, sizes[i], self.data_type
1207 ))
1208 })?;
1209 let offset = offsets[i].to_usize().ok_or_else(|| {
1210 ArrowError::InvalidArgumentError(format!(
1211 "Error converting offset[{}] ({}) to usize for {}",
1212 i, offsets[i], self.data_type
1213 ))
1214 })?;
1215 if size
1216 .checked_add(offset)
1217 .expect("Offset and size have exceeded the usize boundary")
1218 > values_length
1219 {
1220 return Err(ArrowError::InvalidArgumentError(format!(
1221 "Size {} at index {} is larger than the remaining values for {}",
1222 size, i, self.data_type
1223 )));
1224 }
1225 }
1226 Ok(())
1227 }
1228
1229 fn validate_child_data(&self) -> Result<(), ArrowError> {
1231 match &self.data_type {
1232 DataType::List(field) => {
1233 let values_data = self.get_single_valid_child_data(field.data_type())?;
1234 self.validate_offsets::<i32>(values_data.len)?;
1235 Ok(())
1236 }
1237 DataType::LargeList(field) => {
1238 let values_data = self.get_single_valid_child_data(field.data_type())?;
1239 self.validate_offsets::<i64>(values_data.len)?;
1240 Ok(())
1241 }
1242 DataType::Map(field, _) => {
1243 let DataType::Struct(entries_fields) = field.data_type() else {
1244 return Err(ArrowError::InvalidArgumentError(format!(
1245 "Map field should be a entries struct data type, got {:?} instead",
1246 field.data_type()
1247 )));
1248 };
1249 if entries_fields.len() != 2 {
1250 return Err(ArrowError::InvalidArgumentError(format!(
1251 "Map entries data type should be a struct containing 2 fields, got {} fields",
1252 entries_fields.len()
1253 )));
1254 }
1255
1256 if entries_fields[0].is_nullable() {
1258 return Err(ArrowError::InvalidArgumentError(
1259 "Map key field must not be nullable".to_string(),
1260 ));
1261 }
1262 let values_data = self.get_single_valid_child_data(field.data_type())?;
1263 self.validate_offsets::<i32>(values_data.len)?;
1264 Ok(())
1265 }
1266 DataType::ListView(field) => {
1267 let values_data = self.get_single_valid_child_data(field.data_type())?;
1268 self.validate_offsets_and_sizes::<i32>(values_data.len)?;
1269 Ok(())
1270 }
1271 DataType::LargeListView(field) => {
1272 let values_data = self.get_single_valid_child_data(field.data_type())?;
1273 self.validate_offsets_and_sizes::<i64>(values_data.len)?;
1274 Ok(())
1275 }
1276 DataType::FixedSizeList(field, list_size) => {
1277 let values_data = self.get_single_valid_child_data(field.data_type())?;
1278
1279 let list_size: usize = (*list_size).try_into().map_err(|_| {
1280 ArrowError::InvalidArgumentError(format!(
1281 "{} has a negative list_size {}",
1282 self.data_type, list_size
1283 ))
1284 })?;
1285
1286 let expected_values_len = self.len
1287 .checked_mul(list_size)
1288 .expect("integer overflow computing expected number of expected values in FixedListSize");
1289
1290 if values_data.len < expected_values_len {
1291 return Err(ArrowError::InvalidArgumentError(format!(
1292 "Values length {} is less than the length ({}) multiplied by the value size ({}) for {}",
1293 values_data.len, self.len, list_size, self.data_type
1294 )));
1295 }
1296
1297 Ok(())
1298 }
1299 DataType::Struct(fields) => {
1300 self.validate_num_child_data(fields.len())?;
1301 let len_plus_offset =
1302 checked_len_plus_offset(&self.data_type, self.len, self.offset)?;
1303 for (i, field) in fields.iter().enumerate() {
1304 let field_data = self.get_valid_child_data(i, field.data_type())?;
1305
1306 if field_data.len < len_plus_offset {
1308 return Err(ArrowError::InvalidArgumentError(format!(
1309 "{} child array #{} for field {} has length smaller than expected for struct array ({} < {})",
1310 self.data_type,
1311 i,
1312 field.name(),
1313 field_data.len,
1314 len_plus_offset
1315 )));
1316 }
1317 }
1318 Ok(())
1319 }
1320 DataType::RunEndEncoded(run_ends_field, values_field) => {
1321 self.validate_num_child_data(2)?;
1322 let run_ends_data = self.get_valid_child_data(0, run_ends_field.data_type())?;
1323 let values_data = self.get_valid_child_data(1, values_field.data_type())?;
1324 if run_ends_data.len != values_data.len {
1325 return Err(ArrowError::InvalidArgumentError(format!(
1326 "The run_ends array length should be the same as values array length. Run_ends array length is {}, values array length is {}",
1327 run_ends_data.len, values_data.len
1328 )));
1329 }
1330 if run_ends_data.nulls.is_some() {
1331 return Err(ArrowError::InvalidArgumentError(
1332 "Found null values in run_ends array. The run_ends array should not have null values.".to_string(),
1333 ));
1334 }
1335 Ok(())
1336 }
1337 DataType::Union(fields, mode) => {
1338 self.validate_num_child_data(fields.len())?;
1339
1340 for (i, (_, field)) in fields.iter().enumerate() {
1341 let field_data = self.get_valid_child_data(i, field.data_type())?;
1342
1343 if mode == &UnionMode::Sparse {
1344 let len_plus_offset =
1345 checked_len_plus_offset(&self.data_type, self.len, self.offset)?;
1346 if field_data.len < len_plus_offset {
1347 return Err(ArrowError::InvalidArgumentError(format!(
1348 "Sparse union child array #{} has length smaller than expected for union array ({} < {})",
1349 i, field_data.len, len_plus_offset
1350 )));
1351 }
1352 }
1353 }
1354 Ok(())
1355 }
1356 DataType::Dictionary(_key_type, value_type) => {
1357 self.get_single_valid_child_data(value_type)?;
1358 Ok(())
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 Ok(())
1370 }
1371 }
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 self.validate_non_nullable(None, &self.child_data[0])?
1529 }
1530 }
1531 DataType::FixedSizeList(field, len) => {
1532 let child = &self.child_data[0];
1533 if !field.is_nullable() {
1534 match &self.nulls {
1535 Some(nulls) => {
1536 let element_len = *len as usize;
1537 let expanded = nulls.expand(element_len);
1538 self.validate_non_nullable(Some(&expanded), child)?;
1539 }
1540 None => self.validate_non_nullable(None, child)?,
1541 }
1542 }
1543 }
1544 DataType::Struct(fields) => {
1545 for (field, child) in fields.iter().zip(&self.child_data) {
1546 if !field.is_nullable() {
1547 self.validate_non_nullable(self.nulls(), child)?
1548 }
1549 }
1550 }
1551 _ => {}
1552 }
1553
1554 Ok(())
1555 }
1556
1557 fn validate_non_nullable(
1559 &self,
1560 mask: Option<&NullBuffer>,
1561 child: &ArrayData,
1562 ) -> Result<(), ArrowError> {
1563 let Some(mask) = mask else {
1564 return match child.null_count() {
1565 0 => Ok(()),
1566 _ => Err(ArrowError::InvalidArgumentError(format!(
1567 "non-nullable child of type {} contains nulls not present in parent {}",
1568 child.data_type, self.data_type
1569 ))),
1570 };
1571 };
1572
1573 match child.nulls() {
1574 Some(nulls) if !mask.contains(nulls) => Err(ArrowError::InvalidArgumentError(format!(
1575 "non-nullable child of type {} contains nulls not present in parent",
1576 child.data_type
1577 ))),
1578 _ => Ok(()),
1579 }
1580 }
1581
1582 pub fn validate_values(&self) -> Result<(), ArrowError> {
1588 match &self.data_type {
1589 DataType::Utf8 => self.validate_utf8::<i32>(),
1590 DataType::LargeUtf8 => self.validate_utf8::<i64>(),
1591 DataType::Binary => self.validate_offsets_full::<i32>(self.buffer_at(1)?.len()),
1592 DataType::LargeBinary => self.validate_offsets_full::<i64>(self.buffer_at(1)?.len()),
1593 DataType::BinaryView => {
1594 let views = self.typed_buffer::<u128>(0, self.len)?;
1595 validate_binary_view(views, &self.buffers[1..])
1596 }
1597 DataType::Utf8View => {
1598 let views = self.typed_buffer::<u128>(0, self.len)?;
1599 validate_string_view(views, &self.buffers[1..])
1600 }
1601 DataType::List(_) | DataType::Map(_, _) => {
1602 let child = self.child_at(0)?;
1603 self.validate_offsets_full::<i32>(child.len)
1604 }
1605 DataType::LargeList(_) => {
1606 let child = self.child_at(0)?;
1607 self.validate_offsets_full::<i64>(child.len)
1608 }
1609 DataType::Union(_, _) => {
1610 Ok(())
1616 }
1617 DataType::Dictionary(key_type, _value_type) => {
1618 let dictionary_length = self.child_at(0)?.len;
1619 let dictionary_length = i64::try_from(dictionary_length).map_err(|_| {
1620 ArrowError::InvalidArgumentError(format!(
1621 "Dictionary of {dictionary_length} values is too long for an i64"
1622 ))
1623 })?;
1624 let max_value = dictionary_length - 1;
1625 match key_type.as_ref() {
1626 DataType::UInt8 => self.check_bounds::<u8>(max_value),
1627 DataType::UInt16 => self.check_bounds::<u16>(max_value),
1628 DataType::UInt32 => self.check_bounds::<u32>(max_value),
1629 DataType::UInt64 => self.check_bounds::<u64>(max_value),
1630 DataType::Int8 => self.check_bounds::<i8>(max_value),
1631 DataType::Int16 => self.check_bounds::<i16>(max_value),
1632 DataType::Int32 => self.check_bounds::<i32>(max_value),
1633 DataType::Int64 => self.check_bounds::<i64>(max_value),
1634 _ => Err(ArrowError::InvalidArgumentError(format!(
1635 "Dictionary key type must be an integer, got {key_type}"
1636 ))),
1637 }
1638 }
1639 DataType::RunEndEncoded(run_ends, _values) => {
1640 let run_ends_data = self.child_at(0)?;
1641 match run_ends.data_type() {
1642 DataType::Int16 => run_ends_data.check_run_ends::<i16>(),
1643 DataType::Int32 => run_ends_data.check_run_ends::<i32>(),
1644 DataType::Int64 => run_ends_data.check_run_ends::<i64>(),
1645 data_type => Err(ArrowError::InvalidArgumentError(format!(
1646 "Run end type must be Int16, Int32 or Int64, got {data_type}"
1647 ))),
1648 }
1649 }
1650 _ => {
1651 Ok(())
1653 }
1654 }
1655 }
1656
1657 fn validate_each_offset<T, V>(&self, offset_limit: usize, validate: V) -> Result<(), ArrowError>
1668 where
1669 T: ArrowNativeType + TryInto<usize> + num_traits::Num + std::fmt::Display,
1670 V: Fn(usize, Range<usize>) -> Result<(), ArrowError>,
1671 {
1672 self.typed_offsets::<T>()?
1673 .iter()
1674 .enumerate()
1675 .map(|(i, x)| {
1676 let r = x.to_usize().ok_or_else(|| {
1678 ArrowError::InvalidArgumentError(format!(
1679 "Offset invariant failure: Could not convert offset {x} to usize at position {i}"))}
1680 );
1681 match r {
1683 Ok(n) if n <= offset_limit => Ok((i, n)),
1684 Ok(_) => Err(ArrowError::InvalidArgumentError(format!(
1685 "Offset invariant failure: offset at position {i} out of bounds: {x} > {offset_limit}"))
1686 ),
1687 Err(e) => Err(e),
1688 }
1689 })
1690 .scan(0_usize, |start, end| {
1691 match end {
1693 Ok((i, end)) if *start <= end => {
1694 let range = Some(Ok((i, *start..end)));
1695 *start = end;
1696 range
1697 }
1698 Ok((i, end)) => Some(Err(ArrowError::InvalidArgumentError(format!(
1699 "Offset invariant failure: non-monotonic offset at slot {}: {} > {}",
1700 i - 1, start, end))
1701 )),
1702 Err(err) => Some(Err(err)),
1703 }
1704 })
1705 .skip(1) .try_for_each(|res: Result<(usize, Range<usize>), ArrowError>| {
1707 let (item_index, range) = res?;
1708 validate(item_index-1, range)
1709 })
1710 }
1711
1712 fn validate_utf8<T>(&self) -> Result<(), ArrowError>
1715 where
1716 T: ArrowNativeType + TryInto<usize> + num_traits::Num + std::fmt::Display,
1717 {
1718 let values_buffer = &self.buffer_at(1)?.as_slice();
1719 if let Ok(values_str) = std::str::from_utf8(values_buffer) {
1720 self.validate_each_offset::<T, _>(values_buffer.len(), |string_index, range| {
1722 if !values_str.is_char_boundary(range.start)
1723 || !values_str.is_char_boundary(range.end)
1724 {
1725 return Err(ArrowError::InvalidArgumentError(format!(
1726 "incomplete utf-8 byte sequence from index {string_index}"
1727 )));
1728 }
1729 Ok(())
1730 })
1731 } else {
1732 self.validate_each_offset::<T, _>(values_buffer.len(), |string_index, range| {
1734 std::str::from_utf8(&values_buffer[range.clone()]).map_err(|e| {
1735 ArrowError::InvalidArgumentError(format!(
1736 "Invalid UTF8 sequence at string index {string_index} ({range:?}): {e}"
1737 ))
1738 })?;
1739 Ok(())
1740 })
1741 }
1742 }
1743
1744 fn validate_offsets_full<T>(&self, offset_limit: usize) -> Result<(), ArrowError>
1747 where
1748 T: ArrowNativeType + TryInto<usize> + num_traits::Num + std::fmt::Display,
1749 {
1750 self.validate_each_offset::<T, _>(offset_limit, |_string_index, _range| {
1751 Ok(())
1754 })
1755 }
1756
1757 fn check_bounds<T>(&self, max_value: i64) -> Result<(), ArrowError>
1760 where
1761 T: ArrowNativeType + TryInto<i64> + num_traits::Num + std::fmt::Display,
1762 {
1763 let indexes: &[T] = self.typed_buffer::<T>(0, self.len)?;
1766
1767 indexes.iter().enumerate().try_for_each(|(i, &dict_index)| {
1768 if self.is_null(i) {
1770 return Ok(());
1771 }
1772 let dict_index: i64 = dict_index.try_into().map_err(|_| {
1773 ArrowError::InvalidArgumentError(format!(
1774 "Value at position {i} out of bounds: {dict_index} (can not convert to i64)"
1775 ))
1776 })?;
1777
1778 if dict_index < 0 || dict_index > max_value {
1779 return Err(ArrowError::InvalidArgumentError(format!(
1780 "Value at position {i} out of bounds: {dict_index} (should be in [0, {max_value}])"
1781 )));
1782 }
1783 Ok(())
1784 })
1785 }
1786
1787 fn check_run_ends<T>(&self) -> Result<(), ArrowError>
1789 where
1790 T: ArrowNativeType + TryInto<i64> + num_traits::Num + std::fmt::Display,
1791 {
1792 let values = self.typed_buffer::<T>(0, self.len)?;
1793 let mut prev_value = 0_i64;
1794 values.iter().enumerate().try_for_each(|(ix, &inp_value)| {
1795 let value: i64 = inp_value.try_into().map_err(|_| {
1796 ArrowError::InvalidArgumentError(format!(
1797 "Value at position {ix} out of bounds: {inp_value} (can not convert to i64)"
1798 ))
1799 })?;
1800 if value <= 0_i64 {
1801 return Err(ArrowError::InvalidArgumentError(format!(
1802 "The values in run_ends array should be strictly positive. Found value {value} at index {ix} that does not match the criteria."
1803 )));
1804 }
1805 if ix > 0 && value <= prev_value {
1806 return Err(ArrowError::InvalidArgumentError(format!(
1807 "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."
1808 )));
1809 }
1810
1811 prev_value = value;
1812 Ok(())
1813 })?;
1814
1815 let len_plus_offset = checked_len_plus_offset(&self.data_type, self.len, self.offset)?;
1816 if prev_value.as_usize() < len_plus_offset {
1817 return Err(ArrowError::InvalidArgumentError(format!(
1818 "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 {len_plus_offset}."
1819 )));
1820 }
1821 Ok(())
1822 }
1823
1824 pub fn ptr_eq(&self, other: &Self) -> bool {
1828 if self.offset != other.offset
1829 || self.len != other.len
1830 || self.data_type != other.data_type
1831 || self.buffers.len() != other.buffers.len()
1832 || self.child_data.len() != other.child_data.len()
1833 {
1834 return false;
1835 }
1836
1837 match (&self.nulls, &other.nulls) {
1838 (Some(a), Some(b)) if !a.inner().ptr_eq(b.inner()) => return false,
1839 (Some(_), None) | (None, Some(_)) => return false,
1840 _ => {}
1841 }
1842
1843 if !self
1844 .buffers
1845 .iter()
1846 .zip(other.buffers.iter())
1847 .all(|(a, b)| a.as_ptr() == b.as_ptr())
1848 {
1849 return false;
1850 }
1851
1852 self.child_data
1853 .iter()
1854 .zip(other.child_data.iter())
1855 .all(|(a, b)| a.ptr_eq(b))
1856 }
1857
1858 pub fn into_builder(self) -> ArrayDataBuilder {
1860 self.into()
1861 }
1862
1863 #[cfg(feature = "pool")]
1870 pub fn claim(&self, pool: &dyn arrow_buffer::MemoryPool) {
1871 for buffer in &self.buffers {
1873 buffer.claim(pool);
1874 }
1875
1876 if let Some(nulls) = &self.nulls {
1878 nulls.claim(pool);
1879 }
1880
1881 for child in &self.child_data {
1883 child.claim(pool);
1884 }
1885 }
1886}
1887
1888pub fn layout(data_type: &DataType) -> DataTypeLayout {
1891 use arrow_schema::IntervalUnit::*;
1894
1895 match data_type {
1896 DataType::Null => DataTypeLayout {
1897 buffers: vec![],
1898 can_contain_null_mask: false,
1899 variadic: false,
1900 },
1901 DataType::Boolean => DataTypeLayout {
1902 buffers: vec![BufferSpec::BitMap],
1903 can_contain_null_mask: true,
1904 variadic: false,
1905 },
1906 DataType::Int8 => DataTypeLayout::new_fixed_width::<i8>(),
1907 DataType::Int16 => DataTypeLayout::new_fixed_width::<i16>(),
1908 DataType::Int32 => DataTypeLayout::new_fixed_width::<i32>(),
1909 DataType::Int64 => DataTypeLayout::new_fixed_width::<i64>(),
1910 DataType::UInt8 => DataTypeLayout::new_fixed_width::<u8>(),
1911 DataType::UInt16 => DataTypeLayout::new_fixed_width::<u16>(),
1912 DataType::UInt32 => DataTypeLayout::new_fixed_width::<u32>(),
1913 DataType::UInt64 => DataTypeLayout::new_fixed_width::<u64>(),
1914 DataType::Float16 => DataTypeLayout::new_fixed_width::<half::f16>(),
1915 DataType::Float32 => DataTypeLayout::new_fixed_width::<f32>(),
1916 DataType::Float64 => DataTypeLayout::new_fixed_width::<f64>(),
1917 DataType::Timestamp(_, _) => DataTypeLayout::new_fixed_width::<i64>(),
1918 DataType::Date32 => DataTypeLayout::new_fixed_width::<i32>(),
1919 DataType::Date64 => DataTypeLayout::new_fixed_width::<i64>(),
1920 DataType::Time32(_) => DataTypeLayout::new_fixed_width::<i32>(),
1921 DataType::Time64(_) => DataTypeLayout::new_fixed_width::<i64>(),
1922 DataType::Interval(YearMonth) => DataTypeLayout::new_fixed_width::<i32>(),
1923 DataType::Interval(DayTime) => DataTypeLayout::new_fixed_width::<IntervalDayTime>(),
1924 DataType::Interval(MonthDayNano) => {
1925 DataTypeLayout::new_fixed_width::<IntervalMonthDayNano>()
1926 }
1927 DataType::Duration(_) => DataTypeLayout::new_fixed_width::<i64>(),
1928 DataType::Decimal32(_, _) => DataTypeLayout::new_fixed_width::<i32>(),
1929 DataType::Decimal64(_, _) => DataTypeLayout::new_fixed_width::<i64>(),
1930 DataType::Decimal128(_, _) => DataTypeLayout::new_fixed_width::<i128>(),
1931 DataType::Decimal256(_, _) => DataTypeLayout::new_fixed_width::<i256>(),
1932 DataType::FixedSizeBinary(size) => {
1933 let spec = BufferSpec::FixedWidth {
1934 byte_width: (*size).try_into().unwrap(),
1935 alignment: mem::align_of::<u8>(),
1936 };
1937 DataTypeLayout {
1938 buffers: vec![spec],
1939 can_contain_null_mask: true,
1940 variadic: false,
1941 }
1942 }
1943 DataType::Binary => DataTypeLayout::new_binary::<i32>(),
1944 DataType::LargeBinary => DataTypeLayout::new_binary::<i64>(),
1945 DataType::Utf8 => DataTypeLayout::new_binary::<i32>(),
1946 DataType::LargeUtf8 => DataTypeLayout::new_binary::<i64>(),
1947 DataType::BinaryView | DataType::Utf8View => DataTypeLayout::new_view(),
1948 DataType::FixedSizeList(_, _) => DataTypeLayout::new_nullable_empty(), DataType::List(_) => DataTypeLayout::new_fixed_width::<i32>(),
1950 DataType::ListView(_) => DataTypeLayout::new_list_view::<i32>(),
1951 DataType::LargeListView(_) => DataTypeLayout::new_list_view::<i64>(),
1952 DataType::LargeList(_) => DataTypeLayout::new_fixed_width::<i64>(),
1953 DataType::Map(_, _) => DataTypeLayout::new_fixed_width::<i32>(),
1954 DataType::Struct(_) => DataTypeLayout::new_nullable_empty(), DataType::RunEndEncoded(_, _) => DataTypeLayout::new_empty(), DataType::Union(_, mode) => {
1957 let type_ids = BufferSpec::FixedWidth {
1958 byte_width: mem::size_of::<i8>(),
1959 alignment: mem::align_of::<i8>(),
1960 };
1961
1962 DataTypeLayout {
1963 buffers: match mode {
1964 UnionMode::Sparse => {
1965 vec![type_ids]
1966 }
1967 UnionMode::Dense => {
1968 vec![
1969 type_ids,
1970 BufferSpec::FixedWidth {
1971 byte_width: mem::size_of::<i32>(),
1972 alignment: mem::align_of::<i32>(),
1973 },
1974 ]
1975 }
1976 },
1977 can_contain_null_mask: false,
1978 variadic: false,
1979 }
1980 }
1981 DataType::Dictionary(key_type, _value_type) => layout(key_type),
1982 }
1983}
1984
1985#[derive(Debug, PartialEq, Eq)]
1987pub struct DataTypeLayout {
1989 pub buffers: Vec<BufferSpec>,
1991
1992 pub can_contain_null_mask: bool,
1994
1995 pub variadic: bool,
1999}
2000
2001impl DataTypeLayout {
2002 pub fn new_fixed_width<T>() -> Self {
2004 Self {
2005 buffers: vec![BufferSpec::FixedWidth {
2006 byte_width: mem::size_of::<T>(),
2007 alignment: mem::align_of::<T>(),
2008 }],
2009 can_contain_null_mask: true,
2010 variadic: false,
2011 }
2012 }
2013
2014 pub fn new_nullable_empty() -> Self {
2017 Self {
2018 buffers: vec![],
2019 can_contain_null_mask: true,
2020 variadic: false,
2021 }
2022 }
2023
2024 pub fn new_empty() -> Self {
2027 Self {
2028 buffers: vec![],
2029 can_contain_null_mask: false,
2030 variadic: false,
2031 }
2032 }
2033
2034 pub fn new_binary<T>() -> Self {
2038 Self {
2039 buffers: vec![
2040 BufferSpec::FixedWidth {
2042 byte_width: mem::size_of::<T>(),
2043 alignment: mem::align_of::<T>(),
2044 },
2045 BufferSpec::VariableWidth,
2047 ],
2048 can_contain_null_mask: true,
2049 variadic: false,
2050 }
2051 }
2052
2053 pub fn new_view() -> Self {
2055 Self {
2056 buffers: vec![BufferSpec::FixedWidth {
2057 byte_width: mem::size_of::<u128>(),
2058 alignment: mem::align_of::<u128>(),
2059 }],
2060 can_contain_null_mask: true,
2061 variadic: true,
2062 }
2063 }
2064
2065 pub fn new_list_view<T>() -> Self {
2067 Self {
2068 buffers: vec![
2069 BufferSpec::FixedWidth {
2070 byte_width: mem::size_of::<T>(),
2071 alignment: mem::align_of::<T>(),
2072 },
2073 BufferSpec::FixedWidth {
2074 byte_width: mem::size_of::<T>(),
2075 alignment: mem::align_of::<T>(),
2076 },
2077 ],
2078 can_contain_null_mask: true,
2079 variadic: false,
2080 }
2081 }
2082}
2083
2084#[derive(Debug, PartialEq, Eq)]
2086pub enum BufferSpec {
2087 FixedWidth {
2098 byte_width: usize,
2100 alignment: usize,
2102 },
2103 VariableWidth,
2105 BitMap,
2111 AlwaysNull,
2114}
2115
2116impl PartialEq for ArrayData {
2117 fn eq(&self, other: &Self) -> bool {
2118 equal::equal(self, other)
2119 }
2120}
2121
2122#[derive(Debug, Clone)]
2141#[doc(hidden)]
2142pub struct UnsafeFlag(bool);
2143
2144impl UnsafeFlag {
2145 #[inline]
2149 pub const fn new() -> Self {
2150 Self(false)
2151 }
2152
2153 #[inline]
2163 pub unsafe fn set(&mut self, val: bool) {
2164 self.0 = val;
2165 }
2166
2167 #[inline]
2169 pub fn get(&self) -> bool {
2170 self.0
2171 }
2172}
2173
2174impl Default for UnsafeFlag {
2176 fn default() -> Self {
2177 Self::new()
2178 }
2179}
2180
2181#[derive(Debug)]
2183pub struct ArrayDataBuilder {
2184 data_type: DataType,
2185 len: usize,
2186 null_count: Option<usize>,
2187 null_bit_buffer: Option<Buffer>,
2188 nulls: Option<NullBuffer>,
2189 offset: usize,
2190 buffers: Vec<Buffer>,
2191 child_data: Vec<ArrayData>,
2192 align_buffers: bool,
2196 skip_validation: UnsafeFlag,
2206}
2207
2208impl ArrayDataBuilder {
2209 #[inline]
2210 pub const fn new(data_type: DataType) -> Self {
2212 Self {
2213 data_type,
2214 len: 0,
2215 null_count: None,
2216 null_bit_buffer: None,
2217 nulls: None,
2218 offset: 0,
2219 buffers: vec![],
2220 child_data: vec![],
2221 align_buffers: false,
2222 skip_validation: UnsafeFlag::new(),
2223 }
2224 }
2225
2226 pub fn data_type(self, data_type: DataType) -> Self {
2228 Self { data_type, ..self }
2229 }
2230
2231 #[inline]
2232 pub const fn len(mut self, n: usize) -> Self {
2234 self.len = n;
2235 self
2236 }
2237
2238 pub fn nulls(mut self, nulls: Option<NullBuffer>) -> Self {
2240 self.nulls = nulls;
2241 self.null_count = None;
2242 self.null_bit_buffer = None;
2243 self
2244 }
2245
2246 pub fn null_count(mut self, null_count: usize) -> Self {
2248 self.null_count = Some(null_count);
2249 self
2250 }
2251
2252 pub fn null_bit_buffer(mut self, buf: Option<Buffer>) -> Self {
2254 self.nulls = None;
2255 self.null_bit_buffer = buf;
2256 self
2257 }
2258
2259 #[inline]
2261 pub const fn offset(mut self, n: usize) -> Self {
2262 self.offset = n;
2263 self
2264 }
2265
2266 pub fn buffers(mut self, v: Vec<Buffer>) -> Self {
2268 self.buffers = v;
2269 self
2270 }
2271
2272 pub fn add_buffer(mut self, b: Buffer) -> Self {
2274 self.buffers.push(b);
2275 self
2276 }
2277
2278 pub fn add_buffers<I: IntoIterator<Item = Buffer>>(mut self, bs: I) -> Self {
2280 self.buffers.extend(bs);
2281 self
2282 }
2283
2284 pub fn child_data(mut self, v: Vec<ArrayData>) -> Self {
2286 self.child_data = v;
2287 self
2288 }
2289
2290 pub fn add_child_data(mut self, r: ArrayData) -> Self {
2292 self.child_data.push(r);
2293 self
2294 }
2295
2296 pub unsafe fn build_unchecked(self) -> ArrayData {
2312 unsafe { self.skip_validation(true) }.build().unwrap()
2313 }
2314
2315 pub fn build(self) -> Result<ArrayData, ArrowError> {
2324 let Self {
2325 data_type,
2326 len,
2327 null_count,
2328 null_bit_buffer,
2329 nulls,
2330 offset,
2331 buffers,
2332 child_data,
2333 align_buffers,
2334 skip_validation,
2335 } = self;
2336
2337 let nulls = nulls
2338 .or_else(|| {
2339 let buffer = null_bit_buffer?;
2340 let buffer = BooleanBuffer::new(buffer, offset, len);
2341 Some(match null_count {
2342 Some(n) => {
2343 unsafe { NullBuffer::new_unchecked(buffer, n) }
2345 }
2346 None => NullBuffer::new(buffer),
2347 })
2348 })
2349 .filter(|b| b.null_count() != 0);
2350
2351 let mut data = ArrayData {
2352 data_type,
2353 len,
2354 offset,
2355 buffers,
2356 child_data,
2357 nulls,
2358 };
2359
2360 if align_buffers {
2361 data.align_buffers();
2362 }
2363
2364 if !skip_validation.get() || cfg!(feature = "force_validate") {
2366 data.validate_data()?;
2367 }
2368 Ok(data)
2369 }
2370
2371 pub fn align_buffers(mut self, align_buffers: bool) -> Self {
2387 self.align_buffers = align_buffers;
2388 self
2389 }
2390
2391 pub unsafe fn skip_validation(mut self, skip_validation: bool) -> Self {
2405 unsafe {
2406 self.skip_validation.set(skip_validation);
2407 }
2408 self
2409 }
2410}
2411
2412impl From<ArrayData> for ArrayDataBuilder {
2413 fn from(d: ArrayData) -> Self {
2414 Self {
2415 data_type: d.data_type,
2416 len: d.len,
2417 offset: d.offset,
2418 buffers: d.buffers,
2419 child_data: d.child_data,
2420 nulls: d.nulls,
2421 null_bit_buffer: None,
2422 null_count: None,
2423 align_buffers: false,
2424 skip_validation: UnsafeFlag::new(),
2425 }
2426 }
2427}
2428
2429pub(crate) fn get_fixed_size_binary_width(data_type: &DataType) -> usize {
2434 match data_type {
2435 DataType::FixedSizeBinary(i) => {
2436 if *i < 0 {
2437 panic!("cannot compare FixedSizeBinary({})", *i);
2438 }
2439 *i as usize
2440 }
2441 _ => unreachable!(),
2442 }
2443}
2444
2445#[cfg(test)]
2446mod tests {
2447 use super::*;
2448 use crate::ByteView;
2449 use crate::transform::MutableArrayData;
2450 use arrow_buffer::{OffsetBuffer, ScalarBuffer};
2451 use arrow_schema::{Field, Fields};
2452
2453 fn make_i32_buffer(n: usize) -> Buffer {
2457 Buffer::from_slice_ref(vec![42i32; n])
2458 }
2459
2460 fn make_f32_buffer(n: usize) -> Buffer {
2462 Buffer::from_slice_ref(vec![42f32; n])
2463 }
2464
2465 #[test]
2466 fn test_builder() {
2467 let v = (0..25).collect::<Vec<i32>>();
2469 let b1 = Buffer::from_slice_ref(&v);
2470 let arr_data = ArrayData::builder(DataType::Int32)
2471 .len(20)
2472 .offset(5)
2473 .add_buffer(b1)
2474 .null_bit_buffer(Some(Buffer::from([
2475 0b01011111, 0b10110101, 0b01100011, 0b00011110,
2476 ])))
2477 .build()
2478 .unwrap();
2479
2480 assert_eq!(20, arr_data.len());
2481 assert_eq!(10, arr_data.null_count());
2482 assert_eq!(5, arr_data.offset());
2483 assert_eq!(1, arr_data.buffers().len());
2484 assert_eq!(
2485 Buffer::from_slice_ref(&v).as_slice(),
2486 arr_data.buffers()[0].as_slice()
2487 );
2488 }
2489
2490 #[test]
2491 fn test_builder_with_child_data() {
2492 let child_arr_data = ArrayData::try_new(
2493 DataType::Int32,
2494 5,
2495 None,
2496 0,
2497 vec![Buffer::from_slice_ref([1i32, 2, 3, 4, 5])],
2498 vec![],
2499 )
2500 .unwrap();
2501
2502 let field = Arc::new(Field::new("x", DataType::Int32, true));
2503 let data_type = DataType::Struct(vec![field].into());
2504
2505 let arr_data = ArrayData::builder(data_type)
2506 .len(5)
2507 .offset(0)
2508 .add_child_data(child_arr_data.clone())
2509 .build()
2510 .unwrap();
2511
2512 assert_eq!(5, arr_data.len());
2513 assert_eq!(1, arr_data.child_data().len());
2514 assert_eq!(child_arr_data, arr_data.child_data()[0]);
2515 }
2516
2517 #[test]
2518 fn test_struct_validation_accounts_for_parent_offset() {
2519 let data_type =
2520 DataType::Struct(Fields::from(vec![Field::new("x", DataType::Int32, false)]));
2521 let child = ArrayData::builder(DataType::Int32)
2522 .len(5)
2523 .add_buffer(Buffer::from_slice_ref([0, 1, 2, 3, 4]))
2524 .build()
2525 .unwrap();
2526
2527 let err = ArrayData::builder(data_type)
2529 .len(5)
2530 .offset(1)
2531 .add_child_data(child)
2532 .build()
2533 .unwrap_err()
2534 .to_string();
2535
2536 assert!(err.contains(
2537 "child array #0 for field x has length smaller than expected for struct array (5 < 6)"
2538 ));
2539 }
2540
2541 #[test]
2542 fn test_struct_equal_accounts_for_parent_offset() {
2543 let data_type =
2544 DataType::Struct(Fields::from(vec![Field::new("x", DataType::Int32, false)]));
2545
2546 let child1 = ArrayData::builder(DataType::Int32)
2547 .len(5)
2548 .add_buffer(Buffer::from_slice_ref([0, 1, 2, 3, 4]))
2549 .build()
2550 .unwrap();
2551 let child2 = child1.slice(1, 4);
2552
2553 let data1 = ArrayData::builder(data_type.clone())
2555 .len(4)
2556 .offset(1)
2557 .add_child_data(child1)
2558 .build()
2559 .unwrap();
2560 let data2 = ArrayData::builder(data_type)
2561 .len(4)
2562 .add_child_data(child2)
2563 .build()
2564 .unwrap();
2565
2566 assert_eq!(data1, data2);
2567 }
2568
2569 #[test]
2570 fn test_extend_struct_accounts_for_parent_offset() {
2571 let data_type =
2572 DataType::Struct(Fields::from(vec![Field::new("x", DataType::Int32, false)]));
2573 let child = ArrayData::builder(DataType::Int32)
2574 .len(5)
2575 .add_buffer(Buffer::from_slice_ref([0, 1, 2, 3, 4]))
2576 .build()
2577 .unwrap();
2578
2579 let data = ArrayData::builder(data_type)
2580 .len(4)
2581 .offset(1)
2582 .add_child_data(child)
2583 .build()
2584 .unwrap();
2585
2586 let mut mutable = MutableArrayData::new(vec![&data], false, data.len());
2587 mutable.try_extend(0, 0, data.len()).unwrap();
2588 let output = mutable.freeze();
2589
2590 assert_eq!(output.child_data()[0].buffer::<i32>(0), &[1, 2, 3, 4]);
2591 }
2592
2593 #[test]
2594 fn test_null_count() {
2595 let mut bit_v: [u8; 2] = [0; 2];
2596 bit_util::set_bit(&mut bit_v, 0);
2597 bit_util::set_bit(&mut bit_v, 3);
2598 bit_util::set_bit(&mut bit_v, 10);
2599 let arr_data = ArrayData::builder(DataType::Int32)
2600 .len(16)
2601 .add_buffer(make_i32_buffer(16))
2602 .null_bit_buffer(Some(Buffer::from(bit_v)))
2603 .build()
2604 .unwrap();
2605 assert_eq!(13, arr_data.null_count());
2606
2607 let mut bit_v: [u8; 2] = [0; 2];
2609 bit_util::set_bit(&mut bit_v, 0);
2610 bit_util::set_bit(&mut bit_v, 3);
2611 bit_util::set_bit(&mut bit_v, 10);
2612 let arr_data = ArrayData::builder(DataType::Int32)
2613 .len(12)
2614 .offset(2)
2615 .add_buffer(make_i32_buffer(14)) .null_bit_buffer(Some(Buffer::from(bit_v)))
2617 .build()
2618 .unwrap();
2619 assert_eq!(10, arr_data.null_count());
2620 }
2621
2622 #[test]
2623 fn test_null_buffer_ref() {
2624 let mut bit_v: [u8; 2] = [0; 2];
2625 bit_util::set_bit(&mut bit_v, 0);
2626 bit_util::set_bit(&mut bit_v, 3);
2627 bit_util::set_bit(&mut bit_v, 10);
2628 let arr_data = ArrayData::builder(DataType::Int32)
2629 .len(16)
2630 .add_buffer(make_i32_buffer(16))
2631 .null_bit_buffer(Some(Buffer::from(bit_v)))
2632 .build()
2633 .unwrap();
2634 assert!(arr_data.nulls().is_some());
2635 assert_eq!(&bit_v, arr_data.nulls().unwrap().validity());
2636 }
2637
2638 #[test]
2639 fn test_slice() {
2640 let mut bit_v: [u8; 2] = [0; 2];
2641 bit_util::set_bit(&mut bit_v, 0);
2642 bit_util::set_bit(&mut bit_v, 3);
2643 bit_util::set_bit(&mut bit_v, 10);
2644 let data = ArrayData::builder(DataType::Int32)
2645 .len(16)
2646 .add_buffer(make_i32_buffer(16))
2647 .null_bit_buffer(Some(Buffer::from(bit_v)))
2648 .build()
2649 .unwrap();
2650 let new_data = data.slice(1, 15);
2651 assert_eq!(data.len() - 1, new_data.len());
2652 assert_eq!(1, new_data.offset());
2653 assert_eq!(data.null_count(), new_data.null_count());
2654
2655 let new_data = new_data.slice(1, 14);
2657 assert_eq!(data.len() - 2, new_data.len());
2658 assert_eq!(2, new_data.offset());
2659 assert_eq!(data.null_count() - 1, new_data.null_count());
2660 }
2661
2662 #[test]
2663 #[should_panic(expected = "offset + length overflow")]
2664 fn test_slice_panics_on_offset_length_overflow() {
2665 let data = ArrayData::builder(DataType::Int32)
2666 .len(4)
2667 .add_buffer(make_i32_buffer(4))
2668 .build()
2669 .unwrap();
2670 let sliced = data.slice(1, 3);
2671
2672 sliced.slice(1, usize::MAX);
2673 }
2674
2675 #[test]
2676 fn test_typed_offsets_length_overflow() {
2677 let data = ArrayData {
2678 data_type: DataType::Binary,
2679 len: usize::MAX,
2680 offset: 0,
2681 buffers: vec![Buffer::from_slice_ref([0_i32])],
2682 child_data: vec![],
2683 nulls: None,
2684 };
2685 let err = data.typed_offsets::<i32>().unwrap_err();
2686
2687 assert_eq!(
2688 err.to_string(),
2689 format!(
2690 "Invalid argument error: Length {} with offset 1 overflows usize for Binary",
2691 usize::MAX
2692 )
2693 );
2694 }
2695
2696 #[test]
2697 fn test_validate_typed_buffer_length_overflow() {
2698 let data = ArrayData {
2699 data_type: DataType::Binary,
2700 len: 0,
2701 offset: 2,
2702 buffers: vec![Buffer::from_slice_ref([0_i32])],
2703 child_data: vec![],
2704 nulls: None,
2705 };
2706 let err = data.typed_buffer::<i32>(0, usize::MAX).unwrap_err();
2707
2708 assert_eq!(
2709 err.to_string(),
2710 format!(
2711 "Invalid argument error: Length {} with offset 2 overflows usize for Binary",
2712 usize::MAX
2713 )
2714 );
2715 }
2716
2717 fn try_new_binary_length_offset_overflow() -> Result<ArrayData, ArrowError> {
2719 ArrayData::try_new(
2720 DataType::Binary,
2721 usize::MAX,
2722 None,
2723 1,
2724 vec![
2725 Buffer::from_slice_ref([0_i32]),
2726 Buffer::from_iter(std::iter::empty::<u8>()),
2727 ],
2728 vec![],
2729 )
2730 }
2731
2732 #[cfg(not(feature = "force_validate"))]
2733 #[test]
2734 fn test_try_new_length_offset_overflow() {
2735 let err = try_new_binary_length_offset_overflow().unwrap_err();
2736
2737 assert_eq!(
2738 err.to_string(),
2739 format!(
2740 "Invalid argument error: Length {} with offset 1 overflows usize for Binary",
2741 usize::MAX
2742 )
2743 );
2744 }
2745
2746 #[cfg(feature = "force_validate")]
2747 #[test]
2748 #[should_panic(
2749 expected = "Length 18446744073709551615 with offset 1 overflows usize for Binary"
2750 )]
2751 fn test_try_new_length_offset_overflow_force_validate() {
2752 try_new_binary_length_offset_overflow().unwrap();
2753 }
2754
2755 #[test]
2756 fn test_equality() {
2757 let int_data = ArrayData::builder(DataType::Int32)
2758 .len(1)
2759 .add_buffer(make_i32_buffer(1))
2760 .build()
2761 .unwrap();
2762
2763 let float_data = ArrayData::builder(DataType::Float32)
2764 .len(1)
2765 .add_buffer(make_f32_buffer(1))
2766 .build()
2767 .unwrap();
2768 assert_ne!(int_data, float_data);
2769 assert!(!int_data.ptr_eq(&float_data));
2770 assert!(int_data.ptr_eq(&int_data));
2771
2772 let int_data_clone = int_data.clone();
2773 assert_eq!(int_data, int_data_clone);
2774 assert!(int_data.ptr_eq(&int_data_clone));
2775 assert!(int_data_clone.ptr_eq(&int_data));
2776
2777 let int_data_slice = int_data_clone.slice(1, 0);
2778 assert!(int_data_slice.ptr_eq(&int_data_slice));
2779 assert!(!int_data.ptr_eq(&int_data_slice));
2780 assert!(!int_data_slice.ptr_eq(&int_data));
2781
2782 let data_buffer = Buffer::from_slice_ref(b"abcdef");
2783 let offsets_buffer = Buffer::from_slice_ref([0_i32, 2_i32, 2_i32, 5_i32]);
2784 let string_data = ArrayData::try_new(
2785 DataType::Utf8,
2786 3,
2787 Some(Buffer::from_iter(vec![true, false, true])),
2788 0,
2789 vec![offsets_buffer, data_buffer],
2790 vec![],
2791 )
2792 .unwrap();
2793
2794 assert_ne!(float_data, string_data);
2795 assert!(!float_data.ptr_eq(&string_data));
2796
2797 assert!(string_data.ptr_eq(&string_data));
2798
2799 let string_data_cloned = string_data.clone();
2800 assert!(string_data_cloned.ptr_eq(&string_data));
2801 assert!(string_data.ptr_eq(&string_data_cloned));
2802
2803 let string_data_slice = string_data.slice(1, 2);
2804 assert!(string_data_slice.ptr_eq(&string_data_slice));
2805 assert!(!string_data_slice.ptr_eq(&string_data))
2806 }
2807
2808 #[test]
2809 fn test_slice_memory_size_view_payload_buffers() {
2810 for data_type in [DataType::Utf8View, DataType::BinaryView] {
2811 let inline_only = ArrayData::builder(data_type.clone())
2812 .len(2)
2813 .add_buffer(Buffer::from_vec(vec![0_u128; 2]))
2814 .build()
2815 .unwrap();
2816 assert_eq!(
2817 inline_only.get_slice_memory_size().unwrap(),
2818 2 * mem::size_of::<u128>()
2819 );
2820
2821 let mut first_payload = Vec::with_capacity(32);
2822 first_payload.extend_from_slice(b"first payload");
2823 let first_view =
2824 ByteView::new(first_payload.len().try_into().unwrap(), &first_payload[..4])
2825 .as_u128();
2826 let first_payload = Buffer::from_vec(first_payload);
2827 assert!(first_payload.capacity() > first_payload.len());
2828 let first_payload_capacity = first_payload.capacity();
2829
2830 let mut second_payload = Vec::with_capacity(64);
2831 second_payload.extend_from_slice(b"second payload");
2832 let second_view = ByteView::new(
2833 second_payload.len().try_into().unwrap(),
2834 &second_payload[..4],
2835 )
2836 .with_buffer_index(1)
2837 .as_u128();
2838 let second_payload = Buffer::from_vec(second_payload);
2839 assert!(second_payload.capacity() > second_payload.len());
2840 let second_payload_capacity = second_payload.capacity();
2841
2842 let data = ArrayData::builder(data_type)
2843 .len(3)
2844 .add_buffer(Buffer::from_vec(vec![first_view, 0_u128, second_view]))
2845 .add_buffer(first_payload)
2846 .add_buffer(second_payload)
2847 .build()
2848 .unwrap();
2849 let sliced = data.slice(1, 1);
2850
2851 assert_eq!(
2852 sliced.get_slice_memory_size().unwrap(),
2853 mem::size_of::<u128>() + first_payload_capacity + second_payload_capacity
2854 );
2855 }
2856 }
2857
2858 #[test]
2859 fn test_slice_memory_size_utf8_offset_buffer_len_plus_one() {
2860 let data_buffer = Buffer::from_slice_ref(b"helloworld");
2862 let offsets_buffer = Buffer::from_slice_ref([0_i32, 5_i32, 10_i32]);
2865 let array = ArrayData::try_new(
2866 DataType::Utf8,
2867 2,
2868 None,
2869 0,
2870 vec![offsets_buffer, data_buffer],
2871 vec![],
2872 )
2873 .unwrap();
2874 assert_eq!(array.get_slice_memory_size().unwrap(), 22); }
2876
2877 #[test]
2878 fn test_slice_memory_size_binary_offset_buffer_len_plus_one() {
2879 let data_buffer = Buffer::from_slice_ref([0u8, 1, 2, 3, 4]);
2882 let offsets_buffer = Buffer::from_slice_ref([0_i32, 2_i32, 5_i32]);
2884 let array = ArrayData::try_new(
2885 DataType::Binary,
2886 2,
2887 None,
2888 0,
2889 vec![offsets_buffer, data_buffer],
2890 vec![],
2891 )
2892 .unwrap();
2893 assert_eq!(array.get_slice_memory_size().unwrap(), 17); }
2895
2896 #[test]
2897 fn test_slice_memory_size() {
2898 let mut bit_v: [u8; 2] = [0; 2];
2899 bit_util::set_bit(&mut bit_v, 0);
2900 bit_util::set_bit(&mut bit_v, 3);
2901 bit_util::set_bit(&mut bit_v, 10);
2902 let data = ArrayData::builder(DataType::Int32)
2903 .len(16)
2904 .add_buffer(make_i32_buffer(16))
2905 .null_bit_buffer(Some(Buffer::from(bit_v)))
2906 .build()
2907 .unwrap();
2908 let new_data = data.slice(1, 14);
2909 assert_eq!(
2910 data.get_slice_memory_size().unwrap() - 8,
2911 new_data.get_slice_memory_size().unwrap()
2912 );
2913 let data_buffer = Buffer::from_slice_ref(b"abcdef");
2914 let offsets_buffer = Buffer::from_slice_ref([0_i32, 2_i32, 2_i32, 5_i32]);
2915 let string_data = ArrayData::try_new(
2916 DataType::Utf8,
2917 3,
2918 Some(Buffer::from_iter(vec![true, false, true])),
2919 0,
2920 vec![offsets_buffer, data_buffer],
2921 vec![],
2922 )
2923 .unwrap();
2924 let string_data_slice = string_data.slice(1, 2);
2925 assert_eq!(
2927 string_data.get_slice_memory_size().unwrap() - 6,
2928 string_data_slice.get_slice_memory_size().unwrap()
2929 );
2930 }
2931
2932 #[test]
2933 fn test_count_nulls() {
2934 let buffer = Buffer::from([0b00010110, 0b10011111]);
2935 let buffer = NullBuffer::new(BooleanBuffer::new(buffer, 0, 16));
2936 let count = count_nulls(Some(&buffer), 0, 16);
2937 assert_eq!(count, 7);
2938
2939 let count = count_nulls(Some(&buffer), 4, 8);
2940 assert_eq!(count, 3);
2941 }
2942
2943 #[test]
2944 fn test_contains_nulls() {
2945 let buffer: Buffer =
2946 MutableBuffer::from_iter([false, false, false, true, true, false]).into();
2947 let buffer = NullBuffer::new(BooleanBuffer::new(buffer, 0, 6));
2948 assert!(contains_nulls(Some(&buffer), 0, 6));
2949 assert!(contains_nulls(Some(&buffer), 0, 3));
2950 assert!(!contains_nulls(Some(&buffer), 3, 2));
2951 assert!(!contains_nulls(Some(&buffer), 0, 0));
2952 }
2953
2954 #[test]
2955 fn test_alignment() {
2956 let buffer = Buffer::from_vec(vec![1_i32, 2_i32, 3_i32]);
2957 let sliced = buffer.slice(1);
2958
2959 let mut data = ArrayData {
2960 data_type: DataType::Int32,
2961 len: 0,
2962 offset: 0,
2963 buffers: vec![buffer],
2964 child_data: vec![],
2965 nulls: None,
2966 };
2967 data.validate_full().unwrap();
2968
2969 data.buffers[0] = sliced;
2971 let err = data.validate().unwrap_err();
2972
2973 assert_eq!(
2974 err.to_string(),
2975 "Invalid argument error: Misaligned buffers[0] in array of type Int32, offset from expected alignment of 4 by 1"
2976 );
2977
2978 data.align_buffers();
2979 data.validate_full().unwrap();
2980 }
2981
2982 #[test]
2983 fn test_alignment_struct() {
2984 let buffer = Buffer::from_vec(vec![1_i32, 2_i32, 3_i32]);
2985 let sliced = buffer.slice(1);
2986
2987 let child_data = ArrayData {
2988 data_type: DataType::Int32,
2989 len: 0,
2990 offset: 0,
2991 buffers: vec![buffer],
2992 child_data: vec![],
2993 nulls: None,
2994 };
2995
2996 let schema = DataType::Struct(Fields::from(vec![Field::new("a", DataType::Int32, false)]));
2997 let mut data = ArrayData {
2998 data_type: schema,
2999 len: 0,
3000 offset: 0,
3001 buffers: vec![],
3002 child_data: vec![child_data],
3003 nulls: None,
3004 };
3005 data.validate_full().unwrap();
3006
3007 data.child_data[0].buffers[0] = sliced;
3009 let err = data.validate().unwrap_err();
3010
3011 assert_eq!(
3012 err.to_string(),
3013 "Invalid argument error: Misaligned buffers[0] in array of type Int32, offset from expected alignment of 4 by 1"
3014 );
3015
3016 data.align_buffers();
3017 data.validate_full().unwrap();
3018 }
3019
3020 #[test]
3021 fn test_null_view_types() {
3022 let array_len = 32;
3023 let array = ArrayData::new_null(&DataType::BinaryView, array_len);
3024 assert_eq!(array.len(), array_len);
3025 for i in 0..array.len() {
3026 assert!(array.is_null(i));
3027 }
3028
3029 let array = ArrayData::new_null(&DataType::Utf8View, array_len);
3030 assert_eq!(array.len(), array_len);
3031 for i in 0..array.len() {
3032 assert!(array.is_null(i));
3033 }
3034
3035 let array = ArrayData::new_null(
3036 &DataType::ListView(Arc::new(Field::new_list_field(DataType::Int32, true))),
3037 array_len,
3038 );
3039 assert_eq!(array.len(), array_len);
3040 for i in 0..array.len() {
3041 assert!(array.is_null(i));
3042 }
3043
3044 let array = ArrayData::new_null(
3045 &DataType::LargeListView(Arc::new(Field::new_list_field(DataType::Int32, true))),
3046 array_len,
3047 );
3048 assert_eq!(array.len(), array_len);
3049 for i in 0..array.len() {
3050 assert!(array.is_null(i));
3051 }
3052 }
3053
3054 #[test]
3056 fn test_dont_panic_on_bad_input_when_using_try_new() {
3057 let empty_bytes = Buffer::default();
3058
3059 let array_data = ArrayData::try_new(
3060 DataType::Utf8,
3061 1, None,
3063 0,
3064 vec![Buffer::from_vec(vec![0i32, 2i32]), empty_bytes],
3066 vec![],
3067 );
3068
3069 let res = array_data.expect_err("should get error");
3070
3071 assert_eq!(
3072 res.to_string(),
3073 format!("Invalid argument error: Last offset 2 of Utf8 is larger than values length 0",)
3074 );
3075 }
3076
3077 #[test]
3080 #[cfg(not(feature = "force_validate"))]
3081 fn test_validate_values_rejects_a_non_integer_dictionary_key() {
3082 let values = valid_non_nullable_int32_array_data(2);
3083 let data_type = DataType::Dictionary(Box::new(DataType::Utf8), Box::new(DataType::Int32));
3084 let dictionary = unsafe {
3085 ArrayData::builder(data_type)
3086 .len(1)
3087 .add_child_data(values)
3088 .build_unchecked()
3089 };
3090
3091 let err = dictionary.validate_values().expect_err("should get error");
3092 assert_eq!(
3093 err.to_string(),
3094 "Invalid argument error: Dictionary key type must be an integer, got Utf8"
3095 );
3096 }
3097
3098 #[test]
3099 #[cfg(not(feature = "force_validate"))]
3100 fn test_validate_values_rejects_a_non_integer_run_end() {
3101 let data_type = DataType::RunEndEncoded(
3102 Arc::new(Field::new("run_ends", DataType::Utf8, false)),
3103 Arc::new(Field::new("values", DataType::Int32, true)),
3104 );
3105 let run_end_encoded = unsafe {
3106 ArrayData::builder(data_type)
3107 .len(1)
3108 .add_child_data(valid_non_nullable_int32_array_data(1))
3109 .add_child_data(valid_non_nullable_int32_array_data(1))
3110 .build_unchecked()
3111 };
3112
3113 let err = run_end_encoded
3114 .validate_values()
3115 .expect_err("should get error");
3116 assert_eq!(
3117 err.to_string(),
3118 "Invalid argument error: Run end type must be Int16, Int32 or Int64, got Utf8"
3119 );
3120 }
3121
3122 #[test]
3124 #[cfg(not(feature = "force_validate"))]
3125 fn test_validate_values_rejects_missing_child_data() {
3126 let int32 = Box::new(DataType::Int32);
3127 let field = || Arc::new(Field::new("f", DataType::Int32, true));
3128 let data_types = [
3129 DataType::Dictionary(int32.clone(), int32.clone()),
3130 DataType::List(field()),
3131 DataType::LargeList(field()),
3132 DataType::RunEndEncoded(field(), field()),
3133 ];
3134
3135 for data_type in data_types {
3136 let data = unsafe {
3137 ArrayData::builder(data_type.clone())
3138 .len(1)
3139 .build_unchecked()
3140 };
3141 let err = data.validate_values().expect_err("should get error");
3142 assert_eq!(
3143 err.to_string(),
3144 format!(
3145 "Invalid argument error: {data_type} should contain at least 1 child data array(s), had 0"
3146 )
3147 );
3148 }
3149 }
3150
3151 #[test]
3153 #[cfg(not(feature = "force_validate"))]
3154 fn test_validate_values_rejects_missing_buffers() {
3155 let cases = [
3157 (DataType::Utf8, 1),
3158 (DataType::LargeUtf8, 1),
3159 (DataType::Binary, 1),
3160 (DataType::LargeBinary, 1),
3161 (DataType::BinaryView, 0),
3162 (DataType::Utf8View, 0),
3163 ];
3164
3165 for (data_type, missing) in cases {
3166 let data = unsafe {
3167 ArrayData::builder(data_type.clone())
3168 .len(1)
3169 .build_unchecked()
3170 };
3171 let err = data.validate_values().expect_err("should get error");
3172 assert_eq!(
3173 err.to_string(),
3174 format!(
3175 "Invalid argument error: {data_type} should contain at least {} buffer(s), had 0",
3176 missing + 1
3177 )
3178 );
3179 }
3180 }
3181
3182 #[test]
3184 #[cfg(not(feature = "force_validate"))]
3185 fn test_validate_values_rejects_a_short_dictionary_keys_buffer() {
3186 let data_type = DataType::Dictionary(Box::new(DataType::Int32), Box::new(DataType::Int32));
3187 let dictionary = unsafe {
3188 ArrayData::builder(data_type)
3189 .len(4)
3190 .add_buffer(Buffer::from_slice_ref([1_i32, 0]))
3191 .add_child_data(valid_non_nullable_int32_array_data(2))
3192 .build_unchecked()
3193 };
3194
3195 let err = dictionary.validate_values().expect_err("should get error");
3196 assert_eq!(
3197 err.to_string(),
3198 "Invalid argument error: Buffer 0 of Dictionary(Int32, Int32) isn't large enough. Expected 16 bytes got 8"
3199 );
3200 }
3201
3202 #[test]
3203 fn should_fail_validation_when_having_map_field_type_is_not_struct() {
3204 let map_field = Field::new("key", DataType::Int32, false);
3205
3206 let map_field_data = valid_non_nullable_int32_array_data(2);
3207
3208 let results = test_both_builder_and_array_data(
3209 DataType::Map(map_field.into(), false),
3210 1,
3211 None,
3212 0,
3213 vec![
3214 OffsetBuffer::<i32>::from_lengths(vec![2])
3215 .into_inner()
3216 .into(),
3217 ],
3218 vec![map_field_data],
3219 );
3220
3221 for result in results {
3222 let array_data_err = result.expect_err("should fail for non struct field");
3223
3224 match array_data_err {
3225 ArrowError::InvalidArgumentError(msg) => {
3226 assert_eq!(
3227 msg,
3228 "Map field should be a entries struct data type, got Int32 instead"
3229 )
3230 }
3231 _ => panic!("unexpected error type {array_data_err}"),
3232 }
3233 }
3234 }
3235
3236 #[test]
3237 fn should_fail_validation_when_having_map_entries_only_have_1_field() {
3238 let struct_data_type = DataType::Struct(Fields::from(vec![Field::new(
3239 Field::MAP_KEY_FIELD_DEFAULT_NAME,
3240 DataType::Int32,
3241 false,
3242 )]));
3243
3244 let key_array_data = valid_non_nullable_int32_array_data(2);
3245
3246 let struct_data = {
3247 let builder = ArrayDataBuilder::new(struct_data_type.clone())
3248 .len(2)
3249 .nulls(None)
3250 .child_data(vec![key_array_data]);
3251
3252 builder.build().unwrap()
3253 };
3254
3255 let results = test_both_builder_and_array_data(
3256 DataType::Map(
3257 Field::new(
3258 Field::MAP_ENTRIES_FIELD_DEFAULT_NAME,
3259 struct_data_type,
3260 false,
3261 )
3262 .into(),
3263 false,
3264 ),
3265 1,
3266 None,
3267 0,
3268 vec![
3269 OffsetBuffer::<i32>::from_lengths(vec![2])
3270 .into_inner()
3271 .into(),
3272 ],
3273 vec![struct_data],
3274 );
3275
3276 for result in results {
3277 let array_data_err = result.expect_err("should fail for nullable key");
3278
3279 match array_data_err {
3280 ArrowError::InvalidArgumentError(msg) => {
3281 assert_eq!(
3282 msg,
3283 "Map entries data type should be a struct containing 2 fields, got 1 fields"
3284 )
3285 }
3286 _ => panic!("unexpected error type {array_data_err}"),
3287 }
3288 }
3289 }
3290
3291 #[test]
3292 fn should_fail_validation_when_having_map_entries_have_3_fields() {
3293 let struct_data_type = DataType::Struct(Fields::from(vec![
3294 Field::new(Field::MAP_KEY_FIELD_DEFAULT_NAME, DataType::Int32, false),
3295 Field::new(Field::MAP_VALUE_FIELD_DEFAULT_NAME, DataType::Utf8, true),
3296 Field::new("other", DataType::Int32, true),
3297 ]));
3298
3299 let key_array_data = valid_non_nullable_int32_array_data(2);
3300
3301 let values_array_data = valid_string_array_data(2);
3302
3303 let other_array_data = key_array_data.clone();
3304
3305 let struct_data = {
3306 let builder = ArrayDataBuilder::new(struct_data_type.clone())
3307 .len(2)
3308 .nulls(None)
3309 .child_data(vec![key_array_data, values_array_data, other_array_data]);
3310
3311 builder.build().unwrap()
3312 };
3313
3314 let results = test_both_builder_and_array_data(
3315 DataType::Map(
3316 Field::new(
3317 Field::MAP_ENTRIES_FIELD_DEFAULT_NAME,
3318 struct_data_type,
3319 false,
3320 )
3321 .into(),
3322 false,
3323 ),
3324 1,
3325 None,
3326 0,
3327 vec![
3328 OffsetBuffer::<i32>::from_lengths(vec![2])
3329 .into_inner()
3330 .into(),
3331 ],
3332 vec![struct_data],
3333 );
3334
3335 for result in results {
3336 let array_data_err = result.expect_err("should fail for nullable key");
3337
3338 match array_data_err {
3339 ArrowError::InvalidArgumentError(msg) => {
3340 assert_eq!(
3341 msg,
3342 "Map entries data type should be a struct containing 2 fields, got 3 fields"
3343 )
3344 }
3345 _ => panic!("unexpected error type {array_data_err}"),
3346 }
3347 }
3348 }
3349
3350 #[test]
3351 fn should_fail_validation_when_having_nullable_map_keys() {
3352 let struct_data_type = DataType::Struct(Fields::from(vec![
3353 Field::new(Field::MAP_KEY_FIELD_DEFAULT_NAME, DataType::Int32, true),
3354 Field::new(Field::MAP_VALUE_FIELD_DEFAULT_NAME, DataType::Utf8, true),
3355 ]));
3356
3357 let key_array_data = valid_non_nullable_int32_array_data(2);
3358 let values_array_data = valid_string_array_data(2);
3359
3360 let struct_data = {
3361 let builder = ArrayDataBuilder::new(struct_data_type.clone())
3362 .len(2)
3363 .nulls(None)
3364 .child_data(vec![key_array_data, values_array_data]);
3365
3366 builder.build().unwrap()
3367 };
3368
3369 let results = test_both_builder_and_array_data(
3370 DataType::Map(
3371 Field::new(
3372 Field::MAP_ENTRIES_FIELD_DEFAULT_NAME,
3373 struct_data_type,
3374 false,
3375 )
3376 .into(),
3377 false,
3378 ),
3379 1,
3380 None,
3381 0,
3382 vec![
3383 OffsetBuffer::<i32>::from_lengths(vec![2])
3384 .into_inner()
3385 .into(),
3386 ],
3387 vec![struct_data],
3388 );
3389
3390 for result in results {
3391 let array_data_err = result.expect_err("should fail for nullable key");
3392
3393 match array_data_err {
3394 ArrowError::InvalidArgumentError(msg) => {
3395 assert_eq!(msg, "Map key field must not be nullable")
3396 }
3397 _ => panic!("unexpected error type {array_data_err}"),
3398 }
3399 }
3400 }
3401
3402 #[test]
3403 fn should_fail_validation_when_having_entries_is_nullable_for_map() {
3404 let struct_data_type = DataType::Struct(Fields::from(vec![
3405 Field::new(Field::MAP_KEY_FIELD_DEFAULT_NAME, DataType::Int32, false),
3406 Field::new(Field::MAP_VALUE_FIELD_DEFAULT_NAME, DataType::Utf8, true),
3407 ]));
3408
3409 let key_array_data = valid_non_nullable_int32_array_data(2);
3410
3411 let values_array_data = valid_string_array_data(2);
3412
3413 let struct_data = {
3414 let builder = ArrayDataBuilder::new(struct_data_type.clone())
3415 .len(2)
3416 .nulls(None)
3417 .child_data(vec![key_array_data, values_array_data]);
3418
3419 builder.build().unwrap()
3420 };
3421
3422 let results = test_both_builder_and_array_data(
3423 DataType::Map(
3424 Field::new(
3425 Field::MAP_ENTRIES_FIELD_DEFAULT_NAME,
3426 struct_data_type,
3427 true,
3428 )
3429 .into(),
3430 false,
3431 ),
3432 1,
3433 None,
3434 0,
3435 vec![
3436 OffsetBuffer::<i32>::from_lengths(vec![2])
3437 .into_inner()
3438 .into(),
3439 ],
3440 vec![struct_data],
3441 );
3442
3443 for result in results {
3444 let array_data_err = result.expect_err("should fail for nullable entries");
3445
3446 match array_data_err {
3447 ArrowError::InvalidArgumentError(msg) => assert_eq!(
3448 msg,
3449 "The nullable should be set to false for the map entries field."
3450 ),
3451 _ => panic!("unexpected error type {array_data_err}"),
3452 }
3453 }
3454 }
3455
3456 #[test]
3457 fn should_allow_to_create_map_from_data() {
3458 let struct_data_type = DataType::Struct(Fields::from(vec![
3459 Field::new(Field::MAP_KEY_FIELD_DEFAULT_NAME, DataType::Int32, false),
3460 Field::new(Field::MAP_VALUE_FIELD_DEFAULT_NAME, DataType::Utf8, true),
3461 ]));
3462
3463 let key_array_data = valid_non_nullable_int32_array_data(2);
3464 let values_array_data = valid_string_array_data(2);
3465
3466 let struct_data = {
3467 let builder = ArrayDataBuilder::new(struct_data_type.clone())
3468 .len(2)
3469 .nulls(None)
3470 .child_data(vec![key_array_data, values_array_data]);
3471
3472 builder.build().unwrap()
3473 };
3474
3475 let results = test_both_builder_and_array_data(
3476 DataType::Map(
3477 Field::new(
3478 Field::MAP_ENTRIES_FIELD_DEFAULT_NAME,
3479 struct_data_type,
3480 false,
3481 )
3482 .into(),
3483 false,
3484 ),
3485 1,
3486 None,
3487 0,
3488 vec![
3489 OffsetBuffer::<i32>::from_lengths(vec![2])
3490 .into_inner()
3491 .into(),
3492 ],
3493 vec![struct_data],
3494 );
3495
3496 for result in results {
3497 result.expect("should be able to create map ArrayData");
3498 }
3499 }
3500
3501 fn valid_string_array_data(length: usize) -> ArrayData {
3502 let offsets = OffsetBuffer::<i32>::from_lengths(vec![0; length])
3503 .into_inner()
3504 .into_inner();
3505 let empty_bytes = Buffer::default();
3506
3507 let builder = ArrayDataBuilder::new(DataType::Utf8)
3508 .len(length)
3509 .buffers(vec![offsets, empty_bytes])
3510 .nulls(None);
3511
3512 builder.build().unwrap()
3513 }
3514
3515 fn valid_non_nullable_int32_array_data(length: usize) -> ArrayData {
3516 let builder = ArrayDataBuilder::new(DataType::Int32)
3517 .len(length)
3518 .nulls(None)
3519 .buffers(vec![
3520 ScalarBuffer::<i32>::from(vec![1; length]).into_inner(),
3521 ]);
3522
3523 builder.build().unwrap()
3524 }
3525
3526 #[test]
3527 fn empty_and_null_map_array_should_pass_validation() {
3528 let dt = DataType::Map(
3529 Field::new(
3530 Field::MAP_ENTRIES_FIELD_DEFAULT_NAME,
3531 DataType::Struct(Fields::from(vec![
3532 Field::new(Field::MAP_KEY_FIELD_DEFAULT_NAME, DataType::Int32, false),
3533 Field::new(Field::MAP_VALUE_FIELD_DEFAULT_NAME, DataType::Utf8, true),
3534 ])),
3535 false,
3536 )
3537 .into(),
3538 false,
3539 );
3540
3541 ArrayData::new_empty(&dt).validate_full().unwrap();
3542 ArrayData::new_null(&dt, 1).validate_full().unwrap();
3543 }
3544
3545 fn test_both_builder_and_array_data(
3546 data_type: DataType,
3547 len: usize,
3548 null_bit_buffer: Option<Buffer>,
3549 offset: usize,
3550 buffers: Vec<Buffer>,
3551 child_data: Vec<ArrayData>,
3552 ) -> [Result<ArrayData, ArrowError>; 2] {
3553 let from_builder_res = ArrayData::builder(data_type.clone())
3554 .len(len)
3555 .add_buffers(buffers.clone())
3556 .null_bit_buffer(null_bit_buffer.clone())
3557 .offset(offset)
3558 .child_data(child_data.clone())
3559 .build();
3560
3561 let from_try_new_res =
3562 ArrayData::try_new(data_type, len, null_bit_buffer, offset, buffers, child_data);
3563
3564 [from_builder_res, from_try_new_res]
3565 }
3566}