diff --git a/source/client/src/clientImpl.c b/source/client/src/clientImpl.c index a4a5ec7499e13369fd3113f3b0c624deb95861bb..9f53b6dcd3d50a7d4a51c3263728489f48f80c96 100644 --- a/source/client/src/clientImpl.c +++ b/source/client/src/clientImpl.c @@ -148,7 +148,8 @@ STscObj* taos_connect_internal(const char* ip, const char* user, const char* pas return taosConnectImpl(user, &secretEncrypt[0], localDb, NULL, NULL, *pInst, connType); } -int32_t buildRequest(uint64_t connId, const char* sql, int sqlLen, void* param, bool validateSql, SRequestObj** pRequest) { +int32_t buildRequest(uint64_t connId, const char* sql, int sqlLen, void* param, bool validateSql, + SRequestObj** pRequest) { *pRequest = createRequest(connId, TSDB_SQL_SELECT); if (*pRequest == NULL) { tscError("failed to malloc sqlObj, %s", sql); @@ -165,7 +166,7 @@ int32_t buildRequest(uint64_t connId, const char* sql, int sqlLen, void* param, strntolower((*pRequest)->sqlstr, sql, (int32_t)sqlLen); (*pRequest)->sqlstr[sqlLen] = 0; - (*pRequest)->sqlLen = sqlLen; + (*pRequest)->sqlLen = sqlLen; (*pRequest)->validateOnly = validateSql; if (param == NULL) { @@ -351,7 +352,8 @@ int32_t updateQnodeList(SAppInstInfo* pInfo, SArray* pNodeList) { if (pNodeList) { pInfo->pQnodeList = taosArrayDup(pNodeList); taosArraySort(pInfo->pQnodeList, compareQueryNodeLoad); - tscDebug("QnodeList updated in cluster 0x%" PRIx64 ", num:%d", pInfo->clusterId, taosArrayGetSize(pInfo->pQnodeList)); + tscDebug("QnodeList updated in cluster 0x%" PRIx64 ", num:%d", pInfo->clusterId, + taosArrayGetSize(pInfo->pQnodeList)); } taosThreadMutexUnlock(&pInfo->qnodeMutex); @@ -649,22 +651,22 @@ _return: int32_t scheduleQuery(SRequestObj* pRequest, SQueryPlan* pDag, SArray* pNodeList) { void* pTransporter = pRequest->pTscObj->pAppInfo->pTransporter; - SExecResult res = {0}; + SExecResult res = {0}; SRequestConnInfo conn = {.pTrans = pRequest->pTscObj->pAppInfo->pTransporter, .requestId = pRequest->requestId, .requestObjRefId = pRequest->self}; SSchedulerReq req = { - .syncReq = true, - .pConn = &conn, - .pNodeList = pNodeList, - .pDag = pDag, - .sql = pRequest->sqlstr, - .startTs = pRequest->metric.start, - .execFp = NULL, - .cbParam = NULL, - .chkKillFp = chkRequestKilled, - .chkKillParam = (void*)pRequest->self, - .pExecRes = &res, + .syncReq = true, + .pConn = &conn, + .pNodeList = pNodeList, + .pDag = pDag, + .sql = pRequest->sqlstr, + .startTs = pRequest->metric.start, + .execFp = NULL, + .cbParam = NULL, + .chkKillFp = chkRequestKilled, + .chkKillParam = (void*)pRequest->self, + .pExecRes = &res, }; int32_t code = schedulerExecJob(&req, &pRequest->body.queryJob); @@ -778,7 +780,7 @@ int32_t handleQueryExecRsp(SRequestObj* pRequest) { return code; } - SEpSet epset = getEpSet_s(&pAppInfo->mgmtEp); + SEpSet epset = getEpSet_s(&pAppInfo->mgmtEp); SExecResult* pRes = &pRequest->body.resInfo.execRes; switch (pRes->msgType) { @@ -964,17 +966,17 @@ void launchAsyncQuery(SRequestObj* pRequest, SQuery* pQuery, SMetaData* pResultM SRequestConnInfo conn = { .pTrans = pAppInfo->pTransporter, .requestId = pRequest->requestId, .requestObjRefId = pRequest->self}; SSchedulerReq req = { - .syncReq = false, - .pConn = &conn, - .pNodeList = pNodeList, - .pDag = pDag, - .sql = pRequest->sqlstr, - .startTs = pRequest->metric.start, - .execFp = schedulerExecCb, - .cbParam = pRequest, - .chkKillFp = chkRequestKilled, - .chkKillParam = (void*)pRequest->self, - .pExecRes = NULL, + .syncReq = false, + .pConn = &conn, + .pNodeList = pNodeList, + .pDag = pDag, + .sql = pRequest->sqlstr, + .startTs = pRequest->metric.start, + .execFp = schedulerExecCb, + .cbParam = pRequest, + .chkKillFp = chkRequestKilled, + .chkKillParam = (void*)pRequest->self, + .pExecRes = NULL, }; code = schedulerExecJob(&req, &pRequest->body.queryJob); taosArrayDestroy(pNodeList); @@ -993,6 +995,7 @@ void launchAsyncQuery(SRequestObj* pRequest, SQuery* pQuery, SMetaData* pResultM pRequest->body.queryFp(pRequest->body.param, pRequest, 0); break; default: + pRequest->body.queryFp(pRequest->body.param, pRequest, -1); break; } @@ -1416,9 +1419,9 @@ void* doFetchRows(SRequestObj* pRequest, bool setupOneRowPtr, bool convertUcs4) } SReqResultInfo* pResInfo = &pRequest->body.resInfo; - SSchedulerReq req = { - .syncReq = true, - .pFetchRes = (void**)&pResInfo->pData, + SSchedulerReq req = { + .syncReq = true, + .pFetchRes = (void**)&pResInfo->pData, }; pRequest->code = schedulerFetchRows(pRequest->body.queryJob, &req); if (pRequest->code != TSDB_CODE_SUCCESS) { diff --git a/source/libs/function/src/builtins.c b/source/libs/function/src/builtins.c index 1e7e7e57c3d1c9333afaef5969bca49a2ec20ee6..fc87ba964a036294dbc73e9b4b8f8a4b915291d3 100644 --- a/source/libs/function/src/builtins.c +++ b/source/libs/function/src/builtins.c @@ -48,8 +48,8 @@ static int32_t validateTimeUnitParam(uint8_t dbPrec, const SValueNode* pVal) { return TIME_UNIT_INVALID; } - if (TSDB_TIME_PRECISION_MILLI == dbPrec && (0 == strcasecmp(pVal->literal, "1u") || - 0 == strcasecmp(pVal->literal, "1b"))) { + if (TSDB_TIME_PRECISION_MILLI == dbPrec && + (0 == strcasecmp(pVal->literal, "1u") || 0 == strcasecmp(pVal->literal, "1b"))) { return TIME_UNIT_TOO_SMALL; } @@ -57,10 +57,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' && pVal->literal[1] != 'b')) { + 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' && pVal->literal[1] != 'b')) { return TIME_UNIT_INVALID; } @@ -678,9 +677,10 @@ static int32_t translateElapsed(SFunctionNode* pFunc, char* pErrBuf, int32_t len return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName); } - uint8_t paraType = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 0))->resType.type; - if (TSDB_DATA_TYPE_TIMESTAMP != paraType) { - return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName); + SNode* pPara1 = nodesListGetNode(pFunc->pParameterList, 0); + if (QUERY_NODE_COLUMN != nodeType(pPara1) || PRIMARYKEY_TIMESTAMP_COL_ID != ((SColumnNode*)pPara1)->colId) { + return buildFuncErrMsg(pErrBuf, len, TSDB_CODE_FUNC_FUNTION_ERROR, + "The first parameter of the ELAPSED function can only be the timestamp primary key"); } // param1 @@ -694,8 +694,7 @@ static int32_t translateElapsed(SFunctionNode* pFunc, char* pErrBuf, int32_t len pValue->notReserved = true; - paraType = ((SExprNode*)nodesListGetNode(pFunc->pParameterList, 1))->resType.type; - if (!IS_INTEGER_TYPE(paraType)) { + if (!IS_INTEGER_TYPE(pValue->node.resType.type)) { return invaildFuncParaTypeErrMsg(pErrBuf, len, pFunc->functionName); } @@ -706,8 +705,9 @@ static int32_t translateElapsed(SFunctionNode* pFunc, char* pErrBuf, int32_t len 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: [1b, 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: [1b, 1u, 1a, 1s, 1m, 1h, 1d, 1w]"); } } @@ -1229,7 +1229,8 @@ static int32_t translateStateDuration(SFunctionNode* pFunc, char* pErrBuf, int32 "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: [1b, 1u, 1a, 1s, 1m, 1h, 1d, 1w]"); + "STATEDURATION function time unit parameter should be one of the following: [1b, 1u, 1a, " + "1s, 1m, 1h, 1d, 1w]"); } } @@ -1740,8 +1741,9 @@ static int32_t translateTimeTruncate(SFunctionNode* pFunc, char* pErrBuf, int32_ 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: [1b, 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: [1b, 1u, 1a, 1s, 1m, 1h, 1d, 1w]"); } addDbPrecisonParam(&pFunc->pParameterList, dbPrec); @@ -1779,8 +1781,9 @@ static int32_t translateTimeDiff(SFunctionNode* pFunc, char* pErrBuf, int32_t le 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: [1b, 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: [1b, 1u, 1a, 1s, 1m, 1h, 1d, 1w]"); } } diff --git a/source/libs/nodes/src/nodesUtilFuncs.c b/source/libs/nodes/src/nodesUtilFuncs.c index cc442d11034ff1321b3fff62d24b74374bbc550f..897b575e10592e9906a899ae1b71da877dd0b9b0 100644 --- a/source/libs/nodes/src/nodesUtilFuncs.c +++ b/source/libs/nodes/src/nodesUtilFuncs.c @@ -1793,7 +1793,7 @@ static EDealRes classifyConditionImpl(SNode* pNode, void* pContext) { } else if (pCol->hasIndex) { pCxt->hasTagIndexCol = true; pCxt->hasTagCol = true; - } else if (COLUMN_TYPE_TAG == pCol->colType) { + } else if (COLUMN_TYPE_TAG == pCol->colType || COLUMN_TYPE_TBNAME == pCol->colType) { pCxt->hasTagCol = true; } else { pCxt->hasOtherCol = true; diff --git a/source/libs/parser/src/parAstCreater.c b/source/libs/parser/src/parAstCreater.c index c451e52540a52bc8ce35bd2c5c3db438f983f508..7b2cd78711a2553a97bdcc6fccfc8e146895d868 100644 --- a/source/libs/parser/src/parAstCreater.c +++ b/source/libs/parser/src/parAstCreater.c @@ -339,6 +339,10 @@ SNode* createDefaultDatabaseCondValue(SAstCreateContext* pCxt) { SNode* createPlaceholderValueNode(SAstCreateContext* pCxt, const SToken* pLiteral) { CHECK_PARSER_STATUS(pCxt); + if (NULL == pCxt->pQueryCxt->pStmtCb) { + pCxt->errCode = generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_SYNTAX_ERROR, pLiteral->z); + return NULL; + } SValueNode* val = (SValueNode*)nodesMakeNode(QUERY_NODE_VALUE); CHECK_OUT_OF_MEM(val); val->literal = strndup(pLiteral->z, pLiteral->n); diff --git a/source/libs/parser/src/parser.c b/source/libs/parser/src/parser.c index 218b5d9f4bedabe015804915e37defb5a8fed5ff..fdba0e2fccaf36413de248ccf671334f48b37aa9 100644 --- a/source/libs/parser/src/parser.c +++ b/source/libs/parser/src/parser.c @@ -41,7 +41,7 @@ bool qIsInsertValuesSql(const char* pStr, size_t length) { } else if (TK_SELECT == t.type) { return false; } - if (0 == t.type) { + if (0 == t.type || 0 == t.n) { break; } } while (pStr - pSql < length); diff --git a/source/libs/parser/test/parSelectTest.cpp b/source/libs/parser/test/parSelectTest.cpp index 8ad9feb53656771463bb425d9020be3a576cf39a..0aa1773c28546014fde210c12e7d04b842304dec 100644 --- a/source/libs/parser/test/parSelectTest.cpp +++ b/source/libs/parser/test/parSelectTest.cpp @@ -337,70 +337,69 @@ TEST_F(ParserSelectTest, semanticCheck) { useDb("root", "test"); // TSDB_CODE_PAR_INVALID_COLUMN - run("SELECT c1, cc1 FROM t1", TSDB_CODE_PAR_INVALID_COLUMN, PARSER_STAGE_TRANSLATE); + run("SELECT c1, cc1 FROM t1", TSDB_CODE_PAR_INVALID_COLUMN); - run("SELECT t1.c1, t1.cc1 FROM t1", TSDB_CODE_PAR_INVALID_COLUMN, PARSER_STAGE_TRANSLATE); + run("SELECT t1.c1, t1.cc1 FROM t1", TSDB_CODE_PAR_INVALID_COLUMN); // TSDB_CODE_PAR_TABLE_NOT_EXIST - run("SELECT * FROM t10", TSDB_CODE_PAR_TABLE_NOT_EXIST, PARSER_STAGE_TRANSLATE); + run("SELECT * FROM t10", TSDB_CODE_PAR_TABLE_NOT_EXIST); - run("SELECT * FROM test.t10", TSDB_CODE_PAR_TABLE_NOT_EXIST, PARSER_STAGE_TRANSLATE); + run("SELECT * FROM test.t10", TSDB_CODE_PAR_TABLE_NOT_EXIST); - run("SELECT t2.c1 FROM t1", TSDB_CODE_PAR_TABLE_NOT_EXIST, PARSER_STAGE_TRANSLATE); + run("SELECT t2.c1 FROM t1", TSDB_CODE_PAR_TABLE_NOT_EXIST); // TSDB_CODE_PAR_AMBIGUOUS_COLUMN - run("SELECT c2 FROM t1 tt1, t1 tt2 WHERE tt1.c1 = tt2.c1", TSDB_CODE_PAR_AMBIGUOUS_COLUMN, PARSER_STAGE_TRANSLATE); + run("SELECT c2 FROM t1 tt1, t1 tt2 WHERE tt1.c1 = tt2.c1", TSDB_CODE_PAR_AMBIGUOUS_COLUMN); - run("SELECT c2 FROM (SELECT c1 c2, c2 FROM t1)", TSDB_CODE_PAR_AMBIGUOUS_COLUMN, PARSER_STAGE_TRANSLATE); + run("SELECT c2 FROM (SELECT c1 c2, c2 FROM t1)", TSDB_CODE_PAR_AMBIGUOUS_COLUMN); // TSDB_CODE_PAR_WRONG_VALUE_TYPE - run("SELECT timestamp '2010a' FROM t1", TSDB_CODE_PAR_WRONG_VALUE_TYPE, PARSER_STAGE_TRANSLATE); + run("SELECT timestamp '2010a' FROM t1", TSDB_CODE_PAR_WRONG_VALUE_TYPE); - run("SELECT LAST(*) + SUM(c1) FROM t1", TSDB_CODE_PAR_WRONG_VALUE_TYPE, PARSER_STAGE_TRANSLATE); + run("SELECT LAST(*) + SUM(c1) FROM t1", TSDB_CODE_PAR_WRONG_VALUE_TYPE); - run("SELECT CEIL(LAST(ts, c1)) FROM t1", TSDB_CODE_PAR_WRONG_VALUE_TYPE, PARSER_STAGE_TRANSLATE); + run("SELECT CEIL(LAST(ts, c1)) FROM t1", TSDB_CODE_PAR_WRONG_VALUE_TYPE); // TSDB_CODE_PAR_ILLEGAL_USE_AGG_FUNCTION - run("SELECT c2 FROM t1 tt1 join t1 tt2 on COUNT(*) > 0", TSDB_CODE_PAR_ILLEGAL_USE_AGG_FUNCTION, - PARSER_STAGE_TRANSLATE); + run("SELECT c2 FROM t1 tt1 join t1 tt2 on COUNT(*) > 0", TSDB_CODE_PAR_ILLEGAL_USE_AGG_FUNCTION); - run("SELECT c2 FROM t1 WHERE COUNT(*) > 0", TSDB_CODE_PAR_ILLEGAL_USE_AGG_FUNCTION, PARSER_STAGE_TRANSLATE); + run("SELECT c2 FROM t1 WHERE COUNT(*) > 0", TSDB_CODE_PAR_ILLEGAL_USE_AGG_FUNCTION); - run("SELECT c2 FROM t1 GROUP BY COUNT(*)", TSDB_CODE_PAR_ILLEGAL_USE_AGG_FUNCTION, PARSER_STAGE_TRANSLATE); + run("SELECT c2 FROM t1 GROUP BY COUNT(*)", TSDB_CODE_PAR_ILLEGAL_USE_AGG_FUNCTION); // TSDB_CODE_PAR_WRONG_NUMBER_OF_SELECT - run("SELECT c2 FROM t1 order by 0", TSDB_CODE_PAR_WRONG_NUMBER_OF_SELECT, PARSER_STAGE_TRANSLATE); + run("SELECT c2 FROM t1 order by 0", TSDB_CODE_PAR_WRONG_NUMBER_OF_SELECT); - run("SELECT c2 FROM t1 order by 2", TSDB_CODE_PAR_WRONG_NUMBER_OF_SELECT, PARSER_STAGE_TRANSLATE); + run("SELECT c2 FROM t1 order by 2", TSDB_CODE_PAR_WRONG_NUMBER_OF_SELECT); // TSDB_CODE_PAR_GROUPBY_LACK_EXPRESSION - run("SELECT COUNT(*) cnt FROM t1 having c1 > 0", TSDB_CODE_PAR_GROUPBY_LACK_EXPRESSION, PARSER_STAGE_TRANSLATE); + run("SELECT COUNT(*) cnt FROM t1 having c1 > 0", TSDB_CODE_PAR_GROUPBY_LACK_EXPRESSION); - run("SELECT COUNT(*) cnt FROM t1 GROUP BY c2 having c1 > 0", TSDB_CODE_PAR_GROUPBY_LACK_EXPRESSION, - PARSER_STAGE_TRANSLATE); + run("SELECT COUNT(*) cnt FROM t1 GROUP BY c2 having c1 > 0", TSDB_CODE_PAR_GROUPBY_LACK_EXPRESSION); - run("SELECT COUNT(*), c1 cnt FROM t1 GROUP BY c2 having c2 > 0", TSDB_CODE_PAR_GROUPBY_LACK_EXPRESSION, - PARSER_STAGE_TRANSLATE); + run("SELECT COUNT(*), c1 cnt FROM t1 GROUP BY c2 having c2 > 0", TSDB_CODE_PAR_GROUPBY_LACK_EXPRESSION); - run("SELECT COUNT(*) cnt FROM t1 GROUP BY c2 having c2 > 0 order by c1", TSDB_CODE_PAR_GROUPBY_LACK_EXPRESSION, - PARSER_STAGE_TRANSLATE); + run("SELECT COUNT(*) cnt FROM t1 GROUP BY c2 having c2 > 0 order by c1", TSDB_CODE_PAR_GROUPBY_LACK_EXPRESSION); // TSDB_CODE_PAR_NOT_SINGLE_GROUP - run("SELECT COUNT(*), c1 FROM t1", TSDB_CODE_PAR_NOT_SINGLE_GROUP, PARSER_STAGE_TRANSLATE); + run("SELECT COUNT(*), c1 FROM t1", TSDB_CODE_PAR_NOT_SINGLE_GROUP); - run("SELECT COUNT(*) FROM t1 order by c1", TSDB_CODE_PAR_NOT_SINGLE_GROUP, PARSER_STAGE_TRANSLATE); + run("SELECT COUNT(*) FROM t1 order by c1", TSDB_CODE_PAR_NOT_SINGLE_GROUP); - run("SELECT c1 FROM t1 order by COUNT(*)", TSDB_CODE_PAR_NOT_SINGLE_GROUP, PARSER_STAGE_TRANSLATE); + run("SELECT c1 FROM t1 order by COUNT(*)", TSDB_CODE_PAR_NOT_SINGLE_GROUP); // TSDB_CODE_PAR_NOT_SELECTED_EXPRESSION - run("SELECT distinct c1, c2 FROM t1 WHERE c1 > 0 order by ts", TSDB_CODE_PAR_NOT_SELECTED_EXPRESSION, - PARSER_STAGE_TRANSLATE); + run("SELECT distinct c1, c2 FROM t1 WHERE c1 > 0 order by ts", TSDB_CODE_PAR_NOT_SELECTED_EXPRESSION); - run("SELECT distinct c1 FROM t1 WHERE c1 > 0 order by COUNT(c2)", TSDB_CODE_PAR_NOT_SELECTED_EXPRESSION, - PARSER_STAGE_TRANSLATE); + run("SELECT distinct c1 FROM t1 WHERE c1 > 0 order by COUNT(c2)", TSDB_CODE_PAR_NOT_SELECTED_EXPRESSION); - run("SELECT distinct c2 FROM t1 WHERE c1 > 0 order by COUNT(c2)", TSDB_CODE_PAR_NOT_SELECTED_EXPRESSION, - PARSER_STAGE_TRANSLATE); + run("SELECT distinct c2 FROM t1 WHERE c1 > 0 order by COUNT(c2)", TSDB_CODE_PAR_NOT_SELECTED_EXPRESSION); +} + +TEST_F(ParserSelectTest, syntaxError) { + useDb("root", "test"); + + run("SELECT CAST(? AS BINARY(10)) FROM t1", TSDB_CODE_PAR_SYNTAX_ERROR, PARSER_STAGE_PARSE); } TEST_F(ParserSelectTest, setOperator) { diff --git a/source/libs/planner/src/planOptimizer.c b/source/libs/planner/src/planOptimizer.c index d4c470be3c5b88a30b3805ded02e991d6c48bb7e..dee7bd49dbc65f6375c9d132c1d7e253d9933825 100644 --- a/source/libs/planner/src/planOptimizer.c +++ b/source/libs/planner/src/planOptimizer.c @@ -80,6 +80,23 @@ static void optResetParent(SLogicNode* pNode) { FOREACH(pChild, pNode->pChildren) { ((SLogicNode*)pChild)->pParent = pNode; } } +static EDealRes optRebuildTbanme(SNode** pNode, void* pContext) { + if (QUERY_NODE_COLUMN == nodeType(*pNode) && COLUMN_TYPE_TBNAME == ((SColumnNode*)*pNode)->colType) { + SFunctionNode* pFunc = (SFunctionNode*)nodesMakeNode(QUERY_NODE_FUNCTION); + if (NULL == pFunc) { + *(int32_t*)pContext = TSDB_CODE_OUT_OF_MEMORY; + return DEAL_RES_ERROR; + } + strcpy(pFunc->functionName, "tbname"); + pFunc->funcType = FUNCTION_TYPE_TBNAME; + pFunc->node.resType = ((SColumnNode*)*pNode)->node.resType; + nodesDestroyNode(*pNode); + *pNode = (SNode*)pFunc; + return DEAL_RES_IGNORE_CHILD; + } + return DEAL_RES_CONTINUE; +} + EDealRes scanPathOptHaveNormalColImpl(SNode* pNode, void* pContext) { if (QUERY_NODE_COLUMN == nodeType(pNode)) { // *((bool*)pContext) = (COLUMN_TYPE_TAG != ((SColumnNode*)pNode)->colType); @@ -312,6 +329,12 @@ static int32_t pushDownCondOptCalcTimeRange(SOptimizeContext* pCxt, SScanLogicNo return code; } +static int32_t pushDownCondOptRebuildTbanme(SNode** pTagCond) { + int32_t code = TSDB_CODE_SUCCESS; + nodesRewriteExpr(pTagCond, optRebuildTbanme, &code); + return code; +} + static int32_t pushDownCondOptDealScan(SOptimizeContext* pCxt, SScanLogicNode* pScan) { if (NULL == pScan->node.pConditions || OPTIMIZE_FLAG_TEST_MASK(pScan->node.optimizedFlag, OPTIMIZE_FLAG_PUSH_DOWN_CONDE) || @@ -323,6 +346,9 @@ static int32_t pushDownCondOptDealScan(SOptimizeContext* pCxt, SScanLogicNode* p SNode* pOtherCond = NULL; int32_t code = nodesPartitionCond(&pScan->node.pConditions, &pPrimaryKeyCond, &pScan->pTagIndexCond, &pScan->pTagCond, &pOtherCond); + if (TSDB_CODE_SUCCESS == code && NULL != pScan->pTagCond) { + code = pushDownCondOptRebuildTbanme(&pScan->pTagCond); + } if (TSDB_CODE_SUCCESS == code && NULL != pPrimaryKeyCond) { code = pushDownCondOptCalcTimeRange(pCxt, pScan, &pPrimaryKeyCond, &pOtherCond); } @@ -1386,26 +1412,9 @@ static bool partTagsOptMayBeOptimized(SLogicNode* pNode) { return !partTagsOptHasCol(partTagsGetPartKeys(pNode)) && partTagsOptAreSupportedFuncs(partTagsGetFuncs(pNode)); } -static EDealRes partTagsOptRebuildTbanmeImpl(SNode** pNode, void* pContext) { - if (QUERY_NODE_COLUMN == nodeType(*pNode) && COLUMN_TYPE_TBNAME == ((SColumnNode*)*pNode)->colType) { - SFunctionNode* pFunc = (SFunctionNode*)nodesMakeNode(QUERY_NODE_FUNCTION); - if (NULL == pFunc) { - *(int32_t*)pContext = TSDB_CODE_OUT_OF_MEMORY; - return DEAL_RES_ERROR; - } - strcpy(pFunc->functionName, "tbname"); - pFunc->funcType = FUNCTION_TYPE_TBNAME; - pFunc->node.resType = ((SColumnNode*)*pNode)->node.resType; - nodesDestroyNode(*pNode); - *pNode = (SNode*)pFunc; - return DEAL_RES_IGNORE_CHILD; - } - return DEAL_RES_CONTINUE; -} - static int32_t partTagsOptRebuildTbanme(SNodeList* pPartKeys) { int32_t code = TSDB_CODE_SUCCESS; - nodesRewriteExprs(pPartKeys, partTagsOptRebuildTbanmeImpl, &code); + nodesRewriteExprs(pPartKeys, optRebuildTbanme, &code); return code; } diff --git a/source/libs/planner/test/planOptimizeTest.cpp b/source/libs/planner/test/planOptimizeTest.cpp index e4019292d81fa5c5578c1943367992fff7f60dbc..ef056c5ec8437d80bc4b8dfd5c249bbc89bb306e 100644 --- a/source/libs/planner/test/planOptimizeTest.cpp +++ b/source/libs/planner/test/planOptimizeTest.cpp @@ -37,6 +37,8 @@ TEST_F(PlanOptimizeTest, pushDownCondition) { run("SELECT ts, c1 FROM st1 WHERE tag1 > 4"); + run("SELECT ts, c1 FROM st1 WHERE TBNAME = 'st1s1'"); + run("SELECT ts, c1 FROM st1 WHERE tag1 > 4 or tag1 < 2"); run("SELECT ts, c1 FROM st1 WHERE tag1 > 4 AND tag2 = 'hello'");