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;