Skip to main content

arrow_array/array/
list_view_array.rs

1// Licensed to the Apache Software Foundation (ASF) under one
2// or more contributor license agreements.  See the NOTICE file
3// distributed with this work for additional information
4// regarding copyright ownership.  The ASF licenses this file
5// to you under the Apache License, Version 2.0 (the
6// "License"); you may not use this file except in compliance
7// with the License.  You may obtain a copy of the License at
8//
9//   http://www.apache.org/licenses/LICENSE-2.0
10//
11// Unless required by applicable law or agreed to in writing,
12// software distributed under the License is distributed on an
13// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14// KIND, either express or implied.  See the License for the
15// specific language governing permissions and limitations
16// under the License.
17
18use arrow_buffer::{Buffer, NullBuffer, ScalarBuffer};
19use arrow_data::{ArrayData, ArrayDataBuilder};
20use arrow_schema::{ArrowError, DataType, FieldRef};
21use std::any::Any;
22use std::ops::Add;
23use std::sync::Arc;
24
25use crate::array::{make_array, print_long_array};
26use crate::builder::{GenericListViewBuilder, PrimitiveBuilder};
27use crate::iterator::GenericListViewArrayIter;
28use crate::{
29    Array, ArrayAccessor, ArrayRef, ArrowPrimitiveType, FixedSizeListArray, GenericListArray,
30    OffsetSizeTrait, new_empty_array,
31};
32
33/// A [`GenericListViewArray`] of variable size lists, storing offsets as `i32`.
34pub type ListViewArray = GenericListViewArray<i32>;
35
36/// A [`GenericListViewArray`] of variable size lists, storing offsets as `i64`.
37pub type LargeListViewArray = GenericListViewArray<i64>;
38
39/// An array of [variable length lists], specifically in the [list-view layout].
40///
41/// Differs from [`GenericListArray`] (which represents the [list layout]) in that
42/// the sizes of the child arrays are explicitly encoded in a separate buffer, instead
43/// of being derived from the difference between subsequent offsets in the offset buffer.
44///
45/// This allows the offsets (and subsequently child data) to be out of order. It also
46/// allows take / filter operations to be implemented without copying the underlying data.
47///
48/// # Representation
49///
50/// Given the same example array from [`GenericListArray`], it would be represented
51/// as such via a list-view layout array:
52///
53/// ```text
54///                                         ┌ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─
55///                                                                         ┌ ─ ─ ─ ─ ─ ─ ┐    │
56///  ┌─────────────┐  ┌───────┐             │     ┌───┐   ┌───┐   ┌───┐       ┌───┐ ┌───┐
57///  │   [A,B,C]   │  │ (0,3) │                   │ 1 │   │ 0 │   │ 3 │     │ │ 1 │ │ A │ │ 0  │
58///  ├─────────────┤  ├───────┤             │     ├───┤   ├───┤   ├───┤       ├───┤ ├───┤
59///  │      []     │  │ (3,0) │                   │ 1 │   │ 3 │   │ 0 │     │ │ 1 │ │ B │ │ 1  │
60///  ├─────────────┤  ├───────┤             │     ├───┤   ├───┤   ├───┤       ├───┤ ├───┤
61///  │    NULL     │  │ (?,?) │                   │ 0 │   │ ? │   │ ? │     │ │ 1 │ │ C │ │ 2  │
62///  ├─────────────┤  ├───────┤             │     ├───┤   ├───┤   ├───┤       ├───┤ ├───┤
63///  │     [D]     │  │ (4,1) │                   │ 1 │   │ 4 │   │ 1 │     │ │ ? │ │ ? │ │ 3  │
64///  ├─────────────┤  ├───────┤             │     ├───┤   ├───┤   ├───┤       ├───┤ ├───┤
65///  │  [NULL, F]  │  │ (5,2) │                   │ 1 │   │ 5 │   │ 2 │     │ │ 1 │ │ D │ │ 4  │
66///  └─────────────┘  └───────┘             │     └───┘   └───┘   └───┘       ├───┤ ├───┤
67///                                                                         │ │ 0 │ │ ? │ │ 5  │
68///     Logical       Logical               │  Validity  Offsets  Sizes       ├───┤ ├───┤
69///      Values       Offset                   (nulls)                      │ │ 1 │ │ F │ │ 6  │
70///                   & Size                │                                 └───┘ └───┘
71///                                                                         │    Values   │    │
72///                 (offsets[i],            │   ListViewArray                   (Array)
73///                  sizes[i])                                              └ ─ ─ ─ ─ ─ ─ ┘    │
74///                                         └ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─
75/// ```
76///
77/// Another way of representing the same array but taking advantage of the offsets being out of order:
78///
79/// ```text
80///                                         ┌ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─
81///                                                                         ┌ ─ ─ ─ ─ ─ ─ ┐    │
82///  ┌─────────────┐  ┌───────┐             │     ┌───┐   ┌───┐   ┌───┐       ┌───┐ ┌───┐
83///  │   [A,B,C]   │  │ (2,3) │                   │ 1 │   │ 2 │   │ 3 │     │ │ 0 │ │ ? │ │ 0  │
84///  ├─────────────┤  ├───────┤             │     ├───┤   ├───┤   ├───┤       ├───┤ ├───┤
85///  │      []     │  │ (0,0) │                   │ 1 │   │ 0 │   │ 0 │     │ │ 1 │ │ F │ │ 1  │
86///  ├─────────────┤  ├───────┤             │     ├───┤   ├───┤   ├───┤       ├───┤ ├───┤
87///  │    NULL     │  │ (?,?) │                   │ 0 │   │ ? │   │ ? │     │ │ 1 │ │ A │ │ 2  │
88///  ├─────────────┤  ├───────┤             │     ├───┤   ├───┤   ├───┤       ├───┤ ├───┤
89///  │     [D]     │  │ (5,1) │                   │ 1 │   │ 5 │   │ 1 │     │ │ 1 │ │ B │ │ 3  │
90///  ├─────────────┤  ├───────┤             │     ├───┤   ├───┤   ├───┤       ├───┤ ├───┤
91///  │  [NULL, F]  │  │ (0,2) │                   │ 1 │   │ 0 │   │ 2 │     │ │ 1 │ │ C │ │ 4  │
92///  └─────────────┘  └───────┘             │     └───┘   └───┘   └───┘       ├───┤ ├───┤
93///                                                                         │ │ 1 │ │ D │ │ 5  │
94///     Logical       Logical               │  Validity  Offsets  Sizes       └───┘ └───┘
95///      Values       Offset                   (nulls)                      │    Values   │    │
96///                   & Size                │                                   (Array)
97///                                                                         └ ─ ─ ─ ─ ─ ─ ┘    │
98///                 (offsets[i],            │   ListViewArray
99///                  sizes[i])                                                                 │
100///                                         └ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─
101/// ```
102///
103/// [`GenericListArray`]: crate::array::GenericListArray
104/// [variable length lists]: https://arrow.apache.org/docs/format/Columnar.html#variable-size-list-layout
105/// [list layout]: https://arrow.apache.org/docs/format/Columnar.html#list-layout
106/// [list-view layout]: https://arrow.apache.org/docs/format/Columnar.html#listview-layout
107#[derive(Clone)]
108pub struct GenericListViewArray<OffsetSize: OffsetSizeTrait> {
109    data_type: DataType,
110    nulls: Option<NullBuffer>,
111    values: ArrayRef,
112    // Unlike GenericListArray, we do not use OffsetBuffer here as offsets are not
113    // guaranteed to be monotonically increasing.
114    value_offsets: ScalarBuffer<OffsetSize>,
115    value_sizes: ScalarBuffer<OffsetSize>,
116}
117
118impl<OffsetSize: OffsetSizeTrait> GenericListViewArray<OffsetSize> {
119    /// The data type constructor of listview array.
120    /// The input is the schema of the child array and
121    /// the output is the [`DataType`], ListView or LargeListView.
122    pub const DATA_TYPE_CONSTRUCTOR: fn(FieldRef) -> DataType = if OffsetSize::IS_LARGE {
123        DataType::LargeListView
124    } else {
125        DataType::ListView
126    };
127
128    /// Create a new [`GenericListViewArray`] from the provided parts
129    ///
130    /// # Errors
131    ///
132    /// Errors if
133    ///
134    /// * `offsets.len() != sizes.len()`
135    /// * `offsets.len() != nulls.len()`
136    /// * `offsets[i] > values.len()`
137    /// * `!field.is_nullable() && values.is_nullable()`
138    /// * `field.data_type() != values.data_type()`
139    /// * `0 <= offsets[i] <= length of the child array`
140    /// * `0 <= offsets[i] + size[i] <= length of the child array`
141    pub fn try_new(
142        field: FieldRef,
143        offsets: ScalarBuffer<OffsetSize>,
144        sizes: ScalarBuffer<OffsetSize>,
145        values: ArrayRef,
146        nulls: Option<NullBuffer>,
147    ) -> Result<Self, ArrowError> {
148        let len = offsets.len();
149        if let Some(n) = nulls.as_ref() {
150            if n.len() != len {
151                return Err(ArrowError::InvalidArgumentError(format!(
152                    "Incorrect length of null buffer for {}ListViewArray, expected {len} got {}",
153                    OffsetSize::PREFIX,
154                    n.len(),
155                )));
156            }
157        }
158        if len != sizes.len() {
159            return Err(ArrowError::InvalidArgumentError(format!(
160                "Length of offsets buffer and sizes buffer must be equal for {}ListViewArray, got {len} and {}",
161                OffsetSize::PREFIX,
162                sizes.len()
163            )));
164        }
165
166        for (offset, size) in offsets.iter().zip(sizes.iter()) {
167            let offset = offset.as_usize();
168            let size = size.as_usize();
169            if offset.checked_add(size).ok_or_else(|| {
170                ArrowError::InvalidArgumentError(format!(
171                    "Overflow in offset + size for {}ListViewArray",
172                    OffsetSize::PREFIX
173                ))
174            })? > values.len()
175            {
176                return Err(ArrowError::InvalidArgumentError(format!(
177                    "Offset + size for {}ListViewArray must be within the bounds of the child array, got offset: {offset}, size: {size}, child array length: {}",
178                    OffsetSize::PREFIX,
179                    values.len()
180                )));
181            }
182        }
183
184        if !field.is_nullable() && values.is_nullable() {
185            return Err(ArrowError::InvalidArgumentError(format!(
186                "Non-nullable field of {}ListViewArray {:?} cannot contain nulls",
187                OffsetSize::PREFIX,
188                field.name()
189            )));
190        }
191
192        if field.data_type() != values.data_type() {
193            return Err(ArrowError::InvalidArgumentError(format!(
194                "{}ListViewArray expected data type {} got {} for {:?}",
195                OffsetSize::PREFIX,
196                field.data_type(),
197                values.data_type(),
198                field.name()
199            )));
200        }
201
202        Ok(Self {
203            data_type: Self::DATA_TYPE_CONSTRUCTOR(field),
204            nulls,
205            values,
206            value_offsets: offsets,
207            value_sizes: sizes,
208        })
209    }
210
211    /// Create a new [`GenericListViewArray`] from the provided parts
212    ///
213    /// # Panics
214    ///
215    /// Panics if [`Self::try_new`] returns an error
216    pub fn new(
217        field: FieldRef,
218        offsets: ScalarBuffer<OffsetSize>,
219        sizes: ScalarBuffer<OffsetSize>,
220        values: ArrayRef,
221        nulls: Option<NullBuffer>,
222    ) -> Self {
223        Self::try_new(field, offsets, sizes, values, nulls).unwrap()
224    }
225
226    /// Create a new [`GenericListViewArray`] of length `len` where all values are null
227    pub fn new_null(field: FieldRef, len: usize) -> Self {
228        let values = new_empty_array(field.data_type());
229        Self {
230            data_type: Self::DATA_TYPE_CONSTRUCTOR(field),
231            nulls: Some(NullBuffer::new_null(len)),
232            value_offsets: ScalarBuffer::from(vec![OffsetSize::usize_as(0); len]),
233            value_sizes: ScalarBuffer::from(vec![OffsetSize::usize_as(0); len]),
234            values,
235        }
236    }
237
238    /// Deconstruct this array into its constituent parts
239    pub fn into_parts(
240        self,
241    ) -> (
242        FieldRef,
243        ScalarBuffer<OffsetSize>,
244        ScalarBuffer<OffsetSize>,
245        ArrayRef,
246        Option<NullBuffer>,
247    ) {
248        let f = match self.data_type {
249            DataType::ListView(f) | DataType::LargeListView(f) => f,
250            _ => unreachable!(),
251        };
252        (
253            f,
254            self.value_offsets,
255            self.value_sizes,
256            self.values,
257            self.nulls,
258        )
259    }
260
261    /// Returns a reference to the offsets of this list
262    ///
263    /// Unlike [`Self::value_offsets`] this returns the [`ScalarBuffer`]
264    /// allowing for zero-copy cloning
265    #[inline]
266    pub fn offsets(&self) -> &ScalarBuffer<OffsetSize> {
267        &self.value_offsets
268    }
269
270    /// Returns a reference to the values of this list
271    #[inline]
272    pub fn values(&self) -> &ArrayRef {
273        &self.values
274    }
275
276    /// Returns a reference to the sizes of this list
277    ///
278    /// Unlike [`Self::value_sizes`] this returns the [`ScalarBuffer`]
279    /// allowing for zero-copy cloning
280    #[inline]
281    pub fn sizes(&self) -> &ScalarBuffer<OffsetSize> {
282        &self.value_sizes
283    }
284
285    /// Returns a clone of the value type of this list.
286    pub fn value_type(&self) -> DataType {
287        self.values.data_type().clone()
288    }
289
290    /// Returns ith value of this list view array.
291    ///
292    /// Note: This method does not check for nulls and the value is arbitrary
293    /// if [`is_null`](Self::is_null) returns true for the index.
294    ///
295    /// # Safety
296    /// Caller must ensure that the index is within the array bounds
297    pub unsafe fn value_unchecked(&self, i: usize) -> ArrayRef {
298        let offset = unsafe { self.value_offsets().get_unchecked(i).as_usize() };
299        let length = unsafe { self.value_sizes().get_unchecked(i).as_usize() };
300        self.values.slice(offset, length)
301    }
302
303    /// Returns ith value of this list view array.
304    ///
305    /// Note: This method does not check for nulls and the value is arbitrary
306    /// (but still well-defined) if [`is_null`](Self::is_null) returns true for the index.
307    ///
308    /// # Panics
309    /// Panics if the index is out of bounds
310    pub fn value(&self, i: usize) -> ArrayRef {
311        let offset = self.value_offsets()[i].as_usize();
312        let length = self.value_sizes()[i].as_usize();
313        self.values.slice(offset, length)
314    }
315
316    /// Returns the offset values in the offsets buffer
317    #[inline]
318    pub fn value_offsets(&self) -> &[OffsetSize] {
319        &self.value_offsets
320    }
321
322    /// Returns the sizes values in the offsets buffer
323    #[inline]
324    pub fn value_sizes(&self) -> &[OffsetSize] {
325        &self.value_sizes
326    }
327
328    /// Returns the size for value at index `i`.
329    #[inline]
330    pub fn value_size(&self, i: usize) -> OffsetSize {
331        self.value_sizes[i]
332    }
333
334    /// Returns the offset for value at index `i`.
335    pub fn value_offset(&self, i: usize) -> OffsetSize {
336        self.value_offsets[i]
337    }
338
339    /// Constructs a new iterator
340    pub fn iter(&self) -> GenericListViewArrayIter<'_, OffsetSize> {
341        GenericListViewArrayIter::<'_, OffsetSize>::new(self)
342    }
343
344    #[inline]
345    fn get_type(data_type: &DataType) -> Option<&DataType> {
346        match (OffsetSize::IS_LARGE, data_type) {
347            (true, DataType::LargeListView(child)) | (false, DataType::ListView(child)) => {
348                Some(child.data_type())
349            }
350            _ => None,
351        }
352    }
353
354    /// Returns a zero-copy slice of this array with the indicated offset and length.
355    pub fn slice(&self, offset: usize, length: usize) -> Self {
356        Self {
357            data_type: self.data_type.clone(),
358            nulls: self.nulls.as_ref().map(|n| n.slice(offset, length)),
359            values: self.values.clone(),
360            value_offsets: self.value_offsets.slice(offset, length),
361            value_sizes: self.value_sizes.slice(offset, length),
362        }
363    }
364
365    /// Creates a [`GenericListViewArray`] from an iterator of primitive values
366    /// # Example
367    /// ```
368    /// # use arrow_array::ListViewArray;
369    /// # use arrow_array::types::Int32Type;
370    ///
371    /// let data = vec![
372    ///    Some(vec![Some(0), Some(1), Some(2)]),
373    ///    None,
374    ///    Some(vec![Some(3), None, Some(5)]),
375    ///    Some(vec![Some(6), Some(7)]),
376    /// ];
377    /// let list_array = ListViewArray::from_iter_primitive::<Int32Type, _, _>(data);
378    /// println!("{:?}", list_array);
379    /// ```
380    pub fn from_iter_primitive<T, P, I>(iter: I) -> Self
381    where
382        T: ArrowPrimitiveType,
383        P: IntoIterator<Item = Option<<T as ArrowPrimitiveType>::Native>>,
384        I: IntoIterator<Item = Option<P>>,
385    {
386        let iter = iter.into_iter();
387        let size_hint = iter.size_hint().0;
388        let mut builder =
389            GenericListViewBuilder::with_capacity(PrimitiveBuilder::<T>::new(), size_hint);
390
391        for i in iter {
392            match i {
393                Some(p) => {
394                    for t in p {
395                        builder.values().append_option(t);
396                    }
397                    builder.append(true);
398                }
399                None => builder.append(false),
400            }
401        }
402        builder.finish()
403    }
404}
405
406impl<OffsetSize: OffsetSizeTrait> ArrayAccessor for &GenericListViewArray<OffsetSize> {
407    type Item = ArrayRef;
408
409    fn value(&self, index: usize) -> Self::Item {
410        GenericListViewArray::value(self, index)
411    }
412
413    unsafe fn value_unchecked(&self, index: usize) -> Self::Item {
414        unsafe { GenericListViewArray::value_unchecked(self, index) }
415    }
416}
417
418/// SAFETY: Correctly implements the contract of Arrow Arrays
419unsafe impl<OffsetSize: OffsetSizeTrait> Array for GenericListViewArray<OffsetSize> {
420    fn as_any(&self) -> &dyn Any {
421        self
422    }
423
424    fn to_data(&self) -> ArrayData {
425        self.clone().into()
426    }
427
428    fn into_data(self) -> ArrayData {
429        self.into()
430    }
431
432    fn data_type(&self) -> &DataType {
433        &self.data_type
434    }
435
436    fn slice(&self, offset: usize, length: usize) -> ArrayRef {
437        Arc::new(self.slice(offset, length))
438    }
439
440    fn len(&self) -> usize {
441        self.sizes().len()
442    }
443
444    fn is_empty(&self) -> bool {
445        self.value_sizes.is_empty()
446    }
447
448    fn shrink_to_fit(&mut self) {
449        if let Some(nulls) = &mut self.nulls {
450            nulls.shrink_to_fit();
451        }
452        self.values.shrink_to_fit();
453        self.value_offsets.shrink_to_fit();
454        self.value_sizes.shrink_to_fit();
455    }
456
457    fn offset(&self) -> usize {
458        0
459    }
460
461    fn nulls(&self) -> Option<&NullBuffer> {
462        self.nulls.as_ref()
463    }
464
465    fn logical_null_count(&self) -> usize {
466        // More efficient that the default implementation
467        self.null_count()
468    }
469
470    fn get_buffer_memory_size(&self) -> usize {
471        let mut size = self.values.get_buffer_memory_size();
472        size += self.value_offsets.inner().capacity();
473        size += self.value_sizes.inner().capacity();
474        if let Some(n) = self.nulls.as_ref() {
475            size += n.buffer().capacity();
476        }
477        size
478    }
479
480    fn get_array_memory_size(&self) -> usize {
481        let mut size = std::mem::size_of::<Self>() + self.values.get_array_memory_size();
482        size += self.value_offsets.inner().capacity();
483        size += self.value_sizes.inner().capacity();
484        if let Some(n) = self.nulls.as_ref() {
485            size += n.buffer().capacity();
486        }
487        size
488    }
489
490    #[cfg(feature = "pool")]
491    fn claim(&self, pool: &dyn arrow_buffer::MemoryPool) {
492        self.value_offsets.claim(pool);
493        self.value_sizes.claim(pool);
494        self.values.claim(pool);
495        if let Some(nulls) = &self.nulls {
496            nulls.claim(pool);
497        }
498    }
499}
500
501impl<OffsetSize: OffsetSizeTrait> super::ListLikeArray for GenericListViewArray<OffsetSize> {
502    fn values(&self) -> &ArrayRef {
503        self.values()
504    }
505
506    fn element_range(&self, index: usize) -> std::ops::Range<usize> {
507        let offset = self.value_offsets()[index].as_usize();
508        let size = self.value_sizes()[index].as_usize();
509        offset..(offset + size)
510    }
511}
512
513impl<OffsetSize: OffsetSizeTrait> std::fmt::Debug for GenericListViewArray<OffsetSize> {
514    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
515        let prefix = OffsetSize::PREFIX;
516        write!(f, "{prefix}ListViewArray\n[\n")?;
517        print_long_array(self, f, |array, index, f| {
518            std::fmt::Debug::fmt(&array.value(index), f)
519        })?;
520        write!(f, "]")
521    }
522}
523
524impl<OffsetSize: OffsetSizeTrait> From<GenericListArray<OffsetSize>>
525    for GenericListViewArray<OffsetSize>
526{
527    fn from(value: GenericListArray<OffsetSize>) -> Self {
528        let (field, offsets, values, nulls) = value.into_parts();
529        let len = offsets.len() - 1;
530        let mut sizes = Vec::with_capacity(len);
531        let mut view_offsets = Vec::with_capacity(len);
532        for (i, offset) in offsets.iter().enumerate().take(len) {
533            view_offsets.push(*offset);
534            sizes.push(offsets[i + 1] - offsets[i]);
535        }
536
537        Self::new(
538            field,
539            ScalarBuffer::from(view_offsets),
540            ScalarBuffer::from(sizes),
541            values,
542            nulls,
543        )
544    }
545}
546
547impl<OffsetSize: OffsetSizeTrait> From<GenericListViewArray<OffsetSize>> for ArrayData {
548    fn from(array: GenericListViewArray<OffsetSize>) -> Self {
549        let len = array.len();
550        let builder = ArrayDataBuilder::new(array.data_type)
551            .len(len)
552            .nulls(array.nulls)
553            .buffers(vec![
554                array.value_offsets.into_inner(),
555                array.value_sizes.into_inner(),
556            ])
557            .child_data(vec![array.values.to_data()]);
558
559        unsafe { builder.build_unchecked() }
560    }
561}
562
563impl<OffsetSize: OffsetSizeTrait> From<ArrayData> for GenericListViewArray<OffsetSize> {
564    fn from(data: ArrayData) -> Self {
565        Self::try_new_from_array_data(data)
566            .expect("Expected infallible creation of GenericListViewArray from ArrayDataRef failed")
567    }
568}
569
570impl<OffsetSize: OffsetSizeTrait> From<FixedSizeListArray> for GenericListViewArray<OffsetSize> {
571    fn from(value: FixedSizeListArray) -> Self {
572        let (field, size) = match value.data_type() {
573            DataType::FixedSizeList(f, size) => (f, *size as usize),
574            _ => unreachable!(),
575        };
576        let mut acc = 0_usize;
577        let iter = std::iter::repeat_n(size, value.len());
578        let mut sizes = Vec::with_capacity(iter.size_hint().0);
579        let mut offsets = Vec::with_capacity(iter.size_hint().0);
580
581        for size in iter {
582            offsets.push(OffsetSize::usize_as(acc));
583            acc = acc.add(size);
584            sizes.push(OffsetSize::usize_as(size));
585        }
586        let sizes = ScalarBuffer::from(sizes);
587        let offsets = ScalarBuffer::from(offsets);
588        Self {
589            data_type: Self::DATA_TYPE_CONSTRUCTOR(field.clone()),
590            nulls: value.nulls().cloned(),
591            values: value.values().clone(),
592            value_offsets: offsets,
593            value_sizes: sizes,
594        }
595    }
596}
597
598impl<OffsetSize: OffsetSizeTrait> GenericListViewArray<OffsetSize> {
599    fn try_new_from_array_data(data: ArrayData) -> Result<Self, ArrowError> {
600        let (data_type, len, nulls, offset, buffers, child_data) = data.into_parts();
601
602        // ArrayData is valid, and verified type above
603        // buffer[0] is offsets, buffer[1] is sizes
604        let num_buffers = buffers.len();
605        let [offsets_buffer, sizes_buffer] : [Buffer; 2] = buffers.try_into().map_err(|_| {
606             ArrowError::InvalidArgumentError(format!(
607                "ListViewArray data should contain two buffers (value offsets & value sizes), had {num_buffers}",
608            ))
609        })?;
610
611        let num_child = child_data.len();
612        let [values]: [ArrayData; 1] = child_data.try_into().map_err(|_| {
613            ArrowError::InvalidArgumentError(format!(
614                "ListViewArray should contain a single child array (values array), had {num_child}",
615            ))
616        })?;
617
618        if let Some(child_data_type) = Self::get_type(&data_type) {
619            if values.data_type() != child_data_type {
620                return Err(ArrowError::InvalidArgumentError(format!(
621                    "{}ListViewArray's child datatype {:?} does not \
622                             correspond to the List's datatype {:?}",
623                    OffsetSize::PREFIX,
624                    values.data_type(),
625                    child_data_type
626                )));
627            }
628        } else {
629            return Err(ArrowError::InvalidArgumentError(format!(
630                "{}ListViewArray's datatype must be {}ListViewArray(). It is {:?}",
631                OffsetSize::PREFIX,
632                OffsetSize::PREFIX,
633                data_type
634            )));
635        }
636
637        let values = make_array(values);
638        let value_offsets = ScalarBuffer::new(offsets_buffer, offset, len);
639        let value_sizes = ScalarBuffer::new(sizes_buffer, offset, len);
640
641        Ok(Self {
642            data_type,
643            nulls,
644            values,
645            value_offsets,
646            value_sizes,
647        })
648    }
649}
650
651#[cfg(test)]
652mod tests {
653    use arrow_buffer::{BooleanBuffer, Buffer, NullBufferBuilder, ScalarBuffer, bit_util};
654    use arrow_schema::Field;
655
656    use crate::builder::{FixedSizeListBuilder, Int32Builder};
657    use crate::cast::AsArray;
658    use crate::types::Int32Type;
659    use crate::{Int32Array, Int64Array};
660
661    use super::*;
662
663    #[test]
664    fn test_empty_list_view_array() {
665        // Construct an empty value array
666        let vec: Vec<i32> = vec![];
667        let field = Arc::new(Field::new_list_field(DataType::Int32, true));
668        let sizes = ScalarBuffer::from(vec![]);
669        let offsets = ScalarBuffer::from(vec![]);
670        let values = Int32Array::from(vec);
671        let list_array = LargeListViewArray::new(field, offsets, sizes, Arc::new(values), None);
672
673        assert_eq!(list_array.len(), 0)
674    }
675
676    #[test]
677    fn test_list_view_array() {
678        // Construct a value array
679        let value_data = ArrayData::builder(DataType::Int32)
680            .len(8)
681            .add_buffer(Buffer::from_slice_ref([0, 1, 2, 3, 4, 5, 6, 7]))
682            .build()
683            .unwrap();
684
685        let field = Arc::new(Field::new_list_field(DataType::Int32, true));
686        let sizes = ScalarBuffer::from(vec![3i32, 3, 2]);
687        let offsets = ScalarBuffer::from(vec![0i32, 3, 6]);
688        let values = Int32Array::from(vec![0, 1, 2, 3, 4, 5, 6, 7]);
689        let list_array = ListViewArray::new(field, offsets, sizes, Arc::new(values), None);
690
691        let values = list_array.values();
692        assert_eq!(value_data, values.to_data());
693        assert_eq!(DataType::Int32, list_array.value_type());
694        assert_eq!(3, list_array.len());
695        assert_eq!(0, list_array.null_count());
696        assert_eq!(6, list_array.value_offsets()[2]);
697        assert_eq!(2, list_array.value_sizes()[2]);
698        assert_eq!(2, list_array.value_size(2));
699        assert_eq!(0, list_array.value(0).as_primitive::<Int32Type>().value(0));
700        assert_eq!(
701            0,
702            unsafe { list_array.value_unchecked(0) }
703                .as_primitive::<Int32Type>()
704                .value(0)
705        );
706        for i in 0..3 {
707            assert!(list_array.is_valid(i));
708            assert!(!list_array.is_null(i));
709        }
710    }
711
712    #[test]
713    fn test_large_list_view_array() {
714        // Construct a value array
715        let value_data = ArrayData::builder(DataType::Int32)
716            .len(8)
717            .add_buffer(Buffer::from_slice_ref([0, 1, 2, 3, 4, 5, 6, 7]))
718            .build()
719            .unwrap();
720
721        let field = Arc::new(Field::new_list_field(DataType::Int32, true));
722        let sizes = ScalarBuffer::from(vec![3i64, 3, 2]);
723        let offsets = ScalarBuffer::from(vec![0i64, 3, 6]);
724        let values = Int32Array::from(vec![0, 1, 2, 3, 4, 5, 6, 7]);
725        let list_array = LargeListViewArray::new(field, offsets, sizes, Arc::new(values), None);
726
727        let values = list_array.values();
728        assert_eq!(value_data, values.to_data());
729        assert_eq!(DataType::Int32, list_array.value_type());
730        assert_eq!(3, list_array.len());
731        assert_eq!(0, list_array.null_count());
732        assert_eq!(6, list_array.value_offsets()[2]);
733        assert_eq!(2, list_array.value_sizes()[2]);
734        assert_eq!(2, list_array.value_size(2));
735        assert_eq!(0, list_array.value(0).as_primitive::<Int32Type>().value(0));
736        assert_eq!(
737            0,
738            unsafe { list_array.value_unchecked(0) }
739                .as_primitive::<Int32Type>()
740                .value(0)
741        );
742        for i in 0..3 {
743            assert!(list_array.is_valid(i));
744            assert!(!list_array.is_null(i));
745        }
746    }
747
748    #[test]
749    fn test_list_view_array_slice() {
750        // Construct a value array
751        let value_data = ArrayData::builder(DataType::Int32)
752            .len(10)
753            .add_buffer(Buffer::from_slice_ref([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]))
754            .build()
755            .unwrap();
756
757        // 01011001 00000001
758        let mut null_bits: [u8; 2] = [0; 2];
759        bit_util::set_bit(&mut null_bits, 0);
760        bit_util::set_bit(&mut null_bits, 3);
761        bit_util::set_bit(&mut null_bits, 4);
762        bit_util::set_bit(&mut null_bits, 6);
763        bit_util::set_bit(&mut null_bits, 8);
764        let buffer = BooleanBuffer::new(Buffer::from(null_bits), 0, 9);
765        let null_buffer = NullBuffer::new(buffer);
766
767        let field = Arc::new(Field::new_list_field(DataType::Int32, true));
768        let sizes = ScalarBuffer::from(vec![2, 0, 0, 2, 2, 0, 3, 0, 1]);
769        let offsets = ScalarBuffer::from(vec![0, 2, 2, 2, 4, 6, 6, 9, 9]);
770        let values = Int32Array::from(vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
771        let list_array =
772            ListViewArray::new(field, offsets, sizes, Arc::new(values), Some(null_buffer));
773
774        let values = list_array.values();
775        assert_eq!(value_data, values.to_data());
776        assert_eq!(DataType::Int32, list_array.value_type());
777        assert_eq!(9, list_array.len());
778        assert_eq!(4, list_array.null_count());
779        assert_eq!(2, list_array.value_offsets()[3]);
780        assert_eq!(2, list_array.value_sizes()[3]);
781        assert_eq!(2, list_array.value_size(3));
782
783        let sliced_array = list_array.slice(1, 6);
784        assert_eq!(6, sliced_array.len());
785        assert_eq!(3, sliced_array.null_count());
786
787        for i in 0..sliced_array.len() {
788            if bit_util::get_bit(&null_bits, 1 + i) {
789                assert!(sliced_array.is_valid(i));
790            } else {
791                assert!(sliced_array.is_null(i));
792            }
793        }
794
795        // Check offset and length for each non-null value.
796        let sliced_list_array = sliced_array
797            .as_any()
798            .downcast_ref::<ListViewArray>()
799            .unwrap();
800        assert_eq!(2, sliced_list_array.value_offsets()[2]);
801        assert_eq!(2, sliced_list_array.value_sizes()[2]);
802        assert_eq!(2, sliced_list_array.value_size(2));
803
804        assert_eq!(4, sliced_list_array.value_offsets()[3]);
805        assert_eq!(2, sliced_list_array.value_sizes()[3]);
806        assert_eq!(2, sliced_list_array.value_size(3));
807
808        assert_eq!(6, sliced_list_array.value_offsets()[5]);
809        assert_eq!(3, sliced_list_array.value_sizes()[5]);
810        assert_eq!(3, sliced_list_array.value_size(5));
811    }
812
813    #[test]
814    fn test_large_list_view_array_slice() {
815        // Construct a value array
816        let value_data = ArrayData::builder(DataType::Int32)
817            .len(10)
818            .add_buffer(Buffer::from_slice_ref([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]))
819            .build()
820            .unwrap();
821
822        // 01011001 00000001
823        let mut null_bits: [u8; 2] = [0; 2];
824        bit_util::set_bit(&mut null_bits, 0);
825        bit_util::set_bit(&mut null_bits, 3);
826        bit_util::set_bit(&mut null_bits, 4);
827        bit_util::set_bit(&mut null_bits, 6);
828        bit_util::set_bit(&mut null_bits, 8);
829        let buffer = BooleanBuffer::new(Buffer::from(null_bits), 0, 9);
830        let null_buffer = NullBuffer::new(buffer);
831
832        // Construct a large list view array from the above two
833        let field = Arc::new(Field::new_list_field(DataType::Int32, true));
834        let sizes = ScalarBuffer::from(vec![2i64, 0, 0, 2, 2, 0, 3, 0, 1]);
835        let offsets = ScalarBuffer::from(vec![0i64, 2, 2, 2, 4, 6, 6, 9, 9]);
836        let values = Int32Array::from(vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
837        let list_array =
838            LargeListViewArray::new(field, offsets, sizes, Arc::new(values), Some(null_buffer));
839
840        let values = list_array.values();
841        assert_eq!(value_data, values.to_data());
842        assert_eq!(DataType::Int32, list_array.value_type());
843        assert_eq!(9, list_array.len());
844        assert_eq!(4, list_array.null_count());
845        assert_eq!(2, list_array.value_offsets()[3]);
846        assert_eq!(2, list_array.value_sizes()[3]);
847        assert_eq!(2, list_array.value_size(3));
848
849        let sliced_array = list_array.slice(1, 6);
850        assert_eq!(6, sliced_array.len());
851        assert_eq!(3, sliced_array.null_count());
852
853        for i in 0..sliced_array.len() {
854            if bit_util::get_bit(&null_bits, 1 + i) {
855                assert!(sliced_array.is_valid(i));
856            } else {
857                assert!(sliced_array.is_null(i));
858            }
859        }
860
861        // Check offset and length for each non-null value.
862        let sliced_list_array = sliced_array
863            .as_any()
864            .downcast_ref::<LargeListViewArray>()
865            .unwrap();
866        assert_eq!(2, sliced_list_array.value_offsets()[2]);
867        assert_eq!(2, sliced_list_array.value_size(2));
868        assert_eq!(2, sliced_list_array.value_sizes()[2]);
869
870        assert_eq!(4, sliced_list_array.value_offsets()[3]);
871        assert_eq!(2, sliced_list_array.value_size(3));
872        assert_eq!(2, sliced_list_array.value_sizes()[3]);
873
874        assert_eq!(6, sliced_list_array.value_offsets()[5]);
875        assert_eq!(3, sliced_list_array.value_size(5));
876        assert_eq!(2, sliced_list_array.value_sizes()[3]);
877    }
878
879    #[test]
880    #[should_panic(expected = "index out of bounds: the len is 9 but the index is 10")]
881    fn test_list_view_array_index_out_of_bound() {
882        // 01011001 00000001
883        let mut null_bits: [u8; 2] = [0; 2];
884        bit_util::set_bit(&mut null_bits, 0);
885        bit_util::set_bit(&mut null_bits, 3);
886        bit_util::set_bit(&mut null_bits, 4);
887        bit_util::set_bit(&mut null_bits, 6);
888        bit_util::set_bit(&mut null_bits, 8);
889        let buffer = BooleanBuffer::new(Buffer::from(null_bits), 0, 9);
890        let null_buffer = NullBuffer::new(buffer);
891
892        // Construct a buffer for value offsets, for the nested array:
893        //  [[0, 1], null, null, [2, 3], [4, 5], null, [6, 7, 8], null, [9]]
894        // Construct a list array from the above two
895        let field = Arc::new(Field::new_list_field(DataType::Int32, true));
896        let sizes = ScalarBuffer::from(vec![2i32, 0, 0, 2, 2, 0, 3, 0, 1]);
897        let offsets = ScalarBuffer::from(vec![0i32, 2, 2, 2, 4, 6, 6, 9, 9]);
898        let values = Int32Array::from(vec![0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);
899        let list_array =
900            ListViewArray::new(field, offsets, sizes, Arc::new(values), Some(null_buffer));
901
902        assert_eq!(9, list_array.len());
903        list_array.value(10);
904    }
905    #[test]
906    #[should_panic(
907        expected = "ListViewArray data should contain two buffers (value offsets & value sizes), had 0"
908    )]
909    #[cfg(not(feature = "force_validate"))]
910    fn test_list_view_array_invalid_buffer_len() {
911        let value_data = unsafe {
912            ArrayData::builder(DataType::Int32)
913                .len(8)
914                .add_buffer(Buffer::from_slice_ref([0, 1, 2, 3, 4, 5, 6, 7]))
915                .build_unchecked()
916        };
917        let list_data_type =
918            DataType::ListView(Arc::new(Field::new_list_field(DataType::Int32, false)));
919        let list_data = unsafe {
920            ArrayData::builder(list_data_type)
921                .len(3)
922                .add_child_data(value_data)
923                .build_unchecked()
924        };
925        drop(ListViewArray::from(list_data));
926    }
927
928    #[test]
929    #[should_panic(
930        expected = "ListViewArray data should contain two buffers (value offsets & value sizes), had 1"
931    )]
932    #[cfg(not(feature = "force_validate"))]
933    fn test_list_view_array_invalid_child_array_len() {
934        let value_offsets = Buffer::from_slice_ref([0, 2, 5, 7]);
935        let list_data_type =
936            DataType::ListView(Arc::new(Field::new_list_field(DataType::Int32, false)));
937        let list_data = unsafe {
938            ArrayData::builder(list_data_type)
939                .len(3)
940                .add_buffer(value_offsets)
941                .build_unchecked()
942        };
943        drop(ListViewArray::from(list_data));
944    }
945
946    #[test]
947    fn test_list_view_array_offsets_need_not_start_at_zero() {
948        let field = Arc::new(Field::new_list_field(DataType::Int32, true));
949        let sizes = ScalarBuffer::from(vec![0i32, 0, 3]);
950        let offsets = ScalarBuffer::from(vec![2i32, 2, 5]);
951        let values = Int32Array::from(vec![0, 1, 2, 3, 4, 5, 6, 7]);
952        let list_array = ListViewArray::new(field, offsets, sizes, Arc::new(values), None);
953
954        assert_eq!(list_array.value_size(0), 0);
955        assert_eq!(list_array.value_size(1), 0);
956        assert_eq!(list_array.value_size(2), 3);
957    }
958
959    #[test]
960    #[should_panic(expected = "Memory pointer is not aligned with the specified scalar type")]
961    #[cfg(not(feature = "force_validate"))]
962    fn test_list_view_array_alignment() {
963        let offset_buf = Buffer::from_slice_ref([0_u64]);
964        let offset_buf2 = offset_buf.slice(1);
965
966        let size_buf = Buffer::from_slice_ref([0_u64]);
967        let size_buf2 = size_buf.slice(1);
968
969        let values: [i32; 8] = [0; 8];
970        let value_data = unsafe {
971            ArrayData::builder(DataType::Int32)
972                .add_buffer(Buffer::from_slice_ref(values))
973                .build_unchecked()
974        };
975
976        let list_data_type =
977            DataType::ListView(Arc::new(Field::new_list_field(DataType::Int32, false)));
978        let list_data = unsafe {
979            ArrayData::builder(list_data_type)
980                .add_buffer(offset_buf2)
981                .add_buffer(size_buf2)
982                .add_child_data(value_data)
983                .build_unchecked()
984        };
985        drop(ListViewArray::from(list_data));
986    }
987
988    #[test]
989    fn test_empty_offsets() {
990        let f = Arc::new(Field::new("element", DataType::Int32, true));
991        let string = ListViewArray::from(
992            ArrayData::builder(DataType::ListView(f.clone()))
993                .buffers(vec![Buffer::from(&[]), Buffer::from(&[])])
994                .add_child_data(ArrayData::new_empty(&DataType::Int32))
995                .build()
996                .unwrap(),
997        );
998        assert_eq!(string.value_offsets(), &[] as &[i32; 0]);
999        assert_eq!(string.value_sizes(), &[] as &[i32; 0]);
1000
1001        let string = LargeListViewArray::from(
1002            ArrayData::builder(DataType::LargeListView(f))
1003                .buffers(vec![Buffer::from(&[]), Buffer::from(&[])])
1004                .add_child_data(ArrayData::new_empty(&DataType::Int32))
1005                .build()
1006                .unwrap(),
1007        );
1008        assert_eq!(string.len(), 0);
1009        assert_eq!(string.value_offsets(), &[] as &[i64; 0]);
1010        assert_eq!(string.value_sizes(), &[] as &[i64; 0]);
1011    }
1012
1013    #[test]
1014    fn test_try_new() {
1015        let offsets = ScalarBuffer::from(vec![0, 1, 4, 5]);
1016        let sizes = ScalarBuffer::from(vec![1, 3, 1, 0]);
1017        let values = Int32Array::new(vec![1, 2, 3, 4, 5].into(), None);
1018        let values = Arc::new(values) as ArrayRef;
1019
1020        let field = Arc::new(Field::new("element", DataType::Int32, false));
1021        ListViewArray::new(
1022            field.clone(),
1023            offsets.clone(),
1024            sizes.clone(),
1025            values.clone(),
1026            None,
1027        );
1028
1029        let nulls = NullBuffer::new_null(4);
1030        ListViewArray::new(
1031            field.clone(),
1032            offsets,
1033            sizes.clone(),
1034            values.clone(),
1035            Some(nulls),
1036        );
1037
1038        let nulls = NullBuffer::new_null(4);
1039        let offsets = ScalarBuffer::from(vec![0, 1, 2, 3, 4]);
1040        let sizes = ScalarBuffer::from(vec![1, 1, 1, 1, 0]);
1041        let err = LargeListViewArray::try_new(
1042            field,
1043            offsets.clone(),
1044            sizes.clone(),
1045            values.clone(),
1046            Some(nulls),
1047        )
1048        .unwrap_err();
1049
1050        assert_eq!(
1051            err.to_string(),
1052            "Invalid argument error: Incorrect length of null buffer for LargeListViewArray, expected 5 got 4"
1053        );
1054
1055        let field = Arc::new(Field::new("element", DataType::Int64, false));
1056        let err = LargeListViewArray::try_new(
1057            field.clone(),
1058            offsets.clone(),
1059            sizes.clone(),
1060            values.clone(),
1061            None,
1062        )
1063        .unwrap_err();
1064
1065        assert_eq!(
1066            err.to_string(),
1067            "Invalid argument error: LargeListViewArray expected data type Int64 got Int32 for \"element\""
1068        );
1069
1070        let nulls = NullBuffer::new_null(7);
1071        let values = Int64Array::new(vec![0; 7].into(), Some(nulls));
1072        let values = Arc::new(values);
1073
1074        let err = LargeListViewArray::try_new(
1075            field,
1076            offsets.clone(),
1077            sizes.clone(),
1078            values.clone(),
1079            None,
1080        )
1081        .unwrap_err();
1082
1083        assert_eq!(
1084            err.to_string(),
1085            "Invalid argument error: Non-nullable field of LargeListViewArray \"element\" cannot contain nulls"
1086        );
1087    }
1088
1089    #[test]
1090    fn test_from_fixed_size_list() {
1091        let mut builder = FixedSizeListBuilder::new(Int32Builder::new(), 3);
1092        builder.values().append_slice(&[1, 2, 3]);
1093        builder.append(true);
1094        builder.values().append_slice(&[0, 0, 0]);
1095        builder.append(false);
1096        builder.values().append_slice(&[4, 5, 6]);
1097        builder.append(true);
1098        let list: ListViewArray = builder.finish().into();
1099        let values: Vec<_> = list
1100            .iter()
1101            .map(|x| x.map(|x| x.as_primitive::<Int32Type>().values().to_vec()))
1102            .collect();
1103        assert_eq!(values, vec![Some(vec![1, 2, 3]), None, Some(vec![4, 5, 6])]);
1104        let offsets = list.value_offsets();
1105        assert_eq!(offsets, &[0, 3, 6]);
1106        let sizes = list.value_sizes();
1107        assert_eq!(sizes, &[3, 3, 3]);
1108    }
1109
1110    #[test]
1111    fn test_list_view_array_overlap_lists() {
1112        let value_data = unsafe {
1113            ArrayData::builder(DataType::Int32)
1114                .len(8)
1115                .add_buffer(Buffer::from_slice_ref([0, 1, 2, 3, 4, 5, 6, 7]))
1116                .build_unchecked()
1117        };
1118        let list_data_type =
1119            DataType::ListView(Arc::new(Field::new_list_field(DataType::Int32, false)));
1120        let list_data = unsafe {
1121            ArrayData::builder(list_data_type)
1122                .len(2)
1123                .add_buffer(Buffer::from_slice_ref([0, 3])) // offsets
1124                .add_buffer(Buffer::from_slice_ref([5, 5])) // sizes
1125                .add_child_data(value_data)
1126                .build_unchecked()
1127        };
1128        let array = ListViewArray::from(list_data);
1129
1130        assert_eq!(array.len(), 2);
1131        assert_eq!(array.value_size(0), 5);
1132        assert_eq!(array.value_size(1), 5);
1133
1134        let values: Vec<_> = array
1135            .iter()
1136            .map(|x| x.map(|x| x.as_primitive::<Int32Type>().values().to_vec()))
1137            .collect();
1138        assert_eq!(
1139            values,
1140            vec![Some(vec![0, 1, 2, 3, 4]), Some(vec![3, 4, 5, 6, 7])]
1141        );
1142    }
1143
1144    #[test]
1145    fn test_list_view_array_incomplete_offsets() {
1146        let value_data = unsafe {
1147            ArrayData::builder(DataType::Int32)
1148                .len(50)
1149                .add_buffer(Buffer::from_slice_ref((0..50).collect::<Vec<i32>>()))
1150                .build_unchecked()
1151        };
1152        let list_data_type =
1153            DataType::ListView(Arc::new(Field::new_list_field(DataType::Int32, false)));
1154        let list_data = unsafe {
1155            ArrayData::builder(list_data_type)
1156                .len(3)
1157                .add_buffer(Buffer::from_slice_ref([0, 5, 10])) // offsets
1158                .add_buffer(Buffer::from_slice_ref([0, 5, 10])) // sizes
1159                .add_child_data(value_data)
1160                .build_unchecked()
1161        };
1162        let array = ListViewArray::from(list_data);
1163
1164        assert_eq!(array.len(), 3);
1165        assert_eq!(array.value_size(0), 0);
1166        assert_eq!(array.value_size(1), 5);
1167        assert_eq!(array.value_size(2), 10);
1168
1169        let values: Vec<_> = array
1170            .iter()
1171            .map(|x| x.map(|x| x.as_primitive::<Int32Type>().values().to_vec()))
1172            .collect();
1173        assert_eq!(
1174            values,
1175            vec![
1176                Some(vec![]),
1177                Some(vec![5, 6, 7, 8, 9]),
1178                Some(vec![10, 11, 12, 13, 14, 15, 16, 17, 18, 19])
1179            ]
1180        );
1181    }
1182
1183    #[test]
1184    fn test_list_view_array_empty_lists() {
1185        let value_data = unsafe {
1186            ArrayData::builder(DataType::Int32)
1187                .len(0)
1188                .add_buffer(Buffer::from_slice_ref::<i32, &[_; 0]>(&[]))
1189                .build_unchecked()
1190        };
1191        let list_data_type =
1192            DataType::ListView(Arc::new(Field::new_list_field(DataType::Int32, false)));
1193        let list_data = unsafe {
1194            ArrayData::builder(list_data_type)
1195                .len(3)
1196                .add_buffer(Buffer::from_slice_ref([0, 0, 0])) // offsets
1197                .add_buffer(Buffer::from_slice_ref([0, 0, 0])) // sizes
1198                .add_child_data(value_data)
1199                .build_unchecked()
1200        };
1201        let array = ListViewArray::from(list_data);
1202
1203        assert_eq!(array.len(), 3);
1204        assert_eq!(array.value_size(0), 0);
1205        assert_eq!(array.value_size(1), 0);
1206        assert_eq!(array.value_size(2), 0);
1207
1208        let values: Vec<_> = array
1209            .iter()
1210            .map(|x| x.map(|x| x.as_primitive::<Int32Type>().values().to_vec()))
1211            .collect();
1212        assert_eq!(values, vec![Some(vec![]), Some(vec![]), Some(vec![])]);
1213    }
1214
1215    #[test]
1216    fn test_list_view_new_null_len() {
1217        let field = Arc::new(Field::new_list_field(DataType::Int32, true));
1218        let array = ListViewArray::new_null(field, 5);
1219        assert_eq!(array.len(), 5);
1220    }
1221
1222    #[test]
1223    fn test_from_iter_primitive() {
1224        let data = vec![
1225            Some(vec![Some(0), Some(1), Some(2)]),
1226            None,
1227            Some(vec![Some(3), Some(4), Some(5)]),
1228            Some(vec![Some(6), Some(7)]),
1229        ];
1230        let list_array = ListViewArray::from_iter_primitive::<Int32Type, _, _>(data);
1231
1232        //  [[0, 1, 2], NULL, [3, 4, 5], [6, 7]]
1233        let values = Int32Array::from(vec![0, 1, 2, 3, 4, 5, 6, 7]);
1234        let offsets = ScalarBuffer::from(vec![0, 3, 3, 6]);
1235        let sizes = ScalarBuffer::from(vec![3, 0, 3, 2]);
1236        let field = Arc::new(Field::new_list_field(DataType::Int32, true));
1237
1238        let mut nulls = NullBufferBuilder::new(4);
1239        nulls.append(true);
1240        nulls.append(false);
1241        nulls.append_n_non_nulls(2);
1242        let another = ListViewArray::new(field, offsets, sizes, Arc::new(values), nulls.finish());
1243
1244        assert_eq!(list_array, another)
1245    }
1246}