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