From ee16ed17419d5e5fd318aed52142dd61a8caecaa Mon Sep 17 00:00:00 2001 From: Jeremyzz Date: Mon, 8 May 2023 10:01:31 +0800 Subject: [PATCH] Fixed the issue that updating a large amount of data caused the stack to explode Signed-off-by: Jeremyzz --- .../src/common/src/json_common.cpp | 67 ++++++++++--------- .../unittest/api/documentdb_data_test.cpp | 19 ++++++ .../documentdb_json_common_test.cpp | 15 +++++ 3 files changed, 68 insertions(+), 33 deletions(-) diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd_simple/src/common/src/json_common.cpp b/services/distributeddataservice/service/data_share/gaussdb_rd_simple/src/common/src/json_common.cpp index c213f858..9afd81b9 100644 --- a/services/distributeddataservice/service/data_share/gaussdb_rd_simple/src/common/src/json_common.cpp +++ b/services/distributeddataservice/service/data_share/gaussdb_rd_simple/src/common/src/json_common.cpp @@ -189,40 +189,42 @@ bool JsonCommon::CheckProjectionField(JsonObject &jsonObj) int JsonCommon::ParseNode(JsonObject &node, std::vector singlePath, std::vector> &resultPath, bool isFirstFloor) { - std::vector fatherPath; - if (isFirstFloor) { - std::string tempParseName; - std::vector allFiledsName; - std::string priFieldName = node.GetItemFiled(); - for (size_t j = 0; j < priFieldName.size(); j++) { - if (priFieldName[j] != '.') { - tempParseName = tempParseName + priFieldName[j]; - } - if (priFieldName[j] == '.' || j == priFieldName.size() - 1) { - if (j > 0 && priFieldName[j] == '.' && priFieldName[j - 1] == '.') { - return -E_INVALID_ARGS; + while (!node.IsNull()) { + int insertCount = 0; + if (isFirstFloor) { + std::string tempParseName; + std::vector allFiledsName; + std::string priFieldName = node.GetItemFiled(); + for (size_t j = 0; j < priFieldName.size(); j++) { + if (priFieldName[j] != '.') { + tempParseName = tempParseName + priFieldName[j]; + } + if (priFieldName[j] == '.' || j == priFieldName.size() - 1) { + if (j > 0 && priFieldName[j] == '.' && priFieldName[j - 1] == '.') { + return -E_INVALID_ARGS; + } + allFiledsName.emplace_back(tempParseName); + insertCount++; + tempParseName.clear(); } - allFiledsName.emplace_back(tempParseName); - tempParseName.clear(); } + singlePath.insert(singlePath.end(), allFiledsName.begin(), allFiledsName.end()); + } else { + std::vector allFiledsName; + allFiledsName.emplace_back(node.GetItemFiled()); + insertCount++; + singlePath.insert(singlePath.end(), allFiledsName.begin(), allFiledsName.end()); + } + if (!node.GetChild().IsNull() && node.GetChild().GetItemFiled() != "") { + auto nodeNew = node.GetChild(); + ParseNode(nodeNew, singlePath, resultPath, false); + } else { + resultPath.emplace_back(singlePath); } - fatherPath = singlePath; - singlePath.insert(singlePath.end(), allFiledsName.begin(), allFiledsName.end()); - } else { - std::vector allFiledsName; - allFiledsName.emplace_back(node.GetItemFiled()); - fatherPath = singlePath; - singlePath.insert(singlePath.end(), allFiledsName.begin(), allFiledsName.end()); - } - if (!node.GetChild().IsNull() && node.GetChild().GetItemFiled() != "") { - auto nodeNew = node.GetChild(); - ParseNode(nodeNew, singlePath, resultPath, false); - } else { - resultPath.emplace_back(singlePath); - } - if (!node.GetNext().IsNull()) { - auto nodeNew = node.GetNext(); - ParseNode(nodeNew, fatherPath, resultPath, isFirstFloor); + for (int i = 0; i < insertCount; i++) { + singlePath.pop_back(); + } + node = node.GetNext(); } return E_OK; } @@ -526,8 +528,7 @@ int JsonCommon::Append(const JsonObject &src, const JsonObject &add, bool isRepl if (!isCollapse) { bool ret = JsonValueReplace(src, fatherPath, father, item, externErrCode); if (!ret) { - GLOGE("replace faild"); - return false; + return false; // replace faild } isAddedFlag = true; return false; // Different node types, overwrite directly, skip child node diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd_simple/test/unittest/api/documentdb_data_test.cpp b/services/distributeddataservice/service/data_share/gaussdb_rd_simple/test/unittest/api/documentdb_data_test.cpp index 17ff76b7..3eede65d 100644 --- a/services/distributeddataservice/service/data_share/gaussdb_rd_simple/test/unittest/api/documentdb_data_test.cpp +++ b/services/distributeddataservice/service/data_share/gaussdb_rd_simple/test/unittest/api/documentdb_data_test.cpp @@ -22,6 +22,7 @@ #include "grd_document/grd_document_api.h" #include "log_print.h" #include "sqlite_utils.h" +#include "cJSON.h" using namespace DocumentDB; using namespace testing::ext; @@ -257,4 +258,22 @@ HWTEST_F(DocumentDBDataTest, UpdateDataTest006, TestSize.Level0) GLOGD("UpdateDataTest006: update data with flag: %u", flag); EXPECT_EQ(GRD_UpdateDoc(g_db, g_coll, filter.c_str(), document.c_str(), flag), GRD_INVALID_ARGS); } +} + +HWTEST_F(DocumentDBDataTest, UpdateDataTest007, TestSize.Level0) +{ + int result = GRD_OK; + const char *doc = R"({"_id":"007", "field1":{"c_field":{"cc_field":{"ccc_field":1}}}, "field2":2})"; + result = GRD_InsertDoc(g_db,g_coll, doc, 0); + cJSON *updata = cJSON_CreateObject(); + for (int i = 0; i <= 40000; i++) { + string temp = "f" + string(5 - std::to_string(i).size(), '0') + std::to_string(i); + cJSON_AddStringToObject(updata, temp.c_str(), "a"); + } + char *updateStr = cJSON_PrintUnformatted(updata); + result = GRD_UpdateDoc(g_db, g_coll, R""({"_id":"007"})"", updateStr, 0); + EXPECT_EQ(result, 1); + cJSON_Delete(updata); + cJSON_free; + } \ No newline at end of file diff --git a/services/distributeddataservice/service/data_share/gaussdb_rd_simple/test/unittest/oh_adapter/documentdb_json_common_test.cpp b/services/distributeddataservice/service/data_share/gaussdb_rd_simple/test/unittest/oh_adapter/documentdb_json_common_test.cpp index 9c125f7c..10636149 100644 --- a/services/distributeddataservice/service/data_share/gaussdb_rd_simple/test/unittest/oh_adapter/documentdb_json_common_test.cpp +++ b/services/distributeddataservice/service/data_share/gaussdb_rd_simple/test/unittest/oh_adapter/documentdb_json_common_test.cpp @@ -600,4 +600,19 @@ HWTEST_F(DocumentDBJsonCommonTest, JsonObjectisFilterCheckTest022, TestSize.Leve EXPECT_EQ(JsonCommon::IsJsonNodeMatch(srcObj1, filterObj, errCode), false); EXPECT_EQ(JsonCommon::IsJsonNodeMatch(srcObj2, filterObj, errCode), true); } + +HWTEST_F(DocumentDBJsonCommonTest, JsonObjectisFilterCheckTest023, TestSize.Level0) +{ + std::string document = "{\"name\": 1, \"personInfo.school\": 1, \"personInfo.age\": 1}"; + int errCode = E_OK; + JsonObject srcObj = JsonObject::Parse(document, errCode); + EXPECT_EQ(errCode, E_OK); + auto path = JsonCommon::ParsePath(srcObj, errCode); + for (auto singlePath : path) { + for (auto filedName : singlePath) { + GLOGE("filedName is =========>%s", filedName.c_str()); + } + GLOGE("///////////////////////////"); + } +} } \ No newline at end of file -- Gitee