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_type = self.data_type.clone();
1142        let data = self.into_data();
1143        let null_bit_buffer = data.nulls().map(|b| b.inner().sliced());
1144
1145        let element_len = std::mem::size_of::<T::Native>();
1146        let buffer =
1147            data.buffers()[0].slice_with_length(data.offset() * element_len, len * element_len);
1148
1149        drop(data);
1150
1151        let try_mutable_null_buffer = match null_bit_buffer {
1152            None => Ok(None),
1153            Some(null_buffer) => {
1154                // Null buffer exists, tries to make it mutable
1155                null_buffer.into_mutable().map(Some)
1156            }
1157        };
1158
1159        let try_mutable_buffers = match try_mutable_null_buffer {
1160            Ok(mutable_null_buffer) => {
1161                // Got mutable null buffer, tries to get mutable value buffer
1162                let try_mutable_buffer = buffer.into_mutable();
1163
1164                // try_mutable_buffer.map(...).map_err(...) doesn't work as the compiler complains
1165                // mutable_null_buffer is moved into map closure.
1166                match try_mutable_buffer {
1167                    Ok(mutable_buffer) => Ok(PrimitiveBuilder::<T>::new_from_buffer(
1168                        mutable_buffer,
1169                        mutable_null_buffer,
1170                    )),
1171                    Err(buffer) => Err((buffer, mutable_null_buffer.map(|b| b.into()))),
1172                }
1173            }
1174            Err(mutable_null_buffer) => {
1175                // Unable to get mutable null buffer
1176                Err((buffer, Some(mutable_null_buffer)))
1177            }
1178        };
1179
1180        match try_mutable_buffers {
1181            Ok(builder) => Ok(builder.with_data_type(data_type)),
1182            Err((buffer, null_bit_buffer)) => {
1183                let builder = ArrayData::builder(data_type)
1184                    .len(len)
1185                    .add_buffer(buffer)
1186                    .null_bit_buffer(null_bit_buffer);
1187
1188                let array_data = unsafe { builder.build_unchecked() };
1189                let array = PrimitiveArray::<T>::from(array_data);
1190
1191                Err(array)
1192            }
1193        }
1194    }
1195}
1196
1197impl<T: ArrowPrimitiveType> From<PrimitiveArray<T>> for ArrayData {
1198    fn from(array: PrimitiveArray<T>) -> Self {
1199        let builder = ArrayDataBuilder::new(array.data_type)
1200            .len(array.values.len())
1201            .nulls(array.nulls)
1202            .buffers(vec![array.values.into_inner()]);
1203
1204        unsafe { builder.build_unchecked() }
1205    }
1206}
1207
1208/// SAFETY: Correctly implements the contract of Arrow Arrays
1209unsafe impl<T: ArrowPrimitiveType> Array for PrimitiveArray<T> {
1210    fn as_any(&self) -> &dyn Any {
1211        self
1212    }
1213
1214    fn to_data(&self) -> ArrayData {
1215        self.clone().into()
1216    }
1217
1218    fn into_data(self) -> ArrayData {
1219        self.into()
1220    }
1221
1222    fn data_type(&self) -> &DataType {
1223        &self.data_type
1224    }
1225
1226    fn slice(&self, offset: usize, length: usize) -> ArrayRef {
1227        Arc::new(self.slice(offset, length))
1228    }
1229
1230    fn len(&self) -> usize {
1231        self.values.len()
1232    }
1233
1234    fn is_empty(&self) -> bool {
1235        self.values.is_empty()
1236    }
1237
1238    fn shrink_to_fit(&mut self) {
1239        self.values.shrink_to_fit();
1240        if let Some(nulls) = &mut self.nulls {
1241            nulls.shrink_to_fit();
1242        }
1243    }
1244
1245    fn offset(&self) -> usize {
1246        0
1247    }
1248
1249    fn nulls(&self) -> Option<&NullBuffer> {
1250        self.nulls.as_ref()
1251    }
1252
1253    fn logical_null_count(&self) -> usize {
1254        self.null_count()
1255    }
1256
1257    fn get_buffer_memory_size(&self) -> usize {
1258        let mut size = self.values.inner().capacity();
1259        if let Some(n) = self.nulls.as_ref() {
1260            size += n.buffer().capacity();
1261        }
1262        size
1263    }
1264
1265    fn get_array_memory_size(&self) -> usize {
1266        std::mem::size_of::<Self>() + self.get_buffer_memory_size()
1267    }
1268
1269    #[cfg(feature = "pool")]
1270    fn claim(&self, pool: &dyn arrow_buffer::MemoryPool) {
1271        self.values.claim(pool);
1272        if let Some(nulls) = &self.nulls {
1273            nulls.claim(pool);
1274        }
1275    }
1276}
1277
1278impl<T: ArrowPrimitiveType> ArrayAccessor for &PrimitiveArray<T> {
1279    type Item = T::Native;
1280
1281    fn value(&self, index: usize) -> Self::Item {
1282        PrimitiveArray::value(self, index)
1283    }
1284
1285    #[inline]
1286    unsafe fn value_unchecked(&self, index: usize) -> Self::Item {
1287        unsafe { PrimitiveArray::value_unchecked(self, index) }
1288    }
1289}
1290
1291impl<T: ArrowTemporalType> PrimitiveArray<T>
1292where
1293    i64: From<T::Native>,
1294{
1295    /// Returns value as a chrono `NaiveDateTime`, handling time resolution
1296    ///
1297    /// If a data type cannot be converted to `NaiveDateTime`, a `None` is returned.
1298    /// A valid value is expected, thus the user should first check for validity.
1299    ///
1300    /// See notes on [`PrimitiveArray::value`] regarding nulls and panics
1301    pub fn value_as_datetime(&self, i: usize) -> Option<NaiveDateTime> {
1302        as_datetime::<T>(i64::from(self.value(i)))
1303    }
1304
1305    /// Returns value as a chrono `NaiveDateTime`, handling time resolution with the provided tz
1306    ///
1307    /// functionally it is same as `value_as_datetime`, however it adds
1308    /// the passed tz to the to-be-returned NaiveDateTime
1309    ///
1310    /// See notes on [`PrimitiveArray::value`] regarding nulls and panics
1311    pub fn value_as_datetime_with_tz(&self, i: usize, tz: Tz) -> Option<DateTime<Tz>> {
1312        as_datetime_with_timezone::<T>(i64::from(self.value(i)), tz)
1313    }
1314
1315    /// Returns value as a chrono `NaiveDate` by using `Self::datetime()`
1316    ///
1317    /// If a data type cannot be converted to `NaiveDate`, a `None` is returned
1318    ///
1319    /// See notes on [`PrimitiveArray::value`] regarding nulls and panics
1320    pub fn value_as_date(&self, i: usize) -> Option<NaiveDate> {
1321        self.value_as_datetime(i).map(|datetime| datetime.date())
1322    }
1323
1324    /// Returns a value as a chrono `NaiveTime`
1325    ///
1326    /// `Date32` and `Date64` return UTC midnight as they do not have time resolution
1327    ///
1328    /// See notes on [`PrimitiveArray::value`] regarding nulls and panics
1329    pub fn value_as_time(&self, i: usize) -> Option<NaiveTime> {
1330        as_time::<T>(i64::from(self.value(i)))
1331    }
1332
1333    /// Returns a value as a chrono `Duration`
1334    ///
1335    /// If a data type cannot be converted to `Duration`, a `None` is returned
1336    ///
1337    /// See notes on [`PrimitiveArray::value`] regarding nulls and panics
1338    pub fn value_as_duration(&self, i: usize) -> Option<Duration> {
1339        as_duration::<T>(i64::from(self.value(i)))
1340    }
1341}
1342
1343impl<T: ArrowPrimitiveType> std::fmt::Debug for PrimitiveArray<T> {
1344    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
1345        let data_type = self.data_type();
1346
1347        write!(f, "PrimitiveArray<{data_type}>\n[\n")?;
1348        print_long_array(self, f, |array, index, f| match data_type {
1349            DataType::Date32 | DataType::Date64 => {
1350                let v = self.value(index).to_i64().unwrap();
1351                match as_date::<T>(v) {
1352                    Some(date) => write!(f, "{date:?}"),
1353                    None => {
1354                        write!(
1355                            f,
1356                            "Cast error: Failed to convert {v} to temporal for {data_type}"
1357                        )
1358                    }
1359                }
1360            }
1361            DataType::Time32(_) | DataType::Time64(_) => {
1362                let v = self.value(index).to_i64().unwrap();
1363                match as_time::<T>(v) {
1364                    Some(time) => write!(f, "{time:?}"),
1365                    None => {
1366                        write!(
1367                            f,
1368                            "Cast error: Failed to convert {v} to temporal for {data_type}"
1369                        )
1370                    }
1371                }
1372            }
1373            DataType::Timestamp(_, tz_string_opt) => {
1374                let v = self.value(index).to_i64().unwrap();
1375                match tz_string_opt {
1376                    // for Timestamp with TimeZone
1377                    Some(tz_string) => {
1378                        match tz_string.parse::<Tz>() {
1379                            // if the time zone is valid, construct a DateTime<Tz> and format it as rfc3339
1380                            Ok(tz) => match as_datetime_with_timezone::<T>(v, tz) {
1381                                Some(datetime) => write!(f, "{}", datetime.to_rfc3339()),
1382                                None => write!(
1383                                    f,
1384                                    "Cast error: Failed to convert {v} to timestamp for {data_type}"
1385                                ),
1386                            },
1387                            // if the time zone is invalid, shows NaiveDateTime with an error message
1388                            Err(_) => match as_datetime::<T>(v) {
1389                                Some(datetime) => {
1390                                    write!(f, "{datetime:?} (Unknown Time Zone '{tz_string}')")
1391                                }
1392                                None => write!(
1393                                    f,
1394                                    "Cast error: Failed to convert {v} to timestamp for {data_type}"
1395                                ),
1396                            },
1397                        }
1398                    }
1399                    // for Timestamp without TimeZone
1400                    None => match as_datetime::<T>(v) {
1401                        Some(datetime) => write!(f, "{datetime:?}"),
1402                        None => write!(
1403                            f,
1404                            "Cast error: Failed to convert {v} to timestamp for {data_type}"
1405                        ),
1406                    },
1407                }
1408            }
1409            _ => std::fmt::Debug::fmt(&array.value(index), f),
1410        })?;
1411        write!(f, "]")
1412    }
1413}
1414
1415impl<'a, T: ArrowPrimitiveType> IntoIterator for &'a PrimitiveArray<T> {
1416    type Item = Option<<T as ArrowPrimitiveType>::Native>;
1417    type IntoIter = PrimitiveIter<'a, T>;
1418
1419    fn into_iter(self) -> Self::IntoIter {
1420        PrimitiveIter::<'a, T>::new(self)
1421    }
1422}
1423
1424impl<'a, T: ArrowPrimitiveType> PrimitiveArray<T> {
1425    /// constructs a new iterator
1426    pub fn iter(&'a self) -> PrimitiveIter<'a, T> {
1427        PrimitiveIter::<'a, T>::new(self)
1428    }
1429}
1430
1431/// An optional primitive value
1432///
1433/// This struct is used as an adapter when creating `PrimitiveArray` from an iterator.
1434/// `FromIterator` for `PrimitiveArray` takes an iterator where the elements can be `into`
1435/// this struct. So once implementing `From` or `Into` trait for a type, an iterator of
1436/// the type can be collected to `PrimitiveArray`.
1437#[derive(Debug)]
1438pub struct NativeAdapter<T: ArrowPrimitiveType> {
1439    /// Corresponding Rust native type if available
1440    pub native: Option<T::Native>,
1441}
1442
1443macro_rules! def_from_for_primitive {
1444    ( $ty:ident, $tt:tt) => {
1445        impl From<$tt> for NativeAdapter<$ty> {
1446            fn from(value: $tt) -> Self {
1447                NativeAdapter {
1448                    native: Some(value),
1449                }
1450            }
1451        }
1452    };
1453}
1454
1455def_from_for_primitive!(Int8Type, i8);
1456def_from_for_primitive!(Int16Type, i16);
1457def_from_for_primitive!(Int32Type, i32);
1458def_from_for_primitive!(Int64Type, i64);
1459def_from_for_primitive!(UInt8Type, u8);
1460def_from_for_primitive!(UInt16Type, u16);
1461def_from_for_primitive!(UInt32Type, u32);
1462def_from_for_primitive!(UInt64Type, u64);
1463def_from_for_primitive!(Float16Type, f16);
1464def_from_for_primitive!(Float32Type, f32);
1465def_from_for_primitive!(Float64Type, f64);
1466def_from_for_primitive!(Decimal32Type, i32);
1467def_from_for_primitive!(Decimal64Type, i64);
1468def_from_for_primitive!(Decimal128Type, i128);
1469def_from_for_primitive!(Decimal256Type, i256);
1470
1471impl<T: ArrowPrimitiveType> From<Option<<T as ArrowPrimitiveType>::Native>> for NativeAdapter<T> {
1472    fn from(value: Option<<T as ArrowPrimitiveType>::Native>) -> Self {
1473        NativeAdapter { native: value }
1474    }
1475}
1476
1477impl<T: ArrowPrimitiveType> From<&Option<<T as ArrowPrimitiveType>::Native>> for NativeAdapter<T> {
1478    fn from(value: &Option<<T as ArrowPrimitiveType>::Native>) -> Self {
1479        NativeAdapter { native: *value }
1480    }
1481}
1482
1483impl<T: ArrowPrimitiveType, Ptr: Into<NativeAdapter<T>>> FromIterator<Ptr> for PrimitiveArray<T> {
1484    fn from_iter<I: IntoIterator<Item = Ptr>>(iter: I) -> Self {
1485        let iter = iter.into_iter();
1486        let (lower, _) = iter.size_hint();
1487
1488        let mut null_builder = NullBufferBuilder::new(lower);
1489
1490        let buffer: Buffer = iter
1491            .map(|item| {
1492                if let Some(a) = item.into().native {
1493                    null_builder.append_non_null();
1494                    a
1495                } else {
1496                    null_builder.append_null();
1497                    // this ensures that null items on the buffer are not arbitrary.
1498                    // This is important because fallible operations can use null values (e.g. a vectorized "add")
1499                    // which may panic (e.g. overflow if the number on the slots happen to be very large).
1500                    T::Native::default()
1501                }
1502            })
1503            .collect();
1504
1505        let maybe_nulls = null_builder.finish();
1506        PrimitiveArray::new(ScalarBuffer::from(buffer), maybe_nulls)
1507    }
1508}
1509
1510impl<T: ArrowPrimitiveType> PrimitiveArray<T> {
1511    /// Creates a [`PrimitiveArray`] from an iterator of trusted length.
1512    /// # Safety
1513    /// The iterator must be [`TrustedLen`](https://doc.rust-lang.org/std/iter/trait.TrustedLen.html).
1514    /// I.e. that `size_hint().1` correctly reports its length.
1515    #[inline]
1516    pub unsafe fn from_trusted_len_iter<I, P>(iter: I) -> Self
1517    where
1518        P: std::borrow::Borrow<Option<<T as ArrowPrimitiveType>::Native>>,
1519        I: IntoIterator<Item = P>,
1520    {
1521        let iterator = iter.into_iter();
1522        let (_, upper) = iterator.size_hint();
1523        let len = upper.expect("trusted_len_unzip requires an upper limit");
1524
1525        let (null, buffer) = unsafe { trusted_len_unzip(iterator) };
1526
1527        let nulls = NullBuffer::from_unsliced_buffer(null, len);
1528        PrimitiveArray::new(ScalarBuffer::from(buffer), nulls)
1529    }
1530}
1531
1532// TODO: the macro is needed here because we'd get "conflicting implementations" error
1533// otherwise with both `From<Vec<T::Native>>` and `From<Vec<Option<T::Native>>>`.
1534// We should revisit this in future.
1535macro_rules! def_numeric_from_vec {
1536    ( $ty:ident ) => {
1537        impl From<Vec<<$ty as ArrowPrimitiveType>::Native>> for PrimitiveArray<$ty> {
1538            fn from(data: Vec<<$ty as ArrowPrimitiveType>::Native>) -> Self {
1539                let buffer = ScalarBuffer::from(Buffer::from_vec(data));
1540                let nulls = None;
1541                PrimitiveArray::new(buffer, nulls)
1542            }
1543        }
1544
1545        // Constructs a primitive array from a vector. Should only be used for testing.
1546        impl From<Vec<Option<<$ty as ArrowPrimitiveType>::Native>>> for PrimitiveArray<$ty> {
1547            fn from(data: Vec<Option<<$ty as ArrowPrimitiveType>::Native>>) -> Self {
1548                PrimitiveArray::from_iter(data.iter())
1549            }
1550        }
1551    };
1552}
1553
1554def_numeric_from_vec!(Int8Type);
1555def_numeric_from_vec!(Int16Type);
1556def_numeric_from_vec!(Int32Type);
1557def_numeric_from_vec!(Int64Type);
1558def_numeric_from_vec!(UInt8Type);
1559def_numeric_from_vec!(UInt16Type);
1560def_numeric_from_vec!(UInt32Type);
1561def_numeric_from_vec!(UInt64Type);
1562def_numeric_from_vec!(Float16Type);
1563def_numeric_from_vec!(Float32Type);
1564def_numeric_from_vec!(Float64Type);
1565def_numeric_from_vec!(Decimal32Type);
1566def_numeric_from_vec!(Decimal64Type);
1567def_numeric_from_vec!(Decimal128Type);
1568def_numeric_from_vec!(Decimal256Type);
1569
1570def_numeric_from_vec!(Date32Type);
1571def_numeric_from_vec!(Date64Type);
1572def_numeric_from_vec!(Time32SecondType);
1573def_numeric_from_vec!(Time32MillisecondType);
1574def_numeric_from_vec!(Time64MicrosecondType);
1575def_numeric_from_vec!(Time64NanosecondType);
1576def_numeric_from_vec!(IntervalYearMonthType);
1577def_numeric_from_vec!(IntervalDayTimeType);
1578def_numeric_from_vec!(IntervalMonthDayNanoType);
1579def_numeric_from_vec!(DurationSecondType);
1580def_numeric_from_vec!(DurationMillisecondType);
1581def_numeric_from_vec!(DurationMicrosecondType);
1582def_numeric_from_vec!(DurationNanosecondType);
1583def_numeric_from_vec!(TimestampSecondType);
1584def_numeric_from_vec!(TimestampMillisecondType);
1585def_numeric_from_vec!(TimestampMicrosecondType);
1586def_numeric_from_vec!(TimestampNanosecondType);
1587
1588impl<T: ArrowTimestampType> PrimitiveArray<T> {
1589    /// Returns the timezone of this array if any
1590    pub fn timezone(&self) -> Option<&str> {
1591        match self.data_type() {
1592            DataType::Timestamp(_, tz) => tz.as_deref(),
1593            _ => unreachable!(),
1594        }
1595    }
1596
1597    /// Construct a timestamp array with new timezone
1598    pub fn with_timezone(self, timezone: impl Into<Arc<str>>) -> Self {
1599        self.with_timezone_opt(Some(timezone.into()))
1600    }
1601
1602    /// Construct a timestamp array with UTC
1603    pub fn with_timezone_utc(self) -> Self {
1604        self.with_timezone("+00:00")
1605    }
1606
1607    /// Construct a timestamp array with an optional timezone
1608    pub fn with_timezone_opt<S: Into<Arc<str>>>(self, timezone: Option<S>) -> Self {
1609        Self {
1610            data_type: DataType::Timestamp(T::UNIT, timezone.map(Into::into)),
1611            ..self
1612        }
1613    }
1614}
1615
1616/// Constructs a `PrimitiveArray` from an array data reference.
1617impl<T: ArrowPrimitiveType> From<ArrayData> for PrimitiveArray<T> {
1618    fn from(data: ArrayData) -> Self {
1619        let (data_type, len, nulls, offset, mut buffers, _child_data) = data.into_parts();
1620
1621        Self::assert_compatible(&data_type);
1622        assert_eq!(
1623            buffers.len(),
1624            1,
1625            "PrimitiveArray data should contain a single buffer only (values buffer)"
1626        );
1627        let buffer = buffers.pop().expect("checked above");
1628
1629        let values = ScalarBuffer::new(buffer, offset, len);
1630        Self {
1631            data_type,
1632            values,
1633            nulls,
1634        }
1635    }
1636}
1637
1638impl<T: DecimalType + ArrowPrimitiveType> PrimitiveArray<T> {
1639    /// Returns a Decimal array with the same data as self, with the
1640    /// specified precision and scale.
1641    ///
1642    /// See [`validate_decimal_precision_and_scale`]
1643    pub fn with_precision_and_scale(self, precision: u8, scale: i8) -> Result<Self, ArrowError> {
1644        validate_decimal_precision_and_scale::<T>(precision, scale)?;
1645        Ok(Self {
1646            data_type: T::TYPE_CONSTRUCTOR(precision, scale),
1647            ..self
1648        })
1649    }
1650
1651    /// Validates values in this array can be properly interpreted
1652    /// with the specified precision.
1653    pub fn validate_decimal_precision(&self, precision: u8) -> Result<(), ArrowError> {
1654        if precision < self.scale() as u8 {
1655            return Err(ArrowError::InvalidArgumentError(format!(
1656                "Decimal precision {precision} is less than scale {}",
1657                self.scale()
1658            )));
1659        }
1660        (0..self.len()).try_for_each(|idx| {
1661            if self.is_valid(idx) {
1662                let decimal = unsafe { self.value_unchecked(idx) };
1663                T::validate_decimal_precision(decimal, precision, self.scale())
1664            } else {
1665                Ok(())
1666            }
1667        })
1668    }
1669
1670    /// Validates the Decimal Array, if the value of slot is overflow for the specified precision, and
1671    /// will be casted to Null
1672    pub fn null_if_overflow_precision(&self, precision: u8) -> Self {
1673        self.unary_opt::<_, T>(|v| T::is_valid_decimal_precision(v, precision).then_some(v))
1674    }
1675
1676    /// Returns [`Self::value`] formatted as a string
1677    pub fn value_as_string(&self, row: usize) -> String {
1678        T::format_decimal(self.value(row), self.precision(), self.scale())
1679    }
1680
1681    /// Returns the decimal precision of this array
1682    pub fn precision(&self) -> u8 {
1683        match T::BYTE_LENGTH {
1684            4 => {
1685                if let DataType::Decimal32(p, _) = self.data_type() {
1686                    *p
1687                } else {
1688                    unreachable!(
1689                        "Decimal32Array datatype is not DataType::Decimal32 but {}",
1690                        self.data_type()
1691                    )
1692                }
1693            }
1694            8 => {
1695                if let DataType::Decimal64(p, _) = self.data_type() {
1696                    *p
1697                } else {
1698                    unreachable!(
1699                        "Decimal64Array datatype is not DataType::Decimal64 but {}",
1700                        self.data_type()
1701                    )
1702                }
1703            }
1704            16 => {
1705                if let DataType::Decimal128(p, _) = self.data_type() {
1706                    *p
1707                } else {
1708                    unreachable!(
1709                        "Decimal128Array datatype is not DataType::Decimal128 but {}",
1710                        self.data_type()
1711                    )
1712                }
1713            }
1714            32 => {
1715                if let DataType::Decimal256(p, _) = self.data_type() {
1716                    *p
1717                } else {
1718                    unreachable!(
1719                        "Decimal256Array datatype is not DataType::Decimal256 but {}",
1720                        self.data_type()
1721                    )
1722                }
1723            }
1724            other => unreachable!("Unsupported byte length for decimal array {}", other),
1725        }
1726    }
1727
1728    /// Returns the decimal scale of this array
1729    pub fn scale(&self) -> i8 {
1730        match T::BYTE_LENGTH {
1731            4 => {
1732                if let DataType::Decimal32(_, s) = self.data_type() {
1733                    *s
1734                } else {
1735                    unreachable!(
1736                        "Decimal32Array datatype is not DataType::Decimal32 but {}",
1737                        self.data_type()
1738                    )
1739                }
1740            }
1741            8 => {
1742                if let DataType::Decimal64(_, s) = self.data_type() {
1743                    *s
1744                } else {
1745                    unreachable!(
1746                        "Decimal64Array datatype is not DataType::Decimal64 but {}",
1747                        self.data_type()
1748                    )
1749                }
1750            }
1751            16 => {
1752                if let DataType::Decimal128(_, s) = self.data_type() {
1753                    *s
1754                } else {
1755                    unreachable!(
1756                        "Decimal128Array datatype is not DataType::Decimal128 but {}",
1757                        self.data_type()
1758                    )
1759                }
1760            }
1761            32 => {
1762                if let DataType::Decimal256(_, s) = self.data_type() {
1763                    *s
1764                } else {
1765                    unreachable!(
1766                        "Decimal256Array datatype is not DataType::Decimal256 but {}",
1767                        self.data_type()
1768                    )
1769                }
1770            }
1771            other => unreachable!("Unsupported byte length for decimal array {}", other),
1772        }
1773    }
1774}
1775
1776#[cfg(test)]
1777mod tests {
1778    use super::*;
1779    use crate::BooleanArray;
1780    use crate::builder::{
1781        Decimal32Builder, Decimal64Builder, Decimal128Builder, Decimal256Builder,
1782    };
1783    use crate::cast::downcast_array;
1784    use arrow_buffer::{IntervalDayTime, IntervalMonthDayNano};
1785    use arrow_schema::TimeUnit;
1786
1787    #[test]
1788    fn test_primitive_array_from_vec() {
1789        let buf = Buffer::from_slice_ref([0, 1, 2, 3, 4]);
1790        let arr = Int32Array::from(vec![0, 1, 2, 3, 4]);
1791        assert_eq!(&buf, arr.values.inner());
1792        assert_eq!(5, arr.len());
1793        assert_eq!(0, arr.offset());
1794        assert_eq!(0, arr.null_count());
1795        for i in 0..5 {
1796            assert!(!arr.is_null(i));
1797            assert!(arr.is_valid(i));
1798            assert_eq!(i as i32, arr.value(i));
1799        }
1800    }
1801
1802    #[test]
1803    fn test_primitive_array_from_vec_option() {
1804        // Test building a primitive array with null values
1805        let arr = Int32Array::from(vec![Some(0), None, Some(2), None, Some(4)]);
1806        assert_eq!(5, arr.len());
1807        assert_eq!(0, arr.offset());
1808        assert_eq!(2, arr.null_count());
1809        for i in 0..5 {
1810            if i % 2 == 0 {
1811                assert!(!arr.is_null(i));
1812                assert!(arr.is_valid(i));
1813                assert_eq!(i as i32, arr.value(i));
1814            } else {
1815                assert!(arr.is_null(i));
1816                assert!(!arr.is_valid(i));
1817            }
1818        }
1819    }
1820
1821    #[test]
1822    fn test_date64_array_from_vec_option() {
1823        // Test building a primitive array with null values
1824        // we use Int32 and Int64 as a backing array, so all Int32 and Int64 conventions
1825        // work
1826        let arr: PrimitiveArray<Date64Type> =
1827            vec![Some(1550902545147), None, Some(1550902545147)].into();
1828        assert_eq!(3, arr.len());
1829        assert_eq!(0, arr.offset());
1830        assert_eq!(1, arr.null_count());
1831        for i in 0..3 {
1832            if i % 2 == 0 {
1833                assert!(!arr.is_null(i));
1834                assert!(arr.is_valid(i));
1835                assert_eq!(1550902545147, arr.value(i));
1836                // roundtrip to and from datetime
1837                assert_eq!(
1838                    1550902545147,
1839                    arr.value_as_datetime(i)
1840                        .unwrap()
1841                        .and_utc()
1842                        .timestamp_millis()
1843                );
1844            } else {
1845                assert!(arr.is_null(i));
1846                assert!(!arr.is_valid(i));
1847            }
1848        }
1849    }
1850
1851    #[test]
1852    fn test_time32_millisecond_array_from_vec() {
1853        // 1:        00:00:00.001
1854        // 37800005: 10:30:00.005
1855        // 86399210: 23:59:59.210
1856        let arr: PrimitiveArray<Time32MillisecondType> = vec![1, 37_800_005, 86_399_210].into();
1857        assert_eq!(3, arr.len());
1858        assert_eq!(0, arr.offset());
1859        assert_eq!(0, arr.null_count());
1860        let formatted = ["00:00:00.001", "10:30:00.005", "23:59:59.210"];
1861        for (i, formatted) in formatted.iter().enumerate().take(3) {
1862            // check that we can't create dates or datetimes from time instances
1863            assert_eq!(None, arr.value_as_datetime(i));
1864            assert_eq!(None, arr.value_as_date(i));
1865            let time = arr.value_as_time(i).unwrap();
1866            assert_eq!(*formatted, time.format("%H:%M:%S%.3f").to_string());
1867        }
1868    }
1869
1870    #[test]
1871    fn test_time64_nanosecond_array_from_vec() {
1872        // Test building a primitive array with null values
1873        // we use Int32 and Int64 as a backing array, so all Int32 and Int64 conventions
1874        // work
1875
1876        // 1e6:        00:00:00.001
1877        // 37800005e6: 10:30:00.005
1878        // 86399210e6: 23:59:59.210
1879        let arr: PrimitiveArray<Time64NanosecondType> =
1880            vec![1_000_000, 37_800_005_000_000, 86_399_210_000_000].into();
1881        assert_eq!(3, arr.len());
1882        assert_eq!(0, arr.offset());
1883        assert_eq!(0, arr.null_count());
1884        let formatted = ["00:00:00.001", "10:30:00.005", "23:59:59.210"];
1885        for (i, item) in formatted.iter().enumerate().take(3) {
1886            // check that we can't create dates or datetimes from time instances
1887            assert_eq!(None, arr.value_as_datetime(i));
1888            assert_eq!(None, arr.value_as_date(i));
1889            let time = arr.value_as_time(i).unwrap();
1890            assert_eq!(*item, time.format("%H:%M:%S%.3f").to_string());
1891        }
1892    }
1893
1894    #[test]
1895    fn test_interval_array_from_vec() {
1896        // intervals are currently not treated specially, but are Int32 and Int64 arrays
1897        let arr = IntervalYearMonthArray::from(vec![Some(1), None, Some(-5)]);
1898        assert_eq!(3, arr.len());
1899        assert_eq!(0, arr.offset());
1900        assert_eq!(1, arr.null_count());
1901        assert_eq!(1, arr.value(0));
1902        assert_eq!(1, arr.values()[0]);
1903        assert!(arr.is_null(1));
1904        assert_eq!(-5, arr.value(2));
1905        assert_eq!(-5, arr.values()[2]);
1906
1907        let v0 = IntervalDayTime {
1908            days: 34,
1909            milliseconds: 1,
1910        };
1911        let v2 = IntervalDayTime {
1912            days: -2,
1913            milliseconds: -5,
1914        };
1915
1916        let arr = IntervalDayTimeArray::from(vec![Some(v0), None, Some(v2)]);
1917
1918        assert_eq!(3, arr.len());
1919        assert_eq!(0, arr.offset());
1920        assert_eq!(1, arr.null_count());
1921        assert_eq!(v0, arr.value(0));
1922        assert_eq!(v0, arr.values()[0]);
1923        assert!(arr.is_null(1));
1924        assert_eq!(v2, arr.value(2));
1925        assert_eq!(v2, arr.values()[2]);
1926
1927        let v0 = IntervalMonthDayNano {
1928            months: 2,
1929            days: 34,
1930            nanoseconds: -1,
1931        };
1932        let v2 = IntervalMonthDayNano {
1933            months: -3,
1934            days: -2,
1935            nanoseconds: 4,
1936        };
1937
1938        let arr = IntervalMonthDayNanoArray::from(vec![Some(v0), None, Some(v2)]);
1939        assert_eq!(3, arr.len());
1940        assert_eq!(0, arr.offset());
1941        assert_eq!(1, arr.null_count());
1942        assert_eq!(v0, arr.value(0));
1943        assert_eq!(v0, arr.values()[0]);
1944        assert!(arr.is_null(1));
1945        assert_eq!(v2, arr.value(2));
1946        assert_eq!(v2, arr.values()[2]);
1947    }
1948
1949    #[test]
1950    fn test_duration_array_from_vec() {
1951        let arr = DurationSecondArray::from(vec![Some(1), None, Some(-5)]);
1952        assert_eq!(3, arr.len());
1953        assert_eq!(0, arr.offset());
1954        assert_eq!(1, arr.null_count());
1955        assert_eq!(1, arr.value(0));
1956        assert_eq!(1, arr.values()[0]);
1957        assert!(arr.is_null(1));
1958        assert_eq!(-5, arr.value(2));
1959        assert_eq!(-5, arr.values()[2]);
1960
1961        let arr = DurationMillisecondArray::from(vec![Some(1), None, Some(-5)]);
1962        assert_eq!(3, arr.len());
1963        assert_eq!(0, arr.offset());
1964        assert_eq!(1, arr.null_count());
1965        assert_eq!(1, arr.value(0));
1966        assert_eq!(1, arr.values()[0]);
1967        assert!(arr.is_null(1));
1968        assert_eq!(-5, arr.value(2));
1969        assert_eq!(-5, arr.values()[2]);
1970
1971        let arr = DurationMicrosecondArray::from(vec![Some(1), None, Some(-5)]);
1972        assert_eq!(3, arr.len());
1973        assert_eq!(0, arr.offset());
1974        assert_eq!(1, arr.null_count());
1975        assert_eq!(1, arr.value(0));
1976        assert_eq!(1, arr.values()[0]);
1977        assert!(arr.is_null(1));
1978        assert_eq!(-5, arr.value(2));
1979        assert_eq!(-5, arr.values()[2]);
1980
1981        let arr = DurationNanosecondArray::from(vec![Some(1), None, Some(-5)]);
1982        assert_eq!(3, arr.len());
1983        assert_eq!(0, arr.offset());
1984        assert_eq!(1, arr.null_count());
1985        assert_eq!(1, arr.value(0));
1986        assert_eq!(1, arr.values()[0]);
1987        assert!(arr.is_null(1));
1988        assert_eq!(-5, arr.value(2));
1989        assert_eq!(-5, arr.values()[2]);
1990    }
1991
1992    #[test]
1993    fn test_timestamp_array_from_vec() {
1994        let arr = TimestampSecondArray::from(vec![1, -5]);
1995        assert_eq!(2, arr.len());
1996        assert_eq!(0, arr.offset());
1997        assert_eq!(0, arr.null_count());
1998        assert_eq!(1, arr.value(0));
1999        assert_eq!(-5, arr.value(1));
2000        assert_eq!(&[1, -5], arr.values());
2001
2002        let arr = TimestampMillisecondArray::from(vec![1, -5]);
2003        assert_eq!(2, arr.len());
2004        assert_eq!(0, arr.offset());
2005        assert_eq!(0, arr.null_count());
2006        assert_eq!(1, arr.value(0));
2007        assert_eq!(-5, arr.value(1));
2008        assert_eq!(&[1, -5], arr.values());
2009
2010        let arr = TimestampMicrosecondArray::from(vec![1, -5]);
2011        assert_eq!(2, arr.len());
2012        assert_eq!(0, arr.offset());
2013        assert_eq!(0, arr.null_count());
2014        assert_eq!(1, arr.value(0));
2015        assert_eq!(-5, arr.value(1));
2016        assert_eq!(&[1, -5], arr.values());
2017
2018        let arr = TimestampNanosecondArray::from(vec![1, -5]);
2019        assert_eq!(2, arr.len());
2020        assert_eq!(0, arr.offset());
2021        assert_eq!(0, arr.null_count());
2022        assert_eq!(1, arr.value(0));
2023        assert_eq!(-5, arr.value(1));
2024        assert_eq!(&[1, -5], arr.values());
2025    }
2026
2027    #[test]
2028    fn test_primitive_array_slice() {
2029        let arr = Int32Array::from(vec![
2030            Some(0),
2031            None,
2032            Some(2),
2033            None,
2034            Some(4),
2035            Some(5),
2036            Some(6),
2037            None,
2038            None,
2039        ]);
2040        assert_eq!(9, arr.len());
2041        assert_eq!(0, arr.offset());
2042        assert_eq!(4, arr.null_count());
2043
2044        let arr2 = arr.slice(2, 5);
2045        assert_eq!(5, arr2.len());
2046        assert_eq!(1, arr2.null_count());
2047
2048        for i in 0..arr2.len() {
2049            assert_eq!(i == 1, arr2.is_null(i));
2050            assert_eq!(i != 1, arr2.is_valid(i));
2051        }
2052        let int_arr2 = arr2.as_any().downcast_ref::<Int32Array>().unwrap();
2053        assert_eq!(2, int_arr2.values()[0]);
2054        assert_eq!(&[4, 5, 6], &int_arr2.values()[2..5]);
2055
2056        let arr3 = arr2.slice(2, 3);
2057        assert_eq!(3, arr3.len());
2058        assert_eq!(0, arr3.null_count());
2059
2060        let int_arr3 = arr3.as_any().downcast_ref::<Int32Array>().unwrap();
2061        assert_eq!(&[4, 5, 6], int_arr3.values());
2062        assert_eq!(4, int_arr3.value(0));
2063        assert_eq!(5, int_arr3.value(1));
2064        assert_eq!(6, int_arr3.value(2));
2065    }
2066
2067    #[test]
2068    fn test_boolean_array_slice() {
2069        let arr = BooleanArray::from(vec![
2070            Some(true),
2071            None,
2072            Some(false),
2073            None,
2074            Some(true),
2075            Some(false),
2076            Some(true),
2077            Some(false),
2078            None,
2079            Some(true),
2080        ]);
2081
2082        assert_eq!(10, arr.len());
2083        assert_eq!(0, arr.offset());
2084        assert_eq!(3, arr.null_count());
2085
2086        let arr2 = arr.slice(3, 5);
2087        assert_eq!(5, arr2.len());
2088        assert_eq!(3, arr2.offset());
2089        assert_eq!(1, arr2.null_count());
2090
2091        let bool_arr = arr2.as_any().downcast_ref::<BooleanArray>().unwrap();
2092
2093        assert!(!bool_arr.is_valid(0));
2094
2095        assert!(bool_arr.is_valid(1));
2096        assert!(bool_arr.value(1));
2097
2098        assert!(bool_arr.is_valid(2));
2099        assert!(!bool_arr.value(2));
2100
2101        assert!(bool_arr.is_valid(3));
2102        assert!(bool_arr.value(3));
2103
2104        assert!(bool_arr.is_valid(4));
2105        assert!(!bool_arr.value(4));
2106    }
2107
2108    #[test]
2109    fn test_int32_fmt_debug() {
2110        let arr = Int32Array::from(vec![0, 1, 2, 3, 4]);
2111        assert_eq!(
2112            "PrimitiveArray<Int32>\n[\n  0,\n  1,\n  2,\n  3,\n  4,\n]",
2113            format!("{arr:?}")
2114        );
2115    }
2116
2117    #[test]
2118    fn test_fmt_debug_up_to_20_elements() {
2119        (1..=20).for_each(|i| {
2120            let values = (0..i).collect::<Vec<i16>>();
2121            let array_expected = format!(
2122                "PrimitiveArray<Int16>\n[\n{}\n]",
2123                values
2124                    .iter()
2125                    .map(|v| { format!("  {v},") })
2126                    .collect::<Vec<String>>()
2127                    .join("\n")
2128            );
2129            let array = Int16Array::from(values);
2130
2131            assert_eq!(array_expected, format!("{array:?}"));
2132        })
2133    }
2134
2135    #[test]
2136    fn test_int32_with_null_fmt_debug() {
2137        let mut builder = Int32Array::builder(3);
2138        builder.append_slice(&[0, 1]);
2139        builder.append_null();
2140        builder.append_slice(&[3, 4]);
2141        let arr = builder.finish();
2142        assert_eq!(
2143            "PrimitiveArray<Int32>\n[\n  0,\n  1,\n  null,\n  3,\n  4,\n]",
2144            format!("{arr:?}")
2145        );
2146    }
2147
2148    #[test]
2149    fn test_timestamp_fmt_debug() {
2150        let arr: PrimitiveArray<TimestampMillisecondType> =
2151            TimestampMillisecondArray::from(vec![1546214400000, 1546214400000, -1546214400000]);
2152        assert_eq!(
2153            "PrimitiveArray<Timestamp(ms)>\n[\n  2018-12-31T00:00:00,\n  2018-12-31T00:00:00,\n  1921-01-02T00:00:00,\n]",
2154            format!("{arr:?}")
2155        );
2156    }
2157
2158    #[test]
2159    fn test_timestamp_fmt_debug_out_of_range() {
2160        // Include a true null into dataset to ensure we don't write that as an error
2161        let data = Int64Array::new(
2162            vec![i64::MAX, i64::MIN, i64::MAX].into(),
2163            Some(vec![true, true, false].into()),
2164        );
2165
2166        let arr = data.reinterpret_cast::<TimestampSecondType>();
2167        assert_eq!(
2168            "PrimitiveArray<Timestamp(s)>
2169[
2170  Cast error: Failed to convert 9223372036854775807 to timestamp for Timestamp(s),
2171  Cast error: Failed to convert -9223372036854775808 to timestamp for Timestamp(s),
2172  null,
2173]",
2174            format!("{arr:?}")
2175        );
2176
2177        let arr = data.reinterpret_cast::<TimestampMillisecondType>();
2178        assert_eq!(
2179            "PrimitiveArray<Timestamp(ms)>
2180[
2181  Cast error: Failed to convert 9223372036854775807 to timestamp for Timestamp(ms),
2182  Cast error: Failed to convert -9223372036854775808 to timestamp for Timestamp(ms),
2183  null,
2184]",
2185            format!("{arr:?}")
2186        );
2187
2188        let arr = data.reinterpret_cast::<TimestampMicrosecondType>();
2189        assert_eq!(
2190            "PrimitiveArray<Timestamp(µs)>
2191[
2192  Cast error: Failed to convert 9223372036854775807 to timestamp for Timestamp(µs),
2193  Cast error: Failed to convert -9223372036854775808 to timestamp for Timestamp(µs),
2194  null,
2195]",
2196            format!("{arr:?}")
2197        );
2198
2199        // Nanoseconds always in range
2200        let arr = data.reinterpret_cast::<TimestampNanosecondType>();
2201        assert_eq!(
2202            "PrimitiveArray<Timestamp(ns)>
2203[
2204  2262-04-11T23:47:16.854775807,
2205  1677-09-21T00:12:43.145224192,
2206  null,
2207]",
2208            format!("{arr:?}")
2209        );
2210    }
2211
2212    #[test]
2213    fn test_timestamp_utc_fmt_debug() {
2214        let arr: PrimitiveArray<TimestampMillisecondType> =
2215            TimestampMillisecondArray::from(vec![1546214400000, 1546214400000, -1546214400000])
2216                .with_timezone_utc();
2217        assert_eq!(
2218            "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]",
2219            format!("{arr:?}")
2220        );
2221    }
2222
2223    #[test]
2224    #[cfg(feature = "chrono-tz")]
2225    fn test_timestamp_with_named_tz_fmt_debug() {
2226        let arr: PrimitiveArray<TimestampMillisecondType> =
2227            TimestampMillisecondArray::from(vec![1546214400000, 1546214400000, -1546214400000])
2228                .with_timezone("Asia/Taipei".to_string());
2229        assert_eq!(
2230            "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]",
2231            format!("{arr:?}")
2232        );
2233    }
2234
2235    #[test]
2236    #[cfg(not(feature = "chrono-tz"))]
2237    fn test_timestamp_with_named_tz_fmt_debug() {
2238        let arr: PrimitiveArray<TimestampMillisecondType> =
2239            TimestampMillisecondArray::from(vec![1546214400000, 1546214400000, -1546214400000])
2240                .with_timezone("Asia/Taipei".to_string());
2241
2242        println!("{arr:?}");
2243
2244        assert_eq!(
2245            "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]",
2246            format!("{arr:?}")
2247        );
2248    }
2249
2250    #[test]
2251    fn test_timestamp_with_fixed_offset_tz_fmt_debug() {
2252        let arr: PrimitiveArray<TimestampMillisecondType> =
2253            TimestampMillisecondArray::from(vec![1546214400000, 1546214400000, -1546214400000])
2254                .with_timezone("+08:00".to_string());
2255        assert_eq!(
2256            "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]",
2257            format!("{arr:?}")
2258        );
2259    }
2260
2261    #[test]
2262    fn test_timestamp_with_incorrect_tz_fmt_debug() {
2263        let arr: PrimitiveArray<TimestampMillisecondType> =
2264            TimestampMillisecondArray::from(vec![1546214400000, 1546214400000, -1546214400000])
2265                .with_timezone("xxx".to_string());
2266        assert_eq!(
2267            "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]",
2268            format!("{arr:?}")
2269        );
2270    }
2271
2272    #[test]
2273    #[cfg(feature = "chrono-tz")]
2274    fn test_timestamp_with_tz_with_daylight_saving_fmt_debug() {
2275        let arr: PrimitiveArray<TimestampMillisecondType> = TimestampMillisecondArray::from(vec![
2276            1647161999000,
2277            1647162000000,
2278            1667717999000,
2279            1667718000000,
2280        ])
2281        .with_timezone("America/Denver".to_string());
2282        assert_eq!(
2283            "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]",
2284            format!("{arr:?}")
2285        );
2286    }
2287
2288    #[test]
2289    fn test_date32_fmt_debug() {
2290        let arr: PrimitiveArray<Date32Type> = vec![12356, 13548, -365].into();
2291        assert_eq!(
2292            "PrimitiveArray<Date32>\n[\n  2003-10-31,\n  2007-02-04,\n  1969-01-01,\n]",
2293            format!("{arr:?}")
2294        );
2295    }
2296
2297    #[test]
2298    fn test_time32second_fmt_debug() {
2299        let arr: PrimitiveArray<Time32SecondType> = vec![7201, 60054].into();
2300        assert_eq!(
2301            "PrimitiveArray<Time32(s)>\n[\n  02:00:01,\n  16:40:54,\n]",
2302            format!("{arr:?}")
2303        );
2304    }
2305
2306    #[test]
2307    fn test_time32second_invalid_neg() {
2308        // chrono::NaiveDatetime::from_timestamp_opt returns None while input is invalid
2309        let arr: PrimitiveArray<Time32SecondType> = vec![-7201, -60054].into();
2310        assert_eq!(
2311            "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]",
2312            // "PrimitiveArray<Time32(s)>\n[\n  null,\n  null,\n]",
2313            format!("{arr:?}")
2314        )
2315    }
2316
2317    #[test]
2318    fn test_primitive_array_builder() {
2319        // Test building a primitive array with ArrayData builder and offset
2320        let buf = Buffer::from_slice_ref([0i32, 1, 2, 3, 4, 5, 6]);
2321        let buf2 = buf.slice_with_length(8, 20);
2322        let data = ArrayData::builder(DataType::Int32)
2323            .len(5)
2324            .offset(2)
2325            .add_buffer(buf)
2326            .build()
2327            .unwrap();
2328        let arr = Int32Array::from(data);
2329        assert_eq!(&buf2, arr.values.inner());
2330        assert_eq!(5, arr.len());
2331        assert_eq!(0, arr.null_count());
2332        for i in 0..3 {
2333            assert_eq!((i + 2) as i32, arr.value(i));
2334        }
2335    }
2336
2337    #[test]
2338    fn test_primitive_from_iter_values() {
2339        // Test building a primitive array with from_iter_values
2340        let arr: PrimitiveArray<Int32Type> = PrimitiveArray::from_iter_values(0..10);
2341        assert_eq!(10, arr.len());
2342        assert_eq!(0, arr.null_count());
2343        for i in 0..10i32 {
2344            assert_eq!(i, arr.value(i as usize));
2345        }
2346    }
2347
2348    #[test]
2349    fn test_primitive_array_from_unbound_iter() {
2350        // iterator that doesn't declare (upper) size bound
2351        let value_iter = (0..)
2352            .scan(0usize, |pos, i| {
2353                if *pos < 10 {
2354                    *pos += 1;
2355                    Some(Some(i))
2356                } else {
2357                    // actually returns up to 10 values
2358                    None
2359                }
2360            })
2361            // limited using take()
2362            .take(100);
2363
2364        let (_, upper_size_bound) = value_iter.size_hint();
2365        // the upper bound, defined by take above, is 100
2366        assert_eq!(upper_size_bound, Some(100));
2367        let primitive_array: PrimitiveArray<Int32Type> = value_iter.collect();
2368        // but the actual number of items in the array should be 10
2369        assert_eq!(primitive_array.len(), 10);
2370    }
2371
2372    #[test]
2373    fn test_primitive_array_from_non_null_iter() {
2374        let iter = (0..10_i32).map(Some);
2375        let primitive_array = PrimitiveArray::<Int32Type>::from_iter(iter);
2376        assert_eq!(primitive_array.len(), 10);
2377        assert_eq!(primitive_array.null_count(), 0);
2378        assert!(primitive_array.nulls().is_none());
2379        assert_eq!(primitive_array.values(), &[0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
2380    }
2381
2382    #[test]
2383    #[should_panic(expected = "PrimitiveArray data should contain a single buffer only \
2384                               (values buffer)")]
2385    // Different error messages, so skip for now
2386    // https://github.com/apache/arrow-rs/issues/1545
2387    #[cfg(not(feature = "force_validate"))]
2388    fn test_primitive_array_invalid_buffer_len() {
2389        let buffer = Buffer::from_slice_ref([0i32, 1, 2, 3, 4]);
2390        let data = unsafe {
2391            ArrayData::builder(DataType::Int32)
2392                .add_buffer(buffer.clone())
2393                .add_buffer(buffer)
2394                .len(5)
2395                .build_unchecked()
2396        };
2397
2398        drop(Int32Array::from(data));
2399    }
2400
2401    #[test]
2402    fn test_access_array_concurrently() {
2403        let a = Int32Array::from(vec![5, 6, 7, 8, 9]);
2404        let ret = std::thread::spawn(move || a.value(3)).join();
2405
2406        assert!(ret.is_ok());
2407        assert_eq!(8, ret.ok().unwrap());
2408    }
2409
2410    #[test]
2411    fn test_primitive_array_creation() {
2412        let array1: Int8Array = [10_i8, 11, 12, 13, 14].into_iter().collect();
2413        let array2: Int8Array = [10_i8, 11, 12, 13, 14].into_iter().map(Some).collect();
2414
2415        assert_eq!(array1, array2);
2416    }
2417
2418    #[test]
2419    #[should_panic(
2420        expected = "Trying to access an element at index 4 from a PrimitiveArray of length 3"
2421    )]
2422    fn test_string_array_get_value_index_out_of_bound() {
2423        let array: Int8Array = [10_i8, 11, 12].into_iter().collect();
2424
2425        array.value(4);
2426    }
2427
2428    #[test]
2429    #[should_panic(expected = "PrimitiveArray expected data type Int64 got Int32")]
2430    fn test_from_array_data_validation() {
2431        let foo = PrimitiveArray::<Int32Type>::from_iter([1, 2, 3]);
2432        let _ = PrimitiveArray::<Int64Type>::from(foo.into_data());
2433    }
2434
2435    #[test]
2436    fn test_decimal32() {
2437        let values: Vec<_> = vec![0, 1, -1, i32::MIN, i32::MAX];
2438        let array: PrimitiveArray<Decimal32Type> =
2439            PrimitiveArray::from_iter(values.iter().copied());
2440        assert_eq!(array.values(), &values);
2441
2442        let array: PrimitiveArray<Decimal32Type> =
2443            PrimitiveArray::from_iter_values(values.iter().copied());
2444        assert_eq!(array.values(), &values);
2445
2446        let array = PrimitiveArray::<Decimal32Type>::from(values.clone());
2447        assert_eq!(array.values(), &values);
2448
2449        let array = PrimitiveArray::<Decimal32Type>::from(array.to_data());
2450        assert_eq!(array.values(), &values);
2451    }
2452
2453    #[test]
2454    fn test_decimal64() {
2455        let values: Vec<_> = vec![0, 1, -1, i64::MIN, i64::MAX];
2456        let array: PrimitiveArray<Decimal64Type> =
2457            PrimitiveArray::from_iter(values.iter().copied());
2458        assert_eq!(array.values(), &values);
2459
2460        let array: PrimitiveArray<Decimal64Type> =
2461            PrimitiveArray::from_iter_values(values.iter().copied());
2462        assert_eq!(array.values(), &values);
2463
2464        let array = PrimitiveArray::<Decimal64Type>::from(values.clone());
2465        assert_eq!(array.values(), &values);
2466
2467        let array = PrimitiveArray::<Decimal64Type>::from(array.to_data());
2468        assert_eq!(array.values(), &values);
2469    }
2470
2471    #[test]
2472    fn test_decimal128() {
2473        let values: Vec<_> = vec![0, 1, -1, i128::MIN, i128::MAX];
2474        let array: PrimitiveArray<Decimal128Type> =
2475            PrimitiveArray::from_iter(values.iter().copied());
2476        assert_eq!(array.values(), &values);
2477
2478        let array: PrimitiveArray<Decimal128Type> =
2479            PrimitiveArray::from_iter_values(values.iter().copied());
2480        assert_eq!(array.values(), &values);
2481
2482        let array = PrimitiveArray::<Decimal128Type>::from(values.clone());
2483        assert_eq!(array.values(), &values);
2484
2485        let array = PrimitiveArray::<Decimal128Type>::from(array.to_data());
2486        assert_eq!(array.values(), &values);
2487    }
2488
2489    #[test]
2490    fn test_decimal256() {
2491        let values: Vec<_> = vec![i256::ZERO, i256::ONE, i256::MINUS_ONE, i256::MIN, i256::MAX];
2492
2493        let array: PrimitiveArray<Decimal256Type> =
2494            PrimitiveArray::from_iter(values.iter().copied());
2495        assert_eq!(array.values(), &values);
2496
2497        let array: PrimitiveArray<Decimal256Type> =
2498            PrimitiveArray::from_iter_values(values.iter().copied());
2499        assert_eq!(array.values(), &values);
2500
2501        let array = PrimitiveArray::<Decimal256Type>::from(values.clone());
2502        assert_eq!(array.values(), &values);
2503
2504        let array = PrimitiveArray::<Decimal256Type>::from(array.to_data());
2505        assert_eq!(array.values(), &values);
2506    }
2507
2508    #[test]
2509    fn test_decimal_array() {
2510        // let val_8887: [u8; 16] = [192, 219, 180, 17, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
2511        // let val_neg_8887: [u8; 16] = [64, 36, 75, 238, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255];
2512        let values: [u8; 32] = [
2513            192, 219, 180, 17, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 64, 36, 75, 238, 253, 255, 255,
2514            255, 255, 255, 255, 255, 255, 255, 255, 255,
2515        ];
2516        let array_data = ArrayData::builder(DataType::Decimal128(38, 6))
2517            .len(2)
2518            .add_buffer(Buffer::from(&values))
2519            .build()
2520            .unwrap();
2521        let decimal_array = Decimal128Array::from(array_data);
2522        assert_eq!(8_887_000_000_i128, decimal_array.value(0));
2523        assert_eq!(-8_887_000_000_i128, decimal_array.value(1));
2524    }
2525
2526    #[test]
2527    fn test_decimal_append_error_value() {
2528        let mut decimal_builder = Decimal128Builder::with_capacity(10);
2529        decimal_builder.append_value(123456);
2530        decimal_builder.append_value(12345);
2531        let result = decimal_builder.finish().with_precision_and_scale(5, 3);
2532        assert!(result.is_ok());
2533        let arr = result.unwrap();
2534        assert_eq!("12.345", arr.value_as_string(1));
2535
2536        // Validate it explicitly
2537        let result = arr.validate_decimal_precision(5);
2538        let error = result.unwrap_err();
2539        assert_eq!(
2540            "Invalid argument error: 123.456 is too large to store in a Decimal128 of precision 5. Max is 99.999",
2541            error.to_string()
2542        );
2543
2544        decimal_builder = Decimal128Builder::new();
2545        decimal_builder.append_value(100);
2546        decimal_builder.append_value(99);
2547        decimal_builder.append_value(-100);
2548        decimal_builder.append_value(-99);
2549        let result = decimal_builder.finish().with_precision_and_scale(2, 1);
2550        assert!(result.is_ok());
2551        let arr = result.unwrap();
2552        assert_eq!("9.9", arr.value_as_string(1));
2553        assert_eq!("-9.9", arr.value_as_string(3));
2554
2555        // Validate it explicitly
2556        let result = arr.validate_decimal_precision(2);
2557        let error = result.unwrap_err();
2558        assert_eq!(
2559            "Invalid argument error: 10.0 is too large to store in a Decimal128 of precision 2. Max is 9.9",
2560            error.to_string()
2561        );
2562    }
2563
2564    #[test]
2565    fn test_decimal_from_iter_values() {
2566        let array = Decimal128Array::from_iter_values(vec![-100, 0, 101]);
2567        assert_eq!(array.len(), 3);
2568        assert_eq!(array.data_type(), &DataType::Decimal128(38, 10));
2569        assert_eq!(-100_i128, array.value(0));
2570        assert!(!array.is_null(0));
2571        assert_eq!(0_i128, array.value(1));
2572        assert!(!array.is_null(1));
2573        assert_eq!(101_i128, array.value(2));
2574        assert!(!array.is_null(2));
2575    }
2576
2577    #[test]
2578    fn test_decimal_from_iter() {
2579        let array: Decimal128Array = vec![Some(-100), None, Some(101)].into_iter().collect();
2580        assert_eq!(array.len(), 3);
2581        assert_eq!(array.data_type(), &DataType::Decimal128(38, 10));
2582        assert_eq!(-100_i128, array.value(0));
2583        assert!(!array.is_null(0));
2584        assert!(array.is_null(1));
2585        assert_eq!(101_i128, array.value(2));
2586        assert!(!array.is_null(2));
2587    }
2588
2589    #[test]
2590    fn test_decimal_iter_sized() {
2591        let data = vec![Some(-100), None, Some(101)];
2592        let array: Decimal128Array = data.into_iter().collect();
2593        let mut iter = array.into_iter();
2594
2595        // is exact sized
2596        assert_eq!(array.len(), 3);
2597
2598        // size_hint is reported correctly
2599        assert_eq!(iter.size_hint(), (3, Some(3)));
2600        iter.next().unwrap();
2601        assert_eq!(iter.size_hint(), (2, Some(2)));
2602        iter.next().unwrap();
2603        iter.next().unwrap();
2604        assert_eq!(iter.size_hint(), (0, Some(0)));
2605        assert!(iter.next().is_none());
2606        assert_eq!(iter.size_hint(), (0, Some(0)));
2607    }
2608
2609    #[test]
2610    fn test_decimal_array_value_as_string() {
2611        let arr = [123450, -123450, 100, -100, 10, -10, 0]
2612            .into_iter()
2613            .map(Some)
2614            .collect::<Decimal128Array>()
2615            .with_precision_and_scale(6, 3)
2616            .unwrap();
2617
2618        assert_eq!("123.450", arr.value_as_string(0));
2619        assert_eq!("-123.450", arr.value_as_string(1));
2620        assert_eq!("0.100", arr.value_as_string(2));
2621        assert_eq!("-0.100", arr.value_as_string(3));
2622        assert_eq!("0.010", arr.value_as_string(4));
2623        assert_eq!("-0.010", arr.value_as_string(5));
2624        assert_eq!("0.000", arr.value_as_string(6));
2625    }
2626
2627    #[test]
2628    fn test_decimal_array_with_precision_and_scale() {
2629        let arr = Decimal128Array::from_iter_values([12345, 456, 7890, -123223423432432])
2630            .with_precision_and_scale(20, 2)
2631            .unwrap();
2632
2633        assert_eq!(arr.data_type(), &DataType::Decimal128(20, 2));
2634        assert_eq!(arr.precision(), 20);
2635        assert_eq!(arr.scale(), 2);
2636
2637        let actual: Vec<_> = (0..arr.len()).map(|i| arr.value_as_string(i)).collect();
2638        let expected = vec!["123.45", "4.56", "78.90", "-1232234234324.32"];
2639
2640        assert_eq!(actual, expected);
2641    }
2642
2643    #[test]
2644    #[should_panic(
2645        expected = "-1232234234324.32 is too small to store in a Decimal128 of precision 5. Min is -999.99"
2646    )]
2647    fn test_decimal_array_with_precision_and_scale_out_of_range() {
2648        let arr = Decimal128Array::from_iter_values([12345, 456, 7890, -123223423432432])
2649            // precision is too small to hold value
2650            .with_precision_and_scale(5, 2)
2651            .unwrap();
2652        arr.validate_decimal_precision(5).unwrap();
2653    }
2654
2655    #[test]
2656    #[should_panic(expected = "precision cannot be 0, has to be between [1, 38]")]
2657    fn test_decimal_array_with_precision_zero() {
2658        Decimal128Array::from_iter_values([12345, 456])
2659            .with_precision_and_scale(0, 2)
2660            .unwrap();
2661    }
2662
2663    #[test]
2664    #[should_panic(expected = "precision 40 is greater than max 38")]
2665    fn test_decimal_array_with_precision_and_scale_invalid_precision() {
2666        Decimal128Array::from_iter_values([12345, 456])
2667            .with_precision_and_scale(40, 2)
2668            .unwrap();
2669    }
2670
2671    #[test]
2672    #[should_panic(expected = "scale 40 is greater than max 38")]
2673    fn test_decimal_array_with_precision_and_scale_invalid_scale() {
2674        Decimal128Array::from_iter_values([12345, 456])
2675            .with_precision_and_scale(20, 40)
2676            .unwrap();
2677    }
2678
2679    #[test]
2680    #[should_panic(expected = "scale 10 is greater than precision 4")]
2681    fn test_decimal_array_with_precision_and_scale_invalid_precision_and_scale() {
2682        Decimal128Array::from_iter_values([12345, 456])
2683            .with_precision_and_scale(4, 10)
2684            .unwrap();
2685    }
2686
2687    #[test]
2688    fn test_decimal_array_set_null_if_overflow_with_precision() {
2689        let array = Decimal128Array::from(vec![Some(123456), Some(123), None, Some(123456)]);
2690        let result = array.null_if_overflow_precision(5);
2691        let expected = Decimal128Array::from(vec![None, Some(123), None, None]);
2692        assert_eq!(result, expected);
2693    }
2694
2695    #[test]
2696    fn test_decimal256_iter() {
2697        let mut builder = Decimal256Builder::with_capacity(30);
2698        let decimal1 = i256::from_i128(12345);
2699        builder.append_value(decimal1);
2700
2701        builder.append_null();
2702
2703        let decimal2 = i256::from_i128(56789);
2704        builder.append_value(decimal2);
2705
2706        let array: Decimal256Array = builder.finish().with_precision_and_scale(76, 6).unwrap();
2707
2708        let collected: Vec<_> = array.iter().collect();
2709        assert_eq!(vec![Some(decimal1), None, Some(decimal2)], collected);
2710    }
2711
2712    #[test]
2713    fn test_from_iter_decimal256array() {
2714        let value1 = i256::from_i128(12345);
2715        let value2 = i256::from_i128(56789);
2716
2717        let mut array: Decimal256Array =
2718            vec![Some(value1), None, Some(value2)].into_iter().collect();
2719        array = array.with_precision_and_scale(76, 10).unwrap();
2720        assert_eq!(array.len(), 3);
2721        assert_eq!(array.data_type(), &DataType::Decimal256(76, 10));
2722        assert_eq!(value1, array.value(0));
2723        assert!(!array.is_null(0));
2724        assert!(array.is_null(1));
2725        assert_eq!(value2, array.value(2));
2726        assert!(!array.is_null(2));
2727    }
2728
2729    #[test]
2730    fn test_from_iter_decimal128array() {
2731        let mut array: Decimal128Array = vec![Some(-100), None, Some(101)].into_iter().collect();
2732        array = array.with_precision_and_scale(38, 10).unwrap();
2733        assert_eq!(array.len(), 3);
2734        assert_eq!(array.data_type(), &DataType::Decimal128(38, 10));
2735        assert_eq!(-100_i128, array.value(0));
2736        assert!(!array.is_null(0));
2737        assert!(array.is_null(1));
2738        assert_eq!(101_i128, array.value(2));
2739        assert!(!array.is_null(2));
2740    }
2741
2742    #[test]
2743    fn test_decimal64_iter() {
2744        let mut builder = Decimal64Builder::with_capacity(30);
2745        let decimal1 = 12345;
2746        builder.append_value(decimal1);
2747
2748        builder.append_null();
2749
2750        let decimal2 = 56789;
2751        builder.append_value(decimal2);
2752
2753        let array: Decimal64Array = builder.finish().with_precision_and_scale(18, 4).unwrap();
2754
2755        let collected: Vec<_> = array.iter().collect();
2756        assert_eq!(vec![Some(decimal1), None, Some(decimal2)], collected);
2757    }
2758
2759    #[test]
2760    fn test_from_iter_decimal64array() {
2761        let value1 = 12345;
2762        let value2 = 56789;
2763
2764        let mut array: Decimal64Array =
2765            vec![Some(value1), None, Some(value2)].into_iter().collect();
2766        array = array.with_precision_and_scale(18, 4).unwrap();
2767        assert_eq!(array.len(), 3);
2768        assert_eq!(array.data_type(), &DataType::Decimal64(18, 4));
2769        assert_eq!(value1, array.value(0));
2770        assert!(!array.is_null(0));
2771        assert!(array.is_null(1));
2772        assert_eq!(value2, array.value(2));
2773        assert!(!array.is_null(2));
2774    }
2775
2776    #[test]
2777    fn test_decimal32_iter() {
2778        let mut builder = Decimal32Builder::with_capacity(30);
2779        let decimal1 = 12345;
2780        builder.append_value(decimal1);
2781
2782        builder.append_null();
2783
2784        let decimal2 = 56789;
2785        builder.append_value(decimal2);
2786
2787        let array: Decimal32Array = builder.finish().with_precision_and_scale(9, 2).unwrap();
2788
2789        let collected: Vec<_> = array.iter().collect();
2790        assert_eq!(vec![Some(decimal1), None, Some(decimal2)], collected);
2791    }
2792
2793    #[test]
2794    fn test_from_iter_decimal32array() {
2795        let value1 = 12345;
2796        let value2 = 56789;
2797
2798        let mut array: Decimal32Array =
2799            vec![Some(value1), None, Some(value2)].into_iter().collect();
2800        array = array.with_precision_and_scale(9, 2).unwrap();
2801        assert_eq!(array.len(), 3);
2802        assert_eq!(array.data_type(), &DataType::Decimal32(9, 2));
2803        assert_eq!(value1, array.value(0));
2804        assert!(!array.is_null(0));
2805        assert!(array.is_null(1));
2806        assert_eq!(value2, array.value(2));
2807        assert!(!array.is_null(2));
2808    }
2809
2810    #[test]
2811    fn test_unary_opt() {
2812        let array = Int32Array::from(vec![1, 2, 3, 4, 5, 6, 7]);
2813        let r = array.unary_opt::<_, Int32Type>(|x| (x % 2 != 0).then_some(x));
2814
2815        let expected = Int32Array::from(vec![Some(1), None, Some(3), None, Some(5), None, Some(7)]);
2816        assert_eq!(r, expected);
2817
2818        let r = expected.unary_opt::<_, Int32Type>(|x| (x % 3 != 0).then_some(x));
2819        let expected = Int32Array::from(vec![Some(1), None, None, None, Some(5), None, Some(7)]);
2820        assert_eq!(r, expected);
2821    }
2822
2823    #[test]
2824    #[should_panic(
2825        expected = "Trying to access an element at index 4 from a PrimitiveArray of length 3"
2826    )]
2827    fn test_fixed_size_binary_array_get_value_index_out_of_bound() {
2828        let array = Decimal128Array::from(vec![-100, 0, 101]);
2829        array.value(4);
2830    }
2831
2832    #[test]
2833    fn test_into_builder() {
2834        let array: Int32Array = vec![1, 2, 3].into_iter().map(Some).collect();
2835
2836        let boxed: ArrayRef = Arc::new(array);
2837        let col: Int32Array = downcast_array(&boxed);
2838        drop(boxed);
2839
2840        let mut builder = col.into_builder().unwrap();
2841
2842        let slice = builder.values_slice_mut();
2843        assert_eq!(slice, &[1, 2, 3]);
2844
2845        slice[0] = 4;
2846        slice[1] = 2;
2847        slice[2] = 1;
2848
2849        let expected: Int32Array = vec![Some(4), Some(2), Some(1)].into_iter().collect();
2850
2851        let new_array = builder.finish();
2852        assert_eq!(expected, new_array);
2853    }
2854
2855    #[test]
2856    fn test_into_builder_cloned_array() {
2857        let array: Int32Array = vec![1, 2, 3].into_iter().map(Some).collect();
2858
2859        let boxed: ArrayRef = Arc::new(array);
2860
2861        let col: Int32Array = PrimitiveArray::<Int32Type>::from(boxed.to_data());
2862        let err = col.into_builder();
2863
2864        match err {
2865            Ok(_) => panic!("Should not get builder from cloned array"),
2866            Err(returned) => {
2867                let expected: Int32Array = vec![1, 2, 3].into_iter().map(Some).collect();
2868                assert_eq!(expected, returned)
2869            }
2870        }
2871    }
2872
2873    #[test]
2874    fn test_into_builder_keeps_data_type() {
2875        let array = Decimal128Array::from(vec![1, 2])
2876            .with_precision_and_scale(10, 2)
2877            .unwrap();
2878        let data_type = array.data_type().clone();
2879
2880        // Shared buffers: the array is returned
2881        let shared = array.clone();
2882        let array = array.into_builder().unwrap_err();
2883        assert_eq!(array.data_type(), &data_type);
2884        drop(shared);
2885
2886        // Unshared buffers: the buffers are reused by the builder
2887        let mut builder = array.into_builder().unwrap();
2888        builder.append_value(3);
2889        assert_eq!(builder.finish().data_type(), &data_type);
2890    }
2891
2892    #[test]
2893    fn test_into_builder_on_sliced_array() {
2894        let array: Int32Array = vec![1, 2, 3].into_iter().map(Some).collect();
2895        let slice = array.slice(1, 2);
2896        let col: Int32Array = downcast_array(&slice);
2897
2898        drop(slice);
2899
2900        col.into_builder()
2901            .expect_err("Should not build builder from sliced array");
2902    }
2903
2904    #[test]
2905    fn test_unary_mut() {
2906        let array: Int32Array = vec![1, 2, 3].into_iter().map(Some).collect();
2907
2908        let c = array.unary_mut(|x| x * 2 + 1).unwrap();
2909        let expected: Int32Array = vec![3, 5, 7].into_iter().map(Some).collect();
2910
2911        assert_eq!(expected, c);
2912
2913        let array: Int32Array = Int32Array::from(vec![Some(5), Some(7), None]);
2914        let c = array.unary_mut(|x| x * 2 + 1).unwrap();
2915        assert_eq!(c, Int32Array::from(vec![Some(11), Some(15), None]));
2916    }
2917
2918    #[test]
2919    #[should_panic(
2920        expected = "PrimitiveArray expected data type Interval(MonthDayNano) got Interval(DayTime)"
2921    )]
2922    fn test_invalid_interval_type() {
2923        let array = IntervalDayTimeArray::from(vec![IntervalDayTime::ZERO]);
2924        let _ = IntervalMonthDayNanoArray::from(array.into_data());
2925    }
2926
2927    #[test]
2928    fn test_timezone() {
2929        let array = TimestampNanosecondArray::from_iter_values([1, 2]);
2930        assert_eq!(array.timezone(), None);
2931
2932        let array = array.with_timezone("+02:00");
2933        assert_eq!(array.timezone(), Some("+02:00"));
2934    }
2935
2936    #[test]
2937    fn test_try_new() {
2938        Int32Array::new(vec![1, 2, 3, 4].into(), None);
2939        Int32Array::new(vec![1, 2, 3, 4].into(), Some(NullBuffer::new_null(4)));
2940
2941        let err = Int32Array::try_new(vec![1, 2, 3, 4].into(), Some(NullBuffer::new_null(3)))
2942            .unwrap_err();
2943
2944        assert_eq!(
2945            err.to_string(),
2946            "Invalid argument error: Incorrect length of null buffer for PrimitiveArray, expected 4 got 3"
2947        );
2948
2949        TimestampNanosecondArray::new(vec![1, 2, 3, 4].into(), None).with_data_type(
2950            DataType::Timestamp(TimeUnit::Nanosecond, Some("03:00".into())),
2951        );
2952    }
2953
2954    #[test]
2955    #[should_panic(expected = "PrimitiveArray expected data type Int32 got Date32")]
2956    fn test_with_data_type() {
2957        Int32Array::new(vec![1, 2, 3, 4].into(), None).with_data_type(DataType::Date32);
2958    }
2959
2960    #[test]
2961    fn test_time_32second_output() {
2962        let array: Time32SecondArray = vec![
2963            Some(-1),
2964            Some(0),
2965            Some(86_399),
2966            Some(86_400),
2967            Some(86_401),
2968            None,
2969        ]
2970        .into();
2971        let debug_str = format!("{array:?}");
2972        assert_eq!(
2973            "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]",
2974            debug_str
2975        );
2976    }
2977
2978    #[test]
2979    fn test_time_32millisecond_debug_output() {
2980        let array: Time32MillisecondArray = vec![
2981            Some(-1),
2982            Some(0),
2983            Some(86_399_000),
2984            Some(86_400_000),
2985            Some(86_401_000),
2986            None,
2987        ]
2988        .into();
2989        let debug_str = format!("{array:?}");
2990        assert_eq!(
2991            "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]",
2992            debug_str
2993        );
2994    }
2995
2996    #[test]
2997    fn test_time_64nanosecond_debug_output() {
2998        let array: Time64NanosecondArray = vec![
2999            Some(-1),
3000            Some(0),
3001            Some(86_399 * 1_000_000_000),
3002            Some(86_400 * 1_000_000_000),
3003            Some(86_401 * 1_000_000_000),
3004            None,
3005        ]
3006        .into();
3007        let debug_str = format!("{array:?}");
3008        assert_eq!(
3009            "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]",
3010            debug_str
3011        );
3012    }
3013
3014    #[test]
3015    fn test_time_64microsecond_debug_output() {
3016        let array: Time64MicrosecondArray = vec![
3017            Some(-1),
3018            Some(0),
3019            Some(86_399 * 1_000_000),
3020            Some(86_400 * 1_000_000),
3021            Some(86_401 * 1_000_000),
3022            None,
3023        ]
3024        .into();
3025        let debug_str = format!("{array:?}");
3026        assert_eq!(
3027            "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]",
3028            debug_str
3029        );
3030    }
3031
3032    #[test]
3033    fn test_primitive_with_nulls_into_builder() {
3034        let array: Int32Array = vec![
3035            Some(1),
3036            None,
3037            Some(3),
3038            Some(4),
3039            None,
3040            Some(7),
3041            None,
3042            Some(8),
3043        ]
3044        .into_iter()
3045        .collect();
3046        let _ = array.into_builder();
3047    }
3048}