arrow_array/array/
primitive_array.rs

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