304 lines
		
	
	
		
			8.5 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			304 lines
		
	
	
		
			8.5 KiB
		
	
	
	
		
			C++
		
	
	
	
| /*
 | |
|  * Copyright (c) 2019 TAOS Data, Inc. <jhtao@taosdata.com>
 | |
|  *
 | |
|  * 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 <http://www.gnu.org/licenses/>.
 | |
|  */
 | |
| 
 | |
| #include "parTestUtil.h"
 | |
| 
 | |
| using namespace std;
 | |
| 
 | |
| namespace ParserTest {
 | |
| 
 | |
| class ParserInitialDTest : public ParserDdlTest {};
 | |
| 
 | |
| // DELETE FROM table_name [WHERE condition]
 | |
| TEST_F(ParserInitialDTest, delete) {
 | |
|   useDb("root", "test");
 | |
| 
 | |
|   run("DELETE FROM t1");
 | |
| 
 | |
|   run("DELETE FROM t1 WHERE ts > now - 2d and ts < now - 1d");
 | |
| 
 | |
|   run("DELETE FROM st1");
 | |
| 
 | |
|   run("DELETE FROM st1 WHERE ts > now - 2d and ts < now - 1d AND tag1 = 10");
 | |
| }
 | |
| 
 | |
| TEST_F(ParserInitialDTest, deleteSemanticCheck) {
 | |
|   useDb("root", "test");
 | |
| 
 | |
|   run("DELETE FROM t1 WHERE c1 > 10", TSDB_CODE_PAR_INVALID_DELETE_WHERE, PARSER_STAGE_TRANSLATE);
 | |
| }
 | |
| 
 | |
| // DESC table_name
 | |
| TEST_F(ParserInitialDTest, describe) {
 | |
|   useDb("root", "test");
 | |
| 
 | |
|   run("DESC t1");
 | |
| 
 | |
|   run("DESCRIBE st1");
 | |
| }
 | |
| 
 | |
| // todo describe
 | |
| // todo DROP account
 | |
| 
 | |
| // DROP CONSUMER GROUP [ IF EXISTS ] cgroup_name ON topic_name
 | |
| TEST_F(ParserInitialDTest, dropConsumerGroup) {
 | |
|   useDb("root", "test");
 | |
| 
 | |
|   SMDropCgroupReq expect = {0};
 | |
| 
 | |
|   auto clearDropCgroupReq = [&]() { memset(&expect, 0, sizeof(SMDropCgroupReq)); };
 | |
| 
 | |
|   auto setDropCgroupReq = [&](const char* pTopicName, const char* pCGroupName, int8_t igNotExists = 0) {
 | |
|     snprintf(expect.topic, sizeof(expect.topic), "0.%s", pTopicName);
 | |
|     strcpy(expect.cgroup, pCGroupName);
 | |
|     expect.igNotExists = igNotExists;
 | |
|   };
 | |
| 
 | |
|   setCheckDdlFunc([&](const SQuery* pQuery, ParserStage stage) {
 | |
|     ASSERT_EQ(nodeType(pQuery->pRoot), QUERY_NODE_DROP_CGROUP_STMT);
 | |
|     SMDropCgroupReq req = {0};
 | |
|     ASSERT_TRUE(TSDB_CODE_SUCCESS == tDeserializeSMDropCgroupReq(pQuery->pCmdMsg->pMsg, pQuery->pCmdMsg->msgLen, &req));
 | |
| 
 | |
|     ASSERT_EQ(std::string(req.topic), std::string(expect.topic));
 | |
|     ASSERT_EQ(std::string(req.cgroup), std::string(expect.cgroup));
 | |
|     ASSERT_EQ(req.igNotExists, expect.igNotExists);
 | |
|   });
 | |
| 
 | |
|   setDropCgroupReq("tp1", "cg1");
 | |
|   run("DROP CONSUMER GROUP cg1 ON tp1");
 | |
|   clearDropCgroupReq();
 | |
| 
 | |
|   setDropCgroupReq("tp1", "cg1", 1);
 | |
|   run("DROP CONSUMER GROUP IF EXISTS cg1 ON tp1");
 | |
|   clearDropCgroupReq();
 | |
| }
 | |
| 
 | |
| // todo DROP database
 | |
| 
 | |
| TEST_F(ParserInitialDTest, dropDnode) {
 | |
|   useDb("root", "test");
 | |
| 
 | |
|   SDropDnodeReq expect = {0};
 | |
| 
 | |
|   auto clearDropDnodeReq = [&]() { memset(&expect, 0, sizeof(SDropDnodeReq)); };
 | |
| 
 | |
|   auto setDropDnodeReqById = [&](int32_t dnodeId, bool force = false, bool unsafe = false) {
 | |
|     expect.dnodeId = dnodeId;
 | |
|     expect.force = force;
 | |
|     expect.unsafe = unsafe;
 | |
|   };
 | |
| 
 | |
|   auto setDropDnodeReqByEndpoint = [&](const char* pFqdn, int32_t port = tsServerPort, bool force = false, bool unsafe = false) {
 | |
|     strcpy(expect.fqdn, pFqdn);
 | |
|     expect.port = port;
 | |
|     expect.force = force;
 | |
|     expect.unsafe = unsafe;
 | |
|   };
 | |
| 
 | |
|   setCheckDdlFunc([&](const SQuery* pQuery, ParserStage stage) {
 | |
|     ASSERT_EQ(nodeType(pQuery->pRoot), QUERY_NODE_DROP_DNODE_STMT);
 | |
|     SDropDnodeReq req = {0};
 | |
|     ASSERT_TRUE(TSDB_CODE_SUCCESS == tDeserializeSDropDnodeReq(pQuery->pCmdMsg->pMsg, pQuery->pCmdMsg->msgLen, &req));
 | |
| 
 | |
|     ASSERT_EQ(req.dnodeId, expect.dnodeId);
 | |
|     ASSERT_EQ(std::string(req.fqdn), std::string(expect.fqdn));
 | |
|     ASSERT_EQ(req.port, expect.port);
 | |
|     ASSERT_EQ(req.force, expect.force);
 | |
|     ASSERT_EQ(req.unsafe, expect.unsafe);
 | |
|   });
 | |
| 
 | |
|   setDropDnodeReqById(1);
 | |
|   run("DROP DNODE 1");
 | |
|   clearDropDnodeReq();
 | |
| 
 | |
|   setDropDnodeReqById(2, true);
 | |
|   run("DROP DNODE 2 FORCE");
 | |
|   clearDropDnodeReq();
 | |
| 
 | |
|   setDropDnodeReqById(2, false, true);
 | |
|   run("DROP DNODE 2 UNSAFE");
 | |
|   clearDropDnodeReq();
 | |
| 
 | |
|   setDropDnodeReqByEndpoint("host1", 7030);
 | |
|   run("DROP DNODE 'host1:7030'");
 | |
|   clearDropDnodeReq();
 | |
| 
 | |
|   setDropDnodeReqByEndpoint("host2", 8030, true);
 | |
|   run("DROP DNODE 'host2:8030' FORCE");
 | |
|   clearDropDnodeReq();
 | |
| 
 | |
|   setDropDnodeReqByEndpoint("host2", 8030, false, true);
 | |
|   run("DROP DNODE 'host2:8030' UNSAFE");
 | |
|   clearDropDnodeReq();
 | |
| 
 | |
|   setDropDnodeReqByEndpoint("host1");
 | |
|   run("DROP DNODE host1");
 | |
|   clearDropDnodeReq();
 | |
| 
 | |
|   setDropDnodeReqByEndpoint("host2", tsServerPort, true);
 | |
|   run("DROP DNODE host2 FORCE");
 | |
|   clearDropDnodeReq();
 | |
| 
 | |
|   setDropDnodeReqByEndpoint("host2", tsServerPort, false, true);
 | |
|   run("DROP DNODE host2 UNSAFE");
 | |
|   clearDropDnodeReq();
 | |
| }
 | |
| 
 | |
| // todo DROP function
 | |
| 
 | |
| TEST_F(ParserInitialDTest, dropIndex) {
 | |
|   useDb("root", "test");
 | |
| 
 | |
|   SMDropSmaReq expect = {0};
 | |
| 
 | |
|   auto clearDropSmaReq = [&]() { memset(&expect, 0, sizeof(SMDropSmaReq)); };
 | |
| 
 | |
|   auto setDropSmaReq = [&](const char* pName, int8_t igNotExists = 0) {
 | |
|     sprintf(expect.name, "0.test.%s", pName);
 | |
|     expect.igNotExists = igNotExists;
 | |
|   };
 | |
| 
 | |
|   setCheckDdlFunc([&](const SQuery* pQuery, ParserStage stage) {
 | |
|     ASSERT_EQ(nodeType(pQuery->pRoot), QUERY_NODE_DROP_INDEX_STMT);
 | |
|     SMDropSmaReq req = {0};
 | |
|     ASSERT_TRUE(TSDB_CODE_SUCCESS == tDeserializeSMDropSmaReq(pQuery->pCmdMsg->pMsg, pQuery->pCmdMsg->msgLen, &req));
 | |
| 
 | |
|     ASSERT_EQ(std::string(req.name), std::string(expect.name));
 | |
|     ASSERT_EQ(req.igNotExists, expect.igNotExists);
 | |
|   });
 | |
| 
 | |
|   setDropSmaReq("index1");
 | |
|   run("DROP INDEX index1");
 | |
|   clearDropSmaReq();
 | |
| 
 | |
|   setDropSmaReq("index2", 1);
 | |
|   run("DROP INDEX IF EXISTS index2");
 | |
|   clearDropSmaReq();
 | |
| }
 | |
| 
 | |
| TEST_F(ParserInitialDTest, dropMnode) {
 | |
|   useDb("root", "test");
 | |
| 
 | |
|   run("DROP mnode on dnode 1");
 | |
| }
 | |
| 
 | |
| TEST_F(ParserInitialDTest, dropQnode) {
 | |
|   useDb("root", "test");
 | |
| 
 | |
|   SMDropQnodeReq expect = {0};
 | |
| 
 | |
|   auto setDropQnodeReq = [&](int32_t dnodeId) { expect.dnodeId = dnodeId; };
 | |
| 
 | |
|   setCheckDdlFunc([&](const SQuery* pQuery, ParserStage stage) {
 | |
|     ASSERT_EQ(nodeType(pQuery->pRoot), QUERY_NODE_DROP_QNODE_STMT);
 | |
|     SMDropQnodeReq req = {0};
 | |
|     ASSERT_TRUE(TSDB_CODE_SUCCESS ==
 | |
|                 tDeserializeSCreateDropMQSNodeReq(pQuery->pCmdMsg->pMsg, pQuery->pCmdMsg->msgLen, &req));
 | |
| 
 | |
|     ASSERT_EQ(req.dnodeId, expect.dnodeId);
 | |
|   });
 | |
| 
 | |
|   setDropQnodeReq(1);
 | |
|   run("DROP QNODE ON DNODE 1");
 | |
| }
 | |
| 
 | |
| TEST_F(ParserInitialDTest, dropSnode) {
 | |
|   useDb("root", "test");
 | |
| 
 | |
|   run("DROP snode on dnode 1");
 | |
| }
 | |
| 
 | |
| TEST_F(ParserInitialDTest, dropSTable) {
 | |
|   useDb("root", "test");
 | |
| 
 | |
|   run("DROP STABLE st1");
 | |
| }
 | |
| 
 | |
| TEST_F(ParserInitialDTest, dropStream) {
 | |
|   useDb("root", "test");
 | |
| 
 | |
|   SMDropStreamReq expect = {0};
 | |
| 
 | |
|   auto clearDropStreamReq = [&]() { memset(&expect, 0, sizeof(SMDropStreamReq)); };
 | |
| 
 | |
|   auto setDropStreamReq = [&](const char* pStream, int8_t igNotExists = 0) {
 | |
|     sprintf(expect.name, "0.%s", pStream);
 | |
|     expect.igNotExists = igNotExists;
 | |
|   };
 | |
| 
 | |
|   setCheckDdlFunc([&](const SQuery* pQuery, ParserStage stage) {
 | |
|     ASSERT_EQ(nodeType(pQuery->pRoot), QUERY_NODE_DROP_STREAM_STMT);
 | |
|     SMDropStreamReq req = {0};
 | |
|     ASSERT_TRUE(TSDB_CODE_SUCCESS == tDeserializeSMDropStreamReq(pQuery->pCmdMsg->pMsg, pQuery->pCmdMsg->msgLen, &req));
 | |
| 
 | |
|     ASSERT_EQ(std::string(req.name), std::string(expect.name));
 | |
|     ASSERT_EQ(req.igNotExists, expect.igNotExists);
 | |
|   });
 | |
| 
 | |
|   setDropStreamReq("s1");
 | |
|   run("DROP STREAM s1");
 | |
|   clearDropStreamReq();
 | |
| 
 | |
|   setDropStreamReq("s2", 1);
 | |
|   run("DROP STREAM IF EXISTS s2");
 | |
|   clearDropStreamReq();
 | |
| }
 | |
| 
 | |
| TEST_F(ParserInitialDTest, dropTable) {
 | |
|   useDb("root", "test");
 | |
| 
 | |
|   run("DROP TABLE t1");
 | |
|   run("DROP TABLE t1, st1s1, st1s2");
 | |
| }
 | |
| 
 | |
| TEST_F(ParserInitialDTest, dropTopic) {
 | |
|   useDb("root", "test");
 | |
| 
 | |
|   run("DROP topic tp1");
 | |
| 
 | |
|   run("DROP topic if exists tp1");
 | |
| }
 | |
| 
 | |
| TEST_F(ParserInitialDTest, dropUser) {
 | |
|   login("root");
 | |
|   useDb("root", "test");
 | |
| 
 | |
|   SDropUserReq expect = {0};
 | |
| 
 | |
|   auto setDropUserReq = [&](const char* pUser) { sprintf(expect.user, "%s", pUser); };
 | |
| 
 | |
|   setCheckDdlFunc([&](const SQuery* pQuery, ParserStage stage) {
 | |
|     ASSERT_EQ(nodeType(pQuery->pRoot), QUERY_NODE_DROP_USER_STMT);
 | |
|     SDropUserReq req = {0};
 | |
|     ASSERT_TRUE(TSDB_CODE_SUCCESS == tDeserializeSDropUserReq(pQuery->pCmdMsg->pMsg, pQuery->pCmdMsg->msgLen, &req));
 | |
| 
 | |
|     ASSERT_EQ(std::string(req.user), std::string(expect.user));
 | |
|   });
 | |
| 
 | |
|   setDropUserReq("wxy");
 | |
|   run("DROP USER wxy");
 | |
| }
 | |
| 
 | |
| TEST_F(ParserInitialDTest, IntervalOnSysTable) {
 | |
|   login("root");
 | |
|   run("SELECT  count('reboot_time') FROM information_schema.ins_dnodes interval(14m) sliding(9m)",
 | |
|       TSDB_CODE_PAR_SYSTABLE_NOT_ALLOWED, PARSER_STAGE_TRANSLATE);
 | |
| 
 | |
|   run("SELECT  count('create_time') FROM information_schema.ins_qnodes interval(14m) sliding(9m)",
 | |
|       TSDB_CODE_PAR_SYSTABLE_NOT_ALLOWED, PARSER_STAGE_TRANSLATE);
 | |
| }
 | |
| 
 | |
| }  // namespace ParserTest
 |