diff --git a/cpp/examples/arrow/CMakeLists.txt b/cpp/examples/arrow/CMakeLists.txt index ef4beaaca2c..bf0748f5501 100644 --- a/cpp/examples/arrow/CMakeLists.txt +++ b/cpp/examples/arrow/CMakeLists.txt @@ -19,6 +19,7 @@ add_arrow_example(row_wise_conversion_example) if(ARROW_WITH_RAPIDJSON) add_arrow_example(rapidjson_row_converter EXTRA_LINK_LIBS RapidJSON) + add_arrow_example(from_json_string_example EXTRA_LINK_LIBS RapidJSON) endif() if(ARROW_ACERO) diff --git a/cpp/examples/arrow/from_json_string_example.cc b/cpp/examples/arrow/from_json_string_example.cc new file mode 100644 index 00000000000..da13d913489 --- /dev/null +++ b/cpp/examples/arrow/from_json_string_example.cc @@ -0,0 +1,91 @@ +// 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. + +// This example shows how to use some of the *FromJSONString helpers. + +#include +#include + +#include +#include +#include +#include + +using arrow::json::ArrayFromJSONString; +using arrow::json::ChunkedArrayFromJSONString; +using arrow::json::DictArrayFromJSONString; + +/** + * \brief Run Example + * + * ./debug/from-json-string-example + */ +arrow::Status RunExample() { + // Simple types + ARROW_ASSIGN_OR_RAISE(auto int32_array, + ArrayFromJSONString(arrow::int32(), "[1, 2, 3]")); + ARROW_ASSIGN_OR_RAISE(auto float64_array, + ArrayFromJSONString(arrow::float64(), "[4.0, 5.0, 6.0]")); + ARROW_ASSIGN_OR_RAISE(auto bool_array, + ArrayFromJSONString(arrow::boolean(), "[true, false, true]")); + ARROW_ASSIGN_OR_RAISE( + auto string_array, + ArrayFromJSONString(arrow::utf8(), R"(["Hello", "World", null])")); + + // Timestamps can be created from string representations + ARROW_ASSIGN_OR_RAISE( + auto ts_array, + ArrayFromJSONString(timestamp(arrow::TimeUnit::SECOND), + R"(["1970-01-01", "2000-02-29","3989-07-14","1900-02-28"])")); + + // List, Map, Struct + ARROW_ASSIGN_OR_RAISE( + auto list_array, + ArrayFromJSONString(list(arrow::int64()), + "[[null], [], null, [4, 5, 6, 7, 8], [2, 3]]")); + ARROW_ASSIGN_OR_RAISE( + auto map_array, + ArrayFromJSONString(map(arrow::utf8(), arrow::int32()), + R"([[["joe", 0], ["mark", null]], null, [["cap", 8]], []])")); + ARROW_ASSIGN_OR_RAISE( + auto struct_array, + ArrayFromJSONString( + arrow::struct_({field("one", arrow::int32()), field("two", arrow::int32())}), + "[[11, 22], null, [null, 33]]")); + + // ChunkedArrayFromJSONString + std::shared_ptr chunked_array; + ARROW_RETURN_NOT_OK(ChunkedArrayFromJSONString( + arrow::int32(), {"[5, 10]", "[null]", "[16]"}, &chunked_array)); + + // DictArrayFromJSONString + std::shared_ptr dict_array; + ARROW_RETURN_NOT_OK(DictArrayFromJSONString( + dictionary(arrow::int32(), arrow::utf8()), "[0, 1, 0, 2, 0, 3]", + R"(["k1", "k2", "k3", "k4"])", &dict_array)); + + return arrow::Status::OK(); +} + +int main(int argc, char** argv) { + auto status = RunExample(); + if (!status.ok()) { + std::cerr << status.ToString() << std::endl; + return EXIT_FAILURE; + } + return EXIT_SUCCESS; +} diff --git a/cpp/src/arrow/CMakeLists.txt b/cpp/src/arrow/CMakeLists.txt index 7bfdc332f14..3c1dbc46a24 100644 --- a/cpp/src/arrow/CMakeLists.txt +++ b/cpp/src/arrow/CMakeLists.txt @@ -620,6 +620,11 @@ if(ARROW_WITH_OPENTELEMETRY) target_link_libraries(${ARROW_UTIL_TARGET} PRIVATE ${ARROW_OPENTELEMETRY_LIBS}) endforeach() endif() +if(ARROW_WITH_RAPIDJSON) + foreach(ARROW_UTIL_TARGET ${ARROW_UTIL_TARGETS}) + target_link_libraries(${ARROW_UTIL_TARGET} PRIVATE RapidJSON) + endforeach() +endif() if(ARROW_WITH_ZLIB) foreach(ARROW_UTIL_TARGET ${ARROW_UTIL_TARGETS}) target_link_libraries(${ARROW_UTIL_TARGET} PRIVATE ZLIB::ZLIB) @@ -914,18 +919,10 @@ if(ARROW_IPC) ipc/options.cc ipc/reader.cc ipc/writer.cc) - if(ARROW_JSON) - list(APPEND ARROW_IPC_SRCS ipc/json_simple.cc) - endif() arrow_add_object_library(ARROW_IPC ${ARROW_IPC_SRCS}) foreach(ARROW_IPC_TARGET ${ARROW_IPC_TARGETS}) target_link_libraries(${ARROW_IPC_TARGET} PRIVATE arrow::flatbuffers) endforeach() - if(ARROW_JSON) - foreach(ARROW_IPC_TARGET ${ARROW_IPC_TARGETS}) - target_link_libraries(${ARROW_IPC_TARGET} PRIVATE RapidJSON) - endforeach() - endif() else() set(ARROW_IPC_TARGET_SHARED) set(ARROW_IPC_TARGET_STATIC) @@ -939,6 +936,7 @@ if(ARROW_JSON) json/chunked_builder.cc json/chunker.cc json/converter.cc + json/from_string.cc json/object_parser.cc json/object_writer.cc json/parser.cc diff --git a/cpp/src/arrow/c/bridge_benchmark.cc b/cpp/src/arrow/c/bridge_benchmark.cc index 85e091704bf..2df31318ab6 100644 --- a/cpp/src/arrow/c/bridge_benchmark.cc +++ b/cpp/src/arrow/c/bridge_benchmark.cc @@ -22,7 +22,7 @@ #include "arrow/array.h" #include "arrow/c/bridge.h" #include "arrow/c/helpers.h" -#include "arrow/ipc/json_simple.h" +#include "arrow/json/from_string.h" #include "arrow/record_batch.h" #include "arrow/testing/gtest_util.h" #include "arrow/type.h" @@ -79,7 +79,7 @@ static void ExportSchema(benchmark::State& state) { // NOLINT non-const referen static void ExportArray(benchmark::State& state) { // NOLINT non-const reference struct ArrowArray c_export; - auto array = ArrayFromJSON(utf8(), R"(["foo", "bar", null])"); + auto array = arrow::ArrayFromJSON(utf8(), R"(["foo", "bar", null])"); for (auto _ : state) { ABORT_NOT_OK(::arrow::ExportArray(*array, &c_export)); @@ -123,7 +123,7 @@ static void ExportImportSchema(benchmark::State& state) { // NOLINT non-const r static void ExportImportArray(benchmark::State& state) { // NOLINT non-const reference struct ArrowArray c_export; - auto array = ArrayFromJSON(utf8(), R"(["foo", "bar", null])"); + auto array = arrow::ArrayFromJSON(utf8(), R"(["foo", "bar", null])"); auto type = array->type(); for (auto _ : state) { diff --git a/cpp/src/arrow/c/bridge_test.cc b/cpp/src/arrow/c/bridge_test.cc index 5848dd0b55b..75d5d1f428b 100644 --- a/cpp/src/arrow/c/bridge_test.cc +++ b/cpp/src/arrow/c/bridge_test.cc @@ -31,7 +31,6 @@ #include "arrow/c/bridge.h" #include "arrow/c/helpers.h" #include "arrow/c/util_internal.h" -#include "arrow/ipc/json_simple.h" #include "arrow/memory_pool.h" #include "arrow/testing/builder.h" #include "arrow/testing/extension_type.h" diff --git a/cpp/src/arrow/compute/kernels/vector_hash_test.cc b/cpp/src/arrow/compute/kernels/vector_hash_test.cc index 0a966a66f4f..b0fa296e007 100644 --- a/cpp/src/arrow/compute/kernels/vector_hash_test.cc +++ b/cpp/src/arrow/compute/kernels/vector_hash_test.cc @@ -43,8 +43,6 @@ #include "arrow/compute/api.h" #include "arrow/compute/kernels/test_util_internal.h" -#include "arrow/ipc/json_simple.h" - namespace arrow { using internal::checked_cast; diff --git a/cpp/src/arrow/dataset/test_util_internal.h b/cpp/src/arrow/dataset/test_util_internal.h index ee73ebc5a48..a6bc7afb8ff 100644 --- a/cpp/src/arrow/dataset/test_util_internal.h +++ b/cpp/src/arrow/dataset/test_util_internal.h @@ -2140,8 +2140,8 @@ class WriteFileSystemDatasetMixin : public MakeFileSystemDatasetMixin { actual_struct = std::dynamic_pointer_cast(struct_array); } - auto expected_struct = ArrayFromJSON(struct_(expected_physical_schema_->fields()), - file_contents->second); + auto expected_struct = arrow::ArrayFromJSON( + struct_(expected_physical_schema_->fields()), file_contents->second); AssertArraysEqual(*expected_struct, *actual_struct, /*verbose=*/true); } diff --git a/cpp/src/arrow/ipc/CMakeLists.txt b/cpp/src/arrow/ipc/CMakeLists.txt index 9e0b1d723b9..8cbe30f5ae6 100644 --- a/cpp/src/arrow/ipc/CMakeLists.txt +++ b/cpp/src/arrow/ipc/CMakeLists.txt @@ -38,7 +38,6 @@ function(ADD_ARROW_IPC_TEST REL_TEST_NAME) endfunction() add_arrow_test(feather_test) -add_arrow_ipc_test(json_simple_test) add_arrow_ipc_test(message_internal_test) add_arrow_ipc_test(read_write_test) add_arrow_ipc_test(tensor_test) diff --git a/cpp/src/arrow/ipc/api.h b/cpp/src/arrow/ipc/api.h index b5690aed8da..3047180fb1a 100644 --- a/cpp/src/arrow/ipc/api.h +++ b/cpp/src/arrow/ipc/api.h @@ -19,7 +19,6 @@ #include "arrow/ipc/dictionary.h" #include "arrow/ipc/feather.h" -#include "arrow/ipc/json_simple.h" #include "arrow/ipc/message.h" #include "arrow/ipc/reader.h" #include "arrow/ipc/writer.h" diff --git a/cpp/src/arrow/ipc/generate_fuzz_corpus.cc b/cpp/src/arrow/ipc/generate_fuzz_corpus.cc index 6ccf1155d12..123b6981b28 100644 --- a/cpp/src/arrow/ipc/generate_fuzz_corpus.cc +++ b/cpp/src/arrow/ipc/generate_fuzz_corpus.cc @@ -27,9 +27,9 @@ #include "arrow/io/file.h" #include "arrow/io/memory.h" -#include "arrow/ipc/json_simple.h" #include "arrow/ipc/test_common.h" #include "arrow/ipc/writer.h" +#include "arrow/json/from_string.h" #include "arrow/record_batch.h" #include "arrow/result.h" #include "arrow/testing/extension_type.h" @@ -41,7 +41,7 @@ namespace arrow::ipc { using ::arrow::internal::CreateDir; using ::arrow::internal::PlatformFilename; -using internal::json::ArrayFromJSON; +using ::arrow::json::ArrayFromJSONString; Result> MakeExtensionBatch() { auto array = ExampleUuid(); @@ -60,7 +60,7 @@ Result> MakeMapBatch() { [] ] )"; - ARROW_ASSIGN_OR_RAISE(array, ArrayFromJSON(map(int16(), int32()), json_input)); + ARROW_ASSIGN_OR_RAISE(array, ArrayFromJSONString(map(int16(), int32()), json_input)); auto schema = ::arrow::schema({field("f0", array->type())}); return RecordBatch::Make(schema, array->length(), {array}); } diff --git a/cpp/src/arrow/ipc/json_simple.h b/cpp/src/arrow/ipc/json_simple.h deleted file mode 100644 index 3a730ee6a3f..00000000000 --- a/cpp/src/arrow/ipc/json_simple.h +++ /dev/null @@ -1,71 +0,0 @@ -// 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. - -// Implement a simple JSON representation format for arrays - -#pragma once - -#include -#include -#include - -#include "arrow/status.h" -#include "arrow/type_fwd.h" -#include "arrow/util/visibility.h" - -namespace arrow { - -class Array; -class DataType; - -namespace ipc { -namespace internal { -namespace json { - -ARROW_EXPORT -Result> ArrayFromJSON(const std::shared_ptr&, - const std::string& json); - -ARROW_EXPORT -Result> ArrayFromJSON(const std::shared_ptr&, - std::string_view json); - -ARROW_EXPORT -Result> ArrayFromJSON(const std::shared_ptr&, - const char* json); - -ARROW_EXPORT -Status ChunkedArrayFromJSON(const std::shared_ptr& type, - const std::vector& json_strings, - std::shared_ptr* out); - -ARROW_EXPORT -Status DictArrayFromJSON(const std::shared_ptr&, std::string_view indices_json, - std::string_view dictionary_json, std::shared_ptr* out); - -ARROW_EXPORT -Status ScalarFromJSON(const std::shared_ptr&, std::string_view json, - std::shared_ptr* out); - -ARROW_EXPORT -Status DictScalarFromJSON(const std::shared_ptr&, std::string_view index_json, - std::string_view dictionary_json, std::shared_ptr* out); - -} // namespace json -} // namespace internal -} // namespace ipc -} // namespace arrow diff --git a/cpp/src/arrow/json/CMakeLists.txt b/cpp/src/arrow/json/CMakeLists.txt index 95b299d8f0c..fa7d0607848 100644 --- a/cpp/src/arrow/json/CMakeLists.txt +++ b/cpp/src/arrow/json/CMakeLists.txt @@ -20,6 +20,7 @@ add_arrow_test(test chunked_builder_test.cc chunker_test.cc converter_test.cc + from_string_test.cc parser_test.cc reader_test.cc PREFIX diff --git a/cpp/src/arrow/ipc/json_simple.cc b/cpp/src/arrow/json/from_string.cc similarity index 93% rename from cpp/src/arrow/ipc/json_simple.cc rename to cpp/src/arrow/json/from_string.cc index 19f0a6ae1e1..006a7299feb 100644 --- a/cpp/src/arrow/ipc/json_simple.cc +++ b/cpp/src/arrow/json/from_string.cc @@ -31,7 +31,7 @@ #include "arrow/array/builder_time.h" #include "arrow/array/builder_union.h" #include "arrow/chunked_array.h" -#include "arrow/ipc/json_simple.h" +#include "arrow/json/from_string.h" #include "arrow/scalar.h" #include "arrow/type_traits.h" #include "arrow/util/checked_cast.h" @@ -55,14 +55,12 @@ namespace arrow { using internal::ParseValue; using util::Float16; -namespace ipc { -namespace internal { namespace json { using ::arrow::internal::checked_cast; using ::arrow::internal::checked_pointer_cast; -namespace { +namespace internal { constexpr auto kParseFlags = rj::kParseFullPrecisionFlag | rj::kParseNanAndInfFlag; @@ -974,15 +972,15 @@ Status GetConverter(const std::shared_ptr& type, return Status::OK(); } -} // namespace +} // namespace internal -Result> ArrayFromJSON(const std::shared_ptr& type, - std::string_view json_string) { - std::shared_ptr converter; +Result> ArrayFromJSONString(const std::shared_ptr& type, + std::string_view json_string) { + std::shared_ptr converter; RETURN_NOT_OK(GetConverter(type, &converter)); rj::Document json_doc; - json_doc.Parse(json_string.data(), json_string.length()); + json_doc.Parse(json_string.data(), json_string.length()); if (json_doc.HasParseError()) { return Status::Invalid("JSON parse error at offset ", json_doc.GetErrorOffset(), ": ", GetParseError_En(json_doc.GetParseError())); @@ -995,32 +993,33 @@ Result> ArrayFromJSON(const std::shared_ptr& ty return out; } -Result> ArrayFromJSON(const std::shared_ptr& type, - const std::string& json_string) { - return ArrayFromJSON(type, std::string_view(json_string)); +Result> ArrayFromJSONString(const std::shared_ptr& type, + const std::string& json_string) { + return ArrayFromJSONString(type, std::string_view(json_string)); } -Result> ArrayFromJSON(const std::shared_ptr& type, - const char* json_string) { - return ArrayFromJSON(type, std::string_view(json_string)); +Result> ArrayFromJSONString(const std::shared_ptr& type, + const char* json_string) { + return ArrayFromJSONString(type, std::string_view(json_string)); } -Status ChunkedArrayFromJSON(const std::shared_ptr& type, - const std::vector& json_strings, - std::shared_ptr* out) { +Status ChunkedArrayFromJSONString(const std::shared_ptr& type, + const std::vector& json_strings, + std::shared_ptr* out) { ArrayVector out_chunks; out_chunks.reserve(json_strings.size()); for (const std::string& chunk_json : json_strings) { out_chunks.emplace_back(); - ARROW_ASSIGN_OR_RAISE(out_chunks.back(), ArrayFromJSON(type, chunk_json)); + ARROW_ASSIGN_OR_RAISE(out_chunks.back(), ArrayFromJSONString(type, chunk_json)); } *out = std::make_shared(std::move(out_chunks), type); return Status::OK(); } -Status DictArrayFromJSON(const std::shared_ptr& type, - std::string_view indices_json, std::string_view dictionary_json, - std::shared_ptr* out) { +Status DictArrayFromJSONString(const std::shared_ptr& type, + std::string_view indices_json, + std::string_view dictionary_json, + std::shared_ptr* out) { if (type->id() != Type::DICTIONARY) { return Status::TypeError("DictArrayFromJSON requires dictionary type, got ", *type); } @@ -1028,21 +1027,21 @@ Status DictArrayFromJSON(const std::shared_ptr& type, const auto& dictionary_type = checked_cast(*type); ARROW_ASSIGN_OR_RAISE(auto indices, - ArrayFromJSON(dictionary_type.index_type(), indices_json)); - ARROW_ASSIGN_OR_RAISE(auto dictionary, - ArrayFromJSON(dictionary_type.value_type(), dictionary_json)); + ArrayFromJSONString(dictionary_type.index_type(), indices_json)); + ARROW_ASSIGN_OR_RAISE(auto dictionary, ArrayFromJSONString(dictionary_type.value_type(), + dictionary_json)); return DictionaryArray::FromArrays(type, std::move(indices), std::move(dictionary)) .Value(out); } -Status ScalarFromJSON(const std::shared_ptr& type, std::string_view json_string, - std::shared_ptr* out) { - std::shared_ptr converter; +Status ScalarFromJSONString(const std::shared_ptr& type, + std::string_view json_string, std::shared_ptr* out) { + std::shared_ptr converter; RETURN_NOT_OK(GetConverter(type, &converter)); rj::Document json_doc; - json_doc.Parse(json_string.data(), json_string.length()); + json_doc.Parse(json_string.data(), json_string.length()); if (json_doc.HasParseError()) { return Status::Invalid("JSON parse error at offset ", json_doc.GetErrorOffset(), ": ", GetParseError_En(json_doc.GetParseError())); @@ -1055,26 +1054,26 @@ Status ScalarFromJSON(const std::shared_ptr& type, std::string_view js return array->GetScalar(0).Value(out); } -Status DictScalarFromJSON(const std::shared_ptr& type, - std::string_view index_json, std::string_view dictionary_json, - std::shared_ptr* out) { +Status DictScalarFromJSONString(const std::shared_ptr& type, + std::string_view index_json, + std::string_view dictionary_json, + std::shared_ptr* out) { if (type->id() != Type::DICTIONARY) { - return Status::TypeError("DictScalarFromJSON requires dictionary type, got ", *type); + return Status::TypeError("DictScalarFromJSONString requires dictionary type, got ", + *type); } const auto& dictionary_type = checked_cast(*type); std::shared_ptr index; std::shared_ptr dictionary; - RETURN_NOT_OK(ScalarFromJSON(dictionary_type.index_type(), index_json, &index)); - ARROW_ASSIGN_OR_RAISE(dictionary, - ArrayFromJSON(dictionary_type.value_type(), dictionary_json)); + RETURN_NOT_OK(ScalarFromJSONString(dictionary_type.index_type(), index_json, &index)); + ARROW_ASSIGN_OR_RAISE( + dictionary, ArrayFromJSONString(dictionary_type.value_type(), dictionary_json)); *out = DictionaryScalar::Make(std::move(index), std::move(dictionary)); return Status::OK(); } } // namespace json -} // namespace internal -} // namespace ipc } // namespace arrow diff --git a/cpp/src/arrow/json/from_string.h b/cpp/src/arrow/json/from_string.h new file mode 100644 index 00000000000..03c6b1bcdf4 --- /dev/null +++ b/cpp/src/arrow/json/from_string.h @@ -0,0 +1,121 @@ +// 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. + +// Implement a simple JSON representation format for arrays + +#pragma once + +#include +#include +#include + +#include "arrow/status.h" +#include "arrow/type_fwd.h" +#include "arrow/util/visibility.h" + +namespace arrow { + +class Array; +class DataType; + +namespace json { + +/// \defgroup array-from-json-string FromJSONString Helpers +/// +/// These helpers are intended to be used in examples, tests, or for quick +/// prototyping and are not intended to be used where performance matters. +/// +/// See the User Guide for +/// more information. +/// +/// @{ + +/// \brief Create an Array from a JSON string +/// +/// \code {.cpp} +/// std::shared_ptr array = ArrayFromJSONString( +/// int64(), "[2, 3, null, 7, 11]" +/// ).ValueOrDie(); +/// \endcode +ARROW_EXPORT +Result> ArrayFromJSONString(const std::shared_ptr&, + const std::string& json); + +/// \copydoc ArrayFromJSONString(const std::shared_ptr&, const std::string&) +ARROW_EXPORT +Result> ArrayFromJSONString(const std::shared_ptr&, + std::string_view json); + +/// \copydoc ArrayFromJSONString(const std::shared_ptr&, const std::string&) +ARROW_EXPORT +Result> ArrayFromJSONString(const std::shared_ptr&, + const char* json); + +/// \brief Create a ChunkedArray from a JSON string +/// +/// \code {.cpp} +/// std::shared_ptr chunked_array; +/// ChunkedArrayFromJSONString( +/// int64(), {R"([5, 10])", R"([null])", R"([16])"}, &chunked_array +/// ); +/// \endcode +ARROW_EXPORT +Status ChunkedArrayFromJSONString(const std::shared_ptr& type, + const std::vector& json_strings, + std::shared_ptr* out); + +/// \brief Create a DictionaryArray from a JSON string +/// +/// \code {.cpp} +/// std::shared_ptr array; +/// DictArrayFromJSONString( +/// dictionary(int32(), utf8()), +/// "[0, 1, 0, 2, 0, 3]", R"(["k1", "k2", "k3", "k4"])", +/// &array +/// ); +/// \endcode +ARROW_EXPORT +Status DictArrayFromJSONString(const std::shared_ptr&, + std::string_view indices_json, + std::string_view dictionary_json, + std::shared_ptr* out); + +/// \brief Create a Scalar from a JSON string +/// \code {.cpp} +/// std::shared_ptr scalar; +/// ScalarFromJSONString(float64(), "42", &scalar); +/// \endcode +ARROW_EXPORT +Status ScalarFromJSONString(const std::shared_ptr&, std::string_view json, + std::shared_ptr* out); + +/// \brief Create a DictionaryScalar from a JSON string +/// \code {.cpp} +/// std::shared_ptr scalar; +/// DictScalarFromJSONString(dictionary(int32(), utf8()), "3", R"(["k1", "k2", "k3", +/// "k4"])", &scalar); +/// \endcode +ARROW_EXPORT +Status DictScalarFromJSONString(const std::shared_ptr&, + std::string_view index_json, + std::string_view dictionary_json, + std::shared_ptr* out); + +/// @} + +} // namespace json +} // namespace arrow diff --git a/cpp/src/arrow/ipc/json_simple_test.cc b/cpp/src/arrow/json/from_string_test.cc similarity index 77% rename from cpp/src/arrow/ipc/json_simple_test.cc rename to cpp/src/arrow/json/from_string_test.cc index 31312f1ac69..d9fa53f68cb 100644 --- a/cpp/src/arrow/ipc/json_simple_test.cc +++ b/cpp/src/arrow/json/from_string_test.cc @@ -35,7 +35,7 @@ #include "arrow/array/builder_primitive.h" #include "arrow/array/builder_time.h" #include "arrow/chunked_array.h" -#include "arrow/ipc/json_simple.h" +#include "arrow/json/from_string.h" #include "arrow/scalar.h" #include "arrow/testing/builder.h" #include "arrow/testing/gtest_util.h" @@ -55,8 +55,6 @@ namespace arrow { using util::Float16; -namespace ipc { -namespace internal { namespace json { using ::arrow::internal::BytesToBits; @@ -109,7 +107,7 @@ void AssertJSONArray(const std::shared_ptr& type, const std::string& j const std::vector& values) { std::shared_ptr expected; - ASSERT_OK_AND_ASSIGN(auto actual, ArrayFromJSON(type, json)); + ASSERT_OK_AND_ASSIGN(auto actual, ArrayFromJSONString(type, json)); ASSERT_OK(actual->ValidateFull()); ArrayFromVector(type, values, &expected); AssertArraysEqual(*expected, *actual); @@ -121,7 +119,7 @@ void AssertJSONArray(const std::shared_ptr& type, const std::string& j const std::vector& values) { std::shared_ptr expected; - ASSERT_OK_AND_ASSIGN(auto actual, ArrayFromJSON(type, json)); + ASSERT_OK_AND_ASSIGN(auto actual, ArrayFromJSONString(type, json)); ASSERT_OK(actual->ValidateFull()); ArrayFromVector(type, is_valid, values, &expected); AssertArraysEqual(*expected, *actual); @@ -135,11 +133,11 @@ void AssertJSONDictArray(const std::shared_ptr& index_type, auto type = dictionary(index_type, value_type); ASSERT_OK_AND_ASSIGN(auto expected_indices, - ArrayFromJSON(index_type, expected_indices_json)); + ArrayFromJSONString(index_type, expected_indices_json)); ASSERT_OK_AND_ASSIGN(auto expected_values, - ArrayFromJSON(value_type, expected_values_json)); + ArrayFromJSONString(value_type, expected_values_json)); - ASSERT_OK_AND_ASSIGN(auto actual, ArrayFromJSON(type, json)); + ASSERT_OK_AND_ASSIGN(auto actual, ArrayFromJSONString(type, json)); ASSERT_OK(actual->ValidateFull()); const auto& dict_array = checked_cast(*actual); @@ -153,7 +151,7 @@ void AssertJSONScalar(const std::shared_ptr& type, const std::string& SCOPED_TRACE(json); std::shared_ptr actual, expected; - ASSERT_OK(ScalarFromJSON(type, json, &actual)); + ASSERT_OK(ScalarFromJSONString(type, json, &actual)); if (is_valid) { ASSERT_OK_AND_ASSIGN(expected, MakeScalar(type, value)); } else { @@ -212,13 +210,13 @@ TYPED_TEST_P(TestIntegers, Basics) { TYPED_TEST_P(TestIntegers, Errors) { std::shared_ptr array; auto type = this->type(); - ASSERT_RAISES(Invalid, ArrayFromJSON(type, "")); - ASSERT_RAISES(Invalid, ArrayFromJSON(type, "[")); - ASSERT_RAISES(Invalid, ArrayFromJSON(type, "0")); - ASSERT_RAISES(Invalid, ArrayFromJSON(type, "{}")); - ASSERT_RAISES(Invalid, ArrayFromJSON(type, "[0.0]")); - ASSERT_RAISES(Invalid, ArrayFromJSON(type, "[\"0\"]")); - ASSERT_RAISES(Invalid, ArrayFromJSON(type, "[[0]]")); + ASSERT_RAISES(Invalid, ArrayFromJSONString(type, "")); + ASSERT_RAISES(Invalid, ArrayFromJSONString(type, "[")); + ASSERT_RAISES(Invalid, ArrayFromJSONString(type, "0")); + ASSERT_RAISES(Invalid, ArrayFromJSONString(type, "{}")); + ASSERT_RAISES(Invalid, ArrayFromJSONString(type, "[0.0]")); + ASSERT_RAISES(Invalid, ArrayFromJSONString(type, "[\"0\"]")); + ASSERT_RAISES(Invalid, ArrayFromJSONString(type, "[[0]]")); } TYPED_TEST_P(TestIntegers, OutOfBounds) { @@ -229,23 +227,23 @@ TYPED_TEST_P(TestIntegers, OutOfBounds) { auto type = this->type(); if (type->id() == Type::UINT64) { - ASSERT_RAISES(Invalid, ArrayFromJSON(type, "[18446744073709551616]")); - ASSERT_RAISES(Invalid, ArrayFromJSON(type, "[-1]")); + ASSERT_RAISES(Invalid, ArrayFromJSONString(type, "[18446744073709551616]")); + ASSERT_RAISES(Invalid, ArrayFromJSONString(type, "[-1]")); } else if (type->id() == Type::INT64) { - ASSERT_RAISES(Invalid, ArrayFromJSON(type, "[9223372036854775808]")); - ASSERT_RAISES(Invalid, ArrayFromJSON(type, "[-9223372036854775809]")); + ASSERT_RAISES(Invalid, ArrayFromJSONString(type, "[9223372036854775808]")); + ASSERT_RAISES(Invalid, ArrayFromJSONString(type, "[-9223372036854775809]")); } else if (std::is_signed::value) { const auto lower = SafeSignedAdd(std::numeric_limits::min(), -1); const auto upper = SafeSignedAdd(std::numeric_limits::max(), +1); auto json_string = JSONArray(lower); - ASSERT_RAISES(Invalid, ArrayFromJSON(type, json_string)); + ASSERT_RAISES(Invalid, ArrayFromJSONString(type, json_string)); json_string = JSONArray(upper); - ASSERT_RAISES(Invalid, ArrayFromJSON(type, json_string)); + ASSERT_RAISES(Invalid, ArrayFromJSONString(type, json_string)); } else { const auto upper = static_cast(std::numeric_limits::max()) + 1; auto json_string = JSONArray(upper); - ASSERT_RAISES(Invalid, ArrayFromJSON(type, json_string)); - ASSERT_RAISES(Invalid, ArrayFromJSON(type, "[-1]")); + ASSERT_RAISES(Invalid, ArrayFromJSONString(type, json_string)); + ASSERT_RAISES(Invalid, ArrayFromJSONString(type, "[-1]")); } } @@ -321,8 +319,8 @@ TYPED_TEST_P(TestStrings, Errors) { auto type = this->type(); std::shared_ptr array; - ASSERT_RAISES(Invalid, ArrayFromJSON(type, "[0]")); - ASSERT_RAISES(Invalid, ArrayFromJSON(type, "[[]]")); + ASSERT_RAISES(Invalid, ArrayFromJSONString(type, "[0]")); + ASSERT_RAISES(Invalid, ArrayFromJSONString(type, "[[]]")); } TYPED_TEST_P(TestStrings, Dictionary) { @@ -354,9 +352,9 @@ TEST(TestNull, Errors) { std::shared_ptr type = null(); std::shared_ptr array; - ASSERT_RAISES(Invalid, ArrayFromJSON(type, "[[]]")); - ASSERT_RAISES(Invalid, ArrayFromJSON(type, "[0]")); - ASSERT_RAISES(Invalid, ArrayFromJSON(type, "[NaN]")); + ASSERT_RAISES(Invalid, ArrayFromJSONString(type, "[[]]")); + ASSERT_RAISES(Invalid, ArrayFromJSONString(type, "[0]")); + ASSERT_RAISES(Invalid, ArrayFromJSONString(type, "[NaN]")); } TEST(TestBoolean, Basics) { @@ -376,8 +374,8 @@ TEST(TestBoolean, Errors) { std::shared_ptr type = boolean(); std::shared_ptr array; - ASSERT_RAISES(Invalid, ArrayFromJSON(type, "[0.0]")); - ASSERT_RAISES(Invalid, ArrayFromJSON(type, "[\"true\"]")); + ASSERT_RAISES(Invalid, ArrayFromJSONString(type, "[0.0]")); + ASSERT_RAISES(Invalid, ArrayFromJSONString(type, "[\"true\"]")); } TEST(TestFloat, Basics) { @@ -391,7 +389,7 @@ TEST(TestFloat, Basics) { // Check NaN separately as AssertArraysEqual simply memcmp's array contents // and NaNs can have many bit representations. - ASSERT_OK_AND_ASSIGN(actual, ArrayFromJSON(type, "[NaN]")); + ASSERT_OK_AND_ASSIGN(actual, ArrayFromJSONString(type, "[NaN]")); ASSERT_OK(actual->ValidateFull()); float value = checked_cast(*actual).Value(0); ASSERT_TRUE(std::isnan(value)); @@ -401,7 +399,7 @@ TEST(TestFloat, Errors) { std::shared_ptr type = float32(); std::shared_ptr array; - ASSERT_RAISES(Invalid, ArrayFromJSON(type, "[true]")); + ASSERT_RAISES(Invalid, ArrayFromJSONString(type, "[true]")); } TEST(TestDouble, Basics) { @@ -413,7 +411,7 @@ TEST(TestDouble, Basics) { AssertJSONArray(type, "[-0.0, Inf, -Inf, null]", {true, true, true, false}, {-0.0, INFINITY, -INFINITY, 0.0}); - ASSERT_OK_AND_ASSIGN(actual, ArrayFromJSON(type, "[NaN]")); + ASSERT_OK_AND_ASSIGN(actual, ArrayFromJSONString(type, "[NaN]")); ASSERT_OK(actual->ValidateFull()); double value = checked_cast(*actual).Value(0); ASSERT_TRUE(std::isnan(value)); @@ -423,7 +421,7 @@ TEST(TestDouble, Errors) { std::shared_ptr type = float64(); std::shared_ptr array; - ASSERT_RAISES(Invalid, ArrayFromJSON(type, "[true]")); + ASSERT_RAISES(Invalid, ArrayFromJSONString(type, "[true]")); } TEST(TestTimestamp, Basics) { @@ -516,11 +514,11 @@ TEST(TestFixedSizeBinary, Errors) { std::shared_ptr type = fixed_size_binary(3); std::shared_ptr array; - ASSERT_RAISES(Invalid, ArrayFromJSON(type, "[0]")); - ASSERT_RAISES(Invalid, ArrayFromJSON(type, "[[]]")); + ASSERT_RAISES(Invalid, ArrayFromJSONString(type, "[0]")); + ASSERT_RAISES(Invalid, ArrayFromJSONString(type, "[[]]")); // Invalid length - ASSERT_RAISES(Invalid, ArrayFromJSON(type, "[\"\"]")); - ASSERT_RAISES(Invalid, ArrayFromJSON(type, "[\"abcd\"]")); + ASSERT_RAISES(Invalid, ArrayFromJSONString(type, "[\"\"]")); + ASSERT_RAISES(Invalid, ArrayFromJSONString(type, "[\"abcd\"]")); } TEST(TestFixedSizeBinary, Dictionary) { @@ -532,14 +530,14 @@ TEST(TestFixedSizeBinary, Dictionary) { // Invalid length std::shared_ptr array; - ASSERT_RAISES(Invalid, ArrayFromJSON(dictionary(int8(), type), R"(["x"])")); + ASSERT_RAISES(Invalid, ArrayFromJSONString(dictionary(int8(), type), R"(["x"])")); } template void TestDecimalBasic(std::shared_ptr type) { std::shared_ptr expected, actual; - ASSERT_OK_AND_ASSIGN(actual, ArrayFromJSON(type, "[]")); + ASSERT_OK_AND_ASSIGN(actual, ArrayFromJSONString(type, "[]")); ASSERT_OK(actual->ValidateFull()); { DecimalBuilder builder(type); @@ -547,7 +545,7 @@ void TestDecimalBasic(std::shared_ptr type) { } AssertArraysEqual(*expected, *actual); - ASSERT_OK_AND_ASSIGN(actual, ArrayFromJSON(type, "[\"123.4567\", \"-78.9000\"]")); + ASSERT_OK_AND_ASSIGN(actual, ArrayFromJSONString(type, "[\"123.4567\", \"-78.9000\"]")); ASSERT_OK(actual->ValidateFull()); { DecimalBuilder builder(type); @@ -557,7 +555,7 @@ void TestDecimalBasic(std::shared_ptr type) { } AssertArraysEqual(*expected, *actual); - ASSERT_OK_AND_ASSIGN(actual, ArrayFromJSON(type, "[\"123.4567\", null]")); + ASSERT_OK_AND_ASSIGN(actual, ArrayFromJSONString(type, "[\"123.4567\", null]")); ASSERT_OK(actual->ValidateFull()); { DecimalBuilder builder(type); @@ -589,11 +587,11 @@ TEST(TestDecimal, Errors) { {decimal32(8, 4), decimal64(10, 4), decimal128(10, 4), decimal256(10, 4)}) { std::shared_ptr array; - ASSERT_RAISES(Invalid, ArrayFromJSON(type, "[0]")); - ASSERT_RAISES(Invalid, ArrayFromJSON(type, "[12.3456]")); + ASSERT_RAISES(Invalid, ArrayFromJSONString(type, "[0]")); + ASSERT_RAISES(Invalid, ArrayFromJSONString(type, "[12.3456]")); // Bad scale - ASSERT_RAISES(Invalid, ArrayFromJSON(type, "[\"12.345\"]")); - ASSERT_RAISES(Invalid, ArrayFromJSON(type, "[\"12.34560\"]")); + ASSERT_RAISES(Invalid, ArrayFromJSONString(type, "[\"12.345\"]")); + ASSERT_RAISES(Invalid, ArrayFromJSONString(type, "[\"12.34560\"]")); } } @@ -623,7 +621,7 @@ class TestVarLengthListArray : public ::testing::Test { std::shared_ptr type = std::make_shared(int64()); std::shared_ptr offsets, sizes, values, expected, actual; - ASSERT_OK_AND_ASSIGN(actual, ArrayFromJSON(type, "[]")); + ASSERT_OK_AND_ASSIGN(actual, ArrayFromJSONString(type, "[]")); ASSERT_OK(actual->ValidateFull()); ArrayFromVector({0}, &offsets); ArrayFromVector({}, &values); @@ -636,7 +634,7 @@ class TestVarLengthListArray : public ::testing::Test { } AssertArraysEqual(*expected, *actual); - ASSERT_OK_AND_ASSIGN(actual, ArrayFromJSON(type, "[[4, 5], [], [6]]")); + ASSERT_OK_AND_ASSIGN(actual, ArrayFromJSONString(type, "[[4, 5], [], [6]]")); ASSERT_OK(actual->ValidateFull()); ArrayFromVector({0, 2, 2, 3}, &offsets); ArrayFromVector({4, 5, 6}, &values); @@ -649,7 +647,7 @@ class TestVarLengthListArray : public ::testing::Test { } AssertArraysEqual(*expected, *actual); - ASSERT_OK_AND_ASSIGN(actual, ArrayFromJSON(type, "[[], [null], [6, null]]")); + ASSERT_OK_AND_ASSIGN(actual, ArrayFromJSONString(type, "[[], [null], [6, null]]")); ASSERT_OK(actual->ValidateFull()); ArrayFromVector({0, 0, 1, 3}, &offsets); auto is_valid = std::vector{false, true, false}; @@ -663,7 +661,7 @@ class TestVarLengthListArray : public ::testing::Test { } AssertArraysEqual(*expected, *actual); - ASSERT_OK_AND_ASSIGN(actual, ArrayFromJSON(type, "[null, [], null]")); + ASSERT_OK_AND_ASSIGN(actual, ArrayFromJSONString(type, "[null, [], null]")); ASSERT_OK(actual->ValidateFull()); { std::unique_ptr builder; @@ -681,9 +679,9 @@ class TestVarLengthListArray : public ::testing::Test { std::shared_ptr type = std::make_shared(int64()); std::shared_ptr array; - ASSERT_RAISES(Invalid, ArrayFromJSON(type, "[0]")); - ASSERT_RAISES(Invalid, ArrayFromJSON(type, "[[0.0]]")); - ASSERT_RAISES(Invalid, ArrayFromJSON(type, "[[9223372036854775808]]")); + ASSERT_RAISES(Invalid, ArrayFromJSONString(type, "[0]")); + ASSERT_RAISES(Invalid, ArrayFromJSONString(type, "[[0.0]]")); + ASSERT_RAISES(Invalid, ArrayFromJSONString(type, "[[9223372036854775808]]")); } void TestNullList() { @@ -691,7 +689,7 @@ class TestVarLengthListArray : public ::testing::Test { std::shared_ptr type = std::make_shared(null()); std::shared_ptr offsets, sizes, values, expected, actual; - ASSERT_OK_AND_ASSIGN(actual, ArrayFromJSON(type, "[]")); + ASSERT_OK_AND_ASSIGN(actual, ArrayFromJSONString(type, "[]")); ASSERT_OK(actual->ValidateFull()); ArrayFromVector({0}, &offsets); values = std::make_shared(0); @@ -704,7 +702,7 @@ class TestVarLengthListArray : public ::testing::Test { } AssertArraysEqual(*expected, *actual); - ASSERT_OK_AND_ASSIGN(actual, ArrayFromJSON(type, "[[], [null], [null, null]]")); + ASSERT_OK_AND_ASSIGN(actual, ArrayFromJSONString(type, "[[], [null], [null, null]]")); ASSERT_OK(actual->ValidateFull()); ArrayFromVector({0, 0, 1, 3}, &offsets); values = std::make_shared(3); @@ -717,7 +715,7 @@ class TestVarLengthListArray : public ::testing::Test { } AssertArraysEqual(*expected, *actual); - ASSERT_OK_AND_ASSIGN(actual, ArrayFromJSON(type, "[null, [], null]")); + ASSERT_OK_AND_ASSIGN(actual, ArrayFromJSONString(type, "[null, [], null]")); ASSERT_OK(actual->ValidateFull()); { std::unique_ptr builder; @@ -737,7 +735,8 @@ class TestVarLengthListArray : public ::testing::Test { std::make_shared(std::make_shared(uint8())); std::shared_ptr offsets, sizes, values, nested, expected, actual; - ASSERT_OK_AND_ASSIGN(actual, ArrayFromJSON(type, "[[[4], [5, 6]], [[7, 8, 9]]]")); + ASSERT_OK_AND_ASSIGN(actual, + ArrayFromJSONString(type, "[[[4], [5, 6]], [[7, 8, 9]]]")); ASSERT_OK(actual->ValidateFull()); ArrayFromVector({0, 1, 3, 6}, &offsets); ArrayFromVector({4, 5, 6, 7, 8, 9}, &values); @@ -760,7 +759,7 @@ class TestVarLengthListArray : public ::testing::Test { AssertArraysEqual(*expected, *actual); ASSERT_OK_AND_ASSIGN( - actual, ArrayFromJSON(type, "[[], [[]], [[4], [], [5, 6]], [[7, 8, 9]]]")); + actual, ArrayFromJSONString(type, "[[], [[]], [[4], [], [5, 6]], [[7, 8, 9]]]")); ASSERT_OK(actual->ValidateFull()); ArrayFromVector({0, 0, 1, 1, 3, 6}, &offsets); ArrayFromVector({4, 5, 6, 7, 8, 9}, &values); @@ -782,7 +781,7 @@ class TestVarLengthListArray : public ::testing::Test { ASSERT_EQ(actual->length(), 4); AssertArraysEqual(*expected, *actual); - ASSERT_OK_AND_ASSIGN(actual, ArrayFromJSON(type, "[null, [null], [[null]]]")); + ASSERT_OK_AND_ASSIGN(actual, ArrayFromJSONString(type, "[null, [null], [[null]]]")); ASSERT_OK(actual->ValidateFull()); { std::unique_ptr builder; @@ -821,7 +820,7 @@ TEST(TestMap, IntegerToInteger) { [] ] )"; - ASSERT_OK_AND_ASSIGN(actual, ArrayFromJSON(type, input)); + ASSERT_OK_AND_ASSIGN(actual, ArrayFromJSONString(type, input)); std::unique_ptr builder; ASSERT_OK(MakeBuilder(default_memory_pool(), type, &builder)); @@ -852,11 +851,12 @@ TEST(TestMap, StringToInteger) { [] ] )"; - ASSERT_OK_AND_ASSIGN(auto actual, ArrayFromJSON(type, input)); + ASSERT_OK_AND_ASSIGN(auto actual, ArrayFromJSONString(type, input)); std::vector offsets = {0, 2, 2, 3, 3}; ASSERT_OK_AND_ASSIGN(auto expected_keys, - ArrayFromJSON(utf8(), R"(["joe", "mark", "cap"])")); - ASSERT_OK_AND_ASSIGN(auto expected_values, ArrayFromJSON(int32(), "[0, null, 8]")); + ArrayFromJSONString(utf8(), R"(["joe", "mark", "cap"])")); + ASSERT_OK_AND_ASSIGN(auto expected_values, + ArrayFromJSONString(int32(), "[0, null, 8]")); ASSERT_OK_AND_ASSIGN(auto expected_null_bitmap, BytesToBits(std::vector({1, 0, 1, 1}))); auto expected = @@ -870,18 +870,18 @@ TEST(TestMap, Errors) { std::shared_ptr array; // list of pairs isn't an array - ASSERT_RAISES(Invalid, ArrayFromJSON(type, "[0]")); + ASSERT_RAISES(Invalid, ArrayFromJSONString(type, "[0]")); // pair isn't an array - ASSERT_RAISES(Invalid, ArrayFromJSON(type, "[[0]]")); - ASSERT_RAISES(Invalid, ArrayFromJSON(type, "[[null]]")); + ASSERT_RAISES(Invalid, ArrayFromJSONString(type, "[[0]]")); + ASSERT_RAISES(Invalid, ArrayFromJSONString(type, "[[null]]")); // pair with length != 2 - ASSERT_RAISES(Invalid, ArrayFromJSON(type, "[[[0]]]")); - ASSERT_RAISES(Invalid, ArrayFromJSON(type, "[[[0, 1, 2]]]")); + ASSERT_RAISES(Invalid, ArrayFromJSONString(type, "[[[0]]]")); + ASSERT_RAISES(Invalid, ArrayFromJSONString(type, "[[[0, 1, 2]]]")); // null key - ASSERT_RAISES(Invalid, ArrayFromJSON(type, "[[[null, 0]]]")); + ASSERT_RAISES(Invalid, ArrayFromJSONString(type, "[[[null, 0]]]")); // key or value fails to convert - ASSERT_RAISES(Invalid, ArrayFromJSON(type, "[[[0.0, 0]]]")); - ASSERT_RAISES(Invalid, ArrayFromJSON(type, "[[[0, 0.0]]]")); + ASSERT_RAISES(Invalid, ArrayFromJSONString(type, "[[[0.0, 0]]]")); + ASSERT_RAISES(Invalid, ArrayFromJSONString(type, "[[[0, 0.0]]]")); } TEST(TestMap, IntegerMapToStringList) { @@ -907,7 +907,7 @@ TEST(TestMap, IntegerMapToStringList) { null ] )"; - ASSERT_OK_AND_ASSIGN(actual, ArrayFromJSON(type, input)); + ASSERT_OK_AND_ASSIGN(actual, ArrayFromJSONString(type, input)); std::unique_ptr builder; ASSERT_OK(MakeBuilder(default_memory_pool(), type, &builder)); @@ -916,7 +916,8 @@ TEST(TestMap, IntegerMapToStringList) { auto& key_key_builder = checked_cast(*key_builder.key_builder()); auto& key_item_builder = checked_cast(*key_builder.item_builder()); auto& item_builder = checked_cast(*map_builder.item_builder()); - auto& item_value_builder = checked_cast(*item_builder.value_builder()); + auto& item_value_builder = + checked_cast(*item_builder.value_builder()); ASSERT_OK(map_builder.Append()); ASSERT_OK(key_builder.Append()); @@ -949,27 +950,27 @@ TEST(TestFixedSizeList, IntegerList) { auto type = fixed_size_list(int64(), 2); std::shared_ptr values, expected, actual; - ASSERT_OK_AND_ASSIGN(actual, ArrayFromJSON(type, "[]")); + ASSERT_OK_AND_ASSIGN(actual, ArrayFromJSONString(type, "[]")); ASSERT_OK(actual->ValidateFull()); ArrayFromVector({}, &values); expected = std::make_shared(type, 0, values); AssertArraysEqual(*expected, *actual); - ASSERT_OK_AND_ASSIGN(actual, ArrayFromJSON(type, "[[4, 5], [0, 0], [6, 7]]")); + ASSERT_OK_AND_ASSIGN(actual, ArrayFromJSONString(type, "[[4, 5], [0, 0], [6, 7]]")); ASSERT_OK(actual->ValidateFull()); ArrayFromVector({4, 5, 0, 0, 6, 7}, &values); expected = std::make_shared(type, 3, values); AssertArraysEqual(*expected, *actual); ASSERT_OK_AND_ASSIGN(actual, - ArrayFromJSON(type, "[[null, null], [0, null], [6, null]]")); + ArrayFromJSONString(type, "[[null, null], [0, null], [6, null]]")); ASSERT_OK(actual->ValidateFull()); auto is_valid = std::vector{false, false, true, false, true, false}; ArrayFromVector(is_valid, {0, 0, 0, 0, 6, 0}, &values); expected = std::make_shared(type, 3, values); AssertArraysEqual(*expected, *actual); - ASSERT_OK_AND_ASSIGN(actual, ArrayFromJSON(type, "[null, [null, null], null]")); + ASSERT_OK_AND_ASSIGN(actual, ArrayFromJSONString(type, "[null, [null, null], null]")); ASSERT_OK(actual->ValidateFull()); { std::unique_ptr builder; @@ -990,10 +991,10 @@ TEST(TestFixedSizeList, IntegerListErrors) { std::shared_ptr type = fixed_size_list(int64(), 2); std::shared_ptr array; - ASSERT_RAISES(Invalid, ArrayFromJSON(type, "[0]")); - ASSERT_RAISES(Invalid, ArrayFromJSON(type, "[[0.0, 1.0]]")); - ASSERT_RAISES(Invalid, ArrayFromJSON(type, "[[0]]")); - ASSERT_RAISES(Invalid, ArrayFromJSON(type, "[[9223372036854775808, 0]]")); + ASSERT_RAISES(Invalid, ArrayFromJSONString(type, "[0]")); + ASSERT_RAISES(Invalid, ArrayFromJSONString(type, "[[0.0, 1.0]]")); + ASSERT_RAISES(Invalid, ArrayFromJSONString(type, "[[0]]")); + ASSERT_RAISES(Invalid, ArrayFromJSONString(type, "[[9223372036854775808, 0]]")); } TEST(TestFixedSizeList, NullList) { @@ -1001,20 +1002,20 @@ TEST(TestFixedSizeList, NullList) { std::shared_ptr type = fixed_size_list(null(), 2); std::shared_ptr values, expected, actual; - ASSERT_OK_AND_ASSIGN(actual, ArrayFromJSON(type, "[]")); + ASSERT_OK_AND_ASSIGN(actual, ArrayFromJSONString(type, "[]")); ASSERT_OK(actual->ValidateFull()); values = std::make_shared(0); expected = std::make_shared(type, 0, values); AssertArraysEqual(*expected, *actual); - ASSERT_OK_AND_ASSIGN(actual, - ArrayFromJSON(type, "[[null, null], [null, null], [null, null]]")); + ASSERT_OK_AND_ASSIGN( + actual, ArrayFromJSONString(type, "[[null, null], [null, null], [null, null]]")); ASSERT_OK(actual->ValidateFull()); values = std::make_shared(6); expected = std::make_shared(type, 3, values); AssertArraysEqual(*expected, *actual); - ASSERT_OK_AND_ASSIGN(actual, ArrayFromJSON(type, "[null, [null, null], null]")); + ASSERT_OK_AND_ASSIGN(actual, ArrayFromJSONString(type, "[null, [null, null], null]")); ASSERT_OK(actual->ValidateFull()); { std::unique_ptr builder; @@ -1037,14 +1038,15 @@ TEST(TestFixedSizeList, IntegerListList) { std::shared_ptr type = fixed_size_list(nested_type, 1); std::shared_ptr values, nested, expected, actual; - ASSERT_OK_AND_ASSIGN(actual, ArrayFromJSON(type, "[[[1, 4]], [[2, 5]], [[3, 6]]]")); + ASSERT_OK_AND_ASSIGN(actual, + ArrayFromJSONString(type, "[[[1, 4]], [[2, 5]], [[3, 6]]]")); ASSERT_OK(actual->ValidateFull()); ArrayFromVector({1, 4, 2, 5, 3, 6}, &values); nested = std::make_shared(nested_type, 3, values); expected = std::make_shared(type, 3, nested); AssertArraysEqual(*expected, *actual); - ASSERT_OK_AND_ASSIGN(actual, ArrayFromJSON(type, "[[[1, null]], [null], null]")); + ASSERT_OK_AND_ASSIGN(actual, ArrayFromJSONString(type, "[[[1, null]], [null], null]")); ASSERT_OK(actual->ValidateFull()); { std::unique_ptr builder; @@ -1079,7 +1081,7 @@ TEST(TestStruct, SimpleStruct) { std::vector> children; // Trivial - ASSERT_OK_AND_ASSIGN(actual, ArrayFromJSON(type, "[]")); + ASSERT_OK_AND_ASSIGN(actual, ArrayFromJSONString(type, "[]")); ASSERT_OK(actual->ValidateFull()); ArrayFromVector({}, &a); ArrayFromVector({}, &b); @@ -1093,11 +1095,12 @@ TEST(TestStruct, SimpleStruct) { children.assign({a, b}); expected = std::make_shared(type, 2, children); - ASSERT_OK_AND_ASSIGN(actual, ArrayFromJSON(type, "[[5, true], [6, false]]")); + ASSERT_OK_AND_ASSIGN(actual, ArrayFromJSONString(type, "[[5, true], [6, false]]")); ASSERT_OK(actual->ValidateFull()); AssertArraysEqual(*expected, *actual); ASSERT_OK_AND_ASSIGN( - actual, ArrayFromJSON(type, "[{\"a\": 5, \"b\": true}, {\"b\": false, \"a\": 6}]")); + actual, + ArrayFromJSONString(type, "[{\"a\": 5, \"b\": true}, {\"b\": false, \"a\": 6}]")); ASSERT_OK(actual->ValidateFull()); AssertArraysEqual(*expected, *actual); @@ -1111,12 +1114,14 @@ TEST(TestStruct, SimpleStruct) { expected = std::make_shared(type, 4, children, null_bitmap, 1); ASSERT_OK_AND_ASSIGN( - actual, ArrayFromJSON(type, "[null, [5, null], [null, false], [null, null]]")); + actual, + ArrayFromJSONString(type, "[null, [5, null], [null, false], [null, null]]")); ASSERT_OK(actual->ValidateFull()); AssertArraysEqual(*expected, *actual); // When using object notation, null members can be omitted ASSERT_OK_AND_ASSIGN( - actual, ArrayFromJSON(type, "[null, {\"a\": 5, \"b\": null}, {\"b\": false}, {}]")); + actual, + ArrayFromJSONString(type, "[null, {\"a\": 5, \"b\": null}, {\"b\": false}, {}]")); ASSERT_OK(actual->ValidateFull()); AssertArraysEqual(*expected, *actual); } @@ -1133,7 +1138,7 @@ TEST(TestStruct, NestedStruct) { std::vector is_valid; std::vector> children(2); - ASSERT_OK_AND_ASSIGN(actual, ArrayFromJSON(type, "[]")); + ASSERT_OK_AND_ASSIGN(actual, ArrayFromJSONString(type, "[]")); ASSERT_OK(actual->ValidateFull()); ArrayFromVector({}, &children[0]); ArrayFromVector({}, &children[1]); @@ -1142,8 +1147,8 @@ TEST(TestStruct, NestedStruct) { expected = std::make_shared(type, 0, children); AssertArraysEqual(*expected, *actual); - ASSERT_OK_AND_ASSIGN(actual, - ArrayFromJSON(type, "[[[5, true], 1.5], [[6, false], -3e2]]")); + ASSERT_OK_AND_ASSIGN( + actual, ArrayFromJSONString(type, "[[[5, true], 1.5], [[6, false], -3e2]]")); ASSERT_OK(actual->ValidateFull()); ArrayFromVector({5, 6}, &children[0]); ArrayFromVector({true, false}, &children[1]); @@ -1152,8 +1157,8 @@ TEST(TestStruct, NestedStruct) { expected = std::make_shared(type, 2, children); AssertArraysEqual(*expected, *actual); - ASSERT_OK_AND_ASSIGN(actual, - ArrayFromJSON(type, "[null, [[5, null], null], [null, -3e2]]")); + ASSERT_OK_AND_ASSIGN( + actual, ArrayFromJSONString(type, "[null, [[5, null], null], [null, -3e2]]")); ASSERT_OK(actual->ValidateFull()); is_valid = {false, true, false}; ArrayFromVector(is_valid, {0, 5, 0}, &children[0]); @@ -1174,12 +1179,12 @@ TEST(TestStruct, Errors) { std::shared_ptr type = struct_({field_a, field_b}); std::shared_ptr array; - ASSERT_RAISES(Invalid, ArrayFromJSON(type, "[0, true]")); - ASSERT_RAISES(Invalid, ArrayFromJSON(type, "[[0]]")); - ASSERT_RAISES(Invalid, ArrayFromJSON(type, "[[0, true, 1]]")); - ASSERT_RAISES(Invalid, ArrayFromJSON(type, "[[true, 0]]")); - ASSERT_RAISES(Invalid, ArrayFromJSON(type, "[{\"b\": 0, \"a\": true}]")); - ASSERT_RAISES(Invalid, ArrayFromJSON(type, "[{\"c\": 0}]")); + ASSERT_RAISES(Invalid, ArrayFromJSONString(type, "[0, true]")); + ASSERT_RAISES(Invalid, ArrayFromJSONString(type, "[[0]]")); + ASSERT_RAISES(Invalid, ArrayFromJSONString(type, "[[0, true, 1]]")); + ASSERT_RAISES(Invalid, ArrayFromJSONString(type, "[[true, 0]]")); + ASSERT_RAISES(Invalid, ArrayFromJSONString(type, "[{\"b\": 0, \"a\": true}]")); + ASSERT_RAISES(Invalid, ArrayFromJSONString(type, "[{\"c\": 0}]")); } TEST(TestDenseUnion, Basics) { @@ -1189,14 +1194,17 @@ TEST(TestDenseUnion, Basics) { auto type = dense_union({field_a, field_b}, {4, 8}); ASSERT_OK_AND_ASSIGN( auto array_parsed, - ArrayFromJSON(type, "[null, [4, 122], [8, true], [4, null], null, [8, false]]")); + ArrayFromJSONString(type, + "[null, [4, 122], [8, true], [4, null], null, [8, false]]")); auto array = checked_pointer_cast(array_parsed); - ASSERT_OK_AND_ASSIGN(auto expected_types, ArrayFromJSON(int8(), "[4, 4, 8, 4, 4, 8]")); + ASSERT_OK_AND_ASSIGN(auto expected_types, + ArrayFromJSONString(int8(), "[4, 4, 8, 4, 4, 8]")); ASSERT_OK_AND_ASSIGN(auto expected_offsets, - ArrayFromJSON(int32(), "[0, 1, 0, 2, 3, 1]")); - ASSERT_OK_AND_ASSIGN(auto expected_a, ArrayFromJSON(int8(), "[null, 122, null, null]")); - ASSERT_OK_AND_ASSIGN(auto expected_b, ArrayFromJSON(boolean(), "[true, false]")); + ArrayFromJSONString(int32(), "[0, 1, 0, 2, 3, 1]")); + ASSERT_OK_AND_ASSIGN(auto expected_a, + ArrayFromJSONString(int8(), "[null, 122, null, null]")); + ASSERT_OK_AND_ASSIGN(auto expected_b, ArrayFromJSONString(boolean(), "[true, false]")); ASSERT_OK_AND_ASSIGN( auto expected, DenseUnionArray::Make(*expected_types, *expected_offsets, @@ -1217,13 +1225,14 @@ TEST(TestSparseUnion, Basics) { auto type = sparse_union({field_a, field_b}, {4, 8}); ASSERT_OK_AND_ASSIGN( auto array, - ArrayFromJSON(type, "[[4, 122], [8, true], [4, null], null, [8, false]]")); + ArrayFromJSONString(type, "[[4, 122], [8, true], [4, null], null, [8, false]]")); - ASSERT_OK_AND_ASSIGN(auto expected_types, ArrayFromJSON(int8(), "[4, 8, 4, 4, 8]")); + ASSERT_OK_AND_ASSIGN(auto expected_types, + ArrayFromJSONString(int8(), "[4, 8, 4, 4, 8]")); ASSERT_OK_AND_ASSIGN(auto expected_a, - ArrayFromJSON(int8(), "[122, null, null, null, null]")); + ArrayFromJSONString(int8(), "[122, null, null, null, null]")); ASSERT_OK_AND_ASSIGN(auto expected_b, - ArrayFromJSON(boolean(), "[null, true, null, null, false]")); + ArrayFromJSONString(boolean(), "[null, true, null, null, false]")); ASSERT_OK_AND_ASSIGN(auto expected, SparseUnionArray::Make(*expected_types, {expected_a, expected_b}, @@ -1237,23 +1246,27 @@ TEST(TestDenseUnion, ListOfUnion) { auto field_b = field("b", boolean()); auto union_type = dense_union({field_a, field_b}, {4, 8}); auto list_type = list(union_type); - ASSERT_OK_AND_ASSIGN(auto parsed_array, ArrayFromJSON(list_type, - "[" - "[[4, 122], [8, true]]," - "[[4, null], null, [8, false]]" - "]")); + ASSERT_OK_AND_ASSIGN(auto parsed_array, + ArrayFromJSONString(list_type, + "[" + "[[4, 122], [8, true]]," + "[[4, null], null, [8, false]]" + "]")); auto array = checked_pointer_cast(parsed_array); - ASSERT_OK_AND_ASSIGN(auto expected_types, ArrayFromJSON(int8(), "[4, 8, 4, 4, 8]")); - ASSERT_OK_AND_ASSIGN(auto expected_offsets, ArrayFromJSON(int32(), "[0, 0, 1, 2, 1]")); - ASSERT_OK_AND_ASSIGN(auto expected_a, ArrayFromJSON(int8(), "[122, null, null]")); - ASSERT_OK_AND_ASSIGN(auto expected_b, ArrayFromJSON(boolean(), "[true, false]")); + ASSERT_OK_AND_ASSIGN(auto expected_types, + ArrayFromJSONString(int8(), "[4, 8, 4, 4, 8]")); + ASSERT_OK_AND_ASSIGN(auto expected_offsets, + ArrayFromJSONString(int32(), "[0, 0, 1, 2, 1]")); + ASSERT_OK_AND_ASSIGN(auto expected_a, ArrayFromJSONString(int8(), "[122, null, null]")); + ASSERT_OK_AND_ASSIGN(auto expected_b, ArrayFromJSONString(boolean(), "[true, false]")); ASSERT_OK_AND_ASSIGN( auto expected_values, DenseUnionArray::Make(*expected_types, *expected_offsets, {expected_a, expected_b}, {"a", "b"}, {4, 8})); - ASSERT_OK_AND_ASSIGN(auto expected_list_offsets, ArrayFromJSON(int32(), "[0, 2, 5]")); + ASSERT_OK_AND_ASSIGN(auto expected_list_offsets, + ArrayFromJSONString(int32(), "[0, 2, 5]")); ASSERT_OK_AND_ASSIGN(auto expected, ListArray::FromArrays(*expected_list_offsets, *expected_values)); @@ -1272,22 +1285,24 @@ TEST(TestSparseUnion, ListOfUnion) { auto field_b = field("b", boolean()); auto union_type = sparse_union({field_a, field_b}, {4, 8}); auto list_type = list(union_type); - ASSERT_OK_AND_ASSIGN(auto array, ArrayFromJSON(list_type, - "[" - "[[4, 122], [8, true]]," - "[[4, null], null, [8, false]]" - "]")); - - ASSERT_OK_AND_ASSIGN(auto expected_types, ArrayFromJSON(int8(), "[4, 8, 4, 4, 8]")); + ASSERT_OK_AND_ASSIGN(auto array, ArrayFromJSONString(list_type, + "[" + "[[4, 122], [8, true]]," + "[[4, null], null, [8, false]]" + "]")); + + ASSERT_OK_AND_ASSIGN(auto expected_types, + ArrayFromJSONString(int8(), "[4, 8, 4, 4, 8]")); ASSERT_OK_AND_ASSIGN(auto expected_a, - ArrayFromJSON(int8(), "[122, null, null, null, null]")); + ArrayFromJSONString(int8(), "[122, null, null, null, null]")); ASSERT_OK_AND_ASSIGN(auto expected_b, - ArrayFromJSON(boolean(), "[null, true, null, null, false]")); + ArrayFromJSONString(boolean(), "[null, true, null, null, false]")); ASSERT_OK_AND_ASSIGN(auto expected_values, SparseUnionArray::Make(*expected_types, {expected_a, expected_b}, {"a", "b"}, {4, 8})); - ASSERT_OK_AND_ASSIGN(auto expected_list_offsets, ArrayFromJSON(int32(), "[0, 2, 5]")); + ASSERT_OK_AND_ASSIGN(auto expected_list_offsets, + ArrayFromJSONString(int32(), "[0, 2, 5]")); ASSERT_OK_AND_ASSIGN(auto expected, ListArray::FromArrays(*expected_list_offsets, *expected_values)); @@ -1301,8 +1316,9 @@ TEST(TestDenseUnion, UnionOfStructs) { field("foxtrot", list(int8()))})), field("q", struct_({field("quebec", utf8())}))}; auto type = dense_union(fields, {0, 23, 47}); - ASSERT_OK_AND_ASSIGN(auto array_parsed, - ArrayFromJSON(type, R"([[0, {"alpha": 0.0, "bravo": "charlie"}], + ASSERT_OK_AND_ASSIGN( + auto array_parsed, + ArrayFromJSONString(type, R"([[0, {"alpha": 0.0, "bravo": "charlie"}], [23, {"whiskey": 99}], [0, {"bravo": "mike"}], null, @@ -1310,18 +1326,21 @@ TEST(TestDenseUnion, UnionOfStructs) { ])")); auto array = checked_pointer_cast(array_parsed); - ASSERT_OK_AND_ASSIGN(auto expected_types, ArrayFromJSON(int8(), "[0, 23, 0, 0, 23]")); - ASSERT_OK_AND_ASSIGN(auto expected_offsets, ArrayFromJSON(int32(), "[0, 0, 1, 2, 1]")); - ASSERT_OK_AND_ASSIGN(auto expected_fields_0, ArrayFromJSON(fields[0]->type(), R"([ + ASSERT_OK_AND_ASSIGN(auto expected_types, + ArrayFromJSONString(int8(), "[0, 23, 0, 0, 23]")); + ASSERT_OK_AND_ASSIGN(auto expected_offsets, + ArrayFromJSONString(int32(), "[0, 0, 1, 2, 1]")); + ASSERT_OK_AND_ASSIGN(auto expected_fields_0, ArrayFromJSONString(fields[0]->type(), R"([ {"alpha": 0.0, "bravo": "charlie"}, {"bravo": "mike"}, null ])")); - ASSERT_OK_AND_ASSIGN(auto expected_fields_1, ArrayFromJSON(fields[1]->type(), R"([ + ASSERT_OK_AND_ASSIGN(auto expected_fields_1, ArrayFromJSONString(fields[1]->type(), R"([ {"whiskey": 99}, {"tango": 8.25, "foxtrot": [0, 2, 3]} ])")); - ASSERT_OK_AND_ASSIGN(auto expected_fields_2, ArrayFromJSON(fields[2]->type(), "[]")); + ASSERT_OK_AND_ASSIGN(auto expected_fields_2, + ArrayFromJSONString(fields[2]->type(), "[]")); ArrayVector expected_fields = {expected_fields_0, expected_fields_1, expected_fields_2}; ASSERT_OK_AND_ASSIGN( @@ -1346,7 +1365,7 @@ TEST(TestSparseUnion, UnionOfStructs) { field("foxtrot", list(int8()))})), field("q", struct_({field("quebec", utf8())}))}; auto type = sparse_union(fields, {0, 23, 47}); - ASSERT_OK_AND_ASSIGN(auto array, ArrayFromJSON(type, R"([ + ASSERT_OK_AND_ASSIGN(auto array, ArrayFromJSONString(type, R"([ [0, {"alpha": 0.0, "bravo": "charlie"}], [23, {"whiskey": 99}], [0, {"bravo": "mike"}], @@ -1354,23 +1373,25 @@ TEST(TestSparseUnion, UnionOfStructs) { [23, {"tango": 8.25, "foxtrot": [0, 2, 3]}] ])")); - ASSERT_OK_AND_ASSIGN(auto expected_types, ArrayFromJSON(int8(), "[0, 23, 0, 0, 23]")); - ASSERT_OK_AND_ASSIGN(auto expected_fields_0, ArrayFromJSON(fields[0]->type(), R"([ + ASSERT_OK_AND_ASSIGN(auto expected_types, + ArrayFromJSONString(int8(), "[0, 23, 0, 0, 23]")); + ASSERT_OK_AND_ASSIGN(auto expected_fields_0, ArrayFromJSONString(fields[0]->type(), R"([ {"alpha": 0.0, "bravo": "charlie"}, null, {"bravo": "mike"}, null, null ])")); - ASSERT_OK_AND_ASSIGN(auto expected_fields_1, ArrayFromJSON(fields[1]->type(), R"([ + ASSERT_OK_AND_ASSIGN(auto expected_fields_1, ArrayFromJSONString(fields[1]->type(), R"([ null, {"whiskey": 99}, null, null, {"tango": 8.25, "foxtrot": [0, 2, 3]} ])")); - ASSERT_OK_AND_ASSIGN(auto expected_fields_2, - ArrayFromJSON(fields[2]->type(), "[null, null, null, null, null]")) + ASSERT_OK_AND_ASSIGN( + auto expected_fields_2, + ArrayFromJSONString(fields[2]->type(), "[null, null, null, null, null]")) ArrayVector expected_fields = {expected_fields_0, expected_fields_1, expected_fields_2}; ASSERT_OK_AND_ASSIGN(auto expected, @@ -1386,13 +1407,15 @@ TEST(TestDenseUnion, Errors) { std::shared_ptr type = dense_union({field_a, field_b}, {4, 8}); std::shared_ptr array; - ASSERT_RAISES(Invalid, ArrayFromJSON(type, "[\"not a valid type_id\"]")); - ASSERT_RAISES(Invalid, ArrayFromJSON(type, "[[0, 99]]")); // 0 is not one of {4, 8} - ASSERT_RAISES(Invalid, ArrayFromJSON(type, "[[4, \"\"]]")); // "" is not a valid int8() + ASSERT_RAISES(Invalid, ArrayFromJSONString(type, "[\"not a valid type_id\"]")); + ASSERT_RAISES(Invalid, + ArrayFromJSONString(type, "[[0, 99]]")); // 0 is not one of {4, 8} + ASSERT_RAISES(Invalid, + ArrayFromJSONString(type, "[[4, \"\"]]")); // "" is not a valid int8() - ASSERT_RAISES(Invalid, ArrayFromJSON(type, "[\"not a pair\"]")); - ASSERT_RAISES(Invalid, ArrayFromJSON(type, "[[0]]")); - ASSERT_RAISES(Invalid, ArrayFromJSON(type, "[[8, true, 1]]")); + ASSERT_RAISES(Invalid, ArrayFromJSONString(type, "[\"not a pair\"]")); + ASSERT_RAISES(Invalid, ArrayFromJSONString(type, "[[0]]")); + ASSERT_RAISES(Invalid, ArrayFromJSONString(type, "[[8, true, 1]]")); } TEST(TestSparseUnion, Errors) { @@ -1401,13 +1424,13 @@ TEST(TestSparseUnion, Errors) { std::shared_ptr type = sparse_union({field_a, field_b}, {4, 8}); std::shared_ptr array; - ASSERT_RAISES(Invalid, ArrayFromJSON(type, "[\"not a valid type_id\"]")); - ASSERT_RAISES(Invalid, ArrayFromJSON(type, "[[0, 99]]")); - ASSERT_RAISES(Invalid, ArrayFromJSON(type, "[[4, \"\"]]")); + ASSERT_RAISES(Invalid, ArrayFromJSONString(type, "[\"not a valid type_id\"]")); + ASSERT_RAISES(Invalid, ArrayFromJSONString(type, "[[0, 99]]")); + ASSERT_RAISES(Invalid, ArrayFromJSONString(type, "[[4, \"\"]]")); - ASSERT_RAISES(Invalid, ArrayFromJSON(type, "[\"not a pair\"]")); - ASSERT_RAISES(Invalid, ArrayFromJSON(type, "[[0]]")); - ASSERT_RAISES(Invalid, ArrayFromJSON(type, "[[8, true, 1]]")); + ASSERT_RAISES(Invalid, ArrayFromJSONString(type, "[\"not a pair\"]")); + ASSERT_RAISES(Invalid, ArrayFromJSONString(type, "[[0]]")); + ASSERT_RAISES(Invalid, ArrayFromJSONString(type, "[[8, true, 1]]")); } TEST(TestNestedDictionary, ListOfDict) { @@ -1419,14 +1442,14 @@ TEST(TestNestedDictionary, ListOfDict) { std::shared_ptr array, expected, indices, values, dicts, offsets; ASSERT_OK_AND_ASSIGN( - array, ArrayFromJSON(type, R"([["ab", "cd", null], null, ["cd", "cd"]])")); + array, ArrayFromJSONString(type, R"([["ab", "cd", null], null, ["cd", "cd"]])")); ASSERT_OK(array->ValidateFull()); // Build expected array - ASSERT_OK_AND_ASSIGN(indices, ArrayFromJSON(index_type, "[0, 1, null, 1, 1]")); - ASSERT_OK_AND_ASSIGN(values, ArrayFromJSON(value_type, R"(["ab", "cd"])")); + ASSERT_OK_AND_ASSIGN(indices, ArrayFromJSONString(index_type, "[0, 1, null, 1, 1]")); + ASSERT_OK_AND_ASSIGN(values, ArrayFromJSONString(value_type, R"(["ab", "cd"])")); ASSERT_OK_AND_ASSIGN(dicts, DictionaryArray::FromArrays(dict_type, indices, values)); - ASSERT_OK_AND_ASSIGN(offsets, ArrayFromJSON(int32(), "[0, null, 3, 5]")); + ASSERT_OK_AND_ASSIGN(offsets, ArrayFromJSONString(int32(), "[0, null, 3, 5]")); ASSERT_OK_AND_ASSIGN(expected, ListArray::FromArrays(*offsets, *dicts)); AssertArraysEqual(*expected, *array, /*verbose=*/true); @@ -1437,9 +1460,10 @@ TEST(TestDictArrayFromJSON, Basics) { auto array = DictArrayFromJSON(type, "[null, 2, 1, 0]", R"(["whiskey", "tango", "foxtrot"])"); - ASSERT_OK_AND_ASSIGN(auto expected_indices, ArrayFromJSON(int32(), "[null, 2, 1, 0]")); + ASSERT_OK_AND_ASSIGN(auto expected_indices, + ArrayFromJSONString(int32(), "[null, 2, 1, 0]")); ASSERT_OK_AND_ASSIGN(auto expected_dictionary, - ArrayFromJSON(utf8(), R"(["whiskey", "tango", "foxtrot"])")); + ArrayFromJSONString(utf8(), R"(["whiskey", "tango", "foxtrot"])")); ASSERT_ARRAYS_EQUAL(DictionaryArray(type, expected_indices, expected_dictionary), *array); @@ -1449,27 +1473,27 @@ TEST(TestDictArrayFromJSON, Errors) { auto type = dictionary(int32(), utf8()); std::shared_ptr array; - ASSERT_RAISES(Invalid, - DictArrayFromJSON(type, "[\"not a valid index\"]", "[\"\"]", &array)); - ASSERT_RAISES(Invalid, DictArrayFromJSON(type, "[0, 1]", "[1]", - &array)); // dict value isn't string + ASSERT_RAISES(Invalid, DictArrayFromJSONString(type, "[\"not a valid index\"]", + "[\"\"]", &array)); + ASSERT_RAISES(Invalid, DictArrayFromJSONString(type, "[0, 1]", "[1]", + &array)); // dict value isn't string } TEST(TestChunkedArrayFromJSON, Basics) { auto type = int32(); std::shared_ptr chunked_array; - ASSERT_OK(ChunkedArrayFromJSON(type, {}, &chunked_array)); + ASSERT_OK(ChunkedArrayFromJSONString(type, {}, &chunked_array)); ASSERT_OK(chunked_array->ValidateFull()); ASSERT_EQ(chunked_array->num_chunks(), 0); AssertTypeEqual(type, chunked_array->type()); - ASSERT_OK(ChunkedArrayFromJSON(type, {"[1, 2]", "[3, null, 4]"}, &chunked_array)); + ASSERT_OK(ChunkedArrayFromJSONString(type, {"[1, 2]", "[3, null, 4]"}, &chunked_array)); ASSERT_OK(chunked_array->ValidateFull()); ASSERT_EQ(chunked_array->num_chunks(), 2); std::shared_ptr expected_chunk; - ASSERT_OK_AND_ASSIGN(expected_chunk, ArrayFromJSON(type, "[1, 2]")); + ASSERT_OK_AND_ASSIGN(expected_chunk, ArrayFromJSONString(type, "[1, 2]")); AssertArraysEqual(*expected_chunk, *chunked_array->chunk(0), /*verbose=*/true); - ASSERT_OK_AND_ASSIGN(expected_chunk, ArrayFromJSON(type, "[3, null, 4]")); + ASSERT_OK_AND_ASSIGN(expected_chunk, ArrayFromJSONString(type, "[3, null, 4]")); AssertArraysEqual(*expected_chunk, *chunked_array->chunk(1), /*verbose=*/true); } @@ -1492,29 +1516,31 @@ TEST(TestScalarFromJSON, Basics) { AssertJSONScalar(boolean(), "1", true, true); AssertJSONScalar(float64(), "1.0", true, 1.0); AssertJSONScalar(float64(), "-0.0", true, -0.0); - ASSERT_OK(ScalarFromJSON(float64(), "NaN", &scalar)); + ASSERT_OK(ScalarFromJSONString(float64(), "NaN", &scalar)); ASSERT_TRUE(std::isnan(checked_cast(*scalar).value)); - ASSERT_OK(ScalarFromJSON(float64(), "Inf", &scalar)); + ASSERT_OK(ScalarFromJSONString(float64(), "Inf", &scalar)); ASSERT_TRUE(std::isinf(checked_cast(*scalar).value)); } TEST(TestScalarFromJSON, Errors) { std::shared_ptr scalar; - ASSERT_RAISES(Invalid, ScalarFromJSON(int64(), "[0]", &scalar)); - ASSERT_RAISES(Invalid, ScalarFromJSON(int64(), "[9223372036854775808]", &scalar)); - ASSERT_RAISES(Invalid, ScalarFromJSON(int64(), "[-9223372036854775809]", &scalar)); - ASSERT_RAISES(Invalid, ScalarFromJSON(uint64(), "[18446744073709551616]", &scalar)); - ASSERT_RAISES(Invalid, ScalarFromJSON(uint64(), "[-1]", &scalar)); - ASSERT_RAISES(Invalid, ScalarFromJSON(binary(), "0", &scalar)); - ASSERT_RAISES(Invalid, ScalarFromJSON(binary(), "[]", &scalar)); - ASSERT_RAISES(Invalid, ScalarFromJSON(boolean(), "0.0", &scalar)); - ASSERT_RAISES(Invalid, ScalarFromJSON(boolean(), "\"true\"", &scalar)); -} - -TEST(TestDictScalarFromJSON, Basics) { + ASSERT_RAISES(Invalid, ScalarFromJSONString(int64(), "[0]", &scalar)); + ASSERT_RAISES(Invalid, ScalarFromJSONString(int64(), "[9223372036854775808]", &scalar)); + ASSERT_RAISES(Invalid, + ScalarFromJSONString(int64(), "[-9223372036854775809]", &scalar)); + ASSERT_RAISES(Invalid, + ScalarFromJSONString(uint64(), "[18446744073709551616]", &scalar)); + ASSERT_RAISES(Invalid, ScalarFromJSONString(uint64(), "[-1]", &scalar)); + ASSERT_RAISES(Invalid, ScalarFromJSONString(binary(), "0", &scalar)); + ASSERT_RAISES(Invalid, ScalarFromJSONString(binary(), "[]", &scalar)); + ASSERT_RAISES(Invalid, ScalarFromJSONString(boolean(), "0.0", &scalar)); + ASSERT_RAISES(Invalid, ScalarFromJSONString(boolean(), "\"true\"", &scalar)); +} + +TEST(TestDictScalarFromJSONString, Basics) { auto type = dictionary(int32(), utf8()); auto dict = R"(["whiskey", "tango", "foxtrot"])"; - ASSERT_OK_AND_ASSIGN(auto expected_dictionary, ArrayFromJSON(utf8(), dict)); + ASSERT_OK_AND_ASSIGN(auto expected_dictionary, ArrayFromJSONString(utf8(), dict)); for (auto index : {"null", "2", "1", "0"}) { auto scalar = DictScalarFromJSON(type, index, dict); @@ -1525,17 +1551,15 @@ TEST(TestDictScalarFromJSON, Basics) { } } -TEST(TestDictScalarFromJSON, Errors) { +TEST(TestDictScalarFromJSONString, Errors) { auto type = dictionary(int32(), utf8()); std::shared_ptr scalar; - ASSERT_RAISES(Invalid, - DictScalarFromJSON(type, "\"not a valid index\"", "[\"\"]", &scalar)); - ASSERT_RAISES(Invalid, DictScalarFromJSON(type, "0", "[1]", - &scalar)); // dict value isn't string + ASSERT_RAISES(Invalid, DictScalarFromJSONString(type, "\"not a valid index\"", "[\"\"]", + &scalar)); + ASSERT_RAISES(Invalid, DictScalarFromJSONString(type, "0", "[1]", + &scalar)); // dict value isn't string } } // namespace json -} // namespace internal -} // namespace ipc } // namespace arrow diff --git a/cpp/src/arrow/meson.build b/cpp/src/arrow/meson.build index e9c338eac66..ac5099d3906 100644 --- a/cpp/src/arrow/meson.build +++ b/cpp/src/arrow/meson.build @@ -343,11 +343,6 @@ if needs_ipc flatbuffers_dep = dependency('flatbuffers') arrow_ipc_deps = [flatbuffers_dep] - if needs_json - arrow_ipc_srcs += 'ipc/json_simple.cc' - arrow_ipc_deps += rapidjson_dep - endif - arrow_components += { 'arrow_ipc': {'sources': arrow_ipc_srcs, 'dependencies': arrow_ipc_deps}, } @@ -363,6 +358,7 @@ if needs_json 'json/chunked_builder.cc', 'json/chunker.cc', 'json/converter.cc', + 'json/from_string.cc', 'json/object_parser.cc', 'json/object_writer.cc', 'json/parser.cc', diff --git a/cpp/src/arrow/testing/gtest_util.cc b/cpp/src/arrow/testing/gtest_util.cc index 9eeca32e721..9ba59385960 100644 --- a/cpp/src/arrow/testing/gtest_util.cc +++ b/cpp/src/arrow/testing/gtest_util.cc @@ -51,9 +51,9 @@ #include "arrow/datum.h" #include "arrow/extension/json.h" #include "arrow/io/memory.h" -#include "arrow/ipc/json_simple.h" #include "arrow/ipc/reader.h" #include "arrow/ipc/writer.h" +#include "arrow/json/from_string.h" #include "arrow/json/rapidjson_defs.h" // IWYU pragma: keep #include "arrow/pretty_print.h" #include "arrow/record_batch.h" @@ -381,7 +381,7 @@ void AssertDatumsApproxEqual(const Datum& expected, const Datum& actual, bool ve std::shared_ptr ArrayFromJSON(const std::shared_ptr& type, std::string_view json) { - EXPECT_OK_AND_ASSIGN(auto out, ipc::internal::json::ArrayFromJSON(type, json)); + EXPECT_OK_AND_ASSIGN(auto out, json::ArrayFromJSONString(type, json)); return out; } @@ -389,15 +389,14 @@ std::shared_ptr DictArrayFromJSON(const std::shared_ptr& type, std::string_view indices_json, std::string_view dictionary_json) { std::shared_ptr out; - ABORT_NOT_OK( - ipc::internal::json::DictArrayFromJSON(type, indices_json, dictionary_json, &out)); + ABORT_NOT_OK(json::DictArrayFromJSONString(type, indices_json, dictionary_json, &out)); return out; } std::shared_ptr ChunkedArrayFromJSON(const std::shared_ptr& type, const std::vector& json) { std::shared_ptr out; - ABORT_NOT_OK(ipc::internal::json::ChunkedArrayFromJSON(type, json, &out)); + ABORT_NOT_OK(json::ChunkedArrayFromJSONString(type, json, &out)); return out; } @@ -405,7 +404,7 @@ std::shared_ptr RecordBatchFromJSON(const std::shared_ptr& std::string_view json) { // Parse as a StructArray auto struct_type = struct_(schema->fields()); - std::shared_ptr struct_array = ArrayFromJSON(struct_type, json); + std::shared_ptr struct_array = arrow::ArrayFromJSON(struct_type, json); // Convert StructArray to RecordBatch return *RecordBatch::FromStructArray(struct_array); @@ -414,7 +413,7 @@ std::shared_ptr RecordBatchFromJSON(const std::shared_ptr& std::shared_ptr ScalarFromJSON(const std::shared_ptr& type, std::string_view json) { std::shared_ptr out; - ABORT_NOT_OK(ipc::internal::json::ScalarFromJSON(type, json, &out)); + ABORT_NOT_OK(json::ScalarFromJSONString(type, json, &out)); return out; } @@ -422,8 +421,7 @@ std::shared_ptr DictScalarFromJSON(const std::shared_ptr& type std::string_view index_json, std::string_view dictionary_json) { std::shared_ptr out; - ABORT_NOT_OK( - ipc::internal::json::DictScalarFromJSON(type, index_json, dictionary_json, &out)); + ABORT_NOT_OK(json::DictScalarFromJSONString(type, index_json, dictionary_json, &out)); return out; } @@ -440,7 +438,7 @@ std::shared_ptr TensorFromJSON(const std::shared_ptr& type, std::string_view data, std::string_view shape, std::string_view strides, std::string_view dim_names) { - std::shared_ptr array = ArrayFromJSON(type, data); + std::shared_ptr array = arrow::ArrayFromJSON(type, data); rj::Document json_shape; json_shape.Parse(shape.data(), shape.length()); @@ -469,7 +467,7 @@ std::shared_ptr TensorFromJSON(const std::shared_ptr& type, const std::vector& shape, const std::vector& strides, const std::vector& dim_names) { - std::shared_ptr array = ArrayFromJSON(type, data); + std::shared_ptr array = arrow::ArrayFromJSON(type, data); return *Tensor::Make(type, array->data()->buffers[1], shape, strides, dim_names); } @@ -1020,19 +1018,19 @@ std::shared_ptr MakeComplex128(const std::shared_ptr& real, } std::shared_ptr ExampleUuid() { - auto arr = ArrayFromJSON( + auto arr = arrow::ArrayFromJSON( fixed_size_binary(16), "[null, \"abcdefghijklmno0\", \"abcdefghijklmno1\", \"abcdefghijklmno2\"]"); return ExtensionType::WrapArray(uuid(), arr); } std::shared_ptr ExampleSmallint() { - auto arr = ArrayFromJSON(int16(), "[-32768, null, 1, 2, 3, 4, 32767]"); + auto arr = arrow::ArrayFromJSON(int16(), "[-32768, null, 1, 2, 3, 4, 32767]"); return ExtensionType::WrapArray(smallint(), arr); } std::shared_ptr ExampleTinyint() { - auto arr = ArrayFromJSON(int8(), "[-128, null, 1, 2, 3, 4, 127]"); + auto arr = arrow::ArrayFromJSON(int8(), "[-128, null, 1, 2, 3, 4, 127]"); return ExtensionType::WrapArray(tinyint(), arr); } @@ -1043,8 +1041,8 @@ std::shared_ptr ExampleDictExtension() { } std::shared_ptr ExampleComplex128() { - auto arr = ArrayFromJSON(struct_({field("", float64()), field("", float64())}), - "[[1.0, -2.5], null, [3.0, -4.5]]"); + auto arr = arrow::ArrayFromJSON(struct_({field("", float64()), field("", float64())}), + "[[1.0, -2.5], null, [3.0, -4.5]]"); return ExtensionType::WrapArray(complex128(), arr); } diff --git a/cpp/src/arrow/testing/matchers.h b/cpp/src/arrow/testing/matchers.h index b4625b3922e..b800cb30c3c 100644 --- a/cpp/src/arrow/testing/matchers.h +++ b/cpp/src/arrow/testing/matchers.h @@ -75,7 +75,7 @@ class AnyOfJSONMatcher { "AnyOfJSON only supported for std::shared_ptr"); Impl(std::shared_ptr type, std::string array_json) : type_(std::move(type)), array_json_(std::move(array_json)) { - array = ArrayFromJSON(type_, array_json_); + array = arrow::ArrayFromJSON(type_, array_json_); } void DescribeTo(std::ostream* os) const override { *os << "matches at least one scalar from "; @@ -415,7 +415,7 @@ DataEqMatcher DataEq(Data&& dat) { /// Constructs an array with ArrayFromJSON against which arguments are matched inline DataEqMatcher DataEqArray(const std::shared_ptr& type, std::string_view json) { - return DataEq(ArrayFromJSON(type, json)); + return DataEq(arrow::ArrayFromJSON(type, json)); } /// Constructs an array from a vector of optionals against which arguments are matched diff --git a/docs/source/cpp/api/array.rst b/docs/source/cpp/api/array.rst index b17d1957a8b..43601fc2fff 100644 --- a/docs/source/cpp/api/array.rst +++ b/docs/source/cpp/api/array.rst @@ -110,3 +110,11 @@ Utilities :project: arrow_cpp :members: :undoc-members: + +.. _api-array-from-json-string: + +FromJSONString Helpers +---------------------- + +.. doxygengroup:: array-from-json-string + :members: diff --git a/docs/source/cpp/arrays.rst b/docs/source/cpp/arrays.rst index 37550229388..996472ec131 100644 --- a/docs/source/cpp/arrays.rst +++ b/docs/source/cpp/arrays.rst @@ -57,6 +57,10 @@ example a ``std::vector``. Instead, several strategies can be used: subclasses help building up array data incrementally, without having to deal with details of the Arrow format yourself. +.. note:: For cases where performance isn't important such as examples or tests, + you may prefer to use the ``*FromJSONString`` helpers which can create + Arrays using a JSON text shorthand. See :ref:`fromjson_helpers`. + Using ArrayBuilder and its subclasses ------------------------------------- @@ -223,3 +227,26 @@ to some logical subsequence of the data. This is done by calling the :func:`arrow::Array::Slice` and :func:`arrow::ChunkedArray::Slice` methods, respectively. +FromJSONString Helpers +====================== + +A set of helper functions is provided for concisely creating Arrays and Scalars +from JSON_ text. These helpers are intended to be used in examples, tests, or +for quick prototyping and are not intended to be used where performance matters. +Most users will want to use the API described in :doc:`json` which provides a +performant way to create :class:`arrow::Table` and :class:`arrow::RecordBatch` +objects from line-separated JSON files. + +.. _JSON: https://datatracker.ietf.org/doc/html/rfc8259 + +Examples for ``ArrayFromJSONString``, ``ChunkedArrayFromJSONString``, +``DictArrayFromJSONString`` are shown below: + +.. literalinclude:: ../../../cpp/examples/arrow/from_json_string_example.cc + :language: cpp + :start-after: arrow::Status RunExample() { + :end-before: return arrow::Status::OK(); + :dedent: 2 + +Please see the :ref:`FromJSONString API listing ` for +the complete set of helpers. diff --git a/python/pyarrow/src/arrow/python/gdb.cc b/python/pyarrow/src/arrow/python/gdb.cc index 7c58bae3342..38383b86f49 100644 --- a/python/pyarrow/src/arrow/python/gdb.cc +++ b/python/pyarrow/src/arrow/python/gdb.cc @@ -23,7 +23,7 @@ #include "arrow/chunked_array.h" #include "arrow/datum.h" #include "arrow/extension/uuid.h" -#include "arrow/ipc/json_simple.h" +#include "arrow/json/from_string.h" #include "arrow/python/gdb.h" #include "arrow/record_batch.h" #include "arrow/scalar.h" @@ -39,9 +39,9 @@ namespace arrow { using extension::uuid; using extension::UuidType; -using ipc::internal::json::ArrayFromJSON; -using ipc::internal::json::ChunkedArrayFromJSON; -using ipc::internal::json::ScalarFromJSON; +using json::ArrayFromJSONString; +using json::ChunkedArrayFromJSONString; +using json::ScalarFromJSONString; namespace gdb { @@ -61,7 +61,7 @@ class CustomStatusDetail : public StatusDetail { std::shared_ptr SliceArrayFromJSON(const std::shared_ptr& ty, std::string_view json, int64_t offset = 0, int64_t length = -1) { - auto array = *ArrayFromJSON(ty, json); + auto array = *ArrayFromJSONString(ty, json); if (length != -1) { return array->Slice(offset, length); } else { @@ -320,13 +320,13 @@ void TestSession() { Buffer::FromString(" "), fixed_size_binary(3), /*is_valid=*/false}; std::shared_ptr dict_array; - dict_array = *ArrayFromJSON(utf8(), R"(["foo", "bar", "quux"])"); + dict_array = *ArrayFromJSONString(utf8(), R"(["foo", "bar", "quux"])"); DictionaryScalar dict_scalar{{std::make_shared(42), dict_array}, dictionary(int8(), utf8())}; DictionaryScalar dict_scalar_null{dictionary(int8(), utf8())}; - std::shared_ptr list_value_array = *ArrayFromJSON(int32(), R"([4, 5, 6])"); - std::shared_ptr list_zero_length = *ArrayFromJSON(int32(), R"([])"); + std::shared_ptr list_value_array = *ArrayFromJSONString(int32(), R"([4, 5, 6])"); + std::shared_ptr list_zero_length = *ArrayFromJSONString(int32(), R"([])"); ListScalar list_scalar{list_value_array}; ListScalar list_scalar_null{list_zero_length, list(int32()), /*is_valid=*/false}; LargeListScalar large_list_scalar{list_value_array}; @@ -364,8 +364,8 @@ void TestSession() { /*is_valid=*/false}; std::shared_ptr heap_map_scalar; - ARROW_CHECK_OK( - ScalarFromJSON(map(utf8(), int32()), R"([["a", 5], ["b", 6]])", &heap_map_scalar)); + ARROW_CHECK_OK(ScalarFromJSONString(map(utf8(), int32()), R"([["a", 5], ["b", 6]])", + &heap_map_scalar)); auto heap_map_scalar_null = MakeNullScalar(heap_map_scalar->type); // Array and ArrayData @@ -465,15 +465,15 @@ void TestSession() { // ChunkedArray ArrayVector array_chunks(2); - array_chunks[0] = *ArrayFromJSON(int32(), "[1, 2]"); - array_chunks[1] = *ArrayFromJSON(int32(), "[3, null, 4]"); + array_chunks[0] = *ArrayFromJSONString(int32(), "[1, 2]"); + array_chunks[1] = *ArrayFromJSONString(int32(), "[3, null, 4]"); ChunkedArray chunked_array{array_chunks}; // RecordBatch auto batch_schema = schema({field("ints", int32()), field("strs", utf8())}); ArrayVector batch_columns{2}; - batch_columns[0] = *ArrayFromJSON(int32(), "[1, 2, 3]"); - batch_columns[1] = *ArrayFromJSON(utf8(), R"(["abc", null, "def"])"); + batch_columns[0] = *ArrayFromJSONString(int32(), "[1, 2, 3]"); + batch_columns[1] = *ArrayFromJSONString(utf8(), R"(["abc", null, "def"])"); auto batch = RecordBatch::Make(batch_schema, /*num_rows=*/3, batch_columns); auto batch_with_metadata = batch->ReplaceSchemaMetadata( key_value_metadata({"key1", "key2", "key3"}, {"value1", "value2", "value3"})); @@ -481,8 +481,8 @@ void TestSession() { // Table ChunkedArrayVector table_columns{2}; ARROW_CHECK_OK( - ChunkedArrayFromJSON(int32(), {"[1, 2, 3]", "[4, 5]"}, &table_columns[0])); - ARROW_CHECK_OK(ChunkedArrayFromJSON( + ChunkedArrayFromJSONString(int32(), {"[1, 2, 3]", "[4, 5]"}, &table_columns[0])); + ARROW_CHECK_OK(ChunkedArrayFromJSONString( utf8(), {R"(["abc", null])", R"(["def"])", R"(["ghi", "jkl"])"}, &table_columns[1])); auto table = Table::Make(batch_schema, table_columns); diff --git a/python/pyarrow/tests/extensions.pyx b/python/pyarrow/tests/extensions.pyx index 309b574dc02..b958abae4db 100644 --- a/python/pyarrow/tests/extensions.pyx +++ b/python/pyarrow/tests/extensions.pyx @@ -24,7 +24,7 @@ cdef extern from * namespace "arrow::py" nogil: """ #include "arrow/status.h" #include "arrow/extension_type.h" - #include "arrow/ipc/json_simple.h" + #include "arrow/json/from_string.h" namespace arrow { namespace py { @@ -64,7 +64,7 @@ cdef extern from * namespace "arrow::py" nogil: std::shared_ptr MakeUuidArray() { auto uuid_type = MakeUuidType(); auto json = "[\\"abcdefghijklmno0\\", \\"0onmlkjihgfedcba\\"]"; - auto result = ipc::internal::json::ArrayFromJSON(fixed_size_binary(16), json); + auto result = json::ArrayFromJSONString(fixed_size_binary(16), json); return ExtensionType::WrapArray(uuid_type, result.ValueOrDie()); }