This is an automated email from the ASF dual-hosted git repository.
github-bot pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/arrow-nanoarrow.git
The following commit(s) were added to refs/heads/main by this push:
new 14dfcaa Update dist/ for commit
248b498c505aaba88f5593fb34f7c2e21e66c95d
14dfcaa is described below
commit 14dfcaaf9745a83af5b265ae14b9075e749e2d82
Author: GitHub Actions <[email protected]>
AuthorDate: Wed Dec 20 01:18:51 2023 +0000
Update dist/ for commit 248b498c505aaba88f5593fb34f7c2e21e66c95d
---
dist/nanoarrow.c | 56 ++++-----
dist/nanoarrow.h | 243 +++++++++++++++++++++++++++++++--------
dist/nanoarrow.hpp | 278 ++++++++++++++++++++++++++++++++++-----------
dist/nanoarrow_device.c | 10 +-
dist/nanoarrow_ipc.c | 20 ++--
dist/nanoarrow_testing.hpp | 66 ++++++++---
6 files changed, 498 insertions(+), 175 deletions(-)
diff --git a/dist/nanoarrow.c b/dist/nanoarrow.c
index 31e0b86..ff67036 100644
--- a/dist/nanoarrow.c
+++ b/dist/nanoarrow.c
@@ -28,7 +28,7 @@ const char* ArrowNanoarrowVersion(void) { return
NANOARROW_VERSION; }
int ArrowNanoarrowVersionInt(void) { return NANOARROW_VERSION_INT; }
-int ArrowErrorSet(struct ArrowError* error, const char* fmt, ...) {
+ArrowErrorCode ArrowErrorSet(struct ArrowError* error, const char* fmt, ...) {
if (error == NULL) {
return NANOARROW_OK;
}
@@ -49,14 +49,6 @@ int ArrowErrorSet(struct ArrowError* error, const char* fmt,
...) {
}
}
-const char* ArrowErrorMessage(struct ArrowError* error) {
- if (error == NULL) {
- return "";
- } else {
- return error->message;
- }
-}
-
void ArrowLayoutInit(struct ArrowLayout* layout, enum ArrowType storage_type) {
layout->buffer_type[0] = NANOARROW_BUFFER_TYPE_VALIDITY;
layout->buffer_data_type[0] = NANOARROW_TYPE_BOOL;
@@ -255,7 +247,7 @@ struct ArrowBufferAllocator ArrowBufferDeallocator(
#include "nanoarrow.h"
-static void ArrowSchemaRelease(struct ArrowSchema* schema) {
+static void ArrowSchemaReleaseInternal(struct ArrowSchema* schema) {
if (schema->format != NULL) ArrowFree((void*)schema->format);
if (schema->name != NULL) ArrowFree((void*)schema->name);
if (schema->metadata != NULL) ArrowFree((void*)schema->metadata);
@@ -267,7 +259,7 @@ static void ArrowSchemaRelease(struct ArrowSchema* schema) {
for (int64_t i = 0; i < schema->n_children; i++) {
if (schema->children[i] != NULL) {
if (schema->children[i]->release != NULL) {
- schema->children[i]->release(schema->children[i]);
+ ArrowSchemaRelease(schema->children[i]);
}
ArrowFree(schema->children[i]);
@@ -282,7 +274,7 @@ static void ArrowSchemaRelease(struct ArrowSchema* schema) {
// release() callback.
if (schema->dictionary != NULL) {
if (schema->dictionary->release != NULL) {
- schema->dictionary->release(schema->dictionary);
+ ArrowSchemaRelease(schema->dictionary);
}
ArrowFree(schema->dictionary);
@@ -404,7 +396,7 @@ void ArrowSchemaInit(struct ArrowSchema* schema) {
schema->children = NULL;
schema->dictionary = NULL;
schema->private_data = NULL;
- schema->release = &ArrowSchemaRelease;
+ schema->release = &ArrowSchemaReleaseInternal;
}
ArrowErrorCode ArrowSchemaSetType(struct ArrowSchema* schema, enum ArrowType
type) {
@@ -440,7 +432,7 @@ ArrowErrorCode ArrowSchemaInitFromType(struct ArrowSchema*
schema, enum ArrowTyp
int result = ArrowSchemaSetType(schema, type);
if (result != NANOARROW_OK) {
- schema->release(schema);
+ ArrowSchemaRelease(schema);
return result;
}
@@ -722,7 +714,7 @@ ArrowErrorCode ArrowSchemaDeepCopy(const struct
ArrowSchema* schema,
int result = ArrowSchemaSetFormat(schema_out, schema->format);
if (result != NANOARROW_OK) {
- schema_out->release(schema_out);
+ ArrowSchemaRelease(schema_out);
return result;
}
@@ -730,26 +722,26 @@ ArrowErrorCode ArrowSchemaDeepCopy(const struct
ArrowSchema* schema,
result = ArrowSchemaSetName(schema_out, schema->name);
if (result != NANOARROW_OK) {
- schema_out->release(schema_out);
+ ArrowSchemaRelease(schema_out);
return result;
}
result = ArrowSchemaSetMetadata(schema_out, schema->metadata);
if (result != NANOARROW_OK) {
- schema_out->release(schema_out);
+ ArrowSchemaRelease(schema_out);
return result;
}
result = ArrowSchemaAllocateChildren(schema_out, schema->n_children);
if (result != NANOARROW_OK) {
- schema_out->release(schema_out);
+ ArrowSchemaRelease(schema_out);
return result;
}
for (int64_t i = 0; i < schema->n_children; i++) {
result = ArrowSchemaDeepCopy(schema->children[i], schema_out->children[i]);
if (result != NANOARROW_OK) {
- schema_out->release(schema_out);
+ ArrowSchemaRelease(schema_out);
return result;
}
}
@@ -757,13 +749,13 @@ ArrowErrorCode ArrowSchemaDeepCopy(const struct
ArrowSchema* schema,
if (schema->dictionary != NULL) {
result = ArrowSchemaAllocateDictionary(schema_out);
if (result != NANOARROW_OK) {
- schema_out->release(schema_out);
+ ArrowSchemaRelease(schema_out);
return result;
}
result = ArrowSchemaDeepCopy(schema->dictionary, schema_out->dictionary);
if (result != NANOARROW_OK) {
- schema_out->release(schema_out);
+ ArrowSchemaRelease(schema_out);
return result;
}
}
@@ -1780,7 +1772,7 @@ ArrowErrorCode ArrowMetadataBuilderRemove(struct
ArrowBuffer* buffer,
#include "nanoarrow.h"
-static void ArrowArrayRelease(struct ArrowArray* array) {
+static void ArrowArrayReleaseInternal(struct ArrowArray* array) {
// Release buffers held by this array
struct ArrowArrayPrivateData* private_data =
(struct ArrowArrayPrivateData*)array->private_data;
@@ -1798,7 +1790,7 @@ static void ArrowArrayRelease(struct ArrowArray* array) {
for (int64_t i = 0; i < array->n_children; i++) {
if (array->children[i] != NULL) {
if (array->children[i]->release != NULL) {
- array->children[i]->release(array->children[i]);
+ ArrowArrayRelease(array->children[i]);
}
ArrowFree(array->children[i]);
@@ -1813,7 +1805,7 @@ static void ArrowArrayRelease(struct ArrowArray* array) {
// release() callback.
if (array->dictionary != NULL) {
if (array->dictionary->release != NULL) {
- array->dictionary->release(array->dictionary);
+ ArrowArrayRelease(array->dictionary);
}
ArrowFree(array->dictionary);
@@ -1891,7 +1883,7 @@ ArrowErrorCode ArrowArrayInitFromType(struct ArrowArray*
array,
array->buffers = NULL;
array->children = NULL;
array->dictionary = NULL;
- array->release = &ArrowArrayRelease;
+ array->release = &ArrowArrayReleaseInternal;
array->private_data = NULL;
struct ArrowArrayPrivateData* private_data =
@@ -1913,7 +1905,7 @@ ArrowErrorCode ArrowArrayInitFromType(struct ArrowArray*
array,
int result = ArrowArraySetStorageType(array, storage_type);
if (result != NANOARROW_OK) {
- array->release(array);
+ ArrowArrayRelease(array);
return result;
}
@@ -1938,7 +1930,7 @@ ArrowErrorCode ArrowArrayInitFromArrayView(struct
ArrowArray* array,
if (array_view->n_children > 0) {
result = ArrowArrayAllocateChildren(array, array_view->n_children);
if (result != NANOARROW_OK) {
- array->release(array);
+ ArrowArrayRelease(array);
return result;
}
@@ -1946,7 +1938,7 @@ ArrowErrorCode ArrowArrayInitFromArrayView(struct
ArrowArray* array,
result =
ArrowArrayInitFromArrayView(array->children[i],
array_view->children[i], error);
if (result != NANOARROW_OK) {
- array->release(array);
+ ArrowArrayRelease(array);
return result;
}
}
@@ -1955,14 +1947,14 @@ ArrowErrorCode ArrowArrayInitFromArrayView(struct
ArrowArray* array,
if (array_view->dictionary != NULL) {
result = ArrowArrayAllocateDictionary(array);
if (result != NANOARROW_OK) {
- array->release(array);
+ ArrowArrayRelease(array);
return result;
}
result =
ArrowArrayInitFromArrayView(array->dictionary, array_view->dictionary,
error);
if (result != NANOARROW_OK) {
- array->release(array);
+ ArrowArrayRelease(array);
return result;
}
}
@@ -3019,12 +3011,12 @@ static void ArrowBasicArrayStreamRelease(struct
ArrowArrayStream* array_stream)
(struct BasicArrayStreamPrivate*)array_stream->private_data;
if (private_data->schema.release != NULL) {
- private_data->schema.release(&private_data->schema);
+ ArrowSchemaRelease(&private_data->schema);
}
for (int64_t i = 0; i < private_data->n_arrays; i++) {
if (private_data->arrays[i].release != NULL) {
- private_data->arrays[i].release(&private_data->arrays[i]);
+ ArrowArrayRelease(&private_data->arrays[i]);
}
}
diff --git a/dist/nanoarrow.h b/dist/nanoarrow.h
index d0fea4a..8fde828 100644
--- a/dist/nanoarrow.h
+++ b/dist/nanoarrow.h
@@ -162,25 +162,6 @@ struct ArrowArrayStream {
#endif // ARROW_C_STREAM_INTERFACE
#endif // ARROW_FLAG_DICTIONARY_ORDERED
-/// \brief Move the contents of src into dst and set src->release to NULL
-static inline void ArrowSchemaMove(struct ArrowSchema* src, struct
ArrowSchema* dst) {
- memcpy(dst, src, sizeof(struct ArrowSchema));
- src->release = NULL;
-}
-
-/// \brief Move the contents of src into dst and set src->release to NULL
-static inline void ArrowArrayMove(struct ArrowArray* src, struct ArrowArray*
dst) {
- memcpy(dst, src, sizeof(struct ArrowArray));
- src->release = NULL;
-}
-
-/// \brief Move the contents of src into dst and set src->release to NULL
-static inline void ArrowArrayStreamMove(struct ArrowArrayStream* src,
- struct ArrowArrayStream* dst) {
- memcpy(dst, src, sizeof(struct ArrowArrayStream));
- src->release = NULL;
-}
-
/// @}
// Utility macros
@@ -228,6 +209,55 @@ static inline void ArrowArrayStreamMove(struct
ArrowArrayStream* src,
/// \ingroup nanoarrow-errors
typedef int ArrowErrorCode;
+/// \brief Error type containing a UTF-8 encoded message.
+/// \ingroup nanoarrow-errors
+struct ArrowError {
+ /// \brief A character buffer with space for an error message.
+ char message[1024];
+};
+
+/// \brief Ensure an ArrowError is null-terminated by zeroing the first
character.
+/// \ingroup nanoarrow-errors
+///
+/// If error is NULL, this function does nothing.
+static inline void ArrowErrorInit(struct ArrowError* error) {
+ if (error != NULL) {
+ error->message[0] = '\0';
+ }
+}
+
+/// \brief Get the contents of an error
+/// \ingroup nanoarrow-errors
+///
+/// If error is NULL, returns "", or returns the contents of the error message
+/// otherwise.
+static inline const char* ArrowErrorMessage(struct ArrowError* error) {
+ if (error == NULL) {
+ return "";
+ } else {
+ return error->message;
+ }
+}
+
+/// \brief Set the contents of an error from an existing null-terminated string
+/// \ingroup nanoarrow-errors
+///
+/// If error is NULL, this function does nothing.
+static inline void ArrowErrorSetString(struct ArrowError* error, const char*
src) {
+ if (error == NULL) {
+ return;
+ }
+
+ int64_t src_len = strlen(src);
+ if (src_len >= ((int64_t)sizeof(error->message))) {
+ memcpy(error->message, src, sizeof(error->message) - 1);
+ error->message[sizeof(error->message) - 1] = '\0';
+ } else {
+ memcpy(error->message, src, src_len);
+ error->message[src_len] = '\0';
+ }
+}
+
/// \brief Check the result of an expression and return it if not NANOARROW_OK
/// \ingroup nanoarrow-errors
#define NANOARROW_RETURN_NOT_OK(EXPR) \
@@ -245,11 +275,11 @@ typedef int ArrowErrorCode;
_NANOARROW_MAKE_NAME(errno_status_, __COUNTER__), EXPR, ERROR_EXPR,
#EXPR)
#if defined(NANOARROW_DEBUG) && !defined(NANOARROW_PRINT_AND_DIE)
-#define NANOARROW_PRINT_AND_DIE(VALUE, EXPR_STR)
\
- do {
\
- fprintf(stderr, "%s failed with errno %d\n* %s:%d\n", EXPR_STR,
(int)(VALUE), \
- __FILE__, (int)__LINE__);
\
- abort();
\
+#define NANOARROW_PRINT_AND_DIE(VALUE, EXPR_STR)
\
+ do {
\
+ fprintf(stderr, "%s failed with code %d\n* %s:%d\n", EXPR_STR,
(int)(VALUE), \
+ __FILE__, (int)__LINE__);
\
+ abort();
\
} while (0)
#endif
@@ -270,10 +300,99 @@ typedef int ArrowErrorCode;
/// This macro is provided as a convenience for users and is not used
internally.
#define NANOARROW_ASSERT_OK(EXPR) \
_NANOARROW_ASSERT_OK_IMPL(_NANOARROW_MAKE_NAME(errno_status_, __COUNTER__),
EXPR, #EXPR)
+
+#define _NANOARROW_DCHECK_IMPL(EXPR, EXPR_STR) \
+ do { \
+ if (!(EXPR)) NANOARROW_PRINT_AND_DIE(-1, EXPR_STR); \
+ } while (0)
+
+#define NANOARROW_DCHECK(EXPR) _NANOARROW_DCHECK_IMPL(EXPR, #EXPR)
#else
#define NANOARROW_ASSERT_OK(EXPR) EXPR
+#define NANOARROW_DCHECK(EXPR)
#endif
+static inline void ArrowSchemaMove(struct ArrowSchema* src, struct
ArrowSchema* dst) {
+ NANOARROW_DCHECK(src != NULL);
+ NANOARROW_DCHECK(dst != NULL);
+
+ memcpy(dst, src, sizeof(struct ArrowSchema));
+ src->release = NULL;
+}
+
+static inline void ArrowSchemaRelease(struct ArrowSchema* schema) {
+ NANOARROW_DCHECK(schema != NULL);
+ schema->release(schema);
+ NANOARROW_DCHECK(schema->release == NULL);
+}
+
+static inline void ArrowArrayMove(struct ArrowArray* src, struct ArrowArray*
dst) {
+ NANOARROW_DCHECK(src != NULL);
+ NANOARROW_DCHECK(dst != NULL);
+
+ memcpy(dst, src, sizeof(struct ArrowArray));
+ src->release = NULL;
+}
+
+static inline void ArrowArrayRelease(struct ArrowArray* array) {
+ NANOARROW_DCHECK(array != NULL);
+ array->release(array);
+ NANOARROW_DCHECK(array->release == NULL);
+}
+
+static inline void ArrowArrayStreamMove(struct ArrowArrayStream* src,
+ struct ArrowArrayStream* dst) {
+ NANOARROW_DCHECK(src != NULL);
+ NANOARROW_DCHECK(dst != NULL);
+
+ memcpy(dst, src, sizeof(struct ArrowArrayStream));
+ src->release = NULL;
+}
+
+static inline const char* ArrowArrayStreamGetLastError(
+ struct ArrowArrayStream* array_stream) {
+ NANOARROW_DCHECK(array_stream != NULL);
+
+ const char* value = array_stream->get_last_error(array_stream);
+ if (value == NULL) {
+ return "";
+ } else {
+ return value;
+ }
+}
+
+static inline ArrowErrorCode ArrowArrayStreamGetSchema(
+ struct ArrowArrayStream* array_stream, struct ArrowSchema* out,
+ struct ArrowError* error) {
+ NANOARROW_DCHECK(array_stream != NULL);
+
+ int result = array_stream->get_schema(array_stream, out);
+ if (result != NANOARROW_OK && error != NULL) {
+ ArrowErrorSetString(error, ArrowArrayStreamGetLastError(array_stream));
+ }
+
+ return result;
+}
+
+static inline ArrowErrorCode ArrowArrayStreamGetNext(
+ struct ArrowArrayStream* array_stream, struct ArrowArray* out,
+ struct ArrowError* error) {
+ NANOARROW_DCHECK(array_stream != NULL);
+
+ int result = array_stream->get_next(array_stream, out);
+ if (result != NANOARROW_OK && error != NULL) {
+ ArrowErrorSetString(error, ArrowArrayStreamGetLastError(array_stream));
+ }
+
+ return result;
+}
+
+static inline void ArrowArrayStreamRelease(struct ArrowArrayStream*
array_stream) {
+ NANOARROW_DCHECK(array_stream != NULL);
+ array_stream->release(array_stream);
+ NANOARROW_DCHECK(array_stream->release == NULL);
+}
+
static char _ArrowIsLittleEndian(void) {
uint32_t check = 1;
char first_byte;
@@ -849,7 +968,6 @@ static inline void ArrowDecimalSetBytes(struct
ArrowDecimal* decimal,
#define ArrowNanoarrowVersion NANOARROW_SYMBOL(NANOARROW_NAMESPACE,
ArrowNanoarrowVersion)
#define ArrowNanoarrowVersionInt \
NANOARROW_SYMBOL(NANOARROW_NAMESPACE, ArrowNanoarrowVersionInt)
-#define ArrowErrorMessage NANOARROW_SYMBOL(NANOARROW_NAMESPACE,
ArrowErrorMessage)
#define ArrowMalloc NANOARROW_SYMBOL(NANOARROW_NAMESPACE, ArrowMalloc)
#define ArrowRealloc NANOARROW_SYMBOL(NANOARROW_NAMESPACE, ArrowRealloc)
#define ArrowFree NANOARROW_SYMBOL(NANOARROW_NAMESPACE, ArrowFree)
@@ -995,6 +1113,60 @@ struct ArrowBufferAllocator ArrowBufferDeallocator(
/// @}
+/// \brief Move the contents of an src ArrowSchema into dst and set
src->release to NULL
+/// \ingroup nanoarrow-arrow-cdata
+static inline void ArrowSchemaMove(struct ArrowSchema* src, struct
ArrowSchema* dst);
+
+/// \brief Call the release callback of an ArrowSchema
+/// \ingroup nanoarrow-arrow-cdata
+static inline void ArrowSchemaRelease(struct ArrowSchema* schema);
+
+/// \brief Move the contents of an src ArrowArray into dst and set
src->release to NULL
+/// \ingroup nanoarrow-arrow-cdata
+static inline void ArrowArrayMove(struct ArrowArray* src, struct ArrowArray*
dst);
+
+/// \brief Call the release callback of an ArrowArray
+static inline void ArrowArrayRelease(struct ArrowArray* array);
+
+/// \brief Move the contents of an src ArrowArrayStream into dst and set
src->release to
+/// NULL \ingroup nanoarrow-arrow-cdata
+static inline void ArrowArrayStreamMove(struct ArrowArrayStream* src,
+ struct ArrowArrayStream* dst);
+
+/// \brief Call the get_schema callback of an ArrowArrayStream
+/// \ingroup nanoarrow-arrow-cdata
+///
+/// Unlike the get_schema callback, this wrapper checks the return code
+/// and propagates the error reported by get_last_error into error. This
+/// makes it significantly less verbose to iterate over array streams
+/// using NANOARROW_RETURN_NOT_OK()-style error handling.
+static inline ArrowErrorCode ArrowArrayStreamGetSchema(
+ struct ArrowArrayStream* array_stream, struct ArrowSchema* out,
+ struct ArrowError* error);
+
+/// \brief Call the get_schema callback of an ArrowArrayStream
+/// \ingroup nanoarrow-arrow-cdata
+///
+/// Unlike the get_next callback, this wrapper checks the return code
+/// and propagates the error reported by get_last_error into error. This
+/// makes it significantly less verbose to iterate over array streams
+/// using NANOARROW_RETURN_NOT_OK()-style error handling.
+static inline ArrowErrorCode ArrowArrayStreamGetNext(
+ struct ArrowArrayStream* array_stream, struct ArrowArray* out,
+ struct ArrowError* error);
+
+/// \brief Call the get_next callback of an ArrowArrayStream
+/// \ingroup nanoarrow-arrow-cdata
+///
+/// Unlike the get_next callback, this function never returns NULL (i.e., its
+/// result is safe to use in printf-style error formatters). Null values from
the
+/// original callback are reported as "<get_last_error() returned NULL>".
+static inline const char* ArrowArrayStreamGetLastError(
+ struct ArrowArrayStream* array_stream);
+
+/// \brief Call the release callback of an ArrowArrayStream
+static inline void ArrowArrayStreamRelease(struct ArrowArrayStream*
array_stream);
+
/// \defgroup nanoarrow-errors Error handling
///
/// Functions generally return an errno-compatible error code; functions that
@@ -1014,32 +1186,11 @@ struct ArrowBufferAllocator ArrowBufferDeallocator(
///
/// @{
-/// \brief Error type containing a UTF-8 encoded message.
-struct ArrowError {
- /// \brief A character buffer with space for an error message.
- char message[1024];
-};
-
-/// \brief Ensure an ArrowError is null-terminated by zeroing the first
character.
-///
-/// If error is NULL, this function does nothing.
-static inline void ArrowErrorInit(struct ArrowError* error) {
- if (error) {
- error->message[0] = '\0';
- }
-}
-
/// \brief Set the contents of an error using printf syntax.
///
/// If error is NULL, this function does nothing and returns NANOARROW_OK.
ArrowErrorCode ArrowErrorSet(struct ArrowError* error, const char* fmt, ...);
-/// \brief Get the contents of an error
-///
-/// If error is NULL, returns "", or returns the contents of the error message
-/// otherwise.
-const char* ArrowErrorMessage(struct ArrowError* error);
-
/// @}
/// \defgroup nanoarrow-utils Utility data structures
diff --git a/dist/nanoarrow.hpp b/dist/nanoarrow.hpp
index 2638769..15914ce 100644
--- a/dist/nanoarrow.hpp
+++ b/dist/nanoarrow.hpp
@@ -88,70 +88,108 @@ namespace internal {
///
/// @{
-static inline void init_pointer(struct ArrowSchema* data) { data->release =
nullptr; }
+template <typename T>
+static inline void init_pointer(T* data);
+
+template <typename T>
+static inline void move_pointer(T* src, T* dst);
+
+template <typename T>
+static inline void release_pointer(T* data);
+
+template <>
+inline void init_pointer(struct ArrowSchema* data) {
+ data->release = nullptr;
+}
-static inline void move_pointer(struct ArrowSchema* src, struct ArrowSchema*
dst) {
+template <>
+inline void move_pointer(struct ArrowSchema* src, struct ArrowSchema* dst) {
ArrowSchemaMove(src, dst);
}
-static inline void release_pointer(struct ArrowSchema* data) {
+template <>
+inline void release_pointer(struct ArrowSchema* data) {
if (data->release != nullptr) {
data->release(data);
}
}
-static inline void init_pointer(struct ArrowArray* data) { data->release =
nullptr; }
+template <>
+inline void init_pointer(struct ArrowArray* data) {
+ data->release = nullptr;
+}
-static inline void move_pointer(struct ArrowArray* src, struct ArrowArray*
dst) {
+template <>
+inline void move_pointer(struct ArrowArray* src, struct ArrowArray* dst) {
ArrowArrayMove(src, dst);
}
-static inline void release_pointer(struct ArrowArray* data) {
+template <>
+inline void release_pointer(struct ArrowArray* data) {
if (data->release != nullptr) {
data->release(data);
}
}
-static inline void init_pointer(struct ArrowArrayStream* data) {
+template <>
+inline void init_pointer(struct ArrowArrayStream* data) {
data->release = nullptr;
}
-static inline void move_pointer(struct ArrowArrayStream* src,
- struct ArrowArrayStream* dst) {
+template <>
+inline void move_pointer(struct ArrowArrayStream* src, struct
ArrowArrayStream* dst) {
ArrowArrayStreamMove(src, dst);
}
-static inline void release_pointer(ArrowArrayStream* data) {
+template <>
+inline void release_pointer(ArrowArrayStream* data) {
if (data->release != nullptr) {
data->release(data);
}
}
-static inline void init_pointer(struct ArrowBuffer* data) {
ArrowBufferInit(data); }
+template <>
+inline void init_pointer(struct ArrowBuffer* data) {
+ ArrowBufferInit(data);
+}
-static inline void move_pointer(struct ArrowBuffer* src, struct ArrowBuffer*
dst) {
+template <>
+inline void move_pointer(struct ArrowBuffer* src, struct ArrowBuffer* dst) {
ArrowBufferMove(src, dst);
}
-static inline void release_pointer(struct ArrowBuffer* data) {
ArrowBufferReset(data); }
+template <>
+inline void release_pointer(struct ArrowBuffer* data) {
+ ArrowBufferReset(data);
+}
-static inline void init_pointer(struct ArrowBitmap* data) {
ArrowBitmapInit(data); }
+template <>
+inline void init_pointer(struct ArrowBitmap* data) {
+ ArrowBitmapInit(data);
+}
-static inline void move_pointer(struct ArrowBitmap* src, struct ArrowBitmap*
dst) {
+template <>
+inline void move_pointer(struct ArrowBitmap* src, struct ArrowBitmap* dst) {
ArrowBitmapMove(src, dst);
}
-static inline void release_pointer(struct ArrowBitmap* data) {
ArrowBitmapReset(data); }
+template <>
+inline void release_pointer(struct ArrowBitmap* data) {
+ ArrowBitmapReset(data);
+}
-static inline void init_pointer(struct ArrowArrayView* data) {
+template <>
+inline void init_pointer(struct ArrowArrayView* data) {
ArrowArrayViewInitFromType(data, NANOARROW_TYPE_UNINITIALIZED);
}
-static inline void move_pointer(struct ArrowArrayView* src, struct
ArrowArrayView* dst) {
+template <>
+inline void move_pointer(struct ArrowArrayView* src, struct ArrowArrayView*
dst) {
ArrowArrayViewMove(src, dst);
}
-static inline void release_pointer(struct ArrowArrayView* data) {
+template <>
+inline void release_pointer(struct ArrowArrayView* data) {
ArrowArrayViewReset(data);
}
@@ -231,28 +269,124 @@ using UniqueArrayView = internal::Unique<struct
ArrowArrayView>;
/// \defgroup nanoarrow_hpp-array-stream ArrayStream helpers
///
-/// These classes provide simple struct ArrowArrayStream implementations that
+/// These classes provide simple ArrowArrayStream implementations that
/// can be extended to help simplify the process of creating a valid
/// ArrowArrayStream implementation or used as-is for testing.
///
/// @{
+/// @brief Export an ArrowArrayStream from a standard C++ class
+/// @tparam T A class with methods `int GetSchema(ArrowSchema*)`, `int
+/// GetNext(ArrowArray*)`, and `const char* GetLastError()`
+///
+/// This class allows a standard C++ class to be exported to a generic
ArrowArrayStream
+/// consumer by mapping C callback invocations to method calls on an instance
of the
+/// object whose lifecycle is owned by the ArrowArrayStream. See
VectorArrayStream for
+/// minimal useful example of this pattern.
+///
+/// The methods must be accessible to the ArrayStreamFactory, either as public
methods or
+/// by declaring ArrayStreamFactory<ImplClass> a friend. Implementors are
encouraged (but
+/// not required) to implement a ToArrayStream(ArrowArrayStream*) that creates
a new
+/// instance owned by the ArrowArrayStream and moves the relevant data to that
instance.
+///
+/// An example implementation might be:
+///
+/// \code
+/// class StreamImpl {
+/// public:
+/// // Public methods (e.g., constructor) used from C++ to initialize
relevant data
+///
+/// // Idiomatic exporter to move data + lifecycle responsibility to an
instance
+/// // managed by the ArrowArrayStream callbacks
+/// void ToArrayStream(struct ArrowArrayStream* out) {
+/// ArrayStreamFactory<StreamImpl>::InitArrayStream(new StreamImpl(...),
out);
+/// }
+///
+/// private:
+/// // Make relevant methods available to the ArrayStreamFactory
+/// friend class ArrayStreamFactory<StreamImpl>;
+///
+/// // Method implementations (called from C, not normally interacted with
from C++)
+/// int GetSchema(struct ArrowSchema* schema) { return ENOTSUP; }
+/// int GetNext(struct ArrowArray* array) { return ENOTSUP; }
+/// const char* GetLastError() { nullptr; }
+/// };
+/// \endcode
+///
+/// An example usage might be:
+///
+/// \code
+/// // Call constructor and/or public methods to initialize relevant data
+/// StreamImpl impl;
+///
+/// // Export to ArrowArrayStream after data are finalized
+/// UniqueArrayStream stream;
+/// impl.ToArrayStream(stream.get());
+/// \endcode
+template <typename T>
+class ArrayStreamFactory {
+ public:
+ /// \brief Take ownership of instance and populate callbacks of out
+ static void InitArrayStream(T* instance, struct ArrowArrayStream* out) {
+ out->get_schema = &get_schema_wrapper;
+ out->get_next = &get_next_wrapper;
+ out->get_last_error = &get_last_error_wrapper;
+ out->release = &release_wrapper;
+ out->private_data = instance;
+ }
+
+ private:
+ static int get_schema_wrapper(struct ArrowArrayStream* stream,
+ struct ArrowSchema* schema) {
+ return reinterpret_cast<T*>(stream->private_data)->GetSchema(schema);
+ }
+
+ static int get_next_wrapper(struct ArrowArrayStream* stream, struct
ArrowArray* array) {
+ return reinterpret_cast<T*>(stream->private_data)->GetNext(array);
+ }
+
+ static const char* get_last_error_wrapper(struct ArrowArrayStream* stream) {
+ return reinterpret_cast<T*>(stream->private_data)->GetLastError();
+ }
+
+ static void release_wrapper(struct ArrowArrayStream* stream) {
+ delete reinterpret_cast<T*>(stream->private_data);
+ stream->release = nullptr;
+ stream->private_data = nullptr;
+ }
+};
+
/// \brief An empty array stream
///
-/// This class can be constructed from an enum ArrowType or
-/// struct ArrowSchema and implements a default get_next() method that
-/// always marks the output ArrowArray as released. This class can
-/// be extended with an implementation of get_next() for a custom
-/// source.
+/// 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
+ ///
+ /// Takes ownership of schema.
+ EmptyArrayStream(struct ArrowSchema* schema) : schema_(schema) {
+ ArrowErrorInit(&error_);
+ }
+
+ /// \brief Export to ArrowArrayStream
+ void ToArrayStream(struct ArrowArrayStream* out) {
+ EmptyArrayStream* impl = new EmptyArrayStream(schema_.get());
+ ArrayStreamFactory<EmptyArrayStream>::InitArrayStream(impl, out);
+ }
+
/// \brief Create an empty UniqueArrayStream from a struct ArrowSchema
///
- /// This object takes ownership of the schema and marks the source schema
- /// as released.
+ /// DEPRECATED (0.4.0): Use the constructor + ToArrayStream() to export an
+ /// EmptyArrayStream to an ArrowArrayStream consumer.
static UniqueArrayStream MakeUnique(struct ArrowSchema* schema) {
UniqueArrayStream stream;
- (new EmptyArrayStream(schema))->MakeStream(stream.get());
+ EmptyArrayStream(schema).ToArrayStream(stream.get());
return stream;
}
@@ -262,17 +396,7 @@ class EmptyArrayStream {
UniqueSchema schema_;
struct ArrowError error_;
- EmptyArrayStream(struct ArrowSchema* schema) : schema_(schema) {
- error_.message[0] = '\0';
- }
-
- void MakeStream(struct ArrowArrayStream* stream) {
- stream->get_schema = &get_schema_wrapper;
- stream->get_next = &get_next_wrapper;
- stream->get_last_error = &get_last_error_wrapper;
- stream->release = &release_wrapper;
- stream->private_data = this;
- }
+ void MakeStream(struct ArrowArrayStream* stream) { ToArrayStream(stream); }
virtual int get_schema(struct ArrowSchema* schema) {
return ArrowSchemaDeepCopy(schema_.get(), schema);
@@ -286,54 +410,72 @@ class EmptyArrayStream {
virtual const char* get_last_error() { return error_.message; }
private:
- static int get_schema_wrapper(struct ArrowArrayStream* stream,
- struct ArrowSchema* schema) {
- return
reinterpret_cast<EmptyArrayStream*>(stream->private_data)->get_schema(schema);
- }
+ friend class ArrayStreamFactory<EmptyArrayStream>;
- static int get_next_wrapper(struct ArrowArrayStream* stream, struct
ArrowArray* array) {
- return
reinterpret_cast<EmptyArrayStream*>(stream->private_data)->get_next(array);
- }
+ int GetSchema(struct ArrowSchema* schema) { return get_schema(schema); }
- static const char* get_last_error_wrapper(struct ArrowArrayStream* stream) {
- return
reinterpret_cast<EmptyArrayStream*>(stream->private_data)->get_last_error();
- }
+ int GetNext(struct ArrowArray* array) { return get_next(array); }
- static void release_wrapper(struct ArrowArrayStream* stream) {
- delete reinterpret_cast<EmptyArrayStream*>(stream->private_data);
- stream->release = nullptr;
- stream->private_data = nullptr;
- }
+ const char* GetLastError() { return get_last_error(); }
};
-/// \brief Implementation of an ArrowArrayStream backed by a vector of
ArrowArray objects
-class VectorArrayStream : public EmptyArrayStream {
+/// \brief Implementation of an ArrowArrayStream backed by a vector of
UniqueArray objects
+class VectorArrayStream {
public:
+ /// \brief Create a VectorArrayStream from an ArrowSchema + vector of
UniqueArray
+ ///
+ /// Takes ownership of schema and moves arrays if possible.
+ VectorArrayStream(struct ArrowSchema* schema, std::vector<UniqueArray>
arrays)
+ : offset_(0), schema_(schema), arrays_(std::move(arrays)) {}
+
+ /// \brief Create a one-shot VectorArrayStream from an ArrowSchema +
ArrowArray
+ ///
+ /// Takes ownership of schema and array.
+ VectorArrayStream(struct ArrowSchema* schema, struct ArrowArray* array)
+ : offset_(0), schema_(schema) {
+ arrays_.emplace_back(array);
+ }
+
+ /// \brief Export to ArrowArrayStream
+ void ToArrayStream(struct ArrowArrayStream* out) {
+ VectorArrayStream* impl = new VectorArrayStream(schema_.get(),
std::move(arrays_));
+ ArrayStreamFactory<VectorArrayStream>::InitArrayStream(impl, out);
+ }
+
/// \brief Create a UniqueArrowArrayStream from an existing array
///
- /// Takes ownership of the schema and the 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) {
- std::vector<UniqueArray> arrays;
- arrays.emplace_back(array);
- return MakeUnique(schema, std::move(arrays));
+ UniqueArrayStream stream;
+ VectorArrayStream(schema, array).ToArrayStream(stream.get());
+ return stream;
}
/// \brief Create a UniqueArrowArrayStream from existing arrays
///
- /// This object takes ownership of the schema and 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;
- (new VectorArrayStream(schema,
std::move(arrays)))->MakeStream(stream.get());
+ VectorArrayStream(schema, std::move(arrays)).ToArrayStream(stream.get());
return stream;
}
- protected:
- VectorArrayStream(struct ArrowSchema* schema, std::vector<UniqueArray>
arrays)
- : EmptyArrayStream(schema), arrays_(std::move(arrays)), offset_(0) {}
+ private:
+ int64_t offset_;
+ UniqueSchema schema_;
+ std::vector<UniqueArray> arrays_;
+
+ friend class ArrayStreamFactory<VectorArrayStream>;
- int get_next(struct ArrowArray* array) {
+ int GetSchema(struct ArrowSchema* schema) {
+ return ArrowSchemaDeepCopy(schema_.get(), schema);
+ }
+
+ int GetNext(struct ArrowArray* array) {
if (offset_ < static_cast<int64_t>(arrays_.size())) {
arrays_[offset_++].move(array);
} else {
@@ -343,9 +485,7 @@ class VectorArrayStream : public EmptyArrayStream {
return NANOARROW_OK;
}
- private:
- std::vector<UniqueArray> arrays_;
- int64_t offset_;
+ const char* GetLastError() { return ""; }
};
/// @}
diff --git a/dist/nanoarrow_device.c b/dist/nanoarrow_device.c
index c4df3d1..0c76d96 100644
--- a/dist/nanoarrow_device.c
+++ b/dist/nanoarrow_device.c
@@ -226,7 +226,7 @@ static int ArrowDeviceBasicArrayStreamGetNext(struct
ArrowDeviceArrayStream* arr
private_data->naive_stream.get_next(&private_data->naive_stream, &tmp));
int result = ArrowDeviceArrayInit(private_data->device, device_array, &tmp);
if (result != NANOARROW_OK) {
- tmp.release(&tmp);
+ ArrowArrayRelease(&tmp);
return result;
}
@@ -244,7 +244,7 @@ static void ArrowDeviceBasicArrayStreamRelease(
struct ArrowDeviceArrayStream* array_stream) {
struct ArrowBasicDeviceArrayStreamPrivate* private_data =
(struct ArrowBasicDeviceArrayStreamPrivate*)array_stream->private_data;
- private_data->naive_stream.release(&private_data->naive_stream);
+ ArrowArrayStreamRelease(&private_data->naive_stream);
ArrowFree(private_data);
array_stream->release = NULL;
}
@@ -439,19 +439,19 @@ ArrowErrorCode ArrowDeviceArrayViewCopy(struct
ArrowDeviceArrayView* src,
int result =
ArrowDeviceArrayViewCopyInternal(src->device, &src->array_view,
device_dst, &tmp);
if (result != NANOARROW_OK) {
- tmp.release(&tmp);
+ ArrowArrayRelease(&tmp);
return result;
}
result = ArrowArrayFinishBuilding(&tmp, NANOARROW_VALIDATION_LEVEL_MINIMAL,
NULL);
if (result != NANOARROW_OK) {
- tmp.release(&tmp);
+ ArrowArrayRelease(&tmp);
return result;
}
result = ArrowDeviceArrayInit(device_dst, dst, &tmp);
if (result != NANOARROW_OK) {
- tmp.release(&tmp);
+ ArrowArrayRelease(&tmp);
return result;
}
diff --git a/dist/nanoarrow_ipc.c b/dist/nanoarrow_ipc.c
index a37b910..54e7468 100644
--- a/dist/nanoarrow_ipc.c
+++ b/dist/nanoarrow_ipc.c
@@ -20517,7 +20517,7 @@ void ArrowIpcDecoderReset(struct ArrowIpcDecoder*
decoder) {
ArrowArrayViewReset(&private_data->array_view);
if (private_data->array.release != NULL) {
- private_data->array.release(&private_data->array);
+ ArrowArrayRelease(&private_data->array);
}
if (private_data->fields != NULL) {
@@ -21388,7 +21388,7 @@ ArrowErrorCode ArrowIpcDecoderDecodeSchema(struct
ArrowIpcDecoder* decoder,
ArrowSchemaInit(&tmp);
int result = ArrowSchemaSetTypeStruct(&tmp, n_fields);
if (result != NANOARROW_OK) {
- tmp.release(&tmp);
+ ArrowSchemaRelease(&tmp);
ArrowErrorSet(error, "Failed to allocate struct schema with %ld children",
(long)n_fields);
return result;
@@ -21396,13 +21396,13 @@ ArrowErrorCode ArrowIpcDecoderDecodeSchema(struct
ArrowIpcDecoder* decoder,
result = ArrowIpcDecoderSetChildren(&tmp, fields, error);
if (result != NANOARROW_OK) {
- tmp.release(&tmp);
+ ArrowSchemaRelease(&tmp);
return result;
}
result = ArrowIpcDecoderSetMetadata(&tmp,
ns(Schema_custom_metadata(schema)), error);
if (result != NANOARROW_OK) {
- tmp.release(&tmp);
+ ArrowSchemaRelease(&tmp);
return result;
}
@@ -21449,7 +21449,7 @@ ArrowErrorCode ArrowIpcDecoderSetSchema(struct
ArrowIpcDecoder* decoder,
private_data->n_fields = 0;
ArrowArrayViewReset(&private_data->array_view);
if (private_data->array.release != NULL) {
- private_data->array.release(&private_data->array);
+ ArrowArrayRelease(&private_data->array);
}
if (private_data->fields != NULL) {
ArrowFree(private_data->fields);
@@ -21946,7 +21946,7 @@ ArrowErrorCode ArrowIpcDecoderDecodeArray(struct
ArrowIpcDecoder* decoder,
int result =
ArrowIpcDecoderDecodeArrayInternal(decoder, i, &temp, validation_level,
error);
if (result != NANOARROW_OK && temp.release != NULL) {
- temp.release(&temp);
+ ArrowArrayRelease(&temp);
} else if (result != NANOARROW_OK) {
return result;
}
@@ -21970,7 +21970,7 @@ ArrowErrorCode ArrowIpcDecoderDecodeArrayFromShared(
int result =
ArrowIpcDecoderDecodeArrayInternal(decoder, i, &temp, validation_level,
error);
if (result != NANOARROW_OK && temp.release != NULL) {
- temp.release(&temp);
+ ArrowArrayRelease(&temp);
} else if (result != NANOARROW_OK) {
return result;
}
@@ -22169,7 +22169,7 @@ static void ArrowIpcArrayStreamReaderRelease(struct
ArrowArrayStream* stream) {
ArrowIpcDecoderReset(&private_data->decoder);
if (private_data->out_schema.release != NULL) {
- private_data->out_schema.release(&private_data->out_schema);
+ ArrowSchemaRelease(&private_data->out_schema);
}
ArrowBufferReset(&private_data->header);
@@ -22306,7 +22306,7 @@ static int ArrowIpcArrayStreamReaderReadSchemaIfNeeded(
// Only support "read the whole thing" for now
if (private_data->field_index != -1) {
- tmp.release(&tmp);
+ ArrowSchemaRelease(&tmp);
ArrowErrorSet(&private_data->error, "Field index != -1 is not yet
supported");
return ENOTSUP;
}
@@ -22315,7 +22315,7 @@ static int ArrowIpcArrayStreamReaderReadSchemaIfNeeded(
int result =
ArrowIpcDecoderSetSchema(&private_data->decoder, &tmp,
&private_data->error);
if (result != NANOARROW_OK) {
- tmp.release(&tmp);
+ ArrowSchemaRelease(&tmp);
return result;
}
diff --git a/dist/nanoarrow_testing.hpp b/dist/nanoarrow_testing.hpp
index c2502a1..dbcc4f4 100644
--- a/dist/nanoarrow_testing.hpp
+++ b/dist/nanoarrow_testing.hpp
@@ -67,7 +67,7 @@ class TestingJSONWriter {
out << R"({"schema": )";
nanoarrow::UniqueSchema schema;
- NANOARROW_RETURN_NOT_OK(stream->get_schema(stream, schema.get()));
+ NANOARROW_RETURN_NOT_OK(ArrowArrayStreamGetSchema(stream, schema.get(),
nullptr));
NANOARROW_RETURN_NOT_OK(WriteSchema(out, schema.get()));
nanoarrow::UniqueArrayView array_view;
@@ -79,7 +79,7 @@ class TestingJSONWriter {
nanoarrow::UniqueArray array;
std::string sep;
do {
- NANOARROW_RETURN_NOT_OK(stream->get_next(stream, array.get()));
+ NANOARROW_RETURN_NOT_OK(ArrowArrayStreamGetNext(stream, array.get(),
nullptr));
if (array->release == nullptr) {
break;
}
@@ -733,11 +733,18 @@ class TestingJSONReader {
using json = nlohmann::json;
public:
+ TestingJSONReader(ArrowBufferAllocator allocator) : allocator_(allocator) {}
+ TestingJSONReader() : TestingJSONReader(ArrowBufferAllocatorDefault()) {}
+
+ static const int kNumBatchOnlySchema = -2;
+ static const int kNumBatchReadAll = -1;
+
/// \brief Read JSON representing a data file object
///
/// Read a JSON object in the form `{"schema": {...}, "batches": [...],
...}`,
/// propagating `out` on success.
ArrowErrorCode ReadDataFile(const std::string& data_file_json,
ArrowArrayStream* out,
+ int num_batch = kNumBatchReadAll,
ArrowError* error = nullptr) {
try {
auto obj = json::parse(data_file_json);
@@ -760,18 +767,34 @@ class TestingJSONReader {
NANOARROW_RETURN_NOT_OK(
ArrowArrayViewInitFromSchema(array_view.get(), schema.get(), error));
+ // Get a vector of batch ids to parse
+ std::vector<size_t> batch_ids;
+ if (num_batch == kNumBatchOnlySchema) {
+ batch_ids.resize(0);
+ } else if (num_batch == kNumBatchReadAll) {
+ batch_ids.resize(batches.size());
+ std::iota(batch_ids.begin(), batch_ids.end(), 0);
+ } else if (num_batch >= 0 && num_batch < batches.size()) {
+ batch_ids.push_back(num_batch);
+ } else {
+ ArrowErrorSet(error, "Expected num_batch between 0 and %d but got %d",
+ static_cast<int>(batches.size() - 1), num_batch);
+ return EINVAL;
+ }
+
// Initialize ArrayStream with required capacity
nanoarrow::UniqueArrayStream stream;
NANOARROW_RETURN_NOT_OK_WITH_ERROR(
- ArrowBasicArrayStreamInit(stream.get(), schema.get(),
batches.size()), error);
+ ArrowBasicArrayStreamInit(stream.get(), schema.get(),
batch_ids.size()), error);
// Populate ArrayStream batches
- for (size_t i = 0; i < batches.size(); i++) {
+ for (size_t i = 0; i < batch_ids.size(); i++) {
nanoarrow::UniqueArray array;
NANOARROW_RETURN_NOT_OK(
ArrowArrayInitFromArrayView(array.get(), array_view.get(), error));
+ SetArrayAllocatorRecursive(array.get());
NANOARROW_RETURN_NOT_OK(
- SetArrayBatch(batches[i], array_view.get(), array.get(), error));
+ SetArrayBatch(batches[batch_ids[i]], array_view.get(),
array.get(), error));
ArrowBasicArrayStreamSetArray(stream.get(), i, array.get());
}
@@ -839,6 +862,7 @@ class TestingJSONReader {
// ArrowArray to hold memory
nanoarrow::UniqueArray array;
NANOARROW_RETURN_NOT_OK(ArrowArrayInitFromSchema(array.get(), schema,
error));
+ SetArrayAllocatorRecursive(array.get());
NANOARROW_RETURN_NOT_OK(SetArrayBatch(obj, array_view.get(),
array.get(), error));
ArrowArrayMove(array.get(), out);
@@ -867,6 +891,7 @@ class TestingJSONReader {
// ArrowArray to hold memory
nanoarrow::UniqueArray array;
NANOARROW_RETURN_NOT_OK(ArrowArrayInitFromSchema(array.get(), schema,
error));
+ SetArrayAllocatorRecursive(array.get());
// Parse the JSON into the array
NANOARROW_RETURN_NOT_OK(SetArrayColumn(obj, array_view.get(),
array.get(), error));
@@ -881,6 +906,8 @@ class TestingJSONReader {
}
private:
+ ArrowBufferAllocator allocator_;
+
ArrowErrorCode SetSchema(ArrowSchema* schema, const json& value, ArrowError*
error) {
NANOARROW_RETURN_NOT_OK(
Check(value.is_object(), error, "Expected Schema to be a JSON
object"));
@@ -1713,6 +1740,20 @@ class TestingJSONReader {
return NANOARROW_OK;
}
+ void SetArrayAllocatorRecursive(ArrowArray* array) {
+ for (int i = 0; i < array->n_buffers; i++) {
+ ArrowArrayBuffer(array, i)->allocator = allocator_;
+ }
+
+ for (int64_t i = 0; i < array->n_children; i++) {
+ SetArrayAllocatorRecursive(array->children[i]);
+ }
+
+ if (array->dictionary != nullptr) {
+ SetArrayAllocatorRecursive(array->dictionary);
+ }
+ }
+
ArrowErrorCode PrefixError(ArrowErrorCode value, ArrowError* error,
const std::string& prefix) {
if (value != NANOARROW_OK && error != nullptr) {
@@ -1784,10 +1825,10 @@ class TestingJSONComparison {
// Read both schemas
nanoarrow::UniqueSchema actual_schema;
nanoarrow::UniqueSchema expected_schema;
- NANOARROW_RETURN_NOT_OK_WITH_ERROR(actual->get_schema(actual,
actual_schema.get()),
- error);
- NANOARROW_RETURN_NOT_OK_WITH_ERROR(
- expected->get_schema(expected, expected_schema.get()), error);
+ NANOARROW_RETURN_NOT_OK(
+ ArrowArrayStreamGetSchema(actual, actual_schema.get(), error));
+ NANOARROW_RETURN_NOT_OK(
+ ArrowArrayStreamGetSchema(expected, expected_schema.get(), error));
// Compare them and return if they are not equal
NANOARROW_RETURN_NOT_OK(
@@ -1809,10 +1850,9 @@ class TestingJSONComparison {
// Read a batch from each stream
actual_array.reset();
expected_array.reset();
- NANOARROW_RETURN_NOT_OK_WITH_ERROR(actual->get_next(actual,
actual_array.get()),
- error);
- NANOARROW_RETURN_NOT_OK_WITH_ERROR(
- expected->get_next(expected, expected_array.get()), error);
+ NANOARROW_RETURN_NOT_OK(ArrowArrayStreamGetNext(actual,
actual_array.get(), error));
+ NANOARROW_RETURN_NOT_OK(
+ ArrowArrayStreamGetNext(expected, expected_array.get(), error));
// Check the finished/unfinished status of both streams
if (actual_array->release == nullptr && expected_array->release !=
nullptr) {