Skip to main content

arrow_data/
data.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
18//! Contains [`ArrayData`], a generic representation of Arrow array data which encapsulates
19//! common attributes and operations for Arrow array.
20
21use crate::bit_iterator::BitSliceIterator;
22use arrow_buffer::buffer::{BooleanBuffer, NullBuffer};
23use arrow_buffer::{
24    ArrowNativeType, Buffer, IntervalDayTime, IntervalMonthDayNano, MutableBuffer, bit_util, i256,
25};
26use arrow_schema::{ArrowError, DataType, UnionMode};
27use std::mem;
28use std::ops::Range;
29use std::sync::Arc;
30
31use crate::{equal, validate_binary_view, validate_string_view};
32
33#[inline]
34pub(crate) fn contains_nulls(
35    null_bit_buffer: Option<&NullBuffer>,
36    offset: usize,
37    len: usize,
38) -> bool {
39    match null_bit_buffer {
40        Some(buffer) => {
41            match BitSliceIterator::new(buffer.validity(), buffer.offset() + offset, len).next() {
42                Some((start, end)) => start != 0 || end != len,
43                None => len != 0, // No non-null values
44            }
45        }
46        None => false, // No null buffer
47    }
48}
49
50#[inline]
51pub(crate) fn count_nulls(
52    null_bit_buffer: Option<&NullBuffer>,
53    offset: usize,
54    len: usize,
55) -> usize {
56    if let Some(buf) = null_bit_buffer {
57        let buffer = buf.buffer();
58        len - buffer.count_set_bits_offset(offset + buf.offset(), len)
59    } else {
60        0
61    }
62}
63
64/// creates 2 [`MutableBuffer`]s with a given `capacity` (in slots).
65#[inline]
66pub(crate) fn new_buffers(data_type: &DataType, capacity: usize) -> [MutableBuffer; 2] {
67    let empty_buffer = MutableBuffer::new(0);
68    match data_type {
69        DataType::Null => [empty_buffer, MutableBuffer::new(0)],
70        DataType::Boolean => {
71            let bytes = bit_util::ceil(capacity, 8);
72            let buffer = MutableBuffer::new(bytes);
73            [buffer, empty_buffer]
74        }
75        DataType::UInt8
76        | DataType::UInt16
77        | DataType::UInt32
78        | DataType::UInt64
79        | DataType::Int8
80        | DataType::Int16
81        | DataType::Int32
82        | DataType::Int64
83        | DataType::Float16
84        | DataType::Float32
85        | DataType::Float64
86        | DataType::Decimal32(_, _)
87        | DataType::Decimal64(_, _)
88        | DataType::Decimal128(_, _)
89        | DataType::Decimal256(_, _)
90        | DataType::Date32
91        | DataType::Time32(_)
92        | DataType::Date64
93        | DataType::Time64(_)
94        | DataType::Duration(_)
95        | DataType::Timestamp(_, _)
96        | DataType::Interval(_) => [
97            MutableBuffer::new(capacity * data_type.primitive_width().unwrap()),
98            empty_buffer,
99        ],
100        DataType::Utf8 | DataType::Binary => {
101            let mut buffer = MutableBuffer::new((1 + capacity) * mem::size_of::<i32>());
102            // safety: `unsafe` code assumes that this buffer is initialized with one element
103            buffer.push(0i32);
104            [buffer, MutableBuffer::new(capacity * mem::size_of::<u8>())]
105        }
106        DataType::LargeUtf8 | DataType::LargeBinary => {
107            let mut buffer = MutableBuffer::new((1 + capacity) * mem::size_of::<i64>());
108            // safety: `unsafe` code assumes that this buffer is initialized with one element
109            buffer.push(0i64);
110            [buffer, MutableBuffer::new(capacity * mem::size_of::<u8>())]
111        }
112        DataType::BinaryView | DataType::Utf8View => [
113            MutableBuffer::new(capacity * mem::size_of::<u128>()),
114            empty_buffer,
115        ],
116        DataType::List(_) | DataType::Map(_, _) => {
117            // offset buffer always starts with a zero
118            let mut buffer = MutableBuffer::new((1 + capacity) * mem::size_of::<i32>());
119            buffer.push(0i32);
120            [buffer, empty_buffer]
121        }
122        DataType::ListView(_) => [
123            MutableBuffer::new(capacity * mem::size_of::<i32>()),
124            MutableBuffer::new(capacity * mem::size_of::<i32>()),
125        ],
126        DataType::LargeList(_) => {
127            // offset buffer always starts with a zero
128            let mut buffer = MutableBuffer::new((1 + capacity) * mem::size_of::<i64>());
129            buffer.push(0i64);
130            [buffer, empty_buffer]
131        }
132        DataType::LargeListView(_) => [
133            MutableBuffer::new(capacity * mem::size_of::<i64>()),
134            MutableBuffer::new(capacity * mem::size_of::<i64>()),
135        ],
136        DataType::FixedSizeBinary(size) => {
137            if *size < 0 {
138                panic!("cannot construct buffers from FixedSizeBinary({size})");
139            }
140            [MutableBuffer::new(capacity * *size as usize), empty_buffer]
141        }
142        DataType::Dictionary(k, _) => [
143            MutableBuffer::new(capacity * k.primitive_width().unwrap()),
144            empty_buffer,
145        ],
146        DataType::FixedSizeList(_, _) | DataType::Struct(_) | DataType::RunEndEncoded(_, _) => {
147            [empty_buffer, MutableBuffer::new(0)]
148        }
149        DataType::Union(_, mode) => {
150            let type_ids = MutableBuffer::new(capacity * mem::size_of::<i8>());
151            match mode {
152                UnionMode::Sparse => [type_ids, empty_buffer],
153                UnionMode::Dense => {
154                    let offsets = MutableBuffer::new(capacity * mem::size_of::<i32>());
155                    [type_ids, offsets]
156                }
157            }
158        }
159    }
160}
161
162/// A generic representation of Arrow array data which encapsulates common attributes
163/// and operations for Arrow array.
164///
165/// Specific operations for different arrays types (e.g., primitive, list, struct)
166/// are implemented in `Array`.
167///
168/// # Memory Layout
169///
170/// `ArrayData` has references to one or more underlying data buffers
171/// and optional child ArrayData, depending on type as illustrated
172/// below. Bitmaps are not shown for simplicity but they are stored
173/// similarly to the buffers.
174///
175/// ```text
176///                        offset
177///                       points to
178/// ┌───────────────────┐ start of  ┌───────┐       Different
179/// │                   │   data    │       │     ArrayData may
180/// │ArrayData {        │           │....   │     also refers to
181/// │  data_type: ...   │   ─ ─ ─ ─▶│1234   │  ┌ ─  the same
182/// │  offset: ... ─ ─ ─│─ ┘        │4372   │      underlying
183/// │  len: ...    ─ ─ ─│─ ┐        │4888   │  │     buffer with different offset/len
184/// │  buffers: [       │           │5882   │◀─
185/// │    ...            │  │        │4323   │
186/// │  ]                │   ─ ─ ─ ─▶│4859   │
187/// │  child_data: [    │           │....   │
188/// │    ...            │           │       │
189/// │  ]                │           └───────┘
190/// │}                  │
191/// │                   │            Shared Buffer uses
192/// │               │   │            bytes::Bytes to hold
193/// └───────────────────┘            actual data values
194///           ┌ ─ ─ ┘
195///
196///           ▼
197/// ┌───────────────────┐
198/// │ArrayData {        │
199/// │  ...              │
200/// │}                  │
201/// │                   │
202/// └───────────────────┘
203///
204/// Child ArrayData may also have its own buffers and children
205/// ```
206
207#[derive(Debug, Clone)]
208pub struct ArrayData {
209    /// The data type
210    data_type: DataType,
211
212    /// The number of elements
213    len: usize,
214
215    /// The offset in number of items (not bytes).
216    ///
217    /// The offset applies to [`Self::child_data`] and [`Self::buffers`]. It
218    /// does NOT apply to [`Self::nulls`].
219    ///
220    /// See [`Self::offset()`] for details and diagrams.
221    offset: usize,
222
223    /// The buffers that store the actual data for this array, as defined
224    /// in the [Arrow Spec].
225    ///
226    /// Depending on the array types, [`Self::buffers`] can hold different
227    /// kinds of buffers (e.g., value buffer, value offset buffer) at different
228    /// positions.
229    ///
230    /// The buffer may be larger than needed.  Some items at the beginning may be skipped if
231    /// there is an `offset`.  Some items at the end may be skipped if the buffer is longer than
232    /// we need to satisfy `len`.
233    ///
234    /// [Arrow Spec](https://arrow.apache.org/docs/format/Columnar.html#physical-memory-layout)
235    buffers: Vec<Buffer>,
236
237    /// The child(ren) of this array.
238    ///
239    /// Only non-empty for nested types, such as `ListArray` and
240    /// `StructArray`.
241    ///
242    /// The first logical element in each child element begins at `offset`.
243    ///
244    /// If the child element also has an offset then these offsets are
245    /// cumulative.
246    ///
247    /// See [`Self::child_data()`] and [`Self::offset()`] for details.
248    child_data: Vec<ArrayData>,
249
250    /// The null bitmap.
251    ///
252    /// `None` indicates all values are non-null in this array.
253    ///
254    /// [`Self::offset()`] does not apply to the null bitmap. While the
255    /// BooleanBuffer may be sliced (have its own offset) internally, this
256    /// `NullBuffer` always represents exactly `len` elements.
257    nulls: Option<NullBuffer>,
258}
259
260/// A thread-safe, shared reference to the Arrow array data.
261pub type ArrayDataRef = Arc<ArrayData>;
262
263fn checked_len_plus_offset(
264    data_type: &DataType,
265    len: usize,
266    offset: usize,
267) -> Result<usize, ArrowError> {
268    len.checked_add(offset).ok_or_else(|| {
269        ArrowError::InvalidArgumentError(format!(
270            "Length {len} with offset {offset} overflows usize for {data_type}"
271        ))
272    })
273}
274
275/// Returns the first and last of `offsets`, and the bytes of `values` between
276/// them as a `str`. Returns `None` if the offsets are not valid indexes into
277/// `values` or those bytes are not valid UTF-8.
278fn utf8_span<'a, T: ArrowNativeType>(
279    offsets: &[T],
280    values: &'a [u8],
281) -> Option<(usize, usize, &'a str)> {
282    let first = offsets.first()?.to_usize()?;
283    let last = offsets.last()?.to_usize()?;
284    let values_str = std::str::from_utf8(values.get(first..last)?).ok()?;
285    Some((first, last, values_str))
286}
287
288impl ArrayData {
289    /// Create a new ArrayData instance;
290    ///
291    /// If `null_count` is not specified, the number of nulls in
292    /// null_bit_buffer is calculated.
293    ///
294    /// If the number of nulls is 0 then the null_bit_buffer
295    /// is set to `None`.
296    ///
297    /// # Safety
298    ///
299    /// The input values *must* form a valid Arrow array for
300    /// `data_type`, or undefined behavior can result.
301    ///
302    /// Note: This is a low level API and most users of the arrow
303    /// crate should create arrays using the methods in the `array`
304    /// module.
305    pub unsafe fn new_unchecked(
306        data_type: DataType,
307        len: usize,
308        null_count: Option<usize>,
309        null_bit_buffer: Option<Buffer>,
310        offset: usize,
311        buffers: Vec<Buffer>,
312        child_data: Vec<ArrayData>,
313    ) -> Self {
314        let builder = Self::inner_new_builder(
315            data_type,
316            len,
317            null_count,
318            null_bit_buffer,
319            offset,
320            buffers,
321            child_data,
322        );
323
324        // SAFETY: caller responsible for ensuring data is valid
325        unsafe { builder.build_unchecked() }
326    }
327
328    /// Create a new ArrayData, validating that the provided buffers form a valid
329    /// Arrow array of the specified data type.
330    ///
331    /// If the number of nulls in `null_bit_buffer` is 0 then the null_bit_buffer
332    /// is set to `None`.
333    ///
334    /// Internally this calls through to [`Self::validate_data`]
335    ///
336    /// Note: This is a low level API and most users of the arrow crate should create
337    /// arrays using the builders found in [arrow_array](https://docs.rs/arrow-array)
338    /// or [`ArrayDataBuilder`].
339    ///
340    /// See also [`Self::into_parts`] to recover the fields
341    pub fn try_new(
342        data_type: DataType,
343        len: usize,
344        null_bit_buffer: Option<Buffer>,
345        offset: usize,
346        buffers: Vec<Buffer>,
347        child_data: Vec<ArrayData>,
348    ) -> Result<Self, ArrowError> {
349        let builder = Self::inner_new_builder(
350            data_type,
351            len,
352            None,
353            null_bit_buffer,
354            offset,
355            buffers,
356            child_data,
357        );
358
359        assert!(!builder.skip_validation.get());
360
361        // As the data is not trusted, do a full validation of its contents
362        // We don't need to validate children as we can assume that the
363        // [`ArrayData`] in `child_data` have already been validated through
364        // a call to `ArrayData::try_new` or created using unsafe
365        builder.build()
366    }
367
368    fn inner_new_builder(
369        data_type: DataType,
370        len: usize,
371        null_count: Option<usize>,
372        null_bit_buffer: Option<Buffer>,
373        offset: usize,
374        buffers: Vec<Buffer>,
375        child_data: Vec<ArrayData>,
376    ) -> ArrayDataBuilder {
377        ArrayDataBuilder {
378            data_type,
379            len,
380            null_count,
381            null_bit_buffer,
382            nulls: None,
383            offset,
384            buffers,
385            child_data,
386            align_buffers: false,
387            skip_validation: UnsafeFlag::new(),
388        }
389    }
390
391    /// Return the constituent parts of this ArrayData
392    ///
393    /// This is the inverse of [`ArrayData::try_new`].
394    ///
395    /// Returns `(data_type, len, nulls, offset, buffers, child_data)`
396    pub fn into_parts(
397        self,
398    ) -> (
399        DataType,
400        usize,
401        Option<NullBuffer>,
402        usize,
403        Vec<Buffer>,
404        Vec<ArrayData>,
405    ) {
406        let Self {
407            data_type,
408            len,
409            nulls,
410            offset,
411            buffers,
412            child_data,
413        } = self;
414
415        (data_type, len, nulls, offset, buffers, child_data)
416    }
417
418    /// Returns a builder to construct a [`ArrayData`] instance of the same [`DataType`]
419    #[inline]
420    pub const fn builder(data_type: DataType) -> ArrayDataBuilder {
421        ArrayDataBuilder::new(data_type)
422    }
423
424    /// Returns a reference to the [`DataType`] of this [`ArrayData`]
425    #[inline]
426    pub const fn data_type(&self) -> &DataType {
427        &self.data_type
428    }
429
430    /// Returns the [`Buffer`] storing data for this [`ArrayData`]
431    pub fn buffers(&self) -> &[Buffer] {
432        &self.buffers
433    }
434
435    /// Returns a slice of children [`ArrayData`]. This will be non
436    /// empty for type such as lists and structs.
437    ///
438    /// Note: For nested types where the parent element `i` corresponds directly
439    /// to child element `i` (such as structs), both the parent's offset and
440    /// each child's own offset apply when locating child values — see
441    /// [`Self::offset`] for details.
442    pub fn child_data(&self) -> &[ArrayData] {
443        &self.child_data[..]
444    }
445
446    /// Returns whether the element at index `i` is null
447    #[inline]
448    pub fn is_null(&self, i: usize) -> bool {
449        match &self.nulls {
450            Some(v) => v.is_null(i),
451            None => false,
452        }
453    }
454
455    /// Returns a reference to the null buffer of this [`ArrayData`] if any
456    ///
457    /// Note: [`ArrayData::offset`] does NOT apply to the returned [`NullBuffer`]
458    #[inline]
459    pub fn nulls(&self) -> Option<&NullBuffer> {
460        self.nulls.as_ref()
461    }
462
463    /// Returns whether the element at index `i` is not null
464    #[inline]
465    pub fn is_valid(&self, i: usize) -> bool {
466        !self.is_null(i)
467    }
468
469    /// Returns the length (i.e., number of elements) of this [`ArrayData`].
470    #[inline]
471    pub const fn len(&self) -> usize {
472        self.len
473    }
474
475    /// Returns whether this [`ArrayData`] is empty
476    #[inline]
477    pub const fn is_empty(&self) -> bool {
478        self.len == 0
479    }
480
481    /// Returns the offset in elements of this [`ArrayData`]
482    ///
483    /// The offset applies to [`Self::buffers`] and [`Self::child_data`],
484    /// but does NOT apply to [`Self::nulls`], which always represents exactly
485    /// [`Self::len`] elements.
486    ///
487    /// # Offsets for Non-nested types
488    ///
489    /// For non-nested types, the offset skips leading elements in the buffers.
490    /// Logical element `i` is stored at physical position `offset + i`.
491    ///
492    /// For example, with `offset = 2` and `len = 3` the following array
493    /// represents elements `[C, D, E]`:
494    ///
495    /// ```text
496    ///                     offset: 2        len: 3
497    ///                   ◀───────────▶◀────────────────▶
498    ///                   ┌─────┬─────┬─────┬─────┬─────┬─────┐
499    ///    values buffer  │  A  │  B  │  C  │  D  │  E  │  F  │
500    ///                   └─────┴─────┴─────┴─────┴─────┴─────┘
501    ///    physical index    0     1     2     3     4     5
502    ///    logical index                 0     1     2
503    /// ```
504    ///
505    /// # Offsets for Struct types
506    ///
507    /// For [struct]s, logical element `i` of the parent corresponds directly to
508    /// element `i` of each child, with no indirection in between. Since a
509    /// struct has no buffers of its own, its offset applies to each child,
510    /// composing cumulatively with any child offset. Logical element `i` of the
511    /// struct corresponds to element `offset + i` of each child.
512    ///
513    /// For example, a struct with `offset = 2` and `len = 3` whose children
514    /// `c1` and `c2` themselves each have an offset of `1` represents the
515    /// elements `{c1: D, c2: d}`, `{c1: E, c2: e}`, `{c1: F, c2: f}`:
516    ///
517    /// ```text
518    ///                        struct offset: 2    len: 3
519    ///                          ◀───────────▶◀────────────────▶
520    ///    child offset: 1 ◀─────▶
521    ///                    ┌─────┬─────┬─────┬─────┬─────┬─────┬─────┐
522    ///    child c1        │  A  │  B  │  C  │  D  │  E  │  F  │  G  │
523    ///                    ├─────┼─────┼─────┼─────┼─────┼─────┼─────┤
524    ///    child c2        │  a  │  b  │  c  │  d  │  e  │  f  │  g  │
525    ///                    └─────┴─────┴─────┴─────┴─────┴─────┴─────┘
526    ///    physical index     0     1     2     3     4     5     6
527    ///    child index              0     1     2     3     4     5
528    ///    struct index                         0     1     2
529    /// ```
530    ///
531    /// [struct]: https://arrow.apache.org/docs/format/Columnar.html#struct-layout
532    #[inline]
533    pub const fn offset(&self) -> usize {
534        self.offset
535    }
536
537    /// Returns the total number of nulls in this array
538    #[inline]
539    pub fn null_count(&self) -> usize {
540        self.nulls
541            .as_ref()
542            .map(|x| x.null_count())
543            .unwrap_or_default()
544    }
545
546    /// Returns the total number of bytes of memory occupied by the
547    /// buffers owned by this [`ArrayData`] and all of its
548    /// children. (See also diagram on [`ArrayData`]).
549    ///
550    /// Note that this [`ArrayData`] may only refer to a subset of the
551    /// data in the underlying [`Buffer`]s (due to `offset` and
552    /// `length`), but the size returned includes the entire size of
553    /// the buffers.
554    ///
555    /// If multiple [`ArrayData`]s refer to the same underlying
556    /// [`Buffer`]s they will both report the same size.
557    pub fn get_buffer_memory_size(&self) -> usize {
558        let mut size = 0;
559        for buffer in &self.buffers {
560            size += buffer.capacity();
561        }
562        if let Some(bitmap) = &self.nulls {
563            size += bitmap.buffer().capacity()
564        }
565        for child in &self.child_data {
566            size += child.get_buffer_memory_size();
567        }
568        size
569    }
570
571    /// Returns the total number of the bytes of memory occupied by
572    /// the buffers by this slice of [`ArrayData`] (See also diagram on [`ArrayData`]).
573    ///
574    /// This is approximately the number of bytes if a new
575    /// [`ArrayData`] was formed by creating new [`Buffer`]s with
576    /// exactly the data needed. For variadic layouts, this includes the full
577    /// capacity of every variadic buffer retained by a zero-copy slice, without
578    /// inspecting which buffers or ranges are referenced by the slice.
579    ///
580    /// For example, a [`DataType::Int64`] with `100` elements,
581    /// [`Self::get_slice_memory_size`] would return `100 * 8 = 800`. If
582    /// the [`ArrayData`] was then [`Self::slice`]ed to refer to its
583    /// first `20` elements, then [`Self::get_slice_memory_size`] on the
584    /// sliced [`ArrayData`] would return `20 * 8 = 160`.
585    pub fn get_slice_memory_size(&self) -> Result<usize, ArrowError> {
586        let mut result: usize = 0;
587        let layout = layout(&self.data_type);
588
589        for spec in &layout.buffers {
590            match spec {
591                BufferSpec::FixedWidth { byte_width, .. } => {
592                    // Offset buffers contain len+1 elements: one boundary per element
593                    // plus a final boundary marking the end of the last element.
594                    let len = match self.data_type {
595                        DataType::Utf8
596                        | DataType::LargeUtf8
597                        | DataType::Binary
598                        | DataType::LargeBinary
599                        | DataType::List(_)
600                        | DataType::LargeList(_)
601                        | DataType::Map(_, _) => self.len + 1,
602                        _ => self.len,
603                    };
604                    let buffer_size = len.checked_mul(*byte_width).ok_or_else(|| {
605                        ArrowError::ComputeError(
606                            "Integer overflow computing buffer size".to_string(),
607                        )
608                    })?;
609                    result += buffer_size;
610                }
611                BufferSpec::VariableWidth => {
612                    let buffer_len = match self.data_type {
613                        DataType::Utf8 | DataType::Binary => {
614                            let offsets = self.typed_offsets::<i32>()?;
615                            (offsets[self.len] - offsets[0]) as usize
616                        }
617                        DataType::LargeUtf8 | DataType::LargeBinary => {
618                            let offsets = self.typed_offsets::<i64>()?;
619                            (offsets[self.len] - offsets[0]) as usize
620                        }
621                        _ => {
622                            return Err(ArrowError::NotYetImplemented(format!(
623                                "Invalid data type for VariableWidth buffer. Expected Utf8, LargeUtf8, Binary or LargeBinary. Got {}",
624                                self.data_type
625                            )));
626                        }
627                    };
628                    result += buffer_len;
629                }
630                BufferSpec::BitMap => {
631                    let buffer_size = bit_util::ceil(self.len, 8);
632                    result += buffer_size;
633                }
634                BufferSpec::AlwaysNull => {
635                    // Nothing to do
636                }
637            }
638        }
639
640        if layout.variadic {
641            // Slicing view arrays retains all variadic data buffers unchanged.
642            for buffer in self.buffers.iter().skip(layout.buffers.len()) {
643                result += buffer.capacity();
644            }
645        }
646
647        if self.nulls().is_some() {
648            result += bit_util::ceil(self.len, 8);
649        }
650
651        for child in &self.child_data {
652            result += child.get_slice_memory_size()?;
653        }
654        Ok(result)
655    }
656
657    /// Returns the total number of bytes of memory occupied
658    /// physically by this [`ArrayData`] and all its [`Buffer`]s and
659    /// children. (See also diagram on [`ArrayData`]).
660    ///
661    /// Equivalent to:
662    ///  `size_of_val(self)` +
663    ///  [`Self::get_buffer_memory_size`] +
664    ///  `size_of_val(child)` for all children
665    pub fn get_array_memory_size(&self) -> usize {
666        let mut size = mem::size_of_val(self);
667
668        // Calculate rest of the fields top down which contain actual data
669        for buffer in &self.buffers {
670            size += mem::size_of::<Buffer>();
671            size += buffer.capacity();
672        }
673        if let Some(nulls) = &self.nulls {
674            size += nulls.buffer().capacity();
675        }
676        for child in &self.child_data {
677            size += child.get_array_memory_size();
678        }
679
680        size
681    }
682
683    /// Creates a zero-copy slice of itself. This creates a new
684    /// [`ArrayData`] pointing at the same underlying [`Buffer`]s with a
685    /// different offset and len
686    ///
687    /// # Panics
688    ///
689    /// Panics if `offset + length` overflows or is greater than `self.len()`.
690    pub fn slice(&self, offset: usize, length: usize) -> ArrayData {
691        self.clone().sliced(offset, length)
692    }
693
694    /// Creates a zero-copy slice of this array, reusing its buffer and child allocations.
695    ///
696    /// This is equivalent to [`Self::slice`], but consumes `self`.
697    ///
698    /// # Panics
699    ///
700    /// Panics if `offset + length` overflows or is greater than `self.len()`.
701    pub fn sliced(mut self, offset: usize, length: usize) -> Self {
702        self.slice_in_place(offset, length);
703        self
704    }
705
706    fn slice_in_place(&mut self, offset: usize, length: usize) {
707        let end = offset
708            .checked_add(length)
709            .expect("offset + length overflow");
710        assert!(end <= self.len());
711
712        if let DataType::Struct(_) = self.data_type() {
713            // A struct has no buffers of its own, and reading child element `i`
714            // combines this array's offset with the child's own offset. Applying
715            // the slice to both would count it twice, so the cumulative offset
716            // goes to the children and this array's offset is reset to 0.
717            let child_offset = self.offset + offset;
718            for child in &mut self.child_data {
719                child.slice_in_place(child_offset, length);
720            }
721            self.offset = 0;
722        } else {
723            self.offset += offset;
724        }
725        self.len = length;
726        // `nulls` belongs to this array rather than to the children, so
727        // it is sliced by `offset` alone.
728        self.nulls = self.nulls.as_ref().map(|x| x.slice(offset, length));
729    }
730
731    /// Returns the `buffer` as a slice of type `T` starting at self.offset
732    ///
733    /// # Panics
734    /// This function panics if:
735    /// * the buffer is not byte-aligned with type T, or
736    /// * the datatype is `Boolean` (it corresponds to a bit-packed buffer where the offset is not applicable)
737    pub fn buffer<T: ArrowNativeType>(&self, buffer: usize) -> &[T] {
738        &self.buffers()[buffer].typed_data()[self.offset..]
739    }
740
741    /// Returns a new [`ArrayData`] valid for `data_type` containing `len` null values
742    ///
743    /// # Panics
744    /// This function panics if:
745    /// * the datatype `data_type` has incorrect layout
746    pub fn new_null(data_type: &DataType, len: usize) -> Self {
747        let bit_len = bit_util::ceil(len, 8);
748        let zeroed = |len: usize| Buffer::from(MutableBuffer::from_len_zeroed(len));
749
750        let (buffers, child_data, has_nulls) = match data_type.primitive_width() {
751            Some(width) => (vec![zeroed(width * len)], vec![], true),
752            None => match data_type {
753                DataType::Null => (vec![], vec![], false),
754                DataType::Boolean => (vec![zeroed(bit_len)], vec![], true),
755                DataType::Binary | DataType::Utf8 => {
756                    (vec![zeroed((len + 1) * 4), zeroed(0)], vec![], true)
757                }
758                DataType::BinaryView | DataType::Utf8View => (vec![zeroed(len * 16)], vec![], true),
759                DataType::LargeBinary | DataType::LargeUtf8 => {
760                    (vec![zeroed((len + 1) * 8), zeroed(0)], vec![], true)
761                }
762                DataType::FixedSizeBinary(i) => {
763                    if *i < 0 {
764                        panic!("cannot construct null data from FixedSizeBinary({i})");
765                    }
766                    (vec![zeroed(*i as usize * len)], vec![], true)
767                }
768                DataType::List(f) | DataType::Map(f, _) => (
769                    vec![zeroed((len + 1) * 4)],
770                    vec![ArrayData::new_empty(f.data_type())],
771                    true,
772                ),
773                DataType::LargeList(f) => (
774                    vec![zeroed((len + 1) * 8)],
775                    vec![ArrayData::new_empty(f.data_type())],
776                    true,
777                ),
778                DataType::ListView(f) => (
779                    vec![zeroed(len * 4), zeroed(len * 4)],
780                    vec![ArrayData::new_empty(f.data_type())],
781                    true,
782                ),
783                DataType::LargeListView(f) => (
784                    vec![zeroed(len * 8), zeroed(len * 8)],
785                    vec![ArrayData::new_empty(f.data_type())],
786                    true,
787                ),
788                DataType::FixedSizeList(f, list_len) => (
789                    vec![],
790                    vec![ArrayData::new_null(f.data_type(), *list_len as usize * len)],
791                    true,
792                ),
793                DataType::Struct(fields) => (
794                    vec![],
795                    fields
796                        .iter()
797                        .map(|f| Self::new_null(f.data_type(), len))
798                        .collect(),
799                    true,
800                ),
801                DataType::Dictionary(k, v) => (
802                    vec![zeroed(k.primitive_width().unwrap() * len)],
803                    vec![ArrayData::new_empty(v.as_ref())],
804                    true,
805                ),
806                DataType::Union(f, mode) => match f.iter().next() {
807                    // Every slot carries a type id naming one of the children,
808                    // so an empty union has nothing to put in a slot and can
809                    // only be the empty array.
810                    None => {
811                        assert_eq!(
812                            len, 0,
813                            "cannot construct null data from an empty union of length {len}, a slot has no type id to carry"
814                        );
815                        let buffers = match mode {
816                            UnionMode::Sparse => vec![zeroed(0)],
817                            UnionMode::Dense => vec![zeroed(0), zeroed(0)],
818                        };
819                        (buffers, vec![], false)
820                    }
821                    Some((id, _)) => {
822                        let ids = Buffer::from_iter(std::iter::repeat_n(id, len));
823                        let buffers = match mode {
824                            UnionMode::Sparse => vec![ids],
825                            UnionMode::Dense => {
826                                let end_offset = i32::from_usize(len).unwrap();
827                                vec![ids, Buffer::from_iter(0_i32..end_offset)]
828                            }
829                        };
830
831                        let children = f
832                            .iter()
833                            .enumerate()
834                            .map(|(idx, (_, f))| {
835                                if idx == 0 || *mode == UnionMode::Sparse {
836                                    Self::new_null(f.data_type(), len)
837                                } else {
838                                    Self::new_empty(f.data_type())
839                                }
840                            })
841                            .collect();
842
843                        (buffers, children, false)
844                    }
845                },
846                DataType::RunEndEncoded(r, v) => {
847                    if len == 0 {
848                        // For empty arrays, create zero-length child arrays.
849                        let runs = ArrayData::new_empty(r.data_type());
850                        let values = ArrayData::new_empty(v.data_type());
851                        (vec![], vec![runs, values], false)
852                    } else {
853                        let runs = match r.data_type() {
854                            DataType::Int16 => {
855                                let i = i16::from_usize(len).expect("run overflow");
856                                Buffer::from_slice_ref([i])
857                            }
858                            DataType::Int32 => {
859                                let i = i32::from_usize(len).expect("run overflow");
860                                Buffer::from_slice_ref([i])
861                            }
862                            DataType::Int64 => {
863                                let i = i64::from_usize(len).expect("run overflow");
864                                Buffer::from_slice_ref([i])
865                            }
866                            dt => unreachable!("Invalid run ends data type {dt}"),
867                        };
868
869                        let builder = ArrayData::builder(r.data_type().clone())
870                            .len(1)
871                            .buffers(vec![runs]);
872
873                        // SAFETY:
874                        // Valid by construction
875                        let runs = unsafe { builder.build_unchecked() };
876                        (
877                            vec![],
878                            vec![runs, ArrayData::new_null(v.data_type(), 1)],
879                            false,
880                        )
881                    }
882                }
883                // Handled by Some(width) branch above
884                DataType::Int8
885                | DataType::Int16
886                | DataType::Int32
887                | DataType::Int64
888                | DataType::UInt8
889                | DataType::UInt16
890                | DataType::UInt32
891                | DataType::UInt64
892                | DataType::Float16
893                | DataType::Float32
894                | DataType::Float64
895                | DataType::Timestamp(_, _)
896                | DataType::Date32
897                | DataType::Date64
898                | DataType::Time32(_)
899                | DataType::Time64(_)
900                | DataType::Duration(_)
901                | DataType::Interval(_)
902                | DataType::Decimal32(_, _)
903                | DataType::Decimal64(_, _)
904                | DataType::Decimal128(_, _)
905                | DataType::Decimal256(_, _) => unreachable!("{data_type}"),
906            },
907        };
908
909        let mut builder = ArrayDataBuilder::new(data_type.clone())
910            .len(len)
911            .buffers(buffers)
912            .child_data(child_data);
913
914        if has_nulls {
915            builder = builder.nulls(Some(NullBuffer::new_null(len)))
916        }
917
918        // SAFETY:
919        // Data valid by construction
920        unsafe { builder.build_unchecked() }
921    }
922
923    /// Returns a new empty [ArrayData] valid for `data_type`.
924    pub fn new_empty(data_type: &DataType) -> Self {
925        Self::new_null(data_type, 0)
926    }
927
928    /// Verifies that the buffers meet the minimum alignment requirements for the data type
929    ///
930    /// Buffers that are not adequately aligned will be copied to a new aligned allocation
931    ///
932    /// This can be useful for when interacting with data sent over IPC or FFI, that may
933    /// not meet the minimum alignment requirements
934    ///
935    /// This also aligns buffers of children data
936    pub fn align_buffers(&mut self) {
937        let layout = layout(&self.data_type);
938        for (buffer, spec) in self.buffers.iter_mut().zip(&layout.buffers) {
939            if let BufferSpec::FixedWidth { alignment, .. } = spec
940                && buffer.as_ptr().align_offset(*alignment) != 0
941            {
942                *buffer = Buffer::from_slice_ref(buffer.as_ref());
943            }
944        }
945        // align children data recursively
946        for data in &mut self.child_data {
947            data.align_buffers()
948        }
949    }
950
951    /// "cheap" validation of an `ArrayData`. Ensures buffers are
952    /// sufficiently sized to store `len` + `offset` total elements of
953    /// `data_type` and performs other inexpensive consistency checks.
954    ///
955    /// This check is "cheap" in the sense that it does not validate the
956    /// contents of the buffers (e.g. that all offsets for UTF8 arrays
957    /// are within the bounds of the values buffer).
958    ///
959    /// See [ArrayData::validate_data] to validate fully the offset content
960    /// and the validity of utf8 data
961    pub fn validate(&self) -> Result<(), ArrowError> {
962        // Need at least this much space in each buffer
963        let len_plus_offset = checked_len_plus_offset(&self.data_type, self.len, self.offset)?;
964
965        // Check that the data layout conforms to the spec
966        let layout = layout(&self.data_type);
967
968        if !layout.can_contain_null_mask && self.nulls.is_some() {
969            return Err(ArrowError::InvalidArgumentError(format!(
970                "Arrays of type {:?} cannot contain a null bitmask",
971                self.data_type,
972            )));
973        }
974
975        // Check data buffers length for view types and other types
976        if self.buffers.len() < layout.buffers.len()
977            || (!layout.variadic && self.buffers.len() != layout.buffers.len())
978        {
979            return Err(ArrowError::InvalidArgumentError(format!(
980                "Expected {} buffers in array of type {:?}, got {}",
981                layout.buffers.len(),
982                self.data_type,
983                self.buffers.len(),
984            )));
985        }
986
987        for (i, (buffer, spec)) in self.buffers.iter().zip(layout.buffers.iter()).enumerate() {
988            match spec {
989                BufferSpec::FixedWidth {
990                    byte_width,
991                    alignment,
992                } => {
993                    let min_buffer_size = len_plus_offset.saturating_mul(*byte_width);
994
995                    if buffer.len() < min_buffer_size {
996                        return Err(ArrowError::InvalidArgumentError(format!(
997                            "Need at least {} bytes in buffers[{}] in array of type {:?}, but got {}",
998                            min_buffer_size,
999                            i,
1000                            self.data_type,
1001                            buffer.len()
1002                        )));
1003                    }
1004
1005                    let align_offset = buffer.as_ptr().align_offset(*alignment);
1006                    if align_offset != 0 {
1007                        return Err(ArrowError::InvalidArgumentError(format!(
1008                            "Misaligned buffers[{i}] in array of type {:?}, offset from expected alignment of {alignment} by {}",
1009                            self.data_type,
1010                            align_offset.min(alignment - align_offset)
1011                        )));
1012                    }
1013                }
1014                BufferSpec::VariableWidth => {
1015                    // not cheap to validate (need to look at the
1016                    // data). Partially checked in validate_offsets
1017                    // called below. Can check with `validate_full`
1018                }
1019                BufferSpec::BitMap => {
1020                    let min_buffer_size = bit_util::ceil(len_plus_offset, 8);
1021                    if buffer.len() < min_buffer_size {
1022                        return Err(ArrowError::InvalidArgumentError(format!(
1023                            "Need at least {} bytes for bitmap in buffers[{}] in array of type {:?}, but got {}",
1024                            min_buffer_size,
1025                            i,
1026                            self.data_type,
1027                            buffer.len()
1028                        )));
1029                    }
1030                }
1031                BufferSpec::AlwaysNull => {
1032                    // Nothing to validate
1033                }
1034            }
1035        }
1036
1037        // check null bit buffer size
1038        if let Some(nulls) = self.nulls() {
1039            if nulls.null_count() > self.len {
1040                return Err(ArrowError::InvalidArgumentError(format!(
1041                    "null_count {} for an array exceeds length of {} elements",
1042                    nulls.null_count(),
1043                    self.len
1044                )));
1045            }
1046
1047            if nulls.len() != self.len {
1048                return Err(ArrowError::InvalidArgumentError(format!(
1049                    "null buffer incorrect size. got {} expected {}",
1050                    nulls.len(),
1051                    self.len
1052                )));
1053            }
1054        }
1055
1056        self.validate_child_data()?;
1057
1058        // Additional Type specific checks
1059        match &self.data_type {
1060            DataType::Utf8 | DataType::Binary => {
1061                self.validate_offsets::<i32>(self.buffers[1].len())?;
1062            }
1063            DataType::LargeUtf8 | DataType::LargeBinary => {
1064                self.validate_offsets::<i64>(self.buffers[1].len())?;
1065            }
1066            DataType::Dictionary(key_type, _value_type) => {
1067                // At the moment, constructing a DictionaryArray will also check this
1068                if !DataType::is_dictionary_key_type(key_type) {
1069                    return Err(ArrowError::InvalidArgumentError(format!(
1070                        "Dictionary key type must be integer, but was {key_type}"
1071                    )));
1072                }
1073            }
1074            DataType::RunEndEncoded(run_ends_type, _) => {
1075                if run_ends_type.is_nullable() {
1076                    return Err(ArrowError::InvalidArgumentError(
1077                        "The nullable should be set to false for the field defining run_ends array.".to_string()
1078                    ));
1079                }
1080                if !DataType::is_run_ends_type(run_ends_type.data_type()) {
1081                    return Err(ArrowError::InvalidArgumentError(format!(
1082                        "RunArray run_ends types must be Int16, Int32 or Int64, but was {}",
1083                        run_ends_type.data_type()
1084                    )));
1085                }
1086            }
1087            DataType::Map(f, _) if f.is_nullable() => {
1088                return Err(ArrowError::InvalidArgumentError(
1089                    "The nullable should be set to false for the map entries field.".to_string(),
1090                ));
1091            }
1092            _ => {}
1093        }
1094
1095        Ok(())
1096    }
1097
1098    /// Returns a reference to the data in `buffer` as a typed slice
1099    /// (typically `&[i32]` or `&[i64]`) after validating. The
1100    /// returned slice is guaranteed to have at least `self.len + 1`
1101    /// entries.
1102    ///
1103    /// For an empty array, the `buffer` can also be empty.
1104    fn typed_offsets<T: ArrowNativeType + num_traits::Num>(&self) -> Result<&[T], ArrowError> {
1105        // An empty list-like array can have 0 offsets
1106        if self.len == 0 && self.buffer_at(0)?.is_empty() {
1107            return Ok(&[]);
1108        }
1109
1110        let len = checked_len_plus_offset(&self.data_type, self.len, 1)?;
1111
1112        self.typed_buffer(0, len)
1113    }
1114
1115    /// Returns a reference to the data in `buffers[idx]` as a typed slice after validating
1116    fn typed_buffer<T: ArrowNativeType + num_traits::Num>(
1117        &self,
1118        idx: usize,
1119        len: usize,
1120    ) -> Result<&[T], ArrowError> {
1121        let buffer = self.buffer_at(idx)?;
1122
1123        let required_elements = checked_len_plus_offset(&self.data_type, len, self.offset)?;
1124        let byte_width = mem::size_of::<T>();
1125        let required_len = required_elements.checked_mul(byte_width).ok_or_else(|| {
1126            ArrowError::InvalidArgumentError(format!(
1127                "Buffer {idx} of {} byte length overflow: {} elements of {} bytes exceeds usize",
1128                self.data_type, required_elements, byte_width
1129            ))
1130        })?;
1131
1132        if buffer.len() < required_len {
1133            return Err(ArrowError::InvalidArgumentError(format!(
1134                "Buffer {} of {} isn't large enough. Expected {} bytes got {}",
1135                idx,
1136                self.data_type,
1137                required_len,
1138                buffer.len()
1139            )));
1140        }
1141
1142        Ok(&buffer.typed_data::<T>()[self.offset..required_elements])
1143    }
1144
1145    /// Does a cheap sanity check that the `self.len` values in `buffer` are valid
1146    /// offsets (of type T) into some other buffer of `values_length` bytes long
1147    fn validate_offsets<T: ArrowNativeType + num_traits::Num + std::fmt::Display>(
1148        &self,
1149        values_length: usize,
1150    ) -> Result<(), ArrowError> {
1151        // Justification: buffer size was validated above
1152        let offsets = self.typed_offsets::<T>()?;
1153        if offsets.is_empty() {
1154            return Ok(());
1155        }
1156
1157        let first_offset = offsets[0].to_usize().ok_or_else(|| {
1158            ArrowError::InvalidArgumentError(format!(
1159                "Error converting offset[0] ({}) to usize for {}",
1160                offsets[0], self.data_type
1161            ))
1162        })?;
1163
1164        let last_offset = offsets[self.len].to_usize().ok_or_else(|| {
1165            ArrowError::InvalidArgumentError(format!(
1166                "Error converting offset[{}] ({}) to usize for {}",
1167                self.len, offsets[self.len], self.data_type
1168            ))
1169        })?;
1170
1171        if first_offset > values_length {
1172            return Err(ArrowError::InvalidArgumentError(format!(
1173                "First offset {} of {} is larger than values length {}",
1174                first_offset, self.data_type, values_length,
1175            )));
1176        }
1177
1178        if last_offset > values_length {
1179            return Err(ArrowError::InvalidArgumentError(format!(
1180                "Last offset {} of {} is larger than values length {}",
1181                last_offset, self.data_type, values_length,
1182            )));
1183        }
1184
1185        if first_offset > last_offset {
1186            return Err(ArrowError::InvalidArgumentError(format!(
1187                "First offset {} in {} is smaller than last offset {}",
1188                first_offset, self.data_type, last_offset,
1189            )));
1190        }
1191
1192        Ok(())
1193    }
1194
1195    /// Does a cheap sanity check that the `self.len` values in `buffer` are valid
1196    /// offsets and sizes (of type T) into some other buffer of `values_length` bytes long
1197    fn validate_offsets_and_sizes<T: ArrowNativeType + num_traits::Num + std::fmt::Display>(
1198        &self,
1199        values_length: usize,
1200    ) -> Result<(), ArrowError> {
1201        let offsets: &[T] = self.typed_buffer(0, self.len)?;
1202        let sizes: &[T] = self.typed_buffer(1, self.len)?;
1203        if offsets.len() != sizes.len() {
1204            return Err(ArrowError::ComputeError(format!(
1205                "ListView offsets len {} does not match sizes len {}",
1206                offsets.len(),
1207                sizes.len()
1208            )));
1209        }
1210
1211        for i in 0..sizes.len() {
1212            let size = sizes[i].to_usize().ok_or_else(|| {
1213                ArrowError::InvalidArgumentError(format!(
1214                    "Error converting size[{}] ({}) to usize for {}",
1215                    i, sizes[i], self.data_type
1216                ))
1217            })?;
1218            let offset = offsets[i].to_usize().ok_or_else(|| {
1219                ArrowError::InvalidArgumentError(format!(
1220                    "Error converting offset[{}] ({}) to usize for {}",
1221                    i, offsets[i], self.data_type
1222                ))
1223            })?;
1224            if size
1225                .checked_add(offset)
1226                .expect("Offset and size have exceeded the usize boundary")
1227                > values_length
1228            {
1229                return Err(ArrowError::InvalidArgumentError(format!(
1230                    "Size {} at index {} is larger than the remaining values for {}",
1231                    size, i, self.data_type
1232                )));
1233            }
1234        }
1235        Ok(())
1236    }
1237
1238    /// Validates the layout of `child_data` ArrayData structures
1239    fn validate_child_data(&self) -> Result<(), ArrowError> {
1240        match &self.data_type {
1241            DataType::List(field) => {
1242                let values_data = self.get_single_valid_child_data(field.data_type())?;
1243                self.validate_offsets::<i32>(values_data.len)?;
1244            }
1245            DataType::LargeList(field) => {
1246                let values_data = self.get_single_valid_child_data(field.data_type())?;
1247                self.validate_offsets::<i64>(values_data.len)?;
1248            }
1249            DataType::Map(field, _) => {
1250                let DataType::Struct(entries_fields) = field.data_type() else {
1251                    return Err(ArrowError::InvalidArgumentError(format!(
1252                        "Map field should be a entries struct data type, got {:?} instead",
1253                        field.data_type()
1254                    )));
1255                };
1256                if entries_fields.len() != 2 {
1257                    return Err(ArrowError::InvalidArgumentError(format!(
1258                        "Map entries data type should be a struct containing 2 fields, got {} fields",
1259                        entries_fields.len()
1260                    )));
1261                }
1262
1263                // Key field
1264                if entries_fields[0].is_nullable() {
1265                    return Err(ArrowError::InvalidArgumentError(
1266                        "Map key field must not be nullable".to_string(),
1267                    ));
1268                }
1269                let values_data = self.get_single_valid_child_data(field.data_type())?;
1270                self.validate_offsets::<i32>(values_data.len)?;
1271            }
1272            DataType::ListView(field) => {
1273                let values_data = self.get_single_valid_child_data(field.data_type())?;
1274                self.validate_offsets_and_sizes::<i32>(values_data.len)?;
1275            }
1276            DataType::LargeListView(field) => {
1277                let values_data = self.get_single_valid_child_data(field.data_type())?;
1278                self.validate_offsets_and_sizes::<i64>(values_data.len)?;
1279            }
1280            DataType::FixedSizeList(field, list_size) => {
1281                let values_data = self.get_single_valid_child_data(field.data_type())?;
1282
1283                let list_size: usize = (*list_size).try_into().map_err(|_| {
1284                    ArrowError::InvalidArgumentError(format!(
1285                        "{} has a negative list_size {}",
1286                        self.data_type, list_size
1287                    ))
1288                })?;
1289
1290                let len_plus_offset =
1291                    checked_len_plus_offset(&self.data_type, self.len, self.offset)?;
1292                let expected_values_len = len_plus_offset
1293                    .checked_mul(list_size)
1294                    .expect("integer overflow computing expected number of expected values in FixedListSize");
1295
1296                if values_data.len < expected_values_len {
1297                    return Err(ArrowError::InvalidArgumentError(format!(
1298                        "Values length {} is less than the length + offset ({}) multiplied by the value size ({}) for {}",
1299                        values_data.len, len_plus_offset, list_size, self.data_type
1300                    )));
1301                }
1302            }
1303            DataType::Struct(fields) => {
1304                self.validate_num_child_data(fields.len())?;
1305                let len_plus_offset =
1306                    checked_len_plus_offset(&self.data_type, self.len, self.offset)?;
1307                for (i, field) in fields.iter().enumerate() {
1308                    let field_data = self.get_valid_child_data(i, field.data_type())?;
1309
1310                    // Ensure child field has sufficient size
1311                    if field_data.len < len_plus_offset {
1312                        return Err(ArrowError::InvalidArgumentError(format!(
1313                            "{} child array #{} for field {} has length smaller than expected for struct array ({} < {})",
1314                            self.data_type,
1315                            i,
1316                            field.name(),
1317                            field_data.len,
1318                            len_plus_offset
1319                        )));
1320                    }
1321                }
1322            }
1323            DataType::RunEndEncoded(run_ends_field, values_field) => {
1324                self.validate_num_child_data(2)?;
1325                let run_ends_data = self.get_valid_child_data(0, run_ends_field.data_type())?;
1326                let values_data = self.get_valid_child_data(1, values_field.data_type())?;
1327                if run_ends_data.len != values_data.len {
1328                    return Err(ArrowError::InvalidArgumentError(format!(
1329                        "The run_ends array length should be the same as values array length. Run_ends array length is {}, values array length is {}",
1330                        run_ends_data.len, values_data.len
1331                    )));
1332                }
1333                if run_ends_data.nulls.is_some() {
1334                    return Err(ArrowError::InvalidArgumentError(
1335                        "Found null values in run_ends array. The run_ends array should not have null values.".to_string(),
1336                    ));
1337                }
1338            }
1339            DataType::Union(fields, mode) => {
1340                self.validate_num_child_data(fields.len())?;
1341
1342                for (i, (_, field)) in fields.iter().enumerate() {
1343                    let field_data = self.get_valid_child_data(i, field.data_type())?;
1344
1345                    if mode == &UnionMode::Sparse {
1346                        let len_plus_offset =
1347                            checked_len_plus_offset(&self.data_type, self.len, self.offset)?;
1348                        if field_data.len < len_plus_offset {
1349                            return Err(ArrowError::InvalidArgumentError(format!(
1350                                "Sparse union child array #{} has length smaller than expected for union array ({} < {})",
1351                                i, field_data.len, len_plus_offset
1352                            )));
1353                        }
1354                    }
1355                }
1356            }
1357            DataType::Dictionary(_key_type, value_type) => {
1358                self.get_single_valid_child_data(value_type)?;
1359            }
1360            _ => {
1361                // other types do not have child data
1362                if !self.child_data.is_empty() {
1363                    return Err(ArrowError::InvalidArgumentError(format!(
1364                        "Expected no child arrays for type {} but got {}",
1365                        self.data_type,
1366                        self.child_data.len()
1367                    )));
1368                }
1369            }
1370        }
1371        Ok(())
1372    }
1373
1374    /// Ensures that this array data has a single child_data with the
1375    /// expected type, and calls `validate()` on it. Returns a
1376    /// reference to that child_data
1377    fn get_single_valid_child_data(
1378        &self,
1379        expected_type: &DataType,
1380    ) -> Result<&ArrayData, ArrowError> {
1381        self.validate_num_child_data(1)?;
1382        self.get_valid_child_data(0, expected_type)
1383    }
1384
1385    /// Returns `buffers[idx]`, or an error if there is no such buffer.
1386    ///
1387    /// [`Self::validate_values`] can be called on its own, without the buffer counts
1388    /// having been checked by [`Self::validate`] first, so the index may be missing.
1389    fn buffer_at(&self, idx: usize) -> Result<&Buffer, ArrowError> {
1390        self.buffers.get(idx).ok_or_else(|| {
1391            ArrowError::InvalidArgumentError(format!(
1392                "{} should contain at least {} buffer(s), had {}",
1393                self.data_type,
1394                idx + 1,
1395                self.buffers.len()
1396            ))
1397        })
1398    }
1399
1400    /// Returns `child_data[idx]`, or an error if there is no such child.
1401    ///
1402    /// [`Self::validate_values`] can be called on its own, without the child counts
1403    /// having been checked by [`Self::validate`] first, so the index may be missing.
1404    fn child_at(&self, idx: usize) -> Result<&ArrayData, ArrowError> {
1405        self.child_data.get(idx).ok_or_else(|| {
1406            ArrowError::InvalidArgumentError(format!(
1407                "{} should contain at least {} child data array(s), had {}",
1408                self.data_type,
1409                idx + 1,
1410                self.child_data.len()
1411            ))
1412        })
1413    }
1414
1415    /// Returns `Err` if self.child_data does not have exactly `expected_len` elements
1416    fn validate_num_child_data(&self, expected_len: usize) -> Result<(), ArrowError> {
1417        if self.child_data.len() != expected_len {
1418            Err(ArrowError::InvalidArgumentError(format!(
1419                "Value data for {} should contain {} child data array(s), had {}",
1420                self.data_type,
1421                expected_len,
1422                self.child_data.len()
1423            )))
1424        } else {
1425            Ok(())
1426        }
1427    }
1428
1429    /// Ensures that `child_data[i]` has the expected type, calls
1430    /// `validate()` on it, and returns a reference to that child_data
1431    fn get_valid_child_data(
1432        &self,
1433        i: usize,
1434        expected_type: &DataType,
1435    ) -> Result<&ArrayData, ArrowError> {
1436        let values_data = self.child_data.get(i).ok_or_else(|| {
1437            ArrowError::InvalidArgumentError(format!(
1438                "{} did not have enough child arrays. Expected at least {} but had only {}",
1439                self.data_type,
1440                i + 1,
1441                self.child_data.len()
1442            ))
1443        })?;
1444
1445        if expected_type != &values_data.data_type {
1446            return Err(ArrowError::InvalidArgumentError(format!(
1447                "Child type mismatch for {}. Expected {} but child data had {}",
1448                self.data_type, expected_type, values_data.data_type
1449            )));
1450        }
1451
1452        values_data.validate()?;
1453        Ok(values_data)
1454    }
1455
1456    /// Validate that the data contained within this [`ArrayData`] is valid
1457    ///
1458    /// 1. Null count is correct
1459    /// 2. All offsets are valid
1460    /// 3. All String data is valid UTF-8
1461    /// 4. All dictionary offsets are valid
1462    ///
1463    /// Internally this calls:
1464    ///
1465    /// * [`Self::validate`]
1466    /// * [`Self::validate_nulls`]
1467    /// * [`Self::validate_values`]
1468    ///
1469    /// Note: this does not recurse into children, for a recursive variant
1470    /// see [`Self::validate_full`]
1471    pub fn validate_data(&self) -> Result<(), ArrowError> {
1472        self.validate()?;
1473
1474        self.validate_nulls()?;
1475        self.validate_values()?;
1476        Ok(())
1477    }
1478
1479    /// Performs a full recursive validation of this [`ArrayData`] and all its children
1480    ///
1481    /// This is equivalent to calling [`Self::validate_data`] on this [`ArrayData`]
1482    /// and all its children recursively
1483    pub fn validate_full(&self) -> Result<(), ArrowError> {
1484        self.validate_data()?;
1485        // validate all children recursively
1486        self.child_data
1487            .iter()
1488            .enumerate()
1489            .try_for_each(|(i, child_data)| {
1490                child_data.validate_full().map_err(|e| {
1491                    ArrowError::InvalidArgumentError(format!(
1492                        "{} child #{} invalid: {}",
1493                        self.data_type, i, e
1494                    ))
1495                })
1496            })?;
1497        Ok(())
1498    }
1499
1500    /// Validates the values stored within this [`ArrayData`] are valid
1501    /// without recursing into child [`ArrayData`]
1502    ///
1503    /// Does not (yet) check
1504    /// 1. Union type_ids are valid see [#85](https://github.com/apache/arrow-rs/issues/85)
1505    /// 2. the null count is correct and that any
1506    /// 3. nullability requirements of its children are correct
1507    ///
1508    /// [#85]: https://github.com/apache/arrow-rs/issues/85
1509    pub fn validate_nulls(&self) -> Result<(), ArrowError> {
1510        if let Some(nulls) = &self.nulls {
1511            let actual = nulls.len() - nulls.inner().count_set_bits();
1512            if actual != nulls.null_count() {
1513                return Err(ArrowError::InvalidArgumentError(format!(
1514                    "null_count value ({}) doesn't match actual number of nulls in array ({})",
1515                    nulls.null_count(),
1516                    actual
1517                )));
1518            }
1519        }
1520
1521        // In general non-nullable children should not contain nulls, however, for certain
1522        // types, such as StructArray and FixedSizeList, nulls in the parent take up
1523        // space in the child. As such we permit nulls in the children in the corresponding
1524        // positions for such types
1525        match &self.data_type {
1526            DataType::List(f) | DataType::LargeList(f) | DataType::Map(f, _) => {
1527                if !f.is_nullable() {
1528                    let child = &self.child_data[0];
1529                    self.validate_non_nullable(None, child, child.nulls())?
1530                }
1531            }
1532            DataType::FixedSizeList(field, len) => {
1533                let child = &self.child_data[0];
1534                if !field.is_nullable() {
1535                    let element_len = *len as usize;
1536                    let child_nulls = child.nulls().map(|nulls| {
1537                        nulls.slice(self.offset * element_len, self.len * element_len)
1538                    });
1539                    let expanded = self.nulls.as_ref().map(|nulls| nulls.expand(element_len));
1540                    self.validate_non_nullable(expanded.as_ref(), child, child_nulls.as_ref())?;
1541                }
1542            }
1543            DataType::Struct(fields) => {
1544                for (field, child) in fields.iter().zip(&self.child_data) {
1545                    if !field.is_nullable() {
1546                        let child_nulls = child
1547                            .nulls()
1548                            .map(|nulls| nulls.slice(self.offset, self.len));
1549                        self.validate_non_nullable(self.nulls(), child, child_nulls.as_ref())?
1550                    }
1551                }
1552            }
1553            _ => {}
1554        }
1555
1556        Ok(())
1557    }
1558
1559    /// Verifies that `child` contains no nulls not present in `mask`
1560    fn validate_non_nullable(
1561        &self,
1562        mask: Option<&NullBuffer>,
1563        child: &ArrayData,
1564        child_nulls: Option<&NullBuffer>,
1565    ) -> Result<(), ArrowError> {
1566        let Some(mask) = mask else {
1567            return match child_nulls.map(NullBuffer::null_count).unwrap_or_default() {
1568                0 => Ok(()),
1569                _ => Err(ArrowError::InvalidArgumentError(format!(
1570                    "non-nullable child of type {} contains nulls not present in parent {}",
1571                    child.data_type, self.data_type
1572                ))),
1573            };
1574        };
1575
1576        match child_nulls {
1577            Some(nulls) if !mask.contains(nulls) => Err(ArrowError::InvalidArgumentError(format!(
1578                "non-nullable child of type {} contains nulls not present in parent",
1579                child.data_type
1580            ))),
1581            _ => Ok(()),
1582        }
1583    }
1584
1585    /// Validates the values stored within this [`ArrayData`] are valid
1586    /// without recursing into child [`ArrayData`]
1587    ///
1588    /// Does not (yet) check
1589    /// 1. Union type_ids are valid see [#85](https://github.com/apache/arrow-rs/issues/85)
1590    pub fn validate_values(&self) -> Result<(), ArrowError> {
1591        match &self.data_type {
1592            DataType::Utf8 => self.validate_utf8::<i32>(),
1593            DataType::LargeUtf8 => self.validate_utf8::<i64>(),
1594            DataType::Binary => self.validate_offsets_full::<i32>(self.buffer_at(1)?.len()),
1595            DataType::LargeBinary => self.validate_offsets_full::<i64>(self.buffer_at(1)?.len()),
1596            DataType::BinaryView => {
1597                let views = self.typed_buffer::<u128>(0, self.len)?;
1598                validate_binary_view(views, &self.buffers[1..])
1599            }
1600            DataType::Utf8View => {
1601                let views = self.typed_buffer::<u128>(0, self.len)?;
1602                validate_string_view(views, &self.buffers[1..])
1603            }
1604            DataType::List(_) | DataType::Map(_, _) => {
1605                let child = self.child_at(0)?;
1606                self.validate_offsets_full::<i32>(child.len)
1607            }
1608            DataType::LargeList(_) => {
1609                let child = self.child_at(0)?;
1610                self.validate_offsets_full::<i64>(child.len)
1611            }
1612            DataType::Union(fields, mode) => {
1613                let mut child_lens: Vec<Option<usize>> = vec![None; 128];
1614                for (index, (type_id, _)) in fields.iter().enumerate() {
1615                    let child = self.child_at(index)?;
1616                    child_lens[type_id as usize] = Some(child.len());
1617                }
1618
1619                // Type id values must match one of the fields.
1620                let type_ids = self.typed_buffer::<i8>(0, self.len)?;
1621                for (index, &type_id) in type_ids.iter().enumerate() {
1622                    if type_id < 0 {
1623                        return Err(ArrowError::InvalidArgumentError(format!(
1624                            "Type id values cannot be negative, got {type_id} at index {index}"
1625                        )));
1626                    }
1627                    let type_id = type_id as usize;
1628                    if child_lens[type_id].is_none() {
1629                        return Err(ArrowError::InvalidArgumentError(format!(
1630                            "Type id values must match one of the field type ids, got {type_id} at index {index}"
1631                        )));
1632                    }
1633                }
1634
1635                // Check the value offsets are in bounds.
1636                if mode == &UnionMode::Dense {
1637                    let offsets = self.typed_buffer::<i32>(1, self.len)?;
1638
1639                    if type_ids
1640                        .iter()
1641                        .zip(offsets.iter())
1642                        .any(|(&type_id, &offset)| {
1643                            offset < 0 || offset as usize >= child_lens[type_id as usize].unwrap()
1644                        })
1645                    {
1646                        return Err(ArrowError::InvalidArgumentError(
1647                            "Offsets must be non-negative and within the length of the child array"
1648                                .to_string(),
1649                        ));
1650                    }
1651                }
1652
1653                Ok(())
1654            }
1655            DataType::Dictionary(key_type, _value_type) => {
1656                let dictionary_length = self.child_at(0)?.len;
1657                let dictionary_length = i64::try_from(dictionary_length).map_err(|_| {
1658                    ArrowError::InvalidArgumentError(format!(
1659                        "Dictionary of {dictionary_length} values is too long for an i64"
1660                    ))
1661                })?;
1662                let max_value = dictionary_length - 1;
1663                match key_type.as_ref() {
1664                    DataType::UInt8 => self.check_bounds::<u8>(max_value),
1665                    DataType::UInt16 => self.check_bounds::<u16>(max_value),
1666                    DataType::UInt32 => self.check_bounds::<u32>(max_value),
1667                    DataType::UInt64 => self.check_bounds::<u64>(max_value),
1668                    DataType::Int8 => self.check_bounds::<i8>(max_value),
1669                    DataType::Int16 => self.check_bounds::<i16>(max_value),
1670                    DataType::Int32 => self.check_bounds::<i32>(max_value),
1671                    DataType::Int64 => self.check_bounds::<i64>(max_value),
1672                    _ => Err(ArrowError::InvalidArgumentError(format!(
1673                        "Dictionary key type must be an integer, got {key_type}"
1674                    ))),
1675                }
1676            }
1677            DataType::RunEndEncoded(run_ends, _values) => {
1678                let len_plus_offset =
1679                    checked_len_plus_offset(&self.data_type, self.len, self.offset)?;
1680                let run_ends_data = self.child_at(0)?;
1681                match run_ends.data_type() {
1682                    DataType::Int16 => {
1683                        run_ends_data.check_run_ends::<i16>(self.len, len_plus_offset)
1684                    }
1685                    DataType::Int32 => {
1686                        run_ends_data.check_run_ends::<i32>(self.len, len_plus_offset)
1687                    }
1688                    DataType::Int64 => {
1689                        run_ends_data.check_run_ends::<i64>(self.len, len_plus_offset)
1690                    }
1691                    data_type => Err(ArrowError::InvalidArgumentError(format!(
1692                        "Run end type must be Int16, Int32 or Int64, got {data_type}"
1693                    ))),
1694                }
1695            }
1696            _ => {
1697                // No extra validation check required for other types
1698                Ok(())
1699            }
1700        }
1701    }
1702
1703    /// Calls the `validate(item_index, range)` function for each of
1704    /// the ranges specified in the arrow offsets buffer of type
1705    /// `T`. Also validates that each offset is smaller than
1706    /// `offset_limit`
1707    ///
1708    /// For an empty array, the offsets buffer can either be empty
1709    /// or contain a single `0`.
1710    ///
1711    /// For example, the offsets buffer contained `[1, 2, 4]`, this
1712    /// function would call `validate([1,2])`, and `validate([2,4])`
1713    fn validate_each_offset<T, V>(&self, offset_limit: usize, validate: V) -> Result<(), ArrowError>
1714    where
1715        T: ArrowNativeType + TryInto<usize> + num_traits::Num + std::fmt::Display,
1716        V: Fn(usize, Range<usize>) -> Result<(), ArrowError>,
1717    {
1718        self.typed_offsets::<T>()?
1719            .iter()
1720            .enumerate()
1721            .map(|(i, x)| {
1722                // check if the offset can be converted to usize
1723                let r = x.to_usize().ok_or_else(|| {
1724                    ArrowError::InvalidArgumentError(format!(
1725                        "Offset invariant failure: Could not convert offset {x} to usize at position {i}"))}
1726                    );
1727                // check if the offset exceeds the limit
1728                match r {
1729                    Ok(n) if n <= offset_limit => Ok((i, n)),
1730                    Ok(_) => Err(ArrowError::InvalidArgumentError(format!(
1731                        "Offset invariant failure: offset at position {i} out of bounds: {x} > {offset_limit}"))
1732                    ),
1733                    Err(e) => Err(e),
1734                }
1735            })
1736            .scan(0_usize, |start, end| {
1737                // check offsets are monotonically increasing
1738                match end {
1739                    Ok((i, end)) if *start <= end => {
1740                        let range = Some(Ok((i, *start..end)));
1741                        *start = end;
1742                        range
1743                    }
1744                    Ok((i, end)) => Some(Err(ArrowError::InvalidArgumentError(format!(
1745                        "Offset invariant failure: non-monotonic offset at slot {}: {} > {}",
1746                        i - 1, start, end))
1747                    )),
1748                    Err(err) => Some(Err(err)),
1749                }
1750            })
1751            .skip(1) // the first element is meaningless
1752            .try_for_each(|res: Result<(usize, Range<usize>), ArrowError>| {
1753                let (item_index, range) = res?;
1754                validate(item_index-1, range)
1755            })
1756    }
1757
1758    /// Ensures that all strings formed by the offsets in `buffers[0]`
1759    /// into `buffers[1]` are valid utf8 sequences. Bytes of `buffers[1]`
1760    /// outside the range of the offsets are not checked.
1761    fn validate_utf8<T>(&self) -> Result<(), ArrowError>
1762    where
1763        T: ArrowNativeType + TryInto<usize> + num_traits::Num + std::fmt::Display,
1764    {
1765        let values_buffer = &self.buffer_at(1)?.as_slice();
1766        let offsets = self.typed_offsets::<T>()?;
1767        if let Some((first, last, values_str)) = utf8_span(offsets, values_buffer) {
1768            self.validate_each_offset::<T, _>(values_buffer.len(), |string_index, range| {
1769                // `values_str` ends at the last offset. Checking each pair of offsets doesn't
1770                // show that `range.end <= last`: a later offset can still be smaller, which
1771                // `validate_each_offset` reports when it gets there.
1772                if range.end > last {
1773                    return Ok(());
1774                }
1775                let (start, end) = (range.start - first, range.end - first);
1776                if !values_str.is_char_boundary(start) || !values_str.is_char_boundary(end) {
1777                    return Err(ArrowError::InvalidArgumentError(format!(
1778                        "incomplete utf-8 byte sequence from index {string_index}"
1779                    )));
1780                }
1781                Ok(())
1782            })
1783        } else {
1784            // Find specific offset that failed utf8 validation
1785            self.validate_each_offset::<T, _>(values_buffer.len(), |string_index, range| {
1786                std::str::from_utf8(&values_buffer[range.clone()]).map_err(|e| {
1787                    ArrowError::InvalidArgumentError(format!(
1788                        "Invalid UTF8 sequence at string index {string_index} ({range:?}): {e}"
1789                    ))
1790                })?;
1791                Ok(())
1792            })
1793        }
1794    }
1795
1796    /// Ensures that all offsets in `buffers[0]` into `buffers[1]` are
1797    /// between `0` and `offset_limit`
1798    fn validate_offsets_full<T>(&self, offset_limit: usize) -> Result<(), ArrowError>
1799    where
1800        T: ArrowNativeType + TryInto<usize> + num_traits::Num + std::fmt::Display,
1801    {
1802        self.validate_each_offset::<T, _>(offset_limit, |_string_index, _range| {
1803            // No validation applied to each value, but the iteration
1804            // itself applies bounds checking to each range
1805            Ok(())
1806        })
1807    }
1808
1809    /// Validates that each value in self.buffers (typed as T)
1810    /// is within the range [0, max_value], inclusive
1811    fn check_bounds<T>(&self, max_value: i64) -> Result<(), ArrowError>
1812    where
1813        T: ArrowNativeType + TryInto<i64> + num_traits::Num + std::fmt::Display,
1814    {
1815        // `validate()` checks the buffer size too, but `validate_values()` can be called
1816        // on its own, so do not assume it has run.
1817        let indexes: &[T] = self.typed_buffer::<T>(0, self.len)?;
1818
1819        indexes.iter().enumerate().try_for_each(|(i, &dict_index)| {
1820            // Do not check the value is null (value can be arbitrary)
1821            if self.is_null(i) {
1822                return Ok(());
1823            }
1824            let dict_index: i64 = dict_index.try_into().map_err(|_| {
1825                ArrowError::InvalidArgumentError(format!(
1826                    "Value at position {i} out of bounds: {dict_index} (can not convert to i64)"
1827                ))
1828            })?;
1829
1830            if dict_index < 0 || dict_index > max_value {
1831                return Err(ArrowError::InvalidArgumentError(format!(
1832                    "Value at position {i} out of bounds: {dict_index} (should be in [0, {max_value}])"
1833                )));
1834            }
1835            Ok(())
1836        })
1837    }
1838
1839    /// Validates that each value in run_ends array is positive and strictly increasing.
1840    fn check_run_ends<T>(
1841        &self,
1842        parent_len: usize,
1843        parent_len_plus_offset: usize,
1844    ) -> Result<(), ArrowError>
1845    where
1846        T: ArrowNativeType + TryInto<i64> + num_traits::Num + std::fmt::Display,
1847    {
1848        let values = self.typed_buffer::<T>(0, self.len)?;
1849        let mut prev_value = 0_i64;
1850        values.iter().enumerate().try_for_each(|(ix, &inp_value)| {
1851            let value: i64 = inp_value.try_into().map_err(|_| {
1852                ArrowError::InvalidArgumentError(format!(
1853                    "Value at position {ix} out of bounds: {inp_value} (can not convert to i64)"
1854                ))
1855            })?;
1856            if value <= 0_i64 {
1857                return Err(ArrowError::InvalidArgumentError(format!(
1858                    "The values in run_ends array should be strictly positive. Found value {value} at index {ix} that does not match the criteria."
1859                )));
1860            }
1861            if ix > 0 && value <= prev_value {
1862                return Err(ArrowError::InvalidArgumentError(format!(
1863                    "The values in run_ends array should be strictly increasing. Found value {value} at index {ix} with previous value {prev_value} that does not match the criteria."
1864                )));
1865            }
1866
1867            prev_value = value;
1868            Ok(())
1869        })?;
1870
1871        if parent_len > 0 && prev_value.as_usize() < parent_len_plus_offset {
1872            return Err(ArrowError::InvalidArgumentError(format!(
1873                "The offset + length of array should be less or equal to last value in the run_ends array. The last value of run_ends array is {prev_value} and offset + length of array is {parent_len_plus_offset}."
1874            )));
1875        }
1876        Ok(())
1877    }
1878
1879    /// Returns true if this `ArrayData` is equal to `other`, using pointer comparisons
1880    /// to determine buffer equality. This is cheaper than `PartialEq::eq` but may
1881    /// return false when the arrays are logically equal
1882    pub fn ptr_eq(&self, other: &Self) -> bool {
1883        if self.offset != other.offset
1884            || self.len != other.len
1885            || self.data_type != other.data_type
1886            || self.buffers.len() != other.buffers.len()
1887            || self.child_data.len() != other.child_data.len()
1888        {
1889            return false;
1890        }
1891
1892        match (&self.nulls, &other.nulls) {
1893            (Some(a), Some(b)) if !a.inner().ptr_eq(b.inner()) => return false,
1894            (Some(_), None) | (None, Some(_)) => return false,
1895            _ => {}
1896        }
1897
1898        if !self
1899            .buffers
1900            .iter()
1901            .zip(other.buffers.iter())
1902            .all(|(a, b)| a.as_ptr() == b.as_ptr())
1903        {
1904            return false;
1905        }
1906
1907        self.child_data
1908            .iter()
1909            .zip(other.child_data.iter())
1910            .all(|(a, b)| a.ptr_eq(b))
1911    }
1912
1913    /// Converts this [`ArrayData`] into an [`ArrayDataBuilder`]
1914    pub fn into_builder(self) -> ArrayDataBuilder {
1915        self.into()
1916    }
1917
1918    /// Claim memory used by this ArrayData in the provided memory pool.
1919    ///
1920    /// This claims memory for:
1921    /// - All buffers in self.buffers
1922    /// - All child ArrayData recursively
1923    /// - The null buffer if present
1924    #[cfg(feature = "pool")]
1925    pub fn claim(&self, pool: &dyn arrow_buffer::MemoryPool) {
1926        // Claim all data buffers
1927        for buffer in &self.buffers {
1928            buffer.claim(pool);
1929        }
1930
1931        // Claim null buffer if present
1932        if let Some(nulls) = &self.nulls {
1933            nulls.claim(pool);
1934        }
1935
1936        // Recursively claim child data
1937        for child in &self.child_data {
1938            child.claim(pool);
1939        }
1940    }
1941}
1942
1943/// Return the expected [`DataTypeLayout`] Arrays of this data
1944/// type are expected to have
1945pub fn layout(data_type: &DataType) -> DataTypeLayout {
1946    // based on C/C++ implementation in
1947    // https://github.com/apache/arrow/blob/661c7d749150905a63dd3b52e0a04dac39030d95/cpp/src/arrow/type.h (and .cc)
1948    use arrow_schema::IntervalUnit::*;
1949
1950    match data_type {
1951        DataType::Null => DataTypeLayout {
1952            buffers: vec![],
1953            can_contain_null_mask: false,
1954            variadic: false,
1955        },
1956        DataType::Boolean => DataTypeLayout {
1957            buffers: vec![BufferSpec::BitMap],
1958            can_contain_null_mask: true,
1959            variadic: false,
1960        },
1961        DataType::Int8 => DataTypeLayout::new_fixed_width::<i8>(),
1962        DataType::Int16 => DataTypeLayout::new_fixed_width::<i16>(),
1963        DataType::Int32 => DataTypeLayout::new_fixed_width::<i32>(),
1964        DataType::Int64 => DataTypeLayout::new_fixed_width::<i64>(),
1965        DataType::UInt8 => DataTypeLayout::new_fixed_width::<u8>(),
1966        DataType::UInt16 => DataTypeLayout::new_fixed_width::<u16>(),
1967        DataType::UInt32 => DataTypeLayout::new_fixed_width::<u32>(),
1968        DataType::UInt64 => DataTypeLayout::new_fixed_width::<u64>(),
1969        DataType::Float16 => DataTypeLayout::new_fixed_width::<half::f16>(),
1970        DataType::Float32 => DataTypeLayout::new_fixed_width::<f32>(),
1971        DataType::Float64 => DataTypeLayout::new_fixed_width::<f64>(),
1972        DataType::Timestamp(_, _) => DataTypeLayout::new_fixed_width::<i64>(),
1973        DataType::Date32 => DataTypeLayout::new_fixed_width::<i32>(),
1974        DataType::Date64 => DataTypeLayout::new_fixed_width::<i64>(),
1975        DataType::Time32(_) => DataTypeLayout::new_fixed_width::<i32>(),
1976        DataType::Time64(_) => DataTypeLayout::new_fixed_width::<i64>(),
1977        DataType::Interval(YearMonth) => DataTypeLayout::new_fixed_width::<i32>(),
1978        DataType::Interval(DayTime) => DataTypeLayout::new_fixed_width::<IntervalDayTime>(),
1979        DataType::Interval(MonthDayNano) => {
1980            DataTypeLayout::new_fixed_width::<IntervalMonthDayNano>()
1981        }
1982        DataType::Duration(_) => DataTypeLayout::new_fixed_width::<i64>(),
1983        DataType::Decimal32(_, _) => DataTypeLayout::new_fixed_width::<i32>(),
1984        DataType::Decimal64(_, _) => DataTypeLayout::new_fixed_width::<i64>(),
1985        DataType::Decimal128(_, _) => DataTypeLayout::new_fixed_width::<i128>(),
1986        DataType::Decimal256(_, _) => DataTypeLayout::new_fixed_width::<i256>(),
1987        DataType::FixedSizeBinary(size) => {
1988            let spec = BufferSpec::FixedWidth {
1989                byte_width: (*size).try_into().unwrap(),
1990                alignment: mem::align_of::<u8>(),
1991            };
1992            DataTypeLayout {
1993                buffers: vec![spec],
1994                can_contain_null_mask: true,
1995                variadic: false,
1996            }
1997        }
1998        DataType::Binary => DataTypeLayout::new_binary::<i32>(),
1999        DataType::LargeBinary => DataTypeLayout::new_binary::<i64>(),
2000        DataType::Utf8 => DataTypeLayout::new_binary::<i32>(),
2001        DataType::LargeUtf8 => DataTypeLayout::new_binary::<i64>(),
2002        DataType::BinaryView | DataType::Utf8View => DataTypeLayout::new_view(),
2003        DataType::FixedSizeList(_, _) => DataTypeLayout::new_nullable_empty(), // all in child data
2004        DataType::List(_) => DataTypeLayout::new_fixed_width::<i32>(),
2005        DataType::ListView(_) => DataTypeLayout::new_list_view::<i32>(),
2006        DataType::LargeListView(_) => DataTypeLayout::new_list_view::<i64>(),
2007        DataType::LargeList(_) => DataTypeLayout::new_fixed_width::<i64>(),
2008        DataType::Map(_, _) => DataTypeLayout::new_fixed_width::<i32>(),
2009        DataType::Struct(_) => DataTypeLayout::new_nullable_empty(), // all in child data,
2010        DataType::RunEndEncoded(_, _) => DataTypeLayout::new_empty(), // all in child data,
2011        DataType::Union(_, mode) => {
2012            let type_ids = BufferSpec::FixedWidth {
2013                byte_width: mem::size_of::<i8>(),
2014                alignment: mem::align_of::<i8>(),
2015            };
2016
2017            DataTypeLayout {
2018                buffers: match mode {
2019                    UnionMode::Sparse => {
2020                        vec![type_ids]
2021                    }
2022                    UnionMode::Dense => {
2023                        vec![
2024                            type_ids,
2025                            BufferSpec::FixedWidth {
2026                                byte_width: mem::size_of::<i32>(),
2027                                alignment: mem::align_of::<i32>(),
2028                            },
2029                        ]
2030                    }
2031                },
2032                can_contain_null_mask: false,
2033                variadic: false,
2034            }
2035        }
2036        DataType::Dictionary(key_type, _value_type) => layout(key_type),
2037    }
2038}
2039
2040/// Layout specification for a data type
2041#[derive(Debug, PartialEq, Eq)]
2042// Note: Follows structure from C++: https://github.com/apache/arrow/blob/master/cpp/src/arrow/type.h#L91
2043pub struct DataTypeLayout {
2044    /// A vector of buffer layout specifications, one for each expected buffer
2045    pub buffers: Vec<BufferSpec>,
2046
2047    /// Can contain a null bitmask
2048    pub can_contain_null_mask: bool,
2049
2050    /// This field only applies to the view type [`DataType::BinaryView`] and [`DataType::Utf8View`]
2051    /// If `variadic` is true, the number of buffers expected is only lower-bounded by
2052    /// buffers.len(). Buffers that exceed the lower bound are legal.
2053    pub variadic: bool,
2054}
2055
2056impl DataTypeLayout {
2057    /// Describes a basic numeric array where each element has type `T`
2058    pub fn new_fixed_width<T>() -> Self {
2059        Self {
2060            buffers: vec![BufferSpec::FixedWidth {
2061                byte_width: mem::size_of::<T>(),
2062                alignment: mem::align_of::<T>(),
2063            }],
2064            can_contain_null_mask: true,
2065            variadic: false,
2066        }
2067    }
2068
2069    /// Describes arrays which have no data of their own
2070    /// but may still have a Null Bitmap (e.g. FixedSizeList)
2071    pub fn new_nullable_empty() -> Self {
2072        Self {
2073            buffers: vec![],
2074            can_contain_null_mask: true,
2075            variadic: false,
2076        }
2077    }
2078
2079    /// Describes arrays which have no data of their own
2080    /// (e.g. RunEndEncoded).
2081    pub fn new_empty() -> Self {
2082        Self {
2083            buffers: vec![],
2084            can_contain_null_mask: false,
2085            variadic: false,
2086        }
2087    }
2088
2089    /// Describes a basic numeric array where each element has a fixed
2090    /// with offset buffer of type `T`, followed by a
2091    /// variable width data buffer
2092    pub fn new_binary<T>() -> Self {
2093        Self {
2094            buffers: vec![
2095                // offsets
2096                BufferSpec::FixedWidth {
2097                    byte_width: mem::size_of::<T>(),
2098                    alignment: mem::align_of::<T>(),
2099                },
2100                // values
2101                BufferSpec::VariableWidth,
2102            ],
2103            can_contain_null_mask: true,
2104            variadic: false,
2105        }
2106    }
2107
2108    /// Describes a view type
2109    pub fn new_view() -> Self {
2110        Self {
2111            buffers: vec![BufferSpec::FixedWidth {
2112                byte_width: mem::size_of::<u128>(),
2113                alignment: mem::align_of::<u128>(),
2114            }],
2115            can_contain_null_mask: true,
2116            variadic: true,
2117        }
2118    }
2119
2120    /// Describes a list view type
2121    pub fn new_list_view<T>() -> Self {
2122        Self {
2123            buffers: vec![
2124                BufferSpec::FixedWidth {
2125                    byte_width: mem::size_of::<T>(),
2126                    alignment: mem::align_of::<T>(),
2127                },
2128                BufferSpec::FixedWidth {
2129                    byte_width: mem::size_of::<T>(),
2130                    alignment: mem::align_of::<T>(),
2131                },
2132            ],
2133            can_contain_null_mask: true,
2134            variadic: false,
2135        }
2136    }
2137}
2138
2139/// Layout specification for a single data type buffer
2140#[derive(Debug, PartialEq, Eq)]
2141pub enum BufferSpec {
2142    /// Each element is a fixed width primitive, with the given `byte_width` and `alignment`
2143    ///
2144    /// `alignment` is the alignment required by Rust for an array of the corresponding primitive,
2145    /// see [`Layout::array`](std::alloc::Layout::array) and [`std::mem::align_of`].
2146    ///
2147    /// Arrow-rs requires that all buffers have at least this alignment, to allow for
2148    /// [slice](std::slice) based APIs. Alignment in excess of this is not required to allow
2149    /// for array slicing and interoperability with `Vec`, which cannot be over-aligned.
2150    ///
2151    /// Note that these alignment requirements will vary between architectures
2152    FixedWidth {
2153        /// The width of each element in bytes
2154        byte_width: usize,
2155        /// The alignment required by Rust for an array of the corresponding primitive
2156        alignment: usize,
2157    },
2158    /// Variable width, such as string data for utf8 data
2159    VariableWidth,
2160    /// Buffer holds a bitmap.
2161    ///
2162    /// Note: Unlike the C++ implementation, the null/validity buffer
2163    /// is handled specially rather than as another of the buffers in
2164    /// the spec, so this variant is only used for the Boolean type.
2165    BitMap,
2166    /// Buffer is always null. Unused currently in Rust implementation,
2167    /// (used in C++ for Union type)
2168    AlwaysNull,
2169}
2170
2171impl PartialEq for ArrayData {
2172    fn eq(&self, other: &Self) -> bool {
2173        equal::equal(self, other)
2174    }
2175}
2176
2177/// A boolean flag that cannot be mutated outside of unsafe code.
2178///
2179/// Defaults to a value of false.
2180///
2181/// This structure is used to enforce safety in the [`ArrayDataBuilder`]
2182///
2183/// [`ArrayDataBuilder`]: super::ArrayDataBuilder
2184///
2185/// # Example
2186/// ```rust
2187/// use arrow_data::UnsafeFlag;
2188/// assert!(!UnsafeFlag::default().get()); // default is false
2189/// let mut flag = UnsafeFlag::new();
2190/// assert!(!flag.get()); // defaults to false
2191/// // can only set it to true in unsafe code
2192/// unsafe { flag.set(true) };
2193/// assert!(flag.get()); // now true
2194/// ```
2195#[derive(Debug, Clone)]
2196#[doc(hidden)]
2197pub struct UnsafeFlag(bool);
2198
2199impl UnsafeFlag {
2200    /// Creates a new `UnsafeFlag` with the value set to `false`.
2201    ///
2202    /// See examples on [`Self::new`]
2203    #[inline]
2204    pub const fn new() -> Self {
2205        Self(false)
2206    }
2207
2208    /// Sets the value of the flag to the given value
2209    ///
2210    /// Note this can purposely only be done in `unsafe` code
2211    ///
2212    /// # Safety
2213    ///
2214    /// If set, the flag will be set to the given value. There is nothing
2215    /// immediately unsafe about doing so, however, the flag can be used to
2216    /// subsequently bypass safety checks in the [`ArrayDataBuilder`].
2217    #[inline]
2218    pub unsafe fn set(&mut self, val: bool) {
2219        self.0 = val;
2220    }
2221
2222    /// Returns the value of the flag
2223    #[inline]
2224    pub fn get(&self) -> bool {
2225        self.0
2226    }
2227}
2228
2229// Manual impl to make it clear you can not construct unsafe with true
2230impl Default for UnsafeFlag {
2231    fn default() -> Self {
2232        Self::new()
2233    }
2234}
2235
2236/// Builder for [`ArrayData`] type
2237#[derive(Debug)]
2238pub struct ArrayDataBuilder {
2239    data_type: DataType,
2240    len: usize,
2241    null_count: Option<usize>,
2242    null_bit_buffer: Option<Buffer>,
2243    nulls: Option<NullBuffer>,
2244    offset: usize,
2245    buffers: Vec<Buffer>,
2246    child_data: Vec<ArrayData>,
2247    /// Should buffers be realigned (copying if necessary)?
2248    ///
2249    /// Defaults to false.
2250    align_buffers: bool,
2251    /// Should data validation be skipped for this [`ArrayData`]?
2252    ///
2253    /// Defaults to false.
2254    ///
2255    /// # Safety
2256    ///
2257    /// This flag can only be set to true using `unsafe` APIs. However, once true
2258    /// subsequent calls to `build()` may result in undefined behavior if the data
2259    /// is not valid.
2260    skip_validation: UnsafeFlag,
2261}
2262
2263impl ArrayDataBuilder {
2264    #[inline]
2265    /// Creates a new array data builder
2266    pub const fn new(data_type: DataType) -> Self {
2267        Self {
2268            data_type,
2269            len: 0,
2270            null_count: None,
2271            null_bit_buffer: None,
2272            nulls: None,
2273            offset: 0,
2274            buffers: vec![],
2275            child_data: vec![],
2276            align_buffers: false,
2277            skip_validation: UnsafeFlag::new(),
2278        }
2279    }
2280
2281    /// Creates a new array data builder from an existing one, changing the data type
2282    pub fn data_type(self, data_type: DataType) -> Self {
2283        Self { data_type, ..self }
2284    }
2285
2286    #[inline]
2287    /// Sets the length of the [ArrayData]
2288    pub const fn len(mut self, n: usize) -> Self {
2289        self.len = n;
2290        self
2291    }
2292
2293    /// Sets the null buffer of the [ArrayData]
2294    pub fn nulls(mut self, nulls: Option<NullBuffer>) -> Self {
2295        self.nulls = nulls;
2296        self.null_count = None;
2297        self.null_bit_buffer = None;
2298        self
2299    }
2300
2301    /// Sets the null count of the [ArrayData]
2302    pub fn null_count(mut self, null_count: usize) -> Self {
2303        self.null_count = Some(null_count);
2304        self
2305    }
2306
2307    /// Sets the `null_bit_buffer` of the [ArrayData]
2308    pub fn null_bit_buffer(mut self, buf: Option<Buffer>) -> Self {
2309        self.nulls = None;
2310        self.null_bit_buffer = buf;
2311        self
2312    }
2313
2314    /// Sets the offset of the [ArrayData]
2315    #[inline]
2316    pub const fn offset(mut self, n: usize) -> Self {
2317        self.offset = n;
2318        self
2319    }
2320
2321    /// Sets the buffers of the [ArrayData]
2322    pub fn buffers(mut self, v: Vec<Buffer>) -> Self {
2323        self.buffers = v;
2324        self
2325    }
2326
2327    /// Adds a single buffer to the [ArrayData]'s buffers
2328    pub fn add_buffer(mut self, b: Buffer) -> Self {
2329        self.buffers.push(b);
2330        self
2331    }
2332
2333    /// Adds multiple buffers to the [ArrayData]'s buffers
2334    pub fn add_buffers<I: IntoIterator<Item = Buffer>>(mut self, bs: I) -> Self {
2335        self.buffers.extend(bs);
2336        self
2337    }
2338
2339    /// Sets the child data of the [ArrayData]
2340    pub fn child_data(mut self, v: Vec<ArrayData>) -> Self {
2341        self.child_data = v;
2342        self
2343    }
2344
2345    /// Adds a single child data to the [ArrayData]'s child data
2346    pub fn add_child_data(mut self, r: ArrayData) -> Self {
2347        self.child_data.push(r);
2348        self
2349    }
2350
2351    /// Creates an array data, without any validation
2352    ///
2353    /// Note: This is shorthand for
2354    /// ```rust
2355    /// # #[expect(unsafe_op_in_unsafe_fn)]
2356    /// # let mut builder = arrow_data::ArrayDataBuilder::new(arrow_schema::DataType::Null);
2357    /// # let _ = unsafe {
2358    /// builder.skip_validation(true).build().unwrap()
2359    /// # };
2360    /// ```
2361    ///
2362    /// # Safety
2363    ///
2364    /// The same caveats as [`ArrayData::new_unchecked`]
2365    /// apply.
2366    pub unsafe fn build_unchecked(self) -> ArrayData {
2367        unsafe { self.skip_validation(true) }.build().unwrap()
2368    }
2369
2370    /// Creates an `ArrayData`, consuming `self`
2371    ///
2372    /// # Undefined behavior
2373    ///
2374    /// By default the underlying buffers are checked to ensure they are valid
2375    /// Arrow data. However, if the [`Self::skip_validation`] flag has been set
2376    /// to true (by the `unsafe` API) this validation is skipped. If the data is
2377    /// not valid, undefined behavior will result.
2378    pub fn build(self) -> Result<ArrayData, ArrowError> {
2379        let Self {
2380            data_type,
2381            len,
2382            null_count,
2383            null_bit_buffer,
2384            nulls,
2385            offset,
2386            buffers,
2387            child_data,
2388            align_buffers,
2389            skip_validation,
2390        } = self;
2391
2392        // SAFETY: `skip_validation` is only set to true using `unsafe` APIs.
2393        let validate = !skip_validation.get() || cfg!(feature = "force_validate");
2394        if validate && let Some(buffer) = null_bit_buffer.as_ref() {
2395            // Check before constructing the BooleanBuffer, which would otherwise panic.
2396            let len_plus_offset = checked_len_plus_offset(&data_type, len, offset)?;
2397            let needed_len = bit_util::ceil(len_plus_offset, 8);
2398            if buffer.len() < needed_len {
2399                return Err(ArrowError::InvalidArgumentError(format!(
2400                    "null_bit_buffer size too small. got {} needed {}",
2401                    buffer.len(),
2402                    needed_len
2403                )));
2404            }
2405        }
2406
2407        let nulls = nulls
2408            .or_else(|| {
2409                let buffer = null_bit_buffer?;
2410                let buffer = BooleanBuffer::new(buffer, offset, len);
2411                Some(match null_count {
2412                    Some(n) => {
2413                        // SAFETY: call to `data.validate_data()` below validates the null buffer is valid
2414                        unsafe { NullBuffer::new_unchecked(buffer, n) }
2415                    }
2416                    None => NullBuffer::new(buffer),
2417                })
2418            })
2419            .filter(|b| b.null_count() != 0);
2420
2421        let mut data = ArrayData {
2422            data_type,
2423            len,
2424            offset,
2425            buffers,
2426            child_data,
2427            nulls,
2428        };
2429
2430        if align_buffers {
2431            data.align_buffers();
2432        }
2433
2434        if validate {
2435            data.validate_data()?;
2436        }
2437        Ok(data)
2438    }
2439
2440    /// Ensure that all buffers are aligned, copying data if necessary
2441    ///
2442    /// Rust requires that arrays are aligned to their corresponding primitive,
2443    /// see [`Layout::array`](std::alloc::Layout::array) and [`std::mem::align_of`].
2444    ///
2445    /// [`ArrayData`] therefore requires that all buffers have at least this alignment,
2446    /// to allow for [slice](std::slice) based APIs. See [`BufferSpec::FixedWidth`].
2447    ///
2448    /// As this alignment is architecture specific, and not guaranteed by all arrow implementations,
2449    /// this flag is provided to automatically copy buffers to a new correctly aligned allocation
2450    /// when necessary, making it useful when interacting with buffers produced by other systems,
2451    /// e.g. IPC or FFI.
2452    ///
2453    /// If this flag is not enabled, `[Self::build`] return an error on encountering
2454    /// insufficiently aligned buffers.
2455    pub fn align_buffers(mut self, align_buffers: bool) -> Self {
2456        self.align_buffers = align_buffers;
2457        self
2458    }
2459
2460    /// Skips validation of the data.
2461    ///
2462    /// If this flag is enabled, `[Self::build`] will skip validation of the
2463    /// data
2464    ///
2465    /// If this flag is not enabled, `[Self::build`] will validate that all
2466    /// buffers are valid and will return an error if any data is invalid.
2467    /// Validation can be expensive.
2468    ///
2469    /// # Safety
2470    ///
2471    /// If validation is skipped, the buffers must form a valid Arrow array,
2472    /// otherwise undefined behavior will result
2473    pub unsafe fn skip_validation(mut self, skip_validation: bool) -> Self {
2474        unsafe {
2475            self.skip_validation.set(skip_validation);
2476        }
2477        self
2478    }
2479}
2480
2481impl From<ArrayData> for ArrayDataBuilder {
2482    fn from(d: ArrayData) -> Self {
2483        Self {
2484            data_type: d.data_type,
2485            len: d.len,
2486            offset: d.offset,
2487            buffers: d.buffers,
2488            child_data: d.child_data,
2489            nulls: d.nulls,
2490            null_bit_buffer: None,
2491            null_count: None,
2492            align_buffers: false,
2493            skip_validation: UnsafeFlag::new(),
2494        }
2495    }
2496}
2497
2498/// Get byte width of FixedSizeBinary size
2499/// # Panics:
2500/// - Panics if the `data_type` is not FixedSizeBinary
2501/// - Panics if byte width is negative
2502pub(crate) fn get_fixed_size_binary_width(data_type: &DataType) -> usize {
2503    match data_type {
2504        DataType::FixedSizeBinary(i) => {
2505            if *i < 0 {
2506                panic!("cannot compare FixedSizeBinary({})", *i);
2507            }
2508            *i as usize
2509        }
2510        _ => unreachable!(),
2511    }
2512}
2513
2514#[cfg(test)]
2515mod tests {
2516    use arrow_schema::UnionFields;
2517
2518    use super::*;
2519    use crate::ByteView;
2520    use crate::transform::MutableArrayData;
2521    use arrow_buffer::{OffsetBuffer, ScalarBuffer};
2522    use arrow_schema::{Field, Fields};
2523
2524    // See arrow/tests/array_data_validation.rs for test of array validation
2525
2526    /// returns a buffer initialized with some constant value for tests
2527    fn make_i32_buffer(n: usize) -> Buffer {
2528        Buffer::from_slice_ref(vec![42i32; n])
2529    }
2530
2531    /// returns a buffer initialized with some constant value for tests
2532    fn make_f32_buffer(n: usize) -> Buffer {
2533        Buffer::from_slice_ref(vec![42f32; n])
2534    }
2535
2536    #[test]
2537    fn test_builder() {
2538        // Buffer needs to be at least 25 long
2539        let v = (0..25).collect::<Vec<i32>>();
2540        let b1 = Buffer::from_slice_ref(&v);
2541        let arr_data = ArrayData::builder(DataType::Int32)
2542            .len(20)
2543            .offset(5)
2544            .add_buffer(b1)
2545            .null_bit_buffer(Some(Buffer::from([
2546                0b01011111, 0b10110101, 0b01100011, 0b00011110,
2547            ])))
2548            .build()
2549            .unwrap();
2550
2551        assert_eq!(20, arr_data.len());
2552        assert_eq!(10, arr_data.null_count());
2553        assert_eq!(5, arr_data.offset());
2554        assert_eq!(1, arr_data.buffers().len());
2555        assert_eq!(
2556            Buffer::from_slice_ref(&v).as_slice(),
2557            arr_data.buffers()[0].as_slice()
2558        );
2559    }
2560
2561    #[test]
2562    fn test_builder_with_child_data() {
2563        let child_arr_data = ArrayData::try_new(
2564            DataType::Int32,
2565            5,
2566            None,
2567            0,
2568            vec![Buffer::from_slice_ref([1i32, 2, 3, 4, 5])],
2569            vec![],
2570        )
2571        .unwrap();
2572
2573        let field = Arc::new(Field::new("x", DataType::Int32, true));
2574        let data_type = DataType::Struct(vec![field].into());
2575
2576        let arr_data = ArrayData::builder(data_type)
2577            .len(5)
2578            .offset(0)
2579            .add_child_data(child_arr_data.clone())
2580            .build()
2581            .unwrap();
2582
2583        assert_eq!(5, arr_data.len());
2584        assert_eq!(1, arr_data.child_data().len());
2585        assert_eq!(child_arr_data, arr_data.child_data()[0]);
2586    }
2587
2588    #[test]
2589    fn test_struct_validation_accounts_for_parent_offset() {
2590        let data_type =
2591            DataType::Struct(Fields::from(vec![Field::new("x", DataType::Int32, false)]));
2592        let child = ArrayData::builder(DataType::Int32)
2593            .len(5)
2594            .add_buffer(Buffer::from_slice_ref([0, 1, 2, 3, 4]))
2595            .build()
2596            .unwrap();
2597
2598        // The parent needs child elements 1..6, but the child only has five.
2599        let err = ArrayData::builder(data_type)
2600            .len(5)
2601            .offset(1)
2602            .add_child_data(child)
2603            .build()
2604            .unwrap_err()
2605            .to_string();
2606
2607        assert!(err.contains(
2608            "child array #0 for field x has length smaller than expected for struct array (5 < 6)"
2609        ));
2610    }
2611
2612    #[test]
2613    fn test_struct_non_nullable_child_nulls_account_for_parent_offset() {
2614        let build = |parent_nulls| {
2615            let child = ArrayData::builder(DataType::Int32)
2616                .len(5)
2617                .add_buffer(Buffer::from_slice_ref([0, 1, 2, 3, 4]))
2618                .nulls(Some(NullBuffer::new(BooleanBuffer::from(vec![
2619                    true, true, false, true, true,
2620                ]))))
2621                .build()
2622                .unwrap();
2623
2624            ArrayData::builder(DataType::Struct(Fields::from(vec![Field::new(
2625                "x",
2626                DataType::Int32,
2627                false,
2628            )])))
2629            .len(4)
2630            .offset(1)
2631            .nulls(Some(NullBuffer::new(BooleanBuffer::from(parent_nulls))))
2632            .add_child_data(child)
2633            .build()
2634        };
2635
2636        assert!(build(vec![true, false, true, true]).is_ok());
2637        assert!(build(vec![true, true, false, true]).is_err());
2638    }
2639
2640    #[test]
2641    fn test_fixed_size_list_non_nullable_child_nulls_account_for_parent_offset() {
2642        for child_offset in [0, 1] {
2643            let child = ArrayData::builder(DataType::Int32)
2644                .len(6)
2645                .offset(child_offset)
2646                .add_buffer(Buffer::from_slice_ref([0i32; 7]))
2647                .nulls(Some(NullBuffer::from(vec![
2648                    true, true, false, false, true, true,
2649                ])))
2650                .build()
2651                .unwrap();
2652            let build = |parent_nulls| {
2653                ArrayData::builder(DataType::FixedSizeList(
2654                    Arc::new(Field::new("item", DataType::Int32, false)),
2655                    2,
2656                ))
2657                .offset(1)
2658                .len(2)
2659                .nulls(Some(NullBuffer::from(parent_nulls)))
2660                .add_child_data(child.clone())
2661                .build()
2662            };
2663
2664            // The first visible list contains both child nulls.
2665            assert!(build(vec![false, true]).is_ok());
2666            assert!(build(vec![true, false]).is_err());
2667        }
2668    }
2669
2670    #[test]
2671    fn test_fixed_size_list_non_nullable_child_nulls_without_parent_nulls() {
2672        let child = ArrayData::builder(DataType::Int32)
2673            .len(6)
2674            .add_buffer(Buffer::from_slice_ref([0i32; 6]))
2675            .nulls(Some(NullBuffer::from(vec![
2676                false, false, true, true, false, false,
2677            ])))
2678            .build()
2679            .unwrap();
2680        let build = |offset, len, size| {
2681            ArrayData::builder(DataType::FixedSizeList(
2682                Arc::new(Field::new("item", DataType::Int32, false)),
2683                size,
2684            ))
2685            .offset(offset)
2686            .len(len)
2687            .add_child_data(child.clone())
2688            .build()
2689        };
2690
2691        // Nulls before and after the visible child range are irrelevant.
2692        assert!(build(1, 1, 2).is_ok());
2693        assert!(build(0, 1, 2).is_err());
2694        assert!(build(2, 1, 2).is_err());
2695        assert!(build(3, 0, 2).is_ok());
2696        assert!(build(1, 2, 0).is_ok());
2697    }
2698
2699    #[test]
2700    fn test_fixed_size_list_validation_accounts_for_parent_offset() {
2701        for nulls in [None, Some(NullBuffer::new_null(4))] {
2702            let child = ArrayData::builder(DataType::Int32)
2703                .len(4)
2704                .add_buffer(Buffer::from_slice_ref([0i32; 4]))
2705                .nulls(nulls)
2706                .build()
2707                .unwrap();
2708            let err = ArrayData::builder(DataType::FixedSizeList(
2709                Arc::new(Field::new("item", DataType::Int32, false)),
2710                2,
2711            ))
2712            .offset(1)
2713            .len(2)
2714            .add_child_data(child)
2715            .build()
2716            .unwrap_err()
2717            .to_string();
2718            assert!(err.contains("Values length 4 is less than"));
2719        }
2720    }
2721
2722    #[test]
2723    fn test_struct_equal_accounts_for_parent_offset() {
2724        let data_type =
2725            DataType::Struct(Fields::from(vec![Field::new("x", DataType::Int32, false)]));
2726
2727        let child1 = ArrayData::builder(DataType::Int32)
2728            .len(5)
2729            .add_buffer(Buffer::from_slice_ref([0, 1, 2, 3, 4]))
2730            .build()
2731            .unwrap();
2732        let child2 = child1.slice(1, 4);
2733
2734        // data1 has offset at parent level; data2 has offset at child level.
2735        let data1 = ArrayData::builder(data_type.clone())
2736            .len(4)
2737            .offset(1)
2738            .add_child_data(child1)
2739            .build()
2740            .unwrap();
2741        let data2 = ArrayData::builder(data_type)
2742            .len(4)
2743            .add_child_data(child2)
2744            .build()
2745            .unwrap();
2746
2747        assert_eq!(data1, data2);
2748    }
2749
2750    #[test]
2751    fn test_extend_struct_accounts_for_parent_offset() {
2752        let data_type =
2753            DataType::Struct(Fields::from(vec![Field::new("x", DataType::Int32, false)]));
2754        let child = ArrayData::builder(DataType::Int32)
2755            .len(5)
2756            .add_buffer(Buffer::from_slice_ref([0, 1, 2, 3, 4]))
2757            .build()
2758            .unwrap();
2759
2760        let data = ArrayData::builder(data_type)
2761            .len(4)
2762            .offset(1)
2763            .add_child_data(child)
2764            .build()
2765            .unwrap();
2766
2767        let mut mutable = MutableArrayData::new(vec![&data], false, data.len());
2768        mutable.try_extend(0, 0, data.len()).unwrap();
2769        let output = mutable.freeze();
2770
2771        assert_eq!(output.child_data()[0].buffer::<i32>(0), &[1, 2, 3, 4]);
2772    }
2773
2774    #[test]
2775    fn test_extend_fixed_size_list_accounts_for_parent_offset() {
2776        let field = Arc::new(Field::new("item", DataType::Int32, false));
2777        let child = ArrayData::builder(DataType::Int32)
2778            .len(6)
2779            .add_buffer(Buffer::from_slice_ref([0, 1, 2, 3, 4, 5]))
2780            .build()
2781            .unwrap();
2782
2783        let data = ArrayData::builder(DataType::FixedSizeList(field, 2))
2784            .len(2)
2785            .offset(1)
2786            .add_child_data(child)
2787            .build()
2788            .unwrap();
2789
2790        let mut mutable = MutableArrayData::new(vec![&data], false, data.len());
2791        mutable.try_extend(0, 0, data.len()).unwrap();
2792        let output = mutable.freeze();
2793
2794        assert_eq!(output.child_data()[0].buffer::<i32>(0), &[2, 3, 4, 5]);
2795    }
2796
2797    #[test]
2798    fn test_extend_sparse_union_accounts_for_parent_offset() {
2799        let fields = UnionFields::try_new(
2800            [0, 1],
2801            [
2802                Field::new("a", DataType::Int32, false),
2803                Field::new("b", DataType::Int32, false),
2804            ],
2805        )
2806        .unwrap();
2807        let child_a = ArrayData::builder(DataType::Int32)
2808            .len(3)
2809            .add_buffer(Buffer::from_slice_ref([10, 20, 30]))
2810            .build()
2811            .unwrap();
2812        let child_b = ArrayData::builder(DataType::Int32)
2813            .len(3)
2814            .add_buffer(Buffer::from_slice_ref([100, 200, 300]))
2815            .build()
2816            .unwrap();
2817
2818        // The children are left whole, as `ArrayData::slice` and C Data
2819        // Interface producers leave them for a sparse union
2820        let data = ArrayData::builder(DataType::Union(fields, UnionMode::Sparse))
2821            .len(2)
2822            .offset(1)
2823            .add_buffer(Buffer::from_slice_ref([0i8, 1, 0]))
2824            .add_child_data(child_a)
2825            .add_child_data(child_b)
2826            .build()
2827            .unwrap();
2828
2829        let mut mutable = MutableArrayData::new(vec![&data], false, data.len());
2830        mutable.try_extend(0, 0, data.len()).unwrap();
2831        let output = mutable.freeze();
2832
2833        assert_eq!(output.buffer::<i8>(0), &[1, 0]);
2834        assert_eq!(output.child_data()[0].buffer::<i32>(0), &[20, 30]);
2835        assert_eq!(output.child_data()[1].buffer::<i32>(0), &[200, 300]);
2836    }
2837
2838    #[test]
2839    fn test_null_count() {
2840        let mut bit_v: [u8; 2] = [0; 2];
2841        bit_util::set_bit(&mut bit_v, 0);
2842        bit_util::set_bit(&mut bit_v, 3);
2843        bit_util::set_bit(&mut bit_v, 10);
2844        let arr_data = ArrayData::builder(DataType::Int32)
2845            .len(16)
2846            .add_buffer(make_i32_buffer(16))
2847            .null_bit_buffer(Some(Buffer::from(bit_v)))
2848            .build()
2849            .unwrap();
2850        assert_eq!(13, arr_data.null_count());
2851
2852        // Test with offset
2853        let mut bit_v: [u8; 2] = [0; 2];
2854        bit_util::set_bit(&mut bit_v, 0);
2855        bit_util::set_bit(&mut bit_v, 3);
2856        bit_util::set_bit(&mut bit_v, 10);
2857        let arr_data = ArrayData::builder(DataType::Int32)
2858            .len(12)
2859            .offset(2)
2860            .add_buffer(make_i32_buffer(14)) // requires at least 14 bytes of space,
2861            .null_bit_buffer(Some(Buffer::from(bit_v)))
2862            .build()
2863            .unwrap();
2864        assert_eq!(10, arr_data.null_count());
2865    }
2866
2867    #[test]
2868    fn test_null_buffer_ref() {
2869        let mut bit_v: [u8; 2] = [0; 2];
2870        bit_util::set_bit(&mut bit_v, 0);
2871        bit_util::set_bit(&mut bit_v, 3);
2872        bit_util::set_bit(&mut bit_v, 10);
2873        let arr_data = ArrayData::builder(DataType::Int32)
2874            .len(16)
2875            .add_buffer(make_i32_buffer(16))
2876            .null_bit_buffer(Some(Buffer::from(bit_v)))
2877            .build()
2878            .unwrap();
2879        assert!(arr_data.nulls().is_some());
2880        assert_eq!(&bit_v, arr_data.nulls().unwrap().validity());
2881    }
2882
2883    #[test]
2884    fn test_slice() {
2885        let mut bit_v: [u8; 2] = [0; 2];
2886        bit_util::set_bit(&mut bit_v, 0);
2887        bit_util::set_bit(&mut bit_v, 3);
2888        bit_util::set_bit(&mut bit_v, 10);
2889        let data = ArrayData::builder(DataType::Int32)
2890            .len(16)
2891            .add_buffer(make_i32_buffer(16))
2892            .null_bit_buffer(Some(Buffer::from(bit_v)))
2893            .build()
2894            .unwrap();
2895        let new_data = data.slice(1, 15);
2896        assert_eq!(data.len() - 1, new_data.len());
2897        assert_eq!(1, new_data.offset());
2898        assert_eq!(data.null_count(), new_data.null_count());
2899
2900        // slice of a slice (removes one null)
2901        let new_data = new_data.slice(1, 14);
2902        assert_eq!(data.len() - 2, new_data.len());
2903        assert_eq!(2, new_data.offset());
2904        assert_eq!(data.null_count() - 1, new_data.null_count());
2905    }
2906
2907    #[test]
2908    #[should_panic(expected = "offset + length overflow")]
2909    fn test_slice_panics_on_offset_length_overflow() {
2910        let data = ArrayData::builder(DataType::Int32)
2911            .len(4)
2912            .add_buffer(make_i32_buffer(4))
2913            .build()
2914            .unwrap();
2915        let sliced = data.slice(1, 3);
2916
2917        sliced.slice(1, usize::MAX);
2918    }
2919
2920    #[test]
2921    fn test_sliced() {
2922        for nulls in [
2923            None,
2924            Some(NullBuffer::from(vec![true, false, true, false, true])),
2925        ] {
2926            let data = ArrayData::builder(DataType::Int32)
2927                .len(5)
2928                .offset(1)
2929                .add_buffer(make_i32_buffer(6))
2930                .nulls(nulls)
2931                .build()
2932                .unwrap();
2933
2934            for offset in 0..=data.len() {
2935                for length in 0..=data.len() - offset {
2936                    let owned = data.clone();
2937                    let buffers = owned.buffers().as_ptr();
2938                    let sliced = owned.sliced(offset, length);
2939                    assert_eq!(sliced, data.slice(offset, length));
2940                    assert_eq!(sliced.len(), length);
2941                    assert_eq!(sliced.offset(), 1 + offset);
2942                    assert_eq!(sliced.buffers().as_ptr(), buffers);
2943                    assert_eq!(sliced.buffers()[0].as_ptr(), data.buffers()[0].as_ptr());
2944                    if let Some(nulls) = data.nulls() {
2945                        assert_eq!(
2946                            sliced.nulls().unwrap().iter().collect::<Vec<_>>(),
2947                            nulls.iter().skip(offset).take(length).collect::<Vec<_>>()
2948                        );
2949                    }
2950                    sliced.validate_full().unwrap();
2951                }
2952            }
2953        }
2954
2955        let empty = ArrayData::new_empty(&DataType::Int32);
2956        assert_eq!(empty.clone().sliced(0, 0), empty);
2957    }
2958
2959    #[test]
2960    fn test_sliced_nested_struct() {
2961        let child = ArrayData::builder(DataType::Int32)
2962            .len(8)
2963            .offset(1)
2964            .add_buffer(make_i32_buffer(9))
2965            .nulls(Some(NullBuffer::from(vec![
2966                true, false, true, false, true, true, false, true,
2967            ])))
2968            .build()
2969            .unwrap();
2970        let inner = ArrayData::builder(DataType::Struct(Fields::from(vec![Field::new(
2971            "x",
2972            DataType::Int32,
2973            true,
2974        )])))
2975        .len(6)
2976        .offset(1)
2977        .nulls(Some(NullBuffer::from(vec![
2978            true, false, true, true, false, true,
2979        ])))
2980        .add_child_data(child)
2981        .build()
2982        .unwrap();
2983        let data = ArrayData::builder(DataType::Struct(Fields::from(vec![Field::new(
2984            "inner",
2985            inner.data_type().clone(),
2986            true,
2987        )])))
2988        .len(4)
2989        .offset(1)
2990        .nulls(Some(NullBuffer::from(vec![false, true, false, true])))
2991        .add_child_data(inner)
2992        .build()
2993        .unwrap();
2994
2995        for (offset, length) in [(0, 4), (1, 2), (4, 0), (0, 0)] {
2996            let owned = data.clone();
2997            let children = owned.child_data().as_ptr();
2998            let grandchildren = owned.child_data()[0].child_data().as_ptr();
2999            let buffers = owned.child_data()[0].child_data()[0].buffers().as_ptr();
3000            let sliced = owned.sliced(offset, length);
3001            let inner = &sliced.child_data()[0];
3002            let child = &inner.child_data()[0];
3003            assert_eq!(sliced, data.slice(offset, length));
3004            assert_eq!(sliced.offset(), 0);
3005            assert_eq!(inner.offset(), 0);
3006            assert_eq!(child.offset(), 3 + offset);
3007            assert_eq!(sliced.child_data().as_ptr(), children);
3008            assert_eq!(inner.child_data().as_ptr(), grandchildren);
3009            assert_eq!(child.buffers().as_ptr(), buffers);
3010            sliced.validate_full().unwrap();
3011        }
3012
3013        let sliced = data.sliced(1, 2).sliced(1, 1);
3014        assert_eq!(sliced.null_count(), 1);
3015        assert_eq!(sliced.child_data()[0].null_count(), 0);
3016        assert_eq!(sliced.child_data()[0].child_data()[0].offset(), 5);
3017        assert_eq!(sliced.child_data()[0].child_data()[0].null_count(), 0);
3018    }
3019
3020    #[test]
3021    fn test_sliced_list_preserves_children() {
3022        let child = ArrayData::builder(DataType::Int32)
3023            .len(6)
3024            .offset(1)
3025            .add_buffer(make_i32_buffer(7))
3026            .nulls(Some(NullBuffer::from(vec![
3027                true, false, true, false, true, true,
3028            ])))
3029            .build()
3030            .unwrap();
3031        let data = ArrayData::builder(DataType::List(Arc::new(Field::new(
3032            "item",
3033            DataType::Int32,
3034            true,
3035        ))))
3036        .len(4)
3037        .offset(1)
3038        .add_buffer(Buffer::from_slice_ref([0i32, 1, 2, 3, 4, 5]))
3039        .nulls(Some(NullBuffer::from(vec![false, true, false, true])))
3040        .add_child_data(child)
3041        .build()
3042        .unwrap();
3043        let buffers = data.buffers().as_ptr();
3044        let children = data.child_data().as_ptr();
3045        let child_buffers = data.child_data()[0].buffers().as_ptr();
3046        let expected = data.slice(1, 2);
3047        let sliced = data.sliced(1, 2);
3048        assert_eq!(sliced, expected);
3049        assert_eq!(sliced.offset(), 2);
3050        assert_eq!(sliced.child_data()[0].len(), 6);
3051        assert_eq!(sliced.child_data()[0].offset(), 1);
3052        assert_eq!(sliced.buffers().as_ptr(), buffers);
3053        assert_eq!(sliced.child_data().as_ptr(), children);
3054        assert_eq!(sliced.child_data()[0].buffers().as_ptr(), child_buffers);
3055        sliced.validate_full().unwrap();
3056    }
3057
3058    #[test]
3059    #[should_panic(expected = "offset + length overflow")]
3060    fn test_sliced_panics_on_offset_length_overflow() {
3061        ArrayData::new_null(&DataType::Int32, 4).sliced(1, usize::MAX);
3062    }
3063
3064    #[test]
3065    #[should_panic(expected = "end <= self.len()")]
3066    fn test_sliced_panics_on_offset_out_of_bounds() {
3067        ArrayData::new_null(&DataType::Int32, 4).sliced(5, 0);
3068    }
3069
3070    #[test]
3071    #[should_panic(expected = "end <= self.len()")]
3072    fn test_sliced_panics_on_length_out_of_bounds() {
3073        ArrayData::new_null(&DataType::Int32, 4).sliced(3, 2);
3074    }
3075
3076    #[test]
3077    fn test_typed_offsets_length_overflow() {
3078        let data = ArrayData {
3079            data_type: DataType::Binary,
3080            len: usize::MAX,
3081            offset: 0,
3082            buffers: vec![Buffer::from_slice_ref([0_i32])],
3083            child_data: vec![],
3084            nulls: None,
3085        };
3086        let err = data.typed_offsets::<i32>().unwrap_err();
3087
3088        assert_eq!(
3089            err.to_string(),
3090            format!(
3091                "Invalid argument error: Length {} with offset 1 overflows usize for Binary",
3092                usize::MAX
3093            )
3094        );
3095    }
3096
3097    #[test]
3098    fn test_validate_typed_buffer_length_overflow() {
3099        let data = ArrayData {
3100            data_type: DataType::Binary,
3101            len: 0,
3102            offset: 2,
3103            buffers: vec![Buffer::from_slice_ref([0_i32])],
3104            child_data: vec![],
3105            nulls: None,
3106        };
3107        let err = data.typed_buffer::<i32>(0, usize::MAX).unwrap_err();
3108
3109        assert_eq!(
3110            err.to_string(),
3111            format!(
3112                "Invalid argument error: Length {} with offset 2 overflows usize for Binary",
3113                usize::MAX
3114            )
3115        );
3116    }
3117
3118    // Exercises ArrayData::try_new with len + offset overflowing
3119    fn try_new_binary_length_offset_overflow() -> Result<ArrayData, ArrowError> {
3120        ArrayData::try_new(
3121            DataType::Binary,
3122            usize::MAX,
3123            None,
3124            1,
3125            vec![
3126                Buffer::from_slice_ref([0_i32]),
3127                Buffer::from_iter(std::iter::empty::<u8>()),
3128            ],
3129            vec![],
3130        )
3131    }
3132
3133    #[cfg(not(feature = "force_validate"))]
3134    #[test]
3135    fn test_try_new_length_offset_overflow() {
3136        let err = try_new_binary_length_offset_overflow().unwrap_err();
3137
3138        assert_eq!(
3139            err.to_string(),
3140            format!(
3141                "Invalid argument error: Length {} with offset 1 overflows usize for Binary",
3142                usize::MAX
3143            )
3144        );
3145    }
3146
3147    #[cfg(feature = "force_validate")]
3148    #[test]
3149    #[should_panic(
3150        expected = "Length 18446744073709551615 with offset 1 overflows usize for Binary"
3151    )]
3152    fn test_try_new_length_offset_overflow_force_validate() {
3153        try_new_binary_length_offset_overflow().unwrap();
3154    }
3155
3156    #[test]
3157    fn test_equality() {
3158        let int_data = ArrayData::builder(DataType::Int32)
3159            .len(1)
3160            .add_buffer(make_i32_buffer(1))
3161            .build()
3162            .unwrap();
3163
3164        let float_data = ArrayData::builder(DataType::Float32)
3165            .len(1)
3166            .add_buffer(make_f32_buffer(1))
3167            .build()
3168            .unwrap();
3169        assert_ne!(int_data, float_data);
3170        assert!(!int_data.ptr_eq(&float_data));
3171        assert!(int_data.ptr_eq(&int_data));
3172
3173        let int_data_clone = int_data.clone();
3174        assert_eq!(int_data, int_data_clone);
3175        assert!(int_data.ptr_eq(&int_data_clone));
3176        assert!(int_data_clone.ptr_eq(&int_data));
3177
3178        let int_data_slice = int_data_clone.slice(1, 0);
3179        assert!(int_data_slice.ptr_eq(&int_data_slice));
3180        assert!(!int_data.ptr_eq(&int_data_slice));
3181        assert!(!int_data_slice.ptr_eq(&int_data));
3182
3183        let data_buffer = Buffer::from_slice_ref(b"abcdef");
3184        let offsets_buffer = Buffer::from_slice_ref([0_i32, 2_i32, 2_i32, 5_i32]);
3185        let string_data = ArrayData::try_new(
3186            DataType::Utf8,
3187            3,
3188            Some(Buffer::from_iter(vec![true, false, true])),
3189            0,
3190            vec![offsets_buffer, data_buffer],
3191            vec![],
3192        )
3193        .unwrap();
3194
3195        assert_ne!(float_data, string_data);
3196        assert!(!float_data.ptr_eq(&string_data));
3197
3198        assert!(string_data.ptr_eq(&string_data));
3199
3200        let string_data_cloned = string_data.clone();
3201        assert!(string_data_cloned.ptr_eq(&string_data));
3202        assert!(string_data.ptr_eq(&string_data_cloned));
3203
3204        let string_data_slice = string_data.slice(1, 2);
3205        assert!(string_data_slice.ptr_eq(&string_data_slice));
3206        assert!(!string_data_slice.ptr_eq(&string_data))
3207    }
3208
3209    #[test]
3210    fn test_slice_memory_size_view_payload_buffers() {
3211        for data_type in [DataType::Utf8View, DataType::BinaryView] {
3212            let inline_only = ArrayData::builder(data_type.clone())
3213                .len(2)
3214                .add_buffer(Buffer::from_vec(vec![0_u128; 2]))
3215                .build()
3216                .unwrap();
3217            assert_eq!(
3218                inline_only.get_slice_memory_size().unwrap(),
3219                2 * mem::size_of::<u128>()
3220            );
3221
3222            let mut first_payload = Vec::with_capacity(32);
3223            first_payload.extend_from_slice(b"first payload");
3224            let first_view =
3225                ByteView::new(first_payload.len().try_into().unwrap(), &first_payload[..4])
3226                    .as_u128();
3227            let first_payload = Buffer::from_vec(first_payload);
3228            assert!(first_payload.capacity() > first_payload.len());
3229            let first_payload_capacity = first_payload.capacity();
3230
3231            let mut second_payload = Vec::with_capacity(64);
3232            second_payload.extend_from_slice(b"second payload");
3233            let second_view = ByteView::new(
3234                second_payload.len().try_into().unwrap(),
3235                &second_payload[..4],
3236            )
3237            .with_buffer_index(1)
3238            .as_u128();
3239            let second_payload = Buffer::from_vec(second_payload);
3240            assert!(second_payload.capacity() > second_payload.len());
3241            let second_payload_capacity = second_payload.capacity();
3242
3243            let data = ArrayData::builder(data_type)
3244                .len(3)
3245                .add_buffer(Buffer::from_vec(vec![first_view, 0_u128, second_view]))
3246                .add_buffer(first_payload)
3247                .add_buffer(second_payload)
3248                .build()
3249                .unwrap();
3250            let sliced = data.slice(1, 1);
3251
3252            assert_eq!(
3253                sliced.get_slice_memory_size().unwrap(),
3254                mem::size_of::<u128>() + first_payload_capacity + second_payload_capacity
3255            );
3256        }
3257    }
3258
3259    #[test]
3260    fn test_slice_memory_size_utf8_offset_buffer_len_plus_one() {
3261        // 2-element array ["hello", "world"]: array len = 2, 10 bytes
3262        let data_buffer = Buffer::from_slice_ref(b"helloworld");
3263        // offsets need array_len+1 entries to mark the end of every string:
3264        //   [0, 5, 10] -> 3 i32s = 12 bytes
3265        let offsets_buffer = Buffer::from_slice_ref([0_i32, 5_i32, 10_i32]);
3266        let array = ArrayData::try_new(
3267            DataType::Utf8,
3268            2,
3269            None,
3270            0,
3271            vec![offsets_buffer, data_buffer],
3272            vec![],
3273        )
3274        .unwrap();
3275        assert_eq!(array.get_slice_memory_size().unwrap(), 22); // 12 + 10
3276    }
3277
3278    #[test]
3279    fn test_slice_memory_size_binary_offset_buffer_len_plus_one() {
3280        // 2-element array: array len = 2, not 3
3281        // values: 5 bytes
3282        let data_buffer = Buffer::from_slice_ref([0u8, 1, 2, 3, 4]);
3283        // offsets need array_len+1 entries to mark the end of every element:
3284        let offsets_buffer = Buffer::from_slice_ref([0_i32, 2_i32, 5_i32]);
3285        let array = ArrayData::try_new(
3286            DataType::Binary,
3287            2,
3288            None,
3289            0,
3290            vec![offsets_buffer, data_buffer],
3291            vec![],
3292        )
3293        .unwrap();
3294        assert_eq!(array.get_slice_memory_size().unwrap(), 17); // 12 + 5
3295    }
3296
3297    #[test]
3298    fn test_slice_memory_size() {
3299        let mut bit_v: [u8; 2] = [0; 2];
3300        bit_util::set_bit(&mut bit_v, 0);
3301        bit_util::set_bit(&mut bit_v, 3);
3302        bit_util::set_bit(&mut bit_v, 10);
3303        let data = ArrayData::builder(DataType::Int32)
3304            .len(16)
3305            .add_buffer(make_i32_buffer(16))
3306            .null_bit_buffer(Some(Buffer::from(bit_v)))
3307            .build()
3308            .unwrap();
3309        let new_data = data.slice(1, 14);
3310        assert_eq!(
3311            data.get_slice_memory_size().unwrap() - 8,
3312            new_data.get_slice_memory_size().unwrap()
3313        );
3314        let data_buffer = Buffer::from_slice_ref(b"abcdef");
3315        let offsets_buffer = Buffer::from_slice_ref([0_i32, 2_i32, 2_i32, 5_i32]);
3316        let string_data = ArrayData::try_new(
3317            DataType::Utf8,
3318            3,
3319            Some(Buffer::from_iter(vec![true, false, true])),
3320            0,
3321            vec![offsets_buffer, data_buffer],
3322            vec![],
3323        )
3324        .unwrap();
3325        let string_data_slice = string_data.slice(1, 2);
3326        //4 bytes of offset and 2 bytes of data reduced by slicing.
3327        assert_eq!(
3328            string_data.get_slice_memory_size().unwrap() - 6,
3329            string_data_slice.get_slice_memory_size().unwrap()
3330        );
3331    }
3332
3333    #[test]
3334    fn test_builder_rejects_short_null_bit_buffer() {
3335        for (len, offset) in [(8000, 0), (8, 1)] {
3336            let err = ArrayData::builder(DataType::Int32)
3337                .len(len)
3338                .offset(offset)
3339                .add_buffer(make_i32_buffer(len + offset))
3340                .null_bit_buffer(Some(Buffer::from([0_u8])))
3341                .build()
3342                .unwrap_err();
3343            assert_eq!(
3344                err.to_string(),
3345                format!(
3346                    "Invalid argument error: null_bit_buffer size too small. got 1 needed {}",
3347                    bit_util::ceil(len + offset, 8)
3348                )
3349            );
3350        }
3351    }
3352
3353    #[test]
3354    fn test_builder_null_bit_buffer_length_overflow() {
3355        let err = ArrayData::builder(DataType::Int32)
3356            .len(usize::MAX)
3357            .offset(1)
3358            .null_bit_buffer(Some(Buffer::default()))
3359            .build()
3360            .unwrap_err();
3361        assert_eq!(
3362            err.to_string(),
3363            format!(
3364                "Invalid argument error: Length {} with offset 1 overflows usize for Int32",
3365                usize::MAX
3366            )
3367        );
3368    }
3369
3370    #[test]
3371    fn test_builder_accepts_valid_null_bit_buffer() {
3372        for (len, offset) in [(8, 0), (7, 1)] {
3373            let data = ArrayData::builder(DataType::Int32)
3374                .len(len)
3375                .offset(offset)
3376                .add_buffer(make_i32_buffer(len + offset))
3377                .null_bit_buffer(Some(Buffer::from([0_u8])))
3378                .build()
3379                .unwrap();
3380            assert_eq!(data.len(), len);
3381            assert_eq!(data.offset(), offset);
3382            assert_eq!(data.null_count(), len);
3383        }
3384    }
3385
3386    #[test]
3387    fn test_count_nulls() {
3388        let buffer = Buffer::from([0b00010110, 0b10011111]);
3389        let buffer = NullBuffer::new(BooleanBuffer::new(buffer, 0, 16));
3390        let count = count_nulls(Some(&buffer), 0, 16);
3391        assert_eq!(count, 7);
3392
3393        let count = count_nulls(Some(&buffer), 4, 8);
3394        assert_eq!(count, 3);
3395    }
3396
3397    #[test]
3398    fn test_contains_nulls() {
3399        let buffer: Buffer =
3400            MutableBuffer::from_iter([false, false, false, true, true, false]).into();
3401        let buffer = NullBuffer::new(BooleanBuffer::new(buffer, 0, 6));
3402        assert!(contains_nulls(Some(&buffer), 0, 6));
3403        assert!(contains_nulls(Some(&buffer), 0, 3));
3404        assert!(!contains_nulls(Some(&buffer), 3, 2));
3405        assert!(!contains_nulls(Some(&buffer), 0, 0));
3406    }
3407
3408    #[test]
3409    fn test_alignment() {
3410        let buffer = Buffer::from_vec(vec![1_i32, 2_i32, 3_i32]);
3411        let sliced = buffer.slice(1);
3412
3413        let mut data = ArrayData {
3414            data_type: DataType::Int32,
3415            len: 0,
3416            offset: 0,
3417            buffers: vec![buffer],
3418            child_data: vec![],
3419            nulls: None,
3420        };
3421        data.validate_full().unwrap();
3422
3423        // break alignment in data
3424        data.buffers[0] = sliced;
3425        let err = data.validate().unwrap_err();
3426
3427        assert_eq!(
3428            err.to_string(),
3429            "Invalid argument error: Misaligned buffers[0] in array of type Int32, offset from expected alignment of 4 by 1"
3430        );
3431
3432        data.align_buffers();
3433        data.validate_full().unwrap();
3434    }
3435
3436    #[test]
3437    fn test_alignment_struct() {
3438        let buffer = Buffer::from_vec(vec![1_i32, 2_i32, 3_i32]);
3439        let sliced = buffer.slice(1);
3440
3441        let child_data = ArrayData {
3442            data_type: DataType::Int32,
3443            len: 0,
3444            offset: 0,
3445            buffers: vec![buffer],
3446            child_data: vec![],
3447            nulls: None,
3448        };
3449
3450        let schema = DataType::Struct(Fields::from(vec![Field::new("a", DataType::Int32, false)]));
3451        let mut data = ArrayData {
3452            data_type: schema,
3453            len: 0,
3454            offset: 0,
3455            buffers: vec![],
3456            child_data: vec![child_data],
3457            nulls: None,
3458        };
3459        data.validate_full().unwrap();
3460
3461        // break alignment in child data
3462        data.child_data[0].buffers[0] = sliced;
3463        let err = data.validate().unwrap_err();
3464
3465        assert_eq!(
3466            err.to_string(),
3467            "Invalid argument error: Misaligned buffers[0] in array of type Int32, offset from expected alignment of 4 by 1"
3468        );
3469
3470        data.align_buffers();
3471        data.validate_full().unwrap();
3472    }
3473
3474    #[test]
3475    fn test_null_view_types() {
3476        let array_len = 32;
3477        let array = ArrayData::new_null(&DataType::BinaryView, array_len);
3478        assert_eq!(array.len(), array_len);
3479        for i in 0..array.len() {
3480            assert!(array.is_null(i));
3481        }
3482
3483        let array = ArrayData::new_null(&DataType::Utf8View, array_len);
3484        assert_eq!(array.len(), array_len);
3485        for i in 0..array.len() {
3486            assert!(array.is_null(i));
3487        }
3488
3489        let array = ArrayData::new_null(
3490            &DataType::ListView(Arc::new(Field::new_list_field(DataType::Int32, true))),
3491            array_len,
3492        );
3493        assert_eq!(array.len(), array_len);
3494        for i in 0..array.len() {
3495            assert!(array.is_null(i));
3496        }
3497
3498        let array = ArrayData::new_null(
3499            &DataType::LargeListView(Arc::new(Field::new_list_field(DataType::Int32, true))),
3500            array_len,
3501        );
3502        assert_eq!(array.len(), array_len);
3503        for i in 0..array.len() {
3504            assert!(array.is_null(i));
3505        }
3506    }
3507
3508    // Even when `force_validate` feature is on
3509    #[test]
3510    fn test_dont_panic_on_bad_input_when_using_try_new() {
3511        let empty_bytes = Buffer::default();
3512
3513        let array_data = ArrayData::try_new(
3514            DataType::Utf8,
3515            1, // len
3516            None,
3517            0,
3518            // the offsets says that we have 2 bytes but the buffer is empty
3519            vec![Buffer::from_vec(vec![0i32, 2i32]), empty_bytes],
3520            vec![],
3521        );
3522
3523        let res = array_data.expect_err("should get error");
3524
3525        assert_eq!(
3526            res.to_string(),
3527            "Invalid argument error: Last offset 2 of Utf8 is larger than values length 0"
3528        );
3529    }
3530
3531    /// Without `force_validate`, `build_unchecked` skips validation, so these can
3532    /// reach `validate_values` with a data type that has an invalid child type.
3533    #[test]
3534    #[cfg(not(feature = "force_validate"))]
3535    fn test_validate_values_rejects_a_non_integer_dictionary_key() {
3536        let values = valid_non_nullable_int32_array_data(2);
3537        let data_type = DataType::Dictionary(Box::new(DataType::Utf8), Box::new(DataType::Int32));
3538        let dictionary = unsafe {
3539            ArrayData::builder(data_type)
3540                .len(1)
3541                .add_child_data(values)
3542                .build_unchecked()
3543        };
3544
3545        let err = dictionary.validate_values().expect_err("should get error");
3546        assert_eq!(
3547            err.to_string(),
3548            "Invalid argument error: Dictionary key type must be an integer, got Utf8"
3549        );
3550    }
3551
3552    #[test]
3553    #[cfg(not(feature = "force_validate"))]
3554    fn test_validate_values_rejects_a_non_integer_run_end() {
3555        let data_type = DataType::RunEndEncoded(
3556            Arc::new(Field::new(
3557                Field::REE_RUN_ENDS_FIELD_DEFAULT_NAME,
3558                DataType::Utf8,
3559                false,
3560            )),
3561            Arc::new(Field::new(
3562                Field::REE_VALUES_FIELD_DEFAULT_NAME,
3563                DataType::Int32,
3564                true,
3565            )),
3566        );
3567        let run_end_encoded = unsafe {
3568            ArrayData::builder(data_type)
3569                .len(1)
3570                .add_child_data(valid_non_nullable_int32_array_data(1))
3571                .add_child_data(valid_non_nullable_int32_array_data(1))
3572                .build_unchecked()
3573        };
3574
3575        let err = run_end_encoded
3576            .validate_values()
3577            .expect_err("should get error");
3578        assert_eq!(
3579            err.to_string(),
3580            "Invalid argument error: Run end type must be Int16, Int32 or Int64, got Utf8"
3581        );
3582    }
3583
3584    /// Returns a `RunEndEncoded<Int32, Float32>` data type and run ends / values
3585    /// children whose runs end at `[1, 3]`, i.e. a logical length of 3.
3586    fn run_array_test_children() -> (DataType, Vec<ArrayData>) {
3587        let dt = DataType::RunEndEncoded(
3588            Arc::new(Field::new(
3589                Field::REE_RUN_ENDS_FIELD_DEFAULT_NAME,
3590                DataType::Int32,
3591                false,
3592            )),
3593            Arc::new(Field::new(
3594                Field::REE_VALUES_FIELD_DEFAULT_NAME,
3595                DataType::Float32,
3596                true,
3597            )),
3598        );
3599
3600        let runs = ArrayData::builder(DataType::Int32)
3601            .len(2)
3602            .add_buffer(vec![1_i32, 3].into())
3603            .build()
3604            .unwrap();
3605        let values = ArrayData::builder(DataType::Float32)
3606            .len(2)
3607            .add_buffer(vec![1.5_f32, 2.5].into())
3608            .build()
3609            .unwrap();
3610
3611        (dt, vec![runs, values])
3612    }
3613
3614    #[test]
3615    fn test_run_array_validates_last_run() {
3616        let (dt, children) = run_array_test_children();
3617
3618        let err = ArrayDataBuilder::new(dt)
3619            .len(4)
3620            .offset(0)
3621            .child_data(children)
3622            .build()
3623            .unwrap_err();
3624        assert_eq!(
3625            err.to_string(),
3626            "Invalid argument error: The offset + length of array should be less or equal to last value in the run_ends array. The last value of run_ends array is 3 and offset + length of array is 4."
3627        );
3628    }
3629
3630    #[test]
3631    fn test_run_array_empty_validates() {
3632        let (dt, children) = run_array_test_children();
3633
3634        let data = ArrayDataBuilder::new(dt)
3635            .len(0)
3636            .offset(4)
3637            .child_data(children)
3638            .build()
3639            .unwrap();
3640        assert_eq!(data.len(), 0);
3641    }
3642
3643    /// The parent's offset must be included when checking the last run end:
3644    /// offset 2 + length 2 = 4 exceeds the last run end of 3.
3645    #[test]
3646    fn test_run_array_validates_last_run_with_offset() {
3647        let (dt, children) = run_array_test_children();
3648
3649        let err = ArrayDataBuilder::new(dt)
3650            .len(2)
3651            .offset(2)
3652            .child_data(children)
3653            .build()
3654            .unwrap_err();
3655        assert_eq!(
3656            err.to_string(),
3657            "Invalid argument error: The offset + length of array should be less or equal to last value in the run_ends array. The last value of run_ends array is 3 and offset + length of array is 4."
3658        );
3659    }
3660
3661    /// A slice that stays within the last run end is valid:
3662    /// offset 1 + length 2 = 3 equals the last run end of 3.
3663    #[test]
3664    fn test_run_array_sliced_validates() {
3665        let (dt, children) = run_array_test_children();
3666
3667        let data = ArrayDataBuilder::new(dt)
3668            .len(2)
3669            .offset(1)
3670            .child_data(children)
3671            .build()
3672            .unwrap();
3673        assert_eq!(data.len(), 2);
3674        assert_eq!(data.offset(), 1);
3675    }
3676
3677    /// `validate_values` must report missing children rather than index out of bounds.
3678    #[test]
3679    #[cfg(not(feature = "force_validate"))]
3680    fn test_validate_values_rejects_missing_child_data() {
3681        let int32 = Box::new(DataType::Int32);
3682        let field = || Arc::new(Field::new("f", DataType::Int32, true));
3683        let data_types = [
3684            DataType::Dictionary(int32.clone(), int32.clone()),
3685            DataType::List(field()),
3686            DataType::LargeList(field()),
3687            DataType::RunEndEncoded(field(), field()),
3688        ];
3689
3690        for data_type in data_types {
3691            let data = unsafe {
3692                ArrayData::builder(data_type.clone())
3693                    .len(1)
3694                    .build_unchecked()
3695            };
3696            let err = data.validate_values().expect_err("should get error");
3697            assert_eq!(
3698                err.to_string(),
3699                format!(
3700                    "Invalid argument error: {data_type} should contain at least 1 child data array(s), had 0"
3701                )
3702            );
3703        }
3704    }
3705
3706    /// `validate_values` must report missing buffers rather than index out of bounds.
3707    #[test]
3708    #[cfg(not(feature = "force_validate"))]
3709    fn test_validate_values_rejects_missing_buffers() {
3710        // (data type, index of the first missing buffer)
3711        let cases = [
3712            (DataType::Utf8, 1),
3713            (DataType::LargeUtf8, 1),
3714            (DataType::Binary, 1),
3715            (DataType::LargeBinary, 1),
3716            (DataType::BinaryView, 0),
3717            (DataType::Utf8View, 0),
3718        ];
3719
3720        for (data_type, missing) in cases {
3721            let data = unsafe {
3722                ArrayData::builder(data_type.clone())
3723                    .len(1)
3724                    .build_unchecked()
3725            };
3726            let err = data.validate_values().expect_err("should get error");
3727            assert_eq!(
3728                err.to_string(),
3729                format!(
3730                    "Invalid argument error: {data_type} should contain at least {} buffer(s), had 0",
3731                    missing + 1
3732                )
3733            );
3734        }
3735    }
3736
3737    /// A dictionary whose keys buffer is too small must be reported, not asserted on.
3738    #[test]
3739    #[cfg(not(feature = "force_validate"))]
3740    fn test_validate_values_rejects_a_short_dictionary_keys_buffer() {
3741        let data_type = DataType::Dictionary(Box::new(DataType::Int32), Box::new(DataType::Int32));
3742        let dictionary = unsafe {
3743            ArrayData::builder(data_type)
3744                .len(4)
3745                .add_buffer(Buffer::from_slice_ref([1_i32, 0]))
3746                .add_child_data(valid_non_nullable_int32_array_data(2))
3747                .build_unchecked()
3748        };
3749
3750        let err = dictionary.validate_values().expect_err("should get error");
3751        assert_eq!(
3752            err.to_string(),
3753            "Invalid argument error: Buffer 0 of Dictionary(Int32, Int32) isn't large enough. Expected 16 bytes got 8"
3754        );
3755    }
3756
3757    #[test]
3758    fn should_fail_validation_when_having_map_field_type_is_not_struct() {
3759        let map_field = Field::new("key", DataType::Int32, false);
3760
3761        let map_field_data = valid_non_nullable_int32_array_data(2);
3762
3763        let results = test_both_builder_and_array_data(
3764            DataType::Map(map_field.into(), false),
3765            1,
3766            None,
3767            0,
3768            vec![
3769                OffsetBuffer::<i32>::from_lengths(vec![2])
3770                    .into_inner()
3771                    .into(),
3772            ],
3773            vec![map_field_data],
3774        );
3775
3776        for result in results {
3777            let array_data_err = result.expect_err("should fail for non struct field");
3778
3779            match array_data_err {
3780                ArrowError::InvalidArgumentError(msg) => {
3781                    assert_eq!(
3782                        msg,
3783                        "Map field should be a entries struct data type, got Int32 instead"
3784                    )
3785                }
3786                _ => panic!("unexpected error type {array_data_err}"),
3787            }
3788        }
3789    }
3790
3791    #[test]
3792    fn should_fail_validation_when_having_map_entries_only_have_1_field() {
3793        let struct_data_type = DataType::Struct(Fields::from(vec![Field::new(
3794            Field::MAP_KEY_FIELD_DEFAULT_NAME,
3795            DataType::Int32,
3796            false,
3797        )]));
3798
3799        let key_array_data = valid_non_nullable_int32_array_data(2);
3800
3801        let struct_data = {
3802            let builder = ArrayDataBuilder::new(struct_data_type.clone())
3803                .len(2)
3804                .nulls(None)
3805                .child_data(vec![key_array_data]);
3806
3807            builder.build().unwrap()
3808        };
3809
3810        let results = test_both_builder_and_array_data(
3811            DataType::Map(
3812                Field::new(
3813                    Field::MAP_ENTRIES_FIELD_DEFAULT_NAME,
3814                    struct_data_type,
3815                    false,
3816                )
3817                .into(),
3818                false,
3819            ),
3820            1,
3821            None,
3822            0,
3823            vec![
3824                OffsetBuffer::<i32>::from_lengths(vec![2])
3825                    .into_inner()
3826                    .into(),
3827            ],
3828            vec![struct_data],
3829        );
3830
3831        for result in results {
3832            let array_data_err = result.expect_err("should fail for nullable key");
3833
3834            match array_data_err {
3835                ArrowError::InvalidArgumentError(msg) => {
3836                    assert_eq!(
3837                        msg,
3838                        "Map entries data type should be a struct containing 2 fields, got 1 fields"
3839                    )
3840                }
3841                _ => panic!("unexpected error type {array_data_err}"),
3842            }
3843        }
3844    }
3845
3846    #[test]
3847    fn should_fail_validation_when_having_map_entries_have_3_fields() {
3848        let struct_data_type = DataType::Struct(Fields::from(vec![
3849            Field::new(Field::MAP_KEY_FIELD_DEFAULT_NAME, DataType::Int32, false),
3850            Field::new(Field::MAP_VALUE_FIELD_DEFAULT_NAME, DataType::Utf8, true),
3851            Field::new("other", DataType::Int32, true),
3852        ]));
3853
3854        let key_array_data = valid_non_nullable_int32_array_data(2);
3855
3856        let values_array_data = valid_string_array_data(2);
3857
3858        let other_array_data = key_array_data.clone();
3859
3860        let struct_data = {
3861            let builder = ArrayDataBuilder::new(struct_data_type.clone())
3862                .len(2)
3863                .nulls(None)
3864                .child_data(vec![key_array_data, values_array_data, other_array_data]);
3865
3866            builder.build().unwrap()
3867        };
3868
3869        let results = test_both_builder_and_array_data(
3870            DataType::Map(
3871                Field::new(
3872                    Field::MAP_ENTRIES_FIELD_DEFAULT_NAME,
3873                    struct_data_type,
3874                    false,
3875                )
3876                .into(),
3877                false,
3878            ),
3879            1,
3880            None,
3881            0,
3882            vec![
3883                OffsetBuffer::<i32>::from_lengths(vec![2])
3884                    .into_inner()
3885                    .into(),
3886            ],
3887            vec![struct_data],
3888        );
3889
3890        for result in results {
3891            let array_data_err = result.expect_err("should fail for nullable key");
3892
3893            match array_data_err {
3894                ArrowError::InvalidArgumentError(msg) => {
3895                    assert_eq!(
3896                        msg,
3897                        "Map entries data type should be a struct containing 2 fields, got 3 fields"
3898                    )
3899                }
3900                _ => panic!("unexpected error type {array_data_err}"),
3901            }
3902        }
3903    }
3904
3905    #[test]
3906    fn should_fail_validation_when_having_nullable_map_keys() {
3907        let struct_data_type = DataType::Struct(Fields::from(vec![
3908            Field::new(Field::MAP_KEY_FIELD_DEFAULT_NAME, DataType::Int32, true),
3909            Field::new(Field::MAP_VALUE_FIELD_DEFAULT_NAME, DataType::Utf8, true),
3910        ]));
3911
3912        let key_array_data = valid_non_nullable_int32_array_data(2);
3913        let values_array_data = valid_string_array_data(2);
3914
3915        let struct_data = {
3916            let builder = ArrayDataBuilder::new(struct_data_type.clone())
3917                .len(2)
3918                .nulls(None)
3919                .child_data(vec![key_array_data, values_array_data]);
3920
3921            builder.build().unwrap()
3922        };
3923
3924        let results = test_both_builder_and_array_data(
3925            DataType::Map(
3926                Field::new(
3927                    Field::MAP_ENTRIES_FIELD_DEFAULT_NAME,
3928                    struct_data_type,
3929                    false,
3930                )
3931                .into(),
3932                false,
3933            ),
3934            1,
3935            None,
3936            0,
3937            vec![
3938                OffsetBuffer::<i32>::from_lengths(vec![2])
3939                    .into_inner()
3940                    .into(),
3941            ],
3942            vec![struct_data],
3943        );
3944
3945        for result in results {
3946            let array_data_err = result.expect_err("should fail for nullable key");
3947
3948            match array_data_err {
3949                ArrowError::InvalidArgumentError(msg) => {
3950                    assert_eq!(msg, "Map key field must not be nullable")
3951                }
3952                _ => panic!("unexpected error type {array_data_err}"),
3953            }
3954        }
3955    }
3956
3957    #[test]
3958    fn should_fail_validation_when_having_entries_is_nullable_for_map() {
3959        let struct_data_type = DataType::Struct(Fields::from(vec![
3960            Field::new(Field::MAP_KEY_FIELD_DEFAULT_NAME, DataType::Int32, false),
3961            Field::new(Field::MAP_VALUE_FIELD_DEFAULT_NAME, DataType::Utf8, true),
3962        ]));
3963
3964        let key_array_data = valid_non_nullable_int32_array_data(2);
3965
3966        let values_array_data = valid_string_array_data(2);
3967
3968        let struct_data = {
3969            let builder = ArrayDataBuilder::new(struct_data_type.clone())
3970                .len(2)
3971                .nulls(None)
3972                .child_data(vec![key_array_data, values_array_data]);
3973
3974            builder.build().unwrap()
3975        };
3976
3977        let results = test_both_builder_and_array_data(
3978            DataType::Map(
3979                Field::new(
3980                    Field::MAP_ENTRIES_FIELD_DEFAULT_NAME,
3981                    struct_data_type,
3982                    true,
3983                )
3984                .into(),
3985                false,
3986            ),
3987            1,
3988            None,
3989            0,
3990            vec![
3991                OffsetBuffer::<i32>::from_lengths(vec![2])
3992                    .into_inner()
3993                    .into(),
3994            ],
3995            vec![struct_data],
3996        );
3997
3998        for result in results {
3999            let array_data_err = result.expect_err("should fail for nullable entries");
4000
4001            match array_data_err {
4002                ArrowError::InvalidArgumentError(msg) => assert_eq!(
4003                    msg,
4004                    "The nullable should be set to false for the map entries field."
4005                ),
4006                _ => panic!("unexpected error type {array_data_err}"),
4007            }
4008        }
4009    }
4010
4011    #[test]
4012    fn should_allow_to_create_map_from_data() {
4013        let struct_data_type = DataType::Struct(Fields::from(vec![
4014            Field::new(Field::MAP_KEY_FIELD_DEFAULT_NAME, DataType::Int32, false),
4015            Field::new(Field::MAP_VALUE_FIELD_DEFAULT_NAME, DataType::Utf8, true),
4016        ]));
4017
4018        let key_array_data = valid_non_nullable_int32_array_data(2);
4019        let values_array_data = valid_string_array_data(2);
4020
4021        let struct_data = {
4022            let builder = ArrayDataBuilder::new(struct_data_type.clone())
4023                .len(2)
4024                .nulls(None)
4025                .child_data(vec![key_array_data, values_array_data]);
4026
4027            builder.build().unwrap()
4028        };
4029
4030        let results = test_both_builder_and_array_data(
4031            DataType::Map(
4032                Field::new(
4033                    Field::MAP_ENTRIES_FIELD_DEFAULT_NAME,
4034                    struct_data_type,
4035                    false,
4036                )
4037                .into(),
4038                false,
4039            ),
4040            1,
4041            None,
4042            0,
4043            vec![
4044                OffsetBuffer::<i32>::from_lengths(vec![2])
4045                    .into_inner()
4046                    .into(),
4047            ],
4048            vec![struct_data],
4049        );
4050
4051        for result in results {
4052            result.expect("should be able to create map ArrayData");
4053        }
4054    }
4055
4056    fn valid_string_array_data(length: usize) -> ArrayData {
4057        let offsets = OffsetBuffer::<i32>::from_lengths(vec![0; length])
4058            .into_inner()
4059            .into_inner();
4060        let empty_bytes = Buffer::default();
4061
4062        let builder = ArrayDataBuilder::new(DataType::Utf8)
4063            .len(length)
4064            .buffers(vec![offsets, empty_bytes])
4065            .nulls(None);
4066
4067        builder.build().unwrap()
4068    }
4069
4070    fn valid_non_nullable_int32_array_data(length: usize) -> ArrayData {
4071        let builder = ArrayDataBuilder::new(DataType::Int32)
4072            .len(length)
4073            .nulls(None)
4074            .buffers(vec![
4075                ScalarBuffer::<i32>::from(vec![1; length]).into_inner(),
4076            ]);
4077
4078        builder.build().unwrap()
4079    }
4080
4081    #[test]
4082    fn empty_and_null_map_array_should_pass_validation() {
4083        let dt = DataType::Map(
4084            Field::new(
4085                Field::MAP_ENTRIES_FIELD_DEFAULT_NAME,
4086                DataType::Struct(Fields::from(vec![
4087                    Field::new(Field::MAP_KEY_FIELD_DEFAULT_NAME, DataType::Int32, false),
4088                    Field::new(Field::MAP_VALUE_FIELD_DEFAULT_NAME, DataType::Utf8, true),
4089                ])),
4090                false,
4091            )
4092            .into(),
4093            false,
4094        );
4095
4096        ArrayData::new_empty(&dt).validate_full().unwrap();
4097        ArrayData::new_null(&dt, 1).validate_full().unwrap();
4098    }
4099
4100    #[test]
4101    fn null_buffer_offset_is_independent_of_data_offset() {
4102        // 100 values sliced down to the last 50, so the data has offset 50.
4103        let int_data = ArrayData::builder(DataType::UInt32)
4104            .offset(50)
4105            .len(50)
4106            .add_buffer(Buffer::from_vec(vec![0_u32; 100]))
4107            .build()
4108            .unwrap();
4109        int_data.validate().unwrap();
4110
4111        // A null buffer that happens to share the data's offset.
4112        let nulls = NullBuffer::new(BooleanBuffer::from(vec![false; 100]).slice(0, 50));
4113        let with_sliced_nulls = int_data
4114            .clone()
4115            .into_builder()
4116            .nulls(Some(nulls))
4117            .build()
4118            .unwrap();
4119        with_sliced_nulls.validate().unwrap();
4120
4121        // The same 50 nulls at offset 0. ArrayData::offset does not apply to the
4122        // null buffer, so this is just as valid and must not be rejected.
4123        let nulls = NullBuffer::new(BooleanBuffer::from(vec![false; 50]));
4124        let with_unsliced_nulls = int_data.into_builder().nulls(Some(nulls)).build().unwrap();
4125        with_unsliced_nulls.validate().unwrap();
4126        assert_eq!(with_unsliced_nulls.null_count(), 50);
4127    }
4128
4129    fn test_both_builder_and_array_data(
4130        data_type: DataType,
4131        len: usize,
4132        null_bit_buffer: Option<Buffer>,
4133        offset: usize,
4134        buffers: Vec<Buffer>,
4135        child_data: Vec<ArrayData>,
4136    ) -> [Result<ArrayData, ArrowError>; 2] {
4137        let from_builder_res = ArrayData::builder(data_type.clone())
4138            .len(len)
4139            .add_buffers(buffers.clone())
4140            .null_bit_buffer(null_bit_buffer.clone())
4141            .offset(offset)
4142            .child_data(child_data.clone())
4143            .build();
4144
4145        let from_try_new_res =
4146            ArrayData::try_new(data_type, len, null_bit_buffer, offset, buffers, child_data);
4147
4148        [from_builder_res, from_try_new_res]
4149    }
4150
4151    #[test]
4152    fn test_new_null_empty_union() {
4153        for mode in [UnionMode::Sparse, UnionMode::Dense] {
4154            let data_type = DataType::Union(UnionFields::empty(), mode);
4155            let data = ArrayData::new_null(&data_type, 0);
4156            data.validate_full()
4157                .expect("an empty union of length zero is valid");
4158            assert_eq!(data.len(), 0);
4159            assert!(data.child_data().is_empty());
4160        }
4161    }
4162
4163    #[test]
4164    #[should_panic(expected = "cannot construct null data from an empty union")]
4165    fn test_new_null_empty_union_with_slots() {
4166        let data_type = DataType::Union(UnionFields::empty(), UnionMode::Dense);
4167        let _ = ArrayData::new_null(&data_type, 1);
4168    }
4169
4170    #[test]
4171    fn test_union_validate_type_ids() {
4172        let dt = DataType::Union(
4173            UnionFields::try_new(
4174                vec![5],
4175                vec![Arc::new(Field::new("a", DataType::Int32, true))],
4176            )
4177            .unwrap(),
4178            UnionMode::Sparse,
4179        );
4180
4181        let child = ArrayData::builder(DataType::Int32)
4182            .len(2)
4183            .add_buffer(make_i32_buffer(2))
4184            .build()
4185            .unwrap();
4186
4187        let err = ArrayDataBuilder::new(dt)
4188            .len(2)
4189            .offset(0)
4190            .buffers(vec![vec![5_i8, 2].into()])
4191            .child_data(vec![child])
4192            .build()
4193            .unwrap_err();
4194        assert_eq!(
4195            err.to_string(),
4196            "Invalid argument error: Type id values must match one of the field type ids, got 2 at index 1"
4197        );
4198    }
4199
4200    #[test]
4201    fn test_union_validate_dense_offsets() {
4202        let dt = DataType::Union(
4203            UnionFields::try_new(
4204                vec![5],
4205                vec![Arc::new(Field::new("a", DataType::Int32, true))],
4206            )
4207            .unwrap(),
4208            UnionMode::Dense,
4209        );
4210
4211        let child = ArrayData::builder(DataType::Int32)
4212            .len(2)
4213            .add_buffer(make_i32_buffer(2))
4214            .build()
4215            .unwrap();
4216
4217        let err = ArrayDataBuilder::new(dt.clone())
4218            .len(2)
4219            // 2nd offset '10' is out of bounds
4220            .buffers(vec![vec![5_i8, 5].into(), vec![0_i32, 10].into()])
4221            .child_data(vec![child.clone()])
4222            .build()
4223            .unwrap_err();
4224        assert_eq!(
4225            err.to_string(),
4226            "Invalid argument error: Offsets must be non-negative and within the length of the child array"
4227        );
4228
4229        let err = ArrayDataBuilder::new(dt)
4230            .len(2)
4231            // 2nd offset is negative
4232            .buffers(vec![vec![5_i8, 5].into(), vec![0_i32, -1].into()])
4233            .child_data(vec![child])
4234            .build()
4235            .unwrap_err();
4236        assert_eq!(
4237            err.to_string(),
4238            "Invalid argument error: Offsets must be non-negative and within the length of the child array"
4239        );
4240    }
4241}