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);
+}

Reply via email to