This is an automated email from the ASF dual-hosted git repository.
Jefffrey pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/arrow-rs.git
The following commit(s) were added to refs/heads/main by this push:
new 9161d1be2a replace MutableBuffer callsites with fallible methods
(#10641)
9161d1be2a is described below
commit 9161d1be2ac2043b4de1861953427d96307276d3
Author: RIchard Baah <[email protected]>
AuthorDate: Fri Aug 14 04:13:48 2026 -0400
replace MutableBuffer callsites with fallible methods (#10641)
# Which issue does this PR close?
<!--
We generally require a GitHub issue to be filed for all bug fixes and
enhancements and this helps us generate change logs for our releases.
You can link an issue to this PR using the GitHub syntax.
-->
- Closes https://github.com/apache/arrow-rs/issues/9843.
- works off of #10317
# Rationale for this change
it is better to return an error and let down stream users decide how to
proceed than to panic.
<!--
Why are you proposing this change? If this is already explained clearly
in the issue then this section is not needed.
Explaining clearly why changes are proposed helps reviewers understand
your changes and offer better suggestions for fixes.
-->
# What changes are included in this PR?
updates all call sites in the project to use the fallible alternative to
`mutableBuffer` methods.
<!--
There is no need to duplicate the description in the issue here but it
is sometimes worth providing a summary of the individual changes in this
PR.
-->
# Are these changes tested?
n/a behavior hasn't changed
<!--
We typically require tests for all PRs in order to:
1. Prevent the code from being accidentally broken by subsequent changes
2. Serve as another way to document the expected behavior of the code
If tests are not included in your PR, please explain why (for example,
are they covered by existing tests)?
If this PR claims a performance improvement, please include evidence
such as benchmark results.
-->
# Are there any user-facing changes?
no public methods we changed in this PR
<!--
If there are user-facing changes then we may require documentation to be
updated before approving the PR.
If there are any breaking changes to public APIs, please call them out.
-->
---
arrow-array/src/array/fixed_size_binary_array.rs | 24 ++++--
arrow-data/src/transform/fixed_binary.rs | 4 +-
arrow-data/src/transform/mod.rs | 4 +-
arrow-data/src/transform/primitive.rs | 5 +-
arrow-data/src/transform/run.rs | 3 +-
arrow-data/src/transform/union.rs | 10 ++-
arrow-data/src/transform/utils.rs | 4 +-
arrow-ipc/src/reader.rs | 9 +-
arrow-ipc/src/reader/stream.rs | 8 +-
arrow-ord/src/comparison.rs | 6 +-
arrow-select/src/zip.rs | 104 ++++++++++++++---------
arrow-string/src/concat_elements.rs | 8 +-
arrow-string/src/substring.rs | 12 ++-
13 files changed, 135 insertions(+), 66 deletions(-)
diff --git a/arrow-array/src/array/fixed_size_binary_array.rs
b/arrow-array/src/array/fixed_size_binary_array.rs
index ba43ffdc90..52ee02f0bd 100644
--- a/arrow-array/src/array/fixed_size_binary_array.rs
+++ b/arrow-array/src/array/fixed_size_binary_array.rs
@@ -463,7 +463,9 @@ impl FixedSizeBinaryArray {
// sufficient capacity in the underlying mutable buffer for
// the data.
if let Some(capacity) = iter_size_hint.checked_mul(len) {
- buffer.reserve(capacity);
+ buffer
+ .try_reserve(capacity)
+ .map_err(|e|
ArrowError::MemoryError(e.to_string()))?;
}
let prepend_zeros =
slice.len().checked_mul(prepend).ok_or_else(|| {
ArrowError::InvalidArgumentError(format!(
@@ -471,12 +473,18 @@ impl FixedSizeBinaryArray {
slice.len()
))
})?;
- buffer.extend_zeros(prepend_zeros);
+ buffer
+ .try_extend_zeros(prepend_zeros)
+ .map_err(|e| ArrowError::MemoryError(e.to_string()))?;
}
bit_util::set_bit(null_buf.as_slice_mut(), len);
- buffer.extend_from_slice(slice);
+ buffer
+ .try_extend_from_slice(slice)
+ .map_err(|e| ArrowError::MemoryError(e.to_string()))?;
} else if let Some(size) = value_size {
- buffer.extend_zeros(size);
+ buffer
+ .try_extend_zeros(size)
+ .map_err(|e| ArrowError::MemoryError(e.to_string()))?;
} else {
prepend += 1;
}
@@ -638,11 +646,15 @@ impl FixedSizeBinaryArray {
let len = slice.len();
value_size = Some(len);
if let Some(capacity) = iter_size_hint.checked_mul(len) {
- buffer.reserve(capacity);
+ buffer
+ .try_reserve(capacity)
+ .map_err(|e| ArrowError::MemoryError(e.to_string()))?;
}
}
- buffer.extend_from_slice(slice);
+ buffer
+ .try_extend_from_slice(slice)
+ .map_err(|e| ArrowError::MemoryError(e.to_string()))?;
len += 1;
diff --git a/arrow-data/src/transform/fixed_binary.rs
b/arrow-data/src/transform/fixed_binary.rs
index ce0008d27d..3d0dfa8c1e 100644
--- a/arrow-data/src/transform/fixed_binary.rs
+++ b/arrow-data/src/transform/fixed_binary.rs
@@ -38,6 +38,8 @@ pub(super) fn extend_nulls(
let size = get_fixed_size_binary_width(&mutable.data_type);
let values_buffer = &mut mutable.buffer1;
- values_buffer.extend_zeros(len * size);
+ values_buffer
+ .try_extend_zeros(len * size)
+ .map_err(|e| arrow_schema::ArrowError::MemoryError(e.to_string()))?;
Ok(())
}
diff --git a/arrow-data/src/transform/mod.rs b/arrow-data/src/transform/mod.rs
index 59b5948475..7145463ac4 100644
--- a/arrow-data/src/transform/mod.rs
+++ b/arrow-data/src/transform/mod.rs
@@ -789,7 +789,9 @@ impl<'a> MutableArrayData<'a> {
self.data.len += len;
let bit_len = bit_util::ceil(self.data.len, 8);
let nulls = self.data.null_buffer();
- nulls.resize(bit_len, 0);
+ nulls
+ .try_resize(bit_len, 0)
+ .map_err(|e| ArrowError::MemoryError(e.to_string()))?;
self.data.null_count += len;
(self.extend_nulls)(&mut self.data, len)?;
Ok(())
diff --git a/arrow-data/src/transform/primitive.rs
b/arrow-data/src/transform/primitive.rs
index b4846fa617..540ac25ccd 100644
--- a/arrow-data/src/transform/primitive.rs
+++ b/arrow-data/src/transform/primitive.rs
@@ -53,6 +53,9 @@ pub(super) fn extend_nulls<T: ArrowNativeType>(
mutable: &mut _MutableArrayData,
len: usize,
) -> Result<(), arrow_schema::ArrowError> {
- mutable.buffer1.extend_zeros(len * size_of::<T>());
+ mutable
+ .buffer1
+ .try_extend_zeros(len * size_of::<T>())
+ .map_err(|e| arrow_schema::ArrowError::MemoryError(e.to_string()))?;
Ok(())
}
diff --git a/arrow-data/src/transform/run.rs b/arrow-data/src/transform/run.rs
index 3678db16e0..2167790cc1 100644
--- a/arrow-data/src/transform/run.rs
+++ b/arrow-data/src/transform/run.rs
@@ -70,7 +70,8 @@ pub fn extend_nulls(mutable: &mut _MutableArrayData, len:
usize) -> Result<(), A
mutable.child_data[0]
.data
.buffer1
- .extend_from_slice(new_value.to_byte_slice());
+ .try_extend_from_slice(new_value.to_byte_slice())
+ .map_err(|e| ArrowError::MemoryError(e.to_string()))?;
}};
}
diff --git a/arrow-data/src/transform/union.rs
b/arrow-data/src/transform/union.rs
index ba7015f7a9..5c4d1b9313 100644
--- a/arrow-data/src/transform/union.rs
+++ b/arrow-data/src/transform/union.rs
@@ -84,7 +84,10 @@ pub(super) fn extend_nulls_dense(
.0;
// Extend type_ids buffer
- mutable.buffer1.extend_from_slice(&vec![first_type_id; len]);
+ mutable
+ .buffer1
+ .try_extend_from_slice(&vec![first_type_id; len])
+ .map_err(|e| ArrowError::MemoryError(e.to_string()))?;
// Dense: extend offsets pointing into the first child, then extend nulls
in that child
let child_offset = mutable.child_data[0].len();
@@ -108,7 +111,10 @@ pub(super) fn extend_nulls_sparse(
.0;
// Extend type_ids buffer
- mutable.buffer1.extend_from_slice(&vec![first_type_id; len]);
+ mutable
+ .buffer1
+ .try_extend_from_slice(&vec![first_type_id; len])
+ .map_err(|e| ArrowError::MemoryError(e.to_string()))?;
// Sparse: extend nulls in ALL children
for child in mutable.child_data.iter_mut() {
diff --git a/arrow-data/src/transform/utils.rs
b/arrow-data/src/transform/utils.rs
index 294ed94eb7..0424e25c87 100644
--- a/arrow-data/src/transform/utils.rs
+++ b/arrow-data/src/transform/utils.rs
@@ -35,7 +35,9 @@ pub(super) fn try_extend_offsets<T: ArrowNativeType + Integer
+ CheckedAdd>(
mut last_offset: T,
offsets: &[T],
) -> Result<(), ArrowError> {
- buffer.reserve(std::mem::size_of_val(offsets));
+ buffer
+ .try_reserve(std::mem::size_of_val(offsets))
+ .map_err(|e| ArrowError::MemoryError(e.to_string()))?;
// Snapshot the length so we can roll back partial writes on overflow.
let original_len = buffer.len();
for window in offsets.windows(2) {
diff --git a/arrow-ipc/src/reader.rs b/arrow-ipc/src/reader.rs
index 748330aad4..99e7c89c9c 100644
--- a/arrow-ipc/src/reader.rs
+++ b/arrow-ipc/src/reader.rs
@@ -920,7 +920,8 @@ fn read_block<R: Read + Seek>(mut reader: R, block: &Block)
-> Result<Buffer, Ar
let metadata_len = block.metaDataLength().to_usize().unwrap();
let total_len = body_len.checked_add(metadata_len).unwrap();
- let mut buf = MutableBuffer::from_len_zeroed(total_len);
+ let mut buf = MutableBuffer::try_from_len_zeroed(total_len)
+ .map_err(|e| ArrowError::MemoryError(e.to_string()))?;
reader.read_exact(&mut buf)?;
Ok(buf.into())
}
@@ -1825,14 +1826,16 @@ const MAX_PREALLOC_BYTES: usize = 64 * 1024 * 1024;
/// Reads exactly `len` bytes of message body, without reserving `len` before
reading it.
fn read_body_bounded<R: Read>(reader: &mut R, len: usize) ->
Result<MutableBuffer, ArrowError> {
- let mut buf = MutableBuffer::from_len_zeroed(len.min(MAX_PREALLOC_BYTES));
+ let mut buf =
MutableBuffer::try_from_len_zeroed(len.min(MAX_PREALLOC_BYTES))
+ .map_err(|e| ArrowError::MemoryError(e.to_string()))?;
let mut filled = 0;
while filled < len {
let target = buf.len();
reader.read_exact(&mut buf.as_slice_mut()[filled..target])?;
filled = target;
if filled < len {
- buf.resize(len.min(target.saturating_mul(2)), 0);
+ buf.try_resize(len.min(target.saturating_mul(2)), 0)
+ .map_err(|e| ArrowError::MemoryError(e.to_string()))?;
}
}
Ok(buf)
diff --git a/arrow-ipc/src/reader/stream.rs b/arrow-ipc/src/reader/stream.rs
index f136b6b69d..10c45745ca 100644
--- a/arrow-ipc/src/reader/stream.rs
+++ b/arrow-ipc/src/reader/stream.rs
@@ -194,7 +194,9 @@ impl StreamDecoder {
}
let to_read = buffer.len().min(len - self.buf.len());
- self.buf.extend_from_slice(&buffer[..to_read]);
+ self.buf
+ .try_extend_from_slice(&buffer[..to_read])
+ .map_err(|e| ArrowError::MemoryError(e.to_string()))?;
buffer.advance(to_read);
if self.buf.len() == len {
let message =
MessageBuffer::try_new(std::mem::take(&mut self.buf).into())?;
@@ -211,7 +213,9 @@ impl StreamDecoder {
body
} else {
let to_read = buffer.len().min(body_length -
self.buf.len());
- self.buf.extend_from_slice(&buffer[..to_read]);
+ self.buf
+ .try_extend_from_slice(&buffer[..to_read])
+ .map_err(|e|
ArrowError::MemoryError(e.to_string()))?;
buffer.advance(to_read);
if self.buf.len() != body_length {
diff --git a/arrow-ord/src/comparison.rs b/arrow-ord/src/comparison.rs
index 07f40be55e..823be32207 100644
--- a/arrow-ord/src/comparison.rs
+++ b/arrow-ord/src/comparison.rs
@@ -48,7 +48,8 @@ where
let num_bytes = bit_util::ceil(left_len, 8);
let nulls = NullBuffer::union(left.nulls(), right.nulls());
- let mut bool_buf = MutableBuffer::from_len_zeroed(num_bytes);
+ let mut bool_buf = MutableBuffer::try_from_len_zeroed(num_bytes)
+ .map_err(|e| ArrowError::MemoryError(e.to_string()))?;
let bool_slice = bool_buf.as_slice_mut();
// if both array slots are valid, check if list contains primitive
@@ -88,7 +89,8 @@ where
let num_bytes = bit_util::ceil(left_len, 8);
let nulls = NullBuffer::union(left.nulls(), right.nulls());
- let mut bool_buf = MutableBuffer::from_len_zeroed(num_bytes);
+ let mut bool_buf = MutableBuffer::try_from_len_zeroed(num_bytes)
+ .map_err(|e| ArrowError::MemoryError(e.to_string()))?;
let bool_slice = &mut bool_buf;
for i in 0..left_len {
diff --git a/arrow-select/src/zip.rs b/arrow-select/src/zip.rs
index 97ecab5a81..14a3dd60a4 100644
--- a/arrow-select/src/zip.rs
+++ b/arrow-select/src/zip.rs
@@ -473,10 +473,11 @@ impl<T: ByteArrayType> BytesScalarImpl<T> {
/// return an output array that has
/// `value` in all locations where predicate is true
/// `null` otherwise
+ #[expect(clippy::type_complexity)]
fn get_scalar_and_null_buffer_for_single_non_nullable(
predicate: BooleanBuffer,
value: &[u8],
- ) -> (Buffer, OffsetBuffer<T::Offset>, Option<NullBuffer>) {
+ ) -> Result<(Buffer, OffsetBuffer<T::Offset>, Option<NullBuffer>),
ArrowError> {
let value_length = value.len();
let number_of_true = predicate.count_set_bits();
@@ -486,13 +487,13 @@ impl<T: ByteArrayType> BytesScalarImpl<T> {
// All values are null
let nulls = NullBuffer::new_null(predicate.len());
- return (
+ return Ok((
// Empty bytes
Buffer::from(&[]),
// All nulls so all lengths are 0
OffsetBuffer::<T::Offset>::new_zeroed(predicate.len()),
Some(nulls),
- );
+ ));
}
let offsets = OffsetBuffer::<T::Offset>::from_lengths(
@@ -500,7 +501,9 @@ impl<T: ByteArrayType> BytesScalarImpl<T> {
);
let mut bytes = MutableBuffer::with_capacity(0);
- bytes.repeat_slice_n_times(value, number_of_true);
+ bytes
+ .try_repeat_slice_n_times(value, number_of_true)
+ .map_err(|e| ArrowError::MemoryError(e.to_string()))?;
let bytes = Buffer::from(bytes);
@@ -508,7 +511,7 @@ impl<T: ByteArrayType> BytesScalarImpl<T> {
// If a value is false we need the FALSY and the null buffer will have
0 (meaning null)
let nulls = NullBuffer::new(predicate);
- (bytes, offsets, Some(nulls))
+ Ok((bytes, offsets, Some(nulls)))
}
/// Create a [`Buffer`] where `value` slice is repeated `number_of_values`
times
@@ -516,41 +519,36 @@ impl<T: ByteArrayType> BytesScalarImpl<T> {
fn get_bytes_and_offset_for_all_same_value(
number_of_values: usize,
value: &[u8],
- ) -> (Buffer, OffsetBuffer<T::Offset>) {
+ ) -> Result<(Buffer, OffsetBuffer<T::Offset>), ArrowError> {
let value_length = value.len();
let offsets =
OffsetBuffer::<T::Offset>::from_repeated_length(value_length,
number_of_values);
let mut bytes = MutableBuffer::with_capacity(0);
- bytes.repeat_slice_n_times(value, number_of_values);
+ bytes
+ .try_repeat_slice_n_times(value, number_of_values)
+ .map_err(|e| ArrowError::MemoryError(e.to_string()))?;
let bytes = Buffer::from(bytes);
- (bytes, offsets)
+ Ok((bytes, offsets))
}
fn create_output_on_non_nulls(
predicate: &BooleanBuffer,
truthy_val: &[u8],
falsy_val: &[u8],
- ) -> (Buffer, OffsetBuffer<<T as ByteArrayType>::Offset>) {
+ ) -> Result<(Buffer, OffsetBuffer<<T as ByteArrayType>::Offset>),
ArrowError> {
let true_count = predicate.count_set_bits();
match true_count {
0 => {
// All values are falsy
-
- let (bytes, offsets) =
-
Self::get_bytes_and_offset_for_all_same_value(predicate.len(), falsy_val);
-
- return (bytes, offsets);
+ return
Self::get_bytes_and_offset_for_all_same_value(predicate.len(), falsy_val);
}
n if n == predicate.len() => {
// All values are truthy
- let (bytes, offsets) =
-
Self::get_bytes_and_offset_for_all_same_value(predicate.len(), truthy_val);
-
- return (bytes, offsets);
+ return
Self::get_bytes_and_offset_for_all_same_value(predicate.len(), truthy_val);
}
_ => {
@@ -569,12 +567,14 @@ impl<T: ByteArrayType> BytesScalarImpl<T> {
let truthy_len = truthy_val.len();
let falsy_len = falsy_val.len();
- SlicesIterator::from(predicate).for_each(|(start, end)| {
+ SlicesIterator::from(predicate).try_for_each(|(start, end)| ->
Result<(), ArrowError> {
// the gap needs to be filled with falsy values
if start > filled {
let false_repeat_count = start - filled;
// Push false value `repeat_count` times
- mutable.repeat_slice_n_times(falsy_val, false_repeat_count);
+ mutable
+ .try_repeat_slice_n_times(falsy_val, false_repeat_count)
+ .map_err(|e| ArrowError::MemoryError(e.to_string()))?;
for _ in 0..false_repeat_count {
offset_buffer_builder.push_length(falsy_len)
@@ -583,25 +583,30 @@ impl<T: ByteArrayType> BytesScalarImpl<T> {
let true_repeat_count = end - start;
// fill with truthy values
- mutable.repeat_slice_n_times(truthy_val, true_repeat_count);
+ mutable
+ .try_repeat_slice_n_times(truthy_val, true_repeat_count)
+ .map_err(|e| ArrowError::MemoryError(e.to_string()))?;
for _ in 0..true_repeat_count {
offset_buffer_builder.push_length(truthy_len)
}
filled = end;
- });
+ Ok(())
+ })?;
// the remaining part is falsy
if filled < predicate.len() {
let false_repeat_count = predicate.len() - filled;
// Copy the first item from the 'falsy' array into the output
buffer.
- mutable.repeat_slice_n_times(falsy_val, false_repeat_count);
+ mutable
+ .try_repeat_slice_n_times(falsy_val, false_repeat_count)
+ .map_err(|e| ArrowError::MemoryError(e.to_string()))?;
for _ in 0..false_repeat_count {
offset_buffer_builder.push_length(falsy_len)
}
}
- (mutable.into(), offset_buffer_builder.finish())
+ Ok((mutable.into(), offset_buffer_builder.finish()))
}
}
@@ -615,12 +620,12 @@ impl<T: ByteArrayType> ZipImpl for BytesScalarImpl<T> {
match (self.truthy.as_deref(), self.falsy.as_deref()) {
(Some(truthy_val), Some(falsy_val)) => {
let (bytes, offsets) =
- Self::create_output_on_non_nulls(&predicate,
truthy_val, falsy_val);
+ Self::create_output_on_non_nulls(&predicate,
truthy_val, falsy_val)?;
(bytes, offsets, None)
}
(Some(truthy_val), None) => {
-
Self::get_scalar_and_null_buffer_for_single_non_nullable(predicate, truthy_val)
+
Self::get_scalar_and_null_buffer_for_single_non_nullable(predicate, truthy_val)?
}
(None, Some(falsy_val)) => {
// Flipping the boolean buffer as we want the opposite of
the TRUE case
@@ -628,7 +633,7 @@ impl<T: ByteArrayType> ZipImpl for BytesScalarImpl<T> {
// if the condition is true we want null so we need to NOT
the value so we get 0 (meaning null)
// if the condition is false we want the FALSE value so we
need to NOT the value so we get 1 (meaning not null)
let predicate = predicate.not();
-
Self::get_scalar_and_null_buffer_for_single_non_nullable(predicate, falsy_val)
+
Self::get_scalar_and_null_buffer_for_single_non_nullable(predicate, falsy_val)?
}
(None, None) => {
// All values are null
@@ -725,6 +730,7 @@ impl<T: ByteViewType> ByteViewScalarImpl<T> {
(bytes.into(), buffers, Some(nulls))
}
+ #[expect(clippy::type_complexity)]
fn get_views_for_non_nullable(
predicate: BooleanBuffer,
result_len: usize,
@@ -732,16 +738,16 @@ impl<T: ByteViewType> ByteViewScalarImpl<T> {
truthy_buffers: Arc<[Buffer]>,
falsy_view: u128,
falsy_buffers: Arc<[Buffer]>,
- ) -> (ScalarBuffer<u128>, Arc<[Buffer]>, Option<NullBuffer>) {
+ ) -> Result<(ScalarBuffer<u128>, Arc<[Buffer]>, Option<NullBuffer>),
ArrowError> {
let true_count = predicate.count_set_bits();
match true_count {
0 => {
// all values are falsy
- (vec![falsy_view; result_len].into(), falsy_buffers, None)
+ Ok((vec![falsy_view; result_len].into(), falsy_buffers, None))
}
n if n == predicate.len() => {
// all values are truthy
- (vec![truthy_view; result_len].into(), truthy_buffers, None)
+ Ok((vec![truthy_view; result_len].into(), truthy_buffers,
None))
}
_ => {
let true_count = predicate.count_set_bits();
@@ -766,24 +772,38 @@ impl<T: ByteViewType> ByteViewScalarImpl<T> {
let mut mutable = MutableBuffer::new(total_number_of_bytes);
let mut filled = 0;
- SlicesIterator::from(&predicate).for_each(|(start, end)| {
- if start > filled {
- let false_repeat_count = start - filled;
+ SlicesIterator::from(&predicate).try_for_each(
+ |(start, end)| -> Result<(), ArrowError> {
+ if start > filled {
+ let false_repeat_count = start - filled;
+ mutable
+ .try_repeat_slice_n_times(
+ view_falsy.to_byte_slice(),
+ false_repeat_count,
+ )
+ .map_err(|e|
ArrowError::MemoryError(e.to_string()))?;
+ }
+ let true_repeat_count = end - start;
mutable
- .repeat_slice_n_times(view_falsy.to_byte_slice(),
false_repeat_count);
- }
- let true_repeat_count = end - start;
- mutable.repeat_slice_n_times(truthy_view.to_byte_slice(),
true_repeat_count);
- filled = end;
- });
+ .try_repeat_slice_n_times(
+ truthy_view.to_byte_slice(),
+ true_repeat_count,
+ )
+ .map_err(|e|
ArrowError::MemoryError(e.to_string()))?;
+ filled = end;
+ Ok(())
+ },
+ )?;
if filled < predicate.len() {
let false_repeat_count = predicate.len() - filled;
- mutable.repeat_slice_n_times(view_falsy.to_byte_slice(),
false_repeat_count);
+ mutable
+ .try_repeat_slice_n_times(view_falsy.to_byte_slice(),
false_repeat_count)
+ .map_err(|e| ArrowError::MemoryError(e.to_string()))?;
}
let bytes = Buffer::from(mutable);
- (bytes.into(), buffers.into(), None)
+ Ok((bytes.into(), buffers.into(), None))
}
}
}
@@ -812,7 +832,7 @@ impl<T: ByteViewType> ZipImpl for ByteViewScalarImpl<T> {
Arc::clone(&self.truthy_buffers),
falsy,
Arc::clone(&self.falsy_buffers),
- ),
+ )?,
(Some(truthy), None) => Self::get_views_for_single_non_nullable(
predicate,
truthy,
diff --git a/arrow-string/src/concat_elements.rs
b/arrow-string/src/concat_elements.rs
index cbba7fbec6..aa98af2954 100644
--- a/arrow-string/src/concat_elements.rs
+++ b/arrow-string/src/concat_elements.rs
@@ -212,8 +212,12 @@ pub fn concat_elements_fixed_size_binary(
result.append_null();
} else {
buffer.clear();
- buffer.extend_from_slice(left.value(i));
- buffer.extend_from_slice(right.value(i));
+ buffer
+ .try_extend_from_slice(left.value(i))
+ .map_err(|e| ArrowError::MemoryError(e.to_string()))?;
+ buffer
+ .try_extend_from_slice(right.value(i))
+ .map_err(|e| ArrowError::MemoryError(e.to_string()))?;
result.append_value(&buffer)?;
}
}
diff --git a/arrow-string/src/substring.rs b/arrow-string/src/substring.rs
index 66aece9d05..220663edba 100644
--- a/arrow-string/src/substring.rs
+++ b/arrow-string/src/substring.rs
@@ -381,7 +381,11 @@ where
let end = end.as_usize();
&data[start..end]
})
- .for_each(|slice| new_values.extend_from_slice(slice));
+ .try_for_each(|slice| {
+ new_values
+ .try_extend_from_slice(slice)
+ .map_err(|e| ArrowError::MemoryError(e.to_string()))
+ })?;
let offsets = OffsetBuffer::new(new_offsets.into());
let values = new_values.into();
@@ -426,7 +430,11 @@ fn fixed_size_binary_substring(
let offset = idx * array.value_size();
(offset + new_start, offset + new_start + new_len)
})
- .for_each(|(start, end)|
new_values.extend_from_slice(&data[start..end]));
+ .try_for_each(|(start, end)| {
+ new_values
+ .try_extend_from_slice(&data[start..end])
+ .map_err(|e| ArrowError::MemoryError(e.to_string()))
+ })?;
let mut nulls = array
.nulls()