Skip to content

Commit c244812

Browse files
authored
impl(bigquery): Json parsing changes for custom BigQuery library (#14918)
1 parent 025d6fd commit c244812

File tree

2 files changed

+65
-1
lines changed

2 files changed

+65
-1
lines changed

google/cloud/bigquery/v2/minimal/internal/json_utils.h

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,20 @@ bool SafeGetToWithNullable(ResponseType& value, bool& is_null,
101101
if (i != j.end()) {
102102
// BQ sends null type values which crashes get_to() so check for null.
103103
if (!i->is_null()) {
104-
i->get_to(value);
104+
// JSON value for the field, from the server, can be anything.
105+
// In 80% cases its a string value at which point we retrieve
106+
// the string value.
107+
// For any other values, (like nested Arrays or objects) we just give back
108+
// a string to be parsed by the caller. The library has no idea what to
109+
// expect in the value field it can be anything based on what the client
110+
// sends hence its not feasible to parse here. This is best done on the
111+
// client side based on the client-usecase and column schema returned by
112+
// the server for each of these values.
113+
if (i->type() == nlohmann::json::value_t::string) {
114+
i->get_to(value);
115+
} else {
116+
value = i->dump();
117+
}
105118
} else {
106119
is_null = true;
107120
}

google/cloud/bigquery/v2/minimal/internal/json_utils_test.cc

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,57 @@ TEST(JsonUtilsTest, SafeGetToWithNullableNonNull) {
277277
EXPECT_FALSE(is_null);
278278
}
279279

280+
TEST(JsonUtilsTest, SafeGetToWithNullableString) {
281+
auto const* const key = "v";
282+
auto constexpr kJsonText = R"({"v":"Apple"})";
283+
auto json = nlohmann::json::parse(kJsonText, nullptr, false);
284+
EXPECT_TRUE(json.is_object());
285+
286+
std::string val;
287+
bool is_null;
288+
EXPECT_TRUE(SafeGetToWithNullable(val, is_null, json, key));
289+
EXPECT_EQ(val, "Apple");
290+
}
291+
292+
TEST(JsonUtilsTest, SafeGetToWithNullableStringAsNumber) {
293+
auto const* const key = "v";
294+
auto constexpr kJsonText = R"({"v":"123"})";
295+
auto json = nlohmann::json::parse(kJsonText, nullptr, false);
296+
EXPECT_TRUE(json.is_object());
297+
298+
std::string val;
299+
bool is_null;
300+
EXPECT_TRUE(SafeGetToWithNullable(val, is_null, json, key));
301+
EXPECT_EQ(val, "123");
302+
}
303+
304+
TEST(JsonUtilsTest, SafeGetToWithNullableStringAsFloat) {
305+
auto const* const key = "v";
306+
auto constexpr kJsonText = R"({"v":"123.123"})";
307+
auto json = nlohmann::json::parse(kJsonText, nullptr, false);
308+
EXPECT_TRUE(json.is_object());
309+
310+
std::string val;
311+
bool is_null;
312+
EXPECT_TRUE(SafeGetToWithNullable(val, is_null, json, key));
313+
EXPECT_EQ(val, "123.123");
314+
}
315+
316+
TEST(JsonUtilsTest, SafeGetToWithNullableStringAsArray) {
317+
auto const* const key = "v";
318+
auto constexpr kExpectedJsonText =
319+
R"([{"v":"1"},{"v":"2"},{"v":"3"},{"v":"4"},{"v":"5"}])";
320+
auto constexpr kJsonText =
321+
R"({"v":[{"v":"1"},{"v":"2"},{"v":"3"},{"v":"4"},{"v":"5"}]})";
322+
auto json = nlohmann::json::parse(kJsonText, nullptr, false);
323+
EXPECT_TRUE(json.is_object());
324+
325+
std::string val;
326+
bool is_null;
327+
EXPECT_TRUE(SafeGetToWithNullable(val, is_null, json, key));
328+
EXPECT_EQ(val, kExpectedJsonText);
329+
}
330+
280331
GOOGLE_CLOUD_CPP_INLINE_NAMESPACE_END
281332
} // namespace bigquery_v2_minimal_internal
282333
} // namespace cloud

0 commit comments

Comments
 (0)