arrow_array/array/
primitive_array.rs

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