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

paleolimbot pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/arrow-nanoarrow.git


The following commit(s) were added to refs/heads/main by this push:
     new 7bf5d3c2 fix: relax validation for missing validity buffer when 
null_count is -1 (#942)
7bf5d3c2 is described below

commit 7bf5d3c24af8703457a93a1efea06722a09c37db
Author: Andre Sun <[email protected]>
AuthorDate: Tue Sep 15 15:09:29 2026 -0400

    fix: relax validation for missing validity buffer when null_count is -1 
(#942)
    
    Allow a missing validity buffer when the null count is unknown, matching
    Arrow C++’s import behavior. Arrays reporting a positive null count
    still
    require a validity buffer.
    
    Add regression coverage for unknown null counts with a missing validity
    buffer, including sliced arrays and positive-null-count rejection.
    
    Fixes #855
---
 src/nanoarrow/common/array.c       |  3 ++-
 src/nanoarrow/common/array_test.cc | 41 ++++++++++++++++++++++++++++++++++++++
 2 files changed, 43 insertions(+), 1 deletion(-)

diff --git a/src/nanoarrow/common/array.c b/src/nanoarrow/common/array.c
index 25b02c20..20daed5c 100644
--- a/src/nanoarrow/common/array.c
+++ b/src/nanoarrow/common/array.c
@@ -1612,7 +1612,8 @@ static int ArrowArrayViewValidateMinimal(struct 
ArrowArrayView* array_view,
 
     switch (array_view->layout.buffer_type[i]) {
       case NANOARROW_BUFFER_TYPE_VALIDITY:
-        if (array_view->null_count == 0 && 
array_view->buffer_views[i].size_bytes == 0) {
+        // Allow a missing validity buffer unless null_count > 0
+        if (array_view->null_count <= 0 && 
array_view->buffer_views[i].size_bytes == 0) {
           continue;
         }
 
diff --git a/src/nanoarrow/common/array_test.cc 
b/src/nanoarrow/common/array_test.cc
index 1b0d1290..520f6df9 100644
--- a/src/nanoarrow/common/array_test.cc
+++ b/src/nanoarrow/common/array_test.cc
@@ -2441,6 +2441,47 @@ TEST(ArrayTest, ArrayViewTestBasic) {
   ArrowArrayViewReset(&array_view);
 }
 
+TEST(ArrayTest, ArrayViewTestMissingValidityUnknownNullCount) {
+  struct ArrowError error;
+
+  // A missing validity buffer with null_count == -1 is valid
+  int32_t values[] = {11, 12, 13};
+  const void* buffers[] = {nullptr, values};
+
+  nanoarrow::UniqueArray array;
+  array->length = 2;
+  array->offset = 1;
+  array->null_count = -1;
+  array->n_buffers = 2;
+  array->n_children = 0;
+  array->buffers = buffers;
+  array->children = nullptr;
+  array->dictionary = nullptr;
+  array->release = [](struct ArrowArray*) {};
+
+  nanoarrow::UniqueArrayView array_view;
+  ArrowArrayViewInitFromType(array_view.get(), NANOARROW_TYPE_INT32);
+  ASSERT_EQ(ArrowArrayViewSetArray(array_view.get(), array.get(), &error), 
NANOARROW_OK)
+      << error.message;
+  EXPECT_EQ(
+      ArrowArrayViewValidate(array_view.get(), 
NANOARROW_VALIDATION_LEVEL_FULL, &error),
+      NANOARROW_OK)
+      << error.message;
+  EXPECT_EQ(ArrowArrayViewGetBufferView(array_view.get(), 0).size_bytes, 0);
+  EXPECT_EQ(ArrowArrayViewComputeNullCount(array_view.get()), 0);
+  EXPECT_EQ(ArrowArrayViewIsNull(array_view.get(), 0), 0);
+  EXPECT_EQ(ArrowArrayViewIsNull(array_view.get(), 1), 0);
+  EXPECT_EQ(ArrowArrayViewGetIntUnsafe(array_view.get(), 0), 12);
+  EXPECT_EQ(ArrowArrayViewGetIntUnsafe(array_view.get(), 1), 13);
+
+  // A missing validity buffer with null_count > 0 is still an error
+  array->null_count = 1;
+  EXPECT_EQ(ArrowArrayViewSetArray(array_view.get(), array.get(), &error), 
EINVAL);
+  EXPECT_STREQ(error.message,
+               "Expected int32 array buffer 0 to have size >= 1 bytes but 
found buffer "
+               "with 0 bytes");
+}
+
 TEST(ArrayTest, ArrayViewCompareTestStructure) {
   struct ArrowError error;
   struct ArrowArrayView actual;

Reply via email to