From a4944d55163b2436ba42b6b05fe1e35bf20ca490 Mon Sep 17 00:00:00 2001 From: Cary Xu Date: Wed, 11 May 2022 18:25:37 +0800 Subject: [PATCH 1/4] fix: calculate col offset --- source/common/src/trow.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/common/src/trow.c b/source/common/src/trow.c index 44bcd72a33..d1516403c1 100644 --- a/source/common/src/trow.c +++ b/source/common/src/trow.c @@ -1159,7 +1159,7 @@ bool tdGetKvRowValOfColEx(STSRowIter *pIter, col_id_t colId, col_type_t colType, #ifdef TD_SUPPORT_BITMAP int16_t colIdx = -1; - if (pKvIdx) colIdx = POINTER_DISTANCE(TD_ROW_COL_IDX(pRow), pKvIdx) / sizeof(SKvRowIdx); + if (pKvIdx) colIdx = POINTER_DISTANCE(pKvIdx, TD_ROW_COL_IDX(pRow)) / sizeof(SKvRowIdx); if (tdGetBitmapValType(pIter->pBitmap, colIdx, &pVal->valType, 0) != TSDB_CODE_SUCCESS) { pVal->valType = TD_VTYPE_NONE; } @@ -1226,7 +1226,7 @@ bool tdSTSRowGetVal(STSRowIter *pIter, col_id_t colId, col_type_t colType, SCell compareKvRowColId, TD_EQ); #ifdef TD_SUPPORT_BITMAP if (pIdx) { - colIdx = POINTER_DISTANCE(TD_ROW_COL_IDX(pRow), pIdx) / sizeof(SKvRowIdx); + colIdx = POINTER_DISTANCE(pIdx, TD_ROW_COL_IDX(pRow)) / sizeof(SKvRowIdx); } #endif tdGetKvRowValOfCol(pVal, pRow, pIter->pBitmap, pIdx ? pIdx->offset : -1, colIdx); From 41e36dddb786a26b336162057e8877519a56881b Mon Sep 17 00:00:00 2001 From: Xiaoyu Wang Date: Wed, 11 May 2022 19:03:59 +0800 Subject: [PATCH 2/4] fix: some problems of parser --- include/common/tvariant.h | 9 +- include/libs/planner/planner.h | 3 +- source/client/src/clientStmt.c | 220 +++++++-------- source/common/src/tvariant.c | 114 ++------ source/common/test/commonTests.cpp | 91 +++---- source/libs/function/src/builtins.c | 42 +-- source/libs/parser/src/parAstCreater.c | 21 +- source/libs/parser/src/parInsert.c | 155 ++++++----- source/libs/parser/src/parTranslater.c | 3 + source/libs/parser/test/parInitialCTest.cpp | 279 +++++++++++++++----- source/libs/planner/src/planner.c | 141 +++++++++- 11 files changed, 639 insertions(+), 439 deletions(-) diff --git a/include/common/tvariant.h b/include/common/tvariant.h index 83dccd0092..9728e5ecd5 100644 --- a/include/common/tvariant.h +++ b/include/common/tvariant.h @@ -36,12 +36,11 @@ typedef struct SVariant { }; } SVariant; -int32_t toInteger(const char *z, int32_t n, int32_t base, int64_t *value, bool *issigned); +int32_t toInteger(const char *z, int32_t n, int32_t base, int64_t *value); +int32_t toUInteger(const char *z, int32_t n, int32_t base, uint64_t *value); bool taosVariantIsValid(SVariant *pVar); -void taosVariantCreate(SVariant *pVar, const char *z, int32_t n, int32_t type); - void taosVariantCreateFromBinary(SVariant *pVar, const char *pz, size_t len, uint32_t type); void taosVariantDestroy(SVariant *pV); @@ -59,10 +58,10 @@ int32_t taosVariantDumpEx(SVariant *pVariant, char *payload, int16_t type, bool #endif int32_t taosVariantTypeSetType(SVariant *pVariant, char type); -char * taosVariantGet(SVariant *pVar, int32_t type); +char *taosVariantGet(SVariant *pVar, int32_t type); #ifdef __cplusplus } #endif -#endif /*_TD_COMMON_VARIANT_H_*/ +#endif /*_TD_COMMON_VARIANT_H_*/ diff --git a/include/libs/planner/planner.h b/include/libs/planner/planner.h index 367407cae5..e250b7b2b2 100644 --- a/include/libs/planner/planner.h +++ b/include/libs/planner/planner.h @@ -48,7 +48,8 @@ int32_t qCreateQueryPlan(SPlanContext* pCxt, SQueryPlan** pPlan, SArray* pExecNo // @pSource one execution location of this group of datasource subplans int32_t qSetSubplanExecutionNode(SSubplan* pSubplan, int32_t groupId, SDownstreamSourceNode* pSource); -int32_t qStmtBindParam(SQueryPlan* pPlan, TAOS_MULTI_BIND* pParams, int32_t colIdx, uint64_t queryId); +int32_t qStmtBindParam(SQueryPlan* pPlan, TAOS_MULTI_BIND* pParams, int32_t colIdx, uint64_t queryId, + bool* pEmptyResult); // Convert to subplan to string for the scheduler to send to the executor int32_t qSubPlanToString(const SSubplan* pSubplan, char** pStr, int32_t* pLen); diff --git a/source/client/src/clientStmt.c b/source/client/src/clientStmt.c index c804213d89..d69ab4413b 100644 --- a/source/client/src/clientStmt.c +++ b/source/client/src/clientStmt.c @@ -1,12 +1,13 @@ #include "clientInt.h" #include "clientLog.h" -#include "clientStmt.h" #include "tdef.h" +#include "clientStmt.h" + int32_t stmtSwitchStatus(STscStmt* pStmt, STMT_STATUS newStatus) { int32_t code = 0; - + switch (newStatus) { case STMT_PREPARE: break; @@ -29,11 +30,11 @@ int32_t stmtSwitchStatus(STscStmt* pStmt, STMT_STATUS newStatus) { if (STMT_STATUS_EQ(INIT) || STMT_STATUS_EQ(BIND_COL)) { code = TSDB_CODE_TSC_STMT_API_ERROR; } -/* - if ((pStmt->sql.type == STMT_TYPE_MULTI_INSERT) && ()) { - code = TSDB_CODE_TSC_STMT_API_ERROR; - } -*/ + /* + if ((pStmt->sql.type == STMT_TYPE_MULTI_INSERT) && ()) { + code = TSDB_CODE_TSC_STMT_API_ERROR; + } + */ break; case STMT_BIND_COL: if (STMT_STATUS_EQ(INIT) || STMT_STATUS_EQ(BIND)) { @@ -62,12 +63,11 @@ int32_t stmtSwitchStatus(STscStmt* pStmt, STMT_STATUS newStatus) { return TSDB_CODE_SUCCESS; } - -int32_t stmtGetTbName(TAOS_STMT *stmt, char **tbName) { +int32_t stmtGetTbName(TAOS_STMT* stmt, char** tbName) { STscStmt* pStmt = (STscStmt*)stmt; pStmt->sql.type = STMT_TYPE_MULTI_INSERT; - + if (NULL == pStmt->bInfo.tbName) { tscError("no table name set"); STMT_ERR_RET(TSDB_CODE_TSC_STMT_TBNAME_ERROR); @@ -79,10 +79,10 @@ int32_t stmtGetTbName(TAOS_STMT *stmt, char **tbName) { } int32_t stmtBackupQueryFields(STscStmt* pStmt) { - SStmtQueryResInfo *pRes = &pStmt->sql.queryRes; + SStmtQueryResInfo* pRes = &pStmt->sql.queryRes; pRes->numOfCols = pStmt->exec.pRequest->body.resInfo.numOfCols; pRes->precision = pStmt->exec.pRequest->body.resInfo.precision; - + int32_t size = pRes->numOfCols * sizeof(TAOS_FIELD); pRes->fields = taosMemoryMalloc(size); pRes->userFields = taosMemoryMalloc(size); @@ -96,9 +96,9 @@ int32_t stmtBackupQueryFields(STscStmt* pStmt) { } int32_t stmtRestoreQueryFields(STscStmt* pStmt) { - SStmtQueryResInfo *pRes = &pStmt->sql.queryRes; - int32_t size = pRes->numOfCols * sizeof(TAOS_FIELD); - + SStmtQueryResInfo* pRes = &pStmt->sql.queryRes; + int32_t size = pRes->numOfCols * sizeof(TAOS_FIELD); + pStmt->exec.pRequest->body.resInfo.numOfCols = pRes->numOfCols; pStmt->exec.pRequest->body.resInfo.precision = pRes->precision; @@ -151,12 +151,12 @@ int32_t stmtGetExecInfo(TAOS_STMT* stmt, SHashObj** pVgHash, SHashObj** pBlockHa return TSDB_CODE_SUCCESS; } -int32_t stmtCacheBlock(STscStmt *pStmt) { +int32_t stmtCacheBlock(STscStmt* pStmt) { if (pStmt->sql.type != STMT_TYPE_MULTI_INSERT) { return TSDB_CODE_SUCCESS; } - uint64_t uid = pStmt->bInfo.tbUid; + uint64_t uid = pStmt->bInfo.tbUid; uint64_t tuid = (TSDB_CHILD_TABLE == pStmt->bInfo.tbType) ? pStmt->bInfo.tbSuid : uid; if (taosHashGet(pStmt->sql.pTableCache, &tuid, sizeof(tuid))) { @@ -164,13 +164,13 @@ int32_t stmtCacheBlock(STscStmt *pStmt) { } STableDataBlocks** pSrc = taosHashGet(pStmt->exec.pBlockHash, &uid, sizeof(uid)); - STableDataBlocks* pDst = NULL; - + STableDataBlocks* pDst = NULL; + STMT_ERR_RET(qCloneStmtDataBlock(&pDst, *pSrc)); SStmtTableCache cache = { - .pDataBlock = pDst, - .boundTags = pStmt->bInfo.boundTags, + .pDataBlock = pDst, + .boundTags = pStmt->bInfo.boundTags, }; if (taosHashPut(pStmt->sql.pTableCache, &tuid, sizeof(tuid), &cache, sizeof(cache))) { @@ -184,21 +184,21 @@ int32_t stmtCacheBlock(STscStmt *pStmt) { int32_t stmtParseSql(STscStmt* pStmt) { SStmtCallback stmtCb = { - .pStmt = pStmt, - .getTbNameFn = stmtGetTbName, - .setBindInfoFn = stmtSetBindInfo, - .setExecInfoFn = stmtSetExecInfo, - .getExecInfoFn = stmtGetExecInfo, + .pStmt = pStmt, + .getTbNameFn = stmtGetTbName, + .setBindInfoFn = stmtSetBindInfo, + .setExecInfoFn = stmtSetExecInfo, + .getExecInfoFn = stmtGetExecInfo, }; if (NULL == pStmt->exec.pRequest) { STMT_ERR_RET(buildRequest(pStmt->taos, pStmt->sql.sqlStr, pStmt->sql.sqlLen, &pStmt->exec.pRequest)); } - + STMT_ERR_RET(parseSql(pStmt->exec.pRequest, false, &pStmt->sql.pQuery, &stmtCb)); pStmt->bInfo.needParse = false; - + switch (nodeType(pStmt->sql.pQuery->pRoot)) { case QUERY_NODE_VNODE_MODIF_STMT: if (0 == pStmt->sql.type) { @@ -237,14 +237,14 @@ int32_t stmtCleanExecInfo(STscStmt* pStmt, bool keepTable, bool freeRequest) { pStmt->exec.pRequest = NULL; } - void *pIter = taosHashIterate(pStmt->exec.pBlockHash, NULL); + void* pIter = taosHashIterate(pStmt->exec.pBlockHash, NULL); while (pIter) { - STableDataBlocks* pBlocks = *(STableDataBlocks**)pIter; - uint64_t *key = taosHashGetKey(pIter, NULL); - + STableDataBlocks* pBlocks = *(STableDataBlocks**)pIter; + uint64_t* key = taosHashGetKey(pIter, NULL); + if (keepTable && (*key == pStmt->bInfo.tbUid)) { STMT_ERR_RET(qResetStmtDataBlock(pBlocks, true)); - + pIter = taosHashIterate(pStmt->exec.pBlockHash, pIter); continue; } @@ -274,15 +274,15 @@ int32_t stmtCleanSQLInfo(STscStmt* pStmt) { qDestroyQuery(pStmt->sql.pQuery); qDestroyQueryPlan(pStmt->sql.pQueryPlan); taosArrayDestroy(pStmt->sql.nodeList); - - void *pIter = taosHashIterate(pStmt->sql.pTableCache, NULL); + + void* pIter = taosHashIterate(pStmt->sql.pTableCache, NULL); while (pIter) { - SStmtTableCache* pCache = (SStmtTableCache*)pIter; + SStmtTableCache* pCache = (SStmtTableCache*)pIter; qDestroyStmtDataBlock(pCache->pDataBlock); destroyBoundColumnInfo(pCache->boundTags); taosMemoryFreeClear(pCache->boundTags); - + pIter = taosHashIterate(pStmt->sql.pTableCache, pIter); } taosHashCleanup(pStmt->sql.pTableCache); @@ -307,22 +307,23 @@ int32_t stmtGetFromCache(STscStmt* pStmt) { STMT_ERR_RET(catalogGetHandle(pStmt->taos->pAppInfo->clusterId, &pStmt->pCatalog)); } - STableMeta *pTableMeta = NULL; - SEpSet ep = getEpSet_s(&pStmt->taos->pAppInfo->mgmtEp); - int32_t code = catalogGetTableMeta(pStmt->pCatalog, pStmt->taos->pAppInfo->pTransporter, &ep, &pStmt->bInfo.sname, &pTableMeta); + STableMeta* pTableMeta = NULL; + SEpSet ep = getEpSet_s(&pStmt->taos->pAppInfo->mgmtEp); + int32_t code = + catalogGetTableMeta(pStmt->pCatalog, pStmt->taos->pAppInfo->pTransporter, &ep, &pStmt->bInfo.sname, &pTableMeta); if (TSDB_CODE_PAR_TABLE_NOT_EXIST == code) { STMT_ERR_RET(stmtCleanBindInfo(pStmt)); - + return TSDB_CODE_SUCCESS; } STMT_ERR_RET(code); - + uint64_t uid = pTableMeta->uid; uint64_t suid = pTableMeta->suid; - int8_t tableType = pTableMeta->tableType; + int8_t tableType = pTableMeta->tableType; taosMemoryFree(pTableMeta); - + if (uid == pStmt->bInfo.tbUid) { pStmt->bInfo.needParse = false; @@ -333,12 +334,12 @@ int32_t stmtGetFromCache(STscStmt* pStmt) { SStmtTableCache* pCache = taosHashGet(pStmt->sql.pTableCache, &uid, sizeof(uid)); if (NULL == pCache) { tscError("table uid %" PRIx64 "found in exec blockHash, but not in sql blockHash", uid); - + STMT_ERR_RET(TSDB_CODE_TSC_APP_ERROR); } - + pStmt->bInfo.needParse = false; - + pStmt->bInfo.tbUid = uid; pStmt->bInfo.tbSuid = suid; pStmt->bInfo.tbType = tableType; @@ -361,10 +362,11 @@ int32_t stmtGetFromCache(STscStmt* pStmt) { STableDataBlocks* pNewBlock = NULL; STMT_ERR_RET(qRebuildStmtDataBlock(&pNewBlock, pCache->pDataBlock)); - if (taosHashPut(pStmt->exec.pBlockHash, &pStmt->bInfo.tbUid, sizeof(pStmt->bInfo.tbUid), &pNewBlock, POINTER_BYTES)) { + if (taosHashPut(pStmt->exec.pBlockHash, &pStmt->bInfo.tbUid, sizeof(pStmt->bInfo.tbUid), &pNewBlock, + POINTER_BYTES)) { STMT_ERR_RET(TSDB_CODE_OUT_OF_MEMORY); } - + return TSDB_CODE_SUCCESS; } @@ -387,9 +389,8 @@ int32_t stmtResetStmt(STscStmt* pStmt) { return TSDB_CODE_SUCCESS; } - -TAOS_STMT *stmtInit(TAOS *taos) { - STscObj* pObj = (STscObj*)taos; +TAOS_STMT* stmtInit(TAOS* taos) { + STscObj* pObj = (STscObj*)taos; STscStmt* pStmt = NULL; pStmt = taosMemoryCalloc(1, sizeof(STscStmt)); @@ -408,11 +409,11 @@ TAOS_STMT *stmtInit(TAOS *taos) { pStmt->taos = pObj; pStmt->bInfo.needParse = true; pStmt->sql.status = STMT_INIT; - + return pStmt; } -int stmtPrepare(TAOS_STMT *stmt, const char *sql, unsigned long length) { +int stmtPrepare(TAOS_STMT* stmt, const char* sql, unsigned long length) { STscStmt* pStmt = (STscStmt*)stmt; if (pStmt->sql.status >= STMT_PREPARE) { @@ -424,15 +425,14 @@ int stmtPrepare(TAOS_STMT *stmt, const char *sql, unsigned long length) { if (length <= 0) { length = strlen(sql); } - + pStmt->sql.sqlStr = strndup(sql, length); pStmt->sql.sqlLen = length; return TSDB_CODE_SUCCESS; } - -int stmtSetTbName(TAOS_STMT *stmt, const char *tbName) { +int stmtSetTbName(TAOS_STMT* stmt, const char* tbName) { STscStmt* pStmt = (STscStmt*)stmt; STMT_ERR_RET(stmtSwitchStatus(pStmt, STMT_SETTBNAME)); @@ -447,9 +447,10 @@ int stmtSetTbName(TAOS_STMT *stmt, const char *tbName) { if (NULL == pStmt->exec.pRequest) { STMT_ERR_RET(buildRequest(pStmt->taos, pStmt->sql.sqlStr, pStmt->sql.sqlLen, &pStmt->exec.pRequest)); } - - STMT_ERR_RET(qCreateSName(&pStmt->bInfo.sname, tbName, pStmt->taos->acctId, pStmt->exec.pRequest->pDb, pStmt->exec.pRequest->msgBuf, pStmt->exec.pRequest->msgBufLen)); - + + STMT_ERR_RET(qCreateSName(&pStmt->bInfo.sname, tbName, pStmt->taos->acctId, pStmt->exec.pRequest->pDb, + pStmt->exec.pRequest->msgBuf, pStmt->exec.pRequest->msgBufLen)); + STMT_ERR_RET(stmtGetFromCache(pStmt)); if (pStmt->bInfo.needParse) { @@ -460,7 +461,7 @@ int stmtSetTbName(TAOS_STMT *stmt, const char *tbName) { return TSDB_CODE_SUCCESS; } -int stmtSetTbTags(TAOS_STMT *stmt, TAOS_MULTI_BIND *tags) { +int stmtSetTbTags(TAOS_STMT* stmt, TAOS_MULTI_BIND* tags) { STscStmt* pStmt = (STscStmt*)stmt; STMT_ERR_RET(stmtSwitchStatus(pStmt, STMT_SETTAGS)); @@ -471,25 +472,27 @@ int stmtSetTbTags(TAOS_STMT *stmt, TAOS_MULTI_BIND *tags) { STMT_ERR_RET(stmtParseSql(pStmt)); - STableDataBlocks **pDataBlock = (STableDataBlocks**)taosHashGet(pStmt->exec.pBlockHash, (const char*)&pStmt->bInfo.tbUid, sizeof(pStmt->bInfo.tbUid)); + STableDataBlocks** pDataBlock = (STableDataBlocks**)taosHashGet( + pStmt->exec.pBlockHash, (const char*)&pStmt->bInfo.tbUid, sizeof(pStmt->bInfo.tbUid)); if (NULL == pDataBlock) { tscError("table uid %" PRIx64 "not found in exec blockHash", pStmt->bInfo.tbUid); STMT_ERR_RET(TSDB_CODE_QRY_APP_ERROR); } - - STMT_ERR_RET(qBindStmtTagsValue(*pDataBlock, pStmt->bInfo.boundTags, pStmt->bInfo.tbSuid, pStmt->bInfo.sname.tname, tags, pStmt->exec.pRequest->msgBuf, pStmt->exec.pRequest->msgBufLen)); + + STMT_ERR_RET(qBindStmtTagsValue(*pDataBlock, pStmt->bInfo.boundTags, pStmt->bInfo.tbSuid, pStmt->bInfo.sname.tname, + tags, pStmt->exec.pRequest->msgBuf, pStmt->exec.pRequest->msgBufLen)); return TSDB_CODE_SUCCESS; } - -int32_t stmtFetchTagFields(STscStmt* pStmt, int32_t *fieldNum, TAOS_FIELD** fields) { +int32_t stmtFetchTagFields(STscStmt* pStmt, int32_t* fieldNum, TAOS_FIELD** fields) { if (STMT_TYPE_QUERY == pStmt->sql.type) { tscError("invalid operation to get query tag fileds"); STMT_ERR_RET(TSDB_CODE_TSC_STMT_API_ERROR); } - STableDataBlocks **pDataBlock = (STableDataBlocks**)taosHashGet(pStmt->exec.pBlockHash, (const char*)&pStmt->bInfo.tbUid, sizeof(pStmt->bInfo.tbUid)); + STableDataBlocks** pDataBlock = (STableDataBlocks**)taosHashGet( + pStmt->exec.pBlockHash, (const char*)&pStmt->bInfo.tbUid, sizeof(pStmt->bInfo.tbUid)); if (NULL == pDataBlock) { tscError("table uid %" PRIx64 "not found in exec blockHash", pStmt->bInfo.tbUid); STMT_ERR_RET(TSDB_CODE_QRY_APP_ERROR); @@ -500,13 +503,14 @@ int32_t stmtFetchTagFields(STscStmt* pStmt, int32_t *fieldNum, TAOS_FIELD** fiel return TSDB_CODE_SUCCESS; } -int32_t stmtFetchColFields(STscStmt* pStmt, int32_t *fieldNum, TAOS_FIELD** fields) { +int32_t stmtFetchColFields(STscStmt* pStmt, int32_t* fieldNum, TAOS_FIELD** fields) { if (STMT_TYPE_QUERY == pStmt->sql.type) { tscError("invalid operation to get query column fileds"); STMT_ERR_RET(TSDB_CODE_TSC_STMT_API_ERROR); } - STableDataBlocks **pDataBlock = (STableDataBlocks**)taosHashGet(pStmt->exec.pBlockHash, (const char*)&pStmt->bInfo.tbUid, sizeof(pStmt->bInfo.tbUid)); + STableDataBlocks** pDataBlock = (STableDataBlocks**)taosHashGet( + pStmt->exec.pBlockHash, (const char*)&pStmt->bInfo.tbUid, sizeof(pStmt->bInfo.tbUid)); if (NULL == pDataBlock) { tscError("table uid %" PRIx64 "not found in exec blockHash", pStmt->bInfo.tbUid); STMT_ERR_RET(TSDB_CODE_QRY_APP_ERROR); @@ -514,13 +518,14 @@ int32_t stmtFetchColFields(STscStmt* pStmt, int32_t *fieldNum, TAOS_FIELD** fiel STMT_ERR_RET(qBuildStmtColFields(*pDataBlock, fieldNum, fields)); - return TSDB_CODE_SUCCESS; + return TSDB_CODE_SUCCESS; } -int stmtBindBatch(TAOS_STMT *stmt, TAOS_MULTI_BIND *bind, int32_t colIdx) { +int stmtBindBatch(TAOS_STMT* stmt, TAOS_MULTI_BIND* bind, int32_t colIdx) { STscStmt* pStmt = (STscStmt*)stmt; - if (pStmt->bInfo.needParse && pStmt->sql.runTimes && pStmt->sql.type > 0 && STMT_TYPE_MULTI_INSERT != pStmt->sql.type) { + if (pStmt->bInfo.needParse && pStmt->sql.runTimes && pStmt->sql.type > 0 && + STMT_TYPE_MULTI_INSERT != pStmt->sql.type) { pStmt->bInfo.needParse = false; } @@ -528,7 +533,7 @@ int stmtBindBatch(TAOS_STMT *stmt, TAOS_MULTI_BIND *bind, int32_t colIdx) { taos_free_result(pStmt->exec.pRequest); pStmt->exec.pRequest = NULL; } - + if (NULL == pStmt->exec.pRequest) { STMT_ERR_RET(buildRequest(pStmt->taos, pStmt->sql.sqlStr, pStmt->sql.sqlLen, &pStmt->exec.pRequest)); } @@ -548,11 +553,13 @@ int stmtBindBatch(TAOS_STMT *stmt, TAOS_MULTI_BIND *bind, int32_t colIdx) { } else { STMT_ERR_RET(stmtRestoreQueryFields(pStmt)); } - - STMT_RET(qStmtBindParam(pStmt->sql.pQueryPlan, bind, colIdx, pStmt->exec.pRequest->requestId)); + + bool emptyResult = false; + STMT_RET(qStmtBindParam(pStmt->sql.pQueryPlan, bind, colIdx, pStmt->exec.pRequest->requestId, &emptyResult)); } - - STableDataBlocks **pDataBlock = (STableDataBlocks**)taosHashGet(pStmt->exec.pBlockHash, (const char*)&pStmt->bInfo.tbUid, sizeof(pStmt->bInfo.tbUid)); + + STableDataBlocks** pDataBlock = (STableDataBlocks**)taosHashGet( + pStmt->exec.pBlockHash, (const char*)&pStmt->bInfo.tbUid, sizeof(pStmt->bInfo.tbUid)); if (NULL == pDataBlock) { tscError("table uid %" PRIx64 "not found in exec blockHash", pStmt->bInfo.tbUid); STMT_ERR_RET(TSDB_CODE_QRY_APP_ERROR); @@ -571,31 +578,31 @@ int stmtBindBatch(TAOS_STMT *stmt, TAOS_MULTI_BIND *bind, int32_t colIdx) { } pStmt->bInfo.sBindLastIdx = colIdx; - + if (0 == colIdx) { pStmt->bInfo.sBindRowNum = bind->num; } - - qBindStmtSingleColValue(*pDataBlock, bind, pStmt->exec.pRequest->msgBuf, pStmt->exec.pRequest->msgBufLen, colIdx, pStmt->bInfo.sBindRowNum); + + qBindStmtSingleColValue(*pDataBlock, bind, pStmt->exec.pRequest->msgBuf, pStmt->exec.pRequest->msgBufLen, colIdx, + pStmt->bInfo.sBindRowNum); } - + return TSDB_CODE_SUCCESS; } - -int stmtAddBatch(TAOS_STMT *stmt) { +int stmtAddBatch(TAOS_STMT* stmt) { STscStmt* pStmt = (STscStmt*)stmt; STMT_ERR_RET(stmtSwitchStatus(pStmt, STMT_ADD_BATCH)); STMT_ERR_RET(stmtCacheBlock(pStmt)); - + return TSDB_CODE_SUCCESS; } -int stmtExec(TAOS_STMT *stmt) { +int stmtExec(TAOS_STMT* stmt) { STscStmt* pStmt = (STscStmt*)stmt; - int32_t code = 0; + int32_t code = 0; STMT_ERR_RET(stmtSwitchStatus(pStmt, STMT_EXECUTE)); @@ -615,7 +622,7 @@ int stmtExec(TAOS_STMT *stmt) { STMT_ERR_RET(TSDB_CODE_NEED_RETRY); } } - + STMT_ERR_JRET(pStmt->exec.pRequest->code); pStmt->exec.affectedRows = taos_affected_rows(pStmt->exec.pRequest); @@ -624,14 +631,13 @@ int stmtExec(TAOS_STMT *stmt) { _return: stmtCleanExecInfo(pStmt, (code ? false : true), false); - + ++pStmt->sql.runTimes; - + STMT_RET(code); } - -int stmtClose(TAOS_STMT *stmt) { +int stmtClose(TAOS_STMT* stmt) { STscStmt* pStmt = (STscStmt*)stmt; STMT_RET(stmtCleanSQLInfo(pStmt)); @@ -639,11 +645,11 @@ int stmtClose(TAOS_STMT *stmt) { taosMemoryFree(stmt); } -const char *stmtErrstr(TAOS_STMT *stmt) { +const char* stmtErrstr(TAOS_STMT* stmt) { STscStmt* pStmt = (STscStmt*)stmt; if (stmt == NULL || NULL == pStmt->exec.pRequest) { - return (char*) tstrerror(terrno); + return (char*)tstrerror(terrno); } pStmt->exec.pRequest->code = terrno; @@ -651,15 +657,11 @@ const char *stmtErrstr(TAOS_STMT *stmt) { return taos_errstr(pStmt->exec.pRequest); } -int stmtAffectedRows(TAOS_STMT *stmt) { - return ((STscStmt*)stmt)->affectedRows; -} +int stmtAffectedRows(TAOS_STMT* stmt) { return ((STscStmt*)stmt)->affectedRows; } -int stmtAffectedRowsOnce(TAOS_STMT *stmt) { - return ((STscStmt*)stmt)->exec.affectedRows; -} +int stmtAffectedRowsOnce(TAOS_STMT* stmt) { return ((STscStmt*)stmt)->exec.affectedRows; } -int stmtIsInsert(TAOS_STMT *stmt, int *insert) { +int stmtIsInsert(TAOS_STMT* stmt, int* insert) { STscStmt* pStmt = (STscStmt*)stmt; if (pStmt->sql.type) { @@ -667,16 +669,17 @@ int stmtIsInsert(TAOS_STMT *stmt, int *insert) { } else { *insert = isInsertSql(pStmt->sql.sqlStr, 0); } - + return TSDB_CODE_SUCCESS; } -int stmtGetParamNum(TAOS_STMT *stmt, int *nums) { +int stmtGetParamNum(TAOS_STMT* stmt, int* nums) { STscStmt* pStmt = (STscStmt*)stmt; STMT_ERR_RET(stmtSwitchStatus(pStmt, STMT_FETCH_FIELDS)); - if (pStmt->bInfo.needParse && pStmt->sql.runTimes && pStmt->sql.type > 0 && STMT_TYPE_MULTI_INSERT != pStmt->sql.type) { + if (pStmt->bInfo.needParse && pStmt->sql.runTimes && pStmt->sql.type > 0 && + STMT_TYPE_MULTI_INSERT != pStmt->sql.type) { pStmt->bInfo.needParse = false; } @@ -684,7 +687,7 @@ int stmtGetParamNum(TAOS_STMT *stmt, int *nums) { taos_free_result(pStmt->exec.pRequest); pStmt->exec.pRequest = NULL; } - + if (NULL == pStmt->exec.pRequest) { STMT_ERR_RET(buildRequest(pStmt->taos, pStmt->sql.sqlStr, pStmt->sql.sqlLen, &pStmt->exec.pRequest)); } @@ -702,16 +705,16 @@ int stmtGetParamNum(TAOS_STMT *stmt, int *nums) { } else { STMT_ERR_RET(stmtRestoreQueryFields(pStmt)); } - + *nums = taosArrayGetSize(pStmt->sql.pQueryPlan->pPlaceholderValues); } else { STMT_ERR_RET(stmtFetchColFields(stmt, nums, NULL)); } - + return TSDB_CODE_SUCCESS; } -TAOS_RES *stmtUseResult(TAOS_STMT *stmt) { +TAOS_RES* stmtUseResult(TAOS_STMT* stmt) { STscStmt* pStmt = (STscStmt*)stmt; if (STMT_TYPE_QUERY != pStmt->sql.type) { @@ -721,6 +724,3 @@ TAOS_RES *stmtUseResult(TAOS_STMT *stmt) { return pStmt->exec.pRequest; } - - - diff --git a/source/common/src/tvariant.c b/source/common/src/tvariant.c index a546d9bb6b..e44450fe6e 100644 --- a/source/common/src/tvariant.c +++ b/source/common/src/tvariant.c @@ -35,104 +35,36 @@ assert(0); \ } while (0) -int32_t toInteger(const char *z, int32_t n, int32_t base, int64_t *value, bool *isSigned) { +int32_t toInteger(const char *z, int32_t n, int32_t base, int64_t *value) { errno = 0; char *endPtr = NULL; - int32_t index = 0; - - bool specifiedSign = (z[0] == '+' || z[0] == '-'); - if (specifiedSign) { - *isSigned = true; - index = 1; - } - - uint64_t val = strtoull(&z[index], &endPtr, base); - if (errno == ERANGE || errno == EINVAL) { + *value = strtoll(z, &endPtr, base); + if (errno == ERANGE || errno == EINVAL || endPtr - z != n) { errno = 0; return -1; } - if (specifiedSign && val > INT64_MAX) { - return -1; - } - - if (endPtr - &z[index] != n - index) { - return -1; - } - - *isSigned = specifiedSign || (val <= INT64_MAX); - if (*isSigned) { - *value = (z[0] == '-') ? -val : val; - } else { - *(uint64_t *)value = val; - } - return 0; } -void taosVariantCreate(SVariant *pVar, const char *z, int32_t n, int32_t type) { - int32_t ret = 0; - memset(pVar, 0, sizeof(SVariant)); +int32_t toUInteger(const char *z, int32_t n, int32_t base, uint64_t *value) { + errno = 0; + char *endPtr = NULL; - switch (type) { - case TSDB_DATA_TYPE_BOOL: { - if (strncasecmp(z, "true", 4) == 0) { - pVar->i = TSDB_TRUE; - } else if (strncasecmp(z, "false", 5) == 0) { - pVar->i = TSDB_FALSE; - } else { - return; - } - break; - } - - case TSDB_DATA_TYPE_TINYINT: - case TSDB_DATA_TYPE_SMALLINT: - case TSDB_DATA_TYPE_BIGINT: - case TSDB_DATA_TYPE_INT: { - bool sign = true; - - int32_t base = 10; - if (type == TK_NK_HEX) { - base = 16; - } else if (type == TK_NK_OCT) { - base = 8; - } else if (type == TK_NK_BIN) { - base = 2; - } - - ret = toInteger(z, n, base, &pVar->i, &sign); - if (ret != 0) { - pVar->nType = -1; // -1 means error type - return; - } - - pVar->nType = (sign) ? TSDB_DATA_TYPE_BIGINT : TSDB_DATA_TYPE_UBIGINT; - break; - } - case TSDB_DATA_TYPE_DOUBLE: - case TSDB_DATA_TYPE_FLOAT: { - pVar->d = strtod(z, NULL); - break; - } - case TSDB_DATA_TYPE_BINARY: { - pVar->pz = strndup(z, n); - //pVar->nLen = strRmquote(pVar->pz, n); - break; - } - case TSDB_DATA_TYPE_TIMESTAMP: { - assert(0); - pVar->i = taosGetTimestamp(TSDB_TIME_PRECISION_NANO); - break; - } - - default: { // nType == 0 means the null value - type = TSDB_DATA_TYPE_NULL; - } + const char *p = z; + while (*p != 0 && *p == ' ') p++; + if (*p != 0 && *p == '-') { + return -1; } - pVar->nType = type; + *value = strtoull(z, &endPtr, base); + if (errno == ERANGE || errno == EINVAL || endPtr - z != n) { + errno = 0; + return -1; + } + + return 0; } /** @@ -461,7 +393,7 @@ static int32_t toNchar(SVariant *pVariant, char **pDest, int32_t *pDestSize) { if (*pDest == pVariant->pz) { TdUcs4 *pWStr = taosMemoryCalloc(1, (nLen + 1) * TSDB_NCHAR_SIZE); - bool ret = taosMbsToUcs4(pDst, nLen, pWStr, (nLen + 1) * TSDB_NCHAR_SIZE, NULL); + bool ret = taosMbsToUcs4(pDst, nLen, pWStr, (nLen + 1) * TSDB_NCHAR_SIZE, NULL); if (!ret) { taosMemoryFreeClear(pWStr); return -1; @@ -483,7 +415,7 @@ static int32_t toNchar(SVariant *pVariant, char **pDest, int32_t *pDestSize) { } else { int32_t output = 0; - bool ret = taosMbsToUcs4(pDst, nLen, (TdUcs4*)*pDest, (nLen + 1) * TSDB_NCHAR_SIZE, &output); + bool ret = taosMbsToUcs4(pDst, nLen, (TdUcs4 *)*pDest, (nLen + 1) * TSDB_NCHAR_SIZE, &output); if (!ret) { return -1; } @@ -518,9 +450,9 @@ static FORCE_INLINE int32_t convertToInteger(SVariant *pVariant, int64_t *result } else if (IS_UNSIGNED_NUMERIC_TYPE(pVariant->nType)) { *result = pVariant->u; } else if (IS_FLOAT_TYPE(pVariant->nType)) { - *result = (int64_t) pVariant->d; + *result = (int64_t)pVariant->d; } else { - //TODO: handling var types + // TODO: handling var types } #if 0 errno = 0; @@ -909,7 +841,7 @@ int32_t tVariantDumpEx(SVariant *pVariant, char *payload, int16_t type, bool inc return -1; } } else { - tasoUcs4Copy((TdUcs4*)payload, pVariant->ucs4, pVariant->nLen); + tasoUcs4Copy((TdUcs4 *)payload, pVariant->ucs4, pVariant->nLen); } } } else { @@ -1026,7 +958,7 @@ int32_t taosVariantTypeSetType(SVariant *pVariant, char type) { return 0; } -char * taosVariantGet(SVariant *pVar, int32_t type) { +char *taosVariantGet(SVariant *pVar, int32_t type) { switch (type) { case TSDB_DATA_TYPE_BOOL: case TSDB_DATA_TYPE_TINYINT: diff --git a/source/common/test/commonTests.cpp b/source/common/test/commonTests.cpp index fea6c4c891..2adb558d01 100644 --- a/source/common/test/commonTests.cpp +++ b/source/common/test/commonTests.cpp @@ -8,12 +8,11 @@ #pragma GCC diagnostic ignored "-Wsign-compare" #include "os.h" +#include "taos.h" #include "tcommon.h" #include "tdatablock.h" -#include "tcommon.h" -#include "taos.h" -#include "tvariant.h" #include "tdef.h" +#include "tvariant.h" namespace { // @@ -29,72 +28,62 @@ TEST(testCase, toInteger_test) { uint32_t type = 0; int64_t val = 0; - bool sign = true; - int32_t ret = toInteger(s, strlen(s), 10, &val, &sign); + int32_t ret = toInteger(s, strlen(s), 10, &val); ASSERT_EQ(ret, 0); ASSERT_EQ(val, 123); - ASSERT_EQ(sign, true); s = "9223372036854775807"; - ret = toInteger(s, strlen(s), 10, &val, &sign); + ret = toInteger(s, strlen(s), 10, &val); ASSERT_EQ(ret, 0); ASSERT_EQ(val, 9223372036854775807); - ASSERT_EQ(sign, true); s = "9323372036854775807"; - ret = toInteger(s, strlen(s), 10, &val, &sign); + ret = toInteger(s, strlen(s), 10, &val); ASSERT_EQ(ret, 0); ASSERT_EQ(val, 9323372036854775807u); - ASSERT_EQ(sign, false); s = "-9323372036854775807"; - ret = toInteger(s, strlen(s), 10, &val, &sign); + ret = toInteger(s, strlen(s), 10, &val); ASSERT_EQ(ret, -1); s = "-1"; - ret = toInteger(s, strlen(s), 10, &val, &sign); + ret = toInteger(s, strlen(s), 10, &val); ASSERT_EQ(ret, 0); ASSERT_EQ(val, -1); - ASSERT_EQ(sign, true); s = "-9223372036854775807"; - ret = toInteger(s, strlen(s), 10, &val, &sign); + ret = toInteger(s, strlen(s), 10, &val); ASSERT_EQ(ret, 0); ASSERT_EQ(val, -9223372036854775807); - ASSERT_EQ(sign, true); s = "1000u"; - ret = toInteger(s, strlen(s), 10, &val, &sign); + ret = toInteger(s, strlen(s), 10, &val); ASSERT_EQ(ret, -1); s = "0x10"; - ret = toInteger(s, strlen(s), 16, &val, &sign); + ret = toInteger(s, strlen(s), 16, &val); ASSERT_EQ(ret, 0); ASSERT_EQ(val, 16); - ASSERT_EQ(sign, true); s = "110"; - ret = toInteger(s, strlen(s), 2, &val, &sign); + ret = toInteger(s, strlen(s), 2, &val); ASSERT_EQ(ret, 0); ASSERT_EQ(val, 6); - ASSERT_EQ(sign, true); s = "110"; - ret = toInteger(s, strlen(s), 8, &val, &sign); + ret = toInteger(s, strlen(s), 8, &val); ASSERT_EQ(ret, 0); ASSERT_EQ(val, 72); - ASSERT_EQ(sign, true); - //18446744073709551615 UINT64_MAX + // 18446744073709551615 UINT64_MAX s = "18446744073709551615"; - ret = toInteger(s, strlen(s), 10, &val, &sign); + ret = toInteger(s, strlen(s), 10, &val); ASSERT_EQ(ret, 0); ASSERT_EQ(val, 18446744073709551615u); - ASSERT_EQ(sign, false); s = "18446744073709551616"; - ret = toInteger(s, strlen(s), 10, &val, &sign); + ret = toInteger(s, strlen(s), 10, &val); ASSERT_EQ(ret, -1); } @@ -108,8 +97,8 @@ TEST(testCase, Datablock_test) { infoData.info.type = TSDB_DATA_TYPE_INT; infoData.info.colId = 1; - infoData.pData = (char*) taosMemoryCalloc(40, infoData.info.bytes); - infoData.nullbitmap = (char*) taosMemoryCalloc(1, sizeof(char) * (40/8)); + infoData.pData = (char*)taosMemoryCalloc(40, infoData.info.bytes); + infoData.nullbitmap = (char*)taosMemoryCalloc(1, sizeof(char) * (40 / 8)); taosArrayPush(b->pDataBlock, &infoData); SColumnInfoData infoData1 = {0}; @@ -117,36 +106,36 @@ TEST(testCase, Datablock_test) { infoData1.info.type = TSDB_DATA_TYPE_BINARY; infoData1.info.colId = 2; - infoData1.varmeta.offset = (int32_t*) taosMemoryCalloc(40, sizeof(uint32_t)); + infoData1.varmeta.offset = (int32_t*)taosMemoryCalloc(40, sizeof(uint32_t)); taosArrayPush(b->pDataBlock, &infoData1); char* str = "the value of: %d"; - char buf[128] = {0}; - char varbuf[128] = {0}; + char buf[128] = {0}; + char varbuf[128] = {0}; - for(int32_t i = 0; i < 40; ++i) { - SColumnInfoData* p0 = (SColumnInfoData *) taosArrayGet(b->pDataBlock, 0); - SColumnInfoData* p1 = (SColumnInfoData *) taosArrayGet(b->pDataBlock, 1); + for (int32_t i = 0; i < 40; ++i) { + SColumnInfoData* p0 = (SColumnInfoData*)taosArrayGet(b->pDataBlock, 0); + SColumnInfoData* p1 = (SColumnInfoData*)taosArrayGet(b->pDataBlock, 1); - if (i&0x01) { + if (i & 0x01) { int32_t len = sprintf(buf, str, i); STR_TO_VARSTR(varbuf, buf) - colDataAppend(p0, i, (const char*) &i, false); - colDataAppend(p1, i, (const char*) varbuf, false); + colDataAppend(p0, i, (const char*)&i, false); + colDataAppend(p1, i, (const char*)varbuf, false); memset(varbuf, 0, sizeof(varbuf)); memset(buf, 0, sizeof(buf)); } else { - colDataAppend(p0, i, (const char*) &i, true); - colDataAppend(p1, i, (const char*) varbuf, true); + colDataAppend(p0, i, (const char*)&i, true); + colDataAppend(p1, i, (const char*)varbuf, true); } b->info.rows++; } - SColumnInfoData* p0 = (SColumnInfoData *) taosArrayGet(b->pDataBlock, 0); - SColumnInfoData* p1 = (SColumnInfoData *) taosArrayGet(b->pDataBlock, 1); - for(int32_t i = 0; i < 40; ++i) { + SColumnInfoData* p0 = (SColumnInfoData*)taosArrayGet(b->pDataBlock, 0); + SColumnInfoData* p1 = (SColumnInfoData*)taosArrayGet(b->pDataBlock, 1); + for (int32_t i = 0; i < 40; ++i) { if (i & 0x01) { ASSERT_EQ(colDataIsNull_f(p0->nullbitmap, i), false); ASSERT_EQ(colDataIsNull(p1, b->info.rows, i, nullptr), false); @@ -158,7 +147,7 @@ TEST(testCase, Datablock_test) { } } - printf("binary column length:%d\n", *(int32_t*) p1->pData); + printf("binary column length:%d\n", *(int32_t*)p1->pData); ASSERT_EQ(blockDataGetNumOfCols(b), 2); ASSERT_EQ(blockDataGetNumOfRows(b), 40); @@ -166,8 +155,8 @@ TEST(testCase, Datablock_test) { char* pData = colDataGetData(p1, 3); printf("the second row of binary:%s, length:%d\n", (char*)varDataVal(pData), varDataLen(pData)); - SArray* pOrderInfo = taosArrayInit(3, sizeof(SBlockOrderInfo)); - SBlockOrderInfo order = { true, TSDB_ORDER_ASC, 0, NULL }; + SArray* pOrderInfo = taosArrayInit(3, sizeof(SBlockOrderInfo)); + SBlockOrderInfo order = {true, TSDB_ORDER_ASC, 0, NULL}; taosArrayPush(pOrderInfo, &order); blockDataSort(b, pOrderInfo); @@ -244,8 +233,8 @@ TEST(testCase, var_dataBlock_split_test) { infoData.info.type = TSDB_DATA_TYPE_INT; infoData.info.colId = 1; - infoData.pData = (char*) taosMemoryCalloc(numOfRows, infoData.info.bytes); - infoData.nullbitmap = (char*) taosMemoryCalloc(1, sizeof(char) * (numOfRows/8)); + infoData.pData = (char*)taosMemoryCalloc(numOfRows, infoData.info.bytes); + infoData.nullbitmap = (char*)taosMemoryCalloc(1, sizeof(char) * (numOfRows / 8)); taosArrayPush(b->pDataBlock, &infoData); SColumnInfoData infoData1 = {0}; @@ -253,13 +242,13 @@ TEST(testCase, var_dataBlock_split_test) { infoData1.info.type = TSDB_DATA_TYPE_BINARY; infoData1.info.colId = 2; - infoData1.varmeta.offset = (int32_t*) taosMemoryCalloc(numOfRows, sizeof(uint32_t)); + infoData1.varmeta.offset = (int32_t*)taosMemoryCalloc(numOfRows, sizeof(uint32_t)); taosArrayPush(b->pDataBlock, &infoData1); char buf[41] = {0}; char buf1[100] = {0}; - for(int32_t i = 0; i < numOfRows; ++i) { + for (int32_t i = 0; i < numOfRows; ++i) { SColumnInfoData* p0 = (SColumnInfoData*)taosArrayGet(b->pDataBlock, 0); SColumnInfoData* p1 = (SColumnInfoData*)taosArrayGet(b->pDataBlock, 1); @@ -278,10 +267,10 @@ TEST(testCase, var_dataBlock_split_test) { int32_t pageSize = 64 * 1024; - int32_t startIndex= 0; + int32_t startIndex = 0; int32_t stopIndex = 0; int32_t count = 1; - while(1) { + while (1) { blockDataSplitRows(b, true, startIndex, &stopIndex, pageSize); printf("the %d split, from: %d to %d\n", count++, startIndex, stopIndex); diff --git a/source/libs/function/src/builtins.c b/source/libs/function/src/builtins.c index 80bfb626d8..5e3259c8fb 100644 --- a/source/libs/function/src/builtins.c +++ b/source/libs/function/src/builtins.c @@ -239,7 +239,7 @@ static int32_t translateLeastSQR(SFunctionNode* pFunc, char* pErrBuf, int32_t le } } - pFunc->node.resType = (SDataType) { .bytes = 64, .type = TSDB_DATA_TYPE_BINARY }; + pFunc->node.resType = (SDataType){.bytes = 64, .type = TSDB_DATA_TYPE_BINARY}; return TSDB_CODE_SUCCESS; } @@ -977,26 +977,26 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = { .sprocessFunc = timezoneFunction, .finalizeFunc = NULL }, - { - .name = "_rowts", - .type = FUNCTION_TYPE_ROWTS, - .classification = FUNC_MGT_PSEUDO_COLUMN_FUNC, - .translateFunc = translateTimePseudoColumn, - .getEnvFunc = getTimePseudoFuncEnv, - .initFunc = NULL, - .sprocessFunc = NULL, - .finalizeFunc = NULL - }, - { - .name = "_c0", - .type = FUNCTION_TYPE_ROWTS, - .classification = FUNC_MGT_PSEUDO_COLUMN_FUNC, - .translateFunc = translateTimePseudoColumn, - .getEnvFunc = getTimePseudoFuncEnv, - .initFunc = NULL, - .sprocessFunc = NULL, - .finalizeFunc = NULL - }, + // { + // .name = "_rowts", + // .type = FUNCTION_TYPE_ROWTS, + // .classification = FUNC_MGT_PSEUDO_COLUMN_FUNC, + // .translateFunc = translateTimePseudoColumn, + // .getEnvFunc = getTimePseudoFuncEnv, + // .initFunc = NULL, + // .sprocessFunc = NULL, + // .finalizeFunc = NULL + // }, + // { + // .name = "_c0", + // .type = FUNCTION_TYPE_ROWTS, + // .classification = FUNC_MGT_PSEUDO_COLUMN_FUNC, + // .translateFunc = translateTimePseudoColumn, + // .getEnvFunc = getTimePseudoFuncEnv, + // .initFunc = NULL, + // .sprocessFunc = NULL, + // .finalizeFunc = NULL + // }, { .name = "tbname", .type = FUNCTION_TYPE_TBNAME, diff --git a/source/libs/parser/src/parAstCreater.c b/source/libs/parser/src/parAstCreater.c index a9481593e0..b7a14a81c6 100644 --- a/source/libs/parser/src/parAstCreater.c +++ b/source/libs/parser/src/parAstCreater.c @@ -350,7 +350,18 @@ SNode* createNotBetweenAnd(SAstCreateContext* pCxt, SNode* pExpr, SNode* pLeft, createOperatorNode(pCxt, OP_TYPE_GREATER_THAN, nodesCloneNode(pExpr), pRight)); } +static SNode* createPrimaryKeyCol(SAstCreateContext* pCxt) { + SColumnNode* pCol = nodesMakeNode(QUERY_NODE_COLUMN); + CHECK_OUT_OF_MEM(pCol); + pCol->colId = PRIMARYKEY_TIMESTAMP_COL_ID; + strcpy(pCol->colName, PK_TS_COL_INTERNAL_NAME); + return (SNode*)pCol; +} + SNode* createFunctionNode(SAstCreateContext* pCxt, const SToken* pFuncName, SNodeList* pParameterList) { + if (0 == strncasecmp("_rowts", pFuncName->z, pFuncName->n) || 0 == strncasecmp("_c0", pFuncName->z, pFuncName->n)) { + return createPrimaryKeyCol(pCxt); + } SFunctionNode* func = (SFunctionNode*)nodesMakeNode(QUERY_NODE_FUNCTION); CHECK_OUT_OF_MEM(func); strncpy(func->functionName, pFuncName->z, pFuncName->n); @@ -467,13 +478,11 @@ SNode* createSessionWindowNode(SAstCreateContext* pCxt, SNode* pCol, SNode* pGap SNode* createStateWindowNode(SAstCreateContext* pCxt, SNode* pExpr) { SStateWindowNode* state = (SStateWindowNode*)nodesMakeNode(QUERY_NODE_STATE_WINDOW); CHECK_OUT_OF_MEM(state); - state->pCol = nodesMakeNode(QUERY_NODE_COLUMN); + state->pCol = createPrimaryKeyCol(pCxt); if (NULL == state->pCol) { nodesDestroyNode(state); CHECK_OUT_OF_MEM(state->pCol); } - ((SColumnNode*)state->pCol)->colId = PRIMARYKEY_TIMESTAMP_COL_ID; - strcpy(((SColumnNode*)state->pCol)->colName, PK_TS_COL_INTERNAL_NAME); state->pExpr = pExpr; return (SNode*)state; } @@ -482,13 +491,11 @@ SNode* createIntervalWindowNode(SAstCreateContext* pCxt, SNode* pInterval, SNode SNode* pFill) { SIntervalWindowNode* interval = (SIntervalWindowNode*)nodesMakeNode(QUERY_NODE_INTERVAL_WINDOW); CHECK_OUT_OF_MEM(interval); - interval->pCol = nodesMakeNode(QUERY_NODE_COLUMN); + interval->pCol = createPrimaryKeyCol(pCxt); if (NULL == interval->pCol) { nodesDestroyNode(interval); CHECK_OUT_OF_MEM(interval->pCol); } - ((SColumnNode*)interval->pCol)->colId = PRIMARYKEY_TIMESTAMP_COL_ID; - strcpy(((SColumnNode*)interval->pCol)->colName, PK_TS_COL_INTERNAL_NAME); interval->pInterval = pInterval; interval->pOffset = pOffset; interval->pSliding = pSliding; @@ -667,7 +674,7 @@ SNode* setDatabaseOption(SAstCreateContext* pCxt, SNode* pOptions, EDatabaseOpti case DB_OPTION_DAYS: { SToken* pToken = pVal; if (TK_NK_INTEGER == pToken->type) { - ((SDatabaseOptions*)pOptions)->daysPerFile = strtol(pToken->z, NULL, 10); + ((SDatabaseOptions*)pOptions)->daysPerFile = strtol(pToken->z, NULL, 10) * 1440; } else { ((SDatabaseOptions*)pOptions)->pDaysPerFile = (SValueNode*)createDurationValueNode(pCxt, pToken); } diff --git a/source/libs/parser/src/parInsert.c b/source/libs/parser/src/parInsert.c index 64d2934282..87dc8b97c8 100644 --- a/source/libs/parser/src/parInsert.c +++ b/source/libs/parser/src/parInsert.c @@ -246,7 +246,8 @@ static int32_t getTableMetaImpl(SInsertParseContext* pCxt, SToken* pTname, bool tNameGetFullDbName(&name, dbFname); bool pass = false; - CHECK_CODE(catalogChkAuth(pBasicCtx->pCatalog, pBasicCtx->pTransporter, &pBasicCtx->mgmtEpSet, pBasicCtx->pUser, dbFname, AUTH_TYPE_WRITE, &pass)); + CHECK_CODE(catalogChkAuth(pBasicCtx->pCatalog, pBasicCtx->pTransporter, &pBasicCtx->mgmtEpSet, pBasicCtx->pUser, + dbFname, AUTH_TYPE_WRITE, &pass)); if (!pass) { return TSDB_CODE_PAR_PERMISSION_DENIED; } @@ -349,8 +350,7 @@ static int parseTime(char** end, SToken* pToken, int16_t timePrec, int64_t* time } else if (pToken->type == TK_TODAY) { ts = taosGetTimestampToday(timePrec); } else if (pToken->type == TK_NK_INTEGER) { - bool isSigned = false; - toInteger(pToken->z, pToken->n, 10, &ts, &isSigned); + toInteger(pToken->z, pToken->n, 10, &ts); } else { // parse the RFC-3339/ISO-8601 timestamp format string if (taosParseTime(pToken->z, time, pToken->n, timePrec, tsDaylight) != TSDB_CODE_SUCCESS) { return buildSyntaxErrMsg(pMsgBuf, "invalid timestamp format", pToken->z); @@ -453,9 +453,9 @@ static FORCE_INLINE int32_t toDouble(SToken* pToken, double* value, char** endPt static int32_t parseValueToken(char** end, SToken* pToken, SSchema* pSchema, int16_t timePrec, char* tmpTokenBuf, _row_append_fn_t func, void* param, SMsgBuf* pMsgBuf) { - int64_t iv; - char* endptr = NULL; - bool isSigned = false; + int64_t iv; + uint64_t uv; + char* endptr = NULL; int32_t code = checkAndTrimValue(pToken, pSchema->type, tmpTokenBuf, pMsgBuf); if (code != TSDB_CODE_SUCCESS) { @@ -490,7 +490,7 @@ static int32_t parseValueToken(char** end, SToken* pToken, SSchema* pSchema, int } case TSDB_DATA_TYPE_TINYINT: { - if (TSDB_CODE_SUCCESS != toInteger(pToken->z, pToken->n, 10, &iv, &isSigned)) { + if (TSDB_CODE_SUCCESS != toInteger(pToken->z, pToken->n, 10, &iv)) { return buildSyntaxErrMsg(pMsgBuf, "invalid tinyint data", pToken->z); } else if (!IS_VALID_TINYINT(iv)) { return buildSyntaxErrMsg(pMsgBuf, "tinyint data overflow", pToken->z); @@ -501,17 +501,17 @@ static int32_t parseValueToken(char** end, SToken* pToken, SSchema* pSchema, int } case TSDB_DATA_TYPE_UTINYINT: { - if (TSDB_CODE_SUCCESS != toInteger(pToken->z, pToken->n, 10, &iv, &isSigned)) { + if (TSDB_CODE_SUCCESS != toUInteger(pToken->z, pToken->n, 10, &uv)) { return buildSyntaxErrMsg(pMsgBuf, "invalid unsigned tinyint data", pToken->z); - } else if (!IS_VALID_UTINYINT(iv)) { + } else if (!IS_VALID_UTINYINT(uv)) { return buildSyntaxErrMsg(pMsgBuf, "unsigned tinyint data overflow", pToken->z); } - uint8_t tmpVal = (uint8_t)iv; + uint8_t tmpVal = (uint8_t)uv; return func(pMsgBuf, &tmpVal, pSchema->bytes, param); } case TSDB_DATA_TYPE_SMALLINT: { - if (TSDB_CODE_SUCCESS != toInteger(pToken->z, pToken->n, 10, &iv, &isSigned)) { + if (TSDB_CODE_SUCCESS != toInteger(pToken->z, pToken->n, 10, &iv)) { return buildSyntaxErrMsg(pMsgBuf, "invalid smallint data", pToken->z); } else if (!IS_VALID_SMALLINT(iv)) { return buildSyntaxErrMsg(pMsgBuf, "smallint data overflow", pToken->z); @@ -521,17 +521,17 @@ static int32_t parseValueToken(char** end, SToken* pToken, SSchema* pSchema, int } case TSDB_DATA_TYPE_USMALLINT: { - if (TSDB_CODE_SUCCESS != toInteger(pToken->z, pToken->n, 10, &iv, &isSigned)) { + if (TSDB_CODE_SUCCESS != toUInteger(pToken->z, pToken->n, 10, &uv)) { return buildSyntaxErrMsg(pMsgBuf, "invalid unsigned smallint data", pToken->z); - } else if (!IS_VALID_USMALLINT(iv)) { + } else if (!IS_VALID_USMALLINT(uv)) { return buildSyntaxErrMsg(pMsgBuf, "unsigned smallint data overflow", pToken->z); } - uint16_t tmpVal = (uint16_t)iv; + uint16_t tmpVal = (uint16_t)uv; return func(pMsgBuf, &tmpVal, pSchema->bytes, param); } case TSDB_DATA_TYPE_INT: { - if (TSDB_CODE_SUCCESS != toInteger(pToken->z, pToken->n, 10, &iv, &isSigned)) { + if (TSDB_CODE_SUCCESS != toInteger(pToken->z, pToken->n, 10, &iv)) { return buildSyntaxErrMsg(pMsgBuf, "invalid int data", pToken->z); } else if (!IS_VALID_INT(iv)) { return buildSyntaxErrMsg(pMsgBuf, "int data overflow", pToken->z); @@ -541,17 +541,17 @@ static int32_t parseValueToken(char** end, SToken* pToken, SSchema* pSchema, int } case TSDB_DATA_TYPE_UINT: { - if (TSDB_CODE_SUCCESS != toInteger(pToken->z, pToken->n, 10, &iv, &isSigned)) { + if (TSDB_CODE_SUCCESS != toUInteger(pToken->z, pToken->n, 10, &uv)) { return buildSyntaxErrMsg(pMsgBuf, "invalid unsigned int data", pToken->z); - } else if (!IS_VALID_UINT(iv)) { + } else if (!IS_VALID_UINT(uv)) { return buildSyntaxErrMsg(pMsgBuf, "unsigned int data overflow", pToken->z); } - uint32_t tmpVal = (uint32_t)iv; + uint32_t tmpVal = (uint32_t)uv; return func(pMsgBuf, &tmpVal, pSchema->bytes, param); } case TSDB_DATA_TYPE_BIGINT: { - if (TSDB_CODE_SUCCESS != toInteger(pToken->z, pToken->n, 10, &iv, &isSigned)) { + if (TSDB_CODE_SUCCESS != toInteger(pToken->z, pToken->n, 10, &iv)) { return buildSyntaxErrMsg(pMsgBuf, "invalid bigint data", pToken->z); } else if (!IS_VALID_BIGINT(iv)) { return buildSyntaxErrMsg(pMsgBuf, "bigint data overflow", pToken->z); @@ -560,13 +560,12 @@ static int32_t parseValueToken(char** end, SToken* pToken, SSchema* pSchema, int } case TSDB_DATA_TYPE_UBIGINT: { - if (TSDB_CODE_SUCCESS != toInteger(pToken->z, pToken->n, 10, &iv, &isSigned)) { + if (TSDB_CODE_SUCCESS != toUInteger(pToken->z, pToken->n, 10, &uv)) { return buildSyntaxErrMsg(pMsgBuf, "invalid unsigned bigint data", pToken->z); - } else if (!IS_VALID_UBIGINT((uint64_t)iv)) { + } else if (!IS_VALID_UBIGINT(uv)) { return buildSyntaxErrMsg(pMsgBuf, "unsigned bigint data overflow", pToken->z); } - uint64_t tmpVal = (uint64_t)iv; - return func(pMsgBuf, &tmpVal, pSchema->bytes, param); + return func(pMsgBuf, &uv, pSchema->bytes, param); } case TSDB_DATA_TYPE_FLOAT: { @@ -771,7 +770,7 @@ static int32_t KvRowAppend(SMsgBuf* pMsgBuf, const void* value, int32_t len, voi return TSDB_CODE_SUCCESS; } -static int32_t buildCreateTbReq(SVCreateTbReq *pTbReq, const char* tname, SKVRow row, int64_t suid) { +static int32_t buildCreateTbReq(SVCreateTbReq* pTbReq, const char* tname, SKVRow row, int64_t suid) { pTbReq->type = TD_CHILD_TABLE; pTbReq->name = strdup(tname); pTbReq->ctb.suid = suid; @@ -1273,9 +1272,10 @@ int32_t qBuildStmtOutput(SQuery* pQuery, SHashObj* pVgHash, SHashObj* pBlockHash return TSDB_CODE_SUCCESS; } -int32_t qBindStmtTagsValue(void *pBlock, void *boundTags, int64_t suid, char *tName, TAOS_MULTI_BIND *bind, char *msgBuf, int32_t msgBufLen){ - STableDataBlocks *pDataBlock = (STableDataBlocks *)pBlock; - SMsgBuf pBuf = {.buf = msgBuf, .len = msgBufLen}; +int32_t qBindStmtTagsValue(void* pBlock, void* boundTags, int64_t suid, char* tName, TAOS_MULTI_BIND* bind, + char* msgBuf, int32_t msgBufLen) { + STableDataBlocks* pDataBlock = (STableDataBlocks*)pBlock; + SMsgBuf pBuf = {.buf = msgBuf, .len = msgBufLen}; SParsedDataColInfo* tags = (SParsedDataColInfo*)boundTags; if (NULL == tags) { return TSDB_CODE_QRY_APP_ERROR; @@ -1550,16 +1550,16 @@ int32_t qBuildStmtColFields(void* pBlock, int32_t* fieldNum, TAOS_FIELD** fields // schemaless logic start typedef struct SmlExecHandle { - SHashObj* pBlockHash; + SHashObj* pBlockHash; - SParsedDataColInfo tags; // each table - SKVRowBuilder tagsBuilder; // each table - SVCreateTbReq createTblReq; // each table + SParsedDataColInfo tags; // each table + SKVRowBuilder tagsBuilder; // each table + SVCreateTbReq createTblReq; // each table SQuery* pQuery; } SSmlExecHandle; -static int32_t smlBoundColumnData(SArray *cols, SParsedDataColInfo* pColList, SSchema* pSchema) { +static int32_t smlBoundColumnData(SArray* cols, SParsedDataColInfo* pColList, SSchema* pSchema) { col_id_t nCols = pColList->numOfCols; pColList->numOfBound = 0; @@ -1572,8 +1572,8 @@ static int32_t smlBoundColumnData(SArray *cols, SParsedDataColInfo* pColList, SS bool isOrdered = true; col_id_t lastColIdx = -1; // last column found for (int i = 0; i < taosArrayGetSize(cols); ++i) { - SSmlKv *kv = taosArrayGetP(cols, i); - SToken sToken = {.n=kv->keyLen, .z=(char*)kv->key}; + SSmlKv* kv = taosArrayGetP(cols, i); + SToken sToken = {.n = kv->keyLen, .z = (char*)kv->key}; col_id_t t = lastColIdx + 1; col_id_t index = findCol(&sToken, t, nCols, pSchema); if (index < 0 && t > 0) { @@ -1622,7 +1622,7 @@ static int32_t smlBoundColumnData(SArray *cols, SParsedDataColInfo* pColList, SS qsort(pColIdx, pColList->numOfBound, sizeof(SBoundIdxInfo), boundIdxCompar); } - if(pColList->numOfCols > pColList->numOfBound){ + if (pColList->numOfCols > pColList->numOfBound) { memset(&pColList->boundColumns[pColList->numOfBound], 0, sizeof(col_id_t) * (pColList->numOfCols - pColList->numOfBound)); } @@ -1630,53 +1630,52 @@ static int32_t smlBoundColumnData(SArray *cols, SParsedDataColInfo* pColList, SS return TSDB_CODE_SUCCESS; } -static int32_t smlBuildTagRow(SArray *cols, SKVRowBuilder *tagsBuilder, SParsedDataColInfo* tags, SSchema* pSchema, SKVRow *row, SMsgBuf *msg) { +static int32_t smlBuildTagRow(SArray* cols, SKVRowBuilder* tagsBuilder, SParsedDataColInfo* tags, SSchema* pSchema, + SKVRow* row, SMsgBuf* msg) { if (tdInitKVRowBuilder(tagsBuilder) < 0) { return TSDB_CODE_TSC_OUT_OF_MEMORY; } SKvParam param = {.builder = tagsBuilder}; for (int i = 0; i < tags->numOfBound; ++i) { - SSchema* pTagSchema = &pSchema[tags->boundColumns[i] - 1]; // colId starts with 1 + SSchema* pTagSchema = &pSchema[tags->boundColumns[i] - 1]; // colId starts with 1 param.schema = pTagSchema; - SSmlKv *kv = taosArrayGetP(cols, i); - KvRowAppend(msg, kv->value, kv->valueLen, ¶m) ; + SSmlKv* kv = taosArrayGetP(cols, i); + KvRowAppend(msg, kv->value, kv->valueLen, ¶m); } - *row = tdGetKVRowFromBuilder(tagsBuilder); - if(*row == NULL){ + if (*row == NULL) { return TSDB_CODE_SML_INVALID_DATA; } tdSortKVRowByColIdx(*row); return TSDB_CODE_SUCCESS; } -int32_t smlBindData(void *handle, SArray *tags, SArray *colsFormat, SArray *colsSchema, SArray *cols, bool format, - STableMeta *pTableMeta, char *tableName, char *msgBuf, int16_t msgBufLen) { +int32_t smlBindData(void* handle, SArray* tags, SArray* colsFormat, SArray* colsSchema, SArray* cols, bool format, + STableMeta* pTableMeta, char* tableName, char* msgBuf, int16_t msgBufLen) { SMsgBuf pBuf = {.buf = msgBuf, .len = msgBufLen}; - SSmlExecHandle *smlHandle = (SSmlExecHandle *)handle; - SSchema* pTagsSchema = getTableTagSchema(pTableMeta); + SSmlExecHandle* smlHandle = (SSmlExecHandle*)handle; + SSchema* pTagsSchema = getTableTagSchema(pTableMeta); setBoundColumnInfo(&smlHandle->tags, pTagsSchema, getNumOfTags(pTableMeta)); int ret = smlBoundColumnData(tags, &smlHandle->tags, pTagsSchema); - if(ret != TSDB_CODE_SUCCESS){ + if (ret != TSDB_CODE_SUCCESS) { buildInvalidOperationMsg(&pBuf, "bound tags error"); return ret; } SKVRow row = NULL; ret = smlBuildTagRow(tags, &smlHandle->tagsBuilder, &smlHandle->tags, pTagsSchema, &row, &pBuf); - if(ret != TSDB_CODE_SUCCESS){ + if (ret != TSDB_CODE_SUCCESS) { return ret; } buildCreateTbReq(&smlHandle->createTblReq, tableName, row, pTableMeta->suid); STableDataBlocks* pDataBlock = NULL; - ret = getDataBlockFromList(smlHandle->pBlockHash, pTableMeta->uid, TSDB_DEFAULT_PAYLOAD_SIZE, - sizeof(SSubmitBlk), getTableInfo(pTableMeta).rowSize, pTableMeta, - &pDataBlock, NULL, &smlHandle->createTblReq); - if(ret != TSDB_CODE_SUCCESS){ + ret = getDataBlockFromList(smlHandle->pBlockHash, pTableMeta->uid, TSDB_DEFAULT_PAYLOAD_SIZE, sizeof(SSubmitBlk), + getTableInfo(pTableMeta).rowSize, pTableMeta, &pDataBlock, NULL, &smlHandle->createTblReq); + if (ret != TSDB_CODE_SUCCESS) { buildInvalidOperationMsg(&pBuf, "create data block error"); return ret; } @@ -1684,35 +1683,35 @@ int32_t smlBindData(void *handle, SArray *tags, SArray *colsFormat, SArray *cols SSchema* pSchema = getTableColumnSchema(pTableMeta); ret = smlBoundColumnData(colsSchema, &pDataBlock->boundColumnInfo, pSchema); - if(ret != TSDB_CODE_SUCCESS){ + if (ret != TSDB_CODE_SUCCESS) { buildInvalidOperationMsg(&pBuf, "bound cols error"); return ret; } - int32_t extendedRowSize = getExtendedRowSize(pDataBlock); + int32_t extendedRowSize = getExtendedRowSize(pDataBlock); SParsedDataColInfo* spd = &pDataBlock->boundColumnInfo; SRowBuilder* pBuilder = &pDataBlock->rowBuilder; - SMemParam param = {.rb = pBuilder}; + SMemParam param = {.rb = pBuilder}; initRowBuilder(&pDataBlock->rowBuilder, pDataBlock->pTableMeta->sversion, &pDataBlock->boundColumnInfo); int32_t rowNum = format ? taosArrayGetSize(colsFormat) : taosArrayGetSize(cols); - if(rowNum <= 0) { + if (rowNum <= 0) { return buildInvalidOperationMsg(&pBuf, "cols size <= 0"); } ret = allocateMemForSize(pDataBlock, extendedRowSize * rowNum); - if(ret != TSDB_CODE_SUCCESS){ + if (ret != TSDB_CODE_SUCCESS) { buildInvalidOperationMsg(&pBuf, "allocate memory error"); return ret; } for (int32_t r = 0; r < rowNum; ++r) { STSRow* row = (STSRow*)(pDataBlock->pData + pDataBlock->size); // skip the SSubmitBlk header tdSRowResetBuf(pBuilder, row); - void *rowData = NULL; + void* rowData = NULL; size_t rowDataSize = 0; - if(format){ + if (format) { rowData = taosArrayGetP(colsFormat, r); rowDataSize = taosArrayGetSize(rowData); - }else{ + } else { rowData = taosArrayGetP(cols, r); } @@ -1723,19 +1722,20 @@ int32_t smlBindData(void *handle, SArray *tags, SArray *colsFormat, SArray *cols param.schema = pColSchema; getSTSRowAppendInfo(pBuilder->rowType, spd, c, ¶m.toffset, ¶m.colIdx); - SSmlKv *kv = NULL; - if(format){ - if(j < rowDataSize){ + SSmlKv* kv = NULL; + if (format) { + if (j < rowDataSize) { kv = taosArrayGetP(rowData, j); - if (rowDataSize != spd->numOfBound && (kv->keyLen != strlen(pColSchema->name) || strncmp(kv->key, pColSchema->name, kv->keyLen) != 0)){ + if (rowDataSize != spd->numOfBound && + (kv->keyLen != strlen(pColSchema->name) || strncmp(kv->key, pColSchema->name, kv->keyLen) != 0)) { kv = NULL; - }else{ + } else { j++; } } - }else{ - void **p =taosHashGet(rowData, pColSchema->name, strlen(pColSchema->name)); - if(p) kv = *p; + } else { + void** p = taosHashGet(rowData, pColSchema->name, strlen(pColSchema->name)); + if (p) kv = *p; } if (!kv || kv->length == 0) { @@ -1744,7 +1744,7 @@ int32_t smlBindData(void *handle, SArray *tags, SArray *colsFormat, SArray *cols int32_t colLen = pColSchema->bytes; if (IS_VAR_DATA_TYPE(pColSchema->type)) { colLen = kv->length; - } else if(pColSchema->type == TSDB_DATA_TYPE_TIMESTAMP){ + } else if (pColSchema->type == TSDB_DATA_TYPE_TIMESTAMP) { kv->i = convertTimePrecision(kv->i, TSDB_TIME_PRECISION_NANO, pTableMeta->tableInfo.precision); } @@ -1753,7 +1753,7 @@ int32_t smlBindData(void *handle, SArray *tags, SArray *colsFormat, SArray *cols if (PRIMARYKEY_TIMESTAMP_COL_ID == pColSchema->colId) { TSKEY tsKey = TD_ROW_KEY(row); - checkTimestamp(pDataBlock, (const char *)&tsKey); + checkTimestamp(pDataBlock, (const char*)&tsKey); } } @@ -1770,7 +1770,7 @@ int32_t smlBindData(void *handle, SArray *tags, SArray *colsFormat, SArray *cols pDataBlock->size += extendedRowSize; } - SSubmitBlk *pBlocks = (SSubmitBlk *)(pDataBlock->pData); + SSubmitBlk* pBlocks = (SSubmitBlk*)(pDataBlock->pData); if (TSDB_CODE_SUCCESS != setBlockInfo(pBlocks, pDataBlock, rowNum)) { return buildInvalidOperationMsg(&pBuf, "too many rows in sql, total number of rows should be less than 32767"); } @@ -1778,25 +1778,24 @@ int32_t smlBindData(void *handle, SArray *tags, SArray *colsFormat, SArray *cols return TSDB_CODE_SUCCESS; } -void* smlInitHandle(SQuery *pQuery){ - SSmlExecHandle *handle = taosMemoryCalloc(1, sizeof(SSmlExecHandle)); - if(!handle) return NULL; +void* smlInitHandle(SQuery* pQuery) { + SSmlExecHandle* handle = taosMemoryCalloc(1, sizeof(SSmlExecHandle)); + if (!handle) return NULL; handle->pBlockHash = taosHashInit(16, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), true, false); handle->pQuery = pQuery; return handle; } -void smlDestroyHandle(void *pHandle){ - if(!pHandle) return; - SSmlExecHandle *handle = (SSmlExecHandle *)pHandle; +void smlDestroyHandle(void* pHandle) { + if (!pHandle) return; + SSmlExecHandle* handle = (SSmlExecHandle*)pHandle; destroyBlockHashmap(handle->pBlockHash); taosMemoryFree(handle); } int32_t smlBuildOutput(void* handle, SHashObj* pVgHash) { - SSmlExecHandle *smlHandle = (SSmlExecHandle *)handle; + SSmlExecHandle* smlHandle = (SSmlExecHandle*)handle; return qBuildStmtOutput(smlHandle->pQuery, pVgHash, smlHandle->pBlockHash); } // schemaless logic end - diff --git a/source/libs/parser/src/parTranslater.c b/source/libs/parser/src/parTranslater.c index cdcb2592a7..fddc8edb3a 100644 --- a/source/libs/parser/src/parTranslater.c +++ b/source/libs/parser/src/parTranslater.c @@ -1886,6 +1886,9 @@ static int32_t checkDbKeepOption(STranslateContext* pCxt, SDatabaseOptions* pOpt TIME_UNIT_DAY != pVal->unit) { return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_KEEP_UNIT, pVal->unit); } + if (!pVal->isDuration) { + pVal->datum.i = pVal->datum.i * 1440; + } } pOptions->keep[0] = getBigintFromValueNode((SValueNode*)nodesListGetNode(pOptions->pKeep, 0)); diff --git a/source/libs/parser/test/parInitialCTest.cpp b/source/libs/parser/test/parInitialCTest.cpp index cf364aba5c..8eaeffe6df 100644 --- a/source/libs/parser/test/parInitialCTest.cpp +++ b/source/libs/parser/test/parInitialCTest.cpp @@ -3,7 +3,7 @@ * * This program is free software: you can use, redistribute, and/or modify * it under the terms of the GNU Affero General Public License, version 3 - * or later ("AGPL"), as published by the Free Software Foundation. + * or later ("AGPL"), AS published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or @@ -14,6 +14,7 @@ */ #include "parTestUtil.h" +#include "ttime.h" using namespace std; @@ -26,72 +27,226 @@ class ParserInitialCTest : public ParserDdlTest {}; TEST_F(ParserInitialCTest, createAccount) { useDb("root", "test"); - run("create account ac_wxy pass '123456'", TSDB_CODE_PAR_EXPRIE_STATEMENT); + run("CREATE ACCOUNT ac_wxy PASS '123456'", TSDB_CODE_PAR_EXPRIE_STATEMENT); } TEST_F(ParserInitialCTest, createBnode) { useDb("root", "test"); - run("create bnode on dnode 1"); + run("CREATE BNODE ON DNODE 1"); } +/* + * CREATE DATABASE [IF NOT EXISTS] db_name [database_options] + * + * database_options: + * database_option ... + * + * database_option: { + * BUFFER value + * | CACHELAST value + * | COMP {0 | 1 | 2} + * | DAYS value + * | FSYNC value + * | MAXROWS value + * | MINROWS value + * | KEEP value + * | PAGES value + * | PAGESIZE value + * | PRECISION {'ms' | 'us' | 'ns'} + * | REPLICA value + * | RETENTIONS ingestion_duration:keep_duration ... + * | STRICT value + * | WAL value + * | VGROUPS value + * | SINGLE_STABLE {0 | 1} + * } + */ TEST_F(ParserInitialCTest, createDatabase) { useDb("root", "test"); - run("create database wxy_db"); + SCreateDbReq expect = {0}; - run("create database if not exists wxy_db " - "cachelast 2 " - "comp 1 " - "days 100 " - "fsync 100 " - "maxrows 1000 " - "minrows 100 " - "keep 1440 " - "precision 'ms' " - "replica 3 " - "wal 2 " - "vgroups 100 " - "single_stable 0 " - "retentions 15s:7d,1m:21d,15m:5y"); + auto setCreateDbReqFunc = [&](const char* pDbname, int8_t igExists = 0) { + memset(&expect, 0, sizeof(SCreateDbReq)); + int32_t len = snprintf(expect.db, sizeof(expect.db), "0.%s", pDbname); + expect.db[len] = '\0'; + expect.ignoreExist = igExists; + expect.buffer = TSDB_DEFAULT_BUFFER_PER_VNODE; + expect.cacheLastRow = TSDB_DEFAULT_CACHE_LAST_ROW; + expect.compression = TSDB_DEFAULT_COMP_LEVEL; + expect.daysPerFile = TSDB_DEFAULT_DAYS_PER_FILE; + expect.fsyncPeriod = TSDB_DEFAULT_FSYNC_PERIOD; + expect.maxRows = TSDB_DEFAULT_MAXROWS_FBLOCK; + expect.minRows = TSDB_DEFAULT_MINROWS_FBLOCK; + expect.daysToKeep0 = TSDB_DEFAULT_KEEP; + expect.daysToKeep1 = TSDB_DEFAULT_KEEP; + expect.daysToKeep2 = TSDB_DEFAULT_KEEP; + expect.pages = TSDB_DEFAULT_PAGES_PER_VNODE; + expect.pageSize = TSDB_DEFAULT_PAGESIZE_PER_VNODE; + expect.precision = TSDB_DEFAULT_PRECISION; + expect.replications = TSDB_DEFAULT_DB_REPLICA; + expect.strict = TSDB_DEFAULT_DB_STRICT; + expect.walLevel = TSDB_DEFAULT_WAL_LEVEL; + expect.numOfVgroups = TSDB_DEFAULT_VN_PER_DB; + expect.numOfStables = TSDB_DEFAULT_DB_SINGLE_STABLE; + }; - run("create database if not exists wxy_db " - "days 100m " - "keep 1440m,300h,400d "); + auto setDbBufferFunc = [&](int32_t buffer) { expect.buffer = buffer; }; + auto setDbCachelastFunc = [&](int8_t CACHELAST) { expect.cacheLastRow = CACHELAST; }; + auto setDbCompressionFunc = [&](int8_t compressionLevel) { expect.compression = compressionLevel; }; + auto setDbDaysFunc = [&](int32_t daysPerFile) { expect.daysPerFile = daysPerFile; }; + auto setDbFsyncFunc = [&](int32_t fsyncPeriod) { expect.fsyncPeriod = fsyncPeriod; }; + auto setDbMaxRowsFunc = [&](int32_t maxRowsPerBlock) { expect.maxRows = maxRowsPerBlock; }; + auto setDbMinRowsFunc = [&](int32_t minRowsPerBlock) { expect.minRows = minRowsPerBlock; }; + auto setDbKeepFunc = [&](int32_t keep0, int32_t keep1 = 0, int32_t keep2 = 0) { + expect.daysToKeep0 = keep0; + expect.daysToKeep1 = 0 == keep1 ? expect.daysToKeep0 : keep1; + expect.daysToKeep2 = 0 == keep2 ? expect.daysToKeep1 : keep2; + }; + auto setDbPagesFunc = [&](int32_t pages) { expect.pages = pages; }; + auto setDbPageSizeFunc = [&](int32_t pagesize) { expect.pageSize = pagesize; }; + auto setDbPrecisionFunc = [&](int8_t precision) { expect.precision = precision; }; + auto setDbReplicaFunc = [&](int8_t replica) { expect.replications = replica; }; + auto setDbStrictaFunc = [&](int8_t strict) { expect.strict = strict; }; + auto setDbWalLevelFunc = [&](int8_t walLevel) { expect.walLevel = walLevel; }; + auto setDbVgroupsFunc = [&](int32_t numOfVgroups) { expect.numOfVgroups = numOfVgroups; }; + auto setDbSingleStableFunc = [&](int8_t singleStable) { expect.numOfStables = singleStable; }; + auto addDbRetentionFunc = [&](int64_t freq, int64_t keep, int8_t freqUnit, int8_t keepUnit) { + SRetention retention = {0}; + retention.freq = freq; + retention.keep = keep; + retention.freqUnit = freqUnit; + retention.keepUnit = keepUnit; + if (NULL == expect.pRetensions) { + expect.pRetensions = taosArrayInit(TARRAY_MIN_SIZE, sizeof(SRetention)); + } + taosArrayPush(expect.pRetensions, &retention); + ++expect.numOfRetensions; + }; + + setCheckDdlFunc([&](const SQuery* pQuery, ParserStage stage) { + ASSERT_EQ(nodeType(pQuery->pRoot), QUERY_NODE_CREATE_DATABASE_STMT); + SCreateDbReq req = {0}; + ASSERT_TRUE(TSDB_CODE_SUCCESS == tDeserializeSCreateDbReq(pQuery->pCmdMsg->pMsg, pQuery->pCmdMsg->msgLen, &req)); + + ASSERT_EQ(std::string(req.db), std::string(expect.db)); + ASSERT_EQ(req.numOfVgroups, expect.numOfVgroups); + ASSERT_EQ(req.numOfStables, expect.numOfStables); + ASSERT_EQ(req.buffer, expect.buffer); + ASSERT_EQ(req.pageSize, expect.pageSize); + ASSERT_EQ(req.pages, expect.pages); + ASSERT_EQ(req.daysPerFile, expect.daysPerFile); + ASSERT_EQ(req.daysToKeep0, expect.daysToKeep0); + ASSERT_EQ(req.daysToKeep1, expect.daysToKeep1); + ASSERT_EQ(req.daysToKeep2, expect.daysToKeep2); + ASSERT_EQ(req.minRows, expect.minRows); + ASSERT_EQ(req.maxRows, expect.maxRows); + ASSERT_EQ(req.fsyncPeriod, expect.fsyncPeriod); + ASSERT_EQ(req.walLevel, expect.walLevel); + ASSERT_EQ(req.precision, expect.precision); + ASSERT_EQ(req.compression, expect.compression); + ASSERT_EQ(req.replications, expect.replications); + ASSERT_EQ(req.strict, expect.strict); + ASSERT_EQ(req.cacheLastRow, expect.cacheLastRow); + ASSERT_EQ(req.ignoreExist, expect.ignoreExist); + ASSERT_EQ(req.numOfRetensions, expect.numOfRetensions); + if (expect.numOfRetensions > 0) { + ASSERT_EQ(taosArrayGetSize(req.pRetensions), expect.numOfRetensions); + ASSERT_EQ(taosArrayGetSize(req.pRetensions), taosArrayGetSize(expect.pRetensions)); + for (int32_t i = 0; i < expect.numOfRetensions; ++i) { + SRetention* pReten = (SRetention*)taosArrayGet(req.pRetensions, i); + SRetention* pExpectReten = (SRetention*)taosArrayGet(expect.pRetensions, i); + ASSERT_EQ(pReten->freq, pExpectReten->freq); + ASSERT_EQ(pReten->keep, pExpectReten->keep); + ASSERT_EQ(pReten->freqUnit, pExpectReten->freqUnit); + ASSERT_EQ(pReten->keepUnit, pExpectReten->keepUnit); + } + } + }); + + setCreateDbReqFunc("wxy_db"); + run("CREATE DATABASE wxy_db"); + + setCreateDbReqFunc("wxy_db", 1); + setDbBufferFunc(64); + setDbCachelastFunc(2); + setDbCompressionFunc(1); + setDbDaysFunc(100 * 1440); + setDbFsyncFunc(100); + setDbMaxRowsFunc(1000); + setDbMinRowsFunc(100); + setDbKeepFunc(1440 * 1440); + setDbPagesFunc(96); + setDbPageSizeFunc(8); + setDbPrecisionFunc(TSDB_TIME_PRECISION_NANO); + setDbReplicaFunc(3); + addDbRetentionFunc(15 * MILLISECOND_PER_SECOND, 7 * MILLISECOND_PER_DAY, TIME_UNIT_SECOND, TIME_UNIT_DAY); + addDbRetentionFunc(1 * MILLISECOND_PER_MINUTE, 21 * MILLISECOND_PER_DAY, TIME_UNIT_MINUTE, TIME_UNIT_DAY); + addDbRetentionFunc(15 * MILLISECOND_PER_MINUTE, 5, TIME_UNIT_MINUTE, TIME_UNIT_YEAR); + setDbStrictaFunc(1); + setDbWalLevelFunc(2); + setDbVgroupsFunc(100); + setDbSingleStableFunc(1); + run("CREATE DATABASE IF NOT EXISTS wxy_db " + "BUFFER 64 " + "CACHELAST 2 " + "COMP 1 " + "DAYS 100 " + "FSYNC 100 " + "MAXROWS 1000 " + "MINROWS 100 " + "KEEP 1440 " + "PAGES 96 " + "PAGESIZE 8 " + "PRECISION 'ns' " + "REPLICA 3 " + "RETENTIONS 15s:7d,1m:21d,15m:5y " + "STRICT 1 " + "WAL 2 " + "VGROUPS 100 " + "SINGLE_STABLE 1 "); + + setCreateDbReqFunc("wxy_db", 1); + setDbDaysFunc(100); + setDbKeepFunc(1440, 300 * 60, 400 * 1440); + run("CREATE DATABASE IF NOT EXISTS wxy_db " + "DAYS 100m " + "KEEP 1440m,300h,400d "); } TEST_F(ParserInitialCTest, createDnode) { useDb("root", "test"); - run("create dnode abc1 port 7000"); + run("CREATE DNODE abc1 PORT 7000"); - run("create dnode 1.1.1.1 port 9000"); + run("CREATE DNODE 1.1.1.1 PORT 9000"); } -// todo create function +// todo CREATE FUNCTION TEST_F(ParserInitialCTest, createIndexSma) { useDb("root", "test"); - run("create sma index index1 on t1 function(max(c1), min(c3 + 10), sum(c4)) INTERVAL(10s)"); + run("CREATE SMA INDEX index1 ON t1 FUNCTION(MAX(c1), MIN(c3 + 10), SUM(c4)) INTERVAL(10s)"); } TEST_F(ParserInitialCTest, createMnode) { useDb("root", "test"); - run("create mnode on dnode 1"); + run("CREATE MNODE ON DNODE 1"); } TEST_F(ParserInitialCTest, createQnode) { useDb("root", "test"); - run("create qnode on dnode 1"); + run("CREATE QNODE ON DNODE 1"); } TEST_F(ParserInitialCTest, createSnode) { useDb("root", "test"); - run("create snode on dnode 1"); + run("CREATE SNODE ON DNODE 1"); } TEST_F(ParserInitialCTest, createStable) { @@ -194,7 +349,7 @@ TEST_F(ParserInitialCTest, createStable) { addFieldToCreateStbReqFunc(true, "ts", TSDB_DATA_TYPE_TIMESTAMP); addFieldToCreateStbReqFunc(true, "c1", TSDB_DATA_TYPE_INT); addFieldToCreateStbReqFunc(false, "id", TSDB_DATA_TYPE_INT); - run("create stable t1(ts timestamp, c1 int) TAGS(id int)"); + run("CREATE STABLE t1(ts TIMESTAMP, c1 INT) TAGS(id INT)"); setCreateStbReqFunc("t1", 1, 0.1, 2, 100, "test create table"); addFieldToCreateStbReqFunc(true, "ts", TSDB_DATA_TYPE_TIMESTAMP, 0, 0); @@ -227,80 +382,72 @@ TEST_F(ParserInitialCTest, createStable) { addFieldToCreateStbReqFunc(false, "a13", TSDB_DATA_TYPE_BOOL); addFieldToCreateStbReqFunc(false, "a14", TSDB_DATA_TYPE_NCHAR, 30 * TSDB_NCHAR_SIZE + VARSTR_HEADER_SIZE); addFieldToCreateStbReqFunc(false, "a15", TSDB_DATA_TYPE_VARCHAR, 50 + VARSTR_HEADER_SIZE); - run("create stable if not exists test.t1(" + run("CREATE STABLE IF NOT EXISTS test.t1(" "ts TIMESTAMP, c1 INT, c2 INT UNSIGNED, c3 BIGINT, c4 BIGINT UNSIGNED, c5 FLOAT, c6 DOUBLE, c7 BINARY(20), " "c8 SMALLINT, c9 SMALLINT UNSIGNED COMMENT 'test column comment', c10 TINYINT, c11 TINYINT UNSIGNED, c12 BOOL, " "c13 NCHAR(30), c14 VARCHAR(50)) " "TAGS (a1 TIMESTAMP, a2 INT, a3 INT UNSIGNED, a4 BIGINT, a5 BIGINT UNSIGNED, a6 FLOAT, a7 DOUBLE, " "a8 BINARY(20), a9 SMALLINT, a10 SMALLINT UNSIGNED COMMENT 'test column comment', a11 TINYINT, " "a12 TINYINT UNSIGNED, a13 BOOL, a14 NCHAR(30), a15 VARCHAR(50)) " - "TTL 100 COMMENT 'test create table' SMA(c1, c2, c3) ROLLUP (min) FILE_FACTOR 0.1 DELAY 2"); + "TTL 100 COMMENT 'test create table' SMA(c1, c2, c3) ROLLUP (MIN) FILE_FACTOR 0.1 DELAY 2"); } TEST_F(ParserInitialCTest, createStream) { useDb("root", "test"); - run("create stream s1 as select * from t1"); + run("CREATE STREAM s1 AS SELECT * FROM t1"); - run("create stream if not exists s1 as select * from t1"); + run("CREATE STREAM IF NOT EXISTS s1 AS SELECT * FROM t1"); - run("create stream s1 into st1 as select * from t1"); + run("CREATE STREAM s1 INTO st1 AS SELECT * FROM t1"); - run("create stream if not exists s1 trigger window_close watermark 10s into st1 as select * from t1"); + run("CREATE STREAM IF NOT EXISTS s1 TRIGGER WINDOW_CLOSE WATERMARK 10s INTO st1 AS SELECT * FROM t1"); } TEST_F(ParserInitialCTest, createTable) { useDb("root", "test"); - run("create table t1(ts timestamp, c1 int)"); + run("CREATE TABLE t1(ts TIMESTAMP, c1 INT)"); - run("create table if not exists test.t1(" - "ts TIMESTAMP, c1 INT, c2 INT UNSIGNED, c3 BIGINT, c4 BIGINT UNSIGNED, c5 FLOAT, c6 DOUBLE, c7 BINARY(20), c8 " - "SMALLINT, " - "c9 SMALLINT UNSIGNED COMMENT 'test column comment', c10 TINYINT, c11 TINYINT UNSIGNED, c12 BOOL, c13 " - "NCHAR(30), " - "c15 VARCHAR(50)) " + run("CREATE TABLE IF NOT EXISTS test.t1(" + "ts TIMESTAMP, c1 INT, c2 INT UNSIGNED, c3 BIGINT, c4 BIGINT UNSIGNED, c5 FLOAT, c6 DOUBLE, c7 BINARY(20), " + "c8 SMALLINT, c9 SMALLINT UNSIGNED COMMENT 'test column comment', c10 TINYINT, c11 TINYINT UNSIGNED, c12 BOOL, " + "c13 NCHAR(30), c15 VARCHAR(50)) " "TTL 100 COMMENT 'test create table' SMA(c1, c2, c3)"); - run("create table if not exists test.t1(" - "ts TIMESTAMP, c1 INT, c2 INT UNSIGNED, c3 BIGINT, c4 BIGINT UNSIGNED, c5 FLOAT, c6 DOUBLE, c7 BINARY(20), c8 " - "SMALLINT, " - "c9 SMALLINT UNSIGNED COMMENT 'test column comment', c10 TINYINT, c11 TINYINT UNSIGNED, c12 BOOL, c13 " - "NCHAR(30), " - "c15 VARCHAR(50)) " - "TAGS (tsa TIMESTAMP, a1 INT, a2 INT UNSIGNED, a3 BIGINT, a4 BIGINT UNSIGNED, " - "a5 FLOAT, a6 DOUBLE, a7 " - "BINARY(20), a8 SMALLINT, " - "a9 SMALLINT UNSIGNED COMMENT 'test column comment', a10 " - "TINYINT, a11 TINYINT UNSIGNED, a12 BOOL, a13 NCHAR(30), " - "a15 VARCHAR(50)) " - "TTL 100 COMMENT 'test create " - "table' SMA(c1, c2, c3) ROLLUP (min) FILE_FACTOR 0.1 DELAY 2"); + run("CREATE TABLE IF NOT EXISTS test.t1(" + "ts TIMESTAMP, c1 INT, c2 INT UNSIGNED, c3 BIGINT, c4 BIGINT UNSIGNED, c5 FLOAT, c6 DOUBLE, c7 BINARY(20), " + "c8 SMALLINT, c9 SMALLINT UNSIGNED COMMENT 'test column comment', c10 TINYINT, c11 TINYINT UNSIGNED, c12 BOOL, " + "c13 NCHAR(30), c14 VARCHAR(50)) " + "TAGS (a1 TIMESTAMP, a2 INT, a3 INT UNSIGNED, a4 BIGINT, a5 BIGINT UNSIGNED, a6 FLOAT, a7 DOUBLE, a8 BINARY(20), " + "a9 SMALLINT, a10 SMALLINT UNSIGNED COMMENT 'test column comment', a11 TINYINT, a12 TINYINT UNSIGNED, a13 BOOL, " + "a14 NCHAR(30), a15 VARCHAR(50)) " + "TTL 100 COMMENT 'test create table' SMA(c1, c2, c3) ROLLUP (MIN) FILE_FACTOR 0.1 DELAY 2"); - run("create table if not exists t1 using st1 tags(1, 'wxy')"); + run("CREATE TABLE IF NOT EXISTS t1 USING st1 TAGS(1, 'wxy')"); - run("create table " - "if not exists test.t1 using test.st1 (tag1, tag2) tags(1, 'abc') " - "if not exists test.t2 using test.st1 (tag1, tag2) tags(2, 'abc') " - "if not exists test.t3 using test.st1 (tag1, tag2) tags(3, 'abc') "); + run("CREATE TABLE " + "IF NOT EXISTS test.t1 USING test.st1 (tag1, tag2) TAGS(1, 'abc') " + "IF NOT EXISTS test.t2 USING test.st1 (tag1, tag2) TAGS(2, 'abc') " + "IF NOT EXISTS test.t3 USING test.st1 (tag1, tag2) TAGS(3, 'abc') "); } TEST_F(ParserInitialCTest, createTopic) { useDb("root", "test"); - run("create topic tp1 as select * from t1"); + run("CREATE TOPIC tp1 AS SELECT * FROM t1"); - run("create topic if not exists tp1 as select * from t1"); + run("CREATE TOPIC IF NOT EXISTS tp1 AS SELECT * FROM t1"); - run("create topic tp1 as test"); + run("CREATE TOPIC tp1 AS test"); - run("create topic if not exists tp1 as test"); + run("CREATE TOPIC IF NOT EXISTS tp1 AS test"); } TEST_F(ParserInitialCTest, createUser) { useDb("root", "test"); - run("create user wxy pass '123456'"); + run("CREATE USER wxy PASS '123456'"); } } // namespace ParserTest diff --git a/source/libs/planner/src/planner.c b/source/libs/planner/src/planner.c index 6336377279..9ef4d80660 100644 --- a/source/libs/planner/src/planner.c +++ b/source/libs/planner/src/planner.c @@ -16,9 +16,10 @@ #include "planner.h" #include "planInt.h" +#include "scalar.h" typedef struct SCollectPlaceholderValuesCxt { - int32_t errCode; + int32_t errCode; SArray* pValues; } SCollectPlaceholderValuesCxt; @@ -144,9 +145,10 @@ static int32_t setValueByBindParam(SValueNode* pVal, TAOS_MULTI_BIND* pParam) { if (NULL == pVal->datum.p) { return TSDB_CODE_OUT_OF_MEMORY; } - + int32_t output = 0; - if (!taosMbsToUcs4(pParam->buffer, inputSize, (TdUcs4*)varDataVal(pVal->datum.p), pVal->node.resType.bytes, &output)) { + if (!taosMbsToUcs4(pParam->buffer, inputSize, (TdUcs4*)varDataVal(pVal->datum.p), pVal->node.resType.bytes, + &output)) { return errno; } varDataSetLen(pVal->datum.p, output); @@ -181,8 +183,8 @@ static int32_t setValueByBindParam(SValueNode* pVal, TAOS_MULTI_BIND* pParam) { } static EDealRes updatePlanQueryId(SNode* pNode, void* pContext) { - int64_t queryId = *(uint64_t *)pContext; - + int64_t queryId = *(uint64_t*)pContext; + if (QUERY_NODE_PHYSICAL_PLAN == nodeType(pNode)) { SQueryPlan* planNode = (SQueryPlan*)pNode; planNode->queryId = queryId; @@ -194,10 +196,130 @@ static EDealRes updatePlanQueryId(SNode* pNode, void* pContext) { return DEAL_RES_CONTINUE; } -int32_t qStmtBindParam(SQueryPlan* pPlan, TAOS_MULTI_BIND* pParams, int32_t colIdx, uint64_t queryId) { +static int32_t calcConstNode(SNode** pNode) { + if (NULL == *pNode) { + return TSDB_CODE_SUCCESS; + } + + SNode* pNew = NULL; + int32_t code = scalarCalculateConstants(*pNode, &pNew); + if (TSDB_CODE_SUCCESS == code) { + *pNode = pNew; + } + return code; +} + +static int32_t calcConstList(SNodeList* pList) { + SNode* pNode = NULL; + FOREACH(pNode, pList) { + SNode* pNew = NULL; + int32_t code = scalarCalculateConstants(pNode, &pNew); + if (TSDB_CODE_SUCCESS == code) { + REPLACE_NODE(pNew); + } else { + return code; + } + } + return TSDB_CODE_SUCCESS; +} + +static bool isEmptyResultCond(SNode** pCond) { + if (QUERY_NODE_VALUE != nodeType(*pCond)) { + return false; + } + if (((SValueNode*)*pCond)->datum.b) { + nodesDestroyNode(*pCond); + *pCond = NULL; + return false; + } + return true; +} + +static int32_t calcConstSpecificPhysiNode(SPhysiNode* pPhyNode) { + switch (nodeType(pPhyNode)) { + case QUERY_NODE_PHYSICAL_PLAN_TAG_SCAN: + case QUERY_NODE_PHYSICAL_PLAN_TABLE_SCAN: + case QUERY_NODE_PHYSICAL_PLAN_TABLE_SEQ_SCAN: + case QUERY_NODE_PHYSICAL_PLAN_STREAM_SCAN: + case QUERY_NODE_PHYSICAL_PLAN_SYSTABLE_SCAN: + case QUERY_NODE_PHYSICAL_PLAN_EXCHANGE: + case QUERY_NODE_PHYSICAL_PLAN_FILL: + return TSDB_CODE_SUCCESS; + case QUERY_NODE_PHYSICAL_PLAN_PROJECT: + return calcConstList(((SProjectPhysiNode*)pPhyNode)->pProjections); + case QUERY_NODE_PHYSICAL_PLAN_JOIN: + return calcConstNode(&(((SJoinPhysiNode*)pPhyNode)->pOnConditions)); + case QUERY_NODE_PHYSICAL_PLAN_AGG: + return calcConstList(((SAggPhysiNode*)pPhyNode)->pExprs); + case QUERY_NODE_PHYSICAL_PLAN_SORT: + return calcConstList(((SSortPhysiNode*)pPhyNode)->pExprs); + case QUERY_NODE_PHYSICAL_PLAN_INTERVAL: + case QUERY_NODE_PHYSICAL_PLAN_STREAM_INTERVAL: + case QUERY_NODE_PHYSICAL_PLAN_SESSION_WINDOW: + case QUERY_NODE_PHYSICAL_PLAN_STATE_WINDOW: + return calcConstList(((SWinodwPhysiNode*)pPhyNode)->pExprs); + case QUERY_NODE_PHYSICAL_PLAN_PARTITION: + return calcConstList(((SPartitionPhysiNode*)pPhyNode)->pExprs); + default: + break; + } + return TSDB_CODE_SUCCESS; +} + +static int32_t calcConstSubplan(SPhysiNode* pPhyNode, bool* pEmptyResult) { + int32_t code = calcConstNode(&pPhyNode->pConditions); + if (TSDB_CODE_SUCCESS == code) { + code = calcConstSpecificPhysiNode(pPhyNode); + } + if (TSDB_CODE_SUCCESS != code) { + return code; + } + + *pEmptyResult = isEmptyResultCond(&pPhyNode->pConditions); + if (*pEmptyResult) { + return TSDB_CODE_SUCCESS; + } + + *pEmptyResult = true; + + bool subEmptyResult = false; + SNode* pChild = NULL; + FOREACH(pChild, pPhyNode->pChildren) { + code = calcConstSubplan((SPhysiNode*)pChild, &subEmptyResult); + if (TSDB_CODE_SUCCESS != code) { + return code; + } + if (!subEmptyResult) { + *pEmptyResult = false; + } + } + + return TSDB_CODE_SUCCESS; +} + +static int32_t calcConstPhysiPlan(SQueryPlan* pPlan, bool* pEmptyResult) { + *pEmptyResult = true; + + bool subEmptyResult = false; + SNodeListNode* pNode = nodesListGetNode(pPlan->pSubplans, 0); + SNode* pSubplan = NULL; + FOREACH(pSubplan, pNode->pNodeList) { + int32_t code = calcConstSubplan(((SSubplan*)pSubplan)->pNode, pEmptyResult); + if (TSDB_CODE_SUCCESS != code) { + return code; + } + if (!subEmptyResult) { + *pEmptyResult = false; + } + } + return TSDB_CODE_SUCCESS; +} + +int32_t qStmtBindParam(SQueryPlan* pPlan, TAOS_MULTI_BIND* pParams, int32_t colIdx, uint64_t queryId, + bool* pEmptyResult) { int32_t size = taosArrayGetSize(pPlan->pPlaceholderValues); int32_t code = 0; - + if (colIdx < 0) { for (int32_t i = 0; i < size; ++i) { code = setValueByBindParam((SValueNode*)taosArrayGetP(pPlan->pPlaceholderValues, i), pParams + i); @@ -214,9 +336,10 @@ int32_t qStmtBindParam(SQueryPlan* pPlan, TAOS_MULTI_BIND* pParams, int32_t colI if (colIdx < 0 || ((colIdx + 1) == size)) { nodesWalkPhysiPlan((SNode*)pPlan, updatePlanQueryId, &queryId); + code = calcConstPhysiPlan(pPlan, pEmptyResult); } - - return TSDB_CODE_SUCCESS; + + return code; } int32_t qSubPlanToString(const SSubplan* pSubplan, char** pStr, int32_t* pLen) { From 510283290d5adcc31232726484c8beedcf2e4b1d Mon Sep 17 00:00:00 2001 From: Xiaoyu Wang Date: Wed, 11 May 2022 19:49:04 +0800 Subject: [PATCH 3/4] fix: some problems of parser --- source/libs/function/src/builtins.c | 20 -------------------- tests/script/tsim/db/alter_option.sim | 4 ++-- 2 files changed, 2 insertions(+), 22 deletions(-) diff --git a/source/libs/function/src/builtins.c b/source/libs/function/src/builtins.c index 5e3259c8fb..bf1dc091c6 100644 --- a/source/libs/function/src/builtins.c +++ b/source/libs/function/src/builtins.c @@ -977,26 +977,6 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = { .sprocessFunc = timezoneFunction, .finalizeFunc = NULL }, - // { - // .name = "_rowts", - // .type = FUNCTION_TYPE_ROWTS, - // .classification = FUNC_MGT_PSEUDO_COLUMN_FUNC, - // .translateFunc = translateTimePseudoColumn, - // .getEnvFunc = getTimePseudoFuncEnv, - // .initFunc = NULL, - // .sprocessFunc = NULL, - // .finalizeFunc = NULL - // }, - // { - // .name = "_c0", - // .type = FUNCTION_TYPE_ROWTS, - // .classification = FUNC_MGT_PSEUDO_COLUMN_FUNC, - // .translateFunc = translateTimePseudoColumn, - // .getEnvFunc = getTimePseudoFuncEnv, - // .initFunc = NULL, - // .sprocessFunc = NULL, - // .finalizeFunc = NULL - // }, { .name = "tbname", .type = FUNCTION_TYPE_TBNAME, diff --git a/tests/script/tsim/db/alter_option.sim b/tests/script/tsim/db/alter_option.sim index 40882306c8..aeb04293f2 100644 --- a/tests/script/tsim/db/alter_option.sim +++ b/tests/script/tsim/db/alter_option.sim @@ -66,7 +66,7 @@ print ============= create database # | REPLICA value [1 | 3] # | WAL value [1 | 2] -sql create database db CACHELAST 3 COMP 0 DAYS 345600 FSYNC 1000 MAXROWS 8000 MINROWS 10 KEEP 1440000 PRECISION 'ns' REPLICA 3 WAL 2 VGROUPS 6 SINGLE_STABLE 1 +sql create database db CACHELAST 3 COMP 0 DAYS 240 FSYNC 1000 MAXROWS 8000 MINROWS 10 KEEP 1000 PRECISION 'ns' REPLICA 3 WAL 2 VGROUPS 6 SINGLE_STABLE 1 sql show databases print rows: $rows print $data00 $data01 $data02 $data03 $data04 $data05 $data06 $data07 $data08 $data09 @@ -229,7 +229,7 @@ sql_error alter database db days 0 sql_error alter database db days 14400 # set over than keep print ============== modify keep -sql alter database db keep 3456000 +sql alter database db keep 2400 sql show databases print keep $data7_db if $data7_db != 3456000,3456000,3456000 then From ccd07312adb37aead4d6a8d7c3f1e4e2f7909327 Mon Sep 17 00:00:00 2001 From: Xiaoyu Wang Date: Wed, 11 May 2022 19:57:50 +0800 Subject: [PATCH 4/4] fix: some problems of parser --- tests/script/tsim/db/basic6.sim | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/tests/script/tsim/db/basic6.sim b/tests/script/tsim/db/basic6.sim index 8075e54f9e..9075ebb2e8 100644 --- a/tests/script/tsim/db/basic6.sim +++ b/tests/script/tsim/db/basic6.sim @@ -15,8 +15,7 @@ $tb = $tbPrefix . $i print =============== step1 # quorum presicion -#sql create database $db vgroups 8 replica 1 days 2880 keep 3650 cache 32 blocks 12 minrows 80 maxrows 10000 wal 2 fsync 1000 comp 0 cachelast 2 precision 'us' -sql create database $db vgroups 8 replica 1 days 2880 keep 3650 minrows 80 maxrows 10000 wal 2 fsync 1000 comp 0 cachelast 2 precision 'us' +sql create database $db vgroups 8 replica 1 days 2 keep 10 minrows 80 maxrows 10000 wal 2 fsync 1000 comp 0 cachelast 2 precision 'us' sql show databases print $data00 $data01 $data02 $data03 $data04 $data05 $data06 $data07 $data08 $data09 @@ -38,7 +37,7 @@ endi if $data26 != 2880 then return -1 endi -if $data27 != 3650,3650,3650 then +if $data27 != 14400,14400,14400 then return -1 endi #if $data28 != 32 then @@ -67,7 +66,7 @@ print =============== step4 sql_error drop database $db print =============== step5 -sql create database $db replica 1 days 21600 keep 2160000 +sql create database $db replica 1 days 15 keep 1500 sql show databases print $data00 $data01 $data02 $data03 $data04 $data05 $data06 $data07 if $data20 != $db then