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().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 && n.len() != len
228 {
229 return Err(ArrowError::InvalidArgumentError(format!(
230 "Incorrect length of null buffer for {}ListArray, expected {len} got {}",
231 OffsetSize::PREFIX,
232 n.len(),
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 (DataType::List(f) | DataType::LargeList(f)) = self.data_type else {
319 unreachable!()
320 };
321 (f, self.value_offsets, self.values, self.nulls)
322 }
323
324 pub fn value_field(&self) -> &FieldRef {
326 match &self.data_type {
327 DataType::List(f) | DataType::LargeList(f) => f,
328 _ => unreachable!(),
329 }
330 }
331
332 #[inline]
341 pub fn offsets(&self) -> &OffsetBuffer<OffsetSize> {
342 &self.value_offsets
343 }
344
345 #[inline]
352 pub fn values(&self) -> &ArrayRef {
353 &self.values
354 }
355
356 pub fn value_type(&self) -> DataType {
358 self.values.data_type().clone()
359 }
360
361 pub unsafe fn value_unchecked(&self, i: usize) -> ArrayRef {
369 let end = unsafe { self.value_offsets().get_unchecked(i + 1).as_usize() };
370 let start = unsafe { self.value_offsets().get_unchecked(i).as_usize() };
371 self.values.slice(start, end - start)
372 }
373
374 pub fn value(&self, i: usize) -> ArrayRef {
382 let end = self.value_offsets()[i + 1].as_usize();
383 let start = self.value_offsets()[i].as_usize();
384 self.values.slice(start, end - start)
385 }
386
387 #[inline]
391 pub fn value_offsets(&self) -> &[OffsetSize] {
392 &self.value_offsets
393 }
394
395 #[inline]
400 pub fn value_length(&self, i: usize) -> OffsetSize {
401 let offsets = self.value_offsets();
402 offsets[i + 1] - offsets[i]
403 }
404
405 pub fn iter<'a>(&'a self) -> GenericListArrayIter<'a, OffsetSize> {
407 GenericListArrayIter::<'a, OffsetSize>::new(self)
408 }
409
410 #[inline]
411 fn get_type(data_type: &DataType) -> Option<&DataType> {
412 match (OffsetSize::IS_LARGE, data_type) {
413 (true, DataType::LargeList(child)) | (false, DataType::List(child)) => {
414 Some(child.data_type())
415 }
416 _ => None,
417 }
418 }
419
420 pub fn slice(&self, offset: usize, length: usize) -> Self {
429 Self {
430 data_type: self.data_type.clone(),
431 nulls: self.nulls.as_ref().map(|n| n.slice(offset, length)),
432 values: self.values.clone(),
433 value_offsets: self.value_offsets.slice(offset, length),
434 }
435 }
436
437 pub fn from_iter_primitive<T, P, I>(iter: I) -> Self
453 where
454 T: ArrowPrimitiveType,
455 P: IntoIterator<Item = Option<<T as ArrowPrimitiveType>::Native>>,
456 I: IntoIterator<Item = Option<P>>,
457 {
458 Self::from_nested_iter::<PrimitiveBuilder<T>, T::Native, P, I>(iter)
459 }
460
461 pub fn from_nested_iter<B, T, P, I>(iter: I) -> Self
481 where
482 B: ArrayBuilder + Default + Extend<Option<T>>,
483 P: IntoIterator<Item = Option<T>>,
484 I: IntoIterator<Item = Option<P>>,
485 {
486 let iter = iter.into_iter();
487 let size_hint = iter.size_hint().0;
488 let mut builder = GenericListBuilder::with_capacity(B::default(), size_hint);
489
490 for i in iter {
491 match i {
492 Some(p) => {
493 builder.values().extend(p);
494 builder.append(true);
495 }
496 None => builder.append(false),
497 }
498 }
499 builder.finish()
500 }
501}
502
503impl<OffsetSize: OffsetSizeTrait> From<ArrayData> for GenericListArray<OffsetSize> {
504 fn from(data: ArrayData) -> Self {
505 Self::try_new_from_array_data(data)
506 .expect("Expected infallible creation of GenericListArray from ArrayDataRef failed")
507 }
508}
509
510impl<OffsetSize: OffsetSizeTrait> From<GenericListArray<OffsetSize>> for ArrayData {
511 fn from(array: GenericListArray<OffsetSize>) -> Self {
512 let len = array.len();
513 let builder = ArrayDataBuilder::new(array.data_type)
514 .len(len)
515 .nulls(array.nulls)
516 .buffers(vec![array.value_offsets.into_inner().into_inner()])
517 .child_data(vec![array.values.to_data()]);
518
519 unsafe { builder.build_unchecked() }
520 }
521}
522
523impl<OffsetSize: OffsetSizeTrait> From<FixedSizeListArray> for GenericListArray<OffsetSize> {
524 fn from(value: FixedSizeListArray) -> Self {
525 let (field, size) = match value.data_type() {
526 DataType::FixedSizeList(f, size) => (f, *size as usize),
527 _ => unreachable!(),
528 };
529
530 let offsets = OffsetBuffer::from_repeated_length(size, value.len());
531
532 Self {
533 data_type: Self::DATA_TYPE_CONSTRUCTOR(field.clone()),
534 nulls: value.nulls().cloned(),
535 values: value.values().clone(),
536 value_offsets: offsets,
537 }
538 }
539}
540
541impl<OffsetSize: OffsetSizeTrait> GenericListArray<OffsetSize> {
542 fn try_new_from_array_data(data: ArrayData) -> Result<Self, ArrowError> {
543 let (data_type, len, nulls, offset, mut buffers, mut child_data) = data.into_parts();
544
545 if buffers.len() != 1 {
546 return Err(ArrowError::InvalidArgumentError(format!(
547 "ListArray data should contain a single buffer only (value offsets), had {}",
548 buffers.len()
549 )));
550 }
551 let buffer = buffers.pop().expect("checked above");
552
553 if child_data.len() != 1 {
554 return Err(ArrowError::InvalidArgumentError(format!(
555 "ListArray should contain a single child array (values array), had {}",
556 child_data.len()
557 )));
558 }
559
560 let values = child_data.pop().expect("checked above");
561
562 if let Some(child_data_type) = Self::get_type(&data_type) {
563 if values.data_type() != child_data_type {
564 return Err(ArrowError::InvalidArgumentError(format!(
565 "[Large]ListArray's child datatype {:?} does not \
566 correspond to the List's datatype {:?}",
567 values.data_type(),
568 child_data_type
569 )));
570 }
571 } else {
572 return Err(ArrowError::InvalidArgumentError(format!(
573 "[Large]ListArray's datatype must be [Large]ListArray(). It is {data_type:?}",
574 )));
575 }
576
577 let values = make_array(values);
578 let value_offsets = unsafe { get_offsets_from_buffer(buffer, offset, len) };
581
582 Ok(Self {
583 data_type,
584 nulls,
585 values,
586 value_offsets,
587 })
588 }
589}
590
591unsafe impl<OffsetSize: OffsetSizeTrait> Array for GenericListArray<OffsetSize> {
593 fn as_any(&self) -> &dyn Any {
594 self
595 }
596
597 fn to_data(&self) -> ArrayData {
598 self.clone().into()
599 }
600
601 fn into_data(self) -> ArrayData {
602 self.into()
603 }
604
605 fn data_type(&self) -> &DataType {
606 &self.data_type
607 }
608
609 fn slice(&self, offset: usize, length: usize) -> ArrayRef {
610 Arc::new(self.slice(offset, length))
611 }
612
613 fn len(&self) -> usize {
614 self.value_offsets.len() - 1
615 }
616
617 fn is_empty(&self) -> bool {
618 self.value_offsets.len() <= 1
619 }
620
621 fn shrink_to_fit(&mut self) {
622 if let Some(nulls) = &mut self.nulls {
623 nulls.shrink_to_fit();
624 }
625 self.values.shrink_to_fit();
626 self.value_offsets.shrink_to_fit();
627 }
628
629 fn offset(&self) -> usize {
630 0
631 }
632
633 fn nulls(&self) -> Option<&NullBuffer> {
634 self.nulls.as_ref()
635 }
636
637 fn logical_null_count(&self) -> usize {
638 self.null_count()
640 }
641
642 fn get_buffer_memory_size(&self) -> usize {
643 let mut size = self.values.get_buffer_memory_size();
644 size += self.value_offsets.inner().inner().capacity();
645 if let Some(n) = self.nulls.as_ref() {
646 size += n.buffer().capacity();
647 }
648 size
649 }
650
651 fn get_array_memory_size(&self) -> usize {
652 let mut size = std::mem::size_of::<Self>() + self.values.get_array_memory_size();
653 size += self.value_offsets.inner().inner().capacity();
654 if let Some(n) = self.nulls.as_ref() {
655 size += n.buffer().capacity();
656 }
657 size
658 }
659
660 #[cfg(feature = "pool")]
661 fn claim(&self, pool: &dyn arrow_buffer::MemoryPool) {
662 self.value_offsets.claim(pool);
663 self.values.claim(pool);
664 if let Some(nulls) = &self.nulls {
665 nulls.claim(pool);
666 }
667 }
668}
669
670impl<OffsetSize: OffsetSizeTrait> super::ListLikeArray for GenericListArray<OffsetSize> {
671 fn values(&self) -> &ArrayRef {
672 self.values()
673 }
674
675 fn element_range(&self, index: usize) -> std::ops::Range<usize> {
676 let offsets = self.offsets();
677 let start = offsets[index].as_usize();
678 let end = offsets[index + 1].as_usize();
679 start..end
680 }
681}
682
683impl<'a, OffsetSize: OffsetSizeTrait> IntoIterator for &'a GenericListArray<OffsetSize> {
684 type Item = Option<ArrayRef>;
685 type IntoIter = GenericListArrayIter<'a, OffsetSize>;
686
687 fn into_iter(self) -> Self::IntoIter {
688 GenericListArrayIter::<'a, OffsetSize>::new(self)
689 }
690}
691
692impl<OffsetSize: OffsetSizeTrait> ArrayAccessor for &GenericListArray<OffsetSize> {
693 type Item = ArrayRef;
694
695 fn value(&self, index: usize) -> Self::Item {
696 GenericListArray::value(self, index)
697 }
698
699 unsafe fn value_unchecked(&self, index: usize) -> Self::Item {
700 GenericListArray::value(self, index)
701 }
702}
703
704impl<OffsetSize: OffsetSizeTrait> std::fmt::Debug for GenericListArray<OffsetSize> {
705 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
706 let prefix = OffsetSize::PREFIX;
707
708 write!(f, "{prefix}ListArray\n[\n")?;
709 print_long_array(self, f, &mut |index, f| {
710 std::fmt::Debug::fmt(&self.value(index), f)
711 })?;
712 write!(f, "]")
713 }
714}
715
716pub type ListArray = GenericListArray<i32>;
720
721pub type LargeListArray = GenericListArray<i64>;
725
726#[cfg(test)]
727mod tests {
728 use super::*;
729 use crate::builder::{
730 BooleanBuilder, FixedSizeListBuilder, Int32Builder, ListBuilder, StringBuilder,
731 StringDictionaryBuilder, UnionBuilder,
732 };
733 use crate::cast::AsArray;
734 use crate::types::{Int8Type, Int32Type};
735 use crate::{
736 BooleanArray, Int8Array, Int8DictionaryArray, Int32Array, Int64Array, StringArray,
737 };
738 use arrow_buffer::{Buffer, ScalarBuffer, bit_util};
739 use arrow_schema::Field;
740
741 fn create_from_buffers() -> ListArray {
742 let values = Int32Array::from(vec![0, 1, 2, 3, 4, 5, 6, 7]);
744 let offsets = OffsetBuffer::new(ScalarBuffer::from(vec![0, 3, 6, 8]));
745 let field = Arc::new(Field::new_list_field(DataType::Int32, true));
746 ListArray::new(field, offsets, Arc::new(values), None)
747 }
748
749 #[test]
750 fn test_from_iter_primitive() {
751 let data = vec![
752 Some(vec![Some(0), Some(1), Some(2)]),
753 Some(vec![Some(3), Some(4), Some(5)]),
754 Some(vec![Some(6), Some(7)]),
755 ];
756 let list_array = ListArray::from_iter_primitive::<Int32Type, _, _>(data);
757
758 let another = create_from_buffers();
759 assert_eq!(list_array, another)
760 }
761
762 #[test]
763 fn test_empty_list_array() {
764 let value_data = ArrayData::builder(DataType::Int32)
766 .len(0)
767 .add_buffer(Buffer::from([]))
768 .build()
769 .unwrap();
770
771 let value_offsets = Buffer::from([]);
773
774 let list_data_type =
776 DataType::List(Arc::new(Field::new_list_field(DataType::Int32, false)));
777 let list_data = ArrayData::builder(list_data_type)
778 .len(0)
779 .add_buffer(value_offsets)
780 .add_child_data(value_data)
781 .build()
782 .unwrap();
783
784 let list_array = ListArray::from(list_data);
785 assert_eq!(list_array.len(), 0)
786 }
787
788 #[test]
789 fn test_list_array() {
790 let value_data = ArrayData::builder(DataType::Int32)
792 .len(8)
793 .add_buffer(Buffer::from_slice_ref([0, 1, 2, 3, 4, 5, 6, 7]))
794 .build()
795 .unwrap();
796
797 let value_offsets = Buffer::from_slice_ref([0, 3, 6, 8]);
800
801 let list_data_type =
803 DataType::List(Arc::new(Field::new_list_field(DataType::Int32, false)));
804 let list_data = ArrayData::builder(list_data_type.clone())
805 .len(3)
806 .add_buffer(value_offsets.clone())
807 .add_child_data(value_data.clone())
808 .build()
809 .unwrap();
810 let list_array = ListArray::from(list_data);
811
812 let values = list_array.values();
813 assert_eq!(value_data, values.to_data());
814 assert_eq!(DataType::Int32, list_array.value_type());
815 assert_eq!(3, list_array.len());
816 assert_eq!(0, list_array.null_count());
817 assert_eq!(6, list_array.value_offsets()[2]);
818 assert_eq!(2, list_array.value_length(2));
819 assert_eq!(0, list_array.value(0).as_primitive::<Int32Type>().value(0));
820 assert_eq!(
821 0,
822 unsafe { list_array.value_unchecked(0) }
823 .as_primitive::<Int32Type>()
824 .value(0)
825 );
826 for i in 0..3 {
827 assert!(list_array.is_valid(i));
828 assert!(!list_array.is_null(i));
829 }
830
831 let list_data = ArrayData::builder(list_data_type)
834 .len(2)
835 .offset(1)
836 .add_buffer(value_offsets)
837 .add_child_data(value_data.clone())
838 .build()
839 .unwrap();
840 let list_array = ListArray::from(list_data);
841
842 let values = list_array.values();
843 assert_eq!(value_data, values.to_data());
844 assert_eq!(DataType::Int32, list_array.value_type());
845 assert_eq!(2, list_array.len());
846 assert_eq!(0, list_array.null_count());
847 assert_eq!(6, list_array.value_offsets()[1]);
848 assert_eq!(2, list_array.value_length(1));
849 assert_eq!(3, list_array.value(0).as_primitive::<Int32Type>().value(0));
850 assert_eq!(
851 3,
852 unsafe { list_array.value_unchecked(0) }
853 .as_primitive::<Int32Type>()
854 .value(0)
855 );
856 }
857
858 #[test]
859 fn test_large_list_array() {
860 let value_data = ArrayData::builder(DataType::Int32)
862 .len(8)
863 .add_buffer(Buffer::from_slice_ref([0, 1, 2, 3, 4, 5, 6, 7]))
864 .build()
865 .unwrap();
866
867 let value_offsets = Buffer::from_slice_ref([0i64, 3, 6, 8]);
870
871 let list_data_type = DataType::new_large_list(DataType::Int32, false);
873 let list_data = ArrayData::builder(list_data_type.clone())
874 .len(3)
875 .add_buffer(value_offsets.clone())
876 .add_child_data(value_data.clone())
877 .build()
878 .unwrap();
879 let list_array = LargeListArray::from(list_data);
880
881 let values = list_array.values();
882 assert_eq!(value_data, values.to_data());
883 assert_eq!(DataType::Int32, list_array.value_type());
884 assert_eq!(3, list_array.len());
885 assert_eq!(0, list_array.null_count());
886 assert_eq!(6, list_array.value_offsets()[2]);
887 assert_eq!(2, list_array.value_length(2));
888 assert_eq!(0, list_array.value(0).as_primitive::<Int32Type>().value(0));
889 assert_eq!(
890 0,
891 unsafe { list_array.value_unchecked(0) }
892 .as_primitive::<Int32Type>()
893 .value(0)
894 );
895 for i in 0..3 {
896 assert!(list_array.is_valid(i));
897 assert!(!list_array.is_null(i));
898 }
899
900 let list_data = ArrayData::builder(list_data_type)
903 .len(2)
904 .offset(1)
905 .add_buffer(value_offsets)
906 .add_child_data(value_data.clone())
907 .build()
908 .unwrap();
909 let list_array = LargeListArray::from(list_data);
910
911 let values = list_array.values();
912 assert_eq!(value_data, values.to_data());
913 assert_eq!(DataType::Int32, list_array.value_type());
914 assert_eq!(2, list_array.len());
915 assert_eq!(0, list_array.null_count());
916 assert_eq!(6, list_array.value_offsets()[1]);
917 assert_eq!(2, list_array.value_length(1));
918 assert_eq!(3, list_array.value(0).as_primitive::<Int32Type>().value(0));
919 assert_eq!(
920 3,
921 unsafe { list_array.value_unchecked(0) }
922 .as_primitive::<Int32Type>()
923 .value(0)
924 );
925 }
926
927 #[test]
928 fn test_list_array_slice() {
929 let value_data = ArrayData::builder(DataType::Int32)
931 .len(10)
932 .add_buffer(Buffer::from_slice_ref([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]))
933 .build()
934 .unwrap();
935
936 let value_offsets = Buffer::from_slice_ref([0, 2, 2, 2, 4, 6, 6, 9, 9, 10]);
939 let mut null_bits: [u8; 2] = [0; 2];
941 bit_util::set_bit(&mut null_bits, 0);
942 bit_util::set_bit(&mut null_bits, 3);
943 bit_util::set_bit(&mut null_bits, 4);
944 bit_util::set_bit(&mut null_bits, 6);
945 bit_util::set_bit(&mut null_bits, 8);
946
947 let list_data_type =
949 DataType::List(Arc::new(Field::new_list_field(DataType::Int32, false)));
950 let list_data = ArrayData::builder(list_data_type)
951 .len(9)
952 .add_buffer(value_offsets)
953 .add_child_data(value_data.clone())
954 .null_bit_buffer(Some(Buffer::from(null_bits)))
955 .build()
956 .unwrap();
957 let list_array = ListArray::from(list_data);
958
959 let values = list_array.values();
960 assert_eq!(value_data, values.to_data());
961 assert_eq!(DataType::Int32, list_array.value_type());
962 assert_eq!(9, list_array.len());
963 assert_eq!(4, list_array.null_count());
964 assert_eq!(2, list_array.value_offsets()[3]);
965 assert_eq!(2, list_array.value_length(3));
966
967 let sliced_array = list_array.slice(1, 6);
968 assert_eq!(6, sliced_array.len());
969 assert_eq!(3, sliced_array.null_count());
970
971 for i in 0..sliced_array.len() {
972 if bit_util::get_bit(&null_bits, 1 + i) {
973 assert!(sliced_array.is_valid(i));
974 } else {
975 assert!(sliced_array.is_null(i));
976 }
977 }
978
979 let sliced_list_array = sliced_array.as_any().downcast_ref::<ListArray>().unwrap();
981 assert_eq!(2, sliced_list_array.value_offsets()[2]);
982 assert_eq!(2, sliced_list_array.value_length(2));
983 assert_eq!(4, sliced_list_array.value_offsets()[3]);
984 assert_eq!(2, sliced_list_array.value_length(3));
985 assert_eq!(6, sliced_list_array.value_offsets()[5]);
986 assert_eq!(3, sliced_list_array.value_length(5));
987 }
988
989 #[test]
990 fn test_large_list_array_slice() {
991 let value_data = ArrayData::builder(DataType::Int32)
993 .len(10)
994 .add_buffer(Buffer::from_slice_ref([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]))
995 .build()
996 .unwrap();
997
998 let value_offsets = Buffer::from_slice_ref([0i64, 2, 2, 2, 4, 6, 6, 9, 9, 10]);
1001 let mut null_bits: [u8; 2] = [0; 2];
1003 bit_util::set_bit(&mut null_bits, 0);
1004 bit_util::set_bit(&mut null_bits, 3);
1005 bit_util::set_bit(&mut null_bits, 4);
1006 bit_util::set_bit(&mut null_bits, 6);
1007 bit_util::set_bit(&mut null_bits, 8);
1008
1009 let list_data_type = DataType::new_large_list(DataType::Int32, false);
1011 let list_data = ArrayData::builder(list_data_type)
1012 .len(9)
1013 .add_buffer(value_offsets)
1014 .add_child_data(value_data.clone())
1015 .null_bit_buffer(Some(Buffer::from(null_bits)))
1016 .build()
1017 .unwrap();
1018 let list_array = LargeListArray::from(list_data);
1019
1020 let values = list_array.values();
1021 assert_eq!(value_data, values.to_data());
1022 assert_eq!(DataType::Int32, list_array.value_type());
1023 assert_eq!(9, list_array.len());
1024 assert_eq!(4, list_array.null_count());
1025 assert_eq!(2, list_array.value_offsets()[3]);
1026 assert_eq!(2, list_array.value_length(3));
1027
1028 let sliced_array = list_array.slice(1, 6);
1029 assert_eq!(6, sliced_array.len());
1030 assert_eq!(3, sliced_array.null_count());
1031
1032 for i in 0..sliced_array.len() {
1033 if bit_util::get_bit(&null_bits, 1 + i) {
1034 assert!(sliced_array.is_valid(i));
1035 } else {
1036 assert!(sliced_array.is_null(i));
1037 }
1038 }
1039
1040 let sliced_list_array = sliced_array
1042 .as_any()
1043 .downcast_ref::<LargeListArray>()
1044 .unwrap();
1045 assert_eq!(2, sliced_list_array.value_offsets()[2]);
1046 assert_eq!(2, sliced_list_array.value_length(2));
1047 assert_eq!(4, sliced_list_array.value_offsets()[3]);
1048 assert_eq!(2, sliced_list_array.value_length(3));
1049 assert_eq!(6, sliced_list_array.value_offsets()[5]);
1050 assert_eq!(3, sliced_list_array.value_length(5));
1051 }
1052
1053 #[test]
1054 #[should_panic(expected = "index out of bounds: the len is 10 but the index is 11")]
1055 fn test_list_array_index_out_of_bound() {
1056 let value_data = ArrayData::builder(DataType::Int32)
1058 .len(10)
1059 .add_buffer(Buffer::from_slice_ref([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]))
1060 .build()
1061 .unwrap();
1062
1063 let value_offsets = Buffer::from_slice_ref([0i64, 2, 2, 2, 4, 6, 6, 9, 9, 10]);
1066 let mut null_bits: [u8; 2] = [0; 2];
1068 bit_util::set_bit(&mut null_bits, 0);
1069 bit_util::set_bit(&mut null_bits, 3);
1070 bit_util::set_bit(&mut null_bits, 4);
1071 bit_util::set_bit(&mut null_bits, 6);
1072 bit_util::set_bit(&mut null_bits, 8);
1073
1074 let list_data_type = DataType::new_large_list(DataType::Int32, false);
1076 let list_data = ArrayData::builder(list_data_type)
1077 .len(9)
1078 .add_buffer(value_offsets)
1079 .add_child_data(value_data)
1080 .null_bit_buffer(Some(Buffer::from(null_bits)))
1081 .build()
1082 .unwrap();
1083 let list_array = LargeListArray::from(list_data);
1084 assert_eq!(9, list_array.len());
1085
1086 list_array.value(10);
1087 }
1088 #[test]
1089 #[should_panic(expected = "ListArray data should contain a single buffer only (value offsets)")]
1090 #[cfg(not(feature = "force_validate"))]
1093 fn test_list_array_invalid_buffer_len() {
1094 let value_data = unsafe {
1095 ArrayData::builder(DataType::Int32)
1096 .len(8)
1097 .add_buffer(Buffer::from_slice_ref([0, 1, 2, 3, 4, 5, 6, 7]))
1098 .build_unchecked()
1099 };
1100 let list_data_type =
1101 DataType::List(Arc::new(Field::new_list_field(DataType::Int32, false)));
1102 let list_data = unsafe {
1103 ArrayData::builder(list_data_type)
1104 .len(3)
1105 .add_child_data(value_data)
1106 .build_unchecked()
1107 };
1108 drop(ListArray::from(list_data));
1109 }
1110
1111 #[test]
1112 #[should_panic(expected = "ListArray should contain a single child array (values array)")]
1113 #[cfg(not(feature = "force_validate"))]
1116 fn test_list_array_invalid_child_array_len() {
1117 let value_offsets = Buffer::from_slice_ref([0, 2, 5, 7]);
1118 let list_data_type =
1119 DataType::List(Arc::new(Field::new_list_field(DataType::Int32, false)));
1120 let list_data = unsafe {
1121 ArrayData::builder(list_data_type)
1122 .len(3)
1123 .add_buffer(value_offsets)
1124 .build_unchecked()
1125 };
1126 drop(ListArray::from(list_data));
1127 }
1128
1129 #[test]
1130 #[should_panic(expected = "[Large]ListArray's datatype must be [Large]ListArray(). It is List")]
1131 fn test_from_array_data_validation() {
1132 let mut builder = ListBuilder::new(Int32Builder::new());
1133 builder.values().append_value(1);
1134 builder.append(true);
1135 let array = builder.finish();
1136 let _ = LargeListArray::from(array.into_data());
1137 }
1138
1139 #[test]
1140 fn test_list_array_offsets_need_not_start_at_zero() {
1141 let value_data = ArrayData::builder(DataType::Int32)
1142 .len(8)
1143 .add_buffer(Buffer::from_slice_ref([0, 1, 2, 3, 4, 5, 6, 7]))
1144 .build()
1145 .unwrap();
1146
1147 let value_offsets = Buffer::from_slice_ref([2, 2, 5, 7]);
1148
1149 let list_data_type =
1150 DataType::List(Arc::new(Field::new_list_field(DataType::Int32, false)));
1151 let list_data = ArrayData::builder(list_data_type)
1152 .len(3)
1153 .add_buffer(value_offsets)
1154 .add_child_data(value_data)
1155 .build()
1156 .unwrap();
1157
1158 let list_array = ListArray::from(list_data);
1159 assert_eq!(list_array.value_length(0), 0);
1160 assert_eq!(list_array.value_length(1), 3);
1161 assert_eq!(list_array.value_length(2), 2);
1162 }
1163
1164 #[test]
1165 #[should_panic(expected = "Memory pointer is not aligned with the specified scalar type")]
1166 #[cfg(not(feature = "force_validate"))]
1169 fn test_primitive_array_alignment() {
1170 let buf = Buffer::from_slice_ref([0_u64]);
1171 let buf2 = buf.slice(1);
1172 let array_data = unsafe {
1173 ArrayData::builder(DataType::Int32)
1174 .add_buffer(buf2)
1175 .build_unchecked()
1176 };
1177 drop(Int32Array::from(array_data));
1178 }
1179
1180 #[test]
1181 #[should_panic(expected = "Memory pointer is not aligned with the specified scalar type")]
1182 #[cfg(not(feature = "force_validate"))]
1185 fn test_list_array_alignment() {
1186 let buf = Buffer::from_slice_ref([0_u64]);
1187 let buf2 = buf.slice(1);
1188
1189 let values: [i32; 8] = [0; 8];
1190 let value_data = unsafe {
1191 ArrayData::builder(DataType::Int32)
1192 .add_buffer(Buffer::from_slice_ref(values))
1193 .build_unchecked()
1194 };
1195
1196 let list_data_type =
1197 DataType::List(Arc::new(Field::new_list_field(DataType::Int32, false)));
1198 let list_data = unsafe {
1199 ArrayData::builder(list_data_type)
1200 .add_buffer(buf2)
1201 .add_child_data(value_data)
1202 .build_unchecked()
1203 };
1204 drop(ListArray::from(list_data));
1205 }
1206
1207 #[test]
1208 fn list_array_equality() {
1209 fn do_comparison(
1211 lhs_data: Vec<Option<Vec<Option<i32>>>>,
1212 rhs_data: Vec<Option<Vec<Option<i32>>>>,
1213 should_equal: bool,
1214 ) {
1215 let lhs = ListArray::from_iter_primitive::<Int32Type, _, _>(lhs_data.clone());
1216 let rhs = ListArray::from_iter_primitive::<Int32Type, _, _>(rhs_data.clone());
1217 assert_eq!(lhs == rhs, should_equal);
1218
1219 let lhs = LargeListArray::from_iter_primitive::<Int32Type, _, _>(lhs_data);
1220 let rhs = LargeListArray::from_iter_primitive::<Int32Type, _, _>(rhs_data);
1221 assert_eq!(lhs == rhs, should_equal);
1222 }
1223
1224 do_comparison(
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 vec![
1232 Some(vec![Some(0), Some(1), Some(2)]),
1233 None,
1234 Some(vec![Some(3), None, Some(5)]),
1235 Some(vec![Some(6), Some(7)]),
1236 ],
1237 true,
1238 );
1239
1240 do_comparison(
1241 vec![
1242 None,
1243 None,
1244 Some(vec![Some(3), None, Some(5)]),
1245 Some(vec![Some(6), Some(7)]),
1246 ],
1247 vec![
1248 Some(vec![Some(0), Some(1), Some(2)]),
1249 None,
1250 Some(vec![Some(3), None, Some(5)]),
1251 Some(vec![Some(6), Some(7)]),
1252 ],
1253 false,
1254 );
1255
1256 do_comparison(
1257 vec![
1258 None,
1259 None,
1260 Some(vec![Some(3), None, Some(5)]),
1261 Some(vec![Some(6), Some(7)]),
1262 ],
1263 vec![
1264 None,
1265 None,
1266 Some(vec![Some(3), None, Some(5)]),
1267 Some(vec![Some(0), Some(0)]),
1268 ],
1269 false,
1270 );
1271
1272 do_comparison(
1273 vec![None, None, Some(vec![Some(1)])],
1274 vec![None, None, Some(vec![Some(2)])],
1275 false,
1276 );
1277 }
1278
1279 #[test]
1280 fn test_empty_offsets() {
1281 let f = Arc::new(Field::new("element", DataType::Int32, true));
1282 let string = ListArray::from(
1283 ArrayData::builder(DataType::List(f.clone()))
1284 .buffers(vec![Buffer::from(&[])])
1285 .add_child_data(ArrayData::new_empty(&DataType::Int32))
1286 .build()
1287 .unwrap(),
1288 );
1289 assert_eq!(string.value_offsets(), &[0]);
1290 let string = LargeListArray::from(
1291 ArrayData::builder(DataType::LargeList(f))
1292 .buffers(vec![Buffer::from(&[])])
1293 .add_child_data(ArrayData::new_empty(&DataType::Int32))
1294 .build()
1295 .unwrap(),
1296 );
1297 assert_eq!(string.len(), 0);
1298 assert_eq!(string.value_offsets(), &[0]);
1299 }
1300
1301 #[test]
1302 fn test_try_new() {
1303 let offsets = OffsetBuffer::new(vec![0, 1, 4, 5].into());
1304 let values = Int32Array::new(vec![1, 2, 3, 4, 5].into(), None);
1305 let values = Arc::new(values) as ArrayRef;
1306
1307 let field = Arc::new(Field::new("element", DataType::Int32, false));
1308 ListArray::new(field.clone(), offsets.clone(), values.clone(), None);
1309
1310 let nulls = NullBuffer::new_null(3);
1311 ListArray::new(field.clone(), offsets, values.clone(), Some(nulls));
1312
1313 let nulls = NullBuffer::new_null(3);
1314 let offsets = OffsetBuffer::new(vec![0, 1, 2, 4, 5].into());
1315 let err = LargeListArray::try_new(field, offsets.clone(), values.clone(), Some(nulls))
1316 .unwrap_err();
1317
1318 assert_eq!(
1319 err.to_string(),
1320 "Invalid argument error: Incorrect length of null buffer for LargeListArray, expected 4 got 3"
1321 );
1322
1323 let field = Arc::new(Field::new("element", DataType::Int64, false));
1324 let err = LargeListArray::try_new(field.clone(), offsets.clone(), values.clone(), None)
1325 .unwrap_err();
1326
1327 assert_eq!(
1328 err.to_string(),
1329 "Invalid argument error: LargeListArray expected data type Int64 got Int32 for \"element\""
1330 );
1331
1332 let nulls = NullBuffer::new_null(7);
1333 let values = Int64Array::new(vec![0; 7].into(), Some(nulls));
1334 let values = Arc::new(values);
1335
1336 let err =
1337 LargeListArray::try_new(field, offsets.clone(), values.clone(), None).unwrap_err();
1338
1339 assert_eq!(
1340 err.to_string(),
1341 "Invalid argument error: Non-nullable field of LargeListArray \"element\" cannot contain nulls"
1342 );
1343
1344 let field = Arc::new(Field::new("element", DataType::Int64, true));
1345 LargeListArray::new(field.clone(), offsets.clone(), values, None);
1346
1347 let values = Int64Array::new(vec![0; 2].into(), None);
1348 let err = LargeListArray::try_new(field, offsets, Arc::new(values), None).unwrap_err();
1349
1350 assert_eq!(
1351 err.to_string(),
1352 "Invalid argument error: Max offset of 5 exceeds length of values 2"
1353 );
1354 }
1355
1356 #[test]
1357 fn test_from_fixed_size_list() {
1358 let mut builder = FixedSizeListBuilder::new(Int32Builder::new(), 3);
1359 builder.values().append_slice(&[1, 2, 3]);
1360 builder.append(true);
1361 builder.values().append_slice(&[0, 0, 0]);
1362 builder.append(false);
1363 builder.values().append_slice(&[4, 5, 6]);
1364 builder.append(true);
1365 let list: ListArray = builder.finish().into();
1366
1367 let values: Vec<_> = list
1368 .iter()
1369 .map(|x| x.map(|x| x.as_primitive::<Int32Type>().values().to_vec()))
1370 .collect();
1371 assert_eq!(values, vec![Some(vec![1, 2, 3]), None, Some(vec![4, 5, 6])])
1372 }
1373
1374 #[test]
1375 fn test_nullable_union() {
1376 let offsets = OffsetBuffer::new(vec![0, 1, 4, 5].into());
1377 let mut builder = UnionBuilder::new_dense();
1378 builder.append::<Int32Type>("a", 1).unwrap();
1379 builder.append::<Int32Type>("b", 2).unwrap();
1380 builder.append::<Int32Type>("b", 3).unwrap();
1381 builder.append::<Int32Type>("a", 4).unwrap();
1382 builder.append::<Int32Type>("a", 5).unwrap();
1383 let values = builder.build().unwrap();
1384 let field = Arc::new(Field::new("element", values.data_type().clone(), false));
1385 ListArray::new(field.clone(), offsets, Arc::new(values), None);
1386 }
1387
1388 #[test]
1389 fn test_list_new_null_len() {
1390 let field = Arc::new(Field::new_list_field(DataType::Int32, true));
1391 let array = ListArray::new_null(field, 5);
1392 assert_eq!(array.len(), 5);
1393 }
1394
1395 #[test]
1396 fn test_list_from_iter_i32() {
1397 let array = ListArray::from_nested_iter::<Int32Builder, _, _, _>(vec![
1398 None,
1399 Some(vec![Some(1), None, Some(2)]),
1400 ]);
1401 let expected_offsets = &[0, 0, 3];
1402 let expected_values: ArrayRef = Arc::new(Int32Array::from(vec![Some(1), None, Some(2)]));
1403 assert_eq!(array.value_offsets(), expected_offsets);
1404 assert_eq!(array.values(), &expected_values);
1405 }
1406
1407 #[test]
1408 fn test_list_from_iter_bool() {
1409 let array = ListArray::from_nested_iter::<BooleanBuilder, _, _, _>(vec![
1410 Some(vec![None, Some(false), Some(true)]),
1411 None,
1412 ]);
1413 let expected_offsets = &[0, 3, 3];
1414 let expected_values: ArrayRef =
1415 Arc::new(BooleanArray::from(vec![None, Some(false), Some(true)]));
1416 assert_eq!(array.value_offsets(), expected_offsets);
1417 assert_eq!(array.values(), &expected_values);
1418 }
1419
1420 #[test]
1421 fn test_list_from_iter_str() {
1422 let array = ListArray::from_nested_iter::<StringBuilder, _, _, _>(vec![
1423 Some(vec![Some("foo"), None, Some("bar")]),
1424 None,
1425 ]);
1426 let expected_offsets = &[0, 3, 3];
1427 let expected_values: ArrayRef =
1428 Arc::new(StringArray::from(vec![Some("foo"), None, Some("bar")]));
1429 assert_eq!(array.value_offsets(), expected_offsets);
1430 assert_eq!(array.values(), &expected_values);
1431 }
1432
1433 #[test]
1434 fn test_list_from_iter_dict_str() {
1435 let array =
1436 ListArray::from_nested_iter::<StringDictionaryBuilder<Int8Type>, _, _, _>(vec![
1437 Some(vec![Some("foo"), None, Some("bar"), Some("foo")]),
1438 None,
1439 ]);
1440 let expected_offsets = &[0, 4, 4];
1441 let expected_dict_values: ArrayRef =
1442 Arc::new(StringArray::from(vec![Some("foo"), Some("bar")]));
1443 let expected_dict_keys = Int8Array::from(vec![Some(0), None, Some(1), Some(0)]);
1444 let expected_values: ArrayRef = Arc::new(
1445 Int8DictionaryArray::try_new(expected_dict_keys, expected_dict_values).unwrap(),
1446 );
1447 assert_eq!(array.value_offsets(), expected_offsets);
1448 assert_eq!(array.values(), &expected_values);
1449 }
1450}