1use crate::array::{get_offsets_from_buffer, make_array, print_long_array};
6use crate::builder::{ArrayBuilder, GenericListBuilder, PrimitiveBuilder};
7use crate::{
8 Array, ArrayAccessor, ArrayRef, ArrowPrimitiveType, FixedSizeListArray,
9 iterator::GenericListArrayIter, new_empty_array,
10};
11use arrow_buffer::{ArrowNativeType, NullBuffer, OffsetBuffer};
12use arrow_data::{ArrayData, ArrayDataBuilder};
13use arrow_schema::{ArrowError, DataType, FieldRef};
14use num_integer::Integer;
15use std::any::Any;
16use std::sync::Arc;
17
18pub trait OffsetSizeTrait:
28 ArrowNativeType + std::ops::AddAssign + Integer + num_traits::CheckedAdd + num_traits::CheckedSub
29{
30 const IS_LARGE: bool;
32 const PREFIX: &'static str;
34 const MAX_OFFSET: usize;
36}
37
38impl OffsetSizeTrait for i32 {
39 const IS_LARGE: bool = false;
40 const PREFIX: &'static str = "";
41 const MAX_OFFSET: usize = i32::MAX as usize;
42}
43
44impl OffsetSizeTrait for i64 {
45 const IS_LARGE: bool = true;
46 const PREFIX: &'static str = "Large";
47 const MAX_OFFSET: usize = i64::MAX as usize;
48}
49
50pub struct GenericListArray<OffsetSize: OffsetSizeTrait> {
159 data_type: DataType,
160 nulls: Option<NullBuffer>,
161 values: ArrayRef,
162 value_offsets: OffsetBuffer<OffsetSize>,
163}
164
165impl<OffsetSize: OffsetSizeTrait> Clone for GenericListArray<OffsetSize> {
166 fn clone(&self) -> Self {
167 Self {
168 data_type: self.data_type.clone(),
169 nulls: self.nulls.clone(),
170 values: self.values.clone(),
171 value_offsets: self.value_offsets.clone(),
172 }
173 }
174}
175
176impl<OffsetSize: OffsetSizeTrait> GenericListArray<OffsetSize> {
177 pub const DATA_TYPE_CONSTRUCTOR: fn(FieldRef) -> DataType = if OffsetSize::IS_LARGE {
181 DataType::LargeList
182 } else {
183 DataType::List
184 };
185
186 pub fn try_new(
197 field: FieldRef,
198 offsets: OffsetBuffer<OffsetSize>,
199 values: ArrayRef,
200 nulls: Option<NullBuffer>,
201 ) -> Result<Self, ArrowError> {
202 let len = offsets.len() - 1; let end_offset = offsets.last().as_usize();
204 if end_offset > values.len() {
207 return Err(ArrowError::InvalidArgumentError(format!(
208 "Max offset of {end_offset} exceeds length of values {}",
209 values.len()
210 )));
211 }
212
213 if let Some(n) = nulls.as_ref()
214 && n.len() != len
215 {
216 return Err(ArrowError::InvalidArgumentError(format!(
217 "Incorrect length of null buffer for {}ListArray, expected {len} got {}",
218 OffsetSize::PREFIX,
219 n.len(),
220 )));
221 }
222 if !field.is_nullable() && values.logical_null_count() != 0 {
223 return Err(ArrowError::InvalidArgumentError(format!(
224 "Non-nullable field of {}ListArray {:?} cannot contain nulls",
225 OffsetSize::PREFIX,
226 field.name()
227 )));
228 }
229
230 if field.data_type() != values.data_type() {
231 return Err(ArrowError::InvalidArgumentError(format!(
232 "{}ListArray expected data type {} got {} for {:?}",
233 OffsetSize::PREFIX,
234 field.data_type(),
235 values.data_type(),
236 field.name()
237 )));
238 }
239
240 Ok(Self {
241 data_type: Self::DATA_TYPE_CONSTRUCTOR(field),
242 nulls,
243 values,
244 value_offsets: offsets,
245 })
246 }
247
248 pub fn new(
254 field: FieldRef,
255 offsets: OffsetBuffer<OffsetSize>,
256 values: ArrayRef,
257 nulls: Option<NullBuffer>,
258 ) -> Self {
259 Self::try_new(field, offsets, values, nulls).unwrap()
260 }
261
262 pub unsafe fn new_unchecked(
269 field: FieldRef,
270 offsets: OffsetBuffer<OffsetSize>,
271 values: ArrayRef,
272 nulls: Option<NullBuffer>,
273 ) -> Self {
274 if cfg!(feature = "force_validate") {
275 return Self::new(field, offsets, values, nulls);
276 }
277 Self {
278 data_type: Self::DATA_TYPE_CONSTRUCTOR(field),
279 nulls,
280 values,
281 value_offsets: offsets,
282 }
283 }
284
285 pub fn new_null(field: FieldRef, len: usize) -> Self {
287 let values = new_empty_array(field.data_type());
288 Self {
289 data_type: Self::DATA_TYPE_CONSTRUCTOR(field),
290 nulls: Some(NullBuffer::new_null(len)),
291 value_offsets: OffsetBuffer::new_zeroed(len),
292 values,
293 }
294 }
295
296 pub fn into_parts(
298 self,
299 ) -> (
300 FieldRef,
301 OffsetBuffer<OffsetSize>,
302 ArrayRef,
303 Option<NullBuffer>,
304 ) {
305 let (DataType::List(f) | DataType::LargeList(f)) = self.data_type else {
306 unreachable!()
307 };
308 (f, self.value_offsets, self.values, self.nulls)
309 }
310
311 pub fn value_field(&self) -> &FieldRef {
313 match &self.data_type {
314 DataType::List(f) | DataType::LargeList(f) => f,
315 _ => unreachable!(),
316 }
317 }
318
319 #[inline]
328 pub fn offsets(&self) -> &OffsetBuffer<OffsetSize> {
329 &self.value_offsets
330 }
331
332 #[inline]
339 pub fn values(&self) -> &ArrayRef {
340 &self.values
341 }
342
343 pub fn value_type(&self) -> DataType {
345 self.values.data_type().clone()
346 }
347
348 pub unsafe fn value_unchecked(&self, i: usize) -> ArrayRef {
356 let end = unsafe { self.value_offsets().get_unchecked(i + 1).as_usize() };
357 let start = unsafe { self.value_offsets().get_unchecked(i).as_usize() };
358 self.values.slice(start, end - start)
359 }
360
361 pub fn value(&self, i: usize) -> ArrayRef {
369 let end = self.value_offsets()[i + 1].as_usize();
370 let start = self.value_offsets()[i].as_usize();
371 self.values.slice(start, end - start)
372 }
373
374 #[inline]
378 pub fn value_offsets(&self) -> &[OffsetSize] {
379 &self.value_offsets
380 }
381
382 #[inline]
387 pub fn value_length(&self, i: usize) -> OffsetSize {
388 let offsets = self.value_offsets();
389 offsets[i + 1] - offsets[i]
390 }
391
392 pub fn iter<'a>(&'a self) -> GenericListArrayIter<'a, OffsetSize> {
394 GenericListArrayIter::<'a, OffsetSize>::new(self)
395 }
396
397 #[inline]
398 fn get_type(data_type: &DataType) -> Option<&DataType> {
399 match (OffsetSize::IS_LARGE, data_type) {
400 (true, DataType::LargeList(child)) | (false, DataType::List(child)) => {
401 Some(child.data_type())
402 }
403 _ => None,
404 }
405 }
406
407 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<'a, OffsetSize: OffsetSizeTrait> IntoIterator for &'a GenericListArray<OffsetSize> {
671 type Item = Option<ArrayRef>;
672 type IntoIter = GenericListArrayIter<'a, OffsetSize>;
673
674 fn into_iter(self) -> Self::IntoIter {
675 GenericListArrayIter::<'a, OffsetSize>::new(self)
676 }
677}
678
679impl<OffsetSize: OffsetSizeTrait> ArrayAccessor for &GenericListArray<OffsetSize> {
680 type Item = ArrayRef;
681
682 fn value(&self, index: usize) -> Self::Item {
683 GenericListArray::value(self, index)
684 }
685
686 unsafe fn value_unchecked(&self, index: usize) -> Self::Item {
687 GenericListArray::value(self, index)
688 }
689}
690
691impl<OffsetSize: OffsetSizeTrait> std::fmt::Debug for GenericListArray<OffsetSize> {
692 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
693 let prefix = OffsetSize::PREFIX;
694
695 write!(f, "{prefix}ListArray\n[\n")?;
696 print_long_array(self, f, &mut |index, f| {
697 std::fmt::Debug::fmt(&self.value(index), f)
698 })?;
699 write!(f, "]")
700 }
701}
702
703pub type ListArray = GenericListArray<i32>;
707
708pub type LargeListArray = GenericListArray<i64>;
712
713#[cfg(test)]
714mod tests {
715 use super::*;
716 use crate::builder::{
717 BooleanBuilder, FixedSizeListBuilder, Int32Builder, ListBuilder, StringBuilder,
718 StringDictionaryBuilder, UnionBuilder,
719 };
720 use crate::cast::AsArray;
721 use crate::types::{Int8Type, Int32Type};
722 use crate::{
723 BooleanArray, Int8Array, Int8DictionaryArray, Int32Array, Int64Array, StringArray,
724 };
725 use arrow_buffer::{Buffer, ScalarBuffer, bit_util};
726 use arrow_schema::Field;
727
728 fn create_from_buffers() -> ListArray {
729 let values = Int32Array::from(vec![0, 1, 2, 3, 4, 5, 6, 7]);
731 let offsets = OffsetBuffer::new(ScalarBuffer::from(vec![0, 3, 6, 8]));
732 let field = Arc::new(Field::new_list_field(DataType::Int32, true));
733 ListArray::new(field, offsets, Arc::new(values), None)
734 }
735
736 #[test]
737 fn test_from_iter_primitive() {
738 let data = vec![
739 Some(vec![Some(0), Some(1), Some(2)]),
740 Some(vec![Some(3), Some(4), Some(5)]),
741 Some(vec![Some(6), Some(7)]),
742 ];
743 let list_array = ListArray::from_iter_primitive::<Int32Type, _, _>(data);
744
745 let another = create_from_buffers();
746 assert_eq!(list_array, another)
747 }
748
749 #[test]
750 fn test_empty_list_array() {
751 let value_data = ArrayData::builder(DataType::Int32)
753 .len(0)
754 .add_buffer(Buffer::from([]))
755 .build()
756 .unwrap();
757
758 let value_offsets = Buffer::from([]);
760
761 let list_data_type =
763 DataType::List(Arc::new(Field::new_list_field(DataType::Int32, false)));
764 let list_data = ArrayData::builder(list_data_type)
765 .len(0)
766 .add_buffer(value_offsets)
767 .add_child_data(value_data)
768 .build()
769 .unwrap();
770
771 let list_array = ListArray::from(list_data);
772 assert_eq!(list_array.len(), 0)
773 }
774
775 #[test]
776 fn test_list_array() {
777 let value_data = ArrayData::builder(DataType::Int32)
779 .len(8)
780 .add_buffer(Buffer::from_slice_ref([0, 1, 2, 3, 4, 5, 6, 7]))
781 .build()
782 .unwrap();
783
784 let value_offsets = Buffer::from_slice_ref([0, 3, 6, 8]);
787
788 let list_data_type =
790 DataType::List(Arc::new(Field::new_list_field(DataType::Int32, false)));
791 let list_data = ArrayData::builder(list_data_type.clone())
792 .len(3)
793 .add_buffer(value_offsets.clone())
794 .add_child_data(value_data.clone())
795 .build()
796 .unwrap();
797 let list_array = ListArray::from(list_data);
798
799 let values = list_array.values();
800 assert_eq!(value_data, values.to_data());
801 assert_eq!(DataType::Int32, list_array.value_type());
802 assert_eq!(3, list_array.len());
803 assert_eq!(0, list_array.null_count());
804 assert_eq!(6, list_array.value_offsets()[2]);
805 assert_eq!(2, list_array.value_length(2));
806 assert_eq!(0, list_array.value(0).as_primitive::<Int32Type>().value(0));
807 assert_eq!(
808 0,
809 unsafe { list_array.value_unchecked(0) }
810 .as_primitive::<Int32Type>()
811 .value(0)
812 );
813 for i in 0..3 {
814 assert!(list_array.is_valid(i));
815 assert!(!list_array.is_null(i));
816 }
817
818 let list_data = ArrayData::builder(list_data_type)
821 .len(2)
822 .offset(1)
823 .add_buffer(value_offsets)
824 .add_child_data(value_data.clone())
825 .build()
826 .unwrap();
827 let list_array = ListArray::from(list_data);
828
829 let values = list_array.values();
830 assert_eq!(value_data, values.to_data());
831 assert_eq!(DataType::Int32, list_array.value_type());
832 assert_eq!(2, list_array.len());
833 assert_eq!(0, list_array.null_count());
834 assert_eq!(6, list_array.value_offsets()[1]);
835 assert_eq!(2, list_array.value_length(1));
836 assert_eq!(3, list_array.value(0).as_primitive::<Int32Type>().value(0));
837 assert_eq!(
838 3,
839 unsafe { list_array.value_unchecked(0) }
840 .as_primitive::<Int32Type>()
841 .value(0)
842 );
843 }
844
845 #[test]
846 fn test_large_list_array() {
847 let value_data = ArrayData::builder(DataType::Int32)
849 .len(8)
850 .add_buffer(Buffer::from_slice_ref([0, 1, 2, 3, 4, 5, 6, 7]))
851 .build()
852 .unwrap();
853
854 let value_offsets = Buffer::from_slice_ref([0i64, 3, 6, 8]);
857
858 let list_data_type = DataType::new_large_list(DataType::Int32, false);
860 let list_data = ArrayData::builder(list_data_type.clone())
861 .len(3)
862 .add_buffer(value_offsets.clone())
863 .add_child_data(value_data.clone())
864 .build()
865 .unwrap();
866 let list_array = LargeListArray::from(list_data);
867
868 let values = list_array.values();
869 assert_eq!(value_data, values.to_data());
870 assert_eq!(DataType::Int32, list_array.value_type());
871 assert_eq!(3, list_array.len());
872 assert_eq!(0, list_array.null_count());
873 assert_eq!(6, list_array.value_offsets()[2]);
874 assert_eq!(2, list_array.value_length(2));
875 assert_eq!(0, list_array.value(0).as_primitive::<Int32Type>().value(0));
876 assert_eq!(
877 0,
878 unsafe { list_array.value_unchecked(0) }
879 .as_primitive::<Int32Type>()
880 .value(0)
881 );
882 for i in 0..3 {
883 assert!(list_array.is_valid(i));
884 assert!(!list_array.is_null(i));
885 }
886
887 let list_data = ArrayData::builder(list_data_type)
890 .len(2)
891 .offset(1)
892 .add_buffer(value_offsets)
893 .add_child_data(value_data.clone())
894 .build()
895 .unwrap();
896 let list_array = LargeListArray::from(list_data);
897
898 let values = list_array.values();
899 assert_eq!(value_data, values.to_data());
900 assert_eq!(DataType::Int32, list_array.value_type());
901 assert_eq!(2, list_array.len());
902 assert_eq!(0, list_array.null_count());
903 assert_eq!(6, list_array.value_offsets()[1]);
904 assert_eq!(2, list_array.value_length(1));
905 assert_eq!(3, list_array.value(0).as_primitive::<Int32Type>().value(0));
906 assert_eq!(
907 3,
908 unsafe { list_array.value_unchecked(0) }
909 .as_primitive::<Int32Type>()
910 .value(0)
911 );
912 }
913
914 #[test]
915 fn test_list_array_slice() {
916 let value_data = ArrayData::builder(DataType::Int32)
918 .len(10)
919 .add_buffer(Buffer::from_slice_ref([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]))
920 .build()
921 .unwrap();
922
923 let value_offsets = Buffer::from_slice_ref([0, 2, 2, 2, 4, 6, 6, 9, 9, 10]);
926 let mut null_bits: [u8; 2] = [0; 2];
928 bit_util::set_bit(&mut null_bits, 0);
929 bit_util::set_bit(&mut null_bits, 3);
930 bit_util::set_bit(&mut null_bits, 4);
931 bit_util::set_bit(&mut null_bits, 6);
932 bit_util::set_bit(&mut null_bits, 8);
933
934 let list_data_type =
936 DataType::List(Arc::new(Field::new_list_field(DataType::Int32, false)));
937 let list_data = ArrayData::builder(list_data_type)
938 .len(9)
939 .add_buffer(value_offsets)
940 .add_child_data(value_data.clone())
941 .null_bit_buffer(Some(Buffer::from(null_bits)))
942 .build()
943 .unwrap();
944 let list_array = ListArray::from(list_data);
945
946 let values = list_array.values();
947 assert_eq!(value_data, values.to_data());
948 assert_eq!(DataType::Int32, list_array.value_type());
949 assert_eq!(9, list_array.len());
950 assert_eq!(4, list_array.null_count());
951 assert_eq!(2, list_array.value_offsets()[3]);
952 assert_eq!(2, list_array.value_length(3));
953
954 let sliced_array = list_array.slice(1, 6);
955 assert_eq!(6, sliced_array.len());
956 assert_eq!(3, sliced_array.null_count());
957
958 for i in 0..sliced_array.len() {
959 if bit_util::get_bit(&null_bits, 1 + i) {
960 assert!(sliced_array.is_valid(i));
961 } else {
962 assert!(sliced_array.is_null(i));
963 }
964 }
965
966 let sliced_list_array = sliced_array.as_any().downcast_ref::<ListArray>().unwrap();
968 assert_eq!(2, sliced_list_array.value_offsets()[2]);
969 assert_eq!(2, sliced_list_array.value_length(2));
970 assert_eq!(4, sliced_list_array.value_offsets()[3]);
971 assert_eq!(2, sliced_list_array.value_length(3));
972 assert_eq!(6, sliced_list_array.value_offsets()[5]);
973 assert_eq!(3, sliced_list_array.value_length(5));
974 }
975
976 #[test]
977 fn test_large_list_array_slice() {
978 let value_data = ArrayData::builder(DataType::Int32)
980 .len(10)
981 .add_buffer(Buffer::from_slice_ref([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]))
982 .build()
983 .unwrap();
984
985 let value_offsets = Buffer::from_slice_ref([0i64, 2, 2, 2, 4, 6, 6, 9, 9, 10]);
988 let mut null_bits: [u8; 2] = [0; 2];
990 bit_util::set_bit(&mut null_bits, 0);
991 bit_util::set_bit(&mut null_bits, 3);
992 bit_util::set_bit(&mut null_bits, 4);
993 bit_util::set_bit(&mut null_bits, 6);
994 bit_util::set_bit(&mut null_bits, 8);
995
996 let list_data_type = DataType::new_large_list(DataType::Int32, false);
998 let list_data = ArrayData::builder(list_data_type)
999 .len(9)
1000 .add_buffer(value_offsets)
1001 .add_child_data(value_data.clone())
1002 .null_bit_buffer(Some(Buffer::from(null_bits)))
1003 .build()
1004 .unwrap();
1005 let list_array = LargeListArray::from(list_data);
1006
1007 let values = list_array.values();
1008 assert_eq!(value_data, values.to_data());
1009 assert_eq!(DataType::Int32, list_array.value_type());
1010 assert_eq!(9, list_array.len());
1011 assert_eq!(4, list_array.null_count());
1012 assert_eq!(2, list_array.value_offsets()[3]);
1013 assert_eq!(2, list_array.value_length(3));
1014
1015 let sliced_array = list_array.slice(1, 6);
1016 assert_eq!(6, sliced_array.len());
1017 assert_eq!(3, sliced_array.null_count());
1018
1019 for i in 0..sliced_array.len() {
1020 if bit_util::get_bit(&null_bits, 1 + i) {
1021 assert!(sliced_array.is_valid(i));
1022 } else {
1023 assert!(sliced_array.is_null(i));
1024 }
1025 }
1026
1027 let sliced_list_array = sliced_array
1029 .as_any()
1030 .downcast_ref::<LargeListArray>()
1031 .unwrap();
1032 assert_eq!(2, sliced_list_array.value_offsets()[2]);
1033 assert_eq!(2, sliced_list_array.value_length(2));
1034 assert_eq!(4, sliced_list_array.value_offsets()[3]);
1035 assert_eq!(2, sliced_list_array.value_length(3));
1036 assert_eq!(6, sliced_list_array.value_offsets()[5]);
1037 assert_eq!(3, sliced_list_array.value_length(5));
1038 }
1039
1040 #[test]
1041 #[should_panic(expected = "index out of bounds: the len is 10 but the index is 11")]
1042 fn test_list_array_index_out_of_bound() {
1043 let value_data = ArrayData::builder(DataType::Int32)
1045 .len(10)
1046 .add_buffer(Buffer::from_slice_ref([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]))
1047 .build()
1048 .unwrap();
1049
1050 let value_offsets = Buffer::from_slice_ref([0i64, 2, 2, 2, 4, 6, 6, 9, 9, 10]);
1053 let mut null_bits: [u8; 2] = [0; 2];
1055 bit_util::set_bit(&mut null_bits, 0);
1056 bit_util::set_bit(&mut null_bits, 3);
1057 bit_util::set_bit(&mut null_bits, 4);
1058 bit_util::set_bit(&mut null_bits, 6);
1059 bit_util::set_bit(&mut null_bits, 8);
1060
1061 let list_data_type = DataType::new_large_list(DataType::Int32, false);
1063 let list_data = ArrayData::builder(list_data_type)
1064 .len(9)
1065 .add_buffer(value_offsets)
1066 .add_child_data(value_data)
1067 .null_bit_buffer(Some(Buffer::from(null_bits)))
1068 .build()
1069 .unwrap();
1070 let list_array = LargeListArray::from(list_data);
1071 assert_eq!(9, list_array.len());
1072
1073 list_array.value(10);
1074 }
1075 #[test]
1076 #[should_panic(expected = "ListArray data should contain a single buffer only (value offsets)")]
1077 #[cfg(not(feature = "force_validate"))]
1080 fn test_list_array_invalid_buffer_len() {
1081 let value_data = unsafe {
1082 ArrayData::builder(DataType::Int32)
1083 .len(8)
1084 .add_buffer(Buffer::from_slice_ref([0, 1, 2, 3, 4, 5, 6, 7]))
1085 .build_unchecked()
1086 };
1087 let list_data_type =
1088 DataType::List(Arc::new(Field::new_list_field(DataType::Int32, false)));
1089 let list_data = unsafe {
1090 ArrayData::builder(list_data_type)
1091 .len(3)
1092 .add_child_data(value_data)
1093 .build_unchecked()
1094 };
1095 drop(ListArray::from(list_data));
1096 }
1097
1098 #[test]
1099 #[should_panic(expected = "ListArray should contain a single child array (values array)")]
1100 #[cfg(not(feature = "force_validate"))]
1103 fn test_list_array_invalid_child_array_len() {
1104 let value_offsets = Buffer::from_slice_ref([0, 2, 5, 7]);
1105 let list_data_type =
1106 DataType::List(Arc::new(Field::new_list_field(DataType::Int32, false)));
1107 let list_data = unsafe {
1108 ArrayData::builder(list_data_type)
1109 .len(3)
1110 .add_buffer(value_offsets)
1111 .build_unchecked()
1112 };
1113 drop(ListArray::from(list_data));
1114 }
1115
1116 #[test]
1117 #[should_panic(expected = "[Large]ListArray's datatype must be [Large]ListArray(). It is List")]
1118 fn test_from_array_data_validation() {
1119 let mut builder = ListBuilder::new(Int32Builder::new());
1120 builder.values().append_value(1);
1121 builder.append(true);
1122 let array = builder.finish();
1123 let _ = LargeListArray::from(array.into_data());
1124 }
1125
1126 #[test]
1127 fn test_list_array_offsets_need_not_start_at_zero() {
1128 let value_data = ArrayData::builder(DataType::Int32)
1129 .len(8)
1130 .add_buffer(Buffer::from_slice_ref([0, 1, 2, 3, 4, 5, 6, 7]))
1131 .build()
1132 .unwrap();
1133
1134 let value_offsets = Buffer::from_slice_ref([2, 2, 5, 7]);
1135
1136 let list_data_type =
1137 DataType::List(Arc::new(Field::new_list_field(DataType::Int32, false)));
1138 let list_data = ArrayData::builder(list_data_type)
1139 .len(3)
1140 .add_buffer(value_offsets)
1141 .add_child_data(value_data)
1142 .build()
1143 .unwrap();
1144
1145 let list_array = ListArray::from(list_data);
1146 assert_eq!(list_array.value_length(0), 0);
1147 assert_eq!(list_array.value_length(1), 3);
1148 assert_eq!(list_array.value_length(2), 2);
1149 }
1150
1151 #[test]
1152 #[should_panic(expected = "Memory pointer is not aligned with the specified scalar type")]
1153 #[cfg(not(feature = "force_validate"))]
1156 fn test_primitive_array_alignment() {
1157 let buf = Buffer::from_slice_ref([0_u64]);
1158 let buf2 = buf.slice(1);
1159 let array_data = unsafe {
1160 ArrayData::builder(DataType::Int32)
1161 .add_buffer(buf2)
1162 .build_unchecked()
1163 };
1164 drop(Int32Array::from(array_data));
1165 }
1166
1167 #[test]
1168 #[should_panic(expected = "Memory pointer is not aligned with the specified scalar type")]
1169 #[cfg(not(feature = "force_validate"))]
1172 fn test_list_array_alignment() {
1173 let buf = Buffer::from_slice_ref([0_u64]);
1174 let buf2 = buf.slice(1);
1175
1176 let values: [i32; 8] = [0; 8];
1177 let value_data = unsafe {
1178 ArrayData::builder(DataType::Int32)
1179 .add_buffer(Buffer::from_slice_ref(values))
1180 .build_unchecked()
1181 };
1182
1183 let list_data_type =
1184 DataType::List(Arc::new(Field::new_list_field(DataType::Int32, false)));
1185 let list_data = unsafe {
1186 ArrayData::builder(list_data_type)
1187 .add_buffer(buf2)
1188 .add_child_data(value_data)
1189 .build_unchecked()
1190 };
1191 drop(ListArray::from(list_data));
1192 }
1193
1194 #[test]
1195 fn list_array_equality() {
1196 fn do_comparison(
1198 lhs_data: Vec<Option<Vec<Option<i32>>>>,
1199 rhs_data: Vec<Option<Vec<Option<i32>>>>,
1200 should_equal: bool,
1201 ) {
1202 let lhs = ListArray::from_iter_primitive::<Int32Type, _, _>(lhs_data.clone());
1203 let rhs = ListArray::from_iter_primitive::<Int32Type, _, _>(rhs_data.clone());
1204 assert_eq!(lhs == rhs, should_equal);
1205
1206 let lhs = LargeListArray::from_iter_primitive::<Int32Type, _, _>(lhs_data);
1207 let rhs = LargeListArray::from_iter_primitive::<Int32Type, _, _>(rhs_data);
1208 assert_eq!(lhs == rhs, should_equal);
1209 }
1210
1211 do_comparison(
1212 vec![
1213 Some(vec![Some(0), Some(1), Some(2)]),
1214 None,
1215 Some(vec![Some(3), None, Some(5)]),
1216 Some(vec![Some(6), Some(7)]),
1217 ],
1218 vec![
1219 Some(vec![Some(0), Some(1), Some(2)]),
1220 None,
1221 Some(vec![Some(3), None, Some(5)]),
1222 Some(vec![Some(6), Some(7)]),
1223 ],
1224 true,
1225 );
1226
1227 do_comparison(
1228 vec![
1229 None,
1230 None,
1231 Some(vec![Some(3), None, Some(5)]),
1232 Some(vec![Some(6), Some(7)]),
1233 ],
1234 vec![
1235 Some(vec![Some(0), Some(1), Some(2)]),
1236 None,
1237 Some(vec![Some(3), None, Some(5)]),
1238 Some(vec![Some(6), Some(7)]),
1239 ],
1240 false,
1241 );
1242
1243 do_comparison(
1244 vec![
1245 None,
1246 None,
1247 Some(vec![Some(3), None, Some(5)]),
1248 Some(vec![Some(6), Some(7)]),
1249 ],
1250 vec![
1251 None,
1252 None,
1253 Some(vec![Some(3), None, Some(5)]),
1254 Some(vec![Some(0), Some(0)]),
1255 ],
1256 false,
1257 );
1258
1259 do_comparison(
1260 vec![None, None, Some(vec![Some(1)])],
1261 vec![None, None, Some(vec![Some(2)])],
1262 false,
1263 );
1264 }
1265
1266 #[test]
1267 fn test_empty_offsets() {
1268 let f = Arc::new(Field::new("element", DataType::Int32, true));
1269 let string = ListArray::from(
1270 ArrayData::builder(DataType::List(f.clone()))
1271 .buffers(vec![Buffer::from(&[])])
1272 .add_child_data(ArrayData::new_empty(&DataType::Int32))
1273 .build()
1274 .unwrap(),
1275 );
1276 assert_eq!(string.value_offsets(), &[0]);
1277 let string = LargeListArray::from(
1278 ArrayData::builder(DataType::LargeList(f))
1279 .buffers(vec![Buffer::from(&[])])
1280 .add_child_data(ArrayData::new_empty(&DataType::Int32))
1281 .build()
1282 .unwrap(),
1283 );
1284 assert_eq!(string.len(), 0);
1285 assert_eq!(string.value_offsets(), &[0]);
1286 }
1287
1288 #[test]
1289 fn test_try_new() {
1290 let offsets = OffsetBuffer::new(vec![0, 1, 4, 5].into());
1291 let values = Int32Array::new(vec![1, 2, 3, 4, 5].into(), None);
1292 let values = Arc::new(values) as ArrayRef;
1293
1294 let field = Arc::new(Field::new("element", DataType::Int32, false));
1295 ListArray::new(field.clone(), offsets.clone(), values.clone(), None);
1296
1297 let nulls = NullBuffer::new_null(3);
1298 ListArray::new(field.clone(), offsets, values.clone(), Some(nulls));
1299
1300 let nulls = NullBuffer::new_null(3);
1301 let offsets = OffsetBuffer::new(vec![0, 1, 2, 4, 5].into());
1302 let err = LargeListArray::try_new(field, offsets.clone(), values.clone(), Some(nulls))
1303 .unwrap_err();
1304
1305 assert_eq!(
1306 err.to_string(),
1307 "Invalid argument error: Incorrect length of null buffer for LargeListArray, expected 4 got 3"
1308 );
1309
1310 let field = Arc::new(Field::new("element", DataType::Int64, false));
1311 let err = LargeListArray::try_new(field.clone(), offsets.clone(), values.clone(), None)
1312 .unwrap_err();
1313
1314 assert_eq!(
1315 err.to_string(),
1316 "Invalid argument error: LargeListArray expected data type Int64 got Int32 for \"element\""
1317 );
1318
1319 let nulls = NullBuffer::new_null(7);
1320 let values = Int64Array::new(vec![0; 7].into(), Some(nulls));
1321 let values = Arc::new(values);
1322
1323 let err =
1324 LargeListArray::try_new(field, offsets.clone(), values.clone(), None).unwrap_err();
1325
1326 assert_eq!(
1327 err.to_string(),
1328 "Invalid argument error: Non-nullable field of LargeListArray \"element\" cannot contain nulls"
1329 );
1330
1331 let field = Arc::new(Field::new("element", DataType::Int64, true));
1332 LargeListArray::new(field.clone(), offsets.clone(), values, None);
1333
1334 let values = Int64Array::new(vec![0; 2].into(), None);
1335 let err = LargeListArray::try_new(field, offsets, Arc::new(values), None).unwrap_err();
1336
1337 assert_eq!(
1338 err.to_string(),
1339 "Invalid argument error: Max offset of 5 exceeds length of values 2"
1340 );
1341 }
1342
1343 #[test]
1344 fn test_try_new_non_nullable_field_dictionary_values() {
1345 let keys = Int8Array::new(vec![0i8, 1].into(), Some(NullBuffer::new_valid(2)));
1346 let values = StringArray::from(vec!["x", "y"]);
1347 let dict = Int8DictionaryArray::try_new(keys, Arc::new(values)).unwrap();
1348 let field = Arc::new(Field::new("element", dict.data_type().clone(), false));
1349 ListArray::try_new(
1350 field,
1351 OffsetBuffer::new(vec![0, 2].into()),
1352 Arc::new(dict),
1353 None,
1354 )
1355 .unwrap();
1356
1357 let keys = Int8Array::from(vec![Some(0i8), None]);
1358 let values = StringArray::from(vec!["x", "y"]);
1359 let dict = Int8DictionaryArray::try_new(keys, Arc::new(values)).unwrap();
1360 let field = Arc::new(Field::new("element", dict.data_type().clone(), false));
1361 let err = ListArray::try_new(
1362 field,
1363 OffsetBuffer::new(vec![0, 2].into()),
1364 Arc::new(dict),
1365 None,
1366 )
1367 .unwrap_err();
1368
1369 assert!(err.to_string().contains("cannot contain nulls"));
1370 }
1371
1372 #[test]
1373 fn test_from_fixed_size_list() {
1374 let mut builder = FixedSizeListBuilder::new(Int32Builder::new(), 3);
1375 builder.values().append_slice(&[1, 2, 3]);
1376 builder.append(true);
1377 builder.values().append_slice(&[0, 0, 0]);
1378 builder.append(false);
1379 builder.values().append_slice(&[4, 5, 6]);
1380 builder.append(true);
1381 let list: ListArray = builder.finish().into();
1382
1383 let values: Vec<_> = list
1384 .iter()
1385 .map(|x| x.map(|x| x.as_primitive::<Int32Type>().values().to_vec()))
1386 .collect();
1387 assert_eq!(values, vec![Some(vec![1, 2, 3]), None, Some(vec![4, 5, 6])])
1388 }
1389
1390 #[test]
1391 fn test_nullable_union() {
1392 let offsets = OffsetBuffer::new(vec![0, 1, 4, 5].into());
1393 let mut builder = UnionBuilder::new_dense();
1394 builder.append::<Int32Type>("a", 1).unwrap();
1395 builder.append::<Int32Type>("b", 2).unwrap();
1396 builder.append::<Int32Type>("b", 3).unwrap();
1397 builder.append::<Int32Type>("a", 4).unwrap();
1398 builder.append::<Int32Type>("a", 5).unwrap();
1399 let values = builder.build().unwrap();
1400 let field = Arc::new(Field::new("element", values.data_type().clone(), false));
1401 ListArray::new(field.clone(), offsets, Arc::new(values), None);
1402 }
1403
1404 #[test]
1405 fn test_list_new_null_len() {
1406 let field = Arc::new(Field::new_list_field(DataType::Int32, true));
1407 let array = ListArray::new_null(field, 5);
1408 assert_eq!(array.len(), 5);
1409 }
1410
1411 #[test]
1412 fn test_list_from_iter_i32() {
1413 let array = ListArray::from_nested_iter::<Int32Builder, _, _, _>(vec![
1414 None,
1415 Some(vec![Some(1), None, Some(2)]),
1416 ]);
1417 let expected_offsets = &[0, 0, 3];
1418 let expected_values: ArrayRef = Arc::new(Int32Array::from(vec![Some(1), None, Some(2)]));
1419 assert_eq!(array.value_offsets(), expected_offsets);
1420 assert_eq!(array.values(), &expected_values);
1421 }
1422
1423 #[test]
1424 fn test_list_from_iter_bool() {
1425 let array = ListArray::from_nested_iter::<BooleanBuilder, _, _, _>(vec![
1426 Some(vec![None, Some(false), Some(true)]),
1427 None,
1428 ]);
1429 let expected_offsets = &[0, 3, 3];
1430 let expected_values: ArrayRef =
1431 Arc::new(BooleanArray::from(vec![None, Some(false), Some(true)]));
1432 assert_eq!(array.value_offsets(), expected_offsets);
1433 assert_eq!(array.values(), &expected_values);
1434 }
1435
1436 #[test]
1437 fn test_list_from_iter_str() {
1438 let array = ListArray::from_nested_iter::<StringBuilder, _, _, _>(vec![
1439 Some(vec![Some("foo"), None, Some("bar")]),
1440 None,
1441 ]);
1442 let expected_offsets = &[0, 3, 3];
1443 let expected_values: ArrayRef =
1444 Arc::new(StringArray::from(vec![Some("foo"), None, Some("bar")]));
1445 assert_eq!(array.value_offsets(), expected_offsets);
1446 assert_eq!(array.values(), &expected_values);
1447 }
1448
1449 #[test]
1450 fn test_list_from_iter_dict_str() {
1451 let array =
1452 ListArray::from_nested_iter::<StringDictionaryBuilder<Int8Type>, _, _, _>(vec![
1453 Some(vec![Some("foo"), None, Some("bar"), Some("foo")]),
1454 None,
1455 ]);
1456 let expected_offsets = &[0, 4, 4];
1457 let expected_dict_values: ArrayRef =
1458 Arc::new(StringArray::from(vec![Some("foo"), Some("bar")]));
1459 let expected_dict_keys = Int8Array::from(vec![Some(0), None, Some(1), Some(0)]);
1460 let expected_values: ArrayRef = Arc::new(
1461 Int8DictionaryArray::try_new(expected_dict_keys, expected_dict_values).unwrap(),
1462 );
1463 assert_eq!(array.value_offsets(), expected_offsets);
1464 assert_eq!(array.values(), &expected_values);
1465 }
1466}