From 1b37ef03fb10a55ab58e25ff585a622cc3202931 Mon Sep 17 00:00:00 2001 From: wangjiaming0909 <604227650@qq.com> Date: Sun, 7 Apr 2024 17:24:01 +0800 Subject: [PATCH] fix duplicate tsma funcs --- include/common/tcommon.h | 1 + include/libs/nodes/nodes.h | 2 +- source/dnode/mnode/impl/src/mndSma.c | 8 ++- source/libs/nodes/src/nodesUtilFuncs.c | 4 +- source/libs/nodes/test/nodesTestMain.cpp | 9 +++- source/libs/parser/src/parTranslater.c | 64 ++++++++++++++++++------ 6 files changed, 66 insertions(+), 22 deletions(-) diff --git a/include/common/tcommon.h b/include/common/tcommon.h index 58bf4f6365..34f28a8150 100644 --- a/include/common/tcommon.h +++ b/include/common/tcommon.h @@ -416,6 +416,7 @@ int32_t taosGenCrashJsonMsg(int signum, char **pMsg, int64_t clusterId, int64_t #define TSMA_RES_STB_POSTFIX "_tsma_res_stb_" #define MD5_OUTPUT_LEN 32 +#define TSMA_RES_STB_EXTRA_COLUMN_NUM 4 // 3 columns: _wstart, _wend, _wduration, 1 tag: tbname static inline bool isTsmaResSTb(const char* stbName) { const char* pos = strstr(stbName, TSMA_RES_STB_POSTFIX); diff --git a/include/libs/nodes/nodes.h b/include/libs/nodes/nodes.h index 503226e4aa..31091928c9 100644 --- a/include/libs/nodes/nodes.h +++ b/include/libs/nodes/nodes.h @@ -170,7 +170,7 @@ int32_t nodesMsgToNode(const char* pStr, int32_t len, SNode** pNode); int32_t nodesNodeToSQL(SNode* pNode, char* buf, int32_t bufSize, int32_t* len); char* nodesGetNameFromColumnNode(SNode* pNode); int32_t nodesGetOutputNumFromSlotList(SNodeList* pSlots); -void nodesSortList(SNodeList** pList, bool (*)(SNode* pNode1, SNode* pNode2)); +void nodesSortList(SNodeList** pList, int32_t (*)(SNode* pNode1, SNode* pNode2)); #ifdef __cplusplus } diff --git a/source/dnode/mnode/impl/src/mndSma.c b/source/dnode/mnode/impl/src/mndSma.c index e19a4c6382..733f3eda8d 100644 --- a/source/dnode/mnode/impl/src/mndSma.c +++ b/source/dnode/mnode/impl/src/mndSma.c @@ -1960,8 +1960,8 @@ static int32_t mndRetrieveTSMA(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlo // create sql pColInfo = taosArrayGet(pBlock->pDataBlock, cols++); char buf[TSDB_SHOW_SQL_LEN + VARSTR_HEADER_SIZE] = {0}; - len = snprintf(buf + 2, TSDB_SHOW_SQL_LEN, "%s", pSma->sql); - varDataSetLen(buf, len); + len = snprintf(buf + VARSTR_HEADER_SIZE, TSDB_SHOW_SQL_LEN, "%s", pSma->sql); + varDataSetLen(buf, TMIN(len, TSDB_SHOW_SQL_LEN)); colDataSetVal(pColInfo, numOfRows, buf, false); // func list @@ -1976,6 +1976,10 @@ static int32_t mndRetrieveTSMA(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlo if (!fmIsTSMASupportedFunc(pFuncNode->funcId)) continue; len += snprintf(start, TSDB_SHOW_SQL_LEN - len, "%s%s", start != buf + VARSTR_HEADER_SIZE ? "," : "", ((SExprNode *)pFunc)->userAlias); + if (len >= TSDB_SHOW_SQL_LEN) { + len = TSDB_SHOW_SQL_LEN; + break; + } start = buf + VARSTR_HEADER_SIZE + len; } } diff --git a/source/libs/nodes/src/nodesUtilFuncs.c b/source/libs/nodes/src/nodesUtilFuncs.c index 2699e9a022..ed6fa39585 100644 --- a/source/libs/nodes/src/nodesUtilFuncs.c +++ b/source/libs/nodes/src/nodesUtilFuncs.c @@ -2649,7 +2649,7 @@ bool nodesIsTableStar(SNode* pNode) { (0 == strcmp(((SColumnNode*)pNode)->colName, "*")); } -void nodesSortList(SNodeList** pList, bool (*comp)(SNode* pNode1, SNode* pNode2)) { +void nodesSortList(SNodeList** pList, int32_t (*comp)(SNode* pNode1, SNode* pNode2)) { if ((*pList)->length == 1) return; uint32_t inSize = 1; @@ -2684,7 +2684,7 @@ void nodesSortList(SNodeList** pList, bool (*comp)(SNode* pNode1, SNode* pNode2) pCell = p; p = p->pNext; --pSize; - } else if (!comp(q->pNode, p->pNode)) { + } else if (comp(q->pNode, p->pNode) >= 0) { pCell = p; p = p->pNext; --pSize; diff --git a/source/libs/nodes/test/nodesTestMain.cpp b/source/libs/nodes/test/nodesTestMain.cpp index 4bfe807d06..4e50595b62 100644 --- a/source/libs/nodes/test/nodesTestMain.cpp +++ b/source/libs/nodes/test/nodesTestMain.cpp @@ -56,11 +56,16 @@ TEST(NodesTest, traverseTest) { nodesDestroyNode(pRoot); } -bool compareValueNode(SNode* pNode1, SNode* pNode2) { +int32_t compareValueNode(SNode* pNode1, SNode* pNode2) { SValueNode* p1 = (SValueNode*)pNode1; SValueNode* p2 = (SValueNode*)pNode2; - return p1->datum.i < p2->datum.i; + if (p1->datum.i < p2->datum.i) + return -1; + else if (p1->datum.i > p2->datum.i) + return 1; + else + return 0; } void assert_sort_result(SNodeList* pList) { diff --git a/source/libs/parser/src/parTranslater.c b/source/libs/parser/src/parTranslater.c index 9811cfbca8..3a260ae6d1 100644 --- a/source/libs/parser/src/parTranslater.c +++ b/source/libs/parser/src/parTranslater.c @@ -10532,16 +10532,49 @@ static SColumnNode* createColumnNodeWithName(const char* name) { return pCol; } -static bool sortFuncWithFuncId(SNode* pNode1, SNode* pNode2) { - SFunctionNode* pFunc1 = (SFunctionNode*)pNode1; - SFunctionNode* pFunc2 = (SFunctionNode*)pNode2; - return pFunc1->funcId < pFunc2->funcId; -} - -static bool sortColWithColId(SNode* pNode1, SNode* pNode2) { +static int32_t compareTsmaColWithColId(SNode* pNode1, SNode* pNode2) { SColumnNode* pCol1 = (SColumnNode*)pNode1; SColumnNode* pCol2 = (SColumnNode*)pNode2; - return pCol1->colId < pCol2->colId; + if (pCol1->colId < pCol2->colId) + return -1; + else if (pCol1->colId > pCol2->colId) + return 1; + else + return 0; +} + +static int32_t compareTsmaFuncWithFuncAndColId(SNode* pNode1, SNode* pNode2) { + SFunctionNode* pFunc1 = (SFunctionNode*)pNode1; + SFunctionNode* pFunc2 = (SFunctionNode*)pNode2; + if (pFunc1->funcId < pFunc2->funcId) + return -1; + else if (pFunc1->funcId > pFunc2->funcId) + return 1; + else { + SNode* pCol1 = pFunc1->pParameterList->pHead->pNode; + SNode* pCol2 = pFunc2->pParameterList->pHead->pNode; + return compareTsmaColWithColId(pCol1, pCol2); + } +} + +// pFuncs are already sorted by funcId and colId +static int32_t deduplicateTsmaFuncs(SNodeList* pFuncs) { + SNode* pLast = NULL; + SNode* pFunc = NULL; + SNodeList* pRes = NULL; + FOREACH(pFunc, pFuncs) { + if (pLast) { + if (compareTsmaFuncWithFuncAndColId(pLast, pFunc) == 0) { + ERASE_NODE(pFuncs); + continue; + } else { + pLast = pFunc; + } + } else { + pLast = pFunc; + } + } + return TSDB_CODE_SUCCESS; } static int32_t buildTSMAAstStreamSubTable(SCreateTSMAStmt* pStmt, SMCreateSmaReq* pReq, const SNode* pTbname, SNode** pSubTable) { @@ -10716,7 +10749,8 @@ static int32_t rewriteTSMAFuncs(STranslateContext* pCxt, SCreateTSMAStmt* pStmt, } } if (TSDB_CODE_SUCCESS == code) { - nodesSortList(&pStmt->pOptions->pFuncs, sortFuncWithFuncId); + nodesSortList(&pStmt->pOptions->pFuncs, compareTsmaFuncWithFuncAndColId); + deduplicateTsmaFuncs(pStmt->pOptions->pFuncs); } return code; } @@ -10737,11 +10771,6 @@ static int32_t buildCreateTSMAReq(STranslateContext* pCxt, SCreateTSMAStmt* pStm return TSDB_CODE_TSMA_INVALID_INTERVAL; } -#define TSMA_RES_STB_EXTRA_COLUMN_NUM 3 - if (LIST_LENGTH(pStmt->pOptions->pFuncs) > TSDB_MAX_COLUMNS - TSMA_RES_STB_EXTRA_COLUMN_NUM) { - return TSDB_CODE_PAR_TOO_MANY_COLUMNS; - } - int32_t code = TSDB_CODE_SUCCESS; STableMeta* pTableMeta = NULL; @@ -10776,7 +10805,7 @@ static int32_t buildCreateTSMAReq(STranslateContext* pCxt, SCreateTSMAStmt* pStm memcpy(pStmt->originalTbName, pRecursiveTsma->tb, TSDB_TABLE_NAME_LEN); tNameExtractFullName(toName(pCxt->pParseCxt->acctId, pStmt->dbName, pRecursiveTsma->tb, useTbName), pReq->stb); numOfCols = pRecursiveTsma->pUsedCols->size; - numOfTags = pRecursiveTsma->pTags ? pRecursiveTsma->pTags->size: 0; + numOfTags = pRecursiveTsma->pTags ? pRecursiveTsma->pTags->size : 0; pCols = pRecursiveTsma->pUsedCols->pData; pTags = pRecursiveTsma->pTags ? pRecursiveTsma->pTags->pData : NULL; code = getTableMeta(pCxt, pStmt->dbName, pRecursiveTsma->targetTb, &pTableMeta); @@ -10803,6 +10832,11 @@ static int32_t buildCreateTSMAReq(STranslateContext* pCxt, SCreateTSMAStmt* pStm if (TSDB_CODE_SUCCESS == code) { code = rewriteTSMAFuncs(pCxt, pStmt, numOfCols, pCols); } + if (TSDB_CODE_SUCCESS == code && !pStmt->pOptions->recursiveTsma) { + if (LIST_LENGTH(pStmt->pOptions->pFuncs) + numOfTags + TSMA_RES_STB_EXTRA_COLUMN_NUM > TSDB_MAX_COLUMNS) { + code = TSDB_CODE_PAR_TOO_MANY_COLUMNS; + } + } if (TSDB_CODE_SUCCESS == code) { code = buildTSMAAst(pCxt, pStmt, pReq, pStmt->pOptions->recursiveTsma ? pRecursiveTsma->targetTb : pStmt->tableName, numOfTags, pTags);