From 861445c33afc8def8ba76f67881342a233e03c1e Mon Sep 17 00:00:00 2001 From: Xiaoyu Wang Date: Thu, 17 Mar 2022 03:14:59 -0400 Subject: [PATCH] TD-14043 show tables split --- include/libs/nodes/querynodes.h | 1 + source/libs/parser/src/parAstCreater.c | 114 ++++++++++++--------- source/libs/parser/src/parTranslater.c | 41 ++++++-- source/libs/parser/test/mockCatalog.cpp | 31 +++--- source/libs/planner/src/planPhysiCreater.c | 17 +-- source/libs/planner/src/planSpliter.c | 3 +- source/libs/planner/test/plannerTest.cpp | 7 ++ 7 files changed, 138 insertions(+), 76 deletions(-) diff --git a/include/libs/nodes/querynodes.h b/include/libs/nodes/querynodes.h index 6a6d508096..f279b6c663 100644 --- a/include/libs/nodes/querynodes.h +++ b/include/libs/nodes/querynodes.h @@ -125,6 +125,7 @@ typedef struct SRealTableNode { STableNode table; // QUERY_NODE_REAL_TABLE struct STableMeta* pMeta; SVgroupsInfo* pVgroupList; + char useDbName[TSDB_DB_NAME_LEN]; } SRealTableNode; typedef struct STempTableNode { diff --git a/source/libs/parser/src/parAstCreater.c b/source/libs/parser/src/parAstCreater.c index 4ba989ca3e..cd6ddd182c 100644 --- a/source/libs/parser/src/parAstCreater.c +++ b/source/libs/parser/src/parAstCreater.c @@ -321,103 +321,109 @@ void initAstCreateContext(SParseContext* pParseCxt, SAstCreateContext* pCxt) { static bool checkUserName(SAstCreateContext* pCxt, const SToken* pUserName) { if (NULL == pUserName) { - return false; - } - if (pUserName->n >= TSDB_USER_LEN) { - generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_NAME_OR_PASSWD_TOO_LONG); pCxt->valid = false; + } else { + if (pUserName->n >= TSDB_USER_LEN) { + generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_NAME_OR_PASSWD_TOO_LONG); + pCxt->valid = false; + } } return pCxt->valid; } static bool checkPassword(SAstCreateContext* pCxt, const SToken* pPasswordToken, char* pPassword) { if (NULL == pPasswordToken) { - return false; - } - if (pPasswordToken->n >= (TSDB_USET_PASSWORD_LEN - 2)) { + pCxt->valid = false; + } else if (pPasswordToken->n >= (TSDB_USET_PASSWORD_LEN - 2)) { generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_NAME_OR_PASSWD_TOO_LONG); pCxt->valid = false; - return false; - } - strncpy(pPassword, pPasswordToken->z, pPasswordToken->n); - strdequote(pPassword); - if (strtrim(pPassword) <= 0) { - generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_PASSWD_EMPTY); - pCxt->valid = false; + } else { + strncpy(pPassword, pPasswordToken->z, pPasswordToken->n); + strdequote(pPassword); + if (strtrim(pPassword) <= 0) { + generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_PASSWD_EMPTY); + pCxt->valid = false; + } } return pCxt->valid; } static bool checkAndSplitEndpoint(SAstCreateContext* pCxt, const SToken* pEp, char* pFqdn, int32_t* pPort) { if (NULL == pEp) { - return false; - } - if (pEp->n >= TSDB_FQDN_LEN + 2 + 6) { // format 'fqdn:port' + pCxt->valid = false; + } else if (pEp->n >= TSDB_FQDN_LEN + 2 + 6) { // format 'fqdn:port' generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_NAME_OR_PASSWD_TOO_LONG); pCxt->valid = false; - } - char ep[TSDB_FQDN_LEN + 2 + 6]; - strncpy(ep, pEp->z, pEp->n); - strdequote(ep); - strtrim(ep); - char* pColon = strchr(ep, ':'); - if (NULL == pColon) { - generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_ENDPOINT); - pCxt->valid = false; - } - strncpy(pFqdn, ep, pColon - ep); - *pPort = strtol(pColon + 1, NULL, 10); - if (*pPort >= UINT16_MAX || *pPort <= 0) { - generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_PORT); - pCxt->valid = false; + } else { + char ep[TSDB_FQDN_LEN + 2 + 6]; + strncpy(ep, pEp->z, pEp->n); + strdequote(ep); + strtrim(ep); + char* pColon = strchr(ep, ':'); + if (NULL == pColon) { + generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_ENDPOINT); + pCxt->valid = false; + } else { + strncpy(pFqdn, ep, pColon - ep); + *pPort = strtol(pColon + 1, NULL, 10); + if (*pPort >= UINT16_MAX || *pPort <= 0) { + generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_PORT); + pCxt->valid = false; + } + } } return pCxt->valid; } static bool checkFqdn(SAstCreateContext* pCxt, const SToken* pFqdn) { if (NULL == pFqdn) { - return false; - } - if (pFqdn->n >= TSDB_FQDN_LEN) { - generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_NAME_OR_PASSWD_TOO_LONG); pCxt->valid = false; + } else { + if (pFqdn->n >= TSDB_FQDN_LEN) { + generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_NAME_OR_PASSWD_TOO_LONG); + pCxt->valid = false; + } } return pCxt->valid; } static bool checkPort(SAstCreateContext* pCxt, const SToken* pPortToken, int32_t* pPort) { if (NULL == pPortToken) { - return false; - } - *pPort = strtol(pPortToken->z, NULL, 10); - if (*pPort >= UINT16_MAX || *pPort <= 0) { - generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_PORT); pCxt->valid = false; + } else { + *pPort = strtol(pPortToken->z, NULL, 10); + if (*pPort >= UINT16_MAX || *pPort <= 0) { + generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_PORT); + pCxt->valid = false; + } } return pCxt->valid; } static bool checkDbName(SAstCreateContext* pCxt, const SToken* pDbName, bool query) { if (NULL == pDbName) { - return (query ? NULL != pCxt->pQueryCxt->db : true); + pCxt->valid = (query ? NULL != pCxt->pQueryCxt->db : true); + } else { + pCxt->valid = pDbName->n < TSDB_DB_NAME_LEN ? true : false; } - pCxt->valid = pDbName->n < TSDB_DB_NAME_LEN ? true : false; return pCxt->valid; } static bool checkTableName(SAstCreateContext* pCxt, const SToken* pTableName) { if (NULL == pTableName) { - return true; + pCxt->valid = true; + } else { + pCxt->valid = pTableName->n < TSDB_TABLE_NAME_LEN ? true : false; } - pCxt->valid = pTableName->n < TSDB_TABLE_NAME_LEN ? true : false; return pCxt->valid; } static bool checkColumnName(SAstCreateContext* pCxt, const SToken* pColumnName) { if (NULL == pColumnName) { - return true; + pCxt->valid = true; + } else { + pCxt->valid = pColumnName->n < TSDB_COL_NAME_LEN ? true : false; } - pCxt->valid = pColumnName->n < TSDB_COL_NAME_LEN ? true : false; return pCxt->valid; } @@ -517,6 +523,10 @@ SNode* createDurationValueNode(SAstCreateContext* pCxt, const SToken* pLiteral) } SNode* createDefaultDatabaseCondValue(SAstCreateContext* pCxt) { + if (NULL == pCxt->pQueryCxt->db) { + return NULL; + } + SValueNode* val = (SValueNode*)nodesMakeNode(QUERY_NODE_VALUE); CHECK_OUT_OF_MEM(val); val->literal = strdup(pCxt->pQueryCxt->db); @@ -590,6 +600,7 @@ SNode* createRealTableNode(SAstCreateContext* pCxt, const SToken* pDbName, const strncpy(realTable->table.tableAlias, pTableName->z, pTableName->n); } strncpy(realTable->table.tableName, pTableName->z, pTableName->n); + strcpy(realTable->useDbName, pCxt->pQueryCxt->db); return (SNode*)realTable; } @@ -920,7 +931,16 @@ SNode* createUseDatabaseStmt(SAstCreateContext* pCxt, const SToken* pDbName) { return (SNode*)pStmt; } +static bool needDbShowStmt(ENodeType type) { + return QUERY_NODE_SHOW_TABLES_STMT == type || QUERY_NODE_SHOW_STABLES_STMT == type || QUERY_NODE_SHOW_VGROUPS_STMT == type; +} + SNode* createShowStmt(SAstCreateContext* pCxt, ENodeType type, SNode* pDbName, SNode* pTbNamePattern) { + if (needDbShowStmt(type) && NULL == pDbName && NULL == pCxt->pQueryCxt->db) { + snprintf(pCxt->pQueryCxt->pMsg, pCxt->pQueryCxt->msgLen, "db not specified"); + pCxt->valid = false; + return NULL; + } SShowStmt* pStmt = nodesMakeNode(type);; CHECK_OUT_OF_MEM(pStmt); pStmt->pDbName = pDbName; diff --git a/source/libs/parser/src/parTranslater.c b/source/libs/parser/src/parTranslater.c index 9efc88d11b..c088498aef 100644 --- a/source/libs/parser/src/parTranslater.c +++ b/source/libs/parser/src/parTranslater.c @@ -560,6 +560,33 @@ static int32_t toVgroupsInfo(SArray* pVgs, SVgroupsInfo** pVgsInfo) { return TSDB_CODE_SUCCESS; } +static int32_t setSysTableVgroupList(SParseContext* pCxt, SName* pName, SRealTableNode* pRealTable) { + // todo release + // if (0 != strcmp(pRealTable->table.tableName, TSDB_INS_TABLE_USER_TABLES)) { + // return TSDB_CODE_SUCCESS; + // } + + int32_t code = TSDB_CODE_SUCCESS; + SArray* vgroupList = NULL; + if ('\0' != pRealTable->useDbName[0]) { + code = getDBVgInfo(pCxt, pRealTable->useDbName, &vgroupList); + } else { + code = getDBVgInfoImpl(pCxt, pName, &vgroupList); + } + + if (TSDB_CODE_SUCCESS == code) { + // todo remove + if (NULL != vgroupList && taosArrayGetSize(vgroupList) > 0 && 0 != strcmp(pRealTable->table.tableName, TSDB_INS_TABLE_USER_TABLES)) { + taosArrayPopTailBatch(vgroupList, taosArrayGetSize(vgroupList) - 1); + } + + code = toVgroupsInfo(vgroupList, &pRealTable->pVgroupList); + } + taosArrayDestroy(vgroupList); + + return code; +} + static int32_t setTableVgroupList(SParseContext* pCxt, SName* pName, SRealTableNode* pRealTable) { int32_t code = TSDB_CODE_SUCCESS; if (TSDB_SUPER_TABLE == pRealTable->pMeta->tableType) { @@ -570,12 +597,7 @@ static int32_t setTableVgroupList(SParseContext* pCxt, SName* pName, SRealTableN } taosArrayDestroy(vgroupList); } else if (TSDB_SYSTEM_TABLE == pRealTable->pMeta->tableType) { - SArray* vgroupList = NULL; - code = getDBVgInfoImpl(pCxt, pName, &vgroupList); - if (TSDB_CODE_SUCCESS == code) { - code = toVgroupsInfo(vgroupList, &pRealTable->pVgroupList); - } - taosArrayDestroy(vgroupList); + code = setSysTableVgroupList(pCxt, pName, pRealTable); } else { pRealTable->pVgroupList = calloc(1, sizeof(SVgroupsInfo) + sizeof(SVgroupInfo)); if (NULL == pRealTable->pVgroupList) { @@ -1159,9 +1181,6 @@ static int32_t translateShow(STranslateContext* pCxt, SShowStmt* pStmt) { static int32_t translateShowTables(STranslateContext* pCxt) { SVShowTablesReq* pShowReq = calloc(1, sizeof(SVShowTablesReq)); - if (pCxt->pParseCxt->db == NULL || strlen(pCxt->pParseCxt->db) == 0) { - return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_TSC_INVALID_OPERATION, "db not specified"); - } SArray* array = NULL; int32_t code = getDBVgInfo(pCxt->pParseCxt, pCxt->pParseCxt->db, &array); @@ -1407,6 +1426,10 @@ static int32_t createShowCondition(const SShowStmt* pShow, SSelectStmt* pSelect) pSelect->pWhere = (NULL == pDbCond ? pTbCond : pDbCond); } + if (NULL != pShow->pDbName) { + strcpy(((SRealTableNode*)pSelect->pFromTable)->useDbName, ((SValueNode*)pShow->pDbName)->literal); + } + return TSDB_CODE_SUCCESS; } diff --git a/source/libs/parser/test/mockCatalog.cpp b/source/libs/parser/test/mockCatalog.cpp index de354b57f0..5723b93f8b 100644 --- a/source/libs/parser/test/mockCatalog.cpp +++ b/source/libs/parser/test/mockCatalog.cpp @@ -28,58 +28,58 @@ namespace { void generateInformationSchema(MockCatalogService* mcs) { { - ITableBuilder& builder = mcs->createTableBuilder("information_schema", "dnodes", TSDB_NORMAL_TABLE, 1).addColumn("id", TSDB_DATA_TYPE_INT); + ITableBuilder& builder = mcs->createTableBuilder("information_schema", "dnodes", TSDB_SYSTEM_TABLE, 1).addColumn("id", TSDB_DATA_TYPE_INT); builder.done(); } { - ITableBuilder& builder = mcs->createTableBuilder("information_schema", "mnodes", TSDB_NORMAL_TABLE, 1).addColumn("id", TSDB_DATA_TYPE_INT); + ITableBuilder& builder = mcs->createTableBuilder("information_schema", "mnodes", TSDB_SYSTEM_TABLE, 1).addColumn("id", TSDB_DATA_TYPE_INT); builder.done(); } { - ITableBuilder& builder = mcs->createTableBuilder("information_schema", "modules", TSDB_NORMAL_TABLE, 1).addColumn("id", TSDB_DATA_TYPE_INT); + ITableBuilder& builder = mcs->createTableBuilder("information_schema", "modules", TSDB_SYSTEM_TABLE, 1).addColumn("id", TSDB_DATA_TYPE_INT); builder.done(); } { - ITableBuilder& builder = mcs->createTableBuilder("information_schema", "qnodes", TSDB_NORMAL_TABLE, 1).addColumn("id", TSDB_DATA_TYPE_INT); + ITableBuilder& builder = mcs->createTableBuilder("information_schema", "qnodes", TSDB_SYSTEM_TABLE, 1).addColumn("id", TSDB_DATA_TYPE_INT); builder.done(); } { - ITableBuilder& builder = mcs->createTableBuilder("information_schema", "user_databases", TSDB_NORMAL_TABLE, 1).addColumn("name", TSDB_DATA_TYPE_BINARY, TSDB_DB_NAME_LEN); + ITableBuilder& builder = mcs->createTableBuilder("information_schema", "user_databases", TSDB_SYSTEM_TABLE, 1).addColumn("name", TSDB_DATA_TYPE_BINARY, TSDB_DB_NAME_LEN); builder.done(); } { - ITableBuilder& builder = mcs->createTableBuilder("information_schema", "user_functions", TSDB_NORMAL_TABLE, 1).addColumn("name", TSDB_DATA_TYPE_BINARY, TSDB_FUNC_NAME_LEN); + ITableBuilder& builder = mcs->createTableBuilder("information_schema", "user_functions", TSDB_SYSTEM_TABLE, 1).addColumn("name", TSDB_DATA_TYPE_BINARY, TSDB_FUNC_NAME_LEN); builder.done(); } { - ITableBuilder& builder = mcs->createTableBuilder("information_schema", "user_indexes", TSDB_NORMAL_TABLE, 2) + ITableBuilder& builder = mcs->createTableBuilder("information_schema", "user_indexes", TSDB_SYSTEM_TABLE, 2) .addColumn("db_name", TSDB_DATA_TYPE_BINARY, TSDB_DB_NAME_LEN).addColumn("table_name", TSDB_DATA_TYPE_BINARY, TSDB_TABLE_NAME_LEN); builder.done(); } { - ITableBuilder& builder = mcs->createTableBuilder("information_schema", "user_stables", TSDB_NORMAL_TABLE, 2) + ITableBuilder& builder = mcs->createTableBuilder("information_schema", "user_stables", TSDB_SYSTEM_TABLE, 2) .addColumn("db_name", TSDB_DATA_TYPE_BINARY, TSDB_DB_NAME_LEN).addColumn("stable_name", TSDB_DATA_TYPE_BINARY, TSDB_TABLE_NAME_LEN); builder.done(); } { - ITableBuilder& builder = mcs->createTableBuilder("information_schema", "user_streams", TSDB_NORMAL_TABLE, 1).addColumn("stream_name", TSDB_DATA_TYPE_BINARY, TSDB_TABLE_NAME_LEN); + ITableBuilder& builder = mcs->createTableBuilder("information_schema", "user_streams", TSDB_SYSTEM_TABLE, 1).addColumn("stream_name", TSDB_DATA_TYPE_BINARY, TSDB_TABLE_NAME_LEN); builder.done(); } { - ITableBuilder& builder = mcs->createTableBuilder("information_schema", "user_tables", TSDB_NORMAL_TABLE, 2) + ITableBuilder& builder = mcs->createTableBuilder("information_schema", "user_tables", TSDB_SYSTEM_TABLE, 2) .addColumn("db_name", TSDB_DATA_TYPE_BINARY, TSDB_DB_NAME_LEN).addColumn("table_name", TSDB_DATA_TYPE_BINARY, TSDB_TABLE_NAME_LEN); builder.done(); } { - ITableBuilder& builder = mcs->createTableBuilder("information_schema", "user_table_distributed", TSDB_NORMAL_TABLE, 1).addColumn("db_name", TSDB_DATA_TYPE_BINARY, TSDB_DB_NAME_LEN); + ITableBuilder& builder = mcs->createTableBuilder("information_schema", "user_table_distributed", TSDB_SYSTEM_TABLE, 1).addColumn("db_name", TSDB_DATA_TYPE_BINARY, TSDB_DB_NAME_LEN); builder.done(); } { - ITableBuilder& builder = mcs->createTableBuilder("information_schema", "user_users", TSDB_NORMAL_TABLE, 1).addColumn("user_name", TSDB_DATA_TYPE_BINARY, TSDB_USER_LEN); + ITableBuilder& builder = mcs->createTableBuilder("information_schema", "user_users", TSDB_SYSTEM_TABLE, 1).addColumn("user_name", TSDB_DATA_TYPE_BINARY, TSDB_USER_LEN); builder.done(); } { - ITableBuilder& builder = mcs->createTableBuilder("information_schema", "vgroups", TSDB_NORMAL_TABLE, 1).addColumn("db_name", TSDB_DATA_TYPE_BINARY, TSDB_DB_NAME_LEN); + ITableBuilder& builder = mcs->createTableBuilder("information_schema", "vgroups", TSDB_SYSTEM_TABLE, 1).addColumn("db_name", TSDB_DATA_TYPE_BINARY, TSDB_DB_NAME_LEN); builder.done(); } } @@ -124,6 +124,10 @@ int32_t __catalogGetDBVgVersion(SCatalog* pCtg, const char* dbFName, int32_t* ve return 0; } +int32_t __catalogGetDBVgInfo(SCatalog* pCtg, void *pRpc, const SEpSet* pMgmtEps, const char* dbFName, SArray** vgroupList) { + return 0; +} + void initMetaDataEnv() { mockCatalogService.reset(new MockCatalogService()); @@ -133,6 +137,7 @@ void initMetaDataEnv() { stub.set(catalogGetTableHashVgroup, __catalogGetTableHashVgroup); stub.set(catalogGetTableDistVgInfo, __catalogGetTableDistVgInfo); stub.set(catalogGetDBVgVersion, __catalogGetDBVgVersion); + stub.set(catalogGetDBVgInfo, __catalogGetDBVgInfo); // { // AddrAny any("libcatalog.so"); // std::map result; diff --git a/source/libs/planner/src/planPhysiCreater.c b/source/libs/planner/src/planPhysiCreater.c index 93ad586e98..c304e173fb 100644 --- a/source/libs/planner/src/planPhysiCreater.c +++ b/source/libs/planner/src/planPhysiCreater.c @@ -266,14 +266,19 @@ static SPhysiNode* createTableScanPhysiNode(SPhysiPlanContext* pCxt, SSubplan* p return (SPhysiNode*)pTableScan; } -static SPhysiNode* createSystemTableScanPhysiNode(SPhysiPlanContext* pCxt, SScanLogicNode* pScanLogicNode) { +static SPhysiNode* createSystemTableScanPhysiNode(SPhysiPlanContext* pCxt, SSubplan* pSubplan, SScanLogicNode* pScanLogicNode) { SSystemTableScanPhysiNode* pScan = (SSystemTableScanPhysiNode*)makePhysiNode(pCxt, QUERY_NODE_PHYSICAL_PLAN_SYSTABLE_SCAN); CHECK_ALLOC(pScan, NULL); CHECK_CODE(initScanPhysiNode(pCxt, pScanLogicNode, (SScanPhysiNode*)pScan), (SPhysiNode*)pScan); - for (int32_t i = 0; i < pScanLogicNode->pVgroupList->numOfVgroups; ++i) { - SQueryNodeAddr addr; - vgroupInfoToNodeAddr(pScanLogicNode->pVgroupList->vgroups + i, &addr); - taosArrayPush(pCxt->pExecNodeList, &addr); + if (0 == strcmp(pScanLogicNode->tableName.tname, TSDB_INS_TABLE_USER_TABLES)) { + vgroupInfoToNodeAddr(pScanLogicNode->pVgroupList->vgroups, &pSubplan->execNode); + taosArrayPush(pCxt->pExecNodeList, &pSubplan->execNode); + } else { + for (int32_t i = 0; i < pScanLogicNode->pVgroupList->numOfVgroups; ++i) { + SQueryNodeAddr addr; + vgroupInfoToNodeAddr(pScanLogicNode->pVgroupList->vgroups + i, &addr); + taosArrayPush(pCxt->pExecNodeList, &addr); + } } pScan->mgmtEpSet = pCxt->pPlanCxt->mgmtEpSet; return (SPhysiNode*)pScan; @@ -286,7 +291,7 @@ static SPhysiNode* createScanPhysiNode(SPhysiPlanContext* pCxt, SSubplan* pSubpl case SCAN_TYPE_TABLE: return createTableScanPhysiNode(pCxt, pSubplan, pScanLogicNode); case SCAN_TYPE_SYSTEM_TABLE: - return createSystemTableScanPhysiNode(pCxt, pScanLogicNode); + return createSystemTableScanPhysiNode(pCxt, pSubplan, pScanLogicNode); case SCAN_TYPE_STREAM: break; default: diff --git a/source/libs/planner/src/planSpliter.c b/source/libs/planner/src/planSpliter.c index 5a5e1d46c6..5c47ee52b3 100644 --- a/source/libs/planner/src/planSpliter.c +++ b/source/libs/planner/src/planSpliter.c @@ -44,7 +44,8 @@ typedef struct SStsInfo { } SStsInfo; static SLogicNode* stsMatchByNode(SLogicNode* pNode) { - if (QUERY_NODE_LOGIC_PLAN_SCAN == nodeType(pNode) && TSDB_SUPER_TABLE == ((SScanLogicNode*)pNode)->pMeta->tableType) { + if (QUERY_NODE_LOGIC_PLAN_SCAN == nodeType(pNode) && + NULL != ((SScanLogicNode*)pNode)->pVgroupList && ((SScanLogicNode*)pNode)->pVgroupList->numOfVgroups > 1) { return pNode; } SNode* pChild; diff --git a/source/libs/planner/test/plannerTest.cpp b/source/libs/planner/test/plannerTest.cpp index 51642199f9..7e77b50e1c 100644 --- a/source/libs/planner/test/plannerTest.cpp +++ b/source/libs/planner/test/plannerTest.cpp @@ -166,3 +166,10 @@ TEST_F(PlannerTest, subquery) { bind("SELECT count(*) FROM (SELECT c1 + c3 a, c1 + count(*) b FROM t1 where c2 = 'abc' GROUP BY c1, c3) where a > 100 group by b"); ASSERT_TRUE(run()); } + +TEST_F(PlannerTest, showTables) { + setDatabase("root", "test"); + + bind("show tables"); + ASSERT_TRUE(run()); +}