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