diff --git a/include/util/tdef.h b/include/util/tdef.h index e4af88bf10..a2b014cc7e 100644 --- a/include/util/tdef.h +++ b/include/util/tdef.h @@ -184,6 +184,7 @@ typedef enum ELogicConditionType { #define TSDB_UNI_LEN 24 #define TSDB_USER_LEN TSDB_UNI_LEN +#define TSDB_POINTER_PRINT_BYTES 18 // 0x1122334455667788 // ACCOUNT is a 32 bit positive integer // this is the length of its string representation, including the terminator zero #define TSDB_ACCT_ID_LEN 11 @@ -223,6 +224,7 @@ typedef enum ELogicConditionType { #define TSDB_SUBSCRIBE_KEY_LEN (TSDB_CGROUP_LEN + TSDB_TOPIC_FNAME_LEN + 2) #define TSDB_PARTITION_KEY_LEN (TSDB_SUBSCRIBE_KEY_LEN + 20) #define TSDB_COL_NAME_LEN 65 +#define TSDB_COL_FNAME_LEN (TSDB_TABLE_NAME_LEN + TSDB_COL_NAME_LEN + TSDB_NAME_DELIMITER_LEN) #define TSDB_MAX_SAVED_SQL_LEN TSDB_MAX_COLUMNS * 64 #define TSDB_MAX_SQL_LEN TSDB_PAYLOAD_SIZE #define TSDB_MAX_SQL_SHOW_LEN 1024 diff --git a/include/util/tutil.h b/include/util/tutil.h index a2cfa4cfe5..de2cd205f2 100644 --- a/include/util/tutil.h +++ b/include/util/tutil.h @@ -79,6 +79,20 @@ static FORCE_INLINE void taosEncryptPass_c(uint8_t *inBuf, size_t len, char *tar memcpy(target, buf, TSDB_PASSWORD_LEN); } +static FORCE_INLINE int32_t taosCreateMD5Hash(char *pBuf, int32_t len) { + T_MD5_CTX ctx; + tMD5Init(&ctx); + tMD5Update(&ctx, (uint8_t*)pBuf, len); + tMD5Final(&ctx); + char* p = pBuf; + int32_t resLen = 0; + for (uint8_t i = 0; i < tListLen(ctx.digest); ++i) { + resLen += snprintf(p, 3, "%02x", ctx.digest[i]); + p += 2; + } + return resLen; +} + static FORCE_INLINE int32_t taosGetTbHashVal(const char *tbname, int32_t tblen, int32_t method, int32_t prefix, int32_t suffix) { if ((prefix == 0 && suffix == 0) || (tblen <= (prefix + suffix)) || (tblen <= -1 * (prefix + suffix)) || diff --git a/source/libs/function/src/functionMgt.c b/source/libs/function/src/functionMgt.c index 345020cee2..5caeb2b43c 100644 --- a/source/libs/function/src/functionMgt.c +++ b/source/libs/function/src/functionMgt.c @@ -391,8 +391,10 @@ static int32_t createPartialFunction(const SFunctionNode* pSrcFunc, SFunctionNod nodesDestroyList(pParameterList); return TSDB_CODE_OUT_OF_MEMORY; } - snprintf((*pPartialFunc)->node.aliasName, sizeof((*pPartialFunc)->node.aliasName), "%s.%p", - (*pPartialFunc)->functionName, pSrcFunc); + char name[TSDB_FUNC_NAME_LEN + TSDB_NAME_DELIMITER_LEN + TSDB_POINTER_PRINT_BYTES + 1] = {0}; + int32_t len = snprintf(name, sizeof(name) - 1, "%s.%p", (*pPartialFunc)->functionName, pSrcFunc); + taosCreateMD5Hash(name, len); + strncpy((*pPartialFunc)->node.aliasName, name, TSDB_COL_NAME_LEN - 1); return TSDB_CODE_SUCCESS; } diff --git a/source/libs/parser/src/parTranslater.c b/source/libs/parser/src/parTranslater.c index 8ce68a5c8c..2137a6c24a 100644 --- a/source/libs/parser/src/parTranslater.c +++ b/source/libs/parser/src/parTranslater.c @@ -2831,7 +2831,7 @@ static SNode* createMultiResFunc(SFunctionNode* pSrcFunc, SExprNode* pExpr) { pFunc->funcId = pSrcFunc->funcId; pFunc->funcType = pSrcFunc->funcType; strcpy(pFunc->functionName, pSrcFunc->functionName); - char buf[TSDB_FUNC_NAME_LEN + TSDB_TABLE_NAME_LEN + TSDB_COL_NAME_LEN]; + char buf[TSDB_FUNC_NAME_LEN + TSDB_TABLE_NAME_LEN + TSDB_COL_NAME_LEN + TSDB_NAME_DELIMITER_LEN + 3] = {0}; int32_t len = 0; if (QUERY_NODE_COLUMN == nodeType(pExpr)) { SColumnNode* pCol = (SColumnNode*)pExpr; @@ -2839,16 +2839,20 @@ static SNode* createMultiResFunc(SFunctionNode* pSrcFunc, SExprNode* pExpr) { strcpy(pFunc->node.userAlias, pCol->colName); strcpy(pFunc->node.aliasName, pCol->colName); } else { - len = snprintf(buf, sizeof(buf), "%s(%s.%s)", pSrcFunc->functionName, pCol->tableAlias, pCol->colName); - strncpy(pFunc->node.aliasName, buf, TMIN(len, sizeof(pFunc->node.aliasName) - 1)); - len = snprintf(buf, sizeof(buf), "%s(%s)", pSrcFunc->functionName, pCol->colName); - strncpy(pFunc->node.userAlias, buf, TMIN(len, sizeof(pFunc->node.userAlias) - 1)); + len = snprintf(buf, sizeof(buf) - 1, "%s(%s.%s)", pSrcFunc->functionName, pCol->tableAlias, pCol->colName); + taosCreateMD5Hash(buf, len); + strncpy(pFunc->node.aliasName, buf, TSDB_COL_NAME_LEN - 1); + len = snprintf(buf, sizeof(buf) - 1, "%s(%s)", pSrcFunc->functionName, pCol->colName); + taosCreateMD5Hash(buf, len); + strncpy(pFunc->node.userAlias, buf, TSDB_COL_NAME_LEN - 1); } } else { - len = snprintf(buf, sizeof(buf), "%s(%s)", pSrcFunc->functionName, pExpr->aliasName); - strncpy(pFunc->node.aliasName, buf, TMIN(len, sizeof(pFunc->node.aliasName) - 1)); - len = snprintf(buf, sizeof(buf), "%s(%s)", pSrcFunc->functionName, pExpr->userAlias); - strncpy(pFunc->node.userAlias, buf, TMIN(len, sizeof(pFunc->node.userAlias) - 1)); + len = snprintf(buf, sizeof(buf) - 1, "%s(%s)", pSrcFunc->functionName, pExpr->aliasName); + taosCreateMD5Hash(buf, len); + strncpy(pFunc->node.aliasName, buf, TSDB_COL_NAME_LEN - 1); + len = snprintf(buf, sizeof(buf) - 1, "%s(%s)", pSrcFunc->functionName, pExpr->userAlias); + taosCreateMD5Hash(buf, len); + strncpy(pFunc->node.userAlias, buf, TSDB_COL_NAME_LEN - 1); } return (SNode*)pFunc; diff --git a/source/libs/planner/src/planOptimizer.c b/source/libs/planner/src/planOptimizer.c index 5765e304a9..32d883d4ea 100644 --- a/source/libs/planner/src/planOptimizer.c +++ b/source/libs/planner/src/planOptimizer.c @@ -1610,8 +1610,12 @@ static int32_t partTagsOptRebuildTbanme(SNodeList* pPartKeys) { } // todo refact: just to mask compilation warnings -static void partTagsSetAlias(char* pAlias, int32_t len, const char* pTableAlias, const char* pColName) { - snprintf(pAlias, len, "%s.%s", pTableAlias, pColName); +static void partTagsSetAlias(char* pAlias, const char* pTableAlias, const char* pColName) { + char name[TSDB_COL_FNAME_LEN + 1] = {0}; + int32_t len = snprintf(name, TSDB_COL_FNAME_LEN, "%s.%s", pTableAlias, pColName); + + taosCreateMD5Hash(name, len); + strncpy(pAlias, name, TSDB_COL_NAME_LEN - 1); } static SNode* partTagsCreateWrapperFunc(const char* pFuncName, SNode* pNode) { @@ -1623,7 +1627,7 @@ static SNode* partTagsCreateWrapperFunc(const char* pFuncName, SNode* pNode) { snprintf(pFunc->functionName, sizeof(pFunc->functionName), "%s", pFuncName); if (QUERY_NODE_COLUMN == nodeType(pNode) && COLUMN_TYPE_TBNAME != ((SColumnNode*)pNode)->colType) { SColumnNode* pCol = (SColumnNode*)pNode; - partTagsSetAlias(pFunc->node.aliasName, sizeof(pFunc->node.aliasName), pCol->tableAlias, pCol->colName); + partTagsSetAlias(pFunc->node.aliasName, pCol->tableAlias, pCol->colName); } else { strcpy(pFunc->node.aliasName, ((SExprNode*)pNode)->aliasName); } @@ -2132,7 +2136,10 @@ static SNode* rewriteUniqueOptCreateFirstFunc(SFunctionNode* pSelectValue, SNode strcpy(pFunc->node.aliasName, pSelectValue->node.aliasName); } else { int64_t pointer = (int64_t)pFunc; - snprintf(pFunc->node.aliasName, sizeof(pFunc->node.aliasName), "%s.%" PRId64 "", pFunc->functionName, pointer); + char name[TSDB_FUNC_NAME_LEN + TSDB_POINTER_PRINT_BYTES + TSDB_NAME_DELIMITER_LEN + 1] = {0}; + int32_t len = snprintf(name, sizeof(name) - 1, "%s.%" PRId64 "", pFunc->functionName, pointer); + taosCreateMD5Hash(name, len); + strncpy(pFunc->node.aliasName, name, TSDB_COL_NAME_LEN - 1); } int32_t code = nodesListMakeStrictAppend(&pFunc->pParameterList, nodesCloneNode(pCol)); if (TSDB_CODE_SUCCESS == code) { diff --git a/source/libs/planner/src/planPhysiCreater.c b/source/libs/planner/src/planPhysiCreater.c index 06859e195d..eaae9b0c8f 100644 --- a/source/libs/planner/src/planPhysiCreater.c +++ b/source/libs/planner/src/planPhysiCreater.c @@ -39,26 +39,32 @@ typedef struct SPhysiPlanContext { bool hasSysScan; } SPhysiPlanContext; -static int32_t getSlotKey(SNode* pNode, const char* pStmtName, char* pKey) { +static int32_t getSlotKey(SNode* pNode, const char* pStmtName, char* pKey, int32_t keyBufSize) { + int32_t len = 0; if (QUERY_NODE_COLUMN == nodeType(pNode)) { SColumnNode* pCol = (SColumnNode*)pNode; if (NULL != pStmtName) { if ('\0' != pStmtName[0]) { - return sprintf(pKey, "%s.%s", pStmtName, pCol->node.aliasName); + len = snprintf(pKey, keyBufSize, "%s.%s", pStmtName, pCol->node.aliasName); + return taosCreateMD5Hash(pKey, len); } else { - return sprintf(pKey, "%s", pCol->node.aliasName); + return snprintf(pKey, keyBufSize, "%s", pCol->node.aliasName); } } if ('\0' == pCol->tableAlias[0]) { - return sprintf(pKey, "%s", pCol->colName); + return snprintf(pKey, keyBufSize, "%s", pCol->colName); } - return sprintf(pKey, "%s.%s", pCol->tableAlias, pCol->colName); + + len = snprintf(pKey, keyBufSize, "%s.%s", pCol->tableAlias, pCol->colName); + return taosCreateMD5Hash(pKey, len); } if (NULL != pStmtName && '\0' != pStmtName[0]) { - return sprintf(pKey, "%s.%s", pStmtName, ((SExprNode*)pNode)->aliasName); + len = snprintf(pKey, keyBufSize, "%s.%s", pStmtName, ((SExprNode*)pNode)->aliasName); + return taosCreateMD5Hash(pKey, len); } - return sprintf(pKey, "%s", ((SExprNode*)pNode)->aliasName); + + return snprintf(pKey, keyBufSize, "%s", ((SExprNode*)pNode)->aliasName); } static SNode* createSlotDesc(SPhysiPlanContext* pCxt, const char* pName, const SNode* pNode, int16_t slotId, @@ -136,8 +142,8 @@ static int32_t buildDataBlockSlots(SPhysiPlanContext* pCxt, SNodeList* pList, SD int16_t slotId = 0; SNode* pNode = NULL; FOREACH(pNode, pList) { - char name[TSDB_TABLE_NAME_LEN + TSDB_COL_NAME_LEN]; - getSlotKey(pNode, NULL, name); + char name[TSDB_COL_FNAME_LEN + 1] = {0}; + getSlotKey(pNode, NULL, name, TSDB_COL_FNAME_LEN); code = nodesListStrictAppend(pDataBlockDesc->pSlots, createSlotDesc(pCxt, name, pNode, slotId, true, false)); if (TSDB_CODE_SUCCESS == code) { code = putSlotToHash(name, pDataBlockDesc->dataBlockId, slotId, pNode, pHash); @@ -199,8 +205,8 @@ static int32_t addDataBlockSlotsImpl(SPhysiPlanContext* pCxt, SNodeList* pList, SNode* pNode = NULL; FOREACH(pNode, pList) { SNode* pExpr = QUERY_NODE_ORDER_BY_EXPR == nodeType(pNode) ? ((SOrderByExprNode*)pNode)->pExpr : pNode; - char name[TSDB_TABLE_NAME_LEN + TSDB_COL_NAME_LEN] = {0}; - int32_t len = getSlotKey(pExpr, pStmtName, name); + char name[TSDB_COL_FNAME_LEN + 1] = {0}; + int32_t len = getSlotKey(pExpr, pStmtName, name, TSDB_COL_FNAME_LEN); SSlotIndex* pIndex = taosHashGet(pHash, name, len); if (NULL == pIndex) { code = @@ -288,8 +294,8 @@ static void dumpSlots(const char* pName, SHashObj* pHash) { static EDealRes doSetSlotId(SNode* pNode, void* pContext) { if (QUERY_NODE_COLUMN == nodeType(pNode) && 0 != strcmp(((SColumnNode*)pNode)->colName, "*")) { SSetSlotIdCxt* pCxt = (SSetSlotIdCxt*)pContext; - char name[TSDB_TABLE_NAME_LEN + TSDB_COL_NAME_LEN]; - int32_t len = getSlotKey(pNode, NULL, name); + char name[TSDB_COL_FNAME_LEN + 1] = {0}; + int32_t len = getSlotKey(pNode, NULL, name, TSDB_COL_FNAME_LEN); SSlotIndex* pIndex = taosHashGet(pCxt->pLeftHash, name, len); if (NULL == pIndex) { pIndex = taosHashGet(pCxt->pRightHash, name, len); diff --git a/source/libs/planner/src/planSpliter.c b/source/libs/planner/src/planSpliter.c index 84a486649e..7f27a0539d 100644 --- a/source/libs/planner/src/planSpliter.c +++ b/source/libs/planner/src/planSpliter.c @@ -388,7 +388,11 @@ static int32_t stbSplAppendWStart(SNodeList* pFuncs, int32_t* pIndex) { } strcpy(pWStart->functionName, "_wstart"); int64_t pointer = (int64_t)pWStart; - snprintf(pWStart->node.aliasName, sizeof(pWStart->node.aliasName), "%s.%" PRId64 "", pWStart->functionName, pointer); + char name[TSDB_COL_NAME_LEN + TSDB_POINTER_PRINT_BYTES + TSDB_NAME_DELIMITER_LEN + 1] = {0}; + int32_t len = snprintf(name, sizeof(name) - 1, "%s.%" PRId64 "", pWStart->functionName, pointer); + taosCreateMD5Hash(name, len); + strncpy(pWStart->node.aliasName, name, TSDB_COL_NAME_LEN - 1); + int32_t code = fmGetFuncInfo(pWStart, NULL, 0); if (TSDB_CODE_SUCCESS == code) { code = nodesListStrictAppend(pFuncs, (SNode*)pWStart); @@ -414,7 +418,11 @@ static int32_t stbSplAppendWEnd(SWindowLogicNode* pWin, int32_t* pIndex) { } strcpy(pWEnd->functionName, "_wend"); int64_t pointer = (int64_t)pWEnd; - snprintf(pWEnd->node.aliasName, sizeof(pWEnd->node.aliasName), "%s.%" PRId64 "", pWEnd->functionName, pointer); + char name[TSDB_COL_NAME_LEN + TSDB_POINTER_PRINT_BYTES + TSDB_NAME_DELIMITER_LEN + 1] = {0}; + int32_t len = snprintf(name, sizeof(name) - 1, "%s.%" PRId64 "", pWEnd->functionName, pointer); + taosCreateMD5Hash(name, len); + strncpy(pWEnd->node.aliasName, name, TSDB_COL_NAME_LEN - 1); + int32_t code = fmGetFuncInfo(pWEnd, NULL, 0); if (TSDB_CODE_SUCCESS == code) { code = nodesListStrictAppend(pWin->pFuncs, (SNode*)pWEnd); diff --git a/source/libs/planner/src/planUtil.c b/source/libs/planner/src/planUtil.c index 88086cde1d..50f64c6be3 100644 --- a/source/libs/planner/src/planUtil.c +++ b/source/libs/planner/src/planUtil.c @@ -373,5 +373,3 @@ bool isPartTableAgg(SAggLogicNode* pAgg) { bool isPartTableWinodw(SWindowLogicNode* pWindow) { return stbHasPartTbname(stbSplGetPartKeys((SLogicNode*)nodesListGetNode(pWindow->node.pChildren, 0))); } - - diff --git a/tests/parallel_test/cases.task b/tests/parallel_test/cases.task index c3d87315f5..2a670e7b39 100644 --- a/tests/parallel_test/cases.task +++ b/tests/parallel_test/cases.task @@ -137,6 +137,7 @@ ,,y,system-test,./pytest.sh python3 ./test.py -f 99-TDcase/TS-3404.py ,,y,system-test,./pytest.sh python3 ./test.py -f 99-TDcase/TS-3581.py ,,y,system-test,./pytest.sh python3 ./test.py -f 99-TDcase/TS-3311.py +,,y,system-test,./pytest.sh python3 ./test.py -f 99-TDcase/TS-3821.py ,,y,system-test,./pytest.sh python3 ./test.py -f 0-others/balance_vgroups_r1.py -N 6 ,,y,system-test,./pytest.sh python3 ./test.py -f 0-others/taosShell.py diff --git a/tests/system-test/99-TDcase/TS-3821.py b/tests/system-test/99-TDcase/TS-3821.py new file mode 100644 index 0000000000..c9b5dfe3fe --- /dev/null +++ b/tests/system-test/99-TDcase/TS-3821.py @@ -0,0 +1,84 @@ +import taos +import sys +import time +import socket +import os +import threading + +from util.log import * +from util.sql import * +from util.cases import * +from util.dnodes import * + +class TDTestCase: + hostname = socket.gethostname() + + def init(self, conn, logSql, replicaVar=1): + self.replicaVar = int(replicaVar) + tdLog.debug(f"start to excute {__file__}") + #tdSql.init(conn.cursor()) + tdSql.init(conn.cursor(), logSql) # output sql.txt file + + def getBuildPath(self): + selfPath = os.path.dirname(os.path.realpath(__file__)) + + if ("community" in selfPath): + projPath = selfPath[:selfPath.find("community")] + else: + projPath = selfPath[:selfPath.find("tests")] + + for root, dirs, files in os.walk(projPath): + if ("taosd" in files or "taosd.exe" in files): + rootRealPath = os.path.dirname(os.path.realpath(root)) + if ("packaging" not in rootRealPath): + buildPath = root[:len(root) - len("/build/bin")] + break + return buildPath + + def create_tables(self): + tdSql.execute(f'''CREATE STABLE `s_e8d66f7af53e4c88866efbc44252a8cd_device_technical_indicators` + (`ts` TIMESTAMP, `event_time` TIMESTAMP, `wbli` DOUBLE, `vrc` DOUBLE, `csd` DOUBLE, + `oiv` DOUBLE, `tiv` DOUBLE, `flol` DOUBLE, `capacity` DOUBLE, `ispc` NCHAR(50)) TAGS + (`device_identification` NCHAR(64))''') + tdSql.execute(f''' CREATE TABLE `t_1000000000001001_e8d66f7af53e4c88866efbc44252a8cd_device_technical_indicators` + USING `s_e8d66f7af53e4c88866efbc44252a8cd_device_technical_indicators` (`device_identification`) + TAGS ("1000000000001001")''') + + def insert_data(self): + tdLog.debug("start to insert data ............") + + tdSql.execute(f"INSERT INTO `t_1000000000001001_e8d66f7af53e4c88866efbc44252a8cd_device_technical_indicators` VALUES ('2023-08-06 17:47:35.685','2023-07-24 11:18:20.000', 17.199999999999999, 100.000000000000000, 100.000000000000000, NULL, 112.328999999999994, 132.182899999999989, 12.300000000000001, '符合条件')") + tdSql.execute(f"INSERT INTO `t_1000000000001001_e8d66f7af53e4c88866efbc44252a8cd_device_technical_indicators` VALUES ('2023-08-06 17:47:36.239','2023-07-24 11:18:20.000', 17.199999999999999, 100.000000000000000, 100.000000000000000, NULL, 112.328999999999994, 132.182899999999989, 12.300000000000001, '符合条件')") + tdSql.execute(f"INSERT INTO `t_1000000000001001_e8d66f7af53e4c88866efbc44252a8cd_device_technical_indicators` VALUES ('2023-08-06 17:47:37.290','2023-07-24 11:18:20.000', 17.199999999999999, 100.000000000000000, 100.000000000000000, NULL, 112.328999999999994, 132.182899999999989, 12.300000000000001, '符合条件')") + tdSql.execute(f"INSERT INTO `t_1000000000001001_e8d66f7af53e4c88866efbc44252a8cd_device_technical_indicators` VALUES ('2023-08-06 17:47:38.414','2023-07-24 11:18:20.000', 17.199999999999999, 100.000000000000000, 100.000000000000000, NULL, 112.328999999999994, 132.182899999999989, 12.300000000000001, '符合条件')") + tdSql.execute(f"INSERT INTO `t_1000000000001001_e8d66f7af53e4c88866efbc44252a8cd_device_technical_indicators` VALUES ('2023-08-06 17:47:39.471','2023-07-24 11:18:20.000', 17.199999999999999, 100.000000000000000, 100.000000000000000, NULL, 112.328999999999994, 132.182899999999989, 12.300000000000001, '符合条件')") + + tdLog.debug("insert data ............ [OK]") + + def run(self): + tdSql.prepare() + self.create_tables() + self.insert_data() + tdLog.printNoPrefix("======== test TS-3821") + + tdSql.query(f'''select count(*),device_identification from s_e8d66f7af53e4c88866efbc44252a8cd_device_technical_indicators + where 1=1 and device_identification ='1000000000001001' group by device_identification;''') + tdSql.checkRows(1) + tdSql.checkCols(2) + tdSql.checkData(0, 0, 5) + tdSql.checkData(0, 1, "1000000000001001") + + tdSql.query(f'''select count(*),device_identification from t_1000000000001001_e8d66f7af53e4c88866efbc44252a8cd_device_technical_indicators + group by device_identification;''') + tdSql.checkRows(1) + tdSql.checkCols(2) + tdSql.checkData(0, 0, 5) + tdSql.checkData(0, 1, "1000000000001001") + + + def stop(self): + tdSql.close() + tdLog.success(f"{__file__} successfully executed") + +tdCases.addLinux(__file__, TDTestCase()) +tdCases.addWindows(__file__, TDTestCase())