static int ArrowArrayViewValidateFull()

in src/nanoarrow/array.c [1108:1177]


static int ArrowArrayViewValidateFull(struct ArrowArrayView* array_view,
                                      struct ArrowError* error) {
  for (int i = 0; i < 3; i++) {
    switch (array_view->layout.buffer_type[i]) {
      case NANOARROW_BUFFER_TYPE_DATA_OFFSET:
        if (array_view->layout.element_size_bits[i] == 32) {
          NANOARROW_RETURN_NOT_OK(
              ArrowAssertIncreasingInt32(array_view->buffer_views[i], error));
        } else {
          NANOARROW_RETURN_NOT_OK(
              ArrowAssertIncreasingInt64(array_view->buffer_views[i], error));
        }
        break;
      default:
        break;
    }
  }

  if (array_view->storage_type == NANOARROW_TYPE_DENSE_UNION ||
      array_view->storage_type == NANOARROW_TYPE_SPARSE_UNION) {
    if (array_view->union_type_id_map == NULL) {
      // If the union_type_id map is NULL (e.g., when using ArrowArrayInitFromType() +
      // ArrowArrayAllocateChildren() + ArrowArrayFinishBuilding()), we don't have enough
      // information to validate this buffer.
      ArrowErrorSet(error,
                    "Insufficient information provided for validation of union array");
      return EINVAL;
    } else if (_ArrowParsedUnionTypeIdsWillEqualChildIndices(
                   array_view->union_type_id_map, array_view->n_children,
                   array_view->n_children)) {
      NANOARROW_RETURN_NOT_OK(ArrowAssertRangeInt8(
          array_view->buffer_views[0], 0, (int8_t)(array_view->n_children - 1), error));
    } else {
      NANOARROW_RETURN_NOT_OK(ArrowAssertInt8In(array_view->buffer_views[0],
                                                array_view->union_type_id_map + 128,
                                                array_view->n_children, error));
    }
  }

  if (array_view->storage_type == NANOARROW_TYPE_DENSE_UNION &&
      array_view->union_type_id_map != NULL) {
    // Check that offsets refer to child elements that actually exist
    for (int64_t i = 0; i < array_view->length; i++) {
      int8_t child_id = ArrowArrayViewUnionChildIndex(array_view, i);
      int64_t offset = ArrowArrayViewUnionChildOffset(array_view, i);
      int64_t child_length = array_view->children[child_id]->length;
      if (offset < 0 || offset > child_length) {
        ArrowErrorSet(
            error,
            "[%ld] Expected union offset for child id %d to be between 0 and %ld but "
            "found offset value %ld",
            (long)i, (int)child_id, (long)child_length, offset);
        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
  if (array_view->dictionary != NULL) {
    ArrowErrorSet(error, "Validation for dictionary-encoded arrays is not implemented");
    return ENOTSUP;
  }

  return NANOARROW_OK;
}