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

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


The following commit(s) were added to refs/heads/main by this push:
     new 84472e46c9 GH-52161: [C++][Parquet] Add support for string/binary view 
to content defined chunking writer (#52162)
84472e46c9 is described below

commit 84472e46c93dc87af738704f91fea6e6b6e2cf02
Author: Robert Kruszewski <[email protected]>
AuthorDate: Mon Oct 12 05:35:45 2026 +0100

    GH-52161: [C++][Parquet] Add support for string/binary view to content 
defined chunking writer (#52162)
    
    ### Rationale for this change
    
    View types are supported in parquet writer but they error when using 
content defined chunking
    
    ### What changes are included in this PR?
    
    Teach the internal chunker how to calculate the size for view types
    
    ### Are these changes tested?
    
    Added tests
    
    ### Are there any user-facing changes?
    
    No
    
    ### Was AI used for this PR?
    
    In accordance to the [AI generation 
guidelines](https://arrow.apache.org/docs/dev/developers/overview.html#ai-generated-code),
 please disclose below whether and how AI was used in this PR.
    
    **PR code and description written by:**
    
    - [x] Human
    - [ ] AI
    
    **Reviewed before submission by:**
    
    - [x] Human
    - [x] AI
    - [ ] Not reviewed
    
    * GitHub Issue: #52161
    
    Authored-by: Robert Kruszewski <[email protected]>
    Signed-off-by: Zehua Zou <[email protected]>
---
 cpp/src/parquet/chunker_internal.cc      | 14 ++++++++++++++
 cpp/src/parquet/chunker_internal_test.cc | 15 +++++++++++++--
 2 files changed, 27 insertions(+), 2 deletions(-)

diff --git a/cpp/src/parquet/chunker_internal.cc 
b/cpp/src/parquet/chunker_internal.cc
index 794075b733..c45bf0c97e 100644
--- a/cpp/src/parquet/chunker_internal.cc
+++ b/cpp/src/parquet/chunker_internal.cc
@@ -21,6 +21,7 @@
 #include <cstdint>
 #include <iterator>
 #include <string>
+#include <string_view>
 #include <vector>
 
 #include "arrow/array.h"
@@ -349,6 +350,17 @@ class ContentDefinedChunker::Impl {
     });
   }
 
+  std::vector<Chunk> CalculateBinaryView(const int16_t* def_levels,
+                                         const int16_t* rep_levels, int64_t 
num_levels,
+                                         const ::arrow::Array& values) {
+    const auto& array = checked_cast<const ::arrow::BinaryViewArray&>(values);
+    return Calculate(def_levels, rep_levels, num_levels, [&](int64_t i) {
+      const std::string_view value = array.GetView(i);
+      Roll(reinterpret_cast<const uint8_t*>(value.data()),
+           static_cast<int64_t>(value.size()));
+    });
+  }
+
   std::vector<Chunk> GetChunks(const int16_t* def_levels, const int16_t* 
rep_levels,
                                int64_t num_levels, const ::arrow::Array& 
values) {
     auto handle_type = [&](auto&& type) -> std::vector<Chunk> {
@@ -380,6 +392,8 @@ class ContentDefinedChunker::Impl {
       } else if constexpr (::arrow::is_large_binary_like(ArrowType::type_id)) {
         return CalculateBinaryLike<::arrow::LargeBinaryArray>(def_levels, 
rep_levels,
                                                               num_levels, 
values);
+      } else if constexpr (::arrow::is_binary_view_like(ArrowType::type_id)) {
+        return CalculateBinaryView(def_levels, rep_levels, num_levels, values);
       } else if constexpr (::arrow::is_dictionary(ArrowType::type_id)) {
         return GetChunks(def_levels, rep_levels, num_levels,
                          *static_cast<const 
::arrow::DictionaryArray&>(values).indices());
diff --git a/cpp/src/parquet/chunker_internal_test.cc 
b/cpp/src/parquet/chunker_internal_test.cc
index 2469d54afb..8de4136cfa 100644
--- a/cpp/src/parquet/chunker_internal_test.cc
+++ b/cpp/src/parquet/chunker_internal_test.cc
@@ -30,6 +30,7 @@
 #include "arrow/testing/generator.h"
 #include "arrow/type_fwd.h"
 #include "arrow/util/float16.h"
+#include "arrow/visit_data_inline.h"
 #include "parquet/arrow/reader.h"
 #include "parquet/arrow/reader_internal.h"
 #include "parquet/arrow/test_util.h"
@@ -170,6 +171,10 @@ Result<std::shared_ptr<Array>> GenerateArray(const 
std::shared_ptr<Field>& field
                     std::string("bin_") + std::to_string(val))
       GENERATE_CASE(LARGE_BINARY, ::arrow::LargeBinaryBuilder,
                     std::string("bin_") + std::to_string(val))
+      GENERATE_CASE(STRING_VIEW, ::arrow::StringViewBuilder,
+                    std::string("str_") + std::to_string(val))
+      GENERATE_CASE(BINARY_VIEW, ::arrow::BinaryViewBuilder,
+                    std::string("bin_") + std::to_string(val))
     case ::arrow::Type::FIXED_SIZE_BINARY: {
       auto size =
           checked_cast<const 
::arrow::FixedSizeBinaryType*>(type.get())->byte_width();
@@ -742,6 +747,10 @@ Result<int64_t> CalculateCdcSize(const 
std::shared_ptr<Array>& array, bool nulla
   } else if (::arrow::is_large_binary_like(type_id)) {
     auto binary_array = checked_cast<const 
::arrow::LargeBinaryArray*>(array.get());
     result += binary_array->total_values_length();
+  } else if (::arrow::is_binary_view_like(type_id)) {
+    ::arrow::VisitArraySpanInline<::arrow::BinaryViewType>(
+        *array->data(),
+        [&](std::string_view v) { result += static_cast<int64_t>(v.size()); }, 
[] {});
   } else {
     return Status::NotImplemented("CDC size calculation for type ",
                                   array->type()->ToString(), " is not 
implemented");
@@ -784,7 +793,8 @@ void AssertContentDefinedChunkSizes(const 
std::shared_ptr<::arrow::ChunkedArray>
     ASSERT_EQ(column_info.has_dictionary_page, expect_dictionary_page);
   }
 
-  if (::arrow::is_fixed_width(type_id) || 
::arrow::is_base_binary_like(type_id)) {
+  if (::arrow::is_fixed_width(type_id) || 
::arrow::is_base_binary_like(type_id) ||
+      ::arrow::is_binary_view_like(type_id)) {
     int64_t offset = 0;
 
     auto page_lengths = column_info.page_lengths;
@@ -1451,7 +1461,7 @@ INSTANTIATE_TEST_SUITE_P(
     testing::Values(
         CaseConfig{::arrow::boolean(), false}, CaseConfig{::arrow::int64(), 
true},
         // Binary-like
-        CaseConfig{::arrow::utf8(), false},
+        CaseConfig{::arrow::utf8(), false}, CaseConfig{::arrow::utf8_view(), 
true},
         CaseConfig{::arrow::fixed_size_binary(16), true},
         // Nested types
         CaseConfig{::arrow::list(::arrow::int32()), false},
@@ -1475,6 +1485,7 @@ INSTANTIATE_TEST_SUITE_P(
         // Binary-like
         CaseConfig{::arrow::utf8(), false}, CaseConfig{::arrow::binary(), 
true},
         CaseConfig{::arrow::fixed_size_binary(16), true},
+        CaseConfig{::arrow::utf8_view(), false}, 
CaseConfig{::arrow::binary_view(), true},
         // Temporal
         CaseConfig{::arrow::date32(), false},
         CaseConfig{::arrow::time32(::arrow::TimeUnit::MILLI), true},

Reply via email to