Skip to main content

arrow_array/array/
primitive_array.rs

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