diff --git a/include/libs/function/functionMgt.h b/include/libs/function/functionMgt.h index 741b0fddeb..c9c19579cb 100644 --- a/include/libs/function/functionMgt.h +++ b/include/libs/function/functionMgt.h @@ -176,7 +176,8 @@ int32_t fmGetFuncInfo(SFunctionNode* pFunc, char* pMsg, int32_t msgLen); EFuncReturnRows fmGetFuncReturnRows(SFunctionNode* pFunc); -bool fmIsBuiltinFunc(const char* pFunc); +bool fmIsBuiltinFunc(const char* pFunc); +EFunctionType fmGetFuncType(const char* pFunc); bool fmIsAggFunc(int32_t funcId); bool fmIsScalarFunc(int32_t funcId); diff --git a/source/client/inc/clientInt.h b/source/client/inc/clientInt.h index d8aea55529..b8fa9580e7 100644 --- a/source/client/inc/clientInt.h +++ b/source/client/inc/clientInt.h @@ -104,6 +104,7 @@ typedef struct SQueryExecMetric { int64_t ctgEnd; // end to parse, us int64_t semanticEnd; int64_t planEnd; + int64_t resultReady; int64_t execEnd; int64_t send; // start to send to server, us int64_t rsp; // receive response from server, us diff --git a/source/client/src/clientEnv.c b/source/client/src/clientEnv.c index 9117287b32..bf92a9ba6a 100644 --- a/source/client/src/clientEnv.c +++ b/source/client/src/clientEnv.c @@ -76,19 +76,19 @@ static void deregisterRequest(SRequestObj *pRequest) { pRequest->self, pTscObj->id, pRequest->requestId, duration / 1000, num, currentInst); if (QUERY_NODE_VNODE_MODIF_STMT == pRequest->stmtType) { - tscPerf("insert duration %" PRId64 "us: syntax:%" PRId64 "us, ctg:%" PRId64 "us, semantic:%" PRId64 "us, exec:%" PRId64 "us", - duration, pRequest->metric.syntaxEnd - pRequest->metric.syntaxStart, - pRequest->metric.ctgEnd - pRequest->metric.ctgStart, - pRequest->metric.semanticEnd - pRequest->metric.ctgEnd, + tscPerf("insert duration %" PRId64 "us: syntax:%" PRId64 "us, ctg:%" PRId64 "us, semantic:%" PRId64 + "us, exec:%" PRId64 "us", + duration, pRequest->metric.syntaxEnd - pRequest->metric.syntaxStart, + pRequest->metric.ctgEnd - pRequest->metric.ctgStart, pRequest->metric.semanticEnd - pRequest->metric.ctgEnd, pRequest->metric.execEnd - pRequest->metric.semanticEnd); atomic_add_fetch_64((int64_t *)&pActivity->insertElapsedTime, duration); } else if (QUERY_NODE_SELECT_STMT == pRequest->stmtType) { - tscPerf("select duration %" PRId64 "us: syntax:%" PRId64 "us, ctg:%" PRId64 "us, semantic:%" PRId64 "us, planner:%" PRId64 "us, exec:%" PRId64 "us", - duration, pRequest->metric.syntaxEnd - pRequest->metric.syntaxStart, - pRequest->metric.ctgEnd - pRequest->metric.ctgStart, - pRequest->metric.semanticEnd - pRequest->metric.ctgEnd, + tscPerf("select duration %" PRId64 "us: syntax:%" PRId64 "us, ctg:%" PRId64 "us, semantic:%" PRId64 + "us, planner:%" PRId64 "us, exec:%" PRId64 "us", + duration, pRequest->metric.syntaxEnd - pRequest->metric.syntaxStart, + pRequest->metric.ctgEnd - pRequest->metric.ctgStart, pRequest->metric.semanticEnd - pRequest->metric.ctgEnd, pRequest->metric.planEnd - pRequest->metric.semanticEnd, - nowUs - pRequest->metric.semanticEnd); + pRequest->metric.resultReady - pRequest->metric.planEnd); atomic_add_fetch_64((int64_t *)&pActivity->queryElapsedTime, duration); } diff --git a/source/client/src/clientImpl.c b/source/client/src/clientImpl.c index 97429e099b..f91ceb3184 100644 --- a/source/client/src/clientImpl.c +++ b/source/client/src/clientImpl.c @@ -728,7 +728,7 @@ int32_t handleSubmitExecRes(SRequestObj* pRequest, void* res, SCatalog* pCatalog tFreeSTableMetaRsp(blk->pMeta); taosMemoryFreeClear(blk->pMeta); } - + if (NULL == blk->tblFName || 0 == blk->tblFName[0]) { continue; } @@ -851,6 +851,8 @@ void schedulerExecCb(SExecResult* pResult, void* param, int32_t code) { SRequestObj* pRequest = (SRequestObj*)param; pRequest->code = code; + pRequest->metric.resultReady = taosGetTimestampUs(); + if (pResult) { memcpy(&pRequest->body.resInfo.execRes, pResult, sizeof(*pResult)); } diff --git a/source/libs/function/src/functionMgt.c b/source/libs/function/src/functionMgt.c index 152a970c48..26735fa263 100644 --- a/source/libs/function/src/functionMgt.c +++ b/source/libs/function/src/functionMgt.c @@ -101,6 +101,14 @@ bool fmIsBuiltinFunc(const char* pFunc) { return NULL != taosHashGet(gFunMgtService.pFuncNameHashTable, pFunc, strlen(pFunc)); } +EFunctionType fmGetFuncType(const char* pFunc) { + void* pVal = taosHashGet(gFunMgtService.pFuncNameHashTable, pFunc, strlen(pFunc)); + if (NULL != pVal) { + return funcMgtBuiltins[*(int32_t*)pVal].type; + } + return FUNCTION_TYPE_UDF; +} + EFuncDataRequired fmFuncDataRequired(SFunctionNode* pFunc, STimeWindow* pTimeWindow) { if (fmIsUserDefinedFunc(pFunc->funcId) || pFunc->funcId < 0 || pFunc->funcId >= funcMgtBuiltinsNum) { return FUNC_DATA_REQUIRED_DATA_LOAD; diff --git a/source/libs/parser/src/parAstParser.c b/source/libs/parser/src/parAstParser.c index 1fb0642eb7..4dcd2bba5a 100644 --- a/source/libs/parser/src/parAstParser.c +++ b/source/libs/parser/src/parAstParser.c @@ -97,16 +97,23 @@ typedef struct SCollectMetaKeyCxt { typedef struct SCollectMetaKeyFromExprCxt { SCollectMetaKeyCxt* pComCxt; + bool hasLastRow; int32_t errCode; } SCollectMetaKeyFromExprCxt; static int32_t collectMetaKeyFromQuery(SCollectMetaKeyCxt* pCxt, SNode* pStmt); static EDealRes collectMetaKeyFromFunction(SCollectMetaKeyFromExprCxt* pCxt, SFunctionNode* pFunc) { - if (fmIsBuiltinFunc(pFunc->functionName)) { - return DEAL_RES_CONTINUE; + switch (fmGetFuncType(pFunc->functionName)) { + case FUNCTION_TYPE_LAST_ROW: + pCxt->hasLastRow = true; + break; + case FUNCTION_TYPE_UDF: + pCxt->errCode = reserveUdfInCache(pFunc->functionName, pCxt->pComCxt->pMetaCache); + break; + default: + break; } - pCxt->errCode = reserveUdfInCache(pFunc->functionName, pCxt->pComCxt->pMetaCache); return TSDB_CODE_SUCCESS == pCxt->errCode ? DEAL_RES_CONTINUE : DEAL_RES_ERROR; } @@ -136,9 +143,6 @@ static int32_t collectMetaKeyFromRealTableImpl(SCollectMetaKeyCxt* pCxt, const c if (TSDB_CODE_SUCCESS == code && (0 == strcmp(pTable, TSDB_INS_TABLE_DNODE_VARIABLES))) { code = reserveDnodeRequiredInCache(pCxt->pMetaCache); } - if (TSDB_CODE_SUCCESS == code) { - code = reserveDbCfgInCache(pCxt->pParseCxt->acctId, pDb, pCxt->pMetaCache); - } return code; } @@ -185,9 +189,19 @@ static int32_t collectMetaKeyFromSetOperator(SCollectMetaKeyCxt* pCxt, SSetOpera return code; } +static int32_t reserveDbCfgForLastRow(SCollectMetaKeyCxt* pCxt, SNode* pTable) { + if (NULL == pTable || QUERY_NODE_REAL_TABLE != nodeType(pTable)) { + return TSDB_CODE_SUCCESS; + } + return reserveDbCfgInCache(pCxt->pParseCxt->acctId, ((SRealTableNode*)pTable)->table.dbName, pCxt->pMetaCache); +} + static int32_t collectMetaKeyFromSelect(SCollectMetaKeyCxt* pCxt, SSelectStmt* pStmt) { - SCollectMetaKeyFromExprCxt cxt = {.pComCxt = pCxt, .errCode = TSDB_CODE_SUCCESS}; + SCollectMetaKeyFromExprCxt cxt = {.pComCxt = pCxt, .hasLastRow = false, .errCode = TSDB_CODE_SUCCESS}; nodesWalkSelectStmt(pStmt, SQL_CLAUSE_FROM, collectMetaKeyFromExprImpl, &cxt); + if (TSDB_CODE_SUCCESS == cxt.errCode && cxt.hasLastRow) { + cxt.errCode = reserveDbCfgForLastRow(pCxt, pStmt->pFromTable); + } return cxt.errCode; } diff --git a/source/libs/parser/src/parTranslater.c b/source/libs/parser/src/parTranslater.c index 73e252fa87..a857d575f1 100644 --- a/source/libs/parser/src/parTranslater.c +++ b/source/libs/parser/src/parTranslater.c @@ -2160,15 +2160,16 @@ static int32_t setTableIndex(STranslateContext* pCxt, SName* pName, SRealTableNo return TSDB_CODE_SUCCESS; } -static int32_t setTableCacheLastMode(STranslateContext* pCxt, SName* pName, SRealTableNode* pRealTable) { - if (TSDB_SYSTEM_TABLE == pRealTable->pMeta->tableType) { +static int32_t setTableCacheLastMode(STranslateContext* pCxt, SSelectStmt* pSelect) { + if (!pSelect->hasLastRowFunc || QUERY_NODE_REAL_TABLE != nodeType(pSelect->pFromTable)) { return TSDB_CODE_SUCCESS; } - SDbCfgInfo dbCfg = {0}; - int32_t code = getDBCfg(pCxt, pRealTable->table.dbName, &dbCfg); + SRealTableNode* pTable = (SRealTableNode*)pSelect->pFromTable; + SDbCfgInfo dbCfg = {0}; + int32_t code = getDBCfg(pCxt, pTable->table.dbName, &dbCfg); if (TSDB_CODE_SUCCESS == code) { - pRealTable->cacheLastMode = dbCfg.cacheLast; + pTable->cacheLastMode = dbCfg.cacheLast; } return code; } @@ -2192,9 +2193,6 @@ static int32_t translateTable(STranslateContext* pCxt, SNode* pTable) { if (TSDB_CODE_SUCCESS == code) { code = setTableIndex(pCxt, &name, pRealTable); } - if (TSDB_CODE_SUCCESS == code) { - code = setTableCacheLastMode(pCxt, &name, pRealTable); - } } if (TSDB_CODE_SUCCESS == code) { pRealTable->table.precision = pRealTable->pMeta->tableInfo.precision; @@ -2273,10 +2271,14 @@ static SNode* createMultiResFunc(SFunctionNode* pSrcFunc, SExprNode* pExpr) { if (QUERY_NODE_COLUMN == nodeType(pExpr)) { SColumnNode* pCol = (SColumnNode*)pExpr; 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)); } else { len = snprintf(buf, sizeof(buf), "%s(%s)", pSrcFunc->functionName, pExpr->aliasName); + strncpy(pFunc->node.aliasName, buf, TMIN(len, sizeof(pFunc->node.aliasName) - 1)); + strncpy(pFunc->node.userAlias, buf, TMIN(len, sizeof(pFunc->node.userAlias) - 1)); } - strncpy(pFunc->node.aliasName, buf, TMIN(len, sizeof(pFunc->node.aliasName) - 1)); return (SNode*)pFunc; } @@ -3140,6 +3142,9 @@ static int32_t translateSelectFrom(STranslateContext* pCxt, SSelectStmt* pSelect if (TSDB_CODE_SUCCESS == code) { code = replaceOrderByAliasForSelect(pCxt, pSelect); } + if (TSDB_CODE_SUCCESS == code) { + code = setTableCacheLastMode(pCxt, pSelect); + } return code; }