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