783 lines
21 KiB
C++
783 lines
21 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 <algorithm>
|
|
#include <string>
|
|
|
|
#include <gtest/gtest.h>
|
|
|
|
#include "parInt.h"
|
|
#include "parserTestUtil.h"
|
|
|
|
using namespace std;
|
|
using namespace testing;
|
|
|
|
class ParserTest : public Test {
|
|
protected:
|
|
void setDatabase(const string& acctId, const string& db) {
|
|
acctId_ = acctId;
|
|
db_ = db;
|
|
}
|
|
|
|
void bind(const char* sql) {
|
|
reset();
|
|
cxt_.acctId = atoi(acctId_.c_str());
|
|
cxt_.db = db_.c_str();
|
|
sqlBuf_ = string(sql);
|
|
transform(sqlBuf_.begin(), sqlBuf_.end(), sqlBuf_.begin(), ::tolower);
|
|
cxt_.sqlLen = strlen(sql);
|
|
cxt_.pSql = sqlBuf_.c_str();
|
|
}
|
|
|
|
bool run(int32_t parseCode = TSDB_CODE_SUCCESS, int32_t translateCode = TSDB_CODE_SUCCESS) {
|
|
query_ = nullptr;
|
|
bool res = runImpl(parseCode, translateCode);
|
|
qDestroyQuery(query_);
|
|
if (!res || g_isDump) {
|
|
dump();
|
|
}
|
|
return res;
|
|
}
|
|
|
|
private:
|
|
static const int max_err_len = 1024;
|
|
|
|
bool runImpl(int32_t parseCode, int32_t translateCode) {
|
|
int32_t code = parse(&cxt_, &query_);
|
|
if (code != TSDB_CODE_SUCCESS) {
|
|
parseErrStr_ = string("code:") + tstrerror(code) + string(", msg:") + errMagBuf_;
|
|
return (code == parseCode);
|
|
}
|
|
if (TSDB_CODE_SUCCESS != parseCode) {
|
|
return false;
|
|
}
|
|
parsedAstStr_ = toString(query_->pRoot);
|
|
code = translate(&cxt_, query_);
|
|
if (code != TSDB_CODE_SUCCESS) {
|
|
translateErrStr_ = string("code:") + tstrerror(code) + string(", msg:") + errMagBuf_;
|
|
return (code == translateCode);
|
|
}
|
|
translatedAstStr_ = toString(query_->pRoot);
|
|
code = calculateConstant(&cxt_, query_);
|
|
if (code != TSDB_CODE_SUCCESS) {
|
|
calcConstErrStr_ = string("code:") + tstrerror(code) + string(", msg:") + errMagBuf_;
|
|
return false;
|
|
}
|
|
calcConstAstStr_ = toString(query_->pRoot);
|
|
return (TSDB_CODE_SUCCESS == translateCode);
|
|
}
|
|
|
|
void dump() {
|
|
cout << "input sql : [" << cxt_.pSql << "]" << endl;
|
|
if (!parseErrStr_.empty()) {
|
|
cout << "parse error: " << parseErrStr_ << endl;
|
|
}
|
|
if (!parsedAstStr_.empty()) {
|
|
cout << "parse output: " << endl;
|
|
cout << parsedAstStr_ << endl;
|
|
}
|
|
if (!translateErrStr_.empty()) {
|
|
cout << "translate error: " << translateErrStr_ << endl;
|
|
}
|
|
if (!translatedAstStr_.empty()) {
|
|
cout << "translate output: " << endl;
|
|
cout << translatedAstStr_ << endl;
|
|
}
|
|
if (!calcConstErrStr_.empty()) {
|
|
cout << "calculateConstant error: " << calcConstErrStr_ << endl;
|
|
}
|
|
if (!calcConstAstStr_.empty()) {
|
|
cout << "calculateConstant output: " << endl;
|
|
cout << calcConstAstStr_ << endl;
|
|
}
|
|
}
|
|
|
|
string toString(const SNode* pRoot, bool format = false) {
|
|
char* pStr = NULL;
|
|
int32_t len = 0;
|
|
int32_t code = nodesNodeToString(pRoot, format, &pStr, &len);
|
|
if (code != TSDB_CODE_SUCCESS) {
|
|
cout << "sql:[" << cxt_.pSql << "] toString code:" << code << ", strerror:" << tstrerror(code) << endl;
|
|
throw "nodesNodeToString failed!";
|
|
}
|
|
string str(pStr);
|
|
taosMemoryFreeClear(pStr);
|
|
return str;
|
|
}
|
|
|
|
void reset() {
|
|
memset(&cxt_, 0, sizeof(cxt_));
|
|
memset(errMagBuf_, 0, max_err_len);
|
|
cxt_.pMsg = errMagBuf_;
|
|
cxt_.msgLen = max_err_len;
|
|
parseErrStr_.clear();
|
|
parsedAstStr_.clear();
|
|
translateErrStr_.clear();
|
|
translatedAstStr_.clear();
|
|
calcConstErrStr_.clear();
|
|
calcConstAstStr_.clear();
|
|
}
|
|
|
|
string acctId_;
|
|
string db_;
|
|
char errMagBuf_[max_err_len];
|
|
string sqlBuf_;
|
|
SParseContext cxt_;
|
|
SQuery* query_;
|
|
string parseErrStr_;
|
|
string parsedAstStr_;
|
|
string translateErrStr_;
|
|
string translatedAstStr_;
|
|
string calcConstErrStr_;
|
|
string calcConstAstStr_;
|
|
};
|
|
|
|
TEST_F(ParserTest, createAccount) {
|
|
setDatabase("root", "test");
|
|
|
|
bind("create account ac_wxy pass '123456'");
|
|
ASSERT_TRUE(run(TSDB_CODE_PAR_EXPRIE_STATEMENT));
|
|
}
|
|
|
|
TEST_F(ParserTest, alterAccount) {
|
|
setDatabase("root", "test");
|
|
|
|
bind("alter account ac_wxy pass '123456'");
|
|
ASSERT_TRUE(run(TSDB_CODE_PAR_EXPRIE_STATEMENT));
|
|
}
|
|
|
|
TEST_F(ParserTest, createUser) {
|
|
setDatabase("root", "test");
|
|
|
|
bind("create user wxy pass '123456'");
|
|
ASSERT_TRUE(run());
|
|
}
|
|
|
|
TEST_F(ParserTest, alterUser) {
|
|
setDatabase("root", "test");
|
|
|
|
bind("alter user wxy pass '123456'");
|
|
ASSERT_TRUE(run());
|
|
|
|
bind("alter user wxy privilege 'write'");
|
|
ASSERT_TRUE(run());
|
|
}
|
|
|
|
TEST_F(ParserTest, dropUser) {
|
|
setDatabase("root", "test");
|
|
|
|
bind("drop user wxy");
|
|
ASSERT_TRUE(run());
|
|
}
|
|
|
|
TEST_F(ParserTest, selectSimple) {
|
|
setDatabase("root", "test");
|
|
|
|
bind("SELECT * FROM t1");
|
|
ASSERT_TRUE(run());
|
|
|
|
bind("SELECT * FROM test.t1");
|
|
ASSERT_TRUE(run());
|
|
|
|
bind("SELECT ts, c1 FROM t1");
|
|
ASSERT_TRUE(run());
|
|
|
|
bind("SELECT ts, t.c1 FROM (SELECT * FROM t1) t");
|
|
ASSERT_TRUE(run());
|
|
|
|
bind("SELECT * FROM t1 tt1, t1 tt2 WHERE tt1.c1 = tt2.c1");
|
|
ASSERT_TRUE(run());
|
|
}
|
|
|
|
TEST_F(ParserTest, selectConstant) {
|
|
setDatabase("root", "test");
|
|
|
|
bind("SELECT 123, 20.4, 'abc', \"wxy\", TIMESTAMP '2022-02-09 17:30:20', true, false, 10s FROM t1");
|
|
ASSERT_TRUE(run());
|
|
|
|
bind(
|
|
"SELECT 1234567890123456789012345678901234567890, 20.1234567890123456789012345678901234567890, 'abc', \"wxy\", "
|
|
"TIMESTAMP '2022-02-09 17:30:20', true, false, 15s FROM t1");
|
|
ASSERT_TRUE(run());
|
|
|
|
bind("SELECT 123 + 45 FROM t1 where 2 - 1");
|
|
ASSERT_TRUE(run());
|
|
}
|
|
|
|
TEST_F(ParserTest, selectExpression) {
|
|
setDatabase("root", "test");
|
|
|
|
bind("SELECT ts + 10s, c1 + 10, concat(c2, 'abc') FROM t1");
|
|
ASSERT_TRUE(run());
|
|
|
|
bind("SELECT ts > 0, c1 < 20 AND c2 = 'qaz' FROM t1");
|
|
ASSERT_TRUE(run());
|
|
|
|
bind("SELECT ts > 0, c1 BETWEEN 10 AND 20 AND c2 = 'qaz' FROM t1");
|
|
ASSERT_TRUE(run());
|
|
}
|
|
|
|
TEST_F(ParserTest, selectCondition) {
|
|
setDatabase("root", "test");
|
|
|
|
bind("SELECT c1 FROM t1 where ts in (true, false)");
|
|
ASSERT_TRUE(run());
|
|
|
|
bind("SELECT * FROM t1 where c1 > 10 and c1 is not null");
|
|
ASSERT_TRUE(run());
|
|
}
|
|
|
|
TEST_F(ParserTest, selectPseudoColumn) {
|
|
setDatabase("root", "test");
|
|
|
|
bind("SELECT _wstartts, _wendts, count(*) FROM t1 interval(10s)");
|
|
ASSERT_TRUE(run());
|
|
}
|
|
|
|
TEST_F(ParserTest, selectMultiResFunc) {
|
|
setDatabase("root", "test");
|
|
|
|
// bind("SELECT last(*), first(*), last_row(*) FROM t1");
|
|
// ASSERT_TRUE(run());
|
|
|
|
bind("SELECT last(c1, c2), first(t1.*), last_row(c3) FROM t1");
|
|
ASSERT_TRUE(run());
|
|
|
|
bind("SELECT last(t2.*), first(t1.c1, t2.*), last_row(t1.*, t2.*) FROM st1s1 t1, st1s2 t2 where t1.ts = t2.ts");
|
|
ASSERT_TRUE(run());
|
|
}
|
|
|
|
TEST_F(ParserTest, selectClause) {
|
|
setDatabase("root", "test");
|
|
|
|
// GROUP BY clause
|
|
bind("SELECT count(*) cnt FROM t1 WHERE c1 > 0");
|
|
ASSERT_TRUE(run());
|
|
|
|
bind("SELECT count(*), c2 cnt FROM t1 WHERE c1 > 0 GROUP BY c2");
|
|
ASSERT_TRUE(run());
|
|
|
|
bind("SELECT count(*) cnt FROM t1 WHERE c1 > 0 GROUP BY c2 HAVING count(c1) > 10");
|
|
ASSERT_TRUE(run());
|
|
|
|
bind("SELECT count(*), c1, c2 + 10, c1 + c2 cnt FROM t1 WHERE c1 > 0 GROUP BY c2, c1");
|
|
ASSERT_TRUE(run());
|
|
|
|
bind("SELECT count(*), c1 + 10, c2 cnt FROM t1 WHERE c1 > 0 GROUP BY c1 + 10, c2");
|
|
ASSERT_TRUE(run());
|
|
|
|
// ORDER BY clause
|
|
bind("SELECT count(*) cnt FROM t1 WHERE c1 > 0 GROUP BY c2 ORDER BY cnt");
|
|
ASSERT_TRUE(run());
|
|
|
|
bind("SELECT count(*) cnt FROM t1 WHERE c1 > 0 GROUP BY c2 ORDER BY 1");
|
|
ASSERT_TRUE(run());
|
|
|
|
// DISTINCT clause
|
|
bind("SELECT DISTINCT c1, c2 FROM t1 WHERE c1 > 0 ORDER BY c1");
|
|
ASSERT_TRUE(run());
|
|
|
|
bind("SELECT DISTINCT c1 + 10, c2 FROM t1 WHERE c1 > 0 ORDER BY c1 + 10, c2");
|
|
ASSERT_TRUE(run());
|
|
|
|
bind("SELECT DISTINCT c1 + 10 cc1, c2 cc2 FROM t1 WHERE c1 > 0 ORDER BY cc1, c2");
|
|
ASSERT_TRUE(run());
|
|
|
|
bind("SELECT DISTINCT count(c2) FROM t1 WHERE c1 > 0 GROUP BY c1 ORDER BY count(c2)");
|
|
ASSERT_TRUE(run());
|
|
}
|
|
|
|
TEST_F(ParserTest, selectWindow) {
|
|
setDatabase("root", "test");
|
|
|
|
bind("SELECT count(*) FROM t1 interval(10s)");
|
|
ASSERT_TRUE(run());
|
|
}
|
|
|
|
TEST_F(ParserTest, selectSyntaxError) {
|
|
setDatabase("root", "test");
|
|
|
|
bind("SELECTT * FROM t1");
|
|
ASSERT_TRUE(run(TSDB_CODE_FAILED));
|
|
|
|
bind("SELECT *");
|
|
ASSERT_TRUE(run(TSDB_CODE_FAILED));
|
|
|
|
bind("SELECT *, * FROM test.t1");
|
|
ASSERT_TRUE(run(TSDB_CODE_FAILED));
|
|
|
|
bind("SELECT * FROM test.t1 t WHER");
|
|
ASSERT_TRUE(run(TSDB_CODE_FAILED));
|
|
}
|
|
|
|
TEST_F(ParserTest, selectSemanticError) {
|
|
setDatabase("root", "test");
|
|
|
|
// TSDB_CODE_PAR_INVALID_COLUMN
|
|
bind("SELECT c1, cc1 FROM t1");
|
|
ASSERT_TRUE(run(TSDB_CODE_SUCCESS, TSDB_CODE_PAR_INVALID_COLUMN));
|
|
|
|
bind("SELECT t1.c1, t1.cc1 FROM t1");
|
|
ASSERT_TRUE(run(TSDB_CODE_SUCCESS, TSDB_CODE_PAR_INVALID_COLUMN));
|
|
|
|
// TSDB_CODE_PAR_TABLE_NOT_EXIST
|
|
bind("SELECT * FROM t10");
|
|
ASSERT_TRUE(run(TSDB_CODE_SUCCESS, TSDB_CODE_PAR_TABLE_NOT_EXIST));
|
|
|
|
bind("SELECT * FROM test.t10");
|
|
ASSERT_TRUE(run(TSDB_CODE_SUCCESS, TSDB_CODE_PAR_TABLE_NOT_EXIST));
|
|
|
|
bind("SELECT t2.c1 FROM t1");
|
|
ASSERT_TRUE(run(TSDB_CODE_SUCCESS, TSDB_CODE_PAR_TABLE_NOT_EXIST));
|
|
|
|
// TSDB_CODE_PAR_AMBIGUOUS_COLUMN
|
|
bind("SELECT c2 FROM t1 tt1, t1 tt2 WHERE tt1.c1 = tt2.c1");
|
|
ASSERT_TRUE(run(TSDB_CODE_SUCCESS, TSDB_CODE_PAR_AMBIGUOUS_COLUMN));
|
|
|
|
// TSDB_CODE_PAR_WRONG_VALUE_TYPE
|
|
bind("SELECT 10n FROM t1");
|
|
ASSERT_TRUE(run(TSDB_CODE_SUCCESS, TSDB_CODE_PAR_WRONG_VALUE_TYPE));
|
|
|
|
bind("SELECT TIMESTAMP '2010' FROM t1");
|
|
ASSERT_TRUE(run(TSDB_CODE_SUCCESS, TSDB_CODE_PAR_WRONG_VALUE_TYPE));
|
|
|
|
// TSDB_CODE_PAR_INVALID_FUNTION
|
|
bind("SELECT cnt(*) FROM t1");
|
|
ASSERT_TRUE(run(TSDB_CODE_SUCCESS, TSDB_CODE_FUNC_INVALID_FUNTION));
|
|
|
|
// TSDB_CODE_PAR_FUNTION_PARA_NUM
|
|
// TSDB_CODE_PAR_FUNTION_PARA_TYPE
|
|
|
|
// TSDB_CODE_PAR_ILLEGAL_USE_AGG_FUNCTION
|
|
bind("SELECT c2 FROM t1 tt1 JOIN t1 tt2 ON count(*) > 0");
|
|
ASSERT_TRUE(run(TSDB_CODE_SUCCESS, TSDB_CODE_PAR_ILLEGAL_USE_AGG_FUNCTION));
|
|
|
|
bind("SELECT c2 FROM t1 where count(*) > 0");
|
|
ASSERT_TRUE(run(TSDB_CODE_SUCCESS, TSDB_CODE_PAR_ILLEGAL_USE_AGG_FUNCTION));
|
|
|
|
bind("SELECT c2 FROM t1 GROUP BY count(*)");
|
|
ASSERT_TRUE(run(TSDB_CODE_SUCCESS, TSDB_CODE_PAR_ILLEGAL_USE_AGG_FUNCTION));
|
|
|
|
// TSDB_CODE_PAR_WRONG_NUMBER_OF_SELECT
|
|
bind("SELECT c2 FROM t1 ORDER BY 0");
|
|
ASSERT_TRUE(run(TSDB_CODE_SUCCESS, TSDB_CODE_PAR_WRONG_NUMBER_OF_SELECT));
|
|
|
|
bind("SELECT c2 FROM t1 ORDER BY 2");
|
|
ASSERT_TRUE(run(TSDB_CODE_SUCCESS, TSDB_CODE_PAR_WRONG_NUMBER_OF_SELECT));
|
|
|
|
// TSDB_CODE_PAR_GROUPBY_LACK_EXPRESSION
|
|
bind("SELECT count(*) cnt FROM t1 HAVING c1 > 0");
|
|
ASSERT_TRUE(run(TSDB_CODE_SUCCESS, TSDB_CODE_PAR_GROUPBY_LACK_EXPRESSION));
|
|
|
|
bind("SELECT count(*) cnt FROM t1 GROUP BY c2 HAVING c1 > 0");
|
|
ASSERT_TRUE(run(TSDB_CODE_SUCCESS, TSDB_CODE_PAR_GROUPBY_LACK_EXPRESSION));
|
|
|
|
bind("SELECT count(*), c1 cnt FROM t1 GROUP BY c2 HAVING c2 > 0");
|
|
ASSERT_TRUE(run(TSDB_CODE_SUCCESS, TSDB_CODE_PAR_GROUPBY_LACK_EXPRESSION));
|
|
|
|
bind("SELECT count(*) cnt FROM t1 GROUP BY c2 HAVING c2 > 0 ORDER BY c1");
|
|
ASSERT_TRUE(run(TSDB_CODE_SUCCESS, TSDB_CODE_PAR_GROUPBY_LACK_EXPRESSION));
|
|
|
|
// TSDB_CODE_PAR_NOT_SINGLE_GROUP
|
|
bind("SELECT count(*), c1 FROM t1");
|
|
ASSERT_TRUE(run(TSDB_CODE_SUCCESS, TSDB_CODE_PAR_NOT_SINGLE_GROUP));
|
|
|
|
bind("SELECT count(*) FROM t1 ORDER BY c1");
|
|
ASSERT_TRUE(run(TSDB_CODE_SUCCESS, TSDB_CODE_PAR_NOT_SINGLE_GROUP));
|
|
|
|
bind("SELECT c1 FROM t1 ORDER BY count(*)");
|
|
ASSERT_TRUE(run(TSDB_CODE_SUCCESS, TSDB_CODE_PAR_NOT_SINGLE_GROUP));
|
|
|
|
// TSDB_CODE_PAR_NOT_SELECTED_EXPRESSION
|
|
bind("SELECT DISTINCT c1, c2 FROM t1 WHERE c1 > 0 ORDER BY ts");
|
|
ASSERT_TRUE(run(TSDB_CODE_SUCCESS, TSDB_CODE_PAR_NOT_SELECTED_EXPRESSION));
|
|
|
|
bind("SELECT DISTINCT c1 FROM t1 WHERE c1 > 0 ORDER BY count(c2)");
|
|
ASSERT_TRUE(run(TSDB_CODE_SUCCESS, TSDB_CODE_PAR_NOT_SELECTED_EXPRESSION));
|
|
|
|
bind("SELECT DISTINCT c2 FROM t1 WHERE c1 > 0 ORDER BY count(c2)");
|
|
ASSERT_TRUE(run(TSDB_CODE_SUCCESS, TSDB_CODE_PAR_NOT_SELECTED_EXPRESSION));
|
|
}
|
|
|
|
TEST_F(ParserTest, showUsers) {
|
|
setDatabase("root", "test");
|
|
|
|
bind("show users");
|
|
ASSERT_TRUE(run());
|
|
}
|
|
|
|
TEST_F(ParserTest, createDnode) {
|
|
setDatabase("root", "test");
|
|
|
|
bind("create dnode abc1 port 7000");
|
|
ASSERT_TRUE(run());
|
|
|
|
bind("create dnode 1.1.1.1 port 9000");
|
|
ASSERT_TRUE(run());
|
|
}
|
|
|
|
TEST_F(ParserTest, showDnodes) {
|
|
setDatabase("root", "test");
|
|
|
|
bind("show dnodes");
|
|
ASSERT_TRUE(run());
|
|
}
|
|
|
|
TEST_F(ParserTest, alterDnode) {
|
|
setDatabase("root", "test");
|
|
|
|
bind("alter dnode 1 'resetLog'");
|
|
ASSERT_TRUE(run());
|
|
|
|
bind("alter dnode 1 'debugFlag' '134'");
|
|
ASSERT_TRUE(run());
|
|
}
|
|
|
|
TEST_F(ParserTest, createDatabase) {
|
|
setDatabase("root", "test");
|
|
|
|
bind("create database wxy_db");
|
|
ASSERT_TRUE(run());
|
|
|
|
bind(
|
|
"create database if not exists wxy_db "
|
|
"BLOCKS 100 "
|
|
"CACHE 100 "
|
|
"CACHELAST 2 "
|
|
"COMP 1 "
|
|
"DAYS 100 "
|
|
"FSYNC 100 "
|
|
"MAXROWS 1000 "
|
|
"MINROWS 100 "
|
|
"KEEP 100 "
|
|
"PRECISION 'ms' "
|
|
"QUORUM 1 "
|
|
"REPLICA 3 "
|
|
"TTL 100 "
|
|
"WAL 2 "
|
|
"VGROUPS 100 "
|
|
"SINGLE_STABLE 0 "
|
|
"STREAM_MODE 1 "
|
|
"RETENTIONS '15s:7d,1m:21d,15m:5y'");
|
|
ASSERT_TRUE(run());
|
|
|
|
bind(
|
|
"create database if not exists wxy_db "
|
|
"DAYS 100m "
|
|
"KEEP 200m,300h,400d ");
|
|
ASSERT_TRUE(run());
|
|
}
|
|
|
|
TEST_F(ParserTest, alterDatabase) {
|
|
setDatabase("root", "test");
|
|
|
|
bind("alter database wxy_db BLOCKS 200");
|
|
ASSERT_TRUE(run());
|
|
|
|
bind(
|
|
"alter database wxy_db "
|
|
"BLOCKS 200 "
|
|
"CACHELAST 1 "
|
|
"FSYNC 200 "
|
|
"KEEP 200 "
|
|
"QUORUM 2 "
|
|
"WAL 1 ");
|
|
ASSERT_TRUE(run());
|
|
}
|
|
|
|
TEST_F(ParserTest, showDatabase) {
|
|
setDatabase("root", "test");
|
|
|
|
bind("show databases");
|
|
ASSERT_TRUE(run());
|
|
}
|
|
|
|
TEST_F(ParserTest, useDatabase) {
|
|
setDatabase("root", "test");
|
|
|
|
bind("use wxy_db");
|
|
ASSERT_TRUE(run());
|
|
}
|
|
|
|
TEST_F(ParserTest, createTable) {
|
|
setDatabase("root", "test");
|
|
|
|
bind("create table t1(ts timestamp, c1 int)");
|
|
ASSERT_TRUE(run());
|
|
|
|
bind(
|
|
"create table if not exists test.t1("
|
|
"ts TIMESTAMP, c1 INT, c2 INT UNSIGNED, c3 BIGINT, c4 BIGINT UNSIGNED, c5 FLOAT, c6 DOUBLE, c7 BINARY(20), c8 "
|
|
"SMALLINT, "
|
|
"c9 SMALLINT UNSIGNED COMMENT 'test column comment', c10 TINYINT, c11 TINYINT UNSIGNED, c12 BOOL, c13 NCHAR(30), "
|
|
"c14 JSON, c15 VARCHAR(50)) "
|
|
"KEEP 100 TTL 100 COMMENT 'test create table' SMA(c1, c2, c3)");
|
|
ASSERT_TRUE(run());
|
|
|
|
bind(
|
|
"create table if not exists test.t1("
|
|
"ts TIMESTAMP, c1 INT, c2 INT UNSIGNED, c3 BIGINT, c4 BIGINT UNSIGNED, c5 FLOAT, c6 DOUBLE, c7 BINARY(20), c8 "
|
|
"SMALLINT, "
|
|
"c9 SMALLINT UNSIGNED COMMENT 'test column comment', c10 TINYINT, c11 TINYINT UNSIGNED, c12 BOOL, c13 NCHAR(30), "
|
|
"c14 JSON, c15 VARCHAR(50)) "
|
|
"TAGS (tsa TIMESTAMP, a1 INT, a2 INT UNSIGNED, a3 BIGINT, a4 BIGINT UNSIGNED, a5 FLOAT, a6 DOUBLE, a7 "
|
|
"BINARY(20), a8 SMALLINT, "
|
|
"a9 SMALLINT UNSIGNED COMMENT 'test column comment', a10 TINYINT, a11 TINYINT UNSIGNED, a12 BOOL, a13 NCHAR(30), "
|
|
"a14 JSON, a15 VARCHAR(50)) "
|
|
"KEEP 100 TTL 100 COMMENT 'test create table' SMA(c1, c2, c3) ROLLUP (min) FILE_FACTOR 0.1 DELAY 2");
|
|
ASSERT_TRUE(run());
|
|
|
|
bind("create table if not exists t1 using st1 tags(1, 'wxy')");
|
|
ASSERT_TRUE(run());
|
|
|
|
bind(
|
|
"create table "
|
|
"if not exists test.t1 using test.st1 (tag1, tag2) tags(1, 'abc') "
|
|
"if not exists test.t2 using test.st1 (tag1, tag2) tags(2, 'abc') "
|
|
"if not exists test.t3 using test.st1 (tag1, tag2) tags(3, 'abc') "
|
|
"if not exists test.t4 using test.st1 (tag1, tag2) tags(3, null) "
|
|
"if not exists test.t5 using test.st1 (tag1, tag2) tags(null, 'abc') "
|
|
"if not exists test.t6 using test.st1 (tag1, tag2) tags(null, null)");
|
|
ASSERT_TRUE(run());
|
|
|
|
bind("create stable t1(ts timestamp, c1 int) TAGS(id int)");
|
|
ASSERT_TRUE(run());
|
|
|
|
bind(
|
|
"create stable if not exists test.t1("
|
|
"ts TIMESTAMP, c1 INT, c2 INT UNSIGNED, c3 BIGINT, c4 BIGINT UNSIGNED, c5 FLOAT, c6 DOUBLE, c7 BINARY(20), c8 "
|
|
"SMALLINT, "
|
|
"c9 SMALLINT UNSIGNED COMMENT 'test column comment', c10 TINYINT, c11 TINYINT UNSIGNED, c12 BOOL, c13 NCHAR(30), "
|
|
"c14 JSON, c15 VARCHAR(50)) "
|
|
"TAGS (tsa TIMESTAMP, a1 INT, a2 INT UNSIGNED, a3 BIGINT, a4 BIGINT UNSIGNED, a5 FLOAT, a6 DOUBLE, a7 "
|
|
"BINARY(20), a8 SMALLINT, "
|
|
"a9 SMALLINT UNSIGNED COMMENT 'test column comment', a10 TINYINT, a11 TINYINT UNSIGNED, a12 BOOL, a13 NCHAR(30), "
|
|
"a14 JSON, a15 VARCHAR(50)) "
|
|
"KEEP 100 TTL 100 COMMENT 'test create table' SMA(c1, c2, c3) ROLLUP (min) FILE_FACTOR 0.1 DELAY 2");
|
|
ASSERT_TRUE(run());
|
|
}
|
|
|
|
TEST_F(ParserTest, showTables) {
|
|
setDatabase("root", "test");
|
|
|
|
bind("show tables");
|
|
ASSERT_TRUE(run());
|
|
|
|
bind("show test.tables");
|
|
ASSERT_TRUE(run());
|
|
|
|
bind("show tables like 'c%'");
|
|
ASSERT_TRUE(run());
|
|
|
|
bind("show test.tables like 'c%'");
|
|
ASSERT_TRUE(run());
|
|
}
|
|
|
|
TEST_F(ParserTest, showStables) {
|
|
setDatabase("root", "test");
|
|
|
|
bind("show stables");
|
|
ASSERT_TRUE(run());
|
|
|
|
bind("show test.stables");
|
|
ASSERT_TRUE(run());
|
|
|
|
bind("show stables like 'c%'");
|
|
ASSERT_TRUE(run());
|
|
|
|
bind("show test.stables like 'c%'");
|
|
ASSERT_TRUE(run());
|
|
}
|
|
|
|
TEST_F(ParserTest, showVgroups) {
|
|
setDatabase("root", "test");
|
|
|
|
bind("show vgroups");
|
|
ASSERT_TRUE(run());
|
|
|
|
bind("show test.vgroups");
|
|
ASSERT_TRUE(run());
|
|
}
|
|
|
|
TEST_F(ParserTest, showMnodes) {
|
|
setDatabase("root", "test");
|
|
|
|
bind("show mnodes");
|
|
ASSERT_TRUE(run());
|
|
}
|
|
|
|
TEST_F(ParserTest, showModules) {
|
|
setDatabase("root", "test");
|
|
|
|
bind("show modules");
|
|
ASSERT_TRUE(run());
|
|
}
|
|
|
|
TEST_F(ParserTest, showQnodes) {
|
|
setDatabase("root", "test");
|
|
|
|
bind("show qnodes");
|
|
ASSERT_TRUE(run());
|
|
}
|
|
|
|
TEST_F(ParserTest, showFunctions) {
|
|
setDatabase("root", "test");
|
|
|
|
bind("show functions");
|
|
ASSERT_TRUE(run());
|
|
}
|
|
|
|
TEST_F(ParserTest, showIndexes) {
|
|
setDatabase("root", "test");
|
|
|
|
bind("show indexes from t1");
|
|
ASSERT_TRUE(run());
|
|
|
|
bind("show indexes from t1 from test");
|
|
ASSERT_TRUE(run());
|
|
}
|
|
|
|
TEST_F(ParserTest, showStreams) {
|
|
setDatabase("root", "test");
|
|
|
|
bind("show streams");
|
|
ASSERT_TRUE(run());
|
|
}
|
|
|
|
TEST_F(ParserTest, createSmaIndex) {
|
|
setDatabase("root", "test");
|
|
|
|
bind("create sma index index1 on t1 function(max(c1), min(c3 + 10), sum(c4)) INTERVAL(10s)");
|
|
ASSERT_TRUE(run());
|
|
}
|
|
|
|
TEST_F(ParserTest, dropIndex) {
|
|
setDatabase("root", "test");
|
|
|
|
bind("drop index index1 on t1");
|
|
ASSERT_TRUE(run());
|
|
}
|
|
|
|
TEST_F(ParserTest, createQnode) {
|
|
setDatabase("root", "test");
|
|
|
|
bind("create qnode on dnode 1");
|
|
ASSERT_TRUE(run());
|
|
}
|
|
|
|
TEST_F(ParserTest, dropQnode) {
|
|
setDatabase("root", "test");
|
|
|
|
bind("drop qnode on dnode 1");
|
|
ASSERT_TRUE(run());
|
|
}
|
|
|
|
TEST_F(ParserTest, createBnode) {
|
|
setDatabase("root", "test");
|
|
|
|
bind("create bnode on dnode 1");
|
|
ASSERT_TRUE(run());
|
|
}
|
|
|
|
TEST_F(ParserTest, dropBnode) {
|
|
setDatabase("root", "test");
|
|
|
|
bind("drop bnode on dnode 1");
|
|
ASSERT_TRUE(run());
|
|
}
|
|
|
|
TEST_F(ParserTest, createSnode) {
|
|
setDatabase("root", "test");
|
|
|
|
bind("create snode on dnode 1");
|
|
ASSERT_TRUE(run());
|
|
}
|
|
|
|
TEST_F(ParserTest, dropSnode) {
|
|
setDatabase("root", "test");
|
|
|
|
bind("drop snode on dnode 1");
|
|
ASSERT_TRUE(run());
|
|
}
|
|
|
|
TEST_F(ParserTest, createMnode) {
|
|
setDatabase("root", "test");
|
|
|
|
bind("create mnode on dnode 1");
|
|
ASSERT_TRUE(run());
|
|
}
|
|
|
|
TEST_F(ParserTest, dropMnode) {
|
|
setDatabase("root", "test");
|
|
|
|
bind("drop mnode on dnode 1");
|
|
ASSERT_TRUE(run());
|
|
}
|
|
|
|
TEST_F(ParserTest, createTopic) {
|
|
setDatabase("root", "test");
|
|
|
|
bind("create topic tp1 as select * from t1");
|
|
ASSERT_TRUE(run());
|
|
|
|
bind("create topic if not exists tp1 as select * from t1");
|
|
ASSERT_TRUE(run());
|
|
|
|
bind("create topic tp1 as test");
|
|
ASSERT_TRUE(run());
|
|
|
|
bind("create topic if not exists tp1 as test");
|
|
ASSERT_TRUE(run());
|
|
}
|
|
|
|
TEST_F(ParserTest, dropTopic) {
|
|
setDatabase("root", "test");
|
|
|
|
bind("drop topic tp1");
|
|
ASSERT_TRUE(run());
|
|
|
|
bind("drop topic if exists tp1");
|
|
ASSERT_TRUE(run());
|
|
}
|
|
|
|
TEST_F(ParserTest, createStream) {
|
|
setDatabase("root", "test");
|
|
|
|
bind("create stream s1 as select * from t1");
|
|
ASSERT_TRUE(run());
|
|
|
|
bind("create stream if not exists s1 as select * from t1");
|
|
ASSERT_TRUE(run());
|
|
|
|
bind("create stream s1 into st1 as select * from t1");
|
|
ASSERT_TRUE(run());
|
|
|
|
bind("create stream if not exists s1 trigger window_close watermark 10s into st1 as select * from t1");
|
|
ASSERT_TRUE(run());
|
|
}
|
|
|
|
TEST_F(ParserTest, explain) {
|
|
setDatabase("root", "test");
|
|
|
|
bind("explain SELECT * FROM t1");
|
|
ASSERT_TRUE(run());
|
|
|
|
bind("explain analyze SELECT * FROM t1");
|
|
ASSERT_TRUE(run());
|
|
|
|
bind("explain analyze verbose true ratio 0.01 SELECT * FROM t1");
|
|
ASSERT_TRUE(run());
|
|
}
|