From d223a6624b3b40705741cb08a836ed88ac92304b Mon Sep 17 00:00:00 2001 From: Xiaoyu Wang Date: Tue, 5 Jul 2022 14:55:32 +0800 Subject: [PATCH 1/4] fix: execution plan problem in the mode of using qnode as much as possible --- source/libs/parser/src/parTranslater.c | 3 +++ source/libs/parser/src/parUtil.c | 22 +++------------------- source/libs/planner/src/planOptimizer.c | 7 +++++++ source/libs/planner/src/planSpliter.c | 3 ++- source/libs/planner/test/planBasicTest.cpp | 2 ++ source/libs/planner/test/planOtherTest.cpp | 7 ------- source/libs/planner/test/planTestMain.cpp | 4 ++++ source/libs/planner/test/planTestUtil.cpp | 19 +++++++++++++++++++ source/libs/planner/test/planTestUtil.h | 1 + 9 files changed, 41 insertions(+), 27 deletions(-) diff --git a/source/libs/parser/src/parTranslater.c b/source/libs/parser/src/parTranslater.c index f6b8e194cb..eeb9b60270 100644 --- a/source/libs/parser/src/parTranslater.c +++ b/source/libs/parser/src/parTranslater.c @@ -1333,6 +1333,9 @@ static int32_t rewriteSystemInfoFuncImpl(STranslateContext* pCxt, char* pLiteral pVal->isNull = true; } else { pVal->literal = pLiteral; + if (IS_VAR_DATA_TYPE(pVal->node.resType.type)) { + pVal->node.resType.bytes = strlen(pLiteral); + } } if (DEAL_RES_ERROR != translateValue(pCxt, pVal)) { *pNode = (SNode*)pVal; diff --git a/source/libs/parser/src/parUtil.c b/source/libs/parser/src/parUtil.c index 69917ad7f9..27a9102422 100644 --- a/source/libs/parser/src/parUtil.c +++ b/source/libs/parser/src/parUtil.c @@ -236,7 +236,6 @@ int32_t buildSyntaxErrMsg(SMsgBuf* pBuf, const char* additionalInfo, const char* const char* prefix = "syntax error"; if (sourceStr == NULL) { - assert(additionalInfo != NULL); snprintf(pBuf->buf, pBuf->len, msgFormat1, additionalInfo); return TSDB_CODE_TSC_SQL_SYNTAX_ERROR; } @@ -254,40 +253,25 @@ int32_t buildSyntaxErrMsg(SMsgBuf* pBuf, const char* additionalInfo, const char* return TSDB_CODE_TSC_SQL_SYNTAX_ERROR; } -SSchema* getTableColumnSchema(const STableMeta* pTableMeta) { - assert(pTableMeta != NULL); - return (SSchema*)pTableMeta->schema; -} +SSchema* getTableColumnSchema(const STableMeta* pTableMeta) { return (SSchema*)pTableMeta->schema; } static SSchema* getOneColumnSchema(const STableMeta* pTableMeta, int32_t colIndex) { - assert(pTableMeta != NULL && pTableMeta->schema != NULL && colIndex >= 0 && - colIndex < (getNumOfColumns(pTableMeta) + getNumOfTags(pTableMeta))); - SSchema* pSchema = (SSchema*)pTableMeta->schema; return &pSchema[colIndex]; } SSchema* getTableTagSchema(const STableMeta* pTableMeta) { - assert(pTableMeta != NULL && - (pTableMeta->tableType == TSDB_SUPER_TABLE || pTableMeta->tableType == TSDB_CHILD_TABLE)); return getOneColumnSchema(pTableMeta, getTableInfo(pTableMeta).numOfColumns); } int32_t getNumOfColumns(const STableMeta* pTableMeta) { - assert(pTableMeta != NULL); // table created according to super table, use data from super table return getTableInfo(pTableMeta).numOfColumns; } -int32_t getNumOfTags(const STableMeta* pTableMeta) { - assert(pTableMeta != NULL); - return getTableInfo(pTableMeta).numOfTags; -} +int32_t getNumOfTags(const STableMeta* pTableMeta) { return getTableInfo(pTableMeta).numOfTags; } -STableComInfo getTableInfo(const STableMeta* pTableMeta) { - assert(pTableMeta != NULL); - return pTableMeta->tableInfo; -} +STableComInfo getTableInfo(const STableMeta* pTableMeta) { return pTableMeta->tableInfo; } STableMeta* tableMetaDup(const STableMeta* pTableMeta) { size_t size = TABLE_META_SIZE(pTableMeta); diff --git a/source/libs/planner/src/planOptimizer.c b/source/libs/planner/src/planOptimizer.c index 88930b6269..55d61d635d 100644 --- a/source/libs/planner/src/planOptimizer.c +++ b/source/libs/planner/src/planOptimizer.c @@ -75,6 +75,11 @@ static SLogicNode* optFindPossibleNode(SLogicNode* pNode, FMayBeOptimized func) return NULL; } +static void optResetParent(SLogicNode* pNode) { + SNode* pChild = NULL; + FOREACH(pChild, pNode->pChildren) { ((SLogicNode*)pChild)->pParent = pNode; } +} + EDealRes scanPathOptHaveNormalColImpl(SNode* pNode, void* pContext) { if (QUERY_NODE_COLUMN == nodeType(pNode)) { // *((bool*)pContext) = (COLUMN_TYPE_TAG != ((SColumnNode*)pNode)->colType); @@ -1460,6 +1465,7 @@ static int32_t rewriteTailOptCreateSort(SIndefRowsFuncLogicNode* pIndef, SLogicN pSort->groupSort = rewriteTailOptNeedGroupSort(pIndef); TSWAP(pSort->node.pChildren, pIndef->node.pChildren); + optResetParent((SLogicNode*)pSort); pSort->node.precision = pIndef->node.precision; SFunctionNode* pTail = NULL; @@ -1667,6 +1673,7 @@ static int32_t rewriteUniqueOptCreateAgg(SIndefRowsFuncLogicNode* pIndef, SLogic } TSWAP(pAgg->node.pChildren, pIndef->node.pChildren); + optResetParent((SLogicNode*)pAgg); pAgg->node.precision = pIndef->node.precision; int32_t code = TSDB_CODE_SUCCESS; diff --git a/source/libs/planner/src/planSpliter.c b/source/libs/planner/src/planSpliter.c index edeff83d5a..7644fc3b19 100644 --- a/source/libs/planner/src/planSpliter.c +++ b/source/libs/planner/src/planSpliter.c @@ -1203,7 +1203,8 @@ typedef struct SQnodeSplitInfo { static bool qndSplFindSplitNode(SSplitContext* pCxt, SLogicSubplan* pSubplan, SLogicNode* pNode, SQnodeSplitInfo* pInfo) { - if (QUERY_NODE_LOGIC_PLAN_SCAN == nodeType(pNode) && NULL != pNode->pParent) { + if (QUERY_NODE_LOGIC_PLAN_SCAN == nodeType(pNode) && NULL != pNode->pParent && + ((SScanLogicNode*)pNode)->scanSeq[0] < 1 && ((SScanLogicNode*)pNode)->scanSeq[1] < 1) { pInfo->pSplitNode = pNode; pInfo->pSubplan = pSubplan; return true; diff --git a/source/libs/planner/test/planBasicTest.cpp b/source/libs/planner/test/planBasicTest.cpp index bf841e6679..4f4c23eacc 100644 --- a/source/libs/planner/test/planBasicTest.cpp +++ b/source/libs/planner/test/planBasicTest.cpp @@ -81,6 +81,8 @@ TEST_F(PlanBasicTest, tailFunc) { run("SELECT TAIL(c2 + 10, 10, 80) FROM t1 WHERE c1 > 10 PARTITION BY c1 LIMIT 5"); run("SELECT TAIL(c1, 2, 1) FROM st1s1 UNION ALL SELECT c1 FROM st1s2"); + + run("SELECT TAIL(c1, 1) FROM st2 WHERE jtag->'tag1' > 10"); } TEST_F(PlanBasicTest, interpFunc) { diff --git a/source/libs/planner/test/planOtherTest.cpp b/source/libs/planner/test/planOtherTest.cpp index b8963c29f9..2c031aa3a8 100644 --- a/source/libs/planner/test/planOtherTest.cpp +++ b/source/libs/planner/test/planOtherTest.cpp @@ -91,10 +91,3 @@ TEST_F(PlanOtherTest, delete) { run("DELETE FROM st1 WHERE ts > now - 2d and ts < now - 1d AND tag1 = 10"); } - -TEST_F(PlanOtherTest, queryPolicy) { - useDb("root", "test"); - - tsQueryPolicy = QUERY_POLICY_QNODE; - run("SELECT COUNT(*) FROM st1"); -} diff --git a/source/libs/planner/test/planTestMain.cpp b/source/libs/planner/test/planTestMain.cpp index 46c2f33048..8f6fc832a2 100644 --- a/source/libs/planner/test/planTestMain.cpp +++ b/source/libs/planner/test/planTestMain.cpp @@ -78,6 +78,7 @@ static void parseArg(int argc, char* argv[]) { {"skipSql", required_argument, NULL, 's'}, {"limitSql", required_argument, NULL, 'i'}, {"log", required_argument, NULL, 'l'}, + {"queryPolicy", required_argument, NULL, 'q'}, {0, 0, 0, 0} }; // clang-format on @@ -95,6 +96,9 @@ static void parseArg(int argc, char* argv[]) { case 'l': setLogLevel(optarg); break; + case 'q': + setQueryPolicy(optarg); + break; default: break; } diff --git a/source/libs/planner/test/planTestUtil.cpp b/source/libs/planner/test/planTestUtil.cpp index d19e277a7d..4780249ec9 100644 --- a/source/libs/planner/test/planTestUtil.cpp +++ b/source/libs/planner/test/planTestUtil.cpp @@ -24,6 +24,7 @@ #include "mockCatalogService.h" #include "parser.h" #include "planInt.h" +#include "tglobal.h" using namespace std; using namespace testing; @@ -53,6 +54,7 @@ DumpModule g_dumpModule = DUMP_MODULE_NOTHING; int32_t g_skipSql = 0; int32_t g_limitSql = 0; int32_t g_logLevel = 131; +int32_t g_queryPolicy = QUERY_POLICY_VNODE; void setDumpModule(const char* pModule) { if (NULL == pModule) { @@ -79,6 +81,7 @@ void setDumpModule(const char* pModule) { void setSkipSqlNum(const char* pNum) { g_skipSql = stoi(pNum); } void setLimitSqlNum(const char* pNum) { g_limitSql = stoi(pNum); } void setLogLevel(const char* pLogLevel) { g_logLevel = stoi(pLogLevel); } +void setQueryPolicy(const char* pQueryPolicy) { g_queryPolicy = stoi(pQueryPolicy); } int32_t getLogLevel() { return g_logLevel; } @@ -105,7 +108,23 @@ class PlannerTestBaseImpl { } ++sqlNum_; + switch (g_queryPolicy) { + case QUERY_POLICY_VNODE: + case QUERY_POLICY_HYBRID: + case QUERY_POLICY_QNODE: + runImpl(sql, g_queryPolicy); + break; + default: + runImpl(sql, QUERY_POLICY_VNODE); + runImpl(sql, QUERY_POLICY_HYBRID); + runImpl(sql, QUERY_POLICY_QNODE); + break; + } + } + + void runImpl(const string& sql, int32_t queryPolicy) { reset(); + tsQueryPolicy = queryPolicy; try { SQuery* pQuery = nullptr; doParseSql(sql, &pQuery); diff --git a/source/libs/planner/test/planTestUtil.h b/source/libs/planner/test/planTestUtil.h index f9942c93a7..b0ddd726a6 100644 --- a/source/libs/planner/test/planTestUtil.h +++ b/source/libs/planner/test/planTestUtil.h @@ -45,6 +45,7 @@ extern void setDumpModule(const char* pModule); extern void setSkipSqlNum(const char* pNum); extern void setLimitSqlNum(const char* pNum); extern void setLogLevel(const char* pLogLevel); +extern void setQueryPolicy(const char* pQueryPolicy); extern int32_t getLogLevel(); #endif // PLAN_TEST_UTIL_H From 24d0fc4515e9062cd8fd888f25d991e9d7585596 Mon Sep 17 00:00:00 2001 From: Xiaoyu Wang Date: Tue, 5 Jul 2022 15:38:39 +0800 Subject: [PATCH 2/4] fix: adjust parsing of negative numbers --- source/libs/parser/src/parAstCreater.c | 9 +++++++++ source/libs/parser/src/parTranslater.c | 7 +++---- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/source/libs/parser/src/parAstCreater.c b/source/libs/parser/src/parAstCreater.c index c85c44f09b..e5e0ceba4e 100644 --- a/source/libs/parser/src/parAstCreater.c +++ b/source/libs/parser/src/parAstCreater.c @@ -385,6 +385,15 @@ SNode* createLogicConditionNode(SAstCreateContext* pCxt, ELogicConditionType typ SNode* createOperatorNode(SAstCreateContext* pCxt, EOperatorType type, SNode* pLeft, SNode* pRight) { CHECK_PARSER_STATUS(pCxt); + if (OP_TYPE_MINUS == type && QUERY_NODE_VALUE == nodeType(pLeft)) { + SValueNode* pVal = (SValueNode*)pLeft; + char* pNewLiteral = taosMemoryCalloc(1, strlen(pVal->literal) + 1); + CHECK_OUT_OF_MEM(pNewLiteral); + sprintf(pNewLiteral, "-%s", pVal->literal); + taosMemoryFree(pVal->literal); + pVal->literal = pNewLiteral; + return pLeft; + } SOperatorNode* op = (SOperatorNode*)nodesMakeNode(QUERY_NODE_OPERATOR); CHECK_OUT_OF_MEM(op); op->opType = type; diff --git a/source/libs/parser/src/parTranslater.c b/source/libs/parser/src/parTranslater.c index eeb9b60270..894a3c827c 100644 --- a/source/libs/parser/src/parTranslater.c +++ b/source/libs/parser/src/parTranslater.c @@ -878,6 +878,9 @@ static EDealRes translateNormalValue(STranslateContext* pCxt, SValueNode* pVal, } case TSDB_DATA_TYPE_VARCHAR: case TSDB_DATA_TYPE_VARBINARY: { + if (strict && (pVal->node.resType.bytes > targetDt.bytes - VARSTR_HEADER_SIZE)) { + return generateDealNodeErrMsg(pCxt, TSDB_CODE_PAR_WRONG_VALUE_TYPE, pVal->literal); + } pVal->datum.p = taosMemoryCalloc(1, targetDt.bytes + 1); if (NULL == pVal->datum.p) { return generateDealNodeErrMsg(pCxt, TSDB_CODE_OUT_OF_MEMORY); @@ -5829,10 +5832,6 @@ static int32_t buildUpdateTagValReq(STranslateContext* pCxt, SAlterTableStmt* pS return pCxt->errCode; } - if (IS_VAR_DATA_TYPE(pSchema->type) && strlen(pStmt->pVal->literal) > pSchema->bytes) { - return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_WRONG_VALUE_TYPE, pStmt->pVal->literal); - } - pReq->isNull = (TSDB_DATA_TYPE_NULL == pStmt->pVal->node.resType.type); if (targetDt.type == TSDB_DATA_TYPE_JSON) { pReq->isNull = 0; From 3dbb5554a5393416d35592ab0d3c8d3224890e22 Mon Sep 17 00:00:00 2001 From: Xiaoyu Wang Date: Tue, 5 Jul 2022 16:31:44 +0800 Subject: [PATCH 3/4] fix: last(*)/frist(*), etc. do not return the tag column --- source/libs/parser/src/parTranslater.c | 24 +++++++++++------------- tests/script/tsim/stable/tag_modify.sim | 4 ++-- tests/script/tsim/stable/tag_rename.sim | 6 +++--- 3 files changed, 16 insertions(+), 18 deletions(-) diff --git a/source/libs/parser/src/parTranslater.c b/source/libs/parser/src/parTranslater.c index 894a3c827c..4bccb75dcf 100644 --- a/source/libs/parser/src/parTranslater.c +++ b/source/libs/parser/src/parTranslater.c @@ -558,11 +558,11 @@ static void setColumnInfoByExpr(STempTableNode* pTable, SExprNode* pExpr, SColum pCol->node.resType = pExpr->resType; } -static int32_t createColumnsByTable(STranslateContext* pCxt, const STableNode* pTable, SNodeList* pList) { +static int32_t createColumnsByTable(STranslateContext* pCxt, const STableNode* pTable, bool igTags, SNodeList* pList) { if (QUERY_NODE_REAL_TABLE == nodeType(pTable)) { const STableMeta* pMeta = ((SRealTableNode*)pTable)->pMeta; - int32_t nums = - pMeta->tableInfo.numOfColumns + ((TSDB_SUPER_TABLE == pMeta->tableType) ? pMeta->tableInfo.numOfTags : 0); + int32_t nums = pMeta->tableInfo.numOfColumns + + (igTags ? 0 : ((TSDB_SUPER_TABLE == pMeta->tableType) ? pMeta->tableInfo.numOfTags : 0)); for (int32_t i = 0; i < nums; ++i) { SColumnNode* pCol = (SColumnNode*)nodesMakeNode(QUERY_NODE_COLUMN); if (NULL == pCol) { @@ -1934,7 +1934,7 @@ static int32_t translateTable(STranslateContext* pCxt, SNode* pTable) { return code; } -static int32_t createAllColumns(STranslateContext* pCxt, SNodeList** pCols) { +static int32_t createAllColumns(STranslateContext* pCxt, bool igTags, SNodeList** pCols) { *pCols = nodesMakeList(); if (NULL == *pCols) { return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_OUT_OF_MEMORY); @@ -1943,7 +1943,7 @@ static int32_t createAllColumns(STranslateContext* pCxt, SNodeList** pCols) { size_t nums = taosArrayGetSize(pTables); for (size_t i = 0; i < nums; ++i) { STableNode* pTable = taosArrayGetP(pTables, i); - int32_t code = createColumnsByTable(pCxt, pTable, *pCols); + int32_t code = createColumnsByTable(pCxt, pTable, igTags, *pCols); if (TSDB_CODE_SUCCESS != code) { return code; } @@ -1980,7 +1980,7 @@ static SNode* createMultiResFunc(SFunctionNode* pSrcFunc, SExprNode* pExpr) { return (SNode*)pFunc; } -static int32_t createTableAllCols(STranslateContext* pCxt, SColumnNode* pCol, SNodeList** pOutput) { +static int32_t createTableAllCols(STranslateContext* pCxt, SColumnNode* pCol, bool igTags, SNodeList** pOutput) { STableNode* pTable = NULL; int32_t code = findTable(pCxt, pCol->tableAlias, &pTable); if (TSDB_CODE_SUCCESS == code && NULL == *pOutput) { @@ -1990,7 +1990,7 @@ static int32_t createTableAllCols(STranslateContext* pCxt, SColumnNode* pCol, SN } } if (TSDB_CODE_SUCCESS == code) { - code = createColumnsByTable(pCxt, pTable, *pOutput); + code = createColumnsByTable(pCxt, pTable, igTags, *pOutput); } return code; } @@ -2012,11 +2012,9 @@ static int32_t createMultiResFuncsParas(STranslateContext* pCxt, SNodeList* pSrc SNode* pPara = NULL; FOREACH(pPara, pSrcParas) { if (isStar(pPara)) { - code = createAllColumns(pCxt, &pExprs); - // The syntax definition ensures that * and other parameters do not appear at the same time - break; + code = createAllColumns(pCxt, true, &pExprs); } else if (isTableStar(pPara)) { - code = createTableAllCols(pCxt, (SColumnNode*)pPara, &pExprs); + code = createTableAllCols(pCxt, (SColumnNode*)pPara, true, &pExprs); } else { code = nodesListMakeStrictAppend(&pExprs, nodesCloneNode(pPara)); } @@ -2075,7 +2073,7 @@ static int32_t translateStar(STranslateContext* pCxt, SSelectStmt* pSelect) { int32_t code = TSDB_CODE_SUCCESS; if (isStar(pNode)) { SNodeList* pCols = NULL; - code = createAllColumns(pCxt, &pCols); + code = createAllColumns(pCxt, false, &pCols); if (TSDB_CODE_SUCCESS == code) { INSERT_LIST(pSelect->pProjectionList, pCols); ERASE_NODE(pSelect->pProjectionList); @@ -2091,7 +2089,7 @@ static int32_t translateStar(STranslateContext* pCxt, SSelectStmt* pSelect) { } } else if (isTableStar(pNode)) { SNodeList* pCols = NULL; - code = createTableAllCols(pCxt, (SColumnNode*)pNode, &pCols); + code = createTableAllCols(pCxt, (SColumnNode*)pNode, false, &pCols); if (TSDB_CODE_SUCCESS == code) { INSERT_LIST(pSelect->pProjectionList, pCols); ERASE_NODE(pSelect->pProjectionList); diff --git a/tests/script/tsim/stable/tag_modify.sim b/tests/script/tsim/stable/tag_modify.sim index 62e4c7b282..909ed79359 100644 --- a/tests/script/tsim/stable/tag_modify.sim +++ b/tests/script/tsim/stable/tag_modify.sim @@ -14,7 +14,7 @@ sql_error alter table db.stb MODIFY tag ts int sql_error alter table db.stb MODIFY tag t2 binary(3) sql_error alter table db.stb MODIFY tag t2 int sql_error alter table db.stb MODIFY tag t1 int -sql create table db.ctb using db.stb tags(101, "12345") +sql create table db.ctb using db.stb tags(101, "123") sql insert into db.ctb values(now, 1, "1234") sql select * from db.stb @@ -32,7 +32,7 @@ endi if $data[0][3] != 101 then return -1 endi -if $data[0][4] != 1234 then +if $data[0][4] != 123 then return -1 endi diff --git a/tests/script/tsim/stable/tag_rename.sim b/tests/script/tsim/stable/tag_rename.sim index 2f67a3ab2c..5bdfa24990 100644 --- a/tests/script/tsim/stable/tag_rename.sim +++ b/tests/script/tsim/stable/tag_rename.sim @@ -14,7 +14,7 @@ sql_error alter table db.stb rename tag ts c3 sql_error alter table db.stb rename tag t2 t1 sql_error alter table db.stb rename tag t2 t2 sql_error alter table db.stb rename tag t1 t2 -sql create table db.ctb using db.stb tags(101, "12345") +sql create table db.ctb using db.stb tags(101, "123") sql insert into db.ctb values(now, 1, "1234") sql select * from db.stb @@ -32,7 +32,7 @@ endi if $data[0][3] != 101 then return -1 endi -if $data[0][4] != 1234 then +if $data[0][4] != 123 then return -1 endi @@ -56,7 +56,7 @@ endi if $data[0][3] != 101 then return -1 endi -if $data[0][4] != 1234 then +if $data[0][4] != 123 then return -1 endi From 5b14444ca21f56b75d080fceec67d200da162a81 Mon Sep 17 00:00:00 2001 From: Xiaoyu Wang Date: Tue, 5 Jul 2022 18:00:07 +0800 Subject: [PATCH 4/4] fix: a problem of unique function with ts --- source/libs/function/src/builtins.c | 65 +++++++++++----------- source/libs/parser/src/parAstCreater.c | 2 +- source/libs/planner/test/planBasicTest.cpp | 4 ++ 3 files changed, 37 insertions(+), 34 deletions(-) diff --git a/source/libs/function/src/builtins.c b/source/libs/function/src/builtins.c index 0edefdd05b..46b0e61039 100644 --- a/source/libs/function/src/builtins.c +++ b/source/libs/function/src/builtins.c @@ -15,10 +15,10 @@ #include "builtins.h" #include "builtinsimpl.h" +#include "cJSON.h" #include "querynodes.h" #include "scalar.h" #include "taoserror.h" -#include "cJSON.h" static int32_t buildFuncErrMsg(char* pErrBuf, int32_t len, int32_t errCode, const char* pFormat, ...) { va_list vArgList; @@ -40,7 +40,7 @@ static int32_t invaildFuncParaValueErrMsg(char* pErrBuf, int32_t len, const char return buildFuncErrMsg(pErrBuf, len, TSDB_CODE_FUNC_FUNTION_PARA_VALUE, "Invalid parameter value : %s", pFuncName); } -#define TIME_UNIT_INVALID 1 +#define TIME_UNIT_INVALID 1 #define TIME_UNIT_TOO_SMALL 2 static int32_t validateTimeUnitParam(uint8_t dbPrec, const SValueNode* pVal) { @@ -52,10 +52,9 @@ static int32_t validateTimeUnitParam(uint8_t dbPrec, const SValueNode* pVal) { return TIME_UNIT_TOO_SMALL; } - if (pVal->literal[0] != '1' || (pVal->literal[1] != 'u' && pVal->literal[1] != 'a' && - pVal->literal[1] != 's' && pVal->literal[1] != 'm' && - pVal->literal[1] != 'h' && pVal->literal[1] != 'd' && - pVal->literal[1] != 'w')) { + if (pVal->literal[0] != '1' || + (pVal->literal[1] != 'u' && pVal->literal[1] != 'a' && pVal->literal[1] != 's' && pVal->literal[1] != 'm' && + pVal->literal[1] != 'h' && pVal->literal[1] != 'd' && pVal->literal[1] != 'w')) { return TIME_UNIT_INVALID; } @@ -696,13 +695,14 @@ static int32_t translateElapsed(SFunctionNode* pFunc, char* pErrBuf, int32_t len uint8_t dbPrec = pFunc->node.resType.precision; - int32_t ret = validateTimeUnitParam(dbPrec, (SValueNode *)nodesListGetNode(pFunc->pParameterList, 1)); + int32_t ret = validateTimeUnitParam(dbPrec, (SValueNode*)nodesListGetNode(pFunc->pParameterList, 1)); if (ret == TIME_UNIT_TOO_SMALL) { return buildFuncErrMsg(pErrBuf, len, TSDB_CODE_FUNC_FUNTION_ERROR, "ELAPSED function time unit parameter should be greater than db precision"); } else if (ret == TIME_UNIT_INVALID) { - return buildFuncErrMsg(pErrBuf, len, TSDB_CODE_FUNC_FUNTION_ERROR, - "ELAPSED function time unit parameter should be one of the following: [1u, 1a, 1s, 1m, 1h, 1d, 1w]"); + return buildFuncErrMsg( + pErrBuf, len, TSDB_CODE_FUNC_FUNTION_ERROR, + "ELAPSED function time unit parameter should be one of the following: [1u, 1a, 1s, 1m, 1h, 1d, 1w]"); } } @@ -815,13 +815,13 @@ static int8_t validateHistogramBinType(char* binTypeStr) { } static bool validateHistogramBinDesc(char* binDescStr, int8_t binType, char* errMsg, int32_t msgLen) { - const char *msg1 = "HISTOGRAM function requires four parameters"; - const char *msg3 = "HISTOGRAM function invalid format for binDesc parameter"; - const char *msg4 = "HISTOGRAM function binDesc parameter \"count\" should be in range [1, 1000]"; - const char *msg5 = "HISTOGRAM function bin/parameter should be in range [-DBL_MAX, DBL_MAX]"; - const char *msg6 = "HISTOGRAM function binDesc parameter \"width\" cannot be 0"; - const char *msg7 = "HISTOGRAM function binDesc parameter \"start\" cannot be 0 with \"log_bin\" type"; - const char *msg8 = "HISTOGRAM function binDesc parameter \"factor\" cannot be negative or equal to 0/1"; + const char* msg1 = "HISTOGRAM function requires four parameters"; + const char* msg3 = "HISTOGRAM function invalid format for binDesc parameter"; + const char* msg4 = "HISTOGRAM function binDesc parameter \"count\" should be in range [1, 1000]"; + const char* msg5 = "HISTOGRAM function bin/parameter should be in range [-DBL_MAX, DBL_MAX]"; + const char* msg6 = "HISTOGRAM function binDesc parameter \"width\" cannot be 0"; + const char* msg7 = "HISTOGRAM function binDesc parameter \"start\" cannot be 0 with \"log_bin\" type"; + const char* msg8 = "HISTOGRAM function binDesc parameter \"factor\" cannot be negative or equal to 0/1"; cJSON* binDesc = cJSON_Parse(binDescStr); int32_t numOfBins; @@ -1004,8 +1004,8 @@ static int32_t translateHistogram(SFunctionNode* pFunc, char* pErrBuf, int32_t l } if (i == 3 && pValue->datum.i != 1 && pValue->datum.i != 0) { - return buildFuncErrMsg(pErrBuf, len, TSDB_CODE_FUNC_FUNTION_ERROR, - "HISTOGRAM function normalized parameter should be 0/1"); + return buildFuncErrMsg(pErrBuf, len, TSDB_CODE_FUNC_FUNTION_ERROR, + "HISTOGRAM function normalized parameter should be 0/1"); } } @@ -1062,8 +1062,8 @@ static int32_t translateHistogramImpl(SFunctionNode* pFunc, char* pErrBuf, int32 } if (i == 3 && pValue->datum.i != 1 && pValue->datum.i != 0) { - return buildFuncErrMsg(pErrBuf, len, TSDB_CODE_FUNC_FUNTION_ERROR, - "HISTOGRAM function normalized parameter should be 0/1"); + return buildFuncErrMsg(pErrBuf, len, TSDB_CODE_FUNC_FUNTION_ERROR, + "HISTOGRAM function normalized parameter should be 0/1"); } } @@ -1218,13 +1218,14 @@ static int32_t translateStateDuration(SFunctionNode* pFunc, char* pErrBuf, int32 if (numOfParams == 4) { uint8_t dbPrec = pFunc->node.resType.precision; - int32_t ret = validateTimeUnitParam(dbPrec, (SValueNode *)nodesListGetNode(pFunc->pParameterList, 3)); + int32_t ret = validateTimeUnitParam(dbPrec, (SValueNode*)nodesListGetNode(pFunc->pParameterList, 3)); if (ret == TIME_UNIT_TOO_SMALL) { return buildFuncErrMsg(pErrBuf, len, TSDB_CODE_FUNC_FUNTION_ERROR, "STATEDURATION function time unit parameter should be greater than db precision"); } else if (ret == TIME_UNIT_INVALID) { - return buildFuncErrMsg(pErrBuf, len, TSDB_CODE_FUNC_FUNTION_ERROR, - "STATEDURATION function time unit parameter should be one of the following: [1u, 1a, 1s, 1m, 1h, 1d, 1w]"); + return buildFuncErrMsg( + pErrBuf, len, TSDB_CODE_FUNC_FUNTION_ERROR, + "STATEDURATION function time unit parameter should be one of the following: [1u, 1a, 1s, 1m, 1h, 1d, 1w]"); } } @@ -1432,10 +1433,6 @@ static int32_t translateFirstLast(SFunctionNode* pFunc, char* pErrBuf, int32_t l static int32_t translateFirstLastImpl(SFunctionNode* pFunc, char* pErrBuf, int32_t len, bool isPartial) { // first(col_list) will be rewritten as first(col) - if (2 != LIST_LENGTH(pFunc->pParameterList)) { // input has two params c0,ts, is this a bug? - return TSDB_CODE_SUCCESS; - } - SNode* pPara = nodesListGetNode(pFunc->pParameterList, 0); uint8_t paraType = ((SExprNode*)pPara)->resType.type; int32_t paraBytes = ((SExprNode*)pPara)->resType.bytes; @@ -1733,13 +1730,14 @@ static int32_t translateTimeTruncate(SFunctionNode* pFunc, char* pErrBuf, int32_ // add database precision as param uint8_t dbPrec = pFunc->node.resType.precision; - int32_t ret = validateTimeUnitParam(dbPrec, (SValueNode *)nodesListGetNode(pFunc->pParameterList, 1)); + int32_t ret = validateTimeUnitParam(dbPrec, (SValueNode*)nodesListGetNode(pFunc->pParameterList, 1)); if (ret == TIME_UNIT_TOO_SMALL) { return buildFuncErrMsg(pErrBuf, len, TSDB_CODE_FUNC_FUNTION_ERROR, "TIMETRUNCATE function time unit parameter should be greater than db precision"); } else if (ret == TIME_UNIT_INVALID) { - return buildFuncErrMsg(pErrBuf, len, TSDB_CODE_FUNC_FUNTION_ERROR, - "TIMETRUNCATE function time unit parameter should be one of the following: [1u, 1a, 1s, 1m, 1h, 1d, 1w]"); + return buildFuncErrMsg( + pErrBuf, len, TSDB_CODE_FUNC_FUNTION_ERROR, + "TIMETRUNCATE function time unit parameter should be one of the following: [1u, 1a, 1s, 1m, 1h, 1d, 1w]"); } addDbPrecisonParam(&pFunc->pParameterList, dbPrec); @@ -1772,13 +1770,14 @@ static int32_t translateTimeDiff(SFunctionNode* pFunc, char* pErrBuf, int32_t le uint8_t dbPrec = pFunc->node.resType.precision; if (3 == numOfParams) { - int32_t ret = validateTimeUnitParam(dbPrec, (SValueNode *)nodesListGetNode(pFunc->pParameterList, 2)); + int32_t ret = validateTimeUnitParam(dbPrec, (SValueNode*)nodesListGetNode(pFunc->pParameterList, 2)); if (ret == TIME_UNIT_TOO_SMALL) { return buildFuncErrMsg(pErrBuf, len, TSDB_CODE_FUNC_FUNTION_ERROR, "TIMEDIFF function time unit parameter should be greater than db precision"); } else if (ret == TIME_UNIT_INVALID) { - return buildFuncErrMsg(pErrBuf, len, TSDB_CODE_FUNC_FUNTION_ERROR, - "TIMEDIFF function time unit parameter should be one of the following: [1u, 1a, 1s, 1m, 1h, 1d, 1w]"); + return buildFuncErrMsg( + pErrBuf, len, TSDB_CODE_FUNC_FUNTION_ERROR, + "TIMEDIFF function time unit parameter should be one of the following: [1u, 1a, 1s, 1m, 1h, 1d, 1w]"); } } diff --git a/source/libs/parser/src/parAstCreater.c b/source/libs/parser/src/parAstCreater.c index e5e0ceba4e..1042411974 100644 --- a/source/libs/parser/src/parAstCreater.c +++ b/source/libs/parser/src/parAstCreater.c @@ -387,7 +387,7 @@ SNode* createOperatorNode(SAstCreateContext* pCxt, EOperatorType type, SNode* pL CHECK_PARSER_STATUS(pCxt); if (OP_TYPE_MINUS == type && QUERY_NODE_VALUE == nodeType(pLeft)) { SValueNode* pVal = (SValueNode*)pLeft; - char* pNewLiteral = taosMemoryCalloc(1, strlen(pVal->literal) + 1); + char* pNewLiteral = taosMemoryCalloc(1, strlen(pVal->literal) + 2); CHECK_OUT_OF_MEM(pNewLiteral); sprintf(pNewLiteral, "-%s", pVal->literal); taosMemoryFree(pVal->literal); diff --git a/source/libs/planner/test/planBasicTest.cpp b/source/libs/planner/test/planBasicTest.cpp index 4f4c23eacc..c99e4ea866 100644 --- a/source/libs/planner/test/planBasicTest.cpp +++ b/source/libs/planner/test/planBasicTest.cpp @@ -63,6 +63,10 @@ TEST_F(PlanBasicTest, uniqueFunc) { run("SELECT UNIQUE(c2 + 10), ts, c2 FROM t1 WHERE c1 > 10"); run("SELECT UNIQUE(c1) a FROM t1 ORDER BY a"); + + run("SELECT ts, UNIQUE(c1) FROM st1 PARTITION BY TBNAME"); + + run("SELECT TBNAME, UNIQUE(c1) FROM st1 PARTITION BY TBNAME"); } TEST_F(PlanBasicTest, tailFunc) {