diff --git a/include/libs/nodes/nodes.h b/include/libs/nodes/nodes.h index 777e67769f..2153f59bf8 100644 --- a/include/libs/nodes/nodes.h +++ b/include/libs/nodes/nodes.h @@ -285,6 +285,7 @@ int32_t nodesListPushFront(SNodeList* pList, SNode* pNode); SListCell* nodesListErase(SNodeList* pList, SListCell* pCell); void nodesListInsertList(SNodeList* pTarget, SListCell* pPos, SNodeList* pSrc); SNode* nodesListGetNode(SNodeList* pList, int32_t index); +SListCell* nodesListGetCell(SNodeList* pList, int32_t index); void nodesDestroyList(SNodeList* pList); // Only clear the linked list structure, without releasing the elements inside void nodesClearList(SNodeList* pList); diff --git a/source/libs/nodes/src/nodesUtilFuncs.c b/source/libs/nodes/src/nodesUtilFuncs.c index 57ead2d2ae..1d8baf5373 100644 --- a/source/libs/nodes/src/nodesUtilFuncs.c +++ b/source/libs/nodes/src/nodesUtilFuncs.c @@ -372,6 +372,8 @@ static void destroyScanPhysiNode(SScanPhysiNode* pNode) { static void destroyDataSinkNode(SDataSinkNode* pNode) { nodesDestroyNode((SNode*)pNode->pInputDataBlockDesc); } +static void destroyExprNode(SExprNode* pExpr) { taosArrayDestroy(pExpr->pAssociation); } + void nodesDestroyNode(SNode* pNode) { if (NULL == pNode) { return; @@ -379,9 +381,11 @@ void nodesDestroyNode(SNode* pNode) { switch (nodeType(pNode)) { case QUERY_NODE_COLUMN: // pProjectRef is weak reference, no need to release + destroyExprNode((SExprNode*)pNode); break; case QUERY_NODE_VALUE: { SValueNode* pValue = (SValueNode*)pNode; + destroyExprNode((SExprNode*)pNode); taosMemoryFreeClear(pValue->literal); if (IS_VAR_DATA_TYPE(pValue->node.resType.type)) { taosMemoryFreeClear(pValue->datum.p); @@ -390,14 +394,17 @@ void nodesDestroyNode(SNode* pNode) { } case QUERY_NODE_OPERATOR: { SOperatorNode* pOp = (SOperatorNode*)pNode; + destroyExprNode((SExprNode*)pNode); nodesDestroyNode(pOp->pLeft); nodesDestroyNode(pOp->pRight); break; } case QUERY_NODE_LOGIC_CONDITION: + destroyExprNode((SExprNode*)pNode); nodesDestroyList(((SLogicConditionNode*)pNode)->pParameterList); break; case QUERY_NODE_FUNCTION: + destroyExprNode((SExprNode*)pNode); nodesDestroyList(((SFunctionNode*)pNode)->pParameterList); break; case QUERY_NODE_REAL_TABLE: { @@ -833,6 +840,7 @@ void nodesDestroyNode(SNode* pNode) { destroyPhysiNode((SPhysiNode*)pPhyNode); nodesDestroyList(pPhyNode->pExprs); nodesDestroyList(pPhyNode->pSortKeys); + nodesDestroyList(pPhyNode->pTargets); break; } case QUERY_NODE_PHYSICAL_PLAN_HASH_INTERVAL: @@ -1096,6 +1104,16 @@ SNode* nodesListGetNode(SNodeList* pList, int32_t index) { return NULL; } +SListCell* nodesListGetCell(SNodeList* pList, int32_t index) { + SNode* node; + FOREACH(node, pList) { + if (0 == index--) { + return cell; + } + } + return NULL; +} + void nodesDestroyList(SNodeList* pList) { if (NULL == pList) { return; diff --git a/source/libs/parser/src/parCalcConst.c b/source/libs/parser/src/parCalcConst.c index 495950f35c..dcdf73630f 100644 --- a/source/libs/parser/src/parCalcConst.c +++ b/source/libs/parser/src/parCalcConst.c @@ -183,12 +183,15 @@ static int32_t calcConstProject(SNode* pProject, SNode** pNew) { int32_t size = taosArrayGetSize(pAssociation); for (int32_t i = 0; i < size; ++i) { SNode** pCol = taosArrayGetP(pAssociation, i); + nodesDestroyNode(*pCol); *pCol = nodesCloneNode(*pNew); if (NULL == *pCol) { - return TSDB_CODE_OUT_OF_MEMORY; + code = TSDB_CODE_OUT_OF_MEMORY; + break; } } } + taosArrayDestroy(pAssociation); return code; } diff --git a/source/libs/parser/src/parTranslater.c b/source/libs/parser/src/parTranslater.c index eb767ffa61..424968ac80 100644 --- a/source/libs/parser/src/parTranslater.c +++ b/source/libs/parser/src/parTranslater.c @@ -517,8 +517,9 @@ static int32_t createColumnsByTable(STranslateContext* pCxt, const STableNode* p if (NULL == pCol) { return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_OUT_OF_MEMORY); } - setColumnInfoByExpr(pTable, (SExprNode*)pNode, &pCol); nodesListAppend(pList, (SNode*)pCol); + SListCell* pCell = nodesListGetCell(pList, LIST_LENGTH(pList) - 1); + setColumnInfoByExpr(pTable, (SExprNode*)pNode, (SColumnNode**)&pCell->pNode); } } return TSDB_CODE_SUCCESS; @@ -4658,7 +4659,6 @@ static int32_t extractShowLocalVariablesResultSchema(int32_t* numOfCols, SSchema return TSDB_CODE_SUCCESS; } - int32_t extractResultSchema(const SNode* pRoot, int32_t* numOfCols, SSchema** pSchema) { if (NULL == pRoot) { return TSDB_CODE_SUCCESS; diff --git a/source/libs/planner/src/planPhysiCreater.c b/source/libs/planner/src/planPhysiCreater.c index fc88d46c7b..efb0f790e1 100644 --- a/source/libs/planner/src/planPhysiCreater.c +++ b/source/libs/planner/src/planPhysiCreater.c @@ -1197,6 +1197,9 @@ static int32_t createSortPhysiNode(SPhysiPlanContext* pCxt, SNodeList* pChildren nodesDestroyNode((SNode*)pSort); } + nodesDestroyList(pPrecalcExprs); + nodesDestroyList(pSortKeys); + return code; } diff --git a/source/libs/planner/test/planTestMain.cpp b/source/libs/planner/test/planTestMain.cpp index acac3d5053..43b6bf5772 100644 --- a/source/libs/planner/test/planTestMain.cpp +++ b/source/libs/planner/test/planTestMain.cpp @@ -16,9 +16,11 @@ #include #include + #include "functionMgt.h" #include "getopt.h" #include "mockCatalog.h" +#include "parser.h" #include "planTestUtil.h" class PlannerEnv : public testing::Environment { @@ -30,7 +32,12 @@ class PlannerEnv : public testing::Environment { initLog(TD_TMP_DIR_PATH "td"); } - virtual void TearDown() { destroyMetaDataEnv(); } + virtual void TearDown() { + destroyMetaDataEnv(); + qCleanupKeywordsTable(); + fmFuncMgtDestroy(); + taosCloseLog(); + } PlannerEnv() {} virtual ~PlannerEnv() {} diff --git a/source/libs/planner/test/planTestUtil.cpp b/source/libs/planner/test/planTestUtil.cpp index 57d7cb6608..f1ab9c8196 100644 --- a/source/libs/planner/test/planTestUtil.cpp +++ b/source/libs/planner/test/planTestUtil.cpp @@ -102,12 +102,15 @@ class PlannerTestBaseImpl { try { SQuery* pQuery = nullptr; doParseSql(sql, &pQuery); + unique_ptr query(pQuery, qDestroyQuery); SPlanContext cxt = {0}; setPlanContext(pQuery, &cxt); SLogicSubplan* pLogicSubplan = nullptr; doCreateLogicPlan(&cxt, &pLogicSubplan); + unique_ptr logicSubplan(pLogicSubplan, + (void (*)(SLogicSubplan*))nodesDestroyNode); doOptimizeLogicPlan(&cxt, pLogicSubplan); @@ -115,9 +118,12 @@ class PlannerTestBaseImpl { SQueryLogicPlan* pLogicPlan = nullptr; doScaleOutLogicPlan(&cxt, pLogicSubplan, &pLogicPlan); + unique_ptr logicPlan(pLogicPlan, + (void (*)(SQueryLogicPlan*))nodesDestroyNode); SQueryPlan* pPlan = nullptr; doCreatePhysiPlan(&cxt, pLogicPlan, &pPlan); + unique_ptr plan(pPlan, (void (*)(SQueryPlan*))nodesDestroyNode); dump(g_dumpModule); } catch (...) { @@ -345,8 +351,9 @@ class PlannerTestBaseImpl { } void doCreatePhysiPlan(SPlanContext* pCxt, SQueryLogicPlan* pLogicPlan, SQueryPlan** pPlan) { - SArray* pExecNodeList = taosArrayInit(TARRAY_MIN_SIZE, sizeof(SQueryNodeAddr)); - DO_WITH_THROW(createPhysiPlan, pCxt, pLogicPlan, pPlan, pExecNodeList); + unique_ptr execNodeList((SArray*)taosArrayInit(TARRAY_MIN_SIZE, sizeof(SQueryNodeAddr)), + (void (*)(SArray*))taosArrayDestroy); + DO_WITH_THROW(createPhysiPlan, pCxt, pLogicPlan, pPlan, execNodeList.get()); res_.physiPlan_ = toString((SNode*)(*pPlan)); SNode* pNode; FOREACH(pNode, (*pPlan)->pSubplans) {