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