You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@arrow.apache.org by tu...@apache.org on 2022/12/08 16:50:19 UTC

[arrow-rs] branch master updated: Skip null buffer when importing FFI ArrowArray struct if no null buffer in the spec (#3293)

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

tustvold pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/arrow-rs.git


The following commit(s) were added to refs/heads/master by this push:
     new 7d2139749 Skip null buffer when importing FFI ArrowArray struct if no null buffer in the spec (#3293)
7d2139749 is described below

commit 7d2139749029f78b1d88eddf24be664071e12686
Author: Liang-Chi Hsieh <vi...@gmail.com>
AuthorDate: Thu Dec 8 08:50:13 2022 -0800

    Skip null buffer when importing FFI ArrowArray struct if no null buffer in the spec (#3293)
    
    * Fix null buffer import/export behavior
    
    * Clippy
    
    Co-authored-by: Raphael Taylor-Davies <r....@googlemail.com>
---
 arrow/src/ffi.rs | 38 ++++++++++++++++++++++++++------------
 1 file changed, 26 insertions(+), 12 deletions(-)

diff --git a/arrow/src/ffi.rs b/arrow/src/ffi.rs
index 0c1c1fa54..abb53dff6 100644
--- a/arrow/src/ffi.rs
+++ b/arrow/src/ffi.rs
@@ -462,12 +462,18 @@ impl FFI_ArrowArray {
     /// This method releases `buffers`. Consumers of this struct *must* call `release` before
     /// releasing this struct, or contents in `buffers` leak.
     pub fn new(data: &ArrayData) -> Self {
-        // * insert the null buffer at the start
-        // * make all others `Option<Buffer>`.
-        let buffers = iter::once(data.null_buffer().cloned())
-            .chain(data.buffers().iter().map(|b| Some(b.clone())))
-            .collect::<Vec<_>>();
         let data_layout = layout(data.data_type());
+
+        let buffers = if data_layout.can_contain_null_mask {
+            // * insert the null buffer at the start
+            // * make all others `Option<Buffer>`.
+            iter::once(data.null_buffer().cloned())
+                .chain(data.buffers().iter().map(|b| Some(b.clone())))
+                .collect::<Vec<_>>()
+        } else {
+            data.buffers().iter().map(|b| Some(b.clone())).collect()
+        };
+
         // `n_buffers` is the number of buffers by the spec.
         let n_buffers = {
             data_layout.buffers.len() + {
@@ -616,8 +622,15 @@ pub trait ArrowArrayRef {
         let len = self.array().len();
         let offset = self.array().offset();
         let null_count = self.array().null_count();
-        let buffers = self.buffers()?;
-        let null_bit_buffer = self.null_bit_buffer();
+
+        let data_layout = layout(&data_type);
+        let buffers = self.buffers(data_layout.can_contain_null_mask)?;
+
+        let null_bit_buffer = if data_layout.can_contain_null_mask {
+            self.null_bit_buffer()
+        } else {
+            None
+        };
 
         let mut child_data: Vec<ArrayData> = (0..self.array().n_children as usize)
             .map(|i| {
@@ -649,11 +662,12 @@ pub trait ArrowArrayRef {
     }
 
     /// returns all buffers, as organized by Rust (i.e. null buffer is skipped)
-    fn buffers(&self) -> Result<Vec<Buffer>> {
-        (0..self.array().n_buffers - 1)
+    fn buffers(&self, can_contain_null_mask: bool) -> Result<Vec<Buffer>> {
+        // + 1: skip null buffer
+        let buffer_begin = can_contain_null_mask as i64;
+        (buffer_begin..self.array().n_buffers)
             .map(|index| {
-                // + 1: skip null buffer
-                let index = (index + 1) as usize;
+                let index = index as usize;
 
                 let len = self.buffer_len(index)?;
 
@@ -668,7 +682,7 @@ pub trait ArrowArrayRef {
                     }
                     None => Err(ArrowError::CDataInterface(format!(
                         "The external buffer at position {} is null.",
-                        index - 1
+                        index
                     ))),
                 }
             })