Skip to main content

arrow_array/array/
primitive_array.rs

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