Line data Source code
1 : #include "backend/engine/semantic/functions/json_funcs.h"
2 :
3 : #include <vector>
4 :
5 : #include "backend/engine/semantic/value.h"
6 : #include "googlesql/public/type.h"
7 : #include "googlesql/public/types/type_factory.h"
8 : #include "googlesql/public/value.h"
9 : #include "gtest/gtest.h"
10 :
11 : namespace bigquery_emulator {
12 : namespace backend {
13 : namespace engine {
14 : namespace semantic {
15 : namespace functions {
16 : namespace {
17 :
18 1 : const ::googlesql::ArrayType* StringArrayType() {
19 1 : static ::googlesql::TypeFactory factory;
20 1 : const ::googlesql::ArrayType* arr = nullptr;
21 1 : factory.MakeArrayType(factory.get_string(), &arr);
22 1 : return arr;
23 1 : }
24 :
25 1 : TEST(JsonFuncsTest, JsonExtractScalarUnquotesString) {
26 1 : Value doc = Value::String(R"({ "name" : "Jakob", "age" : "6" })");
27 1 : Value path = Value::String("$.name");
28 1 : auto v = JsonExtractScalar({doc, path}, /*return_type=*/nullptr);
29 2 : ASSERT_TRUE(v.ok()) << v.status();
30 1 : EXPECT_EQ(v->string_value(), "Jakob");
31 1 : }
32 :
33 1 : TEST(JsonFuncsTest, JsonExtractReturnsCompactObject) {
34 1 : Value doc =
35 1 : Value::UnvalidatedJsonString(R"({"class":{"students":[{"id":5}]}})");
36 1 : Value path = Value::String("$.class");
37 1 : auto v = JsonExtract({doc, path}, /*return_type=*/nullptr);
38 2 : ASSERT_TRUE(v.ok()) << v.status();
39 1 : EXPECT_EQ(v->string_value(), R"({"students":[{"id":5}]})");
40 1 : }
41 :
42 1 : TEST(JsonFuncsTest, JsonExtractNullFieldReturnsNull) {
43 1 : Value doc = Value::String(R"({"a":null})");
44 1 : Value path = Value::String("$.a");
45 1 : auto v = JsonExtract({doc, path}, /*return_type=*/nullptr);
46 2 : ASSERT_TRUE(v.ok()) << v.status();
47 1 : EXPECT_TRUE(v->is_null());
48 1 : }
49 :
50 1 : TEST(JsonFuncsTest, JsonExtractArraySingleArgRoot) {
51 1 : Value doc = Value::String("[1,2,3]");
52 1 : auto v = JsonExtractArray({doc}, StringArrayType());
53 2 : ASSERT_TRUE(v.ok()) << v.status();
54 1 : ASSERT_EQ(v->num_elements(), 3);
55 1 : EXPECT_EQ(v->element(0).string_value(), "1");
56 1 : EXPECT_EQ(v->element(2).string_value(), "3");
57 1 : }
58 :
59 1 : TEST(JsonFuncsTest, ParseJsonRoundTrip) {
60 1 : Value json_text = Value::String(R"({"coordinates":[10,20],"id":1})");
61 1 : auto v = ParseJson({json_text});
62 2 : ASSERT_TRUE(v.ok()) << v.status();
63 1 : EXPECT_EQ(v->json_string(), R"({"coordinates":[10,20],"id":1})");
64 1 : }
65 :
66 1 : TEST(JsonFuncsTest, JsonCastBoolFromJsonLiteral) {
67 1 : Value literal = Value::UnvalidatedJsonString("true");
68 1 : auto v = JsonCastBool({literal});
69 2 : ASSERT_TRUE(v.ok()) << v.status();
70 1 : EXPECT_TRUE(v->bool_value());
71 1 : }
72 :
73 1 : TEST(JsonFuncsTest, JsonCastInt64FromJsonLiteral) {
74 1 : Value literal = Value::UnvalidatedJsonString("2005");
75 1 : auto v = JsonCastInt64({literal});
76 2 : ASSERT_TRUE(v.ok()) << v.status();
77 1 : EXPECT_EQ(v->int64_value(), 2005);
78 1 : }
79 :
80 : } // namespace
81 : } // namespace functions
82 : } // namespace semantic
83 : } // namespace engine
84 : } // namespace backend
85 : } // namespace bigquery_emulator
|