diff --git a/cpp/examples/arrow/from_json_string_example.cc b/cpp/examples/arrow/from_json_string_example.cc index da13d913489..eb919303fee 100644 --- a/cpp/examples/arrow/from_json_string_example.cc +++ b/cpp/examples/arrow/from_json_string_example.cc @@ -68,15 +68,15 @@ arrow::Status RunExample() { "[[11, 22], null, [null, 33]]")); // ChunkedArrayFromJSONString - std::shared_ptr chunked_array; - ARROW_RETURN_NOT_OK(ChunkedArrayFromJSONString( - arrow::int32(), {"[5, 10]", "[null]", "[16]"}, &chunked_array)); + ARROW_ASSIGN_OR_RAISE( + auto chunked_array, + ChunkedArrayFromJSONString(arrow::int32(), {"[5, 10]", "[null]", "[16]"})); // 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)); + ARROW_ASSIGN_OR_RAISE( + auto dict_array, + DictArrayFromJSONString(dictionary(arrow::int32(), arrow::utf8()), + "[0, 1, 0, 2, 0, 3]", R"(["k1", "k2", "k3", "k4"])")); return arrow::Status::OK(); } diff --git a/cpp/src/arrow/json/from_string.cc b/cpp/src/arrow/json/from_string.cc index b2972f7150e..e35a362f5a2 100644 --- a/cpp/src/arrow/json/from_string.cc +++ b/cpp/src/arrow/json/from_string.cc @@ -1004,23 +1004,20 @@ Result> ArrayFromJSONString(const std::shared_ptr& type, - const std::vector& json_strings, - std::shared_ptr* out) { +Result> ChunkedArrayFromJSONString( + const std::shared_ptr& type, const std::vector& json_strings) { 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(), ArrayFromJSONString(type, chunk_json)); } - *out = std::make_shared(std::move(out_chunks), type); - return Status::OK(); + return std::make_shared(std::move(out_chunks), type); } -Status DictArrayFromJSONString(const std::shared_ptr& type, - std::string_view indices_json, - std::string_view dictionary_json, - std::shared_ptr* out) { +Result> DictArrayFromJSONString( + const std::shared_ptr& type, std::string_view indices_json, + std::string_view dictionary_json) { if (type->id() != Type::DICTIONARY) { return Status::TypeError("DictArrayFromJSON requires dictionary type, got ", *type); } @@ -1031,13 +1028,11 @@ Status DictArrayFromJSONString(const std::shared_ptr& type, 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); + return DictionaryArray::FromArrays(type, std::move(indices), std::move(dictionary)); } -Status ScalarFromJSONString(const std::shared_ptr& type, - std::string_view json_string, std::shared_ptr* out) { +Result> ScalarFromJSONString( + const std::shared_ptr& type, std::string_view json_string) { std::shared_ptr converter; RETURN_NOT_OK(GetConverter(type, &converter)); @@ -1052,13 +1047,12 @@ Status ScalarFromJSONString(const std::shared_ptr& type, RETURN_NOT_OK(converter->AppendValue(json_doc)); RETURN_NOT_OK(converter->Finish(&array)); DCHECK_EQ(array->length(), 1); - return array->GetScalar(0).Value(out); + return array->GetScalar(0); } -Status DictScalarFromJSONString(const std::shared_ptr& type, - std::string_view index_json, - std::string_view dictionary_json, - std::shared_ptr* out) { +Result> DictScalarFromJSONString( + const std::shared_ptr& type, std::string_view index_json, + std::string_view dictionary_json) { if (type->id() != Type::DICTIONARY) { return Status::TypeError("DictScalarFromJSONString requires dictionary type, got ", *type); @@ -1066,14 +1060,13 @@ Status DictScalarFromJSONString(const std::shared_ptr& type, const auto& dictionary_type = checked_cast(*type); - std::shared_ptr index; std::shared_ptr dictionary; - RETURN_NOT_OK(ScalarFromJSONString(dictionary_type.index_type(), index_json, &index)); + ARROW_ASSIGN_OR_RAISE(auto index, + ScalarFromJSONString(dictionary_type.index_type(), index_json)); ARROW_ASSIGN_OR_RAISE( dictionary, ArrayFromJSONString(dictionary_type.value_type(), dictionary_json)); - *out = DictionaryScalar::Make(std::move(index), std::move(dictionary)); - return Status::OK(); + return DictionaryScalar::Make(std::move(index), std::move(dictionary)); } } // namespace json diff --git a/cpp/src/arrow/json/from_string.h b/cpp/src/arrow/json/from_string.h index 03c6b1bcdf4..bd5ed3d46a3 100644 --- a/cpp/src/arrow/json/from_string.h +++ b/cpp/src/arrow/json/from_string.h @@ -47,9 +47,8 @@ namespace json { /// \brief Create an Array from a JSON string /// /// \code {.cpp} -/// std::shared_ptr array = ArrayFromJSONString( -/// int64(), "[2, 3, null, 7, 11]" -/// ).ValueOrDie(); +/// Result> maybe_array = +/// ArrayFromJSONString(int64(), "[2, 3, null, 7, 11]"); /// \endcode ARROW_EXPORT Result> ArrayFromJSONString(const std::shared_ptr&, @@ -68,52 +67,44 @@ Result> ArrayFromJSONString(const std::shared_ptr chunked_array; -/// ChunkedArrayFromJSONString( -/// int64(), {R"([5, 10])", R"([null])", R"([16])"}, &chunked_array -/// ); +/// Result> maybe_chunked_array = +/// ChunkedArrayFromJSONString(int64(), {R"([5, 10])", R"([null])", R"([16])"}); /// \endcode ARROW_EXPORT -Status ChunkedArrayFromJSONString(const std::shared_ptr& type, - const std::vector& json_strings, - std::shared_ptr* out); +Result> ChunkedArrayFromJSONString( + const std::shared_ptr& type, const std::vector& json_strings); /// \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 -/// ); +/// Result> maybe_dict_array = +/// DictArrayFromJSONString(dictionary(int32(), utf8()), "[0, 1, 0, 2, 0, 3]", +/// R"(["k1", "k2", "k3", "k4"])"); /// \endcode ARROW_EXPORT -Status DictArrayFromJSONString(const std::shared_ptr&, - std::string_view indices_json, - std::string_view dictionary_json, - std::shared_ptr* out); +Result> DictArrayFromJSONString(const std::shared_ptr&, + std::string_view indices_json, + std::string_view dictionary_json); /// \brief Create a Scalar from a JSON string /// \code {.cpp} -/// std::shared_ptr scalar; -/// ScalarFromJSONString(float64(), "42", &scalar); +/// Result> maybe_scalar = +/// ScalarFromJSONString(float64(), "42", &scalar); /// \endcode ARROW_EXPORT -Status ScalarFromJSONString(const std::shared_ptr&, std::string_view json, - std::shared_ptr* out); +Result> ScalarFromJSONString(const std::shared_ptr&, + std::string_view json); /// \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); +/// Result> maybe_dict_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); +Result> DictScalarFromJSONString( + const std::shared_ptr&, std::string_view index_json, + std::string_view dictionary_json); /// @} diff --git a/cpp/src/arrow/json/from_string_test.cc b/cpp/src/arrow/json/from_string_test.cc index d9fa53f68cb..b70501b5f34 100644 --- a/cpp/src/arrow/json/from_string_test.cc +++ b/cpp/src/arrow/json/from_string_test.cc @@ -149,9 +149,9 @@ template void AssertJSONScalar(const std::shared_ptr& type, const std::string& json, const bool is_valid, const C_TYPE value) { SCOPED_TRACE(json); - std::shared_ptr actual, expected; + std::shared_ptr expected; - ASSERT_OK(ScalarFromJSONString(type, json, &actual)); + ASSERT_OK_AND_ASSIGN(auto actual, ScalarFromJSONString(type, json)); if (is_valid) { ASSERT_OK_AND_ASSIGN(expected, MakeScalar(type, value)); } else { @@ -1471,35 +1471,33 @@ TEST(TestDictArrayFromJSON, Basics) { TEST(TestDictArrayFromJSON, Errors) { auto type = dictionary(int32(), utf8()); - std::shared_ptr array; - ASSERT_RAISES(Invalid, DictArrayFromJSONString(type, "[\"not a valid index\"]", - "[\"\"]", &array)); - ASSERT_RAISES(Invalid, DictArrayFromJSONString(type, "[0, 1]", "[1]", - &array)); // dict value isn't string + ASSERT_RAISES(Invalid, + DictArrayFromJSONString(type, "[\"not a valid index\"]", "[\"\"]")); + ASSERT_RAISES(Invalid, DictArrayFromJSONString(type, "[0, 1]", + "[1]")); // dict value isn't string } TEST(TestChunkedArrayFromJSON, Basics) { auto type = int32(); - std::shared_ptr chunked_array; - ASSERT_OK(ChunkedArrayFromJSONString(type, {}, &chunked_array)); + ASSERT_OK_AND_ASSIGN(auto chunked_array, ChunkedArrayFromJSONString(type, {})); ASSERT_OK(chunked_array->ValidateFull()); ASSERT_EQ(chunked_array->num_chunks(), 0); AssertTypeEqual(type, chunked_array->type()); - ASSERT_OK(ChunkedArrayFromJSONString(type, {"[1, 2]", "[3, null, 4]"}, &chunked_array)); - ASSERT_OK(chunked_array->ValidateFull()); - ASSERT_EQ(chunked_array->num_chunks(), 2); + ASSERT_OK_AND_ASSIGN(auto chunked_array_two, + ChunkedArrayFromJSONString(type, {"[1, 2]", "[3, null, 4]"})); + ASSERT_OK(chunked_array_two->ValidateFull()); + ASSERT_EQ(chunked_array_two->num_chunks(), 2); std::shared_ptr expected_chunk; ASSERT_OK_AND_ASSIGN(expected_chunk, ArrayFromJSONString(type, "[1, 2]")); - AssertArraysEqual(*expected_chunk, *chunked_array->chunk(0), /*verbose=*/true); + AssertArraysEqual(*expected_chunk, *chunked_array_two->chunk(0), /*verbose=*/true); ASSERT_OK_AND_ASSIGN(expected_chunk, ArrayFromJSONString(type, "[3, null, 4]")); - AssertArraysEqual(*expected_chunk, *chunked_array->chunk(1), /*verbose=*/true); + AssertArraysEqual(*expected_chunk, *chunked_array_two->chunk(1), /*verbose=*/true); } TEST(TestScalarFromJSON, Basics) { // Sanity check for common types (not exhaustive) - std::shared_ptr scalar; AssertJSONScalar(int64(), "4", true, 4); AssertJSONScalar(int64(), "null", false, 0); AssertJSONScalar>(utf8(), R"("")", true, @@ -1516,25 +1514,22 @@ TEST(TestScalarFromJSON, Basics) { AssertJSONScalar(boolean(), "1", true, true); AssertJSONScalar(float64(), "1.0", true, 1.0); AssertJSONScalar(float64(), "-0.0", true, -0.0); - ASSERT_OK(ScalarFromJSONString(float64(), "NaN", &scalar)); - ASSERT_TRUE(std::isnan(checked_cast(*scalar).value)); - ASSERT_OK(ScalarFromJSONString(float64(), "Inf", &scalar)); - ASSERT_TRUE(std::isinf(checked_cast(*scalar).value)); + ASSERT_OK_AND_ASSIGN(auto nan_scalar, ScalarFromJSONString(float64(), "NaN")); + ASSERT_TRUE(std::isnan(checked_cast(*nan_scalar).value)); + ASSERT_OK_AND_ASSIGN(auto inf_scalar, ScalarFromJSONString(float64(), "Inf")); + ASSERT_TRUE(std::isinf(checked_cast(*inf_scalar).value)); } TEST(TestScalarFromJSON, Errors) { - std::shared_ptr scalar; - 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)); + ASSERT_RAISES(Invalid, ScalarFromJSONString(int64(), "[0]")); + ASSERT_RAISES(Invalid, ScalarFromJSONString(int64(), "[9223372036854775808]")); + ASSERT_RAISES(Invalid, ScalarFromJSONString(int64(), "[-9223372036854775809]")); + ASSERT_RAISES(Invalid, ScalarFromJSONString(uint64(), "[18446744073709551616]")); + ASSERT_RAISES(Invalid, ScalarFromJSONString(uint64(), "[-1]")); + ASSERT_RAISES(Invalid, ScalarFromJSONString(binary(), "0")); + ASSERT_RAISES(Invalid, ScalarFromJSONString(binary(), "[]")); + ASSERT_RAISES(Invalid, ScalarFromJSONString(boolean(), "0.0")); + ASSERT_RAISES(Invalid, ScalarFromJSONString(boolean(), "\"true\"")); } TEST(TestDictScalarFromJSONString, Basics) { @@ -1553,12 +1548,11 @@ TEST(TestDictScalarFromJSONString, Basics) { TEST(TestDictScalarFromJSONString, Errors) { auto type = dictionary(int32(), utf8()); - std::shared_ptr scalar; - ASSERT_RAISES(Invalid, DictScalarFromJSONString(type, "\"not a valid index\"", "[\"\"]", - &scalar)); - ASSERT_RAISES(Invalid, DictScalarFromJSONString(type, "0", "[1]", - &scalar)); // dict value isn't string + ASSERT_RAISES(Invalid, + DictScalarFromJSONString(type, "\"not a valid index\"", "[\"\"]")); + ASSERT_RAISES(Invalid, + DictScalarFromJSONString(type, "0", "[1]")); // dict value isn't string } } // namespace json diff --git a/cpp/src/arrow/testing/gtest_util.cc b/cpp/src/arrow/testing/gtest_util.cc index 99d6cabde9e..09e42d6f0fb 100644 --- a/cpp/src/arrow/testing/gtest_util.cc +++ b/cpp/src/arrow/testing/gtest_util.cc @@ -387,15 +387,14 @@ std::shared_ptr ArrayFromJSON(const std::shared_ptr& type, 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(json::DictArrayFromJSONString(type, indices_json, dictionary_json, &out)); + EXPECT_OK_AND_ASSIGN( + auto out, json::DictArrayFromJSONString(type, indices_json, dictionary_json)); return out; } std::shared_ptr ChunkedArrayFromJSON(const std::shared_ptr& type, const std::vector& json) { - std::shared_ptr out; - ABORT_NOT_OK(json::ChunkedArrayFromJSONString(type, json, &out)); + EXPECT_OK_AND_ASSIGN(auto out, json::ChunkedArrayFromJSONString(type, json)); return out; } @@ -411,16 +410,15 @@ 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(json::ScalarFromJSONString(type, json, &out)); + EXPECT_OK_AND_ASSIGN(auto out, json::ScalarFromJSONString(type, json)); return out; } 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(json::DictScalarFromJSONString(type, index_json, dictionary_json, &out)); + EXPECT_OK_AND_ASSIGN(auto out, + json::DictScalarFromJSONString(type, index_json, dictionary_json)); return out; } diff --git a/python/pyarrow/src/arrow/python/gdb.cc b/python/pyarrow/src/arrow/python/gdb.cc index 38383b86f49..2a7d2eda4bf 100644 --- a/python/pyarrow/src/arrow/python/gdb.cc +++ b/python/pyarrow/src/arrow/python/gdb.cc @@ -363,9 +363,8 @@ void TestSession() { ExtensionScalar extension_scalar_null{extension_scalar.value, extension_scalar_type, /*is_valid=*/false}; - std::shared_ptr heap_map_scalar; - ARROW_CHECK_OK(ScalarFromJSONString(map(utf8(), int32()), R"([["a", 5], ["b", 6]])", - &heap_map_scalar)); + auto heap_map_scalar = + *ScalarFromJSONString(map(utf8(), int32()), R"([["a", 5], ["b", 6]])"); auto heap_map_scalar_null = MakeNullScalar(heap_map_scalar->type); // Array and ArrayData @@ -479,13 +478,10 @@ void TestSession() { key_value_metadata({"key1", "key2", "key3"}, {"value1", "value2", "value3"})); // Table - ChunkedArrayVector table_columns{2}; - ARROW_CHECK_OK( - 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); + auto col1 = ChunkedArrayFromJSONString(int32(), {"[1, 2, 3]", "[4, 5]"}); + auto col2 = ChunkedArrayFromJSONString( + utf8(), {R"(["abc", null])", R"(["def"])", R"(["ghi", "jkl"])"}); + auto table = Table::Make(batch_schema, {*col1, *col2}); // Datum Datum empty_datum{};