arrow_array/array/
primitive_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 crate::array::print_long_array;
19use crate::builder::{BooleanBufferBuilder, BufferBuilder, PrimitiveBuilder};
20use crate::iterator::PrimitiveIter;
21use crate::temporal_conversions::{
22    as_date, as_datetime, as_datetime_with_timezone, as_duration, as_time,
23};
24use crate::timezone::Tz;
25use crate::trusted_len::trusted_len_unzip;
26use crate::types::*;
27use crate::{Array, ArrayAccessor, ArrayRef, Scalar};
28use arrow_buffer::{i256, ArrowNativeType, Buffer, NullBuffer, ScalarBuffer};
29use arrow_data::bit_iterator::try_for_each_valid_idx;
30use arrow_data::{ArrayData, ArrayDataBuilder};
31use arrow_schema::{ArrowError, DataType};
32use chrono::{DateTime, Duration, NaiveDate, NaiveDateTime, NaiveTime};
33use half::f16;
34use std::any::Any;
35use std::sync::Arc;
36
37/// A [`PrimitiveArray`] of `i8`
38///
39/// # Examples
40///
41/// Construction
42///
43/// ```
44/// # use arrow_array::Int8Array;
45/// // Create from Vec<Option<i8>>
46/// let arr = Int8Array::from(vec![Some(1), None, Some(2)]);
47/// // Create from Vec<i8>
48/// let arr = Int8Array::from(vec![1, 2, 3]);
49/// // Create iter/collect
50/// let arr: Int8Array = std::iter::repeat(42).take(10).collect();
51/// ```
52///
53/// See [`PrimitiveArray`] for more information and examples
54pub type Int8Array = PrimitiveArray<Int8Type>;
55
56/// A [`PrimitiveArray`] of `i16`
57///
58/// # Examples
59///
60/// Construction
61///
62/// ```
63/// # use arrow_array::Int16Array;
64/// // Create from Vec<Option<i16>>
65/// let arr = Int16Array::from(vec![Some(1), None, Some(2)]);
66/// // Create from Vec<i16>
67/// let arr = Int16Array::from(vec![1, 2, 3]);
68/// // Create iter/collect
69/// let arr: Int16Array = std::iter::repeat(42).take(10).collect();
70/// ```
71///
72/// See [`PrimitiveArray`] for more information and examples
73pub type Int16Array = PrimitiveArray<Int16Type>;
74
75/// A [`PrimitiveArray`] of `i32`
76///
77/// # Examples
78///
79/// Construction
80///
81/// ```
82/// # use arrow_array::Int32Array;
83/// // Create from Vec<Option<i32>>
84/// let arr = Int32Array::from(vec![Some(1), None, Some(2)]);
85/// // Create from Vec<i32>
86/// let arr = Int32Array::from(vec![1, 2, 3]);
87/// // Create iter/collect
88/// let arr: Int32Array = std::iter::repeat(42).take(10).collect();
89/// ```
90///
91/// See [`PrimitiveArray`] for more information and examples
92pub type Int32Array = PrimitiveArray<Int32Type>;
93
94/// A [`PrimitiveArray`] of `i64`
95///
96/// # Examples
97///
98/// Construction
99///
100/// ```
101/// # use arrow_array::Int64Array;
102/// // Create from Vec<Option<i64>>
103/// let arr = Int64Array::from(vec![Some(1), None, Some(2)]);
104/// // Create from Vec<i64>
105/// let arr = Int64Array::from(vec![1, 2, 3]);
106/// // Create iter/collect
107/// let arr: Int64Array = std::iter::repeat(42).take(10).collect();
108/// ```
109///
110/// See [`PrimitiveArray`] for more information and examples
111pub type Int64Array = PrimitiveArray<Int64Type>;
112
113/// A [`PrimitiveArray`] of `u8`
114///
115/// # Examples
116///
117/// Construction
118///
119/// ```
120/// # use arrow_array::UInt8Array;
121/// // Create from Vec<Option<u8>>
122/// let arr = UInt8Array::from(vec![Some(1), None, Some(2)]);
123/// // Create from Vec<u8>
124/// let arr = UInt8Array::from(vec![1, 2, 3]);
125/// // Create iter/collect
126/// let arr: UInt8Array = std::iter::repeat(42).take(10).collect();
127/// ```
128///
129/// See [`PrimitiveArray`] for more information and examples
130pub type UInt8Array = PrimitiveArray<UInt8Type>;
131
132/// A [`PrimitiveArray`] of `u16`
133///
134/// # Examples
135///
136/// Construction
137///
138/// ```
139/// # use arrow_array::UInt16Array;
140/// // Create from Vec<Option<u16>>
141/// let arr = UInt16Array::from(vec![Some(1), None, Some(2)]);
142/// // Create from Vec<u16>
143/// let arr = UInt16Array::from(vec![1, 2, 3]);
144/// // Create iter/collect
145/// let arr: UInt16Array = std::iter::repeat(42).take(10).collect();
146/// ```
147///
148/// See [`PrimitiveArray`] for more information and examples
149pub type UInt16Array = PrimitiveArray<UInt16Type>;
150
151/// A [`PrimitiveArray`] of `u32`
152///
153/// # Examples
154///
155/// Construction
156///
157/// ```
158/// # use arrow_array::UInt32Array;
159/// // Create from Vec<Option<u32>>
160/// let arr = UInt32Array::from(vec![Some(1), None, Some(2)]);
161/// // Create from Vec<u32>
162/// let arr = UInt32Array::from(vec![1, 2, 3]);
163/// // Create iter/collect
164/// let arr: UInt32Array = std::iter::repeat(42).take(10).collect();
165/// ```
166///
167/// See [`PrimitiveArray`] for more information and examples
168pub type UInt32Array = PrimitiveArray<UInt32Type>;
169
170/// A [`PrimitiveArray`] of `u64`
171///
172/// # Examples
173///
174/// Construction
175///
176/// ```
177/// # use arrow_array::UInt64Array;
178/// // Create from Vec<Option<u64>>
179/// let arr = UInt64Array::from(vec![Some(1), None, Some(2)]);
180/// // Create from Vec<u64>
181/// let arr = UInt64Array::from(vec![1, 2, 3]);
182/// // Create iter/collect
183/// let arr: UInt64Array = std::iter::repeat(42).take(10).collect();
184/// ```
185///
186/// See [`PrimitiveArray`] for more information and examples
187pub type UInt64Array = PrimitiveArray<UInt64Type>;
188
189/// A [`PrimitiveArray`] of `f16`
190///
191/// # Examples
192///
193/// Construction
194///
195/// ```
196/// # use arrow_array::Float16Array;
197/// use half::f16;
198/// // Create from Vec<Option<f16>>
199/// let arr = Float16Array::from(vec![Some(f16::from_f64(1.0)), Some(f16::from_f64(2.0))]);
200/// // Create from Vec<i8>
201/// let arr = Float16Array::from(vec![f16::from_f64(1.0), f16::from_f64(2.0), f16::from_f64(3.0)]);
202/// // Create iter/collect
203/// let arr: Float16Array = std::iter::repeat(f16::from_f64(1.0)).take(10).collect();
204/// ```
205///
206/// # Example: Using `collect`
207/// ```
208/// # use arrow_array::Float16Array;
209/// use half::f16;
210/// let arr : Float16Array = [Some(f16::from_f64(1.0)), Some(f16::from_f64(2.0))].into_iter().collect();
211/// ```
212///
213/// See [`PrimitiveArray`] for more information and examples
214pub type Float16Array = PrimitiveArray<Float16Type>;
215
216/// A [`PrimitiveArray`] of `f32`
217///
218/// # Examples
219///
220/// Construction
221///
222/// ```
223/// # use arrow_array::Float32Array;
224/// // Create from Vec<Option<f32>>
225/// let arr = Float32Array::from(vec![Some(1.0), None, Some(2.0)]);
226/// // Create from Vec<f32>
227/// let arr = Float32Array::from(vec![1.0, 2.0, 3.0]);
228/// // Create iter/collect
229/// let arr: Float32Array = std::iter::repeat(42.0).take(10).collect();
230/// ```
231///
232/// See [`PrimitiveArray`] for more information and examples
233pub type Float32Array = PrimitiveArray<Float32Type>;
234
235/// A [`PrimitiveArray`] of `f64`
236///
237/// # Examples
238///
239/// Construction
240///
241/// ```
242/// # use arrow_array::Float64Array;
243/// // Create from Vec<Option<f32>>
244/// let arr = Float64Array::from(vec![Some(1.0), None, Some(2.0)]);
245/// // Create from Vec<f32>
246/// let arr = Float64Array::from(vec![1.0, 2.0, 3.0]);
247/// // Create iter/collect
248/// let arr: Float64Array = std::iter::repeat(42.0).take(10).collect();
249/// ```
250///
251/// See [`PrimitiveArray`] for more information and examples
252pub type Float64Array = PrimitiveArray<Float64Type>;
253
254/// A [`PrimitiveArray`] of seconds since UNIX epoch stored as `i64`
255///
256/// This type is similar to the [`chrono::DateTime`] type and can hold
257/// values such as `1970-05-09 14:25:11 +01:00`
258///
259/// See also [`Timestamp`](arrow_schema::DataType::Timestamp).
260///
261/// # Example: UTC timestamps post epoch
262/// ```
263/// # use arrow_array::TimestampSecondArray;
264/// use arrow_array::timezone::Tz;
265/// // Corresponds to single element array with entry 1970-05-09T14:25:11+0:00
266/// let arr = TimestampSecondArray::from(vec![11111111]);
267/// // OR
268/// let arr = TimestampSecondArray::from(vec![Some(11111111)]);
269/// let utc_tz: Tz = "+00:00".parse().unwrap();
270///
271/// assert_eq!(arr.value_as_datetime_with_tz(0, utc_tz).map(|v| v.to_string()).unwrap(), "1970-05-09 14:25:11 +00:00")
272/// ```
273///
274/// # Example: UTC timestamps pre epoch
275/// ```
276/// # use arrow_array::TimestampSecondArray;
277/// use arrow_array::timezone::Tz;
278/// // Corresponds to single element array with entry 1969-08-25T09:34:49+0:00
279/// let arr = TimestampSecondArray::from(vec![-11111111]);
280/// // OR
281/// let arr = TimestampSecondArray::from(vec![Some(-11111111)]);
282/// let utc_tz: Tz = "+00:00".parse().unwrap();
283///
284/// assert_eq!(arr.value_as_datetime_with_tz(0, utc_tz).map(|v| v.to_string()).unwrap(), "1969-08-25 09:34:49 +00:00")
285/// ```
286///
287/// # Example: With timezone specified
288/// ```
289/// # use arrow_array::TimestampSecondArray;
290/// use arrow_array::timezone::Tz;
291/// // Corresponds to single element array with entry 1970-05-10T00:25:11+10:00
292/// let arr = TimestampSecondArray::from(vec![11111111]).with_timezone("+10:00".to_string());
293/// // OR
294/// let arr = TimestampSecondArray::from(vec![Some(11111111)]).with_timezone("+10:00".to_string());
295/// let sydney_tz: Tz = "+10:00".parse().unwrap();
296///
297/// assert_eq!(arr.value_as_datetime_with_tz(0, sydney_tz).map(|v| v.to_string()).unwrap(), "1970-05-10 00:25:11 +10:00")
298/// ```
299///
300/// See [`PrimitiveArray`] for more information and examples
301pub type TimestampSecondArray = PrimitiveArray<TimestampSecondType>;
302
303/// A [`PrimitiveArray`] of milliseconds since UNIX epoch stored as `i64`
304///
305/// See examples for [`TimestampSecondArray`]
306pub type TimestampMillisecondArray = PrimitiveArray<TimestampMillisecondType>;
307
308/// A [`PrimitiveArray`] of microseconds since UNIX epoch stored as `i64`
309///
310/// See examples for [`TimestampSecondArray`]
311pub type TimestampMicrosecondArray = PrimitiveArray<TimestampMicrosecondType>;
312
313/// A [`PrimitiveArray`] of nanoseconds since UNIX epoch stored as `i64`
314///
315/// See examples for [`TimestampSecondArray`]
316pub type TimestampNanosecondArray = PrimitiveArray<TimestampNanosecondType>;
317
318/// A [`PrimitiveArray`] of days since UNIX epoch stored as `i32`
319///
320/// This type is similar to the [`chrono::NaiveDate`] type and can hold
321/// values such as `2018-11-13`
322pub type Date32Array = PrimitiveArray<Date32Type>;
323
324/// A [`PrimitiveArray`] of milliseconds since UNIX epoch stored as `i64`
325///
326/// This type is similar to the [`chrono::NaiveDate`] type and can hold
327/// values such as `2018-11-13`
328pub type Date64Array = PrimitiveArray<Date64Type>;
329
330/// A [`PrimitiveArray`] of seconds since midnight stored as `i32`
331///
332/// This type is similar to the [`chrono::NaiveTime`] type and can
333/// hold values such as `00:02:00`
334pub type Time32SecondArray = PrimitiveArray<Time32SecondType>;
335
336/// A [`PrimitiveArray`] of milliseconds since midnight stored as `i32`
337///
338/// This type is similar to the [`chrono::NaiveTime`] type and can
339/// hold values such as `00:02:00.123`
340pub type Time32MillisecondArray = PrimitiveArray<Time32MillisecondType>;
341
342/// A [`PrimitiveArray`] of microseconds since midnight stored as `i64`
343///
344/// This type is similar to the [`chrono::NaiveTime`] type and can
345/// hold values such as `00:02:00.123456`
346pub type Time64MicrosecondArray = PrimitiveArray<Time64MicrosecondType>;
347
348/// A [`PrimitiveArray`] of nanoseconds since midnight stored as `i64`
349///
350/// This type is similar to the [`chrono::NaiveTime`] type and can
351/// hold values such as `00:02:00.123456789`
352pub type Time64NanosecondArray = PrimitiveArray<Time64NanosecondType>;
353
354/// A [`PrimitiveArray`] of “calendar” intervals in whole months
355///
356/// See [`IntervalYearMonthType`] for details on representation and caveats.
357///
358/// # Example
359/// ```
360/// # use arrow_array::IntervalYearMonthArray;
361/// let array = IntervalYearMonthArray::from(vec![
362///   2,  // 2 months
363///   25, // 2 years and 1 month
364///   -1  // -1 months
365/// ]);
366/// ```
367pub type IntervalYearMonthArray = PrimitiveArray<IntervalYearMonthType>;
368
369/// A [`PrimitiveArray`] of “calendar” intervals in days and milliseconds
370///
371/// See [`IntervalDayTime`] for details on representation and caveats.
372///
373/// # Example
374/// ```
375/// # use arrow_array::IntervalDayTimeArray;
376/// use arrow_array::types::IntervalDayTime;
377/// let array = IntervalDayTimeArray::from(vec![
378///   IntervalDayTime::new(1, 1000),                 // 1 day, 1000 milliseconds
379///   IntervalDayTime::new(33, 0),                  // 33 days, 0 milliseconds
380///   IntervalDayTime::new(0, 12 * 60 * 60 * 1000), // 0 days, 12 hours
381/// ]);
382/// ```
383pub type IntervalDayTimeArray = PrimitiveArray<IntervalDayTimeType>;
384
385/// A [`PrimitiveArray`] of “calendar” intervals in  months, days, and nanoseconds.
386///
387/// See [`IntervalMonthDayNano`] for details on representation and caveats.
388///
389/// # Example
390/// ```
391/// # use arrow_array::IntervalMonthDayNanoArray;
392/// use arrow_array::types::IntervalMonthDayNano;
393/// let array = IntervalMonthDayNanoArray::from(vec![
394///   IntervalMonthDayNano::new(1, 2, 1000),             // 1 month, 2 days, 1 nanosecond
395///   IntervalMonthDayNano::new(12, 1, 0),               // 12 months, 1 days, 0 nanoseconds
396///   IntervalMonthDayNano::new(0, 0, 12 * 1000 * 1000), // 0 days, 12 milliseconds
397/// ]);
398/// ```
399pub type IntervalMonthDayNanoArray = PrimitiveArray<IntervalMonthDayNanoType>;
400
401/// A [`PrimitiveArray`] of elapsed durations in seconds
402pub type DurationSecondArray = PrimitiveArray<DurationSecondType>;
403
404/// A [`PrimitiveArray`] of elapsed durations in milliseconds
405pub type DurationMillisecondArray = PrimitiveArray<DurationMillisecondType>;
406
407/// A [`PrimitiveArray`] of elapsed durations in microseconds
408pub type DurationMicrosecondArray = PrimitiveArray<DurationMicrosecondType>;
409
410/// A [`PrimitiveArray`] of elapsed durations in nanoseconds
411pub type DurationNanosecondArray = PrimitiveArray<DurationNanosecondType>;
412
413/// A [`PrimitiveArray`] of 128-bit fixed point decimals
414///
415/// # Examples
416///
417/// Construction
418///
419/// ```
420/// # use arrow_array::Decimal128Array;
421/// // Create from Vec<Option<i18>>
422/// let arr = Decimal128Array::from(vec![Some(1), None, Some(2)]);
423/// // Create from Vec<i128>
424/// let arr = Decimal128Array::from(vec![1, 2, 3]);
425/// // Create iter/collect
426/// let arr: Decimal128Array = std::iter::repeat(42).take(10).collect();
427/// ```
428///
429/// See [`PrimitiveArray`] for more information and examples
430pub type Decimal128Array = PrimitiveArray<Decimal128Type>;
431
432/// A [`PrimitiveArray`] of 256-bit fixed point decimals
433///
434/// # Examples
435///
436/// Construction
437///
438/// ```
439/// # use arrow_array::Decimal256Array;
440/// use arrow_buffer::i256;
441/// // Create from Vec<Option<i256>>
442/// let arr = Decimal256Array::from(vec![Some(i256::from(1)), None, Some(i256::from(2))]);
443/// // Create from Vec<i256>
444/// let arr = Decimal256Array::from(vec![i256::from(1), i256::from(2), i256::from(3)]);
445/// // Create iter/collect
446/// let arr: Decimal256Array = std::iter::repeat(i256::from(42)).take(10).collect();
447/// ```
448///
449/// See [`PrimitiveArray`] for more information and examples
450pub type Decimal256Array = PrimitiveArray<Decimal256Type>;
451
452pub use crate::types::ArrowPrimitiveType;
453
454/// An array of primitive values, of type [`ArrowPrimitiveType`]
455///
456/// # Example: From a Vec
457///
458/// ```
459/// # use arrow_array::{Array, PrimitiveArray, types::Int32Type};
460/// let arr: PrimitiveArray<Int32Type> = vec![1, 2, 3, 4].into();
461/// assert_eq!(4, arr.len());
462/// assert_eq!(0, arr.null_count());
463/// assert_eq!(arr.values(), &[1, 2, 3, 4])
464/// ```
465///
466/// # Example: From an optional Vec
467///
468/// ```
469/// # use arrow_array::{Array, PrimitiveArray, types::Int32Type};
470/// let arr: PrimitiveArray<Int32Type> = vec![Some(1), None, Some(3), None].into();
471/// assert_eq!(4, arr.len());
472/// assert_eq!(2, arr.null_count());
473/// // Note: values for null indexes are arbitrary
474/// assert_eq!(arr.values(), &[1, 0, 3, 0])
475/// ```
476///
477/// # Example: From an iterator of values
478///
479/// ```
480/// # use arrow_array::{Array, PrimitiveArray, types::Int32Type};
481/// let arr: PrimitiveArray<Int32Type> = (0..10).map(|x| x + 1).collect();
482/// assert_eq!(10, arr.len());
483/// assert_eq!(0, arr.null_count());
484/// for i in 0..10i32 {
485///     assert_eq!(i + 1, arr.value(i as usize));
486/// }
487/// ```
488///
489/// # Example: From an iterator of option
490///
491/// ```
492/// # use arrow_array::{Array, PrimitiveArray, types::Int32Type};
493/// let arr: PrimitiveArray<Int32Type> = (0..10).map(|x| (x % 2 == 0).then_some(x)).collect();
494/// assert_eq!(10, arr.len());
495/// assert_eq!(5, arr.null_count());
496/// // Note: values for null indexes are arbitrary
497/// assert_eq!(arr.values(), &[0, 0, 2, 0, 4, 0, 6, 0, 8, 0])
498/// ```
499///
500/// # Example: Using Builder
501///
502/// ```
503/// # use arrow_array::Array;
504/// # use arrow_array::builder::PrimitiveBuilder;
505/// # use arrow_array::types::Int32Type;
506/// let mut builder = PrimitiveBuilder::<Int32Type>::new();
507/// builder.append_value(1);
508/// builder.append_null();
509/// builder.append_value(2);
510/// let array = builder.finish();
511/// // Note: values for null indexes are arbitrary
512/// assert_eq!(array.values(), &[1, 0, 2]);
513/// assert!(array.is_null(1));
514/// ```
515///
516/// # Example: Get a `PrimitiveArray` from an [`ArrayRef`]
517/// ```
518/// # use std::sync::Arc;
519/// # use arrow_array::{Array, cast::AsArray, ArrayRef, Float32Array, PrimitiveArray};
520/// # use arrow_array::types::{Float32Type};
521/// # use arrow_schema::DataType;
522/// # let array: ArrayRef =  Arc::new(Float32Array::from(vec![1.2, 2.3]));
523/// // will panic if the array is not a Float32Array
524/// assert_eq!(&DataType::Float32, array.data_type());
525/// let f32_array: Float32Array  = array.as_primitive().clone();
526/// assert_eq!(f32_array, Float32Array::from(vec![1.2, 2.3]));
527/// ```
528pub struct PrimitiveArray<T: ArrowPrimitiveType> {
529    data_type: DataType,
530    /// Values data
531    values: ScalarBuffer<T::Native>,
532    nulls: Option<NullBuffer>,
533}
534
535impl<T: ArrowPrimitiveType> Clone for PrimitiveArray<T> {
536    fn clone(&self) -> Self {
537        Self {
538            data_type: self.data_type.clone(),
539            values: self.values.clone(),
540            nulls: self.nulls.clone(),
541        }
542    }
543}
544
545impl<T: ArrowPrimitiveType> PrimitiveArray<T> {
546    /// Create a new [`PrimitiveArray`] from the provided values and nulls
547    ///
548    /// # Panics
549    ///
550    /// Panics if [`Self::try_new`] returns an error
551    ///
552    /// # Example
553    ///
554    /// Creating a [`PrimitiveArray`] directly from a [`ScalarBuffer`] and [`NullBuffer`] using
555    /// this constructor is the most performant approach, avoiding any additional allocations
556    ///
557    /// ```
558    /// # use arrow_array::Int32Array;
559    /// # use arrow_array::types::Int32Type;
560    /// # use arrow_buffer::NullBuffer;
561    /// // [1, 2, 3, 4]
562    /// let array = Int32Array::new(vec![1, 2, 3, 4].into(), None);
563    /// // [1, null, 3, 4]
564    /// let nulls = NullBuffer::from(vec![true, false, true, true]);
565    /// let array = Int32Array::new(vec![1, 2, 3, 4].into(), Some(nulls));
566    /// ```
567    pub fn new(values: ScalarBuffer<T::Native>, nulls: Option<NullBuffer>) -> Self {
568        Self::try_new(values, nulls).unwrap()
569    }
570
571    /// Create a new [`PrimitiveArray`] of the given length where all values are null
572    pub fn new_null(length: usize) -> Self {
573        Self {
574            data_type: T::DATA_TYPE,
575            values: vec![T::Native::usize_as(0); length].into(),
576            nulls: Some(NullBuffer::new_null(length)),
577        }
578    }
579
580    /// Create a new [`PrimitiveArray`] from the provided values and nulls
581    ///
582    /// # Errors
583    ///
584    /// Errors if:
585    /// - `values.len() != nulls.len()`
586    pub fn try_new(
587        values: ScalarBuffer<T::Native>,
588        nulls: Option<NullBuffer>,
589    ) -> Result<Self, ArrowError> {
590        if let Some(n) = nulls.as_ref() {
591            if n.len() != values.len() {
592                return Err(ArrowError::InvalidArgumentError(format!(
593                    "Incorrect length of null buffer for PrimitiveArray, expected {} got {}",
594                    values.len(),
595                    n.len(),
596                )));
597            }
598        }
599
600        Ok(Self {
601            data_type: T::DATA_TYPE,
602            values,
603            nulls,
604        })
605    }
606
607    /// Create a new [`Scalar`] from `value`
608    pub fn new_scalar(value: T::Native) -> Scalar<Self> {
609        Scalar::new(Self {
610            data_type: T::DATA_TYPE,
611            values: vec![value].into(),
612            nulls: None,
613        })
614    }
615
616    /// Deconstruct this array into its constituent parts
617    pub fn into_parts(self) -> (DataType, ScalarBuffer<T::Native>, Option<NullBuffer>) {
618        (self.data_type, self.values, self.nulls)
619    }
620
621    /// Overrides the [`DataType`] of this [`PrimitiveArray`]
622    ///
623    /// Prefer using [`Self::with_timezone`] or [`Self::with_precision_and_scale`] where
624    /// the primitive type is suitably constrained, as these cannot panic
625    ///
626    /// # Panics
627    ///
628    /// Panics if ![Self::is_compatible]
629    pub fn with_data_type(self, data_type: DataType) -> Self {
630        Self::assert_compatible(&data_type);
631        Self { data_type, ..self }
632    }
633
634    /// Asserts that `data_type` is compatible with `Self`
635    fn assert_compatible(data_type: &DataType) {
636        assert!(
637            Self::is_compatible(data_type),
638            "PrimitiveArray expected data type {} got {}",
639            T::DATA_TYPE,
640            data_type
641        );
642    }
643
644    /// Returns the length of this array.
645    #[inline]
646    pub fn len(&self) -> usize {
647        self.values.len()
648    }
649
650    /// Returns whether this array is empty.
651    pub fn is_empty(&self) -> bool {
652        self.values.is_empty()
653    }
654
655    /// Returns the values of this array
656    #[inline]
657    pub fn values(&self) -> &ScalarBuffer<T::Native> {
658        &self.values
659    }
660
661    /// Returns a new primitive array builder
662    pub fn builder(capacity: usize) -> PrimitiveBuilder<T> {
663        PrimitiveBuilder::<T>::with_capacity(capacity)
664    }
665
666    /// Returns if this [`PrimitiveArray`] is compatible with the provided [`DataType`]
667    ///
668    /// This is equivalent to `data_type == T::DATA_TYPE`, however ignores timestamp
669    /// timezones and decimal precision and scale
670    pub fn is_compatible(data_type: &DataType) -> bool {
671        match T::DATA_TYPE {
672            DataType::Timestamp(t1, _) => {
673                matches!(data_type, DataType::Timestamp(t2, _) if &t1 == t2)
674            }
675            DataType::Decimal128(_, _) => matches!(data_type, DataType::Decimal128(_, _)),
676            DataType::Decimal256(_, _) => matches!(data_type, DataType::Decimal256(_, _)),
677            _ => T::DATA_TYPE.eq(data_type),
678        }
679    }
680
681    /// Returns the primitive value at index `i`.
682    ///
683    /// # Safety
684    ///
685    /// caller must ensure that the passed in offset is less than the array len()
686    #[inline]
687    pub unsafe fn value_unchecked(&self, i: usize) -> T::Native {
688        *self.values.get_unchecked(i)
689    }
690
691    /// Returns the primitive value at index `i`.
692    /// # Panics
693    /// Panics if index `i` is out of bounds
694    #[inline]
695    pub fn value(&self, i: usize) -> T::Native {
696        assert!(
697            i < self.len(),
698            "Trying to access an element at index {} from a PrimitiveArray of length {}",
699            i,
700            self.len()
701        );
702        unsafe { self.value_unchecked(i) }
703    }
704
705    /// Creates a PrimitiveArray based on an iterator of values without nulls
706    pub fn from_iter_values<I: IntoIterator<Item = T::Native>>(iter: I) -> Self {
707        let val_buf: Buffer = iter.into_iter().collect();
708        let len = val_buf.len() / std::mem::size_of::<T::Native>();
709        Self {
710            data_type: T::DATA_TYPE,
711            values: ScalarBuffer::new(val_buf, 0, len),
712            nulls: None,
713        }
714    }
715
716    /// Creates a PrimitiveArray based on an iterator of values with provided nulls
717    pub fn from_iter_values_with_nulls<I: IntoIterator<Item = T::Native>>(
718        iter: I,
719        nulls: Option<NullBuffer>,
720    ) -> Self {
721        let val_buf: Buffer = iter.into_iter().collect();
722        let len = val_buf.len() / std::mem::size_of::<T::Native>();
723        Self {
724            data_type: T::DATA_TYPE,
725            values: ScalarBuffer::new(val_buf, 0, len),
726            nulls,
727        }
728    }
729
730    /// Creates a PrimitiveArray based on a constant value with `count` elements
731    pub fn from_value(value: T::Native, count: usize) -> Self {
732        unsafe {
733            let val_buf = Buffer::from_trusted_len_iter((0..count).map(|_| value));
734            Self::new(val_buf.into(), None)
735        }
736    }
737
738    /// Returns an iterator that returns the values of `array.value(i)` for an iterator with each element `i`
739    pub fn take_iter<'a>(
740        &'a self,
741        indexes: impl Iterator<Item = Option<usize>> + 'a,
742    ) -> impl Iterator<Item = Option<T::Native>> + 'a {
743        indexes.map(|opt_index| opt_index.map(|index| self.value(index)))
744    }
745
746    /// Returns an iterator that returns the values of `array.value(i)` for an iterator with each element `i`
747    /// # Safety
748    ///
749    /// caller must ensure that the offsets in the iterator are less than the array len()
750    pub unsafe fn take_iter_unchecked<'a>(
751        &'a self,
752        indexes: impl Iterator<Item = Option<usize>> + 'a,
753    ) -> impl Iterator<Item = Option<T::Native>> + 'a {
754        indexes.map(|opt_index| opt_index.map(|index| self.value_unchecked(index)))
755    }
756
757    /// Returns a zero-copy slice of this array with the indicated offset and length.
758    pub fn slice(&self, offset: usize, length: usize) -> Self {
759        Self {
760            data_type: self.data_type.clone(),
761            values: self.values.slice(offset, length),
762            nulls: self.nulls.as_ref().map(|n| n.slice(offset, length)),
763        }
764    }
765
766    /// Reinterprets this array's contents as a different data type without copying
767    ///
768    /// This can be used to efficiently convert between primitive arrays with the
769    /// same underlying representation
770    ///
771    /// Note: this will not modify the underlying values, and therefore may change
772    /// the semantic values of the array, e.g. 100 milliseconds in a [`TimestampNanosecondArray`]
773    /// will become 100 seconds in a [`TimestampSecondArray`].
774    ///
775    /// For casts that preserve the semantic value, check out the
776    /// [compute kernels](https://docs.rs/arrow/latest/arrow/compute/kernels/cast/index.html).
777    ///
778    /// ```
779    /// # use arrow_array::{Int64Array, TimestampNanosecondArray};
780    /// let a = Int64Array::from_iter_values([1, 2, 3, 4]);
781    /// let b: TimestampNanosecondArray = a.reinterpret_cast();
782    /// ```
783    pub fn reinterpret_cast<K>(&self) -> PrimitiveArray<K>
784    where
785        K: ArrowPrimitiveType<Native = T::Native>,
786    {
787        let d = self.to_data().into_builder().data_type(K::DATA_TYPE);
788
789        // SAFETY:
790        // Native type is the same
791        PrimitiveArray::from(unsafe { d.build_unchecked() })
792    }
793
794    /// Applies a unary infallible function to a primitive array, producing a
795    /// new array of potentially different type.
796    ///
797    /// This is the fastest way to perform an operation on a primitive array
798    /// when the benefits of a vectorized operation outweigh the cost of
799    /// branching nulls and non-nulls.
800    ///
801    /// See also
802    /// * [`Self::unary_mut`] for in place modification.
803    /// * [`Self::try_unary`] for fallible operations.
804    /// * [`arrow::compute::binary`] for binary operations
805    ///
806    /// [`arrow::compute::binary`]: https://docs.rs/arrow/latest/arrow/compute/fn.binary.html
807    /// # Null Handling
808    ///
809    /// Applies the function for all values, including those on null slots. This
810    /// will often allow the compiler to generate faster vectorized code, but
811    /// requires that the operation must be infallible (not error/panic) for any
812    /// value of the corresponding type or this function may panic.
813    ///
814    /// # Example
815    /// ```rust
816    /// # use arrow_array::{Int32Array, Float32Array, types::Int32Type};
817    /// # fn main() {
818    /// let array = Int32Array::from(vec![Some(5), Some(7), None]);
819    /// // Create a new array with the value of applying sqrt
820    /// let c = array.unary(|x| f32::sqrt(x as f32));
821    /// assert_eq!(c, Float32Array::from(vec![Some(2.236068), Some(2.6457512), None]));
822    /// # }
823    /// ```
824    pub fn unary<F, O>(&self, op: F) -> PrimitiveArray<O>
825    where
826        O: ArrowPrimitiveType,
827        F: Fn(T::Native) -> O::Native,
828    {
829        let nulls = self.nulls().cloned();
830        let values = self.values().iter().map(|v| op(*v));
831        // JUSTIFICATION
832        //  Benefit
833        //      ~60% speedup
834        //  Soundness
835        //      `values` is an iterator with a known size because arrays are sized.
836        let buffer = unsafe { Buffer::from_trusted_len_iter(values) };
837        PrimitiveArray::new(buffer.into(), nulls)
838    }
839
840    /// Applies a unary and infallible function to the array in place if possible.
841    ///
842    /// # Buffer Reuse
843    ///
844    /// If the underlying buffers are not shared with other arrays,  mutates the
845    /// underlying buffer in place, without allocating.
846    ///
847    /// If the underlying buffer is shared, returns Err(self)
848    ///
849    /// # Null Handling
850    ///
851    /// See [`Self::unary`] for more information on null handling.
852    ///
853    /// # Example
854    ///
855    /// ```rust
856    /// # use arrow_array::{Int32Array, types::Int32Type};
857    /// let array = Int32Array::from(vec![Some(5), Some(7), None]);
858    /// // Apply x*2+1 to the data in place, no allocations
859    /// let c = array.unary_mut(|x| x * 2 + 1).unwrap();
860    /// assert_eq!(c, Int32Array::from(vec![Some(11), Some(15), None]));
861    /// ```
862    ///
863    /// # Example: modify [`ArrayRef`] in place, if not shared
864    ///
865    /// It is also possible to modify an [`ArrayRef`] if there are no other
866    /// references to the underlying buffer.
867    ///
868    /// ```rust
869    /// # use std::sync::Arc;
870    /// # use arrow_array::{Array, cast::AsArray, ArrayRef, Int32Array, PrimitiveArray, types::Int32Type};
871    /// # let array: ArrayRef = Arc::new(Int32Array::from(vec![Some(5), Some(7), None]));
872    /// // Convert to Int32Array (panic's if array.data_type is not Int32)
873    /// let a = array.as_primitive::<Int32Type>().clone();
874    /// // Try to apply x*2+1 to the data in place, fails because array is still shared
875    /// a.unary_mut(|x| x * 2 + 1).unwrap_err();
876    /// // Try again, this time dropping the last remaining reference
877    /// let a = array.as_primitive::<Int32Type>().clone();
878    /// drop(array);
879    /// // Now we can apply the operation in place
880    /// let c = a.unary_mut(|x| x * 2 + 1).unwrap();
881    /// assert_eq!(c, Int32Array::from(vec![Some(11), Some(15), None]));
882    /// ```
883    pub fn unary_mut<F>(self, op: F) -> Result<PrimitiveArray<T>, PrimitiveArray<T>>
884    where
885        F: Fn(T::Native) -> T::Native,
886    {
887        let mut builder = self.into_builder()?;
888        builder
889            .values_slice_mut()
890            .iter_mut()
891            .for_each(|v| *v = op(*v));
892        Ok(builder.finish())
893    }
894
895    /// Applies a unary fallible function to all valid values in a primitive
896    /// array, producing a new array of potentially different type.
897    ///
898    /// Applies `op` to only rows that are valid, which is often significantly
899    /// slower than [`Self::unary`], which should be preferred if `op` is
900    /// fallible.
901    ///
902    /// Note: LLVM is currently unable to effectively vectorize fallible operations
903    pub fn try_unary<F, O, E>(&self, op: F) -> Result<PrimitiveArray<O>, E>
904    where
905        O: ArrowPrimitiveType,
906        F: Fn(T::Native) -> Result<O::Native, E>,
907    {
908        let len = self.len();
909
910        let nulls = self.nulls().cloned();
911        let mut buffer = BufferBuilder::<O::Native>::new(len);
912        buffer.append_n_zeroed(len);
913        let slice = buffer.as_slice_mut();
914
915        let f = |idx| {
916            unsafe { *slice.get_unchecked_mut(idx) = op(self.value_unchecked(idx))? };
917            Ok::<_, E>(())
918        };
919
920        match &nulls {
921            Some(nulls) => nulls.try_for_each_valid_idx(f)?,
922            None => (0..len).try_for_each(f)?,
923        }
924
925        let values = buffer.finish().into();
926        Ok(PrimitiveArray::new(values, nulls))
927    }
928
929    /// Applies a unary fallible function to all valid values in a mutable
930    /// primitive array.
931    ///
932    /// # Null Handling
933    ///
934    /// See [`Self::try_unary`] for more information on null handling.
935    ///
936    /// # Buffer Reuse
937    ///
938    /// See [`Self::unary_mut`] for more information on buffer reuse.
939    ///
940    /// This returns an `Err` when the input array is shared buffer with other
941    /// array. In the case, returned `Err` wraps input array. If the function
942    /// encounters an error during applying on values. In the case, this returns an `Err` within
943    /// an `Ok` which wraps the actual error.
944    ///
945    /// Note: LLVM is currently unable to effectively vectorize fallible operations
946    pub fn try_unary_mut<F, E>(
947        self,
948        op: F,
949    ) -> Result<Result<PrimitiveArray<T>, E>, PrimitiveArray<T>>
950    where
951        F: Fn(T::Native) -> Result<T::Native, E>,
952    {
953        let len = self.len();
954        let null_count = self.null_count();
955        let mut builder = self.into_builder()?;
956
957        let (slice, null_buffer) = builder.slices_mut();
958
959        let r = try_for_each_valid_idx(len, 0, null_count, null_buffer.as_deref(), |idx| {
960            unsafe { *slice.get_unchecked_mut(idx) = op(*slice.get_unchecked(idx))? };
961            Ok::<_, E>(())
962        });
963
964        if let Err(err) = r {
965            return Ok(Err(err));
966        }
967
968        Ok(Ok(builder.finish()))
969    }
970
971    /// Applies a unary and nullable function to all valid values in a primitive array
972    ///
973    /// Applies `op` to only rows that are valid, which is often significantly
974    /// slower than [`Self::unary`], which should be preferred if `op` is
975    /// fallible.
976    ///
977    /// Note: LLVM is currently unable to effectively vectorize fallible operations
978    pub fn unary_opt<F, O>(&self, op: F) -> PrimitiveArray<O>
979    where
980        O: ArrowPrimitiveType,
981        F: Fn(T::Native) -> Option<O::Native>,
982    {
983        let len = self.len();
984        let (nulls, null_count, offset) = match self.nulls() {
985            Some(n) => (Some(n.validity()), n.null_count(), n.offset()),
986            None => (None, 0, 0),
987        };
988
989        let mut null_builder = BooleanBufferBuilder::new(len);
990        match nulls {
991            Some(b) => null_builder.append_packed_range(offset..offset + len, b),
992            None => null_builder.append_n(len, true),
993        }
994
995        let mut buffer = BufferBuilder::<O::Native>::new(len);
996        buffer.append_n_zeroed(len);
997        let slice = buffer.as_slice_mut();
998
999        let mut out_null_count = null_count;
1000
1001        let _ = try_for_each_valid_idx(len, offset, null_count, nulls, |idx| {
1002            match op(unsafe { self.value_unchecked(idx) }) {
1003                Some(v) => unsafe { *slice.get_unchecked_mut(idx) = v },
1004                None => {
1005                    out_null_count += 1;
1006                    null_builder.set_bit(idx, false);
1007                }
1008            }
1009            Ok::<_, ()>(())
1010        });
1011
1012        let nulls = null_builder.finish();
1013        let values = buffer.finish().into();
1014        let nulls = unsafe { NullBuffer::new_unchecked(nulls, out_null_count) };
1015        PrimitiveArray::new(values, Some(nulls))
1016    }
1017
1018    /// Applies a unary infallible function to each value in an array, producing a
1019    /// new primitive array.
1020    ///
1021    /// # Null Handling
1022    ///
1023    /// See [`Self::unary`] for more information on null handling.
1024    ///
1025    /// # Example: create an [`Int16Array`] from an [`ArrayAccessor`] with item type `&[u8]`
1026    /// ```
1027    /// use arrow_array::{Array, FixedSizeBinaryArray, Int16Array};
1028    /// let input_arg = vec![ vec![1, 0], vec![2, 0], vec![3, 0] ];
1029    /// let arr = FixedSizeBinaryArray::try_from_iter(input_arg.into_iter()).unwrap();
1030    /// let c = Int16Array::from_unary(&arr, |x| i16::from_le_bytes(x[..2].try_into().unwrap()));
1031    /// assert_eq!(c, Int16Array::from(vec![Some(1i16), Some(2i16), Some(3i16)]));
1032    /// ```
1033    pub fn from_unary<U: ArrayAccessor, F>(left: U, mut op: F) -> Self
1034    where
1035        F: FnMut(U::Item) -> T::Native,
1036    {
1037        let nulls = left.logical_nulls();
1038        let buffer = unsafe {
1039            // SAFETY: i in range 0..left.len()
1040            let iter = (0..left.len()).map(|i| op(left.value_unchecked(i)));
1041            // SAFETY: upper bound is trusted because `iter` is over a range
1042            Buffer::from_trusted_len_iter(iter)
1043        };
1044
1045        PrimitiveArray::new(buffer.into(), nulls)
1046    }
1047
1048    /// Returns a `PrimitiveBuilder` for this array, suitable for mutating values
1049    /// in place.
1050    ///
1051    /// # Buffer Reuse
1052    ///
1053    /// If the underlying data buffer has no other outstanding references, the
1054    /// buffer is used without copying.
1055    ///
1056    /// If the underlying data buffer does have outstanding references, returns
1057    /// `Err(self)`
1058    pub fn into_builder(self) -> Result<PrimitiveBuilder<T>, Self> {
1059        let len = self.len();
1060        let data = self.into_data();
1061        let null_bit_buffer = data.nulls().map(|b| b.inner().sliced());
1062
1063        let element_len = std::mem::size_of::<T::Native>();
1064        let buffer =
1065            data.buffers()[0].slice_with_length(data.offset() * element_len, len * element_len);
1066
1067        drop(data);
1068
1069        let try_mutable_null_buffer = match null_bit_buffer {
1070            None => Ok(None),
1071            Some(null_buffer) => {
1072                // Null buffer exists, tries to make it mutable
1073                null_buffer.into_mutable().map(Some)
1074            }
1075        };
1076
1077        let try_mutable_buffers = match try_mutable_null_buffer {
1078            Ok(mutable_null_buffer) => {
1079                // Got mutable null buffer, tries to get mutable value buffer
1080                let try_mutable_buffer = buffer.into_mutable();
1081
1082                // try_mutable_buffer.map(...).map_err(...) doesn't work as the compiler complains
1083                // mutable_null_buffer is moved into map closure.
1084                match try_mutable_buffer {
1085                    Ok(mutable_buffer) => Ok(PrimitiveBuilder::<T>::new_from_buffer(
1086                        mutable_buffer,
1087                        mutable_null_buffer,
1088                    )),
1089                    Err(buffer) => Err((buffer, mutable_null_buffer.map(|b| b.into()))),
1090                }
1091            }
1092            Err(mutable_null_buffer) => {
1093                // Unable to get mutable null buffer
1094                Err((buffer, Some(mutable_null_buffer)))
1095            }
1096        };
1097
1098        match try_mutable_buffers {
1099            Ok(builder) => Ok(builder),
1100            Err((buffer, null_bit_buffer)) => {
1101                let builder = ArrayData::builder(T::DATA_TYPE)
1102                    .len(len)
1103                    .add_buffer(buffer)
1104                    .null_bit_buffer(null_bit_buffer);
1105
1106                let array_data = unsafe { builder.build_unchecked() };
1107                let array = PrimitiveArray::<T>::from(array_data);
1108
1109                Err(array)
1110            }
1111        }
1112    }
1113}
1114
1115impl<T: ArrowPrimitiveType> From<PrimitiveArray<T>> for ArrayData {
1116    fn from(array: PrimitiveArray<T>) -> Self {
1117        let builder = ArrayDataBuilder::new(array.data_type)
1118            .len(array.values.len())
1119            .nulls(array.nulls)
1120            .buffers(vec![array.values.into_inner()]);
1121
1122        unsafe { builder.build_unchecked() }
1123    }
1124}
1125
1126impl<T: ArrowPrimitiveType> Array for PrimitiveArray<T> {
1127    fn as_any(&self) -> &dyn Any {
1128        self
1129    }
1130
1131    fn to_data(&self) -> ArrayData {
1132        self.clone().into()
1133    }
1134
1135    fn into_data(self) -> ArrayData {
1136        self.into()
1137    }
1138
1139    fn data_type(&self) -> &DataType {
1140        &self.data_type
1141    }
1142
1143    fn slice(&self, offset: usize, length: usize) -> ArrayRef {
1144        Arc::new(self.slice(offset, length))
1145    }
1146
1147    fn len(&self) -> usize {
1148        self.values.len()
1149    }
1150
1151    fn is_empty(&self) -> bool {
1152        self.values.is_empty()
1153    }
1154
1155    fn shrink_to_fit(&mut self) {
1156        self.values.shrink_to_fit();
1157        if let Some(nulls) = &mut self.nulls {
1158            nulls.shrink_to_fit();
1159        }
1160    }
1161
1162    fn offset(&self) -> usize {
1163        0
1164    }
1165
1166    fn nulls(&self) -> Option<&NullBuffer> {
1167        self.nulls.as_ref()
1168    }
1169
1170    fn logical_null_count(&self) -> usize {
1171        self.null_count()
1172    }
1173
1174    fn get_buffer_memory_size(&self) -> usize {
1175        let mut size = self.values.inner().capacity();
1176        if let Some(n) = self.nulls.as_ref() {
1177            size += n.buffer().capacity();
1178        }
1179        size
1180    }
1181
1182    fn get_array_memory_size(&self) -> usize {
1183        std::mem::size_of::<Self>() + self.get_buffer_memory_size()
1184    }
1185}
1186
1187impl<T: ArrowPrimitiveType> ArrayAccessor for &PrimitiveArray<T> {
1188    type Item = T::Native;
1189
1190    fn value(&self, index: usize) -> Self::Item {
1191        PrimitiveArray::value(self, index)
1192    }
1193
1194    #[inline]
1195    unsafe fn value_unchecked(&self, index: usize) -> Self::Item {
1196        PrimitiveArray::value_unchecked(self, index)
1197    }
1198}
1199
1200impl<T: ArrowTemporalType> PrimitiveArray<T>
1201where
1202    i64: From<T::Native>,
1203{
1204    /// Returns value as a chrono `NaiveDateTime`, handling time resolution
1205    ///
1206    /// If a data type cannot be converted to `NaiveDateTime`, a `None` is returned.
1207    /// A valid value is expected, thus the user should first check for validity.
1208    pub fn value_as_datetime(&self, i: usize) -> Option<NaiveDateTime> {
1209        as_datetime::<T>(i64::from(self.value(i)))
1210    }
1211
1212    /// Returns value as a chrono `NaiveDateTime`, handling time resolution with the provided tz
1213    ///
1214    /// functionally it is same as `value_as_datetime`, however it adds
1215    /// the passed tz to the to-be-returned NaiveDateTime
1216    pub fn value_as_datetime_with_tz(&self, i: usize, tz: Tz) -> Option<DateTime<Tz>> {
1217        as_datetime_with_timezone::<T>(i64::from(self.value(i)), tz)
1218    }
1219
1220    /// Returns value as a chrono `NaiveDate` by using `Self::datetime()`
1221    ///
1222    /// If a data type cannot be converted to `NaiveDate`, a `None` is returned
1223    pub fn value_as_date(&self, i: usize) -> Option<NaiveDate> {
1224        self.value_as_datetime(i).map(|datetime| datetime.date())
1225    }
1226
1227    /// Returns a value as a chrono `NaiveTime`
1228    ///
1229    /// `Date32` and `Date64` return UTC midnight as they do not have time resolution
1230    pub fn value_as_time(&self, i: usize) -> Option<NaiveTime> {
1231        as_time::<T>(i64::from(self.value(i)))
1232    }
1233
1234    /// Returns a value as a chrono `Duration`
1235    ///
1236    /// If a data type cannot be converted to `Duration`, a `None` is returned
1237    pub fn value_as_duration(&self, i: usize) -> Option<Duration> {
1238        as_duration::<T>(i64::from(self.value(i)))
1239    }
1240}
1241
1242impl<T: ArrowPrimitiveType> std::fmt::Debug for PrimitiveArray<T> {
1243    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
1244        let data_type = self.data_type();
1245
1246        write!(f, "PrimitiveArray<{data_type:?}>\n[\n")?;
1247        print_long_array(self, f, |array, index, f| match data_type {
1248            DataType::Date32 | DataType::Date64 => {
1249                let v = self.value(index).to_i64().unwrap();
1250                match as_date::<T>(v) {
1251                    Some(date) => write!(f, "{date:?}"),
1252                    None => {
1253                        write!(
1254                            f,
1255                            "Cast error: Failed to convert {v} to temporal for {data_type:?}"
1256                        )
1257                    }
1258                }
1259            }
1260            DataType::Time32(_) | DataType::Time64(_) => {
1261                let v = self.value(index).to_i64().unwrap();
1262                match as_time::<T>(v) {
1263                    Some(time) => write!(f, "{time:?}"),
1264                    None => {
1265                        write!(
1266                            f,
1267                            "Cast error: Failed to convert {v} to temporal for {data_type:?}"
1268                        )
1269                    }
1270                }
1271            }
1272            DataType::Timestamp(_, tz_string_opt) => {
1273                let v = self.value(index).to_i64().unwrap();
1274                match tz_string_opt {
1275                    // for Timestamp with TimeZone
1276                    Some(tz_string) => {
1277                        match tz_string.parse::<Tz>() {
1278                            // if the time zone is valid, construct a DateTime<Tz> and format it as rfc3339
1279                            Ok(tz) => match as_datetime_with_timezone::<T>(v, tz) {
1280                                Some(datetime) => write!(f, "{}", datetime.to_rfc3339()),
1281                                None => write!(f, "null"),
1282                            },
1283                            // if the time zone is invalid, shows NaiveDateTime with an error message
1284                            Err(_) => match as_datetime::<T>(v) {
1285                                Some(datetime) => {
1286                                    write!(f, "{datetime:?} (Unknown Time Zone '{tz_string}')")
1287                                }
1288                                None => write!(f, "null"),
1289                            },
1290                        }
1291                    }
1292                    // for Timestamp without TimeZone
1293                    None => match as_datetime::<T>(v) {
1294                        Some(datetime) => write!(f, "{datetime:?}"),
1295                        None => write!(f, "null"),
1296                    },
1297                }
1298            }
1299            _ => std::fmt::Debug::fmt(&array.value(index), f),
1300        })?;
1301        write!(f, "]")
1302    }
1303}
1304
1305impl<'a, T: ArrowPrimitiveType> IntoIterator for &'a PrimitiveArray<T> {
1306    type Item = Option<<T as ArrowPrimitiveType>::Native>;
1307    type IntoIter = PrimitiveIter<'a, T>;
1308
1309    fn into_iter(self) -> Self::IntoIter {
1310        PrimitiveIter::<'a, T>::new(self)
1311    }
1312}
1313
1314impl<'a, T: ArrowPrimitiveType> PrimitiveArray<T> {
1315    /// constructs a new iterator
1316    pub fn iter(&'a self) -> PrimitiveIter<'a, T> {
1317        PrimitiveIter::<'a, T>::new(self)
1318    }
1319}
1320
1321/// An optional primitive value
1322///
1323/// This struct is used as an adapter when creating `PrimitiveArray` from an iterator.
1324/// `FromIterator` for `PrimitiveArray` takes an iterator where the elements can be `into`
1325/// this struct. So once implementing `From` or `Into` trait for a type, an iterator of
1326/// the type can be collected to `PrimitiveArray`.
1327#[derive(Debug)]
1328pub struct NativeAdapter<T: ArrowPrimitiveType> {
1329    /// Corresponding Rust native type if available
1330    pub native: Option<T::Native>,
1331}
1332
1333macro_rules! def_from_for_primitive {
1334    ( $ty:ident, $tt:tt) => {
1335        impl From<$tt> for NativeAdapter<$ty> {
1336            fn from(value: $tt) -> Self {
1337                NativeAdapter {
1338                    native: Some(value),
1339                }
1340            }
1341        }
1342    };
1343}
1344
1345def_from_for_primitive!(Int8Type, i8);
1346def_from_for_primitive!(Int16Type, i16);
1347def_from_for_primitive!(Int32Type, i32);
1348def_from_for_primitive!(Int64Type, i64);
1349def_from_for_primitive!(UInt8Type, u8);
1350def_from_for_primitive!(UInt16Type, u16);
1351def_from_for_primitive!(UInt32Type, u32);
1352def_from_for_primitive!(UInt64Type, u64);
1353def_from_for_primitive!(Float16Type, f16);
1354def_from_for_primitive!(Float32Type, f32);
1355def_from_for_primitive!(Float64Type, f64);
1356def_from_for_primitive!(Decimal128Type, i128);
1357def_from_for_primitive!(Decimal256Type, i256);
1358
1359impl<T: ArrowPrimitiveType> From<Option<<T as ArrowPrimitiveType>::Native>> for NativeAdapter<T> {
1360    fn from(value: Option<<T as ArrowPrimitiveType>::Native>) -> Self {
1361        NativeAdapter { native: value }
1362    }
1363}
1364
1365impl<T: ArrowPrimitiveType> From<&Option<<T as ArrowPrimitiveType>::Native>> for NativeAdapter<T> {
1366    fn from(value: &Option<<T as ArrowPrimitiveType>::Native>) -> Self {
1367        NativeAdapter { native: *value }
1368    }
1369}
1370
1371impl<T: ArrowPrimitiveType, Ptr: Into<NativeAdapter<T>>> FromIterator<Ptr> for PrimitiveArray<T> {
1372    fn from_iter<I: IntoIterator<Item = Ptr>>(iter: I) -> Self {
1373        let iter = iter.into_iter();
1374        let (lower, _) = iter.size_hint();
1375
1376        let mut null_builder = BooleanBufferBuilder::new(lower);
1377
1378        let buffer: Buffer = iter
1379            .map(|item| {
1380                if let Some(a) = item.into().native {
1381                    null_builder.append(true);
1382                    a
1383                } else {
1384                    null_builder.append(false);
1385                    // this ensures that null items on the buffer are not arbitrary.
1386                    // This is important because fallible operations can use null values (e.g. a vectorized "add")
1387                    // which may panic (e.g. overflow if the number on the slots happen to be very large).
1388                    T::Native::default()
1389                }
1390            })
1391            .collect();
1392
1393        let len = null_builder.len();
1394
1395        let data = unsafe {
1396            ArrayData::new_unchecked(
1397                T::DATA_TYPE,
1398                len,
1399                None,
1400                Some(null_builder.into()),
1401                0,
1402                vec![buffer],
1403                vec![],
1404            )
1405        };
1406        PrimitiveArray::from(data)
1407    }
1408}
1409
1410impl<T: ArrowPrimitiveType> PrimitiveArray<T> {
1411    /// Creates a [`PrimitiveArray`] from an iterator of trusted length.
1412    /// # Safety
1413    /// The iterator must be [`TrustedLen`](https://doc.rust-lang.org/std/iter/trait.TrustedLen.html).
1414    /// I.e. that `size_hint().1` correctly reports its length.
1415    #[inline]
1416    pub unsafe fn from_trusted_len_iter<I, P>(iter: I) -> Self
1417    where
1418        P: std::borrow::Borrow<Option<<T as ArrowPrimitiveType>::Native>>,
1419        I: IntoIterator<Item = P>,
1420    {
1421        let iterator = iter.into_iter();
1422        let (_, upper) = iterator.size_hint();
1423        let len = upper.expect("trusted_len_unzip requires an upper limit");
1424
1425        let (null, buffer) = trusted_len_unzip(iterator);
1426
1427        let data =
1428            ArrayData::new_unchecked(T::DATA_TYPE, len, None, Some(null), 0, vec![buffer], vec![]);
1429        PrimitiveArray::from(data)
1430    }
1431}
1432
1433// TODO: the macro is needed here because we'd get "conflicting implementations" error
1434// otherwise with both `From<Vec<T::Native>>` and `From<Vec<Option<T::Native>>>`.
1435// We should revisit this in future.
1436macro_rules! def_numeric_from_vec {
1437    ( $ty:ident ) => {
1438        impl From<Vec<<$ty as ArrowPrimitiveType>::Native>> for PrimitiveArray<$ty> {
1439            fn from(data: Vec<<$ty as ArrowPrimitiveType>::Native>) -> Self {
1440                let array_data = ArrayData::builder($ty::DATA_TYPE)
1441                    .len(data.len())
1442                    .add_buffer(Buffer::from_vec(data));
1443                let array_data = unsafe { array_data.build_unchecked() };
1444                PrimitiveArray::from(array_data)
1445            }
1446        }
1447
1448        // Constructs a primitive array from a vector. Should only be used for testing.
1449        impl From<Vec<Option<<$ty as ArrowPrimitiveType>::Native>>> for PrimitiveArray<$ty> {
1450            fn from(data: Vec<Option<<$ty as ArrowPrimitiveType>::Native>>) -> Self {
1451                PrimitiveArray::from_iter(data.iter())
1452            }
1453        }
1454    };
1455}
1456
1457def_numeric_from_vec!(Int8Type);
1458def_numeric_from_vec!(Int16Type);
1459def_numeric_from_vec!(Int32Type);
1460def_numeric_from_vec!(Int64Type);
1461def_numeric_from_vec!(UInt8Type);
1462def_numeric_from_vec!(UInt16Type);
1463def_numeric_from_vec!(UInt32Type);
1464def_numeric_from_vec!(UInt64Type);
1465def_numeric_from_vec!(Float16Type);
1466def_numeric_from_vec!(Float32Type);
1467def_numeric_from_vec!(Float64Type);
1468def_numeric_from_vec!(Decimal128Type);
1469def_numeric_from_vec!(Decimal256Type);
1470
1471def_numeric_from_vec!(Date32Type);
1472def_numeric_from_vec!(Date64Type);
1473def_numeric_from_vec!(Time32SecondType);
1474def_numeric_from_vec!(Time32MillisecondType);
1475def_numeric_from_vec!(Time64MicrosecondType);
1476def_numeric_from_vec!(Time64NanosecondType);
1477def_numeric_from_vec!(IntervalYearMonthType);
1478def_numeric_from_vec!(IntervalDayTimeType);
1479def_numeric_from_vec!(IntervalMonthDayNanoType);
1480def_numeric_from_vec!(DurationSecondType);
1481def_numeric_from_vec!(DurationMillisecondType);
1482def_numeric_from_vec!(DurationMicrosecondType);
1483def_numeric_from_vec!(DurationNanosecondType);
1484def_numeric_from_vec!(TimestampSecondType);
1485def_numeric_from_vec!(TimestampMillisecondType);
1486def_numeric_from_vec!(TimestampMicrosecondType);
1487def_numeric_from_vec!(TimestampNanosecondType);
1488
1489impl<T: ArrowTimestampType> PrimitiveArray<T> {
1490    /// Construct a timestamp array from a vec of i64 values and an optional timezone
1491    #[deprecated(note = "Use with_timezone_opt instead")]
1492    pub fn from_vec(data: Vec<i64>, timezone: Option<String>) -> Self
1493    where
1494        Self: From<Vec<i64>>,
1495    {
1496        Self::from(data).with_timezone_opt(timezone)
1497    }
1498
1499    /// Construct a timestamp array from a vec of `Option<i64>` values and an optional timezone
1500    #[deprecated(note = "Use with_timezone_opt instead")]
1501    pub fn from_opt_vec(data: Vec<Option<i64>>, timezone: Option<String>) -> Self
1502    where
1503        Self: From<Vec<Option<i64>>>,
1504    {
1505        Self::from(data).with_timezone_opt(timezone)
1506    }
1507
1508    /// Returns the timezone of this array if any
1509    pub fn timezone(&self) -> Option<&str> {
1510        match self.data_type() {
1511            DataType::Timestamp(_, tz) => tz.as_deref(),
1512            _ => unreachable!(),
1513        }
1514    }
1515
1516    /// Construct a timestamp array with new timezone
1517    pub fn with_timezone(self, timezone: impl Into<Arc<str>>) -> Self {
1518        self.with_timezone_opt(Some(timezone.into()))
1519    }
1520
1521    /// Construct a timestamp array with UTC
1522    pub fn with_timezone_utc(self) -> Self {
1523        self.with_timezone("+00:00")
1524    }
1525
1526    /// Construct a timestamp array with an optional timezone
1527    pub fn with_timezone_opt<S: Into<Arc<str>>>(self, timezone: Option<S>) -> Self {
1528        Self {
1529            data_type: DataType::Timestamp(T::UNIT, timezone.map(Into::into)),
1530            ..self
1531        }
1532    }
1533}
1534
1535/// Constructs a `PrimitiveArray` from an array data reference.
1536impl<T: ArrowPrimitiveType> From<ArrayData> for PrimitiveArray<T> {
1537    fn from(data: ArrayData) -> Self {
1538        Self::assert_compatible(data.data_type());
1539        assert_eq!(
1540            data.buffers().len(),
1541            1,
1542            "PrimitiveArray data should contain a single buffer only (values buffer)"
1543        );
1544
1545        let values = ScalarBuffer::new(data.buffers()[0].clone(), data.offset(), data.len());
1546        Self {
1547            data_type: data.data_type().clone(),
1548            values,
1549            nulls: data.nulls().cloned(),
1550        }
1551    }
1552}
1553
1554impl<T: DecimalType + ArrowPrimitiveType> PrimitiveArray<T> {
1555    /// Returns a Decimal array with the same data as self, with the
1556    /// specified precision and scale.
1557    ///
1558    /// See [`validate_decimal_precision_and_scale`]
1559    pub fn with_precision_and_scale(self, precision: u8, scale: i8) -> Result<Self, ArrowError> {
1560        validate_decimal_precision_and_scale::<T>(precision, scale)?;
1561        Ok(Self {
1562            data_type: T::TYPE_CONSTRUCTOR(precision, scale),
1563            ..self
1564        })
1565    }
1566
1567    /// Validates values in this array can be properly interpreted
1568    /// with the specified precision.
1569    pub fn validate_decimal_precision(&self, precision: u8) -> Result<(), ArrowError> {
1570        (0..self.len()).try_for_each(|idx| {
1571            if self.is_valid(idx) {
1572                let decimal = unsafe { self.value_unchecked(idx) };
1573                T::validate_decimal_precision(decimal, precision)
1574            } else {
1575                Ok(())
1576            }
1577        })
1578    }
1579
1580    /// Validates the Decimal Array, if the value of slot is overflow for the specified precision, and
1581    /// will be casted to Null
1582    pub fn null_if_overflow_precision(&self, precision: u8) -> Self {
1583        self.unary_opt::<_, T>(|v| T::is_valid_decimal_precision(v, precision).then_some(v))
1584    }
1585
1586    /// Returns [`Self::value`] formatted as a string
1587    pub fn value_as_string(&self, row: usize) -> String {
1588        T::format_decimal(self.value(row), self.precision(), self.scale())
1589    }
1590
1591    /// Returns the decimal precision of this array
1592    pub fn precision(&self) -> u8 {
1593        match T::BYTE_LENGTH {
1594            16 => {
1595                if let DataType::Decimal128(p, _) = self.data_type() {
1596                    *p
1597                } else {
1598                    unreachable!(
1599                        "Decimal128Array datatype is not DataType::Decimal128 but {}",
1600                        self.data_type()
1601                    )
1602                }
1603            }
1604            32 => {
1605                if let DataType::Decimal256(p, _) = self.data_type() {
1606                    *p
1607                } else {
1608                    unreachable!(
1609                        "Decimal256Array datatype is not DataType::Decimal256 but {}",
1610                        self.data_type()
1611                    )
1612                }
1613            }
1614            other => unreachable!("Unsupported byte length for decimal array {}", other),
1615        }
1616    }
1617
1618    /// Returns the decimal scale of this array
1619    pub fn scale(&self) -> i8 {
1620        match T::BYTE_LENGTH {
1621            16 => {
1622                if let DataType::Decimal128(_, s) = self.data_type() {
1623                    *s
1624                } else {
1625                    unreachable!(
1626                        "Decimal128Array datatype is not DataType::Decimal128 but {}",
1627                        self.data_type()
1628                    )
1629                }
1630            }
1631            32 => {
1632                if let DataType::Decimal256(_, s) = self.data_type() {
1633                    *s
1634                } else {
1635                    unreachable!(
1636                        "Decimal256Array datatype is not DataType::Decimal256 but {}",
1637                        self.data_type()
1638                    )
1639                }
1640            }
1641            other => unreachable!("Unsupported byte length for decimal array {}", other),
1642        }
1643    }
1644}
1645
1646#[cfg(test)]
1647mod tests {
1648    use super::*;
1649    use crate::builder::{Decimal128Builder, Decimal256Builder};
1650    use crate::cast::downcast_array;
1651    use crate::BooleanArray;
1652    use arrow_buffer::{IntervalDayTime, IntervalMonthDayNano};
1653    use arrow_schema::TimeUnit;
1654
1655    #[test]
1656    fn test_primitive_array_from_vec() {
1657        let buf = Buffer::from_slice_ref([0, 1, 2, 3, 4]);
1658        let arr = Int32Array::from(vec![0, 1, 2, 3, 4]);
1659        assert_eq!(&buf, arr.values.inner());
1660        assert_eq!(5, arr.len());
1661        assert_eq!(0, arr.offset());
1662        assert_eq!(0, arr.null_count());
1663        for i in 0..5 {
1664            assert!(!arr.is_null(i));
1665            assert!(arr.is_valid(i));
1666            assert_eq!(i as i32, arr.value(i));
1667        }
1668    }
1669
1670    #[test]
1671    fn test_primitive_array_from_vec_option() {
1672        // Test building a primitive array with null values
1673        let arr = Int32Array::from(vec![Some(0), None, Some(2), None, Some(4)]);
1674        assert_eq!(5, arr.len());
1675        assert_eq!(0, arr.offset());
1676        assert_eq!(2, arr.null_count());
1677        for i in 0..5 {
1678            if i % 2 == 0 {
1679                assert!(!arr.is_null(i));
1680                assert!(arr.is_valid(i));
1681                assert_eq!(i as i32, arr.value(i));
1682            } else {
1683                assert!(arr.is_null(i));
1684                assert!(!arr.is_valid(i));
1685            }
1686        }
1687    }
1688
1689    #[test]
1690    fn test_date64_array_from_vec_option() {
1691        // Test building a primitive array with null values
1692        // we use Int32 and Int64 as a backing array, so all Int32 and Int64 conventions
1693        // work
1694        let arr: PrimitiveArray<Date64Type> =
1695            vec![Some(1550902545147), None, Some(1550902545147)].into();
1696        assert_eq!(3, arr.len());
1697        assert_eq!(0, arr.offset());
1698        assert_eq!(1, arr.null_count());
1699        for i in 0..3 {
1700            if i % 2 == 0 {
1701                assert!(!arr.is_null(i));
1702                assert!(arr.is_valid(i));
1703                assert_eq!(1550902545147, arr.value(i));
1704                // roundtrip to and from datetime
1705                assert_eq!(
1706                    1550902545147,
1707                    arr.value_as_datetime(i)
1708                        .unwrap()
1709                        .and_utc()
1710                        .timestamp_millis()
1711                );
1712            } else {
1713                assert!(arr.is_null(i));
1714                assert!(!arr.is_valid(i));
1715            }
1716        }
1717    }
1718
1719    #[test]
1720    fn test_time32_millisecond_array_from_vec() {
1721        // 1:        00:00:00.001
1722        // 37800005: 10:30:00.005
1723        // 86399210: 23:59:59.210
1724        let arr: PrimitiveArray<Time32MillisecondType> = vec![1, 37_800_005, 86_399_210].into();
1725        assert_eq!(3, arr.len());
1726        assert_eq!(0, arr.offset());
1727        assert_eq!(0, arr.null_count());
1728        let formatted = ["00:00:00.001", "10:30:00.005", "23:59:59.210"];
1729        for (i, formatted) in formatted.iter().enumerate().take(3) {
1730            // check that we can't create dates or datetimes from time instances
1731            assert_eq!(None, arr.value_as_datetime(i));
1732            assert_eq!(None, arr.value_as_date(i));
1733            let time = arr.value_as_time(i).unwrap();
1734            assert_eq!(*formatted, time.format("%H:%M:%S%.3f").to_string());
1735        }
1736    }
1737
1738    #[test]
1739    fn test_time64_nanosecond_array_from_vec() {
1740        // Test building a primitive array with null values
1741        // we use Int32 and Int64 as a backing array, so all Int32 and Int64 conventions
1742        // work
1743
1744        // 1e6:        00:00:00.001
1745        // 37800005e6: 10:30:00.005
1746        // 86399210e6: 23:59:59.210
1747        let arr: PrimitiveArray<Time64NanosecondType> =
1748            vec![1_000_000, 37_800_005_000_000, 86_399_210_000_000].into();
1749        assert_eq!(3, arr.len());
1750        assert_eq!(0, arr.offset());
1751        assert_eq!(0, arr.null_count());
1752        let formatted = ["00:00:00.001", "10:30:00.005", "23:59:59.210"];
1753        for (i, item) in formatted.iter().enumerate().take(3) {
1754            // check that we can't create dates or datetimes from time instances
1755            assert_eq!(None, arr.value_as_datetime(i));
1756            assert_eq!(None, arr.value_as_date(i));
1757            let time = arr.value_as_time(i).unwrap();
1758            assert_eq!(*item, time.format("%H:%M:%S%.3f").to_string());
1759        }
1760    }
1761
1762    #[test]
1763    fn test_interval_array_from_vec() {
1764        // intervals are currently not treated specially, but are Int32 and Int64 arrays
1765        let arr = IntervalYearMonthArray::from(vec![Some(1), None, Some(-5)]);
1766        assert_eq!(3, arr.len());
1767        assert_eq!(0, arr.offset());
1768        assert_eq!(1, arr.null_count());
1769        assert_eq!(1, arr.value(0));
1770        assert_eq!(1, arr.values()[0]);
1771        assert!(arr.is_null(1));
1772        assert_eq!(-5, arr.value(2));
1773        assert_eq!(-5, arr.values()[2]);
1774
1775        let v0 = IntervalDayTime {
1776            days: 34,
1777            milliseconds: 1,
1778        };
1779        let v2 = IntervalDayTime {
1780            days: -2,
1781            milliseconds: -5,
1782        };
1783
1784        let arr = IntervalDayTimeArray::from(vec![Some(v0), None, Some(v2)]);
1785
1786        assert_eq!(3, arr.len());
1787        assert_eq!(0, arr.offset());
1788        assert_eq!(1, arr.null_count());
1789        assert_eq!(v0, arr.value(0));
1790        assert_eq!(v0, arr.values()[0]);
1791        assert!(arr.is_null(1));
1792        assert_eq!(v2, arr.value(2));
1793        assert_eq!(v2, arr.values()[2]);
1794
1795        let v0 = IntervalMonthDayNano {
1796            months: 2,
1797            days: 34,
1798            nanoseconds: -1,
1799        };
1800        let v2 = IntervalMonthDayNano {
1801            months: -3,
1802            days: -2,
1803            nanoseconds: 4,
1804        };
1805
1806        let arr = IntervalMonthDayNanoArray::from(vec![Some(v0), None, Some(v2)]);
1807        assert_eq!(3, arr.len());
1808        assert_eq!(0, arr.offset());
1809        assert_eq!(1, arr.null_count());
1810        assert_eq!(v0, arr.value(0));
1811        assert_eq!(v0, arr.values()[0]);
1812        assert!(arr.is_null(1));
1813        assert_eq!(v2, arr.value(2));
1814        assert_eq!(v2, arr.values()[2]);
1815    }
1816
1817    #[test]
1818    fn test_duration_array_from_vec() {
1819        let arr = DurationSecondArray::from(vec![Some(1), None, Some(-5)]);
1820        assert_eq!(3, arr.len());
1821        assert_eq!(0, arr.offset());
1822        assert_eq!(1, arr.null_count());
1823        assert_eq!(1, arr.value(0));
1824        assert_eq!(1, arr.values()[0]);
1825        assert!(arr.is_null(1));
1826        assert_eq!(-5, arr.value(2));
1827        assert_eq!(-5, arr.values()[2]);
1828
1829        let arr = DurationMillisecondArray::from(vec![Some(1), None, Some(-5)]);
1830        assert_eq!(3, arr.len());
1831        assert_eq!(0, arr.offset());
1832        assert_eq!(1, arr.null_count());
1833        assert_eq!(1, arr.value(0));
1834        assert_eq!(1, arr.values()[0]);
1835        assert!(arr.is_null(1));
1836        assert_eq!(-5, arr.value(2));
1837        assert_eq!(-5, arr.values()[2]);
1838
1839        let arr = DurationMicrosecondArray::from(vec![Some(1), None, Some(-5)]);
1840        assert_eq!(3, arr.len());
1841        assert_eq!(0, arr.offset());
1842        assert_eq!(1, arr.null_count());
1843        assert_eq!(1, arr.value(0));
1844        assert_eq!(1, arr.values()[0]);
1845        assert!(arr.is_null(1));
1846        assert_eq!(-5, arr.value(2));
1847        assert_eq!(-5, arr.values()[2]);
1848
1849        let arr = DurationNanosecondArray::from(vec![Some(1), None, Some(-5)]);
1850        assert_eq!(3, arr.len());
1851        assert_eq!(0, arr.offset());
1852        assert_eq!(1, arr.null_count());
1853        assert_eq!(1, arr.value(0));
1854        assert_eq!(1, arr.values()[0]);
1855        assert!(arr.is_null(1));
1856        assert_eq!(-5, arr.value(2));
1857        assert_eq!(-5, arr.values()[2]);
1858    }
1859
1860    #[test]
1861    fn test_timestamp_array_from_vec() {
1862        let arr = TimestampSecondArray::from(vec![1, -5]);
1863        assert_eq!(2, arr.len());
1864        assert_eq!(0, arr.offset());
1865        assert_eq!(0, arr.null_count());
1866        assert_eq!(1, arr.value(0));
1867        assert_eq!(-5, arr.value(1));
1868        assert_eq!(&[1, -5], arr.values());
1869
1870        let arr = TimestampMillisecondArray::from(vec![1, -5]);
1871        assert_eq!(2, arr.len());
1872        assert_eq!(0, arr.offset());
1873        assert_eq!(0, arr.null_count());
1874        assert_eq!(1, arr.value(0));
1875        assert_eq!(-5, arr.value(1));
1876        assert_eq!(&[1, -5], arr.values());
1877
1878        let arr = TimestampMicrosecondArray::from(vec![1, -5]);
1879        assert_eq!(2, arr.len());
1880        assert_eq!(0, arr.offset());
1881        assert_eq!(0, arr.null_count());
1882        assert_eq!(1, arr.value(0));
1883        assert_eq!(-5, arr.value(1));
1884        assert_eq!(&[1, -5], arr.values());
1885
1886        let arr = TimestampNanosecondArray::from(vec![1, -5]);
1887        assert_eq!(2, arr.len());
1888        assert_eq!(0, arr.offset());
1889        assert_eq!(0, arr.null_count());
1890        assert_eq!(1, arr.value(0));
1891        assert_eq!(-5, arr.value(1));
1892        assert_eq!(&[1, -5], arr.values());
1893    }
1894
1895    #[test]
1896    fn test_primitive_array_slice() {
1897        let arr = Int32Array::from(vec![
1898            Some(0),
1899            None,
1900            Some(2),
1901            None,
1902            Some(4),
1903            Some(5),
1904            Some(6),
1905            None,
1906            None,
1907        ]);
1908        assert_eq!(9, arr.len());
1909        assert_eq!(0, arr.offset());
1910        assert_eq!(4, arr.null_count());
1911
1912        let arr2 = arr.slice(2, 5);
1913        assert_eq!(5, arr2.len());
1914        assert_eq!(1, arr2.null_count());
1915
1916        for i in 0..arr2.len() {
1917            assert_eq!(i == 1, arr2.is_null(i));
1918            assert_eq!(i != 1, arr2.is_valid(i));
1919        }
1920        let int_arr2 = arr2.as_any().downcast_ref::<Int32Array>().unwrap();
1921        assert_eq!(2, int_arr2.values()[0]);
1922        assert_eq!(&[4, 5, 6], &int_arr2.values()[2..5]);
1923
1924        let arr3 = arr2.slice(2, 3);
1925        assert_eq!(3, arr3.len());
1926        assert_eq!(0, arr3.null_count());
1927
1928        let int_arr3 = arr3.as_any().downcast_ref::<Int32Array>().unwrap();
1929        assert_eq!(&[4, 5, 6], int_arr3.values());
1930        assert_eq!(4, int_arr3.value(0));
1931        assert_eq!(5, int_arr3.value(1));
1932        assert_eq!(6, int_arr3.value(2));
1933    }
1934
1935    #[test]
1936    fn test_boolean_array_slice() {
1937        let arr = BooleanArray::from(vec![
1938            Some(true),
1939            None,
1940            Some(false),
1941            None,
1942            Some(true),
1943            Some(false),
1944            Some(true),
1945            Some(false),
1946            None,
1947            Some(true),
1948        ]);
1949
1950        assert_eq!(10, arr.len());
1951        assert_eq!(0, arr.offset());
1952        assert_eq!(3, arr.null_count());
1953
1954        let arr2 = arr.slice(3, 5);
1955        assert_eq!(5, arr2.len());
1956        assert_eq!(3, arr2.offset());
1957        assert_eq!(1, arr2.null_count());
1958
1959        let bool_arr = arr2.as_any().downcast_ref::<BooleanArray>().unwrap();
1960
1961        assert!(!bool_arr.is_valid(0));
1962
1963        assert!(bool_arr.is_valid(1));
1964        assert!(bool_arr.value(1));
1965
1966        assert!(bool_arr.is_valid(2));
1967        assert!(!bool_arr.value(2));
1968
1969        assert!(bool_arr.is_valid(3));
1970        assert!(bool_arr.value(3));
1971
1972        assert!(bool_arr.is_valid(4));
1973        assert!(!bool_arr.value(4));
1974    }
1975
1976    #[test]
1977    fn test_int32_fmt_debug() {
1978        let arr = Int32Array::from(vec![0, 1, 2, 3, 4]);
1979        assert_eq!(
1980            "PrimitiveArray<Int32>\n[\n  0,\n  1,\n  2,\n  3,\n  4,\n]",
1981            format!("{arr:?}")
1982        );
1983    }
1984
1985    #[test]
1986    fn test_fmt_debug_up_to_20_elements() {
1987        (1..=20).for_each(|i| {
1988            let values = (0..i).collect::<Vec<i16>>();
1989            let array_expected = format!(
1990                "PrimitiveArray<Int16>\n[\n{}\n]",
1991                values
1992                    .iter()
1993                    .map(|v| { format!("  {v},") })
1994                    .collect::<Vec<String>>()
1995                    .join("\n")
1996            );
1997            let array = Int16Array::from(values);
1998
1999            assert_eq!(array_expected, format!("{array:?}"));
2000        })
2001    }
2002
2003    #[test]
2004    fn test_int32_with_null_fmt_debug() {
2005        let mut builder = Int32Array::builder(3);
2006        builder.append_slice(&[0, 1]);
2007        builder.append_null();
2008        builder.append_slice(&[3, 4]);
2009        let arr = builder.finish();
2010        assert_eq!(
2011            "PrimitiveArray<Int32>\n[\n  0,\n  1,\n  null,\n  3,\n  4,\n]",
2012            format!("{arr:?}")
2013        );
2014    }
2015
2016    #[test]
2017    fn test_timestamp_fmt_debug() {
2018        let arr: PrimitiveArray<TimestampMillisecondType> =
2019            TimestampMillisecondArray::from(vec![1546214400000, 1546214400000, -1546214400000]);
2020        assert_eq!(
2021            "PrimitiveArray<Timestamp(Millisecond, None)>\n[\n  2018-12-31T00:00:00,\n  2018-12-31T00:00:00,\n  1921-01-02T00:00:00,\n]",
2022            format!("{arr:?}")
2023        );
2024    }
2025
2026    #[test]
2027    fn test_timestamp_utc_fmt_debug() {
2028        let arr: PrimitiveArray<TimestampMillisecondType> =
2029            TimestampMillisecondArray::from(vec![1546214400000, 1546214400000, -1546214400000])
2030                .with_timezone_utc();
2031        assert_eq!(
2032            "PrimitiveArray<Timestamp(Millisecond, Some(\"+00:00\"))>\n[\n  2018-12-31T00:00:00+00:00,\n  2018-12-31T00:00:00+00:00,\n  1921-01-02T00:00:00+00:00,\n]",
2033            format!("{arr:?}")
2034        );
2035    }
2036
2037    #[test]
2038    #[cfg(feature = "chrono-tz")]
2039    fn test_timestamp_with_named_tz_fmt_debug() {
2040        let arr: PrimitiveArray<TimestampMillisecondType> =
2041            TimestampMillisecondArray::from(vec![1546214400000, 1546214400000, -1546214400000])
2042                .with_timezone("Asia/Taipei".to_string());
2043        assert_eq!(
2044            "PrimitiveArray<Timestamp(Millisecond, Some(\"Asia/Taipei\"))>\n[\n  2018-12-31T08:00:00+08:00,\n  2018-12-31T08:00:00+08:00,\n  1921-01-02T08:00:00+08:00,\n]",
2045            format!("{:?}", arr)
2046        );
2047    }
2048
2049    #[test]
2050    #[cfg(not(feature = "chrono-tz"))]
2051    fn test_timestamp_with_named_tz_fmt_debug() {
2052        let arr: PrimitiveArray<TimestampMillisecondType> =
2053            TimestampMillisecondArray::from(vec![1546214400000, 1546214400000, -1546214400000])
2054                .with_timezone("Asia/Taipei".to_string());
2055
2056        println!("{arr:?}");
2057
2058        assert_eq!(
2059            "PrimitiveArray<Timestamp(Millisecond, Some(\"Asia/Taipei\"))>\n[\n  2018-12-31T00:00:00 (Unknown Time Zone 'Asia/Taipei'),\n  2018-12-31T00:00:00 (Unknown Time Zone 'Asia/Taipei'),\n  1921-01-02T00:00:00 (Unknown Time Zone 'Asia/Taipei'),\n]",
2060            format!("{arr:?}")
2061        );
2062    }
2063
2064    #[test]
2065    fn test_timestamp_with_fixed_offset_tz_fmt_debug() {
2066        let arr: PrimitiveArray<TimestampMillisecondType> =
2067            TimestampMillisecondArray::from(vec![1546214400000, 1546214400000, -1546214400000])
2068                .with_timezone("+08:00".to_string());
2069        assert_eq!(
2070            "PrimitiveArray<Timestamp(Millisecond, Some(\"+08:00\"))>\n[\n  2018-12-31T08:00:00+08:00,\n  2018-12-31T08:00:00+08:00,\n  1921-01-02T08:00:00+08:00,\n]",
2071            format!("{arr:?}")
2072        );
2073    }
2074
2075    #[test]
2076    fn test_timestamp_with_incorrect_tz_fmt_debug() {
2077        let arr: PrimitiveArray<TimestampMillisecondType> =
2078            TimestampMillisecondArray::from(vec![1546214400000, 1546214400000, -1546214400000])
2079                .with_timezone("xxx".to_string());
2080        assert_eq!(
2081            "PrimitiveArray<Timestamp(Millisecond, Some(\"xxx\"))>\n[\n  2018-12-31T00:00:00 (Unknown Time Zone 'xxx'),\n  2018-12-31T00:00:00 (Unknown Time Zone 'xxx'),\n  1921-01-02T00:00:00 (Unknown Time Zone 'xxx'),\n]",
2082            format!("{arr:?}")
2083        );
2084    }
2085
2086    #[test]
2087    #[cfg(feature = "chrono-tz")]
2088    fn test_timestamp_with_tz_with_daylight_saving_fmt_debug() {
2089        let arr: PrimitiveArray<TimestampMillisecondType> = TimestampMillisecondArray::from(vec![
2090            1647161999000,
2091            1647162000000,
2092            1667717999000,
2093            1667718000000,
2094        ])
2095        .with_timezone("America/Denver".to_string());
2096        assert_eq!(
2097            "PrimitiveArray<Timestamp(Millisecond, Some(\"America/Denver\"))>\n[\n  2022-03-13T01:59:59-07:00,\n  2022-03-13T03:00:00-06:00,\n  2022-11-06T00:59:59-06:00,\n  2022-11-06T01:00:00-06:00,\n]",
2098            format!("{:?}", arr)
2099        );
2100    }
2101
2102    #[test]
2103    fn test_date32_fmt_debug() {
2104        let arr: PrimitiveArray<Date32Type> = vec![12356, 13548, -365].into();
2105        assert_eq!(
2106            "PrimitiveArray<Date32>\n[\n  2003-10-31,\n  2007-02-04,\n  1969-01-01,\n]",
2107            format!("{arr:?}")
2108        );
2109    }
2110
2111    #[test]
2112    fn test_time32second_fmt_debug() {
2113        let arr: PrimitiveArray<Time32SecondType> = vec![7201, 60054].into();
2114        assert_eq!(
2115            "PrimitiveArray<Time32(Second)>\n[\n  02:00:01,\n  16:40:54,\n]",
2116            format!("{arr:?}")
2117        );
2118    }
2119
2120    #[test]
2121    fn test_time32second_invalid_neg() {
2122        // chrono::NaiveDatetime::from_timestamp_opt returns None while input is invalid
2123        let arr: PrimitiveArray<Time32SecondType> = vec![-7201, -60054].into();
2124        assert_eq!(
2125        "PrimitiveArray<Time32(Second)>\n[\n  Cast error: Failed to convert -7201 to temporal for Time32(Second),\n  Cast error: Failed to convert -60054 to temporal for Time32(Second),\n]",
2126            // "PrimitiveArray<Time32(Second)>\n[\n  null,\n  null,\n]",
2127            format!("{arr:?}")
2128        )
2129    }
2130
2131    #[test]
2132    fn test_timestamp_micros_out_of_range() {
2133        // replicate the issue from https://github.com/apache/arrow-datafusion/issues/3832
2134        let arr: PrimitiveArray<TimestampMicrosecondType> = vec![9065525203050843594].into();
2135        assert_eq!(
2136            "PrimitiveArray<Timestamp(Microsecond, None)>\n[\n  null,\n]",
2137            format!("{arr:?}")
2138        )
2139    }
2140
2141    #[test]
2142    fn test_primitive_array_builder() {
2143        // Test building a primitive array with ArrayData builder and offset
2144        let buf = Buffer::from_slice_ref([0i32, 1, 2, 3, 4, 5, 6]);
2145        let buf2 = buf.slice_with_length(8, 20);
2146        let data = ArrayData::builder(DataType::Int32)
2147            .len(5)
2148            .offset(2)
2149            .add_buffer(buf)
2150            .build()
2151            .unwrap();
2152        let arr = Int32Array::from(data);
2153        assert_eq!(&buf2, arr.values.inner());
2154        assert_eq!(5, arr.len());
2155        assert_eq!(0, arr.null_count());
2156        for i in 0..3 {
2157            assert_eq!((i + 2) as i32, arr.value(i));
2158        }
2159    }
2160
2161    #[test]
2162    fn test_primitive_from_iter_values() {
2163        // Test building a primitive array with from_iter_values
2164        let arr: PrimitiveArray<Int32Type> = PrimitiveArray::from_iter_values(0..10);
2165        assert_eq!(10, arr.len());
2166        assert_eq!(0, arr.null_count());
2167        for i in 0..10i32 {
2168            assert_eq!(i, arr.value(i as usize));
2169        }
2170    }
2171
2172    #[test]
2173    fn test_primitive_array_from_unbound_iter() {
2174        // iterator that doesn't declare (upper) size bound
2175        let value_iter = (0..)
2176            .scan(0usize, |pos, i| {
2177                if *pos < 10 {
2178                    *pos += 1;
2179                    Some(Some(i))
2180                } else {
2181                    // actually returns up to 10 values
2182                    None
2183                }
2184            })
2185            // limited using take()
2186            .take(100);
2187
2188        let (_, upper_size_bound) = value_iter.size_hint();
2189        // the upper bound, defined by take above, is 100
2190        assert_eq!(upper_size_bound, Some(100));
2191        let primitive_array: PrimitiveArray<Int32Type> = value_iter.collect();
2192        // but the actual number of items in the array should be 10
2193        assert_eq!(primitive_array.len(), 10);
2194    }
2195
2196    #[test]
2197    fn test_primitive_array_from_non_null_iter() {
2198        let iter = (0..10_i32).map(Some);
2199        let primitive_array = PrimitiveArray::<Int32Type>::from_iter(iter);
2200        assert_eq!(primitive_array.len(), 10);
2201        assert_eq!(primitive_array.null_count(), 0);
2202        assert!(primitive_array.nulls().is_none());
2203        assert_eq!(primitive_array.values(), &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
2204    }
2205
2206    #[test]
2207    #[should_panic(expected = "PrimitiveArray data should contain a single buffer only \
2208                               (values buffer)")]
2209    // Different error messages, so skip for now
2210    // https://github.com/apache/arrow-rs/issues/1545
2211    #[cfg(not(feature = "force_validate"))]
2212    fn test_primitive_array_invalid_buffer_len() {
2213        let buffer = Buffer::from_slice_ref([0i32, 1, 2, 3, 4]);
2214        let data = unsafe {
2215            ArrayData::builder(DataType::Int32)
2216                .add_buffer(buffer.clone())
2217                .add_buffer(buffer)
2218                .len(5)
2219                .build_unchecked()
2220        };
2221
2222        drop(Int32Array::from(data));
2223    }
2224
2225    #[test]
2226    fn test_access_array_concurrently() {
2227        let a = Int32Array::from(vec![5, 6, 7, 8, 9]);
2228        let ret = std::thread::spawn(move || a.value(3)).join();
2229
2230        assert!(ret.is_ok());
2231        assert_eq!(8, ret.ok().unwrap());
2232    }
2233
2234    #[test]
2235    fn test_primitive_array_creation() {
2236        let array1: Int8Array = [10_i8, 11, 12, 13, 14].into_iter().collect();
2237        let array2: Int8Array = [10_i8, 11, 12, 13, 14].into_iter().map(Some).collect();
2238
2239        assert_eq!(array1, array2);
2240    }
2241
2242    #[test]
2243    #[should_panic(
2244        expected = "Trying to access an element at index 4 from a PrimitiveArray of length 3"
2245    )]
2246    fn test_string_array_get_value_index_out_of_bound() {
2247        let array: Int8Array = [10_i8, 11, 12].into_iter().collect();
2248
2249        array.value(4);
2250    }
2251
2252    #[test]
2253    #[should_panic(expected = "PrimitiveArray expected data type Int64 got Int32")]
2254    fn test_from_array_data_validation() {
2255        let foo = PrimitiveArray::<Int32Type>::from_iter([1, 2, 3]);
2256        let _ = PrimitiveArray::<Int64Type>::from(foo.into_data());
2257    }
2258
2259    #[test]
2260    fn test_decimal128() {
2261        let values: Vec<_> = vec![0, 1, -1, i128::MIN, i128::MAX];
2262        let array: PrimitiveArray<Decimal128Type> =
2263            PrimitiveArray::from_iter(values.iter().copied());
2264        assert_eq!(array.values(), &values);
2265
2266        let array: PrimitiveArray<Decimal128Type> =
2267            PrimitiveArray::from_iter_values(values.iter().copied());
2268        assert_eq!(array.values(), &values);
2269
2270        let array = PrimitiveArray::<Decimal128Type>::from(values.clone());
2271        assert_eq!(array.values(), &values);
2272
2273        let array = PrimitiveArray::<Decimal128Type>::from(array.to_data());
2274        assert_eq!(array.values(), &values);
2275    }
2276
2277    #[test]
2278    fn test_decimal256() {
2279        let values: Vec<_> = vec![i256::ZERO, i256::ONE, i256::MINUS_ONE, i256::MIN, i256::MAX];
2280
2281        let array: PrimitiveArray<Decimal256Type> =
2282            PrimitiveArray::from_iter(values.iter().copied());
2283        assert_eq!(array.values(), &values);
2284
2285        let array: PrimitiveArray<Decimal256Type> =
2286            PrimitiveArray::from_iter_values(values.iter().copied());
2287        assert_eq!(array.values(), &values);
2288
2289        let array = PrimitiveArray::<Decimal256Type>::from(values.clone());
2290        assert_eq!(array.values(), &values);
2291
2292        let array = PrimitiveArray::<Decimal256Type>::from(array.to_data());
2293        assert_eq!(array.values(), &values);
2294    }
2295
2296    #[test]
2297    fn test_decimal_array() {
2298        // let val_8887: [u8; 16] = [192, 219, 180, 17, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
2299        // let val_neg_8887: [u8; 16] = [64, 36, 75, 238, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255];
2300        let values: [u8; 32] = [
2301            192, 219, 180, 17, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 36, 75, 238, 253, 255, 255,
2302            255, 255, 255, 255, 255, 255, 255, 255, 255,
2303        ];
2304        let array_data = ArrayData::builder(DataType::Decimal128(38, 6))
2305            .len(2)
2306            .add_buffer(Buffer::from(&values[..]))
2307            .build()
2308            .unwrap();
2309        let decimal_array = Decimal128Array::from(array_data);
2310        assert_eq!(8_887_000_000_i128, decimal_array.value(0));
2311        assert_eq!(-8_887_000_000_i128, decimal_array.value(1));
2312    }
2313
2314    #[test]
2315    fn test_decimal_append_error_value() {
2316        let mut decimal_builder = Decimal128Builder::with_capacity(10);
2317        decimal_builder.append_value(123456);
2318        decimal_builder.append_value(12345);
2319        let result = decimal_builder.finish().with_precision_and_scale(5, 3);
2320        assert!(result.is_ok());
2321        let arr = result.unwrap();
2322        assert_eq!("12.345", arr.value_as_string(1));
2323
2324        // Validate it explicitly
2325        let result = arr.validate_decimal_precision(5);
2326        let error = result.unwrap_err();
2327        assert_eq!(
2328            "Invalid argument error: 123456 is too large to store in a Decimal128 of precision 5. Max is 99999",
2329            error.to_string()
2330        );
2331
2332        decimal_builder = Decimal128Builder::new();
2333        decimal_builder.append_value(100);
2334        decimal_builder.append_value(99);
2335        decimal_builder.append_value(-100);
2336        decimal_builder.append_value(-99);
2337        let result = decimal_builder.finish().with_precision_and_scale(2, 1);
2338        assert!(result.is_ok());
2339        let arr = result.unwrap();
2340        assert_eq!("9.9", arr.value_as_string(1));
2341        assert_eq!("-9.9", arr.value_as_string(3));
2342
2343        // Validate it explicitly
2344        let result = arr.validate_decimal_precision(2);
2345        let error = result.unwrap_err();
2346        assert_eq!(
2347            "Invalid argument error: 100 is too large to store in a Decimal128 of precision 2. Max is 99",
2348            error.to_string()
2349        );
2350    }
2351
2352    #[test]
2353    fn test_decimal_from_iter_values() {
2354        let array = Decimal128Array::from_iter_values(vec![-100, 0, 101]);
2355        assert_eq!(array.len(), 3);
2356        assert_eq!(array.data_type(), &DataType::Decimal128(38, 10));
2357        assert_eq!(-100_i128, array.value(0));
2358        assert!(!array.is_null(0));
2359        assert_eq!(0_i128, array.value(1));
2360        assert!(!array.is_null(1));
2361        assert_eq!(101_i128, array.value(2));
2362        assert!(!array.is_null(2));
2363    }
2364
2365    #[test]
2366    fn test_decimal_from_iter() {
2367        let array: Decimal128Array = vec![Some(-100), None, Some(101)].into_iter().collect();
2368        assert_eq!(array.len(), 3);
2369        assert_eq!(array.data_type(), &DataType::Decimal128(38, 10));
2370        assert_eq!(-100_i128, array.value(0));
2371        assert!(!array.is_null(0));
2372        assert!(array.is_null(1));
2373        assert_eq!(101_i128, array.value(2));
2374        assert!(!array.is_null(2));
2375    }
2376
2377    #[test]
2378    fn test_decimal_iter_sized() {
2379        let data = vec![Some(-100), None, Some(101)];
2380        let array: Decimal128Array = data.into_iter().collect();
2381        let mut iter = array.into_iter();
2382
2383        // is exact sized
2384        assert_eq!(array.len(), 3);
2385
2386        // size_hint is reported correctly
2387        assert_eq!(iter.size_hint(), (3, Some(3)));
2388        iter.next().unwrap();
2389        assert_eq!(iter.size_hint(), (2, Some(2)));
2390        iter.next().unwrap();
2391        iter.next().unwrap();
2392        assert_eq!(iter.size_hint(), (0, Some(0)));
2393        assert!(iter.next().is_none());
2394        assert_eq!(iter.size_hint(), (0, Some(0)));
2395    }
2396
2397    #[test]
2398    fn test_decimal_array_value_as_string() {
2399        let arr = [123450, -123450, 100, -100, 10, -10, 0]
2400            .into_iter()
2401            .map(Some)
2402            .collect::<Decimal128Array>()
2403            .with_precision_and_scale(6, 3)
2404            .unwrap();
2405
2406        assert_eq!("123.450", arr.value_as_string(0));
2407        assert_eq!("-123.450", arr.value_as_string(1));
2408        assert_eq!("0.100", arr.value_as_string(2));
2409        assert_eq!("-0.100", arr.value_as_string(3));
2410        assert_eq!("0.010", arr.value_as_string(4));
2411        assert_eq!("-0.010", arr.value_as_string(5));
2412        assert_eq!("0.000", arr.value_as_string(6));
2413    }
2414
2415    #[test]
2416    fn test_decimal_array_with_precision_and_scale() {
2417        let arr = Decimal128Array::from_iter_values([12345, 456, 7890, -123223423432432])
2418            .with_precision_and_scale(20, 2)
2419            .unwrap();
2420
2421        assert_eq!(arr.data_type(), &DataType::Decimal128(20, 2));
2422        assert_eq!(arr.precision(), 20);
2423        assert_eq!(arr.scale(), 2);
2424
2425        let actual: Vec<_> = (0..arr.len()).map(|i| arr.value_as_string(i)).collect();
2426        let expected = vec!["123.45", "4.56", "78.90", "-1232234234324.32"];
2427
2428        assert_eq!(actual, expected);
2429    }
2430
2431    #[test]
2432    #[should_panic(
2433        expected = "-123223423432432 is too small to store in a Decimal128 of precision 5. Min is -99999"
2434    )]
2435    fn test_decimal_array_with_precision_and_scale_out_of_range() {
2436        let arr = Decimal128Array::from_iter_values([12345, 456, 7890, -123223423432432])
2437            // precision is too small to hold value
2438            .with_precision_and_scale(5, 2)
2439            .unwrap();
2440        arr.validate_decimal_precision(5).unwrap();
2441    }
2442
2443    #[test]
2444    #[should_panic(expected = "precision cannot be 0, has to be between [1, 38]")]
2445    fn test_decimal_array_with_precision_zero() {
2446        Decimal128Array::from_iter_values([12345, 456])
2447            .with_precision_and_scale(0, 2)
2448            .unwrap();
2449    }
2450
2451    #[test]
2452    #[should_panic(expected = "precision 40 is greater than max 38")]
2453    fn test_decimal_array_with_precision_and_scale_invalid_precision() {
2454        Decimal128Array::from_iter_values([12345, 456])
2455            .with_precision_and_scale(40, 2)
2456            .unwrap();
2457    }
2458
2459    #[test]
2460    #[should_panic(expected = "scale 40 is greater than max 38")]
2461    fn test_decimal_array_with_precision_and_scale_invalid_scale() {
2462        Decimal128Array::from_iter_values([12345, 456])
2463            .with_precision_and_scale(20, 40)
2464            .unwrap();
2465    }
2466
2467    #[test]
2468    #[should_panic(expected = "scale 10 is greater than precision 4")]
2469    fn test_decimal_array_with_precision_and_scale_invalid_precision_and_scale() {
2470        Decimal128Array::from_iter_values([12345, 456])
2471            .with_precision_and_scale(4, 10)
2472            .unwrap();
2473    }
2474
2475    #[test]
2476    fn test_decimal_array_set_null_if_overflow_with_precision() {
2477        let array = Decimal128Array::from(vec![Some(123456), Some(123), None, Some(123456)]);
2478        let result = array.null_if_overflow_precision(5);
2479        let expected = Decimal128Array::from(vec![None, Some(123), None, None]);
2480        assert_eq!(result, expected);
2481    }
2482
2483    #[test]
2484    fn test_decimal256_iter() {
2485        let mut builder = Decimal256Builder::with_capacity(30);
2486        let decimal1 = i256::from_i128(12345);
2487        builder.append_value(decimal1);
2488
2489        builder.append_null();
2490
2491        let decimal2 = i256::from_i128(56789);
2492        builder.append_value(decimal2);
2493
2494        let array: Decimal256Array = builder.finish().with_precision_and_scale(76, 6).unwrap();
2495
2496        let collected: Vec<_> = array.iter().collect();
2497        assert_eq!(vec![Some(decimal1), None, Some(decimal2)], collected);
2498    }
2499
2500    #[test]
2501    fn test_from_iter_decimal256array() {
2502        let value1 = i256::from_i128(12345);
2503        let value2 = i256::from_i128(56789);
2504
2505        let mut array: Decimal256Array =
2506            vec![Some(value1), None, Some(value2)].into_iter().collect();
2507        array = array.with_precision_and_scale(76, 10).unwrap();
2508        assert_eq!(array.len(), 3);
2509        assert_eq!(array.data_type(), &DataType::Decimal256(76, 10));
2510        assert_eq!(value1, array.value(0));
2511        assert!(!array.is_null(0));
2512        assert!(array.is_null(1));
2513        assert_eq!(value2, array.value(2));
2514        assert!(!array.is_null(2));
2515    }
2516
2517    #[test]
2518    fn test_from_iter_decimal128array() {
2519        let mut array: Decimal128Array = vec![Some(-100), None, Some(101)].into_iter().collect();
2520        array = array.with_precision_and_scale(38, 10).unwrap();
2521        assert_eq!(array.len(), 3);
2522        assert_eq!(array.data_type(), &DataType::Decimal128(38, 10));
2523        assert_eq!(-100_i128, array.value(0));
2524        assert!(!array.is_null(0));
2525        assert!(array.is_null(1));
2526        assert_eq!(101_i128, array.value(2));
2527        assert!(!array.is_null(2));
2528    }
2529
2530    #[test]
2531    fn test_unary_opt() {
2532        let array = Int32Array::from(vec![1, 2, 3, 4, 5, 6, 7]);
2533        let r = array.unary_opt::<_, Int32Type>(|x| (x % 2 != 0).then_some(x));
2534
2535        let expected = Int32Array::from(vec![Some(1), None, Some(3), None, Some(5), None, Some(7)]);
2536        assert_eq!(r, expected);
2537
2538        let r = expected.unary_opt::<_, Int32Type>(|x| (x % 3 != 0).then_some(x));
2539        let expected = Int32Array::from(vec![Some(1), None, None, None, Some(5), None, Some(7)]);
2540        assert_eq!(r, expected);
2541    }
2542
2543    #[test]
2544    #[should_panic(
2545        expected = "Trying to access an element at index 4 from a PrimitiveArray of length 3"
2546    )]
2547    fn test_fixed_size_binary_array_get_value_index_out_of_bound() {
2548        let array = Decimal128Array::from(vec![-100, 0, 101]);
2549        array.value(4);
2550    }
2551
2552    #[test]
2553    fn test_into_builder() {
2554        let array: Int32Array = vec![1, 2, 3].into_iter().map(Some).collect();
2555
2556        let boxed: ArrayRef = Arc::new(array);
2557        let col: Int32Array = downcast_array(&boxed);
2558        drop(boxed);
2559
2560        let mut builder = col.into_builder().unwrap();
2561
2562        let slice = builder.values_slice_mut();
2563        assert_eq!(slice, &[1, 2, 3]);
2564
2565        slice[0] = 4;
2566        slice[1] = 2;
2567        slice[2] = 1;
2568
2569        let expected: Int32Array = vec![Some(4), Some(2), Some(1)].into_iter().collect();
2570
2571        let new_array = builder.finish();
2572        assert_eq!(expected, new_array);
2573    }
2574
2575    #[test]
2576    fn test_into_builder_cloned_array() {
2577        let array: Int32Array = vec![1, 2, 3].into_iter().map(Some).collect();
2578
2579        let boxed: ArrayRef = Arc::new(array);
2580
2581        let col: Int32Array = PrimitiveArray::<Int32Type>::from(boxed.to_data());
2582        let err = col.into_builder();
2583
2584        match err {
2585            Ok(_) => panic!("Should not get builder from cloned array"),
2586            Err(returned) => {
2587                let expected: Int32Array = vec![1, 2, 3].into_iter().map(Some).collect();
2588                assert_eq!(expected, returned)
2589            }
2590        }
2591    }
2592
2593    #[test]
2594    fn test_into_builder_on_sliced_array() {
2595        let array: Int32Array = vec![1, 2, 3].into_iter().map(Some).collect();
2596        let slice = array.slice(1, 2);
2597        let col: Int32Array = downcast_array(&slice);
2598
2599        drop(slice);
2600
2601        col.into_builder()
2602            .expect_err("Should not build builder from sliced array");
2603    }
2604
2605    #[test]
2606    fn test_unary_mut() {
2607        let array: Int32Array = vec![1, 2, 3].into_iter().map(Some).collect();
2608
2609        let c = array.unary_mut(|x| x * 2 + 1).unwrap();
2610        let expected: Int32Array = vec![3, 5, 7].into_iter().map(Some).collect();
2611
2612        assert_eq!(expected, c);
2613
2614        let array: Int32Array = Int32Array::from(vec![Some(5), Some(7), None]);
2615        let c = array.unary_mut(|x| x * 2 + 1).unwrap();
2616        assert_eq!(c, Int32Array::from(vec![Some(11), Some(15), None]));
2617    }
2618
2619    #[test]
2620    #[should_panic(
2621        expected = "PrimitiveArray expected data type Interval(MonthDayNano) got Interval(DayTime)"
2622    )]
2623    fn test_invalid_interval_type() {
2624        let array = IntervalDayTimeArray::from(vec![IntervalDayTime::ZERO]);
2625        let _ = IntervalMonthDayNanoArray::from(array.into_data());
2626    }
2627
2628    #[test]
2629    fn test_timezone() {
2630        let array = TimestampNanosecondArray::from_iter_values([1, 2]);
2631        assert_eq!(array.timezone(), None);
2632
2633        let array = array.with_timezone("+02:00");
2634        assert_eq!(array.timezone(), Some("+02:00"));
2635    }
2636
2637    #[test]
2638    fn test_try_new() {
2639        Int32Array::new(vec![1, 2, 3, 4].into(), None);
2640        Int32Array::new(vec![1, 2, 3, 4].into(), Some(NullBuffer::new_null(4)));
2641
2642        let err = Int32Array::try_new(vec![1, 2, 3, 4].into(), Some(NullBuffer::new_null(3)))
2643            .unwrap_err();
2644
2645        assert_eq!(
2646            err.to_string(),
2647            "Invalid argument error: Incorrect length of null buffer for PrimitiveArray, expected 4 got 3"
2648        );
2649
2650        TimestampNanosecondArray::new(vec![1, 2, 3, 4].into(), None).with_data_type(
2651            DataType::Timestamp(TimeUnit::Nanosecond, Some("03:00".into())),
2652        );
2653    }
2654
2655    #[test]
2656    #[should_panic(expected = "PrimitiveArray expected data type Int32 got Date32")]
2657    fn test_with_data_type() {
2658        Int32Array::new(vec![1, 2, 3, 4].into(), None).with_data_type(DataType::Date32);
2659    }
2660
2661    #[test]
2662    fn test_time_32second_output() {
2663        let array: Time32SecondArray = vec![
2664            Some(-1),
2665            Some(0),
2666            Some(86_399),
2667            Some(86_400),
2668            Some(86_401),
2669            None,
2670        ]
2671        .into();
2672        let debug_str = format!("{:?}", array);
2673        assert_eq!("PrimitiveArray<Time32(Second)>\n[\n  Cast error: Failed to convert -1 to temporal for Time32(Second),\n  00:00:00,\n  23:59:59,\n  Cast error: Failed to convert 86400 to temporal for Time32(Second),\n  Cast error: Failed to convert 86401 to temporal for Time32(Second),\n  null,\n]",
2674    debug_str
2675    );
2676    }
2677
2678    #[test]
2679    fn test_time_32millisecond_debug_output() {
2680        let array: Time32MillisecondArray = vec![
2681            Some(-1),
2682            Some(0),
2683            Some(86_399_000),
2684            Some(86_400_000),
2685            Some(86_401_000),
2686            None,
2687        ]
2688        .into();
2689        let debug_str = format!("{:?}", array);
2690        assert_eq!("PrimitiveArray<Time32(Millisecond)>\n[\n  Cast error: Failed to convert -1 to temporal for Time32(Millisecond),\n  00:00:00,\n  23:59:59,\n  Cast error: Failed to convert 86400000 to temporal for Time32(Millisecond),\n  Cast error: Failed to convert 86401000 to temporal for Time32(Millisecond),\n  null,\n]",
2691            debug_str
2692        );
2693    }
2694
2695    #[test]
2696    fn test_time_64nanosecond_debug_output() {
2697        let array: Time64NanosecondArray = vec![
2698            Some(-1),
2699            Some(0),
2700            Some(86_399 * 1_000_000_000),
2701            Some(86_400 * 1_000_000_000),
2702            Some(86_401 * 1_000_000_000),
2703            None,
2704        ]
2705        .into();
2706        let debug_str = format!("{:?}", array);
2707        assert_eq!(
2708        "PrimitiveArray<Time64(Nanosecond)>\n[\n  Cast error: Failed to convert -1 to temporal for Time64(Nanosecond),\n  00:00:00,\n  23:59:59,\n  Cast error: Failed to convert 86400000000000 to temporal for Time64(Nanosecond),\n  Cast error: Failed to convert 86401000000000 to temporal for Time64(Nanosecond),\n  null,\n]",
2709            debug_str
2710        );
2711    }
2712
2713    #[test]
2714    fn test_time_64microsecond_debug_output() {
2715        let array: Time64MicrosecondArray = vec![
2716            Some(-1),
2717            Some(0),
2718            Some(86_399 * 1_000_000),
2719            Some(86_400 * 1_000_000),
2720            Some(86_401 * 1_000_000),
2721            None,
2722        ]
2723        .into();
2724        let debug_str = format!("{:?}", array);
2725        assert_eq!("PrimitiveArray<Time64(Microsecond)>\n[\n  Cast error: Failed to convert -1 to temporal for Time64(Microsecond),\n  00:00:00,\n  23:59:59,\n  Cast error: Failed to convert 86400000000 to temporal for Time64(Microsecond),\n  Cast error: Failed to convert 86401000000 to temporal for Time64(Microsecond),\n  null,\n]", debug_str);
2726    }
2727
2728    #[test]
2729    fn test_primitive_with_nulls_into_builder() {
2730        let array: Int32Array = vec![
2731            Some(1),
2732            None,
2733            Some(3),
2734            Some(4),
2735            None,
2736            Some(7),
2737            None,
2738            Some(8),
2739        ]
2740        .into_iter()
2741        .collect();
2742        let _ = array.into_builder();
2743    }
2744}