1use crate::array::{get_offsets_from_buffer, make_array, print_long_array};
19use crate::builder::{ArrayBuilder, GenericListBuilder, PrimitiveBuilder};
20use crate::{
21 Array, ArrayAccessor, ArrayRef, ArrowPrimitiveType, FixedSizeListArray,
22 iterator::GenericListArrayIter, new_empty_array,
23};
24use arrow_buffer::{ArrowNativeType, NullBuffer, OffsetBuffer};
25use arrow_data::{ArrayData, ArrayDataBuilder};
26use arrow_schema::{ArrowError, DataType, FieldRef};
27use num_integer::Integer;
28use std::any::Any;
29use std::sync::Arc;
30
31pub trait OffsetSizeTrait:
41 ArrowNativeType + std::ops::AddAssign + Integer + num_traits::CheckedAdd + num_traits::CheckedSub
42{
43 const IS_LARGE: bool;
45 const PREFIX: &'static str;
47 const MAX_OFFSET: usize;
49}
50
51impl OffsetSizeTrait for i32 {
52 const IS_LARGE: bool = false;
53 const PREFIX: &'static str = "";
54 const MAX_OFFSET: usize = i32::MAX as usize;
55}
56
57impl OffsetSizeTrait for i64 {
58 const IS_LARGE: bool = true;
59 const PREFIX: &'static str = "Large";
60 const MAX_OFFSET: usize = i64::MAX as usize;
61}
62
63pub struct GenericListArray<OffsetSize: OffsetSizeTrait> {
172 data_type: DataType,
173 nulls: Option<NullBuffer>,
174 values: ArrayRef,
175 value_offsets: OffsetBuffer<OffsetSize>,
176}
177
178impl<OffsetSize: OffsetSizeTrait> Clone for GenericListArray<OffsetSize> {
179 fn clone(&self) -> Self {
180 Self {
181 data_type: self.data_type.clone(),
182 nulls: self.nulls.clone(),
183 values: self.values.clone(),
184 value_offsets: self.value_offsets.clone(),
185 }
186 }
187}
188
189impl<OffsetSize: OffsetSizeTrait> GenericListArray<OffsetSize> {
190 pub const DATA_TYPE_CONSTRUCTOR: fn(FieldRef) -> DataType = if OffsetSize::IS_LARGE {
194 DataType::LargeList
195 } else {
196 DataType::List
197 };
198
199 pub fn try_new(
210 field: FieldRef,
211 offsets: OffsetBuffer<OffsetSize>,
212 values: ArrayRef,
213 nulls: Option<NullBuffer>,
214 ) -> Result<Self, ArrowError> {
215 let len = offsets.len() - 1; let end_offset = offsets.last().unwrap().as_usize();
217 if end_offset > values.len() {
220 return Err(ArrowError::InvalidArgumentError(format!(
221 "Max offset of {end_offset} exceeds length of values {}",
222 values.len()
223 )));
224 }
225
226 if let Some(n) = nulls.as_ref() {
227 if n.len() != len {
228 return Err(ArrowError::InvalidArgumentError(format!(
229 "Incorrect length of null buffer for {}ListArray, expected {len} got {}",
230 OffsetSize::PREFIX,
231 n.len(),
232 )));
233 }
234 }
235 if !field.is_nullable() && values.is_nullable() {
236 return Err(ArrowError::InvalidArgumentError(format!(
237 "Non-nullable field of {}ListArray {:?} cannot contain nulls",
238 OffsetSize::PREFIX,
239 field.name()
240 )));
241 }
242
243 if field.data_type() != values.data_type() {
244 return Err(ArrowError::InvalidArgumentError(format!(
245 "{}ListArray expected data type {} got {} for {:?}",
246 OffsetSize::PREFIX,
247 field.data_type(),
248 values.data_type(),
249 field.name()
250 )));
251 }
252
253 Ok(Self {
254 data_type: Self::DATA_TYPE_CONSTRUCTOR(field),
255 nulls,
256 values,
257 value_offsets: offsets,
258 })
259 }
260
261 pub fn new(
267 field: FieldRef,
268 offsets: OffsetBuffer<OffsetSize>,
269 values: ArrayRef,
270 nulls: Option<NullBuffer>,
271 ) -> Self {
272 Self::try_new(field, offsets, values, nulls).unwrap()
273 }
274
275 pub unsafe fn new_unchecked(
282 field: FieldRef,
283 offsets: OffsetBuffer<OffsetSize>,
284 values: ArrayRef,
285 nulls: Option<NullBuffer>,
286 ) -> Self {
287 if cfg!(feature = "force_validate") {
288 return Self::new(field, offsets, values, nulls);
289 }
290 Self {
291 data_type: Self::DATA_TYPE_CONSTRUCTOR(field),
292 nulls,
293 values,
294 value_offsets: offsets,
295 }
296 }
297
298 pub fn new_null(field: FieldRef, len: usize) -> Self {
300 let values = new_empty_array(field.data_type());
301 Self {
302 data_type: Self::DATA_TYPE_CONSTRUCTOR(field),
303 nulls: Some(NullBuffer::new_null(len)),
304 value_offsets: OffsetBuffer::new_zeroed(len),
305 values,
306 }
307 }
308
309 pub fn into_parts(
311 self,
312 ) -> (
313 FieldRef,
314 OffsetBuffer<OffsetSize>,
315 ArrayRef,
316 Option<NullBuffer>,
317 ) {
318 let f = match self.data_type {
319 DataType::List(f) | DataType::LargeList(f) => f,
320 _ => unreachable!(),
321 };
322 (f, self.value_offsets, self.values, self.nulls)
323 }
324
325 #[inline]
334 pub fn offsets(&self) -> &OffsetBuffer<OffsetSize> {
335 &self.value_offsets
336 }
337
338 #[inline]
345 pub fn values(&self) -> &ArrayRef {
346 &self.values
347 }
348
349 pub fn value_type(&self) -> DataType {
351 self.values.data_type().clone()
352 }
353
354 pub unsafe fn value_unchecked(&self, i: usize) -> ArrayRef {
362 let end = unsafe { self.value_offsets().get_unchecked(i + 1).as_usize() };
363 let start = unsafe { self.value_offsets().get_unchecked(i).as_usize() };
364 self.values.slice(start, end - start)
365 }
366
367 pub fn value(&self, i: usize) -> ArrayRef {
375 let end = self.value_offsets()[i + 1].as_usize();
376 let start = self.value_offsets()[i].as_usize();
377 self.values.slice(start, end - start)
378 }
379
380 #[inline]
384 pub fn value_offsets(&self) -> &[OffsetSize] {
385 &self.value_offsets
386 }
387
388 #[inline]
390 pub fn value_length(&self, i: usize) -> OffsetSize {
391 let offsets = self.value_offsets();
392 offsets[i + 1] - offsets[i]
393 }
394
395 pub fn iter<'a>(&'a self) -> GenericListArrayIter<'a, OffsetSize> {
397 GenericListArrayIter::<'a, OffsetSize>::new(self)
398 }
399
400 #[inline]
401 fn get_type(data_type: &DataType) -> Option<&DataType> {
402 match (OffsetSize::IS_LARGE, data_type) {
403 (true, DataType::LargeList(child)) | (false, DataType::List(child)) => {
404 Some(child.data_type())
405 }
406 _ => None,
407 }
408 }
409
410 pub fn slice(&self, offset: usize, length: usize) -> Self {
416 Self {
417 data_type: self.data_type.clone(),
418 nulls: self.nulls.as_ref().map(|n| n.slice(offset, length)),
419 values: self.values.clone(),
420 value_offsets: self.value_offsets.slice(offset, length),
421 }
422 }
423
424 pub fn from_iter_primitive<T, P, I>(iter: I) -> Self
440 where
441 T: ArrowPrimitiveType,
442 P: IntoIterator<Item = Option<<T as ArrowPrimitiveType>::Native>>,
443 I: IntoIterator<Item = Option<P>>,
444 {
445 Self::from_nested_iter::<PrimitiveBuilder<T>, T::Native, P, I>(iter)
446 }
447
448 pub fn from_nested_iter<B, T, P, I>(iter: I) -> Self
468 where
469 B: ArrayBuilder + Default + Extend<Option<T>>,
470 P: IntoIterator<Item = Option<T>>,
471 I: IntoIterator<Item = Option<P>>,
472 {
473 let iter = iter.into_iter();
474 let size_hint = iter.size_hint().0;
475 let mut builder = GenericListBuilder::with_capacity(B::default(), size_hint);
476
477 for i in iter {
478 match i {
479 Some(p) => {
480 builder.values().extend(p);
481 builder.append(true);
482 }
483 None => builder.append(false),
484 }
485 }
486 builder.finish()
487 }
488}
489
490impl<OffsetSize: OffsetSizeTrait> From<ArrayData> for GenericListArray<OffsetSize> {
491 fn from(data: ArrayData) -> Self {
492 Self::try_new_from_array_data(data)
493 .expect("Expected infallible creation of GenericListArray from ArrayDataRef failed")
494 }
495}
496
497impl<OffsetSize: OffsetSizeTrait> From<GenericListArray<OffsetSize>> for ArrayData {
498 fn from(array: GenericListArray<OffsetSize>) -> Self {
499 let len = array.len();
500 let builder = ArrayDataBuilder::new(array.data_type)
501 .len(len)
502 .nulls(array.nulls)
503 .buffers(vec![array.value_offsets.into_inner().into_inner()])
504 .child_data(vec![array.values.to_data()]);
505
506 unsafe { builder.build_unchecked() }
507 }
508}
509
510impl<OffsetSize: OffsetSizeTrait> From<FixedSizeListArray> for GenericListArray<OffsetSize> {
511 fn from(value: FixedSizeListArray) -> Self {
512 let (field, size) = match value.data_type() {
513 DataType::FixedSizeList(f, size) => (f, *size as usize),
514 _ => unreachable!(),
515 };
516
517 let offsets = OffsetBuffer::from_repeated_length(size, value.len());
518
519 Self {
520 data_type: Self::DATA_TYPE_CONSTRUCTOR(field.clone()),
521 nulls: value.nulls().cloned(),
522 values: value.values().clone(),
523 value_offsets: offsets,
524 }
525 }
526}
527
528impl<OffsetSize: OffsetSizeTrait> GenericListArray<OffsetSize> {
529 fn try_new_from_array_data(data: ArrayData) -> Result<Self, ArrowError> {
530 let (data_type, len, nulls, offset, mut buffers, mut child_data) = data.into_parts();
531
532 if buffers.len() != 1 {
533 return Err(ArrowError::InvalidArgumentError(format!(
534 "ListArray data should contain a single buffer only (value offsets), had {}",
535 buffers.len()
536 )));
537 }
538 let buffer = buffers.pop().expect("checked above");
539
540 if child_data.len() != 1 {
541 return Err(ArrowError::InvalidArgumentError(format!(
542 "ListArray should contain a single child array (values array), had {}",
543 child_data.len()
544 )));
545 }
546
547 let values = child_data.pop().expect("checked above");
548
549 if let Some(child_data_type) = Self::get_type(&data_type) {
550 if values.data_type() != child_data_type {
551 return Err(ArrowError::InvalidArgumentError(format!(
552 "[Large]ListArray's child datatype {:?} does not \
553 correspond to the List's datatype {:?}",
554 values.data_type(),
555 child_data_type
556 )));
557 }
558 } else {
559 return Err(ArrowError::InvalidArgumentError(format!(
560 "[Large]ListArray's datatype must be [Large]ListArray(). It is {data_type:?}",
561 )));
562 }
563
564 let values = make_array(values);
565 let value_offsets = unsafe { get_offsets_from_buffer(buffer, offset, len) };
568
569 Ok(Self {
570 data_type,
571 nulls,
572 values,
573 value_offsets,
574 })
575 }
576}
577
578unsafe impl<OffsetSize: OffsetSizeTrait> Array for GenericListArray<OffsetSize> {
580 fn as_any(&self) -> &dyn Any {
581 self
582 }
583
584 fn to_data(&self) -> ArrayData {
585 self.clone().into()
586 }
587
588 fn into_data(self) -> ArrayData {
589 self.into()
590 }
591
592 fn data_type(&self) -> &DataType {
593 &self.data_type
594 }
595
596 fn slice(&self, offset: usize, length: usize) -> ArrayRef {
597 Arc::new(self.slice(offset, length))
598 }
599
600 fn len(&self) -> usize {
601 self.value_offsets.len() - 1
602 }
603
604 fn is_empty(&self) -> bool {
605 self.value_offsets.len() <= 1
606 }
607
608 fn shrink_to_fit(&mut self) {
609 if let Some(nulls) = &mut self.nulls {
610 nulls.shrink_to_fit();
611 }
612 self.values.shrink_to_fit();
613 self.value_offsets.shrink_to_fit();
614 }
615
616 fn offset(&self) -> usize {
617 0
618 }
619
620 fn nulls(&self) -> Option<&NullBuffer> {
621 self.nulls.as_ref()
622 }
623
624 fn logical_null_count(&self) -> usize {
625 self.null_count()
627 }
628
629 fn get_buffer_memory_size(&self) -> usize {
630 let mut size = self.values.get_buffer_memory_size();
631 size += self.value_offsets.inner().inner().capacity();
632 if let Some(n) = self.nulls.as_ref() {
633 size += n.buffer().capacity();
634 }
635 size
636 }
637
638 fn get_array_memory_size(&self) -> usize {
639 let mut size = std::mem::size_of::<Self>() + self.values.get_array_memory_size();
640 size += self.value_offsets.inner().inner().capacity();
641 if let Some(n) = self.nulls.as_ref() {
642 size += n.buffer().capacity();
643 }
644 size
645 }
646
647 #[cfg(feature = "pool")]
648 fn claim(&self, pool: &dyn arrow_buffer::MemoryPool) {
649 self.value_offsets.claim(pool);
650 self.values.claim(pool);
651 if let Some(nulls) = &self.nulls {
652 nulls.claim(pool);
653 }
654 }
655}
656
657impl<OffsetSize: OffsetSizeTrait> super::ListLikeArray for GenericListArray<OffsetSize> {
658 fn values(&self) -> &ArrayRef {
659 self.values()
660 }
661
662 fn element_range(&self, index: usize) -> std::ops::Range<usize> {
663 let offsets = self.offsets();
664 let start = offsets[index].as_usize();
665 let end = offsets[index + 1].as_usize();
666 start..end
667 }
668}
669
670impl<OffsetSize: OffsetSizeTrait> ArrayAccessor for &GenericListArray<OffsetSize> {
671 type Item = ArrayRef;
672
673 fn value(&self, index: usize) -> Self::Item {
674 GenericListArray::value(self, index)
675 }
676
677 unsafe fn value_unchecked(&self, index: usize) -> Self::Item {
678 GenericListArray::value(self, index)
679 }
680}
681
682impl<OffsetSize: OffsetSizeTrait> std::fmt::Debug for GenericListArray<OffsetSize> {
683 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
684 let prefix = OffsetSize::PREFIX;
685
686 write!(f, "{prefix}ListArray\n[\n")?;
687 print_long_array(self, f, |array, index, f| {
688 std::fmt::Debug::fmt(&array.value(index), f)
689 })?;
690 write!(f, "]")
691 }
692}
693
694pub type ListArray = GenericListArray<i32>;
698
699pub type LargeListArray = GenericListArray<i64>;
703
704#[cfg(test)]
705mod tests {
706 use super::*;
707 use crate::builder::{
708 BooleanBuilder, FixedSizeListBuilder, Int32Builder, ListBuilder, StringBuilder,
709 StringDictionaryBuilder, UnionBuilder,
710 };
711 use crate::cast::AsArray;
712 use crate::types::{Int8Type, Int32Type};
713 use crate::{
714 BooleanArray, Int8Array, Int8DictionaryArray, Int32Array, Int64Array, StringArray,
715 };
716 use arrow_buffer::{Buffer, ScalarBuffer, bit_util};
717 use arrow_schema::Field;
718
719 fn create_from_buffers() -> ListArray {
720 let values = Int32Array::from(vec![0, 1, 2, 3, 4, 5, 6, 7]);
722 let offsets = OffsetBuffer::new(ScalarBuffer::from(vec![0, 3, 6, 8]));
723 let field = Arc::new(Field::new_list_field(DataType::Int32, true));
724 ListArray::new(field, offsets, Arc::new(values), None)
725 }
726
727 #[test]
728 fn test_from_iter_primitive() {
729 let data = vec![
730 Some(vec![Some(0), Some(1), Some(2)]),
731 Some(vec![Some(3), Some(4), Some(5)]),
732 Some(vec![Some(6), Some(7)]),
733 ];
734 let list_array = ListArray::from_iter_primitive::<Int32Type, _, _>(data);
735
736 let another = create_from_buffers();
737 assert_eq!(list_array, another)
738 }
739
740 #[test]
741 fn test_empty_list_array() {
742 let value_data = ArrayData::builder(DataType::Int32)
744 .len(0)
745 .add_buffer(Buffer::from([]))
746 .build()
747 .unwrap();
748
749 let value_offsets = Buffer::from([]);
751
752 let list_data_type =
754 DataType::List(Arc::new(Field::new_list_field(DataType::Int32, false)));
755 let list_data = ArrayData::builder(list_data_type)
756 .len(0)
757 .add_buffer(value_offsets)
758 .add_child_data(value_data)
759 .build()
760 .unwrap();
761
762 let list_array = ListArray::from(list_data);
763 assert_eq!(list_array.len(), 0)
764 }
765
766 #[test]
767 fn test_list_array() {
768 let value_data = ArrayData::builder(DataType::Int32)
770 .len(8)
771 .add_buffer(Buffer::from_slice_ref([0, 1, 2, 3, 4, 5, 6, 7]))
772 .build()
773 .unwrap();
774
775 let value_offsets = Buffer::from_slice_ref([0, 3, 6, 8]);
778
779 let list_data_type =
781 DataType::List(Arc::new(Field::new_list_field(DataType::Int32, false)));
782 let list_data = ArrayData::builder(list_data_type.clone())
783 .len(3)
784 .add_buffer(value_offsets.clone())
785 .add_child_data(value_data.clone())
786 .build()
787 .unwrap();
788 let list_array = ListArray::from(list_data);
789
790 let values = list_array.values();
791 assert_eq!(value_data, values.to_data());
792 assert_eq!(DataType::Int32, list_array.value_type());
793 assert_eq!(3, list_array.len());
794 assert_eq!(0, list_array.null_count());
795 assert_eq!(6, list_array.value_offsets()[2]);
796 assert_eq!(2, list_array.value_length(2));
797 assert_eq!(0, list_array.value(0).as_primitive::<Int32Type>().value(0));
798 assert_eq!(
799 0,
800 unsafe { list_array.value_unchecked(0) }
801 .as_primitive::<Int32Type>()
802 .value(0)
803 );
804 for i in 0..3 {
805 assert!(list_array.is_valid(i));
806 assert!(!list_array.is_null(i));
807 }
808
809 let list_data = ArrayData::builder(list_data_type)
812 .len(2)
813 .offset(1)
814 .add_buffer(value_offsets)
815 .add_child_data(value_data.clone())
816 .build()
817 .unwrap();
818 let list_array = ListArray::from(list_data);
819
820 let values = list_array.values();
821 assert_eq!(value_data, values.to_data());
822 assert_eq!(DataType::Int32, list_array.value_type());
823 assert_eq!(2, list_array.len());
824 assert_eq!(0, list_array.null_count());
825 assert_eq!(6, list_array.value_offsets()[1]);
826 assert_eq!(2, list_array.value_length(1));
827 assert_eq!(3, list_array.value(0).as_primitive::<Int32Type>().value(0));
828 assert_eq!(
829 3,
830 unsafe { list_array.value_unchecked(0) }
831 .as_primitive::<Int32Type>()
832 .value(0)
833 );
834 }
835
836 #[test]
837 fn test_large_list_array() {
838 let value_data = ArrayData::builder(DataType::Int32)
840 .len(8)
841 .add_buffer(Buffer::from_slice_ref([0, 1, 2, 3, 4, 5, 6, 7]))
842 .build()
843 .unwrap();
844
845 let value_offsets = Buffer::from_slice_ref([0i64, 3, 6, 8]);
848
849 let list_data_type = DataType::new_large_list(DataType::Int32, false);
851 let list_data = ArrayData::builder(list_data_type.clone())
852 .len(3)
853 .add_buffer(value_offsets.clone())
854 .add_child_data(value_data.clone())
855 .build()
856 .unwrap();
857 let list_array = LargeListArray::from(list_data);
858
859 let values = list_array.values();
860 assert_eq!(value_data, values.to_data());
861 assert_eq!(DataType::Int32, list_array.value_type());
862 assert_eq!(3, list_array.len());
863 assert_eq!(0, list_array.null_count());
864 assert_eq!(6, list_array.value_offsets()[2]);
865 assert_eq!(2, list_array.value_length(2));
866 assert_eq!(0, list_array.value(0).as_primitive::<Int32Type>().value(0));
867 assert_eq!(
868 0,
869 unsafe { list_array.value_unchecked(0) }
870 .as_primitive::<Int32Type>()
871 .value(0)
872 );
873 for i in 0..3 {
874 assert!(list_array.is_valid(i));
875 assert!(!list_array.is_null(i));
876 }
877
878 let list_data = ArrayData::builder(list_data_type)
881 .len(2)
882 .offset(1)
883 .add_buffer(value_offsets)
884 .add_child_data(value_data.clone())
885 .build()
886 .unwrap();
887 let list_array = LargeListArray::from(list_data);
888
889 let values = list_array.values();
890 assert_eq!(value_data, values.to_data());
891 assert_eq!(DataType::Int32, list_array.value_type());
892 assert_eq!(2, list_array.len());
893 assert_eq!(0, list_array.null_count());
894 assert_eq!(6, list_array.value_offsets()[1]);
895 assert_eq!(2, list_array.value_length(1));
896 assert_eq!(3, list_array.value(0).as_primitive::<Int32Type>().value(0));
897 assert_eq!(
898 3,
899 unsafe { list_array.value_unchecked(0) }
900 .as_primitive::<Int32Type>()
901 .value(0)
902 );
903 }
904
905 #[test]
906 fn test_list_array_slice() {
907 let value_data = ArrayData::builder(DataType::Int32)
909 .len(10)
910 .add_buffer(Buffer::from_slice_ref([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]))
911 .build()
912 .unwrap();
913
914 let value_offsets = Buffer::from_slice_ref([0, 2, 2, 2, 4, 6, 6, 9, 9, 10]);
917 let mut null_bits: [u8; 2] = [0; 2];
919 bit_util::set_bit(&mut null_bits, 0);
920 bit_util::set_bit(&mut null_bits, 3);
921 bit_util::set_bit(&mut null_bits, 4);
922 bit_util::set_bit(&mut null_bits, 6);
923 bit_util::set_bit(&mut null_bits, 8);
924
925 let list_data_type =
927 DataType::List(Arc::new(Field::new_list_field(DataType::Int32, false)));
928 let list_data = ArrayData::builder(list_data_type)
929 .len(9)
930 .add_buffer(value_offsets)
931 .add_child_data(value_data.clone())
932 .null_bit_buffer(Some(Buffer::from(null_bits)))
933 .build()
934 .unwrap();
935 let list_array = ListArray::from(list_data);
936
937 let values = list_array.values();
938 assert_eq!(value_data, values.to_data());
939 assert_eq!(DataType::Int32, list_array.value_type());
940 assert_eq!(9, list_array.len());
941 assert_eq!(4, list_array.null_count());
942 assert_eq!(2, list_array.value_offsets()[3]);
943 assert_eq!(2, list_array.value_length(3));
944
945 let sliced_array = list_array.slice(1, 6);
946 assert_eq!(6, sliced_array.len());
947 assert_eq!(3, sliced_array.null_count());
948
949 for i in 0..sliced_array.len() {
950 if bit_util::get_bit(&null_bits, 1 + i) {
951 assert!(sliced_array.is_valid(i));
952 } else {
953 assert!(sliced_array.is_null(i));
954 }
955 }
956
957 let sliced_list_array = sliced_array.as_any().downcast_ref::<ListArray>().unwrap();
959 assert_eq!(2, sliced_list_array.value_offsets()[2]);
960 assert_eq!(2, sliced_list_array.value_length(2));
961 assert_eq!(4, sliced_list_array.value_offsets()[3]);
962 assert_eq!(2, sliced_list_array.value_length(3));
963 assert_eq!(6, sliced_list_array.value_offsets()[5]);
964 assert_eq!(3, sliced_list_array.value_length(5));
965 }
966
967 #[test]
968 fn test_large_list_array_slice() {
969 let value_data = ArrayData::builder(DataType::Int32)
971 .len(10)
972 .add_buffer(Buffer::from_slice_ref([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]))
973 .build()
974 .unwrap();
975
976 let value_offsets = Buffer::from_slice_ref([0i64, 2, 2, 2, 4, 6, 6, 9, 9, 10]);
979 let mut null_bits: [u8; 2] = [0; 2];
981 bit_util::set_bit(&mut null_bits, 0);
982 bit_util::set_bit(&mut null_bits, 3);
983 bit_util::set_bit(&mut null_bits, 4);
984 bit_util::set_bit(&mut null_bits, 6);
985 bit_util::set_bit(&mut null_bits, 8);
986
987 let list_data_type = DataType::new_large_list(DataType::Int32, false);
989 let list_data = ArrayData::builder(list_data_type)
990 .len(9)
991 .add_buffer(value_offsets)
992 .add_child_data(value_data.clone())
993 .null_bit_buffer(Some(Buffer::from(null_bits)))
994 .build()
995 .unwrap();
996 let list_array = LargeListArray::from(list_data);
997
998 let values = list_array.values();
999 assert_eq!(value_data, values.to_data());
1000 assert_eq!(DataType::Int32, list_array.value_type());
1001 assert_eq!(9, list_array.len());
1002 assert_eq!(4, list_array.null_count());
1003 assert_eq!(2, list_array.value_offsets()[3]);
1004 assert_eq!(2, list_array.value_length(3));
1005
1006 let sliced_array = list_array.slice(1, 6);
1007 assert_eq!(6, sliced_array.len());
1008 assert_eq!(3, sliced_array.null_count());
1009
1010 for i in 0..sliced_array.len() {
1011 if bit_util::get_bit(&null_bits, 1 + i) {
1012 assert!(sliced_array.is_valid(i));
1013 } else {
1014 assert!(sliced_array.is_null(i));
1015 }
1016 }
1017
1018 let sliced_list_array = sliced_array
1020 .as_any()
1021 .downcast_ref::<LargeListArray>()
1022 .unwrap();
1023 assert_eq!(2, sliced_list_array.value_offsets()[2]);
1024 assert_eq!(2, sliced_list_array.value_length(2));
1025 assert_eq!(4, sliced_list_array.value_offsets()[3]);
1026 assert_eq!(2, sliced_list_array.value_length(3));
1027 assert_eq!(6, sliced_list_array.value_offsets()[5]);
1028 assert_eq!(3, sliced_list_array.value_length(5));
1029 }
1030
1031 #[test]
1032 #[should_panic(expected = "index out of bounds: the len is 10 but the index is 11")]
1033 fn test_list_array_index_out_of_bound() {
1034 let value_data = ArrayData::builder(DataType::Int32)
1036 .len(10)
1037 .add_buffer(Buffer::from_slice_ref([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]))
1038 .build()
1039 .unwrap();
1040
1041 let value_offsets = Buffer::from_slice_ref([0i64, 2, 2, 2, 4, 6, 6, 9, 9, 10]);
1044 let mut null_bits: [u8; 2] = [0; 2];
1046 bit_util::set_bit(&mut null_bits, 0);
1047 bit_util::set_bit(&mut null_bits, 3);
1048 bit_util::set_bit(&mut null_bits, 4);
1049 bit_util::set_bit(&mut null_bits, 6);
1050 bit_util::set_bit(&mut null_bits, 8);
1051
1052 let list_data_type = DataType::new_large_list(DataType::Int32, false);
1054 let list_data = ArrayData::builder(list_data_type)
1055 .len(9)
1056 .add_buffer(value_offsets)
1057 .add_child_data(value_data)
1058 .null_bit_buffer(Some(Buffer::from(null_bits)))
1059 .build()
1060 .unwrap();
1061 let list_array = LargeListArray::from(list_data);
1062 assert_eq!(9, list_array.len());
1063
1064 list_array.value(10);
1065 }
1066 #[test]
1067 #[should_panic(expected = "ListArray data should contain a single buffer only (value offsets)")]
1068 #[cfg(not(feature = "force_validate"))]
1071 fn test_list_array_invalid_buffer_len() {
1072 let value_data = unsafe {
1073 ArrayData::builder(DataType::Int32)
1074 .len(8)
1075 .add_buffer(Buffer::from_slice_ref([0, 1, 2, 3, 4, 5, 6, 7]))
1076 .build_unchecked()
1077 };
1078 let list_data_type =
1079 DataType::List(Arc::new(Field::new_list_field(DataType::Int32, false)));
1080 let list_data = unsafe {
1081 ArrayData::builder(list_data_type)
1082 .len(3)
1083 .add_child_data(value_data)
1084 .build_unchecked()
1085 };
1086 drop(ListArray::from(list_data));
1087 }
1088
1089 #[test]
1090 #[should_panic(expected = "ListArray should contain a single child array (values array)")]
1091 #[cfg(not(feature = "force_validate"))]
1094 fn test_list_array_invalid_child_array_len() {
1095 let value_offsets = Buffer::from_slice_ref([0, 2, 5, 7]);
1096 let list_data_type =
1097 DataType::List(Arc::new(Field::new_list_field(DataType::Int32, false)));
1098 let list_data = unsafe {
1099 ArrayData::builder(list_data_type)
1100 .len(3)
1101 .add_buffer(value_offsets)
1102 .build_unchecked()
1103 };
1104 drop(ListArray::from(list_data));
1105 }
1106
1107 #[test]
1108 #[should_panic(expected = "[Large]ListArray's datatype must be [Large]ListArray(). It is List")]
1109 fn test_from_array_data_validation() {
1110 let mut builder = ListBuilder::new(Int32Builder::new());
1111 builder.values().append_value(1);
1112 builder.append(true);
1113 let array = builder.finish();
1114 let _ = LargeListArray::from(array.into_data());
1115 }
1116
1117 #[test]
1118 fn test_list_array_offsets_need_not_start_at_zero() {
1119 let value_data = ArrayData::builder(DataType::Int32)
1120 .len(8)
1121 .add_buffer(Buffer::from_slice_ref([0, 1, 2, 3, 4, 5, 6, 7]))
1122 .build()
1123 .unwrap();
1124
1125 let value_offsets = Buffer::from_slice_ref([2, 2, 5, 7]);
1126
1127 let list_data_type =
1128 DataType::List(Arc::new(Field::new_list_field(DataType::Int32, false)));
1129 let list_data = ArrayData::builder(list_data_type)
1130 .len(3)
1131 .add_buffer(value_offsets)
1132 .add_child_data(value_data)
1133 .build()
1134 .unwrap();
1135
1136 let list_array = ListArray::from(list_data);
1137 assert_eq!(list_array.value_length(0), 0);
1138 assert_eq!(list_array.value_length(1), 3);
1139 assert_eq!(list_array.value_length(2), 2);
1140 }
1141
1142 #[test]
1143 #[should_panic(expected = "Memory pointer is not aligned with the specified scalar type")]
1144 #[cfg(not(feature = "force_validate"))]
1147 fn test_primitive_array_alignment() {
1148 let buf = Buffer::from_slice_ref([0_u64]);
1149 let buf2 = buf.slice(1);
1150 let array_data = unsafe {
1151 ArrayData::builder(DataType::Int32)
1152 .add_buffer(buf2)
1153 .build_unchecked()
1154 };
1155 drop(Int32Array::from(array_data));
1156 }
1157
1158 #[test]
1159 #[should_panic(expected = "Memory pointer is not aligned with the specified scalar type")]
1160 #[cfg(not(feature = "force_validate"))]
1163 fn test_list_array_alignment() {
1164 let buf = Buffer::from_slice_ref([0_u64]);
1165 let buf2 = buf.slice(1);
1166
1167 let values: [i32; 8] = [0; 8];
1168 let value_data = unsafe {
1169 ArrayData::builder(DataType::Int32)
1170 .add_buffer(Buffer::from_slice_ref(values))
1171 .build_unchecked()
1172 };
1173
1174 let list_data_type =
1175 DataType::List(Arc::new(Field::new_list_field(DataType::Int32, false)));
1176 let list_data = unsafe {
1177 ArrayData::builder(list_data_type)
1178 .add_buffer(buf2)
1179 .add_child_data(value_data)
1180 .build_unchecked()
1181 };
1182 drop(ListArray::from(list_data));
1183 }
1184
1185 #[test]
1186 fn list_array_equality() {
1187 fn do_comparison(
1189 lhs_data: Vec<Option<Vec<Option<i32>>>>,
1190 rhs_data: Vec<Option<Vec<Option<i32>>>>,
1191 should_equal: bool,
1192 ) {
1193 let lhs = ListArray::from_iter_primitive::<Int32Type, _, _>(lhs_data.clone());
1194 let rhs = ListArray::from_iter_primitive::<Int32Type, _, _>(rhs_data.clone());
1195 assert_eq!(lhs == rhs, should_equal);
1196
1197 let lhs = LargeListArray::from_iter_primitive::<Int32Type, _, _>(lhs_data);
1198 let rhs = LargeListArray::from_iter_primitive::<Int32Type, _, _>(rhs_data);
1199 assert_eq!(lhs == rhs, should_equal);
1200 }
1201
1202 do_comparison(
1203 vec![
1204 Some(vec![Some(0), Some(1), Some(2)]),
1205 None,
1206 Some(vec![Some(3), None, Some(5)]),
1207 Some(vec![Some(6), Some(7)]),
1208 ],
1209 vec![
1210 Some(vec![Some(0), Some(1), Some(2)]),
1211 None,
1212 Some(vec![Some(3), None, Some(5)]),
1213 Some(vec![Some(6), Some(7)]),
1214 ],
1215 true,
1216 );
1217
1218 do_comparison(
1219 vec![
1220 None,
1221 None,
1222 Some(vec![Some(3), None, Some(5)]),
1223 Some(vec![Some(6), Some(7)]),
1224 ],
1225 vec![
1226 Some(vec![Some(0), Some(1), Some(2)]),
1227 None,
1228 Some(vec![Some(3), None, Some(5)]),
1229 Some(vec![Some(6), Some(7)]),
1230 ],
1231 false,
1232 );
1233
1234 do_comparison(
1235 vec![
1236 None,
1237 None,
1238 Some(vec![Some(3), None, Some(5)]),
1239 Some(vec![Some(6), Some(7)]),
1240 ],
1241 vec![
1242 None,
1243 None,
1244 Some(vec![Some(3), None, Some(5)]),
1245 Some(vec![Some(0), Some(0)]),
1246 ],
1247 false,
1248 );
1249
1250 do_comparison(
1251 vec![None, None, Some(vec![Some(1)])],
1252 vec![None, None, Some(vec![Some(2)])],
1253 false,
1254 );
1255 }
1256
1257 #[test]
1258 fn test_empty_offsets() {
1259 let f = Arc::new(Field::new("element", DataType::Int32, true));
1260 let string = ListArray::from(
1261 ArrayData::builder(DataType::List(f.clone()))
1262 .buffers(vec![Buffer::from(&[])])
1263 .add_child_data(ArrayData::new_empty(&DataType::Int32))
1264 .build()
1265 .unwrap(),
1266 );
1267 assert_eq!(string.value_offsets(), &[0]);
1268 let string = LargeListArray::from(
1269 ArrayData::builder(DataType::LargeList(f))
1270 .buffers(vec![Buffer::from(&[])])
1271 .add_child_data(ArrayData::new_empty(&DataType::Int32))
1272 .build()
1273 .unwrap(),
1274 );
1275 assert_eq!(string.len(), 0);
1276 assert_eq!(string.value_offsets(), &[0]);
1277 }
1278
1279 #[test]
1280 fn test_try_new() {
1281 let offsets = OffsetBuffer::new(vec![0, 1, 4, 5].into());
1282 let values = Int32Array::new(vec![1, 2, 3, 4, 5].into(), None);
1283 let values = Arc::new(values) as ArrayRef;
1284
1285 let field = Arc::new(Field::new("element", DataType::Int32, false));
1286 ListArray::new(field.clone(), offsets.clone(), values.clone(), None);
1287
1288 let nulls = NullBuffer::new_null(3);
1289 ListArray::new(field.clone(), offsets, values.clone(), Some(nulls));
1290
1291 let nulls = NullBuffer::new_null(3);
1292 let offsets = OffsetBuffer::new(vec![0, 1, 2, 4, 5].into());
1293 let err = LargeListArray::try_new(field, offsets.clone(), values.clone(), Some(nulls))
1294 .unwrap_err();
1295
1296 assert_eq!(
1297 err.to_string(),
1298 "Invalid argument error: Incorrect length of null buffer for LargeListArray, expected 4 got 3"
1299 );
1300
1301 let field = Arc::new(Field::new("element", DataType::Int64, false));
1302 let err = LargeListArray::try_new(field.clone(), offsets.clone(), values.clone(), None)
1303 .unwrap_err();
1304
1305 assert_eq!(
1306 err.to_string(),
1307 "Invalid argument error: LargeListArray expected data type Int64 got Int32 for \"element\""
1308 );
1309
1310 let nulls = NullBuffer::new_null(7);
1311 let values = Int64Array::new(vec![0; 7].into(), Some(nulls));
1312 let values = Arc::new(values);
1313
1314 let err =
1315 LargeListArray::try_new(field, offsets.clone(), values.clone(), None).unwrap_err();
1316
1317 assert_eq!(
1318 err.to_string(),
1319 "Invalid argument error: Non-nullable field of LargeListArray \"element\" cannot contain nulls"
1320 );
1321
1322 let field = Arc::new(Field::new("element", DataType::Int64, true));
1323 LargeListArray::new(field.clone(), offsets.clone(), values, None);
1324
1325 let values = Int64Array::new(vec![0; 2].into(), None);
1326 let err = LargeListArray::try_new(field, offsets, Arc::new(values), None).unwrap_err();
1327
1328 assert_eq!(
1329 err.to_string(),
1330 "Invalid argument error: Max offset of 5 exceeds length of values 2"
1331 );
1332 }
1333
1334 #[test]
1335 fn test_from_fixed_size_list() {
1336 let mut builder = FixedSizeListBuilder::new(Int32Builder::new(), 3);
1337 builder.values().append_slice(&[1, 2, 3]);
1338 builder.append(true);
1339 builder.values().append_slice(&[0, 0, 0]);
1340 builder.append(false);
1341 builder.values().append_slice(&[4, 5, 6]);
1342 builder.append(true);
1343 let list: ListArray = builder.finish().into();
1344
1345 let values: Vec<_> = list
1346 .iter()
1347 .map(|x| x.map(|x| x.as_primitive::<Int32Type>().values().to_vec()))
1348 .collect();
1349 assert_eq!(values, vec![Some(vec![1, 2, 3]), None, Some(vec![4, 5, 6])])
1350 }
1351
1352 #[test]
1353 fn test_nullable_union() {
1354 let offsets = OffsetBuffer::new(vec![0, 1, 4, 5].into());
1355 let mut builder = UnionBuilder::new_dense();
1356 builder.append::<Int32Type>("a", 1).unwrap();
1357 builder.append::<Int32Type>("b", 2).unwrap();
1358 builder.append::<Int32Type>("b", 3).unwrap();
1359 builder.append::<Int32Type>("a", 4).unwrap();
1360 builder.append::<Int32Type>("a", 5).unwrap();
1361 let values = builder.build().unwrap();
1362 let field = Arc::new(Field::new("element", values.data_type().clone(), false));
1363 ListArray::new(field.clone(), offsets, Arc::new(values), None);
1364 }
1365
1366 #[test]
1367 fn test_list_new_null_len() {
1368 let field = Arc::new(Field::new_list_field(DataType::Int32, true));
1369 let array = ListArray::new_null(field, 5);
1370 assert_eq!(array.len(), 5);
1371 }
1372
1373 #[test]
1374 fn test_list_from_iter_i32() {
1375 let array = ListArray::from_nested_iter::<Int32Builder, _, _, _>(vec![
1376 None,
1377 Some(vec![Some(1), None, Some(2)]),
1378 ]);
1379 let expected_offsets = &[0, 0, 3];
1380 let expected_values: ArrayRef = Arc::new(Int32Array::from(vec![Some(1), None, Some(2)]));
1381 assert_eq!(array.value_offsets(), expected_offsets);
1382 assert_eq!(array.values(), &expected_values);
1383 }
1384
1385 #[test]
1386 fn test_list_from_iter_bool() {
1387 let array = ListArray::from_nested_iter::<BooleanBuilder, _, _, _>(vec![
1388 Some(vec![None, Some(false), Some(true)]),
1389 None,
1390 ]);
1391 let expected_offsets = &[0, 3, 3];
1392 let expected_values: ArrayRef =
1393 Arc::new(BooleanArray::from(vec![None, Some(false), Some(true)]));
1394 assert_eq!(array.value_offsets(), expected_offsets);
1395 assert_eq!(array.values(), &expected_values);
1396 }
1397
1398 #[test]
1399 fn test_list_from_iter_str() {
1400 let array = ListArray::from_nested_iter::<StringBuilder, _, _, _>(vec![
1401 Some(vec![Some("foo"), None, Some("bar")]),
1402 None,
1403 ]);
1404 let expected_offsets = &[0, 3, 3];
1405 let expected_values: ArrayRef =
1406 Arc::new(StringArray::from(vec![Some("foo"), None, Some("bar")]));
1407 assert_eq!(array.value_offsets(), expected_offsets);
1408 assert_eq!(array.values(), &expected_values);
1409 }
1410
1411 #[test]
1412 fn test_list_from_iter_dict_str() {
1413 let array =
1414 ListArray::from_nested_iter::<StringDictionaryBuilder<Int8Type>, _, _, _>(vec![
1415 Some(vec![Some("foo"), None, Some("bar"), Some("foo")]),
1416 None,
1417 ]);
1418 let expected_offsets = &[0, 4, 4];
1419 let expected_dict_values: ArrayRef =
1420 Arc::new(StringArray::from(vec![Some("foo"), Some("bar")]));
1421 let expected_dict_keys = Int8Array::from(vec![Some(0), None, Some(1), Some(0)]);
1422 let expected_values: ArrayRef = Arc::new(
1423 Int8DictionaryArray::try_new(expected_dict_keys, expected_dict_values).unwrap(),
1424 );
1425 assert_eq!(array.value_offsets(), expected_offsets);
1426 assert_eq!(array.values(), &expected_values);
1427 }
1428}