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