From 25997c432f9a7b29b87405132b9275157040b427 Mon Sep 17 00:00:00 2001 From: Yichen Wang <18348405+Aiee@users.noreply.github.com> Date: Sun, 13 Mar 2022 22:06:59 +0800 Subject: [PATCH] Fix crash when use `executeJson()` with profile (#3998) * Fix profile json response * Add UT Co-authored-by: Sophie <84560950+Sophie-Xie@users.noreply.github.com> --- src/common/graph/Response.h | 49 +++++++++++-------- .../graph/tests/ResponseEncodeDecodeTest.cpp | 20 ++++++++ 2 files changed, 49 insertions(+), 20 deletions(-) diff --git a/src/common/graph/Response.h b/src/common/graph/Response.h index ee7c0165bdd..7c4679ef35f 100644 --- a/src/common/graph/Response.h +++ b/src/common/graph/Response.h @@ -185,7 +185,7 @@ namespace nebula { -#define X(EnumName, EnumNumber) EnumName = EnumNumber, +#define X(EnumName, EnumNumber) EnumName = (EnumNumber), enum class ErrorCode { ErrorCodeEnums }; @@ -295,7 +295,9 @@ struct ProfilingStats { ProfilingStatsObj.insert("rows", rows); ProfilingStatsObj.insert("execDurationInUs", execDurationInUs); ProfilingStatsObj.insert("totalDurationInUs", totalDurationInUs); - ProfilingStatsObj.insert("otherStats", folly::toDynamic(*otherStats)); + if (otherStats) { + ProfilingStatsObj.insert("otherStats", folly::toDynamic(*otherStats)); + } return ProfilingStatsObj; } @@ -323,7 +325,7 @@ struct PlanNodeBranchInfo { } // True if loop body or then branch of select - bool isDoBranch{0}; + bool isDoBranch{false}; // select/loop node id int64_t conditionNodeId{-1}; @@ -407,22 +409,29 @@ struct PlanNodeDescription { planNodeDescObj.insert("id", id); planNodeDescObj.insert("outputVar", outputVar); - auto descriptionObj = folly::dynamic::array(); - descriptionObj.resize(description->size()); - std::transform( - description->begin(), description->end(), descriptionObj.begin(), [](const auto &ele) { - return ele.toJson(); - }); - planNodeDescObj.insert("description", descriptionObj); - - auto profilesObj = folly::dynamic::array(); - profilesObj.resize(profiles->size()); - std::transform(profiles->begin(), profiles->end(), profilesObj.begin(), [](const auto &ele) { - return ele.toJson(); - }); - planNodeDescObj.insert("profiles", profilesObj); - planNodeDescObj.insert("branchInfo", branchInfo->toJson()); - planNodeDescObj.insert("dependencies", folly::toDynamic(*dependencies)); + if (description) { + auto descriptionObj = folly::dynamic::array(); + descriptionObj.resize(description->size()); + std::transform( + description->begin(), description->end(), descriptionObj.begin(), [](const auto &ele) { + return ele.toJson(); + }); + planNodeDescObj.insert("description", descriptionObj); + } + if (profiles) { + auto profilesObj = folly::dynamic::array(); + profilesObj.resize(profiles->size()); + std::transform(profiles->begin(), profiles->end(), profilesObj.begin(), [](const auto &ele) { + return ele.toJson(); + }); + planNodeDescObj.insert("profiles", profilesObj); + } + if (branchInfo) { + planNodeDescObj.insert("branchInfo", branchInfo->toJson()); + } + if (dependencies) { + planNodeDescObj.insert("dependencies", folly::toDynamic(*dependencies)); + } return planNodeDescObj; } @@ -536,7 +545,7 @@ struct ExecutionResponse { std::unique_ptr planDesc{nullptr}; std::unique_ptr comment{nullptr}; - // Return the response as a JSON string + // Returns the response as a JSON string // only errorCode and latencyInUs are required fields, the rest are optional // if the dataset contains a value of TIME or DATETIME, it will be returned in UTC. // diff --git a/src/common/graph/tests/ResponseEncodeDecodeTest.cpp b/src/common/graph/tests/ResponseEncodeDecodeTest.cpp index de61bc32de8..1365f2b7f4d 100644 --- a/src/common/graph/tests/ResponseEncodeDecodeTest.cpp +++ b/src/common/graph/tests/ResponseEncodeDecodeTest.cpp @@ -89,6 +89,26 @@ TEST(ResponseEncodeDecodeTest, Basic) { } TEST(ResponseEncodeDecodeTest, ToJson) { + // PlanNodeDescription + { + // Dummy data + PlanNodeDescription pnd; + pnd.name = "name"; + pnd.id = 100; + pnd.outputVar = "outputVar"; + pnd.description = nullptr; + pnd.profiles = nullptr; + pnd.branchInfo = nullptr; + pnd.dependencies = nullptr; + + folly::dynamic jsonObj = pnd.toJson(); + folly::dynamic expect = folly::dynamic::object(); + expect.insert("name", "name"); + expect.insert("id", 100); + expect.insert("outputVar", "outputVar"); + + ASSERT_EQ(jsonObj, expect); + } // plan description { std::vector pds;