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

kou 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 df824c10a7 GH-50904: [C++] Replace RapidJSON with simdjson in 
OpaqueType (#50905)
df824c10a7 is described below

commit df824c10a7429bbed6de04715d8e008e28674074
Author: Aaditya Srinivasan <[email protected]>
AuthorDate: Thu Aug 20 02:45:25 2026 +0530

    GH-50904: [C++] Replace RapidJSON with simdjson in OpaqueType (#50905)
    
    ### Rationale for this change
    
    This PR continues the simdjson migration by replacing the remaining 
RapidJSON usage in `OpaqueType` under `cpp/src/arrow/extension` with the 
existing simdjson helpers and On-Demand API.
    
    The existing deserialization validation and behavior are preserved, with 
tests updated for parser-specific error messages.
    
    ### Changes
    
    - Replace RapidJSON parsing in `OpaqueType::Deserialize()` with simdjson.
    - Use the existing `ResolveSimdjsonResult()` helper.
    - Remove the RapidJSON dependency from `opaque.cc`.
    - Update OpaqueType deserialization tests for simdjson parsing errors.
    
    * GitHub Issue: #50904
    
    Authored-by: Aaditya Srinivasan <[email protected]>
    Signed-off-by: Sutou Kouhei <[email protected]>
---
 cpp/src/arrow/extension/opaque.cc      | 90 +++++++++++++++++++++++++---------
 cpp/src/arrow/extension/opaque_test.cc |  7 +--
 2 files changed, 71 insertions(+), 26 deletions(-)

diff --git a/cpp/src/arrow/extension/opaque.cc 
b/cpp/src/arrow/extension/opaque.cc
index b1ad48fdba..c6068babdb 100644
--- a/cpp/src/arrow/extension/opaque.cc
+++ b/cpp/src/arrow/extension/opaque.cc
@@ -20,11 +20,10 @@
 #include <sstream>
 
 #include "arrow/json/json_writer_internal.h"
-#include "arrow/json/rapidjson_defs.h"  // IWYU pragma: keep
 #include "arrow/util/logging_internal.h"
+#include "arrow/util/simdjson_internal.h"
 
-#include <rapidjson/document.h>
-#include <rapidjson/error/en.h>
+#include <simdjson.h>
 
 using ::arrow::json::JsonWriter;
 
@@ -65,34 +64,79 @@ std::string OpaqueType::Serialize() const {
 
 Result<std::shared_ptr<DataType>> OpaqueType::Deserialize(
     std::shared_ptr<DataType> storage_type, const std::string& 
serialized_data) const {
-  rapidjson::Document document;
-  const auto& parsed = document.Parse(serialized_data.data(), 
serialized_data.length());
-  if (parsed.HasParseError()) {
-    return Status::Invalid("Invalid serialized JSON data for OpaqueType: ",
-                           
rapidjson::GetParseError_En(parsed.GetParseError()), ": ",
-                           serialized_data);
-  } else if (!document.IsObject()) {
-    return Status::Invalid("Invalid serialized JSON data for OpaqueType: not 
an object");
+  simdjson::padded_string padded_json(serialized_data);
+  simdjson::ondemand::parser parser;
+
+  ARROW_ASSIGN_OR_RAISE(auto document,
+                        
internal::ResolveSimdjsonResult(parser.iterate(padded_json),
+                                                        "Failed to parse 
JSON"));
+
+  ARROW_ASSIGN_OR_RAISE(auto object,
+                        internal::ResolveSimdjsonResult(document.get_object(),
+                                                        "Failed to get JSON 
object"));
+
+  std::string type_name;
+  std::string vendor_name;
+  bool has_type_name = false;
+  bool has_vendor_name = false;
+
+  for (auto field_result : object) {
+    ARROW_ASSIGN_OR_RAISE(auto field, internal::ResolveSimdjsonResult(
+                                          field_result, "Failed to iterate 
JSON object"));
+
+    ARROW_ASSIGN_OR_RAISE(
+        auto key, internal::ResolveSimdjsonResult(field.unescaped_key(),
+                                                  "Failed to get JSON object 
key"));
+
+    auto value = field.value();
+
+    if (key == "type_name") {
+      has_type_name = true;
+
+      ARROW_ASSIGN_OR_RAISE(auto type,
+                            internal::ResolveSimdjsonResult(
+                                value.type(), "Failed to determine type_name 
JSON type"));
+
+      if (type != simdjson::ondemand::json_type::string) {
+        return Status::Invalid(
+            "Invalid serialized JSON data for OpaqueType: type_name is not a 
string");
+      }
+
+      ARROW_ASSIGN_OR_RAISE(
+          auto name,
+          internal::ResolveSimdjsonResult(value.get_string(), "Failed to get 
type_name"));
+      type_name = std::string(name);
+
+    } else if (key == "vendor_name") {
+      has_vendor_name = true;
+
+      ARROW_ASSIGN_OR_RAISE(
+          auto type, internal::ResolveSimdjsonResult(
+                         value.type(), "Failed to determine vendor_name JSON 
type"));
+
+      if (type != simdjson::ondemand::json_type::string) {
+        return Status::Invalid(
+            "Invalid serialized JSON data for OpaqueType: vendor_name is not a 
string");
+      }
+
+      ARROW_ASSIGN_OR_RAISE(auto name,
+                            internal::ResolveSimdjsonResult(value.get_string(),
+                                                            "Failed to get 
vendor_name"));
+      vendor_name = std::string(name);
+    }
   }
-  if (!document.HasMember("type_name")) {
+
+  if (!has_type_name) {
     return Status::Invalid(
         "Invalid serialized JSON data for OpaqueType: missing type_name");
-  } else if (!document.HasMember("vendor_name")) {
-    return Status::Invalid(
-        "Invalid serialized JSON data for OpaqueType: missing vendor_name");
   }
 
-  const auto& type_name = document["type_name"];
-  const auto& vendor_name = document["vendor_name"];
-  if (!type_name.IsString()) {
+  if (!has_vendor_name) {
     return Status::Invalid(
-        "Invalid serialized JSON data for OpaqueType: type_name is not a 
string");
-  } else if (!vendor_name.IsString()) {
-    return Status::Invalid(
-        "Invalid serialized JSON data for OpaqueType: vendor_name is not a 
string");
+        "Invalid serialized JSON data for OpaqueType: missing vendor_name");
   }
 
-  return opaque(std::move(storage_type), type_name.GetString(), 
vendor_name.GetString());
+  return opaque(std::move(storage_type), std::move(type_name), 
std::move(vendor_name));
 }
 
 std::shared_ptr<Array> OpaqueType::MakeArray(std::shared_ptr<ArrayData> data) 
const {
diff --git a/cpp/src/arrow/extension/opaque_test.cc 
b/cpp/src/arrow/extension/opaque_test.cc
index 16fcba3fa6..ac093ddfe0 100644
--- a/cpp/src/arrow/extension/opaque_test.cc
+++ b/cpp/src/arrow/extension/opaque_test.cc
@@ -127,12 +127,13 @@ TEST(OpaqueType, Deserialize) {
 
   auto type = internal::checked_pointer_cast<extension::OpaqueType>(
       extension::opaque(null(), "type", "vendor"));
-  EXPECT_RAISES_WITH_MESSAGE_THAT(Invalid, testing::HasSubstr("The document is 
empty"),
+  EXPECT_RAISES_WITH_MESSAGE_THAT(Invalid, testing::HasSubstr("Failed to parse 
JSON"),
                                   type->Deserialize(null(), R"()"));
   EXPECT_RAISES_WITH_MESSAGE_THAT(Invalid,
-                                  testing::HasSubstr("Missing a name for 
object member"),
+                                  testing::HasSubstr("Failed to get JSON 
object"),
                                   type->Deserialize(null(), R"({)"));
-  EXPECT_RAISES_WITH_MESSAGE_THAT(Invalid, testing::HasSubstr("not an object"),
+  EXPECT_RAISES_WITH_MESSAGE_THAT(Invalid,
+                                  testing::HasSubstr("Failed to get JSON 
object"),
                                   type->Deserialize(null(), R"([])"));
   EXPECT_RAISES_WITH_MESSAGE_THAT(Invalid, testing::HasSubstr("missing 
type_name"),
                                   type->Deserialize(null(), R"({})"));

Reply via email to