This is an automated email from the ASF dual-hosted git repository.

github-merge-queue[bot] pushed a commit to branch 
gh-readonly-queue/main/pr-11734-f7a72ebaa0386b93227e36f52171297391e49634
in repository https://gitbox.apache.org/repos/asf/arrow-rs.git

commit efb25a30d3deeaac40af73443a441d1a0252c129
Author: Tzu-Chiao Yeh <[email protected]>
AuthorDate: Tue Oct 27 02:37:13 2026 +0000

    fix(arrow-array): make `record_batch!` usable without a direct 
`arrow_schema` dependency (#11734)
    
    # Which issue does this PR close?
    
    None. This is a small, self-contained fix, so no issue was filed.
    
    # Rationale for this change
    
    `record_batch!` expands to `arrow_schema::*` paths, which resolve in the
    caller's crate. Users who depend only on the `arrow` umbrella crate and
    call `arrow::array::record_batch!` get:
    
    ```
    error[E0433]: cannot find module or crate `arrow_schema` in this scope
    ```
    
    and have to add `arrow_schema` as a direct dependency to use the macro,
    or work around it with `use arrow::datatypes as arrow_schema;`.
    
    # What changes are included in this PR?
    
    `record_batch!` now builds the batch with
    `RecordBatch::try_from_iter_with_nullable`, using `create_array!` for
    the columns.
    
    As a side effect, types supported by `create_array!` that are not unit
    `DataType` variants (e.g. `TimestampSecond`) now work in
    `record_batch!`; previously they failed to compile.
    
    # Are these changes tested?
    
    Added unit tests for the macro.
    
    The missing-dependency case itself can't be reproduced in-tree since
    workspace crates already depend on `arrow_schema`; I verified it with a
    standalone crate depending only on `arrow`.
    
    # Are there any significant user-facing changes?
    
    No breaking changes. `record_batch!` now works with only the `arrow`
    dependency and also accepts the additional types mentioned above.
    
    This change was written with help from an AI assistant (Claude Code). I
    have reviewed and understand all of it.
    
    Co-authored-by: RIchard Baah <[email protected]>
---
 arrow-array/src/record_batch.rs | 81 +++++++++++++++++++++++++++++++++--------
 1 file changed, 65 insertions(+), 16 deletions(-)

diff --git a/arrow-array/src/record_batch.rs b/arrow-array/src/record_batch.rs
index 78177a4d42..0933f61589 100644
--- a/arrow-array/src/record_batch.rs
+++ b/arrow-array/src/record_batch.rs
@@ -156,7 +156,6 @@ macro_rules! create_array {
 ///
 /// ```rust
 /// use arrow_array::record_batch;
-/// use arrow_schema;
 ///
 /// let batch = record_batch!(
 ///     ("a", Int32, [1, 2, 3]),
@@ -180,20 +179,13 @@ macro_rules! create_array {
 #[macro_export]
 macro_rules! record_batch {
     ($(($name: expr, $type: ident, $($values: tt)+)),*) => {
-        {
-            let schema = std::sync::Arc::new(arrow_schema::Schema::new(vec![
-                $(
-                    arrow_schema::Field::new($name, 
arrow_schema::DataType::$type, true),
-                )*
-            ]));
-
-            $crate::RecordBatch::try_new(
-                schema,
-                vec![$(
-                    $crate::create_array!($type, $($values)+),
-                )*]
-            )
-        }
+        $crate::RecordBatch::try_from_iter_with_nullable(vec![$(
+            (
+                ::std::string::String::from($name),
+                $crate::create_array!($type, $($values)+) as $crate::ArrayRef,
+                true,
+            ),
+        )*])
     };
 }
 
@@ -962,12 +954,13 @@ where
 #[cfg(test)]
 mod tests {
     use super::*;
+    use crate::types::{Int32Type, Int64Type};
     use crate::{
         BooleanArray, Int8Array, Int32Array, Int64Array, ListArray, 
StringArray, StringViewArray,
     };
     use arrow_buffer::{Buffer, NullBuffer, ToByteSlice};
     use arrow_data::{ArrayData, ArrayDataBuilder};
-    use arrow_schema::Fields;
+    use arrow_schema::{Fields, TimeUnit};
     use std::collections::HashMap;
 
     #[test]
@@ -1038,6 +1031,62 @@ mod tests {
         assert_eq!(b"xxx", large_binary.value(0));
     }
 
+    #[test]
+    fn create_record_batch_macro() {
+        let values = vec![7, 8, 9];
+        let name = String::from("c");
+
+        let record_batch = record_batch!(
+            ("a", Int32, [1, 2, 3]),
+            ("b", Utf8, [Some("x"), None, Some("z")]),
+            (name, Int64, values)
+        )
+        .unwrap();
+
+        let expected = Schema::new(vec![
+            Field::new("a", DataType::Int32, true),
+            Field::new("b", DataType::Utf8, true),
+            Field::new("c", DataType::Int64, true),
+        ]);
+        assert_eq!(&expected, record_batch.schema().as_ref());
+        assert_eq!(3, record_batch.num_rows());
+        assert_eq!(
+            &[1, 2, 3],
+            record_batch.column(0).as_primitive::<Int32Type>().values()
+        );
+        let b = record_batch.column(1).as_string::<i32>();
+        assert_eq!(
+            vec![Some("x"), None, Some("z")],
+            b.iter().collect::<Vec<_>>()
+        );
+        assert_eq!(
+            &[7, 8, 9],
+            record_batch.column(2).as_primitive::<Int64Type>().values()
+        );
+    }
+
+    #[test]
+    fn create_record_batch_macro_parameterized_types() {
+        let record_batch = record_batch!(
+            ("ts", TimestampSecond, [1, 2]),
+            ("d", Decimal128, [Some(100), None])
+        )
+        .unwrap();
+
+        let expected = Schema::new(vec![
+            Field::new("ts", DataType::Timestamp(TimeUnit::Second, None), 
true),
+            Field::new("d", DataType::Decimal128(38, 10), true),
+        ]);
+        assert_eq!(&expected, record_batch.schema().as_ref());
+        assert_eq!(1, record_batch.column(1).null_count());
+    }
+
+    #[test]
+    fn create_record_batch_macro_length_mismatch() {
+        let err = record_batch!(("a", Int32, [1, 2, 3]), ("b", Int32, [1, 
2])).unwrap_err();
+        assert!(matches!(err, ArrowError::InvalidArgumentError(_)));
+    }
+
     #[test]
     fn byte_size_should_not_regress() {
         let schema = Schema::new(vec![

Reply via email to