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