diff --git a/arrow-array/src/array/boolean_array.rs b/arrow-array/src/array/boolean_array.rs index 9245f5b33700..decf16bb6df7 100644 --- a/arrow-array/src/array/boolean_array.rs +++ b/arrow-array/src/array/boolean_array.rs @@ -93,6 +93,17 @@ impl BooleanArray { Self { values, nulls } } + /// Create a new [`BooleanArray`] from the provided values and nulls without validation. + /// + /// # Safety + /// - `values.len() == nulls.len()` if `nulls` is `Some` + pub unsafe fn new_unchecked(values: BooleanBuffer, nulls: Option) -> Self { + if cfg!(feature = "force_validate") { + return Self::new(values, nulls); + } + Self { values, nulls } + } + /// Create a new [`BooleanArray`] with length `len` consisting only of nulls pub fn new_null(len: usize) -> Self { Self { diff --git a/arrow-array/src/array/fixed_size_binary_array.rs b/arrow-array/src/array/fixed_size_binary_array.rs index 85e5d266c908..b53c001a895b 100644 --- a/arrow-array/src/array/fixed_size_binary_array.rs +++ b/arrow-array/src/array/fixed_size_binary_array.rs @@ -118,6 +118,30 @@ impl FixedSizeBinaryArray { Self::try_new(value_length, values, nulls).unwrap() } + /// Create a new [`FixedSizeBinaryArray`] from the provided parts without validation. + /// + /// # Safety + /// - `value_length >= 0` + /// - `values.len() == len * value_length as usize` + /// - `nulls.len() == len` if `nulls` is `Some` + pub unsafe fn new_unchecked( + value_length: i32, + values: Buffer, + nulls: Option, + len: usize, + ) -> Self { + if cfg!(feature = "force_validate") { + return Self::try_new_with_len(value_length, values, nulls, len).unwrap(); + } + Self { + data_type: DataType::FixedSizeBinary(value_length), + value_data: values, + value_size: value_length as usize, + nulls, + len, + } + } + /// Create a new [`Scalar`] from `value` pub fn new_scalar(value: impl AsRef<[u8]>) -> Scalar { let v = value.as_ref(); diff --git a/arrow-array/src/array/fixed_size_list_array.rs b/arrow-array/src/array/fixed_size_list_array.rs index 01ccafd9cc57..797fedbc71bf 100644 --- a/arrow-array/src/array/fixed_size_list_array.rs +++ b/arrow-array/src/array/fixed_size_list_array.rs @@ -142,6 +142,32 @@ impl FixedSizeListArray { Self::try_new(field, size, values, nulls).unwrap() } + /// Create a new [`FixedSizeListArray`] from the provided parts without validation. + /// + /// # Safety + /// - `size >= 0` + /// - `values.len() == len * size as usize` + /// - `nulls.len() == len` if `nulls` is `Some` + /// - `field.data_type() == values.data_type()` + pub unsafe fn new_unchecked( + field: FieldRef, + size: i32, + values: ArrayRef, + nulls: Option, + len: usize, + ) -> Self { + if cfg!(feature = "force_validate") { + return Self::try_new_with_length(field, size, values, nulls, len).unwrap(); + } + Self { + data_type: DataType::FixedSizeList(field, size), + values, + value_length: size, + nulls, + len, + } + } + /// Create a new [`FixedSizeListArray`] from the provided parts, returning an error on failure. /// /// Note that if `size == 0` and `nulls` is `None` (a degenerate, non-nullable diff --git a/arrow-array/src/array/list_array.rs b/arrow-array/src/array/list_array.rs index f74ff7d3f364..4ae2b5668c94 100644 --- a/arrow-array/src/array/list_array.rs +++ b/arrow-array/src/array/list_array.rs @@ -272,6 +272,29 @@ impl GenericListArray { Self::try_new(field, offsets, values, nulls).unwrap() } + /// Create a new [`GenericListArray`] from the provided parts without validation. + /// + /// # Safety + /// - `offsets.len() - 1 == nulls.len()` if `nulls` is `Some` + /// - `offsets.last() <= values.len()` + /// - `field.data_type() == values.data_type()` + pub unsafe fn new_unchecked( + field: FieldRef, + offsets: OffsetBuffer, + values: ArrayRef, + nulls: Option, + ) -> Self { + if cfg!(feature = "force_validate") { + return Self::new(field, offsets, values, nulls); + } + Self { + data_type: Self::DATA_TYPE_CONSTRUCTOR(field), + nulls, + values, + value_offsets: offsets, + } + } + /// Create a new [`GenericListArray`] of length `len` where all values are null pub fn new_null(field: FieldRef, len: usize) -> Self { let values = new_empty_array(field.data_type()); diff --git a/arrow-array/src/array/map_array.rs b/arrow-array/src/array/map_array.rs index e51c90fca6d0..f244ddf2b8ce 100644 --- a/arrow-array/src/array/map_array.rs +++ b/arrow-array/src/array/map_array.rs @@ -146,6 +146,31 @@ impl MapArray { Self::try_new(field, offsets, entries, nulls, ordered).unwrap() } + /// Create a new [`MapArray`] from the provided parts without validation. + /// + /// # Safety + /// - `offsets.len() - 1 == nulls.len()` if `nulls` is `Some` + /// - `offsets.last() <= entries.len()` + /// - `entries` has exactly 2 columns and its keys column is non-nullable + /// - `field.data_type() == entries.data_type()` + pub unsafe fn new_unchecked( + field: FieldRef, + offsets: OffsetBuffer, + entries: StructArray, + nulls: Option, + ordered: bool, + ) -> Self { + if cfg!(feature = "force_validate") { + return Self::new(field, offsets, entries, nulls, ordered); + } + Self { + data_type: DataType::Map(field, ordered), + nulls, + entries, + value_offsets: offsets, + } + } + /// Deconstruct this array into its constituent parts pub fn into_parts( self, diff --git a/arrow-array/src/array/primitive_array.rs b/arrow-array/src/array/primitive_array.rs index 667f816c6b4d..8946af2b74be 100644 --- a/arrow-array/src/array/primitive_array.rs +++ b/arrow-array/src/array/primitive_array.rs @@ -636,6 +636,24 @@ impl PrimitiveArray { Self::try_new(values, nulls).unwrap() } + /// Create a new [`PrimitiveArray`] from the provided values and nulls without validation. + /// + /// # Safety + /// - `values.len() == nulls.len()` if `nulls` is `Some` + pub unsafe fn new_unchecked( + values: ScalarBuffer, + nulls: Option, + ) -> Self { + if cfg!(feature = "force_validate") { + return Self::new(values, nulls); + } + Self { + data_type: T::DATA_TYPE, + values, + nulls, + } + } + /// Create a new [`PrimitiveArray`] of the given length where all values are null pub fn new_null(length: usize) -> Self { Self {