oceanbase/unittest/share/test_json_tree.cpp
Tyshawn f1a6170c93 [FEAT MERGE] Full-text Search Index + [CP]Adaptive DAS Group Rescan + Json Multi-Value Index
Co-authored-by: saltonz <saltonzh@gmail.com>
Co-authored-by: pe-99y <315053752@qq.com>
Co-authored-by: JinmaoLi <ljm.csmaster@gmail.com>
2024-04-22 05:46:19 +00:00

2357 lines
90 KiB
C++

/**
* Copyright (c) 2021 OceanBase
* OceanBase CE is licensed under Mulan PubL v2.
* You can use this software according to the terms and conditions of the Mulan PubL v2.
* You may obtain a copy of Mulan PubL v2 at:
* http://license.coscl.org.cn/MulanPubL-2.0
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PubL v2 for more details.
*/
#include <gtest/gtest.h>
#define private public
#include "lib/json_type/ob_json_tree.h"
#include "lib/json_type/ob_json_bin.h"
#include "lib/json_type/ob_json_parse.h"
#include "lib/timezone/ob_timezone_info.h"
#undef private
#include <sys/time.h>
using namespace std;
namespace oceanbase {
namespace common {
#define YEAR_MAX_YEAR 2155
#define YEAR_MIN_YEAR 1901
#define YEAR_BASE_YEAR 1900
class TestJsonTree : public ::testing::Test {
public:
TestJsonTree()
{}
~TestJsonTree()
{}
virtual void SetUp()
{}
virtual void TearDown()
{}
static void SetUpTestCase()
{}
static void TearDownTestCase()
{}
private:
// disallow copy
DISALLOW_COPY_AND_ASSIGN(TestJsonTree);
};
// ObJsonParser::parse_json_text 单元函数测试
TEST_F(TestJsonTree, test_parse_json_text)
{
const char *syntaxerr = NULL;
uint64_t err_offset = 0;
ObJsonNode *j_node = NULL;
ObArenaAllocator allocator(ObModIds::TEST);
common::ObString j_text("{ \"greeting\" : \"Hello!\", \"farewell\" : \"bye-bye!\"}");
// 1. 入参检查测试
ASSERT_EQ(OB_ERR_NULL_VALUE, ObJsonParser::parse_json_text(NULL, j_text.ptr(), j_text.length(),
syntaxerr, &err_offset, j_node));
ASSERT_EQ(OB_ERR_NULL_VALUE, ObJsonParser::parse_json_text(&allocator, NULL, j_text.length(),
syntaxerr, &err_offset, j_node));
ASSERT_EQ(OB_ERR_NULL_VALUE, ObJsonParser::parse_json_text(&allocator, j_text.ptr(), 0,
syntaxerr, &err_offset, j_node));
ASSERT_EQ(OB_SUCCESS, ObJsonParser::parse_json_text(&allocator, j_text.ptr(), j_text.length(),
syntaxerr, NULL, j_node));
ASSERT_EQ(OB_SUCCESS, ObJsonParser::parse_json_text(&allocator, j_text.ptr(), j_text.length(),
syntaxerr, &err_offset, j_node));
common::ObString j_sp_text("ab' as json)n)mit 1oot@mysql");
ASSERT_EQ(OB_ERR_INVALID_JSON_TEXT, ObJsonParser::parse_json_text(&allocator,
j_sp_text.ptr(), j_sp_text.length(), syntaxerr, &err_offset, j_node));
ASSERT_EQ(OB_ERR_INVALID_JSON_TEXT, ObJsonParser::parse_json_text(&allocator,
j_sp_text.ptr(), 2, syntaxerr, &err_offset, j_node)); // 只解析ab
// 2. 路径覆盖测试,有些异常分支不一定能覆盖到
// 2.1 成功解析,解析结果不为NULL
ASSERT_EQ(OB_SUCCESS, ObJsonParser::parse_json_text(&allocator, j_text.ptr(), j_text.length(),
syntaxerr, &err_offset, j_node));
ASSERT_TRUE(j_node != NULL);
// 2.2 成功解析,解析结果为NULL, syntaxerr不为NULL(这个路径应该是rapidjson出错了,比较难构造用例,不测试)
// 2.3 解析出错,吐出语法错误内容
char buf[256] = {0};
syntaxerr = buf;
j_node = NULL;
common::ObString j_err_text("{ \"greeting\" error \"Hello!\", \"farewell\" : \"bye-bye!\"}");
ASSERT_EQ(OB_ERR_INVALID_JSON_TEXT, ObJsonParser::parse_json_text(&allocator,
j_err_text.ptr(), j_err_text.length(), syntaxerr, &err_offset, j_node));
ASSERT_EQ(NULL, j_node);
std::cout << "syntaxerr:" << syntaxerr << std::endl;
std::cout << "err_offset:" << err_offset << std::endl;
ASSERT_EQ(13, err_offset);
ASSERT_STREQ("Missing a colon after a name of object member.", syntaxerr);
common::ObString j_err_text1("}");
ASSERT_EQ(OB_ERR_INVALID_JSON_TEXT, ObJsonParser::parse_json_text(&allocator,
j_err_text1.ptr(), j_err_text1.length(), syntaxerr, &err_offset, j_node));
}
// add_double_quote 单元函数测试
TEST_F(TestJsonTree, test_add_double_quote)
{
ObArenaAllocator allocator(ObModIds::TEST);
common::ObString str("hello");
ObJsonBuffer j_buf(&allocator);
// 1. 入参检查测试
ASSERT_EQ(OB_ERR_NULL_VALUE, ObJsonBaseUtil::add_double_quote(j_buf, NULL, str.length()));
ASSERT_EQ(OB_SUCCESS, ObJsonBaseUtil::add_double_quote(j_buf, str.ptr(), 0));
// 2. 路径覆盖测试,有些异常分支不一定能覆盖到
// 2.1 源字符串不带转义字符
ASSERT_EQ(OB_SUCCESS, ObJsonBaseUtil::add_double_quote(j_buf, str.ptr(), str.length()));
cout << j_buf.ptr() << endl;
// 2.2 源字符串带转义字符(测试escape_character函数的所有转义字符)
str.reset();
str.assign_ptr("\b\t\n\f\r\"\\", strlen("\b\t\n\f\r\"\\"));
j_buf.reset();
ASSERT_EQ(OB_SUCCESS, ObJsonBaseUtil::add_double_quote(j_buf, str.ptr(), str.length()));
cout << "quote: " << j_buf.ptr() << endl;
str.reset();
str.assign_ptr("\a", strlen("\a"));
j_buf.reset();
ASSERT_EQ(OB_SUCCESS, ObJsonBaseUtil::add_double_quote(j_buf, str.ptr(), str.length()));
str.reset();
cout << "quote: " << j_buf.ptr() << endl;
str.assign_ptr("\0", strlen("\0"));
j_buf.reset();
ASSERT_EQ(OB_SUCCESS, ObJsonBaseUtil::add_double_quote(j_buf, str.ptr(), str.length()));
str.reset();
str.assign_ptr("\?", strlen("\?"));
j_buf.reset();
ASSERT_EQ(OB_SUCCESS, ObJsonBaseUtil::add_double_quote(j_buf, str.ptr(), str.length()));
cout << "quote: " << j_buf.ptr() << endl;
str.reset();
str.assign_ptr("\v", strlen("\v"));
j_buf.reset();
ASSERT_EQ(OB_SUCCESS, ObJsonBaseUtil::add_double_quote(j_buf, str.ptr(), str.length()));
cout << "quote: " << j_buf.ptr() << endl;
}
// ObJsonObject 单元测试
TEST_F(TestJsonTree, test_ObJsonObject)
{
ObArenaAllocator allocator(ObModIds::TEST);
ObJsonObject obj(&allocator);
/* 1. ObJsonObject::add测试 */
// 参数检查测试
ObString j_str("hello");
ASSERT_EQ(OB_INVALID_ARGUMENT, obj.add(j_str, NULL));
// 路径覆盖测试
ObString k1("k1");
ObString k2("k2");
ObString k3("k2");
ObJsonInt j_int1(1);
ObJsonInt j_int2(2);
ObJsonInt j_int3(3);
ASSERT_EQ(OB_SUCCESS, obj.add(k1, &j_int1));
ASSERT_EQ(1, obj.element_count());
ObJsonNode *v1 = obj.get_value(k1);
ASSERT_TRUE(NULL != v1);
ObJsonInt *v1_int = static_cast<ObJsonInt *>(v1);
ASSERT_EQ(1, v1_int->value());
ASSERT_EQ(OB_SUCCESS, obj.add(k2, &j_int2));
ASSERT_EQ(2, obj.element_count());
ObJsonNode *v2 = obj.get_value(k2);
ASSERT_TRUE(NULL != v2);
ObJsonInt *v2_int = static_cast<ObJsonInt *>(v2);
ASSERT_EQ(2, v2_int->value());
ASSERT_EQ(OB_SUCCESS, obj.add(k3, &j_int3)); // 覆盖k2
ASSERT_EQ(2, obj.element_count());
ObJsonNode *v3 = obj.get_value(k3);
ASSERT_TRUE(NULL != v3);
ObJsonInt *v3_int = static_cast<ObJsonInt *>(v3);
ASSERT_EQ(3, v3_int->value());
/* 2. ObJsonObject::replace测试 */
// 参数检查测试
ObJsonInt j_int(1);
ASSERT_EQ(OB_INVALID_ARGUMENT, obj.replace(NULL, &j_int));
ASSERT_EQ(OB_INVALID_ARGUMENT, obj.replace(&j_int, NULL));
// 路径覆盖测试
ASSERT_EQ(OB_SEARCH_NOT_FOUND, obj.replace(&j_int, &j_int1));
ASSERT_EQ(OB_SUCCESS, obj.replace(&j_int1, &j_int2));
v1 = obj.get_value(k1);
ASSERT_TRUE(NULL != v1);
v1_int = static_cast<ObJsonInt *>(v1);
ASSERT_EQ(2, v1_int->value());
/* 3. ObJsonObject::get测试 */
// 参数检查测试
ASSERT_EQ(NULL, obj.get_value(ULLONG_MAX));
// 路径覆盖测试
v1 = obj.get_value(0);
ASSERT_TRUE(NULL != v1);
v1_int = static_cast<ObJsonInt *>(v1);
ASSERT_EQ(2, v1_int->value());
/* 3. ObJsonObject::remove测试 */
// 路径覆盖测试
ASSERT_EQ(OB_SUCCESS, obj.remove(k3));
ASSERT_EQ(1, obj.element_count());
}
// ObJsonArray 单元测试
TEST_F(TestJsonTree, test_ObJsonArray)
{
ObArenaAllocator allocator(ObModIds::TEST);
ObJsonArray j_arr(&allocator);
/* 1. ObJsonArray::append测试 */
// 参数检查测试
ASSERT_EQ(OB_INVALID_ARGUMENT, j_arr.append(NULL));
// 路径覆盖测试
ObJsonInt j_int0(0);
ASSERT_EQ(OB_SUCCESS, j_arr.append(&j_int0));
ASSERT_EQ(1, j_arr.element_count());
ObJsonNode *node = j_arr[0];
ObJsonInt *v = static_cast<ObJsonInt *>(node);
ASSERT_EQ(0, v->value());
/* 2. ObJsonArray::insert测试 */
// 参数检查测试
ASSERT_EQ(OB_INVALID_ARGUMENT, j_arr.insert(0, NULL));
// 路径覆盖测试
ObJsonInt j_int1(1);
ASSERT_EQ(OB_SUCCESS, j_arr.insert(1, &j_int1));
ASSERT_EQ(2, j_arr.element_count());
node = j_arr[1];
v = static_cast<ObJsonInt *>(node);
ASSERT_EQ(1, v->value());
ObJsonInt j_int2(2);
ASSERT_EQ(OB_SUCCESS, j_arr.insert(10, &j_int2));
ASSERT_EQ(3, j_arr.element_count());
node = j_arr[2];
v = static_cast<ObJsonInt *>(node);
ASSERT_EQ(2, v->value());
/* 3. ObJsonArray::replace测试 */
// 参数检查测试
ASSERT_EQ(OB_INVALID_ARGUMENT, j_arr.replace(NULL, &j_int0));
ASSERT_EQ(OB_INVALID_ARGUMENT, j_arr.replace(&j_int0, NULL));
ASSERT_EQ(OB_INVALID_ARGUMENT, j_arr.replace(NULL, NULL));
// 路径覆盖测试
ObJsonInt j_not_found(10);
ASSERT_EQ(OB_SEARCH_NOT_FOUND, j_arr.replace(&j_not_found, &j_int0));
ASSERT_EQ(OB_SUCCESS, j_arr.replace(&j_int0, &j_not_found));
node = j_arr[0];
v = static_cast<ObJsonInt *>(node);
ASSERT_EQ(10, v->value());
/* 4. ObJsonArray::remove测试 */
// 参数检查测试
ASSERT_EQ(OB_ERROR_OUT_OF_RANGE, j_arr.remove(100));
ObJsonNode *null_ptr = NULL;
// 路径覆盖测试
ASSERT_EQ(OB_SUCCESS, j_arr.remove(2));
ASSERT_EQ(2, j_arr.element_count());
}
TEST_F(TestJsonTree, test_rapijson)
{
// correct json text
common::ObString json_text("{ \"greeting\" : \"Hello!\", \"farewell\" : \"bye-bye!\", \
\"json_text\" : \"test!\" }");
common::ObArenaAllocator allocator(ObModIds::TEST);
const char *syntaxerr = NULL;
ObJsonNode *json_tree = NULL;
ASSERT_EQ(OB_SUCCESS, ObJsonParser::parse_json_text(&allocator, json_text.ptr(),
json_text.length(), syntaxerr, NULL, json_tree));
ASSERT_TRUE(json_tree != NULL);
// null allocator
ASSERT_EQ(OB_ERR_NULL_VALUE, ObJsonParser::parse_json_text(NULL, json_text.ptr(),
json_text.length(), syntaxerr, NULL, json_tree));
// null json text
ASSERT_EQ(OB_ERR_NULL_VALUE, ObJsonParser::parse_json_text(&allocator, NULL,
json_text.length(), syntaxerr, NULL, json_tree));
// json text length=0
ASSERT_EQ(OB_ERR_NULL_VALUE, ObJsonParser::parse_json_text(&allocator, json_text.ptr(),
0, syntaxerr, NULL, json_tree));
// wrong json text
const char syntaxerr_info[100] = {0};
const char *err_info_ptr = syntaxerr_info;
uint64_t wr_info_offest = 0;
common::ObString wrong_json_text("{ \"greeting\" , \"Hello!\", \"farewell\" : \"bye-bye!\", \
\"json_text\" : \"test!\" }");
ASSERT_EQ(OB_ERR_INVALID_JSON_TEXT, ObJsonParser::parse_json_text(&allocator,
wrong_json_text.ptr(), wrong_json_text.length(), err_info_ptr, &wr_info_offest, json_tree));
std::cout << err_info_ptr << std::endl;
std::cout << wr_info_offest << std::endl;
ASSERT_STREQ(err_info_ptr, "Missing a colon after a name of object member.");
ASSERT_EQ(13, wr_info_offest);
}
TEST_F(TestJsonTree, test_json_object)
{
ObArenaAllocator allocator(ObModIds::TEST);
ObJsonObject obj(&allocator);
ASSERT_EQ(NULL, obj.get_parent());
ASSERT_EQ(ObJsonNodeType::J_OBJECT, obj.json_type());
ObJsonString v1("v1", 2), v2("v2", 2), v3("v3", 2), v4("v4", 2);
ObString k1("key1"), k2("key2"), k3("key3");
ASSERT_EQ(OB_SUCCESS, obj.add(k1, &v1));
ASSERT_EQ(OB_SUCCESS, obj.add(k2, &v2));
ASSERT_EQ(OB_SUCCESS, obj.add(k3, &v3));
ASSERT_EQ(OB_SUCCESS, obj.add(k2, &v4));
ASSERT_EQ(OB_INVALID_ARGUMENT, obj.add(k2, NULL));
obj.sort();
const ObJsonString *node1 = static_cast<const ObJsonString*>(obj.get_value(k1));
const ObJsonString *node2 = static_cast<const ObJsonString*>(obj.get_value(k2));
const ObJsonString *node3 = static_cast<const ObJsonString*>(obj.get_value(k3));
ASSERT_STREQ("v1", node1->value().ptr());
ASSERT_STREQ("v4", node2->value().ptr()); // v4 覆盖了 v2
ASSERT_STREQ("v3", node3->value().ptr());
ASSERT_EQ(OB_SUCCESS, obj.remove(k1));
node1 = static_cast<const ObJsonString*>(obj.get_value(k1));
ASSERT_EQ(NULL, node1);
ASSERT_EQ(OB_SUCCESS, obj.remove(k1));
obj.clear();
ASSERT_EQ(0, obj.element_count());
}
TEST_F(TestJsonTree, test_array_consume_int)
{
common::ObArenaAllocator alloc(ObModIds::TEST);
ObJsonArray target(&alloc), src(&alloc);
int val = 0, val_initial = 0;
// src array add some elements
ObJsonInt sr_val1(++val);
ASSERT_EQ(src.append(&sr_val1), OB_SUCCESS);
ObJsonInt sr_val2(++val);
ASSERT_EQ(src.append(&sr_val2), OB_SUCCESS);
ObJsonInt sr_val3(++val);
ASSERT_EQ(src.append(&sr_val3), OB_SUCCESS);
ObJsonInt sr_val4(++val);
ASSERT_EQ(src.append(&sr_val4), OB_SUCCESS);
// src elements moved to target
ASSERT_EQ(target.consume(&alloc, &src), false);
ASSERT_EQ(target.element_count(), 4);
ASSERT_EQ(src.element_count(), 0);
for (int i = 0; i < target.element_count(); ++i) {
// check value is correct
ASSERT_EQ((static_cast<ObJsonInt*>(target[i]))->value(), ++val_initial);
}
target.clear();
src.clear();
ASSERT_EQ(target.element_count(), 0);
ASSERT_EQ(src.element_count(), 0);
val = 0, val_initial = 0;
// src array add some elements
ASSERT_EQ(target.append(&sr_val1), OB_SUCCESS);
ASSERT_EQ(target.append(&sr_val2), OB_SUCCESS);
ASSERT_EQ(target.append(&sr_val3), OB_SUCCESS);
ASSERT_EQ(target.append(&sr_val4), OB_SUCCESS);
ASSERT_EQ(target.element_count(), 4);
// src is empty, nothing changed
ASSERT_EQ(target.consume(&alloc, &src), false);
for (int i = 0; i < target.element_count(); ++i) {
// check value is correct
ASSERT_EQ((static_cast<ObJsonInt*>(target[i]))->value(), ++val_initial);
}
val = val_initial = 0;
ASSERT_EQ(src.append(&sr_val1), OB_SUCCESS);
ASSERT_EQ(src.append(&sr_val2), OB_SUCCESS);
ASSERT_EQ(src.append(&sr_val3), OB_SUCCESS);
ASSERT_EQ(src.append(&sr_val4), OB_SUCCESS);
ASSERT_EQ(src.element_count(), 4);
ASSERT_EQ(target.consume(&alloc, &src), false);
ASSERT_EQ(target.element_count(), 8);
ASSERT_EQ(src.element_count(), 0);
}
TEST_F(TestJsonTree, test_array_consume_string)
{
common::ObArenaAllocator alloc(ObModIds::TEST);
ObJsonArray target(&alloc), src(&alloc);
ObString str_val1("sr_val1");
ObJsonString sr_val1(str_val1.ptr(), str_val1.length());
ASSERT_EQ(src.append(&sr_val1), OB_SUCCESS);
ObString str_val2("sr_val2");
ObJsonString sr_val2(str_val2.ptr(), str_val1.length());
ASSERT_EQ(src.append(&sr_val2), OB_SUCCESS);
ObString str_val3("sr_val3");
ObJsonString sr_val3(str_val3.ptr(), str_val1.length());
ASSERT_EQ(src.append(&sr_val3), OB_SUCCESS);
ObString str_val4("sr_val4");
ObJsonString sr_val4(str_val4.ptr(), str_val1.length());
ASSERT_EQ(src.append(&sr_val4), OB_SUCCESS);
// src elements moved to target
ASSERT_EQ(target.consume(&alloc, &src), false);
ASSERT_EQ(target.element_count(), 4);
ASSERT_EQ(src.element_count(), 0);
ASSERT_STREQ((static_cast<ObJsonString*>(target[0]))->value().ptr(), "sr_val1");
ASSERT_STREQ((static_cast<ObJsonString*>(target[1]))->value().ptr(), "sr_val2");
ASSERT_STREQ((static_cast<ObJsonString*>(target[2]))->value().ptr(), "sr_val3");
ASSERT_STREQ((static_cast<ObJsonString*>(target[3]))->value().ptr(), "sr_val4");
target.clear();
src.clear();
ASSERT_EQ(target.element_count(), 0);
ASSERT_EQ(src.element_count(), 0);
// src array add some elements
ASSERT_EQ(target.append(&sr_val1), OB_SUCCESS);
ASSERT_EQ(target.append(&sr_val2), OB_SUCCESS);
ASSERT_EQ(target.append(&sr_val3), OB_SUCCESS);
ASSERT_EQ(target.append(&sr_val4), OB_SUCCESS);
ASSERT_EQ(target.element_count(), 4);
// src is empty, nothing changed
ASSERT_EQ(target.consume(&alloc, &src), false);
ASSERT_EQ(src.append(&sr_val1), OB_SUCCESS);
ASSERT_EQ(src.append(&sr_val2), OB_SUCCESS);
ASSERT_EQ(src.append(&sr_val3), OB_SUCCESS);
ASSERT_EQ(src.append(&sr_val4), OB_SUCCESS);
ASSERT_EQ(src.element_count(), 4);
ASSERT_EQ(target.consume(&alloc, &src), false);
ASSERT_STREQ((static_cast<ObJsonString*>(target[4]))->value().ptr(), "sr_val1");
ASSERT_STREQ((static_cast<ObJsonString*>(target[5]))->value().ptr(), "sr_val2");
ASSERT_STREQ((static_cast<ObJsonString*>(target[6]))->value().ptr(), "sr_val3");
ASSERT_STREQ((static_cast<ObJsonString*>(target[7]))->value().ptr(), "sr_val4");
ASSERT_EQ(target.element_count(), 8);
ASSERT_EQ(src.element_count(), 0);
}
TEST_F(TestJsonTree, test_object_consume)
{
common::ObArenaAllocator alloc(ObModIds::TEST);
ObJsonObject target(&alloc), src(&alloc);
ObString k1("k1");
ObString k2("k2");
ObString k3("k3");
ObJsonInt j_int1(1);
ObJsonInt j_int2(2);
ObJsonInt j_int3(3);
ASSERT_EQ(OB_SUCCESS, src.add(k1, &j_int1));
ASSERT_EQ(OB_SUCCESS, src.add(k2, &j_int2));
ASSERT_EQ(OB_SUCCESS, src.add(k3, &j_int3));
ASSERT_EQ(target.consume(&alloc, &src), OB_SUCCESS);
ASSERT_EQ(target.element_count(), 3);
ASSERT_EQ(src.element_count(), 0);
ASSERT_EQ(OB_SUCCESS, src.add(k1, &j_int1));
ASSERT_EQ(OB_SUCCESS, src.add(k2, &j_int2));
ASSERT_EQ(OB_SUCCESS, src.add(k3, &j_int3));
ASSERT_EQ(target.consume(&alloc, &src), OB_SUCCESS);
ASSERT_EQ(target.element_count(), 3);
ASSERT_EQ(src.element_count(), 0);
}
TEST_F(TestJsonTree, test_merge_patch)
{
common::ObArenaAllocator alloc(ObModIds::TEST);
ObJsonObject patch_obj(&alloc), target_obj(&alloc), sub_obj(&alloc);
ObJsonArray patch_arr(&alloc);
ObString str_key1("str_key1");
ObString str_key2("str_key2");
ObString str_key3("str_key3");
ObJsonString json_str1(str_key1.ptr(), str_key1.length());
ObJsonString json_str2(str_key2.ptr(), str_key2.length());
ObJsonString json_str3(str_key3.ptr(), str_key3.length());
ObJsonInt json_int1(1);
ObJsonInt json_int2(2);
ObJsonInt json_int3(3);
ObJsonNull json_null;
ASSERT_EQ(sub_obj.add(str_key1, &json_str1), OB_SUCCESS);
ASSERT_EQ(sub_obj.add(str_key2, &json_str2), OB_SUCCESS);
ASSERT_EQ(sub_obj.add(str_key3, &json_str3), OB_SUCCESS);
ASSERT_EQ(target_obj.add(str_key1, &sub_obj), OB_SUCCESS);
ASSERT_EQ(target_obj.add(str_key2, &json_str2), OB_SUCCESS);
ASSERT_EQ(target_obj.add(str_key3, &json_str3), OB_SUCCESS);
ASSERT_EQ(patch_obj.add(str_key1, &json_str1), OB_SUCCESS);
// target_obj, str_key1 is overwritten
ASSERT_EQ(target_obj.merge_patch(&alloc, &patch_obj), false);
ASSERT_EQ(target_obj.element_count(), 3);
ASSERT_EQ(target_obj.get_value(str_key1)->json_type(), ObJsonNodeType::J_STRING);
ASSERT_STREQ((static_cast<ObJsonString*>(target_obj.get_value(str_key1)))->value().ptr(),
json_str1.value().ptr());
// patch null value, ignore
patch_obj.clear();
ASSERT_EQ(patch_obj.add(str_key1, &json_null), OB_SUCCESS);
ASSERT_EQ(target_obj.merge_patch(&alloc, &patch_obj), false);
ASSERT_EQ(target_obj.element_count(), 2);
// clear all
patch_obj.clear();
target_obj.clear();
// patch has member which target_obj not exist
ASSERT_EQ(target_obj.add(str_key2, &json_str2), OB_SUCCESS);
ASSERT_EQ(target_obj.add(str_key3, &json_str3), OB_SUCCESS);
ASSERT_EQ(patch_obj.add(str_key1, &json_str1), OB_SUCCESS);
ASSERT_EQ(target_obj.merge_patch(&alloc, &patch_obj), false);
ASSERT_EQ(target_obj.element_count(), 3);
// patch has the same key object
ASSERT_NE(target_obj.get_value(str_key1), static_cast<ObJsonNode*>(NULL));
patch_obj.clear();
ASSERT_EQ(target_obj.add(str_key1, &sub_obj), OB_SUCCESS);
ASSERT_EQ(target_obj.merge_patch(&alloc, &patch_obj), false);
ASSERT_EQ(target_obj.get_value(str_key1), &sub_obj);
ObJsonObject* temp_object = static_cast<ObJsonObject*>(target_obj.get_value(str_key1));
ASSERT_EQ(temp_object->element_count(), 3);
}
TEST_F(TestJsonTree, test_merge_tree_bugfix)
{
common::ObArenaAllocator allocator(ObModIds::TEST);
ObIJsonBase *result = NULL;
ObJsonObject obj1(&allocator);
ObJsonObject obj2(&allocator);
ObIJsonBase *left_obj = &obj1;
ObIJsonBase *right_obj = &obj2;
ObString k1("a");
ObString k2("b");
ObJsonInt v1(2);
ObJsonInt v2(3);
ASSERT_EQ(OB_SUCCESS, obj1.add(k1, &v1));
ASSERT_EQ(OB_SUCCESS, obj2.add(k2, &v2));
ASSERT_EQ(OB_SUCCESS, left_obj->merge_tree(&allocator, right_obj, result));
ASSERT_TRUE(result != NULL);
ASSERT_EQ(2, result->element_count());
}
TEST_F(TestJsonTree, test_json_cast_to_int)
{
int64_t i = 0;
const int64_t MAX_BUF_SIZE = 256;
char buf[MAX_BUF_SIZE] = {0};
common::ObArenaAllocator alloc(ObModIds::TEST);
ObIJsonBase *j_base = NULL;
ObJsonUint my_uint(0);
ObJsonInt my_int(0);
ObJsonString my_str(buf, strlen(buf));
ObJsonBoolean my_bool(true);
ObJsonDouble my_double(0.0);
// uint -> int (10)
j_base = &my_uint;
my_uint.set_value(10);
ASSERT_EQ(OB_SUCCESS, j_base->to_int(i));
ASSERT_EQ(10, i);
// uint -> int (LLONG_MAX)
my_uint.set_value(LLONG_MAX);
ASSERT_EQ(OB_SUCCESS, j_base->to_int(i));
ASSERT_EQ(LLONG_MAX, i);
// int -> int (LLONG_MIN)
j_base = &my_int;
my_int.set_value(LLONG_MIN);
ASSERT_EQ(OB_SUCCESS, j_base->to_int(i));
ASSERT_EQ(LLONG_MIN, i);
// int -> int (0)
my_int.set_value(0);
ASSERT_EQ(OB_SUCCESS, j_base->to_int(i));
ASSERT_EQ(0, i);
// int -> int (LLONG_MAX)
my_int.set_value(LLONG_MAX);
ASSERT_EQ(OB_SUCCESS, j_base->to_int(i));
ASSERT_EQ(LLONG_MAX, i);
// string -> int ("abc")
j_base = &my_str;
ASSERT_EQ(strlen("abc"), sprintf(buf, "abc"));
my_str.set_value(buf, strlen(buf));
ASSERT_EQ(OB_ERR_DATA_TRUNCATED, j_base->to_int(i));
// string -> int ("LLONG_MIN")
j_base = &my_str;
int length = sprintf(buf, "%lld", LLONG_MIN);
my_str.set_value(buf, length);
ASSERT_EQ(OB_SUCCESS, j_base->to_int(i));
ASSERT_EQ(LLONG_MIN, i);
// string -> int ("LLONG_MAX")
j_base = &my_str;
length = sprintf(buf, "%lld", LLONG_MAX);
my_str.set_value(buf, length);
ASSERT_EQ(OB_SUCCESS, j_base->to_int(i));
ASSERT_EQ(LLONG_MAX, i);
// string -> int ("0")
j_base = &my_str;
length = sprintf(buf, "%d", 0);
my_str.set_value(buf, length);
ASSERT_EQ(OB_SUCCESS, j_base->to_int(i));
ASSERT_EQ(0, i);
// boolean -> int (true)
j_base = &my_bool;
my_bool.set_value(true);
ASSERT_EQ(OB_SUCCESS, j_base->to_int(i));
ASSERT_EQ(true, i);
// boolean -> int (false)
j_base = &my_bool;
my_bool.set_value(false);
ASSERT_EQ(OB_SUCCESS, j_base->to_int(i));
ASSERT_EQ(false, i);
// number -> int (LLONG_MIN)
char buf_alloc[MAX_BUF_SIZE];
ObDataBuffer allocator(buf_alloc, MAX_BUF_SIZE);
number::ObNumber num;
allocator.free();
length = sprintf(buf, "%lld", LLONG_MIN);
ASSERT_EQ(OB_SUCCESS, num.from(buf, allocator));
ObJsonDecimal my_num(num);
j_base = &my_num;
ASSERT_EQ(OB_SUCCESS, j_base->to_int(i));
ASSERT_EQ(LLONG_MIN, i);
// number -> int (0)
allocator.free();
length = sprintf(buf, "%d", 0);
ASSERT_EQ(OB_SUCCESS, num.from(buf, allocator));
my_num.set_value(num);
j_base = &my_num;
ASSERT_EQ(OB_SUCCESS, j_base->to_int(i));
ASSERT_EQ(0, i);
// number -> int (LLONG_MAX)
allocator.free();
length = sprintf(buf, "%lld", LLONG_MAX);
ASSERT_EQ(OB_SUCCESS, num.from(buf, allocator));
my_num.set_value(num);
j_base = &my_num;
ASSERT_EQ(OB_SUCCESS, j_base->to_int(i));
ASSERT_EQ(LLONG_MAX, i);
// double -> int (LLONG_MIN - 1)
double d = static_cast<double>(LLONG_MIN);
my_double.set_value(d - 1);
j_base = &my_double;
ASSERT_EQ(OB_SUCCESS, j_base->to_int(i));
ASSERT_EQ(LLONG_MIN, i);
// double -> int (LLONG_MAX + 1)
d = static_cast<double>(LLONG_MAX);
my_double.set_value(d + 1);
j_base = &my_double;
ASSERT_EQ(OB_SUCCESS, j_base->to_int(i));
ASSERT_EQ(LLONG_MAX, i);
// double -> int (3.14159)
my_double.set_value(3.14159);
j_base = &my_double;
ASSERT_EQ(OB_SUCCESS, j_base->to_int(i));
ASSERT_EQ(3, i);
}
TEST_F(TestJsonTree, test_json_cast_to_uint)
{
uint64_t ui = 0;
const int64_t MAX_BUF_SIZE = 256;
char buf[MAX_BUF_SIZE] = {0};
common::ObArenaAllocator alloc(ObModIds::TEST);
ObIJsonBase *j_base = NULL;
ObJsonUint my_uint(0);
ObJsonInt my_int(0);
ObJsonString my_str(buf, strlen(buf));
ObJsonBoolean my_bool(true);
ObJsonDouble my_double(0.0);
// uint -> uint (10)
j_base = &my_uint;
my_uint.set_value(10);
ASSERT_EQ(OB_SUCCESS, j_base->to_uint(ui));
ASSERT_EQ(10, ui);
// uint -> uint (ULLONG_MAX)
my_uint.set_value(ULLONG_MAX);
ASSERT_EQ(OB_SUCCESS, j_base->to_uint(ui));
ASSERT_EQ(ULLONG_MAX, ui);
// int -> uint (LLONG_MIN)
j_base = &my_int;
my_int.set_value(LLONG_MIN);
ASSERT_EQ(OB_SUCCESS, j_base->to_uint(ui));
ASSERT_EQ(LLONG_MAX + 1, ui);
// int -> uint (0)
my_int.set_value(0);
ASSERT_EQ(OB_SUCCESS, j_base->to_uint(ui));
ASSERT_EQ(0, ui);
// int -> uint (LLONG_MAX)
my_int.set_value(LLONG_MAX);
ASSERT_EQ(OB_SUCCESS, j_base->to_uint(ui));
ASSERT_EQ(LLONG_MAX, ui);
// string -> int ("abc")
j_base = &my_str;
ASSERT_EQ(strlen("abc"), sprintf(buf, "abc"));
my_str.set_value(buf, strlen(buf));
ASSERT_EQ(OB_ERR_TRUNCATED_WRONG_VALUE_FOR_FIELD, j_base->to_uint(ui));
// string -> uint ("LLONG_MIN")
j_base = &my_str;
int length = sprintf(buf, "%lld", LLONG_MIN);
my_str.set_value(buf, length);
ASSERT_EQ(OB_SUCCESS, j_base->to_uint(ui));
ASSERT_EQ(LLONG_MAX + 1, ui);
// string -> uint ("ULLONG_MAX")
j_base = &my_str;
length = sprintf(buf, "%llu", ULLONG_MAX);
my_str.set_value(buf, length);
ASSERT_EQ(OB_SUCCESS, j_base->to_uint(ui));
ASSERT_EQ(ULLONG_MAX, ui);
// string -> uint ("0")
j_base = &my_str;
length = sprintf(buf, "%d", 0);
my_str.set_value(buf, length);
ASSERT_EQ(OB_SUCCESS, j_base->to_uint(ui));
ASSERT_EQ(0, ui);
// boolean -> uint (true)
j_base = &my_bool;
my_bool.set_value(true);
ASSERT_EQ(OB_SUCCESS, j_base->to_uint(ui));
ASSERT_EQ(true, ui);
// boolean -> uint (false)
j_base = &my_bool;
my_bool.set_value(false);
ASSERT_EQ(OB_SUCCESS, j_base->to_uint(ui));
ASSERT_EQ(false, ui);
// number -> uint (LLONG_MIN)
char buf_alloc[MAX_BUF_SIZE];
ObDataBuffer allocator(buf_alloc, MAX_BUF_SIZE);
number::ObNumber num;
allocator.free();
length = sprintf(buf, "%lld", LLONG_MIN);
ASSERT_EQ(OB_SUCCESS, num.from(buf, allocator));
ObJsonDecimal my_num(num);
j_base = &my_num;
ASSERT_EQ(OB_SUCCESS, j_base->to_uint(ui));
ASSERT_EQ(LLONG_MAX + 1, ui);
// number -> uint (0)
allocator.free();
length = sprintf(buf, "%d", 0);
ASSERT_EQ(OB_SUCCESS, num.from(buf, allocator));
my_num.set_value(num);
j_base = &my_num;
ASSERT_EQ(OB_SUCCESS, j_base->to_uint(ui));
ASSERT_EQ(0, ui);
// number -> uint (ULLONG_MAX)
allocator.free();
length = sprintf(buf, "%llu", ULLONG_MAX);
ASSERT_EQ(OB_SUCCESS, num.from(buf, allocator));
my_num.set_value(num);
j_base = &my_num;
ASSERT_EQ(OB_SUCCESS, j_base->to_uint(ui));
ASSERT_EQ(ULLONG_MAX, ui);
// double -> uint (LLONG_MIN)
double d = static_cast<double>(LLONG_MIN);
my_double.set_value(d - 1);
j_base = &my_double;
ASSERT_EQ(OB_SUCCESS, j_base->to_uint(ui));
ASSERT_EQ(LLONG_MAX + 1, ui);
// double -> uint (ULLONG_MAX + 1)
d = static_cast<double>(ULLONG_MAX);
my_double.set_value(d + 1);
j_base = &my_double;
ASSERT_EQ(OB_SUCCESS, j_base->to_uint(ui));
ASSERT_EQ(ULLONG_MAX, ui);
// double -> uint (3.14159)
my_double.set_value(3.14159);
j_base = &my_double;
ASSERT_EQ(OB_SUCCESS, j_base->to_uint(ui));
ASSERT_EQ(3, ui);
}
TEST_F(TestJsonTree, test_json_cast_to_double)
{
double dou = 0.0;
const int64_t MAX_BUF_SIZE = 256;
char buf[MAX_BUF_SIZE] = {0};
common::ObArenaAllocator alloc(ObModIds::TEST);
ObIJsonBase *j_base = NULL;
ObJsonUint my_uint(0);
ObJsonInt my_int(0);
ObJsonString my_str(buf, strlen(buf));
ObJsonBoolean my_bool(true);
ObJsonDouble my_double(0.0);
// uint -> double (10)
j_base = &my_uint;
my_uint.set_value(10);
ASSERT_EQ(OB_SUCCESS, j_base->to_double(dou));
ASSERT_EQ(10, dou);
// uint -> double (ULLONG_MAX)
my_uint.set_value(ULLONG_MAX);
ASSERT_EQ(OB_SUCCESS, j_base->to_double(dou));
ASSERT_EQ(ULLONG_MAX, dou);
// int -> double (LLONG_MIN)
j_base = &my_int;
my_int.set_value(LLONG_MIN);
ASSERT_EQ(OB_SUCCESS, j_base->to_double(dou));
ASSERT_EQ(LLONG_MIN, dou);
// int -> double (0)
my_int.set_value(0);
ASSERT_EQ(OB_SUCCESS, j_base->to_double(dou));
ASSERT_EQ(0, dou);
// int -> double (LLONG_MAX)
my_int.set_value(LLONG_MAX);
ASSERT_EQ(OB_SUCCESS, j_base->to_double(dou));
ASSERT_EQ(LLONG_MAX, dou);
// string -> double ("abc")
j_base = &my_str;
ASSERT_EQ(strlen("abc"), sprintf(buf, "abc"));
my_str.set_value(buf, strlen(buf));
ASSERT_EQ(OB_ERR_TRUNCATED_WRONG_VALUE_FOR_FIELD, j_base->to_double(dou));
// string -> double ("LLONG_MIN")
j_base = &my_str;
int length = sprintf(buf, "%lld", LLONG_MIN);
my_str.set_value(buf, length);
ASSERT_EQ(OB_SUCCESS, j_base->to_double(dou));
ASSERT_EQ(LLONG_MIN, dou);
// string -> double ("ULLONG_MAX")
j_base = &my_str;
length = sprintf(buf, "%llu", ULLONG_MAX);
my_str.set_value(buf, length);
ASSERT_EQ(OB_SUCCESS, j_base->to_double(dou));
ASSERT_EQ(ULLONG_MAX, dou);
// string -> double ("0")
j_base = &my_str;
length = sprintf(buf, "%d", 0);
my_str.set_value(buf, length);
ASSERT_EQ(OB_SUCCESS, j_base->to_double(dou));
ASSERT_EQ(0, dou);
// boolean -> double (true)
j_base = &my_bool;
my_bool.set_value(true);
ASSERT_EQ(OB_SUCCESS, j_base->to_double(dou));
ASSERT_EQ(true, dou);
// boolean -> double (false)
j_base = &my_bool;
my_bool.set_value(false);
ASSERT_EQ(OB_SUCCESS, j_base->to_double(dou));
ASSERT_EQ(false, dou);
// number -> double (LLONG_MIN)
char buf_alloc[MAX_BUF_SIZE];
ObDataBuffer allocator(buf_alloc, MAX_BUF_SIZE);
number::ObNumber num;
allocator.free();
length = sprintf(buf, "%lld", LLONG_MIN);
ASSERT_EQ(OB_SUCCESS, num.from(buf, allocator));
ObJsonDecimal my_num(num);
j_base = &my_num;
ASSERT_EQ(OB_SUCCESS, j_base->to_double(dou));
ASSERT_EQ(LLONG_MAX + 1, dou);
// number -> double (0)
allocator.free();
length = sprintf(buf, "%d", 0);
ASSERT_EQ(OB_SUCCESS, num.from(buf, allocator));
my_num.set_value(num);
j_base = &my_num;
ASSERT_EQ(OB_SUCCESS, j_base->to_double(dou));
ASSERT_EQ(0, dou);
// number -> double (ULLONG_MAX)
allocator.free();
length = sprintf(buf, "%llu", ULLONG_MAX);
ASSERT_EQ(OB_SUCCESS, num.from(buf, allocator));
my_num.set_value(num);
j_base = &my_num;
ASSERT_EQ(OB_SUCCESS, j_base->to_double(dou));
ASSERT_EQ(ULLONG_MAX, dou);
// double -> double (DBL_MIN)
my_double.set_value(DBL_MIN);
j_base = &my_double;
ASSERT_EQ(OB_SUCCESS, j_base->to_double(dou));
ASSERT_EQ(DBL_MIN, dou);
// double -> double (DBL_MAX)
my_double.set_value(DBL_MAX);
j_base = &my_double;
ASSERT_EQ(OB_SUCCESS, j_base->to_double(dou));
ASSERT_EQ(DBL_MAX, dou);
// double -> double (3.14159)
my_double.set_value(3.14159);
j_base = &my_double;
ASSERT_EQ(OB_SUCCESS, j_base->to_double(dou));
ASSERT_EQ(3.14159, dou);
}
TEST_F(TestJsonTree, test_json_cast_to_number)
{
int64_t to_int = 0;
int64_t pos = 0;
number::ObNumber nmb;
const int64_t MAX_BUF_SIZE = 512;
char buf[MAX_BUF_SIZE] = {0};
common::ObArenaAllocator alloc(ObModIds::TEST);
ObIJsonBase *j_base = NULL;
ObJsonUint my_uint(0);
ObJsonInt my_int(0);
ObJsonString my_str(buf, strlen(buf));
ObJsonBoolean my_bool(true);
ObJsonDouble my_double(0.0);
// number -> number (LLONG_MIN)
char buf_alloc[MAX_BUF_SIZE];
ObDataBuffer allocator(buf_alloc, MAX_BUF_SIZE);
number::ObNumber num;
allocator.free();
int length = sprintf(buf, "%lld", LLONG_MIN);
ASSERT_EQ(OB_SUCCESS, num.from(buf, allocator));
ObJsonDecimal my_num(num);
j_base = &my_num;
ASSERT_EQ(OB_SUCCESS, j_base->to_number(&alloc, nmb));
ASSERT_EQ(OB_SUCCESS, nmb.cast_to_int64(to_int));
ASSERT_EQ(LLONG_MIN, to_int);
// number -> number (0)
allocator.free();
length = sprintf(buf, "%d", 0);
ASSERT_EQ(OB_SUCCESS, num.from(buf, allocator));
my_num.set_value(num);
j_base = &my_num;
ASSERT_EQ(OB_SUCCESS, j_base->to_number(&alloc, nmb));
ASSERT_EQ(OB_SUCCESS, nmb.cast_to_int64(to_int));
ASSERT_EQ(0, to_int);
// number -> number (ULLONG_MAX)
allocator.free();
length = sprintf(buf, "%llu", ULLONG_MAX);
ASSERT_EQ(OB_SUCCESS, num.from(buf, allocator));
my_num.set_value(num);
j_base = &my_num;
ASSERT_EQ(OB_SUCCESS, j_base->to_number(&alloc, nmb));
ASSERT_EQ(0, nmb.compare(num));
// uint -> number (10)
j_base = &my_uint;
my_uint.set_value(10);
ASSERT_EQ(OB_SUCCESS, j_base->to_number(&alloc, nmb));
ASSERT_EQ(OB_SUCCESS, nmb.cast_to_int64(to_int));
ASSERT_EQ(10, to_int);
// uint -> number (ULLONG_MAX)
my_uint.set_value(ULLONG_MAX);
ASSERT_EQ(OB_SUCCESS, j_base->to_number(&alloc, nmb));
pos = 0;
ASSERT_EQ(OB_SUCCESS, nmb.format(buf, sizeof(buf), pos, -1));
char *endptr = NULL;
int err = 0;
double dou = ObCharset::strntod(buf, pos, &endptr, &err);
ASSERT_EQ(ULLONG_MAX, dou);
// int -> number (LLONG_MIN)
j_base = &my_int;
my_int.set_value(LLONG_MIN);
ASSERT_EQ(OB_SUCCESS, j_base->to_number(&alloc, nmb));
ASSERT_EQ(OB_SUCCESS, nmb.cast_to_int64(to_int));
ASSERT_EQ(LLONG_MIN, to_int);
// int -> number (0)
my_int.set_value(0);
ASSERT_EQ(OB_SUCCESS, j_base->to_number(&alloc, nmb));
ASSERT_EQ(OB_SUCCESS, nmb.cast_to_int64(to_int));
ASSERT_EQ(0, to_int);
// int -> number (LLONG_MAX)
my_int.set_value(LLONG_MAX);
ASSERT_EQ(OB_SUCCESS, j_base->to_number(&alloc, nmb));
ASSERT_EQ(OB_SUCCESS, nmb.cast_to_int64(to_int));
ASSERT_EQ(LLONG_MAX, to_int);
// string -> number ("abc")
MEMSET(buf, 0, sizeof(buf));
j_base = &my_str;
ASSERT_EQ(strlen("abc"), sprintf(buf, "abc"));
my_str.set_value(buf, strlen(buf));
ASSERT_EQ(OB_INVALID_NUMERIC, j_base->to_number(&alloc, nmb));
// string -> number ("LLONG_MIN")
MEMSET(buf, 0, sizeof(buf));
j_base = &my_str;
length = sprintf(buf, "%lld", LLONG_MIN);
my_str.set_value(buf, length);
ASSERT_EQ(OB_SUCCESS, j_base->to_number(&alloc, nmb));
ASSERT_EQ(OB_SUCCESS, nmb.cast_to_int64(to_int));
ASSERT_EQ(LLONG_MIN, to_int);
// string -> number ("ULLONG_MAX")
MEMSET(buf, 0, sizeof(buf));
j_base = &my_str;
length = sprintf(buf, "%llu", ULLONG_MAX);
my_str.set_value(buf, length);
ASSERT_EQ(OB_SUCCESS, j_base->to_number(&alloc, nmb));
pos = 0;
ASSERT_EQ(OB_SUCCESS, nmb.format(buf, sizeof(buf), pos, -1));
uint64_t ui = ObCharset::strntoullrnd(buf, sizeof(buf), true, &endptr, &err);
ASSERT_EQ(ULLONG_MAX, ui);
// string -> number ("0")
MEMSET(buf, 0, sizeof(buf));
j_base = &my_str;
length = sprintf(buf, "%d", 0);
my_str.set_value(buf, length);
ASSERT_EQ(OB_SUCCESS, j_base->to_number(&alloc, nmb));
ASSERT_EQ(OB_SUCCESS, nmb.cast_to_int64(to_int));
ASSERT_EQ(0, to_int);
// boolean -> number (true)
j_base = &my_bool;
my_bool.set_value(true);
ASSERT_EQ(OB_SUCCESS, j_base->to_number(&alloc, nmb));
ASSERT_EQ(OB_SUCCESS, nmb.cast_to_int64(to_int));
ASSERT_EQ(true, to_int);
// boolean -> number (false)
j_base = &my_bool;
my_bool.set_value(false);
ASSERT_EQ(OB_SUCCESS, j_base->to_number(&alloc, nmb));
ASSERT_EQ(OB_SUCCESS, nmb.cast_to_int64(to_int));
ASSERT_EQ(false, to_int);
// double -> number (-123.45678)
MEMSET(buf, 0, sizeof(buf));
my_double.set_value(-123.45678);
j_base = &my_double;
ASSERT_EQ(OB_SUCCESS, j_base->to_number(&alloc, nmb));
pos = 0;
ASSERT_EQ(OB_SUCCESS, nmb.format(buf, sizeof(buf), pos, -1));
dou = ObCharset::strntod(buf, pos, &endptr, &err);
ASSERT_EQ(-123.45678, dou);
// double -> number (123.45678)
MEMSET(buf, 0, sizeof(buf));
my_double.set_value(123.45678);
j_base = &my_double;
ASSERT_EQ(OB_SUCCESS, j_base->to_number(&alloc, nmb));
pos = 0;
ASSERT_EQ(OB_SUCCESS, nmb.format(buf, sizeof(buf), pos, -1));
dou = ObCharset::strntod(buf, pos, &endptr, &err);
ASSERT_EQ(123.45678, dou);
// double -> number (DBL_MIN)
my_double.set_value(DBL_MIN);
j_base = &my_double;
ASSERT_EQ(OB_SUCCESS, j_base->to_number(&alloc, nmb));
// double -> number (DBL_MAN)
my_double.set_value(DBL_MAX);
j_base = &my_double;
ASSERT_EQ(OB_NUMERIC_OVERFLOW, j_base->to_number(&alloc, nmb));
}
static bool ob_time_eq(const ObTime& ans, int64_t year, int64_t month, int64_t day,
int64_t hour, int64_t minute, int64_t second, int64_t usecond)
{
bool ret = (ans.parts_[DT_YEAR] == year || -1 == year) && (ans.parts_[DT_MON] == month || -1 == month) &&
(ans.parts_[DT_MDAY] == day || -1 == day) && (ans.parts_[DT_HOUR] == hour || -1 == hour) &&
(ans.parts_[DT_MIN] == minute || -1 == minute) && (ans.parts_[DT_SEC] == second || -1 == second) &&
(ans.parts_[DT_USEC] == usecond || -1 == usecond);
if (!ret) {
printf("%04u-%02u-%02u %02u:%02u:%02u.%06u\n",
ans.parts_[DT_YEAR],
ans.parts_[DT_MON],
ans.parts_[DT_MDAY],
ans.parts_[DT_HOUR],
ans.parts_[DT_MIN],
ans.parts_[DT_SEC],
ans.parts_[DT_USEC]);
}
return ret;
}
TEST_F(TestJsonTree, test_json_cast_to_datetime)
{
common::ObArenaAllocator alloc(ObModIds::TEST);
ObIJsonBase *j_base = NULL;
int64_t datetime = 0;
int32_t date = 0;
// datetime -> datetime
ObTime ob_time1;
ASSERT_EQ(OB_SUCCESS, ObTimeConverter::datetime_to_ob_time(1429089727 * USECS_PER_SEC, NULL, ob_time1));
ASSERT_TRUE(ob_time_eq(ob_time1, 2015, 4, 15, 9, 22, 7, 0));
ObJsonDatetime j_datetime(ob_time1, ObDateTimeType);
j_base = &j_datetime;
ASSERT_EQ(OB_SUCCESS, j_base->to_datetime(datetime));
ASSERT_EQ(1429089727 * USECS_PER_SEC, datetime);
// date -> datetime
ObTime ob_time2;
ASSERT_EQ(OB_SUCCESS, ObTimeConverter::date_to_ob_time(0, ob_time2));
EXPECT_TRUE(ob_time_eq(ob_time2, 1970, 1, 1, 0, 0, 0, 0));
j_datetime.set_value(ob_time2);
j_datetime.set_field_type(ObDateType);
j_base = &j_datetime;
ASSERT_EQ(OB_SUCCESS, j_base->to_datetime(datetime));
ASSERT_EQ(0, datetime);
ObTime ob_time3;
ASSERT_EQ(OB_SUCCESS, ObTimeConverter::date_to_ob_time(16540, ob_time3));
EXPECT_TRUE(ob_time_eq(ob_time3, 2015, 4, 15, 0, 0, 0, 0));
j_datetime.set_value(ob_time3);
j_base = &j_datetime;
ASSERT_EQ(OB_SUCCESS, j_base->to_datetime(datetime));
ASSERT_EQ(OB_SUCCESS, ObTimeConverter::datetime_to_date(datetime, NULL, date));
ASSERT_EQ(16540, date);
// timestamp -> datetime
ObTime ob_time4;
const int64_t MAX_BUF_SIZE = 256;
char buf[MAX_BUF_SIZE] = {0};
strcpy(buf, "2015-4-15 11:12:00.1234567 -07:00");
ObString str;
str.assign(buf, static_cast<int32_t>(strlen(buf)));
ObTimeZoneInfo tz_info;
ObTimeConvertCtx cvrt_ctx(&tz_info, false);
cvrt_ctx.oracle_nls_format_ = ObTimeConverter::COMPAT_OLD_NLS_TIMESTAMP_TZ_FORMAT;
ObOTimestampData ot_data;
int16_t scale = 0;
ASSERT_EQ(OB_SUCCESS, ObTimeConverter::str_to_otimestamp(str, cvrt_ctx, ObTimestampTZType, ot_data, scale));
ASSERT_EQ(OB_SUCCESS, ObTimeConverter::otimestamp_to_ob_time(ObTimestampNanoType, ot_data, NULL, ob_time4));
j_datetime.set_value(ob_time4);
j_datetime.set_field_type(ObTimestampType);
j_base = &j_datetime;
ASSERT_EQ(OB_SUCCESS, j_base->to_datetime(datetime));
ASSERT_EQ(OB_SUCCESS, ObTimeConverter::datetime_to_date(datetime, NULL, date));
ASSERT_EQ(16540, date);
// string -> datetime
MEMSET(buf, 0, sizeof(buf));
strcpy(buf, "2015-4-15 11:12:00.1234567");
ObJsonString j_str(buf, strlen(buf));
j_base = &j_str;
ASSERT_EQ(OB_SUCCESS, j_base->to_datetime(datetime));
ASSERT_EQ(OB_SUCCESS, ObTimeConverter::datetime_to_date(datetime, NULL, date));
ASSERT_EQ(16540, date);
}
TEST_F(TestJsonTree, test_json_cast_to_date)
{
common::ObArenaAllocator alloc(ObModIds::TEST);
ObIJsonBase *j_base = NULL;
int32_t date = 0;
// datetime -> date
ObTime ob_time1;
ASSERT_EQ(OB_SUCCESS, ObTimeConverter::datetime_to_ob_time(1429089727 * USECS_PER_SEC, NULL, ob_time1));
ASSERT_TRUE(ob_time_eq(ob_time1, 2015, 4, 15, 9, 22, 7, 0));
ObJsonDatetime j_date(ob_time1, ObDateTimeType);
j_base = &j_date;
ASSERT_EQ(OB_SUCCESS, j_base->to_date(date));
ASSERT_EQ(16540, date);
// date -> date
ObTime ob_time2;
ASSERT_EQ(OB_SUCCESS, ObTimeConverter::date_to_ob_time(0, ob_time2));
EXPECT_TRUE(ob_time_eq(ob_time2, 1970, 1, 1, 0, 0, 0, 0));
j_date.set_value(ob_time2);
j_date.set_field_type(ObDateType);
j_base = &j_date;
ASSERT_EQ(OB_SUCCESS, j_base->to_date(date));
ASSERT_EQ(0, date);
ObTime ob_time3;
ASSERT_EQ(OB_SUCCESS, ObTimeConverter::date_to_ob_time(16540, ob_time3));
EXPECT_TRUE(ob_time_eq(ob_time3, 2015, 4, 15, 0, 0, 0, 0));
j_date.set_value(ob_time3);
j_base = &j_date;
ASSERT_EQ(OB_SUCCESS, j_base->to_date(date));
ASSERT_EQ(16540, date);
// timestamp -> date
ObTime ob_time4;
const int64_t MAX_BUF_SIZE = 256;
char buf[MAX_BUF_SIZE] = {0};
strcpy(buf, "2015-4-15 11:12:00.1234567 -07:00");
ObString str;
str.assign(buf, static_cast<int32_t>(strlen(buf)));
ObTimeZoneInfo tz_info;
ObTimeConvertCtx cvrt_ctx(&tz_info, false);
cvrt_ctx.oracle_nls_format_ = ObTimeConverter::COMPAT_OLD_NLS_TIMESTAMP_TZ_FORMAT;
ObOTimestampData ot_data;
int16_t scale = 0;
ASSERT_EQ(OB_SUCCESS, ObTimeConverter::str_to_otimestamp(str, cvrt_ctx, ObTimestampTZType, ot_data, scale));
ASSERT_EQ(OB_SUCCESS, ObTimeConverter::otimestamp_to_ob_time(ObTimestampNanoType, ot_data, NULL, ob_time4));
j_date.set_value(ob_time4);
j_date.set_field_type(ObTimestampType);
j_base = &j_date;
ASSERT_EQ(OB_SUCCESS, j_base->to_date(date));
ASSERT_EQ(16540, date);
// string -> date
MEMSET(buf, 0, sizeof(buf));
strcpy(buf, "2015-4-15 11:12:00.1234567");
ObJsonString j_str(buf, strlen(buf));
j_base = &j_str;
ASSERT_EQ(OB_SUCCESS, j_base->to_date(date));
ASSERT_EQ(16540, date);
}
TEST_F(TestJsonTree, test_json_cast_to_time)
{
common::ObArenaAllocator alloc(ObModIds::TEST);
ObIJsonBase *j_base = NULL;
int64_t time = 0;
// time -> time
ObTime ob_time1;
ASSERT_EQ(OB_SUCCESS, ObTimeConverter::time_to_ob_time(43509 * static_cast<int64_t>(USECS_PER_SEC) + 1234, ob_time1));
ASSERT_TRUE(ob_time_eq(ob_time1, 0, 0, 0, 12, 5, 9, 1234));
ObJsonDatetime j_time(ob_time1, ObTimeType);
j_base = &j_time;
ASSERT_EQ(OB_SUCCESS, j_base->to_time(time));
ASSERT_EQ(43509 * static_cast<int64_t>(USECS_PER_SEC) + 1234, time);
// string -> time
const int64_t MAX_BUF_SIZE = 256;
char buf[MAX_BUF_SIZE] = {0};
strcpy(buf, "12:05:09.001234");
ObJsonString j_str(buf, strlen(buf));
j_base = &j_str;
ASSERT_EQ(OB_SUCCESS, j_base->to_time(time));
ASSERT_EQ(43509 * static_cast<int64_t>(USECS_PER_SEC) + 1234, time);
}
TEST_F(TestJsonTree, test_json_cast_to_bit)
{
uint64_t bit = 0;
const int64_t MAX_BUF_SIZE = 256;
char buf[MAX_BUF_SIZE] = {0};
common::ObArenaAllocator alloc(ObModIds::TEST);
ObIJsonBase *j_base = NULL;
ObJsonUint my_uint(0);
ObJsonInt my_int(0);
ObJsonString my_str(buf, strlen(buf));
ObJsonBoolean my_bool(true);
ObJsonDouble my_double(0.0);
// uint -> bit (10)
j_base = &my_uint;
my_uint.set_value(10);
ASSERT_EQ(OB_SUCCESS, j_base->to_bit(bit));
ASSERT_EQ(10, bit);
// uint -> bit (ULLONG_MAX)
my_uint.set_value(ULLONG_MAX);
ASSERT_EQ(OB_SUCCESS, j_base->to_bit(bit));
ASSERT_EQ(ULLONG_MAX, bit);
// int -> bit (LLONG_MIN)
j_base = &my_int;
my_int.set_value(LLONG_MIN);
ASSERT_EQ(OB_SUCCESS, j_base->to_bit(bit));
ASSERT_EQ(LLONG_MAX + 1, bit);
// int -> bit (0)
my_int.set_value(0);
ASSERT_EQ(OB_SUCCESS, j_base->to_bit(bit));
ASSERT_EQ(0, bit);
// int -> bit (LLONG_MAX)
my_int.set_value(LLONG_MAX);
ASSERT_EQ(OB_SUCCESS, j_base->to_bit(bit));
ASSERT_EQ(LLONG_MAX, bit);
// string -> bit ("a")
j_base = &my_str;
ASSERT_EQ(strlen("a"), sprintf(buf, "a"));
my_str.set_value(buf, strlen(buf));
ASSERT_EQ(OB_SUCCESS, j_base->to_bit(bit));
ASSERT_EQ(97, bit);
// string -> bit ("LLONG_MIN")
j_base = &my_str;
int length = sprintf(buf, "%lld", LLONG_MIN);
my_str.set_value(buf, length);
ASSERT_EQ(OB_ERR_DATA_TOO_LONG, j_base->to_bit(bit));
// string -> bit ("ULLONG_MAX")
j_base = &my_str;
length = sprintf(buf, "%llu", ULLONG_MAX);
my_str.set_value(buf, length);
ASSERT_EQ(OB_ERR_DATA_TOO_LONG, j_base->to_bit(bit));
// string -> bit ("0")
j_base = &my_str;
length = sprintf(buf, "%d", 0);
my_str.set_value(buf, length);
ASSERT_EQ(OB_SUCCESS, j_base->to_bit(bit));
ASSERT_EQ(48, bit);
// boolean -> bit (true)
j_base = &my_bool;
my_bool.set_value(true);
ASSERT_EQ(OB_SUCCESS, j_base->to_bit(bit));
ASSERT_EQ(true, bit);
// boolean -> bit (false)
j_base = &my_bool;
my_bool.set_value(false);
ASSERT_EQ(OB_SUCCESS, j_base->to_bit(bit));
ASSERT_EQ(false, bit);
// number -> bit (LLONG_MIN)
char buf_alloc[MAX_BUF_SIZE];
ObDataBuffer allocator(buf_alloc, MAX_BUF_SIZE);
number::ObNumber num;
allocator.free();
length = sprintf(buf, "%lld", LLONG_MIN);
ASSERT_EQ(OB_SUCCESS, num.from(buf, allocator));
ObJsonDecimal my_num(num);
j_base = &my_num;
ASSERT_EQ(OB_SUCCESS, j_base->to_bit(bit));
ASSERT_EQ(LLONG_MAX + 1, bit);
// number -> bit (0)
allocator.free();
length = sprintf(buf, "%d", 0);
ASSERT_EQ(OB_SUCCESS, num.from(buf, allocator));
my_num.set_value(num);
j_base = &my_num;
ASSERT_EQ(OB_SUCCESS, j_base->to_bit(bit));
ASSERT_EQ(0, bit);
// number -> bit (ULLONG_MAX)
allocator.free();
length = sprintf(buf, "%llu", ULLONG_MAX);
ASSERT_EQ(OB_SUCCESS, num.from(buf, allocator));
my_num.set_value(num);
j_base = &my_num;
ASSERT_EQ(OB_SUCCESS, j_base->to_bit(bit));
ASSERT_EQ(ULLONG_MAX, bit);
// double -> bit (LLONG_MIN)
double d = static_cast<double>(LLONG_MIN);
my_double.set_value(d - 1);
j_base = &my_double;
ASSERT_EQ(OB_SUCCESS, j_base->to_bit(bit));
ASSERT_EQ(LLONG_MAX + 1, bit);
// double -> bit (ULLONG_MAX + 1)
d = static_cast<double>(ULLONG_MAX);
my_double.set_value(d + 1);
j_base = &my_double;
ASSERT_EQ(OB_SUCCESS, j_base->to_bit(bit));
ASSERT_EQ(ULLONG_MAX, bit);
// double -> bit (3.14159)
my_double.set_value(3.14159);
j_base = &my_double;
ASSERT_EQ(OB_SUCCESS, j_base->to_bit(bit));
ASSERT_EQ(3, bit);
// datetime -> bit
ObTime ob_time1;
ASSERT_EQ(OB_SUCCESS, ObTimeConverter::datetime_to_ob_time(1429089727 * USECS_PER_SEC, NULL, ob_time1));
ASSERT_TRUE(ob_time_eq(ob_time1, 2015, 4, 15, 9, 22, 7, 0));
ObJsonDatetime j_datetime(ob_time1, ObDateTimeType);
j_base = &j_datetime;
ASSERT_EQ(OB_ERR_DATA_TOO_LONG, j_base->to_bit(bit));
// date -> bit
ObTime ob_time2;
ASSERT_EQ(OB_SUCCESS, ObTimeConverter::date_to_ob_time(0, ob_time2));
EXPECT_TRUE(ob_time_eq(ob_time2, 1970, 1, 1, 0, 0, 0, 0));
ObJsonDatetime j_date(ob_time2, ObDateType);
j_base = &j_date;
ASSERT_EQ(OB_ERR_DATA_TOO_LONG, j_base->to_bit(bit));
ObTime ob_time3;
ASSERT_EQ(OB_SUCCESS, ObTimeConverter::date_to_ob_time(16540, ob_time3));
EXPECT_TRUE(ob_time_eq(ob_time3, 2015, 4, 15, 0, 0, 0, 0));
j_date.set_value(ob_time3);
j_base = &j_date;
ASSERT_EQ(OB_ERR_DATA_TOO_LONG, j_base->to_bit(bit));
// timestamp -> bit
MEMSET(buf, 0, sizeof(buf));
ObTime ob_time4;
strcpy(buf, "2015-4-15 11:12:00.1234567 -07:00");
ObString str;
str.assign(buf, static_cast<int32_t>(strlen(buf)));
ObTimeZoneInfo tz_info;
ObTimeConvertCtx cvrt_ctx(&tz_info, false);
cvrt_ctx.oracle_nls_format_ = ObTimeConverter::COMPAT_OLD_NLS_TIMESTAMP_TZ_FORMAT;
ObOTimestampData ot_data;
int16_t scale = 0;
ASSERT_EQ(OB_SUCCESS, ObTimeConverter::str_to_otimestamp(str, cvrt_ctx, ObTimestampTZType, ot_data, scale));
ASSERT_EQ(OB_SUCCESS, ObTimeConverter::otimestamp_to_ob_time(ObTimestampNanoType, ot_data, NULL, ob_time4));
ObJsonDatetime j_timestamp(ob_time4, ObTimestampType);
j_base = &j_timestamp;
ASSERT_EQ(OB_SUCCESS, j_base->to_bit(bit));
ASSERT_EQ(0, bit);
// time -> bit
ObTime ob_time5;
ASSERT_EQ(OB_SUCCESS, ObTimeConverter::time_to_ob_time(43509 * static_cast<int64_t>(USECS_PER_SEC) + 1234, ob_time5));
ASSERT_TRUE(ob_time_eq(ob_time5, 0, 0, 0, 12, 5, 9, 1234));
ObJsonDatetime j_time(ob_time5, ObTimeType);
j_base = &j_time;
ASSERT_EQ(OB_SUCCESS, j_base->to_bit(bit));
ASSERT_EQ(3544959835419848761, bit);
}
TEST_F(TestJsonTree, test_get_serialize_size)
{
ObArenaAllocator allocator(ObModIds::TEST);
const char *syntaxerr = NULL;
uint64_t err_offset = 0;
uint64_t serialize_size = 0;
ObJsonNode *j_node = NULL;
// object
common::ObString j_obj_text("{ \"k1\" : 1, \"k2\" : \"a\" }");
ASSERT_EQ(OB_SUCCESS, ObJsonParser::parse_json_text(&allocator, j_obj_text.ptr(), j_obj_text.length(),
syntaxerr, &err_offset, j_node));
serialize_size = j_node->get_serialize_size();
cout << "============ object serialize_size:" << serialize_size << endl;
ASSERT_EQ(19, serialize_size);
// array
common::ObString j_arr_text("[1, \"abc\", 1.2, null, 0, [123, 1, 2]]");
ASSERT_EQ(OB_SUCCESS, ObJsonParser::parse_json_text(&allocator, j_arr_text.ptr(), j_arr_text.length(),
syntaxerr, &err_offset, j_node));
serialize_size = j_node->get_serialize_size();
cout << "============ array serialize_size:" << serialize_size << endl;
ASSERT_EQ(44, serialize_size);
// int
ObJsonInt j_int(1);
j_node = &j_int;
serialize_size = j_node->get_serialize_size();
cout << "============ int(1) serialize_size:" << serialize_size << endl;
ASSERT_EQ(1, serialize_size);
j_int.set_value(LLONG_MAX);
serialize_size = j_node->get_serialize_size();
cout << "============ int(LLONG_MAX) serialize_size:" << serialize_size << endl;
ASSERT_EQ(9, serialize_size);
j_int.set_value(LLONG_MIN);
serialize_size = j_node->get_serialize_size();
cout << "============ int(LLONG_MAX) serialize_size:" << serialize_size << endl;
ASSERT_EQ(10, serialize_size);
// uint
ObJsonUint j_uint(1);
j_node = &j_uint;
serialize_size = j_node->get_serialize_size();
cout << "============ uint(1) serialize_size:" << serialize_size << endl;
ASSERT_EQ(1, serialize_size);
j_uint.set_value(ULLONG_MAX);
serialize_size = j_node->get_serialize_size();
cout << "============ uint(ULLONG_MAX) serialize_size:" << serialize_size << endl;
ASSERT_EQ(10, serialize_size);
// null
ObJsonNull j_null;
j_node = &j_null;
serialize_size = j_node->get_serialize_size();
cout << "============ null serialize_size:" << serialize_size << endl;
ASSERT_EQ(1, serialize_size);
// decimal
const int64_t MAX_BUF_SIZE = 512;
char buf[MAX_BUF_SIZE] = {0};
number::ObNumber num;
sprintf(buf, "%lld", LLONG_MIN);
ASSERT_EQ(OB_SUCCESS, num.from(buf, allocator));
ObJsonDecimal j_dec(num);
j_node = &j_dec;
serialize_size = j_node->get_serialize_size();
cout << "============ decimal(LLONG_MIN) serialize_size:" << serialize_size << endl;
ASSERT_EQ(20, serialize_size);
MEMSET(buf, 0, sizeof(buf));
sprintf(buf, "%d", 1);
ASSERT_EQ(OB_SUCCESS, num.from(buf, allocator));
j_dec.set_value(num);
serialize_size = j_node->get_serialize_size();
cout << "============ decimal(1) serialize_size:" << serialize_size << endl;
ASSERT_EQ(12, serialize_size);
MEMSET(buf, 0, sizeof(buf));
sprintf(buf, "%lld", ULLONG_MAX);
ASSERT_EQ(OB_SUCCESS, num.from(buf, allocator));
j_dec.set_value(num);
serialize_size = j_node->get_serialize_size();
cout << "============ decimal(ULLONG_MAX) serialize_size:" << serialize_size << endl;
ASSERT_EQ(12, serialize_size);
// double
ObJsonDouble j_double(1.0);
j_node = &j_double;
serialize_size = j_node->get_serialize_size();
cout << "============ double(1.0) serialize_size:" << serialize_size << endl;
ASSERT_EQ(8, serialize_size);
j_double.set_value(DBL_MAX);
serialize_size = j_node->get_serialize_size();
cout << "============ double(DBL_MAX) serialize_size:" << serialize_size << endl;
ASSERT_EQ(8, serialize_size);
j_double.set_value(DBL_MIN);
serialize_size = j_node->get_serialize_size();
cout << "============ double(DBL_MIN) serialize_size:" << serialize_size << endl;
ASSERT_EQ(8, serialize_size);
// string
ObJsonString j_str("a", strlen("a"));
j_node = &j_str;
serialize_size = j_node->get_serialize_size();
cout << "============ string(a) serialize_size:" << serialize_size << endl;
ASSERT_EQ(2, serialize_size);
j_str.set_value("abcdefghijklmnobqrst", strlen("abcdefghijklmnobqrst"));
serialize_size = j_node->get_serialize_size();
cout << "============ string(abcdefghijklmnobqrst) serialize_size:" << serialize_size << endl;
ASSERT_EQ(21, serialize_size);
// bool
ObJsonBoolean j_bool(true);
j_node = &j_bool;
serialize_size = j_node->get_serialize_size();
cout << "============ bool(true) serialize_size:" << serialize_size << endl;
ASSERT_EQ(1, serialize_size);
j_bool.set_value(false);
serialize_size = j_node->get_serialize_size();
cout << "============ bool(false) serialize_size:" << serialize_size << endl;
ASSERT_EQ(1, serialize_size);
// date
ObTime ob_time1;
ASSERT_EQ(OB_SUCCESS, ObTimeConverter::date_to_ob_time(16540, ob_time1));
EXPECT_TRUE(ob_time_eq(ob_time1, 2015, 4, 15, 0, 0, 0, 0));
ObJsonDatetime j_date(ob_time1, ObDateType);
j_node = &j_date;
serialize_size = j_node->get_serialize_size();
cout << "============ date(16540) serialize_size:" << serialize_size << endl;
ASSERT_EQ(4, serialize_size);
// time
ObTime ob_time2;
ASSERT_EQ(OB_SUCCESS, ObTimeConverter::time_to_ob_time(43509 * static_cast<int64_t>(USECS_PER_SEC) + 1234, ob_time2));
ASSERT_TRUE(ob_time_eq(ob_time2, 0, 0, 0, 12, 5, 9, 1234));
ObJsonDatetime j_time(ob_time2, ObTimeType);
j_node = &j_time;
serialize_size = j_node->get_serialize_size();
cout << "============ time(43509 * static_cast<int64_t>(USECS_PER_SEC) + 1234) serialize_size:" << serialize_size << endl;
ASSERT_EQ(8, serialize_size);
// datetime
ObTime ob_time3;
ASSERT_EQ(OB_SUCCESS, ObTimeConverter::datetime_to_ob_time(1429089727 * USECS_PER_SEC, NULL, ob_time3));
ASSERT_TRUE(ob_time_eq(ob_time3, 2015, 4, 15, 9, 22, 7, 0));
ObJsonDatetime j_datetime(ob_time3, ObDateTimeType);
j_node = &j_datetime;
serialize_size = j_node->get_serialize_size();
cout << "============ datetime(1429089727 * USECS_PER_SEC) serialize_size:" << serialize_size << endl;
ASSERT_EQ(8, serialize_size);
// opaque
ObString str("10101011010101010110101010101");
ObJsonOpaque j_opaque(str, ObBitType);
j_node = &j_opaque;
serialize_size = j_node->get_serialize_size();
cout << "============ opaque(10101011010101010110101010101) serialize_size:" << serialize_size << endl;
ASSERT_EQ(39, serialize_size);
}
TEST_F(TestJsonTree, test_get_serialize_size_array_one_depth)
{
ObArenaAllocator allocator(ObModIds::TEST);
uint64_t serialize_size = 0;
ObIJsonBase *j_base = NULL;
void *buf = NULL;
common::ObString json_val("vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv");
// array
ObJsonArray j_arr(&allocator);
j_base = &j_arr;
int64 repeat_num = 10000;
int64_t times = 0;
uint64_t last_size = 0;
uint64_t new_size = 0;
while(times < repeat_num) {
buf = allocator.alloc(sizeof(ObJsonString));
ObJsonString *j_str = (ObJsonString *)new(buf) ObJsonString(json_val.ptr(), json_val.length());
ObIJsonBase *tmp_base = j_str;
ASSERT_EQ(OB_SUCCESS, j_base->array_append(tmp_base));
new_size = j_arr.get_serialize_size();
ASSERT_GT(new_size, last_size);
last_size = new_size;
times++;
}
}
TEST_F(TestJsonTree, test_get_serialize_size_array_multi_depth)
{
ObArenaAllocator allocator(ObModIds::TEST);
uint64_t serialize_size = 0;
ObIJsonBase *j_base = NULL;
void *buf = NULL;
common::ObString json_val("vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv");
// array
ObJsonArray j_arr_root(&allocator);
j_base = &j_arr_root;
int64 repeat_num = 10000;
int64_t times = 0;
uint64_t last_size = 0;
uint64_t new_size = 0;
ObIJsonBase *last_j_base = j_base;
while(times < repeat_num) {
// new_array
buf = allocator.alloc(sizeof(ObJsonArray));
ObJsonArray *j_arr = (ObJsonArray *)new(buf) ObJsonArray(&allocator);
ObIJsonBase *tmp_arr_base = j_arr;
// new_string
buf = allocator.alloc(sizeof(ObJsonString));
ObJsonString *j_str = (ObJsonString *)new(buf) ObJsonString(json_val.ptr(), json_val.length());
ObIJsonBase *tmp_str_base = j_str;
ASSERT_EQ(OB_SUCCESS, tmp_arr_base->array_append(tmp_str_base)); // [j_str]
ASSERT_EQ(OB_SUCCESS, last_j_base->array_append(tmp_arr_base));
last_j_base = tmp_arr_base;
new_size = j_arr_root.get_serialize_size();
// cout << "root_serialize_size:" << new_size << endl;
ASSERT_GT(new_size, last_size);
last_size = new_size;
times++;
}
}
TEST_F(TestJsonTree, test_get_serialize_size_object_one_depth)
{
ObArenaAllocator allocator(ObModIds::TEST);
uint64_t serialize_size = 0;
ObIJsonBase *j_base = NULL;
char *buf = NULL;
char key_str[10] = "key";
// object
ObJsonObject j_obj(&allocator);
j_base = &j_obj;
int64 repeat_num = 10000;
int64_t times = 0;
uint64_t last_size = 0;
uint64_t new_size = 0;
while(times < repeat_num) {
// key
buf = reinterpret_cast<char *>(allocator.alloc(10));
MEMCPY(buf, key_str, strlen(key_str));
buf[strlen(key_str)] = '\0';
ObString key(strlen(key_str), buf);
// value
buf = reinterpret_cast<char *>(allocator.alloc(sizeof(ObJsonInt)));
ObJsonInt *j_int = (ObJsonInt *)new(buf) ObJsonInt(1);
ObIJsonBase *j_tmp_base = j_int;
ASSERT_EQ(OB_SUCCESS, j_base->object_add(key, j_tmp_base));
new_size = j_obj.get_serialize_size();
// cout << "root_serialize_size:" << new_size << endl;
ASSERT_GT(new_size, last_size);
last_size = new_size;
times++;
}
}
TEST_F(TestJsonTree, test_get_serialize_size_object_multi_depth)
{
ObArenaAllocator allocator(ObModIds::TEST);
uint64_t serialize_size = 0;
ObIJsonBase *j_base = NULL;
char *buf = NULL;
char key_str[10] = "key";
// object
ObJsonObject j_obj(&allocator);
j_base = &j_obj;
int64 repeat_num = 10000;
int64_t times = 0;
uint64_t last_size = 0;
uint64_t new_size = 0;
ObIJsonBase *last_j_base = j_base;
while(times < repeat_num) {
// new_object
buf = reinterpret_cast<char *>(allocator.alloc(sizeof(ObJsonObject)));
ObJsonObject *j_new_obj = (ObJsonObject *)new(buf) ObJsonObject(&allocator);
ObIJsonBase* tmp_obj_base = j_new_obj;
// new_key
buf = reinterpret_cast<char *>(allocator.alloc(10));
MEMCPY(buf, key_str, strlen(key_str));
buf[strlen(key_str)] = '\0';
ObString key(strlen(key_str), buf);
// new_int
buf = reinterpret_cast<char *>(allocator.alloc(sizeof(ObJsonInt)));
ObJsonInt *j_int = (ObJsonInt *)new(buf) ObJsonInt(1);
ObIJsonBase *tmp_int_base = j_int;
ASSERT_EQ(OB_SUCCESS, tmp_obj_base->object_add(key, tmp_int_base));
ASSERT_EQ(OB_SUCCESS, last_j_base->object_add(key, tmp_obj_base));
last_j_base = tmp_obj_base;
new_size = j_obj.get_serialize_size();
// cout << "root_serialize_size:" << new_size << endl;
ASSERT_GT(new_size, last_size);
last_size = new_size;
times++;
}
}
TEST_F(TestJsonTree, test_clone_node_array)
{
ObArenaAllocator allocator(ObModIds::TEST);
const char *syntaxerr = NULL;
uint64_t err_offset = 0;
uint64_t serialize_size = 0;
ObJsonNode *j_node = NULL;
ObIJsonBase *j_base = NULL;
ObJsonBuffer j_buf(&allocator);
// array
common::ObString j_arr_text("[1, \"abc\", 1.2, null, 0, [123, 1, 2]]");
ASSERT_EQ(OB_SUCCESS, ObJsonParser::parse_json_text(&allocator, j_arr_text.ptr(), j_arr_text.length(),
syntaxerr, &err_offset, j_node));
j_base = j_node;
j_buf.reset();
ASSERT_EQ(OB_SUCCESS, j_base->print(j_buf, false));
cout << "array_without_quote: " << j_buf.ptr() << endl;
ASSERT_EQ(j_node->json_type(), ObJsonNodeType::J_ARRAY);
ObJsonBuffer new_node_buf(&allocator);
new_node_buf.reset();
ObJsonNode *new_node = j_node->clone(&allocator);
ObIJsonBase *j_new_base = new_node;
ASSERT_EQ(OB_SUCCESS, j_new_base->print(new_node_buf, false));
cout << "array_without_quote: " << new_node_buf.ptr() << endl;
ASSERT_EQ(new_node->json_type(), ObJsonNodeType::J_ARRAY);
ASSERT_STREQ(new_node_buf.ptr(), j_buf.ptr());
}
static int create_object(common::ObIAllocator *allocator, const char *key_ptr,
uint64_t length, ObJsonNode *value, ObJsonObject *&j_obj)
{
int ret = OB_SUCCESS;
void *obj_buf = allocator->alloc(sizeof(ObJsonObject));
void *key_buf = allocator->alloc(sizeof(ObString));
void *key_val = allocator->alloc(sizeof(char) * length);
ObJsonObject *obj = new (obj_buf) ObJsonObject(allocator);
MEMCPY(key_val, key_ptr, length);
ObString *key = new (key_buf) ObString(length, (char *)key_val);
if (value == NULL) {
void *val_buf = allocator->alloc(sizeof(ObJsonInt));
value = new (val_buf) ObJsonInt(1);
}
if (OB_FAIL(obj->add(*key, value))) {
ret = OB_ERR_UNEXPECTED;
} else{
j_obj = obj;
}
return ret;
}
TEST_F(TestJsonTree, test_clone_node_object)
{
ObArenaAllocator allocator(ObModIds::TEST);
ObIJsonBase *j_base = NULL;
ObJsonBuffer j_buf(&allocator);
ObJsonObject *last_obj = NULL;
ObJsonObject *new_obj = NULL;
char key_buf[10] = {0};
// 1. 深度测试
// 99个对象嵌套
for (uint32_t i = 0; i < 100; i++) {
sprintf(key_buf, "key%d", i);
if (i == 0) {
ASSERT_EQ(OB_SUCCESS, create_object(&allocator, key_buf, strlen(key_buf), NULL, new_obj));
} else {
ASSERT_EQ(OB_SUCCESS, create_object(&allocator, key_buf, strlen(key_buf), last_obj, new_obj));
}
last_obj = new_obj;
}
j_base = new_obj;
j_buf.reset();
ASSERT_EQ(OB_SUCCESS, j_base->print(j_buf, false));
cout << "object_without_quote: " << j_buf.ptr() << endl;
ObJsonBuffer new_node_buf(&allocator);
new_node_buf.reset();
ObJsonNode *new_node = new_obj->clone(&allocator);
ObIJsonBase *j_new_base = new_node;
ASSERT_EQ(OB_SUCCESS, j_new_base->print(new_node_buf, false));
cout << "object_without_quote: " << new_node_buf.ptr() << endl;
ASSERT_STREQ(new_node_buf.ptr(), j_buf.ptr());
}
// ObJsonWrapper::print 单元测试(boolean类型)
TEST_F(TestJsonTree, test_clone_node_boolean)
{
ObArenaAllocator allocator(ObModIds::TEST);
ObIJsonBase *j_base = NULL;
ObJsonBuffer j_buf(&allocator);
ObJsonBoolean j_bool(true);
j_base = &j_bool;
ASSERT_EQ(OB_SUCCESS, j_base->print(j_buf, false));
cout << "boolean_without_quote: " << j_buf.ptr() << endl;
ASSERT_STREQ("true", j_buf.ptr());
j_buf.reset();
ObJsonNode *new_node = j_bool.clone(&allocator);
ObIJsonBase *j_new_base = new_node;
ASSERT_EQ(OB_SUCCESS, j_new_base->print(j_buf, false));
cout << "boolean_without_quote: " << j_buf.ptr() << endl;
ASSERT_STREQ("true", j_buf.ptr());
}
// ObJsonWrapper::print 单元测试(decimal类型)
TEST_F(TestJsonTree, test_clone_node_decimal)
{
ObArenaAllocator allocator(ObModIds::TEST);
ObIJsonBase *j_base = NULL;
ObJsonBuffer j_buf(&allocator);
const int64_t MAX_BUF_SIZE = 512;
char buf[MAX_BUF_SIZE] = {0};
number::ObNumber num;
int length = sprintf(buf, "%lld", LLONG_MIN);
ASSERT_EQ(OB_SUCCESS, num.from(buf, allocator));
ObJsonDecimal j_decimal(num);
j_base = &j_decimal;
ASSERT_EQ(OB_SUCCESS, j_base->print(j_buf, false));
cout << "date_without_quote: " << j_buf.ptr() << endl;
ASSERT_STREQ("-9223372036854775808", j_buf.ptr());
j_buf.reset();
ObJsonNode *new_node = j_decimal.clone(&allocator);
ObIJsonBase *j_new_base = new_node;
ASSERT_EQ(OB_SUCCESS, j_new_base->print(j_buf, false));
cout << "date_without_quote: " << j_buf.ptr() << endl;
ASSERT_STREQ("-9223372036854775808", j_buf.ptr());
}
// ObJsonWrapper::print 单元测试(double类型)
TEST_F(TestJsonTree, test_clone_node_double)
{
ObArenaAllocator allocator(ObModIds::TEST);
ObIJsonBase *j_base = NULL;
ObJsonBuffer j_buf(&allocator);
ObJsonDouble j_double(DBL_MAX);
j_base = &j_double;
ASSERT_EQ(OB_SUCCESS, j_base->print(j_buf, false));
cout << "double_without_quote: " << j_buf.ptr() << endl;
ASSERT_STREQ("1.7976931348623157e308", j_buf.ptr());
j_buf.reset();
ObJsonNode *new_node = j_double.clone(&allocator);
ObIJsonBase *j_new_base = new_node;
ASSERT_EQ(OB_SUCCESS, j_new_base->print(j_buf, false));
cout << "double_without_quote: " << j_buf.ptr() << endl;
ASSERT_STREQ("1.7976931348623157e308", j_buf.ptr());
}
// ObJsonWrapper::print 单元测试(null类型)
TEST_F(TestJsonTree, test_clone_node_null)
{
ObArenaAllocator allocator(ObModIds::TEST);
ObIJsonBase *j_base = NULL;
ObJsonBuffer j_buf(&allocator);
ObJsonNull j_null;
j_base = &j_null;
ASSERT_EQ(OB_SUCCESS, j_base->print(j_buf, false));
cout << "null_without_quote: " << j_buf.ptr() << endl;
ASSERT_STREQ("null", j_buf.ptr());
j_buf.reset();
ObJsonNode *new_node = j_null.clone(&allocator);
ObIJsonBase *j_new_base = new_node;
ASSERT_EQ(OB_SUCCESS, j_new_base->print(j_buf, false));
cout << "null_without_quote: " << j_buf.ptr() << endl;
ASSERT_STREQ("null", j_buf.ptr());
}
// ObJsonWrapper::print 单元测试(opaque类型)
TEST_F(TestJsonTree, test_clone_node_opaque)
{
ObArenaAllocator allocator(ObModIds::TEST);
ObIJsonBase *j_base = NULL;
ObJsonBuffer j_buf(&allocator);
ObString str("opaque");
ObJsonOpaque j_opaque(str, ObLongTextType);
j_base = &j_opaque;
ASSERT_EQ(OB_SUCCESS, j_base->print(j_buf, false));
cout << "opaque_without_quote: " << j_buf.ptr() << endl;
ASSERT_STREQ("base64:type251:b3BhcXVl", j_buf.ptr());
j_buf.reset();
ObJsonNode *new_node = j_opaque.clone(&allocator);
ObIJsonBase *j_new_base = new_node;
ASSERT_EQ(OB_SUCCESS, j_new_base->print(j_buf, false));
cout << "opaque_without_quote: " << j_buf.ptr() << endl;
ASSERT_STREQ("base64:type251:b3BhcXVl", j_buf.ptr());
}
// ObJsonWrapper::print 单元测试(string类型)
TEST_F(TestJsonTree, test_clone_node_string)
{
ObArenaAllocator allocator(ObModIds::TEST);
ObIJsonBase *j_base = NULL;
ObJsonBuffer j_buf(&allocator);
ObString str("string");
ObJsonString j_string(str.ptr(), str.length());
j_base = &j_string;
ASSERT_EQ(OB_SUCCESS, j_base->print(j_buf, false));
cout << "string_without_quote: " << j_buf.ptr() << endl;
ASSERT_STREQ("string", j_buf.ptr());
j_buf.reset();
ObJsonNode *new_node = j_string.clone(&allocator);
ObIJsonBase *j_new_base = new_node;
ASSERT_EQ(OB_SUCCESS, j_new_base->print(j_buf, false));
cout << "string_without_quote: " << j_buf.ptr() << endl;
ASSERT_STREQ("string", j_buf.ptr());
}
TEST_F(TestJsonTree, test_clone_node_int)
{
ObArenaAllocator allocator(ObModIds::TEST);
ObIJsonBase *j_base = NULL;
ObJsonBuffer j_buf(&allocator);
ObJsonInt j_int(LONGLONG_MIN);
j_base = &j_int;
ASSERT_EQ(OB_SUCCESS, j_base->print(j_buf, false));
cout << "int_without_quote: " << j_buf.ptr() << endl;
ASSERT_STREQ("-9223372036854775808", j_buf.ptr());
j_buf.reset();
ObJsonNode *new_node = j_int.clone(&allocator);
ObIJsonBase *j_new_base = new_node;
ASSERT_EQ(OB_SUCCESS, j_new_base->print(j_buf, false));
cout << "int_without_quote: " << j_buf.ptr() << endl;
ASSERT_STREQ("-9223372036854775808", j_buf.ptr());
}
// ObJsonWrapper::print 单元测试(uint类型)
TEST_F(TestJsonTree, test_clone_node_uint)
{
ObArenaAllocator allocator(ObModIds::TEST);
ObIJsonBase *j_base = NULL;
ObJsonBuffer j_buf(&allocator);
ObJsonUint j_uint(ULLONG_MAX);
j_base = &j_uint;
ASSERT_EQ(OB_SUCCESS, j_base->print(j_buf, false));
cout << "uint_without_quote: " << j_buf.ptr() << endl;
ASSERT_STREQ("18446744073709551615", j_buf.ptr());
j_buf.reset();
ObJsonNode *new_node = j_uint.clone(&allocator);
ObIJsonBase *j_new_base = new_node;
ASSERT_EQ(OB_SUCCESS, j_new_base->print(j_buf, false));
cout << "uint_without_quote: " << j_buf.ptr() << endl;
ASSERT_STREQ("18446744073709551615", j_buf.ptr());
}
// ObRapidJsonHandler::seeing_value 单元测试
TEST_F(TestJsonTree, test_clone_node_datetime)
{
ObArenaAllocator allocator(ObModIds::TEST);
ObIJsonBase *j_base = NULL;
ObJsonBuffer j_buf(&allocator);
// datetime
ObTime ob_time3;
ASSERT_EQ(OB_SUCCESS, ObTimeConverter::datetime_to_ob_time(1429089727 * USECS_PER_SEC, NULL, ob_time3));
ASSERT_TRUE(ob_time_eq(ob_time3, 2015, 4, 15, 9, 22, 7, 0));
ObJsonDatetime j_datetime(ob_time3, ObDateTimeType);
j_base = &j_datetime;
ASSERT_EQ(OB_SUCCESS, j_base->print(j_buf, false));
cout << "datetime_without_quote: " << j_buf.ptr() << endl;
j_buf.reset();
ObJsonNode *new_node = j_datetime.clone(&allocator);
ObIJsonBase *j_new_base = new_node;
ASSERT_EQ(OB_SUCCESS, j_new_base->print(j_buf, false));
cout << "datetime_without_quote: " << j_buf.ptr() << endl;
ASSERT_STREQ("2015-04-15 09:22:07.000000", j_buf.ptr());
}
TEST_F(TestJsonTree, oracle_sub_type)
{
ObArenaAllocator allocator(ObModIds::TEST);
/* contruct type */
// int olong
ObJsonOInt o_int(123);
ObJsonOLong o_long(1234567890);
size_t MAX_BUF_SIZE = 256;
// odecimal
char dec_buf[MAX_BUF_SIZE];
memset(dec_buf, 0, MAX_BUF_SIZE);
number::ObNumber num;
size_t length = sprintf(dec_buf, "%lld", LLONG_MIN);
ASSERT_EQ(OB_SUCCESS, num.from(dec_buf, allocator));
ObJsonDecimal o_dec(num);
// odouble ofloat
ObJsonODouble o_double(0.0);
ObJsonOFloat o_float(23.23);
// interval ds
const char* interval_ds = "interval ds 123";
char* buf1 = (char*)allocator.alloc(MAX_BUF_SIZE);
memset(buf1, 0, MAX_BUF_SIZE);
memcpy(buf1, interval_ds, strlen(interval_ds));
ObJsonOInterval o_intervalds(buf1, strlen(interval_ds), ObIntervalDSType);
// interval ym
const char* interval_ym = "interval ym 123";
char* buf2 = (char*)allocator.alloc(MAX_BUF_SIZE);
memset(buf2, 0, MAX_BUF_SIZE);
memcpy(buf2, interval_ds, strlen(interval_ds));
ObJsonOInterval o_intervalym(buf2, strlen(interval_ds), ObIntervalDSType);
// binary
const char* binary = "binary string";
char* buf3 = (char*)allocator.alloc(MAX_BUF_SIZE);
memset(buf3, 0, MAX_BUF_SIZE);
memcpy(buf3, binary, strlen(binary));
ObJsonORawString o_binary(buf3, strlen(binary), ObJsonNodeType::J_OBINARY);
// odate, oracledate, otimestamp, otimestamptz
ObTime ob_time;
ASSERT_EQ(OB_SUCCESS, ObTimeConverter::datetime_to_ob_time(1429089727 * USECS_PER_SEC, NULL, ob_time));
ObJsonDatetime j_odate(ObJsonNodeType::J_ODATE, ob_time);
ObJsonDatetime j_oracledate(ObJsonNodeType::J_ORACLEDATE, ob_time);
ObJsonDatetime j_otimestamp(ObJsonNodeType::J_OTIMESTAMP, ob_time);
ObJsonDatetime j_otimestamptz(ObJsonNodeType::J_OTIMESTAMPTZ, ob_time);
/* test print */
// print
ObJsonBuffer j_buf(&allocator);
ObIJsonBase *j_base = nullptr;
j_base = (ObIJsonBase*)&o_int;
ASSERT_EQ(OB_SUCCESS, j_base->print(j_buf, false));
cout << "oint = " << j_buf.ptr() << endl;
j_buf.reuse();
j_base = (ObIJsonBase*)&o_long;
ASSERT_EQ(OB_SUCCESS, j_base->print(j_buf, false));
cout << "olong = " << j_buf.ptr() << endl;
j_buf.reuse();
j_base = (ObIJsonBase*)&o_dec;
ASSERT_EQ(OB_SUCCESS, j_base->print(j_buf, false));
cout << "odecimal = " << j_buf.ptr() << endl;
j_buf.reuse();
j_base = (ObIJsonBase*)&o_float;
ASSERT_EQ(OB_SUCCESS, j_base->print(j_buf, false));
cout << "ofloat = " << j_buf.ptr() << endl;
j_buf.reuse();
j_base = (ObIJsonBase*)&o_binary;
ASSERT_EQ(OB_SUCCESS, j_base->print(j_buf, false));
cout << "obinary = " << j_buf.ptr() << endl;
j_buf.reuse();
j_base = (ObIJsonBase*)&o_intervalds;
ASSERT_EQ(OB_SUCCESS, j_base->print(j_buf, false));
cout << "ointervalds = " << j_buf.ptr() << endl;
j_buf.reuse();
j_base = (ObIJsonBase*)&o_intervalym;
ASSERT_EQ(OB_SUCCESS, j_base->print(j_buf, false));
cout << "ointervalmy = " << j_buf.ptr() << endl;
j_buf.reuse();
j_base = (ObIJsonBase*)&j_odate;
ASSERT_EQ(OB_SUCCESS, j_base->print(j_buf, false));
cout << "odate = " << j_buf.ptr() << endl;
j_buf.reuse();
j_base = (ObIJsonBase*)&j_oracledate;
ASSERT_EQ(OB_SUCCESS, j_base->print(j_buf, false));
cout << "oracledate = " << j_buf.ptr() << endl;
j_buf.reuse();
j_base = (ObIJsonBase*)&j_otimestamp;
ASSERT_EQ(OB_SUCCESS, j_base->print(j_buf, false));
cout << "otimestamp = " << j_buf.ptr() << endl;
j_buf.reuse();
j_base = (ObIJsonBase*)&j_otimestamptz;
ASSERT_EQ(OB_SUCCESS, j_base->print(j_buf, false));
cout << "otimestamptz = " << j_buf.ptr() << endl;
/* clone */
ObJsonNode *p_oint = o_int.clone(&allocator);
ASSERT_NE(nullptr, p_oint);
ObJsonNode *p_olong = o_long.clone(&allocator);
ASSERT_NE(nullptr, p_olong);
ObJsonNode *p_ofloat = o_float.clone(&allocator);
ASSERT_NE(nullptr, p_ofloat);
ObJsonNode *p_odoube = o_double.clone(&allocator);
ASSERT_NE(nullptr, p_odoube);
ObJsonNode *p_ointervalds = o_intervalds.clone(&allocator);
ASSERT_NE(nullptr, p_ointervalds);
ObJsonNode *p_ointervalym = o_intervalym.clone(&allocator);
ASSERT_NE(nullptr, p_ointervalym);
ObJsonNode *p_obinary = o_binary.clone(&allocator);
ASSERT_NE(nullptr, p_obinary);
ObJsonNode *p_odate = j_odate.clone(&allocator);
ASSERT_NE(nullptr, p_odate);
ObJsonNode *p_oracledate = j_oracledate.clone(&allocator);
ASSERT_NE(nullptr, p_oracledate);
ObJsonNode *p_otimestamp = j_otimestamp.clone(&allocator);
ASSERT_NE(nullptr, p_otimestamp);
ObJsonNode *p_otimestamptz = j_otimestamptz.clone(&allocator);
ASSERT_NE(nullptr, p_otimestamptz);
double d_value;
float f_value;
uint64_t u_value;
int64_t i_value;
ASSERT_EQ(OB_SUCCESS, o_int.to_double(d_value));
ASSERT_EQ(OB_SUCCESS, o_int.to_uint(u_value));
ASSERT_EQ(OB_SUCCESS, o_float.to_uint(u_value));
ASSERT_EQ(OB_SUCCESS, o_float.to_double(d_value));
ASSERT_EQ(OB_SUCCESS, o_float.to_int(i_value));
}
TEST_F(TestJsonTree, test_sort)
{
set_compat_mode(lib::Worker::CompatMode::MYSQL);
// correct json text
common::ObString json_text("{ \"a\" : \"value1\", \"a\" : \"value2\", \
\"b\" : \"value3\", \"b\" : \"value4\" }");
common::ObArenaAllocator allocator(ObModIds::TEST);
const char *syntaxerr = NULL;
ObJsonNode *json_tree = NULL;
ASSERT_EQ(OB_SUCCESS, ObJsonParser::parse_json_text(&allocator, json_text.ptr(),
json_text.length(), syntaxerr, NULL, json_tree));
ASSERT_TRUE(json_tree != NULL);
ObJsonBuffer j_buf(&allocator);
ASSERT_EQ(json_tree->print(j_buf, false), 0);
std::string tmp_res(j_buf.ptr());
std::string result("{\"a\": \"value2\", \"b\": \"value4\"}");
ASSERT_EQ(result, tmp_res);
}
TEST_F(TestJsonTree, test_big_json)
{
common::ObArenaAllocator allocator(ObModIds::TEST);
ObJsonBuffer j_buf(&allocator);
ASSERT_EQ(j_buf.reserve(1024 * 1024), 0);
ASSERT_EQ(j_buf.append("{"), 0);
static char origin[] = "0123456789abcdef";
char key_buffer[33] = {0};
char value_buffer[16] = {0};
int idx = 0;
for (int64_t pos = 0; pos < 50000; ++pos) {
for (int i = 0; i < 32; ++i) {
idx = ObRandom::rand(0, 15);
key_buffer[i] = origin[idx];
}
ASSERT_EQ(j_buf.append("\""), 0);
ASSERT_EQ(j_buf.append(key_buffer, 32), 0);
ASSERT_EQ(j_buf.append("\""), 0);
ASSERT_EQ(j_buf.append(": "), 0);
snprintf(value_buffer, 16, "%ld", pos);
ASSERT_EQ(j_buf.append(value_buffer), 0);
ASSERT_EQ(j_buf.append(", "), 0);
}
j_buf.set_length(j_buf.length() - 2);
ASSERT_EQ(j_buf.append("}"), 0);
// correct json text
common::ObString json_text(j_buf.length(), j_buf.ptr());
const char *syntaxerr = NULL;
ObJsonNode *json_tree = NULL;
struct timeval time_start, time_end;
gettimeofday(&time_start, nullptr);
ASSERT_EQ(OB_SUCCESS, ObJsonParser::parse_json_text(&allocator, json_text.ptr(),
json_text.length(), syntaxerr, NULL, json_tree));
ASSERT_TRUE(json_tree != NULL);
gettimeofday(&time_end, nullptr);
cout << "time start : " << " sec = " << time_start.tv_sec << ", usec = " << time_start.tv_usec << endl;
cout << "time end : " << " sec = " << time_end.tv_sec << ", usec = " << time_end.tv_usec << endl;
}
TEST_F(TestJsonTree, test_parse_big_json)
{
common::ObArenaAllocator allocator(ObModIds::TEST);
ObJsonBuffer j_buf(&allocator);
ASSERT_EQ(j_buf.reserve(1024 * 1024), 0);
const char* j_string = "{\"nested_level0\": {\"key_0\":\"rFHOjQsWNRJ1fnbGP8dqmEYXk9ZpIw\", \"nested_level1\": {\"key_0\": false, \"key_1\": {\"key1\": [null, null], \"key2\": [{\"key1\": null, \"key2\": null, \"key3\": [{\"key1\": null, \"key2\": 21}, null]}, {\"key1\": {\"key1\": \"GwbmUpJ6RMigaVrfXqAWsQYbus409K\", \"key2\": [[{\"key1\": null}]], \"key3\": \"kuaI4mKt2W9bLAZ0R8zhH5yioGBN3V\"}, \"key2\": {\"key1\": {\"key1\": null}, \"key2\": null, \"key3\": [null, \"vID3PZfurRUT5LMFkG8QtOoWpK1JhH\", {\"key1\": \"KXFkMT35aDyGEj4mSxAU8YLqw9VspO\"}]}}], \"key3\": \"UoLf0FwEsQnGVeKy4SMdkqmslctDiY\"}, \"key_2\": {\"key1\": false, \"key2\": [null], \"key3\": \"GYxPF1X5kuby0SEwBO6aoWTss92McU\"}, \"key_3\": \"Xd01h4umROkcqHw23s8jCAyGpxD9MY\", \"key_4\": true, \"nested_level2\": {\"key_0\": null, \"key_1\": false, \"key_2\": 59, \"key_3\": [{\"key1\": 17, \"key2\": 54}], \"key_4\": {\"key1\": {\"key1\": null, \"key2\": 4, \"key3\": 82}, \"key2\": [\"el16BGbz2TESkOdJ7Zf8hW4Kw0RoV5\"], \"key3\": 19}, \"nested_level3\": {\"key_0\": [null], \"key_1\": {\"key1\": \"idKvulYwSAORrILPJWyMZXzq4tbU31\", \"key2\": [null, false, {\"key1\": {\"key1\": \"UvbyeVAJZuLwdPkqQ409Rss1XtaIN2\"}, \"key2\": \"G2RSg5jhwnXZOuPT17ovErQUtpbx43\"}]}, \"key_2\": \"MFvr5t8WHJXuBK7LVn6OfTbEkxYS2z\", \"key_3\": null, \"key_4\": false, \"nested_level4\": {\"key_0\": {\"key1\": 92, \"key2\": 85, \"key3\": \"rVXPL9us6CTuhwkc0DNHmGy1fWdJnU\"}, \"key_1\": {\"key1\": {\"key1\": {\"key1\": null, \"key2\": \"VE7s2KA5lvIT6t0Zhc4gx3UXRauquj\"}, \"key2\": 75, \"key3\": {\"key1\": {\"key1\": null, \"key2\": {\"key1\": 100, \"key2\": null}, \"key3\": null}, \"key2\": \"ngfA0JpjzRLGlxdIVhsmkawZTsy8XY\", \"key3\": [\"HFk4PXzxRGNMof7wgAWsJervbnyO5j\", \"v3xmXpZ6Ag0cKSs8ua19JbGEQd5Mit\"]}}, \"key2\": [{\"key1\": true, \"key2\": \"l9qfbRybMXaFkOWAPGJumwv3cUI6Y8\", \"key3\": 89}], \"key3\": true}, \"key_2\": [{\"key1\": {\"key1\": 26, \"key2\": [[[[{\"key1\": {\"key1\": null, \"key2\": null}}, null, false]], 11], {\"key1\": [false, \"8AR2jptqZEYMWDsr65PxfbVozQC3Xn\"]}, false], \"key3\": null}, \"key2\": true, \"key3\": true}, \"MaLcwBsy0W1nRtQbNFoi92CkvuK3md\"], \"nested_level5\": {\"key_0\": \"gxhDrz6nR2FZOUIyAjuuqt749XNMHs\", \"key_1\": true, \"nested_level6\": {\"key_0\": {\"key1\": [true], \"key2\": \"VgZsqym3j65eLJw9Crxf8WBIhRpbiT\"}, \"key_1\": [\"mVbEYeovLnj2ktWRXIusxZcHPb9rFB\"], \"key_2\": \"lXuouzj4svAx5Q6qBMyFerZEOV8YUp\", \"key_3\": null, \"nested_level7\": {\"key_0\": [true], \"key_1\": false, \"key_2\": [\"Oo93mYLJR1MHKZ7DbFVjbPaCh05lxf\"], \"nested_level8\": {\"key_0\": 72, \"key_1\": {\"key1\": \"aJzG0c5uR6wMhBpEPZKyNrlxDSI9jk\", \"key2\": [null, [[{\"key1\": 100}, {\"key1\": {\"key1\": [{\"key1\": 68, \"key2\": 34, \"key3\": {\"key1\": \"dX57msTtWEKZw0Pvi9zUaApsuRjS3e\"}}, true, null]}, \"key2\": null, \"key3\": [null, 39, \"8Wdcbl0wNkK4DBCqsJ7oajHI3V6Qus\"]}], {\"key1\": null, \"key2\": \"D0rIQwbL1PqEj8OypscdR3fNuVFslh\"}], [\"iS6BDbbXqnmTAJsLCs2v7y9aoPeuYU\"]]}, \"key_2\": [6, {\"key1\": 33, \"key2\": [\"ESoDuF8srvJqlkCu6tLWh52PBXyZpV\", \"m7NXHuhTjo8bigLWwnd01ZbOQVMzSv\"]}, \"9zPJN74yxCipGF6e2RqDWdtHB1bnKT\"], \"nested_level9\": {\"key_0\": {\"key1\": null, \"key2\": {\"key1\": [null, \"sFuZ57K4hUmTbJnYeoGVsquXSdIa8L\"]}, \"key3\": {\"key1\": false, \"key2\": 83, \"key3\": false}}, \"key_1\": false, \"nested_level10\": {\"key_0\": null, \"key_1\": true, \"key_2\": {\"key1\": null, \"key2\": null, \"key3\": false}, \"key_3\": {\"key1\": true}, \"key_4\": null, \"nested_level11\": {\"key_0\": [{\"key1\": {\"key1\": [{\"key1\": null}], \"key2\": true}}, [65]], \"key_1\": false, \"key_2\": \"34Esmiq7vl8Jy6TsnpfrWBkMtLZCcF\", \"key_3\": null, \"nested_level12\": {\"key_0\": \"l87CXV3fdbKPAJyvLZchr2uNezopOR\", \"key_1\": 7, \"nested_level13\": {\"key_0\": true, \"key_1\": null, \"key_2\": \"uqr9EYIc36kjWdPKXpOw2lf4MZmJSB\", \"nested_level14\": {\"key_0\": 78, \"key_1\": {\"key1\": false}, \"key_2\": null, \"nested_level15\": {\"key_0\": 79, \"key_1\": [null, {\"key1\": null, \"key2\": null, \"key3\": null}, \"6vRfNuGgiV02WL4Z5b1uyBdFo7HsJa\"], \"key_2\": null, \"nested_level16\": {\"key_0\": {\"key1\": null}, \"key_1\": null, \"key_2\": false, \"key_3\": false, \"nested_level17\": {\"key_0\": false, \"nested_level18\": {\"key_0\": null, \"key_1\": [null], \"key_2\": \"5fnC7lsItcugeZmuszXa1iQ6P32yOV\", \"nested_level19\": {\"key_0\": false, \"key_1\": 32, \"key_2\": {\"key1\": \"QIG7vZ9EhHR1uPr8ojebaTcOSYC3xK\", \"key2\": 31, \"key3\": 85}, \"key_3\": 76, \"nested_level20\": {\"key_0\": true, \"key_1\": [null], \"key_2\": {\"key1\": null, \"key2\": {\"key1\": false, \"key2\": false}}, \"key_3\": \"NGneWkhSHCY6yMl0xEBgtjs8aOIufi\", \"key_4\": true, \"nested_level21\": {\"key_0\": null, \"key_1\": {\"key1\": {\"key1\": {\"key1\": false, \"key2\": {\"key1\": 70, \"key2\": \"SbuP0nAVFimGDo9ONLqZQJbRt5kY3x\", \"key3\": null}}}, \"key2\": true, \"key3\": null}, \"key_2\": \"V9j3GruP6iYLAw7SFhEsymW2C1vQbB\", \"key_3\": true, \"nested_level22\": {\"key_0\": false, \"key_1\": [11, null, 40], \"key_2\": 32, \"nested_level23\": {\"key_0\": 43, \"key_1\": null, \"nested_level24\": {\"key_0\": [43, null, null], \"key_1\": 65, \"key_2\": [null, {\"key1\": null}], \"key_3\": null, \"nested_level25\": {\"key_0\": [{\"key1\": {\"key1\": [61], \"key2\": {\"key1\": [true], \"key2\": [null, 8]}}}, false], \"key_1\": {\"key1\": 45, \"key2\": {\"key1\": \"Y0fHj3yOuMFsti5neU6mkJXNrZguWb\", \"key2\": \"SzMi1P9Es0Dl8xAf73CqdkjIpKowuF\"}}, \"key_2\": 70, \"key_3\": [{\"key1\": \"csI9w0HunOjW7e32zvXgAMxo1thaGr\", \"key2\": null}, \"kByJSs7hUzqW6lp5iFuAP98rsctwVe\", {\"key1\": \"b9JY5BloueFMShLRgI6zGaZEfdtOpr\"}], \"key_4\": \"jSmlXdyoOGraMeVnNRT2sYzPqikBU6\", \"nested_level26\": {\"key_0\": [10], \"key_1\": 83, \"nested_level27\": {\"key_0\": false, \"key_1\": null, \"key_2\": 48, \"key_3\": null, \"key_4\": {\"key1\": false, \"key2\": null}, \"nested_level28\": {\"key_0\": null, \"key_1\": [\"aoMdfwsI2VB1jT9txYspDbzlGiq0Jg\"], \"key_2\": {\"key1\": null, \"key2\": \"1eb3XdFrbs7TJlhNsf2O5uAH8Qau0Y\", \"key3\": [\"KS0mbf4pqGjz9dLNAb5iolMkYJVuDs\", 53]}, \"key_3\": \"gRGcAbpKt6fPhuEOIbz7L5dweT2FuD\", \"nested_level29\": {\"key_0\": false, \"key_1\": null, \"key_2\": [true, 82], \"key_3\": \"sn2dwUzkPCbRS7fBWM8jGVtTa1iLe3\", \"key_4\": null, \"nested_level30\": {\"key_0\": 15, \"key_1\": {\"key1\": {\"key1\": {\"key1\": \"c6fJXenbCsgijM9WPpqATxEQhzYwI2\"}, \"key2\": 51, \"key3\": [true]}, \"key2\": \"wEqZtAk6XODMBGCTflgzj20FhuJ5NQ\", \"key3\": [true, {\"key1\": [33, {\"key1\": [52, \"gOCESk4bU1w7Z8KXhB6pedFzTsJMY3\", null]}, null]}]}, \"key_2\": \"oPEVR32FhwbUrYLO60bsgti7ljvDpc\", \"key_3\": [11], \"nested_level31\": {\"key_0\": 26, \"key_1\": false, \"key_2\": false, \"key_3\": [{\"key1\": 78, \"key2\": true, \"key3\": null}, false, [null, false, {\"key1\": {\"key1\": false}, \"key2\": {\"key1\": null, \"key2\": \"HqFrO72eoj1PQpbWRJt0Vy3hd4Uu5z\", \"key3\": false}}]], \"key_4\": 64, \"nested_level32\": {\"key_0\": null, \"key_1\": null, \"key_2\": {\"key1\": 7, \"key2\": \"KcUWAgEe1BiqZSXV2m8GdFahzPQbLM\"}, \"key_3\": \"UyDit9MGsXjrgRkluSQFBE2q56OAbu\", \"key_4\": 87, \"nested_level33\": {\"key_0\": {\"key1\": {\"key1\": {\"key1\": [\"IVKQWg7UsMo4kwGuehnZOizX5LxRNT\", \"skVtwZqWQrND3bdUxK5u8E1jmnhif0\"], \"key2\": false}}, \"key2\": [null]}, \"key_1\": [39, 45, true], \"nested_level34\": {\"key_0\": \"qF7ubaXmKAsJIijw0dUteTxN915DPz\", \"key_1\": 4, \"key_2\": \"qydnVaRsxw0kzmotYeUWJBT93g4Qsb\", \"key_3\": [\"p5Ts8YFGOj1yDvQUEnwctu6LhmeJK3\"], \"key_4\": [null], \"nested_level35\": {\"key_0\": [[{\"key1\": [\"9DVXfgU2loPiIqQjpvM3EROGtWshBd\", true], \"key2\": 21, \"key3\": 99}, {\"key1\": null}, {\"key1\": false, \"key2\": 92}], [[\"ixsu6CM5RZHBnjGe2oackwd8Jl43tq\"], 3], {\"key1\": false, \"key2\": {\"key1\": \"glr7Q4yVtpZC0X5oAvWjzTu6YuSKaM\", \"key2\": 98, \"key3\": [\"wxNqHTzES9WpyRdbhZtinODQA3FJlm\", 3, [\"ui5EOZeRkxYnjTr1lwVy8pcDobhzqS\"]]}, \"key3\": \"elG4iECrDUHBb6VvWKkds9hpM8cP17\"}], \"key_1\": 25, \"nested_level36\": {\"key_0\": \"JsRb0ytMH3oeh4gz97QBiVndsOYkIA\", \"key_1\": {\"key1\": \"jNiksS0R2vfKMoLhdO1gb8qyanAJc9\", \"key2\": \"V9wALy8oTBEMiUbFJfNtahz64rblC3\"}, \"key_2\": \"z5k0sWHTciSl6qyrCVm3ZJ9gYoba82\", \"key_3\": false, \"nested_level37\": {\"key_0\": \"YOn4jmScFweCxuksRATZb5GaNhypz1\", \"key_1\": null, \"key_2\": [{\"key1\": [\"k7Ez4jObJ1PVAGCbv25psiLlyhQwI3\"], \"key2\": {\"key1\": true}}], \"key_3\": {\"key1\": \"6vubTJsGDXmaWe2OcwhQHsVKtCuLjr\", \"key2\": null}, \"nested_level38\": {\"key_0\": [null], \"key_1\": false, \"key_2\": {\"key1\": [null, true], \"key2\": [97], \"key3\": null}, \"nested_level39\": {\"key_0\": [null], \"key_1\": {\"key1\": false, \"key2\": \"0xRhD1VTS4ANKGPLk8rQibofuB3CuY\", \"key3\": {\"key1\": \"lZdwviNxSWGC3uhOuY8E1npc0QUk4B\", \"key2\": \"daHs71Bk9DuWb8ClstZEKzLYNjxbnP\"}}, \"nested_level40\": {\"key_0\": null, \"nested_level41\": {\"key_0\": true, \"key_1\": \"wzWrhDO8EauX0bIYbRqcL5tNG1smnk\", \"nested_level42\": {\"key_0\": 5, \"key_1\": false, \"key_2\": 2, \"key_3\": 9, \"nested_level43\": {\"key_0\": 82, \"key_1\": 23, \"key_2\": true, \"nested_level44\": {\"key_0\": {\"key1\": true}, \"key_1\": \"gFTRk4bDEKHfysxtwcWBG3Is5AZhVl\", \"key_2\": \"XV8I6nCLQZg7q12H9rilpoRKWu5Eb0\", \"key_3\": \"Nq7RjfAsmbTFC8oWH6xKlIpwOtuX1c\", \"nested_level45\": {\"key_0\": {\"key1\": false, \"key2\": 100}, \"key_1\": 19, \"key_2\": [false], \"nested_level46\": {\"key_0\": null, \"key_1\": {\"key1\": [\"Ybd5Ewpklu3CWMcesF9ZuBTVj2yXQm\", 41, \"jH1KONP6QxGW8kBEeosthlAI735vZJ\"], \"key2\": {\"key1\": \"yBdgEDJlcOP4pfhXAYqFHj0M97nCve\"}}, \"key_2\": 50, \"key_3\": false, \"nested_level47\": {\"key_0\": [\"georEv7Yw5zFSJ8TNDVaqQkWsl4mMy\"], \"key_1\": {\"key1\": true, \"key2\": null}, \"nested_level48\": {\"key_0\": \"AqQDLRGK8iahu3jHsNomlIOJ96bv01\", \"key_1\": \"6yJEBOjsmgU1e9iKl3YvuunSDfQkCt\", \"key_2\": \"TW7tz9gFf4rDNlRsbq50QhJiuCI2Ej\", \"key_3\": {\"key1\": \"RS85hbtjzPd9uuavrLogKHbZfemAFl\", \"key2\": {\"key1\": false, \"key2\": false}}, \"key_4\": 36, \"nested_level49\": {\"key_0\": null, \"key_1\": \"w9eVTcFMN2IaSlufEd0kptnozxuOG5\", \"key_2\": false, \"key_3\": [null, [false], [true]], \"key_4\": 60, \"nested_level50\": {\"key_0\": false, \"key_1\": [null, 63, true], \"key_2\": 1, \"nested_level51\": {\"key_0\": {\"key1\": {\"key1\": false, \"key2\": {\"key1\": null, \"key2\": 53, \"key3\": 11}}, \"key2\": {\"key1\": null}}, \"key_1\": {\"key1\": \"oCrdu8SjOIuX1EkaKUicYfF5Ghsy9p\"}, \"key_2\": null, \"key_3\": 64, \"key_4\": {\"key1\": {\"key1\": null, \"key2\": 58, \"key3\": [[89, {\"key1\": false, \"key2\": [false, {\"key1\": \"2GRO8SIiCAkuKfh6Q7cZlbHLTJ9sqy\", \"key2\": 89, \"key3\": \"ORhbeqgAzlWSwCTXMPDZEmdj8cynu9\"}], \"key3\": 69}, {\"key1\": [47, {\"key1\": {\"key1\": [null, null, false]}}, \"oSW6L1JYzgCQw0TbaIbylHuNiekFqZ\"]}], \"XwWf25EnY4U9NKphPsd7A8juL0OZts\", null]}, \"key2\": 11, \"key3\": null}, \"nested_level52\": {\"key_0\": null, \"key_1\": [61, {\"key1\": {\"key1\": [43], \"key2\": [22, {\"key1\": 31}], \"key3\": [true]}, \"key2\": [33, \"Wq4irhIsSuBHGtkbbZmsNCvJX1R5MK\", \"cDQPO782RInHAYeoGvKFZuSqbhrbzf\"], \"key3\": false}, null], \"key_2\": [[{\"key1\": 49}, [false]]], \"key_3\": 17, \"key_4\": [41, [10, {\"key1\": 26, \"key2\": false, \"key3\": {\"key1\": [null, false]}}, null]], \"nested_level53\": {\"key_0\": [{\"key1\": [\"WRQzp2AocbrhimtugCsnEGByTavN6x\", \"zcgDLGbBIamVh93r0dCPnHvo1qNYWt\", [[null, 46], null, {\"key1\": [[null]], \"key2\": \"5vc8wm9ksTXtBZP7afeE1VpyS6hWqd\", \"key3\": null}]], \"key2\": 49, \"key3\": [\"TKHc5CpigazQDWMA72G9RObtuveBN3\", [null, null]]}, {\"key1\": [\"sldEGIPLjV1euFUmksRa0OQ6Mn4CiY\", null], \"key2\": {\"key1\": [false, null]}, \"key3\": {\"key1\": [[\"sYbCReSo7FJyPbBlhuX1tIKTWaGjgA\"], true, [[55]]]}}, [true]], \"key_1\": [true], \"key_2\": 85, \"nested_level54\": {\"key_0\": null, \"key_1\": true, \"nested_level55\": {\"key_0\": 4, \"key_1\": 66, \"nested_level56\": {\"key_0\": [false, 26], \"key_1\": \"npSVJbctCYzkmKGD4X7uqg9dFjviIl\", \"nested_level57\": {\"key_0\": false, \"key_1\": [null, 66, 71], \"nested_level58\": {\"key_0\": \"3bhO9EKBodsAsb2S4WRkvgNmDilpQf\", \"key_1\": \"xJOkcYlBjbt4siPzM9SGF8dCU1nrfZ\", \"key_2\": 44, \"key_3\": \"zARhki7nO6cbDbemdHtv5JSx8rXj9Y\", \"nested_level59\": {\"key_0\": \"B9QLVci2EOhwyxKuusUe4dFGA8rPNR\", \"key_1\": [null, [true, \"XbT6K3OYjHaJAmsyUwuDku7WrGoep8\"]], \"key_2\": \"drXzih3GPsjeMsZfbkJUKL89waYncu\", \"nested_level60\": {\"key_0\": [{\"key1\": {\"key1\": 97}, \"key2\": null}, null], \"key_1\": true, \"key_2\": true, \"key_3\": [null, 56], \"nested_level61\": {\"key_0\": \"AkzfZmrYSDbjxuWnwya0eQ42gTqU7H\", \"nested_level62\": {\"key_0\": {\"key1\": 56, \"key2\": null}, \"key_1\": false, \"key_2\": 47, \"key_3\": {\"key1\": \"O9zdy8ujaUKWEDI6vnfum51TgoYPlM\", \"key2\": null, \"key3\": 9}, \"key_4\": null, \"nested_level63\": {\"key_0\": [{\"key1\": [true, null], \"key2\": true, \"key3\": {\"key1\": [18, [64]]}}], \"key_1\": false, \"nested_level64\": {\"key_0\": false, \"nested_level65\": {\"key_0\": 2, \"key_1\": true, \"key_2\": null, \"key_3\": \"7sbbIQcHFB8tz49auyV3dr0fAZwg2e\", \"key_4\": false, \"nested_level66\": {\"key_0\": [42, {\"key1\": null}], \"key_1\": [\"pngrb7eyvYPF3M9INU8zthGqdZi2cs\", null, [true, {\"key1\": true}, null]], \"key_2\": 41, \"nested_level67\": {\"key_0\": true, \"key_1\": [\"FiZhtaSPInDJAury9RbbcN0osszuOK\", \"cvls8GubUN7Iq95rhSDYuRTs1LxziC\"], \"nested_level68\": {\"key_0\": null, \"nested_level69\": {\"key_0\": \"lMgOQX6bPuImKJexAs9rD2bRcnZLu5\", \"key_1\": true, \"key_2\": \"YPuyawZ49Lhp03nWkujQb5mTBq6GtR\", \"key_3\": null}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}";
// correct json text
common::ObString json_text(j_string);
const char *syntaxerr = NULL;
ObJsonNode *json_tree = NULL;
struct timeval time_start, time_end;
gettimeofday(&time_start, nullptr);
ASSERT_EQ(OB_SUCCESS, ObJsonParser::parse_json_text(&allocator, json_text.ptr(),
json_text.length(), syntaxerr, NULL, json_tree));
ASSERT_TRUE(json_tree != NULL);
ObJsonBin bin(&allocator);
bin.parse_tree(json_tree);
ObString raw_bin;
ASSERT_EQ(OB_SUCCESS, bin.get_raw_binary(raw_bin, &allocator));
gettimeofday(&time_end, nullptr);
cout << "time start : " << " sec = " << time_start.tv_sec << ", usec = " << time_start.tv_usec << endl;
cout << "time end : " << " sec = " << time_end.tv_sec << ", usec = " << time_end.tv_usec << endl;
}
} // namespace common
} // namespace oceanbase
int main(int argc, char** argv)
{
::testing::InitGoogleTest(&argc, argv);
/*
system("rm -f test_json_tree.log");
OB_LOGGER.set_file_name("test_json_tree.log");
OB_LOGGER.set_log_level("INFO");
*/
return RUN_ALL_TESTS();
}