Skip to content

Commit

Permalink
impl(bigquery): Json parsing changes for custom BigQuery library (#14918
Browse files Browse the repository at this point in the history
)
  • Loading branch information
jsrinnn authored Jan 9, 2025
1 parent 025d6fd commit c244812
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 1 deletion.
15 changes: 14 additions & 1 deletion google/cloud/bigquery/v2/minimal/internal/json_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,20 @@ bool SafeGetToWithNullable(ResponseType& value, bool& is_null,
if (i != j.end()) {
// BQ sends null type values which crashes get_to() so check for null.
if (!i->is_null()) {
i->get_to(value);
// JSON value for the field, from the server, can be anything.
// In 80% cases its a string value at which point we retrieve
// the string value.
// For any other values, (like nested Arrays or objects) we just give back
// a string to be parsed by the caller. The library has no idea what to
// expect in the value field it can be anything based on what the client
// sends hence its not feasible to parse here. This is best done on the
// client side based on the client-usecase and column schema returned by
// the server for each of these values.
if (i->type() == nlohmann::json::value_t::string) {
i->get_to(value);
} else {
value = i->dump();
}
} else {
is_null = true;
}
Expand Down
51 changes: 51 additions & 0 deletions google/cloud/bigquery/v2/minimal/internal/json_utils_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,57 @@ TEST(JsonUtilsTest, SafeGetToWithNullableNonNull) {
EXPECT_FALSE(is_null);
}

TEST(JsonUtilsTest, SafeGetToWithNullableString) {
auto const* const key = "v";
auto constexpr kJsonText = R"({"v":"Apple"})";
auto json = nlohmann::json::parse(kJsonText, nullptr, false);
EXPECT_TRUE(json.is_object());

std::string val;
bool is_null;
EXPECT_TRUE(SafeGetToWithNullable(val, is_null, json, key));
EXPECT_EQ(val, "Apple");
}

TEST(JsonUtilsTest, SafeGetToWithNullableStringAsNumber) {
auto const* const key = "v";
auto constexpr kJsonText = R"({"v":"123"})";
auto json = nlohmann::json::parse(kJsonText, nullptr, false);
EXPECT_TRUE(json.is_object());

std::string val;
bool is_null;
EXPECT_TRUE(SafeGetToWithNullable(val, is_null, json, key));
EXPECT_EQ(val, "123");
}

TEST(JsonUtilsTest, SafeGetToWithNullableStringAsFloat) {
auto const* const key = "v";
auto constexpr kJsonText = R"({"v":"123.123"})";
auto json = nlohmann::json::parse(kJsonText, nullptr, false);
EXPECT_TRUE(json.is_object());

std::string val;
bool is_null;
EXPECT_TRUE(SafeGetToWithNullable(val, is_null, json, key));
EXPECT_EQ(val, "123.123");
}

TEST(JsonUtilsTest, SafeGetToWithNullableStringAsArray) {
auto const* const key = "v";
auto constexpr kExpectedJsonText =
R"([{"v":"1"},{"v":"2"},{"v":"3"},{"v":"4"},{"v":"5"}])";
auto constexpr kJsonText =
R"({"v":[{"v":"1"},{"v":"2"},{"v":"3"},{"v":"4"},{"v":"5"}]})";
auto json = nlohmann::json::parse(kJsonText, nullptr, false);
EXPECT_TRUE(json.is_object());

std::string val;
bool is_null;
EXPECT_TRUE(SafeGetToWithNullable(val, is_null, json, key));
EXPECT_EQ(val, kExpectedJsonText);
}

GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_END
} // namespace bigquery_v2_minimal_internal
} // namespace cloud
Expand Down

0 comments on commit c244812

Please sign in to comment.