arrow_array/array/
primitive_array.rs

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