paleolimbot commented on code in PR #578:
URL: https://github.com/apache/arrow-nanoarrow/pull/578#discussion_r1710195563
##########
src/nanoarrow/common/array.c:
##########
@@ -1335,3 +1335,177 @@ ArrowErrorCode ArrowArrayViewValidate(struct
ArrowArrayView* array_view,
ArrowErrorSet(error, "validation_level not recognized");
return EINVAL;
}
+
+struct ArrowComparisonInternalState {
+ enum ArrowCompareLevel level;
+ int is_equal;
+ struct ArrowBuffer path;
+ struct ArrowError reason;
+};
+
+#define RETURN_NOT_EQUAL_IMPL(state_, path_size_, cond_, reason_) \
+ do { \
+ if (cond_) { \
+ ArrowErrorSet(&state_->reason, "%s", reason_); \
+ state_->path.size_bytes = (path_size_); \
+ state_->is_equal = 0; \
+ return NANOARROW_OK; \
+ } \
+ } while (0)
+
+#define RETURN_NOT_EQUAL(state_, path_size_, condition_) \
+ RETURN_NOT_EQUAL_IMPL(state_, path_size_, condition_, #condition_)
+
+static ArrowErrorCode ArrowArrayViewCompareStructure(
+ const struct ArrowArrayView* actual, const struct ArrowArrayView* expected,
+ struct ArrowComparisonInternalState* state) {
+ int64_t path_size = state->path.size_bytes;
+
+ RETURN_NOT_EQUAL(state, path_size, actual->storage_type !=
expected->storage_type);
+ RETURN_NOT_EQUAL(state, path_size, actual->n_children !=
expected->n_children);
+ RETURN_NOT_EQUAL(state, path_size,
+ actual->dictionary == NULL && expected->dictionary != NULL);
+ RETURN_NOT_EQUAL(state, path_size,
+ actual->dictionary != NULL && expected->dictionary == NULL);
+
+ char child_id[128];
+ for (int64_t i = 0; i < actual->n_children; i++) {
+ snprintf(child_id, sizeof(child_id), ".children[%" PRId64 "]", i);
+ state->path.size_bytes = path_size;
+ NANOARROW_RETURN_NOT_OK(
+ ArrowBufferAppendStringView(&state->path, ArrowCharView(child_id)));
+ NANOARROW_RETURN_NOT_OK(ArrowArrayViewCompareStructure(actual->children[i],
+
expected->children[i], state));
+ if (!state->is_equal) {
+ return NANOARROW_OK;
+ }
+ }
+
+ if (actual->dictionary != NULL) {
+ state->path.size_bytes = path_size;
+ NANOARROW_RETURN_NOT_OK(
+ ArrowBufferAppendStringView(&state->path,
ArrowCharView(".dictionary")));
+ NANOARROW_RETURN_NOT_OK(
+ ArrowArrayViewCompareStructure(actual->dictionary,
expected->dictionary, state));
+ if (!state->is_equal) {
+ return NANOARROW_OK;
+ }
+ }
+
+ return NANOARROW_OK;
+}
+
+static ArrowErrorCode ArrowArrayViewCompareIdentical(
+ const struct ArrowArrayView* actual, const struct ArrowArrayView* expected,
+ struct ArrowComparisonInternalState* state) {
+ int64_t path_size = state->path.size_bytes;
+
+ RETURN_NOT_EQUAL(state, path_size, actual->length != expected->length);
+ RETURN_NOT_EQUAL(state, path_size, actual->offset != expected->offset);
+ RETURN_NOT_EQUAL(state, path_size, actual->null_count !=
expected->null_count);
+
+ char child_id[128];
+ for (int i = 0; i < NANOARROW_MAX_FIXED_BUFFERS; i++) {
+ snprintf(child_id, sizeof(child_id), ".buffers[%d]", i);
+ state->path.size_bytes = path_size;
+ NANOARROW_RETURN_NOT_OK(
+ ArrowBufferAppendStringView(&state->path, ArrowCharView(child_id)));
+
+ RETURN_NOT_EQUAL(
+ state, state->path.size_bytes,
+ actual->buffer_views[i].size_bytes !=
expected->buffer_views[i].size_bytes);
+ int64_t buffer_size = actual->buffer_views[i].size_bytes;
+ if (buffer_size == 0) {
+ continue;
+ }
+
+ RETURN_NOT_EQUAL(state, state->path.size_bytes,
+ memcmp(actual->buffer_views[i].data.data,
+ expected->buffer_views[i].data.data, buffer_size)
!= 0);
Review Comment:
Yes, that would be a different validation level (EQUAL maybe). There is also
the case where a parent null shadows (non-null) child elements (where the child
arrays would be unequal except there are specific elements or element ranges
that we have to ignore.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]