merge feat/vnode_compact
This commit is contained in:
commit
f85389d2af
|
@ -2,7 +2,7 @@
|
|||
# taosadapter
|
||||
ExternalProject_Add(taosadapter
|
||||
GIT_REPOSITORY https://github.com/taosdata/taosadapter.git
|
||||
GIT_TAG f0c1753
|
||||
GIT_TAG 5662a6d
|
||||
SOURCE_DIR "${TD_SOURCE_DIR}/tools/taosadapter"
|
||||
BINARY_DIR ""
|
||||
#BUILD_IN_SOURCE TRUE
|
||||
|
|
|
@ -30,6 +30,8 @@ database_option: {
|
|||
| WAL_LEVEL {1 | 2}
|
||||
| VGROUPS value
|
||||
| SINGLE_STABLE {0 | 1}
|
||||
| TABLE_PREFIX value
|
||||
| TABLE_SUFFIX value
|
||||
| WAL_RETENTION_PERIOD value
|
||||
| WAL_ROLL_PERIOD value
|
||||
| WAL_RETENTION_SIZE value
|
||||
|
@ -67,6 +69,8 @@ database_option: {
|
|||
- SINGLE_STABLE: specifies whether the database can contain more than one supertable.
|
||||
- 0: The database can contain multiple supertables.
|
||||
- 1: The database can contain only one supertable.
|
||||
- TABLE_PREFIX:The prefix length in the table name that is ignored when distributing table to vnode based on table name.
|
||||
- TABLE_SUFFIX:The suffix length in the table name that is ignored when distributing table to vnode based on table name.
|
||||
- WAL_RETENTION_PERIOD: specifies the time after which WAL files are deleted. This parameter is used for data subscription. Enter a time in seconds. The default value of single copy is 0. A value of 0 indicates that each WAL file is deleted immediately after its contents are written to disk. -1: WAL files are never deleted. The default value of multiple copy is 4 days.
|
||||
- WAL_RETENTION_SIZE: specifies the size at which WAL files are deleted. This parameter is used for data subscription. Enter a size in KB. The default value of single copy is 0. A value of 0 indicates that each WAL file is deleted immediately after its contents are written to disk. -1: WAL files are never deleted. The default value of multiple copy is -1.
|
||||
- WAL_ROLL_PERIOD: specifies the time after which WAL files are rotated. After this period elapses, a new WAL file is created. The default value of single copy is 0. A value of 0 indicates that a new WAL file is created only after the previous WAL file was written to disk. The default values of multiple copy is 1 day.
|
||||
|
|
|
@ -30,6 +30,8 @@ database_option: {
|
|||
| WAL_LEVEL {1 | 2}
|
||||
| VGROUPS value
|
||||
| SINGLE_STABLE {0 | 1}
|
||||
| TABLE_PREFIX value
|
||||
| TABLE_SUFFIX value
|
||||
| WAL_RETENTION_PERIOD value
|
||||
| WAL_ROLL_PERIOD value
|
||||
| WAL_RETENTION_SIZE value
|
||||
|
@ -67,6 +69,8 @@ database_option: {
|
|||
- SINGLE_STABLE:表示此数据库中是否只可以创建一个超级表,用于超级表列非常多的情况。
|
||||
- 0:表示可以创建多张超级表。
|
||||
- 1:表示只可以创建一张超级表。
|
||||
- TABLE_PREFIX:内部存储引擎根据表名分配存储该表数据的 VNODE 时要忽略的前缀的长度。
|
||||
- TABLE_SUFFIX:内部存储引擎根据表名分配存储该表数据的 VNODE 时要忽略的后缀的长度。
|
||||
- WAL_RETENTION_PERIOD:wal 文件的额外保留策略,用于数据订阅。wal 的保存时长,单位为 s。单副本默认为 0,即落盘后立即删除。-1 表示不删除。多副本默认为 4 天。
|
||||
- WAL_RETENTION_SIZE:wal 文件的额外保留策略,用于数据订阅。wal 的保存的最大上限,单位为 KB。单副本默认为 0,即落盘后立即删除。多副本默认为-1,表示不删除。
|
||||
- WAL_ROLL_PERIOD:wal 文件切换时长,单位为 s。当 wal 文件创建并写入后,经过该时间,会自动创建一个新的 wal 文件。单副本默认为 0,即仅在落盘时创建新文件。多副本默认为 1 天。
|
||||
|
|
|
@ -213,6 +213,7 @@ int32_t qStreamSourceRecoverStep1(qTaskInfo_t tinfo, int64_t ver);
|
|||
int32_t qStreamSourceRecoverStep2(qTaskInfo_t tinfo, int64_t ver);
|
||||
int32_t qStreamRecoverFinish(qTaskInfo_t tinfo);
|
||||
int32_t qStreamRestoreParam(qTaskInfo_t tinfo);
|
||||
bool qStreamRecoverScanFinished(qTaskInfo_t tinfo);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -19,7 +19,7 @@ void metaReaderInit(SMetaReader *pReader, SMeta *pMeta, int32_t flags) {
|
|||
memset(pReader, 0, sizeof(*pReader));
|
||||
pReader->flags = flags;
|
||||
pReader->pMeta = pMeta;
|
||||
if (!(flags & META_READER_NOLOCK)) {
|
||||
if (pReader->pMeta && !(flags & META_READER_NOLOCK)) {
|
||||
metaRLock(pMeta);
|
||||
}
|
||||
}
|
||||
|
@ -152,7 +152,7 @@ bool metaIsTableExist(SMeta *pMeta, tb_uid_t uid) {
|
|||
}
|
||||
|
||||
int metaGetTableEntryByUid(SMetaReader *pReader, tb_uid_t uid) {
|
||||
SMeta *pMeta = pReader->pMeta;
|
||||
SMeta *pMeta = pReader->pMeta;
|
||||
int64_t version1;
|
||||
|
||||
// query uid.idx
|
||||
|
@ -239,7 +239,6 @@ int metaGetTableSzNameByUid(void *meta, uint64_t uid, char *tbName) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int metaGetTableUidByName(void *meta, char *tbName, uint64_t *uid) {
|
||||
int code = 0;
|
||||
SMetaReader mr = {0};
|
||||
|
@ -756,9 +755,7 @@ int64_t metaGetTimeSeriesNum(SMeta *pMeta) {
|
|||
return pMeta->pVnode->config.vndStats.numOfTimeSeries + pMeta->pVnode->config.vndStats.numOfNTimeSeries;
|
||||
}
|
||||
|
||||
int64_t metaGetNtbNum(SMeta *pMeta) {
|
||||
return pMeta->pVnode->config.vndStats.numOfNTables;
|
||||
}
|
||||
int64_t metaGetNtbNum(SMeta *pMeta) { return pMeta->pVnode->config.vndStats.numOfNTables; }
|
||||
|
||||
typedef struct {
|
||||
SMeta *pMeta;
|
||||
|
|
|
@ -136,6 +136,7 @@ typedef struct {
|
|||
SSchemaWrapper* schema;
|
||||
char tbName[TSDB_TABLE_NAME_LEN];
|
||||
int8_t recoverStep;
|
||||
int8_t recoverScanFinished;
|
||||
SQueryTableDataCond tableCond;
|
||||
int64_t fillHistoryVer1;
|
||||
int64_t fillHistoryVer2;
|
||||
|
@ -182,7 +183,7 @@ struct SExecTaskInfo {
|
|||
SSubplan* pSubplan;
|
||||
struct SOperatorInfo* pRoot;
|
||||
SLocalFetch localFetch;
|
||||
SArray* pResultBlockList;// result block list
|
||||
SArray* pResultBlockList; // result block list
|
||||
STaskStopInfo stopInfo;
|
||||
};
|
||||
|
||||
|
@ -199,7 +200,7 @@ typedef struct SOperatorFpSet {
|
|||
__optr_fn_t getNextFn;
|
||||
__optr_fn_t cleanupFn; // call this function to release the allocated resources ASAP
|
||||
__optr_close_fn_t closeFn;
|
||||
__optr_reqBuf_fn_t reqBufFn; // total used buffer for blocking operator
|
||||
__optr_reqBuf_fn_t reqBufFn; // total used buffer for blocking operator
|
||||
__optr_encode_fn_t encodeResultRow;
|
||||
__optr_decode_fn_t decodeResultRow;
|
||||
__optr_explain_fn_t getExplainFn;
|
||||
|
@ -255,22 +256,22 @@ typedef struct SLimitInfo {
|
|||
} SLimitInfo;
|
||||
|
||||
typedef struct SExchangeInfo {
|
||||
SArray* pSources;
|
||||
SArray* pSourceDataInfo;
|
||||
tsem_t ready;
|
||||
void* pTransporter;
|
||||
SArray* pSources;
|
||||
SArray* pSourceDataInfo;
|
||||
tsem_t ready;
|
||||
void* pTransporter;
|
||||
|
||||
// SArray<SSDataBlock*>, result block list, used to keep the multi-block that
|
||||
// passed by downstream operator
|
||||
SArray* pResultBlockList;
|
||||
SArray* pRecycledBlocks;// build a pool for small data block to avoid to repeatly create and then destroy.
|
||||
SSDataBlock* pDummyBlock; // dummy block, not keep data
|
||||
bool seqLoadData; // sequential load data or not, false by default
|
||||
int32_t current;
|
||||
SArray* pResultBlockList;
|
||||
SArray* pRecycledBlocks; // build a pool for small data block to avoid to repeatly create and then destroy.
|
||||
SSDataBlock* pDummyBlock; // dummy block, not keep data
|
||||
bool seqLoadData; // sequential load data or not, false by default
|
||||
int32_t current;
|
||||
SLoadRemoteDataInfo loadInfo;
|
||||
uint64_t self;
|
||||
SLimitInfo limitInfo;
|
||||
int64_t openedTs; // start exec time stamp, todo: move to SLoadRemoteDataInfo
|
||||
int64_t openedTs; // start exec time stamp, todo: move to SLoadRemoteDataInfo
|
||||
} SExchangeInfo;
|
||||
|
||||
typedef struct SScanInfo {
|
||||
|
@ -305,9 +306,9 @@ typedef struct {
|
|||
} SAggOptrPushDownInfo;
|
||||
|
||||
typedef struct STableMetaCacheInfo {
|
||||
SLRUCache* pTableMetaEntryCache; // 100 by default
|
||||
uint64_t metaFetch;
|
||||
uint64_t cacheHit;
|
||||
SLRUCache* pTableMetaEntryCache; // 100 by default
|
||||
uint64_t metaFetch;
|
||||
uint64_t cacheHit;
|
||||
} STableMetaCacheInfo;
|
||||
|
||||
typedef struct STableScanBase {
|
||||
|
@ -325,16 +326,16 @@ typedef struct STableScanBase {
|
|||
} STableScanBase;
|
||||
|
||||
typedef struct STableScanInfo {
|
||||
STableScanBase base;
|
||||
SScanInfo scanInfo;
|
||||
int32_t scanTimes;
|
||||
SSDataBlock* pResBlock;
|
||||
SSampleExecInfo sample; // sample execution info
|
||||
int32_t currentGroupId;
|
||||
int32_t currentTable;
|
||||
int8_t scanMode;
|
||||
int8_t assignBlockUid;
|
||||
bool hasGroupByTag;
|
||||
STableScanBase base;
|
||||
SScanInfo scanInfo;
|
||||
int32_t scanTimes;
|
||||
SSDataBlock* pResBlock;
|
||||
SSampleExecInfo sample; // sample execution info
|
||||
int32_t currentGroupId;
|
||||
int32_t currentTable;
|
||||
int8_t scanMode;
|
||||
int8_t assignBlockUid;
|
||||
bool hasGroupByTag;
|
||||
} STableScanInfo;
|
||||
|
||||
typedef struct STableMergeScanInfo {
|
||||
|
@ -360,11 +361,11 @@ typedef struct STableMergeScanInfo {
|
|||
} STableMergeScanInfo;
|
||||
|
||||
typedef struct STagScanInfo {
|
||||
SColumnInfo* pCols;
|
||||
SSDataBlock* pRes;
|
||||
SColMatchInfo matchInfo;
|
||||
int32_t curPos;
|
||||
SReadHandle readHandle;
|
||||
SColumnInfo* pCols;
|
||||
SSDataBlock* pRes;
|
||||
SColMatchInfo matchInfo;
|
||||
int32_t curPos;
|
||||
SReadHandle readHandle;
|
||||
} STagScanInfo;
|
||||
|
||||
typedef enum EStreamScanMode {
|
||||
|
@ -468,6 +469,11 @@ typedef struct SStreamScanInfo {
|
|||
SNodeList* pGroupTags;
|
||||
SNode* pTagCond;
|
||||
SNode* pTagIndexCond;
|
||||
|
||||
// recover
|
||||
int32_t blockRecoverContiCnt;
|
||||
int32_t blockRecoverTotCnt;
|
||||
|
||||
} SStreamScanInfo;
|
||||
|
||||
typedef struct {
|
||||
|
@ -499,8 +505,8 @@ typedef struct STableCountScanOperatorInfo {
|
|||
|
||||
STableCountScanSupp supp;
|
||||
|
||||
int32_t currGrpIdx;
|
||||
SArray* stbUidList; // when group by db_name and/or stable_name
|
||||
int32_t currGrpIdx;
|
||||
SArray* stbUidList; // when group by db_name and/or stable_name
|
||||
} STableCountScanOperatorInfo;
|
||||
|
||||
typedef struct SOptrBasicInfo {
|
||||
|
@ -678,19 +684,19 @@ void setOperatorInfo(SOperatorInfo* pOperator, const char* name, int32
|
|||
void destroyOperatorInfo(SOperatorInfo* pOperator);
|
||||
int32_t optrDefaultBufFn(SOperatorInfo* pOperator);
|
||||
|
||||
void initBasicInfo(SOptrBasicInfo* pInfo, SSDataBlock* pBlock);
|
||||
void cleanupBasicInfo(SOptrBasicInfo* pInfo);
|
||||
void initBasicInfo(SOptrBasicInfo* pInfo, SSDataBlock* pBlock);
|
||||
void cleanupBasicInfo(SOptrBasicInfo* pInfo);
|
||||
|
||||
int32_t initExprSupp(SExprSupp* pSup, SExprInfo* pExprInfo, int32_t numOfExpr);
|
||||
void cleanupExprSupp(SExprSupp* pSup);
|
||||
|
||||
void destroyExprInfo(SExprInfo* pExpr, int32_t numOfExprs);
|
||||
void destroyExprInfo(SExprInfo* pExpr, int32_t numOfExprs);
|
||||
|
||||
int32_t initAggSup(SExprSupp* pSup, SAggSupporter* pAggSup, SExprInfo* pExprInfo, int32_t numOfCols, size_t keyBufSize,
|
||||
const char* pkey);
|
||||
void cleanupAggSup(SAggSupporter* pAggSup);
|
||||
|
||||
void initResultSizeInfo(SResultInfo* pResultInfo, int32_t numOfRows);
|
||||
void initResultSizeInfo(SResultInfo* pResultInfo, int32_t numOfRows);
|
||||
|
||||
void doBuildStreamResBlock(SOperatorInfo* pOperator, SOptrBasicInfo* pbInfo, SGroupResInfo* pGroupResInfo,
|
||||
SDiskbasedBuf* pBuf);
|
||||
|
@ -803,10 +809,10 @@ void setInputDataBlock(SExprSupp* pExprSupp, SSDataBlock* pBlock, int32_t order,
|
|||
|
||||
int32_t checkForQueryBuf(size_t numOfTables);
|
||||
|
||||
bool isTaskKilled(SExecTaskInfo* pTaskInfo);
|
||||
void setTaskKilled(SExecTaskInfo* pTaskInfo, int32_t rspCode);
|
||||
void doDestroyTask(SExecTaskInfo* pTaskInfo);
|
||||
void setTaskStatus(SExecTaskInfo* pTaskInfo, int8_t status);
|
||||
bool isTaskKilled(SExecTaskInfo* pTaskInfo);
|
||||
void setTaskKilled(SExecTaskInfo* pTaskInfo, int32_t rspCode);
|
||||
void doDestroyTask(SExecTaskInfo* pTaskInfo);
|
||||
void setTaskStatus(SExecTaskInfo* pTaskInfo, int8_t status);
|
||||
|
||||
int32_t createExecTaskInfoImpl(SSubplan* pPlan, SExecTaskInfo** pTaskInfo, SReadHandle* pHandle, uint64_t taskId,
|
||||
char* sql, EOPTR_EXEC_MODEL model);
|
||||
|
@ -828,8 +834,8 @@ bool isDeletedWindow(STimeWindow* pWin, uint64_t groupId, SAggSupporter* pSup);
|
|||
bool isDeletedStreamWindow(STimeWindow* pWin, uint64_t groupId, SStreamState* pState, STimeWindowAggSupp* pTwSup);
|
||||
void appendOneRowToStreamSpecialBlock(SSDataBlock* pBlock, TSKEY* pStartTs, TSKEY* pEndTs, uint64_t* pUid,
|
||||
uint64_t* pGp, void* pTbName);
|
||||
uint64_t calGroupIdByData(SPartitionBySupporter* pParSup, SExprSupp* pExprSup, SSDataBlock* pBlock, int32_t rowId);
|
||||
void calBlockTbName(SStreamScanInfo* pInfo, SSDataBlock* pBlock);
|
||||
uint64_t calGroupIdByData(SPartitionBySupporter* pParSup, SExprSupp* pExprSup, SSDataBlock* pBlock, int32_t rowId);
|
||||
void calBlockTbName(SStreamScanInfo* pInfo, SSDataBlock* pBlock);
|
||||
|
||||
int32_t finalizeResultRows(SDiskbasedBuf* pBuf, SResultRowPosition* resultRowPosition, SExprSupp* pSup,
|
||||
SSDataBlock* pBlock, SExecTaskInfo* pTaskInfo);
|
||||
|
|
|
@ -937,6 +937,11 @@ int32_t qStreamRestoreParam(qTaskInfo_t tinfo) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
bool qStreamRecoverScanFinished(qTaskInfo_t tinfo) {
|
||||
SExecTaskInfo* pTaskInfo = (SExecTaskInfo*)tinfo;
|
||||
return pTaskInfo->streamInfo.recoverScanFinished;
|
||||
}
|
||||
|
||||
void* qExtractReaderFromStreamScanner(void* scanner) {
|
||||
SStreamScanInfo* pInfo = scanner;
|
||||
return (void*)pInfo->tqReader;
|
||||
|
|
|
@ -1785,11 +1785,18 @@ static SSDataBlock* doStreamScan(SOperatorInfo* pOperator) {
|
|||
pTSInfo->scanTimes = 0;
|
||||
pTSInfo->currentGroupId = -1;
|
||||
pTaskInfo->streamInfo.recoverStep = STREAM_RECOVER_STEP__SCAN;
|
||||
pTaskInfo->streamInfo.recoverScanFinished = false;
|
||||
}
|
||||
|
||||
if (pTaskInfo->streamInfo.recoverStep == STREAM_RECOVER_STEP__SCAN) {
|
||||
if (pInfo->blockRecoverContiCnt > 100) {
|
||||
pInfo->blockRecoverTotCnt += pInfo->blockRecoverContiCnt;
|
||||
pInfo->blockRecoverContiCnt = 0;
|
||||
return NULL;
|
||||
}
|
||||
SSDataBlock* pBlock = doTableScan(pInfo->pTableScanOp);
|
||||
if (pBlock != NULL) {
|
||||
pInfo->blockRecoverContiCnt++;
|
||||
calBlockTbName(pInfo, pBlock);
|
||||
if (pInfo->pUpdateInfo) {
|
||||
TSKEY maxTs = updateInfoFillBlockData(pInfo->pUpdateInfo, pBlock, pInfo->primaryTsIndex);
|
||||
|
@ -1807,6 +1814,7 @@ static SSDataBlock* doStreamScan(SOperatorInfo* pOperator) {
|
|||
pTSInfo->base.cond.startVersion = -1;
|
||||
pTSInfo->base.cond.endVersion = -1;
|
||||
|
||||
pTaskInfo->streamInfo.recoverScanFinished = true;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
|
@ -21,6 +21,25 @@ namespace ParserTest {
|
|||
|
||||
class ParserInitialATest : public ParserDdlTest {};
|
||||
|
||||
/*
|
||||
* ALTER ACCOUNT account_name alter_account_options
|
||||
*
|
||||
* alter_account_options:
|
||||
* alter_account_option ...
|
||||
*
|
||||
* alter_account_option: {
|
||||
* PASS value
|
||||
* | PPS value
|
||||
* | TSERIES value
|
||||
* | STORAGE value
|
||||
* | STREAMS value
|
||||
* | QTIME value
|
||||
* | DBS value
|
||||
* | USERS value
|
||||
* | CONNS value
|
||||
* | STATE value
|
||||
* }
|
||||
*/
|
||||
TEST_F(ParserInitialATest, alterAccount) {
|
||||
useDb("root", "test");
|
||||
|
||||
|
@ -48,6 +67,7 @@ TEST_F(ParserInitialATest, alterDnode) {
|
|||
|
||||
setCheckDdlFunc([&](const SQuery* pQuery, ParserStage stage) {
|
||||
ASSERT_EQ(nodeType(pQuery->pRoot), QUERY_NODE_ALTER_DNODE_STMT);
|
||||
ASSERT_EQ(pQuery->pCmdMsg->msgType, TDMT_MND_CONFIG_DNODE);
|
||||
SMCfgDnodeReq req = {0};
|
||||
ASSERT_EQ(tDeserializeSMCfgDnodeReq(pQuery->pCmdMsg->pMsg, pQuery->pCmdMsg->msgLen, &req), TSDB_CODE_SUCCESS);
|
||||
ASSERT_EQ(req.dnodeId, expect.dnodeId);
|
||||
|
@ -86,9 +106,8 @@ TEST_F(ParserInitialATest, alterDnode) {
|
|||
* | KEEP {int_value | duration_value} -- rang [1, 365000], default 3650, unit day
|
||||
* | PAGES int_value -- rang [64, INT32_MAX], default 256, unit page
|
||||
* | REPLICA int_value -- todo: enum 1, 3, default 1, unit replica
|
||||
* | STRICT {'off' | 'on'} -- todo: default 'off'
|
||||
* | WAL_LEVEL int_value -- enum 1, 2, default 1
|
||||
* | SST_TRIGGER int_value -- rang [1, 16], default 8
|
||||
* | STT_TRIGGER int_value -- rang [1, 16], default 8
|
||||
* }
|
||||
*/
|
||||
TEST_F(ParserInitialATest, alterDatabase) {
|
||||
|
@ -130,10 +149,11 @@ TEST_F(ParserInitialATest, alterDatabase) {
|
|||
auto setAlterDbStrict = [&](int8_t strict) { expect.strict = strict; };
|
||||
auto setAlterDbCacheModel = [&](int8_t cacheModel) { expect.cacheLast = cacheModel; };
|
||||
auto setAlterDbReplica = [&](int8_t replications) { expect.replications = replications; };
|
||||
auto setAlterDbSstTrigger = [&](int8_t sstTrigger) { expect.sstTrigger = sstTrigger; };
|
||||
auto setAlterDbSttTrigger = [&](int8_t sstTrigger) { expect.sstTrigger = sstTrigger; };
|
||||
|
||||
setCheckDdlFunc([&](const SQuery* pQuery, ParserStage stage) {
|
||||
ASSERT_EQ(nodeType(pQuery->pRoot), QUERY_NODE_ALTER_DATABASE_STMT);
|
||||
ASSERT_EQ(pQuery->pCmdMsg->msgType, TDMT_MND_ALTER_DB);
|
||||
SAlterDbReq req = {0};
|
||||
ASSERT_EQ(tDeserializeSAlterDbReq(pQuery->pCmdMsg->pMsg, pQuery->pCmdMsg->msgLen, &req), TSDB_CODE_SUCCESS);
|
||||
ASSERT_EQ(std::string(req.db), std::string(expect.db));
|
||||
|
@ -161,11 +181,12 @@ TEST_F(ParserInitialATest, alterDatabase) {
|
|||
setAlterDbFsync(200);
|
||||
setAlterDbWal(1);
|
||||
setAlterDbCacheModel(TSDB_CACHE_MODEL_LAST_ROW);
|
||||
setAlterDbSstTrigger(16);
|
||||
setAlterDbSttTrigger(16);
|
||||
setAlterDbBuffer(16);
|
||||
setAlterDbPages(128);
|
||||
setAlterDbReplica(3);
|
||||
run("ALTER DATABASE test BUFFER 16 CACHEMODEL 'last_row' CACHESIZE 32 WAL_FSYNC_PERIOD 200 KEEP 10 PAGES 128 "
|
||||
"WAL_LEVEL 1 STT_TRIGGER 16");
|
||||
"REPLICA 3 WAL_LEVEL 1 STT_TRIGGER 16");
|
||||
clearAlterDbReq();
|
||||
|
||||
initAlterDb("test");
|
||||
|
@ -240,6 +261,22 @@ TEST_F(ParserInitialATest, alterDatabase) {
|
|||
setAlterDbWal(2);
|
||||
run("ALTER DATABASE test WAL_LEVEL 2");
|
||||
clearAlterDbReq();
|
||||
|
||||
initAlterDb("test");
|
||||
setAlterDbReplica(1);
|
||||
run("ALTER DATABASE test REPLICA 1");
|
||||
setAlterDbReplica(3);
|
||||
run("ALTER DATABASE test REPLICA 3");
|
||||
clearAlterDbReq();
|
||||
|
||||
initAlterDb("test");
|
||||
setAlterDbSttTrigger(1);
|
||||
run("ALTER DATABASE test STT_TRIGGER 1");
|
||||
setAlterDbSttTrigger(4);
|
||||
run("ALTER DATABASE test STT_TRIGGER 4");
|
||||
setAlterDbSttTrigger(16);
|
||||
run("ALTER DATABASE test STT_TRIGGER 16");
|
||||
clearAlterDbReq();
|
||||
}
|
||||
|
||||
TEST_F(ParserInitialATest, alterDatabaseSemanticCheck) {
|
||||
|
@ -260,6 +297,7 @@ TEST_F(ParserInitialATest, alterDatabaseSemanticCheck) {
|
|||
run("ALTER DATABASE test PAGES 63", TSDB_CODE_PAR_INVALID_DB_OPTION);
|
||||
run("ALTER DATABASE test WAL_LEVEL 0", TSDB_CODE_PAR_INVALID_DB_OPTION);
|
||||
run("ALTER DATABASE test WAL_LEVEL 3", TSDB_CODE_PAR_INVALID_DB_OPTION);
|
||||
run("ALTER DATABASE test REPLICA 2", TSDB_CODE_PAR_INVALID_DB_OPTION);
|
||||
run("ALTER DATABASE test STT_TRIGGER 0", TSDB_CODE_PAR_INVALID_DB_OPTION);
|
||||
run("ALTER DATABASE test STT_TRIGGER 17", TSDB_CODE_PAR_INVALID_DB_OPTION);
|
||||
// Regardless of the specific sentence
|
||||
|
@ -267,7 +305,7 @@ TEST_F(ParserInitialATest, alterDatabaseSemanticCheck) {
|
|||
}
|
||||
|
||||
/*
|
||||
* ALTER LOCAL dnode_id 'config' ['value']
|
||||
* ALTER LOCAL 'config' ['value']
|
||||
*/
|
||||
TEST_F(ParserInitialATest, alterLocal) {
|
||||
useDb("root", "test");
|
||||
|
@ -311,19 +349,19 @@ TEST_F(ParserInitialATest, alterLocal) {
|
|||
* | ADD COLUMN col_name column_type
|
||||
* | DROP COLUMN col_name
|
||||
* | MODIFY COLUMN col_name column_type
|
||||
* | RENAME COLUMN old_col_name new_col_name -- normal table
|
||||
* | ADD TAG tag_name tag_type -- super table
|
||||
* | DROP TAG tag_name -- super table
|
||||
* | MODIFY TAG tag_name tag_type -- super table
|
||||
* | RENAME TAG old_tag_name new_tag_name -- super table
|
||||
* | SET TAG tag_name = new_tag_value -- child table
|
||||
* | RENAME COLUMN old_col_name new_col_name -- only normal table
|
||||
* | ADD TAG tag_name tag_type -- only super table
|
||||
* | DROP TAG tag_name -- only super table
|
||||
* | MODIFY TAG tag_name tag_type -- only super table
|
||||
* | RENAME TAG old_tag_name new_tag_name -- only super table
|
||||
* | SET TAG tag_name = new_tag_value -- only child table
|
||||
* }
|
||||
*
|
||||
* alter_table_options:
|
||||
* alter_table_option ...
|
||||
*
|
||||
* alter_table_option: {
|
||||
* TTL int_value -- child/normal table
|
||||
* TTL int_value -- only child/normal table
|
||||
* | COMMENT 'string_value'
|
||||
* }
|
||||
*/
|
||||
|
@ -379,6 +417,7 @@ TEST_F(ParserInitialATest, alterSTable) {
|
|||
|
||||
setCheckDdlFunc([&](const SQuery* pQuery, ParserStage stage) {
|
||||
ASSERT_EQ(nodeType(pQuery->pRoot), QUERY_NODE_ALTER_SUPER_TABLE_STMT);
|
||||
ASSERT_EQ(pQuery->pCmdMsg->msgType, TDMT_MND_ALTER_STB);
|
||||
SMAlterStbReq req = {0};
|
||||
ASSERT_EQ(tDeserializeSMAlterStbReq(pQuery->pCmdMsg->pMsg, pQuery->pCmdMsg->msgLen, &req), TSDB_CODE_SUCCESS);
|
||||
ASSERT_EQ(std::string(req.name), std::string(expect.name));
|
||||
|
@ -444,136 +483,255 @@ TEST_F(ParserInitialATest, alterSTableSemanticCheck) {
|
|||
run("ALTER STABLE st1 TTL 10", TSDB_CODE_PAR_INVALID_ALTER_TABLE);
|
||||
}
|
||||
|
||||
/*
|
||||
* ALTER TABLE [db_name.]tb_name alter_table_clause
|
||||
*
|
||||
* alter_table_clause: {
|
||||
* alter_table_options
|
||||
* | ADD COLUMN col_name column_type
|
||||
* | DROP COLUMN col_name
|
||||
* | MODIFY COLUMN col_name column_type
|
||||
* | RENAME COLUMN old_col_name new_col_name -- only normal table
|
||||
* | ADD TAG tag_name tag_type -- only super table
|
||||
* | DROP TAG tag_name -- only super table
|
||||
* | MODIFY TAG tag_name tag_type -- only super table
|
||||
* | RENAME TAG old_tag_name new_tag_name -- only super table
|
||||
* | SET TAG tag_name = new_tag_value -- only child table
|
||||
* }
|
||||
*
|
||||
* alter_table_options:
|
||||
* alter_table_option ...
|
||||
*
|
||||
* alter_table_option: {
|
||||
* TTL int_value -- only child/normal table
|
||||
* | COMMENT 'string_value'
|
||||
* }
|
||||
*/
|
||||
TEST_F(ParserInitialATest, alterTable) {
|
||||
useDb("root", "test");
|
||||
|
||||
SVAlterTbReq expect = {0};
|
||||
// normal/child table
|
||||
{
|
||||
SVAlterTbReq expect = {0};
|
||||
|
||||
auto clearAlterTbReq = [&]() {
|
||||
free(expect.tbName);
|
||||
free(expect.colName);
|
||||
free(expect.colNewName);
|
||||
free(expect.tagName);
|
||||
memset(&expect, 0, sizeof(SVAlterTbReq));
|
||||
};
|
||||
auto clearAlterTbReq = [&]() {
|
||||
free(expect.tbName);
|
||||
free(expect.colName);
|
||||
free(expect.colNewName);
|
||||
free(expect.tagName);
|
||||
memset(&expect, 0, sizeof(SVAlterTbReq));
|
||||
};
|
||||
|
||||
auto setAlterTableCol = [&](const char* pTbname, int8_t alterType, const char* pColName, int8_t dataType = 0,
|
||||
int32_t dataBytes = 0, const char* pNewColName = nullptr) {
|
||||
expect.tbName = strdup(pTbname);
|
||||
expect.action = alterType;
|
||||
expect.colName = strdup(pColName);
|
||||
auto setAlterTableCol = [&](const char* pTbname, int8_t alterType, const char* pColName, int8_t dataType = 0,
|
||||
int32_t dataBytes = 0, const char* pNewColName = nullptr) {
|
||||
expect.tbName = strdup(pTbname);
|
||||
expect.action = alterType;
|
||||
expect.colName = strdup(pColName);
|
||||
|
||||
switch (alterType) {
|
||||
case TSDB_ALTER_TABLE_ADD_COLUMN:
|
||||
expect.type = dataType;
|
||||
expect.flags = COL_SMA_ON;
|
||||
expect.bytes = dataBytes > 0 ? dataBytes : (dataType > 0 ? tDataTypes[dataType].bytes : 0);
|
||||
break;
|
||||
case TSDB_ALTER_TABLE_UPDATE_COLUMN_BYTES:
|
||||
expect.colModBytes = dataBytes;
|
||||
break;
|
||||
case TSDB_ALTER_TABLE_UPDATE_COLUMN_NAME:
|
||||
expect.colNewName = strdup(pNewColName);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
};
|
||||
switch (alterType) {
|
||||
case TSDB_ALTER_TABLE_ADD_COLUMN:
|
||||
expect.type = dataType;
|
||||
expect.flags = COL_SMA_ON;
|
||||
expect.bytes = dataBytes > 0 ? dataBytes : (dataType > 0 ? tDataTypes[dataType].bytes : 0);
|
||||
break;
|
||||
case TSDB_ALTER_TABLE_UPDATE_COLUMN_BYTES:
|
||||
expect.colModBytes = dataBytes;
|
||||
break;
|
||||
case TSDB_ALTER_TABLE_UPDATE_COLUMN_NAME:
|
||||
expect.colNewName = strdup(pNewColName);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
auto setAlterTableTag = [&](const char* pTbname, const char* pTagName, uint8_t* pNewVal, uint32_t bytes) {
|
||||
expect.tbName = strdup(pTbname);
|
||||
expect.action = TSDB_ALTER_TABLE_UPDATE_TAG_VAL;
|
||||
expect.tagName = strdup(pTagName);
|
||||
auto setAlterTableTag = [&](const char* pTbname, const char* pTagName, uint8_t* pNewVal, uint32_t bytes) {
|
||||
expect.tbName = strdup(pTbname);
|
||||
expect.action = TSDB_ALTER_TABLE_UPDATE_TAG_VAL;
|
||||
expect.tagName = strdup(pTagName);
|
||||
|
||||
expect.isNull = (nullptr == pNewVal);
|
||||
expect.nTagVal = bytes;
|
||||
expect.pTagVal = pNewVal;
|
||||
};
|
||||
expect.isNull = (nullptr == pNewVal);
|
||||
expect.nTagVal = bytes;
|
||||
expect.pTagVal = pNewVal;
|
||||
};
|
||||
|
||||
auto setAlterTableOptions = [&](const char* pTbname, int32_t ttl, char* pComment = nullptr) {
|
||||
expect.tbName = strdup(pTbname);
|
||||
expect.action = TSDB_ALTER_TABLE_UPDATE_OPTIONS;
|
||||
if (-1 != ttl) {
|
||||
expect.updateTTL = true;
|
||||
expect.newTTL = ttl;
|
||||
}
|
||||
if (nullptr != pComment) {
|
||||
expect.newCommentLen = strlen(pComment);
|
||||
expect.newComment = pComment;
|
||||
}
|
||||
};
|
||||
auto setAlterTableOptions = [&](const char* pTbname, int32_t ttl, char* pComment = nullptr) {
|
||||
expect.tbName = strdup(pTbname);
|
||||
expect.action = TSDB_ALTER_TABLE_UPDATE_OPTIONS;
|
||||
if (-1 != ttl) {
|
||||
expect.updateTTL = true;
|
||||
expect.newTTL = ttl;
|
||||
}
|
||||
if (nullptr != pComment) {
|
||||
expect.newCommentLen = strlen(pComment);
|
||||
expect.newComment = pComment;
|
||||
}
|
||||
};
|
||||
|
||||
setCheckDdlFunc([&](const SQuery* pQuery, ParserStage stage) {
|
||||
ASSERT_EQ(nodeType(pQuery->pRoot), QUERY_NODE_VNODE_MODIFY_STMT);
|
||||
SVnodeModifyOpStmt* pStmt = (SVnodeModifyOpStmt*)pQuery->pRoot;
|
||||
setCheckDdlFunc([&](const SQuery* pQuery, ParserStage stage) {
|
||||
ASSERT_EQ(nodeType(pQuery->pRoot), QUERY_NODE_VNODE_MODIFY_STMT);
|
||||
SVnodeModifyOpStmt* pStmt = (SVnodeModifyOpStmt*)pQuery->pRoot;
|
||||
|
||||
ASSERT_EQ(pStmt->sqlNodeType, QUERY_NODE_ALTER_TABLE_STMT);
|
||||
ASSERT_NE(pStmt->pDataBlocks, nullptr);
|
||||
ASSERT_EQ(taosArrayGetSize(pStmt->pDataBlocks), 1);
|
||||
SVgDataBlocks* pVgData = (SVgDataBlocks*)taosArrayGetP(pStmt->pDataBlocks, 0);
|
||||
void* pBuf = POINTER_SHIFT(pVgData->pData, sizeof(SMsgHead));
|
||||
SVAlterTbReq req = {0};
|
||||
SDecoder coder = {0};
|
||||
tDecoderInit(&coder, (uint8_t*)pBuf, pVgData->size);
|
||||
ASSERT_EQ(tDecodeSVAlterTbReq(&coder, &req), TSDB_CODE_SUCCESS);
|
||||
ASSERT_EQ(pStmt->sqlNodeType, QUERY_NODE_ALTER_TABLE_STMT);
|
||||
ASSERT_NE(pStmt->pDataBlocks, nullptr);
|
||||
ASSERT_EQ(taosArrayGetSize(pStmt->pDataBlocks), 1);
|
||||
SVgDataBlocks* pVgData = (SVgDataBlocks*)taosArrayGetP(pStmt->pDataBlocks, 0);
|
||||
void* pBuf = POINTER_SHIFT(pVgData->pData, sizeof(SMsgHead));
|
||||
SVAlterTbReq req = {0};
|
||||
SDecoder coder = {0};
|
||||
tDecoderInit(&coder, (uint8_t*)pBuf, pVgData->size);
|
||||
ASSERT_EQ(tDecodeSVAlterTbReq(&coder, &req), TSDB_CODE_SUCCESS);
|
||||
|
||||
ASSERT_EQ(std::string(req.tbName), std::string(expect.tbName));
|
||||
ASSERT_EQ(req.action, expect.action);
|
||||
if (nullptr != expect.colName) {
|
||||
ASSERT_EQ(std::string(req.colName), std::string(expect.colName));
|
||||
}
|
||||
ASSERT_EQ(req.type, expect.type);
|
||||
ASSERT_EQ(req.flags, expect.flags);
|
||||
ASSERT_EQ(req.bytes, expect.bytes);
|
||||
ASSERT_EQ(req.colModBytes, expect.colModBytes);
|
||||
if (nullptr != expect.colNewName) {
|
||||
ASSERT_EQ(std::string(req.colNewName), std::string(expect.colNewName));
|
||||
}
|
||||
if (nullptr != expect.tagName) {
|
||||
ASSERT_EQ(std::string(req.tagName), std::string(expect.tagName));
|
||||
}
|
||||
ASSERT_EQ(req.isNull, expect.isNull);
|
||||
ASSERT_EQ(req.nTagVal, expect.nTagVal);
|
||||
ASSERT_EQ(memcmp(req.pTagVal, expect.pTagVal, expect.nTagVal), 0);
|
||||
ASSERT_EQ(req.updateTTL, expect.updateTTL);
|
||||
ASSERT_EQ(req.newTTL, expect.newTTL);
|
||||
if (nullptr != expect.newComment) {
|
||||
ASSERT_EQ(std::string(req.newComment), std::string(expect.newComment));
|
||||
ASSERT_EQ(req.newCommentLen, strlen(req.newComment));
|
||||
ASSERT_EQ(expect.newCommentLen, strlen(expect.newComment));
|
||||
}
|
||||
ASSERT_EQ(std::string(req.tbName), std::string(expect.tbName));
|
||||
ASSERT_EQ(req.action, expect.action);
|
||||
if (nullptr != expect.colName) {
|
||||
ASSERT_EQ(std::string(req.colName), std::string(expect.colName));
|
||||
}
|
||||
ASSERT_EQ(req.type, expect.type);
|
||||
ASSERT_EQ(req.flags, expect.flags);
|
||||
ASSERT_EQ(req.bytes, expect.bytes);
|
||||
ASSERT_EQ(req.colModBytes, expect.colModBytes);
|
||||
if (nullptr != expect.colNewName) {
|
||||
ASSERT_EQ(std::string(req.colNewName), std::string(expect.colNewName));
|
||||
}
|
||||
if (nullptr != expect.tagName) {
|
||||
ASSERT_EQ(std::string(req.tagName), std::string(expect.tagName));
|
||||
}
|
||||
ASSERT_EQ(req.isNull, expect.isNull);
|
||||
ASSERT_EQ(req.nTagVal, expect.nTagVal);
|
||||
ASSERT_EQ(memcmp(req.pTagVal, expect.pTagVal, expect.nTagVal), 0);
|
||||
ASSERT_EQ(req.updateTTL, expect.updateTTL);
|
||||
ASSERT_EQ(req.newTTL, expect.newTTL);
|
||||
if (nullptr != expect.newComment) {
|
||||
ASSERT_EQ(std::string(req.newComment), std::string(expect.newComment));
|
||||
ASSERT_EQ(req.newCommentLen, strlen(req.newComment));
|
||||
ASSERT_EQ(expect.newCommentLen, strlen(expect.newComment));
|
||||
}
|
||||
|
||||
tDecoderClear(&coder);
|
||||
});
|
||||
tDecoderClear(&coder);
|
||||
});
|
||||
|
||||
setAlterTableOptions("t1", 10, nullptr);
|
||||
run("ALTER TABLE t1 TTL 10");
|
||||
clearAlterTbReq();
|
||||
setAlterTableOptions("t1", 10, nullptr);
|
||||
run("ALTER TABLE t1 TTL 10");
|
||||
clearAlterTbReq();
|
||||
|
||||
setAlterTableOptions("t1", -1, (char*)"test");
|
||||
run("ALTER TABLE t1 COMMENT 'test'");
|
||||
clearAlterTbReq();
|
||||
setAlterTableOptions("t1", -1, (char*)"test");
|
||||
run("ALTER TABLE t1 COMMENT 'test'");
|
||||
clearAlterTbReq();
|
||||
|
||||
setAlterTableCol("t1", TSDB_ALTER_TABLE_ADD_COLUMN, "cc1", TSDB_DATA_TYPE_BIGINT);
|
||||
run("ALTER TABLE t1 ADD COLUMN cc1 BIGINT");
|
||||
clearAlterTbReq();
|
||||
setAlterTableCol("t1", TSDB_ALTER_TABLE_ADD_COLUMN, "cc1", TSDB_DATA_TYPE_BIGINT);
|
||||
run("ALTER TABLE t1 ADD COLUMN cc1 BIGINT");
|
||||
clearAlterTbReq();
|
||||
|
||||
setAlterTableCol("t1", TSDB_ALTER_TABLE_DROP_COLUMN, "c1");
|
||||
run("ALTER TABLE t1 DROP COLUMN c1");
|
||||
clearAlterTbReq();
|
||||
setAlterTableCol("t1", TSDB_ALTER_TABLE_DROP_COLUMN, "c1");
|
||||
run("ALTER TABLE t1 DROP COLUMN c1");
|
||||
clearAlterTbReq();
|
||||
|
||||
setAlterTableCol("t1", TSDB_ALTER_TABLE_UPDATE_COLUMN_BYTES, "c2", TSDB_DATA_TYPE_VARCHAR, 30 + VARSTR_HEADER_SIZE);
|
||||
run("ALTER TABLE t1 MODIFY COLUMN c2 VARCHAR(30)");
|
||||
clearAlterTbReq();
|
||||
setAlterTableCol("t1", TSDB_ALTER_TABLE_UPDATE_COLUMN_BYTES, "c2", TSDB_DATA_TYPE_VARCHAR, 30 + VARSTR_HEADER_SIZE);
|
||||
run("ALTER TABLE t1 MODIFY COLUMN c2 VARCHAR(30)");
|
||||
clearAlterTbReq();
|
||||
|
||||
setAlterTableCol("t1", TSDB_ALTER_TABLE_UPDATE_COLUMN_NAME, "c1", 0, 0, "cc1");
|
||||
run("ALTER TABLE t1 RENAME COLUMN c1 cc1");
|
||||
clearAlterTbReq();
|
||||
setAlterTableCol("t1", TSDB_ALTER_TABLE_UPDATE_COLUMN_NAME, "c1", 0, 0, "cc1");
|
||||
run("ALTER TABLE t1 RENAME COLUMN c1 cc1");
|
||||
clearAlterTbReq();
|
||||
|
||||
int32_t val = 10;
|
||||
setAlterTableTag("st1s1", "tag1", (uint8_t*)&val, sizeof(val));
|
||||
run("ALTER TABLE st1s1 SET TAG tag1=10");
|
||||
clearAlterTbReq();
|
||||
int32_t val = 10;
|
||||
setAlterTableTag("st1s1", "tag1", (uint8_t*)&val, sizeof(val));
|
||||
run("ALTER TABLE st1s1 SET TAG tag1=10");
|
||||
clearAlterTbReq();
|
||||
}
|
||||
|
||||
// super table
|
||||
{
|
||||
SMAlterStbReq expect = {0};
|
||||
|
||||
auto clearAlterStbReq = [&]() {
|
||||
tFreeSMAltertbReq(&expect);
|
||||
memset(&expect, 0, sizeof(SMAlterStbReq));
|
||||
};
|
||||
|
||||
auto setAlterStbReq = [&](const char* pTbname, int8_t alterType, int32_t numOfFields = 0,
|
||||
const char* pField1Name = nullptr, int8_t field1Type = 0, int32_t field1Bytes = 0,
|
||||
const char* pField2Name = nullptr, const char* pComment = nullptr) {
|
||||
int32_t len = snprintf(expect.name, sizeof(expect.name), "0.test.%s", pTbname);
|
||||
expect.name[len] = '\0';
|
||||
expect.alterType = alterType;
|
||||
if (nullptr != pComment) {
|
||||
expect.comment = strdup(pComment);
|
||||
expect.commentLen = strlen(pComment);
|
||||
}
|
||||
|
||||
expect.numOfFields = numOfFields;
|
||||
if (NULL == expect.pFields) {
|
||||
expect.pFields = taosArrayInit(2, sizeof(TAOS_FIELD));
|
||||
TAOS_FIELD field = {0};
|
||||
taosArrayPush(expect.pFields, &field);
|
||||
taosArrayPush(expect.pFields, &field);
|
||||
}
|
||||
|
||||
TAOS_FIELD* pField = (TAOS_FIELD*)taosArrayGet(expect.pFields, 0);
|
||||
if (NULL != pField1Name) {
|
||||
strcpy(pField->name, pField1Name);
|
||||
pField->name[strlen(pField1Name)] = '\0';
|
||||
} else {
|
||||
memset(pField, 0, sizeof(TAOS_FIELD));
|
||||
}
|
||||
pField->type = field1Type;
|
||||
pField->bytes = field1Bytes > 0 ? field1Bytes : (field1Type > 0 ? tDataTypes[field1Type].bytes : 0);
|
||||
|
||||
pField = (TAOS_FIELD*)taosArrayGet(expect.pFields, 1);
|
||||
if (NULL != pField2Name) {
|
||||
strcpy(pField->name, pField2Name);
|
||||
pField->name[strlen(pField2Name)] = '\0';
|
||||
} else {
|
||||
memset(pField, 0, sizeof(TAOS_FIELD));
|
||||
}
|
||||
pField->type = 0;
|
||||
pField->bytes = 0;
|
||||
};
|
||||
|
||||
setCheckDdlFunc([&](const SQuery* pQuery, ParserStage stage) {
|
||||
ASSERT_EQ(nodeType(pQuery->pRoot), QUERY_NODE_ALTER_TABLE_STMT);
|
||||
ASSERT_EQ(pQuery->pCmdMsg->msgType, TDMT_MND_ALTER_STB);
|
||||
SMAlterStbReq req = {0};
|
||||
ASSERT_EQ(tDeserializeSMAlterStbReq(pQuery->pCmdMsg->pMsg, pQuery->pCmdMsg->msgLen, &req), TSDB_CODE_SUCCESS);
|
||||
ASSERT_EQ(std::string(req.name), std::string(expect.name));
|
||||
ASSERT_EQ(req.alterType, expect.alterType);
|
||||
ASSERT_EQ(req.numOfFields, expect.numOfFields);
|
||||
if (expect.numOfFields > 0) {
|
||||
TAOS_FIELD* pField = (TAOS_FIELD*)taosArrayGet(req.pFields, 0);
|
||||
TAOS_FIELD* pExpectField = (TAOS_FIELD*)taosArrayGet(expect.pFields, 0);
|
||||
ASSERT_EQ(std::string(pField->name), std::string(pExpectField->name));
|
||||
ASSERT_EQ(pField->type, pExpectField->type);
|
||||
ASSERT_EQ(pField->bytes, pExpectField->bytes);
|
||||
}
|
||||
if (expect.numOfFields > 1) {
|
||||
TAOS_FIELD* pField = (TAOS_FIELD*)taosArrayGet(req.pFields, 1);
|
||||
TAOS_FIELD* pExpectField = (TAOS_FIELD*)taosArrayGet(expect.pFields, 1);
|
||||
ASSERT_EQ(std::string(pField->name), std::string(pExpectField->name));
|
||||
ASSERT_EQ(pField->type, pExpectField->type);
|
||||
ASSERT_EQ(pField->bytes, pExpectField->bytes);
|
||||
}
|
||||
tFreeSMAltertbReq(&req);
|
||||
});
|
||||
|
||||
setAlterStbReq("st1", TSDB_ALTER_TABLE_ADD_TAG, 1, "tag11", TSDB_DATA_TYPE_BIGINT);
|
||||
run("ALTER TABLE st1 ADD TAG tag11 BIGINT");
|
||||
clearAlterStbReq();
|
||||
|
||||
setAlterStbReq("st1", TSDB_ALTER_TABLE_DROP_TAG, 1, "tag1");
|
||||
run("ALTER TABLE st1 DROP TAG tag1");
|
||||
clearAlterStbReq();
|
||||
|
||||
setAlterStbReq("st1", TSDB_ALTER_TABLE_UPDATE_TAG_BYTES, 1, "tag2", TSDB_DATA_TYPE_VARCHAR,
|
||||
30 + VARSTR_HEADER_SIZE);
|
||||
run("ALTER TABLE st1 MODIFY TAG tag2 VARCHAR(30)");
|
||||
clearAlterStbReq();
|
||||
|
||||
setAlterStbReq("st1", TSDB_ALTER_TABLE_UPDATE_TAG_NAME, 2, "tag1", 0, 0, "tag11");
|
||||
run("ALTER TABLE st1 RENAME TAG tag1 tag11");
|
||||
clearAlterStbReq();
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(ParserInitialATest, alterTableSemanticCheck) {
|
||||
|
@ -588,7 +746,7 @@ TEST_F(ParserInitialATest, alterTableSemanticCheck) {
|
|||
}
|
||||
|
||||
/*
|
||||
* ALTER USER user_name PASS str_value
|
||||
* ALTER USER user_name alter_user_clause
|
||||
*
|
||||
* alter_user_clause: {
|
||||
* PASS str_value
|
||||
|
@ -618,6 +776,7 @@ TEST_F(ParserInitialATest, alterUser) {
|
|||
|
||||
setCheckDdlFunc([&](const SQuery* pQuery, ParserStage stage) {
|
||||
ASSERT_EQ(nodeType(pQuery->pRoot), QUERY_NODE_ALTER_USER_STMT);
|
||||
ASSERT_EQ(pQuery->pCmdMsg->msgType, TDMT_MND_ALTER_USER);
|
||||
SAlterUserReq req = {0};
|
||||
ASSERT_TRUE(TSDB_CODE_SUCCESS == tDeserializeSAlterUserReq(pQuery->pCmdMsg->pMsg, pQuery->pCmdMsg->msgLen, &req));
|
||||
|
||||
|
|
|
@ -52,8 +52,8 @@ TEST_F(ParserExplainToSyncdbTest, grant) {
|
|||
ASSERT_EQ(string(req.objname), string(expect.objname));
|
||||
});
|
||||
|
||||
setAlterUserReq(TSDB_ALTER_USER_ADD_ALL_DB, "wxy", "0.test");
|
||||
run("GRANT ALL ON test.* TO wxy");
|
||||
setAlterUserReq(TSDB_ALTER_USER_ADD_ALL_DB, "wxy", "0.*");
|
||||
run("GRANT ALL ON *.* TO wxy");
|
||||
|
||||
setAlterUserReq(TSDB_ALTER_USER_ADD_READ_DB, "wxy", "0.test");
|
||||
run("GRANT READ ON test.* TO wxy");
|
||||
|
@ -138,10 +138,38 @@ TEST_F(ParserExplainToSyncdbTest, redistributeVgroup) {
|
|||
TEST_F(ParserExplainToSyncdbTest, revoke) {
|
||||
useDb("root", "test");
|
||||
|
||||
run("REVOKE ALL ON test.* FROM wxy");
|
||||
SAlterUserReq expect = {0};
|
||||
|
||||
auto setAlterUserReq = [&](int8_t alterType, const string& user, const string& obj) {
|
||||
expect.alterType = alterType;
|
||||
snprintf(expect.user, sizeof(expect.user), "%s", user.c_str());
|
||||
snprintf(expect.objname, sizeof(expect.objname), "%s", obj.c_str());
|
||||
};
|
||||
|
||||
setCheckDdlFunc([&](const SQuery* pQuery, ParserStage stage) {
|
||||
ASSERT_EQ(nodeType(pQuery->pRoot), QUERY_NODE_REVOKE_STMT);
|
||||
ASSERT_EQ(pQuery->pCmdMsg->msgType, TDMT_MND_ALTER_USER);
|
||||
SAlterUserReq req = {0};
|
||||
ASSERT_EQ(tDeserializeSAlterUserReq(pQuery->pCmdMsg->pMsg, pQuery->pCmdMsg->msgLen, &req), TSDB_CODE_SUCCESS);
|
||||
ASSERT_EQ(req.alterType, expect.alterType);
|
||||
ASSERT_EQ(string(req.user), string(expect.user));
|
||||
ASSERT_EQ(string(req.objname), string(expect.objname));
|
||||
});
|
||||
|
||||
setAlterUserReq(TSDB_ALTER_USER_REMOVE_ALL_DB, "wxy", "0.*");
|
||||
run("REVOKE ALL ON *.* FROM wxy");
|
||||
|
||||
setAlterUserReq(TSDB_ALTER_USER_REMOVE_READ_DB, "wxy", "0.test");
|
||||
run("REVOKE READ ON test.* FROM wxy");
|
||||
|
||||
setAlterUserReq(TSDB_ALTER_USER_REMOVE_WRITE_DB, "wxy", "0.test");
|
||||
run("REVOKE WRITE ON test.* FROM wxy");
|
||||
|
||||
setAlterUserReq(TSDB_ALTER_USER_REMOVE_ALL_DB, "wxy", "0.test");
|
||||
run("REVOKE READ, WRITE ON test.* FROM wxy");
|
||||
|
||||
setAlterUserReq(TSDB_ALTER_USER_REMOVE_SUBSCRIBE_TOPIC, "wxy", "0.tp1");
|
||||
run("REVOKE SUBSCRIBE ON tp1 FROM wxy");
|
||||
}
|
||||
|
||||
// todo syncdb
|
||||
|
|
|
@ -21,6 +21,9 @@ namespace ParserTest {
|
|||
|
||||
class ParserInitialCTest : public ParserDdlTest {};
|
||||
|
||||
/*
|
||||
* COMPACT DATABASE db_name
|
||||
*/
|
||||
TEST_F(ParserInitialCTest, compact) {
|
||||
SCompactDbReq expect = {0};
|
||||
|
||||
|
@ -38,12 +41,35 @@ TEST_F(ParserInitialCTest, compact) {
|
|||
run("COMPACT DATABASE wxy_db");
|
||||
}
|
||||
|
||||
/*
|
||||
* CREATE ACCOUNT account_name PASS value [create_account_options]
|
||||
*
|
||||
* create_account_options:
|
||||
* create_account_option ...
|
||||
*
|
||||
* create_account_option: {
|
||||
* PPS value
|
||||
* | TSERIES value
|
||||
* | STORAGE value
|
||||
* | STREAMS value
|
||||
* | QTIME value
|
||||
* | DBS value
|
||||
* | USERS value
|
||||
* | CONNS value
|
||||
* | STATE value
|
||||
* }
|
||||
*/
|
||||
TEST_F(ParserInitialCTest, createAccount) {
|
||||
useDb("root", "test");
|
||||
|
||||
run("CREATE ACCOUNT ac_wxy PASS '123456'", TSDB_CODE_PAR_EXPRIE_STATEMENT, PARSER_STAGE_PARSE);
|
||||
}
|
||||
|
||||
/*
|
||||
* CREATE BNODE ON DNODE dnode_id
|
||||
* the server does not support it temporarily
|
||||
*/
|
||||
|
||||
/*
|
||||
* CREATE DATABASE [IF NOT EXISTS] db_name [database_options]
|
||||
*
|
||||
|
@ -85,7 +111,7 @@ TEST_F(ParserInitialCTest, createDatabase) {
|
|||
memset(&expect, 0, sizeof(SCreateDbReq));
|
||||
};
|
||||
|
||||
auto setCreateDbReqFunc = [&](const char* pDbname, int8_t igExists = 0) {
|
||||
auto setCreateDbReq = [&](const char* pDbname, int8_t igExists = 0) {
|
||||
int32_t len = snprintf(expect.db, sizeof(expect.db), "0.%s", pDbname);
|
||||
expect.db[len] = '\0';
|
||||
expect.ignoreExist = igExists;
|
||||
|
@ -119,28 +145,28 @@ TEST_F(ParserInitialCTest, createDatabase) {
|
|||
expect.tsdbPageSize = TSDB_DEFAULT_TSDB_PAGESIZE;
|
||||
};
|
||||
|
||||
auto setDbBufferFunc = [&](int32_t buffer) { expect.buffer = buffer; };
|
||||
auto setDbCachelastFunc = [&](int8_t cachelast) { expect.cacheLast = cachelast; };
|
||||
auto setDbBuffer = [&](int32_t buffer) { expect.buffer = buffer; };
|
||||
auto setDbCachelast = [&](int8_t cachelast) { expect.cacheLast = cachelast; };
|
||||
auto setDbCachelastSize = [&](int8_t cachelastSize) { expect.cacheLastSize = cachelastSize; };
|
||||
auto setDbCompressionFunc = [&](int8_t compressionLevel) { expect.compression = compressionLevel; };
|
||||
auto setDbDaysFunc = [&](int32_t daysPerFile) { expect.daysPerFile = daysPerFile; };
|
||||
auto setDbFsyncFunc = [&](int32_t fsyncPeriod) { expect.walFsyncPeriod = fsyncPeriod; };
|
||||
auto setDbMaxRowsFunc = [&](int32_t maxRowsPerBlock) { expect.maxRows = maxRowsPerBlock; };
|
||||
auto setDbMinRowsFunc = [&](int32_t minRowsPerBlock) { expect.minRows = minRowsPerBlock; };
|
||||
auto setDbKeepFunc = [&](int32_t keep0, int32_t keep1 = 0, int32_t keep2 = 0) {
|
||||
auto setDbCompression = [&](int8_t compressionLevel) { expect.compression = compressionLevel; };
|
||||
auto setDbDays = [&](int32_t daysPerFile) { expect.daysPerFile = daysPerFile; };
|
||||
auto setDbFsync = [&](int32_t fsyncPeriod) { expect.walFsyncPeriod = fsyncPeriod; };
|
||||
auto setDbMaxRows = [&](int32_t maxRowsPerBlock) { expect.maxRows = maxRowsPerBlock; };
|
||||
auto setDbMinRows = [&](int32_t minRowsPerBlock) { expect.minRows = minRowsPerBlock; };
|
||||
auto setDbKeep = [&](int32_t keep0, int32_t keep1 = 0, int32_t keep2 = 0) {
|
||||
expect.daysToKeep0 = keep0;
|
||||
expect.daysToKeep1 = 0 == keep1 ? expect.daysToKeep0 : keep1;
|
||||
expect.daysToKeep2 = 0 == keep2 ? expect.daysToKeep1 : keep2;
|
||||
};
|
||||
auto setDbPagesFunc = [&](int32_t pages) { expect.pages = pages; };
|
||||
auto setDbPageSizeFunc = [&](int32_t pagesize) { expect.pageSize = pagesize; };
|
||||
auto setDbPrecisionFunc = [&](int8_t precision) { expect.precision = precision; };
|
||||
auto setDbReplicaFunc = [&](int8_t replica) { expect.replications = replica; };
|
||||
auto setDbStrictaFunc = [&](int8_t strict) { expect.strict = strict; };
|
||||
auto setDbWalLevelFunc = [&](int8_t walLevel) { expect.walLevel = walLevel; };
|
||||
auto setDbVgroupsFunc = [&](int32_t numOfVgroups) { expect.numOfVgroups = numOfVgroups; };
|
||||
auto setDbSingleStableFunc = [&](int8_t singleStable) { expect.numOfStables = singleStable; };
|
||||
auto addDbRetentionFunc = [&](int64_t freq, int64_t keep, int8_t freqUnit, int8_t keepUnit) {
|
||||
auto setDbPages = [&](int32_t pages) { expect.pages = pages; };
|
||||
auto setDbPageSize = [&](int32_t pagesize) { expect.pageSize = pagesize; };
|
||||
auto setDbPrecision = [&](int8_t precision) { expect.precision = precision; };
|
||||
auto setDbReplica = [&](int8_t replica) { expect.replications = replica; };
|
||||
auto setDbStricta = [&](int8_t strict) { expect.strict = strict; };
|
||||
auto setDbWalLevel = [&](int8_t walLevel) { expect.walLevel = walLevel; };
|
||||
auto setDbVgroups = [&](int32_t numOfVgroups) { expect.numOfVgroups = numOfVgroups; };
|
||||
auto setDbSingleStable = [&](int8_t singleStable) { expect.numOfStables = singleStable; };
|
||||
auto addDbRetention = [&](int64_t freq, int64_t keep, int8_t freqUnit, int8_t keepUnit) {
|
||||
SRetention retention = {0};
|
||||
retention.freq = freq;
|
||||
retention.keep = keep;
|
||||
|
@ -152,7 +178,7 @@ TEST_F(ParserInitialCTest, createDatabase) {
|
|||
taosArrayPush(expect.pRetensions, &retention);
|
||||
++expect.numOfRetensions;
|
||||
};
|
||||
auto setDbSchemalessFunc = [&](int8_t schemaless) { expect.schemaless = schemaless; };
|
||||
auto setDbSchemaless = [&](int8_t schemaless) { expect.schemaless = schemaless; };
|
||||
auto setDbWalRetentionPeriod = [&](int32_t walRetentionPeriod) { expect.walRetentionPeriod = walRetentionPeriod; };
|
||||
auto setDbWalRetentionSize = [&](int32_t walRetentionSize) { expect.walRetentionSize = walRetentionSize; };
|
||||
auto setDbWalRollPeriod = [&](int32_t walRollPeriod) { expect.walRollPeriod = walRollPeriod; };
|
||||
|
@ -164,6 +190,7 @@ TEST_F(ParserInitialCTest, createDatabase) {
|
|||
|
||||
setCheckDdlFunc([&](const SQuery* pQuery, ParserStage stage) {
|
||||
ASSERT_EQ(nodeType(pQuery->pRoot), QUERY_NODE_CREATE_DATABASE_STMT);
|
||||
ASSERT_EQ(pQuery->pCmdMsg->msgType, TDMT_MND_CREATE_DB);
|
||||
SCreateDbReq req = {0};
|
||||
ASSERT_TRUE(TSDB_CODE_SUCCESS == tDeserializeSCreateDbReq(pQuery->pCmdMsg->pMsg, pQuery->pCmdMsg->msgLen, &req));
|
||||
|
||||
|
@ -212,32 +239,32 @@ TEST_F(ParserInitialCTest, createDatabase) {
|
|||
tFreeSCreateDbReq(&req);
|
||||
});
|
||||
|
||||
setCreateDbReqFunc("wxy_db");
|
||||
setCreateDbReq("wxy_db");
|
||||
run("CREATE DATABASE wxy_db");
|
||||
clearCreateDbReq();
|
||||
|
||||
setCreateDbReqFunc("wxy_db", 1);
|
||||
setDbBufferFunc(64);
|
||||
setDbCachelastFunc(2);
|
||||
setCreateDbReq("wxy_db", 1);
|
||||
setDbBuffer(64);
|
||||
setDbCachelast(2);
|
||||
setDbCachelastSize(20);
|
||||
setDbCompressionFunc(1);
|
||||
setDbDaysFunc(100 * 1440);
|
||||
setDbFsyncFunc(100);
|
||||
setDbMaxRowsFunc(1000);
|
||||
setDbMinRowsFunc(100);
|
||||
setDbKeepFunc(1440 * 1440);
|
||||
setDbPagesFunc(96);
|
||||
setDbPageSizeFunc(8);
|
||||
setDbPrecisionFunc(TSDB_TIME_PRECISION_NANO);
|
||||
setDbReplicaFunc(3);
|
||||
addDbRetentionFunc(15 * MILLISECOND_PER_SECOND, 7 * MILLISECOND_PER_DAY, TIME_UNIT_SECOND, TIME_UNIT_DAY);
|
||||
addDbRetentionFunc(1 * MILLISECOND_PER_MINUTE, 21 * MILLISECOND_PER_DAY, TIME_UNIT_MINUTE, TIME_UNIT_DAY);
|
||||
addDbRetentionFunc(15 * MILLISECOND_PER_MINUTE, 500 * MILLISECOND_PER_DAY, TIME_UNIT_MINUTE, TIME_UNIT_DAY);
|
||||
// setDbStrictaFunc(1);
|
||||
setDbWalLevelFunc(2);
|
||||
setDbVgroupsFunc(100);
|
||||
setDbSingleStableFunc(1);
|
||||
setDbSchemalessFunc(1);
|
||||
setDbCompression(1);
|
||||
setDbDays(100 * 1440);
|
||||
setDbFsync(100);
|
||||
setDbMaxRows(1000);
|
||||
setDbMinRows(100);
|
||||
setDbKeep(1440 * 1440);
|
||||
setDbPages(96);
|
||||
setDbPageSize(8);
|
||||
setDbPrecision(TSDB_TIME_PRECISION_NANO);
|
||||
setDbReplica(3);
|
||||
addDbRetention(15 * MILLISECOND_PER_SECOND, 7 * MILLISECOND_PER_DAY, TIME_UNIT_SECOND, TIME_UNIT_DAY);
|
||||
addDbRetention(1 * MILLISECOND_PER_MINUTE, 21 * MILLISECOND_PER_DAY, TIME_UNIT_MINUTE, TIME_UNIT_DAY);
|
||||
addDbRetention(15 * MILLISECOND_PER_MINUTE, 500 * MILLISECOND_PER_DAY, TIME_UNIT_MINUTE, TIME_UNIT_DAY);
|
||||
// setDbStricta(1);
|
||||
setDbWalLevel(2);
|
||||
setDbVgroups(100);
|
||||
setDbSingleStable(1);
|
||||
setDbSchemaless(1);
|
||||
setDbWalRetentionPeriod(-1);
|
||||
setDbWalRetentionSize(-1);
|
||||
setDbWalRollPeriod(10);
|
||||
|
@ -276,16 +303,16 @@ TEST_F(ParserInitialCTest, createDatabase) {
|
|||
"TSDB_PAGESIZE 32");
|
||||
clearCreateDbReq();
|
||||
|
||||
setCreateDbReqFunc("wxy_db", 1);
|
||||
setDbDaysFunc(100);
|
||||
setDbKeepFunc(1440, 300 * 60, 400 * 1440);
|
||||
setCreateDbReq("wxy_db", 1);
|
||||
setDbDays(100);
|
||||
setDbKeep(1440, 300 * 60, 400 * 1440);
|
||||
run("CREATE DATABASE IF NOT EXISTS wxy_db "
|
||||
"DURATION 100m "
|
||||
"KEEP 1440m,300h,400d ");
|
||||
clearCreateDbReq();
|
||||
|
||||
setCreateDbReqFunc("wxy_db", 1);
|
||||
setDbReplicaFunc(3);
|
||||
setCreateDbReq("wxy_db", 1);
|
||||
setDbReplica(3);
|
||||
setDbWalRetentionPeriod(TSDB_REPS_DEF_DB_WAL_RET_PERIOD);
|
||||
setDbWalRetentionSize(TSDB_REPS_DEF_DB_WAL_RET_SIZE);
|
||||
setDbWalRollPeriod(TSDB_REPS_DEF_DB_WAL_ROLL_PERIOD);
|
||||
|
@ -304,6 +331,9 @@ TEST_F(ParserInitialCTest, createDatabaseSemanticCheck) {
|
|||
run("create database db2 retentions 15s:7d,5m:21d,10m:10d", TSDB_CODE_PAR_INVALID_DB_OPTION);
|
||||
}
|
||||
|
||||
/*
|
||||
* CREATE DNODE {dnode_endpoint | dnode_host_name PORT port_val}
|
||||
*/
|
||||
TEST_F(ParserInitialCTest, createDnode) {
|
||||
useDb("root", "test");
|
||||
|
||||
|
@ -311,7 +341,7 @@ TEST_F(ParserInitialCTest, createDnode) {
|
|||
|
||||
auto clearCreateDnodeReq = [&]() { memset(&expect, 0, sizeof(SCreateDnodeReq)); };
|
||||
|
||||
auto setCreateDnodeReqFunc = [&](const char* pFqdn, int32_t port = tsServerPort) {
|
||||
auto setCreateDnodeReq = [&](const char* pFqdn, int32_t port = tsServerPort) {
|
||||
strcpy(expect.fqdn, pFqdn);
|
||||
expect.port = port;
|
||||
};
|
||||
|
@ -325,39 +355,41 @@ TEST_F(ParserInitialCTest, createDnode) {
|
|||
ASSERT_EQ(req.port, expect.port);
|
||||
});
|
||||
|
||||
setCreateDnodeReqFunc("abc1", 7030);
|
||||
setCreateDnodeReq("abc1", 7030);
|
||||
run("CREATE DNODE 'abc1' PORT 7030");
|
||||
clearCreateDnodeReq();
|
||||
|
||||
setCreateDnodeReqFunc("1.1.1.1", 8030);
|
||||
setCreateDnodeReq("1.1.1.1", 8030);
|
||||
run("CREATE DNODE 1.1.1.1 PORT 8030");
|
||||
clearCreateDnodeReq();
|
||||
|
||||
setCreateDnodeReqFunc("host1", 9030);
|
||||
setCreateDnodeReq("host1", 9030);
|
||||
run("CREATE DNODE host1 PORT 9030");
|
||||
clearCreateDnodeReq();
|
||||
|
||||
setCreateDnodeReqFunc("abc2", 7040);
|
||||
setCreateDnodeReq("abc2", 7040);
|
||||
run("CREATE DNODE 'abc2:7040'");
|
||||
clearCreateDnodeReq();
|
||||
|
||||
setCreateDnodeReqFunc("1.1.1.2");
|
||||
setCreateDnodeReq("1.1.1.2");
|
||||
run("CREATE DNODE 1.1.1.2");
|
||||
clearCreateDnodeReq();
|
||||
|
||||
setCreateDnodeReqFunc("host2");
|
||||
setCreateDnodeReq("host2");
|
||||
run("CREATE DNODE host2");
|
||||
clearCreateDnodeReq();
|
||||
}
|
||||
|
||||
// CREATE [AGGREGATE] FUNCTION [IF NOT EXISTS] func_name AS library_path OUTPUTTYPE type_name [BUFSIZE value]
|
||||
/*
|
||||
* CREATE [AGGREGATE] FUNCTION [IF NOT EXISTS] func_name AS library_path OUTPUTTYPE type_name [BUFSIZE value]
|
||||
*/
|
||||
TEST_F(ParserInitialCTest, createFunction) {
|
||||
useDb("root", "test");
|
||||
|
||||
SCreateFuncReq expect = {0};
|
||||
|
||||
auto setCreateFuncReqFunc = [&](const char* pUdfName, int8_t outputType, int32_t outputBytes = 0,
|
||||
int8_t funcType = TSDB_FUNC_TYPE_SCALAR, int8_t igExists = 0, int32_t bufSize = 0) {
|
||||
auto setCreateFuncReq = [&](const char* pUdfName, int8_t outputType, int32_t outputBytes = 0,
|
||||
int8_t funcType = TSDB_FUNC_TYPE_SCALAR, int8_t igExists = 0, int32_t bufSize = 0) {
|
||||
memset(&expect, 0, sizeof(SCreateFuncReq));
|
||||
strcpy(expect.name, pUdfName);
|
||||
expect.igExists = igExists;
|
||||
|
@ -382,13 +414,69 @@ TEST_F(ParserInitialCTest, createFunction) {
|
|||
ASSERT_EQ(req.bufSize, expect.bufSize);
|
||||
});
|
||||
|
||||
setCreateFuncReqFunc("udf1", TSDB_DATA_TYPE_INT);
|
||||
setCreateFuncReq("udf1", TSDB_DATA_TYPE_INT);
|
||||
// run("CREATE FUNCTION udf1 AS './build/lib/libudf1.so' OUTPUTTYPE INT");
|
||||
|
||||
setCreateFuncReqFunc("udf2", TSDB_DATA_TYPE_DOUBLE, 0, TSDB_FUNC_TYPE_AGGREGATE, 1, 8);
|
||||
setCreateFuncReq("udf2", TSDB_DATA_TYPE_DOUBLE, 0, TSDB_FUNC_TYPE_AGGREGATE, 1, 8);
|
||||
// run("CREATE AGGREGATE FUNCTION IF NOT EXISTS udf2 AS './build/lib/libudf2.so' OUTPUTTYPE DOUBLE BUFSIZE 8");
|
||||
}
|
||||
|
||||
/*
|
||||
* CREATE MNODE ON DNODE dnode_id
|
||||
*/
|
||||
TEST_F(ParserInitialCTest, createMnode) {
|
||||
useDb("root", "test");
|
||||
|
||||
SMCreateMnodeReq expect = {0};
|
||||
|
||||
auto setCreateMnodeReq = [&](int32_t dnodeId) { expect.dnodeId = dnodeId; };
|
||||
|
||||
setCheckDdlFunc([&](const SQuery* pQuery, ParserStage stage) {
|
||||
ASSERT_EQ(nodeType(pQuery->pRoot), QUERY_NODE_CREATE_MNODE_STMT);
|
||||
SMCreateMnodeReq req = {0};
|
||||
ASSERT_TRUE(TSDB_CODE_SUCCESS ==
|
||||
tDeserializeSCreateDropMQSNodeReq(pQuery->pCmdMsg->pMsg, pQuery->pCmdMsg->msgLen, &req));
|
||||
|
||||
ASSERT_EQ(req.dnodeId, expect.dnodeId);
|
||||
});
|
||||
|
||||
setCreateMnodeReq(1);
|
||||
run("CREATE MNODE ON DNODE 1");
|
||||
}
|
||||
|
||||
/*
|
||||
* CREATE QNODE ON DNODE dnode_id
|
||||
*/
|
||||
TEST_F(ParserInitialCTest, createQnode) {
|
||||
useDb("root", "test");
|
||||
|
||||
SMCreateQnodeReq expect = {0};
|
||||
|
||||
auto setCreateQnodeReq = [&](int32_t dnodeId) { expect.dnodeId = dnodeId; };
|
||||
|
||||
setCheckDdlFunc([&](const SQuery* pQuery, ParserStage stage) {
|
||||
ASSERT_EQ(nodeType(pQuery->pRoot), QUERY_NODE_CREATE_QNODE_STMT);
|
||||
SMCreateQnodeReq req = {0};
|
||||
ASSERT_TRUE(TSDB_CODE_SUCCESS ==
|
||||
tDeserializeSCreateDropMQSNodeReq(pQuery->pCmdMsg->pMsg, pQuery->pCmdMsg->msgLen, &req));
|
||||
|
||||
ASSERT_EQ(req.dnodeId, expect.dnodeId);
|
||||
});
|
||||
|
||||
setCreateQnodeReq(1);
|
||||
run("CREATE QNODE ON DNODE 1");
|
||||
}
|
||||
|
||||
/*
|
||||
* CREATE SMA INDEX index_name ON tb_name index_option
|
||||
*
|
||||
* index_option:
|
||||
* FUNCTION(functions) INTERVAL(interval_val [, interval_offset]) [SLIDING(sliding_val)]
|
||||
* [WATERMARK(watermark_val)] [MAX_DELAY(max_delay_val)]
|
||||
*
|
||||
* functions:
|
||||
* function [, function] ...
|
||||
*/
|
||||
TEST_F(ParserInitialCTest, createSmaIndex) {
|
||||
useDb("root", "test");
|
||||
|
||||
|
@ -456,24 +544,39 @@ TEST_F(ParserInitialCTest, createSmaIndex) {
|
|||
"DELETE_MARK 1000s");
|
||||
}
|
||||
|
||||
TEST_F(ParserInitialCTest, createMnode) {
|
||||
useDb("root", "test");
|
||||
|
||||
run("CREATE MNODE ON DNODE 1");
|
||||
}
|
||||
|
||||
TEST_F(ParserInitialCTest, createQnode) {
|
||||
useDb("root", "test");
|
||||
|
||||
run("CREATE QNODE ON DNODE 1");
|
||||
}
|
||||
|
||||
/*
|
||||
* CREATE SNODE ON DNODE dnode_id
|
||||
*/
|
||||
TEST_F(ParserInitialCTest, createSnode) {
|
||||
useDb("root", "test");
|
||||
|
||||
SMCreateSnodeReq expect = {0};
|
||||
|
||||
auto setCreateSnodeReq = [&](int32_t dnodeId) { expect.dnodeId = dnodeId; };
|
||||
|
||||
setCheckDdlFunc([&](const SQuery* pQuery, ParserStage stage) {
|
||||
ASSERT_EQ(nodeType(pQuery->pRoot), QUERY_NODE_CREATE_SNODE_STMT);
|
||||
SMCreateSnodeReq req = {0};
|
||||
ASSERT_TRUE(TSDB_CODE_SUCCESS ==
|
||||
tDeserializeSCreateDropMQSNodeReq(pQuery->pCmdMsg->pMsg, pQuery->pCmdMsg->msgLen, &req));
|
||||
|
||||
ASSERT_EQ(req.dnodeId, expect.dnodeId);
|
||||
});
|
||||
|
||||
setCreateSnodeReq(1);
|
||||
run("CREATE SNODE ON DNODE 1");
|
||||
}
|
||||
|
||||
/*
|
||||
* CREATE STABLE [IF NOT EXISTS] stb_name (create_definition [, create_definitionn] ...)
|
||||
* TAGS (create_definition [, create_definition] ...) [table_options]
|
||||
*
|
||||
* create_definition:
|
||||
* col_name column_definition
|
||||
*
|
||||
* column_definition:
|
||||
* type_name [COMMENT 'string_value']
|
||||
*/
|
||||
TEST_F(ParserInitialCTest, createStable) {
|
||||
useDb("root", "test");
|
||||
|
||||
|
@ -484,7 +587,7 @@ TEST_F(ParserInitialCTest, createStable) {
|
|||
memset(&expect, 0, sizeof(SMCreateStbReq));
|
||||
};
|
||||
|
||||
auto setCreateStbReqFunc =
|
||||
auto setCreateStbReq =
|
||||
[&](const char* pDbName, const char* pTbName, int8_t igExists = 0, int64_t delay1 = -1, int64_t delay2 = -1,
|
||||
int64_t watermark1 = TSDB_DEFAULT_ROLLUP_WATERMARK, int64_t watermark2 = TSDB_DEFAULT_ROLLUP_WATERMARK,
|
||||
int64_t deleteMark1 = TSDB_DEFAULT_ROLLUP_DELETE_MARK, int64_t deleteMark2 = TSDB_DEFAULT_ROLLUP_DELETE_MARK,
|
||||
|
@ -505,8 +608,8 @@ TEST_F(ParserInitialCTest, createStable) {
|
|||
}
|
||||
};
|
||||
|
||||
auto addFieldToCreateStbReqFunc = [&](bool col, const char* pFieldName, uint8_t type, int32_t bytes = 0,
|
||||
int8_t flags = COL_SMA_ON) {
|
||||
auto addFieldToCreateStbReq = [&](bool col, const char* pFieldName, uint8_t type, int32_t bytes = 0,
|
||||
int8_t flags = COL_SMA_ON) {
|
||||
SField field = {0};
|
||||
strcpy(field.name, pFieldName);
|
||||
field.type = type;
|
||||
|
@ -582,46 +685,46 @@ TEST_F(ParserInitialCTest, createStable) {
|
|||
tFreeSMCreateStbReq(&req);
|
||||
});
|
||||
|
||||
setCreateStbReqFunc("test", "t1");
|
||||
addFieldToCreateStbReqFunc(true, "ts", TSDB_DATA_TYPE_TIMESTAMP);
|
||||
addFieldToCreateStbReqFunc(true, "c1", TSDB_DATA_TYPE_INT);
|
||||
addFieldToCreateStbReqFunc(false, "id", TSDB_DATA_TYPE_INT);
|
||||
setCreateStbReq("test", "t1");
|
||||
addFieldToCreateStbReq(true, "ts", TSDB_DATA_TYPE_TIMESTAMP);
|
||||
addFieldToCreateStbReq(true, "c1", TSDB_DATA_TYPE_INT);
|
||||
addFieldToCreateStbReq(false, "id", TSDB_DATA_TYPE_INT);
|
||||
run("CREATE STABLE t1(ts TIMESTAMP, c1 INT) TAGS(id INT)");
|
||||
clearCreateStbReq();
|
||||
|
||||
setCreateStbReqFunc("rollup_db", "t1", 1, 100 * MILLISECOND_PER_SECOND, 10 * MILLISECOND_PER_MINUTE, 10,
|
||||
1 * MILLISECOND_PER_MINUTE, 1000 * MILLISECOND_PER_SECOND, 200 * MILLISECOND_PER_MINUTE, 100,
|
||||
"test create table");
|
||||
addFieldToCreateStbReqFunc(true, "ts", TSDB_DATA_TYPE_TIMESTAMP, 0, 0);
|
||||
addFieldToCreateStbReqFunc(true, "c1", TSDB_DATA_TYPE_INT);
|
||||
addFieldToCreateStbReqFunc(true, "c2", TSDB_DATA_TYPE_UINT);
|
||||
addFieldToCreateStbReqFunc(true, "c3", TSDB_DATA_TYPE_BIGINT);
|
||||
addFieldToCreateStbReqFunc(true, "c4", TSDB_DATA_TYPE_UBIGINT, 0, 0);
|
||||
addFieldToCreateStbReqFunc(true, "c5", TSDB_DATA_TYPE_FLOAT, 0, 0);
|
||||
addFieldToCreateStbReqFunc(true, "c6", TSDB_DATA_TYPE_DOUBLE, 0, 0);
|
||||
addFieldToCreateStbReqFunc(true, "c7", TSDB_DATA_TYPE_BINARY, 20 + VARSTR_HEADER_SIZE, 0);
|
||||
addFieldToCreateStbReqFunc(true, "c8", TSDB_DATA_TYPE_SMALLINT, 0, 0);
|
||||
addFieldToCreateStbReqFunc(true, "c9", TSDB_DATA_TYPE_USMALLINT, 0, 0);
|
||||
addFieldToCreateStbReqFunc(true, "c10", TSDB_DATA_TYPE_TINYINT, 0, 0);
|
||||
addFieldToCreateStbReqFunc(true, "c11", TSDB_DATA_TYPE_UTINYINT, 0, 0);
|
||||
addFieldToCreateStbReqFunc(true, "c12", TSDB_DATA_TYPE_BOOL, 0, 0);
|
||||
addFieldToCreateStbReqFunc(true, "c13", TSDB_DATA_TYPE_NCHAR, 30 * TSDB_NCHAR_SIZE + VARSTR_HEADER_SIZE, 0);
|
||||
addFieldToCreateStbReqFunc(true, "c14", TSDB_DATA_TYPE_VARCHAR, 50 + VARSTR_HEADER_SIZE, 0);
|
||||
addFieldToCreateStbReqFunc(false, "a1", TSDB_DATA_TYPE_TIMESTAMP);
|
||||
addFieldToCreateStbReqFunc(false, "a2", TSDB_DATA_TYPE_INT);
|
||||
addFieldToCreateStbReqFunc(false, "a3", TSDB_DATA_TYPE_UINT);
|
||||
addFieldToCreateStbReqFunc(false, "a4", TSDB_DATA_TYPE_BIGINT);
|
||||
addFieldToCreateStbReqFunc(false, "a5", TSDB_DATA_TYPE_UBIGINT);
|
||||
addFieldToCreateStbReqFunc(false, "a6", TSDB_DATA_TYPE_FLOAT);
|
||||
addFieldToCreateStbReqFunc(false, "a7", TSDB_DATA_TYPE_DOUBLE);
|
||||
addFieldToCreateStbReqFunc(false, "a8", TSDB_DATA_TYPE_BINARY, 20 + VARSTR_HEADER_SIZE);
|
||||
addFieldToCreateStbReqFunc(false, "a9", TSDB_DATA_TYPE_SMALLINT);
|
||||
addFieldToCreateStbReqFunc(false, "a10", TSDB_DATA_TYPE_USMALLINT);
|
||||
addFieldToCreateStbReqFunc(false, "a11", TSDB_DATA_TYPE_TINYINT);
|
||||
addFieldToCreateStbReqFunc(false, "a12", TSDB_DATA_TYPE_UTINYINT);
|
||||
addFieldToCreateStbReqFunc(false, "a13", TSDB_DATA_TYPE_BOOL);
|
||||
addFieldToCreateStbReqFunc(false, "a14", TSDB_DATA_TYPE_NCHAR, 30 * TSDB_NCHAR_SIZE + VARSTR_HEADER_SIZE);
|
||||
addFieldToCreateStbReqFunc(false, "a15", TSDB_DATA_TYPE_VARCHAR, 50 + VARSTR_HEADER_SIZE);
|
||||
setCreateStbReq("rollup_db", "t1", 1, 100 * MILLISECOND_PER_SECOND, 10 * MILLISECOND_PER_MINUTE, 10,
|
||||
1 * MILLISECOND_PER_MINUTE, 1000 * MILLISECOND_PER_SECOND, 200 * MILLISECOND_PER_MINUTE, 100,
|
||||
"test create table");
|
||||
addFieldToCreateStbReq(true, "ts", TSDB_DATA_TYPE_TIMESTAMP, 0, 0);
|
||||
addFieldToCreateStbReq(true, "c1", TSDB_DATA_TYPE_INT);
|
||||
addFieldToCreateStbReq(true, "c2", TSDB_DATA_TYPE_UINT);
|
||||
addFieldToCreateStbReq(true, "c3", TSDB_DATA_TYPE_BIGINT);
|
||||
addFieldToCreateStbReq(true, "c4", TSDB_DATA_TYPE_UBIGINT, 0, 0);
|
||||
addFieldToCreateStbReq(true, "c5", TSDB_DATA_TYPE_FLOAT, 0, 0);
|
||||
addFieldToCreateStbReq(true, "c6", TSDB_DATA_TYPE_DOUBLE, 0, 0);
|
||||
addFieldToCreateStbReq(true, "c7", TSDB_DATA_TYPE_BINARY, 20 + VARSTR_HEADER_SIZE, 0);
|
||||
addFieldToCreateStbReq(true, "c8", TSDB_DATA_TYPE_SMALLINT, 0, 0);
|
||||
addFieldToCreateStbReq(true, "c9", TSDB_DATA_TYPE_USMALLINT, 0, 0);
|
||||
addFieldToCreateStbReq(true, "c10", TSDB_DATA_TYPE_TINYINT, 0, 0);
|
||||
addFieldToCreateStbReq(true, "c11", TSDB_DATA_TYPE_UTINYINT, 0, 0);
|
||||
addFieldToCreateStbReq(true, "c12", TSDB_DATA_TYPE_BOOL, 0, 0);
|
||||
addFieldToCreateStbReq(true, "c13", TSDB_DATA_TYPE_NCHAR, 30 * TSDB_NCHAR_SIZE + VARSTR_HEADER_SIZE, 0);
|
||||
addFieldToCreateStbReq(true, "c14", TSDB_DATA_TYPE_VARCHAR, 50 + VARSTR_HEADER_SIZE, 0);
|
||||
addFieldToCreateStbReq(false, "a1", TSDB_DATA_TYPE_TIMESTAMP);
|
||||
addFieldToCreateStbReq(false, "a2", TSDB_DATA_TYPE_INT);
|
||||
addFieldToCreateStbReq(false, "a3", TSDB_DATA_TYPE_UINT);
|
||||
addFieldToCreateStbReq(false, "a4", TSDB_DATA_TYPE_BIGINT);
|
||||
addFieldToCreateStbReq(false, "a5", TSDB_DATA_TYPE_UBIGINT);
|
||||
addFieldToCreateStbReq(false, "a6", TSDB_DATA_TYPE_FLOAT);
|
||||
addFieldToCreateStbReq(false, "a7", TSDB_DATA_TYPE_DOUBLE);
|
||||
addFieldToCreateStbReq(false, "a8", TSDB_DATA_TYPE_BINARY, 20 + VARSTR_HEADER_SIZE);
|
||||
addFieldToCreateStbReq(false, "a9", TSDB_DATA_TYPE_SMALLINT);
|
||||
addFieldToCreateStbReq(false, "a10", TSDB_DATA_TYPE_USMALLINT);
|
||||
addFieldToCreateStbReq(false, "a11", TSDB_DATA_TYPE_TINYINT);
|
||||
addFieldToCreateStbReq(false, "a12", TSDB_DATA_TYPE_UTINYINT);
|
||||
addFieldToCreateStbReq(false, "a13", TSDB_DATA_TYPE_BOOL);
|
||||
addFieldToCreateStbReq(false, "a14", TSDB_DATA_TYPE_NCHAR, 30 * TSDB_NCHAR_SIZE + VARSTR_HEADER_SIZE);
|
||||
addFieldToCreateStbReq(false, "a15", TSDB_DATA_TYPE_VARCHAR, 50 + VARSTR_HEADER_SIZE);
|
||||
run("CREATE STABLE IF NOT EXISTS rollup_db.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, "
|
||||
|
@ -647,6 +750,20 @@ TEST_F(ParserInitialCTest, createStableSemanticCheck) {
|
|||
TSDB_CODE_PAR_INVALID_TABLE_OPTION);
|
||||
}
|
||||
|
||||
/*
|
||||
* CREATE STREAM [IF NOT EXISTS] stream_name [stream_options]
|
||||
* INTO stb_name [TAGS (create_definition [, create_definition] ...)] [SUBTABLE (expr)] AS subquery
|
||||
*
|
||||
* stream_options:
|
||||
* stream_option ...
|
||||
*
|
||||
* stream_option: {
|
||||
* TRIGGER [AT_ONCE | WINDOW_CLOSE | MAX_DELAY time]
|
||||
* | WATERMARK time
|
||||
* | IGNORE EXPIRED value
|
||||
* | FILL_HISTORY value
|
||||
* }
|
||||
*/
|
||||
TEST_F(ParserInitialCTest, createStream) {
|
||||
useDb("root", "test");
|
||||
|
||||
|
@ -751,9 +868,103 @@ TEST_F(ParserInitialCTest, createStreamSemanticCheck) {
|
|||
TSDB_CODE_PAR_STREAM_NOT_ALLOWED_FUNC);
|
||||
}
|
||||
|
||||
/*
|
||||
* CREATE TABLE [IF NOT EXISTS] [db_name.]tb_name (create_definition [, create_definitionn] ...) [table_options]
|
||||
*
|
||||
* CREATE TABLE create_subtable_clause
|
||||
*
|
||||
* CREATE TABLE [IF NOT EXISTS] [db_name.]tb_name (create_definition [, create_definitionn] ...)
|
||||
* [TAGS (create_definition [, create_definitionn] ...)]
|
||||
* [table_options]
|
||||
*
|
||||
* create_subtable_clause: {
|
||||
* create_subtable_clause [create_subtable_clause] ...
|
||||
* | [IF NOT EXISTS] [db_name.]tb_name USING [db_name.]stb_name [(tag_name [, tag_name] ...)]
|
||||
* TAGS (tag_value [, tag_value] ...)
|
||||
* }
|
||||
*
|
||||
* create_definition:
|
||||
* col_name column_definition
|
||||
*
|
||||
* column_definition:
|
||||
* type_name [comment 'string_value']
|
||||
*
|
||||
* table_options:
|
||||
* table_option ...
|
||||
*
|
||||
* table_option: {
|
||||
* COMMENT 'string_value'
|
||||
* | WATERMARK duration[,duration]
|
||||
* | MAX_DELAY duration[,duration]
|
||||
* | ROLLUP(func_name [, func_name] ...)
|
||||
* | SMA(col_name [, col_name] ...)
|
||||
* | TTL value
|
||||
* }
|
||||
*/
|
||||
TEST_F(ParserInitialCTest, createTable) {
|
||||
useDb("root", "test");
|
||||
|
||||
SVCreateTbBatchReq expect = {0};
|
||||
|
||||
auto addCreateTbReq = [&](const char* pName, bool ignoreExists = false, int32_t ttl = TSDB_DEFAULT_TABLE_TTL,
|
||||
const char* pComment = nullptr) {
|
||||
SVCreateTbReq req = {0};
|
||||
req.name = strdup(pName);
|
||||
if (ignoreExists) {
|
||||
req.flags |= TD_CREATE_IF_NOT_EXISTS;
|
||||
}
|
||||
req.ttl = ttl;
|
||||
if (nullptr != pComment) {
|
||||
req.comment = strdup(pComment);
|
||||
req.commentLen = strlen(pComment);
|
||||
}
|
||||
++expect.nReqs;
|
||||
if (nullptr == expect.pArray) {
|
||||
expect.pArray = taosArrayInit(TARRAY_MIN_SIZE, sizeof(SVCreateTbReq));
|
||||
}
|
||||
taosArrayPush(expect.pArray, &req);
|
||||
};
|
||||
|
||||
setCheckDdlFunc([&](const SQuery* pQuery, ParserStage stage) {
|
||||
return; // todo
|
||||
ASSERT_EQ(nodeType(pQuery->pRoot), QUERY_NODE_VNODE_MODIFY_STMT);
|
||||
SVnodeModifyOpStmt* pStmt = (SVnodeModifyOpStmt*)pQuery->pRoot;
|
||||
|
||||
ASSERT_EQ(pStmt->sqlNodeType, QUERY_NODE_CREATE_TABLE_STMT);
|
||||
ASSERT_NE(pStmt->pDataBlocks, nullptr);
|
||||
int32_t numOfBlocks = taosArrayGetSize(pStmt->pDataBlocks);
|
||||
for (int32_t i = 0; i < numOfBlocks; ++i) {
|
||||
SVgDataBlocks* pVgData = (SVgDataBlocks*)taosArrayGetP(pStmt->pDataBlocks, i);
|
||||
void* pBuf = POINTER_SHIFT(pVgData->pData, sizeof(SMsgHead));
|
||||
SVCreateTbBatchReq req = {0};
|
||||
SDecoder coder = {0};
|
||||
tDecoderInit(&coder, (uint8_t*)pBuf, pVgData->size);
|
||||
ASSERT_EQ(tDecodeSVCreateTbBatchReq(&coder, &req), TSDB_CODE_SUCCESS);
|
||||
ASSERT_EQ(req.nReqs, expect.nReqs);
|
||||
for (int32_t j = 0; j < req.nReqs; ++j) {
|
||||
SVCreateTbReq* pReq = req.pReqs + j;
|
||||
SVCreateTbReq* pExpect = (SVCreateTbReq*)taosArrayGet(expect.pArray, j);
|
||||
ASSERT_EQ(pReq->flags, pExpect->flags);
|
||||
ASSERT_EQ(std::string(pReq->name), std::string(pExpect->name));
|
||||
ASSERT_EQ(pReq->uid, pExpect->uid);
|
||||
ASSERT_EQ(pReq->ctime, pExpect->ctime);
|
||||
ASSERT_EQ(pReq->ttl, pExpect->ttl);
|
||||
ASSERT_EQ(pReq->commentLen, pExpect->commentLen);
|
||||
ASSERT_EQ(std::string(pReq->comment), std::string(pExpect->comment));
|
||||
ASSERT_EQ(pReq->type, pExpect->type);
|
||||
if (TD_NORMAL_TABLE == pExpect->type) {
|
||||
ASSERT_EQ(pReq->ntb.schemaRow.version, pExpect->ntb.schemaRow.version);
|
||||
ASSERT_EQ(pReq->ntb.schemaRow.nCols, pExpect->ntb.schemaRow.nCols);
|
||||
} else if (TD_CHILD_TABLE == pExpect->type) {
|
||||
ASSERT_EQ(std::string(pReq->ctb.stbName), std::string(pExpect->ctb.stbName));
|
||||
ASSERT_EQ(pReq->ctb.tagNum, pExpect->ctb.tagNum);
|
||||
ASSERT_EQ(pReq->ctb.suid, pExpect->ctb.suid);
|
||||
}
|
||||
}
|
||||
tDecoderClear(&coder);
|
||||
}
|
||||
});
|
||||
|
||||
run("CREATE TABLE t1(ts TIMESTAMP, c1 INT)");
|
||||
|
||||
run("CREATE TABLE IF NOT EXISTS test.t1("
|
||||
|
@ -778,7 +989,7 @@ TEST_F(ParserInitialCTest, createTable) {
|
|||
"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') ");
|
||||
|
||||
// run("CREATE TABLE IF NOT EXISTS t1 USING st1 TAGS(1, 'wxy', NOW + 1S)");
|
||||
run("CREATE TABLE IF NOT EXISTS t1 USING st1 TAGS(1, 'wxy', NOW + 1S)");
|
||||
}
|
||||
|
||||
TEST_F(ParserInitialCTest, createTableSemanticCheck) {
|
||||
|
@ -796,6 +1007,11 @@ TEST_F(ParserInitialCTest, createTableSemanticCheck) {
|
|||
run(sql, TSDB_CODE_PAR_TOO_MANY_COLUMNS);
|
||||
}
|
||||
|
||||
/*
|
||||
* CREATE TOPIC [IF NOT EXISTS] topic_name AS subquery
|
||||
*
|
||||
* CREATE TOPIC [IF NOT EXISTS] topic_name [WITH META] AS {DATABASE db_name | STABLE stb_name }
|
||||
*/
|
||||
TEST_F(ParserInitialCTest, createTopic) {
|
||||
useDb("root", "test");
|
||||
|
||||
|
@ -803,8 +1019,8 @@ TEST_F(ParserInitialCTest, createTopic) {
|
|||
|
||||
auto clearCreateTopicReq = [&]() { memset(&expect, 0, sizeof(SCMCreateTopicReq)); };
|
||||
|
||||
auto setCreateTopicReqFunc = [&](const char* pTopicName, int8_t igExists, const char* pSql, const char* pAst,
|
||||
const char* pDbName = nullptr, const char* pTbname = nullptr, int8_t withMeta = 0) {
|
||||
auto setCreateTopicReq = [&](const char* pTopicName, int8_t igExists, const char* pSql, const char* pAst,
|
||||
const char* pDbName = nullptr, const char* pTbname = nullptr, int8_t withMeta = 0) {
|
||||
snprintf(expect.name, sizeof(expect.name), "0.%s", pTopicName);
|
||||
expect.igExists = igExists;
|
||||
expect.sql = (char*)pSql;
|
||||
|
@ -848,31 +1064,34 @@ TEST_F(ParserInitialCTest, createTopic) {
|
|||
tFreeSCMCreateTopicReq(&req);
|
||||
});
|
||||
|
||||
setCreateTopicReqFunc("tp1", 0, "create topic tp1 as select * from t1", "ast");
|
||||
setCreateTopicReq("tp1", 0, "create topic tp1 as select * from t1", "ast");
|
||||
run("CREATE TOPIC tp1 AS SELECT * FROM t1");
|
||||
clearCreateTopicReq();
|
||||
|
||||
setCreateTopicReqFunc("tp1", 1, "create topic if not exists tp1 as select ts, ceil(c1) from t1", "ast");
|
||||
setCreateTopicReq("tp1", 1, "create topic if not exists tp1 as select ts, ceil(c1) from t1", "ast");
|
||||
run("CREATE TOPIC IF NOT EXISTS tp1 AS SELECT ts, CEIL(c1) FROM t1");
|
||||
clearCreateTopicReq();
|
||||
|
||||
setCreateTopicReqFunc("tp1", 0, "create topic tp1 as database test", nullptr, "test");
|
||||
setCreateTopicReq("tp1", 0, "create topic tp1 as database test", nullptr, "test");
|
||||
run("CREATE TOPIC tp1 AS DATABASE test");
|
||||
clearCreateTopicReq();
|
||||
|
||||
setCreateTopicReqFunc("tp1", 0, "create topic tp1 with meta as database test", nullptr, "test", nullptr, 1);
|
||||
setCreateTopicReq("tp1", 0, "create topic tp1 with meta as database test", nullptr, "test", nullptr, 1);
|
||||
run("CREATE TOPIC tp1 WITH META AS DATABASE test");
|
||||
clearCreateTopicReq();
|
||||
|
||||
setCreateTopicReqFunc("tp1", 1, "create topic if not exists tp1 as stable st1", nullptr, "test", "st1");
|
||||
setCreateTopicReq("tp1", 1, "create topic if not exists tp1 as stable st1", nullptr, "test", "st1");
|
||||
run("CREATE TOPIC IF NOT EXISTS tp1 AS STABLE st1");
|
||||
clearCreateTopicReq();
|
||||
|
||||
setCreateTopicReqFunc("tp1", 1, "create topic if not exists tp1 with meta as stable st1", nullptr, "test", "st1", 1);
|
||||
setCreateTopicReq("tp1", 1, "create topic if not exists tp1 with meta as stable st1", nullptr, "test", "st1", 1);
|
||||
run("CREATE TOPIC IF NOT EXISTS tp1 WITH META AS STABLE st1");
|
||||
clearCreateTopicReq();
|
||||
}
|
||||
|
||||
/*
|
||||
* CREATE USER use_name PASS password [SYSINFO value]
|
||||
*/
|
||||
TEST_F(ParserInitialCTest, createUser) {
|
||||
useDb("root", "test");
|
||||
|
||||
|
|
|
@ -99,7 +99,7 @@ TEST_F(ParserInitialDTest, dropDnode) {
|
|||
expect.force = force;
|
||||
};
|
||||
|
||||
auto setDropDnodeReqByEndpoint = [&](const char* pFqdn, int32_t port, bool force = false) {
|
||||
auto setDropDnodeReqByEndpoint = [&](const char* pFqdn, int32_t port = tsServerPort, bool force = false) {
|
||||
strcpy(expect.fqdn, pFqdn);
|
||||
expect.port = port;
|
||||
expect.force = force;
|
||||
|
@ -131,6 +131,14 @@ TEST_F(ParserInitialDTest, dropDnode) {
|
|||
setDropDnodeReqByEndpoint("host2", 8030, true);
|
||||
run("DROP DNODE 'host2:8030' FORCE");
|
||||
clearDropDnodeReq();
|
||||
|
||||
setDropDnodeReqByEndpoint("host1");
|
||||
run("DROP DNODE host1");
|
||||
clearDropDnodeReq();
|
||||
|
||||
setDropDnodeReqByEndpoint("host2", tsServerPort, true);
|
||||
run("DROP DNODE host2 FORCE");
|
||||
clearDropDnodeReq();
|
||||
}
|
||||
|
||||
// todo DROP function
|
||||
|
@ -174,7 +182,21 @@ TEST_F(ParserInitialDTest, dropMnode) {
|
|||
TEST_F(ParserInitialDTest, dropQnode) {
|
||||
useDb("root", "test");
|
||||
|
||||
run("DROP qnode on dnode 1");
|
||||
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) {
|
||||
|
@ -237,7 +259,20 @@ TEST_F(ParserInitialDTest, dropUser) {
|
|||
login("root");
|
||||
useDb("root", "test");
|
||||
|
||||
run("DROP user wxy");
|
||||
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");
|
||||
}
|
||||
|
||||
} // namespace ParserTest
|
||||
|
|
|
@ -112,7 +112,11 @@ int32_t streamScanExec(SStreamTask* pTask, int32_t batchSz) {
|
|||
ASSERT(0);
|
||||
}
|
||||
if (output == NULL) {
|
||||
finished = true;
|
||||
if (qStreamRecoverScanFinished(exec)) {
|
||||
finished = true;
|
||||
} else {
|
||||
qSetStreamOpOpen(exec);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#define ALLOW_FORBID_FUNC
|
||||
#define _DEFAULT_SOURCE
|
||||
#include "os.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef WINDOWS
|
||||
void swapStr(char* j, char* J, int width) {
|
||||
|
@ -33,16 +34,5 @@ void swapStr(char* j, char* J, int width) {
|
|||
|
||||
// todo refactor: 1) move away; 2) use merge sort instead; 3) qsort is not a stable sort actually.
|
||||
void taosSort(void* arr, int64_t sz, int64_t width, __compar_fn_t compar) {
|
||||
#ifdef WINDOWS
|
||||
int64_t i, j;
|
||||
for (i = 0; i < sz - 1; i++) {
|
||||
for (j = 0; j < sz - 1 - i; j++) {
|
||||
if (compar((char*)arr + j * width, (char*)arr + (j + 1) * width) > 0.00) {
|
||||
swapStr((char*)arr + j * width, (char*)arr + (j + 1) * width, width);
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
qsort(arr, sz, width, compar);
|
||||
#endif
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue