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