diff --git a/.appveyor.yml b/.appveyor.yml new file mode 100644 index 0000000000..559431e2f9 --- /dev/null +++ b/.appveyor.yml @@ -0,0 +1,28 @@ +version: 1.0.{build} +os: Visual Studio 2015 +environment: + matrix: + - ARCH: amd64 + +clone_folder: c:\dev\TDengine +clone_depth: 1 + +init: + - call "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat" %ARCH% + +before_build: + - cd c:\dev\TDengine + - md build + +build_script: + - cd build + - cmake -G "NMake Makefiles" .. + - nmake install + +notifications: +- provider: Email + to: + - sangshuduo@gmail.com + on_build_success: true + on_build_failure: true + on_build_status_changed: true diff --git a/.gitignore b/.gitignore index ba8611030b..f2c1cb75b3 100644 --- a/.gitignore +++ b/.gitignore @@ -12,6 +12,7 @@ rpms/ mac/ *.pyc *.tmp +*.swp src/connector/nodejs/node_modules/ src/connector/nodejs/out/ tests/test/ diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000000..4679ad71de --- /dev/null +++ b/.travis.yml @@ -0,0 +1,66 @@ +# +# Configuration +# +git: + depth: 1 + +language: c + +compiler: + - clang + - gcc + +os: + - linux + - osx + +addons: + coverity_scan: + + # GitHub project metadata + # ** specific to your project ** + project: + name: TDengine + version: 2.x + description: TDengine + + # Where email notification of build analysis results will be sent + notification_email: sdsang@taosdata.com + + # Commands to prepare for build_command + # ** likely specific to your build ** + build_command_prepend: cmake .. + + # The command that will be added as an argument to "cov-build" to compile your project for analysis, + # ** likely specific to your build ** + build_command: cmake --build . + + # Pattern to match selecting branches that will run analysis. We recommend leaving this set to 'coverity_scan'. + # Take care in resource usage, and consider the build frequency allowances per + # https://scan.coverity.com/faq#frequency + branch_pattern: coverity_scan + +before_script: + - mkdir build + - cd build + +script: + - cmake .. + - cmake --build . + +# +# Build Matrix +# +matrix: + - os: linux + addons: + apt: + packages: + - build-essential + - cmake + + - os: osx + addons: + homebrew: + - cmake + diff --git a/README.md b/README.md index 8d60a892e0..280cf73ba0 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,6 @@ +[![Build Status](https://travis-ci.org/taosdata/TDengine.svg?branch=master)](https://travis-ci.org/taosdata/TDengine) +[![Build status](https://ci.appveyor.com/api/projects/status/kf3pwh2or5afsgl9/branch/master?svg=true)](https://ci.appveyor.com/project/sangshuduo/tdengine-2n8ge/branch/master) + [![TDengine](TDenginelogo.png)](https://www.taosdata.com) # What is TDengine? diff --git a/src/client/inc/tsclient.h b/src/client/inc/tsclient.h index 9cb43a9f36..054b2894c5 100644 --- a/src/client/inc/tsclient.h +++ b/src/client/inc/tsclient.h @@ -357,7 +357,6 @@ typedef struct SSqlObj { char freed : 4; char listed : 4; tsem_t rspSem; - tsem_t emptyRspSem; SSqlCmd cmd; SSqlRes res; uint8_t numOfSubs; @@ -409,7 +408,7 @@ int tscProcessSql(SSqlObj *pSql); int tscRenewMeterMeta(SSqlObj *pSql, char *tableId); void tscQueueAsyncRes(SSqlObj *pSql); -void tscQueueAsyncError(void(*fp), void *param); +void tscQueueAsyncError(void(*fp), void *param, int32_t code); int tscProcessLocalCmd(SSqlObj *pSql); int tscCfgDynamicOptions(char *msg); @@ -450,7 +449,7 @@ void tscFreeSqlObj(SSqlObj *pObj); void tscCloseTscObj(STscObj *pObj); -void doAsyncQuery(STscObj* pObj, SSqlObj* pSql, void (*fp)(), void* param, const char* sqlstr, int32_t sqlLen); +void doAsyncQuery(STscObj* pObj, SSqlObj* pSql, void (*fp)(), void* param, const char* sqlstr, size_t sqlLen); void tscProcessMultiVnodesInsert(SSqlObj *pSql); void tscProcessMultiVnodesInsertFromFile(SSqlObj *pSql); diff --git a/src/client/src/tscAsync.c b/src/client/src/tscAsync.c index c1738e6801..99104ed68c 100644 --- a/src/client/src/tscAsync.c +++ b/src/client/src/tscAsync.c @@ -40,7 +40,7 @@ static void tscProcessAsyncRetrieveImpl(void *param, TAOS_RES *tres, int numOfRo static void tscAsyncFetchRowsProxy(void *param, TAOS_RES *tres, int numOfRows); static void tscAsyncFetchSingleRowProxy(void *param, TAOS_RES *tres, int numOfRows); -void doAsyncQuery(STscObj* pObj, SSqlObj* pSql, void (*fp)(), void* param, const char* sqlstr, int32_t sqlLen) { +void doAsyncQuery(STscObj* pObj, SSqlObj* pSql, void (*fp)(), void* param, const char* sqlstr, size_t sqlLen) { SSqlCmd *pCmd = &pSql->cmd; SSqlRes *pRes = &pSql->res; @@ -51,17 +51,15 @@ void doAsyncQuery(STscObj* pObj, SSqlObj* pSql, void (*fp)(), void* param, const if (TSDB_CODE_SUCCESS != tscAllocPayload(pCmd, TSDB_DEFAULT_PAYLOAD_SIZE)) { tscError("failed to malloc payload"); - tfree(pSql); - tscQueueAsyncError(fp, param); + tscQueueAsyncError(fp, param, TSDB_CODE_CLI_OUT_OF_MEMORY); return; } - pSql->sqlstr = malloc(sqlLen + 1); + pSql->sqlstr = realloc(pSql->sqlstr, sqlLen + 1); if (pSql->sqlstr == NULL) { tscError("%p failed to malloc sql string buffer", pSql); - tscQueueAsyncError(fp, param); + tscQueueAsyncError(fp, param, TSDB_CODE_CLI_OUT_OF_MEMORY); free(pCmd->payload); - free(pSql); return; } @@ -75,7 +73,7 @@ void doAsyncQuery(STscObj* pObj, SSqlObj* pSql, void (*fp)(), void* param, const if (code == TSDB_CODE_ACTION_IN_PROGRESS) return; if (code != TSDB_CODE_SUCCESS) { - pSql->res.code = (uint8_t)code; + pSql->res.code = code; tscQueueAsyncRes(pSql); return; } @@ -88,15 +86,16 @@ void taos_query_a(TAOS *taos, const char *sqlstr, __async_cb_func_t fp, void *pa STscObj *pObj = (STscObj *)taos; if (pObj == NULL || pObj->signature != pObj) { tscError("bug!!! pObj:%p", pObj); - globalCode = TSDB_CODE_DISCONNECTED; - tscQueueAsyncError(fp, param); + terrno = TSDB_CODE_DISCONNECTED; + tscQueueAsyncError(fp, param, TSDB_CODE_DISCONNECTED); return; } int32_t sqlLen = strlen(sqlstr); if (sqlLen > tsMaxSQLStringLen) { tscError("sql string too long"); - tscQueueAsyncError(fp, param); + terrno = TSDB_CODE_INVALID_SQL; + tscQueueAsyncError(fp, param, TSDB_CODE_INVALID_SQL); return; } @@ -105,7 +104,8 @@ void taos_query_a(TAOS *taos, const char *sqlstr, __async_cb_func_t fp, void *pa SSqlObj *pSql = (SSqlObj *)calloc(1, sizeof(SSqlObj)); if (pSql == NULL) { tscError("failed to malloc sqlObj"); - tscQueueAsyncError(fp, param); + terrno = TSDB_CODE_CLI_OUT_OF_MEMORY; + tscQueueAsyncError(fp, param, TSDB_CODE_CLI_OUT_OF_MEMORY); return; } @@ -170,7 +170,7 @@ static void tscProcessAsyncRetrieveImpl(void *param, TAOS_RES *tres, int numOfRo pRes->code = numOfRows; } - tscQueueAsyncError(pSql->fetchFp, param); + tscQueueAsyncError(pSql->fetchFp, param, pRes->code); return; } @@ -200,8 +200,8 @@ void taos_fetch_rows_a(TAOS_RES *taosa, void (*fp)(void *, TAOS_RES *, int), voi SSqlObj *pSql = (SSqlObj *)taosa; if (pSql == NULL || pSql->signature != pSql) { tscError("sql object is NULL"); - globalCode = TSDB_CODE_DISCONNECTED; - tscQueueAsyncError(fp, param); +// globalCode = TSDB_CODE_DISCONNECTED; + tscQueueAsyncError(fp, param, TSDB_CODE_DISCONNECTED); return; } @@ -210,7 +210,7 @@ void taos_fetch_rows_a(TAOS_RES *taosa, void (*fp)(void *, TAOS_RES *, int), voi if (pRes->qhandle == 0) { tscError("qhandle is NULL"); - tscQueueAsyncError(fp, param); + tscQueueAsyncError(fp, param, TSDB_CODE_INVALID_QHANDLE); return; } @@ -232,8 +232,8 @@ void taos_fetch_row_a(TAOS_RES *taosa, void (*fp)(void *, TAOS_RES *, TAOS_ROW), SSqlObj *pSql = (SSqlObj *)taosa; if (pSql == NULL || pSql->signature != pSql) { tscError("sql object is NULL"); - globalCode = TSDB_CODE_DISCONNECTED; - tscQueueAsyncError(fp, param); +// globalCode = TSDB_CODE_DISCONNECTED; + tscQueueAsyncError(fp, param, TSDB_CODE_DISCONNECTED); return; } @@ -242,7 +242,7 @@ void taos_fetch_row_a(TAOS_RES *taosa, void (*fp)(void *, TAOS_RES *, TAOS_ROW), if (pRes->qhandle == 0) { tscError("qhandle is NULL"); - tscQueueAsyncError(fp, param); + tscQueueAsyncError(fp, param, TSDB_CODE_INVALID_QHANDLE); return; } @@ -331,7 +331,7 @@ void tscProcessAsyncRes(SSchedMsg *pMsg) { // pCmd may be released, so cache pCmd->command int cmd = pCmd->command; - int code = pRes->code ? -pRes->code : pRes->numOfRows; + int code = pRes->code; // in case of async insert, restore the user specified callback function bool shouldFree = tscShouldFreeAsyncSqlObj(pSql); @@ -349,18 +349,20 @@ void tscProcessAsyncRes(SSchedMsg *pMsg) { } } -void tscProcessAsyncError(SSchedMsg *pMsg) { +static void tscProcessAsyncError(SSchedMsg *pMsg) { void (*fp)() = pMsg->ahandle; - - (*fp)(pMsg->thandle, NULL, -1); + (*fp)(pMsg->thandle, NULL, *(int32_t*)pMsg->msg); } -void tscQueueAsyncError(void(*fp), void *param) { +void tscQueueAsyncError(void(*fp), void *param, int32_t code) { + int32_t* c = malloc(sizeof(int32_t)); + *c = code; + SSchedMsg schedMsg; schedMsg.fp = tscProcessAsyncError; schedMsg.ahandle = fp; schedMsg.thandle = param; - schedMsg.msg = NULL; + schedMsg.msg = c; taosScheduleTask(tscQhandle, &schedMsg); } @@ -412,7 +414,7 @@ void tscTableMetaCallBack(void *param, TAOS_RES *res, int code) { if (code != 0) { pRes->code = code; tscTrace("%p failed to renew tableMeta", pSql); - tsem_post(&pSql->rspSem); +// tsem_post(&pSql->rspSem); } else { tscTrace("%p renew tableMeta successfully, command:%d, code:%d, retry:%d", pSql, pSql->cmd.command, pSql->res.code, pSql->retry); @@ -424,7 +426,7 @@ void tscTableMetaCallBack(void *param, TAOS_RES *res, int code) { code = tscSendMsgToServer(pSql); if (code != 0) { pRes->code = code; - tsem_post(&pSql->rspSem); +// tsem_post(&pSql->rspSem); } } diff --git a/src/client/src/tscParseInsert.c b/src/client/src/tscParseInsert.c index 6d01538d8f..b8c12bbbdc 100644 --- a/src/client/src/tscParseInsert.c +++ b/src/client/src/tscParseInsert.c @@ -1291,9 +1291,18 @@ int tsParseInsertSql(SSqlObj *pSql) { return doParseInsertSql(pSql, pSql->sqlstr + index); } -int tsParseSql(SSqlObj *pSql, bool multiVnodeInsertion) { +int tsParseSql(SSqlObj *pSql, bool initialParse) { int32_t ret = TSDB_CODE_SUCCESS; - tscTrace("continue parse sql: %s", pSql->asyncTblPos); + + if (initialParse) { + char* p = pSql->sqlstr; + pSql->sqlstr = NULL; + + tscFreeSqlObjPartial(pSql); + pSql->sqlstr = p; + } else { + tscTrace("continue parse sql: %s", pSql->asyncTblPos); + } if (tscIsInsertOrImportData(pSql->sqlstr)) { /* @@ -1301,18 +1310,19 @@ int tsParseSql(SSqlObj *pSql, bool multiVnodeInsertion) { * Set the fp before parse the sql string, in case of getmetermeta failed, in which * the error handle callback function can rightfully restore the user defined function (fp) */ - if (pSql->fp != NULL && multiVnodeInsertion) { - pSql->fetchFp = pSql->fp; - + if (initialParse) { // replace user defined callback function with multi-insert proxy function + pSql->fetchFp = pSql->fp; pSql->fp = (void(*)())tscHandleMultivnodeInsert; } ret = tsParseInsertSql(pSql); } else { ret = tscAllocPayload(&pSql->cmd, TSDB_DEFAULT_PAYLOAD_SIZE); - if (TSDB_CODE_SUCCESS != ret) return ret; - + if (TSDB_CODE_SUCCESS != ret) { + return ret; + } + SSqlInfo SQLInfo = {0}; tSQLParse(&SQLInfo, pSql->sqlstr); @@ -1443,57 +1453,6 @@ static int tscInsertDataFromFile(SSqlObj *pSql, FILE *fp, char *tmpTokenBuf) { return numOfRows; } -/* multi-vnodes insertion in sync query model - * - * modify history - * 2019.05.10 lihui - * Remove the code for importing records from files - */ -void tscProcessMultiVnodesInsert(SSqlObj *pSql) { - SSqlCmd *pCmd = &pSql->cmd; - - // not insert/import, return directly - if (pCmd->command != TSDB_SQL_INSERT) { - return; - } - - // SSqlCmd may have been released - if (pCmd->pDataBlocks == NULL) { - return; - } - - STableDataBlocks *pDataBlock = NULL; - STableMetaInfo * pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, pCmd->clauseIndex, 0); - assert(pCmd->numOfClause == 1); - - int32_t code = TSDB_CODE_SUCCESS; - - /* the first block has been sent to server in processSQL function */ - assert(pTableMetaInfo->vnodeIndex >= 1 && pCmd->pDataBlocks != NULL); - - if (pTableMetaInfo->vnodeIndex < pCmd->pDataBlocks->nSize) { - SDataBlockList *pDataBlocks = pCmd->pDataBlocks; - - for (int32_t i = pTableMetaInfo->vnodeIndex; i < pDataBlocks->nSize; ++i) { - pDataBlock = pDataBlocks->pData[i]; - if (pDataBlock == NULL) { - continue; - } - - if ((code = tscCopyDataBlockToPayload(pSql, pDataBlock)) != TSDB_CODE_SUCCESS) { - tscTrace("%p build submit data block failed, vnodeIdx:%d, total:%d", pSql, pTableMetaInfo->vnodeIndex, - pDataBlocks->nSize); - continue; - } - - tscProcessSql(pSql); - } - } - - // all data have been submit to vnode, release data blocks - pCmd->pDataBlocks = tscDestroyBlockArrayList(pCmd->pDataBlocks); -} - // multi-vnodes insertion in sync query model void tscProcessMultiVnodesInsertFromFile(SSqlObj *pSql) { SSqlCmd *pCmd = &pSql->cmd; diff --git a/src/client/src/tscPrepare.c b/src/client/src/tscPrepare.c index 241f24a747..8b065fcf51 100644 --- a/src/client/src/tscPrepare.c +++ b/src/client/src/tscPrepare.c @@ -488,7 +488,6 @@ TAOS_STMT* taos_stmt_init(TAOS* taos) { } tsem_init(&pSql->rspSem, 0, 0); - tsem_init(&pSql->emptyRspSem, 0, 1); pSql->signature = pSql; pSql->pTscObj = pObj; diff --git a/src/client/src/tscSQLParser.c b/src/client/src/tscSQLParser.c index 4db33b0291..4e7a8ed6bd 100644 --- a/src/client/src/tscSQLParser.c +++ b/src/client/src/tscSQLParser.c @@ -117,7 +117,7 @@ static int32_t doCheckForCreateFromStable(SSqlObj* pSql, SSqlInfo* pInfo); static int32_t doCheckForStream(SSqlObj* pSql, SSqlInfo* pInfo); static int32_t doCheckForQuery(SSqlObj* pSql, SQuerySQL* pQuerySql, int32_t index); -static int32_t tSQLBinaryExprCreateFromSqlExpr(tSQLSyntaxNode **pExpr, tSQLExpr* pAst, int32_t* num, +static int32_t convertSyntaxTreeToExprTree(tExprNode **pExpr, tSQLExpr* pAst, int32_t* num, SColIndexEx** pColIndex, SSqlExprInfo* pExprInfo); /* @@ -215,7 +215,7 @@ int32_t tscToSQLCmd(SSqlObj* pSql, struct SSqlInfo* pInfo) { if (pQueryInfo->numOfTables == 0) { pTableMetaInfo = tscAddEmptyMetaInfo(pQueryInfo); } else { - pTableMetaInfo = &pQueryInfo->pTableMetaInfo[0]; + pTableMetaInfo = pQueryInfo->pTableMetaInfo[0]; } pCmd->command = pInfo->type; @@ -497,6 +497,7 @@ int32_t tscToSQLCmd(SSqlObj* pSql, struct SSqlInfo* pInfo) { } } else if (pCreateTable->type == TSQL_CREATE_TABLE_FROM_STABLE) { + assert(pCmd->numOfCols == 0); if ((code = doCheckForCreateFromStable(pSql, pInfo)) != TSDB_CODE_SUCCESS) { return code; } @@ -1208,12 +1209,12 @@ int32_t parseSelectClause(SSqlCmd* pCmd, int32_t clauseIndex, tSQLExprList* pSel SSqlBinaryExprInfo* pBinExprInfo = &pFuncExpr->binExprInfo; - tSQLSyntaxNode* pNode = NULL; + tExprNode* pNode = NULL; SColIndexEx* pColIndex = NULL; - int32_t ret = tSQLBinaryExprCreateFromSqlExpr(&pNode, pItem->pNode, &pBinExprInfo->numOfCols, &pColIndex, &pQueryInfo->exprsInfo); + int32_t ret = convertSyntaxTreeToExprTree(&pNode, pItem->pNode, &pBinExprInfo->numOfCols, &pColIndex, &pQueryInfo->exprsInfo); if (ret != TSDB_CODE_SUCCESS) { - tSQLBinaryExprDestroy(&pNode, NULL); + tExprTreeDestroy(&pNode, NULL); return invalidSqlErrMsg(pQueryInfo->msg, "invalid expression in select clause"); } @@ -5807,20 +5808,20 @@ int32_t doCheckForQuery(SSqlObj* pSql, SQuerySQL* pQuerySql, int32_t index) { return TSDB_CODE_SUCCESS; // Does not build query message here } -static int32_t tSQLBinaryExprCreateFromSqlExpr(tSQLSyntaxNode **pExpr, tSQLExpr* pAst, int32_t* num, +static int32_t convertSyntaxTreeToExprTree(tExprNode **pExpr, tSQLExpr* pAst, int32_t* num, SColIndexEx** pColIndex, SSqlExprInfo* pExprInfo) { - tSQLSyntaxNode* pLeft = NULL; - tSQLSyntaxNode* pRight= NULL; + tExprNode* pLeft = NULL; + tExprNode* pRight= NULL; if (pAst->pLeft != NULL) { - int32_t ret = tSQLBinaryExprCreateFromSqlExpr(&pLeft, pAst->pLeft, num, pColIndex, pExprInfo); + int32_t ret = convertSyntaxTreeToExprTree(&pLeft, pAst->pLeft, num, pColIndex, pExprInfo); if (ret != TSDB_CODE_SUCCESS) { return ret; } } if (pAst->pRight != NULL) { - int32_t ret = tSQLBinaryExprCreateFromSqlExpr(&pRight, pAst->pRight, num, pColIndex, pExprInfo); + int32_t ret = convertSyntaxTreeToExprTree(&pRight, pAst->pRight, num, pColIndex, pExprInfo); if (ret != TSDB_CODE_SUCCESS) { return ret; } @@ -5828,14 +5829,14 @@ static int32_t tSQLBinaryExprCreateFromSqlExpr(tSQLSyntaxNode **pExpr, tSQLExpr* if (pAst->pLeft == NULL) { if (pAst->nSQLOptr >= TK_TINYINT && pAst->nSQLOptr <= TK_DOUBLE) { - *pExpr = calloc(1, sizeof(tSQLSyntaxNode) + sizeof(tVariant)); + *pExpr = calloc(1, sizeof(tExprNode) + sizeof(tVariant)); (*pExpr)->nodeType = TSQL_NODE_VALUE; - (*pExpr)->pVal = (tVariant*) ((char*)(*pExpr) + sizeof(tSQLSyntaxNode)); + (*pExpr)->pVal = (tVariant*) ((char*)(*pExpr) + sizeof(tExprNode)); tVariantAssign((*pExpr)->pVal, &pAst->val); } else if (pAst->nSQLOptr >= TK_COUNT && pAst->nSQLOptr <= TK_AVG_IRATE) { - *pExpr = calloc(1, sizeof(tSQLSyntaxNode) + sizeof(SSchemaEx)); + *pExpr = calloc(1, sizeof(tExprNode) + sizeof(SSchemaEx)); (*pExpr)->nodeType = TSQL_NODE_COL; - (*pExpr)->pSchema = (SSchema*)((char*)(*pExpr) + sizeof(tSQLSyntaxNode)); + (*pExpr)->pSchema = (SSchema*)((char*)(*pExpr) + sizeof(tExprNode)); strncpy((*pExpr)->pSchema->name, pAst->operand.z, pAst->operand.n); // set the input column data byte and type. @@ -5855,7 +5856,7 @@ static int32_t tSQLBinaryExprCreateFromSqlExpr(tSQLSyntaxNode **pExpr, tSQLExpr* strncpy((*pColIndex)[(*num) - 1].name, pAst->operand.z, pAst->operand.n); } else { - *pExpr = (tSQLSyntaxNode *)calloc(1, sizeof(tSQLSyntaxNode)); + *pExpr = (tExprNode *)calloc(1, sizeof(tExprNode)); (*pExpr)->_node.hasPK = false; (*pExpr)->_node.pLeft = pLeft; (*pExpr)->_node.pRight = pRight; diff --git a/src/client/src/tscServer.c b/src/client/src/tscServer.c index e57f9cc410..87ddd704d2 100644 --- a/src/client/src/tscServer.c +++ b/src/client/src/tscServer.c @@ -285,14 +285,16 @@ void tscProcessMsgFromServer(SRpcMsg *rpcMsg) { pRes->rspType = rpcMsg->msgType; pRes->rspLen = rpcMsg->contLen; - char *tmp = (char *)realloc(pRes->pRsp, pRes->rspLen); - if (tmp == NULL) { - pRes->code = TSDB_CODE_CLI_OUT_OF_MEMORY; - } else { - pRes->pRsp = tmp; - if (pRes->rspLen) { + if (pRes->rspLen > 0) { + char *tmp = (char *)realloc(pRes->pRsp, pRes->rspLen); + if (tmp == NULL) { + pRes->code = TSDB_CODE_CLI_OUT_OF_MEMORY; + } else { + pRes->pRsp = tmp; memcpy(pRes->pRsp, rpcMsg->pCont, pRes->rspLen); } + } else { + pRes->pRsp = NULL; } // ignore the error information returned from mnode when set ignore flag in sql @@ -327,7 +329,7 @@ void tscProcessMsgFromServer(SRpcMsg *rpcMsg) { void *taosres = tscKeepConn[pCmd->command] ? pSql : NULL; rpcMsg->code = pRes->code ? pRes->code : pRes->numOfRows; - tscTrace("%p Async SQL result:%s res:%p", pSql, tstrerror(pRes->code), taosres); + tscTrace("%p Async SQL result:%s res:%p", pSql, tstrerror(pRes->code), pSql); /* * Whether to free sqlObj or not should be decided before call the user defined function, since this SqlObj @@ -893,11 +895,6 @@ int32_t tscBuildCreateDbMsg(SSqlObj *pSql, SSqlInfo *pInfo) { pCmd->payloadLen = sizeof(SCMCreateDbMsg); pCmd->msgType = TSDB_MSG_TYPE_CM_CREATE_DB; - if (TSDB_CODE_SUCCESS != tscAllocPayload(pCmd, pCmd->payloadLen)) { - tscError("%p failed to malloc for query msg", pSql); - return TSDB_CODE_CLI_OUT_OF_MEMORY; - } - SCMCreateDbMsg *pCreateDbMsg = (SCMCreateDbMsg*)pCmd->payload; assert(pCmd->numOfClause == 1); @@ -1228,7 +1225,6 @@ int tscBuildCreateTableMsg(SSqlObj *pSql, SSqlInfo *pInfo) { SCreateTableSQL *pCreateTable = pInfo->pCreateTableInfo; pCreateTableMsg->igExists = pCreateTable->existCheck ? 1 : 0; - pCreateTableMsg->numOfColumns = htons(pCmd->numOfCols); pCreateTableMsg->numOfTags = htons(pCmd->count); diff --git a/src/client/src/tscSql.c b/src/client/src/tscSql.c index bbf46a2353..a3cc785876 100644 --- a/src/client/src/tscSql.c +++ b/src/client/src/tscSql.c @@ -155,6 +155,10 @@ static void syncConnCallback(void *param, TAOS_RES *tres, int code) { STscObj *pObj = (STscObj *)param; assert(pObj != NULL && pObj->pSql != NULL); + if (code < 0) { + pObj->pSql->res.code = code; + } + sem_post(&pObj->pSql->rspSem); } @@ -177,17 +181,17 @@ TAOS *taos_connect(const char *ip, const char *user, const char *pass, const cha sem_wait(&pSql->rspSem); if (pSql->res.code != TSDB_CODE_SUCCESS) { + terrno = pSql->res.code; taos_close(pObj); return NULL; } tscTrace("%p DB connection is opening", pObj); - + // version compare only requires the first 3 segments of the version string int code = taosCheckVersion(version, taos_get_server_info(pObj), 3); if (code != 0) { - pSql->res.code = code; - + terrno = code; taos_close(pObj); return NULL; } else { @@ -267,35 +271,32 @@ int taos_query_imp(STscObj *pObj, SSqlObj *pSql) { return pRes->code; } -static void syncQueryCallback(void *param, TAOS_RES *tres, int code) { - STscObj *pObj = (STscObj *)param; - assert(pObj != NULL && pObj->pSql != NULL); +static void waitForQueryRsp(void *param, TAOS_RES *tres, int code) { + assert(param != NULL); + SSqlObj *pSql = ((STscObj *)param)->pSql; - sem_post(&pObj->pSql->rspSem); + // valid error code is less than 0 + if (code < 0) { + pSql->res.code = code; + } + + sem_post(&pSql->rspSem); } int taos_query(TAOS *taos, const char *sqlstr) { STscObj *pObj = (STscObj *)taos; if (pObj == NULL || pObj->signature != pObj) { - globalCode = TSDB_CODE_DISCONNECTED; + terrno = TSDB_CODE_DISCONNECTED; return TSDB_CODE_DISCONNECTED; } - SSqlObj *pSql = (SSqlObj *)calloc(1, sizeof(SSqlObj)); - if (pSql == NULL) { - tscError("failed to malloc sqlObj"); - return TSDB_CODE_CLI_OUT_OF_MEMORY; - } + SSqlObj* pSql = pObj->pSql; - pObj->pSql = pSql; - tsem_init(&pSql->rspSem, 0, 0); - - int32_t sqlLen = strlen(sqlstr); - doAsyncQuery(pObj, pObj->pSql, syncQueryCallback, taos, sqlstr, sqlLen); + size_t sqlLen = strlen(sqlstr); + doAsyncQuery(pObj, pSql, waitForQueryRsp, taos, sqlstr, sqlLen); // wait for the callback function to post the semaphore sem_wait(&pSql->rspSem); - return pSql->res.code; } @@ -649,12 +650,12 @@ static void **tscBuildResFromSubqueries(SSqlObj *pSql) { return pRes->tsrow; } -static void asyncFetchCallback(void *param, TAOS_RES *tres, int numOfRows) { +static void waitForRetrieveRsp(void *param, TAOS_RES *tres, int numOfRows) { SSqlObj* pSql = (SSqlObj*) tres; + if (numOfRows < 0) { // set the error code pSql->res.code = -numOfRows; } - sem_post(&pSql->rspSem); } @@ -677,7 +678,7 @@ TAOS_ROW taos_fetch_row(TAOS_RES *res) { // current data are exhausted, fetch more data if (pRes->data == NULL || (pRes->data != NULL && pRes->row >= pRes->numOfRows && pRes->completed != true && (pCmd->command == TSDB_SQL_RETRIEVE || pCmd->command == TSDB_SQL_RETRIEVE_METRIC || pCmd->command == TSDB_SQL_FETCH))) { - taos_fetch_rows_a(res, asyncFetchCallback, pSql->pTscObj); + taos_fetch_rows_a(res, waitForRetrieveRsp, pSql->pTscObj); sem_wait(&pSql->rspSem); } @@ -754,20 +755,18 @@ void taos_free_result_imp(TAOS_RES *res, int keepCmd) { if (pRes == NULL || pRes->qhandle == 0) { /* Query rsp is not received from vnode, so the qhandle is NULL */ tscTrace("%p qhandle is null, abort free, fp:%p", pSql, pSql->fp); - if (pSql->fp != NULL) { - STscObj* pObj = pSql->pTscObj; - - if (pSql == pObj->pSql) { - pObj->pSql = NULL; - tscFreeSqlObj(pSql); - } - + + if (tscShouldFreeAsyncSqlObj(pSql)) { + tscFreeSqlObj(pSql); tscTrace("%p Async SqlObj is freed by app", pSql); - } else if (keepCmd) { - tscFreeSqlResult(pSql); } else { - tscFreeSqlObjPartial(pSql); + if (keepCmd) { + tscFreeSqlResult(pSql); + } else { + tscFreeSqlObjPartial(pSql); + } } + return; } @@ -792,10 +791,11 @@ void taos_free_result_imp(TAOS_RES *res, int keepCmd) { * for each subquery. Because the failure of execution tsProcessSql may trigger the callback function * be executed, and the retry efforts may result in double free the resources, e.g.,SRetrieveSupport */ - if (pRes->code != TSDB_CODE_QUERY_CANCELLED && - ((pRes->numOfRows > 0 && pCmd->command < TSDB_SQL_LOCAL) || + if ((pCmd->command == TSDB_SQL_SELECT || pCmd->command == TSDB_SQL_SHOW || pCmd->command == TSDB_SQL_RETRIEVE || + pCmd->command == TSDB_SQL_FETCH) && + (pRes->code != TSDB_CODE_QUERY_CANCELLED && ((pRes->numOfRows > 0 && pCmd->command < TSDB_SQL_LOCAL && pRes->completed == false) || (pRes->code == TSDB_CODE_SUCCESS && pRes->numOfRows == 0 && pCmd->command == TSDB_SQL_SELECT && - pSql->pStream == NULL && pTableMetaInfo->pTableMeta != NULL))) { + pSql->pStream == NULL && pTableMetaInfo->pTableMeta != NULL)))) { pCmd->command = (pCmd->command > TSDB_SQL_MGMT) ? TSDB_SQL_RETRIEVE : TSDB_SQL_FETCH; tscTrace("%p code:%d, numOfRows:%d, command:%d", pSql, pRes->code, pRes->numOfRows, pCmd->command); @@ -836,39 +836,37 @@ void taos_free_result_imp(TAOS_RES *res, int keepCmd) { } } else { // if no free resource msg is sent to vnode, we free this object immediately. - - if (pSql->fp) { + bool free = tscShouldFreeAsyncSqlObj(pSql); + if (free) { assert(pRes->numOfRows == 0 || (pCmd->command > TSDB_SQL_LOCAL)); + tscFreeSqlObj(pSql); tscTrace("%p Async sql result is freed by app", pSql); - } else if (keepCmd) { - tscFreeSqlResult(pSql); - tscTrace("%p sql result is freed while sql command is kept", pSql); } else { - tscFreeSqlObjPartial(pSql); - tscTrace("%p sql result is freed", pSql); + if (keepCmd) { + tscFreeSqlResult(pSql); + tscTrace("%p sql result is freed while sql command is kept", pSql); + } else { + tscFreeSqlObjPartial(pSql); + tscTrace("%p sql result is freed by app", pSql); + } } } } void taos_free_result(TAOS_RES *res) { taos_free_result_imp(res, 0); } +// todo should not be used in async query int taos_errno(TAOS *taos) { STscObj *pObj = (STscObj *)taos; - int code; - if (pObj == NULL || pObj->signature != pObj) return globalCode; + if (pObj == NULL || pObj->signature != pObj) { + return terrno; + } - if ((int8_t)(pObj->pSql->res.code) == -1) - code = TSDB_CODE_OTHERS; - else - code = pObj->pSql->res.code; - - return code; + return pObj->pSql->res.code; } -//static bool validErrorCode(int32_t code) { return code >= TSDB_CODE_SUCCESS && code < TSDB_CODE_MAX_ERROR_CODE; } - /* * In case of invalid sql error, additional information is attached to explain * why the sql is invalid @@ -888,13 +886,15 @@ static bool hasAdditionalErrorInfo(int32_t code, SSqlCmd *pCmd) { return z != NULL; } +// todo should not be used in async model char *taos_errstr(TAOS *taos) { STscObj *pObj = (STscObj *)taos; if (pObj == NULL || pObj->signature != pObj) - return (char*)tstrerror(globalCode); + return (char*)tstrerror(terrno); - SSqlObj *pSql = pObj->pSql; + SSqlObj* pSql = pObj->pSql; + if (hasAdditionalErrorInfo(pSql->res.code, &pSql->cmd)) { return pSql->cmd.payload; } else { diff --git a/src/client/src/tscSub.c b/src/client/src/tscSub.c index 616bcbba50..9d172d4ea5 100644 --- a/src/client/src/tscSub.c +++ b/src/client/src/tscSub.c @@ -124,7 +124,6 @@ static SSub* tscCreateSubscription(STscObj* pObj, const char* topic, const char* pSql->sqlstr = sqlstr; tsem_init(&pSql->rspSem, 0, 0); - tsem_init(&pSql->emptyRspSem, 0, 1); SSqlRes *pRes = &pSql->res; pRes->numOfRows = 1; diff --git a/src/client/src/tscSubquery.c b/src/client/src/tscSubquery.c index b0c7b68ab4..ca6ca369e4 100644 --- a/src/client/src/tscSubquery.c +++ b/src/client/src/tscSubquery.c @@ -392,10 +392,10 @@ void freeSubqueryObj(SSqlObj* pSql) { static void doQuitSubquery(SSqlObj* pParentSql) { freeSubqueryObj(pParentSql); - tsem_wait(&pParentSql->emptyRspSem); - tsem_wait(&pParentSql->emptyRspSem); +// tsem_wait(&pParentSql->emptyRspSem); +// tsem_wait(&pParentSql->emptyRspSem); - tsem_post(&pParentSql->rspSem); +// tsem_post(&pParentSql->rspSem); } static void quitAllSubquery(SSqlObj* pSqlObj, SJoinSubquerySupporter* pSupporter) { @@ -567,7 +567,7 @@ static void joinRetrieveCallback(void* param, TAOS_RES* tres, int numOfRows) { freeSubqueryObj(pParentSql); } - tsem_post(&pParentSql->rspSem); +// tsem_post(&pParentSql->rspSem); } else { tscTrace("%p sub:%p completed, completed:%d, total:%d", pParentSql, tres, finished, numOfTotal); } @@ -662,7 +662,7 @@ void tscFetchDatablockFromSubquery(SSqlObj* pSql) { } // wait for all subquery completed - tsem_wait(&pSql->rspSem); +// tsem_wait(&pSql->rspSem); // update the records for each subquery for(int32_t i = 0; i < pSql->numOfSubs; ++i) { @@ -797,10 +797,7 @@ void tscJoinQueryCallback(void* param, TAOS_RES* tres, int code) { tscProcessSql(pSql); } else { // first retrieve from vnode during the secondary stage sub-query if (pParentSql->fp == NULL) { - tsem_wait(&pParentSql->emptyRspSem); - tsem_wait(&pParentSql->emptyRspSem); - - tsem_post(&pParentSql->rspSem); +// tsem_post(&pParentSql->rspSem); } else { // set the command flag must be after the semaphore been correctly set. // pPObj->cmd.command = TSDB_SQL_RETRIEVE_METRIC; @@ -954,10 +951,7 @@ int32_t tscHandleMasterJoinQuery(SSqlObj* pSql) { } } - tsem_post(&pSql->emptyRspSem); - tsem_wait(&pSql->rspSem); - - tsem_post(&pSql->emptyRspSem); +// tsem_wait(&pSql->rspSem); if (pSql->numOfSubs <= 0) { pSql->cmd.command = TSDB_SQL_RETRIEVE_EMPTY_RESULT; diff --git a/src/client/src/tscSystem.c b/src/client/src/tscSystem.c index 7a585bfa68..ead8c09dec 100644 --- a/src/client/src/tscSystem.c +++ b/src/client/src/tscSystem.c @@ -40,15 +40,10 @@ void * tscQhandle; void * tscCheckDiskUsageTmr; int tsInsertHeadSize; -extern int tscEmbedded; -int tscNumOfThreads; -static pthread_once_t tscinit = PTHREAD_ONCE_INIT; -static pthread_mutex_t tscMutex; +int tscNumOfThreads; -extern int tsTscEnableRecordSql; -extern int tsNumOfLogLines; +static pthread_once_t tscinit = PTHREAD_ONCE_INIT; void taosInitNote(int numOfNoteLines, int maxNotes, char* lable); -void deltaToUtcInitOnce(); void tscCheckDiskUsage(void *para, void *unused) { taosGetDisk(); @@ -60,7 +55,6 @@ int32_t tscInitRpc(const char *user, const char *secret) { char secretEncrypt[32] = {0}; taosEncryptPass((uint8_t *)secret, strlen(secret), secretEncrypt); - pthread_mutex_lock(&tscMutex); if (pVnodeConn == NULL) { memset(&rpcInit, 0, sizeof(rpcInit)); rpcInit.localIp = tsLocalIp; @@ -78,7 +72,6 @@ int32_t tscInitRpc(const char *user, const char *secret) { pVnodeConn = rpcOpen(&rpcInit); if (pVnodeConn == NULL) { tscError("failed to init connection to vnode"); - pthread_mutex_unlock(&tscMutex); return -1; } } @@ -100,12 +93,10 @@ int32_t tscInitRpc(const char *user, const char *secret) { pTscMgmtConn = rpcOpen(&rpcInit); if (pTscMgmtConn == NULL) { tscError("failed to init connection to mgmt"); - pthread_mutex_unlock(&tscMutex); return -1; } } - pthread_mutex_unlock(&tscMutex); return 0; } @@ -113,7 +104,7 @@ void taos_init_imp() { char temp[128]; struct stat dirstat; - pthread_mutex_init(&tscMutex, NULL); + errno = TSDB_CODE_SUCCESS; srand(taosGetTimestampSec()); deltaToUtcInitOnce(); diff --git a/src/client/src/tscUtil.c b/src/client/src/tscUtil.c index ec6881db3f..0b60c1d55c 100644 --- a/src/client/src/tscUtil.c +++ b/src/client/src/tscUtil.c @@ -394,6 +394,10 @@ void tscDestroyResPointerInfo(SSqlRes* pRes) { } void tscFreeSqlCmdData(SSqlCmd* pCmd) { + pCmd->command = 0; + pCmd->numOfCols = 0; + pCmd->count = 0; + pCmd->pDataBlocks = tscDestroyBlockArrayList(pCmd->pDataBlocks); tscFreeSubqueryInfo(pCmd); } @@ -454,9 +458,7 @@ void tscFreeSqlObjPartial(SSqlObj* pSql) { cmd == TSDB_SQL_METRIC_JOIN_RETRIEVE) { tscRemoveFromSqlList(pSql); } - - pCmd->command = 0; - + // pSql->sqlstr will be used by tscBuildQueryStreamDesc pthread_mutex_lock(&pObj->mutex); tfree(pSql->sqlstr); @@ -464,12 +466,17 @@ void tscFreeSqlObjPartial(SSqlObj* pSql) { tscFreeSqlResult(pSql); tfree(pSql->pSubs); - pSql->numOfSubs = 0; + + taosHashCleanup(pSql->pTableHashList); pSql->freed = 0; + pSql->numOfSubs = 0; + pSql->pTableHashList = NULL; + pSql->asyncTblPos = NULL; + tscFreeSqlCmdData(pCmd); - tscTrace("%p free sqlObj partial completed", pSql); + tscTrace("%p partially free sqlObj completed", pSql); } void tscFreeSqlObj(SSqlObj* pSql) { @@ -487,8 +494,6 @@ void tscFreeSqlObj(SSqlObj* pSql) { tfree(pCmd->payload); pCmd->allocSize = 0; - - tsem_destroy(&pSql->rspSem); free(pSql); } @@ -820,7 +825,9 @@ void tscCloseTscObj(STscObj* pObj) { taosTmrStopA(&(pObj->pTimer)); tscFreeSqlObj(pSql); + sem_destroy(&pSql->rspSem); pthread_mutex_destroy(&pObj->mutex); + tscTrace("%p DB connection is closed", pObj); tfree(pObj); } @@ -842,10 +849,9 @@ int tscAllocPayload(SSqlCmd* pCmd, int size) { if (pCmd->payload == NULL) { assert(pCmd->allocSize == 0); - pCmd->payload = (char*)malloc(size); + pCmd->payload = (char*)calloc(1, size); if (pCmd->payload == NULL) return TSDB_CODE_CLI_OUT_OF_MEMORY; pCmd->allocSize = size; - memset(pCmd->payload, 0, pCmd->allocSize); } else { if (pCmd->allocSize < size) { char* b = realloc(pCmd->payload, size); @@ -853,6 +859,8 @@ int tscAllocPayload(SSqlCmd* pCmd, int size) { pCmd->payload = b; pCmd->allocSize = size; } + + memset(pCmd->payload, 0, pCmd->payloadLen); } //memset(pCmd->payload, 0, pCmd->allocSize); @@ -1105,7 +1113,7 @@ void tscClearFieldInfo(SFieldInfo* pFieldInfo) { for(int32_t i = 0; i < pFieldInfo->numOfOutputCols; ++i) { if (pFieldInfo->pExpr[i] != NULL) { - tSQLBinaryExprDestroy(&pFieldInfo->pExpr[i]->binExprInfo.pBinExpr, NULL); + tExprTreeDestroy(&pFieldInfo->pExpr[i]->binExprInfo.pBinExpr, NULL); tfree(pFieldInfo->pExpr[i]->binExprInfo.pReqColumns); tfree(pFieldInfo->pExpr[i]); } @@ -1742,7 +1750,7 @@ bool tscShouldFreeAsyncSqlObj(SSqlObj* pSql) { } STscObj* pTscObj = pSql->pTscObj; - if (pSql->pStream != NULL || pTscObj->pHb == pSql) { + if (pSql->pStream != NULL || pTscObj->pHb == pSql || pTscObj->pSql == pSql) { return false; } @@ -1898,7 +1906,6 @@ void tscFreeSubqueryInfo(SSqlCmd* pCmd) { for (int32_t i = 0; i < pCmd->numOfClause; ++i) { char* addr = (char*)pCmd - offsetof(SSqlObj, cmd); - SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, i); doClearSubqueryInfo(pQueryInfo); @@ -1929,7 +1936,6 @@ STableMetaInfo* tscAddMeterMetaInfo(SQueryInfo* pQueryInfo, const char* name, ST } pTableMetaInfo->pTableMeta = pTableMeta; -// pTableMetaInfo->pMetricMeta = pMetricMeta; pTableMetaInfo->numOfTags = numOfTags; if (tags != NULL) { @@ -1963,7 +1969,7 @@ void doRemoveMeterMetaInfo(SQueryInfo* pQueryInfo, int32_t index, bool removeFro } void tscRemoveAllMeterMetaInfo(SQueryInfo* pQueryInfo, const char* address, bool removeFromCache) { - tscTrace("%p deref the metric/meter meta in cache, numOfTables:%d", address, pQueryInfo->numOfTables); + tscTrace("%p deref the table meta in cache, numOfTables:%d", address, pQueryInfo->numOfTables); int32_t index = pQueryInfo->numOfTables; while (index >= 0) { diff --git a/src/dnode/src/dnodeRead.c b/src/dnode/src/dnodeRead.c index 827c2b004f..530fc1a776 100644 --- a/src/dnode/src/dnodeRead.c +++ b/src/dnode/src/dnodeRead.c @@ -289,6 +289,7 @@ static void dnodeProcessRetrieveMsg(void *pVnode, SReadMsg *pMsg) { dnodeContinueExecuteQuery(pVnode, pQInfo, pMsg); } else { // no further execution invoked, release the ref to vnode dnodeProcessReadResult(pVnode, pMsg); + dnodeReleaseVnode(pVnode); } } diff --git a/src/inc/mnode.h b/src/inc/mnode.h index adb1f27885..2fbceb06df 100644 --- a/src/inc/mnode.h +++ b/src/inc/mnode.h @@ -59,6 +59,7 @@ typedef struct { char mnodeName[TSDB_DNODE_NAME_LEN + 1]; int8_t reserved[15]; int8_t updateEnd[1]; + int32_t refCount; int syncFd; void *hbTimer; void *pSync; @@ -84,6 +85,7 @@ typedef struct { char dnodeName[TSDB_DNODE_NAME_LEN + 1]; int8_t reserved[15]; int8_t updateEnd[1]; + int32_t refCount; SVnodeLoad vload[TSDB_MAX_VNODES]; int32_t status; uint32_t lastReboot; // time stamp for last reboot @@ -102,9 +104,8 @@ typedef struct { } SVnodeGid; typedef struct { - char tableId[TSDB_TABLE_ID_LEN]; + char tableId[TSDB_TABLE_ID_LEN + 1]; int8_t type; - int8_t dirty; } STableInfo; typedef struct SSuperTableObj { @@ -116,6 +117,7 @@ typedef struct SSuperTableObj { int32_t numOfTags; int8_t reserved[15]; int8_t updateEnd[1]; + int32_t refCount; int32_t numOfTables; int16_t nextColId; SSchema * schema; @@ -134,6 +136,7 @@ typedef struct { int8_t reserved[1]; int8_t updateEnd[1]; int16_t nextColId; //used by normal table + int32_t refCount; char* sql; //used by normal table SSchema* schema; //used by normal table SSuperTableObj *superTable; @@ -150,6 +153,7 @@ typedef struct _vg_obj { int8_t lbStatus; int8_t reserved[14]; int8_t updateEnd[1]; + int32_t refCount; struct _vg_obj *prev, *next; struct _db_obj *pDb; int32_t numOfTables; @@ -164,7 +168,7 @@ typedef struct _db_obj { SDbCfg cfg; int8_t reserved[15]; int8_t updateEnd[1]; - struct _db_obj *prev, *next; + int32_t refCount; int32_t numOfVgroups; int32_t numOfTables; int32_t numOfSuperTables; @@ -182,7 +186,7 @@ typedef struct _user_obj { int8_t writeAuth; int8_t reserved[13]; int8_t updateEnd[1]; - struct _user_obj *prev, *next; + int32_t refCount; struct _acctObj * pAcct; SQqueryList * pQList; // query list SStreamList * pSList; // stream list @@ -215,9 +219,8 @@ typedef struct _acctObj { int8_t dirty; int8_t reserved[14]; int8_t updateEnd[1]; + int32_t refCount; SAcctInfo acctInfo; - SDbObj * pHead; - SUserObj * pUser; pthread_mutex_t mutex; } SAcctObj; @@ -247,8 +250,12 @@ typedef struct { void *ahandle; void *thandle; void *pCont; - SDbObj *pDb; + SAcctObj *pAcct; + SDnodeObj*pDnode; SUserObj *pUser; + SDbObj *pDb; + SVgObj *pVgroup; + STableInfo *pTable; } SQueuedMsg; int32_t mgmtInitSystem(); diff --git a/src/mnode/CMakeLists.txt b/src/mnode/CMakeLists.txt index 3d8e712edd..b830695f52 100644 --- a/src/mnode/CMakeLists.txt +++ b/src/mnode/CMakeLists.txt @@ -14,6 +14,4 @@ IF ((TD_LINUX_64) OR (TD_LINUX_32 AND TD_ARM)) ADD_LIBRARY(mnode ${SRC}) TARGET_LINK_LIBRARIES(mnode trpc tutil pthread) -ENDIF () - - +ENDIF () \ No newline at end of file diff --git a/src/mnode/inc/mgmtAcct.h b/src/mnode/inc/mgmtAcct.h index 967aeb1b3f..1f8dc5c74a 100644 --- a/src/mnode/inc/mgmtAcct.h +++ b/src/mnode/inc/mgmtAcct.h @@ -30,12 +30,14 @@ typedef enum { int32_t acctInit(); void acctCleanUp(); SAcctObj *acctGetAcct(char *acctName); +void acctIncRef(SAcctObj *pAcct); +void acctDecRef(SAcctObj *pAcct); int32_t acctCheck(SAcctObj *pAcct, EAcctGrantType type); -int32_t acctAddDb(SAcctObj *pAcct, SDbObj *pDb); -int32_t acctRemoveDb(SAcctObj *pAcct, SDbObj *pDb); -int32_t acctAddUser(SAcctObj *pAcct, SUserObj *pUser); -int32_t acctRemoveUser(SAcctObj *pAcct, SUserObj *pUser); +void acctAddDb(SAcctObj *pAcct, SDbObj *pDb); +void acctRemoveDb(SAcctObj *pAcct, SDbObj *pDb); +void acctAddUser(SAcctObj *pAcct, SUserObj *pUser); +void acctRemoveUser(SAcctObj *pAcct, SUserObj *pUser); #ifdef __cplusplus } diff --git a/src/mnode/inc/mgmtChildTable.h b/src/mnode/inc/mgmtChildTable.h deleted file mode 100644 index 3f6b1d8b85..0000000000 --- a/src/mnode/inc/mgmtChildTable.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (c) 2019 TAOS Data, Inc. - * - * 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. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -#ifndef TBASE_MNODE_CHILD_TABLE_H -#define TBASE_MNODE_CHILD_TABLE_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include -#include -#include "taosdef.h" -#include "mnode.h" - -int32_t mgmtInitChildTables(); -void mgmtCleanUpChildTables(); -void * mgmtGetChildTable(char *tableId); - -void mgmtCreateChildTable(SQueuedMsg *pMsg); -void mgmtDropChildTable(SQueuedMsg *pMsg, SChildTableObj *pTable); -void mgmtGetChildTableMeta(SQueuedMsg *pMsg, SChildTableObj *pTable); -void mgmtAlterChildTable(SQueuedMsg *pMsg, SChildTableObj *pTable); -void mgmtDropAllChildTables(SDbObj *pDropDb); -void mgmtDropAllChildTablesInStable(SSuperTableObj *pStable); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/mnode/inc/mgmtDb.h b/src/mnode/inc/mgmtDb.h index decf25a5c1..fb6b8f8b6f 100644 --- a/src/mnode/inc/mgmtDb.h +++ b/src/mnode/inc/mgmtDb.h @@ -27,6 +27,8 @@ int32_t mgmtInitDbs(); void mgmtCleanUpDbs(); SDbObj *mgmtGetDb(char *db); SDbObj *mgmtGetDbByTableId(char *db); +void mgmtIncDbRef(SDbObj *pDb); +void mgmtDecDbRef(SDbObj *pDb); bool mgmtCheckIsMonitorDB(char *db, char *monitordb); void mgmtDropAllDbs(SAcctObj *pAcct); diff --git a/src/mnode/inc/mgmtDnode.h b/src/mnode/inc/mgmtDnode.h index 30b121c54b..f262cd3c5e 100644 --- a/src/mnode/inc/mgmtDnode.h +++ b/src/mnode/inc/mgmtDnode.h @@ -25,6 +25,8 @@ int32_t mgmtInitDnodes(); void mgmtCleanUpDnodes(); int32_t mgmtGetDnodesNum(); void * mgmtGetNextDnode(void *pNode, SDnodeObj **pDnode); +void mgmtIncDnodeRef(SDnodeObj *pDnode); +void mgmtDecDnodeRef(SDnodeObj *pDnode); SDnodeObj* mgmtGetDnode(int32_t dnodeId); SDnodeObj* mgmtGetDnodeByIp(uint32_t ip); diff --git a/src/mnode/inc/mgmtProfile.h b/src/mnode/inc/mgmtProfile.h index a40f572f8b..b05877f32c 100644 --- a/src/mnode/inc/mgmtProfile.h +++ b/src/mnode/inc/mgmtProfile.h @@ -28,6 +28,8 @@ bool mgmtCheckQhandle(uint64_t qhandle); void mgmtSaveQhandle(void *qhandle); void mgmtFreeQhandle(void *qhandle); +void * mgmtMallocQueuedMsg(SRpcMsg *rpcMsg); +void * mgmtCloneQueuedMsg(SQueuedMsg *pSrcMsg); void mgmtFreeQueuedMsg(SQueuedMsg *pMsg); #ifdef __cplusplus diff --git a/src/mnode/inc/mgmtSdb.h b/src/mnode/inc/mgmtSdb.h index a598a21173..ecf6887b42 100644 --- a/src/mnode/inc/mgmtSdb.h +++ b/src/mnode/inc/mgmtSdb.h @@ -44,6 +44,7 @@ typedef struct { char *tableName; int32_t hashSessions; int32_t maxRowSize; + int32_t refCountPos; ESdbKeyType keyType; int32_t (*insertFp)(SSdbOperDesc *pOper); int32_t (*deleteFp)(SSdbOperDesc *pOper); @@ -62,6 +63,8 @@ int32_t sdbUpdateRow(SSdbOperDesc *pOper); void *sdbGetRow(void *handle, void *key); void *sdbFetchRow(void *handle, void *pNode, void **ppRow); +void sdbIncRef(void *thandle, void *pRow); +void sdbDecRef(void *thandle, void *pRow); int64_t sdbGetNumOfRows(void *handle); int64_t sdbGetId(void *handle); uint64_t sdbGetVersion(); diff --git a/src/mnode/inc/mgmtSuperTable.h b/src/mnode/inc/mgmtSuperTable.h deleted file mode 100644 index 73809148de..0000000000 --- a/src/mnode/inc/mgmtSuperTable.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (c) 2019 TAOS Data, Inc. - * - * 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. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -#ifndef TBASE_MNODE_SUPER_TABLE_H -#define TBASE_MNODE_SUPER_TABLE_H - -#ifdef __cplusplus -extern "C" { -#endif - -#include -#include -#include "taosdef.h" -#include "mnode.h" - -int32_t mgmtInitSuperTables(); -void mgmtCleanUpSuperTables(); -void * mgmtGetSuperTable(char *tableId); - -void mgmtCreateSuperTable(SQueuedMsg *pMsg); -void mgmtDropSuperTable(SQueuedMsg *pMsg, SSuperTableObj *pTable); -void mgmtGetSuperTableMeta(SQueuedMsg *pMsg, SSuperTableObj *pTable); -void mgmtAlterSuperTable(SQueuedMsg *pMsg, SSuperTableObj *pTable); -void mgmtDropAllSuperTables(SDbObj *pDropDb); -int32_t mgmtSetSchemaFromSuperTable(SSchema *pSchema, SSuperTableObj *pTable); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/mnode/inc/mgmtTable.h b/src/mnode/inc/mgmtTable.h index 66557b3362..ddbbfb4a70 100644 --- a/src/mnode/inc/mgmtTable.h +++ b/src/mnode/inc/mgmtTable.h @@ -28,7 +28,10 @@ extern "C" { int32_t mgmtInitTables(); void mgmtCleanUpTables(); STableInfo* mgmtGetTable(char* tableId); -void mgmtExtractTableName(char* tableId, char* tableName); +void mgmtIncTableRef(void *pTable); +void mgmtDecTableRef(void *pTable); +void mgmtDropAllChildTables(SDbObj *pDropDb); +void mgmtDropAllSuperTables(SDbObj *pDropDb); #ifdef __cplusplus } diff --git a/src/mnode/inc/mgmtUser.h b/src/mnode/inc/mgmtUser.h index ff3bfa3be6..f5c9b96f03 100644 --- a/src/mnode/inc/mgmtUser.h +++ b/src/mnode/inc/mgmtUser.h @@ -24,6 +24,8 @@ extern "C" { int32_t mgmtInitUsers(); void mgmtCleanUpUsers(); SUserObj *mgmtGetUser(char *name); +void mgmtIncUserRef(SUserObj *pUser); +void mgmtDecUserRef(SUserObj *pUser); SUserObj *mgmtGetUserFromConn(void *pConn, bool *usePublicIp); int32_t mgmtCreateUser(SAcctObj *pAcct, char *name, char *pass); void mgmtDropAllUsers(SAcctObj *pAcct); diff --git a/src/mnode/inc/mgmtVgroup.h b/src/mnode/inc/mgmtVgroup.h index de0648da44..d0b1e0de97 100644 --- a/src/mnode/inc/mgmtVgroup.h +++ b/src/mnode/inc/mgmtVgroup.h @@ -27,9 +27,11 @@ extern "C" { int32_t mgmtInitVgroups(); void mgmtCleanUpVgroups(); SVgObj *mgmtGetVgroup(int32_t vgId); +void mgmtIncVgroupRef(SVgObj *pVgroup); +void mgmtDecVgroupRef(SVgObj *pVgroup); void mgmtDropAllVgroups(SDbObj *pDropDb); -void mgmtCreateVgroup(SQueuedMsg *pMsg); +void mgmtCreateVgroup(SQueuedMsg *pMsg, SDbObj *pDb); void mgmtDropVgroup(SVgObj *pVgroup, void *ahandle); void mgmtAlterVgroup(SVgObj *pVgroup, void *ahandle); SVgObj *mgmtGetAvailableVgroup(SDbObj *pDb); diff --git a/src/mnode/src/mgmtAcct.c b/src/mnode/src/mgmtAcct.c index d3d2ec697d..22690c4a44 100644 --- a/src/mnode/src/mgmtAcct.c +++ b/src/mnode/src/mgmtAcct.c @@ -18,6 +18,8 @@ #include "taoserror.h" #include "mnode.h" #include "mgmtAcct.h" +#include "mgmtDb.h" +#include "mgmtUser.h" #ifndef _ACCOUNT static SAcctObj tsAcctObj = {0}; @@ -30,79 +32,31 @@ int32_t acctInit() { void acctCleanUp() {} SAcctObj *acctGetAcct(char *acctName) { return &tsAcctObj; } +void acctIncRef(SAcctObj *pAcct) {} +void acctDecRef(SAcctObj *pAcct) {} int32_t acctCheck(SAcctObj *pAcct, EAcctGrantType type) { return TSDB_CODE_SUCCESS; } #endif -int32_t acctAddDb(SAcctObj *pAcct, SDbObj *pDb) { - pthread_mutex_lock(&pAcct->mutex); - pDb->next = pAcct->pHead; - pDb->prev = NULL; +void acctAddDb(SAcctObj *pAcct, SDbObj *pDb) { + atomic_add_fetch_32(&pAcct->acctInfo.numOfDbs, 1); pDb->pAcct = pAcct; - - if (pAcct->pHead) { - pAcct->pHead->prev = pDb; - } - - pAcct->pHead = pDb; - pAcct->acctInfo.numOfDbs++; - pthread_mutex_unlock(&pAcct->mutex); - - return 0; + acctIncRef(pAcct); } -int32_t acctRemoveDb(SAcctObj *pAcct, SDbObj *pDb) { - pthread_mutex_lock(&pAcct->mutex); - if (pDb->prev) { - pDb->prev->next = pDb->next; - } - - if (pDb->next) { - pDb->next->prev = pDb->prev; - } - - if (pDb->prev == NULL) { - pAcct->pHead = pDb->next; - } - - pAcct->acctInfo.numOfDbs--; - pthread_mutex_unlock(&pAcct->mutex); - - return 0; +void acctRemoveDb(SAcctObj *pAcct, SDbObj *pDb) { + atomic_sub_fetch_32(&pAcct->acctInfo.numOfDbs, 1); + pDb->pAcct = NULL; + acctIncRef(pAcct); } -int32_t acctAddUser(SAcctObj *pAcct, SUserObj *pUser) { - pthread_mutex_lock(&pAcct->mutex); - pUser->next = pAcct->pUser; - pUser->prev = NULL; - - if (pAcct->pUser) { - pAcct->pUser->prev = pUser; - } - - pAcct->pUser = pUser; - pAcct->acctInfo.numOfUsers++; +void acctAddUser(SAcctObj *pAcct, SUserObj *pUser) { + atomic_add_fetch_32(&pAcct->acctInfo.numOfUsers, 1); pUser->pAcct = pAcct; - pthread_mutex_unlock(&pAcct->mutex); - - return 0; + acctIncRef(pAcct); } -int32_t acctRemoveUser(SAcctObj *pAcct, SUserObj *pUser) { - pthread_mutex_lock(&pAcct->mutex); - if (pUser->prev) { - pUser->prev->next = pUser->next; - } - - if (pUser->next) { - pUser->next->prev = pUser->prev; - } - - if (pUser->prev == NULL) { - pAcct->pUser = pUser->next; - } - - pAcct->acctInfo.numOfUsers--; - pthread_mutex_unlock(&pAcct->mutex); - - return 0; +void acctRemoveUser(SAcctObj *pAcct, SUserObj *pUser) { + atomic_sub_fetch_32(&pAcct->acctInfo.numOfUsers, 1); + pUser->pAcct = NULL; + acctIncRef(pAcct); } \ No newline at end of file diff --git a/src/mnode/src/mgmtBalance.c b/src/mnode/src/mgmtBalance.c index 3b8a6abc86..3a7ae8dcde 100644 --- a/src/mnode/src/mgmtBalance.c +++ b/src/mnode/src/mgmtBalance.c @@ -29,6 +29,7 @@ int32_t mgmtAllocVnodes(SVgObj *pVgroup) { float vnodeUsage = 1.0; while (1) { + mgmtDecDnodeRef(pDnode); pNode = mgmtGetNextDnode(pNode, &pDnode); if (pDnode == NULL) break; if (pDnode->numOfTotalVnodes <= 0) continue; diff --git a/src/mnode/src/mgmtChildTable.c b/src/mnode/src/mgmtChildTable.c deleted file mode 100644 index 48abae3e9d..0000000000 --- a/src/mnode/src/mgmtChildTable.c +++ /dev/null @@ -1,1226 +0,0 @@ -/* - * Copyright (c) 2019 TAOS Data, Inc. - * - * 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. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -#define _DEFAULT_SOURCE -#include "os.h" -#include "taosmsg.h" -#include "tscompression.h" -#include "tskiplist.h" -#include "ttime.h" -#include "tstatus.h" -#include "tutil.h" -#include "qast.h" -#include "qextbuffer.h" -#include "taoserror.h" -#include "taosmsg.h" -#include "tscompression.h" -#include "tskiplist.h" -#include "tsqlfunction.h" -#include "tstatus.h" -#include "ttime.h" -#include "name.h" -#include "mnode.h" -#include "mgmtAcct.h" -#include "mgmtChildTable.h" -#include "mgmtDb.h" -#include "mgmtDClient.h" -#include "mgmtDnode.h" -#include "mgmtDServer.h" -#include "mgmtGrant.h" -#include "mgmtMnode.h" -#include "mgmtProfile.h" -#include "mgmtSdb.h" -#include "mgmtShell.h" -#include "mgmtSuperTable.h" -#include "mgmtTable.h" -#include "mgmtVgroup.h" -#include "mgmtUser.h" - -void *tsChildTableSdb; -static int32_t tsChildTableUpdateSize; -static void mgmtProcessMultiTableMetaMsg(SQueuedMsg *queueMsg); -static void mgmtProcessCreateTableRsp(SRpcMsg *rpcMsg); -static void mgmtProcessAlterTableRsp(SRpcMsg *rpcMsg); -static void mgmtProcessDropTableRsp(SRpcMsg *rpcMsg); -static void mgmtProcessTableCfgMsg(SRpcMsg *rpcMsg); -static int32_t mgmtGetShowTableMeta(STableMetaMsg *pMeta, SShowObj *pShow, void *pConn); -static int32_t mgmtRetrieveShowTables(SShowObj *pShow, char *data, int32_t rows, void *pConn); - -static void mgmtDestroyChildTable(SChildTableObj *pTable) { - tfree(pTable->schema); - tfree(pTable->sql); - tfree(pTable); -} - -static int32_t mgmtChildTableActionDestroy(SSdbOperDesc *pOper) { - mgmtDestroyChildTable(pOper->pObj); - return TSDB_CODE_SUCCESS; -} - -static int32_t mgmtChildTableActionInsert(SSdbOperDesc *pOper) { - SChildTableObj *pTable = pOper->pObj; - - SVgObj *pVgroup = mgmtGetVgroup(pTable->vgId); - if (pVgroup == NULL) { - mError("ctable:%s, not in vgroup:%d", pTable->info.tableId, pTable->vgId); - return TSDB_CODE_INVALID_VGROUP_ID; - } - - SDbObj *pDb = mgmtGetDb(pVgroup->dbName); - if (pDb == NULL) { - mError("ctable:%s, vgroup:%d not in db:%s", pTable->info.tableId, pVgroup->vgId, pVgroup->dbName); - return TSDB_CODE_INVALID_DB; - } - - SAcctObj *pAcct = acctGetAcct(pDb->cfg.acct); - if (pAcct == NULL) { - mError("ctable:%s, account:%s not exists", pTable->info.tableId, pDb->cfg.acct); - return TSDB_CODE_INVALID_ACCT; - } - - if (pTable->info.type == TSDB_CHILD_TABLE) { - pTable->superTable = mgmtGetSuperTable(pTable->superTableId); - pTable->superTable->numOfTables++; - grantAdd(TSDB_GRANT_TIMESERIES, pTable->superTable->numOfColumns - 1); - pAcct->acctInfo.numOfTimeSeries += (pTable->superTable->numOfColumns - 1); - } else { - grantAdd(TSDB_GRANT_TIMESERIES, pTable->numOfColumns - 1); - pAcct->acctInfo.numOfTimeSeries += (pTable->numOfColumns - 1); - } - mgmtAddTableIntoDb(pDb); - mgmtAddTableIntoVgroup(pVgroup, pTable); - - return TSDB_CODE_SUCCESS; -} - -static int32_t mgmtChildTableActionDelete(SSdbOperDesc *pOper) { - SChildTableObj *pTable = pOper->pObj; - if (pTable->vgId == 0) { - return TSDB_CODE_INVALID_VGROUP_ID; - } - - SVgObj *pVgroup = mgmtGetVgroup(pTable->vgId); - if (pVgroup == NULL) { - return TSDB_CODE_INVALID_VGROUP_ID; - } - - SDbObj *pDb = mgmtGetDb(pVgroup->dbName); - if (pDb == NULL) { - mError("ctable:%s, vgroup:%d not in DB:%s", pTable->info.tableId, pVgroup->vgId, pVgroup->dbName); - return TSDB_CODE_INVALID_DB; - } - - SAcctObj *pAcct = acctGetAcct(pDb->cfg.acct); - if (pAcct == NULL) { - mError("ctable:%s, account:%s not exists", pTable->info.tableId, pDb->cfg.acct); - return TSDB_CODE_INVALID_ACCT; - } - - if (pTable->info.type == TSDB_CHILD_TABLE) { - grantRestore(TSDB_GRANT_TIMESERIES, pTable->superTable->numOfColumns - 1); - pAcct->acctInfo.numOfTimeSeries -= (pTable->superTable->numOfColumns - 1); - pTable->superTable->numOfTables--; - } else { - grantRestore(TSDB_GRANT_TIMESERIES, pTable->numOfColumns - 1); - pAcct->acctInfo.numOfTimeSeries -= (pTable->numOfColumns - 1); - } - mgmtRemoveTableFromDb(pDb); - mgmtRemoveTableFromVgroup(pVgroup, pTable); - - return TSDB_CODE_SUCCESS; -} - -static int32_t mgmtChildTableActionUpdate(SSdbOperDesc *pOper) { - return TSDB_CODE_SUCCESS; -} - -static int32_t mgmtChildTableActionEncode(SSdbOperDesc *pOper) { - SChildTableObj *pTable = pOper->pObj; - assert(pTable != NULL && pOper->rowData != NULL); - - if (pTable->info.type == TSDB_CHILD_TABLE) { - memcpy(pOper->rowData, pTable, tsChildTableUpdateSize); - pOper->rowSize = tsChildTableUpdateSize; - } else { - int32_t schemaSize = pTable->numOfColumns * sizeof(SSchema); - if (pOper->maxRowSize < tsChildTableUpdateSize + schemaSize) { - return TSDB_CODE_INVALID_MSG_LEN; - } - memcpy(pOper->rowData, pTable, tsChildTableUpdateSize); - memcpy(pOper->rowData + tsChildTableUpdateSize, pTable->schema, schemaSize); - memcpy(pOper->rowData + tsChildTableUpdateSize + schemaSize, pTable->sql, pTable->sqlLen); - pOper->rowSize = tsChildTableUpdateSize + schemaSize + pTable->sqlLen; - } - - return TSDB_CODE_SUCCESS; -} - -static int32_t mgmtChildTableActionDecode(SSdbOperDesc *pOper) { - assert(pOper->rowData != NULL); - SChildTableObj *pTable = calloc(1, sizeof(SChildTableObj)); - if (pTable == NULL) { - return TSDB_CODE_SERV_OUT_OF_MEMORY; - } - - memcpy(pTable, pOper->rowData, tsChildTableUpdateSize); - - if (pTable->info.type != TSDB_CHILD_TABLE) { - int32_t schemaSize = pTable->numOfColumns * sizeof(SSchema); - pTable->schema = (SSchema *)malloc(schemaSize); - if (pTable->schema == NULL) { - mgmtDestroyChildTable(pTable); - return TSDB_CODE_SERV_OUT_OF_MEMORY; - } - memcpy(pTable->schema, pOper->rowData + tsChildTableUpdateSize, schemaSize); - - pTable->sql = (char *)malloc(pTable->sqlLen); - if (pTable->sql == NULL) { - mgmtDestroyChildTable(pTable); - return TSDB_CODE_SERV_OUT_OF_MEMORY; - } - memcpy(pTable->sql, pOper->rowData + tsChildTableUpdateSize + schemaSize, pTable->sqlLen); - } - - pOper->pObj = pTable; - return TSDB_CODE_SUCCESS; -} - -int32_t mgmtInitChildTables() { - void *pNode = NULL; - void *pLastNode = NULL; - SChildTableObj *pTable = NULL; - - SChildTableObj tObj; - tsChildTableUpdateSize = (int8_t *)tObj.updateEnd - (int8_t *)&tObj; - - SSdbTableDesc tableDesc = { - .tableName = "ctables", - .hashSessions = tsMaxTables, - .maxRowSize = sizeof(SChildTableObj) + sizeof(SSchema) * TSDB_MAX_COLUMNS, - .keyType = SDB_KEY_TYPE_STRING, - .insertFp = mgmtChildTableActionInsert, - .deleteFp = mgmtChildTableActionDelete, - .updateFp = mgmtChildTableActionUpdate, - .encodeFp = mgmtChildTableActionEncode, - .decodeFp = mgmtChildTableActionDecode, - .destroyFp = mgmtChildTableActionDestroy, - }; - - tsChildTableSdb = sdbOpenTable(&tableDesc); - if (tsChildTableSdb == NULL) { - mError("failed to init child table data"); - return -1; - } - - pNode = NULL; - while (1) { - pLastNode = pNode; - pNode = sdbFetchRow(tsChildTableSdb, pNode, (void **)&pTable); - if (pTable == NULL) { - break; - } - - SDbObj *pDb = mgmtGetDbByTableId(pTable->info.tableId); - if (pDb == NULL) { - mError("ctable:%s, failed to get db, discard it", pTable->info.tableId); - SSdbOperDesc desc = {0}; - desc.type = SDB_OPER_TYPE_LOCAL; - desc.pObj = pTable; - desc.table = tsChildTableSdb; - sdbDeleteRow(&desc); - pNode = pLastNode; - continue; - } - - SVgObj *pVgroup = mgmtGetVgroup(pTable->vgId); - if (pVgroup == NULL) { - mError("ctable:%s, failed to get vgroup:%d sid:%d, discard it", pTable->info.tableId, pTable->vgId, pTable->sid); - pTable->vgId = 0; - SSdbOperDesc desc = {0}; - desc.type = SDB_OPER_TYPE_LOCAL; - desc.pObj = pTable; - desc.table = tsChildTableSdb; - sdbDeleteRow(&desc); - pNode = pLastNode; - continue; - } - - if (strcmp(pVgroup->dbName, pDb->name) != 0) { - mError("ctable:%s, db:%s not match with vgroup:%d db:%s sid:%d, discard it", - pTable->info.tableId, pDb->name, pTable->vgId, pVgroup->dbName, pTable->sid); - pTable->vgId = 0; - SSdbOperDesc desc = {0}; - desc.type = SDB_OPER_TYPE_LOCAL; - desc.pObj = pTable; - desc.table = tsChildTableSdb; - sdbDeleteRow(&desc); - pNode = pLastNode; - continue; - } - - if (pVgroup->tableList == NULL) { - mError("ctable:%s, vgroup:%d tableList is null", pTable->info.tableId, pTable->vgId); - pTable->vgId = 0; - SSdbOperDesc desc = {0}; - desc.type = SDB_OPER_TYPE_LOCAL; - desc.pObj = pTable; - desc.table = tsChildTableSdb; - sdbDeleteRow(&desc); - pNode = pLastNode; - continue; - } - - if (pTable->info.type == TSDB_CHILD_TABLE) { - SSuperTableObj *pSuperTable = mgmtGetSuperTable(pTable->superTableId); - if (pSuperTable == NULL) { - mError("ctable:%s, stable:%s not exist", pTable->info.tableId, pTable->superTableId); - pTable->vgId = 0; - SSdbOperDesc desc = {0}; - desc.type = SDB_OPER_TYPE_LOCAL; - desc.pObj = pTable; - desc.table = tsChildTableSdb; - sdbDeleteRow(&desc); - pNode = pLastNode; - continue; - } - } - } - - mgmtAddShellMsgHandle(TSDB_MSG_TYPE_CM_TABLES_META, mgmtProcessMultiTableMetaMsg); - mgmtAddShellShowMetaHandle(TSDB_MGMT_TABLE_TABLE, mgmtGetShowTableMeta); - mgmtAddShellShowRetrieveHandle(TSDB_MGMT_TABLE_TABLE, mgmtRetrieveShowTables); - mgmtAddDClientRspHandle(TSDB_MSG_TYPE_MD_CREATE_TABLE_RSP, mgmtProcessCreateTableRsp); - mgmtAddDClientRspHandle(TSDB_MSG_TYPE_MD_DROP_TABLE_RSP, mgmtProcessDropTableRsp); - mgmtAddDClientRspHandle(TSDB_MSG_TYPE_MD_ALTER_TABLE_RSP, mgmtProcessAlterTableRsp); - mgmtAddDServerMsgHandle(TSDB_MSG_TYPE_DM_CONFIG_TABLE, mgmtProcessTableCfgMsg); - - mTrace("child table is initialized"); - return 0; -} - -void mgmtCleanUpChildTables() { - sdbCloseTable(tsChildTableSdb); -} - -static void *mgmtBuildCreateChildTableMsg(SCMCreateTableMsg *pMsg, SChildTableObj *pTable) { - char * pTagData = NULL; - int32_t tagDataLen = 0; - int32_t totalCols = 0; - int32_t contLen = 0; - if (pTable->info.type == TSDB_CHILD_TABLE && pMsg != NULL) { - pTagData = pMsg->schema + TSDB_TABLE_ID_LEN + 1; - tagDataLen = htonl(pMsg->contLen) - sizeof(SCMCreateTableMsg) - TSDB_TABLE_ID_LEN - 1; - totalCols = pTable->superTable->numOfColumns + pTable->superTable->numOfTags; - contLen = sizeof(SMDCreateTableMsg) + totalCols * sizeof(SSchema) + tagDataLen + pTable->sqlLen; - } else { - totalCols = pTable->numOfColumns; - contLen = sizeof(SMDCreateTableMsg) + totalCols * sizeof(SSchema) + pTable->sqlLen; - } - - SMDCreateTableMsg *pCreate = rpcMallocCont(contLen); - if (pCreate == NULL) { - terrno = TSDB_CODE_SERV_OUT_OF_MEMORY; - return NULL; - } - - memcpy(pCreate->tableId, pTable->info.tableId, TSDB_TABLE_ID_LEN + 1); - pCreate->contLen = htonl(contLen); - pCreate->vgId = htonl(pTable->vgId); - pCreate->tableType = pTable->info.type; - pCreate->createdTime = htobe64(pTable->createdTime); - pCreate->sid = htonl(pTable->sid); - pCreate->sqlDataLen = htonl(pTable->sqlLen); - pCreate->uid = htobe64(pTable->uid); - - if (pTable->info.type == TSDB_CHILD_TABLE) { - memcpy(pCreate->superTableId, pTable->superTable->info.tableId, TSDB_TABLE_ID_LEN + 1); - pCreate->numOfColumns = htons(pTable->superTable->numOfColumns); - pCreate->numOfTags = htons(pTable->superTable->numOfTags); - pCreate->sversion = htonl(pTable->superTable->sversion); - pCreate->tagDataLen = htonl(tagDataLen); - pCreate->superTableUid = htobe64(pTable->superTable->uid); - } else { - pCreate->numOfColumns = htons(pTable->numOfColumns); - pCreate->numOfTags = 0; - pCreate->sversion = htonl(pTable->sversion); - pCreate->tagDataLen = 0; - pCreate->superTableUid = 0; - } - - SSchema *pSchema = (SSchema *) pCreate->data; - if (pTable->info.type == TSDB_CHILD_TABLE) { - memcpy(pSchema, pTable->superTable->schema, totalCols * sizeof(SSchema)); - } else { - memcpy(pSchema, pTable->schema, totalCols * sizeof(SSchema)); - } - for (int32_t col = 0; col < totalCols; ++col) { - pSchema->bytes = htons(pSchema->bytes); - pSchema->colId = htons(pSchema->colId); - pSchema++; - } - - if (pTable->info.type == TSDB_CHILD_TABLE && pMsg != NULL) { - memcpy(pCreate->data + totalCols * sizeof(SSchema), pTagData, tagDataLen); - memcpy(pCreate->data + totalCols * sizeof(SSchema) + tagDataLen, pTable->sql, pTable->sqlLen); - } - - return pCreate; -} - -static SChildTableObj* mgmtDoCreateChildTable(SCMCreateTableMsg *pCreate, SVgObj *pVgroup, int32_t tid) { - SChildTableObj *pTable = (SChildTableObj *) calloc(1, sizeof(SChildTableObj)); - if (pTable == NULL) { - mError("ctable:%s, failed to alloc memory", pCreate->tableId); - terrno = TSDB_CODE_SERV_OUT_OF_MEMORY; - return NULL; - } - - if (pCreate->numOfColumns == 0) { - pTable->info.type = TSDB_CHILD_TABLE; - } else { - pTable->info.type = TSDB_NORMAL_TABLE; - } - - strcpy(pTable->info.tableId, pCreate->tableId); - pTable->createdTime = taosGetTimestampMs(); - pTable->sid = tid; - pTable->vgId = pVgroup->vgId; - - if (pTable->info.type == TSDB_CHILD_TABLE) { - char *pTagData = (char *) pCreate->schema; // it is a tag key - SSuperTableObj *pSuperTable = mgmtGetSuperTable(pTagData); - if (pSuperTable == NULL) { - mError("ctable:%s, corresponding super table does not exist", pCreate->tableId); - free(pTable); - terrno = TSDB_CODE_INVALID_TABLE; - return NULL; - } - - strcpy(pTable->superTableId, pSuperTable->info.tableId); - pTable->uid = (((uint64_t) pTable->vgId) << 40) + ((((uint64_t) pTable->sid) & ((1ul << 24) - 1ul)) << 16) + - (sdbGetVersion() & ((1ul << 16) - 1ul)); - pTable->superTable = pSuperTable; - } else { - pTable->uid = (((uint64_t) pTable->createdTime) << 16) + (sdbGetVersion() & ((1ul << 16) - 1ul)); - pTable->sversion = 0; - pTable->numOfColumns = htons(pCreate->numOfColumns); - pTable->sqlLen = htons(pCreate->sqlLen); - - int32_t numOfCols = pTable->numOfColumns; - int32_t schemaSize = numOfCols * sizeof(SSchema); - pTable->schema = (SSchema *) calloc(1, schemaSize); - if (pTable->schema == NULL) { - free(pTable); - terrno = TSDB_CODE_SERV_OUT_OF_MEMORY; - return NULL; - } - memcpy(pTable->schema, pCreate->schema, numOfCols * sizeof(SSchema)); - - pTable->nextColId = 0; - for (int32_t col = 0; col < numOfCols; col++) { - SSchema *tschema = pTable->schema; - tschema[col].colId = pTable->nextColId++; - tschema[col].bytes = htons(tschema[col].bytes); - } - - if (pTable->sqlLen != 0) { - pTable->info.type = TSDB_STREAM_TABLE; - pTable->sql = calloc(1, pTable->sqlLen); - if (pTable->sql == NULL) { - free(pTable); - terrno = TSDB_CODE_SERV_OUT_OF_MEMORY; - return NULL; - } - memcpy(pTable->sql, (char *) (pCreate->schema) + numOfCols * sizeof(SSchema), pTable->sqlLen); - pTable->sql[pTable->sqlLen - 1] = 0; - mTrace("table:%s, stream sql len:%d sql:%s", pTable->info.tableId, pTable->sqlLen, pTable->sql); - } - } - - SSdbOperDesc desc = {0}; - desc.type = SDB_OPER_TYPE_GLOBAL; - desc.pObj = pTable; - desc.table = tsChildTableSdb; - - if (sdbInsertRow(&desc) != TSDB_CODE_SUCCESS) { - free(pTable); - mError("ctable:%s, update sdb error", pCreate->tableId); - terrno = TSDB_CODE_SDB_ERROR; - return NULL; - } - - mTrace("ctable:%s, create ctable in vgroup, uid:%" PRIu64 , pTable->info.tableId, pTable->uid); - return pTable; -} - -void mgmtCreateChildTable(SQueuedMsg *pMsg) { - SCMCreateTableMsg *pCreate = pMsg->pCont; - - int32_t code = grantCheck(TSDB_GRANT_TIMESERIES); - if (code != TSDB_CODE_SUCCESS) { - mError("table:%s, failed to create, grant not", pCreate->tableId); - mgmtSendSimpleResp(pMsg->thandle, code); - return; - } - - SQueuedMsg *newMsg = malloc(sizeof(SQueuedMsg)); - memcpy(newMsg, pMsg, sizeof(SQueuedMsg)); - pMsg->pCont = NULL; - - SVgObj *pVgroup = mgmtGetAvailableVgroup(pMsg->pDb); - if (pVgroup == NULL) { - mTrace("table:%s, start to create a new vgroup", pCreate->tableId); - mgmtCreateVgroup(newMsg); - return; - } - - int32_t sid = taosAllocateId(pVgroup->idPool); - if (sid < 0) { - mTrace("tables:%s, no enough sid in vgroup:%d", pVgroup->vgId); - mgmtCreateVgroup(newMsg); - return; - } - - SChildTableObj *pTable = mgmtDoCreateChildTable(pCreate, pVgroup, sid); - if (pTable == NULL) { - mgmtSendSimpleResp(pMsg->thandle, terrno); - mgmtFreeQueuedMsg(newMsg); - return; - } - - SMDCreateTableMsg *pMDCreate = mgmtBuildCreateChildTableMsg(pCreate, (SChildTableObj *) pTable); - if (pMDCreate == NULL) { - mgmtSendSimpleResp(pMsg->thandle, terrno); - mgmtFreeQueuedMsg(newMsg); - return; - } - - SRpcIpSet ipSet = mgmtGetIpSetFromVgroup(pVgroup); - SRpcMsg rpcMsg = { - .handle = newMsg, - .pCont = pMDCreate, - .contLen = htonl(pMDCreate->contLen), - .code = 0, - .msgType = TSDB_MSG_TYPE_MD_CREATE_TABLE - }; - - newMsg->ahandle = pTable; - mgmtSendMsgToDnode(&ipSet, &rpcMsg); -} - -void mgmtDropChildTable(SQueuedMsg *pMsg, SChildTableObj *pTable) { - SVgObj *pVgroup = mgmtGetVgroup(pTable->vgId); - if (pVgroup == NULL) { - mError("ctable:%s, failed to drop child table, vgroup not exist", pTable->info.tableId); - mgmtSendSimpleResp(pMsg->thandle, TSDB_CODE_OTHERS); - return; - } - - SMDDropTableMsg *pDrop = rpcMallocCont(sizeof(SMDDropTableMsg)); - if (pDrop == NULL) { - mError("ctable:%s, failed to drop child table, no enough memory", pTable->info.tableId); - mgmtSendSimpleResp(pMsg->thandle, TSDB_CODE_SERV_OUT_OF_MEMORY); - return; - } - - strcpy(pDrop->tableId, pTable->info.tableId); - pDrop->vgId = htonl(pTable->vgId); - pDrop->contLen = htonl(sizeof(SMDDropTableMsg)); - pDrop->sid = htonl(pTable->sid); - pDrop->uid = htobe64(pTable->uid); - - SRpcIpSet ipSet = mgmtGetIpSetFromVgroup(pVgroup); - - mTrace("ctable:%s, send drop table msg", pDrop->tableId); - SRpcMsg rpcMsg = { - .handle = pMsg, - .pCont = pDrop, - .contLen = sizeof(SMDDropTableMsg), - .code = 0, - .msgType = TSDB_MSG_TYPE_MD_DROP_TABLE - }; - - pMsg->ahandle = pTable; - mgmtSendMsgToDnode(&ipSet, &rpcMsg); -} - -void* mgmtGetChildTable(char *tableId) { - return sdbGetRow(tsChildTableSdb, tableId); -} - -int32_t mgmtModifyChildTableTagValueByName(SChildTableObj *pTable, char *tagName, char *nContent) { -// TODO: send message to dnode -// int32_t col = mgmtFindSuperTableTagIndex(pTable->superTable, tagName); -// if (col < 0 || col > pTable->superTable->numOfTags) { -// return TSDB_CODE_APP_ERROR; -// } -// -// //TODO send msg to dnode -// mTrace("Succeed to modify tag column %d of table %s", col, pTable->info.tableId); -// return TSDB_CODE_SUCCESS; - -// int32_t rowSize = 0; -// SSchema *schema = (SSchema *)(pSuperTable->schema + (pSuperTable->numOfColumns + col) * sizeof(SSchema)); -// -// if (col == 0) { -// pTable->isDirty = 1; -// removeMeterFromMetricIndex(pSuperTable, pTable); -// } -// memcpy(pTable->pTagData + mgmtGetTagsLength(pMetric, col) + TSDB_TABLE_ID_LEN, nContent, schema->bytes); -// if (col == 0) { -// addMeterIntoMetricIndex(pMetric, pTable); -// } -// -// // Encode the string -// int32_t size = sizeof(STabObj) + TSDB_MAX_BYTES_PER_ROW + 1; -// char *msg = (char *)malloc(size); -// if (msg == NULL) { -// mError("failed to allocate message memory while modify tag value"); -// return TSDB_CODE_APP_ERROR; -// } -// memset(msg, 0, size); -// -// mgmtMeterActionEncode(pTable, msg, size, &rowSize); -// -// int32_t ret = sdbUpdateRow(tsChildTableSdb, msg, rowSize, 1); // Need callback function -// tfree(msg); -// -// if (pTable->isDirty) pTable->isDirty = 0; -// -// if (ret < 0) { -// mError("Failed to modify tag column %d of table %s", col, pTable->info.tableId); -// return TSDB_CODE_APP_ERROR; -// } -// -// mTrace("Succeed to modify tag column %d of table %s", col, pTable->info.tableId); -// return TSDB_CODE_SUCCESS; - return 0; -} - - -static int32_t mgmtFindNormalTableColumnIndex(SChildTableObj *pTable, char *colName) { - SSchema *schema = (SSchema *) pTable->schema; - for (int32_t i = 0; i < pTable->numOfColumns; i++) { - if (strcasecmp(schema[i].name, colName) == 0) { - return i; - } - } - - return -1; -} - -static int32_t mgmtAddNormalTableColumn(SChildTableObj *pTable, SSchema schema[], int32_t ncols) { - if (ncols <= 0) { - return TSDB_CODE_APP_ERROR; - } - - for (int32_t i = 0; i < ncols; i++) { - if (mgmtFindNormalTableColumnIndex(pTable, schema[i].name) > 0) { - return TSDB_CODE_APP_ERROR; - } - } - - SDbObj *pDb = mgmtGetDbByTableId(pTable->info.tableId); - if (pDb == NULL) { - mError("table: %s not belongs to any database", pTable->info.tableId); - return TSDB_CODE_APP_ERROR; - } - - SAcctObj *pAcct = acctGetAcct(pDb->cfg.acct); - if (pAcct == NULL) { - mError("DB: %s not belongs to andy account", pDb->name); - return TSDB_CODE_APP_ERROR; - } - - int32_t schemaSize = pTable->numOfColumns * sizeof(SSchema); - pTable->schema = realloc(pTable->schema, schemaSize + sizeof(SSchema) * ncols); - - memcpy(pTable->schema + schemaSize, schema, sizeof(SSchema) * ncols); - - SSchema *tschema = (SSchema *) (pTable->schema + sizeof(SSchema) * pTable->numOfColumns); - for (int32_t i = 0; i < ncols; i++) { - tschema[i].colId = pTable->nextColId++; - } - - pTable->numOfColumns += ncols; - pTable->sversion++; - pAcct->acctInfo.numOfTimeSeries += ncols; - - SSdbOperDesc desc = {0}; - desc.type = SDB_OPER_TYPE_GLOBAL; - desc.pObj = pTable; - desc.table = tsChildTableSdb; - desc.rowData = pTable; - desc.rowSize = tsChildTableUpdateSize; - sdbUpdateRow(&desc); - - return TSDB_CODE_SUCCESS; -} - -static int32_t mgmtDropNormalTableColumnByName(SChildTableObj *pTable, char *colName) { - int32_t col = mgmtFindNormalTableColumnIndex(pTable, colName); - if (col < 0) { - return TSDB_CODE_APP_ERROR; - } - - SDbObj *pDb = mgmtGetDbByTableId(pTable->info.tableId); - if (pDb == NULL) { - mError("table: %s not belongs to any database", pTable->info.tableId); - return TSDB_CODE_APP_ERROR; - } - - SAcctObj *pAcct = acctGetAcct(pDb->cfg.acct); - if (pAcct == NULL) { - mError("DB: %s not belongs to any account", pDb->name); - return TSDB_CODE_APP_ERROR; - } - - memmove(pTable->schema + sizeof(SSchema) * col, pTable->schema + sizeof(SSchema) * (col + 1), - sizeof(SSchema) * (pTable->numOfColumns - col - 1)); - - pTable->numOfColumns--; - pTable->sversion++; - - pAcct->acctInfo.numOfTimeSeries--; - - SSdbOperDesc desc = {0}; - desc.type = SDB_OPER_TYPE_GLOBAL; - desc.pObj = pTable; - desc.table = tsChildTableSdb; - desc.rowData = pTable; - desc.rowSize = tsChildTableUpdateSize; - sdbUpdateRow(&desc); - - return TSDB_CODE_SUCCESS; -} - -static int32_t mgmtSetSchemaFromNormalTable(SSchema *pSchema, SChildTableObj *pTable) { - int32_t numOfCols = pTable->numOfColumns; - for (int32_t i = 0; i < numOfCols; ++i) { - strcpy(pSchema->name, pTable->schema[i].name); - pSchema->type = pTable->schema[i].type; - pSchema->bytes = htons(pTable->schema[i].bytes); - pSchema->colId = htons(pTable->schema[i].colId); - pSchema++; - } - - return numOfCols * sizeof(SSchema); -} - -static int32_t mgmtDoGetChildTableMeta(SDbObj *pDb, SChildTableObj *pTable, STableMetaMsg *pMeta, bool usePublicIp) { - pMeta->uid = htobe64(pTable->uid); - pMeta->sid = htonl(pTable->sid); - pMeta->vgId = htonl(pTable->vgId); - pMeta->precision = pDb->cfg.precision; - pMeta->tableType = pTable->info.type; - strncpy(pMeta->tableId, pTable->info.tableId, tListLen(pTable->info.tableId)); - - if (pTable->info.type == TSDB_CHILD_TABLE) { - pMeta->sversion = htons(pTable->superTable->sversion); - pMeta->numOfTags = 0; - pMeta->numOfColumns = htons((int16_t)pTable->superTable->numOfColumns); - pMeta->contLen = sizeof(STableMetaMsg) + mgmtSetSchemaFromSuperTable(pMeta->schema, pTable->superTable); - strncpy(pMeta->stableId, pTable->superTable->info.tableId, tListLen(pMeta->stableId)); - } else { - pMeta->sversion = htons(pTable->sversion); - pMeta->numOfTags = 0; - pMeta->numOfColumns = htons((int16_t)pTable->numOfColumns); - pMeta->contLen = sizeof(STableMetaMsg) + mgmtSetSchemaFromNormalTable(pMeta->schema, pTable); - } - - SVgObj *pVgroup = mgmtGetVgroup(pTable->vgId); - if (pVgroup == NULL) { - mError("table:%s, failed to get table meta, db not selected", pTable->info.tableId); - return TSDB_CODE_INVALID_VGROUP_ID; - } - - for (int32_t i = 0; i < TSDB_VNODES_SUPPORT; ++i) { - if (usePublicIp) { - pMeta->vpeerDesc[i].ip = pVgroup->vnodeGid[i].publicIp; - } else { - pMeta->vpeerDesc[i].ip = pVgroup->vnodeGid[i].privateIp; - } - pMeta->vpeerDesc[i].vnode = htonl(pVgroup->vnodeGid[i].vnode); - } - pMeta->numOfVpeers = pVgroup->numOfVnodes; - - mTrace("table:%s, uid:%" PRIu64 " table meta is retrieved", pTable->info.tableId, pTable->uid); - - return TSDB_CODE_SUCCESS; -} - -void mgmtGetChildTableMeta(SQueuedMsg *pMsg, SChildTableObj *pTable) { - SCMTableInfoMsg *pInfo = pMsg->pCont; - SDbObj *pDb = mgmtGetDbByTableId(pInfo->tableId); - if (pDb == NULL || pDb->dirty) { - mError("table:%s, failed to get table meta, db not selected", pInfo->tableId); - mgmtSendSimpleResp(pMsg->thandle, TSDB_CODE_DB_NOT_SELECTED); - return; - } - - if (pTable == NULL) { - if (htons(pInfo->createFlag) != 1) { - mError("table:%s, failed to get table meta, table not exist", pInfo->tableId); - mgmtSendSimpleResp(pMsg->thandle, TSDB_CODE_INVALID_TABLE); - return; - } else { - //TODO: on demand create table from super table if table does not exists - int32_t contLen = sizeof(SCMCreateTableMsg) + sizeof(STagData); - SCMCreateTableMsg *pCreateMsg = rpcMallocCont(contLen); - if (pCreateMsg == NULL) { - mError("table:%s, failed to create table while get meta info, no enough memory", pInfo->tableId); - mgmtSendSimpleResp(pMsg->thandle, TSDB_CODE_SERV_OUT_OF_MEMORY); - return; - } - memcpy(pCreateMsg->schema, pInfo->tags, sizeof(STagData)); - strcpy(pCreateMsg->tableId, pInfo->tableId); - - SQueuedMsg *newMsg = malloc(sizeof(SQueuedMsg)); - memcpy(newMsg, pMsg, sizeof(SQueuedMsg)); - pMsg->pCont = NULL; - - newMsg->ahandle = newMsg->pCont; - newMsg->pCont = pCreateMsg; - mTrace("table:%s, start to create in demand", pInfo->tableId); - mgmtAddToShellQueue(newMsg); - return; - } - } - - STableMetaMsg *pMeta = rpcMallocCont(sizeof(STableMetaMsg) + sizeof(SSchema) * TSDB_MAX_COLUMNS); - if (pMeta == NULL) { - mError("table:%s, failed to get table meta, no enough memory", pTable->info.tableId); - mgmtSendSimpleResp(pMsg->thandle, TSDB_CODE_SERV_OUT_OF_MEMORY); - return; - } - - mgmtDoGetChildTableMeta(pDb, pTable, pMeta, pMsg->usePublicIp); - - SRpcMsg rpcRsp = { - .handle = pMsg->thandle, - .pCont = pMeta, - .contLen = pMeta->contLen, - }; - pMeta->contLen = htons(pMeta->contLen); - rpcSendResponse(&rpcRsp); -} - -void mgmtDropAllChildTables(SDbObj *pDropDb) { - void *pNode = NULL; - void *pLastNode = NULL; - int32_t numOfTables = 0; - int32_t dbNameLen = strlen(pDropDb->name); - SChildTableObj *pTable = NULL; - - while (1) { - pNode = sdbFetchRow(tsChildTableSdb, pNode, (void **)&pTable); - if (pTable == NULL) { - break; - } - - if (strncmp(pDropDb->name, pTable->info.tableId, dbNameLen) == 0) { - SSdbOperDesc oper = { - .type = SDB_OPER_TYPE_LOCAL, - .table = tsChildTableSdb, - .pObj = pTable, - }; - sdbDeleteRow(&oper); - pNode = pLastNode; - numOfTables++; - continue; - } - } - - mTrace("db:%s, all child tables:%d is dropped from sdb", pDropDb->name, numOfTables); -} - -void mgmtDropAllChildTablesInStable(SSuperTableObj *pStable) { - void *pNode = NULL; - void *pLastNode = NULL; - int32_t numOfTables = 0; - SChildTableObj *pTable = NULL; - - while (1) { - pNode = sdbFetchRow(tsChildTableSdb, pNode, (void **)&pTable); - if (pTable == NULL) { - break; - } - - if (pTable->superTable == pStable) { - SSdbOperDesc oper = { - .type = SDB_OPER_TYPE_LOCAL, - .table = tsChildTableSdb, - .pObj = pTable, - }; - sdbDeleteRow(&oper); - pNode = pLastNode; - numOfTables++; - continue; - } - } - - mTrace("stable:%s, all child tables:%d is dropped from sdb", pStable->info.tableId, numOfTables); -} - -static STableInfo* mgmtGetTableByPos(uint32_t dnodeId, int32_t vnode, int32_t sid) { - SDnodeObj *pObj = mgmtGetDnode(dnodeId); - SVgObj *pVgroup = mgmtGetVgroup(vnode); - - if (pObj == NULL || pVgroup == NULL) { - return NULL; - } - - return (STableInfo *)pVgroup->tableList[sid]; -} - -static void mgmtProcessTableCfgMsg(SRpcMsg *rpcMsg) { - if (mgmtCheckRedirect(rpcMsg->handle)) return; - - SDMConfigTableMsg *pCfg = (SDMConfigTableMsg *) rpcMsg->pCont; - pCfg->dnode = htonl(pCfg->dnode); - pCfg->vnode = htonl(pCfg->vnode); - pCfg->sid = htonl(pCfg->sid); - mTrace("dnode:%s, vnode:%d, sid:%d, receive table config msg", taosIpStr(pCfg->dnode), pCfg->vnode, pCfg->sid); - - STableInfo *pTable = mgmtGetTableByPos(pCfg->dnode, pCfg->vnode, pCfg->sid); - if (pTable == NULL) { - mError("dnode:%s, vnode:%d, sid:%d, table not found", taosIpStr(pCfg->dnode), pCfg->vnode, pCfg->sid); - mgmtSendSimpleResp(rpcMsg->handle, TSDB_CODE_NOT_ACTIVE_TABLE); - return; - } - - mgmtSendSimpleResp(rpcMsg->handle, TSDB_CODE_SUCCESS); - - SMDCreateTableMsg *pMDCreate = NULL; - pMDCreate = mgmtBuildCreateChildTableMsg(NULL, (SChildTableObj *) pTable); - if (pMDCreate == NULL) { - return; - } - - SRpcIpSet ipSet = mgmtGetIpSetFromIp(pCfg->dnode); - SRpcMsg rpcRsp = { - .handle = NULL, - .pCont = pMDCreate, - .contLen = htonl(pMDCreate->contLen), - .code = 0, - .msgType = TSDB_MSG_TYPE_MD_CREATE_TABLE - }; - mgmtSendMsgToDnode(&ipSet, &rpcRsp); -} - -static void mgmtProcessDropTableRsp(SRpcMsg *rpcMsg) { - if (rpcMsg->handle == NULL) return; - - SQueuedMsg *queueMsg = rpcMsg->handle; - queueMsg->received++; - - SChildTableObj *pTable = queueMsg->ahandle; - mTrace("table:%s, drop table rsp received, thandle:%p result:%s", pTable->info.tableId, queueMsg->thandle, tstrerror(rpcMsg->code)); - - if (rpcMsg->code != TSDB_CODE_SUCCESS) { - mError("table:%s, failed to drop in dnode, reason:%s", pTable->info.tableId, tstrerror(rpcMsg->code)); - mgmtSendSimpleResp(queueMsg->thandle, rpcMsg->code); - free(queueMsg); - return; - } - - SVgObj *pVgroup = mgmtGetVgroup(pTable->vgId); - if (pVgroup == NULL) { - mError("table:%s, failed to get vgroup", pTable->info.tableId); - mgmtSendSimpleResp(queueMsg->thandle, TSDB_CODE_INVALID_VGROUP_ID); - free(queueMsg); - return; - } - - SSdbOperDesc oper = { - .type = SDB_OPER_TYPE_GLOBAL, - .table = tsChildTableSdb, - .pObj = pTable - }; - int32_t code = sdbDeleteRow(&oper); - if (code != TSDB_CODE_SUCCESS) { - mError("table:%s, update ctables sdb error", pTable->info.tableId); - mgmtSendSimpleResp(queueMsg->thandle, TSDB_CODE_SDB_ERROR); - free(queueMsg); - return; - } - - if (pVgroup->numOfTables <= 0) { - mPrint("vgroup:%d, all tables is dropped, drop vgroup", pVgroup->vgId); - mgmtDropVgroup(pVgroup, NULL); - } - - mgmtSendSimpleResp(queueMsg->thandle, TSDB_CODE_SUCCESS); - free(queueMsg); -} - -static void mgmtProcessCreateTableRsp(SRpcMsg *rpcMsg) { - if (rpcMsg->handle == NULL) return; - - SQueuedMsg *queueMsg = rpcMsg->handle; - queueMsg->received++; - - SChildTableObj *pTable = queueMsg->ahandle; - mTrace("table:%s, create table rsp received, thandle:%p ahandle:%p result:%s", pTable->info.tableId, queueMsg->thandle, - rpcMsg->handle, tstrerror(rpcMsg->code)); - - if (rpcMsg->code != TSDB_CODE_SUCCESS) { - SSdbOperDesc oper = { - .type = SDB_OPER_TYPE_GLOBAL, - .table = tsChildTableSdb, - .pObj = pTable - }; - sdbDeleteRow(&oper); - - mError("table:%s, failed to create in dnode, reason:%s", pTable->info.tableId, tstrerror(rpcMsg->code)); - mgmtSendSimpleResp(queueMsg->thandle, rpcMsg->code); - } else { - mTrace("table:%s, created in dnode", pTable->info.tableId); - if (queueMsg->msgType != TSDB_MSG_TYPE_CM_CREATE_TABLE) { - SQueuedMsg *newMsg = calloc(1, sizeof(SQueuedMsg)); - newMsg->msgType = queueMsg->msgType; - newMsg->thandle = queueMsg->thandle; - newMsg->pDb = queueMsg->pDb; - newMsg->pUser = queueMsg->pUser; - newMsg->contLen = queueMsg->contLen; - newMsg->pCont = rpcMallocCont(newMsg->contLen); - memcpy(newMsg->pCont, queueMsg->pCont, newMsg->contLen); - mTrace("table:%s, start to get meta", pTable->info.tableId); - mgmtAddToShellQueue(newMsg); - } else { - mgmtSendSimpleResp(queueMsg->thandle, rpcMsg->code); - } - } - - free(queueMsg); -} - -static void mgmtProcessAlterTableRsp(SRpcMsg *rpcMsg) { - mTrace("alter table rsp received, handle:%p code:%d", rpcMsg->handle, rpcMsg->code); -} - -static void mgmtProcessMultiTableMetaMsg(SQueuedMsg *pMsg) { - SRpcConnInfo connInfo; - if (rpcGetConnInfo(pMsg->thandle, &connInfo) != 0) { - mError("conn:%p is already released while get mulit table meta", pMsg->thandle); - return; - } - - bool usePublicIp = (connInfo.serverIp == tsPublicIpInt); - SUserObj *pUser = mgmtGetUser(connInfo.user); - if (pUser == NULL) { - mgmtSendSimpleResp(pMsg->thandle, TSDB_CODE_INVALID_USER); - return; - } - - SCMMultiTableInfoMsg *pInfo = pMsg->pCont; - pInfo->numOfTables = htonl(pInfo->numOfTables); - - int32_t totalMallocLen = 4*1024*1024; // first malloc 4 MB, subsequent reallocation as twice - SMultiTableMeta *pMultiMeta = rpcMallocCont(totalMallocLen); - if (pMultiMeta == NULL) { - mgmtSendSimpleResp(pMsg->thandle, TSDB_CODE_SERV_OUT_OF_MEMORY); - return; - } - - pMultiMeta->contLen = sizeof(SMultiTableMeta); - pMultiMeta->numOfTables = 0; - - for (int t = 0; t < pInfo->numOfTables; ++t) { - char *tableId = (char*)(pInfo->tableIds + t * TSDB_TABLE_ID_LEN); - SChildTableObj *pTable = mgmtGetChildTable(tableId); - if (pTable == NULL) continue; - - SDbObj *pDb = mgmtGetDbByTableId(tableId); - if (pDb == NULL) continue; - - int availLen = totalMallocLen - pMultiMeta->contLen; - if (availLen <= sizeof(STableMetaMsg) + sizeof(SSchema) * TSDB_MAX_COLUMNS) { - //TODO realloc - //totalMallocLen *= 2; - //pMultiMeta = rpcReMalloc(pMultiMeta, totalMallocLen); - //if (pMultiMeta == NULL) { - /// rpcSendResponse(ahandle, TSDB_CODE_SERV_OUT_OF_MEMORY, NULL, 0); - // return TSDB_CODE_SERV_OUT_OF_MEMORY; - //} else { - // t--; - // continue; - //} - } - - STableMetaMsg *pMeta = (STableMetaMsg *)(pMultiMeta->metas + pMultiMeta->contLen); - int32_t code = mgmtDoGetChildTableMeta(pDb, pTable, pMeta, usePublicIp); - if (code == TSDB_CODE_SUCCESS) { - pMultiMeta->numOfTables ++; - pMultiMeta->contLen += pMeta->contLen; - } - } - - SRpcMsg rpcRsp = {0}; - rpcRsp.handle = pMsg->thandle; - rpcRsp.pCont = pMultiMeta; - rpcRsp.contLen = pMultiMeta->contLen; - rpcSendResponse(&rpcRsp); -} - -static int32_t mgmtGetShowTableMeta(STableMetaMsg *pMeta, SShowObj *pShow, void *pConn) { - SDbObj *pDb = mgmtGetDb(pShow->db); - if (pDb == NULL) { - return TSDB_CODE_DB_NOT_SELECTED; - } - - int32_t cols = 0; - SSchema *pSchema = pMeta->schema; - - pShow->bytes[cols] = TSDB_TABLE_NAME_LEN; - pSchema[cols].type = TSDB_DATA_TYPE_BINARY; - strcpy(pSchema[cols].name, "table name"); - pSchema[cols].bytes = htons(pShow->bytes[cols]); - cols++; - - pShow->bytes[cols] = 8; - pSchema[cols].type = TSDB_DATA_TYPE_TIMESTAMP; - strcpy(pSchema[cols].name, "create time"); - pSchema[cols].bytes = htons(pShow->bytes[cols]); - cols++; - - pShow->bytes[cols] = 2; - pSchema[cols].type = TSDB_DATA_TYPE_SMALLINT; - strcpy(pSchema[cols].name, "columns"); - pSchema[cols].bytes = htons(pShow->bytes[cols]); - cols++; - - pShow->bytes[cols] = TSDB_TABLE_NAME_LEN; - pSchema[cols].type = TSDB_DATA_TYPE_BINARY; - strcpy(pSchema[cols].name, "stable name"); - pSchema[cols].bytes = htons(pShow->bytes[cols]); - cols++; - - pMeta->numOfColumns = htons(cols); - pShow->numOfColumns = cols; - - pShow->offset[0] = 0; - for (int32_t i = 1; i < cols; ++i) { - pShow->offset[i] = pShow->offset[i - 1] + pShow->bytes[i - 1]; - } - - pShow->numOfRows = pDb->numOfTables; - pShow->rowSize = pShow->offset[cols - 1] + pShow->bytes[cols - 1]; - - return 0; -} - -static void mgmtVacuumResult(char *data, int32_t numOfCols, int32_t rows, int32_t capacity, SShowObj *pShow) { - if (rows < capacity) { - for (int32_t i = 0; i < numOfCols; ++i) { - memmove(data + pShow->offset[i] * rows, data + pShow->offset[i] * capacity, pShow->bytes[i] * rows); - } - } -} - -static int32_t mgmtRetrieveShowTables(SShowObj *pShow, char *data, int32_t rows, void *pConn) { - SDbObj *pDb = mgmtGetDb(pShow->db); - if (pDb == NULL) return 0; - - SUserObj *pUser = mgmtGetUserFromConn(pConn, NULL); - if (pUser == NULL) return 0; - - if (mgmtCheckIsMonitorDB(pDb->name, tsMonitorDbName)) { - if (strcmp(pUser->user, "root") != 0 && strcmp(pUser->user, "_root") != 0 && - strcmp(pUser->user, "monitor") != 0) { - return 0; - } - } - - int32_t numOfRows = 0; - SChildTableObj *pTable = NULL; - SPatternCompareInfo info = PATTERN_COMPARE_INFO_INITIALIZER; - - char prefix[64] = {0}; - strcpy(prefix, pDb->name); - strcat(prefix, TS_PATH_DELIMITER); - int32_t prefixLen = strlen(prefix); - - while (numOfRows < rows) { - pShow->pNode = sdbFetchRow(tsChildTableSdb, pShow->pNode, (void **) &pTable); - if (pTable == NULL) break; - - // not belong to current db - if (strncmp(pTable->info.tableId, prefix, prefixLen)) { - continue; - } - - char tableName[TSDB_TABLE_NAME_LEN] = {0}; - memset(tableName, 0, tListLen(tableName)); - - // pattern compare for meter name - mgmtExtractTableName(pTable->info.tableId, tableName); - - if (pShow->payloadLen > 0 && - patternMatch(pShow->payload, tableName, TSDB_TABLE_NAME_LEN, &info) != TSDB_PATTERN_MATCH) { - continue; - } - - int32_t cols = 0; - - char *pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows; - strncpy(pWrite, tableName, TSDB_TABLE_NAME_LEN); - cols++; - - pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows; - *(int64_t *) pWrite = pTable->createdTime; - cols++; - - pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows; - if (pTable->info.type == TSDB_CHILD_TABLE) { - *(int16_t *)pWrite = pTable->superTable->numOfColumns; - } else { - *(int16_t *)pWrite = pTable->numOfColumns; - } - - cols++; - - pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows; - if (pTable->info.type == TSDB_CHILD_TABLE) { - mgmtExtractTableName(pTable->superTableId, pWrite); - } - cols++; - - numOfRows++; - } - - pShow->numOfReads += numOfRows; - const int32_t NUM_OF_COLUMNS = 4; - - mgmtVacuumResult(data, NUM_OF_COLUMNS, numOfRows, rows, pShow); - - return numOfRows; -} - -void mgmtAlterChildTable(SQueuedMsg *pMsg, SChildTableObj *pTable) { - int32_t code = TSDB_CODE_OPS_NOT_SUPPORT; - SCMAlterTableMsg *pAlter = pMsg->pCont;; - - if (pAlter->type == TSDB_ALTER_TABLE_UPDATE_TAG_VAL) { - code = mgmtModifyChildTableTagValueByName(pTable, pAlter->schema[0].name, pAlter->tagVal); - } else if (pAlter->type == TSDB_ALTER_TABLE_ADD_COLUMN) { - code = mgmtAddNormalTableColumn(pTable, pAlter->schema, 1); - } else if (pAlter->type == TSDB_ALTER_TABLE_DROP_COLUMN) { - code = mgmtDropNormalTableColumnByName(pTable, pAlter->schema[0].name); - } else { - } - - mgmtSendSimpleResp(pMsg->thandle, code); -} \ No newline at end of file diff --git a/src/mnode/src/mgmtDb.c b/src/mnode/src/mgmtDb.c index 5f28c30423..1924e85f7b 100644 --- a/src/mnode/src/mgmtDb.c +++ b/src/mnode/src/mgmtDb.c @@ -22,24 +22,22 @@ #include "mnode.h" #include "mgmtAcct.h" #include "mgmtBalance.h" -#include "mgmtChildTable.h" #include "mgmtDb.h" #include "mgmtDnode.h" #include "mgmtGrant.h" #include "mgmtShell.h" #include "mgmtMnode.h" -#include "mgmtChildTable.h" +#include "mgmtProfile.h" #include "mgmtSdb.h" -#include "mgmtSuperTable.h" #include "mgmtTable.h" #include "mgmtUser.h" #include "mgmtVgroup.h" -void * tsDbSdb = NULL; +void * tsDbSdb = NULL; static int32_t tsDbUpdateSize; static int32_t mgmtCreateDb(SAcctObj *pAcct, SCMCreateDbMsg *pCreate); -static void mgmtDropDb(void *handle, void *tmrId); +static void mgmtDropDb(SQueuedMsg *newMsg); static int32_t mgmtSetDbDirty(SDbObj *pDb); static int32_t mgmtGetDbMeta(STableMetaMsg *pMeta, SShowObj *pShow, void *pConn); static int32_t mgmtRetrieveDbs(SShowObj *pShow, char *data, int32_t rows, void *pConn); @@ -58,8 +56,6 @@ static int32_t mgmtDbActionInsert(SSdbOperDesc *pOper) { pDb->pHead = NULL; pDb->pTail = NULL; - pDb->prev = NULL; - pDb->next = NULL; pDb->numOfVgroups = 0; pDb->numOfTables = 0; pDb->numOfSuperTables = 0; @@ -120,6 +116,7 @@ int32_t mgmtInitDbs() { .tableName = "dbs", .hashSessions = TSDB_MAX_DBS, .maxRowSize = tsDbUpdateSize, + .refCountPos = (int8_t *)(&tObj.refCount) - (int8_t *)&tObj, .keyType = SDB_KEY_TYPE_STRING, .insertFp = mgmtDbActionInsert, .deleteFp = mgmtDbActionDelete, @@ -149,6 +146,14 @@ SDbObj *mgmtGetDb(char *db) { return (SDbObj *)sdbGetRow(tsDbSdb, db); } +void mgmtIncDbRef(SDbObj *pDb) { + return sdbIncRef(tsDbSdb, pDb); +} + +void mgmtDecDbRef(SDbObj *pDb) { + return sdbDecRef(tsDbSdb, pDb); +} + SDbObj *mgmtGetDbByTableId(char *tableId) { char db[TSDB_TABLE_ID_LEN], *pos; @@ -282,8 +287,9 @@ static int32_t mgmtCreateDb(SAcctObj *pAcct, SCMCreateDbMsg *pCreate) { return code; } - SDbObj *pDb = (SDbObj *)sdbGetRow(tsDbSdb, pCreate->db); + SDbObj *pDb = mgmtGetDb(pCreate->db); if (pDb != NULL) { + mgmtDecDbRef(pDb); return TSDB_CODE_DB_ALREADY_EXIST; } @@ -511,16 +517,14 @@ static int32_t mgmtGetDbMeta(STableMetaMsg *pMeta, SShowObj *pShow, void *pConn) } pShow->rowSize = pShow->offset[cols - 1] + pShow->bytes[cols - 1]; - pShow->numOfRows = pUser->pAcct->acctInfo.numOfDbs; - pShow->pNode = pUser->pAcct->pHead; + mgmtDecUserRef(pUser); return 0; } static char *mgmtGetDbStr(char *src) { char *pos = strstr(src, TS_PATH_DELIMITER); - return ++pos; } @@ -533,14 +537,8 @@ static int32_t mgmtRetrieveDbs(SShowObj *pShow, char *data, int32_t rows, void * if (pUser == NULL) return 0; while (numOfRows < rows) { - pDb = (SDbObj *)pShow->pNode; + pShow->pNode = sdbFetchRow(tsDbSdb, pShow->pNode, (void **) &pDb); if (pDb == NULL) break; - pShow->pNode = (void *)pDb->next; - if (mgmtCheckIsMonitorDB(pDb->name, tsMonitorDbName)) { - if (strcmp(pUser->user, "root") != 0 && strcmp(pUser->user, "_root") != 0 && strcmp(pUser->user, "monitor") != 0 ) { - continue; - } - } cols = 0; @@ -637,25 +635,32 @@ static int32_t mgmtRetrieveDbs(SShowObj *pShow, char *data, int32_t rows, void * cols++; numOfRows++; + mgmtDecDbRef(pDb); } pShow->numOfReads += numOfRows; + mgmtDecUserRef(pUser); return numOfRows; } void mgmtAddSuperTableIntoDb(SDbObj *pDb) { atomic_add_fetch_32(&pDb->numOfSuperTables, 1); + mgmtIncDbRef(pDb); } void mgmtRemoveSuperTableFromDb(SDbObj *pDb) { atomic_add_fetch_32(&pDb->numOfSuperTables, -1); + mgmtDecDbRef(pDb); } + void mgmtAddTableIntoDb(SDbObj *pDb) { atomic_add_fetch_32(&pDb->numOfTables, 1); + mgmtIncDbRef(pDb); } void mgmtRemoveTableFromDb(SDbObj *pDb) { atomic_add_fetch_32(&pDb->numOfTables, -1); + mgmtDecDbRef(pDb); } static int32_t mgmtSetDbDirty(SDbObj *pDb) { @@ -766,8 +771,6 @@ static int32_t mgmtAlterDb(SDbObj *pDb, SCMAlterDbMsg *pAlter) { } static void mgmtProcessAlterDbMsg(SQueuedMsg *pMsg) { - if (mgmtCheckRedirect(pMsg->thandle)) return; - SCMAlterDbMsg *pAlter = pMsg->pCont; mTrace("db:%s, alter db msg is received from thandle:%p", pAlter->db, pMsg->thandle); @@ -777,13 +780,7 @@ static void mgmtProcessAlterDbMsg(SQueuedMsg *pMsg) { return; } - if (!pMsg->pUser->writeAuth) { - mError("db:%s, failed to alter, no rights", pAlter->db); - mgmtSendSimpleResp(pMsg->thandle, TSDB_CODE_NO_RIGHTS); - return; - } - - SDbObj *pDb = mgmtGetDb(pAlter->db); + SDbObj *pDb = pMsg->pDb = mgmtGetDb(pAlter->db); if (pDb == NULL) { mError("db:%s, failed to alter, invalid db", pAlter->db); mgmtSendSimpleResp(pMsg->thandle, TSDB_CODE_INVALID_DB); @@ -794,15 +791,13 @@ static void mgmtProcessAlterDbMsg(SQueuedMsg *pMsg) { if (code != TSDB_CODE_SUCCESS) { mError("db:%s, failed to alter, invalid db option", pAlter->db); mgmtSendSimpleResp(pMsg->thandle, code); + return; } - SQueuedMsg *newMsg = malloc(sizeof(SQueuedMsg)); - memcpy(newMsg, pMsg, sizeof(SQueuedMsg)); - pMsg->pCont = NULL; - SVgObj *pVgroup = pDb->pHead; if (pVgroup != NULL) { mPrint("vgroup:%d, will be altered", pVgroup->vgId); + SQueuedMsg *newMsg = mgmtCloneQueuedMsg(pMsg); newMsg->ahandle = pVgroup; newMsg->expected = pVgroup->numOfVnodes; mgmtAlterVgroup(pVgroup, newMsg); @@ -810,15 +805,11 @@ static void mgmtProcessAlterDbMsg(SQueuedMsg *pMsg) { } mTrace("db:%s, all vgroups is altered", pDb->name); - - mgmtSendSimpleResp(newMsg->thandle, TSDB_CODE_SUCCESS); - rpcFreeCont(newMsg->pCont); - free(newMsg); + mgmtSendSimpleResp(pMsg->thandle, TSDB_CODE_SUCCESS); } -static void mgmtDropDb(void *handle, void *tmrId) { - SQueuedMsg *newMsg = handle; - SDbObj *pDb = newMsg->ahandle; +static void mgmtDropDb(SQueuedMsg *pMsg) { + SDbObj *pDb = pMsg->pDb; mPrint("db:%s, drop db from sdb", pDb->name); SSdbOperDesc oper = { @@ -831,14 +822,10 @@ static void mgmtDropDb(void *handle, void *tmrId) { code = TSDB_CODE_SDB_ERROR; } - mgmtSendSimpleResp(newMsg->thandle, code); - rpcFreeCont(newMsg->pCont); - free(newMsg); + mgmtSendSimpleResp(pMsg->thandle, code); } static void mgmtProcessDropDbMsg(SQueuedMsg *pMsg) { - if (mgmtCheckRedirect(pMsg->thandle)) return; - SCMDropDbMsg *pDrop = pMsg->pCont; mTrace("db:%s, drop db msg is received from thandle:%p", pDrop->db, pMsg->thandle); @@ -848,13 +835,7 @@ static void mgmtProcessDropDbMsg(SQueuedMsg *pMsg) { return; } - if (!pMsg->pUser->writeAuth) { - mError("db:%s, failed to drop, no rights", pDrop->db); - mgmtSendSimpleResp(pMsg->thandle, TSDB_CODE_NO_RIGHTS); - return; - } - - SDbObj *pDb = mgmtGetDb(pDrop->db); + SDbObj *pDb = pMsg->pDb = mgmtGetDb(pDrop->db); if (pDb == NULL) { if (pDrop->ignoreNotExists) { mTrace("db:%s, db is not exist, think drop success", pDrop->db); @@ -880,13 +861,10 @@ static void mgmtProcessDropDbMsg(SQueuedMsg *pMsg) { return; } - SQueuedMsg *newMsg = malloc(sizeof(SQueuedMsg)); - memcpy(newMsg, pMsg, sizeof(SQueuedMsg)); - pMsg->pCont = NULL; - SVgObj *pVgroup = pDb->pHead; if (pVgroup != NULL) { mPrint("vgroup:%d, will be dropped", pVgroup->vgId); + SQueuedMsg *newMsg = mgmtCloneQueuedMsg(pMsg); newMsg->ahandle = pVgroup; newMsg->expected = pVgroup->numOfVnodes; mgmtDropVgroup(pVgroup, newMsg); @@ -894,10 +872,7 @@ static void mgmtProcessDropDbMsg(SQueuedMsg *pMsg) { } mTrace("db:%s, all vgroups is dropped", pDb->name); - - void *tmpTmr; - newMsg->ahandle = pDb; - taosTmrReset(mgmtDropDb, 10, newMsg, tsMgmtTmr, &tmpTmr); + mgmtDropDb(pMsg); } void mgmtDropAllDbs(SAcctObj *pAcct) { @@ -913,6 +888,7 @@ void mgmtDropAllDbs(SAcctObj *pAcct) { mgmtSetDbDirty(pDb); numOfDbs++; } + mgmtDecDbRef(pDb); } mTrace("acct:%s, all dbs is is set dirty", pAcct->user, numOfDbs); diff --git a/src/mnode/src/mgmtDnode.c b/src/mnode/src/mgmtDnode.c index 9930a3a114..f9ce526c74 100644 --- a/src/mnode/src/mgmtDnode.c +++ b/src/mnode/src/mgmtDnode.c @@ -42,6 +42,8 @@ extern int32_t clusterInit(); extern void clusterCleanUp(); extern int32_t clusterGetDnodesNum(); extern void * clusterGetNextDnode(void *pNode, void **pDnode); +extern void clusterIncDnodeRef(SDnodeObj *pDnode); +extern void clusterDecDnodeRef(SDnodeObj *pDnode); extern SDnodeObj* clusterGetDnode(int32_t dnodeId); extern SDnodeObj* clusterGetDnodeByIp(uint32_t ip); #ifndef _CLUSTER @@ -118,6 +120,18 @@ int32_t mgmtGetDnodesNum() { #endif } +void mgmtIncDnodeRef(SDnodeObj *pDnode) { +#ifdef _CLUSTER + return clusterIncDnodeRef(pDnode); +#endif +} + +void mgmtDecDnodeRef(SDnodeObj *pDnode) { +#ifdef _CLUSTER + return clusterDecDnodeRef(pDnode); +#endif +} + void * mgmtGetNextDnode(void *pNode, SDnodeObj **pDnode) { #ifdef _CLUSTER return clusterGetNextDnode(pNode, pDnode); @@ -183,6 +197,13 @@ void mgmtProcessDnodeStatusMsg(SRpcMsg *rpcMsg) { pStatus->numOfCores = htons(pStatus->numOfCores); pStatus->numOfTotalVnodes = htons(pStatus->numOfTotalVnodes); + uint32_t version = htonl(pStatus->version); + if (version != tsVersion) { + mError("status msg version:%d not equal with mnode:%d", version, tsVersion); + mgmtSendSimpleResp(rpcMsg->handle, TSDB_CODE_INVALID_MSG_VERSION); + return ; + } + SDnodeObj *pDnode = NULL; if (pStatus->dnodeId == 0) { pDnode = mgmtGetDnodeByIp(pStatus->privateIp); @@ -199,13 +220,6 @@ void mgmtProcessDnodeStatusMsg(SRpcMsg *rpcMsg) { return; } } - - uint32_t version = htonl(pStatus->version); - if (version != tsVersion) { - mError("dnode:%d, status msg version:%d not equal with mnode:%d", pDnode->dnodeId, version, tsVersion); - mgmtSendSimpleResp(rpcMsg->handle, TSDB_CODE_INVALID_MSG_VERSION); - return ; - } pDnode->privateIp = pStatus->privateIp; pDnode->publicIp = pStatus->publicIp; @@ -232,6 +246,7 @@ void mgmtProcessDnodeStatusMsg(SRpcMsg *rpcMsg) { mPrint("dnode:%d, vgroup:%d not exist in mnode, drop it", pDnode->dnodeId, pDnode->vload[j].vgId); mgmtSendDropVnodeMsg(pDnode->vload[j].vgId, &ipSet, NULL); } + mgmtDecVgroupRef(pVgroup); } if (pDnode->status != TSDB_DN_STATUS_READY) { @@ -240,6 +255,8 @@ void mgmtProcessDnodeStatusMsg(SRpcMsg *rpcMsg) { mgmtStartBalanceTimer(200); } + mgmtDecDnodeRef(pDnode); + int32_t contLen = sizeof(SDMStatusRsp) + TSDB_MAX_VNODES * sizeof(SVnodeAccess); SDMStatusRsp *pRsp = rpcMallocCont(contLen); if (pRsp == NULL) { @@ -339,6 +356,8 @@ static int32_t mgmtGetDnodeMeta(STableMetaMsg *pMeta, SShowObj *pShow, void *pCo pShow->rowSize = pShow->offset[cols - 1] + pShow->bytes[cols - 1]; pShow->pNode = NULL; + mgmtDecUserRef(pUser); + return 0; } @@ -350,6 +369,7 @@ static int32_t mgmtRetrieveDnodes(SShowObj *pShow, char *data, int32_t rows, voi char ipstr[32]; while (numOfRows < rows) { + mgmtDecDnodeRef(pDnode); pShow->pNode = mgmtGetNextDnode(pShow->pNode, (SDnodeObj **)&pDnode); if (pDnode == NULL) break; @@ -453,6 +473,7 @@ static int32_t mgmtGetModuleMeta(STableMetaMsg *pMeta, SShowObj *pShow, void *pC pShow->rowSize = pShow->offset[cols - 1] + pShow->bytes[cols - 1]; pShow->pNode = NULL; + mgmtDecUserRef(pUser); return 0; } @@ -465,6 +486,7 @@ int32_t mgmtRetrieveModules(SShowObj *pShow, char *data, int32_t rows, void *pCo char ipstr[20]; while (numOfRows < rows) { + mgmtDecDnodeRef(pDnode); pShow->pNode = mgmtGetNextDnode(pShow->pNode, (SDnodeObj **)&pDnode); if (pDnode == NULL) break; @@ -539,6 +561,7 @@ static int32_t mgmtGetConfigMeta(STableMetaMsg *pMeta, SShowObj *pShow, void *pC pShow->rowSize = pShow->offset[cols - 1] + pShow->bytes[cols - 1]; pShow->pNode = NULL; + mgmtDecUserRef(pUser); return 0; } @@ -653,6 +676,8 @@ static int32_t mgmtGetVnodeMeta(STableMetaMsg *pMeta, SShowObj *pShow, void *pCo } pShow->rowSize = pShow->offset[cols - 1] + pShow->bytes[cols - 1]; + mgmtDecDnodeRef(pDnode); + mgmtDecUserRef(pUser); return 0; } diff --git a/src/mnode/src/mgmtMnode.c b/src/mnode/src/mgmtMnode.c index e9277651c7..4ccc4b8a04 100644 --- a/src/mnode/src/mgmtMnode.c +++ b/src/mnode/src/mgmtMnode.c @@ -48,7 +48,7 @@ int32_t mgmtInitMnodes() { void mgmtCleanupMnodes() {} bool mgmtInServerStatus() { return tsMnodeObj.status == TSDB_MN_STATUS_SERVING; } bool mgmtIsMaster() { return tsMnodeObj.role == TSDB_MN_ROLE_MASTER; } -bool mgmtCheckRedirect(void *handle) { return false; } +bool mgmtCheckRedirect(void *thandle) { return false; } static int32_t mgmtGetMnodesNum() { return 1; @@ -117,9 +117,10 @@ static int32_t mgmtGetMnodeMeta(STableMetaMsg *pMeta, SShowObj *pShow, void *pCo pShow->offset[i] = pShow->offset[i - 1] + pShow->bytes[i - 1]; } - pShow->numOfRows = mgmtGetDnodesNum(); + pShow->numOfRows = mgmtGetMnodesNum(); pShow->rowSize = pShow->offset[cols - 1] + pShow->bytes[cols - 1]; pShow->pNode = NULL; + mgmtDecUserRef(pUser); return 0; } @@ -167,6 +168,7 @@ static int32_t mgmtRetrieveMnodes(SShowObj *pShow, char *data, int32_t rows, voi } pShow->numOfReads += numOfRows; + return numOfRows; } diff --git a/src/mnode/src/mgmtProfile.c b/src/mnode/src/mgmtProfile.c index 44bd45faea..4a8b4b1ea1 100644 --- a/src/mnode/src/mgmtProfile.c +++ b/src/mnode/src/mgmtProfile.c @@ -16,10 +16,13 @@ #define _DEFAULT_SOURCE #include "os.h" #include "taosmsg.h" +#include "mgmtDb.h" #include "mgmtMnode.h" #include "mgmtProfile.h" #include "mgmtShell.h" +#include "mgmtTable.h" #include "mgmtUser.h" +#include "mgmtVgroup.h" int32_t mgmtSaveQueryStreamList(SCMHeartBeatMsg *pHBMsg); @@ -763,12 +766,49 @@ int32_t mgmtInitProfile() { void mgmtCleanUpProfile() { } +void *mgmtMallocQueuedMsg(SRpcMsg *rpcMsg) { + bool usePublicIp = false; + SUserObj *pUser = mgmtGetUserFromConn(rpcMsg->handle, &usePublicIp); + if (pUser == NULL) { + return NULL; + } + + SQueuedMsg *pMsg = calloc(1, sizeof(SQueuedMsg)); + pMsg->thandle = rpcMsg->handle; + pMsg->msgType = rpcMsg->msgType; + pMsg->contLen = rpcMsg->contLen; + pMsg->pCont = rpcMsg->pCont; + pMsg->pUser = pUser; + pMsg->usePublicIp = usePublicIp; + + return pMsg; +} + void mgmtFreeQueuedMsg(SQueuedMsg *pMsg) { if (pMsg != NULL) { - if (pMsg->pCont != NULL) { - rpcFreeCont(pMsg->pCont); - pMsg->pCont = NULL; - } + rpcFreeCont(pMsg->pCont); + if (pMsg->pUser) mgmtDecUserRef(pMsg->pUser); + if (pMsg->pDb) mgmtDecDbRef(pMsg->pDb); + if (pMsg->pVgroup) mgmtDecVgroupRef(pMsg->pVgroup); + if (pMsg->pTable) mgmtDecTableRef(pMsg->pTable); + // if (pMsg->pAcct) acctDecRef(pMsg->pAcct); + // if (pMsg->pDnode) mgmtDecTableRef(pMsg->pDnode); free(pMsg); } +} + +void* mgmtCloneQueuedMsg(SQueuedMsg *pSrcMsg) { + SQueuedMsg *pDestMsg = calloc(1, sizeof(SQueuedMsg)); + + pDestMsg->thandle = pSrcMsg->thandle; + pDestMsg->msgType = pSrcMsg->msgType; + pDestMsg->pCont = pSrcMsg->pCont; + pDestMsg->contLen = pSrcMsg->contLen; + pDestMsg->pUser = pSrcMsg->pUser; + pDestMsg->usePublicIp = pSrcMsg->usePublicIp; + + pSrcMsg->pCont = NULL; + pSrcMsg->pUser = NULL; + + return pDestMsg; } \ No newline at end of file diff --git a/src/mnode/src/mgmtSdb.c b/src/mnode/src/mgmtSdb.c index 0b1ac3be97..06cb9dca5c 100644 --- a/src/mnode/src/mgmtSdb.c +++ b/src/mnode/src/mgmtSdb.c @@ -24,6 +24,7 @@ #include "tutil.h" #include "hashint.h" #include "hashstr.h" + #include "mgmtSdb.h" #define abs(x) (((x) < 0) ? -(x) : (x)) @@ -46,6 +47,7 @@ typedef struct _SSdbTable { int32_t tableId; int32_t hashSessions; int32_t maxRowSize; + int32_t refCountPos; int32_t autoIndex; int32_t fd; int64_t numOfRows; @@ -318,11 +320,6 @@ static int32_t sdbInitTableByFile(SSdbTable *pTable) { } } else { if (rowHead->version < 0) { - SSdbOperDesc oper = { - .table = pTable, - .pObj = pMetaRow - }; - (*pTable->destroyFp)(&oper); (*sdbDeleteIndexFp[pTable->keyType])(pTable->iHandle, rowHead->data); pTable->numOfRows--; sdbTrace("table:%s, version:%" PRId64 " numOfRows:%d, read deleted record:%s", @@ -338,8 +335,6 @@ static int32_t sdbInitTableByFile(SSdbTable *pTable) { .rowSize = rowHead->rowSize, .pObj = pMetaRow }; - - (*pTable->destroyFp)(&oper); (*sdbDeleteIndexFp[pTable->keyType])(pTable->iHandle, rowHead->data); int32_t code = (*pTable->decodeFp)(&oper); @@ -373,6 +368,7 @@ static int32_t sdbInitTableByFile(SSdbTable *pTable) { .version = pMeta->version, }; + sdbIncRef(pTable, oper.pObj); int32_t code = (*pTable->insertFp)(&oper); if (code != TSDB_CODE_SUCCESS) { sdbError("table:%s, failed to insert record:%s", pTable->tableName, sdbGetkeyStr(pTable, rowHead->data)); @@ -396,6 +392,7 @@ void *sdbOpenTable(SSdbTableDesc *pDesc) { pTable->keyType = pDesc->keyType; pTable->hashSessions = pDesc->hashSessions; pTable->maxRowSize = pDesc->maxRowSize; + pTable->refCountPos = pDesc->refCountPos; pTable->insertFp = pDesc->insertFp; pTable->deleteFp = pDesc->deleteFp; pTable->updateFp = pDesc->updateFp; @@ -433,6 +430,34 @@ static SRowMeta *sdbGetRowMeta(void *handle, void *key) { return pMeta; } +void sdbIncRef(void *handle, void *pRow) { + if (pRow) { + SSdbTable *pTable = handle; + int32_t *pRefCount = (int32_t *)(pRow + pTable->refCountPos); + atomic_add_fetch_32(pRefCount, 1); + if (0) { + sdbTrace("table:%s, add ref to record:%s:%s:%d", pTable->tableName, pTable->tableName, sdbGetkeyStr(pTable, pRow), *pRefCount); + } + } +} + +void sdbDecRef(void *handle, void *pRow) { + if (pRow) { + SSdbTable *pTable = handle; + int32_t *pRefCount = (int32_t *)(pRow + pTable->refCountPos); + int32_t refCount = atomic_sub_fetch_32(pRefCount, 1); + if (0) { + sdbTrace("table:%s, def ref of record:%s:%s:%d", pTable->tableName, pTable->tableName, sdbGetkeyStr(pTable, pRow), *pRefCount); + } + int8_t* updateEnd = pRow + pTable->refCountPos - 1; + if (refCount <= 0 && *updateEnd) { + sdbTrace("table:%s, record:%s:%s:%d is destroyed", pTable->tableName, pTable->tableName, sdbGetkeyStr(pTable, pRow), *pRefCount); + SSdbOperDesc oper = {.pObj = pRow}; + (*pTable->destroyFp)(&oper); + } + } +} + void *sdbGetRow(void *handle, void *key) { SSdbTable *pTable = (SSdbTable *)handle; SRowMeta * pMeta; @@ -441,6 +466,7 @@ void *sdbGetRow(void *handle, void *key) { pthread_mutex_lock(&pTable->mutex); pMeta = (*sdbGetIndexFp[pTable->keyType])(pTable->iHandle, key); + if (pMeta) sdbIncRef(pTable, pMeta->row); pthread_mutex_unlock(&pTable->mutex); if (pMeta == NULL) { @@ -459,6 +485,7 @@ int32_t sdbInsertRow(SSdbOperDesc *pOper) { if (sdbGetRow(pTable, pOper->pObj)) { sdbError("table:%s, failed to insert record:%s, already exist", pTable->tableName, sdbGetkeyStr(pTable, pOper->pObj)); + sdbDecRef(pTable, pOper->pObj); return TSDB_CODE_ALREADY_THERE; } @@ -526,6 +553,7 @@ int32_t sdbInsertRow(SSdbOperDesc *pOper) { rowMeta.rowSize = pOper->rowSize; rowMeta.row = pOper->pObj; (*sdbAddIndexFp[pTable->keyType])(pTable->iHandle, pOper->pObj, &rowMeta); + sdbIncRef(pTable, pOper->pObj); pTable->numOfRows++; @@ -626,8 +654,9 @@ int32_t sdbDeleteRow(SSdbOperDesc *pOper) { pthread_mutex_unlock(&pTable->mutex); (*pTable->deleteFp)(pOper); - (*pTable->destroyFp)(pOper); - + int8_t* updateEnd = pOper->pObj + pTable->refCountPos - 1; + *updateEnd = 1; + sdbDecRef(pTable, pOper->pObj); return 0; } @@ -762,6 +791,7 @@ void *sdbFetchRow(void *handle, void *pNode, void **ppRow) { if (pMeta == NULL) return NULL; *ppRow = pMeta->row; + sdbIncRef(handle, pMeta->row); return pNode; } diff --git a/src/mnode/src/mgmtShell.c b/src/mnode/src/mgmtShell.c index 696403b2fe..67b7a72c23 100644 --- a/src/mnode/src/mgmtShell.c +++ b/src/mnode/src/mgmtShell.c @@ -25,7 +25,6 @@ #include "mnode.h" #include "mgmtAcct.h" #include "mgmtBalance.h" -#include "mgmtChildTable.h" #include "mgmtDb.h" #include "mgmtDnode.h" #include "mgmtGrant.h" @@ -33,7 +32,6 @@ #include "mgmtProfile.h" #include "mgmtSdb.h" #include "mgmtShell.h" -#include "mgmtSuperTable.h" #include "mgmtTable.h" #include "mgmtUser.h" #include "mgmtVgroup.h" @@ -42,7 +40,7 @@ typedef int32_t (*SShowMetaFp)(STableMetaMsg *pMeta, SShowObj *pShow, void *pCon typedef int32_t (*SShowRetrieveFp)(SShowObj *pShow, char *data, int32_t rows, void *pConn); static int mgmtShellRetriveAuth(char *user, char *spi, char *encrypt, char *secret, char *ckey); -static bool mgmtCheckMsgReadOnly(int8_t type, void *pCont); +static bool mgmtCheckMsgReadOnly(SQueuedMsg *pMsg); static void mgmtProcessMsgFromShell(SRpcMsg *pMsg); static void mgmtProcessUnSupportMsg(SRpcMsg *rpcMsg); static void mgmtProcessMsgWhileNotReady(SRpcMsg *rpcMsg); @@ -121,8 +119,7 @@ void mgmtAddShellShowRetrieveHandle(uint8_t msgType, SShowRetrieveFp fp) { void mgmtProcessTranRequest(SSchedMsg *sched) { SQueuedMsg *queuedMsg = sched->msg; (*tsMgmtProcessShellMsgFp[queuedMsg->msgType])(queuedMsg); - rpcFreeCont(queuedMsg->pCont); - free(queuedMsg); + mgmtFreeQueuedMsg(queuedMsg); } void mgmtAddToShellQueue(SQueuedMsg *queuedMsg) { @@ -137,6 +134,12 @@ static void mgmtProcessMsgFromShell(SRpcMsg *rpcMsg) { return; } + if (mgmtCheckRedirect(rpcMsg->handle)) { + // rpcSendRedirectRsp(rpcMsg->handle, mgmtGetMnodeIpListForRedirect()); + rpcFreeCont(rpcMsg->pCont); + return; + } + if (!mgmtInServerStatus()) { mgmtProcessMsgWhileNotReady(rpcMsg); rpcFreeCont(rpcMsg->pCont); @@ -145,6 +148,7 @@ static void mgmtProcessMsgFromShell(SRpcMsg *rpcMsg) { if (grantCheck(TSDB_GRANT_TIME) != TSDB_CODE_SUCCESS) { mgmtSendSimpleResp(rpcMsg->handle, TSDB_CODE_GRANT_EXPIRED); + rpcFreeCont(rpcMsg->pCont); return; } @@ -154,50 +158,34 @@ static void mgmtProcessMsgFromShell(SRpcMsg *rpcMsg) { return; } - bool usePublicIp = false; - SUserObj *pUser = mgmtGetUserFromConn(rpcMsg->handle, &usePublicIp); - if (pUser == NULL) { + SQueuedMsg *pMsg = mgmtMallocQueuedMsg(rpcMsg); + if (pMsg == NULL) { mgmtSendSimpleResp(rpcMsg->handle, TSDB_CODE_INVALID_USER); rpcFreeCont(rpcMsg->pCont); return; } - - if (mgmtCheckMsgReadOnly(rpcMsg->msgType, rpcMsg->pCont)) { - SQueuedMsg queuedMsg = {0}; - queuedMsg.thandle = rpcMsg->handle; - queuedMsg.msgType = rpcMsg->msgType; - queuedMsg.contLen = rpcMsg->contLen; - queuedMsg.pCont = rpcMsg->pCont; - queuedMsg.pUser = pUser; - queuedMsg.usePublicIp = usePublicIp; - (*tsMgmtProcessShellMsgFp[rpcMsg->msgType])(&queuedMsg); - rpcFreeCont(rpcMsg->pCont); + + if (mgmtCheckMsgReadOnly(pMsg)) { + (*tsMgmtProcessShellMsgFp[rpcMsg->msgType])(pMsg); + mgmtFreeQueuedMsg(pMsg); } else { - SQueuedMsg *queuedMsg = calloc(1, sizeof(SQueuedMsg)); - queuedMsg->thandle = rpcMsg->handle; - queuedMsg->msgType = rpcMsg->msgType; - queuedMsg->contLen = rpcMsg->contLen; - queuedMsg->pCont = rpcMsg->pCont; - queuedMsg->pUser = pUser; - queuedMsg->usePublicIp = usePublicIp; - mgmtAddToShellQueue(queuedMsg); + if (!pMsg->pUser->writeAuth) { + mgmtSendSimpleResp(pMsg->thandle, TSDB_CODE_NO_RIGHTS); + mgmtFreeQueuedMsg(pMsg); + } else { + mgmtAddToShellQueue(pMsg); + } } } static void mgmtProcessShowMsg(SQueuedMsg *pMsg) { SCMShowMsg *pShowMsg = pMsg->pCont; - if (pShowMsg->type == TSDB_MGMT_TABLE_DNODE || TSDB_MGMT_TABLE_GRANTS || TSDB_MGMT_TABLE_SCORES) { - if (mgmtCheckRedirect(pMsg->thandle)) { - return; - } - } - if (pShowMsg->type >= TSDB_MGMT_TABLE_MAX) { mgmtSendSimpleResp(pMsg->thandle, TSDB_CODE_INVALID_MSG_TYPE); return; } - if (!tsMgmtShowMetaFp[pShowMsg->type]) { + if (!tsMgmtShowMetaFp[pShowMsg->type] || !tsMgmtShowRetrieveFp[pShowMsg->type]) { mError("show type:%s is not support", taosGetShowTypeStr(pShowMsg->type)); mgmtSendSimpleResp(pMsg->thandle, TSDB_CODE_OPS_NOT_SUPPORT); return; @@ -311,22 +299,13 @@ static void mgmtProcessRetrieveMsg(SQueuedMsg *pMsg) { } static void mgmtProcessHeartBeatMsg(SQueuedMsg *pMsg) { - //SCMHeartBeatMsg *pHBMsg = (SCMHeartBeatMsg *) rpcMsg->pCont; - //mgmtSaveQueryStreamList(pHBMsg); - SCMHeartBeatRsp *pHBRsp = (SCMHeartBeatRsp *) rpcMallocCont(sizeof(SCMHeartBeatRsp)); if (pHBRsp == NULL) { mgmtSendSimpleResp(pMsg->thandle, TSDB_CODE_SERV_OUT_OF_MEMORY); return; } - SRpcConnInfo connInfo; - if (rpcGetConnInfo(pMsg->thandle, &connInfo) != 0) { - mError("conn:%p is already released while process heart beat msg", pMsg->thandle); - return; - } - - if (connInfo.serverIp == tsPublicIpInt) { + if (pMsg->usePublicIp) { mgmtGetMnodePublicIpList(&pHBRsp->ipList); } else { mgmtGetMnodePrivateIpList(&pHBRsp->ipList); @@ -358,9 +337,11 @@ static int mgmtShellRetriveAuth(char *user, char *spi, char *encrypt, char *secr SUserObj *pUser = mgmtGetUser(user); if (pUser == NULL) { *secret = 0; + mgmtDecUserRef(pUser); return TSDB_CODE_INVALID_USER; } else { memcpy(secret, pUser->pass, TSDB_KEY_LEN); + mgmtDecUserRef(pUser); return TSDB_CODE_SUCCESS; } } @@ -376,28 +357,19 @@ static void mgmtProcessConnectMsg(SQueuedMsg *pMsg) { } int32_t code; - SUserObj *pUser = mgmtGetUser(connInfo.user); - if (pUser == NULL) { - code = TSDB_CODE_INVALID_USER; - goto connect_over; - } - if (grantCheck(TSDB_GRANT_TIME) != TSDB_CODE_SUCCESS) { code = TSDB_CODE_GRANT_EXPIRED; goto connect_over; } - SAcctObj *pAcct = acctGetAcct(pUser->acct); - if (pAcct == NULL) { - code = TSDB_CODE_INVALID_ACCT; - goto connect_over; - } - code = taosCheckVersion(pConnectMsg->clientVersion, version, 3); if (code != TSDB_CODE_SUCCESS) { goto connect_over; } + SUserObj *pUser = pMsg->pUser; + SAcctObj *pAcct = pUser->pAcct; + if (pConnectMsg->db[0]) { char dbName[TSDB_TABLE_ID_LEN * 3] = {0}; sprintf(dbName, "%x%s%s", pAcct->acctId, TS_PATH_DELIMITER, pConnectMsg->db); @@ -419,7 +391,7 @@ static void mgmtProcessConnectMsg(SQueuedMsg *pMsg) { pConnectRsp->writeAuth = pUser->writeAuth; pConnectRsp->superAuth = pUser->superAuth; - if (connInfo.serverIp == tsPublicIpInt) { + if (pMsg->usePublicIp) { mgmtGetMnodePublicIpList(&pConnectRsp->ipList); } else { mgmtGetMnodePrivateIpList(&pConnectRsp->ipList); @@ -443,10 +415,10 @@ static void mgmtProcessUseMsg(SQueuedMsg *pMsg) { SCMUseDbMsg *pUseDbMsg = pMsg->pCont; // todo check for priority of current user - SDbObj* pDbObj = mgmtGetDb(pUseDbMsg->db); + pMsg->pDb = mgmtGetDb(pUseDbMsg->db); int32_t code = TSDB_CODE_SUCCESS; - if (pDbObj == NULL) { + if (pMsg->pDb == NULL) { code = TSDB_CODE_INVALID_DB; } @@ -457,25 +429,29 @@ static void mgmtProcessUseMsg(SQueuedMsg *pMsg) { /** * check if we need to add mgmtProcessTableMetaMsg into tranQueue, which will be executed one-by-one. */ -static bool mgmtCheckMeterMetaMsgType(void *pMsg) { - SCMTableInfoMsg *pInfo = (SCMTableInfoMsg *) pMsg; - int16_t autoCreate = htons(pInfo->createFlag); - STableInfo *pTable = mgmtGetTable(pInfo->tableId); +static bool mgmtCheckTableMetaMsgReadOnly(SQueuedMsg *pMsg) { + SCMTableInfoMsg *pInfo = pMsg->pCont; + pMsg->pTable = mgmtGetTable(pInfo->tableId); + if (pMsg->pTable != NULL) return true; // If table does not exists and autoCreate flag is set, we add the handler into task queue - bool addIntoTranQueue = (pTable == NULL && autoCreate == 1); - if (addIntoTranQueue) { + int16_t autoCreate = htons(pInfo->createFlag); + if (autoCreate == 1) { mTrace("table:%s auto created task added", pInfo->tableId); + return false; } - - return addIntoTranQueue; + + return true; } -static bool mgmtCheckMsgReadOnly(int8_t type, void *pCont) { - if ((type == TSDB_MSG_TYPE_CM_TABLE_META && (!mgmtCheckMeterMetaMsgType(pCont))) || - type == TSDB_MSG_TYPE_CM_STABLE_VGROUP || type == TSDB_MSG_TYPE_RETRIEVE || - type == TSDB_MSG_TYPE_CM_SHOW || type == TSDB_MSG_TYPE_CM_TABLES_META || - type == TSDB_MSG_TYPE_CM_CONNECT) { +static bool mgmtCheckMsgReadOnly(SQueuedMsg *pMsg) { + if (pMsg->msgType == TSDB_MSG_TYPE_CM_TABLE_META) { + return mgmtCheckTableMetaMsgReadOnly(pMsg); + } + + if (pMsg->msgType == TSDB_MSG_TYPE_CM_STABLE_VGROUP || pMsg->msgType == TSDB_MSG_TYPE_RETRIEVE || + pMsg->msgType == TSDB_MSG_TYPE_CM_SHOW || pMsg->msgType == TSDB_MSG_TYPE_CM_TABLES_META || + pMsg->msgType == TSDB_MSG_TYPE_CM_CONNECT) { return true; } diff --git a/src/mnode/src/mgmtSuperTable.c b/src/mnode/src/mgmtSuperTable.c deleted file mode 100644 index a5e79fecf3..0000000000 --- a/src/mnode/src/mgmtSuperTable.c +++ /dev/null @@ -1,672 +0,0 @@ -/* - * Copyright (c) 2019 TAOS Data, Inc. - * - * 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. - * - * This program is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ - -#define _DEFAULT_SOURCE -#include "os.h" -#include "name.h" -#include "tsqlfunction.h" -#include "mgmtAcct.h" -#include "mgmtChildTable.h" -#include "mgmtDb.h" -#include "mgmtDClient.h" -#include "mgmtDnode.h" -#include "mgmtGrant.h" -#include "mgmtShell.h" -#include "mgmtSuperTable.h" -#include "mgmtSdb.h" -#include "mgmtTable.h" -#include "mgmtUser.h" -#include "mgmtVgroup.h" - -static void *tsSuperTableSdb; -static int32_t tsSuperTableUpdateSize; -static void mgmtProcessSuperTableVgroupMsg(SQueuedMsg *queueMsg); -static void mgmtProcessDropStableRsp(SRpcMsg *rpcMsg); -static int32_t mgmtRetrieveShowSuperTables(SShowObj *pShow, char *data, int32_t rows, void *pConn); -static int32_t mgmtGetShowSuperTableMeta(STableMetaMsg *pMeta, SShowObj *pShow, void *pConn); - -static void mgmtDestroySuperTable(SSuperTableObj *pStable) { - tfree(pStable->schema); - tfree(pStable); -} - -static int32_t mgmtSuperTableActionDestroy(SSdbOperDesc *pOper) { - mgmtDestroySuperTable(pOper->pObj); - return TSDB_CODE_SUCCESS; -} - -static int32_t mgmtSuperTableActionInsert(SSdbOperDesc *pOper) { - SSuperTableObj *pStable = pOper->pObj; - SDbObj *pDb = mgmtGetDbByTableId(pStable->info.tableId); - if (pDb != NULL) { - mgmtAddSuperTableIntoDb(pDb); - } - return TSDB_CODE_SUCCESS; -} - -static int32_t mgmtSuperTableActionDelete(SSdbOperDesc *pOper) { - SSuperTableObj *pStable = pOper->pObj; - SDbObj *pDb = mgmtGetDbByTableId(pStable->info.tableId); - if (pDb != NULL) { - mgmtRemoveSuperTableFromDb(pDb); - mgmtDropAllChildTablesInStable((SSuperTableObj *)pStable); - } - return TSDB_CODE_SUCCESS; -} - -static int32_t mgmtSuperTableActionUpdate(SSdbOperDesc *pOper) { - return TSDB_CODE_SUCCESS; -} - -static int32_t mgmtSuperTableActionEncode(SSdbOperDesc *pOper) { - SSuperTableObj *pStable = pOper->pObj; - assert(pOper->pObj != NULL && pOper->rowData != NULL); - - int32_t schemaSize = sizeof(SSchema) * (pStable->numOfColumns + pStable->numOfTags); - - if (pOper->maxRowSize < tsSuperTableUpdateSize + schemaSize) { - return TSDB_CODE_INVALID_MSG_LEN; - } - - memcpy(pOper->rowData, pStable, tsSuperTableUpdateSize); - memcpy(pOper->rowData + tsSuperTableUpdateSize, pStable->schema, schemaSize); - pOper->rowSize = tsSuperTableUpdateSize + schemaSize; - - return TSDB_CODE_SUCCESS; -} - -static int32_t mgmtSuperTableActionDecode(SSdbOperDesc *pOper) { - assert(pOper->rowData != NULL); - - SSuperTableObj *pStable = (SSuperTableObj *) calloc(1, sizeof(SSuperTableObj)); - if (pStable == NULL) return TSDB_CODE_SERV_OUT_OF_MEMORY; - - memcpy(pStable, pOper->rowData, tsSuperTableUpdateSize); - - int32_t schemaSize = sizeof(SSchema) * (pStable->numOfColumns + pStable->numOfTags); - pStable->schema = malloc(schemaSize); - if (pStable->schema == NULL) { - mgmtDestroySuperTable(pStable); - return -1; - } - - memcpy(pStable->schema, pOper->rowData + tsSuperTableUpdateSize, schemaSize); - pOper->pObj = pStable; - - return TSDB_CODE_SUCCESS; -} - -int32_t mgmtInitSuperTables() { - SSuperTableObj tObj; - tsSuperTableUpdateSize = (int8_t *)tObj.updateEnd - (int8_t *)&tObj; - - SSdbTableDesc tableDesc = { - .tableName = "stables", - .hashSessions = TSDB_MAX_SUPER_TABLES, - .maxRowSize = tsSuperTableUpdateSize + sizeof(SSchema) * TSDB_MAX_COLUMNS, - .keyType = SDB_KEY_TYPE_STRING, - .insertFp = mgmtSuperTableActionInsert, - .deleteFp = mgmtSuperTableActionDelete, - .updateFp = mgmtSuperTableActionUpdate, - .encodeFp = mgmtSuperTableActionEncode, - .decodeFp = mgmtSuperTableActionDecode, - .destroyFp = mgmtSuperTableActionDestroy, - }; - - tsSuperTableSdb = sdbOpenTable(&tableDesc); - if (tsSuperTableSdb == NULL) { - mError("failed to init stables data"); - return -1; - } - - mgmtAddShellMsgHandle(TSDB_MSG_TYPE_CM_STABLE_VGROUP, mgmtProcessSuperTableVgroupMsg); - mgmtAddShellShowMetaHandle(TSDB_MGMT_TABLE_METRIC, mgmtGetShowSuperTableMeta); - mgmtAddShellShowRetrieveHandle(TSDB_MGMT_TABLE_METRIC, mgmtRetrieveShowSuperTables); - mgmtAddDClientRspHandle(TSDB_MSG_TYPE_MD_DROP_STABLE_RSP, mgmtProcessDropStableRsp); - - mTrace("stables is initialized"); - return 0; -} - -void mgmtCleanUpSuperTables() { - sdbCloseTable(tsSuperTableSdb); -} - -void mgmtCreateSuperTable(SQueuedMsg *pMsg) { - SCMCreateTableMsg *pCreate = pMsg->pCont; - SSuperTableObj *pStable = (SSuperTableObj *)calloc(1, sizeof(SSuperTableObj)); - if (pStable == NULL) { - mgmtSendSimpleResp(pMsg->thandle, TSDB_CODE_SERV_OUT_OF_MEMORY); - return; - } - - strcpy(pStable->info.tableId, pCreate->tableId); - pStable->info.type = TSDB_SUPER_TABLE; - pStable->createdTime = taosGetTimestampMs(); - pStable->uid = (((uint64_t) pStable->createdTime) << 16) + (sdbGetVersion() & ((1ul << 16) - 1ul)); - pStable->sversion = 0; - pStable->numOfColumns = htons(pCreate->numOfColumns); - pStable->numOfTags = htons(pCreate->numOfTags); - - int32_t numOfCols = pCreate->numOfColumns + pCreate->numOfTags; - int32_t schemaSize = numOfCols * sizeof(SSchema); - pStable->schema = (SSchema *)calloc(1, schemaSize); - if (pStable->schema == NULL) { - free(pStable); - mError("stable:%s, no schema input", pCreate->tableId); - mgmtSendSimpleResp(pMsg->thandle, TSDB_CODE_INVALID_TABLE); - return; - } - memcpy(pStable->schema, pCreate->schema, numOfCols * sizeof(SSchema)); - - pStable->nextColId = 0; - for (int32_t col = 0; col < numOfCols; col++) { - SSchema *tschema = pStable->schema; - tschema[col].colId = pStable->nextColId++; - tschema[col].bytes = htons(tschema[col].bytes); - } - - SSdbOperDesc oper = { - .type = SDB_OPER_TYPE_GLOBAL, - .table = tsSuperTableSdb, - .pObj = pStable, - .rowSize = sizeof(SSuperTableObj) + schemaSize - }; - - int32_t code = sdbInsertRow(&oper); - if (code != TSDB_CODE_SUCCESS) { - mgmtDestroySuperTable(pStable); - mgmtSendSimpleResp(pMsg->thandle, TSDB_CODE_SDB_ERROR); - } else { - mLPrint("stable:%s, is created, tags:%d cols:%d", pStable->info.tableId, pStable->numOfTags, pStable->numOfColumns); - mgmtSendSimpleResp(pMsg->thandle, TSDB_CODE_SUCCESS); - } -} - -void mgmtDropSuperTable(SQueuedMsg *pMsg, SSuperTableObj *pStable) { - if (pStable->numOfTables != 0) { - mError("stable:%s, numOfTables:%d not 0", pStable->info.tableId, pStable->numOfTables); - mgmtSendSimpleResp(pMsg->thandle, TSDB_CODE_OTHERS); - } else { - SSdbOperDesc oper = { - .type = SDB_OPER_TYPE_GLOBAL, - .table = tsSuperTableSdb, - .pObj = pStable - }; - int32_t code = sdbDeleteRow(&oper); - mLPrint("stable:%s, is dropped from sdb, result:%s", pStable->info.tableId, tstrerror(code)); - mgmtSendSimpleResp(pMsg->thandle, code); - } -} - -void* mgmtGetSuperTable(char *tableId) { - return sdbGetRow(tsSuperTableSdb, tableId); -} - -static void *mgmtGetSuperTableVgroup(SSuperTableObj *pStable) { - SCMSTableVgroupRspMsg *rsp = rpcMallocCont(sizeof(SCMSTableVgroupRspMsg) + sizeof(uint32_t) * mgmtGetDnodesNum()); - rsp->numOfDnodes = htonl(1); - rsp->dnodeIps[0] = htonl(inet_addr(tsPrivateIp)); - return rsp; -} - -static int32_t mgmtFindSuperTableTagIndex(SSuperTableObj *pStable, const char *tagName) { - for (int32_t i = 0; i < pStable->numOfTags; i++) { - SSchema *schema = (SSchema *)(pStable->schema + (pStable->numOfColumns + i) * sizeof(SSchema)); - if (strcasecmp(tagName, schema->name) == 0) { - return i; - } - } - - return -1; -} - -static int32_t mgmtAddSuperTableTag(SSuperTableObj *pStable, SSchema schema[], int32_t ntags) { - if (pStable->numOfTags + ntags > TSDB_MAX_TAGS) { - return TSDB_CODE_APP_ERROR; - } - - // check if schemas have the same name - for (int32_t i = 1; i < ntags; i++) { - for (int32_t j = 0; j < i; j++) { - if (strcasecmp(schema[i].name, schema[j].name) == 0) { - return TSDB_CODE_APP_ERROR; - } - } - } - - SDbObj *pDb = mgmtGetDbByTableId(pStable->info.tableId); - if (pDb == NULL) { - mError("meter: %s not belongs to any database", pStable->info.tableId); - return TSDB_CODE_APP_ERROR; - } - - SAcctObj *pAcct = acctGetAcct(pDb->cfg.acct); - if (pAcct == NULL) { - mError("DB: %s not belongs to andy account", pDb->name); - return TSDB_CODE_APP_ERROR; - } - - int32_t schemaSize = sizeof(SSchema) * (pStable->numOfTags + pStable->numOfColumns); - pStable->schema = realloc(pStable->schema, schemaSize + sizeof(SSchema) * ntags); - - memmove(pStable->schema + sizeof(SSchema) * (pStable->numOfColumns + ntags), - pStable->schema + sizeof(SSchema) * pStable->numOfColumns, sizeof(SSchema) * pStable->numOfTags); - memcpy(pStable->schema + sizeof(SSchema) * pStable->numOfColumns, schema, sizeof(SSchema) * ntags); - - SSchema *tschema = (SSchema *) (pStable->schema + sizeof(SSchema) * pStable->numOfColumns); - for (int32_t i = 0; i < ntags; i++) { - tschema[i].colId = pStable->nextColId++; - } - - pStable->numOfColumns += ntags; - pStable->sversion++; - - pAcct->acctInfo.numOfTimeSeries += (ntags * pStable->numOfTables); - // sdbUpdateRow(tsSuperTableSdb, pStable, tsSuperTableUpdateSize, SDB_OPER_GLOBAL); - - mTrace("Succeed to add tag column %s to table %s", schema[0].name, pStable->info.tableId); - return TSDB_CODE_SUCCESS; -} - -static int32_t mgmtDropSuperTableTag(SSuperTableObj *pStable, char *tagName) { - int32_t col = mgmtFindSuperTableTagIndex(pStable, tagName); - if (col <= 0 || col >= pStable->numOfTags) { - return TSDB_CODE_APP_ERROR; - } - - SDbObj *pDb = mgmtGetDbByTableId(pStable->info.tableId); - if (pDb == NULL) { - mError("table: %s not belongs to any database", pStable->info.tableId); - return TSDB_CODE_APP_ERROR; - } - - SAcctObj *pAcct = acctGetAcct(pDb->cfg.acct); - if (pAcct == NULL) { - mError("DB: %s not belongs to any account", pDb->name); - return TSDB_CODE_APP_ERROR; - } - - memmove(pStable->schema + sizeof(SSchema) * col, pStable->schema + sizeof(SSchema) * (col + 1), - sizeof(SSchema) * (pStable->numOfColumns + pStable->numOfTags - col - 1)); - - pStable->numOfTags--; - pStable->sversion++; - - int32_t schemaSize = sizeof(SSchema) * (pStable->numOfTags + pStable->numOfColumns); - pStable->schema = realloc(pStable->schema, schemaSize); - - // sdbUpdateRow(tsSuperTableSdb, pStable, tsSuperTableUpdateSize, SDB_OPER_GLOBAL); - - return TSDB_CODE_SUCCESS; -} - -static int32_t mgmtModifySuperTableTagNameByName(SSuperTableObj *pStable, char *oldTagName, char *newTagName) { - int32_t col = mgmtFindSuperTableTagIndex(pStable, oldTagName); - if (col < 0) { - // Tag name does not exist - mError("Failed to modify table %s tag column, oname: %s, nname: %s", pStable->info.tableId, oldTagName, newTagName); - return TSDB_CODE_INVALID_MSG_TYPE; - } - - // int32_t rowSize = 0; - uint32_t len = strlen(newTagName); - - if (col >= pStable->numOfTags || len >= TSDB_COL_NAME_LEN || mgmtFindSuperTableTagIndex(pStable, newTagName) >= 0) { - return TSDB_CODE_APP_ERROR; - } - - // update - SSchema *schema = (SSchema *) (pStable->schema + (pStable->numOfColumns + col) * sizeof(SSchema)); - strncpy(schema->name, newTagName, TSDB_COL_NAME_LEN); - - // Encode string - int32_t size = 1 + sizeof(SSuperTableObj) + TSDB_MAX_BYTES_PER_ROW; - char *msg = (char *) malloc(size); - if (msg == NULL) return TSDB_CODE_APP_ERROR; - memset(msg, 0, size); - - // mgmtSuperTableActionEncode(pStable, msg, size, &rowSize); - - int32_t ret = 0; - // int32_t ret = sdbUpdateRow(tsSuperTableSdb, msg, tsSuperTableUpdateSize, SDB_OPER_GLOBAL); - tfree(msg); - - if (ret < 0) { - mError("Failed to modify table %s tag column", pStable->info.tableId); - return TSDB_CODE_APP_ERROR; - } - - mTrace("Succeed to modify table %s tag column", pStable->info.tableId); - return TSDB_CODE_SUCCESS; -} - -static int32_t mgmtFindSuperTableColumnIndex(SSuperTableObj *pStable, char *colName) { - SSchema *schema = (SSchema *) pStable->schema; - for (int32_t i = 0; i < pStable->numOfColumns; i++) { - if (strcasecmp(schema[i].name, colName) == 0) { - return i; - } - } - - return -1; -} - -static int32_t mgmtAddSuperTableColumn(SSuperTableObj *pStable, SSchema schema[], int32_t ncols) { - if (ncols <= 0) { - return TSDB_CODE_APP_ERROR; - } - - for (int32_t i = 0; i < ncols; i++) { - if (mgmtFindSuperTableColumnIndex(pStable, schema[i].name) > 0) { - return TSDB_CODE_APP_ERROR; - } - } - - SDbObj *pDb = mgmtGetDbByTableId(pStable->info.tableId); - if (pDb == NULL) { - mError("meter: %s not belongs to any database", pStable->info.tableId); - return TSDB_CODE_APP_ERROR; - } - - SAcctObj *pAcct = acctGetAcct(pDb->cfg.acct); - if (pAcct == NULL) { - mError("DB: %s not belongs to andy account", pDb->name); - return TSDB_CODE_APP_ERROR; - } - - int32_t schemaSize = sizeof(SSchema) * (pStable->numOfTags + pStable->numOfColumns); - pStable->schema = realloc(pStable->schema, schemaSize + sizeof(SSchema) * ncols); - - memmove(pStable->schema + sizeof(SSchema) * (pStable->numOfColumns + ncols), - pStable->schema + sizeof(SSchema) * pStable->numOfColumns, sizeof(SSchema) * pStable->numOfTags); - memcpy(pStable->schema + sizeof(SSchema) * pStable->numOfColumns, schema, sizeof(SSchema) * ncols); - - SSchema *tschema = (SSchema *) (pStable->schema + sizeof(SSchema) * pStable->numOfColumns); - for (int32_t i = 0; i < ncols; i++) { - tschema[i].colId = pStable->nextColId++; - } - - pStable->numOfColumns += ncols; - pStable->sversion++; - - pAcct->acctInfo.numOfTimeSeries += (ncols * pStable->numOfTables); - // sdbUpdateRow(tsSuperTableSdb, pStable, tsSuperTableUpdateSize, SDB_OPER_GLOBAL); - - return TSDB_CODE_SUCCESS; -} - -static int32_t mgmtDropSuperTableColumnByName(SSuperTableObj *pStable, char *colName) { - int32_t col = mgmtFindSuperTableColumnIndex(pStable, colName); - if (col < 0) { - return TSDB_CODE_APP_ERROR; - } - - SDbObj *pDb = mgmtGetDbByTableId(pStable->info.tableId); - if (pDb == NULL) { - mError("table: %s not belongs to any database", pStable->info.tableId); - return TSDB_CODE_APP_ERROR; - } - - SAcctObj *pAcct = acctGetAcct(pDb->cfg.acct); - if (pAcct == NULL) { - mError("DB: %s not belongs to any account", pDb->name); - return TSDB_CODE_APP_ERROR; - } - - memmove(pStable->schema + sizeof(SSchema) * col, pStable->schema + sizeof(SSchema) * (col + 1), - sizeof(SSchema) * (pStable->numOfColumns + pStable->numOfTags - col - 1)); - - pStable->numOfColumns--; - pStable->sversion++; - - int32_t schemaSize = sizeof(SSchema) * (pStable->numOfTags + pStable->numOfColumns); - pStable->schema = realloc(pStable->schema, schemaSize); - - pAcct->acctInfo.numOfTimeSeries -= (pStable->numOfTables); - // sdbUpdateRow(tsSuperTableSdb, pStable, tsSuperTableUpdateSize, SDB_OPER_GLOBAL); - - return TSDB_CODE_SUCCESS; -} - -static int32_t mgmtGetShowSuperTableMeta(STableMetaMsg *pMeta, SShowObj *pShow, void *pConn) { - SDbObj *pDb = mgmtGetDb(pShow->db); - if (pDb == NULL) { - return TSDB_CODE_DB_NOT_SELECTED; - } - - int32_t cols = 0; - SSchema *pSchema = pMeta->schema; - - pShow->bytes[cols] = TSDB_TABLE_NAME_LEN; - pSchema[cols].type = TSDB_DATA_TYPE_BINARY; - strcpy(pSchema[cols].name, "name"); - pSchema[cols].bytes = htons(pShow->bytes[cols]); - cols++; - - pShow->bytes[cols] = 8; - pSchema[cols].type = TSDB_DATA_TYPE_TIMESTAMP; - strcpy(pSchema[cols].name, "create_time"); - pSchema[cols].bytes = htons(pShow->bytes[cols]); - cols++; - - pShow->bytes[cols] = 2; - pSchema[cols].type = TSDB_DATA_TYPE_SMALLINT; - strcpy(pSchema[cols].name, "columns"); - pSchema[cols].bytes = htons(pShow->bytes[cols]); - cols++; - - pShow->bytes[cols] = 2; - pSchema[cols].type = TSDB_DATA_TYPE_SMALLINT; - strcpy(pSchema[cols].name, "tags"); - pSchema[cols].bytes = htons(pShow->bytes[cols]); - cols++; - - pShow->bytes[cols] = 4; - pSchema[cols].type = TSDB_DATA_TYPE_INT; - strcpy(pSchema[cols].name, "tables"); - pSchema[cols].bytes = htons(pShow->bytes[cols]); - cols++; - - pMeta->numOfColumns = htons(cols); - pShow->numOfColumns = cols; - - pShow->offset[0] = 0; - for (int32_t i = 1; i < cols; ++i) pShow->offset[i] = pShow->offset[i - 1] + pShow->bytes[i - 1]; - - pShow->numOfRows = pDb->numOfSuperTables; - pShow->rowSize = pShow->offset[cols - 1] + pShow->bytes[cols - 1]; - - return 0; -} - -int32_t mgmtRetrieveShowSuperTables(SShowObj *pShow, char *data, int32_t rows, void *pConn) { - int32_t numOfRows = 0; - char * pWrite; - int32_t cols = 0; - SSuperTableObj *pTable = NULL; - char prefix[20] = {0}; - int32_t prefixLen; - - SDbObj *pDb = mgmtGetDb(pShow->db); - if (pDb == NULL) return 0; - - SUserObj *pUser = mgmtGetUserFromConn(pConn, NULL); - - if (mgmtCheckIsMonitorDB(pDb->name, tsMonitorDbName)) { - if (strcmp(pUser->user, "root") != 0 && strcmp(pUser->user, "_root") != 0 && strcmp(pUser->user, "monitor") != 0 ) { - return 0; - } - } - - strcpy(prefix, pDb->name); - strcat(prefix, TS_PATH_DELIMITER); - prefixLen = strlen(prefix); - - SPatternCompareInfo info = PATTERN_COMPARE_INFO_INITIALIZER; - char stableName[TSDB_TABLE_NAME_LEN] = {0}; - - while (numOfRows < rows) { - pShow->pNode = sdbFetchRow(tsSuperTableSdb, pShow->pNode, (void **) &pTable); - if (pTable == NULL) break; - if (strncmp(pTable->info.tableId, prefix, prefixLen)) { - continue; - } - - memset(stableName, 0, tListLen(stableName)); - mgmtExtractTableName(pTable->info.tableId, stableName); - - if (pShow->payloadLen > 0 && - patternMatch(pShow->payload, stableName, TSDB_TABLE_NAME_LEN, &info) != TSDB_PATTERN_MATCH) - continue; - - cols = 0; - - pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows; - strncpy(pWrite, stableName, TSDB_TABLE_NAME_LEN); - cols++; - - pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows; - *(int64_t *)pWrite = pTable->createdTime; - cols++; - - pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows; - *(int16_t *)pWrite = pTable->numOfColumns; - cols++; - - pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows; - *(int16_t *)pWrite = pTable->numOfTags; - cols++; - - pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows; - *(int32_t *)pWrite = pTable->numOfTables; - cols++; - - numOfRows++; - } - - pShow->numOfReads += numOfRows; - return numOfRows; -} - -void mgmtDropAllSuperTables(SDbObj *pDropDb) { - void *pNode = NULL; - void *pLastNode = NULL; - int32_t numOfTables = 0; - int32_t dbNameLen = strlen(pDropDb->name); - SSuperTableObj *pTable = NULL; - - while (1) { - pNode = sdbFetchRow(tsSuperTableSdb, pNode, (void **)&pTable); - if (pTable == NULL) { - break; - } - - if (strncmp(pDropDb->name, pTable->info.tableId, dbNameLen) == 0) { - SSdbOperDesc oper = { - .type = SDB_OPER_TYPE_LOCAL, - .table = tsSuperTableSdb, - .pObj = pTable, - }; - sdbDeleteRow(&oper); - pNode = pLastNode; - numOfTables ++; - continue; - } - } - - mTrace("db:%s, all super tables:%d is dropped from sdb", pDropDb->name, numOfTables); -} - -int32_t mgmtSetSchemaFromSuperTable(SSchema *pSchema, SSuperTableObj *pTable) { - int32_t numOfCols = pTable->numOfColumns + pTable->numOfTags; - for (int32_t i = 0; i < numOfCols; ++i) { - strcpy(pSchema->name, pTable->schema[i].name); - pSchema->type = pTable->schema[i].type; - pSchema->bytes = htons(pTable->schema[i].bytes); - pSchema->colId = htons(pTable->schema[i].colId); - pSchema++; - } - - return (pTable->numOfColumns + pTable->numOfTags) * sizeof(SSchema); -} - -void mgmtGetSuperTableMeta(SQueuedMsg *pMsg, SSuperTableObj *pTable) { - SDbObj *pDb = pMsg->pDb; - - STableMetaMsg *pMeta = rpcMallocCont(sizeof(STableMetaMsg) + sizeof(SSchema) * TSDB_MAX_COLUMNS); - pMeta->uid = htobe64(pTable->uid); - pMeta->sversion = htons(pTable->sversion); - pMeta->precision = pDb->cfg.precision; - pMeta->numOfTags = (uint8_t)pTable->numOfTags; - pMeta->numOfColumns = htons((int16_t)pTable->numOfColumns); - pMeta->tableType = pTable->info.type; - pMeta->contLen = sizeof(STableMetaMsg) + mgmtSetSchemaFromSuperTable(pMeta->schema, pTable); - strcpy(pMeta->tableId, pTable->info.tableId); - - SRpcMsg rpcRsp = { - .handle = pMsg->thandle, - .pCont = pMeta, - .contLen = pMeta->contLen, - }; - pMeta->contLen = htons(pMeta->contLen); - rpcSendResponse(&rpcRsp); - - mTrace("stable:%%s, uid:%" PRIu64 " table meta is retrieved", pTable->info.tableId, pTable->uid); -} - -static void mgmtProcessSuperTableVgroupMsg(SQueuedMsg *pMsg) { - SCMSTableVgroupMsg *pInfo = pMsg->pCont; - STableInfo *pTable = mgmtGetSuperTable(pInfo->tableId); - if (pTable == NULL) { - mgmtSendSimpleResp(pMsg->thandle, TSDB_CODE_INVALID_TABLE); - return; - } - - SCMSTableVgroupRspMsg *pRsp = mgmtGetSuperTableVgroup((SSuperTableObj *) pTable); - if (pRsp != NULL) { - int32_t msgLen = sizeof(SSuperTableObj) + htonl(pRsp->numOfDnodes) * sizeof(int32_t); - SRpcMsg rpcRsp = {0}; - rpcRsp.handle = pMsg->thandle; - rpcRsp.pCont = pRsp; - rpcRsp.contLen = msgLen; - rpcSendResponse(&rpcRsp); - } else { - mgmtSendSimpleResp(pMsg->thandle, TSDB_CODE_INVALID_TABLE); - } -} - -void mgmtAlterSuperTable(SQueuedMsg *pMsg, SSuperTableObj *pTable) { - int32_t code = TSDB_CODE_OPS_NOT_SUPPORT; - SCMAlterTableMsg *pAlter = pMsg->pCont; - - if (pAlter->type == TSDB_ALTER_TABLE_ADD_TAG_COLUMN) { - code = mgmtAddSuperTableTag((SSuperTableObj *) pTable, pAlter->schema, 1); - } else if (pAlter->type == TSDB_ALTER_TABLE_DROP_TAG_COLUMN) { - code = mgmtDropSuperTableTag((SSuperTableObj *) pTable, pAlter->schema[0].name); - } else if (pAlter->type == TSDB_ALTER_TABLE_CHANGE_TAG_COLUMN) { - code = mgmtModifySuperTableTagNameByName((SSuperTableObj *) pTable, pAlter->schema[0].name, pAlter->schema[1].name); - } else if (pAlter->type == TSDB_ALTER_TABLE_ADD_COLUMN) { - code = mgmtAddSuperTableColumn((SSuperTableObj *) pTable, pAlter->schema, 1); - } else if (pAlter->type == TSDB_ALTER_TABLE_DROP_COLUMN) { - code = mgmtDropSuperTableColumnByName((SSuperTableObj *) pTable, pAlter->schema[0].name); - } else {} - - mgmtSendSimpleResp(pMsg->thandle, code); -} - -static void mgmtProcessDropStableRsp(SRpcMsg *rpcMsg) { - mTrace("drop stable rsp received, handle:%p code:%d", rpcMsg->handle, rpcMsg->code); -} \ No newline at end of file diff --git a/src/mnode/src/mgmtTable.c b/src/mnode/src/mgmtTable.c index 5169f4a817..492ceeff05 100644 --- a/src/mnode/src/mgmtTable.c +++ b/src/mnode/src/mgmtTable.c @@ -15,8 +15,23 @@ #define _DEFAULT_SOURCE #include "os.h" +#include "taosmsg.h" +#include "tscompression.h" +#include "tskiplist.h" +#include "ttime.h" +#include "tstatus.h" +#include "tutil.h" +#include "qast.h" +#include "qextbuffer.h" +#include "taoserror.h" +#include "taosmsg.h" +#include "tscompression.h" +#include "tskiplist.h" +#include "tsqlfunction.h" +#include "tstatus.h" +#include "ttime.h" +#include "name.h" #include "mgmtAcct.h" -#include "mgmtChildTable.h" #include "mgmtDClient.h" #include "mgmtDb.h" #include "mgmtDnode.h" @@ -26,14 +41,409 @@ #include "mgmtProfile.h" #include "mgmtSdb.h" #include "mgmtShell.h" -#include "mgmtSuperTable.h" #include "mgmtTable.h" #include "mgmtUser.h" +#include "mgmtVgroup.h" + +void * tsChildTableSdb; +void * tsSuperTableSdb; +static int32_t tsChildTableUpdateSize; +static int32_t tsSuperTableUpdateSize; +static void * mgmtGetChildTable(char *tableId); +static void * mgmtGetSuperTable(char *tableId); +static void mgmtDropAllChildTablesInStable(SSuperTableObj *pStable); +static int32_t mgmtGetShowTableMeta(STableMetaMsg *pMeta, SShowObj *pShow, void *pConn); +static int32_t mgmtRetrieveShowTables(SShowObj *pShow, char *data, int32_t rows, void *pConn); +static int32_t mgmtRetrieveShowSuperTables(SShowObj *pShow, char *data, int32_t rows, void *pConn); +static int32_t mgmtGetShowSuperTableMeta(STableMetaMsg *pMeta, SShowObj *pShow, void *pConn); static void mgmtProcessCreateTableMsg(SQueuedMsg *queueMsg); +static void mgmtProcessCreateSuperTableMsg(SQueuedMsg *pMsg); +static void mgmtProcessCreateChildTableMsg(SQueuedMsg *pMsg); +static void mgmtProcessCreateChildTableRsp(SRpcMsg *rpcMsg); + static void mgmtProcessDropTableMsg(SQueuedMsg *queueMsg); -static void mgmtProcessAlterTableMsg(SQueuedMsg *queueMsg); +static void mgmtProcessDropSuperTableMsg(SQueuedMsg *pMsg); +static void mgmtProcessDropSuperTableRsp(SRpcMsg *rpcMsg); +static void mgmtProcessDropChildTableMsg(SQueuedMsg *pMsg); +static void mgmtProcessDropChildTableRsp(SRpcMsg *rpcMsg); + +static void mgmtProcessSuperTableVgroupMsg(SQueuedMsg *queueMsg); +static void mgmtProcessMultiTableMetaMsg(SQueuedMsg *queueMsg); +static void mgmtProcessTableCfgMsg(SRpcMsg *rpcMsg); + static void mgmtProcessTableMetaMsg(SQueuedMsg *queueMsg); +static void mgmtGetSuperTableMeta(SQueuedMsg *pMsg); +static void mgmtGetChildTableMeta(SQueuedMsg *pMsg); + +static void mgmtProcessAlterTableMsg(SQueuedMsg *queueMsg); +static void mgmtProcessAlterTableRsp(SRpcMsg *rpcMsg); + +static void mgmtDestroyChildTable(SChildTableObj *pTable) { + tfree(pTable->schema); + tfree(pTable->sql); + tfree(pTable); +} + +static int32_t mgmtChildTableActionDestroy(SSdbOperDesc *pOper) { + mgmtDestroyChildTable(pOper->pObj); + return TSDB_CODE_SUCCESS; +} + +static int32_t mgmtChildTableActionInsert(SSdbOperDesc *pOper) { + SChildTableObj *pTable = pOper->pObj; + + SVgObj *pVgroup = mgmtGetVgroup(pTable->vgId); + if (pVgroup == NULL) { + mError("ctable:%s, not in vgroup:%d", pTable->info.tableId, pTable->vgId); + return TSDB_CODE_INVALID_VGROUP_ID; + } + mgmtDecVgroupRef(pVgroup); + + SDbObj *pDb = mgmtGetDb(pVgroup->dbName); + if (pDb == NULL) { + mError("ctable:%s, vgroup:%d not in db:%s", pTable->info.tableId, pVgroup->vgId, pVgroup->dbName); + return TSDB_CODE_INVALID_DB; + } + mgmtDecDbRef(pDb); + + SAcctObj *pAcct = acctGetAcct(pDb->cfg.acct); + if (pAcct == NULL) { + mError("ctable:%s, account:%s not exists", pTable->info.tableId, pDb->cfg.acct); + return TSDB_CODE_INVALID_ACCT; + } + acctDecRef(pAcct); + + if (pTable->info.type == TSDB_CHILD_TABLE) { + pTable->superTable = mgmtGetSuperTable(pTable->superTableId); + pTable->superTable->numOfTables++; + grantAdd(TSDB_GRANT_TIMESERIES, pTable->superTable->numOfColumns - 1); + pAcct->acctInfo.numOfTimeSeries += (pTable->superTable->numOfColumns - 1); + } else { + grantAdd(TSDB_GRANT_TIMESERIES, pTable->numOfColumns - 1); + pAcct->acctInfo.numOfTimeSeries += (pTable->numOfColumns - 1); + } + + mgmtAddTableIntoDb(pDb); + mgmtAddTableIntoVgroup(pVgroup, pTable); + + return TSDB_CODE_SUCCESS; +} + +static int32_t mgmtChildTableActionDelete(SSdbOperDesc *pOper) { + SChildTableObj *pTable = pOper->pObj; + if (pTable->vgId == 0) { + return TSDB_CODE_INVALID_VGROUP_ID; + } + + SVgObj *pVgroup = mgmtGetVgroup(pTable->vgId); + if (pVgroup == NULL) { + return TSDB_CODE_INVALID_VGROUP_ID; + } + mgmtDecVgroupRef(pVgroup); + + SDbObj *pDb = mgmtGetDb(pVgroup->dbName); + if (pDb == NULL) { + mError("ctable:%s, vgroup:%d not in DB:%s", pTable->info.tableId, pVgroup->vgId, pVgroup->dbName); + return TSDB_CODE_INVALID_DB; + } + mgmtDecDbRef(pDb); + + SAcctObj *pAcct = acctGetAcct(pDb->cfg.acct); + if (pAcct == NULL) { + mError("ctable:%s, account:%s not exists", pTable->info.tableId, pDb->cfg.acct); + return TSDB_CODE_INVALID_ACCT; + } + acctDecRef(pAcct); + + if (pTable->info.type == TSDB_CHILD_TABLE) { + grantRestore(TSDB_GRANT_TIMESERIES, pTable->superTable->numOfColumns - 1); + pAcct->acctInfo.numOfTimeSeries -= (pTable->superTable->numOfColumns - 1); + pTable->superTable->numOfTables--; + mgmtDecTableRef(pTable->superTable); + } else { + grantRestore(TSDB_GRANT_TIMESERIES, pTable->numOfColumns - 1); + pAcct->acctInfo.numOfTimeSeries -= (pTable->numOfColumns - 1); + } + mgmtRemoveTableFromDb(pDb); + mgmtRemoveTableFromVgroup(pVgroup, pTable); + + return TSDB_CODE_SUCCESS; +} + +static int32_t mgmtChildTableActionUpdate(SSdbOperDesc *pOper) { + return TSDB_CODE_SUCCESS; +} + +static int32_t mgmtChildTableActionEncode(SSdbOperDesc *pOper) { + SChildTableObj *pTable = pOper->pObj; + assert(pTable != NULL && pOper->rowData != NULL); + + if (pTable->info.type == TSDB_CHILD_TABLE) { + memcpy(pOper->rowData, pTable, tsChildTableUpdateSize); + pOper->rowSize = tsChildTableUpdateSize; + } else { + int32_t schemaSize = pTable->numOfColumns * sizeof(SSchema); + if (pOper->maxRowSize < tsChildTableUpdateSize + schemaSize) { + return TSDB_CODE_INVALID_MSG_LEN; + } + memcpy(pOper->rowData, pTable, tsChildTableUpdateSize); + memcpy(pOper->rowData + tsChildTableUpdateSize, pTable->schema, schemaSize); + memcpy(pOper->rowData + tsChildTableUpdateSize + schemaSize, pTable->sql, pTable->sqlLen); + pOper->rowSize = tsChildTableUpdateSize + schemaSize + pTable->sqlLen; + } + + return TSDB_CODE_SUCCESS; +} + +static int32_t mgmtChildTableActionDecode(SSdbOperDesc *pOper) { + assert(pOper->rowData != NULL); + SChildTableObj *pTable = calloc(1, sizeof(SChildTableObj)); + if (pTable == NULL) { + return TSDB_CODE_SERV_OUT_OF_MEMORY; + } + + memcpy(pTable, pOper->rowData, tsChildTableUpdateSize); + + if (pTable->info.type != TSDB_CHILD_TABLE) { + int32_t schemaSize = pTable->numOfColumns * sizeof(SSchema); + pTable->schema = (SSchema *)malloc(schemaSize); + if (pTable->schema == NULL) { + mgmtDestroyChildTable(pTable); + return TSDB_CODE_SERV_OUT_OF_MEMORY; + } + memcpy(pTable->schema, pOper->rowData + tsChildTableUpdateSize, schemaSize); + + pTable->sql = (char *)malloc(pTable->sqlLen); + if (pTable->sql == NULL) { + mgmtDestroyChildTable(pTable); + return TSDB_CODE_SERV_OUT_OF_MEMORY; + } + memcpy(pTable->sql, pOper->rowData + tsChildTableUpdateSize + schemaSize, pTable->sqlLen); + } + + pOper->pObj = pTable; + return TSDB_CODE_SUCCESS; +} + +static int32_t mgmtInitChildTables() { + void *pNode = NULL; + void *pLastNode = NULL; + SChildTableObj *pTable = NULL; + + SChildTableObj tObj; + tsChildTableUpdateSize = (int8_t *)tObj.updateEnd - (int8_t *)&tObj; + + SSdbTableDesc tableDesc = { + .tableName = "ctables", + .hashSessions = tsMaxTables, + .maxRowSize = sizeof(SChildTableObj) + sizeof(SSchema) * TSDB_MAX_COLUMNS, + .refCountPos = (int8_t *)(&tObj.refCount) - (int8_t *)&tObj, + .keyType = SDB_KEY_TYPE_STRING, + .insertFp = mgmtChildTableActionInsert, + .deleteFp = mgmtChildTableActionDelete, + .updateFp = mgmtChildTableActionUpdate, + .encodeFp = mgmtChildTableActionEncode, + .decodeFp = mgmtChildTableActionDecode, + .destroyFp = mgmtChildTableActionDestroy, + }; + + tsChildTableSdb = sdbOpenTable(&tableDesc); + if (tsChildTableSdb == NULL) { + mError("failed to init child table data"); + return -1; + } + + pNode = NULL; + while (1) { + pLastNode = pNode; + mgmtDecTableRef(pTable); + pNode = sdbFetchRow(tsChildTableSdb, pNode, (void **)&pTable); + if (pTable == NULL) break; + + SDbObj *pDb = mgmtGetDbByTableId(pTable->info.tableId); + if (pDb == NULL) { + mError("ctable:%s, failed to get db, discard it", pTable->info.tableId); + SSdbOperDesc desc = {0}; + desc.type = SDB_OPER_TYPE_LOCAL; + desc.pObj = pTable; + desc.table = tsChildTableSdb; + sdbDeleteRow(&desc); + pNode = pLastNode; + continue; + } + mgmtDecDbRef(pDb); + + SVgObj *pVgroup = mgmtGetVgroup(pTable->vgId); + if (pVgroup == NULL) { + mError("ctable:%s, failed to get vgroup:%d sid:%d, discard it", pTable->info.tableId, pTable->vgId, pTable->sid); + pTable->vgId = 0; + SSdbOperDesc desc = {0}; + desc.type = SDB_OPER_TYPE_LOCAL; + desc.pObj = pTable; + desc.table = tsChildTableSdb; + sdbDeleteRow(&desc); + pNode = pLastNode; + continue; + } + mgmtDecVgroupRef(pVgroup); + + if (strcmp(pVgroup->dbName, pDb->name) != 0) { + mError("ctable:%s, db:%s not match with vgroup:%d db:%s sid:%d, discard it", + pTable->info.tableId, pDb->name, pTable->vgId, pVgroup->dbName, pTable->sid); + pTable->vgId = 0; + SSdbOperDesc desc = {0}; + desc.type = SDB_OPER_TYPE_LOCAL; + desc.pObj = pTable; + desc.table = tsChildTableSdb; + sdbDeleteRow(&desc); + pNode = pLastNode; + continue; + } + + if (pVgroup->tableList == NULL) { + mError("ctable:%s, vgroup:%d tableList is null", pTable->info.tableId, pTable->vgId); + pTable->vgId = 0; + SSdbOperDesc desc = {0}; + desc.type = SDB_OPER_TYPE_LOCAL; + desc.pObj = pTable; + desc.table = tsChildTableSdb; + sdbDeleteRow(&desc); + pNode = pLastNode; + continue; + } + + if (pTable->info.type == TSDB_CHILD_TABLE) { + SSuperTableObj *pSuperTable = mgmtGetSuperTable(pTable->superTableId); + if (pSuperTable == NULL) { + mError("ctable:%s, stable:%s not exist", pTable->info.tableId, pTable->superTableId); + pTable->vgId = 0; + SSdbOperDesc desc = {0}; + desc.type = SDB_OPER_TYPE_LOCAL; + desc.pObj = pTable; + desc.table = tsChildTableSdb; + sdbDeleteRow(&desc); + pNode = pLastNode; + continue; + } + mgmtDecTableRef(pSuperTable); + } + } + + mTrace("child table is initialized"); + return 0; +} + +static void mgmtCleanUpChildTables() { + sdbCloseTable(tsChildTableSdb); +} + +static void mgmtDestroySuperTable(SSuperTableObj *pStable) { + tfree(pStable->schema); + tfree(pStable); +} + +static int32_t mgmtSuperTableActionDestroy(SSdbOperDesc *pOper) { + mgmtDestroySuperTable(pOper->pObj); + return TSDB_CODE_SUCCESS; +} + +static int32_t mgmtSuperTableActionInsert(SSdbOperDesc *pOper) { + SSuperTableObj *pStable = pOper->pObj; + SDbObj *pDb = mgmtGetDbByTableId(pStable->info.tableId); + if (pDb != NULL) { + mgmtAddSuperTableIntoDb(pDb); + } + mgmtDecDbRef(pDb); + + return TSDB_CODE_SUCCESS; +} + +static int32_t mgmtSuperTableActionDelete(SSdbOperDesc *pOper) { + SSuperTableObj *pStable = pOper->pObj; + SDbObj *pDb = mgmtGetDbByTableId(pStable->info.tableId); + if (pDb != NULL) { + mgmtRemoveSuperTableFromDb(pDb); + mgmtDropAllChildTablesInStable((SSuperTableObj *)pStable); + } + mgmtDecDbRef(pDb); + + return TSDB_CODE_SUCCESS; +} + +static int32_t mgmtSuperTableActionUpdate(SSdbOperDesc *pOper) { + return TSDB_CODE_SUCCESS; +} + +static int32_t mgmtSuperTableActionEncode(SSdbOperDesc *pOper) { + SSuperTableObj *pStable = pOper->pObj; + assert(pOper->pObj != NULL && pOper->rowData != NULL); + + int32_t schemaSize = sizeof(SSchema) * (pStable->numOfColumns + pStable->numOfTags); + + if (pOper->maxRowSize < tsSuperTableUpdateSize + schemaSize) { + return TSDB_CODE_INVALID_MSG_LEN; + } + + memcpy(pOper->rowData, pStable, tsSuperTableUpdateSize); + memcpy(pOper->rowData + tsSuperTableUpdateSize, pStable->schema, schemaSize); + pOper->rowSize = tsSuperTableUpdateSize + schemaSize; + + return TSDB_CODE_SUCCESS; +} + +static int32_t mgmtSuperTableActionDecode(SSdbOperDesc *pOper) { + assert(pOper->rowData != NULL); + + SSuperTableObj *pStable = (SSuperTableObj *) calloc(1, sizeof(SSuperTableObj)); + if (pStable == NULL) return TSDB_CODE_SERV_OUT_OF_MEMORY; + + memcpy(pStable, pOper->rowData, tsSuperTableUpdateSize); + + int32_t schemaSize = sizeof(SSchema) * (pStable->numOfColumns + pStable->numOfTags); + pStable->schema = malloc(schemaSize); + if (pStable->schema == NULL) { + mgmtDestroySuperTable(pStable); + return -1; + } + + memcpy(pStable->schema, pOper->rowData + tsSuperTableUpdateSize, schemaSize); + pOper->pObj = pStable; + + return TSDB_CODE_SUCCESS; +} + +static int32_t mgmtInitSuperTables() { + SSuperTableObj tObj; + tsSuperTableUpdateSize = (int8_t *)tObj.updateEnd - (int8_t *)&tObj; + + SSdbTableDesc tableDesc = { + .tableName = "stables", + .hashSessions = TSDB_MAX_SUPER_TABLES, + .maxRowSize = tsSuperTableUpdateSize + sizeof(SSchema) * TSDB_MAX_COLUMNS, + .refCountPos = (int8_t *)(&tObj.refCount) - (int8_t *)&tObj, + .keyType = SDB_KEY_TYPE_STRING, + .insertFp = mgmtSuperTableActionInsert, + .deleteFp = mgmtSuperTableActionDelete, + .updateFp = mgmtSuperTableActionUpdate, + .encodeFp = mgmtSuperTableActionEncode, + .decodeFp = mgmtSuperTableActionDecode, + .destroyFp = mgmtSuperTableActionDestroy, + }; + + tsSuperTableSdb = sdbOpenTable(&tableDesc); + if (tsSuperTableSdb == NULL) { + mError("failed to init stables data"); + return -1; + } + + mTrace("stables is initialized"); + return 0; +} + +static void mgmtCleanUpSuperTables() { + sdbCloseTable(tsSuperTableSdb); +} int32_t mgmtInitTables() { int32_t code = mgmtInitSuperTables(); @@ -46,21 +456,43 @@ int32_t mgmtInitTables() { return code; } + mgmtAddShellMsgHandle(TSDB_MSG_TYPE_CM_TABLES_META, mgmtProcessMultiTableMetaMsg); mgmtAddShellMsgHandle(TSDB_MSG_TYPE_CM_CREATE_TABLE, mgmtProcessCreateTableMsg); mgmtAddShellMsgHandle(TSDB_MSG_TYPE_CM_DROP_TABLE, mgmtProcessDropTableMsg); mgmtAddShellMsgHandle(TSDB_MSG_TYPE_CM_ALTER_TABLE, mgmtProcessAlterTableMsg); mgmtAddShellMsgHandle(TSDB_MSG_TYPE_CM_TABLE_META, mgmtProcessTableMetaMsg); + mgmtAddShellMsgHandle(TSDB_MSG_TYPE_CM_STABLE_VGROUP, mgmtProcessSuperTableVgroupMsg); + + mgmtAddDClientRspHandle(TSDB_MSG_TYPE_MD_CREATE_TABLE_RSP, mgmtProcessCreateChildTableRsp); + mgmtAddDClientRspHandle(TSDB_MSG_TYPE_MD_DROP_TABLE_RSP, mgmtProcessDropChildTableRsp); + mgmtAddDClientRspHandle(TSDB_MSG_TYPE_MD_DROP_STABLE_RSP, mgmtProcessDropSuperTableRsp); + mgmtAddDClientRspHandle(TSDB_MSG_TYPE_MD_ALTER_TABLE_RSP, mgmtProcessAlterTableRsp); + mgmtAddDServerMsgHandle(TSDB_MSG_TYPE_DM_CONFIG_TABLE, mgmtProcessTableCfgMsg); + + mgmtAddShellShowMetaHandle(TSDB_MGMT_TABLE_TABLE, mgmtGetShowTableMeta); + mgmtAddShellShowRetrieveHandle(TSDB_MGMT_TABLE_TABLE, mgmtRetrieveShowTables); + mgmtAddShellShowMetaHandle(TSDB_MGMT_TABLE_METRIC, mgmtGetShowSuperTableMeta); + mgmtAddShellShowRetrieveHandle(TSDB_MGMT_TABLE_METRIC, mgmtRetrieveShowSuperTables); + return TSDB_CODE_SUCCESS; } +static void *mgmtGetChildTable(char *tableId) { + return sdbGetRow(tsChildTableSdb, tableId); +} + +static void *mgmtGetSuperTable(char *tableId) { + return sdbGetRow(tsSuperTableSdb, tableId); +} + STableInfo *mgmtGetTable(char *tableId) { - STableInfo *tableInfo = mgmtGetSuperTable(tableId); + STableInfo *tableInfo = sdbGetRow(tsSuperTableSdb, tableId); if (tableInfo != NULL) { return tableInfo; } - tableInfo = mgmtGetChildTable(tableId); + tableInfo = sdbGetRow(tsChildTableSdb, tableId); if (tableInfo != NULL) { return tableInfo; } @@ -68,12 +500,32 @@ STableInfo *mgmtGetTable(char *tableId) { return NULL; } +void mgmtIncTableRef(void *p1) { + STableInfo *pTable = (STableInfo *)p1; + if (pTable->type == TSDB_SUPER_TABLE) { + sdbIncRef(tsSuperTableSdb, pTable); + } else { + sdbIncRef(tsChildTableSdb, pTable); + } +} + +void mgmtDecTableRef(void *p1) { + if (p1 == NULL) return; + + STableInfo *pTable = (STableInfo *)p1; + if (pTable->type == TSDB_SUPER_TABLE) { + sdbDecRef(tsSuperTableSdb, pTable); + } else { + sdbDecRef(tsChildTableSdb, pTable); + } +} + void mgmtCleanUpTables() { mgmtCleanUpChildTables(); mgmtCleanUpSuperTables(); } -void mgmtExtractTableName(char* tableId, char* name) { +static void mgmtExtractTableName(char* tableId, char* name) { int pos = -1; int num = 0; for (pos = 0; tableId[pos] != 0; ++pos) { @@ -88,13 +540,16 @@ void mgmtExtractTableName(char* tableId, char* name) { static void mgmtProcessCreateTableMsg(SQueuedMsg *pMsg) { SCMCreateTableMsg *pCreate = pMsg->pCont; - mTrace("table:%s, create msg is received from thandle:%p", pCreate->tableId, pMsg->thandle); - - if (mgmtCheckRedirect(pMsg->thandle)) return; - - if (!pMsg->pUser->writeAuth) { - mError("table:%s, failed to create, no rights", pCreate->tableId); - mgmtSendSimpleResp(pMsg->thandle, TSDB_CODE_NO_RIGHTS); + + pMsg->pTable = mgmtGetTable(pCreate->tableId); + if (pMsg->pTable != NULL) { + if (pCreate->igExists) { + mTrace("table:%s, is already exist", pCreate->tableId); + mgmtSendSimpleResp(pMsg->thandle, TSDB_CODE_SUCCESS); + } else { + mError("table:%s, failed to create, table already exist", pCreate->tableId); + mgmtSendSimpleResp(pMsg->thandle, TSDB_CODE_TABLE_ALREADY_EXIST); + } return; } @@ -105,40 +560,17 @@ static void mgmtProcessCreateTableMsg(SQueuedMsg *pMsg) { return; } - STableInfo *pTable = mgmtGetTable(pCreate->tableId); - if (pTable != NULL) { - if (pCreate->igExists) { - mTrace("table:%s is already exist", pCreate->tableId); - mgmtSendSimpleResp(pMsg->thandle, TSDB_CODE_SUCCESS); - return; - } else { - mError("table:%s, failed to create, table already exist", pCreate->tableId); - mgmtSendSimpleResp(pMsg->thandle, TSDB_CODE_TABLE_ALREADY_EXIST); - return; - } - } - if (pCreate->numOfTags != 0) { - mTrace("table:%s, is a stable", pCreate->tableId); - mgmtCreateSuperTable(pMsg); + mTrace("table:%s, create msg is received from thandle:%p", pCreate->tableId, pMsg->thandle); + mgmtProcessCreateSuperTableMsg(pMsg); } else { - mTrace("table:%s, is a ctable", pCreate->tableId); - mgmtCreateChildTable(pMsg); + mTrace("table:%s, create msg is received from thandle:%p", pCreate->tableId, pMsg->thandle); + mgmtProcessCreateChildTableMsg(pMsg); } } static void mgmtProcessDropTableMsg(SQueuedMsg *pMsg) { SCMDropTableMsg *pDrop = pMsg->pCont; - mTrace("table:%s, drop table msg is received from thandle:%p", pDrop->tableId, pMsg->thandle); - - if (mgmtCheckRedirect(pMsg->thandle)) return; - - if (!pMsg->pUser->writeAuth) { - mError("table:%s, failed to drop, no rights", pDrop->tableId); - mgmtSendSimpleResp(pMsg->thandle, TSDB_CODE_NO_RIGHTS); - return; - } - pMsg->pDb = mgmtGetDbByTableId(pDrop->tableId); if (pMsg->pDb == NULL || pMsg->pDb->dirty) { mError("table:%s, failed to drop table, db not selected", pDrop->tableId); @@ -152,8 +584,8 @@ static void mgmtProcessDropTableMsg(SQueuedMsg *pMsg) { return; } - STableInfo *pTable = mgmtGetTable(pDrop->tableId); - if (pTable == NULL) { + pMsg->pTable = mgmtGetTable(pDrop->tableId); + if (pMsg->pTable == NULL) { if (pDrop->igNotExists) { mTrace("table:%s, table is not exist, think drop success", pDrop->tableId); mgmtSendSimpleResp(pMsg->thandle, TSDB_CODE_SUCCESS); @@ -165,27 +597,1357 @@ static void mgmtProcessDropTableMsg(SQueuedMsg *pMsg) { } } - if (pTable->type == TSDB_SUPER_TABLE) { + if (pMsg->pTable->type == TSDB_SUPER_TABLE) { mTrace("table:%s, start to drop stable", pDrop->tableId); - mgmtDropSuperTable(pMsg, (SSuperTableObj *)pTable); + mgmtProcessDropSuperTableMsg(pMsg); } else { mTrace("table:%s, start to drop ctable", pDrop->tableId); - mgmtDropChildTable(pMsg, (SChildTableObj *)pTable); + mgmtProcessDropChildTableMsg(pMsg); } } +static void mgmtProcessTableMetaMsg(SQueuedMsg *pMsg) { + SCMTableInfoMsg *pInfo = pMsg->pCont; + mTrace("table:%s, table meta msg is received from thandle:%p", pInfo->tableId, pMsg->thandle); + + pMsg->pDb = mgmtGetDbByTableId(pInfo->tableId); + if (pMsg->pDb == NULL || pMsg->pDb->dirty) { + mError("table:%s, failed to get table meta, db not selected", pInfo->tableId); + mgmtSendSimpleResp(pMsg->thandle, TSDB_CODE_DB_NOT_SELECTED); + return; + } + + if (pMsg->pTable == NULL) { + mgmtGetChildTableMeta(pMsg); + } else { + if (pMsg->pTable->type != TSDB_SUPER_TABLE) { + mgmtGetChildTableMeta(pMsg); + } else { + mgmtGetSuperTableMeta(pMsg); + } + } +} + +static void mgmtProcessCreateSuperTableMsg(SQueuedMsg *pMsg) { + SCMCreateTableMsg *pCreate = pMsg->pCont; + SSuperTableObj *pStable = (SSuperTableObj *)calloc(1, sizeof(SSuperTableObj)); + if (pStable == NULL) { + mError("table:%s, failed to create, no enough memory", pCreate->tableId); + mgmtSendSimpleResp(pMsg->thandle, TSDB_CODE_SERV_OUT_OF_MEMORY); + return; + } + + strcpy(pStable->info.tableId, pCreate->tableId); + pStable->info.type = TSDB_SUPER_TABLE; + pStable->createdTime = taosGetTimestampMs(); + pStable->uid = (((uint64_t) pStable->createdTime) << 16) + (sdbGetVersion() & ((1ul << 16) - 1ul)); + pStable->sversion = 0; + pStable->numOfColumns = htons(pCreate->numOfColumns); + pStable->numOfTags = htons(pCreate->numOfTags); + + int32_t numOfCols = pCreate->numOfColumns + pCreate->numOfTags; + int32_t schemaSize = numOfCols * sizeof(SSchema); + pStable->schema = (SSchema *)calloc(1, schemaSize); + if (pStable->schema == NULL) { + free(pStable); + mError("table:%s, failed to create, no schema input", pCreate->tableId); + mgmtSendSimpleResp(pMsg->thandle, TSDB_CODE_INVALID_TABLE); + return; + } + memcpy(pStable->schema, pCreate->schema, numOfCols * sizeof(SSchema)); + + pStable->nextColId = 0; + for (int32_t col = 0; col < numOfCols; col++) { + SSchema *tschema = pStable->schema; + tschema[col].colId = pStable->nextColId++; + tschema[col].bytes = htons(tschema[col].bytes); + } + + SSdbOperDesc oper = { + .type = SDB_OPER_TYPE_GLOBAL, + .table = tsSuperTableSdb, + .pObj = pStable, + .rowSize = sizeof(SSuperTableObj) + schemaSize + }; + + int32_t code = sdbInsertRow(&oper); + if (code != TSDB_CODE_SUCCESS) { + mgmtDestroySuperTable(pStable); + mError("table:%s, failed to create, sdb error", pCreate->tableId); + mgmtSendSimpleResp(pMsg->thandle, TSDB_CODE_SDB_ERROR); + } else { + mLPrint("table:%s, is created, tags:%d cols:%d", pStable->info.tableId, pStable->numOfTags, pStable->numOfColumns); + mgmtSendSimpleResp(pMsg->thandle, TSDB_CODE_SUCCESS); + } +} + +static void mgmtProcessDropSuperTableMsg(SQueuedMsg *pMsg) { + SSuperTableObj *pStable = (SSuperTableObj *)pMsg->pTable; + if (pStable->numOfTables != 0) { + mError("stable:%s, numOfTables:%d not 0", pStable->info.tableId, pStable->numOfTables); + mgmtSendSimpleResp(pMsg->thandle, TSDB_CODE_OTHERS); + } else { + SSdbOperDesc oper = { + .type = SDB_OPER_TYPE_GLOBAL, + .table = tsSuperTableSdb, + .pObj = pStable + }; + int32_t code = sdbDeleteRow(&oper); + mLPrint("stable:%s, is dropped from sdb, result:%s", pStable->info.tableId, tstrerror(code)); + mgmtSendSimpleResp(pMsg->thandle, code); + } +} + +static int32_t mgmtFindSuperTableTagIndex(SSuperTableObj *pStable, const char *tagName) { + for (int32_t i = 0; i < pStable->numOfTags; i++) { + SSchema *schema = (SSchema *)(pStable->schema + (pStable->numOfColumns + i) * sizeof(SSchema)); + if (strcasecmp(tagName, schema->name) == 0) { + return i; + } + } + + return -1; +} + +static int32_t mgmtAddSuperTableTag(SSuperTableObj *pStable, SSchema schema[], int32_t ntags) { + if (pStable->numOfTags + ntags > TSDB_MAX_TAGS) { + return TSDB_CODE_APP_ERROR; + } + + // check if schemas have the same name + for (int32_t i = 1; i < ntags; i++) { + for (int32_t j = 0; j < i; j++) { + if (strcasecmp(schema[i].name, schema[j].name) == 0) { + return TSDB_CODE_APP_ERROR; + } + } + } + + int32_t schemaSize = sizeof(SSchema) * (pStable->numOfTags + pStable->numOfColumns); + pStable->schema = realloc(pStable->schema, schemaSize + sizeof(SSchema) * ntags); + + memmove(pStable->schema + sizeof(SSchema) * (pStable->numOfColumns + ntags), + pStable->schema + sizeof(SSchema) * pStable->numOfColumns, sizeof(SSchema) * pStable->numOfTags); + memcpy(pStable->schema + sizeof(SSchema) * pStable->numOfColumns, schema, sizeof(SSchema) * ntags); + + SSchema *tschema = (SSchema *) (pStable->schema + sizeof(SSchema) * pStable->numOfColumns); + for (int32_t i = 0; i < ntags; i++) { + tschema[i].colId = pStable->nextColId++; + } + + pStable->numOfColumns += ntags; + pStable->sversion++; + + SSdbOperDesc oper = { + .type = SDB_OPER_TYPE_GLOBAL, + .table = tsSuperTableSdb, + .pObj = pStable, + .rowSize = tsSuperTableUpdateSize + }; + + int32_t code = sdbUpdateRow(&oper); + if (code != TSDB_CODE_SUCCESS) { + return TSDB_CODE_SDB_ERROR; + } + + mPrint("table %s, succeed to add tag %s", pStable->info.tableId, schema[0].name); + return TSDB_CODE_SUCCESS; +} + +static int32_t mgmtDropSuperTableTag(SSuperTableObj *pStable, char *tagName) { + int32_t col = mgmtFindSuperTableTagIndex(pStable, tagName); + if (col <= 0 || col >= pStable->numOfTags) { + return TSDB_CODE_APP_ERROR; + } + + memmove(pStable->schema + sizeof(SSchema) * col, pStable->schema + sizeof(SSchema) * (col + 1), + sizeof(SSchema) * (pStable->numOfColumns + pStable->numOfTags - col - 1)); + + pStable->numOfTags--; + pStable->sversion++; + + int32_t schemaSize = sizeof(SSchema) * (pStable->numOfTags + pStable->numOfColumns); + pStable->schema = realloc(pStable->schema, schemaSize); + + SSdbOperDesc oper = { + .type = SDB_OPER_TYPE_GLOBAL, + .table = tsSuperTableSdb, + .pObj = pStable, + .rowSize = tsSuperTableUpdateSize + }; + + int32_t code = sdbUpdateRow(&oper); + if (code != TSDB_CODE_SUCCESS) { + return TSDB_CODE_SDB_ERROR; + } + + mPrint("table %s, succeed to drop tag %s", pStable->info.tableId, tagName); + return TSDB_CODE_SUCCESS; +} + +static int32_t mgmtModifySuperTableTagName(SSuperTableObj *pStable, char *oldTagName, char *newTagName) { + int32_t col = mgmtFindSuperTableTagIndex(pStable, oldTagName); + if (col < 0) { + // Tag name does not exist + mError("table:%s, failed to modify table tag, oldName: %s, newName: %s", pStable->info.tableId, oldTagName, newTagName); + return TSDB_CODE_INVALID_MSG_TYPE; + } + + // int32_t rowSize = 0; + uint32_t len = strlen(newTagName); + + if (col >= pStable->numOfTags || len >= TSDB_COL_NAME_LEN || mgmtFindSuperTableTagIndex(pStable, newTagName) >= 0) { + return TSDB_CODE_APP_ERROR; + } + + // update + SSchema *schema = (SSchema *) (pStable->schema + (pStable->numOfColumns + col) * sizeof(SSchema)); + strncpy(schema->name, newTagName, TSDB_COL_NAME_LEN); + + SSdbOperDesc oper = { + .type = SDB_OPER_TYPE_GLOBAL, + .table = tsSuperTableSdb, + .pObj = pStable, + .rowSize = tsSuperTableUpdateSize + }; + + int32_t code = sdbUpdateRow(&oper); + if (code != TSDB_CODE_SUCCESS) { + return TSDB_CODE_SDB_ERROR; + } + + mPrint("table %s, succeed to modify tag %s to %s", pStable->info.tableId, oldTagName, newTagName); + return TSDB_CODE_SUCCESS; +} + +static int32_t mgmtFindSuperTableColumnIndex(SSuperTableObj *pStable, char *colName) { + SSchema *schema = (SSchema *) pStable->schema; + for (int32_t i = 0; i < pStable->numOfColumns; i++) { + if (strcasecmp(schema[i].name, colName) == 0) { + return i; + } + } + + return -1; +} + +static int32_t mgmtAddSuperTableColumn(SDbObj *pDb, SSuperTableObj *pStable, SSchema schema[], int32_t ncols) { + if (ncols <= 0) { + return TSDB_CODE_APP_ERROR; + } + + for (int32_t i = 0; i < ncols; i++) { + if (mgmtFindSuperTableColumnIndex(pStable, schema[i].name) > 0) { + return TSDB_CODE_APP_ERROR; + } + } + + int32_t schemaSize = sizeof(SSchema) * (pStable->numOfTags + pStable->numOfColumns); + pStable->schema = realloc(pStable->schema, schemaSize + sizeof(SSchema) * ncols); + + memmove(pStable->schema + sizeof(SSchema) * (pStable->numOfColumns + ncols), + pStable->schema + sizeof(SSchema) * pStable->numOfColumns, sizeof(SSchema) * pStable->numOfTags); + memcpy(pStable->schema + sizeof(SSchema) * pStable->numOfColumns, schema, sizeof(SSchema) * ncols); + + SSchema *tschema = (SSchema *) (pStable->schema + sizeof(SSchema) * pStable->numOfColumns); + for (int32_t i = 0; i < ncols; i++) { + tschema[i].colId = pStable->nextColId++; + } + + pStable->numOfColumns += ncols; + pStable->sversion++; + + SAcctObj *pAcct = acctGetAcct(pDb->cfg.acct); + if (pAcct != NULL) { + pAcct->acctInfo.numOfTimeSeries += (ncols * pStable->numOfTables); + acctDecRef(pAcct); + } + + SSdbOperDesc oper = { + .type = SDB_OPER_TYPE_GLOBAL, + .table = tsSuperTableSdb, + .pObj = pStable, + .rowSize = tsSuperTableUpdateSize + }; + + int32_t code = sdbUpdateRow(&oper); + if (code != TSDB_CODE_SUCCESS) { + return TSDB_CODE_SDB_ERROR; + } + + mPrint("table %s, succeed to add column", pStable->info.tableId); + return TSDB_CODE_SUCCESS; +} + +static int32_t mgmtDropSuperTableColumn(SDbObj *pDb, SSuperTableObj *pStable, char *colName) { + int32_t col = mgmtFindSuperTableColumnIndex(pStable, colName); + if (col < 0) { + return TSDB_CODE_APP_ERROR; + } + + memmove(pStable->schema + sizeof(SSchema) * col, pStable->schema + sizeof(SSchema) * (col + 1), + sizeof(SSchema) * (pStable->numOfColumns + pStable->numOfTags - col - 1)); + + pStable->numOfColumns--; + pStable->sversion++; + + int32_t schemaSize = sizeof(SSchema) * (pStable->numOfTags + pStable->numOfColumns); + pStable->schema = realloc(pStable->schema, schemaSize); + + SAcctObj *pAcct = acctGetAcct(pDb->cfg.acct); + if (pAcct != NULL) { + pAcct->acctInfo.numOfTimeSeries -= pStable->numOfTables; + acctDecRef(pAcct); + } + + SSdbOperDesc oper = { + .type = SDB_OPER_TYPE_GLOBAL, + .table = tsSuperTableSdb, + .pObj = pStable, + .rowSize = tsSuperTableUpdateSize + }; + + int32_t code = sdbUpdateRow(&oper); + if (code != TSDB_CODE_SUCCESS) { + return TSDB_CODE_SDB_ERROR; + } + + mPrint("table %s, succeed to delete column", pStable->info.tableId); + return TSDB_CODE_SUCCESS; +} + +// show super tables +static int32_t mgmtGetShowSuperTableMeta(STableMetaMsg *pMeta, SShowObj *pShow, void *pConn) { + SDbObj *pDb = mgmtGetDb(pShow->db); + if (pDb == NULL) return TSDB_CODE_DB_NOT_SELECTED; + + int32_t cols = 0; + SSchema *pSchema = pMeta->schema; + + pShow->bytes[cols] = TSDB_TABLE_NAME_LEN; + pSchema[cols].type = TSDB_DATA_TYPE_BINARY; + strcpy(pSchema[cols].name, "name"); + pSchema[cols].bytes = htons(pShow->bytes[cols]); + cols++; + + pShow->bytes[cols] = 8; + pSchema[cols].type = TSDB_DATA_TYPE_TIMESTAMP; + strcpy(pSchema[cols].name, "create_time"); + pSchema[cols].bytes = htons(pShow->bytes[cols]); + cols++; + + pShow->bytes[cols] = 2; + pSchema[cols].type = TSDB_DATA_TYPE_SMALLINT; + strcpy(pSchema[cols].name, "columns"); + pSchema[cols].bytes = htons(pShow->bytes[cols]); + cols++; + + pShow->bytes[cols] = 2; + pSchema[cols].type = TSDB_DATA_TYPE_SMALLINT; + strcpy(pSchema[cols].name, "tags"); + pSchema[cols].bytes = htons(pShow->bytes[cols]); + cols++; + + pShow->bytes[cols] = 4; + pSchema[cols].type = TSDB_DATA_TYPE_INT; + strcpy(pSchema[cols].name, "tables"); + pSchema[cols].bytes = htons(pShow->bytes[cols]); + cols++; + + pMeta->numOfColumns = htons(cols); + pShow->numOfColumns = cols; + + pShow->offset[0] = 0; + for (int32_t i = 1; i < cols; ++i) pShow->offset[i] = pShow->offset[i - 1] + pShow->bytes[i - 1]; + + pShow->numOfRows = pDb->numOfSuperTables; + pShow->rowSize = pShow->offset[cols - 1] + pShow->bytes[cols - 1]; + + mgmtDecDbRef(pDb); + return 0; +} + +// retrieve super tables +int32_t mgmtRetrieveShowSuperTables(SShowObj *pShow, char *data, int32_t rows, void *pConn) { + int32_t numOfRows = 0; + char * pWrite; + int32_t cols = 0; + SSuperTableObj *pTable = NULL; + char prefix[20] = {0}; + int32_t prefixLen; + + SDbObj *pDb = mgmtGetDb(pShow->db); + if (pDb == NULL) return 0; + + strcpy(prefix, pDb->name); + strcat(prefix, TS_PATH_DELIMITER); + prefixLen = strlen(prefix); + + SPatternCompareInfo info = PATTERN_COMPARE_INFO_INITIALIZER; + char stableName[TSDB_TABLE_NAME_LEN] = {0}; + + while (numOfRows < rows) { + mgmtDecTableRef(pTable); + pShow->pNode = sdbFetchRow(tsSuperTableSdb, pShow->pNode, (void **) &pTable); + if (pTable == NULL) break; + if (strncmp(pTable->info.tableId, prefix, prefixLen)) { + continue; + } + + memset(stableName, 0, tListLen(stableName)); + mgmtExtractTableName(pTable->info.tableId, stableName); + + if (pShow->payloadLen > 0 && + patternMatch(pShow->payload, stableName, TSDB_TABLE_NAME_LEN, &info) != TSDB_PATTERN_MATCH) + continue; + + cols = 0; + + pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows; + strncpy(pWrite, stableName, TSDB_TABLE_NAME_LEN); + cols++; + + pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows; + *(int64_t *)pWrite = pTable->createdTime; + cols++; + + pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows; + *(int16_t *)pWrite = pTable->numOfColumns; + cols++; + + pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows; + *(int16_t *)pWrite = pTable->numOfTags; + cols++; + + pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows; + *(int32_t *)pWrite = pTable->numOfTables; + cols++; + + numOfRows++; + } + + pShow->numOfReads += numOfRows; + mgmtDecDbRef(pDb); + + return numOfRows; +} + +void mgmtDropAllSuperTables(SDbObj *pDropDb) { + void *pNode = NULL; + void *pLastNode = NULL; + int32_t numOfTables = 0; + int32_t dbNameLen = strlen(pDropDb->name); + SSuperTableObj *pTable = NULL; + + while (1) { + mgmtDecTableRef(pTable); + pNode = sdbFetchRow(tsSuperTableSdb, pNode, (void **)&pTable); + if (pTable == NULL) { + break; + } + + if (strncmp(pDropDb->name, pTable->info.tableId, dbNameLen) == 0) { + SSdbOperDesc oper = { + .type = SDB_OPER_TYPE_LOCAL, + .table = tsSuperTableSdb, + .pObj = pTable, + }; + sdbDeleteRow(&oper); + pNode = pLastNode; + numOfTables ++; + continue; + } + } + mTrace("db:%s, all super tables:%d is dropped from sdb", pDropDb->name, numOfTables); +} + +static int32_t mgmtSetSchemaFromSuperTable(SSchema *pSchema, SSuperTableObj *pTable) { + int32_t numOfCols = pTable->numOfColumns + pTable->numOfTags; + for (int32_t i = 0; i < numOfCols; ++i) { + strcpy(pSchema->name, pTable->schema[i].name); + pSchema->type = pTable->schema[i].type; + pSchema->bytes = htons(pTable->schema[i].bytes); + pSchema->colId = htons(pTable->schema[i].colId); + pSchema++; + } + + return (pTable->numOfColumns + pTable->numOfTags) * sizeof(SSchema); +} + +static void mgmtGetSuperTableMeta(SQueuedMsg *pMsg) { + SSuperTableObj *pTable = (SSuperTableObj *)pMsg->pTable; + STableMetaMsg *pMeta = rpcMallocCont(sizeof(STableMetaMsg) + sizeof(SSchema) * TSDB_MAX_COLUMNS); + pMeta->uid = htobe64(pTable->uid); + pMeta->sversion = htons(pTable->sversion); + pMeta->precision = pMsg->pDb->cfg.precision; + pMeta->numOfTags = (uint8_t)pTable->numOfTags; + pMeta->numOfColumns = htons((int16_t)pTable->numOfColumns); + pMeta->tableType = pTable->info.type; + pMeta->contLen = sizeof(STableMetaMsg) + mgmtSetSchemaFromSuperTable(pMeta->schema, pTable); + strcpy(pMeta->tableId, pTable->info.tableId); + + SRpcMsg rpcRsp = { + .handle = pMsg->thandle, + .pCont = pMeta, + .contLen = pMeta->contLen, + }; + pMeta->contLen = htons(pMeta->contLen); + rpcSendResponse(&rpcRsp); + + mTrace("stable:%%s, uid:%" PRIu64 " table meta is retrieved", pTable->info.tableId, pTable->uid); +} + +static void mgmtProcessSuperTableVgroupMsg(SQueuedMsg *pMsg) { + SCMSTableVgroupMsg *pInfo = pMsg->pCont; + pMsg->pTable = mgmtGetSuperTable(pInfo->tableId); + if (pMsg->pTable == NULL) { + mgmtSendSimpleResp(pMsg->thandle, TSDB_CODE_INVALID_TABLE); + return; + } + + SCMSTableVgroupRspMsg *pRsp = rpcMallocCont(sizeof(SCMSTableVgroupRspMsg) + sizeof(uint32_t) * mgmtGetDnodesNum()); + if (pRsp == NULL) { + mgmtSendSimpleResp(pMsg->thandle, TSDB_CODE_INVALID_TABLE); + return; + } + + pRsp->numOfDnodes = htonl(1); + pRsp->dnodeIps[0] = htonl(inet_addr(tsPrivateIp)); + + int32_t msgLen = sizeof(SSuperTableObj) + htonl(pRsp->numOfDnodes) * sizeof(int32_t); + SRpcMsg rpcRsp = {0}; + rpcRsp.handle = pMsg->thandle; + rpcRsp.pCont = pRsp; + rpcRsp.contLen = msgLen; + rpcSendResponse(&rpcRsp); +} + +static void mgmtProcessDropSuperTableRsp(SRpcMsg *rpcMsg) { + mTrace("drop stable rsp received, handle:%p code:%d", rpcMsg->handle, rpcMsg->code); +} + +static void *mgmtBuildCreateChildTableMsg(SCMCreateTableMsg *pMsg, SChildTableObj *pTable) { + char * pTagData = NULL; + int32_t tagDataLen = 0; + int32_t totalCols = 0; + int32_t contLen = 0; + if (pTable->info.type == TSDB_CHILD_TABLE && pMsg != NULL) { + pTagData = pMsg->schema + TSDB_TABLE_ID_LEN + 1; + tagDataLen = htonl(pMsg->contLen) - sizeof(SCMCreateTableMsg) - TSDB_TABLE_ID_LEN - 1; + totalCols = pTable->superTable->numOfColumns + pTable->superTable->numOfTags; + contLen = sizeof(SMDCreateTableMsg) + totalCols * sizeof(SSchema) + tagDataLen + pTable->sqlLen; + } else { + totalCols = pTable->numOfColumns; + contLen = sizeof(SMDCreateTableMsg) + totalCols * sizeof(SSchema) + pTable->sqlLen; + } + + SMDCreateTableMsg *pCreate = rpcMallocCont(contLen); + if (pCreate == NULL) { + terrno = TSDB_CODE_SERV_OUT_OF_MEMORY; + return NULL; + } + + memcpy(pCreate->tableId, pTable->info.tableId, TSDB_TABLE_ID_LEN + 1); + pCreate->contLen = htonl(contLen); + pCreate->vgId = htonl(pTable->vgId); + pCreate->tableType = pTable->info.type; + pCreate->createdTime = htobe64(pTable->createdTime); + pCreate->sid = htonl(pTable->sid); + pCreate->sqlDataLen = htonl(pTable->sqlLen); + pCreate->uid = htobe64(pTable->uid); + + if (pTable->info.type == TSDB_CHILD_TABLE) { + memcpy(pCreate->superTableId, pTable->superTable->info.tableId, TSDB_TABLE_ID_LEN + 1); + pCreate->numOfColumns = htons(pTable->superTable->numOfColumns); + pCreate->numOfTags = htons(pTable->superTable->numOfTags); + pCreate->sversion = htonl(pTable->superTable->sversion); + pCreate->tagDataLen = htonl(tagDataLen); + pCreate->superTableUid = htobe64(pTable->superTable->uid); + } else { + pCreate->numOfColumns = htons(pTable->numOfColumns); + pCreate->numOfTags = 0; + pCreate->sversion = htonl(pTable->sversion); + pCreate->tagDataLen = 0; + pCreate->superTableUid = 0; + } + + SSchema *pSchema = (SSchema *) pCreate->data; + if (pTable->info.type == TSDB_CHILD_TABLE) { + memcpy(pSchema, pTable->superTable->schema, totalCols * sizeof(SSchema)); + } else { + memcpy(pSchema, pTable->schema, totalCols * sizeof(SSchema)); + } + for (int32_t col = 0; col < totalCols; ++col) { + pSchema->bytes = htons(pSchema->bytes); + pSchema->colId = htons(pSchema->colId); + pSchema++; + } + + if (pTable->info.type == TSDB_CHILD_TABLE && pMsg != NULL) { + memcpy(pCreate->data + totalCols * sizeof(SSchema), pTagData, tagDataLen); + memcpy(pCreate->data + totalCols * sizeof(SSchema) + tagDataLen, pTable->sql, pTable->sqlLen); + } + + return pCreate; +} + +static SChildTableObj* mgmtDoCreateChildTable(SCMCreateTableMsg *pCreate, SVgObj *pVgroup, int32_t tid) { + SChildTableObj *pTable = (SChildTableObj *) calloc(1, sizeof(SChildTableObj)); + if (pTable == NULL) { + mError("table:%s, failed to alloc memory", pCreate->tableId); + terrno = TSDB_CODE_SERV_OUT_OF_MEMORY; + return NULL; + } + + if (pCreate->numOfColumns == 0) { + pTable->info.type = TSDB_CHILD_TABLE; + } else { + pTable->info.type = TSDB_NORMAL_TABLE; + } + + strcpy(pTable->info.tableId, pCreate->tableId); + pTable->createdTime = taosGetTimestampMs(); + pTable->sid = tid; + pTable->vgId = pVgroup->vgId; + + if (pTable->info.type == TSDB_CHILD_TABLE) { + char *pTagData = (char *) pCreate->schema; // it is a tag key + SSuperTableObj *pSuperTable = mgmtGetSuperTable(pTagData); + if (pSuperTable == NULL) { + mError("table:%s, corresponding super table does not exist", pCreate->tableId); + free(pTable); + terrno = TSDB_CODE_INVALID_TABLE; + return NULL; + } + mgmtDecTableRef(pSuperTable); + + strcpy(pTable->superTableId, pSuperTable->info.tableId); + pTable->uid = (((uint64_t) pTable->vgId) << 40) + ((((uint64_t) pTable->sid) & ((1ul << 24) - 1ul)) << 16) + + (sdbGetVersion() & ((1ul << 16) - 1ul)); + pTable->superTable = pSuperTable; + } else { + pTable->uid = (((uint64_t) pTable->createdTime) << 16) + (sdbGetVersion() & ((1ul << 16) - 1ul)); + pTable->sversion = 0; + pTable->numOfColumns = htons(pCreate->numOfColumns); + pTable->sqlLen = htons(pCreate->sqlLen); + + int32_t numOfCols = pTable->numOfColumns; + int32_t schemaSize = numOfCols * sizeof(SSchema); + pTable->schema = (SSchema *) calloc(1, schemaSize); + if (pTable->schema == NULL) { + free(pTable); + terrno = TSDB_CODE_SERV_OUT_OF_MEMORY; + return NULL; + } + memcpy(pTable->schema, pCreate->schema, numOfCols * sizeof(SSchema)); + + pTable->nextColId = 0; + for (int32_t col = 0; col < numOfCols; col++) { + SSchema *tschema = pTable->schema; + tschema[col].colId = pTable->nextColId++; + tschema[col].bytes = htons(tschema[col].bytes); + } + + if (pTable->sqlLen != 0) { + pTable->info.type = TSDB_STREAM_TABLE; + pTable->sql = calloc(1, pTable->sqlLen); + if (pTable->sql == NULL) { + free(pTable); + terrno = TSDB_CODE_SERV_OUT_OF_MEMORY; + return NULL; + } + memcpy(pTable->sql, (char *) (pCreate->schema) + numOfCols * sizeof(SSchema), pTable->sqlLen); + pTable->sql[pTable->sqlLen - 1] = 0; + mTrace("table:%s, stream sql len:%d sql:%s", pTable->info.tableId, pTable->sqlLen, pTable->sql); + } + } + + SSdbOperDesc desc = {0}; + desc.type = SDB_OPER_TYPE_GLOBAL; + desc.pObj = pTable; + desc.table = tsChildTableSdb; + + if (sdbInsertRow(&desc) != TSDB_CODE_SUCCESS) { + free(pTable); + mError("table:%s, update sdb error", pCreate->tableId); + terrno = TSDB_CODE_SDB_ERROR; + return NULL; + } + + mTrace("table:%s, create ctable in vgroup, uid:%" PRIu64 , pTable->info.tableId, pTable->uid); + return pTable; +} + +static void mgmtProcessCreateChildTableMsg(SQueuedMsg *pMsg) { + SCMCreateTableMsg *pCreate = pMsg->pCont; + int32_t code = grantCheck(TSDB_GRANT_TIMESERIES); + if (code != TSDB_CODE_SUCCESS) { + mError("table:%s, failed to create, grant timeseries failed", pCreate->tableId); + mgmtSendSimpleResp(pMsg->thandle, code); + return; + } + + SVgObj *pVgroup = mgmtGetAvailableVgroup(pMsg->pDb); + if (pVgroup == NULL) { + mTrace("table:%s, start to create a new vgroup", pCreate->tableId); + mgmtCreateVgroup(mgmtCloneQueuedMsg(pMsg), pMsg->pDb); + return; + } + + int32_t sid = taosAllocateId(pVgroup->idPool); + if (sid < 0) { + mTrace("tables:%s, no enough sid in vgroup:%d", pVgroup->vgId); + mgmtCreateVgroup(mgmtCloneQueuedMsg(pMsg), pMsg->pDb); + return; + } + + pMsg->pTable = (STableInfo *)mgmtDoCreateChildTable(pCreate, pVgroup, sid); + if (pMsg->pTable == NULL) { + mgmtSendSimpleResp(pMsg->thandle, terrno); + return; + } + + SMDCreateTableMsg *pMDCreate = mgmtBuildCreateChildTableMsg(pCreate, (SChildTableObj *) pMsg->pTable); + if (pMDCreate == NULL) { + mgmtSendSimpleResp(pMsg->thandle, terrno); + return; + } + + SRpcIpSet ipSet = mgmtGetIpSetFromVgroup(pVgroup); + SQueuedMsg *newMsg = mgmtCloneQueuedMsg(pMsg); + newMsg->ahandle = pMsg->pTable; + mgmtIncTableRef(pMsg->pTable); + SRpcMsg rpcMsg = { + .handle = newMsg, + .pCont = pMDCreate, + .contLen = htonl(pMDCreate->contLen), + .code = 0, + .msgType = TSDB_MSG_TYPE_MD_CREATE_TABLE + }; + + mgmtSendMsgToDnode(&ipSet, &rpcMsg); +} + +static void mgmtProcessDropChildTableMsg(SQueuedMsg *pMsg) { + SChildTableObj *pTable = (SChildTableObj *)pMsg->pTable; + SVgObj *pVgroup = pMsg->pVgroup = mgmtGetVgroup(pTable->vgId); + if (pVgroup == NULL) { + mError("table:%s, failed to drop ctable, vgroup not exist", pTable->info.tableId); + mgmtSendSimpleResp(pMsg->thandle, TSDB_CODE_OTHERS); + return; + } + + SMDDropTableMsg *pDrop = rpcMallocCont(sizeof(SMDDropTableMsg)); + if (pDrop == NULL) { + mError("table:%s, failed to drop ctable, no enough memory", pTable->info.tableId); + mgmtSendSimpleResp(pMsg->thandle, TSDB_CODE_SERV_OUT_OF_MEMORY); + return; + } + + strcpy(pDrop->tableId, pTable->info.tableId); + pDrop->vgId = htonl(pTable->vgId); + pDrop->contLen = htonl(sizeof(SMDDropTableMsg)); + pDrop->sid = htonl(pTable->sid); + pDrop->uid = htobe64(pTable->uid); + + SRpcIpSet ipSet = mgmtGetIpSetFromVgroup(pVgroup); + + mTrace("table:%s, send drop ctable msg", pDrop->tableId); + SQueuedMsg *newMsg = mgmtCloneQueuedMsg(pMsg); + newMsg->ahandle = pMsg->pTable; + SRpcMsg rpcMsg = { + .handle = newMsg, + .pCont = pDrop, + .contLen = sizeof(SMDDropTableMsg), + .code = 0, + .msgType = TSDB_MSG_TYPE_MD_DROP_TABLE + }; + + mgmtSendMsgToDnode(&ipSet, &rpcMsg); +} + +static int32_t mgmtModifyChildTableTagValue(SChildTableObj *pTable, char *tagName, char *nContent) { + return TSDB_CODE_OPS_NOT_SUPPORT; +} + +static int32_t mgmtFindNormalTableColumnIndex(SChildTableObj *pTable, char *colName) { + SSchema *schema = (SSchema *) pTable->schema; + for (int32_t i = 0; i < pTable->numOfColumns; i++) { + if (strcasecmp(schema[i].name, colName) == 0) { + return i; + } + } + + return -1; +} + +static int32_t mgmtAddNormalTableColumn(SDbObj *pDb, SChildTableObj *pTable, SSchema schema[], int32_t ncols) { + if (ncols <= 0) { + return TSDB_CODE_APP_ERROR; + } + + for (int32_t i = 0; i < ncols; i++) { + if (mgmtFindNormalTableColumnIndex(pTable, schema[i].name) > 0) { + return TSDB_CODE_APP_ERROR; + } + } + + int32_t schemaSize = pTable->numOfColumns * sizeof(SSchema); + pTable->schema = realloc(pTable->schema, schemaSize + sizeof(SSchema) * ncols); + + memcpy(pTable->schema + schemaSize, schema, sizeof(SSchema) * ncols); + + SSchema *tschema = (SSchema *) (pTable->schema + sizeof(SSchema) * pTable->numOfColumns); + for (int32_t i = 0; i < ncols; i++) { + tschema[i].colId = pTable->nextColId++; + } + + pTable->numOfColumns += ncols; + pTable->sversion++; + + SAcctObj *pAcct = acctGetAcct(pDb->cfg.acct); + if (pAcct != NULL) { + pAcct->acctInfo.numOfTimeSeries += ncols; + acctDecRef(pAcct); + } + + SSdbOperDesc oper = { + .type = SDB_OPER_TYPE_GLOBAL, + .table = tsChildTableSdb, + .pObj = pTable, + .rowSize = tsChildTableUpdateSize + }; + + int32_t code = sdbUpdateRow(&oper); + if (code != TSDB_CODE_SUCCESS) { + return TSDB_CODE_SDB_ERROR; + } + + mPrint("table %s, succeed to add column", pTable->info.tableId); + return TSDB_CODE_SUCCESS; +} + +static int32_t mgmtDropNormalTableColumn(SDbObj *pDb, SChildTableObj *pTable, char *colName) { + int32_t col = mgmtFindNormalTableColumnIndex(pTable, colName); + if (col < 0) { + return TSDB_CODE_APP_ERROR; + } + + memmove(pTable->schema + sizeof(SSchema) * col, pTable->schema + sizeof(SSchema) * (col + 1), + sizeof(SSchema) * (pTable->numOfColumns - col - 1)); + + pTable->numOfColumns--; + pTable->sversion++; + + SAcctObj *pAcct = acctGetAcct(pDb->cfg.acct); + if (pAcct != NULL) { + pAcct->acctInfo.numOfTimeSeries--; + acctDecRef(pAcct); + } + + SSdbOperDesc oper = { + .type = SDB_OPER_TYPE_GLOBAL, + .table = tsChildTableSdb, + .pObj = pTable, + .rowSize = tsChildTableUpdateSize + }; + + int32_t code = sdbUpdateRow(&oper); + if (code != TSDB_CODE_SUCCESS) { + return TSDB_CODE_SDB_ERROR; + } + + mPrint("table %s, succeed to add column %s", pTable->info.tableId, colName); + return TSDB_CODE_SUCCESS; +} + +static int32_t mgmtSetSchemaFromNormalTable(SSchema *pSchema, SChildTableObj *pTable) { + int32_t numOfCols = pTable->numOfColumns; + for (int32_t i = 0; i < numOfCols; ++i) { + strcpy(pSchema->name, pTable->schema[i].name); + pSchema->type = pTable->schema[i].type; + pSchema->bytes = htons(pTable->schema[i].bytes); + pSchema->colId = htons(pTable->schema[i].colId); + pSchema++; + } + + return numOfCols * sizeof(SSchema); +} + +static int32_t mgmtDoGetChildTableMeta(SQueuedMsg *pMsg, STableMetaMsg *pMeta) { + SDbObj *pDb = pMsg->pDb; + SChildTableObj *pTable = (SChildTableObj *)pMsg->pTable; + int8_t usePublicIp = pMsg->usePublicIp; + + pMeta->uid = htobe64(pTable->uid); + pMeta->sid = htonl(pTable->sid); + pMeta->vgId = htonl(pTable->vgId); + pMeta->precision = pDb->cfg.precision; + pMeta->tableType = pTable->info.type; + strncpy(pMeta->tableId, pTable->info.tableId, tListLen(pTable->info.tableId)); + + if (pTable->info.type == TSDB_CHILD_TABLE) { + pMeta->sversion = htons(pTable->superTable->sversion); + pMeta->numOfTags = 0; + pMeta->numOfColumns = htons((int16_t)pTable->superTable->numOfColumns); + pMeta->contLen = sizeof(STableMetaMsg) + mgmtSetSchemaFromSuperTable(pMeta->schema, pTable->superTable); + strncpy(pMeta->stableId, pTable->superTable->info.tableId, tListLen(pMeta->stableId)); + } else { + pMeta->sversion = htons(pTable->sversion); + pMeta->numOfTags = 0; + pMeta->numOfColumns = htons((int16_t)pTable->numOfColumns); + pMeta->contLen = sizeof(STableMetaMsg) + mgmtSetSchemaFromNormalTable(pMeta->schema, pTable); + } + + SVgObj *pVgroup = pMsg->pVgroup = mgmtGetVgroup(pTable->vgId); + if (pVgroup == NULL) { + mError("table:%s, failed to get table meta, db not selected", pTable->info.tableId); + return TSDB_CODE_INVALID_VGROUP_ID; + } + + for (int32_t i = 0; i < TSDB_VNODES_SUPPORT; ++i) { + if (usePublicIp) { + pMeta->vpeerDesc[i].ip = pVgroup->vnodeGid[i].publicIp; + } else { + pMeta->vpeerDesc[i].ip = pVgroup->vnodeGid[i].privateIp; + } + pMeta->vpeerDesc[i].vnode = htonl(pVgroup->vnodeGid[i].vnode); + } + pMeta->numOfVpeers = pVgroup->numOfVnodes; + + mTrace("table:%s, uid:%" PRIu64 " table meta is retrieved", pTable->info.tableId, pTable->uid); + + return TSDB_CODE_SUCCESS; +} + +void mgmtGetChildTableMeta(SQueuedMsg *pMsg) { + SChildTableObj *pTable = (SChildTableObj *)pMsg->pTable; + SCMTableInfoMsg *pInfo = pMsg->pCont; + + if (pTable == NULL) { + if (htons(pInfo->createFlag) != 1) { + mError("table:%s, failed to get table meta, table not exist", pInfo->tableId); + mgmtSendSimpleResp(pMsg->thandle, TSDB_CODE_INVALID_TABLE); + return; + } else { + //TODO: on demand create table from super table if table does not exists + int32_t contLen = sizeof(SCMCreateTableMsg) + sizeof(STagData); + SCMCreateTableMsg *pCreateMsg = rpcMallocCont(contLen); + if (pCreateMsg == NULL) { + mError("table:%s, failed to create table while get meta info, no enough memory", pInfo->tableId); + mgmtSendSimpleResp(pMsg->thandle, TSDB_CODE_SERV_OUT_OF_MEMORY); + return; + } + memcpy(pCreateMsg->schema, pInfo->tags, sizeof(STagData)); + strcpy(pCreateMsg->tableId, pInfo->tableId); + + SQueuedMsg *newMsg = malloc(sizeof(SQueuedMsg)); + memcpy(newMsg, pMsg, sizeof(SQueuedMsg)); + pMsg->pCont = NULL; + + newMsg->ahandle = newMsg->pCont; + newMsg->pCont = pCreateMsg; + mTrace("table:%s, start to create in demand", pInfo->tableId); + mgmtAddToShellQueue(newMsg); + return; + } + } + + STableMetaMsg *pMeta = rpcMallocCont(sizeof(STableMetaMsg) + sizeof(SSchema) * TSDB_MAX_COLUMNS); + if (pMeta == NULL) { + mError("table:%s, failed to get table meta, no enough memory", pTable->info.tableId); + mgmtSendSimpleResp(pMsg->thandle, TSDB_CODE_SERV_OUT_OF_MEMORY); + return; + } + + mgmtDoGetChildTableMeta(pMsg, pMeta); + + SRpcMsg rpcRsp = { + .handle = pMsg->thandle, + .pCont = pMeta, + .contLen = pMeta->contLen, + }; + pMeta->contLen = htons(pMeta->contLen); + rpcSendResponse(&rpcRsp); +} + +void mgmtDropAllChildTables(SDbObj *pDropDb) { + void *pNode = NULL; + void *pLastNode = NULL; + int32_t numOfTables = 0; + int32_t dbNameLen = strlen(pDropDb->name); + SChildTableObj *pTable = NULL; + + while (1) { + mgmtDecTableRef(pTable); + pNode = sdbFetchRow(tsChildTableSdb, pNode, (void **)&pTable); + if (pTable == NULL) { + break; + } + + if (strncmp(pDropDb->name, pTable->info.tableId, dbNameLen) == 0) { + SSdbOperDesc oper = { + .type = SDB_OPER_TYPE_LOCAL, + .table = tsChildTableSdb, + .pObj = pTable, + }; + sdbDeleteRow(&oper); + pNode = pLastNode; + numOfTables++; + continue; + } + } + + mTrace("db:%s, all child tables:%d is dropped from sdb", pDropDb->name, numOfTables); +} + +static void mgmtDropAllChildTablesInStable(SSuperTableObj *pStable) { + void *pNode = NULL; + void *pLastNode = NULL; + int32_t numOfTables = 0; + SChildTableObj *pTable = NULL; + + while (1) { + mgmtDecTableRef(pTable); + pNode = sdbFetchRow(tsChildTableSdb, pNode, (void **)&pTable); + if (pTable == NULL) { + break; + } + + if (pTable->superTable == pStable) { + SSdbOperDesc oper = { + .type = SDB_OPER_TYPE_LOCAL, + .table = tsChildTableSdb, + .pObj = pTable, + }; + sdbDeleteRow(&oper); + pNode = pLastNode; + numOfTables++; + continue; + } + } + + mTrace("stable:%s, all child tables:%d is dropped from sdb", pStable->info.tableId, numOfTables); +} + +static SChildTableObj* mgmtGetTableByPos(uint32_t dnodeId, int32_t vnode, int32_t sid) { + SDnodeObj *pObj = mgmtGetDnode(dnodeId); + SVgObj *pVgroup = mgmtGetVgroup(vnode); + + if (pObj == NULL || pVgroup == NULL) { + return NULL; + } + + SChildTableObj *pTable = pVgroup->tableList[sid]; + mgmtIncTableRef((STableInfo *)pTable); + mgmtDecVgroupRef(pVgroup); + return pTable; +} + +static void mgmtProcessTableCfgMsg(SRpcMsg *rpcMsg) { + if (mgmtCheckRedirect(rpcMsg->handle)) return; + + SDMConfigTableMsg *pCfg = (SDMConfigTableMsg *) rpcMsg->pCont; + pCfg->dnode = htonl(pCfg->dnode); + pCfg->vnode = htonl(pCfg->vnode); + pCfg->sid = htonl(pCfg->sid); + mTrace("dnode:%s, vnode:%d, sid:%d, receive table config msg", taosIpStr(pCfg->dnode), pCfg->vnode, pCfg->sid); + + SChildTableObj *pTable = mgmtGetTableByPos(pCfg->dnode, pCfg->vnode, pCfg->sid); + if (pTable == NULL) { + mError("dnode:%s, vnode:%d, sid:%d, table not found", taosIpStr(pCfg->dnode), pCfg->vnode, pCfg->sid); + mgmtSendSimpleResp(rpcMsg->handle, TSDB_CODE_NOT_ACTIVE_TABLE); + return; + } + + mgmtSendSimpleResp(rpcMsg->handle, TSDB_CODE_SUCCESS); + + SMDCreateTableMsg *pMDCreate = NULL; + pMDCreate = mgmtBuildCreateChildTableMsg(NULL, (SChildTableObj *) pTable); + if (pMDCreate == NULL) { + mgmtDecTableRef(pTable); + return; + } + + SRpcIpSet ipSet = mgmtGetIpSetFromIp(pCfg->dnode); + SRpcMsg rpcRsp = { + .handle = NULL, + .pCont = pMDCreate, + .contLen = htonl(pMDCreate->contLen), + .code = 0, + .msgType = TSDB_MSG_TYPE_MD_CREATE_TABLE + }; + mgmtSendMsgToDnode(&ipSet, &rpcRsp); + mgmtDecTableRef(pTable); +} + +// handle drop child response +static void mgmtProcessDropChildTableRsp(SRpcMsg *rpcMsg) { + if (rpcMsg->handle == NULL) return; + + SQueuedMsg *queueMsg = rpcMsg->handle; + queueMsg->received++; + + SChildTableObj *pTable = queueMsg->ahandle; + mTrace("table:%s, drop table rsp received, thandle:%p result:%s", pTable->info.tableId, queueMsg->thandle, tstrerror(rpcMsg->code)); + + if (rpcMsg->code != TSDB_CODE_SUCCESS) { + mError("table:%s, failed to drop in dnode, reason:%s", pTable->info.tableId, tstrerror(rpcMsg->code)); + mgmtSendSimpleResp(queueMsg->thandle, rpcMsg->code); + free(queueMsg); + mgmtDecTableRef(pTable); + return; + } + + SVgObj *pVgroup = queueMsg->pVgroup = mgmtGetVgroup(pTable->vgId); + if (pVgroup == NULL) { + mError("table:%s, failed to get vgroup", pTable->info.tableId); + mgmtSendSimpleResp(queueMsg->thandle, TSDB_CODE_INVALID_VGROUP_ID); + return; + } + + SSdbOperDesc oper = { + .type = SDB_OPER_TYPE_GLOBAL, + .table = tsChildTableSdb, + .pObj = pTable + }; + + int32_t code = sdbDeleteRow(&oper); + if (code != TSDB_CODE_SUCCESS) { + mError("table:%s, update ctables sdb error", pTable->info.tableId); + mgmtSendSimpleResp(queueMsg->thandle, TSDB_CODE_SDB_ERROR); + return; + } + + if (pVgroup->numOfTables <= 0) { + mPrint("vgroup:%d, all tables is dropped, drop vgroup", pVgroup->vgId); + mgmtDropVgroup(pVgroup, NULL); + } + + mgmtSendSimpleResp(queueMsg->thandle, TSDB_CODE_SUCCESS); + mgmtFreeQueuedMsg(queueMsg); +} + +// handle create table response from dnode +// if failed, drop the table cached +static void mgmtProcessCreateChildTableRsp(SRpcMsg *rpcMsg) { + if (rpcMsg->handle == NULL) return; + + SQueuedMsg *queueMsg = rpcMsg->handle; + queueMsg->received++; + + SChildTableObj *pTable = queueMsg->ahandle; + mTrace("table:%s, create table rsp received, thandle:%p ahandle:%p result:%s", pTable->info.tableId, queueMsg->thandle, + rpcMsg->handle, tstrerror(rpcMsg->code)); + + if (rpcMsg->code != TSDB_CODE_SUCCESS) { + SSdbOperDesc oper = { + .type = SDB_OPER_TYPE_GLOBAL, + .table = tsChildTableSdb, + .pObj = pTable + }; + sdbDeleteRow(&oper); + + mError("table:%s, failed to create in dnode, reason:%s", pTable->info.tableId, tstrerror(rpcMsg->code)); + mgmtSendSimpleResp(queueMsg->thandle, rpcMsg->code); + } else { + mTrace("table:%s, created in dnode", pTable->info.tableId); + if (queueMsg->msgType != TSDB_MSG_TYPE_CM_CREATE_TABLE) { + mTrace("table:%s, start to get meta", pTable->info.tableId); + mgmtAddToShellQueue(mgmtCloneQueuedMsg(queueMsg)); + } else { + mgmtSendSimpleResp(queueMsg->thandle, rpcMsg->code); + } + } + + mgmtFreeQueuedMsg(queueMsg); +} + +// not implemented yet +static void mgmtProcessAlterTableRsp(SRpcMsg *rpcMsg) { + mTrace("alter table rsp received, handle:%p code:%d", rpcMsg->handle, rpcMsg->code); +} + +static void mgmtProcessMultiTableMetaMsg(SQueuedMsg *pMsg) { + SCMMultiTableInfoMsg *pInfo = pMsg->pCont; + pInfo->numOfTables = htonl(pInfo->numOfTables); + + int32_t totalMallocLen = 4*1024*1024; // first malloc 4 MB, subsequent reallocation as twice + SMultiTableMeta *pMultiMeta = rpcMallocCont(totalMallocLen); + if (pMultiMeta == NULL) { + mgmtSendSimpleResp(pMsg->thandle, TSDB_CODE_SERV_OUT_OF_MEMORY); + return; + } + + pMultiMeta->contLen = sizeof(SMultiTableMeta); + pMultiMeta->numOfTables = 0; + + for (int t = 0; t < pInfo->numOfTables; ++t) { + char *tableId = (char*)(pInfo->tableIds + t * TSDB_TABLE_ID_LEN); + SChildTableObj *pTable = mgmtGetChildTable(tableId); + if (pTable == NULL) continue; + + SDbObj *pDb = mgmtGetDbByTableId(tableId); + if (pDb == NULL) continue; + + int availLen = totalMallocLen - pMultiMeta->contLen; + if (availLen <= sizeof(STableMetaMsg) + sizeof(SSchema) * TSDB_MAX_COLUMNS) { + //TODO realloc + //totalMallocLen *= 2; + //pMultiMeta = rpcReMalloc(pMultiMeta, totalMallocLen); + //if (pMultiMeta == NULL) { + /// rpcSendResponse(ahandle, TSDB_CODE_SERV_OUT_OF_MEMORY, NULL, 0); + // return TSDB_CODE_SERV_OUT_OF_MEMORY; + //} else { + // t--; + // continue; + //} + } + + STableMetaMsg *pMeta = (STableMetaMsg *)(pMultiMeta->metas + pMultiMeta->contLen); + int32_t code = mgmtDoGetChildTableMeta(pMsg, pMeta); + if (code == TSDB_CODE_SUCCESS) { + pMultiMeta->numOfTables ++; + pMultiMeta->contLen += pMeta->contLen; + } + } + + SRpcMsg rpcRsp = {0}; + rpcRsp.handle = pMsg->thandle; + rpcRsp.pCont = pMultiMeta; + rpcRsp.contLen = pMultiMeta->contLen; + rpcSendResponse(&rpcRsp); +} + +static int32_t mgmtGetShowTableMeta(STableMetaMsg *pMeta, SShowObj *pShow, void *pConn) { + SDbObj *pDb = mgmtGetDb(pShow->db); + if (pDb == NULL) return TSDB_CODE_DB_NOT_SELECTED; + + int32_t cols = 0; + SSchema *pSchema = pMeta->schema; + + pShow->bytes[cols] = TSDB_TABLE_NAME_LEN; + pSchema[cols].type = TSDB_DATA_TYPE_BINARY; + strcpy(pSchema[cols].name, "table name"); + pSchema[cols].bytes = htons(pShow->bytes[cols]); + cols++; + + pShow->bytes[cols] = 8; + pSchema[cols].type = TSDB_DATA_TYPE_TIMESTAMP; + strcpy(pSchema[cols].name, "create time"); + pSchema[cols].bytes = htons(pShow->bytes[cols]); + cols++; + + pShow->bytes[cols] = 2; + pSchema[cols].type = TSDB_DATA_TYPE_SMALLINT; + strcpy(pSchema[cols].name, "columns"); + pSchema[cols].bytes = htons(pShow->bytes[cols]); + cols++; + + pShow->bytes[cols] = TSDB_TABLE_NAME_LEN; + pSchema[cols].type = TSDB_DATA_TYPE_BINARY; + strcpy(pSchema[cols].name, "stable name"); + pSchema[cols].bytes = htons(pShow->bytes[cols]); + cols++; + + pMeta->numOfColumns = htons(cols); + pShow->numOfColumns = cols; + + pShow->offset[0] = 0; + for (int32_t i = 1; i < cols; ++i) { + pShow->offset[i] = pShow->offset[i - 1] + pShow->bytes[i - 1]; + } + + pShow->numOfRows = pDb->numOfTables; + pShow->rowSize = pShow->offset[cols - 1] + pShow->bytes[cols - 1]; + + mgmtDecDbRef(pDb); + return 0; +} + +static void mgmtVacuumResult(char *data, int32_t numOfCols, int32_t rows, int32_t capacity, SShowObj *pShow) { + if (rows < capacity) { + for (int32_t i = 0; i < numOfCols; ++i) { + memmove(data + pShow->offset[i] * rows, data + pShow->offset[i] * capacity, pShow->bytes[i] * rows); + } + } +} + +static int32_t mgmtRetrieveShowTables(SShowObj *pShow, char *data, int32_t rows, void *pConn) { + SDbObj *pDb = mgmtGetDb(pShow->db); + if (pDb == NULL) return 0; + + int32_t numOfRows = 0; + SChildTableObj *pTable = NULL; + SPatternCompareInfo info = PATTERN_COMPARE_INFO_INITIALIZER; + + char prefix[64] = {0}; + strcpy(prefix, pDb->name); + strcat(prefix, TS_PATH_DELIMITER); + int32_t prefixLen = strlen(prefix); + + while (numOfRows < rows) { + mgmtDecTableRef(pTable); + pShow->pNode = sdbFetchRow(tsChildTableSdb, pShow->pNode, (void **) &pTable); + if (pTable == NULL) break; + + // not belong to current db + if (strncmp(pTable->info.tableId, prefix, prefixLen)) { + continue; + } + + char tableName[TSDB_TABLE_NAME_LEN] = {0}; + memset(tableName, 0, tListLen(tableName)); + + // pattern compare for meter name + mgmtExtractTableName(pTable->info.tableId, tableName); + + if (pShow->payloadLen > 0 && + patternMatch(pShow->payload, tableName, TSDB_TABLE_NAME_LEN, &info) != TSDB_PATTERN_MATCH) { + continue; + } + + int32_t cols = 0; + + char *pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows; + strncpy(pWrite, tableName, TSDB_TABLE_NAME_LEN); + cols++; + + pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows; + *(int64_t *) pWrite = pTable->createdTime; + cols++; + + pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows; + if (pTable->info.type == TSDB_CHILD_TABLE) { + *(int16_t *)pWrite = pTable->superTable->numOfColumns; + } else { + *(int16_t *)pWrite = pTable->numOfColumns; + } + + cols++; + + pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows; + if (pTable->info.type == TSDB_CHILD_TABLE) { + mgmtExtractTableName(pTable->superTableId, pWrite); + } + cols++; + + numOfRows++; + } + + pShow->numOfReads += numOfRows; + const int32_t NUM_OF_COLUMNS = 4; + + mgmtVacuumResult(data, NUM_OF_COLUMNS, numOfRows, rows, pShow); + mgmtDecDbRef(pDb); + + return numOfRows; +} + static void mgmtProcessAlterTableMsg(SQueuedMsg *pMsg) { SCMAlterTableMsg *pAlter = pMsg->pCont; mTrace("table:%s, alter table msg is received from thandle:%p", pAlter->tableId, pMsg->thandle); - if (mgmtCheckRedirect(pMsg->thandle)) return; - - if (!pMsg->pUser->writeAuth) { - mTrace("table:%s, failed to alter table, no rights", pAlter->tableId); - mgmtSendSimpleResp(pMsg->thandle, TSDB_CODE_NO_RIGHTS); - return; - } - pMsg->pDb = mgmtGetDbByTableId(pAlter->tableId); if (pMsg->pDb == NULL || pMsg->pDb->dirty) { mError("table:%s, failed to alter table, db not selected", pAlter->tableId); @@ -199,9 +1961,9 @@ static void mgmtProcessAlterTableMsg(SQueuedMsg *pMsg) { return; } - STableInfo *pTable = mgmtGetTable(pAlter->tableId); - if (pTable == NULL) { - mError("table:%s, failed to alter table, table not exist", pTable->tableId); + pMsg->pTable = mgmtGetTable(pAlter->tableId); + if (pMsg->pTable == NULL) { + mError("table:%s, failed to alter table, table not exist", pMsg->pTable->tableId); mgmtSendSimpleResp(pMsg->thandle, TSDB_CODE_INVALID_TABLE); return; } @@ -217,30 +1979,34 @@ static void mgmtProcessAlterTableMsg(SQueuedMsg *pMsg) { pAlter->schema[i].bytes = htons(pAlter->schema[i].bytes); } - if (pTable->type == TSDB_SUPER_TABLE) { + int32_t code = TSDB_CODE_OPS_NOT_SUPPORT; + if (pMsg->pTable->type == TSDB_SUPER_TABLE) { + SSuperTableObj *pTable = (SSuperTableObj *)pMsg->pTable; mTrace("table:%s, start to alter stable", pAlter->tableId); - mgmtAlterSuperTable(pMsg, (SSuperTableObj *)pTable); + if (pAlter->type == TSDB_ALTER_TABLE_ADD_TAG_COLUMN) { + code = mgmtAddSuperTableTag(pTable, pAlter->schema, 1); + } else if (pAlter->type == TSDB_ALTER_TABLE_DROP_TAG_COLUMN) { + code = mgmtDropSuperTableTag(pTable, pAlter->schema[0].name); + } else if (pAlter->type == TSDB_ALTER_TABLE_CHANGE_TAG_COLUMN) { + code = mgmtModifySuperTableTagName(pTable, pAlter->schema[0].name, pAlter->schema[1].name); + } else if (pAlter->type == TSDB_ALTER_TABLE_ADD_COLUMN) { + code = mgmtAddSuperTableColumn(pMsg->pDb, pTable, pAlter->schema, 1); + } else if (pAlter->type == TSDB_ALTER_TABLE_DROP_COLUMN) { + code = mgmtDropSuperTableColumn(pMsg->pDb, pTable, pAlter->schema[0].name); + } else { + } } else { mTrace("table:%s, start to alter ctable", pAlter->tableId); - mgmtAlterChildTable(pMsg, (SChildTableObj *)pTable); + SChildTableObj *pTable = (SChildTableObj *)pMsg->pTable; + if (pAlter->type == TSDB_ALTER_TABLE_UPDATE_TAG_VAL) { + code = mgmtModifyChildTableTagValue(pTable, pAlter->schema[0].name, pAlter->tagVal); + } else if (pAlter->type == TSDB_ALTER_TABLE_ADD_COLUMN) { + code = mgmtAddNormalTableColumn(pMsg->pDb, pTable, pAlter->schema, 1); + } else if (pAlter->type == TSDB_ALTER_TABLE_DROP_COLUMN) { + code = mgmtDropNormalTableColumn(pMsg->pDb, pTable, pAlter->schema[0].name); + } else { + } } + + mgmtSendSimpleResp(pMsg->thandle, code); } - -static void mgmtProcessTableMetaMsg(SQueuedMsg *pMsg) { - SCMTableInfoMsg *pInfo = pMsg->pCont; - mTrace("table:%s, table meta msg is received from thandle:%p", pInfo->tableId, pMsg->thandle); - - pMsg->pDb = mgmtGetDbByTableId(pInfo->tableId); - if (pMsg->pDb == NULL || pMsg->pDb->dirty) { - mError("table:%s, failed to get table meta, db not selected", pInfo->tableId); - mgmtSendSimpleResp(pMsg->thandle, TSDB_CODE_DB_NOT_SELECTED); - return; - } - - STableInfo *pTable = mgmtGetTable(pInfo->tableId); - if (pTable == NULL || pTable->type != TSDB_SUPER_TABLE) { - mgmtGetChildTableMeta(pMsg, (SChildTableObj *)pTable); - } else { - mgmtGetSuperTableMeta(pMsg, (SSuperTableObj *)pTable); - } -} \ No newline at end of file diff --git a/src/mnode/src/mgmtUser.c b/src/mnode/src/mgmtUser.c index c497fd6e8f..1eac58a5ea 100644 --- a/src/mnode/src/mgmtUser.c +++ b/src/mnode/src/mgmtUser.c @@ -25,14 +25,10 @@ #include "mgmtShell.h" #include "mgmtUser.h" -void * tsUserSdb = NULL; +void * tsUserSdb = NULL; static int32_t tsUserUpdateSize = 0; - -static int32_t mgmtDropUser(SAcctObj *pAcct, char *name); -static int32_t mgmtUpdateUser(SUserObj *pUser); static int32_t mgmtGetUserMeta(STableMetaMsg *pMeta, SShowObj *pShow, void *pConn); static int32_t mgmtRetrieveUsers(SShowObj *pShow, char *data, int32_t rows, void *pConn); - static void mgmtProcessCreateUserMsg(SQueuedMsg *pMsg); static void mgmtProcessAlterUserMsg(SQueuedMsg *pMsg); static void mgmtProcessDropUserMsg(SQueuedMsg *pMsg); @@ -101,6 +97,7 @@ int32_t mgmtInitUsers() { .tableName = "users", .hashSessions = TSDB_MAX_USERS, .maxRowSize = tsUserUpdateSize, + .refCountPos = (int8_t *)(&tObj.refCount) - (int8_t *)&tObj, .keyType = SDB_KEY_TYPE_STRING, .insertFp = mgmtUserActionInsert, .deleteFp = mgmtUserActionDelete, @@ -120,6 +117,7 @@ int32_t mgmtInitUsers() { mgmtCreateUser(pAcct, "root", "taosdata"); mgmtCreateUser(pAcct, "monitor", tsInternalPass); mgmtCreateUser(pAcct, "_root", tsInternalPass); + acctDecRef(pAcct); mgmtAddShellMsgHandle(TSDB_MSG_TYPE_CM_CREATE_USER, mgmtProcessCreateUserMsg); mgmtAddShellMsgHandle(TSDB_MSG_TYPE_CM_ALTER_USER, mgmtProcessAlterUserMsg); @@ -139,6 +137,14 @@ SUserObj *mgmtGetUser(char *name) { return (SUserObj *)sdbGetRow(tsUserSdb, name); } +void mgmtIncUserRef(SUserObj *pUser) { + return sdbIncRef(tsUserSdb, pUser); +} + +void mgmtDecUserRef(SUserObj *pUser) { + return sdbDecRef(tsUserSdb, pUser); +} + static int32_t mgmtUpdateUser(SUserObj *pUser) { SSdbOperDesc oper = { .type = SDB_OPER_TYPE_GLOBAL, @@ -149,7 +155,6 @@ static int32_t mgmtUpdateUser(SUserObj *pUser) { int32_t code = sdbUpdateRow(&oper); if (code != TSDB_CODE_SUCCESS) { - tfree(pUser); code = TSDB_CODE_SDB_ERROR; } @@ -166,9 +171,10 @@ int32_t mgmtCreateUser(SAcctObj *pAcct, char *name, char *pass) { return TSDB_CODE_INVALID_MSG; } - SUserObj *pUser = (SUserObj *)sdbGetRow(tsUserSdb, name); + SUserObj *pUser = mgmtGetUser(name); if (pUser != NULL) { mTrace("user:%s is already there", name); + mgmtDecUserRef(pUser); return TSDB_CODE_USER_ALREADY_EXIST; } @@ -204,19 +210,7 @@ int32_t mgmtCreateUser(SAcctObj *pAcct, char *name, char *pass) { return code; } -static int32_t mgmtDropUser(SAcctObj *pAcct, char *name) { - SUserObj *pUser; - - pUser = (SUserObj *)sdbGetRow(tsUserSdb, name); - if (pUser == NULL) { - mWarn("user:%s is not there", name); - return TSDB_CODE_INVALID_USER; - } - - if (strcmp(pAcct->user, pUser->acct) != 0) { - return TSDB_CODE_NO_RIGHTS; - } - +static int32_t mgmtDropUser(SUserObj *pUser) { SSdbOperDesc oper = { .type = SDB_OPER_TYPE_GLOBAL, .table = tsUserSdb, @@ -268,9 +262,9 @@ static int32_t mgmtGetUserMeta(STableMetaMsg *pMeta, SShowObj *pShow, void *pCon } pShow->numOfRows = pUser->pAcct->acctInfo.numOfUsers; - pShow->pNode = pUser->pAcct->pUser; pShow->rowSize = pShow->offset[cols - 1] + pShow->bytes[cols - 1]; + mgmtDecUserRef(pUser); return 0; } @@ -281,10 +275,9 @@ static int32_t mgmtRetrieveUsers(SShowObj *pShow, char *data, int32_t rows, void char *pWrite; while (numOfRows < rows) { - pUser = (SUserObj *)pShow->pNode; + pShow->pNode = sdbFetchRow(tsUserSdb, pShow->pNode, (void **) &pUser); if (pUser == NULL) break; - pShow->pNode = (void *)pUser->next; - + cols = 0; pWrite = data + pShow->offset[cols] * rows + pShow->bytes[cols] * numOfRows; @@ -306,6 +299,7 @@ static int32_t mgmtRetrieveUsers(SShowObj *pShow, char *data, int32_t rows, void cols++; numOfRows++; + mgmtDecUserRef(pUser); } pShow->numOfReads += numOfRows; return numOfRows; @@ -357,6 +351,7 @@ static void mgmtProcessAlterUserMsg(SQueuedMsg *pMsg) { if (strcmp(pUser->user, "monitor") == 0 || (strcmp(pUser->user + 1, pUser->acct) == 0 && pUser->user[0] == '_')) { mgmtSendSimpleResp(pMsg->thandle, TSDB_CODE_NO_RIGHTS); + mgmtDecUserRef(pUser); return; } @@ -386,10 +381,7 @@ static void mgmtProcessAlterUserMsg(SQueuedMsg *pMsg) { } mgmtSendSimpleResp(pMsg->thandle, code); - return; - } - - if ((pAlter->flag & TSDB_ALTER_USER_PRIVILEGES) != 0) { + } else if ((pAlter->flag & TSDB_ALTER_USER_PRIVILEGES) != 0) { bool hasRight = false; if (strcmp(pUser->user, "root") == 0) { @@ -431,10 +423,11 @@ static void mgmtProcessAlterUserMsg(SQueuedMsg *pMsg) { } mgmtSendSimpleResp(pMsg->thandle, code); - return; + } else { + mgmtSendSimpleResp(pMsg->thandle, TSDB_CODE_NO_RIGHTS); } - mgmtSendSimpleResp(pMsg->thandle, TSDB_CODE_NO_RIGHTS); + mgmtDecUserRef(pUser); } static void mgmtProcessDropUserMsg(SQueuedMsg *pMsg) { @@ -453,6 +446,7 @@ static void mgmtProcessDropUserMsg(SQueuedMsg *pMsg) { if (strcmp(pUser->user, "monitor") == 0 || strcmp(pUser->user, pUser->acct) == 0 || (strcmp(pUser->user + 1, pUser->acct) == 0 && pUser->user[0] == '_')) { mgmtSendSimpleResp(pMsg->thandle, TSDB_CODE_NO_RIGHTS); + mgmtDecUserRef(pUser); return ; } @@ -464,9 +458,7 @@ static void mgmtProcessDropUserMsg(SQueuedMsg *pMsg) { } else if (strcmp(pUser->user, pOperUser->user) == 0) { hasRight = false; } else if (pOperUser->superAuth) { - if (strcmp(pUser->user, "root") == 0) { - hasRight = false; - } else if (strcmp(pOperUser->acct, pUser->acct) != 0) { + if (strcmp(pOperUser->acct, pUser->acct) != 0) { hasRight = false; } else { hasRight = true; @@ -474,22 +466,23 @@ static void mgmtProcessDropUserMsg(SQueuedMsg *pMsg) { } if (hasRight) { - code = mgmtDropUser(pUser->pAcct, pDrop->user); + code = mgmtDropUser(pUser); if (code == TSDB_CODE_SUCCESS) { - mLPrint("user:%s is dropped by %s, result:%d", pUser->user, pOperUser->user, tstrerror(code)); + mLPrint("user:%s is dropped by %s, result:%s", pUser->user, pOperUser->user, tstrerror(code)); } } else { code = TSDB_CODE_NO_RIGHTS; } mgmtSendSimpleResp(pMsg->thandle, code); + mgmtDecUserRef(pUser); } void mgmtDropAllUsers(SAcctObj *pAcct) { - void *pNode = NULL; - void *pLastNode = NULL; - int32_t numOfUsers = 0; - int32_t acctNameLen = strlen(pAcct->user); + void * pNode = NULL; + void * pLastNode = NULL; + int32_t numOfUsers = 0; + int32_t acctNameLen = strlen(pAcct->user); SUserObj *pUser = NULL; while (1) { @@ -506,8 +499,9 @@ void mgmtDropAllUsers(SAcctObj *pAcct) { sdbDeleteRow(&oper); pNode = pLastNode; numOfUsers++; - continue; } + + mgmtDecUserRef(pUser); } mTrace("acct:%s, all users:%d is dropped from sdb", pAcct->user, numOfUsers); diff --git a/src/mnode/src/mgmtVgroup.c b/src/mnode/src/mgmtVgroup.c index 7e46b61d0c..ad12db8b11 100644 --- a/src/mnode/src/mgmtVgroup.c +++ b/src/mnode/src/mgmtVgroup.c @@ -20,7 +20,6 @@ #include "tstatus.h" #include "mnode.h" #include "mgmtBalance.h" -#include "mgmtChildTable.h" #include "mgmtDb.h" #include "mgmtDClient.h" #include "mgmtDnode.h" @@ -59,6 +58,7 @@ static int32_t mgmtVgroupActionDestroy(SSdbOperDesc *pOper) { if (pDnode) { atomic_sub_fetch_32(&pDnode->openVnodes, 1); } + mgmtDecDnodeRef(pDnode); } tfree(pOper->pObj); @@ -71,6 +71,7 @@ static int32_t mgmtVgroupActionInsert(SSdbOperDesc *pOper) { if (pDb == NULL) { return TSDB_CODE_INVALID_DB; } + mgmtDecDbRef(pDb); pVgroup->pDb = pDb; pVgroup->prev = NULL; @@ -96,6 +97,7 @@ static int32_t mgmtVgroupActionInsert(SSdbOperDesc *pOper) { pVgroup->vnodeGid[i].publicIp = pDnode->publicIp; pVgroup->vnodeGid[i].vnode = pVgroup->vgId; atomic_add_fetch_32(&pDnode->openVnodes, 1); + mgmtDecDnodeRef(pDnode); } mgmtAddVgroupIntoDb(pVgroup); @@ -110,6 +112,7 @@ static int32_t mgmtVgroupActionDelete(SSdbOperDesc *pOper) { mgmtRemoveVgroupFromDb(pVgroup); } + mgmtDecDbRef(pVgroup->pDb); return TSDB_CODE_SUCCESS; } @@ -159,6 +162,7 @@ int32_t mgmtInitVgroups() { .tableName = "vgroups", .hashSessions = TSDB_MAX_VGROUPS, .maxRowSize = tsVgUpdateSize, + .refCountPos = (int8_t *)(&tObj.refCount) - (int8_t *)&tObj, .keyType = SDB_KEY_TYPE_AUTO, .insertFp = mgmtVgroupActionInsert, .deleteFp = mgmtVgroupActionDelete, @@ -184,6 +188,14 @@ int32_t mgmtInitVgroups() { return 0; } +void mgmtIncVgroupRef(SVgObj *pVgroup) { + return sdbIncRef(tsVgroupSdb, pVgroup); +} + +void mgmtDecVgroupRef(SVgObj *pVgroup) { + return sdbDecRef(tsVgroupSdb, pVgroup); +} + SVgObj *mgmtGetVgroup(int32_t vgId) { return (SVgObj *)sdbGetRow(tsVgroupSdb, &vgId); } @@ -192,15 +204,7 @@ SVgObj *mgmtGetAvailableVgroup(SDbObj *pDb) { return pDb->pHead; } -void mgmtCreateVgroup(SQueuedMsg *pMsg) { - SDbObj *pDb = pMsg->pDb; - if (pDb == NULL) { - mError("failed to create vgroup, db not found"); - mgmtSendSimpleResp(pMsg->thandle, TSDB_CODE_INVALID_DB); - mgmtFreeQueuedMsg(pMsg); - return; - } - +void mgmtCreateVgroup(SQueuedMsg *pMsg, SDbObj *pDb) { SVgObj *pVgroup = (SVgObj *)calloc(1, sizeof(SVgObj)); strcpy(pVgroup->dbName, pDb->name); pVgroup->numOfVnodes = pDb->cfg.replications; @@ -287,16 +291,16 @@ int32_t mgmtGetVgroupMeta(STableMetaMsg *pMeta, SShowObj *pShow, void *pConn) { int32_t maxReplica = 0; SVgObj *pVgroup = NULL; - SChildTableObj *pTable = NULL; + STableInfo *pTable = NULL; if (pShow->payloadLen > 0 ) { - pTable = mgmtGetChildTable(pShow->payload); - if (NULL == pTable) { + pTable = mgmtGetTable(pShow->payload); + if (NULL == pTable || pTable->type == TSDB_SUPER_TABLE) { return TSDB_CODE_INVALID_TABLE_ID; } - - pVgroup = mgmtGetVgroup(pTable->vgId); + mgmtDecTableRef(pTable); + pVgroup = mgmtGetVgroup(((SChildTableObj*)pTable)->vgId); if (NULL == pVgroup) return TSDB_CODE_INVALID_TABLE_ID; - + mgmtDecVgroupRef(pVgroup); maxReplica = pVgroup->numOfVnodes > maxReplica ? pVgroup->numOfVnodes : maxReplica; } else { SVgObj *pVgroup = pDb->pHead; @@ -348,6 +352,8 @@ int32_t mgmtGetVgroupMeta(STableMetaMsg *pMeta, SShowObj *pShow, void *pConn) { pShow->pNode = pVgroup; } + mgmtDecDbRef(pDb); + return 0; } @@ -357,6 +363,7 @@ char *mgmtGetVnodeStatus(SVgObj *pVgroup, SVnodeGid *pVnode) { mError("vgroup:%d, not exist in dnode:%d", pVgroup->vgId, pDnode->dnodeId); return "null"; } + mgmtDecDnodeRef(pDnode); if (pDnode->status == TSDB_DN_STATUS_OFFLINE) { return "offline"; @@ -436,6 +443,8 @@ int32_t mgmtRetrieveVgroups(SShowObj *pShow, char *data, int32_t rows, void *pCo } pShow->numOfReads += numOfRows; + mgmtDecDbRef(pDb); + return numOfRows; } @@ -445,7 +454,8 @@ void mgmtAddTableIntoVgroup(SVgObj *pVgroup, SChildTableObj *pTable) { taosIdPoolMarkStatus(pVgroup->idPool, pTable->sid); pVgroup->numOfTables++; } - + + mgmtIncVgroupRef(pVgroup); if (pVgroup->numOfTables >= pVgroup->pDb->cfg.maxSessions) mgmtAddVgroupIntoDbTail(pVgroup); } @@ -457,6 +467,7 @@ void mgmtRemoveTableFromVgroup(SVgObj *pVgroup, SChildTableObj *pTable) { pVgroup->numOfTables--; } + mgmtDecVgroupRef(pVgroup); if (pVgroup->numOfTables >= pVgroup->pDb->cfg.maxSessions) mgmtAddVgroupIntoDbTail(pVgroup); } @@ -554,15 +565,7 @@ static void mgmtProcessCreateVnodeRsp(SRpcMsg *rpcMsg) { if (queueMsg->received != queueMsg->expected) return; if (queueMsg->received == queueMsg->successed) { - SQueuedMsg *newMsg = calloc(1, sizeof(SQueuedMsg)); - newMsg->msgType = queueMsg->msgType; - newMsg->thandle = queueMsg->thandle; - newMsg->pDb = queueMsg->pDb; - newMsg->pUser = queueMsg->pUser; - newMsg->contLen = queueMsg->contLen; - newMsg->pCont = rpcMallocCont(newMsg->contLen); - memcpy(newMsg->pCont, queueMsg->pCont, newMsg->contLen); - queueMsg->pCont = NULL; + SQueuedMsg *newMsg = mgmtCloneQueuedMsg(queueMsg); mgmtAddToShellQueue(newMsg); } else { SSdbOperDesc oper = { @@ -638,14 +641,7 @@ static void mgmtProcessDropVnodeRsp(SRpcMsg *rpcMsg) { code = TSDB_CODE_SDB_ERROR; } - SQueuedMsg *newMsg = calloc(1, sizeof(SQueuedMsg)); - newMsg->msgType = queueMsg->msgType; - newMsg->thandle = queueMsg->thandle; - newMsg->pDb = queueMsg->pDb; - newMsg->pUser = queueMsg->pUser; - newMsg->contLen = queueMsg->contLen; - newMsg->pCont = rpcMallocCont(newMsg->contLen); - memcpy(newMsg->pCont, queueMsg->pCont, newMsg->contLen); + SQueuedMsg *newMsg = mgmtCloneQueuedMsg(queueMsg); mgmtAddToShellQueue(newMsg); queueMsg->pCont = NULL; @@ -665,6 +661,7 @@ static void mgmtProcessVnodeCfgMsg(SRpcMsg *rpcMsg) { mgmtSendSimpleResp(rpcMsg->handle, TSDB_CODE_NOT_ACTIVE_VNODE); return; } + mgmtDecDnodeRef(pDnode); SVgObj *pVgroup = mgmtGetVgroup(pCfg->vgId); if (pVgroup == NULL) { @@ -672,6 +669,7 @@ static void mgmtProcessVnodeCfgMsg(SRpcMsg *rpcMsg) { mgmtSendSimpleResp(rpcMsg->handle, TSDB_CODE_NOT_ACTIVE_VNODE); return; } + mgmtDecVgroupRef(pVgroup); mgmtSendSimpleResp(rpcMsg->handle, TSDB_CODE_SUCCESS); @@ -687,6 +685,7 @@ void mgmtDropAllVgroups(SDbObj *pDropDb) { SVgObj *pVgroup = NULL; while (1) { + mgmtDecVgroupRef(pVgroup); pNode = sdbFetchRow(tsVgroupSdb, pNode, (void **)&pVgroup); if (pVgroup == NULL) break; diff --git a/src/os/linux/src/tlinux.c b/src/os/linux/src/tlinux.c index bce4a8f13d..780e2903a0 100644 --- a/src/os/linux/src/tlinux.c +++ b/src/os/linux/src/tlinux.c @@ -236,7 +236,7 @@ void *taosProcessAlarmSignal(void *tharg) { void (*callback)(int) = tharg; timer_t timerId; - struct sigevent sevent; + struct sigevent sevent = {0}; #ifdef _ALPINE sevent.sigev_notify = SIGEV_THREAD; diff --git a/src/query/inc/qast.h b/src/query/inc/qast.h index 51580445d5..616a2a46af 100644 --- a/src/query/inc/qast.h +++ b/src/query/inc/qast.h @@ -16,6 +16,7 @@ #ifndef TDENGINE_TAST_H #define TDENGINE_TAST_H +#include #ifdef __cplusplus extern "C" { #endif @@ -27,14 +28,14 @@ extern "C" { #include "taosdef.h" #include "tvariant.h" -struct tSQLSyntaxNode; +struct tExprNode; struct SSchema; struct tSkipList; struct tSkipListNode; enum { - TSQL_NODE_EXPR = 0x1, - TSQL_NODE_COL = 0x2, + TSQL_NODE_EXPR = 0x1, + TSQL_NODE_COL = 0x2, TSQL_NODE_VALUE = 0x4, }; @@ -60,44 +61,41 @@ typedef struct SBinaryFilterSupp { void * pExtInfo; } SBinaryFilterSupp; -typedef struct tSQLSyntaxNode { +typedef struct tExprNode { uint8_t nodeType; union { struct { - uint8_t optr; // filter operator - uint8_t hasPK; // 0: do not contain primary filter, 1: contain - void * info; // support filter operation on this expression only available for leaf node + uint8_t optr; // filter operator + uint8_t hasPK; // 0: do not contain primary filter, 1: contain + void * info; // support filter operation on this expression only available for leaf node - struct tSQLSyntaxNode *pLeft; // left child pointer - struct tSQLSyntaxNode *pRight; // right child pointer + struct tExprNode *pLeft; // left child pointer + struct tExprNode *pRight; // right child pointer } _node; struct SSchema *pSchema; tVariant * pVal; }; -} tSQLSyntaxNode; +} tExprNode; +void tSQLBinaryExprFromString(tExprNode **pExpr, SSchema *pSchema, int32_t numOfCols, char *src, int32_t len); -typedef struct tQueryResultset { - void ** pRes; - int64_t num; -} tQueryResultset; +void tSQLBinaryExprToString(tExprNode *pExpr, char *dst, int32_t *len); -void tSQLBinaryExprFromString(tSQLSyntaxNode **pExpr, SSchema *pSchema, int32_t numOfCols, char *src, int32_t len); +void tExprTreeDestroy(tExprNode **pExprs, void (*fp)(void*)); -void tSQLBinaryExprToString(tSQLSyntaxNode *pExpr, char *dst, int32_t *len); +void tSQLBinaryExprTraverse(tExprNode *pExpr, SSkipList *pSkipList, SArray *result, SBinaryFilterSupp *param); -void tSQLBinaryExprDestroy(tSQLSyntaxNode **pExprs, void (*fp)(void*)); - -void tSQLBinaryExprTraverse(tSQLSyntaxNode *pExpr, SSkipList *pSkipList, SArray *result, SBinaryFilterSupp *param); - -void tSQLBinaryExprCalcTraverse(tSQLSyntaxNode *pExprs, int32_t numOfRows, char *pOutput, void *param, int32_t order, +void tSQLBinaryExprCalcTraverse(tExprNode *pExprs, int32_t numOfRows, char *pOutput, void *param, int32_t order, char *(*cb)(void *, char *, int32_t)); -void tSQLBinaryExprTrv(tSQLSyntaxNode *pExprs, int32_t *val, int16_t *ids); -void tQueryResultClean(tQueryResultset *pRes); +void tSQLBinaryExprTrv(tExprNode *pExprs, int32_t *val, int16_t *ids); uint8_t getBinaryExprOptr(SSQLToken *pToken); +SBuffer exprTreeToBinary(tExprNode* pExprTree); + +tExprNode* exprTreeFromBinary(const void* pBuf, size_t size); + #ifdef __cplusplus } #endif diff --git a/src/query/inc/qsqlparser.h b/src/query/inc/qsqlparser.h index 951caa8073..b1799b6902 100644 --- a/src/query/inc/qsqlparser.h +++ b/src/query/inc/qsqlparser.h @@ -13,8 +13,8 @@ * along with this program. If not, see . */ -#ifndef TDENGINE_QASTDEF_H -#define TDENGINE_QASTDEF_H +#ifndef TDENGINE_QSQLPARSER_H +#define TDENGINE_QSQLPARSER_H #ifdef __cplusplus extern "C" { @@ -329,4 +329,4 @@ int32_t tSQLParse(SSqlInfo *pSQLInfo, const char *pSql); } #endif -#endif // TDENGINE_QASTDEF_H +#endif // TDENGINE_QSQLPARSER_H diff --git a/src/query/src/qast.c b/src/query/src/qast.c index 192a7f39c0..6674dc1aba 100644 --- a/src/query/src/qast.c +++ b/src/query/src/qast.c @@ -13,11 +13,11 @@ * along with this program. If not, see . */ -#include "qast.h" -#include -#include -#include "../../client/inc/tschemautil.h" #include "os.h" + +#include "tutil.h" +#include "tbuffer.h" +#include "qast.h" #include "qsqlparser.h" #include "qsyntaxtreefunction.h" #include "taosdef.h" @@ -26,7 +26,10 @@ #include "tsqlfunction.h" #include "tstoken.h" #include "ttokendef.h" -#include "tutil.h" + +#include "../../client/inc/tschemautil.h" +#include "tarray.h" +#include "tskiplist.h" /* * @@ -39,22 +42,20 @@ * ver 0.3, pipeline filter in the form of: (a+2)/9 > 14 * */ +static tExprNode *tExprNodeCreate(SSchema *pSchema, int32_t numOfCols, SSQLToken *pToken); +static void tExprNodeDestroy(tExprNode *pNode, void (*fp)(void *)); -static tSQLSyntaxNode *tSQLSyntaxNodeCreate(SSchema *pSchema, int32_t numOfCols, SSQLToken *pToken); -static void tSQLSyntaxNodeDestroy(tSQLSyntaxNode *pNode, void (*fp)(void *)); +static tExprNode *createSyntaxTree(SSchema *pSchema, int32_t numOfCols, char *str, int32_t *i); +static void destroySyntaxTree(tExprNode *); -static tSQLSyntaxNode *createSyntaxTree(SSchema *pSchema, int32_t numOfCols, char *str, int32_t *i); -static void destroySyntaxTree(tSQLSyntaxNode *); - -static uint8_t isQueryOnPrimaryKey(const char *primaryColumnName, const tSQLSyntaxNode *pLeft, - const tSQLSyntaxNode *pRight); +static uint8_t isQueryOnPrimaryKey(const char *primaryColumnName, const tExprNode *pLeft, const tExprNode *pRight); /* * Check the filter value type on the right hand side based on the column id on the left hand side, * the filter value type must be identical to field type for relational operation * As for binary arithmetic operation, it is not necessary to do so. */ -static void reviseBinaryExprIfNecessary(tSQLSyntaxNode **pLeft, tSQLSyntaxNode **pRight, uint8_t *optr) { +static void reviseBinaryExprIfNecessary(tExprNode **pLeft, tExprNode **pRight, uint8_t *optr) { if (*optr >= TSDB_RELATION_LESS && *optr <= TSDB_RELATION_LIKE) { // make sure that the type of data on both sides of relational comparision are identical if ((*pLeft)->nodeType == TSQL_NODE_VALUE) { @@ -79,7 +80,7 @@ static void reviseBinaryExprIfNecessary(tSQLSyntaxNode **pLeft, tSQLSyntaxNode * */ if ((*pLeft)->nodeType == TSQL_NODE_VALUE && (*pRight)->nodeType == TSQL_NODE_COL) { if (*optr >= TSDB_RELATION_LARGE && *optr <= TSDB_RELATION_LARGE_EQUAL && *optr != TSDB_RELATION_EQUAL) { - SWAP(*pLeft, *pRight, tSQLSyntaxNode *); + SWAP(*pLeft, *pRight, tExprNode *); } switch (*optr) { @@ -101,15 +102,15 @@ static void reviseBinaryExprIfNecessary(tSQLSyntaxNode **pLeft, tSQLSyntaxNode * } } -static tSQLSyntaxNode *tSQLSyntaxNodeCreate(SSchema *pSchema, int32_t numOfCols, SSQLToken *pToken) { +static tExprNode *tExprNodeCreate(SSchema *pSchema, int32_t numOfCols, SSQLToken *pToken) { /* if the token is not a value, return false */ if (pToken->type == TK_RP || (pToken->type != TK_INTEGER && pToken->type != TK_FLOAT && pToken->type != TK_ID && pToken->type != TK_TBNAME && pToken->type != TK_STRING && pToken->type != TK_BOOL)) { return NULL; } - size_t nodeSize = sizeof(tSQLSyntaxNode); - tSQLSyntaxNode *pNode = NULL; + size_t nodeSize = sizeof(tExprNode); + tExprNode *pNode = NULL; if (pToken->type == TK_ID || pToken->type == TK_TBNAME) { int32_t i = 0; @@ -130,7 +131,7 @@ static tSQLSyntaxNode *tSQLSyntaxNodeCreate(SSchema *pSchema, int32_t numOfCols, nodeSize += sizeof(SSchema); pNode = calloc(1, nodeSize); - pNode->pSchema = (struct SSchema *)((char *)pNode + sizeof(tSQLSyntaxNode)); + pNode->pSchema = (struct SSchema *)((char *)pNode + sizeof(tExprNode)); pNode->nodeType = TSQL_NODE_COL; if (pToken->type == TK_ID) { @@ -145,7 +146,7 @@ static tSQLSyntaxNode *tSQLSyntaxNodeCreate(SSchema *pSchema, int32_t numOfCols, } else { nodeSize += sizeof(tVariant); pNode = calloc(1, nodeSize); - pNode->pVal = (tVariant *)((char *)pNode + sizeof(tSQLSyntaxNode)); + pNode->pVal = (tVariant *)((char *)pNode + sizeof(tExprNode)); toTSDBType(pToken->type); tVariantCreate(pNode->pVal, pToken); @@ -191,21 +192,21 @@ uint8_t getBinaryExprOptr(SSQLToken *pToken) { } // previous generated expr is reduced as the left child -static tSQLSyntaxNode *parseRemainStr(char *pstr, tSQLSyntaxNode *pExpr, SSchema *pSchema, int32_t optr, +static tExprNode *parseRemainStr(char *pstr, tExprNode *pExpr, SSchema *pSchema, int32_t optr, int32_t numOfCols, int32_t *i) { // set the previous generated node as the left child of new root pExpr->nodeType = TSQL_NODE_EXPR; // remain is the right child - tSQLSyntaxNode *pRight = createSyntaxTree(pSchema, numOfCols, pstr, i); + tExprNode *pRight = createSyntaxTree(pSchema, numOfCols, pstr, i); if (pRight == NULL || (pRight->nodeType == TSQL_NODE_COL && pExpr->nodeType != TSQL_NODE_VALUE) || (pExpr->nodeType == TSQL_NODE_VALUE && pRight->nodeType != TSQL_NODE_COL)) { - tSQLSyntaxNodeDestroy(pExpr, NULL); - tSQLSyntaxNodeDestroy(pRight, NULL); + tExprNodeDestroy(pExpr, NULL); + tExprNodeDestroy(pRight, NULL); return NULL; } - tSQLSyntaxNode *pNewExpr = (tSQLSyntaxNode *)calloc(1, sizeof(tSQLSyntaxNode)); + tExprNode *pNewExpr = (tExprNode *)calloc(1, sizeof(tExprNode)); uint8_t k = optr; reviseBinaryExprIfNecessary(&pExpr, &pRight, &k); pNewExpr->_node.pLeft = pExpr; @@ -218,7 +219,7 @@ static tSQLSyntaxNode *parseRemainStr(char *pstr, tSQLSyntaxNode *pExpr, SSchema return pNewExpr; } -uint8_t isQueryOnPrimaryKey(const char *primaryColumnName, const tSQLSyntaxNode *pLeft, const tSQLSyntaxNode *pRight) { +uint8_t isQueryOnPrimaryKey(const char *primaryColumnName, const tExprNode *pLeft, const tExprNode *pRight) { if (pLeft->nodeType == TSQL_NODE_COL) { // if left node is the primary column,return true return (strcmp(primaryColumnName, pLeft->pSchema->name) == 0) ? 1 : 0; @@ -231,20 +232,21 @@ uint8_t isQueryOnPrimaryKey(const char *primaryColumnName, const tSQLSyntaxNode } } -static tSQLSyntaxNode *createSyntaxTree(SSchema *pSchema, int32_t numOfCols, char *str, int32_t *i) { +static tExprNode *createSyntaxTree(SSchema *pSchema, int32_t numOfCols, char *str, int32_t *i) { SSQLToken t0 = tStrGetToken(str, i, false, 0, NULL); if (t0.n == 0) { return NULL; } - tSQLSyntaxNode *pLeft = NULL; + tExprNode *pLeft = NULL; if (t0.type == TK_LP) { // start new left child branch pLeft = createSyntaxTree(pSchema, numOfCols, str, i); } else { if (t0.type == TK_RP) { return NULL; } - pLeft = tSQLSyntaxNodeCreate(pSchema, numOfCols, &t0); + + pLeft = tExprNodeCreate(pSchema, numOfCols, &t0); } if (pLeft == NULL) { @@ -254,7 +256,7 @@ static tSQLSyntaxNode *createSyntaxTree(SSchema *pSchema, int32_t numOfCols, cha t0 = tStrGetToken(str, i, false, 0, NULL); if (t0.n == 0 || t0.type == TK_RP) { if (pLeft->nodeType != TSQL_NODE_EXPR) { // if left is not the expr, it is not a legal expr - tSQLSyntaxNodeDestroy(pLeft, NULL); + tExprNodeDestroy(pLeft, NULL); return NULL; } @@ -265,12 +267,12 @@ static tSQLSyntaxNode *createSyntaxTree(SSchema *pSchema, int32_t numOfCols, cha uint8_t optr = getBinaryExprOptr(&t0); if (optr == 0) { pError("not support binary operator:%d", t0.type); - tSQLSyntaxNodeDestroy(pLeft, NULL); + tExprNodeDestroy(pLeft, NULL); return NULL; } assert(pLeft != NULL); - tSQLSyntaxNode *pRight = NULL; + tExprNode *pRight = NULL; if (t0.type == TK_AND || t0.type == TK_OR || t0.type == TK_LP) { pRight = createSyntaxTree(pSchema, numOfCols, str, i); @@ -283,51 +285,51 @@ static tSQLSyntaxNode *createSyntaxTree(SSchema *pSchema, int32_t numOfCols, cha */ t0 = tStrGetToken(str, i, true, 0, NULL); if (t0.n == 0) { - tSQLSyntaxNodeDestroy(pLeft, NULL); // illegal expression + tExprNodeDestroy(pLeft, NULL); // illegal expression return NULL; } if (t0.type == TK_LP) { pRight = createSyntaxTree(pSchema, numOfCols, str, i); } else { - pRight = tSQLSyntaxNodeCreate(pSchema, numOfCols, &t0); + pRight = tExprNodeCreate(pSchema, numOfCols, &t0); } } if (pRight == NULL) { - tSQLSyntaxNodeDestroy(pLeft, NULL); + tExprNodeDestroy(pLeft, NULL); return NULL; } /* create binary expr as the child of new parent node */ - tSQLSyntaxNode *pBinExpr = (tSQLSyntaxNode *)calloc(1, sizeof(tSQLSyntaxNode)); + tExprNode *pExpr = (tExprNode *)calloc(1, sizeof(tExprNode)); reviseBinaryExprIfNecessary(&pLeft, &pRight, &optr); - pBinExpr->_node.hasPK = isQueryOnPrimaryKey(pSchema[0].name, pLeft, pRight); - pBinExpr->_node.pLeft = pLeft; - pBinExpr->_node.pRight = pRight; - pBinExpr->_node.optr = optr; + pExpr->_node.hasPK = isQueryOnPrimaryKey(pSchema[0].name, pLeft, pRight); + pExpr->_node.pLeft = pLeft; + pExpr->_node.pRight = pRight; + pExpr->_node.optr = optr; t0 = tStrGetToken(str, i, true, 0, NULL); if (t0.n == 0 || t0.type == TK_RP) { - tSQLSyntaxNode *pn = malloc(sizeof(tSQLSyntaxNode)); - pBinExpr->nodeType = TSQL_NODE_EXPR; - return pBinExpr; + pExpr->nodeType = TSQL_NODE_EXPR; + return pExpr; } else { uint8_t localOptr = getBinaryExprOptr(&t0); if (localOptr == 0) { pError("not support binary operator:%d", t0.type); - free(pBinExpr); + free(pExpr); return NULL; } - return parseRemainStr(str, pBinExpr, pSchema, localOptr, numOfCols, i); + return parseRemainStr(str, pExpr, pSchema, localOptr, numOfCols, i); } } -void tSQLBinaryExprFromString(tSQLSyntaxNode **pExpr, SSchema *pSchema, int32_t numOfCols, char *src, int32_t len) { +void tSQLBinaryExprFromString(tExprNode **pExpr, SSchema *pSchema, int32_t numOfCols, char *src, int32_t len) { *pExpr = NULL; + if (len <= 0 || src == NULL || pSchema == NULL || numOfCols <= 0) { return; } @@ -340,7 +342,7 @@ void tSQLBinaryExprFromString(tSQLSyntaxNode **pExpr, SSchema *pSchema, int32_t } } -int32_t tSQLBinaryExprToStringImpl(tSQLSyntaxNode *pNode, char *dst, uint8_t type) { +int32_t tSQLBinaryExprToStringImpl(tExprNode *pNode, char *dst, uint8_t type) { int32_t len = 0; if (type == TSQL_NODE_EXPR) { *dst = '('; @@ -406,7 +408,7 @@ static char *tSQLOptrToString(uint8_t optr, char *dst) { return dst; } -void tSQLBinaryExprToString(tSQLSyntaxNode *pExpr, char *dst, int32_t *len) { +void tSQLBinaryExprToString(tExprNode *pExpr, char *dst, int32_t *len) { if (pExpr == NULL) { *dst = 0; *len = 0; @@ -423,32 +425,41 @@ void tSQLBinaryExprToString(tSQLSyntaxNode *pExpr, char *dst, int32_t *len) { *len += tSQLBinaryExprToStringImpl(pExpr->_node.pRight, start, pExpr->_node.pRight->nodeType); } -static void UNUSED_FUNC destroySyntaxTree(tSQLSyntaxNode *pNode) { tSQLSyntaxNodeDestroy(pNode, NULL); } +static void UNUSED_FUNC destroySyntaxTree(tExprNode *pNode) { tExprNodeDestroy(pNode, NULL); } -static void tSQLSyntaxNodeDestroy(tSQLSyntaxNode *pNode, void (*fp)(void *)) { +static void tExprNodeDestroy(tExprNode *pNode, void (*fp)(void *)) { if (pNode == NULL) { return; } if (pNode->nodeType == TSQL_NODE_EXPR) { - tSQLBinaryExprDestroy(&pNode, fp); + tExprTreeDestroy(&pNode, fp); } else if (pNode->nodeType == TSQL_NODE_VALUE) { tVariantDestroy(pNode->pVal); + } else if (pNode->nodeType == TSQL_NODE_COL) { + free(pNode->pSchema); } free(pNode); } -void tSQLBinaryExprDestroy(tSQLSyntaxNode **pExpr, void (*fp)(void *)) { +void tExprTreeDestroy(tExprNode **pExpr, void (*fp)(void *)) { if (*pExpr == NULL) { return; } - - tSQLSyntaxNodeDestroy((*pExpr)->_node.pLeft, fp); - tSQLSyntaxNodeDestroy((*pExpr)->_node.pRight, fp); - - if (fp != NULL) { - fp((*pExpr)->_node.info); + + if ((*pExpr)->nodeType == TSQL_NODE_EXPR) { + tExprTreeDestroy(&(*pExpr)->_node.pLeft, fp); + tExprTreeDestroy(&(*pExpr)->_node.pRight, fp); + + if (fp != NULL) { + fp((*pExpr)->_node.info); + } + } else if ((*pExpr)->nodeType == TSQL_NODE_VALUE) { + tVariantDestroy((*pExpr)->pVal); + free((*pExpr)->pVal); + } else if ((*pExpr)->nodeType == TSQL_NODE_COL) { + free((*pExpr)->pSchema); } free(*pExpr); @@ -559,7 +570,7 @@ void tSQLBinaryExprDestroy(tSQLSyntaxNode **pExpr, void (*fp)(void *)) { // DEFAULT_COMP(p1, p2); //} -int32_t merge(tQueryResultset *pLeft, tQueryResultset *pRight, tQueryResultset *pFinalRes) { +int32_t merge(SArray *pLeft, SArray *pRight, SArray *pFinalRes) { // assert(pFinalRes->pRes == 0); // // pFinalRes->pRes = calloc((size_t)(pLeft->num + pRight->num), POINTER_BYTES); @@ -600,7 +611,7 @@ int32_t merge(tQueryResultset *pLeft, tQueryResultset *pRight, tQueryResultset * return 0; } -int32_t intersect(tQueryResultset *pLeft, tQueryResultset *pRight, tQueryResultset *pFinalRes) { +int32_t intersect(SArray *pLeft, SArray *pRight, SArray *pFinalRes) { // int64_t num = MIN(pLeft->num, pRight->num); // // assert(pFinalRes->pRes == 0); @@ -638,25 +649,26 @@ int32_t intersect(tQueryResultset *pLeft, tQueryResultset *pRight, tQueryResults /* * traverse the result and apply the function to each item to check if the item is qualified or not */ -static UNUSED_FUNC void tSQLListTraverseOnResult(struct tSQLSyntaxNode *pExpr, __result_filter_fn_t fp, tQueryResultset *pResult) { - assert(pExpr->_node.pLeft->nodeType == TSQL_NODE_COL && pExpr->_node.pRight->nodeType == TSQL_NODE_VALUE); - - // brutal force scan the result list and check for each item in the list - int64_t num = pResult->num; - for (int32_t i = 0, j = 0; i < pResult->num; ++i) { - if (fp == NULL || (fp(pResult->pRes[i], pExpr->_node.info) == true)) { - pResult->pRes[j++] = pResult->pRes[i]; - } else { - num--; - } - } - - pResult->num = num; +static UNUSED_FUNC void tSQLListTraverseOnResult(struct tExprNode *pExpr, __result_filter_fn_t fp, SArray *pResult) { +// assert(pExpr->_node.pLeft->nodeType == TSQL_NODE_COL && pExpr->_node.pRight->nodeType == TSQL_NODE_VALUE); +// +// // brutal force scan the result list and check for each item in the list +// int64_t num = pResult->num; +// for (int32_t i = 0, j = 0; i < pResult->num; ++i) { +// if (fp == NULL || (fp(pResult->pRes[i], pExpr->_node.info) == true)) { +// pResult->pRes[j++] = pResult->pRes[i]; +// } else { +// num--; +// } +// } +// +// pResult->num = num; + assert(0); } -static bool filterItem(tSQLSyntaxNode *pExpr, const void *pItem, SBinaryFilterSupp *param) { - tSQLSyntaxNode *pLeft = pExpr->_node.pLeft; - tSQLSyntaxNode *pRight = pExpr->_node.pRight; +static bool filterItem(tExprNode *pExpr, const void *pItem, SBinaryFilterSupp *param) { + tExprNode *pLeft = pExpr->_node.pLeft; + tExprNode *pRight = pExpr->_node.pRight; /* * non-leaf nodes, recursively traverse the syntax tree in the post-root order @@ -695,7 +707,7 @@ static bool filterItem(tSQLSyntaxNode *pExpr, const void *pItem, SBinaryFilterSu * @param pSchema tag schemas * @param fp filter callback function */ -static void tSQLBinaryTraverseOnResult(tSQLSyntaxNode *pExpr, SArray *pResult, SBinaryFilterSupp *param) { +static void tSQLBinaryTraverseOnResult(tExprNode *pExpr, SArray *pResult, SBinaryFilterSupp *param) { size_t size = taosArrayGetSize(pResult); SArray* array = taosArrayInit(size, POINTER_BYTES); @@ -710,7 +722,7 @@ static void tSQLBinaryTraverseOnResult(tSQLSyntaxNode *pExpr, SArray *pResult, S taosArrayCopy(pResult, array); } -static void tSQLBinaryTraverseOnSkipList(tSQLSyntaxNode *pExpr, SArray *pResult, SSkipList *pSkipList, +static void tSQLBinaryTraverseOnSkipList(tExprNode *pExpr, SArray *pResult, SSkipList *pSkipList, SBinaryFilterSupp *param) { SSkipListIterator* iter = tSkipListCreateIter(pSkipList); @@ -724,13 +736,13 @@ static void tSQLBinaryTraverseOnSkipList(tSQLSyntaxNode *pExpr, SArray *pResult, } // post-root order traverse syntax tree -void tSQLBinaryExprTraverse(tSQLSyntaxNode *pExpr, SSkipList *pSkipList, SArray *result, SBinaryFilterSupp *param) { +void tSQLBinaryExprTraverse(tExprNode *pExpr, SSkipList *pSkipList, SArray *result, SBinaryFilterSupp *param) { if (pExpr == NULL) { return; } - tSQLSyntaxNode *pLeft = pExpr->_node.pLeft; - tSQLSyntaxNode *pRight = pExpr->_node.pRight; + tExprNode *pLeft = pExpr->_node.pLeft; + tExprNode *pRight = pExpr->_node.pRight; // recursive traverse left child branch if (pLeft->nodeType == TSQL_NODE_EXPR || pRight->nodeType == TSQL_NODE_EXPR) { @@ -751,22 +763,22 @@ void tSQLBinaryExprTraverse(tSQLSyntaxNode *pExpr, SSkipList *pSkipList, SArray assert(taosArrayGetSize(result) == 0); tSQLBinaryTraverseOnSkipList(pExpr, result, pSkipList, param); } else if (weight == 2 || (weight == 1 && pExpr->_node.optr == TSDB_RELATION_OR)) { - tQueryResultset rLeft = {0}; - tQueryResultset rRight = {0}; + SArray* rLeft = taosArrayInit(10, POINTER_BYTES); + SArray* rRight = taosArrayInit(10, POINTER_BYTES); - tSQLBinaryExprTraverse(pLeft, pSkipList, &rLeft, param); - tSQLBinaryExprTraverse(pRight, pSkipList, &rRight, param); + tSQLBinaryExprTraverse(pLeft, pSkipList, rLeft, param); + tSQLBinaryExprTraverse(pRight, pSkipList, rRight, param); if (pExpr->_node.optr == TSDB_RELATION_AND) { // CROSS - intersect(&rLeft, &rRight, result); + intersect(rLeft, rRight, result); } else if (pExpr->_node.optr == TSDB_RELATION_OR) { // or - merge(&rLeft, &rRight, result); + merge(rLeft, rRight, result); } else { assert(false); } - free(rLeft.pRes); - free(rRight.pRes); + taosArrayDestroy(rLeft); + taosArrayDestroy(rRight); } else { /* * (weight == 1 && pExpr->nSQLBinaryOptr == TSDB_RELATION_AND) is handled here @@ -776,8 +788,8 @@ void tSQLBinaryExprTraverse(tSQLSyntaxNode *pExpr, SSkipList *pSkipList, SArray */ assert(pExpr->_node.optr == TSDB_RELATION_AND); - tSQLSyntaxNode *pFirst = NULL; - tSQLSyntaxNode *pSecond = NULL; + tExprNode *pFirst = NULL; + tExprNode *pSecond = NULL; if (pLeft->_node.hasPK == 1) { pFirst = pLeft; pSecond = pRight; @@ -810,14 +822,14 @@ void tSQLBinaryExprTraverse(tSQLSyntaxNode *pExpr, SSkipList *pSkipList, SArray } } -void tSQLBinaryExprCalcTraverse(tSQLSyntaxNode *pExprs, int32_t numOfRows, char *pOutput, void *param, int32_t order, +void tSQLBinaryExprCalcTraverse(tExprNode *pExprs, int32_t numOfRows, char *pOutput, void *param, int32_t order, char *(*getSourceDataBlock)(void *, char *, int32_t)) { if (pExprs == NULL) { return; } - tSQLSyntaxNode *pLeft = pExprs->_node.pLeft; - tSQLSyntaxNode *pRight = pExprs->_node.pRight; + tExprNode *pLeft = pExprs->_node.pLeft; + tExprNode *pRight = pExprs->_node.pRight; /* the left output has result from the left child syntax tree */ char *pLeftOutput = (char*)malloc(sizeof(int64_t) * numOfRows); @@ -890,13 +902,13 @@ void tSQLBinaryExprCalcTraverse(tSQLSyntaxNode *pExprs, int32_t numOfRows, char free(pRightOutput); } -void tSQLBinaryExprTrv(tSQLSyntaxNode *pExprs, int32_t *val, int16_t *ids) { +void tSQLBinaryExprTrv(tExprNode *pExprs, int32_t *val, int16_t *ids) { if (pExprs == NULL) { return; } - tSQLSyntaxNode *pLeft = pExprs->_node.pLeft; - tSQLSyntaxNode *pRight = pExprs->_node.pRight; + tExprNode *pLeft = pExprs->_node.pLeft; + tExprNode *pRight = pExprs->_node.pRight; // recursive traverse left child branch if (pLeft->nodeType == TSQL_NODE_EXPR) { @@ -914,11 +926,97 @@ void tSQLBinaryExprTrv(tSQLSyntaxNode *pExprs, int32_t *val, int16_t *ids) { } } -void tQueryResultClean(tQueryResultset *pRes) { - if (pRes == NULL) { - return; +static void exprTreeToBinaryImpl(tExprNode* pExprTree, SBuffer* pBuf) { + tbufWrite(pBuf, &pExprTree->nodeType, sizeof(pExprTree->nodeType)); + + if (pExprTree->nodeType == TSQL_NODE_VALUE) { + tVariant* pVal = pExprTree->pVal; + + tbufWrite(pBuf, &pVal->nType, sizeof(pVal->nType)); + if (pVal->nType == TSDB_DATA_TYPE_BINARY) { + tbufWrite(pBuf, &pVal->nLen, sizeof(pVal->nLen)); + tbufWrite(pBuf, pVal->pz, pVal->nLen); + } else { + tbufWrite(pBuf, &pVal->pz, sizeof(pVal->i64Key)); + } + + } else if (pExprTree->nodeType == TSQL_NODE_COL) { + SSchema* pSchema = pExprTree->pSchema; + tbufWrite(pBuf, &pSchema->colId, sizeof(pSchema->colId)); + tbufWrite(pBuf, &pSchema->bytes, sizeof(pSchema->bytes)); + tbufWrite(pBuf, &pSchema->type, sizeof(pSchema->type)); + + int32_t len = strlen(pSchema->name); + tbufWriteStringLen(pBuf, pSchema->name, len); + + } else if (pExprTree->nodeType == TSQL_NODE_EXPR) { + tbufWrite(pBuf, &pExprTree->_node.optr, sizeof(pExprTree->_node.optr)); + tbufWrite(pBuf, &pExprTree->_node.hasPK, sizeof(pExprTree->_node.hasPK)); + + exprTreeToBinaryImpl(pExprTree->_node.pLeft, pBuf); + exprTreeToBinaryImpl(pExprTree->_node.pRight, pBuf); } - - tfree(pRes->pRes); - pRes->num = 0; } + +SBuffer exprTreeToBinary(tExprNode* pExprTree) { + SBuffer buf = {0}; + if (pExprTree == NULL) { + return buf; + } + + int32_t code = tbufBeginWrite(&buf); + if (code != 0) { + return buf; + } + + exprTreeToBinaryImpl(pExprTree, &buf); + return buf; +} + +static void exprTreeFromBinaryImpl(tExprNode** pExprTree, SBuffer* pBuf) { + tExprNode* pExpr = calloc(1, sizeof(tExprNode)); + tbufReadToBuffer(pBuf, &pExpr->nodeType, sizeof(pExpr->nodeType)); + + if (pExpr->nodeType == TSQL_NODE_VALUE) { + tVariant* pVal = calloc(1, sizeof(tVariant)); + + tbufReadToBuffer(pBuf, &pVal->nType, sizeof(pVal->nType)); + if (pVal->nType == TSDB_DATA_TYPE_BINARY) { + tbufReadToBuffer(pBuf, &pVal->nLen, sizeof(pVal->nLen)); + pVal->pz = calloc(1, pVal->nLen + 1); + tbufReadToBuffer(pBuf, pVal->pz, pVal->nLen); + } else { + tbufReadToBuffer(pBuf, &pVal->pz, sizeof(pVal->i64Key)); + } + + pExpr->pVal = pVal; + } else if (pExpr->nodeType == TSQL_NODE_COL) { + SSchema* pSchema = calloc(1, sizeof(SSchema)); + tbufReadToBuffer(pBuf, &pSchema->colId, sizeof(pSchema->colId)); + tbufReadToBuffer(pBuf, &pSchema->bytes, sizeof(pSchema->bytes)); + tbufReadToBuffer(pBuf, &pSchema->type, sizeof(pSchema->type)); + + tbufReadToString(pBuf, pSchema->name, TSDB_COL_NAME_LEN); + + pExpr->pSchema = pSchema; + } else if (pExpr->nodeType == TSQL_NODE_EXPR) { + tbufReadToBuffer(pBuf, &pExpr->_node.optr, sizeof(pExpr->_node.optr)); + tbufReadToBuffer(pBuf, &pExpr->_node.hasPK, sizeof(pExpr->_node.hasPK)); + + exprTreeFromBinaryImpl(&pExpr->_node.pLeft, pBuf); + exprTreeFromBinaryImpl(&pExpr->_node.pRight, pBuf); + + assert(pExpr->_node.pLeft != NULL && pExpr->_node.pRight != NULL); + } + + *pExprTree = pExpr; +} + +tExprNode* exprTreeFromBinary(const void* pBuf, size_t size) { + SBuffer rbuf = {0}; + /*int32_t code =*/ tbufBeginRead(&rbuf, pBuf, size); + + tExprNode* pExprNode = NULL; + exprTreeFromBinaryImpl(&pExprNode, &rbuf); + return pExprNode; +} \ No newline at end of file diff --git a/src/query/src/qtokenizer.c b/src/query/src/qtokenizer.c index 61d2e59c87..51b196a9da 100644 --- a/src/query/src/qtokenizer.c +++ b/src/query/src/qtokenizer.c @@ -13,10 +13,10 @@ * along with this program. If not, see . */ +#include "os.h" + #include "hash.h" #include "hashfunc.h" -#include "os.h" -#include "shash.h" #include "taosdef.h" #include "tstoken.h" #include "ttokendef.h" diff --git a/src/query/src/queryExecutor.c b/src/query/src/queryExecutor.c index a32c8638ce..20697f3227 100644 --- a/src/query/src/queryExecutor.c +++ b/src/query/src/queryExecutor.c @@ -87,8 +87,6 @@ typedef enum { static void setQueryStatus(SQuery *pQuery, int8_t status); bool isIntervalQuery(SQuery *pQuery) { return pQuery->intervalTime > 0; } -int32_t setQueryCtxForTableQuery(void *pReadMsg, SQInfo **pQInfo) {} - enum { TS_JOIN_TS_EQUAL = 0, TS_JOIN_TS_NOT_EQUALS = 1, @@ -1021,7 +1019,7 @@ static int32_t setGroupResultOutputBuf(SQueryRuntimeEnv *pRuntimeEnv, char *pDat return TSDB_CODE_SUCCESS; } -static char *getGroupbyColumnData(SQuery *pQuery, SData **data, int16_t *type, int16_t *bytes) { +static UNUSED_FUNC char *getGroupbyColumnData(SQuery *pQuery, SData **data, int16_t *type, int16_t *bytes) { char *groupbyColumnData = NULL; SSqlGroupbyExpr *pGroupbyExpr = pQuery->pGroupbyExpr; @@ -1295,7 +1293,7 @@ static int32_t rowwiseApplyAllFunctions(SQueryRuntimeEnv *pRuntimeEnv, SDataStat return num; } -static int32_t reviseForwardSteps(SQueryRuntimeEnv *pRuntimeEnv, int32_t forwardStep) { +static UNUSED_FUNC int32_t reviseForwardSteps(SQueryRuntimeEnv *pRuntimeEnv, int32_t forwardStep) { /* * 1. If value filter exists, we try all data in current block, and do not set the QUERY_RESBUF_FULL flag. * @@ -1719,7 +1717,7 @@ void doGetAlignedIntervalQueryRangeImpl(SQuery *pQuery, int64_t key, int64_t key } } -static bool doGetQueryPos(TSKEY key, SQInfo *pQInfo, SPointInterpoSupporter *pPointInterpSupporter) { +static UNUSED_FUNC bool doGetQueryPos(TSKEY key, SQInfo *pQInfo, SPointInterpoSupporter *pPointInterpSupporter) { #if 0 SQueryRuntimeEnv *pRuntimeEnv = &pQInfo->runtimeEnv; SQuery * pQuery = pRuntimeEnv->pQuery; @@ -1742,7 +1740,7 @@ static bool doGetQueryPos(TSKEY key, SQInfo *pQInfo, SPointInterpoSupporter *pPo #endif } -static bool doSetDataInfo(SQInfo *pQInfo, SPointInterpoSupporter *pPointInterpSupporter, void *pMeterObj, +static UNUSED_FUNC bool doSetDataInfo(SQInfo *pQInfo, SPointInterpoSupporter *pPointInterpSupporter, void *pMeterObj, TSKEY nextKey) { SQueryRuntimeEnv *pRuntimeEnv = &pQInfo->runtimeEnv; SQuery * pQuery = pRuntimeEnv->pQuery; @@ -2175,7 +2173,7 @@ void pointInterpSupporterDestroy(SPointInterpoSupporter *pPointInterpSupport) { pPointInterpSupport->numOfCols = 0; } -static void allocMemForInterpo(SQInfo *pQInfo, SQuery *pQuery, void *pMeterObj) { +static UNUSED_FUNC void allocMemForInterpo(SQInfo *pQInfo, SQuery *pQuery, void *pMeterObj) { #if 0 if (pQuery->interpoType != TSDB_INTERPO_NONE) { assert(isIntervalQuery(pQuery) || (pQuery->intervalTime == 0 && isPointInterpoQuery(pQuery))); @@ -2609,7 +2607,6 @@ static int64_t doScanAllDataBlocks(SQueryRuntimeEnv *pRuntimeEnv) { GET_QINFO_ADDR(pRuntimeEnv), pQuery->window.skey, pQuery->window.ekey, pQuery->lastKey, pQuery->order.order); tsdb_query_handle_t pQueryHandle = pRuntimeEnv->pQueryHandle; - while (tsdbNextDataBlock(pQueryHandle)) { // check if query is killed or not set the status of query to pass the status check if (isQueryKilled(GET_QINFO_ADDR(pRuntimeEnv))) { @@ -2768,7 +2765,7 @@ static void doMerge(SQueryRuntimeEnv *pRuntimeEnv, int64_t timestamp, SWindowRes } } -static void printBinaryData(int32_t functionId, char *data, int32_t srcDataType) { +static UNUSED_FUNC void printBinaryData(int32_t functionId, char *data, int32_t srcDataType) { if (functionId == TSDB_FUNC_FIRST_DST || functionId == TSDB_FUNC_LAST_DST) { switch (srcDataType) { case TSDB_DATA_TYPE_BINARY: @@ -4038,7 +4035,7 @@ bool vnodeHasRemainResults(void *handle) { } } -static int32_t resultInterpolate(SQInfo *pQInfo, tFilePage **data, tFilePage **pDataSrc, int32_t numOfRows, +static UNUSED_FUNC int32_t resultInterpolate(SQInfo *pQInfo, tFilePage **data, tFilePage **pDataSrc, int32_t numOfRows, int32_t outputRows) { #if 0 SQueryRuntimeEnv *pRuntimeEnv = &pQInfo->runtimeEnv; @@ -4130,6 +4127,8 @@ int32_t vnodeQueryResultInterpolate(SQInfo *pQInfo, tFilePage **pDst, tFilePage } } #endif + + return 0; } void vnodePrintQueryStatistics(SQInfo *pQInfo) { @@ -4300,7 +4299,7 @@ int32_t doInitializeQInfo(SQInfo *pQInfo, void *param, void* tsdb, bool isSTable return TSDB_CODE_SUCCESS; } -static bool isGroupbyEachTable(SSqlGroupbyExpr *pGroupbyExpr, tSidSet *pSidset) { +static UNUSED_FUNC bool isGroupbyEachTable(SSqlGroupbyExpr *pGroupbyExpr, tSidSet *pSidset) { if (pGroupbyExpr == NULL || pGroupbyExpr->numOfGroupCols == 0) { return false; } @@ -4316,7 +4315,7 @@ static bool isGroupbyEachTable(SSqlGroupbyExpr *pGroupbyExpr, tSidSet *pSidset) return false; } -static bool doCheckWithPrevQueryRange(SQuery *pQuery, TSKEY nextKey) { +static UNUSED_FUNC bool doCheckWithPrevQueryRange(SQuery *pQuery, TSKEY nextKey) { if ((nextKey > pQuery->window.ekey && QUERY_IS_ASC_QUERY(pQuery)) || (nextKey < pQuery->window.ekey && !QUERY_IS_ASC_QUERY(pQuery))) { return false; @@ -4325,7 +4324,7 @@ static bool doCheckWithPrevQueryRange(SQuery *pQuery, TSKEY nextKey) { return true; } -static void enableExecutionForNextTable(SQueryRuntimeEnv *pRuntimeEnv) { +static UNUSED_FUNC void enableExecutionForNextTable(SQueryRuntimeEnv *pRuntimeEnv) { SQuery *pQuery = pRuntimeEnv->pQuery; for (int32_t i = 0; i < pQuery->numOfOutputCols; ++i) { @@ -4443,7 +4442,7 @@ static bool multimeterMultioutputHelper(SQInfo *pQInfo, bool *dataInDisk, bool * return true; } -static int64_t doCheckMetersInGroup(SQInfo *pQInfo, int32_t index, int32_t start) { +static UNUSED_FUNC int64_t doCheckMetersInGroup(SQInfo *pQInfo, int32_t index, int32_t start) { SQueryRuntimeEnv *pRuntimeEnv = &pQInfo->runtimeEnv; SQuery * pQuery = pRuntimeEnv->pQuery; @@ -5149,7 +5148,7 @@ static void singleTableQueryImpl(SQInfo* pQInfo) { int64_t st = taosGetTimestampUs(); // group by normal column, sliding window query, interval query are handled by interval query processor - if (pQuery->intervalTime != 0 || isGroupbyNormalCol(pQuery->pGroupbyExpr)) { // interval (down sampling operation) + if (isIntervalQuery(pQuery) || isGroupbyNormalCol(pQuery->pGroupbyExpr)) { // interval (down sampling operation) tableIntervalProcessor(pQInfo); } else { if (isFixedOutputQuery(pQuery)) { @@ -5461,7 +5460,7 @@ static int32_t buildAirthmeticExprFromMsg(SSqlFunctionExpr *pExpr, SQueryTableMs SSqlBinaryExprInfo *pBinaryExprInfo = &pExpr->binExprInfo; SColumnInfo * pColMsg = pQueryMsg->colList; #if 0 - tSQLSyntaxNode* pBinExpr = NULL; + tExprNode* pBinExpr = NULL; SSchema* pSchema = toSchema(pQueryMsg, pColMsg, pQueryMsg->numOfCols); dTrace("qmsg:%p create binary expr from string:%s", pQueryMsg, pExpr->pBase.arg[0].argValue.pz); @@ -5527,8 +5526,6 @@ static int32_t createSqlFunctionExprFromMsg(SQueryTableMsg *pQueryMsg, SSqlFunct int16_t type = 0; int16_t bytes = 0; - SColIndexEx *pColumnIndexExInfo = &pExprs[i].pBase.colInfo; - // parse the arithmetic expression if (pExprs[i].pBase.functionId == TSDB_FUNC_ARITHM) { code = buildAirthmeticExprFromMsg(&pExprs[i], pQueryMsg); @@ -5962,7 +5959,7 @@ static void freeQInfo(SQInfo *pQInfo) { if (pBinExprInfo->numOfCols > 0) { tfree(pBinExprInfo->pReqColumns); - tSQLBinaryExprDestroy(&pBinExprInfo->pBinExpr, NULL); + tExprTreeDestroy(&pBinExprInfo->pBinExpr, NULL); } } diff --git a/src/query/src/queryUtil.c b/src/query/src/queryUtil.c index d954c10849..17410b2868 100644 --- a/src/query/src/queryUtil.c +++ b/src/query/src/queryUtil.c @@ -24,6 +24,7 @@ #include "ttime.h" #include "queryExecutor.h" +#include "queryUtil.h" int32_t initWindowResInfo(SWindowResInfo *pWindowResInfo, SQueryRuntimeEnv *pRuntimeEnv, int32_t size, int32_t threshold, int16_t type) { diff --git a/src/query/tests/astTest.cpp b/src/query/tests/astTest.cpp new file mode 100644 index 0000000000..ac10cd2429 --- /dev/null +++ b/src/query/tests/astTest.cpp @@ -0,0 +1,630 @@ +#include +#include +#include +#include +#include + +#include "qast.h" +#include "taosmsg.h" +#include "tsdb.h" +#include "tskiplist.h" + +typedef struct ResultObj { + int32_t numOfResult; + char * resultName[64]; +} ResultObj; + +static void initSchema(SSchema *pSchema, int32_t numOfCols); + +static void initSchema_binary(SSchema *schema, int32_t numOfCols); + +static tSkipList *createSkipList(SSchema *pSchema, int32_t numOfTags); +static tSkipList *createSkipList_binary(SSchema *pSchema, int32_t numOfTags); + +static void testQueryStr(SSchema *schema, int32_t numOfCols, char *sql, tSkipList *pSkipList, ResultObj *expectedVal); + +static void dropMeter(tSkipList *pSkipList); + +static void Right2LeftTest(SSchema *schema, int32_t numOfCols, tSkipList *pSkipList); + +static void Left2RightTest(SSchema *schema, int32_t numOfCols, tSkipList *pSkipList); + +static void IllegalExprTest(SSchema *schema, int32_t numOfCols, tSkipList *pSkipList); + +static void Left2RightTest_binary(SSchema *schema, int32_t numOfCols, tSkipList *pSkipList); +static void Right2LeftTest_binary(SSchema *schema, int32_t numOfCols, tSkipList *pSkipList); + +void setValue(ResultObj *pResult, int32_t num, char **val) { + pResult->numOfResult = num; + for (int32_t i = 0; i < num; ++i) { + pResult->resultName[i] = val[i]; + } +} + +static void initSchema_binary(SSchema *schema, int32_t numOfCols) { + schema[0].type = TSDB_DATA_TYPE_BINARY; + schema[0].bytes = 8; + strcpy(schema[0].name, "a"); + + schema[1].type = TSDB_DATA_TYPE_DOUBLE; + schema[1].bytes = 8; + strcpy(schema[1].name, "b"); + + schema[2].type = TSDB_DATA_TYPE_INT; + schema[2].bytes = 20; + strcpy(schema[2].name, "c"); + + schema[3].type = TSDB_DATA_TYPE_BIGINT; + schema[3].bytes = 8; + strcpy(schema[3].name, "d"); + + schema[4].type = TSDB_DATA_TYPE_SMALLINT; + schema[4].bytes = 2; + strcpy(schema[4].name, "e"); + + schema[5].type = TSDB_DATA_TYPE_TINYINT; + schema[5].bytes = 1; + strcpy(schema[5].name, "f"); + + schema[6].type = TSDB_DATA_TYPE_FLOAT; + schema[6].bytes = 4; + strcpy(schema[6].name, "g"); + + schema[7].type = TSDB_DATA_TYPE_BOOL; + schema[7].bytes = 1; + strcpy(schema[7].name, "h"); +} + +static void initSchema(SSchema *schema, int32_t numOfCols) { + schema[0].type = TSDB_DATA_TYPE_INT; + schema[0].bytes = 8; + strcpy(schema[0].name, "a"); + + schema[1].type = TSDB_DATA_TYPE_DOUBLE; + schema[1].bytes = 8; + strcpy(schema[1].name, "b"); + + schema[2].type = TSDB_DATA_TYPE_BINARY; + schema[2].bytes = 20; + strcpy(schema[2].name, "c"); + + schema[3].type = TSDB_DATA_TYPE_BIGINT; + schema[3].bytes = 8; + strcpy(schema[3].name, "d"); + + schema[4].type = TSDB_DATA_TYPE_SMALLINT; + schema[4].bytes = 2; + strcpy(schema[4].name, "e"); + + schema[5].type = TSDB_DATA_TYPE_TINYINT; + schema[5].bytes = 1; + strcpy(schema[5].name, "f"); + + schema[6].type = TSDB_DATA_TYPE_FLOAT; + schema[6].bytes = 4; + strcpy(schema[6].name, "g"); + + schema[7].type = TSDB_DATA_TYPE_BOOL; + schema[7].bytes = 1; + strcpy(schema[7].name, "h"); +} + +// static void addOneNode(SSchema *pSchema, int32_t tagsLen, tSkipList *pSkipList, +// char *meterId, int32_t a, double b, char *c, int64_t d, int16_t e, int8_t f, float g, +// bool h, int32_t numOfTags) { +// STabObj *pMeter = calloc(1, sizeof(STabObj)); +// pMeter->numOfTags = numOfTags; +// pMeter->pTagData = calloc(1, tagsLen + TSDB_METER_ID_LEN); +// strcpy(pMeter->meterId, meterId); +// +// char *tags = pMeter->pTagData + TSDB_METER_ID_LEN; +// int32_t offset = 0; +// +// *(int32_t *) tags = a; +// +// offset += pSchema[0].bytes; +// *(double *) (tags + offset) = b; +// +// offset += pSchema[1].bytes; +// memcpy(tags + offset, c, 3); +// +// offset += pSchema[2].bytes; +// *(int64_t *) (tags + offset) = d; +// +// offset += pSchema[3].bytes; +// *(int16_t *) (tags + offset) = e; +// +// offset += pSchema[4].bytes; +// *(int8_t *) (tags + offset) = f; +// +// offset += pSchema[5].bytes; +// *(float *) (tags + offset) = g; +// +// offset += pSchema[6].bytes; +// *(int8_t *) (tags + offset) = h ? 1 : 0; +// +// tSkipListKey pKey = tSkipListCreateKey(pSchema[0].type, tags, pSchema[0].bytes); +// tSkipListPut(pSkipList, pMeter, &pKey, 1); +//} +// +// static void addOneNode_binary(SSchema *pSchema, int32_t tagsLen, tSkipList *pSkipList, +// char *meterId, int32_t a, double b, char *c, int64_t d, int16_t e, int8_t f, float g, +// bool h, int32_t numOfTags) { +// STabObj *pMeter = calloc(1, sizeof(STabObj)); +// pMeter->numOfTags = numOfTags; +// pMeter->pTagData = calloc(1, tagsLen + TSDB_METER_ID_LEN); +// strcpy(pMeter->meterId, meterId); +// +// char *tags = pMeter->pTagData + TSDB_METER_ID_LEN; +// int32_t offset = 0; +// memcpy(tags, c, pSchema[0].bytes); +// +// offset += pSchema[0].bytes; +// *(double *) (tags + offset) = b; +// +// offset += pSchema[1].bytes; +// *(int32_t *) (tags + offset) = a; +// +// offset += pSchema[2].bytes; +// *(int64_t *) (tags + offset) = d; +// +// offset += pSchema[3].bytes; +// *(int16_t *) (tags + offset) = e; +// +// offset += pSchema[4].bytes; +// *(int8_t *) (tags + offset) = f; +// +// offset += pSchema[5].bytes; +// *(float *) (tags + offset) = g; +// +// offset += pSchema[6].bytes; +// *(int8_t *) (tags + offset) = h ? 1 : 0; +// +// tSkipListKey pKey = tSkipListCreateKey(pSchema[0].type, tags, pSchema[0].bytes); +// tSkipListPut(pSkipList, pMeter, &pKey, 1); +// tSkipListDestroyKey(&pKey); +//} + +// static void dropMeter(tSkipList *pSkipList) { +// tSkipListNode **pRes = NULL; +// int32_t num = tSkipListIterateList(pSkipList, &pRes, NULL, NULL); +// for (int32_t i = 0; i < num; ++i) { +// tSkipListNode *pNode = pRes[i]; +// STabObj *pMeter = (STabObj *) pNode->pData; +// free(pMeter->pTagData); +// free(pMeter); +// pNode->pData = NULL; +// } +// free(pRes); +//} + +// static tSkipList *createSkipList(SSchema *pSchema, int32_t numOfTags) { +// int32_t tagsLen = 0; +// for (int32_t i = 0; i < numOfTags; ++i) { +// tagsLen += pSchema[i].bytes; +// } +// +// tSkipList *pSkipList = tSkipListCreate(10, pSchema[0].type, 4); +// +// addOneNode(pSchema, tagsLen, pSkipList, "tm0\0", 0, 10.5, "abc", 1000, -10000, -20, 1.0, true, 8); +// addOneNode(pSchema, tagsLen, pSkipList, "tm1\0", 1, 20.5, "def", 1100, -10500, -30, 2.0, false, 8); +// addOneNode(pSchema, tagsLen, pSkipList, "tm2\0", 2, 30.5, "ghi", 1200, -11000, -40, 3.0, true, 8); +// addOneNode(pSchema, tagsLen, pSkipList, "tm3\0", 3, 40.5, "jkl", 1300, -11500, -50, 4.0, false, 8); +// addOneNode(pSchema, tagsLen, pSkipList, "tm4\0", 4, 50.5, "mno", 1400, -12000, -60, 5.0, true, 8); +// addOneNode(pSchema, tagsLen, pSkipList, "tm5\0", 5, 60.5, "pqr", 1500, -12500, -70, 6.0, false, 8); +// addOneNode(pSchema, tagsLen, pSkipList, "tm6\0", 6, 70.5, "stu", 1600, -13000, -80, 7.0, true, 8); +// +// return pSkipList; +//} +// +// static tSkipList *createSkipList_binary(SSchema *pSchema, int32_t numOfTags) { +// int32_t tagsLen = 0; +// for (int32_t i = 0; i < numOfTags; ++i) { +// tagsLen += pSchema[i].bytes; +// } +// +// tSkipList *pSkipList = tSkipListCreate(10, pSchema[0].type, 4); +// +// addOneNode_binary(pSchema, tagsLen, pSkipList, "tm0\0", 0, 10.5, "abc", 1000, -10000, -20, 1.0, true, 8); +// addOneNode_binary(pSchema, tagsLen, pSkipList, "tm1\0", 1, 20.5, "def", 1100, -10500, -30, 2.0, false, 8); +// addOneNode_binary(pSchema, tagsLen, pSkipList, "tm2\0", 2, 30.5, "ghi", 1200, -11000, -40, 3.0, true, 8); +// addOneNode_binary(pSchema, tagsLen, pSkipList, "tm3\0", 3, 40.5, "jkl", 1300, -11500, -50, 4.0, false, 8); +// addOneNode_binary(pSchema, tagsLen, pSkipList, "tm4\0", 4, 50.5, "mno", 1400, -12000, -60, 5.0, true, 8); +// addOneNode_binary(pSchema, tagsLen, pSkipList, "tm5\0", 5, 60.5, "pqr", 1500, -12500, -70, 6.0, false, 8); +// addOneNode_binary(pSchema, tagsLen, pSkipList, "tm6\0", 6, 70.5, "stu", 1600, -13000, -80, 7.0, true, 8); +// +// return pSkipList; +//} + +static void testQueryStr(SSchema *schema, int32_t numOfCols, char *sql, tSkipList *pSkipList, ResultObj *pResult) { + tExprNode *pExpr = NULL; + tSQLBinaryExprFromString(&pExpr, schema, numOfCols, sql, strlen(sql)); + + char str[512] = {0}; + int32_t len = 0; + if (pExpr == NULL) { + printf("-----error in parse syntax:%s\n\n", sql); + assert(pResult == NULL); + return; + } + + tSQLBinaryExprToString(pExpr, str, &len); + printf("expr is: %s\n", str); + + SArray *result = NULL; + // tSQLBinaryExprTraverse(pExpr, pSkipList, result, tSkipListNodeFilterCallback, &result); + // printf("the result is:%lld\n", result.num); + // + // bool findResult = false; + // for (int32_t i = 0; i < result.num; ++i) { + // STabObj *pm = (STabObj *)result.pRes[i]; + // printf("meterid:%s,\t", pm->meterId); + // + // for (int32_t j = 0; j < pResult->numOfResult; ++j) { + // if (strcmp(pm->meterId, pResult->resultName[j]) == 0) { + // findResult = true; + // break; + // } + // } + // assert(findResult == true); + // findResult = false; + // } + + printf("\n\n"); + tExprTreeDestroy(&pExpr, NULL); +} + +static void Left2RightTest(SSchema *schema, int32_t numOfCols, tSkipList *pSkipList) { + char str[256] = {0}; + + char *t0[1] = {"tm0"}; + char *t1[1] = {"tm1"}; + char *sql = NULL; + + ResultObj res = {1, {"tm1"}}; + testQueryStr(schema, numOfCols, "a=1", pSkipList, &res); + + char *tt[1] = {"tm6"}; + setValue(&res, 1, tt); + testQueryStr(schema, numOfCols, "a>=6", pSkipList, &res); + + setValue(&res, 1, t0); + testQueryStr(schema, numOfCols, "b<=10.6", pSkipList, &res); + + strcpy(str, "c<>'pqr'"); + char *t2[6] = {"tm0", "tm1", "tm2", "tm3", "tm4", "tm6"}; + setValue(&res, 6, t2); + testQueryStr(schema, numOfCols, str, pSkipList, &res); + + strcpy(str, "c='abc'"); + setValue(&res, 1, t0); + testQueryStr(schema, numOfCols, str, pSkipList, &res); + + char *t3[6] = {"tm1", "tm2", "tm3", "tm4", "tm5", "tm6"}; + setValue(&res, 6, t3); + testQueryStr(schema, numOfCols, "d>1050", pSkipList, &res); + + char *t4[3] = {"tm4", "tm5", "tm6"}; + setValue(&res, 3, t4); + testQueryStr(schema, numOfCols, "g>4.5980765", pSkipList, &res); + + char *t5[4] = {"tm0", "tm2", "tm4", "tm6"}; + setValue(&res, 4, t5); + testQueryStr(schema, numOfCols, "h=true", pSkipList, &res); + + char *t6[3] = {"tm1", "tm3", "tm5"}; + setValue(&res, 3, t6); + testQueryStr(schema, numOfCols, "h=0", pSkipList, &res); + + sql = "(((b<40)))\0"; + char *t7[3] = {"tm0", "tm1", "tm2"}; + setValue(&res, 3, t7); + testQueryStr(schema, numOfCols, sql, pSkipList, &res); + + sql = "((a=1) or (a=10)) or ((b=12))"; + setValue(&res, 1, t1); + testQueryStr(schema, numOfCols, sql, pSkipList, &res); + + sql = "((((((a>0 and a<2))) or a=6) or a=3) or (b=50.5)) and h=0"; + char *t8[2] = {"tm1", "tm3"}; + setValue(&res, 2, t8); + testQueryStr(schema, numOfCols, sql, pSkipList, &res); + + char *tf[1] = {"tm6"}; + setValue(&res, 1, tf); + testQueryStr(schema, numOfCols, "e = -13000", pSkipList, &res); + + char *ft[5] = {"tm0", "tm1", "tm2", "tm3", "tm4"}; + setValue(&res, 5, ft); + testQueryStr(schema, numOfCols, "f > -65", pSkipList, &res); +} + +void Right2LeftTest(SSchema *schema, int32_t numOfCols, tSkipList *pSkipList) { + ResultObj res = {1, {"tm1"}}; + testQueryStr(schema, numOfCols, "((1=a))", pSkipList, &res); + + char *t9[2] = {"tm0", "tm1"}; + setValue(&res, 2, t9); + testQueryStr(schema, numOfCols, "1>=a", pSkipList, &res); + + char *t0[1] = {"tm0"}; + setValue(&res, 1, t0); + testQueryStr(schema, numOfCols, "10.6>=b", pSkipList, &res); + + char *t10[3] = {"tm1", "tm3", "tm5"}; + setValue(&res, 3, t10); + testQueryStr(schema, numOfCols, "0=h", pSkipList, &res); +} + +static void IllegalExprTest(SSchema *schema, int32_t numOfCols, tSkipList *pSkipList) { + testQueryStr(schema, numOfCols, "h=", pSkipList, NULL); + testQueryStr(schema, numOfCols, "h<", pSkipList, NULL); + testQueryStr(schema, numOfCols, "a=1 and ", pSkipList, NULL); + testQueryStr(schema, numOfCols, "and or", pSkipList, NULL); + testQueryStr(schema, numOfCols, "and a = 1 or", pSkipList, NULL); + testQueryStr(schema, numOfCols, "(())", pSkipList, NULL); + testQueryStr(schema, numOfCols, "(", pSkipList, NULL); + testQueryStr(schema, numOfCols, "(a", pSkipList, NULL); + testQueryStr(schema, numOfCols, "(a)", pSkipList, NULL); + testQueryStr(schema, numOfCols, "())", pSkipList, NULL); + testQueryStr(schema, numOfCols, "a===1", pSkipList, NULL); + testQueryStr(schema, numOfCols, "a=1 and ", pSkipList, NULL); +} + +static void Left2RightTest_binary(SSchema *schema, int32_t numOfCols, tSkipList *pSkipList) { + char str[256] = {0}; + char *sql = NULL; + + char *t0[1] = {"tm0"}; + char *t1[1] = {"tm1"}; + + ResultObj res = {1, {"tm0"}}; + strcpy(str, "a='abc'"); + testQueryStr(schema, numOfCols, str, pSkipList, &res); + + char *tt[1] = {"tm6"}; + setValue(&res, 1, tt); + testQueryStr(schema, numOfCols, "c>=6", pSkipList, &res); + + setValue(&res, 1, t0); + testQueryStr(schema, numOfCols, "b<=10.6", pSkipList, &res); + + strcpy(str, "a<>'pqr'"); + char *t2[6] = {"tm0", "tm1", "tm2", "tm3", "tm4", "tm6"}; + setValue(&res, 6, t2); + testQueryStr(schema, numOfCols, str, pSkipList, &res); + + strcpy(str, "a='abc'"); + setValue(&res, 1, t0); + testQueryStr(schema, numOfCols, str, pSkipList, &res); + + char *t3[6] = {"tm1", "tm2", "tm3", "tm4", "tm5", "tm6"}; + setValue(&res, 6, t3); + testQueryStr(schema, numOfCols, "d>1050", pSkipList, &res); + + char *t4[3] = {"tm4", "tm5", "tm6"}; + setValue(&res, 3, t4); + testQueryStr(schema, numOfCols, "g>4.5980765", pSkipList, &res); + + char *t5[4] = {"tm0", "tm2", "tm4", "tm6"}; + setValue(&res, 4, t5); + testQueryStr(schema, numOfCols, "h=true", pSkipList, &res); + + char *t6[3] = {"tm1", "tm3", "tm5"}; + setValue(&res, 3, t6); + testQueryStr(schema, numOfCols, "h=0", pSkipList, &res); + + sql = "(((b<40)))\0"; + char *t7[3] = {"tm0", "tm1", "tm2"}; + setValue(&res, 3, t7); + testQueryStr(schema, numOfCols, sql, pSkipList, &res); + + sql = "((c=1) or (c=10)) or ((b=12))\0"; + setValue(&res, 1, t1); + testQueryStr(schema, numOfCols, sql, pSkipList, &res); + + sql = "((((((c>0 and c<2))) or c=6) or c=3) or (b=50.5)) and h=false\0"; + char *t8[2] = {"tm1", "tm3"}; + setValue(&res, 2, t8); + testQueryStr(schema, numOfCols, sql, pSkipList, &res); +} + +static void Right2LeftTest_binary(SSchema *schema, int32_t numOfCols, tSkipList *pSkipList) { + char str[256] = {0}; + char *sql = NULL; + + char *t0[1] = {"tm0"}; + char *t1[1] = {"tm1"}; + + ResultObj res = {1, {"tm0"}}; + strcpy(str, "'abc'=a"); + testQueryStr(schema, numOfCols, str, pSkipList, &res); + + char *tt[1] = {"tm6"}; + setValue(&res, 1, tt); + testQueryStr(schema, numOfCols, "6<=c", pSkipList, &res); + + setValue(&res, 1, t0); + testQueryStr(schema, numOfCols, "10.6>=b", pSkipList, &res); + + strcpy(str, "'pqr'<>a"); + char *t2[6] = {"tm0", "tm1", "tm2", "tm3", "tm4", "tm6"}; + setValue(&res, 6, t2); + testQueryStr(schema, numOfCols, str, pSkipList, &res); +} + +namespace { +// two level expression tree +tExprNode *createExpr1() { + auto *pLeft = (tExprNode*) calloc(1, sizeof(tExprNode)); + pLeft->nodeType = TSQL_NODE_COL; + pLeft->pSchema = (SSchema*) calloc(1, sizeof(SSchema)); + + strcpy(pLeft->pSchema->name, "col_a"); + pLeft->pSchema->type = TSDB_DATA_TYPE_INT; + pLeft->pSchema->bytes = sizeof(int32_t); + pLeft->pSchema->colId = 1; + + auto *pRight = (tExprNode*) calloc(1, sizeof(tExprNode)); + pRight->nodeType = TSQL_NODE_VALUE; + pRight->pVal = (tVariant*) calloc(1, sizeof(tVariant)); + + pRight->pVal->nType = TSDB_DATA_TYPE_INT; + pRight->pVal->i64Key = 12; + + auto *pRoot = (tExprNode*) calloc(1, sizeof(tExprNode)); + pRoot->nodeType = TSQL_NODE_EXPR; + + pRoot->_node.optr = TSDB_RELATION_EQUAL; + pRoot->_node.pLeft = pLeft; + pRoot->_node.pRight = pRight; + pRoot->_node.hasPK = true; + + return pRoot; +} + +// thress level expression tree +tExprNode* createExpr2() { + auto *pLeft2 = (tExprNode*) calloc(1, sizeof(tExprNode)); + pLeft2->nodeType = TSQL_NODE_COL; + pLeft2->pSchema = (SSchema*) calloc(1, sizeof(SSchema)); + + strcpy(pLeft2->pSchema->name, "col_a"); + pLeft2->pSchema->type = TSDB_DATA_TYPE_BINARY; + pLeft2->pSchema->bytes = 20; + pLeft2->pSchema->colId = 1; + + auto *pRight2 = (tExprNode*) calloc(1, sizeof(tExprNode)); + pRight2->nodeType = TSQL_NODE_VALUE; + pRight2->pVal = (tVariant*) calloc(1, sizeof(tVariant)); + + pRight2->pVal->nType = TSDB_DATA_TYPE_BINARY; + const char* v = "hello world!"; + pRight2->pVal->pz = strdup(v); + pRight2->pVal->nLen = strlen(v); + + auto *p1 = (tExprNode*) calloc(1, sizeof(tExprNode)); + p1->nodeType = TSQL_NODE_EXPR; + + p1->_node.optr = TSDB_RELATION_LIKE; + p1->_node.pLeft = pLeft2; + p1->_node.pRight = pRight2; + p1->_node.hasPK = false; + + auto *pLeft1 = (tExprNode*) calloc(1, sizeof(tExprNode)); + pLeft1->nodeType = TSQL_NODE_COL; + pLeft1->pSchema = (SSchema*) calloc(1, sizeof(SSchema)); + + strcpy(pLeft1->pSchema->name, "col_b"); + pLeft1->pSchema->type = TSDB_DATA_TYPE_DOUBLE; + pLeft1->pSchema->bytes = 8; + pLeft1->pSchema->colId = 99; + + auto *pRight1 = (tExprNode*) calloc(1, sizeof(tExprNode)); + pRight1->nodeType = TSQL_NODE_VALUE; + pRight1->pVal = (tVariant*) calloc(1, sizeof(tVariant)); + + pRight1->pVal->nType = TSDB_DATA_TYPE_DOUBLE; + pRight1->pVal->dKey = 91.99; + + auto *p2 = (tExprNode*) calloc(1, sizeof(tExprNode)); + p2->nodeType = TSQL_NODE_EXPR; + + p2->_node.optr = TSDB_RELATION_LARGE_EQUAL; + p2->_node.pLeft = pLeft1; + p2->_node.pRight = pRight1; + p2->_node.hasPK = false; + + auto *pRoot = (tExprNode*) calloc(1, sizeof(tExprNode)); + pRoot->nodeType = TSQL_NODE_EXPR; + + pRoot->_node.optr = TSDB_RELATION_OR; + pRoot->_node.pLeft = p1; + pRoot->_node.pRight = p2; + pRoot->_node.hasPK = true; + return pRoot; +} + +void exprSerializeTest1() { + tExprNode* p1 = createExpr1(); + SBuffer buf = exprTreeToBinary(p1); + + size_t size = tbufTell(&buf); + ASSERT_TRUE(size > 0); + char* b = tbufGetData(&buf, false); + + tExprNode* p2 = exprTreeFromBinary(b, size); + ASSERT_EQ(p1->nodeType, p2->nodeType); + + ASSERT_EQ(p2->_node.optr, p1->_node.optr); + ASSERT_EQ(p2->_node.pLeft->nodeType, p1->_node.pLeft->nodeType); + ASSERT_EQ(p2->_node.pRight->nodeType, p1->_node.pRight->nodeType); + + SSchema* s1 = p1->_node.pLeft->pSchema; + SSchema* s2 = p2->_node.pLeft->pSchema; + + ASSERT_EQ(s2->colId, s1->colId); + ASSERT_EQ(s2->type, s1->type); + ASSERT_EQ(s2->bytes, s1->bytes); + ASSERT_STRCASEEQ(s2->name, s1->name); + + tVariant* v1 = p1->_node.pRight->pVal; + tVariant* v2 = p2->_node.pRight->pVal; + + ASSERT_EQ(v1->nType, v2->nType); + ASSERT_EQ(v1->i64Key, v2->i64Key); + ASSERT_EQ(p1->_node.hasPK, p2->_node.hasPK); + + tExprTreeDestroy(&p1, nullptr); + tExprTreeDestroy(&p2, nullptr); + + tbufClose(&buf, false); +} + +void exprSerializeTest2() { + tExprNode* p1 = createExpr2(); + SBuffer buf = exprTreeToBinary(p1); + + size_t size = tbufTell(&buf); + ASSERT_TRUE(size > 0); + char* b = tbufGetData(&buf, false); + + tExprNode* p2 = exprTreeFromBinary(b, size); + ASSERT_EQ(p1->nodeType, p2->nodeType); + + ASSERT_EQ(p2->_node.optr, p1->_node.optr); + ASSERT_EQ(p2->_node.pLeft->nodeType, p1->_node.pLeft->nodeType); + ASSERT_EQ(p2->_node.pRight->nodeType, p1->_node.pRight->nodeType); + + tExprNode* c1Left = p1->_node.pLeft; + tExprNode* c2Left = p2->_node.pLeft; + + ASSERT_EQ(c1Left->nodeType, c2Left->nodeType); + + ASSERT_EQ(c2Left->nodeType, TSQL_NODE_EXPR); + ASSERT_EQ(c2Left->_node.optr, TSDB_RELATION_LIKE); + + ASSERT_STRCASEEQ(c2Left->_node.pLeft->pSchema->name, "col_a"); + ASSERT_EQ(c2Left->_node.pRight->nodeType, TSQL_NODE_VALUE); + + ASSERT_STRCASEEQ(c2Left->_node.pRight->pVal->pz, "hello world!"); + + tExprNode* c1Right = p1->_node.pRight; + tExprNode* c2Right = p2->_node.pRight; + + ASSERT_EQ(c1Right->nodeType, c2Right->nodeType); + ASSERT_EQ(c2Right->nodeType, TSQL_NODE_EXPR); + ASSERT_EQ(c2Right->_node.optr, TSDB_RELATION_LARGE_EQUAL); + ASSERT_EQ(c2Right->_node.pRight->pVal->dKey, 91.99); + + ASSERT_EQ(p2->_node.hasPK, true); + + tExprTreeDestroy(&p1, nullptr); + tExprTreeDestroy(&p2, nullptr); + + tbufClose(&buf, false); +} +} // namespace +TEST(testCase, astTest) { + exprSerializeTest2(); +} \ No newline at end of file diff --git a/src/rpc/src/rpcMain.c b/src/rpc/src/rpcMain.c index 3e83293a2f..8dbbb97a1a 100755 --- a/src/rpc/src/rpcMain.c +++ b/src/rpc/src/rpcMain.c @@ -840,7 +840,7 @@ static void rpcProcessBrokenLink(SRpcConn *pConn) { rpcMsg.handle = pConn; rpcMsg.msgType = pConn->inType; rpcMsg.code = TSDB_CODE_NETWORK_UNAVAIL; - (*(pRpc->cfp))(&rpcMsg); + // (*(pRpc->cfp))(&rpcMsg); } rpcCloseConn(pConn); @@ -1169,7 +1169,7 @@ static void rpcProcessIdleTimer(void *param, void *tmrId) { rpcMsg.handle = pConn; rpcMsg.msgType = pConn->inType; rpcMsg.code = TSDB_CODE_NETWORK_UNAVAIL; - (*(pRpc->cfp))(&rpcMsg); + // (*(pRpc->cfp))(&rpcMsg); } rpcCloseConn(pConn); } else { diff --git a/src/util/inc/tbuffer.h b/src/util/inc/tbuffer.h index 9dc6d97eb6..d52031fc6a 100644 --- a/src/util/inc/tbuffer.h +++ b/src/util/inc/tbuffer.h @@ -13,14 +13,15 @@ * along with this program. If not, see . */ -#include -#include -#include -#include - #ifndef TDENGINE_TBUFFER_H #define TDENGINE_TBUFFER_H +#include "setjmp.h" +#include "os.h" + +#ifdef __cplusplus +extern "C" { +#endif /* SBuffer can be used to read or write a buffer, but cannot be used for both @@ -80,37 +81,33 @@ int main(int argc, char** argv) { */ typedef struct { jmp_buf jb; - char* data; - size_t pos; - size_t size; + char* data; + size_t pos; + size_t size; } SBuffer; - // common functions can be used in both read & write #define tbufThrowError(buf, code) longjmp((buf)->jb, (code)) size_t tbufTell(SBuffer* buf); size_t tbufSeekTo(SBuffer* buf, size_t pos); size_t tbufSkip(SBuffer* buf, size_t size); -void tbufClose(SBuffer* buf, bool keepData); - +void tbufClose(SBuffer* buf, bool keepData); // basic read functions -#define tbufBeginRead(buf, data, len) (((buf)->data = (char*)data), ((buf)->pos = 0), ((buf)->size = ((data) == NULL) ? 0 : (len)), setjmp((buf)->jb)) -char* tbufRead(SBuffer* buf, size_t size); -void tbufReadToBuffer(SBuffer* buf, void* dst, size_t size); +#define tbufBeginRead(buf, _data, len) ((buf)->data = (char*)(_data), ((buf)->pos = 0), ((buf)->size = ((_data) == NULL) ? 0 : (len)), setjmp((buf)->jb)) +char* tbufRead(SBuffer* buf, size_t size); +void tbufReadToBuffer(SBuffer* buf, void* dst, size_t size); const char* tbufReadString(SBuffer* buf, size_t* len); -size_t tbufReadToString(SBuffer* buf, char* dst, size_t size); - +size_t tbufReadToString(SBuffer* buf, char* dst, size_t size); // basic write functions #define tbufBeginWrite(buf) ((buf)->data = NULL, ((buf)->pos = 0), ((buf)->size = 0), setjmp((buf)->jb)) -void tbufEnsureCapacity(SBuffer* buf, size_t size); +void tbufEnsureCapacity(SBuffer* buf, size_t size); char* tbufGetData(SBuffer* buf, bool takeOver); -void tbufWrite(SBuffer* buf, const void* data, size_t size); -void tbufWriteAt(SBuffer* buf, size_t pos, const void* data, size_t size); -void tbufWriteStringLen(SBuffer* buf, const char* str, size_t len); -void tbufWriteString(SBuffer* buf, const char* str); - +void tbufWrite(SBuffer* buf, const void* data, size_t size); +void tbufWriteAt(SBuffer* buf, size_t pos, const void* data, size_t size); +void tbufWriteStringLen(SBuffer* buf, const char* str, size_t len); +void tbufWriteString(SBuffer* buf, const char* str); // read & write function for primitive types #ifndef TBUFFER_DEFINE_FUNCTION @@ -120,17 +117,21 @@ void tbufWriteString(SBuffer* buf, const char* str); void tbufWrite##name##At(SBuffer* buf, size_t pos, type data); #endif -TBUFFER_DEFINE_FUNCTION( bool, Bool ) -TBUFFER_DEFINE_FUNCTION( char, Char ) -TBUFFER_DEFINE_FUNCTION( int8_t, Int8 ) -TBUFFER_DEFINE_FUNCTION( uint8_t, Unt8 ) -TBUFFER_DEFINE_FUNCTION( int16_t, Int16 ) -TBUFFER_DEFINE_FUNCTION( uint16_t, Uint16 ) -TBUFFER_DEFINE_FUNCTION( int32_t, Int32 ) -TBUFFER_DEFINE_FUNCTION( uint32_t, Uint32 ) -TBUFFER_DEFINE_FUNCTION( int64_t, Int64 ) -TBUFFER_DEFINE_FUNCTION( uint64_t, Uint64 ) -TBUFFER_DEFINE_FUNCTION( float, Float ) -TBUFFER_DEFINE_FUNCTION( double, Double ) +TBUFFER_DEFINE_FUNCTION(bool, Bool) +TBUFFER_DEFINE_FUNCTION(char, Char) +TBUFFER_DEFINE_FUNCTION(int8_t, Int8) +TBUFFER_DEFINE_FUNCTION(uint8_t, Unt8) +TBUFFER_DEFINE_FUNCTION(int16_t, Int16) +TBUFFER_DEFINE_FUNCTION(uint16_t, Uint16) +TBUFFER_DEFINE_FUNCTION(int32_t, Int32) +TBUFFER_DEFINE_FUNCTION(uint32_t, Uint32) +TBUFFER_DEFINE_FUNCTION(int64_t, Int64) +TBUFFER_DEFINE_FUNCTION(uint64_t, Uint64) +TBUFFER_DEFINE_FUNCTION(float, Float) +TBUFFER_DEFINE_FUNCTION(double, Double) + +#ifdef __cplusplus +} +#endif #endif \ No newline at end of file diff --git a/src/util/src/ihash.c b/src/util/src/ihash.c index 6b58d8ef31..e1c7cb0e58 100644 --- a/src/util/src/ihash.c +++ b/src/util/src/ihash.c @@ -221,10 +221,9 @@ void taosCleanUpIntHashWithFp(void *handle, void (*fp)(char *)) { void taosVisitIntHashWithFp(void *handle, int (*fp)(char *, void *), void *param) { IHashObj * pObj; IHashNode *pNode, *pNext; - char * pData = NULL; pObj = (IHashObj *)handle; - if (pObj == NULL || pObj->maxSessions <= 0) return NULL; + if (pObj == NULL || pObj->maxSessions <= 0) return; pthread_mutex_lock(&pObj->mutex); @@ -245,11 +244,10 @@ void taosVisitIntHashWithFp(void *handle, int (*fp)(char *, void *), void *param int32_t taosGetIntHashSize(void *handle) { IHashObj * pObj; IHashNode *pNode, *pNext; - char * pData = NULL; int32_t num = 0; pObj = (IHashObj *)handle; - if (pObj == NULL || pObj->maxSessions <= 0) return NULL; + if (pObj == NULL || pObj->maxSessions <= 0) return 0; pthread_mutex_lock(&pObj->mutex); diff --git a/src/util/src/tbuffer.c b/src/util/src/tbuffer.c index ac7d22078d..a83d7dddb0 100644 --- a/src/util/src/tbuffer.c +++ b/src/util/src/tbuffer.c @@ -30,7 +30,7 @@ tbufWriteAt(buf, pos, &data, sizeof(data));\ } -#include "../inc/tbuffer.h" +#include "tbuffer.h" //////////////////////////////////////////////////////////////////////////////// @@ -119,13 +119,14 @@ void tbufEnsureCapacity(SBuffer* buf, size_t size) { } char* tbufGetData(SBuffer* buf, bool takeOver) { - char* ret = buf->data; - if (takeOver) { - buf->pos = 0; - buf->size = 0; - buf->data = NULL; - } - return ret; + char* ret = buf->data; + if (takeOver) { + buf->pos = 0; + buf->size = 0; + buf->data = NULL; + } + + return ret; } void tbufEndWrite(SBuffer* buf) { diff --git a/src/vnode/tsdb/src/tsdbFile.c b/src/vnode/tsdb/src/tsdbFile.c index ff8da1cdad..bd6699eb84 100644 --- a/src/vnode/tsdb/src/tsdbFile.c +++ b/src/vnode/tsdb/src/tsdbFile.c @@ -147,6 +147,11 @@ void tsdbInitFileGroupIter(STsdbFileH *pFileH, SFileGroupIter *pIter, int direct } void tsdbSeekFileGroupIter(SFileGroupIter *pIter, int fid) { + if (pIter->numOfFGroups == 0) { + assert(pIter->pFileGroup == NULL); + return; + } + int flags = (pIter->direction == TSDB_FGROUP_ITER_FORWARD) ? TD_GE : TD_LE; void *ptr = taosbsearch(&fid, pIter->base, sizeof(SFileGroup), pIter->numOfFGroups, compFGroupKey, flags); if (ptr == NULL) { diff --git a/src/vnode/tsdb/src/tsdbRead.c b/src/vnode/tsdb/src/tsdbRead.c index 5635d9a98f..a625770160 100644 --- a/src/vnode/tsdb/src/tsdbRead.c +++ b/src/vnode/tsdb/src/tsdbRead.c @@ -424,6 +424,29 @@ static SDataBlockInfo getTrueDataBlockInfo(STsdbQueryHandle* pHandle, STableChec SArray *getDefaultLoadColumns(STsdbQueryHandle *pQueryHandle, bool loadTS); static void filterDataInDataBlock(STsdbQueryHandle *pQueryHandle, SDataCols* pCols, SArray *sa); +static bool doLoadDataFromFileBlock(STsdbQueryHandle *pQueryHandle) { + SQueryFilePos *cur = &pQueryHandle->cur; + + STableCheckInfo* pCheckInfo = taosArrayGet(pQueryHandle->pTableCheckInfo, pQueryHandle->activeIndex); + SCompBlock* pBlock = &pCheckInfo->pCompInfo->blocks[cur->slot]; + + SCompData* data = calloc(1, sizeof(SCompData)+ sizeof(SCompCol)*pBlock->numOfCols); + + data->numOfCols = pBlock->numOfCols; + data->uid = pCheckInfo->pTableObj->tableId.uid; + + pCheckInfo->pDataCols = tdNewDataCols(1000, 2, 4096); + tdInitDataCols(pCheckInfo->pDataCols, pCheckInfo->pTableObj->schema); + + SFile* pFile = &pCheckInfo->pFileGroup->files[TSDB_FILE_TYPE_DATA]; + if (pFile->fd == FD_INITIALIZER) { + pFile->fd = open(pFile->fname, O_RDONLY); + } + + tsdbLoadDataBlock(pFile, pBlock, 1, pCheckInfo->pDataCols, data); + return true; +} + static bool loadQualifiedDataFromFileBlock(STsdbQueryHandle *pQueryHandle) { SQueryFilePos *cur = &pQueryHandle->cur; @@ -432,31 +455,18 @@ static bool loadQualifiedDataFromFileBlock(STsdbQueryHandle *pQueryHandle) { SArray *sa = getDefaultLoadColumns(pQueryHandle, true); if (QUERY_IS_ASC_QUERY(pQueryHandle->order)) { + + // query ended in current block if (pQueryHandle->window.ekey < pBlock->keyLast) { - SCompData* data = calloc(1, sizeof(SCompData)+ sizeof(SCompCol)*pBlock->numOfCols); - - data->numOfCols = pBlock->numOfCols; - data->uid = pCheckInfo->pTableObj->tableId.uid; - - pCheckInfo->pDataCols = tdNewDataCols(1000, 2, 4096); - tdInitDataCols(pCheckInfo->pDataCols, pCheckInfo->pTableObj->schema); - - SFile* pFile = &pCheckInfo->pFileGroup->files[TSDB_FILE_TYPE_DATA]; - if (pFile->fd == FD_INITIALIZER) { - pFile->fd = open(pFile->fname, O_RDONLY); - } - - if (tsdbLoadDataBlock(pFile, pBlock, 1, pCheckInfo->pDataCols, data) == 0) { - //do something - } + doLoadDataFromFileBlock(pQueryHandle); + filterDataInDataBlock(pQueryHandle, pCheckInfo->pDataCols, sa); } - } else { + } else {// todo desc query if (pQueryHandle->window.ekey > pBlock->keyFirst) { -// loadDataBlockIntoMem_(pQueryHandle, pBlock, &pQueryHandle->pFields[cur->slot], cur->fileId, sa); +// } } - filterDataInDataBlock(pQueryHandle, pCheckInfo->pDataCols, sa); return pQueryHandle->realNumOfRows > 0; } @@ -475,7 +485,7 @@ bool moveToNextBlock(STsdbQueryHandle *pQueryHandle, int32_t step) { (pQueryHandle->cur.slot == pCheckInfo->compIndex[tid].numOfSuperBlocks - 1)) || (step == QUERY_DESC_FORWARD_STEP && (pQueryHandle->cur.slot == 0))) { // temporarily keep the position value, in case of no data qualified when move forwards(backwards) - SQueryFilePos save = pQueryHandle->cur; +// SQueryFilePos save = pQueryHandle->cur; SFileGroup* fgroup = tsdbGetFileGroupNext(&pCheckInfo->fileIter); int32_t fid = -1; @@ -508,13 +518,15 @@ bool moveToNextBlock(STsdbQueryHandle *pQueryHandle, int32_t step) { // next block in the same file cur->slot += step; - SCompBlock* pBlock = &pQueryHandle->pBlock[cur->slot]; + SCompBlock* pBlock = &pCheckInfo->pCompInfo->blocks[cur->slot]; cur->pos = (step == QUERY_ASC_FORWARD_STEP) ? 0 : pBlock->numOfPoints - 1; return loadQualifiedDataFromFileBlock(pQueryHandle); } } else { // data in cache return hasMoreDataInCacheForSingleModel(pQueryHandle); } + + return false; } int vnodeBinarySearchKey(char *pValue, int num, TSKEY key, int order) { @@ -736,12 +748,21 @@ static bool getQualifiedDataBlock(STsdbQueryHandle *pQueryHandle, STableCheckInf int32_t index = -1; int32_t tid = pCheckInfo->tableId.tid; - SFile* pFile = &pCheckInfo->pFileGroup->files[TSDB_FILE_TYPE_DATA]; - while (1) { + while (pCheckInfo->pFileGroup != NULL) { if ((fid = getFileCompInfo(pCheckInfo, pCheckInfo->pFileGroup)) < 0) { break; } + + // no data block in current file, try next + if (pCheckInfo->compIndex[tid].numOfSuperBlocks == 0) { + dTrace("QInfo:%p no data block in file, fid:%d, tid:%d, try next", pQueryHandle->qinfo, + pCheckInfo->pFileGroup->fileId, tid); + + pCheckInfo->pFileGroup = tsdbGetFileGroupNext(&pCheckInfo->fileIter); + + continue; + } index = binarySearchForBlockImpl(pCheckInfo->pCompInfo->blocks, pCheckInfo->compIndex[tid].numOfSuperBlocks, pQueryHandle->order, key); @@ -769,12 +790,11 @@ static bool getQualifiedDataBlock(STsdbQueryHandle *pQueryHandle, STableCheckInf // load first data block into memory failed, caused by disk block error bool blockLoaded = false; - SArray *sa = NULL; + SArray *sa = getDefaultLoadColumns(pQueryHandle, true); // todo no need to loaded at all cur->slot = index; - sa = getDefaultLoadColumns(pQueryHandle, true); SCompBlock* pBlock = &pCheckInfo->pCompInfo->blocks[cur->slot]; SCompData* data = calloc(1, sizeof(SCompData)+ sizeof(SCompCol)*pBlock->numOfCols); @@ -784,6 +804,7 @@ static bool getQualifiedDataBlock(STsdbQueryHandle *pQueryHandle, STableCheckInf pCheckInfo->pDataCols = tdNewDataCols(1000, 2, 4096); tdInitDataCols(pCheckInfo->pDataCols, pCheckInfo->pTableObj->schema); + SFile* pFile = &pCheckInfo->pFileGroup->files[TSDB_FILE_TYPE_DATA]; if (pFile->fd == FD_INITIALIZER) { pFile->fd = open(pFile->fname, O_RDONLY); } @@ -816,7 +837,7 @@ static bool hasMoreDataInFileForSingleTableModel(STsdbQueryHandle* pHandle) { assert(pHandle->activeIndex == 0 && taosArrayGetSize(pHandle->pTableCheckInfo) == 1); STsdbFileH* pFileHandle = tsdbGetFile(pHandle->pTsdb); - SQueryFilePos* cur = &pHandle->cur; +// SQueryFilePos* cur = &pHandle->cur; STableCheckInfo* pCheckInfo = taosArrayGet(pHandle->pTableCheckInfo, pHandle->activeIndex); @@ -973,11 +994,16 @@ SArray *tsdbRetrieveDataBlock(tsdb_query_handle_t *pQueryHandle, SArray *pIdList STableCheckInfo* pCheckInfo = taosArrayGet(pHandle->pTableCheckInfo, pHandle->activeIndex); SDataBlockInfo binfo = getTrueDataBlockInfo(pHandle, pCheckInfo); - if (pHandle->realNumOfRows <= binfo.size) { + assert(pHandle->realNumOfRows <= binfo.size); + + if (pHandle->realNumOfRows < binfo.size) { return pHandle->pColumns; } else { - // todo do load data block - assert(0); + SArray *sa = getDefaultLoadColumns(pHandle, true); + + doLoadDataFromFileBlock(pHandle); + filterDataInDataBlock(pHandle, pCheckInfo->pDataCols, sa); + return pHandle->pColumns; } } } @@ -1197,7 +1223,7 @@ static void getTagColumnInfo(SSyntaxTreeFilterSupporter* pSupporter, SSchema* pS } void filterPrepare(void* expr, void* param) { - tSQLSyntaxNode *pExpr = (tSQLSyntaxNode*) expr; + tExprNode *pExpr = (tExprNode*) expr; if (pExpr->_node.info != NULL) { return; } @@ -1276,7 +1302,7 @@ bool tSkipListNodeFilterCallback(const void* pNode, void* param) { static int32_t doQueryTableList(STable* pSTable, SArray* pRes, const char* pCond) { STColumn* stcol = schemaColAt(pSTable->tagSchema, 0); - tSQLSyntaxNode* pExpr = NULL; + tExprNode* pExpr = NULL; tSQLBinaryExprFromString(&pExpr, stcol, schemaNCols(pSTable->tagSchema), pCond, strlen(pCond)); // failed to build expression, no result, return immediately @@ -1297,27 +1323,26 @@ static int32_t doQueryTableList(STable* pSTable, SArray* pRes, const char* pCond }; tSQLBinaryExprTraverse(pExpr, pSTable->pIndex, pRes, &supp); - tSQLBinaryExprDestroy(&pExpr, tSQLListTraverseDestroyInfo); + tExprTreeDestroy(&pExpr, tSQLListTraverseDestroyInfo); tansformQueryResult(pRes); return TSDB_CODE_SUCCESS; } -// SArray *tsdbQueryTableList(struct STsdbRepo* tsdb, int64_t uid, const wchar_t *pTagCond, size_t len) { SArray *tsdbQueryTableList(tsdb_repo_t* tsdb, int64_t uid, const wchar_t *pTagCond, size_t len) { // no condition, all tables created according to the stable will involved in querying + SArray* result = taosArrayInit(8, POINTER_BYTES); + if (pTagCond == NULL || wcslen(pTagCond) == 0) { return createTableIdArrayList(tsdb, uid); } else { char* str = convertTagQueryStr(pTagCond, len); - SArray* result = taosArrayInit(8, POINTER_BYTES); STable* pSTable = tsdbGetTableByUid(tsdbGetMeta(tsdb), uid); assert(pSTable != NULL); - if (doQueryTableList(pSTable, result, str) == TSDB_CODE_SUCCESS) { - return result; - } + doQueryTableList(pSTable, result, str); + return result; } } diff --git a/tests/script/basicSuite.sim b/tests/script/basicSuite.sim index e735099181..d16e85323b 100644 --- a/tests/script/basicSuite.sim +++ b/tests/script/basicSuite.sim @@ -1,4 +1,17 @@ ################################# -run general/user/testSuite.sim -run general/table/testSuite.sim + +run general/user/basic1.sim + +run general/show/dnodes.sim + +run general/db/basic1.sim +run general/db/basic2.sim +run general/db/basic3.sim +run general/db/basic4.sim +run general/db/basic5.sim + +run general/table/basic1.sim +run general/table/basic2.sim +run general/table/basic3.sim + ################################## diff --git a/tests/script/general/db/basic1.sim b/tests/script/general/db/basic1.sim new file mode 100644 index 0000000000..094c1a6930 --- /dev/null +++ b/tests/script/general/db/basic1.sim @@ -0,0 +1,59 @@ +system sh/stop_dnodes.sh +system sh/deploy.sh -n dnode1 -m 192.168.0.1 -i 192.168.0.1 +system sh/exec.sh -n dnode1 -s start +sql connect + +print =============== create database +sql create database d1 +sql show databases +if $rows != 1 then + return -1 +endi + +if $data00 != d1 then + return -1 +endi + +if $data02 != 0 then + return -1 +endi + +if $data03 != 0 then + return -1 +endi + +print =============== drop database +sql drop database d1 +sql show databases +if $rows != 0 then + return -1 +endi + +print =============== more databases +sql create database d2 +sql create database d3 +sql create database d4 +sql show databases +if $rows != 3 then + return -1 +endi + +print =============== drop database +sql drop database d2 +sql drop database d3 +sql show databases +if $rows != 1 then + return -1 +endi + +if $data00 != d4 then + return -1 +endi + +if $data02 != 0 then + return -1 +endi + +if $data03 != 0 then + return -1 +endi \ No newline at end of file diff --git a/tests/script/general/db/basic2.sim b/tests/script/general/db/basic2.sim new file mode 100644 index 0000000000..a1e4533707 --- /dev/null +++ b/tests/script/general/db/basic2.sim @@ -0,0 +1,51 @@ +system sh/stop_dnodes.sh +system sh/deploy.sh -n dnode1 -m 192.168.0.1 -i 192.168.0.1 +system sh/exec.sh -n dnode1 -s start +sql connect + +print =============== create database d1 +sql create database d1 +sql use d1 +sql create table t1 (ts timestamp, i int); +sql create table t2 (ts timestamp, i int); +sql create table t3 (ts timestamp, i int); +sql create table t4 (ts timestamp, i int); + +sql show databases +if $rows != 1 then + return -1 +endi + +if $data00 != d1 then + return -1 +endi + +if $data02 != 4 then + return -1 +endi + +if $data03 != 1 then + return -1 +endi + +sql show tables +if $rows != 4 then + return -1 +endi + +print =============== create database d2 +sql create database d2 +sql use d2 +sql create table t1 (ts timestamp, i int); +sql create table t2 (ts timestamp, i int); +sql create table t3 (ts timestamp, i int); + +sql show databases +if $rows != 2 then + return -1 +endi + +sql show tables +if $rows != 3 then + return -1 +endi diff --git a/tests/script/general/db/basic3.sim b/tests/script/general/db/basic3.sim new file mode 100644 index 0000000000..60ff4b74c7 --- /dev/null +++ b/tests/script/general/db/basic3.sim @@ -0,0 +1,49 @@ +system sh/stop_dnodes.sh +system sh/deploy.sh -n dnode1 -m 192.168.0.1 -i 192.168.0.1 +system sh/exec.sh -n dnode1 -s start +sql connect + +print =============== create database d1 +sql create database d1 +sql create table d1.t1 (ts timestamp, i int); +sql create table d1.t2 (ts timestamp, i int); +sql create table d1.t3 (ts timestamp, i int); +sql create table d1.t4 (ts timestamp, i int); + +sql show databases +if $rows != 1 then + return -1 +endi + +if $data00 != d1 then + return -1 +endi + +if $data02 != 4 then + return -1 +endi + +if $data03 != 1 then + return -1 +endi + +sql show d1.tables +if $rows != 4 then + return -1 +endi + +print =============== create database d2 +sql create database d2 +sql create table d2.t1 (ts timestamp, i int); +sql create table d2.t2 (ts timestamp, i int); +sql create table d2.t3 (ts timestamp, i int); + +sql show databases +if $rows != 2 then + return -1 +endi + +sql show d2.tables +if $rows != 3 then + return -1 +endi diff --git a/tests/script/general/db/basic4.sim b/tests/script/general/db/basic4.sim new file mode 100644 index 0000000000..f620112cfb --- /dev/null +++ b/tests/script/general/db/basic4.sim @@ -0,0 +1,118 @@ +system sh/stop_dnodes.sh +system sh/deploy.sh -n dnode1 -m 192.168.0.1 -i 192.168.0.1 +system sh/exec.sh -n dnode1 -s start +sql connect + +print =============== create database d1 +sql create database d1 +sql create table d1.t1 (ts timestamp, i int); +sql create table d1.t2 (ts timestamp, i int); +sql create table d1.t3 (ts timestamp, i int); +sql create table d1.t4 (ts timestamp, i int); + +sql show databases +if $rows != 1 then + return -1 +endi + +if $data00 != d1 then + return -1 +endi + +if $data02 != 4 then + return -1 +endi + +if $data03 != 1 then + return -1 +endi + +sql show d1.tables +if $rows != 4 then + return -1 +endi + +sql show d1.vgroups +if $rows != 1 then + return -1 +endi +if $data00 != 1 then + return -1 +endi +if $data01 != 4 then + return -1 +endi +if $data02 != ready then + return -1 +endi + +print =============== drop table +sql drop table d1.t1 + +sql show databases +if $rows != 1 then + return -1 +endi + +if $data00 != d1 then + return -1 +endi + +if $data02 != 3 then + return -1 +endi + +if $data03 != 1 then + return -1 +endi + +sql show d1.tables +if $rows != 3 then + return -1 +endi + +sql show d1.vgroups +if $rows != 1 then + return -1 +endi +if $data00 != 1 then + return -1 +endi +if $data01 != 3 then + return -1 +endi +if $data02 != ready then + return -1 +endi + +print =============== drop all table +sql drop table d1.t2 +sql drop table d1.t3 +sql drop table d1.t4 + +sql show databases +if $rows != 1 then + return -1 +endi + +if $data00 != d1 then + return -1 +endi + +if $data02 != 0 then + return -1 +endi + +if $data03 != 0 then + return -1 +endi + +sql show d1.tables +if $rows != 0 then + return -1 +endi + +sql show d1.vgroups +if $rows != 0 then + return -1 +endi diff --git a/tests/script/general/db/basic5.sim b/tests/script/general/db/basic5.sim new file mode 100644 index 0000000000..ec619389bd --- /dev/null +++ b/tests/script/general/db/basic5.sim @@ -0,0 +1,57 @@ +system sh/stop_dnodes.sh +system sh/deploy.sh -n dnode1 -m 192.168.0.1 -i 192.168.0.1 +system sh/exec.sh -n dnode1 -s start +sql connect + +print =============== create database d1 +sql create database d1 +sql create table d1.t1 (ts timestamp, i int); +sql create table d1.t2 (ts timestamp, i int); +sql create table d1.t3 (ts timestamp, i int); +sql create table d1.t4 (ts timestamp, i int); + +sql show databases +if $rows != 1 then + return -1 +endi + +if $data00 != d1 then + return -1 +endi + +if $data02 != 4 then + return -1 +endi + +if $data03 != 1 then + return -1 +endi + +sql show d1.tables +if $rows != 4 then + return -1 +endi + +sql show d1.vgroups +if $rows != 1 then + return -1 +endi +if $data00 != 1 then + return -1 +endi +if $data01 != 4 then + return -1 +endi +if $data02 != ready then + return -1 +endi + +print =============== drop table +sql drop database d1 + +sql show databases +if $rows != 0 then + return -1 +endi + +sql_error show d1.vgroups diff --git a/tests/script/general/table/basic1.sim b/tests/script/general/table/basic1.sim new file mode 100644 index 0000000000..00e11483da --- /dev/null +++ b/tests/script/general/table/basic1.sim @@ -0,0 +1,71 @@ +system sh/stop_dnodes.sh +system sh/deploy.sh -n dnode1 -m 192.168.0.1 -i 192.168.0.1 +system sh/exec.sh -n dnode1 -s start +sql connect + +print =============== create database +sql create database d1 +sql show databases +if $rows != 1 then + return -1 +endi + +print $data00 $data01 $data02 + +print =============== create normal table +sql create table d1.n1 (ts timestamp, i int) +sql show d1.tables +if $rows != 1 then + return -1 +endi + +print $data00 $data01 $data02 + +print =============== create super table +sql create table d1.st (ts timestamp, i int) tags (j int) +sql show d1.stables +if $rows != 1 then + return -1 +endi + +print $data00 $data01 $data02 + +print =============== create child table +sql create table d1.c1 using d1.st tags(1) +sql create table d1.c2 using d1.st tags(2) +sql show d1.tables +if $rows != 3 then + return -1 +endi + +print $data00 $data01 $data02 +print $data10 $data11 $data22 +print $data20 $data11 $data22 + +print =============== insert data +sql insert into d1.n1 values(now, 1) +sql insert into d1.n1 values(now, 2) +sql insert into d1.n1 values(now, 3) + +print =============== query data +sql select * from d1.n1 +if $rows != 3 then + return -1 +endi + +print $data00 $data01 +print $data10 $data11 +print $data20 $data11 + +if $data01 != 1 then + return -1 +endi + +if $data11 != 2 then + return -1 +endi + +if $data21 != 3 then + return -1 +endi + diff --git a/tests/script/general/table/basic2.sim b/tests/script/general/table/basic2.sim new file mode 100644 index 0000000000..7701ca1c1f --- /dev/null +++ b/tests/script/general/table/basic2.sim @@ -0,0 +1,66 @@ +system sh/stop_dnodes.sh +system sh/deploy.sh -n dnode1 -m 192.168.0.1 -i 192.168.0.1 +system sh/exec.sh -n dnode1 -s start +sql connect + +print =============== one table +sql create database d1 +sql create table d1.n1 (ts timestamp, i int) +sql create table d1.n2 (ts timestamp, i int) +sql create table d1.n3 (ts timestamp, i int) +sql create table d1.n4 (ts timestamp, i int) + +sql drop table d1.n1 +sql drop table d1.n2 + +sql show d1.tables +if $rows != 2 then + return -1 +endi + +print =============== show +sql show databases +if $data02 != 2 then + return -1 +endi + +if $data03 != 1 then + return -1 +endi + +sql show d1.vgroups +if $data00 != 1 then + return -1 +endi + +if $data01 != 2 then + return -1 +endi + +print =============== insert data1 +sql_error insert into d1.n1 values(now, 1) +sql_error insert into d1.n2 values(now, 1) + +print =============== insert data2 +sql insert into d1.n3 values(now, 1) +sql insert into d1.n3 values(now, 2) +sql insert into d1.n3 values(now, 3) + +print =============== query data +sql select * from d1.n3 +if $rows != 3 then + return -1 +endi + +if $data01 != 1 then + return -1 +endi + +if $data11 != 2 then + return -1 +endi + +if $data21 != 3 then + return -1 +endi + diff --git a/tests/script/general/table/basic.sim b/tests/script/general/table/basic3.sim similarity index 100% rename from tests/script/general/table/basic.sim rename to tests/script/general/table/basic3.sim diff --git a/tests/script/general/table/testSuite.sim b/tests/script/general/table/testSuite.sim deleted file mode 100644 index 32677ab1ac..0000000000 --- a/tests/script/general/table/testSuite.sim +++ /dev/null @@ -1,3 +0,0 @@ -################################# -run general/table/basic.sim -################################## diff --git a/tests/script/general/user/basic.sim b/tests/script/general/user/basic1.sim similarity index 100% rename from tests/script/general/user/basic.sim rename to tests/script/general/user/basic1.sim diff --git a/tests/script/general/user/testSuite.sim b/tests/script/general/user/testSuite.sim deleted file mode 100644 index 99414f1d29..0000000000 --- a/tests/script/general/user/testSuite.sim +++ /dev/null @@ -1,3 +0,0 @@ -################################# -#run general/user/basic.sim -################################## diff --git a/tests/script/jenkins/basic1.txt b/tests/script/jenkins/basic1.txt new file mode 100644 index 0000000000..ef6d4e239b --- /dev/null +++ b/tests/script/jenkins/basic1.txt @@ -0,0 +1,11 @@ +./test.sh -f general/user/basic1.sim + +./test.sh -f general/db/basic1.sim +./test.sh -f general/db/basic2.sim +./test.sh -f general/db/basic3.sim +./test.sh -f general/db/basic4.sim +./test.sh -f general/db/basic5.sim + +./test.sh -f general/table/basic1.sim +./test.sh -f general/table/basic2.sim +./test.sh -f general/table/basic3.sim \ No newline at end of file diff --git a/tests/script/sh/deploy.sh b/tests/script/sh/deploy.sh index d990adaf5f..0192b18979 100755 --- a/tests/script/sh/deploy.sh +++ b/tests/script/sh/deploy.sh @@ -92,7 +92,7 @@ echo "internalIp $NODE_IP" >> $TAOS_CFG echo "privateIp $NODE_IP" >> $TAOS_CFG echo "dDebugFlag 135" >> $TAOS_CFG echo "mDebugFlag 199" >> $TAOS_CFG -echo "sdbDebugFlag 135" >> $TAOS_CFG +echo "sdbDebugFlag 199" >> $TAOS_CFG echo "rpcDebugFlag 135" >> $TAOS_CFG echo "tmrDebugFlag 131" >> $TAOS_CFG echo "cDebugFlag 135" >> $TAOS_CFG diff --git a/tests/script/tjenkins b/tests/script/tjenkins new file mode 100755 index 0000000000..b05ab3c900 Binary files /dev/null and b/tests/script/tjenkins differ