From 7620be6e28e3a86fa6a19f6da12e0de0b1e76355 Mon Sep 17 00:00:00 2001 From: 54liuyao <54liuyao> Date: Thu, 13 Jun 2024 16:23:50 +0800 Subject: [PATCH] optimize show cluster alive stmt --- include/common/taosdef.h | 4 - include/libs/nodes/querynodes.h | 1 + source/libs/command/src/command.c | 124 ------------ source/libs/nodes/src/nodesUtilFuncs.c | 12 ++ source/libs/parser/src/parAstParser.c | 13 ++ source/libs/parser/src/parTranslater.c | 252 +++++++++++++++++++++++-- tests/script/tsim/show/showalive.sim | 167 ++++++++++++++++ 7 files changed, 426 insertions(+), 147 deletions(-) create mode 100644 tests/script/tsim/show/showalive.sim diff --git a/include/common/taosdef.h b/include/common/taosdef.h index 9e92e2f569..c6e03dc1d8 100644 --- a/include/common/taosdef.h +++ b/include/common/taosdef.h @@ -30,10 +30,6 @@ typedef int64_t tb_uid_t; #define IS_TSWINDOW_SPECIFIED(win) (((win).skey != INT64_MIN) || ((win).ekey != INT64_MAX)) #define TSWINDOW_IS_EQUAL(t1, t2) (((t1).skey == (t2).skey) && ((t1).ekey == (t2).ekey)) -//define show cluster alive and show db.alive -#define SHOW_STATUS_NOT_AVAILABLE 0 -#define SHOW_STATUS_AVAILABLE 1 -#define SHOW_STATUS_HALF_AVAILABLE 2 typedef enum { TSDB_SUPER_TABLE = 1, // super table diff --git a/include/libs/nodes/querynodes.h b/include/libs/nodes/querynodes.h index befd6afce9..457937835d 100644 --- a/include/libs/nodes/querynodes.h +++ b/include/libs/nodes/querynodes.h @@ -628,6 +628,7 @@ char* nodesGetStrValueFromNode(SValueNode* pNode); void nodesValueNodeToVariant(const SValueNode* pNode, SVariant* pVal); SValueNode* nodesMakeValueNodeFromString(char* literal); SValueNode* nodesMakeValueNodeFromBool(bool b); +SNode* nodesMakeValueNodeFromInt32(int32_t value); char* nodesGetFillModeString(EFillMode mode); int32_t nodesMergeConds(SNode** pDst, SNodeList** pSrc); diff --git a/source/libs/command/src/command.c b/source/libs/command/src/command.c index d19b4c6913..9ab1348b9a 100644 --- a/source/libs/command/src/command.c +++ b/source/libs/command/src/command.c @@ -234,23 +234,6 @@ static int32_t buildCreateDBResultDataBlock(SSDataBlock** pOutput) { return code; } -static int32_t buildAliveResultDataBlock(SSDataBlock** pOutput) { - SSDataBlock* pBlock = createDataBlock(); - if (NULL == pBlock) { - return TSDB_CODE_OUT_OF_MEMORY; - } - - SColumnInfoData infoData = createColumnInfoData(TSDB_DATA_TYPE_INT, sizeof(int32_t), 1); - int32_t code = blockDataAppendColInfo(pBlock, &infoData); - - if (TSDB_CODE_SUCCESS == code) { - *pOutput = pBlock; - } else { - blockDataDestroy(pBlock); - } - return code; -} - int64_t getValOfDiffPrecision(int8_t unit, int64_t val) { int64_t v = 0; switch (unit) { @@ -398,110 +381,6 @@ static void setCreateDBResultIntoDataBlock(SSDataBlock* pBlock, char* dbName, ch colDataSetVal(pCol2, 0, buf2, false); } -#define CHECK_LEADER(n) \ - (row[n] && (fields[n].type == TSDB_DATA_TYPE_VARCHAR && \ - strncasecmp(row[n], "leader", varDataLen((char*)row[n] - VARSTR_HEADER_SIZE)) == 0)) -// on this row, if have leader return true else return false -bool existLeaderRole(TAOS_ROW row, TAOS_FIELD* fields, int nFields) { - // vgroup_id | db_name | tables | v1_dnode | v1_status | v2_dnode | v2_status | v3_dnode | v3_status | v4_dnode | - // v4_status | cacheload | tsma | - if (nFields != 14) { - return false; - } - - // check have leader on cloumn v*_status on 4 6 8 10 - if (CHECK_LEADER(4) || CHECK_LEADER(6) || CHECK_LEADER(8) || CHECK_LEADER(10)) { - return true; - } - - return false; -} - -// get db alive status, return 1 is alive else return 0 -int32_t getAliveStatusFromApi(int64_t* pConnId, char* dbName, int32_t* pStatus) { - char sql[128 + TSDB_DB_NAME_LEN] = "select * from information_schema.ins_vgroups"; - int32_t code; - - // filter with db name - if (dbName && dbName[0] != 0) { - char str[64 + TSDB_DB_NAME_LEN] = ""; - // test db name exist - sprintf(str, "show create database %s ;", dbName); - TAOS_RES* dbRes = taos_query(pConnId, str); - code = taos_errno(dbRes); - if (code != TSDB_CODE_SUCCESS) { - taos_free_result(dbRes); - return code; - } - taos_free_result(dbRes); - - sprintf(str, " where db_name='%s' ;", dbName); - strcat(sql, str); - } - - TAOS_RES* res = taos_query(pConnId, sql); - code = taos_errno(res); - if (code != TSDB_CODE_SUCCESS) { - taos_free_result(res); - return code; - } - - TAOS_ROW row = NULL; - TAOS_FIELD* fields = taos_fetch_fields(res); - int32_t nFields = taos_num_fields(res); - int32_t nAvailble = 0; - int32_t nUnAvailble = 0; - - while ((row = taos_fetch_row(res)) != NULL) { - if (existLeaderRole(row, fields, nFields)) { - nAvailble++; - } else { - nUnAvailble++; - } - } - taos_free_result(res); - - int32_t status = 0; - if (nAvailble + nUnAvailble == 0 || nUnAvailble == 0) { - status = SHOW_STATUS_AVAILABLE; - } else if (nAvailble > 0 && nUnAvailble > 0) { - status = SHOW_STATUS_HALF_AVAILABLE; - } else { - status = SHOW_STATUS_NOT_AVAILABLE; - } - - if (pStatus) { - *pStatus = status; - } - return TSDB_CODE_SUCCESS; -} - -static int32_t setAliveResultIntoDataBlock(int64_t* pConnId, SSDataBlock* pBlock, char* dbName) { - blockDataEnsureCapacity(pBlock, 1); - pBlock->info.rows = 1; - - SColumnInfoData* pCol1 = taosArrayGet(pBlock->pDataBlock, 0); - int32_t status = 0; - int32_t code = getAliveStatusFromApi(pConnId, dbName, &status); - if (code == TSDB_CODE_SUCCESS) { - colDataSetVal(pCol1, 0, (const char*)&status, false); - } - return code; -} - -static int32_t execShowAliveStatus(int64_t* pConnId, SShowAliveStmt* pStmt, SRetrieveTableRsp** pRsp) { - SSDataBlock* pBlock = NULL; - int32_t code = buildAliveResultDataBlock(&pBlock); - if (TSDB_CODE_SUCCESS == code) { - code = setAliveResultIntoDataBlock(pConnId, pBlock, pStmt->dbName); - } - if (TSDB_CODE_SUCCESS == code) { - code = buildRetrieveTableRsp(pBlock, SHOW_ALIVE_RESULT_COLS, pRsp); - } - blockDataDestroy(pBlock); - return code; -} - static int32_t execShowCreateDatabase(SShowCreateDatabaseStmt* pStmt, SRetrieveTableRsp** pRsp) { SSDataBlock* pBlock = NULL; int32_t code = buildCreateDBResultDataBlock(&pBlock); @@ -1070,9 +949,6 @@ int32_t qExecCommand(int64_t* pConnId, bool sysInfoUser, SNode* pStmt, SRetrieve return execShowLocalVariables(pRsp); case QUERY_NODE_SELECT_STMT: return execSelectWithoutFrom((SSelectStmt*)pStmt, pRsp); - case QUERY_NODE_SHOW_DB_ALIVE_STMT: - case QUERY_NODE_SHOW_CLUSTER_ALIVE_STMT: - return execShowAliveStatus(pConnId, (SShowAliveStmt*)pStmt, pRsp); default: break; } diff --git a/source/libs/nodes/src/nodesUtilFuncs.c b/source/libs/nodes/src/nodesUtilFuncs.c index beedffc4f2..68ce33d596 100644 --- a/source/libs/nodes/src/nodesUtilFuncs.c +++ b/source/libs/nodes/src/nodesUtilFuncs.c @@ -2674,6 +2674,18 @@ SValueNode* nodesMakeValueNodeFromBool(bool b) { return pValNode; } +SNode* nodesMakeValueNodeFromInt32(int32_t value) { + SValueNode* pValNode = (SValueNode*)nodesMakeNode(QUERY_NODE_VALUE); + if (pValNode) { + pValNode->node.resType.type = TSDB_DATA_TYPE_INT; + pValNode->node.resType.bytes = tDataTypes[TSDB_DATA_TYPE_INT].bytes; + nodesSetValueNodeValue(pValNode, &value); + pValNode->translate = true; + pValNode->isNull = false; + } + return (SNode*)pValNode; +} + bool nodesIsStar(SNode* pNode) { return (QUERY_NODE_COLUMN == nodeType(pNode)) && ('\0' == ((SColumnNode*)pNode)->tableAlias[0]) && (0 == strcmp(((SColumnNode*)pNode)->colName, "*")); diff --git a/source/libs/parser/src/parAstParser.c b/source/libs/parser/src/parAstParser.c index 122118b71c..aa2fd287c5 100644 --- a/source/libs/parser/src/parAstParser.c +++ b/source/libs/parser/src/parAstParser.c @@ -821,6 +821,16 @@ static int32_t collectMetaKeyFromShowTSMASStmt(SCollectMetaKeyCxt* pCxt, SShowSt pCxt->pMetaCache); } +static int32_t collectMetaKeyFromShowAlive(SCollectMetaKeyCxt* pCxt, SShowAliveStmt* pStmt) { + int32_t code = reserveTableMetaInCache(pCxt->pParseCxt->acctId, TSDB_INFORMATION_SCHEMA_DB, TSDB_INS_TABLE_VGROUPS, + pCxt->pMetaCache); + if (TSDB_CODE_SUCCESS == code) { + // just to verify whether the database exists + code = reserveDbCfgInCache(pCxt->pParseCxt->acctId, pStmt->dbName, pCxt->pMetaCache); + } + return code; +} + static int32_t collectMetaKeyFromQuery(SCollectMetaKeyCxt* pCxt, SNode* pStmt) { pCxt->pStmt = pStmt; switch (nodeType(pStmt)) { @@ -960,6 +970,9 @@ static int32_t collectMetaKeyFromQuery(SCollectMetaKeyCxt* pCxt, SNode* pStmt) { break; case QUERY_NODE_SHOW_TSMAS_STMT: return collectMetaKeyFromShowTSMASStmt(pCxt, (SShowStmt*)pStmt); + case QUERY_NODE_SHOW_DB_ALIVE_STMT: + case QUERY_NODE_SHOW_CLUSTER_ALIVE_STMT: + return collectMetaKeyFromShowAlive(pCxt, (SShowAliveStmt*)pStmt); default: break; } diff --git a/source/libs/parser/src/parTranslater.c b/source/libs/parser/src/parTranslater.c index 1c4dbaa9e1..58a158bd97 100644 --- a/source/libs/parser/src/parTranslater.c +++ b/source/libs/parser/src/parTranslater.c @@ -33,6 +33,20 @@ #define SYSTABLE_SHOW_TYPE_OFFSET QUERY_NODE_SHOW_DNODES_STMT +#define CHECK_RES_OUT_OF_MEM(p) \ + do { \ + if (TSDB_CODE_SUCCESS != (p)) { \ + return TSDB_CODE_OUT_OF_MEMORY; \ + } \ + } while (0) + +#define CHECK_POINTER_OUT_OF_MEM(p) \ + do { \ + if (NULL == (p)) { \ + return TSDB_CODE_OUT_OF_MEMORY; \ + } \ + } while (0) + typedef struct SRewriteTbNameContext { int32_t errCode; char* pTbName; @@ -11545,20 +11559,6 @@ static int32_t extractShowCreateDatabaseResultSchema(int32_t* numOfCols, SSchema return TSDB_CODE_SUCCESS; } -static int32_t extractShowAliveResultSchema(int32_t* numOfCols, SSchema** pSchema) { - *numOfCols = 1; - *pSchema = taosMemoryCalloc((*numOfCols), sizeof(SSchema)); - if (NULL == (*pSchema)) { - return TSDB_CODE_OUT_OF_MEMORY; - } - - (*pSchema)[0].type = TSDB_DATA_TYPE_INT; - (*pSchema)[0].bytes = sizeof(int32_t); - strcpy((*pSchema)[0].name, "status"); - - return TSDB_CODE_SUCCESS; -} - static int32_t extractShowCreateTableResultSchema(int32_t* numOfCols, SSchema** pSchema) { *numOfCols = 2; *pSchema = taosMemoryCalloc((*numOfCols), sizeof(SSchema)); @@ -11656,9 +11656,6 @@ int32_t extractResultSchema(const SNode* pRoot, int32_t* numOfCols, SSchema** pS } case QUERY_NODE_SHOW_CREATE_DATABASE_STMT: return extractShowCreateDatabaseResultSchema(numOfCols, pSchema); - case QUERY_NODE_SHOW_DB_ALIVE_STMT: - case QUERY_NODE_SHOW_CLUSTER_ALIVE_STMT: - return extractShowAliveResultSchema(numOfCols, pSchema); case QUERY_NODE_SHOW_CREATE_TABLE_STMT: case QUERY_NODE_SHOW_CREATE_STABLE_STMT: return extractShowCreateTableResultSchema(numOfCols, pSchema); @@ -11785,6 +11782,24 @@ static int32_t createOperatorNode(EOperatorType opType, const char* pColName, SN return TSDB_CODE_SUCCESS; } +static int32_t createParOperatorNode(EOperatorType opType, const char* pLeftCol, const char* pRightCol, SNode** ppResOp) { + SOperatorNode* pOper = (SOperatorNode*)nodesMakeNode(QUERY_NODE_OPERATOR); + CHECK_POINTER_OUT_OF_MEM(pOper); + + pOper->opType = opType; + pOper->pLeft = nodesMakeNode(QUERY_NODE_COLUMN); + pOper->pRight = nodesMakeNode(QUERY_NODE_COLUMN); + if (NULL == pOper->pLeft || NULL == pOper->pRight) { + nodesDestroyNode((SNode*)pOper); + return TSDB_CODE_OUT_OF_MEMORY; + } + strcpy(((SColumnNode*)pOper->pLeft)->colName, pLeftCol); + strcpy(((SColumnNode*)pOper->pRight)->colName, pRightCol); + + *ppResOp = (SNode*)pOper; + return TSDB_CODE_SUCCESS; +} + static const char* getTbNameColName(ENodeType type) { const char* colName; switch (type) { @@ -13312,6 +13327,203 @@ static int32_t rewriteShowCompactDetailsStmt(STranslateContext* pCxt, SQuery* pQ return code; } +static int32_t createParWhenThenNode(SNode* pWhen, SNode* pThen, SNode** ppResWhenThen) { + SWhenThenNode* pWThen = (SWhenThenNode*)nodesMakeNode(QUERY_NODE_WHEN_THEN); + CHECK_POINTER_OUT_OF_MEM(pWThen); + + pWThen->pWhen = pWhen; + pWThen->pThen = pThen; + *ppResWhenThen = (SNode*)pWThen; + return TSDB_CODE_SUCCESS; +} + +static int32_t createParCaseWhenNode(SNode* pCase, SNodeList* pWhenThenList, SNode* pElse, const char* pAias, SNode** ppResCaseWhen) { + SCaseWhenNode* pCaseWhen = (SCaseWhenNode*)nodesMakeNode(QUERY_NODE_CASE_WHEN); + CHECK_POINTER_OUT_OF_MEM(pCaseWhen); + + pCaseWhen->pCase = pCase; + pCaseWhen->pWhenThenList = pWhenThenList; + pCaseWhen->pElse = pElse; + if (pAias) { + strcpy(pCaseWhen->node.aliasName, pAias); + strcpy(pCaseWhen->node.userAlias, pAias); + } + *ppResCaseWhen = (SNode*)pCaseWhen; + return TSDB_CODE_SUCCESS; +} + +static int32_t createParFunctionNode(const char* pFunName, const char* pAias, SNodeList* pParameterList, SNode** ppResFunc) { + SFunctionNode* pFunc = (SFunctionNode*)nodesMakeNode(QUERY_NODE_FUNCTION); + CHECK_POINTER_OUT_OF_MEM(pFunc); + strcpy(pFunc->functionName, pFunName); + strcpy(pFunc->node.aliasName, pAias); + strcpy(pFunc->node.userAlias, pAias); + pFunc->pParameterList = pParameterList; + *ppResFunc = (SNode*)pFunc; + return TSDB_CODE_SUCCESS; +} + +static int32_t createParListNode(SNode* pItem, SNodeList** ppResList) { + SNodeList* pList = nodesMakeList(); + CHECK_POINTER_OUT_OF_MEM(pList); + CHECK_RES_OUT_OF_MEM(nodesListStrictAppend(pList, pItem)); + *ppResList = pList; + return TSDB_CODE_SUCCESS; +} + +static int32_t createParTempTableNode(SSelectStmt* pSubquery, SNode** ppResTempTable) { + STempTableNode* pTempTable = (STempTableNode*)nodesMakeNode(QUERY_NODE_TEMP_TABLE); + CHECK_POINTER_OUT_OF_MEM(pTempTable); + pTempTable->pSubquery = (SNode*)pSubquery; + taosRandStr(pTempTable->table.tableAlias, 8); + strcpy(pSubquery->stmtName, pTempTable->table.tableAlias); + pSubquery->isSubquery = true; + *ppResTempTable = (SNode*)pTempTable; + return TSDB_CODE_SUCCESS; +} + +static int32_t rewriteShowAliveStmt(STranslateContext* pCxt, SQuery* pQuery) { + int32_t code = TSDB_CODE_SUCCESS; + char* pDbName = ((SShowAliveStmt*)pQuery->pRoot)->dbName; + if (pDbName && pDbName[0] != 0) { + SDbCfgInfo dbCfg = {0}; + code = getDBCfg(pCxt, pDbName, &dbCfg); + if (TSDB_CODE_SUCCESS != code) { + return code; + } + } + + SValueNode* pValNode = nodesMakeValueNodeFromString("leader"); + CHECK_POINTER_OUT_OF_MEM(pValNode); + + SNode* pCond1 = NULL; + SNode* pCond2 = NULL; + SNode* pCond3 = NULL; + SNode* pCond4 = NULL; + CHECK_RES_OUT_OF_MEM(createOperatorNode(OP_TYPE_EQUAL, "v1_status", (SNode*)pValNode, &pCond1)); + CHECK_RES_OUT_OF_MEM(createOperatorNode(OP_TYPE_EQUAL, "v2_status", (SNode*)pValNode, &pCond2)); + CHECK_RES_OUT_OF_MEM(createOperatorNode(OP_TYPE_EQUAL, "v3_status", (SNode*)pValNode, &pCond3)); + CHECK_RES_OUT_OF_MEM(createOperatorNode(OP_TYPE_EQUAL, "v4_status", (SNode*)pValNode, &pCond4)); + nodesDestroyNode((SNode*)pValNode); + + SNode* pTemp1 = NULL; + SNode* pTemp2 = NULL; + SNode* pFullCond = NULL; + CHECK_RES_OUT_OF_MEM(createLogicCondNode(pCond1, pCond2, &pTemp1, LOGIC_COND_TYPE_OR)); + CHECK_RES_OUT_OF_MEM(createLogicCondNode(pTemp1, pCond3, &pTemp2, LOGIC_COND_TYPE_OR)); + CHECK_RES_OUT_OF_MEM(createLogicCondNode(pTemp2, pCond4, &pFullCond, LOGIC_COND_TYPE_OR)); + + SNode* pThen = nodesMakeValueNodeFromInt32(1); + CHECK_POINTER_OUT_OF_MEM(pThen); + + SNode* pWhenThen = NULL; + CHECK_RES_OUT_OF_MEM(createParWhenThenNode(pFullCond, pThen, &pWhenThen)); + SNodeList* pWhenThenlist = NULL; + CHECK_RES_OUT_OF_MEM(createParListNode(pWhenThen, &pWhenThenlist)); + + SNode* pElse = nodesMakeValueNodeFromInt32(0); + CHECK_POINTER_OUT_OF_MEM(pElse); + + // case when (v1_status = "leader" or v2_status = "lead er" or v3_status = "leader" or v4_status = "leader") then 1 else 0 end + SNode* pCaseWhen = NULL; + CHECK_RES_OUT_OF_MEM(createParCaseWhenNode(NULL, pWhenThenlist, pElse, NULL, &pCaseWhen)); + + SNodeList* pParaList = NULL; + CHECK_RES_OUT_OF_MEM(createParListNode(pCaseWhen, &pParaList)); + + + // sum( case when ... end) as leader_col + SNode* pSumFun = NULL; + const char* pSumColAlias = "leader_col"; + CHECK_RES_OUT_OF_MEM(createParFunctionNode("sum", pSumColAlias, pParaList, &pSumFun)); + + SNode* pPara1 = nodesMakeValueNodeFromInt32(1); + CHECK_POINTER_OUT_OF_MEM(pThen); + pParaList = NULL; + CHECK_RES_OUT_OF_MEM(createParListNode(pPara1, &pParaList)); + + // count(1) as count_col + SNode* pCountFun = NULL; + const char* pCountColAlias = "count_col"; + CHECK_RES_OUT_OF_MEM(createParFunctionNode("count", pCountColAlias, pParaList, &pCountFun)); + + SNodeList* pProjList = NULL; + CHECK_RES_OUT_OF_MEM(createParListNode(pSumFun, &pProjList)); + CHECK_RES_OUT_OF_MEM(nodesListStrictAppend(pProjList, pCountFun)); + + SSelectStmt* pSubSelect = NULL; + // select sum( case when .... end) as leader_col, count(*) as count_col from information_schema.ins_vgroups + CHECK_RES_OUT_OF_MEM(createSimpleSelectStmtFromProjList(TSDB_INFORMATION_SCHEMA_DB, TSDB_INS_TABLE_VGROUPS, pProjList, &pSubSelect)); + + if (pDbName && pDbName[0] != 0) { + // for show db.alive + // select sum( case when .... end) as leader_col, count(*) as count_col from information_schema.ins_vgroups where db_name = "..." + SNode* pDbCond = NULL; + pValNode = nodesMakeValueNodeFromString(pDbName); + CHECK_RES_OUT_OF_MEM(createOperatorNode(OP_TYPE_EQUAL, "db_name", (SNode*)pValNode, &pDbCond)); + nodesDestroyNode((SNode*)pValNode); + pCxt->showRewrite = false; + pQuery->showRewrite = false; + pSubSelect->pWhere = pDbCond; + } + + + + pCond1 = NULL; + CHECK_RES_OUT_OF_MEM(createParOperatorNode(OP_TYPE_EQUAL, pSumColAlias, pCountColAlias, &pCond1)); + pCond2 = NULL; + SNode* pTempVal = nodesMakeValueNodeFromInt32(0); + CHECK_RES_OUT_OF_MEM(createOperatorNode(OP_TYPE_GREATER_THAN, pSumColAlias, pTempVal, &pCond2)); + //leader_col = count_col and leader_col > 0 + pTemp1 = NULL; + CHECK_RES_OUT_OF_MEM(createLogicCondNode(pCond1, pCond2, &pTemp1, LOGIC_COND_TYPE_AND)); + + pThen = nodesMakeValueNodeFromInt32(1); + CHECK_POINTER_OUT_OF_MEM(pThen); + pWhenThen = NULL; + CHECK_RES_OUT_OF_MEM(createParWhenThenNode(pTemp1, pThen, &pWhenThen)); + pWhenThenlist = NULL; + CHECK_RES_OUT_OF_MEM(createParListNode(pWhenThen, &pWhenThenlist)); + + pCond1 = NULL; + CHECK_RES_OUT_OF_MEM(createParOperatorNode(OP_TYPE_LOWER_THAN, pSumColAlias, pCountColAlias, &pCond1)); + pCond2 = NULL; + CHECK_RES_OUT_OF_MEM(createOperatorNode(OP_TYPE_GREATER_THAN, pSumColAlias, pTempVal, &pCond2)); + // leader_col < count_col and leader_col > 0 + pTemp2 = NULL; + CHECK_RES_OUT_OF_MEM(createLogicCondNode(pCond1, pCond2, &pTemp2, LOGIC_COND_TYPE_AND)); + nodesDestroyNode((SNode*)pTempVal); + + pThen = nodesMakeValueNodeFromInt32(2); + CHECK_POINTER_OUT_OF_MEM(pThen); + pWhenThen = NULL; + CHECK_RES_OUT_OF_MEM(createParWhenThenNode(pTemp2, pThen, &pWhenThen)); + CHECK_RES_OUT_OF_MEM(nodesListStrictAppend(pWhenThenlist, pWhenThen)); + + // case when leader_col = count_col and count_col > 0 then 1 when leader_col < count_col and count_col > 0 then 2 else 0 end as status + pCaseWhen = NULL; + pElse = nodesMakeValueNodeFromInt32(0); + CHECK_POINTER_OUT_OF_MEM(pElse); + CHECK_RES_OUT_OF_MEM(createParCaseWhenNode(NULL, pWhenThenlist, pElse, "status", &pCaseWhen)); + + pProjList = NULL; + CHECK_RES_OUT_OF_MEM(createParListNode(pCaseWhen, &pProjList)); + + SNode* pTempTblNode = NULL; + CHECK_RES_OUT_OF_MEM(createParTempTableNode(pSubSelect, &pTempTblNode)); + + + SSelectStmt* pStmt = (SSelectStmt*)nodesMakeNode(QUERY_NODE_SELECT_STMT); + CHECK_POINTER_OUT_OF_MEM(pStmt); + pStmt->pProjectionList = pProjList; + pStmt->pFromTable = pTempTblNode; + sprintf(pStmt->stmtName, "%p", pStmt); + + nodesDestroyNode(pQuery->pRoot); + pQuery->pRoot = (SNode*)pStmt; + return TSDB_CODE_SUCCESS; +} + static int32_t rewriteQuery(STranslateContext* pCxt, SQuery* pQuery) { int32_t code = TSDB_CODE_SUCCESS; switch (nodeType(pQuery->pRoot)) { @@ -13388,6 +13600,10 @@ static int32_t rewriteQuery(STranslateContext* pCxt, SQuery* pQuery) { case QUERY_NODE_SHOW_COMPACT_DETAILS_STMT: code = rewriteShowCompactDetailsStmt(pCxt, pQuery); break; + case QUERY_NODE_SHOW_DB_ALIVE_STMT: + case QUERY_NODE_SHOW_CLUSTER_ALIVE_STMT: + code = rewriteShowAliveStmt(pCxt, pQuery); + break; default: break; } @@ -13479,8 +13695,6 @@ static int32_t setQuery(STranslateContext* pCxt, SQuery* pQuery) { break; case QUERY_NODE_DESCRIBE_STMT: case QUERY_NODE_SHOW_CREATE_DATABASE_STMT: - case QUERY_NODE_SHOW_DB_ALIVE_STMT: - case QUERY_NODE_SHOW_CLUSTER_ALIVE_STMT: case QUERY_NODE_SHOW_CREATE_TABLE_STMT: case QUERY_NODE_SHOW_CREATE_STABLE_STMT: case QUERY_NODE_SHOW_CREATE_VIEW_STMT: diff --git a/tests/script/tsim/show/showalive.sim b/tests/script/tsim/show/showalive.sim new file mode 100644 index 0000000000..4cad1da01d --- /dev/null +++ b/tests/script/tsim/show/showalive.sim @@ -0,0 +1,167 @@ +system sh/stop_dnodes.sh +system sh/deploy.sh -n dnode1 -i 1 +system sh/deploy.sh -n dnode2 -i 2 +system sh/deploy.sh -n dnode3 -i 3 +system sh/deploy.sh -n dnode4 -i 4 +system sh/exec.sh -n dnode1 -s start +system sh/exec.sh -n dnode2 -s start +system sh/exec.sh -n dnode3 -s start +system sh/exec.sh -n dnode4 -s start + +sleep 1000 + +sql connect + + +print =============== add dnode into cluster +sql create dnode $hostname1 port 7200 +sql create dnode $hostname2 port 7300 +sql create dnode $hostname3 port 7400 +sql create dnode $hostname4 port 7500 + +sleep 1000 + +print =============== create database, stable, table +sql create database test vgroups 6; +sql use test; +sql create stable st(ts timestamp,a int,b int,c int) tags(ta int,tb int,tc int); +sql create table t1 using st tags(1,1,1); +sql create table t2 using st tags(2,2,2); +sql insert into t1 values(1648791211000,1,2,3); +sql insert into t1 values(1648791222001,2,2,3); +sql insert into t2 values(1648791211000,1,2,3); +sql insert into t2 values(1648791222001,2,2,3); + +$loop_count = 0 + +loop0: + +sleep 1000 + +$loop_count = $loop_count + 1 +if $loop_count == 20 then + return -1 +endi + +print show cluster alive; +sql show cluster alive; + +if $data00 != 1 then + print =====data00=$data00 + goto loop0 +endi + +print show test.alive; +sql show test.alive; + +if $data00 != 1 then + print =====data00=$data00 + goto loop0 +endi + +print stop dnode3 +print stop dnode4 +system sh/exec.sh -n dnode3 -s stop -x SIGKILL +system sh/exec.sh -n dnode4 -s stop -x SIGKILL + +$loop_count = 0 + +loop1: + +sleep 1000 + +$loop_count = $loop_count + 1 +if $loop_count == 20 then + return -1 +endi + +print show cluster alive; +sql show cluster alive; + +if $data00 != 2 then + print =====data00=$data00 + goto loop1 +endi + +print show test.alive +sql show test.alive; + +if $data00 != 2 then + print =====data00=$data00 + goto loop1 +endi + + +sql create database test1 vgroups 2; + +$loop_count = 0 + +loop2: + +sleep 1000 + +$loop_count = $loop_count + 1 +if $loop_count == 20 then + return -1 +endi + +print show cluster alive; +sql show cluster alive; + +if $data00 != 2 then + goto loop2 +endi + +print show test1.alive; +sql show test1.alive; + +if $data00 != 1 then + print =====data00=$data00 + goto loop2 +endi + +print stop dnode2 + +system sh/exec.sh -n dnode2 -s stop -x SIGKILL + + +$loop_count = 0 + +loop3: + +sleep 1000 + +$loop_count = $loop_count + 1 +if $loop_count == 20 then + return -1 +endi + + +print show cluster alive; +sql show cluster alive; + +if $data00 != 2 then + print =====data00=$data00 + goto loop3 +endi + +print show test.alive; +sql show test.alive; + +if $data00 != 2 then + print =====data00=$data00 + goto loop3 +endi + +sql show test1.alive; + +if $data00 != 2 then + print =====data00=$data00 + goto loop3 +endi + + +system sh/exec.sh -n dnode1 -s stop -x SIGINT +system sh/exec.sh -n dnode2 -s stop -x SIGINT +system sh/exec.sh -n dnode3 -s stop -x SIGINT +system sh/exec.sh -n dnode4 -s stop -x SIGINT