Skip to main content

arrow_array/array/
primitive_array.rs

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