This is an automated email from the ASF dual-hosted git repository.
github-merge-queue[bot] 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 b5e7cad208 fix(arrow-data): extend Interval(DayTime) as
IntervalDayTime in MutableArrayData (#11906)
b5e7cad208 is described below
commit b5e7cad208f488cc7d4d50c795d2d180192cb37b
Author: NingLin Liu <[email protected]>
AuthorDate: Mon Oct 26 04:41:38 2026 +0000
fix(arrow-data): extend Interval(DayTime) as IntervalDayTime in
MutableArrayData (#11906)
# Which issue does this PR close?
- Closes #11862.
# Rationale for this change
`ArrayData::build` only requires an `Interval(DayTime)` values buffer to
be aligned to `align_of::<IntervalDayTime>()` (4 bytes, since it is a
`#[repr(C)]` struct of two `i32`s). `MutableArrayData` extended it as
`i64`, so `Buffer::typed_data::<i64>` asserted 8-byte alignment and
panicked on a valid, 4-byte aligned buffer. Every kernel built on
`MutableArrayData` (`zip`, `merge`, `concat` of some layouts, ...) hit
this. This is the `DayTime` counterpart of #5917, which #10171 fixed for
`MonthDayNano`.
# What changes are included in this PR?
`build_extend` and `build_extend_nulls` now use `IntervalDayTime` for
`Interval(DayTime)`, the same way `MonthDayNano` uses
`IntervalMonthDayNano`. The element size is unchanged (8 bytes), so the
produced buffers are identical; only the alignment requirement drops to
the one `ArrayData` already validates.
# Are these changes tested?
Yes. Added `test_interval_day_time_aligned_to_4` in
`arrow/tests/array_transform.rs`, which builds an `Interval(DayTime)`
array on a buffer starting at 4 mod 8, extends it and a null through
`MutableArrayData`, and checks the result. It panics at
`arrow-buffer/src/buffer/immutable.rs:334` without the change and passes
with it. `cargo test -p arrow --test array_transform`, `cargo test -p
arrow-data -p arrow-select` and `cargo clippy -p arrow-data
--all-targets -- -D warnings` pass.
# Are there any user-facing changes?
No API changes; kernels no longer panic on 4-byte aligned
`Interval(DayTime)` arrays.
This PR was prepared with AI assistance and reviewed/tested by the
author.
---
arrow-data/src/transform/mod.rs | 15 ++++++++++-----
arrow/tests/array_transform.rs | 26 ++++++++++++++++++++++++++
2 files changed, 36 insertions(+), 5 deletions(-)
diff --git a/arrow-data/src/transform/mod.rs b/arrow-data/src/transform/mod.rs
index c4cd2bee5b..cc6c20b2fd 100644
--- a/arrow-data/src/transform/mod.rs
+++ b/arrow-data/src/transform/mod.rs
@@ -23,7 +23,9 @@
use super::{ArrayData, ArrayDataBuilder, ByteView, data::new_buffers};
use crate::bit_mask::set_bits;
use arrow_buffer::buffer::{BooleanBuffer, NullBuffer};
-use arrow_buffer::{ArrowNativeType, Buffer, IntervalMonthDayNano,
MutableBuffer, bit_util, i256};
+use arrow_buffer::{
+ ArrowNativeType, Buffer, IntervalDayTime, IntervalMonthDayNano,
MutableBuffer, bit_util, i256,
+};
use arrow_schema::{ArrowError, DataType, IntervalUnit, UnionMode};
use half::f16;
use num_integer::Integer;
@@ -259,8 +261,11 @@ fn build_extend(array: &ArrayData) -> Extend<'_> {
DataType::Date64
| DataType::Time64(_)
| DataType::Timestamp(_, _)
- | DataType::Duration(_)
- | DataType::Interval(IntervalUnit::DayTime) =>
primitive::build_extend::<i64>(array),
+ | DataType::Duration(_) => primitive::build_extend::<i64>(array),
+ // `IntervalDayTime` is two `i32`s, so its buffers need only be 4-byte
aligned
+ DataType::Interval(IntervalUnit::DayTime) => {
+ primitive::build_extend::<IntervalDayTime>(array)
+ }
DataType::Interval(IntervalUnit::MonthDayNano) => {
primitive::build_extend::<IntervalMonthDayNano>(array)
}
@@ -308,8 +313,8 @@ fn build_extend_nulls(data_type: &DataType) -> ExtendNulls {
DataType::Date64
| DataType::Time64(_)
| DataType::Timestamp(_, _)
- | DataType::Duration(_)
- | DataType::Interval(IntervalUnit::DayTime) =>
primitive::extend_nulls::<i64>,
+ | DataType::Duration(_) => primitive::extend_nulls::<i64>,
+ DataType::Interval(IntervalUnit::DayTime) =>
primitive::extend_nulls::<IntervalDayTime>,
DataType::Interval(IntervalUnit::MonthDayNano) => {
primitive::extend_nulls::<IntervalMonthDayNano>
}
diff --git a/arrow/tests/array_transform.rs b/arrow/tests/array_transform.rs
index ff005b8630..287fa684a3 100644
--- a/arrow/tests/array_transform.rs
+++ b/arrow/tests/array_transform.rs
@@ -1292,3 +1292,29 @@ fn test_interval_month_day_nano_aligned_to_8() {
// roundtripping through arraydata shouldnt panic
MutableArrayData::new(vec![&b], false, 0);
}
+
+#[test]
+fn test_interval_day_time_aligned_to_4() {
+ let ty = DataType::Interval(arrow_schema::IntervalUnit::DayTime);
+
+ // `IntervalDayTime` only requires 4-byte alignment, so this slice is valid
+ // even though it does not start on an 8-byte boundary
+ let buffer = Buffer::from_slice_ref([0i32, 1, 2, 3, 4]).slice(4);
+ let b = ArrayData::builder(ty)
+ .len(2)
+ .add_buffer(buffer)
+ .build()
+ .unwrap();
+
+ let mut mutable = MutableArrayData::new(vec![&b], true, 3);
+ mutable.try_extend(0, 0, 2).unwrap();
+ mutable.try_extend_nulls(1).unwrap();
+ let result = &arrow_array::IntervalDayTimeArray::from(mutable.freeze());
+
+ let expected = arrow_array::IntervalDayTimeArray::from(vec![
+ Some(arrow_buffer::IntervalDayTime::new(1, 2)),
+ Some(arrow_buffer::IntervalDayTime::new(3, 4)),
+ None,
+ ]);
+ assert_eq!(result, &expected);
+}