fix duplicate tsma funcs

This commit is contained in:
wangjiaming0909 2024-04-07 17:24:01 +08:00
parent 97498e1844
commit 1b37ef03fb
6 changed files with 66 additions and 22 deletions

View File

@ -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 TSMA_RES_STB_POSTFIX "_tsma_res_stb_"
#define MD5_OUTPUT_LEN 32 #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) { static inline bool isTsmaResSTb(const char* stbName) {
const char* pos = strstr(stbName, TSMA_RES_STB_POSTFIX); const char* pos = strstr(stbName, TSMA_RES_STB_POSTFIX);

View File

@ -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); int32_t nodesNodeToSQL(SNode* pNode, char* buf, int32_t bufSize, int32_t* len);
char* nodesGetNameFromColumnNode(SNode* pNode); char* nodesGetNameFromColumnNode(SNode* pNode);
int32_t nodesGetOutputNumFromSlotList(SNodeList* pSlots); 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 #ifdef __cplusplus
} }

View File

@ -1960,8 +1960,8 @@ static int32_t mndRetrieveTSMA(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlo
// create sql // create sql
pColInfo = taosArrayGet(pBlock->pDataBlock, cols++); pColInfo = taosArrayGet(pBlock->pDataBlock, cols++);
char buf[TSDB_SHOW_SQL_LEN + VARSTR_HEADER_SIZE] = {0}; char buf[TSDB_SHOW_SQL_LEN + VARSTR_HEADER_SIZE] = {0};
len = snprintf(buf + 2, TSDB_SHOW_SQL_LEN, "%s", pSma->sql); len = snprintf(buf + VARSTR_HEADER_SIZE, TSDB_SHOW_SQL_LEN, "%s", pSma->sql);
varDataSetLen(buf, len); varDataSetLen(buf, TMIN(len, TSDB_SHOW_SQL_LEN));
colDataSetVal(pColInfo, numOfRows, buf, false); colDataSetVal(pColInfo, numOfRows, buf, false);
// func list // func list
@ -1976,6 +1976,10 @@ static int32_t mndRetrieveTSMA(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlo
if (!fmIsTSMASupportedFunc(pFuncNode->funcId)) continue; if (!fmIsTSMASupportedFunc(pFuncNode->funcId)) continue;
len += snprintf(start, TSDB_SHOW_SQL_LEN - len, "%s%s", start != buf + VARSTR_HEADER_SIZE ? "," : "", len += snprintf(start, TSDB_SHOW_SQL_LEN - len, "%s%s", start != buf + VARSTR_HEADER_SIZE ? "," : "",
((SExprNode *)pFunc)->userAlias); ((SExprNode *)pFunc)->userAlias);
if (len >= TSDB_SHOW_SQL_LEN) {
len = TSDB_SHOW_SQL_LEN;
break;
}
start = buf + VARSTR_HEADER_SIZE + len; start = buf + VARSTR_HEADER_SIZE + len;
} }
} }

View File

@ -2649,7 +2649,7 @@ bool nodesIsTableStar(SNode* pNode) {
(0 == strcmp(((SColumnNode*)pNode)->colName, "*")); (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; if ((*pList)->length == 1) return;
uint32_t inSize = 1; uint32_t inSize = 1;
@ -2684,7 +2684,7 @@ void nodesSortList(SNodeList** pList, bool (*comp)(SNode* pNode1, SNode* pNode2)
pCell = p; pCell = p;
p = p->pNext; p = p->pNext;
--pSize; --pSize;
} else if (!comp(q->pNode, p->pNode)) { } else if (comp(q->pNode, p->pNode) >= 0) {
pCell = p; pCell = p;
p = p->pNext; p = p->pNext;
--pSize; --pSize;

View File

@ -56,11 +56,16 @@ TEST(NodesTest, traverseTest) {
nodesDestroyNode(pRoot); nodesDestroyNode(pRoot);
} }
bool compareValueNode(SNode* pNode1, SNode* pNode2) { int32_t compareValueNode(SNode* pNode1, SNode* pNode2) {
SValueNode* p1 = (SValueNode*)pNode1; SValueNode* p1 = (SValueNode*)pNode1;
SValueNode* p2 = (SValueNode*)pNode2; 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) { void assert_sort_result(SNodeList* pList) {

View File

@ -10532,16 +10532,49 @@ static SColumnNode* createColumnNodeWithName(const char* name) {
return pCol; return pCol;
} }
static bool sortFuncWithFuncId(SNode* pNode1, SNode* pNode2) { static int32_t compareTsmaColWithColId(SNode* pNode1, SNode* pNode2) {
SFunctionNode* pFunc1 = (SFunctionNode*)pNode1;
SFunctionNode* pFunc2 = (SFunctionNode*)pNode2;
return pFunc1->funcId < pFunc2->funcId;
}
static bool sortColWithColId(SNode* pNode1, SNode* pNode2) {
SColumnNode* pCol1 = (SColumnNode*)pNode1; SColumnNode* pCol1 = (SColumnNode*)pNode1;
SColumnNode* pCol2 = (SColumnNode*)pNode2; 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) { 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) { if (TSDB_CODE_SUCCESS == code) {
nodesSortList(&pStmt->pOptions->pFuncs, sortFuncWithFuncId); nodesSortList(&pStmt->pOptions->pFuncs, compareTsmaFuncWithFuncAndColId);
deduplicateTsmaFuncs(pStmt->pOptions->pFuncs);
} }
return code; return code;
} }
@ -10737,11 +10771,6 @@ static int32_t buildCreateTSMAReq(STranslateContext* pCxt, SCreateTSMAStmt* pStm
return TSDB_CODE_TSMA_INVALID_INTERVAL; 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; int32_t code = TSDB_CODE_SUCCESS;
STableMeta* pTableMeta = NULL; STableMeta* pTableMeta = NULL;
@ -10803,6 +10832,11 @@ static int32_t buildCreateTSMAReq(STranslateContext* pCxt, SCreateTSMAStmt* pStm
if (TSDB_CODE_SUCCESS == code) { if (TSDB_CODE_SUCCESS == code) {
code = rewriteTSMAFuncs(pCxt, pStmt, numOfCols, pCols); 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) { if (TSDB_CODE_SUCCESS == code) {
code = buildTSMAAst(pCxt, pStmt, pReq, pStmt->pOptions->recursiveTsma ? pRecursiveTsma->targetTb : pStmt->tableName, code = buildTSMAAst(pCxt, pStmt, pReq, pStmt->pOptions->recursiveTsma ? pRecursiveTsma->targetTb : pStmt->tableName,
numOfTags, pTags); numOfTags, pTags);