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 9ec3acaf91 GH-50566: [C++] Introduce simdjson and migrate ObjectParser 
(#50469)
9ec3acaf91 is described below

commit 9ec3acaf9123c81348f2ede2f178d1d7b3df2989
Author: Aaditya Srinivasan <[email protected]>
AuthorDate: Tue Jul 21 07:26:22 2026 +0530

    GH-50566: [C++] Introduce simdjson and migrate ObjectParser (#50469)
    
    ### Rationale for this change
    
    This PR is the first in a series of PRs for GH-35460 to migrate Arrow's 
JSON implementation from RapidJSON to simdjson.
    
    As the foundation for the migration, this PR introduces simdjson into 
Arrow's build system, updates the bundled simdjson version to v4.6.4, and 
migrates the self-contained `arrow::json::internal::ObjectParser`.
    
    ### What changes are included in this PR?
    
    This PR:
    
    - Introduces `simdjson` as a third-party dependency.
    - Adds CMake support for discovering and building `simdjson`.
    - Updates the bundled simdjson dependency to **v4.6.4**.
    - Adds system package and vcpkg integration required for simdjson across 
supported build environments.
    - Links `simdjson` into the Arrow JSON library.
    - Migrates `arrow::json::internal::ObjectParser` from RapidJSON to the 
simdjson DOM API.
    - Adds dedicated unit tests covering:
      - String retrieval
      - Boolean retrieval
      - String map extraction
      - Invalid JSON
      - Missing keys
      - Incorrect types
      - Non-object root documents
      - Empty objects
    
    This establishes the build infrastructure needed for the remaining JSON 
migration, which will be completed incrementally in follow-up PRs.
    
    ### Performance
    
    On the ObjectParser benchmark, the simdjson implementation achieved 
approximately **6.3×** higher throughput than the previous RapidJSON 
implementation (about **84%** lower execution time).
    
    ### Are these changes tested?
    
    Yes.
    
    - Added dedicated unit tests for `ObjectParser`.
    - Verified the ObjectParser JSON test suite locally.
    - Updated the build system and validated the dependency integration across 
supported CI configurations (currently 41 CI checks passing; remaining failures 
are limited to two Windows-specific workflows under investigation).
    
    * GitHub Issue: #50566
    
    Authored-by: Aaditya Srinivasan <[email protected]>
    Signed-off-by: Sutou Kouhei <[email protected]>
---
 ci/conda_env_cpp.txt                               |   1 +
 ci/docker/alpine-linux-3.22-cpp.dockerfile         |   1 +
 ci/docker/debian-13-cpp.dockerfile                 |   1 +
 ci/docker/debian-experimental-cpp.dockerfile       |   1 +
 ci/docker/fedora-42-cpp.dockerfile                 |   1 +
 ci/docker/ubuntu-22.04-cpp.dockerfile              |   2 +
 ci/docker/ubuntu-24.04-cpp.dockerfile              |   1 +
 ci/scripts/PKGBUILD                                |   1 +
 ci/scripts/cpp_build.sh                            |   1 +
 ci/scripts/msys2_setup.sh                          |   1 +
 ci/scripts/r_revdepcheck.sh                        |   1 +
 ci/vcpkg/vcpkg.json                                |   3 +-
 cpp/cmake_modules/ThirdpartyToolchain.cmake        |  51 +++++++++
 cpp/src/arrow/CMakeLists.txt                       |   2 +-
 cpp/src/arrow/json/CMakeLists.txt                  |   1 +
 cpp/src/arrow/json/object_parser.cc                | 121 +++++++++++++++------
 cpp/src/arrow/json/object_parser_test.cc           | 113 +++++++++++++++++++
 cpp/thirdparty/versions.txt                        |   3 +
 cpp/vcpkg.json                                     |   1 +
 dev/tasks/linux-packages/apache-arrow/debian/rules |   1 +
 20 files changed, 274 insertions(+), 34 deletions(-)

diff --git a/ci/conda_env_cpp.txt b/ci/conda_env_cpp.txt
index e8a7d55239..3986f7736e 100644
--- a/ci/conda_env_cpp.txt
+++ b/ci/conda_env_cpp.txt
@@ -45,6 +45,7 @@ pkg-config
 python
 rapidjson
 re2
+simdjson
 snappy
 thrift-cpp>=0.11.0
 xsimd>=14.2
diff --git a/ci/docker/alpine-linux-3.22-cpp.dockerfile 
b/ci/docker/alpine-linux-3.22-cpp.dockerfile
index 17073b3f26..89e1884323 100644
--- a/ci/docker/alpine-linux-3.22-cpp.dockerfile
+++ b/ci/docker/alpine-linux-3.22-cpp.dockerfile
@@ -59,6 +59,7 @@ RUN apk add \
         re2-dev \
         rsync \
         samurai \
+        simdjson-dev \
         snappy-dev \
         sqlite-dev \
         thrift-dev \
diff --git a/ci/docker/debian-13-cpp.dockerfile 
b/ci/docker/debian-13-cpp.dockerfile
index 552800888e..9bf60c9f95 100644
--- a/ci/docker/debian-13-cpp.dockerfile
+++ b/ci/docker/debian-13-cpp.dockerfile
@@ -65,6 +65,7 @@ RUN apt-get update -y -q && \
         libprotobuf-dev \
         libprotoc-dev \
         libre2-dev \
+        libsimdjson-dev \
         libsnappy-dev \
         libsqlite3-dev \
         libssl-dev \
diff --git a/ci/docker/debian-experimental-cpp.dockerfile 
b/ci/docker/debian-experimental-cpp.dockerfile
index c0de08e5a4..359ac70080 100644
--- a/ci/docker/debian-experimental-cpp.dockerfile
+++ b/ci/docker/debian-experimental-cpp.dockerfile
@@ -66,6 +66,7 @@ RUN if [ -n "${gcc}" ]; then \
         libpsl-dev \
         libre2-dev \
         librtmp-dev \
+        libsimdjson-dev \
         libsnappy-dev \
         libsqlite3-dev \
         libssh-dev \
diff --git a/ci/docker/fedora-42-cpp.dockerfile 
b/ci/docker/fedora-42-cpp.dockerfile
index 60e7dab678..1c751ea7e8 100644
--- a/ci/docker/fedora-42-cpp.dockerfile
+++ b/ci/docker/fedora-42-cpp.dockerfile
@@ -60,6 +60,7 @@ RUN dnf update -y && \
         python-pip \
         rapidjson-devel \
         re2-devel \
+        simdjson-devel \
         snappy-devel \
         thrift-devel \
         utf8proc-devel \
diff --git a/ci/docker/ubuntu-22.04-cpp.dockerfile 
b/ci/docker/ubuntu-22.04-cpp.dockerfile
index d098eb346e..54b671c7a5 100644
--- a/ci/docker/ubuntu-22.04-cpp.dockerfile
+++ b/ci/docker/ubuntu-22.04-cpp.dockerfile
@@ -94,6 +94,7 @@ RUN apt-get update -y -q && \
         libradospp-dev \
         libre2-dev \
         librtmp-dev \
+        libsimdjson-dev \
         libsnappy-dev \
         libsqlite3-dev \
         libssh-dev \
@@ -226,4 +227,5 @@ ENV absl_SOURCE=BUNDLED \
     PARQUET_BUILD_EXECUTABLES=ON \
     PATH=/usr/lib/ccache/:$PATH \
     PYTHON=python3 \
+    simdjson_SOURCE=BUNDLED \
     xsimd_SOURCE=BUNDLED
diff --git a/ci/docker/ubuntu-24.04-cpp.dockerfile 
b/ci/docker/ubuntu-24.04-cpp.dockerfile
index ffc763b3c2..ce2a30d980 100644
--- a/ci/docker/ubuntu-24.04-cpp.dockerfile
+++ b/ci/docker/ubuntu-24.04-cpp.dockerfile
@@ -95,6 +95,7 @@ RUN apt-get update -y -q && \
         libradospp-dev \
         libre2-dev \
         librtmp-dev \
+        libsimdjson-dev \
         libsnappy-dev \
         libsqlite3-dev \
         libssh-dev \
diff --git a/ci/scripts/PKGBUILD b/ci/scripts/PKGBUILD
index ff6615b919..2b3f3f51ff 100644
--- a/ci/scripts/PKGBUILD
+++ b/ci/scripts/PKGBUILD
@@ -138,6 +138,7 @@ build() {
     -DARROW_CXXFLAGS="${CPPFLAGS}" \
     -DAWSSDK_SOURCE=BUNDLED \
     -DCMAKE_BUILD_TYPE="release" \
+    -DCMAKE_DISABLE_PRECOMPILE_HEADERS=ON \
     -DCMAKE_INSTALL_PREFIX=${MINGW_PREFIX} \
     -DCMAKE_UNITY_BUILD=OFF \
     -DCMAKE_VERBOSE_MAKEFILE=ON \
diff --git a/ci/scripts/cpp_build.sh b/ci/scripts/cpp_build.sh
index a8d39bf970..32ccf654bf 100755
--- a/ci/scripts/cpp_build.sh
+++ b/ci/scripts/cpp_build.sh
@@ -291,6 +291,7 @@ else
     -DProtobuf_SOURCE="${Protobuf_SOURCE:-}" \
     -DRapidJSON_SOURCE="${RapidJSON_SOURCE:-}" \
     -Dre2_SOURCE="${re2_SOURCE:-}" \
+    -Dsimdjson_SOURCE="${simdjson_SOURCE:-}" \
     -DSnappy_SOURCE="${Snappy_SOURCE:-}" \
     -DThrift_SOURCE="${Thrift_SOURCE:-}" \
     -Dutf8proc_SOURCE="${utf8proc_SOURCE:-}" \
diff --git a/ci/scripts/msys2_setup.sh b/ci/scripts/msys2_setup.sh
index b4634070a8..d2b06e7490 100755
--- a/ci/scripts/msys2_setup.sh
+++ b/ci/scripts/msys2_setup.sh
@@ -45,6 +45,7 @@ case "${target}" in
     packages+=("${MINGW_PACKAGE_PREFIX}-protobuf")
     packages+=("${MINGW_PACKAGE_PREFIX}-rapidjson")
     packages+=("${MINGW_PACKAGE_PREFIX}-re2")
+    packages+=("${MINGW_PACKAGE_PREFIX}-simdjson")
     packages+=("${MINGW_PACKAGE_PREFIX}-snappy")
     packages+=("${MINGW_PACKAGE_PREFIX}-sqlite3")
     packages+=("${MINGW_PACKAGE_PREFIX}-thrift")
diff --git a/ci/scripts/r_revdepcheck.sh b/ci/scripts/r_revdepcheck.sh
index 4205151655..5c82d7e70a 100755
--- a/ci/scripts/r_revdepcheck.sh
+++ b/ci/scripts/r_revdepcheck.sh
@@ -44,6 +44,7 @@ apt install -y \
   libprotoc-dev \
   libradospp-dev \
   libre2-dev \
+  libsimdjson-dev \
   libsnappy-dev \
   libssl-dev \
   libthrift-dev \
diff --git a/ci/vcpkg/vcpkg.json b/ci/vcpkg/vcpkg.json
index 75f2b25cc0..2418e3b64d 100644
--- a/ci/vcpkg/vcpkg.json
+++ b/ci/vcpkg/vcpkg.json
@@ -57,7 +57,8 @@
     "json": {
       "description": "JSON support",
       "dependencies": [
-        "rapidjson"
+        "rapidjson",
+        "simdjson"
       ]
     },
     "gandiva": {
diff --git a/cpp/cmake_modules/ThirdpartyToolchain.cmake 
b/cpp/cmake_modules/ThirdpartyToolchain.cmake
index 4eab2ab208..d251e787a8 100644
--- a/cpp/cmake_modules/ThirdpartyToolchain.cmake
+++ b/cpp/cmake_modules/ThirdpartyToolchain.cmake
@@ -64,6 +64,7 @@ set(ARROW_THIRDPARTY_DEPENDENCIES
     re2
     Protobuf
     RapidJSON
+    simdjson
     Snappy
     Substrait
     Thrift
@@ -209,6 +210,8 @@ macro(build_dependency DEPENDENCY_NAME)
     build_protobuf()
   elseif("${DEPENDENCY_NAME}" STREQUAL "RapidJSON")
     build_rapidjson()
+  elseif("${DEPENDENCY_NAME}" STREQUAL "simdjson")
+    build_simdjson()
   elseif("${DEPENDENCY_NAME}" STREQUAL "re2")
     build_re2()
   elseif("${DEPENDENCY_NAME}" STREQUAL "Snappy")
@@ -411,6 +414,10 @@ if(ARROW_JSON OR ARROW_FLIGHT_SQL_ODBC)
   set(ARROW_WITH_RAPIDJSON ON)
 endif()
 
+if(ARROW_JSON)
+  set(ARROW_WITH_SIMDJSON ON)
+endif()
+
 if(ARROW_ORC OR ARROW_FLIGHT)
   set(ARROW_WITH_PROTOBUF ON)
 endif()
@@ -763,6 +770,14 @@ else()
            
"${THIRDPARTY_MIRROR_URL}/rapidjson-${ARROW_RAPIDJSON_BUILD_VERSION}.tar.gz")
 endif()
 
+if(DEFINED ENV{ARROW_SIMDJSON_URL})
+  set(SIMDJSON_SOURCE_URL "$ENV{ARROW_SIMDJSON_URL}")
+else()
+  set_urls(SIMDJSON_SOURCE_URL
+           
"https://github.com/simdjson/simdjson/archive/refs/tags/${ARROW_SIMDJSON_BUILD_VERSION}.tar.gz";
+           
"${THIRDPARTY_MIRROR_URL}/simdjson-${ARROW_SIMDJSON_BUILD_VERSION}.tar.gz")
+endif()
+
 if(DEFINED ENV{ARROW_S2N_TLS_URL})
   set(S2N_TLS_SOURCE_URL "$ENV{ARROW_S2N_TLS_URL}")
 else()
@@ -2784,6 +2799,42 @@ if(ARROW_BUILD_BENCHMARKS)
                      FALSE)
 endif()
 
+function(build_simdjson)
+  list(APPEND CMAKE_MESSAGE_INDENT "simdjson: ")
+  message(STATUS "Building simdjson from source")
+
+  fetchcontent_declare(simdjson
+                       ${FC_DECLARE_COMMON_OPTIONS} OVERRIDE_FIND_PACKAGE
+                       URL ${SIMDJSON_SOURCE_URL}
+                       URL_HASH 
"SHA256=${ARROW_SIMDJSON_BUILD_SHA256_CHECKSUM}")
+
+  prepare_fetchcontent()
+
+  fetchcontent_makeavailable(simdjson)
+
+  set(SIMDJSON_VENDORED
+      TRUE
+      PARENT_SCOPE)
+
+  list(APPEND ARROW_BUNDLED_STATIC_LIBS simdjson::simdjson)
+  set(ARROW_BUNDLED_STATIC_LIBS
+      "${ARROW_BUNDLED_STATIC_LIBS}"
+      PARENT_SCOPE)
+
+  list(POP_BACK CMAKE_MESSAGE_INDENT)
+endfunction()
+
+if(ARROW_WITH_SIMDJSON)
+  set(ARROW_SIMDJSON_REQUIRED_VERSION "3.0.0")
+  resolve_dependency(simdjson
+                     FORCE_ANY_NEWER_VERSION
+                     TRUE
+                     REQUIRED_VERSION
+                     ${ARROW_SIMDJSON_REQUIRED_VERSION}
+                     IS_RUNTIME_DEPENDENCY
+                     FALSE)
+endif()
+
 function(build_rapidjson)
   list(APPEND CMAKE_MESSAGE_INDENT "RapidJSON: ")
   message(STATUS "Building from source")
diff --git a/cpp/src/arrow/CMakeLists.txt b/cpp/src/arrow/CMakeLists.txt
index 8750598f6c..e792574a18 100644
--- a/cpp/src/arrow/CMakeLists.txt
+++ b/cpp/src/arrow/CMakeLists.txt
@@ -1044,7 +1044,7 @@ if(ARROW_JSON)
                            json/parser.cc
                            json/reader.cc)
   foreach(ARROW_JSON_TARGET ${ARROW_JSON_TARGETS})
-    target_link_libraries(${ARROW_JSON_TARGET} PRIVATE RapidJSON)
+    target_link_libraries(${ARROW_JSON_TARGET} PRIVATE RapidJSON 
simdjson::simdjson)
   endforeach()
 else()
   set(ARROW_JSON_TARGET_SHARED)
diff --git a/cpp/src/arrow/json/CMakeLists.txt 
b/cpp/src/arrow/json/CMakeLists.txt
index fa7d060784..b5b47c0ed3 100644
--- a/cpp/src/arrow/json/CMakeLists.txt
+++ b/cpp/src/arrow/json/CMakeLists.txt
@@ -23,6 +23,7 @@ add_arrow_test(test
                from_string_test.cc
                parser_test.cc
                reader_test.cc
+               object_parser_test.cc
                PREFIX
                "arrow-json"
                EXTRA_LINK_LIBS
diff --git a/cpp/src/arrow/json/object_parser.cc 
b/cpp/src/arrow/json/object_parser.cc
index 346fd1039a..c730988c1e 100644
--- a/cpp/src/arrow/json/object_parser.cc
+++ b/cpp/src/arrow/json/object_parser.cc
@@ -16,72 +16,129 @@
 // under the License.
 
 #include "arrow/json/object_parser.h"
-#include "arrow/json/rapidjson_defs.h"  // IWYU pragma: keep
 
-#include <rapidjson/document.h>
+#include <simdjson.h>
 
 namespace arrow {
 namespace json {
 namespace internal {
 
-namespace rj = arrow::rapidjson;
-
 class ObjectParser::Impl {
  public:
   Status Parse(std::string_view json) {
-    document_.Parse(reinterpret_cast<const rj::Document::Ch*>(json.data()),
-                    static_cast<size_t>(json.size()));
+    // Copy into padded buffer
+    padded_json_ = simdjson::padded_string(json);
 
-    if (document_.HasParseError()) {
-      return Status::Invalid("Json parse error (offset ", 
document_.GetErrorOffset(),
-                             "): ", document_.GetParseError());
-    }
-    if (!document_.IsObject()) {
-      return Status::TypeError("Not a json object");
+    // Store parsed document
+    document_ = parser_.iterate(padded_json_);
+
+    // Validate root is an object
+    auto object = document_.get_object();
+    if (object.error()) {
+      if (object.error() == simdjson::INCORRECT_TYPE) {
+        return Status::TypeError("Not a JSON object");
+      }
+      return Status::Invalid("JSON parse error: ",
+                             simdjson::error_message(object.error()));
     }
+
     return Status::OK();
   }
 
-  Result<std::string> GetString(const char* key) const {
-    if (!document_.HasMember(key)) {
+  Result<std::string> GetString(const char* key) {
+    document_.rewind();
+
+    auto object = document_.get_object();
+
+    auto field = object.find_field(key);
+
+    if (field.error() == simdjson::NO_SUCH_FIELD) {
       return Status::KeyError("Key '", key, "' does not exist");
     }
-    if (!document_[key].IsString()) {
+    if (field.error()) {
+      return Status::Invalid("Error accessing key '", key,
+                             "': ", simdjson::error_message(field.error()));
+    }
+
+    auto str_result = field.get_string();
+    if (str_result.error() == simdjson::INCORRECT_TYPE) {
       return Status::TypeError("Key '", key, "' is not a string");
     }
-    return document_[key].GetString();
+    if (str_result.error()) {
+      return Status::Invalid("Error getting string for key '", key,
+                             "': ", 
simdjson::error_message(str_result.error()));
+    }
+
+    return std::string(str_result.value());
   }
 
-  Result<std::unordered_map<std::string, std::string>> GetStringMap() const {
+  Result<std::unordered_map<std::string, std::string>> GetStringMap() {
     std::unordered_map<std::string, std::string> map;
-    for (auto itr = document_.MemberBegin(); itr != document_.MemberEnd(); 
++itr) {
-      const auto& json_name = itr->name;
-      const auto& json_value = itr->value;
-      if (!json_name.IsString()) {
-        return Status::TypeError("Key is not a string");
+
+    document_.rewind();
+
+    auto object = document_.get_object();
+
+    for (auto field : object) {
+      auto key_result = field.unescaped_key();
+
+      auto key = key_result.value();
+
+      if (key_result.error()) {
+        return Status::Invalid("Error getting value for key '", 
std::string(key),
+                               "': ", 
simdjson::error_message(key_result.error()));
+      }
+
+      auto value = field.value();
+
+      auto str_result = value.get_string();
+
+      if (str_result.error() == simdjson::INCORRECT_TYPE) {
+        return Status::TypeError("Key '", std::string(key),
+                                 "' does not have a string value");
       }
-      std::string name = json_name.GetString();
-      if (!json_value.IsString()) {
-        return Status::TypeError("Key '", name, "' does not have a string 
value");
+      if (str_result.error()) {
+        return Status::Invalid("Error getting value for key '", 
std::string(key),
+                               "': (code=", 
static_cast<int>(str_result.error()), ")");
       }
-      std::string value = json_value.GetString();
-      map.insert({std::move(name), std::move(value)});
+
+      map.emplace(std::string(key), std::string(str_result.value()));
     }
+
     return map;
   }
 
-  Result<bool> GetBool(const char* key) const {
-    if (!document_.HasMember(key)) {
+  Result<bool> GetBool(const char* key) {
+    document_.rewind();
+
+    auto object = document_.get_object();
+
+    auto field = object.find_field(key);
+
+    if (field.error() == simdjson::NO_SUCH_FIELD) {
       return Status::KeyError("Key '", key, "' does not exist");
     }
-    if (!document_[key].IsBool()) {
+    if (field.error()) {
+      return Status::Invalid("Error accessing key '", key,
+                             "': ", simdjson::error_message(field.error()));
+    }
+
+    auto bool_result = field.get_bool();
+    if (bool_result.error() == simdjson::INCORRECT_TYPE) {
       return Status::TypeError("Key '", key, "' is not a boolean");
     }
-    return document_[key].GetBool();
+    if (bool_result.error()) {
+      return Status::Invalid("Error getting bool for key '", key,
+                             "': ", 
simdjson::error_message(bool_result.error()));
+    }
+
+    return bool_result.value();
   }
 
  private:
-  rj::Document document_;
+  simdjson::ondemand::parser parser_;
+  simdjson::padded_string padded_json_;
+  simdjson::ondemand::document document_;
 };
 
 ObjectParser::ObjectParser() : impl_(new ObjectParser::Impl()) {}
diff --git a/cpp/src/arrow/json/object_parser_test.cc 
b/cpp/src/arrow/json/object_parser_test.cc
new file mode 100644
index 0000000000..b9465aee4c
--- /dev/null
+++ b/cpp/src/arrow/json/object_parser_test.cc
@@ -0,0 +1,113 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+#include "arrow/json/object_parser.h"
+
+#include <gmock/gmock.h>
+#include <gtest/gtest.h>
+
+#include <string>
+#include <unordered_map>
+
+#include "arrow/testing/gtest_util.h"
+
+namespace arrow {
+namespace json {
+namespace internal {
+
+TEST(ObjectParser, GetString) {
+  ObjectParser parser;
+
+  ASSERT_OK(parser.Parse(R"({"name":"arrow"})"));
+
+  ASSERT_OK_AND_ASSIGN(auto value, parser.GetString("name"));
+  EXPECT_EQ(value, "arrow");
+}
+
+TEST(ObjectParser, GetBool) {
+  ObjectParser parser;
+
+  ASSERT_OK(parser.Parse(R"({"enabled":true})"));
+
+  ASSERT_OK_AND_ASSIGN(auto value, parser.GetBool("enabled"));
+  EXPECT_TRUE(value);
+}
+
+TEST(ObjectParser, InvalidJson) {
+  ObjectParser parser;
+
+  EXPECT_RAISES_WITH_MESSAGE_THAT(Invalid, ::testing::HasSubstr("JSON parse 
error"),
+                                  parser.Parse(R"({"name":)"));
+}
+
+TEST(ObjectParser, GetStringMap) {
+  ObjectParser parser;
+
+  ASSERT_OK(parser.Parse(R"({
+    "k1": "v1",
+    "k2": "v2"
+  })"));
+
+  ASSERT_OK_AND_ASSIGN(auto map, parser.GetStringMap());
+
+  ASSERT_EQ(map.size(), 2U);
+  EXPECT_EQ(map["k1"], "v1");
+  EXPECT_EQ(map["k2"], "v2");
+}
+
+TEST(ObjectParser, MissingKey) {
+  ObjectParser parser;
+
+  ASSERT_OK(parser.Parse(R"({
+    "name": "arrow"
+  })"));
+
+  ASSERT_RAISES(KeyError, parser.GetString("missing"));
+  ASSERT_RAISES(KeyError, parser.GetBool("missing"));
+}
+
+TEST(ObjectParser, WrongType) {
+  ObjectParser parser;
+
+  ASSERT_OK(parser.Parse(R"({
+    "flag": true,
+    "name": "arrow"
+  })"));
+
+  ASSERT_RAISES(TypeError, parser.GetString("flag"));
+  ASSERT_RAISES(TypeError, parser.GetBool("name"));
+}
+
+TEST(ObjectParser, NonObjectRoot) {
+  ObjectParser parser;
+
+  ASSERT_RAISES(TypeError, parser.Parse(R"(["a", "b"])"));
+}
+
+TEST(ObjectParser, EmptyObject) {
+  ObjectParser parser;
+
+  ASSERT_OK(parser.Parse(R"({})"));
+
+  ASSERT_OK_AND_ASSIGN(auto map, parser.GetStringMap());
+
+  EXPECT_TRUE(map.empty());
+}
+
+}  // namespace internal
+}  // namespace json
+}  // namespace arrow
diff --git a/cpp/thirdparty/versions.txt b/cpp/thirdparty/versions.txt
index c6f4b01a71..a7f0d3d1db 100644
--- a/cpp/thirdparty/versions.txt
+++ b/cpp/thirdparty/versions.txt
@@ -102,6 +102,8 @@ 
ARROW_RAPIDJSON_BUILD_SHA256_CHECKSUM=b9290a9a6d444c8e049bd589ab804e0ccf2b05dc59
 # for CRAN builds. This version includes musl libc support (GH-48010).
 ARROW_RE2_BUILD_VERSION=2023-03-01
 
ARROW_RE2_BUILD_SHA256_CHECKSUM=7a9a4824958586980926a300b4717202485c4b4115ac031822e29aa4ef207e48
+ARROW_SIMDJSON_BUILD_VERSION=v4.6.4
+ARROW_SIMDJSON_BUILD_SHA256_CHECKSUM=b091107844fe928158c5c2265c20360fff312889ddf7ebc4528a0f0f8f2ff9cd
 ARROW_SNAPPY_BUILD_VERSION=1.2.2
 
ARROW_SNAPPY_BUILD_SHA256_CHECKSUM=90f74bc1fbf78a6c56b3c4a082a05103b3a56bb17bca1a27e052ea11723292dc
 ARROW_SUBSTRAIT_BUILD_VERSION=v0.44.0
@@ -163,6 +165,7 @@ DEPENDENCIES=(
   "ARROW_ORC_URL orc-${ARROW_ORC_BUILD_VERSION}.tar.gz 
https://www.apache.org/dyn/closer.lua/orc/orc-${ARROW_ORC_BUILD_VERSION}/orc-${ARROW_ORC_BUILD_VERSION}.tar.gz?action=download";
   "ARROW_PROTOBUF_URL protobuf-${ARROW_PROTOBUF_BUILD_VERSION}.tar.gz 
https://github.com/google/protobuf/releases/download/${ARROW_PROTOBUF_BUILD_VERSION}/protobuf-${ARROW_PROTOBUF_BUILD_VERSION:1}.tar.gz";
   "ARROW_RAPIDJSON_URL rapidjson-${ARROW_RAPIDJSON_BUILD_VERSION}.tar.gz 
https://github.com/miloyip/rapidjson/archive/${ARROW_RAPIDJSON_BUILD_VERSION}.tar.gz";
+  "ARROW_SIMDJSON_URL simdjson-${ARROW_SIMDJSON_BUILD_VERSION}.tar.gz 
https://github.com/simdjson/simdjson/archive/refs/tags/${ARROW_SIMDJSON_BUILD_VERSION}.tar.gz";
   "ARROW_RE2_URL re2-${ARROW_RE2_BUILD_VERSION}.tar.gz 
https://github.com/google/re2/archive/${ARROW_RE2_BUILD_VERSION}.tar.gz";
   "ARROW_S2N_TLS_URL s2n-${ARROW_S2N_TLS_BUILD_VERSION}.tar.gz 
https://github.com/aws/s2n-tls/archive/${ARROW_S2N_TLS_BUILD_VERSION}.tar.gz";
   "ARROW_SNAPPY_URL snappy-${ARROW_SNAPPY_BUILD_VERSION}.tar.gz 
https://github.com/google/snappy/archive/${ARROW_SNAPPY_BUILD_VERSION}.tar.gz";
diff --git a/cpp/vcpkg.json b/cpp/vcpkg.json
index 56e7c00649..1a8ceb3498 100644
--- a/cpp/vcpkg.json
+++ b/cpp/vcpkg.json
@@ -48,6 +48,7 @@
     "protobuf",
     "rapidjson",
     "re2",
+    "simdjson",
     "snappy",
     "sqlite3",
     "thrift",
diff --git a/dev/tasks/linux-packages/apache-arrow/debian/rules 
b/dev/tasks/linux-packages/apache-arrow/debian/rules
index 9b8a7f0ec5..6f636d2d2d 100755
--- a/dev/tasks/linux-packages/apache-arrow/debian/rules
+++ b/dev/tasks/linux-packages/apache-arrow/debian/rules
@@ -74,6 +74,7 @@ override_dh_auto_configure:
          -DARROW_WITH_ZLIB=ON                                  \
          -DARROW_WITH_ZSTD=ON                                  \
          -DCMAKE_BUILD_TYPE=$(BUILD_TYPE)                      \
+         -DCMAKE_VERBOSE_MAKEFILE=OFF                          \
          -DCUDAToolkit_ROOT=/usr                               \
          -DFETCHCONTENT_FULLY_DISCONNECTED=OFF                 \
          -DPARQUET_BUILD_EXECUTABLES=ON                        \

Reply via email to