/** * 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 #include "lib/string/ob_sql_string.h" #define private public #include "lib/json_type/ob_json_path.h" #include "lib/json_type/ob_json_bin.h" #undef private using namespace oceanbase::common; class TestJsonPath : public ::testing::Test { public: TestJsonPath() {} ~TestJsonPath() {} virtual void SetUp() {} virtual void TearDown() {} static void SetUpTestCase() {} static void TearDownTestCase() {} private: // disallow copy DISALLOW_COPY_AND_ASSIGN(TestJsonPath); }; TEST_F(TestJsonPath, test_get_cnt) { ObJsonPath path(NULL); ASSERT_EQ(0, path.path_node_cnt()); } TEST_F(TestJsonPath, test_is_mysql_terminator_mysql) { char ch[] = "[. *ibc%^&"; for(int i = 0; i < sizeof(ch); ++i) { if (i <= 3) { ASSERT_EQ(true, ObJsonPathUtil::is_mysql_terminator(ch[i])); } else { ASSERT_EQ(false, ObJsonPathUtil::is_mysql_terminator(ch[i])); } } } // 测试 basicNode的构造函数 TEST_F(TestJsonPath, test_create_basic_node) { ObArenaAllocator allocator(ObModIds::TEST); // ** ObJsonPathBasicNode temp1(&allocator); ASSERT_EQ(0, temp1.init(JPN_WILDCARD_ELLIPSIS, true)); ASSERT_EQ(JPN_WILDCARD_ELLIPSIS, temp1.get_node_type()); ASSERT_EQ(true, temp1.node_content_.is_had_wildcard_); // .* ObJsonPathBasicNode temp2(&allocator); ASSERT_EQ(0, temp2.init(JPN_MEMBER_WILDCARD, true)); ASSERT_EQ(JPN_MEMBER_WILDCARD, temp2.get_node_type()); ASSERT_EQ(true, temp2.node_content_.is_had_wildcard_); // [*] ObJsonPathBasicNode temp3(&allocator); ASSERT_EQ(0, temp3.init(JPN_ARRAY_CELL_WILDCARD, true)); ASSERT_EQ(JPN_ARRAY_CELL_WILDCARD, temp3.get_node_type()); ASSERT_EQ(true, temp3.node_content_.is_had_wildcard_); // [1] ObJsonPathBasicNode temp4(&allocator,1,false); ASSERT_EQ(JPN_ARRAY_CELL, temp4.get_node_type()); ASSERT_EQ(1, temp4.node_content_.array_cell_.index_); ASSERT_EQ(false, temp4.node_content_.array_cell_.is_index_from_end_); // [last-3 to 6] ObJsonPathBasicNode temp5(&allocator,3, true, 6, false); ASSERT_EQ(JPN_ARRAY_RANGE, temp5.get_node_type()); ASSERT_EQ(3, temp5.node_content_.array_range_.first_index_); ASSERT_EQ(true, temp5.node_content_.array_range_.is_first_index_from_end_); ASSERT_EQ(6, temp5.node_content_.array_range_.last_index_); ASSERT_EQ(false, temp5.node_content_.array_range_.is_last_index_from_end_); // .keyname ObString kn("keyname"); ObJsonPathBasicNode temp6(&allocator,kn); ASSERT_EQ(JPN_MEMBER, temp6.get_node_type()); std::cout< (fa1))->get_node_type()); ASSERT_EQ(true, fa1->node_content_.is_had_wildcard_); } // 测试 append函数 TEST_F(TestJsonPath, test_append) { // append ** int ret = OB_SUCCESS; ObArenaAllocator allocator(ObModIds::TEST); ObJsonPath test_path(&allocator); ObJsonPathBasicNode temp1(&allocator); ASSERT_EQ(0, temp1.init(JPN_WILDCARD_ELLIPSIS, true)); ObJsonPathNode *fa1 = &temp1; ret = test_path.append(fa1); ASSERT_EQ(OB_SUCCESS,ret); ASSERT_EQ(JPN_WILDCARD_ELLIPSIS, test_path.path_nodes_[0]->get_node_type()); ASSERT_EQ(true, test_path.path_nodes_[0]->node_content_.is_had_wildcard_); // append .* ObJsonPathBasicNode temp2(&allocator); ASSERT_EQ(0, temp2.init(JPN_MEMBER_WILDCARD, true)); ObJsonPathNode *fa2 = &temp2; ret = test_path.append(fa2); ASSERT_EQ(OB_SUCCESS,ret); ASSERT_EQ(JPN_MEMBER_WILDCARD, test_path.path_nodes_[1]->get_node_type()); ASSERT_EQ(true, test_path.path_nodes_[1]->node_content_.is_had_wildcard_); // append [*] ObJsonPathBasicNode temp3(&allocator); ASSERT_EQ(0, temp3.init(JPN_ARRAY_CELL_WILDCARD, true)); ObJsonPathNode *fa3 = &temp3; ret = test_path.append(fa3); ASSERT_EQ(OB_SUCCESS,ret); ASSERT_EQ(JPN_ARRAY_CELL_WILDCARD, test_path.path_nodes_[2]->get_node_type()); ASSERT_EQ(true, test_path.path_nodes_[2]->node_content_.is_had_wildcard_); // append array_cell ObJsonPathBasicNode temp4(&allocator,1,false); ObJsonPathNode *fa4 = &temp4; ret = test_path.append(fa4); ASSERT_EQ(OB_SUCCESS,ret); ASSERT_EQ(JPN_ARRAY_CELL, test_path.path_nodes_[3]->get_node_type()); ASSERT_EQ(1, test_path.path_nodes_[3]->node_content_.array_cell_.index_); ASSERT_EQ(false, test_path.path_nodes_[3]->node_content_.array_cell_.is_index_from_end_); // [last-3 to 6] ObJsonPathBasicNode temp5(&allocator,3, true, 6, false); ObJsonPathNode *fa5 = &temp5; ret = test_path.append(fa5); ASSERT_EQ(OB_SUCCESS,ret); ASSERT_EQ(JPN_ARRAY_RANGE, test_path.path_nodes_[4]->get_node_type()); ASSERT_EQ(3, test_path.path_nodes_[4]->node_content_.array_range_.first_index_); ASSERT_EQ(true, test_path.path_nodes_[4]->node_content_.array_range_.is_first_index_from_end_); ASSERT_EQ(6, test_path.path_nodes_[4]->node_content_.array_range_.last_index_); ASSERT_EQ(false, test_path.path_nodes_[4]->node_content_.array_range_.is_last_index_from_end_); // .keyname ObString kn("keyname"); ObJsonPathBasicNode temp6(&allocator,kn); ObJsonPathNode *fa6 = &temp6; ret = test_path.append(fa6); ASSERT_EQ(OB_SUCCESS,ret); ASSERT_EQ(JPN_MEMBER, test_path.path_nodes_[5]->get_node_type()); std::cout<<"6: "<node_content_.member_.object_name_<node_type); //ASSERT_EQ(10, test_path1.path_nodes_[0]->path_node_content_.array_cell_.index_); //ASSERT_EQ(false, test_path1.path_nodes_[0]->path_node_content_.array_cell_.index_); } // 测试能否正确解析array_cell_node TEST_F(TestJsonPath, test_array_cell_node) { int ret = OB_SUCCESS; ObArenaAllocator allocator(ObModIds::TEST); ObJsonPath test_path("$[last-10]", &allocator); test_path.is_mysql_ = false; if(test_path.is_mysql_ == false){ std::cout<<"oracle"<get_node_type()); ASSERT_EQ(10, test_path.path_nodes_[0]->node_content_.multi_array_[0]->first_index_); ASSERT_EQ(true,test_path.path_nodes_[0]->node_content_.multi_array_[0]->is_first_index_from_end_); ASSERT_EQ(10, test_path.path_nodes_[0]->node_content_.multi_array_[0]->last_index_); ASSERT_EQ(true,test_path.path_nodes_[0]->node_content_.multi_array_[0]->is_last_index_from_end_); } // 测试能否正确解析array_range_node TEST_F(TestJsonPath, test_array_range_node) { int ret = OB_SUCCESS; ObArenaAllocator allocator(ObModIds::TEST); ObJsonPath test_path("$[1 to 10]", &allocator); test_path.is_mysql_ = false; if(test_path.is_mysql_ == false){ std::cout<<"oracle"<get_node_type()); ASSERT_EQ(1, test_path.path_nodes_[0]->node_content_.multi_array_[0]->first_index_); ASSERT_EQ(false,test_path.path_nodes_[0]->node_content_.multi_array_[0]->is_first_index_from_end_); ASSERT_EQ(10, test_path.path_nodes_[0]->node_content_.multi_array_[0]->last_index_); ASSERT_EQ(false,test_path.path_nodes_[0]->node_content_.multi_array_[0]->is_last_index_from_end_); } TEST_F(TestJsonPath, test_multi_array_node) { int ret = OB_SUCCESS; ObArenaAllocator allocator(ObModIds::TEST); ObJsonPath test_path("$[last - 10, 1 to 10]", &allocator); test_path.is_mysql_ = false; if(test_path.is_mysql_ == false){ std::cout<<"oracle"<get_node_type()); ASSERT_EQ(2, test_path.path_nodes_[0]->node_content_.multi_array_.size()); ASSERT_EQ(10, test_path.path_nodes_[0]->node_content_.multi_array_[0]->first_index_); ASSERT_EQ(true,test_path.path_nodes_[0]->node_content_.multi_array_[0]->is_first_index_from_end_); ASSERT_EQ(10, test_path.path_nodes_[0]->node_content_.multi_array_[0]->last_index_); ASSERT_EQ(true,test_path.path_nodes_[0]->node_content_.multi_array_[0]->is_last_index_from_end_); ASSERT_EQ(1, test_path.path_nodes_[0]->node_content_.multi_array_[1]->first_index_); ASSERT_EQ(false,test_path.path_nodes_[0]->node_content_.multi_array_[1]->is_first_index_from_end_); ASSERT_EQ(10, test_path.path_nodes_[0]->node_content_.multi_array_[1]->last_index_); ASSERT_EQ(false,test_path.path_nodes_[0]->node_content_.multi_array_[1]->is_last_index_from_end_); } TEST_F(TestJsonPath, test_filter_node) { int ret = OB_SUCCESS; ObArenaAllocator allocator(ObModIds::TEST); ObString str1("$?(@.LineItems[*].*..\"Part\".Description like \"Nixon\")"); ObJsonPath test_path(str1, &allocator); test_path.is_mysql_ = false; if(test_path.is_mysql_ == false){ std::cout<<"oracle"<= test_path.expression_.length()){ std::cout<<"end of path"<get_node_type()< 2016) 30. $.friends[3].cars[0]?(@.year.number() > 2016) 31. $.friends[3].cars[0]?(@.year.numberOnly() > 2016) 32. $.friends[3]?(@.addresses.city == \"San Francisco\") 33. $.friends[*].addresses?(@.addresses.city starts with \"San \") 34. $.friends[3]?(@.addresses.city == \"San Francisco\" && @.addresses.state == \"Nevada\") 35. $.friends[3].addresses?(@.city == \"San Francisco\" && @.state == \"Nevada\") 36. $?(@.LineItems.Part.UPCCode == 85391628927 && @.LineItems.Quantity > 3) 37. $?(@.User == \"ABULL\" && exists(@.LineItems[*]?(@.Part.UPCCode == 85391628927 && @.Quantity > 3))) */ /* 比较谓词 // node_to_string 所得字符串不会有多余的空格 38. $.friends[*].addresses?(@.addresses.city starts with \"San \") 39. $.friends[*].addresses?(@.addresses.city has substring \"San \") 40. $.friends[*].addresses?(@.addresses.city has substring \"San \") 41. $.friends[*].addresses?(@.addresses.city like \"San \") 42. $.friends[*].addresses?(@.addresses.city like \"San \") 43. $.friends[*].addresses?(@.addresses.city like_regex \"San \") 44. $.friends[*].addresses?(@.addresses.city like_regex \"San \") 45. $.friends[*].addresses?(@.addresses.city eq_regex \"San \") 46. $?(@.User == \"ABULL\" && exists(@.LineItems[*]?(@.Part.UPCCode == 85391628927 && @.Quantity > 3))) 47. $?(@.User == \"ABULL\" && exists (@.LineItems[*]?(@.Part.UPCCode == 85391628927 && @.Quantity > 3))) 48. $?(@.User == \"ABULL\" && !exists(@.LineItems[*]?(@.Part.UPCCode == 85391628927 && @.Quantity > 3))) 49. $?(@.User == \"ABULL\" && !exists (@.LineItems[*]?(@.Part.UPCCode == 85391628927 && @.Quantity > 3))) 50. $?(@.User == \"ABULL\" && ! exists(@.LineItems[*]?(@.Part.UPCCode == 85391628927 && @.Quantity > 3))) 51. $.friends[3].cars[0]?(@.year.number() > 2016) 52. $.friends[3].cars[0]?(@.year.number() > 2016 ) 53. $.friends[3].cars[0]?(@.year.number() > 2016.1) 54. $.friends[3].cars[0]?(@.year.number() > -2016.1) 55. $.friends[3].cars[0]?(@.year.number() > -4294967295) 56. $.friends[3].cars[0]?(@.year.number() < 2016) 57. $.friends[3].cars[0]?(@.year.number() >= 2016) 58. $.friends[3].cars[0]?(@.year.number() <= 2016) 59. $.friends[3].cars[0]?(@.year.number() == 2016) 60. $.friends[3].cars[0]?(@.year.number() != 2016) 61. $.friends[3].cars[0]?(@.year.number() != 2016 && @.year.number() > 2016) 62. $.friends[3].cars[0]?(@.year.number() != 2016 || @.year.number() > 2016) 63. $.friends[3].cars[0]?(@.year.number() != 2016 && !(@.year.number() > 2016)) 64. $.friends[3].cars[0]?(@.year.number() == 2016 || @.year.number() != 2016 && !(@.year.number() > 2016)) 65. $.friends[3].cars[0]?((@.year.number() == 2016 || @.year.number() != 2016) && !(@.year.number() > 2016)) 66. $.friends[3].cars[0]?(@.year.date() == "2022-8-22") 67. $.friends[3].cars[0]?(@.year.date() == "2022-8-22" ) 68. $.LineItems.Part?(@.UPCCode == $v1) 69. $.LineItems.Part?(@.UPCCode == $v1 ) 70. $.LineItems.Part?(@.UPCCode == true) 71. $.LineItems.Part?(@.UPCCode == true ) 72. $.LineItems.Part?(@.UPCCode == false) 73. $.LineItems.Part?(@.UPCCode == false ) 74. $.LineItems.Part?(@.UPCCode == null) 75. $.LineItems.Part?(2016 == 2016) 76. $.LineItems.Part?(\"San \" == \"San \") 77. $.LineItems.Part?(2016 == @.UPCCode) 78. $.LineItems.Part?( 2016 == @.UPCCode) 79. $.LineItems.Part?($v1 == @.UPCCode) 80. $.LineItems.Part?( $v1 == @.UPCCode) 81. $.LineItems.Part?( \"San \" == @.UPCCode) 82. $?(@.LineItems[*].*..Part.Description like \"Nixon\" && $v1 == @.UPCCode) 83. $.friends[ * ]. addresses?(@.addresses.city has substring \"San \") 84. $.friends[*].addresses?(\"San \" has substring @.addresses.city) 85. $.friends[*].addresses?(@.addresses.city has substring $v1) 86. $.LineItems.Part?(\"San \" has substring \"San \") 87. $.friends[*].addresses?(@.addresses.city like_regex $v1) 88. $.friends[*].addresses?(@.addresses.city starts with $v1) 89. $.friends[*].addresses?(@.addresses.city starts with $v1) 90. $.friends[*].addresses ?(@.addresses.city starts with $v1) 91. $.friends[*].addresses ? (@.addresses.city starts with $v1) 比较符号(==, !=, >, ...)两端的组合可以为如下组合: (标量,标量), (标量,subpath) (subpath,标量), (subpath,变量), (变量,subpath) 除此之外均为非法 但是starts with, has substring 等限制更多,只能是以下组合: (subpath, str), (subpath, 变量), (str, str) */ int ret = OB_SUCCESS; ObArenaAllocator allocator(ObModIds::TEST); ObString str0("$?(@.UPCCode.number() >= $v1 && @.addresses.city starts with $v1)"); ObString str1("$?(@.UPCCode.number() >= $v1 && @.addresses.city starts with $v1)"); ObJsonPath test_path(str0, &allocator); test_path.is_mysql_ = false; if(test_path.is_mysql_ == false){ std::cout<<"oracle"<= test_path.expression_.length()){ std::cout<<"end of path"< 2016) 24. $.friends[*].addresses?(@.addresses.city starts with \"San ) 25. $.friends[3].cars[0]?(@.year.number( > 2016) 26. $.friends[*].addresses?(@.addresses.city start with \"San \") 27. $.friends[*].addresses?(@.addresses.city had substring \"San \") 28. $.friends[*].addresses?(@.addresses.city likes \"San \") 29. $.friends[*].addresses?(@.addresses.city like-regex \"San \") 30. $.friends[*].addresses?(@.addresses.city like _regex \"San \") 31. $.friends[*].addresses?(@.addresses.city eq_Regex \"San \") 32. $?(@.User == \"ABULL\" && exist(@.LineItems[*]?(@.Part.UPCCode == 85391628927 && @.Quantity > 3))) 33. $?(@.User == \"ABULL\" && exist @.LineItems[*]?(@.Part.UPCCode == 85391628927 && @.Quantity > 3)) 34. $?(@.User == \"ABULL\" && !exist(@.LineItems[*]?(@.Part.UPCCode == 85391628927 && @.Quantity > 3))) 35. $.friends[3].cars[0]?(@.year.number() > 201 6) 36. $.friends[3].cars[0]?(@.year.number() > ) 37. $.friends[3].cars[0]?(> 201) 38. $.friends[3].cars[0]?(@.year.number() > 201.6.1) 39. $.friends[3].cars[0]?(@.year.number() > --2016.1) 40. $.friends[3].cars[0]?(@.year.number() > +4294967295) 41. $.friends[3].cars[0]?(@.year.number() < 2-016) 42. $.friends[3].cars[0]?(@.year.number() > = 2016) 43. $.friends[3].cars[0]?(@.year.number() < = 2016) 44. $.friends[3].cars[0]?(@.year.number() = = 2016) 45. $.friends[3].cars[0]?(@.year.number() ! = 2016) 46. $.friends[3].cars[0]?(@.year.number() != 2016 & & @.year.number() > 2016) 47. $.friends[3].cars[0]?(@.year.number() != 2016 | | @.year.number() > 2016) 48. $.friends[3].cars[0]?(@.year.number() != 2016 && !@.year.number() > 2016) 49. $.friends[3].cars[0]?(@.year.date() == \"2022-8-22 ) 50. $.LineItems.Part?(@.UPCCode == $ v1) 51. $.LineItems.Part?(@.UPCCode == TRUE) 52. $.LineItems.Part?(@.UPCCode == False) 53. $.LineItems.Part?(@.UPCCode == NULL) 括号不匹配/不合法 54. $.LineItems.Part?(@.UPCCode == null)) 55. $.LineItems.Part?((@.UPCCode == null) 56. $.LineItems.Part?(@.UPCCode == null()) 57. $.LineItems.Part?([@.UPCCode == $ v1]) 58. $.LineItems.Part?(@.UPCCode == $v1 59. $.LineItems.Part?@.UPCCode == $v1) 60. $.LineItems.Part?()(@.UPCCode == $v1) 不合法的变量名 61. $.LineItems.Part?([@.UPCCode == $1v]) 62. $.LineItems.Part?([@.UPCCode == $v@]) 63. $.LineItems.Part?([@.UPCCode == $v**]) 64. $.LineItems.Part?(@.UPCCode == $(v1)) 65. $.LineItems.Part?(@.UPCCode == $\"v1\") 不合法的组合 66. $.LineItems.Part?(2016 == $v1) 67. $.LineItems.Part?(\"abc\" == $v1) 68. $.LineItems.Part?(true == $v1) 69. $.LineItems.Part?( $v1 == 2016) 70. $.LineItems.Part?( $v1 == \"abc\") 71. $.LineItems.Part?( $v1 == false) 72. $.LineItems.Part?( $v1 == $v4) 73. $.LineItems.Part?(@.UPCCode == @.UPCCode) 74. $.friends[*].addresses?(@.city like_regex 1234) 75. $.friends[*].addresses?(@.city like_regex false) 76. $.friends[*].addresses?(@.city eq_regex true) 77. $.friends[*].addresses?(@.city like null) 78. $.friends[*].addresses?(@.city like_regex @.UPCCode) 79. $.LineItems.Part?( $v1 starts with @.city) 80. $.LineItems.Part?( $v1 starts with $v1) 81. $.LineItems.Part?( $v1 starts with \"abc\") 82. $.LineItems.Part?( $v1 starts with 123.5) 83. $.LineItems.Part?( $v1 starts with true) 84. $.LineItems.Part?( \"abc\" starts with $friends) 85. $.LineItems.Part?( \"abc\" starts with 123.5) 86. $.LineItems.Part?( \"abc\" starts with true) 87. $.LineItems.Part?(true starts with true) 88. $.LineItems.Part?( true starts with $friends) 89. $.LineItems.Part?( 12345 starts with $friends) 90. $.LineItems.Part?( true starts with @.city) 91. $.LineItems.Part?( 12345 starts with @.city) 92. $?(exists(85391628927 == 85391628927)) 93. $?(exists($v1 == 85391628927)) 94. $?(exists($v1 == $v1)) 95. $?(exists($v1 == \"abc\")) 96. $?(exists($v1 == true)) 97. $?(exists(\"abc\" == \"abc\")) 98. $?(exists(\"abc\" has substring \"abc\")) 99. $?(exists(\"abc\" starts with \"abc\")) 100. $?(exists(true == true)) 101. $?(exists(true != true)) 102. $.LineItems.Part?(@.UPCCode[1-] == null) 103. $.LineItems.Part?(@.UPCCode[1].. == null) 104. $.LineItems.Part?(@.UPCCode[1]...abc == null) 105. $.LineItems.Part?(@.UPCCode[1, ] == null) 106. $.friends[3].cars[0]?(@.year.number() != 2016 &| @.year.number() > 2016) 107. $.friends[3].cars[0]?(@.year.number() != 2016 !& @.year.number() > 2016) 108. $.friends[3].cars[0]?(@.year.number() != 2016 && !)@.year.number() > 2016)) 109. $.friends[3].cars[0]?(@.year.number() != 2016 && !(&&@.year.number() > 2016)) 110. $.friends[3].cars[0]?(@.year.number() == 2016 || && @.year.number() != 2016 && !(@.year.number() > 2016)) */ int ret = OB_SUCCESS; ObString str = "$.friends[3].cars[0]?(@.year.number() == 2016 || && @.year.number() != 2016 && !(@.year.number() > 2016))"; ObArenaAllocator allocator(ObModIds::TEST); ObJsonPath test_path(str, &allocator); test_path.is_mysql_ = false; if(test_path.is_mysql_ == false){ std::cout<<"oracle"<= test_path.expression_.length()){ std::cout<<"end of path"<get_node_type()); ASSERT_EQ(JPN_TYPE,test_path.path_nodes_[1]->get_node_type()); } // 测试能否正确解析array_range_wildcard_node TEST_F(TestJsonPath, test_array_wildcard_node) { int ret = OB_SUCCESS; ObArenaAllocator allocator(ObModIds::TEST); ObJsonPath test_path("$[*]", &allocator); test_path.is_mysql_ = false; if(test_path.is_mysql_ == false){ std::cout<<"oracle"<get_node_type()); } // 测试能否正确解析member_wildcard_node TEST_F(TestJsonPath, test_member_wildcard_node) { int ret = OB_SUCCESS; ObArenaAllocator allocator(ObModIds::TEST); ObJsonPath test_path("$.*", &allocator); test_path.is_mysql_ = false; ret = test_path.parse_path(); if(test_path.is_mysql_ == false){ std::cout<<"oracle"<get_node_type()); } // 测试能否正确解析member_node TEST_F(TestJsonPath, test_member_node) { int ret = OB_SUCCESS; ObString str_orgin("$.name"); ObArenaAllocator allocator(ObModIds::TEST); ObJsonPath test_path(str_orgin, &allocator); test_path.is_mysql_ = false; if(test_path.is_mysql_ == false){ std::cout<<"oracle"<get_node_type()); const auto &member = test_path.path_nodes_[0]->node_content_.member_; ObString str(member.len_, member.object_name_); ASSERT_TRUE(str.case_compare("name") == 0); std::cout<node_content_.member_.object_name_<get_node_type()); ASSERT_EQ(JPN_ARRAY_CELL,test_path.path_nodes_[1]->get_node_type()); ASSERT_EQ(10,test_path.path_nodes_[1]->node_content_.array_cell_.index_); ASSERT_EQ(false,test_path.path_nodes_[1]->node_content_.array_cell_.is_index_from_end_); } // 测试能否成功解析path表达式 TEST_F(TestJsonPath, test_parse_path) { int ret = OB_SUCCESS; ObArenaAllocator allocator(ObModIds::TEST); ObJsonPath test_path("$[last-10 to last-1]", &allocator); ret = test_path.parse_path(); ASSERT_EQ(OB_SUCCESS, ret); // 只有一个节点 ASSERT_EQ(1, test_path.path_node_cnt()); if (OB_SUCC(ret)) { for(int i=0; inode_type); std::cout<node_type); /* ASSERT_EQ(JPN_MEMBER,test_path.path_nodes_[i]->node_type); std::cout<node_content_.member_.object_name_<node_type); ASSERT_EQ(10,test_path.path_nodes_[i]->node_content_.array_cell_.index_); ASSERT_EQ(true,test_path.path_nodes_[i]->node_content_.array_cell_.is_index_from_end_); */ ASSERT_EQ(10,test_path.path_nodes_[i]->node_content_.array_range_.first_index_); ASSERT_EQ(true,test_path.path_nodes_[i]->node_content_.array_range_.is_first_index_from_end_); ASSERT_EQ(1,test_path.path_nodes_[i]->node_content_.array_range_.last_index_); ASSERT_EQ(true,test_path.path_nodes_[i]->node_content_.array_range_.is_last_index_from_end_); } } } else { std::cout<<"fail\n"; } } // test tostring // test array_cell node to string TEST_F(TestJsonPath, test_array_cell_node_to_string) { ObArenaAllocator allocator(ObModIds::TEST); ObJsonBuffer str(&allocator); ObJsonPathBasicNode node(&allocator,10, true); node.node_to_string(str, true, false); std::cout<get_node_type()<node_content_.member_.object_name_<node_content_.array_cell_.index_<node_content_.array_cell_.is_index_from_end_<get_path_string().ptr(), read_ok_path1->get_path_string().ptr()); // cache stratety works, iff the path string unchanged, the path needn't parse again ret = path_cache.find_and_add_cache(json_path, ok_path1, ok_path1_idx); ASSERT_EQ(ret, OB_SUCCESS); ASSERT_EQ(json_path, read_ok_path1); ObString ok_path2 = " $.\" abc d \" "; // some spaces do not has any effect upon the path cache ret = path_cache.find_and_add_cache(json_path, ok_path2, ok_path1_idx); ASSERT_EQ(ret, OB_SUCCESS); ASSERT_EQ(json_path, read_ok_path1); ObJsonPath* read_ok_path2 = path_cache.path_at(ok_path1_idx); ASSERT_EQ(read_ok_path2, read_ok_path1); } TEST_F(TestJsonPath, test_pathcache_exprire) { int ret = OB_SUCCESS; ObArenaAllocator allocator(ObModIds::TEST); ObJsonPathCache path_cache(&allocator); ObString ok_path1 = "$.\"abc d\""; // test a nornal json path ObJsonPath* json_path = NULL; int ok_path1_idx = path_cache.size(); // parse a normal path ret = path_cache.find_and_add_cache(json_path, ok_path1, ok_path1_idx); ASSERT_EQ(ret, OB_SUCCESS); ASSERT_EQ(path_cache.path_stat_at(ok_path1_idx), ObPathParseStat::OK_NOT_NULL); ObJsonPath* read_ok_path1 = path_cache.path_at(ok_path1_idx); ObString ok_path2 = " $.\"efs d \""; // some spaces do not has any effect upon the path cache ret = path_cache.find_and_add_cache(json_path, ok_path2, ok_path1_idx); ASSERT_EQ(ret, OB_SUCCESS); // json path string differs, cache invalid ASSERT_NE(json_path, read_ok_path1); ObJsonPath* read_ok_path2 = path_cache.path_at(ok_path1_idx); ASSERT_EQ(read_ok_path2, json_path); } TEST_F(TestJsonPath, test_pathcache_reset) { int ret = OB_SUCCESS; ObArenaAllocator allocator(ObModIds::TEST); ObJsonPathCache path_cache(&allocator); ObString ok_path1 = "$.\"abc d\""; // test a nornal json path ObJsonPath* json_path = NULL; int ok_path1_idx = path_cache.size(); // parse a normal path ret = path_cache.find_and_add_cache(json_path, ok_path1, ok_path1_idx); ASSERT_EQ(ret, OB_SUCCESS); ASSERT_EQ(path_cache.path_stat_at(ok_path1_idx), ObPathParseStat::OK_NOT_NULL); path_cache.reset(); ASSERT_EQ(path_cache.path_stat_at(ok_path1_idx), ObPathParseStat::UNINITIALIZED); ASSERT_EQ(path_cache.size(), 0); } int main(int argc, char** argv) { ::testing::InitGoogleTest(&argc, argv); /* system("rm -f test_json_path.log"); OB_LOGGER.set_file_name("test_json_path.log"); OB_LOGGER.set_log_level("INFO"); */ return RUN_ALL_TESTS(); }