polars_arrow/array/primitive/
mod.rs

1use std::ops::Range;
2
3use either::Either;
4
5use super::{Array, Splitable};
6use crate::array::iterator::NonNullValuesIter;
7use crate::bitmap::Bitmap;
8use crate::bitmap::utils::{BitmapIter, ZipValidity};
9use crate::buffer::Buffer;
10use crate::datatypes::*;
11use crate::trusted_len::TrustedLen;
12use crate::types::{NativeType, days_ms, f16, i256, months_days_ns};
13
14mod ffi;
15pub(super) mod fmt;
16mod from_natural;
17pub mod iterator;
18#[cfg(feature = "proptest")]
19pub mod proptest;
20
21mod mutable;
22pub use mutable::*;
23mod builder;
24pub use builder::*;
25use polars_error::{PolarsResult, polars_bail};
26use polars_utils::index::{Bounded, Indexable, NullCount};
27use polars_utils::slice::SliceAble;
28
29/// A [`PrimitiveArray`] is Arrow's semantically equivalent of an immutable `Vec<Option<T>>` where
30/// T is [`NativeType`] (e.g. [`i32`]). It implements [`Array`].
31///
32/// One way to think about a [`PrimitiveArray`] is `(DataType, Arc<Vec<T>>, Option<Arc<Vec<u8>>>)`
33/// where:
34/// * the first item is the array's logical type
35/// * the second is the immutable values
36/// * the third is the immutable validity (whether a value is null or not as a bitmap).
37///
38/// The size of this struct is `O(1)`, as all data is stored behind an [`std::sync::Arc`].
39/// # Example
40/// ```
41/// use polars_arrow::array::PrimitiveArray;
42/// use polars_arrow::bitmap::Bitmap;
43/// use polars_arrow::buffer::Buffer;
44///
45/// let array = PrimitiveArray::from([Some(1i32), None, Some(10)]);
46/// assert_eq!(array.value(0), 1);
47/// assert_eq!(array.iter().collect::<Vec<_>>(), vec![Some(&1i32), None, Some(&10)]);
48/// assert_eq!(array.values_iter().copied().collect::<Vec<_>>(), vec![1, 0, 10]);
49/// // the underlying representation
50/// assert_eq!(array.values(), &Buffer::from(vec![1i32, 0, 10]));
51/// assert_eq!(array.validity(), Some(&Bitmap::from([true, false, true])));
52///
53/// ```
54#[derive(Clone)]
55pub struct PrimitiveArray<T: NativeType> {
56    dtype: ArrowDataType,
57    values: Buffer<T>,
58    validity: Option<Bitmap>,
59}
60
61pub(super) fn check<T: NativeType>(
62    dtype: &ArrowDataType,
63    values: &[T],
64    validity_len: Option<usize>,
65) -> PolarsResult<()> {
66    if validity_len.is_some_and(|len| len != values.len()) {
67        polars_bail!(ComputeError: "validity mask length must match the number of values")
68    }
69
70    if dtype.to_physical_type() != PhysicalType::Primitive(T::PRIMITIVE) {
71        polars_bail!(ComputeError: "PrimitiveArray can only be initialized with a DataType whose physical type is Primitive")
72    }
73    Ok(())
74}
75
76impl<T: NativeType> PrimitiveArray<T> {
77    /// The canonical method to create a [`PrimitiveArray`] out of its internal components.
78    /// # Implementation
79    /// This function is `O(1)`.
80    ///
81    /// # Errors
82    /// This function errors iff:
83    /// * The validity is not `None` and its length is different from `values`'s length
84    /// * The `dtype`'s [`PhysicalType`] is not equal to [`PhysicalType::Primitive(T::PRIMITIVE)`]
85    pub fn try_new(
86        dtype: ArrowDataType,
87        values: Buffer<T>,
88        validity: Option<Bitmap>,
89    ) -> PolarsResult<Self> {
90        check(&dtype, &values, validity.as_ref().map(|v| v.len()))?;
91        Ok(Self {
92            dtype,
93            values,
94            validity,
95        })
96    }
97
98    /// # Safety
99    /// Doesn't check invariants
100    pub unsafe fn new_unchecked(
101        dtype: ArrowDataType,
102        values: Buffer<T>,
103        validity: Option<Bitmap>,
104    ) -> Self {
105        if cfg!(debug_assertions) {
106            check(&dtype, &values, validity.as_ref().map(|v| v.len())).unwrap();
107        }
108
109        Self {
110            dtype,
111            values,
112            validity,
113        }
114    }
115
116    /// Returns a new [`PrimitiveArray`] with a different logical type.
117    ///
118    /// This function is useful to assign a different [`ArrowDataType`] to the array.
119    /// Used to change the arrays' logical type (see example).
120    /// # Example
121    /// ```
122    /// use polars_arrow::array::Int32Array;
123    /// use polars_arrow::datatypes::ArrowDataType;
124    ///
125    /// let array = Int32Array::from(&[Some(1), None, Some(2)]).to(ArrowDataType::Date32);
126    /// assert_eq!(
127    ///    format!("{:?}", array),
128    ///    "Date32[1970-01-02, None, 1970-01-03]"
129    /// );
130    /// ```
131    /// # Panics
132    /// Panics iff the `dtype`'s [`PhysicalType`] is not equal to [`PhysicalType::Primitive(T::PRIMITIVE)`]
133    #[inline]
134    #[must_use]
135    pub fn to(self, dtype: ArrowDataType) -> Self {
136        check(
137            &dtype,
138            &self.values,
139            self.validity.as_ref().map(|v| v.len()),
140        )
141        .unwrap();
142        Self {
143            dtype,
144            values: self.values,
145            validity: self.validity,
146        }
147    }
148
149    /// Creates a (non-null) [`PrimitiveArray`] from a vector of values.
150    /// This function is `O(1)`.
151    /// # Examples
152    /// ```
153    /// use polars_arrow::array::PrimitiveArray;
154    ///
155    /// let array = PrimitiveArray::from_vec(vec![1, 2, 3]);
156    /// assert_eq!(format!("{:?}", array), "Int32[1, 2, 3]");
157    /// ```
158    pub fn from_vec(values: Vec<T>) -> Self {
159        Self::new(T::PRIMITIVE.into(), values.into(), None)
160    }
161
162    /// Returns an iterator over the values and validity, `Option<&T>`.
163    #[inline]
164    pub fn iter(&self) -> ZipValidity<&T, std::slice::Iter<'_, T>, BitmapIter<'_>> {
165        ZipValidity::new_with_validity(self.values().iter(), self.validity())
166    }
167
168    /// Returns an iterator of the values, `&T`, ignoring the arrays' validity.
169    #[inline]
170    pub fn values_iter(&self) -> std::slice::Iter<'_, T> {
171        self.values().iter()
172    }
173
174    /// Returns an iterator of the non-null values `T`.
175    #[inline]
176    pub fn non_null_values_iter(&self) -> NonNullValuesIter<'_, [T]> {
177        NonNullValuesIter::new(self.values(), self.validity())
178    }
179
180    /// Returns the length of this array
181    #[inline]
182    pub fn len(&self) -> usize {
183        self.values.len()
184    }
185
186    /// The values [`Buffer`].
187    /// Values on null slots are undetermined (they can be anything).
188    #[inline]
189    pub fn values(&self) -> &Buffer<T> {
190        &self.values
191    }
192
193    /// Returns the optional validity.
194    #[inline]
195    pub fn validity(&self) -> Option<&Bitmap> {
196        self.validity.as_ref()
197    }
198
199    /// Returns the arrays' [`ArrowDataType`].
200    #[inline]
201    pub fn dtype(&self) -> &ArrowDataType {
202        &self.dtype
203    }
204
205    /// Returns the value at slot `i`.
206    ///
207    /// Equivalent to `self.values()[i]`. The value of a null slot is undetermined (it can be anything).
208    /// # Panic
209    /// This function panics iff `i >= self.len`.
210    #[inline]
211    pub fn value(&self, i: usize) -> T {
212        self.values[i]
213    }
214
215    /// Returns the value at index `i`.
216    /// The value on null slots is undetermined (it can be anything).
217    ///
218    /// # Safety
219    /// Caller must be sure that `i < self.len()`
220    #[inline]
221    pub unsafe fn value_unchecked(&self, i: usize) -> T {
222        *self.values.get_unchecked(i)
223    }
224
225    // /// Returns the element at index `i` or `None` if it is null
226    // /// # Panics
227    // /// iff `i >= self.len()`
228    // #[inline]
229    // pub fn get(&self, i: usize) -> Option<T> {
230    //     if !self.is_null(i) {
231    //         // soundness: Array::is_null panics if i >= self.len
232    //         unsafe { Some(self.value_unchecked(i)) }
233    //     } else {
234    //         None
235    //     }
236    // }
237
238    /// Slices this [`PrimitiveArray`] by an offset and length.
239    /// # Implementation
240    /// This operation is `O(1)`.
241    #[inline]
242    pub fn slice(&mut self, offset: usize, length: usize) {
243        assert!(
244            offset + length <= self.len(),
245            "offset + length may not exceed length of array"
246        );
247        unsafe { self.slice_unchecked(offset, length) }
248    }
249
250    /// Slices this [`PrimitiveArray`] by an offset and length.
251    /// # Implementation
252    /// This operation is `O(1)`.
253    ///
254    /// # Safety
255    /// The caller must ensure that `offset + length <= self.len()`.
256    #[inline]
257    pub unsafe fn slice_unchecked(&mut self, offset: usize, length: usize) {
258        self.validity = self
259            .validity
260            .take()
261            .map(|bitmap| bitmap.sliced_unchecked(offset, length))
262            .filter(|bitmap| bitmap.unset_bits() > 0);
263        self.values.slice_unchecked(offset, length);
264    }
265
266    impl_sliced!();
267    impl_mut_validity!();
268    impl_into_array!();
269
270    /// Returns this [`PrimitiveArray`] with new values.
271    /// # Panics
272    /// This function panics iff `values.len() != self.len()`.
273    #[must_use]
274    pub fn with_values(mut self, values: Buffer<T>) -> Self {
275        self.set_values(values);
276        self
277    }
278
279    /// Update the values of this [`PrimitiveArray`].
280    /// # Panics
281    /// This function panics iff `values.len() != self.len()`.
282    pub fn set_values(&mut self, values: Buffer<T>) {
283        assert_eq!(
284            values.len(),
285            self.len(),
286            "values' length must be equal to this arrays' length"
287        );
288        self.values = values;
289    }
290
291    /// Applies a function `f` to the validity of this array.
292    ///
293    /// This is an API to leverage clone-on-write
294    /// # Panics
295    /// This function panics if the function `f` modifies the length of the [`Bitmap`].
296    pub fn apply_validity<F: FnOnce(Bitmap) -> Bitmap>(&mut self, f: F) {
297        if let Some(validity) = std::mem::take(&mut self.validity) {
298            self.set_validity(Some(f(validity)))
299        }
300    }
301
302    /// Returns an option of a mutable reference to the values of this [`PrimitiveArray`].
303    pub fn get_mut_values(&mut self) -> Option<&mut [T]> {
304        self.values.get_mut_slice()
305    }
306
307    /// Returns its internal representation
308    #[must_use]
309    pub fn into_inner(self) -> (ArrowDataType, Buffer<T>, Option<Bitmap>) {
310        let Self {
311            dtype,
312            values,
313            validity,
314        } = self;
315        (dtype, values, validity)
316    }
317
318    /// Creates a [`PrimitiveArray`] from its internal representation.
319    /// This is the inverted from [`PrimitiveArray::into_inner`]
320    pub fn from_inner(
321        dtype: ArrowDataType,
322        values: Buffer<T>,
323        validity: Option<Bitmap>,
324    ) -> PolarsResult<Self> {
325        check(&dtype, &values, validity.as_ref().map(|v| v.len()))?;
326        Ok(unsafe { Self::from_inner_unchecked(dtype, values, validity) })
327    }
328
329    /// Creates a [`PrimitiveArray`] from its internal representation.
330    /// This is the inverted from [`PrimitiveArray::into_inner`]
331    ///
332    /// # Safety
333    /// Callers must ensure all invariants of this struct are upheld.
334    pub unsafe fn from_inner_unchecked(
335        dtype: ArrowDataType,
336        values: Buffer<T>,
337        validity: Option<Bitmap>,
338    ) -> Self {
339        Self {
340            dtype,
341            values,
342            validity,
343        }
344    }
345
346    /// Try to convert this [`PrimitiveArray`] to a [`MutablePrimitiveArray`] via copy-on-write semantics.
347    ///
348    /// A [`PrimitiveArray`] is backed by a [`Buffer`] and [`Bitmap`] which are essentially `Arc<Vec<_>>`.
349    /// This function returns a [`MutablePrimitiveArray`] (via [`std::sync::Arc::get_mut`]) iff both values
350    /// and validity have not been cloned / are unique references to their underlying vectors.
351    ///
352    /// This function is primarily used to reuse memory regions.
353    #[must_use]
354    pub fn into_mut(self) -> Either<Self, MutablePrimitiveArray<T>> {
355        use Either::*;
356
357        if let Some(bitmap) = self.validity {
358            match bitmap.into_mut() {
359                Left(bitmap) => Left(PrimitiveArray::new(self.dtype, self.values, Some(bitmap))),
360                Right(mutable_bitmap) => match self.values.into_mut() {
361                    Right(values) => Right(
362                        MutablePrimitiveArray::try_new(self.dtype, values, Some(mutable_bitmap))
363                            .unwrap(),
364                    ),
365                    Left(values) => Left(PrimitiveArray::new(
366                        self.dtype,
367                        values,
368                        Some(mutable_bitmap.into()),
369                    )),
370                },
371            }
372        } else {
373            match self.values.into_mut() {
374                Right(values) => {
375                    Right(MutablePrimitiveArray::try_new(self.dtype, values, None).unwrap())
376                },
377                Left(values) => Left(PrimitiveArray::new(self.dtype, values, None)),
378            }
379        }
380    }
381
382    /// Returns a new empty (zero-length) [`PrimitiveArray`].
383    pub fn new_empty(dtype: ArrowDataType) -> Self {
384        Self::new(dtype, Buffer::new(), None)
385    }
386
387    /// Returns a new [`PrimitiveArray`] where all slots are null / `None`.
388    #[inline]
389    pub fn new_null(dtype: ArrowDataType, length: usize) -> Self {
390        Self::new(
391            dtype,
392            vec![T::default(); length].into(),
393            Some(Bitmap::new_zeroed(length)),
394        )
395    }
396
397    /// Creates a (non-null) [`PrimitiveArray`] from an iterator of values.
398    /// # Implementation
399    /// This does not assume that the iterator has a known length.
400    pub fn from_values<I: IntoIterator<Item = T>>(iter: I) -> Self {
401        Self::new(T::PRIMITIVE.into(), Vec::<T>::from_iter(iter).into(), None)
402    }
403
404    /// Creates a (non-null) [`PrimitiveArray`] from a slice of values.
405    /// # Implementation
406    /// This is essentially a memcopy and is thus `O(N)`
407    pub fn from_slice<P: AsRef<[T]>>(slice: P) -> Self {
408        Self::new(
409            T::PRIMITIVE.into(),
410            Vec::<T>::from(slice.as_ref()).into(),
411            None,
412        )
413    }
414
415    /// Creates a (non-null) [`PrimitiveArray`] from a [`TrustedLen`] of values.
416    /// # Implementation
417    /// This does not assume that the iterator has a known length.
418    pub fn from_trusted_len_values_iter<I: TrustedLen<Item = T>>(iter: I) -> Self {
419        MutablePrimitiveArray::<T>::from_trusted_len_values_iter(iter).into()
420    }
421
422    /// Creates a new [`PrimitiveArray`] from an iterator over values
423    ///
424    /// # Safety
425    /// The iterator must be [`TrustedLen`](https://doc.rust-lang.org/std/iter/trait.TrustedLen.html).
426    /// I.e. that `size_hint().1` correctly reports its length.
427    pub unsafe fn from_trusted_len_values_iter_unchecked<I: Iterator<Item = T>>(iter: I) -> Self {
428        MutablePrimitiveArray::<T>::from_trusted_len_values_iter_unchecked(iter).into()
429    }
430
431    /// Creates a [`PrimitiveArray`] from a [`TrustedLen`] of optional values.
432    pub fn from_trusted_len_iter<I: TrustedLen<Item = Option<T>>>(iter: I) -> Self {
433        MutablePrimitiveArray::<T>::from_trusted_len_iter(iter).into()
434    }
435
436    /// Creates a [`PrimitiveArray`] from an iterator of optional values.
437    ///
438    /// # Safety
439    /// The iterator must be [`TrustedLen`](https://doc.rust-lang.org/std/iter/trait.TrustedLen.html).
440    /// I.e. that `size_hint().1` correctly reports its length.
441    pub unsafe fn from_trusted_len_iter_unchecked<I: Iterator<Item = Option<T>>>(iter: I) -> Self {
442        MutablePrimitiveArray::<T>::from_trusted_len_iter_unchecked(iter).into()
443    }
444
445    /// Alias for `Self::try_new(..).unwrap()`.
446    /// # Panics
447    /// This function errors iff:
448    /// * The validity is not `None` and its length is different from `values`'s length
449    /// * The `dtype`'s [`PhysicalType`] is not equal to [`PhysicalType::Primitive`].
450    pub fn new(dtype: ArrowDataType, values: Buffer<T>, validity: Option<Bitmap>) -> Self {
451        Self::try_new(dtype, values, validity).unwrap()
452    }
453
454    /// Transmute this PrimitiveArray into another PrimitiveArray.
455    ///
456    /// T and U must have the same size and alignment.
457    pub fn transmute<U: NativeType>(self) -> PrimitiveArray<U> {
458        let PrimitiveArray {
459            values, validity, ..
460        } = self;
461        PrimitiveArray::new(
462            U::PRIMITIVE.into(),
463            Buffer::try_transmute::<U>(values).unwrap(),
464            validity,
465        )
466    }
467
468    /// Fills this entire array with the given value, leaving the validity mask intact.
469    ///
470    /// Reuses the memory of the PrimitiveArray if possible.
471    pub fn fill_with(mut self, value: T) -> Self {
472        if let Some(values) = self.get_mut_values() {
473            for x in values.iter_mut() {
474                *x = value;
475            }
476            self
477        } else {
478            let values = vec![value; self.len()];
479            Self::new(T::PRIMITIVE.into(), values.into(), self.validity)
480        }
481    }
482}
483
484impl<T: NativeType> Array for PrimitiveArray<T> {
485    impl_common_array!();
486
487    fn validity(&self) -> Option<&Bitmap> {
488        self.validity.as_ref()
489    }
490
491    #[inline]
492    fn with_validity(&self, validity: Option<Bitmap>) -> Box<dyn Array> {
493        Box::new(self.clone().with_validity(validity))
494    }
495}
496
497impl<T: NativeType> Splitable for PrimitiveArray<T> {
498    #[inline(always)]
499    fn check_bound(&self, offset: usize) -> bool {
500        offset <= self.len()
501    }
502
503    unsafe fn _split_at_unchecked(&self, offset: usize) -> (Self, Self) {
504        let (lhs_values, rhs_values) = unsafe { self.values.split_at_unchecked(offset) };
505        let (lhs_validity, rhs_validity) = unsafe { self.validity.split_at_unchecked(offset) };
506
507        (
508            Self {
509                dtype: self.dtype.clone(),
510                values: lhs_values,
511                validity: lhs_validity,
512            },
513            Self {
514                dtype: self.dtype.clone(),
515                values: rhs_values,
516                validity: rhs_validity,
517            },
518        )
519    }
520}
521
522impl<T: NativeType> SliceAble for PrimitiveArray<T> {
523    unsafe fn slice_unchecked(&self, range: Range<usize>) -> Self {
524        self.clone().sliced_unchecked(range.start, range.len())
525    }
526
527    fn slice(&self, range: Range<usize>) -> Self {
528        self.clone().sliced(range.start, range.len())
529    }
530}
531
532impl<T: NativeType> Indexable for PrimitiveArray<T> {
533    type Item = Option<T>;
534
535    fn get(&self, i: usize) -> Self::Item {
536        if !self.is_null(i) {
537            // soundness: Array::is_null panics if i >= self.len
538            unsafe { Some(self.value_unchecked(i)) }
539        } else {
540            None
541        }
542    }
543
544    unsafe fn get_unchecked(&self, i: usize) -> Self::Item {
545        if !self.is_null_unchecked(i) {
546            Some(self.value_unchecked(i))
547        } else {
548            None
549        }
550    }
551}
552
553/// A type definition [`PrimitiveArray`] for `i8`
554pub type Int8Array = PrimitiveArray<i8>;
555/// A type definition [`PrimitiveArray`] for `i16`
556pub type Int16Array = PrimitiveArray<i16>;
557/// A type definition [`PrimitiveArray`] for `i32`
558pub type Int32Array = PrimitiveArray<i32>;
559/// A type definition [`PrimitiveArray`] for `i64`
560pub type Int64Array = PrimitiveArray<i64>;
561/// A type definition [`PrimitiveArray`] for `i128`
562pub type Int128Array = PrimitiveArray<i128>;
563/// A type definition [`PrimitiveArray`] for `i256`
564pub type Int256Array = PrimitiveArray<i256>;
565/// A type definition [`PrimitiveArray`] for [`days_ms`]
566pub type DaysMsArray = PrimitiveArray<days_ms>;
567/// A type definition [`PrimitiveArray`] for [`months_days_ns`]
568pub type MonthsDaysNsArray = PrimitiveArray<months_days_ns>;
569/// A type definition [`PrimitiveArray`] for `f16`
570pub type Float16Array = PrimitiveArray<f16>;
571/// A type definition [`PrimitiveArray`] for `f32`
572pub type Float32Array = PrimitiveArray<f32>;
573/// A type definition [`PrimitiveArray`] for `f64`
574pub type Float64Array = PrimitiveArray<f64>;
575/// A type definition [`PrimitiveArray`] for `u8`
576pub type UInt8Array = PrimitiveArray<u8>;
577/// A type definition [`PrimitiveArray`] for `u16`
578pub type UInt16Array = PrimitiveArray<u16>;
579/// A type definition [`PrimitiveArray`] for `u32`
580pub type UInt32Array = PrimitiveArray<u32>;
581/// A type definition [`PrimitiveArray`] for `u64`
582pub type UInt64Array = PrimitiveArray<u64>;
583/// A type definition [`PrimitiveArray`] for `u128`
584pub type UInt128Array = PrimitiveArray<u128>;
585
586/// A type definition [`MutablePrimitiveArray`] for `i8`
587pub type Int8Vec = MutablePrimitiveArray<i8>;
588/// A type definition [`MutablePrimitiveArray`] for `i16`
589pub type Int16Vec = MutablePrimitiveArray<i16>;
590/// A type definition [`MutablePrimitiveArray`] for `i32`
591pub type Int32Vec = MutablePrimitiveArray<i32>;
592/// A type definition [`MutablePrimitiveArray`] for `i64`
593pub type Int64Vec = MutablePrimitiveArray<i64>;
594/// A type definition [`MutablePrimitiveArray`] for `i128`
595pub type Int128Vec = MutablePrimitiveArray<i128>;
596/// A type definition [`MutablePrimitiveArray`] for `i256`
597pub type Int256Vec = MutablePrimitiveArray<i256>;
598/// A type definition [`MutablePrimitiveArray`] for [`days_ms`]
599pub type DaysMsVec = MutablePrimitiveArray<days_ms>;
600/// A type definition [`MutablePrimitiveArray`] for [`months_days_ns`]
601pub type MonthsDaysNsVec = MutablePrimitiveArray<months_days_ns>;
602/// A type definition [`MutablePrimitiveArray`] for `f16`
603pub type Float16Vec = MutablePrimitiveArray<f16>;
604/// A type definition [`MutablePrimitiveArray`] for `f32`
605pub type Float32Vec = MutablePrimitiveArray<f32>;
606/// A type definition [`MutablePrimitiveArray`] for `f64`
607pub type Float64Vec = MutablePrimitiveArray<f64>;
608/// A type definition [`MutablePrimitiveArray`] for `u8`
609pub type UInt8Vec = MutablePrimitiveArray<u8>;
610/// A type definition [`MutablePrimitiveArray`] for `u16`
611pub type UInt16Vec = MutablePrimitiveArray<u16>;
612/// A type definition [`MutablePrimitiveArray`] for `u32`
613pub type UInt32Vec = MutablePrimitiveArray<u32>;
614/// A type definition [`MutablePrimitiveArray`] for `u64`
615pub type UInt64Vec = MutablePrimitiveArray<u64>;
616/// A type definition [`MutablePrimitiveArray`] for `u128`
617pub type UInt128Vec = MutablePrimitiveArray<u128>;
618
619impl<T: NativeType> Default for PrimitiveArray<T> {
620    fn default() -> Self {
621        PrimitiveArray::new(T::PRIMITIVE.into(), Default::default(), None)
622    }
623}
624
625impl<T: NativeType> Bounded for PrimitiveArray<T> {
626    fn len(&self) -> usize {
627        self.values.len()
628    }
629}
630
631impl<T: NativeType> NullCount for PrimitiveArray<T> {
632    fn null_count(&self) -> usize {
633        <Self as Array>::null_count(self)
634    }
635}