From a53d1d95fb6e1cd8e543b509143dc8d4e7536bc3 Mon Sep 17 00:00:00 2001 From: Liu Jicong Date: Mon, 27 Dec 2021 20:45:30 +0800 Subject: [PATCH 1/2] add dag serialize and deserialize --- include/libs/planner/planner.h | 8 +++- source/libs/planner/src/physicalPlanJson.c | 50 ++++++++++++++++++++++ 2 files changed, 57 insertions(+), 1 deletion(-) diff --git a/include/libs/planner/planner.h b/include/libs/planner/planner.h index b3262953b5..f9c25c3ccc 100644 --- a/include/libs/planner/planner.h +++ b/include/libs/planner/planner.h @@ -21,6 +21,7 @@ extern "C" { #endif #include "tmsg.h" +#include "tarray.h" #define QUERY_TYPE_MERGE 1 #define QUERY_TYPE_PARTIAL 2 @@ -158,6 +159,8 @@ int32_t qStringToSubplan(const char* str, SSubplan** subplan); void qDestroySubplan(SSubplan* pSubplan); +char* qDagSerialize(const SQueryDag* pDag); + /** * Destroy the physical plan. * @param pQueryPhyNode @@ -165,8 +168,11 @@ void qDestroySubplan(SSubplan* pSubplan); */ void qDestroyQueryDag(SQueryDag* pDag); +char* qDagToString(const SQueryDag* pDag); +SQueryDag* qStringToDag(const char* pStr); + #ifdef __cplusplus } #endif -#endif /*_TD_PLANNER_H_*/ \ No newline at end of file +#endif /*_TD_PLANNER_H_*/ diff --git a/source/libs/planner/src/physicalPlanJson.c b/source/libs/planner/src/physicalPlanJson.c index 5a1b2a6da2..945c354284 100644 --- a/source/libs/planner/src/physicalPlanJson.c +++ b/source/libs/planner/src/physicalPlanJson.c @@ -857,3 +857,53 @@ int32_t stringToSubplan(const char* str, SSubplan** subplan) { *subplan = subplanFromJson(json); return (NULL == *subplan ? TSDB_CODE_FAILED : TSDB_CODE_SUCCESS); } + +cJSON* qDagToJson(const SQueryDag* pDag) { + cJSON* pRoot = cJSON_CreateObject(); + cJSON_AddNumberToObject(pRoot, "numOfSubplans", pDag->numOfSubplans); + cJSON_AddNumberToObject(pRoot, "queryId", pDag->queryId); + cJSON *pLevels = cJSON_CreateArray(); + cJSON_AddItemToObject(pRoot, "pSubplans", pLevels); + size_t level = taosArrayGetSize(pDag->pSubplans); + for(size_t i = 0; i < level; i++) { + const SArray* pSubplans = (const SArray*)taosArrayGetP(pDag->pSubplans, i); + size_t num = taosArrayGetSize(pSubplans); + cJSON* plansOneLevel = cJSON_CreateArray(); + cJSON_AddItemToArray(pLevels, plansOneLevel); + for(size_t j = 0; j < num; j++) { + cJSON* pSubplan = subplanToJson((const SSubplan*)taosArrayGetP(pSubplans, j)); + cJSON_AddItemToArray(plansOneLevel, pSubplan); + } + } + return pRoot; +} + +char* qDagToString(const SQueryDag* pDag) { + cJSON* pRoot = qDagToJson(pDag); + return cJSON_Print(pRoot); +} + +SQueryDag* qJsonToDag(const cJSON* pRoot) { + SQueryDag* pDag = malloc(sizeof(SQueryDag)); + if(pDag == NULL) { + return NULL; + } + pDag->numOfSubplans = cJSON_GetNumberValue(cJSON_GetObjectItem(pRoot, "numOfSubplans")); + pDag->pSubplans = taosArrayInit(0, sizeof(SArray)); + cJSON* pLevels = cJSON_GetObjectItem(pRoot, "numOfSubplans"); + int level = cJSON_GetArraySize(pLevels); + for(int i = 0; i < level; i++) { + cJSON* pItem = cJSON_GetArrayItem(pLevels, i); + int sz = cJSON_GetArraySize(pItem); + for(int j = 0; j < sz; j++) { + cJSON* pSubplanJson = cJSON_GetArrayItem(pItem, j); + SSubplan* pSubplan = subplanFromJson(pSubplanJson); + } + } + return NULL; +} + +SQueryDag* qStringToDag(const char* pStr) { + cJSON* pRoot = cJSON_Parse(pStr); + return qJsonToDag(pRoot); +} From d5f5fc00bf2ca9210a1353dd0cabb3905e2adf7a Mon Sep 17 00:00:00 2001 From: Liu Jicong Date: Mon, 27 Dec 2021 20:46:30 +0800 Subject: [PATCH 2/2] add dag serialize and deserialize --- include/libs/planner/planner.h | 4 +-- source/libs/planner/src/physicalPlanJson.c | 37 ++++++++++++++++++++-- source/libs/planner/test/phyPlanTests.cpp | 15 ++++++--- 3 files changed, 46 insertions(+), 10 deletions(-) diff --git a/include/libs/planner/planner.h b/include/libs/planner/planner.h index f9c25c3ccc..3ca923b0aa 100644 --- a/include/libs/planner/planner.h +++ b/include/libs/planner/planner.h @@ -132,7 +132,7 @@ typedef struct SSubplan { typedef struct SQueryDag { uint64_t queryId; int32_t numOfSubplans; - SArray *pSubplans; // Element is SArray*, and nested element is SSubplan. The execution level of subplan, starting from 0. + SArray *pSubplans; // SArray*>. The execution level of subplan, starting from 0. } SQueryDag; struct SQueryNode; @@ -159,8 +159,6 @@ int32_t qStringToSubplan(const char* str, SSubplan** subplan); void qDestroySubplan(SSubplan* pSubplan); -char* qDagSerialize(const SQueryDag* pDag); - /** * Destroy the physical plan. * @param pQueryPhyNode diff --git a/source/libs/planner/src/physicalPlanJson.c b/source/libs/planner/src/physicalPlanJson.c index 945c354284..9b2c9c1796 100644 --- a/source/libs/planner/src/physicalPlanJson.c +++ b/source/libs/planner/src/physicalPlanJson.c @@ -860,18 +860,33 @@ int32_t stringToSubplan(const char* str, SSubplan** subplan) { cJSON* qDagToJson(const SQueryDag* pDag) { cJSON* pRoot = cJSON_CreateObject(); + if(pRoot == NULL) { + return NULL; + } cJSON_AddNumberToObject(pRoot, "numOfSubplans", pDag->numOfSubplans); cJSON_AddNumberToObject(pRoot, "queryId", pDag->queryId); cJSON *pLevels = cJSON_CreateArray(); + if(pLevels == NULL) { + cJSON_Delete(pRoot); + return NULL; + } cJSON_AddItemToObject(pRoot, "pSubplans", pLevels); size_t level = taosArrayGetSize(pDag->pSubplans); for(size_t i = 0; i < level; i++) { const SArray* pSubplans = (const SArray*)taosArrayGetP(pDag->pSubplans, i); size_t num = taosArrayGetSize(pSubplans); cJSON* plansOneLevel = cJSON_CreateArray(); + if(plansOneLevel == NULL) { + cJSON_Delete(pRoot); + return NULL; + } cJSON_AddItemToArray(pLevels, plansOneLevel); for(size_t j = 0; j < num; j++) { cJSON* pSubplan = subplanToJson((const SSubplan*)taosArrayGetP(pSubplans, j)); + if(pSubplan == NULL) { + cJSON_Delete(pRoot); + return NULL; + } cJSON_AddItemToArray(plansOneLevel, pSubplan); } } @@ -889,18 +904,34 @@ SQueryDag* qJsonToDag(const cJSON* pRoot) { return NULL; } pDag->numOfSubplans = cJSON_GetNumberValue(cJSON_GetObjectItem(pRoot, "numOfSubplans")); + pDag->queryId = cJSON_GetNumberValue(cJSON_GetObjectItem(pRoot, "queryId")); pDag->pSubplans = taosArrayInit(0, sizeof(SArray)); - cJSON* pLevels = cJSON_GetObjectItem(pRoot, "numOfSubplans"); + if (pDag->pSubplans == NULL) { + free(pDag); + return NULL; + } + cJSON* pLevels = cJSON_GetObjectItem(pRoot, "pSubplans"); int level = cJSON_GetArraySize(pLevels); for(int i = 0; i < level; i++) { + SArray* plansOneLevel = taosArrayInit(0, sizeof(void*)); + if(plansOneLevel == NULL) { + for(int j = 0; j < i; j++) { + taosArrayDestroy(taosArrayGetP(pDag->pSubplans, j)); + } + taosArrayDestroy(pDag->pSubplans); + free(pDag); + return NULL; + } cJSON* pItem = cJSON_GetArrayItem(pLevels, i); int sz = cJSON_GetArraySize(pItem); for(int j = 0; j < sz; j++) { cJSON* pSubplanJson = cJSON_GetArrayItem(pItem, j); SSubplan* pSubplan = subplanFromJson(pSubplanJson); - } + taosArrayPush(plansOneLevel, &pSubplan); + } + taosArrayPush(pDag->pSubplans, plansOneLevel); } - return NULL; + return pDag; } SQueryDag* qStringToDag(const char* pStr) { diff --git a/source/libs/planner/test/phyPlanTests.cpp b/source/libs/planner/test/phyPlanTests.cpp index d0f6fd5adf..02d06bb49d 100644 --- a/source/libs/planner/test/phyPlanTests.cpp +++ b/source/libs/planner/test/phyPlanTests.cpp @@ -83,7 +83,7 @@ protected: } } - SQueryDag* reslut() { + SQueryDag* result() { return dag_.get(); } @@ -149,16 +149,23 @@ TEST_F(PhyPlanTest, tableScanTest) { pushScan("test", "t1", QNODE_TABLESCAN); ASSERT_EQ(run(), TSDB_CODE_SUCCESS); explain(); - SQueryDag* dag = reslut(); + SQueryDag* dag = result(); // todo check } +TEST_F(PhyPlanTest, serializeTest) { + pushScan("test", "t1", QNODE_TABLESCAN); + ASSERT_EQ(run(), TSDB_CODE_SUCCESS); + SQueryDag* dag = result(); + cout << qDagToString(dag) << endl; +} + // select * from supertable TEST_F(PhyPlanTest, superTableScanTest) { pushScan("test", "st1", QNODE_TABLESCAN); ASSERT_EQ(run(), TSDB_CODE_SUCCESS); explain(); - SQueryDag* dag = reslut(); + SQueryDag* dag = result(); // todo check } @@ -166,6 +173,6 @@ TEST_F(PhyPlanTest, superTableScanTest) { TEST_F(PhyPlanTest, insertTest) { ASSERT_EQ(run("test", "insert into t1 values (now, 1, \"beijing\")"), TSDB_CODE_SUCCESS); explain(); - SQueryDag* dag = reslut(); + SQueryDag* dag = result(); // todo check }