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

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


The following commit(s) were added to refs/heads/main by this push:
     new 593199dbd chore(c/vendor): Update vendored nanoarrow to 0.7.0 (#2930)
593199dbd is described below

commit 593199dbd64ac43d22782d26d684c9ef54a6e97f
Author: Dewey Dunnington <[email protected]>
AuthorDate: Mon Jul 21 18:45:11 2025 -0500

    chore(c/vendor): Update vendored nanoarrow to 0.7.0 (#2930)
    
    Updates nanoarrow to the latest version.
---
 c/vendor/nanoarrow/nanoarrow.c   | 251 +++++++++++++++++++--
 c/vendor/nanoarrow/nanoarrow.h   | 447 ++++++++++++++++++++++++------------
 c/vendor/nanoarrow/nanoarrow.hpp | 473 +++++++++++++++++++++++++++------------
 c/vendor/vendor_nanoarrow.sh     |   2 +-
 4 files changed, 862 insertions(+), 311 deletions(-)

diff --git a/c/vendor/nanoarrow/nanoarrow.c b/c/vendor/nanoarrow/nanoarrow.c
index 8f2659881..80b79eee5 100644
--- a/c/vendor/nanoarrow/nanoarrow.c
+++ b/c/vendor/nanoarrow/nanoarrow.c
@@ -111,6 +111,7 @@ void ArrowLayoutInit(struct ArrowLayout* layout, enum 
ArrowType storage_type) {
     case NANOARROW_TYPE_UINT32:
     case NANOARROW_TYPE_INT32:
     case NANOARROW_TYPE_FLOAT:
+    case NANOARROW_TYPE_DECIMAL32:
       layout->element_size_bits[1] = 32;
       break;
     case NANOARROW_TYPE_INTERVAL_MONTHS:
@@ -122,6 +123,7 @@ void ArrowLayoutInit(struct ArrowLayout* layout, enum 
ArrowType storage_type) {
     case NANOARROW_TYPE_INT64:
     case NANOARROW_TYPE_DOUBLE:
     case NANOARROW_TYPE_INTERVAL_DAY_TIME:
+    case NANOARROW_TYPE_DECIMAL64:
       layout->element_size_bits[1] = 64;
       break;
 
@@ -188,6 +190,24 @@ void ArrowLayoutInit(struct ArrowLayout* layout, enum 
ArrowType storage_type) {
       layout->buffer_type[1] = NANOARROW_BUFFER_TYPE_DATA;
       layout->buffer_data_type[1] = NANOARROW_TYPE_STRING_VIEW;
       layout->element_size_bits[1] = 128;
+      break;
+
+    case NANOARROW_TYPE_LIST_VIEW:
+      layout->buffer_type[1] = NANOARROW_BUFFER_TYPE_VIEW_OFFSET;
+      layout->buffer_data_type[1] = NANOARROW_TYPE_INT32;
+      layout->element_size_bits[1] = 32;
+      layout->buffer_type[2] = NANOARROW_BUFFER_TYPE_SIZE;
+      layout->buffer_data_type[2] = NANOARROW_TYPE_INT32;
+      layout->element_size_bits[2] = 32;
+      break;
+    case NANOARROW_TYPE_LARGE_LIST_VIEW:
+      layout->buffer_type[1] = NANOARROW_BUFFER_TYPE_VIEW_OFFSET;
+      layout->buffer_data_type[1] = NANOARROW_TYPE_INT64;
+      layout->element_size_bits[1] = 64;
+      layout->buffer_type[2] = NANOARROW_BUFFER_TYPE_SIZE;
+      layout->buffer_data_type[2] = NANOARROW_TYPE_INT64;
+      layout->element_size_bits[2] = 64;
+      break;
 
     default:
       break;
@@ -326,13 +346,14 @@ ArrowErrorCode ArrowDecimalSetDigits(struct ArrowDecimal* 
decimal,
 
   // Use 32-bit words for portability
   uint32_t words32[8];
-  int n_words32 = decimal->n_words * 2;
+  memset(words32, 0, sizeof(words32));
+  int n_words32 = decimal->n_words > 0 ? decimal->n_words * 2 : 1;
   NANOARROW_DCHECK(n_words32 <= 8);
   memset(words32, 0, sizeof(words32));
 
   ShiftAndAdd(value, words32, n_words32);
 
-  if (decimal->low_word_index == 0) {
+  if (_ArrowIsLittleEndian() || n_words32 == 1) {
     memcpy(decimal->words, words32, sizeof(uint32_t) * n_words32);
   } else {
     uint64_t lo;
@@ -356,11 +377,31 @@ ArrowErrorCode ArrowDecimalSetDigits(struct ArrowDecimal* 
decimal,
 // 
https://github.com/apache/arrow/blob/cd3321b28b0c9703e5d7105d6146c1270bbadd7f/cpp/src/arrow/util/decimal.cc#L365
 ArrowErrorCode ArrowDecimalAppendDigitsToBuffer(const struct ArrowDecimal* 
decimal,
                                                 struct ArrowBuffer* buffer) {
-  NANOARROW_DCHECK(decimal->n_words == 2 || decimal->n_words == 4);
+  NANOARROW_DCHECK(decimal->n_words == 0 || decimal->n_words == 1 ||
+                   decimal->n_words == 2 || decimal->n_words == 4);
+
+  // For the 32-bit case, just use snprintf()
+  if (decimal->n_words == 0) {
+    int32_t value;
+    memcpy(&value, decimal->words, sizeof(int32_t));
+    NANOARROW_RETURN_NOT_OK(ArrowBufferReserve(buffer, 16));
+    int n_chars = snprintf((char*)buffer->data + buffer->size_bytes,
+                           (buffer->capacity_bytes - buffer->size_bytes), 
"%d", value);
+    if (n_chars <= 0) {
+      return EINVAL;
+    }
+
+    buffer->size_bytes += n_chars;
+    return NANOARROW_OK;
+  }
+
   int is_negative = ArrowDecimalSign(decimal) < 0;
 
   uint64_t words_little_endian[4];
-  if (decimal->low_word_index == 0) {
+  if (decimal->n_words == 0) {
+    words_little_endian[0] = 0;
+    memcpy(words_little_endian, decimal->words, sizeof(uint32_t));
+  } else if (decimal->low_word_index == 0) {
     memcpy(words_little_endian, decimal->words, decimal->n_words * 
sizeof(uint64_t));
   } else {
     for (int i = 0; i < decimal->n_words; i++) {
@@ -370,21 +411,33 @@ ArrowErrorCode ArrowDecimalAppendDigitsToBuffer(const 
struct ArrowDecimal* decim
 
   // We've already made a copy, so negate that if needed
   if (is_negative) {
-    uint64_t carry = 1;
-    for (int i = 0; i < decimal->n_words; i++) {
-      uint64_t elem = words_little_endian[i];
-      elem = ~elem + carry;
-      carry &= (elem == 0);
-      words_little_endian[i] = elem;
+    if (decimal->n_words == 0) {
+      uint32_t elem = (uint32_t)words_little_endian[0];
+      elem = ~elem + 1;
+      words_little_endian[0] = (int32_t)elem;
+    } else {
+      uint64_t carry = 1;
+      for (int i = 0; i < decimal->n_words; i++) {
+        uint64_t elem = words_little_endian[i];
+        elem = ~elem + carry;
+        carry &= (elem == 0);
+        words_little_endian[i] = elem;
+      }
     }
   }
 
   // Find the most significant word that is non-zero
   int most_significant_elem_idx = -1;
-  for (int i = decimal->n_words - 1; i >= 0; i--) {
-    if (words_little_endian[i] != 0) {
-      most_significant_elem_idx = i;
-      break;
+  if (decimal->n_words == 0) {
+    if (words_little_endian[0] != 0) {
+      most_significant_elem_idx = 0;
+    }
+  } else {
+    for (int i = decimal->n_words - 1; i >= 0; i--) {
+      if (words_little_endian[i] != 0) {
+        most_significant_elem_idx = i;
+        break;
+      }
     }
   }
 
@@ -462,6 +515,50 @@ ArrowErrorCode ArrowDecimalAppendDigitsToBuffer(const 
struct ArrowDecimal* decim
 
   return NANOARROW_OK;
 }
+
+ArrowErrorCode ArrowDecimalAppendStringToBuffer(const struct ArrowDecimal* 
decimal,
+                                                struct ArrowBuffer* buffer) {
+  int64_t buffer_size = buffer->size_bytes;
+  NANOARROW_RETURN_NOT_OK(ArrowDecimalAppendDigitsToBuffer(decimal, buffer));
+  int64_t digits_size = buffer->size_bytes - buffer_size;
+
+  if (decimal->scale <= 0) {
+    // e.g., digits are -12345 and scale is -2 -> -1234500
+    // Just add zeros to the end
+    for (int i = decimal->scale; i < 0; i++) {
+      NANOARROW_RETURN_NOT_OK(ArrowBufferAppendInt8(buffer, '0'));
+    }
+    return NANOARROW_OK;
+  }
+
+  int is_negative = buffer->data[0] == '-';
+  int64_t num_digits = digits_size - is_negative;
+  if (num_digits <= decimal->scale) {
+    // e.g., digits are -12345 and scale is 6 -> -0.012345
+    // Insert "0.<some zeros>" between the (maybe) negative sign and the digits
+    int64_t num_zeros_after_decimal = decimal->scale - num_digits;
+    NANOARROW_RETURN_NOT_OK(
+        ArrowBufferResize(buffer, buffer->size_bytes + num_zeros_after_decimal 
+ 2, 0));
+
+    uint8_t* digits_start = buffer->data + is_negative;
+    memmove(digits_start + num_zeros_after_decimal + 2, digits_start, 
num_digits);
+    *digits_start++ = '0';
+    *digits_start++ = '.';
+    for (int i = 0; i < num_zeros_after_decimal; i++) {
+      *digits_start++ = '0';
+    }
+
+  } else {
+    // e.g., digits are -12345 and scale is 4 -> -1.2345
+    // Insert a decimal point before scale digits of output
+    NANOARROW_RETURN_NOT_OK(ArrowBufferResize(buffer, buffer->size_bytes + 1, 
0));
+    uint8_t* decimal_point_to_be = buffer->data + buffer->size_bytes - 1 - 
decimal->scale;
+    memmove(decimal_point_to_be + 1, decimal_point_to_be, decimal->scale);
+    *decimal_point_to_be = '.';
+  }
+
+  return NANOARROW_OK;
+}
 // Licensed to the Apache Software Foundation (ASF) under one
 // or more contributor license agreements.  See the NOTICE file
 // distributed with this work for additional information
@@ -589,6 +686,10 @@ static const char* ArrowSchemaFormatTemplate(enum 
ArrowType type) {
       return "+l";
     case NANOARROW_TYPE_LARGE_LIST:
       return "+L";
+    case NANOARROW_TYPE_LIST_VIEW:
+      return "+vl";
+    case NANOARROW_TYPE_LARGE_LIST_VIEW:
+      return "+vL";
     case NANOARROW_TYPE_STRUCT:
       return "+s";
     case NANOARROW_TYPE_MAP:
@@ -607,6 +708,8 @@ static int ArrowSchemaInitChildrenIfNeeded(struct 
ArrowSchema* schema,
     case NANOARROW_TYPE_LIST:
     case NANOARROW_TYPE_LARGE_LIST:
     case NANOARROW_TYPE_FIXED_SIZE_LIST:
+    case NANOARROW_TYPE_LIST_VIEW:
+    case NANOARROW_TYPE_LARGE_LIST_VIEW:
       NANOARROW_RETURN_NOT_OK(ArrowSchemaAllocateChildren(schema, 1));
       ArrowSchemaInit(schema->children[0]);
       NANOARROW_RETURN_NOT_OK(ArrowSchemaSetName(schema->children[0], "item"));
@@ -735,11 +838,35 @@ ArrowErrorCode ArrowSchemaSetTypeDecimal(struct 
ArrowSchema* schema, enum ArrowT
   char buffer[64];
   int n_chars;
   switch (type) {
+    case NANOARROW_TYPE_DECIMAL32:
+      if (decimal_precision > 9) {
+        return EINVAL;
+      }
+
+      n_chars = snprintf(buffer, sizeof(buffer), "d:%d,%d,32", 
decimal_precision,
+                         decimal_scale);
+      break;
+    case NANOARROW_TYPE_DECIMAL64:
+      if (decimal_precision > 18) {
+        return EINVAL;
+      }
+
+      n_chars = snprintf(buffer, sizeof(buffer), "d:%d,%d,64", 
decimal_precision,
+                         decimal_scale);
+      break;
     case NANOARROW_TYPE_DECIMAL128:
+      if (decimal_precision > 38) {
+        return EINVAL;
+      }
+
       n_chars =
           snprintf(buffer, sizeof(buffer), "d:%d,%d", decimal_precision, 
decimal_scale);
       break;
     case NANOARROW_TYPE_DECIMAL256:
+      if (decimal_precision > 76) {
+        return EINVAL;
+      }
+
       n_chars = snprintf(buffer, sizeof(buffer), "d:%d,%d,256", 
decimal_precision,
                          decimal_scale);
       break;
@@ -1185,6 +1312,12 @@ static ArrowErrorCode ArrowSchemaViewParse(struct 
ArrowSchemaView* schema_view,
       *format_end_out = parse_end;
 
       switch (schema_view->decimal_bitwidth) {
+        case 32:
+          ArrowSchemaViewSetPrimitive(schema_view, NANOARROW_TYPE_DECIMAL32);
+          return NANOARROW_OK;
+        case 64:
+          ArrowSchemaViewSetPrimitive(schema_view, NANOARROW_TYPE_DECIMAL64);
+          return NANOARROW_OK;
         case 128:
           ArrowSchemaViewSetPrimitive(schema_view, NANOARROW_TYPE_DECIMAL128);
           return NANOARROW_OK;
@@ -1321,6 +1454,24 @@ static ArrowErrorCode ArrowSchemaViewParse(struct 
ArrowSchemaView* schema_view,
             return EINVAL;
           }
 
+        // views
+        case 'v':
+          switch (format[2]) {
+            case 'l':
+              schema_view->storage_type = NANOARROW_TYPE_LIST_VIEW;
+              schema_view->type = NANOARROW_TYPE_LIST_VIEW;
+              *format_end_out = format + 3;
+              return NANOARROW_OK;
+            case 'L':
+              schema_view->storage_type = NANOARROW_TYPE_LARGE_LIST_VIEW;
+              schema_view->type = NANOARROW_TYPE_LARGE_LIST_VIEW;
+              *format_end_out = format + 3;
+              return NANOARROW_OK;
+            default:
+              ArrowErrorSet(
+                  error, "Expected view format string +vl or +vL but found 
'%s'", format);
+              return EINVAL;
+          }
         default:
           ArrowErrorSet(error, "Expected nested type format string but found 
'%s'",
                         format);
@@ -1621,6 +1772,8 @@ static ArrowErrorCode ArrowSchemaViewValidate(struct 
ArrowSchemaView* schema_vie
     case NANOARROW_TYPE_HALF_FLOAT:
     case NANOARROW_TYPE_FLOAT:
     case NANOARROW_TYPE_DOUBLE:
+    case NANOARROW_TYPE_DECIMAL32:
+    case NANOARROW_TYPE_DECIMAL64:
     case NANOARROW_TYPE_DECIMAL128:
     case NANOARROW_TYPE_DECIMAL256:
     case NANOARROW_TYPE_STRING:
@@ -1649,7 +1802,9 @@ static ArrowErrorCode ArrowSchemaViewValidate(struct 
ArrowSchemaView* schema_vie
       return ArrowSchemaViewValidateNChildren(schema_view, 0, error);
 
     case NANOARROW_TYPE_LIST:
+    case NANOARROW_TYPE_LIST_VIEW:
     case NANOARROW_TYPE_LARGE_LIST:
+    case NANOARROW_TYPE_LARGE_LIST_VIEW:
     case NANOARROW_TYPE_FIXED_SIZE_LIST:
       return ArrowSchemaViewValidateNChildren(schema_view, 1, error);
 
@@ -1759,7 +1914,7 @@ ArrowErrorCode ArrowSchemaViewInit(struct 
ArrowSchemaView* schema_view,
 
   ArrowLayoutInit(&schema_view->layout, schema_view->storage_type);
   if (schema_view->storage_type == NANOARROW_TYPE_FIXED_SIZE_BINARY) {
-    schema_view->layout.element_size_bits[1] = schema_view->fixed_size * 8;
+    schema_view->layout.element_size_bits[1] = 
(int64_t)schema_view->fixed_size * 8;
   } else if (schema_view->storage_type == NANOARROW_TYPE_FIXED_SIZE_LIST) {
     schema_view->layout.child_size_elements = schema_view->fixed_size;
   }
@@ -1780,6 +1935,8 @@ static int64_t ArrowSchemaTypeToStringInternal(struct 
ArrowSchemaView* schema_vi
                                                char* out, int64_t n) {
   const char* type_string = ArrowTypeString(schema_view->type);
   switch (schema_view->type) {
+    case NANOARROW_TYPE_DECIMAL32:
+    case NANOARROW_TYPE_DECIMAL64:
     case NANOARROW_TYPE_DECIMAL128:
     case NANOARROW_TYPE_DECIMAL256:
       return snprintf(out, n, "%s(%" PRId32 ", %" PRId32 ")", type_string,
@@ -2237,6 +2394,8 @@ static ArrowErrorCode ArrowArraySetStorageType(struct 
ArrowArray* array,
     case NANOARROW_TYPE_HALF_FLOAT:
     case NANOARROW_TYPE_FLOAT:
     case NANOARROW_TYPE_DOUBLE:
+    case NANOARROW_TYPE_DECIMAL32:
+    case NANOARROW_TYPE_DECIMAL64:
     case NANOARROW_TYPE_DECIMAL128:
     case NANOARROW_TYPE_DECIMAL256:
     case NANOARROW_TYPE_INTERVAL_MONTHS:
@@ -2254,6 +2413,8 @@ static ArrowErrorCode ArrowArraySetStorageType(struct 
ArrowArray* array,
     case NANOARROW_TYPE_LARGE_STRING:
     case NANOARROW_TYPE_BINARY:
     case NANOARROW_TYPE_LARGE_BINARY:
+    case NANOARROW_TYPE_LIST_VIEW:
+    case NANOARROW_TYPE_LARGE_LIST_VIEW:
       array->n_buffers = 3;
       break;
 
@@ -2300,6 +2461,7 @@ ArrowErrorCode ArrowArrayInitFromType(struct ArrowArray* 
array,
   private_data->n_variadic_buffers = 0;
   private_data->variadic_buffers = NULL;
   private_data->variadic_buffer_sizes = NULL;
+  private_data->list_view_offset = 0;
 
   array->private_data = private_data;
   array->buffers = (const void**)(private_data->buffer_data);
@@ -2831,6 +2993,8 @@ void ArrowArrayViewSetLength(struct ArrowArrayView* 
array_view, int64_t length)
         continue;
       case NANOARROW_BUFFER_TYPE_TYPE_ID:
       case NANOARROW_BUFFER_TYPE_UNION_OFFSET:
+      case NANOARROW_BUFFER_TYPE_VIEW_OFFSET:
+      case NANOARROW_BUFFER_TYPE_SIZE:
         array_view->buffer_views[i].size_bytes = element_size_bytes * length;
         continue;
       case NANOARROW_BUFFER_TYPE_VARIADIC_DATA:
@@ -2987,12 +3151,19 @@ static int ArrowArrayViewValidateMinimal(struct 
ArrowArrayView* array_view,
 
         min_buffer_size_bytes = _ArrowBytesForBits(offset_plus_length);
         break;
+      case NANOARROW_BUFFER_TYPE_SIZE:
+        min_buffer_size_bytes = element_size_bytes * offset_plus_length;
+        break;
       case NANOARROW_BUFFER_TYPE_DATA_OFFSET:
         // Probably don't want/need to rely on the producer to have allocated 
an
         // offsets buffer of length 1 for a zero-size array
         min_buffer_size_bytes =
             (offset_plus_length != 0) * element_size_bytes * 
(offset_plus_length + 1);
         break;
+      case NANOARROW_BUFFER_TYPE_VIEW_OFFSET:
+        min_buffer_size_bytes =
+            (offset_plus_length != 0) * element_size_bytes * 
offset_plus_length;
+        break;
       case NANOARROW_BUFFER_TYPE_DATA:
         min_buffer_size_bytes =
             _ArrowRoundUpToMultipleOf8(array_view->layout.element_size_bits[i] 
*
@@ -3029,6 +3200,8 @@ static int ArrowArrayViewValidateMinimal(struct 
ArrowArrayView* array_view,
     case NANOARROW_TYPE_LARGE_LIST:
     case NANOARROW_TYPE_FIXED_SIZE_LIST:
     case NANOARROW_TYPE_MAP:
+    case NANOARROW_TYPE_LIST_VIEW:
+    case NANOARROW_TYPE_LARGE_LIST_VIEW:
       if (array_view->n_children != 1) {
         ArrowErrorSet(error,
                       "Expected 1 child of %s array but found %" PRId64 " 
child arrays",
@@ -3308,10 +3481,11 @@ static int ArrowArrayViewValidateDefault(struct 
ArrowArrayView* array_view,
 
         if (array_view->children[0]->length < last_offset) {
           ArrowErrorSet(error,
-                        "Expected child of large list array to have length >= 
%" PRId64
+                        "Expected child of %s array to have length >= %" PRId64
                         " but found array "
                         "with length %" PRId64,
-                        last_offset, array_view->children[0]->length);
+                        ArrowTypeString(array_view->storage_type), last_offset,
+                        array_view->children[0]->length);
           return EINVAL;
         }
       }
@@ -3554,12 +3728,53 @@ static int ArrowArrayViewValidateFull(struct 
ArrowArrayView* array_view,
     }
   }
 
+  if (array_view->storage_type == NANOARROW_TYPE_LIST_VIEW ||
+      array_view->storage_type == NANOARROW_TYPE_LARGE_LIST_VIEW) {
+    int64_t child_len = array_view->children[0]->length;
+
+    struct ArrowBufferView offsets, sizes;
+    offsets.data.data = array_view->buffer_views[1].data.data;
+    sizes.data.data = array_view->buffer_views[2].data.data;
+
+    for (int64_t i = array_view->offset; i < array_view->length + 
array_view->offset;
+         i++) {
+      int64_t offset, size;
+      if (array_view->storage_type == NANOARROW_TYPE_LIST_VIEW) {
+        offset = offsets.data.as_int32[i];
+        size = sizes.data.as_int32[i];
+      } else {
+        offset = offsets.data.as_int64[i];
+        size = sizes.data.as_int64[i];
+      }
+
+      if (offset < 0) {
+        ArrowErrorSet(error, "Invalid negative offset %" PRId64 " at index %" 
PRId64,
+                      offset, i);
+        return EINVAL;
+      }
+
+      if (size < 0) {
+        ArrowErrorSet(error, "Invalid negative size %" PRId64 " at index %" 
PRId64, size,
+                      i);
+        return EINVAL;
+      }
+
+      if ((offset + size) > child_len) {
+        ArrowErrorSet(error,
+                      "Offset: %" PRId64 " + size: %" PRId64 " at index: %" 
PRId64
+                      " exceeds length of child view: %" PRId64,
+                      offset, size, i, child_len);
+        return EINVAL;
+      }
+    }
+  }
+
   // Recurse for children
   for (int64_t i = 0; i < array_view->n_children; i++) {
     
NANOARROW_RETURN_NOT_OK(ArrowArrayViewValidateFull(array_view->children[i], 
error));
   }
 
-  // Dictionary valiation not implemented
+  // Dictionary validation not implemented
   if (array_view->dictionary != NULL) {
     NANOARROW_RETURN_NOT_OK(ArrowArrayViewValidateFull(array_view->dictionary, 
error));
     // TODO: validate the indices
diff --git a/c/vendor/nanoarrow/nanoarrow.h b/c/vendor/nanoarrow/nanoarrow.h
index 264aad5b6..1fcac16ac 100644
--- a/c/vendor/nanoarrow/nanoarrow.h
+++ b/c/vendor/nanoarrow/nanoarrow.h
@@ -15,13 +15,13 @@
 // specific language governing permissions and limitations
 // under the License.
 
-#ifndef NANOARROW_BUILD_ID_H_INCLUDED
-#define NANOARROW_BUILD_ID_H_INCLUDED
+#ifndef NANOARROW_CONFIG_H_INCLUDED
+#define NANOARROW_CONFIG_H_INCLUDED
 
 #define NANOARROW_VERSION_MAJOR 0
-#define NANOARROW_VERSION_MINOR 6
+#define NANOARROW_VERSION_MINOR 7
 #define NANOARROW_VERSION_PATCH 0
-#define NANOARROW_VERSION "0.6.0"
+#define NANOARROW_VERSION "0.7.0"
 
 #define NANOARROW_VERSION_INT                                        \
   (NANOARROW_VERSION_MAJOR * 10000 + NANOARROW_VERSION_MINOR * 100 + \
@@ -29,6 +29,13 @@
 
 #define NANOARROW_NAMESPACE Private
 
+#if !defined(NANOARROW_CXX_NAMESPACE)
+#define NANOARROW_CXX_NAMESPACE nanoarrow
+#endif
+
+#define NANOARROW_CXX_NAMESPACE_BEGIN namespace NANOARROW_CXX_NAMESPACE {
+#define NANOARROW_CXX_NAMESPACE_END }
+
 #endif
 // Licensed to the Apache Software Foundation (ASF) under one
 // or more contributor license agreements.  See the NOTICE file
@@ -181,14 +188,14 @@ struct ArrowArrayStream {
   NANOARROW_RETURN_NOT_OK((x_ <= max_) ? NANOARROW_OK : EINVAL)
 
 #if defined(NANOARROW_DEBUG)
-#define _NANOARROW_RETURN_NOT_OK_WITH_ERROR_IMPL(NAME, EXPR, ERROR_PTR_EXPR, 
EXPR_STR)  \
-  do {                                                                         
         \
-    const int NAME = (EXPR);                                                   
         \
-    if (NAME) {                                                                
         \
-      ArrowErrorSet((ERROR_PTR_EXPR), "%s failed with errno %d(%s)\n* %s:%d", 
EXPR_STR, \
-                    NAME, strerror(NAME), __FILE__, __LINE__);                 
         \
-      return NAME;                                                             
         \
-    }                                                                          
         \
+#define _NANOARROW_RETURN_NOT_OK_WITH_ERROR_IMPL(NAME, EXPR, ERROR_PTR_EXPR, 
EXPR_STR) \
+  do {                                                                         
        \
+    const int NAME = (EXPR);                                                   
        \
+    if (NAME) {                                                                
        \
+      ArrowErrorSet((ERROR_PTR_EXPR), "%s failed with errno %d\n* %s:%d", 
EXPR_STR,    \
+                    NAME, __FILE__, __LINE__);                                 
        \
+      return NAME;                                                             
        \
+    }                                                                          
        \
   } while (0)
 #else
 #define _NANOARROW_RETURN_NOT_OK_WITH_ERROR_IMPL(NAME, EXPR, ERROR_PTR_EXPR, 
EXPR_STR) \
@@ -485,7 +492,11 @@ enum ArrowType {
   NANOARROW_TYPE_INTERVAL_MONTH_DAY_NANO,
   NANOARROW_TYPE_RUN_END_ENCODED,
   NANOARROW_TYPE_BINARY_VIEW,
-  NANOARROW_TYPE_STRING_VIEW
+  NANOARROW_TYPE_STRING_VIEW,
+  NANOARROW_TYPE_DECIMAL32,
+  NANOARROW_TYPE_DECIMAL64,
+  NANOARROW_TYPE_LIST_VIEW,
+  NANOARROW_TYPE_LARGE_LIST_VIEW,
 };
 
 /// \brief Get a string value of an enum ArrowType value
@@ -542,6 +553,10 @@ static inline const char* ArrowTypeString(enum ArrowType 
type) {
       return "interval_months";
     case NANOARROW_TYPE_INTERVAL_DAY_TIME:
       return "interval_day_time";
+    case NANOARROW_TYPE_DECIMAL32:
+      return "decimal32";
+    case NANOARROW_TYPE_DECIMAL64:
+      return "decimal64";
     case NANOARROW_TYPE_DECIMAL128:
       return "decimal128";
     case NANOARROW_TYPE_DECIMAL256:
@@ -578,6 +593,10 @@ static inline const char* ArrowTypeString(enum ArrowType 
type) {
       return "binary_view";
     case NANOARROW_TYPE_STRING_VIEW:
       return "string_view";
+    case NANOARROW_TYPE_LIST_VIEW:
+      return "list_view";
+    case NANOARROW_TYPE_LARGE_LIST_VIEW:
+      return "large_list_view";
     default:
       return NULL;
   }
@@ -656,7 +675,9 @@ enum ArrowBufferType {
   NANOARROW_BUFFER_TYPE_DATA_OFFSET,
   NANOARROW_BUFFER_TYPE_DATA,
   NANOARROW_BUFFER_TYPE_VARIADIC_DATA,
-  NANOARROW_BUFFER_TYPE_VARIADIC_SIZE
+  NANOARROW_BUFFER_TYPE_VARIADIC_SIZE,
+  NANOARROW_BUFFER_TYPE_VIEW_OFFSET,
+  NANOARROW_BUFFER_TYPE_SIZE,
 };
 
 /// \brief The maximum number of fixed buffers in an ArrowArrayView or 
ArrowLayout
@@ -890,6 +911,9 @@ struct ArrowArrayPrivateData {
 
   // Size of each variadic buffer in bytes
   int64_t* variadic_buffer_sizes;
+
+  // The current offset used to build list views
+  int64_t list_view_offset;
 };
 
 /// \brief A representation of an interval.
@@ -922,7 +946,8 @@ static inline void ArrowIntervalInit(struct ArrowInterval* 
interval,
 /// values set using ArrowDecimalSetInt(), ArrowDecimalSetBytes128(),
 /// or ArrowDecimalSetBytes256().
 struct ArrowDecimal {
-  /// \brief An array of 64-bit integers of n_words length defined in 
native-endian order
+  /// \brief An array of 64-bit integers of n_words length defined in 
native-endian order.
+  /// For a 32-bit decimal value, index 0 will be a 32-bit integer value.
   uint64_t words[4];
 
   /// \brief The number of significant digits this decimal number can represent
@@ -931,7 +956,8 @@ struct ArrowDecimal {
   /// \brief The number of digits after the decimal point. This can be 
negative.
   int32_t scale;
 
-  /// \brief The number of words in the words array
+  /// \brief The number of 64-bit words in the words array. For the special 
case of a
+  /// 32-bit decimal value, this will be 0.
   int n_words;
 
   /// \brief Cached value used by the implementation
@@ -948,13 +974,14 @@ static inline void ArrowDecimalInit(struct ArrowDecimal* 
decimal, int32_t bitwid
   memset(decimal->words, 0, sizeof(decimal->words));
   decimal->precision = precision;
   decimal->scale = scale;
+  // n_words will be 0 for bitwidth == 32
   decimal->n_words = (int)(bitwidth / 8 / sizeof(uint64_t));
 
   if (_ArrowIsLittleEndian()) {
     decimal->low_word_index = 0;
-    decimal->high_word_index = decimal->n_words - 1;
+    decimal->high_word_index = decimal->n_words > 0 ? decimal->n_words - 1 : 0;
   } else {
-    decimal->low_word_index = decimal->n_words - 1;
+    decimal->low_word_index = decimal->n_words > 0 ? decimal->n_words - 1 : 0;
     decimal->high_word_index = 0;
   }
 }
@@ -965,6 +992,12 @@ static inline void ArrowDecimalInit(struct ArrowDecimal* 
decimal, int32_t bitwid
 /// within the signed 64-bit integer range (A precision less than or equal
 /// to 18 is sufficiently small).
 static inline int64_t ArrowDecimalGetIntUnsafe(const struct ArrowDecimal* 
decimal) {
+  if (decimal->n_words == 0) {
+    int32_t value;
+    memcpy(&value, decimal->words, sizeof(int32_t));
+    return value;
+  }
+
   return (int64_t)decimal->words[decimal->low_word_index];
 }
 
@@ -972,18 +1005,32 @@ static inline int64_t ArrowDecimalGetIntUnsafe(const 
struct ArrowDecimal* decima
 /// \ingroup nanoarrow-utils
 static inline void ArrowDecimalGetBytes(const struct ArrowDecimal* decimal,
                                         uint8_t* out) {
-  memcpy(out, decimal->words, decimal->n_words * sizeof(uint64_t));
+  if (decimal->n_words == 0) {
+    memcpy(out, decimal->words, sizeof(int32_t));
+  } else {
+    memcpy(out, decimal->words, decimal->n_words * sizeof(uint64_t));
+  }
 }
 
 /// \brief Returns 1 if the value represented by decimal is >= 0 or -1 
otherwise
 /// \ingroup nanoarrow-utils
 static inline int64_t ArrowDecimalSign(const struct ArrowDecimal* decimal) {
-  return 1 | ((int64_t)(decimal->words[decimal->high_word_index]) >> 63);
+  if (decimal->n_words == 0) {
+    return ArrowDecimalGetIntUnsafe(decimal) >= 0 ? 1 : -1;
+  } else {
+    return 1 | ((int64_t)(decimal->words[decimal->high_word_index]) >> 63);
+  }
 }
 
 /// \brief Sets the integer value of this decimal
 /// \ingroup nanoarrow-utils
 static inline void ArrowDecimalSetInt(struct ArrowDecimal* decimal, int64_t 
value) {
+  if (decimal->n_words == 0) {
+    int32_t value32 = (int32_t)value;
+    memcpy(decimal->words, &value32, sizeof(int32_t));
+    return;
+  }
+
   if (value < 0) {
     memset(decimal->words, 0xff, decimal->n_words * sizeof(uint64_t));
   } else {
@@ -996,6 +1043,14 @@ static inline void ArrowDecimalSetInt(struct 
ArrowDecimal* decimal, int64_t valu
 /// \brief Negate the value of this decimal in place
 /// \ingroup nanoarrow-utils
 static inline void ArrowDecimalNegate(struct ArrowDecimal* decimal) {
+  if (decimal->n_words == 0) {
+    int32_t value;
+    memcpy(&value, decimal->words, sizeof(int32_t));
+    value = -value;
+    memcpy(decimal->words, &value, sizeof(int32_t));
+    return;
+  }
+
   uint64_t carry = 1;
 
   if (decimal->low_word_index == 0) {
@@ -1019,7 +1074,11 @@ static inline void ArrowDecimalNegate(struct 
ArrowDecimal* decimal) {
 /// \ingroup nanoarrow-utils
 static inline void ArrowDecimalSetBytes(struct ArrowDecimal* decimal,
                                         const uint8_t* value) {
-  memcpy(decimal->words, value, decimal->n_words * sizeof(uint64_t));
+  if (decimal->n_words == 0) {
+    memcpy(decimal->words, value, sizeof(int32_t));
+  } else {
+    memcpy(decimal->words, value, decimal->n_words * sizeof(uint64_t));
+  }
 }
 
 #ifdef __cplusplus
@@ -1079,6 +1138,8 @@ static inline void ArrowDecimalSetBytes(struct 
ArrowDecimal* decimal,
 #define ArrowDecimalSetDigits NANOARROW_SYMBOL(NANOARROW_NAMESPACE, 
ArrowDecimalSetDigits)
 #define ArrowDecimalAppendDigitsToBuffer \
   NANOARROW_SYMBOL(NANOARROW_NAMESPACE, ArrowDecimalAppendDigitsToBuffer)
+#define ArrowDecimalAppendStringToBuffer \
+  NANOARROW_SYMBOL(NANOARROW_NAMESPACE, ArrowDecimalAppendStringToBuffer)
 #define ArrowSchemaInit NANOARROW_SYMBOL(NANOARROW_NAMESPACE, ArrowSchemaInit)
 #define ArrowSchemaInitFromType \
   NANOARROW_SYMBOL(NANOARROW_NAMESPACE, ArrowSchemaInitFromType)
@@ -1168,6 +1229,20 @@ static inline void ArrowDecimalSetBytes(struct 
ArrowDecimal* decimal,
 
 #endif
 
+#if (defined _WIN32 || defined __CYGWIN__) && defined(NANOARROW_BUILD_DLL)
+#if defined(NANOARROW_EXPORT_DLL)
+#define NANOARROW_DLL __declspec(dllexport)
+#else
+#define NANOARROW_DLL __declspec(dllimport)
+#endif  // defined(NANOARROW_EXPORT_DLL)
+#elif !defined(NANOARROW_DLL)
+#if defined(__GNUC__) && __GNUC__ >= 4
+#define NANOARROW_DLL __attribute__((visibility("default")))
+#else
+#define NANOARROW_DLL
+#endif  // __GNUC__ >= 4
+#endif
+
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -1191,19 +1266,19 @@ extern "C" {
 /// @{
 
 /// \brief Allocate like malloc()
-void* ArrowMalloc(int64_t size);
+NANOARROW_DLL void* ArrowMalloc(int64_t size);
 
 /// \brief Reallocate like realloc()
-void* ArrowRealloc(void* ptr, int64_t size);
+NANOARROW_DLL void* ArrowRealloc(void* ptr, int64_t size);
 
 /// \brief Free a pointer allocated using ArrowMalloc() or ArrowRealloc().
-void ArrowFree(void* ptr);
+NANOARROW_DLL void ArrowFree(void* ptr);
 
 /// \brief Return the default allocator
 ///
 /// The default allocator uses ArrowMalloc(), ArrowRealloc(), and
 /// ArrowFree().
-struct ArrowBufferAllocator ArrowBufferAllocatorDefault(void);
+NANOARROW_DLL struct ArrowBufferAllocator ArrowBufferAllocatorDefault(void);
 
 /// \brief Create a custom deallocator
 ///
@@ -1211,8 +1286,8 @@ struct ArrowBufferAllocator 
ArrowBufferAllocatorDefault(void);
 /// attach a custom deallocator to an ArrowBuffer. This may be used to
 /// avoid copying an existing buffer that was not allocated using the
 /// infrastructure provided here (e.g., by an R or Python object).
-struct ArrowBufferAllocator 
ArrowBufferDeallocator(ArrowBufferDeallocatorCallback,
-                                                   void* private_data);
+NANOARROW_DLL struct ArrowBufferAllocator ArrowBufferDeallocator(
+    ArrowBufferDeallocatorCallback, void* private_data);
 
 /// @}
 
@@ -1292,8 +1367,8 @@ static inline void ArrowArrayStreamRelease(struct 
ArrowArrayStream* array_stream
 /// \brief Set the contents of an error using printf syntax.
 ///
 /// If error is NULL, this function does nothing and returns NANOARROW_OK.
-NANOARROW_CHECK_PRINTF_ATTRIBUTE int ArrowErrorSet(struct ArrowError* error,
-                                                   const char* fmt, ...);
+NANOARROW_DLL NANOARROW_CHECK_PRINTF_ATTRIBUTE int ArrowErrorSet(struct 
ArrowError* error,
+                                                                 const char* 
fmt, ...);
 
 /// @}
 
@@ -1302,24 +1377,29 @@ NANOARROW_CHECK_PRINTF_ATTRIBUTE int 
ArrowErrorSet(struct ArrowError* error,
 /// @{
 
 /// \brief Return a version string in the form "major.minor.patch"
-const char* ArrowNanoarrowVersion(void);
+NANOARROW_DLL const char* ArrowNanoarrowVersion(void);
 
 /// \brief Return an integer that can be used to compare versions sequentially
-int ArrowNanoarrowVersionInt(void);
+NANOARROW_DLL int ArrowNanoarrowVersionInt(void);
 
 /// \brief Initialize a description of buffer arrangements from a storage type
-void ArrowLayoutInit(struct ArrowLayout* layout, enum ArrowType storage_type);
+NANOARROW_DLL void ArrowLayoutInit(struct ArrowLayout* layout,
+                                   enum ArrowType storage_type);
 
 /// \brief Create a string view from a null-terminated string
 static inline struct ArrowStringView ArrowCharView(const char* value);
 
 /// \brief Sets the integer value of an ArrowDecimal from a string
-ArrowErrorCode ArrowDecimalSetDigits(struct ArrowDecimal* decimal,
-                                     struct ArrowStringView value);
+NANOARROW_DLL ArrowErrorCode ArrowDecimalSetDigits(struct ArrowDecimal* 
decimal,
+                                                   struct ArrowStringView 
value);
 
 /// \brief Get the integer value of an ArrowDecimal as string
-ArrowErrorCode ArrowDecimalAppendDigitsToBuffer(const struct ArrowDecimal* 
decimal,
-                                                struct ArrowBuffer* buffer);
+NANOARROW_DLL ArrowErrorCode ArrowDecimalAppendDigitsToBuffer(
+    const struct ArrowDecimal* decimal, struct ArrowBuffer* buffer);
+
+/// \brief Get the decimal value of an ArrowDecimal as a string
+NANOARROW_DLL ArrowErrorCode ArrowDecimalAppendStringToBuffer(
+    const struct ArrowDecimal* decimal, struct ArrowBuffer* buffer);
 
 /// \brief Get the half float value of a float
 static inline uint16_t ArrowFloatToHalfFloat(float value);
@@ -1348,7 +1428,7 @@ static inline int64_t ArrowResolveChunk64(int64_t index, 
const int64_t* offsets,
 /// Initializes the fields and release callback of schema_out. Caller
 /// is responsible for calling the schema->release callback if
 /// NANOARROW_OK is returned.
-void ArrowSchemaInit(struct ArrowSchema* schema);
+NANOARROW_DLL void ArrowSchemaInit(struct ArrowSchema* schema);
 
 /// \brief Initialize an ArrowSchema from an ArrowType
 ///
@@ -1356,7 +1436,8 @@ void ArrowSchemaInit(struct ArrowSchema* schema);
 /// ArrowSchemaSetType() for the common case of constructing an
 /// unparameterized type. The caller is responsible for calling the 
schema->release
 /// callback if NANOARROW_OK is returned.
-ArrowErrorCode ArrowSchemaInitFromType(struct ArrowSchema* schema, enum 
ArrowType type);
+NANOARROW_DLL ArrowErrorCode ArrowSchemaInitFromType(struct ArrowSchema* 
schema,
+                                                     enum ArrowType type);
 
 /// \brief Get a human-readable summary of a Schema
 ///
@@ -1364,8 +1445,8 @@ ArrowErrorCode ArrowSchemaInitFromType(struct 
ArrowSchema* schema, enum ArrowTyp
 /// and returns the number of characters required for the output if
 /// n were sufficiently large. If recursive is non-zero, the result will
 /// also include children.
-int64_t ArrowSchemaToString(const struct ArrowSchema* schema, char* out, 
int64_t n,
-                            char recursive);
+NANOARROW_DLL int64_t ArrowSchemaToString(const struct ArrowSchema* schema, 
char* out,
+                                          int64_t n, char recursive);
 
 /// \brief Set the format field of a schema from an ArrowType
 ///
@@ -1375,14 +1456,16 @@ int64_t ArrowSchemaToString(const struct ArrowSchema* 
schema, char* out, int64_t
 /// allocated, initialized, and named; however, the caller must
 /// ArrowSchemaSetType() on the preinitialized children. Schema must have been 
initialized
 /// using ArrowSchemaInit() or ArrowSchemaDeepCopy().
-ArrowErrorCode ArrowSchemaSetType(struct ArrowSchema* schema, enum ArrowType 
type);
+NANOARROW_DLL ArrowErrorCode ArrowSchemaSetType(struct ArrowSchema* schema,
+                                                enum ArrowType type);
 
 /// \brief Set the format field and initialize children of a struct schema
 ///
 /// The specified number of children are initialized; however, the caller is 
responsible
 /// for calling ArrowSchemaSetType() and ArrowSchemaSetName() on each child.
 /// Schema must have been initialized using ArrowSchemaInit() or 
ArrowSchemaDeepCopy().
-ArrowErrorCode ArrowSchemaSetTypeStruct(struct ArrowSchema* schema, int64_t 
n_children);
+NANOARROW_DLL ArrowErrorCode ArrowSchemaSetTypeStruct(struct ArrowSchema* 
schema,
+                                                      int64_t n_children);
 
 /// \brief Set the format field of a fixed-size schema
 ///
@@ -1392,17 +1475,20 @@ ArrowErrorCode ArrowSchemaSetTypeStruct(struct 
ArrowSchema* schema, int64_t n_ch
 /// allocated, initialized, and named; however, the caller must
 /// ArrowSchemaSetType() the first child. Schema must have been initialized 
using
 /// ArrowSchemaInit() or ArrowSchemaDeepCopy().
-ArrowErrorCode ArrowSchemaSetTypeFixedSize(struct ArrowSchema* schema,
-                                           enum ArrowType type, int32_t 
fixed_size);
+NANOARROW_DLL ArrowErrorCode ArrowSchemaSetTypeFixedSize(struct ArrowSchema* 
schema,
+                                                         enum ArrowType type,
+                                                         int32_t fixed_size);
 
 /// \brief Set the format field of a decimal schema
 ///
 /// Returns EINVAL for scale <= 0 or for type that is not
-/// NANOARROW_TYPE_DECIMAL128 or NANOARROW_TYPE_DECIMAL256. Schema must have 
been
-/// initialized using ArrowSchemaInit() or ArrowSchemaDeepCopy().
-ArrowErrorCode ArrowSchemaSetTypeDecimal(struct ArrowSchema* schema, enum 
ArrowType type,
-                                         int32_t decimal_precision,
-                                         int32_t decimal_scale);
+/// NANOARROW_TYPE_DECIMAL32, NANOARROW_TYPE_DECIMAL64, 
NANOARROW_TYPE_DECIMAL128 or
+/// NANOARROW_TYPE_DECIMAL256. Schema must have been initialized using
+/// ArrowSchemaInit() or ArrowSchemaDeepCopy().
+NANOARROW_DLL ArrowErrorCode ArrowSchemaSetTypeDecimal(struct ArrowSchema* 
schema,
+                                                       enum ArrowType type,
+                                                       int32_t 
decimal_precision,
+                                                       int32_t decimal_scale);
 
 /// \brief Set the format field of a run-end encoded schema
 ///
@@ -1412,8 +1498,8 @@ ArrowErrorCode ArrowSchemaSetTypeDecimal(struct 
ArrowSchema* schema, enum ArrowT
 /// The caller must call `ArrowSchemaSetTypeXXX(schema->children[1])` to
 /// set the value type. Note that when building arrays using the 
`ArrowArrayAppendXXX()`
 /// functions, the run-end encoded array's logical length must be updated 
manually.
-ArrowErrorCode ArrowSchemaSetTypeRunEndEncoded(struct ArrowSchema* schema,
-                                               enum ArrowType run_end_type);
+NANOARROW_DLL ArrowErrorCode ArrowSchemaSetTypeRunEndEncoded(struct 
ArrowSchema* schema,
+                                                             enum ArrowType 
run_end_type);
 
 /// \brief Set the format field of a time, timestamp, or duration schema
 ///
@@ -1422,55 +1508,60 @@ ArrowErrorCode ArrowSchemaSetTypeRunEndEncoded(struct 
ArrowSchema* schema,
 /// NANOARROW_TYPE_TIMESTAMP, or NANOARROW_TYPE_DURATION. The
 /// timezone parameter must be NULL for a non-timestamp type. Schema must have 
been
 /// initialized using ArrowSchemaInit() or ArrowSchemaDeepCopy().
-ArrowErrorCode ArrowSchemaSetTypeDateTime(struct ArrowSchema* schema, enum 
ArrowType type,
-                                          enum ArrowTimeUnit time_unit,
-                                          const char* timezone);
+NANOARROW_DLL ArrowErrorCode ArrowSchemaSetTypeDateTime(struct ArrowSchema* 
schema,
+                                                        enum ArrowType type,
+                                                        enum ArrowTimeUnit 
time_unit,
+                                                        const char* timezone);
 
 /// \brief Set the format field of a union schema
 ///
 /// Returns EINVAL for a type that is not NANOARROW_TYPE_DENSE_UNION
 /// or NANOARROW_TYPE_SPARSE_UNION. The specified number of children are
 /// allocated, and initialized.
-ArrowErrorCode ArrowSchemaSetTypeUnion(struct ArrowSchema* schema, enum 
ArrowType type,
-                                       int64_t n_children);
+NANOARROW_DLL ArrowErrorCode ArrowSchemaSetTypeUnion(struct ArrowSchema* 
schema,
+                                                     enum ArrowType type,
+                                                     int64_t n_children);
 
 /// \brief Make a (recursive) copy of a schema
 ///
 /// Allocates and copies fields of schema into schema_out.
-ArrowErrorCode ArrowSchemaDeepCopy(const struct ArrowSchema* schema,
-                                   struct ArrowSchema* schema_out);
+NANOARROW_DLL ArrowErrorCode ArrowSchemaDeepCopy(const struct ArrowSchema* 
schema,
+                                                 struct ArrowSchema* 
schema_out);
 
 /// \brief Copy format into schema->format
 ///
 /// schema must have been allocated using ArrowSchemaInitFromType() or
 /// ArrowSchemaDeepCopy().
-ArrowErrorCode ArrowSchemaSetFormat(struct ArrowSchema* schema, const char* 
format);
+NANOARROW_DLL ArrowErrorCode ArrowSchemaSetFormat(struct ArrowSchema* schema,
+                                                  const char* format);
 
 /// \brief Copy name into schema->name
 ///
 /// schema must have been allocated using ArrowSchemaInitFromType() or
 /// ArrowSchemaDeepCopy().
-ArrowErrorCode ArrowSchemaSetName(struct ArrowSchema* schema, const char* 
name);
+NANOARROW_DLL ArrowErrorCode ArrowSchemaSetName(struct ArrowSchema* schema,
+                                                const char* name);
 
 /// \brief Copy metadata into schema->metadata
 ///
 /// schema must have been allocated using ArrowSchemaInitFromType() or
 /// ArrowSchemaDeepCopy.
-ArrowErrorCode ArrowSchemaSetMetadata(struct ArrowSchema* schema, const char* 
metadata);
+NANOARROW_DLL ArrowErrorCode ArrowSchemaSetMetadata(struct ArrowSchema* schema,
+                                                    const char* metadata);
 
 /// \brief Allocate the schema->children array
 ///
 /// Includes the memory for each child struct ArrowSchema.
 /// schema must have been allocated using ArrowSchemaInitFromType() or
 /// ArrowSchemaDeepCopy().
-ArrowErrorCode ArrowSchemaAllocateChildren(struct ArrowSchema* schema,
-                                           int64_t n_children);
+NANOARROW_DLL ArrowErrorCode ArrowSchemaAllocateChildren(struct ArrowSchema* 
schema,
+                                                         int64_t n_children);
 
 /// \brief Allocate the schema->dictionary member
 ///
 /// schema must have been allocated using ArrowSchemaInitFromType() or
 /// ArrowSchemaDeepCopy().
-ArrowErrorCode ArrowSchemaAllocateDictionary(struct ArrowSchema* schema);
+NANOARROW_DLL ArrowErrorCode ArrowSchemaAllocateDictionary(struct ArrowSchema* 
schema);
 
 /// @}
 
@@ -1494,49 +1585,51 @@ struct ArrowMetadataReader {
 };
 
 /// \brief Initialize an ArrowMetadataReader
-ArrowErrorCode ArrowMetadataReaderInit(struct ArrowMetadataReader* reader,
-                                       const char* metadata);
+NANOARROW_DLL ArrowErrorCode ArrowMetadataReaderInit(struct 
ArrowMetadataReader* reader,
+                                                     const char* metadata);
 
 /// \brief Read the next key/value pair from an ArrowMetadataReader
-ArrowErrorCode ArrowMetadataReaderRead(struct ArrowMetadataReader* reader,
-                                       struct ArrowStringView* key_out,
-                                       struct ArrowStringView* value_out);
+NANOARROW_DLL ArrowErrorCode ArrowMetadataReaderRead(struct 
ArrowMetadataReader* reader,
+                                                     struct ArrowStringView* 
key_out,
+                                                     struct ArrowStringView* 
value_out);
 
 /// \brief The number of bytes in in a key/value metadata string
-int64_t ArrowMetadataSizeOf(const char* metadata);
+NANOARROW_DLL int64_t ArrowMetadataSizeOf(const char* metadata);
 
 /// \brief Check for a key in schema metadata
-char ArrowMetadataHasKey(const char* metadata, struct ArrowStringView key);
+NANOARROW_DLL char ArrowMetadataHasKey(const char* metadata, struct 
ArrowStringView key);
 
 /// \brief Extract a value from schema metadata
 ///
 /// If key does not exist in metadata, value_out is unmodified
-ArrowErrorCode ArrowMetadataGetValue(const char* metadata, struct 
ArrowStringView key,
-                                     struct ArrowStringView* value_out);
+NANOARROW_DLL ArrowErrorCode ArrowMetadataGetValue(const char* metadata,
+                                                   struct ArrowStringView key,
+                                                   struct ArrowStringView* 
value_out);
 
 /// \brief Initialize a builder for schema metadata from key/value pairs
 ///
 /// metadata can be an existing metadata string or NULL to initialize
 /// an empty metadata string.
-ArrowErrorCode ArrowMetadataBuilderInit(struct ArrowBuffer* buffer, const 
char* metadata);
+NANOARROW_DLL ArrowErrorCode ArrowMetadataBuilderInit(struct ArrowBuffer* 
buffer,
+                                                      const char* metadata);
 
 /// \brief Append a key/value pair to a buffer containing serialized metadata
-ArrowErrorCode ArrowMetadataBuilderAppend(struct ArrowBuffer* buffer,
-                                          struct ArrowStringView key,
-                                          struct ArrowStringView value);
+NANOARROW_DLL ArrowErrorCode ArrowMetadataBuilderAppend(struct ArrowBuffer* 
buffer,
+                                                        struct ArrowStringView 
key,
+                                                        struct ArrowStringView 
value);
 
 /// \brief Set a key/value pair to a buffer containing serialized metadata
 ///
 /// Ensures that the only entry for key in the metadata is set to value.
 /// This function maintains the existing position of (the first instance of)
 /// key if present in the data.
-ArrowErrorCode ArrowMetadataBuilderSet(struct ArrowBuffer* buffer,
-                                       struct ArrowStringView key,
-                                       struct ArrowStringView value);
+NANOARROW_DLL ArrowErrorCode ArrowMetadataBuilderSet(struct ArrowBuffer* 
buffer,
+                                                     struct ArrowStringView 
key,
+                                                     struct ArrowStringView 
value);
 
 /// \brief Remove a key from a buffer containing serialized metadata
-ArrowErrorCode ArrowMetadataBuilderRemove(struct ArrowBuffer* buffer,
-                                          struct ArrowStringView key);
+NANOARROW_DLL ArrowErrorCode ArrowMetadataBuilderRemove(struct ArrowBuffer* 
buffer,
+                                                        struct ArrowStringView 
key);
 
 /// @}
 
@@ -1634,9 +1727,9 @@ struct ArrowSchemaView {
 };
 
 /// \brief Initialize an ArrowSchemaView
-ArrowErrorCode ArrowSchemaViewInit(struct ArrowSchemaView* schema_view,
-                                   const struct ArrowSchema* schema,
-                                   struct ArrowError* error);
+NANOARROW_DLL ArrowErrorCode ArrowSchemaViewInit(struct ArrowSchemaView* 
schema_view,
+                                                 const struct ArrowSchema* 
schema,
+                                                 struct ArrowError* error);
 
 /// @}
 
@@ -1852,24 +1945,24 @@ static inline void ArrowBitmapReset(struct ArrowBitmap* 
bitmap);
 /// Initializes the fields and release callback of array. Caller
 /// is responsible for calling the array->release callback if
 /// NANOARROW_OK is returned.
-ArrowErrorCode ArrowArrayInitFromType(struct ArrowArray* array,
-                                      enum ArrowType storage_type);
+NANOARROW_DLL ArrowErrorCode ArrowArrayInitFromType(struct ArrowArray* array,
+                                                    enum ArrowType 
storage_type);
 
 /// \brief Initialize the contents of an ArrowArray from an ArrowSchema
 ///
 /// Caller is responsible for calling the array->release callback if
 /// NANOARROW_OK is returned.
-ArrowErrorCode ArrowArrayInitFromSchema(struct ArrowArray* array,
-                                        const struct ArrowSchema* schema,
-                                        struct ArrowError* error);
+NANOARROW_DLL ArrowErrorCode ArrowArrayInitFromSchema(struct ArrowArray* array,
+                                                      const struct 
ArrowSchema* schema,
+                                                      struct ArrowError* 
error);
 
 /// \brief Initialize the contents of an ArrowArray from an ArrowArrayView
 ///
 /// Caller is responsible for calling the array->release callback if
 /// NANOARROW_OK is returned.
-ArrowErrorCode ArrowArrayInitFromArrayView(struct ArrowArray* array,
-                                           const struct ArrowArrayView* 
array_view,
-                                           struct ArrowError* error);
+NANOARROW_DLL ArrowErrorCode ArrowArrayInitFromArrayView(
+    struct ArrowArray* array, const struct ArrowArrayView* array_view,
+    struct ArrowError* error);
 
 /// \brief Allocate the array->children array
 ///
@@ -1877,7 +1970,8 @@ ArrowErrorCode ArrowArrayInitFromArrayView(struct 
ArrowArray* array,
 /// whose members are marked as released and may be subsequently initialized
 /// with ArrowArrayInitFromType() or moved from an existing ArrowArray.
 /// schema must have been allocated using ArrowArrayInitFromType().
-ArrowErrorCode ArrowArrayAllocateChildren(struct ArrowArray* array, int64_t 
n_children);
+NANOARROW_DLL ArrowErrorCode ArrowArrayAllocateChildren(struct ArrowArray* 
array,
+                                                        int64_t n_children);
 
 /// \brief Allocate the array->dictionary member
 ///
@@ -1885,18 +1979,19 @@ ArrowErrorCode ArrowArrayAllocateChildren(struct 
ArrowArray* array, int64_t n_ch
 /// is marked as released and may be subsequently initialized
 /// with ArrowArrayInitFromType() or moved from an existing ArrowArray.
 /// array must have been allocated using ArrowArrayInitFromType()
-ArrowErrorCode ArrowArrayAllocateDictionary(struct ArrowArray* array);
+NANOARROW_DLL ArrowErrorCode ArrowArrayAllocateDictionary(struct ArrowArray* 
array);
 
 /// \brief Set the validity bitmap of an ArrowArray
 ///
 /// array must have been allocated using ArrowArrayInitFromType()
-void ArrowArraySetValidityBitmap(struct ArrowArray* array, struct ArrowBitmap* 
bitmap);
+NANOARROW_DLL void ArrowArraySetValidityBitmap(struct ArrowArray* array,
+                                               struct ArrowBitmap* bitmap);
 
 /// \brief Set a buffer of an ArrowArray
 ///
 /// array must have been allocated using ArrowArrayInitFromType()
-ArrowErrorCode ArrowArraySetBuffer(struct ArrowArray* array, int64_t i,
-                                   struct ArrowBuffer* buffer);
+NANOARROW_DLL ArrowErrorCode ArrowArraySetBuffer(struct ArrowArray* array, 
int64_t i,
+                                                 struct ArrowBuffer* buffer);
 
 /// \brief Get the validity bitmap of an ArrowArray
 ///
@@ -1922,8 +2017,8 @@ static inline ArrowErrorCode 
ArrowArrayStartAppending(struct ArrowArray* array);
 /// child array sizes for non-fixed-size arrays), recursively reserve space for
 /// additional elements. This is useful for reducing the number of 
reallocations
 /// that occur using the item-wise appenders.
-ArrowErrorCode ArrowArrayReserve(struct ArrowArray* array,
-                                 int64_t additional_size_elements);
+NANOARROW_DLL ArrowErrorCode ArrowArrayReserve(struct ArrowArray* array,
+                                               int64_t 
additional_size_elements);
 
 /// \brief Append a null value to an array
 static inline ArrowErrorCode ArrowArrayAppendNull(struct ArrowArray* array, 
int64_t n);
@@ -2021,8 +2116,8 @@ static inline ArrowErrorCode ArrowArrayShrinkToFit(struct 
ArrowArray* array);
 /// into array->buffers and checks the actual size of the buffers
 /// against the expected size based on the final length.
 /// array must have been allocated using ArrowArrayInitFromType()
-ArrowErrorCode ArrowArrayFinishBuildingDefault(struct ArrowArray* array,
-                                               struct ArrowError* error);
+NANOARROW_DLL ArrowErrorCode ArrowArrayFinishBuildingDefault(struct 
ArrowArray* array,
+                                                             struct 
ArrowError* error);
 
 /// \brief Finish building an ArrowArray with explicit validation
 ///
@@ -2031,9 +2126,9 @@ ArrowErrorCode ArrowArrayFinishBuildingDefault(struct 
ArrowArray* array,
 /// buffer data access is not possible or more validation (i.e.,
 /// NANOARROW_VALIDATION_LEVEL_FULL) if buffer content was obtained from an 
untrusted or
 /// corruptible source.
-ArrowErrorCode ArrowArrayFinishBuilding(struct ArrowArray* array,
-                                        enum ArrowValidationLevel 
validation_level,
-                                        struct ArrowError* error);
+NANOARROW_DLL ArrowErrorCode ArrowArrayFinishBuilding(
+    struct ArrowArray* array, enum ArrowValidationLevel validation_level,
+    struct ArrowError* error);
 
 /// @}
 
@@ -2044,8 +2139,8 @@ ArrowErrorCode ArrowArrayFinishBuilding(struct 
ArrowArray* array,
 /// @{
 
 /// \brief Initialize the contents of an ArrowArrayView
-void ArrowArrayViewInitFromType(struct ArrowArrayView* array_view,
-                                enum ArrowType storage_type);
+NANOARROW_DLL void ArrowArrayViewInitFromType(struct ArrowArrayView* 
array_view,
+                                              enum ArrowType storage_type);
 
 /// \brief Move an ArrowArrayView
 ///
@@ -2055,32 +2150,34 @@ static inline void ArrowArrayViewMove(struct 
ArrowArrayView* src,
                                       struct ArrowArrayView* dst);
 
 /// \brief Initialize the contents of an ArrowArrayView from an ArrowSchema
-ArrowErrorCode ArrowArrayViewInitFromSchema(struct ArrowArrayView* array_view,
-                                            const struct ArrowSchema* schema,
-                                            struct ArrowError* error);
+NANOARROW_DLL ArrowErrorCode
+ArrowArrayViewInitFromSchema(struct ArrowArrayView* array_view,
+                             const struct ArrowSchema* schema, struct 
ArrowError* error);
 
 /// \brief Allocate the array_view->children array
 ///
 /// Includes the memory for each child struct ArrowArrayView
-ArrowErrorCode ArrowArrayViewAllocateChildren(struct ArrowArrayView* 
array_view,
-                                              int64_t n_children);
+NANOARROW_DLL ArrowErrorCode
+ArrowArrayViewAllocateChildren(struct ArrowArrayView* array_view, int64_t 
n_children);
 
 /// \brief Allocate array_view->dictionary
-ArrowErrorCode ArrowArrayViewAllocateDictionary(struct ArrowArrayView* 
array_view);
+NANOARROW_DLL ArrowErrorCode
+ArrowArrayViewAllocateDictionary(struct ArrowArrayView* array_view);
 
 /// \brief Set data-independent buffer sizes from length
-void ArrowArrayViewSetLength(struct ArrowArrayView* array_view, int64_t 
length);
+NANOARROW_DLL void ArrowArrayViewSetLength(struct ArrowArrayView* array_view,
+                                           int64_t length);
 
 /// \brief Set buffer sizes and data pointers from an ArrowArray
-ArrowErrorCode ArrowArrayViewSetArray(struct ArrowArrayView* array_view,
-                                      const struct ArrowArray* array,
-                                      struct ArrowError* error);
+NANOARROW_DLL ArrowErrorCode ArrowArrayViewSetArray(struct ArrowArrayView* 
array_view,
+                                                    const struct ArrowArray* 
array,
+                                                    struct ArrowError* error);
 
 /// \brief Set buffer sizes and data pointers from an ArrowArray except for 
those
 /// that require dereferencing buffer content.
-ArrowErrorCode ArrowArrayViewSetArrayMinimal(struct ArrowArrayView* array_view,
-                                             const struct ArrowArray* array,
-                                             struct ArrowError* error);
+NANOARROW_DLL ArrowErrorCode
+ArrowArrayViewSetArrayMinimal(struct ArrowArrayView* array_view,
+                              const struct ArrowArray* array, struct 
ArrowError* error);
 
 /// \brief Get the number of buffers
 ///
@@ -2132,9 +2229,9 @@ static inline int64_t 
ArrowArrayViewGetBufferElementSizeBits(
 /// and sizes otherwise, you may wish to perform checks at a different level. 
See
 /// documentation for ArrowValidationLevel for the details of checks performed
 /// at each level.
-ArrowErrorCode ArrowArrayViewValidate(struct ArrowArrayView* array_view,
-                                      enum ArrowValidationLevel 
validation_level,
-                                      struct ArrowError* error);
+NANOARROW_DLL ArrowErrorCode ArrowArrayViewValidate(
+    struct ArrowArrayView* array_view, enum ArrowValidationLevel 
validation_level,
+    struct ArrowError* error);
 
 /// \brief Compare two ArrowArrayView objects for equality
 ///
@@ -2144,13 +2241,13 @@ ArrowErrorCode ArrowArrayViewValidate(struct 
ArrowArrayView* array_view,
 /// error if error is non-NULL.
 ///
 /// Returns NANOARROW_OK if the comparison completed successfully.
-ArrowErrorCode ArrowArrayViewCompare(const struct ArrowArrayView* actual,
-                                     const struct ArrowArrayView* expected,
-                                     enum ArrowCompareLevel level, int* out,
-                                     struct ArrowError* reason);
+NANOARROW_DLL ArrowErrorCode ArrowArrayViewCompare(const struct 
ArrowArrayView* actual,
+                                                   const struct 
ArrowArrayView* expected,
+                                                   enum ArrowCompareLevel 
level, int* out,
+                                                   struct ArrowError* reason);
 
 /// \brief Reset the contents of an ArrowArrayView and frees resources
-void ArrowArrayViewReset(struct ArrowArrayView* array_view);
+NANOARROW_DLL void ArrowArrayViewReset(struct ArrowArrayView* array_view);
 
 /// \brief Check for a null element in an ArrowArrayView
 static inline int8_t ArrowArrayViewIsNull(const struct ArrowArrayView* 
array_view,
@@ -2229,8 +2326,8 @@ static inline void ArrowArrayViewGetDecimalUnsafe(const 
struct ArrowArrayView* a
 /// This function moves the ownership of schema to the array_stream. If
 /// this function returns NANOARROW_OK, the caller is responsible for
 /// releasing the ArrowArrayStream.
-ArrowErrorCode ArrowBasicArrayStreamInit(struct ArrowArrayStream* array_stream,
-                                         struct ArrowSchema* schema, int64_t 
n_arrays);
+NANOARROW_DLL ArrowErrorCode ArrowBasicArrayStreamInit(
+    struct ArrowArrayStream* array_stream, struct ArrowSchema* schema, int64_t 
n_arrays);
 
 /// \brief Set the ith ArrowArray in this ArrowArrayStream.
 ///
@@ -2239,16 +2336,16 @@ ArrowErrorCode ArrowBasicArrayStreamInit(struct 
ArrowArrayStream* array_stream,
 /// be greater than zero and less than the value of n_arrays passed in
 /// ArrowBasicArrayStreamInit(). Callers are not required to fill all
 /// n_arrays members (i.e., n_arrays is a maximum bound).
-void ArrowBasicArrayStreamSetArray(struct ArrowArrayStream* array_stream, 
int64_t i,
-                                   struct ArrowArray* array);
+NANOARROW_DLL void ArrowBasicArrayStreamSetArray(struct ArrowArrayStream* 
array_stream,
+                                                 int64_t i, struct ArrowArray* 
array);
 
 /// \brief Validate the contents of this ArrowArrayStream
 ///
 /// array_stream must have been initialized with ArrowBasicArrayStreamInit().
 /// This function uses ArrowArrayStreamInitFromSchema() and 
ArrowArrayStreamSetArray()
 /// to validate the contents of the arrays.
-ArrowErrorCode ArrowBasicArrayStreamValidate(const struct ArrowArrayStream* 
array_stream,
-                                             struct ArrowError* error);
+NANOARROW_DLL ArrowErrorCode ArrowBasicArrayStreamValidate(
+    const struct ArrowArrayStream* array_stream, struct ArrowError* error);
 
 /// @}
 
@@ -2893,6 +2990,9 @@ static inline void ArrowBitmapAppendInt8Unsafe(struct 
ArrowBitmap* bitmap,
     return;
   }
 
+  NANOARROW_DCHECK(bitmap->buffer.data != NULL);
+  NANOARROW_DCHECK(values != NULL);
+
   const int8_t* values_cursor = values;
   int64_t n_remaining = n_values;
   int64_t out_i_cursor = bitmap->size_bits;
@@ -2940,6 +3040,9 @@ static inline void ArrowBitmapAppendInt32Unsafe(struct 
ArrowBitmap* bitmap,
     return;
   }
 
+  NANOARROW_DCHECK(bitmap->buffer.data != NULL);
+  NANOARROW_DCHECK(values != NULL);
+
   const int32_t* values_cursor = values;
   int64_t n_remaining = n_values;
   int64_t out_i_cursor = bitmap->size_bits;
@@ -3283,6 +3386,9 @@ static inline ArrowErrorCode 
_ArrowArrayAppendEmptyInternal(struct ArrowArray* a
       case NANOARROW_BUFFER_TYPE_VARIADIC_SIZE:
       case NANOARROW_BUFFER_TYPE_VALIDITY:
         continue;
+      case NANOARROW_BUFFER_TYPE_SIZE:
+        NANOARROW_RETURN_NOT_OK(ArrowBufferAppendFill(buffer, 0, size_bytes * 
n));
+        continue;
       case NANOARROW_BUFFER_TYPE_DATA_OFFSET:
         // Append the current value at the end of the offset buffer for each 
element
         NANOARROW_RETURN_NOT_OK(ArrowBufferReserve(buffer, size_bytes * n));
@@ -3303,7 +3409,10 @@ static inline ArrowErrorCode 
_ArrowArrayAppendEmptyInternal(struct ArrowArray* a
           NANOARROW_RETURN_NOT_OK(_ArrowArrayAppendBits(array, i, 0, n));
         }
         continue;
-
+      case NANOARROW_BUFFER_TYPE_VIEW_OFFSET:
+        NANOARROW_RETURN_NOT_OK(ArrowBufferReserve(buffer, size_bytes * n));
+        NANOARROW_RETURN_NOT_OK(ArrowBufferAppendFill(buffer, 0, size_bytes * 
n));
+        continue;
       case NANOARROW_BUFFER_TYPE_TYPE_ID:
       case NANOARROW_BUFFER_TYPE_UNION_OFFSET:
         // These cases return above
@@ -3693,6 +3802,22 @@ static inline ArrowErrorCode 
ArrowArrayAppendDecimal(struct ArrowArray* array,
   struct ArrowBuffer* data_buffer = ArrowArrayBuffer(array, 1);
 
   switch (private_data->storage_type) {
+    case NANOARROW_TYPE_DECIMAL32:
+      if (value->n_words != 0) {
+        return EINVAL;
+      } else {
+        NANOARROW_RETURN_NOT_OK(
+            ArrowBufferAppend(data_buffer, value->words, sizeof(uint32_t)));
+        break;
+      }
+    case NANOARROW_TYPE_DECIMAL64:
+      if (value->n_words != 1) {
+        return EINVAL;
+      } else {
+        NANOARROW_RETURN_NOT_OK(
+            ArrowBufferAppend(data_buffer, value->words, sizeof(uint64_t)));
+        break;
+      }
     case NANOARROW_TYPE_DECIMAL128:
       if (value->n_words != 2) {
         return EINVAL;
@@ -3734,6 +3859,7 @@ static inline ArrowErrorCode 
ArrowArrayFinishElement(struct ArrowArray* array) {
       if (child_length > INT32_MAX) {
         return EOVERFLOW;
       }
+
       NANOARROW_RETURN_NOT_OK(
           ArrowBufferAppendInt32(ArrowArrayBuffer(array, 1), 
(int32_t)child_length));
       break;
@@ -3749,6 +3875,31 @@ static inline ArrowErrorCode 
ArrowArrayFinishElement(struct ArrowArray* array) {
         return EINVAL;
       }
       break;
+    case NANOARROW_TYPE_LIST_VIEW: {
+      child_length = array->children[0]->length;
+      if (child_length > INT32_MAX) {
+        return EOVERFLOW;
+      }
+
+      const int32_t last_valid_offset = 
(int32_t)private_data->list_view_offset;
+      NANOARROW_RETURN_NOT_OK(
+          ArrowBufferAppendInt32(ArrowArrayBuffer(array, 1), 
last_valid_offset));
+      NANOARROW_RETURN_NOT_OK(ArrowBufferAppendInt32(
+          ArrowArrayBuffer(array, 2), (int32_t)child_length - 
last_valid_offset));
+      private_data->list_view_offset = child_length;
+      break;
+    }
+    case NANOARROW_TYPE_LARGE_LIST_VIEW: {
+      child_length = array->children[0]->length;
+      const int64_t last_valid_offset = private_data->list_view_offset;
+      NANOARROW_RETURN_NOT_OK(
+          ArrowBufferAppendInt64(ArrowArrayBuffer(array, 1), 
last_valid_offset));
+      NANOARROW_RETURN_NOT_OK(ArrowBufferAppendInt64(ArrowArrayBuffer(array, 
2),
+                                                     child_length - 
last_valid_offset));
+      private_data->list_view_offset = child_length;
+      break;
+    }
+
     case NANOARROW_TYPE_STRUCT:
       for (int64_t i = 0; i < array->n_children; i++) {
         child_length = array->children[i]->length;
@@ -4023,8 +4174,10 @@ static inline int64_t ArrowArrayViewListChildOffset(
     const struct ArrowArrayView* array_view, int64_t i) {
   switch (array_view->storage_type) {
     case NANOARROW_TYPE_LIST:
+    case NANOARROW_TYPE_LIST_VIEW:
       return array_view->buffer_views[1].data.as_int32[i];
     case NANOARROW_TYPE_LARGE_LIST:
+    case NANOARROW_TYPE_LARGE_LIST_VIEW:
       return array_view->buffer_views[1].data.as_int64[i];
     default:
       return -1;
@@ -4161,7 +4314,7 @@ static inline struct ArrowStringView 
ArrowArrayViewGetStringUnsafe(
     case NANOARROW_TYPE_BINARY:
       view.data = data_view + offsets_view->data.as_int32[i];
       view.size_bytes =
-          offsets_view->data.as_int32[i + 1] - offsets_view->data.as_int32[i];
+          (int64_t)offsets_view->data.as_int32[i + 1] - 
offsets_view->data.as_int32[i];
       break;
     case NANOARROW_TYPE_LARGE_STRING:
     case NANOARROW_TYPE_LARGE_BINARY:
@@ -4201,7 +4354,7 @@ static inline struct ArrowBufferView 
ArrowArrayViewGetBytesUnsafe(
     case NANOARROW_TYPE_STRING:
     case NANOARROW_TYPE_BINARY:
       view.size_bytes =
-          offsets_view->data.as_int32[i + 1] - offsets_view->data.as_int32[i];
+          (int64_t)offsets_view->data.as_int32[i + 1] - 
offsets_view->data.as_int32[i];
       view.data.as_uint8 = data_view + offsets_view->data.as_int32[i];
       break;
     case NANOARROW_TYPE_LARGE_STRING:
@@ -4231,23 +4384,25 @@ static inline struct ArrowBufferView 
ArrowArrayViewGetBytesUnsafe(
 static inline void ArrowArrayViewGetIntervalUnsafe(
     const struct ArrowArrayView* array_view, int64_t i, struct ArrowInterval* 
out) {
   const uint8_t* data_view = array_view->buffer_views[1].data.as_uint8;
+  const int64_t offset = array_view->offset;
+  const int64_t index = offset + i;
   switch (array_view->storage_type) {
     case NANOARROW_TYPE_INTERVAL_MONTHS: {
       const size_t size = sizeof(int32_t);
-      memcpy(&out->months, data_view + i * size, sizeof(int32_t));
+      memcpy(&out->months, data_view + index * size, sizeof(int32_t));
       break;
     }
     case NANOARROW_TYPE_INTERVAL_DAY_TIME: {
       const size_t size = sizeof(int32_t) + sizeof(int32_t);
-      memcpy(&out->days, data_view + i * size, sizeof(int32_t));
-      memcpy(&out->ms, data_view + i * size + 4, sizeof(int32_t));
+      memcpy(&out->days, data_view + index * size, sizeof(int32_t));
+      memcpy(&out->ms, data_view + index * size + 4, sizeof(int32_t));
       break;
     }
     case NANOARROW_TYPE_INTERVAL_MONTH_DAY_NANO: {
       const size_t size = sizeof(int32_t) + sizeof(int32_t) + sizeof(int64_t);
-      memcpy(&out->months, data_view + i * size, sizeof(int32_t));
-      memcpy(&out->days, data_view + i * size + 4, sizeof(int32_t));
-      memcpy(&out->ns, data_view + i * size + 8, sizeof(int64_t));
+      memcpy(&out->months, data_view + index * size, sizeof(int32_t));
+      memcpy(&out->days, data_view + index * size + 4, sizeof(int32_t));
+      memcpy(&out->ns, data_view + index * size + 8, sizeof(int64_t));
       break;
     }
     default:
@@ -4260,6 +4415,12 @@ static inline void ArrowArrayViewGetDecimalUnsafe(const 
struct ArrowArrayView* a
   i += array_view->offset;
   const uint8_t* data_view = array_view->buffer_views[1].data.as_uint8;
   switch (array_view->storage_type) {
+    case NANOARROW_TYPE_DECIMAL32:
+      ArrowDecimalSetBytes(out, data_view + (i * 4));
+      break;
+    case NANOARROW_TYPE_DECIMAL64:
+      ArrowDecimalSetBytes(out, data_view + (i * 8));
+      break;
     case NANOARROW_TYPE_DECIMAL128:
       ArrowDecimalSetBytes(out, data_view + (i * 16));
       break;
diff --git a/c/vendor/nanoarrow/nanoarrow.hpp b/c/vendor/nanoarrow/nanoarrow.hpp
index f2eade3d8..6f224f66f 100644
--- a/c/vendor/nanoarrow/nanoarrow.hpp
+++ b/c/vendor/nanoarrow/nanoarrow.hpp
@@ -15,16 +15,6 @@
 // specific language governing permissions and limitations
 // under the License.
 
-#include <cstring>
-#include <exception>
-#include <string>
-#include <vector>
-
-#include "nanoarrow.h"
-
-#ifndef NANOARROW_HPP_INCLUDED
-#define NANOARROW_HPP_INCLUDED
-
 /// \defgroup nanoarrow_hpp Nanoarrow C++ Helpers
 ///
 /// The utilities provided in this file are intended to support C++ users
@@ -32,7 +22,38 @@
 /// and error handling can be used with nanoarrow data structures.
 /// These utilities are not intended to mirror the nanoarrow C API.
 
-namespace nanoarrow {
+
+
+
+
+
+
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+#ifndef NANOARROW_HPP_EXCEPTION_HPP_INCLUDED
+#define NANOARROW_HPP_EXCEPTION_HPP_INCLUDED
+
+#include <exception>
+#include <string>
+
+#include "nanoarrow.h"
+
+NANOARROW_CXX_NAMESPACE_BEGIN
 
 /// \defgroup nanoarrow_hpp-errors Error handling helpers
 ///
@@ -83,6 +104,37 @@ class Exception : public std::exception {
 
 /// @}
 
+NANOARROW_CXX_NAMESPACE_END
+
+#endif
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+#ifndef NANOARROW_HPP_OPERATORS_HPP_INCLUDED
+#define NANOARROW_HPP_OPERATORS_HPP_INCLUDED
+
+#include <stddef.h>
+#include <stdint.h>
+#include <string.h>
+
+#include "nanoarrow.h"
+
+NANOARROW_CXX_NAMESPACE_BEGIN
+
 namespace literals {
 
 /// \defgroup nanoarrow_hpp-string_view_helpers ArrowStringView helpers
@@ -93,11 +145,11 @@ namespace literals {
 
 /// \brief User literal operator allowing ArrowStringView construction like 
"str"_asv
 #if !defined(__clang__) && (defined(__GNUC__) && __GNUC__ < 6)
-inline ArrowStringView operator"" _asv(const char* data, std::size_t 
size_bytes) {
+inline ArrowStringView operator"" _asv(const char* data, size_t size_bytes) {
   return {data, static_cast<int64_t>(size_bytes)};
 }
 #else
-inline ArrowStringView operator""_asv(const char* data, std::size_t 
size_bytes) {
+inline ArrowStringView operator""_asv(const char* data, size_t size_bytes) {
   return {data, static_cast<int64_t>(size_bytes)};
 }
 #endif
@@ -107,6 +159,42 @@ inline ArrowStringView operator""_asv(const char* data, 
std::size_t size_bytes)
 
 }  // namespace literals
 
+NANOARROW_CXX_NAMESPACE_END
+
+/// \brief Equality comparison operator between ArrowStringView
+/// \ingroup nanoarrow_hpp-string_view_helpers
+inline bool operator==(ArrowStringView l, ArrowStringView r) {
+  if (l.size_bytes != r.size_bytes) return false;
+  return memcmp(l.data, r.data, l.size_bytes) == 0;
+}
+
+#endif
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+#ifndef NANOARROW_HPP_UNIQUE_HPP_INCLUDED
+#define NANOARROW_HPP_UNIQUE_HPP_INCLUDED
+
+#include <string.h>
+
+#include "nanoarrow.h"
+
+NANOARROW_CXX_NAMESPACE_BEGIN
+
 namespace internal {
 
 /// \defgroup nanoarrow_hpp-unique_base Base classes for Unique wrappers
@@ -225,13 +313,13 @@ class Unique {
  public:
   /// \brief Construct an invalid instance of T holding no resources
   Unique() {
-    std::memset(&data_, 0, sizeof(data_));
+    memset(&data_, 0, sizeof(data_));
     init_pointer(&data_);
   }
 
   /// \brief Move and take ownership of data
   Unique(T* data) {
-    std::memset(&data_, 0, sizeof(data_));
+    memset(&data_, 0, sizeof(data_));
     move_pointer(data, &data_);
   }
 
@@ -272,15 +360,6 @@ class Unique {
   T data_;
 };
 
-template <typename T>
-static inline void DeallocateWrappedBuffer(struct ArrowBufferAllocator* 
allocator,
-                                           uint8_t* ptr, int64_t size) {
-  NANOARROW_UNUSED(ptr);
-  NANOARROW_UNUSED(size);
-  auto obj = reinterpret_cast<T*>(allocator->private_data);
-  delete obj;
-}
-
 /// @}
 
 }  // namespace internal
@@ -313,50 +392,34 @@ using UniqueArrayView = internal::Unique<struct 
ArrowArrayView>;
 
 /// @}
 
-/// \defgroup nanoarrow_hpp-buffer Buffer helpers
-///
-/// Helpers to wrap buffer-like C++ objects as ArrowBuffer objects that can
-/// be used to build ArrowArray objects.
-///
-/// @{
+NANOARROW_CXX_NAMESPACE_END
 
-/// \brief Initialize a buffer wrapping an arbitrary C++ object
-///
-/// Initializes a buffer with a release callback that deletes the moved obj
-/// when ArrowBufferReset is called. This version is useful for wrapping
-/// an object whose .data() member is missing or unrelated to the buffer
-/// value that is destined for a the buffer of an ArrowArray. T must be 
movable.
-template <typename T>
-static inline void BufferInitWrapped(struct ArrowBuffer* buffer, T obj,
-                                     const uint8_t* data, int64_t size_bytes) {
-  T* obj_moved = new T(std::move(obj));
-  buffer->data = const_cast<uint8_t*>(data);
-  buffer->size_bytes = size_bytes;
-  buffer->capacity_bytes = 0;
-  buffer->allocator =
-      ArrowBufferDeallocator(&internal::DeallocateWrappedBuffer<T>, obj_moved);
-}
+#endif
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+#ifndef NANOARROW_HPP_ARRAY_STREAM_HPP_INCLUDED
+#define NANOARROW_HPP_ARRAY_STREAM_HPP_INCLUDED
+
+#include <vector>
 
-/// \brief Initialize a buffer wrapping a C++ sequence
-///
-/// Specifically, this uses obj.data() to set the buffer address and
-/// obj.size() * sizeof(T::value_type) to set the buffer size. This works
-/// for STL containers like std::vector, std::array, and std::string.
-/// This function moves obj and ensures it is deleted when ArrowBufferReset
-/// is called.
-template <typename T>
-void BufferInitSequence(struct ArrowBuffer* buffer, T obj) {
-  // Move before calling .data() (matters sometimes).
-  T* obj_moved = new T(std::move(obj));
-  buffer->data =
-      const_cast<uint8_t*>(reinterpret_cast<const 
uint8_t*>(obj_moved->data()));
-  buffer->size_bytes = obj_moved->size() * sizeof(typename T::value_type);
-  buffer->capacity_bytes = 0;
-  buffer->allocator =
-      ArrowBufferDeallocator(&internal::DeallocateWrappedBuffer<T>, obj_moved);
-}
 
-/// @}
+
+NANOARROW_CXX_NAMESPACE_BEGIN
 
 /// \defgroup nanoarrow_hpp-array-stream ArrayStream helpers
 ///
@@ -451,11 +514,6 @@ class ArrayStreamFactory {
 ///
 /// This class can be constructed from an struct ArrowSchema and implements a 
default
 /// get_next() method that always marks the output ArrowArray as released.
-///
-/// DEPRECATED (0.4.0): Early versions of nanoarrow allowed subclasses to 
override
-/// get_schema(), get_next(), and get_last_error(). This functionality will be 
removed
-/// in a future release: use the pattern documented in ArrayStreamFactory to 
create
-/// custom ArrowArrayStream implementations.
 class EmptyArrayStream {
  public:
   /// \brief Create an EmptyArrayStream from an ArrowSchema
@@ -471,43 +529,22 @@ class EmptyArrayStream {
     ArrayStreamFactory<EmptyArrayStream>::InitArrayStream(impl, out);
   }
 
-  /// \brief Create an empty UniqueArrayStream from a struct ArrowSchema
-  ///
-  /// DEPRECATED (0.4.0): Use the constructor + ToArrayStream() to export an
-  /// EmptyArrayStream to an ArrowArrayStream consumer.
-  static UniqueArrayStream MakeUnique(struct ArrowSchema* schema) {
-    UniqueArrayStream stream;
-    EmptyArrayStream(schema).ToArrayStream(stream.get());
-    return stream;
-  }
-
-  virtual ~EmptyArrayStream() {}
-
- protected:
+ private:
   UniqueSchema schema_;
   struct ArrowError error_;
 
-  void MakeStream(struct ArrowArrayStream* stream) { ToArrayStream(stream); }
+  friend class ArrayStreamFactory<EmptyArrayStream>;
 
-  virtual int get_schema(struct ArrowSchema* schema) {
+  int GetSchema(struct ArrowSchema* schema) {
     return ArrowSchemaDeepCopy(schema_.get(), schema);
   }
 
-  virtual int get_next(struct ArrowArray* array) {
+  int GetNext(struct ArrowArray* array) {
     array->release = nullptr;
     return NANOARROW_OK;
   }
 
-  virtual const char* get_last_error() { return error_.message; }
-
- private:
-  friend class ArrayStreamFactory<EmptyArrayStream>;
-
-  int GetSchema(struct ArrowSchema* schema) { return get_schema(schema); }
-
-  int GetNext(struct ArrowArray* array) { return get_next(array); }
-
-  const char* GetLastError() { return get_last_error(); }
+  const char* GetLastError() { return error_.message; }
 };
 
 /// \brief Implementation of an ArrowArrayStream backed by a vector of 
UniqueArray objects
@@ -533,28 +570,6 @@ class VectorArrayStream {
     ArrayStreamFactory<VectorArrayStream>::InitArrayStream(impl, out);
   }
 
-  /// \brief Create a UniqueArrowArrayStream from an existing array
-  ///
-  /// DEPRECATED (0.4.0): Use the constructors + ToArrayStream() to export a
-  /// VectorArrayStream to an ArrowArrayStream consumer.
-  static UniqueArrayStream MakeUnique(struct ArrowSchema* schema,
-                                      struct ArrowArray* array) {
-    UniqueArrayStream stream;
-    VectorArrayStream(schema, array).ToArrayStream(stream.get());
-    return stream;
-  }
-
-  /// \brief Create a UniqueArrowArrayStream from existing arrays
-  ///
-  /// DEPRECATED (0.4.0): Use the constructor + ToArrayStream() to export a
-  /// VectorArrayStream to an ArrowArrayStream consumer.
-  static UniqueArrayStream MakeUnique(struct ArrowSchema* schema,
-                                      std::vector<UniqueArray> arrays) {
-    UniqueArrayStream stream;
-    VectorArrayStream(schema, std::move(arrays)).ToArrayStream(stream.get());
-    return stream;
-  }
-
  private:
   int64_t offset_;
   UniqueSchema schema_;
@@ -581,25 +596,146 @@ class VectorArrayStream {
 
 /// @}
 
+NANOARROW_CXX_NAMESPACE_END
+
+#endif
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+#ifndef NANOARROW_HPP_BUFFER_HPP_INCLUDED
+#define NANOARROW_HPP_BUFFER_HPP_INCLUDED
+
+#include <stdint.h>
+#include <utility>
+#include "nanoarrow.h"
+
+NANOARROW_CXX_NAMESPACE_BEGIN
+
+namespace internal {
+template <typename T>
+static inline void DeallocateWrappedBuffer(struct ArrowBufferAllocator* 
allocator,
+                                           uint8_t* ptr, int64_t size) {
+  NANOARROW_UNUSED(ptr);
+  NANOARROW_UNUSED(size);
+  auto obj = reinterpret_cast<T*>(allocator->private_data);
+  delete obj;
+}
+}  // namespace internal
+
+/// \defgroup nanoarrow_hpp-buffer Buffer helpers
+///
+/// Helpers to wrap buffer-like C++ objects as ArrowBuffer objects that can
+/// be used to build ArrowArray objects.
+///
+/// @{
+
+/// \brief Initialize a buffer wrapping an arbitrary C++ object
+///
+/// Initializes a buffer with a release callback that deletes the moved obj
+/// when ArrowBufferReset is called. This version is useful for wrapping
+/// an object whose .data() member is missing or unrelated to the buffer
+/// value that is destined for a the buffer of an ArrowArray. T must be 
movable.
+template <typename T>
+static inline void BufferInitWrapped(struct ArrowBuffer* buffer, T obj,
+                                     const uint8_t* data, int64_t size_bytes) {
+  T* obj_moved = new T(std::move(obj));
+  buffer->data = const_cast<uint8_t*>(data);
+  buffer->size_bytes = size_bytes;
+  buffer->capacity_bytes = 0;
+  buffer->allocator =
+      ArrowBufferDeallocator(&internal::DeallocateWrappedBuffer<T>, obj_moved);
+}
+
+/// \brief Initialize a buffer wrapping a C++ sequence
+///
+/// Specifically, this uses obj.data() to set the buffer address and
+/// obj.size() * sizeof(T::value_type) to set the buffer size. This works
+/// for STL containers like std::vector, std::array, and std::string.
+/// This function moves obj and ensures it is deleted when ArrowBufferReset
+/// is called.
+template <typename T>
+void BufferInitSequence(struct ArrowBuffer* buffer, T obj) {
+  // Move before calling .data() (matters sometimes).
+  T* obj_moved = new T(std::move(obj));
+  buffer->data =
+      const_cast<uint8_t*>(reinterpret_cast<const 
uint8_t*>(obj_moved->data()));
+  buffer->size_bytes = obj_moved->size() * sizeof(typename T::value_type);
+  buffer->capacity_bytes = 0;
+  buffer->allocator =
+      ArrowBufferDeallocator(&internal::DeallocateWrappedBuffer<T>, obj_moved);
+}
+
+/// @}
+
+NANOARROW_CXX_NAMESPACE_END
+
+#endif
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+#ifndef NANOARROW_HPP_VIEW_HPP_INCLUDED
+#define NANOARROW_HPP_VIEW_HPP_INCLUDED
+
+#include <stdint.h>
+#include <type_traits>
+
+
+#include "nanoarrow.h"
+
+NANOARROW_CXX_NAMESPACE_BEGIN
+
 namespace internal {
 struct Nothing {};
 
 template <typename T>
 class Maybe {
  public:
-  Maybe() : nothing_(Nothing()), is_something_(false) {}
+  Maybe() : is_something_(false) {}
   Maybe(Nothing) : Maybe() {}
 
   Maybe(T something)  // NOLINT(google-explicit-constructor)
-      : something_(something), is_something_(true) {}
+      : is_something_(true), something_(something) {}
 
   explicit constexpr operator bool() const { return is_something_; }
 
   const T& operator*() const { return something_; }
 
   friend inline bool operator==(Maybe l, Maybe r) {
-    if (l.is_something_ != r.is_something_) return false;
-    return l.is_something_ ? l.something_ == r.something_ : true;
+    if (l.is_something_) {
+      return r.is_something_ && l.something_ == r.something_;
+    } else if (r.is_something_) {
+      return l.is_something_ && l.something_ == r.something_;
+    } else {
+      return l.is_something_ == r.is_something_;
+    }
   }
   friend inline bool operator!=(Maybe l, Maybe r) { return !(l == r); }
 
@@ -610,16 +746,14 @@ class Maybe {
   // is_trivially_copyable<T>::value
   static_assert(std::is_trivially_destructible<T>::value, "");
 
-  union {
-    Nothing nothing_;
-    T something_;
-  };
-  bool is_something_;
+  bool is_something_{};
+  T something_{};
 };
 
 template <typename Get>
 struct RandomAccessRange {
   Get get;
+  int64_t offset;
   int64_t size;
 
   using value_type = decltype(std::declval<Get>()(0));
@@ -633,8 +767,8 @@ struct RandomAccessRange {
     value_type operator*() const { return range->get(i); }
   };
 
-  const_iterator begin() const { return {0, this}; }
-  const_iterator end() const { return {size, this}; }
+  const_iterator begin() const { return {offset, this}; }
+  const_iterator end() const { return {offset + size, this}; }
 };
 
 template <typename Next>
@@ -687,10 +821,8 @@ class ViewArrayAs {
   struct Get {
     const uint8_t* validity;
     const void* values;
-    int64_t offset;
 
     internal::Maybe<T> operator()(int64_t i) const {
-      i += offset;
       if (validity == nullptr || ArrowBitGet(validity, i)) {
         if (std::is_same<T, bool>::value) {
           return ArrowBitGet(static_cast<const uint8_t*>(values), i);
@@ -710,8 +842,8 @@ class ViewArrayAs {
             Get{
                 array_view->buffer_views[0].data.as_uint8,
                 array_view->buffer_views[1].data.data,
-                array_view->offset,
             },
+            array_view->offset,
             array_view->length,
         } {}
 
@@ -720,8 +852,8 @@ class ViewArrayAs {
             Get{
                 static_cast<const uint8_t*>(array->buffers[0]),
                 array->buffers[1],
-                /*offset=*/0,
             },
+            array->offset,
             array->length,
         } {}
 
@@ -748,10 +880,8 @@ class ViewArrayAsBytes {
     const uint8_t* validity;
     const void* offsets;
     const char* data;
-    int64_t offset;
 
     internal::Maybe<ArrowStringView> operator()(int64_t i) const {
-      i += offset;
       auto* offsets = static_cast<const OffsetType*>(this->offsets);
       if (validity == nullptr || ArrowBitGet(validity, i)) {
         return ArrowStringView{data + offsets[i], offsets[i + 1] - offsets[i]};
@@ -769,8 +899,8 @@ class ViewArrayAsBytes {
                 array_view->buffer_views[0].data.as_uint8,
                 array_view->buffer_views[1].data.data,
                 array_view->buffer_views[2].data.as_char,
-                array_view->offset,
             },
+            array_view->offset,
             array_view->length,
         } {}
 
@@ -780,8 +910,62 @@ class ViewArrayAsBytes {
                 static_cast<const uint8_t*>(array->buffers[0]),
                 array->buffers[1],
                 static_cast<const char*>(array->buffers[2]),
-                /*offset=*/0,
             },
+            array->offset,
+            array->length,
+        } {}
+
+  using value_type = typename internal::RandomAccessRange<Get>::value_type;
+  using const_iterator = typename 
internal::RandomAccessRange<Get>::const_iterator;
+  const_iterator begin() const { return range_.begin(); }
+  const_iterator end() const { return range_.end(); }
+  value_type operator[](int64_t i) const { return range_.get(i); }
+};
+
+class ViewBinaryViewArrayAsBytes {
+ private:
+  struct Get {
+    const uint8_t* validity;
+    const union ArrowBinaryView* inline_data;
+    const void** variadic_buffers;
+
+    internal::Maybe<ArrowStringView> operator()(int64_t i) const {
+      if (validity == nullptr || ArrowBitGet(validity, i)) {
+        const union ArrowBinaryView* bv = &inline_data[i];
+        if (bv->inlined.size <= NANOARROW_BINARY_VIEW_INLINE_SIZE) {
+          return ArrowStringView{reinterpret_cast<const 
char*>(bv->inlined.data),
+                                 bv->inlined.size};
+        }
+
+        return ArrowStringView{
+            reinterpret_cast<const 
char*>(variadic_buffers[bv->ref.buffer_index]) +
+                bv->ref.offset,
+            bv->ref.size};
+      }
+      return NA;
+    }
+  };
+
+  internal::RandomAccessRange<Get> range_;
+
+ public:
+  ViewBinaryViewArrayAsBytes(const ArrowArrayView* array_view)
+      : range_{
+            Get{
+                array_view->buffer_views[0].data.as_uint8,
+                array_view->buffer_views[1].data.as_binary_view,
+                array_view->variadic_buffers,
+            },
+            array_view->offset,
+            array_view->length,
+        } {}
+
+  ViewBinaryViewArrayAsBytes(const ArrowArray* array)
+      : range_{
+            Get{static_cast<const uint8_t*>(array->buffers[0]),
+                static_cast<const union ArrowBinaryView*>(array->buffers[1]),
+                array->buffers + NANOARROW_BINARY_VIEW_FIXED_BUFFERS},
+            array->offset,
             array->length,
         } {}
 
@@ -801,11 +985,9 @@ class ViewArrayAsFixedSizeBytes {
   struct Get {
     const uint8_t* validity;
     const char* data;
-    int64_t offset;
     int fixed_size;
 
     internal::Maybe<ArrowStringView> operator()(int64_t i) const {
-      i += offset;
       if (validity == nullptr || ArrowBitGet(validity, i)) {
         return ArrowStringView{data + i * fixed_size, fixed_size};
       }
@@ -821,9 +1003,9 @@ class ViewArrayAsFixedSizeBytes {
             Get{
                 array_view->buffer_views[0].data.as_uint8,
                 array_view->buffer_views[1].data.as_char,
-                array_view->offset,
                 fixed_size,
             },
+            array_view->offset,
             array_view->length,
         } {}
 
@@ -832,9 +1014,9 @@ class ViewArrayAsFixedSizeBytes {
             Get{
                 static_cast<const uint8_t*>(array->buffers[0]),
                 static_cast<const char*>(array->buffers[1]),
-                /*offset=*/0,
                 fixed_size,
             },
+            array->offset,
             array->length,
         } {}
 
@@ -927,13 +1109,6 @@ class ViewArrayStream {
 
 /// @}
 
-}  // namespace nanoarrow
-
-/// \brief Equality comparison operator between ArrowStringView
-/// \ingroup nanoarrow_hpp-string_view_helpers
-inline bool operator==(ArrowStringView l, ArrowStringView r) {
-  if (l.size_bytes != r.size_bytes) return false;
-  return memcmp(l.data, r.data, l.size_bytes) == 0;
-}
+NANOARROW_CXX_NAMESPACE_END
 
 #endif
diff --git a/c/vendor/vendor_nanoarrow.sh b/c/vendor/vendor_nanoarrow.sh
index 9024090fe..d213b6af5 100755
--- a/c/vendor/vendor_nanoarrow.sh
+++ b/c/vendor/vendor_nanoarrow.sh
@@ -21,7 +21,7 @@
 main() {
     local -r repo_url="https://github.com/apache/arrow-nanoarrow";
     # Check releases page: https://github.com/apache/arrow-nanoarrow/releases/
-    local -r commit_sha=33d2c8b973d8f8f424e02ac92ddeaace2a92f8dd
+    local -r commit_sha=2cfba631b40886f1418a463f3b7c4552c8ae0dc7
 
     echo "Fetching $commit_sha from $repo_url"
     SCRATCH=$(mktemp -d)


Reply via email to