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    /// Returns the timezone of this array if any
1491    pub fn timezone(&self) -> Option<&str> {
1492        match self.data_type() {
1493            DataType::Timestamp(_, tz) => tz.as_deref(),
1494            _ => unreachable!(),
1495        }
1496    }
1497
1498    /// Construct a timestamp array with new timezone
1499    pub fn with_timezone(self, timezone: impl Into<Arc<str>>) -> Self {
1500        self.with_timezone_opt(Some(timezone.into()))
1501    }
1502
1503    /// Construct a timestamp array with UTC
1504    pub fn with_timezone_utc(self) -> Self {
1505        self.with_timezone("+00:00")
1506    }
1507
1508    /// Construct a timestamp array with an optional timezone
1509    pub fn with_timezone_opt<S: Into<Arc<str>>>(self, timezone: Option<S>) -> Self {
1510        Self {
1511            data_type: DataType::Timestamp(T::UNIT, timezone.map(Into::into)),
1512            ..self
1513        }
1514    }
1515}
1516
1517/// Constructs a `PrimitiveArray` from an array data reference.
1518impl<T: ArrowPrimitiveType> From<ArrayData> for PrimitiveArray<T> {
1519    fn from(data: ArrayData) -> Self {
1520        Self::assert_compatible(data.data_type());
1521        assert_eq!(
1522            data.buffers().len(),
1523            1,
1524            "PrimitiveArray data should contain a single buffer only (values buffer)"
1525        );
1526
1527        let values = ScalarBuffer::new(data.buffers()[0].clone(), data.offset(), data.len());
1528        Self {
1529            data_type: data.data_type().clone(),
1530            values,
1531            nulls: data.nulls().cloned(),
1532        }
1533    }
1534}
1535
1536impl<T: DecimalType + ArrowPrimitiveType> PrimitiveArray<T> {
1537    /// Returns a Decimal array with the same data as self, with the
1538    /// specified precision and scale.
1539    ///
1540    /// See [`validate_decimal_precision_and_scale`]
1541    pub fn with_precision_and_scale(self, precision: u8, scale: i8) -> Result<Self, ArrowError> {
1542        validate_decimal_precision_and_scale::<T>(precision, scale)?;
1543        Ok(Self {
1544            data_type: T::TYPE_CONSTRUCTOR(precision, scale),
1545            ..self
1546        })
1547    }
1548
1549    /// Validates values in this array can be properly interpreted
1550    /// with the specified precision.
1551    pub fn validate_decimal_precision(&self, precision: u8) -> Result<(), ArrowError> {
1552        (0..self.len()).try_for_each(|idx| {
1553            if self.is_valid(idx) {
1554                let decimal = unsafe { self.value_unchecked(idx) };
1555                T::validate_decimal_precision(decimal, precision)
1556            } else {
1557                Ok(())
1558            }
1559        })
1560    }
1561
1562    /// Validates the Decimal Array, if the value of slot is overflow for the specified precision, and
1563    /// will be casted to Null
1564    pub fn null_if_overflow_precision(&self, precision: u8) -> Self {
1565        self.unary_opt::<_, T>(|v| T::is_valid_decimal_precision(v, precision).then_some(v))
1566    }
1567
1568    /// Returns [`Self::value`] formatted as a string
1569    pub fn value_as_string(&self, row: usize) -> String {
1570        T::format_decimal(self.value(row), self.precision(), self.scale())
1571    }
1572
1573    /// Returns the decimal precision of this array
1574    pub fn precision(&self) -> u8 {
1575        match T::BYTE_LENGTH {
1576            16 => {
1577                if let DataType::Decimal128(p, _) = self.data_type() {
1578                    *p
1579                } else {
1580                    unreachable!(
1581                        "Decimal128Array datatype is not DataType::Decimal128 but {}",
1582                        self.data_type()
1583                    )
1584                }
1585            }
1586            32 => {
1587                if let DataType::Decimal256(p, _) = self.data_type() {
1588                    *p
1589                } else {
1590                    unreachable!(
1591                        "Decimal256Array datatype is not DataType::Decimal256 but {}",
1592                        self.data_type()
1593                    )
1594                }
1595            }
1596            other => unreachable!("Unsupported byte length for decimal array {}", other),
1597        }
1598    }
1599
1600    /// Returns the decimal scale of this array
1601    pub fn scale(&self) -> i8 {
1602        match T::BYTE_LENGTH {
1603            16 => {
1604                if let DataType::Decimal128(_, s) = self.data_type() {
1605                    *s
1606                } else {
1607                    unreachable!(
1608                        "Decimal128Array datatype is not DataType::Decimal128 but {}",
1609                        self.data_type()
1610                    )
1611                }
1612            }
1613            32 => {
1614                if let DataType::Decimal256(_, s) = self.data_type() {
1615                    *s
1616                } else {
1617                    unreachable!(
1618                        "Decimal256Array datatype is not DataType::Decimal256 but {}",
1619                        self.data_type()
1620                    )
1621                }
1622            }
1623            other => unreachable!("Unsupported byte length for decimal array {}", other),
1624        }
1625    }
1626}
1627
1628#[cfg(test)]
1629mod tests {
1630    use super::*;
1631    use crate::builder::{Decimal128Builder, Decimal256Builder};
1632    use crate::cast::downcast_array;
1633    use crate::BooleanArray;
1634    use arrow_buffer::{IntervalDayTime, IntervalMonthDayNano};
1635    use arrow_schema::TimeUnit;
1636
1637    #[test]
1638    fn test_primitive_array_from_vec() {
1639        let buf = Buffer::from_slice_ref([0, 1, 2, 3, 4]);
1640        let arr = Int32Array::from(vec![0, 1, 2, 3, 4]);
1641        assert_eq!(&buf, arr.values.inner());
1642        assert_eq!(5, arr.len());
1643        assert_eq!(0, arr.offset());
1644        assert_eq!(0, arr.null_count());
1645        for i in 0..5 {
1646            assert!(!arr.is_null(i));
1647            assert!(arr.is_valid(i));
1648            assert_eq!(i as i32, arr.value(i));
1649        }
1650    }
1651
1652    #[test]
1653    fn test_primitive_array_from_vec_option() {
1654        // Test building a primitive array with null values
1655        let arr = Int32Array::from(vec![Some(0), None, Some(2), None, Some(4)]);
1656        assert_eq!(5, arr.len());
1657        assert_eq!(0, arr.offset());
1658        assert_eq!(2, arr.null_count());
1659        for i in 0..5 {
1660            if i % 2 == 0 {
1661                assert!(!arr.is_null(i));
1662                assert!(arr.is_valid(i));
1663                assert_eq!(i as i32, arr.value(i));
1664            } else {
1665                assert!(arr.is_null(i));
1666                assert!(!arr.is_valid(i));
1667            }
1668        }
1669    }
1670
1671    #[test]
1672    fn test_date64_array_from_vec_option() {
1673        // Test building a primitive array with null values
1674        // we use Int32 and Int64 as a backing array, so all Int32 and Int64 conventions
1675        // work
1676        let arr: PrimitiveArray<Date64Type> =
1677            vec![Some(1550902545147), None, Some(1550902545147)].into();
1678        assert_eq!(3, arr.len());
1679        assert_eq!(0, arr.offset());
1680        assert_eq!(1, arr.null_count());
1681        for i in 0..3 {
1682            if i % 2 == 0 {
1683                assert!(!arr.is_null(i));
1684                assert!(arr.is_valid(i));
1685                assert_eq!(1550902545147, arr.value(i));
1686                // roundtrip to and from datetime
1687                assert_eq!(
1688                    1550902545147,
1689                    arr.value_as_datetime(i)
1690                        .unwrap()
1691                        .and_utc()
1692                        .timestamp_millis()
1693                );
1694            } else {
1695                assert!(arr.is_null(i));
1696                assert!(!arr.is_valid(i));
1697            }
1698        }
1699    }
1700
1701    #[test]
1702    fn test_time32_millisecond_array_from_vec() {
1703        // 1:        00:00:00.001
1704        // 37800005: 10:30:00.005
1705        // 86399210: 23:59:59.210
1706        let arr: PrimitiveArray<Time32MillisecondType> = vec![1, 37_800_005, 86_399_210].into();
1707        assert_eq!(3, arr.len());
1708        assert_eq!(0, arr.offset());
1709        assert_eq!(0, arr.null_count());
1710        let formatted = ["00:00:00.001", "10:30:00.005", "23:59:59.210"];
1711        for (i, formatted) in formatted.iter().enumerate().take(3) {
1712            // check that we can't create dates or datetimes from time instances
1713            assert_eq!(None, arr.value_as_datetime(i));
1714            assert_eq!(None, arr.value_as_date(i));
1715            let time = arr.value_as_time(i).unwrap();
1716            assert_eq!(*formatted, time.format("%H:%M:%S%.3f").to_string());
1717        }
1718    }
1719
1720    #[test]
1721    fn test_time64_nanosecond_array_from_vec() {
1722        // Test building a primitive array with null values
1723        // we use Int32 and Int64 as a backing array, so all Int32 and Int64 conventions
1724        // work
1725
1726        // 1e6:        00:00:00.001
1727        // 37800005e6: 10:30:00.005
1728        // 86399210e6: 23:59:59.210
1729        let arr: PrimitiveArray<Time64NanosecondType> =
1730            vec![1_000_000, 37_800_005_000_000, 86_399_210_000_000].into();
1731        assert_eq!(3, arr.len());
1732        assert_eq!(0, arr.offset());
1733        assert_eq!(0, arr.null_count());
1734        let formatted = ["00:00:00.001", "10:30:00.005", "23:59:59.210"];
1735        for (i, item) in formatted.iter().enumerate().take(3) {
1736            // check that we can't create dates or datetimes from time instances
1737            assert_eq!(None, arr.value_as_datetime(i));
1738            assert_eq!(None, arr.value_as_date(i));
1739            let time = arr.value_as_time(i).unwrap();
1740            assert_eq!(*item, time.format("%H:%M:%S%.3f").to_string());
1741        }
1742    }
1743
1744    #[test]
1745    fn test_interval_array_from_vec() {
1746        // intervals are currently not treated specially, but are Int32 and Int64 arrays
1747        let arr = IntervalYearMonthArray::from(vec![Some(1), None, Some(-5)]);
1748        assert_eq!(3, arr.len());
1749        assert_eq!(0, arr.offset());
1750        assert_eq!(1, arr.null_count());
1751        assert_eq!(1, arr.value(0));
1752        assert_eq!(1, arr.values()[0]);
1753        assert!(arr.is_null(1));
1754        assert_eq!(-5, arr.value(2));
1755        assert_eq!(-5, arr.values()[2]);
1756
1757        let v0 = IntervalDayTime {
1758            days: 34,
1759            milliseconds: 1,
1760        };
1761        let v2 = IntervalDayTime {
1762            days: -2,
1763            milliseconds: -5,
1764        };
1765
1766        let arr = IntervalDayTimeArray::from(vec![Some(v0), None, Some(v2)]);
1767
1768        assert_eq!(3, arr.len());
1769        assert_eq!(0, arr.offset());
1770        assert_eq!(1, arr.null_count());
1771        assert_eq!(v0, arr.value(0));
1772        assert_eq!(v0, arr.values()[0]);
1773        assert!(arr.is_null(1));
1774        assert_eq!(v2, arr.value(2));
1775        assert_eq!(v2, arr.values()[2]);
1776
1777        let v0 = IntervalMonthDayNano {
1778            months: 2,
1779            days: 34,
1780            nanoseconds: -1,
1781        };
1782        let v2 = IntervalMonthDayNano {
1783            months: -3,
1784            days: -2,
1785            nanoseconds: 4,
1786        };
1787
1788        let arr = IntervalMonthDayNanoArray::from(vec![Some(v0), None, Some(v2)]);
1789        assert_eq!(3, arr.len());
1790        assert_eq!(0, arr.offset());
1791        assert_eq!(1, arr.null_count());
1792        assert_eq!(v0, arr.value(0));
1793        assert_eq!(v0, arr.values()[0]);
1794        assert!(arr.is_null(1));
1795        assert_eq!(v2, arr.value(2));
1796        assert_eq!(v2, arr.values()[2]);
1797    }
1798
1799    #[test]
1800    fn test_duration_array_from_vec() {
1801        let arr = DurationSecondArray::from(vec![Some(1), None, Some(-5)]);
1802        assert_eq!(3, arr.len());
1803        assert_eq!(0, arr.offset());
1804        assert_eq!(1, arr.null_count());
1805        assert_eq!(1, arr.value(0));
1806        assert_eq!(1, arr.values()[0]);
1807        assert!(arr.is_null(1));
1808        assert_eq!(-5, arr.value(2));
1809        assert_eq!(-5, arr.values()[2]);
1810
1811        let arr = DurationMillisecondArray::from(vec![Some(1), None, Some(-5)]);
1812        assert_eq!(3, arr.len());
1813        assert_eq!(0, arr.offset());
1814        assert_eq!(1, arr.null_count());
1815        assert_eq!(1, arr.value(0));
1816        assert_eq!(1, arr.values()[0]);
1817        assert!(arr.is_null(1));
1818        assert_eq!(-5, arr.value(2));
1819        assert_eq!(-5, arr.values()[2]);
1820
1821        let arr = DurationMicrosecondArray::from(vec![Some(1), None, Some(-5)]);
1822        assert_eq!(3, arr.len());
1823        assert_eq!(0, arr.offset());
1824        assert_eq!(1, arr.null_count());
1825        assert_eq!(1, arr.value(0));
1826        assert_eq!(1, arr.values()[0]);
1827        assert!(arr.is_null(1));
1828        assert_eq!(-5, arr.value(2));
1829        assert_eq!(-5, arr.values()[2]);
1830
1831        let arr = DurationNanosecondArray::from(vec![Some(1), None, Some(-5)]);
1832        assert_eq!(3, arr.len());
1833        assert_eq!(0, arr.offset());
1834        assert_eq!(1, arr.null_count());
1835        assert_eq!(1, arr.value(0));
1836        assert_eq!(1, arr.values()[0]);
1837        assert!(arr.is_null(1));
1838        assert_eq!(-5, arr.value(2));
1839        assert_eq!(-5, arr.values()[2]);
1840    }
1841
1842    #[test]
1843    fn test_timestamp_array_from_vec() {
1844        let arr = TimestampSecondArray::from(vec![1, -5]);
1845        assert_eq!(2, arr.len());
1846        assert_eq!(0, arr.offset());
1847        assert_eq!(0, arr.null_count());
1848        assert_eq!(1, arr.value(0));
1849        assert_eq!(-5, arr.value(1));
1850        assert_eq!(&[1, -5], arr.values());
1851
1852        let arr = TimestampMillisecondArray::from(vec![1, -5]);
1853        assert_eq!(2, arr.len());
1854        assert_eq!(0, arr.offset());
1855        assert_eq!(0, arr.null_count());
1856        assert_eq!(1, arr.value(0));
1857        assert_eq!(-5, arr.value(1));
1858        assert_eq!(&[1, -5], arr.values());
1859
1860        let arr = TimestampMicrosecondArray::from(vec![1, -5]);
1861        assert_eq!(2, arr.len());
1862        assert_eq!(0, arr.offset());
1863        assert_eq!(0, arr.null_count());
1864        assert_eq!(1, arr.value(0));
1865        assert_eq!(-5, arr.value(1));
1866        assert_eq!(&[1, -5], arr.values());
1867
1868        let arr = TimestampNanosecondArray::from(vec![1, -5]);
1869        assert_eq!(2, arr.len());
1870        assert_eq!(0, arr.offset());
1871        assert_eq!(0, arr.null_count());
1872        assert_eq!(1, arr.value(0));
1873        assert_eq!(-5, arr.value(1));
1874        assert_eq!(&[1, -5], arr.values());
1875    }
1876
1877    #[test]
1878    fn test_primitive_array_slice() {
1879        let arr = Int32Array::from(vec![
1880            Some(0),
1881            None,
1882            Some(2),
1883            None,
1884            Some(4),
1885            Some(5),
1886            Some(6),
1887            None,
1888            None,
1889        ]);
1890        assert_eq!(9, arr.len());
1891        assert_eq!(0, arr.offset());
1892        assert_eq!(4, arr.null_count());
1893
1894        let arr2 = arr.slice(2, 5);
1895        assert_eq!(5, arr2.len());
1896        assert_eq!(1, arr2.null_count());
1897
1898        for i in 0..arr2.len() {
1899            assert_eq!(i == 1, arr2.is_null(i));
1900            assert_eq!(i != 1, arr2.is_valid(i));
1901        }
1902        let int_arr2 = arr2.as_any().downcast_ref::<Int32Array>().unwrap();
1903        assert_eq!(2, int_arr2.values()[0]);
1904        assert_eq!(&[4, 5, 6], &int_arr2.values()[2..5]);
1905
1906        let arr3 = arr2.slice(2, 3);
1907        assert_eq!(3, arr3.len());
1908        assert_eq!(0, arr3.null_count());
1909
1910        let int_arr3 = arr3.as_any().downcast_ref::<Int32Array>().unwrap();
1911        assert_eq!(&[4, 5, 6], int_arr3.values());
1912        assert_eq!(4, int_arr3.value(0));
1913        assert_eq!(5, int_arr3.value(1));
1914        assert_eq!(6, int_arr3.value(2));
1915    }
1916
1917    #[test]
1918    fn test_boolean_array_slice() {
1919        let arr = BooleanArray::from(vec![
1920            Some(true),
1921            None,
1922            Some(false),
1923            None,
1924            Some(true),
1925            Some(false),
1926            Some(true),
1927            Some(false),
1928            None,
1929            Some(true),
1930        ]);
1931
1932        assert_eq!(10, arr.len());
1933        assert_eq!(0, arr.offset());
1934        assert_eq!(3, arr.null_count());
1935
1936        let arr2 = arr.slice(3, 5);
1937        assert_eq!(5, arr2.len());
1938        assert_eq!(3, arr2.offset());
1939        assert_eq!(1, arr2.null_count());
1940
1941        let bool_arr = arr2.as_any().downcast_ref::<BooleanArray>().unwrap();
1942
1943        assert!(!bool_arr.is_valid(0));
1944
1945        assert!(bool_arr.is_valid(1));
1946        assert!(bool_arr.value(1));
1947
1948        assert!(bool_arr.is_valid(2));
1949        assert!(!bool_arr.value(2));
1950
1951        assert!(bool_arr.is_valid(3));
1952        assert!(bool_arr.value(3));
1953
1954        assert!(bool_arr.is_valid(4));
1955        assert!(!bool_arr.value(4));
1956    }
1957
1958    #[test]
1959    fn test_int32_fmt_debug() {
1960        let arr = Int32Array::from(vec![0, 1, 2, 3, 4]);
1961        assert_eq!(
1962            "PrimitiveArray<Int32>\n[\n  0,\n  1,\n  2,\n  3,\n  4,\n]",
1963            format!("{arr:?}")
1964        );
1965    }
1966
1967    #[test]
1968    fn test_fmt_debug_up_to_20_elements() {
1969        (1..=20).for_each(|i| {
1970            let values = (0..i).collect::<Vec<i16>>();
1971            let array_expected = format!(
1972                "PrimitiveArray<Int16>\n[\n{}\n]",
1973                values
1974                    .iter()
1975                    .map(|v| { format!("  {v},") })
1976                    .collect::<Vec<String>>()
1977                    .join("\n")
1978            );
1979            let array = Int16Array::from(values);
1980
1981            assert_eq!(array_expected, format!("{array:?}"));
1982        })
1983    }
1984
1985    #[test]
1986    fn test_int32_with_null_fmt_debug() {
1987        let mut builder = Int32Array::builder(3);
1988        builder.append_slice(&[0, 1]);
1989        builder.append_null();
1990        builder.append_slice(&[3, 4]);
1991        let arr = builder.finish();
1992        assert_eq!(
1993            "PrimitiveArray<Int32>\n[\n  0,\n  1,\n  null,\n  3,\n  4,\n]",
1994            format!("{arr:?}")
1995        );
1996    }
1997
1998    #[test]
1999    fn test_timestamp_fmt_debug() {
2000        let arr: PrimitiveArray<TimestampMillisecondType> =
2001            TimestampMillisecondArray::from(vec![1546214400000, 1546214400000, -1546214400000]);
2002        assert_eq!(
2003            "PrimitiveArray<Timestamp(Millisecond, None)>\n[\n  2018-12-31T00:00:00,\n  2018-12-31T00:00:00,\n  1921-01-02T00:00:00,\n]",
2004            format!("{arr:?}")
2005        );
2006    }
2007
2008    #[test]
2009    fn test_timestamp_utc_fmt_debug() {
2010        let arr: PrimitiveArray<TimestampMillisecondType> =
2011            TimestampMillisecondArray::from(vec![1546214400000, 1546214400000, -1546214400000])
2012                .with_timezone_utc();
2013        assert_eq!(
2014            "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]",
2015            format!("{arr:?}")
2016        );
2017    }
2018
2019    #[test]
2020    #[cfg(feature = "chrono-tz")]
2021    fn test_timestamp_with_named_tz_fmt_debug() {
2022        let arr: PrimitiveArray<TimestampMillisecondType> =
2023            TimestampMillisecondArray::from(vec![1546214400000, 1546214400000, -1546214400000])
2024                .with_timezone("Asia/Taipei".to_string());
2025        assert_eq!(
2026            "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]",
2027            format!("{:?}", arr)
2028        );
2029    }
2030
2031    #[test]
2032    #[cfg(not(feature = "chrono-tz"))]
2033    fn test_timestamp_with_named_tz_fmt_debug() {
2034        let arr: PrimitiveArray<TimestampMillisecondType> =
2035            TimestampMillisecondArray::from(vec![1546214400000, 1546214400000, -1546214400000])
2036                .with_timezone("Asia/Taipei".to_string());
2037
2038        println!("{arr:?}");
2039
2040        assert_eq!(
2041            "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]",
2042            format!("{arr:?}")
2043        );
2044    }
2045
2046    #[test]
2047    fn test_timestamp_with_fixed_offset_tz_fmt_debug() {
2048        let arr: PrimitiveArray<TimestampMillisecondType> =
2049            TimestampMillisecondArray::from(vec![1546214400000, 1546214400000, -1546214400000])
2050                .with_timezone("+08:00".to_string());
2051        assert_eq!(
2052            "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]",
2053            format!("{arr:?}")
2054        );
2055    }
2056
2057    #[test]
2058    fn test_timestamp_with_incorrect_tz_fmt_debug() {
2059        let arr: PrimitiveArray<TimestampMillisecondType> =
2060            TimestampMillisecondArray::from(vec![1546214400000, 1546214400000, -1546214400000])
2061                .with_timezone("xxx".to_string());
2062        assert_eq!(
2063            "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]",
2064            format!("{arr:?}")
2065        );
2066    }
2067
2068    #[test]
2069    #[cfg(feature = "chrono-tz")]
2070    fn test_timestamp_with_tz_with_daylight_saving_fmt_debug() {
2071        let arr: PrimitiveArray<TimestampMillisecondType> = TimestampMillisecondArray::from(vec![
2072            1647161999000,
2073            1647162000000,
2074            1667717999000,
2075            1667718000000,
2076        ])
2077        .with_timezone("America/Denver".to_string());
2078        assert_eq!(
2079            "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]",
2080            format!("{:?}", arr)
2081        );
2082    }
2083
2084    #[test]
2085    fn test_date32_fmt_debug() {
2086        let arr: PrimitiveArray<Date32Type> = vec![12356, 13548, -365].into();
2087        assert_eq!(
2088            "PrimitiveArray<Date32>\n[\n  2003-10-31,\n  2007-02-04,\n  1969-01-01,\n]",
2089            format!("{arr:?}")
2090        );
2091    }
2092
2093    #[test]
2094    fn test_time32second_fmt_debug() {
2095        let arr: PrimitiveArray<Time32SecondType> = vec![7201, 60054].into();
2096        assert_eq!(
2097            "PrimitiveArray<Time32(Second)>\n[\n  02:00:01,\n  16:40:54,\n]",
2098            format!("{arr:?}")
2099        );
2100    }
2101
2102    #[test]
2103    fn test_time32second_invalid_neg() {
2104        // chrono::NaiveDatetime::from_timestamp_opt returns None while input is invalid
2105        let arr: PrimitiveArray<Time32SecondType> = vec![-7201, -60054].into();
2106        assert_eq!(
2107        "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]",
2108            // "PrimitiveArray<Time32(Second)>\n[\n  null,\n  null,\n]",
2109            format!("{arr:?}")
2110        )
2111    }
2112
2113    #[test]
2114    fn test_timestamp_micros_out_of_range() {
2115        // replicate the issue from https://github.com/apache/arrow-datafusion/issues/3832
2116        let arr: PrimitiveArray<TimestampMicrosecondType> = vec![9065525203050843594].into();
2117        assert_eq!(
2118            "PrimitiveArray<Timestamp(Microsecond, None)>\n[\n  null,\n]",
2119            format!("{arr:?}")
2120        )
2121    }
2122
2123    #[test]
2124    fn test_primitive_array_builder() {
2125        // Test building a primitive array with ArrayData builder and offset
2126        let buf = Buffer::from_slice_ref([0i32, 1, 2, 3, 4, 5, 6]);
2127        let buf2 = buf.slice_with_length(8, 20);
2128        let data = ArrayData::builder(DataType::Int32)
2129            .len(5)
2130            .offset(2)
2131            .add_buffer(buf)
2132            .build()
2133            .unwrap();
2134        let arr = Int32Array::from(data);
2135        assert_eq!(&buf2, arr.values.inner());
2136        assert_eq!(5, arr.len());
2137        assert_eq!(0, arr.null_count());
2138        for i in 0..3 {
2139            assert_eq!((i + 2) as i32, arr.value(i));
2140        }
2141    }
2142
2143    #[test]
2144    fn test_primitive_from_iter_values() {
2145        // Test building a primitive array with from_iter_values
2146        let arr: PrimitiveArray<Int32Type> = PrimitiveArray::from_iter_values(0..10);
2147        assert_eq!(10, arr.len());
2148        assert_eq!(0, arr.null_count());
2149        for i in 0..10i32 {
2150            assert_eq!(i, arr.value(i as usize));
2151        }
2152    }
2153
2154    #[test]
2155    fn test_primitive_array_from_unbound_iter() {
2156        // iterator that doesn't declare (upper) size bound
2157        let value_iter = (0..)
2158            .scan(0usize, |pos, i| {
2159                if *pos < 10 {
2160                    *pos += 1;
2161                    Some(Some(i))
2162                } else {
2163                    // actually returns up to 10 values
2164                    None
2165                }
2166            })
2167            // limited using take()
2168            .take(100);
2169
2170        let (_, upper_size_bound) = value_iter.size_hint();
2171        // the upper bound, defined by take above, is 100
2172        assert_eq!(upper_size_bound, Some(100));
2173        let primitive_array: PrimitiveArray<Int32Type> = value_iter.collect();
2174        // but the actual number of items in the array should be 10
2175        assert_eq!(primitive_array.len(), 10);
2176    }
2177
2178    #[test]
2179    fn test_primitive_array_from_non_null_iter() {
2180        let iter = (0..10_i32).map(Some);
2181        let primitive_array = PrimitiveArray::<Int32Type>::from_iter(iter);
2182        assert_eq!(primitive_array.len(), 10);
2183        assert_eq!(primitive_array.null_count(), 0);
2184        assert!(primitive_array.nulls().is_none());
2185        assert_eq!(primitive_array.values(), &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
2186    }
2187
2188    #[test]
2189    #[should_panic(expected = "PrimitiveArray data should contain a single buffer only \
2190                               (values buffer)")]
2191    // Different error messages, so skip for now
2192    // https://github.com/apache/arrow-rs/issues/1545
2193    #[cfg(not(feature = "force_validate"))]
2194    fn test_primitive_array_invalid_buffer_len() {
2195        let buffer = Buffer::from_slice_ref([0i32, 1, 2, 3, 4]);
2196        let data = unsafe {
2197            ArrayData::builder(DataType::Int32)
2198                .add_buffer(buffer.clone())
2199                .add_buffer(buffer)
2200                .len(5)
2201                .build_unchecked()
2202        };
2203
2204        drop(Int32Array::from(data));
2205    }
2206
2207    #[test]
2208    fn test_access_array_concurrently() {
2209        let a = Int32Array::from(vec![5, 6, 7, 8, 9]);
2210        let ret = std::thread::spawn(move || a.value(3)).join();
2211
2212        assert!(ret.is_ok());
2213        assert_eq!(8, ret.ok().unwrap());
2214    }
2215
2216    #[test]
2217    fn test_primitive_array_creation() {
2218        let array1: Int8Array = [10_i8, 11, 12, 13, 14].into_iter().collect();
2219        let array2: Int8Array = [10_i8, 11, 12, 13, 14].into_iter().map(Some).collect();
2220
2221        assert_eq!(array1, array2);
2222    }
2223
2224    #[test]
2225    #[should_panic(
2226        expected = "Trying to access an element at index 4 from a PrimitiveArray of length 3"
2227    )]
2228    fn test_string_array_get_value_index_out_of_bound() {
2229        let array: Int8Array = [10_i8, 11, 12].into_iter().collect();
2230
2231        array.value(4);
2232    }
2233
2234    #[test]
2235    #[should_panic(expected = "PrimitiveArray expected data type Int64 got Int32")]
2236    fn test_from_array_data_validation() {
2237        let foo = PrimitiveArray::<Int32Type>::from_iter([1, 2, 3]);
2238        let _ = PrimitiveArray::<Int64Type>::from(foo.into_data());
2239    }
2240
2241    #[test]
2242    fn test_decimal128() {
2243        let values: Vec<_> = vec![0, 1, -1, i128::MIN, i128::MAX];
2244        let array: PrimitiveArray<Decimal128Type> =
2245            PrimitiveArray::from_iter(values.iter().copied());
2246        assert_eq!(array.values(), &values);
2247
2248        let array: PrimitiveArray<Decimal128Type> =
2249            PrimitiveArray::from_iter_values(values.iter().copied());
2250        assert_eq!(array.values(), &values);
2251
2252        let array = PrimitiveArray::<Decimal128Type>::from(values.clone());
2253        assert_eq!(array.values(), &values);
2254
2255        let array = PrimitiveArray::<Decimal128Type>::from(array.to_data());
2256        assert_eq!(array.values(), &values);
2257    }
2258
2259    #[test]
2260    fn test_decimal256() {
2261        let values: Vec<_> = vec![i256::ZERO, i256::ONE, i256::MINUS_ONE, i256::MIN, i256::MAX];
2262
2263        let array: PrimitiveArray<Decimal256Type> =
2264            PrimitiveArray::from_iter(values.iter().copied());
2265        assert_eq!(array.values(), &values);
2266
2267        let array: PrimitiveArray<Decimal256Type> =
2268            PrimitiveArray::from_iter_values(values.iter().copied());
2269        assert_eq!(array.values(), &values);
2270
2271        let array = PrimitiveArray::<Decimal256Type>::from(values.clone());
2272        assert_eq!(array.values(), &values);
2273
2274        let array = PrimitiveArray::<Decimal256Type>::from(array.to_data());
2275        assert_eq!(array.values(), &values);
2276    }
2277
2278    #[test]
2279    fn test_decimal_array() {
2280        // let val_8887: [u8; 16] = [192, 219, 180, 17, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
2281        // let val_neg_8887: [u8; 16] = [64, 36, 75, 238, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255];
2282        let values: [u8; 32] = [
2283            192, 219, 180, 17, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 36, 75, 238, 253, 255, 255,
2284            255, 255, 255, 255, 255, 255, 255, 255, 255,
2285        ];
2286        let array_data = ArrayData::builder(DataType::Decimal128(38, 6))
2287            .len(2)
2288            .add_buffer(Buffer::from(&values))
2289            .build()
2290            .unwrap();
2291        let decimal_array = Decimal128Array::from(array_data);
2292        assert_eq!(8_887_000_000_i128, decimal_array.value(0));
2293        assert_eq!(-8_887_000_000_i128, decimal_array.value(1));
2294    }
2295
2296    #[test]
2297    fn test_decimal_append_error_value() {
2298        let mut decimal_builder = Decimal128Builder::with_capacity(10);
2299        decimal_builder.append_value(123456);
2300        decimal_builder.append_value(12345);
2301        let result = decimal_builder.finish().with_precision_and_scale(5, 3);
2302        assert!(result.is_ok());
2303        let arr = result.unwrap();
2304        assert_eq!("12.345", arr.value_as_string(1));
2305
2306        // Validate it explicitly
2307        let result = arr.validate_decimal_precision(5);
2308        let error = result.unwrap_err();
2309        assert_eq!(
2310            "Invalid argument error: 123456 is too large to store in a Decimal128 of precision 5. Max is 99999",
2311            error.to_string()
2312        );
2313
2314        decimal_builder = Decimal128Builder::new();
2315        decimal_builder.append_value(100);
2316        decimal_builder.append_value(99);
2317        decimal_builder.append_value(-100);
2318        decimal_builder.append_value(-99);
2319        let result = decimal_builder.finish().with_precision_and_scale(2, 1);
2320        assert!(result.is_ok());
2321        let arr = result.unwrap();
2322        assert_eq!("9.9", arr.value_as_string(1));
2323        assert_eq!("-9.9", arr.value_as_string(3));
2324
2325        // Validate it explicitly
2326        let result = arr.validate_decimal_precision(2);
2327        let error = result.unwrap_err();
2328        assert_eq!(
2329            "Invalid argument error: 100 is too large to store in a Decimal128 of precision 2. Max is 99",
2330            error.to_string()
2331        );
2332    }
2333
2334    #[test]
2335    fn test_decimal_from_iter_values() {
2336        let array = Decimal128Array::from_iter_values(vec![-100, 0, 101]);
2337        assert_eq!(array.len(), 3);
2338        assert_eq!(array.data_type(), &DataType::Decimal128(38, 10));
2339        assert_eq!(-100_i128, array.value(0));
2340        assert!(!array.is_null(0));
2341        assert_eq!(0_i128, array.value(1));
2342        assert!(!array.is_null(1));
2343        assert_eq!(101_i128, array.value(2));
2344        assert!(!array.is_null(2));
2345    }
2346
2347    #[test]
2348    fn test_decimal_from_iter() {
2349        let array: Decimal128Array = vec![Some(-100), None, Some(101)].into_iter().collect();
2350        assert_eq!(array.len(), 3);
2351        assert_eq!(array.data_type(), &DataType::Decimal128(38, 10));
2352        assert_eq!(-100_i128, array.value(0));
2353        assert!(!array.is_null(0));
2354        assert!(array.is_null(1));
2355        assert_eq!(101_i128, array.value(2));
2356        assert!(!array.is_null(2));
2357    }
2358
2359    #[test]
2360    fn test_decimal_iter_sized() {
2361        let data = vec![Some(-100), None, Some(101)];
2362        let array: Decimal128Array = data.into_iter().collect();
2363        let mut iter = array.into_iter();
2364
2365        // is exact sized
2366        assert_eq!(array.len(), 3);
2367
2368        // size_hint is reported correctly
2369        assert_eq!(iter.size_hint(), (3, Some(3)));
2370        iter.next().unwrap();
2371        assert_eq!(iter.size_hint(), (2, Some(2)));
2372        iter.next().unwrap();
2373        iter.next().unwrap();
2374        assert_eq!(iter.size_hint(), (0, Some(0)));
2375        assert!(iter.next().is_none());
2376        assert_eq!(iter.size_hint(), (0, Some(0)));
2377    }
2378
2379    #[test]
2380    fn test_decimal_array_value_as_string() {
2381        let arr = [123450, -123450, 100, -100, 10, -10, 0]
2382            .into_iter()
2383            .map(Some)
2384            .collect::<Decimal128Array>()
2385            .with_precision_and_scale(6, 3)
2386            .unwrap();
2387
2388        assert_eq!("123.450", arr.value_as_string(0));
2389        assert_eq!("-123.450", arr.value_as_string(1));
2390        assert_eq!("0.100", arr.value_as_string(2));
2391        assert_eq!("-0.100", arr.value_as_string(3));
2392        assert_eq!("0.010", arr.value_as_string(4));
2393        assert_eq!("-0.010", arr.value_as_string(5));
2394        assert_eq!("0.000", arr.value_as_string(6));
2395    }
2396
2397    #[test]
2398    fn test_decimal_array_with_precision_and_scale() {
2399        let arr = Decimal128Array::from_iter_values([12345, 456, 7890, -123223423432432])
2400            .with_precision_and_scale(20, 2)
2401            .unwrap();
2402
2403        assert_eq!(arr.data_type(), &DataType::Decimal128(20, 2));
2404        assert_eq!(arr.precision(), 20);
2405        assert_eq!(arr.scale(), 2);
2406
2407        let actual: Vec<_> = (0..arr.len()).map(|i| arr.value_as_string(i)).collect();
2408        let expected = vec!["123.45", "4.56", "78.90", "-1232234234324.32"];
2409
2410        assert_eq!(actual, expected);
2411    }
2412
2413    #[test]
2414    #[should_panic(
2415        expected = "-123223423432432 is too small to store in a Decimal128 of precision 5. Min is -99999"
2416    )]
2417    fn test_decimal_array_with_precision_and_scale_out_of_range() {
2418        let arr = Decimal128Array::from_iter_values([12345, 456, 7890, -123223423432432])
2419            // precision is too small to hold value
2420            .with_precision_and_scale(5, 2)
2421            .unwrap();
2422        arr.validate_decimal_precision(5).unwrap();
2423    }
2424
2425    #[test]
2426    #[should_panic(expected = "precision cannot be 0, has to be between [1, 38]")]
2427    fn test_decimal_array_with_precision_zero() {
2428        Decimal128Array::from_iter_values([12345, 456])
2429            .with_precision_and_scale(0, 2)
2430            .unwrap();
2431    }
2432
2433    #[test]
2434    #[should_panic(expected = "precision 40 is greater than max 38")]
2435    fn test_decimal_array_with_precision_and_scale_invalid_precision() {
2436        Decimal128Array::from_iter_values([12345, 456])
2437            .with_precision_and_scale(40, 2)
2438            .unwrap();
2439    }
2440
2441    #[test]
2442    #[should_panic(expected = "scale 40 is greater than max 38")]
2443    fn test_decimal_array_with_precision_and_scale_invalid_scale() {
2444        Decimal128Array::from_iter_values([12345, 456])
2445            .with_precision_and_scale(20, 40)
2446            .unwrap();
2447    }
2448
2449    #[test]
2450    #[should_panic(expected = "scale 10 is greater than precision 4")]
2451    fn test_decimal_array_with_precision_and_scale_invalid_precision_and_scale() {
2452        Decimal128Array::from_iter_values([12345, 456])
2453            .with_precision_and_scale(4, 10)
2454            .unwrap();
2455    }
2456
2457    #[test]
2458    fn test_decimal_array_set_null_if_overflow_with_precision() {
2459        let array = Decimal128Array::from(vec![Some(123456), Some(123), None, Some(123456)]);
2460        let result = array.null_if_overflow_precision(5);
2461        let expected = Decimal128Array::from(vec![None, Some(123), None, None]);
2462        assert_eq!(result, expected);
2463    }
2464
2465    #[test]
2466    fn test_decimal256_iter() {
2467        let mut builder = Decimal256Builder::with_capacity(30);
2468        let decimal1 = i256::from_i128(12345);
2469        builder.append_value(decimal1);
2470
2471        builder.append_null();
2472
2473        let decimal2 = i256::from_i128(56789);
2474        builder.append_value(decimal2);
2475
2476        let array: Decimal256Array = builder.finish().with_precision_and_scale(76, 6).unwrap();
2477
2478        let collected: Vec<_> = array.iter().collect();
2479        assert_eq!(vec![Some(decimal1), None, Some(decimal2)], collected);
2480    }
2481
2482    #[test]
2483    fn test_from_iter_decimal256array() {
2484        let value1 = i256::from_i128(12345);
2485        let value2 = i256::from_i128(56789);
2486
2487        let mut array: Decimal256Array =
2488            vec![Some(value1), None, Some(value2)].into_iter().collect();
2489        array = array.with_precision_and_scale(76, 10).unwrap();
2490        assert_eq!(array.len(), 3);
2491        assert_eq!(array.data_type(), &DataType::Decimal256(76, 10));
2492        assert_eq!(value1, array.value(0));
2493        assert!(!array.is_null(0));
2494        assert!(array.is_null(1));
2495        assert_eq!(value2, array.value(2));
2496        assert!(!array.is_null(2));
2497    }
2498
2499    #[test]
2500    fn test_from_iter_decimal128array() {
2501        let mut array: Decimal128Array = vec![Some(-100), None, Some(101)].into_iter().collect();
2502        array = array.with_precision_and_scale(38, 10).unwrap();
2503        assert_eq!(array.len(), 3);
2504        assert_eq!(array.data_type(), &DataType::Decimal128(38, 10));
2505        assert_eq!(-100_i128, array.value(0));
2506        assert!(!array.is_null(0));
2507        assert!(array.is_null(1));
2508        assert_eq!(101_i128, array.value(2));
2509        assert!(!array.is_null(2));
2510    }
2511
2512    #[test]
2513    fn test_unary_opt() {
2514        let array = Int32Array::from(vec![1, 2, 3, 4, 5, 6, 7]);
2515        let r = array.unary_opt::<_, Int32Type>(|x| (x % 2 != 0).then_some(x));
2516
2517        let expected = Int32Array::from(vec![Some(1), None, Some(3), None, Some(5), None, Some(7)]);
2518        assert_eq!(r, expected);
2519
2520        let r = expected.unary_opt::<_, Int32Type>(|x| (x % 3 != 0).then_some(x));
2521        let expected = Int32Array::from(vec![Some(1), None, None, None, Some(5), None, Some(7)]);
2522        assert_eq!(r, expected);
2523    }
2524
2525    #[test]
2526    #[should_panic(
2527        expected = "Trying to access an element at index 4 from a PrimitiveArray of length 3"
2528    )]
2529    fn test_fixed_size_binary_array_get_value_index_out_of_bound() {
2530        let array = Decimal128Array::from(vec![-100, 0, 101]);
2531        array.value(4);
2532    }
2533
2534    #[test]
2535    fn test_into_builder() {
2536        let array: Int32Array = vec![1, 2, 3].into_iter().map(Some).collect();
2537
2538        let boxed: ArrayRef = Arc::new(array);
2539        let col: Int32Array = downcast_array(&boxed);
2540        drop(boxed);
2541
2542        let mut builder = col.into_builder().unwrap();
2543
2544        let slice = builder.values_slice_mut();
2545        assert_eq!(slice, &[1, 2, 3]);
2546
2547        slice[0] = 4;
2548        slice[1] = 2;
2549        slice[2] = 1;
2550
2551        let expected: Int32Array = vec![Some(4), Some(2), Some(1)].into_iter().collect();
2552
2553        let new_array = builder.finish();
2554        assert_eq!(expected, new_array);
2555    }
2556
2557    #[test]
2558    fn test_into_builder_cloned_array() {
2559        let array: Int32Array = vec![1, 2, 3].into_iter().map(Some).collect();
2560
2561        let boxed: ArrayRef = Arc::new(array);
2562
2563        let col: Int32Array = PrimitiveArray::<Int32Type>::from(boxed.to_data());
2564        let err = col.into_builder();
2565
2566        match err {
2567            Ok(_) => panic!("Should not get builder from cloned array"),
2568            Err(returned) => {
2569                let expected: Int32Array = vec![1, 2, 3].into_iter().map(Some).collect();
2570                assert_eq!(expected, returned)
2571            }
2572        }
2573    }
2574
2575    #[test]
2576    fn test_into_builder_on_sliced_array() {
2577        let array: Int32Array = vec![1, 2, 3].into_iter().map(Some).collect();
2578        let slice = array.slice(1, 2);
2579        let col: Int32Array = downcast_array(&slice);
2580
2581        drop(slice);
2582
2583        col.into_builder()
2584            .expect_err("Should not build builder from sliced array");
2585    }
2586
2587    #[test]
2588    fn test_unary_mut() {
2589        let array: Int32Array = vec![1, 2, 3].into_iter().map(Some).collect();
2590
2591        let c = array.unary_mut(|x| x * 2 + 1).unwrap();
2592        let expected: Int32Array = vec![3, 5, 7].into_iter().map(Some).collect();
2593
2594        assert_eq!(expected, c);
2595
2596        let array: Int32Array = Int32Array::from(vec![Some(5), Some(7), None]);
2597        let c = array.unary_mut(|x| x * 2 + 1).unwrap();
2598        assert_eq!(c, Int32Array::from(vec![Some(11), Some(15), None]));
2599    }
2600
2601    #[test]
2602    #[should_panic(
2603        expected = "PrimitiveArray expected data type Interval(MonthDayNano) got Interval(DayTime)"
2604    )]
2605    fn test_invalid_interval_type() {
2606        let array = IntervalDayTimeArray::from(vec![IntervalDayTime::ZERO]);
2607        let _ = IntervalMonthDayNanoArray::from(array.into_data());
2608    }
2609
2610    #[test]
2611    fn test_timezone() {
2612        let array = TimestampNanosecondArray::from_iter_values([1, 2]);
2613        assert_eq!(array.timezone(), None);
2614
2615        let array = array.with_timezone("+02:00");
2616        assert_eq!(array.timezone(), Some("+02:00"));
2617    }
2618
2619    #[test]
2620    fn test_try_new() {
2621        Int32Array::new(vec![1, 2, 3, 4].into(), None);
2622        Int32Array::new(vec![1, 2, 3, 4].into(), Some(NullBuffer::new_null(4)));
2623
2624        let err = Int32Array::try_new(vec![1, 2, 3, 4].into(), Some(NullBuffer::new_null(3)))
2625            .unwrap_err();
2626
2627        assert_eq!(
2628            err.to_string(),
2629            "Invalid argument error: Incorrect length of null buffer for PrimitiveArray, expected 4 got 3"
2630        );
2631
2632        TimestampNanosecondArray::new(vec![1, 2, 3, 4].into(), None).with_data_type(
2633            DataType::Timestamp(TimeUnit::Nanosecond, Some("03:00".into())),
2634        );
2635    }
2636
2637    #[test]
2638    #[should_panic(expected = "PrimitiveArray expected data type Int32 got Date32")]
2639    fn test_with_data_type() {
2640        Int32Array::new(vec![1, 2, 3, 4].into(), None).with_data_type(DataType::Date32);
2641    }
2642
2643    #[test]
2644    fn test_time_32second_output() {
2645        let array: Time32SecondArray = vec![
2646            Some(-1),
2647            Some(0),
2648            Some(86_399),
2649            Some(86_400),
2650            Some(86_401),
2651            None,
2652        ]
2653        .into();
2654        let debug_str = format!("{:?}", array);
2655        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]",
2656    debug_str
2657    );
2658    }
2659
2660    #[test]
2661    fn test_time_32millisecond_debug_output() {
2662        let array: Time32MillisecondArray = vec![
2663            Some(-1),
2664            Some(0),
2665            Some(86_399_000),
2666            Some(86_400_000),
2667            Some(86_401_000),
2668            None,
2669        ]
2670        .into();
2671        let debug_str = format!("{:?}", array);
2672        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]",
2673            debug_str
2674        );
2675    }
2676
2677    #[test]
2678    fn test_time_64nanosecond_debug_output() {
2679        let array: Time64NanosecondArray = vec![
2680            Some(-1),
2681            Some(0),
2682            Some(86_399 * 1_000_000_000),
2683            Some(86_400 * 1_000_000_000),
2684            Some(86_401 * 1_000_000_000),
2685            None,
2686        ]
2687        .into();
2688        let debug_str = format!("{:?}", array);
2689        assert_eq!(
2690        "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]",
2691            debug_str
2692        );
2693    }
2694
2695    #[test]
2696    fn test_time_64microsecond_debug_output() {
2697        let array: Time64MicrosecondArray = vec![
2698            Some(-1),
2699            Some(0),
2700            Some(86_399 * 1_000_000),
2701            Some(86_400 * 1_000_000),
2702            Some(86_401 * 1_000_000),
2703            None,
2704        ]
2705        .into();
2706        let debug_str = format!("{:?}", array);
2707        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);
2708    }
2709
2710    #[test]
2711    fn test_primitive_with_nulls_into_builder() {
2712        let array: Int32Array = vec![
2713            Some(1),
2714            None,
2715            Some(3),
2716            Some(4),
2717            None,
2718            Some(7),
2719            None,
2720            Some(8),
2721        ]
2722        .into_iter()
2723        .collect();
2724        let _ = array.into_builder();
2725    }
2726}