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        let val_buf: Vec<_> = vec![value; count];
733        Self::new(val_buf.into(), None)
734    }
735
736    /// Returns an iterator that returns the values of `array.value(i)` for an iterator with each element `i`
737    pub fn take_iter<'a>(
738        &'a self,
739        indexes: impl Iterator<Item = Option<usize>> + 'a,
740    ) -> impl Iterator<Item = Option<T::Native>> + 'a {
741        indexes.map(|opt_index| opt_index.map(|index| self.value(index)))
742    }
743
744    /// Returns an iterator that returns the values of `array.value(i)` for an iterator with each element `i`
745    /// # Safety
746    ///
747    /// caller must ensure that the offsets in the iterator are less than the array len()
748    pub unsafe fn take_iter_unchecked<'a>(
749        &'a self,
750        indexes: impl Iterator<Item = Option<usize>> + 'a,
751    ) -> impl Iterator<Item = Option<T::Native>> + 'a {
752        indexes.map(|opt_index| opt_index.map(|index| self.value_unchecked(index)))
753    }
754
755    /// Returns a zero-copy slice of this array with the indicated offset and length.
756    pub fn slice(&self, offset: usize, length: usize) -> Self {
757        Self {
758            data_type: self.data_type.clone(),
759            values: self.values.slice(offset, length),
760            nulls: self.nulls.as_ref().map(|n| n.slice(offset, length)),
761        }
762    }
763
764    /// Reinterprets this array's contents as a different data type without copying
765    ///
766    /// This can be used to efficiently convert between primitive arrays with the
767    /// same underlying representation
768    ///
769    /// Note: this will not modify the underlying values, and therefore may change
770    /// the semantic values of the array, e.g. 100 milliseconds in a [`TimestampNanosecondArray`]
771    /// will become 100 seconds in a [`TimestampSecondArray`].
772    ///
773    /// For casts that preserve the semantic value, check out the
774    /// [compute kernels](https://docs.rs/arrow/latest/arrow/compute/kernels/cast/index.html).
775    ///
776    /// ```
777    /// # use arrow_array::{Int64Array, TimestampNanosecondArray};
778    /// let a = Int64Array::from_iter_values([1, 2, 3, 4]);
779    /// let b: TimestampNanosecondArray = a.reinterpret_cast();
780    /// ```
781    pub fn reinterpret_cast<K>(&self) -> PrimitiveArray<K>
782    where
783        K: ArrowPrimitiveType<Native = T::Native>,
784    {
785        let d = self.to_data().into_builder().data_type(K::DATA_TYPE);
786
787        // SAFETY:
788        // Native type is the same
789        PrimitiveArray::from(unsafe { d.build_unchecked() })
790    }
791
792    /// Applies a unary infallible function to a primitive array, producing a
793    /// new array of potentially different type.
794    ///
795    /// This is the fastest way to perform an operation on a primitive array
796    /// when the benefits of a vectorized operation outweigh the cost of
797    /// branching nulls and non-nulls.
798    ///
799    /// See also
800    /// * [`Self::unary_mut`] for in place modification.
801    /// * [`Self::try_unary`] for fallible operations.
802    /// * [`arrow::compute::binary`] for binary operations
803    ///
804    /// [`arrow::compute::binary`]: https://docs.rs/arrow/latest/arrow/compute/fn.binary.html
805    /// # Null Handling
806    ///
807    /// Applies the function for all values, including those on null slots. This
808    /// will often allow the compiler to generate faster vectorized code, but
809    /// requires that the operation must be infallible (not error/panic) for any
810    /// value of the corresponding type or this function may panic.
811    ///
812    /// # Example
813    /// ```rust
814    /// # use arrow_array::{Int32Array, Float32Array, types::Int32Type};
815    /// # fn main() {
816    /// let array = Int32Array::from(vec![Some(5), Some(7), None]);
817    /// // Create a new array with the value of applying sqrt
818    /// let c = array.unary(|x| f32::sqrt(x as f32));
819    /// assert_eq!(c, Float32Array::from(vec![Some(2.236068), Some(2.6457512), None]));
820    /// # }
821    /// ```
822    pub fn unary<F, O>(&self, op: F) -> PrimitiveArray<O>
823    where
824        O: ArrowPrimitiveType,
825        F: Fn(T::Native) -> O::Native,
826    {
827        let nulls = self.nulls().cloned();
828        let values = self.values().into_iter().map(|v| op(*v));
829        let buffer: Vec<_> = values.collect();
830        PrimitiveArray::new(buffer.into(), nulls)
831    }
832
833    /// Applies a unary and infallible function to the array in place if possible.
834    ///
835    /// # Buffer Reuse
836    ///
837    /// If the underlying buffers are not shared with other arrays,  mutates the
838    /// underlying buffer in place, without allocating.
839    ///
840    /// If the underlying buffer is shared, returns Err(self)
841    ///
842    /// # Null Handling
843    ///
844    /// See [`Self::unary`] for more information on null handling.
845    ///
846    /// # Example
847    ///
848    /// ```rust
849    /// # use arrow_array::{Int32Array, types::Int32Type};
850    /// let array = Int32Array::from(vec![Some(5), Some(7), None]);
851    /// // Apply x*2+1 to the data in place, no allocations
852    /// let c = array.unary_mut(|x| x * 2 + 1).unwrap();
853    /// assert_eq!(c, Int32Array::from(vec![Some(11), Some(15), None]));
854    /// ```
855    ///
856    /// # Example: modify [`ArrayRef`] in place, if not shared
857    ///
858    /// It is also possible to modify an [`ArrayRef`] if there are no other
859    /// references to the underlying buffer.
860    ///
861    /// ```rust
862    /// # use std::sync::Arc;
863    /// # use arrow_array::{Array, cast::AsArray, ArrayRef, Int32Array, PrimitiveArray, types::Int32Type};
864    /// # let array: ArrayRef = Arc::new(Int32Array::from(vec![Some(5), Some(7), None]));
865    /// // Convert to Int32Array (panic's if array.data_type is not Int32)
866    /// let a = array.as_primitive::<Int32Type>().clone();
867    /// // Try to apply x*2+1 to the data in place, fails because array is still shared
868    /// a.unary_mut(|x| x * 2 + 1).unwrap_err();
869    /// // Try again, this time dropping the last remaining reference
870    /// let a = array.as_primitive::<Int32Type>().clone();
871    /// drop(array);
872    /// // Now we can apply the operation in place
873    /// let c = a.unary_mut(|x| x * 2 + 1).unwrap();
874    /// assert_eq!(c, Int32Array::from(vec![Some(11), Some(15), None]));
875    /// ```
876    pub fn unary_mut<F>(self, op: F) -> Result<PrimitiveArray<T>, PrimitiveArray<T>>
877    where
878        F: Fn(T::Native) -> T::Native,
879    {
880        let mut builder = self.into_builder()?;
881        builder
882            .values_slice_mut()
883            .iter_mut()
884            .for_each(|v| *v = op(*v));
885        Ok(builder.finish())
886    }
887
888    /// Applies a unary fallible function to all valid values in a primitive
889    /// array, producing a new array of potentially different type.
890    ///
891    /// Applies `op` to only rows that are valid, which is often significantly
892    /// slower than [`Self::unary`], which should be preferred if `op` is
893    /// fallible.
894    ///
895    /// Note: LLVM is currently unable to effectively vectorize fallible operations
896    pub fn try_unary<F, O, E>(&self, op: F) -> Result<PrimitiveArray<O>, E>
897    where
898        O: ArrowPrimitiveType,
899        F: Fn(T::Native) -> Result<O::Native, E>,
900    {
901        let len = self.len();
902
903        let nulls = self.nulls().cloned();
904        let mut buffer = BufferBuilder::<O::Native>::new(len);
905        buffer.append_n_zeroed(len);
906        let slice = buffer.as_slice_mut();
907
908        let f = |idx| {
909            unsafe { *slice.get_unchecked_mut(idx) = op(self.value_unchecked(idx))? };
910            Ok::<_, E>(())
911        };
912
913        match &nulls {
914            Some(nulls) => nulls.try_for_each_valid_idx(f)?,
915            None => (0..len).try_for_each(f)?,
916        }
917
918        let values = buffer.finish().into();
919        Ok(PrimitiveArray::new(values, nulls))
920    }
921
922    /// Applies a unary fallible function to all valid values in a mutable
923    /// primitive array.
924    ///
925    /// # Null Handling
926    ///
927    /// See [`Self::try_unary`] for more information on null handling.
928    ///
929    /// # Buffer Reuse
930    ///
931    /// See [`Self::unary_mut`] for more information on buffer reuse.
932    ///
933    /// This returns an `Err` when the input array is shared buffer with other
934    /// array. In the case, returned `Err` wraps input array. If the function
935    /// encounters an error during applying on values. In the case, this returns an `Err` within
936    /// an `Ok` which wraps the actual error.
937    ///
938    /// Note: LLVM is currently unable to effectively vectorize fallible operations
939    pub fn try_unary_mut<F, E>(
940        self,
941        op: F,
942    ) -> Result<Result<PrimitiveArray<T>, E>, PrimitiveArray<T>>
943    where
944        F: Fn(T::Native) -> Result<T::Native, E>,
945    {
946        let len = self.len();
947        let null_count = self.null_count();
948        let mut builder = self.into_builder()?;
949
950        let (slice, null_buffer) = builder.slices_mut();
951
952        let r = try_for_each_valid_idx(len, 0, null_count, null_buffer.as_deref(), |idx| {
953            unsafe { *slice.get_unchecked_mut(idx) = op(*slice.get_unchecked(idx))? };
954            Ok::<_, E>(())
955        });
956
957        if let Err(err) = r {
958            return Ok(Err(err));
959        }
960
961        Ok(Ok(builder.finish()))
962    }
963
964    /// Applies a unary and nullable function to all valid values in a primitive array
965    ///
966    /// Applies `op` to only rows that are valid, which is often significantly
967    /// slower than [`Self::unary`], which should be preferred if `op` is
968    /// fallible.
969    ///
970    /// Note: LLVM is currently unable to effectively vectorize fallible operations
971    pub fn unary_opt<F, O>(&self, op: F) -> PrimitiveArray<O>
972    where
973        O: ArrowPrimitiveType,
974        F: Fn(T::Native) -> Option<O::Native>,
975    {
976        let len = self.len();
977        let (nulls, null_count, offset) = match self.nulls() {
978            Some(n) => (Some(n.validity()), n.null_count(), n.offset()),
979            None => (None, 0, 0),
980        };
981
982        let mut null_builder = BooleanBufferBuilder::new(len);
983        match nulls {
984            Some(b) => null_builder.append_packed_range(offset..offset + len, b),
985            None => null_builder.append_n(len, true),
986        }
987
988        let mut buffer = BufferBuilder::<O::Native>::new(len);
989        buffer.append_n_zeroed(len);
990        let slice = buffer.as_slice_mut();
991
992        let mut out_null_count = null_count;
993
994        let _ = try_for_each_valid_idx(len, offset, null_count, nulls, |idx| {
995            match op(unsafe { self.value_unchecked(idx) }) {
996                Some(v) => unsafe { *slice.get_unchecked_mut(idx) = v },
997                None => {
998                    out_null_count += 1;
999                    null_builder.set_bit(idx, false);
1000                }
1001            }
1002            Ok::<_, ()>(())
1003        });
1004
1005        let nulls = null_builder.finish();
1006        let values = buffer.finish().into();
1007        let nulls = unsafe { NullBuffer::new_unchecked(nulls, out_null_count) };
1008        PrimitiveArray::new(values, Some(nulls))
1009    }
1010
1011    /// Applies a unary infallible function to each value in an array, producing a
1012    /// new primitive array.
1013    ///
1014    /// # Null Handling
1015    ///
1016    /// See [`Self::unary`] for more information on null handling.
1017    ///
1018    /// # Example: create an [`Int16Array`] from an [`ArrayAccessor`] with item type `&[u8]`
1019    /// ```
1020    /// use arrow_array::{Array, FixedSizeBinaryArray, Int16Array};
1021    /// let input_arg = vec![ vec![1, 0], vec![2, 0], vec![3, 0] ];
1022    /// let arr = FixedSizeBinaryArray::try_from_iter(input_arg.into_iter()).unwrap();
1023    /// let c = Int16Array::from_unary(&arr, |x| i16::from_le_bytes(x[..2].try_into().unwrap()));
1024    /// assert_eq!(c, Int16Array::from(vec![Some(1i16), Some(2i16), Some(3i16)]));
1025    /// ```
1026    pub fn from_unary<U: ArrayAccessor, F>(left: U, mut op: F) -> Self
1027    where
1028        F: FnMut(U::Item) -> T::Native,
1029    {
1030        let nulls = left.logical_nulls();
1031        let buffer: Vec<_> = (0..left.len())
1032            // SAFETY: i in range 0..left.len()
1033            .map(|i| op(unsafe { left.value_unchecked(i) }))
1034            .collect();
1035        PrimitiveArray::new(buffer.into(), nulls)
1036    }
1037
1038    /// Returns a `PrimitiveBuilder` for this array, suitable for mutating values
1039    /// in place.
1040    ///
1041    /// # Buffer Reuse
1042    ///
1043    /// If the underlying data buffer has no other outstanding references, the
1044    /// buffer is used without copying.
1045    ///
1046    /// If the underlying data buffer does have outstanding references, returns
1047    /// `Err(self)`
1048    pub fn into_builder(self) -> Result<PrimitiveBuilder<T>, Self> {
1049        let len = self.len();
1050        let data = self.into_data();
1051        let null_bit_buffer = data.nulls().map(|b| b.inner().sliced());
1052
1053        let element_len = std::mem::size_of::<T::Native>();
1054        let buffer =
1055            data.buffers()[0].slice_with_length(data.offset() * element_len, len * element_len);
1056
1057        drop(data);
1058
1059        let try_mutable_null_buffer = match null_bit_buffer {
1060            None => Ok(None),
1061            Some(null_buffer) => {
1062                // Null buffer exists, tries to make it mutable
1063                null_buffer.into_mutable().map(Some)
1064            }
1065        };
1066
1067        let try_mutable_buffers = match try_mutable_null_buffer {
1068            Ok(mutable_null_buffer) => {
1069                // Got mutable null buffer, tries to get mutable value buffer
1070                let try_mutable_buffer = buffer.into_mutable();
1071
1072                // try_mutable_buffer.map(...).map_err(...) doesn't work as the compiler complains
1073                // mutable_null_buffer is moved into map closure.
1074                match try_mutable_buffer {
1075                    Ok(mutable_buffer) => Ok(PrimitiveBuilder::<T>::new_from_buffer(
1076                        mutable_buffer,
1077                        mutable_null_buffer,
1078                    )),
1079                    Err(buffer) => Err((buffer, mutable_null_buffer.map(|b| b.into()))),
1080                }
1081            }
1082            Err(mutable_null_buffer) => {
1083                // Unable to get mutable null buffer
1084                Err((buffer, Some(mutable_null_buffer)))
1085            }
1086        };
1087
1088        match try_mutable_buffers {
1089            Ok(builder) => Ok(builder),
1090            Err((buffer, null_bit_buffer)) => {
1091                let builder = ArrayData::builder(T::DATA_TYPE)
1092                    .len(len)
1093                    .add_buffer(buffer)
1094                    .null_bit_buffer(null_bit_buffer);
1095
1096                let array_data = unsafe { builder.build_unchecked() };
1097                let array = PrimitiveArray::<T>::from(array_data);
1098
1099                Err(array)
1100            }
1101        }
1102    }
1103}
1104
1105impl<T: ArrowPrimitiveType> From<PrimitiveArray<T>> for ArrayData {
1106    fn from(array: PrimitiveArray<T>) -> Self {
1107        let builder = ArrayDataBuilder::new(array.data_type)
1108            .len(array.values.len())
1109            .nulls(array.nulls)
1110            .buffers(vec![array.values.into_inner()]);
1111
1112        unsafe { builder.build_unchecked() }
1113    }
1114}
1115
1116impl<T: ArrowPrimitiveType> Array for PrimitiveArray<T> {
1117    fn as_any(&self) -> &dyn Any {
1118        self
1119    }
1120
1121    fn to_data(&self) -> ArrayData {
1122        self.clone().into()
1123    }
1124
1125    fn into_data(self) -> ArrayData {
1126        self.into()
1127    }
1128
1129    fn data_type(&self) -> &DataType {
1130        &self.data_type
1131    }
1132
1133    fn slice(&self, offset: usize, length: usize) -> ArrayRef {
1134        Arc::new(self.slice(offset, length))
1135    }
1136
1137    fn len(&self) -> usize {
1138        self.values.len()
1139    }
1140
1141    fn is_empty(&self) -> bool {
1142        self.values.is_empty()
1143    }
1144
1145    fn shrink_to_fit(&mut self) {
1146        self.values.shrink_to_fit();
1147        if let Some(nulls) = &mut self.nulls {
1148            nulls.shrink_to_fit();
1149        }
1150    }
1151
1152    fn offset(&self) -> usize {
1153        0
1154    }
1155
1156    fn nulls(&self) -> Option<&NullBuffer> {
1157        self.nulls.as_ref()
1158    }
1159
1160    fn logical_null_count(&self) -> usize {
1161        self.null_count()
1162    }
1163
1164    fn get_buffer_memory_size(&self) -> usize {
1165        let mut size = self.values.inner().capacity();
1166        if let Some(n) = self.nulls.as_ref() {
1167            size += n.buffer().capacity();
1168        }
1169        size
1170    }
1171
1172    fn get_array_memory_size(&self) -> usize {
1173        std::mem::size_of::<Self>() + self.get_buffer_memory_size()
1174    }
1175}
1176
1177impl<T: ArrowPrimitiveType> ArrayAccessor for &PrimitiveArray<T> {
1178    type Item = T::Native;
1179
1180    fn value(&self, index: usize) -> Self::Item {
1181        PrimitiveArray::value(self, index)
1182    }
1183
1184    #[inline]
1185    unsafe fn value_unchecked(&self, index: usize) -> Self::Item {
1186        PrimitiveArray::value_unchecked(self, index)
1187    }
1188}
1189
1190impl<T: ArrowTemporalType> PrimitiveArray<T>
1191where
1192    i64: From<T::Native>,
1193{
1194    /// Returns value as a chrono `NaiveDateTime`, handling time resolution
1195    ///
1196    /// If a data type cannot be converted to `NaiveDateTime`, a `None` is returned.
1197    /// A valid value is expected, thus the user should first check for validity.
1198    pub fn value_as_datetime(&self, i: usize) -> Option<NaiveDateTime> {
1199        as_datetime::<T>(i64::from(self.value(i)))
1200    }
1201
1202    /// Returns value as a chrono `NaiveDateTime`, handling time resolution with the provided tz
1203    ///
1204    /// functionally it is same as `value_as_datetime`, however it adds
1205    /// the passed tz to the to-be-returned NaiveDateTime
1206    pub fn value_as_datetime_with_tz(&self, i: usize, tz: Tz) -> Option<DateTime<Tz>> {
1207        as_datetime_with_timezone::<T>(i64::from(self.value(i)), tz)
1208    }
1209
1210    /// Returns value as a chrono `NaiveDate` by using `Self::datetime()`
1211    ///
1212    /// If a data type cannot be converted to `NaiveDate`, a `None` is returned
1213    pub fn value_as_date(&self, i: usize) -> Option<NaiveDate> {
1214        self.value_as_datetime(i).map(|datetime| datetime.date())
1215    }
1216
1217    /// Returns a value as a chrono `NaiveTime`
1218    ///
1219    /// `Date32` and `Date64` return UTC midnight as they do not have time resolution
1220    pub fn value_as_time(&self, i: usize) -> Option<NaiveTime> {
1221        as_time::<T>(i64::from(self.value(i)))
1222    }
1223
1224    /// Returns a value as a chrono `Duration`
1225    ///
1226    /// If a data type cannot be converted to `Duration`, a `None` is returned
1227    pub fn value_as_duration(&self, i: usize) -> Option<Duration> {
1228        as_duration::<T>(i64::from(self.value(i)))
1229    }
1230}
1231
1232impl<T: ArrowPrimitiveType> std::fmt::Debug for PrimitiveArray<T> {
1233    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
1234        let data_type = self.data_type();
1235
1236        write!(f, "PrimitiveArray<{data_type:?}>\n[\n")?;
1237        print_long_array(self, f, |array, index, f| match data_type {
1238            DataType::Date32 | DataType::Date64 => {
1239                let v = self.value(index).to_i64().unwrap();
1240                match as_date::<T>(v) {
1241                    Some(date) => write!(f, "{date:?}"),
1242                    None => {
1243                        write!(
1244                            f,
1245                            "Cast error: Failed to convert {v} to temporal for {data_type:?}"
1246                        )
1247                    }
1248                }
1249            }
1250            DataType::Time32(_) | DataType::Time64(_) => {
1251                let v = self.value(index).to_i64().unwrap();
1252                match as_time::<T>(v) {
1253                    Some(time) => write!(f, "{time:?}"),
1254                    None => {
1255                        write!(
1256                            f,
1257                            "Cast error: Failed to convert {v} to temporal for {data_type:?}"
1258                        )
1259                    }
1260                }
1261            }
1262            DataType::Timestamp(_, tz_string_opt) => {
1263                let v = self.value(index).to_i64().unwrap();
1264                match tz_string_opt {
1265                    // for Timestamp with TimeZone
1266                    Some(tz_string) => {
1267                        match tz_string.parse::<Tz>() {
1268                            // if the time zone is valid, construct a DateTime<Tz> and format it as rfc3339
1269                            Ok(tz) => match as_datetime_with_timezone::<T>(v, tz) {
1270                                Some(datetime) => write!(f, "{}", datetime.to_rfc3339()),
1271                                None => write!(f, "null"),
1272                            },
1273                            // if the time zone is invalid, shows NaiveDateTime with an error message
1274                            Err(_) => match as_datetime::<T>(v) {
1275                                Some(datetime) => {
1276                                    write!(f, "{datetime:?} (Unknown Time Zone '{tz_string}')")
1277                                }
1278                                None => write!(f, "null"),
1279                            },
1280                        }
1281                    }
1282                    // for Timestamp without TimeZone
1283                    None => match as_datetime::<T>(v) {
1284                        Some(datetime) => write!(f, "{datetime:?}"),
1285                        None => write!(f, "null"),
1286                    },
1287                }
1288            }
1289            _ => std::fmt::Debug::fmt(&array.value(index), f),
1290        })?;
1291        write!(f, "]")
1292    }
1293}
1294
1295impl<'a, T: ArrowPrimitiveType> IntoIterator for &'a PrimitiveArray<T> {
1296    type Item = Option<<T as ArrowPrimitiveType>::Native>;
1297    type IntoIter = PrimitiveIter<'a, T>;
1298
1299    fn into_iter(self) -> Self::IntoIter {
1300        PrimitiveIter::<'a, T>::new(self)
1301    }
1302}
1303
1304impl<'a, T: ArrowPrimitiveType> PrimitiveArray<T> {
1305    /// constructs a new iterator
1306    pub fn iter(&'a self) -> PrimitiveIter<'a, T> {
1307        PrimitiveIter::<'a, T>::new(self)
1308    }
1309}
1310
1311/// An optional primitive value
1312///
1313/// This struct is used as an adapter when creating `PrimitiveArray` from an iterator.
1314/// `FromIterator` for `PrimitiveArray` takes an iterator where the elements can be `into`
1315/// this struct. So once implementing `From` or `Into` trait for a type, an iterator of
1316/// the type can be collected to `PrimitiveArray`.
1317#[derive(Debug)]
1318pub struct NativeAdapter<T: ArrowPrimitiveType> {
1319    /// Corresponding Rust native type if available
1320    pub native: Option<T::Native>,
1321}
1322
1323macro_rules! def_from_for_primitive {
1324    ( $ty:ident, $tt:tt) => {
1325        impl From<$tt> for NativeAdapter<$ty> {
1326            fn from(value: $tt) -> Self {
1327                NativeAdapter {
1328                    native: Some(value),
1329                }
1330            }
1331        }
1332    };
1333}
1334
1335def_from_for_primitive!(Int8Type, i8);
1336def_from_for_primitive!(Int16Type, i16);
1337def_from_for_primitive!(Int32Type, i32);
1338def_from_for_primitive!(Int64Type, i64);
1339def_from_for_primitive!(UInt8Type, u8);
1340def_from_for_primitive!(UInt16Type, u16);
1341def_from_for_primitive!(UInt32Type, u32);
1342def_from_for_primitive!(UInt64Type, u64);
1343def_from_for_primitive!(Float16Type, f16);
1344def_from_for_primitive!(Float32Type, f32);
1345def_from_for_primitive!(Float64Type, f64);
1346def_from_for_primitive!(Decimal128Type, i128);
1347def_from_for_primitive!(Decimal256Type, i256);
1348
1349impl<T: ArrowPrimitiveType> From<Option<<T as ArrowPrimitiveType>::Native>> for NativeAdapter<T> {
1350    fn from(value: Option<<T as ArrowPrimitiveType>::Native>) -> Self {
1351        NativeAdapter { native: value }
1352    }
1353}
1354
1355impl<T: ArrowPrimitiveType> From<&Option<<T as ArrowPrimitiveType>::Native>> for NativeAdapter<T> {
1356    fn from(value: &Option<<T as ArrowPrimitiveType>::Native>) -> Self {
1357        NativeAdapter { native: *value }
1358    }
1359}
1360
1361impl<T: ArrowPrimitiveType, Ptr: Into<NativeAdapter<T>>> FromIterator<Ptr> for PrimitiveArray<T> {
1362    fn from_iter<I: IntoIterator<Item = Ptr>>(iter: I) -> Self {
1363        let iter = iter.into_iter();
1364        let (lower, _) = iter.size_hint();
1365
1366        let mut null_builder = BooleanBufferBuilder::new(lower);
1367
1368        let buffer: Buffer = iter
1369            .map(|item| {
1370                if let Some(a) = item.into().native {
1371                    null_builder.append(true);
1372                    a
1373                } else {
1374                    null_builder.append(false);
1375                    // this ensures that null items on the buffer are not arbitrary.
1376                    // This is important because fallible operations can use null values (e.g. a vectorized "add")
1377                    // which may panic (e.g. overflow if the number on the slots happen to be very large).
1378                    T::Native::default()
1379                }
1380            })
1381            .collect();
1382
1383        let len = null_builder.len();
1384
1385        let data = unsafe {
1386            ArrayData::new_unchecked(
1387                T::DATA_TYPE,
1388                len,
1389                None,
1390                Some(null_builder.into()),
1391                0,
1392                vec![buffer],
1393                vec![],
1394            )
1395        };
1396        PrimitiveArray::from(data)
1397    }
1398}
1399
1400impl<T: ArrowPrimitiveType> PrimitiveArray<T> {
1401    /// Creates a [`PrimitiveArray`] from an iterator of trusted length.
1402    /// # Safety
1403    /// The iterator must be [`TrustedLen`](https://doc.rust-lang.org/std/iter/trait.TrustedLen.html).
1404    /// I.e. that `size_hint().1` correctly reports its length.
1405    #[inline]
1406    pub unsafe fn from_trusted_len_iter<I, P>(iter: I) -> Self
1407    where
1408        P: std::borrow::Borrow<Option<<T as ArrowPrimitiveType>::Native>>,
1409        I: IntoIterator<Item = P>,
1410    {
1411        let iterator = iter.into_iter();
1412        let (_, upper) = iterator.size_hint();
1413        let len = upper.expect("trusted_len_unzip requires an upper limit");
1414
1415        let (null, buffer) = trusted_len_unzip(iterator);
1416
1417        let data =
1418            ArrayData::new_unchecked(T::DATA_TYPE, len, None, Some(null), 0, vec![buffer], vec![]);
1419        PrimitiveArray::from(data)
1420    }
1421}
1422
1423// TODO: the macro is needed here because we'd get "conflicting implementations" error
1424// otherwise with both `From<Vec<T::Native>>` and `From<Vec<Option<T::Native>>>`.
1425// We should revisit this in future.
1426macro_rules! def_numeric_from_vec {
1427    ( $ty:ident ) => {
1428        impl From<Vec<<$ty as ArrowPrimitiveType>::Native>> for PrimitiveArray<$ty> {
1429            fn from(data: Vec<<$ty as ArrowPrimitiveType>::Native>) -> Self {
1430                let array_data = ArrayData::builder($ty::DATA_TYPE)
1431                    .len(data.len())
1432                    .add_buffer(Buffer::from_vec(data));
1433                let array_data = unsafe { array_data.build_unchecked() };
1434                PrimitiveArray::from(array_data)
1435            }
1436        }
1437
1438        // Constructs a primitive array from a vector. Should only be used for testing.
1439        impl From<Vec<Option<<$ty as ArrowPrimitiveType>::Native>>> for PrimitiveArray<$ty> {
1440            fn from(data: Vec<Option<<$ty as ArrowPrimitiveType>::Native>>) -> Self {
1441                PrimitiveArray::from_iter(data.iter())
1442            }
1443        }
1444    };
1445}
1446
1447def_numeric_from_vec!(Int8Type);
1448def_numeric_from_vec!(Int16Type);
1449def_numeric_from_vec!(Int32Type);
1450def_numeric_from_vec!(Int64Type);
1451def_numeric_from_vec!(UInt8Type);
1452def_numeric_from_vec!(UInt16Type);
1453def_numeric_from_vec!(UInt32Type);
1454def_numeric_from_vec!(UInt64Type);
1455def_numeric_from_vec!(Float16Type);
1456def_numeric_from_vec!(Float32Type);
1457def_numeric_from_vec!(Float64Type);
1458def_numeric_from_vec!(Decimal128Type);
1459def_numeric_from_vec!(Decimal256Type);
1460
1461def_numeric_from_vec!(Date32Type);
1462def_numeric_from_vec!(Date64Type);
1463def_numeric_from_vec!(Time32SecondType);
1464def_numeric_from_vec!(Time32MillisecondType);
1465def_numeric_from_vec!(Time64MicrosecondType);
1466def_numeric_from_vec!(Time64NanosecondType);
1467def_numeric_from_vec!(IntervalYearMonthType);
1468def_numeric_from_vec!(IntervalDayTimeType);
1469def_numeric_from_vec!(IntervalMonthDayNanoType);
1470def_numeric_from_vec!(DurationSecondType);
1471def_numeric_from_vec!(DurationMillisecondType);
1472def_numeric_from_vec!(DurationMicrosecondType);
1473def_numeric_from_vec!(DurationNanosecondType);
1474def_numeric_from_vec!(TimestampSecondType);
1475def_numeric_from_vec!(TimestampMillisecondType);
1476def_numeric_from_vec!(TimestampMicrosecondType);
1477def_numeric_from_vec!(TimestampNanosecondType);
1478
1479impl<T: ArrowTimestampType> PrimitiveArray<T> {
1480    /// Returns the timezone of this array if any
1481    pub fn timezone(&self) -> Option<&str> {
1482        match self.data_type() {
1483            DataType::Timestamp(_, tz) => tz.as_deref(),
1484            _ => unreachable!(),
1485        }
1486    }
1487
1488    /// Construct a timestamp array with new timezone
1489    pub fn with_timezone(self, timezone: impl Into<Arc<str>>) -> Self {
1490        self.with_timezone_opt(Some(timezone.into()))
1491    }
1492
1493    /// Construct a timestamp array with UTC
1494    pub fn with_timezone_utc(self) -> Self {
1495        self.with_timezone("+00:00")
1496    }
1497
1498    /// Construct a timestamp array with an optional timezone
1499    pub fn with_timezone_opt<S: Into<Arc<str>>>(self, timezone: Option<S>) -> Self {
1500        Self {
1501            data_type: DataType::Timestamp(T::UNIT, timezone.map(Into::into)),
1502            ..self
1503        }
1504    }
1505}
1506
1507/// Constructs a `PrimitiveArray` from an array data reference.
1508impl<T: ArrowPrimitiveType> From<ArrayData> for PrimitiveArray<T> {
1509    fn from(data: ArrayData) -> Self {
1510        Self::assert_compatible(data.data_type());
1511        assert_eq!(
1512            data.buffers().len(),
1513            1,
1514            "PrimitiveArray data should contain a single buffer only (values buffer)"
1515        );
1516
1517        let values = ScalarBuffer::new(data.buffers()[0].clone(), data.offset(), data.len());
1518        Self {
1519            data_type: data.data_type().clone(),
1520            values,
1521            nulls: data.nulls().cloned(),
1522        }
1523    }
1524}
1525
1526impl<T: DecimalType + ArrowPrimitiveType> PrimitiveArray<T> {
1527    /// Returns a Decimal array with the same data as self, with the
1528    /// specified precision and scale.
1529    ///
1530    /// See [`validate_decimal_precision_and_scale`]
1531    pub fn with_precision_and_scale(self, precision: u8, scale: i8) -> Result<Self, ArrowError> {
1532        validate_decimal_precision_and_scale::<T>(precision, scale)?;
1533        Ok(Self {
1534            data_type: T::TYPE_CONSTRUCTOR(precision, scale),
1535            ..self
1536        })
1537    }
1538
1539    /// Validates values in this array can be properly interpreted
1540    /// with the specified precision.
1541    pub fn validate_decimal_precision(&self, precision: u8) -> Result<(), ArrowError> {
1542        (0..self.len()).try_for_each(|idx| {
1543            if self.is_valid(idx) {
1544                let decimal = unsafe { self.value_unchecked(idx) };
1545                T::validate_decimal_precision(decimal, precision)
1546            } else {
1547                Ok(())
1548            }
1549        })
1550    }
1551
1552    /// Validates the Decimal Array, if the value of slot is overflow for the specified precision, and
1553    /// will be casted to Null
1554    pub fn null_if_overflow_precision(&self, precision: u8) -> Self {
1555        self.unary_opt::<_, T>(|v| T::is_valid_decimal_precision(v, precision).then_some(v))
1556    }
1557
1558    /// Returns [`Self::value`] formatted as a string
1559    pub fn value_as_string(&self, row: usize) -> String {
1560        T::format_decimal(self.value(row), self.precision(), self.scale())
1561    }
1562
1563    /// Returns the decimal precision of this array
1564    pub fn precision(&self) -> u8 {
1565        match T::BYTE_LENGTH {
1566            16 => {
1567                if let DataType::Decimal128(p, _) = self.data_type() {
1568                    *p
1569                } else {
1570                    unreachable!(
1571                        "Decimal128Array datatype is not DataType::Decimal128 but {}",
1572                        self.data_type()
1573                    )
1574                }
1575            }
1576            32 => {
1577                if let DataType::Decimal256(p, _) = self.data_type() {
1578                    *p
1579                } else {
1580                    unreachable!(
1581                        "Decimal256Array datatype is not DataType::Decimal256 but {}",
1582                        self.data_type()
1583                    )
1584                }
1585            }
1586            other => unreachable!("Unsupported byte length for decimal array {}", other),
1587        }
1588    }
1589
1590    /// Returns the decimal scale of this array
1591    pub fn scale(&self) -> i8 {
1592        match T::BYTE_LENGTH {
1593            16 => {
1594                if let DataType::Decimal128(_, s) = self.data_type() {
1595                    *s
1596                } else {
1597                    unreachable!(
1598                        "Decimal128Array datatype is not DataType::Decimal128 but {}",
1599                        self.data_type()
1600                    )
1601                }
1602            }
1603            32 => {
1604                if let DataType::Decimal256(_, s) = self.data_type() {
1605                    *s
1606                } else {
1607                    unreachable!(
1608                        "Decimal256Array datatype is not DataType::Decimal256 but {}",
1609                        self.data_type()
1610                    )
1611                }
1612            }
1613            other => unreachable!("Unsupported byte length for decimal array {}", other),
1614        }
1615    }
1616}
1617
1618#[cfg(test)]
1619mod tests {
1620    use super::*;
1621    use crate::builder::{Decimal128Builder, Decimal256Builder};
1622    use crate::cast::downcast_array;
1623    use crate::BooleanArray;
1624    use arrow_buffer::{IntervalDayTime, IntervalMonthDayNano};
1625    use arrow_schema::TimeUnit;
1626
1627    #[test]
1628    fn test_primitive_array_from_vec() {
1629        let buf = Buffer::from_slice_ref([0, 1, 2, 3, 4]);
1630        let arr = Int32Array::from(vec![0, 1, 2, 3, 4]);
1631        assert_eq!(&buf, arr.values.inner());
1632        assert_eq!(5, arr.len());
1633        assert_eq!(0, arr.offset());
1634        assert_eq!(0, arr.null_count());
1635        for i in 0..5 {
1636            assert!(!arr.is_null(i));
1637            assert!(arr.is_valid(i));
1638            assert_eq!(i as i32, arr.value(i));
1639        }
1640    }
1641
1642    #[test]
1643    fn test_primitive_array_from_vec_option() {
1644        // Test building a primitive array with null values
1645        let arr = Int32Array::from(vec![Some(0), None, Some(2), None, Some(4)]);
1646        assert_eq!(5, arr.len());
1647        assert_eq!(0, arr.offset());
1648        assert_eq!(2, arr.null_count());
1649        for i in 0..5 {
1650            if i % 2 == 0 {
1651                assert!(!arr.is_null(i));
1652                assert!(arr.is_valid(i));
1653                assert_eq!(i as i32, arr.value(i));
1654            } else {
1655                assert!(arr.is_null(i));
1656                assert!(!arr.is_valid(i));
1657            }
1658        }
1659    }
1660
1661    #[test]
1662    fn test_date64_array_from_vec_option() {
1663        // Test building a primitive array with null values
1664        // we use Int32 and Int64 as a backing array, so all Int32 and Int64 conventions
1665        // work
1666        let arr: PrimitiveArray<Date64Type> =
1667            vec![Some(1550902545147), None, Some(1550902545147)].into();
1668        assert_eq!(3, arr.len());
1669        assert_eq!(0, arr.offset());
1670        assert_eq!(1, arr.null_count());
1671        for i in 0..3 {
1672            if i % 2 == 0 {
1673                assert!(!arr.is_null(i));
1674                assert!(arr.is_valid(i));
1675                assert_eq!(1550902545147, arr.value(i));
1676                // roundtrip to and from datetime
1677                assert_eq!(
1678                    1550902545147,
1679                    arr.value_as_datetime(i)
1680                        .unwrap()
1681                        .and_utc()
1682                        .timestamp_millis()
1683                );
1684            } else {
1685                assert!(arr.is_null(i));
1686                assert!(!arr.is_valid(i));
1687            }
1688        }
1689    }
1690
1691    #[test]
1692    fn test_time32_millisecond_array_from_vec() {
1693        // 1:        00:00:00.001
1694        // 37800005: 10:30:00.005
1695        // 86399210: 23:59:59.210
1696        let arr: PrimitiveArray<Time32MillisecondType> = vec![1, 37_800_005, 86_399_210].into();
1697        assert_eq!(3, arr.len());
1698        assert_eq!(0, arr.offset());
1699        assert_eq!(0, arr.null_count());
1700        let formatted = ["00:00:00.001", "10:30:00.005", "23:59:59.210"];
1701        for (i, formatted) in formatted.iter().enumerate().take(3) {
1702            // check that we can't create dates or datetimes from time instances
1703            assert_eq!(None, arr.value_as_datetime(i));
1704            assert_eq!(None, arr.value_as_date(i));
1705            let time = arr.value_as_time(i).unwrap();
1706            assert_eq!(*formatted, time.format("%H:%M:%S%.3f").to_string());
1707        }
1708    }
1709
1710    #[test]
1711    fn test_time64_nanosecond_array_from_vec() {
1712        // Test building a primitive array with null values
1713        // we use Int32 and Int64 as a backing array, so all Int32 and Int64 conventions
1714        // work
1715
1716        // 1e6:        00:00:00.001
1717        // 37800005e6: 10:30:00.005
1718        // 86399210e6: 23:59:59.210
1719        let arr: PrimitiveArray<Time64NanosecondType> =
1720            vec![1_000_000, 37_800_005_000_000, 86_399_210_000_000].into();
1721        assert_eq!(3, arr.len());
1722        assert_eq!(0, arr.offset());
1723        assert_eq!(0, arr.null_count());
1724        let formatted = ["00:00:00.001", "10:30:00.005", "23:59:59.210"];
1725        for (i, item) in formatted.iter().enumerate().take(3) {
1726            // check that we can't create dates or datetimes from time instances
1727            assert_eq!(None, arr.value_as_datetime(i));
1728            assert_eq!(None, arr.value_as_date(i));
1729            let time = arr.value_as_time(i).unwrap();
1730            assert_eq!(*item, time.format("%H:%M:%S%.3f").to_string());
1731        }
1732    }
1733
1734    #[test]
1735    fn test_interval_array_from_vec() {
1736        // intervals are currently not treated specially, but are Int32 and Int64 arrays
1737        let arr = IntervalYearMonthArray::from(vec![Some(1), None, Some(-5)]);
1738        assert_eq!(3, arr.len());
1739        assert_eq!(0, arr.offset());
1740        assert_eq!(1, arr.null_count());
1741        assert_eq!(1, arr.value(0));
1742        assert_eq!(1, arr.values()[0]);
1743        assert!(arr.is_null(1));
1744        assert_eq!(-5, arr.value(2));
1745        assert_eq!(-5, arr.values()[2]);
1746
1747        let v0 = IntervalDayTime {
1748            days: 34,
1749            milliseconds: 1,
1750        };
1751        let v2 = IntervalDayTime {
1752            days: -2,
1753            milliseconds: -5,
1754        };
1755
1756        let arr = IntervalDayTimeArray::from(vec![Some(v0), None, Some(v2)]);
1757
1758        assert_eq!(3, arr.len());
1759        assert_eq!(0, arr.offset());
1760        assert_eq!(1, arr.null_count());
1761        assert_eq!(v0, arr.value(0));
1762        assert_eq!(v0, arr.values()[0]);
1763        assert!(arr.is_null(1));
1764        assert_eq!(v2, arr.value(2));
1765        assert_eq!(v2, arr.values()[2]);
1766
1767        let v0 = IntervalMonthDayNano {
1768            months: 2,
1769            days: 34,
1770            nanoseconds: -1,
1771        };
1772        let v2 = IntervalMonthDayNano {
1773            months: -3,
1774            days: -2,
1775            nanoseconds: 4,
1776        };
1777
1778        let arr = IntervalMonthDayNanoArray::from(vec![Some(v0), None, Some(v2)]);
1779        assert_eq!(3, arr.len());
1780        assert_eq!(0, arr.offset());
1781        assert_eq!(1, arr.null_count());
1782        assert_eq!(v0, arr.value(0));
1783        assert_eq!(v0, arr.values()[0]);
1784        assert!(arr.is_null(1));
1785        assert_eq!(v2, arr.value(2));
1786        assert_eq!(v2, arr.values()[2]);
1787    }
1788
1789    #[test]
1790    fn test_duration_array_from_vec() {
1791        let arr = DurationSecondArray::from(vec![Some(1), None, Some(-5)]);
1792        assert_eq!(3, arr.len());
1793        assert_eq!(0, arr.offset());
1794        assert_eq!(1, arr.null_count());
1795        assert_eq!(1, arr.value(0));
1796        assert_eq!(1, arr.values()[0]);
1797        assert!(arr.is_null(1));
1798        assert_eq!(-5, arr.value(2));
1799        assert_eq!(-5, arr.values()[2]);
1800
1801        let arr = DurationMillisecondArray::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 = DurationMicrosecondArray::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 = DurationNanosecondArray::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
1832    #[test]
1833    fn test_timestamp_array_from_vec() {
1834        let arr = TimestampSecondArray::from(vec![1, -5]);
1835        assert_eq!(2, arr.len());
1836        assert_eq!(0, arr.offset());
1837        assert_eq!(0, arr.null_count());
1838        assert_eq!(1, arr.value(0));
1839        assert_eq!(-5, arr.value(1));
1840        assert_eq!(&[1, -5], arr.values());
1841
1842        let arr = TimestampMillisecondArray::from(vec![1, -5]);
1843        assert_eq!(2, arr.len());
1844        assert_eq!(0, arr.offset());
1845        assert_eq!(0, arr.null_count());
1846        assert_eq!(1, arr.value(0));
1847        assert_eq!(-5, arr.value(1));
1848        assert_eq!(&[1, -5], arr.values());
1849
1850        let arr = TimestampMicrosecondArray::from(vec![1, -5]);
1851        assert_eq!(2, arr.len());
1852        assert_eq!(0, arr.offset());
1853        assert_eq!(0, arr.null_count());
1854        assert_eq!(1, arr.value(0));
1855        assert_eq!(-5, arr.value(1));
1856        assert_eq!(&[1, -5], arr.values());
1857
1858        let arr = TimestampNanosecondArray::from(vec![1, -5]);
1859        assert_eq!(2, arr.len());
1860        assert_eq!(0, arr.offset());
1861        assert_eq!(0, arr.null_count());
1862        assert_eq!(1, arr.value(0));
1863        assert_eq!(-5, arr.value(1));
1864        assert_eq!(&[1, -5], arr.values());
1865    }
1866
1867    #[test]
1868    fn test_primitive_array_slice() {
1869        let arr = Int32Array::from(vec![
1870            Some(0),
1871            None,
1872            Some(2),
1873            None,
1874            Some(4),
1875            Some(5),
1876            Some(6),
1877            None,
1878            None,
1879        ]);
1880        assert_eq!(9, arr.len());
1881        assert_eq!(0, arr.offset());
1882        assert_eq!(4, arr.null_count());
1883
1884        let arr2 = arr.slice(2, 5);
1885        assert_eq!(5, arr2.len());
1886        assert_eq!(1, arr2.null_count());
1887
1888        for i in 0..arr2.len() {
1889            assert_eq!(i == 1, arr2.is_null(i));
1890            assert_eq!(i != 1, arr2.is_valid(i));
1891        }
1892        let int_arr2 = arr2.as_any().downcast_ref::<Int32Array>().unwrap();
1893        assert_eq!(2, int_arr2.values()[0]);
1894        assert_eq!(&[4, 5, 6], &int_arr2.values()[2..5]);
1895
1896        let arr3 = arr2.slice(2, 3);
1897        assert_eq!(3, arr3.len());
1898        assert_eq!(0, arr3.null_count());
1899
1900        let int_arr3 = arr3.as_any().downcast_ref::<Int32Array>().unwrap();
1901        assert_eq!(&[4, 5, 6], int_arr3.values());
1902        assert_eq!(4, int_arr3.value(0));
1903        assert_eq!(5, int_arr3.value(1));
1904        assert_eq!(6, int_arr3.value(2));
1905    }
1906
1907    #[test]
1908    fn test_boolean_array_slice() {
1909        let arr = BooleanArray::from(vec![
1910            Some(true),
1911            None,
1912            Some(false),
1913            None,
1914            Some(true),
1915            Some(false),
1916            Some(true),
1917            Some(false),
1918            None,
1919            Some(true),
1920        ]);
1921
1922        assert_eq!(10, arr.len());
1923        assert_eq!(0, arr.offset());
1924        assert_eq!(3, arr.null_count());
1925
1926        let arr2 = arr.slice(3, 5);
1927        assert_eq!(5, arr2.len());
1928        assert_eq!(3, arr2.offset());
1929        assert_eq!(1, arr2.null_count());
1930
1931        let bool_arr = arr2.as_any().downcast_ref::<BooleanArray>().unwrap();
1932
1933        assert!(!bool_arr.is_valid(0));
1934
1935        assert!(bool_arr.is_valid(1));
1936        assert!(bool_arr.value(1));
1937
1938        assert!(bool_arr.is_valid(2));
1939        assert!(!bool_arr.value(2));
1940
1941        assert!(bool_arr.is_valid(3));
1942        assert!(bool_arr.value(3));
1943
1944        assert!(bool_arr.is_valid(4));
1945        assert!(!bool_arr.value(4));
1946    }
1947
1948    #[test]
1949    fn test_int32_fmt_debug() {
1950        let arr = Int32Array::from(vec![0, 1, 2, 3, 4]);
1951        assert_eq!(
1952            "PrimitiveArray<Int32>\n[\n  0,\n  1,\n  2,\n  3,\n  4,\n]",
1953            format!("{arr:?}")
1954        );
1955    }
1956
1957    #[test]
1958    fn test_fmt_debug_up_to_20_elements() {
1959        (1..=20).for_each(|i| {
1960            let values = (0..i).collect::<Vec<i16>>();
1961            let array_expected = format!(
1962                "PrimitiveArray<Int16>\n[\n{}\n]",
1963                values
1964                    .iter()
1965                    .map(|v| { format!("  {v},") })
1966                    .collect::<Vec<String>>()
1967                    .join("\n")
1968            );
1969            let array = Int16Array::from(values);
1970
1971            assert_eq!(array_expected, format!("{array:?}"));
1972        })
1973    }
1974
1975    #[test]
1976    fn test_int32_with_null_fmt_debug() {
1977        let mut builder = Int32Array::builder(3);
1978        builder.append_slice(&[0, 1]);
1979        builder.append_null();
1980        builder.append_slice(&[3, 4]);
1981        let arr = builder.finish();
1982        assert_eq!(
1983            "PrimitiveArray<Int32>\n[\n  0,\n  1,\n  null,\n  3,\n  4,\n]",
1984            format!("{arr:?}")
1985        );
1986    }
1987
1988    #[test]
1989    fn test_timestamp_fmt_debug() {
1990        let arr: PrimitiveArray<TimestampMillisecondType> =
1991            TimestampMillisecondArray::from(vec![1546214400000, 1546214400000, -1546214400000]);
1992        assert_eq!(
1993            "PrimitiveArray<Timestamp(Millisecond, None)>\n[\n  2018-12-31T00:00:00,\n  2018-12-31T00:00:00,\n  1921-01-02T00:00:00,\n]",
1994            format!("{arr:?}")
1995        );
1996    }
1997
1998    #[test]
1999    fn test_timestamp_utc_fmt_debug() {
2000        let arr: PrimitiveArray<TimestampMillisecondType> =
2001            TimestampMillisecondArray::from(vec![1546214400000, 1546214400000, -1546214400000])
2002                .with_timezone_utc();
2003        assert_eq!(
2004            "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]",
2005            format!("{arr:?}")
2006        );
2007    }
2008
2009    #[test]
2010    #[cfg(feature = "chrono-tz")]
2011    fn test_timestamp_with_named_tz_fmt_debug() {
2012        let arr: PrimitiveArray<TimestampMillisecondType> =
2013            TimestampMillisecondArray::from(vec![1546214400000, 1546214400000, -1546214400000])
2014                .with_timezone("Asia/Taipei".to_string());
2015        assert_eq!(
2016            "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]",
2017            format!("{:?}", arr)
2018        );
2019    }
2020
2021    #[test]
2022    #[cfg(not(feature = "chrono-tz"))]
2023    fn test_timestamp_with_named_tz_fmt_debug() {
2024        let arr: PrimitiveArray<TimestampMillisecondType> =
2025            TimestampMillisecondArray::from(vec![1546214400000, 1546214400000, -1546214400000])
2026                .with_timezone("Asia/Taipei".to_string());
2027
2028        println!("{arr:?}");
2029
2030        assert_eq!(
2031            "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]",
2032            format!("{arr:?}")
2033        );
2034    }
2035
2036    #[test]
2037    fn test_timestamp_with_fixed_offset_tz_fmt_debug() {
2038        let arr: PrimitiveArray<TimestampMillisecondType> =
2039            TimestampMillisecondArray::from(vec![1546214400000, 1546214400000, -1546214400000])
2040                .with_timezone("+08:00".to_string());
2041        assert_eq!(
2042            "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]",
2043            format!("{arr:?}")
2044        );
2045    }
2046
2047    #[test]
2048    fn test_timestamp_with_incorrect_tz_fmt_debug() {
2049        let arr: PrimitiveArray<TimestampMillisecondType> =
2050            TimestampMillisecondArray::from(vec![1546214400000, 1546214400000, -1546214400000])
2051                .with_timezone("xxx".to_string());
2052        assert_eq!(
2053            "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]",
2054            format!("{arr:?}")
2055        );
2056    }
2057
2058    #[test]
2059    #[cfg(feature = "chrono-tz")]
2060    fn test_timestamp_with_tz_with_daylight_saving_fmt_debug() {
2061        let arr: PrimitiveArray<TimestampMillisecondType> = TimestampMillisecondArray::from(vec![
2062            1647161999000,
2063            1647162000000,
2064            1667717999000,
2065            1667718000000,
2066        ])
2067        .with_timezone("America/Denver".to_string());
2068        assert_eq!(
2069            "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]",
2070            format!("{:?}", arr)
2071        );
2072    }
2073
2074    #[test]
2075    fn test_date32_fmt_debug() {
2076        let arr: PrimitiveArray<Date32Type> = vec![12356, 13548, -365].into();
2077        assert_eq!(
2078            "PrimitiveArray<Date32>\n[\n  2003-10-31,\n  2007-02-04,\n  1969-01-01,\n]",
2079            format!("{arr:?}")
2080        );
2081    }
2082
2083    #[test]
2084    fn test_time32second_fmt_debug() {
2085        let arr: PrimitiveArray<Time32SecondType> = vec![7201, 60054].into();
2086        assert_eq!(
2087            "PrimitiveArray<Time32(Second)>\n[\n  02:00:01,\n  16:40:54,\n]",
2088            format!("{arr:?}")
2089        );
2090    }
2091
2092    #[test]
2093    fn test_time32second_invalid_neg() {
2094        // chrono::NaiveDatetime::from_timestamp_opt returns None while input is invalid
2095        let arr: PrimitiveArray<Time32SecondType> = vec![-7201, -60054].into();
2096        assert_eq!(
2097        "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]",
2098            // "PrimitiveArray<Time32(Second)>\n[\n  null,\n  null,\n]",
2099            format!("{arr:?}")
2100        )
2101    }
2102
2103    #[test]
2104    fn test_timestamp_micros_out_of_range() {
2105        // replicate the issue from https://github.com/apache/arrow-datafusion/issues/3832
2106        let arr: PrimitiveArray<TimestampMicrosecondType> = vec![9065525203050843594].into();
2107        assert_eq!(
2108            "PrimitiveArray<Timestamp(Microsecond, None)>\n[\n  null,\n]",
2109            format!("{arr:?}")
2110        )
2111    }
2112
2113    #[test]
2114    fn test_primitive_array_builder() {
2115        // Test building a primitive array with ArrayData builder and offset
2116        let buf = Buffer::from_slice_ref([0i32, 1, 2, 3, 4, 5, 6]);
2117        let buf2 = buf.slice_with_length(8, 20);
2118        let data = ArrayData::builder(DataType::Int32)
2119            .len(5)
2120            .offset(2)
2121            .add_buffer(buf)
2122            .build()
2123            .unwrap();
2124        let arr = Int32Array::from(data);
2125        assert_eq!(&buf2, arr.values.inner());
2126        assert_eq!(5, arr.len());
2127        assert_eq!(0, arr.null_count());
2128        for i in 0..3 {
2129            assert_eq!((i + 2) as i32, arr.value(i));
2130        }
2131    }
2132
2133    #[test]
2134    fn test_primitive_from_iter_values() {
2135        // Test building a primitive array with from_iter_values
2136        let arr: PrimitiveArray<Int32Type> = PrimitiveArray::from_iter_values(0..10);
2137        assert_eq!(10, arr.len());
2138        assert_eq!(0, arr.null_count());
2139        for i in 0..10i32 {
2140            assert_eq!(i, arr.value(i as usize));
2141        }
2142    }
2143
2144    #[test]
2145    fn test_primitive_array_from_unbound_iter() {
2146        // iterator that doesn't declare (upper) size bound
2147        let value_iter = (0..)
2148            .scan(0usize, |pos, i| {
2149                if *pos < 10 {
2150                    *pos += 1;
2151                    Some(Some(i))
2152                } else {
2153                    // actually returns up to 10 values
2154                    None
2155                }
2156            })
2157            // limited using take()
2158            .take(100);
2159
2160        let (_, upper_size_bound) = value_iter.size_hint();
2161        // the upper bound, defined by take above, is 100
2162        assert_eq!(upper_size_bound, Some(100));
2163        let primitive_array: PrimitiveArray<Int32Type> = value_iter.collect();
2164        // but the actual number of items in the array should be 10
2165        assert_eq!(primitive_array.len(), 10);
2166    }
2167
2168    #[test]
2169    fn test_primitive_array_from_non_null_iter() {
2170        let iter = (0..10_i32).map(Some);
2171        let primitive_array = PrimitiveArray::<Int32Type>::from_iter(iter);
2172        assert_eq!(primitive_array.len(), 10);
2173        assert_eq!(primitive_array.null_count(), 0);
2174        assert!(primitive_array.nulls().is_none());
2175        assert_eq!(primitive_array.values(), &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
2176    }
2177
2178    #[test]
2179    #[should_panic(expected = "PrimitiveArray data should contain a single buffer only \
2180                               (values buffer)")]
2181    // Different error messages, so skip for now
2182    // https://github.com/apache/arrow-rs/issues/1545
2183    #[cfg(not(feature = "force_validate"))]
2184    fn test_primitive_array_invalid_buffer_len() {
2185        let buffer = Buffer::from_slice_ref([0i32, 1, 2, 3, 4]);
2186        let data = unsafe {
2187            ArrayData::builder(DataType::Int32)
2188                .add_buffer(buffer.clone())
2189                .add_buffer(buffer)
2190                .len(5)
2191                .build_unchecked()
2192        };
2193
2194        drop(Int32Array::from(data));
2195    }
2196
2197    #[test]
2198    fn test_access_array_concurrently() {
2199        let a = Int32Array::from(vec![5, 6, 7, 8, 9]);
2200        let ret = std::thread::spawn(move || a.value(3)).join();
2201
2202        assert!(ret.is_ok());
2203        assert_eq!(8, ret.ok().unwrap());
2204    }
2205
2206    #[test]
2207    fn test_primitive_array_creation() {
2208        let array1: Int8Array = [10_i8, 11, 12, 13, 14].into_iter().collect();
2209        let array2: Int8Array = [10_i8, 11, 12, 13, 14].into_iter().map(Some).collect();
2210
2211        assert_eq!(array1, array2);
2212    }
2213
2214    #[test]
2215    #[should_panic(
2216        expected = "Trying to access an element at index 4 from a PrimitiveArray of length 3"
2217    )]
2218    fn test_string_array_get_value_index_out_of_bound() {
2219        let array: Int8Array = [10_i8, 11, 12].into_iter().collect();
2220
2221        array.value(4);
2222    }
2223
2224    #[test]
2225    #[should_panic(expected = "PrimitiveArray expected data type Int64 got Int32")]
2226    fn test_from_array_data_validation() {
2227        let foo = PrimitiveArray::<Int32Type>::from_iter([1, 2, 3]);
2228        let _ = PrimitiveArray::<Int64Type>::from(foo.into_data());
2229    }
2230
2231    #[test]
2232    fn test_decimal128() {
2233        let values: Vec<_> = vec![0, 1, -1, i128::MIN, i128::MAX];
2234        let array: PrimitiveArray<Decimal128Type> =
2235            PrimitiveArray::from_iter(values.iter().copied());
2236        assert_eq!(array.values(), &values);
2237
2238        let array: PrimitiveArray<Decimal128Type> =
2239            PrimitiveArray::from_iter_values(values.iter().copied());
2240        assert_eq!(array.values(), &values);
2241
2242        let array = PrimitiveArray::<Decimal128Type>::from(values.clone());
2243        assert_eq!(array.values(), &values);
2244
2245        let array = PrimitiveArray::<Decimal128Type>::from(array.to_data());
2246        assert_eq!(array.values(), &values);
2247    }
2248
2249    #[test]
2250    fn test_decimal256() {
2251        let values: Vec<_> = vec![i256::ZERO, i256::ONE, i256::MINUS_ONE, i256::MIN, i256::MAX];
2252
2253        let array: PrimitiveArray<Decimal256Type> =
2254            PrimitiveArray::from_iter(values.iter().copied());
2255        assert_eq!(array.values(), &values);
2256
2257        let array: PrimitiveArray<Decimal256Type> =
2258            PrimitiveArray::from_iter_values(values.iter().copied());
2259        assert_eq!(array.values(), &values);
2260
2261        let array = PrimitiveArray::<Decimal256Type>::from(values.clone());
2262        assert_eq!(array.values(), &values);
2263
2264        let array = PrimitiveArray::<Decimal256Type>::from(array.to_data());
2265        assert_eq!(array.values(), &values);
2266    }
2267
2268    #[test]
2269    fn test_decimal_array() {
2270        // let val_8887: [u8; 16] = [192, 219, 180, 17, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
2271        // let val_neg_8887: [u8; 16] = [64, 36, 75, 238, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255];
2272        let values: [u8; 32] = [
2273            192, 219, 180, 17, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 36, 75, 238, 253, 255, 255,
2274            255, 255, 255, 255, 255, 255, 255, 255, 255,
2275        ];
2276        let array_data = ArrayData::builder(DataType::Decimal128(38, 6))
2277            .len(2)
2278            .add_buffer(Buffer::from(&values))
2279            .build()
2280            .unwrap();
2281        let decimal_array = Decimal128Array::from(array_data);
2282        assert_eq!(8_887_000_000_i128, decimal_array.value(0));
2283        assert_eq!(-8_887_000_000_i128, decimal_array.value(1));
2284    }
2285
2286    #[test]
2287    fn test_decimal_append_error_value() {
2288        let mut decimal_builder = Decimal128Builder::with_capacity(10);
2289        decimal_builder.append_value(123456);
2290        decimal_builder.append_value(12345);
2291        let result = decimal_builder.finish().with_precision_and_scale(5, 3);
2292        assert!(result.is_ok());
2293        let arr = result.unwrap();
2294        assert_eq!("12.345", arr.value_as_string(1));
2295
2296        // Validate it explicitly
2297        let result = arr.validate_decimal_precision(5);
2298        let error = result.unwrap_err();
2299        assert_eq!(
2300            "Invalid argument error: 123456 is too large to store in a Decimal128 of precision 5. Max is 99999",
2301            error.to_string()
2302        );
2303
2304        decimal_builder = Decimal128Builder::new();
2305        decimal_builder.append_value(100);
2306        decimal_builder.append_value(99);
2307        decimal_builder.append_value(-100);
2308        decimal_builder.append_value(-99);
2309        let result = decimal_builder.finish().with_precision_and_scale(2, 1);
2310        assert!(result.is_ok());
2311        let arr = result.unwrap();
2312        assert_eq!("9.9", arr.value_as_string(1));
2313        assert_eq!("-9.9", arr.value_as_string(3));
2314
2315        // Validate it explicitly
2316        let result = arr.validate_decimal_precision(2);
2317        let error = result.unwrap_err();
2318        assert_eq!(
2319            "Invalid argument error: 100 is too large to store in a Decimal128 of precision 2. Max is 99",
2320            error.to_string()
2321        );
2322    }
2323
2324    #[test]
2325    fn test_decimal_from_iter_values() {
2326        let array = Decimal128Array::from_iter_values(vec![-100, 0, 101]);
2327        assert_eq!(array.len(), 3);
2328        assert_eq!(array.data_type(), &DataType::Decimal128(38, 10));
2329        assert_eq!(-100_i128, array.value(0));
2330        assert!(!array.is_null(0));
2331        assert_eq!(0_i128, array.value(1));
2332        assert!(!array.is_null(1));
2333        assert_eq!(101_i128, array.value(2));
2334        assert!(!array.is_null(2));
2335    }
2336
2337    #[test]
2338    fn test_decimal_from_iter() {
2339        let array: Decimal128Array = vec![Some(-100), None, Some(101)].into_iter().collect();
2340        assert_eq!(array.len(), 3);
2341        assert_eq!(array.data_type(), &DataType::Decimal128(38, 10));
2342        assert_eq!(-100_i128, array.value(0));
2343        assert!(!array.is_null(0));
2344        assert!(array.is_null(1));
2345        assert_eq!(101_i128, array.value(2));
2346        assert!(!array.is_null(2));
2347    }
2348
2349    #[test]
2350    fn test_decimal_iter_sized() {
2351        let data = vec![Some(-100), None, Some(101)];
2352        let array: Decimal128Array = data.into_iter().collect();
2353        let mut iter = array.into_iter();
2354
2355        // is exact sized
2356        assert_eq!(array.len(), 3);
2357
2358        // size_hint is reported correctly
2359        assert_eq!(iter.size_hint(), (3, Some(3)));
2360        iter.next().unwrap();
2361        assert_eq!(iter.size_hint(), (2, Some(2)));
2362        iter.next().unwrap();
2363        iter.next().unwrap();
2364        assert_eq!(iter.size_hint(), (0, Some(0)));
2365        assert!(iter.next().is_none());
2366        assert_eq!(iter.size_hint(), (0, Some(0)));
2367    }
2368
2369    #[test]
2370    fn test_decimal_array_value_as_string() {
2371        let arr = [123450, -123450, 100, -100, 10, -10, 0]
2372            .into_iter()
2373            .map(Some)
2374            .collect::<Decimal128Array>()
2375            .with_precision_and_scale(6, 3)
2376            .unwrap();
2377
2378        assert_eq!("123.450", arr.value_as_string(0));
2379        assert_eq!("-123.450", arr.value_as_string(1));
2380        assert_eq!("0.100", arr.value_as_string(2));
2381        assert_eq!("-0.100", arr.value_as_string(3));
2382        assert_eq!("0.010", arr.value_as_string(4));
2383        assert_eq!("-0.010", arr.value_as_string(5));
2384        assert_eq!("0.000", arr.value_as_string(6));
2385    }
2386
2387    #[test]
2388    fn test_decimal_array_with_precision_and_scale() {
2389        let arr = Decimal128Array::from_iter_values([12345, 456, 7890, -123223423432432])
2390            .with_precision_and_scale(20, 2)
2391            .unwrap();
2392
2393        assert_eq!(arr.data_type(), &DataType::Decimal128(20, 2));
2394        assert_eq!(arr.precision(), 20);
2395        assert_eq!(arr.scale(), 2);
2396
2397        let actual: Vec<_> = (0..arr.len()).map(|i| arr.value_as_string(i)).collect();
2398        let expected = vec!["123.45", "4.56", "78.90", "-1232234234324.32"];
2399
2400        assert_eq!(actual, expected);
2401    }
2402
2403    #[test]
2404    #[should_panic(
2405        expected = "-123223423432432 is too small to store in a Decimal128 of precision 5. Min is -99999"
2406    )]
2407    fn test_decimal_array_with_precision_and_scale_out_of_range() {
2408        let arr = Decimal128Array::from_iter_values([12345, 456, 7890, -123223423432432])
2409            // precision is too small to hold value
2410            .with_precision_and_scale(5, 2)
2411            .unwrap();
2412        arr.validate_decimal_precision(5).unwrap();
2413    }
2414
2415    #[test]
2416    #[should_panic(expected = "precision cannot be 0, has to be between [1, 38]")]
2417    fn test_decimal_array_with_precision_zero() {
2418        Decimal128Array::from_iter_values([12345, 456])
2419            .with_precision_and_scale(0, 2)
2420            .unwrap();
2421    }
2422
2423    #[test]
2424    #[should_panic(expected = "precision 40 is greater than max 38")]
2425    fn test_decimal_array_with_precision_and_scale_invalid_precision() {
2426        Decimal128Array::from_iter_values([12345, 456])
2427            .with_precision_and_scale(40, 2)
2428            .unwrap();
2429    }
2430
2431    #[test]
2432    #[should_panic(expected = "scale 40 is greater than max 38")]
2433    fn test_decimal_array_with_precision_and_scale_invalid_scale() {
2434        Decimal128Array::from_iter_values([12345, 456])
2435            .with_precision_and_scale(20, 40)
2436            .unwrap();
2437    }
2438
2439    #[test]
2440    #[should_panic(expected = "scale 10 is greater than precision 4")]
2441    fn test_decimal_array_with_precision_and_scale_invalid_precision_and_scale() {
2442        Decimal128Array::from_iter_values([12345, 456])
2443            .with_precision_and_scale(4, 10)
2444            .unwrap();
2445    }
2446
2447    #[test]
2448    fn test_decimal_array_set_null_if_overflow_with_precision() {
2449        let array = Decimal128Array::from(vec![Some(123456), Some(123), None, Some(123456)]);
2450        let result = array.null_if_overflow_precision(5);
2451        let expected = Decimal128Array::from(vec![None, Some(123), None, None]);
2452        assert_eq!(result, expected);
2453    }
2454
2455    #[test]
2456    fn test_decimal256_iter() {
2457        let mut builder = Decimal256Builder::with_capacity(30);
2458        let decimal1 = i256::from_i128(12345);
2459        builder.append_value(decimal1);
2460
2461        builder.append_null();
2462
2463        let decimal2 = i256::from_i128(56789);
2464        builder.append_value(decimal2);
2465
2466        let array: Decimal256Array = builder.finish().with_precision_and_scale(76, 6).unwrap();
2467
2468        let collected: Vec<_> = array.iter().collect();
2469        assert_eq!(vec![Some(decimal1), None, Some(decimal2)], collected);
2470    }
2471
2472    #[test]
2473    fn test_from_iter_decimal256array() {
2474        let value1 = i256::from_i128(12345);
2475        let value2 = i256::from_i128(56789);
2476
2477        let mut array: Decimal256Array =
2478            vec![Some(value1), None, Some(value2)].into_iter().collect();
2479        array = array.with_precision_and_scale(76, 10).unwrap();
2480        assert_eq!(array.len(), 3);
2481        assert_eq!(array.data_type(), &DataType::Decimal256(76, 10));
2482        assert_eq!(value1, array.value(0));
2483        assert!(!array.is_null(0));
2484        assert!(array.is_null(1));
2485        assert_eq!(value2, array.value(2));
2486        assert!(!array.is_null(2));
2487    }
2488
2489    #[test]
2490    fn test_from_iter_decimal128array() {
2491        let mut array: Decimal128Array = vec![Some(-100), None, Some(101)].into_iter().collect();
2492        array = array.with_precision_and_scale(38, 10).unwrap();
2493        assert_eq!(array.len(), 3);
2494        assert_eq!(array.data_type(), &DataType::Decimal128(38, 10));
2495        assert_eq!(-100_i128, array.value(0));
2496        assert!(!array.is_null(0));
2497        assert!(array.is_null(1));
2498        assert_eq!(101_i128, array.value(2));
2499        assert!(!array.is_null(2));
2500    }
2501
2502    #[test]
2503    fn test_unary_opt() {
2504        let array = Int32Array::from(vec![1, 2, 3, 4, 5, 6, 7]);
2505        let r = array.unary_opt::<_, Int32Type>(|x| (x % 2 != 0).then_some(x));
2506
2507        let expected = Int32Array::from(vec![Some(1), None, Some(3), None, Some(5), None, Some(7)]);
2508        assert_eq!(r, expected);
2509
2510        let r = expected.unary_opt::<_, Int32Type>(|x| (x % 3 != 0).then_some(x));
2511        let expected = Int32Array::from(vec![Some(1), None, None, None, Some(5), None, Some(7)]);
2512        assert_eq!(r, expected);
2513    }
2514
2515    #[test]
2516    #[should_panic(
2517        expected = "Trying to access an element at index 4 from a PrimitiveArray of length 3"
2518    )]
2519    fn test_fixed_size_binary_array_get_value_index_out_of_bound() {
2520        let array = Decimal128Array::from(vec![-100, 0, 101]);
2521        array.value(4);
2522    }
2523
2524    #[test]
2525    fn test_into_builder() {
2526        let array: Int32Array = vec![1, 2, 3].into_iter().map(Some).collect();
2527
2528        let boxed: ArrayRef = Arc::new(array);
2529        let col: Int32Array = downcast_array(&boxed);
2530        drop(boxed);
2531
2532        let mut builder = col.into_builder().unwrap();
2533
2534        let slice = builder.values_slice_mut();
2535        assert_eq!(slice, &[1, 2, 3]);
2536
2537        slice[0] = 4;
2538        slice[1] = 2;
2539        slice[2] = 1;
2540
2541        let expected: Int32Array = vec![Some(4), Some(2), Some(1)].into_iter().collect();
2542
2543        let new_array = builder.finish();
2544        assert_eq!(expected, new_array);
2545    }
2546
2547    #[test]
2548    fn test_into_builder_cloned_array() {
2549        let array: Int32Array = vec![1, 2, 3].into_iter().map(Some).collect();
2550
2551        let boxed: ArrayRef = Arc::new(array);
2552
2553        let col: Int32Array = PrimitiveArray::<Int32Type>::from(boxed.to_data());
2554        let err = col.into_builder();
2555
2556        match err {
2557            Ok(_) => panic!("Should not get builder from cloned array"),
2558            Err(returned) => {
2559                let expected: Int32Array = vec![1, 2, 3].into_iter().map(Some).collect();
2560                assert_eq!(expected, returned)
2561            }
2562        }
2563    }
2564
2565    #[test]
2566    fn test_into_builder_on_sliced_array() {
2567        let array: Int32Array = vec![1, 2, 3].into_iter().map(Some).collect();
2568        let slice = array.slice(1, 2);
2569        let col: Int32Array = downcast_array(&slice);
2570
2571        drop(slice);
2572
2573        col.into_builder()
2574            .expect_err("Should not build builder from sliced array");
2575    }
2576
2577    #[test]
2578    fn test_unary_mut() {
2579        let array: Int32Array = vec![1, 2, 3].into_iter().map(Some).collect();
2580
2581        let c = array.unary_mut(|x| x * 2 + 1).unwrap();
2582        let expected: Int32Array = vec![3, 5, 7].into_iter().map(Some).collect();
2583
2584        assert_eq!(expected, c);
2585
2586        let array: Int32Array = Int32Array::from(vec![Some(5), Some(7), None]);
2587        let c = array.unary_mut(|x| x * 2 + 1).unwrap();
2588        assert_eq!(c, Int32Array::from(vec![Some(11), Some(15), None]));
2589    }
2590
2591    #[test]
2592    #[should_panic(
2593        expected = "PrimitiveArray expected data type Interval(MonthDayNano) got Interval(DayTime)"
2594    )]
2595    fn test_invalid_interval_type() {
2596        let array = IntervalDayTimeArray::from(vec![IntervalDayTime::ZERO]);
2597        let _ = IntervalMonthDayNanoArray::from(array.into_data());
2598    }
2599
2600    #[test]
2601    fn test_timezone() {
2602        let array = TimestampNanosecondArray::from_iter_values([1, 2]);
2603        assert_eq!(array.timezone(), None);
2604
2605        let array = array.with_timezone("+02:00");
2606        assert_eq!(array.timezone(), Some("+02:00"));
2607    }
2608
2609    #[test]
2610    fn test_try_new() {
2611        Int32Array::new(vec![1, 2, 3, 4].into(), None);
2612        Int32Array::new(vec![1, 2, 3, 4].into(), Some(NullBuffer::new_null(4)));
2613
2614        let err = Int32Array::try_new(vec![1, 2, 3, 4].into(), Some(NullBuffer::new_null(3)))
2615            .unwrap_err();
2616
2617        assert_eq!(
2618            err.to_string(),
2619            "Invalid argument error: Incorrect length of null buffer for PrimitiveArray, expected 4 got 3"
2620        );
2621
2622        TimestampNanosecondArray::new(vec![1, 2, 3, 4].into(), None).with_data_type(
2623            DataType::Timestamp(TimeUnit::Nanosecond, Some("03:00".into())),
2624        );
2625    }
2626
2627    #[test]
2628    #[should_panic(expected = "PrimitiveArray expected data type Int32 got Date32")]
2629    fn test_with_data_type() {
2630        Int32Array::new(vec![1, 2, 3, 4].into(), None).with_data_type(DataType::Date32);
2631    }
2632
2633    #[test]
2634    fn test_time_32second_output() {
2635        let array: Time32SecondArray = vec![
2636            Some(-1),
2637            Some(0),
2638            Some(86_399),
2639            Some(86_400),
2640            Some(86_401),
2641            None,
2642        ]
2643        .into();
2644        let debug_str = format!("{:?}", array);
2645        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]",
2646    debug_str
2647    );
2648    }
2649
2650    #[test]
2651    fn test_time_32millisecond_debug_output() {
2652        let array: Time32MillisecondArray = vec![
2653            Some(-1),
2654            Some(0),
2655            Some(86_399_000),
2656            Some(86_400_000),
2657            Some(86_401_000),
2658            None,
2659        ]
2660        .into();
2661        let debug_str = format!("{:?}", array);
2662        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]",
2663            debug_str
2664        );
2665    }
2666
2667    #[test]
2668    fn test_time_64nanosecond_debug_output() {
2669        let array: Time64NanosecondArray = vec![
2670            Some(-1),
2671            Some(0),
2672            Some(86_399 * 1_000_000_000),
2673            Some(86_400 * 1_000_000_000),
2674            Some(86_401 * 1_000_000_000),
2675            None,
2676        ]
2677        .into();
2678        let debug_str = format!("{:?}", array);
2679        assert_eq!(
2680        "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]",
2681            debug_str
2682        );
2683    }
2684
2685    #[test]
2686    fn test_time_64microsecond_debug_output() {
2687        let array: Time64MicrosecondArray = vec![
2688            Some(-1),
2689            Some(0),
2690            Some(86_399 * 1_000_000),
2691            Some(86_400 * 1_000_000),
2692            Some(86_401 * 1_000_000),
2693            None,
2694        ]
2695        .into();
2696        let debug_str = format!("{:?}", array);
2697        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);
2698    }
2699
2700    #[test]
2701    fn test_primitive_with_nulls_into_builder() {
2702        let array: Int32Array = vec![
2703            Some(1),
2704            None,
2705            Some(3),
2706            Some(4),
2707            None,
2708            Some(7),
2709            None,
2710            Some(8),
2711        ]
2712        .into_iter()
2713        .collect();
2714        let _ = array.into_builder();
2715    }
2716}