From 607f8163d3da22c1587d207a76146a06a8376abb Mon Sep 17 00:00:00 2001 From: wangmm0220 Date: Sun, 10 Jul 2022 18:54:58 +0800 Subject: [PATCH 001/153] feat:add logic for get_tmq_meta_json --- include/client/taos.h | 4 +- include/common/tdataformat.h | 3 +- include/common/tmsg.h | 6 + include/libs/parser/parser.h | 6 +- source/client/src/clientSml.c | 2 +- source/client/src/clientStmt.c | 11 +- source/client/src/tmq.c | 233 ++++++++++++++---- source/common/src/tmsg.c | 16 ++ source/dnode/mnode/impl/src/mndStb.c | 12 +- source/libs/parser/src/parInsert.c | 38 +-- source/libs/parser/src/parTranslater.c | 18 +- source/libs/parser/src/parUtil.c | 3 +- source/libs/scalar/src/sclfunc.c | 2 +- .../libs/scalar/test/scalar/scalarTests.cpp | 4 +- 14 files changed, 261 insertions(+), 97 deletions(-) diff --git a/include/client/taos.h b/include/client/taos.h index 362782b420..690c473986 100644 --- a/include/client/taos.h +++ b/include/client/taos.h @@ -265,7 +265,9 @@ typedef struct tmq_raw_data tmq_raw_data; DLL_EXPORT tmq_res_t tmq_get_res_type(TAOS_RES *res); DLL_EXPORT tmq_raw_data *tmq_get_raw_meta(TAOS_RES *res); DLL_EXPORT int32_t taos_write_raw_meta(TAOS *taos, tmq_raw_data *raw_meta); -DLL_EXPORT char *tmq_get_json_meta(TAOS_RES *res); // Returning null means error. Returned result need to be freed. +DLL_EXPORT void tmq_free_raw_meta(tmq_raw_data *rawMeta); +DLL_EXPORT char *tmq_get_json_meta(TAOS_RES *res); // Returning null means error. Returned result need to be freed by tmq_free_json_meta +DLL_EXPORT void tmq_free_json_meta(char* jsonMeta); DLL_EXPORT const char *tmq_get_topic_name(TAOS_RES *res); DLL_EXPORT const char *tmq_get_db_name(TAOS_RES *res); DLL_EXPORT int32_t tmq_get_vgroup_id(TAOS_RES *res); diff --git a/include/common/tdataformat.h b/include/common/tdataformat.h index e70008e4ef..95ab12b94e 100644 --- a/include/common/tdataformat.h +++ b/include/common/tdataformat.h @@ -78,7 +78,7 @@ int32_t tEncodeTag(SEncoder *pEncoder, const STag *pTag); int32_t tDecodeTag(SDecoder *pDecoder, STag **ppTag); int32_t tTagToValArray(const STag *pTag, SArray **ppArray); void debugPrintSTag(STag *pTag, const char *tag, int32_t ln); // TODO: remove -int32_t parseJsontoTagData(const char* json, SArray* pTagVals, STag** ppTag, void* pMsgBuf); +int32_t parseJsontoTagData(const char* json, SArray* pTagVals, STag** ppTag, void* pMsgBuf, const char* colName); // STRUCT ================= struct STColumn { @@ -147,6 +147,7 @@ struct SColVal { #pragma pack(push, 1) struct STagVal { + char colName[TSDB_COL_NAME_LEN]; // only used for tmq_get_meta union { int16_t cid; char *pKey; diff --git a/include/common/tmsg.h b/include/common/tmsg.h index 896ea27598..6140d30771 100644 --- a/include/common/tmsg.h +++ b/include/common/tmsg.h @@ -1915,6 +1915,8 @@ typedef struct SVCreateStbReq { SSchemaWrapper schemaRow; SSchemaWrapper schemaTag; SRSmaParam rsmaParam; + int32_t alterOriDataLen; + void* alterOriData; } SVCreateStbReq; int tEncodeSVCreateStbReq(SEncoder* pCoder, const SVCreateStbReq* pReq); @@ -1942,6 +1944,7 @@ typedef struct SVCreateTbReq { int8_t type; union { struct { + char* name; tb_uid_t suid; uint8_t* pTag; } ctb; @@ -1959,6 +1962,7 @@ static FORCE_INLINE void tdDestroySVCreateTbReq(SVCreateTbReq* req) { taosMemoryFreeClear(req->comment); if (req->type == TSDB_CHILD_TABLE) { taosMemoryFreeClear(req->ctb.pTag); + taosMemoryFreeClear(req->ctb.name); } else if (req->type == TSDB_NORMAL_TABLE) { taosMemoryFreeClear(req->ntb.schemaRow.pSchema); } @@ -2042,12 +2046,14 @@ typedef struct { int32_t bytes; // TSDB_ALTER_TABLE_DROP_COLUMN // TSDB_ALTER_TABLE_UPDATE_COLUMN_BYTES + int8_t colModType; int32_t colModBytes; // TSDB_ALTER_TABLE_UPDATE_COLUMN_NAME char* colNewName; // TSDB_ALTER_TABLE_UPDATE_TAG_VAL char* tagName; int8_t isNull; + int8_t tagType; uint32_t nTagVal; uint8_t* pTagVal; // TSDB_ALTER_TABLE_UPDATE_OPTIONS diff --git a/include/libs/parser/parser.h b/include/libs/parser/parser.h index a4aec72d4f..a3de9164a2 100644 --- a/include/libs/parser/parser.h +++ b/include/libs/parser/parser.h @@ -29,7 +29,7 @@ struct SMetaData; typedef struct SStmtCallback { TAOS_STMT* pStmt; int32_t (*getTbNameFn)(TAOS_STMT*, char**); - int32_t (*setInfoFn)(TAOS_STMT*, STableMeta*, void*, char*, bool, SHashObj*, SHashObj*); + int32_t (*setInfoFn)(TAOS_STMT*, STableMeta*, void*, char*, bool, SHashObj*, SHashObj*, const char*); int32_t (*getExecInfoFn)(TAOS_STMT*, SHashObj**, SHashObj**); } SStmtCallback; @@ -84,7 +84,7 @@ int32_t qBindStmtSingleColValue(void* pBlock, TAOS_MULTI_BIND* bind, char* msgBu int32_t rowNum); int32_t qBuildStmtColFields(void* pDataBlock, int32_t* fieldNum, TAOS_FIELD_E** fields); int32_t qBuildStmtTagFields(void* pBlock, void* boundTags, int32_t* fieldNum, TAOS_FIELD_E** fields); -int32_t qBindStmtTagsValue(void* pBlock, void* boundTags, int64_t suid, char* tName, TAOS_MULTI_BIND* bind, +int32_t qBindStmtTagsValue(void* pBlock, void* boundTags, int64_t suid, const char* sTableName, char* tName, TAOS_MULTI_BIND* bind, char* msgBuf, int32_t msgBufLen); void destroyBoundColumnInfo(void* pBoundInfo); int32_t qCreateSName(SName* pName, const char* pTableName, int32_t acctId, char* dbName, char* msgBuf, @@ -93,7 +93,7 @@ int32_t qCreateSName(SName* pName, const char* pTableName, int32_t acctId, char* void* smlInitHandle(SQuery* pQuery); void smlDestroyHandle(void* pHandle); int32_t smlBindData(void* handle, SArray* tags, SArray* colsSchema, SArray* cols, bool format, STableMeta* pTableMeta, - char* tableName, char* msgBuf, int16_t msgBufLen); + char* tableName, const char* sTableName, int32_t sTableNameLen, char* msgBuf, int16_t msgBufLen); int32_t smlBuildOutput(void* handle, SHashObj* pVgHash); int32_t rewriteToVnodeModifyOpStmt(SQuery* pQuery, SArray* pBufArray); diff --git a/source/client/src/clientSml.c b/source/client/src/clientSml.c index b6972e4670..df62f25168 100644 --- a/source/client/src/clientSml.c +++ b/source/client/src/clientSml.c @@ -2256,7 +2256,7 @@ static int32_t smlInsertData(SSmlHandle *info) { (*pMeta)->tableMeta->uid = tableData->uid; // one table merge data block together according uid code = smlBindData(info->exec, tableData->tags, (*pMeta)->cols, tableData->cols, info->dataFormat, - (*pMeta)->tableMeta, tableData->childTableName, info->msgBuf.buf, info->msgBuf.len); + (*pMeta)->tableMeta, tableData->childTableName, tableData->sTableName, tableData->sTableNameLen, info->msgBuf.buf, info->msgBuf.len); if (code != TSDB_CODE_SUCCESS) { uError("SML:0x%" PRIx64 " smlBindData failed", info->id); return code; diff --git a/source/client/src/clientStmt.c b/source/client/src/clientStmt.c index 1e0f30695d..7287c46796 100644 --- a/source/client/src/clientStmt.c +++ b/source/client/src/clientStmt.c @@ -128,7 +128,7 @@ int32_t stmtRestoreQueryFields(STscStmt* pStmt) { return TSDB_CODE_SUCCESS; } -int32_t stmtUpdateBindInfo(TAOS_STMT* stmt, STableMeta* pTableMeta, void* tags, char* tbFName) { +int32_t stmtUpdateBindInfo(TAOS_STMT* stmt, STableMeta* pTableMeta, void* tags, char* tbFName, const char* sTableName) { STscStmt* pStmt = (STscStmt*)stmt; strncpy(pStmt->bInfo.tbFName, tbFName, sizeof(pStmt->bInfo.tbFName) - 1); @@ -139,6 +139,7 @@ int32_t stmtUpdateBindInfo(TAOS_STMT* stmt, STableMeta* pTableMeta, void* tags, pStmt->bInfo.tbType = pTableMeta->tableType; pStmt->bInfo.boundTags = tags; pStmt->bInfo.tagsCached = false; + strcpy(pStmt->bInfo.stbFName, sTableName); return TSDB_CODE_SUCCESS; } @@ -154,10 +155,10 @@ int32_t stmtUpdateExecInfo(TAOS_STMT* stmt, SHashObj* pVgHash, SHashObj* pBlockH } int32_t stmtUpdateInfo(TAOS_STMT* stmt, STableMeta* pTableMeta, void* tags, char* tbFName, bool autoCreateTbl, - SHashObj* pVgHash, SHashObj* pBlockHash) { + SHashObj* pVgHash, SHashObj* pBlockHash, const char* sTableName) { STscStmt* pStmt = (STscStmt*)stmt; - STMT_ERR_RET(stmtUpdateBindInfo(stmt, pTableMeta, tags, tbFName)); + STMT_ERR_RET(stmtUpdateBindInfo(stmt, pTableMeta, tags, tbFName, sTableName)); STMT_ERR_RET(stmtUpdateExecInfo(stmt, pVgHash, pBlockHash, autoCreateTbl)); pStmt->sql.autoCreateTbl = autoCreateTbl; @@ -247,7 +248,7 @@ int32_t stmtCleanBindInfo(STscStmt* pStmt) { destroyBoundColumnInfo(pStmt->bInfo.boundTags); taosMemoryFreeClear(pStmt->bInfo.boundTags); } - + memset(pStmt->bInfo.stbFName, 0, TSDB_TABLE_FNAME_LEN); return TSDB_CODE_SUCCESS; } @@ -568,7 +569,7 @@ int stmtSetTbTags(TAOS_STMT* stmt, TAOS_MULTI_BIND* tags) { STMT_ERR_RET(TSDB_CODE_QRY_APP_ERROR); } - STMT_ERR_RET(qBindStmtTagsValue(*pDataBlock, pStmt->bInfo.boundTags, pStmt->bInfo.tbSuid, pStmt->bInfo.sname.tname, + STMT_ERR_RET(qBindStmtTagsValue(*pDataBlock, pStmt->bInfo.boundTags, pStmt->bInfo.tbSuid, pStmt->bInfo.stbFName, pStmt->bInfo.sname.tname, tags, pStmt->exec.pRequest->msgBuf, pStmt->exec.pRequest->msgBufLen)); return TSDB_CODE_SUCCESS; diff --git a/source/client/src/tmq.c b/source/client/src/tmq.c index 907691698c..fa9f715be3 100644 --- a/source/client/src/tmq.c +++ b/source/client/src/tmq.c @@ -1867,10 +1867,10 @@ static char *buildCreateTableJson(SSchemaWrapper *schemaRow, SSchemaWrapper* sch cJSON* type = cJSON_CreateString("create"); cJSON_AddItemToObject(json, "type", type); - char uid[32] = {0}; - sprintf(uid, "%"PRIi64, id); - cJSON* id_ = cJSON_CreateString(uid); - cJSON_AddItemToObject(json, "id", id_); +// char uid[32] = {0}; +// sprintf(uid, "%"PRIi64, id); +// cJSON* id_ = cJSON_CreateString(uid); +// cJSON_AddItemToObject(json, "id", id_); cJSON* tableName = cJSON_CreateString(name); cJSON_AddItemToObject(json, "tableName", tableName); cJSON* tableType = cJSON_CreateString(t == TSDB_NORMAL_TABLE ? "normal" : "super"); @@ -1925,6 +1925,98 @@ static char *buildCreateTableJson(SSchemaWrapper *schemaRow, SSchemaWrapper* sch return string; } +static char *buildAlterSTableJson(void* alterData, int32_t alterDataLen){ + SMAlterStbReq req = {0}; + cJSON* json = NULL; + char* string = NULL; + + if (tDeserializeSMAlterStbReq(alterData, alterDataLen, &req) != 0) { + goto end; + } + + json = cJSON_CreateObject(); + if (json == NULL) { + goto end; + } + cJSON* type = cJSON_CreateString("alter"); + cJSON_AddItemToObject(json, "type", type); +// cJSON* uid = cJSON_CreateNumber(id); +// cJSON_AddItemToObject(json, "uid", uid); + SName name = {0}; + tNameFromString(&name, req.name, T_NAME_ACCT | T_NAME_DB | T_NAME_TABLE); + cJSON* tableName = cJSON_CreateString(name.tname); + cJSON_AddItemToObject(json, "tableName", tableName); + cJSON* tableType = cJSON_CreateString("super"); + cJSON_AddItemToObject(json, "tableType", tableType); + + cJSON* alterType = cJSON_CreateNumber(req.alterType); + cJSON_AddItemToObject(json, "alterType", alterType); + switch (req.alterType) { + case TSDB_ALTER_TABLE_ADD_TAG: + case TSDB_ALTER_TABLE_ADD_COLUMN: { + TAOS_FIELD *field = taosArrayGet(req.pFields, 0); + cJSON* colName = cJSON_CreateString(field->name); + cJSON_AddItemToObject(json, "colName", colName); + cJSON* colType = cJSON_CreateNumber(field->type); + cJSON_AddItemToObject(json, "colType", colType); + + if(field->type == TSDB_DATA_TYPE_BINARY){ + int32_t length = field->bytes - VARSTR_HEADER_SIZE; + cJSON* cbytes = cJSON_CreateNumber(length); + cJSON_AddItemToObject(json, "colLength", cbytes); + }else if (field->type == TSDB_DATA_TYPE_NCHAR){ + int32_t length = (field->bytes - VARSTR_HEADER_SIZE)/TSDB_NCHAR_SIZE; + cJSON* cbytes = cJSON_CreateNumber(length); + cJSON_AddItemToObject(json, "colLength", cbytes); + } + break; + } + case TSDB_ALTER_TABLE_DROP_TAG: + case TSDB_ALTER_TABLE_DROP_COLUMN:{ + TAOS_FIELD *field = taosArrayGet(req.pFields, 0); + cJSON* colName = cJSON_CreateString(field->name); + cJSON_AddItemToObject(json, "colName", colName); + break; + } + case TSDB_ALTER_TABLE_UPDATE_TAG_BYTES: + case TSDB_ALTER_TABLE_UPDATE_COLUMN_BYTES:{ + TAOS_FIELD *field = taosArrayGet(req.pFields, 0); + cJSON* colName = cJSON_CreateString(field->name); + cJSON_AddItemToObject(json, "colName", colName); + cJSON* colType = cJSON_CreateNumber(field->type); + cJSON_AddItemToObject(json, "colType", colType); + if(field->type == TSDB_DATA_TYPE_BINARY){ + int32_t length = field->bytes - VARSTR_HEADER_SIZE; + cJSON* cbytes = cJSON_CreateNumber(length); + cJSON_AddItemToObject(json, "colLength", cbytes); + }else if (field->type == TSDB_DATA_TYPE_NCHAR){ + int32_t length = (field->bytes - VARSTR_HEADER_SIZE)/TSDB_NCHAR_SIZE; + cJSON* cbytes = cJSON_CreateNumber(length); + cJSON_AddItemToObject(json, "colLength", cbytes); + } + break; + } + case TSDB_ALTER_TABLE_UPDATE_TAG_NAME: + case TSDB_ALTER_TABLE_UPDATE_COLUMN_NAME:{ + TAOS_FIELD *oldField = taosArrayGet(req.pFields, 0); + TAOS_FIELD *newField = taosArrayGet(req.pFields, 1); + cJSON* colName = cJSON_CreateString(oldField->name); + cJSON_AddItemToObject(json, "colName", colName); + cJSON* colNewName = cJSON_CreateString(newField->name); + cJSON_AddItemToObject(json, "colNewName", colNewName); + break; + } + default: + break; + } + string = cJSON_PrintUnformatted(json); + +end: + cJSON_Delete(json); + tFreeSMAltertbReq(&req); + return string; +} + static char *processCreateStb(SMqMetaRsp *metaRsp){ SVCreateStbReq req = {0}; SDecoder coder; @@ -1947,53 +2039,74 @@ _err: return string; } -static char *buildCreateCTableJson(STag* pTag, int64_t sid, char* name, int64_t id){ +static char *processAlterStb(SMqMetaRsp *metaRsp){ + SVCreateStbReq req = {0}; + SDecoder coder; char* string = NULL; + + // decode and process req + void* data = POINTER_SHIFT(metaRsp->metaRsp, sizeof(SMsgHead)); + int32_t len = metaRsp->metaRspLen - sizeof(SMsgHead); + tDecoderInit(&coder, data, len); + + if (tDecodeSVCreateStbReq(&coder, &req) < 0) { + goto _err; + } + string = buildAlterSTableJson(req.alterOriData, req.alterOriDataLen); + tDecoderClear(&coder); + return string; + + _err: + tDecoderClear(&coder); + return string; +} + +static char *buildCreateCTableJson(STag* pTag, char* sname, char* name, int64_t id){ + char* string = NULL; + SArray* pTagVals = NULL; cJSON* json = cJSON_CreateObject(); if (json == NULL) { return string; } cJSON* type = cJSON_CreateString("create"); cJSON_AddItemToObject(json, "type", type); - char cid[32] = {0}; - sprintf(cid, "%"PRIi64, id); - cJSON* cid_ = cJSON_CreateString(cid); - cJSON_AddItemToObject(json, "id", cid_); +// char cid[32] = {0}; +// sprintf(cid, "%"PRIi64, id); +// cJSON* cid_ = cJSON_CreateString(cid); +// cJSON_AddItemToObject(json, "id", cid_); cJSON* tableName = cJSON_CreateString(name); cJSON_AddItemToObject(json, "tableName", tableName); cJSON* tableType = cJSON_CreateString("child"); cJSON_AddItemToObject(json, "tableType", tableType); - - char sid_[32] = {0}; - sprintf(sid_, "%"PRIi64, sid); - cJSON* using = cJSON_CreateString(sid_); + cJSON* using = cJSON_CreateString(sname); cJSON_AddItemToObject(json, "using", using); // cJSON* version = cJSON_CreateNumber(1); // cJSON_AddItemToObject(json, "version", version); cJSON* tags = cJSON_CreateArray(); + int32_t code = tTagToValArray(pTag, &pTagVals); + if (code) { + goto end; + } - if (tTagIsJson(pTag)) { // todo + if (tTagIsJson(pTag)) { + STag* p = (STag*)pTag; + if(p->nTag == 0){ + goto end; + } char* pJson = parseTagDatatoJson(pTag); - cJSON* tag = cJSON_CreateObject(); - cJSON* tname = cJSON_CreateString("unknown"); // todo + STagVal* pTagVal = taosArrayGet(pTagVals, 0); + + cJSON* tname = cJSON_CreateString(pTagVal->colName); cJSON_AddItemToObject(tag, "name", tname); cJSON* ttype = cJSON_CreateNumber(TSDB_DATA_TYPE_JSON); cJSON_AddItemToObject(tag, "type", ttype); cJSON* tvalue = cJSON_CreateString(pJson); cJSON_AddItemToObject(tag, "value", tvalue); cJSON_AddItemToArray(tags, tag); - cJSON_AddItemToObject(json, "tags", tags); - - string = cJSON_PrintUnformatted(json); - goto end; - } - - SArray* pTagVals = NULL; - int32_t code = tTagToValArray(pTag, &pTagVals); - if (code) { + taosMemoryFree(pJson); goto end; } @@ -2001,8 +2114,7 @@ static char *buildCreateCTableJson(STag* pTag, int64_t sid, char* name, int64_t STagVal* pTagVal = (STagVal*)taosArrayGet(pTagVals, i); cJSON* tag = cJSON_CreateObject(); -// cJSON* tname = cJSON_CreateNumber(pTagVal->cid); - cJSON* tname = cJSON_CreateString("unkonwn"); // todo + cJSON* tname = cJSON_CreateString(pTagVal->colName); cJSON_AddItemToObject(tag, "name", tname); cJSON* ttype = cJSON_CreateNumber(pTagVal->type); cJSON_AddItemToObject(tag, "type", ttype); @@ -2021,12 +2133,12 @@ static char *buildCreateCTableJson(STag* pTag, int64_t sid, char* name, int64_t cJSON_AddItemToObject(tag, "value", tvalue); cJSON_AddItemToArray(tags, tag); } + + end: cJSON_AddItemToObject(json, "tags", tags); string = cJSON_PrintUnformatted(json); - -end: - cJSON_Delete(json); + taosArrayDestroy(pTagVals); return string; } @@ -2047,7 +2159,7 @@ static char *processCreateTable(SMqMetaRsp *metaRsp){ for (int32_t iReq = 0; iReq < req.nReqs; iReq++) { pCreateReq = req.pReqs + iReq; if(pCreateReq->type == TSDB_CHILD_TABLE){ - string = buildCreateCTableJson((STag*)pCreateReq->ctb.pTag, pCreateReq->ctb.suid, pCreateReq->name, pCreateReq->uid); + string = buildCreateCTableJson((STag*)pCreateReq->ctb.pTag, pCreateReq->ctb.name, pCreateReq->name, pCreateReq->uid); }else if(pCreateReq->type == TSDB_NORMAL_TABLE){ string = buildCreateTableJson(&pCreateReq->ntb.schemaRow, NULL, pCreateReq->name, pCreateReq->uid, TSDB_NORMAL_TABLE); } @@ -2085,11 +2197,11 @@ static char *processAlterTable(SMqMetaRsp *metaRsp){ cJSON_AddItemToObject(json, "tableName", tableName); cJSON* tableType = cJSON_CreateString(vAlterTbReq.action == TSDB_ALTER_TABLE_UPDATE_TAG_VAL ? "child" : "normal"); cJSON_AddItemToObject(json, "tableType", tableType); + cJSON* alterType = cJSON_CreateNumber(vAlterTbReq.action); + cJSON_AddItemToObject(json, "alterType", alterType); switch (vAlterTbReq.action) { case TSDB_ALTER_TABLE_ADD_COLUMN: { - cJSON* alterType = cJSON_CreateNumber(TSDB_ALTER_TABLE_ADD_COLUMN); - cJSON_AddItemToObject(json, "alterType", alterType); cJSON* colName = cJSON_CreateString(vAlterTbReq.colName); cJSON_AddItemToObject(json, "colName", colName); cJSON* colType = cJSON_CreateNumber(vAlterTbReq.type); @@ -2107,33 +2219,27 @@ static char *processAlterTable(SMqMetaRsp *metaRsp){ break; } case TSDB_ALTER_TABLE_DROP_COLUMN:{ - cJSON* alterType = cJSON_CreateNumber(TSDB_ALTER_TABLE_DROP_COLUMN); - cJSON_AddItemToObject(json, "alterType", alterType); cJSON* colName = cJSON_CreateString(vAlterTbReq.colName); cJSON_AddItemToObject(json, "colName", colName); break; } case TSDB_ALTER_TABLE_UPDATE_COLUMN_BYTES:{ - cJSON* alterType = cJSON_CreateNumber(TSDB_ALTER_TABLE_UPDATE_COLUMN_BYTES); - cJSON_AddItemToObject(json, "alterType", alterType); cJSON* colName = cJSON_CreateString(vAlterTbReq.colName); cJSON_AddItemToObject(json, "colName", colName); - cJSON* colType = cJSON_CreateNumber(vAlterTbReq.type); + cJSON* colType = cJSON_CreateNumber(vAlterTbReq.colModType); cJSON_AddItemToObject(json, "colType", colType); - if(vAlterTbReq.type == TSDB_DATA_TYPE_BINARY){ - int32_t length = vAlterTbReq.bytes - VARSTR_HEADER_SIZE; + if(vAlterTbReq.colModType == TSDB_DATA_TYPE_BINARY){ + int32_t length = vAlterTbReq.colModBytes - VARSTR_HEADER_SIZE; cJSON* cbytes = cJSON_CreateNumber(length); cJSON_AddItemToObject(json, "colLength", cbytes); - }else if (vAlterTbReq.type == TSDB_DATA_TYPE_NCHAR){ - int32_t length = (vAlterTbReq.bytes - VARSTR_HEADER_SIZE)/TSDB_NCHAR_SIZE; + }else if (vAlterTbReq.colModType == TSDB_DATA_TYPE_NCHAR){ + int32_t length = (vAlterTbReq.colModBytes - VARSTR_HEADER_SIZE)/TSDB_NCHAR_SIZE; cJSON* cbytes = cJSON_CreateNumber(length); cJSON_AddItemToObject(json, "colLength", cbytes); } break; } case TSDB_ALTER_TABLE_UPDATE_COLUMN_NAME:{ - cJSON* alterType = cJSON_CreateNumber(TSDB_ALTER_TABLE_UPDATE_COLUMN_NAME); - cJSON_AddItemToObject(json, "alterType", alterType); cJSON* colName = cJSON_CreateString(vAlterTbReq.colName); cJSON_AddItemToObject(json, "colName", colName); cJSON* colNewName = cJSON_CreateString(vAlterTbReq.colNewName); @@ -2141,12 +2247,25 @@ static char *processAlterTable(SMqMetaRsp *metaRsp){ break; } case TSDB_ALTER_TABLE_UPDATE_TAG_VAL:{ - cJSON* alterType = cJSON_CreateNumber(TSDB_ALTER_TABLE_UPDATE_TAG_VAL); - cJSON_AddItemToObject(json, "alterType", alterType); cJSON* tagName = cJSON_CreateString(vAlterTbReq.tagName); cJSON_AddItemToObject(json, "colName", tagName); - cJSON* colValue = cJSON_CreateString("invalid, todo"); // todo - cJSON_AddItemToObject(json, "colValue", colValue); + + if (!vAlterTbReq.isNull){ + char* buf = NULL; + + if (vAlterTbReq.tagType == TSDB_DATA_TYPE_JSON) { + ASSERT(tTagIsJson(vAlterTbReq.pTagVal) == true); + buf = parseTagDatatoJson(vAlterTbReq.pTagVal); + } else { + buf = taosMemoryCalloc(vAlterTbReq.nTagVal + 1, 1); + dataConverToStr(buf, vAlterTbReq.tagType, vAlterTbReq.pTagVal, vAlterTbReq.nTagVal, NULL); + } + + cJSON* colValue = cJSON_CreateString(buf); + cJSON_AddItemToObject(json, "colValue", colValue); + taosMemoryFree(buf); + } + cJSON* isNull = cJSON_CreateBool(vAlterTbReq.isNull); cJSON_AddItemToObject(json, "colValueNull", isNull); break; @@ -2180,10 +2299,6 @@ static char *processDropSTable(SMqMetaRsp *metaRsp){ } cJSON* type = cJSON_CreateString("drop"); cJSON_AddItemToObject(json, "type", type); - char uid[32] = {0}; - sprintf(uid, "%"PRIi64, req.suid); - cJSON* id = cJSON_CreateString(uid); - cJSON_AddItemToObject(json, "id", id); cJSON* tableName = cJSON_CreateString(req.name); cJSON_AddItemToObject(json, "tableName", tableName); cJSON* tableType = cJSON_CreateString("super"); @@ -2224,7 +2339,7 @@ static char *processDropTable(SMqMetaRsp *metaRsp){ for (int32_t iReq = 0; iReq < req.nReqs; iReq++) { SVDropTbReq* pDropTbReq = req.pReqs + iReq; - cJSON* tableName = cJSON_CreateString(pDropTbReq->name); // todo + cJSON* tableName = cJSON_CreateString(pDropTbReq->name); cJSON_AddItemToArray(tableNameList, tableName); } cJSON_AddItemToObject(json, "tableNameList", tableNameList); @@ -2245,7 +2360,7 @@ char *tmq_get_json_meta(TAOS_RES *res){ if(pMetaRspObj->metaRsp.resMsgType == TDMT_VND_CREATE_STB){ return processCreateStb(&pMetaRspObj->metaRsp); }else if(pMetaRspObj->metaRsp.resMsgType == TDMT_VND_ALTER_STB){ - return processCreateStb(&pMetaRspObj->metaRsp); + return processAlterStb(&pMetaRspObj->metaRsp); }else if(pMetaRspObj->metaRsp.resMsgType == TDMT_VND_DROP_STB){ return processDropSTable(&pMetaRspObj->metaRsp); }else if(pMetaRspObj->metaRsp.resMsgType == TDMT_VND_CREATE_TABLE){ @@ -2258,6 +2373,10 @@ char *tmq_get_json_meta(TAOS_RES *res){ return NULL; } +void tmq_free_json_meta(char* jsonMeta){ + taosMemoryFreeClear(jsonMeta); +} + static int32_t taosCreateStb(TAOS *taos, void *meta, int32_t metaLen){ SVCreateStbReq req = {0}; SDecoder coder; @@ -2310,6 +2429,7 @@ static int32_t taosCreateStb(TAOS *taos, void *meta, int32_t metaLen){ pReq.commentLen = -1; pReq.suid = req.suid; pReq.source = 1; + pReq.igExists = true; SName tableName; tNameExtractFullName(toName(pTscObj->acctId, pRequest->pDb, req.name, &tableName), pReq.name); @@ -2747,6 +2867,7 @@ end: } int32_t taos_write_raw_meta(TAOS *taos, tmq_raw_data *raw_meta){ + return 0; if (!taos || !raw_meta) { return TSDB_CODE_INVALID_PARA; } @@ -2767,6 +2888,10 @@ int32_t taos_write_raw_meta(TAOS *taos, tmq_raw_data *raw_meta){ return TSDB_CODE_INVALID_PARA; } +void tmq_free_raw_meta(tmq_raw_data *rawMeta){ + taosMemoryFreeClear(rawMeta); +} + void tmq_commit_async(tmq_t* tmq, const TAOS_RES* msg, tmq_commit_cb* cb, void* param) { tmqCommitInner2(tmq, msg, 0, 1, cb, param); } diff --git a/source/common/src/tmsg.c b/source/common/src/tmsg.c index 165e8631c4..0ffb4f6d2a 100644 --- a/source/common/src/tmsg.c +++ b/source/common/src/tmsg.c @@ -4803,6 +4803,11 @@ int tEncodeSVCreateStbReq(SEncoder *pCoder, const SVCreateStbReq *pReq) { if (tEncodeSRSmaParam(pCoder, &pReq->rsmaParam) < 0) return -1; } + if (tEncodeI32(pCoder, pReq->alterOriDataLen) < 0) return -1; + if (pReq->alterOriDataLen > 0) { + if (tEncodeBinary(pCoder, pReq->alterOriData, pReq->alterOriDataLen) < 0) return -1; + } + tEndEncode(pCoder); return 0; } @@ -4819,6 +4824,11 @@ int tDecodeSVCreateStbReq(SDecoder *pCoder, SVCreateStbReq *pReq) { if (tDecodeSRSmaParam(pCoder, &pReq->rsmaParam) < 0) return -1; } + if (tDecodeI32(pCoder, &pReq->alterOriDataLen) < 0) return -1; + if (pReq->alterOriDataLen > 0) { + if (tDecodeBinary(pCoder, (uint8_t **)&pReq->alterOriData, NULL) < 0) return -1; + } + tEndDecode(pCoder); return 0; } @@ -4862,6 +4872,7 @@ int tEncodeSVCreateTbReq(SEncoder *pCoder, const SVCreateTbReq *pReq) { } if (pReq->type == TSDB_CHILD_TABLE) { + if (tEncodeCStr(pCoder, pReq->ctb.name) < 0) return -1; if (tEncodeI64(pCoder, pReq->ctb.suid) < 0) return -1; if (tEncodeTag(pCoder, (const STag *)pReq->ctb.pTag) < 0) return -1; } else if (pReq->type == TSDB_NORMAL_TABLE) { @@ -4891,6 +4902,7 @@ int tDecodeSVCreateTbReq(SDecoder *pCoder, SVCreateTbReq *pReq) { } if (pReq->type == TSDB_CHILD_TABLE) { + if (tDecodeCStr(pCoder, &pReq->ctb.name) < 0) return -1; if (tDecodeI64(pCoder, &pReq->ctb.suid) < 0) return -1; if (tDecodeTag(pCoder, (STag **)&pReq->ctb.pTag) < 0) return -1; } else if (pReq->type == TSDB_NORMAL_TABLE) { @@ -5224,6 +5236,7 @@ int32_t tEncodeSVAlterTbReq(SEncoder *pEncoder, const SVAlterTbReq *pReq) { break; case TSDB_ALTER_TABLE_UPDATE_COLUMN_BYTES: if (tEncodeCStr(pEncoder, pReq->colName) < 0) return -1; + if (tEncodeI8(pEncoder, pReq->colModType) < 0) return -1; if (tEncodeI32v(pEncoder, pReq->colModBytes) < 0) return -1; break; case TSDB_ALTER_TABLE_UPDATE_COLUMN_NAME: @@ -5233,6 +5246,7 @@ int32_t tEncodeSVAlterTbReq(SEncoder *pEncoder, const SVAlterTbReq *pReq) { case TSDB_ALTER_TABLE_UPDATE_TAG_VAL: if (tEncodeCStr(pEncoder, pReq->tagName) < 0) return -1; if (tEncodeI8(pEncoder, pReq->isNull) < 0) return -1; + if (tEncodeI8(pEncoder, pReq->tagType) < 0) return -1; if (!pReq->isNull) { if (tEncodeBinary(pEncoder, pReq->pTagVal, pReq->nTagVal) < 0) return -1; } @@ -5272,6 +5286,7 @@ int32_t tDecodeSVAlterTbReq(SDecoder *pDecoder, SVAlterTbReq *pReq) { break; case TSDB_ALTER_TABLE_UPDATE_COLUMN_BYTES: if (tDecodeCStr(pDecoder, &pReq->colName) < 0) return -1; + if (tDecodeI8(pDecoder, &pReq->colModType) < 0) return -1; if (tDecodeI32v(pDecoder, &pReq->colModBytes) < 0) return -1; break; case TSDB_ALTER_TABLE_UPDATE_COLUMN_NAME: @@ -5281,6 +5296,7 @@ int32_t tDecodeSVAlterTbReq(SDecoder *pDecoder, SVAlterTbReq *pReq) { case TSDB_ALTER_TABLE_UPDATE_TAG_VAL: if (tDecodeCStr(pDecoder, &pReq->tagName) < 0) return -1; if (tDecodeI8(pDecoder, &pReq->isNull) < 0) return -1; + if (tDecodeI8(pDecoder, &pReq->tagType) < 0) return -1; if (!pReq->isNull) { if (tDecodeBinary(pDecoder, &pReq->pTagVal, &pReq->nTagVal) < 0) return -1; } diff --git a/source/dnode/mnode/impl/src/mndStb.c b/source/dnode/mnode/impl/src/mndStb.c index 6d1cc05ace..17885de60b 100644 --- a/source/dnode/mnode/impl/src/mndStb.c +++ b/source/dnode/mnode/impl/src/mndStb.c @@ -409,7 +409,7 @@ static FORCE_INLINE int32_t schemaExColIdCompare(const void *colId, const void * return 0; } -static void *mndBuildVCreateStbReq(SMnode *pMnode, SVgObj *pVgroup, SStbObj *pStb, int32_t *pContLen) { +static void *mndBuildVCreateStbReq(SMnode *pMnode, SVgObj *pVgroup, SStbObj *pStb, int32_t *pContLen, void* alterOriData, int32_t alterOriDataLen) { SEncoder encoder = {0}; int32_t contLen; SName name = {0}; @@ -422,6 +422,8 @@ static void *mndBuildVCreateStbReq(SMnode *pMnode, SVgObj *pVgroup, SStbObj *pSt req.name = (char *)tNameGetTableName(&name); req.suid = pStb->uid; req.rollup = pStb->ast1Len > 0 ? 1 : 0; + req.alterOriData = alterOriData; + req.alterOriDataLen = alterOriDataLen; // todo req.schemaRow.nCols = pStb->numOfColumns; req.schemaRow.version = pStb->colVer; @@ -626,7 +628,7 @@ static int32_t mndSetCreateStbRedoActions(SMnode *pMnode, STrans *pTrans, SDbObj continue; } - void *pReq = mndBuildVCreateStbReq(pMnode, pVgroup, pStb, &contLen); + void *pReq = mndBuildVCreateStbReq(pMnode, pVgroup, pStb, &contLen, NULL, 0); if (pReq == NULL) { sdbCancelFetch(pSdb, pIter); sdbRelease(pSdb, pVgroup); @@ -1278,7 +1280,7 @@ static int32_t mndSetAlterStbCommitLogs(SMnode *pMnode, STrans *pTrans, SDbObj * return 0; } -static int32_t mndSetAlterStbRedoActions(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SStbObj *pStb) { +static int32_t mndSetAlterStbRedoActions(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SStbObj *pStb, void* alterOriData, int32_t alterOriDataLen) { SSdb *pSdb = pMnode->pSdb; SVgObj *pVgroup = NULL; void *pIter = NULL; @@ -1292,7 +1294,7 @@ static int32_t mndSetAlterStbRedoActions(SMnode *pMnode, STrans *pTrans, SDbObj continue; } - void *pReq = mndBuildVCreateStbReq(pMnode, pVgroup, pStb, &contLen); + void *pReq = mndBuildVCreateStbReq(pMnode, pVgroup, pStb, &contLen, alterOriData, alterOriDataLen); if (pReq == NULL) { sdbCancelFetch(pSdb, pIter); sdbRelease(pSdb, pVgroup); @@ -1575,7 +1577,7 @@ static int32_t mndAlterStb(SMnode *pMnode, SRpcMsg *pReq, const SMAlterStbReq *p if (mndSetAlterStbRedoLogs(pMnode, pTrans, pDb, &stbObj) != 0) goto _OVER; if (mndSetAlterStbCommitLogs(pMnode, pTrans, pDb, &stbObj) != 0) goto _OVER; - if (mndSetAlterStbRedoActions(pMnode, pTrans, pDb, &stbObj) != 0) goto _OVER; + if (mndSetAlterStbRedoActions(pMnode, pTrans, pDb, &stbObj, pReq->pCont, pReq->contLen) != 0) goto _OVER; if (mndTransPrepare(pMnode, pTrans) != 0) goto _OVER; code = 0; diff --git a/source/libs/parser/src/parInsert.c b/source/libs/parser/src/parInsert.c index a5cf755a74..576dc6d8d3 100644 --- a/source/libs/parser/src/parInsert.c +++ b/source/libs/parser/src/parInsert.c @@ -71,6 +71,7 @@ typedef struct SInsertParseContext { SVnodeModifOpStmt* pOutput; SStmtCallback* pStmtCb; SParseMetaCache* pMetaCache; + char sTableName[TSDB_TABLE_NAME_LEN]; } SInsertParseContext; typedef struct SInsertParseSyntaxCxt { @@ -811,10 +812,11 @@ static int32_t parseBoundColumns(SInsertParseContext* pCxt, SParsedDataColInfo* return TSDB_CODE_SUCCESS; } -static void buildCreateTbReq(SVCreateTbReq* pTbReq, const char* tname, STag* pTag, int64_t suid) { +static void buildCreateTbReq(SVCreateTbReq* pTbReq, const char* tname, STag* pTag, int64_t suid, const char* sname) { pTbReq->type = TD_CHILD_TABLE; pTbReq->name = strdup(tname); pTbReq->ctb.suid = suid; + if(sname) pTbReq->ctb.name = strdup(sname); pTbReq->ctb.pTag = (uint8_t*)pTag; pTbReq->commentLen = -1; @@ -835,6 +837,7 @@ static int32_t parseTagToken(char** end, SToken* pToken, SSchema* pSchema, int16 return TSDB_CODE_SUCCESS; } + strcpy(val->colName, pSchema->name); val->cid = pSchema->colId; val->type = pSchema->type; @@ -1051,7 +1054,7 @@ static int32_t parseTagsClause(SInsertParseContext* pCxt, SSchema* pSchema, uint if (isNullStr(&sToken)) { code = tTagNew(pTagVals, 1, true, &pTag); } else { - code = parseJsontoTagData(sToken.z, pTagVals, &pTag, &pCxt->msg); + code = parseJsontoTagData(sToken.z, pTagVals, &pTag, &pCxt->msg, pTagSchema->name); } taosMemoryFree(tmpTokenBuf); if (code != TSDB_CODE_SUCCESS) { @@ -1081,7 +1084,7 @@ static int32_t parseTagsClause(SInsertParseContext* pCxt, SSchema* pSchema, uint goto end; } - buildCreateTbReq(&pCxt->createTblReq, tName, pTag, pCxt->pTableMeta->suid); + buildCreateTbReq(&pCxt->createTblReq, tName, pTag, pCxt->pTableMeta->suid, pCxt->sTableName); end: for (int i = 0; i < taosArrayGetSize(pTagVals); ++i) { @@ -1166,6 +1169,7 @@ static int32_t parseUsingClause(SInsertParseContext* pCxt, SName* name, char* tb createSName(&sname, &sToken, pCxt->pComCxt->acctId, pCxt->pComCxt->db, &pCxt->msg); char dbFName[TSDB_DB_FNAME_LEN]; tNameGetFullDbName(&sname, dbFName); + strcpy(pCxt->sTableName, sname.tname); CHECK_CODE(getSTableMeta(pCxt, &sname, dbFName)); if (TSDB_SUPER_TABLE != pCxt->pTableMeta->tableType) { @@ -1402,15 +1406,10 @@ static int32_t parseDataFromFile(SInsertParseContext* pCxt, SToken filePath, STa return TSDB_CODE_SUCCESS; } -void destroyCreateSubTbReq(SVCreateTbReq* pReq) { - taosMemoryFreeClear(pReq->name); - taosMemoryFreeClear(pReq->ctb.pTag); -} - static void destroyInsertParseContextForTable(SInsertParseContext* pCxt) { taosMemoryFreeClear(pCxt->pTableMeta); destroyBoundColumnInfo(&pCxt->tags); - destroyCreateSubTbReq(&pCxt->createTblReq); + tdDestroySVCreateTbReq(&pCxt->createTblReq); } static void destroySubTableHashElem(void* p) { taosMemoryFree(*(STableMeta**)p); } @@ -1556,7 +1555,7 @@ static int32_t parseInsertBody(SInsertParseContext* pCxt) { } memcpy(tags, &pCxt->tags, sizeof(pCxt->tags)); (*pCxt->pStmtCb->setInfoFn)(pCxt->pStmtCb->pStmt, pCxt->pTableMeta, tags, tbFName, autoCreateTbl, - pCxt->pVgroupsHashObj, pCxt->pTableBlockHashObj); + pCxt->pVgroupsHashObj, pCxt->pTableBlockHashObj, pCxt->sTableName); memset(&pCxt->tags, 0, sizeof(pCxt->tags)); pCxt->pVgroupsHashObj = NULL; @@ -1865,7 +1864,7 @@ int32_t qBuildStmtOutput(SQuery* pQuery, SHashObj* pVgHash, SHashObj* pBlockHash return TSDB_CODE_SUCCESS; } -int32_t qBindStmtTagsValue(void* pBlock, void* boundTags, int64_t suid, char* tName, TAOS_MULTI_BIND* bind, +int32_t qBindStmtTagsValue(void* pBlock, void* boundTags, int64_t suid, const char* sTableName, char* tName, TAOS_MULTI_BIND* bind, char* msgBuf, int32_t msgBufLen) { STableDataBlocks* pDataBlock = (STableDataBlocks*)pBlock; SMsgBuf pBuf = {.buf = msgBuf, .len = msgBufLen}; @@ -1904,13 +1903,14 @@ int32_t qBindStmtTagsValue(void* pBlock, void* boundTags, int64_t suid, char* tN isJson = true; char* tmp = taosMemoryCalloc(1, colLen + 1); memcpy(tmp, bind[c].buffer, colLen); - code = parseJsontoTagData(tmp, pTagArray, &pTag, &pBuf); + code = parseJsontoTagData(tmp, pTagArray, &pTag, &pBuf, pTagSchema->name); taosMemoryFree(tmp); if (code != TSDB_CODE_SUCCESS) { goto end; } } else { STagVal val = {.cid = pTagSchema->colId, .type = pTagSchema->type}; + strcpy(val.colName, pTagSchema->name); if (pTagSchema->type == TSDB_DATA_TYPE_BINARY) { val.pData = (uint8_t*)bind[c].buffer; val.nData = colLen; @@ -1947,9 +1947,9 @@ int32_t qBindStmtTagsValue(void* pBlock, void* boundTags, int64_t suid, char* tN } SVCreateTbReq tbReq = {0}; - buildCreateTbReq(&tbReq, tName, pTag, suid); + buildCreateTbReq(&tbReq, tName, pTag, suid, sTableName); code = buildCreateTbMsg(pDataBlock, &tbReq); - destroyCreateSubTbReq(&tbReq); + tdDestroySVCreateTbReq(&tbReq); end: for (int i = 0; i < taosArrayGetSize(pTagArray); ++i) { @@ -2213,7 +2213,7 @@ typedef struct SmlExecHandle { static void smlDestroyTableHandle(void* pHandle) { SmlExecTableHandle* handle = (SmlExecTableHandle*)pHandle; destroyBoundColumnInfo(&handle->tags); - destroyCreateSubTbReq(&handle->createTblReq); + tdDestroySVCreateTbReq(&handle->createTblReq); } static int32_t smlBoundColumnData(SArray* cols, SParsedDataColInfo* pColList, SSchema* pSchema) { @@ -2311,6 +2311,7 @@ static int32_t smlBuildTagRow(SArray* cols, SParsedDataColInfo* tags, SSchema* p SSmlKv* kv = taosArrayGetP(cols, i); STagVal val = {.cid = pTagSchema->colId, .type = pTagSchema->type}; + strcpy(val.colName, pTagSchema->name); if (pTagSchema->type == TSDB_DATA_TYPE_BINARY) { val.pData = (uint8_t*)kv->value; val.nData = kv->length; @@ -2354,7 +2355,7 @@ end: } int32_t smlBindData(void* handle, SArray* tags, SArray* colsSchema, SArray* cols, bool format, STableMeta* pTableMeta, - char* tableName, char* msgBuf, int16_t msgBufLen) { + char* tableName, const char* sTableName, int32_t sTableNameLen, char* msgBuf, int16_t msgBufLen) { SMsgBuf pBuf = {.buf = msgBuf, .len = msgBufLen}; SSmlExecHandle* smlHandle = (SSmlExecHandle*)handle; @@ -2372,7 +2373,10 @@ int32_t smlBindData(void* handle, SArray* tags, SArray* colsSchema, SArray* cols return ret; } - buildCreateTbReq(&smlHandle->tableExecHandle.createTblReq, tableName, pTag, pTableMeta->suid); + buildCreateTbReq(&smlHandle->tableExecHandle.createTblReq, tableName, pTag, pTableMeta->suid, NULL); + smlHandle->tableExecHandle.createTblReq.ctb.name = taosMemoryMalloc(sTableNameLen + 1); + memcpy(smlHandle->tableExecHandle.createTblReq.ctb.name, sTableName, sTableNameLen); + smlHandle->tableExecHandle.createTblReq.ctb.name[sTableNameLen] = 0; STableDataBlocks* pDataBlock = NULL; ret = getDataBlockFromList(smlHandle->pBlockHash, &pTableMeta->uid, sizeof(pTableMeta->uid), diff --git a/source/libs/parser/src/parTranslater.c b/source/libs/parser/src/parTranslater.c index ed6d3c1c93..5ea06ca892 100644 --- a/source/libs/parser/src/parTranslater.c +++ b/source/libs/parser/src/parTranslater.c @@ -5369,7 +5369,7 @@ static int32_t rewriteCreateTable(STranslateContext* pCxt, SQuery* pQuery) { } static void addCreateTbReqIntoVgroup(int32_t acctId, SHashObj* pVgroupHashmap, SCreateSubTableClause* pStmt, - const STag* pTag, uint64_t suid, SVgroupInfo* pVgInfo) { + const STag* pTag, uint64_t suid, const char* sTableNmae, SVgroupInfo* pVgInfo) { // char dbFName[TSDB_DB_FNAME_LEN] = {0}; // SName name = {.type = TSDB_DB_NAME_T, .acctId = acctId}; // strcpy(name.dbname, pStmt->dbName); @@ -5386,6 +5386,7 @@ static void addCreateTbReqIntoVgroup(int32_t acctId, SHashObj* pVgroupHashmap, S req.commentLen = -1; } req.ctb.suid = suid; + req.ctb.name = strdup(sTableNmae); req.ctb.pTag = (uint8_t*)pTag; if (pStmt->ignoreExists) { req.flags |= TD_CREATE_IF_NOT_EXISTS; @@ -5471,13 +5472,14 @@ static int32_t buildJsonTagVal(STranslateContext* pCxt, SSchema* pTagSchema, SVa return buildSyntaxErrMsg(&pCxt->msgBuf, "json string too long than 4095", pVal->literal); } - return parseJsontoTagData(pVal->literal, pTagArray, ppTag, &pCxt->msgBuf); + return parseJsontoTagData(pVal->literal, pTagArray, ppTag, &pCxt->msgBuf, pTagSchema->name); } static int32_t buildNormalTagVal(STranslateContext* pCxt, SSchema* pTagSchema, SValueNode* pVal, SArray* pTagArray) { if (pVal->node.resType.type != TSDB_DATA_TYPE_NULL) { void* nodeVal = nodesGetValueFromNode(pVal); STagVal val = {.cid = pTagSchema->colId, .type = pTagSchema->type}; + strcpy(val.colName, pTagSchema->name); if (IS_VAR_DATA_TYPE(pTagSchema->type)) { val.pData = varDataVal(nodeVal); val.nData = varDataLen(nodeVal); @@ -5571,6 +5573,7 @@ static int32_t buildKVRowForAllTags(STranslateContext* pCxt, SCreateSubTableClau } else if (pVal->node.resType.type != TSDB_DATA_TYPE_NULL && !pVal->isNull) { char* tmpVal = nodesGetValueFromNode(pVal); STagVal val = {.cid = pTagSchema->colId, .type = pTagSchema->type}; + strcpy(val.colName, pTagSchema->name); if (IS_VAR_DATA_TYPE(pTagSchema->type)) { val.pData = varDataVal(tmpVal); val.nData = varDataLen(tmpVal); @@ -5627,7 +5630,7 @@ static int32_t rewriteCreateSubTable(STranslateContext* pCxt, SCreateSubTableCla code = getTableHashVgroup(pCxt, pStmt->dbName, pStmt->tableName, &info); } if (TSDB_CODE_SUCCESS == code) { - addCreateTbReqIntoVgroup(pCxt->pParseCxt->acctId, pVgroupHashmap, pStmt, pTag, pSuperTableMeta->uid, &info); + addCreateTbReqIntoVgroup(pCxt->pParseCxt->acctId, pVgroupHashmap, pStmt, pTag, pSuperTableMeta->uid, pStmt->useTableName, &info); } taosMemoryFreeClear(pSuperTableMeta); @@ -5845,8 +5848,8 @@ static int32_t buildUpdateTagValReq(STranslateContext* pCxt, SAlterTableStmt* pS } pReq->isNull = (TSDB_DATA_TYPE_NULL == pStmt->pVal->node.resType.type); + pReq->tagType = targetDt.type; if (targetDt.type == TSDB_DATA_TYPE_JSON) { - pReq->isNull = 0; if (pStmt->pVal->literal && strlen(pStmt->pVal->literal) > (TSDB_MAX_JSON_TAG_LEN - VARSTR_HEADER_SIZE) / TSDB_NCHAR_SIZE) { return buildSyntaxErrMsg(&pCxt->msgBuf, "json string too long than 4095", pStmt->pVal->literal); @@ -5855,7 +5858,7 @@ static int32_t buildUpdateTagValReq(STranslateContext* pCxt, SAlterTableStmt* pS int32_t code = TSDB_CODE_SUCCESS; STag* pTag = NULL; do { - code = parseJsontoTagData(pStmt->pVal->literal, pTagVals, &pTag, &pCxt->msgBuf); + code = parseJsontoTagData(pStmt->pVal->literal, pTagVals, &pTag, &pCxt->msgBuf, pReq->tagName); if (TSDB_CODE_SUCCESS != code) { break; } @@ -5870,6 +5873,9 @@ static int32_t buildUpdateTagValReq(STranslateContext* pCxt, SAlterTableStmt* pS if (code != TSDB_CODE_SUCCESS) { return code; } + if(pTag->nTag == 0){ + pReq->isNull = true; + } pReq->nTagVal = pTag->len; pReq->pTagVal = (uint8_t*)pTag; pStmt->pVal->datum.p = (char*)pTag; // for free @@ -5927,7 +5933,7 @@ static int32_t buildDropColReq(STranslateContext* pCxt, SAlterTableStmt* pStmt, static int32_t buildUpdateColReq(STranslateContext* pCxt, SAlterTableStmt* pStmt, STableMeta* pTableMeta, SVAlterTbReq* pReq) { pReq->colModBytes = calcTypeBytes(pStmt->dataType); - + pReq->colModType = pStmt->dataType.type; SSchema* pSchema = getColSchema(pTableMeta, pStmt->colName); if (NULL == pSchema) { return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_INVALID_COLUMN, pStmt->colName); diff --git a/source/libs/parser/src/parUtil.c b/source/libs/parser/src/parUtil.c index 7a23338035..2f12c9adf6 100644 --- a/source/libs/parser/src/parUtil.c +++ b/source/libs/parser/src/parUtil.c @@ -341,7 +341,7 @@ static bool isValidateTag(char* input) { return true; } -int32_t parseJsontoTagData(const char* json, SArray* pTagVals, STag** ppTag, void* pMsgBuf) { +int32_t parseJsontoTagData(const char* json, SArray* pTagVals, STag** ppTag, void* pMsgBuf, const char* colName) { int32_t retCode = TSDB_CODE_SUCCESS; cJSON* root = NULL; SHashObj* keyHash = NULL; @@ -389,6 +389,7 @@ int32_t parseJsontoTagData(const char* json, SArray* pTagVals, STag** ppTag, voi continue; } STagVal val = {0}; + strcpy(val.colName, colName); val.pKey = jsonKey; taosHashPut(keyHash, jsonKey, keyLen, &keyLen, CHAR_BYTES); // add key to hash to remove dumplicate, value is useless diff --git a/source/libs/scalar/src/sclfunc.c b/source/libs/scalar/src/sclfunc.c index df5df127f0..dd0a60dced 100644 --- a/source/libs/scalar/src/sclfunc.c +++ b/source/libs/scalar/src/sclfunc.c @@ -1150,7 +1150,7 @@ int32_t toJsonFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOu } memcpy(tmp, varDataVal(input), varDataLen(input)); tmp[varDataLen(input)] = 0; - if(parseJsontoTagData(tmp, pTagVals, &pTag, NULL)){ + if(parseJsontoTagData(tmp, pTagVals, &pTag, NULL, "")){ tTagNew(pTagVals, 1, true, &pTag); } } diff --git a/source/libs/scalar/test/scalar/scalarTests.cpp b/source/libs/scalar/test/scalar/scalarTests.cpp index 07440e7435..8fcc76f51f 100644 --- a/source/libs/scalar/test/scalar/scalarTests.cpp +++ b/source/libs/scalar/test/scalar/scalarTests.cpp @@ -1114,7 +1114,7 @@ TEST(columnTest, json_column_arith_op) { memcpy(rightv, rightvTmp, strlen(rightvTmp)); SArray *tags = taosArrayInit(1, sizeof(STagVal)); STag* row = NULL; - parseJsontoTagData(rightv, tags, &row, NULL); + parseJsontoTagData(rightv, tags, &row, NULL, ""); const int32_t len = 8; EOperatorType op[len] = {OP_TYPE_ADD, OP_TYPE_SUB, OP_TYPE_MULTI, OP_TYPE_DIV, @@ -1262,7 +1262,7 @@ TEST(columnTest, json_column_logic_op) { memcpy(rightv, rightvTmp, strlen(rightvTmp)); SArray *tags = taosArrayInit(1, sizeof(STagVal)); STag* row = NULL; - parseJsontoTagData(rightv, tags, &row, NULL); + parseJsontoTagData(rightv, tags, &row, NULL, ""); const int32_t len0 = 6; const int32_t len = 9; -- GitLab From 2411a1416a849fa761149040476a27daf434c8b0 Mon Sep 17 00:00:00 2001 From: wangmm0220 Date: Sun, 10 Jul 2022 19:01:56 +0800 Subject: [PATCH 002/153] fix:conflicts --- source/dnode/mnode/impl/src/mndStb.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/source/dnode/mnode/impl/src/mndStb.c b/source/dnode/mnode/impl/src/mndStb.c index c60058e496..2117ef24d9 100644 --- a/source/dnode/mnode/impl/src/mndStb.c +++ b/source/dnode/mnode/impl/src/mndStb.c @@ -45,7 +45,7 @@ static int32_t mndProcessTableMetaReq(SRpcMsg *pReq); static int32_t mndRetrieveStb(SRpcMsg *pReq, SShowObj *pShow, SSDataBlock *pBlock, int32_t rows); static void mndCancelGetNextStb(SMnode *pMnode, void *pIter); static int32_t mndProcessTableCfgReq(SRpcMsg *pReq); -static int32_t mndAlterStbImp(SMnode *pMnode, SRpcMsg *pReq, SDbObj *pDb, SStbObj *pStb, bool needRsp); +static int32_t mndAlterStbImp(SMnode *pMnode, SRpcMsg *pReq, SDbObj *pDb, SStbObj *pStb, bool needRsp, void* alterOriData, int32_t alterOriDataLen); int32_t mndInitStb(SMnode *pMnode) { SSdbTable table = { @@ -936,7 +936,7 @@ static int32_t mndProcessCreateStbReq(SRpcMsg *pReq) { if (isAlter) { bool needRsp = false; - code = mndAlterStbImp(pMnode, pReq, pDb, pStb, needRsp); + code = mndAlterStbImp(pMnode, pReq, pDb, pStb, needRsp, NULL, 0); } else { code = mndCreateStb(pMnode, pReq, &createReq, pDb); } @@ -1544,7 +1544,7 @@ static int32_t mndBuildSMAlterStbRsp(SDbObj *pDb, SStbObj *pObj, void **pCont, i return 0; } -static int32_t mndAlterStbImp(SMnode *pMnode, SRpcMsg *pReq, SDbObj *pDb, SStbObj *pStb, bool needRsp) { +static int32_t mndAlterStbImp(SMnode *pMnode, SRpcMsg *pReq, SDbObj *pDb, SStbObj *pStb, bool needRsp, void* alterOriData, int32_t alterOriDataLen) { int32_t code = -1; STrans *pTrans = mndTransCreate(pMnode, TRN_POLICY_RETRY, TRN_CONFLICT_DB_INSIDE, pReq); if (pTrans == NULL) goto _OVER; @@ -1561,7 +1561,7 @@ static int32_t mndAlterStbImp(SMnode *pMnode, SRpcMsg *pReq, SDbObj *pDb, SStbOb if (mndSetAlterStbRedoLogs(pMnode, pTrans, pDb, pStb) != 0) goto _OVER; if (mndSetAlterStbCommitLogs(pMnode, pTrans, pDb, pStb) != 0) goto _OVER; - if (mndSetAlterStbRedoActions(pMnode, pTrans, pDb, pStb) != 0) goto _OVER; + if (mndSetAlterStbRedoActions(pMnode, pTrans, pDb, pStb, alterOriData, alterOriDataLen) != 0) goto _OVER; if (mndTransPrepare(pMnode, pTrans) != 0) goto _OVER; code = 0; @@ -1622,7 +1622,7 @@ static int32_t mndAlterStb(SMnode *pMnode, SRpcMsg *pReq, const SMAlterStbReq *p } if (code != 0) goto _OVER; - code = mndAlterStbImp(pMnode, pReq, pDb, &stbObj, needRsp); + code = mndAlterStbImp(pMnode, pReq, pDb, &stbObj, needRsp, pReq->pCont, pReq->contLen); _OVER: taosMemoryFreeClear(stbObj.pTags); -- GitLab From 3d2e129dd634ef4064cb71b025dcb8f20d1ac104 Mon Sep 17 00:00:00 2001 From: wangmm0220 Date: Mon, 11 Jul 2022 10:18:01 +0800 Subject: [PATCH 003/153] feat:add tmq get meta --- source/client/src/tmq.c | 1 - 1 file changed, 1 deletion(-) diff --git a/source/client/src/tmq.c b/source/client/src/tmq.c index 90cb43c676..6d24d8d9ff 100644 --- a/source/client/src/tmq.c +++ b/source/client/src/tmq.c @@ -2869,7 +2869,6 @@ end: } int32_t taos_write_raw_meta(TAOS *taos, tmq_raw_data *raw_meta){ - return 0; if (!taos || !raw_meta) { return TSDB_CODE_INVALID_PARA; } -- GitLab From 0a193cf811df5443aa7231d08f3b2b56a2d239d3 Mon Sep 17 00:00:00 2001 From: wangmm0220 Date: Mon, 11 Jul 2022 16:12:07 +0800 Subject: [PATCH 004/153] feat:get meta ok --- examples/c/tmq.c | 67 +++++++++++++++++----------- include/common/tmsg.h | 7 ++- include/util/tlog.h | 2 +- source/dnode/mnode/impl/src/mndStb.c | 50 ++++++++++++++++++--- source/dnode/vnode/src/tq/tq.c | 2 +- 5 files changed, 91 insertions(+), 37 deletions(-) diff --git a/examples/c/tmq.c b/examples/c/tmq.c index 5d7f1bbe70..c6248a62c1 100644 --- a/examples/c/tmq.c +++ b/examples/c/tmq.c @@ -30,10 +30,25 @@ static void msg_process(TAOS_RES* msg) { if (tmq_get_res_type(msg) == TMQ_RES_TABLE_META) { tmq_raw_data *raw = tmq_get_raw_meta(msg); if(raw){ - TAOS* pConn = taos_connect("192.168.1.86", "root", "taosdata", "abc1", 0); + TAOS* pConn = taos_connect("192.168.1.86", "root", "taosdata", NULL, 0); if (pConn == NULL) { return; } + + TAOS_RES* pRes = taos_query(pConn, "create database if not exists abc1 vgroups 1"); + if (taos_errno(pRes) != 0) { + printf("error in create db, reason:%s\n", taos_errstr(pRes)); + return; + } + taos_free_result(pRes); + + pRes = taos_query(pConn, "use abc1"); + if (taos_errno(pRes) != 0) { + printf("error in use db, reason:%s\n", taos_errstr(pRes)); + return; + } + taos_free_result(pRes); + int32_t ret = taos_write_raw_meta(pConn, raw); printf("write raw data: %s\n", tmq_err2str(ret)); free(raw); @@ -132,12 +147,12 @@ int32_t init_env() { } taos_free_result(pRes); - pRes = taos_query(pConn, "alter table st1 add column c4 bigint"); - if (taos_errno(pRes) != 0) { - printf("failed to alter super table st1, reason:%s\n", taos_errstr(pRes)); - return -1; - } - taos_free_result(pRes); +// pRes = taos_query(pConn, "alter table st1 add column c4 bigint"); +// if (taos_errno(pRes) != 0) { +// printf("failed to alter super table st1, reason:%s\n", taos_errstr(pRes)); +// return -1; +// } +// taos_free_result(pRes); pRes = taos_query(pConn, "alter table st1 modify column c3 binary(64)"); if (taos_errno(pRes) != 0) { @@ -160,19 +175,19 @@ int32_t init_env() { } taos_free_result(pRes); - pRes = taos_query(pConn, "drop table ct3 ct1"); - if (taos_errno(pRes) != 0) { - printf("failed to drop child table ct3, reason:%s\n", taos_errstr(pRes)); - return -1; - } - taos_free_result(pRes); - - pRes = taos_query(pConn, "drop table st1"); - if (taos_errno(pRes) != 0) { - printf("failed to drop super table st1, reason:%s\n", taos_errstr(pRes)); - return -1; - } - taos_free_result(pRes); +// pRes = taos_query(pConn, "drop table ct3 ct1"); +// if (taos_errno(pRes) != 0) { +// printf("failed to drop child table ct3, reason:%s\n", taos_errstr(pRes)); +// return -1; +// } +// taos_free_result(pRes); +// +// pRes = taos_query(pConn, "drop table st1"); +// if (taos_errno(pRes) != 0) { +// printf("failed to drop super table st1, reason:%s\n", taos_errstr(pRes)); +// return -1; +// } +// taos_free_result(pRes); pRes = taos_query(pConn, "create table if not exists n1(ts timestamp, c1 int, c2 nchar(4))"); if (taos_errno(pRes) != 0) { @@ -209,12 +224,12 @@ int32_t init_env() { } taos_free_result(pRes); - pRes = taos_query(pConn, "drop table n1"); - if (taos_errno(pRes) != 0) { - printf("failed to drop normal table n1, reason:%s\n", taos_errstr(pRes)); - return -1; - } - taos_free_result(pRes); +// pRes = taos_query(pConn, "drop table n1"); +// if (taos_errno(pRes) != 0) { +// printf("failed to drop normal table n1, reason:%s\n", taos_errstr(pRes)); +// return -1; +// } +// taos_free_result(pRes); pRes = taos_query(pConn, "create table jt(ts timestamp, i int) tags(t json)"); if (taos_errno(pRes) != 0) { diff --git a/include/common/tmsg.h b/include/common/tmsg.h index b67f220e1c..01f8ad99fd 100644 --- a/include/common/tmsg.h +++ b/include/common/tmsg.h @@ -2843,8 +2843,8 @@ typedef struct { static FORCE_INLINE int32_t tEncodeSMqMetaRsp(void** buf, const SMqMetaRsp* pRsp) { int32_t tlen = 0; - // tlen += taosEncodeFixedI64(buf, pRsp->reqOffset); - // tlen += taosEncodeFixedI64(buf, pRsp->rspOffset); + tlen += taosEncodeFixedI64(buf, pRsp->reqOffset); + tlen += taosEncodeFixedI64(buf, pRsp->rspOffset); tlen += taosEncodeFixedI16(buf, pRsp->resMsgType); tlen += taosEncodeFixedI32(buf, pRsp->metaRspLen); tlen += taosEncodeBinary(buf, pRsp->metaRsp, pRsp->metaRspLen); @@ -2852,8 +2852,7 @@ static FORCE_INLINE int32_t tEncodeSMqMetaRsp(void** buf, const SMqMetaRsp* pRsp } static FORCE_INLINE void* tDecodeSMqMetaRsp(const void* buf, SMqMetaRsp* pRsp) { - // buf = taosDecodeFixedI64(buf, &pRsp->reqOffset); - // buf = taosDecodeFixedI64(buf, &pRsp->rspOffset); + buf = taosDecodeFixedI64(buf, &pRsp->reqOffset);buf = taosDecodeFixedI64(buf, &pRsp->rspOffset); buf = taosDecodeFixedI16(buf, &pRsp->resMsgType); buf = taosDecodeFixedI32(buf, &pRsp->metaRspLen); buf = taosDecodeBinary(buf, &pRsp->metaRsp, pRsp->metaRspLen); diff --git a/include/util/tlog.h b/include/util/tlog.h index a8c9eeabde..d186c32841 100644 --- a/include/util/tlog.h +++ b/include/util/tlog.h @@ -94,7 +94,7 @@ void taosPrintLongString(const char *flags, ELogLevel level, int32_t dflag, cons #define pError(...) { taosPrintLog("APP ERROR ", DEBUG_ERROR, 255, __VA_ARGS__); } #define pPrint(...) { taosPrintLog("APP ", DEBUG_INFO, 255, __VA_ARGS__); } // clang-format on -#define BUF_PAGE_DEBUG +//#define BUF_PAGE_DEBUG #ifdef __cplusplus } #endif diff --git a/source/dnode/mnode/impl/src/mndStb.c b/source/dnode/mnode/impl/src/mndStb.c index 2117ef24d9..3a7b137f9f 100644 --- a/source/dnode/mnode/impl/src/mndStb.c +++ b/source/dnode/mnode/impl/src/mndStb.c @@ -708,7 +708,7 @@ int32_t mndBuildStbFromReq(SMnode *pMnode, SStbObj *pDst, SMCreateStbReq *pCreat memcpy(pDst->db, pDb->name, TSDB_DB_FNAME_LEN); pDst->createdTime = taosGetTimestampMs(); pDst->updateTime = pDst->createdTime; - pDst->uid = (pCreate->source == 1) ? pCreate->suid : mndGenerateUid(pCreate->name, TSDB_TABLE_FNAME_LEN); + pDst->uid = (pCreate->source == TD_REQ_FROM_TAOX) ? pCreate->suid : mndGenerateUid(pCreate->name, TSDB_TABLE_FNAME_LEN); pDst->dbUid = pDb->uid; pDst->tagVer = (pCreate->source != TD_REQ_FROM_APP) ? pCreate->tagVer : 1; pDst->colVer = (pCreate->source != TD_REQ_FROM_APP) ? pCreate->colVer : 1; @@ -883,9 +883,9 @@ static int32_t mndProcessCreateStbReq(SRpcMsg *pReq) { terrno = TSDB_CODE_MND_STABLE_UID_NOT_MATCH; goto _OVER; } else if (createReq.tagVer > 0 || createReq.colVer > 0) { - int32_t tagDelta = pStb->tagVer - createReq.tagVer; - int32_t colDelta = pStb->colVer - createReq.colVer; - int32_t verDelta = tagDelta + verDelta; + int32_t tagDelta = createReq.tagVer - pStb->tagVer; + int32_t colDelta = createReq.colVer - pStb->colVer; + int32_t verDelta = tagDelta + colDelta; mInfo("stb:%s, already exist while create, input tagVer:%d colVer:%d, exist tagVer:%d colVer:%d", createReq.name, createReq.tagVer, createReq.colVer, pStb->tagVer, pStb->colVer); if (tagDelta <= 0 && colDelta <= 0) { @@ -936,7 +936,47 @@ static int32_t mndProcessCreateStbReq(SRpcMsg *pReq) { if (isAlter) { bool needRsp = false; - code = mndAlterStbImp(pMnode, pReq, pDb, pStb, needRsp, NULL, 0); + SStbObj pDst = {0}; + taosRLockLatch(&pStb->lock); + memcpy(&pDst, pStb, sizeof(SStbObj)); + taosRUnLockLatch(&pStb->lock); + + pDst.updateTime = taosGetTimestampMs(); + pDst.nextColId = 1; + pDst.numOfColumns = createReq.numOfColumns; + pDst.numOfTags = createReq.numOfTags; + pDst.pColumns = taosMemoryCalloc(1, pDst.numOfColumns * sizeof(SSchema)); + pDst.pTags = taosMemoryCalloc(1, pDst.numOfTags * sizeof(SSchema)); + if (pDst.pColumns == NULL || pDst.pTags == NULL) { + terrno = TSDB_CODE_OUT_OF_MEMORY; + goto _OVER; + } + + for (int32_t i = 0; i < pDst.numOfColumns; ++i) { + SField *pField = taosArrayGet(createReq.pColumns, i); + SSchema *pSchema = &pDst.pColumns[i]; + pSchema->type = pField->type; + pSchema->bytes = pField->bytes; + pSchema->flags = pField->flags; + memcpy(pSchema->name, pField->name, TSDB_COL_NAME_LEN); + pSchema->colId = pDst.nextColId; + pDst.nextColId++; + } + + for (int32_t i = 0; i < pDst.numOfTags; ++i) { + SField *pField = taosArrayGet(createReq.pTags, i); + SSchema *pSchema = &pDst.pTags[i]; + pSchema->type = pField->type; + pSchema->bytes = pField->bytes; + memcpy(pSchema->name, pField->name, TSDB_COL_NAME_LEN); + pSchema->colId = pDst.nextColId; + pDst.nextColId++; + } + pDst.tagVer = createReq.tagVer; + pDst.colVer = createReq.colVer; + code = mndAlterStbImp(pMnode, pReq, pDb, &pDst, needRsp, NULL, 0); + taosMemoryFreeClear(pDst.pTags); + taosMemoryFreeClear(pDst.pColumns); } else { code = mndCreateStb(pMnode, pReq, &createReq, pDb); } diff --git a/source/dnode/vnode/src/tq/tq.c b/source/dnode/vnode/src/tq/tq.c index 52949838b9..d97a958888 100644 --- a/source/dnode/vnode/src/tq/tq.c +++ b/source/dnode/vnode/src/tq/tq.c @@ -406,7 +406,7 @@ int32_t tqProcessPollReq(STQ* pTq, SRpcMsg* pMsg, int32_t workerId) { tqInfo("fetch meta msg, ver:%" PRId64 ", type:%d", pHead->version, pHead->msgType); SMqMetaRsp metaRsp = {0}; /*metaRsp.reqOffset = pReq->reqOffset.version;*/ - /*metaRsp.rspOffset = fetchVer;*/ + metaRsp.rspOffset = fetchVer; /*metaRsp.rspOffsetNew.version = fetchVer;*/ tqOffsetResetToLog(&metaRsp.reqOffsetNew, pReq->reqOffset.version); tqOffsetResetToLog(&metaRsp.rspOffsetNew, fetchVer); -- GitLab From c54bc76925b01793bca4b0a81b03f1007a862b40 Mon Sep 17 00:00:00 2001 From: wangmm0220 Date: Mon, 11 Jul 2022 17:36:07 +0800 Subject: [PATCH 005/153] feat:get meta ok --- examples/c/tmq.c | 71 +++++++++------ source/client/src/tmq.c | 4 +- source/dnode/mnode/impl/src/mndStb.c | 126 +++++++++++++++------------ 3 files changed, 116 insertions(+), 85 deletions(-) diff --git a/examples/c/tmq.c b/examples/c/tmq.c index c6248a62c1..c55cb2ca58 100644 --- a/examples/c/tmq.c +++ b/examples/c/tmq.c @@ -51,15 +51,14 @@ static void msg_process(TAOS_RES* msg) { int32_t ret = taos_write_raw_meta(pConn, raw); printf("write raw data: %s\n", tmq_err2str(ret)); - free(raw); taos_close(pConn); } + tmq_free_raw_meta(raw); char* result = tmq_get_json_meta(msg); if(result){ printf("meta result: %s\n", result); - free(result); } - printf("meta:%p\n", raw); + tmq_free_json_meta(result); return; } while (1) { @@ -83,7 +82,7 @@ int32_t init_env() { return -1; } - TAOS_RES* pRes = taos_query(pConn, "create database if not exists abc1 vgroups 1"); + TAOS_RES* pRes = taos_query(pConn, "create database if not exists abc1 vgroups 3"); if (taos_errno(pRes) != 0) { printf("error in create db, reason:%s\n", taos_errstr(pRes)); return -1; @@ -126,6 +125,13 @@ int32_t init_env() { } taos_free_result(pRes); + pRes = taos_query(pConn, "create table if not exists ct2 using st1 tags(NULL)"); + if (taos_errno(pRes) != 0) { + printf("failed to create child table ct2, reason:%s\n", taos_errstr(pRes)); + return -1; + } + taos_free_result(pRes); + pRes = taos_query(pConn, "insert into ct1 values(now, 3, 4, 'b')"); if (taos_errno(pRes) != 0) { printf("failed to insert into ct1, reason:%s\n", taos_errstr(pRes)); @@ -147,12 +153,12 @@ int32_t init_env() { } taos_free_result(pRes); -// pRes = taos_query(pConn, "alter table st1 add column c4 bigint"); -// if (taos_errno(pRes) != 0) { -// printf("failed to alter super table st1, reason:%s\n", taos_errstr(pRes)); -// return -1; -// } -// taos_free_result(pRes); + pRes = taos_query(pConn, "alter table st1 add column c4 bigint"); + if (taos_errno(pRes) != 0) { + printf("failed to alter super table st1, reason:%s\n", taos_errstr(pRes)); + return -1; + } + taos_free_result(pRes); pRes = taos_query(pConn, "alter table st1 modify column c3 binary(64)"); if (taos_errno(pRes) != 0) { @@ -175,19 +181,19 @@ int32_t init_env() { } taos_free_result(pRes); -// pRes = taos_query(pConn, "drop table ct3 ct1"); -// if (taos_errno(pRes) != 0) { -// printf("failed to drop child table ct3, reason:%s\n", taos_errstr(pRes)); -// return -1; -// } -// taos_free_result(pRes); -// -// pRes = taos_query(pConn, "drop table st1"); -// if (taos_errno(pRes) != 0) { -// printf("failed to drop super table st1, reason:%s\n", taos_errstr(pRes)); -// return -1; -// } -// taos_free_result(pRes); + pRes = taos_query(pConn, "drop table ct3 ct1"); + if (taos_errno(pRes) != 0) { + printf("failed to drop child table ct3, reason:%s\n", taos_errstr(pRes)); + return -1; + } + taos_free_result(pRes); + + pRes = taos_query(pConn, "drop table st1"); + if (taos_errno(pRes) != 0) { + printf("failed to drop super table st1, reason:%s\n", taos_errstr(pRes)); + return -1; + } + taos_free_result(pRes); pRes = taos_query(pConn, "create table if not exists n1(ts timestamp, c1 int, c2 nchar(4))"); if (taos_errno(pRes) != 0) { @@ -224,12 +230,12 @@ int32_t init_env() { } taos_free_result(pRes); -// pRes = taos_query(pConn, "drop table n1"); -// if (taos_errno(pRes) != 0) { -// printf("failed to drop normal table n1, reason:%s\n", taos_errstr(pRes)); -// return -1; -// } -// taos_free_result(pRes); + pRes = taos_query(pConn, "drop table n1"); + if (taos_errno(pRes) != 0) { + printf("failed to drop normal table n1, reason:%s\n", taos_errstr(pRes)); + return -1; + } + taos_free_result(pRes); pRes = taos_query(pConn, "create table jt(ts timestamp, i int) tags(t json)"); if (taos_errno(pRes) != 0) { @@ -245,6 +251,13 @@ int32_t init_env() { } taos_free_result(pRes); + pRes = taos_query(pConn, "create table jt2 using jt tags('')"); + if (taos_errno(pRes) != 0) { + printf("failed to create super table jt2, reason:%s\n", taos_errstr(pRes)); + return -1; + } + taos_free_result(pRes); + return 0; } diff --git a/source/client/src/tmq.c b/source/client/src/tmq.c index 6d24d8d9ff..4dc0dbfa64 100644 --- a/source/client/src/tmq.c +++ b/source/client/src/tmq.c @@ -2430,7 +2430,7 @@ static int32_t taosCreateStb(TAOS *taos, void *meta, int32_t metaLen){ pReq.numOfTags = req.schemaTag.nCols; pReq.commentLen = -1; pReq.suid = req.suid; - pReq.source = 1; + pReq.source = TD_REQ_FROM_TAOX; pReq.igExists = true; SName tableName; @@ -2497,7 +2497,7 @@ static int32_t taosDropStb(TAOS *taos, void *meta, int32_t metaLen){ // build drop stable pReq.igNotExists = true; - pReq.source = 1; + pReq.source = TD_REQ_FROM_TAOX; pReq.suid = req.suid; SName tableName; tNameExtractFullName(toName(pTscObj->acctId, pRequest->pDb, req.name, &tableName), pReq.name); diff --git a/source/dnode/mnode/impl/src/mndStb.c b/source/dnode/mnode/impl/src/mndStb.c index 3a7b137f9f..5040b556e7 100644 --- a/source/dnode/mnode/impl/src/mndStb.c +++ b/source/dnode/mnode/impl/src/mndStb.c @@ -851,6 +851,75 @@ static int32_t mndProcessTtlTimer(SRpcMsg *pReq) { return 0; } +static int32_t mndFindSuperTableTagIndex(const SStbObj *pStb, const char *tagName) { + for (int32_t tag = 0; tag < pStb->numOfTags; tag++) { + if (strcasecmp(pStb->pTags[tag].name, tagName) == 0) { + return tag; + } + } + + return -1; +} + +static int32_t mndFindSuperTableColumnIndex(const SStbObj *pStb, const char *colName) { + for (int32_t col = 0; col < pStb->numOfColumns; col++) { + if (strcasecmp(pStb->pColumns[col].name, colName) == 0) { + return col; + } + } + + return -1; +} + +static int32_t mndBuildStbFromAlter(SStbObj *pStb, SStbObj *pDst, SMCreateStbReq *createReq) { + taosRLockLatch(&pStb->lock); + memcpy(pDst, pStb, sizeof(SStbObj)); + taosRUnLockLatch(&pStb->lock); + + pDst->updateTime = taosGetTimestampMs(); + pDst->numOfColumns = createReq->numOfColumns; + pDst->numOfTags = createReq->numOfTags; + pDst->pColumns = taosMemoryCalloc(1, pDst->numOfColumns * sizeof(SSchema)); + pDst->pTags = taosMemoryCalloc(1, pDst->numOfTags * sizeof(SSchema)); + if (pDst->pColumns == NULL || pDst->pTags == NULL) { + terrno = TSDB_CODE_OUT_OF_MEMORY; + return -1; + } + + for (int32_t i = 0; i < pDst->numOfColumns; ++i) { + SField *pField = taosArrayGet(createReq->pColumns, i); + SSchema *pSchema = &pDst->pColumns[i]; + pSchema->type = pField->type; + pSchema->bytes = pField->bytes; + pSchema->flags = pField->flags; + memcpy(pSchema->name, pField->name, TSDB_COL_NAME_LEN); + int32_t cIndex = mndFindSuperTableColumnIndex(pStb, pField->name); + if (cIndex >= 0){ + pSchema->colId = pStb->pColumns[cIndex].colId; + }else{ + pSchema->colId = pDst->nextColId++; + } + } + + for (int32_t i = 0; i < pDst->numOfTags; ++i) { + SField *pField = taosArrayGet(createReq->pTags, i); + SSchema *pSchema = &pDst->pTags[i]; + pSchema->type = pField->type; + pSchema->bytes = pField->bytes; + memcpy(pSchema->name, pField->name, TSDB_COL_NAME_LEN); + int32_t cIndex = mndFindSuperTableTagIndex(pStb, pField->name); + if (cIndex >= 0){ + pSchema->colId = pStb->pTags[cIndex].colId; + }else{ + pSchema->colId = pDst->nextColId++; + } + + } + pDst->tagVer = createReq->tagVer; + pDst->colVer = createReq->colVer; + return TSDB_CODE_SUCCESS; +} + static int32_t mndProcessCreateStbReq(SRpcMsg *pReq) { SMnode *pMnode = pReq->info.node; int32_t code = -1; @@ -937,43 +1006,12 @@ static int32_t mndProcessCreateStbReq(SRpcMsg *pReq) { if (isAlter) { bool needRsp = false; SStbObj pDst = {0}; - taosRLockLatch(&pStb->lock); - memcpy(&pDst, pStb, sizeof(SStbObj)); - taosRUnLockLatch(&pStb->lock); - - pDst.updateTime = taosGetTimestampMs(); - pDst.nextColId = 1; - pDst.numOfColumns = createReq.numOfColumns; - pDst.numOfTags = createReq.numOfTags; - pDst.pColumns = taosMemoryCalloc(1, pDst.numOfColumns * sizeof(SSchema)); - pDst.pTags = taosMemoryCalloc(1, pDst.numOfTags * sizeof(SSchema)); - if (pDst.pColumns == NULL || pDst.pTags == NULL) { - terrno = TSDB_CODE_OUT_OF_MEMORY; + if (mndBuildStbFromAlter(pStb, &pDst, &createReq) != 0) { + taosMemoryFreeClear(pDst.pTags); + taosMemoryFreeClear(pDst.pColumns); goto _OVER; } - for (int32_t i = 0; i < pDst.numOfColumns; ++i) { - SField *pField = taosArrayGet(createReq.pColumns, i); - SSchema *pSchema = &pDst.pColumns[i]; - pSchema->type = pField->type; - pSchema->bytes = pField->bytes; - pSchema->flags = pField->flags; - memcpy(pSchema->name, pField->name, TSDB_COL_NAME_LEN); - pSchema->colId = pDst.nextColId; - pDst.nextColId++; - } - - for (int32_t i = 0; i < pDst.numOfTags; ++i) { - SField *pField = taosArrayGet(createReq.pTags, i); - SSchema *pSchema = &pDst.pTags[i]; - pSchema->type = pField->type; - pSchema->bytes = pField->bytes; - memcpy(pSchema->name, pField->name, TSDB_COL_NAME_LEN); - pSchema->colId = pDst.nextColId; - pDst.nextColId++; - } - pDst.tagVer = createReq.tagVer; - pDst.colVer = createReq.colVer; code = mndAlterStbImp(pMnode, pReq, pDb, &pDst, needRsp, NULL, 0); taosMemoryFreeClear(pDst.pTags); taosMemoryFreeClear(pDst.pColumns); @@ -1014,26 +1052,6 @@ static int32_t mndCheckAlterStbReq(SMAlterStbReq *pAlter) { return 0; } -static int32_t mndFindSuperTableTagIndex(const SStbObj *pStb, const char *tagName) { - for (int32_t tag = 0; tag < pStb->numOfTags; tag++) { - if (strcasecmp(pStb->pTags[tag].name, tagName) == 0) { - return tag; - } - } - - return -1; -} - -static int32_t mndFindSuperTableColumnIndex(const SStbObj *pStb, const char *colName) { - for (int32_t col = 0; col < pStb->numOfColumns; col++) { - if (strcasecmp(pStb->pColumns[col].name, colName) == 0) { - return col; - } - } - - return -1; -} - static int32_t mndAllocStbSchemas(const SStbObj *pOld, SStbObj *pNew) { pNew->pTags = taosMemoryCalloc(pNew->numOfTags, sizeof(SSchema)); pNew->pColumns = taosMemoryCalloc(pNew->numOfColumns, sizeof(SSchema)); -- GitLab From a196298640d91d04fd8f7737412d1ed081355b2e Mon Sep 17 00:00:00 2001 From: wangmm0220 Date: Mon, 11 Jul 2022 18:07:46 +0800 Subject: [PATCH 006/153] fix:disable colName in tag --- source/client/src/tmq.c | 13 +++++++++---- source/libs/parser/src/parInsert.c | 6 +++--- source/libs/parser/src/parTranslater.c | 4 ++-- source/libs/parser/src/parUtil.c | 2 +- 4 files changed, 15 insertions(+), 10 deletions(-) diff --git a/source/client/src/tmq.c b/source/client/src/tmq.c index 4dc0dbfa64..5f0fcf1d78 100644 --- a/source/client/src/tmq.c +++ b/source/client/src/tmq.c @@ -2101,8 +2101,10 @@ static char *buildCreateCTableJson(STag* pTag, char* sname, char* name, int64_t cJSON* tag = cJSON_CreateObject(); STagVal* pTagVal = taosArrayGet(pTagVals, 0); - cJSON* tname = cJSON_CreateString(pTagVal->colName); - cJSON_AddItemToObject(tag, "name", tname); +// cJSON* tname = cJSON_CreateString(pTagVal->colName); +// cJSON_AddItemToObject(tag, "name", tname); + cJSON* cid_ = cJSON_CreateString(""); + cJSON_AddItemToObject(tag, "cid", cid_); cJSON* ttype = cJSON_CreateNumber(TSDB_DATA_TYPE_JSON); cJSON_AddItemToObject(tag, "type", ttype); cJSON* tvalue = cJSON_CreateString(pJson); @@ -2116,8 +2118,11 @@ static char *buildCreateCTableJson(STag* pTag, char* sname, char* name, int64_t STagVal* pTagVal = (STagVal*)taosArrayGet(pTagVals, i); cJSON* tag = cJSON_CreateObject(); - cJSON* tname = cJSON_CreateString(pTagVal->colName); - cJSON_AddItemToObject(tag, "name", tname); + + char cid[32] = {0}; + sprintf(cid, "%d", pTagVal->cid); + cJSON* cid_ = cJSON_CreateString(cid); + cJSON_AddItemToObject(tag, "cid", cid_); cJSON* ttype = cJSON_CreateNumber(pTagVal->type); cJSON_AddItemToObject(tag, "type", ttype); diff --git a/source/libs/parser/src/parInsert.c b/source/libs/parser/src/parInsert.c index 576dc6d8d3..ad0877476d 100644 --- a/source/libs/parser/src/parInsert.c +++ b/source/libs/parser/src/parInsert.c @@ -837,7 +837,7 @@ static int32_t parseTagToken(char** end, SToken* pToken, SSchema* pSchema, int16 return TSDB_CODE_SUCCESS; } - strcpy(val->colName, pSchema->name); +// strcpy(val->colName, pSchema->name); val->cid = pSchema->colId; val->type = pSchema->type; @@ -1910,7 +1910,7 @@ int32_t qBindStmtTagsValue(void* pBlock, void* boundTags, int64_t suid, const ch } } else { STagVal val = {.cid = pTagSchema->colId, .type = pTagSchema->type}; - strcpy(val.colName, pTagSchema->name); +// strcpy(val.colName, pTagSchema->name); if (pTagSchema->type == TSDB_DATA_TYPE_BINARY) { val.pData = (uint8_t*)bind[c].buffer; val.nData = colLen; @@ -2311,7 +2311,7 @@ static int32_t smlBuildTagRow(SArray* cols, SParsedDataColInfo* tags, SSchema* p SSmlKv* kv = taosArrayGetP(cols, i); STagVal val = {.cid = pTagSchema->colId, .type = pTagSchema->type}; - strcpy(val.colName, pTagSchema->name); +// strcpy(val.colName, pTagSchema->name); if (pTagSchema->type == TSDB_DATA_TYPE_BINARY) { val.pData = (uint8_t*)kv->value; val.nData = kv->length; diff --git a/source/libs/parser/src/parTranslater.c b/source/libs/parser/src/parTranslater.c index a03cdb6485..75fc2b71dc 100644 --- a/source/libs/parser/src/parTranslater.c +++ b/source/libs/parser/src/parTranslater.c @@ -5555,7 +5555,7 @@ static int32_t buildNormalTagVal(STranslateContext* pCxt, SSchema* pTagSchema, S if (pVal->node.resType.type != TSDB_DATA_TYPE_NULL) { void* nodeVal = nodesGetValueFromNode(pVal); STagVal val = {.cid = pTagSchema->colId, .type = pTagSchema->type}; - strcpy(val.colName, pTagSchema->name); +// strcpy(val.colName, pTagSchema->name); if (IS_VAR_DATA_TYPE(pTagSchema->type)) { val.pData = varDataVal(nodeVal); val.nData = varDataLen(nodeVal); @@ -5649,7 +5649,7 @@ static int32_t buildKVRowForAllTags(STranslateContext* pCxt, SCreateSubTableClau } else if (pVal->node.resType.type != TSDB_DATA_TYPE_NULL && !pVal->isNull) { char* tmpVal = nodesGetValueFromNode(pVal); STagVal val = {.cid = pTagSchema->colId, .type = pTagSchema->type}; - strcpy(val.colName, pTagSchema->name); +// strcpy(val.colName, pTagSchema->name); if (IS_VAR_DATA_TYPE(pTagSchema->type)) { val.pData = varDataVal(tmpVal); val.nData = varDataLen(tmpVal); diff --git a/source/libs/parser/src/parUtil.c b/source/libs/parser/src/parUtil.c index 2f12c9adf6..b6ebb0de22 100644 --- a/source/libs/parser/src/parUtil.c +++ b/source/libs/parser/src/parUtil.c @@ -389,7 +389,7 @@ int32_t parseJsontoTagData(const char* json, SArray* pTagVals, STag** ppTag, voi continue; } STagVal val = {0}; - strcpy(val.colName, colName); +// strcpy(val.colName, colName); val.pKey = jsonKey; taosHashPut(keyHash, jsonKey, keyLen, &keyLen, CHAR_BYTES); // add key to hash to remove dumplicate, value is useless -- GitLab From 4862f032d6b3691ff903ffe7a784b445bdad63eb Mon Sep 17 00:00:00 2001 From: wangmm0220 Date: Mon, 11 Jul 2022 18:07:54 +0800 Subject: [PATCH 007/153] fix:disable colName in tag --- include/common/tdataformat.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/common/tdataformat.h b/include/common/tdataformat.h index e768f89372..d37b8ce1ca 100644 --- a/include/common/tdataformat.h +++ b/include/common/tdataformat.h @@ -167,7 +167,7 @@ struct SColVal { #pragma pack(push, 1) struct STagVal { - char colName[TSDB_COL_NAME_LEN]; // only used for tmq_get_meta +// char colName[TSDB_COL_NAME_LEN]; // only used for tmq_get_meta union { int16_t cid; char *pKey; -- GitLab From 5d3e07c0220ec84e7db53431166edde50f678990 Mon Sep 17 00:00:00 2001 From: wangmm0220 Date: Mon, 11 Jul 2022 19:10:41 +0800 Subject: [PATCH 008/153] fix:conflict from 3.0 --- source/client/src/tmq.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/source/client/src/tmq.c b/source/client/src/tmq.c index e3dfdc68a8..649584a9a1 100644 --- a/source/client/src/tmq.c +++ b/source/client/src/tmq.c @@ -2114,8 +2114,8 @@ static char *buildCreateCTableJson(STag* pTag, char* sname, char* name, int64_t // cJSON* tname = cJSON_CreateString(pTagVal->colName); // cJSON_AddItemToObject(tag, "name", tname); - cJSON* cid_ = cJSON_CreateString(""); - cJSON_AddItemToObject(tag, "cid", cid_); +// cJSON* cid_ = cJSON_CreateString(""); +// cJSON_AddItemToObject(tag, "cid", cid_); cJSON* ttype = cJSON_CreateNumber(TSDB_DATA_TYPE_JSON); cJSON_AddItemToObject(tag, "type", ttype); cJSON* tvalue = cJSON_CreateString(pJson); @@ -2130,10 +2130,8 @@ static char *buildCreateCTableJson(STag* pTag, char* sname, char* name, int64_t cJSON* tag = cJSON_CreateObject(); - char cid[32] = {0}; - sprintf(cid, "%d", pTagVal->cid); - cJSON* cid_ = cJSON_CreateString(cid); - cJSON_AddItemToObject(tag, "cid", cid_); + cJSON* cid = cJSON_CreateNumber(pTagVal->cid); + cJSON_AddItemToObject(tag, "cid", cid); cJSON* ttype = cJSON_CreateNumber(pTagVal->type); cJSON_AddItemToObject(tag, "type", ttype); -- GitLab From 1f5663f03ef8c6bb6635f1686383caa182145bd0 Mon Sep 17 00:00:00 2001 From: tomchon Date: Mon, 11 Jul 2022 19:52:18 +0800 Subject: [PATCH 009/153] test:add test case of tsbs query --- tests/system-test/2-query/tsbsQuery.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/tests/system-test/2-query/tsbsQuery.py b/tests/system-test/2-query/tsbsQuery.py index d24e5ea283..819380d7fd 100644 --- a/tests/system-test/2-query/tsbsQuery.py +++ b/tests/system-test/2-query/tsbsQuery.py @@ -58,11 +58,18 @@ class TDTestCase: tdSql.query(" SELECT avg(velocity) as mean_velocity ,name,driver,fleet FROM readings WHERE ts > 1451606400000 AND ts <= 1451606460000 partition BY name,driver,fleet interval(10m); ") tdSql.checkRows(1) + # test insert into + tdSql.execute("create table testsnode (ts timestamp, c1 float,c2 binary(30),c3 binary(30),c4 binary(30)) ;") + tdSql.query("insert into testsnode SELECT ts,avg(velocity) as mean_velocity,name,driver,fleet FROM readings WHERE ts > 1451606400000 AND ts <= 1451606460000 partition BY name,driver,fleet,ts interval(10m);") + tdSql.checkRows(1) + + tdSql.query("insert into testsnode(c1,c2,c3,c4) SELECT avg(velocity) as mean_velocity,name,driver,fleet FROM readings WHERE ts > 1451606400000 AND ts <= 1451606460000 partition BY name,driver,fleet interval(10m);") + tdSql.checkRows(1) def run(self): # sourcery skip: extract-duplicate-method, remove-redundant-fstring tdLog.printNoPrefix("==========step1:create database and table,insert data ==============") - self.tsbsIotQuery() + self.prepareData() self.tsbsIotQuery() -- GitLab From 8684f75dcdeafbe05a5b566efd5d1f42907195ba Mon Sep 17 00:00:00 2001 From: tomchon Date: Mon, 11 Jul 2022 20:00:11 +0800 Subject: [PATCH 010/153] test:add test case of tsbs query --- tests/system-test/2-query/tsbsQuery.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/tests/system-test/2-query/tsbsQuery.py b/tests/system-test/2-query/tsbsQuery.py index 819380d7fd..bc7095f627 100644 --- a/tests/system-test/2-query/tsbsQuery.py +++ b/tests/system-test/2-query/tsbsQuery.py @@ -8,7 +8,12 @@ from util.sql import * from util.cases import * class TDTestCase: - + + clientCfgDict = {'queryproxy': '1','debugFlag': 135} + clientCfgDict["debugFlag"] = 143 + updatecfgDict = {'clientCfg': {}} + updatecfgDict["clientCfg"] = clientCfgDict + def init(self, conn, logSql): tdLog.debug(f"start to excute {__file__}") tdSql.init(conn.cursor(), True) @@ -61,10 +66,8 @@ class TDTestCase: # test insert into tdSql.execute("create table testsnode (ts timestamp, c1 float,c2 binary(30),c3 binary(30),c4 binary(30)) ;") tdSql.query("insert into testsnode SELECT ts,avg(velocity) as mean_velocity,name,driver,fleet FROM readings WHERE ts > 1451606400000 AND ts <= 1451606460000 partition BY name,driver,fleet,ts interval(10m);") - tdSql.checkRows(1) - + tdSql.query("insert into testsnode(c1,c2,c3,c4) SELECT avg(velocity) as mean_velocity,name,driver,fleet FROM readings WHERE ts > 1451606400000 AND ts <= 1451606460000 partition BY name,driver,fleet interval(10m);") - tdSql.checkRows(1) def run(self): # sourcery skip: extract-duplicate-method, remove-redundant-fstring -- GitLab From 218c71df6a8bdc02dea0af36d2f1eadd09ec15c7 Mon Sep 17 00:00:00 2001 From: wangmm0220 Date: Mon, 11 Jul 2022 20:03:57 +0800 Subject: [PATCH 011/153] feat:add tmq alter table option --- examples/c/tmq.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/examples/c/tmq.c b/examples/c/tmq.c index c55cb2ca58..f421f344a2 100644 --- a/examples/c/tmq.c +++ b/examples/c/tmq.c @@ -223,6 +223,13 @@ int32_t init_env() { } taos_free_result(pRes); + pRes = taos_query(pConn, "alter table n1 comment 'hello'"); + if (taos_errno(pRes) != 0) { + printf("failed to alter normal table n1, reason:%s\n", taos_errstr(pRes)); + return -1; + } + taos_free_result(pRes); + pRes = taos_query(pConn, "alter table n1 drop column c1"); if (taos_errno(pRes) != 0) { printf("failed to alter normal table n1, reason:%s\n", taos_errstr(pRes)); -- GitLab From 835ddbacf414e20faaba36a55a4b9e1add89c8b4 Mon Sep 17 00:00:00 2001 From: dapan1121 Date: Mon, 11 Jul 2022 21:14:37 +0800 Subject: [PATCH 012/153] fix: fix retry issue --- source/libs/scheduler/inc/schInt.h | 2 ++ source/libs/scheduler/src/schJob.c | 38 ++++++++++++++++++++++++--- source/libs/scheduler/src/schRemote.c | 2 +- source/libs/scheduler/src/schTask.c | 3 ++- 4 files changed, 39 insertions(+), 6 deletions(-) diff --git a/source/libs/scheduler/inc/schInt.h b/source/libs/scheduler/inc/schInt.h index e5c7e37479..4cae547077 100644 --- a/source/libs/scheduler/inc/schInt.h +++ b/source/libs/scheduler/inc/schInt.h @@ -223,6 +223,7 @@ typedef struct SSchJobAttr { typedef struct { int32_t op; + SRWLatch lock; bool syncReq; } SSchOpStatus; @@ -473,6 +474,7 @@ int32_t schGetTaskFromList(SHashObj *pTaskList, uint64_t taskId, SSchTask **pTas int32_t schInitTask(SSchJob *pJob, SSchTask *pTask, SSubplan *pPlan, SSchLevel *pLevel, int32_t levelNum); int32_t schSwitchTaskCandidateAddr(SSchJob *pJob, SSchTask *pTask); void schDirectPostJobRes(SSchedulerReq* pReq, int32_t errCode); +bool schChkCurrentOp(SSchJob *pJob, int32_t op, bool sync); extern SSchDebug gSCHDebug; diff --git a/source/libs/scheduler/src/schJob.c b/source/libs/scheduler/src/schJob.c index e482814ee7..19bb93249f 100644 --- a/source/libs/scheduler/src/schJob.c +++ b/source/libs/scheduler/src/schJob.c @@ -443,25 +443,37 @@ int32_t schNotifyUserFetchRes(SSchJob* pJob) { } void schPostJobRes(SSchJob *pJob, SCH_OP_TYPE op) { + SCH_LOCK(SCH_WRITE, &pJob->opStatus.lock); + if (SCH_OP_NULL == pJob->opStatus.op) { SCH_JOB_DLOG("job not in any operation, no need to post job res, status:%s", jobTaskStatusStr(pJob->status)); - return; + goto _return; } if (op && pJob->opStatus.op != op) { SCH_JOB_ELOG("job in operation %s mis-match with expected %s", schGetOpStr(pJob->opStatus.op), schGetOpStr(op)); - return; + goto _return; } if (SCH_JOB_IN_SYNC_OP(pJob)) { + SCH_UNLOCK(SCH_WRITE, &pJob->opStatus.lock); tsem_post(&pJob->rspSem); } else if (SCH_JOB_IN_ASYNC_EXEC_OP(pJob)) { + SCH_UNLOCK(SCH_WRITE, &pJob->opStatus.lock); schNotifyUserExecRes(pJob); } else if (SCH_JOB_IN_ASYNC_FETCH_OP(pJob)) { + SCH_UNLOCK(SCH_WRITE, &pJob->opStatus.lock); schNotifyUserFetchRes(pJob); } else { + SCH_UNLOCK(SCH_WRITE, &pJob->opStatus.lock); SCH_JOB_ELOG("job not in any operation, status:%s", jobTaskStatusStr(pJob->status)); } + + return; + +_return: + + SCH_UNLOCK(SCH_WRITE, &pJob->opStatus.lock); } int32_t schProcessOnJobFailureImpl(SSchJob *pJob, int32_t status, int32_t errCode) { @@ -658,13 +670,13 @@ int32_t schJobFetchRows(SSchJob *pJob) { if (!(pJob->attr.explainMode == EXPLAIN_MODE_STATIC)) { SCH_ERR_RET(schLaunchFetchTask(pJob)); - if (pJob->opStatus.syncReq) { + if (schChkCurrentOp(pJob, SCH_OP_FETCH, true)) { SCH_JOB_DLOG("sync wait for rsp now, job status:%s", SCH_GET_JOB_STATUS_STR(pJob)); tsem_wait(&pJob->rspSem); SCH_RET(schDumpJobFetchRes(pJob, pJob->userRes.fetchRes)); } } else { - if (pJob->opStatus.syncReq) { + if (schChkCurrentOp(pJob, SCH_OP_FETCH, true)) { SCH_RET(schDumpJobFetchRes(pJob, pJob->userRes.fetchRes)); } else { schPostJobRes(pJob, SCH_OP_FETCH); @@ -775,25 +787,37 @@ void schDirectPostJobRes(SSchedulerReq* pReq, int32_t errCode) { } } +bool schChkCurrentOp(SSchJob *pJob, int32_t op, bool sync) { + SCH_LOCK(SCH_READ, &pJob->opStatus.lock); + bool r = (pJob->opStatus.op == op) && (pJob->opStatus.syncReq == sync); + SCH_UNLOCK(SCH_READ, &pJob->opStatus.lock); + + return r; +} + void schProcessOnOpEnd(SSchJob *pJob, SCH_OP_TYPE type, SSchedulerReq* pReq, int32_t errCode) { int32_t op = 0; switch (type) { case SCH_OP_EXEC: if (pReq && pReq->syncReq) { + SCH_LOCK(SCH_WRITE, &pJob->opStatus.lock); op = atomic_val_compare_exchange_32(&pJob->opStatus.op, type, SCH_OP_NULL); if (SCH_OP_NULL == op || op != type) { SCH_JOB_ELOG("job not in %s operation, op:%s, status:%s", schGetOpStr(type), schGetOpStr(op), jobTaskStatusStr(pJob->status)); } + SCH_UNLOCK(SCH_WRITE, &pJob->opStatus.lock); schDumpJobExecRes(pJob, pReq->pExecRes); } break; case SCH_OP_FETCH: if (pReq && pReq->syncReq) { + SCH_LOCK(SCH_WRITE, &pJob->opStatus.lock); op = atomic_val_compare_exchange_32(&pJob->opStatus.op, type, SCH_OP_NULL); if (SCH_OP_NULL == op || op != type) { SCH_JOB_ELOG("job not in %s operation, op:%s, status:%s", schGetOpStr(type), schGetOpStr(op), jobTaskStatusStr(pJob->status)); } + SCH_UNLOCK(SCH_WRITE, &pJob->opStatus.lock); } break; case SCH_OP_GET_STATUS: @@ -816,8 +840,10 @@ int32_t schProcessOnOpBegin(SSchJob* pJob, SCH_OP_TYPE type, SSchedulerReq* pReq switch (type) { case SCH_OP_EXEC: + SCH_LOCK(SCH_WRITE, &pJob->opStatus.lock); if (SCH_OP_NULL != atomic_val_compare_exchange_32(&pJob->opStatus.op, SCH_OP_NULL, type)) { SCH_JOB_ELOG("job already in %s operation", schGetOpStr(pJob->opStatus.op)); + SCH_UNLOCK(SCH_WRITE, &pJob->opStatus.lock); schDirectPostJobRes(pReq, TSDB_CODE_TSC_APP_ERROR); SCH_ERR_RET(TSDB_CODE_TSC_APP_ERROR); } @@ -825,10 +851,13 @@ int32_t schProcessOnOpBegin(SSchJob* pJob, SCH_OP_TYPE type, SSchedulerReq* pReq SCH_JOB_DLOG("job start %s operation", schGetOpStr(pJob->opStatus.op)); pJob->opStatus.syncReq = pReq->syncReq; + SCH_UNLOCK(SCH_WRITE, &pJob->opStatus.lock); break; case SCH_OP_FETCH: + SCH_LOCK(SCH_WRITE, &pJob->opStatus.lock); if (SCH_OP_NULL != atomic_val_compare_exchange_32(&pJob->opStatus.op, SCH_OP_NULL, type)) { SCH_JOB_ELOG("job already in %s operation", schGetOpStr(pJob->opStatus.op)); + SCH_UNLOCK(SCH_WRITE, &pJob->opStatus.lock); schDirectPostJobRes(pReq, TSDB_CODE_TSC_APP_ERROR); SCH_ERR_RET(TSDB_CODE_TSC_APP_ERROR); } @@ -840,6 +869,7 @@ int32_t schProcessOnOpBegin(SSchJob* pJob, SCH_OP_TYPE type, SSchedulerReq* pReq pJob->userRes.cbParam = pReq->cbParam; pJob->opStatus.syncReq = pReq->syncReq; + SCH_UNLOCK(SCH_WRITE, &pJob->opStatus.lock); if (!SCH_JOB_NEED_FETCH(pJob)) { SCH_JOB_ELOG("no need to fetch data, status:%s", SCH_GET_JOB_STATUS_STR(pJob)); diff --git a/source/libs/scheduler/src/schRemote.c b/source/libs/scheduler/src/schRemote.c index 2257ba8328..3db1ba7be8 100644 --- a/source/libs/scheduler/src/schRemote.c +++ b/source/libs/scheduler/src/schRemote.c @@ -940,7 +940,7 @@ int32_t schBuildAndSendMsg(SSchJob *pJob, SSchTask *pTask, SQueryNodeAddr *addr, if (NULL == addr) { addr = taosArrayGet(pTask->candidateAddrs, pTask->candidateIdx); isCandidateAddr = true; - SCH_TASK_DLOG("target candidateIdx %d", pTask->candidateIdx); + SCH_TASK_DLOG("target candidateIdx %d, epInUse %d/%d", pTask->candidateIdx, addr->epSet.inUse, addr->epSet.numOfEps); } switch (msgType) { diff --git a/source/libs/scheduler/src/schTask.c b/source/libs/scheduler/src/schTask.c index a6621d279d..d77fbc33fd 100644 --- a/source/libs/scheduler/src/schTask.c +++ b/source/libs/scheduler/src/schTask.c @@ -545,7 +545,8 @@ int32_t schHandleTaskRetry(SSchJob *pJob, SSchTask *pTask) { schDeregisterTaskHb(pJob, pTask); if (SCH_IS_DATA_BIND_TASK(pTask)) { - SCH_SWITCH_EPSET(&pTask->plan->execNode); + SQueryNodeAddr *addr = taosArrayGet(pTask->candidateAddrs, pTask->candidateIdx); + SCH_SWITCH_EPSET(addr); } else { SCH_ERR_RET(schSwitchTaskCandidateAddr(pJob, pTask)); } -- GitLab From 7fcf80a8f92515f9981290943434558225748f9c Mon Sep 17 00:00:00 2001 From: dapan1121 Date: Tue, 12 Jul 2022 09:24:01 +0800 Subject: [PATCH 013/153] enh: add more retry times for data src task --- source/libs/scheduler/src/schTask.c | 2 ++ tests/script/api/stopquery.c | 10 +++++----- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/source/libs/scheduler/src/schTask.c b/source/libs/scheduler/src/schTask.c index d77fbc33fd..b83e24d6df 100644 --- a/source/libs/scheduler/src/schTask.c +++ b/source/libs/scheduler/src/schTask.c @@ -508,6 +508,7 @@ int32_t schTaskCheckSetRetry(SSchJob *pJob, SSchTask *pTask, int32_t errCode, bo return TSDB_CODE_SUCCESS; } +/* if (SCH_IS_DATA_BIND_TASK(pTask)) { if ((pTask->execId + 1) >= SCH_TASK_NUM_OF_EPS(&pTask->plan->execNode)) { *needRetry = false; @@ -525,6 +526,7 @@ int32_t schTaskCheckSetRetry(SSchJob *pJob, SSchTask *pTask, int32_t errCode, bo return TSDB_CODE_SUCCESS; } } +*/ *needRetry = true; SCH_TASK_DLOG("task need the %dth retry, errCode:%x - %s", pTask->execId + 1, errCode, tstrerror(errCode)); diff --git a/tests/script/api/stopquery.c b/tests/script/api/stopquery.c index 0f27fdf9f9..eeaf9295d9 100644 --- a/tests/script/api/stopquery.c +++ b/tests/script/api/stopquery.c @@ -578,6 +578,8 @@ int sqConKillSyncQuery(bool fetch) { pthread_join(qid, NULL); pthread_join(cid, NULL); + + taos_close(param.taos); } CASE_LEAVE(); } @@ -593,6 +595,8 @@ int sqConKillAsyncQuery(bool fetch) { pthread_join(qid, NULL); pthread_join(cid, NULL); + + taos_close(param.taos); } CASE_LEAVE(); } @@ -600,7 +604,6 @@ int sqConKillAsyncQuery(bool fetch) { void sqRunAllCase(void) { -/* sqStopSyncQuery(false); sqStopSyncQuery(true); sqStopAsyncQuery(false); @@ -620,17 +623,14 @@ void sqRunAllCase(void) { sqConCloseSyncQuery(true); sqConCloseAsyncQuery(false); sqConCloseAsyncQuery(true); -*/ -#if 0 sqKillSyncQuery(false); sqKillSyncQuery(true); sqKillAsyncQuery(false); sqKillAsyncQuery(true); -#endif - //sqConKillSyncQuery(false); + sqConKillSyncQuery(false); sqConKillSyncQuery(true); #if 0 sqConKillAsyncQuery(false); -- GitLab From e3a48b01ecf1109a9fd8f86069c687c9b8dc7c8d Mon Sep 17 00:00:00 2001 From: tomchon Date: Tue, 12 Jul 2022 14:25:02 +0800 Subject: [PATCH 014/153] test:add testcase of qnode --- tests/system-test/fulltest.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/system-test/fulltest.sh b/tests/system-test/fulltest.sh index 3b0dd76a30..1884420ccd 100755 --- a/tests/system-test/fulltest.sh +++ b/tests/system-test/fulltest.sh @@ -120,7 +120,7 @@ python3 ./test.py -f 2-query/irate.py python3 ./test.py -f 2-query/and_or_for_byte.py python3 ./test.py -f 2-query/function_null.py -#python3 ./test.py -f 2-query/queryQnode.py +python3 ./test.py -f 2-query/queryQnode.py python3 ./test.py -f 6-cluster/5dnode1mnode.py #BUG python3 ./test.py -f 6-cluster/5dnode2mnode.py -N 5 -M 3 -- GitLab From 9f0152239d9bacda1168e1de5568ef1af5362a9d Mon Sep 17 00:00:00 2001 From: dapan1121 Date: Tue, 12 Jul 2022 14:56:12 +0800 Subject: [PATCH 015/153] fix: fix stop query --- source/libs/catalog/src/catalog.c | 1 + source/util/src/tref.c | 2 +- tests/script/api/stopquery.c | 14 ++++++++++---- 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/source/libs/catalog/src/catalog.c b/source/libs/catalog/src/catalog.c index 3a7ad4a2d6..1b7f53ae67 100644 --- a/source/libs/catalog/src/catalog.c +++ b/source/libs/catalog/src/catalog.c @@ -1293,6 +1293,7 @@ void catalogDestroy(void) { if (!taosCheckCurrentInDll()) { ctgClearCacheEnqueue(NULL, true, true, true); + taosThreadJoin(gCtgMgmt.updateThread, NULL); } taosHashCleanup(gCtgMgmt.pCluster); diff --git a/source/util/src/tref.c b/source/util/src/tref.c index 2e4c33bc87..9cd849b9be 100644 --- a/source/util/src/tref.c +++ b/source/util/src/tref.c @@ -431,7 +431,7 @@ static int32_t taosDecRefCount(int32_t rsetId, int64_t rid, int32_t remove) { } released = 1; } else { - uTrace("rsetId:%d p:%p rid:%" PRId64 " is released", rsetId, pNode->p, rid); + uTrace("rsetId:%d p:%p rid:%" PRId64 " is released, remain count %d", rsetId, pNode->p, rid, pNode->count); } } else { uTrace("rsetId:%d rid:%" PRId64 " is not there, failed to release/remove", rsetId, rid); diff --git a/tests/script/api/stopquery.c b/tests/script/api/stopquery.c index eeaf9295d9..a42e9e2d44 100644 --- a/tests/script/api/stopquery.c +++ b/tests/script/api/stopquery.c @@ -36,7 +36,7 @@ int64_t st, et; char hostName[128]; char dbName[128]; char tbName[128]; -int32_t runTimes = 10000; +int32_t runTimes = 1000; typedef struct { int id; @@ -88,6 +88,7 @@ static void sqExecSQLE(TAOS *taos, char *command) { void sqExit(char* prefix, const char* errMsg) { fprintf(stderr, "%s error: %s\n", prefix, errMsg); + sleep(10000); exit(1); } @@ -141,16 +142,20 @@ void sqCloseFetchCb(void *param, TAOS_RES *pRes, int numOfRows) { taos_close(qParam->taos); *qParam->end = 1; + + taos_free_result(pRes); } void sqCloseQueryCb(void *param, TAOS_RES *pRes, int code) { SSP_CB_PARAM *qParam = (SSP_CB_PARAM *)param; if (code == 0 && pRes) { if (qParam->fetch) { - taos_fetch_rows_a(pRes, sqFreeFetchCb, param); + taos_fetch_rows_a(pRes, sqCloseFetchCb, param); } else { taos_close(qParam->taos); *qParam->end = 1; + + taos_free_result(pRes); } } else { sqExit("select", taos_errstr(pRes)); @@ -358,6 +363,7 @@ int sqCloseSyncQuery(bool fetch) { } taos_close(taos); + taos_free_result(pRes); } CASE_LEAVE(); } @@ -382,7 +388,7 @@ int sqCloseAsyncQuery(bool fetch) { SSP_CB_PARAM param = {0}; param.fetch = fetch; param.end = &qEnd; - taos_query_a(taos, sql, sqFreeQueryCb, ¶m); + taos_query_a(taos, sql, sqCloseQueryCb, ¶m); while (0 == qEnd) { usleep(5000); } @@ -640,7 +646,7 @@ void sqRunAllCase(void) { int32_t l = 5; while (l) { printf("%d\n", l--); - sleep(1); + sleep(1000); } } -- GitLab From 2641714e87808cfe3c40b4b1cd81803b8d33f26a Mon Sep 17 00:00:00 2001 From: tomchon Date: Tue, 12 Jul 2022 15:20:05 +0800 Subject: [PATCH 016/153] test:add test case of tsbs query --- tests/system-test/2-query/tsbsQuery.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/tests/system-test/2-query/tsbsQuery.py b/tests/system-test/2-query/tsbsQuery.py index bc7095f627..be3a788006 100644 --- a/tests/system-test/2-query/tsbsQuery.py +++ b/tests/system-test/2-query/tsbsQuery.py @@ -10,8 +10,9 @@ from util.cases import * class TDTestCase: clientCfgDict = {'queryproxy': '1','debugFlag': 135} - clientCfgDict["debugFlag"] = 143 + clientCfgDict["debugFlag"] = 131 updatecfgDict = {'clientCfg': {}} + updatecfgDict = {'debugFlag': 131} updatecfgDict["clientCfg"] = clientCfgDict def init(self, conn, logSql): @@ -60,9 +61,14 @@ class TDTestCase: def tsbsIotQuery(self): tdSql.execute("use db_tsbs") + + # test interval and partition + tdSql.query(" SELECT avg(velocity) as mean_velocity ,name,driver,fleet FROM readings WHERE ts > 1451606400000 AND ts <= 1451606460000 partition BY name,driver,fleet; ") + parRows=tdSql.queryRows tdSql.query(" SELECT avg(velocity) as mean_velocity ,name,driver,fleet FROM readings WHERE ts > 1451606400000 AND ts <= 1451606460000 partition BY name,driver,fleet interval(10m); ") - tdSql.checkRows(1) - + tdSql.checkRows(parRows) + + # test insert into tdSql.execute("create table testsnode (ts timestamp, c1 float,c2 binary(30),c3 binary(30),c4 binary(30)) ;") tdSql.query("insert into testsnode SELECT ts,avg(velocity) as mean_velocity,name,driver,fleet FROM readings WHERE ts > 1451606400000 AND ts <= 1451606460000 partition BY name,driver,fleet,ts interval(10m);") -- GitLab From 759bc7c434ff1de23f72fb465d0b415a9a850f6d Mon Sep 17 00:00:00 2001 From: Xiaoyu Wang Date: Tue, 12 Jul 2022 16:51:37 +0800 Subject: [PATCH 017/153] feat: the 'null' value for the user is of type 'varchar(0)' --- source/libs/function/src/builtins.c | 2 +- source/libs/parser/src/parCalcConst.c | 2 +- source/libs/parser/src/parTranslater.c | 9 +++++++-- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/source/libs/function/src/builtins.c b/source/libs/function/src/builtins.c index a735edafab..f4dadbf5d0 100644 --- a/source/libs/function/src/builtins.c +++ b/source/libs/function/src/builtins.c @@ -1976,7 +1976,7 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = { { .name = "leastsquares", .type = FUNCTION_TYPE_LEASTSQUARES, - .classification = FUNC_MGT_AGG_FUNC | FUNC_MGT_FORBID_STREAM_FUNC, + .classification = FUNC_MGT_AGG_FUNC | FUNC_MGT_TIMELINE_FUNC | FUNC_MGT_FORBID_STREAM_FUNC, .translateFunc = translateLeastSQR, .getEnvFunc = getLeastSQRFuncEnv, .initFunc = leastSQRFunctionSetup, diff --git a/source/libs/parser/src/parCalcConst.c b/source/libs/parser/src/parCalcConst.c index 4dff42592a..b799ae5fb1 100644 --- a/source/libs/parser/src/parCalcConst.c +++ b/source/libs/parser/src/parCalcConst.c @@ -218,7 +218,7 @@ static SNode* createConstantValue() { static int32_t calcConstProjections(SCalcConstContext* pCxt, SSelectStmt* pSelect, bool subquery) { SNode* pProj = NULL; WHERE_EACH(pProj, pSelect->pProjectionList) { - if (subquery && isUselessCol((SExprNode*)pProj)) { + if (subquery && !pSelect->isDistinct && isUselessCol((SExprNode*)pProj)) { ERASE_NODE(pSelect->pProjectionList); continue; } diff --git a/source/libs/parser/src/parTranslater.c b/source/libs/parser/src/parTranslater.c index da393bb883..ca000fcf2d 100644 --- a/source/libs/parser/src/parTranslater.c +++ b/source/libs/parser/src/parTranslater.c @@ -4757,8 +4757,13 @@ static int32_t extractQueryResultSchema(const SNodeList* pProjections, int32_t* int32_t index = 0; FOREACH(pNode, pProjections) { SExprNode* pExpr = (SExprNode*)pNode; - (*pSchema)[index].type = pExpr->resType.type; - (*pSchema)[index].bytes = pExpr->resType.bytes; + if (TSDB_DATA_TYPE_NULL == pExpr->resType.type) { + (*pSchema)[index].type = TSDB_DATA_TYPE_VARCHAR; + (*pSchema)[index].bytes = 0; + } else { + (*pSchema)[index].type = pExpr->resType.type; + (*pSchema)[index].bytes = pExpr->resType.bytes; + } (*pSchema)[index].colId = index + 1; if ('\0' != pExpr->userAlias[0]) { strcpy((*pSchema)[index].name, pExpr->userAlias); -- GitLab From 473e134f310c699249f319ff773eb4830f32eb2a Mon Sep 17 00:00:00 2001 From: Minghao Li Date: Tue, 12 Jul 2022 16:57:19 +0800 Subject: [PATCH 018/153] refactor(sync): add resp ttl clean --- include/libs/sync/sync.h | 2 + source/dnode/vnode/src/vnd/vnodeSync.c | 23 +++++++---- source/libs/sync/src/syncMain.c | 9 +---- source/libs/sync/src/syncRespMgr.c | 53 ++++++++++---------------- source/libs/sync/src/syncTimeout.c | 2 + 5 files changed, 42 insertions(+), 47 deletions(-) diff --git a/include/libs/sync/sync.h b/include/libs/sync/sync.h index bef26cb310..c226d7c8cc 100644 --- a/include/libs/sync/sync.h +++ b/include/libs/sync/sync.h @@ -26,6 +26,8 @@ extern "C" { extern bool gRaftDetailLog; +#define SYNC_RESP_TTL_MS 5000 + #define SYNC_MAX_BATCH_SIZE 500 #define SYNC_INDEX_BEGIN 0 #define SYNC_INDEX_INVALID -1 diff --git a/source/dnode/vnode/src/vnd/vnodeSync.c b/source/dnode/vnode/src/vnd/vnodeSync.c index bdcfe208d6..87148a8450 100644 --- a/source/dnode/vnode/src/vnd/vnodeSync.c +++ b/source/dnode/vnode/src/vnd/vnodeSync.c @@ -427,13 +427,22 @@ static void vnodeSyncCommitMsg(SSyncFSM *pFsm, const SRpcMsg *pMsg, SFsmCbMeta c syncGetVgId(pVnode->sync), pFsm, cbMeta.index, cbMeta.isWeak, cbMeta.code, cbMeta.state, syncUtilState2String(cbMeta.state), pMsg->msgType, TMSG_INFO(pMsg->msgType)); - SRpcMsg rpcMsg = {.msgType = pMsg->msgType, .contLen = pMsg->contLen}; - rpcMsg.pCont = rpcMallocCont(rpcMsg.contLen); - memcpy(rpcMsg.pCont, pMsg->pCont, pMsg->contLen); - syncGetAndDelRespRpc(pVnode->sync, cbMeta.seqNum, &rpcMsg.info); - rpcMsg.info.conn.applyIndex = cbMeta.index; - rpcMsg.info.conn.applyTerm = cbMeta.term; - tmsgPutToQueue(&pVnode->msgCb, APPLY_QUEUE, &rpcMsg); + if (cbMeta.code == 0) { + SRpcMsg rpcMsg = {.msgType = pMsg->msgType, .contLen = pMsg->contLen}; + rpcMsg.pCont = rpcMallocCont(rpcMsg.contLen); + memcpy(rpcMsg.pCont, pMsg->pCont, pMsg->contLen); + syncGetAndDelRespRpc(pVnode->sync, cbMeta.seqNum, &rpcMsg.info); + rpcMsg.info.conn.applyIndex = cbMeta.index; + rpcMsg.info.conn.applyTerm = cbMeta.term; + tmsgPutToQueue(&pVnode->msgCb, APPLY_QUEUE, &rpcMsg); + } else { + SRpcMsg rsp = {.code = cbMeta.code, .info = pMsg->info}; + vError("vgId:%d, sync commit error, msgtype:%d,%s, error:0x%X, errmsg:%s", syncGetVgId(pVnode->sync), pMsg->msgType, + TMSG_INFO(pMsg->msgType), cbMeta.code, tstrerror(cbMeta.code)); + if (rsp.info.handle != NULL) { + tmsgSendRsp(&rsp); + } + } } static void vnodeSyncPreCommitMsg(SSyncFSM *pFsm, const SRpcMsg *pMsg, SFsmCbMeta cbMeta) { diff --git a/source/libs/sync/src/syncMain.c b/source/libs/sync/src/syncMain.c index abc0f53611..918496c894 100644 --- a/source/libs/sync/src/syncMain.c +++ b/source/libs/sync/src/syncMain.c @@ -1055,19 +1055,12 @@ SSyncNode* syncNodeOpen(const SSyncInfo* pOldSyncInfo) { } // tools - pSyncNode->pSyncRespMgr = syncRespMgrCreate(pSyncNode, 0); + pSyncNode->pSyncRespMgr = syncRespMgrCreate(pSyncNode, SYNC_RESP_TTL_MS); ASSERT(pSyncNode->pSyncRespMgr != NULL); // restore state pSyncNode->restoreFinish = false; - // pSyncNode->pSnapshot = NULL; - // if (pSyncNode->pFsm->FpGetSnapshotInfo != NULL) { - // pSyncNode->pSnapshot = taosMemoryMalloc(sizeof(SSnapshot)); - // pSyncNode->pFsm->FpGetSnapshotInfo(pSyncNode->pFsm, pSyncNode->pSnapshot); - // } - // tsem_init(&(pSyncNode->restoreSem), 0, 0); - // snapshot senders for (int i = 0; i < TSDB_MAX_REPLICA; ++i) { SSyncSnapshotSender* pSender = snapshotSenderCreate(pSyncNode, i); diff --git a/source/libs/sync/src/syncRespMgr.c b/source/libs/sync/src/syncRespMgr.c index eaeadd3991..2aaa98b299 100644 --- a/source/libs/sync/src/syncRespMgr.c +++ b/source/libs/sync/src/syncRespMgr.c @@ -122,54 +122,43 @@ void syncRespCleanByTTL(SSyncRespMgr *pObj, int64_t ttl) { int cnt = 0; SSyncNode *pSyncNode = pObj->data; - SArray *delIndexArray = taosArrayInit(0, sizeof(SyncIndex)); + SArray *delIndexArray = taosArrayInit(0, sizeof(uint64_t)); ASSERT(delIndexArray != NULL); while (pStub) { - size_t len; - void * key = taosHashGetKey(pStub, &len); - SyncIndex *pIndex = (SyncIndex *)key; + size_t len; + void *key = taosHashGetKey(pStub, &len); + uint64_t *pSeqNum = (uint64_t *)key; int64_t nowMS = taosGetTimestampMs(); if (nowMS - pStub->createTime > ttl) { - taosArrayPush(delIndexArray, pIndex); + taosArrayPush(delIndexArray, pSeqNum); cnt++; - SSyncRaftEntry *pEntry = NULL; - int32_t code = 0; - if (pSyncNode->pLogStore != NULL) { - code = pSyncNode->pLogStore->syncLogGetEntry(pSyncNode->pLogStore, *pIndex, &pEntry); - if (code == 0 && pEntry != NULL) { - SFsmCbMeta cbMeta = {0}; - cbMeta.index = pEntry->index; - cbMeta.lastConfigIndex = syncNodeGetSnapshotConfigIndex(pSyncNode, cbMeta.index); - cbMeta.isWeak = pEntry->isWeak; - cbMeta.code = TSDB_CODE_SYN_TIMEOUT; - cbMeta.state = pSyncNode->state; - cbMeta.seqNum = pEntry->seqNum; - cbMeta.term = pEntry->term; - cbMeta.currentTerm = pSyncNode->pRaftStore->currentTerm; - cbMeta.flag = 0; - - SRpcMsg rpcMsg = pStub->rpcMsg; - rpcMsg.pCont = rpcMallocCont(pEntry->dataLen); - memcpy(rpcMsg.pCont, pEntry->data, pEntry->dataLen); - pSyncNode->pFsm->FpCommitCb(pSyncNode->pFsm, &rpcMsg, cbMeta); - - syncEntryDestory(pEntry); - } - } + SFsmCbMeta cbMeta = {0}; + cbMeta.index = SYNC_INDEX_INVALID; + cbMeta.lastConfigIndex = SYNC_INDEX_INVALID; + cbMeta.isWeak = false; + cbMeta.code = TSDB_CODE_SYN_TIMEOUT; + cbMeta.state = pSyncNode->state; + cbMeta.seqNum = *pSeqNum; + cbMeta.term = SYNC_TERM_INVALID; + cbMeta.currentTerm = pSyncNode->pRaftStore->currentTerm; + cbMeta.flag = 0; + + pSyncNode->pFsm->FpCommitCb(pSyncNode->pFsm, &(pStub->rpcMsg), cbMeta); } pStub = (SRespStub *)taosHashIterate(pObj->pRespHash, pStub); } int32_t arraySize = taosArrayGetSize(delIndexArray); - sDebug("vgId:%d, resp clean by ttl, cnt:%d, array-size:%d", pSyncNode->vgId, cnt, arraySize); + sDebug("vgId:%d, resp mgr clean by ttl, cnt:%d, array-size:%d", pSyncNode->vgId, cnt, arraySize); for (int32_t i = 0; i < arraySize; ++i) { - SyncIndex *pIndex = taosArrayGet(delIndexArray, i); - taosHashRemove(pObj->pRespHash, pIndex, sizeof(SyncIndex)); + uint64_t *pSeqNum = taosArrayGet(delIndexArray, i); + taosHashRemove(pObj->pRespHash, pSeqNum, sizeof(uint64_t)); + sDebug("vgId:%d, resp mgr clean by ttl, seq:%d", pSyncNode->vgId, *pSeqNum); } taosArrayDestroy(delIndexArray); } diff --git a/source/libs/sync/src/syncTimeout.c b/source/libs/sync/src/syncTimeout.c index 52181a3da8..97de75c108 100644 --- a/source/libs/sync/src/syncTimeout.c +++ b/source/libs/sync/src/syncTimeout.c @@ -16,9 +16,11 @@ #include "syncTimeout.h" #include "syncElection.h" #include "syncReplication.h" +#include "syncRespMgr.h" int32_t syncNodeTimerRoutine(SSyncNode* ths) { syncNodeEventLog(ths, "timer routines ... "); + syncRespClean(ths->pSyncRespMgr); return 0; } -- GitLab From 2b442621e85fc31e6d17b2bd95f7108ab7d8d38a Mon Sep 17 00:00:00 2001 From: wangmm0220 Date: Tue, 12 Jul 2022 18:58:33 +0800 Subject: [PATCH 019/153] feat:get child table name in tmq meta --- examples/c/tmq.c | 10 ++--- include/common/tdataformat.h | 2 +- include/common/tmsg.h | 4 +- source/client/src/tmq.c | 16 +++++--- source/common/src/tmsg.c | 15 +++++++ source/dnode/mnode/sdb/inc/sdb.h | 1 + source/libs/parser/src/parInsert.c | 39 +++++++++++++++---- source/libs/parser/src/parTranslater.c | 25 ++++++++---- source/libs/parser/src/parUtil.c | 2 +- source/libs/scalar/src/sclfunc.c | 2 +- .../libs/scalar/test/scalar/scalarTests.cpp | 4 +- 11 files changed, 87 insertions(+), 33 deletions(-) diff --git a/examples/c/tmq.c b/examples/c/tmq.c index f421f344a2..c114237353 100644 --- a/examples/c/tmq.c +++ b/examples/c/tmq.c @@ -97,14 +97,14 @@ int32_t init_env() { taos_free_result(pRes); pRes = - taos_query(pConn, "create stable if not exists st1 (ts timestamp, c1 int, c2 float, c3 binary(16)) tags(t1 int)"); + taos_query(pConn, "create stable if not exists st1 (ts timestamp, c1 int, c2 float, c3 binary(16)) tags(t1 int, t3 nchar(8), t4 bool)"); if (taos_errno(pRes) != 0) { printf("failed to create super table st1, reason:%s\n", taos_errstr(pRes)); return -1; } taos_free_result(pRes); - pRes = taos_query(pConn, "create table if not exists ct0 using st1 tags(1000)"); + pRes = taos_query(pConn, "create table if not exists ct0 using st1 tags(1000, \"ttt\", true)"); if (taos_errno(pRes) != 0) { printf("failed to create child table tu1, reason:%s\n", taos_errstr(pRes)); return -1; @@ -118,14 +118,14 @@ int32_t init_env() { } taos_free_result(pRes); - pRes = taos_query(pConn, "create table if not exists ct1 using st1 tags(2000)"); + pRes = taos_query(pConn, "create table if not exists ct1 using st1(t1) tags(2000)"); if (taos_errno(pRes) != 0) { printf("failed to create child table ct1, reason:%s\n", taos_errstr(pRes)); return -1; } taos_free_result(pRes); - pRes = taos_query(pConn, "create table if not exists ct2 using st1 tags(NULL)"); + pRes = taos_query(pConn, "create table if not exists ct2 using st1(t1) tags(NULL)"); if (taos_errno(pRes) != 0) { printf("failed to create child table ct2, reason:%s\n", taos_errstr(pRes)); return -1; @@ -139,7 +139,7 @@ int32_t init_env() { } taos_free_result(pRes); - pRes = taos_query(pConn, "create table if not exists ct3 using st1 tags(3000)"); + pRes = taos_query(pConn, "create table if not exists ct3 using st1(t1) tags(3000)"); if (taos_errno(pRes) != 0) { printf("failed to create child table ct3, reason:%s\n", taos_errstr(pRes)); return -1; diff --git a/include/common/tdataformat.h b/include/common/tdataformat.h index d37b8ce1ca..6f54472dbb 100644 --- a/include/common/tdataformat.h +++ b/include/common/tdataformat.h @@ -97,7 +97,7 @@ int32_t tEncodeTag(SEncoder *pEncoder, const STag *pTag); int32_t tDecodeTag(SDecoder *pDecoder, STag **ppTag); int32_t tTagToValArray(const STag *pTag, SArray **ppArray); void debugPrintSTag(STag *pTag, const char *tag, int32_t ln); // TODO: remove -int32_t parseJsontoTagData(const char* json, SArray* pTagVals, STag** ppTag, void* pMsgBuf, const char* colName); +int32_t parseJsontoTagData(const char* json, SArray* pTagVals, STag** ppTag, void* pMsgBuf); // STRUCT ================= struct STColumn { diff --git a/include/common/tmsg.h b/include/common/tmsg.h index e157c4cc1b..5e7e045b78 100644 --- a/include/common/tmsg.h +++ b/include/common/tmsg.h @@ -1968,8 +1968,9 @@ typedef struct SVCreateTbReq { int8_t type; union { struct { - char* name; + char* name; // super table name tb_uid_t suid; + SArray* tagName; uint8_t* pTag; } ctb; struct { @@ -1987,6 +1988,7 @@ static FORCE_INLINE void tdDestroySVCreateTbReq(SVCreateTbReq* req) { if (req->type == TSDB_CHILD_TABLE) { taosMemoryFreeClear(req->ctb.pTag); taosMemoryFreeClear(req->ctb.name); + taosArrayDestroy(req->ctb.tagName); } else if (req->type == TSDB_NORMAL_TABLE) { taosMemoryFreeClear(req->ntb.schemaRow.pSchema); } diff --git a/source/client/src/tmq.c b/source/client/src/tmq.c index 649584a9a1..c5cf6eecdf 100644 --- a/source/client/src/tmq.c +++ b/source/client/src/tmq.c @@ -2074,7 +2074,7 @@ static char *processAlterStb(SMqMetaRsp *metaRsp){ return string; } -static char *buildCreateCTableJson(STag* pTag, char* sname, char* name, int64_t id){ +static char *buildCreateCTableJson(STag* pTag, char* sname, char* name, SArray* tagName, int64_t id){ char* string = NULL; SArray* pTagVals = NULL; cJSON* json = cJSON_CreateObject(); @@ -2112,8 +2112,9 @@ static char *buildCreateCTableJson(STag* pTag, char* sname, char* name, int64_t cJSON* tag = cJSON_CreateObject(); STagVal* pTagVal = taosArrayGet(pTagVals, 0); -// cJSON* tname = cJSON_CreateString(pTagVal->colName); -// cJSON_AddItemToObject(tag, "name", tname); + char* ptname = taosArrayGet(tagName, 0); + cJSON* tname = cJSON_CreateString(ptname); + cJSON_AddItemToObject(tag, "name", tname); // cJSON* cid_ = cJSON_CreateString(""); // cJSON_AddItemToObject(tag, "cid", cid_); cJSON* ttype = cJSON_CreateNumber(TSDB_DATA_TYPE_JSON); @@ -2130,8 +2131,11 @@ static char *buildCreateCTableJson(STag* pTag, char* sname, char* name, int64_t cJSON* tag = cJSON_CreateObject(); - cJSON* cid = cJSON_CreateNumber(pTagVal->cid); - cJSON_AddItemToObject(tag, "cid", cid); + char* ptname = taosArrayGet(tagName, i); + cJSON* tname = cJSON_CreateString(ptname); + cJSON_AddItemToObject(tag, "name", tname); +// cJSON* cid = cJSON_CreateNumber(pTagVal->cid); +// cJSON_AddItemToObject(tag, "cid", cid); cJSON* ttype = cJSON_CreateNumber(pTagVal->type); cJSON_AddItemToObject(tag, "type", ttype); @@ -2175,7 +2179,7 @@ static char *processCreateTable(SMqMetaRsp *metaRsp){ for (int32_t iReq = 0; iReq < req.nReqs; iReq++) { pCreateReq = req.pReqs + iReq; if(pCreateReq->type == TSDB_CHILD_TABLE){ - string = buildCreateCTableJson((STag*)pCreateReq->ctb.pTag, pCreateReq->ctb.name, pCreateReq->name, pCreateReq->uid); + string = buildCreateCTableJson((STag*)pCreateReq->ctb.pTag, pCreateReq->ctb.name, pCreateReq->name, pCreateReq->ctb.tagName, pCreateReq->uid); }else if(pCreateReq->type == TSDB_NORMAL_TABLE){ string = buildCreateTableJson(&pCreateReq->ntb.schemaRow, NULL, pCreateReq->name, pCreateReq->uid, TSDB_NORMAL_TABLE); } diff --git a/source/common/src/tmsg.c b/source/common/src/tmsg.c index 7245a62eb2..8901014600 100644 --- a/source/common/src/tmsg.c +++ b/source/common/src/tmsg.c @@ -4943,6 +4943,12 @@ int tEncodeSVCreateTbReq(SEncoder *pCoder, const SVCreateTbReq *pReq) { if (tEncodeCStr(pCoder, pReq->ctb.name) < 0) return -1; if (tEncodeI64(pCoder, pReq->ctb.suid) < 0) return -1; if (tEncodeTag(pCoder, (const STag *)pReq->ctb.pTag) < 0) return -1; + int32_t len = taosArrayGetSize(pReq->ctb.tagName); + if (tEncodeI32(pCoder, len) < 0) return -1; + for (int32_t i = 0; i < len; i++){ + char* name = taosArrayGet(pReq->ctb.tagName, i); + if (tEncodeCStr(pCoder, name) < 0) return -1; + } } else if (pReq->type == TSDB_NORMAL_TABLE) { if (tEncodeSSchemaWrapper(pCoder, &pReq->ntb.schemaRow) < 0) return -1; } else { @@ -4973,6 +4979,15 @@ int tDecodeSVCreateTbReq(SDecoder *pCoder, SVCreateTbReq *pReq) { if (tDecodeCStr(pCoder, &pReq->ctb.name) < 0) return -1; if (tDecodeI64(pCoder, &pReq->ctb.suid) < 0) return -1; if (tDecodeTag(pCoder, (STag **)&pReq->ctb.pTag) < 0) return -1; + int32_t len = 0; + if (tDecodeI32(pCoder, &len) < 0) return -1; + pReq->ctb.tagName = taosArrayInit(len, TSDB_COL_NAME_LEN); + if(pReq->ctb.tagName == NULL) return -1; + for (int32_t i = 0; i < len; i++){ + char *name = NULL; + if (tDecodeCStr(pCoder, &name) < 0) return -1; + taosArrayPush(pReq->ctb.tagName, name); + } } else if (pReq->type == TSDB_NORMAL_TABLE) { if (tDecodeSSchemaWrapper(pCoder, &pReq->ntb.schemaRow) < 0) return -1; } else { diff --git a/source/dnode/mnode/sdb/inc/sdb.h b/source/dnode/mnode/sdb/inc/sdb.h index 1294f0cff3..be56d901de 100644 --- a/source/dnode/mnode/sdb/inc/sdb.h +++ b/source/dnode/mnode/sdb/inc/sdb.h @@ -163,6 +163,7 @@ typedef struct SSdbRow { ESdbType type; ESdbStatus status; int32_t refCount; + int64_t forAlign; char pObj[]; } SSdbRow; diff --git a/source/libs/parser/src/parInsert.c b/source/libs/parser/src/parInsert.c index 9bb55cf663..46a8ffcc6c 100644 --- a/source/libs/parser/src/parInsert.c +++ b/source/libs/parser/src/parInsert.c @@ -732,12 +732,13 @@ static int32_t parseBoundColumns(SInsertParseContext* pCxt, SParsedDataColInfo* return TSDB_CODE_SUCCESS; } -static void buildCreateTbReq(SVCreateTbReq* pTbReq, const char* tname, STag* pTag, int64_t suid, const char* sname) { +static void buildCreateTbReq(SVCreateTbReq* pTbReq, const char* tname, STag* pTag, int64_t suid, const char* sname, SArray* tagName) { pTbReq->type = TD_CHILD_TABLE; pTbReq->name = strdup(tname); pTbReq->ctb.suid = suid; if(sname) pTbReq->ctb.name = strdup(sname); pTbReq->ctb.pTag = (uint8_t*)pTag; + pTbReq->ctb.tagName = taosArrayDup(tagName); pTbReq->commentLen = -1; return; @@ -936,6 +937,7 @@ static int32_t parseTagToken(char** end, SToken* pToken, SSchema* pSchema, int16 static int32_t parseTagsClause(SInsertParseContext* pCxt, SSchema* pSchema, uint8_t precision, const char* tName) { int32_t code = TSDB_CODE_SUCCESS; SArray* pTagVals = taosArrayInit(pCxt->tags.numOfBound, sizeof(STagVal)); + SArray* tagName = taosArrayInit(8, TSDB_COL_NAME_LEN); SToken sToken; bool isParseBindParam = false; bool isJson = false; @@ -965,6 +967,10 @@ static int32_t parseTagsClause(SInsertParseContext* pCxt, SSchema* pSchema, uint taosMemoryFree(tmpTokenBuf); goto end; } + + if (!isNullStr(&sToken)) { + taosArrayPush(tagName, pTagSchema->name); + } if (pTagSchema->type == TSDB_DATA_TYPE_JSON) { if (sToken.n > (TSDB_MAX_JSON_TAG_LEN - VARSTR_HEADER_SIZE) / TSDB_NCHAR_SIZE) { code = buildSyntaxErrMsg(&pCxt->msg, "json string too long than 4095", sToken.z); @@ -974,7 +980,7 @@ static int32_t parseTagsClause(SInsertParseContext* pCxt, SSchema* pSchema, uint if (isNullStr(&sToken)) { code = tTagNew(pTagVals, 1, true, &pTag); } else { - code = parseJsontoTagData(sToken.z, pTagVals, &pTag, &pCxt->msg, pTagSchema->name); + code = parseJsontoTagData(sToken.z, pTagVals, &pTag, &pCxt->msg); } taosMemoryFree(tmpTokenBuf); if (code != TSDB_CODE_SUCCESS) { @@ -1004,7 +1010,7 @@ static int32_t parseTagsClause(SInsertParseContext* pCxt, SSchema* pSchema, uint goto end; } - buildCreateTbReq(&pCxt->createTblReq, tName, pTag, pCxt->pTableMeta->suid, pCxt->sTableName); + buildCreateTbReq(&pCxt->createTblReq, tName, pTag, pCxt->pTableMeta->suid, pCxt->sTableName, tagName); end: for (int i = 0; i < taosArrayGetSize(pTagVals); ++i) { @@ -1014,6 +1020,7 @@ end: } } taosArrayDestroy(pTagVals); + taosArrayDestroy(tagName); return code; } @@ -1798,6 +1805,11 @@ int32_t qBindStmtTagsValue(void* pBlock, void* boundTags, int64_t suid, const ch return buildInvalidOperationMsg(&pBuf, "out of memory"); } + SArray* tagName = taosArrayInit(8, TSDB_COL_NAME_LEN); + if (!tagName) { + return buildInvalidOperationMsg(&pBuf, "out of memory"); + } + int32_t code = TSDB_CODE_SUCCESS; SSchema* pSchema = getTableTagSchema(pDataBlock->pTableMeta); @@ -1814,6 +1826,7 @@ int32_t qBindStmtTagsValue(void* pBlock, void* boundTags, int64_t suid, const ch if (IS_VAR_DATA_TYPE(pTagSchema->type)) { colLen = bind[c].length[0]; } + taosArrayPush(tagName, pTagSchema->name); if (pTagSchema->type == TSDB_DATA_TYPE_JSON) { if (colLen > (TSDB_MAX_JSON_TAG_LEN - VARSTR_HEADER_SIZE) / TSDB_NCHAR_SIZE) { code = buildSyntaxErrMsg(&pBuf, "json string too long than 4095", bind[c].buffer); @@ -1823,7 +1836,7 @@ int32_t qBindStmtTagsValue(void* pBlock, void* boundTags, int64_t suid, const ch isJson = true; char* tmp = taosMemoryCalloc(1, colLen + 1); memcpy(tmp, bind[c].buffer, colLen); - code = parseJsontoTagData(tmp, pTagArray, &pTag, &pBuf, pTagSchema->name); + code = parseJsontoTagData(tmp, pTagArray, &pTag, &pBuf); taosMemoryFree(tmp); if (code != TSDB_CODE_SUCCESS) { goto end; @@ -1867,7 +1880,7 @@ int32_t qBindStmtTagsValue(void* pBlock, void* boundTags, int64_t suid, const ch } SVCreateTbReq tbReq = {0}; - buildCreateTbReq(&tbReq, tName, pTag, suid, sTableName); + buildCreateTbReq(&tbReq, tName, pTag, suid, sTableName, tagName); code = buildCreateTbMsg(pDataBlock, &tbReq); tdDestroySVCreateTbReq(&tbReq); @@ -1879,6 +1892,7 @@ end: } } taosArrayDestroy(pTagArray); + taosArrayDestroy(tagName); return code; } @@ -2219,17 +2233,22 @@ static int32_t smlBoundColumnData(SArray* cols, SParsedDataColInfo* pColList, SS * @param msg * @return int32_t */ -static int32_t smlBuildTagRow(SArray* cols, SParsedDataColInfo* tags, SSchema* pSchema, STag** ppTag, SMsgBuf* msg) { +static int32_t smlBuildTagRow(SArray* cols, SParsedDataColInfo* tags, SSchema* pSchema, STag** ppTag, SArray** tagName, SMsgBuf* msg) { SArray* pTagArray = taosArrayInit(tags->numOfBound, sizeof(STagVal)); if (!pTagArray) { return TSDB_CODE_TSC_OUT_OF_MEMORY; } + *tagName = taosArrayInit(8, TSDB_COL_NAME_LEN); + if (!*tagName) { + return TSDB_CODE_TSC_OUT_OF_MEMORY; + } int32_t code = TSDB_CODE_SUCCESS; for (int i = 0; i < tags->numOfBound; ++i) { SSchema* pTagSchema = &pSchema[tags->boundColumns[i]]; SSmlKv* kv = taosArrayGetP(cols, i); + taosArrayPush(*tagName, pTagSchema->name); STagVal val = {.cid = pTagSchema->colId, .type = pTagSchema->type}; // strcpy(val.colName, pTagSchema->name); if (pTagSchema->type == TSDB_DATA_TYPE_BINARY) { @@ -2288,12 +2307,16 @@ int32_t smlBindData(void* handle, SArray* tags, SArray* colsSchema, SArray* cols return ret; } STag* pTag = NULL; - ret = smlBuildTagRow(tags, &smlHandle->tableExecHandle.tags, pTagsSchema, &pTag, &pBuf); + SArray* tagName = NULL; + ret = smlBuildTagRow(tags, &smlHandle->tableExecHandle.tags, pTagsSchema, &pTag, &tagName, &pBuf); if (ret != TSDB_CODE_SUCCESS) { + taosArrayDestroy(tagName); return ret; } - buildCreateTbReq(&smlHandle->tableExecHandle.createTblReq, tableName, pTag, pTableMeta->suid, NULL); + buildCreateTbReq(&smlHandle->tableExecHandle.createTblReq, tableName, pTag, pTableMeta->suid, NULL, tagName); + taosArrayDestroy(tagName); + smlHandle->tableExecHandle.createTblReq.ctb.name = taosMemoryMalloc(sTableNameLen + 1); memcpy(smlHandle->tableExecHandle.createTblReq.ctb.name, sTableName, sTableNameLen); smlHandle->tableExecHandle.createTblReq.ctb.name[sTableNameLen] = 0; diff --git a/source/libs/parser/src/parTranslater.c b/source/libs/parser/src/parTranslater.c index f822945ef5..ffacafb504 100644 --- a/source/libs/parser/src/parTranslater.c +++ b/source/libs/parser/src/parTranslater.c @@ -5263,6 +5263,8 @@ static void destroyCreateTbReqBatch(void* data) { taosMemoryFreeClear(pTableReq->ntb.schemaRow.pSchema); } else if (pTableReq->type == TSDB_CHILD_TABLE) { taosMemoryFreeClear(pTableReq->ctb.pTag); + taosMemoryFreeClear(pTableReq->ctb.name); + taosArrayDestroy(pTableReq->ctb.tagName); } } @@ -5334,7 +5336,7 @@ static int32_t rewriteCreateTable(STranslateContext* pCxt, SQuery* pQuery) { } static void addCreateTbReqIntoVgroup(int32_t acctId, SHashObj* pVgroupHashmap, SCreateSubTableClause* pStmt, - const STag* pTag, uint64_t suid, const char* sTableNmae, SVgroupInfo* pVgInfo) { + const STag* pTag, uint64_t suid, const char* sTableNmae, SVgroupInfo* pVgInfo, SArray* tagName) { // char dbFName[TSDB_DB_FNAME_LEN] = {0}; // SName name = {.type = TSDB_DB_NAME_T, .acctId = acctId}; // strcpy(name.dbname, pStmt->dbName); @@ -5353,6 +5355,7 @@ static void addCreateTbReqIntoVgroup(int32_t acctId, SHashObj* pVgroupHashmap, S req.ctb.suid = suid; req.ctb.name = strdup(sTableNmae); req.ctb.pTag = (uint8_t*)pTag; + req.ctb.tagName = taosArrayDup(tagName); if (pStmt->ignoreExists) { req.flags |= TD_CREATE_IF_NOT_EXISTS; } @@ -5437,7 +5440,7 @@ static int32_t buildJsonTagVal(STranslateContext* pCxt, SSchema* pTagSchema, SVa return buildSyntaxErrMsg(&pCxt->msgBuf, "json string too long than 4095", pVal->literal); } - return parseJsontoTagData(pVal->literal, pTagArray, ppTag, &pCxt->msgBuf, pTagSchema->name); + return parseJsontoTagData(pVal->literal, pTagArray, ppTag, &pCxt->msgBuf); } static int32_t buildNormalTagVal(STranslateContext* pCxt, SSchema* pTagSchema, SValueNode* pVal, SArray* pTagArray) { @@ -5457,7 +5460,7 @@ static int32_t buildNormalTagVal(STranslateContext* pCxt, SSchema* pTagSchema, S } static int32_t buildKVRowForBindTags(STranslateContext* pCxt, SCreateSubTableClause* pStmt, STableMeta* pSuperTableMeta, - STag** ppTag) { + STag** ppTag, SArray* tagName) { int32_t numOfTags = getNumOfTags(pSuperTableMeta); if (LIST_LENGTH(pStmt->pValsOfTags) != LIST_LENGTH(pStmt->pSpecificTags) || numOfTags < LIST_LENGTH(pStmt->pValsOfTags)) { @@ -5488,8 +5491,10 @@ static int32_t buildKVRowForBindTags(STranslateContext* pCxt, SCreateSubTableCla if (pSchema->type == TSDB_DATA_TYPE_JSON) { isJson = true; code = buildJsonTagVal(pCxt, pSchema, pVal, pTagArray, ppTag); + taosArrayPush(tagName, pCol->colName); } else if (pVal->node.resType.type != TSDB_DATA_TYPE_NULL) { code = buildNormalTagVal(pCxt, pSchema, pVal, pTagArray); + taosArrayPush(tagName, pCol->colName); } } if (TSDB_CODE_SUCCESS == code) { @@ -5510,7 +5515,7 @@ static int32_t buildKVRowForBindTags(STranslateContext* pCxt, SCreateSubTableCla } static int32_t buildKVRowForAllTags(STranslateContext* pCxt, SCreateSubTableClause* pStmt, STableMeta* pSuperTableMeta, - STag** ppTag) { + STag** ppTag, SArray* tagName) { if (getNumOfTags(pSuperTableMeta) != LIST_LENGTH(pStmt->pValsOfTags)) { return generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_TAGS_NOT_MATCHED); } @@ -5535,6 +5540,7 @@ static int32_t buildKVRowForAllTags(STranslateContext* pCxt, SCreateSubTableClau if (pTagSchema->type == TSDB_DATA_TYPE_JSON) { isJson = true; code = buildJsonTagVal(pCxt, pTagSchema, pVal, pTagArray, ppTag); + taosArrayPush(tagName, pTagSchema->name); } else if (pVal->node.resType.type != TSDB_DATA_TYPE_NULL && !pVal->isNull) { char* tmpVal = nodesGetValueFromNode(pVal); STagVal val = {.cid = pTagSchema->colId, .type = pTagSchema->type}; @@ -5546,6 +5552,7 @@ static int32_t buildKVRowForAllTags(STranslateContext* pCxt, SCreateSubTableClau memcpy(&val.i64, tmpVal, pTagSchema->bytes); } taosArrayPush(pTagArray, &val); + taosArrayPush(tagName, pTagSchema->name); } } if (TSDB_CODE_SUCCESS == code) { @@ -5581,12 +5588,13 @@ static int32_t rewriteCreateSubTable(STranslateContext* pCxt, SCreateSubTableCla } STag* pTag = NULL; + SArray* tagName = taosArrayInit(8, TSDB_COL_NAME_LEN); if (TSDB_CODE_SUCCESS == code) { if (NULL != pStmt->pSpecificTags) { - code = buildKVRowForBindTags(pCxt, pStmt, pSuperTableMeta, &pTag); + code = buildKVRowForBindTags(pCxt, pStmt, pSuperTableMeta, &pTag, tagName); } else { - code = buildKVRowForAllTags(pCxt, pStmt, pSuperTableMeta, &pTag); + code = buildKVRowForAllTags(pCxt, pStmt, pSuperTableMeta, &pTag, tagName); } } @@ -5595,9 +5603,10 @@ static int32_t rewriteCreateSubTable(STranslateContext* pCxt, SCreateSubTableCla code = getTableHashVgroup(pCxt, pStmt->dbName, pStmt->tableName, &info); } if (TSDB_CODE_SUCCESS == code) { - addCreateTbReqIntoVgroup(pCxt->pParseCxt->acctId, pVgroupHashmap, pStmt, pTag, pSuperTableMeta->uid, pStmt->useTableName, &info); + addCreateTbReqIntoVgroup(pCxt->pParseCxt->acctId, pVgroupHashmap, pStmt, pTag, pSuperTableMeta->uid, pStmt->useTableName, &info, tagName); } + taosArrayDestroy(tagName); taosMemoryFreeClear(pSuperTableMeta); return code; } @@ -5823,7 +5832,7 @@ static int32_t buildUpdateTagValReq(STranslateContext* pCxt, SAlterTableStmt* pS int32_t code = TSDB_CODE_SUCCESS; STag* pTag = NULL; do { - code = parseJsontoTagData(pStmt->pVal->literal, pTagVals, &pTag, &pCxt->msgBuf, pReq->tagName); + code = parseJsontoTagData(pStmt->pVal->literal, pTagVals, &pTag, &pCxt->msgBuf); if (TSDB_CODE_SUCCESS != code) { break; } diff --git a/source/libs/parser/src/parUtil.c b/source/libs/parser/src/parUtil.c index b6ebb0de22..69cc95a726 100644 --- a/source/libs/parser/src/parUtil.c +++ b/source/libs/parser/src/parUtil.c @@ -341,7 +341,7 @@ static bool isValidateTag(char* input) { return true; } -int32_t parseJsontoTagData(const char* json, SArray* pTagVals, STag** ppTag, void* pMsgBuf, const char* colName) { +int32_t parseJsontoTagData(const char* json, SArray* pTagVals, STag** ppTag, void* pMsgBuf) { int32_t retCode = TSDB_CODE_SUCCESS; cJSON* root = NULL; SHashObj* keyHash = NULL; diff --git a/source/libs/scalar/src/sclfunc.c b/source/libs/scalar/src/sclfunc.c index dd0a60dced..df5df127f0 100644 --- a/source/libs/scalar/src/sclfunc.c +++ b/source/libs/scalar/src/sclfunc.c @@ -1150,7 +1150,7 @@ int32_t toJsonFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOu } memcpy(tmp, varDataVal(input), varDataLen(input)); tmp[varDataLen(input)] = 0; - if(parseJsontoTagData(tmp, pTagVals, &pTag, NULL, "")){ + if(parseJsontoTagData(tmp, pTagVals, &pTag, NULL)){ tTagNew(pTagVals, 1, true, &pTag); } } diff --git a/source/libs/scalar/test/scalar/scalarTests.cpp b/source/libs/scalar/test/scalar/scalarTests.cpp index 6663fc3cc4..9b40f0a465 100644 --- a/source/libs/scalar/test/scalar/scalarTests.cpp +++ b/source/libs/scalar/test/scalar/scalarTests.cpp @@ -1114,7 +1114,7 @@ TEST(columnTest, json_column_arith_op) { memcpy(rightv, rightvTmp, strlen(rightvTmp)); SArray *tags = taosArrayInit(1, sizeof(STagVal)); STag* row = NULL; - parseJsontoTagData(rightv, tags, &row, NULL, ""); + parseJsontoTagData(rightv, tags, &row, NULL); const int32_t len = 8; EOperatorType op[len] = {OP_TYPE_ADD, OP_TYPE_SUB, OP_TYPE_MULTI, OP_TYPE_DIV, @@ -1262,7 +1262,7 @@ TEST(columnTest, json_column_logic_op) { memcpy(rightv, rightvTmp, strlen(rightvTmp)); SArray *tags = taosArrayInit(1, sizeof(STagVal)); STag* row = NULL; - parseJsontoTagData(rightv, tags, &row, NULL, ""); + parseJsontoTagData(rightv, tags, &row, NULL); const int32_t len0 = 6; const int32_t len = 9; -- GitLab From e91ca30b19a21589cc78393350c957623fa56c91 Mon Sep 17 00:00:00 2001 From: Minghao Li Date: Tue, 12 Jul 2022 20:23:31 +0800 Subject: [PATCH 020/153] refactor(sync): add resp ttl clean --- source/libs/sync/src/syncRespMgr.c | 2 ++ source/libs/sync/src/syncTimeout.c | 5 ++++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/source/libs/sync/src/syncRespMgr.c b/source/libs/sync/src/syncRespMgr.c index 2aaa98b299..8e477a5159 100644 --- a/source/libs/sync/src/syncRespMgr.c +++ b/source/libs/sync/src/syncRespMgr.c @@ -146,6 +146,8 @@ void syncRespCleanByTTL(SSyncRespMgr *pObj, int64_t ttl) { cbMeta.currentTerm = pSyncNode->pRaftStore->currentTerm; cbMeta.flag = 0; + pStub->rpcMsg.pCont = NULL; + pStub->rpcMsg.contLen = 0; pSyncNode->pFsm->FpCommitCb(pSyncNode->pFsm, &(pStub->rpcMsg), cbMeta); } diff --git a/source/libs/sync/src/syncTimeout.c b/source/libs/sync/src/syncTimeout.c index 97de75c108..ad5f82900c 100644 --- a/source/libs/sync/src/syncTimeout.c +++ b/source/libs/sync/src/syncTimeout.c @@ -20,7 +20,10 @@ int32_t syncNodeTimerRoutine(SSyncNode* ths) { syncNodeEventLog(ths, "timer routines ... "); - syncRespClean(ths->pSyncRespMgr); + + if (ths->vgId != 1) { + syncRespClean(ths->pSyncRespMgr); + } return 0; } -- GitLab From 9af7cb1a4518659e5cc3d771eeee0e8a6572670f Mon Sep 17 00:00:00 2001 From: Shengliang Guan Date: Wed, 13 Jul 2022 09:56:27 +0800 Subject: [PATCH 021/153] fix: hanlde the error if propose failed --- source/dnode/mnode/impl/src/mndSync.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/source/dnode/mnode/impl/src/mndSync.c b/source/dnode/mnode/impl/src/mndSync.c index bcf926e5ee..3c3864b620 100644 --- a/source/dnode/mnode/impl/src/mndSync.c +++ b/source/dnode/mnode/impl/src/mndSync.c @@ -56,20 +56,22 @@ void mndSyncCommitMsg(struct SSyncFSM *pFsm, const SRpcMsg *pMsg, SFsmCbMeta cbM sdbSetApplyInfo(pMnode->pSdb, cbMeta.index, cbMeta.term, cbMeta.lastConfigIndex); } - if (pMgmt->transId == transId) { + if (pMgmt->transId == transId && transId != 0) { if (pMgmt->errCode != 0) { mError("trans:%d, failed to propose since %s", transId, tstrerror(pMgmt->errCode)); } pMgmt->transId = 0; tsem_post(&pMgmt->syncSem); } else { +#if 1 + mError("trans:%d, invalid commit msg since trandId not match with %d", transId, pMgmt->transId); +#else STrans *pTrans = mndAcquireTrans(pMnode, transId); if (pTrans != NULL) { mndTransExecute(pMnode, pTrans); mndReleaseTrans(pMnode, pTrans); } -#if 0 - sdbWriteFile(pMnode->pSdb, SDB_WRITE_DELTA); + // sdbWriteFile(pMnode->pSdb, SDB_WRITE_DELTA); #endif } } -- GitLab From f61c7c9a22535cf97cbf5307d205a78a642a0c9e Mon Sep 17 00:00:00 2001 From: plum-lihui Date: Wed, 13 Jul 2022 10:25:17 +0800 Subject: [PATCH 022/153] test: add test case for tmq --- tests/system-test/7-tmq/tmqUpdate-1ctb.py | 259 ++++++++++++++++++ tests/system-test/7-tmq/tmqUpdate-multiCtb.py | 259 ++++++++++++++++++ 2 files changed, 518 insertions(+) create mode 100644 tests/system-test/7-tmq/tmqUpdate-1ctb.py create mode 100644 tests/system-test/7-tmq/tmqUpdate-multiCtb.py diff --git a/tests/system-test/7-tmq/tmqUpdate-1ctb.py b/tests/system-test/7-tmq/tmqUpdate-1ctb.py new file mode 100644 index 0000000000..9e2d06d1bd --- /dev/null +++ b/tests/system-test/7-tmq/tmqUpdate-1ctb.py @@ -0,0 +1,259 @@ + +import taos +import sys +import time +import socket +import os +import threading +from enum import Enum + +from util.log import * +from util.sql import * +from util.cases import * +from util.dnodes import * +sys.path.append("./7-tmq") +from tmqCommon import * + +class TDTestCase: + def __init__(self): + self.snapshot = 0 + self.vgroups = 2 + self.ctbNum = 1 + self.rowsPerTbl = 100000 + + def init(self, conn, logSql): + tdLog.debug(f"start to excute {__file__}") + tdSql.init(conn.cursor(), False) + + def prepareTestEnv(self): + tdLog.printNoPrefix("======== prepare test env include database, stable, ctables, and insert data: ") + paraDict = {'dbName': 'dbt', + 'dropFlag': 1, + 'event': '', + 'vgroups': 4, + 'stbName': 'stb', + 'colPrefix': 'c', + 'tagPrefix': 't', + 'colSchema': [{'type': 'INT', 'count':1},{'type': 'BIGINT', 'count':1},{'type': 'DOUBLE', 'count':1},{'type': 'BINARY', 'len':32, 'count':1},{'type': 'NCHAR', 'len':32, 'count':1},{'type': 'TIMESTAMP', 'count':1}], + 'tagSchema': [{'type': 'INT', 'count':1},{'type': 'BIGINT', 'count':1},{'type': 'DOUBLE', 'count':1},{'type': 'BINARY', 'len':32, 'count':1},{'type': 'NCHAR', 'len':32, 'count':1}], + 'ctbPrefix': 'ctb', + 'ctbStartIdx': 0, + 'ctbNum': 1, + 'rowsPerTbl': 100000, + 'batchNum': 1200, + 'startTs': 1640966400000, # 2022-01-01 00:00:00.000 + 'pollDelay': 3, + 'showMsg': 1, + 'showRow': 1, + 'snapshot': 0} + + paraDict['vgroups'] = self.vgroups + paraDict['ctbNum'] = self.ctbNum + paraDict['rowsPerTbl'] = self.rowsPerTbl + + tmqCom.initConsumerTable() + tdCom.create_database(tdSql, paraDict["dbName"],paraDict["dropFlag"], vgroups=paraDict["vgroups"],replica=1) + tdLog.info("create stb") + tmqCom.create_stable(tdSql, dbName=paraDict["dbName"],stbName=paraDict["stbName"]) + tdLog.info("create ctb") + tmqCom.create_ctable(tdSql, dbName=paraDict["dbName"],stbName=paraDict["stbName"],ctbPrefix=paraDict['ctbPrefix'], + ctbNum=paraDict["ctbNum"],ctbStartIdx=paraDict['ctbStartIdx']) + tdLog.info("insert data") + tmqCom.insert_data_interlaceByMultiTbl(tsql=tdSql,dbName=paraDict["dbName"],ctbPrefix=paraDict["ctbPrefix"], + ctbNum=paraDict["ctbNum"],rowsPerTbl=paraDict["rowsPerTbl"],batchNum=paraDict["batchNum"], + startTs=paraDict["startTs"],ctbStartIdx=paraDict['ctbStartIdx']) + # tmqCom.insert_data_with_autoCreateTbl(tsql=tdSql,dbName=paraDict["dbName"],stbName=paraDict["stbName"],ctbPrefix="ctbx", + # ctbNum=paraDict["ctbNum"],rowsPerTbl=paraDict["rowsPerTbl"],batchNum=paraDict["batchNum"], + # startTs=paraDict["startTs"],ctbStartIdx=paraDict['ctbStartIdx']) + + # tdLog.info("restart taosd to ensure that the data falls into the disk") + # tdSql.query("flush database %s"%(paraDict['dbName'])) + return + + # 自动建表完成数据插入,启动消费 + def tmqCase1(self): + tdLog.printNoPrefix("======== test case 1: ") + paraDict = {'dbName': 'dbt', + 'dropFlag': 1, + 'event': '', + 'vgroups': 4, + 'stbName': 'stb', + 'colPrefix': 'c', + 'tagPrefix': 't', + 'colSchema': [{'type': 'INT', 'count':1},{'type': 'BIGINT', 'count':1},{'type': 'DOUBLE', 'count':1},{'type': 'BINARY', 'len':32, 'count':1},{'type': 'NCHAR', 'len':32, 'count':1},{'type': 'TIMESTAMP', 'count':1}], + 'tagSchema': [{'type': 'INT', 'count':1},{'type': 'BIGINT', 'count':1},{'type': 'DOUBLE', 'count':1},{'type': 'BINARY', 'len':32, 'count':1},{'type': 'NCHAR', 'len':32, 'count':1}], + 'ctbPrefix': 'ctb', + 'ctbStartIdx': 0, + 'ctbNum': 1, + 'rowsPerTbl': 100000, + 'batchNum': 3000, + 'startTs': 1640966400000, # 2022-01-01 00:00:00.000 + 'pollDelay': 5, + 'showMsg': 1, + 'showRow': 1, + 'snapshot': 0} + paraDict['snapshot'] = self.snapshot + paraDict['vgroups'] = self.vgroups + paraDict['ctbNum'] = self.ctbNum + paraDict['rowsPerTbl'] = self.rowsPerTbl + + # update to half tables + paraDict['rowsPerTbl'] = int(self.rowsPerTbl / 2) + # tmqCom.insert_data_with_autoCreateTbl(tsql=tdSql,dbName=paraDict["dbName"],stbName=paraDict["stbName"],ctbPrefix="ctbx", + # ctbNum=paraDict["ctbNum"],rowsPerTbl=paraDict["rowsPerTbl"],batchNum=paraDict["batchNum"], + # startTs=paraDict["startTs"],ctbStartIdx=paraDict['ctbStartIdx']) + tmqCom.insert_data_interlaceByMultiTbl(tsql=tdSql,dbName=paraDict["dbName"],ctbPrefix=paraDict["ctbPrefix"], + ctbNum=paraDict["ctbNum"],rowsPerTbl=paraDict["rowsPerTbl"],batchNum=paraDict["batchNum"], + startTs=paraDict["startTs"],ctbStartIdx=paraDict['ctbStartIdx']) + + tdLog.info("create topics from stb1") + topicFromStb1 = 'topic_stb1' + queryString = "select ts, c1, c2 from %s.%s"%(paraDict['dbName'], paraDict['stbName']) + sqlString = "create topic %s as %s" %(topicFromStb1, queryString) + tdLog.info("create topic sql: %s"%sqlString) + tdSql.execute(sqlString) + + # paraDict['ctbNum'] = self.ctbNum + paraDict['rowsPerTbl'] = self.rowsPerTbl + consumerId = 0 + expectrowcnt = int(paraDict["rowsPerTbl"] * paraDict["ctbNum"] * 3/2) + topicList = topicFromStb1 + ifcheckdata = 1 + ifManualCommit = 1 + keyList = 'group.id:cgrp1,\ + enable.auto.commit:true,\ + auto.commit.interval.ms:1000,\ + auto.offset.reset:earliest' + tmqCom.insertConsumerInfo(consumerId, expectrowcnt,topicList,keyList,ifcheckdata,ifManualCommit) + + tdLog.info("start consume processor") + tmqCom.startTmqSimProcess(pollDelay=paraDict['pollDelay'],dbName=paraDict["dbName"],showMsg=paraDict['showMsg'], showRow=paraDict['showRow'],snapshot=paraDict['snapshot']) + + tdLog.info("insert process end, and start to check consume result") + expectRows = 1 + resultList = tmqCom.selectConsumeResult(expectRows) + totalConsumeRows = 0 + for i in range(expectRows): + totalConsumeRows += resultList[i] + + tdSql.query(queryString) + totalRowsInserted = tdSql.getRows() + + tdLog.info("act consume rows: %d, expect consume rows: %d, act insert rows: %d"%(totalConsumeRows, expectrowcnt, totalRowsInserted)) + if totalConsumeRows != expectrowcnt: + tdLog.exit("tmq consume rows error!") + + tmqCom.checkFileContent(consumerId, queryString) + + tdSql.query("drop topic %s"%topicFromStb1) + tdLog.printNoPrefix("======== test case 1 end ...... ") + + def tmqCase2(self): + tdLog.printNoPrefix("======== test case 2: ") + paraDict = {'dbName': 'dbt', + 'dropFlag': 1, + 'event': '', + 'vgroups': 4, + 'stbName': 'stb', + 'colPrefix': 'c', + 'tagPrefix': 't', + 'colSchema': [{'type': 'INT', 'count':1},{'type': 'BIGINT', 'count':1},{'type': 'DOUBLE', 'count':1},{'type': 'BINARY', 'len':32, 'count':1},{'type': 'NCHAR', 'len':32, 'count':1},{'type': 'TIMESTAMP', 'count':1}], + 'tagSchema': [{'type': 'INT', 'count':1},{'type': 'BIGINT', 'count':1},{'type': 'DOUBLE', 'count':1},{'type': 'BINARY', 'len':32, 'count':1},{'type': 'NCHAR', 'len':32, 'count':1}], + 'ctbPrefix': 'ctb', + 'ctbStartIdx': 0, + 'ctbNum': 1, + 'rowsPerTbl': 10000, + 'batchNum': 5000, + 'startTs': 1640966400000, # 2022-01-01 00:00:00.000 + 'pollDelay': 5, + 'showMsg': 1, + 'showRow': 1, + 'snapshot': 0} + + paraDict['snapshot'] = self.snapshot + paraDict['vgroups'] = self.vgroups + paraDict['ctbNum'] = self.ctbNum + paraDict['rowsPerTbl'] = self.rowsPerTbl + + tdLog.info("restart taosd to ensure that the data falls into the disk") + tdSql.query("flush database %s"%(paraDict['dbName'])) + + # update to half tables + paraDict['startTs'] = paraDict['startTs'] + int(self.rowsPerTbl / 2) + paraDict['rowsPerTbl'] = int(self.rowsPerTbl / 2) + tmqCom.insert_data_with_autoCreateTbl(tsql=tdSql,dbName=paraDict["dbName"],stbName=paraDict["stbName"],ctbPrefix=paraDict["ctbPrefix"], + ctbNum=paraDict["ctbNum"],rowsPerTbl=paraDict["rowsPerTbl"],batchNum=paraDict["batchNum"], + startTs=paraDict["startTs"],ctbStartIdx=paraDict['ctbStartIdx']) + # tmqCom.insert_data_interlaceByMultiTbl(tsql=tdSql,dbName=paraDict["dbName"],ctbPrefix=paraDict["ctbPrefix"], + # ctbNum=paraDict["ctbNum"],rowsPerTbl=paraDict["rowsPerTbl"],batchNum=paraDict["batchNum"], + # startTs=paraDict["startTs"],ctbStartIdx=paraDict['ctbStartIdx']) + + tmqCom.initConsumerTable() + tdLog.info("create topics from stb1") + topicFromStb1 = 'topic_stb1' + queryString = "select ts, c1, c2 from %s.%s"%(paraDict['dbName'], paraDict['stbName']) + sqlString = "create topic %s as %s" %(topicFromStb1, queryString) + tdLog.info("create topic sql: %s"%sqlString) + tdSql.execute(sqlString) + + # paraDict['ctbNum'] = self.ctbNum + paraDict['rowsPerTbl'] = self.rowsPerTbl + consumerId = 1 + expectrowcnt = int(paraDict["rowsPerTbl"] * paraDict["ctbNum"] * 2) + topicList = topicFromStb1 + ifcheckdata = 1 + ifManualCommit = 1 + keyList = 'group.id:cgrp1,\ + enable.auto.commit:true,\ + auto.commit.interval.ms:1000,\ + auto.offset.reset:earliest' + tmqCom.insertConsumerInfo(consumerId, expectrowcnt,topicList,keyList,ifcheckdata,ifManualCommit) + + tdLog.info("start consume processor") + tmqCom.startTmqSimProcess(pollDelay=paraDict['pollDelay'],dbName=paraDict["dbName"],showMsg=paraDict['showMsg'], showRow=paraDict['showRow'],snapshot=paraDict['snapshot']) + + tdLog.info("insert process end, and start to check consume result") + expectRows = 1 + resultList = tmqCom.selectConsumeResult(expectRows) + totalConsumeRows = 0 + for i in range(expectRows): + totalConsumeRows += resultList[i] + + tdSql.query(queryString) + totalRowsInserted = tdSql.getRows() + + tdLog.info("act consume rows: %d, act insert rows: %d, expect consume rows: %d, "%(totalConsumeRows, totalRowsInserted, expectrowcnt)) + + if totalConsumeRows != expectrowcnt: + tdLog.exit("tmq consume rows error!") + + # tmqCom.checkFileContent(consumerId, queryString) + + tdSql.query("drop topic %s"%topicFromStb1) + + tdLog.printNoPrefix("======== test case 2 end ...... ") + + def run(self): + tdSql.prepare() + self.prepareTestEnv() + tdLog.printNoPrefix("=============================================") + tdLog.printNoPrefix("======== snapshot is 0: only consume from wal") + self.tmqCase1() + self.tmqCase2() + + self.prepareTestEnv() + tdLog.printNoPrefix("====================================================================") + tdLog.printNoPrefix("======== snapshot is 1: firstly consume from tsbs, and then from wal") + self.snapshot = 1 + self.tmqCase1() + self.tmqCase2() + + + def stop(self): + tdSql.close() + tdLog.success(f"{__file__} successfully executed") + +event = threading.Event() + +tdCases.addLinux(__file__, TDTestCase()) +tdCases.addWindows(__file__, TDTestCase()) diff --git a/tests/system-test/7-tmq/tmqUpdate-multiCtb.py b/tests/system-test/7-tmq/tmqUpdate-multiCtb.py new file mode 100644 index 0000000000..9e2d06d1bd --- /dev/null +++ b/tests/system-test/7-tmq/tmqUpdate-multiCtb.py @@ -0,0 +1,259 @@ + +import taos +import sys +import time +import socket +import os +import threading +from enum import Enum + +from util.log import * +from util.sql import * +from util.cases import * +from util.dnodes import * +sys.path.append("./7-tmq") +from tmqCommon import * + +class TDTestCase: + def __init__(self): + self.snapshot = 0 + self.vgroups = 2 + self.ctbNum = 1 + self.rowsPerTbl = 100000 + + def init(self, conn, logSql): + tdLog.debug(f"start to excute {__file__}") + tdSql.init(conn.cursor(), False) + + def prepareTestEnv(self): + tdLog.printNoPrefix("======== prepare test env include database, stable, ctables, and insert data: ") + paraDict = {'dbName': 'dbt', + 'dropFlag': 1, + 'event': '', + 'vgroups': 4, + 'stbName': 'stb', + 'colPrefix': 'c', + 'tagPrefix': 't', + 'colSchema': [{'type': 'INT', 'count':1},{'type': 'BIGINT', 'count':1},{'type': 'DOUBLE', 'count':1},{'type': 'BINARY', 'len':32, 'count':1},{'type': 'NCHAR', 'len':32, 'count':1},{'type': 'TIMESTAMP', 'count':1}], + 'tagSchema': [{'type': 'INT', 'count':1},{'type': 'BIGINT', 'count':1},{'type': 'DOUBLE', 'count':1},{'type': 'BINARY', 'len':32, 'count':1},{'type': 'NCHAR', 'len':32, 'count':1}], + 'ctbPrefix': 'ctb', + 'ctbStartIdx': 0, + 'ctbNum': 1, + 'rowsPerTbl': 100000, + 'batchNum': 1200, + 'startTs': 1640966400000, # 2022-01-01 00:00:00.000 + 'pollDelay': 3, + 'showMsg': 1, + 'showRow': 1, + 'snapshot': 0} + + paraDict['vgroups'] = self.vgroups + paraDict['ctbNum'] = self.ctbNum + paraDict['rowsPerTbl'] = self.rowsPerTbl + + tmqCom.initConsumerTable() + tdCom.create_database(tdSql, paraDict["dbName"],paraDict["dropFlag"], vgroups=paraDict["vgroups"],replica=1) + tdLog.info("create stb") + tmqCom.create_stable(tdSql, dbName=paraDict["dbName"],stbName=paraDict["stbName"]) + tdLog.info("create ctb") + tmqCom.create_ctable(tdSql, dbName=paraDict["dbName"],stbName=paraDict["stbName"],ctbPrefix=paraDict['ctbPrefix'], + ctbNum=paraDict["ctbNum"],ctbStartIdx=paraDict['ctbStartIdx']) + tdLog.info("insert data") + tmqCom.insert_data_interlaceByMultiTbl(tsql=tdSql,dbName=paraDict["dbName"],ctbPrefix=paraDict["ctbPrefix"], + ctbNum=paraDict["ctbNum"],rowsPerTbl=paraDict["rowsPerTbl"],batchNum=paraDict["batchNum"], + startTs=paraDict["startTs"],ctbStartIdx=paraDict['ctbStartIdx']) + # tmqCom.insert_data_with_autoCreateTbl(tsql=tdSql,dbName=paraDict["dbName"],stbName=paraDict["stbName"],ctbPrefix="ctbx", + # ctbNum=paraDict["ctbNum"],rowsPerTbl=paraDict["rowsPerTbl"],batchNum=paraDict["batchNum"], + # startTs=paraDict["startTs"],ctbStartIdx=paraDict['ctbStartIdx']) + + # tdLog.info("restart taosd to ensure that the data falls into the disk") + # tdSql.query("flush database %s"%(paraDict['dbName'])) + return + + # 自动建表完成数据插入,启动消费 + def tmqCase1(self): + tdLog.printNoPrefix("======== test case 1: ") + paraDict = {'dbName': 'dbt', + 'dropFlag': 1, + 'event': '', + 'vgroups': 4, + 'stbName': 'stb', + 'colPrefix': 'c', + 'tagPrefix': 't', + 'colSchema': [{'type': 'INT', 'count':1},{'type': 'BIGINT', 'count':1},{'type': 'DOUBLE', 'count':1},{'type': 'BINARY', 'len':32, 'count':1},{'type': 'NCHAR', 'len':32, 'count':1},{'type': 'TIMESTAMP', 'count':1}], + 'tagSchema': [{'type': 'INT', 'count':1},{'type': 'BIGINT', 'count':1},{'type': 'DOUBLE', 'count':1},{'type': 'BINARY', 'len':32, 'count':1},{'type': 'NCHAR', 'len':32, 'count':1}], + 'ctbPrefix': 'ctb', + 'ctbStartIdx': 0, + 'ctbNum': 1, + 'rowsPerTbl': 100000, + 'batchNum': 3000, + 'startTs': 1640966400000, # 2022-01-01 00:00:00.000 + 'pollDelay': 5, + 'showMsg': 1, + 'showRow': 1, + 'snapshot': 0} + paraDict['snapshot'] = self.snapshot + paraDict['vgroups'] = self.vgroups + paraDict['ctbNum'] = self.ctbNum + paraDict['rowsPerTbl'] = self.rowsPerTbl + + # update to half tables + paraDict['rowsPerTbl'] = int(self.rowsPerTbl / 2) + # tmqCom.insert_data_with_autoCreateTbl(tsql=tdSql,dbName=paraDict["dbName"],stbName=paraDict["stbName"],ctbPrefix="ctbx", + # ctbNum=paraDict["ctbNum"],rowsPerTbl=paraDict["rowsPerTbl"],batchNum=paraDict["batchNum"], + # startTs=paraDict["startTs"],ctbStartIdx=paraDict['ctbStartIdx']) + tmqCom.insert_data_interlaceByMultiTbl(tsql=tdSql,dbName=paraDict["dbName"],ctbPrefix=paraDict["ctbPrefix"], + ctbNum=paraDict["ctbNum"],rowsPerTbl=paraDict["rowsPerTbl"],batchNum=paraDict["batchNum"], + startTs=paraDict["startTs"],ctbStartIdx=paraDict['ctbStartIdx']) + + tdLog.info("create topics from stb1") + topicFromStb1 = 'topic_stb1' + queryString = "select ts, c1, c2 from %s.%s"%(paraDict['dbName'], paraDict['stbName']) + sqlString = "create topic %s as %s" %(topicFromStb1, queryString) + tdLog.info("create topic sql: %s"%sqlString) + tdSql.execute(sqlString) + + # paraDict['ctbNum'] = self.ctbNum + paraDict['rowsPerTbl'] = self.rowsPerTbl + consumerId = 0 + expectrowcnt = int(paraDict["rowsPerTbl"] * paraDict["ctbNum"] * 3/2) + topicList = topicFromStb1 + ifcheckdata = 1 + ifManualCommit = 1 + keyList = 'group.id:cgrp1,\ + enable.auto.commit:true,\ + auto.commit.interval.ms:1000,\ + auto.offset.reset:earliest' + tmqCom.insertConsumerInfo(consumerId, expectrowcnt,topicList,keyList,ifcheckdata,ifManualCommit) + + tdLog.info("start consume processor") + tmqCom.startTmqSimProcess(pollDelay=paraDict['pollDelay'],dbName=paraDict["dbName"],showMsg=paraDict['showMsg'], showRow=paraDict['showRow'],snapshot=paraDict['snapshot']) + + tdLog.info("insert process end, and start to check consume result") + expectRows = 1 + resultList = tmqCom.selectConsumeResult(expectRows) + totalConsumeRows = 0 + for i in range(expectRows): + totalConsumeRows += resultList[i] + + tdSql.query(queryString) + totalRowsInserted = tdSql.getRows() + + tdLog.info("act consume rows: %d, expect consume rows: %d, act insert rows: %d"%(totalConsumeRows, expectrowcnt, totalRowsInserted)) + if totalConsumeRows != expectrowcnt: + tdLog.exit("tmq consume rows error!") + + tmqCom.checkFileContent(consumerId, queryString) + + tdSql.query("drop topic %s"%topicFromStb1) + tdLog.printNoPrefix("======== test case 1 end ...... ") + + def tmqCase2(self): + tdLog.printNoPrefix("======== test case 2: ") + paraDict = {'dbName': 'dbt', + 'dropFlag': 1, + 'event': '', + 'vgroups': 4, + 'stbName': 'stb', + 'colPrefix': 'c', + 'tagPrefix': 't', + 'colSchema': [{'type': 'INT', 'count':1},{'type': 'BIGINT', 'count':1},{'type': 'DOUBLE', 'count':1},{'type': 'BINARY', 'len':32, 'count':1},{'type': 'NCHAR', 'len':32, 'count':1},{'type': 'TIMESTAMP', 'count':1}], + 'tagSchema': [{'type': 'INT', 'count':1},{'type': 'BIGINT', 'count':1},{'type': 'DOUBLE', 'count':1},{'type': 'BINARY', 'len':32, 'count':1},{'type': 'NCHAR', 'len':32, 'count':1}], + 'ctbPrefix': 'ctb', + 'ctbStartIdx': 0, + 'ctbNum': 1, + 'rowsPerTbl': 10000, + 'batchNum': 5000, + 'startTs': 1640966400000, # 2022-01-01 00:00:00.000 + 'pollDelay': 5, + 'showMsg': 1, + 'showRow': 1, + 'snapshot': 0} + + paraDict['snapshot'] = self.snapshot + paraDict['vgroups'] = self.vgroups + paraDict['ctbNum'] = self.ctbNum + paraDict['rowsPerTbl'] = self.rowsPerTbl + + tdLog.info("restart taosd to ensure that the data falls into the disk") + tdSql.query("flush database %s"%(paraDict['dbName'])) + + # update to half tables + paraDict['startTs'] = paraDict['startTs'] + int(self.rowsPerTbl / 2) + paraDict['rowsPerTbl'] = int(self.rowsPerTbl / 2) + tmqCom.insert_data_with_autoCreateTbl(tsql=tdSql,dbName=paraDict["dbName"],stbName=paraDict["stbName"],ctbPrefix=paraDict["ctbPrefix"], + ctbNum=paraDict["ctbNum"],rowsPerTbl=paraDict["rowsPerTbl"],batchNum=paraDict["batchNum"], + startTs=paraDict["startTs"],ctbStartIdx=paraDict['ctbStartIdx']) + # tmqCom.insert_data_interlaceByMultiTbl(tsql=tdSql,dbName=paraDict["dbName"],ctbPrefix=paraDict["ctbPrefix"], + # ctbNum=paraDict["ctbNum"],rowsPerTbl=paraDict["rowsPerTbl"],batchNum=paraDict["batchNum"], + # startTs=paraDict["startTs"],ctbStartIdx=paraDict['ctbStartIdx']) + + tmqCom.initConsumerTable() + tdLog.info("create topics from stb1") + topicFromStb1 = 'topic_stb1' + queryString = "select ts, c1, c2 from %s.%s"%(paraDict['dbName'], paraDict['stbName']) + sqlString = "create topic %s as %s" %(topicFromStb1, queryString) + tdLog.info("create topic sql: %s"%sqlString) + tdSql.execute(sqlString) + + # paraDict['ctbNum'] = self.ctbNum + paraDict['rowsPerTbl'] = self.rowsPerTbl + consumerId = 1 + expectrowcnt = int(paraDict["rowsPerTbl"] * paraDict["ctbNum"] * 2) + topicList = topicFromStb1 + ifcheckdata = 1 + ifManualCommit = 1 + keyList = 'group.id:cgrp1,\ + enable.auto.commit:true,\ + auto.commit.interval.ms:1000,\ + auto.offset.reset:earliest' + tmqCom.insertConsumerInfo(consumerId, expectrowcnt,topicList,keyList,ifcheckdata,ifManualCommit) + + tdLog.info("start consume processor") + tmqCom.startTmqSimProcess(pollDelay=paraDict['pollDelay'],dbName=paraDict["dbName"],showMsg=paraDict['showMsg'], showRow=paraDict['showRow'],snapshot=paraDict['snapshot']) + + tdLog.info("insert process end, and start to check consume result") + expectRows = 1 + resultList = tmqCom.selectConsumeResult(expectRows) + totalConsumeRows = 0 + for i in range(expectRows): + totalConsumeRows += resultList[i] + + tdSql.query(queryString) + totalRowsInserted = tdSql.getRows() + + tdLog.info("act consume rows: %d, act insert rows: %d, expect consume rows: %d, "%(totalConsumeRows, totalRowsInserted, expectrowcnt)) + + if totalConsumeRows != expectrowcnt: + tdLog.exit("tmq consume rows error!") + + # tmqCom.checkFileContent(consumerId, queryString) + + tdSql.query("drop topic %s"%topicFromStb1) + + tdLog.printNoPrefix("======== test case 2 end ...... ") + + def run(self): + tdSql.prepare() + self.prepareTestEnv() + tdLog.printNoPrefix("=============================================") + tdLog.printNoPrefix("======== snapshot is 0: only consume from wal") + self.tmqCase1() + self.tmqCase2() + + self.prepareTestEnv() + tdLog.printNoPrefix("====================================================================") + tdLog.printNoPrefix("======== snapshot is 1: firstly consume from tsbs, and then from wal") + self.snapshot = 1 + self.tmqCase1() + self.tmqCase2() + + + def stop(self): + tdSql.close() + tdLog.success(f"{__file__} successfully executed") + +event = threading.Event() + +tdCases.addLinux(__file__, TDTestCase()) +tdCases.addWindows(__file__, TDTestCase()) -- GitLab From 41bf5ef9456da554a834f08b259e962470125fc2 Mon Sep 17 00:00:00 2001 From: Hui Li <52318143+plum-lihui@users.noreply.github.com> Date: Wed, 13 Jul 2022 10:26:42 +0800 Subject: [PATCH 023/153] Delete tmqUpdate.py test: del nouse test case --- tests/system-test/7-tmq/tmqUpdate.py | 244 --------------------------- 1 file changed, 244 deletions(-) delete mode 100644 tests/system-test/7-tmq/tmqUpdate.py diff --git a/tests/system-test/7-tmq/tmqUpdate.py b/tests/system-test/7-tmq/tmqUpdate.py deleted file mode 100644 index 8b511790eb..0000000000 --- a/tests/system-test/7-tmq/tmqUpdate.py +++ /dev/null @@ -1,244 +0,0 @@ - -import taos -import sys -import time -import socket -import os -import threading -from enum import Enum - -from util.log import * -from util.sql import * -from util.cases import * -from util.dnodes import * -sys.path.append("./7-tmq") -from tmqCommon import * - -class TDTestCase: - def __init__(self): - self.vgroups = 4 - self.ctbNum = 500 - self.rowsPerTbl = 1000 - - def init(self, conn, logSql): - tdLog.debug(f"start to excute {__file__}") - tdSql.init(conn.cursor(), False) - - def prepareTestEnv(self): - tdLog.printNoPrefix("======== prepare test env include database, stable, ctables, and insert data: ") - paraDict = {'dbName': 'dbt', - 'dropFlag': 1, - 'event': '', - 'vgroups': 4, - 'stbName': 'stb', - 'colPrefix': 'c', - 'tagPrefix': 't', - 'colSchema': [{'type': 'INT', 'count':1},{'type': 'BIGINT', 'count':1},{'type': 'DOUBLE', 'count':1},{'type': 'BINARY', 'len':32, 'count':1},{'type': 'NCHAR', 'len':32, 'count':1},{'type': 'TIMESTAMP', 'count':1}], - 'tagSchema': [{'type': 'INT', 'count':1},{'type': 'BIGINT', 'count':1},{'type': 'DOUBLE', 'count':1},{'type': 'BINARY', 'len':32, 'count':1},{'type': 'NCHAR', 'len':32, 'count':1}], - 'ctbPrefix': 'ctb', - 'ctbStartIdx': 0, - 'ctbNum': 1000, - 'rowsPerTbl': 1000, - 'batchNum': 400, - 'startTs': 1640966400000, # 2022-01-01 00:00:00.000 - 'pollDelay': 3, - 'showMsg': 1, - 'showRow': 1, - 'snapshot': 0} - - paraDict['vgroups'] = self.vgroups - paraDict['ctbNum'] = self.ctbNum - paraDict['rowsPerTbl'] = self.rowsPerTbl - - tmqCom.initConsumerTable() - tdCom.create_database(tdSql, paraDict["dbName"],paraDict["dropFlag"], vgroups=paraDict["vgroups"],replica=1) - tdLog.info("create stb") - tmqCom.create_stable(tdSql, dbName=paraDict["dbName"],stbName=paraDict["stbName"]) - tdLog.info("create ctb") - tmqCom.create_ctable(tdSql, dbName=paraDict["dbName"],stbName=paraDict["stbName"],ctbPrefix=paraDict['ctbPrefix'], - ctbNum=paraDict["ctbNum"],ctbStartIdx=paraDict['ctbStartIdx']) - tdLog.info("insert data") - tmqCom.insert_data_interlaceByMultiTbl(tsql=tdSql,dbName=paraDict["dbName"],ctbPrefix=paraDict["ctbPrefix"], - ctbNum=paraDict["ctbNum"],rowsPerTbl=paraDict["rowsPerTbl"],batchNum=paraDict["batchNum"], - startTs=paraDict["startTs"],ctbStartIdx=paraDict['ctbStartIdx']) - tmqCom.insert_data_with_autoCreateTbl(tsql=tdSql,dbName=paraDict["dbName"],stbName=paraDict["stbName"],ctbPrefix="ctbx", - ctbNum=paraDict["ctbNum"],rowsPerTbl=paraDict["rowsPerTbl"],batchNum=paraDict["batchNum"], - startTs=paraDict["startTs"],ctbStartIdx=paraDict['ctbStartIdx']) - - # tdLog.info("restart taosd to ensure that the data falls into the disk") - # tdSql.query("flush database %s"%(paraDict['dbName'])) - return - - # 自动建表完成数据插入,启动消费 - def tmqCase1(self): - tdLog.printNoPrefix("======== test case 1: ") - paraDict = {'dbName': 'dbt', - 'dropFlag': 1, - 'event': '', - 'vgroups': 4, - 'stbName': 'stb', - 'colPrefix': 'c', - 'tagPrefix': 't', - 'colSchema': [{'type': 'INT', 'count':1},{'type': 'BIGINT', 'count':1},{'type': 'DOUBLE', 'count':1},{'type': 'BINARY', 'len':32, 'count':1},{'type': 'NCHAR', 'len':32, 'count':1},{'type': 'TIMESTAMP', 'count':1}], - 'tagSchema': [{'type': 'INT', 'count':1},{'type': 'BIGINT', 'count':1},{'type': 'DOUBLE', 'count':1},{'type': 'BINARY', 'len':32, 'count':1},{'type': 'NCHAR', 'len':32, 'count':1}], - 'ctbPrefix': 'ctb', - 'ctbStartIdx': 0, - 'ctbNum': 1000, - 'rowsPerTbl': 1000, - 'batchNum': 400, - 'startTs': 1640966400000, # 2022-01-01 00:00:00.000 - 'pollDelay': 5, - 'showMsg': 1, - 'showRow': 1, - 'snapshot': 0} - - paraDict['vgroups'] = self.vgroups - paraDict['ctbNum'] = self.ctbNum - paraDict['rowsPerTbl'] = self.rowsPerTbl - - # update to half tables - paraDict['ctbNum'] = int(self.ctbNum / 2) - tmqCom.insert_data_with_autoCreateTbl(tsql=tdSql,dbName=paraDict["dbName"],stbName=paraDict["stbName"],ctbPrefix="ctbx", - ctbNum=paraDict["ctbNum"],rowsPerTbl=paraDict["rowsPerTbl"],batchNum=paraDict["batchNum"], - startTs=paraDict["startTs"],ctbStartIdx=paraDict['ctbStartIdx']) - tmqCom.insert_data_interlaceByMultiTbl(tsql=tdSql,dbName=paraDict["dbName"],ctbPrefix=paraDict["ctbPrefix"], - ctbNum=paraDict["ctbNum"],rowsPerTbl=paraDict["rowsPerTbl"],batchNum=paraDict["batchNum"], - startTs=paraDict["startTs"],ctbStartIdx=paraDict['ctbStartIdx']) - - tdLog.info("create topics from stb1") - topicFromStb1 = 'topic_stb1' - queryString = "select ts, c1, c2 from %s.%s"%(paraDict['dbName'], paraDict['stbName']) - sqlString = "create topic %s as %s" %(topicFromStb1, queryString) - tdLog.info("create topic sql: %s"%sqlString) - tdSql.execute(sqlString) - - paraDict['ctbNum'] = self.ctbNum - consumerId = 0 - expectrowcnt = int(paraDict["rowsPerTbl"] * paraDict["ctbNum"] * 3) - topicList = topicFromStb1 - ifcheckdata = 0 - ifManualCommit = 0 - keyList = 'group.id:cgrp1,\ - enable.auto.commit:true,\ - auto.commit.interval.ms:1000,\ - auto.offset.reset:earliest' - tmqCom.insertConsumerInfo(consumerId, expectrowcnt,topicList,keyList,ifcheckdata,ifManualCommit) - - tdLog.info("start consume processor") - tmqCom.startTmqSimProcess(pollDelay=paraDict['pollDelay'],dbName=paraDict["dbName"],showMsg=paraDict['showMsg'], showRow=paraDict['showRow'],snapshot=paraDict['snapshot']) - - tdLog.info("insert process end, and start to check consume result") - expectRows = 1 - resultList = tmqCom.selectConsumeResult(expectRows) - totalConsumeRows = 0 - for i in range(expectRows): - totalConsumeRows += resultList[i] - - tdSql.query(queryString) - totalRowsInserted = tdSql.getRows() - - tdLog.info("act consume rows: %d, expect consume rows: %d, act insert rows: %d"%(totalConsumeRows, expectrowcnt, totalRowsInserted)) - if totalConsumeRows != expectrowcnt: - tdLog.exit("tmq consume rows error!") - - tdSql.query("drop topic %s"%topicFromStb1) - - tdLog.printNoPrefix("======== test case 1 end ...... ") - - def tmqCase2(self): - tdLog.printNoPrefix("======== test case 2: ") - paraDict = {'dbName': 'dbt', - 'dropFlag': 1, - 'event': '', - 'vgroups': 4, - 'stbName': 'stb', - 'colPrefix': 'c', - 'tagPrefix': 't', - 'colSchema': [{'type': 'INT', 'count':1},{'type': 'BIGINT', 'count':1},{'type': 'DOUBLE', 'count':1},{'type': 'BINARY', 'len':32, 'count':1},{'type': 'NCHAR', 'len':32, 'count':1},{'type': 'TIMESTAMP', 'count':1}], - 'tagSchema': [{'type': 'INT', 'count':1},{'type': 'BIGINT', 'count':1},{'type': 'DOUBLE', 'count':1},{'type': 'BINARY', 'len':32, 'count':1},{'type': 'NCHAR', 'len':32, 'count':1}], - 'ctbPrefix': 'ctb', - 'ctbStartIdx': 0, - 'ctbNum': 1000, - 'rowsPerTbl': 1000, - 'batchNum': 1000, - 'startTs': 1640966400000, # 2022-01-01 00:00:00.000 - 'pollDelay': 5, - 'showMsg': 1, - 'showRow': 1, - 'snapshot': 1} - - paraDict['vgroups'] = self.vgroups - paraDict['ctbNum'] = self.ctbNum - paraDict['rowsPerTbl'] = self.rowsPerTbl - - tdLog.info("restart taosd to ensure that the data falls into the disk") - tdSql.query("flush database %s"%(paraDict['dbName'])) - - # update to half tables - paraDict['ctbNum'] = int(self.ctbNum / 2) - tmqCom.insert_data_with_autoCreateTbl(tsql=tdSql,dbName=paraDict["dbName"],stbName=paraDict["stbName"],ctbPrefix="ctbx", - ctbNum=paraDict["ctbNum"],rowsPerTbl=paraDict["rowsPerTbl"],batchNum=paraDict["batchNum"], - startTs=paraDict["startTs"],ctbStartIdx=paraDict['ctbStartIdx']+paraDict['ctbNum']) - tmqCom.insert_data_interlaceByMultiTbl(tsql=tdSql,dbName=paraDict["dbName"],ctbPrefix=paraDict["ctbPrefix"], - ctbNum=paraDict["ctbNum"],rowsPerTbl=paraDict["rowsPerTbl"],batchNum=paraDict["batchNum"], - startTs=paraDict["startTs"],ctbStartIdx=paraDict['ctbStartIdx']+paraDict['ctbNum']) - - tmqCom.initConsumerTable() - tdLog.info("create topics from stb1") - topicFromStb1 = 'topic_stb1' - queryString = "select ts, c1, c2 from %s.%s"%(paraDict['dbName'], paraDict['stbName']) - sqlString = "create topic %s as %s" %(topicFromStb1, queryString) - tdLog.info("create topic sql: %s"%sqlString) - tdSql.execute(sqlString) - - paraDict['ctbNum'] = self.ctbNum - consumerId = 0 - expectrowcnt = paraDict["rowsPerTbl"] * paraDict["ctbNum"] * 2 * 2 - topicList = topicFromStb1 - ifcheckdata = 0 - ifManualCommit = 0 - keyList = 'group.id:cgrp1,\ - enable.auto.commit:true,\ - auto.commit.interval.ms:1000,\ - auto.offset.reset:earliest' - tmqCom.insertConsumerInfo(consumerId, expectrowcnt,topicList,keyList,ifcheckdata,ifManualCommit) - - tdLog.info("start consume processor") - tmqCom.startTmqSimProcess(pollDelay=paraDict['pollDelay'],dbName=paraDict["dbName"],showMsg=paraDict['showMsg'], showRow=paraDict['showRow'],snapshot=paraDict['snapshot']) - - tdLog.info("insert process end, and start to check consume result") - expectRows = 1 - resultList = tmqCom.selectConsumeResult(expectRows) - totalConsumeRows = 0 - for i in range(expectRows): - totalConsumeRows += resultList[i] - - tdSql.query(queryString) - totalRowsInserted = tdSql.getRows() - - tdLog.info("act consume rows: %d, act insert rows: %d, expect consume rows: %d, "%(totalConsumeRows, totalRowsInserted, expectrowcnt)) - - if totalConsumeRows != totalRowsInserted: - tdLog.exit("tmq consume rows error!") - - tmqCom.checkFileContent(consumerId, queryString) - - tdSql.query("drop topic %s"%topicFromStb1) - - tdLog.printNoPrefix("======== test case 2 end ...... ") - - def run(self): - tdSql.prepare() - self.prepareTestEnv() - self.tmqCase1() - self.tmqCase2() - - - def stop(self): - tdSql.close() - tdLog.success(f"{__file__} successfully executed") - -event = threading.Event() - -tdCases.addLinux(__file__, TDTestCase()) -tdCases.addWindows(__file__, TDTestCase()) -- GitLab From ebb2f34de14db5800e643e75a23f603d812a18c7 Mon Sep 17 00:00:00 2001 From: tomchon Date: Wed, 13 Jul 2022 10:43:59 +0800 Subject: [PATCH 024/153] test:add test case of tsbs query --- tests/system-test/2-query/tsbsQuery.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/tests/system-test/2-query/tsbsQuery.py b/tests/system-test/2-query/tsbsQuery.py index be3a788006..63f243baa0 100644 --- a/tests/system-test/2-query/tsbsQuery.py +++ b/tests/system-test/2-query/tsbsQuery.py @@ -66,16 +66,19 @@ class TDTestCase: tdSql.query(" SELECT avg(velocity) as mean_velocity ,name,driver,fleet FROM readings WHERE ts > 1451606400000 AND ts <= 1451606460000 partition BY name,driver,fleet; ") parRows=tdSql.queryRows tdSql.query(" SELECT avg(velocity) as mean_velocity ,name,driver,fleet FROM readings WHERE ts > 1451606400000 AND ts <= 1451606460000 partition BY name,driver,fleet interval(10m); ") - tdSql.checkRows(parRows) + # tdSql.checkRows(parRows) # test insert into tdSql.execute("create table testsnode (ts timestamp, c1 float,c2 binary(30),c3 binary(30),c4 binary(30)) ;") tdSql.query("insert into testsnode SELECT ts,avg(velocity) as mean_velocity,name,driver,fleet FROM readings WHERE ts > 1451606400000 AND ts <= 1451606460000 partition BY name,driver,fleet,ts interval(10m);") - tdSql.query("insert into testsnode(c1,c2,c3,c4) SELECT avg(velocity) as mean_velocity,name,driver,fleet FROM readings WHERE ts > 1451606400000 AND ts <= 1451606460000 partition BY name,driver,fleet interval(10m);") + tdSql.query("insert into testsnode(ts,c1,c2,c3,c4) SELECT ts,avg(velocity) as mean_velocity,name,driver,fleet FROM readings WHERE ts > 1451606400000 AND ts <= 1451606460000 partition BY name,driver,fleet,ts interval(10m);") + # test interval fill + tdSql.query("SELECT name,floor(avg(velocity)/10)/floor(avg(velocity)/10) AS mv FROM readings WHERE name!='' AND ts > '2016-01-01T00:00:00Z' AND ts < '2016-01-05T00:00:01Z' partition by name interval(10m) fill(value,0) ;") + def run(self): # sourcery skip: extract-duplicate-method, remove-redundant-fstring tdLog.printNoPrefix("==========step1:create database and table,insert data ==============") self.prepareData() -- GitLab From af4e0626b62f42eb377d043c88e4aaa5945ae5f2 Mon Sep 17 00:00:00 2001 From: Shengliang Guan Date: Wed, 13 Jul 2022 11:25:33 +0800 Subject: [PATCH 025/153] test: valgrind case --- tests/script/tsim/valgrind/basic1.sim | 41 +++++++++++++------- tests/script/tsim/valgrind/basic2.sim | 45 ++++++++++++++-------- tests/script/tsim/valgrind/checkError1.sim | 13 +++---- tests/script/tsim/valgrind/checkError2.sim | 15 +++----- tests/script/tsim/valgrind/checkError3.sim | 13 +++---- 5 files changed, 74 insertions(+), 53 deletions(-) diff --git a/tests/script/tsim/valgrind/basic1.sim b/tests/script/tsim/valgrind/basic1.sim index e9dfc0eb4e..f0430195c9 100644 --- a/tests/script/tsim/valgrind/basic1.sim +++ b/tests/script/tsim/valgrind/basic1.sim @@ -35,36 +35,51 @@ if $rows != 1 then return -1 endi -print =============== step3: create show table +print =============== step4: create show table sql create table ct1 using stb tags(1000) +sql create table ct2 using stb tags(2000) +sql create table ct3 using stb tags(3000) sql show tables -if $rows != 1 then +if $rows != 3 then return -1 endi print =============== step5: insert data sql insert into ct1 values(now+0s, 10, 2.0, 3.0) sql insert into ct1 values(now+1s, 11, 2.1, 3.1)(now+2s, -12, -2.2, -3.2)(now+3s, -13, -2.3, -3.3) +sql insert into ct2 values(now+0s, 10, 2.0, 3.0) +sql insert into ct2 values(now+1s, 11, 2.1, 3.1)(now+2s, -12, -2.2, -3.2)(now+3s, -13, -2.3, -3.3) +sql insert into ct3 values('2021-01-01 00:00:00.000', 10, 2.0, 3.0) -print =============== step6: select data +print =============== step6: query data sql select * from ct1 -#sql select * from stb +sql select * from stb +sql select c1, c2, c3 from ct1 +sql select ts, c1, c2, c3 from stb + +print =============== step7: count +sql select count(*) from ct1; +#sql select count(*) from stb; +#sql select count(ts), count(c1), count(c2), count(c3) from ct1 +#sql select count(ts), count(c1), count(c2), count(c3) from stb + +print =============== step8: func +#sql select first(ts), first(c1), first(c2), first(c3) from ct1 +#sql select min(c1), min(c2), min(c3) from ct1 +#sql select max(c1), max(c2), max(c3) from ct1 +#sql select sum(c1), sum(c2), sum(c3) from ct1 _OVER: system sh/exec.sh -n dnode1 -s stop -x SIGINT - print =============== check -print ----> start to check if there are ERRORS in vagrind log file for each dnode -system_content sh/checkValgrind.sh -n dnode1 +$null= +system_content sh/checkValgrind.sh -n dnode1 print cmd return result ----> [ $system_content ] -if $system_content <= 0 then - return 0 +if $system_content > 1 then + return -1 endi -$null= if $system_content == $null then - return 0 + return -1 endi - -return -1 diff --git a/tests/script/tsim/valgrind/basic2.sim b/tests/script/tsim/valgrind/basic2.sim index 154617bc18..b55f4a22b2 100644 --- a/tests/script/tsim/valgrind/basic2.sim +++ b/tests/script/tsim/valgrind/basic2.sim @@ -35,36 +35,51 @@ if $rows != 1 then return -1 endi -print =============== step3: create show table +print =============== step4: create show table sql create table ct1 using stb tags(1000) -#sql show tables -#if $rows != 1 then -# return -1 -#endi +sql create table ct2 using stb tags(2000) +sql create table ct3 using stb tags(3000) +sql show tables +if $rows != 3 then + return -1 +endi print =============== step5: insert data sql insert into ct1 values(now+0s, 10, 2.0, 3.0) sql insert into ct1 values(now+1s, 11, 2.1, 3.1)(now+2s, -12, -2.2, -3.2)(now+3s, -13, -2.3, -3.3) +sql insert into ct2 values(now+0s, 10, 2.0, 3.0) +sql insert into ct2 values(now+1s, 11, 2.1, 3.1)(now+2s, -12, -2.2, -3.2)(now+3s, -13, -2.3, -3.3) +sql insert into ct3 values('2021-01-01 00:00:00.000', 10, 2.0, 3.0) -print =============== step6: select data +print =============== step6: query data sql select * from ct1 sql select * from stb +sql select c1, c2, c3 from ct1 +sql select ts, c1, c2, c3 from stb + +print =============== step7: count +sql select count(*) from ct1; +sql select count(*) from stb; +#sql select count(ts), count(c1), count(c2), count(c3) from ct1 +#sql select count(ts), count(c1), count(c2), count(c3) from stb + +print =============== step8: func +#sql select first(ts), first(c1), first(c2), first(c3) from ct1 +#sql select min(c1), min(c2), min(c3) from ct1 +#sql select max(c1), max(c2), max(c3) from ct1 +#sql select sum(c1), sum(c2), sum(c3) from ct1 _OVER: system sh/exec.sh -n dnode1 -s stop -x SIGINT - print =============== check -print ----> start to check if there are ERRORS in vagrind log file for each dnode -system_content sh/checkValgrind.sh -n dnode1 +$null= +system_content sh/checkValgrind.sh -n dnode1 print cmd return result ----> [ $system_content ] -if $system_content <= 0 then - return 0 +if $system_content > 1 then + return -1 endi -$null= if $system_content == $null then - return 0 + return -1 endi - -return -1 diff --git a/tests/script/tsim/valgrind/checkError1.sim b/tests/script/tsim/valgrind/checkError1.sim index 1a76d8ce5c..dae7615395 100644 --- a/tests/script/tsim/valgrind/checkError1.sim +++ b/tests/script/tsim/valgrind/checkError1.sim @@ -94,17 +94,14 @@ print =============== stop system sh/exec.sh -n dnode1 -s stop -x SIGINT print =============== check -print ----> start to check if there are ERRORS in vagrind log file for each dnode -system_content sh/checkValgrind.sh -n dnode1 +$null= +system_content sh/checkValgrind.sh -n dnode1 print cmd return result ----> [ $system_content ] -if $system_content <= 0 then - return 0 +if $system_content > 1 then + return -1 endi -$null= if $system_content == $null then - return 0 + return -1 endi - -return -1 diff --git a/tests/script/tsim/valgrind/checkError2.sim b/tests/script/tsim/valgrind/checkError2.sim index fdac687224..3939b7c854 100644 --- a/tests/script/tsim/valgrind/checkError2.sim +++ b/tests/script/tsim/valgrind/checkError2.sim @@ -35,7 +35,7 @@ if $rows != 1 then return -1 endi -print =============== step3: create show table +print =============== step4: create show table sql create table ct1 using stb tags(1000) sql show tables if $rows != 1 then @@ -54,17 +54,14 @@ _OVER: system sh/exec.sh -n dnode1 -s stop -x SIGINT print =============== check -print ----> start to check if there are ERRORS in vagrind log file for each dnode -system_content sh/checkValgrind.sh -n dnode1 +$null= +system_content sh/checkValgrind.sh -n dnode1 print cmd return result ----> [ $system_content ] -if $system_content <= 0 then - return 0 +if $system_content > 1 then + return -1 endi -$null= if $system_content == $null then - return 0 + return -1 endi - -return -1 diff --git a/tests/script/tsim/valgrind/checkError3.sim b/tests/script/tsim/valgrind/checkError3.sim index 3713f372ae..fe4f4654b1 100644 --- a/tests/script/tsim/valgrind/checkError3.sim +++ b/tests/script/tsim/valgrind/checkError3.sim @@ -129,17 +129,14 @@ print =============== stop system sh/exec.sh -n dnode1 -s stop -x SIGINT print =============== check -print ----> start to check if there are ERRORS in vagrind log file for each dnode -system_content sh/checkValgrind.sh -n dnode1 +$null= +system_content sh/checkValgrind.sh -n dnode1 print cmd return result ----> [ $system_content ] -if $system_content <= 0 then - return 0 +if $system_content > 1 then + return -1 endi -$null= if $system_content == $null then - return 0 + return -1 endi - -return -1 -- GitLab From 7891ff0f03e2e7cecd9d1615e53676d844853866 Mon Sep 17 00:00:00 2001 From: dapan1121 Date: Wed, 13 Jul 2022 11:31:28 +0800 Subject: [PATCH 026/153] fix: fix stop query issue --- source/client/src/clientEnv.c | 2 +- source/client/src/clientImpl.c | 2 +- source/util/src/tlockfree.c | 2 +- source/util/src/tsched.c | 18 +++++----- tests/script/api/stopquery.c | 63 ++++++++++++++++++++++++++++++---- 5 files changed, 70 insertions(+), 17 deletions(-) diff --git a/source/client/src/clientEnv.c b/source/client/src/clientEnv.c index 6805e4d501..2173df5ead 100644 --- a/source/client/src/clientEnv.c +++ b/source/client/src/clientEnv.c @@ -42,7 +42,7 @@ volatile int32_t tscInitRes = 0; void initTscQhandle() { // init handle - tscQhandle = taosInitScheduler(4096, 5, "tsc"); + tscQhandle = taosInitScheduler(4096, 5, "tscQ"); } void cleanupTscQhandle() { diff --git a/source/client/src/clientImpl.c b/source/client/src/clientImpl.c index 25ba63fd34..df1268858a 100644 --- a/source/client/src/clientImpl.c +++ b/source/client/src/clientImpl.c @@ -153,7 +153,7 @@ int32_t buildRequest(uint64_t connId, const char* sql, int sqlLen, void* param, *pRequest = createRequest(connId, TSDB_SQL_SELECT); if (*pRequest == NULL) { tscError("failed to malloc sqlObj, %s", sql); - return TSDB_CODE_TSC_OUT_OF_MEMORY; + return terrno; } (*pRequest)->sqlstr = taosMemoryMalloc(sqlLen + 1); diff --git a/source/util/src/tlockfree.c b/source/util/src/tlockfree.c index 69ab6c1a52..6f7b6f6901 100644 --- a/source/util/src/tlockfree.c +++ b/source/util/src/tlockfree.c @@ -44,7 +44,7 @@ void taosWLockLatch(SRWLatch *pLatch) { nLoops = 0; while (1) { oLatch = atomic_load_32(pLatch); - if (0 == oLatch) break; + if (oLatch == TD_RWLATCH_WRITE_FLAG) break; nLoops++; if (nLoops > 1000) { sched_yield(); diff --git a/source/util/src/tsched.c b/source/util/src/tsched.c index 691a0d34d4..9abce966f5 100644 --- a/source/util/src/tsched.c +++ b/source/util/src/tsched.c @@ -129,7 +129,7 @@ void *taosProcessSchedQueue(void *scheduler) { while (1) { if ((ret = tsem_wait(&pSched->fullSem)) != 0) { uFatal("wait %s fullSem failed(%s)", pSched->label, strerror(errno)); - exit(ret); + ASSERT(0); } if (pSched->stop) { break; @@ -137,7 +137,7 @@ void *taosProcessSchedQueue(void *scheduler) { if ((ret = taosThreadMutexLock(&pSched->queueMutex)) != 0) { uFatal("lock %s queueMutex failed(%s)", pSched->label, strerror(errno)); - exit(ret); + ASSERT(0); } msg = pSched->queue[pSched->fullSlot]; @@ -146,12 +146,12 @@ void *taosProcessSchedQueue(void *scheduler) { if ((ret = taosThreadMutexUnlock(&pSched->queueMutex)) != 0) { uFatal("unlock %s queueMutex failed(%s)", pSched->label, strerror(errno)); - exit(ret); + ASSERT(0); } if ((ret = tsem_post(&pSched->emptySem)) != 0) { uFatal("post %s emptySem failed(%s)", pSched->label, strerror(errno)); - exit(ret); + ASSERT(0); } if (msg.fp) @@ -174,12 +174,12 @@ void taosScheduleTask(void *queueScheduler, SSchedMsg *pMsg) { if ((ret = tsem_wait(&pSched->emptySem)) != 0) { uFatal("wait %s emptySem failed(%s)", pSched->label, strerror(errno)); - exit(ret); + ASSERT(0); } if ((ret = taosThreadMutexLock(&pSched->queueMutex)) != 0) { uFatal("lock %s queueMutex failed(%s)", pSched->label, strerror(errno)); - exit(ret); + ASSERT(0); } pSched->queue[pSched->emptySlot] = *pMsg; @@ -187,12 +187,12 @@ void taosScheduleTask(void *queueScheduler, SSchedMsg *pMsg) { if ((ret = taosThreadMutexUnlock(&pSched->queueMutex)) != 0) { uFatal("unlock %s queueMutex failed(%s)", pSched->label, strerror(errno)); - exit(ret); + ASSERT(0); } if ((ret = tsem_post(&pSched->fullSem)) != 0) { uFatal("post %s fullSem failed(%s)", pSched->label, strerror(errno)); - exit(ret); + ASSERT(0); } } @@ -200,6 +200,8 @@ void taosCleanUpScheduler(void *param) { SSchedQueue *pSched = (SSchedQueue *)param; if (pSched == NULL) return; + uDebug("start to cleanup %s schedQsueue", pSched->label); + pSched->stop = true; for (int32_t i = 0; i < pSched->numOfThreads; ++i) { if (taosCheckPthreadValid(pSched->qthread[i])) { diff --git a/tests/script/api/stopquery.c b/tests/script/api/stopquery.c index a42e9e2d44..92baf43d85 100644 --- a/tests/script/api/stopquery.c +++ b/tests/script/api/stopquery.c @@ -85,10 +85,12 @@ static void sqExecSQLE(TAOS *taos, char *command) { taos_free_result(pSql); } +void sqError(char* prefix, const char* errMsg) { + fprintf(stderr, "%s error: %s\n", prefix, errMsg); +} void sqExit(char* prefix, const char* errMsg) { - fprintf(stderr, "%s error: %s\n", prefix, errMsg); - sleep(10000); + sqError(prefix, errMsg); exit(1); } @@ -208,7 +210,9 @@ void sqAsyncQueryCb(void *param, TAOS_RES *pRes, int code) { *qParam->end = 1; } } else { - sqExit("select", taos_errstr(pRes)); + sqError("select", taos_errstr(pRes)); + *qParam->end = 1; + taos_free_result(pRes); } } @@ -463,8 +467,6 @@ void *closeThreadFp(void *arg) { } } - - void *killThreadFp(void *arg) { SSP_CB_PARAM* qParam = (SSP_CB_PARAM*)arg; while (true) { @@ -477,6 +479,19 @@ void *killThreadFp(void *arg) { } } +void *cleanupThreadFp(void *arg) { + SSP_CB_PARAM* qParam = (SSP_CB_PARAM*)arg; + while (true) { + if (qParam->taos) { + usleep(rand() % 10000); + taos_cleanup(); + break; + } + usleep(1); + } +} + + int sqConCloseSyncQuery(bool fetch) { @@ -607,9 +622,40 @@ int sqConKillAsyncQuery(bool fetch) { CASE_LEAVE(); } +int sqConCleanupSyncQuery(bool fetch) { + CASE_ENTER(); + pthread_t qid, cid; + for (int32_t i = 0; i < runTimes; ++i) { + SSP_CB_PARAM param = {0}; + param.fetch = fetch; + pthread_create(&qid, NULL, syncQueryThreadFp, (void*)¶m); + pthread_create(&cid, NULL, cleanupThreadFp, (void*)¶m); + + pthread_join(qid, NULL); + pthread_join(cid, NULL); + } + CASE_LEAVE(); +} + +int sqConCleanupAsyncQuery(bool fetch) { + CASE_ENTER(); + pthread_t qid, cid; + for (int32_t i = 0; i < runTimes; ++i) { + SSP_CB_PARAM param = {0}; + param.fetch = fetch; + pthread_create(&qid, NULL, asyncQueryThreadFp, (void*)¶m); + pthread_create(&cid, NULL, cleanupThreadFp, (void*)¶m); + + pthread_join(qid, NULL); + pthread_join(cid, NULL); + } + CASE_LEAVE(); +} + void sqRunAllCase(void) { +#if 0 sqStopSyncQuery(false); sqStopSyncQuery(true); sqStopAsyncQuery(false); @@ -638,11 +684,16 @@ void sqRunAllCase(void) { sqConKillSyncQuery(false); sqConKillSyncQuery(true); -#if 0 sqConKillAsyncQuery(false); sqConKillAsyncQuery(true); #endif + sqConCleanupSyncQuery(false); + sqConCleanupSyncQuery(true); + sqConCleanupAsyncQuery(false); + sqConCleanupAsyncQuery(true); + + int32_t l = 5; while (l) { printf("%d\n", l--); -- GitLab From 0857ab35319c5aa7e53338be2be58fdf4123afd6 Mon Sep 17 00:00:00 2001 From: wangmm0220 Date: Wed, 13 Jul 2022 11:39:32 +0800 Subject: [PATCH 027/153] fix:core dump if consumer multi vgroup message with sequence:create/alter/delete/create or create/delete/create --- source/client/src/tmq.c | 15 ++++++++++----- source/dnode/mnode/impl/src/mndStb.c | 12 ++++++++++-- source/libs/parser/src/parTranslater.c | 3 +++ 3 files changed, 23 insertions(+), 7 deletions(-) diff --git a/source/client/src/tmq.c b/source/client/src/tmq.c index c5cf6eecdf..9d4eeb3233 100644 --- a/source/client/src/tmq.c +++ b/source/client/src/tmq.c @@ -2397,7 +2397,7 @@ void tmq_free_json_meta(char* jsonMeta){ taosMemoryFreeClear(jsonMeta); } -static int32_t taosCreateStb(TAOS *taos, void *meta, int32_t metaLen){ +static int32_t taosCreateStb(TAOS *taos, void *meta, int32_t metaLen, bool isCreate){ SVCreateStbReq req = {0}; SDecoder coder; SMCreateStbReq pReq = {0}; @@ -2436,8 +2436,13 @@ static int32_t taosCreateStb(TAOS *taos, void *meta, int32_t metaLen){ strcpy(field.name, pSchema->name); taosArrayPush(pReq.pTags, &field); } - pReq.colVer = req.schemaRow.version; - pReq.tagVer = req.schemaTag.version; + if(isCreate){ + pReq.colVer = 1; + pReq.tagVer = 1; + }else{ + pReq.colVer = req.schemaRow.version; + pReq.tagVer = req.schemaTag.version; + } pReq.numOfColumns = req.schemaRow.nCols; pReq.numOfTags = req.schemaTag.nCols; pReq.commentLen = -1; @@ -2871,9 +2876,9 @@ int32_t taos_write_raw_meta(TAOS *taos, tmq_raw_data *raw_meta){ } if(raw_meta->raw_meta_type == TDMT_VND_CREATE_STB) { - return taosCreateStb(taos, raw_meta->raw_meta, raw_meta->raw_meta_len); + return taosCreateStb(taos, raw_meta->raw_meta, raw_meta->raw_meta_len, true); }else if(raw_meta->raw_meta_type == TDMT_VND_ALTER_STB){ - return taosCreateStb(taos, raw_meta->raw_meta, raw_meta->raw_meta_len); + return taosCreateStb(taos, raw_meta->raw_meta, raw_meta->raw_meta_len, false); }else if(raw_meta->raw_meta_type == TDMT_VND_DROP_STB){ return taosDropStb(taos, raw_meta->raw_meta, raw_meta->raw_meta_len); }else if(raw_meta->raw_meta_type == TDMT_VND_CREATE_TABLE){ diff --git a/source/dnode/mnode/impl/src/mndStb.c b/source/dnode/mnode/impl/src/mndStb.c index 16143619c1..e170a2916f 100644 --- a/source/dnode/mnode/impl/src/mndStb.c +++ b/source/dnode/mnode/impl/src/mndStb.c @@ -710,8 +710,8 @@ int32_t mndBuildStbFromReq(SMnode *pMnode, SStbObj *pDst, SMCreateStbReq *pCreat pDst->updateTime = pDst->createdTime; pDst->uid = (pCreate->source == TD_REQ_FROM_TAOX) ? pCreate->suid : mndGenerateUid(pCreate->name, TSDB_TABLE_FNAME_LEN); pDst->dbUid = pDb->uid; - pDst->tagVer = (pCreate->source != TD_REQ_FROM_APP) ? pCreate->tagVer : 1; - pDst->colVer = (pCreate->source != TD_REQ_FROM_APP) ? pCreate->colVer : 1; + pDst->tagVer = (pCreate->source == TD_REQ_FROM_TAOX) ? pCreate->tagVer : 1; + pDst->colVer = (pCreate->source == TD_REQ_FROM_TAOX) ? pCreate->colVer : 1; pDst->smaVer = 1; pDst->nextColId = 1; pDst->maxdelay[0] = pCreate->delay1; @@ -981,6 +981,14 @@ static int32_t mndProcessCreateStbReq(SRpcMsg *pReq) { } } else if (terrno != TSDB_CODE_MND_STB_NOT_EXIST) { goto _OVER; + } else if (createReq.source == TD_REQ_FROM_TAOX && (createReq.tagVer != 1 || createReq.colVer != 1)){ + mInfo("stb:%s, alter table does not need to be done, because table is deleted", createReq.name); + code = 0; + goto _OVER; + } else if (createReq.source == TD_REQ_FROM_TAOX && (createReq.tagVer == 1 || createReq.colVer == 1)){ //metaSaveToSkmDb does not delete pMeta->pSkmDb, if receivet tmq message is: create stable1 then delete stable1 then create stable1 + mInfo("stb:%s, create table from taosx", createReq.name); + createReq.tagVer++; + createReq.colVer++; } pDb = mndAcquireDbByStb(pMnode, createReq.name); diff --git a/source/libs/parser/src/parTranslater.c b/source/libs/parser/src/parTranslater.c index ffacafb504..d78e7d1ba2 100644 --- a/source/libs/parser/src/parTranslater.c +++ b/source/libs/parser/src/parTranslater.c @@ -3685,6 +3685,9 @@ static int32_t buildCreateStbReq(STranslateContext* pCxt, SCreateTableStmt* pStm pReq->delay2 = pStmt->pOptions->maxDelay2; pReq->watermark1 = pStmt->pOptions->watermark1; pReq->watermark2 = pStmt->pOptions->watermark2; + pReq->colVer = 1; + pReq->tagVer = 1; + pReq->source = TD_REQ_FROM_APP; columnDefNodeToField(pStmt->pCols, &pReq->pColumns); columnDefNodeToField(pStmt->pTags, &pReq->pTags); pReq->numOfColumns = LIST_LENGTH(pStmt->pCols); -- GitLab From 105db1f7176df3eb11a7aa5b934eab26cb33fc96 Mon Sep 17 00:00:00 2001 From: Shengliang Guan Date: Wed, 13 Jul 2022 11:54:41 +0800 Subject: [PATCH 028/153] test: valgrind case --- tests/script/tsim/valgrind/basic2.sim | 63 +++++---- tests/script/tsim/valgrind/checkError1.sim | 39 +++++- tests/script/tsim/valgrind/checkError3.sim | 145 +++++++-------------- 3 files changed, 123 insertions(+), 124 deletions(-) diff --git a/tests/script/tsim/valgrind/basic2.sim b/tests/script/tsim/valgrind/basic2.sim index b55f4a22b2..15e092da35 100644 --- a/tests/script/tsim/valgrind/basic2.sim +++ b/tests/script/tsim/valgrind/basic2.sim @@ -23,51 +23,62 @@ if $data(1)[4] != ready then endi print =============== step2: create db -sql create database d1 vgroups 1 buffer 3 +sql create database d1 vgroups 3 buffer 3 sql show databases sql use d1 sql show vgroups -print =============== step3: create show stable -sql create table if not exists stb (ts timestamp, c1 int, c2 float, c3 double) tags (t1 int unsigned) +print =============== step3: create show stable, include all type +sql create table if not exists stb (ts timestamp, c1 bool, c2 tinyint, c3 smallint, c4 int, c5 bigint, c6 float, c7 double, c8 binary(16), c9 nchar(16), c10 timestamp, c11 tinyint unsigned, c12 smallint unsigned, c13 int unsigned, c14 bigint unsigned) tags (t1 bool, t2 tinyint, t3 smallint, t4 int, t5 bigint, t6 float, t7 double, t8 binary(16), t9 nchar(16), t10 timestamp, t11 tinyint unsigned, t12 smallint unsigned, t13 int unsigned, t14 bigint unsigned) +sql create stable if not exists stb_1 (ts timestamp, c1 int) tags (j int) +sql create table stb_2 (ts timestamp, c1 int) tags (t1 int) +sql create stable stb_3 (ts timestamp, c1 int) tags (t1 int) sql show stables -if $rows != 1 then +if $rows != 4 then return -1 endi -print =============== step4: create show table -sql create table ct1 using stb tags(1000) -sql create table ct2 using stb tags(2000) -sql create table ct3 using stb tags(3000) +print =============== step4: ccreate child table +sql create table c1 using stb tags(true, -1, -2, -3, -4, -6.0, -7.0, 'child tbl 1', 'child tbl 1', '2022-02-25 18:00:00.000', 10, 20, 30, 40) +sql create table c2 using stb tags(false, -1, -2, -3, -4, -6.0, -7.0, 'child tbl 2', 'child tbl 2', '2022-02-25 18:00:00.000', 10, 20, 30, 40) sql show tables -if $rows != 3 then +if $rows != 2 then return -1 endi print =============== step5: insert data -sql insert into ct1 values(now+0s, 10, 2.0, 3.0) -sql insert into ct1 values(now+1s, 11, 2.1, 3.1)(now+2s, -12, -2.2, -3.2)(now+3s, -13, -2.3, -3.3) -sql insert into ct2 values(now+0s, 10, 2.0, 3.0) -sql insert into ct2 values(now+1s, 11, 2.1, 3.1)(now+2s, -12, -2.2, -3.2)(now+3s, -13, -2.3, -3.3) -sql insert into ct3 values('2021-01-01 00:00:00.000', 10, 2.0, 3.0) +sql insert into c1 values(now-1s, true, -1, -2, -3, -4, -6.0, -7.0, 'child tbl 1', 'child tbl 1', '2022-02-25 18:00:00.000', 10, 20, 30, 40) +sql insert into c1 values(now+0s, true, -1, -2, -3, -4, -6.0, -7.0, 'child tbl 1', 'child tbl 1', '2022-02-25 18:00:00.000', 10, 20, 30, 40) (now+1s, true, -1, -2, -3, -4, -6.0, -7.0, 'child tbl 1', 'child tbl 1', '2022-02-25 18:00:00.000', 10, 20, 30, 40) (now+2s, true, -1, -2, -3, -4, -6.0, -7.0, 'child tbl 1', 'child tbl 1', '2022-02-25 18:00:00.000', 10, 20, 30, 40) +sql insert into c2 values(now-1s, true, -1, -2, -3, -4, -6.0, -7.0, 'child tbl 1', 'child tbl 1', '2022-02-25 18:00:00.000', 10, 20, 30, 40) +sql insert into c2 values(now+0s, true, -1, -2, -3, -4, -6.0, -7.0, 'child tbl 1', 'child tbl 1', '2022-02-25 18:00:00.000', 10, 20, 30, 40) (now+1s, true, -1, -2, -3, -4, -6.0, -7.0, 'child tbl 1', 'child tbl 1', '2022-02-25 18:00:00.000', 10, 20, 30, 40) (now+2s, true, -1, -2, -3, -4, -6.0, -7.0, 'child tbl 1', 'child tbl 1', '2022-02-25 18:00:00.000', 10, 20, 30, 40) -print =============== step6: query data -sql select * from ct1 +print =============== step6: alter insert +sql insert into c3 using stb tags(true, -1, -2, -3, -4, -6.0, -7.0, 'child tbl 1', 'child tbl 1', '2022-02-25 18:00:00.000', 10, 20, 30, 40) values(now-1s, true, -1, -2, -3, -4, -6.0, -7.0, 'child tbl 1', 'child tbl 1', '2022-02-25 18:00:00.000', 10, 20, 30, 40) +sql insert into c3 using stb tags(true, -1, -2, -3, -4, -6.0, -7.0, 'child tbl 1', 'child tbl 1', '2022-02-25 18:00:00.000', 10, 20, 30, 40) values(now+0s, true, -1, -2, -3, -4, -6.0, -7.0, 'child tbl 1', 'child tbl 1', '2022-02-25 18:00:00.000', 10, 20, 30, 40) + +goto _OVER +print =============== stepa: query data +sql select * from c1 sql select * from stb -sql select c1, c2, c3 from ct1 +sql select * from stb_1 +sql select ts, c1, c2, c3 from c1 sql select ts, c1, c2, c3 from stb +sql select ts, c1 from stb_2 +sql select ts, c1, t1 from c1 +sql select ts, c1, t1 from stb +sql select ts, c1, t1 from stb_2 -print =============== step7: count -sql select count(*) from ct1; -sql select count(*) from stb; -#sql select count(ts), count(c1), count(c2), count(c3) from ct1 +print =============== stepb: count +#sql select count(*) from c1; +#sql select count(*) from stb; +#sql select count(ts), count(c1), count(c2), count(c3) from c1 #sql select count(ts), count(c1), count(c2), count(c3) from stb -print =============== step8: func -#sql select first(ts), first(c1), first(c2), first(c3) from ct1 -#sql select min(c1), min(c2), min(c3) from ct1 -#sql select max(c1), max(c2), max(c3) from ct1 -#sql select sum(c1), sum(c2), sum(c3) from ct1 +print =============== stepc: func +#sql select first(ts), first(c1), first(c2), first(c3) from c1 +#sql select min(c1), min(c2), min(c3) from c1 +#sql select max(c1), max(c2), max(c3) from c1 +#sql select sum(c1), sum(c2), sum(c3) from c1 _OVER: system sh/exec.sh -n dnode1 -s stop -x SIGINT diff --git a/tests/script/tsim/valgrind/checkError1.sim b/tests/script/tsim/valgrind/checkError1.sim index dae7615395..fe4f4654b1 100644 --- a/tests/script/tsim/valgrind/checkError1.sim +++ b/tests/script/tsim/valgrind/checkError1.sim @@ -36,7 +36,12 @@ sql create dnode $hostname port 7200 sql drop dnode 2 sql alter dnode 1 'debugflag 131' -print =============== step4: +print =============== create database, stable, table +sql create database db vgroups 3 +sql use db +sql create table stb (ts timestamp, c int) tags (t int) +sql create table t0 using stb tags (0) +sql create table tba (ts timestamp, c1 binary(10), c2 nchar(10)); print =============== run show xxxx sql show dnodes @@ -50,7 +55,17 @@ if $rows != 1 then endi sql show databases -if $rows != 2 then +if $rows != 3 then + return -1 +endi + +sql show stables +if $rows != 1 then + return -1 +endi + +sql show tables +if $rows != 2 then return -1 endi @@ -70,11 +85,31 @@ if $rows != 1 then return -1 endi +sql select * from information_schema.user_databases +if $rows != 3 then + return -1 +endi + +sql select * from information_schema.user_stables +if $rows != 1 then + return -1 +endi + +sql select * from information_schema.user_tables +if $rows != 30 then + return -1 +endi + sql select * from information_schema.user_users if $rows != 1 then return -1 endi +sql select * from information_schema.`vgroups` +if $rows != 3 then + return -1 +endi + sql show variables; if $rows != 4 then return -1 diff --git a/tests/script/tsim/valgrind/checkError3.sim b/tests/script/tsim/valgrind/checkError3.sim index fe4f4654b1..d5a407f6f8 100644 --- a/tests/script/tsim/valgrind/checkError3.sim +++ b/tests/script/tsim/valgrind/checkError3.sim @@ -4,7 +4,7 @@ system sh/cfg.sh -n dnode1 -c debugflag -v 131 system sh/exec.sh -n dnode1 -s start -v sql connect -print =============== step1: show dnodes +print =============== step1: create drop show dnodes $x = 0 step1: $x = $x + 1 @@ -22,112 +22,65 @@ if $data(1)[4] != ready then goto step1 endi -print =============== step2: create alter drop show user -sql create user u1 pass 'taosdata' -sql show users -sql alter user u1 sysinfo 1 -sql alter user u1 enable 1 -sql alter user u1 pass 'taosdata' -sql drop user u1 -sql_error alter user u2 sysinfo 0 - -print =============== step3: create drop dnode -sql create dnode $hostname port 7200 -sql drop dnode 2 -sql alter dnode 1 'debugflag 131' - -print =============== create database, stable, table -sql create database db vgroups 3 -sql use db -sql create table stb (ts timestamp, c int) tags (t int) -sql create table t0 using stb tags (0) -sql create table tba (ts timestamp, c1 binary(10), c2 nchar(10)); - -print =============== run show xxxx -sql show dnodes -if $rows != 1 then - return -1 -endi - -sql show mnodes -if $rows != 1 then - return -1 -endi - +print =============== step2: create db +sql create database d1 vgroups 3 buffer 3 sql show databases -if $rows != 3 then - return -1 -endi - +sql use d1 +sql show vgroups + +print =============== step3: create show stable, include all type +sql create table if not exists stb (ts timestamp, c1 bool, c2 tinyint, c3 smallint, c4 int, c5 bigint, c6 float, c7 double, c8 binary(16), c9 nchar(16), c10 timestamp, c11 tinyint unsigned, c12 smallint unsigned, c13 int unsigned, c14 bigint unsigned) tags (t1 bool, t2 tinyint, t3 smallint, t4 int, t5 bigint, t6 float, t7 double, t8 binary(16), t9 nchar(16), t10 timestamp, t11 tinyint unsigned, t12 smallint unsigned, t13 int unsigned, t14 bigint unsigned) +sql create stable if not exists stb_1 (ts timestamp, c1 int) tags (j int) +sql create table stb_2 (ts timestamp, c1 int) tags (t1 int) +sql create stable stb_3 (ts timestamp, c1 int) tags (t1 int) sql show stables -if $rows != 1 then +if $rows != 4 then return -1 endi +print =============== step4: ccreate child table +sql create table c1 using stb tags(true, -1, -2, -3, -4, -6.0, -7.0, 'child tbl 1', 'child tbl 1', '2022-02-25 18:00:00.000', 10, 20, 30, 40) +sql create table c2 using stb tags(false, -1, -2, -3, -4, -6.0, -7.0, 'child tbl 2', 'child tbl 2', '2022-02-25 18:00:00.000', 10, 20, 30, 40) sql show tables if $rows != 2 then return -1 endi -sql show users -if $rows != 1 then - return -1 -endi - -print =============== run select * from information_schema.xxxx -sql select * from information_schema.`dnodes` -if $rows != 1 then - return -1 -endi - -sql select * from information_schema.`mnodes` -if $rows != 1 then - return -1 -endi - -sql select * from information_schema.user_databases -if $rows != 3 then - return -1 -endi - -sql select * from information_schema.user_stables -if $rows != 1 then - return -1 -endi - -sql select * from information_schema.user_tables -if $rows != 30 then - return -1 -endi - -sql select * from information_schema.user_users -if $rows != 1 then - return -1 -endi - -sql select * from information_schema.`vgroups` -if $rows != 3 then - return -1 -endi - -sql show variables; -if $rows != 4 then - return -1 -endi - -sql show dnode 1 variables; -if $rows <= 0 then - return -1 -endi - -sql show local variables; -if $rows <= 0 then - return -1 -endi - -print =============== stop +print =============== step5: insert data +sql insert into c1 values(now-1s, true, -1, -2, -3, -4, -6.0, -7.0, 'child tbl 1', 'child tbl 1', '2022-02-25 18:00:00.000', 10, 20, 30, 40) +sql insert into c1 values(now+0s, true, -1, -2, -3, -4, -6.0, -7.0, 'child tbl 1', 'child tbl 1', '2022-02-25 18:00:00.000', 10, 20, 30, 40) (now+1s, true, -1, -2, -3, -4, -6.0, -7.0, 'child tbl 1', 'child tbl 1', '2022-02-25 18:00:00.000', 10, 20, 30, 40) (now+2s, true, -1, -2, -3, -4, -6.0, -7.0, 'child tbl 1', 'child tbl 1', '2022-02-25 18:00:00.000', 10, 20, 30, 40) +sql insert into c2 values(now-1s, true, -1, -2, -3, -4, -6.0, -7.0, 'child tbl 1', 'child tbl 1', '2022-02-25 18:00:00.000', 10, 20, 30, 40) +sql insert into c2 values(now+0s, true, -1, -2, -3, -4, -6.0, -7.0, 'child tbl 1', 'child tbl 1', '2022-02-25 18:00:00.000', 10, 20, 30, 40) (now+1s, true, -1, -2, -3, -4, -6.0, -7.0, 'child tbl 1', 'child tbl 1', '2022-02-25 18:00:00.000', 10, 20, 30, 40) (now+2s, true, -1, -2, -3, -4, -6.0, -7.0, 'child tbl 1', 'child tbl 1', '2022-02-25 18:00:00.000', 10, 20, 30, 40) + +print =============== step6: alter insert +sql insert into c3 using stb tags(true, -1, -2, -3, -4, -6.0, -7.0, 'child tbl 1', 'child tbl 1', '2022-02-25 18:00:00.000', 10, 20, 30, 40) values(now-1s, true, -1, -2, -3, -4, -6.0, -7.0, 'child tbl 1', 'child tbl 1', '2022-02-25 18:00:00.000', 10, 20, 30, 40) +sql insert into c3 using stb tags(true, -1, -2, -3, -4, -6.0, -7.0, 'child tbl 1', 'child tbl 1', '2022-02-25 18:00:00.000', 10, 20, 30, 40) values(now+0s, true, -1, -2, -3, -4, -6.0, -7.0, 'child tbl 1', 'child tbl 1', '2022-02-25 18:00:00.000', 10, 20, 30, 40) + +print =============== stepa: query data +sql select * from c1 +sql select * from stb +sql select * from stb_1 +sql select ts, c1, c2, c3 from c1 +sql select ts, c1, c2, c3 from stb +sql select ts, c1 from stb_2 +sql select ts, c1, t1 from c1 +sql select ts, c1, t1 from stb +sql select ts, c1, t1 from stb_2 + +print =============== stepb: count +#sql select count(*) from c1; +#sql select count(*) from stb; +#sql select count(ts), count(c1), count(c2), count(c3) from c1 +#sql select count(ts), count(c1), count(c2), count(c3) from stb + +print =============== stepc: func +#sql select first(ts), first(c1), first(c2), first(c3) from c1 +#sql select min(c1), min(c2), min(c3) from c1 +#sql select max(c1), max(c2), max(c3) from c1 +#sql select sum(c1), sum(c2), sum(c3) from c1 + +_OVER: system sh/exec.sh -n dnode1 -s stop -x SIGINT - print =============== check $null= -- GitLab From 65e653835209dd7e0cbaeb8ada6590586d5e1c57 Mon Sep 17 00:00:00 2001 From: "slzhou@taodata.com" Date: Wed, 13 Jul 2022 13:07:10 +0800 Subject: [PATCH 029/153] fix: optimize the scan only when interval window --- source/libs/planner/src/planOptimizer.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/source/libs/planner/src/planOptimizer.c b/source/libs/planner/src/planOptimizer.c index 1548ab0ee3..45f947e128 100644 --- a/source/libs/planner/src/planOptimizer.c +++ b/source/libs/planner/src/planOptimizer.c @@ -107,12 +107,15 @@ static bool scanPathOptMayBeOptimized(SLogicNode* pNode) { QUERY_NODE_LOGIC_PLAN_PARTITION != nodeType(pNode->pParent))) { return false; } - if (QUERY_NODE_LOGIC_PLAN_WINDOW == nodeType(pNode->pParent) || + if ((QUERY_NODE_LOGIC_PLAN_WINDOW == nodeType(pNode->pParent) && WINDOW_TYPE_INTERVAL == ((SWindowLogicNode*)pNode->pParent)->winType) || (QUERY_NODE_LOGIC_PLAN_PARTITION == nodeType(pNode->pParent) && pNode->pParent->pParent && - QUERY_NODE_LOGIC_PLAN_WINDOW == nodeType(pNode->pParent->pParent))) { + QUERY_NODE_LOGIC_PLAN_WINDOW == nodeType(pNode->pParent->pParent) && WINDOW_TYPE_INTERVAL == ((SWindowLogicNode*)pNode->pParent)->winType)) { return true; } - return !scanPathOptHaveNormalCol(((SAggLogicNode*)pNode->pParent)->pGroupKeys); + if (QUERY_NODE_LOGIC_PLAN_AGG == nodeType(pNode->pParent)) { + return !scanPathOptHaveNormalCol(((SAggLogicNode*)pNode->pParent)->pGroupKeys); + } + return false; } static SNodeList* scanPathOptGetAllFuncs(SLogicNode* pNode) { -- GitLab From 037ea1519c3e1fe14b32ab9ba55cd760a70ba631 Mon Sep 17 00:00:00 2001 From: wangmm0220 Date: Wed, 13 Jul 2022 13:42:55 +0800 Subject: [PATCH 030/153] fix:core dump if consumer multi vgroup message with sequence:create/alter/delete/create or create/delete/create --- examples/c/tmq.c | 17 +++++++++++++++-- source/client/src/tmq.c | 16 ++++++---------- source/dnode/mnode/impl/src/mndStb.c | 8 ++------ source/dnode/vnode/src/meta/metaTable.c | 5 +++++ 4 files changed, 28 insertions(+), 18 deletions(-) diff --git a/examples/c/tmq.c b/examples/c/tmq.c index c114237353..24c415b2fc 100644 --- a/examples/c/tmq.c +++ b/examples/c/tmq.c @@ -96,8 +96,7 @@ int32_t init_env() { } taos_free_result(pRes); - pRes = - taos_query(pConn, "create stable if not exists st1 (ts timestamp, c1 int, c2 float, c3 binary(16)) tags(t1 int, t3 nchar(8), t4 bool)"); + pRes = taos_query(pConn, "create stable if not exists st1 (ts timestamp, c1 int, c2 float, c3 binary(16)) tags(t1 int, t3 nchar(8), t4 bool)"); if (taos_errno(pRes) != 0) { printf("failed to create super table st1, reason:%s\n", taos_errstr(pRes)); return -1; @@ -265,6 +264,20 @@ int32_t init_env() { } taos_free_result(pRes); + pRes = taos_query(pConn, "create stable if not exists st1 (ts timestamp, c1 int, c2 float, c3 binary(16)) tags(t1 int, t3 nchar(8), t4 bool)"); + if (taos_errno(pRes) != 0) { + printf("failed to create super table st1, reason:%s\n", taos_errstr(pRes)); + return -1; + } + taos_free_result(pRes); + + pRes = taos_query(pConn, "drop table st1"); + if (taos_errno(pRes) != 0) { + printf("failed to drop super table st1, reason:%s\n", taos_errstr(pRes)); + return -1; + } + taos_free_result(pRes); + return 0; } diff --git a/source/client/src/tmq.c b/source/client/src/tmq.c index 9d4eeb3233..ed9efdf3da 100644 --- a/source/client/src/tmq.c +++ b/source/client/src/tmq.c @@ -2397,7 +2397,7 @@ void tmq_free_json_meta(char* jsonMeta){ taosMemoryFreeClear(jsonMeta); } -static int32_t taosCreateStb(TAOS *taos, void *meta, int32_t metaLen, bool isCreate){ +static int32_t taosCreateStb(TAOS *taos, void *meta, int32_t metaLen){ SVCreateStbReq req = {0}; SDecoder coder; SMCreateStbReq pReq = {0}; @@ -2436,13 +2436,9 @@ static int32_t taosCreateStb(TAOS *taos, void *meta, int32_t metaLen, bool isCre strcpy(field.name, pSchema->name); taosArrayPush(pReq.pTags, &field); } - if(isCreate){ - pReq.colVer = 1; - pReq.tagVer = 1; - }else{ - pReq.colVer = req.schemaRow.version; - pReq.tagVer = req.schemaTag.version; - } + + pReq.colVer = req.schemaRow.version; + pReq.tagVer = req.schemaTag.version; pReq.numOfColumns = req.schemaRow.nCols; pReq.numOfTags = req.schemaTag.nCols; pReq.commentLen = -1; @@ -2876,9 +2872,9 @@ int32_t taos_write_raw_meta(TAOS *taos, tmq_raw_data *raw_meta){ } if(raw_meta->raw_meta_type == TDMT_VND_CREATE_STB) { - return taosCreateStb(taos, raw_meta->raw_meta, raw_meta->raw_meta_len, true); + return taosCreateStb(taos, raw_meta->raw_meta, raw_meta->raw_meta_len); }else if(raw_meta->raw_meta_type == TDMT_VND_ALTER_STB){ - return taosCreateStb(taos, raw_meta->raw_meta, raw_meta->raw_meta_len, false); + return taosCreateStb(taos, raw_meta->raw_meta, raw_meta->raw_meta_len); }else if(raw_meta->raw_meta_type == TDMT_VND_DROP_STB){ return taosDropStb(taos, raw_meta->raw_meta, raw_meta->raw_meta_len); }else if(raw_meta->raw_meta_type == TDMT_VND_CREATE_TABLE){ diff --git a/source/dnode/mnode/impl/src/mndStb.c b/source/dnode/mnode/impl/src/mndStb.c index e170a2916f..51f550ad92 100644 --- a/source/dnode/mnode/impl/src/mndStb.c +++ b/source/dnode/mnode/impl/src/mndStb.c @@ -710,8 +710,8 @@ int32_t mndBuildStbFromReq(SMnode *pMnode, SStbObj *pDst, SMCreateStbReq *pCreat pDst->updateTime = pDst->createdTime; pDst->uid = (pCreate->source == TD_REQ_FROM_TAOX) ? pCreate->suid : mndGenerateUid(pCreate->name, TSDB_TABLE_FNAME_LEN); pDst->dbUid = pDb->uid; - pDst->tagVer = (pCreate->source == TD_REQ_FROM_TAOX) ? pCreate->tagVer : 1; - pDst->colVer = (pCreate->source == TD_REQ_FROM_TAOX) ? pCreate->colVer : 1; + pDst->tagVer = 1; + pDst->colVer = 1; pDst->smaVer = 1; pDst->nextColId = 1; pDst->maxdelay[0] = pCreate->delay1; @@ -985,10 +985,6 @@ static int32_t mndProcessCreateStbReq(SRpcMsg *pReq) { mInfo("stb:%s, alter table does not need to be done, because table is deleted", createReq.name); code = 0; goto _OVER; - } else if (createReq.source == TD_REQ_FROM_TAOX && (createReq.tagVer == 1 || createReq.colVer == 1)){ //metaSaveToSkmDb does not delete pMeta->pSkmDb, if receivet tmq message is: create stable1 then delete stable1 then create stable1 - mInfo("stb:%s, create table from taosx", createReq.name); - createReq.tagVer++; - createReq.colVer++; } pDb = mndAcquireDbByStb(pMnode, createReq.name); diff --git a/source/dnode/vnode/src/meta/metaTable.c b/source/dnode/vnode/src/meta/metaTable.c index daf7ccb26a..29c10c40c2 100644 --- a/source/dnode/vnode/src/meta/metaTable.c +++ b/source/dnode/vnode/src/meta/metaTable.c @@ -1125,6 +1125,11 @@ static int metaSaveToSkmDb(SMeta *pMeta, const SMetaEntry *pME) { skmDbKey.uid = pME->uid; skmDbKey.sver = pSW->version; + // if receive tmq meta message is: create stable1 then delete stable1 then create stable1 with multi vgroups + if (tdbTbGet(pMeta->pSkmDb, &skmDbKey, sizeof(skmDbKey), NULL, NULL) == 0) { + return rcode; + } + // encode schema int32_t ret = 0; tEncodeSize(tEncodeSSchemaWrapper, pSW, vLen, ret); -- GitLab From 480de34a0ed41f002fa7efee95c94ab6a6f4c055 Mon Sep 17 00:00:00 2001 From: Shengliang Guan Date: Wed, 13 Jul 2022 14:13:12 +0800 Subject: [PATCH 031/153] enh: support alter debugflag in dnode --- source/common/src/tglobal.c | 34 +++++++++++++++ source/dnode/mnode/impl/src/mndDnode.c | 58 ++++++++++++++++++++------ source/libs/sync/src/syncMain.c | 4 +- 3 files changed, 81 insertions(+), 15 deletions(-) diff --git a/source/common/src/tglobal.c b/source/common/src/tglobal.c index 24bf4e5c2d..974146302c 100644 --- a/source/common/src/tglobal.c +++ b/source/common/src/tglobal.c @@ -1117,10 +1117,44 @@ void taosCfgDynamicOptions(const char *option, const char *value) { if (strncasecmp(option, "debugFlag", 9) == 0) { int32_t flag = atoi(value); taosSetAllDebugFlag(flag); + return; } if (strcasecmp(option, "resetlog") == 0) { taosResetLog(); cfgDumpCfg(tsCfg, 0, false); + return; } + + if (strcasecmp(option, "monitor") == 0) { + int32_t monitor = atoi(value); + uInfo("monitor set from %d to %d", tsEnableMonitor, monitor); + tsEnableMonitor = monitor; + return; + } + + const char *options[] = { + "dDebugFlag", "vDebugFlag", "mDebugFlag", "wDebugFlag", "sDebugFlag", "tsdbDebugFlag", + "tqDebugFlag", "fsDebugFlag", "udfDebugFlag", "smaDebugFlag", "idxDebugFlag", "tmrDebugFlag", + "uDebugFlag", "smaDebugFlag", "rpcDebugFlag", "qDebugFlag", + }; + int32_t *optionVars[] = { + &dDebugFlag, &vDebugFlag, &mDebugFlag, &wDebugFlag, &sDebugFlag, &tsdbDebugFlag, + &tqDebugFlag, &fsDebugFlag, &udfDebugFlag, &smaDebugFlag, &idxDebugFlag, &tmrDebugFlag, + &uDebugFlag, &smaDebugFlag, &rpcDebugFlag, &qDebugFlag, + }; + + int32_t optionSize = tListLen(options); + for (int32_t d = 0; d < optionSize; ++d) { + const char *optName = options[d]; + int32_t optLen = strlen(optName); + if (strncasecmp(option, optName, optLen) != 0) continue; + + int32_t flag = atoi(value); + uInfo("%s set from %d to %d", optName, *optionVars[d], flag); + *optionVars[d] = flag; + return; + } + + uError("failed to cfg dynamic option:%s value:%s", option, value); } diff --git a/source/dnode/mnode/impl/src/mndDnode.c b/source/dnode/mnode/impl/src/mndDnode.c index 9ce108b789..3e5d378bb1 100644 --- a/source/dnode/mnode/impl/src/mndDnode.c +++ b/source/dnode/mnode/impl/src/mndDnode.c @@ -781,7 +781,13 @@ _OVER: } static int32_t mndProcessConfigDnodeReq(SRpcMsg *pReq) { - SMnode *pMnode = pReq->info.node; + SMnode *pMnode = pReq->info.node; + const char *options[] = { + "debugFlag", "dDebugFlag", "vDebugFlag", "mDebugFlag", "wDebugFlag", "sDebugFlag", + "tsdbDebugFlag", "tqDebugFlag", "fsDebugFlag", "udfDebugFlag", "smaDebugFlag", "idxDebugFlag", + "tmrDebugFlag", "uDebugFlag", "smaDebugFlag", "rpcDebugFlag", "qDebugFlag", + }; + int32_t optionSize = tListLen(options); SMCfgDnodeReq cfgReq = {0}; if (tDeserializeSMCfgDnodeReq(pReq->pCont, pReq->contLen, &cfgReq) != 0) { @@ -802,27 +808,52 @@ static int32_t mndProcessConfigDnodeReq(SRpcMsg *pReq) { SEpSet epSet = mndGetDnodeEpset(pDnode); mndReleaseDnode(pMnode, pDnode); + SDCfgDnodeReq dcfgReq = {0}; - if (strncasecmp(cfgReq.config, "debugFlag", 9) == 0) { + if (strcasecmp(cfgReq.config, "resetlog") == 0) { + strcpy(dcfgReq.config, "resetlog"); + } else if (strncasecmp(cfgReq.config, "monitor", 7) == 0) { const char *value = cfgReq.value; int32_t flag = atoi(value); if (flag <= 0) { - flag = atoi(cfgReq.config + 10); + flag = atoi(cfgReq.config + 8); } - if (flag <= 0 || flag > 255) { - mError("dnode:%d, failed to config debugFlag since value:%d", cfgReq.dnodeId, flag); + if (flag < 0 || flag > 2) { + mError("dnode:%d, failed to config monitor since value:%d", cfgReq.dnodeId, flag); terrno = TSDB_CODE_INVALID_CFG; return -1; } - strcpy(dcfgReq.config, "debugFlag"); + strcpy(dcfgReq.config, "monitor"); snprintf(dcfgReq.value, TSDB_DNODE_VALUE_LEN, "%d", flag); - } else if (strcasecmp(cfgReq.config, "resetlog") == 0) { - strcpy(dcfgReq.config, "resetlog"); } else { - terrno = TSDB_CODE_INVALID_CFG; - mError("dnode:%d, failed to config since %s", cfgReq.dnodeId, terrstr()); - return -1; + bool findOpt = false; + for (int32_t d = 0; d < optionSize; ++d) { + const char *optName = options[d]; + int32_t optLen = strlen(optName); + if (strncasecmp(cfgReq.config, optName, optLen) != 0) continue; + + const char *value = cfgReq.value; + int32_t flag = atoi(value); + if (flag <= 0) { + flag = atoi(cfgReq.config + optLen + 1); + } + if (flag <= 0 || flag > 255) { + mError("dnode:%d, failed to config %s since value:%d", cfgReq.dnodeId, optName, flag); + terrno = TSDB_CODE_INVALID_CFG; + return -1; + } + + tstrncpy(dcfgReq.config, optName, optLen + 1); + snprintf(dcfgReq.value, TSDB_DNODE_VALUE_LEN, "%d", flag); + findOpt = true; + } + + if (!findOpt) { + terrno = TSDB_CODE_INVALID_CFG; + mError("dnode:%d, failed to config since %s", cfgReq.dnodeId, terrstr()); + return -1; + } } int32_t bufLen = tSerializeSDCfgDnodeReq(NULL, 0, &dcfgReq); @@ -831,13 +862,14 @@ static int32_t mndProcessConfigDnodeReq(SRpcMsg *pReq) { if (pBuf == NULL) return -1; tSerializeSDCfgDnodeReq(pBuf, bufLen, &dcfgReq); - mDebug("dnode:%d, send config req to dnode, app:%p", cfgReq.dnodeId, pReq->info.ahandle); + mInfo("dnode:%d, send config req to dnode, app:%p config:%s value:%s", cfgReq.dnodeId, pReq->info.ahandle, + dcfgReq.config, dcfgReq.value); SRpcMsg rpcMsg = {.msgType = TDMT_DND_CONFIG_DNODE, .pCont = pBuf, .contLen = bufLen}; return tmsgSendReq(&epSet, &rpcMsg); } static int32_t mndProcessConfigDnodeRsp(SRpcMsg *pRsp) { - mDebug("config rsp from dnode, app:%p", pRsp->info.ahandle); + mInfo("config rsp from dnode, app:%p", pRsp->info.ahandle); return 0; } diff --git a/source/libs/sync/src/syncMain.c b/source/libs/sync/src/syncMain.c index abc0f53611..bab64b6f11 100644 --- a/source/libs/sync/src/syncMain.c +++ b/source/libs/sync/src/syncMain.c @@ -293,7 +293,7 @@ int32_t syncLeaderTransferTo(int64_t rid, SNodeInfo newLeader) { int32_t syncNodeLeaderTransfer(SSyncNode* pSyncNode) { if (pSyncNode->peersNum == 0) { - sError("only one replica, cannot leader transfer"); + sDebug("only one replica, cannot leader transfer"); terrno = TSDB_CODE_SYN_ONE_REPLICA; return -1; } @@ -307,7 +307,7 @@ int32_t syncNodeLeaderTransferTo(SSyncNode* pSyncNode, SNodeInfo newLeader) { int32_t ret = 0; if (pSyncNode->replicaNum == 1) { - sError("only one replica, cannot leader transfer"); + sDebug("only one replica, cannot leader transfer"); terrno = TSDB_CODE_SYN_ONE_REPLICA; return -1; } -- GitLab From ba90514d9020a186668dbaf3746dd7ca75b26e64 Mon Sep 17 00:00:00 2001 From: plum-lihui Date: Wed, 13 Jul 2022 14:17:07 +0800 Subject: [PATCH 032/153] test: add test casse for tmq --- tests/system-test/7-tmq/tmqCommon.py | 4 +- tests/system-test/7-tmq/tmqUpdate-1ctb.py | 14 ++-- tests/system-test/7-tmq/tmqUpdate-multiCtb.py | 77 +++++++++++-------- tests/system-test/fulltest.sh | 4 +- 4 files changed, 59 insertions(+), 40 deletions(-) diff --git a/tests/system-test/7-tmq/tmqCommon.py b/tests/system-test/7-tmq/tmqCommon.py index 2030563a9a..98c9e37132 100644 --- a/tests/system-test/7-tmq/tmqCommon.py +++ b/tests/system-test/7-tmq/tmqCommon.py @@ -371,7 +371,7 @@ class TMQCom: elif (i % 3 == 0): tagBinaryValue = 'changsha' - sql += " %s.%s_%d using %s.%s tags (%d, %d, %d, '%s', '%s') values "%(dbName,ctbPrefix,i+ctbStartIdx,dbName,stbName,i+ctbStartIdx,i+ctbStartIdx,i+ctbStartIdx,tagBinaryValue,tagBinaryValue) + sql += " %s.%s%d using %s.%s tags (%d, %d, %d, '%s', '%s') values "%(dbName,ctbPrefix,i+ctbStartIdx,dbName,stbName,i+ctbStartIdx,i+ctbStartIdx,i+ctbStartIdx,tagBinaryValue,tagBinaryValue) for j in range(rowsPerTbl): sql += "(%d, %d, %d, %d, 'binary_%d', 'nchar_%d', now) "%(startTs+j, j,j, j,i+ctbStartIdx,rowsBatched) rowsBatched += 1 @@ -379,7 +379,7 @@ class TMQCom: tsql.execute(sql) rowsBatched = 0 if j < rowsPerTbl - 1: - sql = "insert into %s.%s_%d using %s.%s tags (%d, %d, %d, '%s', '%s') values " %(dbName,ctbPrefix,i+ctbStartIdx,dbName,stbName,i+ctbStartIdx,i+ctbStartIdx,i+ctbStartIdx,tagBinaryValue,tagBinaryValue) + sql = "insert into %s.%s%d using %s.%s tags (%d, %d, %d, '%s', '%s') values " %(dbName,ctbPrefix,i+ctbStartIdx,dbName,stbName,i+ctbStartIdx,i+ctbStartIdx,i+ctbStartIdx,tagBinaryValue,tagBinaryValue) else: sql = "insert into " #end sql diff --git a/tests/system-test/7-tmq/tmqUpdate-1ctb.py b/tests/system-test/7-tmq/tmqUpdate-1ctb.py index 9e2d06d1bd..3cb364f91d 100644 --- a/tests/system-test/7-tmq/tmqUpdate-1ctb.py +++ b/tests/system-test/7-tmq/tmqUpdate-1ctb.py @@ -17,7 +17,7 @@ from tmqCommon import * class TDTestCase: def __init__(self): self.snapshot = 0 - self.vgroups = 2 + self.vgroups = 4 self.ctbNum = 1 self.rowsPerTbl = 100000 @@ -235,18 +235,18 @@ class TDTestCase: def run(self): tdSql.prepare() - self.prepareTestEnv() - tdLog.printNoPrefix("=============================================") - tdLog.printNoPrefix("======== snapshot is 0: only consume from wal") - self.tmqCase1() - self.tmqCase2() + # self.prepareTestEnv() + # tdLog.printNoPrefix("=============================================") + # tdLog.printNoPrefix("======== snapshot is 0: only consume from wal") + # self.tmqCase1() + # self.tmqCase2() self.prepareTestEnv() tdLog.printNoPrefix("====================================================================") tdLog.printNoPrefix("======== snapshot is 1: firstly consume from tsbs, and then from wal") self.snapshot = 1 self.tmqCase1() - self.tmqCase2() + # self.tmqCase2() def stop(self): diff --git a/tests/system-test/7-tmq/tmqUpdate-multiCtb.py b/tests/system-test/7-tmq/tmqUpdate-multiCtb.py index 9e2d06d1bd..491feb68bd 100644 --- a/tests/system-test/7-tmq/tmqUpdate-multiCtb.py +++ b/tests/system-test/7-tmq/tmqUpdate-multiCtb.py @@ -17,9 +17,10 @@ from tmqCommon import * class TDTestCase: def __init__(self): self.snapshot = 0 - self.vgroups = 2 - self.ctbNum = 1 - self.rowsPerTbl = 100000 + self.vgroups = 4 + self.ctbNum = 100 + self.rowsPerTbl = 1000 + self.autoCtbPrefix = 'aCtb' def init(self, conn, logSql): tdLog.debug(f"start to excute {__file__}") @@ -38,9 +39,9 @@ class TDTestCase: 'tagSchema': [{'type': 'INT', 'count':1},{'type': 'BIGINT', 'count':1},{'type': 'DOUBLE', 'count':1},{'type': 'BINARY', 'len':32, 'count':1},{'type': 'NCHAR', 'len':32, 'count':1}], 'ctbPrefix': 'ctb', 'ctbStartIdx': 0, - 'ctbNum': 1, - 'rowsPerTbl': 100000, - 'batchNum': 1200, + 'ctbNum': 1000, + 'rowsPerTbl': 1000, + 'batchNum': 10000, 'startTs': 1640966400000, # 2022-01-01 00:00:00.000 'pollDelay': 3, 'showMsg': 1, @@ -62,9 +63,9 @@ class TDTestCase: tmqCom.insert_data_interlaceByMultiTbl(tsql=tdSql,dbName=paraDict["dbName"],ctbPrefix=paraDict["ctbPrefix"], ctbNum=paraDict["ctbNum"],rowsPerTbl=paraDict["rowsPerTbl"],batchNum=paraDict["batchNum"], startTs=paraDict["startTs"],ctbStartIdx=paraDict['ctbStartIdx']) - # tmqCom.insert_data_with_autoCreateTbl(tsql=tdSql,dbName=paraDict["dbName"],stbName=paraDict["stbName"],ctbPrefix="ctbx", - # ctbNum=paraDict["ctbNum"],rowsPerTbl=paraDict["rowsPerTbl"],batchNum=paraDict["batchNum"], - # startTs=paraDict["startTs"],ctbStartIdx=paraDict['ctbStartIdx']) + tmqCom.insert_data_with_autoCreateTbl(tsql=tdSql,dbName=paraDict["dbName"],stbName=paraDict["stbName"],ctbPrefix=self.autoCtbPrefix, + ctbNum=paraDict["ctbNum"],rowsPerTbl=paraDict["rowsPerTbl"],batchNum=paraDict["batchNum"], + startTs=paraDict["startTs"],ctbStartIdx=paraDict['ctbStartIdx']) # tdLog.info("restart taosd to ensure that the data falls into the disk") # tdSql.query("flush database %s"%(paraDict['dbName'])) @@ -84,9 +85,9 @@ class TDTestCase: 'tagSchema': [{'type': 'INT', 'count':1},{'type': 'BIGINT', 'count':1},{'type': 'DOUBLE', 'count':1},{'type': 'BINARY', 'len':32, 'count':1},{'type': 'NCHAR', 'len':32, 'count':1}], 'ctbPrefix': 'ctb', 'ctbStartIdx': 0, - 'ctbNum': 1, - 'rowsPerTbl': 100000, - 'batchNum': 3000, + 'ctbNum': 1000, + 'rowsPerTbl': 1000, + 'batchNum': 10000, 'startTs': 1640966400000, # 2022-01-01 00:00:00.000 'pollDelay': 5, 'showMsg': 1, @@ -98,10 +99,11 @@ class TDTestCase: paraDict['rowsPerTbl'] = self.rowsPerTbl # update to half tables + paraDict['ctbNum'] = int(self.ctbNum/2) paraDict['rowsPerTbl'] = int(self.rowsPerTbl / 2) - # tmqCom.insert_data_with_autoCreateTbl(tsql=tdSql,dbName=paraDict["dbName"],stbName=paraDict["stbName"],ctbPrefix="ctbx", - # ctbNum=paraDict["ctbNum"],rowsPerTbl=paraDict["rowsPerTbl"],batchNum=paraDict["batchNum"], - # startTs=paraDict["startTs"],ctbStartIdx=paraDict['ctbStartIdx']) + tmqCom.insert_data_with_autoCreateTbl(tsql=tdSql,dbName=paraDict["dbName"],stbName=paraDict["stbName"],ctbPrefix=self.autoCtbPrefix, + ctbNum=paraDict["ctbNum"],rowsPerTbl=paraDict["rowsPerTbl"],batchNum=paraDict["batchNum"], + startTs=paraDict["startTs"],ctbStartIdx=paraDict['ctbStartIdx']) tmqCom.insert_data_interlaceByMultiTbl(tsql=tdSql,dbName=paraDict["dbName"],ctbPrefix=paraDict["ctbPrefix"], ctbNum=paraDict["ctbNum"],rowsPerTbl=paraDict["rowsPerTbl"],batchNum=paraDict["batchNum"], startTs=paraDict["startTs"],ctbStartIdx=paraDict['ctbStartIdx']) @@ -113,10 +115,14 @@ class TDTestCase: tdLog.info("create topic sql: %s"%sqlString) tdSql.execute(sqlString) - # paraDict['ctbNum'] = self.ctbNum + paraDict['ctbNum'] = self.ctbNum paraDict['rowsPerTbl'] = self.rowsPerTbl consumerId = 0 - expectrowcnt = int(paraDict["rowsPerTbl"] * paraDict["ctbNum"] * 3/2) + if self.snapshot == 0: + expectrowcnt = int(paraDict["rowsPerTbl"] * paraDict["ctbNum"] * (2 + 1/2*1/2*2)) + elif self.snapshot == 1: + expectrowcnt = int(paraDict["rowsPerTbl"] * paraDict["ctbNum"] * (2)) + topicList = topicFromStb1 ifcheckdata = 1 ifManualCommit = 1 @@ -129,7 +135,7 @@ class TDTestCase: tdLog.info("start consume processor") tmqCom.startTmqSimProcess(pollDelay=paraDict['pollDelay'],dbName=paraDict["dbName"],showMsg=paraDict['showMsg'], showRow=paraDict['showRow'],snapshot=paraDict['snapshot']) - tdLog.info("insert process end, and start to check consume result") + tdLog.info("start to check consume result") expectRows = 1 resultList = tmqCom.selectConsumeResult(expectRows) totalConsumeRows = 0 @@ -143,7 +149,7 @@ class TDTestCase: if totalConsumeRows != expectrowcnt: tdLog.exit("tmq consume rows error!") - tmqCom.checkFileContent(consumerId, queryString) + # tmqCom.checkFileContent(consumerId, queryString) tdSql.query("drop topic %s"%topicFromStb1) tdLog.printNoPrefix("======== test case 1 end ...... ") @@ -161,9 +167,9 @@ class TDTestCase: 'tagSchema': [{'type': 'INT', 'count':1},{'type': 'BIGINT', 'count':1},{'type': 'DOUBLE', 'count':1},{'type': 'BINARY', 'len':32, 'count':1},{'type': 'NCHAR', 'len':32, 'count':1}], 'ctbPrefix': 'ctb', 'ctbStartIdx': 0, - 'ctbNum': 1, - 'rowsPerTbl': 10000, - 'batchNum': 5000, + 'ctbNum': 1000, + 'rowsPerTbl': 1000, + 'batchNum': 10000, 'startTs': 1640966400000, # 2022-01-01 00:00:00.000 'pollDelay': 5, 'showMsg': 1, @@ -179,14 +185,20 @@ class TDTestCase: tdSql.query("flush database %s"%(paraDict['dbName'])) # update to half tables - paraDict['startTs'] = paraDict['startTs'] + int(self.rowsPerTbl / 2) + paraDict['ctbNum'] = int(self.ctbNum/2) paraDict['rowsPerTbl'] = int(self.rowsPerTbl / 2) - tmqCom.insert_data_with_autoCreateTbl(tsql=tdSql,dbName=paraDict["dbName"],stbName=paraDict["stbName"],ctbPrefix=paraDict["ctbPrefix"], + paraDict['startTs'] = paraDict['startTs'] + int(self.rowsPerTbl / 2) + tmqCom.insert_data_with_autoCreateTbl(tsql=tdSql,dbName=paraDict["dbName"],stbName=paraDict["stbName"],ctbPrefix=self.autoCtbPrefix, ctbNum=paraDict["ctbNum"],rowsPerTbl=paraDict["rowsPerTbl"],batchNum=paraDict["batchNum"], - startTs=paraDict["startTs"],ctbStartIdx=paraDict['ctbStartIdx']) - # tmqCom.insert_data_interlaceByMultiTbl(tsql=tdSql,dbName=paraDict["dbName"],ctbPrefix=paraDict["ctbPrefix"], - # ctbNum=paraDict["ctbNum"],rowsPerTbl=paraDict["rowsPerTbl"],batchNum=paraDict["batchNum"], - # startTs=paraDict["startTs"],ctbStartIdx=paraDict['ctbStartIdx']) + startTs=paraDict["startTs"],ctbStartIdx=paraDict['ctbStartIdx']+int(self.ctbNum/2)) + + tmqCom.insert_data_with_autoCreateTbl(tsql=tdSql,dbName=paraDict["dbName"],stbName=paraDict["stbName"],ctbPrefix="aCtby", + ctbNum=paraDict["ctbNum"],rowsPerTbl=paraDict["rowsPerTbl"],batchNum=paraDict["batchNum"], + startTs=paraDict["startTs"],ctbStartIdx=paraDict['ctbStartIdx']+int(self.ctbNum/2)) + + tmqCom.insert_data_interlaceByMultiTbl(tsql=tdSql,dbName=paraDict["dbName"],ctbPrefix=paraDict["ctbPrefix"], + ctbNum=paraDict["ctbNum"],rowsPerTbl=paraDict["rowsPerTbl"],batchNum=paraDict["batchNum"], + startTs=paraDict["startTs"],ctbStartIdx=paraDict['ctbStartIdx']+int(self.ctbNum/2)) tmqCom.initConsumerTable() tdLog.info("create topics from stb1") @@ -197,9 +209,14 @@ class TDTestCase: tdSql.execute(sqlString) # paraDict['ctbNum'] = self.ctbNum + paraDict['ctbNum'] = self.ctbNum paraDict['rowsPerTbl'] = self.rowsPerTbl consumerId = 1 - expectrowcnt = int(paraDict["rowsPerTbl"] * paraDict["ctbNum"] * 2) + if self.snapshot == 0: + expectrowcnt = int(paraDict["rowsPerTbl"] * paraDict["ctbNum"] * (2 + 1/2*1/2*2 + 1/2*1/2)) + elif self.snapshot == 1: + expectrowcnt = int(paraDict["rowsPerTbl"] * paraDict["ctbNum"] * (2 + 1/2*1/2)) + topicList = topicFromStb1 ifcheckdata = 1 ifManualCommit = 1 @@ -212,7 +229,7 @@ class TDTestCase: tdLog.info("start consume processor") tmqCom.startTmqSimProcess(pollDelay=paraDict['pollDelay'],dbName=paraDict["dbName"],showMsg=paraDict['showMsg'], showRow=paraDict['showRow'],snapshot=paraDict['snapshot']) - tdLog.info("insert process end, and start to check consume result") + tdLog.info("start to check consume result") expectRows = 1 resultList = tmqCom.selectConsumeResult(expectRows) totalConsumeRows = 0 diff --git a/tests/system-test/fulltest.sh b/tests/system-test/fulltest.sh index 269f83a139..5672571bb5 100755 --- a/tests/system-test/fulltest.sh +++ b/tests/system-test/fulltest.sh @@ -178,6 +178,8 @@ python3 ./test.py -f 7-tmq/tmqConsFromTsdb1-mutilVg-mutilCtb-funcNFilter.py python3 ./test.py -f 7-tmq/tmqConsFromTsdb1-mutilVg-mutilCtb.py python3 ./test.py -f 7-tmq/tmqAutoCreateTbl.py #python3 ./test.py -f 7-tmq/tmqDnodeRestart.py +#python3 ./test.py -f 7-tmq/tmqUpdate-1ctb.py +python3 ./test.py -f 7-tmq/tmqUpdate-multiCtb.py #------------querPolicy 2----------- @@ -353,4 +355,4 @@ python3 ./test.py -f 2-query/twa.py -Q 3 python3 ./test.py -f 2-query/irate.py -Q 3 python3 ./test.py -f 2-query/function_null.py -Q 3 python3 ./test.py -f 2-query/count_partition.py -Q 3 -python3 ./test.py -f 2-query/max_partition.py -Q 3 \ No newline at end of file +python3 ./test.py -f 2-query/max_partition.py -Q 3 -- GitLab From 8e7b494bee1230be0725d3034f89e039c22249f2 Mon Sep 17 00:00:00 2001 From: plum-lihui Date: Wed, 13 Jul 2022 14:18:10 +0800 Subject: [PATCH 033/153] test: add test case --- tests/system-test/fulltest.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/system-test/fulltest.sh b/tests/system-test/fulltest.sh index 5672571bb5..ec31235241 100755 --- a/tests/system-test/fulltest.sh +++ b/tests/system-test/fulltest.sh @@ -179,7 +179,7 @@ python3 ./test.py -f 7-tmq/tmqConsFromTsdb1-mutilVg-mutilCtb.py python3 ./test.py -f 7-tmq/tmqAutoCreateTbl.py #python3 ./test.py -f 7-tmq/tmqDnodeRestart.py #python3 ./test.py -f 7-tmq/tmqUpdate-1ctb.py -python3 ./test.py -f 7-tmq/tmqUpdate-multiCtb.py +#python3 ./test.py -f 7-tmq/tmqUpdate-multiCtb.py #------------querPolicy 2----------- -- GitLab From 339967a3579d6f2ac64a2145f3333d2c9bf96e67 Mon Sep 17 00:00:00 2001 From: plum-lihui Date: Wed, 13 Jul 2022 14:19:02 +0800 Subject: [PATCH 034/153] test: add test case into ci --- tests/system-test/fulltest.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/system-test/fulltest.sh b/tests/system-test/fulltest.sh index ec31235241..5672571bb5 100755 --- a/tests/system-test/fulltest.sh +++ b/tests/system-test/fulltest.sh @@ -179,7 +179,7 @@ python3 ./test.py -f 7-tmq/tmqConsFromTsdb1-mutilVg-mutilCtb.py python3 ./test.py -f 7-tmq/tmqAutoCreateTbl.py #python3 ./test.py -f 7-tmq/tmqDnodeRestart.py #python3 ./test.py -f 7-tmq/tmqUpdate-1ctb.py -#python3 ./test.py -f 7-tmq/tmqUpdate-multiCtb.py +python3 ./test.py -f 7-tmq/tmqUpdate-multiCtb.py #------------querPolicy 2----------- -- GitLab From 649cf7e55dbe7182e914d377c6889f3ef49e7e81 Mon Sep 17 00:00:00 2001 From: Haojun Liao Date: Wed, 13 Jul 2022 14:21:44 +0800 Subject: [PATCH 035/153] fix(query): support last_row(tags) for super table query. --- source/dnode/vnode/inc/vnode.h | 2 +- source/dnode/vnode/src/tsdb/tsdbCacheRead.c | 6 ++-- source/libs/executor/inc/executorimpl.h | 3 ++ source/libs/executor/src/cachescanoperator.c | 31 ++++++++++++++------ source/libs/executor/src/scanoperator.c | 4 --- source/libs/function/src/builtinsimpl.c | 13 ++++---- 6 files changed, 37 insertions(+), 22 deletions(-) diff --git a/source/dnode/vnode/inc/vnode.h b/source/dnode/vnode/inc/vnode.h index 9f32964fa9..f0a6b6505d 100644 --- a/source/dnode/vnode/inc/vnode.h +++ b/source/dnode/vnode/inc/vnode.h @@ -138,7 +138,7 @@ void *tsdbGetIdx(SMeta *pMeta); void *tsdbGetIvtIdx(SMeta *pMeta); int32_t tsdbLastRowReaderOpen(void *pVnode, int32_t type, SArray *pTableIdList, int32_t numOfCols, void **pReader); -int32_t tsdbRetrieveLastRow(void *pReader, SSDataBlock *pResBlock, const int32_t *slotIds); +int32_t tsdbRetrieveLastRow(void *pReader, SSDataBlock *pResBlock, const int32_t *slotIds, SArray* pTableUids); int32_t tsdbLastrowReaderClose(void *pReader); int32_t tsdbGetTableSchema(SVnode *pVnode, int64_t uid, STSchema **pSchema, int64_t *suid); diff --git a/source/dnode/vnode/src/tsdb/tsdbCacheRead.c b/source/dnode/vnode/src/tsdb/tsdbCacheRead.c index 5c09c7663f..5855468f31 100644 --- a/source/dnode/vnode/src/tsdb/tsdbCacheRead.c +++ b/source/dnode/vnode/src/tsdb/tsdbCacheRead.c @@ -104,7 +104,7 @@ int32_t tsdbLastrowReaderClose(void* pReader) { return TSDB_CODE_SUCCESS; } -int32_t tsdbRetrieveLastRow(void* pReader, SSDataBlock* pResBlock, const int32_t* slotIds) { +int32_t tsdbRetrieveLastRow(void* pReader, SSDataBlock* pResBlock, const int32_t* slotIds, SArray* pTableUidList) { if (pReader == NULL || pResBlock == NULL) { return TSDB_CODE_INVALID_PARA; } @@ -141,14 +141,15 @@ int32_t tsdbRetrieveLastRow(void* pReader, SSDataBlock* pResBlock, const int32_t // appended or not. if (internalResult) { pResBlock->info.rows -= 1; + taosArrayClear(pTableUidList); } saveOneRow(pRow, pResBlock, pr, slotIds); + taosArrayPush(pTableUidList, &pKeyInfo->uid); internalResult = true; lastKey = pRow->ts; } - // taosMemoryFree(pRow); tsdbCacheRelease(lruCache, h); } } else if (pr->type == LASTROW_RETRIEVE_TYPE_ALL) { @@ -171,6 +172,7 @@ int32_t tsdbRetrieveLastRow(void* pReader, SSDataBlock* pResBlock, const int32_t // tsdbCacheLastArray2Row(pLast, &pRow, pr->pSchema); saveOneRow(pRow, pResBlock, pr, slotIds); + taosArrayPush(pTableUidList, &pKeyInfo->uid); // taosMemoryFree(pRow); tsdbCacheRelease(lruCache, h); diff --git a/source/libs/executor/inc/executorimpl.h b/source/libs/executor/inc/executorimpl.h index aab2f51421..3da8e298a6 100644 --- a/source/libs/executor/inc/executorimpl.h +++ b/source/libs/executor/inc/executorimpl.h @@ -319,6 +319,7 @@ typedef struct SLastrowScanInfo { void *pLastrowReader; SArray *pColMatchInfo; int32_t *pSlotIds; + SExprSupp pseudoExprSup; } SLastrowScanInfo; typedef enum EStreamScanMode { @@ -787,6 +788,8 @@ int32_t getBufferPgSize(int32_t rowSize, uint32_t* defaultPgsz, uint32_t* defaul void doSetOperatorCompleted(SOperatorInfo* pOperator); void doFilter(const SNode* pFilterNode, SSDataBlock* pBlock); +int32_t addTagPseudoColumnData(SReadHandle* pHandle, SExprInfo* pPseudoExpr, int32_t numOfPseudoExpr, + SSDataBlock* pBlock, const char* idStr); void cleanupAggSup(SAggSupporter* pAggSup); void destroyBasicOperatorInfo(void* param, int32_t numOfOutput); diff --git a/source/libs/executor/src/cachescanoperator.c b/source/libs/executor/src/cachescanoperator.c index 7b1351a024..0f6817cd6b 100644 --- a/source/libs/executor/src/cachescanoperator.c +++ b/source/libs/executor/src/cachescanoperator.c @@ -45,20 +45,20 @@ SOperatorInfo* createLastrowScanOperator(SLastRowScanPhysiNode* pScanNode, SRead int32_t numOfCols = 0; pInfo->pColMatchInfo = extractColMatchInfo(pScanNode->pScanCols, pScanNode->node.pOutputDataBlockDesc, &numOfCols, COL_MATCH_FROM_COL_ID); - int32_t* pCols = taosMemoryMalloc(numOfCols * sizeof(int32_t)); - for (int32_t i = 0; i < taosArrayGetSize(pInfo->pColMatchInfo); ++i) { - SColMatchInfo* pColMatch = taosArrayGet(pInfo->pColMatchInfo, i); - pCols[i] = pColMatch->colId; - } - int32_t code = extractTargetSlotId(pInfo->pColMatchInfo, pTaskInfo, &pInfo->pSlotIds); if (code != TSDB_CODE_SUCCESS) { goto _error; } - tsdbLastRowReaderOpen(readHandle->vnode, LASTROW_RETRIEVE_TYPE_ALL, pTableList, taosArrayGetSize(pInfo->pColMatchInfo), + tsdbLastRowReaderOpen(readHandle->vnode, LASTROW_RETRIEVE_TYPE_SINGLE, pTableList, taosArrayGetSize(pInfo->pColMatchInfo), &pInfo->pLastrowReader); - taosMemoryFree(pCols); + + if (pScanNode->pScanPseudoCols != NULL) { + SExprSupp* pPseudoExpr = &pInfo->pseudoExprSup; + + pPseudoExpr->pExprInfo = createExprInfo(pScanNode->pScanPseudoCols, NULL, &pPseudoExpr->numOfExprs); + pPseudoExpr->pCtx = createSqlFunctionCtx(pPseudoExpr->pExprInfo, pPseudoExpr->numOfExprs, &pPseudoExpr->rowEntryInfoOffset); + } pOperator->name = "LastrowScanOperator"; pOperator->operatorType = QUERY_NODE_PHYSICAL_PLAN_LAST_ROW_SCAN; @@ -100,7 +100,20 @@ SSDataBlock* doScanLastrow(SOperatorInfo* pOperator) { // check if it is a group by tbname if (size == taosArrayGetSize(pInfo->pTableList)) { blockDataCleanup(pInfo->pRes); - tsdbRetrieveLastRow(pInfo->pLastrowReader, pInfo->pRes, pInfo->pSlotIds); + SArray* pUidList = taosArrayInit(1, sizeof(tb_uid_t)); + int32_t code = tsdbRetrieveLastRow(pInfo->pLastrowReader, pInfo->pRes, pInfo->pSlotIds, pUidList); + if (code != TSDB_CODE_SUCCESS) { + longjmp(pTaskInfo->env, code); + } + + // check for tag values + if (pInfo->pRes->info.rows > 0 && pInfo->pseudoExprSup.numOfExprs > 0) { + SExprSupp* pSup = &pInfo->pseudoExprSup; + pInfo->pRes->info.uid = *(tb_uid_t*) taosArrayGet(pUidList, 0); + addTagPseudoColumnData(&pInfo->readHandle, pSup->pExprInfo, pSup->numOfExprs, pInfo->pRes, GET_TASKID(pTaskInfo)); + } + + doSetOperatorCompleted(pOperator); return (pInfo->pRes->info.rows == 0) ? NULL : pInfo->pRes; } else { // todo fetch the result for each group diff --git a/source/libs/executor/src/scanoperator.c b/source/libs/executor/src/scanoperator.c index 64c740decf..66703502eb 100644 --- a/source/libs/executor/src/scanoperator.c +++ b/source/libs/executor/src/scanoperator.c @@ -39,8 +39,6 @@ static int32_t buildSysDbTableInfo(const SSysTableScanInfo* pInfo, int32_t capac static int32_t buildDbTableInfoBlock(const SSDataBlock* p, const SSysTableMeta* pSysDbTableMeta, size_t size, const char* dbName); -static int32_t addTagPseudoColumnData(SReadHandle* pHandle, SExprInfo* pPseudoExpr, int32_t numOfPseudoExpr, - SSDataBlock* pBlock, const char* idStr); static bool processBlockWithProbability(const SSampleExecInfo* pInfo); bool processBlockWithProbability(const SSampleExecInfo* pInfo) { @@ -320,8 +318,6 @@ int32_t addTagPseudoColumnData(SReadHandle* pHandle, SExprInfo* pPseudoExpr, int int32_t dstSlotId = pExpr->base.resSchema.slotId; SColumnInfoData* pColInfoData = taosArrayGet(pBlock->pDataBlock, dstSlotId); - - colInfoDataEnsureCapacity(pColInfoData, pBlock->info.rows); colInfoDataCleanup(pColInfoData, pBlock->info.rows); int32_t functionId = pExpr->pExpr->_function.functionId; diff --git a/source/libs/function/src/builtinsimpl.c b/source/libs/function/src/builtinsimpl.c index ccf28bfd78..c1143020f0 100644 --- a/source/libs/function/src/builtinsimpl.c +++ b/source/libs/function/src/builtinsimpl.c @@ -80,11 +80,12 @@ typedef struct STopBotRes { } STopBotRes; typedef struct SFirstLastRes { - bool hasResult; + bool hasResult; // used for last_row function only, isNullRes in SResultRowEntry can not be passed to downstream.So, // this attribute is required - bool isNull; + bool isNull; int32_t bytes; + int64_t ts; char buf[]; } SFirstLastRes; @@ -2951,6 +2952,7 @@ int32_t firstLastFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock) { SFirstLastRes* pRes = GET_ROWCELL_INTERBUF(pResInfo); colDataAppend(pCol, pBlock->info.rows, pRes->buf, pRes->isNull||pResInfo->isNullRes); + // handle selectivity STuplePos* pTuplePos = (STuplePos*)(pRes->buf + pRes->bytes + sizeof(TSKEY)); setSelectivityValue(pCtx, pBlock, pTuplePos, pBlock->info.rows); @@ -5988,7 +5990,7 @@ int32_t lastrowFunction(SqlFunctionCtx* pCtx) { SInputColumnInfoData* pInput = &pCtx->input; SColumnInfoData* pInputCol = pInput->pData[0]; - int32_t type = pInputCol->info.type; + int32_t type = pInputCol->info.type; int32_t bytes = pInputCol->info.bytes; pInfo->bytes = bytes; @@ -5999,7 +6001,7 @@ int32_t lastrowFunction(SqlFunctionCtx* pCtx) { char* data = colDataGetData(pInputCol, i); TSKEY cts = getRowPTs(pInput->pPTS, i); - if (pResInfo->numOfRes == 0 || *(TSKEY*)(pInfo->buf + bytes) < cts) { + if (pResInfo->numOfRes == 0 || pInfo->ts < cts) { if (colDataIsNull_s(pInputCol, i)) { pInfo->isNull = true; @@ -6012,8 +6014,7 @@ int32_t lastrowFunction(SqlFunctionCtx* pCtx) { memcpy(pInfo->buf, data, bytes); } - *(TSKEY*)(pInfo->buf + bytes) = cts; - + pInfo->ts = cts; pInfo->hasResult = true; pResInfo->numOfRes = 1; -- GitLab From 5ba8dbfba45f279fe843e6dd47029b8e6482731e Mon Sep 17 00:00:00 2001 From: Shengliang Guan Date: Wed, 13 Jul 2022 14:32:52 +0800 Subject: [PATCH 036/153] enh: support alter debugflag in dnode --- tests/script/general/alter/dnode.sim | 67 ------------------- tests/script/jenkins/basic.txt | 5 ++ .../alter/cached_schema_after_alter.sim | 0 tests/script/tsim/alter/dnode.sim | 62 +++++++++++++++++ .../script/{general => tsim}/alter/table.sim | 2 - 5 files changed, 67 insertions(+), 69 deletions(-) delete mode 100644 tests/script/general/alter/dnode.sim rename tests/script/{general => tsim}/alter/cached_schema_after_alter.sim (100%) create mode 100644 tests/script/tsim/alter/dnode.sim rename tests/script/{general => tsim}/alter/table.sim (99%) diff --git a/tests/script/general/alter/dnode.sim b/tests/script/general/alter/dnode.sim deleted file mode 100644 index 64e8a17de0..0000000000 --- a/tests/script/general/alter/dnode.sim +++ /dev/null @@ -1,67 +0,0 @@ -system sh/stop_dnodes.sh -system sh/deploy.sh -n dnode1 -i 1 -system sh/exec.sh -n dnode1 -s start -sql connect - -print ======== step1 -sql alter dnode 1 resetlog -sql alter dnode 1 monitor 1 - -sleep 3000 -sql select * from log.dn -if $rows <= 0 then - return -1 -endi - -print ======== step2 - -sql alter dnode 1 resetquerycache -sql alter dnode 1 debugFlag 135 -sql alter dnode 1 debugFlag 131 -sql alter dnode 1 monitor 0 -sql alter dnode 1 debugFlag 135 -sql alter dnode 1 monDebugFlag 135 -sql alter dnode 1 vDebugFlag 135 -sql alter dnode 1 mDebugFlag 135 -sql alter dnode 1 cDebugFlag 135 -sql alter dnode 1 httpDebugFlag 135 -sql alter dnode 1 qDebugflag 135 -sql alter dnode 1 sdbDebugFlag 135 -sql alter dnode 1 uDebugFlag 135 -sql alter dnode 1 tsdbDebugFlag 135 -sql alter dnode 1 sDebugflag 135 -sql alter dnode 1 rpcDebugFlag 135 -sql alter dnode 1 dDebugFlag 135 -sql alter dnode 1 mqttDebugFlag 135 -sql alter dnode 1 wDebugFlag 135 -sql alter dnode 1 tmrDebugFlag 135 -sql_error alter dnode 2 wDebugFlag 135 -sql_error alter dnode 2 tmrDebugFlag 135 - -print ======== step3 -sql_error alter $hostname1 debugFlag 135 -sql_error alter $hostname1 monDebugFlag 135 -sql_error alter $hostname1 vDebugFlag 135 -sql_error alter $hostname1 mDebugFlag 135 -sql_error alter dnode $hostname2 debugFlag 135 -sql_error alter dnode $hostname2 monDebugFlag 135 -sql_error alter dnode $hostname2 vDebugFlag 135 -sql_error alter dnode $hostname2 mDebugFlag 135 -sql alter dnode $hostname1 debugFlag 135 -sql alter dnode $hostname1 monDebugFlag 135 -sql alter dnode $hostname1 vDebugFlag 135 -sql alter dnode $hostname1 tmrDebugFlag 131 - -print ======== step4 -sql_error sql alter dnode 1 balance 0 -sql_error sql alter dnode 1 balance vnode:1-dnode:1 -sql_error sql alter dnode 1 balance "vnode:1" -sql_error sql alter dnode 1 balance "vnode:1-dnode:1" -sql_error sql alter dnode 1 balance "dnode:1-vnode:1" -sql_error sql alter dnode 1 balance "dnode:1-" -sql_error sql alter dnode 1 balance "vnode:2-dnod" -sql alter dnode 1 balance "vnode:2-dnode:1" -x step4 -step4: - -print ======= over -system sh/exec.sh -n dnode1 -s stop -x SIGINT \ No newline at end of file diff --git a/tests/script/jenkins/basic.txt b/tests/script/jenkins/basic.txt index 50d4c04a93..13a28aa527 100644 --- a/tests/script/jenkins/basic.txt +++ b/tests/script/jenkins/basic.txt @@ -1,6 +1,11 @@ #======================b1-start=============== +# ---- alter +./test.sh -f tsim/alter/cached_schema_after_alter.sim +./test.sh -f tsim/alter/dnode.sim +#./test.sh -f tsim/alter/table.sim + # ---- user ./test.sh -f tsim/user/basic.sim ./test.sh -f tsim/user/password.sim diff --git a/tests/script/general/alter/cached_schema_after_alter.sim b/tests/script/tsim/alter/cached_schema_after_alter.sim similarity index 100% rename from tests/script/general/alter/cached_schema_after_alter.sim rename to tests/script/tsim/alter/cached_schema_after_alter.sim diff --git a/tests/script/tsim/alter/dnode.sim b/tests/script/tsim/alter/dnode.sim new file mode 100644 index 0000000000..35620f17aa --- /dev/null +++ b/tests/script/tsim/alter/dnode.sim @@ -0,0 +1,62 @@ +system sh/stop_dnodes.sh +system sh/deploy.sh -n dnode1 -i 1 +system sh/exec.sh -n dnode1 -s start +sql connect + +print ======== step1 +sql alter dnode 1 'resetlog' +sql alter dnode 1 'monitor' '1' +sql alter dnode 1 'monitor' '0' +sql alter dnode 1 'monitor 1' +sql alter dnode 1 'monitor 0' + +print ======== step2 +sql_error alter dnode 1 'resetquerycache' +sql alter dnode 1 'debugFlag 135' +sql alter dnode 1 'dDebugFlag 131' +sql alter dnode 1 'vDebugFlag 131' +sql alter dnode 1 'mDebugFlag 131' +sql alter dnode 1 'wDebugFlag 131' +sql alter dnode 1 'sDebugFlag 131' +sql alter dnode 1 'tsdbDebugFlag 131' +sql alter dnode 1 'tqDebugFlag 131' +sql alter dnode 1 'fsDebugFlag 131' +sql alter dnode 1 'udfDebugFlag 131' +sql alter dnode 1 'smaDebugFlag 131' +sql alter dnode 1 'idxDebugFlag 131' +sql alter dnode 1 'tmrDebugFlag 131' +sql alter dnode 1 'uDebugFlag 131' +sql alter dnode 1 'smaDebugFlag 131' +sql alter dnode 1 'rpcDebugFlag 131' +sql alter dnode 1 'qDebugFlag 131' + +sql_error alter dnode 2 'wDebugFlag 135' +sql_error alter dnode 2 'tmrDebugFlag 135' + +print ======== step3 +sql_error alter $hostname1 debugFlag 135 +sql_error alter $hostname1 monDebugFlag 135 +sql_error alter $hostname1 vDebugFlag 135 +sql_error alter $hostname1 mDebugFlag 135 +sql_error alter dnode $hostname2 debugFlag 135 +sql_error alter dnode $hostname2 monDebugFlag 135 +sql_error alter dnode $hostname2 vDebugFlag 135 +sql_error alter dnode $hostname2 mDebugFlag 135 +sql_error alter dnode $hostname1 debugFlag 135 +sql_error alter dnode $hostname1 monDebugFlag 135 +sql_error alter dnode $hostname1 vDebugFlag 135 +sql_error alter dnode $hostname1 tmrDebugFlag 131 + +print ======== step4 +sql_error sql alter dnode 1 balance 0 +sql_error sql alter dnode 1 balance vnode:1-dnode:1 +sql_error sql alter dnode 1 balance "vnode:1" +sql_error sql alter dnode 1 balance "vnode:1-dnode:1" +sql_error sql alter dnode 1 balance "dnode:1-vnode:1" +sql_error sql alter dnode 1 balance "dnode:1-" +sql_error sql alter dnode 1 balance "vnode:2-dnod" +sql alter dnode 1 balance "vnode:2-dnode:1" -x step4 +step4: + +print ======= over +system sh/exec.sh -n dnode1 -s stop -x SIGINT \ No newline at end of file diff --git a/tests/script/general/alter/table.sim b/tests/script/tsim/alter/table.sim similarity index 99% rename from tests/script/general/alter/table.sim rename to tests/script/tsim/alter/table.sim index 9ca2f60bdc..cc995d171f 100644 --- a/tests/script/general/alter/table.sim +++ b/tests/script/tsim/alter/table.sim @@ -315,9 +315,7 @@ endi print ======== step9 print ======== step10 system sh/exec.sh -n dnode1 -s stop -x SIGINT -sleep 3000 system sh/exec.sh -n dnode1 -s start -sleep 3000 sql use d1 sql describe tb -- GitLab From db6eca9bef283b7148f6d31dcce3d19ce5a9e665 Mon Sep 17 00:00:00 2001 From: Ganlin Zhao Date: Wed, 13 Jul 2022 14:41:50 +0800 Subject: [PATCH 037/153] fix test cases --- tests/system-test/2-query/arccos.py | 92 ++++++++++++++--------------- 1 file changed, 46 insertions(+), 46 deletions(-) diff --git a/tests/system-test/2-query/arccos.py b/tests/system-test/2-query/arccos.py index e7e5ecb114..d5656d9104 100644 --- a/tests/system-test/2-query/arccos.py +++ b/tests/system-test/2-query/arccos.py @@ -9,14 +9,14 @@ from util.cases import * class TDTestCase: - updatecfgDict = {'debugFlag': 143 ,"cDebugFlag":143,"uDebugFlag":143 ,"rpcDebugFlag":143 , "tmrDebugFlag":143 , + updatecfgDict = {'debugFlag': 143 ,"cDebugFlag":143,"uDebugFlag":143 ,"rpcDebugFlag":143 , "tmrDebugFlag":143 , "jniDebugFlag":143 ,"simDebugFlag":143,"dDebugFlag":143, "dDebugFlag":143,"vDebugFlag":143,"mDebugFlag":143,"qDebugFlag":143, "wDebugFlag":143,"sDebugFlag":143,"tsdbDebugFlag":143,"tqDebugFlag":143 ,"fsDebugFlag":143 ,"udfDebugFlag":143} def init(self, conn, powSql): tdLog.debug(f"start to excute {__file__}") tdSql.init(conn.cursor()) self.PI =3.1415926 - + def prepare_datas(self): tdSql.execute( '''create table stb1 @@ -24,7 +24,7 @@ class TDTestCase: tags (t1 int) ''' ) - + tdSql.execute( ''' create table t1 @@ -66,14 +66,14 @@ class TDTestCase: ( '2023-02-21 01:01:01.000', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL ) ''' ) - + def check_result_auto_acos(self ,origin_query , pow_query): pow_result = tdSql.getResult(pow_query) origin_result = tdSql.getResult(origin_query) auto_result =[] - + for row in origin_result: row_check = [] for elem in row: @@ -93,7 +93,7 @@ class TDTestCase: if auto_result[row_index][col_index] == None and not (auto_result[row_index][col_index] == None and elem == None): check_status = False elif auto_result[row_index][col_index] != None and (auto_result[row_index][col_index] - elem > 0.00000001): - check_status = False + check_status = False else: pass if not check_status: @@ -101,7 +101,7 @@ class TDTestCase: sys.exit(1) else: tdLog.info("acos value check pass , it work as expected ,sql is \"%s\" "%pow_query ) - + def test_errors(self): error_sql_lists = [ "select acos from t1", @@ -135,42 +135,42 @@ class TDTestCase: ] for error_sql in error_sql_lists: tdSql.error(error_sql) - + def support_types(self): type_error_sql_lists = [ - "select acos(ts) from t1" , + "select acos(ts) from t1" , "select acos(c7) from t1", "select acos(c8) from t1", "select acos(c9) from t1", - "select acos(ts) from ct1" , + "select acos(ts) from ct1" , "select acos(c7) from ct1", "select acos(c8) from ct1", "select acos(c9) from ct1", - "select acos(ts) from ct3" , + "select acos(ts) from ct3" , "select acos(c7) from ct3", "select acos(c8) from ct3", "select acos(c9) from ct3", - "select acos(ts) from ct4" , + "select acos(ts) from ct4" , "select acos(c7) from ct4", "select acos(c8) from ct4", "select acos(c9) from ct4", - "select acos(ts) from stb1" , + "select acos(ts) from stb1" , "select acos(c7) from stb1", "select acos(c8) from stb1", "select acos(c9) from stb1" , - "select acos(ts) from stbbb1" , + "select acos(ts) from stbbb1" , "select acos(c7) from stbbb1", "select acos(ts) from tbname", "select acos(c9) from tbname" ] - + for type_sql in type_error_sql_lists: tdSql.error(type_sql) - - + + type_sql_lists = [ "select acos(c1) from t1", "select acos(c2) from t1", @@ -200,16 +200,16 @@ class TDTestCase: "select acos(c5) from stb1", "select acos(c6) from stb1", - "select acos(c6) as alisb from stb1", - "select acos(c6) alisb from stb1", + "select acos(c6) as alisb from stb1", + "select acos(c6) alisb from stb1", ] for type_sql in type_sql_lists: tdSql.query(type_sql) - + def basic_acos_function(self): - # basic query + # basic query tdSql.query("select c1 from ct3") tdSql.checkRows(0) tdSql.query("select c1 from t1") @@ -250,7 +250,7 @@ class TDTestCase: tdSql.checkData(5, 5, None) self.check_result_auto_acos( "select abs(c1), abs(c2), abs(c3) , abs(c4), abs(c5) from t1", "select acos(abs(c1)), acos(abs(c2)) ,acos(abs(c3)), acos(abs(c4)), acos(abs(c5)) from t1") - + # used for sub table tdSql.query("select c2 ,acos(c2) from ct1") tdSql.checkData(0, 1, None) @@ -266,7 +266,7 @@ class TDTestCase: tdSql.checkData(5 , 2, None) self.check_result_auto_acos( "select c1, c2, c3 , c4, c5 from ct1", "select acos(c1), acos(c2) ,acos(c3), acos(c4), acos(c5) from ct1") - + # nest query for acos functions tdSql.query("select c4 , acos(c4) ,acos(acos(c4)) , acos(acos(acos(c4))) from ct1;") tdSql.checkData(0 , 0 , 88) @@ -284,21 +284,21 @@ class TDTestCase: tdSql.checkData(11 , 2 , None) tdSql.checkData(11 , 3 , None) - # used for stable table - + # used for stable table + tdSql.query("select acos(c1) from stb1") tdSql.checkRows(25) - + # used for not exists table tdSql.error("select acos(c1) from stbbb1") tdSql.error("select acos(c1) from tbname") tdSql.error("select acos(c1) from ct5") - # mix with common col + # mix with common col tdSql.query("select c1, acos(c1) from ct1") tdSql.query("select c2, acos(c2) from ct4") - + # mix with common functions tdSql.query("select c1, acos(c1),acos(c1), acos(acos(c1)) from ct4 ") @@ -306,7 +306,7 @@ class TDTestCase: tdSql.checkData(0 , 1 ,None) tdSql.checkData(0 , 2 ,None) tdSql.checkData(0 , 3 ,None) - + tdSql.checkData(3 , 0 , 6) tdSql.checkData(3 , 1 ,None) tdSql.checkData(3 , 2 ,None) @@ -327,8 +327,8 @@ class TDTestCase: tdSql.query("select max(c5), count(c5) from stb1") tdSql.query("select max(c5), count(c5) from ct1") - - # # bug fix for compute + + # # bug fix for compute tdSql.query("select c1, acos(c1) -0 ,acos(c1-4)-0 from ct4 ") tdSql.checkData(0, 0, None) tdSql.checkData(0, 1, None) @@ -397,10 +397,10 @@ class TDTestCase: tdSql.checkData(0,3,0.000000000) tdSql.checkData(0,4,-0.100000000) tdSql.checkData(0,5,2) - + def pow_Arithmetic(self): pass - + def check_boundary_values(self): PI=3.1415926 @@ -429,11 +429,11 @@ class TDTestCase: f"insert into sub1_bound values ( now()+1s, 2147483648, 9223372036854775808, 32768, 128, 3.40E+38, 1.7e+308, True, 'binary_tb1', 'nchar_tb1', now() )" ) self.check_result_auto_acos( "select abs(c1), abs(c2), abs(c3) , abs(c4), abs(c5) from sub1_bound ", "select acos(abs(c1)), acos(abs(c2)) ,acos(abs(c3)), acos(abs(c4)), acos(abs(c5)) from sub1_bound") - + self.check_result_auto_acos( "select c1, c2, c3 , c3, c2 ,c1 from sub1_bound ", "select acos(c1), acos(c2) ,acos(c3), acos(c3), acos(c2) ,acos(c1) from sub1_bound") self.check_result_auto_acos("select abs(abs(abs(abs(abs(abs(abs(abs(abs(c1))))))))) nest_col_func from sub1_bound" , "select acos(abs(c1)) from sub1_bound" ) - + # check basic elem for table per row tdSql.query("select acos(abs(c1)) ,acos(abs(c2)) , acos(abs(c3)) , acos(abs(c4)), acos(abs(c5)), acos(abs(c6)) from sub1_bound ") tdSql.checkData(0,0,None) @@ -492,41 +492,41 @@ class TDTestCase: self.check_result_auto_acos( " select t1,c5 from stb1 where c1 > 0 order by tbname " , "select acos(t1) ,acos(c5) from stb1 where c1 > 0 order by tbname" ) self.check_result_auto_acos( " select t1,c5 from stb1 where c1 > 0 order by tbname " , "select acos(t1) , acos(c5) from stb1 where c1 > 0 order by tbname" ) pass - - + + def run(self): # sourcery skip: extract-duplicate-method, remove-redundant-fstring tdSql.prepare() tdLog.printNoPrefix("==========step1:create table ==============") - + self.prepare_datas() - tdLog.printNoPrefix("==========step2:test errors ==============") + tdLog.printNoPrefix("==========step2:test errors ==============") self.test_errors() - - tdLog.printNoPrefix("==========step3:support types ============") + + tdLog.printNoPrefix("==========step3:support types ============") self.support_types() - tdLog.printNoPrefix("==========step4: acos basic query ============") + tdLog.printNoPrefix("==========step4: acos basic query ============") self.basic_acos_function() - tdLog.printNoPrefix("==========step5: big number acos query ============") + tdLog.printNoPrefix("==========step5: big number acos query ============") self.test_big_number() - tdLog.printNoPrefix("==========step6: acos boundary query ============") + tdLog.printNoPrefix("==========step6: acos boundary query ============") self.check_boundary_values() - tdLog.printNoPrefix("==========step7: acos filter query ============") + tdLog.printNoPrefix("==========step7: acos filter query ============") self.abs_func_filter() - tdLog.printNoPrefix("==========step7: acos filter query ============") + tdLog.printNoPrefix("==========step7: acos filter query ============") self.abs_func_filter() -- GitLab From adbc50140335c793b14bde5ca14fad899d55a0fd Mon Sep 17 00:00:00 2001 From: Ganlin Zhao Date: Wed, 13 Jul 2022 14:41:50 +0800 Subject: [PATCH 038/153] fix test cases --- tests/system-test/2-query/queryQnode.py | 54 ++++++++++++------------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/tests/system-test/2-query/queryQnode.py b/tests/system-test/2-query/queryQnode.py index 3fdc09478d..8bdb99deec 100644 --- a/tests/system-test/2-query/queryQnode.py +++ b/tests/system-test/2-query/queryQnode.py @@ -45,7 +45,7 @@ class TDTestCase: case1: limit offset base function test case2: offset return valid ''' - return + return def getBuildPath(self): selfPath = os.path.dirname(os.path.realpath(__file__)) @@ -71,7 +71,7 @@ class TDTestCase: # self.create_tables(); self.ts = 1500000000000 - # stop + # stop def stop(self): tdSql.close() tdLog.success("%s successfully executed" % __file__) @@ -82,7 +82,7 @@ class TDTestCase: def newcur(self,host,cfg): user = "root" password = "taosdata" - port =6030 + port =6030 con=taos.connect(host=host, user=user, password=password, config=cfg ,port=port) cur=con.cursor() print(cur) @@ -92,7 +92,7 @@ class TDTestCase: def create_tables(self,host,dbname,stbname,count): buildPath = self.getBuildPath() config = buildPath+ "../sim/dnode1/cfg/" - + tsql=self.newcur(host,config) tsql.execute("use %s" %dbname) @@ -111,7 +111,7 @@ class TDTestCase: tsql.execute(sql) sql = pre_create # print(time.time()) - # end sql + # end sql if sql != pre_create: # print(sql) tsql.execute(sql) @@ -124,7 +124,7 @@ class TDTestCase: def mutiThread_create_tables(self,host,dbname,stbname,vgroups,threadNumbers,childcount): buildPath = self.getBuildPath() config = buildPath+ "../sim/dnode1/cfg/" - + tsql=self.newcur(host,config) tdLog.debug("create database %s"%dbname) tsql.execute("drop database if exists %s"%dbname) @@ -134,7 +134,7 @@ class TDTestCase: threads = [] for i in range(threadNumbers): tsql.execute("create stable %s%d(ts timestamp, c1 int, c2 binary(10)) tags(t1 int)"%(stbname,i)) - threads.append(thd.Thread(target=self.create_tables, args=(host, dbname, stbname+"%d"%i, count,))) + threads.append(thd.Thread(target=self.create_tables, args=(host, dbname, stbname+"%d"%i, count,))) start_time = time.time() for tr in threads: tr.start() @@ -144,7 +144,7 @@ class TDTestCase: spendTime=end_time-start_time speedCreate=threadNumbers*count/spendTime tdLog.debug("spent %.2fs to create %d stable and %d table, create speed is %.2f table/s... [OK]"% (spendTime,threadNumbers,threadNumbers*count,speedCreate)) - + return # def create_tables(self,host,dbname,stbname,vgroups,tcountStart,tcountStop): @@ -171,7 +171,7 @@ class TDTestCase: # print(sql) tsql.execute(sql) sql = "insert into %s_%d values " %(stbname,i) - # end sql + # end sql if sql != pre_insert: # print(sql) print(len(sql)) @@ -186,7 +186,7 @@ class TDTestCase: def mutiThread_insert_data(self, host, dbname, stbname, threadNumbers, chilCount, ts_start, childrowcount): buildPath = self.getBuildPath() config = buildPath+ "../sim/dnode1/cfg/" - + tsql=self.newcur(host,config) tdLog.debug("ready to inser data") @@ -195,7 +195,7 @@ class TDTestCase: threads = [] for i in range(threadNumbers): # tsql.execute("create stable %s%d(ts timestamp, c1 int, c2 binary(10)) tags(t1 int)"%(stbname,i)) - threads.append(thd.Thread(target=self.insert_data, args=(host, dbname, stbname+"%d"%i, chilCount, ts_start, childrowcount,))) + threads.append(thd.Thread(target=self.insert_data, args=(host, dbname, stbname+"%d"%i, chilCount, ts_start, childrowcount,))) start_time = time.time() for tr in threads: tr.start() @@ -226,10 +226,10 @@ class TDTestCase: tdLog.info("taosd found in %s" % buildPath) taosBenchbin = buildPath+ "/build/bin/taosBenchmark" os.system("%s -f %s -y " %(taosBenchbin,jsonFile)) - + return def taosBenchCreate(self,host,dropdb,dbname,stbname,vgroups,processNumbers,count): - + # count=50000 buildPath = self.getBuildPath() config = buildPath+ "../sim/dnode1/cfg/" @@ -243,7 +243,7 @@ class TDTestCase: # tsql.getResult("show databases") # print(tdSql.queryResult) tsql.execute("use %s" %dbname) - + threads = [] for i in range(processNumbers): jsonfile="1-insert/Vgroups%d%d.json"%(vgroups,i) @@ -254,7 +254,7 @@ class TDTestCase: os.system("sed -i 's/\"childtable_count\": 10000,/\"childtable_count\": %d,/g' %s "%(count,jsonfile)) os.system("sed -i 's/\"name\": \"stb1\",/\"name\": \"%s%d\",/g' %s "%(stbname,i,jsonfile)) os.system("sed -i 's/\"childtable_prefix\": \"stb1_\",/\"childtable_prefix\": \"%s%d_\",/g' %s "%(stbname,i,jsonfile)) - threads.append(mp.Process(target=self.taosBench, args=("%s"%jsonfile,))) + threads.append(mp.Process(target=self.taosBench, args=("%s"%jsonfile,))) start_time = time.time() for tr in threads: tr.start() @@ -276,8 +276,8 @@ class TDTestCase: for i in range(stableCount): tdSql.query("select count(*) from %s%d"%(stbname,i)) tdSql.checkData(0,0,rowsPerSTable) - return - + return + # test case : Switch back and forth among the three queryPolicy(1\2\3) def test_case1(self): self.taosBenchCreate("127.0.0.1","no","db1", "stb1", 1, 2, 1*10) @@ -303,7 +303,7 @@ class TDTestCase: tdSql.execute("reset query cache") tdSql.query("select max(c1) from stb10;") tdSql.checkData(0, 0, "%s"%maxQnode) - tdSql.query("select min(c1) from stb11;") + tdSql.query("select min(c1) from stb11;") tdSql.checkData(0, 0, "%s"%minQnode) tdSql.query("select c0,c1 from stb11_1 where (c0>1000) union select c0,c1 from stb11_1 where c0>2000;") unionVnode=tdSql.queryResult @@ -352,8 +352,8 @@ class TDTestCase: tdSql.execute("reset query cache") tdSql.query("select max(c1) from stb10;") assert maxQnode==tdSql.getData(0,0) - tdSql.query("select min(c1) from stb11;") - assert minQnode==tdSql.getData(0,0) + tdSql.query("select min(c1) from stb11;") + assert minQnode==tdSql.getData(0,0) tdSql.error("select c0,c1 from stb11_1 where (c0>1000) union select c0,c1 from stb11_1 where c0>2000;") tdSql.error("select c0,c1 from stb11_1 where (c0>1000) union all select c0,c1 from stb11_1 where c0>2000;") @@ -417,7 +417,7 @@ class TDTestCase: tdLog.exit("alter queryPolicy to %d failed"%queryPolicy) tdSql.execute("use db1;") tdSql.error("select max(c1) from stb10;") - tdSql.error("select min(c1) from stb11;") + tdSql.error("select min(c1) from stb11;") tdSql.error("select c0,c1 from stb11_1 where (c0>1000) union select c0,c1 from stb11_1 where c0>2000;") tdSql.error("select c0,c1 from stb11_1 where (c0>1000) union all select c0,c1 from stb11_1 where c0>2000;") @@ -452,20 +452,20 @@ class TDTestCase: tdSql.execute("reset query cache") tdSql.error("select max(c1) from stb10;") - tdSql.error("select min(c1) from stb11;") + tdSql.error("select min(c1) from stb11;") tdSql.error("select c0,c1 from stb11_1 where (c0>1000) union select c0,c1 from stb11_1 where c0>2000;") tdSql.error("select c0,c1 from stb11_1 where (c0>1000) union all select c0,c1 from stb11_1 where c0>2000;") - # run case + # run case def run(self): # test qnode - tdLog.debug(" test_case1 ............ [start]") + tdLog.debug(" test_case1 ............ [start]") self.test_case1() tdLog.debug(" test_case1 ............ [OK]") - tdLog.debug(" test_case2 ............ [start]") + tdLog.debug(" test_case2 ............ [start]") self.test_case2() tdLog.debug(" test_case2 ............ [OK]") - tdLog.debug(" test_case3 ............ [start]") + tdLog.debug(" test_case3 ............ [start]") self.test_case3() tdLog.debug(" test_case3 ............ [OK]") @@ -475,7 +475,7 @@ class TDTestCase: tdSql.close() tdLog.success(f"{__file__} successfully executed") - return + return # # add case with filename # -- GitLab From dbe21e748ab503faa856d41949ce7321e7ccad75 Mon Sep 17 00:00:00 2001 From: Ganlin Zhao Date: Wed, 13 Jul 2022 14:41:50 +0800 Subject: [PATCH 039/153] fix test cases --- tests/system-test/2-query/arcsin.py | 90 ++++++++++++++--------------- 1 file changed, 45 insertions(+), 45 deletions(-) diff --git a/tests/system-test/2-query/arcsin.py b/tests/system-test/2-query/arcsin.py index 80c89a47ab..31185ffcaa 100644 --- a/tests/system-test/2-query/arcsin.py +++ b/tests/system-test/2-query/arcsin.py @@ -9,14 +9,14 @@ from util.cases import * class TDTestCase: - updatecfgDict = {'debugFlag': 143 ,"cDebugFlag":143,"uDebugFlag":143 ,"rpcDebugFlag":143 , "tmrDebugFlag":143 , + updatecfgDict = {'debugFlag': 143 ,"cDebugFlag":143,"uDebugFlag":143 ,"rpcDebugFlag":143 , "tmrDebugFlag":143 , "jniDebugFlag":143 ,"simDebugFlag":143,"dDebugFlag":143, "dDebugFlag":143,"vDebugFlag":143,"mDebugFlag":143,"qDebugFlag":143, "wDebugFlag":143,"sDebugFlag":143,"tsdbDebugFlag":143,"tqDebugFlag":143 ,"fsDebugFlag":143 ,"udfDebugFlag":143} def init(self, conn, powSql): tdLog.debug(f"start to excute {__file__}") tdSql.init(conn.cursor()) self.PI =3.1415926 - + def prepare_datas(self): tdSql.execute( '''create table stb1 @@ -24,7 +24,7 @@ class TDTestCase: tags (t1 int) ''' ) - + tdSql.execute( ''' create table t1 @@ -66,14 +66,14 @@ class TDTestCase: ( '2023-02-21 01:01:01.000', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL ) ''' ) - + def check_result_auto_asin(self ,origin_query , pow_query): pow_result = tdSql.getResult(pow_query) origin_result = tdSql.getResult(origin_query) auto_result =[] - + for row in origin_result: row_check = [] for elem in row: @@ -93,7 +93,7 @@ class TDTestCase: if auto_result[row_index][col_index] == None and not (auto_result[row_index][col_index] == None and elem == None): check_status = False elif auto_result[row_index][col_index] != None and (auto_result[row_index][col_index] - elem > 0.00000001): - check_status = False + check_status = False else: pass if not check_status: @@ -101,7 +101,7 @@ class TDTestCase: sys.exit(1) else: tdLog.info("asin value check pass , it work as expected ,sql is \"%s\" "%pow_query ) - + def test_errors(self): error_sql_lists = [ "select asin from t1", @@ -135,42 +135,42 @@ class TDTestCase: ] for error_sql in error_sql_lists: tdSql.error(error_sql) - + def support_types(self): type_error_sql_lists = [ - "select asin(ts) from t1" , + "select asin(ts) from t1" , "select asin(c7) from t1", "select asin(c8) from t1", "select asin(c9) from t1", - "select asin(ts) from ct1" , + "select asin(ts) from ct1" , "select asin(c7) from ct1", "select asin(c8) from ct1", "select asin(c9) from ct1", - "select asin(ts) from ct3" , + "select asin(ts) from ct3" , "select asin(c7) from ct3", "select asin(c8) from ct3", "select asin(c9) from ct3", - "select asin(ts) from ct4" , + "select asin(ts) from ct4" , "select asin(c7) from ct4", "select asin(c8) from ct4", "select asin(c9) from ct4", - "select asin(ts) from stb1" , + "select asin(ts) from stb1" , "select asin(c7) from stb1", "select asin(c8) from stb1", "select asin(c9) from stb1" , - "select asin(ts) from stbbb1" , + "select asin(ts) from stbbb1" , "select asin(c7) from stbbb1", "select asin(ts) from tbname", "select asin(c9) from tbname" ] - + for type_sql in type_error_sql_lists: tdSql.error(type_sql) - - + + type_sql_lists = [ "select asin(c1) from t1", "select asin(c2) from t1", @@ -200,16 +200,16 @@ class TDTestCase: "select asin(c5) from stb1", "select asin(c6) from stb1", - "select asin(c6) as alisb from stb1", - "select asin(c6) alisb from stb1", + "select asin(c6) as alisb from stb1", + "select asin(c6) alisb from stb1", ] for type_sql in type_sql_lists: tdSql.query(type_sql) - + def basic_asin_function(self): - # basic query + # basic query tdSql.query("select c1 from ct3") tdSql.checkRows(0) tdSql.query("select c1 from t1") @@ -250,7 +250,7 @@ class TDTestCase: tdSql.checkData(5, 5, None) self.check_result_auto_asin( "select abs(c1), abs(c2), abs(c3) , abs(c4), abs(c5) from t1", "select asin(abs(c1)), asin(abs(c2)) ,asin(abs(c3)), asin(abs(c4)), asin(abs(c5)) from t1") - + # used for sub table tdSql.query("select c2 ,asin(c2) from ct1") tdSql.checkData(0, 1, None) @@ -266,7 +266,7 @@ class TDTestCase: tdSql.checkData(5 , 2, None) self.check_result_auto_asin( "select c1, c2, c3 , c4, c5 from ct1", "select asin(c1), asin(c2) ,asin(c3), asin(c4), asin(c5) from ct1") - + # nest query for asin functions tdSql.query("select c4 , asin(c4) ,asin(asin(c4)) , asin(asin(asin(c4))) from ct1;") tdSql.checkData(0 , 0 , 88) @@ -284,21 +284,21 @@ class TDTestCase: tdSql.checkData(11 , 2 , None) tdSql.checkData(11 , 3 , None) - # used for stable table - + # used for stable table + tdSql.query("select asin(c1) from stb1") tdSql.checkRows(25) - + # used for not exists table tdSql.error("select asin(c1) from stbbb1") tdSql.error("select asin(c1) from tbname") tdSql.error("select asin(c1) from ct5") - # mix with common col + # mix with common col tdSql.query("select c1, asin(c1) from ct1") tdSql.query("select c2, asin(c2) from ct4") - + # mix with common functions tdSql.query("select c1, asin(c1),asin(c1), asin(asin(c1)) from ct4 ") @@ -306,7 +306,7 @@ class TDTestCase: tdSql.checkData(0 , 1 ,None) tdSql.checkData(0 , 2 ,None) tdSql.checkData(0 , 3 ,None) - + tdSql.checkData(3 , 0 , 6) tdSql.checkData(3 , 1 ,None) tdSql.checkData(3 , 2 ,None) @@ -327,8 +327,8 @@ class TDTestCase: tdSql.query("select max(c5), count(c5) from stb1") tdSql.query("select max(c5), count(c5) from ct1") - - # # bug fix for compute + + # # bug fix for compute tdSql.query("select c1, asin(c1) -0 ,asin(c1-4)-0 from ct4 ") tdSql.checkData(0, 0, None) tdSql.checkData(0, 1, None) @@ -397,10 +397,10 @@ class TDTestCase: tdSql.checkData(0,3,1.000000000) tdSql.checkData(0,4,0.900000000) tdSql.checkData(0,5,2) - + def pow_Arithmetic(self): pass - + def check_boundary_values(self): PI=3.1415926 @@ -429,11 +429,11 @@ class TDTestCase: f"insert into sub1_bound values ( now()+1s, 2147483648, 9223372036854775808, 32768, 128, 3.40E+38, 1.7e+308, True, 'binary_tb1', 'nchar_tb1', now() )" ) self.check_result_auto_asin( "select abs(c1), abs(c2), abs(c3) , abs(c4), abs(c5) from sub1_bound ", "select asin(abs(c1)), asin(abs(c2)) ,asin(abs(c3)), asin(abs(c4)), asin(abs(c5)) from sub1_bound") - + self.check_result_auto_asin( "select c1, c2, c3 , c3, c2 ,c1 from sub1_bound ", "select asin(c1), asin(c2) ,asin(c3), asin(c3), asin(c2) ,asin(c1) from sub1_bound") self.check_result_auto_asin("select abs(abs(abs(abs(abs(abs(abs(abs(abs(c1))))))))) nest_col_func from sub1_bound" , "select asin(abs(c1)) from sub1_bound" ) - + # check basic elem for table per row tdSql.query("select asin(abs(c1)) ,asin(abs(c2)) , asin(abs(c3)) , asin(abs(c4)), asin(abs(c5)), asin(abs(c6)) from sub1_bound ") tdSql.checkData(0,0,None) @@ -492,37 +492,37 @@ class TDTestCase: self.check_result_auto_asin( " select t1,c5 from stb1 where c1 > 0 order by tbname " , "select asin(t1) ,asin(c5) from stb1 where c1 > 0 order by tbname" ) self.check_result_auto_asin( " select t1,c5 from stb1 where c1 > 0 order by tbname " , "select asin(t1) , asin(c5) from stb1 where c1 > 0 order by tbname" ) pass - - + + def run(self): # sourcery skip: extract-duplicate-method, remove-redundant-fstring tdSql.prepare() tdLog.printNoPrefix("==========step1:create table ==============") - + self.prepare_datas() - tdLog.printNoPrefix("==========step2:test errors ==============") + tdLog.printNoPrefix("==========step2:test errors ==============") self.test_errors() - - tdLog.printNoPrefix("==========step3:support types ============") + + tdLog.printNoPrefix("==========step3:support types ============") self.support_types() - tdLog.printNoPrefix("==========step4: asin basic query ============") + tdLog.printNoPrefix("==========step4: asin basic query ============") self.basic_asin_function() - tdLog.printNoPrefix("==========step5: big number asin query ============") + tdLog.printNoPrefix("==========step5: big number asin query ============") self.test_big_number() - tdLog.printNoPrefix("==========step6: asin boundary query ============") + tdLog.printNoPrefix("==========step6: asin boundary query ============") self.check_boundary_values() - tdLog.printNoPrefix("==========step7: asin filter query ============") + tdLog.printNoPrefix("==========step7: asin filter query ============") self.abs_func_filter() -- GitLab From 860091f4841c84a6f82e248fab2bdfddc219b64d Mon Sep 17 00:00:00 2001 From: Ganlin Zhao Date: Wed, 13 Jul 2022 14:41:50 +0800 Subject: [PATCH 040/153] fix test cases --- tests/system-test/2-query/diff.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/system-test/2-query/diff.py b/tests/system-test/2-query/diff.py index 0d8b0de3dc..30b588fa97 100644 --- a/tests/system-test/2-query/diff.py +++ b/tests/system-test/2-query/diff.py @@ -50,7 +50,7 @@ class TDTestCase: tdSql.checkData(0, 0, None) tdSql.checkData(1, 0, None) - tdSql.execute('''create table stb(ts timestamp, col1 tinyint, col2 smallint, col3 int, col4 bigint, col5 float, col6 double, + tdSql.execute('''create table stb(ts timestamp, col1 tinyint, col2 smallint, col3 int, col4 bigint, col5 float, col6 double, col7 bool, col8 binary(20), col9 nchar(20), col11 tinyint unsigned, col12 smallint unsigned, col13 int unsigned, col14 bigint unsigned) tags(loc nchar(20))''') tdSql.execute("create table stb_1 using stb tags('beijing')") tdSql.execute( @@ -115,7 +115,7 @@ class TDTestCase: tdSql.query("select diff(col6) from stb_1") tdSql.checkRows(10) - tdSql.execute('''create table stb1(ts timestamp, col1 tinyint, col2 smallint, col3 int, col4 bigint, col5 float, col6 double, + tdSql.execute('''create table stb1(ts timestamp, col1 tinyint, col2 smallint, col3 int, col4 bigint, col5 float, col6 double, col7 bool, col8 binary(20), col9 nchar(20), col11 tinyint unsigned, col12 smallint unsigned, col13 int unsigned, col14 bigint unsigned) tags(loc nchar(20))''') tdSql.execute("create table stb1_1 using stb tags('shanghai')") -- GitLab From b877cbbec97d81ed033ee6275388eef266455181 Mon Sep 17 00:00:00 2001 From: Ganlin Zhao Date: Wed, 13 Jul 2022 14:41:50 +0800 Subject: [PATCH 041/153] fix test cases --- tests/system-test/2-query/arctan.py | 90 ++++++++++++++--------------- 1 file changed, 45 insertions(+), 45 deletions(-) diff --git a/tests/system-test/2-query/arctan.py b/tests/system-test/2-query/arctan.py index db59693425..4c729bd521 100644 --- a/tests/system-test/2-query/arctan.py +++ b/tests/system-test/2-query/arctan.py @@ -9,13 +9,13 @@ from util.cases import * class TDTestCase: - updatecfgDict = {'debugFlag': 143 ,"cDebugFlag":143,"uDebugFlag":143 ,"rpcDebugFlag":143 , "tmrDebugFlag":143 , + updatecfgDict = {'debugFlag': 143 ,"cDebugFlag":143,"uDebugFlag":143 ,"rpcDebugFlag":143 , "tmrDebugFlag":143 , "jniDebugFlag":143 ,"simDebugFlag":143,"dDebugFlag":143, "dDebugFlag":143,"vDebugFlag":143,"mDebugFlag":143,"qDebugFlag":143, "wDebugFlag":143,"sDebugFlag":143,"tsdbDebugFlag":143,"tqDebugFlag":143 ,"fsDebugFlag":143 ,"udfDebugFlag":143} def init(self, conn, powSql): tdLog.debug(f"start to excute {__file__}") tdSql.init(conn.cursor()) - + def prepare_datas(self): tdSql.execute( '''create table stb1 @@ -23,7 +23,7 @@ class TDTestCase: tags (t1 int) ''' ) - + tdSql.execute( ''' create table t1 @@ -65,14 +65,14 @@ class TDTestCase: ( '2023-02-21 01:01:01.000', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL ) ''' ) - + def check_result_auto_atan(self ,origin_query , pow_query): pow_result = tdSql.getResult(pow_query) origin_result = tdSql.getResult(origin_query) auto_result =[] - + for row in origin_result: row_check = [] for elem in row: @@ -90,7 +90,7 @@ class TDTestCase: if auto_result[row_index][col_index] == None and not (auto_result[row_index][col_index] == None and elem == None): check_status = False elif auto_result[row_index][col_index] != None and (auto_result[row_index][col_index] - elem > 0.00000001): - check_status = False + check_status = False else: pass if not check_status: @@ -98,7 +98,7 @@ class TDTestCase: sys.exit(1) else: tdLog.info("atan value check pass , it work as expected ,sql is \"%s\" "%pow_query ) - + def test_errors(self): error_sql_lists = [ "select atan from t1", @@ -132,42 +132,42 @@ class TDTestCase: ] for error_sql in error_sql_lists: tdSql.error(error_sql) - + def support_types(self): type_error_sql_lists = [ - "select atan(ts) from t1" , + "select atan(ts) from t1" , "select atan(c7) from t1", "select atan(c8) from t1", "select atan(c9) from t1", - "select atan(ts) from ct1" , + "select atan(ts) from ct1" , "select atan(c7) from ct1", "select atan(c8) from ct1", "select atan(c9) from ct1", - "select atan(ts) from ct3" , + "select atan(ts) from ct3" , "select atan(c7) from ct3", "select atan(c8) from ct3", "select atan(c9) from ct3", - "select atan(ts) from ct4" , + "select atan(ts) from ct4" , "select atan(c7) from ct4", "select atan(c8) from ct4", "select atan(c9) from ct4", - "select atan(ts) from stb1" , + "select atan(ts) from stb1" , "select atan(c7) from stb1", "select atan(c8) from stb1", "select atan(c9) from stb1" , - "select atan(ts) from stbbb1" , + "select atan(ts) from stbbb1" , "select atan(c7) from stbbb1", "select atan(ts) from tbname", "select atan(c9) from tbname" ] - + for type_sql in type_error_sql_lists: tdSql.error(type_sql) - - + + type_sql_lists = [ "select atan(c1) from t1", "select atan(c2) from t1", @@ -197,16 +197,16 @@ class TDTestCase: "select atan(c5) from stb1", "select atan(c6) from stb1", - "select atan(c6) as alisb from stb1", - "select atan(c6) alisb from stb1", + "select atan(c6) as alisb from stb1", + "select atan(c6) alisb from stb1", ] for type_sql in type_sql_lists: tdSql.query(type_sql) - + def basic_atan_function(self): - # basic query + # basic query tdSql.query("select c1 from ct3") tdSql.checkRows(0) tdSql.query("select c1 from t1") @@ -247,7 +247,7 @@ class TDTestCase: tdSql.checkData(5, 5, None) self.check_result_auto_atan( "select abs(c1), abs(c2), abs(c3) , abs(c4), abs(c5) from t1", "select atan(abs(c1)), atan(abs(c2)) ,atan(abs(c3)), atan(abs(c4)), atan(abs(c5)) from t1") - + # used for sub table tdSql.query("select c2 ,atan(c2) from ct1") tdSql.checkData(0, 1, 1.570785077) @@ -263,7 +263,7 @@ class TDTestCase: tdSql.checkData(5 , 2, None) self.check_result_auto_atan( "select c1, c2, c3 , c4, c5 from ct1", "select atan(c1), atan(c2) ,atan(c3), atan(c4), atan(c5) from ct1") - + # nest query for atan functions tdSql.query("select c4 , atan(c4) ,atan(atan(c4)) , atan(atan(atan(c4))) from ct1;") tdSql.checkData(0 , 0 , 88) @@ -281,21 +281,21 @@ class TDTestCase: tdSql.checkData(11 , 2 , -1.000958403) tdSql.checkData(11 , 3 , -0.785877135) - # used for stable table - + # used for stable table + tdSql.query("select atan(c1) from stb1") tdSql.checkRows(25) - + # used for not exists table tdSql.error("select atan(c1) from stbbb1") tdSql.error("select atan(c1) from tbname") tdSql.error("select atan(c1) from ct5") - # mix with common col + # mix with common col tdSql.query("select c1, atan(c1) from ct1") tdSql.query("select c2, atan(c2) from ct4") - + # mix with common functions tdSql.query("select c1, atan(c1),atan(c1), atan(atan(c1)) from ct4 ") @@ -303,7 +303,7 @@ class TDTestCase: tdSql.checkData(0 , 1 ,None) tdSql.checkData(0 , 2 ,None) tdSql.checkData(0 , 3 ,None) - + tdSql.checkData(3 , 0 , 6) tdSql.checkData(3 , 1 ,1.405647649) tdSql.checkData(3 , 2 ,1.405647649) @@ -324,8 +324,8 @@ class TDTestCase: tdSql.query("select max(c5), count(c5) from stb1") tdSql.query("select max(c5), count(c5) from ct1") - - # # bug fix for compute + + # # bug fix for compute tdSql.query("select c1, atan(c1) -0 ,atan(c1-4)-0 from ct4 ") tdSql.checkData(0, 0, None) tdSql.checkData(0, 1, None) @@ -394,10 +394,10 @@ class TDTestCase: tdSql.checkData(0,3,0.000000000) tdSql.checkData(0,4,-0.100000000) tdSql.checkData(0,5,0.000000000) - + def pow_Arithmetic(self): pass - + def check_boundary_values(self): PI=3.1415926 @@ -426,11 +426,11 @@ class TDTestCase: f"insert into sub1_bound values ( now()+1s, 2147483648, 9223372036854775808, 32768, 128, 3.40E+38, 1.7e+308, True, 'binary_tb1', 'nchar_tb1', now() )" ) self.check_result_auto_atan( "select abs(c1), abs(c2), abs(c3) , abs(c4), abs(c5) from sub1_bound ", "select atan(abs(c1)), atan(abs(c2)) ,atan(abs(c3)), atan(abs(c4)), atan(abs(c5)) from sub1_bound") - + self.check_result_auto_atan( "select c1, c2, c3 , c3, c2 ,c1 from sub1_bound ", "select atan(c1), atan(c2) ,atan(c3), atan(c3), atan(c2) ,atan(c1) from sub1_bound") self.check_result_auto_atan("select abs(abs(abs(abs(abs(abs(abs(abs(abs(c1))))))))) nest_col_func from sub1_bound" , "select atan(abs(c1)) from sub1_bound" ) - + # check basic elem for table per row tdSql.query("select atan(abs(c1)) ,atan(abs(c2)) , atan(abs(c3)) , atan(abs(c4)), atan(abs(c5)), atan(abs(c6)) from sub1_bound ") tdSql.checkData(0,0,math.atan(2147483647)) @@ -490,36 +490,36 @@ class TDTestCase: self.check_result_auto_atan( " select t1,c5 from stb1 where c1 > 0 order by tbname " , "select atan(t1) ,atan(c5) from stb1 where c1 > 0 order by tbname" ) self.check_result_auto_atan( " select t1,c5 from stb1 where c1 > 0 order by tbname " , "select atan(t1) , atan(c5) from stb1 where c1 > 0 order by tbname" ) pass - + def run(self): # sourcery skip: extract-duplicate-method, remove-redundant-fstring tdSql.prepare() tdLog.printNoPrefix("==========step1:create table ==============") - + self.prepare_datas() - tdLog.printNoPrefix("==========step2:test errors ==============") + tdLog.printNoPrefix("==========step2:test errors ==============") self.test_errors() - - tdLog.printNoPrefix("==========step3:support types ============") + + tdLog.printNoPrefix("==========step3:support types ============") self.support_types() - tdLog.printNoPrefix("==========step4: atan basic query ============") + tdLog.printNoPrefix("==========step4: atan basic query ============") self.basic_atan_function() - tdLog.printNoPrefix("==========step5: big number atan query ============") + tdLog.printNoPrefix("==========step5: big number atan query ============") self.test_big_number() - tdLog.printNoPrefix("==========step6: atan boundary query ============") + tdLog.printNoPrefix("==========step6: atan boundary query ============") self.check_boundary_values() - tdLog.printNoPrefix("==========step7: atan filter query ============") + tdLog.printNoPrefix("==========step7: atan filter query ============") self.abs_func_filter() @@ -527,7 +527,7 @@ class TDTestCase: self.support_super_table_test() - + def stop(self): tdSql.close() -- GitLab From 5917c740368efc9add7d9b248a3f7db5c47c5893 Mon Sep 17 00:00:00 2001 From: Ganlin Zhao Date: Wed, 13 Jul 2022 14:41:50 +0800 Subject: [PATCH 042/153] fix test cases --- tests/system-test/2-query/elapsed.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/system-test/2-query/elapsed.py b/tests/system-test/2-query/elapsed.py index d2f1331e00..333c60286e 100644 --- a/tests/system-test/2-query/elapsed.py +++ b/tests/system-test/2-query/elapsed.py @@ -894,7 +894,7 @@ class TDTestCase: tdSql.query(sql_common) results= query_datas[0] if operator == "+": - for data in query_datas[1:]: + for data in query_datas[1:]: results += data tdSql.checkData(0,0,results) -- GitLab From 2bc95eeb5f0b3426dabfe6dc7bb8a015552e64ad Mon Sep 17 00:00:00 2001 From: Ganlin Zhao Date: Wed, 13 Jul 2022 14:41:50 +0800 Subject: [PATCH 043/153] fix test cases --- tests/system-test/2-query/nestedQuery_str.py | 3500 +++++++++--------- 1 file changed, 1750 insertions(+), 1750 deletions(-) diff --git a/tests/system-test/2-query/nestedQuery_str.py b/tests/system-test/2-query/nestedQuery_str.py index 6244b37ba4..0d40ef8147 100755 --- a/tests/system-test/2-query/nestedQuery_str.py +++ b/tests/system-test/2-query/nestedQuery_str.py @@ -24,10 +24,10 @@ from util.dnodes import tdDnodes from util.dnodes import * class TDTestCase: - updatecfgDict = {'maxSQLLength':1048576,'debugFlag': 143 ,"cDebugFlag":143,"uDebugFlag":143 ,"rpcDebugFlag":143 , "tmrDebugFlag":143 , + updatecfgDict = {'maxSQLLength':1048576,'debugFlag': 143 ,"cDebugFlag":143,"uDebugFlag":143 ,"rpcDebugFlag":143 , "tmrDebugFlag":143 , "jniDebugFlag":143 ,"simDebugFlag":143,"dDebugFlag":143, "dDebugFlag":143,"vDebugFlag":143,"mDebugFlag":143,"qDebugFlag":143, "wDebugFlag":143,"sDebugFlag":143,"tsdbDebugFlag":143,"tqDebugFlag":143 ,"fsDebugFlag":143 ,"udfDebugFlag":143} - + def init(self, conn, logSql): tdLog.debug("start to execute %s" % __file__) tdSql.init(conn.cursor(), logSql) @@ -35,13 +35,13 @@ class TDTestCase: self.testcasePath = os.path.split(__file__)[0] self.testcaseFilename = os.path.split(__file__)[-1] os.system("rm -rf %s/%s.sql" % (self.testcasePath,self.testcaseFilename)) - + self.num = 10 self.fornum = 5 - + self.db_nest = "nest" self.dropandcreateDB_random("%s" %self.db_nest, 1) - + # regular column select #q_select= ['ts' , '*' , 'q_int', 'q_bigint' , 'q_bigint' , 'q_smallint' , 'q_tinyint' , 'q_bool' , 'q_binary' , 'q_nchar' ,'q_float' , 'q_double' ,'q_ts '] self.q_select= ['ts' , 'q_int', 'q_bigint' , 'q_bigint' , 'q_smallint' , 'q_tinyint' , 'q_bool' , 'q_binary' , 'q_nchar' ,'q_float' , 'q_double' ,'q_ts ', 'q_int_null ', 'q_bigint_null ' , 'q_bigint_null ' , 'q_smallint_null ' , 'q_tinyint_null ' , 'q_bool_null ' , 'q_binary_null ' , 'q_nchar_null ' ,'q_float_null ' , 'q_double_null ' ,'q_ts_null '] @@ -54,11 +54,11 @@ class TDTestCase: self.qt_select= self.q_select + self.t_select # distinct regular column select - self.dq_select= ['distinct q_int', 'distinct q_bigint' , 'distinct q_smallint' , 'distinct q_tinyint' , + self.dq_select= ['distinct q_int', 'distinct q_bigint' , 'distinct q_smallint' , 'distinct q_tinyint' , 'distinct q_bool' , 'distinct q_binary' , 'distinct q_nchar' ,'distinct q_float' , 'distinct q_double' ,'distinct q_ts '] # distinct tag column select - self.dt_select= ['distinct loc', 'distinct t_int', 'distinct t_bigint' , 'distinct t_smallint' , 'distinct t_tinyint' , + self.dt_select= ['distinct loc', 'distinct t_int', 'distinct t_bigint' , 'distinct t_smallint' , 'distinct t_tinyint' , 'distinct t_bool' , 'distinct t_binary' , 'distinct t_nchar' ,'distinct t_float' , 'distinct t_double' ,'distinct t_ts '] # distinct regular and tag column select @@ -69,13 +69,13 @@ class TDTestCase: self.s_s_select= ['tbname' , '_rowts' , '_c0', '_C0' ] self.unionall_or_union= [ ' union ' , ' union all ' ] - # regular column where + # regular column where self.q_where = ['ts < now +1s','q_bigint >= -9223372036854775807 and q_bigint <= 9223372036854775807', 'q_int <= 2147483647 and q_int >= -2147483647', - 'q_smallint >= -32767 and q_smallint <= 32767','q_tinyint >= -127 and q_tinyint <= 127','q_float >= -1.7E308 and q_float <= 1.7E308', - 'q_double >= -1.7E308 and q_double <= 1.7E308', 'q_binary like \'binary%\' or q_binary = \'0\' ' , 'q_nchar like \'nchar%\' or q_nchar = \'0\' ' , + 'q_smallint >= -32767 and q_smallint <= 32767','q_tinyint >= -127 and q_tinyint <= 127','q_float >= -1.7E308 and q_float <= 1.7E308', + 'q_double >= -1.7E308 and q_double <= 1.7E308', 'q_binary like \'binary%\' or q_binary = \'0\' ' , 'q_nchar like \'nchar%\' or q_nchar = \'0\' ' , 'q_bool = true or q_bool = false' , 'q_bool in (0 , 1)' , 'q_bool in ( true , false)' , 'q_bool = 0 or q_bool = 1', - 'q_bigint between -9223372036854775807 and 9223372036854775807',' q_int between -2147483647 and 2147483647','q_smallint between -32767 and 32767', - 'q_bigint not between 9223372036854775807 and -9223372036854775807','q_int not between 2147483647 and -2147483647','q_smallint not between 32767 and -32767', + 'q_bigint between -9223372036854775807 and 9223372036854775807',' q_int between -2147483647 and 2147483647','q_smallint between -32767 and 32767', + 'q_bigint not between 9223372036854775807 and -9223372036854775807','q_int not between 2147483647 and -2147483647','q_smallint not between 32767 and -32767', 'q_tinyint between -127 and 127 ','q_float >= -3.4E38 ','q_float <= 3.4E38 ','q_double >= -1.7E308 ', 'q_double <= 1.7E308 ','q_float between -3.4E38 and 3.4E38 ','q_double between -1.7E308 and 1.7E308 ' ,'q_float not between 3.4E38 and -3.4E38 ','q_double not between 1.7E308 and -1.7E308 ', 'q_float is not null ' ,'q_double is not null ' ,'q_binary match \'binary\' ','q_binary nmatch \'binarynchar\' ','q_nchar match \'nchar\' ','q_nchar nmatch \'binarynchar\' ', @@ -88,38 +88,38 @@ class TDTestCase: 't1.q_smallint >= -32767 and t1.q_smallint <= 32767 and t2.q_smallint >= -32767 and t2.q_smallint <= 32767', 't1.q_tinyint >= -127 and t1.q_tinyint <= 127 and t2.q_tinyint >= -127 and t2.q_tinyint <= 127', 't1.q_float >= - 1.7E308 and t1.q_float <= 1.7E308 and t2.q_float >= - 1.7E308 and t2.q_float <= 1.7E308', - 't1.q_double >= - 1.7E308 and t1.q_double <= 1.7E308 and t2.q_double >= - 1.7E308 and t2.q_double <= 1.7E308', - 't1.q_binary like \'binary%\' and t2.q_binary like \'binary%\' ' , - 't1.q_nchar like \'nchar%\' and t2.q_nchar like \'nchar%\' ' , - 't1.q_bool in (0 , 1) and t2.q_bool in (0 , 1)' , 't1.q_bool in ( true , false) and t2.q_bool in ( true , false)' , + 't1.q_double >= - 1.7E308 and t1.q_double <= 1.7E308 and t2.q_double >= - 1.7E308 and t2.q_double <= 1.7E308', + 't1.q_binary like \'binary%\' and t2.q_binary like \'binary%\' ' , + 't1.q_nchar like \'nchar%\' and t2.q_nchar like \'nchar%\' ' , + 't1.q_bool in (0 , 1) and t2.q_bool in (0 , 1)' , 't1.q_bool in ( true , false) and t2.q_bool in ( true , false)' , 't1.q_bigint between -9223372036854775807 and 9223372036854775807 and t2.q_bigint between -9223372036854775807 and 9223372036854775807', 't1.q_int between -2147483647 and 2147483647 and t2.q_int between -2147483647 and 2147483647', - 't1.q_smallint between -32767 and 32767 and t2.q_smallint between -32767 and 32767', + 't1.q_smallint between -32767 and 32767 and t2.q_smallint between -32767 and 32767', 't1.q_tinyint between -127 and 127 and t2.q_tinyint between -127 and 127 ','t1.q_float between -1.7E308 and 1.7E308 and t2.q_float between -1.7E308 and 1.7E308', 't1.q_double between -1.7E308 and 1.7E308 and t2.q_double between -1.7E308 and 1.7E308', 't1.q_bigint not between 9223372036854775807 and -9223372036854775807 and t2.q_bigint not between 9223372036854775807 and -9223372036854775807', 't1.q_int not between 2147483647 and -2147483647 and t2.q_int not between 2147483647 and -2147483647', - 't1.q_smallint not between 32767 and -32767 and t2.q_smallint not between 32767 and -32767', + 't1.q_smallint not between 32767 and -32767 and t2.q_smallint not between 32767 and -32767', 't1.q_tinyint not between 127 and -127 and t2.q_tinyint not between 127 and -127 ','t1.q_float not between -1.7E308 and -1.7E308 and t2.q_float not between 1.7E308 and -1.7E308', 't1.q_double not between 1.7E308 and -1.7E308 and t2.q_double not between 1.7E308 and -1.7E308'] #TD-6201 ,'t1.q_bool between 0 and 1 or t2.q_bool between 0 and 1'] #'t1.q_bool = true and t1.q_bool = false and t2.q_bool = true and t2.q_bool = false' , 't1.q_bool = 0 and t1.q_bool = 1 and t2.q_bool = 0 and t2.q_bool = 1' , - self.q_u_or_where = ['(t1.q_binary like \'binary%\' or t1.q_binary = \'0\' or t2.q_binary like \'binary%\' or t2.q_binary = \'0\' )' , - '(t1.q_nchar like \'nchar%\' or t1.q_nchar = \'0\' or t2.q_nchar like \'nchar%\' or t2.q_nchar = \'0\' )' , '(t1.q_bool = true or t1.q_bool = false or t2.q_bool = true or t2.q_bool = false)' , + self.q_u_or_where = ['(t1.q_binary like \'binary%\' or t1.q_binary = \'0\' or t2.q_binary like \'binary%\' or t2.q_binary = \'0\' )' , + '(t1.q_nchar like \'nchar%\' or t1.q_nchar = \'0\' or t2.q_nchar like \'nchar%\' or t2.q_nchar = \'0\' )' , '(t1.q_bool = true or t1.q_bool = false or t2.q_bool = true or t2.q_bool = false)' , '(t1.q_bool in (0 , 1) or t2.q_bool in (0 , 1))' , '(t1.q_bool in ( true , false) or t2.q_bool in ( true , false))' , '(t1.q_bool = 0 or t1.q_bool = 1 or t2.q_bool = 0 or t2.q_bool = 1)' , '(t1.q_bigint between -9223372036854775807 and 9223372036854775807 or t2.q_bigint between -9223372036854775807 and 9223372036854775807)', '(t1.q_int between -2147483647 and 2147483647 or t2.q_int between -2147483647 and 2147483647)', - '(t1.q_smallint between -32767 and 32767 or t2.q_smallint between -32767 and 32767)', + '(t1.q_smallint between -32767 and 32767 or t2.q_smallint between -32767 and 32767)', '(t1.q_tinyint between -127 and 127 or t2.q_tinyint between -127 and 127 )','(t1.q_float between -1.7E308 and 1.7E308 or t2.q_float between -1.7E308 and 1.7E308)', '(t1.q_double between -1.7E308 and 1.7E308 or t2.q_double between -1.7E308 and 1.7E308)'] # tag column where self.t_where = ['ts < now +1s','t_bigint >= -9223372036854775807 and t_bigint <= 9223372036854775807','t_int <= 2147483647 and t_int >= -2147483647', 't_smallint >= -32767 and t_smallint <= 32767','q_tinyint >= -127 and t_tinyint <= 127','t_float >= -1.7E308 and t_float <= 1.7E308', - 't_double >= -1.7E308 and t_double <= 1.7E308', 't_binary like \'binary%\' or t_binary = \'0\' ' , 't_nchar like \'nchar%\' or t_nchar = \'0\'' , + 't_double >= -1.7E308 and t_double <= 1.7E308', 't_binary like \'binary%\' or t_binary = \'0\' ' , 't_nchar like \'nchar%\' or t_nchar = \'0\'' , 't_bool = true or t_bool = false' , 't_bool in (0 , 1)' , 't_bool in ( true , false)' , 't_bool = 0 or t_bool = 1', - 't_bigint between -9223372036854775807 and 9223372036854775807',' t_int between -2147483647 and 2147483647','t_smallint between -32767 and 32767', + 't_bigint between -9223372036854775807 and 9223372036854775807',' t_int between -2147483647 and 2147483647','t_smallint between -32767 and 32767', 't_tinyint between -127 and 127 ','t_float between -1.7E308 and 1.7E308','t_double between -1.7E308 and 1.7E308', 't_binary match \'binary\' ','t_binary nmatch \'binarynchar\' ','t_nchar match \'nchar\' ','t_nchar nmatch \'binarynchar\' ', 't_binary like \'binary%\' ','t_nchar like \'nchar%\' ','(t_binary like \'binary%\' or t_nchar = \'0\' ) ','(t_nchar like \'nchar%\' or t_binary = \'0\' ) ',] @@ -131,27 +131,27 @@ class TDTestCase: 't1.t_smallint >= -32767 and t1.t_smallint <= 32767 and t2.t_smallint >= -32767 and t2.t_smallint <= 32767', 't1.t_tinyint >= -127 and t1.t_tinyint <= 127 and t2.t_tinyint >= -127 and t2.t_tinyint <= 127', 't1.t_float >= -1.7E308 and t1.t_float <= 1.7E308 and t2.t_float >= -1.7E308 and t2.t_float <= 1.7E308', - 't1.t_double >= -1.7E308 and t1.t_double <= 1.7E308 and t2.t_double >= -1.7E308 and t2.t_double <= 1.7E308', - '(t1.t_binary like \'binary%\' or t1.t_binary = \'0\' or t2.t_binary like \'binary%\' or t2.t_binary = \'0\') ' , - '(t1.t_nchar like \'nchar%\' or t1.t_nchar = \'0\' or t2.t_nchar like \'nchar%\' or t2.t_nchar = \'0\' )' , '(t1.t_bool = true or t1.t_bool = false or t2.t_bool = true or t2.t_bool = false)' , + 't1.t_double >= -1.7E308 and t1.t_double <= 1.7E308 and t2.t_double >= -1.7E308 and t2.t_double <= 1.7E308', + '(t1.t_binary like \'binary%\' or t1.t_binary = \'0\' or t2.t_binary like \'binary%\' or t2.t_binary = \'0\') ' , + '(t1.t_nchar like \'nchar%\' or t1.t_nchar = \'0\' or t2.t_nchar like \'nchar%\' or t2.t_nchar = \'0\' )' , '(t1.t_bool = true or t1.t_bool = false or t2.t_bool = true or t2.t_bool = false)' , 't1.t_bool in (0 , 1) and t2.t_bool in (0 , 1)' , 't1.t_bool in ( true , false) and t2.t_bool in ( true , false)' , '(t1.t_bool = 0 or t1.t_bool = 1 or t2.t_bool = 0 or t2.t_bool = 1)', 't1.t_bigint between -9223372036854775807 and 9223372036854775807 and t2.t_bigint between -9223372036854775807 and 9223372036854775807', 't1.t_int between -2147483647 and 2147483647 and t2.t_int between -2147483647 and 2147483647', - 't1.t_smallint between -32767 and 32767 and t2.t_smallint between -32767 and 32767', + 't1.t_smallint between -32767 and 32767 and t2.t_smallint between -32767 and 32767', '(t1.t_tinyint between -127 and 127 and t2.t_tinyint between -127 and 127) ','t1.t_float between -1.7E308 and 1.7E308 and t2.t_float between -1.7E308 and 1.7E308', '(t1.t_double between -1.7E308 and 1.7E308 and t2.t_double between -1.7E308 and 1.7E308)'] #TD-6201,'t1.t_bool between 0 and 1 or t2.q_bool between 0 and 1'] - self.t_u_or_where = ['(t1.t_binary like \'binary%\' or t1.t_binary = \'0\' or t2.t_binary like \'binary%\' or t2.t_binary = \'0\' )' , - '(t1.t_nchar like \'nchar%\' or t1.t_nchar = \'0\' or t2.t_nchar like \'nchar%\' or t2.t_nchar = \'0\' )' , '(t1.t_bool = true or t1.t_bool = false or t2.t_bool = true or t2.t_bool = false)' , + self.t_u_or_where = ['(t1.t_binary like \'binary%\' or t1.t_binary = \'0\' or t2.t_binary like \'binary%\' or t2.t_binary = \'0\' )' , + '(t1.t_nchar like \'nchar%\' or t1.t_nchar = \'0\' or t2.t_nchar like \'nchar%\' or t2.t_nchar = \'0\' )' , '(t1.t_bool = true or t1.t_bool = false or t2.t_bool = true or t2.t_bool = false)' , '(t1.t_bool in (0 , 1) or t2.t_bool in (0 , 1))' , '(t1.t_bool in ( true , false) or t2.t_bool in ( true , false))' , '(t1.t_bool = 0 or t1.t_bool = 1 or t2.t_bool = 0 or t2.t_bool = 1)', '(t1.t_bigint between -9223372036854775807 and 9223372036854775807 or t2.t_bigint between -9223372036854775807 and 9223372036854775807)', '(t1.t_int between -2147483647 and 2147483647 or t2.t_int between -2147483647 and 2147483647)', - '(t1.t_smallint between -32767 and 32767 or t2.t_smallint between -32767 and 32767)', + '(t1.t_smallint between -32767 and 32767 or t2.t_smallint between -32767 and 32767)', '(t1.t_tinyint between -127 and 127 or t2.t_tinyint between -127 and 127 )','(t1.t_float between -1.7E308 and 1.7E308 or t2.t_float between -1.7E308 and 1.7E308)', '(t1.t_double between -1.7E308 and 1.7E308 or t2.t_double between -1.7E308 and 1.7E308)'] - # regular and tag column where + # regular and tag column where self.qt_where = self.q_where + self.t_where self.qt_u_where = self.q_u_where + self.t_u_where # now,qt_u_or_where is not support @@ -165,78 +165,78 @@ class TDTestCase: self.session_where = ['session(ts,10a)' , 'session(ts,10s)', 'session(ts,10m)' , 'session(ts,10h)','session(ts,10d)' , 'session(ts,10w)'] self.session_u_where = ['session(t1.ts,10a)' , 'session(t1.ts,10s)', 'session(t1.ts,10m)' , 'session(t1.ts,10h)','session(t1.ts,10d)' , 'session(t1.ts,10w)', 'session(t2.ts,10a)' , 'session(t2.ts,10s)', 'session(t2.ts,10m)' , 'session(t2.ts,10h)','session(t2.ts,10d)' , 'session(t2.ts,10w)'] - + self.fill_where = ['FILL(NONE)','FILL(PREV)','FILL(NULL)','FILL(LINEAR)','FILL(NEXT)','FILL(VALUE, 1.23)'] - + self.state_window = ['STATE_WINDOW(q_tinyint)','STATE_WINDOW(q_bigint)','STATE_WINDOW(q_int)','STATE_WINDOW(q_bool)','STATE_WINDOW(q_smallint)'] self.state_u_window = ['STATE_WINDOW(t1.q_tinyint)','STATE_WINDOW(t1.q_bigint)','STATE_WINDOW(t1.q_int)','STATE_WINDOW(t1.q_bool)','STATE_WINDOW(t1.q_smallint)', 'STATE_WINDOW(t2.q_tinyint)','STATE_WINDOW(t2.q_bigint)','STATE_WINDOW(t2.q_int)','STATE_WINDOW(t2.q_bool)','STATE_WINDOW(t2.q_smallint)'] - # order by where + # order by where self.order_where = ['order by ts' , 'order by ts asc'] self.order_u_where = ['order by t1.ts' , 'order by t1.ts asc' , 'order by t2.ts' , 'order by t2.ts asc'] self.order_desc_where = ['order by ts' , 'order by ts asc' , 'order by ts desc' ] self.orders_desc_where = ['order by ts' , 'order by ts asc' , 'order by ts desc' , 'order by loc' , 'order by loc asc' , 'order by loc desc'] - - self.group_where = ['group by tbname , loc' , 'group by tbname', 'group by tbname, t_bigint', 'group by tbname,t_int', 'group by tbname, t_smallint', 'group by tbname,t_tinyint', + + self.group_where = ['group by tbname , loc' , 'group by tbname', 'group by tbname, t_bigint', 'group by tbname,t_int', 'group by tbname, t_smallint', 'group by tbname,t_tinyint', 'group by tbname,t_float', 'group by tbname,t_double' , 'group by tbname,t_binary', 'group by tbname,t_nchar', 'group by tbname,t_bool' ,'group by tbname ,loc ,t_bigint', 'group by tbname,t_binary ,t_nchar ,t_bool' , 'group by tbname,t_int ,t_smallint ,t_tinyint' , 'group by tbname,t_float ,t_double ' , - 'PARTITION BY tbname , loc' , 'PARTITION BY tbname', 'PARTITION BY tbname, t_bigint', 'PARTITION BY tbname,t_int', 'PARTITION BY tbname, t_smallint', 'PARTITION BY tbname,t_tinyint', + 'PARTITION BY tbname , loc' , 'PARTITION BY tbname', 'PARTITION BY tbname, t_bigint', 'PARTITION BY tbname,t_int', 'PARTITION BY tbname, t_smallint', 'PARTITION BY tbname,t_tinyint', 'PARTITION BY tbname,t_float', 'PARTITION BY tbname,t_double' , 'PARTITION BY tbname,t_binary', 'PARTITION BY tbname,t_nchar', 'PARTITION BY tbname,t_bool' ,'PARTITION BY tbname ,loc ,t_bigint', 'PARTITION BY tbname,t_binary ,t_nchar ,t_bool' , 'PARTITION BY tbname,t_int ,t_smallint ,t_tinyint' , 'PARTITION BY tbname,t_float ,t_double '] - self.group_where_j = ['group by t1.loc' , 'group by t1.t_bigint', 'group by t1.t_int', 'group by t1.t_smallint', 'group by t1.t_tinyint', + self.group_where_j = ['group by t1.loc' , 'group by t1.t_bigint', 'group by t1.t_int', 'group by t1.t_smallint', 'group by t1.t_tinyint', 'group by t1.t_float', 'group by t1.t_double' , 'group by t1.t_binary', 'group by t1.t_nchar', 'group by t1.t_bool' ,'group by t1.loc ,t1.t_bigint', 'group by t1.t_binary ,t1.t_nchar ,t1.t_bool' , 'group by t1.t_int ,t1.t_smallint ,t1.t_tinyint' , 'group by t1.t_float ,t1.t_double ' , - 'PARTITION BY t1.loc' , 'PARTITION by t1.t_bigint', 'PARTITION by t1.t_int', 'PARTITION by t1.t_smallint', 'PARTITION by t1.t_tinyint', + 'PARTITION BY t1.loc' , 'PARTITION by t1.t_bigint', 'PARTITION by t1.t_int', 'PARTITION by t1.t_smallint', 'PARTITION by t1.t_tinyint', 'PARTITION by t1.t_float', 'PARTITION by t1.t_double' , 'PARTITION by t1.t_binary', 'PARTITION by t1.t_nchar', 'PARTITION by t1.t_bool' ,'PARTITION BY t1.loc ,t1.t_bigint', 'PARTITION by t1.t_binary ,t1.t_nchar ,t1.t_bool' , 'PARTITION by t1.t_int ,t1.t_smallint ,t1.t_tinyint' , 'PARTITION by t1.t_float ,t1.t_double ', - 'group by t2.loc' , 'group by t2.t_bigint', 'group by t2.t_int', 'group by t2.t_smallint', 'group by t2.t_tinyint', + 'group by t2.loc' , 'group by t2.t_bigint', 'group by t2.t_int', 'group by t2.t_smallint', 'group by t2.t_tinyint', 'group by t2.t_float', 'group by t2.t_double' , 'group by t2.t_binary', 'group by t2.t_nchar', 'group by t2.t_bool' ,'group by t2.loc ,t2.t_bigint', 'group by t2.t_binary ,t2.t_nchar ,t2.t_bool' , 'group by t2.t_int ,t2.t_smallint ,t2.t_tinyint' , 'group by t2.t_float ,t2.t_double ' , - 'PARTITION BY t2.loc' , 'PARTITION by t2.t_bigint', 'PARTITION by t2.t_int', 'PARTITION by t2.t_smallint', 'PARTITION by t2.t_tinyint', + 'PARTITION BY t2.loc' , 'PARTITION by t2.t_bigint', 'PARTITION by t2.t_int', 'PARTITION by t2.t_smallint', 'PARTITION by t2.t_tinyint', 'PARTITION by t2.t_float', 'PARTITION by t2.t_double' , 'PARTITION by t2.t_binary', 'PARTITION by t2.t_nchar', 'PARTITION by t2.t_bool' ,'PARTITION BY t2.loc ,t2.t_bigint', - 'PARTITION by t2.t_binary ,t2.t_nchar ,t2.t_bool' , 'PARTITION by t2.t_int ,t2.t_smallint ,t2.t_tinyint' , 'PARTITION by t2.t_float ,t2.t_double '] - - self.partiton_where = ['PARTITION BY tbname , loc' , 'PARTITION BY tbname', 'PARTITION BY tbname, t_bigint', 'PARTITION BY tbname,t_int', 'PARTITION BY tbname, t_smallint', 'PARTITION BY tbname,t_tinyint', + 'PARTITION by t2.t_binary ,t2.t_nchar ,t2.t_bool' , 'PARTITION by t2.t_int ,t2.t_smallint ,t2.t_tinyint' , 'PARTITION by t2.t_float ,t2.t_double '] + + self.partiton_where = ['PARTITION BY tbname , loc' , 'PARTITION BY tbname', 'PARTITION BY tbname, t_bigint', 'PARTITION BY tbname,t_int', 'PARTITION BY tbname, t_smallint', 'PARTITION BY tbname,t_tinyint', 'PARTITION BY tbname,t_float', 'PARTITION BY tbname,t_double' , 'PARTITION BY tbname,t_binary', 'PARTITION BY tbname,t_nchar', 'PARTITION BY tbname,t_bool' ,'PARTITION BY tbname ,loc ,t_bigint', 'PARTITION BY tbname,t_binary ,t_nchar ,t_bool' , 'PARTITION BY tbname,t_int ,t_smallint ,t_tinyint' , 'PARTITION BY tbname,t_float ,t_double '] - self.partiton_where_j = ['PARTITION BY t1.loc' , 'PARTITION by t1.t_bigint', 'PARTITION by t1.t_int', 'PARTITION by t1.t_smallint', 'PARTITION by t1.t_tinyint', + self.partiton_where_j = ['PARTITION BY t1.loc' , 'PARTITION by t1.t_bigint', 'PARTITION by t1.t_int', 'PARTITION by t1.t_smallint', 'PARTITION by t1.t_tinyint', 'PARTITION by t1.t_float', 'PARTITION by t1.t_double' , 'PARTITION by t1.t_binary', 'PARTITION by t1.t_nchar', 'PARTITION by t1.t_bool' ,'PARTITION BY t1.loc ,t1.t_bigint', 'PARTITION by t1.t_binary ,t1.t_nchar ,t1.t_bool' , 'PARTITION by t1.t_int ,t1.t_smallint ,t1.t_tinyint' , 'PARTITION by t1.t_float ,t1.t_double ', - 'PARTITION BY t2.loc' , 'PARTITION by t2.t_bigint', 'PARTITION by t2.t_int', 'PARTITION by t2.t_smallint', 'PARTITION by t2.t_tinyint', + 'PARTITION BY t2.loc' , 'PARTITION by t2.t_bigint', 'PARTITION by t2.t_int', 'PARTITION by t2.t_smallint', 'PARTITION by t2.t_tinyint', 'PARTITION by t2.t_float', 'PARTITION by t2.t_double' , 'PARTITION by t2.t_binary', 'PARTITION by t2.t_nchar', 'PARTITION by t2.t_bool' ,'PARTITION BY t2.loc ,t2.t_bigint', - 'PARTITION by t2.t_binary ,t2.t_nchar ,t2.t_bool' , 'PARTITION by t2.t_int ,t2.t_smallint ,t2.t_tinyint' , 'PARTITION by t2.t_float ,t2.t_double '] + 'PARTITION by t2.t_binary ,t2.t_nchar ,t2.t_bool' , 'PARTITION by t2.t_int ,t2.t_smallint ,t2.t_tinyint' , 'PARTITION by t2.t_float ,t2.t_double '] + - - self.group_where_regular = ['group by tbname ' , 'group by tbname', 'group by tbname, q_bigint', 'group by tbname,q_int', 'group by tbname, q_smallint', 'group by tbname,q_tinyint', + self.group_where_regular = ['group by tbname ' , 'group by tbname', 'group by tbname, q_bigint', 'group by tbname,q_int', 'group by tbname, q_smallint', 'group by tbname,q_tinyint', 'group by tbname,q_float', 'group by tbname,q_double' , 'group by tbname,q_binary', 'group by tbname,q_nchar', 'group by tbname,q_bool' ,'group by tbname ,q_bigint', 'group by tbname,q_binary ,q_nchar ,q_bool' , 'group by tbname,q_int ,q_smallint ,q_tinyint' , 'group by tbname,q_float ,q_double ' , - 'PARTITION BY tbname ' , 'PARTITION BY tbname', 'PARTITION BY tbname, q_bigint', 'PARTITION BY tbname,q_int', 'PARTITION BY tbname, q_smallint', 'PARTITION BY tbname,q_tinyint', + 'PARTITION BY tbname ' , 'PARTITION BY tbname', 'PARTITION BY tbname, q_bigint', 'PARTITION BY tbname,q_int', 'PARTITION BY tbname, q_smallint', 'PARTITION BY tbname,q_tinyint', 'PARTITION BY tbname,q_float', 'PARTITION BY tbname,q_double' , 'PARTITION BY tbname,q_binary', 'PARTITION BY tbname,q_nchar', 'PARTITION BY tbname,q_bool' ,'PARTITION BY tbname ,q_bigint', 'PARTITION BY tbname,q_binary ,q_nchar ,q_bool' , 'PARTITION BY tbname,q_int ,q_smallint ,q_tinyint' , 'PARTITION BY tbname,q_float ,q_double '] - self.group_where_regular_j = ['group by t1.q_bigint', 'group by t1.q_int', 'group by t1.q_smallint', 'group by t1.q_tinyint', + self.group_where_regular_j = ['group by t1.q_bigint', 'group by t1.q_int', 'group by t1.q_smallint', 'group by t1.q_tinyint', 'group by t1.q_float', 'group by t1.q_double' , 'group by t1.q_binary', 'group by t1.q_nchar', 'group by t1.q_bool' ,'group by t1.q_bigint', 'group by t1.q_binary ,t1.q_nchar ,t1.q_bool' , 'group by t1.q_int ,t1.q_smallint ,t1.q_tinyint' , 'group by t1.q_float ,t1.q_double ' , - 'PARTITION by t1.q_bigint', 'PARTITION by t1.q_int', 'PARTITION by t1.q_smallint', 'PARTITION by t1.q_tinyint', + 'PARTITION by t1.q_bigint', 'PARTITION by t1.q_int', 'PARTITION by t1.q_smallint', 'PARTITION by t1.q_tinyint', 'PARTITION by t1.q_float', 'PARTITION by t1.q_double' , 'PARTITION by t1.q_binary', 'PARTITION by t1.q_nchar', 'PARTITION by t1.q_bool' ,'PARTITION BY t1.q_bigint', 'PARTITION by t1.q_binary ,t1.q_nchar ,t1.q_bool' , 'PARTITION by t1.q_int ,t1.q_smallint ,t1.q_tinyint' , 'PARTITION by t1.q_float ,t1.q_double ', - 'group by t2.q_bigint', 'group by t2.q_int', 'group by t2.q_smallint', 'group by t2.q_tinyint', + 'group by t2.q_bigint', 'group by t2.q_int', 'group by t2.q_smallint', 'group by t2.q_tinyint', 'group by t2.q_float', 'group by t2.q_double' , 'group by t2.q_binary', 'group by t2.q_nchar', 'group by t2.q_bool' ,'group by t2.q_bigint', 'group by t2.q_binary ,t2.q_nchar ,t2.q_bool' , 'group by t2.q_int ,t2.q_smallint ,t2.q_tinyint' , 'group by t2.q_float ,t2.q_double ' , - 'PARTITION by t2.q_bigint', 'PARTITION by t2.q_int', 'PARTITION by t2.q_smallint', 'PARTITION by t2.q_tinyint', + 'PARTITION by t2.q_bigint', 'PARTITION by t2.q_int', 'PARTITION by t2.q_smallint', 'PARTITION by t2.q_tinyint', 'PARTITION by t2.q_float', 'PARTITION by t2.q_double' , 'PARTITION by t2.q_binary', 'PARTITION by t2.q_nchar', 'PARTITION by t2.q_bool' ,'PARTITION BY t2.q_bigint', - 'PARTITION by t2.q_binary ,t2.q_nchar ,t2.q_bool' , 'PARTITION by t2.q_int ,t2.q_smallint ,t2.q_tinyint' , 'PARTITION by t2.q_float ,t2.q_double '] - - self.partiton_where_regular = ['PARTITION BY tbname ' , 'PARTITION BY tbname', 'PARTITION BY tbname, q_bigint', 'PARTITION BY tbname,q_int', 'PARTITION BY tbname, q_smallint', 'PARTITION BY tbname,q_tinyint', + 'PARTITION by t2.q_binary ,t2.q_nchar ,t2.q_bool' , 'PARTITION by t2.q_int ,t2.q_smallint ,t2.q_tinyint' , 'PARTITION by t2.q_float ,t2.q_double '] + + self.partiton_where_regular = ['PARTITION BY tbname ' , 'PARTITION BY tbname', 'PARTITION BY tbname, q_bigint', 'PARTITION BY tbname,q_int', 'PARTITION BY tbname, q_smallint', 'PARTITION BY tbname,q_tinyint', 'PARTITION BY tbname,q_float', 'PARTITION BY tbname,q_double' , 'PARTITION BY tbname,q_binary', 'PARTITION BY tbname,q_nchar', 'PARTITION BY tbname,q_bool' ,'PARTITION BY tbname ,q_bigint', 'PARTITION BY tbname,q_binary ,q_nchar ,q_bool' , 'PARTITION BY tbname,q_int ,q_smallint ,q_tinyint' , 'PARTITION BY tbname,q_float ,q_double '] - self.partiton_where_regular_j = ['PARTITION by t1.q_bigint', 'PARTITION by t1.q_int', 'PARTITION by t1.q_smallint', 'PARTITION by t1.q_tinyint', + self.partiton_where_regular_j = ['PARTITION by t1.q_bigint', 'PARTITION by t1.q_int', 'PARTITION by t1.q_smallint', 'PARTITION by t1.q_tinyint', 'PARTITION by t1.q_float', 'PARTITION by t1.q_double' , 'PARTITION by t1.q_binary', 'PARTITION by t1.q_nchar', 'PARTITION by t1.q_bool' ,'PARTITION BY t1.q_bigint', 'PARTITION by t1.q_binary ,t1.q_nchar ,t1.q_bool' , 'PARTITION by t1.q_int ,t1.q_smallint ,t1.q_tinyint' , 'PARTITION by t1.q_float ,t1.q_double ', - 'PARTITION by t2.q_bigint', 'PARTITION by t2.q_int', 'PARTITION by t2.q_smallint', 'PARTITION by t2.q_tinyint', + 'PARTITION by t2.q_bigint', 'PARTITION by t2.q_int', 'PARTITION by t2.q_smallint', 'PARTITION by t2.q_tinyint', 'PARTITION by t2.q_float', 'PARTITION by t2.q_double' , 'PARTITION by t2.q_binary', 'PARTITION by t2.q_nchar', 'PARTITION by t2.q_bool' ,'PARTITION BY t2.q_bigint', - 'PARTITION by t2.q_binary ,t2.q_nchar ,t2.q_bool' , 'PARTITION by t2.q_int ,t2.q_smallint ,t2.q_tinyint' , 'PARTITION by t2.q_float ,t2.q_double '] - + 'PARTITION by t2.q_binary ,t2.q_nchar ,t2.q_bool' , 'PARTITION by t2.q_int ,t2.q_smallint ,t2.q_tinyint' , 'PARTITION by t2.q_float ,t2.q_double '] + self.having_support = ['having count(q_int) > 0','having count(q_bigint) > 0','having count(q_smallint) > 0','having count(q_tinyint) > 0','having count(q_float) > 0','having count(q_double) > 0','having count(q_bool) > 0', 'having avg(q_int) > 0','having avg(q_bigint) > 0','having avg(q_smallint) > 0','having avg(q_tinyint) > 0','having avg(q_float) > 0','having avg(q_double) > 0', 'having sum(q_int) > 0','having sum(q_bigint) > 0','having sum(q_smallint) > 0','having sum(q_tinyint) > 0','having sum(q_float) > 0','having sum(q_double) > 0', @@ -251,9 +251,9 @@ class TDTestCase: self.having_not_support = ['having TOP(q_int,10) > 0','having TOP(q_bigint,10) > 0','having TOP(q_smallint,10) > 0','having TOP(q_tinyint,10) > 0','having TOP(q_float,10) > 0','having TOP(q_double,10) > 0','having TOP(q_bool,10) > 0', 'having BOTTOM(q_int,10) > 0','having BOTTOM(q_bigint,10) > 0','having BOTTOM(q_smallint,10) > 0','having BOTTOM(q_tinyint,10) > 0','having BOTTOM(q_float,10) > 0','having BOTTOM(q_double,10) > 0','having BOTTOM(q_bool,10) > 0', 'having LEASTSQUARES(q_int) > 0','having LEASTSQUARES(q_bigint) > 0','having LEASTSQUARES(q_smallint) > 0','having LEASTSQUARES(q_tinyint) > 0','having LEASTSQUARES(q_float) > 0','having LEASTSQUARES(q_double) > 0','having LEASTSQUARES(q_bool) > 0', - 'having FIRST(q_bool) > 0','having IRATE(q_bool) > 0','having PERCENTILE(q_bool,10) > 0','having avg(q_bool) > 0','having LAST_ROW(q_bool) > 0','having sum(q_bool) > 0','having STDDEV(q_bool) > 0','having APERCENTILE(q_bool,10) > 0','having TWA(q_bool) > 0','having LAST(q_bool) > 0', + 'having FIRST(q_bool) > 0','having IRATE(q_bool) > 0','having PERCENTILE(q_bool,10) > 0','having avg(q_bool) > 0','having LAST_ROW(q_bool) > 0','having sum(q_bool) > 0','having STDDEV(q_bool) > 0','having APERCENTILE(q_bool,10) > 0','having TWA(q_bool) > 0','having LAST(q_bool) > 0', 'having PERCENTILE(q_int,10) > 0','having PERCENTILE(q_bigint,10) > 0','having PERCENTILE(q_smallint,10) > 0','having PERCENTILE(q_tinyint,10) > 0','having PERCENTILE(q_float,10) > 0','having PERCENTILE(q_double,10) > 0'] - self.having_tagnot_support = ['having LAST_ROW(q_int) > 0','having LAST_ROW(q_bigint) > 0','having LAST_ROW(q_smallint) > 0','having LAST_ROW(q_tinyint) > 0','having LAST_ROW(q_float) > 0','having LAST_ROW(q_double) > 0'] + self.having_tagnot_support = ['having LAST_ROW(q_int) > 0','having LAST_ROW(q_bigint) > 0','having LAST_ROW(q_smallint) > 0','having LAST_ROW(q_tinyint) > 0','having LAST_ROW(q_float) > 0','having LAST_ROW(q_double) > 0'] self.having_support_j = ['having count(t1.q_int) > 0','having count(t1.q_bigint) > 0','having count(t1.q_smallint) > 0','having count(t1.q_tinyint) > 0','having count(t1.q_float) > 0','having count(t1.q_double) > 0','having count(t1.q_bool) > 0', 'having avg(t1.q_int) > 0','having avg(t1.q_bigint) > 0','having avg(t1.q_smallint) > 0','having avg(t1.q_tinyint) > 0','having avg(t1.q_float) > 0','having avg(t1.q_double) > 0', @@ -266,7 +266,7 @@ class TDTestCase: 'having FIRST(t1.q_int) > 0','having FIRST(t1.q_bigint) > 0','having FIRST(t1.q_smallint) > 0','having FIRST(t1.q_tinyint) > 0','having FIRST(t1.q_float) > 0','having FIRST(t1.q_double) > 0', 'having LAST(t1.q_int) > 0','having LAST(t1.q_bigint) > 0','having LAST(t1.q_smallint) > 0','having LAST(t1.q_tinyint) > 0','having LAST(t1.q_float) > 0','having LAST(t1.q_double) > 0', 'having APERCENTILE(t1.q_int,10) > 0','having APERCENTILE(t1.q_bigint,10) > 0','having APERCENTILE(t1.q_smallint,10) > 0','having APERCENTILE(t1.q_tinyint,10) > 0','having APERCENTILE(t1.q_float,10) > 0','having APERCENTILE(t1.q_double,10) > 0'] - + # limit offset where self.limit_where = ['limit 1 offset 1' , 'limit 1' , 'limit 2 offset 1' , 'limit 2', 'limit 12 offset 1' , 'limit 20', 'limit 20 offset 10' , 'limit 200'] self.limit1_where = ['limit 1 offset 1' , 'limit 1' ] @@ -275,8 +275,8 @@ class TDTestCase: # slimit soffset where self.slimit_where = ['slimit 1 soffset 1' , 'slimit 1' , 'slimit 2 soffset 1' , 'slimit 2'] self.slimit1_where = ['slimit 2 soffset 1' , 'slimit 1' ] - - # aggregate function include [all:count(*)\avg\sum\stddev ||regualr:twa\irate\leastsquares ||group by tbname:twa\irate\] + + # aggregate function include [all:count(*)\avg\sum\stddev ||regualr:twa\irate\leastsquares ||group by tbname:twa\irate\] # select function include [all: min\max\first(*)\last(*)\top\bottom\apercentile\last_row(*)(not with interval)\interp(*)(FILL) ||regualr: percentile] # calculation function include [all:spread\+-*/ ||regualr:diff\derivative ||group by tbname:diff\derivative\] # **_ns_** express is not support stable, therefore, separated from regular tables @@ -286,7 +286,7 @@ class TDTestCase: # calc_select_all calc_select_regular calc_select_in_ts calc_select_fill calc_select_not_interval # select function include [all: min\max\first(*)\last(*)\top\bottom\apercentile\last_row(*)(not with interval)\interp(*)(FILL) ||regualr: percentile] - + self.calc_select_all = ['bottom(q_int,20)' , 'bottom(q_bigint,20)' , 'bottom(q_smallint,20)' , 'bottom(q_tinyint,20)' ,'bottom(q_float,20)' , 'bottom(q_double,20)' , 'top(q_int,20)' , 'top(q_bigint,20)' , 'top(q_smallint,20)' ,'top(q_tinyint,20)' ,'top(q_float,20)' ,'top(q_double,20)' , 'first(q_int)' , 'first(q_bigint)' , 'first(q_smallint)' , 'first(q_tinyint)' , 'first(q_float)' ,'first(q_double)' ,'first(q_binary)' ,'first(q_nchar)' ,'first(q_bool)' ,'first(q_ts)' , @@ -294,7 +294,7 @@ class TDTestCase: 'min(q_int)' , 'min(q_bigint)' , 'min(q_smallint)' , 'min(q_tinyint)' , 'min(q_float)' ,'min(q_double)' , 'max(q_int)' , 'max(q_bigint)' , 'max(q_smallint)' , 'max(q_tinyint)' ,'max(q_float)' ,'max(q_double)' , 'apercentile(q_int,20)' , 'apercentile(q_bigint,20)' ,'apercentile(q_smallint,20)' ,'apercentile(q_tinyint,20)' ,'apercentile(q_float,20)' ,'apercentile(q_double,20)' , - 'last_row(q_int)' , 'last_row(q_bigint)' , 'last_row(q_smallint)' , 'last_row(q_tinyint)' , 'last_row(q_float)' , + 'last_row(q_int)' , 'last_row(q_bigint)' , 'last_row(q_smallint)' , 'last_row(q_tinyint)' , 'last_row(q_float)' , 'last_row(q_double)' , 'last_row(q_bool)' ,'last_row(q_binary)' ,'last_row(q_nchar)' ,'last_row(q_ts)'] self.calc_select_in_ts = ['bottom(q_int,20)' , 'bottom(q_bigint,20)' , 'bottom(q_smallint,20)' , 'bottom(q_tinyint,20)' ,'bottom(q_float,20)' , 'bottom(q_double,20)' , @@ -305,23 +305,23 @@ class TDTestCase: self.calc_select_in = ['min(q_int)' , 'min(q_bigint)' , 'min(q_smallint)' , 'min(q_tinyint)' , 'min(q_float)' ,'min(q_double)' , 'max(q_int)' , 'max(q_bigint)' , 'max(q_smallint)' , 'max(q_tinyint)' ,'max(q_float)' ,'max(q_double)' , 'apercentile(q_int,20)' , 'apercentile(q_bigint,20)' ,'apercentile(q_smallint,20)' ,'apercentile(q_tinyint,20)' ,'apercentile(q_float,20)' ,'apercentile(q_double,20)' , - 'last_row(q_int)' , 'last_row(q_bigint)' , 'last_row(q_smallint)' , 'last_row(q_tinyint)' , 'last_row(q_float)' , + 'last_row(q_int)' , 'last_row(q_bigint)' , 'last_row(q_smallint)' , 'last_row(q_tinyint)' , 'last_row(q_float)' , 'last_row(q_double)' , 'last_row(q_bool)' ,'last_row(q_binary)' ,'last_row(q_nchar)' ,'last_row(q_ts)'] - + self.calc_select_not_support_ts = ['first(q_int)' , 'first(q_bigint)' , 'first(q_smallint)' , 'first(q_tinyint)' , 'first(q_float)' ,'first(q_double)' ,'first(q_binary)' ,'first(q_nchar)' ,'first(q_bool)' ,'first(q_ts)' , 'last(q_int)' , 'last(q_bigint)' , 'last(q_smallint)' , 'last(q_tinyint)' , 'last(q_float)' ,'last(q_double)' , 'last(q_binary)' ,'last(q_nchar)' ,'last(q_bool)' ,'last(q_ts)' , - 'last_row(q_int)' , 'last_row(q_bigint)' , 'last_row(q_smallint)' , 'last_row(q_tinyint)' , 'last_row(q_float)' , + 'last_row(q_int)' , 'last_row(q_bigint)' , 'last_row(q_smallint)' , 'last_row(q_tinyint)' , 'last_row(q_float)' , 'last_row(q_double)' , 'last_row(q_bool)' ,'last_row(q_binary)' ,'last_row(q_nchar)' ,'last_row(q_ts)', - 'apercentile(q_int,20)' , 'apercentile(q_bigint,20)' ,'apercentile(q_smallint,20)' ,'apercentile(q_tinyint,20)' ,'apercentile(q_float,20)' ,'apercentile(q_double,20)'] - + 'apercentile(q_int,20)' , 'apercentile(q_bigint,20)' ,'apercentile(q_smallint,20)' ,'apercentile(q_tinyint,20)' ,'apercentile(q_float,20)' ,'apercentile(q_double,20)'] + self.calc_select_support_ts = ['bottom(q_int,20)' , 'bottom(q_bigint,20)' , 'bottom(q_smallint,20)' , 'bottom(q_tinyint,20)' ,'bottom(q_float,20)' , 'bottom(q_double,20)' , 'top(q_int,20)' , 'top(q_bigint,20)' , 'top(q_smallint,20)' ,'top(q_tinyint,20)' ,'top(q_float,20)' ,'top(q_double,20)' , 'min(q_int)' , 'min(q_bigint)' , 'min(q_smallint)' , 'min(q_tinyint)' , 'min(q_float)' ,'min(q_double)' , 'max(q_int)' , 'max(q_bigint)' , 'max(q_smallint)' , 'max(q_tinyint)' ,'max(q_float)' ,'max(q_double)' ] - + self.calc_select_regular = [ 'PERCENTILE(q_int,10)' ,'PERCENTILE(q_bigint,20)' , 'PERCENTILE(q_smallint,30)' ,'PERCENTILE(q_tinyint,40)' ,'PERCENTILE(q_float,50)' ,'PERCENTILE(q_double,60)'] - + self.calc_select_fill = ['INTERP(q_int)' ,'INTERP(q_bigint)' ,'INTERP(q_smallint)' ,'INTERP(q_tinyint)', 'INTERP(q_float)' ,'INTERP(q_double)'] self.interp_where = ['ts = now' , 'ts = \'2020-09-13 20:26:40.000\'' , 'ts = \'2020-09-13 20:26:40.009\'' ,'tbname in (\'table_1\') and ts = now' ,'tbname in (\'table_0\' ,\'table_1\',\'table_2\',\'table_3\',\'table_4\',\'table_5\') and ts = \'2020-09-13 20:26:40.000\'','tbname like \'table%\' and ts = \'2020-09-13 20:26:40.002\''] @@ -346,28 +346,28 @@ class TDTestCase: ] self.calc_select_in_not_support_ts_j = ['apercentile(t1.q_int,20)' , 'apercentile(t1.q_bigint,20)' ,'apercentile(t1.q_smallint,20)' ,'apercentile(t1.q_tinyint,20)' ,'apercentile(t1.q_float,20)' ,'apercentile(t1.q_double,20)' , - 'last_row(t1.q_int)' , 'last_row(t1.q_bigint)' , 'last_row(t1.q_smallint)' , 'last_row(t1.q_tinyint)' , 'last_row(t1.q_float)' , + 'last_row(t1.q_int)' , 'last_row(t1.q_bigint)' , 'last_row(t1.q_smallint)' , 'last_row(t1.q_tinyint)' , 'last_row(t1.q_float)' , 'last_row(t1.q_double)' , 'last_row(t1.q_bool)' ,'last_row(t1.q_binary)' ,'last_row(t1.q_nchar)' ,'last_row(t1.q_ts)' , 'apercentile(t2.q_int,20)' , 'apercentile(t2.q_bigint,20)' ,'apercentile(t2.q_smallint,20)' ,'apercentile(t2.q_tinyint,20)' ,'apercentile(t2.q_float,20)' ,'apercentile(t2.q_double,20)' , - 'last_row(t2.q_int)' , 'last_row(t2.q_bigint)' , 'last_row(t2.q_smallint)' , 'last_row(t2.q_tinyint)' , 'last_row(t2.q_float)' , + 'last_row(t2.q_int)' , 'last_row(t2.q_bigint)' , 'last_row(t2.q_smallint)' , 'last_row(t2.q_tinyint)' , 'last_row(t2.q_float)' , 'last_row(t2.q_double)' , 'last_row(t2.q_bool)' ,'last_row(t2.q_binary)' ,'last_row(t2.q_nchar)' ,'last_row(t2.q_ts)'] self.calc_select_in_j = ['min(t1.q_int)' , 'min(t1.q_bigint)' , 'min(t1.q_smallint)' , 'min(t1.q_tinyint)' , 'min(t1.q_float)' ,'min(t1.q_double)' , 'max(t1.q_int)' , 'max(t1.q_bigint)' , 'max(t1.q_smallint)' , 'max(t1.q_tinyint)' ,'max(t1.q_float)' ,'max(t1.q_double)' , 'apercentile(t1.q_int,20)' , 'apercentile(t1.q_bigint,20)' ,'apercentile(t1.q_smallint,20)' ,'apercentile(t1.q_tinyint,20)' ,'apercentile(t1.q_float,20)' ,'apercentile(t1.q_double,20)' , - 'last_row(t1.q_int)' , 'last_row(t1.q_bigint)' , 'last_row(t1.q_smallint)' , 'last_row(t1.q_tinyint)' , 'last_row(t1.q_float)' , + 'last_row(t1.q_int)' , 'last_row(t1.q_bigint)' , 'last_row(t1.q_smallint)' , 'last_row(t1.q_tinyint)' , 'last_row(t1.q_float)' , 'last_row(t1.q_double)' , 'last_row(t1.q_bool)' ,'last_row(t1.q_binary)' ,'last_row(t1.q_nchar)' ,'last_row(t1.q_ts)' , 'min(t2.q_int)' , 'min(t2.q_bigint)' , 'min(t2.q_smallint)' , 'min(t2.q_tinyint)' , 'min(t2.q_float)' ,'min(t2.q_double)' , 'max(t2.q_int)' , 'max(t2.q_bigint)' , 'max(t2.q_smallint)' , 'max(t2.q_tinyint)' ,'max(t2.q_float)' ,'max(t2.q_double)' , 'apercentile(t2.q_int,20)' , 'apercentile(t2.q_bigint,20)' ,'apercentile(t2.q_smallint,20)' ,'apercentile(t2.q_tinyint,20)' ,'apercentile(t2.q_float,20)' ,'apercentile(t2.q_double,20)' , - 'last_row(t2.q_int)' , 'last_row(t2.q_bigint)' , 'last_row(t2.q_smallint)' , 'last_row(t2.q_tinyint)' , 'last_row(t2.q_float)' , - 'last_row(t2.q_double)' , 'last_row(t2.q_bool)' ,'last_row(t2.q_binary)' ,'last_row(t2.q_nchar)' ,'last_row(t2.q_ts)'] + 'last_row(t2.q_int)' , 'last_row(t2.q_bigint)' , 'last_row(t2.q_smallint)' , 'last_row(t2.q_tinyint)' , 'last_row(t2.q_float)' , + 'last_row(t2.q_double)' , 'last_row(t2.q_bool)' ,'last_row(t2.q_binary)' ,'last_row(t2.q_nchar)' ,'last_row(t2.q_ts)'] self.calc_select_all_j = self.calc_select_in_ts_j + self.calc_select_in_j self.calc_select_regular_j = [ 'PERCENTILE(t1.q_int,10)' ,'PERCENTILE(t1.q_bigint,20)' , 'PERCENTILE(t1.q_smallint,30)' ,'PERCENTILE(t1.q_tinyint,40)' ,'PERCENTILE(t1.q_float,50)' ,'PERCENTILE(t1.q_double,60)' , 'PERCENTILE(t2.q_int,10)' ,'PERCENTILE(t2.q_bigint,20)' , 'PERCENTILE(t2.q_smallint,30)' ,'PERCENTILE(t2.q_tinyint,40)' ,'PERCENTILE(t2.q_float,50)' ,'PERCENTILE(t2.q_double,60)'] - + self.calc_select_fill_j = ['INTERP(t1.q_int)' ,'INTERP(t1.q_bigint)' ,'INTERP(t1.q_smallint)' ,'INTERP(t1.q_tinyint)', 'INTERP(t1.q_float)' ,'INTERP(t1.q_double)' , 'INTERP(t2.q_int)' ,'INTERP(t2.q_bigint)' ,'INTERP(t2.q_smallint)' ,'INTERP(t2.q_tinyint)', 'INTERP(t2.q_float)' ,'INTERP(t2.q_double)'] self.interp_where_j = ['t1.ts = now' , 't1.ts = \'2020-09-13 20:26:40.000\'' , 't1.ts = \'2020-09-13 20:26:40.009\'' ,'t2.ts = now' , 't2.ts = \'2020-09-13 20:26:40.000\'' , 't2.ts = \'2020-09-13 20:26:40.009\'' , @@ -389,7 +389,7 @@ class TDTestCase: 'PERCENTILE(q_int,10)' ,'PERCENTILE(q_bigint,20)' , 'PERCENTILE(q_smallint,30)' ,'PERCENTILE(q_tinyint,40)' ,'PERCENTILE(q_float,50)' ,'PERCENTILE(q_double,60)'] self.calc_aggregate_groupbytbname = ['twa(q_int)' ,'twa(q_bigint)' , 'twa(q_smallint)' ,'twa(q_tinyint)' ,'twa (q_float)' ,'twa(q_double)' , - 'IRATE(q_int)' ,'IRATE(q_bigint)' , 'IRATE(q_smallint)' ,'IRATE(q_tinyint)' ,'IRATE (q_float)' ,'IRATE(q_double)' ] + 'IRATE(q_int)' ,'IRATE(q_bigint)' , 'IRATE(q_smallint)' ,'IRATE(q_tinyint)' ,'IRATE (q_float)' ,'IRATE(q_double)' ] #two table join self.calc_aggregate_all_j = ['count(t1.*)' , 'count(t1.q_int)' ,'count(t1.q_bigint)' , 'count(t1.q_smallint)' ,'count(t1.q_tinyint)' ,'count(t1.q_float)' , @@ -417,18 +417,18 @@ class TDTestCase: self.calc_aggregate_groupbytbname_j = ['twa(t1.q_int)' ,'twa(t1.q_bigint)' , 'twa(t1.q_smallint)' ,'twa(t1.q_tinyint)' ,'twa (t1.q_float)' ,'twa(t1.q_double)' , 'IRATE(t1.q_int)' ,'IRATE(t1.q_bigint)' , 'IRATE(t1.q_smallint)' ,'IRATE(t1.q_tinyint)' ,'IRATE (t1.q_float)' ,'IRATE(t1.q_double)' , 'twa(t2.q_int)' ,'twa(t2.q_bigint)' , 'twa(t2.q_smallint)' ,'twa(t2.q_tinyint)' ,'twa (t2.q_float)' ,'twa(t2.q_double)' , - 'IRATE(t2.q_int)' ,'IRATE(t2.q_bigint)' , 'IRATE(t2.q_smallint)' ,'IRATE(t2.q_tinyint)' ,'IRATE (t2.q_float)' ,'IRATE(t2.q_double)' ] - + 'IRATE(t2.q_int)' ,'IRATE(t2.q_bigint)' , 'IRATE(t2.q_smallint)' ,'IRATE(t2.q_tinyint)' ,'IRATE (t2.q_float)' ,'IRATE(t2.q_double)' ] + # calc_calculate_all calc_calculate_regular calc_calculate_groupbytbname # calculation function include [all:spread\+-*/ ||regualr:diff\derivative ||group by tbname:diff\derivative\] - self.calc_calculate_all = ['SPREAD(ts)' , 'SPREAD(q_ts)' , 'SPREAD(q_int)' ,'SPREAD(q_bigint)' , 'SPREAD(q_smallint)' ,'SPREAD(q_tinyint)' ,'SPREAD(q_float)' ,'SPREAD(q_double)' , + self.calc_calculate_all = ['SPREAD(ts)' , 'SPREAD(q_ts)' , 'SPREAD(q_int)' ,'SPREAD(q_bigint)' , 'SPREAD(q_smallint)' ,'SPREAD(q_tinyint)' ,'SPREAD(q_float)' ,'SPREAD(q_double)' , '(SPREAD(q_int) + SPREAD(q_bigint))' , '(SPREAD(q_smallint) - SPREAD(q_float))', '(SPREAD(q_double) * SPREAD(q_tinyint))' , '(SPREAD(q_double) / SPREAD(q_float))'] self.calc_calculate_regular = ['DIFF(q_int)' ,'DIFF(q_bigint)' , 'DIFF(q_smallint)' ,'DIFF(q_tinyint)' ,'DIFF(q_float)' ,'DIFF(q_double)' , 'DIFF(q_int,0)' ,'DIFF(q_bigint,0)' , 'DIFF(q_smallint,0)' ,'DIFF(q_tinyint,0)' ,'DIFF(q_float,0)' ,'DIFF(q_double,0)' , 'DIFF(q_int,1)' ,'DIFF(q_bigint,1)' , 'DIFF(q_smallint,1)' ,'DIFF(q_tinyint,1)' ,'DIFF(q_float,1)' ,'DIFF(q_double,1)' , 'DERIVATIVE(q_int,15s,0)' , 'DERIVATIVE(q_bigint,10s,1)' , 'DERIVATIVE(q_smallint,20s,0)' ,'DERIVATIVE(q_tinyint,10s,1)' ,'DERIVATIVE(q_float,6s,0)' ,'DERIVATIVE(q_double,3s,1)' ] self.calc_calculate_groupbytbname = self.calc_calculate_regular - + #two table join self.calc_calculate_all_j = ['SPREAD(t1.ts)' , 'SPREAD(t1.q_ts)' , 'SPREAD(t1.q_int)' ,'SPREAD(t1.q_bigint)' , 'SPREAD(t1.q_smallint)' ,'SPREAD(t1.q_tinyint)' ,'SPREAD(t1.q_float)' ,'SPREAD(t1.q_double)' , 'SPREAD(t2.ts)' , 'SPREAD(t2.q_ts)' , 'SPREAD(t2.q_int)' ,'SPREAD(t2.q_bigint)' , 'SPREAD(t2.q_smallint)' ,'SPREAD(t2.q_tinyint)' ,'SPREAD(t2.q_float)' ,'SPREAD(t2.q_double)' , @@ -452,17 +452,17 @@ class TDTestCase: 'interval(1y,1n) ','interval(1n,1w) ','interval(1w,1d) ','interval(1d,1h) ','interval(1h,1m) ','interval(1m,1s) ','interval(1s,10a) ' ,'interval(100a,30a)'] self.conn1 = taos.connect(host="127.0.0.1", user="root", password="taosdata", config="/etc/taos/") - self.cur1 = self.conn1.cursor() - print(self.cur1) + self.cur1 = self.conn1.cursor() + print(self.cur1) self.cur1.execute("use %s ;" %self.db_nest) sql = 'select * from stable_1 limit 5;' self.cur1.execute(sql) - + def data_matrix_equal(self, sql1,row1_s,row1_e,col1_s,col1_e, sql2,row2_s,row2_e,col2_s,col2_e): # ----row1_start----col1_start---- - # - - - - 是一个矩阵内的数据相等- - - - # - - - - - - - - - - - - - - - - + # - - - - 是一个矩阵内的数据相等- - - + # - - - - - - - - - - - - - - - - # ----row1_end------col1_end------ self.sql1 = sql1 list1 =[] @@ -474,9 +474,9 @@ class TDTestCase: #print("data=%s" %(tdSql.getData(i1,j1))) list1.append(tdSql.getData(i1,j1)) print("=====list1-------list1---=%s" %set(list1)) - + tdSql.execute("reset query cache;") - self.sql2 = sql2 + self.sql2 = sql2 list2 =[] tdSql.query(sql2) for i2 in range(row2_s-1,row2_e): @@ -485,8 +485,8 @@ class TDTestCase: #print("jjjj222=%d"%j2) #print("data=%s" %(tdSql.getData(i2,j2))) list2.append(tdSql.getData(i2,j2)) - print("=====list2-------list2---=%s" %set(list2)) - + print("=====list2-------list2---=%s" %set(list2)) + if (list1 == list2) and len(list2)>0: # print(("=====matrix===sql1.list1:'%s',sql2.list2:'%s'") %(list1,list2)) tdLog.info(("===matrix===sql1:'%s' matrix_result = sql2:'%s' matrix_result") %(sql1,sql2)) @@ -512,7 +512,7 @@ class TDTestCase: print(("=====matrix_error===sql1.list1:'%s',sql2.list2:'%s'") %(list1,list2)) tdLog.info(("sql1:'%s' matrix_result != sql2:'%s' matrix_result") %(sql1,sql2)) return tdSql.checkEqual(list1,list2) - + def restartDnodes(self): pass # tdDnodes.stop(1) @@ -536,7 +536,7 @@ class TDTestCase: q_binary5 binary(100) , q_nchar5 nchar(100) ,q_binary6 binary(100) , q_nchar6 nchar(100) ,q_binary7 binary(100) , q_nchar7 nchar(100) ,q_binary8 binary(100) , q_nchar8 nchar(100) ,\ q_int_null int , q_bigint_null bigint , q_smallint_null smallint , q_tinyint_null tinyint, q_float_null float , q_double_null double , q_bool_null bool , q_binary_null binary(20) , q_nchar_null nchar(20) , q_ts_null timestamp) \ tags(loc nchar(100) , t_int int , t_bigint bigint , t_smallint smallint , t_tinyint tinyint, t_bool bool , t_binary binary(100) , t_nchar nchar(100) ,t_float float , t_double double , t_ts timestamp);''') - + tdSql.execute('''create stable stable_null_data (ts timestamp , q_int int , q_bigint bigint , q_smallint smallint , q_tinyint tinyint , q_float float , q_double double , q_bool bool , q_binary binary(100) , q_nchar nchar(100) , q_ts timestamp , \ q_binary1 binary(100) , q_nchar1 nchar(100) ,q_binary2 binary(100) , q_nchar2 nchar(100) ,q_binary3 binary(100) , q_nchar3 nchar(100) ,q_binary4 binary(100) , q_nchar4 nchar(100) ,\ q_binary5 binary(100) , q_nchar5 nchar(100) ,q_binary6 binary(100) , q_nchar6 nchar(100) ,q_binary7 binary(100) , q_nchar7 nchar(100) ,q_binary8 binary(100) , q_nchar8 nchar(100) ,\ @@ -548,35 +548,35 @@ class TDTestCase: q_binary5 binary(100) , q_nchar5 nchar(100) ,q_binary6 binary(100) , q_nchar6 nchar(100) ,q_binary7 binary(100) , q_nchar7 nchar(100) ,q_binary8 binary(100) , q_nchar8 nchar(100) ,\ q_int_null int , q_bigint_null bigint , q_smallint_null smallint , q_tinyint_null tinyint, q_float_null float , q_double_null double , q_bool_null bool , q_binary_null binary(20) , q_nchar_null nchar(20) , q_ts_null timestamp) \ tags(loc nchar(100) , t_int int , t_bigint bigint , t_smallint smallint , t_tinyint tinyint, t_bool bool , t_binary binary(100) , t_nchar nchar(100) ,t_float float , t_double double , t_ts timestamp);''') - + #tdSql.execute('''create table stable_1_1 using stable_1 tags('stable_1_1', '0' , '0' , '0' , '0' , 0 , 'binary1' , 'nchar1' , '0' , '0' ,'0') ;''') - tdSql.execute('''create table stable_1_1 using stable_1 tags('stable_1_1', '%d' , '%d', '%d' , '%d' , 0 , 'binary1.%s' , 'nchar1.%s' , '%f', '%f' ,'%d') ;''' - %(fake.random_int(min=-2147483647, max=2147483647, step=1), fake.random_int(min=-9223372036854775807, max=9223372036854775807, step=1), - fake.random_int(min=-32767, max=32767, step=1) , fake.random_int(min=-127, max=127, step=1) , - fake.pystr() ,fake.pystr() ,fake.pyfloat(),fake.pyfloat(),fake.random_int(min=-2147483647, max=2147483647, step=1))) + tdSql.execute('''create table stable_1_1 using stable_1 tags('stable_1_1', '%d' , '%d', '%d' , '%d' , 0 , 'binary1.%s' , 'nchar1.%s' , '%f', '%f' ,'%d') ;''' + %(fake.random_int(min=-2147483647, max=2147483647, step=1), fake.random_int(min=-9223372036854775807, max=9223372036854775807, step=1), + fake.random_int(min=-32767, max=32767, step=1) , fake.random_int(min=-127, max=127, step=1) , + fake.pystr() ,fake.pystr() ,fake.pyfloat(),fake.pyfloat(),fake.random_int(min=-2147483647, max=2147483647, step=1))) tdSql.execute('''create table stable_1_2 using stable_1 tags('stable_1_2', '2147483647' , '9223372036854775807' , '32767' , '127' , 1 , 'binary2' , 'nchar2' , '2' , '22' , \'1999-09-09 09:09:09.090\') ;''') tdSql.execute('''create table stable_1_3 using stable_1 tags('stable_1_3', '-2147483647' , '-9223372036854775807' , '-32767' , '-127' , false , 'binary3' , 'nchar3nchar3' , '-3.3' , '-33.33' , \'2099-09-09 09:09:09.090\') ;''') #tdSql.execute('''create table stable_1_4 using stable_1 tags('stable_1_4', '0' , '0' , '0' , '0' , 0 , '0' , '0' , '0' , '0' ,'0') ;''') - tdSql.execute('''create table stable_1_4 using stable_1 tags('stable_1_4', '%d' , '%d', '%d' , '%d' , 1 , 'binary1.%s' , 'nchar1.%s' , '%f', '%f' ,'%d') ;''' - %(fake.random_int(min=-2147483647, max=2147483647, step=1), fake.random_int(min=-9223372036854775807, max=9223372036854775807, step=1), - fake.random_int(min=-32767, max=32767, step=1) , fake.random_int(min=-127, max=127, step=1) , - fake.pystr() ,fake.pystr() ,fake.pyfloat(),fake.pyfloat(),fake.random_int(min=-2147483647, max=2147483647, step=1))) + tdSql.execute('''create table stable_1_4 using stable_1 tags('stable_1_4', '%d' , '%d', '%d' , '%d' , 1 , 'binary1.%s' , 'nchar1.%s' , '%f', '%f' ,'%d') ;''' + %(fake.random_int(min=-2147483647, max=2147483647, step=1), fake.random_int(min=-9223372036854775807, max=9223372036854775807, step=1), + fake.random_int(min=-32767, max=32767, step=1) , fake.random_int(min=-127, max=127, step=1) , + fake.pystr() ,fake.pystr() ,fake.pyfloat(),fake.pyfloat(),fake.random_int(min=-2147483647, max=2147483647, step=1))) # tdSql.execute('''create table stable_2_1 using stable_2 tags('stable_2_1' , '0' , '0' , '0' , '0' , 0 , 'binary21' , 'nchar21' , '0' , '0' ,'0') ;''') # tdSql.execute('''create table stable_2_2 using stable_2 tags('stable_2_2' , '0' , '0' , '0' , '0' , 0 , '0' , '0' , '0' , '0' ,'0') ;''') # tdSql.execute('''create table stable_null_data_1 using stable_null_data tags('stable_null_data_1', '0' , '0' , '0' , '0' , 0 , '0' , '0' , '0' , '0' ,'0') ;''') - + tdSql.execute('''create table stable_2_1 using stable_2 tags('stable_2_1' , '0' , '0' , '0' , '0' , 0 , 'binary21' , 'nchar21' , '0' , '0' ,\'2099-09-09 09:09:09.090\') ;''') - tdSql.execute('''create table stable_2_2 using stable_2 tags('stable_2_2' , '%d' , '%d', '%d' , '%d' , 0 , 'binary2.%s' , 'nchar2.%s' , '%f', '%f' ,'%d') ;''' - %(fake.random_int(min=-2147483647, max=2147483647, step=1), fake.random_int(min=-9223372036854775807, max=9223372036854775807, step=1), - fake.random_int(min=-32767, max=32767, step=1) , fake.random_int(min=-127, max=127, step=1) , - fake.pystr() ,fake.pystr() ,fake.pyfloat(),fake.pyfloat(),fake.random_int(min=-2147483647, max=2147483647, step=1))) + tdSql.execute('''create table stable_2_2 using stable_2 tags('stable_2_2' , '%d' , '%d', '%d' , '%d' , 0 , 'binary2.%s' , 'nchar2.%s' , '%f', '%f' ,'%d') ;''' + %(fake.random_int(min=-2147483647, max=2147483647, step=1), fake.random_int(min=-9223372036854775807, max=9223372036854775807, step=1), + fake.random_int(min=-32767, max=32767, step=1) , fake.random_int(min=-127, max=127, step=1) , + fake.pystr() ,fake.pystr() ,fake.pyfloat(),fake.pyfloat(),fake.random_int(min=-2147483647, max=2147483647, step=1))) - tdSql.execute('''create table stable_null_data_1 using stable_null_data tags('stable_null_data_1', '%d' , '%d', '%d' , '%d' , 1 , 'binary1.%s' , 'nchar1.%s' , '%f', '%f' ,'%d') ;''' - %(fake.random_int(min=-2147483647, max=2147483647, step=1), fake.random_int(min=-9223372036854775807, max=9223372036854775807, step=1), - fake.random_int(min=-32767, max=32767, step=1) , fake.random_int(min=-127, max=127, step=1) , - fake.pystr() ,fake.pystr() ,fake.pyfloat(),fake.pyfloat(),fake.random_int(min=-2147483647, max=2147483647, step=1))) + tdSql.execute('''create table stable_null_data_1 using stable_null_data tags('stable_null_data_1', '%d' , '%d', '%d' , '%d' , 1 , 'binary1.%s' , 'nchar1.%s' , '%f', '%f' ,'%d') ;''' + %(fake.random_int(min=-2147483647, max=2147483647, step=1), fake.random_int(min=-9223372036854775807, max=9223372036854775807, step=1), + fake.random_int(min=-32767, max=32767, step=1) , fake.random_int(min=-127, max=127, step=1) , + fake.pystr() ,fake.pystr() ,fake.pyfloat(),fake.pyfloat(),fake.random_int(min=-2147483647, max=2147483647, step=1))) #regular table tdSql.execute('''create table regular_table_1 \ @@ -602,92 +602,92 @@ class TDTestCase: q_int_null int , q_bigint_null bigint , q_smallint_null smallint , q_tinyint_null tinyint, q_float_null float , q_double_null double , q_bool_null bool , q_binary_null binary(20) , q_nchar_null nchar(20) , q_ts_null timestamp) ;''') - for i in range(num_random*n): + for i in range(num_random*n): tdSql.execute('''insert into stable_1_1 (ts , q_int , q_bigint , q_smallint , q_tinyint , q_float , q_double , q_bool , q_binary , q_nchar, q_ts,\ q_binary1 , q_nchar1 , q_binary2 , q_nchar2 , q_binary3 , q_nchar3 , q_binary4 , q_nchar4 , q_binary5 , q_nchar5 , q_binary6 , q_nchar6 , q_binary7 , q_nchar7, q_binary8 , q_nchar8) \ values(%d, %d, %d, %d, %d, %f, %f, 0, 'binary.%s', 'nchar.%s', %d, 'binary1.%s', 'nchar1.%s', 'binary2.%s', 'nchar2.%s', 'binary3.%s', 'nchar3.%s', \ - 'binary4.%s', 'nchar4.%s', 'binary5.%s', 'nchar5.%s', 'binary6.%s', 'nchar6.%s', 'binary7.%s', 'nchar7.%s', 'binary8.%s', 'nchar8.%s') ;''' - % (ts + i*1000, fake.random_int(min=-2147483647, max=2147483647, step=1), - fake.random_int(min=-9223372036854775807, max=9223372036854775807, step=1), - fake.random_int(min=-32767, max=32767, step=1) , fake.random_int(min=-127, max=127, step=1) , - fake.pyfloat() , fake.pyfloat() , fake.pystr() , fake.address() , ts + i , fake.pystr() , fake.address() , fake.pystr() , fake.address() , fake.pystr() , fake.address() , + 'binary4.%s', 'nchar4.%s', 'binary5.%s', 'nchar5.%s', 'binary6.%s', 'nchar6.%s', 'binary7.%s', 'nchar7.%s', 'binary8.%s', 'nchar8.%s') ;''' + % (ts + i*1000, fake.random_int(min=-2147483647, max=2147483647, step=1), + fake.random_int(min=-9223372036854775807, max=9223372036854775807, step=1), + fake.random_int(min=-32767, max=32767, step=1) , fake.random_int(min=-127, max=127, step=1) , + fake.pyfloat() , fake.pyfloat() , fake.pystr() , fake.address() , ts + i , fake.pystr() , fake.address() , fake.pystr() , fake.address() , fake.pystr() , fake.address() , fake.pystr() , fake.address() , fake.pystr() , fake.address() , fake.pystr() , fake.address() , fake.pystr() , fake.address() , fake.pystr() , fake.address())) tdSql.execute('''insert into regular_table_1 (ts , q_int , q_bigint , q_smallint , q_tinyint , q_float , q_double, q_bool , q_binary , q_nchar, q_ts,\ q_binary1 , q_nchar1 , q_binary2 , q_nchar2 , q_binary3 , q_nchar3 , q_binary4 , q_nchar4 , q_binary5 , q_nchar5 , q_binary6 , q_nchar6 , q_binary7 , q_nchar7, q_binary8 , q_nchar8) \ values(%d, %d, %d, %d, %d, %f, %f, 0, 'binary.%s', 'nchar.%s', %d, 'binary1.%s', 'nchar1.%s', 'binary2.%s', 'nchar2.%s', 'binary3.%s', 'nchar3.%s', \ - 'binary4.%s', 'nchar4.%s', 'binary5.%s', 'nchar5.%s', 'binary6.%s', 'nchar6.%s', 'binary7.%s', 'nchar7.%s', 'binary8.%s', 'nchar8.%s') ;''' - % (ts + i*1000, fake.random_int(min=-2147483647, max=2147483647, step=1) , - fake.random_int(min=-9223372036854775807, max=9223372036854775807, step=1) , - fake.random_int(min=-32767, max=32767, step=1) , fake.random_int(min=-127, max=127, step=1) , - fake.pyfloat() , fake.pyfloat() , fake.pystr() , fake.address() , ts + i, fake.pystr() , fake.address() , fake.pystr() , fake.address() , fake.pystr() , fake.address() , + 'binary4.%s', 'nchar4.%s', 'binary5.%s', 'nchar5.%s', 'binary6.%s', 'nchar6.%s', 'binary7.%s', 'nchar7.%s', 'binary8.%s', 'nchar8.%s') ;''' + % (ts + i*1000, fake.random_int(min=-2147483647, max=2147483647, step=1) , + fake.random_int(min=-9223372036854775807, max=9223372036854775807, step=1) , + fake.random_int(min=-32767, max=32767, step=1) , fake.random_int(min=-127, max=127, step=1) , + fake.pyfloat() , fake.pyfloat() , fake.pystr() , fake.address() , ts + i, fake.pystr() , fake.address() , fake.pystr() , fake.address() , fake.pystr() , fake.address() , fake.pystr() , fake.address() , fake.pystr() , fake.address() , fake.pystr() , fake.address() , fake.pystr() , fake.address() , fake.pystr() , fake.address())) tdSql.execute('''insert into stable_1_2 (ts , q_int , q_bigint , q_smallint , q_tinyint , q_float , q_double, q_bool , q_binary , q_nchar, q_ts,\ q_binary1 , q_nchar1 , q_binary2 , q_nchar2 , q_binary3 , q_nchar3 , q_binary4 , q_nchar4 , q_binary5 , q_nchar5 , q_binary6 , q_nchar6 , q_binary7 , q_nchar7, q_binary8 , q_nchar8)\ values(%d, %d, %d, %d, %d, %f, %f, 1, 'binary.%s', 'nchar.%s', %d, 'binary1.%s', 'nchar1.%s', 'binary2.%s', 'nchar2.%s', 'binary3.%s', 'nchar3.%s', \ - 'binary4.%s', 'nchar4.%s', 'binary5.%s', 'nchar5.%s', 'binary6.%s', 'nchar6.%s', 'binary7.%s', 'nchar7.%s', 'binary8.%s', 'nchar8.%s') ;''' - % (ts + i*1000, fake.random_int(min=0, max=2147483647, step=1), - fake.random_int(min=0, max=9223372036854775807, step=1), - fake.random_int(min=0, max=32767, step=1) , fake.random_int(min=0, max=127, step=1) , - fake.pyfloat() , fake.pyfloat() , fake.pystr() , fake.address() , ts + i, fake.pystr() , fake.address() , fake.pystr() , fake.address() , fake.pystr() , fake.address() , + 'binary4.%s', 'nchar4.%s', 'binary5.%s', 'nchar5.%s', 'binary6.%s', 'nchar6.%s', 'binary7.%s', 'nchar7.%s', 'binary8.%s', 'nchar8.%s') ;''' + % (ts + i*1000, fake.random_int(min=0, max=2147483647, step=1), + fake.random_int(min=0, max=9223372036854775807, step=1), + fake.random_int(min=0, max=32767, step=1) , fake.random_int(min=0, max=127, step=1) , + fake.pyfloat() , fake.pyfloat() , fake.pystr() , fake.address() , ts + i, fake.pystr() , fake.address() , fake.pystr() , fake.address() , fake.pystr() , fake.address() , fake.pystr() , fake.address() , fake.pystr() , fake.address() , fake.pystr() , fake.address() , fake.pystr() , fake.address() , fake.pystr() , fake.address())) tdSql.execute('''insert into regular_table_2 (ts , q_int , q_bigint , q_smallint , q_tinyint , q_float , q_double, q_bool , q_binary , q_nchar, q_ts,\ q_binary1 , q_nchar1 , q_binary2 , q_nchar2 , q_binary3 , q_nchar3 , q_binary4 , q_nchar4 , q_binary5 , q_nchar5 , q_binary6 , q_nchar6 , q_binary7 , q_nchar7, q_binary8 , q_nchar8) \ values(%d, %d, %d, %d, %d, %f, %f, 1, 'binary.%s', 'nchar.%s', %d, 'binary1.%s', 'nchar1.%s', 'binary2.%s', 'nchar2.%s', 'binary3.%s', 'nchar3.%s', \ - 'binary4.%s', 'nchar4.%s', 'binary5.%s', 'nchar5.%s', 'binary6.%s', 'nchar6.%s', 'binary7.%s', 'nchar7.%s', 'binary8.%s', 'nchar8.%s') ;''' - % (ts + i*1000, fake.random_int(min=0, max=2147483647, step=1), - fake.random_int(min=0, max=9223372036854775807, step=1), - fake.random_int(min=0, max=32767, step=1) , fake.random_int(min=0, max=127, step=1) , - fake.pyfloat() , fake.pyfloat() , fake.pystr() , fake.address() , ts + i, fake.pystr() , fake.address() , fake.pystr() , fake.address() , fake.pystr() , fake.address() , + 'binary4.%s', 'nchar4.%s', 'binary5.%s', 'nchar5.%s', 'binary6.%s', 'nchar6.%s', 'binary7.%s', 'nchar7.%s', 'binary8.%s', 'nchar8.%s') ;''' + % (ts + i*1000, fake.random_int(min=0, max=2147483647, step=1), + fake.random_int(min=0, max=9223372036854775807, step=1), + fake.random_int(min=0, max=32767, step=1) , fake.random_int(min=0, max=127, step=1) , + fake.pyfloat() , fake.pyfloat() , fake.pystr() , fake.address() , ts + i, fake.pystr() , fake.address() , fake.pystr() , fake.address() , fake.pystr() , fake.address() , fake.pystr() , fake.address() , fake.pystr() , fake.address() , fake.pystr() , fake.address() , fake.pystr() , fake.address() , fake.pystr() , fake.address())) - + tdSql.execute('''insert into stable_1_2 (ts , q_int , q_bigint , q_smallint , q_tinyint , q_float , q_double, q_bool , q_binary , q_nchar, q_ts,\ q_binary1 , q_nchar1 , q_binary2 , q_nchar2 , q_binary3 , q_nchar3 , q_binary4 , q_nchar4 , q_binary5 , q_nchar5 , q_binary6 , q_nchar6 , q_binary7 , q_nchar7, q_binary8 , q_nchar8) \ values(%d, %d, %d, %d, %d, %f, %f, 1, 'binary.%s', 'nchar.%s', %d, 'binary1.%s', 'nchar1.%s', 'binary2.%s', 'nchar2.%s', 'binary3.%s', 'nchar3.%s', \ - 'binary4.%s', 'nchar4.%s', 'binary5.%s', 'nchar5.%s', 'binary6.%s', 'nchar6.%s', 'binary7.%s', 'nchar7.%s', 'binary8.%s', 'nchar8.%s') ;''' - % (ts + i*1000 +1, fake.random_int(min=-2147483647, max=0, step=1), - fake.random_int(min=-9223372036854775807, max=0, step=1), - fake.random_int(min=-32767, max=0, step=1) , fake.random_int(min=-127, max=0, step=1) , - fake.pyfloat() , fake.pyfloat() , fake.pystr() , fake.address() , ts + i +1, fake.pystr() , fake.address() , fake.pystr() , fake.address() , fake.pystr() , fake.address() , + 'binary4.%s', 'nchar4.%s', 'binary5.%s', 'nchar5.%s', 'binary6.%s', 'nchar6.%s', 'binary7.%s', 'nchar7.%s', 'binary8.%s', 'nchar8.%s') ;''' + % (ts + i*1000 +1, fake.random_int(min=-2147483647, max=0, step=1), + fake.random_int(min=-9223372036854775807, max=0, step=1), + fake.random_int(min=-32767, max=0, step=1) , fake.random_int(min=-127, max=0, step=1) , + fake.pyfloat() , fake.pyfloat() , fake.pystr() , fake.address() , ts + i +1, fake.pystr() , fake.address() , fake.pystr() , fake.address() , fake.pystr() , fake.address() , fake.pystr() , fake.address() , fake.pystr() , fake.address() , fake.pystr() , fake.address() , fake.pystr() , fake.address() , fake.pystr() , fake.address())) tdSql.execute('''insert into regular_table_2 (ts , q_int , q_bigint , q_smallint , q_tinyint , q_float , q_double, q_bool , q_binary , q_nchar, q_ts,\ q_binary1 , q_nchar1 , q_binary2 , q_nchar2 , q_binary3 , q_nchar3 , q_binary4 , q_nchar4 , q_binary5 , q_nchar5 , q_binary6 , q_nchar6 , q_binary7 , q_nchar7, q_binary8 , q_nchar8) \ values(%d, %d, %d, %d, %d, %f, %f, 1, 'binary.%s', 'nchar.%s', %d, 'binary1.%s', 'nchar1.%s', 'binary2.%s', 'nchar2.%s', 'binary3.%s', 'nchar3.%s', \ - 'binary4.%s', 'nchar4.%s', 'binary5.%s', 'nchar5.%s', 'binary6.%s', 'nchar6.%s', 'binary7.%s', 'nchar7.%s', 'binary8.%s', 'nchar8.%s') ;''' - % (ts + i*1000 +1, fake.random_int(min=-2147483647, max=0, step=1), - fake.random_int(min=-9223372036854775807, max=0, step=1), - fake.random_int(min=-32767, max=0, step=1) , fake.random_int(min=-127, max=0, step=1) , - fake.pyfloat() , fake.pyfloat() , fake.pystr() , fake.address() , ts + i +1, fake.pystr() , fake.address() , fake.pystr() , fake.address() , fake.pystr() , fake.address() , + 'binary4.%s', 'nchar4.%s', 'binary5.%s', 'nchar5.%s', 'binary6.%s', 'nchar6.%s', 'binary7.%s', 'nchar7.%s', 'binary8.%s', 'nchar8.%s') ;''' + % (ts + i*1000 +1, fake.random_int(min=-2147483647, max=0, step=1), + fake.random_int(min=-9223372036854775807, max=0, step=1), + fake.random_int(min=-32767, max=0, step=1) , fake.random_int(min=-127, max=0, step=1) , + fake.pyfloat() , fake.pyfloat() , fake.pystr() , fake.address() , ts + i +1, fake.pystr() , fake.address() , fake.pystr() , fake.address() , fake.pystr() , fake.address() , fake.pystr() , fake.address() , fake.pystr() , fake.address() , fake.pystr() , fake.address() , fake.pystr() , fake.address() , fake.pystr() , fake.address())) tdSql.execute('''insert into stable_2_1 (ts , q_int , q_bigint , q_smallint , q_tinyint , q_float , q_double, q_bool , q_binary , q_nchar, q_ts,\ q_binary1 , q_nchar1 , q_binary2 , q_nchar2 , q_binary3 , q_nchar3 , q_binary4 , q_nchar4 , q_binary5 , q_nchar5 , q_binary6 , q_nchar6 , q_binary7 , q_nchar7, q_binary8 , q_nchar8) \ values(%d, %d, %d, %d, %d, %f, %f, 0, 'binary.%s', 'nchar.%s', %d, 'binary1.%s', 'nchar1.%s', 'binary2.%s', 'nchar2.%s', 'binary3.%s', 'nchar3.%s', \ - 'binary4.%s', 'nchar4.%s', 'binary5.%s', 'nchar5.%s', 'binary6.%s', 'nchar6.%s', 'binary7.%s', 'nchar7.%s', 'binary8.%s', 'nchar8.%s') ;''' - % (ts + i*1000, fake.random_int(min=-0, max=2147483647, step=1), - fake.random_int(min=-0, max=9223372036854775807, step=1), - fake.random_int(min=-0, max=32767, step=1) , fake.random_int(min=-0, max=127, step=1) , - fake.pyfloat() , fake.pyfloat() , fake.pystr() , fake.address() , ts + i, fake.pystr() , fake.address() , fake.pystr() , fake.address() , fake.pystr() , fake.address() , + 'binary4.%s', 'nchar4.%s', 'binary5.%s', 'nchar5.%s', 'binary6.%s', 'nchar6.%s', 'binary7.%s', 'nchar7.%s', 'binary8.%s', 'nchar8.%s') ;''' + % (ts + i*1000, fake.random_int(min=-0, max=2147483647, step=1), + fake.random_int(min=-0, max=9223372036854775807, step=1), + fake.random_int(min=-0, max=32767, step=1) , fake.random_int(min=-0, max=127, step=1) , + fake.pyfloat() , fake.pyfloat() , fake.pystr() , fake.address() , ts + i, fake.pystr() , fake.address() , fake.pystr() , fake.address() , fake.pystr() , fake.address() , fake.pystr() , fake.address() , fake.pystr() , fake.address() , fake.pystr() , fake.address() , fake.pystr() , fake.address() , fake.pystr() , fake.address())) tdSql.execute('''insert into stable_2_1 (ts , q_int , q_bigint , q_smallint , q_tinyint , q_float , q_double, q_bool , q_binary , q_nchar, q_ts,\ q_binary1 , q_nchar1 , q_binary2 , q_nchar2 , q_binary3 , q_nchar3 , q_binary4 , q_nchar4 , q_binary5 , q_nchar5 , q_binary6 , q_nchar6 , q_binary7 , q_nchar7, q_binary8 , q_nchar8) \ values(%d, %d, %d, %d, %d, %f, %f, 0, 'binary.%s', 'nchar.%s', %d, 'binary1.%s', 'nchar1.%s', 'binary2.%s', 'nchar2.%s', 'binary3.%s', 'nchar3.%s', \ - 'binary4.%s', 'nchar4.%s', 'binary5.%s', 'nchar5.%s', 'binary6.%s', 'nchar6.%s', 'binary7.%s', 'nchar7.%s', 'binary8.%s', 'nchar8.%s') ;''' - % (ts + i*1000 +1, fake.random_int(min=-0, max=2147483647, step=1), - fake.random_int(min=-0, max=9223372036854775807, step=1), - fake.random_int(min=-0, max=32767, step=1) , fake.random_int(min=-0, max=127, step=1) , - fake.pyfloat() , fake.pyfloat() , fake.pystr() , fake.address() , ts + i, fake.pystr() , fake.address() , fake.pystr() , fake.address() , fake.pystr() , fake.address() , + 'binary4.%s', 'nchar4.%s', 'binary5.%s', 'nchar5.%s', 'binary6.%s', 'nchar6.%s', 'binary7.%s', 'nchar7.%s', 'binary8.%s', 'nchar8.%s') ;''' + % (ts + i*1000 +1, fake.random_int(min=-0, max=2147483647, step=1), + fake.random_int(min=-0, max=9223372036854775807, step=1), + fake.random_int(min=-0, max=32767, step=1) , fake.random_int(min=-0, max=127, step=1) , + fake.pyfloat() , fake.pyfloat() , fake.pystr() , fake.address() , ts + i, fake.pystr() , fake.address() , fake.pystr() , fake.address() , fake.pystr() , fake.address() , fake.pystr() , fake.address() , fake.pystr() , fake.address() , fake.pystr() , fake.address() , fake.pystr() , fake.address() , fake.pystr() , fake.address())) tdSql.execute('''insert into stable_2_1 (ts , q_int , q_bigint , q_smallint , q_tinyint , q_float , q_double, q_bool , q_binary , q_nchar, q_ts,\ q_binary1 , q_nchar1 , q_binary2 , q_nchar2 , q_binary3 , q_nchar3 , q_binary4 , q_nchar4 , q_binary5 , q_nchar5 , q_binary6 , q_nchar6 , q_binary7 , q_nchar7, q_binary8 , q_nchar8) \ values(%d, %d, %d, %d, %d, %f, %f, 0, 'binary.%s', 'nchar.%s', %d, 'binary1.%s', 'nchar1.%s', 'binary2.%s', 'nchar2.%s', 'binary3.%s', 'nchar3.%s', \ - 'binary4.%s', 'nchar4.%s', 'binary5.%s', 'nchar5.%s', 'binary6.%s', 'nchar6.%s', 'binary7.%s', 'nchar7.%s', 'binary8.%s', 'nchar8.%s') ;''' - % (ts + i*1000 +10, fake.random_int(min=-0, max=2147483647, step=1), - fake.random_int(min=-0, max=9223372036854775807, step=1), - fake.random_int(min=-0, max=32767, step=1) , fake.random_int(min=-0, max=127, step=1) , - fake.pyfloat() , fake.pyfloat() , fake.pystr() , fake.address() , ts + i, fake.pystr() , fake.address() , fake.pystr() , fake.address() , fake.pystr() , fake.address() , + 'binary4.%s', 'nchar4.%s', 'binary5.%s', 'nchar5.%s', 'binary6.%s', 'nchar6.%s', 'binary7.%s', 'nchar7.%s', 'binary8.%s', 'nchar8.%s') ;''' + % (ts + i*1000 +10, fake.random_int(min=-0, max=2147483647, step=1), + fake.random_int(min=-0, max=9223372036854775807, step=1), + fake.random_int(min=-0, max=32767, step=1) , fake.random_int(min=-0, max=127, step=1) , + fake.pyfloat() , fake.pyfloat() , fake.pystr() , fake.address() , ts + i, fake.pystr() , fake.address() , fake.pystr() , fake.address() , fake.pystr() , fake.address() , fake.pystr() , fake.address() , fake.pystr() , fake.address() , fake.pystr() , fake.address() , fake.pystr() , fake.address() , fake.pystr() , fake.address())) tdSql.query("select count(*) from stable_1;") @@ -696,149 +696,149 @@ class TDTestCase: tdSql.checkData(0,0,num_random*n) def math_nest(self,mathlist): - - print("==========%s===start=============" %mathlist) - os.system("rm -rf %s/%s.sql" % (self.testcasePath,self.testcaseFilename)) - + + print("==========%s===start=============" %mathlist) + os.system("rm -rf %s/%s.sql" % (self.testcasePath,self.testcaseFilename)) + self.dropandcreateDB_random("%s" %self.db_nest, 1) - + if (mathlist == ['ABS','SQRT']) or (mathlist == ['SIN','COS','TAN','ASIN','ACOS','ATAN']) or (mathlist == ['FLOOR','CEIL','ROUND']) \ or (mathlist == ['CSUM']) or (mathlist == ['']): - math_functions = mathlist - fun_fix_column = ['(q_bigint)','(q_smallint)','(q_tinyint)','(q_int)','(q_float)','(q_double)','(q_bigint_null)','(q_smallint_null)','(q_tinyint_null)','(q_int_null)','(q_float_null)','(q_double_null)'] + math_functions = mathlist + fun_fix_column = ['(q_bigint)','(q_smallint)','(q_tinyint)','(q_int)','(q_float)','(q_double)','(q_bigint_null)','(q_smallint_null)','(q_tinyint_null)','(q_int_null)','(q_float_null)','(q_double_null)'] fun_column_1 = random.sample(math_functions,1)+random.sample(fun_fix_column,1) math_fun_1 = str(fun_column_1).replace("[","").replace("]","").replace("'","").replace(", ","") fun_column_2 = random.sample(math_functions,1)+random.sample(fun_fix_column,1) math_fun_2 = str(fun_column_2).replace("[","").replace("]","").replace("'","").replace(", ","") - + fun_fix_column_j = ['(t1.q_bigint)','(t1.q_smallint)','(t1.q_tinyint)','(t1.q_int)','(t1.q_float)','(t1.q_double)','(t1.q_bigint_null)','(t1.q_smallint_null)','(t1.q_tinyint_null)','(t1.q_int_null)','(t1.q_float_null)','(t1.q_double_null)', - '(t2.q_bigint)','(t2.q_smallint)','(t2.q_tinyint)','(t2.q_int)','(t2.q_float)','(t2.q_double)','(t2.q_bigint_null)','(t2.q_smallint_null)','(t2.q_tinyint_null)','(t2.q_int_null)','(t2.q_float_null)','(t2.q_double_null)'] + '(t2.q_bigint)','(t2.q_smallint)','(t2.q_tinyint)','(t2.q_int)','(t2.q_float)','(t2.q_double)','(t2.q_bigint_null)','(t2.q_smallint_null)','(t2.q_tinyint_null)','(t2.q_int_null)','(t2.q_float_null)','(t2.q_double_null)'] fun_column_join_1 = random.sample(math_functions,1)+random.sample(fun_fix_column_j,1) math_fun_join_1 = str(fun_column_join_1).replace("[","").replace("]","").replace("'","").replace(", ","") fun_column_join_2 = random.sample(math_functions,1)+random.sample(fun_fix_column_j,1) math_fun_join_2 = str(fun_column_join_2).replace("[","").replace("]","").replace("'","").replace(", ","") - + elif (mathlist == ['UNIQUE']) or (mathlist == ['HYPERLOGLOG']): - math_functions = mathlist + math_functions = mathlist fun_fix_column = ['(q_bigint)','(q_smallint)','(q_tinyint)','(q_int)','(q_float)','(q_double)','(q_binary)','(q_nchar)','(q_bool)','(q_ts)', - '(q_bigint_null)','(q_smallint_null)','(q_tinyint_null)','(q_int_null)','(q_float_null)','(q_double_null)','(q_binary_null)','(q_nchar_null)','(q_bool_null)','(q_ts_null)'] + '(q_bigint_null)','(q_smallint_null)','(q_tinyint_null)','(q_int_null)','(q_float_null)','(q_double_null)','(q_binary_null)','(q_nchar_null)','(q_bool_null)','(q_ts_null)'] fun_column_1 = random.sample(math_functions,1)+random.sample(fun_fix_column,1) math_fun_1 = str(fun_column_1).replace("[","").replace("]","").replace("'","").replace(", ","") fun_column_2 = random.sample(math_functions,1)+random.sample(fun_fix_column,1) math_fun_2 = str(fun_column_2).replace("[","").replace("]","").replace("'","").replace(", ","") - + fun_fix_column_j = ['(t1.q_bigint)','(t1.q_smallint)','(t1.q_tinyint)','(t1.q_int)','(t1.q_float)','(t1.q_double)','(t1.q_bigint_null)','(t1.q_smallint_null)','(t1.q_tinyint_null)','(t1.q_int_null)','(t1.q_float_null)','(t1.q_double_null)', - '(t2.q_bigint)','(t2.q_smallint)','(t2.q_tinyint)','(t2.q_int)','(t2.q_float)','(t2.q_double)','(t2.q_bigint_null)','(t2.q_smallint_null)','(t2.q_tinyint_null)','(t2.q_int_null)','(t2.q_float_null)','(t2.q_double_null)'] + '(t2.q_bigint)','(t2.q_smallint)','(t2.q_tinyint)','(t2.q_int)','(t2.q_float)','(t2.q_double)','(t2.q_bigint_null)','(t2.q_smallint_null)','(t2.q_tinyint_null)','(t2.q_int_null)','(t2.q_float_null)','(t2.q_double_null)'] fun_column_join_1 = random.sample(math_functions,1)+random.sample(fun_fix_column_j,1) math_fun_join_1 = str(fun_column_join_1).replace("[","").replace("]","").replace("'","").replace(", ","") fun_column_join_2 = random.sample(math_functions,1)+random.sample(fun_fix_column_j,1) math_fun_join_2 = str(fun_column_join_2).replace("[","").replace("]","").replace("'","").replace(", ","") elif (mathlist == ['POW','LOG']) or (mathlist == ['MAVG']) or (mathlist == ['SAMPLE']) or (mathlist == ['TAIL']): - math_functions = mathlist - num = random.randint(0, 1000) + math_functions = mathlist + num = random.randint(0, 1000) fun_fix_column = ['(q_bigint,num)','(q_smallint,num)','(q_tinyint,num)','(q_int,num)','(q_float,num)','(q_double,num)', - '(q_bigint_null,num)','(q_smallint_null,num)','(q_tinyint_null,num)','(q_int_null,num)','(q_float_null,num)','(q_double_null,num)'] + '(q_bigint_null,num)','(q_smallint_null,num)','(q_tinyint_null,num)','(q_int_null,num)','(q_float_null,num)','(q_double_null,num)'] fun_column_1 = random.sample(math_functions,1)+random.sample(fun_fix_column,1) math_fun_1 = str(fun_column_1).replace("[","").replace("]","").replace("'","").replace(", ","").replace("num",str(num)) fun_column_2 = random.sample(math_functions,1)+random.sample(fun_fix_column,1) math_fun_2 = str(fun_column_2).replace("[","").replace("]","").replace("'","").replace(", ","").replace("num",str(num)) - + fun_fix_column_j = ['(t1.q_bigint,num)','(t1.q_smallint,num)','(t1.q_tinyint,num)','(t1.q_int,num)','(t1.q_float,num)','(t1.q_double,num)', '(t1.q_bigint_null,num)','(t1.q_smallint_null,num)','(t1.q_tinyint_null,num)','(t1.q_int_null,num)','(t1.q_float_null,num)','(t1.q_double_null,num)', '(t2.q_bigint,num)','(t2.q_smallint,num)','(t2.q_tinyint,num)','(t2.q_int,num)','(t2.q_float,num)','(t2.q_double,num)', - '(t2.q_bigint_null,num)','(t2.q_smallint_null,num)','(t2.q_tinyint_null,num)','(t2.q_int_null,num)','(t2.q_float_null,num)','(t2.q_double_null,num)'] + '(t2.q_bigint_null,num)','(t2.q_smallint_null,num)','(t2.q_tinyint_null,num)','(t2.q_int_null,num)','(t2.q_float_null,num)','(t2.q_double_null,num)'] fun_column_join_1 = random.sample(math_functions,1)+random.sample(fun_fix_column_j,1) math_fun_join_1 = str(fun_column_join_1).replace("[","").replace("]","").replace("'","").replace(", ","").replace("num",str(num)) fun_column_join_2 = random.sample(math_functions,1)+random.sample(fun_fix_column_j,1) math_fun_join_2 = str(fun_column_join_2).replace("[","").replace("]","").replace("'","").replace(", ","").replace("num",str(num)) - + tdSql.query("select 1-1 as math_nest from stable_1 limit 1;") for i in range(self.fornum): if (mathlist == ['SIN','COS','TAN','ASIN','ACOS','ATAN']) or (mathlist == ['ABS','SQRT']) \ or (mathlist == ['POW','LOG']) or (mathlist == ['FLOOR','CEIL','ROUND']) : - sql = "select ts , floor(asct1) from ( select " - sql += "%s as asct1, " % math_fun_1 - sql += "%s as asct2, " % math_fun_2 + sql = "select ts , floor(asct1) from ( select " + sql += "%s as asct1, " % math_fun_1 + sql += "%s as asct2, " % math_fun_2 sql += "%s, " % random.choice(self.s_s_select) - sql += "%s, " % random.choice(self.q_select) + sql += "%s, " % random.choice(self.q_select) sql += "ts from regular_table_1 where " sql += "%s " % random.choice(self.q_where) sql += "%s " % random.choice(self.order_where) sql += ");" - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) tdSql.query(sql) tdSql.checkRows(100) self.cur1.execute(sql) elif (mathlist == ['MAVG']) or (mathlist == ['SAMPLE'])or (mathlist == ['TAIL']) or (mathlist == ['CSUM']) \ or (mathlist == ['HYPERLOGLOG']) or (mathlist == ['UNIQUE']): - sql = "select floor(asct1) from ( select " - sql += "%s as asct1 " % math_fun_1 - # sql += "%s as asct2, " % math_fun_2 + sql = "select floor(asct1) from ( select " + sql += "%s as asct1 " % math_fun_1 + # sql += "%s as asct2, " % math_fun_2 # sql += "%s, " % random.choice(self.s_s_select) - # sql += "%s, " % random.choice(self.q_select) + # sql += "%s, " % random.choice(self.q_select) sql += " from regular_table_1 where " sql += "%s " % random.choice(self.q_where) #sql += "%s " % random.choice(self.order_where) sql += ");" - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) tdSql.query(sql) #tdSql.checkRows(100) self.cur1.execute(sql) - + tdSql.query("select 1-2 as math_nest from stable_1 limit 1;") for i in range(self.fornum): if (mathlist == ['SIN','COS','TAN','ASIN','ACOS','ATAN']) or (mathlist == ['ABS','SQRT']) \ or (mathlist == ['POW','LOG']) or (mathlist == ['FLOOR','CEIL','ROUND']) : sql = "select ts , abs(asct1) from ( select " - sql += "%s as asct1, " % math_fun_1 + sql += "%s as asct1, " % math_fun_1 sql += "%s, " % random.choice(self.s_s_select) - sql += "%s, " % random.choice(self.q_select) + sql += "%s, " % random.choice(self.q_select) sql += "ts ts from regular_table_1 where " sql += "%s " % random.choice(self.q_where) sql += "%s )" % random.choice(self.order_where) - sql += "%s " % random.choice(self.unionall_or_union) + sql += "%s " % random.choice(self.unionall_or_union) sql += "select ts , asct2 from ( select " - sql += "%s as asct2, " % math_fun_2 + sql += "%s as asct2, " % math_fun_2 sql += "%s, " % random.choice(self.s_s_select) - sql += "%s, " % random.choice(self.q_select) + sql += "%s, " % random.choice(self.q_select) sql += "ts ts from regular_table_1 where " - sql += "%s " % random.choice(self.q_where) + sql += "%s " % random.choice(self.q_where) #sql += "%s " % random.choice(having_support) sql += "%s " % random.choice(self.order_where) sql += "%s " % random.choice(self.limit1_where) sql += ")" - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) #TD-15437 tdSql.query(sql) - #TD-15437 self.cur1.execute(sql) + #TD-15437 self.cur1.execute(sql) elif (mathlist == ['MAVG']) or (mathlist == ['SAMPLE'])or (mathlist == ['TAIL']) or (mathlist == ['CSUM']) \ - or (mathlist == ['HYPERLOGLOG']) or (mathlist == ['UNIQUE']): + or (mathlist == ['HYPERLOGLOG']) or (mathlist == ['UNIQUE']): sql = "select abs(asct1) from ( select " - sql += "%s as asct1 " % math_fun_1 + sql += "%s as asct1 " % math_fun_1 # sql += "%s, " % random.choice(self.s_s_select) - # sql += "%s, " % random.choice(self.q_select) + # sql += "%s, " % random.choice(self.q_select) sql += "from regular_table_1 where " sql += "%s )" % random.choice(self.q_where) #sql += "%s )" % random.choice(self.order_where) - sql += "%s " % random.choice(self.unionall_or_union) + sql += "%s " % random.choice(self.unionall_or_union) sql += "select floor(asct2) from ( select " - sql += "%s as asct2 " % math_fun_2 + sql += "%s as asct2 " % math_fun_2 # sql += "%s, " % random.choice(self.s_s_select) - # sql += "%s, " % random.choice(self.q_select) + # sql += "%s, " % random.choice(self.q_select) sql += " from regular_table_1 where " - sql += "%s " % random.choice(self.q_where) + sql += "%s " % random.choice(self.q_where) #sql += "%s " % random.choice(having_support) #sql += "%s " % random.choice(self.order_where) sql += "%s " % random.choice(self.limit1_where) sql += ")" - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) #TD-15473 tdSql.query(sql) - #TD-15473 self.cur1.execute(sql) - + #TD-15473 self.cur1.execute(sql) + tdSql.query("select 1-3 as math_nest from stable_1 limit 1;") for i in range(self.fornum): if (mathlist == ['SIN','COS','TAN','ASIN','ACOS','ATAN']) or (mathlist == ['ABS','SQRT']) \ @@ -847,20 +847,20 @@ class TDTestCase: sql += "%s as asct1, ts ," % math_fun_1 sql += "%s as asct2, " % math_fun_2 sql += "%s, " % random.choice(self.s_s_select) - sql += "%s, " % random.choice(self.q_select) + sql += "%s, " % random.choice(self.q_select) sql += "ts from regular_table_1 where " sql += "%s " % random.choice(self.q_where) - sql += "%s select " % random.choice(self.unionall_or_union) + sql += "%s select " % random.choice(self.unionall_or_union) sql += "%s as asct2, ts ," % math_fun_2 sql += "%s as asct1, " % math_fun_1 sql += "%s, " % random.choice(self.s_s_select) - sql += "%s, " % random.choice(self.q_select) + sql += "%s, " % random.choice(self.q_select) sql += "ts from regular_table_2 where " sql += "%s " % random.choice(self.q_where) sql += "%s " % random.choice(self.order_where) sql += ")" - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) #TD-15473 tdSql.query(sql) #self.cur1.execute(sql) elif (mathlist == ['MAVG']) or (mathlist == ['SAMPLE'])or (mathlist == ['TAIL']) or (mathlist == ['CSUM']) \ @@ -869,86 +869,86 @@ class TDTestCase: sql += "%s as asct1, ts ," % math_fun_1 sql += "%s as asct2, " % math_fun_2 sql += "%s, " % random.choice(self.s_s_select) - sql += "%s, " % random.choice(self.q_select) + sql += "%s, " % random.choice(self.q_select) sql += "ts from regular_table_1 where " sql += "%s " % random.choice(self.q_where) - sql += "%s select " % random.choice(self.unionall_or_union) + sql += "%s select " % random.choice(self.unionall_or_union) sql += "%s as asct2, ts ," % math_fun_2 sql += "%s as asct1, " % math_fun_1 sql += "%s, " % random.choice(self.s_s_select) - sql += "%s, " % random.choice(self.q_select) + sql += "%s, " % random.choice(self.q_select) sql += "ts from regular_table_2 where " sql += "%s " % random.choice(self.q_where) sql += "%s " % random.choice(self.order_where) sql += ")" - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) #TD-15473 tdSql.query(sql) #self.cur1.execute(sql) - + tdSql.query("select 1-4 as math_nest from stable_1 limit 1;") for i in range(self.fornum): if (mathlist == ['SIN','COS','TAN','ASIN','ACOS','ATAN']) or (mathlist == ['ABS','SQRT']) \ or (mathlist == ['POW','LOG']) or (mathlist == ['FLOOR','CEIL','ROUND']) : sql = "select ts , asct1 from ( select t1.ts as ts," - sql += "%s, " % math_fun_join_1 - sql += "%s as asct1, " % math_fun_join_2 - sql += "%s, " % math_fun_join_1 - sql += "t1.%s, " % random.choice(self.q_select) - sql += "t2.%s, " % random.choice(self.q_select) + sql += "%s, " % math_fun_join_1 + sql += "%s as asct1, " % math_fun_join_2 + sql += "%s, " % math_fun_join_1 + sql += "t1.%s, " % random.choice(self.q_select) + sql += "t2.%s, " % random.choice(self.q_select) sql += "t2.ts from regular_table_1 t1 , regular_table_2 t2 where t1.ts = t2.ts and " sql += "%s " % random.choice(self.q_u_where) sql += "and %s " % random.choice(self.q_u_or_where) sql += "%s " % random.choice(self.order_u_where) sql += ");" - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) tdSql.query(sql) tdSql.checkRows(100) self.cur1.execute(sql) elif (mathlist == ['MAVG']) or (mathlist == ['SAMPLE'])or (mathlist == ['TAIL']) or (mathlist == ['CSUM'])\ or (mathlist == ['HYPERLOGLOG']) or (mathlist == ['UNIQUE']): sql = "select count(asct1) from ( select " - sql += "%s as asct1 " % math_fun_join_2 + sql += "%s as asct1 " % math_fun_join_2 sql += "from regular_table_1 t1 , regular_table_2 t2 where t1.ts = t2.ts and " sql += "%s " % random.choice(self.q_u_where) sql += "and %s " % random.choice(self.q_u_or_where) sql += ");" - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) tdSql.query(sql) self.cur1.execute(sql) - + tdSql.query("select 1-5 as math_nest from stable_1 limit 1;") for i in range(self.fornum): if (mathlist == ['SIN','COS','TAN','ASIN','ACOS','ATAN']) or (mathlist == ['ABS','SQRT']) \ or (mathlist == ['POW','LOG']) or (mathlist == ['FLOOR','CEIL','ROUND']) : sql = "select ts ," - sql += "%s, " % math_fun_1 + sql += "%s, " % math_fun_1 + sql += "%s, " % random.choice(self.q_select) sql += "%s, " % random.choice(self.q_select) - sql += "%s, " % random.choice(self.q_select) sql += "%s " % math_fun_2 sql += " from ( select * from regular_table_1 ) where " sql += "%s " % random.choice(self.q_where) sql += "%s " % random.choice(self.order_where) sql += " ;" - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) tdSql.query(sql) tdSql.checkRows(100) self.cur1.execute(sql) elif (mathlist == ['MAVG']) or (mathlist == ['SAMPLE'])or (mathlist == ['TAIL']) or (mathlist == ['CSUM'])\ or (mathlist == ['HYPERLOGLOG']) or (mathlist == ['UNIQUE']): sql = "select " - # sql += "%s, " % math_fun_1 + # sql += "%s, " % math_fun_1 + # sql += "%s, " % random.choice(self.q_select) # sql += "%s, " % random.choice(self.q_select) - # sql += "%s, " % random.choice(self.q_select) sql += "%s " % math_fun_2 sql += " from ( select * from regular_table_1 ) where " sql += "%s " % random.choice(self.q_where) sql += " ;" - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) #TD-15973 tdSql.query(sql) #TD-15973 self.cur1.execute(sql) @@ -957,35 +957,35 @@ class TDTestCase: if (mathlist == ['SIN','COS','TAN','ASIN','ACOS','ATAN']) or (mathlist == ['ABS','SQRT']) \ or (mathlist == ['POW','LOG']) or (mathlist == ['FLOOR','CEIL','ROUND']) : sql = "select ts , max(asct1) from ( select t1.ts as ts," - sql += "%s, " % math_fun_join_1 - sql += "%s as asct1, " % math_fun_join_2 - sql += "t1.%s, " % random.choice(self.q_select) - sql += "t2.%s, " % random.choice(self.q_select) - sql += "%s, " % math_fun_join_1 + sql += "%s, " % math_fun_join_1 + sql += "%s as asct1, " % math_fun_join_2 + sql += "t1.%s, " % random.choice(self.q_select) + sql += "t2.%s, " % random.choice(self.q_select) + sql += "%s, " % math_fun_join_1 sql += "t2.ts from regular_table_1 t1 , regular_table_2 t2 where t1.ts = t2.ts and " sql += "%s " % random.choice(self.q_u_where) sql += "and %s )" % random.choice(self.q_u_or_where) sql += "%s " % random.choice(self.order_where) sql += "%s " % random.choice(self.limit1_where) - tdLog.info(sql) - tdLog.info(len(sql)) - tdSql.query(sql) + tdLog.info(sql) + tdLog.info(len(sql)) + tdSql.query(sql) self.cur1.execute(sql) elif (mathlist == ['MAVG']) or (mathlist == ['SAMPLE'])or (mathlist == ['TAIL']) or (mathlist == ['CSUM']) \ or (mathlist == ['HYPERLOGLOG']) or (mathlist == ['UNIQUE']): sql = "select max(asct1) from ( select " - #sql += "%s, " % math_fun_join_1 - sql += "%s as asct1 " % math_fun_join_2 - # sql += "t1.%s, " % random.choice(self.q_select) - # sql += "t2.%s, " % random.choice(self.q_select) - # sql += "%s, " % math_fun_join_1 + #sql += "%s, " % math_fun_join_1 + sql += "%s as asct1 " % math_fun_join_2 + # sql += "t1.%s, " % random.choice(self.q_select) + # sql += "t2.%s, " % random.choice(self.q_select) + # sql += "%s, " % math_fun_join_1 sql += "from regular_table_1 t1 , regular_table_2 t2 where t1.ts = t2.ts and " sql += "%s " % random.choice(self.q_u_where) sql += "and %s )" % random.choice(self.q_u_or_where) sql += "%s " % random.choice(self.limit1_where) - tdLog.info(sql) - tdLog.info(len(sql)) - tdSql.query(sql) + tdLog.info(sql) + tdLog.info(len(sql)) + tdSql.query(sql) self.cur1.execute(sql) tdSql.query("select 1-7 as math_nest from stable_1 limit 1;") @@ -995,13 +995,13 @@ class TDTestCase: sql = "select ts , abs(asct1) from ( select " sql += "%s as asct1, ts ," % math_fun_1 sql += "%s as asct2, " % math_fun_2 - sql += "%s, " % random.choice(self.q_select) - sql += "%s, " % random.choice(self.t_select) + sql += "%s, " % random.choice(self.q_select) + sql += "%s, " % random.choice(self.t_select) sql += "ts from stable_1 where " sql += "%s " % random.choice(self.qt_where) sql += "%s " % random.choice(self.order_where) sql += ") ;" - tdLog.info(sql) + tdLog.info(sql) tdLog.info(len(sql)) # tdSql.query(sql) # tdSql.checkRows(300) @@ -1013,11 +1013,11 @@ class TDTestCase: sql += "from stable_1 where " sql += "%s " % random.choice(self.qt_where) sql += ") ;" - tdLog.info(sql) + tdLog.info(sql) tdLog.info(len(sql)) # tdSql.query(sql) # self.cur1.execute(sql)# TD-16039 - + tdSql.query("select 1-8 as math_nest from stable_1 limit 1;") for i in range(self.fornum): if (mathlist == ['SIN','COS','TAN','ASIN','ACOS','ATAN']) or (mathlist == ['ABS','SQRT']) \ @@ -1027,13 +1027,13 @@ class TDTestCase: sql += "%s, " % random.choice(self.s_s_select) sql += "%s as asct1, ts ," % math_fun_1 sql += "%s as asct2, " % math_fun_2 - sql += "%s, " % random.choice(self.q_select) - sql += "%s, " % random.choice(self.t_select) + sql += "%s, " % random.choice(self.q_select) + sql += "%s, " % random.choice(self.t_select) sql += "ts from stable_1 where " sql += "%s " % random.choice(self.qt_where) sql += "%s " % random.choice(self.order_where) sql += ") ;" - tdLog.info(sql) + tdLog.info(sql) tdLog.info(len(sql)) #tdSql.query(sql) # tdSql.checkRows(300) @@ -1046,7 +1046,7 @@ class TDTestCase: sql += " from stable_1 where " sql += "%s " % random.choice(self.qt_where) sql += ") ;" - tdLog.info(sql) + tdLog.info(sql) tdLog.info(len(sql)) # tdSql.query(sql) # self.cur1.execute(sql)# TD-16039 @@ -1056,12 +1056,12 @@ class TDTestCase: if (mathlist == ['SIN','COS','TAN','ASIN','ACOS','ATAN']) or (mathlist == ['ABS','SQRT']) \ or (mathlist == ['POW','LOG']) or (mathlist == ['FLOOR','CEIL','ROUND']) : sql = "select ts , max(asct1) from ( select t1.ts as ts," - sql += "%s, " % math_fun_join_1 - sql += "%s as asct1, " % math_fun_join_2 - sql += "t1.%s, " % random.choice(self.q_select) - sql += "t1.%s, " % random.choice(self.q_select) - sql += "t2.%s, " % random.choice(self.q_select) - sql += "t2.%s, " % random.choice(self.q_select) + sql += "%s, " % math_fun_join_1 + sql += "%s as asct1, " % math_fun_join_2 + sql += "t1.%s, " % random.choice(self.q_select) + sql += "t1.%s, " % random.choice(self.q_select) + sql += "t2.%s, " % random.choice(self.q_select) + sql += "t2.%s, " % random.choice(self.q_select) sql += "t2.ts from stable_1 t1 , stable_2 t2 where t1.ts = t2.ts and " sql += "%s " % random.choice(self.t_join_where) sql += "and %s " % random.choice(self.t_u_where) @@ -1069,29 +1069,29 @@ class TDTestCase: sql += "%s " % random.choice(self.order_u_where) sql += "%s " % random.choice(self.limit1_where) sql += ") ;" - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) # tdSql.query(sql) # self.cur1.execute(sql)# TD-16039 elif (mathlist == ['MAVG']) or (mathlist == ['SAMPLE'])or (mathlist == ['TAIL']) or (mathlist == ['CSUM'])\ or (mathlist == ['HYPERLOGLOG']) or (mathlist == ['UNIQUE']): - sql = "select max(asct1) from ( select " - sql += "%s as asct1 " % math_fun_join_2 - # sql += "t1.%s, " % random.choice(self.q_select) - # sql += "t1.%s, " % random.choice(self.q_select) - # sql += "t2.%s, " % random.choice(self.q_select) - # sql += "t2.%s, " % random.choice(self.q_select) + sql = "select max(asct1) from ( select " + sql += "%s as asct1 " % math_fun_join_2 + # sql += "t1.%s, " % random.choice(self.q_select) + # sql += "t1.%s, " % random.choice(self.q_select) + # sql += "t2.%s, " % random.choice(self.q_select) + # sql += "t2.%s, " % random.choice(self.q_select) sql += "from stable_1 t1 , stable_2 t2 where t1.ts = t2.ts and " sql += "%s " % random.choice(self.t_join_where) sql += "and %s " % random.choice(self.t_u_where) sql += "and %s " % random.choice(self.t_u_or_where) sql += "%s " % random.choice(self.limit1_where) sql += ") ;" - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) # tdSql.query(sql)# TD-16039 # self.cur1.execute(sql) - + self.restartDnodes() tdSql.query("select 1-10 as math_nest from stable_1 limit 1;") for i in range(self.fornum): @@ -1116,8 +1116,8 @@ class TDTestCase: sql += "%s " % random.choice(self.order_where) sql += "%s " % random.choice(self.limit1_where) sql += ")" - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) #TD-15437 tdSql.query(sql) #TD-15437 self.cur1.execute(sql) elif (mathlist == ['MAVG']) or (mathlist == ['SAMPLE'])or (mathlist == ['TAIL']) or (mathlist == ['CSUM']) \ @@ -1133,11 +1133,11 @@ class TDTestCase: sql += "%s " % random.choice(self.q_where) sql += "%s " % random.choice(self.limit1_where) sql += ")" - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) #TD-15437 tdSql.query(sql) #TD-15437 self.cur1.execute(sql) - + #3 inter union not support tdSql.query("select 1-11 as math_nest from stable_1 limit 1;") for i in range(self.fornum): @@ -1163,8 +1163,8 @@ class TDTestCase: sql += "%s " % random.choice(self.order_where) sql += "%s " % random.choice(self.limit1_where) sql += ")" - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) #TD-15837 tdSql.query(sql) # self.cur1.execute(sql) elif (mathlist == ['MAVG']) or (mathlist == ['SAMPLE'])or (mathlist == ['TAIL']) or (mathlist == ['CSUM']) \ @@ -1180,8 +1180,8 @@ class TDTestCase: sql += "%s " % random.choice(self.q_where) sql += "%s " % random.choice(self.limit1_where) sql += ")" - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) #TD-15837 tdSql.query(sql) #self.cur1.execute(sql) @@ -1190,52 +1190,52 @@ class TDTestCase: if (mathlist == ['SIN','COS','TAN','ASIN','ACOS','ATAN']) or (mathlist == ['ABS','SQRT']) \ or (mathlist == ['POW','LOG']) or (mathlist == ['FLOOR','CEIL','ROUND']) : sql = "select ts , max(asct1) from ( select t1.ts as ts," - sql += "%s, " % math_fun_join_1 - sql += "%s as asct1, " % math_fun_join_2 - sql += "t1.%s, " % random.choice(self.q_select) - sql += "t1.%s, " % random.choice(self.q_select) - sql += "t2.%s, " % random.choice(self.q_select) - sql += "t2.%s, " % random.choice(self.q_select) + sql += "%s, " % math_fun_join_1 + sql += "%s as asct1, " % math_fun_join_2 + sql += "t1.%s, " % random.choice(self.q_select) + sql += "t1.%s, " % random.choice(self.q_select) + sql += "t2.%s, " % random.choice(self.q_select) + sql += "t2.%s, " % random.choice(self.q_select) sql += "t2.ts from stable_1 t1 , stable_2 t2 where t1.ts = t2.ts and " sql += "%s " % random.choice(self.t_u_where) sql += "and %s " % random.choice(self.t_u_or_where) sql += "%s " % random.choice(self.order_u_where) sql += "%s " % random.choice(self.limit1_where) sql += ");" - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) # tdSql.query(sql) # self.cur1.execute(sql)# TD-16039 elif (mathlist == ['MAVG']) or (mathlist == ['SAMPLE'])or (mathlist == ['TAIL']) or (mathlist == ['CSUM'])\ or (mathlist == ['HYPERLOGLOG']) or (mathlist == ['UNIQUE']): - sql = "select max(asct1) from ( select " - sql += "%s as asct1 " % math_fun_join_2 + sql = "select max(asct1) from ( select " + sql += "%s as asct1 " % math_fun_join_2 sql += " from stable_1 t1 , stable_2 t2 where t1.ts = t2.ts and " sql += "%s " % random.choice(self.t_u_where) sql += "and %s " % random.choice(self.t_u_or_where) sql += "%s " % random.choice(self.limit1_where) sql += ");" - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) # tdSql.query(sql) # self.cur1.execute(sql)# TD-16039 - + tdSql.query("select 1-13 as math_nest from stable_1 limit 1;") for i in range(self.fornum): if (mathlist == ['SIN','COS','TAN','ASIN','ACOS','ATAN']) or (mathlist == ['ABS','SQRT']) \ or (mathlist == ['POW','LOG']) or (mathlist == ['FLOOR','CEIL','ROUND']) : sql = "select ts ," - sql += "%s, " % math_fun_1 + sql += "%s, " % math_fun_1 + sql += "%s, " % random.choice(self.q_select) sql += "%s, " % random.choice(self.q_select) - sql += "%s, " % random.choice(self.q_select) sql += "%s " % math_fun_2 - sql += "%s " % random.choice(self.t_select) + sql += "%s " % random.choice(self.t_select) sql += " from ( select * from stable_1 where " sql += "%s " % random.choice(self.qt_where) sql += "%s " % random.choice(self.order_where) sql += ") ;" - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) # tdSql.query(sql) # tdSql.checkRows(300) # self.cur1.execute(sql) # TD-16039 @@ -1243,21 +1243,21 @@ class TDTestCase: or (mathlist == ['HYPERLOGLOG']) or (mathlist == ['UNIQUE']): sql = "select " sql += "%s " % math_fun_2 - sql += "%s " % random.choice(self.t_select) + sql += "%s " % random.choice(self.t_select) sql += " from ( select * from stable_1 where " sql += "%s " % random.choice(self.qt_where) sql += ") ;" - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) #TD15973 tdSql.query(sql) #TD15973 self.cur1.execute(sql) - + tdSql.query("select 1-14 as math_nest from stable_1 limit 1;") for i in range(self.fornum): if (mathlist == ['SIN','COS','TAN','ASIN','ACOS','ATAN']) or (mathlist == ['ABS','SQRT']) \ or (mathlist == ['POW','LOG']) or (mathlist == ['FLOOR','CEIL','ROUND']) : sql = "select avg(asct1),count(asct2) from ( select " - sql += "%s as asct1, " % math_fun_1 + sql += "%s as asct1, " % math_fun_1 sql += "%s as asct2" % math_fun_2 sql += " from stable_1 where " sql += "%s " % random.choice(self.q_where) @@ -1265,63 +1265,63 @@ class TDTestCase: sql += "%s " % random.choice(self.order_desc_where) sql += "%s " % random.choice([self.limit_where[2] , self.limit_where[3]] ) sql += " ) ;" - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) # tdSql.query(sql) # self.cur1.execute(sql) # TD-16039 elif (mathlist == ['MAVG']) or (mathlist == ['SAMPLE'])or (mathlist == ['TAIL']) or (mathlist == ['CSUM'])\ or (mathlist == ['HYPERLOGLOG']) or (mathlist == ['UNIQUE']): sql = "select avg(asct1) from ( select " - sql += "%s as asct1 " % math_fun_1 + sql += "%s as asct1 " % math_fun_1 sql += " from stable_1 where " sql += "%s " % random.choice(self.q_where) sql += "%s " % random.choice(self.partiton_where) sql += "%s " % random.choice([self.limit_where[2] , self.limit_where[3]] ) sql += " ) ;" - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) # tdSql.query(sql) # self.cur1.execute(sql) # TD-16039 - + tdSql.query("select 1-15 as math_nest from stable_1 limit 1;") for i in range(self.fornum): if (mathlist == ['SIN','COS','TAN','ASIN','ACOS','ATAN']) or (mathlist == ['ABS','SQRT']) \ or (mathlist == ['POW','LOG']) or (mathlist == ['FLOOR','CEIL','ROUND']) : sql = "select ts , max(asct1) from ( select t1.ts as ts," - sql += "%s, " % math_fun_join_1 - sql += "%s as asct1, " % math_fun_join_2 - sql += "t1.%s, " % random.choice(self.q_select) - sql += "t1.%s, " % random.choice(self.q_select) - sql += "t2.%s, " % random.choice(self.q_select) - sql += "t2.%s " % random.choice(self.q_select) + sql += "%s, " % math_fun_join_1 + sql += "%s as asct1, " % math_fun_join_2 + sql += "t1.%s, " % random.choice(self.q_select) + sql += "t1.%s, " % random.choice(self.q_select) + sql += "t2.%s, " % random.choice(self.q_select) + sql += "t2.%s " % random.choice(self.q_select) sql += "from stable_1 t1, stable_2 t2 where t1.ts = t2.ts and " sql += "%s " % random.choice(self.t_join_where) sql += " and %s " % random.choice(self.qt_u_or_where) sql += "%s " % random.choice(self.partiton_where_j) sql += "%s " % random.choice(self.slimit1_where) - sql += ") " + sql += ") " sql += "%s " % random.choice(self.order_desc_where) sql += "%s ;" % random.choice(self.limit_u_where) - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) # tdSql.query(sql) # self.cur1.execute(sql) # TD-16039 elif (mathlist == ['MAVG']) or (mathlist == ['SAMPLE']) or (mathlist == ['TAIL']) or (mathlist == ['CSUM'])\ - or (mathlist == ['HYPERLOGLOG']) or (mathlist == ['UNIQUE']): - sql = "select max(asct1) from ( select " - sql += "%s as asct1 " % math_fun_join_2 + or (mathlist == ['HYPERLOGLOG']) or (mathlist == ['UNIQUE']): + sql = "select max(asct1) from ( select " + sql += "%s as asct1 " % math_fun_join_2 sql += "from stable_1 t1, stable_2 t2 where t1.ts = t2.ts and " sql += "%s " % random.choice(self.t_join_where) sql += " and %s " % random.choice(self.qt_u_or_where) sql += "%s " % random.choice(self.partiton_where_j) sql += "%s " % random.choice(self.slimit1_where) - sql += ") " + sql += ") " sql += "%s ;" % random.choice(self.limit_u_where) - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) # tdSql.query(sql) # self.cur1.execute(sql) # TD-16039 - + #taos -f sql startTime_taos_f = time.time() print("taos -f %s sql start!" %mathlist) @@ -1329,271 +1329,271 @@ class TDTestCase: _ = subprocess.check_output(taos_cmd1, shell=True).decode("utf-8") print("taos -f %s sql over!" %mathlist) endTime_taos_f = time.time() - print("taos_f total time %ds" % (endTime_taos_f - startTime_taos_f)) - - print("=========%s====over=============" %mathlist) + print("taos_f total time %ds" % (endTime_taos_f - startTime_taos_f)) + + print("=========%s====over=============" %mathlist) def str_nest(self,strlist): - - print("==========%s===start=============" %strlist) - os.system("rm -rf %s/%s.sql" % (self.testcasePath,self.testcaseFilename)) - + + print("==========%s===start=============" %strlist) + os.system("rm -rf %s/%s.sql" % (self.testcasePath,self.testcaseFilename)) + self.dropandcreateDB_random("%s" %self.db_nest, 1) - + if (strlist == ['LTRIM','RTRIM','LOWER','UPPER']) or (strlist == ['LENGTH','CHAR_LENGTH']) \ or (strlist == ['']): - str_functions = strlist - fun_fix_column = ['(q_nchar)','(q_binary)','(q_nchar_null)','(q_binary_null)'] + str_functions = strlist + fun_fix_column = ['(q_nchar)','(q_binary)','(q_nchar_null)','(q_binary_null)'] fun_column_1 = random.sample(str_functions,1)+random.sample(fun_fix_column,1) str_fun_1 = str(fun_column_1).replace("[","").replace("]","").replace("'","").replace(", ","") fun_column_2 = random.sample(str_functions,1)+random.sample(fun_fix_column,1) str_fun_2 = str(fun_column_2).replace("[","").replace("]","").replace("'","").replace(", ","") - + fun_fix_column_j = ['(t1.q_nchar)','(t1.q_binary)','(t1.q_nchar_null)','(t1.q_binary_null)', - '(t2.q_nchar)','(t2.q_binary)','(t2.q_nchar_null)','(t2.q_binary_null)'] + '(t2.q_nchar)','(t2.q_binary)','(t2.q_nchar_null)','(t2.q_binary_null)'] fun_column_join_1 = random.sample(str_functions,1)+random.sample(fun_fix_column_j,1) str_fun_join_1 = str(fun_column_join_1).replace("[","").replace("]","").replace("'","").replace(", ","") fun_column_join_2 = random.sample(str_functions,1)+random.sample(fun_fix_column_j,1) str_fun_join_2 = str(fun_column_join_2).replace("[","").replace("]","").replace("'","").replace(", ","") - - fun_fix_column_s = ['(q_nchar)','(q_binary)','(q_nchar_null)','(q_binary_null)','(loc)','(tbname)'] + + fun_fix_column_s = ['(q_nchar)','(q_binary)','(q_nchar_null)','(q_binary_null)','(loc)','(tbname)'] fun_column_s_1 = random.sample(str_functions,1)+random.sample(fun_fix_column_s,1) str_fun_s_1 = str(fun_column_s_1).replace("[","").replace("]","").replace("'","").replace(", ","") fun_column_s_2 = random.sample(str_functions,1)+random.sample(fun_fix_column_s,1) str_fun_s_2 = str(fun_column_s_2).replace("[","").replace("]","").replace("'","").replace(", ","") - + fun_fix_column_s_j = ['(t1.q_nchar)','(t1.q_binary)','(t1.q_nchar_null)','(t1.q_binary_null)','(t1.loc)','(t1.tbname)', - '(t2.q_nchar)','(t2.q_binary)','(t2.q_nchar_null)','(t2.q_binary_null)','(t2.loc)','(t2.tbname)'] + '(t2.q_nchar)','(t2.q_binary)','(t2.q_nchar_null)','(t2.q_binary_null)','(t2.loc)','(t2.tbname)'] fun_column_join_s_1 = random.sample(str_functions,1)+random.sample(fun_fix_column_j,1) str_fun_join_s_1 = str(fun_column_join_1).replace("[","").replace("]","").replace("'","").replace(", ","") fun_column_join_s_2 = random.sample(str_functions,1)+random.sample(fun_fix_column_j,1) str_fun_join_s_2 = str(fun_column_join_2).replace("[","").replace("]","").replace("'","").replace(", ","") - + elif (strlist == ['SUBSTR']) : - str_functions = strlist - pos = random.randint(1, 20) - sub_len = random.randint(1, 10) + str_functions = strlist + pos = random.randint(1, 20) + sub_len = random.randint(1, 10) fun_fix_column = ['(q_nchar,pos)','(q_binary,pos)','(q_nchar_null,pos)','(q_binary_null,pos)', - '(q_nchar,pos,sub_len)','(q_binary,pos,sub_len)','(q_nchar_null,pos,sub_len)','(q_binary_null,pos,sub_len)',] + '(q_nchar,pos,sub_len)','(q_binary,pos,sub_len)','(q_nchar_null,pos,sub_len)','(q_binary_null,pos,sub_len)',] fun_column_1 = random.sample(str_functions,1)+random.sample(fun_fix_column,1) str_fun_1 = str(fun_column_1).replace("[","").replace("]","").replace("'","").replace(", ","").replace("pos",str(pos)).replace("sub_len",str(sub_len)) fun_column_2 = random.sample(str_functions,1)+random.sample(fun_fix_column,1) str_fun_2 = str(fun_column_2).replace("[","").replace("]","").replace("'","").replace(", ","").replace("pos",str(pos)).replace("sub_len",str(sub_len)) - + fun_fix_column_j = ['(t1.q_nchar,pos)','(t1.q_binary,pos)','(t1.q_nchar_null,pos)','(t1.q_binary_null,pos)', '(t1.q_nchar,pos,sub_len)','(t1.q_binary,pos,sub_len)','(t1.q_nchar_null,pos,sub_len)','(t1.q_binary_null,pos,sub_len)', '(t2.q_nchar,pos)','(t2.q_binary,pos)','(t2.q_nchar_null,pos)','(t2.q_binary_null,pos)', - '(t2.q_nchar,pos,sub_len)','(t2.q_binary,pos,sub_len)','(t2.q_nchar_null,pos,sub_len)','(t2.q_binary_null,pos,sub_len)'] + '(t2.q_nchar,pos,sub_len)','(t2.q_binary,pos,sub_len)','(t2.q_nchar_null,pos,sub_len)','(t2.q_binary_null,pos,sub_len)'] fun_column_join_1 = random.sample(str_functions,1)+random.sample(fun_fix_column_j,1) str_fun_join_1 = str(fun_column_join_1).replace("[","").replace("]","").replace("'","").replace(", ","").replace("pos",str(pos)).replace("sub_len",str(sub_len)) fun_column_join_2 = random.sample(str_functions,1)+random.sample(fun_fix_column_j,1) str_fun_join_2 = str(fun_column_join_2).replace("[","").replace("]","").replace("'","").replace(", ","").replace("pos",str(pos)).replace("sub_len",str(sub_len)) - + fun_fix_column_s = ['(q_nchar,pos)','(q_binary,pos)','(q_nchar_null,pos)','(q_binary_null,pos)','(loc,pos)', - '(q_nchar,pos,sub_len)','(q_binary,pos,sub_len)','(q_nchar_null,pos,sub_len)','(q_binary_null,pos,sub_len)','(loc,pos,sub_len)',] + '(q_nchar,pos,sub_len)','(q_binary,pos,sub_len)','(q_nchar_null,pos,sub_len)','(q_binary_null,pos,sub_len)','(loc,pos,sub_len)',] fun_column_s_1 = random.sample(str_functions,1)+random.sample(fun_fix_column_s,1) str_fun_s_1 = str(fun_column_1).replace("[","").replace("]","").replace("'","").replace(", ","").replace("pos",str(pos)).replace("sub_len",str(sub_len)) fun_column_s_2 = random.sample(str_functions,1)+random.sample(fun_fix_column_s,1) str_fun_s_2 = str(fun_column_2).replace("[","").replace("]","").replace("'","").replace(", ","").replace("pos",str(pos)).replace("sub_len",str(sub_len)) - + fun_fix_column_s_j = ['(t1.q_nchar,pos)','(t1.q_binary,pos)','(t1.q_nchar_null,pos)','(t1.q_binary_null,pos)','(t1.loc,pos)', '(t1.q_nchar,pos,sub_len)','(t1.q_binary,pos,sub_len)','(t1.q_nchar_null,pos,sub_len)','(t1.q_binary_null,pos,sub_len)','(t1.loc,pos,sub_len)', '(t2.q_nchar,pos)','(t2.q_binary,pos)','(t2.q_nchar_null,pos)','(t2.q_binary_null,pos)','(t2.loc,pos)', - '(t2.q_nchar,pos,sub_len)','(t2.q_binary,pos,sub_len)','(t2.q_nchar_null,pos,sub_len)','(t2.q_binary_null,pos,sub_len)','(t2.loc,pos,sub_len)'] + '(t2.q_nchar,pos,sub_len)','(t2.q_binary,pos,sub_len)','(t2.q_nchar_null,pos,sub_len)','(t2.q_binary_null,pos,sub_len)','(t2.loc,pos,sub_len)'] fun_column_join_s_1 = random.sample(str_functions,1)+random.sample(fun_fix_column_s_j,1) str_fun_join_s_1 = str(fun_column_join_1).replace("[","").replace("]","").replace("'","").replace(", ","").replace("pos",str(pos)).replace("sub_len",str(sub_len)) fun_column_join_s_2 = random.sample(str_functions,1)+random.sample(fun_fix_column_s_j,1) str_fun_join_s_2 = str(fun_column_join_2).replace("[","").replace("]","").replace("'","").replace(", ","").replace("pos",str(pos)).replace("sub_len",str(sub_len)) - + elif (strlist == ['CONCAT']) : - str_functions = strlist - i = random.randint(2,8) + str_functions = strlist + i = random.randint(2,8) fun_fix_column = ['q_nchar','q_nchar1','q_nchar2','q_nchar3','q_nchar4','q_nchar5','q_nchar6','q_nchar7','q_nchar8','q_nchar_null', - 'q_binary','q_binary1','q_binary2','q_binary3','q_binary4','q_binary5','q_binary6','q_binary7','q_binary8','q_binary_null'] - - column1 = str(random.sample(fun_fix_column,i)).replace("[","").replace("]","").replace("'","") + 'q_binary','q_binary1','q_binary2','q_binary3','q_binary4','q_binary5','q_binary6','q_binary7','q_binary8','q_binary_null'] + + column1 = str(random.sample(fun_fix_column,i)).replace("[","").replace("]","").replace("'","") fun_column_1 = str(random.sample(str_functions,1))+'('+column1+')' str_fun_1 = str(fun_column_1).replace("[","").replace("]","").replace("'","") - + column2 = str(random.sample(fun_fix_column,i)).replace("[","").replace("]","").replace("'","") fun_column_2 = str(random.sample(str_functions,1))+'('+column2+')' str_fun_2 = str(fun_column_2).replace("[","").replace("]","").replace("'","") - + fun_fix_column_j = ['(t1.q_nchar)','(t1.q_nchar1)','(t1.q_nchar2)','(t1.q_nchar3)','(t1.q_nchar4)','(t1.q_nchar5)','(t1.q_nchar6)','(t1.q_nchar7)','(t1.q_nchar8)','(t1.q_nchar_null)', '(t2.q_nchar)','(t2.q_nchar1)','(t2.q_nchar2)','(t2.q_nchar3)','(t2.q_nchar4)','(t2.q_nchar5)','(t2.q_nchar6)','(t2.q_nchar7)','(t2.q_nchar8)','(t2.q_nchar_null)', '(t1.q_binary)','(t1.q_binary1)','(t1.q_binary2)','(t1.q_binary3)','(t1.q_binary4)','(t1.q_binary5)','(t1.q_binary6)','(t1.q_binary7)','(t1.q_binary8)','(t1.q_binary_null)', - '(t2.q_binary)','(t2.q_binary1)','(t2.q_binary2)','(t2.q_binary3)','(t2.q_binary4)','(t2.q_binary5)','(t2.q_binary6)','(t2.q_binary7)','(t2.q_binary8)','(t2.q_binary_null)'] - - column_j1 = str(random.sample(fun_fix_column_j,i)).replace("[","").replace("]","").replace("'","") + '(t2.q_binary)','(t2.q_binary1)','(t2.q_binary2)','(t2.q_binary3)','(t2.q_binary4)','(t2.q_binary5)','(t2.q_binary6)','(t2.q_binary7)','(t2.q_binary8)','(t2.q_binary_null)'] + + column_j1 = str(random.sample(fun_fix_column_j,i)).replace("[","").replace("]","").replace("'","") fun_column_join_1 = str(random.sample(str_functions,1))+'('+column_j1+')' str_fun_join_1 = str(fun_column_join_1).replace("[","").replace("]","").replace("'","") - - column_j2 = str(random.sample(fun_fix_column_j,i)).replace("[","").replace("]","").replace("'","") + + column_j2 = str(random.sample(fun_fix_column_j,i)).replace("[","").replace("]","").replace("'","") fun_column_join_2 = str(random.sample(str_functions,1))+'('+column_j2+')' str_fun_join_2 = str(fun_column_join_2).replace("[","").replace("]","").replace("'","") - + fun_fix_column_s = ['q_nchar','q_nchar1','q_nchar2','q_nchar3','q_nchar4','q_nchar5','q_nchar6','q_nchar7','q_nchar8','loc','q_nchar_null', - 'q_binary','q_binary1','q_binary2','q_binary3','q_binary4','q_binary5','q_binary6','q_binary7','q_binary8','q_binary_null'] - - column_s1 = str(random.sample(fun_fix_column,i)).replace("[","").replace("]","").replace("'","") + 'q_binary','q_binary1','q_binary2','q_binary3','q_binary4','q_binary5','q_binary6','q_binary7','q_binary8','q_binary_null'] + + column_s1 = str(random.sample(fun_fix_column,i)).replace("[","").replace("]","").replace("'","") fun_column_s_1 = str(random.sample(str_functions,1))+'('+column_s1+')' str_fun_s_1 = str(fun_column_s_1).replace("[","").replace("]","").replace("'","") - - column_s2 = str(random.sample(fun_fix_column,i)).replace("[","").replace("]","").replace("'","") + + column_s2 = str(random.sample(fun_fix_column,i)).replace("[","").replace("]","").replace("'","") fun_column_s_2 = str(random.sample(str_functions,1))+'('+column_s2+')' str_fun_s_2 = str(fun_column_s_2).replace("[","").replace("]","").replace("'","") - + fun_fix_column_s_j = ['(t1.q_nchar)','(t1.q_nchar1)','(t1.q_nchar2)','(t1.q_nchar3)','(t1.q_nchar4)','(t1.q_nchar5)','(t1.q_nchar6)','(t1.q_nchar7)','(t1.q_nchar8)','(t1.q_nchar_null)','(t1.loc)', '(t2.q_nchar)','(t2.q_nchar1)','(t2.q_nchar2)','(t2.q_nchar3)','(t2.q_nchar4)','(t2.q_nchar5)','(t2.q_nchar6)','(t2.q_nchar7)','(t2.q_nchar8)','(t2.q_nchar_null)','(t2.loc)', '(t1.q_binary)','(t1.q_binary1)','(t1.q_binary2)','(t1.q_binary3)','(t1.q_binary4)','(t1.q_binary5)','(t1.q_binary6)','(t1.q_binary7)','(t1.q_binary8)','(t1.q_binary_null)', '(t2.q_binary)','(t2.q_binary1)','(t2.q_binary2)','(t2.q_binary3)','(t2.q_binary4)','(t2.q_binary5)','(t2.q_binary6)','(t2.q_binary7)','(t2.q_binary8)','(t2.q_binary_null)'] - - column_j_s1 = str(random.sample(fun_fix_column_s_j,i)).replace("[","").replace("]","").replace("'","") + + column_j_s1 = str(random.sample(fun_fix_column_s_j,i)).replace("[","").replace("]","").replace("'","") fun_column_join_s_1 = str(random.sample(str_functions,1))+'('+column_j_s1+')' str_fun_join_s_1 = str(fun_column_join_s_1).replace("[","").replace("]","").replace("'","") - - column_j_s2 = str(random.sample(fun_fix_column_s_j,i)).replace("[","").replace("]","").replace("'","") + + column_j_s2 = str(random.sample(fun_fix_column_s_j,i)).replace("[","").replace("]","").replace("'","") fun_column_join_s_2 = str(random.sample(str_functions,1))+'('+column_j_s2+')' str_fun_join_s_2 = str(fun_column_join_s_2).replace("[","").replace("]","").replace("'","") - + elif (strlist == ['CONCAT_WS']): - str_functions = strlist - i = random.randint(2,8) + str_functions = strlist + i = random.randint(2,8) fun_fix_column = ['q_nchar','q_nchar1','q_nchar2','q_nchar3','q_nchar4','q_nchar5','q_nchar6','q_nchar7','q_nchar8','q_nchar_null', - 'q_binary','q_binary1','q_binary2','q_binary3','q_binary4','q_binary5','q_binary6','q_binary7','q_binary8','q_binary_null'] - + 'q_binary','q_binary1','q_binary2','q_binary3','q_binary4','q_binary5','q_binary6','q_binary7','q_binary8','q_binary_null'] + separators = ['',' ','abc','123','!','@','#','$','%','^','&','*','(',')','-','_','+','=','{', '[','}',']','|',';',':',',','.','<','>','?','/','~','`','taos','涛思'] - separator = str(random.sample(separators,i)).replace("[","").replace("]","") - - column1 = str(random.sample(fun_fix_column,i)).replace("[","").replace("]","").replace("'","") + separator = str(random.sample(separators,i)).replace("[","").replace("]","") + + column1 = str(random.sample(fun_fix_column,i)).replace("[","").replace("]","").replace("'","") fun_column_1 = str(random.sample(str_functions,1))+'('+'\"'+separator+'\",'+column1+')' str_fun_1 = str(fun_column_1).replace("[","").replace("]","").replace("'","") - + column2 = str(random.sample(fun_fix_column,i)).replace("[","").replace("]","").replace("'","") fun_column_2 = str(random.sample(str_functions,1))+'('+'\"'+separator+'\",'+column2+')' str_fun_2 = str(fun_column_2).replace("[","").replace("]","").replace("'","") - + fun_fix_column_j = ['(t1.q_nchar)','(t1.q_nchar1)','(t1.q_nchar2)','(t1.q_nchar3)','(t1.q_nchar4)','(t1.q_nchar5)','(t1.q_nchar6)','(t1.q_nchar7)','(t1.q_nchar8)','(t1.q_nchar_null)', '(t2.q_nchar)','(t2.q_nchar1)','(t2.q_nchar2)','(t2.q_nchar3)','(t2.q_nchar4)','(t2.q_nchar5)','(t2.q_nchar6)','(t2.q_nchar7)','(t2.q_nchar8)','(t2.q_nchar_null)', '(t1.q_binary)','(t1.q_binary1)','(t1.q_binary2)','(t1.q_binary3)','(t1.q_binary4)','(t1.q_binary5)','(t1.q_binary6)','(t1.q_binary7)','(t1.q_binary8)','(t1.q_binary_null)', - '(t2.q_binary)','(t2.q_binary1)','(t2.q_binary2)','(t2.q_binary3)','(t2.q_binary4)','(t2.q_binary5)','(t2.q_binary6)','(t2.q_binary7)','(t2.q_binary8)','(t2.q_binary_null)'] - - column_j1 = str(random.sample(fun_fix_column_j,i)).replace("[","").replace("]","").replace("'","") + '(t2.q_binary)','(t2.q_binary1)','(t2.q_binary2)','(t2.q_binary3)','(t2.q_binary4)','(t2.q_binary5)','(t2.q_binary6)','(t2.q_binary7)','(t2.q_binary8)','(t2.q_binary_null)'] + + column_j1 = str(random.sample(fun_fix_column_j,i)).replace("[","").replace("]","").replace("'","") fun_column_join_1 = str(random.sample(str_functions,1))+'('+'\"'+separator+'\",'+column_j1+')' str_fun_join_1 = str(fun_column_join_1).replace("[","").replace("]","").replace("'","") - - column_j2 = str(random.sample(fun_fix_column_j,i)).replace("[","").replace("]","").replace("'","") + + column_j2 = str(random.sample(fun_fix_column_j,i)).replace("[","").replace("]","").replace("'","") fun_column_join_2 = str(random.sample(str_functions,1))+'('+'\"'+separator+'\",'+column_j2+')' str_fun_join_2 = str(fun_column_join_2).replace("[","").replace("]","").replace("'","") - + fun_fix_column_s = ['q_nchar','q_nchar1','q_nchar2','q_nchar3','q_nchar4','q_nchar5','q_nchar6','q_nchar7','q_nchar8','loc','q_nchar_null', - 'q_binary','q_binary1','q_binary2','q_binary3','q_binary4','q_binary5','q_binary6','q_binary7','q_binary8','q_binary_null'] - - column_s1 = str(random.sample(fun_fix_column,i)).replace("[","").replace("]","").replace("'","") + 'q_binary','q_binary1','q_binary2','q_binary3','q_binary4','q_binary5','q_binary6','q_binary7','q_binary8','q_binary_null'] + + column_s1 = str(random.sample(fun_fix_column,i)).replace("[","").replace("]","").replace("'","") fun_column_s_1 = str(random.sample(str_functions,1))+'('+'\"'+separator+'\",'+column_s1+')' str_fun_s_1 = str(fun_column_s_1).replace("[","").replace("]","").replace("'","") - - column_s2 = str(random.sample(fun_fix_column,i)).replace("[","").replace("]","").replace("'","") + + column_s2 = str(random.sample(fun_fix_column,i)).replace("[","").replace("]","").replace("'","") fun_column_s_2 = str(random.sample(str_functions,1))+'('+'\"'+separator+'\",'+column_s2+')' str_fun_s_2 = str(fun_column_s_2).replace("[","").replace("]","").replace("'","") - + fun_fix_column_s_j = ['(t1.q_nchar)','(t1.q_nchar1)','(t1.q_nchar2)','(t1.q_nchar3)','(t1.q_nchar4)','(t1.q_nchar5)','(t1.q_nchar6)','(t1.q_nchar7)','(t1.q_nchar8)','(t1.q_nchar_null)','(t1.loc)', '(t2.q_nchar)','(t2.q_nchar1)','(t2.q_nchar2)','(t2.q_nchar3)','(t2.q_nchar4)','(t2.q_nchar5)','(t2.q_nchar6)','(t2.q_nchar7)','(t2.q_nchar8)','(t2.q_nchar_null)','(t2.loc)', '(t1.q_binary)','(t1.q_binary1)','(t1.q_binary2)','(t1.q_binary3)','(t1.q_binary4)','(t1.q_binary5)','(t1.q_binary6)','(t1.q_binary7)','(t1.q_binary8)','(t1.q_binary_null)', '(t2.q_binary)','(t2.q_binary1)','(t2.q_binary2)','(t2.q_binary3)','(t2.q_binary4)','(t2.q_binary5)','(t2.q_binary6)','(t2.q_binary7)','(t2.q_binary8)','(t2.q_binary_null)'] - - column_j_s1 = str(random.sample(fun_fix_column_s_j,i)).replace("[","").replace("]","").replace("'","") + + column_j_s1 = str(random.sample(fun_fix_column_s_j,i)).replace("[","").replace("]","").replace("'","") fun_column_join_s_1 = str(random.sample(str_functions,1))+'('+'\"'+separator+'\",'+column_j_s1+')' str_fun_join_s_1 = str(fun_column_join_s_1).replace("[","").replace("]","").replace("'","") - - column_j_s2 = str(random.sample(fun_fix_column_s_j,i)).replace("[","").replace("]","").replace("'","") + + column_j_s2 = str(random.sample(fun_fix_column_s_j,i)).replace("[","").replace("]","").replace("'","") fun_column_join_s_2 = str(random.sample(str_functions,1))+'('+'\"'+separator+'\",'+column_j_s2+')' str_fun_join_s_2 = str(fun_column_join_s_2).replace("[","").replace("]","").replace("'","") - - + + tdSql.query("select 1-1 as str_nest from stable_1 limit 1;") for i in range(self.fornum): if (strlist == ['LTRIM','RTRIM','LOWER','UPPER']) or (strlist == ['SUBSTR']) or (strlist == ['CONCAT']) or (strlist == ['CONCAT_WS']) : - sql = "select ts , LTRIM(asct1), LOWER(asct1), RTRIM(asct2), UPPER(asct2) from ( select " - sql += "%s as asct1, " % str_fun_1 - sql += "%s as asct2, " % str_fun_2 + sql = "select ts , LTRIM(asct1), LOWER(asct1), RTRIM(asct2), UPPER(asct2) from ( select " + sql += "%s as asct1, " % str_fun_1 + sql += "%s as asct2, " % str_fun_2 sql += "%s, " % random.choice(self.s_s_select) - sql += "%s, " % random.choice(self.q_select) + sql += "%s, " % random.choice(self.q_select) sql += "ts from regular_table_1 where " sql += "%s " % random.choice(self.q_where) sql += "%s " % random.choice(self.order_where) sql += ");" - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) tdSql.query(sql) tdSql.checkRows(100) self.cur1.execute(sql) elif (strlist == ['LENGTH','CHAR_LENGTH']): - sql = "select sum(asct1), min(asct1), max(asct2), avg(asct2) from ( select " - sql += "%s as asct1, " % str_fun_1 - sql += "%s as asct2, " % str_fun_2 + sql = "select sum(asct1), min(asct1), max(asct2), avg(asct2) from ( select " + sql += "%s as asct1, " % str_fun_1 + sql += "%s as asct2, " % str_fun_2 sql += "%s, " % random.choice(self.s_s_select) - sql += "%s, " % random.choice(self.q_select) + sql += "%s, " % random.choice(self.q_select) sql += "ts from regular_table_1 where " sql += "%s " % random.choice(self.q_where) sql += "%s " % random.choice(self.order_where) sql += ");" - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) tdSql.query(sql) self.cur1.execute(sql) - + tdSql.query("select 1-2 as str_nest from stable_1 limit 1;") for i in range(self.fornum): if (strlist == ['LTRIM','RTRIM','LOWER','UPPER']) or (strlist == ['SUBSTR']) or (strlist == ['CONCAT']) or (strlist == ['CONCAT_WS']) : sql = "select ts , LTRIM(asct1), LOWER(asct1), RTRIM(asct2), UPPER(asct2) from ( select " - sql += "%s as asct1, " % str_fun_1 + sql += "%s as asct1, " % str_fun_1 sql += "%s, " % random.choice(self.s_s_select) - sql += "%s, " % random.choice(self.q_select) + sql += "%s, " % random.choice(self.q_select) sql += "ts ts from regular_table_1 where " sql += "%s " % random.choice(self.q_where) sql += "%s )" % random.choice(self.order_where) - sql += "%s " % random.choice(self.unionall_or_union) + sql += "%s " % random.choice(self.unionall_or_union) sql += "select ts , asct2 from ( select " - sql += "%s as asct2, " % str_fun_2 + sql += "%s as asct2, " % str_fun_2 sql += "%s, " % random.choice(self.s_s_select) - sql += "%s, " % random.choice(self.q_select) + sql += "%s, " % random.choice(self.q_select) sql += "ts ts from regular_table_1 where " - sql += "%s " % random.choice(self.q_where) + sql += "%s " % random.choice(self.q_where) #sql += "%s " % random.choice(having_support) sql += "%s " % random.choice(self.order_where) sql += "%s " % random.choice(self.limit1_where) sql += ")" - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) #TD-15437 tdSql.query(sql) - #TD-15437 self.cur1.execute(sql) - elif (strlist == ['LENGTH','CHAR_LENGTH']): + #TD-15437 self.cur1.execute(sql) + elif (strlist == ['LENGTH','CHAR_LENGTH']): sql = "select sum(asct1), min(asct1), max(asct2), avg(asct2) from ( select " - sql += "%s as asct1, " % str_fun_1 + sql += "%s as asct1, " % str_fun_1 sql += "%s, " % random.choice(self.s_s_select) - sql += "%s, " % random.choice(self.q_select) + sql += "%s, " % random.choice(self.q_select) sql += "ts ts from regular_table_1 where " sql += "%s " % random.choice(self.q_where) sql += "%s )" % random.choice(self.order_where) - sql += "%s " % random.choice(self.unionall_or_union) + sql += "%s " % random.choice(self.unionall_or_union) sql += "select ts , asct2 from ( select " - sql += "%s as asct2, " % str_fun_2 + sql += "%s as asct2, " % str_fun_2 sql += "%s, " % random.choice(self.s_s_select) - sql += "%s, " % random.choice(self.q_select) + sql += "%s, " % random.choice(self.q_select) sql += "ts ts from regular_table_1 where " - sql += "%s " % random.choice(self.q_where) + sql += "%s " % random.choice(self.q_where) #sql += "%s " % random.choice(having_support) sql += "%s " % random.choice(self.order_where) sql += "%s " % random.choice(self.limit1_where) sql += ")" - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) #TD-15437 tdSql.query(sql) - #TD-15437 self.cur1.execute(sql) - + #TD-15437 self.cur1.execute(sql) + tdSql.query("select 1-3 as str_nest from stable_1 limit 1;") for i in range(self.fornum): if (strlist == ['LTRIM','RTRIM','LOWER','UPPER']) or (strlist == ['SUBSTR']) or (strlist == ['CONCAT']) or (strlist == ['CONCAT_WS']): @@ -1601,20 +1601,20 @@ class TDTestCase: sql += "%s as asct1, ts ," % str_fun_1 sql += "%s as asct2, " % str_fun_2 sql += "%s, " % random.choice(self.s_s_select) - sql += "%s, " % random.choice(self.q_select) + sql += "%s, " % random.choice(self.q_select) sql += "ts from regular_table_1 where " sql += "%s " % random.choice(self.q_where) - sql += "%s select " % random.choice(self.unionall_or_union) + sql += "%s select " % random.choice(self.unionall_or_union) sql += "%s as asct2, ts ," % str_fun_2 sql += "%s as asct1, " % str_fun_1 sql += "%s, " % random.choice(self.s_s_select) - sql += "%s, " % random.choice(self.q_select) + sql += "%s, " % random.choice(self.q_select) sql += "ts from regular_table_2 where " sql += "%s " % random.choice(self.q_where) sql += "%s " % random.choice(self.order_where) sql += ")" - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) #TD-15473 tdSql.query(sql) #self.cur1.execute(sql) elif (strlist == ['LENGTH','CHAR_LENGTH']): @@ -1622,88 +1622,88 @@ class TDTestCase: sql += "%s as asct1, ts ," % str_fun_1 sql += "%s as asct2, " % str_fun_2 sql += "%s, " % random.choice(self.s_s_select) - sql += "%s, " % random.choice(self.q_select) + sql += "%s, " % random.choice(self.q_select) sql += "ts from regular_table_1 where " sql += "%s " % random.choice(self.q_where) - sql += "%s select " % random.choice(self.unionall_or_union) + sql += "%s select " % random.choice(self.unionall_or_union) sql += "%s as asct2, ts ," % str_fun_2 sql += "%s as asct1, " % str_fun_1 sql += "%s, " % random.choice(self.s_s_select) - sql += "%s, " % random.choice(self.q_select) + sql += "%s, " % random.choice(self.q_select) sql += "ts from regular_table_2 where " sql += "%s " % random.choice(self.q_where) sql += "%s " % random.choice(self.order_where) sql += ")" - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) #TD-15473 tdSql.query(sql) #self.cur1.execute(sql) - + tdSql.query("select 1-4 as str_nest from stable_1 limit 1;") for i in range(self.fornum): if (strlist == ['LTRIM','RTRIM','LOWER','UPPER']) or (strlist == ['SUBSTR']) or (strlist == ['CONCAT']) or (strlist == ['CONCAT_WS']): sql = "select ts , LTRIM(asct1), LOWER(asct1), RTRIM(asct2), UPPER(asct2) from ( select t1.ts as ts," - sql += "%s as asct2, " % str_fun_join_1 - sql += "%s as asct1, " % str_fun_join_2 - sql += "%s, " % str_fun_join_1 - sql += "t1.%s, " % random.choice(self.q_select) - sql += "t2.%s, " % random.choice(self.q_select) + sql += "%s as asct2, " % str_fun_join_1 + sql += "%s as asct1, " % str_fun_join_2 + sql += "%s, " % str_fun_join_1 + sql += "t1.%s, " % random.choice(self.q_select) + sql += "t2.%s, " % random.choice(self.q_select) sql += "t2.ts from regular_table_1 t1 , regular_table_2 t2 where t1.ts = t2.ts and " sql += "%s " % random.choice(self.q_u_where) sql += "and %s " % random.choice(self.q_u_or_where) sql += "%s " % random.choice(self.order_u_where) sql += ");" - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) tdSql.query(sql) tdSql.checkRows(100) self.cur1.execute(sql) elif (strlist == ['LENGTH','CHAR_LENGTH']): sql = "select sum(asct1), min(asct1), max(asct2), avg(asct2) from ( select t1.ts as ts," - sql += "%s as asct2, " % str_fun_join_1 - sql += "%s as asct1, " % str_fun_join_2 - sql += "%s, " % str_fun_join_1 - sql += "t1.%s, " % random.choice(self.q_select) - sql += "t2.%s, " % random.choice(self.q_select) + sql += "%s as asct2, " % str_fun_join_1 + sql += "%s as asct1, " % str_fun_join_2 + sql += "%s, " % str_fun_join_1 + sql += "t1.%s, " % random.choice(self.q_select) + sql += "t2.%s, " % random.choice(self.q_select) sql += "t2.ts from regular_table_1 t1 , regular_table_2 t2 where t1.ts = t2.ts and " sql += "%s " % random.choice(self.q_u_where) sql += "and %s " % random.choice(self.q_u_or_where) sql += "%s " % random.choice(self.order_u_where) sql += ");" - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) tdSql.query(sql) self.cur1.execute(sql) - + tdSql.query("select 1-5 as str_nest from stable_1 limit 1;") for i in range(self.fornum): if (strlist == ['LTRIM','RTRIM','LOWER','UPPER']) or (strlist == ['SUBSTR']) or (strlist == ['CONCAT']) or (strlist == ['CONCAT_WS']): sql = "select ts ," - sql += "%s, " % str_fun_1 + sql += "%s, " % str_fun_1 + sql += "%s, " % random.choice(self.q_select) sql += "%s, " % random.choice(self.q_select) - sql += "%s, " % random.choice(self.q_select) sql += "%s " % str_fun_2 sql += " from ( select * from regular_table_1 ) where " sql += "%s " % random.choice(self.q_where) sql += "%s " % random.choice(self.order_where) sql += " ;" - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) tdSql.query(sql) tdSql.checkRows(100) self.cur1.execute(sql) elif (strlist == ['LENGTH','CHAR_LENGTH']): sql = "select ts ," - sql += "%s, " % str_fun_1 + sql += "%s, " % str_fun_1 + sql += "%s, " % random.choice(self.q_select) sql += "%s, " % random.choice(self.q_select) - sql += "%s, " % random.choice(self.q_select) sql += "%s " % str_fun_2 sql += " from ( select * from regular_table_1 ) where " sql += "%s " % random.choice(self.q_where) sql += "%s " % random.choice(self.order_where) sql += " ;" - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) tdSql.query(sql) tdSql.checkRows(100) self.cur1.execute(sql) @@ -1712,34 +1712,34 @@ class TDTestCase: for i in range(self.fornum): if (strlist == ['LTRIM','RTRIM','LOWER','UPPER']) or (strlist == ['SUBSTR']) or (strlist == ['CONCAT']) or (strlist == ['CONCAT_WS']): sql = "select ts , LTRIM(asct1), LOWER(asct1), RTRIM(asct2), UPPER(asct2) from ( select t1.ts as ts," - sql += "%s as asct2, " % str_fun_join_1 - sql += "%s as asct1, " % str_fun_join_2 - sql += "t1.%s, " % random.choice(self.q_select) - sql += "t2.%s, " % random.choice(self.q_select) - sql += "%s, " % str_fun_join_1 + sql += "%s as asct2, " % str_fun_join_1 + sql += "%s as asct1, " % str_fun_join_2 + sql += "t1.%s, " % random.choice(self.q_select) + sql += "t2.%s, " % random.choice(self.q_select) + sql += "%s, " % str_fun_join_1 sql += "t2.ts from regular_table_1 t1 , regular_table_2 t2 where t1.ts = t2.ts and " sql += "%s " % random.choice(self.q_u_where) sql += "and %s )" % random.choice(self.q_u_or_where) sql += "%s " % random.choice(self.order_where) sql += "%s " % random.choice(self.limit1_where) - tdLog.info(sql) - tdLog.info(len(sql)) - tdSql.query(sql) + tdLog.info(sql) + tdLog.info(len(sql)) + tdSql.query(sql) self.cur1.execute(sql) elif (strlist == ['LENGTH','CHAR_LENGTH']): sql = "select sum(asct1), min(asct1), max(asct2), avg(asct2) from ( select t1.ts as ts," - sql += "%s as asct2, " % str_fun_join_1 - sql += "%s as asct1, " % str_fun_join_2 - sql += "t1.%s, " % random.choice(self.q_select) - sql += "t2.%s, " % random.choice(self.q_select) - sql += "%s, " % str_fun_join_1 + sql += "%s as asct2, " % str_fun_join_1 + sql += "%s as asct1, " % str_fun_join_2 + sql += "t1.%s, " % random.choice(self.q_select) + sql += "t2.%s, " % random.choice(self.q_select) + sql += "%s, " % str_fun_join_1 sql += "t2.ts from regular_table_1 t1 , regular_table_2 t2 where t1.ts = t2.ts and " sql += "%s " % random.choice(self.q_u_where) sql += "and %s )" % random.choice(self.q_u_or_where) sql += "%s " % random.choice(self.limit1_where) - tdLog.info(sql) - tdLog.info(len(sql)) - tdSql.query(sql) + tdLog.info(sql) + tdLog.info(len(sql)) + tdSql.query(sql) self.cur1.execute(sql) tdSql.query("select 1-7 as str_nest from stable_1 limit 1;") @@ -1748,13 +1748,13 @@ class TDTestCase: sql = "select ts , LTRIM(asct1), LOWER(asct1), RTRIM(asct2), UPPER(asct2) from ( select " sql += "%s as asct1, ts ," % str_fun_s_1 sql += "%s as asct2, " % str_fun_s_2 - sql += "%s, " % random.choice(self.q_select) - sql += "%s, " % random.choice(self.t_select) + sql += "%s, " % random.choice(self.q_select) + sql += "%s, " % random.choice(self.t_select) sql += "ts from stable_1 where " sql += "%s " % random.choice(self.qt_where) sql += "%s " % random.choice(self.order_where) sql += ") ;" - tdLog.info(sql) + tdLog.info(sql) tdLog.info(len(sql)) # tdSql.query(sql) # tdSql.checkRows(300) @@ -1763,17 +1763,17 @@ class TDTestCase: sql = "select sum(asct1), min(asct1), max(asct2), avg(asct2) from ( select " sql += "%s as asct1, ts ," % str_fun_s_1 sql += "%s as asct2, " % str_fun_s_2 - sql += "%s, " % random.choice(self.q_select) - sql += "%s, " % random.choice(self.t_select) + sql += "%s, " % random.choice(self.q_select) + sql += "%s, " % random.choice(self.t_select) sql += "ts from stable_1 where " sql += "%s " % random.choice(self.qt_where) sql += "%s " % random.choice(self.order_where) sql += ") ;" - tdLog.info(sql) + tdLog.info(sql) tdLog.info(len(sql)) # tdSql.query(sql) # self.cur1.execute(sql)# TD-16039 - + tdSql.query("select 1-8 as str_nest from stable_1 limit 1;") for i in range(self.fornum): if (strlist == ['LTRIM','RTRIM','LOWER','UPPER']) or (strlist == ['SUBSTR']) or (strlist == ['CONCAT']) or (strlist == ['CONCAT_WS']): @@ -1782,13 +1782,13 @@ class TDTestCase: sql += "%s, " % random.choice(self.s_s_select) sql += "%s as asct1, ts ," % str_fun_s_1 sql += "%s as asct2, " % str_fun_s_2 - sql += "%s, " % random.choice(self.q_select) - sql += "%s, " % random.choice(self.t_select) + sql += "%s, " % random.choice(self.q_select) + sql += "%s, " % random.choice(self.t_select) sql += "ts from stable_1 where " sql += "%s " % random.choice(self.qt_where) sql += "%s " % random.choice(self.order_where) sql += ") ;" - tdLog.info(sql) + tdLog.info(sql) tdLog.info(len(sql)) # tdSql.query(sql) # tdSql.checkRows(300) @@ -1799,13 +1799,13 @@ class TDTestCase: sql += "%s, " % random.choice(self.s_s_select) sql += "%s as asct1, ts ," % str_fun_s_1 sql += "%s as asct2, " % str_fun_s_2 - sql += "%s, " % random.choice(self.q_select) - sql += "%s, " % random.choice(self.t_select) + sql += "%s, " % random.choice(self.q_select) + sql += "%s, " % random.choice(self.t_select) sql += "ts from stable_1 where " sql += "%s " % random.choice(self.qt_where) sql += "%s " % random.choice(self.order_where) sql += ") ;" - tdLog.info(sql) + tdLog.info(sql) tdLog.info(len(sql)) # tdSql.query(sql) # self.cur1.execute(sql)# TD-16039 @@ -1814,12 +1814,12 @@ class TDTestCase: for i in range(self.fornum): if (strlist == ['LTRIM','RTRIM','LOWER','UPPER']) or (strlist == ['SUBSTR']) or (strlist == ['CONCAT']) or (strlist == ['CONCAT_WS']): sql = "select ts , LTRIM(asct1), LOWER(asct1), RTRIM(asct2), UPPER(asct2) from ( select t1.ts as ts," - sql += "%s as asct2, " % str_fun_join_s_1 - sql += "%s as asct1, " % str_fun_join_s_2 - sql += "t1.%s, " % random.choice(self.q_select) - sql += "t1.%s, " % random.choice(self.q_select) - sql += "t2.%s, " % random.choice(self.q_select) - sql += "t2.%s, " % random.choice(self.q_select) + sql += "%s as asct2, " % str_fun_join_s_1 + sql += "%s as asct1, " % str_fun_join_s_2 + sql += "t1.%s, " % random.choice(self.q_select) + sql += "t1.%s, " % random.choice(self.q_select) + sql += "t2.%s, " % random.choice(self.q_select) + sql += "t2.%s, " % random.choice(self.q_select) sql += "t2.ts from stable_1 t1 , stable_2 t2 where t1.ts = t2.ts and " sql += "%s " % random.choice(self.t_join_where) sql += "and %s " % random.choice(self.t_u_where) @@ -1827,18 +1827,18 @@ class TDTestCase: sql += "%s " % random.choice(self.order_u_where) sql += "%s " % random.choice(self.limit1_where) sql += ") ;" - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) # tdSql.query(sql) # self.cur1.execute(sql) # TD-16039 elif (strlist == ['LENGTH','CHAR_LENGTH']): sql = "select sum(asct1), min(asct1), max(asct2), avg(asct2) from ( select t1.ts as ts," - sql += "%s as asct2, " % str_fun_join_s_1 - sql += "%s as asct1, " % str_fun_join_s_2 - sql += "t1.%s, " % random.choice(self.q_select) - sql += "t1.%s, " % random.choice(self.q_select) - sql += "t2.%s, " % random.choice(self.q_select) - sql += "t2.%s, " % random.choice(self.q_select) + sql += "%s as asct2, " % str_fun_join_s_1 + sql += "%s as asct1, " % str_fun_join_s_2 + sql += "t1.%s, " % random.choice(self.q_select) + sql += "t1.%s, " % random.choice(self.q_select) + sql += "t2.%s, " % random.choice(self.q_select) + sql += "t2.%s, " % random.choice(self.q_select) sql += "t2.ts from stable_1 t1 , stable_2 t2 where t1.ts = t2.ts and " sql += "%s " % random.choice(self.t_join_where) sql += "and %s " % random.choice(self.t_u_where) @@ -1846,11 +1846,11 @@ class TDTestCase: sql += "%s " % random.choice(self.order_u_where) sql += "%s " % random.choice(self.limit1_where) sql += ") ;" - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) # tdSql.query(sql) # self.cur1.execute(sql)# TD-16039 - + self.restartDnodes() tdSql.query("select 1-10 as str_nest from stable_1 limit 1;") for i in range(self.fornum): @@ -1874,8 +1874,8 @@ class TDTestCase: sql += "%s " % random.choice(self.order_where) sql += "%s " % random.choice(self.limit1_where) sql += ")" - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) #TD-15437 tdSql.query(sql) #TD-15437 self.cur1.execute(sql) elif (strlist == ['LENGTH','CHAR_LENGTH']): @@ -1898,11 +1898,11 @@ class TDTestCase: sql += "%s " % random.choice(self.order_where) sql += "%s " % random.choice(self.limit1_where) sql += ")" - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) #TD-15437 tdSql.query(sql) #TD-15437 self.cur1.execute(sql) - + #3 inter union not support tdSql.query("select 1-11 as str_nest from stable_1 limit 1;") for i in range(self.fornum): @@ -1927,8 +1927,8 @@ class TDTestCase: sql += "%s " % random.choice(self.order_where) sql += "%s " % random.choice(self.limit1_where) sql += ")" - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) #TD-15837 tdSql.query(sql) # self.cur1.execute(sql) elif (strlist == ['LENGTH','CHAR_LENGTH']): @@ -1952,8 +1952,8 @@ class TDTestCase: sql += "%s " % random.choice(self.order_where) sql += "%s " % random.choice(self.limit1_where) sql += ")" - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) #TD-15837 tdSql.query(sql) # self.cur1.execute(sql) @@ -1961,81 +1961,81 @@ class TDTestCase: for i in range(self.fornum): if (strlist == ['LTRIM','RTRIM','LOWER','UPPER']) or (strlist == ['SUBSTR']) or (strlist == ['CONCAT']) or (strlist == ['CONCAT_WS']): sql = "select ts , LTRIM(asct1), LOWER(asct1), RTRIM(asct2), UPPER(asct2) from ( select t1.ts as ts," - sql += "%s as asct2, " % str_fun_join_s_1 - sql += "%s as asct1, " % str_fun_join_s_2 - sql += "t1.%s, " % random.choice(self.q_select) - sql += "t1.%s, " % random.choice(self.q_select) - sql += "t2.%s, " % random.choice(self.q_select) - sql += "t2.%s, " % random.choice(self.q_select) + sql += "%s as asct2, " % str_fun_join_s_1 + sql += "%s as asct1, " % str_fun_join_s_2 + sql += "t1.%s, " % random.choice(self.q_select) + sql += "t1.%s, " % random.choice(self.q_select) + sql += "t2.%s, " % random.choice(self.q_select) + sql += "t2.%s, " % random.choice(self.q_select) sql += "t2.ts from stable_1 t1 , stable_2 t2 where t1.ts = t2.ts and " sql += "%s " % random.choice(self.t_u_where) sql += "and %s " % random.choice(self.t_u_or_where) sql += "%s " % random.choice(self.order_u_where) sql += "%s " % random.choice(self.limit1_where) sql += ");" - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) # tdSql.query(sql) # self.cur1.execute(sql)# TD-16039 elif (strlist == ['LENGTH','CHAR_LENGTH']): sql = "select sum(asct1), min(asct1), max(asct2), avg(asct2) from ( select t1.ts as ts," - sql += "%s as asct2, " % str_fun_join_s_1 - sql += "%s as asct1, " % str_fun_join_s_2 - sql += "t1.%s, " % random.choice(self.q_select) - sql += "t1.%s, " % random.choice(self.q_select) - sql += "t2.%s, " % random.choice(self.q_select) - sql += "t2.%s, " % random.choice(self.q_select) + sql += "%s as asct2, " % str_fun_join_s_1 + sql += "%s as asct1, " % str_fun_join_s_2 + sql += "t1.%s, " % random.choice(self.q_select) + sql += "t1.%s, " % random.choice(self.q_select) + sql += "t2.%s, " % random.choice(self.q_select) + sql += "t2.%s, " % random.choice(self.q_select) sql += "t2.ts from stable_1 t1 , stable_2 t2 where t1.ts = t2.ts and " sql += "%s " % random.choice(self.t_u_where) sql += "and %s " % random.choice(self.t_u_or_where) sql += "%s " % random.choice(self.order_u_where) sql += "%s " % random.choice(self.limit1_where) sql += ");" - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) # tdSql.query(sql) # self.cur1.execute(sql)# TD-16039 - + tdSql.query("select 1-13 as str_nest from stable_1 limit 1;") for i in range(self.fornum): if (strlist == ['LTRIM','RTRIM','LOWER','UPPER']) or (strlist == ['SUBSTR']) or (strlist == ['CONCAT']) or (strlist == ['CONCAT_WS']): sql = "select ts ," - sql += "%s, " % str_fun_1 + sql += "%s, " % str_fun_1 + sql += "%s, " % random.choice(self.q_select) sql += "%s, " % random.choice(self.q_select) - sql += "%s, " % random.choice(self.q_select) sql += "%s, " % str_fun_2 - sql += "%s " % random.choice(self.t_select) + sql += "%s " % random.choice(self.t_select) sql += " from ( select * from stable_1 where " sql += "%s " % random.choice(self.qt_where) sql += "%s " % random.choice(self.order_where) sql += ") ;" - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) # tdSql.query(sql) # tdSql.checkRows(300) # self.cur1.execute(sql) # TD-16039 elif (strlist == ['LENGTH','CHAR_LENGTH']): sql = "select ts ," - sql += "%s, " % str_fun_1 + sql += "%s, " % str_fun_1 + sql += "%s, " % random.choice(self.q_select) sql += "%s, " % random.choice(self.q_select) - sql += "%s, " % random.choice(self.q_select) sql += "%s, " % str_fun_2 - sql += "%s " % random.choice(self.t_select) + sql += "%s " % random.choice(self.t_select) sql += " from ( select * from stable_1 where " sql += "%s " % random.choice(self.qt_where) sql += "%s " % random.choice(self.order_where) sql += ") ;" - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) # tdSql.query(sql) # tdSql.checkRows(300) # self.cur1.execute(sql)# TD-16039 - + tdSql.query("select 1-14 as str_nest from stable_1 limit 1;") for i in range(self.fornum): if (strlist == ['LTRIM','RTRIM','LOWER','UPPER']) or (strlist == ['SUBSTR']) or (strlist == ['CONCAT']) or (strlist == ['CONCAT_WS']): sql = "select LTRIM(asct1), LOWER(asct1), RTRIM(asct2), UPPER(asct2) from ( select " - sql += "%s as asct1, " % str_fun_s_1 + sql += "%s as asct1, " % str_fun_s_1 sql += "%s as asct2" % str_fun_s_2 sql += " from stable_1 where " sql += "%s " % random.choice(self.q_where) @@ -2043,13 +2043,13 @@ class TDTestCase: sql += "%s " % random.choice(self.order_desc_where) sql += "%s " % random.choice([self.limit_where[2] , self.limit_where[3]] ) sql += " ) ;" - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) # tdSql.query(sql) # self.cur1.execute(sql) # TD-16039 elif (strlist == ['LENGTH','CHAR_LENGTH']): sql = "select sum(asct1), min(asct1), max(asct2), avg(asct2) from ( select " - sql += "%s as asct1, " % str_fun_s_1 + sql += "%s as asct1, " % str_fun_s_1 sql += "%s as asct2" % str_fun_s_2 sql += " from stable_1 where " sql += "%s " % random.choice(self.q_where) @@ -2057,54 +2057,54 @@ class TDTestCase: sql += "%s " % random.choice(self.order_desc_where) sql += "%s " % random.choice([self.limit_where[2] , self.limit_where[3]] ) sql += " ) ;" - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) # tdSql.query(sql) # self.cur1.execute(sql) # TD-16039 - + tdSql.query("select 1-15 as str_nest from stable_1 limit 1;") for i in range(self.fornum): if (strlist == ['LTRIM','RTRIM','LOWER','UPPER']) or (strlist == ['SUBSTR']) or (strlist == ['CONCAT']) or (strlist == ['CONCAT_WS']): sql = "select ts , LTRIM(asct1), LOWER(asct1), RTRIM(asct2), UPPER(asct2) from ( select t1.ts as ts," - sql += "%s as asct2, " % str_fun_join_s_1 - sql += "%s as asct1, " % str_fun_join_s_2 - sql += "t1.%s, " % random.choice(self.q_select) - sql += "t1.%s, " % random.choice(self.q_select) - sql += "t2.%s, " % random.choice(self.q_select) - sql += "t2.%s " % random.choice(self.q_select) + sql += "%s as asct2, " % str_fun_join_s_1 + sql += "%s as asct1, " % str_fun_join_s_2 + sql += "t1.%s, " % random.choice(self.q_select) + sql += "t1.%s, " % random.choice(self.q_select) + sql += "t2.%s, " % random.choice(self.q_select) + sql += "t2.%s " % random.choice(self.q_select) sql += "from stable_1 t1, stable_2 t2 where t1.ts = t2.ts and " sql += "%s " % random.choice(self.t_join_where) sql += " and %s " % random.choice(self.qt_u_or_where) sql += "%s " % random.choice(self.partiton_where_j) sql += "%s " % random.choice(self.slimit1_where) - sql += ") " + sql += ") " sql += "%s " % random.choice(self.order_desc_where) sql += "%s ;" % random.choice(self.limit_u_where) - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) #TD-15955 tdSql.query(sql) - #TD-15955 self.cur1.execute(sql) + #TD-15955 self.cur1.execute(sql) elif (strlist == ['LENGTH','CHAR_LENGTH']): sql = "select sum(asct1), min(asct1), max(asct2), avg(asct2) from ( select t1.ts as ts," - sql += "%s as asct2, " % str_fun_join_s_1 - sql += "%s as asct1, " % str_fun_join_s_2 - sql += "t1.%s, " % random.choice(self.q_select) - sql += "t1.%s, " % random.choice(self.q_select) - sql += "t2.%s, " % random.choice(self.q_select) - sql += "t2.%s " % random.choice(self.q_select) + sql += "%s as asct2, " % str_fun_join_s_1 + sql += "%s as asct1, " % str_fun_join_s_2 + sql += "t1.%s, " % random.choice(self.q_select) + sql += "t1.%s, " % random.choice(self.q_select) + sql += "t2.%s, " % random.choice(self.q_select) + sql += "t2.%s " % random.choice(self.q_select) sql += "from stable_1 t1, stable_2 t2 where t1.ts = t2.ts and " sql += "%s " % random.choice(self.t_join_where) sql += " and %s " % random.choice(self.qt_u_or_where) sql += "%s " % random.choice(self.partiton_where_j) sql += "%s " % random.choice(self.slimit1_where) - sql += ") " + sql += ") " sql += "%s " % random.choice(self.order_desc_where) sql += "%s ;" % random.choice(self.limit_u_where) - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) #TD-15955 tdSql.query(sql) - #TD-15955 self.cur1.execute(sql) - + #TD-15955 self.cur1.execute(sql) + #taos -f sql startTime_taos_f = time.time() print("taos -f %s sql start!" %strlist) @@ -2112,169 +2112,169 @@ class TDTestCase: _ = subprocess.check_output(taos_cmd1, shell=True).decode("utf-8") print("taos -f %s sql over!" %strlist) endTime_taos_f = time.time() - print("taos_f total time %ds" % (endTime_taos_f - startTime_taos_f)) - - print("=========%s====over=============" %strlist) - + print("taos_f total time %ds" % (endTime_taos_f - startTime_taos_f)) + + print("=========%s====over=============" %strlist) + def time_nest(self,timelist): - - print("==========%s===start=============" %timelist) - os.system("rm -rf %s/%s.sql" % (self.testcasePath,self.testcaseFilename)) - + + print("==========%s===start=============" %timelist) + os.system("rm -rf %s/%s.sql" % (self.testcasePath,self.testcaseFilename)) + self.dropandcreateDB_random("%s" %self.db_nest, 1) - + if (timelist == ['NOW','TODAY']) or (timelist == ['TIMEZONE']): - time_functions = timelist - fun_fix_column = ['()'] + time_functions = timelist + fun_fix_column = ['()'] fun_column_1 = random.sample(time_functions,1)+random.sample(fun_fix_column,1) time_fun_1 = str(fun_column_1).replace("[","").replace("]","").replace("'","").replace(", ","") fun_column_2 = random.sample(time_functions,1)+random.sample(fun_fix_column,1) time_fun_2 = str(fun_column_2).replace("[","").replace("]","").replace("'","").replace(", ","") - - fun_fix_column_j = ['()'] + + fun_fix_column_j = ['()'] fun_column_join_1 = random.sample(time_functions,1)+random.sample(fun_fix_column_j,1) time_fun_join_1 = str(fun_column_join_1).replace("[","").replace("]","").replace("'","").replace(", ","") fun_column_join_2 = random.sample(time_functions,1)+random.sample(fun_fix_column_j,1) time_fun_join_2 = str(fun_column_join_2).replace("[","").replace("]","").replace("'","").replace(", ","") elif (timelist == ['TIMETRUNCATE']): - time_functions = timelist - - t = time.time() - t_to_s = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(t)) + time_functions = timelist + + t = time.time() + t_to_s = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(t)) fun_fix_column = ['q_ts','ts','_c0','_C0','_rowts','1600000000000','1600000000000000','1600000000000000000', - '%d' %t, '%d000' %t, '%d000000' %t,'t_to_s'] - - timeunits = ['1u' , '1a' ,'1s', '1m' ,'1h', '1d'] - timeunit = str(random.sample(timeunits,1)).replace("[","").replace("]","").replace("'","") - - column_1 = ['(%s,timeutil)'%(random.sample(fun_fix_column,1))] + '%d' %t, '%d000' %t, '%d000000' %t,'t_to_s'] + + timeunits = ['1u' , '1a' ,'1s', '1m' ,'1h', '1d'] + timeunit = str(random.sample(timeunits,1)).replace("[","").replace("]","").replace("'","") + + column_1 = ['(%s,timeutil)'%(random.sample(fun_fix_column,1))] fun_column_1 = random.sample(time_functions,1)+random.sample(column_1,1) time_fun_1 = str(fun_column_1).replace("[","").replace("]","").replace("'","").replace(", ","").replace("\"","").replace("t_to_s","'t_to_s'") time_fun_1 = str(time_fun_1).replace("timeutil","%s" %timeunit).replace("t_to_s","%s" %t_to_s) - - column_2 = ['(%s,timeutil)'%(random.sample(fun_fix_column,1))] + + column_2 = ['(%s,timeutil)'%(random.sample(fun_fix_column,1))] fun_column_2 = random.sample(time_functions,1)+random.sample(column_2,1) time_fun_2 = str(fun_column_2).replace("[","").replace("]","").replace("'","").replace(", ","").replace("\"","").replace("t_to_s","'t_to_s'") time_fun_2 = str(time_fun_2).replace("timeutil","%s" %timeunit).replace("t_to_s","%s" %t_to_s) - - + + fun_fix_column_j = ['(t1.q_ts)','(t1.ts)', '(t2.q_ts)','(t2.ts)','(1600000000000)','(1600000000000000)','(1600000000000000000)', - '(%d)' %t, '(%d000)' %t, '(%d000000)' %t,'t_to_s'] - - column_j1 = ['(%s,timeutil)'%(random.sample(fun_fix_column_j,1))] + '(%d)' %t, '(%d000)' %t, '(%d000000)' %t,'t_to_s'] + + column_j1 = ['(%s,timeutil)'%(random.sample(fun_fix_column_j,1))] fun_column_join_1 = random.sample(time_functions,1)+random.sample(column_j1,1) time_fun_join_1 = str(fun_column_join_1).replace("[","").replace("]","").replace("'","").replace(", ","").replace("\"","").replace("t_to_s","'t_to_s'") time_fun_join_1 = str(time_fun_join_1).replace("timeutil","%s" %timeunit).replace("t_to_s","%s" %t_to_s) - - column_j2 = ['(%s,timeutil)'%(random.sample(fun_fix_column_j,1))] + + column_j2 = ['(%s,timeutil)'%(random.sample(fun_fix_column_j,1))] fun_column_join_2 = random.sample(time_functions,1)+random.sample(column_j2,1) time_fun_join_2 = str(fun_column_join_2).replace("[","").replace("]","").replace("'","").replace(", ","").replace("\"","").replace("t_to_s","'t_to_s'") time_fun_join_2 = str(time_fun_join_2).replace("timeutil","%s" %timeunit).replace("t_to_s","%s" %t_to_s) elif (timelist == ['TO_ISO8601']): - time_functions = timelist - - t = time.time() + time_functions = timelist + + t = time.time() fun_fix_column = ['(now())','(ts)','(q_ts)','(_rowts)','(_c0)','(_C0)', '(1600000000000)','(1600000000000000)','(1600000000000000000)', - '(%d)' %t, '(%d000)' %t, '(%d000000)' %t] - + '(%d)' %t, '(%d000)' %t, '(%d000000)' %t] + fun_column_1 = random.sample(time_functions,1)+random.sample(fun_fix_column,1) time_fun_1 = str(fun_column_1).replace("[","").replace("]","").replace("'","").replace(", ","") - + fun_column_2 = random.sample(time_functions,1)+random.sample(fun_fix_column,1) time_fun_2 = str(fun_column_2).replace("[","").replace("]","").replace("'","").replace(", ","") - + fun_fix_column_j = ['(t1.q_ts)','(t1.ts)', '(t2.q_ts)','(t2.ts)','(1600000000000)','(1600000000000000)','(1600000000000000000)','(now())', - '(%d)' %t, '(%d000)' %t, '(%d000000)' %t] - + '(%d)' %t, '(%d000)' %t, '(%d000000)' %t] + fun_column_join_1 = random.sample(time_functions,1)+random.sample(fun_fix_column_j,1) time_fun_join_1 = str(fun_column_join_1).replace("[","").replace("]","").replace("'","").replace(", ","") - + fun_column_join_2 = random.sample(time_functions,1)+random.sample(fun_fix_column_j,1) time_fun_join_2 = str(fun_column_join_2).replace("[","").replace("]","").replace("'","").replace(", ","") elif (timelist == ['TO_UNIXTIMESTAMP']): - time_functions = timelist - - t = time.time() - t_to_s = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(t)) - fun_fix_column = ['(q_nchar)','(q_nchar1)','(q_nchar2)','(q_nchar3)','(q_nchar4)','(q_nchar_null)','(q_binary)','(q_binary5)','(q_binary6)','(q_binary7)','(q_binary8)','(q_binary_null)','(t_to_s)'] - + time_functions = timelist + + t = time.time() + t_to_s = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(t)) + fun_fix_column = ['(q_nchar)','(q_nchar1)','(q_nchar2)','(q_nchar3)','(q_nchar4)','(q_nchar_null)','(q_binary)','(q_binary5)','(q_binary6)','(q_binary7)','(q_binary8)','(q_binary_null)','(t_to_s)'] + fun_column_1 = random.sample(time_functions,1)+random.sample(fun_fix_column,1) time_fun_1 = str(fun_column_1).replace("[","").replace("]","").replace("'","").replace(", ","").replace("t_to_s","'t_to_s'") time_fun_1 = str(time_fun_1).replace("t_to_s","%s" %t_to_s) - + fun_column_2 = random.sample(time_functions,1)+random.sample(fun_fix_column,1) time_fun_2 = str(fun_column_2).replace("[","").replace("]","").replace("'","").replace(", ","").replace("t_to_s","'t_to_s'") time_fun_2 = str(time_fun_2).replace("t_to_s","%s" %t_to_s) - - fun_fix_column_j = ['(t1.q_nchar)','(t1.q_binary)', '(t2.q_nchar)','(t2.q_binary)','(t_to_s)'] - + + fun_fix_column_j = ['(t1.q_nchar)','(t1.q_binary)', '(t2.q_nchar)','(t2.q_binary)','(t_to_s)'] + fun_column_join_1 = random.sample(time_functions,1)+random.sample(fun_fix_column_j,1) time_fun_join_1 = str(fun_column_join_1).replace("[","").replace("]","").replace("'","").replace(", ","").replace("t_to_s","'t_to_s'") time_fun_join_1 = str(time_fun_join_1).replace("t_to_s","%s" %t_to_s) - + fun_column_join_2 = random.sample(time_functions,1)+random.sample(fun_fix_column_j,1) time_fun_join_2 = str(fun_column_join_2).replace("[","").replace("]","").replace("'","").replace(", ","").replace("t_to_s","'t_to_s'") time_fun_join_2 = str(time_fun_join_2).replace("t_to_s","%s" %t_to_s) elif (timelist == ['TIMEDIFF']): - time_functions = timelist - - t = time.time() - t_to_s = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(t)) - fun_fix_column = ['(q_nchar)','(q_nchar1)','(q_nchar2)','(q_nchar3)','(q_nchar4)','(q_nchar_null)','(q_binary)','(q_binary5)','(q_binary6)','(q_binary7)','(q_binary8)','(q_binary_null)','(t_to_s)'] - + time_functions = timelist + + t = time.time() + t_to_s = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(t)) + fun_fix_column = ['(q_nchar)','(q_nchar1)','(q_nchar2)','(q_nchar3)','(q_nchar4)','(q_nchar_null)','(q_binary)','(q_binary5)','(q_binary6)','(q_binary7)','(q_binary8)','(q_binary_null)','(t_to_s)'] + fun_column_1 = random.sample(time_functions,1)+random.sample(fun_fix_column,1) time_fun_1 = str(fun_column_1).replace("[","").replace("]","").replace("'","").replace(", ","").replace("t_to_s","'t_to_s'") time_fun_1 = str(time_fun_1).replace("t_to_s","%s" %t_to_s) - + fun_column_2 = random.sample(time_functions,1)+random.sample(fun_fix_column,1) time_fun_2 = str(fun_column_2).replace("[","").replace("]","").replace("'","").replace(", ","").replace("t_to_s","'t_to_s'") time_fun_2 = str(time_fun_2).replace("t_to_s","%s" %t_to_s) - - fun_fix_column_j = ['(t1.q_nchar)','(t1.q_binary)', '(t2.q_nchar)','(t2.q_binary)','(t_to_s)'] - + + fun_fix_column_j = ['(t1.q_nchar)','(t1.q_binary)', '(t2.q_nchar)','(t2.q_binary)','(t_to_s)'] + fun_column_join_1 = random.sample(time_functions,1)+random.sample(fun_fix_column_j,1) time_fun_join_1 = str(fun_column_join_1).replace("[","").replace("]","").replace("'","").replace(", ","").replace("t_to_s","'t_to_s'") time_fun_join_1 = str(time_fun_join_1).replace("t_to_s","%s" %t_to_s) - + fun_column_join_2 = random.sample(time_functions,1)+random.sample(fun_fix_column_j,1) time_fun_join_2 = str(fun_column_join_2).replace("[","").replace("]","").replace("'","").replace(", ","").replace("t_to_s","'t_to_s'") time_fun_join_2 = str(time_fun_join_2).replace("t_to_s","%s" %t_to_s) elif (timelist == ['ELAPSED']): - time_functions = timelist - - fun_fix_column = ['(ts)','(q_ts)','(_c0)','(_C0)','(_rowts)','(ts,time_unit)','(_c0,time_unit)','(_C0,time_unit)','(_rowts,time_unit)'] - - time_units = ['nums','numm','numh','numd','numa'] - time_unit = str(random.sample(time_units,1)).replace("[","").replace("]","").replace("'","") - time_num1 = random.randint(0, 1000) - time_unit1 = time_unit.replace("num","%d" %time_num1) - time_num2 = random.randint(0, 1000) - time_unit2 = time_unit.replace("num","%d" %time_num2) - + time_functions = timelist + + fun_fix_column = ['(ts)','(q_ts)','(_c0)','(_C0)','(_rowts)','(ts,time_unit)','(_c0,time_unit)','(_C0,time_unit)','(_rowts,time_unit)'] + + time_units = ['nums','numm','numh','numd','numa'] + time_unit = str(random.sample(time_units,1)).replace("[","").replace("]","").replace("'","") + time_num1 = random.randint(0, 1000) + time_unit1 = time_unit.replace("num","%d" %time_num1) + time_num2 = random.randint(0, 1000) + time_unit2 = time_unit.replace("num","%d" %time_num2) + fun_column_1 = random.sample(time_functions,1)+random.sample(fun_fix_column,1) time_fun_1 = str(fun_column_1).replace("[","").replace("]","").replace("'","").replace(", ","").replace("time_unit","%s" %time_unit1) - + fun_column_2 = random.sample(time_functions,1)+random.sample(fun_fix_column,1) time_fun_2 = str(fun_column_2).replace("[","").replace("]","").replace("'","").replace(", ","").replace("time_unit","%s" %time_unit2) - - - fun_fix_column_j = ['(t1.ts)','(t1.q_ts)', '(t2.ts)','(t2.q_ts)','(t1.ts,time_unit)','(t1.q_ts,time_unit)','(t2.ts,time_unit)','(t2.q_ts,time_unit)'] - + + + fun_fix_column_j = ['(t1.ts)','(t1.q_ts)', '(t2.ts)','(t2.q_ts)','(t1.ts,time_unit)','(t1.q_ts,time_unit)','(t2.ts,time_unit)','(t2.q_ts,time_unit)'] + fun_column_join_1 = random.sample(time_functions,1)+random.sample(fun_fix_column_j,1) time_fun_join_1 = str(fun_column_join_1).replace("[","").replace("]","").replace("'","").replace(", ","").replace("time_unit","%s" %time_unit1) - + fun_column_join_2 = random.sample(time_functions,1)+random.sample(fun_fix_column_j,1) time_fun_join_2 = str(fun_column_join_2).replace("[","").replace("]","").replace("'","").replace(", ","").replace("time_unit","%s" %time_unit2) - - + + elif (timelist == ['CAST']) : - str_functions = timelist + str_functions = timelist #下面的4个是全的,这个只是1个 i = random.randint(1,4) if i ==1: @@ -2282,33 +2282,33 @@ class TDTestCase: fun_fix_column = ['q_bool','q_bool_null','q_bigint','q_bigint_null','q_smallint','q_smallint_null', 'q_tinyint','q_tinyint_null','q_int','q_int_null','q_float','q_float_null','q_double','q_double_null'] type_names = ['BIGINT','BINARY(100)','TIMESTAMP','NCHAR(100)','BIGINT UNSIGNED'] - - type_name1 = str(random.sample(type_names,1)).replace("[","").replace("]","").replace("'","") + + type_name1 = str(random.sample(type_names,1)).replace("[","").replace("]","").replace("'","") fun_column_1 = str(random.sample(str_functions,1))+'('+str(random.sample(fun_fix_column,1))+' AS '+type_name1+')' time_fun_1 = str(fun_column_1).replace("[","").replace("]","").replace("'","") - - type_name2 = str(random.sample(type_names,1)).replace("[","").replace("]","").replace("'","") + + type_name2 = str(random.sample(type_names,1)).replace("[","").replace("]","").replace("'","") fun_column_2 = str(random.sample(str_functions,1))+'('+str(random.sample(fun_fix_column,1))+' AS '+type_name2+')' time_fun_2 = str(fun_column_2).replace("[","").replace("]","").replace("'","") - + fun_fix_column_j = ['t1.q_bool','t1.q_bool_null','t1.q_bigint','t1.q_bigint_null','t1.q_smallint','t1.q_smallint_null', 't1.q_tinyint','t1.q_tinyint_null','t1.q_int','t1.q_int_null','t1.q_float','t1.q_float_null','t1.q_double','t1.q_double_null', 't2.q_bool','t2.q_bool_null','t2.q_bigint','t2.q_bigint_null','t2.q_smallint','t2.q_smallint_null', - 't2.q_tinyint','t2.q_tinyint_null','t2.q_int','t2.q_int_null','t2.q_float','t2.q_float_null','t2.q_double','t2.q_double_null'] - - type_name_j1 = str(random.sample(type_names,1)).replace("[","").replace("]","").replace("'","") + 't2.q_tinyint','t2.q_tinyint_null','t2.q_int','t2.q_int_null','t2.q_float','t2.q_float_null','t2.q_double','t2.q_double_null'] + + type_name_j1 = str(random.sample(type_names,1)).replace("[","").replace("]","").replace("'","") fun_column_join_1 = str(random.sample(str_functions,1))+'('+str(random.sample(fun_fix_column_j,1))+' AS '+type_name_j1+')' time_fun_join_1 = str(fun_column_join_1).replace("[","").replace("]","").replace("'","") - - type_name_j2 = str(random.sample(type_names,1)).replace("[","").replace("]","").replace("'","") + + type_name_j2 = str(random.sample(type_names,1)).replace("[","").replace("]","").replace("'","") fun_column_join_2 = str(random.sample(str_functions,1))+'('+str(random.sample(fun_fix_column_j,1))+' AS '+type_name_j2+')' - time_fun_join_2 = str(fun_column_join_2).replace("[","").replace("]","").replace("'","") - + time_fun_join_2 = str(fun_column_join_2).replace("[","").replace("]","").replace("'","") + elif i==2: print('===========cast_2===========') fun_fix_column = ['q_binary','q_binary_null','q_binary1','q_binary2','q_binary3','q_binary4'] type_names = ['BIGINT','BINARY(100)','NCHAR(100)','BIGINT UNSIGNED'] - + type_name1 = str(random.sample(type_names,1)).replace("[","").replace("]","").replace("'","") fun_column_1 = str(random.sample(str_functions,1))+'('+str(random.sample(fun_fix_column,1))+' AS '+type_name1+')' time_fun_1 = str(fun_column_1).replace("[","").replace("]","").replace("'","") @@ -2316,279 +2316,279 @@ class TDTestCase: type_name2 = str(random.sample(type_names,1)).replace("[","").replace("]","").replace("'","") fun_column_2 = str(random.sample(str_functions,1))+'('+str(random.sample(fun_fix_column,1))+' AS '+type_name2+')' time_fun_2 = str(fun_column_2).replace("[","").replace("]","").replace("'","") - + fun_fix_column_j = ['t1.q_binary','t1.q_binary_null','t1.q_binary1','t1.q_binary2','t1.q_binary3','t1.q_smallint_null','t1.q_binary4', - 't2.q_binary','t2.q_binary_null','t2.q_bigint','t2.q_binary1','t2.q_binary2','t2.q_binary3','t2.q_binary4'] - - type_name_j1 = str(random.sample(type_names,1)).replace("[","").replace("]","").replace("'","") + 't2.q_binary','t2.q_binary_null','t2.q_bigint','t2.q_binary1','t2.q_binary2','t2.q_binary3','t2.q_binary4'] + + type_name_j1 = str(random.sample(type_names,1)).replace("[","").replace("]","").replace("'","") fun_column_join_1 = str(random.sample(str_functions,1))+'('+str(random.sample(fun_fix_column_j,1))+' AS '+type_name_j1+')' time_fun_join_1 = str(fun_column_join_1).replace("[","").replace("]","").replace("'","") - - type_name_j2 = str(random.sample(type_names,1)).replace("[","").replace("]","").replace("'","") + + type_name_j2 = str(random.sample(type_names,1)).replace("[","").replace("]","").replace("'","") fun_column_join_2 = str(random.sample(str_functions,1))+'('+str(random.sample(fun_fix_column_j,1))+' AS '+type_name_j2+')' - time_fun_join_2 = str(fun_column_join_2).replace("[","").replace("]","").replace("'","") - + time_fun_join_2 = str(fun_column_join_2).replace("[","").replace("]","").replace("'","") + elif i==3: print('===========cast_3===========') fun_fix_column = ['q_nchar','q_nchar_null','q_nchar5','q_nchar6','q_nchar7','q_nchar8'] type_names = ['BIGINT','NCHAR(100)','BIGINT UNSIGNED'] - + type_name1 = str(random.sample(type_names,1)).replace("[","").replace("]","").replace("'","") fun_column_1 = str(random.sample(str_functions,1))+'('+str(random.sample(fun_fix_column,1))+' AS '+type_name1+')' - time_fun_1 = str(fun_column_1).replace("[","").replace("]","").replace("'","") + time_fun_1 = str(fun_column_1).replace("[","").replace("]","").replace("'","") type_name2 = str(random.sample(type_names,1)).replace("[","").replace("]","").replace("'","") fun_column_2 = str(random.sample(str_functions,1))+'('+str(random.sample(fun_fix_column,1))+' AS '+type_name2+')' - time_fun_2 = str(fun_column_2).replace("[","").replace("]","").replace("'","") - + time_fun_2 = str(fun_column_2).replace("[","").replace("]","").replace("'","") + fun_fix_column_j = ['t1.q_nchar','t1.q_nchar_null','t1.q_nchar5','t1.q_nchar6','t1.q_nchar7','t1.q_nchar8', - 't2.q_nchar','t2.q_nchar_null','t2.q_nchar5','t2.q_nchar6','t2.q_nchar7','t2.q_nchar8'] - - type_name_j1 = str(random.sample(type_names,1)).replace("[","").replace("]","").replace("'","") + 't2.q_nchar','t2.q_nchar_null','t2.q_nchar5','t2.q_nchar6','t2.q_nchar7','t2.q_nchar8'] + + type_name_j1 = str(random.sample(type_names,1)).replace("[","").replace("]","").replace("'","") fun_column_join_1 = str(random.sample(str_functions,1))+'('+str(random.sample(fun_fix_column_j,1))+' AS '+type_name_j1+')' time_fun_join_1 = str(fun_column_join_1).replace("[","").replace("]","").replace("'","") - - type_name_j2 = str(random.sample(type_names,1)).replace("[","").replace("]","").replace("'","") + + type_name_j2 = str(random.sample(type_names,1)).replace("[","").replace("]","").replace("'","") fun_column_join_2 = str(random.sample(str_functions,1))+'('+str(random.sample(fun_fix_column_j,1))+' AS '+type_name_j2+')' - time_fun_join_2 = str(fun_column_join_2).replace("[","").replace("]","").replace("'","") - + time_fun_join_2 = str(fun_column_join_2).replace("[","").replace("]","").replace("'","") + elif i==4: print('===========cast_4===========') fun_fix_column = ['q_ts','q_ts_null','_C0','_c0','ts','_rowts'] type_names = ['BIGINT','TIMESTAMP','BIGINT UNSIGNED'] - + type_name1 = str(random.sample(type_names,1)).replace("[","").replace("]","").replace("'","") fun_column_1 = str(random.sample(str_functions,1))+'('+str(random.sample(fun_fix_column,1))+' AS '+type_name1+')' - time_fun_1 = str(fun_column_1).replace("[","").replace("]","").replace("'","") - + time_fun_1 = str(fun_column_1).replace("[","").replace("]","").replace("'","") + type_name2 = str(random.sample(type_names,1)).replace("[","").replace("]","").replace("'","") fun_column_2 = str(random.sample(str_functions,1))+'('+str(random.sample(fun_fix_column,1))+' AS '+type_name2+')' - time_fun_2 = str(fun_column_2).replace("[","").replace("]","").replace("'","") - - fun_fix_column_j = ['t1.q_ts','t1.q_ts_null','t1.ts','t2.q_ts','t2.q_ts_null','t2.ts'] - - type_name_j1 = str(random.sample(type_names,1)).replace("[","").replace("]","").replace("'","") + time_fun_2 = str(fun_column_2).replace("[","").replace("]","").replace("'","") + + fun_fix_column_j = ['t1.q_ts','t1.q_ts_null','t1.ts','t2.q_ts','t2.q_ts_null','t2.ts'] + + type_name_j1 = str(random.sample(type_names,1)).replace("[","").replace("]","").replace("'","") fun_column_join_1 = str(random.sample(str_functions,1))+'('+str(random.sample(fun_fix_column_j,1))+' AS '+type_name_j1+')' time_fun_join_1 = str(fun_column_join_1).replace("[","").replace("]","").replace("'","") - - type_name_j2 = str(random.sample(type_names,1)).replace("[","").replace("]","").replace("'","") + + type_name_j2 = str(random.sample(type_names,1)).replace("[","").replace("]","").replace("'","") fun_column_join_2 = str(random.sample(str_functions,1))+'('+str(random.sample(fun_fix_column_j,1))+' AS '+type_name_j2+')' - time_fun_join_2 = str(fun_column_join_2).replace("[","").replace("]","").replace("'","") - + time_fun_join_2 = str(fun_column_join_2).replace("[","").replace("]","").replace("'","") + elif (timelist == ['CAST_1']) : - str_functions = timelist - + str_functions = timelist + print('===========cast_1===========') fun_fix_column = ['q_bool','q_bool_null','q_bigint','q_bigint_null','q_smallint','q_smallint_null', 'q_tinyint','q_tinyint_null','q_int','q_int_null','q_float','q_float_null','q_double','q_double_null'] type_names = ['BIGINT','BINARY(100)','TIMESTAMP','NCHAR(100)','BIGINT UNSIGNED'] - - type_name1 = str(random.sample(type_names,1)).replace("[","").replace("]","").replace("'","") + + type_name1 = str(random.sample(type_names,1)).replace("[","").replace("]","").replace("'","") fun_column_1 = str(random.sample(str_functions,1))+'('+str(random.sample(fun_fix_column,1))+' AS '+type_name1+')' - time_fun_1 = str(fun_column_1).replace("[","").replace("]","").replace("'","").replace("_1","") - - type_name2 = str(random.sample(type_names,1)).replace("[","").replace("]","").replace("'","") + time_fun_1 = str(fun_column_1).replace("[","").replace("]","").replace("'","").replace("_1","") + + type_name2 = str(random.sample(type_names,1)).replace("[","").replace("]","").replace("'","") fun_column_2 = str(random.sample(str_functions,1))+'('+str(random.sample(fun_fix_column,1))+' AS '+type_name2+')' - time_fun_2 = str(fun_column_2).replace("[","").replace("]","").replace("'","").replace("_1","") - + time_fun_2 = str(fun_column_2).replace("[","").replace("]","").replace("'","").replace("_1","") + fun_fix_column_j = ['t1.q_bool','t1.q_bool_null','t1.q_bigint','t1.q_bigint_null','t1.q_smallint','t1.q_smallint_null', 't1.q_tinyint','t1.q_tinyint_null','t1.q_int','t1.q_int_null','t1.q_float','t1.q_float_null','t1.q_double','t1.q_double_null', 't2.q_bool','t2.q_bool_null','t2.q_bigint','t2.q_bigint_null','t2.q_smallint','t2.q_smallint_null', - 't2.q_tinyint','t2.q_tinyint_null','t2.q_int','t2.q_int_null','t2.q_float','t2.q_float_null','t2.q_double','t2.q_double_null'] - - type_name_j1 = str(random.sample(type_names,1)).replace("[","").replace("]","").replace("'","") + 't2.q_tinyint','t2.q_tinyint_null','t2.q_int','t2.q_int_null','t2.q_float','t2.q_float_null','t2.q_double','t2.q_double_null'] + + type_name_j1 = str(random.sample(type_names,1)).replace("[","").replace("]","").replace("'","") fun_column_join_1 = str(random.sample(str_functions,1))+'('+str(random.sample(fun_fix_column_j,1))+' AS '+type_name_j1+')' - time_fun_join_1 = str(fun_column_join_1).replace("[","").replace("]","").replace("'","").replace("_1","") - - type_name_j2 = str(random.sample(type_names,1)).replace("[","").replace("]","").replace("'","") + time_fun_join_1 = str(fun_column_join_1).replace("[","").replace("]","").replace("'","").replace("_1","") + + type_name_j2 = str(random.sample(type_names,1)).replace("[","").replace("]","").replace("'","") fun_column_join_2 = str(random.sample(str_functions,1))+'('+str(random.sample(fun_fix_column_j,1))+' AS '+type_name_j2+')' - time_fun_join_2 = str(fun_column_join_2).replace("[","").replace("]","").replace("'","").replace("_1","") - + time_fun_join_2 = str(fun_column_join_2).replace("[","").replace("]","").replace("'","").replace("_1","") + elif (timelist == ['CAST_2']) : - str_functions = timelist + str_functions = timelist print('===========cast_2===========') fun_fix_column = ['q_binary','q_binary_null','q_binary1','q_binary2','q_binary3','q_binary4'] type_names = ['BIGINT','BINARY(100)','NCHAR(100)','BIGINT UNSIGNED'] - + type_name1 = str(random.sample(type_names,1)).replace("[","").replace("]","").replace("'","") fun_column_1 = str(random.sample(str_functions,1))+'('+str(random.sample(fun_fix_column,1))+' AS '+type_name1+')' - time_fun_1 = str(fun_column_1).replace("[","").replace("]","").replace("'","").replace("_2","") + time_fun_1 = str(fun_column_1).replace("[","").replace("]","").replace("'","").replace("_2","") type_name2 = str(random.sample(type_names,1)).replace("[","").replace("]","").replace("'","") fun_column_2 = str(random.sample(str_functions,1))+'('+str(random.sample(fun_fix_column,1))+' AS '+type_name2+')' - time_fun_2 = str(fun_column_2).replace("[","").replace("]","").replace("'","").replace("_2","") - + time_fun_2 = str(fun_column_2).replace("[","").replace("]","").replace("'","").replace("_2","") + fun_fix_column_j = ['t1.q_binary','t1.q_binary_null','t1.q_binary1','t1.q_binary2','t1.q_binary3','t1.q_smallint_null','t1.q_binary4', - 't2.q_binary','t2.q_binary_null','t2.q_bigint','t2.q_binary1','t2.q_binary2','t2.q_binary3','t2.q_binary4'] - - type_name_j1 = str(random.sample(type_names,1)).replace("[","").replace("]","").replace("'","") + 't2.q_binary','t2.q_binary_null','t2.q_bigint','t2.q_binary1','t2.q_binary2','t2.q_binary3','t2.q_binary4'] + + type_name_j1 = str(random.sample(type_names,1)).replace("[","").replace("]","").replace("'","") fun_column_join_1 = str(random.sample(str_functions,1))+'('+str(random.sample(fun_fix_column_j,1))+' AS '+type_name_j1+')' - time_fun_join_1 = str(fun_column_join_1).replace("[","").replace("]","").replace("'","").replace("_2","") - - type_name_j2 = str(random.sample(type_names,1)).replace("[","").replace("]","").replace("'","") + time_fun_join_1 = str(fun_column_join_1).replace("[","").replace("]","").replace("'","").replace("_2","") + + type_name_j2 = str(random.sample(type_names,1)).replace("[","").replace("]","").replace("'","") fun_column_join_2 = str(random.sample(str_functions,1))+'('+str(random.sample(fun_fix_column_j,1))+' AS '+type_name_j2+')' - time_fun_join_2 = str(fun_column_join_2).replace("[","").replace("]","").replace("'","").replace("_2","") - + time_fun_join_2 = str(fun_column_join_2).replace("[","").replace("]","").replace("'","").replace("_2","") + elif (timelist == ['CAST_3']) : - str_functions = timelist + str_functions = timelist print('===========cast_3===========') fun_fix_column = ['q_nchar','q_nchar_null','q_nchar5','q_nchar6','q_nchar7','q_nchar8'] type_names = ['BIGINT','NCHAR(100)','BIGINT UNSIGNED'] - + type_name1 = str(random.sample(type_names,1)).replace("[","").replace("]","").replace("'","") fun_column_1 = str(random.sample(str_functions,1))+'('+str(random.sample(fun_fix_column,1))+' AS '+type_name1+')' - time_fun_1 = str(fun_column_1).replace("[","").replace("]","").replace("'","").replace("_3","") + time_fun_1 = str(fun_column_1).replace("[","").replace("]","").replace("'","").replace("_3","") type_name2 = str(random.sample(type_names,1)).replace("[","").replace("]","").replace("'","") fun_column_2 = str(random.sample(str_functions,1))+'('+str(random.sample(fun_fix_column,1))+' AS '+type_name2+')' - time_fun_2 = str(fun_column_2).replace("[","").replace("]","").replace("'","").replace("_3","") - + time_fun_2 = str(fun_column_2).replace("[","").replace("]","").replace("'","").replace("_3","") + fun_fix_column_j = ['t1.q_nchar','t1.q_nchar_null','t1.q_nchar5','t1.q_nchar6','t1.q_nchar7','t1.q_nchar8', - 't2.q_nchar','t2.q_nchar_null','t2.q_nchar5','t2.q_nchar6','t2.q_nchar7','t2.q_nchar8'] - - type_name_j1 = str(random.sample(type_names,1)).replace("[","").replace("]","").replace("'","") + 't2.q_nchar','t2.q_nchar_null','t2.q_nchar5','t2.q_nchar6','t2.q_nchar7','t2.q_nchar8'] + + type_name_j1 = str(random.sample(type_names,1)).replace("[","").replace("]","").replace("'","") fun_column_join_1 = str(random.sample(str_functions,1))+'('+str(random.sample(fun_fix_column_j,1))+' AS '+type_name_j1+')' - time_fun_join_1 = str(fun_column_join_1).replace("[","").replace("]","").replace("'","").replace("_3","") - - type_name_j2 = str(random.sample(type_names,1)).replace("[","").replace("]","").replace("'","") + time_fun_join_1 = str(fun_column_join_1).replace("[","").replace("]","").replace("'","").replace("_3","") + + type_name_j2 = str(random.sample(type_names,1)).replace("[","").replace("]","").replace("'","") fun_column_join_2 = str(random.sample(str_functions,1))+'('+str(random.sample(fun_fix_column_j,1))+' AS '+type_name_j2+')' - time_fun_join_2 = str(fun_column_join_2).replace("[","").replace("]","").replace("'","").replace("_3","") - + time_fun_join_2 = str(fun_column_join_2).replace("[","").replace("]","").replace("'","").replace("_3","") + elif (timelist == ['CAST_4']) : - str_functions = timelist + str_functions = timelist print('===========cast_4===========') fun_fix_column = ['q_ts','q_ts_null','_C0','_c0','ts','_rowts'] type_names = ['BIGINT','TIMESTAMP','BIGINT UNSIGNED'] - + type_name1 = str(random.sample(type_names,1)).replace("[","").replace("]","").replace("'","") fun_column_1 = str(random.sample(str_functions,1))+'('+str(random.sample(fun_fix_column,1))+' AS '+type_name1+')' - time_fun_1 = str(fun_column_1).replace("[","").replace("]","").replace("'","").replace("_4","") - + time_fun_1 = str(fun_column_1).replace("[","").replace("]","").replace("'","").replace("_4","") + type_name2 = str(random.sample(type_names,1)).replace("[","").replace("]","").replace("'","") fun_column_2 = str(random.sample(str_functions,1))+'('+str(random.sample(fun_fix_column,1))+' AS '+type_name2+')' - time_fun_2 = str(fun_column_2).replace("[","").replace("]","").replace("'","").replace("_4","") - - fun_fix_column_j = ['t1.q_ts','t1.q_ts_null','t1.ts','t2.q_ts','t2.q_ts_null','t2.ts'] - - type_name_j1 = str(random.sample(type_names,1)).replace("[","").replace("]","").replace("'","") + time_fun_2 = str(fun_column_2).replace("[","").replace("]","").replace("'","").replace("_4","") + + fun_fix_column_j = ['t1.q_ts','t1.q_ts_null','t1.ts','t2.q_ts','t2.q_ts_null','t2.ts'] + + type_name_j1 = str(random.sample(type_names,1)).replace("[","").replace("]","").replace("'","") fun_column_join_1 = str(random.sample(str_functions,1))+'('+str(random.sample(fun_fix_column_j,1))+' AS '+type_name_j1+')' - time_fun_join_1 = str(fun_column_join_1).replace("[","").replace("]","").replace("'","").replace("_4","") - - type_name_j2 = str(random.sample(type_names,1)).replace("[","").replace("]","").replace("'","") + time_fun_join_1 = str(fun_column_join_1).replace("[","").replace("]","").replace("'","").replace("_4","") + + type_name_j2 = str(random.sample(type_names,1)).replace("[","").replace("]","").replace("'","") fun_column_join_2 = str(random.sample(str_functions,1))+'('+str(random.sample(fun_fix_column_j,1))+' AS '+type_name_j2+')' - time_fun_join_2 = str(fun_column_join_2).replace("[","").replace("]","").replace("'","").replace("_4","") - + time_fun_join_2 = str(fun_column_join_2).replace("[","").replace("]","").replace("'","").replace("_4","") + tdSql.query("select 1-1 as time_nest from stable_1 limit 1;") for i in range(self.fornum): if (timelist == ['NOW','TODAY']) or (timelist == ['TIMETRUNCATE']) or (timelist == ['TO_ISO8601'])\ or (timelist == ['TO_UNIXTIMESTAMP']): - sql = "select ts , timediff(asct1,now) from ( select " - sql += "%s as asct1, " % time_fun_1 - sql += "%s as asct2, " % time_fun_2 + sql = "select ts , timediff(asct1,now) from ( select " + sql += "%s as asct1, " % time_fun_1 + sql += "%s as asct2, " % time_fun_2 sql += "%s, " % random.choice(self.s_s_select) - sql += "%s, " % random.choice(self.q_select) + sql += "%s, " % random.choice(self.q_select) sql += "ts from regular_table_1 where " sql += "%s " % random.choice(self.q_where) sql += "%s " % random.choice(self.order_where) sql += ");" - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) tdSql.query(sql) tdSql.checkRows(100) self.cur1.execute(sql) elif (timelist == ['TIMEZONE']) \ or (timelist == ['CAST']) or (timelist == ['CAST_1']) or (timelist == ['CAST_2']) or (timelist == ['CAST_3']) or (timelist == ['CAST_4']): - sql = "select ts , asct1,now(),today(),timezone() from ( select " - sql += "%s as asct1, " % time_fun_1 - sql += "%s as asct2, " % time_fun_2 + sql = "select ts , asct1,now(),today(),timezone() from ( select " + sql += "%s as asct1, " % time_fun_1 + sql += "%s as asct2, " % time_fun_2 sql += "%s, " % random.choice(self.s_s_select) - sql += "%s, " % random.choice(self.q_select) + sql += "%s, " % random.choice(self.q_select) sql += "ts from regular_table_1 where " sql += "%s " % random.choice(self.q_where) sql += "%s " % random.choice(self.order_where) sql += ");" - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) tdSql.query(sql) tdSql.checkRows(100) self.cur1.execute(sql) elif (timelist == ['ELAPSED']) : - sql = "select max(asct1),now(),today(),timezone() from ( select " - sql += "%s as asct1, " % time_fun_1 - sql += "%s as asct2 " % time_fun_2 + sql = "select max(asct1),now(),today(),timezone() from ( select " + sql += "%s as asct1, " % time_fun_1 + sql += "%s as asct2 " % time_fun_2 sql += "from regular_table_1 where " sql += "%s " % random.choice(self.q_where) sql += ");" - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) tdSql.query(sql) self.cur1.execute(sql) - + tdSql.query("select 1-2 as time_nest from stable_1 limit 1;") for i in range(self.fornum): if (timelist == ['NOW','TODAY']) or (timelist == ['TIMETRUNCATE']) or (timelist == ['TO_ISO8601'])\ or (timelist == ['TO_UNIXTIMESTAMP']): sql = "select ts , timediff(asct1,now),now(),today(),timezone() from ( select " - sql += "%s as asct1, " % time_fun_1 + sql += "%s as asct1, " % time_fun_1 sql += "%s, " % random.choice(self.s_s_select) - sql += "%s, " % random.choice(self.q_select) + sql += "%s, " % random.choice(self.q_select) sql += "ts ts from regular_table_1 where " sql += "%s " % random.choice(self.q_where) sql += "%s )" % random.choice(self.order_where) - sql += "%s " % random.choice(self.unionall_or_union) + sql += "%s " % random.choice(self.unionall_or_union) sql += "select ts , timediff(asct2,now),now(),today(),timezone() from ( select " - sql += "%s as asct2, " % time_fun_2 + sql += "%s as asct2, " % time_fun_2 sql += "%s, " % random.choice(self.s_s_select) - sql += "%s, " % random.choice(self.q_select) + sql += "%s, " % random.choice(self.q_select) sql += "ts ts from regular_table_1 where " - sql += "%s " % random.choice(self.q_where) + sql += "%s " % random.choice(self.q_where) #sql += "%s " % random.choice(having_support) sql += "%s " % random.choice(self.order_where) sql += "%s " % random.choice(self.limit1_where) sql += ")" - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) #TD-15437 tdSql.query(sql) - #TD-15437 self.cur1.execute(sql) + #TD-15437 self.cur1.execute(sql) elif (timelist == ['TIMEZONE']) or (timelist == ['CAST']) or (timelist == ['CAST_1']) or (timelist == ['CAST_2']) or (timelist == ['CAST_3']) or (timelist == ['CAST_4']): sql = "select ts , (asct1),now(),today(),timezone() from ( select " - sql += "%s as asct1, " % time_fun_1 + sql += "%s as asct1, " % time_fun_1 sql += "%s, " % random.choice(self.s_s_select) - sql += "%s, " % random.choice(self.q_select) + sql += "%s, " % random.choice(self.q_select) sql += "ts ts from regular_table_1 where " sql += "%s " % random.choice(self.q_where) sql += "%s )" % random.choice(self.order_where) - sql += "%s " % random.choice(self.unionall_or_union) + sql += "%s " % random.choice(self.unionall_or_union) sql += "select ts , asct2,now(),today(),timezone() from ( select " - sql += "%s as asct2, " % time_fun_2 + sql += "%s as asct2, " % time_fun_2 sql += "%s, " % random.choice(self.s_s_select) - sql += "%s, " % random.choice(self.q_select) + sql += "%s, " % random.choice(self.q_select) sql += "ts ts from regular_table_1 where " - sql += "%s " % random.choice(self.q_where) + sql += "%s " % random.choice(self.q_where) sql += "%s " % random.choice(self.order_where) sql += "%s " % random.choice(self.limit1_where) sql += ")" - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) #TD-15437 tdSql.query(sql) - #TD-15437 self.cur1.execute(sql) - elif (timelist == ['ELAPSED']) : + #TD-15437 self.cur1.execute(sql) + elif (timelist == ['ELAPSED']) : sql = "select min(asct1),now(),today(),timezone() from ( select " - sql += "%s as asct1 " % time_fun_1 + sql += "%s as asct1 " % time_fun_1 sql += " from regular_table_1 where " sql += "%s )" % random.choice(self.q_where) - sql += "%s " % random.choice(self.unionall_or_union) + sql += "%s " % random.choice(self.unionall_or_union) sql += "select avg(asct2),now(),today(),timezone() from ( select " - sql += "%s as asct2 " % time_fun_2 + sql += "%s as asct2 " % time_fun_2 sql += " from regular_table_1 where " - sql += "%s " % random.choice(self.q_where) + sql += "%s " % random.choice(self.q_where) sql += "%s " % random.choice(self.limit1_where) sql += ")" - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) tdSql.query(sql) - self.cur1.execute(sql) - + self.cur1.execute(sql) + tdSql.query("select 1-3 as time_nest from stable_1 limit 1;") for i in range(self.fornum): if (timelist == ['NOW','TODAY']) or (timelist == ['TIMETRUNCATE']) or (timelist == ['TO_ISO8601'])\ @@ -2597,20 +2597,20 @@ class TDTestCase: sql += "%s as asct1, ts ," % time_fun_1 sql += "%s as asct2, " % time_fun_2 sql += "%s, " % random.choice(self.s_s_select) - sql += "%s, " % random.choice(self.q_select) + sql += "%s, " % random.choice(self.q_select) sql += "ts from regular_table_1 where " sql += "%s " % random.choice(self.q_where) - sql += "%s select " % random.choice(self.unionall_or_union) + sql += "%s select " % random.choice(self.unionall_or_union) sql += "%s as asct2, ts ," % time_fun_2 sql += "%s as asct1, " % time_fun_1 sql += "%s, " % random.choice(self.s_s_select) - sql += "%s, " % random.choice(self.q_select) + sql += "%s, " % random.choice(self.q_select) sql += "ts from regular_table_2 where " sql += "%s " % random.choice(self.q_where) sql += "%s " % random.choice(self.order_where) sql += ")" - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) #TD-15473 tdSql.query(sql) #self.cur1.execute(sql) elif (timelist == ['TIMEZONE']) or (timelist == ['CAST']) or (timelist == ['CAST_1']) or (timelist == ['CAST_2']) or (timelist == ['CAST_3']) or (timelist == ['CAST_4']): @@ -2618,167 +2618,167 @@ class TDTestCase: sql += "%s as asct1, ts ," % time_fun_1 sql += "%s as asct2, " % time_fun_2 sql += "%s, " % random.choice(self.s_s_select) - sql += "%s, " % random.choice(self.q_select) + sql += "%s, " % random.choice(self.q_select) sql += "ts from regular_table_1 where " sql += "%s " % random.choice(self.q_where) - sql += "%s select " % random.choice(self.unionall_or_union) + sql += "%s select " % random.choice(self.unionall_or_union) sql += "%s as asct2, ts ," % time_fun_2 sql += "%s as asct1, " % time_fun_1 sql += "%s, " % random.choice(self.s_s_select) - sql += "%s, " % random.choice(self.q_select) + sql += "%s, " % random.choice(self.q_select) sql += "ts from regular_table_2 where " sql += "%s " % random.choice(self.q_where) sql += "%s " % random.choice(self.order_where) sql += ")" - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) #TD-15473 tdSql.query(sql) #self.cur1.execute(sql) - elif (timelist == ['ELAPSED']) : + elif (timelist == ['ELAPSED']) : sql = "select abs(asct1),now(),today(),timezone() from ( select " sql += "%s as asct1," % time_fun_1 sql += "%s as asct2 " % time_fun_2 sql += "from regular_table_1 where " sql += "%s " % random.choice(self.q_where) - sql += "%s select " % random.choice(self.unionall_or_union) + sql += "%s select " % random.choice(self.unionall_or_union) sql += "%s as asct2," % time_fun_2 sql += "%s as asct1 " % time_fun_1 sql += "from regular_table_2 where " sql += "%s " % random.choice(self.q_where) sql += "%s " % random.choice(self.order_where) sql += ")" - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) tdSql.query(sql) self.cur1.execute(sql) - + tdSql.query("select 1-4 as time_nest from stable_1 limit 1;") for i in range(self.fornum): if (timelist == ['NOW','TODAY']) or (timelist == ['TIMETRUNCATE']) or (timelist == ['TO_ISO8601'])\ or (timelist == ['TO_UNIXTIMESTAMP']): sql = "select ts , timediff(asct1,now) from ( select t1.ts as ts," - sql += "%s, " % time_fun_join_1 - sql += "%s as asct1, " % time_fun_join_2 - sql += "%s, " % time_fun_join_1 - sql += "t1.%s, " % random.choice(self.q_select) - sql += "t2.%s, " % random.choice(self.q_select) + sql += "%s, " % time_fun_join_1 + sql += "%s as asct1, " % time_fun_join_2 + sql += "%s, " % time_fun_join_1 + sql += "t1.%s, " % random.choice(self.q_select) + sql += "t2.%s, " % random.choice(self.q_select) sql += "t2.ts from regular_table_1 t1 , regular_table_2 t2 where t1.ts = t2.ts and " sql += "%s " % random.choice(self.q_u_where) sql += "and %s " % random.choice(self.q_u_or_where) sql += "%s " % random.choice(self.order_u_where) sql += ");" - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) tdSql.query(sql) tdSql.checkRows(100) self.cur1.execute(sql) elif (timelist == ['TIMEZONE']) or (timelist == ['CAST']) or (timelist == ['CAST_1']) or (timelist == ['CAST_2']) or (timelist == ['CAST_3']) or (timelist == ['CAST_4']): sql = "select ts , (asct1) from ( select t1.ts as ts," - sql += "%s, " % time_fun_join_1 - sql += "%s as asct1, " % time_fun_join_2 - sql += "%s, " % time_fun_join_1 - sql += "t1.%s, " % random.choice(self.q_select) - sql += "t2.%s, " % random.choice(self.q_select) + sql += "%s, " % time_fun_join_1 + sql += "%s as asct1, " % time_fun_join_2 + sql += "%s, " % time_fun_join_1 + sql += "t1.%s, " % random.choice(self.q_select) + sql += "t2.%s, " % random.choice(self.q_select) sql += "t2.ts from regular_table_1 t1 , regular_table_2 t2 where t1.ts = t2.ts and " sql += "%s " % random.choice(self.q_u_where) sql += "and %s " % random.choice(self.q_u_or_where) sql += "%s " % random.choice(self.order_u_where) sql += ");" - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) tdSql.query(sql) tdSql.checkRows(100) self.cur1.execute(sql) - elif (timelist == ['ELAPSED']) : + elif (timelist == ['ELAPSED']) : sql = "select floor(asct1) from ( select " - sql += "%s, " % time_fun_join_1 - sql += "%s as asct1, " % time_fun_join_2 - sql += "%s " % time_fun_join_1 + sql += "%s, " % time_fun_join_1 + sql += "%s as asct1, " % time_fun_join_2 + sql += "%s " % time_fun_join_1 sql += " from regular_table_1 t1 , regular_table_2 t2 where t1.ts = t2.ts and " sql += "%s " % random.choice(self.q_u_where) sql += "and %s " % random.choice(self.q_u_or_where) sql += ");" - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) tdSql.query(sql) self.cur1.execute(sql) - + tdSql.query("select 1-5 as time_nest from stable_1 limit 1;") for i in range(self.fornum): - if (timelist == ['ELAPSED']) : + if (timelist == ['ELAPSED']) : sql = "select now(),today(),timezone(), " - sql += "%s, " % time_fun_1 + sql += "%s, " % time_fun_1 sql += "%s " % time_fun_2 sql += " from ( select * from regular_table_1 ) where " sql += "%s " % random.choice(self.q_where) sql += " ;" - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) tdSql.query(sql) self.cur1.execute(sql) else: sql = "select ts ,now(),today(),timezone(), " - sql += "%s, " % time_fun_1 + sql += "%s, " % time_fun_1 + sql += "%s, " % random.choice(self.q_select) sql += "%s, " % random.choice(self.q_select) - sql += "%s, " % random.choice(self.q_select) sql += "%s " % time_fun_2 sql += " from ( select * from regular_table_1 ) where " sql += "%s " % random.choice(self.q_where) sql += "%s " % random.choice(self.order_where) sql += " ;" - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) tdSql.query(sql) tdSql.checkRows(100) self.cur1.execute(sql) tdSql.query("select 1-6 as time_nest from stable_1 limit 1;") - for i in range(self.fornum): + for i in range(self.fornum): if (timelist == ['NOW','TODAY']) or (timelist == ['TIMETRUNCATE']) or (timelist == ['TO_ISO8601'])\ or (timelist == ['TO_UNIXTIMESTAMP']): sql = "select ts , timediff(asct1,now) from ( select t1.ts as ts," - sql += "%s, " % time_fun_join_1 - sql += "%s as asct1, " % time_fun_join_2 - sql += "t1.%s, " % random.choice(self.q_select) - sql += "t2.%s, " % random.choice(self.q_select) - sql += "%s, " % time_fun_join_1 + sql += "%s, " % time_fun_join_1 + sql += "%s as asct1, " % time_fun_join_2 + sql += "t1.%s, " % random.choice(self.q_select) + sql += "t2.%s, " % random.choice(self.q_select) + sql += "%s, " % time_fun_join_1 sql += "t2.ts from regular_table_1 t1 , regular_table_2 t2 where t1.ts = t2.ts and " sql += "%s " % random.choice(self.q_u_where) sql += "and %s )" % random.choice(self.q_u_or_where) sql += "%s " % random.choice(self.order_where) sql += "%s " % random.choice(self.limit1_where) - tdLog.info(sql) - tdLog.info(len(sql)) - tdSql.query(sql) + tdLog.info(sql) + tdLog.info(len(sql)) + tdSql.query(sql) self.cur1.execute(sql) elif (timelist == ['TIMEZONE']) or (timelist == ['CAST']) or (timelist == ['CAST_1']) or (timelist == ['CAST_2']) or (timelist == ['CAST_3']) or (timelist == ['CAST_4']): sql = "select ts , (asct1) from ( select t1.ts as ts," - sql += "%s, " % time_fun_join_1 - sql += "%s as asct1, " % time_fun_join_2 - sql += "t1.%s, " % random.choice(self.q_select) - sql += "t2.%s, " % random.choice(self.q_select) - sql += "%s, " % time_fun_join_1 + sql += "%s, " % time_fun_join_1 + sql += "%s as asct1, " % time_fun_join_2 + sql += "t1.%s, " % random.choice(self.q_select) + sql += "t2.%s, " % random.choice(self.q_select) + sql += "%s, " % time_fun_join_1 sql += "t2.ts from regular_table_1 t1 , regular_table_2 t2 where t1.ts = t2.ts and " sql += "%s " % random.choice(self.q_u_where) sql += "and %s )" % random.choice(self.q_u_or_where) sql += "%s " % random.choice(self.order_where) sql += "%s " % random.choice(self.limit1_where) - tdLog.info(sql) - tdLog.info(len(sql)) - tdSql.query(sql) + tdLog.info(sql) + tdLog.info(len(sql)) + tdSql.query(sql) self.cur1.execute(sql) elif (timelist == ['ELAPSED']) : sql = "select (asct1)*111 from ( select " - sql += "%s, " % time_fun_join_1 - sql += "%s as asct1, " % time_fun_join_2 - sql += "%s " % time_fun_join_1 + sql += "%s, " % time_fun_join_1 + sql += "%s as asct1, " % time_fun_join_2 + sql += "%s " % time_fun_join_1 sql += " from regular_table_1 t1 , regular_table_2 t2 where t1.ts = t2.ts and " sql += "%s " % random.choice(self.q_u_where) sql += "and %s )" % random.choice(self.q_u_or_where) sql += "%s " % random.choice(self.limit1_where) - tdLog.info(sql) - tdLog.info(len(sql)) - tdSql.query(sql) + tdLog.info(sql) + tdLog.info(len(sql)) + tdSql.query(sql) self.cur1.execute(sql) tdSql.query("select 1-7 as time_nest from stable_1 limit 1;") @@ -2788,13 +2788,13 @@ class TDTestCase: sql = "select ts , timediff(asct1,now) from ( select " sql += "%s as asct1, ts ," % time_fun_1 sql += "%s as asct2, " % time_fun_2 - sql += "%s, " % random.choice(self.q_select) - sql += "%s, " % random.choice(self.t_select) + sql += "%s, " % random.choice(self.q_select) + sql += "%s, " % random.choice(self.t_select) sql += "ts from stable_1 where " sql += "%s " % random.choice(self.qt_where) sql += "%s " % random.choice(self.order_where) sql += ") ;" - tdLog.info(sql) + tdLog.info(sql) tdLog.info(len(sql)) # tdSql.query(sql) # TD-16039 # tdSql.checkRows(300) @@ -2803,13 +2803,13 @@ class TDTestCase: sql = "select ts , (asct1),now(),today(),timezone() from ( select " sql += "%s as asct1, ts ," % time_fun_1 sql += "%s as asct2, " % time_fun_2 - sql += "%s, " % random.choice(self.q_select) - sql += "%s, " % random.choice(self.t_select) + sql += "%s, " % random.choice(self.q_select) + sql += "%s, " % random.choice(self.t_select) sql += "ts from stable_1 where " sql += "%s " % random.choice(self.qt_where) sql += "%s " % random.choice(self.order_where) sql += ") ;" - tdLog.info(sql) + tdLog.info(sql) tdLog.info(len(sql)) # tdSql.query(sql) # TD-16039 # tdSql.checkRows(300) @@ -2821,11 +2821,11 @@ class TDTestCase: sql += "from stable_1 where " sql += "%s " % random.choice(self.qt_where) sql += ") ;" - tdLog.info(sql) + tdLog.info(sql) tdLog.info(len(sql)) # tdSql.query(sql) #同时出现core:TD-16095和TD-16042 # self.cur1.execute(sql) - + tdSql.query("select 1-8 as time_nest from stable_1 limit 1;") for i in range(self.fornum): if (timelist == ['NOW','TODAY']) or (timelist == ['TIMETRUNCATE']) or (timelist == ['TO_ISO8601'])\ @@ -2835,13 +2835,13 @@ class TDTestCase: sql += "%s, " % random.choice(self.s_s_select) sql += "%s as asct1, ts ," % time_fun_1 sql += "%s as asct2, " % time_fun_2 - sql += "%s, " % random.choice(self.q_select) - sql += "%s, " % random.choice(self.t_select) + sql += "%s, " % random.choice(self.q_select) + sql += "%s, " % random.choice(self.t_select) sql += "ts from stable_1 where " sql += "%s " % random.choice(self.qt_where) sql += "%s " % random.choice(self.order_where) sql += ") ;" - tdLog.info(sql) + tdLog.info(sql) tdLog.info(len(sql)) # tdSql.query(sql) # TD-16039 # tdSql.checkRows(300) @@ -2852,17 +2852,17 @@ class TDTestCase: sql += "%s, " % random.choice(self.s_s_select) sql += "%s as asct1, ts ," % time_fun_1 sql += "%s as asct2, " % time_fun_2 - sql += "%s, " % random.choice(self.q_select) - sql += "%s, " % random.choice(self.t_select) + sql += "%s, " % random.choice(self.q_select) + sql += "%s, " % random.choice(self.t_select) sql += "ts from stable_1 where " sql += "%s " % random.choice(self.qt_where) sql += "%s " % random.choice(self.order_where) sql += ") ;" - tdLog.info(sql) + tdLog.info(sql) tdLog.info(len(sql)) # tdSql.query(sql) # TD-16039 # tdSql.checkRows(300) - # self.cur1.execute(sql) + # self.cur1.execute(sql) elif (timelist == ['ELAPSED']) : sql = "select floor(abs(asct1)),now(),today(),timezone() " sql += "from ( select " @@ -2873,22 +2873,22 @@ class TDTestCase: sql += "%s " % random.choice(self.qt_where) sql += "%s " % random.choice(self.order_where) sql += ") ;" - tdLog.info(sql) + tdLog.info(sql) tdLog.info(len(sql)) # tdSql.query(sql) # TD-16039 - # self.cur1.execute(sql) + # self.cur1.execute(sql) tdSql.query("select 1-9 as time_nest from stable_1 limit 1;") for i in range(self.fornum): if (timelist == ['NOW','TODAY']) or (timelist == ['TIMETRUNCATE']) or (timelist == ['TO_ISO8601'])\ or (timelist == ['TO_UNIXTIMESTAMP']): sql = "select ts , timediff(asct1,now) from ( select t1.ts as ts," - sql += "%s, " % time_fun_join_1 - sql += "%s as asct1, " % time_fun_join_2 - sql += "t1.%s, " % random.choice(self.q_select) - sql += "t1.%s, " % random.choice(self.q_select) - sql += "t2.%s, " % random.choice(self.q_select) - sql += "t2.%s, " % random.choice(self.q_select) + sql += "%s, " % time_fun_join_1 + sql += "%s as asct1, " % time_fun_join_2 + sql += "t1.%s, " % random.choice(self.q_select) + sql += "t1.%s, " % random.choice(self.q_select) + sql += "t2.%s, " % random.choice(self.q_select) + sql += "t2.%s, " % random.choice(self.q_select) sql += "t2.ts from stable_1 t1 , stable_2 t2 where t1.ts = t2.ts and " sql += "%s " % random.choice(self.t_join_where) sql += "and %s " % random.choice(self.t_u_where) @@ -2896,18 +2896,18 @@ class TDTestCase: sql += "%s " % random.choice(self.order_u_where) sql += "%s " % random.choice(self.limit1_where) sql += ") ;" - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) # tdSql.query(sql) TD-16039 # self.cur1.execute(sql) TD-16039 elif (timelist == ['TIMEZONE']) or (timelist == ['CAST']) or (timelist == ['CAST_1']) or (timelist == ['CAST_2']) or (timelist == ['CAST_3']) or (timelist == ['CAST_4']): sql = "select ts , asct1 from ( select t1.ts as ts," - sql += "%s, " % time_fun_join_1 - sql += "%s as asct1, " % time_fun_join_2 - sql += "t1.%s, " % random.choice(self.q_select) - sql += "t1.%s, " % random.choice(self.q_select) - sql += "t2.%s, " % random.choice(self.q_select) - sql += "t2.%s, " % random.choice(self.q_select) + sql += "%s, " % time_fun_join_1 + sql += "%s as asct1, " % time_fun_join_2 + sql += "t1.%s, " % random.choice(self.q_select) + sql += "t1.%s, " % random.choice(self.q_select) + sql += "t2.%s, " % random.choice(self.q_select) + sql += "t2.%s, " % random.choice(self.q_select) sql += "t2.ts from stable_1 t1 , stable_2 t2 where t1.ts = t2.ts and " sql += "%s " % random.choice(self.t_join_where) sql += "and %s " % random.choice(self.t_u_where) @@ -2915,25 +2915,25 @@ class TDTestCase: sql += "%s " % random.choice(self.order_u_where) sql += "%s " % random.choice(self.limit1_where) sql += ") ;" - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) # tdSql.query(sql) - # self.cur1.execute(sql) # TD-16039 + # self.cur1.execute(sql) # TD-16039 elif (timelist == ['ELAPSED']) : sql = "select min(asct1*110) from ( select " - sql += "%s, " % time_fun_join_1 - sql += "%s as asct1 " % time_fun_join_2 + sql += "%s, " % time_fun_join_1 + sql += "%s as asct1 " % time_fun_join_2 sql += "from stable_1 t1 , stable_2 t2 where t1.ts = t2.ts and " sql += "%s " % random.choice(self.t_join_where) sql += "and %s " % random.choice(self.t_u_where) sql += "and %s " % random.choice(self.t_u_or_where) sql += "%s " % random.choice(self.limit1_where) sql += ") ;" - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) # tdSql.query(sql) - # self.cur1.execute(sql) # TD-16039 - + # self.cur1.execute(sql) # TD-16039 + self.restartDnodes() tdSql.query("select 1-10 as time_nest from stable_1 limit 1;") for i in range(self.fornum): @@ -2958,8 +2958,8 @@ class TDTestCase: sql += "%s " % random.choice(self.order_where) sql += "%s " % random.choice(self.limit1_where) sql += ")" - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) #TD-15437 tdSql.query(sql) #TD-15437 self.cur1.execute(sql) elif (timelist == ['TIMEZONE']) or (timelist == ['CAST']) or (timelist == ['CAST_1']) or (timelist == ['CAST_2']) or (timelist == ['CAST_3']) or (timelist == ['CAST_4']): @@ -2982,10 +2982,10 @@ class TDTestCase: sql += "%s " % random.choice(self.order_where) sql += "%s " % random.choice(self.limit1_where) sql += ")" - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) #TD-15437 tdSql.query(sql) - #TD-15437 self.cur1.execute(sql) + #TD-15437 self.cur1.execute(sql) elif (timelist == ['ELAPSED']) : sql = "select abs(asct1),now(),today(),timezone() from ( select " sql += "%s as asct1 ," % time_fun_1 @@ -3000,11 +3000,11 @@ class TDTestCase: sql += "%s " % random.choice(self.q_where) sql += "%s " % random.choice(self.limit1_where) sql += ")" - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) tdSql.query(sql) - #TD-15437 self.cur1.execute(sql) - + #TD-15437 self.cur1.execute(sql) + #3 inter union not support tdSql.query("select 1-11 as time_nest from stable_1 limit 1;") for i in range(self.fornum): @@ -3028,10 +3028,10 @@ class TDTestCase: sql += "%s " % random.choice(self.order_where) sql += "%s " % random.choice(self.limit1_where) sql += ")" - tdLog.info(sql) - tdLog.info(len(sql)) - # tdSql.query(sql)#TD-15473 - # self.cur1.execute(sql)#TD-15473 + tdLog.info(sql) + tdLog.info(len(sql)) + # tdSql.query(sql)#TD-15473 + # self.cur1.execute(sql)#TD-15473 elif (timelist == ['TIMEZONE']) or (timelist == ['CAST']) or (timelist == ['CAST_1']) or (timelist == ['CAST_2']) or (timelist == ['CAST_3']) or (timelist == ['CAST_4']): sql = "select ts , (asct1,now()),(now(),asct2) from ( select " sql += "%s as asct1, ts ," % time_fun_1 @@ -3051,10 +3051,10 @@ class TDTestCase: sql += "%s " % random.choice(self.order_where) sql += "%s " % random.choice(self.limit1_where) sql += ")" - tdLog.info(sql) - tdLog.info(len(sql)) - # tdSql.query(sql)#TD-15473 - # self.cur1.execute(sql)#TD-15473 + tdLog.info(sql) + tdLog.info(len(sql)) + # tdSql.query(sql)#TD-15473 + # self.cur1.execute(sql)#TD-15473 elif (timelist == ['ELAPSED']) : sql = "select asct1+asct2,now(),today(),timezone() from ( select " sql += "%s as asct1, " % time_fun_1 @@ -3070,118 +3070,118 @@ class TDTestCase: sql += "%s " % random.choice(self.order_where) sql += "%s " % random.choice(self.limit1_where) sql += ")" - tdLog.info(sql) - tdLog.info(len(sql)) - tdSql.query(sql)#TD-15473 - self.cur1.execute(sql)#TD-15473 + tdLog.info(sql) + tdLog.info(len(sql)) + tdSql.query(sql)#TD-15473 + self.cur1.execute(sql)#TD-15473 tdSql.query("select 1-12 as time_nest from stable_1 limit 1;") for i in range(self.fornum): if (timelist == ['NOW','TODAY']) or (timelist == ['TIMETRUNCATE']) or (timelist == ['TO_ISO8601'])\ or (timelist == ['TO_UNIXTIMESTAMP']): sql = "select ts , timediff(asct1,now) from ( select t1.ts as ts," - sql += "%s, " % time_fun_join_1 - sql += "%s as asct1, " % time_fun_join_2 - sql += "t1.%s, " % random.choice(self.q_select) - sql += "t1.%s, " % random.choice(self.q_select) - sql += "t2.%s, " % random.choice(self.q_select) - sql += "t2.%s, " % random.choice(self.q_select) + sql += "%s, " % time_fun_join_1 + sql += "%s as asct1, " % time_fun_join_2 + sql += "t1.%s, " % random.choice(self.q_select) + sql += "t1.%s, " % random.choice(self.q_select) + sql += "t2.%s, " % random.choice(self.q_select) + sql += "t2.%s, " % random.choice(self.q_select) sql += "t2.ts from stable_1 t1 , stable_2 t2 where t1.ts = t2.ts and " sql += "%s " % random.choice(self.t_u_where) sql += "and %s " % random.choice(self.t_u_or_where) sql += "%s " % random.choice(self.order_u_where) sql += "%s " % random.choice(self.limit1_where) sql += ");" - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) # tdSql.query(sql) # self.cur1.execute(sql)# TD-16039 elif (timelist == ['TIMEZONE']) or (timelist == ['CAST']) or (timelist == ['CAST_1']) or (timelist == ['CAST_2']) or (timelist == ['CAST_3']) or (timelist == ['CAST_4']): sql = "select ts , asct1,now() from ( select t1.ts as ts," - sql += "%s, " % time_fun_join_1 - sql += "%s as asct1, " % time_fun_join_2 - sql += "t1.%s, " % random.choice(self.q_select) - sql += "t1.%s, " % random.choice(self.q_select) - sql += "t2.%s, " % random.choice(self.q_select) - sql += "t2.%s, " % random.choice(self.q_select) + sql += "%s, " % time_fun_join_1 + sql += "%s as asct1, " % time_fun_join_2 + sql += "t1.%s, " % random.choice(self.q_select) + sql += "t1.%s, " % random.choice(self.q_select) + sql += "t2.%s, " % random.choice(self.q_select) + sql += "t2.%s, " % random.choice(self.q_select) sql += "t2.ts from stable_1 t1 , stable_2 t2 where t1.ts = t2.ts and " sql += "%s " % random.choice(self.t_u_where) sql += "and %s " % random.choice(self.t_u_or_where) sql += "%s " % random.choice(self.order_u_where) sql += "%s " % random.choice(self.limit1_where) sql += ");" - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) # tdSql.query(sql) # self.cur1.execute(sql)# TD-16039 elif (timelist == ['ELAPSED']) : sql = "select min(floor(asct1)),now() from ( select " - sql += "%s, " % time_fun_join_1 - sql += "%s as asct1 " % time_fun_join_2 + sql += "%s, " % time_fun_join_1 + sql += "%s as asct1 " % time_fun_join_2 sql += " from stable_1 t1 , stable_2 t2 where t1.ts = t2.ts and " sql += "%s " % random.choice(self.t_u_where) sql += "and %s " % random.choice(self.t_u_or_where) sql += "%s " % random.choice(self.limit1_where) sql += ");" - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) # tdSql.query(sql) # self.cur1.execute(sql)# TD-16039 - + tdSql.query("select 1-13 as time_nest from stable_1 limit 1;") for i in range(self.fornum): if (timelist == ['NOW','TODAY']) or (timelist == ['TIMETRUNCATE']) or (timelist == ['TO_ISO8601'])\ or (timelist == ['TO_UNIXTIMESTAMP']): sql = "select ts , timediff(%s,now)," % time_fun_2 - sql += "%s as asct1, " % time_fun_1 + sql += "%s as asct1, " % time_fun_1 + sql += "%s, " % random.choice(self.q_select) sql += "%s, " % random.choice(self.q_select) - sql += "%s, " % random.choice(self.q_select) sql += "%s " % time_fun_2 - sql += "%s " % random.choice(self.t_select) + sql += "%s " % random.choice(self.t_select) sql += " from ( select * from stable_1 where " sql += "%s " % random.choice(self.qt_where) sql += "%s " % random.choice(self.order_where) sql += ") ;" - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) # tdSql.query(sql) # tdSql.checkRows(300) # self.cur1.execute(sql) # TD-16039 elif (timelist == ['TIMEZONE']) or (timelist == ['CAST']) or (timelist == ['CAST_1']) or (timelist == ['CAST_2']) or (timelist == ['CAST_3']) or (timelist == ['CAST_4']): sql = "select ts ,now(),today(),timezone(), " - sql += "%s as asct1, " % time_fun_1 + sql += "%s as asct1, " % time_fun_1 + sql += "%s, " % random.choice(self.q_select) sql += "%s, " % random.choice(self.q_select) - sql += "%s, " % random.choice(self.q_select) sql += "%s " % time_fun_2 - sql += "%s " % random.choice(self.t_select) + sql += "%s " % random.choice(self.t_select) sql += " from ( select * from stable_1 where " sql += "%s " % random.choice(self.qt_where) sql += "%s " % random.choice(self.order_where) sql += ") ;" - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) # tdSql.query(sql) # tdSql.checkRows(300) # self.cur1.execute(sql) # TD-16039 elif (timelist == ['ELAPSED']) : sql = "select now(),today(),timezone(), " - sql += "%s as asct1, " % time_fun_1 + sql += "%s as asct1, " % time_fun_1 sql += "%s " % time_fun_2 sql += " from ( select * from stable_1 where " sql += "%s " % random.choice(self.qt_where) sql += "%s " % random.choice(self.order_where) sql += ") ;" - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) # tdSql.query(sql) # self.cur1.execute(sql) # TD-16039 - + tdSql.query("select 1-14 as time_nest from stable_1 limit 1;") for i in range(self.fornum): if (timelist == ['NOW','TODAY']) or (timelist == ['TIMETRUNCATE']) or (timelist == ['TO_ISO8601'])\ or (timelist == ['TO_UNIXTIMESTAMP']): sql = "select ts , timediff(asct1,now),timediff(now,asct2) from ( select ts ts ," - sql += "%s as asct1, " % time_fun_1 + sql += "%s as asct1, " % time_fun_1 sql += "%s as asct2" % time_fun_2 sql += " from stable_1 where " sql += "%s " % random.choice(self.q_where) @@ -3189,13 +3189,13 @@ class TDTestCase: sql += "%s " % random.choice(self.order_desc_where) sql += "%s " % random.choice([self.limit_where[2] , self.limit_where[3]] ) sql += " ) ;" - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) # tdSql.query(sql) # self.cur1.execute(sql) # TD-16039 elif (timelist == ['TIMEZONE']) or (timelist == ['CAST']) or (timelist == ['CAST_1']) or (timelist == ['CAST_2']) or (timelist == ['CAST_3']) or (timelist == ['CAST_4']): sql = "select ts , (asct1),now(),(now()),asct2 from ( select ts ts ," - sql += "%s as asct1, " % time_fun_1 + sql += "%s as asct1, " % time_fun_1 sql += "%s as asct2" % time_fun_2 sql += " from stable_1 where " sql += "%s " % random.choice(self.q_where) @@ -3203,83 +3203,83 @@ class TDTestCase: sql += "%s " % random.choice(self.order_desc_where) sql += "%s " % random.choice([self.limit_where[2] , self.limit_where[3]] ) sql += " ) ;" - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) # tdSql.query(sql) # self.cur1.execute(sql) # TD-16039 elif (timelist == ['ELAPSED']) : sql = "select ts , (asct1)*asct2,now(),(now()) from ( select " - sql += "%s as asct1, " % time_fun_1 + sql += "%s as asct1, " % time_fun_1 sql += "%s as asct2" % time_fun_2 sql += " from stable_1 where " sql += "%s " % random.choice(self.q_where) sql += "%s " % random.choice(self.partiton_where) sql += "%s " % random.choice([self.limit_where[2] , self.limit_where[3]] ) sql += " ) ;" - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) # tdSql.query(sql) # self.cur1.execute(sql) # TD-16039 - + tdSql.query("select 1-15 as time_nest from stable_1 limit 1;") for i in range(self.fornum): if (timelist == ['NOW','TODAY']) or (timelist == ['TIMETRUNCATE']) or (timelist == ['TO_ISO8601'])\ or (timelist == ['TO_UNIXTIMESTAMP']): sql = "select ts , timediff(asct1,now),timediff(now,asct2) from ( select t1.ts as ts," - sql += "%s as asct2, " % time_fun_join_1 - sql += "%s as asct1, " % time_fun_join_2 - sql += "t1.%s, " % random.choice(self.q_select) - sql += "t1.%s, " % random.choice(self.q_select) - sql += "t2.%s, " % random.choice(self.q_select) - sql += "t2.%s " % random.choice(self.q_select) + sql += "%s as asct2, " % time_fun_join_1 + sql += "%s as asct1, " % time_fun_join_2 + sql += "t1.%s, " % random.choice(self.q_select) + sql += "t1.%s, " % random.choice(self.q_select) + sql += "t2.%s, " % random.choice(self.q_select) + sql += "t2.%s " % random.choice(self.q_select) sql += "from stable_1 t1, stable_2 t2 where t1.ts = t2.ts and " sql += "%s " % random.choice(self.t_join_where) sql += " and %s " % random.choice(self.qt_u_or_where) sql += "%s " % random.choice(self.partiton_where_j) sql += "%s " % random.choice(self.slimit1_where) - sql += ") " + sql += ") " sql += "%s " % random.choice(self.order_desc_where) sql += "%s ;" % random.choice(self.limit_u_where) - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) # tdSql.query(sql) - # self.cur1.execute(sql) # TD-16039 + # self.cur1.execute(sql) # TD-16039 elif (timelist == ['TIMEZONE']) or (timelist == ['CAST']) or (timelist == ['CAST_1']) or (timelist == ['CAST_2']) or (timelist == ['CAST_3']) or (timelist == ['CAST_4']): sql = "select ts , asct1,(now()),(now()),asct2 ,now(),today(),timezone() from ( select t1.ts as ts," - sql += "%s as asct2, " % time_fun_join_1 - sql += "%s as asct1, " % time_fun_join_2 - sql += "t1.%s, " % random.choice(self.q_select) - sql += "t1.%s, " % random.choice(self.q_select) - sql += "t2.%s, " % random.choice(self.q_select) - sql += "t2.%s " % random.choice(self.q_select) + sql += "%s as asct2, " % time_fun_join_1 + sql += "%s as asct1, " % time_fun_join_2 + sql += "t1.%s, " % random.choice(self.q_select) + sql += "t1.%s, " % random.choice(self.q_select) + sql += "t2.%s, " % random.choice(self.q_select) + sql += "t2.%s " % random.choice(self.q_select) sql += "from stable_1 t1, stable_2 t2 where t1.ts = t2.ts and " sql += "%s " % random.choice(self.t_join_where) sql += " and %s " % random.choice(self.qt_u_or_where) sql += "%s " % random.choice(self.partiton_where_j) sql += "%s " % random.choice(self.slimit1_where) - sql += ") " + sql += ") " sql += "%s " % random.choice(self.order_desc_where) sql += "%s ;" % random.choice(self.limit_u_where) - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) # tdSql.query(sql) # self.cur1.execute(sql) # TD-16039 elif (timelist == ['ELAPSED']) : sql = "select asct1,(now()),(now()),asct2 ,now(),today(),timezone() from ( select " - sql += "%s as asct2, " % time_fun_join_1 - sql += "%s as asct1 " % time_fun_join_2 + sql += "%s as asct2, " % time_fun_join_1 + sql += "%s as asct1 " % time_fun_join_2 sql += "from stable_1 t1, stable_2 t2 where t1.ts = t2.ts and " sql += "%s " % random.choice(self.t_join_where) sql += " and %s " % random.choice(self.qt_u_or_where) sql += "%s " % random.choice(self.partiton_where_j) sql += "%s " % random.choice(self.slimit1_where) - sql += ") " + sql += ") " sql += "%s ;" % random.choice(self.limit_u_where) - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) tdSql.query(sql) self.cur1.execute(sql) # TD-16039 - + #taos -f sql startTime_taos_f = time.time() print("taos -f %s sql start!" %timelist) @@ -3287,149 +3287,149 @@ class TDTestCase: _ = subprocess.check_output(taos_cmd1, shell=True).decode("utf-8") print("taos -f %s sql over!" %timelist) endTime_taos_f = time.time() - print("taos_f total time %ds" % (endTime_taos_f - startTime_taos_f)) - - print("=========%s====over=============" %timelist) + print("taos_f total time %ds" % (endTime_taos_f - startTime_taos_f)) + + print("=========%s====over=============" %timelist) def base_nest(self,baselist): - - print("==========%s===start=============" %baselist) - os.system("rm -rf %s/%s.sql" % (self.testcasePath,self.testcaseFilename)) - + + print("==========%s===start=============" %baselist) + os.system("rm -rf %s/%s.sql" % (self.testcasePath,self.testcaseFilename)) + self.dropandcreateDB_random("%s" %self.db_nest, 1) - + if (baselist == ['A']) or (baselist == ['S']) or (baselist == ['F']) \ or (baselist == ['C']): - base_functions = baselist - fun_fix_column = ['(q_bigint)','(q_smallint)','(q_tinyint)','(q_int)','(q_float)','(q_double)','(q_bigint_null)','(q_smallint_null)','(q_tinyint_null)','(q_int_null)','(q_float_null)','(q_double_null)'] + base_functions = baselist + fun_fix_column = ['(q_bigint)','(q_smallint)','(q_tinyint)','(q_int)','(q_float)','(q_double)','(q_bigint_null)','(q_smallint_null)','(q_tinyint_null)','(q_int_null)','(q_float_null)','(q_double_null)'] fun_column_1 = random.sample(base_functions,1)+random.sample(fun_fix_column,1) base_fun_1 = str(fun_column_1).replace("[","").replace("]","").replace("'","").replace(", ","") fun_column_2 = random.sample(base_functions,1)+random.sample(fun_fix_column,1) base_fun_2 = str(fun_column_2).replace("[","").replace("]","").replace("'","").replace(", ","") - + fun_fix_column_j = ['(t1.q_bigint)','(t1.q_smallint)','(t1.q_tinyint)','(t1.q_int)','(t1.q_float)','(t1.q_double)','(t1.q_bigint_null)','(t1.q_smallint_null)','(t1.q_tinyint_null)','(t1.q_int_null)','(t1.q_float_null)','(t1.q_double_null)', - '(t2.q_bigint)','(t2.q_smallint)','(t2.q_tinyint)','(t2.q_int)','(t2.q_float)','(t2.q_double)','(t2.q_bigint_null)','(t2.q_smallint_null)','(t2.q_tinyint_null)','(t2.q_int_null)','(t2.q_float_null)','(t2.q_double_null)'] + '(t2.q_bigint)','(t2.q_smallint)','(t2.q_tinyint)','(t2.q_int)','(t2.q_float)','(t2.q_double)','(t2.q_bigint_null)','(t2.q_smallint_null)','(t2.q_tinyint_null)','(t2.q_int_null)','(t2.q_float_null)','(t2.q_double_null)'] fun_column_join_1 = random.sample(base_functions,1)+random.sample(fun_fix_column_j,1) base_fun_join_1 = str(fun_column_join_1).replace("[","").replace("]","").replace("'","").replace(", ","") fun_column_join_2 = random.sample(base_functions,1)+random.sample(fun_fix_column_j,1) base_fun_join_2 = str(fun_column_join_2).replace("[","").replace("]","").replace("'","").replace(", ","") elif (baselist == ['P']) or (baselist == ['M']) or (baselist == ['S'])or (baselist == ['T']): - base_functions = baselist - num = random.randint(0, 1000) + base_functions = baselist + num = random.randint(0, 1000) fun_fix_column = ['(q_bigint,num)','(q_smallint,num)','(q_tinyint,num)','(q_int,num)','(q_float,num)','(q_double,num)', - '(q_bigint_null,num)','(q_smallint_null,num)','(q_tinyint_null,num)','(q_int_null,num)','(q_float_null,num)','(q_double_null,num)'] + '(q_bigint_null,num)','(q_smallint_null,num)','(q_tinyint_null,num)','(q_int_null,num)','(q_float_null,num)','(q_double_null,num)'] fun_column_1 = random.sample(base_functions,1)+random.sample(fun_fix_column,1) base_fun_1 = str(fun_column_1).replace("[","").replace("]","").replace("'","").replace(", ","").replace("num",base(num)) fun_column_2 = random.sample(base_functions,1)+random.sample(fun_fix_column,1) base_fun_2 = str(fun_column_2).replace("[","").replace("]","").replace("'","").replace(", ","").replace("num",base(num)) - + fun_fix_column_j = ['(t1.q_bigint,num)','(t1.q_smallint,num)','(t1.q_tinyint,num)','(t1.q_int,num)','(t1.q_float,num)','(t1.q_double,num)', '(t1.q_bigint_null,num)','(t1.q_smallint_null,num)','(t1.q_tinyint_null,num)','(t1.q_int_null,num)','(t1.q_float_null,num)','(t1.q_double_null,num)', '(t2.q_bigint,num)','(t2.q_smallint,num)','(t2.q_tinyint,num)','(t2.q_int,num)','(t2.q_float,num)','(t2.q_double,num)', - '(t2.q_bigint_null,num)','(t2.q_smallint_null,num)','(t2.q_tinyint_null,num)','(t2.q_int_null,num)','(t2.q_float_null,num)','(t2.q_double_null,num)'] + '(t2.q_bigint_null,num)','(t2.q_smallint_null,num)','(t2.q_tinyint_null,num)','(t2.q_int_null,num)','(t2.q_float_null,num)','(t2.q_double_null,num)'] fun_column_join_1 = random.sample(base_functions,1)+random.sample(fun_fix_column_j,1) base_fun_join_1 = str(fun_column_join_1).replace("[","").replace("]","").replace("'","").replace(", ","").replace("num",base(num)) fun_column_join_2 = random.sample(base_functions,1)+random.sample(fun_fix_column_j,1) base_fun_join_2 = str(fun_column_join_2).replace("[","").replace("]","").replace("'","").replace(", ","").replace("num",base(num)) - + tdSql.query("select 1-1 as base_nest from stable_1 limit 1;") for i in range(self.fornum): - sql = "select ts , floor(asct1) from ( select " - sql += "%s as asct1, " % base_fun_1 - sql += "%s as asct2, " % base_fun_2 + sql = "select ts , floor(asct1) from ( select " + sql += "%s as asct1, " % base_fun_1 + sql += "%s as asct2, " % base_fun_2 sql += "%s, " % random.choice(self.s_s_select) - sql += "%s, " % random.choice(self.q_select) + sql += "%s, " % random.choice(self.q_select) sql += "ts from regular_table_1 where " sql += "%s " % random.choice(self.q_where) sql += "%s " % random.choice(self.order_where) sql += ");" - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) tdSql.query(sql) tdSql.checkRows(100) self.cur1.execute(sql) - + tdSql.query("select 1-2 as base_nest from stable_1 limit 1;") for i in range(self.fornum): sql = "select ts , abs(asct1) from ( select " - sql += "%s as asct1, " % base_fun_1 + sql += "%s as asct1, " % base_fun_1 sql += "%s, " % random.choice(self.s_s_select) - sql += "%s, " % random.choice(self.q_select) + sql += "%s, " % random.choice(self.q_select) sql += "ts ts from regular_table_1 where " sql += "%s " % random.choice(self.q_where) sql += "%s )" % random.choice(self.order_where) - sql += "%s " % random.choice(self.unionall_or_union) + sql += "%s " % random.choice(self.unionall_or_union) sql += "select ts , asct2 from ( select " - sql += "%s as asct2, " % base_fun_2 + sql += "%s as asct2, " % base_fun_2 sql += "%s, " % random.choice(self.s_s_select) - sql += "%s, " % random.choice(self.q_select) + sql += "%s, " % random.choice(self.q_select) sql += "ts ts from regular_table_1 where " - sql += "%s " % random.choice(self.q_where) + sql += "%s " % random.choice(self.q_where) #sql += "%s " % random.choice(having_support) sql += "%s " % random.choice(self.order_where) sql += "%s " % random.choice(self.limit1_where) sql += ")" - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) #TD-15437 tdSql.query(sql) - #TD-15437 self.cur1.execute(sql) - + #TD-15437 self.cur1.execute(sql) + tdSql.query("select 1-3 as base_nest from stable_1 limit 1;") for i in range(self.fornum): sql = "select ts , min(asct1) from ( select " sql += "%s as asct1, ts ," % base_fun_1 sql += "%s as asct2, " % base_fun_2 sql += "%s, " % random.choice(self.s_s_select) - sql += "%s, " % random.choice(self.q_select) + sql += "%s, " % random.choice(self.q_select) sql += "ts from regular_table_1 where " sql += "%s " % random.choice(self.q_where) - sql += "%s select " % random.choice(self.unionall_or_union) + sql += "%s select " % random.choice(self.unionall_or_union) sql += "%s as asct2, ts ," % base_fun_2 sql += "%s as asct1, " % base_fun_1 sql += "%s, " % random.choice(self.s_s_select) - sql += "%s, " % random.choice(self.q_select) + sql += "%s, " % random.choice(self.q_select) sql += "ts from regular_table_2 where " sql += "%s " % random.choice(self.q_where) sql += "%s " % random.choice(self.order_where) sql += ")" - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) #TD-15473 tdSql.query(sql) #self.cur1.execute(sql) - + tdSql.query("select 1-4 as base_nest from stable_1 limit 1;") for i in range(self.fornum): sql = "select ts , asct1 from ( select t1.ts as ts," - sql += "%s, " % base_fun_join_1 - sql += "%s as asct1, " % base_fun_join_2 - sql += "%s, " % base_fun_join_1 - sql += "t1.%s, " % random.choice(self.q_select) - sql += "t2.%s, " % random.choice(self.q_select) + sql += "%s, " % base_fun_join_1 + sql += "%s as asct1, " % base_fun_join_2 + sql += "%s, " % base_fun_join_1 + sql += "t1.%s, " % random.choice(self.q_select) + sql += "t2.%s, " % random.choice(self.q_select) sql += "t2.ts from regular_table_1 t1 , regular_table_2 t2 where t1.ts = t2.ts and " sql += "%s " % random.choice(self.q_u_where) sql += "and %s " % random.choice(self.q_u_or_where) sql += "%s " % random.choice(self.order_u_where) sql += ");" - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) tdSql.query(sql) tdSql.checkRows(100) self.cur1.execute(sql) - + tdSql.query("select 1-5 as base_nest from stable_1 limit 1;") for i in range(self.fornum): sql = "select ts ," - sql += "%s, " % base_fun_1 + sql += "%s, " % base_fun_1 + sql += "%s, " % random.choice(self.q_select) sql += "%s, " % random.choice(self.q_select) - sql += "%s, " % random.choice(self.q_select) sql += "%s " % base_fun_2 sql += " from ( select * from regular_table_1 ) where " sql += "%s " % random.choice(self.q_where) sql += "%s " % random.choice(self.order_where) sql += " ;" - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) tdSql.query(sql) tdSql.checkRows(100) self.cur1.execute(sql) @@ -3437,19 +3437,19 @@ class TDTestCase: tdSql.query("select 1-6 as base_nest from stable_1 limit 1;") for i in range(self.fornum): sql = "select ts , max(asct1) from ( select t1.ts as ts," - sql += "%s, " % base_fun_join_1 - sql += "%s as asct1, " % base_fun_join_2 - sql += "t1.%s, " % random.choice(self.q_select) - sql += "t2.%s, " % random.choice(self.q_select) - sql += "%s, " % base_fun_join_1 + sql += "%s, " % base_fun_join_1 + sql += "%s as asct1, " % base_fun_join_2 + sql += "t1.%s, " % random.choice(self.q_select) + sql += "t2.%s, " % random.choice(self.q_select) + sql += "%s, " % base_fun_join_1 sql += "t2.ts from regular_table_1 t1 , regular_table_2 t2 where t1.ts = t2.ts and " sql += "%s " % random.choice(self.q_u_where) sql += "and %s )" % random.choice(self.q_u_or_where) sql += "%s " % random.choice(self.order_where) sql += "%s " % random.choice(self.limit1_where) - tdLog.info(sql) - tdLog.info(len(sql)) - tdSql.query(sql) + tdLog.info(sql) + tdLog.info(len(sql)) + tdSql.query(sql) self.cur1.execute(sql) tdSql.query("select 1-7 as base_nest from stable_1 limit 1;") @@ -3457,18 +3457,18 @@ class TDTestCase: sql = "select ts , abs(asct1) from ( select " sql += "%s as asct1, ts ," % base_fun_1 sql += "%s as asct2, " % base_fun_2 - sql += "%s, " % random.choice(self.q_select) - sql += "%s, " % random.choice(self.t_select) + sql += "%s, " % random.choice(self.q_select) + sql += "%s, " % random.choice(self.t_select) sql += "ts from stable_1 where " sql += "%s " % random.choice(self.qt_where) sql += "%s " % random.choice(self.order_where) sql += ") ;" - tdLog.info(sql) + tdLog.info(sql) tdLog.info(len(sql)) tdSql.query(sql) tdSql.checkRows(300) self.cur1.execute(sql) - + tdSql.query("select 1-8 as base_nest from stable_1 limit 1;") for i in range(self.fornum): sql = "select ts,floor(asct1) " @@ -3476,13 +3476,13 @@ class TDTestCase: sql += "%s, " % random.choice(self.s_s_select) sql += "%s as asct1, ts ," % base_fun_1 sql += "%s as asct2, " % base_fun_2 - sql += "%s, " % random.choice(self.q_select) - sql += "%s, " % random.choice(self.t_select) + sql += "%s, " % random.choice(self.q_select) + sql += "%s, " % random.choice(self.t_select) sql += "ts from stable_1 where " sql += "%s " % random.choice(self.qt_where) sql += "%s " % random.choice(self.order_where) sql += ") ;" - tdLog.info(sql) + tdLog.info(sql) tdLog.info(len(sql)) tdSql.query(sql) tdSql.checkRows(300) @@ -3491,12 +3491,12 @@ class TDTestCase: tdSql.query("select 1-9 as base_nest from stable_1 limit 1;") for i in range(self.fornum): sql = "select ts , max(asct1) from ( select t1.ts as ts," - sql += "%s, " % base_fun_join_1 - sql += "%s as asct1, " % base_fun_join_2 - sql += "t1.%s, " % random.choice(self.q_select) - sql += "t1.%s, " % random.choice(self.q_select) - sql += "t2.%s, " % random.choice(self.q_select) - sql += "t2.%s, " % random.choice(self.q_select) + sql += "%s, " % base_fun_join_1 + sql += "%s as asct1, " % base_fun_join_2 + sql += "t1.%s, " % random.choice(self.q_select) + sql += "t1.%s, " % random.choice(self.q_select) + sql += "t2.%s, " % random.choice(self.q_select) + sql += "t2.%s, " % random.choice(self.q_select) sql += "t2.ts from stable_1 t1 , stable_2 t2 where t1.ts = t2.ts and " sql += "%s " % random.choice(self.t_join_where) sql += "and %s " % random.choice(self.t_u_where) @@ -3504,11 +3504,11 @@ class TDTestCase: sql += "%s " % random.choice(self.order_u_where) sql += "%s " % random.choice(self.limit1_where) sql += ") ;" - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) tdSql.query(sql) self.cur1.execute(sql) - + self.restartDnodes() tdSql.query("select 1-10 as base_nest from stable_1 limit 1;") for i in range(self.fornum): @@ -3531,11 +3531,11 @@ class TDTestCase: sql += "%s " % random.choice(self.order_where) sql += "%s " % random.choice(self.limit1_where) sql += ")" - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) #TD-15437 tdSql.query(sql) #TD-15437 self.cur1.execute(sql) - + #3 inter union not support tdSql.query("select 1-11 as base_nest from stable_1 limit 1;") for i in range(self.fornum): @@ -3559,53 +3559,53 @@ class TDTestCase: sql += "%s " % random.choice(self.order_where) sql += "%s " % random.choice(self.limit1_where) sql += ")" - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) #TD-15837 tdSql.query(sql) # self.cur1.execute(sql) tdSql.query("select 1-12 as base_nest from stable_1 limit 1;") for i in range(self.fornum): sql = "select ts , max(asct1) from ( select t1.ts as ts," - sql += "%s, " % base_fun_join_1 - sql += "%s as asct1, " % base_fun_join_2 - sql += "t1.%s, " % random.choice(self.q_select) - sql += "t1.%s, " % random.choice(self.q_select) - sql += "t2.%s, " % random.choice(self.q_select) - sql += "t2.%s, " % random.choice(self.q_select) + sql += "%s, " % base_fun_join_1 + sql += "%s as asct1, " % base_fun_join_2 + sql += "t1.%s, " % random.choice(self.q_select) + sql += "t1.%s, " % random.choice(self.q_select) + sql += "t2.%s, " % random.choice(self.q_select) + sql += "t2.%s, " % random.choice(self.q_select) sql += "t2.ts from stable_1 t1 , stable_2 t2 where t1.ts = t2.ts and " sql += "%s " % random.choice(self.t_u_where) sql += "and %s " % random.choice(self.t_u_or_where) sql += "%s " % random.choice(self.order_u_where) sql += "%s " % random.choice(self.limit1_where) sql += ");" - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) tdSql.query(sql) self.cur1.execute(sql) - + tdSql.query("select 1-13 as base_nest from stable_1 limit 1;") for i in range(self.fornum): sql = "select ts ," - sql += "%s, " % base_fun_1 + sql += "%s, " % base_fun_1 + sql += "%s, " % random.choice(self.q_select) sql += "%s, " % random.choice(self.q_select) - sql += "%s, " % random.choice(self.q_select) sql += "%s " % base_fun_2 - sql += "%s " % random.choice(self.t_select) + sql += "%s " % random.choice(self.t_select) sql += " from ( select * from stable_1 where " sql += "%s " % random.choice(self.qt_where) sql += "%s " % random.choice(self.order_where) sql += ") ;" - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) tdSql.query(sql) tdSql.checkRows(300) self.cur1.execute(sql) - + tdSql.query("select 1-14 as base_nest from stable_1 limit 1;") for i in range(self.fornum): sql = "select avg(asct1),count(asct2) from ( select " - sql += "%s as asct1, " % base_fun_1 + sql += "%s as asct1, " % base_fun_1 sql += "%s as asct2" % base_fun_2 sql += " from stable_1 where " sql += "%s " % random.choice(self.q_where) @@ -3613,33 +3613,33 @@ class TDTestCase: sql += "%s " % random.choice(self.order_desc_where) sql += "%s " % random.choice([self.limit_where[2] , self.limit_where[3]] ) sql += " ) ;" - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) tdSql.query(sql) - self.cur1.execute(sql) - + self.cur1.execute(sql) + tdSql.query("select 1-15 as base_nest from stable_1 limit 1;") for i in range(self.fornum): sql = "select ts , max(asct1) from ( select t1.ts as ts," - sql += "%s, " % base_fun_join_1 - sql += "%s as asct1, " % base_fun_join_2 - sql += "t1.%s, " % random.choice(self.q_select) - sql += "t1.%s, " % random.choice(self.q_select) - sql += "t2.%s, " % random.choice(self.q_select) - sql += "t2.%s " % random.choice(self.q_select) + sql += "%s, " % base_fun_join_1 + sql += "%s as asct1, " % base_fun_join_2 + sql += "t1.%s, " % random.choice(self.q_select) + sql += "t1.%s, " % random.choice(self.q_select) + sql += "t2.%s, " % random.choice(self.q_select) + sql += "t2.%s " % random.choice(self.q_select) sql += "from stable_1 t1, stable_2 t2 where t1.ts = t2.ts and " sql += "%s " % random.choice(self.t_join_where) sql += " and %s " % random.choice(self.qt_u_or_where) sql += "%s " % random.choice(self.partiton_where_j) sql += "%s " % random.choice(self.slimit1_where) - sql += ") " + sql += ") " sql += "%s " % random.choice(self.order_desc_where) sql += "%s ;" % random.choice(self.limit_u_where) - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) tdSql.query(sql) - self.cur1.execute(sql) - + self.cur1.execute(sql) + #taos -f sql startTime_taos_f = time.time() print("taos -f %s sql start!" %baselist) @@ -3647,35 +3647,35 @@ class TDTestCase: _ = subprocess.check_output(taos_cmd1, shell=True).decode("utf-8") print("taos -f %s sql over!" %baselist) endTime_taos_f = time.time() - print("taos_f total time %ds" % (endTime_taos_f - startTime_taos_f)) - - print("=========%s====over=============" %baselist) - + print("taos_f total time %ds" % (endTime_taos_f - startTime_taos_f)) + + print("=========%s====over=============" %baselist) + def function_before_26(self): - + print('=====================2.6 old function start ===========') - os.system("rm -rf %s/%s.sql" % (self.testcasePath,self.testcaseFilename)) - + os.system("rm -rf %s/%s.sql" % (self.testcasePath,self.testcaseFilename)) + self.dropandcreateDB_random("%s" %self.db_nest, 1) - + #1 select * from (select column form regular_table where <\>\in\and\or order by) tdSql.query("select 1-1 from stable_1;") for i in range(self.fornum): #sql = "select ts , * from ( select " ===暂时不支持select * ,用下面这一行 sql = "select ts from ( select " sql += "%s, " % random.choice(self.s_s_select) - sql += "%s, " % random.choice(self.q_select) + sql += "%s, " % random.choice(self.q_select) sql += "ts from regular_table_1 where " sql += "%s " % random.choice(self.q_where) sql += "%s " % random.choice(self.order_where) sql += ");" - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) tdSql.query(sql) tdSql.checkRows(100) self.cur1.execute(sql) - - #1 outer union not support + + #1 outer union not support #self.dropandcreateDB_random("%s" %db, 1) tdSql.query("select 1-2 from stable_1;") for i in range(self.fornum): @@ -3695,12 +3695,12 @@ class TDTestCase: sql += "%s " % random.choice(self.q_where) sql += "%s " % random.choice(self.order_where) sql += ")" - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) tdSql.query(sql) tdSql.checkRows(100) self.cur1.execute(sql) - + #self.dropandcreateDB_random("%s" %db, 1) tdSql.query("select 1-2 from stable_1;") for i in range(self.fornum): @@ -3720,12 +3720,12 @@ class TDTestCase: sql += "%s " % random.choice(self.q_where) sql += "%s " % random.choice(self.order_where) sql += ")" - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) tdSql.query(sql) tdSql.checkRows(200) self.cur1.execute(sql) - + #1 inter union not support tdSql.query("select 1-3 from stable_1;") for i in range(self.fornum): @@ -3735,7 +3735,7 @@ class TDTestCase: sql += "%s, " % random.choice(self.q_select) sql += "ts from regular_table_1 where " sql += "%s " % random.choice(self.q_where) - sql += "" + sql += "" sql += " union select " sql += "%s, " % random.choice(self.s_r_select) sql += "%s, " % random.choice(self.q_select) @@ -3743,12 +3743,12 @@ class TDTestCase: sql += "%s " % random.choice(self.q_where) sql += "%s " % random.choice(self.order_where) sql += ")" - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) #TD-15607 tdSql.query(sql) #tdSql.checkRows(200) #self.cur1.execute(sql) - + tdSql.query("select 1-3 from stable_1;") for i in range(self.fornum): #sql = "select ts , * from ( select " @@ -3764,47 +3764,47 @@ class TDTestCase: sql += "%s " % random.choice(self.q_where) sql += "%s " % random.choice(self.order_where) sql += ")" - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) #TD-15607 tdSql.query(sql) # tdSql.checkRows(300) #self.cur1.execute(sql) - - #join:select * from (select column form regular_table1,regular_table2 where t1.ts=t2.ts and <\>\in\and\or order by) + + #join:select * from (select column form regular_table1,regular_table2 where t1.ts=t2.ts and <\>\in\and\or order by) #self.dropandcreateDB_random("%s" %db, 1) tdSql.query("select 1-4 from stable_1;") for i in range(self.fornum): #sql = "select ts , * from ( select t1.ts ," sql = "select * from ( select t1.ts ," - sql += "t1.%s, " % random.choice(self.q_select) - sql += "t1.%s, " % random.choice(self.q_select) - sql += "t2.%s, " % random.choice(self.q_select) - sql += "t2.%s, " % random.choice(self.q_select) + sql += "t1.%s, " % random.choice(self.q_select) + sql += "t1.%s, " % random.choice(self.q_select) + sql += "t2.%s, " % random.choice(self.q_select) + sql += "t2.%s, " % random.choice(self.q_select) sql += "t2.ts from regular_table_1 t1 , regular_table_2 t2 where t1.ts = t2.ts and " sql += "%s " % random.choice(self.q_u_where) - sql += "and %s " % random.choice(self.q_u_or_where) + sql += "and %s " % random.choice(self.q_u_or_where) sql += "%s " % random.choice(self.order_u_where) sql += ");" - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) tdSql.query(sql) tdSql.checkRows(100) self.cur1.execute(sql) - #2 select column from (select * form regular_table ) where <\>\in\and\or order by + #2 select column from (select * form regular_table ) where <\>\in\and\or order by #self.dropandcreateDB_random("%s" %db, 1) tdSql.query("select 2-1 from stable_1;") for i in range(self.fornum): sql = "select ts ," sql += "%s, " % random.choice(self.s_r_select) - sql += "%s " % random.choice(self.q_select) + sql += "%s " % random.choice(self.q_select) sql += " from ( select * from regular_table_1 ) where " sql += "%s " % random.choice(self.q_where) sql += "%s " % random.choice(self.order_where) sql += " ;" - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) tdSql.query(sql) tdSql.checkRows(100) self.cur1.execute(sql) @@ -3814,31 +3814,31 @@ class TDTestCase: tdSql.query("select 2-2 from stable_1;") for i in range(self.fornum): sql = "select ts , * from ( select t1.ts ," - sql += "t1.%s, " % random.choice(self.q_select) - sql += "t1.%s, " % random.choice(self.q_select) - sql += "t2.%s, " % random.choice(self.q_select) - sql += "t2.%s, " % random.choice(self.q_select) + sql += "t1.%s, " % random.choice(self.q_select) + sql += "t1.%s, " % random.choice(self.q_select) + sql += "t2.%s, " % random.choice(self.q_select) + sql += "t2.%s, " % random.choice(self.q_select) sql += "t2.ts from regular_table_1 t1 , regular_table_2 t2 ) where t1.ts = t2.ts and " sql += "%s " % random.choice(self.q_u_where) sql += "%s " % random.choice(self.order_u_where) #sql += ");" - tdLog.info(sql) - tdLog.info(len(sql)) - tdSql.error(sql) + tdLog.info(sql) + tdLog.info(len(sql)) + tdSql.error(sql) - #3 select * from (select column\tag form stable where <\>\in\and\or order by ) + #3 select * from (select column\tag form stable where <\>\in\and\or order by ) #self.dropandcreateDB_random("%s" %db, 1) tdSql.query("select 3-1 from stable_1;") for i in range(self.fornum): sql = "select * from ( select " sql += "%s, " % random.choice(self.s_s_select) - sql += "%s, " % random.choice(self.q_select) - sql += "%s, " % random.choice(self.t_select) + sql += "%s, " % random.choice(self.q_select) + sql += "%s, " % random.choice(self.t_select) sql += "ts from stable_1 where " sql += "%s " % random.choice(self.qt_where) sql += "%s " % random.choice(self.order_where) sql += ") ;" - tdLog.info(sql) + tdLog.info(sql) tdLog.info(len(sql)) tdSql.query(sql) tdSql.checkRows(300) @@ -3849,37 +3849,37 @@ class TDTestCase: sql += "%s " % random.choice(self.s_r_select) sql += "from ( select " sql += "%s, " % random.choice(self.s_s_select) - sql += "%s, " % random.choice(self.q_select) - sql += "%s, " % random.choice(self.t_select) + sql += "%s, " % random.choice(self.q_select) + sql += "%s, " % random.choice(self.t_select) sql += "ts from stable_1 where " sql += "%s " % random.choice(self.qt_where) sql += "%s " % random.choice(self.order_where) sql += ") ;" - tdLog.info(sql) + tdLog.info(sql) tdLog.info(len(sql)) tdSql.query(sql) tdSql.checkRows(300) self.cur1.execute(sql) - # select ts,* from (select column\tag form stable1,stable2 where t1.ts = t2.ts and <\>\in\and\or order by ) + # select ts,* from (select column\tag form stable1,stable2 where t1.ts = t2.ts and <\>\in\and\or order by ) #self.dropandcreateDB_random("%s" %db, 1) tdSql.query("select 3-2 from stable_1;") for i in range(self.fornum): sql = "select ts , * from ( select t1.ts , " - sql += "t1.%s, " % random.choice(self.s_s_select) - sql += "t1.%s, " % random.choice(self.q_select) - sql += "t2.%s, " % random.choice(self.s_s_select) - sql += "t2.%s, " % random.choice(self.q_select) + sql += "t1.%s, " % random.choice(self.s_s_select) + sql += "t1.%s, " % random.choice(self.q_select) + sql += "t2.%s, " % random.choice(self.s_s_select) + sql += "t2.%s, " % random.choice(self.q_select) sql += "t2.ts from stable_1 t1 , stable_2 t2 where t1.ts = t2.ts and " sql += "%s " % random.choice(self.t_join_where) sql += "%s " % random.choice(self.order_u_where) sql += ") ;" - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) # TD-15609 tdSql.query(sql) # tdSql.checkRows(100) #self.cur1.execute(sql) - + #3 outer union not support self.restartDnodes() tdSql.query("select 3-3 from stable_1;") @@ -3899,8 +3899,8 @@ class TDTestCase: sql += "%s " % random.choice(self.q_where) sql += "%s " % random.choice(self.order_where) sql += ")" - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) tdSql.query(sql) tdSql.checkRows(300) self.cur1.execute(sql) @@ -3920,12 +3920,12 @@ class TDTestCase: sql += "%s " % random.choice(self.q_where) sql += "%s " % random.choice(self.order_where) sql += ")" - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) tdSql.query(sql) tdSql.checkRows(600) self.cur1.execute(sql) - + #3 inter union not support tdSql.query("select 3-4 from stable_1;") for i in range(self.fornum): @@ -3943,8 +3943,8 @@ class TDTestCase: sql += "%s " % random.choice(self.q_where) sql += "%s " % random.choice(self.order_where) sql += ")" - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) #TD-15837 tdSql.query(sql) # self.cur1.execute(sql) @@ -3952,16 +3952,16 @@ class TDTestCase: tdSql.query("select 3-5 from stable_1;") for i in range(self.fornum): sql = "select * from ( select t1.ts ," - sql += "t1.%s, " % random.choice(self.q_select) - sql += "t1.%s, " % random.choice(self.q_select) - sql += "t2.%s, " % random.choice(self.q_select) - sql += "t2.%s, " % random.choice(self.q_select) + sql += "t1.%s, " % random.choice(self.q_select) + sql += "t1.%s, " % random.choice(self.q_select) + sql += "t2.%s, " % random.choice(self.q_select) + sql += "t2.%s, " % random.choice(self.q_select) sql += "t2.ts from stable_1 t1 , stable_2 t2 where t1.ts = t2.ts and " sql += "%s " % random.choice(self.t_u_where) sql += "%s " % random.choice(self.order_u_where) sql += ");" - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) # TD-15609 tdSql.query(sql) # tdSql.checkRows(100) #self.cur1.execute(sql) @@ -3969,34 +3969,34 @@ class TDTestCase: tdSql.query("select 3-6 from stable_1;") for i in range(self.fornum): sql = "select * from ( select t1.ts ," - sql += "t1.%s, " % random.choice(self.q_select) - sql += "t1.%s, " % random.choice(self.q_select) - sql += "t2.%s, " % random.choice(self.q_select) - sql += "t2.%s, " % random.choice(self.q_select) + sql += "t1.%s, " % random.choice(self.q_select) + sql += "t1.%s, " % random.choice(self.q_select) + sql += "t2.%s, " % random.choice(self.q_select) + sql += "t2.%s, " % random.choice(self.q_select) sql += "t2.ts from stable_1 t1 , stable_2 t2 where t1.ts = t2.ts and " sql += "%s " % random.choice(self.t_u_or_where) sql += "%s " % random.choice(self.order_u_where) sql += ");" - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) # TD-15609 同上 tdSql.query(sql) # tdSql.checkRows(100) #self.cur1.execute(sql) - #4 select column from (select * form stable where <\>\in\and\or order by ) + #4 select column from (select * form stable where <\>\in\and\or order by ) #self.dropandcreateDB_random("%s" %db, 1) tdSql.query("select 4-1 from stable_1;") for i in range(self.fornum): sql = "select ts , " sql += "%s, " % random.choice(self.q_select) - sql += "%s, " % random.choice(self.q_select) - sql += "%s " % random.choice(self.t_select) + sql += "%s, " % random.choice(self.q_select) + sql += "%s " % random.choice(self.t_select) sql += " from ( select * from stable_1 where " sql += "%s " % random.choice(self.qt_where) sql += "%s " % random.choice(self.order_where) sql += ") ;" - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) tdSql.query(sql) tdSql.checkRows(300) self.cur1.execute(sql) @@ -4010,8 +4010,8 @@ class TDTestCase: sql += "%s " % random.choice(self.qt_where) sql += "%s " % random.choice(self.order_where) sql += ") ;" - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) #TD-15500 tdSql.query(sql) #self.cur1.execute(sql) @@ -4020,13 +4020,13 @@ class TDTestCase: for i in range(self.fornum): sql = "select distinct c5_1 " sql += " from ( select " - sql += "%s " % random.choice(self.calc_select_in_ts) + sql += "%s " % random.choice(self.calc_select_in_ts) sql += " as c5_1 from stable_1 where " sql += "%s " % random.choice(self.qt_where) #sql += "%s " % random.choice(order_where) sql += ") ;" - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) tdSql.query(sql) #tdSql.checkRows(1)有的函数还没有提交,会不返回结果,先忽略 self.cur1.execute(sql) @@ -4040,8 +4040,8 @@ class TDTestCase: sql += "%s " % random.choice(self.qt_where) sql += "%s " % random.choice(self.order_desc_where) sql += ") ;" - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) tdSql.error(sql) tdSql.query("select 6-1 from stable_1;") for i in range(self.fornum): @@ -4049,8 +4049,8 @@ class TDTestCase: sql += "%s " % random.choice(self.dt_select) sql += " from stable_1 where " sql += "%s ) ;" % random.choice(self.qt_where) - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) tdSql.query(sql) self.cur1.execute(sql) @@ -4064,8 +4064,8 @@ class TDTestCase: sql += "%s " % random.choice(self.order_desc_where) sql += "%s " % random.choice([self.limit_where[0] , self.limit_where[1]] ) sql += ") ;" - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) tdSql.error(sql) #distinct 和 order by 不能混合使用 tdSql.query("select 7-1 from stable_1;") for i in range(self.fornum): @@ -4076,177 +4076,177 @@ class TDTestCase: #sql += "%s " % random.choice(order_desc_where) sql += "%s " % random.choice([self.limit_where[0] , self.limit_where[1]] ) sql += ") ;" - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) tdSql.query(sql) tdSql.checkRows(1) self.cur1.execute(sql) #calc_select,TWA/Diff/Derivative/Irate are not allowed to apply to super table directly #8 select * from (select ts,calc form ragular_table where <\>\in\and\or order by ) - + # dcDB = self.dropandcreateDB_random("%s" %db, 1) tdSql.query("select 8-1 from stable_1;") for i in range(self.fornum): sql = "select * from ( select ts ," - sql += "%s " % random.choice(self.calc_select_support_ts) + sql += "%s " % random.choice(self.calc_select_support_ts) sql += "from regular_table_1 where " sql += "%s " % random.choice(self.q_where) sql += "%s " % random.choice(self.order_where) sql += "%s " % random.choice(self.limit1_where) sql += ") ;" - tdLog.info(sql) - tdLog.info(len(sql)) - tdSql.query(sql) # 聚合函数不在可以和ts一起使用了 DB error: Not a single-group group function + tdLog.info(sql) + tdLog.info(len(sql)) + tdSql.query(sql) # 聚合函数不在可以和ts一起使用了 DB error: Not a single-group group function self.cur1.execute(sql) tdSql.query("select 8-1 from stable_1;") for i in range(self.fornum): sql = "select * from ( select " - sql += "%s " % random.choice(self.calc_select_not_support_ts) + sql += "%s " % random.choice(self.calc_select_not_support_ts) sql += "from regular_table_1 where " sql += "%s " % random.choice(self.q_where) sql += "%s " % random.choice(self.limit1_where) sql += ") ;" - tdLog.info(sql) - tdLog.info(len(sql)) - #TD-15651 tdSql.query(sql) # 聚合函数不在可以和ts一起使用了 DB error: Not a single-group group function + tdLog.info(sql) + tdLog.info(len(sql)) + #TD-15651 tdSql.query(sql) # 聚合函数不在可以和ts一起使用了 DB error: Not a single-group group function #self.cur1.execute(sql) - + for i in range(self.fornum): sql = "select * from ( select " - sql += "%s " % random.choice(self.calc_select_in_ts) + sql += "%s " % random.choice(self.calc_select_in_ts) sql += "from regular_table_1 where " sql += "%s " % random.choice(self.q_where) #sql += "%s " % random.choice(order_where) sql += "%s " % random.choice(self.limit1_where) sql += ") ;" - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) tdSql.query(sql) self.cur1.execute(sql) tdSql.query("select 8-2 from stable_1;") for i in range(self.fornum): sql = "select * from ( select t1.ts, " - sql += "%s " % random.choice(self.calc_select_in_support_ts_j) + sql += "%s " % random.choice(self.calc_select_in_support_ts_j) sql += "from regular_table_1 t1, regular_table_2 t2 where t1.ts = t2.ts and " sql += "%s " % random.choice(self.q_u_where) sql += "%s " % random.choice(self.order_u_where) sql += "%s " % random.choice(self.limit1_where) sql += ") ;" - tdLog.info(sql) - tdLog.info(len(sql)) - tdSql.query(sql)# 聚合函数不在可以和ts一起使用了 DB error: Not a single-group group function + tdLog.info(sql) + tdLog.info(len(sql)) + tdSql.query(sql)# 聚合函数不在可以和ts一起使用了 DB error: Not a single-group group function self.cur1.execute(sql) for i in range(self.fornum): sql = "select * from ( select " - sql += "%s " % random.choice(self.calc_select_in_not_support_ts_j) + sql += "%s " % random.choice(self.calc_select_in_not_support_ts_j) sql += "from regular_table_1 t1, regular_table_2 t2 where t1.ts = t2.ts and " sql += "%s " % random.choice(self.q_u_where) sql += "%s " % random.choice(self.limit1_where) sql += ") ;" - tdLog.info(sql) - tdLog.info(len(sql)) - #TD-15651 tdSql.query(sql) - ##top返回结果有问题 tdSql.checkRows(1) - #self.cur1.execute(sql) + tdLog.info(sql) + tdLog.info(len(sql)) + #TD-15651 tdSql.query(sql) + ##top返回结果有问题 tdSql.checkRows(1) + #self.cur1.execute(sql) - #9 select * from (select ts,calc form stable where <\>\in\and\or order by ) + #9 select * from (select ts,calc form stable where <\>\in\and\or order by ) # self.dropandcreateDB_random("%s" %db, 1) tdSql.query("select 9-1 from stable_1;") for i in range(self.fornum): sql = "select * from ( select " - sql += "%s " % random.choice(self.calc_select_not_support_ts) + sql += "%s " % random.choice(self.calc_select_not_support_ts) sql += "from stable_1 where " sql += "%s " % random.choice(self.qt_where) sql += "%s " % random.choice(self.limit1_where) sql += ") ;" - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) #TD-15651 tdSql.query(sql) # self.cur1.execute(sql) tdSql.query("select 9-2 from stable_1;") for i in range(self.fornum): sql = "select * from ( select ts ," - sql += "%s " % random.choice(self.calc_select_support_ts) + sql += "%s " % random.choice(self.calc_select_support_ts) sql += "from stable_1 where " sql += "%s " % random.choice(self.qt_where) sql += "%s " % random.choice(self.order_where) sql += "%s " % random.choice(self.limit1_where) sql += ") ;" - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) tdSql.query(sql) self.cur1.execute(sql) - + tdSql.query("select 9-3 from stable_1;") for i in range(self.fornum): sql = "select * from ( select " - sql += "%s " % random.choice(self.calc_select_in_not_support_ts_j) + sql += "%s " % random.choice(self.calc_select_in_not_support_ts_j) sql += "from stable_1 t1, stable_2 t2 where t1.ts = t2.ts and " sql += "%s " % random.choice(self.t_join_where) sql += " and %s " % random.choice(self.qt_u_or_where) sql += "%s " % random.choice(self.limit1_where) sql += ") ;" - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) #TD-15651 tdSql.query(sql) #self.cur1.execute(sql) tdSql.query("select 9-4 from stable_1;") for i in range(self.fornum): sql = "select * from ( select t1.ts," - sql += "%s " % random.choice(self.calc_select_in_support_ts_j) + sql += "%s " % random.choice(self.calc_select_in_support_ts_j) sql += "from stable_1 t1, stable_2 t2 where t1.ts = t2.ts and " sql += "%s " % random.choice(self.t_join_where) sql += " and %s " % random.choice(self.qt_u_or_where) sql += "%s " % random.choice(self.order_u_where) sql += "%s " % random.choice(self.limit1_where) sql += ") ;" - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) tdSql.query(sql) self.cur1.execute(sql) - - #10 select calc from (select * form regualr_table where <\>\in\and\or order by ) + + #10 select calc from (select * form regualr_table where <\>\in\and\or order by ) tdSql.query("select 10-1 from stable_1;") for i in range(self.fornum): - sql = "select " - sql += "%s " % random.choice(self.calc_select_in_ts) + sql = "select " + sql += "%s " % random.choice(self.calc_select_in_ts) sql += "as calc10_1 from ( select * from regular_table_1 where " sql += "%s " % random.choice(self.q_where) sql += "%s " % random.choice(self.order_desc_where) sql += "%s " % random.choice(self.limit1_where) sql += ") ;" - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) tdSql.query(sql) tdSql.checkRows(1) self.cur1.execute(sql) - + #10-1 select calc from (select * form regualr_table where <\>\in\and\or order by ) - # rsDn = self.restartDnodes() + # rsDn = self.restartDnodes() # self.dropandcreateDB_random("%s" %db, 1) # rsDn = self.restartDnodes() tdSql.query("select 10-2 from stable_1;") for i in range(self.fornum): - sql = "select " - sql += "%s " % random.choice(self.calc_select_all) + sql = "select " + sql += "%s " % random.choice(self.calc_select_all) sql += "as calc10_2 from ( select * from regular_table_1 where " sql += "%s " % random.choice(self.q_where) sql += "%s " % random.choice(self.order_desc_where) sql += "%s " % random.choice(self.limit1_where) sql += ") ;" - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) #TD-15651 tdSql.query(sql) # tdSql.checkRows(1) #self.cur1.execute(sql) - #10-2 select calc from (select * form regualr_tables where <\>\in\and\or order by ) + #10-2 select calc from (select * form regualr_tables where <\>\in\and\or order by ) tdSql.query("select 10-3 from stable_1;") for i in range(self.fornum): - sql = "select " - sql += "%s as calc10_3 " % random.choice(self.calc_select_all) + sql = "select " + sql += "%s as calc10_3 " % random.choice(self.calc_select_all) sql += " from ( select * from regular_table_1 t1, regular_table_2 t2 where t1.ts = t2.ts and " sql += "%s " % random.choice(self.q_u_where) sql += " and %s " % random.choice(self.q_u_or_where) @@ -4254,15 +4254,15 @@ class TDTestCase: sql += "%s " % random.choice(self.limit_u_where) sql += ") " sql += "%s ;" % random.choice(self.limit1_where) - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) #TD-15651 tdSql.query(sql) #self.cur1.execute(sql) tdSql.query("select 10-4 from stable_1;") for i in range(self.fornum): - sql = "select " - sql += "%s as calc10_4 " % random.choice(self.calc_select_all) + sql = "select " + sql += "%s as calc10_4 " % random.choice(self.calc_select_all) sql += " from ( select * from regular_table_1 t1, regular_table_2 t2 where t1.ts = t2.ts and " sql += "%s " % random.choice(self.q_u_or_where) sql += " and %s " % random.choice(self.q_u_or_where) @@ -4270,89 +4270,89 @@ class TDTestCase: sql += "%s " % random.choice(self.limit_u_where) sql += ") " sql += "%s ;" % random.choice(self.limit_u_where) - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) #TD-15651 tdSql.query(sql) - # tdSql.checkRows(1) + # tdSql.checkRows(1) #self.cur1.execute(sql) - #11 select calc from (select * form stable where <\>\in\and\or order by limit ) + #11 select calc from (select * form stable where <\>\in\and\or order by limit ) tdSql.query("select 11-1 from stable_1;") for i in range(self.fornum): sql = "select " - sql += "%s " % random.choice(self.calc_select_in_ts) + sql += "%s " % random.choice(self.calc_select_in_ts) sql += "as calc11_1 from ( select * from stable_1 where " sql += "%s " % random.choice(self.qt_where) sql += "%s " % random.choice(self.order_desc_where) sql += "%s " % random.choice(self.limit1_where) sql += ") ;" - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) tdSql.query(sql) tdSql.checkRows(1) self.cur1.execute(sql) - #11-1 select calc from (select * form stable where <\>\in\and\or order by limit ) + #11-1 select calc from (select * form stable where <\>\in\and\or order by limit ) tdSql.query("select 11-2 from stable_1;") for i in range(self.fornum): sql = "select " - sql += "%s " % random.choice(self.calc_select_all) + sql += "%s " % random.choice(self.calc_select_all) sql += "as calc11_1 from ( select * from stable_1 where " sql += "%s " % random.choice(self.qt_where) sql += "%s " % random.choice(self.order_desc_where) sql += "%s " % random.choice(self.limit1_where) sql += ") ;" - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) #TD-15651 tdSql.query(sql) #self.cur1.execute(sql) #不好计算结果 tdSql.checkRows(1) - + #11-2 select calc from (select * form stables where <\>\in\and\or order by limit ) tdSql.query("select 11-3 from stable_1;") for i in range(self.fornum): sql = "select " - sql += "%s " % random.choice(self.calc_select_all) + sql += "%s " % random.choice(self.calc_select_all) sql += "as calc11_1 from ( select * from stable_1 t1, stable_2 t2 where t1.ts = t2.ts and " sql += "%s " % random.choice(self.t_join_where) sql += "%s " % random.choice(self.order_u_where) sql += "%s " % random.choice(self.limit_u_where) sql += ") " sql += "%s ;" % random.choice(self.limit_u_where) - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) #TD-15651 tdSql.query(sql) #self.cur1.execute(sql) tdSql.query("select 11-4 from stable_1;") for i in range(self.fornum): sql = "select " - sql += "%s " % random.choice(self.calc_select_all) + sql += "%s " % random.choice(self.calc_select_all) sql += "as calc11_1 from ( select * from stable_1 t1, stable_2 t2 where t1.ts = t2.ts and " sql += "%s " % random.choice(self.qt_u_or_where) sql += "%s " % random.choice(self.order_u_where) sql += "%s " % random.choice(self.limit_u_where) sql += ") " sql += "%s ;" % random.choice(self.limit_u_where) - tdLog.info(sql) - tdLog.info(len(sql)) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) + tdLog.info(len(sql)) #TD-15651 tdSql.query(sql) #self.cur1.execute(sql) - #12 select calc-diff from (select * form regualr_table where <\>\in\and\or order by limit ) + #12 select calc-diff from (select * form regualr_table where <\>\in\and\or order by limit ) ##self.dropandcreateDB_random("%s" %db, 1) tdSql.query("select 12-1 from stable_1;") for i in range(self.fornum): sql = "select " - sql += "%s " % random.choice(self.calc_calculate_regular) + sql += "%s " % random.choice(self.calc_calculate_regular) sql += " from ( select * from regular_table_1 where " sql += "%s " % random.choice(self.q_where) sql += "%s " % random.choice(self.order_desc_where) sql += "%s " % random.choice([self.limit_where[2] , self.limit_where[3]] ) sql += ") ;" - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) ##目前derivative不支持 tdSql.query(sql) # tdSql.checkRows(1) #self.cur1.execute(sql) @@ -4360,14 +4360,14 @@ class TDTestCase: tdSql.query("select 12-2 from stable_1;") for i in range(self.fornum): sql = "select " - sql += "%s " % random.choice(self.calc_calculate_regular) + sql += "%s " % random.choice(self.calc_calculate_regular) sql += " from ( select * from regular_table_1 t1, regular_table_2 t2 where t1.ts = t2.ts and " sql += "%s " % random.choice(self.q_u_where) sql += "%s " % random.choice(self.order_u_where) sql += "%s " % random.choice([self.limit_where[2] , self.limit_where[3]] ) sql += ") ;" - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) #目前derivative不支持 tdSql.query(sql) # tdSql.checkRows(1) #self.cur1.execute(sql) @@ -4375,14 +4375,14 @@ class TDTestCase: tdSql.query("select 12-2.2 from stable_1;") for i in range(self.fornum): sql = "select " - sql += "%s " % random.choice(self.calc_calculate_regular) + sql += "%s " % random.choice(self.calc_calculate_regular) sql += " from ( select * from regular_table_1 t1, regular_table_2 t2 where t1.ts = t2.ts and " sql += "%s " % random.choice(self.q_u_or_where) sql += "%s " % random.choice(self.order_u_where) sql += "%s " % random.choice([self.limit_where[2] , self.limit_where[3]] ) sql += ") ;" - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) #目前derivative不支持 tdSql.query(sql) #self.cur1.execute(sql) @@ -4391,7 +4391,7 @@ class TDTestCase: self.restartDnodes() for i in range(self.fornum): sql = "select * from ( select " - sql += "%s " % random.choice(self.calc_calculate_regular) + sql += "%s " % random.choice(self.calc_calculate_regular) sql += " from stable_1 where " sql += "%s " % random.choice(self.q_where) sql += "%s " % random.choice(self.group_where) @@ -4399,8 +4399,8 @@ class TDTestCase: sql += "%s " % random.choice(self.order_desc_where) sql += "%s " % random.choice([self.limit_where[2] , self.limit_where[3]] ) sql += " ;" - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) #目前derivative不支持 tdSql.query(sql) #self.cur1.execute(sql) @@ -4408,7 +4408,7 @@ class TDTestCase: #join query does not support group by for i in range(self.fornum): sql = "select * from ( select " - sql += "%s " % random.choice(self.calc_calculate_regular_j) + sql += "%s " % random.choice(self.calc_calculate_regular_j) sql += " from stable_1 t1, stable_2 t2 where t1.ts = t2.ts and " sql += "%s " % random.choice(self.t_join_where) sql += "%s " % random.choice(self.group_where_j) @@ -4416,8 +4416,8 @@ class TDTestCase: #sql += "%s " % random.choice(self.order_desc_where) sql += "%s " % random.choice([self.limit_where[2] , self.limit_where[3]] ) sql += " ;" - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) #tdSql.query(sql) 目前de函数不支持,另外看看需要不需要将group by和pari by分开 #self.cur1.execute(sql) @@ -4425,7 +4425,7 @@ class TDTestCase: #join query does not support group by for i in range(self.fornum): sql = "select * from ( select " - sql += "%s " % random.choice(self.calc_calculate_regular_j) + sql += "%s " % random.choice(self.calc_calculate_regular_j) sql += " from stable_1 t1, stable_2 t2 where t1.ts = t2.ts and " sql += "%s " % random.choice(self.qt_u_or_where) sql += "%s " % random.choice(self.group_where_j) @@ -4433,43 +4433,43 @@ class TDTestCase: sql += "%s " % random.choice(self.order_desc_where) sql += "%s " % random.choice([self.limit_where[2] , self.limit_where[3]] ) sql += " ;" - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) #derivative not support tdSql.query(sql) #self.cur1.execute(sql) - + #13 select calc-diff as diffns from (select * form stable where <\>\in\and\or order by limit ) tdSql.query("select 13-1 from stable_1;") for i in range(self.fornum): sql = "select " - sql += "%s " % random.choice(self.calc_calculate_regular) + sql += "%s " % random.choice(self.calc_calculate_regular) sql += " as calc13_1 from ( select * from stable_1 where " sql += "%s " % random.choice(self.qt_where) sql += "%s " % random.choice(self.orders_desc_where) sql += "%s " % random.choice([self.limit_where[2] , self.limit_where[3]] ) sql += ") ;" - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) #derivative not support tdSql.query(sql) #self.cur1.execute(sql) #14 select * from (select calc_aggregate_alls as agg from stable where <\>\in\and\or group by order by slimit soffset ) - # TD-5955 select * from ( select count (q_double) from stable_1 where t_bool = true or t_bool = false group by loc order by ts asc slimit 1 ) ; + # TD-5955 select * from ( select count (q_double) from stable_1 where t_bool = true or t_bool = false group by loc order by ts asc slimit 1 ) ; tdSql.query("select 14-1 from stable_1;") for i in range(self.fornum): sql = "select * from ( select " - sql += "%s as calc14_1, " % random.choice(self.calc_aggregate_all) - sql += "%s as calc14_2, " % random.choice(self.calc_aggregate_all) - sql += "%s " % random.choice(self.calc_aggregate_all) + sql += "%s as calc14_1, " % random.choice(self.calc_aggregate_all) + sql += "%s as calc14_2, " % random.choice(self.calc_aggregate_all) + sql += "%s " % random.choice(self.calc_aggregate_all) sql += " as calc14_3 from stable_1 where " sql += "%s " % random.choice(self.qt_where) sql += "%s " % random.choice(self.group_where) sql += "%s " % random.choice(self.order_desc_where) sql += "%s " % random.choice(self.slimit1_where) sql += ") ;" - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) #TD-15678 tdSql.query(sql) # tdSql.checkRows(1) #self.cur1.execute(sql) @@ -4478,9 +4478,9 @@ class TDTestCase: tdSql.query("select 14-2 from stable_1;") for i in range(self.fornum): sql = "select * from ( select " - sql += "%s as calc14_1, " % random.choice(self.calc_aggregate_all) - sql += "%s as calc14_2, " % random.choice(self.calc_aggregate_all) - sql += "%s " % random.choice(self.calc_aggregate_all) + sql += "%s as calc14_1, " % random.choice(self.calc_aggregate_all) + sql += "%s as calc14_2, " % random.choice(self.calc_aggregate_all) + sql += "%s " % random.choice(self.calc_aggregate_all) sql += " as calc14_3 from stable_1 where " sql += "%s " % random.choice(self.qt_where) sql += "%s " % random.choice(self.group_where) @@ -4489,44 +4489,44 @@ class TDTestCase: sql += "%s " % random.choice(self.slimit1_where) sql += ") " sql += "%s " % random.choice(self.group_where) - tdLog.info(sql) + tdLog.info(sql) tdLog.info(len(sql)) #TD-15678 tdSql.query(sql) - # tdSql.checkRows(1) + # tdSql.checkRows(1) #self.cur1.execute(sql) #14-2 select * from (select calc_aggregate_all_js as agg from stables where <\>\in\and\or group by order by slimit soffset ) tdSql.query("select 14-3 from stable_1;") for i in range(self.fornum): sql = "select * from ( select " - sql += "%s as calc14_1, " % random.choice(self.calc_aggregate_all_j) - sql += "%s as calc14_2, " % random.choice(self.calc_aggregate_all_j) - sql += "%s " % random.choice(self.calc_aggregate_all_j) + sql += "%s as calc14_1, " % random.choice(self.calc_aggregate_all_j) + sql += "%s as calc14_2, " % random.choice(self.calc_aggregate_all_j) + sql += "%s " % random.choice(self.calc_aggregate_all_j) sql += " as calc14_3 from stable_1 t1, stable_2 t2 where t1.ts = t2.ts and " sql += "%s " % random.choice(self.t_join_where) sql += "%s " % random.choice(self.partiton_where_j) sql += "%s " % random.choice(self.slimit1_where) sql += ") " sql += "%s ;" % random.choice(self.limit_u_where) - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) tdSql.query(sql) self.cur1.execute(sql) tdSql.query("select 14-4 from stable_1;") for i in range(self.fornum): sql = "select * from ( select " - sql += "%s as calc14_1, " % random.choice(self.calc_aggregate_all_j) - sql += "%s as calc14_2, " % random.choice(self.calc_aggregate_all_j) - sql += "%s " % random.choice(self.calc_aggregate_all_j) + sql += "%s as calc14_1, " % random.choice(self.calc_aggregate_all_j) + sql += "%s as calc14_2, " % random.choice(self.calc_aggregate_all_j) + sql += "%s " % random.choice(self.calc_aggregate_all_j) sql += " as calc14_3 from stable_1 t1, stable_2 t2 where t1.ts = t2.ts and " sql += "%s " % random.choice(self.qt_u_or_where) sql += "%s " % random.choice(self.partiton_where_j) sql += "%s " % random.choice(self.slimit1_where) sql += ") " sql += "%s ;" % random.choice(self.limit_u_where) - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) tdSql.query(sql) self.cur1.execute(sql) @@ -4534,50 +4534,50 @@ class TDTestCase: tdSql.query("select 15-1 from stable_1;") for i in range(self.fornum): sql = "select * from ( select " - sql += "%s as calc15_1, " % random.choice(self.calc_aggregate_regular) - sql += "%s as calc15_2, " % random.choice(self.calc_aggregate_regular) - sql += "%s " % random.choice(self.calc_aggregate_regular) + sql += "%s as calc15_1, " % random.choice(self.calc_aggregate_regular) + sql += "%s as calc15_2, " % random.choice(self.calc_aggregate_regular) + sql += "%s " % random.choice(self.calc_aggregate_regular) sql += " as calc15_3 from regular_table_1 where " sql += "%s " % random.choice(self.q_where) - sql += "%s " % random.choice(self.group_where_regular) + sql += "%s " % random.choice(self.group_where_regular) sql += ") ;" - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) #tdSql.query(sql) #Invalid function name: twa' # tdSql.checkRows(1) #self.cur1.execute(sql) - + tdSql.query("select 15-2 from stable_1;") for i in range(self.fornum): sql = "select * from ( select " - sql += "%s as calc15_1, " % random.choice(self.calc_aggregate_regular_j) - sql += "%s as calc15_2, " % random.choice(self.calc_aggregate_regular_j) - sql += "%s " % random.choice(self.calc_aggregate_regular_j) + sql += "%s as calc15_1, " % random.choice(self.calc_aggregate_regular_j) + sql += "%s as calc15_2, " % random.choice(self.calc_aggregate_regular_j) + sql += "%s " % random.choice(self.calc_aggregate_regular_j) sql += " as calc15_3 from regular_table_1 t1, regular_table_2 t2 where t1.ts = t2.ts and " sql += "%s " % random.choice(self.q_u_where) - sql += "%s " % random.choice(self.group_where_regular_j) + sql += "%s " % random.choice(self.group_where_regular_j) sql += "%s " % random.choice(self.limit_u_where) sql += ") " sql += "%s ;" % random.choice(self.limit_u_where) - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) #tdSql.query(sql) #Invalid function name: twa' #self.cur1.execute(sql) tdSql.query("select 15-2.2 from stable_1;") for i in range(self.fornum): sql = "select * from ( select " - sql += "%s as calc15_1, " % random.choice(self.calc_aggregate_regular_j) - sql += "%s as calc15_2, " % random.choice(self.calc_aggregate_regular_j) - sql += "%s " % random.choice(self.calc_aggregate_regular_j) + sql += "%s as calc15_1, " % random.choice(self.calc_aggregate_regular_j) + sql += "%s as calc15_2, " % random.choice(self.calc_aggregate_regular_j) + sql += "%s " % random.choice(self.calc_aggregate_regular_j) sql += " as calc15_3 from regular_table_1 t1, regular_table_2 t2 where t1.ts = t2.ts and " sql += "%s " % random.choice(self.q_u_or_where) - sql += "%s " % random.choice(self.group_where_regular_j) + sql += "%s " % random.choice(self.group_where_regular_j) sql += "%s " % random.choice(self.limit_u_where) sql += ") " sql += "%s ;" % random.choice(self.limit_u_where) - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) #tdSql.query(sql) #Invalid function name: twa' #self.cur1.execute(sql) @@ -4585,222 +4585,222 @@ class TDTestCase: tdSql.query("select 15-3 from stable_1;") for i in range(self.fornum): sql = "select * from ( select " - sql += "%s as calc15_1, " % random.choice(self.calc_aggregate_groupbytbname) - sql += "%s as calc15_2, " % random.choice(self.calc_aggregate_groupbytbname) - sql += "%s " % random.choice(self.calc_aggregate_groupbytbname) + sql += "%s as calc15_1, " % random.choice(self.calc_aggregate_groupbytbname) + sql += "%s as calc15_2, " % random.choice(self.calc_aggregate_groupbytbname) + sql += "%s " % random.choice(self.calc_aggregate_groupbytbname) sql += " as calc15_3 from stable_1 where " sql += "%s " % random.choice(self.q_where) sql += "%s " % random.choice(self.group_where) sql += "%s " % random.choice(self.having_support) sql += "%s " % random.choice(self.order_desc_where) sql += ") " - sql += "order by calc15_1 " + sql += "order by calc15_1 " sql += "%s " % random.choice(self.limit_where) - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) #tdSql.query(sql) #Invalid function name: twa',可能还的去掉order by #self.cur1.execute(sql) tdSql.query("select 15-4 from stable_1;") for i in range(self.fornum): sql = "select * from ( select " - sql += "%s as calc15_1, " % random.choice(self.calc_aggregate_groupbytbname_j) - sql += "%s as calc15_2, " % random.choice(self.calc_aggregate_groupbytbname_j) - sql += "%s " % random.choice(self.calc_aggregate_groupbytbname_j) + sql += "%s as calc15_1, " % random.choice(self.calc_aggregate_groupbytbname_j) + sql += "%s as calc15_2, " % random.choice(self.calc_aggregate_groupbytbname_j) + sql += "%s " % random.choice(self.calc_aggregate_groupbytbname_j) sql += " as calc15_3 from stable_1 t1, stable_2 t2 where t1.ts = t2.ts and " sql += "%s " % random.choice(self.t_join_where) sql += "%s " % random.choice(self.group_where_j) sql += "%s " % random.choice(self.having_support_j) #sql += "%s " % random.choice(orders_desc_where) sql += ") " - sql += "order by calc15_1 " + sql += "order by calc15_1 " sql += "%s " % random.choice(self.limit_u_where) - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) #tdSql.query(sql) #'Invalid function name: irate' #self.cur1.execute(sql) tdSql.query("select 15-4.2 from stable_1;") for i in range(self.fornum): sql = "select * from ( select " - sql += "%s as calc15_1, " % random.choice(self.calc_aggregate_groupbytbname_j) - sql += "%s as calc15_2, " % random.choice(self.calc_aggregate_groupbytbname_j) - sql += "%s " % random.choice(self.calc_aggregate_groupbytbname_j) + sql += "%s as calc15_1, " % random.choice(self.calc_aggregate_groupbytbname_j) + sql += "%s as calc15_2, " % random.choice(self.calc_aggregate_groupbytbname_j) + sql += "%s " % random.choice(self.calc_aggregate_groupbytbname_j) sql += " as calc15_3 from stable_1 t1, stable_2 t2 where t1.ts = t2.ts and " sql += "%s " % random.choice(self.qt_u_or_where) sql += "%s " % random.choice(self.group_where_j) sql += "%s " % random.choice(self.having_support_j) sql += "%s " % random.choice(self.orders_desc_where) sql += ") " - sql += "order by calc15_1 " + sql += "order by calc15_1 " sql += "%s " % random.choice(self.limit_u_where) - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) #TD-15678 #tdSql.query(sql) #self.cur1.execute(sql) tdSql.query("select 15-5 from stable_1;") for i in range(self.fornum): sql = "select * from ( select " - sql += "%s as calc15_1, " % random.choice(self.calc_aggregate_groupbytbname) - sql += "%s as calc15_2, " % random.choice(self.calc_aggregate_groupbytbname) - sql += "%s " % random.choice(self.calc_aggregate_groupbytbname) + sql += "%s as calc15_1, " % random.choice(self.calc_aggregate_groupbytbname) + sql += "%s as calc15_2, " % random.choice(self.calc_aggregate_groupbytbname) + sql += "%s " % random.choice(self.calc_aggregate_groupbytbname) sql += " as calc15_3 from stable_1 where " sql += "%s " % random.choice(self.q_where) sql += "%s " % random.choice(self.group_where) sql += ") " - sql += "order by calc15_1 " + sql += "order by calc15_1 " sql += "%s " % random.choice(self.limit_where) - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) #tdSql.query(sql) #'Invalid function name: irate' #self.cur1.execute(sql) - #16 select * from (select calc_aggregate_regulars as agg from regular_table where <\>\in\and\or order by limit offset ) + #16 select * from (select calc_aggregate_regulars as agg from regular_table where <\>\in\and\or order by limit offset ) #self.dropandcreateDB_random("%s" %db, 1) tdSql.query("select 16-1 from stable_1;") for i in range(self.fornum): - sql = "select * from ( select " + sql = "select * from ( select " sql += "%s as calc16_0 , " % random.choice(self.calc_calculate_all) - sql += "%s as calc16_1 , " % random.choice(self.calc_aggregate_all) - sql += "%s as calc16_2 " % random.choice(self.calc_select_in) + sql += "%s as calc16_1 , " % random.choice(self.calc_aggregate_all) + sql += "%s as calc16_2 " % random.choice(self.calc_select_in) sql += " from stable_1 where " sql += "%s " % random.choice(self.q_where) sql += "%s " % random.choice(self.group_where) #sql += "%s " % random.choice(having_support)having和 partition不能混合使用 sql += ") " - sql += "order by calc16_0 " + sql += "order by calc16_0 " sql += "%s " % random.choice(self.limit1_where) - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) #TD-15651 tdSql.query(sql) #self.cur1.execute(sql) tdSql.query("select 16-2 from stable_1;") for i in range(self.fornum): - sql = "select * from ( select " + sql = "select * from ( select " sql += "%s as calc16_0 " % random.choice(self.calc_calculate_all_j) - sql += ", %s as calc16_1 " % random.choice(self.calc_aggregate_all_j) - #sql += ", %s as calc16_2 " % random.choice(self.calc_select_in_j) + sql += ", %s as calc16_1 " % random.choice(self.calc_aggregate_all_j) + #sql += ", %s as calc16_2 " % random.choice(self.calc_select_in_j) sql += " from stable_1 t1, stable_2 t2 where t1.ts = t2.ts and " sql += "%s " % random.choice(self.t_join_where) sql += ") " - sql += "order by calc16_0 " + sql += "order by calc16_0 " sql += "%s " % random.choice(self.limit1_where) - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) tdSql.query(sql) self.cur1.execute(sql) tdSql.query("select 16-2.2 from stable_1;") for i in range(self.fornum): - sql = "select * from ( select " + sql = "select * from ( select " sql += "%s as calc16_0 " % random.choice(self.calc_calculate_all_j) - sql += ", %s as calc16_1 " % random.choice(self.calc_aggregate_all_j) + sql += ", %s as calc16_1 " % random.choice(self.calc_aggregate_all_j) sql += " from stable_1 t1, stable_2 t2 where t1.ts = t2.ts and " sql += "%s " % random.choice(self.qt_u_or_where) sql += ") " - sql += "order by calc16_0 " + sql += "order by calc16_0 " sql += "%s " % random.choice(self.limit1_where) - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) tdSql.query(sql) self.cur1.execute(sql) - + tdSql.query("select 16-3 from stable_1;") for i in range(self.fornum): - sql = "select * from ( select " - sql += "%s as calc16_1 " % random.choice(self.calc_calculate_regular) + sql = "select * from ( select " + sql += "%s as calc16_1 " % random.choice(self.calc_calculate_regular) sql += " from regular_table_1 where " sql += "%s " % random.choice(self.q_where) sql += "limit 2 ) " sql += "%s " % random.choice(self.limit1_where) - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) #tdSql.query(sql)#Invalid function name: derivative' #self.cur1.execute(sql) tdSql.query("select 16-4 from stable_1;") for i in range(self.fornum): - sql = "select * from ( select " - sql += "%s as calc16_1 " % random.choice(self.calc_calculate_regular_j) + sql = "select * from ( select " + sql += "%s as calc16_1 " % random.choice(self.calc_calculate_regular_j) sql += " from regular_table_1 t1, regular_table_2 t2 where t1.ts = t2.ts and " sql += "%s " % random.choice(self.q_u_where) sql += "limit 2 ) " sql += "%s " % random.choice(self.limit1_where) - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) #tdSql.query(sql)#Invalid function name: derivative' #self.cur1.execute(sql) tdSql.query("select 16-4.2 from stable_1;") for i in range(self.fornum): - sql = "select * from ( select " - sql += "%s as calc16_1 " % random.choice(self.calc_calculate_regular_j) + sql = "select * from ( select " + sql += "%s as calc16_1 " % random.choice(self.calc_calculate_regular_j) sql += " from regular_table_1 t1, regular_table_2 t2 where t1.ts = t2.ts and " sql += "%s " % random.choice(self.q_u_or_where) sql += "limit 2 ) " sql += "%s " % random.choice(self.limit1_where) - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) #tdSql.query(sql)#Invalid function name: derivative' #self.cur1.execute(sql) - + tdSql.query("select 16-5 from stable_1;") for i in range(self.fornum): - sql = "select * from ( select " + sql = "select * from ( select " sql += "%s as calc16_1 , " % random.choice(self.calc_calculate_all) - sql += "%s as calc16_1 , " % random.choice(self.calc_calculate_regular) - sql += "%s as calc16_2 " % random.choice(self.calc_select_all) + sql += "%s as calc16_1 , " % random.choice(self.calc_calculate_regular) + sql += "%s as calc16_2 " % random.choice(self.calc_select_all) sql += " from stable_1 where " sql += "%s " % random.choice(self.q_where) sql += "%s " % random.choice(self.group_where) #sql += "%s " % random.choice(having_support) sql += ") " - sql += "order by calc16_1 " + sql += "order by calc16_1 " sql += "%s " % random.choice(self.limit1_where) - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) # tdSql.query(sql) #self.cur1.execute(sql) - + tdSql.query("select 16-6 from stable_1;") for i in range(self.fornum): - sql = "select * from ( select " - sql += "%s as calc16_1 " % random.choice(self.calc_calculate_groupbytbname) + sql = "select * from ( select " + sql += "%s as calc16_1 " % random.choice(self.calc_calculate_groupbytbname) sql += " from stable_1 where " sql += "%s " % random.choice(self.q_where) sql += "%s " % random.choice(self.group_where) sql += "limit 2 ) " sql += "%s " % random.choice(self.limit1_where) - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) #Invalid function name: derivative' tdSql.query(sql) #self.cur1.execute(sql) tdSql.query("select 16-7 from stable_1;") for i in range(self.fornum): - sql = "select * from ( select " - sql += "%s as calc16_1 " % random.choice(self.calc_calculate_groupbytbname_j) + sql = "select * from ( select " + sql += "%s as calc16_1 " % random.choice(self.calc_calculate_groupbytbname_j) sql += " from stable_1 t1, stable_2 t2 where t1.ts = t2.ts and " sql += "%s " % random.choice(self.t_join_where) sql += "limit 2 ) " sql += "%s " % random.choice(self.limit1_where) - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) #Invalid function name: derivative' tdSql.query(sql) #self.cur1.execute(sql) tdSql.query("select 16-8 from stable_1;") for i in range(self.fornum): - sql = "select * from ( select " - sql += "%s as calc16_1 " % random.choice(self.calc_calculate_groupbytbname_j) + sql = "select * from ( select " + sql += "%s as calc16_1 " % random.choice(self.calc_calculate_groupbytbname_j) sql += " from stable_1 t1, stable_2 t2 where t1.ts = t2.ts and " sql += "%s " % random.choice(self.qt_u_or_where) sql += "limit 2 ) " sql += "%s " % random.choice(self.limit1_where) - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) #Invalid function name: derivative' tdSql.query(sql) #self.cur1.execute(sql) @@ -4808,11 +4808,11 @@ class TDTestCase: #self.dropandcreateDB_random("%s" %db, 1) tdSql.query("select 17-1 from stable_1;") for i in range(self.fornum): - #this is having_support , but tag-select cannot mix with last_row,other select can + #this is having_support , but tag-select cannot mix with last_row,other select can sql = "select apercentile(cal17_0, %d)/10 ,apercentile(cal17_1, %d)/1000 ,apercentile(cal17_2, %d)*10+%d from ( select " %(random.randint(0,100) , random.randint(0,100) , random.randint(0,100) ,random.randint(-1000,1000)) sql += "%s as cal17_0 , " % random.choice(self.calc_calculate_all) - sql += "%s as cal17_1 ," % random.choice(self.calc_aggregate_all) - sql += "%s as cal17_2 " % random.choice(self.calc_aggregate_all) + sql += "%s as cal17_1 ," % random.choice(self.calc_aggregate_all) + sql += "%s as cal17_2 " % random.choice(self.calc_aggregate_all) sql += " from stable_1 where " sql += "%s " % random.choice(self.qt_where) sql += "%s " % random.choice(self.partiton_where) @@ -4822,36 +4822,36 @@ class TDTestCase: sql += "%s " % random.choice(self.limit1_where) sql += ") " #sql += "%s " % random.choice(interval_sliding) - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) tdSql.query(sql) self.cur1.execute(sql) - + tdSql.query("select 17-2 from stable_1;") for i in range(self.fornum): - #this is having_support , but tag-select cannot mix with last_row,other select can + #this is having_support , but tag-select cannot mix with last_row,other select can sql = "select apercentile(cal17_0, %d)/10 ,apercentile(cal17_1, %d)/1000 ,apercentile(cal17_2, %d)*10+%d from ( select " %(random.randint(0,100) , random.randint(0,100) , random.randint(0,100) ,random.randint(-1000,1000)) sql += "%s as cal17_0 , " % random.choice(self.calc_calculate_all_j) - sql += "%s as cal17_1 ," % random.choice(self.calc_aggregate_all_j) - sql += "%s as cal17_2 " % random.choice(self.calc_aggregate_all_j) + sql += "%s as cal17_1 ," % random.choice(self.calc_aggregate_all_j) + sql += "%s as cal17_2 " % random.choice(self.calc_aggregate_all_j) sql += " from stable_1 t1, stable_2 t2 where t1.ts = t2.ts and " sql += "%s " % random.choice(self.t_join_where) sql += "%s " % random.choice(self.interval_sliding) sql += "%s " % random.choice(self.limit_u_where) sql += ") " #sql += "%s " % random.choice(interval_sliding) - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) tdSql.query(sql) self.cur1.execute(sql) tdSql.query("select 17-2.2 from stable_1;") for i in range(self.fornum): - #this is having_support , but tag-select cannot mix with last_row,other select can + #this is having_support , but tag-select cannot mix with last_row,other select can sql = "select apercentile(cal17_0, %d)/10 ,apercentile(cal17_1, %d)/1000 ,apercentile(cal17_2, %d)*10+%d from ( select " %(random.randint(0,100) , random.randint(0,100) , random.randint(0,100) ,random.randint(-1000,1000)) sql += "%s as cal17_0 , " % random.choice(self.calc_calculate_all_j) - sql += "%s as cal17_1 ," % random.choice(self.calc_aggregate_all_j) - sql += "%s as cal17_2 " % random.choice(self.calc_aggregate_all_j) + sql += "%s as cal17_1 ," % random.choice(self.calc_aggregate_all_j) + sql += "%s as cal17_2 " % random.choice(self.calc_aggregate_all_j) sql += " from stable_1 t1, stable_2 t2 where t1.ts = t2.ts and " sql += "%s " % random.choice(self.qt_u_or_where) sql += "%s " % random.choice(self.interval_sliding) @@ -4859,8 +4859,8 @@ class TDTestCase: sql += "%s " % random.choice(self.limit_u_where) sql += ") " #sql += "%s " % random.choice(self.interval_sliding) - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) tdSql.query(sql) self.cur1.execute(sql) @@ -4869,8 +4869,8 @@ class TDTestCase: for i in range(self.fornum): #this is having_tagnot_support , because tag-select cannot mix with last_row... sql = "select apercentile(cal17_1, %d)/1000 ,apercentile(cal17_2, %d)*10+%d from ( select " %(random.randint(0,100) , random.randint(0,100) ,random.randint(-1000,1000)) - sql += "%s as cal17_1 ," % random.choice(self.calc_aggregate_all) - sql += "%s as cal17_2 " % random.choice(self.calc_aggregate_all) + sql += "%s as cal17_1 ," % random.choice(self.calc_aggregate_all) + sql += "%s as cal17_2 " % random.choice(self.calc_aggregate_all) sql += " from stable_1 where " sql += "%s " % random.choice(self.q_where) sql += "%s " % random.choice(self.partiton_where) @@ -4880,8 +4880,8 @@ class TDTestCase: sql += "%s " % random.choice(self.limit1_where) sql += ") " #sql += "%s " % random.choice(self.interval_sliding) - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) tdSql.query(sql) self.cur1.execute(sql) @@ -4889,8 +4889,8 @@ class TDTestCase: for i in range(self.fornum): #this is having_tagnot_support , because tag-select cannot mix with last_row... sql = "select apercentile(cal17_1, %d)/1000 ,apercentile(cal17_2, %d)*10+%d from ( select " %(random.randint(0,100) , random.randint(0,100) ,random.randint(-1000,1000)) - sql += "%s as cal17_1 ," % random.choice(self.calc_aggregate_all_j) - sql += "%s as cal17_2 " % random.choice(self.calc_aggregate_all_j) + sql += "%s as cal17_1 ," % random.choice(self.calc_aggregate_all_j) + sql += "%s as cal17_2 " % random.choice(self.calc_aggregate_all_j) sql += " from stable_1 t1, stable_2 t2 where t1.ts = t2.ts and " sql += "%s " % random.choice(self.t_join_where) sql += "%s " % random.choice(self.interval_sliding) @@ -4898,8 +4898,8 @@ class TDTestCase: sql += "%s " % random.choice(self.limit_u_where) sql += ") " #sql += "%s " % random.choice(interval_sliding) - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) tdSql.query(sql) self.cur1.execute(sql) @@ -4907,8 +4907,8 @@ class TDTestCase: for i in range(self.fornum): #this is having_tagnot_support , because tag-select cannot mix with last_row... sql = "select apercentile(cal17_1, %d)/1000 ,apercentile(cal17_2, %d)*10+%d from ( select " %(random.randint(0,100) , random.randint(0,100) ,random.randint(-1000,1000)) - sql += "%s as cal17_1 ," % random.choice(self.calc_aggregate_all_j) - sql += "%s as cal17_2 " % random.choice(self.calc_aggregate_all_j) + sql += "%s as cal17_1 ," % random.choice(self.calc_aggregate_all_j) + sql += "%s as cal17_2 " % random.choice(self.calc_aggregate_all_j) sql += " from stable_1 t1, stable_2 t2 where t1.ts = t2.ts and " sql += "%s " % random.choice(self.qt_u_or_where) sql += "%s " % random.choice(self.interval_sliding) @@ -4916,17 +4916,17 @@ class TDTestCase: sql += "%s " % random.choice(self.limit_u_where) sql += ") " #sql += "%s " % random.choice(self.interval_sliding) - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) tdSql.query(sql) self.cur1.execute(sql) tdSql.query("select 17-5 from stable_1;") for i in range(self.fornum): - #having_not_support + #having_not_support sql = "select apercentile(cal17_1, %d)/1000 ,apercentile(cal17_2, %d)*10+%d from ( select " %(random.randint(0,100) , random.randint(0,100) ,random.randint(-1000,1000)) - sql += "%s as cal17_1 ," % random.choice(self.calc_aggregate_all) - sql += "%s as cal17_2 " % random.choice(self.calc_aggregate_all) + sql += "%s as cal17_1 ," % random.choice(self.calc_aggregate_all) + sql += "%s as cal17_2 " % random.choice(self.calc_aggregate_all) sql += " from stable_1 where " sql += "%s " % random.choice(self.qt_where) sql += "%s " % random.choice(self.partiton_where) @@ -4936,16 +4936,16 @@ class TDTestCase: sql += "%s " % random.choice(self.limit1_where) sql += ") " #sql += "%s " % random.choice(self.interval_sliding) - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) tdSql.query(sql) self.cur1.execute(sql) - + tdSql.query("select 17-6 from stable_1;") for i in range(self.fornum): sql = "select apercentile(cal17_1, %d)/1000 ,apercentile(cal17_2, %d)*10+%d from ( select " %(random.randint(0,100) , random.randint(0,100) ,random.randint(-1000,1000)) - sql += "%s as cal17_1 ," % random.choice(self.calc_aggregate_all) - sql += "%s as cal17_2 " % random.choice(self.calc_aggregate_all) + sql += "%s as cal17_1 ," % random.choice(self.calc_aggregate_all) + sql += "%s as cal17_2 " % random.choice(self.calc_aggregate_all) sql += " from stable_1 where " sql += "%s " % random.choice(self.q_where) sql += "%s " % random.choice(self.interval_sliding) @@ -4953,16 +4953,16 @@ class TDTestCase: sql += "%s " % random.choice(self.limit1_where) sql += ") " #sql += "%s " % random.choice(interval_sliding) - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) tdSql.query(sql) self.cur1.execute(sql) tdSql.query("select 17-7 from stable_1;") for i in range(self.fornum): sql = "select apercentile(cal17_1, %d)/1000 ,apercentile(cal17_2, %d)*10+%d from ( select " %(random.randint(0,100) , random.randint(0,100) ,random.randint(-1000,1000)) - sql += "%s as cal17_1 ," % random.choice(self.calc_aggregate_all_j) - sql += "%s as cal17_2 " % random.choice(self.calc_aggregate_all_j) + sql += "%s as cal17_1 ," % random.choice(self.calc_aggregate_all_j) + sql += "%s as cal17_2 " % random.choice(self.calc_aggregate_all_j) sql += " from stable_1_1 t1, stable_1_2 t2 where t1.ts = t2.ts and " sql += "%s " % random.choice(self.q_u_where) sql += "%s " % random.choice(self.interval_sliding) @@ -4970,16 +4970,16 @@ class TDTestCase: sql += "%s " % random.choice(self.limit1_where) sql += ") " #sql += "%s " % random.choice(interval_sliding) - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) tdSql.query(sql) self.cur1.execute(sql) tdSql.query("select 17-7.2 from stable_1;") for i in range(self.fornum): sql = "select apercentile(cal17_1, %d)/1000 ,apercentile(cal17_2, %d)*10+%d from ( select " %(random.randint(0,100) , random.randint(0,100) ,random.randint(-1000,1000)) - sql += "%s as cal17_1 ," % random.choice(self.calc_aggregate_all_j) - sql += "%s as cal17_2 " % random.choice(self.calc_aggregate_all_j) + sql += "%s as cal17_1 ," % random.choice(self.calc_aggregate_all_j) + sql += "%s as cal17_2 " % random.choice(self.calc_aggregate_all_j) sql += " from stable_1_1 t1, stable_1_2 t2 where t1.ts = t2.ts and " sql += "%s " % random.choice(self.q_u_or_where) sql += "%s " % random.choice(self.interval_sliding) @@ -4987,8 +4987,8 @@ class TDTestCase: sql += "%s " % random.choice(self.limit1_where) sql += ") " #sql += "%s " % random.choice(interval_sliding) - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) tdSql.query(sql) self.cur1.execute(sql) @@ -4996,8 +4996,8 @@ class TDTestCase: tdSql.query("select 17-8 from stable_1;") for i in range(self.fornum): sql = "select apercentile(cal17_1, %d)/1000 ,apercentile(cal17_2, %d)*10+%d from ( select " %(random.randint(0,100) , random.randint(0,100) ,random.randint(-1000,1000)) - sql += "%s as cal17_1 ," % random.choice(self.calc_aggregate_all) - sql += "%s as cal17_2 " % random.choice(self.calc_aggregate_all) + sql += "%s as cal17_1 ," % random.choice(self.calc_aggregate_all) + sql += "%s as cal17_2 " % random.choice(self.calc_aggregate_all) sql += " from regular_table_1 where " sql += "%s " % random.choice(self.q_where) sql += "%s " % random.choice(self.interval_sliding) @@ -5005,16 +5005,16 @@ class TDTestCase: sql += "%s " % random.choice(self.limit1_where) sql += ") " #sql += "%s " % random.choice(interval_sliding) - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) tdSql.query(sql) self.cur1.execute(sql) - + tdSql.query("select 17-9 from stable_1;") for i in range(self.fornum): sql = "select apercentile(cal17_1, %d)/1000 ,apercentile(cal17_2, %d)*10+%d from ( select " %(random.randint(0,100) , random.randint(0,100) ,random.randint(-1000,1000)) - sql += "%s as cal17_1 ," % random.choice(self.calc_aggregate_all_j) - sql += "%s as cal17_2 " % random.choice(self.calc_aggregate_all_j) + sql += "%s as cal17_1 ," % random.choice(self.calc_aggregate_all_j) + sql += "%s as cal17_2 " % random.choice(self.calc_aggregate_all_j) sql += " from regular_table_1 t1, regular_table_2 t2 where t1.ts = t2.ts and " sql += "%s " % random.choice(self.q_u_where) sql += "%s " % random.choice(self.interval_sliding) @@ -5022,16 +5022,16 @@ class TDTestCase: sql += "%s " % random.choice(self.limit_u_where) sql += ") " #sql += "%s " % random.choice(interval_sliding) - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) tdSql.query(sql) self.cur1.execute(sql) tdSql.query("select 17-10 from stable_1;") for i in range(self.fornum): sql = "select apercentile(cal17_1, %d)/1000 ,apercentile(cal17_2, %d)*10+%d from ( select " %(random.randint(0,100) , random.randint(0,100) ,random.randint(-1000,1000)) - sql += "%s as cal17_1 ," % random.choice(self.calc_aggregate_all_j) - sql += "%s as cal17_2 " % random.choice(self.calc_aggregate_all_j) + sql += "%s as cal17_1 ," % random.choice(self.calc_aggregate_all_j) + sql += "%s as cal17_2 " % random.choice(self.calc_aggregate_all_j) sql += " from regular_table_1 t1, regular_table_2 t2 where t1.ts = t2.ts and " sql += "%s " % random.choice(self.q_u_or_where) sql += "%s " % random.choice(self.interval_sliding) @@ -5039,8 +5039,8 @@ class TDTestCase: sql += "%s " % random.choice(self.limit_u_where) sql += ") " #sql += "%s " % random.choice(interval_sliding) - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) tdSql.query(sql) self.cur1.execute(sql) @@ -5048,8 +5048,8 @@ class TDTestCase: tdSql.query("select 18-1 from stable_1;") for i in range(self.fornum): sql = "select apercentile(cal18_1, %d)/1000 ,apercentile(cal18_2, %d)*10+%d from ( select " %(random.randint(0,100) , random.randint(0,100) ,random.randint(-1000,1000)) - sql += "%s as cal18_1 ," % random.choice(self.calc_aggregate_all) - sql += "%s as cal18_2 " % random.choice(self.calc_aggregate_all) + sql += "%s as cal18_1 ," % random.choice(self.calc_aggregate_all) + sql += "%s as cal18_2 " % random.choice(self.calc_aggregate_all) sql += " from regular_table_1 where " sql += "%s " % random.choice(self.q_where) sql += "%s " % random.choice(self.session_where) @@ -5058,16 +5058,16 @@ class TDTestCase: sql += "%s " % random.choice(self.limit1_where) sql += ") " #sql += "%s " % random.choice(interval_sliding) - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) tdSql.query(sql) self.cur1.execute(sql) - + tdSql.query("select 18-2 from stable_1;") for i in range(self.fornum): sql = "select apercentile(cal18_1, %d)/1000 ,apercentile(cal18_2, %d)*10+%d from ( select " %(random.randint(0,100) , random.randint(0,100) ,random.randint(-1000,1000)) - sql += "%s as cal18_1 ," % random.choice(self.calc_aggregate_all_j) - sql += "%s as cal18_2 " % random.choice(self.calc_aggregate_all_j) + sql += "%s as cal18_1 ," % random.choice(self.calc_aggregate_all_j) + sql += "%s as cal18_2 " % random.choice(self.calc_aggregate_all_j) sql += " from regular_table_1 t1, regular_table_2 t2 where t1.ts = t2.ts and " sql += "%s " % random.choice(self.q_u_where) sql += "%s " % random.choice(self.session_u_where) @@ -5075,16 +5075,16 @@ class TDTestCase: sql += "%s " % random.choice(self.limit_u_where) sql += ") " #sql += "%s " % random.choice(interval_sliding) - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) tdSql.query(sql) self.cur1.execute(sql) tdSql.query("select 18-2.2 from stable_1;") for i in range(self.fornum): sql = "select apercentile(cal18_1, %d)/1000 ,apercentile(cal18_2, %d)*10+%d from ( select " %(random.randint(0,100) , random.randint(0,100) ,random.randint(-1000,1000)) - sql += "%s as cal18_1 ," % random.choice(self.calc_aggregate_all_j) - sql += "%s as cal18_2 " % random.choice(self.calc_aggregate_all_j) + sql += "%s as cal18_1 ," % random.choice(self.calc_aggregate_all_j) + sql += "%s as cal18_2 " % random.choice(self.calc_aggregate_all_j) sql += " from regular_table_1 t1, regular_table_2 t2 where t1.ts = t2.ts and " sql += "%s " % random.choice(self.q_u_or_where) sql += "%s " % random.choice(self.session_u_where) @@ -5092,8 +5092,8 @@ class TDTestCase: sql += "%s " % random.choice(self.limit_u_where) sql += ") " #sql += "%s " % random.choice(self.interval_sliding) - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) tdSql.query(sql) self.cur1.execute(sql) @@ -5101,8 +5101,8 @@ class TDTestCase: tdSql.query("select 18-3 from stable_1;") for i in range(self.fornum): sql = "select apercentile(cal18_1, %d)/1000 ,apercentile(cal18_2, %d)*10+%d from ( select " %(random.randint(0,100) , random.randint(0,100) ,random.randint(-1000,1000)) - sql += "%s as cal18_1 ," % random.choice(self.calc_aggregate_all) - sql += "%s as cal18_2 " % random.choice(self.calc_aggregate_all) + sql += "%s as cal18_1 ," % random.choice(self.calc_aggregate_all) + sql += "%s as cal18_2 " % random.choice(self.calc_aggregate_all) sql += " from stable_1_1 where " sql += "%s " % random.choice(self.q_where) sql += "%s " % random.choice(self.session_where) @@ -5111,16 +5111,16 @@ class TDTestCase: sql += "%s " % random.choice(self.limit1_where) sql += ") " #sql += "%s " % random.choice(self.interval_sliding) - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) tdSql.query(sql) self.cur1.execute(sql) tdSql.query("select 18-4 from stable_1;") for i in range(self.fornum): sql = "select apercentile(cal18_1, %d)/1000 ,apercentile(cal18_2, %d)*10+%d from ( select " %(random.randint(0,100) , random.randint(0,100) ,random.randint(-1000,1000)) - sql += "%s as cal18_1 ," % random.choice(self.calc_aggregate_all_j) - sql += "%s as cal18_2 " % random.choice(self.calc_aggregate_all_j) + sql += "%s as cal18_1 ," % random.choice(self.calc_aggregate_all_j) + sql += "%s as cal18_2 " % random.choice(self.calc_aggregate_all_j) sql += " from stable_1_1 t1, regular_table_2 t2 where t1.ts = t2.ts and " sql += "%s " % random.choice(self.q_u_where) sql += "%s " % random.choice(self.session_u_where) @@ -5128,16 +5128,16 @@ class TDTestCase: sql += "%s " % random.choice(self.limit_u_where) sql += ") " #sql += "%s " % random.choice(self.interval_sliding) - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) tdSql.query(sql) self.cur1.execute(sql) tdSql.query("select 18-4.2 from stable_1;") for i in range(self.fornum): sql = "select apercentile(cal18_1, %d)/1000 ,apercentile(cal18_2, %d)*10+%d from ( select " %(random.randint(0,100) , random.randint(0,100) ,random.randint(-1000,1000)) - sql += "%s as cal18_1 ," % random.choice(self.calc_aggregate_all_j) - sql += "%s as cal18_2 " % random.choice(self.calc_aggregate_all_j) + sql += "%s as cal18_1 ," % random.choice(self.calc_aggregate_all_j) + sql += "%s as cal18_2 " % random.choice(self.calc_aggregate_all_j) sql += " from stable_1_1 t1, regular_table_2 t2 where t1.ts = t2.ts and " sql += "%s " % random.choice(self.q_u_or_where) sql += "%s " % random.choice(self.session_u_where) @@ -5145,16 +5145,16 @@ class TDTestCase: sql += "%s " % random.choice(self.limit_u_where) sql += ") " #sql += "%s " % random.choice(self.interval_sliding) - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) tdSql.query(sql) self.cur1.execute(sql) tdSql.query("select 18-5 from stable_1;") for i in range(self.fornum): sql = "select apercentile(cal18_1, %d)/1000 ,apercentile(cal18_2, %d)*10+%d from ( select " %(random.randint(0,100) , random.randint(0,100) ,random.randint(-1000,1000)) - sql += "%s as cal18_1 ," % random.choice(self.calc_aggregate_all) - sql += "%s as cal18_2 " % random.choice(self.calc_aggregate_all) + sql += "%s as cal18_1 ," % random.choice(self.calc_aggregate_all) + sql += "%s as cal18_2 " % random.choice(self.calc_aggregate_all) sql += " from stable_1 where " sql += "%s " % random.choice(self.q_where) sql += "%s " % random.choice(self.session_where) @@ -5163,16 +5163,16 @@ class TDTestCase: sql += "%s " % random.choice(self.limit1_where) sql += ") " #sql += "%s " % random.choice(interval_sliding) - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) tdSql.query(sql) self.cur1.execute(sql) tdSql.query("select 18-6 from stable_1;") for i in range(self.fornum): sql = "select apercentile(cal18_1, %d)/1000 ,apercentile(cal18_2, %d)*10+%d from ( select " %(random.randint(0,100) , random.randint(0,100) ,random.randint(-1000,1000)) - sql += "%s as cal18_1 ," % random.choice(self.calc_aggregate_all_j) - sql += "%s as cal18_2 " % random.choice(self.calc_aggregate_all_j) + sql += "%s as cal18_1 ," % random.choice(self.calc_aggregate_all_j) + sql += "%s as cal18_2 " % random.choice(self.calc_aggregate_all_j) sql += " from stable_1 t1, stable_2 t2 where t1.ts = t2.ts and " sql += "%s " % random.choice(self.t_join_where) sql += "%s " % random.choice(self.session_u_where) @@ -5180,16 +5180,16 @@ class TDTestCase: sql += "%s " % random.choice(self.limit_u_where) sql += ") " #sql += "%s " % random.choice(self.interval_sliding) - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) tdSql.query(sql) self.cur1.execute(sql) - + tdSql.query("select 18-7 from stable_1;") for i in range(self.fornum): sql = "select apercentile(cal18_1, %d)/1000 ,apercentile(cal18_2, %d)*10+%d from ( select " %(random.randint(0,100) , random.randint(0,100) ,random.randint(-1000,1000)) - sql += "%s as cal18_1 ," % random.choice(self.calc_aggregate_all_j) - sql += "%s as cal18_2 " % random.choice(self.calc_aggregate_all_j) + sql += "%s as cal18_1 ," % random.choice(self.calc_aggregate_all_j) + sql += "%s as cal18_2 " % random.choice(self.calc_aggregate_all_j) sql += " from stable_1 t1, stable_2 t2 where t1.ts = t2.ts and " sql += "%s " % random.choice(self.qt_u_or_where) sql += "%s " % random.choice(self.session_u_where) @@ -5197,454 +5197,454 @@ class TDTestCase: sql += "%s " % random.choice(self.limit_u_where) sql += ") " #sql += "%s " % random.choice(self.interval_sliding) - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) tdSql.query(sql) self.cur1.execute(sql) - #19 select apercentile from (select calc_aggregate_alls form regualr_table or stable where <\>\in\and\or session order by limit )interval_sliding + #19 select apercentile from (select calc_aggregate_alls form regualr_table or stable where <\>\in\and\or session order by limit )interval_sliding #self.dropandcreateDB_random("%s" %db, 1) tdSql.query("select 19-1 from stable_1;") for i in range(self.fornum): sql = "select apercentile(cal19_1, %d)/1000 ,apercentile(cal19_2, %d)*10+%d from ( select " %(random.randint(0,100) , random.randint(0,100) ,random.randint(-1000,1000)) - sql += "%s as cal19_1 ," % random.choice(self.calc_aggregate_all) - sql += "%s as cal19_2 " % random.choice(self.calc_aggregate_all) + sql += "%s as cal19_1 ," % random.choice(self.calc_aggregate_all) + sql += "%s as cal19_2 " % random.choice(self.calc_aggregate_all) sql += " from regular_table_1 where " - sql += "%s " % random.choice(self.q_where) + sql += "%s " % random.choice(self.q_where) sql += "%s " % random.choice(self.state_window) #sql += "%s " % random.choice(self.order_where) sql += "%s " % random.choice(self.limit1_where) sql += ") " - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) tdSql.query(sql) self.cur1.execute(sql) tdSql.query("select 19-2 from stable_1;") for i in range(self.fornum): sql = "select apercentile(cal19_1, %d)/1000 ,apercentile(cal19_2, %d)*10+%d from ( select " %(random.randint(0,100) , random.randint(0,100) ,random.randint(-1000,1000)) - sql += "%s as cal19_1 ," % random.choice(self.calc_aggregate_all_j) - sql += "%s as cal19_2 " % random.choice(self.calc_aggregate_all_j) + sql += "%s as cal19_1 ," % random.choice(self.calc_aggregate_all_j) + sql += "%s as cal19_2 " % random.choice(self.calc_aggregate_all_j) sql += " from regular_table_1 t1, regular_table_2 t2 where t1.ts = t2.ts and " - sql += "%s " % random.choice(self.q_u_where) + sql += "%s " % random.choice(self.q_u_where) sql += "%s " % random.choice(self.state_u_window) #sql += "%s " % random.choice(self.order_u_where) sql += "%s " % random.choice(self.limit_u_where) sql += ") " - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) tdSql.query(sql) self.cur1.execute(sql) tdSql.query("select 19-2.2 from stable_1;") for i in range(self.fornum): sql = "select apercentile(cal19_1, %d)/1000 ,apercentile(cal19_2, %d)*10+%d from ( select " %(random.randint(0,100) , random.randint(0,100) ,random.randint(-1000,1000)) - sql += "%s as cal19_1 ," % random.choice(self.calc_aggregate_all_j) - sql += "%s as cal19_2 " % random.choice(self.calc_aggregate_all_j) + sql += "%s as cal19_1 ," % random.choice(self.calc_aggregate_all_j) + sql += "%s as cal19_2 " % random.choice(self.calc_aggregate_all_j) sql += " from regular_table_1 t1, regular_table_2 t2 where t1.ts = t2.ts and " - sql += "%s " % random.choice(self.q_u_or_where) + sql += "%s " % random.choice(self.q_u_or_where) sql += "%s " % random.choice(self.state_u_window) #sql += "%s " % random.choice(self.order_u_where) sql += "%s " % random.choice(self.limit_u_where) sql += ") " - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) tdSql.query(sql) self.cur1.execute(sql) - + tdSql.query("select 19-3 from stable_1;") for i in range(self.fornum): sql = "select apercentile(cal19_1, %d)/1000 ,apercentile(cal19_2, %d)*10+%d from ( select " %(random.randint(0,100) , random.randint(0,100) ,random.randint(-1000,1000)) - sql += "%s as cal19_1 ," % random.choice(self.calc_aggregate_all) - sql += "%s as cal19_2 " % random.choice(self.calc_aggregate_all) + sql += "%s as cal19_1 ," % random.choice(self.calc_aggregate_all) + sql += "%s as cal19_2 " % random.choice(self.calc_aggregate_all) sql += " from stable_1_1 where " - sql += "%s " % random.choice(self.q_where) + sql += "%s " % random.choice(self.q_where) sql += "%s " % random.choice(self.state_window) #sql += "%s " % random.choice(self.order_where) sql += "%s " % random.choice(self.limit1_where) sql += ") " - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) tdSql.query(sql) self.cur1.execute(sql) tdSql.query("select 19-4 from stable_1;") for i in range(self.fornum): sql = "select apercentile(cal19_1, %d)/1000 ,apercentile(cal19_2, %d)*10+%d from ( select " %(random.randint(0,100) , random.randint(0,100) ,random.randint(-1000,1000)) - sql += "%s as cal19_1 ," % random.choice(self.calc_aggregate_all_j) - sql += "%s as cal19_2 " % random.choice(self.calc_aggregate_all_j) + sql += "%s as cal19_1 ," % random.choice(self.calc_aggregate_all_j) + sql += "%s as cal19_2 " % random.choice(self.calc_aggregate_all_j) sql += " from stable_1_1 t1, stable_1_2 t2 where t1.ts = t2.ts and " - sql += "%s " % random.choice(self.q_u_where) + sql += "%s " % random.choice(self.q_u_where) #sql += "%s " % random.choice(self.state_window) #sql += "%s " % random.choice(self.order_u_where) sql += "%s " % random.choice(self.limit_u_where) sql += ") " - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) tdSql.query(sql) self.cur1.execute(sql) tdSql.query("select 19-4.2 from stable_1;") for i in range(self.fornum): sql = "select apercentile(cal19_1, %d)/1000 ,apercentile(cal19_2, %d)*10+%d from ( select " %(random.randint(0,100) , random.randint(0,100) ,random.randint(-1000,1000)) - sql += "%s as cal19_1 ," % random.choice(self.calc_aggregate_all_j) - sql += "%s as cal19_2 " % random.choice(self.calc_aggregate_all_j) + sql += "%s as cal19_1 ," % random.choice(self.calc_aggregate_all_j) + sql += "%s as cal19_2 " % random.choice(self.calc_aggregate_all_j) sql += " from stable_1_1 t1, stable_1_2 t2 where t1.ts = t2.ts and " - sql += "%s " % random.choice(self.q_u_or_where) + sql += "%s " % random.choice(self.q_u_or_where) #sql += "%s " % random.choice(self.order_u_where) sql += "%s " % random.choice(self.limit_u_where) sql += ") " - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) tdSql.query(sql) self.cur1.execute(sql) tdSql.query("select 19-5 from stable_1;") for i in range(self.fornum): sql = "select apercentile(cal19_1, %d)/1000 ,apercentile(cal19_2, %d)*10+%d from ( select " %(random.randint(0,100) , random.randint(0,100) ,random.randint(-1000,1000)) - sql += "%s as cal19_1 ," % random.choice(self.calc_aggregate_all) - sql += "%s as cal19_2 " % random.choice(self.calc_aggregate_all) + sql += "%s as cal19_1 ," % random.choice(self.calc_aggregate_all) + sql += "%s as cal19_2 " % random.choice(self.calc_aggregate_all) sql += " from stable_1 where " - sql += "%s " % random.choice(self.q_where) + sql += "%s " % random.choice(self.q_where) sql += "%s " % random.choice(self.state_window) sql += "%s " % random.choice(self.order_where) sql += "%s " % random.choice(self.limit1_where) sql += ") " sql += "%s " % random.choice(self.interval_sliding) - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) tdSql.error(sql) #'STATE_WINDOW not support for super table query' - + tdSql.query("select 19-6 from stable_1;") for i in range(self.fornum): sql = "select apercentile(cal19_1, %d)/1000 ,apercentile(cal19_2, %d)*10+%d from ( select " %(random.randint(0,100) , random.randint(0,100) ,random.randint(-1000,1000)) - sql += "%s as cal19_1 ," % random.choice(self.calc_aggregate_all_j) - sql += "%s as cal19_2 " % random.choice(self.calc_aggregate_all_j) + sql += "%s as cal19_1 ," % random.choice(self.calc_aggregate_all_j) + sql += "%s as cal19_2 " % random.choice(self.calc_aggregate_all_j) sql += " from stable_1 t1 , stable_2 t2 where t1.ts = t2.ts and " - sql += "%s " % random.choice(self.q_u_where) + sql += "%s " % random.choice(self.q_u_where) #sql += "%s " % random.choice(self.state_window) #sql += "%s " % random.choice(self.order_u_where) sql += "%s " % random.choice(self.limit_u_where) sql += ") " #sql += "%s " % random.choice(self.interval_sliding) - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) tdSql.query(sql) self.cur1.execute(sql) tdSql.query("select 19-7 from stable_1;") for i in range(self.fornum): sql = "select apercentile(cal19_1, %d)/1000 ,apercentile(cal19_2, %d)*10+%d from ( select " %(random.randint(0,100) , random.randint(0,100) ,random.randint(-1000,1000)) - sql += "%s as cal19_1 ," % random.choice(self.calc_aggregate_all_j) - sql += "%s as cal19_2 " % random.choice(self.calc_aggregate_all_j) + sql += "%s as cal19_1 ," % random.choice(self.calc_aggregate_all_j) + sql += "%s as cal19_2 " % random.choice(self.calc_aggregate_all_j) sql += " from stable_1 t1 , stable_2 t2 where t1.ts = t2.ts and " - sql += "%s " % random.choice(self.qt_u_or_where) + sql += "%s " % random.choice(self.qt_u_or_where) #sql += "%s " % random.choice(self.order_u_where) sql += "%s " % random.choice(self.limit_u_where) sql += ") " #sql += "%s " % random.choice(self.interval_sliding) - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) tdSql.query(sql) self.cur1.execute(sql) - #20 select * from (select calc_select_fills form regualr_table or stable where <\>\in\and\or fill_where group by order by limit offset ) + #20 select * from (select calc_select_fills form regualr_table or stable where <\>\in\and\or fill_where group by order by limit offset ) #self.dropandcreateDB_random("%s" %db, 1) tdSql.query("select 20-1 from stable_1;") for i in range(self.fornum): - sql = "select * from ( select " + sql = "select * from ( select " sql += "%s , " % random.choice(self.calc_select_fill) - sql += "%s ," % random.choice(self.calc_select_fill) - sql += "%s " % random.choice(self.calc_select_fill) + sql += "%s ," % random.choice(self.calc_select_fill) + sql += "%s " % random.choice(self.calc_select_fill) sql += " from stable_1 where " - sql += "%s " % random.choice(self.interp_where) + sql += "%s " % random.choice(self.interp_where) sql += "%s " % random.choice(self.fill_where) sql += "%s " % random.choice(self.group_where) sql += "%s " % random.choice(self.order_where) sql += "%s " % random.choice(self.limit_where) sql += ") " - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) #interp不支持 tdSql.query(sql) #self.cur1.execute(sql) rsDn = self.restartDnodes() tdSql.query("select 20-2 from stable_1;") for i in range(self.fornum): - sql = "select * from ( select " + sql = "select * from ( select " sql += "%s , " % random.choice(self.calc_select_fill_j) - sql += "%s ," % random.choice(self.calc_select_fill_j) - sql += "%s " % random.choice(self.calc_select_fill_j) + sql += "%s ," % random.choice(self.calc_select_fill_j) + sql += "%s " % random.choice(self.calc_select_fill_j) sql += " from stable_1 t1 , stable_2 t2 where t1.ts = t2.ts and " sql += "%s and " % random.choice(self.t_join_where) - sql += "%s " % random.choice(self.interp_where_j) + sql += "%s " % random.choice(self.interp_where_j) sql += "%s " % random.choice(self.order_u_where) sql += "%s " % random.choice(self.limit_u_where) sql += ") " - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) #interp不支持 tdSql.query(sql) #self.cur1.execute(sql) tdSql.query("select 20-2.2 from stable_1;") for i in range(self.fornum): - sql = "select * from ( select " + sql = "select * from ( select " sql += "%s , " % random.choice(self.calc_select_fill_j) - sql += "%s ," % random.choice(self.calc_select_fill_j) - sql += "%s " % random.choice(self.calc_select_fill_j) + sql += "%s ," % random.choice(self.calc_select_fill_j) + sql += "%s " % random.choice(self.calc_select_fill_j) sql += " from stable_1 t1 , stable_2 t2 where t1.ts = t2.ts and " sql += "%s and " % random.choice(self.qt_u_or_where) - sql += "%s " % random.choice(self.interp_where_j) + sql += "%s " % random.choice(self.interp_where_j) sql += "%s " % random.choice(self.order_u_where) sql += "%s " % random.choice(self.limit_u_where) sql += ") " - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) #interp不支持 tdSql.query(sql) #self.cur1.execute(sql) tdSql.query("select 20-3 from stable_1;") for i in range(self.fornum): - sql = "select * from ( select " + sql = "select * from ( select " sql += "%s , " % random.choice(self.calc_select_fill) - sql += "%s ," % random.choice(self.calc_select_fill) - sql += "%s " % random.choice(self.calc_select_fill) + sql += "%s ," % random.choice(self.calc_select_fill) + sql += "%s " % random.choice(self.calc_select_fill) sql += " from stable_1 where " - sql += "%s " % self.interp_where[2] + sql += "%s " % self.interp_where[2] sql += "%s " % random.choice(self.fill_where) sql += "%s " % random.choice(self.order_where) sql += "%s " % random.choice(self.limit_where) sql += ") " - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) #interp不支持 tdSql.query(sql) #self.cur1.execute(sql) - + tdSql.query("select 20-4 from stable_1;") for i in range(self.fornum): - sql = "select * from ( select " + sql = "select * from ( select " sql += "%s , " % random.choice(self.calc_select_fill_j) - sql += "%s ," % random.choice(self.calc_select_fill_j) - sql += "%s " % random.choice(self.calc_select_fill_j) - sql += " from stable_1 t1, table_1 t2 where t1.ts = t2.ts and " + sql += "%s ," % random.choice(self.calc_select_fill_j) + sql += "%s " % random.choice(self.calc_select_fill_j) + sql += " from stable_1 t1, table_1 t2 where t1.ts = t2.ts and " #sql += "%s and " % random.choice(self.t_join_where) sql += "%s " % self.interp_where_j[random.randint(0,5)] sql += "%s " % random.choice(self.order_u_where) sql += "%s " % random.choice(self.limit_u_where) sql += ") " - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) #interp不支持 tdSql.query(sql) #self.cur1.execute(sql) tdSql.query("select 20-4.2 from stable_1;") for i in range(self.fornum): - sql = "select * from ( select " + sql = "select * from ( select " sql += "%s , " % random.choice(self.calc_select_fill_j) - sql += "%s ," % random.choice(self.calc_select_fill_j) - sql += "%s " % random.choice(self.calc_select_fill_j) - sql += " from stable_1 t1, stable_1_1 t2 where t1.ts = t2.ts and " + sql += "%s ," % random.choice(self.calc_select_fill_j) + sql += "%s " % random.choice(self.calc_select_fill_j) + sql += " from stable_1 t1, stable_1_1 t2 where t1.ts = t2.ts and " sql += "%s and " % random.choice(self.qt_u_or_where) sql += "%s " % self.interp_where_j[random.randint(0,5)] sql += "%s " % random.choice(self.fill_where) sql += "%s " % random.choice(self.order_u_where) sql += "%s " % random.choice(self.limit_u_where) sql += ") " - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) ##interp不支持 tdSql.error(sql) #self.cur1.execute(sql) - + tdSql.query("select 20-5 from stable_1;") for i in range(self.fornum): - sql = "select * from ( select " + sql = "select * from ( select " sql += "%s , " % random.choice(self.calc_select_fill) - sql += "%s ," % random.choice(self.calc_select_fill) - sql += "%s " % random.choice(self.calc_select_fill) + sql += "%s ," % random.choice(self.calc_select_fill) + sql += "%s " % random.choice(self.calc_select_fill) sql += " from regular_table_1 where " - sql += "%s " % self.interp_where[1] + sql += "%s " % self.interp_where[1] sql += "%s " % random.choice(self.fill_where) sql += "%s " % random.choice(self.order_where) sql += "%s " % random.choice(self.limit_where) sql += ") " - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) ##interp不支持 tdSql.query(sql) #self.cur1.execute(sql) tdSql.query("select 20-6 from stable_1;") for i in range(self.fornum): - sql = "select * from ( select " + sql = "select * from ( select " sql += "%s , " % random.choice(self.calc_select_fill_j) - sql += "%s ," % random.choice(self.calc_select_fill_j) - sql += "%s " % random.choice(self.calc_select_fill_j) + sql += "%s ," % random.choice(self.calc_select_fill_j) + sql += "%s " % random.choice(self.calc_select_fill_j) sql += " from regular_table_1 t1, regular_table_2 t2 where t1.ts = t2.ts and " - #sql += "%s " % random.choice(self.interp_where_j) - sql += "%s " % self.interp_where_j[random.randint(0,5)] + #sql += "%s " % random.choice(self.interp_where_j) + sql += "%s " % self.interp_where_j[random.randint(0,5)] sql += "%s " % random.choice(self.order_u_where) sql += "%s " % random.choice(self.limit_u_where) sql += ") " - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) ##interp不支持 tdSql.query(sql) #self.cur1.execute(sql) #1 select * from (select * from (select * form regular_table where <\>\in\and\or order by limit )) tdSql.query("select 1-1 from stable_1;") - for i in range(self.fornum): + for i in range(self.fornum): # sql_start = "select * from ( " # sql_end = ")" for_num = random.randint(1, 15); - sql = "select * from (" * for_num + sql = "select * from (" * for_num sql += "select * from ( select * from ( select " - sql += "%s, " % random.choice(self.s_r_select) - sql += "%s, " % random.choice(self.q_select) + sql += "%s, " % random.choice(self.s_r_select) + sql += "%s, " % random.choice(self.q_select) sql += "ts from regular_table_1 where " sql += "%s " % random.choice(self.q_where) sql += ")) " - sql += ")" * for_num - tdLog.info(sql) - tdLog.info(len(sql)) - tdSql.query(sql) + sql += ")" * for_num + tdLog.info(sql) + tdLog.info(len(sql)) + tdSql.query(sql) self.cur1.execute(sql) - + sql2 = "select * from ( select * from ( select " - sql2 += "%s, " % random.choice(self.s_r_select) - sql2 += "%s, " % random.choice(self.q_select) + sql2 += "%s, " % random.choice(self.s_r_select) + sql2 += "%s, " % random.choice(self.q_select) sql2 += "ts from regular_table_1 where " sql2 += "%s " % random.choice(self.q_where) - sql2 += ")) " - tdLog.info(sql2) - tdLog.info(len(sql2)) - tdSql.query(sql2) + sql2 += ")) " + tdLog.info(sql2) + tdLog.info(len(sql2)) + tdSql.query(sql2) self.cur1.execute(sql2) - + self.data_matrix_equal('%s' %sql ,1,10,1,1,'%s' %sql2 ,1,10,1,1) self.data_matrix_equal('%s' %sql ,1,10,1,1,'%s' %sql ,1,10,3,3) self.data_matrix_equal('%s' %sql ,1,10,3,3,'%s' %sql2 ,1,10,3,3) - + for i in range(self.fornum): for_num = random.randint(1, 15); - sql = "select ts from (" * for_num + sql = "select ts from (" * for_num sql += "select * from ( select * from ( select " - sql += "%s, " % random.choice(self.s_r_select) - sql += "%s, " % random.choice(self.q_select) + sql += "%s, " % random.choice(self.s_r_select) + sql += "%s, " % random.choice(self.q_select) sql += "ts from regular_table_1 where " sql += "%s " % random.choice(self.q_where) sql += ")) " - sql += ")" * for_num - tdLog.info(sql) - tdLog.info(len(sql)) - tdSql.query(sql) + sql += ")" * for_num + tdLog.info(sql) + tdLog.info(len(sql)) + tdSql.query(sql) self.cur1.execute(sql) - + sql2 = "select * from ( select * from ( select " - sql2 += "%s, " % random.choice(self.s_r_select) - sql2 += "%s, " % random.choice(self.q_select) + sql2 += "%s, " % random.choice(self.s_r_select) + sql2 += "%s, " % random.choice(self.q_select) sql2 += "ts from regular_table_1 where " sql2 += "%s " % random.choice(self.q_where) - sql2 += ")) " - tdLog.info(sql2) - tdLog.info(len(sql2)) + sql2 += ")) " + tdLog.info(sql2) + tdLog.info(len(sql2)) tdSql.query(sql2) - self.cur1.execute(sql2) - + self.cur1.execute(sql2) + self.data_matrix_equal('%s' %sql ,1,10,1,1,'%s' %sql2 ,1,10,1,1) - + #2 select * from (select * from (select * form stable where <\>\in\and\or order by limit )) tdSql.query("select 2-1 from stable_1;") for i in range(self.fornum): for_num = random.randint(1, 15); - sql = "select * from (" * for_num + sql = "select * from (" * for_num sql += "select * from ( select * from ( select " - sql += "%s, " % random.choice(self.s_s_select) - sql += "%s, " % random.choice(self.qt_select) + sql += "%s, " % random.choice(self.s_s_select) + sql += "%s, " % random.choice(self.qt_select) sql += "ts from stable_1 where " sql += "%s " % random.choice(self.q_where) sql += ")) " - sql += ")" * for_num - tdLog.info(sql) - tdLog.info(len(sql)) - tdSql.query(sql) + sql += ")" * for_num + tdLog.info(sql) + tdLog.info(len(sql)) + tdSql.query(sql) self.cur1.execute(sql) - + sql2 = "select * from ( select * from ( select " - sql2 += "%s, " % random.choice(self.s_s_select) - sql2 += "%s, " % random.choice(self.qt_select) + sql2 += "%s, " % random.choice(self.s_s_select) + sql2 += "%s, " % random.choice(self.qt_select) sql2 += "ts from stable_1 where " sql2 += "%s " % random.choice(self.q_where) - sql2 += ")) " - tdLog.info(sql2) - tdLog.info(len(sql2)) - tdSql.query(sql2) + sql2 += ")) " + tdLog.info(sql2) + tdLog.info(len(sql2)) + tdSql.query(sql2) self.cur1.execute(sql2) - + self.data_matrix_equal('%s' %sql ,1,10,3,3,'%s' %sql2 ,1,10,3,3) - + for i in range(self.fornum): for_num = random.randint(1, 15); - sql = "select ts from (" * for_num + sql = "select ts from (" * for_num sql += "select * from ( select * from ( select " - sql += "%s, " % random.choice(self.s_s_select) - sql += "%s, " % random.choice(self.qt_select) + sql += "%s, " % random.choice(self.s_s_select) + sql += "%s, " % random.choice(self.qt_select) sql += "ts from stable_1 where " sql += "%s " % random.choice(self.q_where) sql += ")) " - sql += ")" * for_num - tdLog.info(sql) - tdLog.info(len(sql)) - tdSql.query(sql) + sql += ")" * for_num + tdLog.info(sql) + tdLog.info(len(sql)) + tdSql.query(sql) self.cur1.execute(sql) - + sql2 = "select ts from ( select * from ( select " - sql2 += "%s, " % random.choice(self.s_s_select) - sql2 += "%s, " % random.choice(self.qt_select) + sql2 += "%s, " % random.choice(self.s_s_select) + sql2 += "%s, " % random.choice(self.qt_select) sql2 += "ts from stable_1 where " sql2 += "%s " % random.choice(self.q_where) - sql2 += ")) " - tdLog.info(sql2) - tdLog.info(len(sql2)) - tdSql.query(sql2) + sql2 += ")) " + tdLog.info(sql2) + tdLog.info(len(sql2)) + tdSql.query(sql2) self.cur1.execute(sql2) - + self.data_matrix_equal('%s' %sql ,1,10,1,1,'%s' %sql2 ,1,10,1,1) - - #3 select ts ,calc from (select * form stable where <\>\in\and\or order by limit ) + + #3 select ts ,calc from (select * form stable where <\>\in\and\or order by limit ) #self.dropandcreateDB_random("%s" %db, 1) tdSql.query("select 3-1 from stable_1;") for i in range(self.fornum): sql = "select " - sql += "%s " % random.choice(self.calc_calculate_regular) + sql += "%s " % random.choice(self.calc_calculate_regular) sql += " from ( select * from stable_1 where " sql += "%s " % random.choice(self.qt_where) sql += "%s " % random.choice(self.orders_desc_where) sql += "%s " % random.choice(self.limit_where) sql += ") ;" - tdLog.info(sql) - tdLog.info(len(sql)) - #'Invalid function name: derivative' tdSql.query(sql) - #self.cur1.execute(sql) + tdLog.info(sql) + tdLog.info(len(sql)) + #'Invalid function name: derivative' tdSql.query(sql) + #self.cur1.execute(sql) #4 select * from (select calc form stable where <\>\in\and\or order by limit ) tdSql.query("select 4-1 from stable_1;") for i in range(self.fornum): sql = "select * from ( select " - sql += "%s " % random.choice(self.calc_select_in_ts) + sql += "%s " % random.choice(self.calc_select_in_ts) sql += "from stable_1 where " sql += "%s " % random.choice(self.qt_where) #sql += "%s " % random.choice(self.order_desc_where) sql += "%s " % random.choice(self.limit_where) sql += ") ;" - tdLog.info(sql) - tdLog.info(len(sql)) + tdLog.info(sql) + tdLog.info(len(sql)) tdSql.query(sql) self.cur1.execute(sql) - + #5 select ts ,tbname from (select * form stable where <\>\in\and\or order by limit ) tdSql.query("select 5-1 from stable_1;") for i in range(self.fornum): sql = "select ts , tbname , " - sql += "%s ," % random.choice(self.calc_calculate_regular) + sql += "%s ," % random.choice(self.calc_calculate_regular) sql += "%s ," % random.choice(self.dqt_select) sql += "%s " % random.choice(self.qt_select) sql += " from ( select * from stable_1 where " @@ -5652,9 +5652,9 @@ class TDTestCase: sql += "%s " % random.choice(self.orders_desc_where) sql += "%s " % random.choice(self.limit_where) sql += ") ;" - tdLog.info(sql) - tdLog.info(len(sql)) - tdSql.error(sql) + tdLog.info(sql) + tdLog.info(len(sql)) + tdSql.error(sql) #special sql tdSql.query("select 6-1 from stable_1;") @@ -5678,7 +5678,7 @@ class TDTestCase: tdSql.error(sql) sql = "select * from (select server_status() as status);" tdSql.error(sql) - + #taos -f sql startTime_taos_f = time.time() print("taos -f sql start!") @@ -5690,36 +5690,36 @@ class TDTestCase: print('=====================2.6 old function end ===========') - - + + def run(self): tdSql.prepare() - - startTime = time.time() - - # - - + + startTime = time.time() + + # + + #self.math_nest(['TAIL']) #TD-16009 # self.math_nest(['HYPERLOGLOG']) #TD-16038 # self.math_nest(['UNIQUE']) - + # # #self.function_before_26() #TD-16031 - - # self.math_nest(['ABS','SQRT']) #TD-16042 - # self.math_nest(['SIN','COS','TAN','ASIN','ACOS','ATAN']) + + # self.math_nest(['ABS','SQRT']) #TD-16042 + # self.math_nest(['SIN','COS','TAN','ASIN','ACOS','ATAN']) # self.math_nest(['POW','LOG']) #TD-16039 - # self.math_nest(['FLOOR','CEIL','ROUND']) - # #self.math_nest(['SAMPLE']) #TD-16017 + # self.math_nest(['FLOOR','CEIL','ROUND']) + # #self.math_nest(['SAMPLE']) #TD-16017 # #self.math_nest(['CSUM']) #TD-15936 crash - # self.math_nest(['MAVG']) - - self.str_nest(['LTRIM','RTRIM','LOWER','UPPER']) - self.str_nest(['LENGTH','CHAR_LENGTH']) - self.str_nest(['SUBSTR']) #TD-16042 + # self.math_nest(['MAVG']) + + self.str_nest(['LTRIM','RTRIM','LOWER','UPPER']) + self.str_nest(['LENGTH','CHAR_LENGTH']) + self.str_nest(['SUBSTR']) #TD-16042 self.str_nest(['CONCAT']) #TD-16002 偶尔 self.str_nest(['CONCAT_WS']) #TD-16002 偶尔 # self.time_nest(['CAST']) #TD-16017偶尔,放到time里起来弄 @@ -5727,21 +5727,21 @@ class TDTestCase: self.time_nest(['CAST_2']) self.time_nest(['CAST_3']) self.time_nest(['CAST_4']) - - - + + + # self.time_nest(['NOW','TODAY']) # # self.time_nest(['TIMEZONE']) # # self.time_nest(['TIMETRUNCATE']) #TD-16039 # self.time_nest(['TO_ISO8601']) # self.time_nest(['TO_UNIXTIMESTAMP'])#core多 # self.time_nest(['ELAPSED']) - + endTime = time.time() print("total time %ds" % (endTime - startTime)) - + def stop(self): -- GitLab From 51399762c29659a533bb529a6c473f5571e51a77 Mon Sep 17 00:00:00 2001 From: Ganlin Zhao Date: Wed, 13 Jul 2022 14:41:50 +0800 Subject: [PATCH 044/153] fix test cases --- tests/system-test/2-query/To_unixtimestamp.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/tests/system-test/2-query/To_unixtimestamp.py b/tests/system-test/2-query/To_unixtimestamp.py index 8dc995b178..60d5cc7b72 100644 --- a/tests/system-test/2-query/To_unixtimestamp.py +++ b/tests/system-test/2-query/To_unixtimestamp.py @@ -13,11 +13,11 @@ class TDTestCase: tdLog.debug(f"start to excute {__file__}") tdSql.init(conn.cursor()) # name of normal table - self.ntbname = 'ntb' + self.ntbname = 'ntb' # name of stable - self.stbname = 'stb' + self.stbname = 'stb' # structure of column - self.column_dict = { + self.column_dict = { 'ts':'timestamp', 'c1':'int', 'c2':'float', @@ -25,13 +25,13 @@ class TDTestCase: 'c4':'nchar(20)' } # structure of tag - self.tag_dict = { + self.tag_dict = { 't0':'int' } # number of child tables - self.tbnum = 2 + self.tbnum = 2 # values of tag,the number of values should equal to tbnum - self.tag_values = [ + self.tag_values = [ f'10', f'100' ] @@ -42,7 +42,7 @@ class TDTestCase: ] self.error_param = [1,'now()'] - + def run(self): # sourcery skip: extract-duplicate-method tdSql.prepare() tdLog.printNoPrefix("==========step1:create tables==========") @@ -93,11 +93,11 @@ class TDTestCase: tdSql.query("select ts from ntb where to_unixtimestamp('1970-01-01T08:00:00+08:00')=0") tdSql.checkRows(3) - + def stop(self): tdSql.close() tdLog.success(f"{__file__} successfully executed") tdCases.addLinux(__file__, TDTestCase()) -tdCases.addWindows(__file__, TDTestCase()) \ No newline at end of file +tdCases.addWindows(__file__, TDTestCase()) -- GitLab From 7fbef9cbbe17c920fecc02117fb5578733a09b6c Mon Sep 17 00:00:00 2001 From: Ganlin Zhao Date: Wed, 13 Jul 2022 14:41:50 +0800 Subject: [PATCH 045/153] fix test cases --- tests/system-test/2-query/unique.py | 92 ++++++++++++++--------------- 1 file changed, 46 insertions(+), 46 deletions(-) diff --git a/tests/system-test/2-query/unique.py b/tests/system-test/2-query/unique.py index 4467dcb471..fce0d21f4d 100644 --- a/tests/system-test/2-query/unique.py +++ b/tests/system-test/2-query/unique.py @@ -11,14 +11,14 @@ from util.sql import * from util.cases import * class TDTestCase: - updatecfgDict = {'debugFlag': 143 ,"cDebugFlag":143,"uDebugFlag":143 ,"rpcDebugFlag":143 , "tmrDebugFlag":143 , + updatecfgDict = {'debugFlag': 143 ,"cDebugFlag":143,"uDebugFlag":143 ,"rpcDebugFlag":143 , "tmrDebugFlag":143 , "jniDebugFlag":143 ,"simDebugFlag":143,"dDebugFlag":143, "dDebugFlag":143,"vDebugFlag":143,"mDebugFlag":143,"qDebugFlag":143, "wDebugFlag":143,"sDebugFlag":143,"tsdbDebugFlag":143,"tqDebugFlag":143 ,"fsDebugFlag":143 ,"udfDebugFlag":143} def init(self, conn, logSql): tdLog.debug(f"start to excute {__file__}") tdSql.init(conn.cursor()) - + def prepare_datas(self): tdSql.execute( '''create table stb1 @@ -26,7 +26,7 @@ class TDTestCase: tags (t1 int) ''' ) - + tdSql.execute( ''' create table t1 @@ -68,7 +68,7 @@ class TDTestCase: ( '2023-02-21 01:01:01.000', NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL ) ''' ) - + def test_errors(self): error_sql_lists = [ "select unique from t1", @@ -119,40 +119,40 @@ class TDTestCase: "select unique(c1) , diff(c1) from stb1 partition by tbname", #"select unique(c1) , abs(c1) from stb1 partition by tbname", # support #"select unique(c1) , c1 from stb1 partition by tbname" # support - + ] for error_sql in error_sql_lists: tdSql.error(error_sql) pass - + def support_types(self): other_no_value_types = [ - "select unique(ts) from t1" , + "select unique(ts) from t1" , "select unique(c7) from t1", "select unique(c8) from t1", "select unique(c9) from t1", - "select unique(ts) from ct1" , + "select unique(ts) from ct1" , "select unique(c7) from ct1", "select unique(c8) from ct1", "select unique(c9) from ct1", - "select unique(ts) from ct3" , + "select unique(ts) from ct3" , "select unique(c7) from ct3", "select unique(c8) from ct3", "select unique(c9) from ct3", - "select unique(ts) from ct4" , + "select unique(ts) from ct4" , "select unique(c7) from ct4", "select unique(c8) from ct4", "select unique(c9) from ct4", - "select unique(ts) from stb1 partition by tbname" , + "select unique(ts) from stb1 partition by tbname" , "select unique(c7) from stb1 partition by tbname", "select unique(c8) from stb1 partition by tbname", - "select unique(c9) from stb1 partition by tbname" + "select unique(c9) from stb1 partition by tbname" ] - + for type_sql in other_no_value_types: tdSql.query(type_sql) tdLog.info("support type ok , sql is : %s"%type_sql) - + type_sql_lists = [ "select unique(c1) from t1", "select unique(c2) from t1", @@ -182,8 +182,8 @@ class TDTestCase: "select unique(c5) from stb1 partition by tbname", "select unique(c6) from stb1 partition by tbname", - "select unique(c6) as alisb from stb1 partition by tbname", - "select unique(c6) alisb from stb1 partition by tbname", + "select unique(c6) as alisb from stb1 partition by tbname", + "select unique(c6) alisb from stb1 partition by tbname", ] for type_sql in type_sql_lists: @@ -194,18 +194,18 @@ class TDTestCase: origin_sql = unique_sql.replace("unique(","").replace(")","") tdSql.query(unique_sql) unique_result = tdSql.queryResult - + unique_datas = [] for elem in unique_result: unique_datas.append(elem[0]) unique_datas.sort(key=lambda x: (x is None, x)) - + tdSql.query(origin_sql) origin_result = tdSql.queryResult origin_datas = [] for elem in origin_result: origin_datas.append(elem[0]) - + pre_unique = [] for elem in origin_datas: if elem in pre_unique: @@ -221,7 +221,7 @@ class TDTestCase: def basic_unique_function(self): - # basic query + # basic query tdSql.query("select c1 from ct3") tdSql.checkRows(0) tdSql.query("select c1 from t1") @@ -242,19 +242,19 @@ class TDTestCase: tdSql.checkRows(0) tdSql.query("select unique(c6) from ct3") - # will support _rowts mix with + # will support _rowts mix with # tdSql.query("select unique(c6),_rowts from ct3") - + # auto check for t1 table # used for regular table tdSql.query("select unique(c1) from t1") - + tdSql.query("desc t1") col_lists_rows = tdSql.queryResult col_lists = [] for col_name in col_lists_rows: col_lists.append(col_name[0]) - + for col in col_lists: self.check_unique_table(f"select unique({col}) from t1") @@ -269,17 +269,17 @@ class TDTestCase: #tdSql.error("select unique(c1),tbname from ct1") #support #tdSql.error("select unique(c1),t1 from ct1") #support - # unique with common col + # unique with common col #tdSql.error("select unique(c1) ,ts from ct1") #tdSql.error("select unique(c1) ,c1 from ct1") - # unique with scalar function + # unique with scalar function #tdSql.error("select unique(c1) ,abs(c1) from ct1") tdSql.error("select unique(c1) , unique(c2) from ct1") #tdSql.error("select unique(c1) , abs(c2)+2 from ct1") - - # unique with aggregate function + + # unique with aggregate function tdSql.error("select unique(c1) ,sum(c1) from ct1") tdSql.error("select unique(c1) ,max(c1) from ct1") tdSql.error("select unique(c1) ,csum(c1) from ct1") @@ -306,7 +306,7 @@ class TDTestCase: tdSql.checkData(7, 0, 1) tdSql.checkData(8, 0, 0) - # unique with union all + # unique with union all tdSql.query("select unique(c1) from ct4 union all select c1 from ct1") tdSql.checkRows(23) tdSql.query("select unique(c1) from ct4 union all select distinct(c1) from ct4") @@ -314,8 +314,8 @@ class TDTestCase: tdSql.query("select unique(c2) from ct4 union all select abs(c2)/2 from ct4") tdSql.checkRows(22) - # unique with join - # prepare join datas with same ts + # unique with join + # prepare join datas with same ts tdSql.execute(" use db ") tdSql.execute(" create stable st1 (ts timestamp , num int) tags(ind int)") @@ -371,7 +371,7 @@ class TDTestCase: tdSql.checkRows(10) tdSql.checkData(0, 0, None) tdSql.checkData(1, 0, -7.000000000) - + # bug for stable #partition by tbname @@ -380,8 +380,8 @@ class TDTestCase: # tdSql.query(" select unique(c1) from stb1 partition by tbname ") # tdSql.checkRows(21) - - # group by + + # group by tdSql.error("select unique(c1) from ct1 group by c1") tdSql.error("select unique(c1) from ct1 group by tbname") @@ -393,7 +393,7 @@ class TDTestCase: tdSql.checkRows(4) - # bug need fix + # bug need fix # tdSql.query("select tbname , tail(c1,2) from stb1 partition by tbname") # tdSql.checkRows(4) @@ -411,7 +411,7 @@ class TDTestCase: tdSql.checkRows(4) - # # bug need fix + # # bug need fix # tdSql.query(" select tbname , unique(c1) from stb1 where t1 = 0 partition by tbname ") # tdSql.checkRows(2) # tdSql.query(" select tbname , unique(c1) from stb1 where t1 = 0 partition by tbname order by tbname ") @@ -430,7 +430,7 @@ class TDTestCase: tdSql.query(" select unique(t1) from stb1 partition by tbname ") tdSql.checkRows(2) - # nest query + # nest query tdSql.query(" select unique(c1) from (select _rowts , t1 ,c1 , tbname from stb1 ) ") tdSql.checkRows(11) tdSql.checkData(0,0,6) @@ -439,7 +439,7 @@ class TDTestCase: tdSql.checkRows(2) tdSql.checkData(0,0,4) tdSql.checkData(1,0,1) - + def check_boundary_values(self): tdSql.execute("drop database if exists bound_test") @@ -467,11 +467,11 @@ class TDTestCase: tdSql.execute( f"insert into sub1_bound values ( now(), -2147483643, -9223372036854775803, -32763, -123, -3.39E+38, -1.69e+308, True, 'binary_tb1', 'nchar_tb1', now() )" ) - + tdSql.error( f"insert into sub1_bound values ( now()+1s, 2147483648, 9223372036854775808, 32768, 128, 3.40E+38, 1.7e+308, True, 'binary_tb1', 'nchar_tb1', now() )" ) - + tdSql.query("select unique(c2) from sub1_bound order by 1 desc") tdSql.checkRows(5) tdSql.checkData(0,0,9223372036854775807) @@ -480,22 +480,22 @@ class TDTestCase: tdSql.prepare() tdLog.printNoPrefix("==========step1:create table ==============") - + self.prepare_datas() - tdLog.printNoPrefix("==========step2:test errors ==============") + tdLog.printNoPrefix("==========step2:test errors ==============") self.test_errors() - - tdLog.printNoPrefix("==========step3:support types ============") + + tdLog.printNoPrefix("==========step3:support types ============") self.support_types() - tdLog.printNoPrefix("==========step4: floor basic query ============") + tdLog.printNoPrefix("==========step4: floor basic query ============") self.basic_unique_function() - tdLog.printNoPrefix("==========step5: floor boundary query ============") + tdLog.printNoPrefix("==========step5: floor boundary query ============") self.check_boundary_values() -- GitLab From 79bbda564ef6e6a26a35457c75fde5c80aa54627 Mon Sep 17 00:00:00 2001 From: Shengliang Guan Date: Wed, 13 Jul 2022 14:55:02 +0800 Subject: [PATCH 046/153] test: comment out unstable case --- tests/system-test/fulltest.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/system-test/fulltest.sh b/tests/system-test/fulltest.sh index 269f83a139..ca4850e433 100755 --- a/tests/system-test/fulltest.sh +++ b/tests/system-test/fulltest.sh @@ -148,7 +148,7 @@ python3 ./test.py -f 7-tmq/subscribeDb2.py python3 ./test.py -f 7-tmq/subscribeDb3.py #python3 ./test.py -f 7-tmq/subscribeDb4.py python3 ./test.py -f 7-tmq/subscribeStb.py -python3 ./test.py -f 7-tmq/subscribeStb0.py +#python3 ./test.py -f 7-tmq/subscribeStb0.py python3 ./test.py -f 7-tmq/subscribeStb1.py python3 ./test.py -f 7-tmq/subscribeStb2.py python3 ./test.py -f 7-tmq/subscribeStb3.py -- GitLab From 85d2e6f1be2ee64c48c21078dad0df9bf9f2326b Mon Sep 17 00:00:00 2001 From: Shengliang Guan Date: Wed, 13 Jul 2022 15:02:44 +0800 Subject: [PATCH 047/153] test: restore some 2.0 case --- tests/script/general/cache/testSuite.sim | 3 --- tests/script/jenkins/basic.txt | 5 +++++ .../{general => tsim}/cache/new_metrics.sim | 16 ---------------- .../{general => tsim}/cache/restart_metrics.sim | 9 +-------- .../{general => tsim}/cache/restart_table.sim | 9 +-------- 5 files changed, 7 insertions(+), 35 deletions(-) delete mode 100644 tests/script/general/cache/testSuite.sim rename tests/script/{general => tsim}/cache/new_metrics.sim (92%) rename tests/script/{general => tsim}/cache/restart_metrics.sim (91%) rename tests/script/{general => tsim}/cache/restart_table.sim (86%) diff --git a/tests/script/general/cache/testSuite.sim b/tests/script/general/cache/testSuite.sim deleted file mode 100644 index f09ece89b6..0000000000 --- a/tests/script/general/cache/testSuite.sim +++ /dev/null @@ -1,3 +0,0 @@ -run general/cache/new_metrics.sim -run general/cache/restart_table.sim -run general/cache/restart_metrics.sim diff --git a/tests/script/jenkins/basic.txt b/tests/script/jenkins/basic.txt index 13a28aa527..34e1ef3bdc 100644 --- a/tests/script/jenkins/basic.txt +++ b/tests/script/jenkins/basic.txt @@ -12,6 +12,11 @@ ./test.sh -f tsim/user/privilege_db.sim ./test.sh -f tsim/user/privilege_sysinfo.sim +# ---- cache +./test.sh -f tsim/cache/new_metrics.sim +./test.sh -f tsim/cache/restart_table.sim +./test.sh -f tsim/cache/restart_metrics.sim + ## ---- db ./test.sh -f tsim/db/alter_option.sim # ./test.sh -f tsim/db/alter_replica_13.sim diff --git a/tests/script/general/cache/new_metrics.sim b/tests/script/tsim/cache/new_metrics.sim similarity index 92% rename from tests/script/general/cache/new_metrics.sim rename to tests/script/tsim/cache/new_metrics.sim index eb9b042483..af7db90070 100644 --- a/tests/script/general/cache/new_metrics.sim +++ b/tests/script/tsim/cache/new_metrics.sim @@ -1,11 +1,6 @@ system sh/stop_dnodes.sh - - system sh/deploy.sh -n dnode1 -i 1 -system sh/cfg.sh -n dnode1 -c walLevel -v 1 system sh/exec.sh -n dnode1 -s start - -sleep 2000 sql connect $i = 0 @@ -38,7 +33,6 @@ while $i < 5 endw print =============== step2 - sql select * from $tb order by ts desc print ===>rows $rows, data $data01 if $rows != 20 then @@ -67,7 +61,6 @@ if $data00 != 100 then endi print =============== step3 - sql show stables if $rows != 1 then return -1 @@ -75,12 +68,8 @@ endi if $data00 != $mt then return -1 endi -if $data04 != 5 then - return -1 -endi print =============== step4 - while $i < 10 $tb = $tbPrefix . $i sql create table $tb using $mt tags( 1 ) @@ -99,7 +88,6 @@ sql reset query cache sleep 1000 print =============== step5 - sql select * from $tb order by ts desc print ===>rows $rows, data $data01 if $rows != 20 then @@ -128,7 +116,6 @@ if $data00 != 200 then endi print =============== step6 - sql show stables if $rows != 1 then return -1 @@ -136,8 +123,5 @@ endi if $data00 != $mt then return -1 endi -if $data04 != 10 then - return -1 -endi system sh/exec.sh -n dnode1 -s stop -x SIGINT \ No newline at end of file diff --git a/tests/script/general/cache/restart_metrics.sim b/tests/script/tsim/cache/restart_metrics.sim similarity index 91% rename from tests/script/general/cache/restart_metrics.sim rename to tests/script/tsim/cache/restart_metrics.sim index a1b2365b2a..e144a49bf7 100644 --- a/tests/script/general/cache/restart_metrics.sim +++ b/tests/script/tsim/cache/restart_metrics.sim @@ -1,14 +1,9 @@ system sh/stop_dnodes.sh - - system sh/deploy.sh -n dnode1 -i 1 -system sh/cfg.sh -n dnode1 -c walLevel -v 1 system sh/exec.sh -n dnode1 -s start - -sleep 2000 sql connect -print ======================== dnode1 start +print ======================== dnode1 start $i = 0 $dbPrefix = ca_rm_db $tbPrefix = ca_rm_tb @@ -49,9 +44,7 @@ endi print =============== step2 system sh/exec.sh -n dnode1 -s stop -sleep 3000 system sh/deploy.sh -n dnode1 -i 1 -system sh/cfg.sh -n dnode1 -c walLevel -v 1 system sh/exec.sh -n dnode1 -s start print =============== step3 diff --git a/tests/script/general/cache/restart_table.sim b/tests/script/tsim/cache/restart_table.sim similarity index 86% rename from tests/script/general/cache/restart_table.sim rename to tests/script/tsim/cache/restart_table.sim index 1f7d982a28..b450f6c654 100644 --- a/tests/script/general/cache/restart_table.sim +++ b/tests/script/tsim/cache/restart_table.sim @@ -1,14 +1,9 @@ system sh/stop_dnodes.sh - - system sh/deploy.sh -n dnode1 -i 1 -system sh/cfg.sh -n dnode1 -c walLevel -v 1 system sh/exec.sh -n dnode1 -s start - -sleep 2000 sql connect -print ======================== dnode1 start +print ======================== dnode1 start $i = 0 $dbPrefix = ca_rt_db $tbPrefix = ca_rt_tb @@ -33,9 +28,7 @@ endi print =============== step2 system sh/exec.sh -n dnode1 -s stop -sleep 3000 system sh/deploy.sh -n dnode1 -i 1 -system sh/cfg.sh -n dnode1 -c walLevel -v 1 system sh/exec.sh -n dnode1 -s start print =============== step3 -- GitLab From 56b1d11beb1f36188681af3c2ea92b07388102fa Mon Sep 17 00:00:00 2001 From: Haojun Liao Date: Wed, 13 Jul 2022 15:06:27 +0800 Subject: [PATCH 048/153] fix(query): prepare the output buffer before assign daata. --- source/libs/executor/src/executorimpl.c | 2 +- source/libs/executor/src/scanoperator.c | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/source/libs/executor/src/executorimpl.c b/source/libs/executor/src/executorimpl.c index 6f4a6b805d..760d7e55c8 100644 --- a/source/libs/executor/src/executorimpl.c +++ b/source/libs/executor/src/executorimpl.c @@ -4334,6 +4334,7 @@ SOperatorInfo* createOperatorTree(SPhysiNode* pPhyNode, SExecTaskInfo* pTaskInfo pTaskInfo->code = code; return NULL; } + code = extractTableSchemaInfo(pHandle, pTableScanNode->scan.uid, pTaskInfo); if (code) { pTaskInfo->code = terrno; @@ -4349,7 +4350,6 @@ SOperatorInfo* createOperatorTree(SPhysiNode* pPhyNode, SExecTaskInfo* pTaskInfo } else if (QUERY_NODE_PHYSICAL_PLAN_EXCHANGE == type) { return createExchangeOperatorInfo(pHandle->pMsgCb->clientRpc, (SExchangePhysiNode*)pPhyNode, pTaskInfo); - } else if (QUERY_NODE_PHYSICAL_PLAN_STREAM_SCAN == type) { STableScanPhysiNode* pTableScanNode = (STableScanPhysiNode*)pPhyNode; STimeWindowAggSupp twSup = { diff --git a/source/libs/executor/src/scanoperator.c b/source/libs/executor/src/scanoperator.c index 66703502eb..c7112ab8a6 100644 --- a/source/libs/executor/src/scanoperator.c +++ b/source/libs/executor/src/scanoperator.c @@ -1153,10 +1153,11 @@ static int32_t setBlockIntoRes(SStreamScanInfo* pInfo, const SSDataBlock* pBlock SOperatorInfo* pOperator = pInfo->pStreamScanOp; SExecTaskInfo* pTaskInfo = pInfo->pStreamScanOp->pTaskInfo; + blockDataEnsureCapacity(pInfo->pRes, pBlock->info.rows); + pInfo->pRes->info.rows = pBlock->info.rows; pInfo->pRes->info.uid = pBlock->info.uid; pInfo->pRes->info.type = STREAM_NORMAL; - pInfo->pRes->info.capacity = pBlock->info.rows; uint64_t* groupIdPre = taosHashGet(pOperator->pTaskInfo->tableqinfoList.map, &pBlock->info.uid, sizeof(int64_t)); if (groupIdPre) { @@ -2415,6 +2416,7 @@ int32_t createScanTableListInfo(STableScanPhysiNode* pTableScanNode, SReadHandle qDebug("no table qualified for query, TID:0x%" PRIx64 ", QID:0x%" PRIx64, taskId, queryId); return TSDB_CODE_SUCCESS; } + pTableListInfo->needSortTableByGroupId = pTableScanNode->groupSort; code = generateGroupIdMap(pTableListInfo, pHandle, pTableScanNode->pGroupTags); if (code != TSDB_CODE_SUCCESS) { -- GitLab From 161880224847ba0c71fc043243a0680e1419e833 Mon Sep 17 00:00:00 2001 From: Shengliang Guan Date: Wed, 13 Jul 2022 15:07:26 +0800 Subject: [PATCH 049/153] test: restore some 2.0 case --- tests/script/general/column/testSuite.sim | 3 --- tests/script/jenkins/basic.txt | 7 ++++++- tests/script/{general => tsim}/column/commit.sim | 10 ---------- tests/script/{general => tsim}/column/metrics.sim | 10 ---------- tests/script/{general => tsim}/column/table.sim | 9 --------- 5 files changed, 6 insertions(+), 33 deletions(-) delete mode 100644 tests/script/general/column/testSuite.sim rename tests/script/{general => tsim}/column/commit.sim (99%) rename tests/script/{general => tsim}/column/metrics.sim (99%) rename tests/script/{general => tsim}/column/table.sim (99%) diff --git a/tests/script/general/column/testSuite.sim b/tests/script/general/column/testSuite.sim deleted file mode 100644 index f60d197e95..0000000000 --- a/tests/script/general/column/testSuite.sim +++ /dev/null @@ -1,3 +0,0 @@ -run general/column/commit.sim -run general/column/metrics.sim -run general/column/table.sim diff --git a/tests/script/jenkins/basic.txt b/tests/script/jenkins/basic.txt index 34e1ef3bdc..afe5527380 100644 --- a/tests/script/jenkins/basic.txt +++ b/tests/script/jenkins/basic.txt @@ -17,7 +17,12 @@ ./test.sh -f tsim/cache/restart_table.sim ./test.sh -f tsim/cache/restart_metrics.sim -## ---- db +# ---- column +./test.sh -f tsim/column/commit.sim +./test.sh -f tsim/column/metrics.sim +./test.sh -f tsim/column/table.sim + +# ---- db ./test.sh -f tsim/db/alter_option.sim # ./test.sh -f tsim/db/alter_replica_13.sim # ./test.sh -f tsim/db/alter_replica_31.sim diff --git a/tests/script/general/column/commit.sim b/tests/script/tsim/column/commit.sim similarity index 99% rename from tests/script/general/column/commit.sim rename to tests/script/tsim/column/commit.sim index 008bec3bf9..43aebb4902 100644 --- a/tests/script/general/column/commit.sim +++ b/tests/script/tsim/column/commit.sim @@ -1,11 +1,6 @@ system sh/stop_dnodes.sh - - system sh/deploy.sh -n dnode1 -i 1 -system sh/cfg.sh -n dnode1 -c walLevel -v 1 system sh/exec.sh -n dnode1 -s start - -sleep 2000 sql connect print =============== step1 @@ -25,7 +20,6 @@ if $rows != 1 then endi print =============== step2 - sql insert into d3.t1 values (now -300d,0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ); sql insert into d3.t1 values (now-200d,1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 ); sql insert into d3.t1 values (now-150d,2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 ); @@ -38,7 +32,6 @@ sql insert into d3.t1 values (now,8 , 8 , 8 , 8 , 8 , 8 , 8 , 8 , 8 , 8 , 8 , 8 sql insert into d3.t1 values (now+1d,9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 ); print =============== step3 - sql select * from d3.mt if $rows != 10 then return -1 @@ -89,12 +82,9 @@ endi print =============== step4 system sh/exec.sh -n dnode1 -s stop -x SIGINT -sleep 3000 system sh/exec.sh -n dnode1 -s start -sleep 3000 print =============== step5 - sql select * from d3.mt if $rows != 10 then return -1 diff --git a/tests/script/general/column/metrics.sim b/tests/script/tsim/column/metrics.sim similarity index 99% rename from tests/script/general/column/metrics.sim rename to tests/script/tsim/column/metrics.sim index 580e2320cd..a492f5a2f9 100644 --- a/tests/script/general/column/metrics.sim +++ b/tests/script/tsim/column/metrics.sim @@ -1,11 +1,6 @@ system sh/stop_dnodes.sh - - system sh/deploy.sh -n dnode1 -i 1 -system sh/cfg.sh -n dnode1 -c walLevel -v 1 system sh/exec.sh -n dnode1 -s start - -sleep 2000 sql connect print =============== step1 @@ -26,7 +21,6 @@ if $rows != 1 then endi print =============== step2 - sql insert into d2.t1 values (now,0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ) sql insert into d2.t1 values (now+1m,1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 ) sql insert into d2.t1 values (now+2m,2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 ) @@ -58,7 +52,6 @@ sql insert into d2.t2 values (now+8m,8 , 8 , 8 , 8 , 8 , 8 , 8 , 8 , 8 , 8 , 8 , sql insert into d2.t2 values (now+9m,9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 ) print =============== step3 - sql select * from d2.mt if $rows != 20 then return -1 @@ -157,12 +150,9 @@ endi print =============== step4 system sh/exec.sh -n dnode1 -s stop -x SIGINT -sleep 3000 system sh/exec.sh -n dnode1 -s start -sleep 3000 print =============== step5 - sql select * from d2.mt if $rows != 20 then return -1 diff --git a/tests/script/general/column/table.sim b/tests/script/tsim/column/table.sim similarity index 99% rename from tests/script/general/column/table.sim rename to tests/script/tsim/column/table.sim index 46d5de1e82..07948ebce3 100644 --- a/tests/script/general/column/table.sim +++ b/tests/script/tsim/column/table.sim @@ -1,11 +1,6 @@ system sh/stop_dnodes.sh - - system sh/deploy.sh -n dnode1 -i 1 -system sh/cfg.sh -n dnode1 -c walLevel -v 1 system sh/exec.sh -n dnode1 -s start - -sleep 2000 sql connect print =============== step1 @@ -19,7 +14,6 @@ if $rows != 1 then endi print =============== step2 - sql insert into d1.t1 values (now,0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ) sql insert into d1.t1 values (now+1m,1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 , 1 ) sql insert into d1.t1 values (now+2m,2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 , 2 ) @@ -36,7 +30,6 @@ sql insert into d1.t1 values (now+8m,8 , 8 , 8 , 8 , 8 , 8 , 8 , 8 , 8 , 8 , 8 , sql insert into d1.t1 values (now+9m,9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 , 9 ) print ======= step3 - sql select * from d1.t1 print select * from d1.t1 => rows $rows if $rows != 10 then @@ -129,9 +122,7 @@ endi print =============== step4 system sh/exec.sh -n dnode1 -s stop -x SIGINT -sleep 3000 system sh/exec.sh -n dnode1 -s start -sleep 3000 print ============== step5 -- GitLab From 43b5ca1efe1d4c12ee63b203a96a01246eb9ade5 Mon Sep 17 00:00:00 2001 From: Xiaoyu Wang Date: Wed, 13 Jul 2022 15:13:01 +0800 Subject: [PATCH 050/153] feat: support pseudo columns such as _qstart, _qend and _qduration --- examples/c/stream_demo.c | 8 +- include/common/ttokendef.h | 115 +- include/libs/function/functionMgt.h | 11 +- include/libs/nodes/querynodes.h | 2 +- source/libs/executor/src/executorimpl.c | 8 +- source/libs/executor/src/timewindowoperator.c | 6 +- source/libs/function/src/builtins.c | 34 +- source/libs/function/src/functionMgt.c | 4 +- source/libs/nodes/src/nodesUtilFuncs.c | 21 +- source/libs/parser/inc/sql.y | 13 +- source/libs/parser/src/parAstCreater.c | 2 +- source/libs/parser/src/parTokenizer.c | 9 +- source/libs/parser/src/parTranslater.c | 8 +- source/libs/parser/src/parUtil.c | 2 +- source/libs/parser/src/sql.c | 4798 +++++++++-------- source/libs/parser/test/parSelectTest.cpp | 8 +- source/libs/planner/src/planLogicCreater.c | 2 +- source/libs/planner/src/planOptimizer.c | 17 +- source/libs/planner/src/planSpliter.c | 8 +- source/libs/planner/test/planBasicTest.cpp | 6 + source/libs/planner/test/planIntervalTest.cpp | 6 +- source/libs/planner/test/planOptimizeTest.cpp | 2 +- source/libs/planner/test/planOtherTest.cpp | 2 +- tests/pytest/stream/test1.py | 2 +- tests/pytest/stream/test2.py | 8 +- tests/script/tsim/query/interval-offset.sim | 20 +- tests/script/tsim/query/interval.sim | 4 +- tests/script/tsim/query/session.sim | 30 +- tests/script/tsim/query/stddev.sim | 32 +- .../script/tsim/sma/tsmaCreateInsertQuery.sim | 8 +- tests/script/tsim/stream/basic0.sim | 8 +- tests/script/tsim/stream/basic1.sim | 16 +- tests/script/tsim/stream/basic2.sim | 6 +- .../tsim/stream/distributeInterval0.sim | 6 +- .../stream/distributeIntervalRetrive0.sim | 2 +- .../script/tsim/stream/distributeSession0.sim | 2 +- .../script/tsim/stream/ignoreExpiredData.sim | 10 +- tests/script/tsim/stream/partitionby.sim | 6 +- tests/script/tsim/stream/partitionby1.sim | 6 +- tests/script/tsim/stream/schedSnode.sim | 4 +- tests/script/tsim/stream/session0.sim | 18 +- tests/script/tsim/stream/session1.sim | 2 +- tests/script/tsim/stream/state0.sim | 14 +- tests/script/tsim/stream/triggerInterval0.sim | 2 +- tests/script/tsim/stream/triggerSession0.sim | 2 +- tests/script/tsim/stream/windowClose.sim | 2 +- tests/script/tsim/vnode/stable_dnode2.sim | 10 +- .../script/tsim/vnode/stable_dnode2_stop.sim | 4 +- tests/script/tsim/vnode/stable_dnode3.sim | 10 +- .../tsim/vnode/stable_replica3_dnode6.sim | 10 +- .../tsim/vnode/stable_replica3_vnode3.sim | 10 +- 51 files changed, 2704 insertions(+), 2642 deletions(-) diff --git a/examples/c/stream_demo.c b/examples/c/stream_demo.c index 1e9058d628..dd4fbc8d2d 100644 --- a/examples/c/stream_demo.c +++ b/examples/c/stream_demo.c @@ -98,10 +98,10 @@ int32_t create_stream() { /*const char* sql = "select min(k), max(k), sum(k) as sum_of_k from st1";*/ /*const char* sql = "select sum(k) from tu1 interval(10m)";*/ /*pRes = tmq_create_stream(pConn, "stream1", "out1", sql);*/ - pRes = taos_query( - pConn, - "create stream stream1 trigger max_delay 10s into outstb as select _wstartts, sum(k) from st1 partition " - "by tbname session(ts, 10s) "); + pRes = + taos_query(pConn, + "create stream stream1 trigger max_delay 10s into outstb as select _wstart, sum(k) from st1 partition " + "by tbname session(ts, 10s) "); if (taos_errno(pRes) != 0) { printf("failed to create stream stream1, reason:%s\n", taos_errstr(pRes)); return -1; diff --git a/include/common/ttokendef.h b/include/common/ttokendef.h index 29dd4daa25..e2089f3023 100644 --- a/include/common/ttokendef.h +++ b/include/common/ttokendef.h @@ -213,63 +213,64 @@ #define TK_NK_ARROW 195 #define TK_ROWTS 196 #define TK_TBNAME 197 -#define TK_QSTARTTS 198 -#define TK_QENDTS 199 -#define TK_WSTARTTS 200 -#define TK_WENDTS 201 -#define TK_WDURATION 202 -#define TK_CAST 203 -#define TK_NOW 204 -#define TK_TODAY 205 -#define TK_TIMEZONE 206 -#define TK_CLIENT_VERSION 207 -#define TK_SERVER_VERSION 208 -#define TK_SERVER_STATUS 209 -#define TK_CURRENT_USER 210 -#define TK_COUNT 211 -#define TK_LAST_ROW 212 -#define TK_BETWEEN 213 -#define TK_IS 214 -#define TK_NK_LT 215 -#define TK_NK_GT 216 -#define TK_NK_LE 217 -#define TK_NK_GE 218 -#define TK_NK_NE 219 -#define TK_MATCH 220 -#define TK_NMATCH 221 -#define TK_CONTAINS 222 -#define TK_JOIN 223 -#define TK_INNER 224 -#define TK_SELECT 225 -#define TK_DISTINCT 226 -#define TK_WHERE 227 -#define TK_PARTITION 228 -#define TK_BY 229 -#define TK_SESSION 230 -#define TK_STATE_WINDOW 231 -#define TK_SLIDING 232 -#define TK_FILL 233 -#define TK_VALUE 234 -#define TK_NONE 235 -#define TK_PREV 236 -#define TK_LINEAR 237 -#define TK_NEXT 238 -#define TK_HAVING 239 -#define TK_RANGE 240 -#define TK_EVERY 241 -#define TK_ORDER 242 -#define TK_SLIMIT 243 -#define TK_SOFFSET 244 -#define TK_LIMIT 245 -#define TK_OFFSET 246 -#define TK_ASC 247 -#define TK_NULLS 248 -#define TK_ID 249 -#define TK_NK_BITNOT 250 -#define TK_VALUES 251 -#define TK_IMPORT 252 -#define TK_NK_SEMI 253 -#define TK_FILE 254 +#define TK_QSTART 198 +#define TK_QEND 199 +#define TK_QDURATION 200 +#define TK_WSTART 201 +#define TK_WEND 202 +#define TK_WDURATION 203 +#define TK_CAST 204 +#define TK_NOW 205 +#define TK_TODAY 206 +#define TK_TIMEZONE 207 +#define TK_CLIENT_VERSION 208 +#define TK_SERVER_VERSION 209 +#define TK_SERVER_STATUS 210 +#define TK_CURRENT_USER 211 +#define TK_COUNT 212 +#define TK_LAST_ROW 213 +#define TK_BETWEEN 214 +#define TK_IS 215 +#define TK_NK_LT 216 +#define TK_NK_GT 217 +#define TK_NK_LE 218 +#define TK_NK_GE 219 +#define TK_NK_NE 220 +#define TK_MATCH 221 +#define TK_NMATCH 222 +#define TK_CONTAINS 223 +#define TK_JOIN 224 +#define TK_INNER 225 +#define TK_SELECT 226 +#define TK_DISTINCT 227 +#define TK_WHERE 228 +#define TK_PARTITION 229 +#define TK_BY 230 +#define TK_SESSION 231 +#define TK_STATE_WINDOW 232 +#define TK_SLIDING 233 +#define TK_FILL 234 +#define TK_VALUE 235 +#define TK_NONE 236 +#define TK_PREV 237 +#define TK_LINEAR 238 +#define TK_NEXT 239 +#define TK_HAVING 240 +#define TK_RANGE 241 +#define TK_EVERY 242 +#define TK_ORDER 243 +#define TK_SLIMIT 244 +#define TK_SOFFSET 245 +#define TK_LIMIT 246 +#define TK_OFFSET 247 +#define TK_ASC 248 +#define TK_NULLS 249 +#define TK_ID 250 +#define TK_NK_BITNOT 251 +#define TK_VALUES 252 +#define TK_IMPORT 253 +#define TK_NK_SEMI 254 +#define TK_FILE 255 #define TK_NK_SPACE 300 #define TK_NK_COMMENT 301 diff --git a/include/libs/function/functionMgt.h b/include/libs/function/functionMgt.h index 1012161d0e..6af7fca10f 100644 --- a/include/libs/function/functionMgt.h +++ b/include/libs/function/functionMgt.h @@ -34,7 +34,7 @@ typedef enum EFunctionType { FUNCTION_TYPE_ELAPSED, FUNCTION_TYPE_IRATE, FUNCTION_TYPE_LAST_ROW, - FUNCTION_TYPE_LAST_ROWT, //TODO: removed + FUNCTION_TYPE_LAST_ROWT, // TODO: removed FUNCTION_TYPE_MAX, FUNCTION_TYPE_MIN, FUNCTION_TYPE_MODE, @@ -114,10 +114,11 @@ typedef enum EFunctionType { // pseudo column function FUNCTION_TYPE_ROWTS = 3500, FUNCTION_TYPE_TBNAME, - FUNCTION_TYPE_QSTARTTS, - FUNCTION_TYPE_QENDTS, - FUNCTION_TYPE_WSTARTTS, - FUNCTION_TYPE_WENDTS, + FUNCTION_TYPE_QSTART, + FUNCTION_TYPE_QEND, + FUNCTION_TYPE_QDURATION, + FUNCTION_TYPE_WSTART, + FUNCTION_TYPE_WEND, FUNCTION_TYPE_WDURATION, // internal function diff --git a/include/libs/nodes/querynodes.h b/include/libs/nodes/querynodes.h index bbff34c66f..49db69c7c7 100644 --- a/include/libs/nodes/querynodes.h +++ b/include/libs/nodes/querynodes.h @@ -228,7 +228,7 @@ typedef struct SFillNode { ENodeType type; // QUERY_NODE_FILL EFillMode mode; SNode* pValues; // SNodeListNode - SNode* pWStartTs; // _wstartts pseudo column + SNode* pWStartTs; // _wstart pseudo column STimeWindow timeRange; } SFillNode; diff --git a/source/libs/executor/src/executorimpl.c b/source/libs/executor/src/executorimpl.c index ac80432052..1ba47db356 100644 --- a/source/libs/executor/src/executorimpl.c +++ b/source/libs/executor/src/executorimpl.c @@ -1479,8 +1479,8 @@ int32_t finalizeResultRowIntoResultDataBlock(SDiskbasedBuf* pBuf, SResultRowPosi } else if (strcmp(pCtx[j].pExpr->pExpr->_function.functionName, "_select_value") == 0) { // do nothing, todo refactor } else { - // expand the result into multiple rows. E.g., _wstartts, top(k, 20) - // the _wstartts needs to copy to 20 following rows, since the results of top-k expands to 20 different rows. + // expand the result into multiple rows. E.g., _wstart, top(k, 20) + // the _wstart needs to copy to 20 following rows, since the results of top-k expands to 20 different rows. SColumnInfoData* pColInfoData = taosArrayGet(pBlock->pDataBlock, slotId); char* in = GET_ROWCELL_INTERBUF(pCtx[j].resultInfo); for (int32_t k = 0; k < pRow->numOfRows; ++k) { @@ -1551,8 +1551,8 @@ int32_t doCopyToSDataBlock(SExecTaskInfo* pTaskInfo, SSDataBlock* pBlock, SExprI } else if (strcmp(pCtx[j].pExpr->pExpr->_function.functionName, "_select_value") == 0) { // do nothing, todo refactor } else { - // expand the result into multiple rows. E.g., _wstartts, top(k, 20) - // the _wstartts needs to copy to 20 following rows, since the results of top-k expands to 20 different rows. + // expand the result into multiple rows. E.g., _wstart, top(k, 20) + // the _wstart needs to copy to 20 following rows, since the results of top-k expands to 20 different rows. SColumnInfoData* pColInfoData = taosArrayGet(pBlock->pDataBlock, slotId); char* in = GET_ROWCELL_INTERBUF(pCtx[j].resultInfo); if (pCtx[j].increase) { diff --git a/source/libs/executor/src/timewindowoperator.c b/source/libs/executor/src/timewindowoperator.c index 78775073a4..5161d26e4b 100644 --- a/source/libs/executor/src/timewindowoperator.c +++ b/source/libs/executor/src/timewindowoperator.c @@ -1579,7 +1579,7 @@ static bool timeWindowinterpNeeded(SqlFunctionCtx* pCtx, int32_t numOfCols, SInt } void increaseTs(SqlFunctionCtx* pCtx) { - if (pCtx[0].pExpr->pExpr->_function.pFunctNode->funcType == FUNCTION_TYPE_WSTARTTS) { + if (pCtx[0].pExpr->pExpr->_function.pFunctNode->funcType == FUNCTION_TYPE_WSTART) { pCtx[0].increase = true; } } @@ -2491,8 +2491,8 @@ static void doHashInterval(SOperatorInfo* pOperatorInfo, SSDataBlock* pSDataBloc if (IS_FINAL_OP(pInfo)) { forwardRows = 1; } else { - forwardRows = getNumOfRowsInTimeWindow(&pSDataBlock->info, tsCols, startPos, nextWin.ekey, binarySearchForKey, NULL, - TSDB_ORDER_ASC); + forwardRows = getNumOfRowsInTimeWindow(&pSDataBlock->info, tsCols, startPos, nextWin.ekey, binarySearchForKey, + NULL, TSDB_ORDER_ASC); } if (pInfo->twAggSup.calTrigger == STREAM_TRIGGER_AT_ONCE && pUpdated) { saveResultRow(pResult, tableGroupId, pUpdated); diff --git a/source/libs/function/src/builtins.c b/source/libs/function/src/builtins.c index f4dadbf5d0..2b617be55b 100644 --- a/source/libs/function/src/builtins.c +++ b/source/libs/function/src/builtins.c @@ -2784,28 +2784,38 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = { .finalizeFunc = NULL }, { - .name = "_qstartts", - .type = FUNCTION_TYPE_QSTARTTS, - .classification = FUNC_MGT_PSEUDO_COLUMN_FUNC | FUNC_MGT_WINDOW_PC_FUNC, + .name = "_qstart", + .type = FUNCTION_TYPE_QSTART, + .classification = FUNC_MGT_PSEUDO_COLUMN_FUNC | FUNC_MGT_SCAN_PC_FUNC, .translateFunc = translateTimePseudoColumn, .getEnvFunc = getTimePseudoFuncEnv, .initFunc = NULL, - .sprocessFunc = qStartTsFunction, + .sprocessFunc = qStartTsFunction, // todo .finalizeFunc = NULL }, { - .name = "_qendts", - .type = FUNCTION_TYPE_QENDTS, - .classification = FUNC_MGT_PSEUDO_COLUMN_FUNC | FUNC_MGT_WINDOW_PC_FUNC, + .name = "_qend", + .type = FUNCTION_TYPE_QEND, + .classification = FUNC_MGT_PSEUDO_COLUMN_FUNC | FUNC_MGT_SCAN_PC_FUNC, .translateFunc = translateTimePseudoColumn, .getEnvFunc = getTimePseudoFuncEnv, .initFunc = NULL, - .sprocessFunc = qEndTsFunction, + .sprocessFunc = qEndTsFunction, // todo + .finalizeFunc = NULL + }, + { + .name = "_qduration", + .type = FUNCTION_TYPE_QDURATION, + .classification = FUNC_MGT_PSEUDO_COLUMN_FUNC | FUNC_MGT_SCAN_PC_FUNC, + .translateFunc = translateWduration, + .getEnvFunc = getTimePseudoFuncEnv, + .initFunc = NULL, + .sprocessFunc = winDurFunction, // todo .finalizeFunc = NULL }, { - .name = "_wstartts", - .type = FUNCTION_TYPE_WSTARTTS, + .name = "_wstart", + .type = FUNCTION_TYPE_WSTART, .classification = FUNC_MGT_PSEUDO_COLUMN_FUNC | FUNC_MGT_WINDOW_PC_FUNC, .translateFunc = translateTimePseudoColumn, .getEnvFunc = getTimePseudoFuncEnv, @@ -2814,8 +2824,8 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = { .finalizeFunc = NULL }, { - .name = "_wendts", - .type = FUNCTION_TYPE_WENDTS, + .name = "_wend", + .type = FUNCTION_TYPE_WEND, .classification = FUNC_MGT_PSEUDO_COLUMN_FUNC | FUNC_MGT_WINDOW_PC_FUNC, .translateFunc = translateTimePseudoColumn, .getEnvFunc = getTimePseudoFuncEnv, diff --git a/source/libs/function/src/functionMgt.c b/source/libs/function/src/functionMgt.c index ed82654f77..c003f917b5 100644 --- a/source/libs/function/src/functionMgt.c +++ b/source/libs/function/src/functionMgt.c @@ -227,8 +227,8 @@ bool fmIsInvertible(int32_t funcId) { case FUNCTION_TYPE_SUM: case FUNCTION_TYPE_STDDEV: case FUNCTION_TYPE_AVG: - case FUNCTION_TYPE_WSTARTTS: - case FUNCTION_TYPE_WENDTS: + case FUNCTION_TYPE_WSTART: + case FUNCTION_TYPE_WEND: case FUNCTION_TYPE_WDURATION: res = true; break; diff --git a/source/libs/nodes/src/nodesUtilFuncs.c b/source/libs/nodes/src/nodesUtilFuncs.c index 4abb8f5c2c..9b754c92d0 100644 --- a/source/libs/nodes/src/nodesUtilFuncs.c +++ b/source/libs/nodes/src/nodesUtilFuncs.c @@ -956,7 +956,6 @@ void nodesDestroyNode(SNode* pNode) { } case QUERY_NODE_PHYSICAL_SUBPLAN: { SSubplan* pSubplan = (SSubplan*)pNode; - // nodesDestroyList(pSubplan->pChildren); nodesClearList(pSubplan->pChildren); nodesDestroyNode((SNode*)pSubplan->pNode); nodesDestroyNode((SNode*)pSubplan->pDataSink); @@ -965,25 +964,9 @@ void nodesDestroyNode(SNode* pNode) { nodesClearList(pSubplan->pParents); break; } - case QUERY_NODE_PHYSICAL_PLAN: { - SQueryPlan* pPlan = (SQueryPlan*)pNode; - if (NULL != pPlan->pSubplans) { - // only need to destroy the top-level subplans, because they will recurse to all the subplans below - bool first = true; - SNode* pElement = NULL; - FOREACH(pElement, pPlan->pSubplans) { - if (first) { - // first = false; - nodesDestroyNode(pElement); - } else { - nodesClearList(((SNodeListNode*)pElement)->pNodeList); - taosMemoryFreeClear(pElement); - } - } - nodesClearList(pPlan->pSubplans); - } + case QUERY_NODE_PHYSICAL_PLAN: + nodesDestroyList(((SQueryPlan*)pNode)->pSubplans); break; - } default: break; } diff --git a/source/libs/parser/inc/sql.y b/source/libs/parser/inc/sql.y index 606d35a65b..ddde20e8e9 100644 --- a/source/libs/parser/inc/sql.y +++ b/source/libs/parser/inc/sql.y @@ -520,7 +520,9 @@ cmd ::= DELETE FROM full_table_name(A) where_clause_opt(B). cmd ::= query_expression(A). { pCxt->pRootNode = A; } /************************************************ insert **************************************************************/ -cmd ::= INSERT INTO full_table_name(A) specific_cols_opt(B) query_expression(C). { pCxt->pRootNode = createInsertStmt(pCxt, A, B, C); } +cmd ::= INSERT INTO full_table_name(A) + NK_LP col_name_list(B) NK_RP query_expression(C). { pCxt->pRootNode = createInsertStmt(pCxt, A, B, C); } +cmd ::= INSERT INTO full_table_name(A) query_expression(B). { pCxt->pRootNode = createInsertStmt(pCxt, A, NULL, B); } /************************************************ literal *************************************************************/ literal(A) ::= NK_INTEGER(B). { A = createRawExprNode(pCxt, &B, createValueNode(pCxt, TSDB_DATA_TYPE_BIGINT, &B)); } @@ -675,10 +677,11 @@ column_reference(A) ::= table_name(B) NK_DOT column_name(C). pseudo_column(A) ::= ROWTS(B). { A = createRawExprNode(pCxt, &B, createFunctionNode(pCxt, &B, NULL)); } pseudo_column(A) ::= TBNAME(B). { A = createRawExprNode(pCxt, &B, createFunctionNode(pCxt, &B, NULL)); } pseudo_column(A) ::= table_name(B) NK_DOT TBNAME(C). { A = createRawExprNodeExt(pCxt, &B, &C, createFunctionNode(pCxt, &C, createNodeList(pCxt, createValueNode(pCxt, TSDB_DATA_TYPE_BINARY, &B)))); } -pseudo_column(A) ::= QSTARTTS(B). { A = createRawExprNode(pCxt, &B, createFunctionNode(pCxt, &B, NULL)); } -pseudo_column(A) ::= QENDTS(B). { A = createRawExprNode(pCxt, &B, createFunctionNode(pCxt, &B, NULL)); } -pseudo_column(A) ::= WSTARTTS(B). { A = createRawExprNode(pCxt, &B, createFunctionNode(pCxt, &B, NULL)); } -pseudo_column(A) ::= WENDTS(B). { A = createRawExprNode(pCxt, &B, createFunctionNode(pCxt, &B, NULL)); } +pseudo_column(A) ::= QSTART(B). { A = createRawExprNode(pCxt, &B, createFunctionNode(pCxt, &B, NULL)); } +pseudo_column(A) ::= QEND(B). { A = createRawExprNode(pCxt, &B, createFunctionNode(pCxt, &B, NULL)); } +pseudo_column(A) ::= QDURATION(B). { A = createRawExprNode(pCxt, &B, createFunctionNode(pCxt, &B, NULL)); } +pseudo_column(A) ::= WSTART(B). { A = createRawExprNode(pCxt, &B, createFunctionNode(pCxt, &B, NULL)); } +pseudo_column(A) ::= WEND(B). { A = createRawExprNode(pCxt, &B, createFunctionNode(pCxt, &B, NULL)); } pseudo_column(A) ::= WDURATION(B). { A = createRawExprNode(pCxt, &B, createFunctionNode(pCxt, &B, NULL)); } function_expression(A) ::= function_name(B) NK_LP expression_list(C) NK_RP(D). { A = createRawExprNodeExt(pCxt, &B, &D, createFunctionNode(pCxt, &B, C)); } diff --git a/source/libs/parser/src/parAstCreater.c b/source/libs/parser/src/parAstCreater.c index c60e5541e0..ca0ab7f42e 100644 --- a/source/libs/parser/src/parAstCreater.c +++ b/source/libs/parser/src/parAstCreater.c @@ -598,7 +598,7 @@ SNode* createFillNode(SAstCreateContext* pCxt, EFillMode mode, SNode* pValues) { nodesDestroyNode((SNode*)fill); CHECK_OUT_OF_MEM(fill->pWStartTs); } - strcpy(((SFunctionNode*)fill->pWStartTs)->functionName, "_wstartts"); + strcpy(((SFunctionNode*)fill->pWStartTs)->functionName, "_wstart"); return (SNode*)fill; } diff --git a/source/libs/parser/src/parTokenizer.c b/source/libs/parser/src/parTokenizer.c index 58f6354402..0d176cef09 100644 --- a/source/libs/parser/src/parTokenizer.c +++ b/source/libs/parser/src/parTokenizer.c @@ -240,12 +240,13 @@ static SKeyword keywordTable[] = { {"WITH", TK_WITH}, {"WRITE", TK_WRITE}, {"_C0", TK_ROWTS}, - {"_QENDTS", TK_QENDTS}, - {"_QSTARTTS", TK_QSTARTTS}, + {"_QDURATION", TK_QDURATION}, + {"_QEND", TK_QEND}, + {"_QSTART", TK_QSTART}, {"_ROWTS", TK_ROWTS}, {"_WDURATION", TK_WDURATION}, - {"_WENDTS", TK_WENDTS}, - {"_WSTARTTS", TK_WSTARTTS}, + {"_WEND", TK_WEND}, + {"_WSTART", TK_WSTART}, // {"ID", TK_ID}, // {"STRING", TK_STRING}, // {"EQ", TK_EQ}, diff --git a/source/libs/parser/src/parTranslater.c b/source/libs/parser/src/parTranslater.c index ca000fcf2d..6b7bf3af26 100644 --- a/source/libs/parser/src/parTranslater.c +++ b/source/libs/parser/src/parTranslater.c @@ -496,7 +496,7 @@ static bool isPrimaryKeyImpl(SNode* pExpr) { SFunctionNode* pFunc = (SFunctionNode*)pExpr; if (FUNCTION_TYPE_SELECT_VALUE == pFunc->funcType) { return isPrimaryKeyImpl(nodesListGetNode(pFunc->pParameterList, 0)); - } else if (FUNCTION_TYPE_WSTARTTS == pFunc->funcType || FUNCTION_TYPE_WENDTS == pFunc->funcType) { + } else if (FUNCTION_TYPE_WSTART == pFunc->funcType || FUNCTION_TYPE_WEND == pFunc->funcType) { return true; } } @@ -3508,7 +3508,7 @@ static int32_t buildSampleAst(STranslateContext* pCxt, SSampleAstInfo* pInfo, ch nodesDestroyNode((SNode*)pSelect); return TSDB_CODE_OUT_OF_MEMORY; } - strcpy(pFunc->functionName, "_wstartts"); + strcpy(pFunc->functionName, "_wstart"); nodesListPushFront(pSelect->pProjectionList, (SNode*)pFunc); SNode* pProject = NULL; FOREACH(pProject, pSelect->pProjectionList) { sprintf(((SExprNode*)pProject)->aliasName, "#%p", pProject); } @@ -4334,14 +4334,14 @@ static int32_t addWstartTsToCreateStreamQuery(SNode* pStmt) { SSelectStmt* pSelect = (SSelectStmt*)pStmt; SNode* pProj = nodesListGetNode(pSelect->pProjectionList, 0); if (NULL == pSelect->pWindow || - (QUERY_NODE_FUNCTION == nodeType(pProj) && 0 == strcmp("_wstartts", ((SFunctionNode*)pProj)->functionName))) { + (QUERY_NODE_FUNCTION == nodeType(pProj) && 0 == strcmp("_wstart", ((SFunctionNode*)pProj)->functionName))) { return TSDB_CODE_SUCCESS; } SFunctionNode* pFunc = (SFunctionNode*)nodesMakeNode(QUERY_NODE_FUNCTION); if (NULL == pFunc) { return TSDB_CODE_OUT_OF_MEMORY; } - strcpy(pFunc->functionName, "_wstartts"); + strcpy(pFunc->functionName, "_wstart"); strcpy(pFunc->node.aliasName, pFunc->functionName); int32_t code = nodesListPushFront(pSelect->pProjectionList, (SNode*)pFunc); if (TSDB_CODE_SUCCESS != code) { diff --git a/source/libs/parser/src/parUtil.c b/source/libs/parser/src/parUtil.c index dedd9cabfc..3484fa61c7 100644 --- a/source/libs/parser/src/parUtil.c +++ b/source/libs/parser/src/parUtil.c @@ -187,7 +187,7 @@ static char* getSyntaxErrFormat(int32_t errCode) { case TSDB_CODE_PAR_FILL_NOT_ALLOWED_FUNC: return "%s function is not supported in fill query"; case TSDB_CODE_PAR_INVALID_WINDOW_PC: - return "_WSTARTTS, _WENDTS and _WDURATION can only be used in window query"; + return "_WSTART, _WEND and _WDURATION can only be used in window query"; case TSDB_CODE_PAR_WINDOW_NOT_ALLOWED_FUNC: return "%s function is not supported in time window query"; case TSDB_CODE_PAR_STREAM_NOT_ALLOWED_FUNC: diff --git a/source/libs/parser/src/sql.c b/source/libs/parser/src/sql.c index d01050ceeb..2200b43db1 100644 --- a/source/libs/parser/src/sql.c +++ b/source/libs/parser/src/sql.c @@ -104,26 +104,26 @@ #endif /************* Begin control #defines *****************************************/ #define YYCODETYPE unsigned short int -#define YYNOCODE 378 +#define YYNOCODE 379 #define YYACTIONTYPE unsigned short int #define ParseTOKENTYPE SToken typedef union { int yyinit; ParseTOKENTYPE yy0; - EFillMode yy18; - EJoinType yy36; - ENullOrder yy109; - EOperatorType yy128; - bool yy173; - SDataType yy196; - EOrder yy218; - SAlterOption yy389; - int32_t yy424; - SToken yy533; - SNode* yy560; - int64_t yy585; - SNodeList* yy712; - int8_t yy719; + EOrder yy58; + bool yy151; + int8_t yy285; + SNodeList* yy356; + SToken yy361; + SAlterOption yy409; + int64_t yy457; + EFillMode yy494; + EJoinType yy504; + EOperatorType yy526; + SDataType yy600; + ENullOrder yy613; + SNode* yy616; + int32_t yy734; } YYMINORTYPE; #ifndef YYSTACKDEPTH #define YYSTACKDEPTH 100 @@ -139,17 +139,17 @@ typedef union { #define ParseCTX_FETCH #define ParseCTX_STORE #define YYFALLBACK 1 -#define YYNSTATE 666 -#define YYNRULE 489 -#define YYNTOKEN 255 -#define YY_MAX_SHIFT 665 -#define YY_MIN_SHIFTREDUCE 970 -#define YY_MAX_SHIFTREDUCE 1458 -#define YY_ERROR_ACTION 1459 -#define YY_ACCEPT_ACTION 1460 -#define YY_NO_ACTION 1461 -#define YY_MIN_REDUCE 1462 -#define YY_MAX_REDUCE 1950 +#define YYNSTATE 669 +#define YYNRULE 491 +#define YYNTOKEN 256 +#define YY_MAX_SHIFT 668 +#define YY_MIN_SHIFTREDUCE 974 +#define YY_MAX_SHIFTREDUCE 1464 +#define YY_ERROR_ACTION 1465 +#define YY_ACCEPT_ACTION 1466 +#define YY_NO_ACTION 1467 +#define YY_MIN_REDUCE 1468 +#define YY_MAX_REDUCE 1958 /************* End control #defines *******************************************/ #define YY_NLOOKAHEAD ((int)(sizeof(yy_lookahead)/sizeof(yy_lookahead[0]))) @@ -216,648 +216,694 @@ typedef union { ** yy_default[] Default action for each state. ** *********** Begin parsing tables **********************************************/ -#define YY_ACTTAB_COUNT (2318) +#define YY_ACTTAB_COUNT (2547) static const YYACTIONTYPE yy_action[] = { - /* 0 */ 529, 1700, 433, 552, 434, 1497, 441, 1589, 434, 1497, - /* 10 */ 1772, 113, 39, 37, 386, 62, 517, 1585, 471, 380, - /* 20 */ 338, 1768, 1259, 1003, 324, 79, 1785, 1697, 1600, 30, - /* 30 */ 260, 122, 143, 1335, 103, 1257, 1556, 102, 101, 100, - /* 40 */ 99, 98, 97, 96, 95, 94, 1593, 1764, 1770, 327, - /* 50 */ 71, 302, 557, 1928, 1803, 555, 1330, 1514, 1285, 574, - /* 60 */ 1928, 14, 581, 1007, 1008, 500, 1927, 1754, 1265, 580, - /* 70 */ 1925, 120, 1596, 159, 39, 37, 1398, 1925, 498, 487, - /* 80 */ 496, 529, 338, 557, 1259, 1, 250, 1870, 551, 1020, - /* 90 */ 550, 1019, 164, 1928, 1816, 1335, 61, 1257, 89, 1786, - /* 100 */ 583, 1788, 1789, 579, 469, 574, 161, 662, 1862, 1600, - /* 110 */ 1925, 343, 305, 1858, 1645, 1647, 71, 61, 1330, 1021, - /* 120 */ 43, 1337, 1338, 14, 1928, 1463, 1928, 33, 32, 117, - /* 130 */ 1265, 40, 38, 36, 35, 34, 475, 161, 1595, 160, - /* 140 */ 142, 1925, 1474, 1925, 1485, 1785, 103, 2, 214, 102, - /* 150 */ 101, 100, 99, 98, 97, 96, 95, 94, 474, 1156, - /* 160 */ 1157, 486, 485, 484, 170, 1928, 1260, 483, 1258, 662, - /* 170 */ 118, 480, 325, 1803, 479, 478, 477, 1460, 1926, 74, - /* 180 */ 140, 556, 1925, 1337, 1338, 1754, 1754, 555, 580, 1602, - /* 190 */ 1646, 1647, 69, 1263, 1264, 68, 1313, 1314, 1316, 1317, - /* 200 */ 1318, 1319, 1320, 576, 572, 1328, 1329, 1331, 1332, 1333, - /* 210 */ 1334, 1336, 1339, 1816, 36, 35, 34, 90, 1786, 583, - /* 220 */ 1788, 1789, 579, 529, 574, 162, 371, 1862, 1260, 555, - /* 230 */ 1258, 329, 1858, 154, 113, 419, 162, 350, 1484, 33, - /* 240 */ 32, 476, 450, 40, 38, 36, 35, 34, 373, 369, - /* 250 */ 1285, 1600, 552, 1889, 1395, 1263, 1264, 162, 1313, 1314, - /* 260 */ 1316, 1317, 1318, 1319, 1320, 576, 572, 1328, 1329, 1331, - /* 270 */ 1332, 1333, 1334, 1336, 1339, 39, 37, 1455, 1928, 1754, - /* 280 */ 122, 174, 173, 338, 220, 1259, 40, 38, 36, 35, - /* 290 */ 34, 159, 306, 61, 42, 1925, 1335, 1741, 1257, 1114, - /* 300 */ 605, 604, 603, 1118, 602, 1120, 1121, 601, 1123, 598, - /* 310 */ 1803, 1129, 595, 1131, 1132, 592, 589, 1298, 545, 1330, - /* 320 */ 120, 1785, 33, 32, 14, 1357, 40, 38, 36, 35, - /* 330 */ 34, 1265, 39, 37, 554, 155, 1870, 1871, 86, 1875, - /* 340 */ 338, 552, 1259, 1772, 359, 1652, 1239, 1240, 2, 1803, - /* 350 */ 341, 119, 326, 1335, 1768, 1257, 544, 581, 140, 1592, - /* 360 */ 344, 1650, 1754, 529, 580, 1402, 1454, 1602, 140, 122, - /* 370 */ 662, 1284, 1284, 379, 165, 378, 1330, 1602, 557, 1358, - /* 380 */ 1764, 1770, 333, 1578, 1337, 1338, 1462, 432, 1265, 1816, - /* 390 */ 436, 1600, 574, 89, 1786, 583, 1788, 1789, 579, 1483, - /* 400 */ 574, 440, 1363, 1862, 436, 8, 215, 305, 1858, 120, - /* 410 */ 112, 111, 110, 109, 108, 107, 106, 105, 104, 1928, - /* 420 */ 482, 481, 632, 630, 156, 1870, 1871, 662, 1875, 1260, - /* 430 */ 208, 1258, 159, 162, 162, 61, 1925, 75, 516, 1482, - /* 440 */ 1754, 1337, 1338, 450, 29, 336, 1352, 1353, 1354, 1355, - /* 450 */ 1356, 1360, 1361, 1362, 1481, 315, 1263, 1264, 546, 1313, - /* 460 */ 1314, 1316, 1317, 1318, 1319, 1320, 576, 572, 1328, 1329, - /* 470 */ 1331, 1332, 1333, 1334, 1336, 1339, 1394, 33, 32, 1928, - /* 480 */ 1754, 40, 38, 36, 35, 34, 1260, 1359, 1258, 73, - /* 490 */ 304, 1652, 159, 519, 541, 1754, 1925, 33, 32, 348, - /* 500 */ 1286, 40, 38, 36, 35, 34, 316, 1651, 314, 313, - /* 510 */ 1364, 473, 616, 1263, 1264, 475, 1313, 1314, 1316, 1317, - /* 520 */ 1318, 1319, 1320, 576, 572, 1328, 1329, 1331, 1332, 1333, - /* 530 */ 1334, 1336, 1339, 39, 37, 1340, 438, 474, 1007, 1008, - /* 540 */ 1928, 338, 1282, 1259, 1785, 162, 1877, 1480, 1315, 1020, - /* 550 */ 306, 1019, 27, 159, 1335, 1429, 1257, 1925, 1591, 33, - /* 560 */ 32, 221, 222, 40, 38, 36, 35, 34, 1287, 1768, - /* 570 */ 1874, 552, 1803, 547, 542, 162, 1576, 1330, 1283, 1021, - /* 580 */ 556, 529, 529, 1357, 153, 1754, 1479, 580, 1754, 1265, - /* 590 */ 39, 37, 384, 385, 22, 1764, 1770, 1639, 338, 122, - /* 600 */ 1259, 1524, 1076, 11, 10, 140, 9, 574, 1652, 1600, - /* 610 */ 1600, 1335, 1816, 1257, 1603, 342, 90, 1786, 583, 1788, - /* 620 */ 1789, 579, 304, 574, 1650, 519, 1862, 1754, 662, 529, - /* 630 */ 329, 1858, 154, 252, 1330, 1078, 616, 1358, 1877, 120, - /* 640 */ 389, 1557, 1337, 1338, 158, 1345, 1265, 1696, 1690, 299, - /* 650 */ 517, 1284, 1888, 1265, 157, 1870, 1871, 1600, 1875, 172, - /* 660 */ 1363, 1698, 1873, 9, 639, 638, 637, 636, 346, 1587, - /* 670 */ 635, 634, 633, 123, 628, 627, 626, 625, 624, 623, - /* 680 */ 622, 621, 133, 617, 1527, 662, 1284, 1260, 1371, 1258, - /* 690 */ 33, 32, 1877, 1478, 40, 38, 36, 35, 34, 1337, - /* 700 */ 1338, 232, 29, 336, 1352, 1353, 1354, 1355, 1356, 1360, - /* 710 */ 1361, 1362, 7, 1477, 1263, 1264, 1872, 1313, 1314, 1316, - /* 720 */ 1317, 1318, 1319, 1320, 576, 572, 1328, 1329, 1331, 1332, - /* 730 */ 1333, 1334, 1336, 1339, 1754, 33, 32, 1882, 1391, 40, - /* 740 */ 38, 36, 35, 34, 1260, 561, 1258, 486, 485, 484, - /* 750 */ 44, 4, 1259, 483, 1754, 272, 118, 480, 1630, 608, - /* 760 */ 479, 478, 477, 1476, 619, 1257, 1419, 1695, 1409, 299, - /* 770 */ 612, 1263, 1264, 1643, 1313, 1314, 1316, 1317, 1318, 1319, - /* 780 */ 1320, 576, 572, 1328, 1329, 1331, 1332, 1333, 1334, 1336, - /* 790 */ 1339, 39, 37, 301, 613, 1282, 614, 1643, 1265, 338, - /* 800 */ 1583, 1259, 412, 1785, 1754, 424, 1268, 538, 1417, 1418, - /* 810 */ 1420, 1421, 1335, 1298, 1257, 131, 130, 611, 610, 609, - /* 820 */ 11, 10, 397, 529, 425, 211, 399, 631, 1315, 529, - /* 830 */ 529, 1803, 529, 1473, 404, 1330, 620, 662, 1572, 581, - /* 840 */ 405, 449, 26, 1597, 1754, 59, 580, 1265, 33, 32, - /* 850 */ 1509, 1600, 40, 38, 36, 35, 34, 1600, 1600, 390, - /* 860 */ 1600, 33, 32, 1315, 2, 40, 38, 36, 35, 34, - /* 870 */ 374, 1816, 489, 570, 1754, 91, 1786, 583, 1788, 1789, - /* 880 */ 579, 28, 574, 1457, 1458, 1862, 662, 33, 32, 1861, - /* 890 */ 1858, 40, 38, 36, 35, 34, 1260, 1391, 1258, 423, - /* 900 */ 1337, 1338, 418, 417, 416, 415, 414, 411, 410, 409, - /* 910 */ 408, 407, 403, 402, 401, 400, 394, 393, 392, 391, - /* 920 */ 575, 388, 387, 1263, 1264, 529, 564, 529, 1507, 141, - /* 930 */ 1472, 529, 199, 529, 278, 197, 1729, 201, 510, 1271, - /* 940 */ 200, 1047, 514, 194, 527, 1260, 562, 1258, 276, 58, - /* 950 */ 492, 203, 57, 1600, 202, 1600, 607, 146, 502, 1600, - /* 960 */ 509, 1600, 467, 463, 459, 455, 193, 1785, 177, 429, - /* 970 */ 427, 1754, 1263, 1264, 1048, 1313, 1314, 1316, 1317, 1318, - /* 980 */ 1319, 1320, 576, 572, 1328, 1329, 1331, 1332, 1333, 1334, - /* 990 */ 1336, 1339, 335, 334, 72, 1803, 61, 191, 529, 1928, - /* 1000 */ 529, 205, 1273, 581, 204, 1349, 139, 1475, 1754, 528, - /* 1010 */ 580, 261, 159, 1335, 1773, 1266, 1925, 52, 513, 529, - /* 1020 */ 255, 539, 85, 468, 1471, 1768, 1600, 1470, 1600, 1267, - /* 1030 */ 345, 1469, 82, 41, 88, 1816, 1330, 1577, 1468, 90, - /* 1040 */ 1786, 583, 1788, 1789, 579, 1785, 574, 1600, 1265, 1862, - /* 1050 */ 1467, 1764, 1770, 329, 1858, 1941, 1503, 503, 244, 190, - /* 1060 */ 183, 1575, 188, 574, 1896, 1754, 446, 1466, 1754, 66, - /* 1070 */ 65, 383, 1754, 1803, 169, 1465, 1207, 1804, 347, 1754, - /* 1080 */ 377, 581, 219, 125, 559, 181, 1754, 569, 580, 1775, - /* 1090 */ 1498, 1754, 1640, 300, 128, 129, 367, 50, 365, 361, - /* 1100 */ 357, 166, 352, 349, 657, 1892, 236, 50, 1754, 41, - /* 1110 */ 249, 553, 254, 1816, 257, 259, 1754, 90, 1786, 583, - /* 1120 */ 1788, 1789, 579, 1785, 574, 223, 522, 1862, 1777, 565, - /* 1130 */ 80, 329, 1858, 1941, 614, 3, 162, 229, 1107, 41, - /* 1140 */ 1416, 53, 1919, 5, 351, 1282, 1274, 354, 1269, 239, - /* 1150 */ 1365, 1803, 1321, 131, 130, 611, 610, 609, 614, 581, - /* 1160 */ 587, 128, 1270, 358, 1754, 1785, 580, 311, 1076, 129, - /* 1170 */ 114, 128, 312, 1277, 1279, 1223, 268, 131, 130, 611, - /* 1180 */ 610, 609, 271, 406, 572, 1328, 1329, 1331, 1332, 1333, - /* 1190 */ 1334, 1816, 1692, 1803, 171, 90, 1786, 583, 1788, 1789, - /* 1200 */ 579, 581, 574, 1135, 1139, 1862, 1754, 413, 580, 329, - /* 1210 */ 1858, 1941, 1146, 1144, 132, 421, 426, 420, 422, 428, - /* 1220 */ 1881, 430, 557, 1288, 431, 439, 1785, 180, 1291, 442, - /* 1230 */ 443, 182, 1290, 1816, 444, 1292, 1785, 285, 1786, 583, - /* 1240 */ 1788, 1789, 579, 445, 574, 491, 185, 447, 1289, 187, - /* 1250 */ 448, 189, 70, 451, 1803, 192, 470, 472, 1590, 196, - /* 1260 */ 501, 1586, 581, 1928, 1803, 303, 1734, 1754, 93, 580, - /* 1270 */ 198, 209, 581, 269, 207, 134, 161, 1754, 135, 580, - /* 1280 */ 1925, 1588, 504, 557, 1584, 136, 137, 508, 494, 505, - /* 1290 */ 212, 511, 488, 1785, 1816, 515, 216, 206, 285, 1786, - /* 1300 */ 583, 1788, 1789, 579, 1816, 574, 537, 1785, 91, 1786, - /* 1310 */ 583, 1788, 1789, 579, 126, 574, 518, 1733, 1862, 1702, - /* 1320 */ 321, 1803, 568, 1858, 1928, 56, 520, 523, 55, 578, - /* 1330 */ 323, 127, 524, 525, 1754, 1803, 580, 159, 225, 227, - /* 1340 */ 270, 1925, 1601, 581, 78, 1287, 533, 540, 1754, 535, - /* 1350 */ 580, 234, 1893, 1903, 536, 1902, 238, 1785, 328, 543, - /* 1360 */ 6, 1816, 1884, 549, 534, 293, 1786, 583, 1788, 1789, - /* 1370 */ 579, 577, 574, 571, 1834, 1816, 243, 1785, 148, 144, - /* 1380 */ 1786, 583, 1788, 1789, 579, 1803, 574, 532, 531, 248, - /* 1390 */ 1391, 245, 246, 581, 121, 247, 1286, 1878, 1754, 566, - /* 1400 */ 580, 563, 48, 330, 253, 1803, 1924, 1573, 1644, 273, - /* 1410 */ 322, 658, 585, 581, 560, 1944, 1843, 264, 1754, 661, - /* 1420 */ 580, 51, 659, 558, 1942, 1816, 147, 277, 256, 91, - /* 1430 */ 1786, 583, 1788, 1789, 579, 1748, 574, 286, 275, 1862, - /* 1440 */ 567, 258, 296, 1785, 1859, 1816, 63, 295, 1747, 294, - /* 1450 */ 1786, 583, 1788, 1789, 579, 1785, 574, 1746, 64, 1745, - /* 1460 */ 353, 1742, 355, 1251, 356, 1785, 1252, 167, 360, 1740, - /* 1470 */ 364, 1803, 362, 363, 1739, 366, 530, 1738, 368, 581, - /* 1480 */ 1737, 1736, 370, 1803, 1754, 1719, 580, 372, 168, 375, - /* 1490 */ 376, 581, 1226, 1803, 1225, 1713, 1754, 1712, 580, 381, - /* 1500 */ 382, 581, 1711, 1710, 1195, 1685, 1754, 1684, 580, 1683, - /* 1510 */ 67, 1816, 1682, 1681, 1680, 294, 1786, 583, 1788, 1789, - /* 1520 */ 579, 1785, 574, 1816, 1679, 1678, 396, 289, 1786, 583, - /* 1530 */ 1788, 1789, 579, 1816, 574, 1785, 395, 144, 1786, 583, - /* 1540 */ 1788, 1789, 579, 1677, 574, 398, 1676, 1675, 1674, 1803, - /* 1550 */ 124, 1662, 1661, 1660, 1659, 1658, 1657, 578, 1673, 1672, - /* 1560 */ 1671, 1670, 1754, 1803, 580, 548, 1669, 1668, 337, 1667, - /* 1570 */ 1666, 581, 1665, 1664, 1663, 1656, 1754, 1655, 580, 1197, - /* 1580 */ 1654, 1653, 1943, 1529, 175, 1528, 176, 1526, 1785, 1816, - /* 1590 */ 1494, 178, 1010, 293, 1786, 583, 1788, 1789, 579, 1493, - /* 1600 */ 574, 115, 1835, 1816, 179, 1009, 152, 294, 1786, 583, - /* 1610 */ 1788, 1789, 579, 665, 574, 453, 1803, 435, 116, 1727, - /* 1620 */ 1721, 339, 437, 1709, 581, 184, 1708, 267, 186, 1754, - /* 1630 */ 1785, 580, 1694, 1579, 1525, 1523, 452, 454, 1521, 456, - /* 1640 */ 457, 151, 1519, 460, 1785, 458, 655, 651, 647, 643, - /* 1650 */ 265, 1040, 461, 462, 1517, 466, 1816, 464, 1803, 465, - /* 1660 */ 294, 1786, 583, 1788, 1789, 579, 581, 574, 1506, 1505, - /* 1670 */ 1490, 1754, 1803, 580, 1581, 1150, 49, 1149, 87, 1580, - /* 1680 */ 581, 230, 1075, 1074, 195, 1754, 1073, 580, 1072, 629, - /* 1690 */ 1515, 1069, 631, 1068, 1067, 1066, 1510, 317, 1816, 318, - /* 1700 */ 1508, 490, 279, 1786, 583, 1788, 1789, 579, 1785, 574, - /* 1710 */ 319, 493, 1816, 1489, 526, 495, 280, 1786, 583, 1788, - /* 1720 */ 1789, 579, 1488, 574, 497, 1487, 499, 92, 1726, 1233, - /* 1730 */ 1785, 1720, 506, 1707, 1705, 1706, 1803, 54, 1704, 1703, - /* 1740 */ 1701, 1693, 226, 231, 581, 82, 217, 213, 507, 1754, - /* 1750 */ 1785, 580, 218, 320, 41, 16, 15, 512, 1803, 1431, - /* 1760 */ 138, 521, 228, 224, 47, 242, 581, 1231, 76, 210, - /* 1770 */ 77, 1754, 23, 580, 17, 241, 1816, 1243, 1803, 235, - /* 1780 */ 281, 1786, 583, 1788, 1789, 579, 581, 574, 1413, 1775, - /* 1790 */ 233, 1754, 1785, 580, 237, 25, 251, 145, 1816, 46, - /* 1800 */ 1415, 240, 288, 1786, 583, 1788, 1789, 579, 1785, 574, - /* 1810 */ 1408, 24, 81, 1774, 149, 1388, 1387, 18, 1816, 1443, - /* 1820 */ 1803, 1442, 290, 1786, 583, 1788, 1789, 579, 581, 574, - /* 1830 */ 45, 1448, 1437, 1754, 331, 580, 1803, 1447, 13, 1446, - /* 1840 */ 332, 10, 1275, 19, 581, 1819, 1306, 1325, 573, 1754, - /* 1850 */ 1323, 580, 1322, 150, 1350, 31, 12, 20, 163, 582, - /* 1860 */ 1816, 1785, 21, 586, 282, 1786, 583, 1788, 1789, 579, - /* 1870 */ 340, 574, 584, 1785, 1136, 588, 1816, 1133, 590, 591, - /* 1880 */ 291, 1786, 583, 1788, 1789, 579, 593, 574, 594, 1803, - /* 1890 */ 596, 599, 1130, 1113, 1124, 597, 600, 581, 1128, 1122, - /* 1900 */ 83, 1803, 1754, 84, 580, 1127, 1126, 1125, 1145, 581, - /* 1910 */ 262, 606, 60, 1141, 1754, 1785, 580, 1063, 1082, 1038, - /* 1920 */ 615, 618, 263, 1061, 1060, 1785, 1056, 1059, 1058, 1816, - /* 1930 */ 1057, 1055, 1054, 283, 1786, 583, 1788, 1789, 579, 1785, - /* 1940 */ 574, 1816, 1079, 1803, 1077, 292, 1786, 583, 1788, 1789, - /* 1950 */ 579, 581, 574, 1803, 1051, 1050, 1754, 1049, 580, 1046, - /* 1960 */ 1045, 581, 1044, 1043, 1522, 640, 1754, 1803, 580, 1520, - /* 1970 */ 641, 642, 644, 645, 646, 581, 1518, 648, 649, 1516, - /* 1980 */ 1754, 652, 580, 1816, 650, 653, 654, 284, 1786, 583, - /* 1990 */ 1788, 1789, 579, 1816, 574, 1785, 1504, 297, 1786, 583, - /* 2000 */ 1788, 1789, 579, 656, 574, 1785, 1000, 1816, 1486, 266, - /* 2010 */ 660, 298, 1786, 583, 1788, 1789, 579, 1785, 574, 1261, - /* 2020 */ 274, 663, 664, 1803, 1461, 1461, 1461, 1461, 1461, 1461, - /* 2030 */ 1461, 581, 1461, 1803, 1461, 1461, 1754, 1461, 580, 1461, - /* 2040 */ 1461, 581, 1461, 1461, 1461, 1803, 1754, 1461, 580, 1461, - /* 2050 */ 1461, 1461, 1461, 581, 1461, 1461, 1461, 1461, 1754, 1461, - /* 2060 */ 580, 1461, 1461, 1816, 1461, 1461, 1461, 1797, 1786, 583, - /* 2070 */ 1788, 1789, 579, 1816, 574, 1461, 1461, 1796, 1786, 583, - /* 2080 */ 1788, 1789, 579, 1785, 574, 1816, 1461, 1461, 1461, 1795, - /* 2090 */ 1786, 583, 1788, 1789, 579, 1785, 574, 1461, 1461, 1461, - /* 2100 */ 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, - /* 2110 */ 1461, 1803, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 581, - /* 2120 */ 1461, 1461, 1461, 1803, 1754, 1461, 580, 1461, 1461, 1461, - /* 2130 */ 1461, 581, 1461, 1461, 1461, 1461, 1754, 1461, 580, 1461, - /* 2140 */ 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1785, 1461, - /* 2150 */ 1461, 1816, 1461, 1461, 1461, 309, 1786, 583, 1788, 1789, - /* 2160 */ 579, 1461, 574, 1816, 1461, 1461, 1461, 308, 1786, 583, - /* 2170 */ 1788, 1789, 579, 1461, 574, 1461, 1803, 1461, 1461, 1461, - /* 2180 */ 1461, 1461, 1461, 1461, 581, 1461, 1461, 1461, 1461, 1754, - /* 2190 */ 1461, 580, 1461, 1461, 1461, 1461, 1461, 1461, 1785, 1461, - /* 2200 */ 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1785, 1461, - /* 2210 */ 552, 1461, 1461, 1461, 1461, 1461, 1816, 1461, 1461, 1461, - /* 2220 */ 310, 1786, 583, 1788, 1789, 579, 1803, 574, 1461, 1461, - /* 2230 */ 1461, 1461, 1461, 1461, 581, 1461, 1803, 1461, 122, 1754, - /* 2240 */ 1461, 580, 1461, 1461, 581, 1461, 1461, 1461, 1461, 1754, - /* 2250 */ 1461, 580, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 557, - /* 2260 */ 1461, 1461, 1461, 1461, 1461, 1461, 1816, 1461, 1461, 1461, - /* 2270 */ 307, 1786, 583, 1788, 1789, 579, 1816, 574, 120, 1461, - /* 2280 */ 287, 1786, 583, 1788, 1789, 579, 1461, 574, 1461, 1461, - /* 2290 */ 1461, 1461, 1461, 250, 1870, 551, 1461, 550, 1461, 1461, - /* 2300 */ 1928, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, 1461, - /* 2310 */ 1461, 1461, 1461, 159, 1461, 1461, 1461, 1925, + /* 0 */ 532, 73, 1466, 436, 555, 437, 1503, 327, 520, 73, + /* 10 */ 1658, 115, 39, 37, 119, 142, 326, 312, 474, 1703, + /* 20 */ 340, 1469, 1264, 1601, 1608, 145, 1656, 555, 1606, 1562, + /* 30 */ 1810, 1602, 124, 1341, 444, 1262, 437, 1503, 548, 558, + /* 40 */ 345, 389, 105, 1651, 1653, 104, 103, 102, 101, 100, + /* 50 */ 99, 98, 97, 96, 81, 124, 1336, 1491, 1792, 33, + /* 60 */ 32, 14, 353, 40, 38, 36, 35, 34, 1270, 39, + /* 70 */ 37, 1404, 122, 558, 558, 1599, 547, 340, 303, 1264, + /* 80 */ 1936, 1290, 144, 1936, 1480, 1, 1810, 158, 1878, 1879, + /* 90 */ 1341, 1883, 1262, 162, 584, 122, 1935, 1933, 1761, 1761, + /* 100 */ 1933, 583, 435, 1936, 64, 439, 1289, 665, 532, 557, + /* 110 */ 157, 1878, 1879, 1336, 1883, 560, 161, 1290, 14, 55, + /* 120 */ 1933, 1343, 1344, 30, 261, 1270, 1824, 131, 155, 221, + /* 130 */ 91, 1793, 586, 1795, 1796, 582, 1606, 577, 43, 42, + /* 140 */ 1870, 1645, 2, 105, 306, 1866, 104, 103, 102, 101, + /* 150 */ 100, 99, 98, 97, 96, 343, 1936, 40, 38, 36, + /* 160 */ 35, 34, 1080, 142, 665, 63, 1265, 195, 1263, 163, + /* 170 */ 54, 63, 1608, 1933, 383, 519, 351, 443, 1343, 1344, + /* 180 */ 439, 148, 1160, 1161, 1401, 63, 470, 466, 462, 458, + /* 190 */ 194, 1243, 1244, 1268, 1269, 1082, 1318, 1319, 1321, 1322, + /* 200 */ 1323, 1324, 1325, 1326, 579, 575, 1334, 1335, 1337, 1338, + /* 210 */ 1339, 1340, 1342, 1345, 1936, 1936, 1936, 1936, 74, 1652, + /* 220 */ 1653, 192, 1024, 1265, 1023, 1263, 164, 162, 161, 161, + /* 230 */ 161, 1933, 1933, 1933, 1933, 33, 32, 350, 63, 40, + /* 240 */ 38, 36, 35, 34, 1490, 382, 171, 381, 555, 564, + /* 250 */ 1268, 1269, 1025, 1318, 1319, 1321, 1322, 1323, 1324, 1325, + /* 260 */ 1326, 579, 575, 1334, 1335, 1337, 1338, 1339, 1340, 1342, + /* 270 */ 1345, 39, 37, 1468, 71, 1289, 124, 70, 1936, 340, + /* 280 */ 164, 1264, 1792, 191, 184, 1761, 189, 1584, 307, 49, + /* 290 */ 449, 161, 1341, 453, 1262, 1933, 532, 114, 113, 112, + /* 300 */ 111, 110, 109, 108, 107, 106, 164, 115, 1289, 182, + /* 310 */ 1810, 1489, 164, 1303, 479, 1336, 122, 1936, 559, 505, + /* 320 */ 14, 1363, 1488, 1761, 1606, 583, 164, 1270, 39, 37, + /* 330 */ 1934, 159, 1878, 1879, 1933, 1883, 340, 532, 1264, 1530, + /* 340 */ 317, 485, 484, 1425, 2, 478, 1658, 453, 166, 1341, + /* 350 */ 1824, 1262, 1761, 328, 92, 1793, 586, 1795, 1796, 582, + /* 360 */ 1936, 577, 1656, 1761, 1870, 1606, 665, 477, 331, 1866, + /* 370 */ 156, 1582, 1336, 161, 549, 1364, 1658, 1933, 1291, 164, + /* 380 */ 1343, 1344, 160, 344, 1270, 541, 1423, 1424, 1426, 1427, + /* 390 */ 1896, 318, 1656, 316, 315, 1702, 476, 300, 1369, 1706, + /* 400 */ 478, 8, 642, 641, 640, 639, 348, 1400, 638, 637, + /* 410 */ 636, 125, 631, 630, 629, 628, 627, 626, 625, 624, + /* 420 */ 135, 620, 477, 665, 1024, 1265, 1023, 1263, 33, 32, + /* 430 */ 164, 619, 40, 38, 36, 35, 34, 1343, 1344, 472, + /* 440 */ 1007, 29, 338, 1358, 1359, 1360, 1361, 1362, 1366, 1367, + /* 450 */ 1368, 565, 1268, 1269, 1025, 1318, 1319, 1321, 1322, 1323, + /* 460 */ 1324, 1325, 1326, 579, 575, 1334, 1335, 1337, 1338, 1339, + /* 470 */ 1340, 1342, 1345, 1583, 216, 222, 223, 489, 488, 487, + /* 480 */ 1011, 1012, 1265, 486, 1263, 1320, 120, 483, 635, 633, + /* 490 */ 482, 481, 480, 33, 32, 1533, 1779, 40, 38, 36, + /* 500 */ 35, 34, 209, 63, 619, 77, 1487, 1775, 422, 1268, + /* 510 */ 1269, 253, 1318, 1319, 1321, 1322, 1323, 1324, 1325, 1326, + /* 520 */ 579, 575, 1334, 1335, 1337, 1338, 1339, 1340, 1342, 1345, + /* 530 */ 39, 37, 1346, 1771, 1777, 329, 305, 441, 340, 522, + /* 540 */ 1264, 1792, 164, 1287, 215, 577, 307, 1761, 1701, 346, + /* 550 */ 300, 1341, 532, 1262, 175, 174, 1509, 142, 489, 488, + /* 560 */ 487, 75, 305, 387, 486, 522, 1608, 120, 483, 1810, + /* 570 */ 617, 482, 481, 480, 1336, 76, 1365, 559, 1461, 1363, + /* 580 */ 1606, 544, 1761, 494, 583, 1658, 1270, 39, 37, 133, + /* 590 */ 132, 614, 613, 612, 532, 340, 532, 1264, 504, 1370, + /* 600 */ 1696, 1657, 567, 9, 660, 388, 503, 392, 1341, 1824, + /* 610 */ 1262, 173, 208, 92, 1793, 586, 1795, 1796, 582, 501, + /* 620 */ 577, 499, 1606, 1870, 1606, 665, 497, 331, 1866, 156, + /* 630 */ 491, 1336, 374, 1364, 1597, 207, 532, 532, 1288, 1343, + /* 640 */ 1344, 1779, 27, 1270, 164, 1775, 88, 407, 408, 1897, + /* 650 */ 1595, 1408, 1775, 1486, 376, 372, 1369, 1289, 1270, 121, + /* 660 */ 9, 550, 545, 58, 1606, 1606, 57, 1598, 1460, 33, + /* 670 */ 32, 1771, 1777, 40, 38, 36, 35, 34, 1771, 1777, + /* 680 */ 335, 520, 665, 577, 1265, 1351, 1263, 36, 35, 34, + /* 690 */ 577, 1289, 1704, 1485, 1761, 611, 1343, 1344, 1581, 29, + /* 700 */ 338, 1358, 1359, 1360, 1361, 1362, 1366, 1367, 1368, 11, + /* 710 */ 10, 1268, 1269, 61, 1318, 1319, 1321, 1322, 1323, 1324, + /* 720 */ 1325, 1326, 579, 575, 1334, 1335, 1337, 1338, 1339, 1340, + /* 730 */ 1342, 1345, 33, 32, 1761, 1885, 40, 38, 36, 35, + /* 740 */ 34, 1265, 615, 1263, 623, 1649, 1578, 1435, 1118, 608, + /* 750 */ 607, 606, 1122, 605, 1124, 1125, 604, 1127, 601, 1882, + /* 760 */ 1133, 598, 1135, 1136, 595, 592, 1484, 22, 1268, 1269, + /* 770 */ 1483, 1318, 1319, 1321, 1322, 1323, 1324, 1325, 1326, 579, + /* 780 */ 575, 1334, 1335, 1337, 1338, 1339, 1340, 1342, 1345, 39, + /* 790 */ 37, 302, 1051, 1287, 1377, 617, 142, 340, 532, 1264, + /* 800 */ 415, 1792, 532, 427, 622, 1609, 568, 1761, 532, 452, + /* 810 */ 1341, 1761, 1262, 1603, 133, 132, 614, 613, 612, 1735, + /* 820 */ 400, 532, 428, 1747, 402, 1052, 1606, 532, 532, 1810, + /* 830 */ 1606, 1292, 513, 1336, 1320, 7, 1606, 584, 517, 530, + /* 840 */ 1482, 1479, 1761, 634, 583, 1270, 33, 32, 87, 1606, + /* 850 */ 40, 38, 36, 35, 34, 1606, 1606, 393, 84, 33, + /* 860 */ 32, 532, 2, 40, 38, 36, 35, 34, 1320, 1824, + /* 870 */ 362, 617, 531, 93, 1793, 586, 1795, 1796, 582, 1591, + /* 880 */ 577, 1761, 1761, 1870, 665, 1478, 377, 1869, 1866, 1606, + /* 890 */ 133, 132, 614, 613, 612, 44, 4, 426, 1343, 1344, + /* 900 */ 421, 420, 419, 418, 417, 414, 413, 412, 411, 410, + /* 910 */ 406, 405, 404, 403, 397, 396, 395, 394, 1885, 391, + /* 920 */ 390, 1593, 1477, 26, 1415, 1885, 1761, 143, 1589, 33, + /* 930 */ 32, 1476, 279, 40, 38, 36, 35, 34, 1011, 1012, + /* 940 */ 1273, 532, 1881, 1265, 212, 1263, 277, 60, 28, 1880, + /* 950 */ 59, 512, 262, 562, 33, 32, 1475, 41, 40, 38, + /* 960 */ 36, 35, 34, 1761, 233, 1792, 178, 432, 430, 1606, + /* 970 */ 1268, 1269, 1761, 1318, 1319, 1321, 1322, 1323, 1324, 1325, + /* 980 */ 1326, 579, 575, 1334, 1335, 1337, 1338, 1339, 1340, 1342, + /* 990 */ 1345, 668, 532, 1810, 63, 273, 616, 1761, 1636, 1649, + /* 1000 */ 1211, 584, 578, 347, 141, 268, 1761, 1474, 583, 1473, + /* 1010 */ 33, 32, 1472, 1471, 40, 38, 36, 35, 34, 153, + /* 1020 */ 1606, 1397, 560, 1520, 658, 654, 650, 646, 266, 1272, + /* 1030 */ 1890, 1397, 90, 1824, 53, 516, 1782, 91, 1793, 586, + /* 1040 */ 1795, 1796, 582, 220, 577, 490, 1792, 1870, 1761, 1515, + /* 1050 */ 1761, 306, 1866, 1761, 1761, 200, 89, 1513, 198, 231, + /* 1060 */ 337, 336, 202, 1936, 127, 201, 573, 68, 67, 386, + /* 1070 */ 1278, 492, 170, 1276, 1810, 1784, 161, 610, 380, 495, + /* 1080 */ 1933, 1341, 584, 1271, 130, 1481, 224, 1761, 1303, 583, + /* 1090 */ 1563, 301, 529, 256, 370, 131, 368, 364, 360, 167, + /* 1100 */ 355, 352, 1780, 204, 1336, 206, 203, 525, 205, 51, + /* 1110 */ 41, 237, 542, 1775, 1824, 51, 1270, 41, 92, 1793, + /* 1120 */ 586, 1795, 1796, 582, 218, 577, 590, 230, 1870, 11, + /* 1130 */ 10, 471, 331, 1866, 1949, 164, 1792, 1811, 1111, 1771, + /* 1140 */ 1777, 1463, 1464, 1904, 130, 1235, 131, 211, 116, 506, + /* 1150 */ 130, 577, 1422, 1327, 240, 572, 245, 349, 1371, 1504, + /* 1160 */ 272, 1646, 1275, 1900, 1810, 556, 250, 3, 255, 1139, + /* 1170 */ 258, 5, 584, 260, 354, 1287, 361, 1761, 357, 583, + /* 1180 */ 313, 1080, 1227, 314, 269, 409, 1698, 1143, 424, 1150, + /* 1190 */ 172, 1148, 1792, 134, 416, 423, 425, 429, 1355, 431, + /* 1200 */ 434, 433, 1293, 442, 1824, 1296, 445, 181, 93, 1793, + /* 1210 */ 586, 1795, 1796, 582, 1279, 577, 1274, 446, 1870, 183, + /* 1220 */ 1810, 1295, 571, 1866, 1297, 448, 186, 447, 584, 188, + /* 1230 */ 1294, 450, 451, 1761, 1792, 583, 190, 454, 72, 193, + /* 1240 */ 473, 1282, 1284, 475, 1596, 95, 197, 1592, 199, 136, + /* 1250 */ 137, 1594, 304, 575, 1334, 1335, 1337, 1338, 1339, 1340, + /* 1260 */ 1824, 1590, 1810, 138, 92, 1793, 586, 1795, 1796, 582, + /* 1270 */ 584, 577, 139, 270, 1870, 1761, 210, 583, 331, 1866, + /* 1280 */ 1949, 1740, 507, 540, 511, 526, 213, 1792, 217, 1927, + /* 1290 */ 508, 514, 518, 521, 128, 323, 1739, 1792, 1708, 523, + /* 1300 */ 129, 325, 1824, 226, 527, 528, 92, 1793, 586, 1795, + /* 1310 */ 1796, 582, 228, 577, 271, 1810, 1870, 1607, 1292, 543, + /* 1320 */ 331, 1866, 1949, 584, 80, 1810, 536, 538, 1761, 539, + /* 1330 */ 583, 1889, 1264, 584, 1901, 330, 546, 6, 1761, 534, + /* 1340 */ 583, 235, 244, 239, 552, 1262, 537, 1792, 1397, 1911, + /* 1350 */ 1910, 150, 535, 123, 560, 1824, 1291, 1792, 1892, 280, + /* 1360 */ 1793, 586, 1795, 1796, 582, 1824, 577, 249, 246, 286, + /* 1370 */ 1793, 586, 1795, 1796, 582, 1810, 577, 569, 1270, 332, + /* 1380 */ 1886, 566, 1932, 584, 254, 1810, 563, 257, 1761, 1952, + /* 1390 */ 583, 48, 82, 581, 247, 1936, 1650, 248, 1761, 1579, + /* 1400 */ 583, 274, 265, 1851, 560, 588, 661, 570, 163, 662, + /* 1410 */ 664, 259, 1933, 52, 149, 1824, 278, 665, 1755, 286, + /* 1420 */ 1793, 586, 1795, 1796, 582, 1824, 577, 276, 1754, 294, + /* 1430 */ 1793, 586, 1795, 1796, 582, 580, 577, 574, 1842, 1792, + /* 1440 */ 555, 287, 297, 296, 65, 1936, 1753, 1752, 66, 1751, + /* 1450 */ 356, 1748, 358, 359, 1255, 1256, 168, 363, 161, 1746, + /* 1460 */ 365, 366, 1933, 367, 1745, 369, 1744, 1810, 124, 1743, + /* 1470 */ 371, 1742, 373, 375, 1725, 584, 1265, 169, 1263, 378, + /* 1480 */ 1761, 379, 583, 1230, 1229, 1719, 1718, 384, 385, 560, + /* 1490 */ 1717, 1716, 1691, 1792, 1199, 1690, 1689, 69, 1688, 1687, + /* 1500 */ 1686, 1685, 1684, 1268, 1269, 398, 1683, 1824, 122, 401, + /* 1510 */ 399, 146, 1793, 586, 1795, 1796, 582, 1792, 577, 1682, + /* 1520 */ 1681, 1810, 126, 251, 1878, 554, 1680, 553, 1679, 584, + /* 1530 */ 1936, 1678, 1677, 1676, 1761, 1675, 583, 1674, 1673, 1672, + /* 1540 */ 1671, 1670, 1669, 163, 1668, 1810, 1667, 1933, 1666, 1665, + /* 1550 */ 324, 1664, 1663, 584, 117, 561, 1950, 1662, 1761, 1661, + /* 1560 */ 583, 1824, 1660, 1659, 1535, 93, 1793, 586, 1795, 1796, + /* 1570 */ 582, 1792, 577, 176, 1534, 1870, 1201, 177, 1532, 1500, + /* 1580 */ 1867, 1792, 1014, 1013, 1499, 1824, 154, 179, 1733, 295, + /* 1590 */ 1793, 586, 1795, 1796, 582, 1727, 577, 1715, 180, 1810, + /* 1600 */ 118, 438, 440, 1714, 533, 185, 1700, 584, 1585, 1810, + /* 1610 */ 187, 1531, 1761, 1529, 583, 1044, 455, 584, 456, 457, + /* 1620 */ 1527, 459, 1761, 460, 583, 1525, 461, 1523, 463, 465, + /* 1630 */ 464, 1792, 468, 467, 1512, 469, 1511, 1496, 1587, 1824, + /* 1640 */ 1154, 50, 196, 295, 1793, 586, 1795, 1796, 582, 1824, + /* 1650 */ 577, 1153, 1586, 290, 1793, 586, 1795, 1796, 582, 1810, + /* 1660 */ 577, 1079, 632, 1078, 634, 1077, 1076, 584, 1073, 1521, + /* 1670 */ 1072, 319, 1761, 320, 583, 1071, 1070, 1516, 1514, 321, + /* 1680 */ 496, 1792, 1495, 498, 1494, 500, 1493, 502, 493, 1732, + /* 1690 */ 94, 551, 15, 1792, 1237, 1726, 140, 509, 1713, 1824, + /* 1700 */ 1711, 1712, 1710, 146, 1793, 586, 1795, 1796, 582, 1810, + /* 1710 */ 577, 1709, 1707, 56, 1699, 1247, 229, 581, 510, 227, + /* 1720 */ 214, 1810, 1761, 16, 583, 232, 339, 225, 322, 584, + /* 1730 */ 219, 78, 515, 41, 1761, 17, 583, 47, 79, 23, + /* 1740 */ 524, 1437, 84, 234, 13, 243, 236, 1419, 1951, 1824, + /* 1750 */ 1421, 238, 147, 294, 1793, 586, 1795, 1796, 582, 241, + /* 1760 */ 577, 1824, 1843, 242, 1782, 295, 1793, 586, 1795, 1796, + /* 1770 */ 582, 1792, 577, 24, 25, 252, 46, 1414, 83, 18, + /* 1780 */ 1781, 1792, 1394, 1393, 151, 1449, 1448, 333, 1453, 1454, + /* 1790 */ 1443, 1452, 334, 10, 1280, 1356, 1331, 45, 19, 1810, + /* 1800 */ 1827, 576, 1311, 1329, 341, 1328, 31, 584, 152, 1810, + /* 1810 */ 12, 20, 1761, 165, 583, 21, 589, 584, 585, 587, + /* 1820 */ 342, 1140, 1761, 1137, 583, 591, 594, 593, 1134, 596, + /* 1830 */ 597, 1792, 1128, 599, 600, 602, 1132, 1131, 1117, 1824, + /* 1840 */ 609, 1792, 1149, 295, 1793, 586, 1795, 1796, 582, 1824, + /* 1850 */ 577, 1792, 1126, 281, 1793, 586, 1795, 1796, 582, 1810, + /* 1860 */ 577, 603, 85, 86, 62, 263, 1145, 584, 1130, 1810, + /* 1870 */ 1129, 1042, 1761, 618, 583, 264, 1067, 584, 1086, 1810, + /* 1880 */ 621, 1065, 1761, 1064, 583, 1063, 1062, 584, 1061, 1060, + /* 1890 */ 1059, 1058, 1761, 1083, 583, 1081, 1055, 1054, 1053, 1824, + /* 1900 */ 1050, 1049, 1528, 282, 1793, 586, 1795, 1796, 582, 1824, + /* 1910 */ 577, 1048, 1047, 289, 1793, 586, 1795, 1796, 582, 1824, + /* 1920 */ 577, 643, 644, 291, 1793, 586, 1795, 1796, 582, 645, + /* 1930 */ 577, 1526, 1792, 647, 648, 649, 1524, 1522, 651, 652, + /* 1940 */ 653, 655, 656, 657, 1510, 659, 1004, 1492, 267, 663, + /* 1950 */ 666, 1792, 1266, 667, 275, 1467, 1467, 1467, 1467, 1467, + /* 1960 */ 1810, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 584, 1467, + /* 1970 */ 1467, 1467, 1467, 1761, 1467, 583, 1467, 1467, 1467, 1810, + /* 1980 */ 1467, 1467, 1467, 1467, 1467, 1467, 1467, 584, 1467, 1467, + /* 1990 */ 1467, 1467, 1761, 1467, 583, 1467, 1467, 1467, 1467, 1467, + /* 2000 */ 1824, 1467, 1467, 1467, 283, 1793, 586, 1795, 1796, 582, + /* 2010 */ 1467, 577, 1467, 1792, 1467, 1467, 1467, 1467, 1467, 1824, + /* 2020 */ 1467, 1467, 1467, 292, 1793, 586, 1795, 1796, 582, 1792, + /* 2030 */ 577, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, + /* 2040 */ 1467, 1810, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 584, + /* 2050 */ 1467, 1467, 1467, 1467, 1761, 1467, 583, 1810, 1467, 1467, + /* 2060 */ 1467, 1467, 1467, 1467, 1467, 584, 1467, 1467, 1467, 1467, + /* 2070 */ 1761, 1467, 583, 1467, 1467, 1467, 1467, 1467, 1467, 1467, + /* 2080 */ 1467, 1824, 1792, 1467, 1467, 284, 1793, 586, 1795, 1796, + /* 2090 */ 582, 1467, 577, 1467, 1467, 1467, 1467, 1824, 1467, 1792, + /* 2100 */ 1467, 293, 1793, 586, 1795, 1796, 582, 1467, 577, 1467, + /* 2110 */ 1810, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 584, 1467, + /* 2120 */ 1467, 1467, 1467, 1761, 1467, 583, 1467, 1810, 1467, 1467, + /* 2130 */ 1467, 1467, 1467, 1467, 1467, 584, 1467, 1467, 1467, 1467, + /* 2140 */ 1761, 1467, 583, 1467, 1467, 1467, 1467, 1467, 1467, 1467, + /* 2150 */ 1824, 1467, 1792, 1467, 285, 1793, 586, 1795, 1796, 582, + /* 2160 */ 1467, 577, 1467, 1467, 1792, 1467, 1467, 1824, 1467, 1467, + /* 2170 */ 1467, 298, 1793, 586, 1795, 1796, 582, 1467, 577, 1467, + /* 2180 */ 1810, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 584, 1467, + /* 2190 */ 1467, 1467, 1810, 1761, 1467, 583, 1467, 1467, 1467, 1467, + /* 2200 */ 584, 1467, 1467, 1467, 1467, 1761, 1467, 583, 1467, 1467, + /* 2210 */ 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, + /* 2220 */ 1824, 1467, 1467, 1467, 299, 1793, 586, 1795, 1796, 582, + /* 2230 */ 1467, 577, 1824, 1792, 1467, 1467, 1804, 1793, 586, 1795, + /* 2240 */ 1796, 582, 1467, 577, 1467, 1467, 1467, 1792, 1467, 1467, + /* 2250 */ 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, + /* 2260 */ 1467, 1810, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 584, + /* 2270 */ 1467, 1467, 1467, 1467, 1761, 1810, 583, 1467, 1467, 1467, + /* 2280 */ 1467, 1467, 1467, 584, 1467, 1467, 1467, 1467, 1761, 1792, + /* 2290 */ 583, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, + /* 2300 */ 1467, 1824, 1467, 1467, 1467, 1803, 1793, 586, 1795, 1796, + /* 2310 */ 582, 1467, 577, 1467, 1467, 1824, 1467, 1810, 1467, 1802, + /* 2320 */ 1793, 586, 1795, 1796, 582, 584, 577, 1467, 1467, 1467, + /* 2330 */ 1761, 1467, 583, 1467, 1467, 1467, 1467, 1467, 1467, 1467, + /* 2340 */ 1467, 1792, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, + /* 2350 */ 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1824, 1467, 1792, + /* 2360 */ 1467, 310, 1793, 586, 1795, 1796, 582, 1467, 577, 1810, + /* 2370 */ 1467, 1467, 1467, 1467, 1467, 1467, 1467, 584, 1467, 1467, + /* 2380 */ 1467, 1467, 1761, 1792, 583, 1467, 1467, 1810, 1467, 1467, + /* 2390 */ 1467, 1467, 1467, 1467, 1467, 584, 1467, 1467, 1467, 1467, + /* 2400 */ 1761, 1467, 583, 1467, 1467, 1467, 1467, 1467, 1467, 1824, + /* 2410 */ 1467, 1810, 1467, 309, 1793, 586, 1795, 1796, 582, 584, + /* 2420 */ 577, 1467, 1467, 1467, 1761, 1467, 583, 1824, 1467, 1467, + /* 2430 */ 1467, 311, 1793, 586, 1795, 1796, 582, 1467, 577, 555, + /* 2440 */ 1792, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, + /* 2450 */ 1467, 1824, 1467, 1467, 1467, 308, 1793, 586, 1795, 1796, + /* 2460 */ 582, 1467, 577, 1467, 1467, 1467, 1467, 124, 1810, 1467, + /* 2470 */ 1467, 1467, 1467, 1467, 1467, 1467, 584, 1467, 1467, 1467, + /* 2480 */ 1467, 1761, 1467, 583, 1467, 1467, 1467, 1467, 560, 1467, + /* 2490 */ 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, + /* 2500 */ 1467, 1467, 1467, 1467, 1467, 1467, 1467, 122, 1824, 1467, + /* 2510 */ 1467, 1467, 288, 1793, 586, 1795, 1796, 582, 1467, 577, + /* 2520 */ 1467, 1467, 251, 1878, 554, 1467, 553, 1467, 1467, 1936, + /* 2530 */ 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, 1467, + /* 2540 */ 1467, 1467, 161, 1467, 1467, 1467, 1933, }; static const YYCODETYPE yy_lookahead[] = { - /* 0 */ 266, 0, 262, 266, 264, 265, 262, 287, 264, 265, - /* 10 */ 288, 277, 12, 13, 266, 4, 301, 287, 284, 315, - /* 20 */ 20, 299, 22, 4, 309, 268, 258, 312, 294, 341, - /* 30 */ 342, 294, 271, 33, 21, 35, 275, 24, 25, 26, - /* 40 */ 27, 28, 29, 30, 31, 32, 289, 325, 326, 327, - /* 50 */ 270, 303, 315, 356, 286, 20, 56, 0, 20, 337, - /* 60 */ 356, 61, 294, 44, 45, 21, 369, 299, 68, 301, - /* 70 */ 373, 334, 292, 369, 12, 13, 14, 373, 34, 22, - /* 80 */ 36, 266, 20, 315, 22, 85, 349, 350, 351, 20, - /* 90 */ 353, 22, 277, 356, 326, 33, 85, 35, 330, 331, - /* 100 */ 332, 333, 334, 335, 35, 337, 369, 107, 340, 294, - /* 110 */ 373, 297, 344, 345, 300, 301, 270, 85, 56, 50, - /* 120 */ 85, 121, 122, 61, 356, 0, 356, 8, 9, 283, - /* 130 */ 68, 12, 13, 14, 15, 16, 97, 369, 292, 369, - /* 140 */ 257, 373, 259, 373, 258, 258, 21, 85, 56, 24, - /* 150 */ 25, 26, 27, 28, 29, 30, 31, 32, 119, 121, - /* 160 */ 122, 63, 64, 65, 56, 356, 166, 69, 168, 107, - /* 170 */ 72, 73, 278, 286, 76, 77, 78, 255, 369, 87, - /* 180 */ 286, 294, 373, 121, 122, 299, 299, 20, 301, 295, - /* 190 */ 300, 301, 84, 193, 194, 87, 196, 197, 198, 199, + /* 0 */ 267, 271, 256, 263, 267, 265, 266, 279, 302, 271, + /* 10 */ 287, 278, 12, 13, 284, 287, 310, 294, 285, 313, + /* 20 */ 20, 0, 22, 293, 296, 272, 303, 267, 295, 276, + /* 30 */ 287, 293, 295, 33, 263, 35, 265, 266, 295, 20, + /* 40 */ 298, 267, 21, 301, 302, 24, 25, 26, 27, 28, + /* 50 */ 29, 30, 31, 32, 269, 295, 56, 259, 259, 8, + /* 60 */ 9, 61, 316, 12, 13, 14, 15, 16, 68, 12, + /* 70 */ 13, 14, 335, 20, 20, 290, 333, 20, 304, 22, + /* 80 */ 357, 20, 258, 357, 260, 85, 287, 350, 351, 352, + /* 90 */ 33, 354, 35, 370, 295, 335, 370, 374, 300, 300, + /* 100 */ 374, 302, 264, 357, 4, 267, 20, 107, 267, 349, + /* 110 */ 350, 351, 352, 56, 354, 316, 370, 20, 61, 278, + /* 120 */ 374, 121, 122, 342, 343, 68, 327, 43, 286, 116, + /* 130 */ 331, 332, 333, 334, 335, 336, 295, 338, 85, 85, + /* 140 */ 341, 299, 85, 21, 345, 346, 24, 25, 26, 27, + /* 150 */ 28, 29, 30, 31, 32, 279, 357, 12, 13, 14, + /* 160 */ 15, 16, 35, 287, 107, 85, 166, 33, 168, 370, + /* 170 */ 86, 85, 296, 374, 316, 316, 316, 264, 121, 122, + /* 180 */ 267, 47, 121, 122, 4, 85, 52, 53, 54, 55, + /* 190 */ 56, 178, 179, 193, 194, 68, 196, 197, 198, 199, /* 200 */ 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, - /* 210 */ 210, 211, 212, 326, 14, 15, 16, 330, 331, 332, - /* 220 */ 333, 334, 335, 266, 337, 225, 161, 340, 166, 20, - /* 230 */ 168, 344, 345, 346, 277, 79, 225, 315, 258, 8, - /* 240 */ 9, 284, 60, 12, 13, 14, 15, 16, 183, 184, - /* 250 */ 20, 294, 266, 366, 4, 193, 194, 225, 196, 197, - /* 260 */ 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, - /* 270 */ 208, 209, 210, 211, 212, 12, 13, 158, 356, 299, - /* 280 */ 294, 125, 126, 20, 116, 22, 12, 13, 14, 15, - /* 290 */ 16, 369, 61, 85, 85, 373, 33, 0, 35, 98, - /* 300 */ 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, - /* 310 */ 286, 110, 111, 112, 113, 114, 115, 86, 294, 56, - /* 320 */ 334, 258, 8, 9, 61, 94, 12, 13, 14, 15, - /* 330 */ 16, 68, 12, 13, 348, 349, 350, 351, 268, 353, - /* 340 */ 20, 266, 22, 288, 47, 286, 178, 179, 85, 286, - /* 350 */ 278, 281, 293, 33, 299, 35, 332, 294, 286, 289, - /* 360 */ 278, 302, 299, 266, 301, 14, 247, 295, 286, 294, - /* 370 */ 107, 20, 20, 165, 277, 167, 56, 295, 315, 148, - /* 380 */ 325, 326, 327, 0, 121, 122, 0, 263, 68, 326, - /* 390 */ 266, 294, 337, 330, 331, 332, 333, 334, 335, 258, - /* 400 */ 337, 263, 171, 340, 266, 85, 56, 344, 345, 334, - /* 410 */ 24, 25, 26, 27, 28, 29, 30, 31, 32, 356, - /* 420 */ 272, 273, 272, 273, 349, 350, 351, 107, 353, 166, - /* 430 */ 117, 168, 369, 225, 225, 85, 373, 87, 315, 258, - /* 440 */ 299, 121, 122, 60, 213, 214, 215, 216, 217, 218, - /* 450 */ 219, 220, 221, 222, 258, 37, 193, 194, 20, 196, - /* 460 */ 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, - /* 470 */ 207, 208, 209, 210, 211, 212, 226, 8, 9, 356, - /* 480 */ 299, 12, 13, 14, 15, 16, 166, 148, 168, 176, - /* 490 */ 177, 286, 369, 180, 151, 299, 373, 8, 9, 315, - /* 500 */ 20, 12, 13, 14, 15, 16, 88, 302, 90, 91, - /* 510 */ 171, 93, 60, 193, 194, 97, 196, 197, 198, 199, - /* 520 */ 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, - /* 530 */ 210, 211, 212, 12, 13, 14, 14, 119, 44, 45, - /* 540 */ 356, 20, 20, 22, 258, 225, 328, 258, 197, 20, - /* 550 */ 61, 22, 213, 369, 33, 86, 35, 373, 288, 8, - /* 560 */ 9, 116, 117, 12, 13, 14, 15, 16, 20, 299, - /* 570 */ 352, 266, 286, 230, 231, 225, 0, 56, 20, 50, - /* 580 */ 294, 266, 266, 94, 285, 299, 258, 301, 299, 68, - /* 590 */ 12, 13, 277, 277, 43, 325, 326, 298, 20, 294, - /* 600 */ 22, 0, 35, 1, 2, 286, 85, 337, 286, 294, - /* 610 */ 294, 33, 326, 35, 295, 293, 330, 331, 332, 333, - /* 620 */ 334, 335, 177, 337, 302, 180, 340, 299, 107, 266, - /* 630 */ 344, 345, 346, 153, 56, 68, 60, 148, 328, 334, - /* 640 */ 277, 275, 121, 122, 358, 14, 68, 311, 294, 313, - /* 650 */ 301, 20, 366, 68, 349, 350, 351, 294, 353, 305, - /* 660 */ 171, 312, 352, 85, 63, 64, 65, 66, 67, 287, - /* 670 */ 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, - /* 680 */ 79, 80, 81, 82, 0, 107, 20, 166, 86, 168, - /* 690 */ 8, 9, 328, 258, 12, 13, 14, 15, 16, 121, - /* 700 */ 122, 153, 213, 214, 215, 216, 217, 218, 219, 220, - /* 710 */ 221, 222, 39, 258, 193, 194, 352, 196, 197, 198, - /* 720 */ 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, - /* 730 */ 209, 210, 211, 212, 299, 8, 9, 223, 224, 12, - /* 740 */ 13, 14, 15, 16, 166, 43, 168, 63, 64, 65, - /* 750 */ 42, 43, 22, 69, 299, 279, 72, 73, 282, 96, - /* 760 */ 76, 77, 78, 258, 68, 35, 193, 311, 86, 313, - /* 770 */ 296, 193, 194, 299, 196, 197, 198, 199, 200, 201, - /* 780 */ 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, - /* 790 */ 212, 12, 13, 18, 296, 20, 97, 299, 68, 20, - /* 800 */ 287, 22, 27, 258, 299, 30, 35, 234, 235, 236, - /* 810 */ 237, 238, 33, 86, 35, 116, 117, 118, 119, 120, - /* 820 */ 1, 2, 47, 266, 49, 287, 51, 43, 197, 266, - /* 830 */ 266, 286, 266, 258, 277, 56, 274, 107, 276, 294, - /* 840 */ 277, 277, 2, 277, 299, 3, 301, 68, 8, 9, - /* 850 */ 0, 294, 12, 13, 14, 15, 16, 294, 294, 84, - /* 860 */ 294, 8, 9, 197, 85, 12, 13, 14, 15, 16, - /* 870 */ 86, 326, 22, 61, 299, 330, 331, 332, 333, 334, - /* 880 */ 335, 2, 337, 121, 122, 340, 107, 8, 9, 344, - /* 890 */ 345, 12, 13, 14, 15, 16, 166, 224, 168, 124, - /* 900 */ 121, 122, 127, 128, 129, 130, 131, 132, 133, 134, - /* 910 */ 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, - /* 920 */ 287, 146, 147, 193, 194, 266, 43, 266, 0, 18, - /* 930 */ 258, 266, 89, 266, 23, 92, 277, 89, 277, 168, - /* 940 */ 92, 35, 277, 33, 277, 166, 244, 168, 37, 38, - /* 950 */ 22, 89, 41, 294, 92, 294, 287, 47, 315, 294, - /* 960 */ 319, 294, 52, 53, 54, 55, 56, 258, 57, 58, - /* 970 */ 59, 299, 193, 194, 68, 196, 197, 198, 199, 200, - /* 980 */ 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, - /* 990 */ 211, 212, 12, 13, 84, 286, 85, 87, 266, 356, - /* 1000 */ 266, 89, 22, 294, 92, 193, 153, 259, 299, 277, - /* 1010 */ 301, 277, 369, 33, 288, 35, 373, 153, 154, 266, - /* 1020 */ 376, 367, 85, 267, 258, 299, 294, 258, 294, 35, - /* 1030 */ 277, 258, 95, 43, 123, 326, 56, 0, 258, 330, - /* 1040 */ 331, 332, 333, 334, 335, 258, 337, 294, 68, 340, - /* 1050 */ 258, 325, 326, 344, 345, 346, 0, 322, 363, 149, - /* 1060 */ 150, 0, 152, 337, 355, 299, 156, 258, 299, 158, - /* 1070 */ 159, 160, 299, 286, 163, 258, 86, 286, 267, 299, - /* 1080 */ 169, 294, 43, 43, 242, 175, 299, 107, 301, 46, - /* 1090 */ 265, 299, 298, 182, 43, 43, 185, 43, 187, 188, - /* 1100 */ 189, 190, 191, 192, 48, 329, 43, 43, 299, 43, - /* 1110 */ 347, 354, 370, 326, 370, 370, 299, 330, 331, 332, - /* 1120 */ 333, 334, 335, 258, 337, 86, 86, 340, 85, 246, - /* 1130 */ 85, 344, 345, 346, 97, 357, 225, 86, 86, 43, - /* 1140 */ 86, 290, 355, 227, 324, 20, 166, 266, 168, 86, - /* 1150 */ 86, 286, 86, 116, 117, 118, 119, 120, 97, 294, - /* 1160 */ 43, 43, 168, 47, 299, 258, 301, 323, 35, 43, - /* 1170 */ 43, 43, 272, 193, 194, 164, 317, 116, 117, 118, - /* 1180 */ 119, 120, 86, 266, 204, 205, 206, 207, 208, 209, - /* 1190 */ 210, 326, 266, 286, 42, 330, 331, 332, 333, 334, - /* 1200 */ 335, 294, 337, 86, 86, 340, 299, 306, 301, 344, - /* 1210 */ 345, 346, 86, 86, 86, 148, 266, 304, 304, 266, - /* 1220 */ 355, 266, 315, 20, 260, 260, 258, 270, 20, 321, - /* 1230 */ 301, 270, 20, 326, 314, 20, 258, 330, 331, 332, - /* 1240 */ 333, 334, 335, 316, 337, 4, 270, 314, 20, 270, - /* 1250 */ 307, 270, 270, 266, 286, 270, 260, 286, 286, 286, - /* 1260 */ 19, 286, 294, 356, 286, 260, 299, 299, 266, 301, - /* 1270 */ 286, 268, 294, 321, 33, 286, 369, 299, 286, 301, - /* 1280 */ 373, 286, 174, 315, 286, 286, 286, 301, 47, 320, - /* 1290 */ 268, 266, 51, 258, 326, 266, 268, 56, 330, 331, - /* 1300 */ 332, 333, 334, 335, 326, 337, 232, 258, 330, 331, - /* 1310 */ 332, 333, 334, 335, 310, 337, 299, 299, 340, 299, - /* 1320 */ 314, 286, 344, 345, 356, 84, 299, 150, 87, 294, - /* 1330 */ 299, 310, 308, 307, 299, 286, 301, 369, 294, 268, - /* 1340 */ 282, 373, 294, 294, 268, 20, 299, 233, 299, 299, - /* 1350 */ 301, 310, 329, 362, 299, 362, 310, 258, 299, 299, - /* 1360 */ 239, 326, 365, 157, 241, 330, 331, 332, 333, 334, - /* 1370 */ 335, 336, 337, 338, 339, 326, 364, 258, 362, 330, - /* 1380 */ 331, 332, 333, 334, 335, 286, 337, 240, 228, 324, - /* 1390 */ 224, 361, 360, 294, 294, 359, 20, 328, 299, 245, - /* 1400 */ 301, 243, 85, 248, 371, 286, 372, 276, 299, 266, - /* 1410 */ 291, 36, 290, 294, 372, 377, 343, 268, 299, 260, - /* 1420 */ 301, 318, 261, 374, 375, 326, 313, 256, 371, 330, - /* 1430 */ 331, 332, 333, 334, 335, 0, 337, 280, 269, 340, - /* 1440 */ 372, 371, 280, 258, 345, 326, 176, 280, 0, 330, - /* 1450 */ 331, 332, 333, 334, 335, 258, 337, 0, 42, 0, - /* 1460 */ 76, 0, 35, 35, 186, 258, 35, 35, 186, 0, - /* 1470 */ 186, 286, 35, 35, 0, 186, 291, 0, 35, 294, - /* 1480 */ 0, 0, 22, 286, 299, 0, 301, 35, 85, 171, - /* 1490 */ 170, 294, 168, 286, 166, 0, 299, 0, 301, 162, - /* 1500 */ 161, 294, 0, 0, 46, 0, 299, 0, 301, 0, - /* 1510 */ 145, 326, 0, 0, 0, 330, 331, 332, 333, 334, - /* 1520 */ 335, 258, 337, 326, 0, 0, 35, 330, 331, 332, - /* 1530 */ 333, 334, 335, 326, 337, 258, 140, 330, 331, 332, - /* 1540 */ 333, 334, 335, 0, 337, 140, 0, 0, 0, 286, - /* 1550 */ 42, 0, 0, 0, 0, 0, 0, 294, 0, 0, - /* 1560 */ 0, 0, 299, 286, 301, 368, 0, 0, 291, 0, - /* 1570 */ 0, 294, 0, 0, 0, 0, 299, 0, 301, 22, - /* 1580 */ 0, 0, 375, 0, 56, 0, 56, 0, 258, 326, - /* 1590 */ 0, 42, 14, 330, 331, 332, 333, 334, 335, 0, - /* 1600 */ 337, 39, 339, 326, 40, 14, 43, 330, 331, 332, - /* 1610 */ 333, 334, 335, 19, 337, 47, 286, 46, 39, 0, - /* 1620 */ 0, 291, 46, 0, 294, 39, 0, 33, 157, 299, - /* 1630 */ 258, 301, 0, 0, 0, 0, 35, 39, 0, 35, - /* 1640 */ 47, 47, 0, 35, 258, 39, 52, 53, 54, 55, - /* 1650 */ 56, 62, 47, 39, 0, 39, 326, 35, 286, 47, - /* 1660 */ 330, 331, 332, 333, 334, 335, 294, 337, 0, 0, - /* 1670 */ 0, 299, 286, 301, 0, 35, 94, 22, 84, 0, - /* 1680 */ 294, 87, 35, 35, 92, 299, 35, 301, 35, 43, - /* 1690 */ 0, 35, 43, 35, 35, 35, 0, 22, 326, 22, - /* 1700 */ 0, 49, 330, 331, 332, 333, 334, 335, 258, 337, - /* 1710 */ 22, 35, 326, 0, 120, 35, 330, 331, 332, 333, - /* 1720 */ 334, 335, 0, 337, 35, 0, 22, 20, 0, 35, - /* 1730 */ 258, 0, 22, 0, 0, 0, 286, 153, 0, 0, - /* 1740 */ 0, 0, 39, 46, 294, 95, 152, 150, 153, 299, - /* 1750 */ 258, 301, 86, 153, 43, 229, 85, 155, 286, 86, - /* 1760 */ 172, 151, 149, 85, 43, 46, 294, 173, 85, 175, - /* 1770 */ 85, 299, 85, 301, 229, 43, 326, 181, 286, 86, - /* 1780 */ 330, 331, 332, 333, 334, 335, 294, 337, 86, 46, - /* 1790 */ 85, 299, 258, 301, 85, 43, 46, 85, 326, 43, - /* 1800 */ 86, 85, 330, 331, 332, 333, 334, 335, 258, 337, - /* 1810 */ 86, 85, 85, 46, 46, 86, 86, 43, 326, 35, - /* 1820 */ 286, 35, 330, 331, 332, 333, 334, 335, 294, 337, - /* 1830 */ 223, 86, 86, 299, 35, 301, 286, 35, 229, 35, - /* 1840 */ 35, 2, 22, 43, 294, 85, 22, 86, 85, 299, - /* 1850 */ 86, 301, 86, 46, 193, 85, 85, 85, 46, 195, - /* 1860 */ 326, 258, 85, 35, 330, 331, 332, 333, 334, 335, - /* 1870 */ 35, 337, 96, 258, 86, 85, 326, 86, 35, 85, - /* 1880 */ 330, 331, 332, 333, 334, 335, 35, 337, 85, 286, - /* 1890 */ 35, 35, 86, 22, 86, 85, 85, 294, 109, 86, - /* 1900 */ 85, 286, 299, 85, 301, 109, 109, 109, 35, 294, - /* 1910 */ 43, 97, 85, 22, 299, 258, 301, 35, 68, 62, - /* 1920 */ 61, 83, 43, 35, 35, 258, 22, 35, 35, 326, - /* 1930 */ 35, 35, 35, 330, 331, 332, 333, 334, 335, 258, - /* 1940 */ 337, 326, 68, 286, 35, 330, 331, 332, 333, 334, - /* 1950 */ 335, 294, 337, 286, 35, 35, 299, 35, 301, 35, - /* 1960 */ 35, 294, 35, 35, 0, 35, 299, 286, 301, 0, - /* 1970 */ 47, 39, 35, 47, 39, 294, 0, 35, 47, 0, - /* 1980 */ 299, 35, 301, 326, 39, 47, 39, 330, 331, 332, - /* 1990 */ 333, 334, 335, 326, 337, 258, 0, 330, 331, 332, - /* 2000 */ 333, 334, 335, 35, 337, 258, 35, 326, 0, 22, - /* 2010 */ 21, 330, 331, 332, 333, 334, 335, 258, 337, 22, - /* 2020 */ 22, 21, 20, 286, 378, 378, 378, 378, 378, 378, - /* 2030 */ 378, 294, 378, 286, 378, 378, 299, 378, 301, 378, - /* 2040 */ 378, 294, 378, 378, 378, 286, 299, 378, 301, 378, - /* 2050 */ 378, 378, 378, 294, 378, 378, 378, 378, 299, 378, - /* 2060 */ 301, 378, 378, 326, 378, 378, 378, 330, 331, 332, - /* 2070 */ 333, 334, 335, 326, 337, 378, 378, 330, 331, 332, - /* 2080 */ 333, 334, 335, 258, 337, 326, 378, 378, 378, 330, - /* 2090 */ 331, 332, 333, 334, 335, 258, 337, 378, 378, 378, - /* 2100 */ 378, 378, 378, 378, 378, 378, 378, 378, 378, 378, - /* 2110 */ 378, 286, 378, 378, 378, 378, 378, 378, 378, 294, - /* 2120 */ 378, 378, 378, 286, 299, 378, 301, 378, 378, 378, - /* 2130 */ 378, 294, 378, 378, 378, 378, 299, 378, 301, 378, - /* 2140 */ 378, 378, 378, 378, 378, 378, 378, 378, 258, 378, - /* 2150 */ 378, 326, 378, 378, 378, 330, 331, 332, 333, 334, - /* 2160 */ 335, 378, 337, 326, 378, 378, 378, 330, 331, 332, - /* 2170 */ 333, 334, 335, 378, 337, 378, 286, 378, 378, 378, - /* 2180 */ 378, 378, 378, 378, 294, 378, 378, 378, 378, 299, - /* 2190 */ 378, 301, 378, 378, 378, 378, 378, 378, 258, 378, - /* 2200 */ 378, 378, 378, 378, 378, 378, 378, 378, 258, 378, - /* 2210 */ 266, 378, 378, 378, 378, 378, 326, 378, 378, 378, - /* 2220 */ 330, 331, 332, 333, 334, 335, 286, 337, 378, 378, - /* 2230 */ 378, 378, 378, 378, 294, 378, 286, 378, 294, 299, - /* 2240 */ 378, 301, 378, 378, 294, 378, 378, 378, 378, 299, - /* 2250 */ 378, 301, 378, 378, 378, 378, 378, 378, 378, 315, - /* 2260 */ 378, 378, 378, 378, 378, 378, 326, 378, 378, 378, - /* 2270 */ 330, 331, 332, 333, 334, 335, 326, 337, 334, 378, - /* 2280 */ 330, 331, 332, 333, 334, 335, 378, 337, 378, 378, - /* 2290 */ 378, 378, 378, 349, 350, 351, 378, 353, 378, 378, - /* 2300 */ 356, 378, 378, 378, 378, 378, 378, 378, 378, 378, - /* 2310 */ 378, 378, 378, 369, 378, 378, 378, 373, + /* 210 */ 210, 211, 212, 213, 357, 357, 357, 357, 84, 301, + /* 220 */ 302, 87, 20, 166, 22, 168, 226, 370, 370, 370, + /* 230 */ 370, 374, 374, 374, 374, 8, 9, 316, 85, 12, + /* 240 */ 13, 14, 15, 16, 259, 165, 56, 167, 267, 43, + /* 250 */ 193, 194, 50, 196, 197, 198, 199, 200, 201, 202, + /* 260 */ 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, + /* 270 */ 213, 12, 13, 0, 84, 20, 295, 87, 357, 20, + /* 280 */ 226, 22, 259, 149, 150, 300, 152, 0, 61, 85, + /* 290 */ 156, 370, 33, 60, 35, 374, 267, 24, 25, 26, + /* 300 */ 27, 28, 29, 30, 31, 32, 226, 278, 20, 175, + /* 310 */ 287, 259, 226, 86, 285, 56, 335, 357, 295, 316, + /* 320 */ 61, 94, 259, 300, 295, 302, 226, 68, 12, 13, + /* 330 */ 370, 350, 351, 352, 374, 354, 20, 267, 22, 0, + /* 340 */ 37, 273, 274, 193, 85, 97, 287, 60, 278, 33, + /* 350 */ 327, 35, 300, 294, 331, 332, 333, 334, 335, 336, + /* 360 */ 357, 338, 303, 300, 341, 295, 107, 119, 345, 346, + /* 370 */ 347, 0, 56, 370, 20, 148, 287, 374, 20, 226, + /* 380 */ 121, 122, 359, 294, 68, 235, 236, 237, 238, 239, + /* 390 */ 367, 88, 303, 90, 91, 312, 93, 314, 171, 0, + /* 400 */ 97, 85, 63, 64, 65, 66, 67, 227, 69, 70, + /* 410 */ 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, + /* 420 */ 81, 82, 119, 107, 20, 166, 22, 168, 8, 9, + /* 430 */ 226, 60, 12, 13, 14, 15, 16, 121, 122, 35, + /* 440 */ 4, 214, 215, 216, 217, 218, 219, 220, 221, 222, + /* 450 */ 223, 245, 193, 194, 50, 196, 197, 198, 199, 200, + /* 460 */ 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, + /* 470 */ 211, 212, 213, 0, 56, 116, 117, 63, 64, 65, + /* 480 */ 44, 45, 166, 69, 168, 197, 72, 73, 273, 274, + /* 490 */ 76, 77, 78, 8, 9, 0, 289, 12, 13, 14, + /* 500 */ 15, 16, 117, 85, 60, 87, 259, 300, 79, 193, + /* 510 */ 194, 153, 196, 197, 198, 199, 200, 201, 202, 203, + /* 520 */ 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, + /* 530 */ 12, 13, 14, 326, 327, 328, 177, 14, 20, 180, + /* 540 */ 22, 259, 226, 20, 56, 338, 61, 300, 312, 279, + /* 550 */ 314, 33, 267, 35, 125, 126, 0, 287, 63, 64, + /* 560 */ 65, 176, 177, 278, 69, 180, 296, 72, 73, 287, + /* 570 */ 97, 76, 77, 78, 56, 87, 148, 295, 158, 94, + /* 580 */ 295, 151, 300, 4, 302, 287, 68, 12, 13, 116, + /* 590 */ 117, 118, 119, 120, 267, 20, 267, 22, 19, 171, + /* 600 */ 295, 303, 43, 85, 48, 278, 21, 278, 33, 327, + /* 610 */ 35, 306, 33, 331, 332, 333, 334, 335, 336, 34, + /* 620 */ 338, 36, 295, 341, 295, 107, 47, 345, 346, 347, + /* 630 */ 51, 56, 161, 148, 289, 56, 267, 267, 20, 121, + /* 640 */ 122, 289, 214, 68, 226, 300, 269, 278, 278, 367, + /* 650 */ 288, 14, 300, 259, 183, 184, 171, 20, 68, 282, + /* 660 */ 85, 231, 232, 84, 295, 295, 87, 290, 248, 8, + /* 670 */ 9, 326, 327, 12, 13, 14, 15, 16, 326, 327, + /* 680 */ 328, 302, 107, 338, 166, 14, 168, 14, 15, 16, + /* 690 */ 338, 20, 313, 259, 300, 96, 121, 122, 0, 214, + /* 700 */ 215, 216, 217, 218, 219, 220, 221, 222, 223, 1, + /* 710 */ 2, 193, 194, 3, 196, 197, 198, 199, 200, 201, + /* 720 */ 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, + /* 730 */ 212, 213, 8, 9, 300, 329, 12, 13, 14, 15, + /* 740 */ 16, 166, 297, 168, 275, 300, 277, 86, 98, 99, + /* 750 */ 100, 101, 102, 103, 104, 105, 106, 107, 108, 353, + /* 760 */ 110, 111, 112, 113, 114, 115, 259, 43, 193, 194, + /* 770 */ 259, 196, 197, 198, 199, 200, 201, 202, 203, 204, + /* 780 */ 205, 206, 207, 208, 209, 210, 211, 212, 213, 12, + /* 790 */ 13, 18, 35, 20, 86, 97, 287, 20, 267, 22, + /* 800 */ 27, 259, 267, 30, 68, 296, 247, 300, 267, 278, + /* 810 */ 33, 300, 35, 278, 116, 117, 118, 119, 120, 278, + /* 820 */ 47, 267, 49, 0, 51, 68, 295, 267, 267, 287, + /* 830 */ 295, 20, 278, 56, 197, 39, 295, 295, 278, 278, + /* 840 */ 259, 259, 300, 43, 302, 68, 8, 9, 85, 295, + /* 850 */ 12, 13, 14, 15, 16, 295, 295, 84, 95, 8, + /* 860 */ 9, 267, 85, 12, 13, 14, 15, 16, 197, 327, + /* 870 */ 47, 97, 278, 331, 332, 333, 334, 335, 336, 288, + /* 880 */ 338, 300, 300, 341, 107, 259, 86, 345, 346, 295, + /* 890 */ 116, 117, 118, 119, 120, 42, 43, 124, 121, 122, + /* 900 */ 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, + /* 910 */ 137, 138, 139, 140, 141, 142, 143, 144, 329, 146, + /* 920 */ 147, 288, 259, 2, 86, 329, 300, 18, 288, 8, + /* 930 */ 9, 259, 23, 12, 13, 14, 15, 16, 44, 45, + /* 940 */ 35, 267, 353, 166, 288, 168, 37, 38, 2, 353, + /* 950 */ 41, 320, 278, 243, 8, 9, 259, 43, 12, 13, + /* 960 */ 14, 15, 16, 300, 153, 259, 57, 58, 59, 295, + /* 970 */ 193, 194, 300, 196, 197, 198, 199, 200, 201, 202, + /* 980 */ 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, + /* 990 */ 213, 19, 267, 287, 85, 280, 297, 300, 283, 300, + /* 1000 */ 86, 295, 288, 278, 153, 33, 300, 259, 302, 259, + /* 1010 */ 8, 9, 259, 259, 12, 13, 14, 15, 16, 47, + /* 1020 */ 295, 225, 316, 0, 52, 53, 54, 55, 56, 35, + /* 1030 */ 224, 225, 123, 327, 153, 154, 46, 331, 332, 333, + /* 1040 */ 334, 335, 336, 43, 338, 22, 259, 341, 300, 0, + /* 1050 */ 300, 345, 346, 300, 300, 89, 84, 0, 92, 87, + /* 1060 */ 12, 13, 89, 357, 43, 92, 61, 158, 159, 160, + /* 1070 */ 22, 22, 163, 168, 287, 85, 370, 288, 169, 22, + /* 1080 */ 374, 33, 295, 35, 43, 260, 86, 300, 86, 302, + /* 1090 */ 276, 182, 120, 377, 185, 43, 187, 188, 189, 190, + /* 1100 */ 191, 192, 289, 89, 56, 89, 92, 86, 92, 43, + /* 1110 */ 43, 43, 368, 300, 327, 43, 68, 43, 331, 332, + /* 1120 */ 333, 334, 335, 336, 152, 338, 43, 86, 341, 1, + /* 1130 */ 2, 268, 345, 346, 347, 226, 259, 287, 86, 326, + /* 1140 */ 327, 121, 122, 356, 43, 173, 43, 175, 43, 323, + /* 1150 */ 43, 338, 86, 86, 86, 107, 364, 268, 86, 266, + /* 1160 */ 86, 299, 168, 330, 287, 355, 348, 358, 371, 86, + /* 1170 */ 371, 228, 295, 371, 325, 20, 47, 300, 267, 302, + /* 1180 */ 324, 35, 164, 273, 318, 267, 267, 86, 148, 86, + /* 1190 */ 42, 86, 259, 86, 307, 305, 305, 267, 193, 267, + /* 1200 */ 261, 267, 20, 261, 327, 20, 322, 271, 331, 332, + /* 1210 */ 333, 334, 335, 336, 166, 338, 168, 302, 341, 271, + /* 1220 */ 287, 20, 345, 346, 20, 317, 271, 315, 295, 271, + /* 1230 */ 20, 315, 308, 300, 259, 302, 271, 267, 271, 271, + /* 1240 */ 261, 193, 194, 287, 287, 267, 287, 287, 287, 287, + /* 1250 */ 287, 287, 261, 205, 206, 207, 208, 209, 210, 211, + /* 1260 */ 327, 287, 287, 287, 331, 332, 333, 334, 335, 336, + /* 1270 */ 295, 338, 287, 322, 341, 300, 269, 302, 345, 346, + /* 1280 */ 347, 300, 174, 233, 302, 150, 269, 259, 269, 356, + /* 1290 */ 321, 267, 267, 300, 311, 315, 300, 259, 300, 300, + /* 1300 */ 311, 300, 327, 295, 309, 308, 331, 332, 333, 334, + /* 1310 */ 335, 336, 269, 338, 283, 287, 341, 295, 20, 234, + /* 1320 */ 345, 346, 347, 295, 269, 287, 300, 300, 300, 300, + /* 1330 */ 302, 356, 22, 295, 330, 300, 300, 240, 300, 229, + /* 1340 */ 302, 311, 365, 311, 157, 35, 242, 259, 225, 363, + /* 1350 */ 363, 363, 241, 295, 316, 327, 20, 259, 366, 331, + /* 1360 */ 332, 333, 334, 335, 336, 327, 338, 325, 362, 331, + /* 1370 */ 332, 333, 334, 335, 336, 287, 338, 246, 68, 249, + /* 1380 */ 329, 244, 373, 295, 372, 287, 373, 372, 300, 378, + /* 1390 */ 302, 85, 85, 295, 361, 357, 300, 360, 300, 277, + /* 1400 */ 302, 267, 269, 344, 316, 291, 36, 373, 370, 262, + /* 1410 */ 261, 372, 374, 319, 314, 327, 257, 107, 0, 331, + /* 1420 */ 332, 333, 334, 335, 336, 327, 338, 270, 0, 331, + /* 1430 */ 332, 333, 334, 335, 336, 337, 338, 339, 340, 259, + /* 1440 */ 267, 281, 281, 281, 176, 357, 0, 0, 42, 0, + /* 1450 */ 76, 0, 35, 186, 35, 35, 35, 186, 370, 0, + /* 1460 */ 35, 35, 374, 186, 0, 186, 0, 287, 295, 0, + /* 1470 */ 35, 0, 22, 35, 0, 295, 166, 85, 168, 171, + /* 1480 */ 300, 170, 302, 168, 166, 0, 0, 162, 161, 316, + /* 1490 */ 0, 0, 0, 259, 46, 0, 0, 145, 0, 0, + /* 1500 */ 0, 0, 0, 193, 194, 140, 0, 327, 335, 140, + /* 1510 */ 35, 331, 332, 333, 334, 335, 336, 259, 338, 0, + /* 1520 */ 0, 287, 42, 350, 351, 352, 0, 354, 0, 295, + /* 1530 */ 357, 0, 0, 0, 300, 0, 302, 0, 0, 0, + /* 1540 */ 0, 0, 0, 370, 0, 287, 0, 374, 0, 0, + /* 1550 */ 292, 0, 0, 295, 39, 375, 376, 0, 300, 0, + /* 1560 */ 302, 327, 0, 0, 0, 331, 332, 333, 334, 335, + /* 1570 */ 336, 259, 338, 56, 0, 341, 22, 56, 0, 0, + /* 1580 */ 346, 259, 14, 14, 0, 327, 43, 42, 0, 331, + /* 1590 */ 332, 333, 334, 335, 336, 0, 338, 0, 40, 287, + /* 1600 */ 39, 46, 46, 0, 292, 39, 0, 295, 0, 287, + /* 1610 */ 157, 0, 300, 0, 302, 62, 35, 295, 47, 39, + /* 1620 */ 0, 35, 300, 47, 302, 0, 39, 0, 35, 39, + /* 1630 */ 47, 259, 47, 35, 0, 39, 0, 0, 0, 327, + /* 1640 */ 35, 94, 92, 331, 332, 333, 334, 335, 336, 327, + /* 1650 */ 338, 22, 0, 331, 332, 333, 334, 335, 336, 287, + /* 1660 */ 338, 35, 43, 35, 43, 35, 35, 295, 35, 0, + /* 1670 */ 35, 22, 300, 22, 302, 35, 35, 0, 0, 22, + /* 1680 */ 35, 259, 0, 35, 0, 35, 0, 22, 49, 0, + /* 1690 */ 20, 369, 85, 259, 35, 0, 172, 22, 0, 327, + /* 1700 */ 0, 0, 0, 331, 332, 333, 334, 335, 336, 287, + /* 1710 */ 338, 0, 0, 153, 0, 181, 149, 295, 153, 39, + /* 1720 */ 150, 287, 300, 230, 302, 46, 292, 85, 153, 295, + /* 1730 */ 86, 85, 155, 43, 300, 230, 302, 43, 85, 85, + /* 1740 */ 151, 86, 95, 85, 230, 46, 86, 86, 376, 327, + /* 1750 */ 86, 85, 85, 331, 332, 333, 334, 335, 336, 85, + /* 1760 */ 338, 327, 340, 43, 46, 331, 332, 333, 334, 335, + /* 1770 */ 336, 259, 338, 85, 43, 46, 43, 86, 85, 43, + /* 1780 */ 46, 259, 86, 86, 46, 35, 35, 35, 35, 86, + /* 1790 */ 86, 35, 35, 2, 22, 193, 86, 224, 43, 287, + /* 1800 */ 85, 85, 22, 86, 292, 86, 85, 295, 46, 287, + /* 1810 */ 85, 85, 300, 46, 302, 85, 35, 295, 195, 96, + /* 1820 */ 35, 86, 300, 86, 302, 85, 85, 35, 86, 35, + /* 1830 */ 85, 259, 86, 35, 85, 35, 109, 109, 22, 327, + /* 1840 */ 97, 259, 35, 331, 332, 333, 334, 335, 336, 327, + /* 1850 */ 338, 259, 86, 331, 332, 333, 334, 335, 336, 287, + /* 1860 */ 338, 85, 85, 85, 85, 43, 22, 295, 109, 287, + /* 1870 */ 109, 62, 300, 61, 302, 43, 35, 295, 68, 287, + /* 1880 */ 83, 35, 300, 35, 302, 35, 35, 295, 35, 22, + /* 1890 */ 35, 35, 300, 68, 302, 35, 35, 35, 35, 327, + /* 1900 */ 35, 35, 0, 331, 332, 333, 334, 335, 336, 327, + /* 1910 */ 338, 35, 35, 331, 332, 333, 334, 335, 336, 327, + /* 1920 */ 338, 35, 47, 331, 332, 333, 334, 335, 336, 39, + /* 1930 */ 338, 0, 259, 35, 47, 39, 0, 0, 35, 47, + /* 1940 */ 39, 35, 47, 39, 0, 35, 35, 0, 22, 21, + /* 1950 */ 21, 259, 22, 20, 22, 379, 379, 379, 379, 379, + /* 1960 */ 287, 379, 379, 379, 379, 379, 379, 379, 295, 379, + /* 1970 */ 379, 379, 379, 300, 379, 302, 379, 379, 379, 287, + /* 1980 */ 379, 379, 379, 379, 379, 379, 379, 295, 379, 379, + /* 1990 */ 379, 379, 300, 379, 302, 379, 379, 379, 379, 379, + /* 2000 */ 327, 379, 379, 379, 331, 332, 333, 334, 335, 336, + /* 2010 */ 379, 338, 379, 259, 379, 379, 379, 379, 379, 327, + /* 2020 */ 379, 379, 379, 331, 332, 333, 334, 335, 336, 259, + /* 2030 */ 338, 379, 379, 379, 379, 379, 379, 379, 379, 379, + /* 2040 */ 379, 287, 379, 379, 379, 379, 379, 379, 379, 295, + /* 2050 */ 379, 379, 379, 379, 300, 379, 302, 287, 379, 379, + /* 2060 */ 379, 379, 379, 379, 379, 295, 379, 379, 379, 379, + /* 2070 */ 300, 379, 302, 379, 379, 379, 379, 379, 379, 379, + /* 2080 */ 379, 327, 259, 379, 379, 331, 332, 333, 334, 335, + /* 2090 */ 336, 379, 338, 379, 379, 379, 379, 327, 379, 259, + /* 2100 */ 379, 331, 332, 333, 334, 335, 336, 379, 338, 379, + /* 2110 */ 287, 379, 379, 379, 379, 379, 379, 379, 295, 379, + /* 2120 */ 379, 379, 379, 300, 379, 302, 379, 287, 379, 379, + /* 2130 */ 379, 379, 379, 379, 379, 295, 379, 379, 379, 379, + /* 2140 */ 300, 379, 302, 379, 379, 379, 379, 379, 379, 379, + /* 2150 */ 327, 379, 259, 379, 331, 332, 333, 334, 335, 336, + /* 2160 */ 379, 338, 379, 379, 259, 379, 379, 327, 379, 379, + /* 2170 */ 379, 331, 332, 333, 334, 335, 336, 379, 338, 379, + /* 2180 */ 287, 379, 379, 379, 379, 379, 379, 379, 295, 379, + /* 2190 */ 379, 379, 287, 300, 379, 302, 379, 379, 379, 379, + /* 2200 */ 295, 379, 379, 379, 379, 300, 379, 302, 379, 379, + /* 2210 */ 379, 379, 379, 379, 379, 379, 379, 379, 379, 379, + /* 2220 */ 327, 379, 379, 379, 331, 332, 333, 334, 335, 336, + /* 2230 */ 379, 338, 327, 259, 379, 379, 331, 332, 333, 334, + /* 2240 */ 335, 336, 379, 338, 379, 379, 379, 259, 379, 379, + /* 2250 */ 379, 379, 379, 379, 379, 379, 379, 379, 379, 379, + /* 2260 */ 379, 287, 379, 379, 379, 379, 379, 379, 379, 295, + /* 2270 */ 379, 379, 379, 379, 300, 287, 302, 379, 379, 379, + /* 2280 */ 379, 379, 379, 295, 379, 379, 379, 379, 300, 259, + /* 2290 */ 302, 379, 379, 379, 379, 379, 379, 379, 379, 379, + /* 2300 */ 379, 327, 379, 379, 379, 331, 332, 333, 334, 335, + /* 2310 */ 336, 379, 338, 379, 379, 327, 379, 287, 379, 331, + /* 2320 */ 332, 333, 334, 335, 336, 295, 338, 379, 379, 379, + /* 2330 */ 300, 379, 302, 379, 379, 379, 379, 379, 379, 379, + /* 2340 */ 379, 259, 379, 379, 379, 379, 379, 379, 379, 379, + /* 2350 */ 379, 379, 379, 379, 379, 379, 379, 327, 379, 259, + /* 2360 */ 379, 331, 332, 333, 334, 335, 336, 379, 338, 287, + /* 2370 */ 379, 379, 379, 379, 379, 379, 379, 295, 379, 379, + /* 2380 */ 379, 379, 300, 259, 302, 379, 379, 287, 379, 379, + /* 2390 */ 379, 379, 379, 379, 379, 295, 379, 379, 379, 379, + /* 2400 */ 300, 379, 302, 379, 379, 379, 379, 379, 379, 327, + /* 2410 */ 379, 287, 379, 331, 332, 333, 334, 335, 336, 295, + /* 2420 */ 338, 379, 379, 379, 300, 379, 302, 327, 379, 379, + /* 2430 */ 379, 331, 332, 333, 334, 335, 336, 379, 338, 267, + /* 2440 */ 259, 379, 379, 379, 379, 379, 379, 379, 379, 379, + /* 2450 */ 379, 327, 379, 379, 379, 331, 332, 333, 334, 335, + /* 2460 */ 336, 379, 338, 379, 379, 379, 379, 295, 287, 379, + /* 2470 */ 379, 379, 379, 379, 379, 379, 295, 379, 379, 379, + /* 2480 */ 379, 300, 379, 302, 379, 379, 379, 379, 316, 379, + /* 2490 */ 379, 379, 379, 379, 379, 379, 379, 379, 379, 379, + /* 2500 */ 379, 379, 379, 379, 379, 379, 379, 335, 327, 379, + /* 2510 */ 379, 379, 331, 332, 333, 334, 335, 336, 379, 338, + /* 2520 */ 379, 379, 350, 351, 352, 379, 354, 379, 379, 357, + /* 2530 */ 379, 379, 379, 379, 379, 379, 379, 379, 379, 379, + /* 2540 */ 379, 379, 370, 379, 379, 379, 374, }; -#define YY_SHIFT_COUNT (665) +#define YY_SHIFT_COUNT (668) #define YY_SHIFT_MIN (0) -#define YY_SHIFT_MAX (2008) +#define YY_SHIFT_MAX (1947) static const unsigned short int yy_shift_ofst[] = { - /* 0 */ 911, 0, 0, 62, 62, 263, 263, 263, 320, 320, - /* 10 */ 263, 263, 521, 578, 779, 578, 578, 578, 578, 578, - /* 20 */ 578, 578, 578, 578, 578, 578, 578, 578, 578, 578, - /* 30 */ 578, 578, 578, 578, 578, 578, 578, 578, 578, 578, - /* 40 */ 578, 578, 209, 209, 35, 35, 35, 980, 980, 980, - /* 50 */ 980, 208, 350, 32, 32, 167, 167, 19, 19, 11, - /* 60 */ 38, 32, 32, 167, 167, 167, 167, 167, 167, 167, - /* 70 */ 167, 167, 182, 167, 167, 167, 230, 352, 167, 167, - /* 80 */ 352, 438, 167, 352, 352, 352, 167, 452, 775, 231, - /* 90 */ 489, 489, 13, 98, 730, 730, 730, 730, 730, 730, - /* 100 */ 730, 730, 730, 730, 730, 730, 730, 730, 730, 730, - /* 110 */ 730, 730, 730, 418, 38, 522, 522, 383, 567, 576, - /* 120 */ 480, 480, 480, 567, 558, 230, 1, 1, 352, 352, - /* 130 */ 585, 585, 663, 696, 201, 201, 201, 201, 201, 201, - /* 140 */ 201, 1594, 125, 684, 119, 573, 69, 313, 343, 351, - /* 150 */ 631, 529, 494, 39, 548, 514, 673, 514, 708, 842, - /* 160 */ 842, 842, 250, 666, 1045, 916, 1125, 1116, 1133, 1011, - /* 170 */ 1125, 1125, 1152, 1067, 1067, 1125, 1125, 1125, 1203, 1203, - /* 180 */ 1208, 182, 230, 182, 1212, 1215, 182, 1212, 182, 1228, - /* 190 */ 182, 182, 1125, 182, 1203, 352, 352, 352, 352, 352, - /* 200 */ 352, 352, 352, 352, 352, 352, 1125, 1203, 585, 1208, - /* 210 */ 452, 1108, 230, 452, 1125, 1125, 1212, 452, 1074, 585, - /* 220 */ 585, 585, 585, 1074, 585, 1177, 558, 1228, 452, 663, - /* 230 */ 452, 558, 1325, 585, 1114, 1074, 585, 585, 1114, 1074, - /* 240 */ 585, 585, 352, 1121, 1206, 1114, 1123, 1147, 1160, 916, - /* 250 */ 1166, 558, 1376, 1154, 1158, 1155, 1154, 1158, 1154, 1158, - /* 260 */ 1317, 1045, 585, 696, 1125, 452, 1375, 1203, 2318, 2318, - /* 270 */ 2318, 2318, 2318, 2318, 2318, 601, 910, 386, 1241, 469, - /* 280 */ 551, 682, 840, 879, 853, 727, 1037, 314, 314, 314, - /* 290 */ 314, 314, 314, 314, 314, 1061, 699, 274, 274, 445, - /* 300 */ 65, 108, 156, 44, 168, 602, 339, 200, 200, 200, - /* 310 */ 200, 297, 784, 843, 848, 862, 912, 57, 850, 928, - /* 320 */ 92, 864, 990, 1039, 1040, 1051, 1052, 1054, 1063, 819, - /* 330 */ 762, 702, 883, 1064, 771, 994, 812, 1066, 1043, 1096, - /* 340 */ 1117, 1118, 1126, 1127, 1128, 937, 906, 1056, 1435, 1270, - /* 350 */ 1448, 1457, 1416, 1459, 1384, 1461, 1427, 1278, 1428, 1431, - /* 360 */ 1432, 1282, 1469, 1437, 1438, 1284, 1474, 1289, 1477, 1443, - /* 370 */ 1480, 1460, 1481, 1452, 1485, 1403, 1318, 1320, 1324, 1328, - /* 380 */ 1495, 1497, 1337, 1339, 1502, 1503, 1458, 1505, 1507, 1509, - /* 390 */ 1365, 1512, 1513, 1514, 1524, 1525, 1396, 1491, 1543, 1405, - /* 400 */ 1546, 1547, 1548, 1558, 1559, 1560, 1561, 1566, 1567, 1569, - /* 410 */ 1570, 1572, 1573, 1574, 1508, 1551, 1552, 1553, 1554, 1555, - /* 420 */ 1556, 1557, 1575, 1577, 1580, 1581, 1583, 1528, 1585, 1530, - /* 430 */ 1587, 1590, 1549, 1562, 1563, 1578, 1571, 1591, 1576, 1599, - /* 440 */ 1564, 1579, 1619, 1620, 1623, 1586, 1471, 1626, 1632, 1633, - /* 450 */ 1589, 1634, 1635, 1601, 1568, 1598, 1638, 1604, 1593, 1606, - /* 460 */ 1642, 1608, 1605, 1614, 1654, 1622, 1612, 1616, 1668, 1669, - /* 470 */ 1670, 1674, 1582, 1592, 1640, 1655, 1679, 1647, 1648, 1651, - /* 480 */ 1653, 1646, 1649, 1656, 1658, 1659, 1660, 1690, 1675, 1696, - /* 490 */ 1677, 1652, 1700, 1688, 1676, 1713, 1680, 1722, 1689, 1725, - /* 500 */ 1704, 1707, 1728, 1584, 1694, 1731, 1588, 1710, 1595, 1597, - /* 510 */ 1733, 1734, 1600, 1602, 1735, 1738, 1739, 1671, 1666, 1596, - /* 520 */ 1740, 1678, 1610, 1683, 1741, 1703, 1613, 1685, 1650, 1697, - /* 530 */ 1711, 1526, 1687, 1673, 1705, 1693, 1702, 1709, 1721, 1714, - /* 540 */ 1712, 1716, 1726, 1724, 1732, 1719, 1743, 1727, 1752, 1545, - /* 550 */ 1729, 1730, 1750, 1607, 1756, 1767, 1768, 1745, 1774, 1609, - /* 560 */ 1746, 1784, 1786, 1799, 1802, 1804, 1805, 1746, 1839, 1820, - /* 570 */ 1661, 1800, 1760, 1761, 1763, 1764, 1770, 1766, 1807, 1771, - /* 580 */ 1772, 1812, 1824, 1664, 1777, 1776, 1788, 1828, 1835, 1790, - /* 590 */ 1791, 1843, 1794, 1806, 1851, 1803, 1808, 1855, 1810, 1813, - /* 600 */ 1856, 1811, 1789, 1796, 1797, 1798, 1871, 1814, 1815, 1818, - /* 610 */ 1873, 1827, 1867, 1867, 1891, 1857, 1859, 1882, 1850, 1838, - /* 620 */ 1879, 1888, 1889, 1892, 1893, 1895, 1904, 1896, 1897, 1874, - /* 630 */ 1646, 1909, 1649, 1919, 1920, 1922, 1924, 1925, 1927, 1928, - /* 640 */ 1964, 1930, 1923, 1932, 1969, 1937, 1926, 1935, 1976, 1942, - /* 650 */ 1931, 1945, 1979, 1946, 1938, 1947, 1996, 1968, 1971, 2008, - /* 660 */ 1987, 1989, 1997, 1998, 2000, 2002, + /* 0 */ 909, 0, 0, 57, 57, 259, 259, 259, 316, 316, + /* 10 */ 259, 259, 518, 575, 777, 575, 575, 575, 575, 575, + /* 20 */ 575, 575, 575, 575, 575, 575, 575, 575, 575, 575, + /* 30 */ 575, 575, 575, 575, 575, 575, 575, 575, 575, 575, + /* 40 */ 575, 575, 54, 54, 53, 53, 53, 1048, 1048, 86, + /* 50 */ 1048, 1048, 80, 418, 153, 204, 153, 19, 19, 436, + /* 60 */ 436, 100, 61, 153, 153, 19, 19, 19, 19, 19, + /* 70 */ 19, 19, 19, 19, 233, 19, 19, 19, 97, 255, + /* 80 */ 19, 19, 255, 354, 19, 255, 255, 255, 19, 444, + /* 90 */ 773, 227, 485, 485, 122, 414, 1310, 1310, 1310, 1310, + /* 100 */ 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, 1310, + /* 110 */ 1310, 1310, 1310, 1310, 1310, 303, 61, 523, 523, 287, + /* 120 */ 127, 371, 358, 358, 358, 127, 618, 97, 399, 399, + /* 130 */ 255, 255, 590, 590, 599, 736, 650, 650, 650, 650, + /* 140 */ 650, 650, 650, 972, 21, 495, 420, 150, 404, 385, + /* 150 */ 430, 637, 671, 202, 894, 248, 811, 806, 796, 806, + /* 160 */ 853, 710, 710, 710, 180, 288, 943, 1155, 1129, 1146, + /* 170 */ 1018, 1155, 1155, 1148, 1040, 1040, 1155, 1155, 1155, 1182, + /* 180 */ 1182, 1185, 233, 97, 233, 1201, 1204, 233, 1201, 233, + /* 190 */ 1210, 233, 233, 1155, 233, 1182, 255, 255, 255, 255, + /* 200 */ 255, 255, 255, 255, 255, 255, 255, 1155, 1182, 590, + /* 210 */ 1185, 444, 1108, 97, 444, 1155, 1155, 1201, 444, 1050, + /* 220 */ 590, 590, 590, 590, 1050, 590, 1135, 618, 1210, 444, + /* 230 */ 599, 444, 618, 1298, 590, 1085, 1050, 590, 590, 1085, + /* 240 */ 1050, 590, 590, 255, 1097, 1187, 1085, 1104, 1111, 1110, + /* 250 */ 943, 1123, 618, 1336, 1131, 1137, 1130, 1131, 1137, 1131, + /* 260 */ 1137, 1306, 1307, 590, 736, 1155, 444, 1370, 1182, 2547, + /* 270 */ 2547, 2547, 2547, 2547, 2547, 2547, 339, 134, 273, 579, + /* 280 */ 661, 724, 838, 921, 946, 851, 1002, 473, 51, 51, + /* 290 */ 51, 51, 51, 51, 51, 51, 698, 774, 145, 145, + /* 300 */ 359, 471, 190, 429, 585, 13, 708, 428, 673, 673, + /* 310 */ 673, 673, 84, 823, 800, 966, 973, 1014, 1016, 1023, + /* 320 */ 1049, 1057, 488, 881, 914, 1000, 1021, 1041, 1052, 1066, + /* 330 */ 1068, 1128, 1020, 206, 559, 1072, 905, 994, 1005, 1067, + /* 340 */ 990, 1074, 1083, 1101, 1103, 1105, 1107, 763, 757, 556, + /* 350 */ 1418, 1428, 1268, 1446, 1447, 1406, 1449, 1374, 1451, 1417, + /* 360 */ 1267, 1419, 1420, 1421, 1271, 1459, 1425, 1426, 1277, 1464, + /* 370 */ 1279, 1466, 1435, 1469, 1450, 1471, 1438, 1474, 1392, 1308, + /* 380 */ 1311, 1315, 1318, 1485, 1486, 1325, 1327, 1490, 1491, 1448, + /* 390 */ 1492, 1495, 1496, 1352, 1498, 1499, 1500, 1501, 1502, 1365, + /* 400 */ 1475, 1506, 1369, 1519, 1520, 1526, 1528, 1531, 1532, 1533, + /* 410 */ 1535, 1537, 1538, 1539, 1540, 1541, 1542, 1480, 1544, 1546, + /* 420 */ 1548, 1549, 1551, 1552, 1554, 1557, 1559, 1562, 1563, 1564, + /* 430 */ 1517, 1574, 1521, 1578, 1579, 1545, 1515, 1543, 1568, 1555, + /* 440 */ 1569, 1556, 1584, 1558, 1561, 1588, 1595, 1597, 1566, 1453, + /* 450 */ 1603, 1606, 1608, 1553, 1611, 1613, 1581, 1571, 1580, 1620, + /* 460 */ 1586, 1576, 1587, 1625, 1593, 1583, 1590, 1627, 1598, 1585, + /* 470 */ 1596, 1634, 1636, 1637, 1638, 1547, 1550, 1605, 1629, 1652, + /* 480 */ 1626, 1628, 1630, 1631, 1619, 1621, 1633, 1635, 1640, 1641, + /* 490 */ 1669, 1649, 1677, 1651, 1639, 1678, 1657, 1645, 1682, 1648, + /* 500 */ 1684, 1650, 1686, 1665, 1670, 1689, 1560, 1659, 1695, 1524, + /* 510 */ 1675, 1565, 1570, 1698, 1700, 1575, 1577, 1701, 1702, 1711, + /* 520 */ 1607, 1644, 1534, 1712, 1642, 1589, 1646, 1714, 1680, 1567, + /* 530 */ 1653, 1647, 1679, 1690, 1493, 1654, 1655, 1658, 1660, 1661, + /* 540 */ 1666, 1694, 1664, 1667, 1674, 1688, 1691, 1720, 1699, 1718, + /* 550 */ 1693, 1731, 1505, 1696, 1697, 1729, 1573, 1733, 1734, 1738, + /* 560 */ 1703, 1736, 1514, 1704, 1750, 1751, 1752, 1753, 1756, 1757, + /* 570 */ 1704, 1791, 1772, 1602, 1755, 1715, 1710, 1716, 1717, 1721, + /* 580 */ 1719, 1762, 1725, 1726, 1767, 1780, 1623, 1730, 1723, 1735, + /* 590 */ 1781, 1785, 1740, 1737, 1792, 1741, 1742, 1794, 1745, 1746, + /* 600 */ 1798, 1749, 1766, 1800, 1776, 1727, 1728, 1759, 1761, 1816, + /* 610 */ 1743, 1777, 1778, 1807, 1779, 1822, 1822, 1844, 1809, 1812, + /* 620 */ 1841, 1810, 1797, 1832, 1846, 1848, 1850, 1851, 1853, 1867, + /* 630 */ 1855, 1856, 1825, 1619, 1860, 1621, 1861, 1862, 1863, 1865, + /* 640 */ 1866, 1876, 1877, 1902, 1886, 1875, 1890, 1931, 1898, 1887, + /* 650 */ 1896, 1936, 1903, 1892, 1901, 1937, 1906, 1895, 1904, 1944, + /* 660 */ 1910, 1911, 1947, 1926, 1928, 1930, 1932, 1929, 1933, }; -#define YY_REDUCE_COUNT (274) -#define YY_REDUCE_MIN (-312) -#define YY_REDUCE_MAX (1950) +#define YY_REDUCE_COUNT (275) +#define YY_REDUCE_MIN (-294) +#define YY_REDUCE_MAX (2181) static const short yy_reduce_ofst[] = { - /* 0 */ -78, -232, 63, 286, -113, 709, 787, 865, 907, 968, - /* 10 */ 545, 978, 1035, 1049, 1099, 1119, 1185, 1197, 1207, 1263, - /* 20 */ 1277, 1330, 1372, 1386, 1450, 1472, 1492, 1534, 1550, 1603, - /* 30 */ 1615, 1657, 1667, 1681, 1737, 1747, 1759, 1825, 1837, 1890, - /* 40 */ 1940, 1950, -263, 1944, -14, 75, 305, -278, 55, 270, - /* 50 */ 726, -296, 123, 184, 643, -266, -43, -260, -256, -303, - /* 60 */ -186, -230, -191, -185, 97, 315, 316, 363, 557, 563, - /* 70 */ 564, 566, -154, 659, 661, 665, -285, -106, 667, 732, - /* 80 */ 59, 24, 734, 72, 322, 82, 753, 70, -252, -312, - /* 90 */ -312, -312, -117, -239, -114, -20, 141, 181, 196, 289, - /* 100 */ 328, 435, 455, 505, 575, 672, 766, 769, 773, 780, - /* 110 */ 792, 809, 817, 299, -110, 124, 138, -220, 148, -243, - /* 120 */ 218, 310, 364, 150, 354, 349, 336, 456, 319, 205, - /* 130 */ 474, 498, 476, 562, -280, -270, 382, 513, 538, 633, - /* 140 */ 669, 641, 748, 366, 644, 654, 756, 735, 695, 791, - /* 150 */ 791, 811, 825, 794, 776, 757, 757, 757, 763, 742, - /* 160 */ 744, 745, 778, 791, 851, 820, 881, 844, 900, 859, - /* 170 */ 917, 926, 901, 913, 914, 950, 953, 955, 964, 965, - /* 180 */ 908, 957, 929, 961, 920, 927, 976, 933, 979, 943, - /* 190 */ 981, 982, 987, 985, 996, 971, 972, 973, 975, 984, - /* 200 */ 989, 992, 995, 998, 999, 1000, 1002, 1005, 967, 952, - /* 210 */ 1003, 969, 986, 1022, 1025, 1029, 1006, 1028, 1004, 1017, - /* 220 */ 1018, 1020, 1027, 1021, 1031, 1024, 1044, 1026, 1071, 1058, - /* 230 */ 1076, 1048, 1023, 1047, 991, 1041, 1050, 1055, 993, 1046, - /* 240 */ 1059, 1060, 791, 997, 1012, 1016, 1030, 1032, 1036, 1065, - /* 250 */ 757, 1100, 1069, 1034, 1033, 1038, 1042, 1057, 1068, 1070, - /* 260 */ 1073, 1122, 1109, 1131, 1143, 1149, 1161, 1159, 1103, 1113, - /* 270 */ 1157, 1162, 1167, 1169, 1171, + /* 0 */ -254, -201, 706, 23, 282, 787, 933, 975, 1038, 1088, + /* 10 */ 542, 877, 1098, 1180, 1234, 1258, 1312, 1322, 1372, 1422, + /* 20 */ 1434, 1512, 1028, 1522, 1572, 1582, 1592, 1673, 1692, 1754, + /* 30 */ 1770, 1823, 1840, 1893, 1905, 1974, 1988, 2030, 2082, 2100, + /* 40 */ 2124, 2181, 1173, 2172, -240, -263, -19, 207, 352, -277, + /* 50 */ 345, 813, -142, -141, -140, -79, 3, -267, 29, -260, + /* 60 */ -229, -274, -258, -143, -40, -159, 70, 285, 327, 329, + /* 70 */ 369, 370, 531, 535, -270, 541, 554, 560, -294, -272, + /* 80 */ 561, 594, 59, -257, 674, -124, 89, 270, 725, 377, + /* 90 */ -226, -219, -219, -219, -176, -247, -202, -15, 52, 63, + /* 100 */ 247, 394, 434, 507, 511, 581, 582, 626, 663, 672, + /* 110 */ 697, 748, 750, 753, 754, -158, -82, -162, -87, -262, + /* 120 */ 68, -215, 406, 589, 596, 215, 305, 379, 83, 236, + /* 130 */ 509, 298, 445, 699, 715, 469, 362, 591, 633, 640, + /* 140 */ 656, 714, 789, 631, 825, 814, 716, 744, 863, 826, + /* 150 */ 792, 850, 850, 889, 893, 862, 833, 810, 810, 810, + /* 160 */ 818, 797, 799, 802, 809, 850, 849, 911, 856, 910, + /* 170 */ 866, 918, 919, 887, 890, 891, 930, 932, 934, 939, + /* 180 */ 942, 884, 936, 915, 948, 912, 908, 955, 916, 958, + /* 190 */ 924, 965, 967, 970, 968, 979, 956, 957, 959, 960, + /* 200 */ 961, 962, 963, 964, 974, 976, 985, 978, 991, 981, + /* 210 */ 951, 1007, 969, 982, 1017, 1024, 1025, 980, 1019, 983, + /* 220 */ 993, 996, 998, 999, 989, 1001, 995, 1008, 997, 1043, + /* 230 */ 1031, 1055, 1022, 1004, 1026, 986, 1030, 1027, 1029, 987, + /* 240 */ 1032, 1035, 1036, 850, 992, 977, 988, 1006, 1033, 1037, + /* 250 */ 1042, 810, 1058, 1051, 1009, 1012, 1011, 1013, 1015, 1034, + /* 260 */ 1039, 1059, 1114, 1096, 1122, 1134, 1133, 1147, 1149, 1094, + /* 270 */ 1100, 1160, 1161, 1162, 1157, 1159, }; static const YYACTIONTYPE yy_default[] = { - /* 0 */ 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, - /* 10 */ 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, - /* 20 */ 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, - /* 30 */ 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, - /* 40 */ 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, - /* 50 */ 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, - /* 60 */ 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, - /* 70 */ 1459, 1459, 1533, 1459, 1459, 1459, 1459, 1459, 1459, 1459, - /* 80 */ 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1531, 1686, 1459, - /* 90 */ 1864, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, - /* 100 */ 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, - /* 110 */ 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1533, 1459, 1531, - /* 120 */ 1876, 1876, 1876, 1459, 1459, 1459, 1730, 1730, 1459, 1459, - /* 130 */ 1459, 1459, 1629, 1459, 1459, 1459, 1459, 1459, 1459, 1459, - /* 140 */ 1459, 1722, 1459, 1459, 1945, 1459, 1459, 1728, 1899, 1459, - /* 150 */ 1459, 1459, 1459, 1582, 1891, 1868, 1882, 1869, 1866, 1930, - /* 160 */ 1930, 1930, 1885, 1459, 1598, 1895, 1459, 1459, 1459, 1714, - /* 170 */ 1459, 1459, 1691, 1688, 1688, 1459, 1459, 1459, 1459, 1459, - /* 180 */ 1459, 1533, 1459, 1533, 1459, 1459, 1533, 1459, 1533, 1459, - /* 190 */ 1533, 1533, 1459, 1533, 1459, 1459, 1459, 1459, 1459, 1459, - /* 200 */ 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, - /* 210 */ 1531, 1724, 1459, 1531, 1459, 1459, 1459, 1531, 1904, 1459, - /* 220 */ 1459, 1459, 1459, 1904, 1459, 1459, 1459, 1459, 1531, 1459, - /* 230 */ 1531, 1459, 1459, 1459, 1906, 1904, 1459, 1459, 1906, 1904, - /* 240 */ 1459, 1459, 1459, 1918, 1914, 1906, 1922, 1920, 1897, 1895, - /* 250 */ 1882, 1459, 1459, 1936, 1932, 1948, 1936, 1932, 1936, 1932, - /* 260 */ 1459, 1598, 1459, 1459, 1459, 1531, 1491, 1459, 1716, 1730, - /* 270 */ 1632, 1632, 1632, 1534, 1464, 1459, 1459, 1459, 1459, 1459, - /* 280 */ 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1802, 1917, 1916, - /* 290 */ 1840, 1839, 1838, 1836, 1801, 1459, 1594, 1800, 1799, 1459, - /* 300 */ 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1793, 1794, 1792, - /* 310 */ 1791, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, - /* 320 */ 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1865, - /* 330 */ 1459, 1933, 1937, 1459, 1459, 1459, 1459, 1459, 1776, 1459, - /* 340 */ 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, - /* 350 */ 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, - /* 360 */ 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, - /* 370 */ 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, - /* 380 */ 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, - /* 390 */ 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, - /* 400 */ 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, - /* 410 */ 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, - /* 420 */ 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, - /* 430 */ 1459, 1459, 1459, 1459, 1496, 1459, 1459, 1459, 1459, 1459, - /* 440 */ 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, - /* 450 */ 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, - /* 460 */ 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, - /* 470 */ 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, - /* 480 */ 1459, 1563, 1562, 1459, 1459, 1459, 1459, 1459, 1459, 1459, - /* 490 */ 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, - /* 500 */ 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, - /* 510 */ 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, - /* 520 */ 1734, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, - /* 530 */ 1898, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, - /* 540 */ 1459, 1459, 1459, 1459, 1459, 1459, 1776, 1459, 1915, 1459, - /* 550 */ 1875, 1871, 1459, 1459, 1867, 1775, 1459, 1459, 1931, 1459, - /* 560 */ 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1860, 1459, - /* 570 */ 1459, 1833, 1818, 1459, 1459, 1459, 1459, 1459, 1459, 1459, - /* 580 */ 1459, 1459, 1459, 1787, 1459, 1459, 1459, 1459, 1459, 1626, - /* 590 */ 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, - /* 600 */ 1459, 1459, 1611, 1609, 1608, 1607, 1459, 1604, 1459, 1459, - /* 610 */ 1459, 1459, 1635, 1634, 1459, 1459, 1459, 1459, 1459, 1459, - /* 620 */ 1554, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, - /* 630 */ 1545, 1459, 1544, 1459, 1459, 1459, 1459, 1459, 1459, 1459, - /* 640 */ 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, - /* 650 */ 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, 1459, - /* 660 */ 1459, 1459, 1459, 1459, 1459, 1459, + /* 0 */ 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, + /* 10 */ 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, + /* 20 */ 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, + /* 30 */ 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, + /* 40 */ 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, + /* 50 */ 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, + /* 60 */ 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, + /* 70 */ 1465, 1465, 1465, 1465, 1539, 1465, 1465, 1465, 1465, 1465, + /* 80 */ 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1537, + /* 90 */ 1692, 1465, 1872, 1465, 1465, 1465, 1465, 1465, 1465, 1465, + /* 100 */ 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, + /* 110 */ 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1539, + /* 120 */ 1465, 1537, 1884, 1884, 1884, 1465, 1465, 1465, 1736, 1736, + /* 130 */ 1465, 1465, 1465, 1465, 1635, 1465, 1465, 1465, 1465, 1465, + /* 140 */ 1465, 1465, 1465, 1728, 1465, 1465, 1953, 1465, 1465, 1734, + /* 150 */ 1907, 1465, 1465, 1465, 1465, 1588, 1899, 1876, 1890, 1877, + /* 160 */ 1874, 1938, 1938, 1938, 1893, 1465, 1903, 1465, 1465, 1465, + /* 170 */ 1720, 1465, 1465, 1697, 1694, 1694, 1465, 1465, 1465, 1465, + /* 180 */ 1465, 1465, 1539, 1465, 1539, 1465, 1465, 1539, 1465, 1539, + /* 190 */ 1465, 1539, 1539, 1465, 1539, 1465, 1465, 1465, 1465, 1465, + /* 200 */ 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, + /* 210 */ 1465, 1537, 1730, 1465, 1537, 1465, 1465, 1465, 1537, 1912, + /* 220 */ 1465, 1465, 1465, 1465, 1912, 1465, 1465, 1465, 1465, 1537, + /* 230 */ 1465, 1537, 1465, 1465, 1465, 1914, 1912, 1465, 1465, 1914, + /* 240 */ 1912, 1465, 1465, 1465, 1926, 1922, 1914, 1930, 1928, 1905, + /* 250 */ 1903, 1890, 1465, 1465, 1944, 1940, 1956, 1944, 1940, 1944, + /* 260 */ 1940, 1465, 1604, 1465, 1465, 1465, 1537, 1497, 1465, 1722, + /* 270 */ 1736, 1638, 1638, 1638, 1540, 1470, 1465, 1465, 1465, 1465, + /* 280 */ 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1809, 1925, + /* 290 */ 1924, 1848, 1847, 1846, 1844, 1808, 1465, 1600, 1807, 1806, + /* 300 */ 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1800, 1801, + /* 310 */ 1799, 1798, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, + /* 320 */ 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, + /* 330 */ 1465, 1873, 1465, 1941, 1945, 1465, 1465, 1465, 1465, 1465, + /* 340 */ 1783, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, + /* 350 */ 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, + /* 360 */ 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, + /* 370 */ 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, + /* 380 */ 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, + /* 390 */ 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, + /* 400 */ 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, + /* 410 */ 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, + /* 420 */ 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, + /* 430 */ 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1502, 1465, 1465, + /* 440 */ 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, + /* 450 */ 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, + /* 460 */ 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, + /* 470 */ 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, + /* 480 */ 1465, 1465, 1465, 1465, 1569, 1568, 1465, 1465, 1465, 1465, + /* 490 */ 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, + /* 500 */ 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, + /* 510 */ 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, + /* 520 */ 1465, 1465, 1465, 1740, 1465, 1465, 1465, 1465, 1465, 1465, + /* 530 */ 1465, 1465, 1465, 1906, 1465, 1465, 1465, 1465, 1465, 1465, + /* 540 */ 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1783, + /* 550 */ 1465, 1923, 1465, 1883, 1879, 1465, 1465, 1875, 1782, 1465, + /* 560 */ 1465, 1939, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, + /* 570 */ 1465, 1868, 1465, 1465, 1841, 1826, 1465, 1465, 1465, 1465, + /* 580 */ 1465, 1465, 1465, 1465, 1465, 1465, 1794, 1465, 1465, 1465, + /* 590 */ 1465, 1465, 1632, 1465, 1465, 1465, 1465, 1465, 1465, 1465, + /* 600 */ 1465, 1465, 1465, 1465, 1465, 1617, 1615, 1614, 1613, 1465, + /* 610 */ 1610, 1465, 1465, 1465, 1465, 1641, 1640, 1465, 1465, 1465, + /* 620 */ 1465, 1465, 1465, 1560, 1465, 1465, 1465, 1465, 1465, 1465, + /* 630 */ 1465, 1465, 1465, 1551, 1465, 1550, 1465, 1465, 1465, 1465, + /* 640 */ 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, + /* 650 */ 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, + /* 660 */ 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, 1465, }; /********** End of lemon-generated parsing tables *****************************/ @@ -1075,10 +1121,11 @@ static const YYCODETYPE yyFallback[] = { 0, /* NK_ARROW => nothing */ 0, /* ROWTS => nothing */ 0, /* TBNAME => nothing */ - 0, /* QSTARTTS => nothing */ - 0, /* QENDTS => nothing */ - 0, /* WSTARTTS => nothing */ - 0, /* WENDTS => nothing */ + 0, /* QSTART => nothing */ + 0, /* QEND => nothing */ + 0, /* QDURATION => nothing */ + 0, /* WSTART => nothing */ + 0, /* WEND => nothing */ 0, /* WDURATION => nothing */ 0, /* CAST => nothing */ 0, /* NOW => nothing */ @@ -1127,11 +1174,11 @@ static const YYCODETYPE yyFallback[] = { 0, /* ASC => nothing */ 0, /* NULLS => nothing */ 0, /* ID => nothing */ - 249, /* NK_BITNOT => ID */ - 249, /* VALUES => ID */ - 249, /* IMPORT => ID */ - 249, /* NK_SEMI => ID */ - 249, /* FILE => ID */ + 250, /* NK_BITNOT => ID */ + 250, /* VALUES => ID */ + 250, /* IMPORT => ID */ + 250, /* NK_SEMI => ID */ + 250, /* FILE => ID */ }; #endif /* YYFALLBACK */ @@ -1417,186 +1464,187 @@ static const char *const yyTokenName[] = { /* 195 */ "NK_ARROW", /* 196 */ "ROWTS", /* 197 */ "TBNAME", - /* 198 */ "QSTARTTS", - /* 199 */ "QENDTS", - /* 200 */ "WSTARTTS", - /* 201 */ "WENDTS", - /* 202 */ "WDURATION", - /* 203 */ "CAST", - /* 204 */ "NOW", - /* 205 */ "TODAY", - /* 206 */ "TIMEZONE", - /* 207 */ "CLIENT_VERSION", - /* 208 */ "SERVER_VERSION", - /* 209 */ "SERVER_STATUS", - /* 210 */ "CURRENT_USER", - /* 211 */ "COUNT", - /* 212 */ "LAST_ROW", - /* 213 */ "BETWEEN", - /* 214 */ "IS", - /* 215 */ "NK_LT", - /* 216 */ "NK_GT", - /* 217 */ "NK_LE", - /* 218 */ "NK_GE", - /* 219 */ "NK_NE", - /* 220 */ "MATCH", - /* 221 */ "NMATCH", - /* 222 */ "CONTAINS", - /* 223 */ "JOIN", - /* 224 */ "INNER", - /* 225 */ "SELECT", - /* 226 */ "DISTINCT", - /* 227 */ "WHERE", - /* 228 */ "PARTITION", - /* 229 */ "BY", - /* 230 */ "SESSION", - /* 231 */ "STATE_WINDOW", - /* 232 */ "SLIDING", - /* 233 */ "FILL", - /* 234 */ "VALUE", - /* 235 */ "NONE", - /* 236 */ "PREV", - /* 237 */ "LINEAR", - /* 238 */ "NEXT", - /* 239 */ "HAVING", - /* 240 */ "RANGE", - /* 241 */ "EVERY", - /* 242 */ "ORDER", - /* 243 */ "SLIMIT", - /* 244 */ "SOFFSET", - /* 245 */ "LIMIT", - /* 246 */ "OFFSET", - /* 247 */ "ASC", - /* 248 */ "NULLS", - /* 249 */ "ID", - /* 250 */ "NK_BITNOT", - /* 251 */ "VALUES", - /* 252 */ "IMPORT", - /* 253 */ "NK_SEMI", - /* 254 */ "FILE", - /* 255 */ "cmd", - /* 256 */ "account_options", - /* 257 */ "alter_account_options", - /* 258 */ "literal", - /* 259 */ "alter_account_option", - /* 260 */ "user_name", - /* 261 */ "sysinfo_opt", - /* 262 */ "privileges", - /* 263 */ "priv_level", - /* 264 */ "priv_type_list", - /* 265 */ "priv_type", - /* 266 */ "db_name", - /* 267 */ "dnode_endpoint", - /* 268 */ "not_exists_opt", - /* 269 */ "db_options", - /* 270 */ "exists_opt", - /* 271 */ "alter_db_options", - /* 272 */ "integer_list", - /* 273 */ "variable_list", - /* 274 */ "retention_list", - /* 275 */ "alter_db_option", - /* 276 */ "retention", - /* 277 */ "full_table_name", - /* 278 */ "column_def_list", - /* 279 */ "tags_def_opt", - /* 280 */ "table_options", - /* 281 */ "multi_create_clause", - /* 282 */ "tags_def", - /* 283 */ "multi_drop_clause", - /* 284 */ "alter_table_clause", - /* 285 */ "alter_table_options", - /* 286 */ "column_name", - /* 287 */ "type_name", - /* 288 */ "signed_literal", - /* 289 */ "create_subtable_clause", - /* 290 */ "specific_cols_opt", - /* 291 */ "expression_list", - /* 292 */ "drop_table_clause", - /* 293 */ "col_name_list", - /* 294 */ "table_name", - /* 295 */ "column_def", - /* 296 */ "duration_list", - /* 297 */ "rollup_func_list", - /* 298 */ "alter_table_option", - /* 299 */ "duration_literal", - /* 300 */ "rollup_func_name", - /* 301 */ "function_name", - /* 302 */ "col_name", - /* 303 */ "db_name_cond_opt", - /* 304 */ "like_pattern_opt", - /* 305 */ "table_name_cond", - /* 306 */ "from_db_opt", - /* 307 */ "index_name", - /* 308 */ "index_options", - /* 309 */ "func_list", - /* 310 */ "sliding_opt", - /* 311 */ "sma_stream_opt", - /* 312 */ "func", - /* 313 */ "stream_options", - /* 314 */ "topic_name", - /* 315 */ "query_expression", - /* 316 */ "cgroup_name", - /* 317 */ "analyze_opt", - /* 318 */ "explain_options", - /* 319 */ "agg_func_opt", - /* 320 */ "bufsize_opt", - /* 321 */ "stream_name", - /* 322 */ "into_opt", - /* 323 */ "dnode_list", - /* 324 */ "where_clause_opt", - /* 325 */ "signed", - /* 326 */ "literal_func", - /* 327 */ "literal_list", - /* 328 */ "table_alias", - /* 329 */ "column_alias", - /* 330 */ "expression", - /* 331 */ "pseudo_column", - /* 332 */ "column_reference", - /* 333 */ "function_expression", - /* 334 */ "subquery", - /* 335 */ "star_func", - /* 336 */ "star_func_para_list", - /* 337 */ "noarg_func", - /* 338 */ "other_para_list", - /* 339 */ "star_func_para", - /* 340 */ "predicate", - /* 341 */ "compare_op", - /* 342 */ "in_op", - /* 343 */ "in_predicate_value", - /* 344 */ "boolean_value_expression", - /* 345 */ "boolean_primary", - /* 346 */ "common_expression", - /* 347 */ "from_clause_opt", - /* 348 */ "table_reference_list", - /* 349 */ "table_reference", - /* 350 */ "table_primary", - /* 351 */ "joined_table", - /* 352 */ "alias_opt", - /* 353 */ "parenthesized_joined_table", - /* 354 */ "join_type", - /* 355 */ "search_condition", - /* 356 */ "query_specification", - /* 357 */ "set_quantifier_opt", - /* 358 */ "select_list", - /* 359 */ "partition_by_clause_opt", - /* 360 */ "range_opt", - /* 361 */ "every_opt", - /* 362 */ "fill_opt", - /* 363 */ "twindow_clause_opt", - /* 364 */ "group_by_clause_opt", - /* 365 */ "having_clause_opt", - /* 366 */ "select_item", - /* 367 */ "fill_mode", - /* 368 */ "group_by_list", - /* 369 */ "query_expression_body", - /* 370 */ "order_by_clause_opt", - /* 371 */ "slimit_clause_opt", - /* 372 */ "limit_clause_opt", - /* 373 */ "query_primary", - /* 374 */ "sort_specification_list", - /* 375 */ "sort_specification", - /* 376 */ "ordering_specification_opt", - /* 377 */ "null_ordering_opt", + /* 198 */ "QSTART", + /* 199 */ "QEND", + /* 200 */ "QDURATION", + /* 201 */ "WSTART", + /* 202 */ "WEND", + /* 203 */ "WDURATION", + /* 204 */ "CAST", + /* 205 */ "NOW", + /* 206 */ "TODAY", + /* 207 */ "TIMEZONE", + /* 208 */ "CLIENT_VERSION", + /* 209 */ "SERVER_VERSION", + /* 210 */ "SERVER_STATUS", + /* 211 */ "CURRENT_USER", + /* 212 */ "COUNT", + /* 213 */ "LAST_ROW", + /* 214 */ "BETWEEN", + /* 215 */ "IS", + /* 216 */ "NK_LT", + /* 217 */ "NK_GT", + /* 218 */ "NK_LE", + /* 219 */ "NK_GE", + /* 220 */ "NK_NE", + /* 221 */ "MATCH", + /* 222 */ "NMATCH", + /* 223 */ "CONTAINS", + /* 224 */ "JOIN", + /* 225 */ "INNER", + /* 226 */ "SELECT", + /* 227 */ "DISTINCT", + /* 228 */ "WHERE", + /* 229 */ "PARTITION", + /* 230 */ "BY", + /* 231 */ "SESSION", + /* 232 */ "STATE_WINDOW", + /* 233 */ "SLIDING", + /* 234 */ "FILL", + /* 235 */ "VALUE", + /* 236 */ "NONE", + /* 237 */ "PREV", + /* 238 */ "LINEAR", + /* 239 */ "NEXT", + /* 240 */ "HAVING", + /* 241 */ "RANGE", + /* 242 */ "EVERY", + /* 243 */ "ORDER", + /* 244 */ "SLIMIT", + /* 245 */ "SOFFSET", + /* 246 */ "LIMIT", + /* 247 */ "OFFSET", + /* 248 */ "ASC", + /* 249 */ "NULLS", + /* 250 */ "ID", + /* 251 */ "NK_BITNOT", + /* 252 */ "VALUES", + /* 253 */ "IMPORT", + /* 254 */ "NK_SEMI", + /* 255 */ "FILE", + /* 256 */ "cmd", + /* 257 */ "account_options", + /* 258 */ "alter_account_options", + /* 259 */ "literal", + /* 260 */ "alter_account_option", + /* 261 */ "user_name", + /* 262 */ "sysinfo_opt", + /* 263 */ "privileges", + /* 264 */ "priv_level", + /* 265 */ "priv_type_list", + /* 266 */ "priv_type", + /* 267 */ "db_name", + /* 268 */ "dnode_endpoint", + /* 269 */ "not_exists_opt", + /* 270 */ "db_options", + /* 271 */ "exists_opt", + /* 272 */ "alter_db_options", + /* 273 */ "integer_list", + /* 274 */ "variable_list", + /* 275 */ "retention_list", + /* 276 */ "alter_db_option", + /* 277 */ "retention", + /* 278 */ "full_table_name", + /* 279 */ "column_def_list", + /* 280 */ "tags_def_opt", + /* 281 */ "table_options", + /* 282 */ "multi_create_clause", + /* 283 */ "tags_def", + /* 284 */ "multi_drop_clause", + /* 285 */ "alter_table_clause", + /* 286 */ "alter_table_options", + /* 287 */ "column_name", + /* 288 */ "type_name", + /* 289 */ "signed_literal", + /* 290 */ "create_subtable_clause", + /* 291 */ "specific_cols_opt", + /* 292 */ "expression_list", + /* 293 */ "drop_table_clause", + /* 294 */ "col_name_list", + /* 295 */ "table_name", + /* 296 */ "column_def", + /* 297 */ "duration_list", + /* 298 */ "rollup_func_list", + /* 299 */ "alter_table_option", + /* 300 */ "duration_literal", + /* 301 */ "rollup_func_name", + /* 302 */ "function_name", + /* 303 */ "col_name", + /* 304 */ "db_name_cond_opt", + /* 305 */ "like_pattern_opt", + /* 306 */ "table_name_cond", + /* 307 */ "from_db_opt", + /* 308 */ "index_name", + /* 309 */ "index_options", + /* 310 */ "func_list", + /* 311 */ "sliding_opt", + /* 312 */ "sma_stream_opt", + /* 313 */ "func", + /* 314 */ "stream_options", + /* 315 */ "topic_name", + /* 316 */ "query_expression", + /* 317 */ "cgroup_name", + /* 318 */ "analyze_opt", + /* 319 */ "explain_options", + /* 320 */ "agg_func_opt", + /* 321 */ "bufsize_opt", + /* 322 */ "stream_name", + /* 323 */ "into_opt", + /* 324 */ "dnode_list", + /* 325 */ "where_clause_opt", + /* 326 */ "signed", + /* 327 */ "literal_func", + /* 328 */ "literal_list", + /* 329 */ "table_alias", + /* 330 */ "column_alias", + /* 331 */ "expression", + /* 332 */ "pseudo_column", + /* 333 */ "column_reference", + /* 334 */ "function_expression", + /* 335 */ "subquery", + /* 336 */ "star_func", + /* 337 */ "star_func_para_list", + /* 338 */ "noarg_func", + /* 339 */ "other_para_list", + /* 340 */ "star_func_para", + /* 341 */ "predicate", + /* 342 */ "compare_op", + /* 343 */ "in_op", + /* 344 */ "in_predicate_value", + /* 345 */ "boolean_value_expression", + /* 346 */ "boolean_primary", + /* 347 */ "common_expression", + /* 348 */ "from_clause_opt", + /* 349 */ "table_reference_list", + /* 350 */ "table_reference", + /* 351 */ "table_primary", + /* 352 */ "joined_table", + /* 353 */ "alias_opt", + /* 354 */ "parenthesized_joined_table", + /* 355 */ "join_type", + /* 356 */ "search_condition", + /* 357 */ "query_specification", + /* 358 */ "set_quantifier_opt", + /* 359 */ "select_list", + /* 360 */ "partition_by_clause_opt", + /* 361 */ "range_opt", + /* 362 */ "every_opt", + /* 363 */ "fill_opt", + /* 364 */ "twindow_clause_opt", + /* 365 */ "group_by_clause_opt", + /* 366 */ "having_clause_opt", + /* 367 */ "select_item", + /* 368 */ "fill_mode", + /* 369 */ "group_by_list", + /* 370 */ "query_expression_body", + /* 371 */ "order_by_clause_opt", + /* 372 */ "slimit_clause_opt", + /* 373 */ "limit_clause_opt", + /* 374 */ "query_primary", + /* 375 */ "sort_specification_list", + /* 376 */ "sort_specification", + /* 377 */ "ordering_specification_opt", + /* 378 */ "null_ordering_opt", }; #endif /* defined(YYCOVERAGE) || !defined(NDEBUG) */ @@ -1890,209 +1938,211 @@ static const char *const yyRuleName[] = { /* 283 */ "cmd ::= SYNCDB db_name REPLICA", /* 284 */ "cmd ::= DELETE FROM full_table_name where_clause_opt", /* 285 */ "cmd ::= query_expression", - /* 286 */ "cmd ::= INSERT INTO full_table_name specific_cols_opt query_expression", - /* 287 */ "literal ::= NK_INTEGER", - /* 288 */ "literal ::= NK_FLOAT", - /* 289 */ "literal ::= NK_STRING", - /* 290 */ "literal ::= NK_BOOL", - /* 291 */ "literal ::= TIMESTAMP NK_STRING", - /* 292 */ "literal ::= duration_literal", - /* 293 */ "literal ::= NULL", - /* 294 */ "literal ::= NK_QUESTION", - /* 295 */ "duration_literal ::= NK_VARIABLE", - /* 296 */ "signed ::= NK_INTEGER", - /* 297 */ "signed ::= NK_PLUS NK_INTEGER", - /* 298 */ "signed ::= NK_MINUS NK_INTEGER", - /* 299 */ "signed ::= NK_FLOAT", - /* 300 */ "signed ::= NK_PLUS NK_FLOAT", - /* 301 */ "signed ::= NK_MINUS NK_FLOAT", - /* 302 */ "signed_literal ::= signed", - /* 303 */ "signed_literal ::= NK_STRING", - /* 304 */ "signed_literal ::= NK_BOOL", - /* 305 */ "signed_literal ::= TIMESTAMP NK_STRING", - /* 306 */ "signed_literal ::= duration_literal", - /* 307 */ "signed_literal ::= NULL", - /* 308 */ "signed_literal ::= literal_func", - /* 309 */ "signed_literal ::= NK_QUESTION", - /* 310 */ "literal_list ::= signed_literal", - /* 311 */ "literal_list ::= literal_list NK_COMMA signed_literal", - /* 312 */ "db_name ::= NK_ID", - /* 313 */ "table_name ::= NK_ID", - /* 314 */ "column_name ::= NK_ID", - /* 315 */ "function_name ::= NK_ID", - /* 316 */ "table_alias ::= NK_ID", - /* 317 */ "column_alias ::= NK_ID", - /* 318 */ "user_name ::= NK_ID", - /* 319 */ "index_name ::= NK_ID", - /* 320 */ "topic_name ::= NK_ID", - /* 321 */ "stream_name ::= NK_ID", - /* 322 */ "cgroup_name ::= NK_ID", - /* 323 */ "expression ::= literal", - /* 324 */ "expression ::= pseudo_column", - /* 325 */ "expression ::= column_reference", - /* 326 */ "expression ::= function_expression", - /* 327 */ "expression ::= subquery", - /* 328 */ "expression ::= NK_LP expression NK_RP", - /* 329 */ "expression ::= NK_PLUS expression", - /* 330 */ "expression ::= NK_MINUS expression", - /* 331 */ "expression ::= expression NK_PLUS expression", - /* 332 */ "expression ::= expression NK_MINUS expression", - /* 333 */ "expression ::= expression NK_STAR expression", - /* 334 */ "expression ::= expression NK_SLASH expression", - /* 335 */ "expression ::= expression NK_REM expression", - /* 336 */ "expression ::= column_reference NK_ARROW NK_STRING", - /* 337 */ "expression ::= expression NK_BITAND expression", - /* 338 */ "expression ::= expression NK_BITOR expression", - /* 339 */ "expression_list ::= expression", - /* 340 */ "expression_list ::= expression_list NK_COMMA expression", - /* 341 */ "column_reference ::= column_name", - /* 342 */ "column_reference ::= table_name NK_DOT column_name", - /* 343 */ "pseudo_column ::= ROWTS", - /* 344 */ "pseudo_column ::= TBNAME", - /* 345 */ "pseudo_column ::= table_name NK_DOT TBNAME", - /* 346 */ "pseudo_column ::= QSTARTTS", - /* 347 */ "pseudo_column ::= QENDTS", - /* 348 */ "pseudo_column ::= WSTARTTS", - /* 349 */ "pseudo_column ::= WENDTS", - /* 350 */ "pseudo_column ::= WDURATION", - /* 351 */ "function_expression ::= function_name NK_LP expression_list NK_RP", - /* 352 */ "function_expression ::= star_func NK_LP star_func_para_list NK_RP", - /* 353 */ "function_expression ::= CAST NK_LP expression AS type_name NK_RP", - /* 354 */ "function_expression ::= literal_func", - /* 355 */ "literal_func ::= noarg_func NK_LP NK_RP", - /* 356 */ "literal_func ::= NOW", - /* 357 */ "noarg_func ::= NOW", - /* 358 */ "noarg_func ::= TODAY", - /* 359 */ "noarg_func ::= TIMEZONE", - /* 360 */ "noarg_func ::= DATABASE", - /* 361 */ "noarg_func ::= CLIENT_VERSION", - /* 362 */ "noarg_func ::= SERVER_VERSION", - /* 363 */ "noarg_func ::= SERVER_STATUS", - /* 364 */ "noarg_func ::= CURRENT_USER", - /* 365 */ "noarg_func ::= USER", - /* 366 */ "star_func ::= COUNT", - /* 367 */ "star_func ::= FIRST", - /* 368 */ "star_func ::= LAST", - /* 369 */ "star_func ::= LAST_ROW", - /* 370 */ "star_func_para_list ::= NK_STAR", - /* 371 */ "star_func_para_list ::= other_para_list", - /* 372 */ "other_para_list ::= star_func_para", - /* 373 */ "other_para_list ::= other_para_list NK_COMMA star_func_para", - /* 374 */ "star_func_para ::= expression", - /* 375 */ "star_func_para ::= table_name NK_DOT NK_STAR", - /* 376 */ "predicate ::= expression compare_op expression", - /* 377 */ "predicate ::= expression BETWEEN expression AND expression", - /* 378 */ "predicate ::= expression NOT BETWEEN expression AND expression", - /* 379 */ "predicate ::= expression IS NULL", - /* 380 */ "predicate ::= expression IS NOT NULL", - /* 381 */ "predicate ::= expression in_op in_predicate_value", - /* 382 */ "compare_op ::= NK_LT", - /* 383 */ "compare_op ::= NK_GT", - /* 384 */ "compare_op ::= NK_LE", - /* 385 */ "compare_op ::= NK_GE", - /* 386 */ "compare_op ::= NK_NE", - /* 387 */ "compare_op ::= NK_EQ", - /* 388 */ "compare_op ::= LIKE", - /* 389 */ "compare_op ::= NOT LIKE", - /* 390 */ "compare_op ::= MATCH", - /* 391 */ "compare_op ::= NMATCH", - /* 392 */ "compare_op ::= CONTAINS", - /* 393 */ "in_op ::= IN", - /* 394 */ "in_op ::= NOT IN", - /* 395 */ "in_predicate_value ::= NK_LP literal_list NK_RP", - /* 396 */ "boolean_value_expression ::= boolean_primary", - /* 397 */ "boolean_value_expression ::= NOT boolean_primary", - /* 398 */ "boolean_value_expression ::= boolean_value_expression OR boolean_value_expression", - /* 399 */ "boolean_value_expression ::= boolean_value_expression AND boolean_value_expression", - /* 400 */ "boolean_primary ::= predicate", - /* 401 */ "boolean_primary ::= NK_LP boolean_value_expression NK_RP", - /* 402 */ "common_expression ::= expression", - /* 403 */ "common_expression ::= boolean_value_expression", - /* 404 */ "from_clause_opt ::=", - /* 405 */ "from_clause_opt ::= FROM table_reference_list", - /* 406 */ "table_reference_list ::= table_reference", - /* 407 */ "table_reference_list ::= table_reference_list NK_COMMA table_reference", - /* 408 */ "table_reference ::= table_primary", - /* 409 */ "table_reference ::= joined_table", - /* 410 */ "table_primary ::= table_name alias_opt", - /* 411 */ "table_primary ::= db_name NK_DOT table_name alias_opt", - /* 412 */ "table_primary ::= subquery alias_opt", - /* 413 */ "table_primary ::= parenthesized_joined_table", - /* 414 */ "alias_opt ::=", - /* 415 */ "alias_opt ::= table_alias", - /* 416 */ "alias_opt ::= AS table_alias", - /* 417 */ "parenthesized_joined_table ::= NK_LP joined_table NK_RP", - /* 418 */ "parenthesized_joined_table ::= NK_LP parenthesized_joined_table NK_RP", - /* 419 */ "joined_table ::= table_reference join_type JOIN table_reference ON search_condition", - /* 420 */ "join_type ::=", - /* 421 */ "join_type ::= INNER", - /* 422 */ "query_specification ::= SELECT set_quantifier_opt select_list from_clause_opt where_clause_opt partition_by_clause_opt range_opt every_opt fill_opt twindow_clause_opt group_by_clause_opt having_clause_opt", - /* 423 */ "set_quantifier_opt ::=", - /* 424 */ "set_quantifier_opt ::= DISTINCT", - /* 425 */ "set_quantifier_opt ::= ALL", - /* 426 */ "select_list ::= select_item", - /* 427 */ "select_list ::= select_list NK_COMMA select_item", - /* 428 */ "select_item ::= NK_STAR", - /* 429 */ "select_item ::= common_expression", - /* 430 */ "select_item ::= common_expression column_alias", - /* 431 */ "select_item ::= common_expression AS column_alias", - /* 432 */ "select_item ::= table_name NK_DOT NK_STAR", - /* 433 */ "where_clause_opt ::=", - /* 434 */ "where_clause_opt ::= WHERE search_condition", - /* 435 */ "partition_by_clause_opt ::=", - /* 436 */ "partition_by_clause_opt ::= PARTITION BY expression_list", - /* 437 */ "twindow_clause_opt ::=", - /* 438 */ "twindow_clause_opt ::= SESSION NK_LP column_reference NK_COMMA duration_literal NK_RP", - /* 439 */ "twindow_clause_opt ::= STATE_WINDOW NK_LP expression NK_RP", - /* 440 */ "twindow_clause_opt ::= INTERVAL NK_LP duration_literal NK_RP sliding_opt fill_opt", - /* 441 */ "twindow_clause_opt ::= INTERVAL NK_LP duration_literal NK_COMMA duration_literal NK_RP sliding_opt fill_opt", - /* 442 */ "sliding_opt ::=", - /* 443 */ "sliding_opt ::= SLIDING NK_LP duration_literal NK_RP", - /* 444 */ "fill_opt ::=", - /* 445 */ "fill_opt ::= FILL NK_LP fill_mode NK_RP", - /* 446 */ "fill_opt ::= FILL NK_LP VALUE NK_COMMA literal_list NK_RP", - /* 447 */ "fill_mode ::= NONE", - /* 448 */ "fill_mode ::= PREV", - /* 449 */ "fill_mode ::= NULL", - /* 450 */ "fill_mode ::= LINEAR", - /* 451 */ "fill_mode ::= NEXT", - /* 452 */ "group_by_clause_opt ::=", - /* 453 */ "group_by_clause_opt ::= GROUP BY group_by_list", - /* 454 */ "group_by_list ::= expression", - /* 455 */ "group_by_list ::= group_by_list NK_COMMA expression", - /* 456 */ "having_clause_opt ::=", - /* 457 */ "having_clause_opt ::= HAVING search_condition", - /* 458 */ "range_opt ::=", - /* 459 */ "range_opt ::= RANGE NK_LP expression NK_COMMA expression NK_RP", - /* 460 */ "every_opt ::=", - /* 461 */ "every_opt ::= EVERY NK_LP duration_literal NK_RP", - /* 462 */ "query_expression ::= query_expression_body order_by_clause_opt slimit_clause_opt limit_clause_opt", - /* 463 */ "query_expression_body ::= query_primary", - /* 464 */ "query_expression_body ::= query_expression_body UNION ALL query_expression_body", - /* 465 */ "query_expression_body ::= query_expression_body UNION query_expression_body", - /* 466 */ "query_primary ::= query_specification", - /* 467 */ "query_primary ::= NK_LP query_expression_body order_by_clause_opt slimit_clause_opt limit_clause_opt NK_RP", - /* 468 */ "order_by_clause_opt ::=", - /* 469 */ "order_by_clause_opt ::= ORDER BY sort_specification_list", - /* 470 */ "slimit_clause_opt ::=", - /* 471 */ "slimit_clause_opt ::= SLIMIT NK_INTEGER", - /* 472 */ "slimit_clause_opt ::= SLIMIT NK_INTEGER SOFFSET NK_INTEGER", - /* 473 */ "slimit_clause_opt ::= SLIMIT NK_INTEGER NK_COMMA NK_INTEGER", - /* 474 */ "limit_clause_opt ::=", - /* 475 */ "limit_clause_opt ::= LIMIT NK_INTEGER", - /* 476 */ "limit_clause_opt ::= LIMIT NK_INTEGER OFFSET NK_INTEGER", - /* 477 */ "limit_clause_opt ::= LIMIT NK_INTEGER NK_COMMA NK_INTEGER", - /* 478 */ "subquery ::= NK_LP query_expression NK_RP", - /* 479 */ "search_condition ::= common_expression", - /* 480 */ "sort_specification_list ::= sort_specification", - /* 481 */ "sort_specification_list ::= sort_specification_list NK_COMMA sort_specification", - /* 482 */ "sort_specification ::= expression ordering_specification_opt null_ordering_opt", - /* 483 */ "ordering_specification_opt ::=", - /* 484 */ "ordering_specification_opt ::= ASC", - /* 485 */ "ordering_specification_opt ::= DESC", - /* 486 */ "null_ordering_opt ::=", - /* 487 */ "null_ordering_opt ::= NULLS FIRST", - /* 488 */ "null_ordering_opt ::= NULLS LAST", + /* 286 */ "cmd ::= INSERT INTO full_table_name NK_LP col_name_list NK_RP query_expression", + /* 287 */ "cmd ::= INSERT INTO full_table_name query_expression", + /* 288 */ "literal ::= NK_INTEGER", + /* 289 */ "literal ::= NK_FLOAT", + /* 290 */ "literal ::= NK_STRING", + /* 291 */ "literal ::= NK_BOOL", + /* 292 */ "literal ::= TIMESTAMP NK_STRING", + /* 293 */ "literal ::= duration_literal", + /* 294 */ "literal ::= NULL", + /* 295 */ "literal ::= NK_QUESTION", + /* 296 */ "duration_literal ::= NK_VARIABLE", + /* 297 */ "signed ::= NK_INTEGER", + /* 298 */ "signed ::= NK_PLUS NK_INTEGER", + /* 299 */ "signed ::= NK_MINUS NK_INTEGER", + /* 300 */ "signed ::= NK_FLOAT", + /* 301 */ "signed ::= NK_PLUS NK_FLOAT", + /* 302 */ "signed ::= NK_MINUS NK_FLOAT", + /* 303 */ "signed_literal ::= signed", + /* 304 */ "signed_literal ::= NK_STRING", + /* 305 */ "signed_literal ::= NK_BOOL", + /* 306 */ "signed_literal ::= TIMESTAMP NK_STRING", + /* 307 */ "signed_literal ::= duration_literal", + /* 308 */ "signed_literal ::= NULL", + /* 309 */ "signed_literal ::= literal_func", + /* 310 */ "signed_literal ::= NK_QUESTION", + /* 311 */ "literal_list ::= signed_literal", + /* 312 */ "literal_list ::= literal_list NK_COMMA signed_literal", + /* 313 */ "db_name ::= NK_ID", + /* 314 */ "table_name ::= NK_ID", + /* 315 */ "column_name ::= NK_ID", + /* 316 */ "function_name ::= NK_ID", + /* 317 */ "table_alias ::= NK_ID", + /* 318 */ "column_alias ::= NK_ID", + /* 319 */ "user_name ::= NK_ID", + /* 320 */ "index_name ::= NK_ID", + /* 321 */ "topic_name ::= NK_ID", + /* 322 */ "stream_name ::= NK_ID", + /* 323 */ "cgroup_name ::= NK_ID", + /* 324 */ "expression ::= literal", + /* 325 */ "expression ::= pseudo_column", + /* 326 */ "expression ::= column_reference", + /* 327 */ "expression ::= function_expression", + /* 328 */ "expression ::= subquery", + /* 329 */ "expression ::= NK_LP expression NK_RP", + /* 330 */ "expression ::= NK_PLUS expression", + /* 331 */ "expression ::= NK_MINUS expression", + /* 332 */ "expression ::= expression NK_PLUS expression", + /* 333 */ "expression ::= expression NK_MINUS expression", + /* 334 */ "expression ::= expression NK_STAR expression", + /* 335 */ "expression ::= expression NK_SLASH expression", + /* 336 */ "expression ::= expression NK_REM expression", + /* 337 */ "expression ::= column_reference NK_ARROW NK_STRING", + /* 338 */ "expression ::= expression NK_BITAND expression", + /* 339 */ "expression ::= expression NK_BITOR expression", + /* 340 */ "expression_list ::= expression", + /* 341 */ "expression_list ::= expression_list NK_COMMA expression", + /* 342 */ "column_reference ::= column_name", + /* 343 */ "column_reference ::= table_name NK_DOT column_name", + /* 344 */ "pseudo_column ::= ROWTS", + /* 345 */ "pseudo_column ::= TBNAME", + /* 346 */ "pseudo_column ::= table_name NK_DOT TBNAME", + /* 347 */ "pseudo_column ::= QSTART", + /* 348 */ "pseudo_column ::= QEND", + /* 349 */ "pseudo_column ::= QDURATION", + /* 350 */ "pseudo_column ::= WSTART", + /* 351 */ "pseudo_column ::= WEND", + /* 352 */ "pseudo_column ::= WDURATION", + /* 353 */ "function_expression ::= function_name NK_LP expression_list NK_RP", + /* 354 */ "function_expression ::= star_func NK_LP star_func_para_list NK_RP", + /* 355 */ "function_expression ::= CAST NK_LP expression AS type_name NK_RP", + /* 356 */ "function_expression ::= literal_func", + /* 357 */ "literal_func ::= noarg_func NK_LP NK_RP", + /* 358 */ "literal_func ::= NOW", + /* 359 */ "noarg_func ::= NOW", + /* 360 */ "noarg_func ::= TODAY", + /* 361 */ "noarg_func ::= TIMEZONE", + /* 362 */ "noarg_func ::= DATABASE", + /* 363 */ "noarg_func ::= CLIENT_VERSION", + /* 364 */ "noarg_func ::= SERVER_VERSION", + /* 365 */ "noarg_func ::= SERVER_STATUS", + /* 366 */ "noarg_func ::= CURRENT_USER", + /* 367 */ "noarg_func ::= USER", + /* 368 */ "star_func ::= COUNT", + /* 369 */ "star_func ::= FIRST", + /* 370 */ "star_func ::= LAST", + /* 371 */ "star_func ::= LAST_ROW", + /* 372 */ "star_func_para_list ::= NK_STAR", + /* 373 */ "star_func_para_list ::= other_para_list", + /* 374 */ "other_para_list ::= star_func_para", + /* 375 */ "other_para_list ::= other_para_list NK_COMMA star_func_para", + /* 376 */ "star_func_para ::= expression", + /* 377 */ "star_func_para ::= table_name NK_DOT NK_STAR", + /* 378 */ "predicate ::= expression compare_op expression", + /* 379 */ "predicate ::= expression BETWEEN expression AND expression", + /* 380 */ "predicate ::= expression NOT BETWEEN expression AND expression", + /* 381 */ "predicate ::= expression IS NULL", + /* 382 */ "predicate ::= expression IS NOT NULL", + /* 383 */ "predicate ::= expression in_op in_predicate_value", + /* 384 */ "compare_op ::= NK_LT", + /* 385 */ "compare_op ::= NK_GT", + /* 386 */ "compare_op ::= NK_LE", + /* 387 */ "compare_op ::= NK_GE", + /* 388 */ "compare_op ::= NK_NE", + /* 389 */ "compare_op ::= NK_EQ", + /* 390 */ "compare_op ::= LIKE", + /* 391 */ "compare_op ::= NOT LIKE", + /* 392 */ "compare_op ::= MATCH", + /* 393 */ "compare_op ::= NMATCH", + /* 394 */ "compare_op ::= CONTAINS", + /* 395 */ "in_op ::= IN", + /* 396 */ "in_op ::= NOT IN", + /* 397 */ "in_predicate_value ::= NK_LP literal_list NK_RP", + /* 398 */ "boolean_value_expression ::= boolean_primary", + /* 399 */ "boolean_value_expression ::= NOT boolean_primary", + /* 400 */ "boolean_value_expression ::= boolean_value_expression OR boolean_value_expression", + /* 401 */ "boolean_value_expression ::= boolean_value_expression AND boolean_value_expression", + /* 402 */ "boolean_primary ::= predicate", + /* 403 */ "boolean_primary ::= NK_LP boolean_value_expression NK_RP", + /* 404 */ "common_expression ::= expression", + /* 405 */ "common_expression ::= boolean_value_expression", + /* 406 */ "from_clause_opt ::=", + /* 407 */ "from_clause_opt ::= FROM table_reference_list", + /* 408 */ "table_reference_list ::= table_reference", + /* 409 */ "table_reference_list ::= table_reference_list NK_COMMA table_reference", + /* 410 */ "table_reference ::= table_primary", + /* 411 */ "table_reference ::= joined_table", + /* 412 */ "table_primary ::= table_name alias_opt", + /* 413 */ "table_primary ::= db_name NK_DOT table_name alias_opt", + /* 414 */ "table_primary ::= subquery alias_opt", + /* 415 */ "table_primary ::= parenthesized_joined_table", + /* 416 */ "alias_opt ::=", + /* 417 */ "alias_opt ::= table_alias", + /* 418 */ "alias_opt ::= AS table_alias", + /* 419 */ "parenthesized_joined_table ::= NK_LP joined_table NK_RP", + /* 420 */ "parenthesized_joined_table ::= NK_LP parenthesized_joined_table NK_RP", + /* 421 */ "joined_table ::= table_reference join_type JOIN table_reference ON search_condition", + /* 422 */ "join_type ::=", + /* 423 */ "join_type ::= INNER", + /* 424 */ "query_specification ::= SELECT set_quantifier_opt select_list from_clause_opt where_clause_opt partition_by_clause_opt range_opt every_opt fill_opt twindow_clause_opt group_by_clause_opt having_clause_opt", + /* 425 */ "set_quantifier_opt ::=", + /* 426 */ "set_quantifier_opt ::= DISTINCT", + /* 427 */ "set_quantifier_opt ::= ALL", + /* 428 */ "select_list ::= select_item", + /* 429 */ "select_list ::= select_list NK_COMMA select_item", + /* 430 */ "select_item ::= NK_STAR", + /* 431 */ "select_item ::= common_expression", + /* 432 */ "select_item ::= common_expression column_alias", + /* 433 */ "select_item ::= common_expression AS column_alias", + /* 434 */ "select_item ::= table_name NK_DOT NK_STAR", + /* 435 */ "where_clause_opt ::=", + /* 436 */ "where_clause_opt ::= WHERE search_condition", + /* 437 */ "partition_by_clause_opt ::=", + /* 438 */ "partition_by_clause_opt ::= PARTITION BY expression_list", + /* 439 */ "twindow_clause_opt ::=", + /* 440 */ "twindow_clause_opt ::= SESSION NK_LP column_reference NK_COMMA duration_literal NK_RP", + /* 441 */ "twindow_clause_opt ::= STATE_WINDOW NK_LP expression NK_RP", + /* 442 */ "twindow_clause_opt ::= INTERVAL NK_LP duration_literal NK_RP sliding_opt fill_opt", + /* 443 */ "twindow_clause_opt ::= INTERVAL NK_LP duration_literal NK_COMMA duration_literal NK_RP sliding_opt fill_opt", + /* 444 */ "sliding_opt ::=", + /* 445 */ "sliding_opt ::= SLIDING NK_LP duration_literal NK_RP", + /* 446 */ "fill_opt ::=", + /* 447 */ "fill_opt ::= FILL NK_LP fill_mode NK_RP", + /* 448 */ "fill_opt ::= FILL NK_LP VALUE NK_COMMA literal_list NK_RP", + /* 449 */ "fill_mode ::= NONE", + /* 450 */ "fill_mode ::= PREV", + /* 451 */ "fill_mode ::= NULL", + /* 452 */ "fill_mode ::= LINEAR", + /* 453 */ "fill_mode ::= NEXT", + /* 454 */ "group_by_clause_opt ::=", + /* 455 */ "group_by_clause_opt ::= GROUP BY group_by_list", + /* 456 */ "group_by_list ::= expression", + /* 457 */ "group_by_list ::= group_by_list NK_COMMA expression", + /* 458 */ "having_clause_opt ::=", + /* 459 */ "having_clause_opt ::= HAVING search_condition", + /* 460 */ "range_opt ::=", + /* 461 */ "range_opt ::= RANGE NK_LP expression NK_COMMA expression NK_RP", + /* 462 */ "every_opt ::=", + /* 463 */ "every_opt ::= EVERY NK_LP duration_literal NK_RP", + /* 464 */ "query_expression ::= query_expression_body order_by_clause_opt slimit_clause_opt limit_clause_opt", + /* 465 */ "query_expression_body ::= query_primary", + /* 466 */ "query_expression_body ::= query_expression_body UNION ALL query_expression_body", + /* 467 */ "query_expression_body ::= query_expression_body UNION query_expression_body", + /* 468 */ "query_primary ::= query_specification", + /* 469 */ "query_primary ::= NK_LP query_expression_body order_by_clause_opt slimit_clause_opt limit_clause_opt NK_RP", + /* 470 */ "order_by_clause_opt ::=", + /* 471 */ "order_by_clause_opt ::= ORDER BY sort_specification_list", + /* 472 */ "slimit_clause_opt ::=", + /* 473 */ "slimit_clause_opt ::= SLIMIT NK_INTEGER", + /* 474 */ "slimit_clause_opt ::= SLIMIT NK_INTEGER SOFFSET NK_INTEGER", + /* 475 */ "slimit_clause_opt ::= SLIMIT NK_INTEGER NK_COMMA NK_INTEGER", + /* 476 */ "limit_clause_opt ::=", + /* 477 */ "limit_clause_opt ::= LIMIT NK_INTEGER", + /* 478 */ "limit_clause_opt ::= LIMIT NK_INTEGER OFFSET NK_INTEGER", + /* 479 */ "limit_clause_opt ::= LIMIT NK_INTEGER NK_COMMA NK_INTEGER", + /* 480 */ "subquery ::= NK_LP query_expression NK_RP", + /* 481 */ "search_condition ::= common_expression", + /* 482 */ "sort_specification_list ::= sort_specification", + /* 483 */ "sort_specification_list ::= sort_specification_list NK_COMMA sort_specification", + /* 484 */ "sort_specification ::= expression ordering_specification_opt null_ordering_opt", + /* 485 */ "ordering_specification_opt ::=", + /* 486 */ "ordering_specification_opt ::= ASC", + /* 487 */ "ordering_specification_opt ::= DESC", + /* 488 */ "null_ordering_opt ::=", + /* 489 */ "null_ordering_opt ::= NULLS FIRST", + /* 490 */ "null_ordering_opt ::= NULLS LAST", }; #endif /* NDEBUG */ @@ -2219,181 +2269,181 @@ static void yy_destructor( */ /********* Begin destructor definitions ***************************************/ /* Default NON-TERMINAL Destructor */ - case 255: /* cmd */ - case 258: /* literal */ - case 269: /* db_options */ - case 271: /* alter_db_options */ - case 276: /* retention */ - case 277: /* full_table_name */ - case 280: /* table_options */ - case 284: /* alter_table_clause */ - case 285: /* alter_table_options */ - case 288: /* signed_literal */ - case 289: /* create_subtable_clause */ - case 292: /* drop_table_clause */ - case 295: /* column_def */ - case 299: /* duration_literal */ - case 300: /* rollup_func_name */ - case 302: /* col_name */ - case 303: /* db_name_cond_opt */ - case 304: /* like_pattern_opt */ - case 305: /* table_name_cond */ - case 306: /* from_db_opt */ - case 308: /* index_options */ - case 310: /* sliding_opt */ - case 311: /* sma_stream_opt */ - case 312: /* func */ - case 313: /* stream_options */ - case 315: /* query_expression */ - case 318: /* explain_options */ - case 322: /* into_opt */ - case 324: /* where_clause_opt */ - case 325: /* signed */ - case 326: /* literal_func */ - case 330: /* expression */ - case 331: /* pseudo_column */ - case 332: /* column_reference */ - case 333: /* function_expression */ - case 334: /* subquery */ - case 339: /* star_func_para */ - case 340: /* predicate */ - case 343: /* in_predicate_value */ - case 344: /* boolean_value_expression */ - case 345: /* boolean_primary */ - case 346: /* common_expression */ - case 347: /* from_clause_opt */ - case 348: /* table_reference_list */ - case 349: /* table_reference */ - case 350: /* table_primary */ - case 351: /* joined_table */ - case 353: /* parenthesized_joined_table */ - case 355: /* search_condition */ - case 356: /* query_specification */ - case 360: /* range_opt */ - case 361: /* every_opt */ - case 362: /* fill_opt */ - case 363: /* twindow_clause_opt */ - case 365: /* having_clause_opt */ - case 366: /* select_item */ - case 369: /* query_expression_body */ - case 371: /* slimit_clause_opt */ - case 372: /* limit_clause_opt */ - case 373: /* query_primary */ - case 375: /* sort_specification */ + case 256: /* cmd */ + case 259: /* literal */ + case 270: /* db_options */ + case 272: /* alter_db_options */ + case 277: /* retention */ + case 278: /* full_table_name */ + case 281: /* table_options */ + case 285: /* alter_table_clause */ + case 286: /* alter_table_options */ + case 289: /* signed_literal */ + case 290: /* create_subtable_clause */ + case 293: /* drop_table_clause */ + case 296: /* column_def */ + case 300: /* duration_literal */ + case 301: /* rollup_func_name */ + case 303: /* col_name */ + case 304: /* db_name_cond_opt */ + case 305: /* like_pattern_opt */ + case 306: /* table_name_cond */ + case 307: /* from_db_opt */ + case 309: /* index_options */ + case 311: /* sliding_opt */ + case 312: /* sma_stream_opt */ + case 313: /* func */ + case 314: /* stream_options */ + case 316: /* query_expression */ + case 319: /* explain_options */ + case 323: /* into_opt */ + case 325: /* where_clause_opt */ + case 326: /* signed */ + case 327: /* literal_func */ + case 331: /* expression */ + case 332: /* pseudo_column */ + case 333: /* column_reference */ + case 334: /* function_expression */ + case 335: /* subquery */ + case 340: /* star_func_para */ + case 341: /* predicate */ + case 344: /* in_predicate_value */ + case 345: /* boolean_value_expression */ + case 346: /* boolean_primary */ + case 347: /* common_expression */ + case 348: /* from_clause_opt */ + case 349: /* table_reference_list */ + case 350: /* table_reference */ + case 351: /* table_primary */ + case 352: /* joined_table */ + case 354: /* parenthesized_joined_table */ + case 356: /* search_condition */ + case 357: /* query_specification */ + case 361: /* range_opt */ + case 362: /* every_opt */ + case 363: /* fill_opt */ + case 364: /* twindow_clause_opt */ + case 366: /* having_clause_opt */ + case 367: /* select_item */ + case 370: /* query_expression_body */ + case 372: /* slimit_clause_opt */ + case 373: /* limit_clause_opt */ + case 374: /* query_primary */ + case 376: /* sort_specification */ { - nodesDestroyNode((yypminor->yy560)); + nodesDestroyNode((yypminor->yy616)); } break; - case 256: /* account_options */ - case 257: /* alter_account_options */ - case 259: /* alter_account_option */ - case 320: /* bufsize_opt */ + case 257: /* account_options */ + case 258: /* alter_account_options */ + case 260: /* alter_account_option */ + case 321: /* bufsize_opt */ { } break; - case 260: /* user_name */ - case 263: /* priv_level */ - case 266: /* db_name */ - case 267: /* dnode_endpoint */ - case 286: /* column_name */ - case 294: /* table_name */ - case 301: /* function_name */ - case 307: /* index_name */ - case 314: /* topic_name */ - case 316: /* cgroup_name */ - case 321: /* stream_name */ - case 328: /* table_alias */ - case 329: /* column_alias */ - case 335: /* star_func */ - case 337: /* noarg_func */ - case 352: /* alias_opt */ + case 261: /* user_name */ + case 264: /* priv_level */ + case 267: /* db_name */ + case 268: /* dnode_endpoint */ + case 287: /* column_name */ + case 295: /* table_name */ + case 302: /* function_name */ + case 308: /* index_name */ + case 315: /* topic_name */ + case 317: /* cgroup_name */ + case 322: /* stream_name */ + case 329: /* table_alias */ + case 330: /* column_alias */ + case 336: /* star_func */ + case 338: /* noarg_func */ + case 353: /* alias_opt */ { } break; - case 261: /* sysinfo_opt */ + case 262: /* sysinfo_opt */ { } break; - case 262: /* privileges */ - case 264: /* priv_type_list */ - case 265: /* priv_type */ + case 263: /* privileges */ + case 265: /* priv_type_list */ + case 266: /* priv_type */ { } break; - case 268: /* not_exists_opt */ - case 270: /* exists_opt */ - case 317: /* analyze_opt */ - case 319: /* agg_func_opt */ - case 357: /* set_quantifier_opt */ + case 269: /* not_exists_opt */ + case 271: /* exists_opt */ + case 318: /* analyze_opt */ + case 320: /* agg_func_opt */ + case 358: /* set_quantifier_opt */ { } break; - case 272: /* integer_list */ - case 273: /* variable_list */ - case 274: /* retention_list */ - case 278: /* column_def_list */ - case 279: /* tags_def_opt */ - case 281: /* multi_create_clause */ - case 282: /* tags_def */ - case 283: /* multi_drop_clause */ - case 290: /* specific_cols_opt */ - case 291: /* expression_list */ - case 293: /* col_name_list */ - case 296: /* duration_list */ - case 297: /* rollup_func_list */ - case 309: /* func_list */ - case 323: /* dnode_list */ - case 327: /* literal_list */ - case 336: /* star_func_para_list */ - case 338: /* other_para_list */ - case 358: /* select_list */ - case 359: /* partition_by_clause_opt */ - case 364: /* group_by_clause_opt */ - case 368: /* group_by_list */ - case 370: /* order_by_clause_opt */ - case 374: /* sort_specification_list */ + case 273: /* integer_list */ + case 274: /* variable_list */ + case 275: /* retention_list */ + case 279: /* column_def_list */ + case 280: /* tags_def_opt */ + case 282: /* multi_create_clause */ + case 283: /* tags_def */ + case 284: /* multi_drop_clause */ + case 291: /* specific_cols_opt */ + case 292: /* expression_list */ + case 294: /* col_name_list */ + case 297: /* duration_list */ + case 298: /* rollup_func_list */ + case 310: /* func_list */ + case 324: /* dnode_list */ + case 328: /* literal_list */ + case 337: /* star_func_para_list */ + case 339: /* other_para_list */ + case 359: /* select_list */ + case 360: /* partition_by_clause_opt */ + case 365: /* group_by_clause_opt */ + case 369: /* group_by_list */ + case 371: /* order_by_clause_opt */ + case 375: /* sort_specification_list */ { - nodesDestroyList((yypminor->yy712)); + nodesDestroyList((yypminor->yy356)); } break; - case 275: /* alter_db_option */ - case 298: /* alter_table_option */ + case 276: /* alter_db_option */ + case 299: /* alter_table_option */ { } break; - case 287: /* type_name */ + case 288: /* type_name */ { } break; - case 341: /* compare_op */ - case 342: /* in_op */ + case 342: /* compare_op */ + case 343: /* in_op */ { } break; - case 354: /* join_type */ + case 355: /* join_type */ { } break; - case 367: /* fill_mode */ + case 368: /* fill_mode */ { } break; - case 376: /* ordering_specification_opt */ + case 377: /* ordering_specification_opt */ { } break; - case 377: /* null_ordering_opt */ + case 378: /* null_ordering_opt */ { } @@ -2692,495 +2742,497 @@ static const struct { YYCODETYPE lhs; /* Symbol on the left-hand side of the rule */ signed char nrhs; /* Negative of the number of RHS symbols in the rule */ } yyRuleInfo[] = { - { 255, -6 }, /* (0) cmd ::= CREATE ACCOUNT NK_ID PASS NK_STRING account_options */ - { 255, -4 }, /* (1) cmd ::= ALTER ACCOUNT NK_ID alter_account_options */ - { 256, 0 }, /* (2) account_options ::= */ - { 256, -3 }, /* (3) account_options ::= account_options PPS literal */ - { 256, -3 }, /* (4) account_options ::= account_options TSERIES literal */ - { 256, -3 }, /* (5) account_options ::= account_options STORAGE literal */ - { 256, -3 }, /* (6) account_options ::= account_options STREAMS literal */ - { 256, -3 }, /* (7) account_options ::= account_options QTIME literal */ - { 256, -3 }, /* (8) account_options ::= account_options DBS literal */ - { 256, -3 }, /* (9) account_options ::= account_options USERS literal */ - { 256, -3 }, /* (10) account_options ::= account_options CONNS literal */ - { 256, -3 }, /* (11) account_options ::= account_options STATE literal */ - { 257, -1 }, /* (12) alter_account_options ::= alter_account_option */ - { 257, -2 }, /* (13) alter_account_options ::= alter_account_options alter_account_option */ - { 259, -2 }, /* (14) alter_account_option ::= PASS literal */ - { 259, -2 }, /* (15) alter_account_option ::= PPS literal */ - { 259, -2 }, /* (16) alter_account_option ::= TSERIES literal */ - { 259, -2 }, /* (17) alter_account_option ::= STORAGE literal */ - { 259, -2 }, /* (18) alter_account_option ::= STREAMS literal */ - { 259, -2 }, /* (19) alter_account_option ::= QTIME literal */ - { 259, -2 }, /* (20) alter_account_option ::= DBS literal */ - { 259, -2 }, /* (21) alter_account_option ::= USERS literal */ - { 259, -2 }, /* (22) alter_account_option ::= CONNS literal */ - { 259, -2 }, /* (23) alter_account_option ::= STATE literal */ - { 255, -6 }, /* (24) cmd ::= CREATE USER user_name PASS NK_STRING sysinfo_opt */ - { 255, -5 }, /* (25) cmd ::= ALTER USER user_name PASS NK_STRING */ - { 255, -5 }, /* (26) cmd ::= ALTER USER user_name ENABLE NK_INTEGER */ - { 255, -5 }, /* (27) cmd ::= ALTER USER user_name SYSINFO NK_INTEGER */ - { 255, -3 }, /* (28) cmd ::= DROP USER user_name */ - { 261, 0 }, /* (29) sysinfo_opt ::= */ - { 261, -2 }, /* (30) sysinfo_opt ::= SYSINFO NK_INTEGER */ - { 255, -6 }, /* (31) cmd ::= GRANT privileges ON priv_level TO user_name */ - { 255, -6 }, /* (32) cmd ::= REVOKE privileges ON priv_level FROM user_name */ - { 262, -1 }, /* (33) privileges ::= ALL */ - { 262, -1 }, /* (34) privileges ::= priv_type_list */ - { 264, -1 }, /* (35) priv_type_list ::= priv_type */ - { 264, -3 }, /* (36) priv_type_list ::= priv_type_list NK_COMMA priv_type */ - { 265, -1 }, /* (37) priv_type ::= READ */ - { 265, -1 }, /* (38) priv_type ::= WRITE */ - { 263, -3 }, /* (39) priv_level ::= NK_STAR NK_DOT NK_STAR */ - { 263, -3 }, /* (40) priv_level ::= db_name NK_DOT NK_STAR */ - { 255, -3 }, /* (41) cmd ::= CREATE DNODE dnode_endpoint */ - { 255, -5 }, /* (42) cmd ::= CREATE DNODE dnode_endpoint PORT NK_INTEGER */ - { 255, -3 }, /* (43) cmd ::= DROP DNODE NK_INTEGER */ - { 255, -3 }, /* (44) cmd ::= DROP DNODE dnode_endpoint */ - { 255, -4 }, /* (45) cmd ::= ALTER DNODE NK_INTEGER NK_STRING */ - { 255, -5 }, /* (46) cmd ::= ALTER DNODE NK_INTEGER NK_STRING NK_STRING */ - { 255, -4 }, /* (47) cmd ::= ALTER ALL DNODES NK_STRING */ - { 255, -5 }, /* (48) cmd ::= ALTER ALL DNODES NK_STRING NK_STRING */ - { 267, -1 }, /* (49) dnode_endpoint ::= NK_STRING */ - { 267, -1 }, /* (50) dnode_endpoint ::= NK_ID */ - { 267, -1 }, /* (51) dnode_endpoint ::= NK_IPTOKEN */ - { 255, -3 }, /* (52) cmd ::= ALTER LOCAL NK_STRING */ - { 255, -4 }, /* (53) cmd ::= ALTER LOCAL NK_STRING NK_STRING */ - { 255, -5 }, /* (54) cmd ::= CREATE QNODE ON DNODE NK_INTEGER */ - { 255, -5 }, /* (55) cmd ::= DROP QNODE ON DNODE NK_INTEGER */ - { 255, -5 }, /* (56) cmd ::= CREATE BNODE ON DNODE NK_INTEGER */ - { 255, -5 }, /* (57) cmd ::= DROP BNODE ON DNODE NK_INTEGER */ - { 255, -5 }, /* (58) cmd ::= CREATE SNODE ON DNODE NK_INTEGER */ - { 255, -5 }, /* (59) cmd ::= DROP SNODE ON DNODE NK_INTEGER */ - { 255, -5 }, /* (60) cmd ::= CREATE MNODE ON DNODE NK_INTEGER */ - { 255, -5 }, /* (61) cmd ::= DROP MNODE ON DNODE NK_INTEGER */ - { 255, -5 }, /* (62) cmd ::= CREATE DATABASE not_exists_opt db_name db_options */ - { 255, -4 }, /* (63) cmd ::= DROP DATABASE exists_opt db_name */ - { 255, -2 }, /* (64) cmd ::= USE db_name */ - { 255, -4 }, /* (65) cmd ::= ALTER DATABASE db_name alter_db_options */ - { 255, -3 }, /* (66) cmd ::= FLUSH DATABASE db_name */ - { 255, -3 }, /* (67) cmd ::= TRIM DATABASE db_name */ - { 268, -3 }, /* (68) not_exists_opt ::= IF NOT EXISTS */ - { 268, 0 }, /* (69) not_exists_opt ::= */ - { 270, -2 }, /* (70) exists_opt ::= IF EXISTS */ - { 270, 0 }, /* (71) exists_opt ::= */ - { 269, 0 }, /* (72) db_options ::= */ - { 269, -3 }, /* (73) db_options ::= db_options BUFFER NK_INTEGER */ - { 269, -3 }, /* (74) db_options ::= db_options CACHELAST NK_INTEGER */ - { 269, -3 }, /* (75) db_options ::= db_options CACHELASTSIZE NK_INTEGER */ - { 269, -3 }, /* (76) db_options ::= db_options COMP NK_INTEGER */ - { 269, -3 }, /* (77) db_options ::= db_options DURATION NK_INTEGER */ - { 269, -3 }, /* (78) db_options ::= db_options DURATION NK_VARIABLE */ - { 269, -3 }, /* (79) db_options ::= db_options FSYNC NK_INTEGER */ - { 269, -3 }, /* (80) db_options ::= db_options MAXROWS NK_INTEGER */ - { 269, -3 }, /* (81) db_options ::= db_options MINROWS NK_INTEGER */ - { 269, -3 }, /* (82) db_options ::= db_options KEEP integer_list */ - { 269, -3 }, /* (83) db_options ::= db_options KEEP variable_list */ - { 269, -3 }, /* (84) db_options ::= db_options PAGES NK_INTEGER */ - { 269, -3 }, /* (85) db_options ::= db_options PAGESIZE NK_INTEGER */ - { 269, -3 }, /* (86) db_options ::= db_options PRECISION NK_STRING */ - { 269, -3 }, /* (87) db_options ::= db_options REPLICA NK_INTEGER */ - { 269, -3 }, /* (88) db_options ::= db_options STRICT NK_INTEGER */ - { 269, -3 }, /* (89) db_options ::= db_options WAL NK_INTEGER */ - { 269, -3 }, /* (90) db_options ::= db_options VGROUPS NK_INTEGER */ - { 269, -3 }, /* (91) db_options ::= db_options SINGLE_STABLE NK_INTEGER */ - { 269, -3 }, /* (92) db_options ::= db_options RETENTIONS retention_list */ - { 269, -3 }, /* (93) db_options ::= db_options SCHEMALESS NK_INTEGER */ - { 271, -1 }, /* (94) alter_db_options ::= alter_db_option */ - { 271, -2 }, /* (95) alter_db_options ::= alter_db_options alter_db_option */ - { 275, -2 }, /* (96) alter_db_option ::= BUFFER NK_INTEGER */ - { 275, -2 }, /* (97) alter_db_option ::= CACHELAST NK_INTEGER */ - { 275, -2 }, /* (98) alter_db_option ::= CACHELASTSIZE NK_INTEGER */ - { 275, -2 }, /* (99) alter_db_option ::= FSYNC NK_INTEGER */ - { 275, -2 }, /* (100) alter_db_option ::= KEEP integer_list */ - { 275, -2 }, /* (101) alter_db_option ::= KEEP variable_list */ - { 275, -2 }, /* (102) alter_db_option ::= PAGES NK_INTEGER */ - { 275, -2 }, /* (103) alter_db_option ::= REPLICA NK_INTEGER */ - { 275, -2 }, /* (104) alter_db_option ::= STRICT NK_INTEGER */ - { 275, -2 }, /* (105) alter_db_option ::= WAL NK_INTEGER */ - { 272, -1 }, /* (106) integer_list ::= NK_INTEGER */ - { 272, -3 }, /* (107) integer_list ::= integer_list NK_COMMA NK_INTEGER */ - { 273, -1 }, /* (108) variable_list ::= NK_VARIABLE */ - { 273, -3 }, /* (109) variable_list ::= variable_list NK_COMMA NK_VARIABLE */ - { 274, -1 }, /* (110) retention_list ::= retention */ - { 274, -3 }, /* (111) retention_list ::= retention_list NK_COMMA retention */ - { 276, -3 }, /* (112) retention ::= NK_VARIABLE NK_COLON NK_VARIABLE */ - { 255, -9 }, /* (113) cmd ::= CREATE TABLE not_exists_opt full_table_name NK_LP column_def_list NK_RP tags_def_opt table_options */ - { 255, -3 }, /* (114) cmd ::= CREATE TABLE multi_create_clause */ - { 255, -9 }, /* (115) cmd ::= CREATE STABLE not_exists_opt full_table_name NK_LP column_def_list NK_RP tags_def table_options */ - { 255, -3 }, /* (116) cmd ::= DROP TABLE multi_drop_clause */ - { 255, -4 }, /* (117) cmd ::= DROP STABLE exists_opt full_table_name */ - { 255, -3 }, /* (118) cmd ::= ALTER TABLE alter_table_clause */ - { 255, -3 }, /* (119) cmd ::= ALTER STABLE alter_table_clause */ - { 284, -2 }, /* (120) alter_table_clause ::= full_table_name alter_table_options */ - { 284, -5 }, /* (121) alter_table_clause ::= full_table_name ADD COLUMN column_name type_name */ - { 284, -4 }, /* (122) alter_table_clause ::= full_table_name DROP COLUMN column_name */ - { 284, -5 }, /* (123) alter_table_clause ::= full_table_name MODIFY COLUMN column_name type_name */ - { 284, -5 }, /* (124) alter_table_clause ::= full_table_name RENAME COLUMN column_name column_name */ - { 284, -5 }, /* (125) alter_table_clause ::= full_table_name ADD TAG column_name type_name */ - { 284, -4 }, /* (126) alter_table_clause ::= full_table_name DROP TAG column_name */ - { 284, -5 }, /* (127) alter_table_clause ::= full_table_name MODIFY TAG column_name type_name */ - { 284, -5 }, /* (128) alter_table_clause ::= full_table_name RENAME TAG column_name column_name */ - { 284, -6 }, /* (129) alter_table_clause ::= full_table_name SET TAG column_name NK_EQ signed_literal */ - { 281, -1 }, /* (130) multi_create_clause ::= create_subtable_clause */ - { 281, -2 }, /* (131) multi_create_clause ::= multi_create_clause create_subtable_clause */ - { 289, -10 }, /* (132) create_subtable_clause ::= not_exists_opt full_table_name USING full_table_name specific_cols_opt TAGS NK_LP expression_list NK_RP table_options */ - { 283, -1 }, /* (133) multi_drop_clause ::= drop_table_clause */ - { 283, -2 }, /* (134) multi_drop_clause ::= multi_drop_clause drop_table_clause */ - { 292, -2 }, /* (135) drop_table_clause ::= exists_opt full_table_name */ - { 290, 0 }, /* (136) specific_cols_opt ::= */ - { 290, -3 }, /* (137) specific_cols_opt ::= NK_LP col_name_list NK_RP */ - { 277, -1 }, /* (138) full_table_name ::= table_name */ - { 277, -3 }, /* (139) full_table_name ::= db_name NK_DOT table_name */ - { 278, -1 }, /* (140) column_def_list ::= column_def */ - { 278, -3 }, /* (141) column_def_list ::= column_def_list NK_COMMA column_def */ - { 295, -2 }, /* (142) column_def ::= column_name type_name */ - { 295, -4 }, /* (143) column_def ::= column_name type_name COMMENT NK_STRING */ - { 287, -1 }, /* (144) type_name ::= BOOL */ - { 287, -1 }, /* (145) type_name ::= TINYINT */ - { 287, -1 }, /* (146) type_name ::= SMALLINT */ - { 287, -1 }, /* (147) type_name ::= INT */ - { 287, -1 }, /* (148) type_name ::= INTEGER */ - { 287, -1 }, /* (149) type_name ::= BIGINT */ - { 287, -1 }, /* (150) type_name ::= FLOAT */ - { 287, -1 }, /* (151) type_name ::= DOUBLE */ - { 287, -4 }, /* (152) type_name ::= BINARY NK_LP NK_INTEGER NK_RP */ - { 287, -1 }, /* (153) type_name ::= TIMESTAMP */ - { 287, -4 }, /* (154) type_name ::= NCHAR NK_LP NK_INTEGER NK_RP */ - { 287, -2 }, /* (155) type_name ::= TINYINT UNSIGNED */ - { 287, -2 }, /* (156) type_name ::= SMALLINT UNSIGNED */ - { 287, -2 }, /* (157) type_name ::= INT UNSIGNED */ - { 287, -2 }, /* (158) type_name ::= BIGINT UNSIGNED */ - { 287, -1 }, /* (159) type_name ::= JSON */ - { 287, -4 }, /* (160) type_name ::= VARCHAR NK_LP NK_INTEGER NK_RP */ - { 287, -1 }, /* (161) type_name ::= MEDIUMBLOB */ - { 287, -1 }, /* (162) type_name ::= BLOB */ - { 287, -4 }, /* (163) type_name ::= VARBINARY NK_LP NK_INTEGER NK_RP */ - { 287, -1 }, /* (164) type_name ::= DECIMAL */ - { 287, -4 }, /* (165) type_name ::= DECIMAL NK_LP NK_INTEGER NK_RP */ - { 287, -6 }, /* (166) type_name ::= DECIMAL NK_LP NK_INTEGER NK_COMMA NK_INTEGER NK_RP */ - { 279, 0 }, /* (167) tags_def_opt ::= */ - { 279, -1 }, /* (168) tags_def_opt ::= tags_def */ - { 282, -4 }, /* (169) tags_def ::= TAGS NK_LP column_def_list NK_RP */ - { 280, 0 }, /* (170) table_options ::= */ - { 280, -3 }, /* (171) table_options ::= table_options COMMENT NK_STRING */ - { 280, -3 }, /* (172) table_options ::= table_options MAX_DELAY duration_list */ - { 280, -3 }, /* (173) table_options ::= table_options WATERMARK duration_list */ - { 280, -5 }, /* (174) table_options ::= table_options ROLLUP NK_LP rollup_func_list NK_RP */ - { 280, -3 }, /* (175) table_options ::= table_options TTL NK_INTEGER */ - { 280, -5 }, /* (176) table_options ::= table_options SMA NK_LP col_name_list NK_RP */ - { 285, -1 }, /* (177) alter_table_options ::= alter_table_option */ - { 285, -2 }, /* (178) alter_table_options ::= alter_table_options alter_table_option */ - { 298, -2 }, /* (179) alter_table_option ::= COMMENT NK_STRING */ - { 298, -2 }, /* (180) alter_table_option ::= TTL NK_INTEGER */ - { 296, -1 }, /* (181) duration_list ::= duration_literal */ - { 296, -3 }, /* (182) duration_list ::= duration_list NK_COMMA duration_literal */ - { 297, -1 }, /* (183) rollup_func_list ::= rollup_func_name */ - { 297, -3 }, /* (184) rollup_func_list ::= rollup_func_list NK_COMMA rollup_func_name */ - { 300, -1 }, /* (185) rollup_func_name ::= function_name */ - { 300, -1 }, /* (186) rollup_func_name ::= FIRST */ - { 300, -1 }, /* (187) rollup_func_name ::= LAST */ - { 293, -1 }, /* (188) col_name_list ::= col_name */ - { 293, -3 }, /* (189) col_name_list ::= col_name_list NK_COMMA col_name */ - { 302, -1 }, /* (190) col_name ::= column_name */ - { 255, -2 }, /* (191) cmd ::= SHOW DNODES */ - { 255, -2 }, /* (192) cmd ::= SHOW USERS */ - { 255, -2 }, /* (193) cmd ::= SHOW DATABASES */ - { 255, -4 }, /* (194) cmd ::= SHOW db_name_cond_opt TABLES like_pattern_opt */ - { 255, -4 }, /* (195) cmd ::= SHOW db_name_cond_opt STABLES like_pattern_opt */ - { 255, -3 }, /* (196) cmd ::= SHOW db_name_cond_opt VGROUPS */ - { 255, -2 }, /* (197) cmd ::= SHOW MNODES */ - { 255, -2 }, /* (198) cmd ::= SHOW MODULES */ - { 255, -2 }, /* (199) cmd ::= SHOW QNODES */ - { 255, -2 }, /* (200) cmd ::= SHOW FUNCTIONS */ - { 255, -5 }, /* (201) cmd ::= SHOW INDEXES FROM table_name_cond from_db_opt */ - { 255, -2 }, /* (202) cmd ::= SHOW STREAMS */ - { 255, -2 }, /* (203) cmd ::= SHOW ACCOUNTS */ - { 255, -2 }, /* (204) cmd ::= SHOW APPS */ - { 255, -2 }, /* (205) cmd ::= SHOW CONNECTIONS */ - { 255, -2 }, /* (206) cmd ::= SHOW LICENCE */ - { 255, -2 }, /* (207) cmd ::= SHOW GRANTS */ - { 255, -4 }, /* (208) cmd ::= SHOW CREATE DATABASE db_name */ - { 255, -4 }, /* (209) cmd ::= SHOW CREATE TABLE full_table_name */ - { 255, -4 }, /* (210) cmd ::= SHOW CREATE STABLE full_table_name */ - { 255, -2 }, /* (211) cmd ::= SHOW QUERIES */ - { 255, -2 }, /* (212) cmd ::= SHOW SCORES */ - { 255, -2 }, /* (213) cmd ::= SHOW TOPICS */ - { 255, -2 }, /* (214) cmd ::= SHOW VARIABLES */ - { 255, -3 }, /* (215) cmd ::= SHOW LOCAL VARIABLES */ - { 255, -4 }, /* (216) cmd ::= SHOW DNODE NK_INTEGER VARIABLES */ - { 255, -2 }, /* (217) cmd ::= SHOW BNODES */ - { 255, -2 }, /* (218) cmd ::= SHOW SNODES */ - { 255, -2 }, /* (219) cmd ::= SHOW CLUSTER */ - { 255, -2 }, /* (220) cmd ::= SHOW TRANSACTIONS */ - { 255, -4 }, /* (221) cmd ::= SHOW TABLE DISTRIBUTED full_table_name */ - { 255, -2 }, /* (222) cmd ::= SHOW CONSUMERS */ - { 255, -2 }, /* (223) cmd ::= SHOW SUBSCRIPTIONS */ - { 303, 0 }, /* (224) db_name_cond_opt ::= */ - { 303, -2 }, /* (225) db_name_cond_opt ::= db_name NK_DOT */ - { 304, 0 }, /* (226) like_pattern_opt ::= */ - { 304, -2 }, /* (227) like_pattern_opt ::= LIKE NK_STRING */ - { 305, -1 }, /* (228) table_name_cond ::= table_name */ - { 306, 0 }, /* (229) from_db_opt ::= */ - { 306, -2 }, /* (230) from_db_opt ::= FROM db_name */ - { 255, -8 }, /* (231) cmd ::= CREATE SMA INDEX not_exists_opt index_name ON table_name index_options */ - { 255, -4 }, /* (232) cmd ::= DROP INDEX exists_opt index_name */ - { 308, -10 }, /* (233) index_options ::= FUNCTION NK_LP func_list NK_RP INTERVAL NK_LP duration_literal NK_RP sliding_opt sma_stream_opt */ - { 308, -12 }, /* (234) index_options ::= FUNCTION NK_LP func_list NK_RP INTERVAL NK_LP duration_literal NK_COMMA duration_literal NK_RP sliding_opt sma_stream_opt */ - { 309, -1 }, /* (235) func_list ::= func */ - { 309, -3 }, /* (236) func_list ::= func_list NK_COMMA func */ - { 312, -4 }, /* (237) func ::= function_name NK_LP expression_list NK_RP */ - { 311, 0 }, /* (238) sma_stream_opt ::= */ - { 311, -3 }, /* (239) sma_stream_opt ::= stream_options WATERMARK duration_literal */ - { 311, -3 }, /* (240) sma_stream_opt ::= stream_options MAX_DELAY duration_literal */ - { 255, -6 }, /* (241) cmd ::= CREATE TOPIC not_exists_opt topic_name AS query_expression */ - { 255, -7 }, /* (242) cmd ::= CREATE TOPIC not_exists_opt topic_name AS DATABASE db_name */ - { 255, -9 }, /* (243) cmd ::= CREATE TOPIC not_exists_opt topic_name WITH META AS DATABASE db_name */ - { 255, -7 }, /* (244) cmd ::= CREATE TOPIC not_exists_opt topic_name AS STABLE full_table_name */ - { 255, -9 }, /* (245) cmd ::= CREATE TOPIC not_exists_opt topic_name WITH META AS STABLE full_table_name */ - { 255, -4 }, /* (246) cmd ::= DROP TOPIC exists_opt topic_name */ - { 255, -7 }, /* (247) cmd ::= DROP CONSUMER GROUP exists_opt cgroup_name ON topic_name */ - { 255, -2 }, /* (248) cmd ::= DESC full_table_name */ - { 255, -2 }, /* (249) cmd ::= DESCRIBE full_table_name */ - { 255, -3 }, /* (250) cmd ::= RESET QUERY CACHE */ - { 255, -4 }, /* (251) cmd ::= EXPLAIN analyze_opt explain_options query_expression */ - { 317, 0 }, /* (252) analyze_opt ::= */ - { 317, -1 }, /* (253) analyze_opt ::= ANALYZE */ - { 318, 0 }, /* (254) explain_options ::= */ - { 318, -3 }, /* (255) explain_options ::= explain_options VERBOSE NK_BOOL */ - { 318, -3 }, /* (256) explain_options ::= explain_options RATIO NK_FLOAT */ - { 255, -6 }, /* (257) cmd ::= COMPACT VNODES IN NK_LP integer_list NK_RP */ - { 255, -10 }, /* (258) cmd ::= CREATE agg_func_opt FUNCTION not_exists_opt function_name AS NK_STRING OUTPUTTYPE type_name bufsize_opt */ - { 255, -4 }, /* (259) cmd ::= DROP FUNCTION exists_opt function_name */ - { 319, 0 }, /* (260) agg_func_opt ::= */ - { 319, -1 }, /* (261) agg_func_opt ::= AGGREGATE */ - { 320, 0 }, /* (262) bufsize_opt ::= */ - { 320, -2 }, /* (263) bufsize_opt ::= BUFSIZE NK_INTEGER */ - { 255, -8 }, /* (264) cmd ::= CREATE STREAM not_exists_opt stream_name stream_options into_opt AS query_expression */ - { 255, -4 }, /* (265) cmd ::= DROP STREAM exists_opt stream_name */ - { 322, 0 }, /* (266) into_opt ::= */ - { 322, -2 }, /* (267) into_opt ::= INTO full_table_name */ - { 313, 0 }, /* (268) stream_options ::= */ - { 313, -3 }, /* (269) stream_options ::= stream_options TRIGGER AT_ONCE */ - { 313, -3 }, /* (270) stream_options ::= stream_options TRIGGER WINDOW_CLOSE */ - { 313, -4 }, /* (271) stream_options ::= stream_options TRIGGER MAX_DELAY duration_literal */ - { 313, -3 }, /* (272) stream_options ::= stream_options WATERMARK duration_literal */ - { 313, -3 }, /* (273) stream_options ::= stream_options IGNORE EXPIRED */ - { 255, -3 }, /* (274) cmd ::= KILL CONNECTION NK_INTEGER */ - { 255, -3 }, /* (275) cmd ::= KILL QUERY NK_STRING */ - { 255, -3 }, /* (276) cmd ::= KILL TRANSACTION NK_INTEGER */ - { 255, -2 }, /* (277) cmd ::= BALANCE VGROUP */ - { 255, -4 }, /* (278) cmd ::= MERGE VGROUP NK_INTEGER NK_INTEGER */ - { 255, -4 }, /* (279) cmd ::= REDISTRIBUTE VGROUP NK_INTEGER dnode_list */ - { 255, -3 }, /* (280) cmd ::= SPLIT VGROUP NK_INTEGER */ - { 323, -2 }, /* (281) dnode_list ::= DNODE NK_INTEGER */ - { 323, -3 }, /* (282) dnode_list ::= dnode_list DNODE NK_INTEGER */ - { 255, -3 }, /* (283) cmd ::= SYNCDB db_name REPLICA */ - { 255, -4 }, /* (284) cmd ::= DELETE FROM full_table_name where_clause_opt */ - { 255, -1 }, /* (285) cmd ::= query_expression */ - { 255, -5 }, /* (286) cmd ::= INSERT INTO full_table_name specific_cols_opt query_expression */ - { 258, -1 }, /* (287) literal ::= NK_INTEGER */ - { 258, -1 }, /* (288) literal ::= NK_FLOAT */ - { 258, -1 }, /* (289) literal ::= NK_STRING */ - { 258, -1 }, /* (290) literal ::= NK_BOOL */ - { 258, -2 }, /* (291) literal ::= TIMESTAMP NK_STRING */ - { 258, -1 }, /* (292) literal ::= duration_literal */ - { 258, -1 }, /* (293) literal ::= NULL */ - { 258, -1 }, /* (294) literal ::= NK_QUESTION */ - { 299, -1 }, /* (295) duration_literal ::= NK_VARIABLE */ - { 325, -1 }, /* (296) signed ::= NK_INTEGER */ - { 325, -2 }, /* (297) signed ::= NK_PLUS NK_INTEGER */ - { 325, -2 }, /* (298) signed ::= NK_MINUS NK_INTEGER */ - { 325, -1 }, /* (299) signed ::= NK_FLOAT */ - { 325, -2 }, /* (300) signed ::= NK_PLUS NK_FLOAT */ - { 325, -2 }, /* (301) signed ::= NK_MINUS NK_FLOAT */ - { 288, -1 }, /* (302) signed_literal ::= signed */ - { 288, -1 }, /* (303) signed_literal ::= NK_STRING */ - { 288, -1 }, /* (304) signed_literal ::= NK_BOOL */ - { 288, -2 }, /* (305) signed_literal ::= TIMESTAMP NK_STRING */ - { 288, -1 }, /* (306) signed_literal ::= duration_literal */ - { 288, -1 }, /* (307) signed_literal ::= NULL */ - { 288, -1 }, /* (308) signed_literal ::= literal_func */ - { 288, -1 }, /* (309) signed_literal ::= NK_QUESTION */ - { 327, -1 }, /* (310) literal_list ::= signed_literal */ - { 327, -3 }, /* (311) literal_list ::= literal_list NK_COMMA signed_literal */ - { 266, -1 }, /* (312) db_name ::= NK_ID */ - { 294, -1 }, /* (313) table_name ::= NK_ID */ - { 286, -1 }, /* (314) column_name ::= NK_ID */ - { 301, -1 }, /* (315) function_name ::= NK_ID */ - { 328, -1 }, /* (316) table_alias ::= NK_ID */ - { 329, -1 }, /* (317) column_alias ::= NK_ID */ - { 260, -1 }, /* (318) user_name ::= NK_ID */ - { 307, -1 }, /* (319) index_name ::= NK_ID */ - { 314, -1 }, /* (320) topic_name ::= NK_ID */ - { 321, -1 }, /* (321) stream_name ::= NK_ID */ - { 316, -1 }, /* (322) cgroup_name ::= NK_ID */ - { 330, -1 }, /* (323) expression ::= literal */ - { 330, -1 }, /* (324) expression ::= pseudo_column */ - { 330, -1 }, /* (325) expression ::= column_reference */ - { 330, -1 }, /* (326) expression ::= function_expression */ - { 330, -1 }, /* (327) expression ::= subquery */ - { 330, -3 }, /* (328) expression ::= NK_LP expression NK_RP */ - { 330, -2 }, /* (329) expression ::= NK_PLUS expression */ - { 330, -2 }, /* (330) expression ::= NK_MINUS expression */ - { 330, -3 }, /* (331) expression ::= expression NK_PLUS expression */ - { 330, -3 }, /* (332) expression ::= expression NK_MINUS expression */ - { 330, -3 }, /* (333) expression ::= expression NK_STAR expression */ - { 330, -3 }, /* (334) expression ::= expression NK_SLASH expression */ - { 330, -3 }, /* (335) expression ::= expression NK_REM expression */ - { 330, -3 }, /* (336) expression ::= column_reference NK_ARROW NK_STRING */ - { 330, -3 }, /* (337) expression ::= expression NK_BITAND expression */ - { 330, -3 }, /* (338) expression ::= expression NK_BITOR expression */ - { 291, -1 }, /* (339) expression_list ::= expression */ - { 291, -3 }, /* (340) expression_list ::= expression_list NK_COMMA expression */ - { 332, -1 }, /* (341) column_reference ::= column_name */ - { 332, -3 }, /* (342) column_reference ::= table_name NK_DOT column_name */ - { 331, -1 }, /* (343) pseudo_column ::= ROWTS */ - { 331, -1 }, /* (344) pseudo_column ::= TBNAME */ - { 331, -3 }, /* (345) pseudo_column ::= table_name NK_DOT TBNAME */ - { 331, -1 }, /* (346) pseudo_column ::= QSTARTTS */ - { 331, -1 }, /* (347) pseudo_column ::= QENDTS */ - { 331, -1 }, /* (348) pseudo_column ::= WSTARTTS */ - { 331, -1 }, /* (349) pseudo_column ::= WENDTS */ - { 331, -1 }, /* (350) pseudo_column ::= WDURATION */ - { 333, -4 }, /* (351) function_expression ::= function_name NK_LP expression_list NK_RP */ - { 333, -4 }, /* (352) function_expression ::= star_func NK_LP star_func_para_list NK_RP */ - { 333, -6 }, /* (353) function_expression ::= CAST NK_LP expression AS type_name NK_RP */ - { 333, -1 }, /* (354) function_expression ::= literal_func */ - { 326, -3 }, /* (355) literal_func ::= noarg_func NK_LP NK_RP */ - { 326, -1 }, /* (356) literal_func ::= NOW */ - { 337, -1 }, /* (357) noarg_func ::= NOW */ - { 337, -1 }, /* (358) noarg_func ::= TODAY */ - { 337, -1 }, /* (359) noarg_func ::= TIMEZONE */ - { 337, -1 }, /* (360) noarg_func ::= DATABASE */ - { 337, -1 }, /* (361) noarg_func ::= CLIENT_VERSION */ - { 337, -1 }, /* (362) noarg_func ::= SERVER_VERSION */ - { 337, -1 }, /* (363) noarg_func ::= SERVER_STATUS */ - { 337, -1 }, /* (364) noarg_func ::= CURRENT_USER */ - { 337, -1 }, /* (365) noarg_func ::= USER */ - { 335, -1 }, /* (366) star_func ::= COUNT */ - { 335, -1 }, /* (367) star_func ::= FIRST */ - { 335, -1 }, /* (368) star_func ::= LAST */ - { 335, -1 }, /* (369) star_func ::= LAST_ROW */ - { 336, -1 }, /* (370) star_func_para_list ::= NK_STAR */ - { 336, -1 }, /* (371) star_func_para_list ::= other_para_list */ - { 338, -1 }, /* (372) other_para_list ::= star_func_para */ - { 338, -3 }, /* (373) other_para_list ::= other_para_list NK_COMMA star_func_para */ - { 339, -1 }, /* (374) star_func_para ::= expression */ - { 339, -3 }, /* (375) star_func_para ::= table_name NK_DOT NK_STAR */ - { 340, -3 }, /* (376) predicate ::= expression compare_op expression */ - { 340, -5 }, /* (377) predicate ::= expression BETWEEN expression AND expression */ - { 340, -6 }, /* (378) predicate ::= expression NOT BETWEEN expression AND expression */ - { 340, -3 }, /* (379) predicate ::= expression IS NULL */ - { 340, -4 }, /* (380) predicate ::= expression IS NOT NULL */ - { 340, -3 }, /* (381) predicate ::= expression in_op in_predicate_value */ - { 341, -1 }, /* (382) compare_op ::= NK_LT */ - { 341, -1 }, /* (383) compare_op ::= NK_GT */ - { 341, -1 }, /* (384) compare_op ::= NK_LE */ - { 341, -1 }, /* (385) compare_op ::= NK_GE */ - { 341, -1 }, /* (386) compare_op ::= NK_NE */ - { 341, -1 }, /* (387) compare_op ::= NK_EQ */ - { 341, -1 }, /* (388) compare_op ::= LIKE */ - { 341, -2 }, /* (389) compare_op ::= NOT LIKE */ - { 341, -1 }, /* (390) compare_op ::= MATCH */ - { 341, -1 }, /* (391) compare_op ::= NMATCH */ - { 341, -1 }, /* (392) compare_op ::= CONTAINS */ - { 342, -1 }, /* (393) in_op ::= IN */ - { 342, -2 }, /* (394) in_op ::= NOT IN */ - { 343, -3 }, /* (395) in_predicate_value ::= NK_LP literal_list NK_RP */ - { 344, -1 }, /* (396) boolean_value_expression ::= boolean_primary */ - { 344, -2 }, /* (397) boolean_value_expression ::= NOT boolean_primary */ - { 344, -3 }, /* (398) boolean_value_expression ::= boolean_value_expression OR boolean_value_expression */ - { 344, -3 }, /* (399) boolean_value_expression ::= boolean_value_expression AND boolean_value_expression */ - { 345, -1 }, /* (400) boolean_primary ::= predicate */ - { 345, -3 }, /* (401) boolean_primary ::= NK_LP boolean_value_expression NK_RP */ - { 346, -1 }, /* (402) common_expression ::= expression */ - { 346, -1 }, /* (403) common_expression ::= boolean_value_expression */ - { 347, 0 }, /* (404) from_clause_opt ::= */ - { 347, -2 }, /* (405) from_clause_opt ::= FROM table_reference_list */ - { 348, -1 }, /* (406) table_reference_list ::= table_reference */ - { 348, -3 }, /* (407) table_reference_list ::= table_reference_list NK_COMMA table_reference */ - { 349, -1 }, /* (408) table_reference ::= table_primary */ - { 349, -1 }, /* (409) table_reference ::= joined_table */ - { 350, -2 }, /* (410) table_primary ::= table_name alias_opt */ - { 350, -4 }, /* (411) table_primary ::= db_name NK_DOT table_name alias_opt */ - { 350, -2 }, /* (412) table_primary ::= subquery alias_opt */ - { 350, -1 }, /* (413) table_primary ::= parenthesized_joined_table */ - { 352, 0 }, /* (414) alias_opt ::= */ - { 352, -1 }, /* (415) alias_opt ::= table_alias */ - { 352, -2 }, /* (416) alias_opt ::= AS table_alias */ - { 353, -3 }, /* (417) parenthesized_joined_table ::= NK_LP joined_table NK_RP */ - { 353, -3 }, /* (418) parenthesized_joined_table ::= NK_LP parenthesized_joined_table NK_RP */ - { 351, -6 }, /* (419) joined_table ::= table_reference join_type JOIN table_reference ON search_condition */ - { 354, 0 }, /* (420) join_type ::= */ - { 354, -1 }, /* (421) join_type ::= INNER */ - { 356, -12 }, /* (422) query_specification ::= SELECT set_quantifier_opt select_list from_clause_opt where_clause_opt partition_by_clause_opt range_opt every_opt fill_opt twindow_clause_opt group_by_clause_opt having_clause_opt */ - { 357, 0 }, /* (423) set_quantifier_opt ::= */ - { 357, -1 }, /* (424) set_quantifier_opt ::= DISTINCT */ - { 357, -1 }, /* (425) set_quantifier_opt ::= ALL */ - { 358, -1 }, /* (426) select_list ::= select_item */ - { 358, -3 }, /* (427) select_list ::= select_list NK_COMMA select_item */ - { 366, -1 }, /* (428) select_item ::= NK_STAR */ - { 366, -1 }, /* (429) select_item ::= common_expression */ - { 366, -2 }, /* (430) select_item ::= common_expression column_alias */ - { 366, -3 }, /* (431) select_item ::= common_expression AS column_alias */ - { 366, -3 }, /* (432) select_item ::= table_name NK_DOT NK_STAR */ - { 324, 0 }, /* (433) where_clause_opt ::= */ - { 324, -2 }, /* (434) where_clause_opt ::= WHERE search_condition */ - { 359, 0 }, /* (435) partition_by_clause_opt ::= */ - { 359, -3 }, /* (436) partition_by_clause_opt ::= PARTITION BY expression_list */ - { 363, 0 }, /* (437) twindow_clause_opt ::= */ - { 363, -6 }, /* (438) twindow_clause_opt ::= SESSION NK_LP column_reference NK_COMMA duration_literal NK_RP */ - { 363, -4 }, /* (439) twindow_clause_opt ::= STATE_WINDOW NK_LP expression NK_RP */ - { 363, -6 }, /* (440) twindow_clause_opt ::= INTERVAL NK_LP duration_literal NK_RP sliding_opt fill_opt */ - { 363, -8 }, /* (441) twindow_clause_opt ::= INTERVAL NK_LP duration_literal NK_COMMA duration_literal NK_RP sliding_opt fill_opt */ - { 310, 0 }, /* (442) sliding_opt ::= */ - { 310, -4 }, /* (443) sliding_opt ::= SLIDING NK_LP duration_literal NK_RP */ - { 362, 0 }, /* (444) fill_opt ::= */ - { 362, -4 }, /* (445) fill_opt ::= FILL NK_LP fill_mode NK_RP */ - { 362, -6 }, /* (446) fill_opt ::= FILL NK_LP VALUE NK_COMMA literal_list NK_RP */ - { 367, -1 }, /* (447) fill_mode ::= NONE */ - { 367, -1 }, /* (448) fill_mode ::= PREV */ - { 367, -1 }, /* (449) fill_mode ::= NULL */ - { 367, -1 }, /* (450) fill_mode ::= LINEAR */ - { 367, -1 }, /* (451) fill_mode ::= NEXT */ - { 364, 0 }, /* (452) group_by_clause_opt ::= */ - { 364, -3 }, /* (453) group_by_clause_opt ::= GROUP BY group_by_list */ - { 368, -1 }, /* (454) group_by_list ::= expression */ - { 368, -3 }, /* (455) group_by_list ::= group_by_list NK_COMMA expression */ - { 365, 0 }, /* (456) having_clause_opt ::= */ - { 365, -2 }, /* (457) having_clause_opt ::= HAVING search_condition */ - { 360, 0 }, /* (458) range_opt ::= */ - { 360, -6 }, /* (459) range_opt ::= RANGE NK_LP expression NK_COMMA expression NK_RP */ - { 361, 0 }, /* (460) every_opt ::= */ - { 361, -4 }, /* (461) every_opt ::= EVERY NK_LP duration_literal NK_RP */ - { 315, -4 }, /* (462) query_expression ::= query_expression_body order_by_clause_opt slimit_clause_opt limit_clause_opt */ - { 369, -1 }, /* (463) query_expression_body ::= query_primary */ - { 369, -4 }, /* (464) query_expression_body ::= query_expression_body UNION ALL query_expression_body */ - { 369, -3 }, /* (465) query_expression_body ::= query_expression_body UNION query_expression_body */ - { 373, -1 }, /* (466) query_primary ::= query_specification */ - { 373, -6 }, /* (467) query_primary ::= NK_LP query_expression_body order_by_clause_opt slimit_clause_opt limit_clause_opt NK_RP */ - { 370, 0 }, /* (468) order_by_clause_opt ::= */ - { 370, -3 }, /* (469) order_by_clause_opt ::= ORDER BY sort_specification_list */ - { 371, 0 }, /* (470) slimit_clause_opt ::= */ - { 371, -2 }, /* (471) slimit_clause_opt ::= SLIMIT NK_INTEGER */ - { 371, -4 }, /* (472) slimit_clause_opt ::= SLIMIT NK_INTEGER SOFFSET NK_INTEGER */ - { 371, -4 }, /* (473) slimit_clause_opt ::= SLIMIT NK_INTEGER NK_COMMA NK_INTEGER */ - { 372, 0 }, /* (474) limit_clause_opt ::= */ - { 372, -2 }, /* (475) limit_clause_opt ::= LIMIT NK_INTEGER */ - { 372, -4 }, /* (476) limit_clause_opt ::= LIMIT NK_INTEGER OFFSET NK_INTEGER */ - { 372, -4 }, /* (477) limit_clause_opt ::= LIMIT NK_INTEGER NK_COMMA NK_INTEGER */ - { 334, -3 }, /* (478) subquery ::= NK_LP query_expression NK_RP */ - { 355, -1 }, /* (479) search_condition ::= common_expression */ - { 374, -1 }, /* (480) sort_specification_list ::= sort_specification */ - { 374, -3 }, /* (481) sort_specification_list ::= sort_specification_list NK_COMMA sort_specification */ - { 375, -3 }, /* (482) sort_specification ::= expression ordering_specification_opt null_ordering_opt */ - { 376, 0 }, /* (483) ordering_specification_opt ::= */ - { 376, -1 }, /* (484) ordering_specification_opt ::= ASC */ - { 376, -1 }, /* (485) ordering_specification_opt ::= DESC */ - { 377, 0 }, /* (486) null_ordering_opt ::= */ - { 377, -2 }, /* (487) null_ordering_opt ::= NULLS FIRST */ - { 377, -2 }, /* (488) null_ordering_opt ::= NULLS LAST */ + { 256, -6 }, /* (0) cmd ::= CREATE ACCOUNT NK_ID PASS NK_STRING account_options */ + { 256, -4 }, /* (1) cmd ::= ALTER ACCOUNT NK_ID alter_account_options */ + { 257, 0 }, /* (2) account_options ::= */ + { 257, -3 }, /* (3) account_options ::= account_options PPS literal */ + { 257, -3 }, /* (4) account_options ::= account_options TSERIES literal */ + { 257, -3 }, /* (5) account_options ::= account_options STORAGE literal */ + { 257, -3 }, /* (6) account_options ::= account_options STREAMS literal */ + { 257, -3 }, /* (7) account_options ::= account_options QTIME literal */ + { 257, -3 }, /* (8) account_options ::= account_options DBS literal */ + { 257, -3 }, /* (9) account_options ::= account_options USERS literal */ + { 257, -3 }, /* (10) account_options ::= account_options CONNS literal */ + { 257, -3 }, /* (11) account_options ::= account_options STATE literal */ + { 258, -1 }, /* (12) alter_account_options ::= alter_account_option */ + { 258, -2 }, /* (13) alter_account_options ::= alter_account_options alter_account_option */ + { 260, -2 }, /* (14) alter_account_option ::= PASS literal */ + { 260, -2 }, /* (15) alter_account_option ::= PPS literal */ + { 260, -2 }, /* (16) alter_account_option ::= TSERIES literal */ + { 260, -2 }, /* (17) alter_account_option ::= STORAGE literal */ + { 260, -2 }, /* (18) alter_account_option ::= STREAMS literal */ + { 260, -2 }, /* (19) alter_account_option ::= QTIME literal */ + { 260, -2 }, /* (20) alter_account_option ::= DBS literal */ + { 260, -2 }, /* (21) alter_account_option ::= USERS literal */ + { 260, -2 }, /* (22) alter_account_option ::= CONNS literal */ + { 260, -2 }, /* (23) alter_account_option ::= STATE literal */ + { 256, -6 }, /* (24) cmd ::= CREATE USER user_name PASS NK_STRING sysinfo_opt */ + { 256, -5 }, /* (25) cmd ::= ALTER USER user_name PASS NK_STRING */ + { 256, -5 }, /* (26) cmd ::= ALTER USER user_name ENABLE NK_INTEGER */ + { 256, -5 }, /* (27) cmd ::= ALTER USER user_name SYSINFO NK_INTEGER */ + { 256, -3 }, /* (28) cmd ::= DROP USER user_name */ + { 262, 0 }, /* (29) sysinfo_opt ::= */ + { 262, -2 }, /* (30) sysinfo_opt ::= SYSINFO NK_INTEGER */ + { 256, -6 }, /* (31) cmd ::= GRANT privileges ON priv_level TO user_name */ + { 256, -6 }, /* (32) cmd ::= REVOKE privileges ON priv_level FROM user_name */ + { 263, -1 }, /* (33) privileges ::= ALL */ + { 263, -1 }, /* (34) privileges ::= priv_type_list */ + { 265, -1 }, /* (35) priv_type_list ::= priv_type */ + { 265, -3 }, /* (36) priv_type_list ::= priv_type_list NK_COMMA priv_type */ + { 266, -1 }, /* (37) priv_type ::= READ */ + { 266, -1 }, /* (38) priv_type ::= WRITE */ + { 264, -3 }, /* (39) priv_level ::= NK_STAR NK_DOT NK_STAR */ + { 264, -3 }, /* (40) priv_level ::= db_name NK_DOT NK_STAR */ + { 256, -3 }, /* (41) cmd ::= CREATE DNODE dnode_endpoint */ + { 256, -5 }, /* (42) cmd ::= CREATE DNODE dnode_endpoint PORT NK_INTEGER */ + { 256, -3 }, /* (43) cmd ::= DROP DNODE NK_INTEGER */ + { 256, -3 }, /* (44) cmd ::= DROP DNODE dnode_endpoint */ + { 256, -4 }, /* (45) cmd ::= ALTER DNODE NK_INTEGER NK_STRING */ + { 256, -5 }, /* (46) cmd ::= ALTER DNODE NK_INTEGER NK_STRING NK_STRING */ + { 256, -4 }, /* (47) cmd ::= ALTER ALL DNODES NK_STRING */ + { 256, -5 }, /* (48) cmd ::= ALTER ALL DNODES NK_STRING NK_STRING */ + { 268, -1 }, /* (49) dnode_endpoint ::= NK_STRING */ + { 268, -1 }, /* (50) dnode_endpoint ::= NK_ID */ + { 268, -1 }, /* (51) dnode_endpoint ::= NK_IPTOKEN */ + { 256, -3 }, /* (52) cmd ::= ALTER LOCAL NK_STRING */ + { 256, -4 }, /* (53) cmd ::= ALTER LOCAL NK_STRING NK_STRING */ + { 256, -5 }, /* (54) cmd ::= CREATE QNODE ON DNODE NK_INTEGER */ + { 256, -5 }, /* (55) cmd ::= DROP QNODE ON DNODE NK_INTEGER */ + { 256, -5 }, /* (56) cmd ::= CREATE BNODE ON DNODE NK_INTEGER */ + { 256, -5 }, /* (57) cmd ::= DROP BNODE ON DNODE NK_INTEGER */ + { 256, -5 }, /* (58) cmd ::= CREATE SNODE ON DNODE NK_INTEGER */ + { 256, -5 }, /* (59) cmd ::= DROP SNODE ON DNODE NK_INTEGER */ + { 256, -5 }, /* (60) cmd ::= CREATE MNODE ON DNODE NK_INTEGER */ + { 256, -5 }, /* (61) cmd ::= DROP MNODE ON DNODE NK_INTEGER */ + { 256, -5 }, /* (62) cmd ::= CREATE DATABASE not_exists_opt db_name db_options */ + { 256, -4 }, /* (63) cmd ::= DROP DATABASE exists_opt db_name */ + { 256, -2 }, /* (64) cmd ::= USE db_name */ + { 256, -4 }, /* (65) cmd ::= ALTER DATABASE db_name alter_db_options */ + { 256, -3 }, /* (66) cmd ::= FLUSH DATABASE db_name */ + { 256, -3 }, /* (67) cmd ::= TRIM DATABASE db_name */ + { 269, -3 }, /* (68) not_exists_opt ::= IF NOT EXISTS */ + { 269, 0 }, /* (69) not_exists_opt ::= */ + { 271, -2 }, /* (70) exists_opt ::= IF EXISTS */ + { 271, 0 }, /* (71) exists_opt ::= */ + { 270, 0 }, /* (72) db_options ::= */ + { 270, -3 }, /* (73) db_options ::= db_options BUFFER NK_INTEGER */ + { 270, -3 }, /* (74) db_options ::= db_options CACHELAST NK_INTEGER */ + { 270, -3 }, /* (75) db_options ::= db_options CACHELASTSIZE NK_INTEGER */ + { 270, -3 }, /* (76) db_options ::= db_options COMP NK_INTEGER */ + { 270, -3 }, /* (77) db_options ::= db_options DURATION NK_INTEGER */ + { 270, -3 }, /* (78) db_options ::= db_options DURATION NK_VARIABLE */ + { 270, -3 }, /* (79) db_options ::= db_options FSYNC NK_INTEGER */ + { 270, -3 }, /* (80) db_options ::= db_options MAXROWS NK_INTEGER */ + { 270, -3 }, /* (81) db_options ::= db_options MINROWS NK_INTEGER */ + { 270, -3 }, /* (82) db_options ::= db_options KEEP integer_list */ + { 270, -3 }, /* (83) db_options ::= db_options KEEP variable_list */ + { 270, -3 }, /* (84) db_options ::= db_options PAGES NK_INTEGER */ + { 270, -3 }, /* (85) db_options ::= db_options PAGESIZE NK_INTEGER */ + { 270, -3 }, /* (86) db_options ::= db_options PRECISION NK_STRING */ + { 270, -3 }, /* (87) db_options ::= db_options REPLICA NK_INTEGER */ + { 270, -3 }, /* (88) db_options ::= db_options STRICT NK_INTEGER */ + { 270, -3 }, /* (89) db_options ::= db_options WAL NK_INTEGER */ + { 270, -3 }, /* (90) db_options ::= db_options VGROUPS NK_INTEGER */ + { 270, -3 }, /* (91) db_options ::= db_options SINGLE_STABLE NK_INTEGER */ + { 270, -3 }, /* (92) db_options ::= db_options RETENTIONS retention_list */ + { 270, -3 }, /* (93) db_options ::= db_options SCHEMALESS NK_INTEGER */ + { 272, -1 }, /* (94) alter_db_options ::= alter_db_option */ + { 272, -2 }, /* (95) alter_db_options ::= alter_db_options alter_db_option */ + { 276, -2 }, /* (96) alter_db_option ::= BUFFER NK_INTEGER */ + { 276, -2 }, /* (97) alter_db_option ::= CACHELAST NK_INTEGER */ + { 276, -2 }, /* (98) alter_db_option ::= CACHELASTSIZE NK_INTEGER */ + { 276, -2 }, /* (99) alter_db_option ::= FSYNC NK_INTEGER */ + { 276, -2 }, /* (100) alter_db_option ::= KEEP integer_list */ + { 276, -2 }, /* (101) alter_db_option ::= KEEP variable_list */ + { 276, -2 }, /* (102) alter_db_option ::= PAGES NK_INTEGER */ + { 276, -2 }, /* (103) alter_db_option ::= REPLICA NK_INTEGER */ + { 276, -2 }, /* (104) alter_db_option ::= STRICT NK_INTEGER */ + { 276, -2 }, /* (105) alter_db_option ::= WAL NK_INTEGER */ + { 273, -1 }, /* (106) integer_list ::= NK_INTEGER */ + { 273, -3 }, /* (107) integer_list ::= integer_list NK_COMMA NK_INTEGER */ + { 274, -1 }, /* (108) variable_list ::= NK_VARIABLE */ + { 274, -3 }, /* (109) variable_list ::= variable_list NK_COMMA NK_VARIABLE */ + { 275, -1 }, /* (110) retention_list ::= retention */ + { 275, -3 }, /* (111) retention_list ::= retention_list NK_COMMA retention */ + { 277, -3 }, /* (112) retention ::= NK_VARIABLE NK_COLON NK_VARIABLE */ + { 256, -9 }, /* (113) cmd ::= CREATE TABLE not_exists_opt full_table_name NK_LP column_def_list NK_RP tags_def_opt table_options */ + { 256, -3 }, /* (114) cmd ::= CREATE TABLE multi_create_clause */ + { 256, -9 }, /* (115) cmd ::= CREATE STABLE not_exists_opt full_table_name NK_LP column_def_list NK_RP tags_def table_options */ + { 256, -3 }, /* (116) cmd ::= DROP TABLE multi_drop_clause */ + { 256, -4 }, /* (117) cmd ::= DROP STABLE exists_opt full_table_name */ + { 256, -3 }, /* (118) cmd ::= ALTER TABLE alter_table_clause */ + { 256, -3 }, /* (119) cmd ::= ALTER STABLE alter_table_clause */ + { 285, -2 }, /* (120) alter_table_clause ::= full_table_name alter_table_options */ + { 285, -5 }, /* (121) alter_table_clause ::= full_table_name ADD COLUMN column_name type_name */ + { 285, -4 }, /* (122) alter_table_clause ::= full_table_name DROP COLUMN column_name */ + { 285, -5 }, /* (123) alter_table_clause ::= full_table_name MODIFY COLUMN column_name type_name */ + { 285, -5 }, /* (124) alter_table_clause ::= full_table_name RENAME COLUMN column_name column_name */ + { 285, -5 }, /* (125) alter_table_clause ::= full_table_name ADD TAG column_name type_name */ + { 285, -4 }, /* (126) alter_table_clause ::= full_table_name DROP TAG column_name */ + { 285, -5 }, /* (127) alter_table_clause ::= full_table_name MODIFY TAG column_name type_name */ + { 285, -5 }, /* (128) alter_table_clause ::= full_table_name RENAME TAG column_name column_name */ + { 285, -6 }, /* (129) alter_table_clause ::= full_table_name SET TAG column_name NK_EQ signed_literal */ + { 282, -1 }, /* (130) multi_create_clause ::= create_subtable_clause */ + { 282, -2 }, /* (131) multi_create_clause ::= multi_create_clause create_subtable_clause */ + { 290, -10 }, /* (132) create_subtable_clause ::= not_exists_opt full_table_name USING full_table_name specific_cols_opt TAGS NK_LP expression_list NK_RP table_options */ + { 284, -1 }, /* (133) multi_drop_clause ::= drop_table_clause */ + { 284, -2 }, /* (134) multi_drop_clause ::= multi_drop_clause drop_table_clause */ + { 293, -2 }, /* (135) drop_table_clause ::= exists_opt full_table_name */ + { 291, 0 }, /* (136) specific_cols_opt ::= */ + { 291, -3 }, /* (137) specific_cols_opt ::= NK_LP col_name_list NK_RP */ + { 278, -1 }, /* (138) full_table_name ::= table_name */ + { 278, -3 }, /* (139) full_table_name ::= db_name NK_DOT table_name */ + { 279, -1 }, /* (140) column_def_list ::= column_def */ + { 279, -3 }, /* (141) column_def_list ::= column_def_list NK_COMMA column_def */ + { 296, -2 }, /* (142) column_def ::= column_name type_name */ + { 296, -4 }, /* (143) column_def ::= column_name type_name COMMENT NK_STRING */ + { 288, -1 }, /* (144) type_name ::= BOOL */ + { 288, -1 }, /* (145) type_name ::= TINYINT */ + { 288, -1 }, /* (146) type_name ::= SMALLINT */ + { 288, -1 }, /* (147) type_name ::= INT */ + { 288, -1 }, /* (148) type_name ::= INTEGER */ + { 288, -1 }, /* (149) type_name ::= BIGINT */ + { 288, -1 }, /* (150) type_name ::= FLOAT */ + { 288, -1 }, /* (151) type_name ::= DOUBLE */ + { 288, -4 }, /* (152) type_name ::= BINARY NK_LP NK_INTEGER NK_RP */ + { 288, -1 }, /* (153) type_name ::= TIMESTAMP */ + { 288, -4 }, /* (154) type_name ::= NCHAR NK_LP NK_INTEGER NK_RP */ + { 288, -2 }, /* (155) type_name ::= TINYINT UNSIGNED */ + { 288, -2 }, /* (156) type_name ::= SMALLINT UNSIGNED */ + { 288, -2 }, /* (157) type_name ::= INT UNSIGNED */ + { 288, -2 }, /* (158) type_name ::= BIGINT UNSIGNED */ + { 288, -1 }, /* (159) type_name ::= JSON */ + { 288, -4 }, /* (160) type_name ::= VARCHAR NK_LP NK_INTEGER NK_RP */ + { 288, -1 }, /* (161) type_name ::= MEDIUMBLOB */ + { 288, -1 }, /* (162) type_name ::= BLOB */ + { 288, -4 }, /* (163) type_name ::= VARBINARY NK_LP NK_INTEGER NK_RP */ + { 288, -1 }, /* (164) type_name ::= DECIMAL */ + { 288, -4 }, /* (165) type_name ::= DECIMAL NK_LP NK_INTEGER NK_RP */ + { 288, -6 }, /* (166) type_name ::= DECIMAL NK_LP NK_INTEGER NK_COMMA NK_INTEGER NK_RP */ + { 280, 0 }, /* (167) tags_def_opt ::= */ + { 280, -1 }, /* (168) tags_def_opt ::= tags_def */ + { 283, -4 }, /* (169) tags_def ::= TAGS NK_LP column_def_list NK_RP */ + { 281, 0 }, /* (170) table_options ::= */ + { 281, -3 }, /* (171) table_options ::= table_options COMMENT NK_STRING */ + { 281, -3 }, /* (172) table_options ::= table_options MAX_DELAY duration_list */ + { 281, -3 }, /* (173) table_options ::= table_options WATERMARK duration_list */ + { 281, -5 }, /* (174) table_options ::= table_options ROLLUP NK_LP rollup_func_list NK_RP */ + { 281, -3 }, /* (175) table_options ::= table_options TTL NK_INTEGER */ + { 281, -5 }, /* (176) table_options ::= table_options SMA NK_LP col_name_list NK_RP */ + { 286, -1 }, /* (177) alter_table_options ::= alter_table_option */ + { 286, -2 }, /* (178) alter_table_options ::= alter_table_options alter_table_option */ + { 299, -2 }, /* (179) alter_table_option ::= COMMENT NK_STRING */ + { 299, -2 }, /* (180) alter_table_option ::= TTL NK_INTEGER */ + { 297, -1 }, /* (181) duration_list ::= duration_literal */ + { 297, -3 }, /* (182) duration_list ::= duration_list NK_COMMA duration_literal */ + { 298, -1 }, /* (183) rollup_func_list ::= rollup_func_name */ + { 298, -3 }, /* (184) rollup_func_list ::= rollup_func_list NK_COMMA rollup_func_name */ + { 301, -1 }, /* (185) rollup_func_name ::= function_name */ + { 301, -1 }, /* (186) rollup_func_name ::= FIRST */ + { 301, -1 }, /* (187) rollup_func_name ::= LAST */ + { 294, -1 }, /* (188) col_name_list ::= col_name */ + { 294, -3 }, /* (189) col_name_list ::= col_name_list NK_COMMA col_name */ + { 303, -1 }, /* (190) col_name ::= column_name */ + { 256, -2 }, /* (191) cmd ::= SHOW DNODES */ + { 256, -2 }, /* (192) cmd ::= SHOW USERS */ + { 256, -2 }, /* (193) cmd ::= SHOW DATABASES */ + { 256, -4 }, /* (194) cmd ::= SHOW db_name_cond_opt TABLES like_pattern_opt */ + { 256, -4 }, /* (195) cmd ::= SHOW db_name_cond_opt STABLES like_pattern_opt */ + { 256, -3 }, /* (196) cmd ::= SHOW db_name_cond_opt VGROUPS */ + { 256, -2 }, /* (197) cmd ::= SHOW MNODES */ + { 256, -2 }, /* (198) cmd ::= SHOW MODULES */ + { 256, -2 }, /* (199) cmd ::= SHOW QNODES */ + { 256, -2 }, /* (200) cmd ::= SHOW FUNCTIONS */ + { 256, -5 }, /* (201) cmd ::= SHOW INDEXES FROM table_name_cond from_db_opt */ + { 256, -2 }, /* (202) cmd ::= SHOW STREAMS */ + { 256, -2 }, /* (203) cmd ::= SHOW ACCOUNTS */ + { 256, -2 }, /* (204) cmd ::= SHOW APPS */ + { 256, -2 }, /* (205) cmd ::= SHOW CONNECTIONS */ + { 256, -2 }, /* (206) cmd ::= SHOW LICENCE */ + { 256, -2 }, /* (207) cmd ::= SHOW GRANTS */ + { 256, -4 }, /* (208) cmd ::= SHOW CREATE DATABASE db_name */ + { 256, -4 }, /* (209) cmd ::= SHOW CREATE TABLE full_table_name */ + { 256, -4 }, /* (210) cmd ::= SHOW CREATE STABLE full_table_name */ + { 256, -2 }, /* (211) cmd ::= SHOW QUERIES */ + { 256, -2 }, /* (212) cmd ::= SHOW SCORES */ + { 256, -2 }, /* (213) cmd ::= SHOW TOPICS */ + { 256, -2 }, /* (214) cmd ::= SHOW VARIABLES */ + { 256, -3 }, /* (215) cmd ::= SHOW LOCAL VARIABLES */ + { 256, -4 }, /* (216) cmd ::= SHOW DNODE NK_INTEGER VARIABLES */ + { 256, -2 }, /* (217) cmd ::= SHOW BNODES */ + { 256, -2 }, /* (218) cmd ::= SHOW SNODES */ + { 256, -2 }, /* (219) cmd ::= SHOW CLUSTER */ + { 256, -2 }, /* (220) cmd ::= SHOW TRANSACTIONS */ + { 256, -4 }, /* (221) cmd ::= SHOW TABLE DISTRIBUTED full_table_name */ + { 256, -2 }, /* (222) cmd ::= SHOW CONSUMERS */ + { 256, -2 }, /* (223) cmd ::= SHOW SUBSCRIPTIONS */ + { 304, 0 }, /* (224) db_name_cond_opt ::= */ + { 304, -2 }, /* (225) db_name_cond_opt ::= db_name NK_DOT */ + { 305, 0 }, /* (226) like_pattern_opt ::= */ + { 305, -2 }, /* (227) like_pattern_opt ::= LIKE NK_STRING */ + { 306, -1 }, /* (228) table_name_cond ::= table_name */ + { 307, 0 }, /* (229) from_db_opt ::= */ + { 307, -2 }, /* (230) from_db_opt ::= FROM db_name */ + { 256, -8 }, /* (231) cmd ::= CREATE SMA INDEX not_exists_opt index_name ON table_name index_options */ + { 256, -4 }, /* (232) cmd ::= DROP INDEX exists_opt index_name */ + { 309, -10 }, /* (233) index_options ::= FUNCTION NK_LP func_list NK_RP INTERVAL NK_LP duration_literal NK_RP sliding_opt sma_stream_opt */ + { 309, -12 }, /* (234) index_options ::= FUNCTION NK_LP func_list NK_RP INTERVAL NK_LP duration_literal NK_COMMA duration_literal NK_RP sliding_opt sma_stream_opt */ + { 310, -1 }, /* (235) func_list ::= func */ + { 310, -3 }, /* (236) func_list ::= func_list NK_COMMA func */ + { 313, -4 }, /* (237) func ::= function_name NK_LP expression_list NK_RP */ + { 312, 0 }, /* (238) sma_stream_opt ::= */ + { 312, -3 }, /* (239) sma_stream_opt ::= stream_options WATERMARK duration_literal */ + { 312, -3 }, /* (240) sma_stream_opt ::= stream_options MAX_DELAY duration_literal */ + { 256, -6 }, /* (241) cmd ::= CREATE TOPIC not_exists_opt topic_name AS query_expression */ + { 256, -7 }, /* (242) cmd ::= CREATE TOPIC not_exists_opt topic_name AS DATABASE db_name */ + { 256, -9 }, /* (243) cmd ::= CREATE TOPIC not_exists_opt topic_name WITH META AS DATABASE db_name */ + { 256, -7 }, /* (244) cmd ::= CREATE TOPIC not_exists_opt topic_name AS STABLE full_table_name */ + { 256, -9 }, /* (245) cmd ::= CREATE TOPIC not_exists_opt topic_name WITH META AS STABLE full_table_name */ + { 256, -4 }, /* (246) cmd ::= DROP TOPIC exists_opt topic_name */ + { 256, -7 }, /* (247) cmd ::= DROP CONSUMER GROUP exists_opt cgroup_name ON topic_name */ + { 256, -2 }, /* (248) cmd ::= DESC full_table_name */ + { 256, -2 }, /* (249) cmd ::= DESCRIBE full_table_name */ + { 256, -3 }, /* (250) cmd ::= RESET QUERY CACHE */ + { 256, -4 }, /* (251) cmd ::= EXPLAIN analyze_opt explain_options query_expression */ + { 318, 0 }, /* (252) analyze_opt ::= */ + { 318, -1 }, /* (253) analyze_opt ::= ANALYZE */ + { 319, 0 }, /* (254) explain_options ::= */ + { 319, -3 }, /* (255) explain_options ::= explain_options VERBOSE NK_BOOL */ + { 319, -3 }, /* (256) explain_options ::= explain_options RATIO NK_FLOAT */ + { 256, -6 }, /* (257) cmd ::= COMPACT VNODES IN NK_LP integer_list NK_RP */ + { 256, -10 }, /* (258) cmd ::= CREATE agg_func_opt FUNCTION not_exists_opt function_name AS NK_STRING OUTPUTTYPE type_name bufsize_opt */ + { 256, -4 }, /* (259) cmd ::= DROP FUNCTION exists_opt function_name */ + { 320, 0 }, /* (260) agg_func_opt ::= */ + { 320, -1 }, /* (261) agg_func_opt ::= AGGREGATE */ + { 321, 0 }, /* (262) bufsize_opt ::= */ + { 321, -2 }, /* (263) bufsize_opt ::= BUFSIZE NK_INTEGER */ + { 256, -8 }, /* (264) cmd ::= CREATE STREAM not_exists_opt stream_name stream_options into_opt AS query_expression */ + { 256, -4 }, /* (265) cmd ::= DROP STREAM exists_opt stream_name */ + { 323, 0 }, /* (266) into_opt ::= */ + { 323, -2 }, /* (267) into_opt ::= INTO full_table_name */ + { 314, 0 }, /* (268) stream_options ::= */ + { 314, -3 }, /* (269) stream_options ::= stream_options TRIGGER AT_ONCE */ + { 314, -3 }, /* (270) stream_options ::= stream_options TRIGGER WINDOW_CLOSE */ + { 314, -4 }, /* (271) stream_options ::= stream_options TRIGGER MAX_DELAY duration_literal */ + { 314, -3 }, /* (272) stream_options ::= stream_options WATERMARK duration_literal */ + { 314, -3 }, /* (273) stream_options ::= stream_options IGNORE EXPIRED */ + { 256, -3 }, /* (274) cmd ::= KILL CONNECTION NK_INTEGER */ + { 256, -3 }, /* (275) cmd ::= KILL QUERY NK_STRING */ + { 256, -3 }, /* (276) cmd ::= KILL TRANSACTION NK_INTEGER */ + { 256, -2 }, /* (277) cmd ::= BALANCE VGROUP */ + { 256, -4 }, /* (278) cmd ::= MERGE VGROUP NK_INTEGER NK_INTEGER */ + { 256, -4 }, /* (279) cmd ::= REDISTRIBUTE VGROUP NK_INTEGER dnode_list */ + { 256, -3 }, /* (280) cmd ::= SPLIT VGROUP NK_INTEGER */ + { 324, -2 }, /* (281) dnode_list ::= DNODE NK_INTEGER */ + { 324, -3 }, /* (282) dnode_list ::= dnode_list DNODE NK_INTEGER */ + { 256, -3 }, /* (283) cmd ::= SYNCDB db_name REPLICA */ + { 256, -4 }, /* (284) cmd ::= DELETE FROM full_table_name where_clause_opt */ + { 256, -1 }, /* (285) cmd ::= query_expression */ + { 256, -7 }, /* (286) cmd ::= INSERT INTO full_table_name NK_LP col_name_list NK_RP query_expression */ + { 256, -4 }, /* (287) cmd ::= INSERT INTO full_table_name query_expression */ + { 259, -1 }, /* (288) literal ::= NK_INTEGER */ + { 259, -1 }, /* (289) literal ::= NK_FLOAT */ + { 259, -1 }, /* (290) literal ::= NK_STRING */ + { 259, -1 }, /* (291) literal ::= NK_BOOL */ + { 259, -2 }, /* (292) literal ::= TIMESTAMP NK_STRING */ + { 259, -1 }, /* (293) literal ::= duration_literal */ + { 259, -1 }, /* (294) literal ::= NULL */ + { 259, -1 }, /* (295) literal ::= NK_QUESTION */ + { 300, -1 }, /* (296) duration_literal ::= NK_VARIABLE */ + { 326, -1 }, /* (297) signed ::= NK_INTEGER */ + { 326, -2 }, /* (298) signed ::= NK_PLUS NK_INTEGER */ + { 326, -2 }, /* (299) signed ::= NK_MINUS NK_INTEGER */ + { 326, -1 }, /* (300) signed ::= NK_FLOAT */ + { 326, -2 }, /* (301) signed ::= NK_PLUS NK_FLOAT */ + { 326, -2 }, /* (302) signed ::= NK_MINUS NK_FLOAT */ + { 289, -1 }, /* (303) signed_literal ::= signed */ + { 289, -1 }, /* (304) signed_literal ::= NK_STRING */ + { 289, -1 }, /* (305) signed_literal ::= NK_BOOL */ + { 289, -2 }, /* (306) signed_literal ::= TIMESTAMP NK_STRING */ + { 289, -1 }, /* (307) signed_literal ::= duration_literal */ + { 289, -1 }, /* (308) signed_literal ::= NULL */ + { 289, -1 }, /* (309) signed_literal ::= literal_func */ + { 289, -1 }, /* (310) signed_literal ::= NK_QUESTION */ + { 328, -1 }, /* (311) literal_list ::= signed_literal */ + { 328, -3 }, /* (312) literal_list ::= literal_list NK_COMMA signed_literal */ + { 267, -1 }, /* (313) db_name ::= NK_ID */ + { 295, -1 }, /* (314) table_name ::= NK_ID */ + { 287, -1 }, /* (315) column_name ::= NK_ID */ + { 302, -1 }, /* (316) function_name ::= NK_ID */ + { 329, -1 }, /* (317) table_alias ::= NK_ID */ + { 330, -1 }, /* (318) column_alias ::= NK_ID */ + { 261, -1 }, /* (319) user_name ::= NK_ID */ + { 308, -1 }, /* (320) index_name ::= NK_ID */ + { 315, -1 }, /* (321) topic_name ::= NK_ID */ + { 322, -1 }, /* (322) stream_name ::= NK_ID */ + { 317, -1 }, /* (323) cgroup_name ::= NK_ID */ + { 331, -1 }, /* (324) expression ::= literal */ + { 331, -1 }, /* (325) expression ::= pseudo_column */ + { 331, -1 }, /* (326) expression ::= column_reference */ + { 331, -1 }, /* (327) expression ::= function_expression */ + { 331, -1 }, /* (328) expression ::= subquery */ + { 331, -3 }, /* (329) expression ::= NK_LP expression NK_RP */ + { 331, -2 }, /* (330) expression ::= NK_PLUS expression */ + { 331, -2 }, /* (331) expression ::= NK_MINUS expression */ + { 331, -3 }, /* (332) expression ::= expression NK_PLUS expression */ + { 331, -3 }, /* (333) expression ::= expression NK_MINUS expression */ + { 331, -3 }, /* (334) expression ::= expression NK_STAR expression */ + { 331, -3 }, /* (335) expression ::= expression NK_SLASH expression */ + { 331, -3 }, /* (336) expression ::= expression NK_REM expression */ + { 331, -3 }, /* (337) expression ::= column_reference NK_ARROW NK_STRING */ + { 331, -3 }, /* (338) expression ::= expression NK_BITAND expression */ + { 331, -3 }, /* (339) expression ::= expression NK_BITOR expression */ + { 292, -1 }, /* (340) expression_list ::= expression */ + { 292, -3 }, /* (341) expression_list ::= expression_list NK_COMMA expression */ + { 333, -1 }, /* (342) column_reference ::= column_name */ + { 333, -3 }, /* (343) column_reference ::= table_name NK_DOT column_name */ + { 332, -1 }, /* (344) pseudo_column ::= ROWTS */ + { 332, -1 }, /* (345) pseudo_column ::= TBNAME */ + { 332, -3 }, /* (346) pseudo_column ::= table_name NK_DOT TBNAME */ + { 332, -1 }, /* (347) pseudo_column ::= QSTART */ + { 332, -1 }, /* (348) pseudo_column ::= QEND */ + { 332, -1 }, /* (349) pseudo_column ::= QDURATION */ + { 332, -1 }, /* (350) pseudo_column ::= WSTART */ + { 332, -1 }, /* (351) pseudo_column ::= WEND */ + { 332, -1 }, /* (352) pseudo_column ::= WDURATION */ + { 334, -4 }, /* (353) function_expression ::= function_name NK_LP expression_list NK_RP */ + { 334, -4 }, /* (354) function_expression ::= star_func NK_LP star_func_para_list NK_RP */ + { 334, -6 }, /* (355) function_expression ::= CAST NK_LP expression AS type_name NK_RP */ + { 334, -1 }, /* (356) function_expression ::= literal_func */ + { 327, -3 }, /* (357) literal_func ::= noarg_func NK_LP NK_RP */ + { 327, -1 }, /* (358) literal_func ::= NOW */ + { 338, -1 }, /* (359) noarg_func ::= NOW */ + { 338, -1 }, /* (360) noarg_func ::= TODAY */ + { 338, -1 }, /* (361) noarg_func ::= TIMEZONE */ + { 338, -1 }, /* (362) noarg_func ::= DATABASE */ + { 338, -1 }, /* (363) noarg_func ::= CLIENT_VERSION */ + { 338, -1 }, /* (364) noarg_func ::= SERVER_VERSION */ + { 338, -1 }, /* (365) noarg_func ::= SERVER_STATUS */ + { 338, -1 }, /* (366) noarg_func ::= CURRENT_USER */ + { 338, -1 }, /* (367) noarg_func ::= USER */ + { 336, -1 }, /* (368) star_func ::= COUNT */ + { 336, -1 }, /* (369) star_func ::= FIRST */ + { 336, -1 }, /* (370) star_func ::= LAST */ + { 336, -1 }, /* (371) star_func ::= LAST_ROW */ + { 337, -1 }, /* (372) star_func_para_list ::= NK_STAR */ + { 337, -1 }, /* (373) star_func_para_list ::= other_para_list */ + { 339, -1 }, /* (374) other_para_list ::= star_func_para */ + { 339, -3 }, /* (375) other_para_list ::= other_para_list NK_COMMA star_func_para */ + { 340, -1 }, /* (376) star_func_para ::= expression */ + { 340, -3 }, /* (377) star_func_para ::= table_name NK_DOT NK_STAR */ + { 341, -3 }, /* (378) predicate ::= expression compare_op expression */ + { 341, -5 }, /* (379) predicate ::= expression BETWEEN expression AND expression */ + { 341, -6 }, /* (380) predicate ::= expression NOT BETWEEN expression AND expression */ + { 341, -3 }, /* (381) predicate ::= expression IS NULL */ + { 341, -4 }, /* (382) predicate ::= expression IS NOT NULL */ + { 341, -3 }, /* (383) predicate ::= expression in_op in_predicate_value */ + { 342, -1 }, /* (384) compare_op ::= NK_LT */ + { 342, -1 }, /* (385) compare_op ::= NK_GT */ + { 342, -1 }, /* (386) compare_op ::= NK_LE */ + { 342, -1 }, /* (387) compare_op ::= NK_GE */ + { 342, -1 }, /* (388) compare_op ::= NK_NE */ + { 342, -1 }, /* (389) compare_op ::= NK_EQ */ + { 342, -1 }, /* (390) compare_op ::= LIKE */ + { 342, -2 }, /* (391) compare_op ::= NOT LIKE */ + { 342, -1 }, /* (392) compare_op ::= MATCH */ + { 342, -1 }, /* (393) compare_op ::= NMATCH */ + { 342, -1 }, /* (394) compare_op ::= CONTAINS */ + { 343, -1 }, /* (395) in_op ::= IN */ + { 343, -2 }, /* (396) in_op ::= NOT IN */ + { 344, -3 }, /* (397) in_predicate_value ::= NK_LP literal_list NK_RP */ + { 345, -1 }, /* (398) boolean_value_expression ::= boolean_primary */ + { 345, -2 }, /* (399) boolean_value_expression ::= NOT boolean_primary */ + { 345, -3 }, /* (400) boolean_value_expression ::= boolean_value_expression OR boolean_value_expression */ + { 345, -3 }, /* (401) boolean_value_expression ::= boolean_value_expression AND boolean_value_expression */ + { 346, -1 }, /* (402) boolean_primary ::= predicate */ + { 346, -3 }, /* (403) boolean_primary ::= NK_LP boolean_value_expression NK_RP */ + { 347, -1 }, /* (404) common_expression ::= expression */ + { 347, -1 }, /* (405) common_expression ::= boolean_value_expression */ + { 348, 0 }, /* (406) from_clause_opt ::= */ + { 348, -2 }, /* (407) from_clause_opt ::= FROM table_reference_list */ + { 349, -1 }, /* (408) table_reference_list ::= table_reference */ + { 349, -3 }, /* (409) table_reference_list ::= table_reference_list NK_COMMA table_reference */ + { 350, -1 }, /* (410) table_reference ::= table_primary */ + { 350, -1 }, /* (411) table_reference ::= joined_table */ + { 351, -2 }, /* (412) table_primary ::= table_name alias_opt */ + { 351, -4 }, /* (413) table_primary ::= db_name NK_DOT table_name alias_opt */ + { 351, -2 }, /* (414) table_primary ::= subquery alias_opt */ + { 351, -1 }, /* (415) table_primary ::= parenthesized_joined_table */ + { 353, 0 }, /* (416) alias_opt ::= */ + { 353, -1 }, /* (417) alias_opt ::= table_alias */ + { 353, -2 }, /* (418) alias_opt ::= AS table_alias */ + { 354, -3 }, /* (419) parenthesized_joined_table ::= NK_LP joined_table NK_RP */ + { 354, -3 }, /* (420) parenthesized_joined_table ::= NK_LP parenthesized_joined_table NK_RP */ + { 352, -6 }, /* (421) joined_table ::= table_reference join_type JOIN table_reference ON search_condition */ + { 355, 0 }, /* (422) join_type ::= */ + { 355, -1 }, /* (423) join_type ::= INNER */ + { 357, -12 }, /* (424) query_specification ::= SELECT set_quantifier_opt select_list from_clause_opt where_clause_opt partition_by_clause_opt range_opt every_opt fill_opt twindow_clause_opt group_by_clause_opt having_clause_opt */ + { 358, 0 }, /* (425) set_quantifier_opt ::= */ + { 358, -1 }, /* (426) set_quantifier_opt ::= DISTINCT */ + { 358, -1 }, /* (427) set_quantifier_opt ::= ALL */ + { 359, -1 }, /* (428) select_list ::= select_item */ + { 359, -3 }, /* (429) select_list ::= select_list NK_COMMA select_item */ + { 367, -1 }, /* (430) select_item ::= NK_STAR */ + { 367, -1 }, /* (431) select_item ::= common_expression */ + { 367, -2 }, /* (432) select_item ::= common_expression column_alias */ + { 367, -3 }, /* (433) select_item ::= common_expression AS column_alias */ + { 367, -3 }, /* (434) select_item ::= table_name NK_DOT NK_STAR */ + { 325, 0 }, /* (435) where_clause_opt ::= */ + { 325, -2 }, /* (436) where_clause_opt ::= WHERE search_condition */ + { 360, 0 }, /* (437) partition_by_clause_opt ::= */ + { 360, -3 }, /* (438) partition_by_clause_opt ::= PARTITION BY expression_list */ + { 364, 0 }, /* (439) twindow_clause_opt ::= */ + { 364, -6 }, /* (440) twindow_clause_opt ::= SESSION NK_LP column_reference NK_COMMA duration_literal NK_RP */ + { 364, -4 }, /* (441) twindow_clause_opt ::= STATE_WINDOW NK_LP expression NK_RP */ + { 364, -6 }, /* (442) twindow_clause_opt ::= INTERVAL NK_LP duration_literal NK_RP sliding_opt fill_opt */ + { 364, -8 }, /* (443) twindow_clause_opt ::= INTERVAL NK_LP duration_literal NK_COMMA duration_literal NK_RP sliding_opt fill_opt */ + { 311, 0 }, /* (444) sliding_opt ::= */ + { 311, -4 }, /* (445) sliding_opt ::= SLIDING NK_LP duration_literal NK_RP */ + { 363, 0 }, /* (446) fill_opt ::= */ + { 363, -4 }, /* (447) fill_opt ::= FILL NK_LP fill_mode NK_RP */ + { 363, -6 }, /* (448) fill_opt ::= FILL NK_LP VALUE NK_COMMA literal_list NK_RP */ + { 368, -1 }, /* (449) fill_mode ::= NONE */ + { 368, -1 }, /* (450) fill_mode ::= PREV */ + { 368, -1 }, /* (451) fill_mode ::= NULL */ + { 368, -1 }, /* (452) fill_mode ::= LINEAR */ + { 368, -1 }, /* (453) fill_mode ::= NEXT */ + { 365, 0 }, /* (454) group_by_clause_opt ::= */ + { 365, -3 }, /* (455) group_by_clause_opt ::= GROUP BY group_by_list */ + { 369, -1 }, /* (456) group_by_list ::= expression */ + { 369, -3 }, /* (457) group_by_list ::= group_by_list NK_COMMA expression */ + { 366, 0 }, /* (458) having_clause_opt ::= */ + { 366, -2 }, /* (459) having_clause_opt ::= HAVING search_condition */ + { 361, 0 }, /* (460) range_opt ::= */ + { 361, -6 }, /* (461) range_opt ::= RANGE NK_LP expression NK_COMMA expression NK_RP */ + { 362, 0 }, /* (462) every_opt ::= */ + { 362, -4 }, /* (463) every_opt ::= EVERY NK_LP duration_literal NK_RP */ + { 316, -4 }, /* (464) query_expression ::= query_expression_body order_by_clause_opt slimit_clause_opt limit_clause_opt */ + { 370, -1 }, /* (465) query_expression_body ::= query_primary */ + { 370, -4 }, /* (466) query_expression_body ::= query_expression_body UNION ALL query_expression_body */ + { 370, -3 }, /* (467) query_expression_body ::= query_expression_body UNION query_expression_body */ + { 374, -1 }, /* (468) query_primary ::= query_specification */ + { 374, -6 }, /* (469) query_primary ::= NK_LP query_expression_body order_by_clause_opt slimit_clause_opt limit_clause_opt NK_RP */ + { 371, 0 }, /* (470) order_by_clause_opt ::= */ + { 371, -3 }, /* (471) order_by_clause_opt ::= ORDER BY sort_specification_list */ + { 372, 0 }, /* (472) slimit_clause_opt ::= */ + { 372, -2 }, /* (473) slimit_clause_opt ::= SLIMIT NK_INTEGER */ + { 372, -4 }, /* (474) slimit_clause_opt ::= SLIMIT NK_INTEGER SOFFSET NK_INTEGER */ + { 372, -4 }, /* (475) slimit_clause_opt ::= SLIMIT NK_INTEGER NK_COMMA NK_INTEGER */ + { 373, 0 }, /* (476) limit_clause_opt ::= */ + { 373, -2 }, /* (477) limit_clause_opt ::= LIMIT NK_INTEGER */ + { 373, -4 }, /* (478) limit_clause_opt ::= LIMIT NK_INTEGER OFFSET NK_INTEGER */ + { 373, -4 }, /* (479) limit_clause_opt ::= LIMIT NK_INTEGER NK_COMMA NK_INTEGER */ + { 335, -3 }, /* (480) subquery ::= NK_LP query_expression NK_RP */ + { 356, -1 }, /* (481) search_condition ::= common_expression */ + { 375, -1 }, /* (482) sort_specification_list ::= sort_specification */ + { 375, -3 }, /* (483) sort_specification_list ::= sort_specification_list NK_COMMA sort_specification */ + { 376, -3 }, /* (484) sort_specification ::= expression ordering_specification_opt null_ordering_opt */ + { 377, 0 }, /* (485) ordering_specification_opt ::= */ + { 377, -1 }, /* (486) ordering_specification_opt ::= ASC */ + { 377, -1 }, /* (487) ordering_specification_opt ::= DESC */ + { 378, 0 }, /* (488) null_ordering_opt ::= */ + { 378, -2 }, /* (489) null_ordering_opt ::= NULLS FIRST */ + { 378, -2 }, /* (490) null_ordering_opt ::= NULLS LAST */ }; static void yy_accept(yyParser*); /* Forward Declaration */ @@ -3269,11 +3321,11 @@ static YYACTIONTYPE yy_reduce( YYMINORTYPE yylhsminor; case 0: /* cmd ::= CREATE ACCOUNT NK_ID PASS NK_STRING account_options */ { pCxt->errCode = generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_EXPRIE_STATEMENT); } - yy_destructor(yypParser,256,&yymsp[0].minor); + yy_destructor(yypParser,257,&yymsp[0].minor); break; case 1: /* cmd ::= ALTER ACCOUNT NK_ID alter_account_options */ { pCxt->errCode = generateSyntaxErrMsg(&pCxt->msgBuf, TSDB_CODE_PAR_EXPRIE_STATEMENT); } - yy_destructor(yypParser,257,&yymsp[0].minor); + yy_destructor(yypParser,258,&yymsp[0].minor); break; case 2: /* account_options ::= */ { } @@ -3287,20 +3339,20 @@ static YYACTIONTYPE yy_reduce( case 9: /* account_options ::= account_options USERS literal */ yytestcase(yyruleno==9); case 10: /* account_options ::= account_options CONNS literal */ yytestcase(yyruleno==10); case 11: /* account_options ::= account_options STATE literal */ yytestcase(yyruleno==11); -{ yy_destructor(yypParser,256,&yymsp[-2].minor); +{ yy_destructor(yypParser,257,&yymsp[-2].minor); { } - yy_destructor(yypParser,258,&yymsp[0].minor); + yy_destructor(yypParser,259,&yymsp[0].minor); } break; case 12: /* alter_account_options ::= alter_account_option */ -{ yy_destructor(yypParser,259,&yymsp[0].minor); +{ yy_destructor(yypParser,260,&yymsp[0].minor); { } } break; case 13: /* alter_account_options ::= alter_account_options alter_account_option */ -{ yy_destructor(yypParser,257,&yymsp[-1].minor); +{ yy_destructor(yypParser,258,&yymsp[-1].minor); { } - yy_destructor(yypParser,259,&yymsp[0].minor); + yy_destructor(yypParser,260,&yymsp[0].minor); } break; case 14: /* alter_account_option ::= PASS literal */ @@ -3314,72 +3366,72 @@ static YYACTIONTYPE yy_reduce( case 22: /* alter_account_option ::= CONNS literal */ yytestcase(yyruleno==22); case 23: /* alter_account_option ::= STATE literal */ yytestcase(yyruleno==23); { } - yy_destructor(yypParser,258,&yymsp[0].minor); + yy_destructor(yypParser,259,&yymsp[0].minor); break; case 24: /* cmd ::= CREATE USER user_name PASS NK_STRING sysinfo_opt */ -{ pCxt->pRootNode = createCreateUserStmt(pCxt, &yymsp[-3].minor.yy533, &yymsp[-1].minor.yy0, yymsp[0].minor.yy719); } +{ pCxt->pRootNode = createCreateUserStmt(pCxt, &yymsp[-3].minor.yy361, &yymsp[-1].minor.yy0, yymsp[0].minor.yy285); } break; case 25: /* cmd ::= ALTER USER user_name PASS NK_STRING */ -{ pCxt->pRootNode = createAlterUserStmt(pCxt, &yymsp[-2].minor.yy533, TSDB_ALTER_USER_PASSWD, &yymsp[0].minor.yy0); } +{ pCxt->pRootNode = createAlterUserStmt(pCxt, &yymsp[-2].minor.yy361, TSDB_ALTER_USER_PASSWD, &yymsp[0].minor.yy0); } break; case 26: /* cmd ::= ALTER USER user_name ENABLE NK_INTEGER */ -{ pCxt->pRootNode = createAlterUserStmt(pCxt, &yymsp[-2].minor.yy533, TSDB_ALTER_USER_ENABLE, &yymsp[0].minor.yy0); } +{ pCxt->pRootNode = createAlterUserStmt(pCxt, &yymsp[-2].minor.yy361, TSDB_ALTER_USER_ENABLE, &yymsp[0].minor.yy0); } break; case 27: /* cmd ::= ALTER USER user_name SYSINFO NK_INTEGER */ -{ pCxt->pRootNode = createAlterUserStmt(pCxt, &yymsp[-2].minor.yy533, TSDB_ALTER_USER_SYSINFO, &yymsp[0].minor.yy0); } +{ pCxt->pRootNode = createAlterUserStmt(pCxt, &yymsp[-2].minor.yy361, TSDB_ALTER_USER_SYSINFO, &yymsp[0].minor.yy0); } break; case 28: /* cmd ::= DROP USER user_name */ -{ pCxt->pRootNode = createDropUserStmt(pCxt, &yymsp[0].minor.yy533); } +{ pCxt->pRootNode = createDropUserStmt(pCxt, &yymsp[0].minor.yy361); } break; case 29: /* sysinfo_opt ::= */ -{ yymsp[1].minor.yy719 = 1; } +{ yymsp[1].minor.yy285 = 1; } break; case 30: /* sysinfo_opt ::= SYSINFO NK_INTEGER */ -{ yymsp[-1].minor.yy719 = taosStr2Int8(yymsp[0].minor.yy0.z, NULL, 10); } +{ yymsp[-1].minor.yy285 = taosStr2Int8(yymsp[0].minor.yy0.z, NULL, 10); } break; case 31: /* cmd ::= GRANT privileges ON priv_level TO user_name */ -{ pCxt->pRootNode = createGrantStmt(pCxt, yymsp[-4].minor.yy585, &yymsp[-2].minor.yy533, &yymsp[0].minor.yy533); } +{ pCxt->pRootNode = createGrantStmt(pCxt, yymsp[-4].minor.yy457, &yymsp[-2].minor.yy361, &yymsp[0].minor.yy361); } break; case 32: /* cmd ::= REVOKE privileges ON priv_level FROM user_name */ -{ pCxt->pRootNode = createRevokeStmt(pCxt, yymsp[-4].minor.yy585, &yymsp[-2].minor.yy533, &yymsp[0].minor.yy533); } +{ pCxt->pRootNode = createRevokeStmt(pCxt, yymsp[-4].minor.yy457, &yymsp[-2].minor.yy361, &yymsp[0].minor.yy361); } break; case 33: /* privileges ::= ALL */ -{ yymsp[0].minor.yy585 = PRIVILEGE_TYPE_ALL; } +{ yymsp[0].minor.yy457 = PRIVILEGE_TYPE_ALL; } break; case 34: /* privileges ::= priv_type_list */ case 35: /* priv_type_list ::= priv_type */ yytestcase(yyruleno==35); -{ yylhsminor.yy585 = yymsp[0].minor.yy585; } - yymsp[0].minor.yy585 = yylhsminor.yy585; +{ yylhsminor.yy457 = yymsp[0].minor.yy457; } + yymsp[0].minor.yy457 = yylhsminor.yy457; break; case 36: /* priv_type_list ::= priv_type_list NK_COMMA priv_type */ -{ yylhsminor.yy585 = yymsp[-2].minor.yy585 | yymsp[0].minor.yy585; } - yymsp[-2].minor.yy585 = yylhsminor.yy585; +{ yylhsminor.yy457 = yymsp[-2].minor.yy457 | yymsp[0].minor.yy457; } + yymsp[-2].minor.yy457 = yylhsminor.yy457; break; case 37: /* priv_type ::= READ */ -{ yymsp[0].minor.yy585 = PRIVILEGE_TYPE_READ; } +{ yymsp[0].minor.yy457 = PRIVILEGE_TYPE_READ; } break; case 38: /* priv_type ::= WRITE */ -{ yymsp[0].minor.yy585 = PRIVILEGE_TYPE_WRITE; } +{ yymsp[0].minor.yy457 = PRIVILEGE_TYPE_WRITE; } break; case 39: /* priv_level ::= NK_STAR NK_DOT NK_STAR */ -{ yylhsminor.yy533 = yymsp[-2].minor.yy0; } - yymsp[-2].minor.yy533 = yylhsminor.yy533; +{ yylhsminor.yy361 = yymsp[-2].minor.yy0; } + yymsp[-2].minor.yy361 = yylhsminor.yy361; break; case 40: /* priv_level ::= db_name NK_DOT NK_STAR */ -{ yylhsminor.yy533 = yymsp[-2].minor.yy533; } - yymsp[-2].minor.yy533 = yylhsminor.yy533; +{ yylhsminor.yy361 = yymsp[-2].minor.yy361; } + yymsp[-2].minor.yy361 = yylhsminor.yy361; break; case 41: /* cmd ::= CREATE DNODE dnode_endpoint */ -{ pCxt->pRootNode = createCreateDnodeStmt(pCxt, &yymsp[0].minor.yy533, NULL); } +{ pCxt->pRootNode = createCreateDnodeStmt(pCxt, &yymsp[0].minor.yy361, NULL); } break; case 42: /* cmd ::= CREATE DNODE dnode_endpoint PORT NK_INTEGER */ -{ pCxt->pRootNode = createCreateDnodeStmt(pCxt, &yymsp[-2].minor.yy533, &yymsp[0].minor.yy0); } +{ pCxt->pRootNode = createCreateDnodeStmt(pCxt, &yymsp[-2].minor.yy361, &yymsp[0].minor.yy0); } break; case 43: /* cmd ::= DROP DNODE NK_INTEGER */ { pCxt->pRootNode = createDropDnodeStmt(pCxt, &yymsp[0].minor.yy0); } break; case 44: /* cmd ::= DROP DNODE dnode_endpoint */ -{ pCxt->pRootNode = createDropDnodeStmt(pCxt, &yymsp[0].minor.yy533); } +{ pCxt->pRootNode = createDropDnodeStmt(pCxt, &yymsp[0].minor.yy361); } break; case 45: /* cmd ::= ALTER DNODE NK_INTEGER NK_STRING */ { pCxt->pRootNode = createAlterDnodeStmt(pCxt, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0, NULL); } @@ -3396,32 +3448,32 @@ static YYACTIONTYPE yy_reduce( case 49: /* dnode_endpoint ::= NK_STRING */ case 50: /* dnode_endpoint ::= NK_ID */ yytestcase(yyruleno==50); case 51: /* dnode_endpoint ::= NK_IPTOKEN */ yytestcase(yyruleno==51); - case 312: /* db_name ::= NK_ID */ yytestcase(yyruleno==312); - case 313: /* table_name ::= NK_ID */ yytestcase(yyruleno==313); - case 314: /* column_name ::= NK_ID */ yytestcase(yyruleno==314); - case 315: /* function_name ::= NK_ID */ yytestcase(yyruleno==315); - case 316: /* table_alias ::= NK_ID */ yytestcase(yyruleno==316); - case 317: /* column_alias ::= NK_ID */ yytestcase(yyruleno==317); - case 318: /* user_name ::= NK_ID */ yytestcase(yyruleno==318); - case 319: /* index_name ::= NK_ID */ yytestcase(yyruleno==319); - case 320: /* topic_name ::= NK_ID */ yytestcase(yyruleno==320); - case 321: /* stream_name ::= NK_ID */ yytestcase(yyruleno==321); - case 322: /* cgroup_name ::= NK_ID */ yytestcase(yyruleno==322); - case 357: /* noarg_func ::= NOW */ yytestcase(yyruleno==357); - case 358: /* noarg_func ::= TODAY */ yytestcase(yyruleno==358); - case 359: /* noarg_func ::= TIMEZONE */ yytestcase(yyruleno==359); - case 360: /* noarg_func ::= DATABASE */ yytestcase(yyruleno==360); - case 361: /* noarg_func ::= CLIENT_VERSION */ yytestcase(yyruleno==361); - case 362: /* noarg_func ::= SERVER_VERSION */ yytestcase(yyruleno==362); - case 363: /* noarg_func ::= SERVER_STATUS */ yytestcase(yyruleno==363); - case 364: /* noarg_func ::= CURRENT_USER */ yytestcase(yyruleno==364); - case 365: /* noarg_func ::= USER */ yytestcase(yyruleno==365); - case 366: /* star_func ::= COUNT */ yytestcase(yyruleno==366); - case 367: /* star_func ::= FIRST */ yytestcase(yyruleno==367); - case 368: /* star_func ::= LAST */ yytestcase(yyruleno==368); - case 369: /* star_func ::= LAST_ROW */ yytestcase(yyruleno==369); -{ yylhsminor.yy533 = yymsp[0].minor.yy0; } - yymsp[0].minor.yy533 = yylhsminor.yy533; + case 313: /* db_name ::= NK_ID */ yytestcase(yyruleno==313); + case 314: /* table_name ::= NK_ID */ yytestcase(yyruleno==314); + case 315: /* column_name ::= NK_ID */ yytestcase(yyruleno==315); + case 316: /* function_name ::= NK_ID */ yytestcase(yyruleno==316); + case 317: /* table_alias ::= NK_ID */ yytestcase(yyruleno==317); + case 318: /* column_alias ::= NK_ID */ yytestcase(yyruleno==318); + case 319: /* user_name ::= NK_ID */ yytestcase(yyruleno==319); + case 320: /* index_name ::= NK_ID */ yytestcase(yyruleno==320); + case 321: /* topic_name ::= NK_ID */ yytestcase(yyruleno==321); + case 322: /* stream_name ::= NK_ID */ yytestcase(yyruleno==322); + case 323: /* cgroup_name ::= NK_ID */ yytestcase(yyruleno==323); + case 359: /* noarg_func ::= NOW */ yytestcase(yyruleno==359); + case 360: /* noarg_func ::= TODAY */ yytestcase(yyruleno==360); + case 361: /* noarg_func ::= TIMEZONE */ yytestcase(yyruleno==361); + case 362: /* noarg_func ::= DATABASE */ yytestcase(yyruleno==362); + case 363: /* noarg_func ::= CLIENT_VERSION */ yytestcase(yyruleno==363); + case 364: /* noarg_func ::= SERVER_VERSION */ yytestcase(yyruleno==364); + case 365: /* noarg_func ::= SERVER_STATUS */ yytestcase(yyruleno==365); + case 366: /* noarg_func ::= CURRENT_USER */ yytestcase(yyruleno==366); + case 367: /* noarg_func ::= USER */ yytestcase(yyruleno==367); + case 368: /* star_func ::= COUNT */ yytestcase(yyruleno==368); + case 369: /* star_func ::= FIRST */ yytestcase(yyruleno==369); + case 370: /* star_func ::= LAST */ yytestcase(yyruleno==370); + case 371: /* star_func ::= LAST_ROW */ yytestcase(yyruleno==371); +{ yylhsminor.yy361 = yymsp[0].minor.yy0; } + yymsp[0].minor.yy361 = yylhsminor.yy361; break; case 52: /* cmd ::= ALTER LOCAL NK_STRING */ { pCxt->pRootNode = createAlterLocalStmt(pCxt, &yymsp[0].minor.yy0, NULL); } @@ -3454,169 +3506,169 @@ static YYACTIONTYPE yy_reduce( { pCxt->pRootNode = createDropComponentNodeStmt(pCxt, QUERY_NODE_DROP_MNODE_STMT, &yymsp[0].minor.yy0); } break; case 62: /* cmd ::= CREATE DATABASE not_exists_opt db_name db_options */ -{ pCxt->pRootNode = createCreateDatabaseStmt(pCxt, yymsp[-2].minor.yy173, &yymsp[-1].minor.yy533, yymsp[0].minor.yy560); } +{ pCxt->pRootNode = createCreateDatabaseStmt(pCxt, yymsp[-2].minor.yy151, &yymsp[-1].minor.yy361, yymsp[0].minor.yy616); } break; case 63: /* cmd ::= DROP DATABASE exists_opt db_name */ -{ pCxt->pRootNode = createDropDatabaseStmt(pCxt, yymsp[-1].minor.yy173, &yymsp[0].minor.yy533); } +{ pCxt->pRootNode = createDropDatabaseStmt(pCxt, yymsp[-1].minor.yy151, &yymsp[0].minor.yy361); } break; case 64: /* cmd ::= USE db_name */ -{ pCxt->pRootNode = createUseDatabaseStmt(pCxt, &yymsp[0].minor.yy533); } +{ pCxt->pRootNode = createUseDatabaseStmt(pCxt, &yymsp[0].minor.yy361); } break; case 65: /* cmd ::= ALTER DATABASE db_name alter_db_options */ -{ pCxt->pRootNode = createAlterDatabaseStmt(pCxt, &yymsp[-1].minor.yy533, yymsp[0].minor.yy560); } +{ pCxt->pRootNode = createAlterDatabaseStmt(pCxt, &yymsp[-1].minor.yy361, yymsp[0].minor.yy616); } break; case 66: /* cmd ::= FLUSH DATABASE db_name */ -{ pCxt->pRootNode = createFlushDatabaseStmt(pCxt, &yymsp[0].minor.yy533); } +{ pCxt->pRootNode = createFlushDatabaseStmt(pCxt, &yymsp[0].minor.yy361); } break; case 67: /* cmd ::= TRIM DATABASE db_name */ -{ pCxt->pRootNode = createTrimDatabaseStmt(pCxt, &yymsp[0].minor.yy533); } +{ pCxt->pRootNode = createTrimDatabaseStmt(pCxt, &yymsp[0].minor.yy361); } break; case 68: /* not_exists_opt ::= IF NOT EXISTS */ -{ yymsp[-2].minor.yy173 = true; } +{ yymsp[-2].minor.yy151 = true; } break; case 69: /* not_exists_opt ::= */ case 71: /* exists_opt ::= */ yytestcase(yyruleno==71); case 252: /* analyze_opt ::= */ yytestcase(yyruleno==252); case 260: /* agg_func_opt ::= */ yytestcase(yyruleno==260); - case 423: /* set_quantifier_opt ::= */ yytestcase(yyruleno==423); -{ yymsp[1].minor.yy173 = false; } + case 425: /* set_quantifier_opt ::= */ yytestcase(yyruleno==425); +{ yymsp[1].minor.yy151 = false; } break; case 70: /* exists_opt ::= IF EXISTS */ -{ yymsp[-1].minor.yy173 = true; } +{ yymsp[-1].minor.yy151 = true; } break; case 72: /* db_options ::= */ -{ yymsp[1].minor.yy560 = createDefaultDatabaseOptions(pCxt); } +{ yymsp[1].minor.yy616 = createDefaultDatabaseOptions(pCxt); } break; case 73: /* db_options ::= db_options BUFFER NK_INTEGER */ -{ yylhsminor.yy560 = setDatabaseOption(pCxt, yymsp[-2].minor.yy560, DB_OPTION_BUFFER, &yymsp[0].minor.yy0); } - yymsp[-2].minor.yy560 = yylhsminor.yy560; +{ yylhsminor.yy616 = setDatabaseOption(pCxt, yymsp[-2].minor.yy616, DB_OPTION_BUFFER, &yymsp[0].minor.yy0); } + yymsp[-2].minor.yy616 = yylhsminor.yy616; break; case 74: /* db_options ::= db_options CACHELAST NK_INTEGER */ -{ yylhsminor.yy560 = setDatabaseOption(pCxt, yymsp[-2].minor.yy560, DB_OPTION_CACHELAST, &yymsp[0].minor.yy0); } - yymsp[-2].minor.yy560 = yylhsminor.yy560; +{ yylhsminor.yy616 = setDatabaseOption(pCxt, yymsp[-2].minor.yy616, DB_OPTION_CACHELAST, &yymsp[0].minor.yy0); } + yymsp[-2].minor.yy616 = yylhsminor.yy616; break; case 75: /* db_options ::= db_options CACHELASTSIZE NK_INTEGER */ -{ yylhsminor.yy560 = setDatabaseOption(pCxt, yymsp[-2].minor.yy560, DB_OPTION_CACHELASTSIZE, &yymsp[0].minor.yy0); } - yymsp[-2].minor.yy560 = yylhsminor.yy560; +{ yylhsminor.yy616 = setDatabaseOption(pCxt, yymsp[-2].minor.yy616, DB_OPTION_CACHELASTSIZE, &yymsp[0].minor.yy0); } + yymsp[-2].minor.yy616 = yylhsminor.yy616; break; case 76: /* db_options ::= db_options COMP NK_INTEGER */ -{ yylhsminor.yy560 = setDatabaseOption(pCxt, yymsp[-2].minor.yy560, DB_OPTION_COMP, &yymsp[0].minor.yy0); } - yymsp[-2].minor.yy560 = yylhsminor.yy560; +{ yylhsminor.yy616 = setDatabaseOption(pCxt, yymsp[-2].minor.yy616, DB_OPTION_COMP, &yymsp[0].minor.yy0); } + yymsp[-2].minor.yy616 = yylhsminor.yy616; break; case 77: /* db_options ::= db_options DURATION NK_INTEGER */ case 78: /* db_options ::= db_options DURATION NK_VARIABLE */ yytestcase(yyruleno==78); -{ yylhsminor.yy560 = setDatabaseOption(pCxt, yymsp[-2].minor.yy560, DB_OPTION_DAYS, &yymsp[0].minor.yy0); } - yymsp[-2].minor.yy560 = yylhsminor.yy560; +{ yylhsminor.yy616 = setDatabaseOption(pCxt, yymsp[-2].minor.yy616, DB_OPTION_DAYS, &yymsp[0].minor.yy0); } + yymsp[-2].minor.yy616 = yylhsminor.yy616; break; case 79: /* db_options ::= db_options FSYNC NK_INTEGER */ -{ yylhsminor.yy560 = setDatabaseOption(pCxt, yymsp[-2].minor.yy560, DB_OPTION_FSYNC, &yymsp[0].minor.yy0); } - yymsp[-2].minor.yy560 = yylhsminor.yy560; +{ yylhsminor.yy616 = setDatabaseOption(pCxt, yymsp[-2].minor.yy616, DB_OPTION_FSYNC, &yymsp[0].minor.yy0); } + yymsp[-2].minor.yy616 = yylhsminor.yy616; break; case 80: /* db_options ::= db_options MAXROWS NK_INTEGER */ -{ yylhsminor.yy560 = setDatabaseOption(pCxt, yymsp[-2].minor.yy560, DB_OPTION_MAXROWS, &yymsp[0].minor.yy0); } - yymsp[-2].minor.yy560 = yylhsminor.yy560; +{ yylhsminor.yy616 = setDatabaseOption(pCxt, yymsp[-2].minor.yy616, DB_OPTION_MAXROWS, &yymsp[0].minor.yy0); } + yymsp[-2].minor.yy616 = yylhsminor.yy616; break; case 81: /* db_options ::= db_options MINROWS NK_INTEGER */ -{ yylhsminor.yy560 = setDatabaseOption(pCxt, yymsp[-2].minor.yy560, DB_OPTION_MINROWS, &yymsp[0].minor.yy0); } - yymsp[-2].minor.yy560 = yylhsminor.yy560; +{ yylhsminor.yy616 = setDatabaseOption(pCxt, yymsp[-2].minor.yy616, DB_OPTION_MINROWS, &yymsp[0].minor.yy0); } + yymsp[-2].minor.yy616 = yylhsminor.yy616; break; case 82: /* db_options ::= db_options KEEP integer_list */ case 83: /* db_options ::= db_options KEEP variable_list */ yytestcase(yyruleno==83); -{ yylhsminor.yy560 = setDatabaseOption(pCxt, yymsp[-2].minor.yy560, DB_OPTION_KEEP, yymsp[0].minor.yy712); } - yymsp[-2].minor.yy560 = yylhsminor.yy560; +{ yylhsminor.yy616 = setDatabaseOption(pCxt, yymsp[-2].minor.yy616, DB_OPTION_KEEP, yymsp[0].minor.yy356); } + yymsp[-2].minor.yy616 = yylhsminor.yy616; break; case 84: /* db_options ::= db_options PAGES NK_INTEGER */ -{ yylhsminor.yy560 = setDatabaseOption(pCxt, yymsp[-2].minor.yy560, DB_OPTION_PAGES, &yymsp[0].minor.yy0); } - yymsp[-2].minor.yy560 = yylhsminor.yy560; +{ yylhsminor.yy616 = setDatabaseOption(pCxt, yymsp[-2].minor.yy616, DB_OPTION_PAGES, &yymsp[0].minor.yy0); } + yymsp[-2].minor.yy616 = yylhsminor.yy616; break; case 85: /* db_options ::= db_options PAGESIZE NK_INTEGER */ -{ yylhsminor.yy560 = setDatabaseOption(pCxt, yymsp[-2].minor.yy560, DB_OPTION_PAGESIZE, &yymsp[0].minor.yy0); } - yymsp[-2].minor.yy560 = yylhsminor.yy560; +{ yylhsminor.yy616 = setDatabaseOption(pCxt, yymsp[-2].minor.yy616, DB_OPTION_PAGESIZE, &yymsp[0].minor.yy0); } + yymsp[-2].minor.yy616 = yylhsminor.yy616; break; case 86: /* db_options ::= db_options PRECISION NK_STRING */ -{ yylhsminor.yy560 = setDatabaseOption(pCxt, yymsp[-2].minor.yy560, DB_OPTION_PRECISION, &yymsp[0].minor.yy0); } - yymsp[-2].minor.yy560 = yylhsminor.yy560; +{ yylhsminor.yy616 = setDatabaseOption(pCxt, yymsp[-2].minor.yy616, DB_OPTION_PRECISION, &yymsp[0].minor.yy0); } + yymsp[-2].minor.yy616 = yylhsminor.yy616; break; case 87: /* db_options ::= db_options REPLICA NK_INTEGER */ -{ yylhsminor.yy560 = setDatabaseOption(pCxt, yymsp[-2].minor.yy560, DB_OPTION_REPLICA, &yymsp[0].minor.yy0); } - yymsp[-2].minor.yy560 = yylhsminor.yy560; +{ yylhsminor.yy616 = setDatabaseOption(pCxt, yymsp[-2].minor.yy616, DB_OPTION_REPLICA, &yymsp[0].minor.yy0); } + yymsp[-2].minor.yy616 = yylhsminor.yy616; break; case 88: /* db_options ::= db_options STRICT NK_INTEGER */ -{ yylhsminor.yy560 = setDatabaseOption(pCxt, yymsp[-2].minor.yy560, DB_OPTION_STRICT, &yymsp[0].minor.yy0); } - yymsp[-2].minor.yy560 = yylhsminor.yy560; +{ yylhsminor.yy616 = setDatabaseOption(pCxt, yymsp[-2].minor.yy616, DB_OPTION_STRICT, &yymsp[0].minor.yy0); } + yymsp[-2].minor.yy616 = yylhsminor.yy616; break; case 89: /* db_options ::= db_options WAL NK_INTEGER */ -{ yylhsminor.yy560 = setDatabaseOption(pCxt, yymsp[-2].minor.yy560, DB_OPTION_WAL, &yymsp[0].minor.yy0); } - yymsp[-2].minor.yy560 = yylhsminor.yy560; +{ yylhsminor.yy616 = setDatabaseOption(pCxt, yymsp[-2].minor.yy616, DB_OPTION_WAL, &yymsp[0].minor.yy0); } + yymsp[-2].minor.yy616 = yylhsminor.yy616; break; case 90: /* db_options ::= db_options VGROUPS NK_INTEGER */ -{ yylhsminor.yy560 = setDatabaseOption(pCxt, yymsp[-2].minor.yy560, DB_OPTION_VGROUPS, &yymsp[0].minor.yy0); } - yymsp[-2].minor.yy560 = yylhsminor.yy560; +{ yylhsminor.yy616 = setDatabaseOption(pCxt, yymsp[-2].minor.yy616, DB_OPTION_VGROUPS, &yymsp[0].minor.yy0); } + yymsp[-2].minor.yy616 = yylhsminor.yy616; break; case 91: /* db_options ::= db_options SINGLE_STABLE NK_INTEGER */ -{ yylhsminor.yy560 = setDatabaseOption(pCxt, yymsp[-2].minor.yy560, DB_OPTION_SINGLE_STABLE, &yymsp[0].minor.yy0); } - yymsp[-2].minor.yy560 = yylhsminor.yy560; +{ yylhsminor.yy616 = setDatabaseOption(pCxt, yymsp[-2].minor.yy616, DB_OPTION_SINGLE_STABLE, &yymsp[0].minor.yy0); } + yymsp[-2].minor.yy616 = yylhsminor.yy616; break; case 92: /* db_options ::= db_options RETENTIONS retention_list */ -{ yylhsminor.yy560 = setDatabaseOption(pCxt, yymsp[-2].minor.yy560, DB_OPTION_RETENTIONS, yymsp[0].minor.yy712); } - yymsp[-2].minor.yy560 = yylhsminor.yy560; +{ yylhsminor.yy616 = setDatabaseOption(pCxt, yymsp[-2].minor.yy616, DB_OPTION_RETENTIONS, yymsp[0].minor.yy356); } + yymsp[-2].minor.yy616 = yylhsminor.yy616; break; case 93: /* db_options ::= db_options SCHEMALESS NK_INTEGER */ -{ yylhsminor.yy560 = setDatabaseOption(pCxt, yymsp[-2].minor.yy560, DB_OPTION_SCHEMALESS, &yymsp[0].minor.yy0); } - yymsp[-2].minor.yy560 = yylhsminor.yy560; +{ yylhsminor.yy616 = setDatabaseOption(pCxt, yymsp[-2].minor.yy616, DB_OPTION_SCHEMALESS, &yymsp[0].minor.yy0); } + yymsp[-2].minor.yy616 = yylhsminor.yy616; break; case 94: /* alter_db_options ::= alter_db_option */ -{ yylhsminor.yy560 = createAlterDatabaseOptions(pCxt); yylhsminor.yy560 = setAlterDatabaseOption(pCxt, yylhsminor.yy560, &yymsp[0].minor.yy389); } - yymsp[0].minor.yy560 = yylhsminor.yy560; +{ yylhsminor.yy616 = createAlterDatabaseOptions(pCxt); yylhsminor.yy616 = setAlterDatabaseOption(pCxt, yylhsminor.yy616, &yymsp[0].minor.yy409); } + yymsp[0].minor.yy616 = yylhsminor.yy616; break; case 95: /* alter_db_options ::= alter_db_options alter_db_option */ -{ yylhsminor.yy560 = setAlterDatabaseOption(pCxt, yymsp[-1].minor.yy560, &yymsp[0].minor.yy389); } - yymsp[-1].minor.yy560 = yylhsminor.yy560; +{ yylhsminor.yy616 = setAlterDatabaseOption(pCxt, yymsp[-1].minor.yy616, &yymsp[0].minor.yy409); } + yymsp[-1].minor.yy616 = yylhsminor.yy616; break; case 96: /* alter_db_option ::= BUFFER NK_INTEGER */ -{ yymsp[-1].minor.yy389.type = DB_OPTION_BUFFER; yymsp[-1].minor.yy389.val = yymsp[0].minor.yy0; } +{ yymsp[-1].minor.yy409.type = DB_OPTION_BUFFER; yymsp[-1].minor.yy409.val = yymsp[0].minor.yy0; } break; case 97: /* alter_db_option ::= CACHELAST NK_INTEGER */ -{ yymsp[-1].minor.yy389.type = DB_OPTION_CACHELAST; yymsp[-1].minor.yy389.val = yymsp[0].minor.yy0; } +{ yymsp[-1].minor.yy409.type = DB_OPTION_CACHELAST; yymsp[-1].minor.yy409.val = yymsp[0].minor.yy0; } break; case 98: /* alter_db_option ::= CACHELASTSIZE NK_INTEGER */ -{ yymsp[-1].minor.yy389.type = DB_OPTION_CACHELASTSIZE; yymsp[-1].minor.yy389.val = yymsp[0].minor.yy0; } +{ yymsp[-1].minor.yy409.type = DB_OPTION_CACHELASTSIZE; yymsp[-1].minor.yy409.val = yymsp[0].minor.yy0; } break; case 99: /* alter_db_option ::= FSYNC NK_INTEGER */ -{ yymsp[-1].minor.yy389.type = DB_OPTION_FSYNC; yymsp[-1].minor.yy389.val = yymsp[0].minor.yy0; } +{ yymsp[-1].minor.yy409.type = DB_OPTION_FSYNC; yymsp[-1].minor.yy409.val = yymsp[0].minor.yy0; } break; case 100: /* alter_db_option ::= KEEP integer_list */ case 101: /* alter_db_option ::= KEEP variable_list */ yytestcase(yyruleno==101); -{ yymsp[-1].minor.yy389.type = DB_OPTION_KEEP; yymsp[-1].minor.yy389.pList = yymsp[0].minor.yy712; } +{ yymsp[-1].minor.yy409.type = DB_OPTION_KEEP; yymsp[-1].minor.yy409.pList = yymsp[0].minor.yy356; } break; case 102: /* alter_db_option ::= PAGES NK_INTEGER */ -{ yymsp[-1].minor.yy389.type = DB_OPTION_PAGES; yymsp[-1].minor.yy389.val = yymsp[0].minor.yy0; } +{ yymsp[-1].minor.yy409.type = DB_OPTION_PAGES; yymsp[-1].minor.yy409.val = yymsp[0].minor.yy0; } break; case 103: /* alter_db_option ::= REPLICA NK_INTEGER */ -{ yymsp[-1].minor.yy389.type = DB_OPTION_REPLICA; yymsp[-1].minor.yy389.val = yymsp[0].minor.yy0; } +{ yymsp[-1].minor.yy409.type = DB_OPTION_REPLICA; yymsp[-1].minor.yy409.val = yymsp[0].minor.yy0; } break; case 104: /* alter_db_option ::= STRICT NK_INTEGER */ -{ yymsp[-1].minor.yy389.type = DB_OPTION_STRICT; yymsp[-1].minor.yy389.val = yymsp[0].minor.yy0; } +{ yymsp[-1].minor.yy409.type = DB_OPTION_STRICT; yymsp[-1].minor.yy409.val = yymsp[0].minor.yy0; } break; case 105: /* alter_db_option ::= WAL NK_INTEGER */ -{ yymsp[-1].minor.yy389.type = DB_OPTION_WAL; yymsp[-1].minor.yy389.val = yymsp[0].minor.yy0; } +{ yymsp[-1].minor.yy409.type = DB_OPTION_WAL; yymsp[-1].minor.yy409.val = yymsp[0].minor.yy0; } break; case 106: /* integer_list ::= NK_INTEGER */ -{ yylhsminor.yy712 = createNodeList(pCxt, createValueNode(pCxt, TSDB_DATA_TYPE_BIGINT, &yymsp[0].minor.yy0)); } - yymsp[0].minor.yy712 = yylhsminor.yy712; +{ yylhsminor.yy356 = createNodeList(pCxt, createValueNode(pCxt, TSDB_DATA_TYPE_BIGINT, &yymsp[0].minor.yy0)); } + yymsp[0].minor.yy356 = yylhsminor.yy356; break; case 107: /* integer_list ::= integer_list NK_COMMA NK_INTEGER */ case 282: /* dnode_list ::= dnode_list DNODE NK_INTEGER */ yytestcase(yyruleno==282); -{ yylhsminor.yy712 = addNodeToList(pCxt, yymsp[-2].minor.yy712, createValueNode(pCxt, TSDB_DATA_TYPE_BIGINT, &yymsp[0].minor.yy0)); } - yymsp[-2].minor.yy712 = yylhsminor.yy712; +{ yylhsminor.yy356 = addNodeToList(pCxt, yymsp[-2].minor.yy356, createValueNode(pCxt, TSDB_DATA_TYPE_BIGINT, &yymsp[0].minor.yy0)); } + yymsp[-2].minor.yy356 = yylhsminor.yy356; break; case 108: /* variable_list ::= NK_VARIABLE */ -{ yylhsminor.yy712 = createNodeList(pCxt, createDurationValueNode(pCxt, &yymsp[0].minor.yy0)); } - yymsp[0].minor.yy712 = yylhsminor.yy712; +{ yylhsminor.yy356 = createNodeList(pCxt, createDurationValueNode(pCxt, &yymsp[0].minor.yy0)); } + yymsp[0].minor.yy356 = yylhsminor.yy356; break; case 109: /* variable_list ::= variable_list NK_COMMA NK_VARIABLE */ -{ yylhsminor.yy712 = addNodeToList(pCxt, yymsp[-2].minor.yy712, createDurationValueNode(pCxt, &yymsp[0].minor.yy0)); } - yymsp[-2].minor.yy712 = yylhsminor.yy712; +{ yylhsminor.yy356 = addNodeToList(pCxt, yymsp[-2].minor.yy356, createDurationValueNode(pCxt, &yymsp[0].minor.yy0)); } + yymsp[-2].minor.yy356 = yylhsminor.yy356; break; case 110: /* retention_list ::= retention */ case 130: /* multi_create_clause ::= create_subtable_clause */ yytestcase(yyruleno==130); @@ -3625,266 +3677,266 @@ static YYACTIONTYPE yy_reduce( case 183: /* rollup_func_list ::= rollup_func_name */ yytestcase(yyruleno==183); case 188: /* col_name_list ::= col_name */ yytestcase(yyruleno==188); case 235: /* func_list ::= func */ yytestcase(yyruleno==235); - case 310: /* literal_list ::= signed_literal */ yytestcase(yyruleno==310); - case 372: /* other_para_list ::= star_func_para */ yytestcase(yyruleno==372); - case 426: /* select_list ::= select_item */ yytestcase(yyruleno==426); - case 480: /* sort_specification_list ::= sort_specification */ yytestcase(yyruleno==480); -{ yylhsminor.yy712 = createNodeList(pCxt, yymsp[0].minor.yy560); } - yymsp[0].minor.yy712 = yylhsminor.yy712; + case 311: /* literal_list ::= signed_literal */ yytestcase(yyruleno==311); + case 374: /* other_para_list ::= star_func_para */ yytestcase(yyruleno==374); + case 428: /* select_list ::= select_item */ yytestcase(yyruleno==428); + case 482: /* sort_specification_list ::= sort_specification */ yytestcase(yyruleno==482); +{ yylhsminor.yy356 = createNodeList(pCxt, yymsp[0].minor.yy616); } + yymsp[0].minor.yy356 = yylhsminor.yy356; break; case 111: /* retention_list ::= retention_list NK_COMMA retention */ case 141: /* column_def_list ::= column_def_list NK_COMMA column_def */ yytestcase(yyruleno==141); case 184: /* rollup_func_list ::= rollup_func_list NK_COMMA rollup_func_name */ yytestcase(yyruleno==184); case 189: /* col_name_list ::= col_name_list NK_COMMA col_name */ yytestcase(yyruleno==189); case 236: /* func_list ::= func_list NK_COMMA func */ yytestcase(yyruleno==236); - case 311: /* literal_list ::= literal_list NK_COMMA signed_literal */ yytestcase(yyruleno==311); - case 373: /* other_para_list ::= other_para_list NK_COMMA star_func_para */ yytestcase(yyruleno==373); - case 427: /* select_list ::= select_list NK_COMMA select_item */ yytestcase(yyruleno==427); - case 481: /* sort_specification_list ::= sort_specification_list NK_COMMA sort_specification */ yytestcase(yyruleno==481); -{ yylhsminor.yy712 = addNodeToList(pCxt, yymsp[-2].minor.yy712, yymsp[0].minor.yy560); } - yymsp[-2].minor.yy712 = yylhsminor.yy712; + case 312: /* literal_list ::= literal_list NK_COMMA signed_literal */ yytestcase(yyruleno==312); + case 375: /* other_para_list ::= other_para_list NK_COMMA star_func_para */ yytestcase(yyruleno==375); + case 429: /* select_list ::= select_list NK_COMMA select_item */ yytestcase(yyruleno==429); + case 483: /* sort_specification_list ::= sort_specification_list NK_COMMA sort_specification */ yytestcase(yyruleno==483); +{ yylhsminor.yy356 = addNodeToList(pCxt, yymsp[-2].minor.yy356, yymsp[0].minor.yy616); } + yymsp[-2].minor.yy356 = yylhsminor.yy356; break; case 112: /* retention ::= NK_VARIABLE NK_COLON NK_VARIABLE */ -{ yylhsminor.yy560 = createNodeListNodeEx(pCxt, createDurationValueNode(pCxt, &yymsp[-2].minor.yy0), createDurationValueNode(pCxt, &yymsp[0].minor.yy0)); } - yymsp[-2].minor.yy560 = yylhsminor.yy560; +{ yylhsminor.yy616 = createNodeListNodeEx(pCxt, createDurationValueNode(pCxt, &yymsp[-2].minor.yy0), createDurationValueNode(pCxt, &yymsp[0].minor.yy0)); } + yymsp[-2].minor.yy616 = yylhsminor.yy616; break; case 113: /* cmd ::= CREATE TABLE not_exists_opt full_table_name NK_LP column_def_list NK_RP tags_def_opt table_options */ case 115: /* cmd ::= CREATE STABLE not_exists_opt full_table_name NK_LP column_def_list NK_RP tags_def table_options */ yytestcase(yyruleno==115); -{ pCxt->pRootNode = createCreateTableStmt(pCxt, yymsp[-6].minor.yy173, yymsp[-5].minor.yy560, yymsp[-3].minor.yy712, yymsp[-1].minor.yy712, yymsp[0].minor.yy560); } +{ pCxt->pRootNode = createCreateTableStmt(pCxt, yymsp[-6].minor.yy151, yymsp[-5].minor.yy616, yymsp[-3].minor.yy356, yymsp[-1].minor.yy356, yymsp[0].minor.yy616); } break; case 114: /* cmd ::= CREATE TABLE multi_create_clause */ -{ pCxt->pRootNode = createCreateMultiTableStmt(pCxt, yymsp[0].minor.yy712); } +{ pCxt->pRootNode = createCreateMultiTableStmt(pCxt, yymsp[0].minor.yy356); } break; case 116: /* cmd ::= DROP TABLE multi_drop_clause */ -{ pCxt->pRootNode = createDropTableStmt(pCxt, yymsp[0].minor.yy712); } +{ pCxt->pRootNode = createDropTableStmt(pCxt, yymsp[0].minor.yy356); } break; case 117: /* cmd ::= DROP STABLE exists_opt full_table_name */ -{ pCxt->pRootNode = createDropSuperTableStmt(pCxt, yymsp[-1].minor.yy173, yymsp[0].minor.yy560); } +{ pCxt->pRootNode = createDropSuperTableStmt(pCxt, yymsp[-1].minor.yy151, yymsp[0].minor.yy616); } break; case 118: /* cmd ::= ALTER TABLE alter_table_clause */ case 285: /* cmd ::= query_expression */ yytestcase(yyruleno==285); -{ pCxt->pRootNode = yymsp[0].minor.yy560; } +{ pCxt->pRootNode = yymsp[0].minor.yy616; } break; case 119: /* cmd ::= ALTER STABLE alter_table_clause */ -{ pCxt->pRootNode = setAlterSuperTableType(yymsp[0].minor.yy560); } +{ pCxt->pRootNode = setAlterSuperTableType(yymsp[0].minor.yy616); } break; case 120: /* alter_table_clause ::= full_table_name alter_table_options */ -{ yylhsminor.yy560 = createAlterTableModifyOptions(pCxt, yymsp[-1].minor.yy560, yymsp[0].minor.yy560); } - yymsp[-1].minor.yy560 = yylhsminor.yy560; +{ yylhsminor.yy616 = createAlterTableModifyOptions(pCxt, yymsp[-1].minor.yy616, yymsp[0].minor.yy616); } + yymsp[-1].minor.yy616 = yylhsminor.yy616; break; case 121: /* alter_table_clause ::= full_table_name ADD COLUMN column_name type_name */ -{ yylhsminor.yy560 = createAlterTableAddModifyCol(pCxt, yymsp[-4].minor.yy560, TSDB_ALTER_TABLE_ADD_COLUMN, &yymsp[-1].minor.yy533, yymsp[0].minor.yy196); } - yymsp[-4].minor.yy560 = yylhsminor.yy560; +{ yylhsminor.yy616 = createAlterTableAddModifyCol(pCxt, yymsp[-4].minor.yy616, TSDB_ALTER_TABLE_ADD_COLUMN, &yymsp[-1].minor.yy361, yymsp[0].minor.yy600); } + yymsp[-4].minor.yy616 = yylhsminor.yy616; break; case 122: /* alter_table_clause ::= full_table_name DROP COLUMN column_name */ -{ yylhsminor.yy560 = createAlterTableDropCol(pCxt, yymsp[-3].minor.yy560, TSDB_ALTER_TABLE_DROP_COLUMN, &yymsp[0].minor.yy533); } - yymsp[-3].minor.yy560 = yylhsminor.yy560; +{ yylhsminor.yy616 = createAlterTableDropCol(pCxt, yymsp[-3].minor.yy616, TSDB_ALTER_TABLE_DROP_COLUMN, &yymsp[0].minor.yy361); } + yymsp[-3].minor.yy616 = yylhsminor.yy616; break; case 123: /* alter_table_clause ::= full_table_name MODIFY COLUMN column_name type_name */ -{ yylhsminor.yy560 = createAlterTableAddModifyCol(pCxt, yymsp[-4].minor.yy560, TSDB_ALTER_TABLE_UPDATE_COLUMN_BYTES, &yymsp[-1].minor.yy533, yymsp[0].minor.yy196); } - yymsp[-4].minor.yy560 = yylhsminor.yy560; +{ yylhsminor.yy616 = createAlterTableAddModifyCol(pCxt, yymsp[-4].minor.yy616, TSDB_ALTER_TABLE_UPDATE_COLUMN_BYTES, &yymsp[-1].minor.yy361, yymsp[0].minor.yy600); } + yymsp[-4].minor.yy616 = yylhsminor.yy616; break; case 124: /* alter_table_clause ::= full_table_name RENAME COLUMN column_name column_name */ -{ yylhsminor.yy560 = createAlterTableRenameCol(pCxt, yymsp[-4].minor.yy560, TSDB_ALTER_TABLE_UPDATE_COLUMN_NAME, &yymsp[-1].minor.yy533, &yymsp[0].minor.yy533); } - yymsp[-4].minor.yy560 = yylhsminor.yy560; +{ yylhsminor.yy616 = createAlterTableRenameCol(pCxt, yymsp[-4].minor.yy616, TSDB_ALTER_TABLE_UPDATE_COLUMN_NAME, &yymsp[-1].minor.yy361, &yymsp[0].minor.yy361); } + yymsp[-4].minor.yy616 = yylhsminor.yy616; break; case 125: /* alter_table_clause ::= full_table_name ADD TAG column_name type_name */ -{ yylhsminor.yy560 = createAlterTableAddModifyCol(pCxt, yymsp[-4].minor.yy560, TSDB_ALTER_TABLE_ADD_TAG, &yymsp[-1].minor.yy533, yymsp[0].minor.yy196); } - yymsp[-4].minor.yy560 = yylhsminor.yy560; +{ yylhsminor.yy616 = createAlterTableAddModifyCol(pCxt, yymsp[-4].minor.yy616, TSDB_ALTER_TABLE_ADD_TAG, &yymsp[-1].minor.yy361, yymsp[0].minor.yy600); } + yymsp[-4].minor.yy616 = yylhsminor.yy616; break; case 126: /* alter_table_clause ::= full_table_name DROP TAG column_name */ -{ yylhsminor.yy560 = createAlterTableDropCol(pCxt, yymsp[-3].minor.yy560, TSDB_ALTER_TABLE_DROP_TAG, &yymsp[0].minor.yy533); } - yymsp[-3].minor.yy560 = yylhsminor.yy560; +{ yylhsminor.yy616 = createAlterTableDropCol(pCxt, yymsp[-3].minor.yy616, TSDB_ALTER_TABLE_DROP_TAG, &yymsp[0].minor.yy361); } + yymsp[-3].minor.yy616 = yylhsminor.yy616; break; case 127: /* alter_table_clause ::= full_table_name MODIFY TAG column_name type_name */ -{ yylhsminor.yy560 = createAlterTableAddModifyCol(pCxt, yymsp[-4].minor.yy560, TSDB_ALTER_TABLE_UPDATE_TAG_BYTES, &yymsp[-1].minor.yy533, yymsp[0].minor.yy196); } - yymsp[-4].minor.yy560 = yylhsminor.yy560; +{ yylhsminor.yy616 = createAlterTableAddModifyCol(pCxt, yymsp[-4].minor.yy616, TSDB_ALTER_TABLE_UPDATE_TAG_BYTES, &yymsp[-1].minor.yy361, yymsp[0].minor.yy600); } + yymsp[-4].minor.yy616 = yylhsminor.yy616; break; case 128: /* alter_table_clause ::= full_table_name RENAME TAG column_name column_name */ -{ yylhsminor.yy560 = createAlterTableRenameCol(pCxt, yymsp[-4].minor.yy560, TSDB_ALTER_TABLE_UPDATE_TAG_NAME, &yymsp[-1].minor.yy533, &yymsp[0].minor.yy533); } - yymsp[-4].minor.yy560 = yylhsminor.yy560; +{ yylhsminor.yy616 = createAlterTableRenameCol(pCxt, yymsp[-4].minor.yy616, TSDB_ALTER_TABLE_UPDATE_TAG_NAME, &yymsp[-1].minor.yy361, &yymsp[0].minor.yy361); } + yymsp[-4].minor.yy616 = yylhsminor.yy616; break; case 129: /* alter_table_clause ::= full_table_name SET TAG column_name NK_EQ signed_literal */ -{ yylhsminor.yy560 = createAlterTableSetTag(pCxt, yymsp[-5].minor.yy560, &yymsp[-2].minor.yy533, yymsp[0].minor.yy560); } - yymsp[-5].minor.yy560 = yylhsminor.yy560; +{ yylhsminor.yy616 = createAlterTableSetTag(pCxt, yymsp[-5].minor.yy616, &yymsp[-2].minor.yy361, yymsp[0].minor.yy616); } + yymsp[-5].minor.yy616 = yylhsminor.yy616; break; case 131: /* multi_create_clause ::= multi_create_clause create_subtable_clause */ case 134: /* multi_drop_clause ::= multi_drop_clause drop_table_clause */ yytestcase(yyruleno==134); -{ yylhsminor.yy712 = addNodeToList(pCxt, yymsp[-1].minor.yy712, yymsp[0].minor.yy560); } - yymsp[-1].minor.yy712 = yylhsminor.yy712; +{ yylhsminor.yy356 = addNodeToList(pCxt, yymsp[-1].minor.yy356, yymsp[0].minor.yy616); } + yymsp[-1].minor.yy356 = yylhsminor.yy356; break; case 132: /* create_subtable_clause ::= not_exists_opt full_table_name USING full_table_name specific_cols_opt TAGS NK_LP expression_list NK_RP table_options */ -{ yylhsminor.yy560 = createCreateSubTableClause(pCxt, yymsp[-9].minor.yy173, yymsp[-8].minor.yy560, yymsp[-6].minor.yy560, yymsp[-5].minor.yy712, yymsp[-2].minor.yy712, yymsp[0].minor.yy560); } - yymsp[-9].minor.yy560 = yylhsminor.yy560; +{ yylhsminor.yy616 = createCreateSubTableClause(pCxt, yymsp[-9].minor.yy151, yymsp[-8].minor.yy616, yymsp[-6].minor.yy616, yymsp[-5].minor.yy356, yymsp[-2].minor.yy356, yymsp[0].minor.yy616); } + yymsp[-9].minor.yy616 = yylhsminor.yy616; break; case 135: /* drop_table_clause ::= exists_opt full_table_name */ -{ yylhsminor.yy560 = createDropTableClause(pCxt, yymsp[-1].minor.yy173, yymsp[0].minor.yy560); } - yymsp[-1].minor.yy560 = yylhsminor.yy560; +{ yylhsminor.yy616 = createDropTableClause(pCxt, yymsp[-1].minor.yy151, yymsp[0].minor.yy616); } + yymsp[-1].minor.yy616 = yylhsminor.yy616; break; case 136: /* specific_cols_opt ::= */ case 167: /* tags_def_opt ::= */ yytestcase(yyruleno==167); - case 435: /* partition_by_clause_opt ::= */ yytestcase(yyruleno==435); - case 452: /* group_by_clause_opt ::= */ yytestcase(yyruleno==452); - case 468: /* order_by_clause_opt ::= */ yytestcase(yyruleno==468); -{ yymsp[1].minor.yy712 = NULL; } + case 437: /* partition_by_clause_opt ::= */ yytestcase(yyruleno==437); + case 454: /* group_by_clause_opt ::= */ yytestcase(yyruleno==454); + case 470: /* order_by_clause_opt ::= */ yytestcase(yyruleno==470); +{ yymsp[1].minor.yy356 = NULL; } break; case 137: /* specific_cols_opt ::= NK_LP col_name_list NK_RP */ -{ yymsp[-2].minor.yy712 = yymsp[-1].minor.yy712; } +{ yymsp[-2].minor.yy356 = yymsp[-1].minor.yy356; } break; case 138: /* full_table_name ::= table_name */ -{ yylhsminor.yy560 = createRealTableNode(pCxt, NULL, &yymsp[0].minor.yy533, NULL); } - yymsp[0].minor.yy560 = yylhsminor.yy560; +{ yylhsminor.yy616 = createRealTableNode(pCxt, NULL, &yymsp[0].minor.yy361, NULL); } + yymsp[0].minor.yy616 = yylhsminor.yy616; break; case 139: /* full_table_name ::= db_name NK_DOT table_name */ -{ yylhsminor.yy560 = createRealTableNode(pCxt, &yymsp[-2].minor.yy533, &yymsp[0].minor.yy533, NULL); } - yymsp[-2].minor.yy560 = yylhsminor.yy560; +{ yylhsminor.yy616 = createRealTableNode(pCxt, &yymsp[-2].minor.yy361, &yymsp[0].minor.yy361, NULL); } + yymsp[-2].minor.yy616 = yylhsminor.yy616; break; case 142: /* column_def ::= column_name type_name */ -{ yylhsminor.yy560 = createColumnDefNode(pCxt, &yymsp[-1].minor.yy533, yymsp[0].minor.yy196, NULL); } - yymsp[-1].minor.yy560 = yylhsminor.yy560; +{ yylhsminor.yy616 = createColumnDefNode(pCxt, &yymsp[-1].minor.yy361, yymsp[0].minor.yy600, NULL); } + yymsp[-1].minor.yy616 = yylhsminor.yy616; break; case 143: /* column_def ::= column_name type_name COMMENT NK_STRING */ -{ yylhsminor.yy560 = createColumnDefNode(pCxt, &yymsp[-3].minor.yy533, yymsp[-2].minor.yy196, &yymsp[0].minor.yy0); } - yymsp[-3].minor.yy560 = yylhsminor.yy560; +{ yylhsminor.yy616 = createColumnDefNode(pCxt, &yymsp[-3].minor.yy361, yymsp[-2].minor.yy600, &yymsp[0].minor.yy0); } + yymsp[-3].minor.yy616 = yylhsminor.yy616; break; case 144: /* type_name ::= BOOL */ -{ yymsp[0].minor.yy196 = createDataType(TSDB_DATA_TYPE_BOOL); } +{ yymsp[0].minor.yy600 = createDataType(TSDB_DATA_TYPE_BOOL); } break; case 145: /* type_name ::= TINYINT */ -{ yymsp[0].minor.yy196 = createDataType(TSDB_DATA_TYPE_TINYINT); } +{ yymsp[0].minor.yy600 = createDataType(TSDB_DATA_TYPE_TINYINT); } break; case 146: /* type_name ::= SMALLINT */ -{ yymsp[0].minor.yy196 = createDataType(TSDB_DATA_TYPE_SMALLINT); } +{ yymsp[0].minor.yy600 = createDataType(TSDB_DATA_TYPE_SMALLINT); } break; case 147: /* type_name ::= INT */ case 148: /* type_name ::= INTEGER */ yytestcase(yyruleno==148); -{ yymsp[0].minor.yy196 = createDataType(TSDB_DATA_TYPE_INT); } +{ yymsp[0].minor.yy600 = createDataType(TSDB_DATA_TYPE_INT); } break; case 149: /* type_name ::= BIGINT */ -{ yymsp[0].minor.yy196 = createDataType(TSDB_DATA_TYPE_BIGINT); } +{ yymsp[0].minor.yy600 = createDataType(TSDB_DATA_TYPE_BIGINT); } break; case 150: /* type_name ::= FLOAT */ -{ yymsp[0].minor.yy196 = createDataType(TSDB_DATA_TYPE_FLOAT); } +{ yymsp[0].minor.yy600 = createDataType(TSDB_DATA_TYPE_FLOAT); } break; case 151: /* type_name ::= DOUBLE */ -{ yymsp[0].minor.yy196 = createDataType(TSDB_DATA_TYPE_DOUBLE); } +{ yymsp[0].minor.yy600 = createDataType(TSDB_DATA_TYPE_DOUBLE); } break; case 152: /* type_name ::= BINARY NK_LP NK_INTEGER NK_RP */ -{ yymsp[-3].minor.yy196 = createVarLenDataType(TSDB_DATA_TYPE_BINARY, &yymsp[-1].minor.yy0); } +{ yymsp[-3].minor.yy600 = createVarLenDataType(TSDB_DATA_TYPE_BINARY, &yymsp[-1].minor.yy0); } break; case 153: /* type_name ::= TIMESTAMP */ -{ yymsp[0].minor.yy196 = createDataType(TSDB_DATA_TYPE_TIMESTAMP); } +{ yymsp[0].minor.yy600 = createDataType(TSDB_DATA_TYPE_TIMESTAMP); } break; case 154: /* type_name ::= NCHAR NK_LP NK_INTEGER NK_RP */ -{ yymsp[-3].minor.yy196 = createVarLenDataType(TSDB_DATA_TYPE_NCHAR, &yymsp[-1].minor.yy0); } +{ yymsp[-3].minor.yy600 = createVarLenDataType(TSDB_DATA_TYPE_NCHAR, &yymsp[-1].minor.yy0); } break; case 155: /* type_name ::= TINYINT UNSIGNED */ -{ yymsp[-1].minor.yy196 = createDataType(TSDB_DATA_TYPE_UTINYINT); } +{ yymsp[-1].minor.yy600 = createDataType(TSDB_DATA_TYPE_UTINYINT); } break; case 156: /* type_name ::= SMALLINT UNSIGNED */ -{ yymsp[-1].minor.yy196 = createDataType(TSDB_DATA_TYPE_USMALLINT); } +{ yymsp[-1].minor.yy600 = createDataType(TSDB_DATA_TYPE_USMALLINT); } break; case 157: /* type_name ::= INT UNSIGNED */ -{ yymsp[-1].minor.yy196 = createDataType(TSDB_DATA_TYPE_UINT); } +{ yymsp[-1].minor.yy600 = createDataType(TSDB_DATA_TYPE_UINT); } break; case 158: /* type_name ::= BIGINT UNSIGNED */ -{ yymsp[-1].minor.yy196 = createDataType(TSDB_DATA_TYPE_UBIGINT); } +{ yymsp[-1].minor.yy600 = createDataType(TSDB_DATA_TYPE_UBIGINT); } break; case 159: /* type_name ::= JSON */ -{ yymsp[0].minor.yy196 = createDataType(TSDB_DATA_TYPE_JSON); } +{ yymsp[0].minor.yy600 = createDataType(TSDB_DATA_TYPE_JSON); } break; case 160: /* type_name ::= VARCHAR NK_LP NK_INTEGER NK_RP */ -{ yymsp[-3].minor.yy196 = createVarLenDataType(TSDB_DATA_TYPE_VARCHAR, &yymsp[-1].minor.yy0); } +{ yymsp[-3].minor.yy600 = createVarLenDataType(TSDB_DATA_TYPE_VARCHAR, &yymsp[-1].minor.yy0); } break; case 161: /* type_name ::= MEDIUMBLOB */ -{ yymsp[0].minor.yy196 = createDataType(TSDB_DATA_TYPE_MEDIUMBLOB); } +{ yymsp[0].minor.yy600 = createDataType(TSDB_DATA_TYPE_MEDIUMBLOB); } break; case 162: /* type_name ::= BLOB */ -{ yymsp[0].minor.yy196 = createDataType(TSDB_DATA_TYPE_BLOB); } +{ yymsp[0].minor.yy600 = createDataType(TSDB_DATA_TYPE_BLOB); } break; case 163: /* type_name ::= VARBINARY NK_LP NK_INTEGER NK_RP */ -{ yymsp[-3].minor.yy196 = createVarLenDataType(TSDB_DATA_TYPE_VARBINARY, &yymsp[-1].minor.yy0); } +{ yymsp[-3].minor.yy600 = createVarLenDataType(TSDB_DATA_TYPE_VARBINARY, &yymsp[-1].minor.yy0); } break; case 164: /* type_name ::= DECIMAL */ -{ yymsp[0].minor.yy196 = createDataType(TSDB_DATA_TYPE_DECIMAL); } +{ yymsp[0].minor.yy600 = createDataType(TSDB_DATA_TYPE_DECIMAL); } break; case 165: /* type_name ::= DECIMAL NK_LP NK_INTEGER NK_RP */ -{ yymsp[-3].minor.yy196 = createDataType(TSDB_DATA_TYPE_DECIMAL); } +{ yymsp[-3].minor.yy600 = createDataType(TSDB_DATA_TYPE_DECIMAL); } break; case 166: /* type_name ::= DECIMAL NK_LP NK_INTEGER NK_COMMA NK_INTEGER NK_RP */ -{ yymsp[-5].minor.yy196 = createDataType(TSDB_DATA_TYPE_DECIMAL); } +{ yymsp[-5].minor.yy600 = createDataType(TSDB_DATA_TYPE_DECIMAL); } break; case 168: /* tags_def_opt ::= tags_def */ - case 371: /* star_func_para_list ::= other_para_list */ yytestcase(yyruleno==371); -{ yylhsminor.yy712 = yymsp[0].minor.yy712; } - yymsp[0].minor.yy712 = yylhsminor.yy712; + case 373: /* star_func_para_list ::= other_para_list */ yytestcase(yyruleno==373); +{ yylhsminor.yy356 = yymsp[0].minor.yy356; } + yymsp[0].minor.yy356 = yylhsminor.yy356; break; case 169: /* tags_def ::= TAGS NK_LP column_def_list NK_RP */ -{ yymsp[-3].minor.yy712 = yymsp[-1].minor.yy712; } +{ yymsp[-3].minor.yy356 = yymsp[-1].minor.yy356; } break; case 170: /* table_options ::= */ -{ yymsp[1].minor.yy560 = createDefaultTableOptions(pCxt); } +{ yymsp[1].minor.yy616 = createDefaultTableOptions(pCxt); } break; case 171: /* table_options ::= table_options COMMENT NK_STRING */ -{ yylhsminor.yy560 = setTableOption(pCxt, yymsp[-2].minor.yy560, TABLE_OPTION_COMMENT, &yymsp[0].minor.yy0); } - yymsp[-2].minor.yy560 = yylhsminor.yy560; +{ yylhsminor.yy616 = setTableOption(pCxt, yymsp[-2].minor.yy616, TABLE_OPTION_COMMENT, &yymsp[0].minor.yy0); } + yymsp[-2].minor.yy616 = yylhsminor.yy616; break; case 172: /* table_options ::= table_options MAX_DELAY duration_list */ -{ yylhsminor.yy560 = setTableOption(pCxt, yymsp[-2].minor.yy560, TABLE_OPTION_MAXDELAY, yymsp[0].minor.yy712); } - yymsp[-2].minor.yy560 = yylhsminor.yy560; +{ yylhsminor.yy616 = setTableOption(pCxt, yymsp[-2].minor.yy616, TABLE_OPTION_MAXDELAY, yymsp[0].minor.yy356); } + yymsp[-2].minor.yy616 = yylhsminor.yy616; break; case 173: /* table_options ::= table_options WATERMARK duration_list */ -{ yylhsminor.yy560 = setTableOption(pCxt, yymsp[-2].minor.yy560, TABLE_OPTION_WATERMARK, yymsp[0].minor.yy712); } - yymsp[-2].minor.yy560 = yylhsminor.yy560; +{ yylhsminor.yy616 = setTableOption(pCxt, yymsp[-2].minor.yy616, TABLE_OPTION_WATERMARK, yymsp[0].minor.yy356); } + yymsp[-2].minor.yy616 = yylhsminor.yy616; break; case 174: /* table_options ::= table_options ROLLUP NK_LP rollup_func_list NK_RP */ -{ yylhsminor.yy560 = setTableOption(pCxt, yymsp[-4].minor.yy560, TABLE_OPTION_ROLLUP, yymsp[-1].minor.yy712); } - yymsp[-4].minor.yy560 = yylhsminor.yy560; +{ yylhsminor.yy616 = setTableOption(pCxt, yymsp[-4].minor.yy616, TABLE_OPTION_ROLLUP, yymsp[-1].minor.yy356); } + yymsp[-4].minor.yy616 = yylhsminor.yy616; break; case 175: /* table_options ::= table_options TTL NK_INTEGER */ -{ yylhsminor.yy560 = setTableOption(pCxt, yymsp[-2].minor.yy560, TABLE_OPTION_TTL, &yymsp[0].minor.yy0); } - yymsp[-2].minor.yy560 = yylhsminor.yy560; +{ yylhsminor.yy616 = setTableOption(pCxt, yymsp[-2].minor.yy616, TABLE_OPTION_TTL, &yymsp[0].minor.yy0); } + yymsp[-2].minor.yy616 = yylhsminor.yy616; break; case 176: /* table_options ::= table_options SMA NK_LP col_name_list NK_RP */ -{ yylhsminor.yy560 = setTableOption(pCxt, yymsp[-4].minor.yy560, TABLE_OPTION_SMA, yymsp[-1].minor.yy712); } - yymsp[-4].minor.yy560 = yylhsminor.yy560; +{ yylhsminor.yy616 = setTableOption(pCxt, yymsp[-4].minor.yy616, TABLE_OPTION_SMA, yymsp[-1].minor.yy356); } + yymsp[-4].minor.yy616 = yylhsminor.yy616; break; case 177: /* alter_table_options ::= alter_table_option */ -{ yylhsminor.yy560 = createAlterTableOptions(pCxt); yylhsminor.yy560 = setTableOption(pCxt, yylhsminor.yy560, yymsp[0].minor.yy389.type, &yymsp[0].minor.yy389.val); } - yymsp[0].minor.yy560 = yylhsminor.yy560; +{ yylhsminor.yy616 = createAlterTableOptions(pCxt); yylhsminor.yy616 = setTableOption(pCxt, yylhsminor.yy616, yymsp[0].minor.yy409.type, &yymsp[0].minor.yy409.val); } + yymsp[0].minor.yy616 = yylhsminor.yy616; break; case 178: /* alter_table_options ::= alter_table_options alter_table_option */ -{ yylhsminor.yy560 = setTableOption(pCxt, yymsp[-1].minor.yy560, yymsp[0].minor.yy389.type, &yymsp[0].minor.yy389.val); } - yymsp[-1].minor.yy560 = yylhsminor.yy560; +{ yylhsminor.yy616 = setTableOption(pCxt, yymsp[-1].minor.yy616, yymsp[0].minor.yy409.type, &yymsp[0].minor.yy409.val); } + yymsp[-1].minor.yy616 = yylhsminor.yy616; break; case 179: /* alter_table_option ::= COMMENT NK_STRING */ -{ yymsp[-1].minor.yy389.type = TABLE_OPTION_COMMENT; yymsp[-1].minor.yy389.val = yymsp[0].minor.yy0; } +{ yymsp[-1].minor.yy409.type = TABLE_OPTION_COMMENT; yymsp[-1].minor.yy409.val = yymsp[0].minor.yy0; } break; case 180: /* alter_table_option ::= TTL NK_INTEGER */ -{ yymsp[-1].minor.yy389.type = TABLE_OPTION_TTL; yymsp[-1].minor.yy389.val = yymsp[0].minor.yy0; } +{ yymsp[-1].minor.yy409.type = TABLE_OPTION_TTL; yymsp[-1].minor.yy409.val = yymsp[0].minor.yy0; } break; case 181: /* duration_list ::= duration_literal */ - case 339: /* expression_list ::= expression */ yytestcase(yyruleno==339); -{ yylhsminor.yy712 = createNodeList(pCxt, releaseRawExprNode(pCxt, yymsp[0].minor.yy560)); } - yymsp[0].minor.yy712 = yylhsminor.yy712; + case 340: /* expression_list ::= expression */ yytestcase(yyruleno==340); +{ yylhsminor.yy356 = createNodeList(pCxt, releaseRawExprNode(pCxt, yymsp[0].minor.yy616)); } + yymsp[0].minor.yy356 = yylhsminor.yy356; break; case 182: /* duration_list ::= duration_list NK_COMMA duration_literal */ - case 340: /* expression_list ::= expression_list NK_COMMA expression */ yytestcase(yyruleno==340); -{ yylhsminor.yy712 = addNodeToList(pCxt, yymsp[-2].minor.yy712, releaseRawExprNode(pCxt, yymsp[0].minor.yy560)); } - yymsp[-2].minor.yy712 = yylhsminor.yy712; + case 341: /* expression_list ::= expression_list NK_COMMA expression */ yytestcase(yyruleno==341); +{ yylhsminor.yy356 = addNodeToList(pCxt, yymsp[-2].minor.yy356, releaseRawExprNode(pCxt, yymsp[0].minor.yy616)); } + yymsp[-2].minor.yy356 = yylhsminor.yy356; break; case 185: /* rollup_func_name ::= function_name */ -{ yylhsminor.yy560 = createFunctionNode(pCxt, &yymsp[0].minor.yy533, NULL); } - yymsp[0].minor.yy560 = yylhsminor.yy560; +{ yylhsminor.yy616 = createFunctionNode(pCxt, &yymsp[0].minor.yy361, NULL); } + yymsp[0].minor.yy616 = yylhsminor.yy616; break; case 186: /* rollup_func_name ::= FIRST */ case 187: /* rollup_func_name ::= LAST */ yytestcase(yyruleno==187); -{ yylhsminor.yy560 = createFunctionNode(pCxt, &yymsp[0].minor.yy0, NULL); } - yymsp[0].minor.yy560 = yylhsminor.yy560; +{ yylhsminor.yy616 = createFunctionNode(pCxt, &yymsp[0].minor.yy0, NULL); } + yymsp[0].minor.yy616 = yylhsminor.yy616; break; case 190: /* col_name ::= column_name */ -{ yylhsminor.yy560 = createColumnNode(pCxt, NULL, &yymsp[0].minor.yy533); } - yymsp[0].minor.yy560 = yylhsminor.yy560; +{ yylhsminor.yy616 = createColumnNode(pCxt, NULL, &yymsp[0].minor.yy361); } + yymsp[0].minor.yy616 = yylhsminor.yy616; break; case 191: /* cmd ::= SHOW DNODES */ { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_DNODES_STMT); } @@ -3896,13 +3948,13 @@ static YYACTIONTYPE yy_reduce( { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_DATABASES_STMT); } break; case 194: /* cmd ::= SHOW db_name_cond_opt TABLES like_pattern_opt */ -{ pCxt->pRootNode = createShowStmtWithCond(pCxt, QUERY_NODE_SHOW_TABLES_STMT, yymsp[-2].minor.yy560, yymsp[0].minor.yy560, OP_TYPE_LIKE); } +{ pCxt->pRootNode = createShowStmtWithCond(pCxt, QUERY_NODE_SHOW_TABLES_STMT, yymsp[-2].minor.yy616, yymsp[0].minor.yy616, OP_TYPE_LIKE); } break; case 195: /* cmd ::= SHOW db_name_cond_opt STABLES like_pattern_opt */ -{ pCxt->pRootNode = createShowStmtWithCond(pCxt, QUERY_NODE_SHOW_STABLES_STMT, yymsp[-2].minor.yy560, yymsp[0].minor.yy560, OP_TYPE_LIKE); } +{ pCxt->pRootNode = createShowStmtWithCond(pCxt, QUERY_NODE_SHOW_STABLES_STMT, yymsp[-2].minor.yy616, yymsp[0].minor.yy616, OP_TYPE_LIKE); } break; case 196: /* cmd ::= SHOW db_name_cond_opt VGROUPS */ -{ pCxt->pRootNode = createShowStmtWithCond(pCxt, QUERY_NODE_SHOW_VGROUPS_STMT, yymsp[-1].minor.yy560, NULL, OP_TYPE_LIKE); } +{ pCxt->pRootNode = createShowStmtWithCond(pCxt, QUERY_NODE_SHOW_VGROUPS_STMT, yymsp[-1].minor.yy616, NULL, OP_TYPE_LIKE); } break; case 197: /* cmd ::= SHOW MNODES */ { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_MNODES_STMT); } @@ -3917,7 +3969,7 @@ static YYACTIONTYPE yy_reduce( { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_FUNCTIONS_STMT); } break; case 201: /* cmd ::= SHOW INDEXES FROM table_name_cond from_db_opt */ -{ pCxt->pRootNode = createShowStmtWithCond(pCxt, QUERY_NODE_SHOW_INDEXES_STMT, yymsp[0].minor.yy560, yymsp[-1].minor.yy560, OP_TYPE_EQUAL); } +{ pCxt->pRootNode = createShowStmtWithCond(pCxt, QUERY_NODE_SHOW_INDEXES_STMT, yymsp[0].minor.yy616, yymsp[-1].minor.yy616, OP_TYPE_EQUAL); } break; case 202: /* cmd ::= SHOW STREAMS */ { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_STREAMS_STMT); } @@ -3936,13 +3988,13 @@ static YYACTIONTYPE yy_reduce( { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_LICENCE_STMT); } break; case 208: /* cmd ::= SHOW CREATE DATABASE db_name */ -{ pCxt->pRootNode = createShowCreateDatabaseStmt(pCxt, &yymsp[0].minor.yy533); } +{ pCxt->pRootNode = createShowCreateDatabaseStmt(pCxt, &yymsp[0].minor.yy361); } break; case 209: /* cmd ::= SHOW CREATE TABLE full_table_name */ -{ pCxt->pRootNode = createShowCreateTableStmt(pCxt, QUERY_NODE_SHOW_CREATE_TABLE_STMT, yymsp[0].minor.yy560); } +{ pCxt->pRootNode = createShowCreateTableStmt(pCxt, QUERY_NODE_SHOW_CREATE_TABLE_STMT, yymsp[0].minor.yy616); } break; case 210: /* cmd ::= SHOW CREATE STABLE full_table_name */ -{ pCxt->pRootNode = createShowCreateTableStmt(pCxt, QUERY_NODE_SHOW_CREATE_STABLE_STMT, yymsp[0].minor.yy560); } +{ pCxt->pRootNode = createShowCreateTableStmt(pCxt, QUERY_NODE_SHOW_CREATE_STABLE_STMT, yymsp[0].minor.yy616); } break; case 211: /* cmd ::= SHOW QUERIES */ { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_QUERIES_STMT); } @@ -3975,7 +4027,7 @@ static YYACTIONTYPE yy_reduce( { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_TRANSACTIONS_STMT); } break; case 221: /* cmd ::= SHOW TABLE DISTRIBUTED full_table_name */ -{ pCxt->pRootNode = createShowTableDistributedStmt(pCxt, yymsp[0].minor.yy560); } +{ pCxt->pRootNode = createShowTableDistributedStmt(pCxt, yymsp[0].minor.yy616); } break; case 222: /* cmd ::= SHOW CONSUMERS */ { pCxt->pRootNode = createShowStmt(pCxt, QUERY_NODE_SHOW_CONSUMERS_STMT); } @@ -3985,154 +4037,154 @@ static YYACTIONTYPE yy_reduce( break; case 224: /* db_name_cond_opt ::= */ case 229: /* from_db_opt ::= */ yytestcase(yyruleno==229); -{ yymsp[1].minor.yy560 = createDefaultDatabaseCondValue(pCxt); } +{ yymsp[1].minor.yy616 = createDefaultDatabaseCondValue(pCxt); } break; case 225: /* db_name_cond_opt ::= db_name NK_DOT */ -{ yylhsminor.yy560 = createValueNode(pCxt, TSDB_DATA_TYPE_BINARY, &yymsp[-1].minor.yy533); } - yymsp[-1].minor.yy560 = yylhsminor.yy560; +{ yylhsminor.yy616 = createValueNode(pCxt, TSDB_DATA_TYPE_BINARY, &yymsp[-1].minor.yy361); } + yymsp[-1].minor.yy616 = yylhsminor.yy616; break; case 226: /* like_pattern_opt ::= */ case 266: /* into_opt ::= */ yytestcase(yyruleno==266); - case 404: /* from_clause_opt ::= */ yytestcase(yyruleno==404); - case 433: /* where_clause_opt ::= */ yytestcase(yyruleno==433); - case 437: /* twindow_clause_opt ::= */ yytestcase(yyruleno==437); - case 442: /* sliding_opt ::= */ yytestcase(yyruleno==442); - case 444: /* fill_opt ::= */ yytestcase(yyruleno==444); - case 456: /* having_clause_opt ::= */ yytestcase(yyruleno==456); - case 458: /* range_opt ::= */ yytestcase(yyruleno==458); - case 460: /* every_opt ::= */ yytestcase(yyruleno==460); - case 470: /* slimit_clause_opt ::= */ yytestcase(yyruleno==470); - case 474: /* limit_clause_opt ::= */ yytestcase(yyruleno==474); -{ yymsp[1].minor.yy560 = NULL; } + case 406: /* from_clause_opt ::= */ yytestcase(yyruleno==406); + case 435: /* where_clause_opt ::= */ yytestcase(yyruleno==435); + case 439: /* twindow_clause_opt ::= */ yytestcase(yyruleno==439); + case 444: /* sliding_opt ::= */ yytestcase(yyruleno==444); + case 446: /* fill_opt ::= */ yytestcase(yyruleno==446); + case 458: /* having_clause_opt ::= */ yytestcase(yyruleno==458); + case 460: /* range_opt ::= */ yytestcase(yyruleno==460); + case 462: /* every_opt ::= */ yytestcase(yyruleno==462); + case 472: /* slimit_clause_opt ::= */ yytestcase(yyruleno==472); + case 476: /* limit_clause_opt ::= */ yytestcase(yyruleno==476); +{ yymsp[1].minor.yy616 = NULL; } break; case 227: /* like_pattern_opt ::= LIKE NK_STRING */ -{ yymsp[-1].minor.yy560 = createValueNode(pCxt, TSDB_DATA_TYPE_BINARY, &yymsp[0].minor.yy0); } +{ yymsp[-1].minor.yy616 = createValueNode(pCxt, TSDB_DATA_TYPE_BINARY, &yymsp[0].minor.yy0); } break; case 228: /* table_name_cond ::= table_name */ -{ yylhsminor.yy560 = createValueNode(pCxt, TSDB_DATA_TYPE_BINARY, &yymsp[0].minor.yy533); } - yymsp[0].minor.yy560 = yylhsminor.yy560; +{ yylhsminor.yy616 = createValueNode(pCxt, TSDB_DATA_TYPE_BINARY, &yymsp[0].minor.yy361); } + yymsp[0].minor.yy616 = yylhsminor.yy616; break; case 230: /* from_db_opt ::= FROM db_name */ -{ yymsp[-1].minor.yy560 = createValueNode(pCxt, TSDB_DATA_TYPE_BINARY, &yymsp[0].minor.yy533); } +{ yymsp[-1].minor.yy616 = createValueNode(pCxt, TSDB_DATA_TYPE_BINARY, &yymsp[0].minor.yy361); } break; case 231: /* cmd ::= CREATE SMA INDEX not_exists_opt index_name ON table_name index_options */ -{ pCxt->pRootNode = createCreateIndexStmt(pCxt, INDEX_TYPE_SMA, yymsp[-4].minor.yy173, &yymsp[-3].minor.yy533, &yymsp[-1].minor.yy533, NULL, yymsp[0].minor.yy560); } +{ pCxt->pRootNode = createCreateIndexStmt(pCxt, INDEX_TYPE_SMA, yymsp[-4].minor.yy151, &yymsp[-3].minor.yy361, &yymsp[-1].minor.yy361, NULL, yymsp[0].minor.yy616); } break; case 232: /* cmd ::= DROP INDEX exists_opt index_name */ -{ pCxt->pRootNode = createDropIndexStmt(pCxt, yymsp[-1].minor.yy173, &yymsp[0].minor.yy533); } +{ pCxt->pRootNode = createDropIndexStmt(pCxt, yymsp[-1].minor.yy151, &yymsp[0].minor.yy361); } break; case 233: /* index_options ::= FUNCTION NK_LP func_list NK_RP INTERVAL NK_LP duration_literal NK_RP sliding_opt sma_stream_opt */ -{ yymsp[-9].minor.yy560 = createIndexOption(pCxt, yymsp[-7].minor.yy712, releaseRawExprNode(pCxt, yymsp[-3].minor.yy560), NULL, yymsp[-1].minor.yy560, yymsp[0].minor.yy560); } +{ yymsp[-9].minor.yy616 = createIndexOption(pCxt, yymsp[-7].minor.yy356, releaseRawExprNode(pCxt, yymsp[-3].minor.yy616), NULL, yymsp[-1].minor.yy616, yymsp[0].minor.yy616); } break; case 234: /* index_options ::= FUNCTION NK_LP func_list NK_RP INTERVAL NK_LP duration_literal NK_COMMA duration_literal NK_RP sliding_opt sma_stream_opt */ -{ yymsp[-11].minor.yy560 = createIndexOption(pCxt, yymsp[-9].minor.yy712, releaseRawExprNode(pCxt, yymsp[-5].minor.yy560), releaseRawExprNode(pCxt, yymsp[-3].minor.yy560), yymsp[-1].minor.yy560, yymsp[0].minor.yy560); } +{ yymsp[-11].minor.yy616 = createIndexOption(pCxt, yymsp[-9].minor.yy356, releaseRawExprNode(pCxt, yymsp[-5].minor.yy616), releaseRawExprNode(pCxt, yymsp[-3].minor.yy616), yymsp[-1].minor.yy616, yymsp[0].minor.yy616); } break; case 237: /* func ::= function_name NK_LP expression_list NK_RP */ -{ yylhsminor.yy560 = createFunctionNode(pCxt, &yymsp[-3].minor.yy533, yymsp[-1].minor.yy712); } - yymsp[-3].minor.yy560 = yylhsminor.yy560; +{ yylhsminor.yy616 = createFunctionNode(pCxt, &yymsp[-3].minor.yy361, yymsp[-1].minor.yy356); } + yymsp[-3].minor.yy616 = yylhsminor.yy616; break; case 238: /* sma_stream_opt ::= */ case 268: /* stream_options ::= */ yytestcase(yyruleno==268); -{ yymsp[1].minor.yy560 = createStreamOptions(pCxt); } +{ yymsp[1].minor.yy616 = createStreamOptions(pCxt); } break; case 239: /* sma_stream_opt ::= stream_options WATERMARK duration_literal */ case 272: /* stream_options ::= stream_options WATERMARK duration_literal */ yytestcase(yyruleno==272); -{ ((SStreamOptions*)yymsp[-2].minor.yy560)->pWatermark = releaseRawExprNode(pCxt, yymsp[0].minor.yy560); yylhsminor.yy560 = yymsp[-2].minor.yy560; } - yymsp[-2].minor.yy560 = yylhsminor.yy560; +{ ((SStreamOptions*)yymsp[-2].minor.yy616)->pWatermark = releaseRawExprNode(pCxt, yymsp[0].minor.yy616); yylhsminor.yy616 = yymsp[-2].minor.yy616; } + yymsp[-2].minor.yy616 = yylhsminor.yy616; break; case 240: /* sma_stream_opt ::= stream_options MAX_DELAY duration_literal */ -{ ((SStreamOptions*)yymsp[-2].minor.yy560)->pDelay = releaseRawExprNode(pCxt, yymsp[0].minor.yy560); yylhsminor.yy560 = yymsp[-2].minor.yy560; } - yymsp[-2].minor.yy560 = yylhsminor.yy560; +{ ((SStreamOptions*)yymsp[-2].minor.yy616)->pDelay = releaseRawExprNode(pCxt, yymsp[0].minor.yy616); yylhsminor.yy616 = yymsp[-2].minor.yy616; } + yymsp[-2].minor.yy616 = yylhsminor.yy616; break; case 241: /* cmd ::= CREATE TOPIC not_exists_opt topic_name AS query_expression */ -{ pCxt->pRootNode = createCreateTopicStmtUseQuery(pCxt, yymsp[-3].minor.yy173, &yymsp[-2].minor.yy533, yymsp[0].minor.yy560); } +{ pCxt->pRootNode = createCreateTopicStmtUseQuery(pCxt, yymsp[-3].minor.yy151, &yymsp[-2].minor.yy361, yymsp[0].minor.yy616); } break; case 242: /* cmd ::= CREATE TOPIC not_exists_opt topic_name AS DATABASE db_name */ -{ pCxt->pRootNode = createCreateTopicStmtUseDb(pCxt, yymsp[-4].minor.yy173, &yymsp[-3].minor.yy533, &yymsp[0].minor.yy533, false); } +{ pCxt->pRootNode = createCreateTopicStmtUseDb(pCxt, yymsp[-4].minor.yy151, &yymsp[-3].minor.yy361, &yymsp[0].minor.yy361, false); } break; case 243: /* cmd ::= CREATE TOPIC not_exists_opt topic_name WITH META AS DATABASE db_name */ -{ pCxt->pRootNode = createCreateTopicStmtUseDb(pCxt, yymsp[-6].minor.yy173, &yymsp[-5].minor.yy533, &yymsp[0].minor.yy533, true); } +{ pCxt->pRootNode = createCreateTopicStmtUseDb(pCxt, yymsp[-6].minor.yy151, &yymsp[-5].minor.yy361, &yymsp[0].minor.yy361, true); } break; case 244: /* cmd ::= CREATE TOPIC not_exists_opt topic_name AS STABLE full_table_name */ -{ pCxt->pRootNode = createCreateTopicStmtUseTable(pCxt, yymsp[-4].minor.yy173, &yymsp[-3].minor.yy533, yymsp[0].minor.yy560, false); } +{ pCxt->pRootNode = createCreateTopicStmtUseTable(pCxt, yymsp[-4].minor.yy151, &yymsp[-3].minor.yy361, yymsp[0].minor.yy616, false); } break; case 245: /* cmd ::= CREATE TOPIC not_exists_opt topic_name WITH META AS STABLE full_table_name */ -{ pCxt->pRootNode = createCreateTopicStmtUseTable(pCxt, yymsp[-6].minor.yy173, &yymsp[-5].minor.yy533, yymsp[0].minor.yy560, true); } +{ pCxt->pRootNode = createCreateTopicStmtUseTable(pCxt, yymsp[-6].minor.yy151, &yymsp[-5].minor.yy361, yymsp[0].minor.yy616, true); } break; case 246: /* cmd ::= DROP TOPIC exists_opt topic_name */ -{ pCxt->pRootNode = createDropTopicStmt(pCxt, yymsp[-1].minor.yy173, &yymsp[0].minor.yy533); } +{ pCxt->pRootNode = createDropTopicStmt(pCxt, yymsp[-1].minor.yy151, &yymsp[0].minor.yy361); } break; case 247: /* cmd ::= DROP CONSUMER GROUP exists_opt cgroup_name ON topic_name */ -{ pCxt->pRootNode = createDropCGroupStmt(pCxt, yymsp[-3].minor.yy173, &yymsp[-2].minor.yy533, &yymsp[0].minor.yy533); } +{ pCxt->pRootNode = createDropCGroupStmt(pCxt, yymsp[-3].minor.yy151, &yymsp[-2].minor.yy361, &yymsp[0].minor.yy361); } break; case 248: /* cmd ::= DESC full_table_name */ case 249: /* cmd ::= DESCRIBE full_table_name */ yytestcase(yyruleno==249); -{ pCxt->pRootNode = createDescribeStmt(pCxt, yymsp[0].minor.yy560); } +{ pCxt->pRootNode = createDescribeStmt(pCxt, yymsp[0].minor.yy616); } break; case 250: /* cmd ::= RESET QUERY CACHE */ { pCxt->pRootNode = createResetQueryCacheStmt(pCxt); } break; case 251: /* cmd ::= EXPLAIN analyze_opt explain_options query_expression */ -{ pCxt->pRootNode = createExplainStmt(pCxt, yymsp[-2].minor.yy173, yymsp[-1].minor.yy560, yymsp[0].minor.yy560); } +{ pCxt->pRootNode = createExplainStmt(pCxt, yymsp[-2].minor.yy151, yymsp[-1].minor.yy616, yymsp[0].minor.yy616); } break; case 253: /* analyze_opt ::= ANALYZE */ case 261: /* agg_func_opt ::= AGGREGATE */ yytestcase(yyruleno==261); - case 424: /* set_quantifier_opt ::= DISTINCT */ yytestcase(yyruleno==424); -{ yymsp[0].minor.yy173 = true; } + case 426: /* set_quantifier_opt ::= DISTINCT */ yytestcase(yyruleno==426); +{ yymsp[0].minor.yy151 = true; } break; case 254: /* explain_options ::= */ -{ yymsp[1].minor.yy560 = createDefaultExplainOptions(pCxt); } +{ yymsp[1].minor.yy616 = createDefaultExplainOptions(pCxt); } break; case 255: /* explain_options ::= explain_options VERBOSE NK_BOOL */ -{ yylhsminor.yy560 = setExplainVerbose(pCxt, yymsp[-2].minor.yy560, &yymsp[0].minor.yy0); } - yymsp[-2].minor.yy560 = yylhsminor.yy560; +{ yylhsminor.yy616 = setExplainVerbose(pCxt, yymsp[-2].minor.yy616, &yymsp[0].minor.yy0); } + yymsp[-2].minor.yy616 = yylhsminor.yy616; break; case 256: /* explain_options ::= explain_options RATIO NK_FLOAT */ -{ yylhsminor.yy560 = setExplainRatio(pCxt, yymsp[-2].minor.yy560, &yymsp[0].minor.yy0); } - yymsp[-2].minor.yy560 = yylhsminor.yy560; +{ yylhsminor.yy616 = setExplainRatio(pCxt, yymsp[-2].minor.yy616, &yymsp[0].minor.yy0); } + yymsp[-2].minor.yy616 = yylhsminor.yy616; break; case 257: /* cmd ::= COMPACT VNODES IN NK_LP integer_list NK_RP */ -{ pCxt->pRootNode = createCompactStmt(pCxt, yymsp[-1].minor.yy712); } +{ pCxt->pRootNode = createCompactStmt(pCxt, yymsp[-1].minor.yy356); } break; case 258: /* cmd ::= CREATE agg_func_opt FUNCTION not_exists_opt function_name AS NK_STRING OUTPUTTYPE type_name bufsize_opt */ -{ pCxt->pRootNode = createCreateFunctionStmt(pCxt, yymsp[-6].minor.yy173, yymsp[-8].minor.yy173, &yymsp[-5].minor.yy533, &yymsp[-3].minor.yy0, yymsp[-1].minor.yy196, yymsp[0].minor.yy424); } +{ pCxt->pRootNode = createCreateFunctionStmt(pCxt, yymsp[-6].minor.yy151, yymsp[-8].minor.yy151, &yymsp[-5].minor.yy361, &yymsp[-3].minor.yy0, yymsp[-1].minor.yy600, yymsp[0].minor.yy734); } break; case 259: /* cmd ::= DROP FUNCTION exists_opt function_name */ -{ pCxt->pRootNode = createDropFunctionStmt(pCxt, yymsp[-1].minor.yy173, &yymsp[0].minor.yy533); } +{ pCxt->pRootNode = createDropFunctionStmt(pCxt, yymsp[-1].minor.yy151, &yymsp[0].minor.yy361); } break; case 262: /* bufsize_opt ::= */ -{ yymsp[1].minor.yy424 = 0; } +{ yymsp[1].minor.yy734 = 0; } break; case 263: /* bufsize_opt ::= BUFSIZE NK_INTEGER */ -{ yymsp[-1].minor.yy424 = taosStr2Int32(yymsp[0].minor.yy0.z, NULL, 10); } +{ yymsp[-1].minor.yy734 = taosStr2Int32(yymsp[0].minor.yy0.z, NULL, 10); } break; case 264: /* cmd ::= CREATE STREAM not_exists_opt stream_name stream_options into_opt AS query_expression */ -{ pCxt->pRootNode = createCreateStreamStmt(pCxt, yymsp[-5].minor.yy173, &yymsp[-4].minor.yy533, yymsp[-2].minor.yy560, yymsp[-3].minor.yy560, yymsp[0].minor.yy560); } +{ pCxt->pRootNode = createCreateStreamStmt(pCxt, yymsp[-5].minor.yy151, &yymsp[-4].minor.yy361, yymsp[-2].minor.yy616, yymsp[-3].minor.yy616, yymsp[0].minor.yy616); } break; case 265: /* cmd ::= DROP STREAM exists_opt stream_name */ -{ pCxt->pRootNode = createDropStreamStmt(pCxt, yymsp[-1].minor.yy173, &yymsp[0].minor.yy533); } +{ pCxt->pRootNode = createDropStreamStmt(pCxt, yymsp[-1].minor.yy151, &yymsp[0].minor.yy361); } break; case 267: /* into_opt ::= INTO full_table_name */ - case 405: /* from_clause_opt ::= FROM table_reference_list */ yytestcase(yyruleno==405); - case 434: /* where_clause_opt ::= WHERE search_condition */ yytestcase(yyruleno==434); - case 457: /* having_clause_opt ::= HAVING search_condition */ yytestcase(yyruleno==457); -{ yymsp[-1].minor.yy560 = yymsp[0].minor.yy560; } + case 407: /* from_clause_opt ::= FROM table_reference_list */ yytestcase(yyruleno==407); + case 436: /* where_clause_opt ::= WHERE search_condition */ yytestcase(yyruleno==436); + case 459: /* having_clause_opt ::= HAVING search_condition */ yytestcase(yyruleno==459); +{ yymsp[-1].minor.yy616 = yymsp[0].minor.yy616; } break; case 269: /* stream_options ::= stream_options TRIGGER AT_ONCE */ -{ ((SStreamOptions*)yymsp[-2].minor.yy560)->triggerType = STREAM_TRIGGER_AT_ONCE; yylhsminor.yy560 = yymsp[-2].minor.yy560; } - yymsp[-2].minor.yy560 = yylhsminor.yy560; +{ ((SStreamOptions*)yymsp[-2].minor.yy616)->triggerType = STREAM_TRIGGER_AT_ONCE; yylhsminor.yy616 = yymsp[-2].minor.yy616; } + yymsp[-2].minor.yy616 = yylhsminor.yy616; break; case 270: /* stream_options ::= stream_options TRIGGER WINDOW_CLOSE */ -{ ((SStreamOptions*)yymsp[-2].minor.yy560)->triggerType = STREAM_TRIGGER_WINDOW_CLOSE; yylhsminor.yy560 = yymsp[-2].minor.yy560; } - yymsp[-2].minor.yy560 = yylhsminor.yy560; +{ ((SStreamOptions*)yymsp[-2].minor.yy616)->triggerType = STREAM_TRIGGER_WINDOW_CLOSE; yylhsminor.yy616 = yymsp[-2].minor.yy616; } + yymsp[-2].minor.yy616 = yylhsminor.yy616; break; case 271: /* stream_options ::= stream_options TRIGGER MAX_DELAY duration_literal */ -{ ((SStreamOptions*)yymsp[-3].minor.yy560)->triggerType = STREAM_TRIGGER_MAX_DELAY; ((SStreamOptions*)yymsp[-3].minor.yy560)->pDelay = releaseRawExprNode(pCxt, yymsp[0].minor.yy560); yylhsminor.yy560 = yymsp[-3].minor.yy560; } - yymsp[-3].minor.yy560 = yylhsminor.yy560; +{ ((SStreamOptions*)yymsp[-3].minor.yy616)->triggerType = STREAM_TRIGGER_MAX_DELAY; ((SStreamOptions*)yymsp[-3].minor.yy616)->pDelay = releaseRawExprNode(pCxt, yymsp[0].minor.yy616); yylhsminor.yy616 = yymsp[-3].minor.yy616; } + yymsp[-3].minor.yy616 = yylhsminor.yy616; break; case 273: /* stream_options ::= stream_options IGNORE EXPIRED */ -{ ((SStreamOptions*)yymsp[-2].minor.yy560)->ignoreExpired = true; yylhsminor.yy560 = yymsp[-2].minor.yy560; } - yymsp[-2].minor.yy560 = yylhsminor.yy560; +{ ((SStreamOptions*)yymsp[-2].minor.yy616)->ignoreExpired = true; yylhsminor.yy616 = yymsp[-2].minor.yy616; } + yymsp[-2].minor.yy616 = yylhsminor.yy616; break; case 274: /* cmd ::= KILL CONNECTION NK_INTEGER */ { pCxt->pRootNode = createKillStmt(pCxt, QUERY_NODE_KILL_CONNECTION_STMT, &yymsp[0].minor.yy0); } @@ -4150,546 +4202,550 @@ static YYACTIONTYPE yy_reduce( { pCxt->pRootNode = createMergeVgroupStmt(pCxt, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0); } break; case 279: /* cmd ::= REDISTRIBUTE VGROUP NK_INTEGER dnode_list */ -{ pCxt->pRootNode = createRedistributeVgroupStmt(pCxt, &yymsp[-1].minor.yy0, yymsp[0].minor.yy712); } +{ pCxt->pRootNode = createRedistributeVgroupStmt(pCxt, &yymsp[-1].minor.yy0, yymsp[0].minor.yy356); } break; case 280: /* cmd ::= SPLIT VGROUP NK_INTEGER */ { pCxt->pRootNode = createSplitVgroupStmt(pCxt, &yymsp[0].minor.yy0); } break; case 281: /* dnode_list ::= DNODE NK_INTEGER */ -{ yymsp[-1].minor.yy712 = createNodeList(pCxt, createValueNode(pCxt, TSDB_DATA_TYPE_BIGINT, &yymsp[0].minor.yy0)); } +{ yymsp[-1].minor.yy356 = createNodeList(pCxt, createValueNode(pCxt, TSDB_DATA_TYPE_BIGINT, &yymsp[0].minor.yy0)); } break; case 283: /* cmd ::= SYNCDB db_name REPLICA */ -{ pCxt->pRootNode = createSyncdbStmt(pCxt, &yymsp[-1].minor.yy533); } +{ pCxt->pRootNode = createSyncdbStmt(pCxt, &yymsp[-1].minor.yy361); } break; case 284: /* cmd ::= DELETE FROM full_table_name where_clause_opt */ -{ pCxt->pRootNode = createDeleteStmt(pCxt, yymsp[-1].minor.yy560, yymsp[0].minor.yy560); } - break; - case 286: /* cmd ::= INSERT INTO full_table_name specific_cols_opt query_expression */ -{ pCxt->pRootNode = createInsertStmt(pCxt, yymsp[-2].minor.yy560, yymsp[-1].minor.yy712, yymsp[0].minor.yy560); } - break; - case 287: /* literal ::= NK_INTEGER */ -{ yylhsminor.yy560 = createRawExprNode(pCxt, &yymsp[0].minor.yy0, createValueNode(pCxt, TSDB_DATA_TYPE_BIGINT, &yymsp[0].minor.yy0)); } - yymsp[0].minor.yy560 = yylhsminor.yy560; - break; - case 288: /* literal ::= NK_FLOAT */ -{ yylhsminor.yy560 = createRawExprNode(pCxt, &yymsp[0].minor.yy0, createValueNode(pCxt, TSDB_DATA_TYPE_DOUBLE, &yymsp[0].minor.yy0)); } - yymsp[0].minor.yy560 = yylhsminor.yy560; - break; - case 289: /* literal ::= NK_STRING */ -{ yylhsminor.yy560 = createRawExprNode(pCxt, &yymsp[0].minor.yy0, createValueNode(pCxt, TSDB_DATA_TYPE_BINARY, &yymsp[0].minor.yy0)); } - yymsp[0].minor.yy560 = yylhsminor.yy560; - break; - case 290: /* literal ::= NK_BOOL */ -{ yylhsminor.yy560 = createRawExprNode(pCxt, &yymsp[0].minor.yy0, createValueNode(pCxt, TSDB_DATA_TYPE_BOOL, &yymsp[0].minor.yy0)); } - yymsp[0].minor.yy560 = yylhsminor.yy560; - break; - case 291: /* literal ::= TIMESTAMP NK_STRING */ -{ yylhsminor.yy560 = createRawExprNodeExt(pCxt, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0, createValueNode(pCxt, TSDB_DATA_TYPE_TIMESTAMP, &yymsp[0].minor.yy0)); } - yymsp[-1].minor.yy560 = yylhsminor.yy560; - break; - case 292: /* literal ::= duration_literal */ - case 302: /* signed_literal ::= signed */ yytestcase(yyruleno==302); - case 323: /* expression ::= literal */ yytestcase(yyruleno==323); - case 324: /* expression ::= pseudo_column */ yytestcase(yyruleno==324); - case 325: /* expression ::= column_reference */ yytestcase(yyruleno==325); - case 326: /* expression ::= function_expression */ yytestcase(yyruleno==326); - case 327: /* expression ::= subquery */ yytestcase(yyruleno==327); - case 354: /* function_expression ::= literal_func */ yytestcase(yyruleno==354); - case 396: /* boolean_value_expression ::= boolean_primary */ yytestcase(yyruleno==396); - case 400: /* boolean_primary ::= predicate */ yytestcase(yyruleno==400); - case 402: /* common_expression ::= expression */ yytestcase(yyruleno==402); - case 403: /* common_expression ::= boolean_value_expression */ yytestcase(yyruleno==403); - case 406: /* table_reference_list ::= table_reference */ yytestcase(yyruleno==406); - case 408: /* table_reference ::= table_primary */ yytestcase(yyruleno==408); - case 409: /* table_reference ::= joined_table */ yytestcase(yyruleno==409); - case 413: /* table_primary ::= parenthesized_joined_table */ yytestcase(yyruleno==413); - case 463: /* query_expression_body ::= query_primary */ yytestcase(yyruleno==463); - case 466: /* query_primary ::= query_specification */ yytestcase(yyruleno==466); -{ yylhsminor.yy560 = yymsp[0].minor.yy560; } - yymsp[0].minor.yy560 = yylhsminor.yy560; - break; - case 293: /* literal ::= NULL */ -{ yylhsminor.yy560 = createRawExprNode(pCxt, &yymsp[0].minor.yy0, createValueNode(pCxt, TSDB_DATA_TYPE_NULL, &yymsp[0].minor.yy0)); } - yymsp[0].minor.yy560 = yylhsminor.yy560; - break; - case 294: /* literal ::= NK_QUESTION */ -{ yylhsminor.yy560 = createRawExprNode(pCxt, &yymsp[0].minor.yy0, createPlaceholderValueNode(pCxt, &yymsp[0].minor.yy0)); } - yymsp[0].minor.yy560 = yylhsminor.yy560; - break; - case 295: /* duration_literal ::= NK_VARIABLE */ -{ yylhsminor.yy560 = createRawExprNode(pCxt, &yymsp[0].minor.yy0, createDurationValueNode(pCxt, &yymsp[0].minor.yy0)); } - yymsp[0].minor.yy560 = yylhsminor.yy560; - break; - case 296: /* signed ::= NK_INTEGER */ -{ yylhsminor.yy560 = createValueNode(pCxt, TSDB_DATA_TYPE_BIGINT, &yymsp[0].minor.yy0); } - yymsp[0].minor.yy560 = yylhsminor.yy560; - break; - case 297: /* signed ::= NK_PLUS NK_INTEGER */ -{ yymsp[-1].minor.yy560 = createValueNode(pCxt, TSDB_DATA_TYPE_BIGINT, &yymsp[0].minor.yy0); } - break; - case 298: /* signed ::= NK_MINUS NK_INTEGER */ +{ pCxt->pRootNode = createDeleteStmt(pCxt, yymsp[-1].minor.yy616, yymsp[0].minor.yy616); } + break; + case 286: /* cmd ::= INSERT INTO full_table_name NK_LP col_name_list NK_RP query_expression */ +{ pCxt->pRootNode = createInsertStmt(pCxt, yymsp[-4].minor.yy616, yymsp[-2].minor.yy356, yymsp[0].minor.yy616); } + break; + case 287: /* cmd ::= INSERT INTO full_table_name query_expression */ +{ pCxt->pRootNode = createInsertStmt(pCxt, yymsp[-1].minor.yy616, NULL, yymsp[0].minor.yy616); } + break; + case 288: /* literal ::= NK_INTEGER */ +{ yylhsminor.yy616 = createRawExprNode(pCxt, &yymsp[0].minor.yy0, createValueNode(pCxt, TSDB_DATA_TYPE_BIGINT, &yymsp[0].minor.yy0)); } + yymsp[0].minor.yy616 = yylhsminor.yy616; + break; + case 289: /* literal ::= NK_FLOAT */ +{ yylhsminor.yy616 = createRawExprNode(pCxt, &yymsp[0].minor.yy0, createValueNode(pCxt, TSDB_DATA_TYPE_DOUBLE, &yymsp[0].minor.yy0)); } + yymsp[0].minor.yy616 = yylhsminor.yy616; + break; + case 290: /* literal ::= NK_STRING */ +{ yylhsminor.yy616 = createRawExprNode(pCxt, &yymsp[0].minor.yy0, createValueNode(pCxt, TSDB_DATA_TYPE_BINARY, &yymsp[0].minor.yy0)); } + yymsp[0].minor.yy616 = yylhsminor.yy616; + break; + case 291: /* literal ::= NK_BOOL */ +{ yylhsminor.yy616 = createRawExprNode(pCxt, &yymsp[0].minor.yy0, createValueNode(pCxt, TSDB_DATA_TYPE_BOOL, &yymsp[0].minor.yy0)); } + yymsp[0].minor.yy616 = yylhsminor.yy616; + break; + case 292: /* literal ::= TIMESTAMP NK_STRING */ +{ yylhsminor.yy616 = createRawExprNodeExt(pCxt, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0, createValueNode(pCxt, TSDB_DATA_TYPE_TIMESTAMP, &yymsp[0].minor.yy0)); } + yymsp[-1].minor.yy616 = yylhsminor.yy616; + break; + case 293: /* literal ::= duration_literal */ + case 303: /* signed_literal ::= signed */ yytestcase(yyruleno==303); + case 324: /* expression ::= literal */ yytestcase(yyruleno==324); + case 325: /* expression ::= pseudo_column */ yytestcase(yyruleno==325); + case 326: /* expression ::= column_reference */ yytestcase(yyruleno==326); + case 327: /* expression ::= function_expression */ yytestcase(yyruleno==327); + case 328: /* expression ::= subquery */ yytestcase(yyruleno==328); + case 356: /* function_expression ::= literal_func */ yytestcase(yyruleno==356); + case 398: /* boolean_value_expression ::= boolean_primary */ yytestcase(yyruleno==398); + case 402: /* boolean_primary ::= predicate */ yytestcase(yyruleno==402); + case 404: /* common_expression ::= expression */ yytestcase(yyruleno==404); + case 405: /* common_expression ::= boolean_value_expression */ yytestcase(yyruleno==405); + case 408: /* table_reference_list ::= table_reference */ yytestcase(yyruleno==408); + case 410: /* table_reference ::= table_primary */ yytestcase(yyruleno==410); + case 411: /* table_reference ::= joined_table */ yytestcase(yyruleno==411); + case 415: /* table_primary ::= parenthesized_joined_table */ yytestcase(yyruleno==415); + case 465: /* query_expression_body ::= query_primary */ yytestcase(yyruleno==465); + case 468: /* query_primary ::= query_specification */ yytestcase(yyruleno==468); +{ yylhsminor.yy616 = yymsp[0].minor.yy616; } + yymsp[0].minor.yy616 = yylhsminor.yy616; + break; + case 294: /* literal ::= NULL */ +{ yylhsminor.yy616 = createRawExprNode(pCxt, &yymsp[0].minor.yy0, createValueNode(pCxt, TSDB_DATA_TYPE_NULL, &yymsp[0].minor.yy0)); } + yymsp[0].minor.yy616 = yylhsminor.yy616; + break; + case 295: /* literal ::= NK_QUESTION */ +{ yylhsminor.yy616 = createRawExprNode(pCxt, &yymsp[0].minor.yy0, createPlaceholderValueNode(pCxt, &yymsp[0].minor.yy0)); } + yymsp[0].minor.yy616 = yylhsminor.yy616; + break; + case 296: /* duration_literal ::= NK_VARIABLE */ +{ yylhsminor.yy616 = createRawExprNode(pCxt, &yymsp[0].minor.yy0, createDurationValueNode(pCxt, &yymsp[0].minor.yy0)); } + yymsp[0].minor.yy616 = yylhsminor.yy616; + break; + case 297: /* signed ::= NK_INTEGER */ +{ yylhsminor.yy616 = createValueNode(pCxt, TSDB_DATA_TYPE_BIGINT, &yymsp[0].minor.yy0); } + yymsp[0].minor.yy616 = yylhsminor.yy616; + break; + case 298: /* signed ::= NK_PLUS NK_INTEGER */ +{ yymsp[-1].minor.yy616 = createValueNode(pCxt, TSDB_DATA_TYPE_BIGINT, &yymsp[0].minor.yy0); } + break; + case 299: /* signed ::= NK_MINUS NK_INTEGER */ { SToken t = yymsp[-1].minor.yy0; t.n = (yymsp[0].minor.yy0.z + yymsp[0].minor.yy0.n) - yymsp[-1].minor.yy0.z; - yylhsminor.yy560 = createValueNode(pCxt, TSDB_DATA_TYPE_BIGINT, &t); + yylhsminor.yy616 = createValueNode(pCxt, TSDB_DATA_TYPE_BIGINT, &t); } - yymsp[-1].minor.yy560 = yylhsminor.yy560; + yymsp[-1].minor.yy616 = yylhsminor.yy616; break; - case 299: /* signed ::= NK_FLOAT */ -{ yylhsminor.yy560 = createValueNode(pCxt, TSDB_DATA_TYPE_DOUBLE, &yymsp[0].minor.yy0); } - yymsp[0].minor.yy560 = yylhsminor.yy560; + case 300: /* signed ::= NK_FLOAT */ +{ yylhsminor.yy616 = createValueNode(pCxt, TSDB_DATA_TYPE_DOUBLE, &yymsp[0].minor.yy0); } + yymsp[0].minor.yy616 = yylhsminor.yy616; break; - case 300: /* signed ::= NK_PLUS NK_FLOAT */ -{ yymsp[-1].minor.yy560 = createValueNode(pCxt, TSDB_DATA_TYPE_DOUBLE, &yymsp[0].minor.yy0); } + case 301: /* signed ::= NK_PLUS NK_FLOAT */ +{ yymsp[-1].minor.yy616 = createValueNode(pCxt, TSDB_DATA_TYPE_DOUBLE, &yymsp[0].minor.yy0); } break; - case 301: /* signed ::= NK_MINUS NK_FLOAT */ + case 302: /* signed ::= NK_MINUS NK_FLOAT */ { SToken t = yymsp[-1].minor.yy0; t.n = (yymsp[0].minor.yy0.z + yymsp[0].minor.yy0.n) - yymsp[-1].minor.yy0.z; - yylhsminor.yy560 = createValueNode(pCxt, TSDB_DATA_TYPE_DOUBLE, &t); + yylhsminor.yy616 = createValueNode(pCxt, TSDB_DATA_TYPE_DOUBLE, &t); } - yymsp[-1].minor.yy560 = yylhsminor.yy560; + yymsp[-1].minor.yy616 = yylhsminor.yy616; break; - case 303: /* signed_literal ::= NK_STRING */ -{ yylhsminor.yy560 = createValueNode(pCxt, TSDB_DATA_TYPE_BINARY, &yymsp[0].minor.yy0); } - yymsp[0].minor.yy560 = yylhsminor.yy560; + case 304: /* signed_literal ::= NK_STRING */ +{ yylhsminor.yy616 = createValueNode(pCxt, TSDB_DATA_TYPE_BINARY, &yymsp[0].minor.yy0); } + yymsp[0].minor.yy616 = yylhsminor.yy616; break; - case 304: /* signed_literal ::= NK_BOOL */ -{ yylhsminor.yy560 = createValueNode(pCxt, TSDB_DATA_TYPE_BOOL, &yymsp[0].minor.yy0); } - yymsp[0].minor.yy560 = yylhsminor.yy560; + case 305: /* signed_literal ::= NK_BOOL */ +{ yylhsminor.yy616 = createValueNode(pCxt, TSDB_DATA_TYPE_BOOL, &yymsp[0].minor.yy0); } + yymsp[0].minor.yy616 = yylhsminor.yy616; break; - case 305: /* signed_literal ::= TIMESTAMP NK_STRING */ -{ yymsp[-1].minor.yy560 = createValueNode(pCxt, TSDB_DATA_TYPE_TIMESTAMP, &yymsp[0].minor.yy0); } + case 306: /* signed_literal ::= TIMESTAMP NK_STRING */ +{ yymsp[-1].minor.yy616 = createValueNode(pCxt, TSDB_DATA_TYPE_TIMESTAMP, &yymsp[0].minor.yy0); } break; - case 306: /* signed_literal ::= duration_literal */ - case 308: /* signed_literal ::= literal_func */ yytestcase(yyruleno==308); - case 374: /* star_func_para ::= expression */ yytestcase(yyruleno==374); - case 429: /* select_item ::= common_expression */ yytestcase(yyruleno==429); - case 479: /* search_condition ::= common_expression */ yytestcase(yyruleno==479); -{ yylhsminor.yy560 = releaseRawExprNode(pCxt, yymsp[0].minor.yy560); } - yymsp[0].minor.yy560 = yylhsminor.yy560; + case 307: /* signed_literal ::= duration_literal */ + case 309: /* signed_literal ::= literal_func */ yytestcase(yyruleno==309); + case 376: /* star_func_para ::= expression */ yytestcase(yyruleno==376); + case 431: /* select_item ::= common_expression */ yytestcase(yyruleno==431); + case 481: /* search_condition ::= common_expression */ yytestcase(yyruleno==481); +{ yylhsminor.yy616 = releaseRawExprNode(pCxt, yymsp[0].minor.yy616); } + yymsp[0].minor.yy616 = yylhsminor.yy616; break; - case 307: /* signed_literal ::= NULL */ -{ yylhsminor.yy560 = createValueNode(pCxt, TSDB_DATA_TYPE_NULL, &yymsp[0].minor.yy0); } - yymsp[0].minor.yy560 = yylhsminor.yy560; + case 308: /* signed_literal ::= NULL */ +{ yylhsminor.yy616 = createValueNode(pCxt, TSDB_DATA_TYPE_NULL, &yymsp[0].minor.yy0); } + yymsp[0].minor.yy616 = yylhsminor.yy616; break; - case 309: /* signed_literal ::= NK_QUESTION */ -{ yylhsminor.yy560 = createPlaceholderValueNode(pCxt, &yymsp[0].minor.yy0); } - yymsp[0].minor.yy560 = yylhsminor.yy560; + case 310: /* signed_literal ::= NK_QUESTION */ +{ yylhsminor.yy616 = createPlaceholderValueNode(pCxt, &yymsp[0].minor.yy0); } + yymsp[0].minor.yy616 = yylhsminor.yy616; break; - case 328: /* expression ::= NK_LP expression NK_RP */ - case 401: /* boolean_primary ::= NK_LP boolean_value_expression NK_RP */ yytestcase(yyruleno==401); -{ yylhsminor.yy560 = createRawExprNodeExt(pCxt, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0, releaseRawExprNode(pCxt, yymsp[-1].minor.yy560)); } - yymsp[-2].minor.yy560 = yylhsminor.yy560; + case 329: /* expression ::= NK_LP expression NK_RP */ + case 403: /* boolean_primary ::= NK_LP boolean_value_expression NK_RP */ yytestcase(yyruleno==403); +{ yylhsminor.yy616 = createRawExprNodeExt(pCxt, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0, releaseRawExprNode(pCxt, yymsp[-1].minor.yy616)); } + yymsp[-2].minor.yy616 = yylhsminor.yy616; break; - case 329: /* expression ::= NK_PLUS expression */ + case 330: /* expression ::= NK_PLUS expression */ { - SToken t = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy560); - yylhsminor.yy560 = createRawExprNodeExt(pCxt, &yymsp[-1].minor.yy0, &t, releaseRawExprNode(pCxt, yymsp[0].minor.yy560)); + SToken t = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy616); + yylhsminor.yy616 = createRawExprNodeExt(pCxt, &yymsp[-1].minor.yy0, &t, releaseRawExprNode(pCxt, yymsp[0].minor.yy616)); } - yymsp[-1].minor.yy560 = yylhsminor.yy560; + yymsp[-1].minor.yy616 = yylhsminor.yy616; break; - case 330: /* expression ::= NK_MINUS expression */ + case 331: /* expression ::= NK_MINUS expression */ { - SToken t = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy560); - yylhsminor.yy560 = createRawExprNodeExt(pCxt, &yymsp[-1].minor.yy0, &t, createOperatorNode(pCxt, OP_TYPE_MINUS, releaseRawExprNode(pCxt, yymsp[0].minor.yy560), NULL)); + SToken t = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy616); + yylhsminor.yy616 = createRawExprNodeExt(pCxt, &yymsp[-1].minor.yy0, &t, createOperatorNode(pCxt, OP_TYPE_MINUS, releaseRawExprNode(pCxt, yymsp[0].minor.yy616), NULL)); } - yymsp[-1].minor.yy560 = yylhsminor.yy560; + yymsp[-1].minor.yy616 = yylhsminor.yy616; break; - case 331: /* expression ::= expression NK_PLUS expression */ + case 332: /* expression ::= expression NK_PLUS expression */ { - SToken s = getTokenFromRawExprNode(pCxt, yymsp[-2].minor.yy560); - SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy560); - yylhsminor.yy560 = createRawExprNodeExt(pCxt, &s, &e, createOperatorNode(pCxt, OP_TYPE_ADD, releaseRawExprNode(pCxt, yymsp[-2].minor.yy560), releaseRawExprNode(pCxt, yymsp[0].minor.yy560))); + SToken s = getTokenFromRawExprNode(pCxt, yymsp[-2].minor.yy616); + SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy616); + yylhsminor.yy616 = createRawExprNodeExt(pCxt, &s, &e, createOperatorNode(pCxt, OP_TYPE_ADD, releaseRawExprNode(pCxt, yymsp[-2].minor.yy616), releaseRawExprNode(pCxt, yymsp[0].minor.yy616))); } - yymsp[-2].minor.yy560 = yylhsminor.yy560; + yymsp[-2].minor.yy616 = yylhsminor.yy616; break; - case 332: /* expression ::= expression NK_MINUS expression */ + case 333: /* expression ::= expression NK_MINUS expression */ { - SToken s = getTokenFromRawExprNode(pCxt, yymsp[-2].minor.yy560); - SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy560); - yylhsminor.yy560 = createRawExprNodeExt(pCxt, &s, &e, createOperatorNode(pCxt, OP_TYPE_SUB, releaseRawExprNode(pCxt, yymsp[-2].minor.yy560), releaseRawExprNode(pCxt, yymsp[0].minor.yy560))); + SToken s = getTokenFromRawExprNode(pCxt, yymsp[-2].minor.yy616); + SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy616); + yylhsminor.yy616 = createRawExprNodeExt(pCxt, &s, &e, createOperatorNode(pCxt, OP_TYPE_SUB, releaseRawExprNode(pCxt, yymsp[-2].minor.yy616), releaseRawExprNode(pCxt, yymsp[0].minor.yy616))); } - yymsp[-2].minor.yy560 = yylhsminor.yy560; + yymsp[-2].minor.yy616 = yylhsminor.yy616; break; - case 333: /* expression ::= expression NK_STAR expression */ + case 334: /* expression ::= expression NK_STAR expression */ { - SToken s = getTokenFromRawExprNode(pCxt, yymsp[-2].minor.yy560); - SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy560); - yylhsminor.yy560 = createRawExprNodeExt(pCxt, &s, &e, createOperatorNode(pCxt, OP_TYPE_MULTI, releaseRawExprNode(pCxt, yymsp[-2].minor.yy560), releaseRawExprNode(pCxt, yymsp[0].minor.yy560))); + SToken s = getTokenFromRawExprNode(pCxt, yymsp[-2].minor.yy616); + SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy616); + yylhsminor.yy616 = createRawExprNodeExt(pCxt, &s, &e, createOperatorNode(pCxt, OP_TYPE_MULTI, releaseRawExprNode(pCxt, yymsp[-2].minor.yy616), releaseRawExprNode(pCxt, yymsp[0].minor.yy616))); } - yymsp[-2].minor.yy560 = yylhsminor.yy560; + yymsp[-2].minor.yy616 = yylhsminor.yy616; break; - case 334: /* expression ::= expression NK_SLASH expression */ + case 335: /* expression ::= expression NK_SLASH expression */ { - SToken s = getTokenFromRawExprNode(pCxt, yymsp[-2].minor.yy560); - SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy560); - yylhsminor.yy560 = createRawExprNodeExt(pCxt, &s, &e, createOperatorNode(pCxt, OP_TYPE_DIV, releaseRawExprNode(pCxt, yymsp[-2].minor.yy560), releaseRawExprNode(pCxt, yymsp[0].minor.yy560))); + SToken s = getTokenFromRawExprNode(pCxt, yymsp[-2].minor.yy616); + SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy616); + yylhsminor.yy616 = createRawExprNodeExt(pCxt, &s, &e, createOperatorNode(pCxt, OP_TYPE_DIV, releaseRawExprNode(pCxt, yymsp[-2].minor.yy616), releaseRawExprNode(pCxt, yymsp[0].minor.yy616))); } - yymsp[-2].minor.yy560 = yylhsminor.yy560; + yymsp[-2].minor.yy616 = yylhsminor.yy616; break; - case 335: /* expression ::= expression NK_REM expression */ + case 336: /* expression ::= expression NK_REM expression */ { - SToken s = getTokenFromRawExprNode(pCxt, yymsp[-2].minor.yy560); - SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy560); - yylhsminor.yy560 = createRawExprNodeExt(pCxt, &s, &e, createOperatorNode(pCxt, OP_TYPE_REM, releaseRawExprNode(pCxt, yymsp[-2].minor.yy560), releaseRawExprNode(pCxt, yymsp[0].minor.yy560))); + SToken s = getTokenFromRawExprNode(pCxt, yymsp[-2].minor.yy616); + SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy616); + yylhsminor.yy616 = createRawExprNodeExt(pCxt, &s, &e, createOperatorNode(pCxt, OP_TYPE_REM, releaseRawExprNode(pCxt, yymsp[-2].minor.yy616), releaseRawExprNode(pCxt, yymsp[0].minor.yy616))); } - yymsp[-2].minor.yy560 = yylhsminor.yy560; + yymsp[-2].minor.yy616 = yylhsminor.yy616; break; - case 336: /* expression ::= column_reference NK_ARROW NK_STRING */ + case 337: /* expression ::= column_reference NK_ARROW NK_STRING */ { - SToken s = getTokenFromRawExprNode(pCxt, yymsp[-2].minor.yy560); - yylhsminor.yy560 = createRawExprNodeExt(pCxt, &s, &yymsp[0].minor.yy0, createOperatorNode(pCxt, OP_TYPE_JSON_GET_VALUE, releaseRawExprNode(pCxt, yymsp[-2].minor.yy560), createValueNode(pCxt, TSDB_DATA_TYPE_BINARY, &yymsp[0].minor.yy0))); + SToken s = getTokenFromRawExprNode(pCxt, yymsp[-2].minor.yy616); + yylhsminor.yy616 = createRawExprNodeExt(pCxt, &s, &yymsp[0].minor.yy0, createOperatorNode(pCxt, OP_TYPE_JSON_GET_VALUE, releaseRawExprNode(pCxt, yymsp[-2].minor.yy616), createValueNode(pCxt, TSDB_DATA_TYPE_BINARY, &yymsp[0].minor.yy0))); } - yymsp[-2].minor.yy560 = yylhsminor.yy560; + yymsp[-2].minor.yy616 = yylhsminor.yy616; break; - case 337: /* expression ::= expression NK_BITAND expression */ + case 338: /* expression ::= expression NK_BITAND expression */ { - SToken s = getTokenFromRawExprNode(pCxt, yymsp[-2].minor.yy560); - SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy560); - yylhsminor.yy560 = createRawExprNodeExt(pCxt, &s, &e, createOperatorNode(pCxt, OP_TYPE_BIT_AND, releaseRawExprNode(pCxt, yymsp[-2].minor.yy560), releaseRawExprNode(pCxt, yymsp[0].minor.yy560))); + SToken s = getTokenFromRawExprNode(pCxt, yymsp[-2].minor.yy616); + SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy616); + yylhsminor.yy616 = createRawExprNodeExt(pCxt, &s, &e, createOperatorNode(pCxt, OP_TYPE_BIT_AND, releaseRawExprNode(pCxt, yymsp[-2].minor.yy616), releaseRawExprNode(pCxt, yymsp[0].minor.yy616))); } - yymsp[-2].minor.yy560 = yylhsminor.yy560; + yymsp[-2].minor.yy616 = yylhsminor.yy616; break; - case 338: /* expression ::= expression NK_BITOR expression */ + case 339: /* expression ::= expression NK_BITOR expression */ { - SToken s = getTokenFromRawExprNode(pCxt, yymsp[-2].minor.yy560); - SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy560); - yylhsminor.yy560 = createRawExprNodeExt(pCxt, &s, &e, createOperatorNode(pCxt, OP_TYPE_BIT_OR, releaseRawExprNode(pCxt, yymsp[-2].minor.yy560), releaseRawExprNode(pCxt, yymsp[0].minor.yy560))); + SToken s = getTokenFromRawExprNode(pCxt, yymsp[-2].minor.yy616); + SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy616); + yylhsminor.yy616 = createRawExprNodeExt(pCxt, &s, &e, createOperatorNode(pCxt, OP_TYPE_BIT_OR, releaseRawExprNode(pCxt, yymsp[-2].minor.yy616), releaseRawExprNode(pCxt, yymsp[0].minor.yy616))); } - yymsp[-2].minor.yy560 = yylhsminor.yy560; - break; - case 341: /* column_reference ::= column_name */ -{ yylhsminor.yy560 = createRawExprNode(pCxt, &yymsp[0].minor.yy533, createColumnNode(pCxt, NULL, &yymsp[0].minor.yy533)); } - yymsp[0].minor.yy560 = yylhsminor.yy560; - break; - case 342: /* column_reference ::= table_name NK_DOT column_name */ -{ yylhsminor.yy560 = createRawExprNodeExt(pCxt, &yymsp[-2].minor.yy533, &yymsp[0].minor.yy533, createColumnNode(pCxt, &yymsp[-2].minor.yy533, &yymsp[0].minor.yy533)); } - yymsp[-2].minor.yy560 = yylhsminor.yy560; - break; - case 343: /* pseudo_column ::= ROWTS */ - case 344: /* pseudo_column ::= TBNAME */ yytestcase(yyruleno==344); - case 346: /* pseudo_column ::= QSTARTTS */ yytestcase(yyruleno==346); - case 347: /* pseudo_column ::= QENDTS */ yytestcase(yyruleno==347); - case 348: /* pseudo_column ::= WSTARTTS */ yytestcase(yyruleno==348); - case 349: /* pseudo_column ::= WENDTS */ yytestcase(yyruleno==349); - case 350: /* pseudo_column ::= WDURATION */ yytestcase(yyruleno==350); - case 356: /* literal_func ::= NOW */ yytestcase(yyruleno==356); -{ yylhsminor.yy560 = createRawExprNode(pCxt, &yymsp[0].minor.yy0, createFunctionNode(pCxt, &yymsp[0].minor.yy0, NULL)); } - yymsp[0].minor.yy560 = yylhsminor.yy560; - break; - case 345: /* pseudo_column ::= table_name NK_DOT TBNAME */ -{ yylhsminor.yy560 = createRawExprNodeExt(pCxt, &yymsp[-2].minor.yy533, &yymsp[0].minor.yy0, createFunctionNode(pCxt, &yymsp[0].minor.yy0, createNodeList(pCxt, createValueNode(pCxt, TSDB_DATA_TYPE_BINARY, &yymsp[-2].minor.yy533)))); } - yymsp[-2].minor.yy560 = yylhsminor.yy560; - break; - case 351: /* function_expression ::= function_name NK_LP expression_list NK_RP */ - case 352: /* function_expression ::= star_func NK_LP star_func_para_list NK_RP */ yytestcase(yyruleno==352); -{ yylhsminor.yy560 = createRawExprNodeExt(pCxt, &yymsp[-3].minor.yy533, &yymsp[0].minor.yy0, createFunctionNode(pCxt, &yymsp[-3].minor.yy533, yymsp[-1].minor.yy712)); } - yymsp[-3].minor.yy560 = yylhsminor.yy560; - break; - case 353: /* function_expression ::= CAST NK_LP expression AS type_name NK_RP */ -{ yylhsminor.yy560 = createRawExprNodeExt(pCxt, &yymsp[-5].minor.yy0, &yymsp[0].minor.yy0, createCastFunctionNode(pCxt, releaseRawExprNode(pCxt, yymsp[-3].minor.yy560), yymsp[-1].minor.yy196)); } - yymsp[-5].minor.yy560 = yylhsminor.yy560; - break; - case 355: /* literal_func ::= noarg_func NK_LP NK_RP */ -{ yylhsminor.yy560 = createRawExprNodeExt(pCxt, &yymsp[-2].minor.yy533, &yymsp[0].minor.yy0, createFunctionNode(pCxt, &yymsp[-2].minor.yy533, NULL)); } - yymsp[-2].minor.yy560 = yylhsminor.yy560; - break; - case 370: /* star_func_para_list ::= NK_STAR */ -{ yylhsminor.yy712 = createNodeList(pCxt, createColumnNode(pCxt, NULL, &yymsp[0].minor.yy0)); } - yymsp[0].minor.yy712 = yylhsminor.yy712; - break; - case 375: /* star_func_para ::= table_name NK_DOT NK_STAR */ - case 432: /* select_item ::= table_name NK_DOT NK_STAR */ yytestcase(yyruleno==432); -{ yylhsminor.yy560 = createColumnNode(pCxt, &yymsp[-2].minor.yy533, &yymsp[0].minor.yy0); } - yymsp[-2].minor.yy560 = yylhsminor.yy560; - break; - case 376: /* predicate ::= expression compare_op expression */ - case 381: /* predicate ::= expression in_op in_predicate_value */ yytestcase(yyruleno==381); + yymsp[-2].minor.yy616 = yylhsminor.yy616; + break; + case 342: /* column_reference ::= column_name */ +{ yylhsminor.yy616 = createRawExprNode(pCxt, &yymsp[0].minor.yy361, createColumnNode(pCxt, NULL, &yymsp[0].minor.yy361)); } + yymsp[0].minor.yy616 = yylhsminor.yy616; + break; + case 343: /* column_reference ::= table_name NK_DOT column_name */ +{ yylhsminor.yy616 = createRawExprNodeExt(pCxt, &yymsp[-2].minor.yy361, &yymsp[0].minor.yy361, createColumnNode(pCxt, &yymsp[-2].minor.yy361, &yymsp[0].minor.yy361)); } + yymsp[-2].minor.yy616 = yylhsminor.yy616; + break; + case 344: /* pseudo_column ::= ROWTS */ + case 345: /* pseudo_column ::= TBNAME */ yytestcase(yyruleno==345); + case 347: /* pseudo_column ::= QSTART */ yytestcase(yyruleno==347); + case 348: /* pseudo_column ::= QEND */ yytestcase(yyruleno==348); + case 349: /* pseudo_column ::= QDURATION */ yytestcase(yyruleno==349); + case 350: /* pseudo_column ::= WSTART */ yytestcase(yyruleno==350); + case 351: /* pseudo_column ::= WEND */ yytestcase(yyruleno==351); + case 352: /* pseudo_column ::= WDURATION */ yytestcase(yyruleno==352); + case 358: /* literal_func ::= NOW */ yytestcase(yyruleno==358); +{ yylhsminor.yy616 = createRawExprNode(pCxt, &yymsp[0].minor.yy0, createFunctionNode(pCxt, &yymsp[0].minor.yy0, NULL)); } + yymsp[0].minor.yy616 = yylhsminor.yy616; + break; + case 346: /* pseudo_column ::= table_name NK_DOT TBNAME */ +{ yylhsminor.yy616 = createRawExprNodeExt(pCxt, &yymsp[-2].minor.yy361, &yymsp[0].minor.yy0, createFunctionNode(pCxt, &yymsp[0].minor.yy0, createNodeList(pCxt, createValueNode(pCxt, TSDB_DATA_TYPE_BINARY, &yymsp[-2].minor.yy361)))); } + yymsp[-2].minor.yy616 = yylhsminor.yy616; + break; + case 353: /* function_expression ::= function_name NK_LP expression_list NK_RP */ + case 354: /* function_expression ::= star_func NK_LP star_func_para_list NK_RP */ yytestcase(yyruleno==354); +{ yylhsminor.yy616 = createRawExprNodeExt(pCxt, &yymsp[-3].minor.yy361, &yymsp[0].minor.yy0, createFunctionNode(pCxt, &yymsp[-3].minor.yy361, yymsp[-1].minor.yy356)); } + yymsp[-3].minor.yy616 = yylhsminor.yy616; + break; + case 355: /* function_expression ::= CAST NK_LP expression AS type_name NK_RP */ +{ yylhsminor.yy616 = createRawExprNodeExt(pCxt, &yymsp[-5].minor.yy0, &yymsp[0].minor.yy0, createCastFunctionNode(pCxt, releaseRawExprNode(pCxt, yymsp[-3].minor.yy616), yymsp[-1].minor.yy600)); } + yymsp[-5].minor.yy616 = yylhsminor.yy616; + break; + case 357: /* literal_func ::= noarg_func NK_LP NK_RP */ +{ yylhsminor.yy616 = createRawExprNodeExt(pCxt, &yymsp[-2].minor.yy361, &yymsp[0].minor.yy0, createFunctionNode(pCxt, &yymsp[-2].minor.yy361, NULL)); } + yymsp[-2].minor.yy616 = yylhsminor.yy616; + break; + case 372: /* star_func_para_list ::= NK_STAR */ +{ yylhsminor.yy356 = createNodeList(pCxt, createColumnNode(pCxt, NULL, &yymsp[0].minor.yy0)); } + yymsp[0].minor.yy356 = yylhsminor.yy356; + break; + case 377: /* star_func_para ::= table_name NK_DOT NK_STAR */ + case 434: /* select_item ::= table_name NK_DOT NK_STAR */ yytestcase(yyruleno==434); +{ yylhsminor.yy616 = createColumnNode(pCxt, &yymsp[-2].minor.yy361, &yymsp[0].minor.yy0); } + yymsp[-2].minor.yy616 = yylhsminor.yy616; + break; + case 378: /* predicate ::= expression compare_op expression */ + case 383: /* predicate ::= expression in_op in_predicate_value */ yytestcase(yyruleno==383); { - SToken s = getTokenFromRawExprNode(pCxt, yymsp[-2].minor.yy560); - SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy560); - yylhsminor.yy560 = createRawExprNodeExt(pCxt, &s, &e, createOperatorNode(pCxt, yymsp[-1].minor.yy128, releaseRawExprNode(pCxt, yymsp[-2].minor.yy560), releaseRawExprNode(pCxt, yymsp[0].minor.yy560))); + SToken s = getTokenFromRawExprNode(pCxt, yymsp[-2].minor.yy616); + SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy616); + yylhsminor.yy616 = createRawExprNodeExt(pCxt, &s, &e, createOperatorNode(pCxt, yymsp[-1].minor.yy526, releaseRawExprNode(pCxt, yymsp[-2].minor.yy616), releaseRawExprNode(pCxt, yymsp[0].minor.yy616))); } - yymsp[-2].minor.yy560 = yylhsminor.yy560; + yymsp[-2].minor.yy616 = yylhsminor.yy616; break; - case 377: /* predicate ::= expression BETWEEN expression AND expression */ + case 379: /* predicate ::= expression BETWEEN expression AND expression */ { - SToken s = getTokenFromRawExprNode(pCxt, yymsp[-4].minor.yy560); - SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy560); - yylhsminor.yy560 = createRawExprNodeExt(pCxt, &s, &e, createBetweenAnd(pCxt, releaseRawExprNode(pCxt, yymsp[-4].minor.yy560), releaseRawExprNode(pCxt, yymsp[-2].minor.yy560), releaseRawExprNode(pCxt, yymsp[0].minor.yy560))); + SToken s = getTokenFromRawExprNode(pCxt, yymsp[-4].minor.yy616); + SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy616); + yylhsminor.yy616 = createRawExprNodeExt(pCxt, &s, &e, createBetweenAnd(pCxt, releaseRawExprNode(pCxt, yymsp[-4].minor.yy616), releaseRawExprNode(pCxt, yymsp[-2].minor.yy616), releaseRawExprNode(pCxt, yymsp[0].minor.yy616))); } - yymsp[-4].minor.yy560 = yylhsminor.yy560; + yymsp[-4].minor.yy616 = yylhsminor.yy616; break; - case 378: /* predicate ::= expression NOT BETWEEN expression AND expression */ + case 380: /* predicate ::= expression NOT BETWEEN expression AND expression */ { - SToken s = getTokenFromRawExprNode(pCxt, yymsp[-5].minor.yy560); - SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy560); - yylhsminor.yy560 = createRawExprNodeExt(pCxt, &s, &e, createNotBetweenAnd(pCxt, releaseRawExprNode(pCxt, yymsp[-5].minor.yy560), releaseRawExprNode(pCxt, yymsp[-2].minor.yy560), releaseRawExprNode(pCxt, yymsp[0].minor.yy560))); + SToken s = getTokenFromRawExprNode(pCxt, yymsp[-5].minor.yy616); + SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy616); + yylhsminor.yy616 = createRawExprNodeExt(pCxt, &s, &e, createNotBetweenAnd(pCxt, releaseRawExprNode(pCxt, yymsp[-5].minor.yy616), releaseRawExprNode(pCxt, yymsp[-2].minor.yy616), releaseRawExprNode(pCxt, yymsp[0].minor.yy616))); } - yymsp[-5].minor.yy560 = yylhsminor.yy560; + yymsp[-5].minor.yy616 = yylhsminor.yy616; break; - case 379: /* predicate ::= expression IS NULL */ + case 381: /* predicate ::= expression IS NULL */ { - SToken s = getTokenFromRawExprNode(pCxt, yymsp[-2].minor.yy560); - yylhsminor.yy560 = createRawExprNodeExt(pCxt, &s, &yymsp[0].minor.yy0, createOperatorNode(pCxt, OP_TYPE_IS_NULL, releaseRawExprNode(pCxt, yymsp[-2].minor.yy560), NULL)); + SToken s = getTokenFromRawExprNode(pCxt, yymsp[-2].minor.yy616); + yylhsminor.yy616 = createRawExprNodeExt(pCxt, &s, &yymsp[0].minor.yy0, createOperatorNode(pCxt, OP_TYPE_IS_NULL, releaseRawExprNode(pCxt, yymsp[-2].minor.yy616), NULL)); } - yymsp[-2].minor.yy560 = yylhsminor.yy560; + yymsp[-2].minor.yy616 = yylhsminor.yy616; break; - case 380: /* predicate ::= expression IS NOT NULL */ + case 382: /* predicate ::= expression IS NOT NULL */ { - SToken s = getTokenFromRawExprNode(pCxt, yymsp[-3].minor.yy560); - yylhsminor.yy560 = createRawExprNodeExt(pCxt, &s, &yymsp[0].minor.yy0, createOperatorNode(pCxt, OP_TYPE_IS_NOT_NULL, releaseRawExprNode(pCxt, yymsp[-3].minor.yy560), NULL)); + SToken s = getTokenFromRawExprNode(pCxt, yymsp[-3].minor.yy616); + yylhsminor.yy616 = createRawExprNodeExt(pCxt, &s, &yymsp[0].minor.yy0, createOperatorNode(pCxt, OP_TYPE_IS_NOT_NULL, releaseRawExprNode(pCxt, yymsp[-3].minor.yy616), NULL)); } - yymsp[-3].minor.yy560 = yylhsminor.yy560; + yymsp[-3].minor.yy616 = yylhsminor.yy616; break; - case 382: /* compare_op ::= NK_LT */ -{ yymsp[0].minor.yy128 = OP_TYPE_LOWER_THAN; } + case 384: /* compare_op ::= NK_LT */ +{ yymsp[0].minor.yy526 = OP_TYPE_LOWER_THAN; } break; - case 383: /* compare_op ::= NK_GT */ -{ yymsp[0].minor.yy128 = OP_TYPE_GREATER_THAN; } + case 385: /* compare_op ::= NK_GT */ +{ yymsp[0].minor.yy526 = OP_TYPE_GREATER_THAN; } break; - case 384: /* compare_op ::= NK_LE */ -{ yymsp[0].minor.yy128 = OP_TYPE_LOWER_EQUAL; } + case 386: /* compare_op ::= NK_LE */ +{ yymsp[0].minor.yy526 = OP_TYPE_LOWER_EQUAL; } break; - case 385: /* compare_op ::= NK_GE */ -{ yymsp[0].minor.yy128 = OP_TYPE_GREATER_EQUAL; } + case 387: /* compare_op ::= NK_GE */ +{ yymsp[0].minor.yy526 = OP_TYPE_GREATER_EQUAL; } break; - case 386: /* compare_op ::= NK_NE */ -{ yymsp[0].minor.yy128 = OP_TYPE_NOT_EQUAL; } + case 388: /* compare_op ::= NK_NE */ +{ yymsp[0].minor.yy526 = OP_TYPE_NOT_EQUAL; } break; - case 387: /* compare_op ::= NK_EQ */ -{ yymsp[0].minor.yy128 = OP_TYPE_EQUAL; } + case 389: /* compare_op ::= NK_EQ */ +{ yymsp[0].minor.yy526 = OP_TYPE_EQUAL; } break; - case 388: /* compare_op ::= LIKE */ -{ yymsp[0].minor.yy128 = OP_TYPE_LIKE; } + case 390: /* compare_op ::= LIKE */ +{ yymsp[0].minor.yy526 = OP_TYPE_LIKE; } break; - case 389: /* compare_op ::= NOT LIKE */ -{ yymsp[-1].minor.yy128 = OP_TYPE_NOT_LIKE; } + case 391: /* compare_op ::= NOT LIKE */ +{ yymsp[-1].minor.yy526 = OP_TYPE_NOT_LIKE; } break; - case 390: /* compare_op ::= MATCH */ -{ yymsp[0].minor.yy128 = OP_TYPE_MATCH; } + case 392: /* compare_op ::= MATCH */ +{ yymsp[0].minor.yy526 = OP_TYPE_MATCH; } break; - case 391: /* compare_op ::= NMATCH */ -{ yymsp[0].minor.yy128 = OP_TYPE_NMATCH; } + case 393: /* compare_op ::= NMATCH */ +{ yymsp[0].minor.yy526 = OP_TYPE_NMATCH; } break; - case 392: /* compare_op ::= CONTAINS */ -{ yymsp[0].minor.yy128 = OP_TYPE_JSON_CONTAINS; } + case 394: /* compare_op ::= CONTAINS */ +{ yymsp[0].minor.yy526 = OP_TYPE_JSON_CONTAINS; } break; - case 393: /* in_op ::= IN */ -{ yymsp[0].minor.yy128 = OP_TYPE_IN; } + case 395: /* in_op ::= IN */ +{ yymsp[0].minor.yy526 = OP_TYPE_IN; } break; - case 394: /* in_op ::= NOT IN */ -{ yymsp[-1].minor.yy128 = OP_TYPE_NOT_IN; } + case 396: /* in_op ::= NOT IN */ +{ yymsp[-1].minor.yy526 = OP_TYPE_NOT_IN; } break; - case 395: /* in_predicate_value ::= NK_LP literal_list NK_RP */ -{ yylhsminor.yy560 = createRawExprNodeExt(pCxt, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0, createNodeListNode(pCxt, yymsp[-1].minor.yy712)); } - yymsp[-2].minor.yy560 = yylhsminor.yy560; + case 397: /* in_predicate_value ::= NK_LP literal_list NK_RP */ +{ yylhsminor.yy616 = createRawExprNodeExt(pCxt, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0, createNodeListNode(pCxt, yymsp[-1].minor.yy356)); } + yymsp[-2].minor.yy616 = yylhsminor.yy616; break; - case 397: /* boolean_value_expression ::= NOT boolean_primary */ + case 399: /* boolean_value_expression ::= NOT boolean_primary */ { - SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy560); - yylhsminor.yy560 = createRawExprNodeExt(pCxt, &yymsp[-1].minor.yy0, &e, createLogicConditionNode(pCxt, LOGIC_COND_TYPE_NOT, releaseRawExprNode(pCxt, yymsp[0].minor.yy560), NULL)); + SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy616); + yylhsminor.yy616 = createRawExprNodeExt(pCxt, &yymsp[-1].minor.yy0, &e, createLogicConditionNode(pCxt, LOGIC_COND_TYPE_NOT, releaseRawExprNode(pCxt, yymsp[0].minor.yy616), NULL)); } - yymsp[-1].minor.yy560 = yylhsminor.yy560; + yymsp[-1].minor.yy616 = yylhsminor.yy616; break; - case 398: /* boolean_value_expression ::= boolean_value_expression OR boolean_value_expression */ + case 400: /* boolean_value_expression ::= boolean_value_expression OR boolean_value_expression */ { - SToken s = getTokenFromRawExprNode(pCxt, yymsp[-2].minor.yy560); - SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy560); - yylhsminor.yy560 = createRawExprNodeExt(pCxt, &s, &e, createLogicConditionNode(pCxt, LOGIC_COND_TYPE_OR, releaseRawExprNode(pCxt, yymsp[-2].minor.yy560), releaseRawExprNode(pCxt, yymsp[0].minor.yy560))); + SToken s = getTokenFromRawExprNode(pCxt, yymsp[-2].minor.yy616); + SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy616); + yylhsminor.yy616 = createRawExprNodeExt(pCxt, &s, &e, createLogicConditionNode(pCxt, LOGIC_COND_TYPE_OR, releaseRawExprNode(pCxt, yymsp[-2].minor.yy616), releaseRawExprNode(pCxt, yymsp[0].minor.yy616))); } - yymsp[-2].minor.yy560 = yylhsminor.yy560; + yymsp[-2].minor.yy616 = yylhsminor.yy616; break; - case 399: /* boolean_value_expression ::= boolean_value_expression AND boolean_value_expression */ + case 401: /* boolean_value_expression ::= boolean_value_expression AND boolean_value_expression */ { - SToken s = getTokenFromRawExprNode(pCxt, yymsp[-2].minor.yy560); - SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy560); - yylhsminor.yy560 = createRawExprNodeExt(pCxt, &s, &e, createLogicConditionNode(pCxt, LOGIC_COND_TYPE_AND, releaseRawExprNode(pCxt, yymsp[-2].minor.yy560), releaseRawExprNode(pCxt, yymsp[0].minor.yy560))); + SToken s = getTokenFromRawExprNode(pCxt, yymsp[-2].minor.yy616); + SToken e = getTokenFromRawExprNode(pCxt, yymsp[0].minor.yy616); + yylhsminor.yy616 = createRawExprNodeExt(pCxt, &s, &e, createLogicConditionNode(pCxt, LOGIC_COND_TYPE_AND, releaseRawExprNode(pCxt, yymsp[-2].minor.yy616), releaseRawExprNode(pCxt, yymsp[0].minor.yy616))); } - yymsp[-2].minor.yy560 = yylhsminor.yy560; + yymsp[-2].minor.yy616 = yylhsminor.yy616; break; - case 407: /* table_reference_list ::= table_reference_list NK_COMMA table_reference */ -{ yylhsminor.yy560 = createJoinTableNode(pCxt, JOIN_TYPE_INNER, yymsp[-2].minor.yy560, yymsp[0].minor.yy560, NULL); } - yymsp[-2].minor.yy560 = yylhsminor.yy560; + case 409: /* table_reference_list ::= table_reference_list NK_COMMA table_reference */ +{ yylhsminor.yy616 = createJoinTableNode(pCxt, JOIN_TYPE_INNER, yymsp[-2].minor.yy616, yymsp[0].minor.yy616, NULL); } + yymsp[-2].minor.yy616 = yylhsminor.yy616; break; - case 410: /* table_primary ::= table_name alias_opt */ -{ yylhsminor.yy560 = createRealTableNode(pCxt, NULL, &yymsp[-1].minor.yy533, &yymsp[0].minor.yy533); } - yymsp[-1].minor.yy560 = yylhsminor.yy560; + case 412: /* table_primary ::= table_name alias_opt */ +{ yylhsminor.yy616 = createRealTableNode(pCxt, NULL, &yymsp[-1].minor.yy361, &yymsp[0].minor.yy361); } + yymsp[-1].minor.yy616 = yylhsminor.yy616; break; - case 411: /* table_primary ::= db_name NK_DOT table_name alias_opt */ -{ yylhsminor.yy560 = createRealTableNode(pCxt, &yymsp[-3].minor.yy533, &yymsp[-1].minor.yy533, &yymsp[0].minor.yy533); } - yymsp[-3].minor.yy560 = yylhsminor.yy560; + case 413: /* table_primary ::= db_name NK_DOT table_name alias_opt */ +{ yylhsminor.yy616 = createRealTableNode(pCxt, &yymsp[-3].minor.yy361, &yymsp[-1].minor.yy361, &yymsp[0].minor.yy361); } + yymsp[-3].minor.yy616 = yylhsminor.yy616; break; - case 412: /* table_primary ::= subquery alias_opt */ -{ yylhsminor.yy560 = createTempTableNode(pCxt, releaseRawExprNode(pCxt, yymsp[-1].minor.yy560), &yymsp[0].minor.yy533); } - yymsp[-1].minor.yy560 = yylhsminor.yy560; + case 414: /* table_primary ::= subquery alias_opt */ +{ yylhsminor.yy616 = createTempTableNode(pCxt, releaseRawExprNode(pCxt, yymsp[-1].minor.yy616), &yymsp[0].minor.yy361); } + yymsp[-1].minor.yy616 = yylhsminor.yy616; break; - case 414: /* alias_opt ::= */ -{ yymsp[1].minor.yy533 = nil_token; } + case 416: /* alias_opt ::= */ +{ yymsp[1].minor.yy361 = nil_token; } break; - case 415: /* alias_opt ::= table_alias */ -{ yylhsminor.yy533 = yymsp[0].minor.yy533; } - yymsp[0].minor.yy533 = yylhsminor.yy533; + case 417: /* alias_opt ::= table_alias */ +{ yylhsminor.yy361 = yymsp[0].minor.yy361; } + yymsp[0].minor.yy361 = yylhsminor.yy361; break; - case 416: /* alias_opt ::= AS table_alias */ -{ yymsp[-1].minor.yy533 = yymsp[0].minor.yy533; } + case 418: /* alias_opt ::= AS table_alias */ +{ yymsp[-1].minor.yy361 = yymsp[0].minor.yy361; } break; - case 417: /* parenthesized_joined_table ::= NK_LP joined_table NK_RP */ - case 418: /* parenthesized_joined_table ::= NK_LP parenthesized_joined_table NK_RP */ yytestcase(yyruleno==418); -{ yymsp[-2].minor.yy560 = yymsp[-1].minor.yy560; } + case 419: /* parenthesized_joined_table ::= NK_LP joined_table NK_RP */ + case 420: /* parenthesized_joined_table ::= NK_LP parenthesized_joined_table NK_RP */ yytestcase(yyruleno==420); +{ yymsp[-2].minor.yy616 = yymsp[-1].minor.yy616; } break; - case 419: /* joined_table ::= table_reference join_type JOIN table_reference ON search_condition */ -{ yylhsminor.yy560 = createJoinTableNode(pCxt, yymsp[-4].minor.yy36, yymsp[-5].minor.yy560, yymsp[-2].minor.yy560, yymsp[0].minor.yy560); } - yymsp[-5].minor.yy560 = yylhsminor.yy560; + case 421: /* joined_table ::= table_reference join_type JOIN table_reference ON search_condition */ +{ yylhsminor.yy616 = createJoinTableNode(pCxt, yymsp[-4].minor.yy504, yymsp[-5].minor.yy616, yymsp[-2].minor.yy616, yymsp[0].minor.yy616); } + yymsp[-5].minor.yy616 = yylhsminor.yy616; break; - case 420: /* join_type ::= */ -{ yymsp[1].minor.yy36 = JOIN_TYPE_INNER; } + case 422: /* join_type ::= */ +{ yymsp[1].minor.yy504 = JOIN_TYPE_INNER; } break; - case 421: /* join_type ::= INNER */ -{ yymsp[0].minor.yy36 = JOIN_TYPE_INNER; } + case 423: /* join_type ::= INNER */ +{ yymsp[0].minor.yy504 = JOIN_TYPE_INNER; } break; - case 422: /* query_specification ::= SELECT set_quantifier_opt select_list from_clause_opt where_clause_opt partition_by_clause_opt range_opt every_opt fill_opt twindow_clause_opt group_by_clause_opt having_clause_opt */ + case 424: /* query_specification ::= SELECT set_quantifier_opt select_list from_clause_opt where_clause_opt partition_by_clause_opt range_opt every_opt fill_opt twindow_clause_opt group_by_clause_opt having_clause_opt */ { - yymsp[-11].minor.yy560 = createSelectStmt(pCxt, yymsp[-10].minor.yy173, yymsp[-9].minor.yy712, yymsp[-8].minor.yy560); - yymsp[-11].minor.yy560 = addWhereClause(pCxt, yymsp[-11].minor.yy560, yymsp[-7].minor.yy560); - yymsp[-11].minor.yy560 = addPartitionByClause(pCxt, yymsp[-11].minor.yy560, yymsp[-6].minor.yy712); - yymsp[-11].minor.yy560 = addWindowClauseClause(pCxt, yymsp[-11].minor.yy560, yymsp[-2].minor.yy560); - yymsp[-11].minor.yy560 = addGroupByClause(pCxt, yymsp[-11].minor.yy560, yymsp[-1].minor.yy712); - yymsp[-11].minor.yy560 = addHavingClause(pCxt, yymsp[-11].minor.yy560, yymsp[0].minor.yy560); - yymsp[-11].minor.yy560 = addRangeClause(pCxt, yymsp[-11].minor.yy560, yymsp[-5].minor.yy560); - yymsp[-11].minor.yy560 = addEveryClause(pCxt, yymsp[-11].minor.yy560, yymsp[-4].minor.yy560); - yymsp[-11].minor.yy560 = addFillClause(pCxt, yymsp[-11].minor.yy560, yymsp[-3].minor.yy560); + yymsp[-11].minor.yy616 = createSelectStmt(pCxt, yymsp[-10].minor.yy151, yymsp[-9].minor.yy356, yymsp[-8].minor.yy616); + yymsp[-11].minor.yy616 = addWhereClause(pCxt, yymsp[-11].minor.yy616, yymsp[-7].minor.yy616); + yymsp[-11].minor.yy616 = addPartitionByClause(pCxt, yymsp[-11].minor.yy616, yymsp[-6].minor.yy356); + yymsp[-11].minor.yy616 = addWindowClauseClause(pCxt, yymsp[-11].minor.yy616, yymsp[-2].minor.yy616); + yymsp[-11].minor.yy616 = addGroupByClause(pCxt, yymsp[-11].minor.yy616, yymsp[-1].minor.yy356); + yymsp[-11].minor.yy616 = addHavingClause(pCxt, yymsp[-11].minor.yy616, yymsp[0].minor.yy616); + yymsp[-11].minor.yy616 = addRangeClause(pCxt, yymsp[-11].minor.yy616, yymsp[-5].minor.yy616); + yymsp[-11].minor.yy616 = addEveryClause(pCxt, yymsp[-11].minor.yy616, yymsp[-4].minor.yy616); + yymsp[-11].minor.yy616 = addFillClause(pCxt, yymsp[-11].minor.yy616, yymsp[-3].minor.yy616); } break; - case 425: /* set_quantifier_opt ::= ALL */ -{ yymsp[0].minor.yy173 = false; } + case 427: /* set_quantifier_opt ::= ALL */ +{ yymsp[0].minor.yy151 = false; } break; - case 428: /* select_item ::= NK_STAR */ -{ yylhsminor.yy560 = createColumnNode(pCxt, NULL, &yymsp[0].minor.yy0); } - yymsp[0].minor.yy560 = yylhsminor.yy560; + case 430: /* select_item ::= NK_STAR */ +{ yylhsminor.yy616 = createColumnNode(pCxt, NULL, &yymsp[0].minor.yy0); } + yymsp[0].minor.yy616 = yylhsminor.yy616; break; - case 430: /* select_item ::= common_expression column_alias */ -{ yylhsminor.yy560 = setProjectionAlias(pCxt, releaseRawExprNode(pCxt, yymsp[-1].minor.yy560), &yymsp[0].minor.yy533); } - yymsp[-1].minor.yy560 = yylhsminor.yy560; + case 432: /* select_item ::= common_expression column_alias */ +{ yylhsminor.yy616 = setProjectionAlias(pCxt, releaseRawExprNode(pCxt, yymsp[-1].minor.yy616), &yymsp[0].minor.yy361); } + yymsp[-1].minor.yy616 = yylhsminor.yy616; break; - case 431: /* select_item ::= common_expression AS column_alias */ -{ yylhsminor.yy560 = setProjectionAlias(pCxt, releaseRawExprNode(pCxt, yymsp[-2].minor.yy560), &yymsp[0].minor.yy533); } - yymsp[-2].minor.yy560 = yylhsminor.yy560; + case 433: /* select_item ::= common_expression AS column_alias */ +{ yylhsminor.yy616 = setProjectionAlias(pCxt, releaseRawExprNode(pCxt, yymsp[-2].minor.yy616), &yymsp[0].minor.yy361); } + yymsp[-2].minor.yy616 = yylhsminor.yy616; break; - case 436: /* partition_by_clause_opt ::= PARTITION BY expression_list */ - case 453: /* group_by_clause_opt ::= GROUP BY group_by_list */ yytestcase(yyruleno==453); - case 469: /* order_by_clause_opt ::= ORDER BY sort_specification_list */ yytestcase(yyruleno==469); -{ yymsp[-2].minor.yy712 = yymsp[0].minor.yy712; } + case 438: /* partition_by_clause_opt ::= PARTITION BY expression_list */ + case 455: /* group_by_clause_opt ::= GROUP BY group_by_list */ yytestcase(yyruleno==455); + case 471: /* order_by_clause_opt ::= ORDER BY sort_specification_list */ yytestcase(yyruleno==471); +{ yymsp[-2].minor.yy356 = yymsp[0].minor.yy356; } break; - case 438: /* twindow_clause_opt ::= SESSION NK_LP column_reference NK_COMMA duration_literal NK_RP */ -{ yymsp[-5].minor.yy560 = createSessionWindowNode(pCxt, releaseRawExprNode(pCxt, yymsp[-3].minor.yy560), releaseRawExprNode(pCxt, yymsp[-1].minor.yy560)); } + case 440: /* twindow_clause_opt ::= SESSION NK_LP column_reference NK_COMMA duration_literal NK_RP */ +{ yymsp[-5].minor.yy616 = createSessionWindowNode(pCxt, releaseRawExprNode(pCxt, yymsp[-3].minor.yy616), releaseRawExprNode(pCxt, yymsp[-1].minor.yy616)); } break; - case 439: /* twindow_clause_opt ::= STATE_WINDOW NK_LP expression NK_RP */ -{ yymsp[-3].minor.yy560 = createStateWindowNode(pCxt, releaseRawExprNode(pCxt, yymsp[-1].minor.yy560)); } + case 441: /* twindow_clause_opt ::= STATE_WINDOW NK_LP expression NK_RP */ +{ yymsp[-3].minor.yy616 = createStateWindowNode(pCxt, releaseRawExprNode(pCxt, yymsp[-1].minor.yy616)); } break; - case 440: /* twindow_clause_opt ::= INTERVAL NK_LP duration_literal NK_RP sliding_opt fill_opt */ -{ yymsp[-5].minor.yy560 = createIntervalWindowNode(pCxt, releaseRawExprNode(pCxt, yymsp[-3].minor.yy560), NULL, yymsp[-1].minor.yy560, yymsp[0].minor.yy560); } + case 442: /* twindow_clause_opt ::= INTERVAL NK_LP duration_literal NK_RP sliding_opt fill_opt */ +{ yymsp[-5].minor.yy616 = createIntervalWindowNode(pCxt, releaseRawExprNode(pCxt, yymsp[-3].minor.yy616), NULL, yymsp[-1].minor.yy616, yymsp[0].minor.yy616); } break; - case 441: /* twindow_clause_opt ::= INTERVAL NK_LP duration_literal NK_COMMA duration_literal NK_RP sliding_opt fill_opt */ -{ yymsp[-7].minor.yy560 = createIntervalWindowNode(pCxt, releaseRawExprNode(pCxt, yymsp[-5].minor.yy560), releaseRawExprNode(pCxt, yymsp[-3].minor.yy560), yymsp[-1].minor.yy560, yymsp[0].minor.yy560); } + case 443: /* twindow_clause_opt ::= INTERVAL NK_LP duration_literal NK_COMMA duration_literal NK_RP sliding_opt fill_opt */ +{ yymsp[-7].minor.yy616 = createIntervalWindowNode(pCxt, releaseRawExprNode(pCxt, yymsp[-5].minor.yy616), releaseRawExprNode(pCxt, yymsp[-3].minor.yy616), yymsp[-1].minor.yy616, yymsp[0].minor.yy616); } break; - case 443: /* sliding_opt ::= SLIDING NK_LP duration_literal NK_RP */ - case 461: /* every_opt ::= EVERY NK_LP duration_literal NK_RP */ yytestcase(yyruleno==461); -{ yymsp[-3].minor.yy560 = releaseRawExprNode(pCxt, yymsp[-1].minor.yy560); } + case 445: /* sliding_opt ::= SLIDING NK_LP duration_literal NK_RP */ + case 463: /* every_opt ::= EVERY NK_LP duration_literal NK_RP */ yytestcase(yyruleno==463); +{ yymsp[-3].minor.yy616 = releaseRawExprNode(pCxt, yymsp[-1].minor.yy616); } break; - case 445: /* fill_opt ::= FILL NK_LP fill_mode NK_RP */ -{ yymsp[-3].minor.yy560 = createFillNode(pCxt, yymsp[-1].minor.yy18, NULL); } + case 447: /* fill_opt ::= FILL NK_LP fill_mode NK_RP */ +{ yymsp[-3].minor.yy616 = createFillNode(pCxt, yymsp[-1].minor.yy494, NULL); } break; - case 446: /* fill_opt ::= FILL NK_LP VALUE NK_COMMA literal_list NK_RP */ -{ yymsp[-5].minor.yy560 = createFillNode(pCxt, FILL_MODE_VALUE, createNodeListNode(pCxt, yymsp[-1].minor.yy712)); } + case 448: /* fill_opt ::= FILL NK_LP VALUE NK_COMMA literal_list NK_RP */ +{ yymsp[-5].minor.yy616 = createFillNode(pCxt, FILL_MODE_VALUE, createNodeListNode(pCxt, yymsp[-1].minor.yy356)); } break; - case 447: /* fill_mode ::= NONE */ -{ yymsp[0].minor.yy18 = FILL_MODE_NONE; } + case 449: /* fill_mode ::= NONE */ +{ yymsp[0].minor.yy494 = FILL_MODE_NONE; } break; - case 448: /* fill_mode ::= PREV */ -{ yymsp[0].minor.yy18 = FILL_MODE_PREV; } + case 450: /* fill_mode ::= PREV */ +{ yymsp[0].minor.yy494 = FILL_MODE_PREV; } break; - case 449: /* fill_mode ::= NULL */ -{ yymsp[0].minor.yy18 = FILL_MODE_NULL; } + case 451: /* fill_mode ::= NULL */ +{ yymsp[0].minor.yy494 = FILL_MODE_NULL; } break; - case 450: /* fill_mode ::= LINEAR */ -{ yymsp[0].minor.yy18 = FILL_MODE_LINEAR; } + case 452: /* fill_mode ::= LINEAR */ +{ yymsp[0].minor.yy494 = FILL_MODE_LINEAR; } break; - case 451: /* fill_mode ::= NEXT */ -{ yymsp[0].minor.yy18 = FILL_MODE_NEXT; } + case 453: /* fill_mode ::= NEXT */ +{ yymsp[0].minor.yy494 = FILL_MODE_NEXT; } break; - case 454: /* group_by_list ::= expression */ -{ yylhsminor.yy712 = createNodeList(pCxt, createGroupingSetNode(pCxt, releaseRawExprNode(pCxt, yymsp[0].minor.yy560))); } - yymsp[0].minor.yy712 = yylhsminor.yy712; + case 456: /* group_by_list ::= expression */ +{ yylhsminor.yy356 = createNodeList(pCxt, createGroupingSetNode(pCxt, releaseRawExprNode(pCxt, yymsp[0].minor.yy616))); } + yymsp[0].minor.yy356 = yylhsminor.yy356; break; - case 455: /* group_by_list ::= group_by_list NK_COMMA expression */ -{ yylhsminor.yy712 = addNodeToList(pCxt, yymsp[-2].minor.yy712, createGroupingSetNode(pCxt, releaseRawExprNode(pCxt, yymsp[0].minor.yy560))); } - yymsp[-2].minor.yy712 = yylhsminor.yy712; + case 457: /* group_by_list ::= group_by_list NK_COMMA expression */ +{ yylhsminor.yy356 = addNodeToList(pCxt, yymsp[-2].minor.yy356, createGroupingSetNode(pCxt, releaseRawExprNode(pCxt, yymsp[0].minor.yy616))); } + yymsp[-2].minor.yy356 = yylhsminor.yy356; break; - case 459: /* range_opt ::= RANGE NK_LP expression NK_COMMA expression NK_RP */ -{ yymsp[-5].minor.yy560 = createInterpTimeRange(pCxt, releaseRawExprNode(pCxt, yymsp[-3].minor.yy560), releaseRawExprNode(pCxt, yymsp[-1].minor.yy560)); } + case 461: /* range_opt ::= RANGE NK_LP expression NK_COMMA expression NK_RP */ +{ yymsp[-5].minor.yy616 = createInterpTimeRange(pCxt, releaseRawExprNode(pCxt, yymsp[-3].minor.yy616), releaseRawExprNode(pCxt, yymsp[-1].minor.yy616)); } break; - case 462: /* query_expression ::= query_expression_body order_by_clause_opt slimit_clause_opt limit_clause_opt */ + case 464: /* query_expression ::= query_expression_body order_by_clause_opt slimit_clause_opt limit_clause_opt */ { - yylhsminor.yy560 = addOrderByClause(pCxt, yymsp[-3].minor.yy560, yymsp[-2].minor.yy712); - yylhsminor.yy560 = addSlimitClause(pCxt, yylhsminor.yy560, yymsp[-1].minor.yy560); - yylhsminor.yy560 = addLimitClause(pCxt, yylhsminor.yy560, yymsp[0].minor.yy560); + yylhsminor.yy616 = addOrderByClause(pCxt, yymsp[-3].minor.yy616, yymsp[-2].minor.yy356); + yylhsminor.yy616 = addSlimitClause(pCxt, yylhsminor.yy616, yymsp[-1].minor.yy616); + yylhsminor.yy616 = addLimitClause(pCxt, yylhsminor.yy616, yymsp[0].minor.yy616); } - yymsp[-3].minor.yy560 = yylhsminor.yy560; + yymsp[-3].minor.yy616 = yylhsminor.yy616; break; - case 464: /* query_expression_body ::= query_expression_body UNION ALL query_expression_body */ -{ yylhsminor.yy560 = createSetOperator(pCxt, SET_OP_TYPE_UNION_ALL, yymsp[-3].minor.yy560, yymsp[0].minor.yy560); } - yymsp[-3].minor.yy560 = yylhsminor.yy560; + case 466: /* query_expression_body ::= query_expression_body UNION ALL query_expression_body */ +{ yylhsminor.yy616 = createSetOperator(pCxt, SET_OP_TYPE_UNION_ALL, yymsp[-3].minor.yy616, yymsp[0].minor.yy616); } + yymsp[-3].minor.yy616 = yylhsminor.yy616; break; - case 465: /* query_expression_body ::= query_expression_body UNION query_expression_body */ -{ yylhsminor.yy560 = createSetOperator(pCxt, SET_OP_TYPE_UNION, yymsp[-2].minor.yy560, yymsp[0].minor.yy560); } - yymsp[-2].minor.yy560 = yylhsminor.yy560; + case 467: /* query_expression_body ::= query_expression_body UNION query_expression_body */ +{ yylhsminor.yy616 = createSetOperator(pCxt, SET_OP_TYPE_UNION, yymsp[-2].minor.yy616, yymsp[0].minor.yy616); } + yymsp[-2].minor.yy616 = yylhsminor.yy616; break; - case 467: /* query_primary ::= NK_LP query_expression_body order_by_clause_opt slimit_clause_opt limit_clause_opt NK_RP */ + case 469: /* query_primary ::= NK_LP query_expression_body order_by_clause_opt slimit_clause_opt limit_clause_opt NK_RP */ { - yymsp[-5].minor.yy560 = addOrderByClause(pCxt, yymsp[-4].minor.yy560, yymsp[-3].minor.yy712); - yymsp[-5].minor.yy560 = addSlimitClause(pCxt, yymsp[-5].minor.yy560, yymsp[-2].minor.yy560); - yymsp[-5].minor.yy560 = addLimitClause(pCxt, yymsp[-5].minor.yy560, yymsp[-1].minor.yy560); + yymsp[-5].minor.yy616 = addOrderByClause(pCxt, yymsp[-4].minor.yy616, yymsp[-3].minor.yy356); + yymsp[-5].minor.yy616 = addSlimitClause(pCxt, yymsp[-5].minor.yy616, yymsp[-2].minor.yy616); + yymsp[-5].minor.yy616 = addLimitClause(pCxt, yymsp[-5].minor.yy616, yymsp[-1].minor.yy616); } break; - case 471: /* slimit_clause_opt ::= SLIMIT NK_INTEGER */ - case 475: /* limit_clause_opt ::= LIMIT NK_INTEGER */ yytestcase(yyruleno==475); -{ yymsp[-1].minor.yy560 = createLimitNode(pCxt, &yymsp[0].minor.yy0, NULL); } + case 473: /* slimit_clause_opt ::= SLIMIT NK_INTEGER */ + case 477: /* limit_clause_opt ::= LIMIT NK_INTEGER */ yytestcase(yyruleno==477); +{ yymsp[-1].minor.yy616 = createLimitNode(pCxt, &yymsp[0].minor.yy0, NULL); } break; - case 472: /* slimit_clause_opt ::= SLIMIT NK_INTEGER SOFFSET NK_INTEGER */ - case 476: /* limit_clause_opt ::= LIMIT NK_INTEGER OFFSET NK_INTEGER */ yytestcase(yyruleno==476); -{ yymsp[-3].minor.yy560 = createLimitNode(pCxt, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0); } + case 474: /* slimit_clause_opt ::= SLIMIT NK_INTEGER SOFFSET NK_INTEGER */ + case 478: /* limit_clause_opt ::= LIMIT NK_INTEGER OFFSET NK_INTEGER */ yytestcase(yyruleno==478); +{ yymsp[-3].minor.yy616 = createLimitNode(pCxt, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0); } break; - case 473: /* slimit_clause_opt ::= SLIMIT NK_INTEGER NK_COMMA NK_INTEGER */ - case 477: /* limit_clause_opt ::= LIMIT NK_INTEGER NK_COMMA NK_INTEGER */ yytestcase(yyruleno==477); -{ yymsp[-3].minor.yy560 = createLimitNode(pCxt, &yymsp[0].minor.yy0, &yymsp[-2].minor.yy0); } + case 475: /* slimit_clause_opt ::= SLIMIT NK_INTEGER NK_COMMA NK_INTEGER */ + case 479: /* limit_clause_opt ::= LIMIT NK_INTEGER NK_COMMA NK_INTEGER */ yytestcase(yyruleno==479); +{ yymsp[-3].minor.yy616 = createLimitNode(pCxt, &yymsp[0].minor.yy0, &yymsp[-2].minor.yy0); } break; - case 478: /* subquery ::= NK_LP query_expression NK_RP */ -{ yylhsminor.yy560 = createRawExprNodeExt(pCxt, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0, yymsp[-1].minor.yy560); } - yymsp[-2].minor.yy560 = yylhsminor.yy560; + case 480: /* subquery ::= NK_LP query_expression NK_RP */ +{ yylhsminor.yy616 = createRawExprNodeExt(pCxt, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0, yymsp[-1].minor.yy616); } + yymsp[-2].minor.yy616 = yylhsminor.yy616; break; - case 482: /* sort_specification ::= expression ordering_specification_opt null_ordering_opt */ -{ yylhsminor.yy560 = createOrderByExprNode(pCxt, releaseRawExprNode(pCxt, yymsp[-2].minor.yy560), yymsp[-1].minor.yy218, yymsp[0].minor.yy109); } - yymsp[-2].minor.yy560 = yylhsminor.yy560; + case 484: /* sort_specification ::= expression ordering_specification_opt null_ordering_opt */ +{ yylhsminor.yy616 = createOrderByExprNode(pCxt, releaseRawExprNode(pCxt, yymsp[-2].minor.yy616), yymsp[-1].minor.yy58, yymsp[0].minor.yy613); } + yymsp[-2].minor.yy616 = yylhsminor.yy616; break; - case 483: /* ordering_specification_opt ::= */ -{ yymsp[1].minor.yy218 = ORDER_ASC; } + case 485: /* ordering_specification_opt ::= */ +{ yymsp[1].minor.yy58 = ORDER_ASC; } break; - case 484: /* ordering_specification_opt ::= ASC */ -{ yymsp[0].minor.yy218 = ORDER_ASC; } + case 486: /* ordering_specification_opt ::= ASC */ +{ yymsp[0].minor.yy58 = ORDER_ASC; } break; - case 485: /* ordering_specification_opt ::= DESC */ -{ yymsp[0].minor.yy218 = ORDER_DESC; } + case 487: /* ordering_specification_opt ::= DESC */ +{ yymsp[0].minor.yy58 = ORDER_DESC; } break; - case 486: /* null_ordering_opt ::= */ -{ yymsp[1].minor.yy109 = NULL_ORDER_DEFAULT; } + case 488: /* null_ordering_opt ::= */ +{ yymsp[1].minor.yy613 = NULL_ORDER_DEFAULT; } break; - case 487: /* null_ordering_opt ::= NULLS FIRST */ -{ yymsp[-1].minor.yy109 = NULL_ORDER_FIRST; } + case 489: /* null_ordering_opt ::= NULLS FIRST */ +{ yymsp[-1].minor.yy613 = NULL_ORDER_FIRST; } break; - case 488: /* null_ordering_opt ::= NULLS LAST */ -{ yymsp[-1].minor.yy109 = NULL_ORDER_LAST; } + case 490: /* null_ordering_opt ::= NULLS LAST */ +{ yymsp[-1].minor.yy613 = NULL_ORDER_LAST; } break; default: break; diff --git a/source/libs/parser/test/parSelectTest.cpp b/source/libs/parser/test/parSelectTest.cpp index 0aa1773c28..e682059793 100644 --- a/source/libs/parser/test/parSelectTest.cpp +++ b/source/libs/parser/test/parSelectTest.cpp @@ -75,7 +75,7 @@ TEST_F(ParserSelectTest, condition) { TEST_F(ParserSelectTest, pseudoColumn) { useDb("root", "test"); - run("SELECT _WSTARTTS, _WENDTS, COUNT(*) FROM t1 INTERVAL(10s)"); + run("SELECT _WSTART, _WEND, COUNT(*) FROM t1 INTERVAL(10s)"); } TEST_F(ParserSelectTest, pseudoColumnSemanticCheck) { @@ -286,7 +286,7 @@ TEST_F(ParserSelectTest, intervalSemanticCheck) { run("SELECT HISTOGRAM(c1, 'log_bin', '{\"start\": -33,\"factor\": 55,\"count\": 5,\"infinity\": false}', 1) FROM t1 " "WHERE ts > TIMESTAMP '2022-04-01 00:00:00' and ts < TIMESTAMP '2022-04-30 23:59:59' INTERVAL(10s) FILL(NULL)", TSDB_CODE_PAR_FILL_NOT_ALLOWED_FUNC); - run("SELECT _WSTARTTS, _WENDTS, _WDURATION, sum(c1) FROM t1", TSDB_CODE_PAR_INVALID_WINDOW_PC); + run("SELECT _WSTART, _WEND, _WDURATION, sum(c1) FROM t1", TSDB_CODE_PAR_INVALID_WINDOW_PC); } TEST_F(ParserSelectTest, interp) { @@ -310,11 +310,11 @@ TEST_F(ParserSelectTest, subquery) { run("SELECT SUM(a) FROM (SELECT MAX(c1) a, ts FROM st1s1 INTERVAL(1m)) INTERVAL(1n)"); - run("SELECT SUM(a) FROM (SELECT MAX(c1) a, _wstartts FROM st1s1 INTERVAL(1m)) INTERVAL(1n)"); + run("SELECT SUM(a) FROM (SELECT MAX(c1) a, _wstart FROM st1s1 INTERVAL(1m)) INTERVAL(1n)"); run("SELECT SUM(a) FROM (SELECT MAX(c1) a, ts FROM st1s1 PARTITION BY TBNAME INTERVAL(1m)) INTERVAL(1n)"); - run("SELECT SUM(a) FROM (SELECT MAX(c1) a, _wstartts FROM st1s1 PARTITION BY TBNAME INTERVAL(1m)) INTERVAL(1n)"); + run("SELECT SUM(a) FROM (SELECT MAX(c1) a, _wstart FROM st1s1 PARTITION BY TBNAME INTERVAL(1m)) INTERVAL(1n)"); run("SELECT _C0 FROM (SELECT _ROWTS, ts FROM st1s1)"); diff --git a/source/libs/planner/src/planLogicCreater.c b/source/libs/planner/src/planLogicCreater.c index e90be75743..7b5c5b7182 100644 --- a/source/libs/planner/src/planLogicCreater.c +++ b/source/libs/planner/src/planLogicCreater.c @@ -59,7 +59,7 @@ static EDealRes doRewriteExpr(SNode** pNode, void* pContext) { strcpy(pCol->node.aliasName, pToBeRewrittenExpr->aliasName); strcpy(pCol->colName, ((SExprNode*)pExpr)->aliasName); if (QUERY_NODE_FUNCTION == nodeType(pExpr)) { - if (FUNCTION_TYPE_WSTARTTS == ((SFunctionNode*)pExpr)->funcType) { + if (FUNCTION_TYPE_WSTART == ((SFunctionNode*)pExpr)->funcType) { pCol->colId = PRIMARYKEY_TIMESTAMP_COL_ID; } else if (FUNCTION_TYPE_TBNAME == ((SFunctionNode*)pExpr)->funcType) { pCol->colType = COLUMN_TYPE_TBNAME; diff --git a/source/libs/planner/src/planOptimizer.c b/source/libs/planner/src/planOptimizer.c index 855427f26e..ea1b3d3f81 100644 --- a/source/libs/planner/src/planOptimizer.c +++ b/source/libs/planner/src/planOptimizer.c @@ -792,15 +792,15 @@ static EDealRes rewriteAggGroupKeyCondForPushDownImpl(SNode** pNode, void* pCont if (0 == strcmp(((SExprNode*)pGroup)->aliasName, ((SColumnNode*)(*pNode))->colName)) { SNode* pExpr = nodesCloneNode(pGroup); if (pExpr == NULL) { - pCxt->errCode = terrno; + pCxt->errCode = TSDB_CODE_OUT_OF_MEMORY; return DEAL_RES_ERROR; } nodesDestroyNode(*pNode); *pNode = pExpr; + return DEAL_RES_IGNORE_CHILD; } } } - return DEAL_RES_IGNORE_CHILD; } return DEAL_RES_CONTINUE; } @@ -861,16 +861,16 @@ static EDealRes rewriteProjectCondForPushDownImpl(SNode** ppNode, void* pContext if (0 == strcmp(((SExprNode*)pProjection)->aliasName, ((SColumnNode*)(*ppNode))->colName)) { SNode* pExpr = nodesCloneNode(pProjection); if (pExpr == NULL) { - pCxt->errCode = terrno; + pCxt->errCode = TSDB_CODE_OUT_OF_MEMORY; return DEAL_RES_ERROR; } nodesDestroyNode(*ppNode); *ppNode = pExpr; + return DEAL_RES_IGNORE_CHILD; } // end if expr alias name equal column name } // end for each project } // end if target node equals cond column node } // end for each targets - return DEAL_RES_IGNORE_CHILD; } return DEAL_RES_CONTINUE; } @@ -1208,7 +1208,7 @@ static int32_t smaIndexOptCreateSmaCols(SNodeList* pFuncs, uint64_t tableId, SNo int32_t smaFuncIndex = -1; *pWStrartIndex = -1; FOREACH(pFunc, pFuncs) { - if (FUNCTION_TYPE_WSTARTTS == ((SFunctionNode*)pFunc)->funcType) { + if (FUNCTION_TYPE_WSTART == ((SFunctionNode*)pFunc)->funcType) { *pWStrartIndex = index; } smaFuncIndex = smaIndexOptFindSmaFunc(pFunc, pSmaFuncs); @@ -1252,7 +1252,7 @@ static SNode* smaIndexOptCreateWStartTs() { if (NULL == pWStart) { return NULL; } - strcpy(pWStart->functionName, "_wstartts"); + strcpy(pWStart->functionName, "_wstart"); snprintf(pWStart->node.aliasName, sizeof(pWStart->node.aliasName), "%s.%p", pWStart->functionName, pWStart); if (TSDB_CODE_SUCCESS != fmGetFuncInfo(pWStart, NULL, 0)) { nodesDestroyNode((SNode*)pWStart); @@ -2100,11 +2100,12 @@ static bool tagScanMayBeOptimized(SLogicNode* pNode) { if (QUERY_NODE_LOGIC_PLAN_SCAN != nodeType(pNode) || (SCAN_TYPE_TAG == ((SScanLogicNode*)pNode)->scanType)) { return false; } - SScanLogicNode *pScan = (SScanLogicNode*)pNode; + SScanLogicNode* pScan = (SScanLogicNode*)pNode; if (NULL != pScan->pScanCols) { return false; } - if (NULL == pNode->pParent || QUERY_NODE_LOGIC_PLAN_AGG != nodeType(pNode->pParent) || 1 != LIST_LENGTH(pNode->pParent->pChildren)) { + if (NULL == pNode->pParent || QUERY_NODE_LOGIC_PLAN_AGG != nodeType(pNode->pParent) || + 1 != LIST_LENGTH(pNode->pParent->pChildren)) { return false; } diff --git a/source/libs/planner/src/planSpliter.c b/source/libs/planner/src/planSpliter.c index 987da0dd17..7b9d553501 100644 --- a/source/libs/planner/src/planSpliter.c +++ b/source/libs/planner/src/planSpliter.c @@ -308,7 +308,7 @@ static int32_t stbSplAppendWStart(SNodeList* pFuncs, int32_t* pIndex) { int32_t index = 0; SNode* pFunc = NULL; FOREACH(pFunc, pFuncs) { - if (FUNCTION_TYPE_WSTARTTS == ((SFunctionNode*)pFunc)->funcType) { + if (FUNCTION_TYPE_WSTART == ((SFunctionNode*)pFunc)->funcType) { *pIndex = index; return TSDB_CODE_SUCCESS; } @@ -319,7 +319,7 @@ static int32_t stbSplAppendWStart(SNodeList* pFuncs, int32_t* pIndex) { if (NULL == pWStart) { return TSDB_CODE_OUT_OF_MEMORY; } - strcpy(pWStart->functionName, "_wstartts"); + strcpy(pWStart->functionName, "_wstart"); snprintf(pWStart->node.aliasName, sizeof(pWStart->node.aliasName), "%s.%p", pWStart->functionName, pWStart); int32_t code = fmGetFuncInfo(pWStart, NULL, 0); if (TSDB_CODE_SUCCESS == code) { @@ -333,7 +333,7 @@ static int32_t stbSplAppendWEnd(SWindowLogicNode* pWin, int32_t* pIndex) { int32_t index = 0; SNode* pFunc = NULL; FOREACH(pFunc, pWin->pFuncs) { - if (FUNCTION_TYPE_WENDTS == ((SFunctionNode*)pFunc)->funcType) { + if (FUNCTION_TYPE_WEND == ((SFunctionNode*)pFunc)->funcType) { *pIndex = index; return TSDB_CODE_SUCCESS; } @@ -344,7 +344,7 @@ static int32_t stbSplAppendWEnd(SWindowLogicNode* pWin, int32_t* pIndex) { if (NULL == pWEnd) { return TSDB_CODE_OUT_OF_MEMORY; } - strcpy(pWEnd->functionName, "_wendts"); + strcpy(pWEnd->functionName, "_wend"); snprintf(pWEnd->node.aliasName, sizeof(pWEnd->node.aliasName), "%s.%p", pWEnd->functionName, pWEnd); int32_t code = fmGetFuncInfo(pWEnd, NULL, 0); if (TSDB_CODE_SUCCESS == code) { diff --git a/source/libs/planner/test/planBasicTest.cpp b/source/libs/planner/test/planBasicTest.cpp index c99e4ea866..2379ea262a 100644 --- a/source/libs/planner/test/planBasicTest.cpp +++ b/source/libs/planner/test/planBasicTest.cpp @@ -137,6 +137,12 @@ TEST_F(PlanBasicTest, sampleFunc) { run("SELECT SAMPLE(c1, 10) FROM st1 PARTITION BY TBNAME"); } +TEST_F(PlanBasicTest, pseudoColumn) { + useDb("root", "test"); + + run("SELECT _QSTART, _QEND, _QDURATION FROM t1"); +} + TEST_F(PlanBasicTest, withoutFrom) { useDb("root", "test"); diff --git a/source/libs/planner/test/planIntervalTest.cpp b/source/libs/planner/test/planIntervalTest.cpp index 73fa898bf8..9f34ead6ff 100644 --- a/source/libs/planner/test/planIntervalTest.cpp +++ b/source/libs/planner/test/planIntervalTest.cpp @@ -29,7 +29,7 @@ TEST_F(PlanIntervalTest, basic) { TEST_F(PlanIntervalTest, pseudoCol) { useDb("root", "test"); - run("SELECT _WSTARTTS, _WDURATION, _WENDTS, COUNT(*) FROM t1 INTERVAL(10s)"); + run("SELECT _WSTART, _WDURATION, _WEND, COUNT(*) FROM t1 INTERVAL(10s)"); } TEST_F(PlanIntervalTest, fill) { @@ -59,9 +59,9 @@ TEST_F(PlanIntervalTest, stable) { run("SELECT COUNT(*) FROM st1 INTERVAL(10s)"); - run("SELECT _WSTARTTS, COUNT(*) FROM st1 INTERVAL(10s)"); + run("SELECT _WSTART, COUNT(*) FROM st1 INTERVAL(10s)"); - run("SELECT _WSTARTTS, COUNT(*) FROM st1 PARTITION BY TBNAME INTERVAL(10s)"); + run("SELECT _WSTART, COUNT(*) FROM st1 PARTITION BY TBNAME INTERVAL(10s)"); run("SELECT TBNAME, COUNT(*) FROM st1 PARTITION BY TBNAME INTERVAL(10s)"); } diff --git a/source/libs/planner/test/planOptimizeTest.cpp b/source/libs/planner/test/planOptimizeTest.cpp index 316148df27..75b4aa0dc1 100644 --- a/source/libs/planner/test/planOptimizeTest.cpp +++ b/source/libs/planner/test/planOptimizeTest.cpp @@ -55,7 +55,7 @@ TEST_F(PlanOptimizeTest, sortPrimaryKey) { run("SELECT c1 FROM t1 ORDER BY ts DESC"); - run("SELECT COUNT(*) FROM t1 INTERVAL(10S) ORDER BY _WSTARTTS DESC"); + run("SELECT COUNT(*) FROM t1 INTERVAL(10S) ORDER BY _WSTART DESC"); } TEST_F(PlanOptimizeTest, PartitionTags) { diff --git a/source/libs/planner/test/planOtherTest.cpp b/source/libs/planner/test/planOtherTest.cpp index 6add1cf630..7107f8b3c9 100644 --- a/source/libs/planner/test/planOtherTest.cpp +++ b/source/libs/planner/test/planOtherTest.cpp @@ -49,7 +49,7 @@ TEST_F(PlanOtherTest, createSmaIndex) { run("SELECT SUM(c4) FROM t1 INTERVAL(10s)"); - run("SELECT _WSTARTTS, MIN(c3 + 10) FROM t1 " + run("SELECT _WSTART, MIN(c3 + 10) FROM t1 " "WHERE ts BETWEEN TIMESTAMP '2022-04-01 00:00:00' AND TIMESTAMP '2022-04-30 23:59:59.999' INTERVAL(10s)"); run("SELECT SUM(c4), MAX(c3) FROM t1 INTERVAL(10s)"); diff --git a/tests/pytest/stream/test1.py b/tests/pytest/stream/test1.py index d3439a7bdb..31e70c21d2 100644 --- a/tests/pytest/stream/test1.py +++ b/tests/pytest/stream/test1.py @@ -18,7 +18,7 @@ class TDTestCase: tdSql.execute('create table ownsampling_ct1 using downsampling_stb tags(10, 10.1, "beijing", True);') tdSql.execute('create table if not exists scalar_stb (ts timestamp, c1 int, c2 double, c3 binary(20)) tags (t1 int);') tdSql.execute('create table scalar_ct1 using scalar_stb tags(10);') - tdSql.execute('create stream downsampling_stream into output_downsampling_stb as select _wstartts AS start, min(c1), max(c2), sum(c1) from downsampling_stb interval(10m);') + tdSql.execute('create stream downsampling_stream into output_downsampling_stb as select _wstart AS start, min(c1), max(c2), sum(c1) from downsampling_stb interval(10m);') tdSql.execute('create stream scalar_stream into output_scalar_stb as select ts, abs(c1) a1 , abs(c2) a2 from scalar_stb;') tdSql.execute('insert into scalar_ct1 values (1653471881952, 100, 100.1, "beijing");') tdSql.execute('insert into scalar_ct1 values (1653471881952+1s, -50, -50.1, "tianjin");') diff --git a/tests/pytest/stream/test2.py b/tests/pytest/stream/test2.py index a441174722..e6044662e9 100644 --- a/tests/pytest/stream/test2.py +++ b/tests/pytest/stream/test2.py @@ -22,23 +22,23 @@ class TDTestCase: tdSql.execute('create table downsampling_ct1 using downsampling_stb tags(10, 10.1, "Beijing", True);') tdSql.execute('create table if not exists scalar_stb (ts timestamp, c1 int, c2 double, c3 binary(20), c4 nchar(20), c5 nchar(20)) tags (t1 int);') tdSql.execute('create table scalar_ct1 using scalar_stb tags(10);') - tdSql.execute('create stream downsampling_stream into output_downsampling_stb as select _wstartts AS start, min(c1), max(c2), sum(c1) from downsampling_stb interval(10m);') + tdSql.execute('create stream downsampling_stream into output_downsampling_stb as select _wstart AS start, min(c1), max(c2), sum(c1) from downsampling_stb interval(10m);') tdSql.execute('insert into downsampling_ct1 values (1653547828591, 100, 100.1, "Beijing", True);') tdSql.execute('insert into downsampling_ct1 values (1653547828591+1s, -100, -100.1, "Tianjin", False);') tdSql.execute('insert into downsampling_ct1 values (1653547828591+2s, 50, 50.3, "HeBei", False);') tdSql.execute('select * from output_downsampling_stb;') tdSql.execute('select start, `min(c1)`, `max(c2)`, `sum(c1)` from output_downsampling_stb;') - tdSql.execute('select _wstartts AS start, min(c1), max(c2), sum(c1) from downsampling_stb interval(10m);') + tdSql.execute('select _wstart AS start, min(c1), max(c2), sum(c1) from downsampling_stb interval(10m);') tdSql.execute('insert into downsampling_ct1 values (1653547828591+10m, 60, 60.3, "heilongjiang", True);') tdSql.execute('insert into downsampling_ct1 values (1653547828591+11m, 70, 70.3, "JiLin", True);') tdSql.execute('select * from output_downsampling_stb;') tdSql.execute('select start, `min(c1)`, `max(c2)`, `sum(c1)` from output_downsampling_stb;') - tdSql.execute('select _wstartts AS start, min(c1), max(c2), sum(c1) from downsampling_stb interval(10m);') + tdSql.execute('select _wstart AS start, min(c1), max(c2), sum(c1) from downsampling_stb interval(10m);') tdSql.execute('insert into downsampling_ct1 values (1653547828591+21m, 70, 70.3, "JiLin", True);') tdSql.execute('select * from output_downsampling_stb;') tdSql.execute('select * from output_downsampling_stb;') tdSql.execute('select start, `min(c1)`, `max(c2)`, `sum(c1)` from output_downsampling_stb;') - tdSql.execute('select _wstartts AS start, min(c1), max(c2), sum(c1) from downsampling_stb interval(10m);') + tdSql.execute('select _wstart AS start, min(c1), max(c2), sum(c1) from downsampling_stb interval(10m);') tdSql.execute('create stream abs_stream into output_abs_stb as select ts, abs(c1), abs(c2), c3 from scalar_stb;') tdSql.query('describe output_abs_stb') tdSql.execute('create stream acos_stream into output_acos_stb as select ts, acos(c1), acos(c2), c3 from scalar_stb;') diff --git a/tests/script/tsim/query/interval-offset.sim b/tests/script/tsim/query/interval-offset.sim index ab6ee79d6e..b6dffb5fe3 100644 --- a/tests/script/tsim/query/interval-offset.sim +++ b/tests/script/tsim/query/interval-offset.sim @@ -68,8 +68,8 @@ sql insert into ct4 values ( '2022-12-01 01:01:30.000', 8 ) sql insert into ct4 values ( '2022-12-31 01:01:36.000', 9 ) print ================ start query ====================== -sql select _wstartts, _wendts, _wduration, _qstartts, _qendts, count(*) from ct1 interval(10s, 2s) -print ===> select _wstartts, _wendts, _wduration, _qstartts, _qendts, count(*) from ct1 interval(10s, 2s) +sql select _wstart, _wend, _wduration, _qstart, _qend, count(*) from ct1 interval(10s, 2s) +print ===> select _wstart, _wend, _wduration, _qstart, _qend, count(*) from ct1 interval(10s, 2s) print ===> rows: $rows print ===> rows0: $data00 $data01 $data02 $data05 print ===> rows1: $data10 $data11 $data12 $data15 @@ -89,8 +89,8 @@ if $data45 != 1 then return -1 endi -sql select _wstartts, _wendts, _wduration, _qstartts, _qendts, count(*) from ct1 interval(10s, 2s) sliding(10s) -print ===> select _wstartts, _wendts, _wduration, _qstartts, _qendts, count(*) from ct1 interval(10s, 2s) sliding(10s) +sql select _wstart, _wend, _wduration, _qstart, _qend, count(*) from ct1 interval(10s, 2s) sliding(10s) +print ===> select _wstart, _wend, _wduration, _qstart, _qend, count(*) from ct1 interval(10s, 2s) sliding(10s) print ===> rows: $rows print ===> rows0: $data00 $data01 $data02 $data05 print ===> rows1: $data10 $data11 $data12 $data15 @@ -177,7 +177,7 @@ if $data70 != 1 then return -1 endi -sql select _wstartts, count(tbcol), _wduration, _wstartts, count(*) from ct3 interval(1n, 1w) +sql select _wstart, count(tbcol), _wduration, _wstart, count(*) from ct3 interval(1n, 1w) print ===> select count(tbcol), sum(tbcol), max(tbcol), min(tbcol), count(*) from ct3 interval(1n, 1w) print ===> rows: $rows print ===> rows0: $data00 $data01 $data02 $data03 $data04 @@ -200,11 +200,11 @@ if $data02 != 2678400000 then return -1 endi -sql_error select _wstartts, count(tbcol), _wduration, _wstartts, count(*) from ct3 interval(1n, 1w) sliding(2w) -sql_error select _wstartts, count(tbcol), _wduration, _wstartts, count(*) from ct3 interval(1n, 1w) sliding(4w) +sql_error select _wstart, count(tbcol), _wduration, _wstart, count(*) from ct3 interval(1n, 1w) sliding(2w) +sql_error select _wstart, count(tbcol), _wduration, _wstart, count(*) from ct3 interval(1n, 1w) sliding(4w) -sql select _wstartts, count(tbcol), _wduration, _wstartts, count(*) from ct4 interval(1y, 6n) -print ===> select _wstartts, count(tbcol), _wduration, _wstartts, count(*) from ct4 interval(1y, 6n) +sql select _wstart, count(tbcol), _wduration, _wstart, count(*) from ct4 interval(1y, 6n) +print ===> select _wstart, count(tbcol), _wduration, _wstart, count(*) from ct4 interval(1y, 6n) print ===> rows: $rows print ===> rows0: $data00 $data01 $data02 $data03 $data04 print ===> rows1: $data10 $data11 $data12 $data13 $data14 @@ -220,7 +220,7 @@ if $data04 != 2 then endi sql_error select count(tbcol), sum(tbcol), max(tbcol), min(tbcol), count(*) from ct4 interval(1y, 6n) sliding(6n) -sql_error select _wstartts, count(tbcol), _wduration, _wstartts, count(*) from ct4 interval(1y, 6n) sliding(12n) +sql_error select _wstart, count(tbcol), _wduration, _wstart, count(*) from ct4 interval(1y, 6n) sliding(12n) #================================================= print =============== stop and restart taosd diff --git a/tests/script/tsim/query/interval.sim b/tests/script/tsim/query/interval.sim index 9d7104c3de..280a66de00 100644 --- a/tests/script/tsim/query/interval.sim +++ b/tests/script/tsim/query/interval.sim @@ -82,8 +82,8 @@ print =============== step4 #$cc = 1 * 60000 #$ms2 = 1601481600000 - $cc -sql select _wstartts, _wendts, _wduration, _qstartts, _qendts, count(tbcol) from $tb interval(1m) -print ===> select _wstartts, _wendts, _wduration, _qstartts, _qendts, count(tbcol) from $tb interval(1m) +sql select _wstart, _wend, _wduration, _qstart, _qend, count(tbcol) from $tb interval(1m) +print ===> select _wstart, _wend, _wduration, _qstart, _qend, count(tbcol) from $tb interval(1m) print ===> $rows $data01 $data05 if $rows != $rowNum then return -1 diff --git a/tests/script/tsim/query/session.sim b/tests/script/tsim/query/session.sim index c39956c0df..29559fdee5 100644 --- a/tests/script/tsim/query/session.sim +++ b/tests/script/tsim/query/session.sim @@ -81,7 +81,7 @@ sql use $dbNamme # session(ts,5a) print ====> select count(*) from dev_001 session(ts,5a) -sql select _wstartts, count(*) from dev_001 session(ts,5a) +sql select _wstart, count(*) from dev_001 session(ts,5a) print ====> rows: $rows print ====> $data00 $data01 $data02 $data03 $data04 $data05 print ====> $data10 $data11 $data12 $data13 $data14 $data15 @@ -102,7 +102,7 @@ endi # #print ====> select count(*) from (select * from dev_001) session(ts,5a) -#sql select _wstartts, count(*) from (select * from dev_001) session(ts,5a) +#sql select _wstart, count(*) from (select * from dev_001) session(ts,5a) #if $rows != 15 then # return -1 #endi @@ -111,7 +111,7 @@ endi #endi print ====> select count(*) from dev_001 session(ts,1s) -sql select _wstartts, count(*) from dev_001 session(ts,1s) +sql select _wstart, count(*) from dev_001 session(ts,1s) if $rows != 12 then return -1 endi @@ -120,7 +120,7 @@ if $data01 != 5 then endi #print ====> select count(*) from (select * from dev_001) session(ts,1s) -#sql select _wstartts, count(*) from (select * from dev_001) session(ts,1s) +#sql select _wstart, count(*) from (select * from dev_001) session(ts,1s) #if $rows != 12 then # return -1 #endi @@ -129,7 +129,7 @@ endi #endi print ====> select count(*) from dev_001 session(ts,1000a) -sql select _wstartts, count(*) from dev_001 session(ts,1000a) +sql select _wstart, count(*) from dev_001 session(ts,1000a) if $rows != 12 then return -1 endi @@ -138,7 +138,7 @@ if $data01 != 5 then endi #print ====> select count(*) from (select * from dev_001) session(ts,1000a) -#sql select _wstartts, count(*) from (select * from dev_001) session(ts,1000a) +#sql select _wstart, count(*) from (select * from dev_001) session(ts,1000a) #if $rows != 12 then # return -1 #endi @@ -147,7 +147,7 @@ endi #endi print ====> select count(*) from dev_001 session(ts,1m) -sql select _wstartts, count(*) from dev_001 session(ts,1m) +sql select _wstart, count(*) from dev_001 session(ts,1m) if $rows != 9 then return -1 endi @@ -156,7 +156,7 @@ if $data01 != 8 then endi #print ====> select count(*) from (select * from dev_001) session(ts,1m) -#sql select _wstartts, count(*) from (select * from dev_001) session(ts,1m) +#sql select _wstart, count(*) from (select * from dev_001) session(ts,1m) #if $rows != 9 then # return -1 #endi @@ -165,7 +165,7 @@ endi #endi print ====> select count(*) from dev_001 session(ts,1h) -sql select _wstartts, count(*) from dev_001 session(ts,1h) +sql select _wstart, count(*) from dev_001 session(ts,1h) if $rows != 6 then return -1 endi @@ -174,7 +174,7 @@ if $data01 != 11 then endi #print ====> select count(*) from (select * from dev_001) session(ts,1h) -#sql select _wstartts, count(*) from (select * from dev_001) session(ts,1h) +#sql select _wstart, count(*) from (select * from dev_001) session(ts,1h) #if $rows != 6 then # return -1 #endi @@ -183,7 +183,7 @@ endi #endi print ====> select count(*) from dev_001 session(ts,1d) -sql select _wstartts, count(*) from dev_001 session(ts,1d) +sql select _wstart, count(*) from dev_001 session(ts,1d) if $rows != 4 then return -1 endi @@ -192,7 +192,7 @@ if $data01 != 13 then endi #print ====> select count(*) from (select * from dev_001) session(ts,1d) -#sql select _wstartts, count(*) from (select * from dev_001) session(ts,1d) +#sql select _wstart, count(*) from (select * from dev_001) session(ts,1d) #if $rows != 4 then # return -1 #endi @@ -201,7 +201,7 @@ endi #endi print ====> select count(*) from dev_001 session(ts,1w) -sql select _wstartts, count(*) from dev_001 session(ts,1w) +sql select _wstart, count(*) from dev_001 session(ts,1w) if $rows != 2 then return -1 endi @@ -210,7 +210,7 @@ if $data01 != 15 then endi #print ====> select count(*) from (select * from dev_001) session(ts,1w) -#sql select _wstartts, count(*) from (select * from dev_001) session(ts,1w) +#sql select _wstart, count(*) from (select * from dev_001) session(ts,1w) #if $rows != 2 then # return -1 #endi @@ -298,7 +298,7 @@ sql_error select count(*) from dev_001 session(i,1y) sql_error select count(*) from dev_001 session(ts,1d) where ts <'2020-05-20 0:0:0' #print ====> select count(*) from dev_001 session(ts,1u) -#sql select _wstartts, count(*) from dev_001 session(ts,1u) +#sql select _wstart, count(*) from dev_001 session(ts,1u) #print rows: $rows #print $data00 $data01 $data02 $data03 #print $data10 $data11 $data12 $data13 diff --git a/tests/script/tsim/query/stddev.sim b/tests/script/tsim/query/stddev.sim index 74bc444da2..15041623bc 100644 --- a/tests/script/tsim/query/stddev.sim +++ b/tests/script/tsim/query/stddev.sim @@ -103,29 +103,29 @@ if $rows != 1 then return -1 endi -print =====sql : select _wstartts, stddev(c1) as b from ct4 interval(1y) -sql select _wstartts, stddev(c1) as b from ct4 interval(1y) +print =====sql : select _wstart, stddev(c1) as b from ct4 interval(1y) +sql select _wstart, stddev(c1) as b from ct4 interval(1y) print ===> $rows if $rows != 4 then return -1 endi -print =====sql : select _wstartts, stddev(c1) as b from t1 interval(1y) -sql select _wstartts, stddev(c1) as b from t1 interval(1y) +print =====sql : select _wstart, stddev(c1) as b from t1 interval(1y) +sql select _wstart, stddev(c1) as b from t1 interval(1y) print ===> $rows if $rows != 3 then return -1 endi -print =====select _wstartts, stddev(c1) as b from ct4 where c1 <= 6 interval(180d) -sql select _wstartts, stddev(c1) as b from ct4 where c1 <= 6 interval(180d) +print =====select _wstart, stddev(c1) as b from ct4 where c1 <= 6 interval(180d) +sql select _wstart, stddev(c1) as b from ct4 where c1 <= 6 interval(180d) # print ===> $rows # if $rows != 3 then # return -1 # endi -print =====select _wstartts, stddev(c1) as b from t1 where c1 <= 6 interval(180d) -sql select _wstartts, stddev(c1) as b from t1 where c1 <= 6 interval(180d) +print =====select _wstart, stddev(c1) as b from t1 where c1 <= 6 interval(180d) +sql select _wstart, stddev(c1) as b from t1 where c1 <= 6 interval(180d) # print ===> $rows # if $rows != 3 then # return -1 @@ -281,29 +281,29 @@ if $rows != 1 then return -1 endi -print =====sql : select _wstartts, stddev(c1) as b from ct4 interval(1y) -sql select _wstartts, stddev(c1) as b from ct4 interval(1y) +print =====sql : select _wstart, stddev(c1) as b from ct4 interval(1y) +sql select _wstart, stddev(c1) as b from ct4 interval(1y) print ===> $rows if $rows != 4 then return -1 endi -print =====sql : select _wstartts, stddev(c1) as b from t1 interval(1y) -sql select _wstartts, stddev(c1) as b from t1 interval(1y) +print =====sql : select _wstart, stddev(c1) as b from t1 interval(1y) +sql select _wstart, stddev(c1) as b from t1 interval(1y) print ===> $rows if $rows != 3 then return -1 endi -print =====select _wstartts, stddev(c1) as b from ct4 where c1 <= 6 interval(180d) -sql select _wstartts, stddev(c1) as b from ct4 where c1 <= 6 interval(180d) +print =====select _wstart, stddev(c1) as b from ct4 where c1 <= 6 interval(180d) +sql select _wstart, stddev(c1) as b from ct4 where c1 <= 6 interval(180d) print ===> $rows if $rows != 3 then return -1 endi -print =====select _wstartts, stddev(c1) as b from t1 where c1 <= 6 interval(180d) -sql select _wstartts, stddev(c1) as b from t1 where c1 <= 6 interval(180d) +print =====select _wstart, stddev(c1) as b from t1 where c1 <= 6 interval(180d) +sql select _wstart, stddev(c1) as b from t1 where c1 <= 6 interval(180d) print ===> $rows if $rows != 3 then return -1 diff --git a/tests/script/tsim/sma/tsmaCreateInsertQuery.sim b/tests/script/tsim/sma/tsmaCreateInsertQuery.sim index 3a1ed62a72..6cca47423a 100644 --- a/tests/script/tsim/sma/tsmaCreateInsertQuery.sim +++ b/tests/script/tsim/sma/tsmaCreateInsertQuery.sim @@ -58,7 +58,7 @@ if $rows != 5 then endi print =============== select * from stb from memory in designated vgroup -sql select _wstartts, _wendts, min(c1),max(c2),max(c1) from stb interval(5m,10s) sliding(5m); +sql select _wstart, _wend, min(c1),max(c2),max(c1) from stb interval(5m,10s) sliding(5m); print $data00 $data01 $data02 $data03 $data04 if $rows != 1 then print rows $rows != 1 @@ -81,7 +81,7 @@ if $data04 != 20 then endi print =============== select * from stb from memory in common vgroups -sql select _wstartts, _wendts, min(c1),max(c2),max(c1),max(c3) from stb interval(5m,10s) sliding(5m); +sql select _wstart, _wend, min(c1),max(c2),max(c1),max(c3) from stb interval(5m,10s) sliding(5m); print $data00 $data01 $data02 $data03 $data04 $data05 if $rows != 1 then print rows $rows != 1 @@ -128,7 +128,7 @@ if $rows != 5 then endi print =============== select * from stb from file in designated vgroup -sql select _wstartts, _wendts, min(c1),max(c2),max(c1) from stb interval(5m,10s) sliding(5m); +sql select _wstart, _wend, min(c1),max(c2),max(c1) from stb interval(5m,10s) sliding(5m); print $data00 $data01 $data02 $data03 $data04 if $rows != 1 then print rows $rows != 1 @@ -151,7 +151,7 @@ if $data04 != 20 then endi print =============== select * from stb from file in common vgroups -sql select _wstartts, _wendts, min(c1),max(c2),max(c1),max(c3) from stb interval(5m,10s) sliding(5m); +sql select _wstart, _wend, min(c1),max(c2),max(c1),max(c3) from stb interval(5m,10s) sliding(5m); print $data00 $data01 $data02 $data03 $data04 $data05 if $rows != 1 then print rows $rows != 1 diff --git a/tests/script/tsim/stream/basic0.sim b/tests/script/tsim/stream/basic0.sim index 29775a5ef1..61f7a57dcf 100644 --- a/tests/script/tsim/stream/basic0.sim +++ b/tests/script/tsim/stream/basic0.sim @@ -33,7 +33,7 @@ if $rows != 3 then return -1 endi -sql create stream s1 trigger at_once into outstb as select _wstartts, min(k), max(k), sum(k) as sum_alias from ct1 interval(10m) +sql create stream s1 trigger at_once into outstb as select _wstart, min(k), max(k), sum(k) as sum_alias from ct1 interval(10m) sql show stables if $rows != 2 then @@ -48,7 +48,7 @@ sleep 100 #=================================================================== print =============== query data from child table -sql select `_wstartts`,`min(k)`,`max(k)`,sum_alias from outstb +sql select `_wstart`,`min(k)`,`max(k)`,sum_alias from outstb print rows: $rows print $data00 $data01 $data02 $data03 if $rows != 1 then @@ -77,7 +77,7 @@ sleep 100 #=================================================================== print =============== query data from child table -sql select `_wstartts`,`min(k)`,`max(k)`,sum_alias from outstb +sql select `_wstart`,`min(k)`,`max(k)`,sum_alias from outstb print rows: $rows print $data00 $data01 $data02 $data03 if $rows != 1 then @@ -105,7 +105,7 @@ sleep 100 #=================================================================== print =============== query data from child table -sql select `_wstartts`,`min(k)`,`max(k)`,sum_alias from outstb +sql select `_wstart`,`min(k)`,`max(k)`,sum_alias from outstb print rows: $rows print $data00 $data01 $data02 $data03 print $data10 $data11 $data12 $data13 diff --git a/tests/script/tsim/stream/basic1.sim b/tests/script/tsim/stream/basic1.sim index 8e6391eb0b..2a6d64bcaf 100644 --- a/tests/script/tsim/stream/basic1.sim +++ b/tests/script/tsim/stream/basic1.sim @@ -17,14 +17,14 @@ sql use test sql create table t1(ts timestamp, a int, b int , c int, d double); -sql create stream streams1 trigger at_once into streamt as select _wstartts, count(*) c1, count(d) c2 , sum(a) c3 , max(b) c4, min(c) c5 from t1 interval(10s); +sql create stream streams1 trigger at_once into streamt as select _wstart, count(*) c1, count(d) c2 , sum(a) c3 , max(b) c4, min(c) c5 from t1 interval(10s); sql insert into t1 values(1648791213000,1,2,3,1.0); sql insert into t1 values(1648791223001,2,2,3,1.1); sql insert into t1 values(1648791233002,3,2,3,2.1); sql insert into t1 values(1648791243003,4,2,3,3.1); sql insert into t1 values(1648791213004,4,2,3,4.1); sleep 1000 -sql select `_wstartts`, c1, c2 ,c3 ,c4, c5 from streamt; +sql select `_wstart`, c1, c2 ,c3 ,c4, c5 from streamt; if $rows != 4 then print ======$rows @@ -254,7 +254,7 @@ endi sql insert into t1 values(1648791223002,12,14,13,11.1); sleep 100 -sql select `_wstartts`, c1, c2 ,c3 ,c4, c5 from streamt; +sql select `_wstart`, c1, c2 ,c3 ,c4, c5 from streamt; # row 1 if $data11 != 2 then @@ -284,7 +284,7 @@ endi sql insert into t1 values(1648791223003,12,14,13,11.1); sleep 100 -sql select `_wstartts`, c1, c2 ,c3 ,c4, c5 from streamt; +sql select `_wstart`, c1, c2 ,c3 ,c4, c5 from streamt; # row 1 if $data11 != 3 then @@ -316,7 +316,7 @@ sql insert into t1 values(1648791223001,1,1,1,1.1); sql insert into t1 values(1648791223002,2,2,2,2.1); sql insert into t1 values(1648791223003,3,3,3,3.1); sleep 100 -sql select `_wstartts`, c1, c2 ,c3 ,c4, c5 from streamt; +sql select `_wstart`, c1, c2 ,c3 ,c4, c5 from streamt; # row 1 if $data11 != 3 then @@ -348,7 +348,7 @@ sql insert into t1 values(1648791233003,3,2,3,2.1); sql insert into t1 values(1648791233002,5,6,7,8.1); sql insert into t1 values(1648791233002,3,2,3,2.1); sleep 100 -sql select `_wstartts`, c1, c2 ,c3 ,c4, c5 from streamt; +sql select `_wstart`, c1, c2 ,c3 ,c4, c5 from streamt; # row 2 if $data21 != 2 then @@ -378,7 +378,7 @@ endi sql insert into t1 values(1648791213004,4,2,3,4.1) (1648791213006,5,4,7,9.1) (1648791213004,40,20,30,40.1) (1648791213005,4,2,3,4.1); sleep 100 -sql select `_wstartts`, c1, c2 ,c3 ,c4, c5 from streamt; +sql select `_wstart`, c1, c2 ,c3 ,c4, c5 from streamt; # row 0 if $data01 != 4 then @@ -408,7 +408,7 @@ endi sql insert into t1 values(1648791223004,4,2,3,4.1) (1648791233006,5,4,7,9.1) (1648791223004,40,20,30,40.1) (1648791233005,4,2,3,4.1); sleep 100 -sql select `_wstartts`, c1, c2 ,c3 ,c4, c5 from streamt; +sql select `_wstart`, c1, c2 ,c3 ,c4, c5 from streamt; # row 1 if $data11 != 4 then diff --git a/tests/script/tsim/stream/basic2.sim b/tests/script/tsim/stream/basic2.sim index 247d8f62ee..1a6c7c5c25 100644 --- a/tests/script/tsim/stream/basic2.sim +++ b/tests/script/tsim/stream/basic2.sim @@ -33,7 +33,7 @@ if $rows != 3 then return -1 endi -sql create stream s1 trigger at_once into outstb as select _wstartts, min(k), max(k), sum(k) as sum_alias from ct1 interval(10m) +sql create stream s1 trigger at_once into outstb as select _wstart, min(k), max(k), sum(k) as sum_alias from ct1 interval(10m) sql show stables if $rows != 2 then @@ -48,7 +48,7 @@ sleep 100 #=================================================================== print =============== query data from child table -sql select `_wstartts`,`min(k)`,`max(k)`,sum_alias from outstb +sql select `_wstart`,`min(k)`,`max(k)`,sum_alias from outstb print rows: $rows print $data00 $data01 $data02 $data03 if $rows != 1 then @@ -77,7 +77,7 @@ sleep 100 #=================================================================== print =============== query data from child table -sql select `_wstartts`,`min(k)`,`max(k)`,sum_alias from outstb +sql select `_wstart`,`min(k)`,`max(k)`,sum_alias from outstb print rows: $rows print $data00 $data01 $data02 $data03 print $data10 $data11 $data12 $data13 diff --git a/tests/script/tsim/stream/distributeInterval0.sim b/tests/script/tsim/stream/distributeInterval0.sim index ab2ca92c86..1ee72527e9 100644 --- a/tests/script/tsim/stream/distributeInterval0.sim +++ b/tests/script/tsim/stream/distributeInterval0.sim @@ -41,7 +41,7 @@ sql create table ts1 using st tags(1,1,1); sql create table ts2 using st tags(2,2,2); sql create table ts3 using st tags(3,2,2); sql create table ts4 using st tags(4,2,2); -sql create stream stream_t1 trigger at_once watermark 1d into streamtST1 as select _wstartts, count(*) c1, count(d) c2 , sum(a) c3 , max(b) c4, min(c) c5 from st interval(10s); +sql create stream stream_t1 trigger at_once watermark 1d into streamtST1 as select _wstart, count(*) c1, count(d) c2 , sum(a) c3 , max(b) c4, min(c) c5 from st interval(10s); sleep 1000 @@ -195,7 +195,7 @@ if $data35 != 3 then return -1 endi -sql select _wstartts, count(*) c1, count(d) c2 , sum(a) c3 , max(b) c4, min(c) c5, avg(d) from st interval(10s); +sql select _wstart, count(*) c1, count(d) c2 , sum(a) c3 , max(b) c4, min(c) c5, avg(d) from st interval(10s); sql create database test1 vgroups 1; @@ -203,7 +203,7 @@ sql use test1; sql create stable st(ts timestamp, a int, b int , c int) tags(ta int,tb int,tc int); sql create table ts1 using st tags(1,1,1); sql create table ts2 using st tags(2,2,2); -sql create stream stream_t2 trigger at_once watermark 20s into streamtST1 as select _wstartts, count(*) c1, count(a) c2 , sum(a) c3 , max(b) c5, min(c) c6 from st interval(10s) ; +sql create stream stream_t2 trigger at_once watermark 20s into streamtST1 as select _wstart, count(*) c1, count(a) c2 , sum(a) c3 , max(b) c5, min(c) c6 from st interval(10s) ; sql insert into ts1 values(1648791211000,1,2,3); sql insert into ts1 values(1648791222001,2,2,3); diff --git a/tests/script/tsim/stream/distributeIntervalRetrive0.sim b/tests/script/tsim/stream/distributeIntervalRetrive0.sim index cde5c7058f..15d9e3b186 100644 --- a/tests/script/tsim/stream/distributeIntervalRetrive0.sim +++ b/tests/script/tsim/stream/distributeIntervalRetrive0.sim @@ -41,7 +41,7 @@ sql create table ts1 using st tags(1,1,1); sql create table ts2 using st tags(2,2,2); sql create table ts3 using st tags(3,2,2); sql create table ts4 using st tags(4,2,2); -sql create stream stream_t1 trigger at_once into streamtST1 as select _wstartts, count(*) c1, sum(a) c3 , max(b) c4, min(c) c5 from st interval(10s); +sql create stream stream_t1 trigger at_once into streamtST1 as select _wstart, count(*) c1, sum(a) c3 , max(b) c4, min(c) c5 from st interval(10s); sleep 1000 diff --git a/tests/script/tsim/stream/distributeSession0.sim b/tests/script/tsim/stream/distributeSession0.sim index 30c3c641d4..190304ff19 100644 --- a/tests/script/tsim/stream/distributeSession0.sim +++ b/tests/script/tsim/stream/distributeSession0.sim @@ -39,7 +39,7 @@ sql use test; sql create stable st(ts timestamp,a int,b int,c int) tags(ta int,tb int,tc int); sql create table ts1 using st tags(1,1,1); sql create table ts2 using st tags(2,2,2); -sql create stream stream_t1 trigger at_once into streamtST as select _wstartts, count(*) c1, sum(a) c2 , max(b) c3 from st session(ts, 10s) ; +sql create stream stream_t1 trigger at_once into streamtST as select _wstart, count(*) c1, sum(a) c2 , max(b) c3 from st session(ts, 10s) ; sleep 1000 diff --git a/tests/script/tsim/stream/ignoreExpiredData.sim b/tests/script/tsim/stream/ignoreExpiredData.sim index c6b708d1e8..a3b14c4f7a 100644 --- a/tests/script/tsim/stream/ignoreExpiredData.sim +++ b/tests/script/tsim/stream/ignoreExpiredData.sim @@ -45,9 +45,9 @@ print $data00 $data01 $data02 sql use test sql create table t1(ts timestamp, a int, b int , c int, d double); -sql create stream streams1 trigger at_once IGNORE EXPIRED into streamt1 as select _wstartts, count(*) c1, sum(a) c3 from t1 interval(10s); -sql create stream streams2 trigger at_once IGNORE EXPIRED into streamt2 as select _wstartts, count(*) c1, sum(a) c3 from t1 session(ts,10s); -sql create stream streams3 trigger at_once IGNORE EXPIRED into streamt3 as select _wstartts, count(*) c1, sum(a) c3 from t1 state_window(a); +sql create stream streams1 trigger at_once IGNORE EXPIRED into streamt1 as select _wstart, count(*) c1, sum(a) c3 from t1 interval(10s); +sql create stream streams2 trigger at_once IGNORE EXPIRED into streamt2 as select _wstart, count(*) c1, sum(a) c3 from t1 session(ts,10s); +sql create stream streams3 trigger at_once IGNORE EXPIRED into streamt3 as select _wstart, count(*) c1, sum(a) c3 from t1 state_window(a); sql insert into t1 values(1648791213000,1,2,3,1.0); sql insert into t1 values(1648791223001,1,2,3,1.1); sql insert into t1 values(1648791233002,2,2,3,2.1); @@ -111,8 +111,8 @@ sql use test1 sql create stable st(ts timestamp,a int,b int,c int) tags(ta int,tb int,tc int); sql create table ts1 using st tags(1,1,1); sql create table ts2 using st tags(2,2,2); -sql create stream stream_t1 trigger at_once IGNORE EXPIRED into streamtST1 as select _wstartts, count(*) c1, count(a) c2 , sum(a) c3 , max(b) c5, min(c) c6 from st interval(10s) ; -sql create stream stream_t2 trigger at_once IGNORE EXPIRED into streamtST2 as select _wstartts, count(*) c1, count(a) c2 , sum(a) c3 , max(b) c5, min(c) c6 from st session(ts, 10s) ; +sql create stream stream_t1 trigger at_once IGNORE EXPIRED into streamtST1 as select _wstart, count(*) c1, count(a) c2 , sum(a) c3 , max(b) c5, min(c) c6 from st interval(10s) ; +sql create stream stream_t2 trigger at_once IGNORE EXPIRED into streamtST2 as select _wstart, count(*) c1, count(a) c2 , sum(a) c3 , max(b) c5, min(c) c6 from st session(ts, 10s) ; sql insert into ts1 values(1648791211000,1,2,3); sql insert into ts1 values(1648791222001,2,2,3); sql insert into ts2 values(1648791211000,1,2,3); diff --git a/tests/script/tsim/stream/partitionby.sim b/tests/script/tsim/stream/partitionby.sim index c634ad85ee..e5e02c3873 100644 --- a/tests/script/tsim/stream/partitionby.sim +++ b/tests/script/tsim/stream/partitionby.sim @@ -11,7 +11,7 @@ sql create table ts1 using st tags(1,1,1); sql create table ts2 using st tags(2,2,2); sql create table ts3 using st tags(3,2,2); sql create table ts4 using st tags(4,2,2); -sql create stream stream_t1 trigger at_once into streamtST1 as select _wstartts, count(*) c1, count(d) c2 , sum(a) c3 , max(b) c4, min(c) c5 from st partition by ta,tb,tc interval(10s); +sql create stream stream_t1 trigger at_once into streamtST1 as select _wstart, count(*) c1, count(d) c2 , sum(a) c3 , max(b) c4, min(c) c5 from st partition by ta,tb,tc interval(10s); sql insert into ts1 values(1648791213001,1,12,3,1.0); sql insert into ts2 values(1648791213001,1,12,3,1.0); @@ -43,7 +43,7 @@ sql create table ts1 using st tags(1,2,3); sql create table ts2 using st tags(1,3,4); sql create table ts3 using st tags(1,4,5); -sql create stream streams1 trigger at_once into streamt as select _wstartts, count(*) c1, count(a) c2 from st partition by ta,tb,tc interval(10s); +sql create stream streams1 trigger at_once into streamt as select _wstart, count(*) c1, count(a) c2 from st partition by ta,tb,tc interval(10s); sql insert into ts1 values(1648791211000,1,2,3); @@ -74,7 +74,7 @@ sql create stable st(ts timestamp,a int,b int,c int,id int) tags(ta int,tb int,t sql create table ts1 using st tags(1,1,1); sql create table ts2 using st tags(2,2,2); -sql create stream stream_t2 trigger at_once watermark 20s into streamtST as select _wstartts, count(*) c1, count(a) c2 , sum(a) c3 , max(b) c5, min(c) c6, max(id) c7 from st partition by ta interval(10s) ; +sql create stream stream_t2 trigger at_once watermark 20s into streamtST as select _wstart, count(*) c1, count(a) c2 , sum(a) c3 , max(b) c5, min(c) c6, max(id) c7 from st partition by ta interval(10s) ; sql insert into ts1 values(1648791211000,1,2,3,1); sql insert into ts1 values(1648791222001,2,2,3,2); sql insert into ts2 values(1648791211000,1,2,3,3); diff --git a/tests/script/tsim/stream/partitionby1.sim b/tests/script/tsim/stream/partitionby1.sim index 3e823b05d6..b29666cad7 100644 --- a/tests/script/tsim/stream/partitionby1.sim +++ b/tests/script/tsim/stream/partitionby1.sim @@ -11,7 +11,7 @@ sql create table ts1 using st tags(1,1,1); sql create table ts2 using st tags(2,2,2); sql create table ts3 using st tags(3,2,2); sql create table ts4 using st tags(4,2,2); -sql create stream stream_t1 trigger at_once into streamtST1 as select _wstartts, count(*) c1, count(d) c2 , sum(a) c3 , max(b) c4, min(c) c5 from st partition by tbname interval(10s); +sql create stream stream_t1 trigger at_once into streamtST1 as select _wstart, count(*) c1, count(d) c2 , sum(a) c3 , max(b) c4, min(c) c5 from st partition by tbname interval(10s); sql insert into ts1 values(1648791213001,1,12,3,1.0); sql insert into ts2 values(1648791213001,1,12,3,1.0); @@ -43,7 +43,7 @@ sql create table ts1 using st tags(1,2,3); sql create table ts2 using st tags(1,3,4); sql create table ts3 using st tags(1,4,5); -sql create stream streams1 trigger at_once into streamt as select _wstartts, count(*) c1, count(a) c2 from st partition by tbname interval(10s); +sql create stream streams1 trigger at_once into streamt as select _wstart, count(*) c1, count(a) c2 from st partition by tbname interval(10s); sql insert into ts1 values(1648791211000,1,2,3); @@ -74,7 +74,7 @@ sql create stable st(ts timestamp,a int,b int,c int,id int) tags(ta int,tb int,t sql create table ts1 using st tags(1,1,1); sql create table ts2 using st tags(2,2,2); -sql create stream stream_t2 trigger at_once into streamtST as select _wstartts, count(*) c1, count(a) c2 , sum(a) c3 , max(b) c5, min(c) c6, max(id) c7 from st partition by tbname interval(10s) ; +sql create stream stream_t2 trigger at_once into streamtST as select _wstart, count(*) c1, count(a) c2 , sum(a) c3 , max(b) c5, min(c) c6, max(id) c7 from st partition by tbname interval(10s) ; sql insert into ts1 values(1648791211000,1,2,3,1); sql insert into ts1 values(1648791222001,2,2,3,2); sql insert into ts2 values(1648791211000,1,2,3,3); diff --git a/tests/script/tsim/stream/schedSnode.sim b/tests/script/tsim/stream/schedSnode.sim index dbdaaf65d0..61f01baf39 100644 --- a/tests/script/tsim/stream/schedSnode.sim +++ b/tests/script/tsim/stream/schedSnode.sim @@ -16,7 +16,7 @@ sql create table ts1 using st tags(1,1,1); sql create table ts2 using st tags(2,2,2); sql create table ts3 using st tags(3,2,2); sql create table ts4 using st tags(4,2,2); -sql create stream stream_t1 trigger at_once into target.streamtST1 as select _wstartts, count(*) c1, count(d) c2 , sum(a) c3 , max(b) c4, min(c) c5 from st interval(10s); +sql create stream stream_t1 trigger at_once into target.streamtST1 as select _wstart, count(*) c1, count(d) c2 , sum(a) c3 , max(b) c4, min(c) c5 from st interval(10s); sleep 1000 @@ -170,4 +170,4 @@ if $data35 != 3 then return -1 endi -sql select _wstartts, count(*) c1, count(d) c2 , sum(a) c3 , max(b) c4, min(c) c5, avg(d) from st interval(10s); +sql select _wstart, count(*) c1, count(d) c2 , sum(a) c3 , max(b) c4, min(c) c5, avg(d) from st interval(10s); diff --git a/tests/script/tsim/stream/session0.sim b/tests/script/tsim/stream/session0.sim index eb440d78c4..16a53d49f3 100644 --- a/tests/script/tsim/stream/session0.sim +++ b/tests/script/tsim/stream/session0.sim @@ -17,7 +17,7 @@ sql use test sql create table t1(ts timestamp, a int, b int , c int, d double,id int); -sql create stream streams1 trigger at_once into streamt as select _wstartts, count(*) c1, sum(a), max(a), min(d), stddev(a), last(a), first(d), max(id) s from t1 session(ts,10s); +sql create stream streams1 trigger at_once into streamt as select _wstart, count(*) c1, sum(a), max(a), min(d), stddev(a), last(a), first(d), max(id) s from t1 session(ts,10s); sql insert into t1 values(1648791213000,NULL,NULL,NULL,NULL,1); sql insert into t1 values(1648791223001,10,2,3,1.1,2); sql insert into t1 values(1648791233002,3,2,3,2.1,3); @@ -179,7 +179,7 @@ endi sql create database test2 vgroups 1; sql use test2; sql create table t2(ts timestamp, a int, b int , c int, d double, id int); -sql create stream streams2 trigger at_once watermark 1d into streamt2 as select _wstartts,apercentile(a,30) c1, apercentile(a,70), apercentile(a,20,"t-digest") c2, apercentile(a,60,"t-digest") c3, max(id) c4 from t2 session(ts,10s); +sql create stream streams2 trigger at_once watermark 1d into streamt2 as select _wstart,apercentile(a,30) c1, apercentile(a,70), apercentile(a,20,"t-digest") c2, apercentile(a,60,"t-digest") c3, max(id) c4 from t2 session(ts,10s); sql insert into t2 values(1648791213001,1,1,3,1.0,1); sql insert into t2 values(1648791213002,2,2,6,3.4,2); sql insert into t2 values(1648791213003,4,9,3,4.8,3); @@ -229,13 +229,13 @@ endi sql create database test3 vgroups 1; sql use test3; sql create table t1(ts timestamp, a int, b int , c int, d double); -sql create stream streams3 trigger at_once watermark 1d into streamt3 as select _wstartts, min(b), a,c from t1 session(ts,10s); -sql create stream streams4 trigger at_once watermark 1d into streamt4 as select _wstartts, max(b), a,c from t1 session(ts,10s); -# sql create stream streams5 trigger at_once watermark 1d into streamt5 as select _wstartts, top(b,3), a,c from t1 session(ts,10s); -# sql create stream streams6 trigger at_once watermark 1d into streamt6 as select _wstartts, bottom(b,3), a,c from t1 session(ts,10s); -# sql create stream streams7 trigger at_once watermark 1d into streamt7 as select _wstartts, spread(a), elapsed(ts), hyperloglog(a) from t1 session(ts,10s); -sql create stream streams7 trigger at_once watermark 1d into streamt7 as select _wstartts, spread(a), hyperloglog(a) from t1 session(ts,10s); -# sql create stream streams8 trigger at_once watermark 1d into streamt8 as select _wstartts, histogram(a,"user_input", "[1,3,5,7]", 1), histogram(a,"user_input", "[1,3,5,7]", 0) from t1 session(ts,10s); +sql create stream streams3 trigger at_once watermark 1d into streamt3 as select _wstart, min(b), a,c from t1 session(ts,10s); +sql create stream streams4 trigger at_once watermark 1d into streamt4 as select _wstart, max(b), a,c from t1 session(ts,10s); +# sql create stream streams5 trigger at_once watermark 1d into streamt5 as select _wstart, top(b,3), a,c from t1 session(ts,10s); +# sql create stream streams6 trigger at_once watermark 1d into streamt6 as select _wstart, bottom(b,3), a,c from t1 session(ts,10s); +# sql create stream streams7 trigger at_once watermark 1d into streamt7 as select _wstart, spread(a), elapsed(ts), hyperloglog(a) from t1 session(ts,10s); +sql create stream streams7 trigger at_once watermark 1d into streamt7 as select _wstart, spread(a), hyperloglog(a) from t1 session(ts,10s); +# sql create stream streams8 trigger at_once watermark 1d into streamt8 as select _wstart, histogram(a,"user_input", "[1,3,5,7]", 1), histogram(a,"user_input", "[1,3,5,7]", 0) from t1 session(ts,10s); sql insert into t1 values(1648791213001,1,1,1,1.0); sql insert into t1 values(1648791213002,2,3,2,3.4); sql insert into t1 values(1648791213003,4,9,3,4.8); diff --git a/tests/script/tsim/stream/session1.sim b/tests/script/tsim/stream/session1.sim index 347eda9bf6..12ff2a6199 100644 --- a/tests/script/tsim/stream/session1.sim +++ b/tests/script/tsim/stream/session1.sim @@ -17,7 +17,7 @@ sql use test sql create table t1(ts timestamp, a int, b int , c int, d double,id int); -sql create stream streams2 trigger at_once into streamt as select _wstartts, count(*) c1, sum(a), min(b), max(id) s from t1 session(ts,10s); +sql create stream streams2 trigger at_once into streamt as select _wstart, count(*) c1, sum(a), min(b), max(id) s from t1 session(ts,10s); sql insert into t1 values(1648791210000,1,1,1,1.1,1); sql insert into t1 values(1648791220000,2,2,2,2.1,2); sql insert into t1 values(1648791230000,3,3,3,3.1,3); diff --git a/tests/script/tsim/stream/state0.sim b/tests/script/tsim/stream/state0.sim index f98e356540..a0535cf93d 100644 --- a/tests/script/tsim/stream/state0.sim +++ b/tests/script/tsim/stream/state0.sim @@ -16,7 +16,7 @@ print $data00 $data01 $data02 sql use test sql create table t1(ts timestamp, a int, b int , c int, d double, id int); -sql create stream streams1 trigger at_once into streamt1 as select _wstartts, count(*) c1, count(d) c2 , sum(a) c3 , max(a) c4, min(c) c5, max(id) c from t1 state_window(a); +sql create stream streams1 trigger at_once into streamt1 as select _wstart, count(*) c1, count(d) c2 , sum(a) c3 , max(a) c4, min(c) c5, max(id) c from t1 state_window(a); sql insert into t1 values(1648791213000,1,2,3,1.0,1); sql insert into t1 values(1648791213000,1,2,3,1.0,2); @@ -54,7 +54,7 @@ sql insert into t1 values(1648791213000,1,2,3,1.0,5); sql insert into t1 values(1648791214000,1,2,3,1.0,6); $loop_count = 0 loop1: -sql select * from streamt1 where c >=4 order by `_wstartts`; +sql select * from streamt1 where c >=4 order by `_wstart`; sleep 300 $loop_count = $loop_count + 1 if $loop_count == 10 then @@ -163,7 +163,7 @@ sql insert into t1 values(1648791213011,1,2,3,1.0,7); $loop_count = 0 loop2: -sql select * from streamt1 where c in (5,4,7) order by `_wstartts`; +sql select * from streamt1 where c in (5,4,7) order by `_wstart`; sleep 300 $loop_count = $loop_count + 1 if $loop_count == 10 then @@ -207,7 +207,7 @@ sql insert into t1 values(1648791213011,1,2,3,1.0,8); $loop_count = 0 loop21: -sql select * from streamt1 where c in (5,4,8) order by `_wstartts`; +sql select * from streamt1 where c in (5,4,8) order by `_wstart`; sleep 300 $loop_count = $loop_count + 1 if $loop_count == 10 then @@ -227,7 +227,7 @@ sql insert into t1 values(1648791213011,10,20,10,10.0,12); $loop_count = 0 loop3: -sql select * from streamt1 where c in (5,4,10,11,12) order by `_wstartts`; +sql select * from streamt1 where c in (5,4,10,11,12) order by `_wstart`; sleep 300 $loop_count = $loop_count + 1 if $loop_count == 10 then @@ -339,7 +339,7 @@ sql insert into t1 values(1648791213030,3,14,14,14.0,15) (1648791214020,15,15,15 $loop_count = 0 loop4: -sql select * from streamt1 where c in (14,15,16) order by `_wstartts`; +sql select * from streamt1 where c in (14,15,16) order by `_wstart`; sleep 300 $loop_count = $loop_count + 1 @@ -457,7 +457,7 @@ print $data00 $data01 $data02 sql use test1 sql create table t1(ts timestamp, a int, b int , c int, d double, id int); -sql create stream streams2 trigger at_once into streamt1 as select _wstartts, count(*) c1, count(d) c2 , sum(a) c3 , max(a) c4, min(c) c5, max(id) c from t1 state_window(a); +sql create stream streams2 trigger at_once into streamt1 as select _wstart, count(*) c1, count(d) c2 , sum(a) c3 , max(a) c4, min(c) c5, max(id) c from t1 state_window(a); sql insert into t1 values(1648791212000,2,2,3,1.0,1); sql insert into t1 values(1648791213000,1,2,3,1.0,1); diff --git a/tests/script/tsim/stream/triggerInterval0.sim b/tests/script/tsim/stream/triggerInterval0.sim index 756f591f3f..db6f27ed51 100644 --- a/tests/script/tsim/stream/triggerInterval0.sim +++ b/tests/script/tsim/stream/triggerInterval0.sim @@ -15,7 +15,7 @@ print $data00 $data01 $data02 sql use test sql create table t1(ts timestamp, a int, b int , c int, d double); -sql create stream streams1 trigger window_close into streamt as select _wstartts, count(*) c1, count(d) c2 , sum(a) c3 , max(b) c4, min(c) c5 from t1 interval(10s); +sql create stream streams1 trigger window_close into streamt as select _wstart, count(*) c1, count(d) c2 , sum(a) c3 , max(b) c4, min(c) c5 from t1 interval(10s); sql insert into t1 values(1648791213001,1,2,3,1.0); sleep 300 diff --git a/tests/script/tsim/stream/triggerSession0.sim b/tests/script/tsim/stream/triggerSession0.sim index 48827a64a2..b15083ab1b 100644 --- a/tests/script/tsim/stream/triggerSession0.sim +++ b/tests/script/tsim/stream/triggerSession0.sim @@ -15,7 +15,7 @@ print $data00 $data01 $data02 sql use test sql create table t2(ts timestamp, a int, b int , c int, d double); -sql create stream streams2 trigger window_close into streamt2 as select _wstartts, count(*) c1, count(d) c2 , sum(a) c3 , max(b) c4, min(c) c5 from t2 session(ts, 10s); +sql create stream streams2 trigger window_close into streamt2 as select _wstart, count(*) c1, count(d) c2 , sum(a) c3 , max(b) c4, min(c) c5 from t2 session(ts, 10s); sql insert into t2 values(1648791213000,1,2,3,1.0); sql insert into t2 values(1648791222999,1,2,3,1.0); diff --git a/tests/script/tsim/stream/windowClose.sim b/tests/script/tsim/stream/windowClose.sim index 695d5749fa..1f024b9836 100644 --- a/tests/script/tsim/stream/windowClose.sim +++ b/tests/script/tsim/stream/windowClose.sim @@ -18,7 +18,7 @@ sql create stable st(ts timestamp, a int) tags(t int); sql create table tu1 using st tags(1); sql create table tu2 using st tags(2); -sql create stream stream1 trigger window_close into streamt as select _wstartts, sum(a) from st interval(10s); +sql create stream stream1 trigger window_close into streamt as select _wstart, sum(a) from st interval(10s); sql insert into tu1 values(now, 1); diff --git a/tests/script/tsim/vnode/stable_dnode2.sim b/tests/script/tsim/vnode/stable_dnode2.sim index c29d960706..99047086c4 100644 --- a/tests/script/tsim/vnode/stable_dnode2.sim +++ b/tests/script/tsim/vnode/stable_dnode2.sim @@ -109,20 +109,20 @@ if $data00 != $rowNum then endi print =============== step5 -sql select _wstartts, count(tbcol) as b from $tb interval(1m) +sql select _wstart, count(tbcol) as b from $tb interval(1m) print ===> $data01 if $data01 != 1 then return -1 endi -sql select _wstartts, count(tbcol) as b from $tb interval(1d) +sql select _wstart, count(tbcol) as b from $tb interval(1d) print ===> $data01 if $data01 != $rowNum then return -1 endi print =============== step6 -sql select _wstartts, count(tbcol) as b from $tb where ts <= 1519833840000 interval(1m) +sql select _wstart, count(tbcol) as b from $tb where ts <= 1519833840000 interval(1m) print ===> $data01 if $data01 != 1 then return -1 @@ -164,13 +164,13 @@ if $data00 != 25 then endi print =============== step9 -sql select _wstartts, count(tbcol) as b from $mt interval(1m) +sql select _wstart, count(tbcol) as b from $mt interval(1m) print ===> $data01 if $data01 != 10 then return -1 endi -sql select _wstartts, count(tbcol) as b from $mt interval(1d) +sql select _wstart, count(tbcol) as b from $mt interval(1d) print ===> $data01 if $data01 != 200 then return -1 diff --git a/tests/script/tsim/vnode/stable_dnode2_stop.sim b/tests/script/tsim/vnode/stable_dnode2_stop.sim index 113cf27e17..87972a15f9 100644 --- a/tests/script/tsim/vnode/stable_dnode2_stop.sim +++ b/tests/script/tsim/vnode/stable_dnode2_stop.sim @@ -138,13 +138,13 @@ if $data00 != 25 then endi print =============== step4 -sql select _wstartts, count(tbcol) as b from $mt interval(1m) +sql select _wstart, count(tbcol) as b from $mt interval(1m) print ===> $data01 if $data01 != 10 then return -1 endi -sql select _wstartts, count(tbcol) as b from $mt interval(1d) +sql select _wstart, count(tbcol) as b from $mt interval(1d) print ===> $data01 if $data01 != 200 then return -1 diff --git a/tests/script/tsim/vnode/stable_dnode3.sim b/tests/script/tsim/vnode/stable_dnode3.sim index ae777b9942..279fb3b441 100644 --- a/tests/script/tsim/vnode/stable_dnode3.sim +++ b/tests/script/tsim/vnode/stable_dnode3.sim @@ -111,20 +111,20 @@ if $data00 != $rowNum then endi print =============== step5 -sql select _wstartts, count(tbcol) as b from $tb interval(1m) +sql select _wstart, count(tbcol) as b from $tb interval(1m) print ===> $data01 if $data01 != 1 then return -1 endi -sql select _wstartts, count(tbcol) as b from $tb interval(1d) +sql select _wstart, count(tbcol) as b from $tb interval(1d) print ===> $data01 if $data01 != $rowNum then return -1 endi print =============== step6 -sql select _wstartts, count(tbcol) as b from $tb where ts <= 1519833840000 interval(1m) +sql select _wstart, count(tbcol) as b from $tb where ts <= 1519833840000 interval(1m) print ===> $data01 if $data01 != 1 then return -1 @@ -166,13 +166,13 @@ if $data00 != 25 then endi print =============== step9 -sql select _wstartts, count(tbcol) as b from $mt interval(1m) +sql select _wstart, count(tbcol) as b from $mt interval(1m) print ===> $data01 if $data01 != 10 then return -1 endi -sql select _wstartts, count(tbcol) as b from $mt interval(1d) +sql select _wstart, count(tbcol) as b from $mt interval(1d) print ===> $data01 if $data01 != 200 then return -1 diff --git a/tests/script/tsim/vnode/stable_replica3_dnode6.sim b/tests/script/tsim/vnode/stable_replica3_dnode6.sim index aea5b88fed..e5c677ccbc 100644 --- a/tests/script/tsim/vnode/stable_replica3_dnode6.sim +++ b/tests/script/tsim/vnode/stable_replica3_dnode6.sim @@ -140,20 +140,20 @@ if $data00 != $rowNum then endi print =============== step5 -sql select _wstartts, count(tbcol) as b from $tb interval(1m) +sql select _wstart, count(tbcol) as b from $tb interval(1m) print ===> $data01 if $data01 != 1 then return -1 endi -sql select _wstartts, count(tbcol) as b from $tb interval(1d) +sql select _wstart, count(tbcol) as b from $tb interval(1d) print ===> $data01 if $data01 != $rowNum then return -1 endi print =============== step6 -sql select _wstartts, count(tbcol) as b from $tb where ts <= 1519833840000 interval(1m) +sql select _wstart, count(tbcol) as b from $tb where ts <= 1519833840000 interval(1m) print ===> $data01 if $data01 != 1 then return -1 @@ -195,13 +195,13 @@ if $data00 != 25 then endi print =============== step9 -#sql select _wstartts, count(tbcol) as b from $mt interval(1m) +#sql select _wstart, count(tbcol) as b from $mt interval(1m) #print ===> $data01 #if $data01 != 10 then # return -1 #endi -sql select _wstartts, count(tbcol) as b from $mt interval(1d) +sql select _wstart, count(tbcol) as b from $mt interval(1d) print ===> $data01 if $data01 != 200 then return -1 diff --git a/tests/script/tsim/vnode/stable_replica3_vnode3.sim b/tests/script/tsim/vnode/stable_replica3_vnode3.sim index 8137b087f5..ca26b2fd10 100644 --- a/tests/script/tsim/vnode/stable_replica3_vnode3.sim +++ b/tests/script/tsim/vnode/stable_replica3_vnode3.sim @@ -124,20 +124,20 @@ if $data00 != $rowNum then endi print =============== step5 -sql select _wstartts, count(tbcol) as b from $tb interval(1m) +sql select _wstart, count(tbcol) as b from $tb interval(1m) print ===> $data01 if $data01 != 1 then return -1 endi -sql select _wstartts, count(tbcol) as b from $tb interval(1d) +sql select _wstart, count(tbcol) as b from $tb interval(1d) print ===> $data01 if $data01 != $rowNum then return -1 endi print =============== step6 -sql select _wstartts, count(tbcol) as b from $tb where ts <= 1519833840000 interval(1m) +sql select _wstart, count(tbcol) as b from $tb where ts <= 1519833840000 interval(1m) print ===> $data01 if $data01 != 1 then return -1 @@ -180,13 +180,13 @@ if $data00 != 25 then endi print =============== step9 -sql select _wstartts, count(tbcol) as b from $mt interval(1m) +sql select _wstart, count(tbcol) as b from $mt interval(1m) print ===> $data01 if $data01 != 10 then return -1 endi -sql select _wstartts, count(tbcol) as b from $mt interval(1d) +sql select _wstart, count(tbcol) as b from $mt interval(1d) print ===> $data01 if $data01 != 200 then return -1 -- GitLab From 0030888d1d9764e4224e0e4274bf0ab340d4e578 Mon Sep 17 00:00:00 2001 From: Shengliang Guan Date: Wed, 13 Jul 2022 15:13:48 +0800 Subject: [PATCH 051/153] test: restore some 2.0 case --- tests/script/general/compress/testSuite.sim | 4 ---- tests/script/jenkins/basic.txt | 6 ++++++ tests/script/{general => tsim}/compress/commitlog.sim | 10 +--------- tests/script/{general => tsim}/compress/compress.sim | 9 --------- tests/script/{general => tsim}/compress/compress2.sim | 8 -------- tests/script/{general => tsim}/compress/uncompress.sim | 10 +--------- 6 files changed, 8 insertions(+), 39 deletions(-) delete mode 100644 tests/script/general/compress/testSuite.sim rename tests/script/{general => tsim}/compress/commitlog.sim (93%) rename tests/script/{general => tsim}/compress/compress.sim (92%) rename tests/script/{general => tsim}/compress/compress2.sim (93%) rename tests/script/{general => tsim}/compress/uncompress.sim (93%) diff --git a/tests/script/general/compress/testSuite.sim b/tests/script/general/compress/testSuite.sim deleted file mode 100644 index 3573985c8a..0000000000 --- a/tests/script/general/compress/testSuite.sim +++ /dev/null @@ -1,4 +0,0 @@ -run general/compress/commitlog.sim -run general/compress/compress2.sim -run general/compress/compress.sim -run general/compress/uncompress.sim diff --git a/tests/script/jenkins/basic.txt b/tests/script/jenkins/basic.txt index afe5527380..b24ca5f85e 100644 --- a/tests/script/jenkins/basic.txt +++ b/tests/script/jenkins/basic.txt @@ -22,6 +22,12 @@ ./test.sh -f tsim/column/metrics.sim ./test.sh -f tsim/column/table.sim +# ---- compress +./test.sh -f tsim/compress/commitlog.sim +./test.sh -f tsim/compress/compress2.sim +./test.sh -f tsim/compress/compress.sim +./test.sh -f tsim/compress/uncompress.sim + # ---- db ./test.sh -f tsim/db/alter_option.sim # ./test.sh -f tsim/db/alter_replica_13.sim diff --git a/tests/script/general/compress/commitlog.sim b/tests/script/tsim/compress/commitlog.sim similarity index 93% rename from tests/script/general/compress/commitlog.sim rename to tests/script/tsim/compress/commitlog.sim index e8eab6ed0c..d90780bd6c 100644 --- a/tests/script/general/compress/commitlog.sim +++ b/tests/script/tsim/compress/commitlog.sim @@ -1,14 +1,9 @@ system sh/stop_dnodes.sh - system sh/deploy.sh -n dnode1 -i 1 -system sh/cfg.sh -n dnode1 -c walLevel -v 1 -system sh/cfg.sh -n dnode1 -c comp -v 1 system sh/exec.sh -n dnode1 -s start - -sleep 2000 sql connect -print ============================ dnode1 start +print ============================ dnode1 start $i = 0 $dbPrefix = db $tbPrefix = tb @@ -18,7 +13,6 @@ $tb = $tbPrefix . $i $N = 2000 print =============== step1 - sql create database $db sql use $db sql create table $tb (ts timestamp, b bool, t tinyint, s smallint, i int, big bigint, str binary(256)) @@ -87,9 +81,7 @@ endi print =============== step4 system sh/exec.sh -n dnode1 -s stop -x SIGINT -sleep 3000 system sh/exec.sh -n dnode1 -s start -sleep 3000 print =============== step5 diff --git a/tests/script/general/compress/compress.sim b/tests/script/tsim/compress/compress.sim similarity index 92% rename from tests/script/general/compress/compress.sim rename to tests/script/tsim/compress/compress.sim index cecfe61229..766f97450c 100644 --- a/tests/script/general/compress/compress.sim +++ b/tests/script/tsim/compress/compress.sim @@ -1,15 +1,9 @@ system sh/stop_dnodes.sh - system sh/deploy.sh -n dnode1 -i 1 -system sh/cfg.sh -n dnode1 -c walLevel -v 1 -system sh/cfg.sh -n dnode1 -c comp -v 1 system sh/exec.sh -n dnode1 -s start - -sleep 2000 sql connect print ============================ dnode1 start - $i = 0 $dbPrefix = db $tbPrefix = tb @@ -19,7 +13,6 @@ $tb = $tbPrefix . $i $N = 2000 print =============== step1 - sql create database $db sql use $db sql create table $tb (ts timestamp, b bool, t tinyint, s smallint, i int, big bigint, str binary(256)) @@ -82,9 +75,7 @@ endi print =============== step4 system sh/exec.sh -n dnode1 -s stop -x SIGINT -sleep 3000 system sh/exec.sh -n dnode1 -s start -sleep 3000 print =============== step5 diff --git a/tests/script/general/compress/compress2.sim b/tests/script/tsim/compress/compress2.sim similarity index 93% rename from tests/script/general/compress/compress2.sim rename to tests/script/tsim/compress/compress2.sim index 1e6868eaa6..87e50cce5b 100644 --- a/tests/script/general/compress/compress2.sim +++ b/tests/script/tsim/compress/compress2.sim @@ -1,15 +1,9 @@ system sh/stop_dnodes.sh - system sh/deploy.sh -n dnode1 -i 1 -system sh/cfg.sh -n dnode1 -c walLevel -v 1 -system sh/cfg.sh -n dnode1 -c comp -v 2 system sh/exec.sh -n dnode1 -s start - -sleep 2000 sql connect print ============================ dnode1 start - $i = 0 $dbPrefix = db $tbPrefix = tb @@ -82,9 +76,7 @@ endi print =============== step4 system sh/exec.sh -n dnode1 -s stop -x SIGINT -sleep 3000 system sh/exec.sh -n dnode1 -s start -sleep 3000 print =============== step5 diff --git a/tests/script/general/compress/uncompress.sim b/tests/script/tsim/compress/uncompress.sim similarity index 93% rename from tests/script/general/compress/uncompress.sim rename to tests/script/tsim/compress/uncompress.sim index 49945dcb79..ccd5db4b0c 100644 --- a/tests/script/general/compress/uncompress.sim +++ b/tests/script/tsim/compress/uncompress.sim @@ -1,13 +1,9 @@ system sh/stop_dnodes.sh system sh/deploy.sh -n dnode1 -i 1 -system sh/cfg.sh -n dnode1 -c walLevel -v 1 -system sh/cfg.sh -n dnode1 -c comp -v 1 system sh/exec.sh -n dnode1 -s start - -sleep 2000 sql connect -print ============================ dnode1 start +print ============================ dnode1 start $i = 0 $dbPrefix = cp_cp_db $tbPrefix = cp_cp_tb @@ -17,7 +13,6 @@ $tb = $tbPrefix . $i $N = 2000 print =============== step1 - sql create database $db sql use $db @@ -81,12 +76,9 @@ endi print =============== step4 system sh/exec.sh -n dnode1 -s stop -x SIGINT -sleep 3000 system sh/exec.sh -n dnode1 -s start -sleep 2000 print =============== step5 - $i = 0 $db = $dbPrefix . $i $tb = $tbPrefix . $i -- GitLab From db65b890c8b4a2baf44973b2b54a66b374e6a570 Mon Sep 17 00:00:00 2001 From: Xiaoyu Wang Date: Wed, 13 Jul 2022 15:14:13 +0800 Subject: [PATCH 052/153] feat: support pseudo columns such as _qstart, _qend and _qduration --- source/libs/planner/src/planOptimizer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/libs/planner/src/planOptimizer.c b/source/libs/planner/src/planOptimizer.c index ea1b3d3f81..7732669f84 100644 --- a/source/libs/planner/src/planOptimizer.c +++ b/source/libs/planner/src/planOptimizer.c @@ -2054,11 +2054,11 @@ static EDealRes mergeProjectionsExpr(SNode** pNode, void* pContext) { ((SExprNode*)*pNode)->aliasName); nodesDestroyNode(*pNode); *pNode = pExpr; + return DEAL_RES_IGNORE_CHILD; } } } } - return DEAL_RES_IGNORE_CHILD; } return DEAL_RES_CONTINUE; } -- GitLab From 0cd7d1fb13c48130f246767d25fc545be2a7e346 Mon Sep 17 00:00:00 2001 From: Minglei Jin Date: Wed, 13 Jul 2022 15:28:21 +0800 Subject: [PATCH 053/153] fix: fix last row reader close memory issues --- source/dnode/vnode/src/tsdb/tsdbCacheRead.c | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/source/dnode/vnode/src/tsdb/tsdbCacheRead.c b/source/dnode/vnode/src/tsdb/tsdbCacheRead.c index 5c09c7663f..127e9d2b02 100644 --- a/source/dnode/vnode/src/tsdb/tsdbCacheRead.c +++ b/source/dnode/vnode/src/tsdb/tsdbCacheRead.c @@ -22,11 +22,11 @@ typedef struct SLastrowReader { SVnode* pVnode; STSchema* pSchema; uint64_t uid; - char** transferBuf; // todo remove it soon - int32_t numOfCols; - int32_t type; - int32_t tableIndex; // currently returned result tables - SArray* pTableList; // table id list + char** transferBuf; // todo remove it soon + int32_t numOfCols; + int32_t type; + int32_t tableIndex; // currently returned result tables + SArray* pTableList; // table id list } SLastrowReader; static void saveOneRow(STSRow* pRow, SSDataBlock* pBlock, SLastrowReader* pReader, const int32_t* slotIds) { @@ -94,12 +94,15 @@ int32_t tsdbLastRowReaderOpen(void* pVnode, int32_t type, SArray* pTableIdList, int32_t tsdbLastrowReaderClose(void* pReader) { SLastrowReader* p = pReader; - for (int32_t i = 0; i < p->pSchema->numOfCols; ++i) { - taosMemoryFreeClear(p->transferBuf[i]); + if (p->pSchema != NULL) { + for (int32_t i = 0; i < p->pSchema->numOfCols; ++i) { + taosMemoryFreeClear(p->transferBuf[i]); + } + + taosMemoryFree(p->transferBuf); + taosMemoryFree(p->pSchema); } - taosMemoryFree(p->pSchema); - taosMemoryFree(p->transferBuf); taosMemoryFree(pReader); return TSDB_CODE_SUCCESS; } -- GitLab From 0237ccbbb693ecb2fbd2926bed884f65d0456db7 Mon Sep 17 00:00:00 2001 From: wangmm0220 Date: Wed, 13 Jul 2022 15:33:31 +0800 Subject: [PATCH 054/153] fix:error in tmq meta --- include/common/tcommon.h | 1 - source/client/src/tmq.c | 1 + source/dnode/mnode/impl/src/mndStb.c | 4 ++-- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/include/common/tcommon.h b/include/common/tcommon.h index 3d15e8b087..9440a3452b 100644 --- a/include/common/tcommon.h +++ b/include/common/tcommon.h @@ -40,7 +40,6 @@ enum { || x == TDMT_VND_CREATE_TABLE \ || x == TDMT_VND_ALTER_TABLE \ || x == TDMT_VND_DROP_TABLE \ - || x == TDMT_VND_DROP_TTL_TABLE \ ) // clang-format on diff --git a/source/client/src/tmq.c b/source/client/src/tmq.c index ed9efdf3da..7e01e5cd83 100644 --- a/source/client/src/tmq.c +++ b/source/client/src/tmq.c @@ -2713,6 +2713,7 @@ static int32_t taosDropTable(TAOS *taos, void *meta, int32_t metaLen){ // loop to create table for (int32_t iReq = 0; iReq < req.nReqs; iReq++) { pDropReq = req.pReqs + iReq; + pDropReq->igNotExists = true; SVgroupInfo pInfo = {0}; SName pName; diff --git a/source/dnode/mnode/impl/src/mndStb.c b/source/dnode/mnode/impl/src/mndStb.c index 51f550ad92..bff33af5af 100644 --- a/source/dnode/mnode/impl/src/mndStb.c +++ b/source/dnode/mnode/impl/src/mndStb.c @@ -1849,8 +1849,8 @@ static int32_t mndProcessDropStbReq(SRpcMsg *pReq) { } } - if (dropReq.source != TD_REQ_FROM_APP && pStb->uid != dropReq.suid) { - terrno = TSDB_CODE_MND_STB_NOT_EXIST; + if (dropReq.source == TD_REQ_FROM_TAOX && pStb->uid != dropReq.suid) { + code = 0; goto _OVER; } -- GitLab From 511c39a0cfa3c8bdca7581b981b19ba1ef4b0fb9 Mon Sep 17 00:00:00 2001 From: Minghao Li Date: Wed, 13 Jul 2022 15:55:38 +0800 Subject: [PATCH 055/153] refactor(sync): add skiplist entry cache --- source/libs/sync/inc/syncRaftEntry.h | 54 +++- source/libs/sync/src/syncRaftEntry.c | 274 ++++++++++++++++-- source/libs/sync/src/syncRespMgr.c | 2 +- source/libs/sync/test/CMakeLists.txt | 14 + source/libs/sync/test/syncEntryCacheTest.cpp | 233 +++------------- source/libs/sync/test/syncHashCacheTest.cpp | 277 +++++++++++++++++++ 6 files changed, 633 insertions(+), 221 deletions(-) create mode 100644 source/libs/sync/test/syncHashCacheTest.cpp diff --git a/source/libs/sync/inc/syncRaftEntry.h b/source/libs/sync/inc/syncRaftEntry.h index 82d5c0a6ea..fdfabf12a3 100644 --- a/source/libs/sync/inc/syncRaftEntry.h +++ b/source/libs/sync/inc/syncRaftEntry.h @@ -26,6 +26,7 @@ extern "C" { #include "syncInt.h" #include "syncMessage.h" #include "taosdef.h" +#include "tskiplist.h" typedef struct SSyncRaftEntry { uint32_t bytes; @@ -58,29 +59,52 @@ void syncEntryLog(const SSyncRaftEntry* pObj); void syncEntryLog2(char* s, const SSyncRaftEntry* pObj); //----------------------------------- -typedef struct SRaftEntryCache { +typedef struct SRaftEntryHashCache { SHashObj* pEntryHash; int32_t maxCount; int32_t currentCount; TdThreadMutex mutex; SSyncNode* pSyncNode; +} SRaftEntryHashCache; + +SRaftEntryHashCache* raftCacheCreate(SSyncNode* pSyncNode, int32_t maxCount); +void raftCacheDestroy(SRaftEntryHashCache* pCache); +int32_t raftCachePutEntry(struct SRaftEntryHashCache* pCache, SSyncRaftEntry* pEntry); +int32_t raftCacheGetEntry(struct SRaftEntryHashCache* pCache, SyncIndex index, SSyncRaftEntry** ppEntry); +int32_t raftCacheGetEntryP(struct SRaftEntryHashCache* pCache, SyncIndex index, SSyncRaftEntry** ppEntry); +int32_t raftCacheDelEntry(struct SRaftEntryHashCache* pCache, SyncIndex index); +int32_t raftCacheGetAndDel(struct SRaftEntryHashCache* pCache, SyncIndex index, SSyncRaftEntry** ppEntry); +int32_t raftCacheClear(struct SRaftEntryHashCache* pCache); + +cJSON* raftCache2Json(SRaftEntryHashCache* pObj); +char* raftCache2Str(SRaftEntryHashCache* pObj); +void raftCachePrint(SRaftEntryHashCache* pObj); +void raftCachePrint2(char* s, SRaftEntryHashCache* pObj); +void raftCacheLog(SRaftEntryHashCache* pObj); +void raftCacheLog2(char* s, SRaftEntryHashCache* pObj); + +//----------------------------------- +typedef struct SRaftEntryCache { + SSkipList* pSkipList; + int32_t maxCount; + int32_t currentCount; + TdThreadMutex mutex; + SSyncNode* pSyncNode; } SRaftEntryCache; -SRaftEntryCache* raftCacheCreate(SSyncNode* pSyncNode, int32_t maxCount); -void raftCacheDestroy(SRaftEntryCache* pCache); -int32_t raftCachePutEntry(struct SRaftEntryCache* pCache, SSyncRaftEntry* pEntry); -int32_t raftCacheGetEntry(struct SRaftEntryCache* pCache, SyncIndex index, SSyncRaftEntry** ppEntry); -int32_t raftCacheGetEntryP(struct SRaftEntryCache* pCache, SyncIndex index, SSyncRaftEntry** ppEntry); -int32_t raftCacheDelEntry(struct SRaftEntryCache* pCache, SyncIndex index); -int32_t raftCacheGetAndDel(struct SRaftEntryCache* pCache, SyncIndex index, SSyncRaftEntry** ppEntry); -int32_t raftCacheClear(struct SRaftEntryCache* pCache); +SRaftEntryCache* raftEntryCacheCreate(SSyncNode* pSyncNode, int32_t maxCount); +void raftEntryCacheDestroy(SRaftEntryCache* pCache); +int32_t raftEntryCachePutEntry(struct SRaftEntryCache* pCache, SSyncRaftEntry* pEntry); +int32_t raftEntryCacheGetEntry(struct SRaftEntryCache* pCache, SyncIndex index, SSyncRaftEntry** ppEntry); +int32_t raftEntryCacheGetEntryP(struct SRaftEntryCache* pCache, SyncIndex index, SSyncRaftEntry** ppEntry); +int32_t raftEntryCacheClear(struct SRaftEntryCache* pCache, int32_t count); -cJSON* raftCache2Json(SRaftEntryCache* pObj); -char* raftCache2Str(SRaftEntryCache* pObj); -void raftCachePrint(SRaftEntryCache* pObj); -void raftCachePrint2(char* s, SRaftEntryCache* pObj); -void raftCacheLog(SRaftEntryCache* pObj); -void raftCacheLog2(char* s, SRaftEntryCache* pObj); +cJSON* raftEntryCache2Json(SRaftEntryCache* pObj); +char* raftEntryCache2Str(SRaftEntryCache* pObj); +void raftEntryCachePrint(SRaftEntryCache* pObj); +void raftEntryCachePrint2(char* s, SRaftEntryCache* pObj); +void raftEntryCacheLog(SRaftEntryCache* pObj); +void raftEntryCacheLog2(char* s, SRaftEntryCache* pObj); #ifdef __cplusplus } diff --git a/source/libs/sync/src/syncRaftEntry.c b/source/libs/sync/src/syncRaftEntry.c index 465584a40f..89e67fab28 100644 --- a/source/libs/sync/src/syncRaftEntry.c +++ b/source/libs/sync/src/syncRaftEntry.c @@ -198,8 +198,8 @@ void syncEntryLog2(char* s, const SSyncRaftEntry* pObj) { } //----------------------------------- -SRaftEntryCache* raftCacheCreate(SSyncNode* pSyncNode, int32_t maxCount) { - SRaftEntryCache* pCache = taosMemoryMalloc(sizeof(SRaftEntryCache)); +SRaftEntryHashCache* raftCacheCreate(SSyncNode* pSyncNode, int32_t maxCount) { + SRaftEntryHashCache* pCache = taosMemoryMalloc(sizeof(SRaftEntryHashCache)); if (pCache == NULL) { sError("vgId:%d raft cache create error", pSyncNode->vgId); return NULL; @@ -220,7 +220,7 @@ SRaftEntryCache* raftCacheCreate(SSyncNode* pSyncNode, int32_t maxCount) { return pCache; } -void raftCacheDestroy(SRaftEntryCache* pCache) { +void raftCacheDestroy(SRaftEntryHashCache* pCache) { if (pCache != NULL) { taosThreadMutexLock(&(pCache->mutex)); taosHashCleanup(pCache->pEntryHash); @@ -233,7 +233,7 @@ void raftCacheDestroy(SRaftEntryCache* pCache) { // success, return 1 // max count, return 0 // error, return -1 -int32_t raftCachePutEntry(struct SRaftEntryCache* pCache, SSyncRaftEntry* pEntry) { +int32_t raftCachePutEntry(struct SRaftEntryHashCache* pCache, SSyncRaftEntry* pEntry) { taosThreadMutexLock(&(pCache->mutex)); if (pCache->currentCount >= pCache->maxCount) { @@ -259,7 +259,7 @@ int32_t raftCachePutEntry(struct SRaftEntryCache* pCache, SSyncRaftEntry* pEntry // success, return 0 // error, return -1 // not exist, return -1, terrno = TSDB_CODE_WAL_LOG_NOT_EXIST -int32_t raftCacheGetEntry(struct SRaftEntryCache* pCache, SyncIndex index, SSyncRaftEntry** ppEntry) { +int32_t raftCacheGetEntry(struct SRaftEntryHashCache* pCache, SyncIndex index, SSyncRaftEntry** ppEntry) { if (ppEntry == NULL) { return -1; } @@ -292,7 +292,7 @@ int32_t raftCacheGetEntry(struct SRaftEntryCache* pCache, SyncIndex index, SSync // success, return 0 // error, return -1 // not exist, return -1, terrno = TSDB_CODE_WAL_LOG_NOT_EXIST -int32_t raftCacheGetEntryP(struct SRaftEntryCache* pCache, SyncIndex index, SSyncRaftEntry** ppEntry) { +int32_t raftCacheGetEntryP(struct SRaftEntryHashCache* pCache, SyncIndex index, SSyncRaftEntry** ppEntry) { if (ppEntry == NULL) { return -1; } @@ -321,7 +321,7 @@ int32_t raftCacheGetEntryP(struct SRaftEntryCache* pCache, SyncIndex index, SSyn return -1; } -int32_t raftCacheDelEntry(struct SRaftEntryCache* pCache, SyncIndex index) { +int32_t raftCacheDelEntry(struct SRaftEntryHashCache* pCache, SyncIndex index) { taosThreadMutexLock(&(pCache->mutex)); taosHashRemove(pCache->pEntryHash, &index, sizeof(index)); --(pCache->currentCount); @@ -329,7 +329,7 @@ int32_t raftCacheDelEntry(struct SRaftEntryCache* pCache, SyncIndex index) { return 0; } -int32_t raftCacheGetAndDel(struct SRaftEntryCache* pCache, SyncIndex index, SSyncRaftEntry** ppEntry) { +int32_t raftCacheGetAndDel(struct SRaftEntryHashCache* pCache, SyncIndex index, SSyncRaftEntry** ppEntry) { if (ppEntry == NULL) { return -1; } @@ -362,7 +362,7 @@ int32_t raftCacheGetAndDel(struct SRaftEntryCache* pCache, SyncIndex index, SSyn return -1; } -int32_t raftCacheClear(struct SRaftEntryCache* pCache) { +int32_t raftCacheClear(struct SRaftEntryHashCache* pCache) { taosThreadMutexLock(&(pCache->mutex)); taosHashClear(pCache->pEntryHash); pCache->currentCount = 0; @@ -371,7 +371,7 @@ int32_t raftCacheClear(struct SRaftEntryCache* pCache) { } //----------------------------------- -cJSON* raftCache2Json(SRaftEntryCache* pCache) { +cJSON* raftCache2Json(SRaftEntryHashCache* pCache) { char u64buf[128] = {0}; cJSON* pRoot = cJSON_CreateObject(); @@ -402,41 +402,283 @@ cJSON* raftCache2Json(SRaftEntryCache* pCache) { } cJSON* pJson = cJSON_CreateObject(); - cJSON_AddItemToObject(pJson, "SRaftEntryCache", pRoot); + cJSON_AddItemToObject(pJson, "SRaftEntryHashCache", pRoot); return pJson; } -char* raftCache2Str(SRaftEntryCache* pCache) { +char* raftCache2Str(SRaftEntryHashCache* pCache) { cJSON* pJson = raftCache2Json(pCache); char* serialized = cJSON_Print(pJson); cJSON_Delete(pJson); return serialized; } -void raftCachePrint(SRaftEntryCache* pCache) { +void raftCachePrint(SRaftEntryHashCache* pCache) { char* serialized = raftCache2Str(pCache); printf("raftCachePrint | len:%" PRIu64 " | %s \n", strlen(serialized), serialized); fflush(NULL); taosMemoryFree(serialized); } -void raftCachePrint2(char* s, SRaftEntryCache* pCache) { +void raftCachePrint2(char* s, SRaftEntryHashCache* pCache) { char* serialized = raftCache2Str(pCache); printf("raftCachePrint2 | len:%" PRIu64 " | %s | %s \n", strlen(serialized), s, serialized); fflush(NULL); taosMemoryFree(serialized); } -void raftCacheLog(SRaftEntryCache* pCache) { +void raftCacheLog(SRaftEntryHashCache* pCache) { char* serialized = raftCache2Str(pCache); sTrace("raftCacheLog | len:%" PRIu64 " | %s", strlen(serialized), serialized); taosMemoryFree(serialized); } -void raftCacheLog2(char* s, SRaftEntryCache* pCache) { +void raftCacheLog2(char* s, SRaftEntryHashCache* pCache) { if (gRaftDetailLog) { char* serialized = raftCache2Str(pCache); sTraceLong("raftCacheLog2 | len:%" PRIu64 " | %s | %s", strlen(serialized), s, serialized); taosMemoryFree(serialized); } +} + +//----------------------------------- +static char* keyFn(const void* pData) { + SSyncRaftEntry* pEntry = (SSyncRaftEntry*)pData; + return (char*)(&(pEntry->index)); +} + +static int cmpFn(const void* p1, const void* p2) { return memcmp(p1, p2, sizeof(SyncIndex)); } + +SRaftEntryCache* raftEntryCacheCreate(SSyncNode* pSyncNode, int32_t maxCount) { + SRaftEntryCache* pCache = taosMemoryMalloc(sizeof(SRaftEntryCache)); + if (pCache == NULL) { + sError("vgId:%d raft cache create error", pSyncNode->vgId); + return NULL; + } + + pCache->pSkipList = + tSkipListCreate(MAX_SKIP_LIST_LEVEL, TSDB_DATA_TYPE_BINARY, sizeof(SyncIndex), cmpFn, SL_ALLOW_DUP_KEY, keyFn); + if (pCache->pSkipList == NULL) { + sError("vgId:%d raft cache create hash error", pSyncNode->vgId); + return NULL; + } + + taosThreadMutexInit(&(pCache->mutex), NULL); + pCache->maxCount = maxCount; + pCache->currentCount = 0; + pCache->pSyncNode = pSyncNode; + + return pCache; +} + +void raftEntryCacheDestroy(SRaftEntryCache* pCache) { + if (pCache != NULL) { + taosThreadMutexLock(&(pCache->mutex)); + tSkipListDestroy(pCache->pSkipList); + taosThreadMutexUnlock(&(pCache->mutex)); + taosThreadMutexDestroy(&(pCache->mutex)); + taosMemoryFree(pCache); + } +} + +// success, return 1 +// max count, return 0 +// error, return -1 +int32_t raftEntryCachePutEntry(struct SRaftEntryCache* pCache, SSyncRaftEntry* pEntry) { + taosThreadMutexLock(&(pCache->mutex)); + + if (pCache->currentCount >= pCache->maxCount) { + taosThreadMutexUnlock(&(pCache->mutex)); + return 0; + } + + SSkipListNode* pSkipListNode = tSkipListPut(pCache->pSkipList, pEntry); + ASSERT(pSkipListNode != NULL); + ++(pCache->currentCount); + + do { + char eventLog[128]; + snprintf(eventLog, sizeof(eventLog), "raft cache add, type:%s,%d, type2:%s,%d, index:%" PRId64 ", bytes:%d", + TMSG_INFO(pEntry->msgType), pEntry->msgType, TMSG_INFO(pEntry->originalRpcType), pEntry->originalRpcType, + pEntry->index, pEntry->bytes); + syncNodeEventLog(pCache->pSyncNode, eventLog); + } while (0); + + taosThreadMutexUnlock(&(pCache->mutex)); + return 1; +} + +// find one, return 1 +// not found, return 0 +// error, return -1 +int32_t raftEntryCacheGetEntry(struct SRaftEntryCache* pCache, SyncIndex index, SSyncRaftEntry** ppEntry) { + ASSERT(ppEntry != NULL); + SSyncRaftEntry* pEntry = NULL; + int32_t code = raftEntryCacheGetEntryP(pCache, index, &pEntry); + if (code == 1) { + *ppEntry = taosMemoryMalloc(pEntry->bytes); + memcpy(*ppEntry, pEntry, pEntry->bytes); + } else { + *ppEntry = NULL; + } + return code; +} + +// find one, return 1 +// not found, return 0 +// error, return -1 +int32_t raftEntryCacheGetEntryP(struct SRaftEntryCache* pCache, SyncIndex index, SSyncRaftEntry** ppEntry) { + taosThreadMutexLock(&(pCache->mutex)); + + SyncIndex index2 = index; + int32_t code = 0; + + SArray* entryPArray = tSkipListGet(pCache->pSkipList, (char*)(&index2)); + int32_t arraySize = taosArrayGetSize(entryPArray); + if (arraySize == 1) { + SSkipListNode** ppNode = (SSkipListNode**)taosArrayGet(entryPArray, 0); + ASSERT(*ppNode != NULL); + *ppEntry = (SSyncRaftEntry*)SL_GET_NODE_DATA(*ppNode); + code = 1; + + } else if (arraySize == 0) { + code = 0; + + } else { + ASSERT(0); + + code = -1; + } + taosArrayDestroy(entryPArray); + + taosThreadMutexUnlock(&(pCache->mutex)); + return code; +} + +// count = -1, clear all +// count >= 0, clear count +// return -1, error +// return delete count +int32_t raftEntryCacheClear(struct SRaftEntryCache* pCache, int32_t count) { + taosThreadMutexLock(&(pCache->mutex)); + int32_t returnCnt = 0; + + if (count == -1) { + // clear all + SSkipListIterator* pIter = tSkipListCreateIter(pCache->pSkipList); + while (tSkipListIterNext(pIter)) { + SSkipListNode* pNode = tSkipListIterGet(pIter); + ASSERT(pNode != NULL); + SSyncRaftEntry* pEntry = (SSyncRaftEntry*)SL_GET_NODE_DATA(pNode); + syncEntryDestory(pEntry); + ++returnCnt; + } + tSkipListDestroyIter(pIter); + + tSkipListDestroy(pCache->pSkipList); + pCache->pSkipList = + tSkipListCreate(MAX_SKIP_LIST_LEVEL, TSDB_DATA_TYPE_BINARY, sizeof(SyncIndex), cmpFn, SL_ALLOW_DUP_KEY, keyFn); + ASSERT(pCache->pSkipList != NULL); + + } else { + // clear count + int i = 0; + SSkipListIterator* pIter = tSkipListCreateIter(pCache->pSkipList); + SArray* delNodeArray = taosArrayInit(0, sizeof(SSkipListNode*)); + + // free entry + while (tSkipListIterNext(pIter)) { + SSkipListNode* pNode = tSkipListIterGet(pIter); + ASSERT(pNode != NULL); + if (i++ >= count) { + break; + } + + // sDebug("push pNode:%p", pNode); + taosArrayPush(delNodeArray, &pNode); + ++returnCnt; + SSyncRaftEntry* pEntry = (SSyncRaftEntry*)SL_GET_NODE_DATA(pNode); + syncEntryDestory(pEntry); + } + tSkipListDestroyIter(pIter); + + // delete skiplist node + int32_t arraySize = taosArrayGetSize(delNodeArray); + for (int32_t i = 0; i < arraySize; ++i) { + SSkipListNode** ppNode = taosArrayGet(delNodeArray, i); + // sDebug("get pNode:%p", *ppNode); + tSkipListRemoveNode(pCache->pSkipList, *ppNode); + } + taosArrayDestroy(delNodeArray); + } + + pCache->currentCount -= returnCnt; + taosThreadMutexUnlock(&(pCache->mutex)); + return returnCnt; +} + +cJSON* raftEntryCache2Json(SRaftEntryCache* pCache) { + char u64buf[128] = {0}; + cJSON* pRoot = cJSON_CreateObject(); + + if (pCache != NULL) { + taosThreadMutexLock(&(pCache->mutex)); + + snprintf(u64buf, sizeof(u64buf), "%p", pCache->pSyncNode); + cJSON_AddStringToObject(pRoot, "pSyncNode", u64buf); + cJSON_AddNumberToObject(pRoot, "currentCount", pCache->currentCount); + cJSON_AddNumberToObject(pRoot, "maxCount", pCache->maxCount); + cJSON* pEntries = cJSON_CreateArray(); + cJSON_AddItemToObject(pRoot, "entries", pEntries); + + SSkipListIterator* pIter = tSkipListCreateIter(pCache->pSkipList); + while (tSkipListIterNext(pIter)) { + SSkipListNode* pNode = tSkipListIterGet(pIter); + ASSERT(pNode != NULL); + SSyncRaftEntry* pEntry = (SSyncRaftEntry*)SL_GET_NODE_DATA(pNode); + cJSON_AddItemToArray(pEntries, syncEntry2Json(pEntry)); + } + tSkipListDestroyIter(pIter); + + taosThreadMutexUnlock(&(pCache->mutex)); + } + + cJSON* pJson = cJSON_CreateObject(); + cJSON_AddItemToObject(pJson, "SRaftEntryCache", pRoot); + return pJson; +} + +char* raftEntryCache2Str(SRaftEntryCache* pObj) { + cJSON* pJson = raftEntryCache2Json(pObj); + char* serialized = cJSON_Print(pJson); + cJSON_Delete(pJson); + return serialized; +} + +void raftEntryCachePrint(SRaftEntryCache* pObj) { + char* serialized = raftEntryCache2Str(pObj); + printf("raftEntryCachePrint | len:%" PRIu64 " | %s \n", strlen(serialized), serialized); + fflush(NULL); + taosMemoryFree(serialized); +} + +void raftEntryCachePrint2(char* s, SRaftEntryCache* pObj) { + char* serialized = raftEntryCache2Str(pObj); + printf("raftEntryCachePrint2 | len:%" PRIu64 " | %s | %s \n", strlen(serialized), s, serialized); + fflush(NULL); + taosMemoryFree(serialized); +} + +void raftEntryCacheLog(SRaftEntryCache* pObj) { + char* serialized = raftEntryCache2Str(pObj); + sTrace("raftEntryCacheLog | len:%" PRIu64 " | %s", strlen(serialized), serialized); + taosMemoryFree(serialized); +} + +void raftEntryCacheLog2(char* s, SRaftEntryCache* pObj) { + if (gRaftDetailLog) { + char* serialized = raftEntryCache2Str(pObj); + sTraceLong("raftEntryCacheLog2 | len:%" PRIu64 " | %s | %s", strlen(serialized), s, serialized); + taosMemoryFree(serialized); + } } \ No newline at end of file diff --git a/source/libs/sync/src/syncRespMgr.c b/source/libs/sync/src/syncRespMgr.c index 8e477a5159..97e5816038 100644 --- a/source/libs/sync/src/syncRespMgr.c +++ b/source/libs/sync/src/syncRespMgr.c @@ -127,7 +127,7 @@ void syncRespCleanByTTL(SSyncRespMgr *pObj, int64_t ttl) { while (pStub) { size_t len; - void *key = taosHashGetKey(pStub, &len); + void * key = taosHashGetKey(pStub, &len); uint64_t *pSeqNum = (uint64_t *)key; int64_t nowMS = taosGetTimestampMs(); diff --git a/source/libs/sync/test/CMakeLists.txt b/source/libs/sync/test/CMakeLists.txt index e1f3a2b2fc..e787080795 100644 --- a/source/libs/sync/test/CMakeLists.txt +++ b/source/libs/sync/test/CMakeLists.txt @@ -18,6 +18,7 @@ add_executable(syncIndexMgrTest "") add_executable(syncLogStoreTest "") add_executable(syncEntryTest "") add_executable(syncEntryCacheTest "") +add_executable(syncHashCacheTest "") add_executable(syncRequestVoteTest "") add_executable(syncRequestVoteReplyTest "") add_executable(syncAppendEntriesTest "") @@ -137,6 +138,10 @@ target_sources(syncEntryCacheTest PRIVATE "syncEntryCacheTest.cpp" ) +target_sources(syncHashCacheTest + PRIVATE + "syncHashCacheTest.cpp" +) target_sources(syncRequestVoteTest PRIVATE "syncRequestVoteTest.cpp" @@ -387,6 +392,11 @@ target_include_directories(syncEntryCacheTest "${TD_SOURCE_DIR}/include/libs/sync" "${CMAKE_CURRENT_SOURCE_DIR}/../inc" ) +target_include_directories(syncHashCacheTest + PUBLIC + "${TD_SOURCE_DIR}/include/libs/sync" + "${CMAKE_CURRENT_SOURCE_DIR}/../inc" +) target_include_directories(syncRequestVoteTest PUBLIC "${TD_SOURCE_DIR}/include/libs/sync" @@ -654,6 +664,10 @@ target_link_libraries(syncEntryCacheTest sync gtest_main ) +target_link_libraries(syncHashCacheTest + sync + gtest_main +) target_link_libraries(syncRequestVoteTest sync gtest_main diff --git a/source/libs/sync/test/syncEntryCacheTest.cpp b/source/libs/sync/test/syncEntryCacheTest.cpp index 6250181b25..66b93563e7 100644 --- a/source/libs/sync/test/syncEntryCacheTest.cpp +++ b/source/libs/sync/test/syncEntryCacheTest.cpp @@ -43,222 +43,82 @@ SRaftEntryCache* createCache(int maxCount) { SSyncNode* pSyncNode = createFakeNode(); ASSERT(pSyncNode != NULL); - SRaftEntryCache* pCache = raftCacheCreate(pSyncNode, maxCount); + SRaftEntryCache* pCache = raftEntryCacheCreate(pSyncNode, maxCount); ASSERT(pCache != NULL); return pCache; } void test1() { - int32_t code = 0; + int32_t code = 0; SRaftEntryCache* pCache = createCache(5); - for (int i = 0; i < 5; ++i) { + for (int i = 0; i < 10; ++i) { SSyncRaftEntry* pEntry = createEntry(i); - code = raftCachePutEntry(pCache, pEntry); - ASSERT(code == 1); - syncEntryDestory(pEntry); + code = raftEntryCachePutEntry(pCache, pEntry); + sTrace("put entry code:%d, pEntry:%p", code, pEntry); } - raftCacheLog2((char*)"==test1 write 5 entries==", pCache); + raftEntryCacheLog2((char*)"==test1 write 5 entries==", pCache); - SyncIndex index; - index = 1; - code = raftCacheDelEntry(pCache, index); - ASSERT(code == 0); - index = 3; - code = raftCacheDelEntry(pCache, index); - ASSERT(code == 0); - raftCacheLog2((char*)"==test1 delete 1,3==", pCache); + raftEntryCacheClear(pCache, 3); + raftEntryCacheLog2((char*)"==test1 evict 3 entries==", pCache); - code = raftCacheClear(pCache); - ASSERT(code == 0); - raftCacheLog2((char*)"==clear all==", pCache); + raftEntryCacheClear(pCache, -1); + raftEntryCacheLog2((char*)"==test1 evict -1(all) entries==", pCache); } void test2() { - int32_t code = 0; + int32_t code = 0; SRaftEntryCache* pCache = createCache(5); - for (int i = 0; i < 5; ++i) { + for (int i = 0; i < 10; ++i) { SSyncRaftEntry* pEntry = createEntry(i); - code = raftCachePutEntry(pCache, pEntry); - ASSERT(code == 1); - syncEntryDestory(pEntry); + code = raftEntryCachePutEntry(pCache, pEntry); + sTrace("put entry code:%d, pEntry:%p", code, pEntry); } - raftCacheLog2((char*)"==test2 write 5 entries==", pCache); + raftEntryCacheLog2((char*)"==test1 write 5 entries==", pCache); - SyncIndex index; - index = 1; - SSyncRaftEntry* pEntry; - code = raftCacheGetEntry(pCache, index, &pEntry); - ASSERT(code == 0); - syncEntryDestory(pEntry); - syncEntryLog2((char*)"==test2 get entry 1==", pEntry); + SyncIndex index = 2; + SSyncRaftEntry* pEntry = NULL; - index = 2; - code = raftCacheGetEntryP(pCache, index, &pEntry); - ASSERT(code == 0); + code = raftEntryCacheGetEntryP(pCache, index, &pEntry); + ASSERT(code == 1 && index == pEntry->index); + sTrace("get entry:%p for %ld", pEntry, index); syncEntryLog2((char*)"==test2 get entry pointer 2==", pEntry); + code = raftEntryCacheGetEntry(pCache, index, &pEntry); + ASSERT(code == 1 && index == pEntry->index); + sTrace("get entry:%p for %ld", pEntry, index); + syncEntryLog2((char*)"==test2 get entry 2==", pEntry); + syncEntryDestory(pEntry); + // not found index = 8; - code = raftCacheGetEntry(pCache, index, &pEntry); - ASSERT(code == -1 && terrno == TSDB_CODE_WAL_LOG_NOT_EXIST); + code = raftEntryCacheGetEntry(pCache, index, &pEntry); + ASSERT(code == 0); + sTrace("get entry:%p for %ld", pEntry, index); sTrace("==test2 get entry 8 not found=="); // not found index = 9; - code = raftCacheGetEntryP(pCache, index, &pEntry); - ASSERT(code == -1 && terrno == TSDB_CODE_WAL_LOG_NOT_EXIST); - sTrace("==test2 get entry pointer 9 not found=="); + code = raftEntryCacheGetEntry(pCache, index, &pEntry); + ASSERT(code == 0); + sTrace("get entry:%p for %ld", pEntry, index); + sTrace("==test2 get entry 9 not found=="); } void test3() { - int32_t code = 0; - SRaftEntryCache* pCache = createCache(5); - for (int i = 0; i < 5; ++i) { - SSyncRaftEntry* pEntry = createEntry(i); - code = raftCachePutEntry(pCache, pEntry); - ASSERT(code == 1); - syncEntryDestory(pEntry); - } - for (int i = 6; i < 10; ++i) { - SSyncRaftEntry* pEntry = createEntry(i); - code = raftCachePutEntry(pCache, pEntry); - ASSERT(code == 0); - syncEntryDestory(pEntry); - } - raftCacheLog2((char*)"==test3 write 10 entries, max count is 5==", pCache); -} - -void test4() { - int32_t code = 0; - SRaftEntryCache* pCache = createCache(5); - for (int i = 0; i < 5; ++i) { + int32_t code = 0; + SRaftEntryCache* pCache = createCache(20); + for (int i = 0; i <= 4; ++i) { SSyncRaftEntry* pEntry = createEntry(i); - code = raftCachePutEntry(pCache, pEntry); - ASSERT(code == 1); - syncEntryDestory(pEntry); - } - raftCacheLog2((char*)"==test4 write 5 entries==", pCache); - - SyncIndex index; - index = 3; - SSyncRaftEntry* pEntry; - code = raftCacheGetAndDel(pCache, index, &pEntry); - ASSERT(code == 0); - syncEntryLog2((char*)"==test4 get-and-del entry 3==", pEntry); - raftCacheLog2((char*)"==test4 after get-and-del entry 3==", pCache); -} - -static char* keyFn(const void* pData) { - SSyncRaftEntry* pEntry = (SSyncRaftEntry*)pData; - return (char*)(&(pEntry->index)); -} - -static int cmpFn(const void* p1, const void* p2) { return memcmp(p1, p2, sizeof(SyncIndex)); } - -void printSkipList(SSkipList* pSkipList) { - ASSERT(pSkipList != NULL); - - SSkipListIterator* pIter = tSkipListCreateIter(pSkipList); - while (tSkipListIterNext(pIter)) { - SSkipListNode* pNode = tSkipListIterGet(pIter); - ASSERT(pNode != NULL); - SSyncRaftEntry* pEntry = (SSyncRaftEntry*)SL_GET_NODE_DATA(pNode); - syncEntryPrint2((char*)"", pEntry); - } -} - -void delSkipListFirst(SSkipList* pSkipList, int n) { - ASSERT(pSkipList != NULL); - - sTrace("delete first %d -------------", n); - SSkipListIterator* pIter = tSkipListCreateIter(pSkipList); - for (int i = 0; i < n; ++i) { - tSkipListIterNext(pIter); - SSkipListNode* pNode = tSkipListIterGet(pIter); - tSkipListRemoveNode(pSkipList, pNode); + code = raftEntryCachePutEntry(pCache, pEntry); + sTrace("put entry code:%d, pEntry:%p", code, pEntry); } -} - - -SSyncRaftEntry* getLogEntry2(SSkipList* pSkipList, SyncIndex index) { - SyncIndex index2 = index; - SSyncRaftEntry *pEntry = NULL; - int arraySize = 0; - - SArray* entryPArray = tSkipListGet(pSkipList, (char*)(&index2)); - arraySize = taosArrayGetSize(entryPArray); - if (arraySize > 0) { - SSkipListNode** ppNode = (SSkipListNode**)taosArrayGet(entryPArray, 0); - ASSERT(*ppNode != NULL); - pEntry = (SSyncRaftEntry*)SL_GET_NODE_DATA(*ppNode); - } - taosArrayDestroy(entryPArray); - - sTrace("get index2: %ld, arraySize:%d -------------", index, arraySize); - syncEntryLog2((char*)"getLogEntry2", pEntry); - return pEntry; -} - - -SSyncRaftEntry* getLogEntry(SSkipList* pSkipList, SyncIndex index) { - sTrace("get index: %ld -------------", index); - SyncIndex index2 = index; - SSyncRaftEntry *pEntry = NULL; - SSkipListIterator* pIter = tSkipListCreateIterFromVal(pSkipList, (const char *)&index2, TSDB_DATA_TYPE_BINARY, TSDB_ORDER_ASC); - if (tSkipListIterNext(pIter)) { - SSkipListNode* pNode = tSkipListIterGet(pIter); - ASSERT(pNode != NULL); - pEntry = (SSyncRaftEntry*)SL_GET_NODE_DATA(pNode); - } - - syncEntryLog2((char*)"getLogEntry", pEntry); - return pEntry; -} - -void test5() { - SSkipList* pSkipList = - tSkipListCreate(MAX_SKIP_LIST_LEVEL, TSDB_DATA_TYPE_BINARY, sizeof(SyncIndex), cmpFn, SL_ALLOW_DUP_KEY, keyFn); - ASSERT(pSkipList != NULL); - - sTrace("insert 9 - 5"); for (int i = 9; i >= 5; --i) { SSyncRaftEntry* pEntry = createEntry(i); - SSkipListNode* pSkipListNode = tSkipListPut(pSkipList, pEntry); + code = raftEntryCachePutEntry(pCache, pEntry); + sTrace("put entry code:%d, pEntry:%p", code, pEntry); } - - sTrace("insert 0 - 4"); - for (int i = 0; i <= 4; ++i) { - SSyncRaftEntry* pEntry = createEntry(i); - SSkipListNode* pSkipListNode = tSkipListPut(pSkipList, pEntry); - } - - sTrace("insert 7 7 7 7 7"); - for (int i = 0; i <= 4; ++i) { - SSyncRaftEntry* pEntry = createEntry(7); - SSkipListNode* pSkipListNode = tSkipListPut(pSkipList, pEntry); - } - - sTrace("print: -------------"); - printSkipList(pSkipList); - - delSkipListFirst(pSkipList, 3); - - sTrace("print: -------------"); - printSkipList(pSkipList); - - getLogEntry(pSkipList, 2); - getLogEntry(pSkipList, 5); - getLogEntry(pSkipList, 7); - getLogEntry(pSkipList, 7); - - getLogEntry2(pSkipList, 2); - getLogEntry2(pSkipList, 5); - getLogEntry2(pSkipList, 7); - getLogEntry2(pSkipList, 7); - - - tSkipListDestroy(pSkipList); + raftEntryCacheLog2((char*)"==test3 write 10 entries==", pCache); } int main(int argc, char** argv) { @@ -266,14 +126,9 @@ int main(int argc, char** argv) { tsAsyncLog = 0; sDebugFlag = DEBUG_TRACE + DEBUG_SCREEN + DEBUG_FILE + DEBUG_DEBUG; - /* - test1(); - test2(); - test3(); - test4(); - */ - - test5(); + test1(); + test2(); + test3(); return 0; } diff --git a/source/libs/sync/test/syncHashCacheTest.cpp b/source/libs/sync/test/syncHashCacheTest.cpp new file mode 100644 index 0000000000..f155bd834f --- /dev/null +++ b/source/libs/sync/test/syncHashCacheTest.cpp @@ -0,0 +1,277 @@ +#include +#include "syncEnv.h" +#include "syncIO.h" +#include "syncInt.h" +#include "syncRaftLog.h" +#include "syncRaftStore.h" +#include "syncUtil.h" +#include "tskiplist.h" + +void logTest() { + sTrace("--- sync log test: trace"); + sDebug("--- sync log test: debug"); + sInfo("--- sync log test: info"); + sWarn("--- sync log test: warn"); + sError("--- sync log test: error"); + sFatal("--- sync log test: fatal"); +} + +SSyncRaftEntry* createEntry(int i) { + int32_t dataLen = 20; + SSyncRaftEntry* pEntry = syncEntryBuild(dataLen); + assert(pEntry != NULL); + pEntry->msgType = 88; + pEntry->originalRpcType = 99; + pEntry->seqNum = 3; + pEntry->isWeak = true; + pEntry->term = 100 + i; + pEntry->index = i; + snprintf(pEntry->data, dataLen, "value%d", i); + + return pEntry; +} + +SSyncNode* createFakeNode() { + SSyncNode* pSyncNode = (SSyncNode*)taosMemoryMalloc(sizeof(SSyncNode)); + ASSERT(pSyncNode != NULL); + memset(pSyncNode, 0, sizeof(SSyncNode)); + + return pSyncNode; +} + +SRaftEntryHashCache* createCache(int maxCount) { + SSyncNode* pSyncNode = createFakeNode(); + ASSERT(pSyncNode != NULL); + + SRaftEntryHashCache* pCache = raftCacheCreate(pSyncNode, maxCount); + ASSERT(pCache != NULL); + + return pCache; +} + +void test1() { + int32_t code = 0; + SRaftEntryHashCache* pCache = createCache(5); + for (int i = 0; i < 5; ++i) { + SSyncRaftEntry* pEntry = createEntry(i); + code = raftCachePutEntry(pCache, pEntry); + ASSERT(code == 1); + syncEntryDestory(pEntry); + } + raftCacheLog2((char*)"==test1 write 5 entries==", pCache); + + SyncIndex index; + index = 1; + code = raftCacheDelEntry(pCache, index); + ASSERT(code == 0); + index = 3; + code = raftCacheDelEntry(pCache, index); + ASSERT(code == 0); + raftCacheLog2((char*)"==test1 delete 1,3==", pCache); + + code = raftCacheClear(pCache); + ASSERT(code == 0); + raftCacheLog2((char*)"==clear all==", pCache); +} + +void test2() { + int32_t code = 0; + SRaftEntryHashCache* pCache = createCache(5); + for (int i = 0; i < 5; ++i) { + SSyncRaftEntry* pEntry = createEntry(i); + code = raftCachePutEntry(pCache, pEntry); + ASSERT(code == 1); + syncEntryDestory(pEntry); + } + raftCacheLog2((char*)"==test2 write 5 entries==", pCache); + + SyncIndex index; + index = 1; + SSyncRaftEntry* pEntry; + code = raftCacheGetEntry(pCache, index, &pEntry); + ASSERT(code == 0); + syncEntryDestory(pEntry); + syncEntryLog2((char*)"==test2 get entry 1==", pEntry); + + index = 2; + code = raftCacheGetEntryP(pCache, index, &pEntry); + ASSERT(code == 0); + syncEntryLog2((char*)"==test2 get entry pointer 2==", pEntry); + + // not found + index = 8; + code = raftCacheGetEntry(pCache, index, &pEntry); + ASSERT(code == -1 && terrno == TSDB_CODE_WAL_LOG_NOT_EXIST); + sTrace("==test2 get entry 8 not found=="); + + // not found + index = 9; + code = raftCacheGetEntryP(pCache, index, &pEntry); + ASSERT(code == -1 && terrno == TSDB_CODE_WAL_LOG_NOT_EXIST); + sTrace("==test2 get entry pointer 9 not found=="); +} + +void test3() { + int32_t code = 0; + SRaftEntryHashCache* pCache = createCache(5); + for (int i = 0; i < 5; ++i) { + SSyncRaftEntry* pEntry = createEntry(i); + code = raftCachePutEntry(pCache, pEntry); + ASSERT(code == 1); + syncEntryDestory(pEntry); + } + for (int i = 6; i < 10; ++i) { + SSyncRaftEntry* pEntry = createEntry(i); + code = raftCachePutEntry(pCache, pEntry); + ASSERT(code == 0); + syncEntryDestory(pEntry); + } + raftCacheLog2((char*)"==test3 write 10 entries, max count is 5==", pCache); +} + +void test4() { + int32_t code = 0; + SRaftEntryHashCache* pCache = createCache(5); + for (int i = 0; i < 5; ++i) { + SSyncRaftEntry* pEntry = createEntry(i); + code = raftCachePutEntry(pCache, pEntry); + ASSERT(code == 1); + syncEntryDestory(pEntry); + } + raftCacheLog2((char*)"==test4 write 5 entries==", pCache); + + SyncIndex index; + index = 3; + SSyncRaftEntry* pEntry; + code = raftCacheGetAndDel(pCache, index, &pEntry); + ASSERT(code == 0); + syncEntryLog2((char*)"==test4 get-and-del entry 3==", pEntry); + raftCacheLog2((char*)"==test4 after get-and-del entry 3==", pCache); +} + +static char* keyFn(const void* pData) { + SSyncRaftEntry* pEntry = (SSyncRaftEntry*)pData; + return (char*)(&(pEntry->index)); +} + +static int cmpFn(const void* p1, const void* p2) { return memcmp(p1, p2, sizeof(SyncIndex)); } + +void printSkipList(SSkipList* pSkipList) { + ASSERT(pSkipList != NULL); + + SSkipListIterator* pIter = tSkipListCreateIter(pSkipList); + while (tSkipListIterNext(pIter)) { + SSkipListNode* pNode = tSkipListIterGet(pIter); + ASSERT(pNode != NULL); + SSyncRaftEntry* pEntry = (SSyncRaftEntry*)SL_GET_NODE_DATA(pNode); + syncEntryPrint2((char*)"", pEntry); + } +} + +void delSkipListFirst(SSkipList* pSkipList, int n) { + ASSERT(pSkipList != NULL); + + sTrace("delete first %d -------------", n); + SSkipListIterator* pIter = tSkipListCreateIter(pSkipList); + for (int i = 0; i < n; ++i) { + tSkipListIterNext(pIter); + SSkipListNode* pNode = tSkipListIterGet(pIter); + tSkipListRemoveNode(pSkipList, pNode); + } +} + +SSyncRaftEntry* getLogEntry2(SSkipList* pSkipList, SyncIndex index) { + SyncIndex index2 = index; + SSyncRaftEntry* pEntry = NULL; + int arraySize = 0; + + SArray* entryPArray = tSkipListGet(pSkipList, (char*)(&index2)); + arraySize = taosArrayGetSize(entryPArray); + if (arraySize > 0) { + SSkipListNode** ppNode = (SSkipListNode**)taosArrayGet(entryPArray, 0); + ASSERT(*ppNode != NULL); + pEntry = (SSyncRaftEntry*)SL_GET_NODE_DATA(*ppNode); + } + taosArrayDestroy(entryPArray); + + sTrace("get index2: %ld, arraySize:%d -------------", index, arraySize); + syncEntryLog2((char*)"getLogEntry2", pEntry); + return pEntry; +} + +SSyncRaftEntry* getLogEntry(SSkipList* pSkipList, SyncIndex index) { + sTrace("get index: %ld -------------", index); + SyncIndex index2 = index; + SSyncRaftEntry* pEntry = NULL; + SSkipListIterator* pIter = + tSkipListCreateIterFromVal(pSkipList, (const char*)&index2, TSDB_DATA_TYPE_BINARY, TSDB_ORDER_ASC); + if (tSkipListIterNext(pIter)) { + SSkipListNode* pNode = tSkipListIterGet(pIter); + ASSERT(pNode != NULL); + pEntry = (SSyncRaftEntry*)SL_GET_NODE_DATA(pNode); + } + + syncEntryLog2((char*)"getLogEntry", pEntry); + return pEntry; +} + +void test5() { + SSkipList* pSkipList = + tSkipListCreate(MAX_SKIP_LIST_LEVEL, TSDB_DATA_TYPE_BINARY, sizeof(SyncIndex), cmpFn, SL_ALLOW_DUP_KEY, keyFn); + ASSERT(pSkipList != NULL); + + sTrace("insert 9 - 5"); + for (int i = 9; i >= 5; --i) { + SSyncRaftEntry* pEntry = createEntry(i); + SSkipListNode* pSkipListNode = tSkipListPut(pSkipList, pEntry); + } + + sTrace("insert 0 - 4"); + for (int i = 0; i <= 4; ++i) { + SSyncRaftEntry* pEntry = createEntry(i); + SSkipListNode* pSkipListNode = tSkipListPut(pSkipList, pEntry); + } + + sTrace("insert 7 7 7 7 7"); + for (int i = 0; i <= 4; ++i) { + SSyncRaftEntry* pEntry = createEntry(7); + SSkipListNode* pSkipListNode = tSkipListPut(pSkipList, pEntry); + } + + sTrace("print: -------------"); + printSkipList(pSkipList); + + delSkipListFirst(pSkipList, 3); + + sTrace("print: -------------"); + printSkipList(pSkipList); + + getLogEntry(pSkipList, 2); + getLogEntry(pSkipList, 5); + getLogEntry(pSkipList, 7); + getLogEntry(pSkipList, 7); + + getLogEntry2(pSkipList, 2); + getLogEntry2(pSkipList, 5); + getLogEntry2(pSkipList, 7); + getLogEntry2(pSkipList, 7); + + tSkipListDestroy(pSkipList); +} + +int main(int argc, char** argv) { + gRaftDetailLog = true; + tsAsyncLog = 0; + sDebugFlag = DEBUG_TRACE + DEBUG_SCREEN + DEBUG_FILE + DEBUG_DEBUG; + + /* + test1(); + test2(); + test3(); + test4(); + */ + + test5(); + + return 0; +} -- GitLab From 531dfd4452e75f924584908a93eb2bdc52ff97dd Mon Sep 17 00:00:00 2001 From: wangmm0220 Date: Wed, 13 Jul 2022 16:00:06 +0800 Subject: [PATCH 056/153] fix:error in tmq meta --- examples/c/tmq.c | 4 ++-- source/client/src/tmq.c | 3 +++ source/dnode/vnode/src/vnd/vnodeSvr.c | 2 +- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/examples/c/tmq.c b/examples/c/tmq.c index 24c415b2fc..94e0b86821 100644 --- a/examples/c/tmq.c +++ b/examples/c/tmq.c @@ -35,7 +35,7 @@ static void msg_process(TAOS_RES* msg) { return; } - TAOS_RES* pRes = taos_query(pConn, "create database if not exists abc1 vgroups 1"); + TAOS_RES* pRes = taos_query(pConn, "create database if not exists abc1 vgroups 5"); if (taos_errno(pRes) != 0) { printf("error in create db, reason:%s\n", taos_errstr(pRes)); return; @@ -82,7 +82,7 @@ int32_t init_env() { return -1; } - TAOS_RES* pRes = taos_query(pConn, "create database if not exists abc1 vgroups 3"); + TAOS_RES* pRes = taos_query(pConn, "create database if not exists abc1 vgroups 5"); if (taos_errno(pRes) != 0) { printf("error in create db, reason:%s\n", taos_errstr(pRes)); return -1; diff --git a/source/client/src/tmq.c b/source/client/src/tmq.c index 7e01e5cd83..d4d7c05b56 100644 --- a/source/client/src/tmq.c +++ b/source/client/src/tmq.c @@ -2856,6 +2856,9 @@ static int32_t taosAlterTable(TAOS *taos, void *meta, int32_t metaLen){ pVgData = NULL; pArray = NULL; code = pRequest->code; + if (code == TSDB_CODE_VND_TABLE_NOT_EXIST){ + code = 0; + } end: taosArrayDestroy(pArray); diff --git a/source/dnode/vnode/src/vnd/vnodeSvr.c b/source/dnode/vnode/src/vnd/vnodeSvr.c index d25ae817c7..d369475437 100644 --- a/source/dnode/vnode/src/vnd/vnodeSvr.c +++ b/source/dnode/vnode/src/vnd/vnodeSvr.c @@ -611,7 +611,7 @@ static int32_t vnodeProcessAlterTbReq(SVnode *pVnode, int64_t version, void *pRe // process if (metaAlterTable(pVnode->pMeta, version, &vAlterTbReq, &vMetaRsp) < 0) { - vAlterTbRsp.code = TSDB_CODE_INVALID_MSG; + vAlterTbRsp.code = terrno; tDecoderClear(&dc); rcode = -1; goto _exit; -- GitLab From c2aebfa3224e9fd50ed03d65924ecdd6cf4aee43 Mon Sep 17 00:00:00 2001 From: Shengliang Guan Date: Wed, 13 Jul 2022 16:26:22 +0800 Subject: [PATCH 057/153] enh: add stream queue to vnode --- include/common/tglobal.h | 1 + include/common/tmsgcb.h | 1 + source/common/src/tglobal.c | 6 ++++ source/dnode/mgmt/mgmt_vnode/inc/vmInt.h | 3 ++ source/dnode/mgmt/mgmt_vnode/src/vmInt.c | 1 + source/dnode/mgmt/mgmt_vnode/src/vmWorker.c | 39 ++++++++++++++++++++- source/libs/stream/src/stream.c | 2 +- 7 files changed, 51 insertions(+), 2 deletions(-) diff --git a/include/common/tglobal.h b/include/common/tglobal.h index 944eaa28bc..96014b1234 100644 --- a/include/common/tglobal.h +++ b/include/common/tglobal.h @@ -64,6 +64,7 @@ extern int32_t tsNumOfMnodeQueryThreads; extern int32_t tsNumOfMnodeFetchThreads; extern int32_t tsNumOfMnodeReadThreads; extern int32_t tsNumOfVnodeQueryThreads; +extern int32_t tsNumOfVnodeStreamThreads; extern int32_t tsNumOfVnodeFetchThreads; extern int32_t tsNumOfVnodeWriteThreads; extern int32_t tsNumOfVnodeSyncThreads; diff --git a/include/common/tmsgcb.h b/include/common/tmsgcb.h index b56f755266..c13c50e161 100644 --- a/include/common/tmsgcb.h +++ b/include/common/tmsgcb.h @@ -34,6 +34,7 @@ typedef enum { WRITE_QUEUE, APPLY_QUEUE, SYNC_QUEUE, + STREAM_QUEUE, QUEUE_MAX, } EQueueType; diff --git a/source/common/src/tglobal.c b/source/common/src/tglobal.c index 24bf4e5c2d..2d3f35ea39 100644 --- a/source/common/src/tglobal.c +++ b/source/common/src/tglobal.c @@ -55,6 +55,7 @@ int32_t tsNumOfMnodeQueryThreads = 2; int32_t tsNumOfMnodeFetchThreads = 1; int32_t tsNumOfMnodeReadThreads = 1; int32_t tsNumOfVnodeQueryThreads = 2; +int32_t tsNumOfVnodeStreamThreads = 2; int32_t tsNumOfVnodeFetchThreads = 4; int32_t tsNumOfVnodeWriteThreads = 2; int32_t tsNumOfVnodeSyncThreads = 2; @@ -412,6 +413,10 @@ static int32_t taosAddServerCfg(SConfig *pCfg) { tsNumOfVnodeQueryThreads = TMAX(tsNumOfVnodeQueryThreads, 2); if (cfgAddInt32(pCfg, "numOfVnodeQueryThreads", tsNumOfVnodeQueryThreads, 1, 1024, 0) != 0) return -1; + tsNumOfVnodeStreamThreads = tsNumOfCores / 4; + tsNumOfVnodeStreamThreads = TMAX(tsNumOfVnodeStreamThreads, 4); + if (cfgAddInt32(pCfg, "numOfVnodeStreamThreads", tsNumOfVnodeStreamThreads, 1, 1024, 0) != 0) return -1; + tsNumOfVnodeFetchThreads = tsNumOfCores / 4; tsNumOfVnodeFetchThreads = TMAX(tsNumOfVnodeFetchThreads, 4); if (cfgAddInt32(pCfg, "numOfVnodeFetchThreads", tsNumOfVnodeFetchThreads, 1, 1024, 0) != 0) return -1; @@ -587,6 +592,7 @@ static int32_t taosSetServerCfg(SConfig *pCfg) { tsNumOfMnodeQueryThreads = cfgGetItem(pCfg, "numOfMnodeQueryThreads")->i32; tsNumOfMnodeReadThreads = cfgGetItem(pCfg, "numOfMnodeReadThreads")->i32; tsNumOfVnodeQueryThreads = cfgGetItem(pCfg, "numOfVnodeQueryThreads")->i32; + tsNumOfVnodeStreamThreads = cfgGetItem(pCfg, "numOfVnodeStreamThreads")->i32; tsNumOfVnodeFetchThreads = cfgGetItem(pCfg, "numOfVnodeFetchThreads")->i32; tsNumOfVnodeWriteThreads = cfgGetItem(pCfg, "numOfVnodeWriteThreads")->i32; tsNumOfVnodeSyncThreads = cfgGetItem(pCfg, "numOfVnodeSyncThreads")->i32; diff --git a/source/dnode/mgmt/mgmt_vnode/inc/vmInt.h b/source/dnode/mgmt/mgmt_vnode/inc/vmInt.h index 6fc0ab4e5d..ebbb9fa5d4 100644 --- a/source/dnode/mgmt/mgmt_vnode/inc/vmInt.h +++ b/source/dnode/mgmt/mgmt_vnode/inc/vmInt.h @@ -31,6 +31,7 @@ typedef struct SVnodeMgmt { const char *path; const char *name; SQWorkerPool queryPool; + SQWorkerPool streamPool; SWWorkerPool fetchPool; SWWorkerPool syncPool; SWWorkerPool writePool; @@ -61,6 +62,7 @@ typedef struct { STaosQueue *pSyncQ; STaosQueue *pApplyQ; STaosQueue *pQueryQ; + STaosQueue *pStreamQ; STaosQueue *pFetchQ; } SVnodeObj; @@ -105,6 +107,7 @@ int32_t vmPutMsgToWriteQueue(SVnodeMgmt *pMgmt, SRpcMsg *pMsg); int32_t vmPutMsgToSyncQueue(SVnodeMgmt *pMgmt, SRpcMsg *pMsg); int32_t vmPutMsgToQueryQueue(SVnodeMgmt *pMgmt, SRpcMsg *pMsg); int32_t vmPutMsgToFetchQueue(SVnodeMgmt *pMgmt, SRpcMsg *pMsg); +int32_t vmPutMsgToStreamQueue(SVnodeMgmt *pMgmt, SRpcMsg *pMsg); int32_t vmPutMsgToMergeQueue(SVnodeMgmt *pMgmt, SRpcMsg *pMsg); int32_t vmPutMsgToMgmtQueue(SVnodeMgmt *pMgmt, SRpcMsg *pMsg); int32_t vmPutMsgToMonitorQueue(SVnodeMgmt *pMgmt, SRpcMsg *pMsg); diff --git a/source/dnode/mgmt/mgmt_vnode/src/vmInt.c b/source/dnode/mgmt/mgmt_vnode/src/vmInt.c index 36f6fab699..1f981cc9e0 100644 --- a/source/dnode/mgmt/mgmt_vnode/src/vmInt.c +++ b/source/dnode/mgmt/mgmt_vnode/src/vmInt.c @@ -92,6 +92,7 @@ void vmCloseVnode(SVnodeMgmt *pMgmt, SVnodeObj *pVnode) { while (!taosQueueEmpty(pVnode->pApplyQ)) taosMsleep(10); while (!taosQueueEmpty(pVnode->pQueryQ)) taosMsleep(10); while (!taosQueueEmpty(pVnode->pFetchQ)) taosMsleep(10); + while (!taosQueueEmpty(pVnode->pStreamQ)) taosMsleep(10); dTrace("vgId:%d, vnode queue is empty", pVnode->vgId); vmFreeQueue(pMgmt, pVnode); diff --git a/source/dnode/mgmt/mgmt_vnode/src/vmWorker.c b/source/dnode/mgmt/mgmt_vnode/src/vmWorker.c index 93f93b1ab7..4a60dbfe0f 100644 --- a/source/dnode/mgmt/mgmt_vnode/src/vmWorker.c +++ b/source/dnode/mgmt/mgmt_vnode/src/vmWorker.c @@ -81,6 +81,23 @@ static void vmProcessQueryQueue(SQueueInfo *pInfo, SRpcMsg *pMsg) { taosFreeQitem(pMsg); } +static void vmProcessStreamQueue(SQueueInfo *pInfo, SRpcMsg *pMsg) { + SVnodeObj *pVnode = pInfo->ahandle; + const STraceId *trace = &pMsg->info.traceId; + + dGTrace("vgId:%d, msg:%p get from vnode-stream queue", pVnode->vgId, pMsg); + int32_t code = vnodeProcessFetchMsg(pVnode->pImpl, pMsg, pInfo); + if (code != 0) { + if (terrno != 0) code = terrno; + dGError("vgId:%d, msg:%p failed to stream since %s", pVnode->vgId, pMsg, terrstr()); + vmSendRsp(pMsg, code); + } + + dGTrace("vgId:%d, msg:%p is freed, code:0x%x", pVnode->vgId, pMsg, code); + rpcFreeCont(pMsg->pCont); + taosFreeQitem(pMsg); +} + static void vmProcessFetchQueue(SQueueInfo *pInfo, STaosQall *qall, int32_t numOfMsgs) { SVnodeObj *pVnode = pInfo->ahandle; SRpcMsg *pMsg = NULL; @@ -140,6 +157,10 @@ static int32_t vmPutMsgToQueue(SVnodeMgmt *pMgmt, SRpcMsg *pMsg, EQueueType qtyp dGTrace("vgId:%d, msg:%p put into vnode-query queue", pVnode->vgId, pMsg); taosWriteQitem(pVnode->pQueryQ, pMsg); break; + case STREAM_QUEUE: + dGTrace("vgId:%d, msg:%p put into vnode-stream queue", pVnode->vgId, pMsg); + taosWriteQitem(pVnode->pStreamQ, pMsg); + break; case FETCH_QUEUE: dGTrace("vgId:%d, msg:%p put into vnode-fetch queue", pVnode->vgId, pMsg); taosWriteQitem(pVnode->pFetchQ, pMsg); @@ -174,6 +195,8 @@ int32_t vmPutMsgToQueryQueue(SVnodeMgmt *pMgmt, SRpcMsg *pMsg) { return vmPutMsg int32_t vmPutMsgToFetchQueue(SVnodeMgmt *pMgmt, SRpcMsg *pMsg) { return vmPutMsgToQueue(pMgmt, pMsg, FETCH_QUEUE); } +int32_t vmPutMsgToStreamQueue(SVnodeMgmt *pMgmt, SRpcMsg *pMsg) { return vmPutMsgToQueue(pMgmt, pMsg, STREAM_QUEUE); } + int32_t vmPutMsgToMgmtQueue(SVnodeMgmt *pMgmt, SRpcMsg *pMsg) { const STraceId *trace = &pMsg->info.traceId; dGTrace("msg:%p, put into vnode-mgmt queue", pMsg); @@ -234,6 +257,9 @@ int32_t vmGetQueueSize(SVnodeMgmt *pMgmt, int32_t vgId, EQueueType qtype) { case FETCH_QUEUE: size = taosQueueItemSize(pVnode->pFetchQ); break; + case STREAM_QUEUE: + size = taosQueueItemSize(pVnode->pStreamQ); + break; default: break; } @@ -247,10 +273,11 @@ int32_t vmAllocQueue(SVnodeMgmt *pMgmt, SVnodeObj *pVnode) { pVnode->pSyncQ = tWWorkerAllocQueue(&pMgmt->syncPool, pVnode, (FItems)vmProcessSyncQueue); pVnode->pApplyQ = tWWorkerAllocQueue(&pMgmt->applyPool, pVnode->pImpl, (FItems)vnodeApplyWriteMsg); pVnode->pQueryQ = tQWorkerAllocQueue(&pMgmt->queryPool, pVnode, (FItem)vmProcessQueryQueue); + pVnode->pStreamQ = tQWorkerAllocQueue(&pMgmt->streamPool, pVnode, (FItem)vmProcessStreamQueue); pVnode->pFetchQ = tWWorkerAllocQueue(&pMgmt->fetchPool, pVnode, (FItems)vmProcessFetchQueue); if (pVnode->pWriteQ == NULL || pVnode->pSyncQ == NULL || pVnode->pApplyQ == NULL || pVnode->pQueryQ == NULL || - pVnode->pFetchQ == NULL) { + pVnode->pStreamQ == NULL || pVnode->pFetchQ == NULL) { terrno = TSDB_CODE_OUT_OF_MEMORY; return -1; } @@ -259,6 +286,7 @@ int32_t vmAllocQueue(SVnodeMgmt *pMgmt, SVnodeObj *pVnode) { dDebug("vgId:%d, sync-queue:%p is alloced", pVnode->vgId, pVnode->pSyncQ); dDebug("vgId:%d, apply-queue:%p is alloced", pVnode->vgId, pVnode->pApplyQ); dDebug("vgId:%d, query-queue:%p is alloced", pVnode->vgId, pVnode->pQueryQ); + dDebug("vgId:%d, stream-queue:%p is alloced", pVnode->vgId, pVnode->pStreamQ); dDebug("vgId:%d, fetch-queue:%p is alloced", pVnode->vgId, pVnode->pFetchQ); return 0; } @@ -268,11 +296,13 @@ void vmFreeQueue(SVnodeMgmt *pMgmt, SVnodeObj *pVnode) { tWWorkerFreeQueue(&pMgmt->applyPool, pVnode->pApplyQ); tWWorkerFreeQueue(&pMgmt->syncPool, pVnode->pSyncQ); tQWorkerFreeQueue(&pMgmt->queryPool, pVnode->pQueryQ); + tQWorkerFreeQueue(&pMgmt->streamPool, pVnode->pStreamQ); tWWorkerFreeQueue(&pMgmt->fetchPool, pVnode->pFetchQ); pVnode->pWriteQ = NULL; pVnode->pSyncQ = NULL; pVnode->pApplyQ = NULL; pVnode->pQueryQ = NULL; + pVnode->pStreamQ = NULL; pVnode->pFetchQ = NULL; dDebug("vgId:%d, queue is freed", pVnode->vgId); } @@ -284,6 +314,12 @@ int32_t vmStartWorker(SVnodeMgmt *pMgmt) { pQPool->max = tsNumOfVnodeQueryThreads; if (tQWorkerInit(pQPool) != 0) return -1; + SQWorkerPool *pStreamPool = &pMgmt->streamPool; + pStreamPool->name = "vnode-stream"; + pStreamPool->min = tsNumOfVnodeStreamThreads; + pStreamPool->max = tsNumOfVnodeStreamThreads; + if (tQWorkerInit(pStreamPool) != 0) return -1; + SWWorkerPool *pFPool = &pMgmt->fetchPool; pFPool->name = "vnode-fetch"; pFPool->max = tsNumOfVnodeFetchThreads; @@ -333,6 +369,7 @@ void vmStopWorker(SVnodeMgmt *pMgmt) { tWWorkerCleanup(&pMgmt->applyPool); tWWorkerCleanup(&pMgmt->syncPool); tQWorkerCleanup(&pMgmt->queryPool); + tQWorkerCleanup(&pMgmt->streamPool); tWWorkerCleanup(&pMgmt->fetchPool); dDebug("vnode workers are closed"); } diff --git a/source/libs/stream/src/stream.c b/source/libs/stream/src/stream.c index becfac0cac..566d9209a8 100644 --- a/source/libs/stream/src/stream.c +++ b/source/libs/stream/src/stream.c @@ -97,7 +97,7 @@ int32_t streamLaunchByWrite(SStreamTask* pTask, int32_t vgId) { .pCont = pRunReq, .contLen = sizeof(SStreamTaskRunReq), }; - tmsgPutToQueue(pTask->pMsgCb, FETCH_QUEUE, &msg); + tmsgPutToQueue(pTask->pMsgCb, STREAM_QUEUE, &msg); } return 0; } -- GitLab From ff20bae06bd3e26c7707e3219c20316742515c67 Mon Sep 17 00:00:00 2001 From: Shengliang Guan Date: Wed, 13 Jul 2022 16:36:03 +0800 Subject: [PATCH 058/153] test: restore some 2.0 case --- tests/script/general/import/testSuite.sim | 4 --- tests/script/jenkins/basic.txt | 6 ++++ .../script/{general => tsim}/import/basic.sim | 26 ---------------- .../{general => tsim}/import/commit.sim | 28 ----------------- .../script/{general => tsim}/import/large.sim | 26 ---------------- .../{general => tsim}/import/replica1.sim | 31 ------------------- 6 files changed, 6 insertions(+), 115 deletions(-) delete mode 100644 tests/script/general/import/testSuite.sim rename tests/script/{general => tsim}/import/basic.sim (74%) rename tests/script/{general => tsim}/import/commit.sim (64%) rename tests/script/{general => tsim}/import/large.sim (61%) rename tests/script/{general => tsim}/import/replica1.sim (83%) diff --git a/tests/script/general/import/testSuite.sim b/tests/script/general/import/testSuite.sim deleted file mode 100644 index 9157410ea5..0000000000 --- a/tests/script/general/import/testSuite.sim +++ /dev/null @@ -1,4 +0,0 @@ -run general/import/basic.sim -run general/import/commit.sim -run general/import/large.sim -run general/import/replica1.sim diff --git a/tests/script/jenkins/basic.txt b/tests/script/jenkins/basic.txt index b24ca5f85e..32279b3a4a 100644 --- a/tests/script/jenkins/basic.txt +++ b/tests/script/jenkins/basic.txt @@ -66,6 +66,12 @@ # ./test.sh -f tsim/dnode/redistribute_vgroup_replica3_v3.sim # ./test.sh -f tsim/dnode/vnode_clean.sim +# ---- import +./test.sh -f tsim/import/basic.sim +./test.sh -f tsim/import/commit.sim +./test.sh -f tsim/import/large.sim +./test.sh -f tsim/import/replica1.sim + # ---- insert ./test.sh -f tsim/insert/basic0.sim ./test.sh -f tsim/insert/basic1.sim diff --git a/tests/script/general/import/basic.sim b/tests/script/tsim/import/basic.sim similarity index 74% rename from tests/script/general/import/basic.sim rename to tests/script/tsim/import/basic.sim index f72d132ca3..cb1b525120 100644 --- a/tests/script/general/import/basic.sim +++ b/tests/script/tsim/import/basic.sim @@ -1,32 +1,6 @@ system sh/stop_dnodes.sh system sh/deploy.sh -n dnode1 -i 1 -system sh/deploy.sh -n dnode2 -i 2 -system sh/deploy.sh -n dnode3 -i 3 -system sh/deploy.sh -n dnode4 -i 4 - -system sh/cfg.sh -n dnode1 -c numOfMnodes -v 1 -system sh/cfg.sh -n dnode2 -c numOfMnodes -v 1 -system sh/cfg.sh -n dnode3 -c numOfMnodes -v 1 -system sh/cfg.sh -n dnode4 -c numOfMnodes -v 1 - -system sh/cfg.sh -n dnode1 -c mnodeEqualVnodeNum -v 10 -system sh/cfg.sh -n dnode2 -c mnodeEqualVnodeNum -v 10 -system sh/cfg.sh -n dnode3 -c mnodeEqualVnodeNum -v 10 -system sh/cfg.sh -n dnode4 -c mnodeEqualVnodeNum -v 10 - -system sh/cfg.sh -n dnode1 -c maxtablesPerVnode -v 2000 -system sh/cfg.sh -n dnode2 -c maxtablesPerVnode -v 2000 -system sh/cfg.sh -n dnode3 -c maxtablesPerVnode -v 2000 -system sh/cfg.sh -n dnode4 -c maxtablesPerVnode -v 2000 - -system sh/cfg.sh -n dnode1 -c walLevel -v 1 -system sh/cfg.sh -n dnode2 -c walLevel -v 1 -system sh/cfg.sh -n dnode3 -c walLevel -v 1 -system sh/cfg.sh -n dnode4 -c walLevel -v 1 - -print ========= start dnode1 system sh/exec.sh -n dnode1 -s start -sleep 2000 sql connect sql create database ibadb diff --git a/tests/script/general/import/commit.sim b/tests/script/tsim/import/commit.sim similarity index 64% rename from tests/script/general/import/commit.sim rename to tests/script/tsim/import/commit.sim index aefc724fdb..e7f0440f5e 100644 --- a/tests/script/general/import/commit.sim +++ b/tests/script/tsim/import/commit.sim @@ -1,32 +1,6 @@ system sh/stop_dnodes.sh system sh/deploy.sh -n dnode1 -i 1 -system sh/deploy.sh -n dnode2 -i 2 -system sh/deploy.sh -n dnode3 -i 3 -system sh/deploy.sh -n dnode4 -i 4 - -system sh/cfg.sh -n dnode1 -c numOfMnodes -v 1 -system sh/cfg.sh -n dnode2 -c numOfMnodes -v 1 -system sh/cfg.sh -n dnode3 -c numOfMnodes -v 1 -system sh/cfg.sh -n dnode4 -c numOfMnodes -v 1 - -system sh/cfg.sh -n dnode1 -c mnodeEqualVnodeNum -v 10 -system sh/cfg.sh -n dnode2 -c mnodeEqualVnodeNum -v 10 -system sh/cfg.sh -n dnode3 -c mnodeEqualVnodeNum -v 10 -system sh/cfg.sh -n dnode4 -c mnodeEqualVnodeNum -v 10 - -system sh/cfg.sh -n dnode1 -c maxtablesPerVnode -v 2000 -system sh/cfg.sh -n dnode2 -c maxtablesPerVnode -v 2000 -system sh/cfg.sh -n dnode3 -c maxtablesPerVnode -v 2000 -system sh/cfg.sh -n dnode4 -c maxtablesPerVnode -v 2000 - -system sh/cfg.sh -n dnode1 -c walLevel -v 1 -system sh/cfg.sh -n dnode2 -c walLevel -v 1 -system sh/cfg.sh -n dnode3 -c walLevel -v 1 -system sh/cfg.sh -n dnode4 -c walLevel -v 1 - -print ========= start dnode1 system sh/exec.sh -n dnode1 -s start -sleep 2000 sql connect print ========= step1 @@ -72,9 +46,7 @@ endi print ========= step3 system sh/exec.sh -n dnode1 -s stop -x SIGINT -sleep 3000 system sh/exec.sh -n dnode1 -s start -sleep 3000 print ========= step4 sql select * from ic2db.tb; diff --git a/tests/script/general/import/large.sim b/tests/script/tsim/import/large.sim similarity index 61% rename from tests/script/general/import/large.sim rename to tests/script/tsim/import/large.sim index 23fbcc75ea..f694502e2a 100644 --- a/tests/script/general/import/large.sim +++ b/tests/script/tsim/import/large.sim @@ -1,32 +1,6 @@ system sh/stop_dnodes.sh system sh/deploy.sh -n dnode1 -i 1 -system sh/deploy.sh -n dnode2 -i 2 -system sh/deploy.sh -n dnode3 -i 3 -system sh/deploy.sh -n dnode4 -i 4 - -system sh/cfg.sh -n dnode1 -c numOfMnodes -v 1 -system sh/cfg.sh -n dnode2 -c numOfMnodes -v 1 -system sh/cfg.sh -n dnode3 -c numOfMnodes -v 1 -system sh/cfg.sh -n dnode4 -c numOfMnodes -v 1 - -system sh/cfg.sh -n dnode1 -c mnodeEqualVnodeNum -v 10 -system sh/cfg.sh -n dnode2 -c mnodeEqualVnodeNum -v 10 -system sh/cfg.sh -n dnode3 -c mnodeEqualVnodeNum -v 10 -system sh/cfg.sh -n dnode4 -c mnodeEqualVnodeNum -v 10 - -system sh/cfg.sh -n dnode1 -c maxtablesPerVnode -v 2000 -system sh/cfg.sh -n dnode2 -c maxtablesPerVnode -v 2000 -system sh/cfg.sh -n dnode3 -c maxtablesPerVnode -v 2000 -system sh/cfg.sh -n dnode4 -c maxtablesPerVnode -v 2000 - -system sh/cfg.sh -n dnode1 -c walLevel -v 1 -system sh/cfg.sh -n dnode2 -c walLevel -v 1 -system sh/cfg.sh -n dnode3 -c walLevel -v 1 -system sh/cfg.sh -n dnode4 -c walLevel -v 1 - -print ========= start dnode1 system sh/exec.sh -n dnode1 -s start -sleep 2000 sql connect sql create database db diff --git a/tests/script/general/import/replica1.sim b/tests/script/tsim/import/replica1.sim similarity index 83% rename from tests/script/general/import/replica1.sim rename to tests/script/tsim/import/replica1.sim index 1e8eabb798..3a4b4a2876 100644 --- a/tests/script/general/import/replica1.sim +++ b/tests/script/tsim/import/replica1.sim @@ -1,33 +1,6 @@ system sh/stop_dnodes.sh - system sh/deploy.sh -n dnode1 -i 1 -system sh/deploy.sh -n dnode2 -i 2 -system sh/deploy.sh -n dnode3 -i 3 -system sh/deploy.sh -n dnode4 -i 4 - -system sh/cfg.sh -n dnode1 -c numOfMnodes -v 1 -system sh/cfg.sh -n dnode2 -c numOfMnodes -v 1 -system sh/cfg.sh -n dnode3 -c numOfMnodes -v 1 -system sh/cfg.sh -n dnode4 -c numOfMnodes -v 1 - -system sh/cfg.sh -n dnode1 -c mnodeEqualVnodeNum -v 10 -system sh/cfg.sh -n dnode2 -c mnodeEqualVnodeNum -v 10 -system sh/cfg.sh -n dnode3 -c mnodeEqualVnodeNum -v 10 -system sh/cfg.sh -n dnode4 -c mnodeEqualVnodeNum -v 10 - -system sh/cfg.sh -n dnode1 -c maxtablesPerVnode -v 2000 -system sh/cfg.sh -n dnode2 -c maxtablesPerVnode -v 2000 -system sh/cfg.sh -n dnode3 -c maxtablesPerVnode -v 2000 -system sh/cfg.sh -n dnode4 -c maxtablesPerVnode -v 2000 - -system sh/cfg.sh -n dnode1 -c walLevel -v 2 -system sh/cfg.sh -n dnode2 -c walLevel -v 2 -system sh/cfg.sh -n dnode3 -c walLevel -v 2 -system sh/cfg.sh -n dnode4 -c walLevel -v 2 - -print ========= start dnode1 system sh/exec.sh -n dnode1 -s start -sleep 2000 sql connect sql create database ir1db duration 7 @@ -93,9 +66,7 @@ endi print ================== dnode restart system sh/exec.sh -n dnode1 -s stop -x SIGINT -sleep 3000 system sh/exec.sh -n dnode1 -s start -sleep 3000 sql use ir1db sql select * from tb; @@ -162,9 +133,7 @@ endi print ================= step10 system sh/exec.sh -n dnode1 -s stop -x SIGINT -sleep 3000 system sh/exec.sh -n dnode1 -s start -sleep 3000 sql use ir1db sql select * from tb; -- GitLab From 8a6e4b877a7e453d90e6ea86cb5d359f99300b3f Mon Sep 17 00:00:00 2001 From: Liu Jicong Date: Wed, 13 Jul 2022 16:37:33 +0800 Subject: [PATCH 059/153] refactor(stream): simple batch --- include/libs/executor/executor.h | 5 +- include/libs/stream/tstream.h | 6 ++- source/libs/executor/CMakeLists.txt | 2 +- source/libs/executor/inc/executorimpl.h | 3 ++ source/libs/executor/src/executor.c | 2 - source/libs/executor/src/executorMain.c | 14 ++++++ source/libs/executor/src/scanoperator.c | 23 --------- source/libs/executor/src/timewindowoperator.c | 4 +- source/libs/qworker/CMakeLists.txt | 2 +- source/libs/stream/inc/streamInc.h | 3 ++ source/libs/stream/src/streamData.c | 26 ++++++++++ source/libs/stream/src/streamDispatch.c | 5 +- source/libs/stream/src/streamExec.c | 47 +++++++++++++------ 13 files changed, 94 insertions(+), 48 deletions(-) diff --git a/include/libs/executor/executor.h b/include/libs/executor/executor.h index 630e983f81..dd64c5bf71 100644 --- a/include/libs/executor/executor.h +++ b/include/libs/executor/executor.h @@ -186,9 +186,12 @@ int32_t qStreamExtractOffset(qTaskInfo_t tinfo, STqOffsetVal* pOffset); void* qStreamExtractMetaMsg(qTaskInfo_t tinfo); -void* qExtractReaderFromStreamScanner(void* scanner); +void* qExtractReaderFromStreamScanner(void* scanner); + int32_t qExtractStreamScanner(qTaskInfo_t tinfo, void** scanner); +int32_t qStreamInput(qTaskInfo_t tinfo, void* pItem); + #ifdef __cplusplus } #endif diff --git a/include/libs/stream/tstream.h b/include/libs/stream/tstream.h index ac9784b91b..cae14a6d59 100644 --- a/include/libs/stream/tstream.h +++ b/include/libs/stream/tstream.h @@ -13,6 +13,7 @@ * along with this program. If not, see . */ +#include "executor.h" #include "os.h" #include "query.h" #include "tdatablock.h" @@ -120,7 +121,6 @@ static FORCE_INLINE void* streamQueueCurItem(SStreamQueue* queue) { return queue static FORCE_INLINE void* streamQueueNextItem(SStreamQueue* queue) { int8_t dequeueFlag = atomic_exchange_8(&queue->status, STREAM_QUEUE__PROCESSING); if (dequeueFlag == STREAM_QUEUE__FAILED) { - ASSERT(0); ASSERT(queue->qItem != NULL); return streamQueueCurItem(queue); } else { @@ -309,12 +309,16 @@ static FORCE_INLINE int32_t streamTaskInput(SStreamTask* pTask, SStreamQueueItem } qInfo("task %d %p submit enqueue %p %p %p", pTask->taskId, pTask, pItem, pSubmitClone, pSubmitClone->data); taosWriteQitem(pTask->inputQueue->queue, pSubmitClone); + // qStreamInput(pTask->exec.executor, pSubmitClone); } else if (pItem->type == STREAM_INPUT__DATA_BLOCK || pItem->type == STREAM_INPUT__DATA_RETRIEVE) { taosWriteQitem(pTask->inputQueue->queue, pItem); + // qStreamInput(pTask->exec.executor, pItem); } else if (pItem->type == STREAM_INPUT__CHECKPOINT) { taosWriteQitem(pTask->inputQueue->queue, pItem); + // qStreamInput(pTask->exec.executor, pItem); } else if (pItem->type == STREAM_INPUT__TRIGGER) { taosWriteQitem(pTask->inputQueue->queue, pItem); + // qStreamInput(pTask->exec.executor, pItem); } if (pItem->type != STREAM_INPUT__TRIGGER && pItem->type != STREAM_INPUT__CHECKPOINT && pTask->triggerParam != 0) { diff --git a/source/libs/executor/CMakeLists.txt b/source/libs/executor/CMakeLists.txt index ed15aeb038..89d08b3078 100644 --- a/source/libs/executor/CMakeLists.txt +++ b/source/libs/executor/CMakeLists.txt @@ -8,7 +8,7 @@ add_library(executor STATIC ${EXECUTOR_SRC}) # ) target_link_libraries(executor - PRIVATE os util common function parser planner qcom vnode scalar nodes index + PRIVATE os util common function parser planner qcom vnode scalar nodes index stream ) target_include_directories( diff --git a/source/libs/executor/inc/executorimpl.h b/source/libs/executor/inc/executorimpl.h index aab2f51421..045b4379ca 100644 --- a/source/libs/executor/inc/executorimpl.h +++ b/source/libs/executor/inc/executorimpl.h @@ -39,6 +39,7 @@ extern "C" { #include "tmsg.h" #include "tpagedbuf.h" #include "tstreamUpdate.h" +#include "tstream.h" #include "vnode.h" #include "executorInt.h" @@ -139,12 +140,14 @@ typedef struct STaskIdInfo { } STaskIdInfo; typedef struct { + //TODO remove prepareStatus STqOffsetVal prepareStatus; // for tmq STqOffsetVal lastStatus; // for tmq void* metaBlk; // for tmq fetching meta SSDataBlock* pullOverBlk; // for streaming SWalFilterCond cond; int64_t lastScanUid; + SStreamQueue* inputQueue; } SStreamTaskInfo; typedef struct SExecTaskInfo { diff --git a/source/libs/executor/src/executor.c b/source/libs/executor/src/executor.c index 6e4f02527f..f2008ed97a 100644 --- a/source/libs/executor/src/executor.c +++ b/source/libs/executor/src/executor.c @@ -60,8 +60,6 @@ static int32_t doSetStreamBlock(SOperatorInfo* pOperator, void* input, size_t nu taosArrayAddAll(p->pDataBlock, pDataBlock->pDataBlock); taosArrayPush(pInfo->pBlockLists, &p); } - /*} else if (type == STREAM_INPUT__TABLE_SCAN) {*/ - /*ASSERT(pInfo->blockType == STREAM_INPUT__TABLE_SCAN);*/ } else { ASSERT(0); } diff --git a/source/libs/executor/src/executorMain.c b/source/libs/executor/src/executorMain.c index 5d9fea523c..6381d20255 100644 --- a/source/libs/executor/src/executorMain.c +++ b/source/libs/executor/src/executorMain.c @@ -44,6 +44,13 @@ int32_t qCreateExecTask(SReadHandle* readHandle, int32_t vgId, uint64_t taskId, goto _error; } + if (model == OPTR_EXEC_MODEL_STREAM) { + (*pTask)->streamInfo.inputQueue = streamQueueOpen(); + if ((*pTask)->streamInfo.inputQueue == NULL) { + goto _error; + } + } + SDataSinkMgtCfg cfg = {.maxDataBlockNum = 1000, .maxDataBlockNumPerQuery = 100}; code = dsDataSinkMgtInit(&cfg); if (code != TSDB_CODE_SUCCESS) { @@ -252,6 +259,13 @@ int32_t qExtractStreamScanner(qTaskInfo_t tinfo, void** scanner) { } } +int32_t qStreamInput(qTaskInfo_t tinfo, void* pItem) { + SExecTaskInfo* pTaskInfo = (SExecTaskInfo*)tinfo; + ASSERT(pTaskInfo->execModel == OPTR_EXEC_MODEL_STREAM); + taosWriteQitem(pTaskInfo->streamInfo.inputQueue->queue, pItem); + return 0; +} + void* qExtractReaderFromStreamScanner(void* scanner) { SStreamScanInfo* pInfo = scanner; return (void*)pInfo->tqReader; diff --git a/source/libs/executor/src/scanoperator.c b/source/libs/executor/src/scanoperator.c index 64c740decf..b14648991e 100644 --- a/source/libs/executor/src/scanoperator.c +++ b/source/libs/executor/src/scanoperator.c @@ -1202,15 +1202,6 @@ static int32_t setBlockIntoRes(SStreamScanInfo* pInfo, const SSDataBlock* pBlock taosArrayDestroy(pBlock->pDataBlock); ASSERT(pInfo->pRes->pDataBlock != NULL); -#if 0 - if (pInfo->pRes->pDataBlock == NULL) { - // TODO add log - updateInfoDestoryColseWinSBF(pInfo->pUpdateInfo); - pOperator->status = OP_EXEC_DONE; - pTaskInfo->code = terrno; - return -1; - } -#endif // currently only the tbname pseudo column if (pInfo->numOfPseudoExpr > 0) { @@ -1231,11 +1222,6 @@ static SSDataBlock* doStreamScan(SOperatorInfo* pOperator) { SExecTaskInfo* pTaskInfo = pOperator->pTaskInfo; SStreamScanInfo* pInfo = pOperator->info; - /*pTaskInfo->code = pOperator->fpSet._openFn(pOperator);*/ - /*if (pTaskInfo->code != TSDB_CODE_SUCCESS || pOperator->status == OP_EXEC_DONE) {*/ - /*return NULL;*/ - /*}*/ - qDebug("stream scan called"); if (pTaskInfo->streamInfo.prepareStatus.type == TMQ_OFFSET__LOG) { while (1) { @@ -1425,15 +1411,6 @@ static SSDataBlock* doStreamScan(SOperatorInfo* pOperator) { qDebug("scan rows: %d", pBlockInfo->rows); return (pBlockInfo->rows == 0) ? NULL : pInfo->pRes; -#if 0 - } else if (pInfo->blockType == STREAM_INPUT__TABLE_SCAN) { - ASSERT(0); - // check reader last status - // if not match, reset status - SSDataBlock* pResult = doTableScan(pInfo->pTableScanOp); - return pResult && pResult->info.rows > 0 ? pResult : NULL; -#endif - } else { ASSERT(0); return NULL; diff --git a/source/libs/executor/src/timewindowoperator.c b/source/libs/executor/src/timewindowoperator.c index 773484a9b3..da78480d3b 100644 --- a/source/libs/executor/src/timewindowoperator.c +++ b/source/libs/executor/src/timewindowoperator.c @@ -653,11 +653,11 @@ static void doInterpUnclosedTimeWindow(SOperatorInfo* pOperatorInfo, int32_t num void printDataBlock(SSDataBlock* pBlock, const char* flag) { if (pBlock == NULL) { - qDebug("======printDataBlock Block is Null"); + qInfo("======printDataBlock Block is Null"); return; } char* pBuf = NULL; - qDebug("%s", dumpBlockData(pBlock, flag, &pBuf)); + qInfo("%s", dumpBlockData(pBlock, flag, &pBuf)); taosMemoryFree(pBuf); } diff --git a/source/libs/qworker/CMakeLists.txt b/source/libs/qworker/CMakeLists.txt index 306753808b..92ccde3163 100644 --- a/source/libs/qworker/CMakeLists.txt +++ b/source/libs/qworker/CMakeLists.txt @@ -13,4 +13,4 @@ target_link_libraries(qworker if(${BUILD_TEST}) ADD_SUBDIRECTORY(test) -endif(${BUILD_TEST}) \ No newline at end of file +endif(${BUILD_TEST}) diff --git a/source/libs/stream/inc/streamInc.h b/source/libs/stream/inc/streamInc.h index 1629c863d5..f9f4e62774 100644 --- a/source/libs/stream/inc/streamInc.h +++ b/source/libs/stream/inc/streamInc.h @@ -42,6 +42,9 @@ int32_t streamBroadcastToChildren(SStreamTask* pTask, const SSDataBlock* pBlock) int32_t tEncodeStreamRetrieveReq(SEncoder* pEncoder, const SStreamRetrieveReq* pReq); +int32_t streamAppendQueueItem(SStreamQueueItem* dst, SStreamQueueItem* elem); +void streamFreeQitem(SStreamQueueItem* data); + #ifdef __cplusplus } #endif diff --git a/source/libs/stream/src/streamData.c b/source/libs/stream/src/streamData.c index 529615d4fd..2b3307b7f5 100644 --- a/source/libs/stream/src/streamData.c +++ b/source/libs/stream/src/streamData.c @@ -97,3 +97,29 @@ void streamDataSubmitRefDec(SStreamDataSubmit* pDataSubmit) { taosMemoryFree(pDataSubmit->dataRef); } } + +int32_t streamAppendQueueItem(SStreamQueueItem* dst, SStreamQueueItem* elem) { + ASSERT(elem); + if (dst->type == elem->type && dst->type == STREAM_INPUT__DATA_BLOCK) { + SStreamDataBlock* pBlock = (SStreamDataBlock*)dst; + SStreamDataBlock* pBlockSrc = (SStreamDataBlock*)elem; + taosArrayAddAll(pBlock->blocks, pBlockSrc->blocks); + return 0; + } else { + return -1; + } +} + +void streamFreeQitem(SStreamQueueItem* data) { + int8_t type = data->type; + if (type == STREAM_INPUT__TRIGGER) { + blockDataDestroy(((SStreamTrigger*)data)->pBlock); + taosFreeQitem(data); + } else if (type == STREAM_INPUT__DATA_BLOCK || type == STREAM_INPUT__DATA_RETRIEVE) { + taosArrayDestroyEx(((SStreamDataBlock*)data)->blocks, (FDelete)tDeleteSSDataBlock); + taosFreeQitem(data); + } else if (type == STREAM_INPUT__DATA_SUBMIT) { + streamDataSubmitRefDec((SStreamDataSubmit*)data); + taosFreeQitem(data); + } +} diff --git a/source/libs/stream/src/streamDispatch.c b/source/libs/stream/src/streamDispatch.c index 98b0874b00..05efce8bc2 100644 --- a/source/libs/stream/src/streamDispatch.c +++ b/source/libs/stream/src/streamDispatch.c @@ -251,8 +251,8 @@ int32_t streamBuildDispatchMsg(SStreamTask* pTask, const SStreamDataBlock* data, ASSERT(vgId > 0 || vgId == SNODE_HANDLE); req.taskId = downstreamTaskId; - qInfo("dispatch from task %d (child id %d) to down stream task %d in vnode %d", pTask->taskId, pTask->selfChildId, - downstreamTaskId, vgId); + qDebug("dispatch from task %d (child id %d) to down stream task %d in vnode %d", pTask->taskId, pTask->selfChildId, + downstreamTaskId, vgId); // serialize int32_t tlen; @@ -298,6 +298,7 @@ int32_t streamDispatch(SStreamTask* pTask, SMsgCb* pMsgCb) { SStreamDataBlock* pBlock = streamQueueNextItem(pTask->outputQueue); if (pBlock == NULL) { + qDebug("stream stop dispatching since no output: task %d", pTask->taskId); atomic_store_8(&pTask->outputStatus, TASK_OUTPUT_STATUS__NORMAL); return 0; } diff --git a/source/libs/stream/src/streamExec.c b/source/libs/stream/src/streamExec.c index 36885e73c0..9644d9eac6 100644 --- a/source/libs/stream/src/streamExec.c +++ b/source/libs/stream/src/streamExec.c @@ -75,10 +75,35 @@ static int32_t streamTaskExecImpl(SStreamTask* pTask, void* data, SArray* pRes) static SArray* streamExecForQall(SStreamTask* pTask, SArray* pRes) { while (1) { - void* data = streamQueueNextItem(pTask->inputQueue); + int32_t cnt = 0; + void* data = NULL; + while (1) { + SStreamQueueItem* qItem = streamQueueNextItem(pTask->inputQueue); + if (qItem == NULL) { + qInfo("stream exec over, queue empty"); + break; + } + if (data == NULL) { + data = qItem; + streamQueueProcessSuccess(pTask->inputQueue); + continue; + } else { + if (streamAppendQueueItem(data, qItem) < 0) { + streamQueueProcessFail(pTask->inputQueue); + break; + } else { + cnt++; + streamQueueProcessSuccess(pTask->inputQueue); + taosArrayDestroy(((SStreamDataBlock*)qItem)->blocks); + taosFreeQitem(qItem); + } + } + } if (data == NULL) break; + qInfo("stream task %d exec begin, batch msg: %d", pTask->taskId, cnt); streamTaskExecImpl(pTask, data, pRes); + qInfo("stream task %d exec end", pTask->taskId); if (pTask->taskStatus == TASK_STATUS__DROPPING) { taosArrayDestroyEx(pRes, (FDelete)tDeleteSSDataBlock); @@ -95,27 +120,16 @@ static SArray* streamExecForQall(SStreamTask* pTask, SArray* pRes) { qRes->type = STREAM_INPUT__DATA_BLOCK; qRes->blocks = pRes; if (streamTaskOutput(pTask, qRes) < 0) { - streamQueueProcessFail(pTask->inputQueue); + /*streamQueueProcessFail(pTask->inputQueue);*/ taosArrayDestroyEx(pRes, (FDelete)tDeleteSSDataBlock); taosFreeQitem(qRes); return NULL; } - streamQueueProcessSuccess(pTask->inputQueue); + /*streamQueueProcessSuccess(pTask->inputQueue);*/ pRes = taosArrayInit(0, sizeof(SSDataBlock)); } - int8_t type = ((SStreamQueueItem*)data)->type; - if (type == STREAM_INPUT__TRIGGER) { - blockDataDestroy(((SStreamTrigger*)data)->pBlock); - taosFreeQitem(data); - } else if (type == STREAM_INPUT__DATA_BLOCK || type == STREAM_INPUT__DATA_RETRIEVE) { - taosArrayDestroyEx(((SStreamDataBlock*)data)->blocks, (FDelete)tDeleteSSDataBlock); - taosFreeQitem(data); - } else if (type == STREAM_INPUT__DATA_SUBMIT) { - ASSERT(pTask->isDataScan); - streamDataSubmitRefDec((SStreamDataSubmit*)data); - taosFreeQitem(data); - } + streamFreeQitem(data); } return pRes; } @@ -129,6 +143,7 @@ int32_t streamExec(SStreamTask* pTask, SMsgCb* pMsgCb) { atomic_val_compare_exchange_8(&pTask->execStatus, TASK_EXEC_STATUS__IDLE, TASK_EXEC_STATUS__EXECUTING); if (execStatus == TASK_EXEC_STATUS__IDLE) { // first run + qDebug("stream exec, enter exec status"); pRes = streamExecForQall(pTask, pRes); if (pRes == NULL) goto FAIL; @@ -136,11 +151,13 @@ int32_t streamExec(SStreamTask* pTask, SMsgCb* pMsgCb) { atomic_store_8(&pTask->execStatus, TASK_EXEC_STATUS__CLOSING); // second run, make sure inputQ and qall are cleared + qDebug("stream exec, enter closing status"); pRes = streamExecForQall(pTask, pRes); if (pRes == NULL) goto FAIL; taosArrayDestroyEx(pRes, (FDelete)tDeleteSSDataBlock); atomic_store_8(&pTask->execStatus, TASK_EXEC_STATUS__IDLE); + qDebug("stream exec, return result"); return 0; } else if (execStatus == TASK_EXEC_STATUS__CLOSING) { continue; -- GitLab From 8c83f07fe436369deb193347b6ea5a83407f641f Mon Sep 17 00:00:00 2001 From: dapan1121 Date: Wed, 13 Jul 2022 16:43:50 +0800 Subject: [PATCH 060/153] fix: fix natural timestamp issue --- include/common/ttime.h | 2 + include/libs/scalar/scalar.h | 1 + source/common/src/ttime.c | 26 ++++++ source/libs/parser/src/parCalcConst.c | 11 ++- source/libs/parser/src/parTranslater.c | 3 +- source/libs/scalar/inc/sclInt.h | 1 + source/libs/scalar/src/scalar.c | 119 ++++++++++++++----------- source/libs/scalar/src/sclvector.c | 41 +++++---- tests/script/jenkins/basic.txt | 1 + tests/script/tsim/scalar/scalar.sim | 67 ++++++++++++++ 10 files changed, 198 insertions(+), 74 deletions(-) create mode 100644 tests/script/tsim/scalar/scalar.sim diff --git a/include/common/ttime.h b/include/common/ttime.h index cd704bb1f7..de55b016cd 100644 --- a/include/common/ttime.h +++ b/include/common/ttime.h @@ -72,6 +72,8 @@ static FORCE_INLINE int64_t taosGetTimestampToday(int32_t precision) { } int64_t taosTimeAdd(int64_t t, int64_t duration, char unit, int32_t precision); +int64_t taosTimeSub(int64_t t, int64_t duration, char unit, int32_t precision); + int64_t taosTimeTruncate(int64_t t, const SInterval* pInterval, int32_t precision); int32_t taosTimeCountInterval(int64_t skey, int64_t ekey, int64_t interval, char unit, int32_t precision); diff --git a/include/libs/scalar/scalar.h b/include/libs/scalar/scalar.h index c81c474366..517c5ff0e6 100644 --- a/include/libs/scalar/scalar.h +++ b/include/libs/scalar/scalar.h @@ -32,6 +32,7 @@ pNode will be freed in API; *pRes need to freed in caller */ int32_t scalarCalculateConstants(SNode *pNode, SNode **pRes); +int32_t scalarCalculateConstantsFromDual(SNode *pNode, SNode **pRes); /* pDst need to freed in caller diff --git a/source/common/src/ttime.c b/source/common/src/ttime.c index befb0abac8..d728bbe49e 100644 --- a/source/common/src/ttime.c +++ b/source/common/src/ttime.c @@ -710,6 +710,32 @@ int64_t taosTimeAdd(int64_t t, int64_t duration, char unit, int32_t precision) { return (int64_t)(taosMktime(&tm) * TSDB_TICK_PER_SECOND(precision)); } +int64_t taosTimeSub(int64_t t, int64_t duration, char unit, int32_t precision) { + if (duration == 0) { + return t; + } + + if (unit != 'n' && unit != 'y') { + return t - duration; + } + + // The following code handles the y/n time duration + int64_t numOfMonth = duration; + if (unit == 'y') { + numOfMonth *= 12; + } + + struct tm tm; + time_t tt = (time_t)(t / TSDB_TICK_PER_SECOND(precision)); + taosLocalTime(&tt, &tm); + int32_t mon = tm.tm_year * 12 + tm.tm_mon - (int32_t)numOfMonth; + tm.tm_year = mon / 12; + tm.tm_mon = mon % 12; + + return (int64_t)(taosMktime(&tm) * TSDB_TICK_PER_SECOND(precision)); +} + + int32_t taosTimeCountInterval(int64_t skey, int64_t ekey, int64_t interval, char unit, int32_t precision) { if (ekey < skey) { int64_t tmp = ekey; diff --git a/source/libs/parser/src/parCalcConst.c b/source/libs/parser/src/parCalcConst.c index 4dff42592a..cd10cd50f6 100644 --- a/source/libs/parser/src/parCalcConst.c +++ b/source/libs/parser/src/parCalcConst.c @@ -166,7 +166,7 @@ static int32_t calcConstStmtCondition(SCalcConstContext* pCxt, SNode** pCond, bo return code; } -static int32_t calcConstProject(SNode* pProject, SNode** pNew) { +static int32_t calcConstProject(SNode* pProject, bool dual, SNode** pNew) { SArray* pAssociation = NULL; if (NULL != ((SExprNode*)pProject)->pAssociation) { pAssociation = taosArrayDup(((SExprNode*)pProject)->pAssociation); @@ -177,7 +177,12 @@ static int32_t calcConstProject(SNode* pProject, SNode** pNew) { char aliasName[TSDB_COL_NAME_LEN] = {0}; strcpy(aliasName, ((SExprNode*)pProject)->aliasName); - int32_t code = scalarCalculateConstants(pProject, pNew); + int32_t code = TSDB_CODE_SUCCESS; + if (dual) { + code = scalarCalculateConstantsFromDual(pProject, pNew); + } else { + code = scalarCalculateConstants(pProject, pNew); + } if (TSDB_CODE_SUCCESS == code && QUERY_NODE_VALUE == nodeType(*pNew) && NULL != pAssociation) { strcpy(((SExprNode*)*pNew)->aliasName, aliasName); int32_t size = taosArrayGetSize(pAssociation); @@ -223,7 +228,7 @@ static int32_t calcConstProjections(SCalcConstContext* pCxt, SSelectStmt* pSelec continue; } SNode* pNew = NULL; - int32_t code = calcConstProject(pProj, &pNew); + int32_t code = calcConstProject(pProj, (NULL == pSelect->pFromTable), &pNew); if (TSDB_CODE_SUCCESS == code) { REPLACE_NODE(pNew); } else { diff --git a/source/libs/parser/src/parTranslater.c b/source/libs/parser/src/parTranslater.c index da393bb883..f90c7ee23c 100644 --- a/source/libs/parser/src/parTranslater.c +++ b/source/libs/parser/src/parTranslater.c @@ -916,8 +916,6 @@ static EDealRes translateValueImpl(STranslateContext* pCxt, SValueNode* pVal, SD } if (TSDB_DATA_TYPE_NULL == pVal->node.resType.type) { - // TODO - // pVal->node.resType = targetDt; pVal->translate = true; pVal->isNull = true; return DEAL_RES_CONTINUE; @@ -932,6 +930,7 @@ static EDealRes translateValueImpl(STranslateContext* pCxt, SValueNode* pVal, SD res = translateNormalValue(pCxt, pVal, targetDt, strict); } pVal->node.resType = targetDt; + pVal->node.resType.scale = pVal->unit; pVal->translate = true; return res; } diff --git a/source/libs/scalar/inc/sclInt.h b/source/libs/scalar/inc/sclInt.h index 4422da1b81..d423b92da7 100644 --- a/source/libs/scalar/inc/sclInt.h +++ b/source/libs/scalar/inc/sclInt.h @@ -30,6 +30,7 @@ typedef struct SOperatorValueType { typedef struct SScalarCtx { int32_t code; + bool dual; SArray *pBlockList; /* element is SSDataBlock* */ SHashObj *pRes; /* element is SScalarParam */ void *param; // additional parameter (meta actually) for acquire value such as tbname/tags values diff --git a/source/libs/scalar/src/scalar.c b/source/libs/scalar/src/scalar.c index e610fcb62e..a2e9f7a1cd 100644 --- a/source/libs/scalar/src/scalar.c +++ b/source/libs/scalar/src/scalar.c @@ -700,7 +700,7 @@ EDealRes sclRewriteNonConstOperator(SNode** pNode, SScalarCtx *ctx) { EDealRes sclRewriteFunction(SNode** pNode, SScalarCtx *ctx) { SFunctionNode *node = (SFunctionNode *)*pNode; SNode* tnode = NULL; - if (!fmIsScalarFunc(node->funcId)) { + if ((!fmIsScalarFunc(node->funcId)) && (!ctx->dual)) { return DEAL_RES_CONTINUE; } @@ -1010,13 +1010,14 @@ int32_t sclExtendResRows(SScalarParam *pDst, SScalarParam *pSrc, SArray *pBlockL return TSDB_CODE_SUCCESS; } -int32_t scalarCalculateConstants(SNode *pNode, SNode **pRes) { +int32_t sclCalcConstants(SNode *pNode, bool dual, SNode **pRes) { if (NULL == pNode) { SCL_ERR_RET(TSDB_CODE_QRY_INVALID_INPUT); } int32_t code = 0; SScalarCtx ctx = {0}; + ctx.dual = dual; ctx.pRes = taosHashInit(SCL_DEFAULT_OP_NUM, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), false, HASH_NO_LOCK); if (NULL == ctx.pRes) { sclError("taosHashInit failed, num:%d", SCL_DEFAULT_OP_NUM); @@ -1028,54 +1029,12 @@ int32_t scalarCalculateConstants(SNode *pNode, SNode **pRes) { *pRes = pNode; _return: - sclFreeRes(ctx.pRes); - return code; -} - -int32_t scalarCalculate(SNode *pNode, SArray *pBlockList, SScalarParam *pDst) { - if (NULL == pNode || NULL == pBlockList) { - SCL_ERR_RET(TSDB_CODE_QRY_INVALID_INPUT); - } - - int32_t code = 0; - SScalarCtx ctx = {.code = 0, .pBlockList = pBlockList, .param = pDst ? pDst->param : NULL}; - - // TODO: OPT performance - ctx.pRes = taosHashInit(SCL_DEFAULT_OP_NUM, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), false, HASH_NO_LOCK); - if (NULL == ctx.pRes) { - sclError("taosHashInit failed, num:%d", SCL_DEFAULT_OP_NUM); - SCL_ERR_RET(TSDB_CODE_QRY_OUT_OF_MEMORY); - } - - nodesWalkExprPostOrder(pNode, sclCalcWalker, (void *)&ctx); - SCL_ERR_JRET(ctx.code); - - if (pDst) { - SScalarParam *res = (SScalarParam *)taosHashGet(ctx.pRes, (void *)&pNode, POINTER_BYTES); - if (NULL == res) { - sclError("no valid res in hash, node:%p, type:%d", pNode, nodeType(pNode)); - SCL_ERR_JRET(TSDB_CODE_QRY_APP_ERROR); - } - if (1 == res->numOfRows) { - SCL_ERR_JRET(sclExtendResRows(pDst, res, pBlockList)); - } else { - colInfoDataEnsureCapacity(pDst->columnData, res->numOfRows); - colDataAssign(pDst->columnData, res->columnData, res->numOfRows, NULL); - pDst->numOfRows = res->numOfRows; - } - - sclFreeParam(res); - taosHashRemove(ctx.pRes, (void *)&pNode, POINTER_BYTES); - } - -_return: - //nodesDestroyNode(pNode); sclFreeRes(ctx.pRes); return code; } -static int32_t getMinusOperatorResultType(SOperatorNode* pOp) { +static int32_t sclGetMinusOperatorResType(SOperatorNode* pOp) { if (!IS_MATHABLE_TYPE(((SExprNode*)(pOp->pLeft))->resType.type)) { return TSDB_CODE_TSC_INVALID_OPERATION; } @@ -1084,7 +1043,7 @@ static int32_t getMinusOperatorResultType(SOperatorNode* pOp) { return TSDB_CODE_SUCCESS; } -static int32_t getArithmeticOperatorResultType(SOperatorNode* pOp) { +static int32_t sclGetMathOperatorResType(SOperatorNode* pOp) { SDataType ldt = ((SExprNode*)(pOp->pLeft))->resType; SDataType rdt = ((SExprNode*)(pOp->pRight))->resType; if ((TSDB_DATA_TYPE_TIMESTAMP == ldt.type && TSDB_DATA_TYPE_TIMESTAMP == rdt.type) || @@ -1106,7 +1065,7 @@ static int32_t getArithmeticOperatorResultType(SOperatorNode* pOp) { return TSDB_CODE_SUCCESS; } -static int32_t getComparisonOperatorResultType(SOperatorNode* pOp) { +static int32_t sclGetCompOperatorResType(SOperatorNode* pOp) { SDataType ldt = ((SExprNode*)(pOp->pLeft))->resType; if (OP_TYPE_IN == pOp->opType || OP_TYPE_NOT_IN == pOp->opType) { ((SExprNode*)(pOp->pRight))->resType = ldt; @@ -1122,7 +1081,7 @@ static int32_t getComparisonOperatorResultType(SOperatorNode* pOp) { return TSDB_CODE_SUCCESS; } -static int32_t getJsonOperatorResultType(SOperatorNode* pOp) { +static int32_t sclGetJsonOperatorResType(SOperatorNode* pOp) { SDataType ldt = ((SExprNode*)(pOp->pLeft))->resType; SDataType rdt = ((SExprNode*)(pOp->pRight))->resType; if (TSDB_DATA_TYPE_JSON != ldt.type || !IS_STR_DATA_TYPE(rdt.type)) { @@ -1137,12 +1096,64 @@ static int32_t getJsonOperatorResultType(SOperatorNode* pOp) { return TSDB_CODE_SUCCESS; } -static int32_t getBitwiseOperatorResultType(SOperatorNode* pOp) { +static int32_t sclGetBitwiseOperatorResType(SOperatorNode* pOp) { pOp->node.resType.type = TSDB_DATA_TYPE_BIGINT; pOp->node.resType.bytes = tDataTypes[TSDB_DATA_TYPE_BIGINT].bytes; return TSDB_CODE_SUCCESS; } + +int32_t scalarCalculateConstants(SNode *pNode, SNode **pRes) { + return sclCalcConstants(pNode, false, pRes); +} + +int32_t scalarCalculateConstantsFromDual(SNode *pNode, SNode **pRes) { + return sclCalcConstants(pNode, true, pRes); +} + +int32_t scalarCalculate(SNode *pNode, SArray *pBlockList, SScalarParam *pDst) { + if (NULL == pNode || NULL == pBlockList) { + SCL_ERR_RET(TSDB_CODE_QRY_INVALID_INPUT); + } + + int32_t code = 0; + SScalarCtx ctx = {.code = 0, .pBlockList = pBlockList, .param = pDst ? pDst->param : NULL}; + + // TODO: OPT performance + ctx.pRes = taosHashInit(SCL_DEFAULT_OP_NUM, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), false, HASH_NO_LOCK); + if (NULL == ctx.pRes) { + sclError("taosHashInit failed, num:%d", SCL_DEFAULT_OP_NUM); + SCL_ERR_RET(TSDB_CODE_QRY_OUT_OF_MEMORY); + } + + nodesWalkExprPostOrder(pNode, sclCalcWalker, (void *)&ctx); + SCL_ERR_JRET(ctx.code); + + if (pDst) { + SScalarParam *res = (SScalarParam *)taosHashGet(ctx.pRes, (void *)&pNode, POINTER_BYTES); + if (NULL == res) { + sclError("no valid res in hash, node:%p, type:%d", pNode, nodeType(pNode)); + SCL_ERR_JRET(TSDB_CODE_QRY_APP_ERROR); + } + + if (1 == res->numOfRows) { + SCL_ERR_JRET(sclExtendResRows(pDst, res, pBlockList)); + } else { + colInfoDataEnsureCapacity(pDst->columnData, res->numOfRows); + colDataAssign(pDst->columnData, res->columnData, res->numOfRows, NULL); + pDst->numOfRows = res->numOfRows; + } + + sclFreeParam(res); + taosHashRemove(ctx.pRes, (void *)&pNode, POINTER_BYTES); + } + +_return: + //nodesDestroyNode(pNode); + sclFreeRes(ctx.pRes); + return code; +} + int32_t scalarGetOperatorResultType(SOperatorNode* pOp) { if (TSDB_DATA_TYPE_BLOB == ((SExprNode*)(pOp->pLeft))->resType.type || (NULL != pOp->pRight && TSDB_DATA_TYPE_BLOB == ((SExprNode*)(pOp->pRight))->resType.type)) { @@ -1155,15 +1166,15 @@ int32_t scalarGetOperatorResultType(SOperatorNode* pOp) { case OP_TYPE_MULTI: case OP_TYPE_DIV: case OP_TYPE_REM: - return getArithmeticOperatorResultType(pOp); + return sclGetMathOperatorResType(pOp); case OP_TYPE_MINUS: - return getMinusOperatorResultType(pOp); + return sclGetMinusOperatorResType(pOp); case OP_TYPE_ASSIGN: pOp->node.resType = ((SExprNode*)(pOp->pLeft))->resType; break; case OP_TYPE_BIT_AND: case OP_TYPE_BIT_OR: - return getBitwiseOperatorResultType(pOp); + return sclGetBitwiseOperatorResType(pOp); case OP_TYPE_GREATER_THAN: case OP_TYPE_GREATER_EQUAL: case OP_TYPE_LOWER_THAN: @@ -1184,10 +1195,10 @@ int32_t scalarGetOperatorResultType(SOperatorNode* pOp) { case OP_TYPE_NMATCH: case OP_TYPE_IN: case OP_TYPE_NOT_IN: - return getComparisonOperatorResultType(pOp); + return sclGetCompOperatorResType(pOp); case OP_TYPE_JSON_GET_VALUE: case OP_TYPE_JSON_CONTAINS: - return getJsonOperatorResultType(pOp); + return sclGetJsonOperatorResType(pOp); default: break; } diff --git a/source/libs/scalar/src/sclvector.c b/source/libs/scalar/src/sclvector.c index bf457d07eb..39b2f04f3e 100644 --- a/source/libs/scalar/src/sclvector.c +++ b/source/libs/scalar/src/sclvector.c @@ -1055,7 +1055,7 @@ static void vectorMathAddHelper(SColumnInfoData* pLeftCol, SColumnInfoData* pRig } } -static void vectorMathBigintAddHelper(SColumnInfoData* pLeftCol, SColumnInfoData* pRightCol, SColumnInfoData* pOutputCol, int32_t numOfRows, int32_t step, int32_t i) { +static void vectorMathTsAddHelper(SColumnInfoData* pLeftCol, SColumnInfoData* pRightCol, SColumnInfoData* pOutputCol, int32_t numOfRows, int32_t step, int32_t i) { _getBigintValue_fn_t getVectorBigintValueFnLeft = getVectorBigintValueFn(pLeftCol->info.type); _getBigintValue_fn_t getVectorBigintValueFnRight = getVectorBigintValueFn(pRightCol->info.type); @@ -1069,7 +1069,8 @@ static void vectorMathBigintAddHelper(SColumnInfoData* pLeftCol, SColumnInfoData colDataAppendNULL(pOutputCol, i); continue; // TODO set null or ignore } - *output = getVectorBigintValueFnLeft(pLeftCol->pData, i) + getVectorBigintValueFnRight(pRightCol->pData, 0); + *output = taosTimeAdd(getVectorBigintValueFnLeft(pLeftCol->pData, i), getVectorBigintValueFnRight(pRightCol->pData, 0), + pRightCol->info.scale, pRightCol->info.precision); } } } @@ -1116,7 +1117,17 @@ void vectorMathAdd(SScalarParam* pLeft, SScalarParam* pRight, SScalarParam *pOut _getBigintValue_fn_t getVectorBigintValueFnLeft = getVectorBigintValueFn(pLeftCol->info.type); _getBigintValue_fn_t getVectorBigintValueFnRight = getVectorBigintValueFn(pRightCol->info.type); - if (pLeft->numOfRows == pRight->numOfRows) { + if (pLeft->numOfRows == 1 && pRight->numOfRows == 1) { + if (GET_PARAM_TYPE(pLeft) == TSDB_DATA_TYPE_TIMESTAMP) { + vectorMathTsAddHelper(pLeftCol, pRightCol, pOutputCol, pRight->numOfRows, step, i); + } else { + vectorMathTsAddHelper(pRightCol, pLeftCol, pOutputCol, pRight->numOfRows, step, i); + } + } else if (pLeft->numOfRows == 1) { + vectorMathTsAddHelper(pRightCol, pLeftCol, pOutputCol, pRight->numOfRows, step, i); + } else if (pRight->numOfRows == 1) { + vectorMathTsAddHelper(pLeftCol, pRightCol, pOutputCol, pLeft->numOfRows, step, i); + } else if (pLeft->numOfRows == pRight->numOfRows) { for (; i < pRight->numOfRows && i >= 0; i += step, output += 1) { if (IS_NULL) { colDataAppendNULL(pOutputCol, i); @@ -1124,11 +1135,7 @@ void vectorMathAdd(SScalarParam* pLeft, SScalarParam* pRight, SScalarParam *pOut } *output = getVectorBigintValueFnLeft(pLeftCol->pData, i) + getVectorBigintValueFnRight(pRightCol->pData, i); } - } else if (pLeft->numOfRows == 1) { - vectorMathBigintAddHelper(pRightCol, pLeftCol, pOutputCol, pRight->numOfRows, step, i); - } else if (pRight->numOfRows == 1) { - vectorMathBigintAddHelper(pLeftCol, pRightCol, pOutputCol, pLeft->numOfRows, step, i); - } + } } else { double *output = (double *)pOutputCol->pData; _getDoubleValue_fn_t getVectorDoubleValueFnLeft = getVectorDoubleValueFn(pLeftCol->info.type); @@ -1174,7 +1181,7 @@ static void vectorMathSubHelper(SColumnInfoData* pLeftCol, SColumnInfoData* pRig } } -static void vectorMathBigintSubHelper(SColumnInfoData* pLeftCol, SColumnInfoData* pRightCol, SColumnInfoData* pOutputCol, int32_t numOfRows, int32_t step, int32_t factor, int32_t i) { +static void vectorMathTsSubHelper(SColumnInfoData* pLeftCol, SColumnInfoData* pRightCol, SColumnInfoData* pOutputCol, int32_t numOfRows, int32_t step, int32_t factor, int32_t i) { _getBigintValue_fn_t getVectorBigintValueFnLeft = getVectorBigintValueFn(pLeftCol->info.type); _getBigintValue_fn_t getVectorBigintValueFnRight = getVectorBigintValueFn(pRightCol->info.type); @@ -1188,7 +1195,9 @@ static void vectorMathBigintSubHelper(SColumnInfoData* pLeftCol, SColumnInfoData colDataAppendNULL(pOutputCol, i); continue; // TODO set null or ignore } - *output = (getVectorBigintValueFnLeft(pLeftCol->pData, i) - getVectorBigintValueFnRight(pRightCol->pData, 0)) * factor; + *output = taosTimeSub(getVectorBigintValueFnLeft(pLeftCol->pData, i), getVectorBigintValueFnRight(pRightCol->pData, 0), + pRightCol->info.scale, pRightCol->info.precision); + } } } @@ -1211,7 +1220,13 @@ void vectorMathSub(SScalarParam* pLeft, SScalarParam* pRight, SScalarParam *pOut _getBigintValue_fn_t getVectorBigintValueFnLeft = getVectorBigintValueFn(pLeftCol->info.type); _getBigintValue_fn_t getVectorBigintValueFnRight = getVectorBigintValueFn(pRightCol->info.type); - if (pLeft->numOfRows == pRight->numOfRows) { + if (pLeft->numOfRows == 1 && pRight->numOfRows == 1) { + vectorMathTsSubHelper(pLeftCol, pRightCol, pOutputCol, pLeft->numOfRows, step, 1, i); + } else if (pLeft->numOfRows == 1) { + vectorMathTsSubHelper(pRightCol, pLeftCol, pOutputCol, pRight->numOfRows, step, -1, i); + } else if (pRight->numOfRows == 1) { + vectorMathTsSubHelper(pLeftCol, pRightCol, pOutputCol, pLeft->numOfRows, step, 1, i); + } else if (pLeft->numOfRows == pRight->numOfRows) { for (; i < pRight->numOfRows && i >= 0; i += step, output += 1) { if (IS_NULL) { colDataAppendNULL(pOutputCol, i); @@ -1219,10 +1234,6 @@ void vectorMathSub(SScalarParam* pLeft, SScalarParam* pRight, SScalarParam *pOut } *output = getVectorBigintValueFnLeft(pLeftCol->pData, i) - getVectorBigintValueFnRight(pRightCol->pData, i); } - } else if (pLeft->numOfRows == 1) { - vectorMathBigintSubHelper(pRightCol, pLeftCol, pOutputCol, pRight->numOfRows, step, -1, i); - } else if (pRight->numOfRows == 1) { - vectorMathBigintSubHelper(pLeftCol, pRightCol, pOutputCol, pLeft->numOfRows, step, 1, i); } } else { double *output = (double *)pOutputCol->pData; diff --git a/tests/script/jenkins/basic.txt b/tests/script/jenkins/basic.txt index 50d4c04a93..b4f9df8e5f 100644 --- a/tests/script/jenkins/basic.txt +++ b/tests/script/jenkins/basic.txt @@ -197,5 +197,6 @@ # --- scalar ./test.sh -f tsim/scalar/in.sim +./test.sh -f tsim/scalar/scalar.sim #======================b1-end=============== diff --git a/tests/script/tsim/scalar/scalar.sim b/tests/script/tsim/scalar/scalar.sim new file mode 100644 index 0000000000..32224e33ba --- /dev/null +++ b/tests/script/tsim/scalar/scalar.sim @@ -0,0 +1,67 @@ +system sh/stop_dnodes.sh +system sh/deploy.sh -n dnode1 -i 1 +system sh/exec.sh -n dnode1 -s start +sql connect + +print ======== step1 +sql drop database if exists db1; +sql create database db1 vgroups 3; +sql use db1; +sql create stable st1 (fts timestamp, fbool bool, ftiny tinyint, fsmall smallint, fint int, fbig bigint, futiny tinyint unsigned, fusmall smallint unsigned, fuint int unsigned, fubig bigint unsigned, ffloat float, fdouble double, fbin binary(10), fnchar nchar(10)) tags(tts timestamp, tbool bool, ttiny tinyint, tsmall smallint, tint int, tbig bigint, tutiny tinyint unsigned, tusmall smallint unsigned, tuint int unsigned, tubig bigint unsigned, tfloat float, tdouble double, tbin binary(10), tnchar nchar(10)); +sql create table tb1 using st1 tags('2022-07-10 16:31:00', true, 1, 1, 1, 1, 1, 1, 1, 1, 1.0, 1.0, 'a', 'a'); +sql create table tb2 using st1 tags('2022-07-10 16:32:00', false, 2, 2, 2, 2, 2, 2, 2, 2, 2.0, 2.0, 'b', 'b'); +sql create table tb3 using st1 tags('2022-07-10 16:33:00', true, 3, 3, 3, 3, 3, 3, 3, 3, 3.0, 3.0, 'c', 'c'); + +sql insert into tb1 values ('2022-07-10 16:31:01', false, 1, 1, 1, 1, 1, 1, 1, 1, 1.0, 1.0, 'a', 'a'); +sql insert into tb1 values ('2022-07-10 16:31:02', true, 2, 2, 2, 2, 2, 2, 2, 2, 2.0, 2.0, 'b', 'b'); +sql insert into tb1 values ('2022-07-10 16:31:03', false, 3, 3, 3, 3, 3, 3, 3, 3, 3.0, 3.0, 'c', 'c'); +sql insert into tb1 values ('2022-07-10 16:31:04', true, 4, 4, 4, 4, 4, 4, 4, 4, 4.0, 4.0, 'd', 'd'); +sql insert into tb1 values ('2022-07-10 16:31:05', false, 5, 5, 5, 5, 5, 5, 5, 5, 5.0, 5.0, 'e', 'e'); + +sql insert into tb2 values ('2022-07-10 16:32:01', false, 1, 1, 1, 1, 1, 1, 1, 1, 1.0, 1.0, 'a', 'a'); +sql insert into tb2 values ('2022-07-10 16:32:02', true, 2, 2, 2, 2, 2, 2, 2, 2, 2.0, 2.0, 'b', 'b'); +sql insert into tb2 values ('2022-07-10 16:32:03', false, 3, 3, 3, 3, 3, 3, 3, 3, 3.0, 3.0, 'c', 'c'); +sql insert into tb2 values ('2022-07-10 16:32:04', true, 4, 4, 4, 4, 4, 4, 4, 4, 4.0, 4.0, 'd', 'd'); +sql insert into tb2 values ('2022-07-10 16:32:05', false, 5, 5, 5, 5, 5, 5, 5, 5, 5.0, 5.0, 'e', 'e'); + +sql insert into tb3 values ('2022-07-10 16:33:01', false, 1, 1, 1, 1, 1, 1, 1, 1, 1.0, 1.0, 'a', 'a'); +sql insert into tb3 values ('2022-07-10 16:33:02', true, 2, 2, 2, 2, 2, 2, 2, 2, 2.0, 2.0, 'b', 'b'); +sql insert into tb3 values ('2022-07-10 16:33:03', false, 3, 3, 3, 3, 3, 3, 3, 3, 3.0, 3.0, 'c', 'c'); +sql insert into tb3 values ('2022-07-10 16:33:04', true, 4, 4, 4, 4, 4, 4, 4, 4, 4.0, 4.0, 'd', 'd'); +sql insert into tb3 values ('2022-07-10 16:33:05', false, 5, 5, 5, 5, 5, 5, 5, 5, 5.0, 5.0, 'e', 'e'); + +sql select 1+1n; +if $rows != 1 then + return -1 +endi +if $data00 != 2.000000000 then + return -1 +endi + + +sql select cast(1 as timestamp)+1n; +if $rows != 1 then + return -1 +endi +if $data00 != @70-02-01 08:00:00.000@ then + return -1 +endi + +sql select 1-1n; +if $rows != 1 then + return -1 +endi + +sql select cast(1 as timestamp)-1y; +if $rows != 1 then + return -1 +endi +if $data00 != @69-01-01 08:00:00.000@ then + return -1 +endi + +sql select 1n-now(); +sql select 1n+now(); +#sql select avg(4n); + +system sh/exec.sh -n dnode1 -s stop -x SIGINT -- GitLab From c2e2e73cc59a56fd1521879d45c21fbadb8e70da Mon Sep 17 00:00:00 2001 From: Shengliang Guan Date: Wed, 13 Jul 2022 17:03:26 +0800 Subject: [PATCH 061/153] fix: get mnode epset from sync module --- source/dnode/mnode/impl/src/mndMnode.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/source/dnode/mnode/impl/src/mndMnode.c b/source/dnode/mnode/impl/src/mndMnode.c index c03951b1d8..d7eaa72202 100644 --- a/source/dnode/mnode/impl/src/mndMnode.c +++ b/source/dnode/mnode/impl/src/mndMnode.c @@ -218,6 +218,7 @@ bool mndIsMnode(SMnode *pMnode, int32_t dnodeId) { } void mndGetMnodeEpSet(SMnode *pMnode, SEpSet *pEpSet) { +#if 0 SSdb *pSdb = pMnode->pSdb; int32_t totalMnodes = sdbGetSize(pSdb, SDB_MNODE); void *pIter = NULL; @@ -237,6 +238,9 @@ void mndGetMnodeEpSet(SMnode *pMnode, SEpSet *pEpSet) { addEpIntoEpSet(pEpSet, pObj->pDnode->fqdn, pObj->pDnode->port); sdbRelease(pSdb, pObj); } +#else + syncGetRetryEpSet(pMnode->syncMgmt.sync, pEpSet); +#endif } static int32_t mndSetCreateMnodeRedoLogs(SMnode *pMnode, STrans *pTrans, SMnodeObj *pObj) { -- GitLab From 32cb6755a2768d27740fa9c964e2678a36dfb06b Mon Sep 17 00:00:00 2001 From: 54liuyao <54liuyao@163.com> Date: Wed, 13 Jul 2022 17:08:27 +0800 Subject: [PATCH 062/153] feat(stream): optimize close window --- source/libs/executor/src/timewindowoperator.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source/libs/executor/src/timewindowoperator.c b/source/libs/executor/src/timewindowoperator.c index 943763dadb..2d64e6bd1c 100644 --- a/source/libs/executor/src/timewindowoperator.c +++ b/source/libs/executor/src/timewindowoperator.c @@ -1338,9 +1338,9 @@ static int32_t closeIntervalWindow(SHashObj* pHashMap, STimeWindowAggSupp* pSup, uint64_t groupId = *(uint64_t*)key; ASSERT(keyLen == GET_RES_WINDOW_KEY_LEN(sizeof(TSKEY))); TSKEY ts = *(int64_t*)((char*)key + sizeof(uint64_t)); - SResultRowInfo dumyInfo; - dumyInfo.cur.pageId = -1; - STimeWindow win = getActiveTimeWindow(NULL, &dumyInfo, ts, pInterval, TSDB_ORDER_ASC); + STimeWindow win; + win.skey = ts; + win.ekey = taosTimeAdd(win.skey, pInterval->interval, pInterval->intervalUnit, pInterval->precision) - 1; SWinRes winRe = { .ts = win.skey, .groupId = groupId, -- GitLab From ca754adaa6ee13c2553a696574f2dd1b686931a5 Mon Sep 17 00:00:00 2001 From: dapan1121 Date: Wed, 13 Jul 2022 17:14:04 +0800 Subject: [PATCH 063/153] fix: add agg processing --- include/util/taoserror.h | 3 ++- source/libs/command/src/command.c | 10 +++++++--- source/libs/scalar/src/scalar.c | 2 +- source/util/src/terror.c | 1 + 4 files changed, 11 insertions(+), 5 deletions(-) diff --git a/include/util/taoserror.h b/include/util/taoserror.h index ce434612c3..c057d48875 100644 --- a/include/util/taoserror.h +++ b/include/util/taoserror.h @@ -584,7 +584,8 @@ int32_t* taosGetErrno(); #define TSDB_CODE_PAR_INVALID_INTERP_CLAUSE TAOS_DEF_ERROR_CODE(0, 0x265D) #define TSDB_CODE_PAR_NO_VALID_FUNC_IN_WIN TAOS_DEF_ERROR_CODE(0, 0x265E) #define TSDB_CODE_PAR_ONLY_SUPPORT_SINGLE_TABLE TAOS_DEF_ERROR_CODE(0, 0x265F) -#define TSDB_CODE_PAR_INVALID_SMA_INDEX TAOS_DEF_ERROR_CODE(0, 0x265C) +#define TSDB_CODE_PAR_INVALID_SMA_INDEX TAOS_DEF_ERROR_CODE(0, 0x2660) +#define TSDB_CODE_PAR_INVALID_SELECTED_EXPR TAOS_DEF_ERROR_CODE(0, 0x2661) //planner #define TSDB_CODE_PLAN_INTERNAL_ERROR TAOS_DEF_ERROR_CODE(0, 0x2700) diff --git a/source/libs/command/src/command.c b/source/libs/command/src/command.c index a2816209a9..034778e5bf 100644 --- a/source/libs/command/src/command.c +++ b/source/libs/command/src/command.c @@ -570,10 +570,14 @@ int32_t buildSelectResultDataBlock(SNodeList* pProjects, SSDataBlock* pBlock) { int32_t index = 0; SNode* pProj = NULL; FOREACH(pProj, pProjects) { - if (((SValueNode*)pProj)->isNull) { - colDataAppend(taosArrayGet(pBlock->pDataBlock, index++), 0, NULL, true); + if (QUERY_NODE_VALUE != nodeType(pProj)) { + return TSDB_CODE_PAR_INVALID_SELECTED_EXPR; } else { - colDataAppend(taosArrayGet(pBlock->pDataBlock, index++), 0, nodesGetValueFromNode((SValueNode*)pProj), false); + if (((SValueNode*)pProj)->isNull) { + colDataAppend(taosArrayGet(pBlock->pDataBlock, index++), 0, NULL, true); + } else { + colDataAppend(taosArrayGet(pBlock->pDataBlock, index++), 0, nodesGetValueFromNode((SValueNode*)pProj), false); + } } } diff --git a/source/libs/scalar/src/scalar.c b/source/libs/scalar/src/scalar.c index a2e9f7a1cd..bdfc411fa6 100644 --- a/source/libs/scalar/src/scalar.c +++ b/source/libs/scalar/src/scalar.c @@ -700,7 +700,7 @@ EDealRes sclRewriteNonConstOperator(SNode** pNode, SScalarCtx *ctx) { EDealRes sclRewriteFunction(SNode** pNode, SScalarCtx *ctx) { SFunctionNode *node = (SFunctionNode *)*pNode; SNode* tnode = NULL; - if ((!fmIsScalarFunc(node->funcId)) && (!ctx->dual)) { + if (!fmIsScalarFunc(node->funcId)) { return DEAL_RES_CONTINUE; } diff --git a/source/util/src/terror.c b/source/util/src/terror.c index ef6697b3b5..2364c53a9a 100644 --- a/source/util/src/terror.c +++ b/source/util/src/terror.c @@ -561,6 +561,7 @@ TAOS_DEFINE_ERROR(TSDB_CODE_PAR_INVALID_COL_JSON, "Only tag can be jso TAOS_DEFINE_ERROR(TSDB_CODE_PAR_VALUE_TOO_LONG, "Value too long for column/tag") TAOS_DEFINE_ERROR(TSDB_CODE_PAR_INVALID_DELETE_WHERE, "The DELETE statement must have a definite time window range") TAOS_DEFINE_ERROR(TSDB_CODE_PAR_INVALID_REDISTRIBUTE_VG, "The REDISTRIBUTE VGROUP statement only support 1 to 3 dnodes") +TAOS_DEFINE_ERROR(TSDB_CODE_PAR_INVALID_SELECTED_EXPR, "Invalid SELECTed expression") //planner TAOS_DEFINE_ERROR(TSDB_CODE_PLAN_INTERNAL_ERROR, "Planner internal error") -- GitLab From a015aca162066abe644db333b4ccd4499324c012 Mon Sep 17 00:00:00 2001 From: wangmm0220 Date: Wed, 13 Jul 2022 17:16:34 +0800 Subject: [PATCH 064/153] fix:core dump if stable name is null in SVCreateTbReq --- source/dnode/vnode/src/tq/tqSink.c | 1 + 1 file changed, 1 insertion(+) diff --git a/source/dnode/vnode/src/tq/tqSink.c b/source/dnode/vnode/src/tq/tqSink.c index dbbb2b2661..25615f8d5c 100644 --- a/source/dnode/vnode/src/tq/tqSink.c +++ b/source/dnode/vnode/src/tq/tqSink.c @@ -50,6 +50,7 @@ SSubmitReq* tdBlockToSubmit(const SArray* pBlocks, const STSchema* pTSchema, boo SVCreateTbReq createTbReq = {0}; createTbReq.name = buildCtbNameByGroupId(stbFullName, pDataBlock->info.groupId); + createTbReq.ctb.name = strdup(stbFullName); createTbReq.flags = 0; createTbReq.type = TSDB_CHILD_TABLE; createTbReq.ctb.suid = suid; -- GitLab From 2ea11ba9c1773936c396e0a1943e3ed0321b128b Mon Sep 17 00:00:00 2001 From: Shengliang Guan Date: Wed, 13 Jul 2022 16:54:49 +0800 Subject: [PATCH 065/153] test: restore some 2.0 case --- tests/script/general/field/testSuite.sim | 14 ----- tests/script/jenkins/basic.txt | 61 ++++++++++++------- tests/script/{general => tsim}/field/2.sim | 12 ++-- tests/script/{general => tsim}/field/3.sim | 18 +++--- tests/script/{general => tsim}/field/4.sim | 22 +++---- tests/script/{general => tsim}/field/5.sim | 26 ++++---- tests/script/{general => tsim}/field/6.sim | 30 +++++---- .../script/{general => tsim}/field/bigint.sim | 9 +-- .../script/{general => tsim}/field/binary.sim | 6 +- tests/script/{general => tsim}/field/bool.sim | 9 +-- .../script/{general => tsim}/field/double.sim | 9 +-- .../script/{general => tsim}/field/float.sim | 10 ++- tests/script/{general => tsim}/field/int.sim | 10 ++- .../script/{general => tsim}/field/single.sim | 6 +- .../{general => tsim}/field/smallint.sim | 10 ++- .../{general => tsim}/field/tinyint.sim | 9 +-- .../field/unsigined_bigint.sim | 13 ++-- 17 files changed, 120 insertions(+), 154 deletions(-) delete mode 100644 tests/script/general/field/testSuite.sim rename tests/script/{general => tsim}/field/2.sim (95%) rename tests/script/{general => tsim}/field/3.sim (97%) rename tests/script/{general => tsim}/field/4.sim (97%) rename tests/script/{general => tsim}/field/5.sim (97%) rename tests/script/{general => tsim}/field/6.sim (97%) rename tests/script/{general => tsim}/field/bigint.sim (94%) rename tests/script/{general => tsim}/field/binary.sim (93%) rename tests/script/{general => tsim}/field/bool.sim (93%) rename tests/script/{general => tsim}/field/double.sim (93%) rename tests/script/{general => tsim}/field/float.sim (93%) rename tests/script/{general => tsim}/field/int.sim (93%) rename tests/script/{general => tsim}/field/single.sim (97%) rename tests/script/{general => tsim}/field/smallint.sim (93%) rename tests/script/{general => tsim}/field/tinyint.sim (93%) rename tests/script/{general => tsim}/field/unsigined_bigint.sim (94%) diff --git a/tests/script/general/field/testSuite.sim b/tests/script/general/field/testSuite.sim deleted file mode 100644 index d12f0ebbd4..0000000000 --- a/tests/script/general/field/testSuite.sim +++ /dev/null @@ -1,14 +0,0 @@ -# run general/field/single.sim -run general/field/bool.sim -run general/field/smallint.sim -run general/field/tinyint.sim -run general/field/int.sim -run general/field/bigint.sim -run general/field/float.sim -run general/field/double.sim -# run general/field/binary.sim -# run general/field/2.sim -# run general/field/3.sim -# run general/field/4.sim -# run general/field/5.sim -# run general/field/6.sim diff --git a/tests/script/jenkins/basic.txt b/tests/script/jenkins/basic.txt index 32279b3a4a..0c3126bac7 100644 --- a/tests/script/jenkins/basic.txt +++ b/tests/script/jenkins/basic.txt @@ -1,33 +1,12 @@ #======================b1-start=============== -# ---- alter -./test.sh -f tsim/alter/cached_schema_after_alter.sim -./test.sh -f tsim/alter/dnode.sim -#./test.sh -f tsim/alter/table.sim - # ---- user ./test.sh -f tsim/user/basic.sim ./test.sh -f tsim/user/password.sim ./test.sh -f tsim/user/privilege_db.sim ./test.sh -f tsim/user/privilege_sysinfo.sim -# ---- cache -./test.sh -f tsim/cache/new_metrics.sim -./test.sh -f tsim/cache/restart_table.sim -./test.sh -f tsim/cache/restart_metrics.sim - -# ---- column -./test.sh -f tsim/column/commit.sim -./test.sh -f tsim/column/metrics.sim -./test.sh -f tsim/column/table.sim - -# ---- compress -./test.sh -f tsim/compress/commitlog.sim -./test.sh -f tsim/compress/compress2.sim -./test.sh -f tsim/compress/compress.sim -./test.sh -f tsim/compress/uncompress.sim - # ---- db ./test.sh -f tsim/db/alter_option.sim # ./test.sh -f tsim/db/alter_replica_13.sim @@ -108,7 +87,7 @@ ./test.sh -f tsim/mnode/basic1.sim ./test.sh -f tsim/mnode/basic2.sim ./test.sh -f tsim/mnode/basic3.sim -#./test.sh -f tsim/mnode/basic4.sim +./test.sh -f tsim/mnode/basic4.sim ./test.sh -f tsim/mnode/basic5.sim # ---- show @@ -225,4 +204,42 @@ # --- scalar ./test.sh -f tsim/scalar/in.sim +# ---- alter +./test.sh -f tsim/alter/cached_schema_after_alter.sim +./test.sh -f tsim/alter/dnode.sim +#./test.sh -f tsim/alter/table.sim + +# ---- cache +./test.sh -f tsim/cache/new_metrics.sim +./test.sh -f tsim/cache/restart_table.sim +./test.sh -f tsim/cache/restart_metrics.sim + +# ---- column +./test.sh -f tsim/column/commit.sim +./test.sh -f tsim/column/metrics.sim +./test.sh -f tsim/column/table.sim + +# ---- compress +./test.sh -f tsim/compress/commitlog.sim +./test.sh -f tsim/compress/compress2.sim +./test.sh -f tsim/compress/compress.sim +./test.sh -f tsim/compress/uncompress.sim + +# ---- field +./test.sh -f tsim/field/2.sim +./test.sh -f tsim/field/3.sim +./test.sh -f tsim/field/4.sim +./test.sh -f tsim/field/5.sim +./test.sh -f tsim/field/6.sim +./test.sh -f tsim/field/binary.sim +./test.sh -f tsim/field/bigint.sim +./test.sh -f tsim/field/bool.sim +./test.sh -f tsim/field/double.sim +./test.sh -f tsim/field/float.sim +./test.sh -f tsim/field/int.sim +./test.sh -f tsim/field/single.sim +./test.sh -f tsim/field/smallint.sim +./test.sh -f tsim/field/tinyint.sim +./test.sh -f tsim/field/unsigined_bigint.sim + #======================b1-end=============== diff --git a/tests/script/general/field/2.sim b/tests/script/tsim/field/2.sim similarity index 95% rename from tests/script/general/field/2.sim rename to tests/script/tsim/field/2.sim index cc6889fd75..b5c501ceed 100644 --- a/tests/script/general/field/2.sim +++ b/tests/script/tsim/field/2.sim @@ -1,10 +1,8 @@ system sh/stop_dnodes.sh system sh/deploy.sh -n dnode1 -i 1 -system sh/cfg.sh -n dnode1 -c walLevel -v 1 system sh/exec.sh -n dnode1 -s start - -sleep 2000 sql connect + print ======================== dnode1 start $dbPrefix = db @@ -280,18 +278,18 @@ if $data00 != 25 then endi print =============== step12 -sql select count(tbcol), avg(tbcol), sum(tbcol), min(tbcol), max(tbcol), first(tbcol), last(tbcol) from $mt where tbcol2 = 1 interval(1d) group by tgcol order by tgcol desc +sql select count(tbcol), avg(tbcol), sum(tbcol), min(tbcol), max(tbcol), first(tbcol), last(tbcol) from $mt where tbcol2 = 1 group by tgcol order by tgcol desc print $db -print select count(tbcol), avg(tbcol), sum(tbcol), min(tbcol), max(tbcol), first(tbcol), last(tbcol) from $mt where tbcol2 = 1 interval(1d) group by tgcol +print select count(tbcol), avg(tbcol), sum(tbcol), min(tbcol), max(tbcol), first(tbcol), last(tbcol) from $mt where tbcol2 = 1 group by tgcol print $data00 $data01 $data02 $data03 $data04 $data05 $data06 -if $data01 != 100 then +if $data00 != 100 then return -1 endi print =============== clear sql drop database $db sql show databases -if $rows != 0 then +if $rows != 2 then return -1 endi diff --git a/tests/script/general/field/3.sim b/tests/script/tsim/field/3.sim similarity index 97% rename from tests/script/general/field/3.sim rename to tests/script/tsim/field/3.sim index cb3c6621ac..661bc6a85a 100644 --- a/tests/script/general/field/3.sim +++ b/tests/script/tsim/field/3.sim @@ -1,10 +1,8 @@ system sh/stop_dnodes.sh system sh/deploy.sh -n dnode1 -i 1 -system sh/cfg.sh -n dnode1 -c walLevel -v 1 system sh/exec.sh -n dnode1 -s start - -sleep 2000 sql connect + print ======================== dnode1 start $dbPrefix = db @@ -493,28 +491,28 @@ if $data00 != 25 then endi print =============== step19 -sql select count(tbcol1), avg(tbcol1), sum(tbcol1), min(tbcol1), max(tbcol1), first(tbcol1), last(tbcol1) from $mt where tbcol1 = 1 and tbcol2 = 1 and tbcol3 = 1 interval(1d) group by tgcol1 order by tgcol1 desc +sql select count(tbcol1), avg(tbcol1), sum(tbcol1), min(tbcol1), max(tbcol1), first(tbcol1), last(tbcol1) from $mt where tbcol1 = 1 and tbcol2 = 1 and tbcol3 = 1 group by tgcol1 order by tgcol1 desc print $data00 $data01 $data02 $data03 $data04 $data05 $data06 -if $data01 != 100 then +if $data00 != 100 then return -1 endi -sql select count(tbcol1), avg(tbcol1), sum(tbcol1), min(tbcol1), max(tbcol1), first(tbcol1), last(tbcol1) from $mt where tbcol1 = 1 and tbcol2 = 1 and tbcol3 = 1 interval(1d) group by tgcol2 order by tgcol2 desc +sql select count(tbcol1), avg(tbcol1), sum(tbcol1), min(tbcol1), max(tbcol1), first(tbcol1), last(tbcol1) from $mt where tbcol1 = 1 and tbcol2 = 1 and tbcol3 = 1 group by tgcol2 order by tgcol2 desc print $data00 $data01 $data02 $data03 $data04 $data05 $data06 -if $data01 != 100 then +if $data00 != 100 then return -1 endi -sql select count(tbcol1), avg(tbcol1), sum(tbcol1), min(tbcol1), max(tbcol1), first(tbcol1), last(tbcol1) from $mt where tbcol1 = 1 and tbcol2 = 1 and tbcol3 = 1 interval(1d) group by tgcol3 order by tgcol3 desc +sql select count(tbcol1), avg(tbcol1), sum(tbcol1), min(tbcol1), max(tbcol1), first(tbcol1), last(tbcol1) from $mt where tbcol1 = 1 and tbcol2 = 1 and tbcol3 = 1 group by tgcol3 order by tgcol3 desc print $data00 $data01 $data02 $data03 $data04 $data05 $data06 -if $data01 != 100 then +if $data00 != 100 then return -1 endi print =============== clear sql drop database $db sql show databases -if $rows != 0 then +if $rows != 2 then return -1 endi diff --git a/tests/script/general/field/4.sim b/tests/script/tsim/field/4.sim similarity index 97% rename from tests/script/general/field/4.sim rename to tests/script/tsim/field/4.sim index 2d893da777..734179c5bb 100644 --- a/tests/script/general/field/4.sim +++ b/tests/script/tsim/field/4.sim @@ -1,10 +1,8 @@ system sh/stop_dnodes.sh system sh/deploy.sh -n dnode1 -i 1 -system sh/cfg.sh -n dnode1 -c walLevel -v 1 system sh/exec.sh -n dnode1 -s start - -sleep 2000 sql connect + print ======================== dnode1 start $dbPrefix = db @@ -677,34 +675,34 @@ if $data00 != 25 then endi print =============== step24 -sql select count(tbcol1), avg(tbcol1), sum(tbcol1), min(tbcol1), max(tbcol1), first(tbcol1), last(tbcol1) from $mt where tbcol1 = 1 and tbcol2 = 1 and tbcol3 = 1 interval(1d) group by tgcol1 order by tgcol1 desc +sql select count(tbcol1), avg(tbcol1), sum(tbcol1), min(tbcol1), max(tbcol1), first(tbcol1), last(tbcol1) from $mt where tbcol1 = 1 and tbcol2 = 1 and tbcol3 = 1 group by tgcol1 order by tgcol1 desc print $data00 $data01 $data02 $data03 $data04 $data05 $data06 -if $data01 != 100 then +if $data00 != 100 then return -1 endi -sql select count(tbcol1), avg(tbcol1), sum(tbcol1), min(tbcol1), max(tbcol1), first(tbcol1), last(tbcol1) from $mt where tbcol1 = 1 and tbcol2 = 1 and tbcol3 = 1 interval(1d) group by tgcol2 order by tgcol2 desc +sql select count(tbcol1), avg(tbcol1), sum(tbcol1), min(tbcol1), max(tbcol1), first(tbcol1), last(tbcol1) from $mt where tbcol1 = 1 and tbcol2 = 1 and tbcol3 = 1 group by tgcol2 order by tgcol2 desc print $data00 $data01 $data02 $data03 $data04 $data05 $data06 -if $data01 != 100 then +if $data00 != 100 then return -1 endi -sql select count(tbcol1), avg(tbcol1), sum(tbcol1), min(tbcol1), max(tbcol1), first(tbcol1), last(tbcol1) from $mt where tbcol1 = 1 and tbcol2 = 1 and tbcol3 = 1 interval(1d) group by tgcol3 order by tgcol3 desc +sql select count(tbcol1), avg(tbcol1), sum(tbcol1), min(tbcol1), max(tbcol1), first(tbcol1), last(tbcol1) from $mt where tbcol1 = 1 and tbcol2 = 1 and tbcol3 = 1 group by tgcol3 order by tgcol3 desc print $data00 $data01 $data02 $data03 $data04 $data05 $data06 -if $data01 != 100 then +if $data00 != 100 then return -1 endi -sql select count(tbcol1), avg(tbcol1), sum(tbcol1), min(tbcol1), max(tbcol1), first(tbcol1), last(tbcol1) from $mt where tbcol1 = 1 and tbcol2 = 1 and tbcol3 = 1 and tbcol4 = 1 interval(1d) group by tgcol4 order by tgcol4 desc +sql select count(tbcol1), avg(tbcol1), sum(tbcol1), min(tbcol1), max(tbcol1), first(tbcol1), last(tbcol1) from $mt where tbcol1 = 1 and tbcol2 = 1 and tbcol3 = 1 and tbcol4 = 1 group by tgcol4 order by tgcol4 desc print $data00 $data01 $data02 $data03 $data04 $data05 $data06 -if $data01 != 100 then +if $data00 != 100 then return -1 endi print =============== clear sql drop database $db sql show databases -if $rows != 0 then +if $rows != 2 then return -1 endi diff --git a/tests/script/general/field/5.sim b/tests/script/tsim/field/5.sim similarity index 97% rename from tests/script/general/field/5.sim rename to tests/script/tsim/field/5.sim index e1421bdb4f..5185d8556e 100644 --- a/tests/script/general/field/5.sim +++ b/tests/script/tsim/field/5.sim @@ -1,10 +1,8 @@ system sh/stop_dnodes.sh system sh/deploy.sh -n dnode1 -i 1 -system sh/cfg.sh -n dnode1 -c walLevel -v 1 system sh/exec.sh -n dnode1 -s start - -sleep 2000 sql connect + print ======================== dnode1 start $dbPrefix = db @@ -794,40 +792,40 @@ endi print =============== step27 -sql select count(tbcol1), avg(tbcol1), sum(tbcol1), min(tbcol1), max(tbcol1), first(tbcol1), last(tbcol1) from $mt where tbcol1 = 1 and tbcol2 = 1 and tbcol3 = 1 interval(1d) group by tgcol1 order by tgcol1 desc +sql select count(tbcol1), avg(tbcol1), sum(tbcol1), min(tbcol1), max(tbcol1), first(tbcol1), last(tbcol1) from $mt where tbcol1 = 1 and tbcol2 = 1 and tbcol3 = 1 group by tgcol1 order by tgcol1 desc print $data00 $data01 $data02 $data03 $data04 $data05 $data06 -if $data01 != 100 then +if $data00 != 100 then return -1 endi -sql select count(tbcol1), avg(tbcol1), sum(tbcol1), min(tbcol1), max(tbcol1), first(tbcol1), last(tbcol1) from $mt where tbcol1 = 1 and tbcol2 = 1 and tbcol3 = 1 interval(1d) group by tgcol2 order by tgcol2 desc +sql select count(tbcol1), avg(tbcol1), sum(tbcol1), min(tbcol1), max(tbcol1), first(tbcol1), last(tbcol1) from $mt where tbcol1 = 1 and tbcol2 = 1 and tbcol3 = 1 group by tgcol2 order by tgcol2 desc print $data00 $data01 $data02 $data03 $data04 $data05 $data06 -if $data01 != 100 then +if $data00 != 100 then return -1 endi -sql select count(tbcol1), avg(tbcol1), sum(tbcol1), min(tbcol1), max(tbcol1), first(tbcol1), last(tbcol1) from $mt where tbcol1 = 1 and tbcol2 = 1 and tbcol3 = 1 interval(1d) group by tgcol3 order by tgcol3 desc +sql select count(tbcol1), avg(tbcol1), sum(tbcol1), min(tbcol1), max(tbcol1), first(tbcol1), last(tbcol1) from $mt where tbcol1 = 1 and tbcol2 = 1 and tbcol3 = 1 group by tgcol3 order by tgcol3 desc print $data00 $data01 $data02 $data03 $data04 $data05 $data06 -if $data01 != 100 then +if $data00 != 100 then return -1 endi -sql select count(tbcol1), avg(tbcol1), sum(tbcol1), min(tbcol1), max(tbcol1), first(tbcol1), last(tbcol1) from $mt where tbcol1 = 1 and tbcol2 = 1 and tbcol3 = 1 and tbcol4 = 1 interval(1d) group by tgcol4 order by tgcol4 desc +sql select count(tbcol1), avg(tbcol1), sum(tbcol1), min(tbcol1), max(tbcol1), first(tbcol1), last(tbcol1) from $mt where tbcol1 = 1 and tbcol2 = 1 and tbcol3 = 1 and tbcol4 = 1 group by tgcol4 order by tgcol4 desc print $data00 $data01 $data02 $data03 $data04 $data05 $data06 -if $data01 != 100 then +if $data00 != 100 then return -1 endi -sql select count(tbcol1), avg(tbcol1), sum(tbcol1), min(tbcol1), max(tbcol1), first(tbcol1), last(tbcol1) from $mt where tbcol1 = 1 and tbcol2 = 1 and tbcol3 = 1 and tbcol4 = 1 and tbcol5 = 1 interval(1d) group by tgcol5 order by tgcol5 desc +sql select count(tbcol1), avg(tbcol1), sum(tbcol1), min(tbcol1), max(tbcol1), first(tbcol1), last(tbcol1) from $mt where tbcol1 = 1 and tbcol2 = 1 and tbcol3 = 1 and tbcol4 = 1 and tbcol5 = 1 group by tgcol5 order by tgcol5 desc print $data00 $data01 $data02 $data03 $data04 $data05 $data06 -if $data01 != 100 then +if $data00 != 100 then return -1 endi print =============== clear sql drop database $db sql show databases -if $rows != 0 then +if $rows != 2 then return -1 endi diff --git a/tests/script/general/field/6.sim b/tests/script/tsim/field/6.sim similarity index 97% rename from tests/script/general/field/6.sim rename to tests/script/tsim/field/6.sim index 27475d591f..8ceefae228 100644 --- a/tests/script/general/field/6.sim +++ b/tests/script/tsim/field/6.sim @@ -1,10 +1,8 @@ system sh/stop_dnodes.sh system sh/deploy.sh -n dnode1 -i 1 -system sh/cfg.sh -n dnode1 -c walLevel -v 1 system sh/exec.sh -n dnode1 -s start - -sleep 2000 sql connect + print ======================== dnode1 start $dbPrefix = db @@ -943,46 +941,46 @@ if $data00 != 25 then endi print =============== step31 -sql select count(tbcol1), avg(tbcol1), sum(tbcol1), min(tbcol1), max(tbcol1), first(tbcol1), last(tbcol1) from $mt where tbcol1 = 1 and tbcol2 = 1 and tbcol3 = 1 interval(1d) group by tgcol1 order by tgcol1 desc +sql select count(tbcol1), avg(tbcol1), sum(tbcol1), min(tbcol1), max(tbcol1), first(tbcol1), last(tbcol1) from $mt where tbcol1 = 1 and tbcol2 = 1 and tbcol3 = 1 group by tgcol1 order by tgcol1 desc print $data00 $data01 $data02 $data03 $data04 $data05 $data06 -if $data01 != 100 then +if $data00 != 100 then return -1 endi -sql select count(tbcol1), avg(tbcol1), sum(tbcol1), min(tbcol1), max(tbcol1), first(tbcol1), last(tbcol1) from $mt where tbcol1 = 1 and tbcol2 = 1 and tbcol3 = 1 interval(1d) group by tgcol2 order by tgcol2 desc +sql select count(tbcol1), avg(tbcol1), sum(tbcol1), min(tbcol1), max(tbcol1), first(tbcol1), last(tbcol1) from $mt where tbcol1 = 1 and tbcol2 = 1 and tbcol3 = 1 group by tgcol2 order by tgcol2 desc print $data00 $data01 $data02 $data03 $data04 $data05 $data06 -if $data01 != 100 then +if $data00 != 100 then return -1 endi -sql select count(tbcol1), avg(tbcol1), sum(tbcol1), min(tbcol1), max(tbcol1), first(tbcol1), last(tbcol1) from $mt where tbcol1 = 1 and tbcol2 = 1 and tbcol3 = 1 interval(1d) group by tgcol3 order by tgcol3 desc +sql select count(tbcol1), avg(tbcol1), sum(tbcol1), min(tbcol1), max(tbcol1), first(tbcol1), last(tbcol1) from $mt where tbcol1 = 1 and tbcol2 = 1 and tbcol3 = 1 group by tgcol3 order by tgcol3 desc print $data00 $data01 $data02 $data03 $data04 $data05 $data06 -if $data01 != 100 then +if $data00 != 100 then return -1 endi -sql select count(tbcol1), avg(tbcol1), sum(tbcol1), min(tbcol1), max(tbcol1), first(tbcol1), last(tbcol1) from $mt where tbcol1 = 1 and tbcol2 = 1 and tbcol3 = 1 and tbcol4 = 1 interval(1d) group by tgcol4 order by tgcol4 desc +sql select count(tbcol1), avg(tbcol1), sum(tbcol1), min(tbcol1), max(tbcol1), first(tbcol1), last(tbcol1) from $mt where tbcol1 = 1 and tbcol2 = 1 and tbcol3 = 1 and tbcol4 = 1 group by tgcol4 order by tgcol4 desc print $data00 $data01 $data02 $data03 $data04 $data05 $data06 -if $data01 != 100 then +if $data00 != 100 then return -1 endi -sql select count(tbcol1), avg(tbcol1), sum(tbcol1), min(tbcol1), max(tbcol1), first(tbcol1), last(tbcol1) from $mt where tbcol1 = 1 and tbcol2 = 1 and tbcol3 = 1 and tbcol4 = 1 and tbcol5 = 1 interval(1d) group by tgcol5 order by tgcol5 desc +sql select count(tbcol1), avg(tbcol1), sum(tbcol1), min(tbcol1), max(tbcol1), first(tbcol1), last(tbcol1) from $mt where tbcol1 = 1 and tbcol2 = 1 and tbcol3 = 1 and tbcol4 = 1 and tbcol5 = 1 group by tgcol5 order by tgcol5 desc print $data00 $data01 $data02 $data03 $data04 $data05 $data06 -if $data01 != 100 then +if $data00 != 100 then return -1 endi -sql select count(tbcol1), avg(tbcol1), sum(tbcol1), min(tbcol1), max(tbcol1), first(tbcol1), last(tbcol1) from $mt where tbcol1 = 1 and tbcol2 = 1 and tbcol3 = 1 and tbcol4 = 1 and tbcol5 = 1 and tbcol6 = 1 interval(1d) group by tgcol6 order by tgcol6 desc +sql select count(tbcol1), avg(tbcol1), sum(tbcol1), min(tbcol1), max(tbcol1), first(tbcol1), last(tbcol1) from $mt where tbcol1 = 1 and tbcol2 = 1 and tbcol3 = 1 and tbcol4 = 1 and tbcol5 = 1 and tbcol6 = 1 group by tgcol6 order by tgcol6 desc print $data00 $data01 $data02 $data03 $data04 $data05 $data06 -if $data01 != 100 then +if $data00 != 100 then return -1 endi print =============== clear sql drop database $db sql show databases -if $rows != 0 then +if $rows != 2 then return -1 endi diff --git a/tests/script/general/field/bigint.sim b/tests/script/tsim/field/bigint.sim similarity index 94% rename from tests/script/general/field/bigint.sim rename to tests/script/tsim/field/bigint.sim index cfe8c561f0..c580a4df1c 100644 --- a/tests/script/general/field/bigint.sim +++ b/tests/script/tsim/field/bigint.sim @@ -1,9 +1,6 @@ system sh/stop_dnodes.sh system sh/deploy.sh -n dnode1 -i 1 -system sh/cfg.sh -n dnode1 -c walLevel -v 1 system sh/exec.sh -n dnode1 -s start - -sleep 2000 sql connect print ======================== dnode1 start @@ -146,16 +143,16 @@ if $data00 != 25 then endi print =============== step8 -sql select count(tbcol), avg(tbcol), sum(tbcol), min(tbcol), max(tbcol), first(tbcol), last(tbcol) from $mt where tbcol = 1 interval(1d) group by tgcol order by tgcol desc +sql select count(tbcol), avg(tbcol), sum(tbcol), min(tbcol), max(tbcol), first(tbcol), last(tbcol) from $mt where tbcol = 1 group by tgcol order by tgcol desc print $data00 $data01 $data02 $data03 $data04 $data05 $data06 -if $data01 != 100 then +if $data00 != 100 then return -1 endi print =============== clear sql drop database $db sql show databases -if $rows != 0 then +if $rows != 2 then return -1 endi diff --git a/tests/script/general/field/binary.sim b/tests/script/tsim/field/binary.sim similarity index 93% rename from tests/script/general/field/binary.sim rename to tests/script/tsim/field/binary.sim index 821dbc9a82..59005e1ef1 100644 --- a/tests/script/general/field/binary.sim +++ b/tests/script/tsim/field/binary.sim @@ -1,9 +1,6 @@ system sh/stop_dnodes.sh system sh/deploy.sh -n dnode1 -i 1 -system sh/cfg.sh -n dnode1 -c walLevel -v 1 system sh/exec.sh -n dnode1 -s start - -sleep 2000 sql connect print ======================== dnode1 start @@ -47,7 +44,6 @@ while $i < 10 $i = $i + 1 endw - print =============== step2 sql select * from $mt where tbcol = '0' @@ -70,7 +66,7 @@ sql_error select count(tbcol), avg(tbcol), sum(tbcol), min(tbcol), max(tbcol), f print =============== clear sql drop database $db sql show databases -if $rows != 0 then +if $rows != 2 then return -1 endi diff --git a/tests/script/general/field/bool.sim b/tests/script/tsim/field/bool.sim similarity index 93% rename from tests/script/general/field/bool.sim rename to tests/script/tsim/field/bool.sim index d94071b328..37292e9758 100644 --- a/tests/script/general/field/bool.sim +++ b/tests/script/tsim/field/bool.sim @@ -1,9 +1,6 @@ system sh/stop_dnodes.sh system sh/deploy.sh -n dnode1 -i 1 -system sh/cfg.sh -n dnode1 -c walLevel -v 1 system sh/exec.sh -n dnode1 -s start - -sleep 2000 sql connect print ======================== dnode1 start @@ -144,8 +141,8 @@ if $data00 != 25 then endi print =============== step8 -sql select count(tbcol), first(tbcol), last(tbcol) from $mt where tbcol = true interval(1d) group by tgcol order by tgcol desc -print select count(tbcol), first(tbcol), last(tbcol) from $mt where tbcol = true interval(1d) group by tgcol order by tgcol desc +sql select count(tbcol), first(tbcol), last(tbcol) from $mt where tbcol = true group by tgcol order by tgcol desc +print select count(tbcol), first(tbcol), last(tbcol) from $mt where tbcol = true group by tgcol order by tgcol desc print $data00 $data01 $data02 $data03 $data04 $data05 $data06 if $data01 != 100 then return -1 @@ -154,7 +151,7 @@ endi print =============== clear sql drop database $db sql show databases -if $rows != 0 then +if $rows != 2 then return -1 endi diff --git a/tests/script/general/field/double.sim b/tests/script/tsim/field/double.sim similarity index 93% rename from tests/script/general/field/double.sim rename to tests/script/tsim/field/double.sim index 0c9c23e304..e7b1c8e8af 100644 --- a/tests/script/general/field/double.sim +++ b/tests/script/tsim/field/double.sim @@ -1,9 +1,6 @@ system sh/stop_dnodes.sh system sh/deploy.sh -n dnode1 -i 1 -system sh/cfg.sh -n dnode1 -c walLevel -v 1 system sh/exec.sh -n dnode1 -s start - -sleep 2000 sql connect print ======================== dnode1 start @@ -144,16 +141,16 @@ if $data00 != 25 then endi print =============== step8 -sql select count(tbcol), avg(tbcol), sum(tbcol), min(tbcol), max(tbcol), first(tbcol), last(tbcol) from $mt where tbcol = 1 interval(1d) group by tgcol order by tgcol desc +sql select count(tbcol), avg(tbcol), sum(tbcol), min(tbcol), max(tbcol), first(tbcol), last(tbcol) from $mt where tbcol = 1 group by tgcol order by tgcol desc print $data00 $data01 $data02 $data03 $data04 $data05 $data06 -if $data01 != 100 then +if $data00 != 100 then return -1 endi print =============== clear sql drop database $db sql show databases -if $rows != 0 then +if $rows != 2 then return -1 endi diff --git a/tests/script/general/field/float.sim b/tests/script/tsim/field/float.sim similarity index 93% rename from tests/script/general/field/float.sim rename to tests/script/tsim/field/float.sim index 00423c00b8..159a4b60ab 100644 --- a/tests/script/general/field/float.sim +++ b/tests/script/tsim/field/float.sim @@ -1,10 +1,8 @@ system sh/stop_dnodes.sh system sh/deploy.sh -n dnode1 -i 1 -system sh/cfg.sh -n dnode1 -c walLevel -v 1 system sh/exec.sh -n dnode1 -s start - -sleep 2000 sql connect + print ======================== dnode1 start $dbPrefix = db @@ -144,16 +142,16 @@ if $data00 != 25 then endi print =============== step8 -sql select count(tbcol), avg(tbcol), sum(tbcol), min(tbcol), max(tbcol), first(tbcol), last(tbcol) from $mt where tbcol = 1 interval(1d) group by tgcol order by tgcol desc +sql select count(tbcol), avg(tbcol), sum(tbcol), min(tbcol), max(tbcol), first(tbcol), last(tbcol) from $mt where tbcol = 1 group by tgcol order by tgcol desc print $data00 $data01 $data02 $data03 $data04 $data05 $data06 -if $data01 != 100 then +if $data00 != 100 then return -1 endi print =============== clear sql drop database $db sql show databases -if $rows != 0 then +if $rows != 2 then return -1 endi diff --git a/tests/script/general/field/int.sim b/tests/script/tsim/field/int.sim similarity index 93% rename from tests/script/general/field/int.sim rename to tests/script/tsim/field/int.sim index 0e322e4f12..2b5b70141a 100644 --- a/tests/script/general/field/int.sim +++ b/tests/script/tsim/field/int.sim @@ -1,10 +1,8 @@ system sh/stop_dnodes.sh system sh/deploy.sh -n dnode1 -i 1 -system sh/cfg.sh -n dnode1 -c walLevel -v 1 system sh/exec.sh -n dnode1 -s start - -sleep 2000 sql connect + print ======================== dnode1 start $dbPrefix = db @@ -144,16 +142,16 @@ if $data00 != 25 then endi print =============== step8 -sql select count(tbcol), avg(tbcol), sum(tbcol), min(tbcol), max(tbcol), first(tbcol), last(tbcol) from $mt where tbcol = 1 interval(1d) group by tgcol order by tgcol desc +sql select count(tbcol), avg(tbcol), sum(tbcol), min(tbcol), max(tbcol), first(tbcol), last(tbcol) from $mt where tbcol = 1 group by tgcol order by tgcol desc print $data00 $data01 $data02 $data03 $data04 $data05 $data06 -if $data01 != 100 then +if $data00 != 100 then return -1 endi print =============== clear sql drop database $db sql show databases -if $rows != 0 then +if $rows != 2 then return -1 endi diff --git a/tests/script/general/field/single.sim b/tests/script/tsim/field/single.sim similarity index 97% rename from tests/script/general/field/single.sim rename to tests/script/tsim/field/single.sim index 3f6bf4309f..115e76ffeb 100644 --- a/tests/script/general/field/single.sim +++ b/tests/script/tsim/field/single.sim @@ -1,10 +1,8 @@ system sh/stop_dnodes.sh system sh/deploy.sh -n dnode1 -i 1 -system sh/cfg.sh -n dnode1 -c walLevel -v 1 system sh/exec.sh -n dnode1 -s start - -sleep 2000 sql connect + print ======================== dnode1 start $dbPrefix = db @@ -211,7 +209,7 @@ endi print =============== clear sql drop database $db sql show databases -if $rows != 0 then +if $rows != 2 then return -1 endi diff --git a/tests/script/general/field/smallint.sim b/tests/script/tsim/field/smallint.sim similarity index 93% rename from tests/script/general/field/smallint.sim rename to tests/script/tsim/field/smallint.sim index 78b2b998cf..975f02bf9b 100644 --- a/tests/script/general/field/smallint.sim +++ b/tests/script/tsim/field/smallint.sim @@ -1,10 +1,8 @@ system sh/stop_dnodes.sh system sh/deploy.sh -n dnode1 -i 1 -system sh/cfg.sh -n dnode1 -c walLevel -v 1 system sh/exec.sh -n dnode1 -s start - -sleep 2000 sql connect + print ======================== dnode1 start $dbPrefix = db @@ -144,16 +142,16 @@ if $data00 != 25 then endi print =============== step8 -sql select count(tbcol), avg(tbcol), sum(tbcol), min(tbcol), max(tbcol), first(tbcol), last(tbcol) from $mt where tbcol = 1 interval(1d) group by tgcol order by tgcol desc +sql select count(tbcol), avg(tbcol), sum(tbcol), min(tbcol), max(tbcol), first(tbcol), last(tbcol) from $mt where tbcol = 1 group by tgcol order by tgcol desc print $data00 $data01 $data02 $data03 $data04 $data05 $data06 -if $data01 != 100 then +if $data00 != 100 then return -1 endi print =============== clear sql drop database $db sql show databases -if $rows != 0 then +if $rows != 2 then return -1 endi diff --git a/tests/script/general/field/tinyint.sim b/tests/script/tsim/field/tinyint.sim similarity index 93% rename from tests/script/general/field/tinyint.sim rename to tests/script/tsim/field/tinyint.sim index 7e1a0c6e80..ff24e484a7 100644 --- a/tests/script/general/field/tinyint.sim +++ b/tests/script/tsim/field/tinyint.sim @@ -1,9 +1,6 @@ system sh/stop_dnodes.sh system sh/deploy.sh -n dnode1 -i 1 -system sh/cfg.sh -n dnode1 -c walLevel -v 1 system sh/exec.sh -n dnode1 -s start - -sleep 2000 sql connect print ======================== dnode1 start @@ -145,16 +142,16 @@ if $data00 != 25 then endi print =============== step8 -sql select count(tbcol), avg(tbcol), sum(tbcol), min(tbcol), max(tbcol), first(tbcol), last(tbcol) from $mt where tbcol = 1 interval(1d) group by tgcol order by tgcol desc +sql select count(tbcol), avg(tbcol), sum(tbcol), min(tbcol), max(tbcol), first(tbcol), last(tbcol) from $mt where tbcol = 1 group by tgcol order by tgcol desc print $data00 $data01 $data02 $data03 $data04 $data05 $data06 -if $data01 != 100 then +if $data00 != 100 then return -1 endi print =============== clear sql drop database $db sql show databases -if $rows != 0 then +if $rows != 2 then return -1 endi diff --git a/tests/script/general/field/unsigined_bigint.sim b/tests/script/tsim/field/unsigined_bigint.sim similarity index 94% rename from tests/script/general/field/unsigined_bigint.sim rename to tests/script/tsim/field/unsigined_bigint.sim index 260128b5c2..d8421e7626 100644 --- a/tests/script/general/field/unsigined_bigint.sim +++ b/tests/script/tsim/field/unsigined_bigint.sim @@ -1,12 +1,9 @@ system sh/stop_dnodes.sh system sh/deploy.sh -n dnode1 -i 1 -system sh/cfg.sh -n dnode1 -c walLevel -v 1 system sh/exec.sh -n dnode1 -s start - -sleep 2000 sql connect -print ======================== dnode1 start +print ======================== dnode1 start $dbPrefix = db $tbPrefix = tb $mtPrefix = st @@ -27,7 +24,7 @@ $i = 0 while $i < 5 $tb = $tbPrefix . $i sql create table $tb using $mt tags( 0 ) - sql create table $tb using $mt tags( -111 ) + sql_error create table $tb using $mt tags( -111 ) $x = 0 while $x < $rowNum $ms = $x . m @@ -150,16 +147,16 @@ if $data00 != 25 then endi print =============== step8 -sql select count(tbcol), avg(tbcol), sum(tbcol), min(tbcol), max(tbcol), first(tbcol), last(tbcol) from $mt where tbcol = 1 interval(1d) group by tgcol order by tgcol desc +sql select count(tbcol), avg(tbcol), sum(tbcol), min(tbcol), max(tbcol), first(tbcol), last(tbcol) from $mt where tbcol = 1 group by tgcol order by tgcol desc print $data00 $data01 $data02 $data03 $data04 $data05 $data06 -if $data01 != 100 then +if $data00 != 100 then return -1 endi print =============== clear sql drop database $db sql show databases -if $rows != 0 then +if $rows != 2 then return -1 endi -- GitLab From a717042acf1da787baa793a857ef77b3f713f7c2 Mon Sep 17 00:00:00 2001 From: Liu Jicong Date: Wed, 13 Jul 2022 16:43:58 +0800 Subject: [PATCH 066/153] refactor(stream): simple batch --- include/libs/stream/tstream.h | 2 +- source/dnode/mgmt/mgmt_vnode/src/vmHandle.c | 16 ++++++++-------- source/libs/executor/src/timewindowoperator.c | 4 ++-- source/libs/stream/src/streamExec.c | 6 +++--- 4 files changed, 14 insertions(+), 14 deletions(-) diff --git a/include/libs/stream/tstream.h b/include/libs/stream/tstream.h index cae14a6d59..a08db7b8f8 100644 --- a/include/libs/stream/tstream.h +++ b/include/libs/stream/tstream.h @@ -307,7 +307,7 @@ static FORCE_INLINE int32_t streamTaskInput(SStreamTask* pTask, SStreamQueueItem atomic_store_8(&pTask->inputStatus, TASK_INPUT_STATUS__FAILED); return -1; } - qInfo("task %d %p submit enqueue %p %p %p", pTask->taskId, pTask, pItem, pSubmitClone, pSubmitClone->data); + qDebug("task %d %p submit enqueue %p %p %p", pTask->taskId, pTask, pItem, pSubmitClone, pSubmitClone->data); taosWriteQitem(pTask->inputQueue->queue, pSubmitClone); // qStreamInput(pTask->exec.executor, pSubmitClone); } else if (pItem->type == STREAM_INPUT__DATA_BLOCK || pItem->type == STREAM_INPUT__DATA_RETRIEVE) { diff --git a/source/dnode/mgmt/mgmt_vnode/src/vmHandle.c b/source/dnode/mgmt/mgmt_vnode/src/vmHandle.c index 7e7139ba53..9571a83116 100644 --- a/source/dnode/mgmt/mgmt_vnode/src/vmHandle.c +++ b/source/dnode/mgmt/mgmt_vnode/src/vmHandle.c @@ -357,16 +357,16 @@ SArray *vmGetMsgHandles() { if (dmSetMgmtHandle(pArray, TDMT_VND_COMMIT, vmPutMsgToWriteQueue, 0) == NULL) goto _OVER; if (dmSetMgmtHandle(pArray, TDMT_SCH_QUERY_HEARTBEAT, vmPutMsgToFetchQueue, 0) == NULL) goto _OVER; - if (dmSetMgmtHandle(pArray, TDMT_VND_STREAM_TRIGGER, vmPutMsgToFetchQueue, 0) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_VND_STREAM_TRIGGER, vmPutMsgToStreamQueue, 0) == NULL) goto _OVER; if (dmSetMgmtHandle(pArray, TDMT_STREAM_TASK_DROP, vmPutMsgToWriteQueue, 0) == NULL) goto _OVER; if (dmSetMgmtHandle(pArray, TDMT_STREAM_TASK_DEPLOY, vmPutMsgToWriteQueue, 0) == NULL) goto _OVER; - if (dmSetMgmtHandle(pArray, TDMT_STREAM_TASK_RUN, vmPutMsgToFetchQueue, 0) == NULL) goto _OVER; - if (dmSetMgmtHandle(pArray, TDMT_STREAM_TASK_DISPATCH, vmPutMsgToFetchQueue, 0) == NULL) goto _OVER; - if (dmSetMgmtHandle(pArray, TDMT_STREAM_TASK_DISPATCH_RSP, vmPutMsgToFetchQueue, 0) == NULL) goto _OVER; - if (dmSetMgmtHandle(pArray, TDMT_STREAM_TASK_RECOVER, vmPutMsgToFetchQueue, 0) == NULL) goto _OVER; - if (dmSetMgmtHandle(pArray, TDMT_STREAM_TASK_RECOVER_RSP, vmPutMsgToFetchQueue, 0) == NULL) goto _OVER; - if (dmSetMgmtHandle(pArray, TDMT_STREAM_RETRIEVE, vmPutMsgToFetchQueue, 0) == NULL) goto _OVER; - if (dmSetMgmtHandle(pArray, TDMT_STREAM_RETRIEVE_RSP, vmPutMsgToFetchQueue, 0) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_STREAM_TASK_RUN, vmPutMsgToStreamQueue, 0) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_STREAM_TASK_DISPATCH, vmPutMsgToStreamQueue, 0) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_STREAM_TASK_DISPATCH_RSP, vmPutMsgToStreamQueue, 0) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_STREAM_TASK_RECOVER, vmPutMsgToStreamQueue, 0) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_STREAM_TASK_RECOVER_RSP, vmPutMsgToStreamQueue, 0) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_STREAM_RETRIEVE, vmPutMsgToStreamQueue, 0) == NULL) goto _OVER; + if (dmSetMgmtHandle(pArray, TDMT_STREAM_RETRIEVE_RSP, vmPutMsgToStreamQueue, 0) == NULL) goto _OVER; if (dmSetMgmtHandle(pArray, TDMT_VND_ALTER_REPLICA, vmPutMsgToWriteQueue, 0) == NULL) goto _OVER; if (dmSetMgmtHandle(pArray, TDMT_VND_ALTER_CONFIG, vmPutMsgToWriteQueue, 0) == NULL) goto _OVER; diff --git a/source/libs/executor/src/timewindowoperator.c b/source/libs/executor/src/timewindowoperator.c index da78480d3b..773484a9b3 100644 --- a/source/libs/executor/src/timewindowoperator.c +++ b/source/libs/executor/src/timewindowoperator.c @@ -653,11 +653,11 @@ static void doInterpUnclosedTimeWindow(SOperatorInfo* pOperatorInfo, int32_t num void printDataBlock(SSDataBlock* pBlock, const char* flag) { if (pBlock == NULL) { - qInfo("======printDataBlock Block is Null"); + qDebug("======printDataBlock Block is Null"); return; } char* pBuf = NULL; - qInfo("%s", dumpBlockData(pBlock, flag, &pBuf)); + qDebug("%s", dumpBlockData(pBlock, flag, &pBuf)); taosMemoryFree(pBuf); } diff --git a/source/libs/stream/src/streamExec.c b/source/libs/stream/src/streamExec.c index 9644d9eac6..d0d81e3343 100644 --- a/source/libs/stream/src/streamExec.c +++ b/source/libs/stream/src/streamExec.c @@ -80,7 +80,7 @@ static SArray* streamExecForQall(SStreamTask* pTask, SArray* pRes) { while (1) { SStreamQueueItem* qItem = streamQueueNextItem(pTask->inputQueue); if (qItem == NULL) { - qInfo("stream exec over, queue empty"); + qDebug("stream exec over, queue empty"); break; } if (data == NULL) { @@ -101,9 +101,9 @@ static SArray* streamExecForQall(SStreamTask* pTask, SArray* pRes) { } if (data == NULL) break; - qInfo("stream task %d exec begin, batch msg: %d", pTask->taskId, cnt); + qDebug("stream task %d exec begin, batch msg: %d", pTask->taskId, cnt); streamTaskExecImpl(pTask, data, pRes); - qInfo("stream task %d exec end", pTask->taskId); + qDebug("stream task %d exec end", pTask->taskId); if (pTask->taskStatus == TASK_STATUS__DROPPING) { taosArrayDestroyEx(pRes, (FDelete)tDeleteSSDataBlock); -- GitLab From efeae69890c586d3e269e07348d9cafa21442e96 Mon Sep 17 00:00:00 2001 From: tangfangzhi Date: Wed, 13 Jul 2022 17:29:59 +0800 Subject: [PATCH 067/153] ci: explicitly exit 0 --- tests/system-test/test.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/system-test/test.py b/tests/system-test/test.py index 0a891759d0..fd0979745e 100644 --- a/tests/system-test/test.py +++ b/tests/system-test/test.py @@ -370,3 +370,4 @@ if __name__ == "__main__": tdLog.info("not need to query") if conn is not None: conn.close() + sys.exit(0) -- GitLab From 78abf57f1ad13cfd219bdfb5d78ee15bb83b7bf2 Mon Sep 17 00:00:00 2001 From: plum-lihui Date: Wed, 13 Jul 2022 17:35:34 +0800 Subject: [PATCH 068/153] test:modify case --- tests/system-test/7-tmq/tmqUpdate-1ctb.py | 2 +- tests/system-test/fulltest.sh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/system-test/7-tmq/tmqUpdate-1ctb.py b/tests/system-test/7-tmq/tmqUpdate-1ctb.py index 3cb364f91d..8513092be9 100644 --- a/tests/system-test/7-tmq/tmqUpdate-1ctb.py +++ b/tests/system-test/7-tmq/tmqUpdate-1ctb.py @@ -19,7 +19,7 @@ class TDTestCase: self.snapshot = 0 self.vgroups = 4 self.ctbNum = 1 - self.rowsPerTbl = 100000 + self.rowsPerTbl = 10000 def init(self, conn, logSql): tdLog.debug(f"start to excute {__file__}") diff --git a/tests/system-test/fulltest.sh b/tests/system-test/fulltest.sh index becb5db501..2c116113bc 100755 --- a/tests/system-test/fulltest.sh +++ b/tests/system-test/fulltest.sh @@ -148,7 +148,7 @@ python3 ./test.py -f 7-tmq/subscribeDb2.py python3 ./test.py -f 7-tmq/subscribeDb3.py #python3 ./test.py -f 7-tmq/subscribeDb4.py python3 ./test.py -f 7-tmq/subscribeStb.py -#python3 ./test.py -f 7-tmq/subscribeStb0.py +python3 ./test.py -f 7-tmq/subscribeStb0.py python3 ./test.py -f 7-tmq/subscribeStb1.py python3 ./test.py -f 7-tmq/subscribeStb2.py python3 ./test.py -f 7-tmq/subscribeStb3.py -- GitLab From 43738ca3854b28e94376a42347353b14fad169db Mon Sep 17 00:00:00 2001 From: tangfangzhi Date: Wed, 13 Jul 2022 17:36:21 +0800 Subject: [PATCH 069/153] enh: print command exit code in log --- tests/parallel_test/run_case.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/parallel_test/run_case.sh b/tests/parallel_test/run_case.sh index 9705c024b8..52a5627e34 100755 --- a/tests/parallel_test/run_case.sh +++ b/tests/parallel_test/run_case.sh @@ -65,6 +65,7 @@ ulimit -c unlimited $TIMEOUT_CMD $cmd RET=$? +echo "cmd exit code: $RET" if [ $RET -ne 0 ]; then pwd -- GitLab From dd8f235e974f476f8c99ba7ef05d5380c3c52144 Mon Sep 17 00:00:00 2001 From: Ganlin Zhao Date: Wed, 13 Jul 2022 17:47:56 +0800 Subject: [PATCH 070/153] feat(query): add count function scalar version TD-17344 --- include/libs/scalar/scalar.h | 3 +++ source/libs/function/src/builtins.c | 1 + source/libs/scalar/src/sclfunc.c | 22 ++++++++++++++++++++++ 3 files changed, 26 insertions(+) diff --git a/include/libs/scalar/scalar.h b/include/libs/scalar/scalar.h index c81c474366..dfc83e1ff0 100644 --- a/include/libs/scalar/scalar.h +++ b/include/libs/scalar/scalar.h @@ -95,6 +95,9 @@ int32_t qEndTsFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOu int32_t qTbnameFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput); +/* Aggregation functions */ +int32_t countScalarFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput); + #ifdef __cplusplus } #endif diff --git a/source/libs/function/src/builtins.c b/source/libs/function/src/builtins.c index 1ed6dcad39..af0a0261d5 100644 --- a/source/libs/function/src/builtins.c +++ b/source/libs/function/src/builtins.c @@ -1886,6 +1886,7 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = { .getEnvFunc = getCountFuncEnv, .initFunc = functionSetup, .processFunc = countFunction, + .sprocessFunc = countScalarFunction, .finalizeFunc = functionFinalize, .invertFunc = countInvertFunction, .combineFunc = combineFunction, diff --git a/source/libs/scalar/src/sclfunc.c b/source/libs/scalar/src/sclfunc.c index df5df127f0..d0cad23983 100644 --- a/source/libs/scalar/src/sclfunc.c +++ b/source/libs/scalar/src/sclfunc.c @@ -702,6 +702,7 @@ int32_t substrFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOu return TSDB_CODE_SUCCESS; } +/** Conversion functions **/ int32_t castFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput) { int16_t inputType = GET_PARAM_TYPE(&pInput[0]); int16_t inputLen = GET_PARAM_BYTES(&pInput[0]); @@ -1164,6 +1165,7 @@ int32_t toJsonFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOu return TSDB_CODE_SUCCESS; } +/** Time functions **/ int32_t timeTruncateFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput) { int32_t type = GET_PARAM_TYPE(&pInput[0]); @@ -1736,3 +1738,23 @@ int32_t qTbnameFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pO pOutput->numOfRows += pInput->numOfRows; return TSDB_CODE_SUCCESS; } + + +/** Aggregation functions **/ +int32_t countScalarFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput) { + SColumnInfoData *pInputData = pInput->columnData; + SColumnInfoData *pOutputData = pOutput->columnData; + + int64_t *out = (int64_t *)pOutputData->pData; + *out = 0; + for (int32_t i = 0; i < pInput->numOfRows; ++i) { + if (colDataIsNull_s(pInputData, i)) { + colDataAppendNULL(pOutputData, i); + break; + } + (*out)++; + } + + pOutput->numOfRows = pInput->numOfRows; + return TSDB_CODE_SUCCESS; +} -- GitLab From 312dce4e212a96c1f73eace01a7ebc8fbdd38883 Mon Sep 17 00:00:00 2001 From: "slzhou@taodata.com" Date: Wed, 13 Jul 2022 17:57:59 +0800 Subject: [PATCH 071/153] fix: reset hasGroupId after outputing the previous group results --- source/libs/executor/src/sortoperator.c | 4 +++- source/libs/executor/src/timewindowoperator.c | 3 ++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/source/libs/executor/src/sortoperator.c b/source/libs/executor/src/sortoperator.c index 8d9cac3614..9795907404 100644 --- a/source/libs/executor/src/sortoperator.c +++ b/source/libs/executor/src/sortoperator.c @@ -621,7 +621,9 @@ SSDataBlock* getMultiwaySortedBlockData(SSortHandle* pHandle, SSDataBlock* pData break; } } - + if (pInfo->groupSort) { + pInfo->hasGroupId = false; + } if (p->info.rows > 0) { // todo extract method blockDataEnsureCapacity(pDataBlock, p->info.rows); int32_t numOfCols = taosArrayGetSize(pColMatchInfo); diff --git a/source/libs/executor/src/timewindowoperator.c b/source/libs/executor/src/timewindowoperator.c index 773484a9b3..1be1488d11 100644 --- a/source/libs/executor/src/timewindowoperator.c +++ b/source/libs/executor/src/timewindowoperator.c @@ -4507,13 +4507,14 @@ static SSDataBlock* doMergeAlignedIntervalAgg(SOperatorInfo* pOperator) { setInputDataBlock(pOperator, pSup->pCtx, pBlock, iaInfo->order, scanFlag, true); doMergeAlignedIntervalAggImpl(pOperator, &iaInfo->binfo.resultRowInfo, pBlock, scanFlag, pRes); doFilter(miaInfo->pCondition, pRes); - if (pRes->info.rows > 0) { + if (pRes->info.rows >= pOperator->resultInfo.capacity) { break; } } pRes->info.groupId = miaInfo->groupId; } + miaInfo->hasGroupId = false; if (miaInfo->inputBlocksFinished) { doSetOperatorCompleted(pOperator); -- GitLab From 0ba9d225938e32eabfe6105f6700bc7bddd0ad59 Mon Sep 17 00:00:00 2001 From: Shengliang Guan Date: Wed, 13 Jul 2022 17:59:25 +0800 Subject: [PATCH 072/153] test: restore some 2.0 case --- tests/script/general/compute/testSuite.sim | 17 ---------- tests/script/jenkins/basic.txt | 20 +++++++++++ .../script/{general => tsim}/compute/avg.sim | 5 +-- .../{general => tsim}/compute/block_dist.sim | 5 +-- .../{general => tsim}/compute/bottom.sim | 5 +-- .../{general => tsim}/compute/count.sim | 5 +-- .../script/{general => tsim}/compute/diff.sim | 5 +-- .../{general => tsim}/compute/diff2.sim | 5 +-- .../{general => tsim}/compute/first.sim | 5 +-- .../{general => tsim}/compute/interval.sim | 5 +-- .../script/{general => tsim}/compute/last.sim | 5 +-- .../{general => tsim}/compute/last_row.sim | 5 +-- .../{general => tsim}/compute/leastsquare.sim | 5 +-- .../script/{general => tsim}/compute/max.sim | 5 +-- .../script/{general => tsim}/compute/min.sim | 32 ++++++++---------- .../script/{general => tsim}/compute/null.sim | 23 ++++++------- .../{general => tsim}/compute/percentile.sim | 6 +--- .../{general => tsim}/compute/stddev.sim | 17 ++++------ .../script/{general => tsim}/compute/sum.sim | 33 +++++++++---------- .../script/{general => tsim}/compute/top.sim | 29 ++++++++-------- 20 files changed, 94 insertions(+), 143 deletions(-) delete mode 100644 tests/script/general/compute/testSuite.sim rename tests/script/{general => tsim}/compute/avg.sim (96%) rename tests/script/{general => tsim}/compute/block_dist.sim (95%) rename tests/script/{general => tsim}/compute/bottom.sim (93%) rename tests/script/{general => tsim}/compute/count.sim (97%) rename tests/script/{general => tsim}/compute/diff.sim (93%) rename tests/script/{general => tsim}/compute/diff2.sim (96%) rename tests/script/{general => tsim}/compute/first.sim (96%) rename tests/script/{general => tsim}/compute/interval.sim (96%) rename tests/script/{general => tsim}/compute/last.sim (96%) rename tests/script/{general => tsim}/compute/last_row.sim (98%) rename tests/script/{general => tsim}/compute/leastsquare.sim (94%) rename tests/script/{general => tsim}/compute/max.sim (96%) rename tests/script/{general => tsim}/compute/min.sim (85%) rename tests/script/{general => tsim}/compute/null.sim (92%) rename tests/script/{general => tsim}/compute/percentile.sim (95%) rename tests/script/{general => tsim}/compute/stddev.sim (85%) rename tests/script/{general => tsim}/compute/sum.sim (83%) rename tests/script/{general => tsim}/compute/top.sim (78%) diff --git a/tests/script/general/compute/testSuite.sim b/tests/script/general/compute/testSuite.sim deleted file mode 100644 index 91bf4bf0cd..0000000000 --- a/tests/script/general/compute/testSuite.sim +++ /dev/null @@ -1,17 +0,0 @@ -run general/compute/avg.sim -run general/compute/bottom.sim -run general/compute/count.sim -run general/compute/diff.sim -run general/compute/diff2.sim -run general/compute/first.sim -run general/compute/interval.sim -run general/compute/last.sim -run general/compute/leastsquare.sim -run general/compute/max.sim -run general/compute/min.sim -run general/compute/null.sim -run general/compute/percentile.sim -run general/compute/stddev.sim -run general/compute/sum.sim -run general/compute/top.sim -run general/compute/block_dist.sim diff --git a/tests/script/jenkins/basic.txt b/tests/script/jenkins/basic.txt index 0c3126bac7..ba94743df8 100644 --- a/tests/script/jenkins/basic.txt +++ b/tests/script/jenkins/basic.txt @@ -225,6 +225,26 @@ ./test.sh -f tsim/compress/compress.sim ./test.sh -f tsim/compress/uncompress.sim +# ---- compute +#./test.sh -f tsim/compute/avg.sim +#./test.sh -f tsim/compute/block_dist.sim +#./test.sh -f tsim/compute/bottom.sim +#./test.sh -f tsim/compute/count.sim +#./test.sh -f tsim/compute/diff.sim +#./test.sh -f tsim/compute/diff2.sim +#./test.sh -f tsim/compute/first.sim +#./test.sh -f tsim/compute/interval.sim +#./test.sh -f tsim/compute/last_row.sim +#./test.sh -f tsim/compute/last.sim +#./test.sh -f tsim/compute/leastsquare.sim +#./test.sh -f tsim/compute/max.sim +#./test.sh -f tsim/compute/min.sim +#./test.sh -f tsim/compute/null.sim +./test.sh -f tsim/compute/percentile.sim +./test.sh -f tsim/compute/stddev.sim +./test.sh -f tsim/compute/sum.sim +./test.sh -f tsim/compute/top.sim + # ---- field ./test.sh -f tsim/field/2.sim ./test.sh -f tsim/field/3.sim diff --git a/tests/script/general/compute/avg.sim b/tests/script/tsim/compute/avg.sim similarity index 96% rename from tests/script/general/compute/avg.sim rename to tests/script/tsim/compute/avg.sim index db452b0344..2805b65fff 100644 --- a/tests/script/general/compute/avg.sim +++ b/tests/script/tsim/compute/avg.sim @@ -1,9 +1,6 @@ system sh/stop_dnodes.sh - system sh/deploy.sh -n dnode1 -i 1 -system sh/cfg.sh -n dnode1 -c walLevel -v 1 system sh/exec.sh -n dnode1 -s start -sleep 2000 sql connect $dbPrefix = m_av_db @@ -163,7 +160,7 @@ endi print =============== clear sql drop database $db sql show databases -if $rows != 0 then +if $rows != 2 then return -1 endi diff --git a/tests/script/general/compute/block_dist.sim b/tests/script/tsim/compute/block_dist.sim similarity index 95% rename from tests/script/general/compute/block_dist.sim rename to tests/script/tsim/compute/block_dist.sim index 5343c1db28..201d222af7 100644 --- a/tests/script/general/compute/block_dist.sim +++ b/tests/script/tsim/compute/block_dist.sim @@ -1,9 +1,6 @@ system sh/stop_dnodes.sh - system sh/deploy.sh -n dnode1 -i 1 -system sh/cfg.sh -n dnode1 -c walLevel -v 1 system sh/exec.sh -n dnode1 -s start -sleep 2000 sql connect $dbPrefix = m_di_db @@ -91,7 +88,7 @@ sql_error select _block_dist() from (select * from $mt) print =============== clear sql drop database $db sql show databases -if $rows != 0 then +if $rows != 2 then return -1 endi diff --git a/tests/script/general/compute/bottom.sim b/tests/script/tsim/compute/bottom.sim similarity index 93% rename from tests/script/general/compute/bottom.sim rename to tests/script/tsim/compute/bottom.sim index 7af67ecbf0..cfac02d6d5 100644 --- a/tests/script/general/compute/bottom.sim +++ b/tests/script/tsim/compute/bottom.sim @@ -1,9 +1,6 @@ system sh/stop_dnodes.sh - system sh/deploy.sh -n dnode1 -i 1 -system sh/cfg.sh -n dnode1 -c walLevel -v 1 system sh/exec.sh -n dnode1 -s start -sleep 2000 sql connect $dbPrefix = m_bo_db @@ -98,7 +95,7 @@ step6: print =============== clear sql drop database $db sql show databases -if $rows != 0 then +if $rows != 2 then return -1 endi diff --git a/tests/script/general/compute/count.sim b/tests/script/tsim/compute/count.sim similarity index 97% rename from tests/script/general/compute/count.sim rename to tests/script/tsim/compute/count.sim index cf84918f5b..0a6ce93077 100644 --- a/tests/script/general/compute/count.sim +++ b/tests/script/tsim/compute/count.sim @@ -1,9 +1,6 @@ system sh/stop_dnodes.sh - system sh/deploy.sh -n dnode1 -i 1 -system sh/cfg.sh -n dnode1 -c walLevel -v 1 system sh/exec.sh -n dnode1 -s start -sleep 2000 sql connect $dbPrefix = m_co_db @@ -192,7 +189,7 @@ endi print =============== clear sql drop database $db sql show databases -if $rows != 0 then +if $rows != 2 then return -1 endi diff --git a/tests/script/general/compute/diff.sim b/tests/script/tsim/compute/diff.sim similarity index 93% rename from tests/script/general/compute/diff.sim rename to tests/script/tsim/compute/diff.sim index bc303a9ca5..ba4b32ddbb 100644 --- a/tests/script/general/compute/diff.sim +++ b/tests/script/tsim/compute/diff.sim @@ -1,9 +1,6 @@ system sh/stop_dnodes.sh - system sh/deploy.sh -n dnode1 -i 1 -system sh/cfg.sh -n dnode1 -c walLevel -v 1 system sh/exec.sh -n dnode1 -s start -sleep 2000 sql connect $dbPrefix = m_di_db @@ -91,7 +88,7 @@ step6: print =============== clear sql drop database $db sql show databases -if $rows != 0 then +if $rows != 2 then return -1 endi diff --git a/tests/script/general/compute/diff2.sim b/tests/script/tsim/compute/diff2.sim similarity index 96% rename from tests/script/general/compute/diff2.sim rename to tests/script/tsim/compute/diff2.sim index 55fa1daa95..08b52cb37b 100644 --- a/tests/script/general/compute/diff2.sim +++ b/tests/script/tsim/compute/diff2.sim @@ -1,9 +1,6 @@ system sh/stop_dnodes.sh - system sh/deploy.sh -n dnode1 -i 1 -system sh/cfg.sh -n dnode1 -c walLevel -v 1 system sh/exec.sh -n dnode1 -s start -sleep 2000 sql connect $dbPrefix = m_di_db @@ -152,7 +149,7 @@ step6: print =============== clear #sql drop database $db #sql show databases -#if $rows != 0 then +#if $rows != 2 then # return -1 #endi diff --git a/tests/script/general/compute/first.sim b/tests/script/tsim/compute/first.sim similarity index 96% rename from tests/script/general/compute/first.sim rename to tests/script/tsim/compute/first.sim index fce334167b..cf1160dbdb 100644 --- a/tests/script/general/compute/first.sim +++ b/tests/script/tsim/compute/first.sim @@ -1,9 +1,6 @@ system sh/stop_dnodes.sh - system sh/deploy.sh -n dnode1 -i 1 -system sh/cfg.sh -n dnode1 -c walLevel -v 1 system sh/exec.sh -n dnode1 -s start -sleep 2000 sql connect $dbPrefix = m_fi_db @@ -165,7 +162,7 @@ endi print =============== clear sql drop database $db sql show databases -if $rows != 0 then +if $rows != 2 then return -1 endi diff --git a/tests/script/general/compute/interval.sim b/tests/script/tsim/compute/interval.sim similarity index 96% rename from tests/script/general/compute/interval.sim rename to tests/script/tsim/compute/interval.sim index c21003a646..a8539701c7 100644 --- a/tests/script/general/compute/interval.sim +++ b/tests/script/tsim/compute/interval.sim @@ -1,9 +1,6 @@ system sh/stop_dnodes.sh - system sh/deploy.sh -n dnode1 -i 1 -system sh/cfg.sh -n dnode1 -c walLevel -v 1 system sh/exec.sh -n dnode1 -s start -sleep 2000 sql connect $dbPrefix = m_in_db @@ -199,7 +196,7 @@ endi print =============== clear sql drop database $db sql show databases -if $rows != 0 then +if $rows != 2 then return -1 endi diff --git a/tests/script/general/compute/last.sim b/tests/script/tsim/compute/last.sim similarity index 96% rename from tests/script/general/compute/last.sim rename to tests/script/tsim/compute/last.sim index 9f20f8c5aa..aa9b041ca9 100644 --- a/tests/script/general/compute/last.sim +++ b/tests/script/tsim/compute/last.sim @@ -1,9 +1,6 @@ system sh/stop_dnodes.sh - system sh/deploy.sh -n dnode1 -i 1 -system sh/cfg.sh -n dnode1 -c walLevel -v 1 system sh/exec.sh -n dnode1 -s start -sleep 2000 sql connect $dbPrefix = m_la_db @@ -169,7 +166,7 @@ endi print =============== clear sql drop database $db sql show databases -if $rows != 0 then +if $rows != 2 then return -1 endi diff --git a/tests/script/general/compute/last_row.sim b/tests/script/tsim/compute/last_row.sim similarity index 98% rename from tests/script/general/compute/last_row.sim rename to tests/script/tsim/compute/last_row.sim index 3b28b0baa5..867f64fa2e 100644 --- a/tests/script/general/compute/last_row.sim +++ b/tests/script/tsim/compute/last_row.sim @@ -1,9 +1,6 @@ system sh/stop_dnodes.sh - system sh/deploy.sh -n dnode1 -i 1 -system sh/cfg.sh -n dnode1 -c walLevel -v 1 system sh/exec.sh -n dnode1 -s start -sleep 2000 sql connect $dbPrefix = m_la_db @@ -217,7 +214,7 @@ endi print =============== clear sql drop database $db sql show databases -if $rows != 0 then +if $rows != 2 then return -1 endi diff --git a/tests/script/general/compute/leastsquare.sim b/tests/script/tsim/compute/leastsquare.sim similarity index 94% rename from tests/script/general/compute/leastsquare.sim rename to tests/script/tsim/compute/leastsquare.sim index 1c8af7fe7f..aa83a4e14e 100644 --- a/tests/script/general/compute/leastsquare.sim +++ b/tests/script/tsim/compute/leastsquare.sim @@ -1,9 +1,6 @@ system sh/stop_dnodes.sh - system sh/deploy.sh -n dnode1 -i 1 -system sh/cfg.sh -n dnode1 -c walLevel -v 1 system sh/exec.sh -n dnode1 -s start -sleep 2000 sql connect $dbPrefix = m_le_db @@ -93,7 +90,7 @@ endi print =============== clear sql drop database $db sql show databases -if $rows != 0 then +if $rows != 2 then return -1 endi diff --git a/tests/script/general/compute/max.sim b/tests/script/tsim/compute/max.sim similarity index 96% rename from tests/script/general/compute/max.sim rename to tests/script/tsim/compute/max.sim index f9665a823d..1b3fac5820 100644 --- a/tests/script/general/compute/max.sim +++ b/tests/script/tsim/compute/max.sim @@ -1,9 +1,6 @@ system sh/stop_dnodes.sh - system sh/deploy.sh -n dnode1 -i 1 -system sh/cfg.sh -n dnode1 -c walLevel -v 1 system sh/exec.sh -n dnode1 -s start -sleep 2000 sql connect $dbPrefix = m_ma_db @@ -169,7 +166,7 @@ endi print =============== clear sql drop database $db sql show databases -if $rows != 0 then +if $rows != 2 then return -1 endi diff --git a/tests/script/general/compute/min.sim b/tests/script/tsim/compute/min.sim similarity index 85% rename from tests/script/general/compute/min.sim rename to tests/script/tsim/compute/min.sim index 4a9904e065..33e9eb0f3e 100644 --- a/tests/script/general/compute/min.sim +++ b/tests/script/tsim/compute/min.sim @@ -1,10 +1,6 @@ system sh/stop_dnodes.sh - system sh/deploy.sh -n dnode1 -i 1 -system sh/cfg.sh -n dnode1 -c walLevel -v 1 system sh/exec.sh -n dnode1 -s start - -sleep 2000 sql connect $dbPrefix = m_mi_db @@ -73,14 +69,14 @@ endi print =============== step5 sql select min(tbcol) as b from $tb interval(1m) -print ===> $data11 -if $data11 != 1 then +print ===> $data10 +if $data10 != 1 then return -1 endi sql select min(tbcol) as b from $tb interval(1d) -print ===> $data01 -if $data01 != 0 then +print ===> $data00 +if $data00 != 0 then return -1 endi @@ -90,8 +86,8 @@ $ms = 1601481600000 + $cc sql select min(tbcol) as b from $tb where ts <= $ms interval(1m) print select min(tbcol) as b from $tb where ts <= $ms interval(1m) -print ===> $data11 -if $data11 != 1 then +print ===> $data10 +if $data10 != 1 then return -1 endi if $rows != 5 then @@ -130,14 +126,14 @@ endi print =============== step9 sql select min(tbcol) as b from $mt interval(1m) -print ===> $data11 -if $data11 != 1 then +print ===> $data10 +if $data10 != 1 then return -1 endi sql select min(tbcol) as b from $mt interval(1d) -print ===> $data01 -if $data01 != 0 then +print ===> $data00 +if $data00 != 0 then return -1 endi @@ -155,9 +151,9 @@ endi print =============== step11 $cc = 4 * 60000 $ms = 1601481600000 + $cc -sql select min(tbcol) as b from $mt where ts <= $ms interval(1m) group by tgcol -print ===> $data11 -if $data11 != 1 then +sql select min(tbcol) as b from $mt where ts <= $ms partition by tgcol interval(1m) +print ===> $data10 +if $data10 != 1 then return -1 endi print ===> $rows @@ -168,7 +164,7 @@ endi print =============== clear sql drop database $db sql show databases -if $rows != 0 then +if $rows != 2 then return -1 endi diff --git a/tests/script/general/compute/null.sim b/tests/script/tsim/compute/null.sim similarity index 92% rename from tests/script/general/compute/null.sim rename to tests/script/tsim/compute/null.sim index cd00b7a69d..30860da48b 100644 --- a/tests/script/general/compute/null.sim +++ b/tests/script/tsim/compute/null.sim @@ -1,9 +1,6 @@ system sh/stop_dnodes.sh - system sh/deploy.sh -n dnode1 -i 1 -system sh/cfg.sh -n dnode1 -c walLevel -v 1 system sh/exec.sh -n dnode1 -s start -sleep 2000 sql connect $dbPrefix = db @@ -98,22 +95,26 @@ if $data02 != 19 then return -1 endi -sql select * from $tb where tbcol = NULL -x step3 +sql select * from $tb where tbcol is NULL +if $rows != 1 then return -1 -step3: +endi + +sql_error select * from $tb where tbcol = NULL + +return print =============== step5 -sql create table $tb using $mt tags( NULL ) -# return -1 -#step51: +sql create table tt using $mt tags( NULL ) #sql alter table $tb set tgcol=NULL -x step52 # return -1 #step52: -sql select * from $mt where tgcol = NULL -x step5 +sql select * from $mt where tgcol is NULL +if $rows != 1 then return -1 -step5: +endi print =============== step6 sql select count(tbcol), count(tbcol2), avg(tbcol), avg(tbcol2), sum(tbcol), sum(tbcol2) from $mt @@ -222,7 +223,7 @@ endi print =============== clear sql drop database $db sql show databases -if $rows != 0 then +if $rows != 2 then return -1 endi diff --git a/tests/script/general/compute/percentile.sim b/tests/script/tsim/compute/percentile.sim similarity index 95% rename from tests/script/general/compute/percentile.sim rename to tests/script/tsim/compute/percentile.sim index b0f4fff8d7..5cba3ad856 100644 --- a/tests/script/general/compute/percentile.sim +++ b/tests/script/tsim/compute/percentile.sim @@ -1,9 +1,6 @@ system sh/stop_dnodes.sh - system sh/deploy.sh -n dnode1 -i 1 -system sh/cfg.sh -n dnode1 -c walLevel -v 1 system sh/exec.sh -n dnode1 -s start -sleep 2000 sql connect $dbPrefix = m_pe_db @@ -125,11 +122,10 @@ if $data00 != 5.000000000 then return -1 endi - print =============== clear sql drop database $db sql show databases -if $rows != 0 then +if $rows != 2 then return -1 endi diff --git a/tests/script/general/compute/stddev.sim b/tests/script/tsim/compute/stddev.sim similarity index 85% rename from tests/script/general/compute/stddev.sim rename to tests/script/tsim/compute/stddev.sim index 772ec8386a..7048399112 100644 --- a/tests/script/general/compute/stddev.sim +++ b/tests/script/tsim/compute/stddev.sim @@ -1,9 +1,6 @@ system sh/stop_dnodes.sh - system sh/deploy.sh -n dnode1 -i 1 -system sh/cfg.sh -n dnode1 -c walLevel -v 1 system sh/exec.sh -n dnode1 -s start -sleep 2000 sql connect $dbPrefix = m_st_db @@ -72,14 +69,14 @@ endi print =============== step5 sql select stddev(tbcol) as b from $tb interval(1m) -print ===> $data01 -if $data01 != 0.000000000 then +print ===> $data00 +if $data00 != 0.000000000 then return -1 endi sql select stddev(tbcol) as b from $tb interval(1d) -print ===> $data01 -if $data01 != 5.766281297 then +print ===> $data00 +if $data00 != 5.766281297 then return -1 endi @@ -88,8 +85,8 @@ $cc = 4 * 60000 $ms = 1601481600000 + $cc sql select stddev(tbcol) as b from $tb where ts <= $ms interval(1m) -print ===> $data01 -if $data01 != 0.000000000 then +print ===> $data00 +if $data00 != 0.000000000 then return -1 endi if $rows != 5 then @@ -99,7 +96,7 @@ endi print =============== clear sql drop database $db sql show databases -if $rows != 0 then +if $rows != 2 then return -1 endi diff --git a/tests/script/general/compute/sum.sim b/tests/script/tsim/compute/sum.sim similarity index 83% rename from tests/script/general/compute/sum.sim rename to tests/script/tsim/compute/sum.sim index 8fad992750..d4185f3204 100644 --- a/tests/script/general/compute/sum.sim +++ b/tests/script/tsim/compute/sum.sim @@ -1,9 +1,6 @@ system sh/stop_dnodes.sh - system sh/deploy.sh -n dnode1 -i 1 -system sh/cfg.sh -n dnode1 -c walLevel -v 1 system sh/exec.sh -n dnode1 -s start -sleep 2000 sql connect $dbPrefix = m_su_db @@ -72,14 +69,14 @@ endi print =============== step5 sql select sum(tbcol) as b from $tb interval(1m) -print ===> $data11 -if $data11 != 1 then +print ===> $data10 +if $data10 != 1 then return -1 endi sql select sum(tbcol) as b from $tb interval(1d) -print ===> $data01 -if $data01 != 190 then +print ===> $data00 +if $data00 != 190 then return -1 endi @@ -88,8 +85,8 @@ $cc = 4 * 60000 $ms = 1601481600000 + $cc sql select sum(tbcol) as b from $tb where ts <= $ms interval(1m) -print ===> $data11 -if $data11 != 1 then +print ===> $data10 +if $data10 != 1 then return -1 endi if $rows != 5 then @@ -130,14 +127,14 @@ endi print =============== step9 sql select sum(tbcol) as b from $mt interval(1m) -print ===> $data11 -if $data11 < 5 then +print ===> $data10 +if $data10 < 5 then return -1 endi sql select sum(tbcol) as b from $mt interval(1d) -print ===> $data01 -if $data01 != 1900 then +print ===> $data00 +if $data00 != 1900 then return -1 endi @@ -156,10 +153,10 @@ print =============== step11 $cc = 4 * 60000 $ms = 1601481600000 + $cc -sql select sum(tbcol) as b from $mt where ts <= $ms interval(1d) group by tgcol -print select sum(tbcol) as b from $mt where ts <= $ms interval(1d) group by tgcol -print ===> $data01 -if $data01 != 10 then +sql select sum(tbcol) as b from $mt where ts <= $ms group by tgcol +print select sum(tbcol) as b from $mt where ts <= $ms group by tgcol +print ===> $data00 +if $data00 != 10 then return -1 endi if $rows != 10 then @@ -169,7 +166,7 @@ endi print =============== clear sql drop database $db sql show databases -if $rows != 0 then +if $rows != 2 then return -1 endi diff --git a/tests/script/general/compute/top.sim b/tests/script/tsim/compute/top.sim similarity index 78% rename from tests/script/general/compute/top.sim rename to tests/script/tsim/compute/top.sim index 1e9d302b7c..9899a8a9ea 100644 --- a/tests/script/general/compute/top.sim +++ b/tests/script/tsim/compute/top.sim @@ -1,9 +1,6 @@ system sh/stop_dnodes.sh - system sh/deploy.sh -n dnode1 -i 1 -system sh/cfg.sh -n dnode1 -c walLevel -v 1 system sh/exec.sh -n dnode1 -s start -sleep 2000 sql connect $dbPrefix = m_to_db @@ -48,8 +45,8 @@ $i = 1 $tb = $tbPrefix . $i sql select top(tbcol, 1) from $tb -print ===> $data01 -if $data01 != 19 then +print ===> $data00 +if $data00 != 19 then return -1 endi @@ -58,25 +55,25 @@ $cc = 4 * 60000 $ms = 1601481600000 + $cc sql select top(tbcol, 1) from $tb where ts <= $ms -print ===> $data01 -if $data01 != 4 then +print ===> $data00 +if $data00 != 4 then return -1 endi print =============== step4 sql select top(tbcol, 1) as b from $tb -print ===> $data01 -if $data01 != 19 then +print ===> $data00 +if $data00 != 19 then return -1 endi print =============== step5 sql select top(tbcol, 2) as b from $tb -print ===> $data01 $data11 -if $data01 != 18 then +print ===> $data00 $data10 +if $data00 != 18 then return -1 endi -if $data11 != 19 then +if $data10 != 19 then return -1 endi @@ -85,11 +82,11 @@ $cc = 4 * 60000 $ms = 1601481600000 + $cc sql select top(tbcol, 2) as b from $tb where ts <= $ms -print ===> $data01 $data11 -if $data01 != 3 then +print ===> $data00 $data10 +if $data00 != 3 then return -1 endi -if $data11 != 4 then +if $data10 != 4 then return -1 endi @@ -100,7 +97,7 @@ step6: print =============== clear sql drop database $db sql show databases -if $rows != 0 then +if $rows != 2 then return -1 endi -- GitLab From caa06f938ab36be29dd727dcfec245691f74e45e Mon Sep 17 00:00:00 2001 From: 54liuyao <54liuyao@163.com> Date: Wed, 13 Jul 2022 18:09:14 +0800 Subject: [PATCH 073/153] ci(stream): stream sliding --- tests/script/tsim/stream/sliding.sim | 243 +++++++++++++++++++++++++++ 1 file changed, 243 insertions(+) create mode 100644 tests/script/tsim/stream/sliding.sim diff --git a/tests/script/tsim/stream/sliding.sim b/tests/script/tsim/stream/sliding.sim new file mode 100644 index 0000000000..750be7cb49 --- /dev/null +++ b/tests/script/tsim/stream/sliding.sim @@ -0,0 +1,243 @@ +system sh/stop_dnodes.sh +system sh/deploy.sh -n dnode1 -i 1 +system sh/exec.sh -n dnode1 -s start +sleep 50 +sql connect + +print =============== create database +sql create database test vgroups 1 +sql show databases +if $rows != 3 then + return -1 +endi + +print $data00 $data01 $data02 + +sql use test +sql create stable st(ts timestamp, a int, b int, c int, d double) tags(ta int,tb int,tc int); +sql create table t1 using st tags(1,1,1); +sql create table t2 using st tags(2,2,2); +sql create stream streams1 trigger at_once into streamt as select _wstartts, count(*) c1, sum(a) c3 , max(b) c4, min(c) c5 from t1 interval(10s) sliding (5s); +sql create stream streams2 trigger at_once watermark 1d into streamt2 as select _wstartts, count(*) c1, sum(a) c3 , max(b) c4, min(c) c5 from t1 interval(10s) sliding (5s); +sql create stream stream_t1 trigger at_once into streamtST as select _wstartts, count(*) c1, sum(a) c3 , max(b) c4, min(c) c5 from st interval(10s) sliding (5s); +sql create stream stream_t2 trigger at_once watermark 1d into streamtST2 as select _wstartts, count(*) c1, sum(a) c3 , max(b) c4, min(c) c5 from st interval(10s) sliding (5s); + +sql insert into t1 values(1648791210000,1,2,3,1.0); +sql insert into t1 values(1648791216000,2,2,3,1.1); +sql insert into t1 values(1648791220000,3,2,3,2.1); + +sql insert into t1 values(1648791210000,1,2,3,1.0); +sql insert into t1 values(1648791216000,2,2,3,1.1); +sql insert into t1 values(1648791220000,3,2,3,2.1); + +sql insert into t2 values(1648791210000,1,2,3,1.0); +sql insert into t2 values(1648791216000,2,2,3,1.1); +sql insert into t2 values(1648791220000,3,2,3,2.1); + +sql insert into t2 values(1648791210000,1,2,3,1.0); +sql insert into t2 values(1648791216000,2,2,3,1.1); +sql insert into t2 values(1648791220000,3,2,3,2.1); + +$loop_count = 0 + +loop0: +sleep 300 + +$loop_count = $loop_count + 1 +if $loop_count == 10 then + return -1 +endi + + +sql select * from streamt + +# row 0 +if $data01 != 1 then + print =====data01=$data01 + goto loop0 +endi + +if $data02 != 1 then + print =====data02=$data02 + goto loop0 +endi + +# row 1 +if $data11 != 2 then + print =====data11=$data11 + goto loop0 +endi + +if $data12 != 3 then + print =====data12=$data12 + goto loop0 +endi + +# row 2 +if $data21 != 2 then + print =====data21=$data21 + goto loop0 +endi + +if $data22 != 5 then + print =====data22=$data22 + goto loop0 +endi + +# row 3 +if $data31 != 1 then + print =====data31=$data31 + goto loop0 +endi + +if $data32 != 3 then + print =====data32=$data32 + goto loop0 +endi + +print step 1 + +sql select * from streamt2 + +# row 0 +if $data01 != 1 then + print =====data01=$data01 + goto loop0 +endi + +if $data02 != 1 then + print =====data02=$data02 + goto loop0 +endi + +# row 1 +if $data11 != 2 then + print =====data11=$data11 + goto loop0 +endi + +if $data12 != 3 then + print =====data12=$data12 + goto loop0 +endi + +# row 2 +if $data21 != 2 then + print =====data21=$data21 + goto loop0 +endi + +if $data22 != 5 then + print =====data22=$data22 + goto loop0 +endi + +# row 3 +if $data31 != 1 then + print =====data31=$data31 + goto loop0 +endi + +if $data32 != 3 then + print =====data32=$data32 + goto loop0 +endi + +print step 2 + +sql select * from streamtST + +# row 0 +if $data01 != 2 then + print =====data01=$data01 + goto loop0 +endi + +if $data02 != 2 then + print =====data02=$data02 + goto loop0 +endi + +# row 1 +if $data11 != 4 then + print =====data11=$data11 + goto loop0 +endi + +if $data12 != 6 then + print =====data12=$data12 + goto loop0 +endi + +# row 2 +if $data21 != 4 then + print =====data21=$data21 + goto loop0 +endi + +if $data22 != 10 then + print =====data22=$data22 + goto loop0 +endi + +# row 3 +if $data31 != 2 then + print =====data31=$data31 + goto loop0 +endi + +if $data32 != 6 then + print =====data32=$data32 + goto loop0 +endi + +print step 3 + +sql select * from streamtST2 + +# row 0 +if $data01 != 2 then + print =====data01=$data01 + goto loop0 +endi + +if $data02 != 2 then + print =====data02=$data02 + goto loop0 +endi + +# row 1 +if $data11 != 4 then + print =====data11=$data11 + goto loop0 +endi + +if $data12 != 6 then + print =====data12=$data12 + goto loop0 +endi + +# row 2 +if $data21 != 4 then + print =====data21=$data21 + goto loop0 +endi + +if $data22 != 10 then + print =====data22=$data22 + goto loop0 +endi + +# row 3 +if $data31 != 2 then + print =====data31=$data31 + goto loop0 +endi + +if $data32 != 6 then + print =====data32=$data32 + goto loop0 +endi + + +system sh/stop_dnodes.sh \ No newline at end of file -- GitLab From 4830b7d9d3c5b7ceec3d4f8e8270889f9b74b87d Mon Sep 17 00:00:00 2001 From: Xiaoyu Wang Date: Wed, 13 Jul 2022 18:12:02 +0800 Subject: [PATCH 074/153] feat: support pseudo columns such as _qstart, _qend and _qduration --- include/libs/function/functionMgt.h | 1 + include/libs/nodes/querynodes.h | 1 + source/libs/function/inc/functionMgtInt.h | 1 + source/libs/function/src/builtins.c | 18 ++-- source/libs/function/src/functionMgt.c | 2 + source/libs/nodes/src/nodesCloneFuncs.c | 1 + source/libs/nodes/src/nodesCodeFuncs.c | 7 ++ source/libs/nodes/src/nodesUtilFuncs.c | 5 + source/libs/parser/src/parAstCreater.c | 1 + source/libs/parser/src/parTranslater.c | 101 +++++++++++++++++---- source/libs/planner/test/planBasicTest.cpp | 5 + 11 files changed, 115 insertions(+), 28 deletions(-) diff --git a/include/libs/function/functionMgt.h b/include/libs/function/functionMgt.h index 6af7fca10f..04825f376f 100644 --- a/include/libs/function/functionMgt.h +++ b/include/libs/function/functionMgt.h @@ -198,6 +198,7 @@ bool fmIsInterpFunc(int32_t funcId); bool fmIsLastRowFunc(int32_t funcId); bool fmIsSystemInfoFunc(int32_t funcId); bool fmIsImplicitTsFunc(int32_t funcId); +bool fmIsClientPseudoColumnFunc(int32_t funcId); int32_t fmGetDistMethod(const SFunctionNode* pFunc, SFunctionNode** pPartialFunc, SFunctionNode** pMergeFunc); diff --git a/include/libs/nodes/querynodes.h b/include/libs/nodes/querynodes.h index 49db69c7c7..234b554526 100644 --- a/include/libs/nodes/querynodes.h +++ b/include/libs/nodes/querynodes.h @@ -248,6 +248,7 @@ typedef struct SSelectStmt { SNodeList* pOrderByList; // SOrderByExprNode SLimitNode* pLimit; SLimitNode* pSlimit; + STimeWindow timeRange; char stmtName[TSDB_TABLE_NAME_LEN]; uint8_t precision; int32_t selectFuncNum; diff --git a/source/libs/function/inc/functionMgtInt.h b/source/libs/function/inc/functionMgtInt.h index 2fcddce5eb..da5dd0433d 100644 --- a/source/libs/function/inc/functionMgtInt.h +++ b/source/libs/function/inc/functionMgtInt.h @@ -47,6 +47,7 @@ extern "C" { #define FUNC_MGT_FORBID_WINDOW_FUNC FUNC_MGT_FUNC_CLASSIFICATION_MASK(18) #define FUNC_MGT_FORBID_GROUP_BY_FUNC FUNC_MGT_FUNC_CLASSIFICATION_MASK(19) #define FUNC_MGT_SYSTEM_INFO_FUNC FUNC_MGT_FUNC_CLASSIFICATION_MASK(20) +#define FUNC_MGT_CLIENT_PC_FUNC FUNC_MGT_FUNC_CLASSIFICATION_MASK(21) #define FUNC_MGT_TEST_MASK(val, mask) (((val) & (mask)) != 0) diff --git a/source/libs/function/src/builtins.c b/source/libs/function/src/builtins.c index 972ce2396b..5feb142757 100644 --- a/source/libs/function/src/builtins.c +++ b/source/libs/function/src/builtins.c @@ -2786,31 +2786,31 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = { { .name = "_qstart", .type = FUNCTION_TYPE_QSTART, - .classification = FUNC_MGT_PSEUDO_COLUMN_FUNC | FUNC_MGT_SCAN_PC_FUNC, + .classification = FUNC_MGT_PSEUDO_COLUMN_FUNC | FUNC_MGT_CLIENT_PC_FUNC, .translateFunc = translateTimePseudoColumn, - .getEnvFunc = getTimePseudoFuncEnv, + .getEnvFunc = NULL, .initFunc = NULL, - .sprocessFunc = qStartTsFunction, // todo + .sprocessFunc = NULL, .finalizeFunc = NULL }, { .name = "_qend", .type = FUNCTION_TYPE_QEND, - .classification = FUNC_MGT_PSEUDO_COLUMN_FUNC | FUNC_MGT_SCAN_PC_FUNC, + .classification = FUNC_MGT_PSEUDO_COLUMN_FUNC | FUNC_MGT_CLIENT_PC_FUNC, .translateFunc = translateTimePseudoColumn, - .getEnvFunc = getTimePseudoFuncEnv, + .getEnvFunc = NULL, .initFunc = NULL, - .sprocessFunc = qEndTsFunction, // todo + .sprocessFunc = NULL, .finalizeFunc = NULL }, { .name = "_qduration", .type = FUNCTION_TYPE_QDURATION, - .classification = FUNC_MGT_PSEUDO_COLUMN_FUNC | FUNC_MGT_SCAN_PC_FUNC, + .classification = FUNC_MGT_PSEUDO_COLUMN_FUNC | FUNC_MGT_CLIENT_PC_FUNC, .translateFunc = translateWduration, - .getEnvFunc = getTimePseudoFuncEnv, + .getEnvFunc = NULL, .initFunc = NULL, - .sprocessFunc = winDurFunction, // todo + .sprocessFunc = NULL, .finalizeFunc = NULL }, { diff --git a/source/libs/function/src/functionMgt.c b/source/libs/function/src/functionMgt.c index c003f917b5..f73a61fa60 100644 --- a/source/libs/function/src/functionMgt.c +++ b/source/libs/function/src/functionMgt.c @@ -183,6 +183,8 @@ bool fmIsSystemInfoFunc(int32_t funcId) { return isSpecificClassifyFunc(funcId, bool fmIsImplicitTsFunc(int32_t funcId) { return isSpecificClassifyFunc(funcId, FUNC_MGT_IMPLICIT_TS_FUNC); } +bool fmIsClientPseudoColumnFunc(int32_t funcId) { return isSpecificClassifyFunc(funcId, FUNC_MGT_CLIENT_PC_FUNC); } + bool fmIsInterpFunc(int32_t funcId) { if (funcId < 0 || funcId >= funcMgtBuiltinsNum) { return false; diff --git a/source/libs/nodes/src/nodesCloneFuncs.c b/source/libs/nodes/src/nodesCloneFuncs.c index 6c0717e845..e7109b5a87 100644 --- a/source/libs/nodes/src/nodesCloneFuncs.c +++ b/source/libs/nodes/src/nodesCloneFuncs.c @@ -127,6 +127,7 @@ static int32_t valueNodeCopy(const SValueNode* pSrc, SValueNode* pDst) { COPY_SCALAR_FIELD(isDuration); COPY_SCALAR_FIELD(translate); COPY_SCALAR_FIELD(notReserved); + COPY_SCALAR_FIELD(isNull); COPY_SCALAR_FIELD(placeholderNo); COPY_SCALAR_FIELD(typeData); COPY_SCALAR_FIELD(unit); diff --git a/source/libs/nodes/src/nodesCodeFuncs.c b/source/libs/nodes/src/nodesCodeFuncs.c index 3c285cc7f1..75f9cd7b48 100644 --- a/source/libs/nodes/src/nodesCodeFuncs.c +++ b/source/libs/nodes/src/nodesCodeFuncs.c @@ -2712,6 +2712,7 @@ static const char* jkValueLiteral = "Literal"; static const char* jkValueDuration = "Duration"; static const char* jkValueTranslate = "Translate"; static const char* jkValueNotReserved = "NotReserved"; +static const char* jkValueIsNull = "IsNull"; static const char* jkValueDatum = "Datum"; static int32_t datumToJson(const void* pObj, SJson* pJson) { @@ -2798,6 +2799,9 @@ static int32_t valueNodeToJson(const void* pObj, SJson* pJson) { if (TSDB_CODE_SUCCESS == code) { code = tjsonAddBoolToObject(pJson, jkValueNotReserved, pNode->notReserved); } + if (TSDB_CODE_SUCCESS == code) { + code = tjsonAddBoolToObject(pJson, jkValueIsNull, pNode->isNull); + } if (TSDB_CODE_SUCCESS == code && pNode->translate) { code = datumToJson(pNode, pJson); } @@ -2945,6 +2949,9 @@ static int32_t jsonToValueNode(const SJson* pJson, void* pObj) { if (TSDB_CODE_SUCCESS == code) { code = tjsonGetBoolValue(pJson, jkValueNotReserved, &pNode->notReserved); } + if (TSDB_CODE_SUCCESS == code) { + code = tjsonGetBoolValue(pJson, jkValueIsNull, &pNode->isNull); + } if (TSDB_CODE_SUCCESS == code && pNode->translate) { code = jsonToDatum(pJson, pNode); } diff --git a/source/libs/nodes/src/nodesUtilFuncs.c b/source/libs/nodes/src/nodesUtilFuncs.c index 9b754c92d0..051cdf9a94 100644 --- a/source/libs/nodes/src/nodesUtilFuncs.c +++ b/source/libs/nodes/src/nodesUtilFuncs.c @@ -1692,6 +1692,11 @@ int32_t nodesGetOutputNumFromSlotList(SNodeList* pSlots) { } void nodesValueNodeToVariant(const SValueNode* pNode, SVariant* pVal) { + if (pNode->isNull) { + pVal->nType = TSDB_DATA_TYPE_NULL; + pVal->nLen = tDataTypes[TSDB_DATA_TYPE_NULL].bytes; + return; + } pVal->nType = pNode->node.resType.type; pVal->nLen = pNode->node.resType.bytes; switch (pNode->node.resType.type) { diff --git a/source/libs/parser/src/parAstCreater.c b/source/libs/parser/src/parAstCreater.c index ca0ab7f42e..a7806f5e34 100644 --- a/source/libs/parser/src/parAstCreater.c +++ b/source/libs/parser/src/parAstCreater.c @@ -740,6 +740,7 @@ SNode* createSelectStmt(SAstCreateContext* pCxt, bool isDistinct, SNodeList* pPr select->pFromTable = pTable; sprintf(select->stmtName, "%p", select); select->isTimeLineResult = true; + select->timeRange = TSWINDOW_INITIALIZER; return (SNode*)select; } diff --git a/source/libs/parser/src/parTranslater.c b/source/libs/parser/src/parTranslater.c index 6b7bf3af26..ec8aadf827 100644 --- a/source/libs/parser/src/parTranslater.c +++ b/source/libs/parser/src/parTranslater.c @@ -1198,7 +1198,7 @@ static void setFuncClassification(SNode* pCurrStmt, SFunctionNode* pFunc) { } } -static int32_t rewriteSystemInfoFuncImpl(STranslateContext* pCxt, char* pLiteral, SNode** pNode) { +static int32_t rewriteFuncToValue(STranslateContext* pCxt, char* pLiteral, SNode** pNode) { SValueNode* pVal = (SValueNode*)nodesMakeNode(QUERY_NODE_VALUE); if (NULL == pVal) { return TSDB_CODE_OUT_OF_MEMORY; @@ -1229,7 +1229,7 @@ static int32_t rewriteDatabaseFunc(STranslateContext* pCxt, SNode** pNode) { return TSDB_CODE_OUT_OF_MEMORY; } } - return rewriteSystemInfoFuncImpl(pCxt, pCurrDb, pNode); + return rewriteFuncToValue(pCxt, pCurrDb, pNode); } static int32_t rewriteClentVersionFunc(STranslateContext* pCxt, SNode** pNode) { @@ -1237,7 +1237,7 @@ static int32_t rewriteClentVersionFunc(STranslateContext* pCxt, SNode** pNode) { if (NULL == pVer) { return TSDB_CODE_OUT_OF_MEMORY; } - return rewriteSystemInfoFuncImpl(pCxt, pVer, pNode); + return rewriteFuncToValue(pCxt, pVer, pNode); } static int32_t rewriteServerVersionFunc(STranslateContext* pCxt, SNode** pNode) { @@ -1245,7 +1245,7 @@ static int32_t rewriteServerVersionFunc(STranslateContext* pCxt, SNode** pNode) if (NULL == pVer) { return TSDB_CODE_OUT_OF_MEMORY; } - return rewriteSystemInfoFuncImpl(pCxt, pVer, pNode); + return rewriteFuncToValue(pCxt, pVer, pNode); } static int32_t rewriteServerStatusFunc(STranslateContext* pCxt, SNode** pNode) { @@ -1253,7 +1253,7 @@ static int32_t rewriteServerStatusFunc(STranslateContext* pCxt, SNode** pNode) { return TSDB_CODE_RPC_NETWORK_UNAVAIL; } char* pStatus = taosMemoryStrDup((void*)"1"); - return rewriteSystemInfoFuncImpl(pCxt, pStatus, pNode); + return rewriteFuncToValue(pCxt, pStatus, pNode); } static int32_t rewriteUserFunc(STranslateContext* pCxt, SNode** pNode) { @@ -1264,7 +1264,7 @@ static int32_t rewriteUserFunc(STranslateContext* pCxt, SNode** pNode) { if (NULL == pUserConn) { return TSDB_CODE_OUT_OF_MEMORY; } - return rewriteSystemInfoFuncImpl(pCxt, pUserConn, pNode); + return rewriteFuncToValue(pCxt, pUserConn, pNode); } static int32_t rewriteSystemInfoFunc(STranslateContext* pCxt, SNode** pNode) { @@ -1318,10 +1318,60 @@ static int32_t translateNoramlFunction(STranslateContext* pCxt, SFunctionNode* p return code; } +static int32_t rewriteQueryTimeFunc(STranslateContext* pCxt, int64_t val, SNode** pNode) { + if (INT64_MIN == val || INT64_MAX == val) { + return rewriteFuncToValue(pCxt, NULL, pNode); + } + + char* pStr = taosMemoryCalloc(1, 20); + if (NULL == pStr) { + return TSDB_CODE_OUT_OF_MEMORY; + } + snprintf(pStr, 20, "%" PRId64 "", val); + return rewriteFuncToValue(pCxt, pStr, pNode); +} + +static int32_t rewriteQstartFunc(STranslateContext* pCxt, SNode** pNode) { + return rewriteQueryTimeFunc(pCxt, ((SSelectStmt*)pCxt->pCurrStmt)->timeRange.skey, pNode); +} + +static int32_t rewriteQendFunc(STranslateContext* pCxt, SNode** pNode) { + return rewriteQueryTimeFunc(pCxt, ((SSelectStmt*)pCxt->pCurrStmt)->timeRange.ekey, pNode); +} + +static int32_t rewriteQdurationFunc(STranslateContext* pCxt, SNode** pNode) { + STimeWindow range = ((SSelectStmt*)pCxt->pCurrStmt)->timeRange; + if (INT64_MIN == range.skey || INT64_MAX == range.ekey) { + return rewriteQueryTimeFunc(pCxt, INT64_MIN, pNode); + } + return rewriteQueryTimeFunc(pCxt, range.ekey - range.skey + 1, pNode); +} + +static int32_t rewriteClientPseudoColumnFunc(STranslateContext* pCxt, SNode** pNode) { + if (NULL == pCxt->pCurrStmt || QUERY_NODE_SELECT_STMT != nodeType(pCxt->pCurrStmt) || + pCxt->currClause <= SQL_CLAUSE_WHERE) { + return generateSyntaxErrMsgExt(&pCxt->msgBuf, TSDB_CODE_PAR_NOT_ALLOWED_FUNC, "Illegal pseudo column"); + } + switch (((SFunctionNode*)*pNode)->funcType) { + case FUNCTION_TYPE_QSTART: + return rewriteQstartFunc(pCxt, pNode); + case FUNCTION_TYPE_QEND: + return rewriteQendFunc(pCxt, pNode); + case FUNCTION_TYPE_QDURATION: + return rewriteQdurationFunc(pCxt, pNode); + default: + break; + } + return TSDB_CODE_PAR_INTERNAL_ERROR; +} + static int32_t translateFunctionImpl(STranslateContext* pCxt, SFunctionNode** pFunc) { if (fmIsSystemInfoFunc((*pFunc)->funcId)) { return rewriteSystemInfoFunc(pCxt, (SNode**)pFunc); } + if (fmIsClientPseudoColumnFunc((*pFunc)->funcId)) { + return rewriteClientPseudoColumnFunc(pCxt, (SNode**)pFunc); + } return translateNoramlFunction(pCxt, *pFunc); } @@ -2078,7 +2128,7 @@ static int32_t getTimeRange(SNode** pPrimaryKeyCond, STimeWindow* pTimeRange, bo return code; } -static int32_t getFillTimeRange(STranslateContext* pCxt, SNode* pWhere, STimeWindow* pTimeRange) { +static int32_t getQueryTimeRange(STranslateContext* pCxt, SNode* pWhere, STimeWindow* pTimeRange) { if (NULL == pWhere) { *pTimeRange = TSWINDOW_INITIALIZER; return TSDB_CODE_SUCCESS; @@ -2139,16 +2189,13 @@ static int32_t checkFill(STranslateContext* pCxt, SFillNode* pFill, SValueNode* return TSDB_CODE_SUCCESS; } -static int32_t translateFill(STranslateContext* pCxt, SNode* pWhere, SIntervalWindowNode* pInterval) { +static int32_t translateFill(STranslateContext* pCxt, SSelectStmt* pSelect, SIntervalWindowNode* pInterval) { if (NULL == pInterval->pFill) { return TSDB_CODE_SUCCESS; } - int32_t code = getFillTimeRange(pCxt, pWhere, &(((SFillNode*)pInterval->pFill)->timeRange)); - if (TSDB_CODE_SUCCESS == code) { - code = checkFill(pCxt, (SFillNode*)pInterval->pFill, (SValueNode*)pInterval->pInterval); - } - return code; + ((SFillNode*)pInterval->pFill)->timeRange = pSelect->timeRange; + return checkFill(pCxt, (SFillNode*)pInterval->pFill, (SValueNode*)pInterval->pInterval); } static int64_t getMonthsFromTimeVal(int64_t val, int32_t fromPrecision, char unit) { @@ -2235,7 +2282,7 @@ static int32_t checkIntervalWindow(STranslateContext* pCxt, SIntervalWindowNode* static int32_t translateIntervalWindow(STranslateContext* pCxt, SSelectStmt* pSelect, SIntervalWindowNode* pInterval) { int32_t code = checkIntervalWindow(pCxt, pInterval); if (TSDB_CODE_SUCCESS == code) { - code = translateFill(pCxt, pSelect->pWhere, pInterval); + code = translateFill(pCxt, pSelect, pInterval); } return code; } @@ -2330,7 +2377,7 @@ static int32_t translateInterpFill(STranslateContext* pCxt, SSelectStmt* pSelect code = translateExpr(pCxt, &pSelect->pFill); } if (TSDB_CODE_SUCCESS == code) { - code = getFillTimeRange(pCxt, pSelect->pRange, &(((SFillNode*)pSelect->pFill)->timeRange)); + code = getQueryTimeRange(pCxt, pSelect->pRange, &(((SFillNode*)pSelect->pFill)->timeRange)); } if (TSDB_CODE_SUCCESS == code) { code = checkFill(pCxt, (SFillNode*)pSelect->pFill, (SValueNode*)pSelect->pEvery); @@ -2362,9 +2409,24 @@ static int32_t translatePartitionBy(STranslateContext* pCxt, SNodeList* pPartiti return translateExprList(pCxt, pPartitionByList); } -static int32_t translateWhere(STranslateContext* pCxt, SNode** pWhere) { +static bool isDataTable(int8_t tableType) { + return TSDB_SUPER_TABLE == tableType || TSDB_CHILD_TABLE == tableType || TSDB_NORMAL_TABLE == tableType; +} + +static bool needCalcTimeRange(SSelectStmt* pSelect) { + if (QUERY_NODE_REAL_TABLE != nodeType(pSelect->pFromTable)) { + return false; + } + return isDataTable(((SRealTableNode*)pSelect->pFromTable)->pMeta->tableType); +} + +static int32_t translateWhere(STranslateContext* pCxt, SSelectStmt* pSelect) { pCxt->currClause = SQL_CLAUSE_WHERE; - return translateExpr(pCxt, pWhere); + int32_t code = translateExpr(pCxt, &pSelect->pWhere); + if (TSDB_CODE_SUCCESS == code && needCalcTimeRange(pSelect)) { + code = getQueryTimeRange(pCxt, pSelect->pWhere, &pSelect->timeRange); + } + return code; } static int32_t translateFrom(STranslateContext* pCxt, SNode* pTable) { @@ -2495,7 +2557,7 @@ static int32_t translateSelectFrom(STranslateContext* pCxt, SSelectStmt* pSelect int32_t code = translateFrom(pCxt, pSelect->pFromTable); if (TSDB_CODE_SUCCESS == code) { pSelect->precision = ((STableNode*)pSelect->pFromTable)->precision; - code = translateWhere(pCxt, &pSelect->pWhere); + code = translateWhere(pCxt, pSelect); } if (TSDB_CODE_SUCCESS == code) { code = translatePartitionBy(pCxt, pSelect->pPartitionByList); @@ -2681,7 +2743,8 @@ static int32_t partitionDeleteWhere(STranslateContext* pCxt, SDeleteStmt* pDelet } static int32_t translateDeleteWhere(STranslateContext* pCxt, SDeleteStmt* pDelete) { - int32_t code = translateWhere(pCxt, &pDelete->pWhere); + pCxt->currClause = SQL_CLAUSE_WHERE; + int32_t code = translateExpr(pCxt, &pDelete->pWhere); if (TSDB_CODE_SUCCESS == code) { code = partitionDeleteWhere(pCxt, pDelete); } diff --git a/source/libs/planner/test/planBasicTest.cpp b/source/libs/planner/test/planBasicTest.cpp index 2379ea262a..0d6bab145a 100644 --- a/source/libs/planner/test/planBasicTest.cpp +++ b/source/libs/planner/test/planBasicTest.cpp @@ -141,6 +141,11 @@ TEST_F(PlanBasicTest, pseudoColumn) { useDb("root", "test"); run("SELECT _QSTART, _QEND, _QDURATION FROM t1"); + + run("SELECT _QSTART, _QEND, _QDURATION FROM t1 WHERE ts BETWEEN '2017-7-14 18:00:00' AND '2017-7-14 19:00:00'"); + + run("SELECT _QSTART, _QEND, _QDURATION, _WSTART, _WEND, _WDURATION, COUNT(*) FROM t1 " + "WHERE ts BETWEEN '2017-7-14 18:00:00' AND '2017-7-14 19:00:00' INTERVAL(10S)"); } TEST_F(PlanBasicTest, withoutFrom) { -- GitLab From 099f2d2c98b75326cf631b03c0262e4c78263557 Mon Sep 17 00:00:00 2001 From: Ganlin Zhao Date: Wed, 13 Jul 2022 18:14:27 +0800 Subject: [PATCH 075/153] remove scalar function check to allow agg function execute --- source/libs/scalar/src/scalar.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/source/libs/scalar/src/scalar.c b/source/libs/scalar/src/scalar.c index e610fcb62e..00b4dadc46 100644 --- a/source/libs/scalar/src/scalar.c +++ b/source/libs/scalar/src/scalar.c @@ -700,9 +700,9 @@ EDealRes sclRewriteNonConstOperator(SNode** pNode, SScalarCtx *ctx) { EDealRes sclRewriteFunction(SNode** pNode, SScalarCtx *ctx) { SFunctionNode *node = (SFunctionNode *)*pNode; SNode* tnode = NULL; - if (!fmIsScalarFunc(node->funcId)) { - return DEAL_RES_CONTINUE; - } + //if (!fmIsScalarFunc(node->funcId)) { + // return DEAL_RES_CONTINUE; + //} FOREACH(tnode, node->pParameterList) { if (!SCL_IS_CONST_NODE(tnode)) { @@ -728,8 +728,9 @@ EDealRes sclRewriteFunction(SNode** pNode, SScalarCtx *ctx) { res->translate = true; if (colDataIsNull_s(output.columnData, 0)) { - res->node.resType.type = TSDB_DATA_TYPE_NULL; - res->node.resType.bytes = tDataTypes[TSDB_DATA_TYPE_NULL].bytes; + res->isNull = true; + //res->node.resType.type = TSDB_DATA_TYPE_NULL; + //res->node.resType.bytes = tDataTypes[TSDB_DATA_TYPE_NULL].bytes; } else { res->node.resType.type = output.columnData->info.type; res->node.resType.bytes = output.columnData->info.bytes; -- GitLab From 4bc3770cd3001550c0bdecccd1455a989859bdbb Mon Sep 17 00:00:00 2001 From: Ganlin Zhao Date: Wed, 13 Jul 2022 18:16:41 +0800 Subject: [PATCH 076/153] fix code format --- source/libs/scalar/src/scalar.c | 64 ++++++++++++++++----------------- 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/source/libs/scalar/src/scalar.c b/source/libs/scalar/src/scalar.c index 00b4dadc46..fd4fe20dcf 100644 --- a/source/libs/scalar/src/scalar.c +++ b/source/libs/scalar/src/scalar.c @@ -11,7 +11,7 @@ #include "ttime.h" int32_t scalarGetOperatorParamNum(EOperatorType type) { - if (OP_TYPE_IS_NULL == type || OP_TYPE_IS_NOT_NULL == type || OP_TYPE_IS_TRUE == type || OP_TYPE_IS_NOT_TRUE == type + if (OP_TYPE_IS_NULL == type || OP_TYPE_IS_NOT_NULL == type || OP_TYPE_IS_TRUE == type || OP_TYPE_IS_NOT_TRUE == type || OP_TYPE_IS_FALSE == type || OP_TYPE_IS_NOT_FALSE == type || OP_TYPE_IS_UNKNOWN == type || OP_TYPE_IS_NOT_UNKNOWN == type || OP_TYPE_MINUS == type) { return 1; @@ -28,7 +28,7 @@ int32_t sclConvertToTsValueNode(int8_t precision, SValueNode* valueNode) { } taosMemoryFree(timeStr); valueNode->typeData = valueNode->datum.i; - + valueNode->node.resType.type = TSDB_DATA_TYPE_TIMESTAMP; valueNode->node.resType.bytes = tDataTypes[TSDB_DATA_TYPE_TIMESTAMP].bytes; @@ -82,7 +82,7 @@ int32_t scalarGenerateSetFromList(void **data, void *pNode, uint32_t type) { SCL_ERR_RET(TSDB_CODE_QRY_OUT_OF_MEMORY); } - taosHashSetEqualFp(pObj, taosGetDefaultEqualFunction(type)); + taosHashSetEqualFp(pObj, taosGetDefaultEqualFunction(type)); int32_t code = 0; SNodeListNode *nodeList = (SNodeListNode *)pNode; @@ -91,10 +91,10 @@ int32_t scalarGenerateSetFromList(void **data, void *pNode, uint32_t type) { int32_t len = 0; void *buf = NULL; - + for (int32_t i = 0; i < nodeList->pNodeList->length; ++i) { SValueNode *valueNode = (SValueNode *)cell->pNode; - + if (valueNode->node.resType.type != type) { out.columnData->info.type = type; if (IS_VAR_DATA_TYPE(type)) { @@ -134,7 +134,7 @@ int32_t scalarGenerateSetFromList(void **data, void *pNode, uint32_t type) { len = valueNode->node.resType.bytes; } } - + if (taosHashPut(pObj, buf, (size_t)len, NULL, 0)) { sclError("taosHashPut to set failed"); SCL_ERR_JRET(TSDB_CODE_QRY_OUT_OF_MEMORY); @@ -180,7 +180,7 @@ int32_t sclCopyValueNodeValue(SValueNode *pNode, void **res) { if (TSDB_DATA_TYPE_NULL == pNode->node.resType.type) { return TSDB_CODE_SUCCESS; } - + *res = taosMemoryMalloc(pNode->node.resType.bytes); if (NULL == (*res)) { sclError("malloc %d failed", pNode->node.resType.bytes); @@ -222,14 +222,14 @@ int32_t sclInitParam(SNode* node, SScalarParam *param, SScalarCtx *ctx, int32_t if (type == 0) { type = nodeList->dataType.type; } - + SCL_ERR_RET(scalarGenerateSetFromList((void **)¶m->pHashFilter, node, type)); param->hashValueType = type; if (taosHashPut(ctx->pRes, &node, POINTER_BYTES, param, sizeof(*param))) { taosHashCleanup(param->pHashFilter); sclError("taosHashPut nodeList failed, size:%d", (int32_t)sizeof(*param)); return TSDB_CODE_QRY_OUT_OF_MEMORY; - } + } break; } case QUERY_NODE_COLUMN: { @@ -237,7 +237,7 @@ int32_t sclInitParam(SNode* node, SScalarParam *param, SScalarCtx *ctx, int32_t sclError("invalid node type for constant calculating, type:%d, src:%p", nodeType(node), ctx->pBlockList); SCL_ERR_RET(TSDB_CODE_QRY_APP_ERROR); } - + SColumnNode *ref = (SColumnNode *)node; int32_t index = -1; @@ -285,7 +285,7 @@ int32_t sclInitParam(SNode* node, SScalarParam *param, SScalarCtx *ctx, int32_t sclError("different row nums, rowNum:%d, newRowNum:%d", *rowNum, param->numOfRows); SCL_ERR_RET(TSDB_CODE_QRY_INVALID_INPUT); } - + *rowNum = param->numOfRows; } @@ -293,7 +293,7 @@ int32_t sclInitParam(SNode* node, SScalarParam *param, SScalarCtx *ctx, int32_t return TSDB_CODE_SUCCESS; } -int32_t sclInitParamList(SScalarParam **pParams, SNodeList* pParamList, SScalarCtx *ctx, int32_t *paramNum, int32_t *rowNum) { +int32_t sclInitParamList(SScalarParam **pParams, SNodeList* pParamList, SScalarCtx *ctx, int32_t *paramNum, int32_t *rowNum) { int32_t code = 0; if (NULL == pParamList) { if (ctx->pBlockList) { @@ -318,18 +318,18 @@ int32_t sclInitParamList(SScalarParam **pParams, SNodeList* pParamList, SScalarC SNode *tnode = NULL; int32_t i = 0; if (SCL_IS_CONST_CALC(ctx)) { - WHERE_EACH (tnode, pParamList) { + WHERE_EACH (tnode, pParamList) { if (!SCL_IS_CONST_NODE(tnode)) { WHERE_NEXT; } else { SCL_ERR_JRET(sclInitParam(tnode, ¶mList[i], ctx, rowNum)); ERASE_NODE(pParamList); } - + ++i; } } else { - FOREACH(tnode, pParamList) { + FOREACH(tnode, pParamList) { SCL_ERR_JRET(sclInitParam(tnode, ¶mList[i], ctx, rowNum)); ++i; } @@ -339,7 +339,7 @@ int32_t sclInitParamList(SScalarParam **pParams, SNodeList* pParamList, SScalarC } if (0 == *rowNum) { - taosMemoryFreeClear(paramList); + taosMemoryFreeClear(paramList); } *pParams = paramList; @@ -354,7 +354,7 @@ int32_t sclGetNodeType(SNode *pNode, SScalarCtx *ctx) { if (NULL == pNode) { return -1; } - + switch ((int)nodeType(pNode)) { case QUERY_NODE_VALUE: { SValueNode *valueNode = (SValueNode *)pNode; @@ -397,7 +397,7 @@ int32_t sclInitOperatorParams(SScalarParam **pParams, SOperatorNode *node, SScal sclError("invalid operation node, left:%p, right:%p", node->pLeft, node->pRight); SCL_ERR_RET(TSDB_CODE_QRY_INVALID_INPUT); } - + SScalarParam *paramList = taosMemoryCalloc(paramNum, sizeof(SScalarParam)); if (NULL == paramList) { sclError("calloc %d failed", (int32_t)(paramNum * sizeof(SScalarParam))); @@ -440,7 +440,7 @@ int32_t sclExecFunction(SFunctionNode *node, SScalarCtx *ctx, SScalarParam *outp sclError("fmGetFuncExecFuncs failed, funcId:%d, code:%s", node->funcId, tstrerror(code)); SCL_ERR_JRET(code); } - + code = sclCreateColumnInfoData(&node->node.resType, rowNum, output); if (code != TSDB_CODE_SUCCESS) { SCL_ERR_JRET(code); @@ -588,27 +588,27 @@ EDealRes sclRewriteNullInOptr(SNode** pNode, SScalarCtx *ctx, EOperatorType opTy if (opType <= OP_TYPE_CALC_MAX) { SValueNode *res = (SValueNode *)nodesMakeNode(QUERY_NODE_VALUE); if (NULL == res) { - sclError("make value node failed"); + sclError("make value node failed"); ctx->code = TSDB_CODE_QRY_OUT_OF_MEMORY; return DEAL_RES_ERROR; } - + res->node.resType.type = TSDB_DATA_TYPE_NULL; - + nodesDestroyNode(*pNode); *pNode = (SNode*)res; } else { SValueNode *res = (SValueNode *)nodesMakeNode(QUERY_NODE_VALUE); if (NULL == res) { - sclError("make value node failed"); + sclError("make value node failed"); ctx->code = TSDB_CODE_QRY_OUT_OF_MEMORY; return DEAL_RES_ERROR; } - + res->node.resType.type = TSDB_DATA_TYPE_BOOL; res->node.resType.bytes = tDataTypes[TSDB_DATA_TYPE_BOOL].bytes; res->datum.b = false; - + nodesDestroyNode(*pNode); *pNode = (SNode*)res; } @@ -641,12 +641,12 @@ EDealRes sclRewriteNonConstOperator(SNode** pNode, SScalarCtx *ctx) { if (node->pLeft && (QUERY_NODE_VALUE == nodeType(node->pLeft))) { SValueNode *valueNode = (SValueNode *)node->pLeft; - if (SCL_IS_NULL_VALUE_NODE(valueNode) && (node->opType != OP_TYPE_IS_NULL && node->opType != OP_TYPE_IS_NOT_NULL) + if (SCL_IS_NULL_VALUE_NODE(valueNode) && (node->opType != OP_TYPE_IS_NULL && node->opType != OP_TYPE_IS_NOT_NULL) && (!sclContainsAggFuncNode(node->pRight))) { return sclRewriteNullInOptr(pNode, ctx, node->opType); } - if (IS_STR_DATA_TYPE(valueNode->node.resType.type) && node->pRight && nodesIsExprNode(node->pRight) + if (IS_STR_DATA_TYPE(valueNode->node.resType.type) && node->pRight && nodesIsExprNode(node->pRight) && ((SExprNode*)node->pRight)->resType.type == TSDB_DATA_TYPE_TIMESTAMP) { code = sclConvertToTsValueNode(((SExprNode*)node->pRight)->resType.precision, valueNode); if (code) { @@ -663,7 +663,7 @@ EDealRes sclRewriteNonConstOperator(SNode** pNode, SScalarCtx *ctx) { return sclRewriteNullInOptr(pNode, ctx, node->opType); } - if (IS_STR_DATA_TYPE(valueNode->node.resType.type) && node->pLeft && nodesIsExprNode(node->pLeft) + if (IS_STR_DATA_TYPE(valueNode->node.resType.type) && node->pLeft && nodesIsExprNode(node->pLeft) && ((SExprNode*)node->pLeft)->resType.type == TSDB_DATA_TYPE_TIMESTAMP) { code = sclConvertToTsValueNode(((SExprNode*)node->pLeft)->resType.precision, valueNode); if (code) { @@ -833,7 +833,7 @@ EDealRes sclRewriteOperator(SNode** pNode, SScalarCtx *ctx) { res->datum.p = output.columnData->pData; output.columnData->pData = NULL; } else { - nodesSetValueNodeValue(res, output.columnData->pData); + nodesSetValueNodeValue(res, output.columnData->pData); } } @@ -900,7 +900,7 @@ EDealRes sclWalkLogic(SNode* pNode, SScalarCtx *ctx) { EDealRes sclWalkOperator(SNode* pNode, SScalarCtx *ctx) { SOperatorNode *node = (SOperatorNode *)pNode; SScalarParam output = {0}; - + ctx->code = sclExecOperator(node, ctx, &output); if (ctx->code) { return DEAL_RES_ERROR; @@ -1023,7 +1023,7 @@ int32_t scalarCalculateConstants(SNode *pNode, SNode **pRes) { sclError("taosHashInit failed, num:%d", SCL_DEFAULT_OP_NUM); SCL_ERR_RET(TSDB_CODE_QRY_OUT_OF_MEMORY); } - + nodesRewriteExprPostOrder(&pNode, sclConstantsRewriter, (void *)&ctx); SCL_ERR_JRET(ctx.code); *pRes = pNode; @@ -1047,7 +1047,7 @@ int32_t scalarCalculate(SNode *pNode, SArray *pBlockList, SScalarParam *pDst) { sclError("taosHashInit failed, num:%d", SCL_DEFAULT_OP_NUM); SCL_ERR_RET(TSDB_CODE_QRY_OUT_OF_MEMORY); } - + nodesWalkExprPostOrder(pNode, sclCalcWalker, (void *)&ctx); SCL_ERR_JRET(ctx.code); -- GitLab From f488b0dd003050d68da3b157d5249e085a3f5d87 Mon Sep 17 00:00:00 2001 From: Shengliang Guan Date: Wed, 13 Jul 2022 18:48:35 +0800 Subject: [PATCH 077/153] test: restore some 2.0 case --- tests/script/tsim/field/bool.sim | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/script/tsim/field/bool.sim b/tests/script/tsim/field/bool.sim index 37292e9758..90bb4e7c3d 100644 --- a/tests/script/tsim/field/bool.sim +++ b/tests/script/tsim/field/bool.sim @@ -144,7 +144,7 @@ print =============== step8 sql select count(tbcol), first(tbcol), last(tbcol) from $mt where tbcol = true group by tgcol order by tgcol desc print select count(tbcol), first(tbcol), last(tbcol) from $mt where tbcol = true group by tgcol order by tgcol desc print $data00 $data01 $data02 $data03 $data04 $data05 $data06 -if $data01 != 100 then +if $data00 != 100 then return -1 endi -- GitLab From 8aa04f8e5549c8c46ba0890675731f3964e70b18 Mon Sep 17 00:00:00 2001 From: wangmm0220 Date: Wed, 13 Jul 2022 18:49:57 +0800 Subject: [PATCH 078/153] fix:error in tmq meta --- include/util/tencode.h | 4 ++-- source/common/src/tmsg.c | 6 ++++-- source/dnode/vnode/src/vnd/vnodeSvr.c | 10 +++++++--- 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/include/util/tencode.h b/include/util/tencode.h index e318d4f240..ad642cd612 100644 --- a/include/util/tencode.h +++ b/include/util/tencode.h @@ -440,7 +440,7 @@ static FORCE_INLINE bool tDecodeIsEnd(SDecoder* pCoder) { return (pCoder->size = static FORCE_INLINE void* tEncoderMalloc(SEncoder* pCoder, int32_t size) { void* p = NULL; - SCoderMem* pMem = (SCoderMem*)taosMemoryMalloc(sizeof(*pMem) + size); + SCoderMem* pMem = (SCoderMem*)taosMemoryCalloc(1, sizeof(*pMem) + size); if (pMem) { pMem->next = pCoder->mList; pCoder->mList = pMem; @@ -451,7 +451,7 @@ static FORCE_INLINE void* tEncoderMalloc(SEncoder* pCoder, int32_t size) { static FORCE_INLINE void* tDecoderMalloc(SDecoder* pCoder, int32_t size) { void* p = NULL; - SCoderMem* pMem = (SCoderMem*)taosMemoryMalloc(sizeof(*pMem) + size); + SCoderMem* pMem = (SCoderMem*)taosMemoryCalloc(1, sizeof(*pMem) + size); if (pMem) { pMem->next = pCoder->mList; pCoder->mList = pMem; diff --git a/source/common/src/tmsg.c b/source/common/src/tmsg.c index 714a17df0d..9ebfa78b80 100644 --- a/source/common/src/tmsg.c +++ b/source/common/src/tmsg.c @@ -4984,8 +4984,10 @@ int tDecodeSVCreateTbReq(SDecoder *pCoder, SVCreateTbReq *pReq) { pReq->ctb.tagName = taosArrayInit(len, TSDB_COL_NAME_LEN); if(pReq->ctb.tagName == NULL) return -1; for (int32_t i = 0; i < len; i++){ - char *name = NULL; - if (tDecodeCStr(pCoder, &name) < 0) return -1; + char name[TSDB_COL_NAME_LEN] = {0}; + char *tmp = NULL; + if (tDecodeCStr(pCoder, &tmp) < 0) return -1; + strcpy(name, tmp); taosArrayPush(pReq->ctb.tagName, name); } } else if (pReq->type == TSDB_NORMAL_TABLE) { diff --git a/source/dnode/vnode/src/vnd/vnodeSvr.c b/source/dnode/vnode/src/vnd/vnodeSvr.c index d369475437..cca212a4e4 100644 --- a/source/dnode/vnode/src/vnd/vnodeSvr.c +++ b/source/dnode/vnode/src/vnd/vnodeSvr.c @@ -494,8 +494,6 @@ static int32_t vnodeProcessCreateTbReq(SVnode *pVnode, int64_t version, void *pR taosArrayPush(rsp.pArray, &cRsp); } - tDecoderClear(&decoder); - tqUpdateTbUidList(pVnode->pTq, tbUids, true); tdUpdateTbUidList(pVnode->pSma, pStore); tdUidStoreFree(pStore); @@ -512,9 +510,12 @@ static int32_t vnodeProcessCreateTbReq(SVnode *pVnode, int64_t version, void *pR } tEncoderInit(&encoder, pRsp->pCont, pRsp->contLen); tEncodeSVCreateTbBatchRsp(&encoder, &rsp); - tEncoderClear(&encoder); _exit: + for (int32_t iReq = 0; iReq < req.nReqs; iReq++) { + pCreateReq = req.pReqs + iReq; + taosArrayDestroy(pCreateReq->ctb.tagName); + } taosArrayDestroy(rsp.pArray); taosArrayDestroy(tbUids); tDecoderClear(&decoder); @@ -795,6 +796,7 @@ static int32_t vnodeProcessSubmitReq(SVnode *pVnode, int64_t version, void *pReq if (tDecodeSVCreateTbReq(&decoder, &createTbReq) < 0) { pRsp->code = TSDB_CODE_INVALID_MSG; tDecoderClear(&decoder); + taosArrayDestroy(createTbReq.ctb.tagName); goto _exit; } @@ -802,6 +804,7 @@ static int32_t vnodeProcessSubmitReq(SVnode *pVnode, int64_t version, void *pReq if (terrno != TSDB_CODE_TDB_TABLE_ALREADY_EXIST) { submitBlkRsp.code = terrno; tDecoderClear(&decoder); + taosArrayDestroy(createTbReq.ctb.tagName); goto _exit; } } @@ -822,6 +825,7 @@ static int32_t vnodeProcessSubmitReq(SVnode *pVnode, int64_t version, void *pReq vnodeDebugPrintSingleSubmitMsg(pVnode->pMeta, pBlock, &msgIter, "real uid"); #endif tDecoderClear(&decoder); + taosArrayDestroy(createTbReq.ctb.tagName); } else { submitBlkRsp.tblFName = taosMemoryMalloc(TSDB_TABLE_FNAME_LEN); sprintf(submitBlkRsp.tblFName, "%s.", pVnode->config.dbname); -- GitLab From 9887c63c5de481cac3bbf0a52069742806b17837 Mon Sep 17 00:00:00 2001 From: Xiaoyu Wang Date: Wed, 13 Jul 2022 19:03:40 +0800 Subject: [PATCH 079/153] feat: support pseudo columns such as _qstart, _qend and _qduration --- source/libs/nodes/src/nodesUtilFuncs.c | 2 +- source/libs/parser/src/parTranslater.c | 15 +-------------- 2 files changed, 2 insertions(+), 15 deletions(-) diff --git a/source/libs/nodes/src/nodesUtilFuncs.c b/source/libs/nodes/src/nodesUtilFuncs.c index 051cdf9a94..b00b08a66d 100644 --- a/source/libs/nodes/src/nodesUtilFuncs.c +++ b/source/libs/nodes/src/nodesUtilFuncs.c @@ -1777,7 +1777,7 @@ static EDealRes classifyConditionImpl(SNode* pNode, void* pContext) { SClassifyConditionCxt* pCxt = (SClassifyConditionCxt*)pContext; if (QUERY_NODE_COLUMN == nodeType(pNode)) { SColumnNode* pCol = (SColumnNode*)pNode; - if (PRIMARYKEY_TIMESTAMP_COL_ID == pCol->colId) { + if (PRIMARYKEY_TIMESTAMP_COL_ID == pCol->colId && TSDB_SYSTEM_TABLE != pCol->tableType) { pCxt->hasPrimaryKey = true; } else if (pCol->hasIndex) { pCxt->hasTagIndexCol = true; diff --git a/source/libs/parser/src/parTranslater.c b/source/libs/parser/src/parTranslater.c index ec8aadf827..653451a7a6 100644 --- a/source/libs/parser/src/parTranslater.c +++ b/source/libs/parser/src/parTranslater.c @@ -916,8 +916,6 @@ static EDealRes translateValueImpl(STranslateContext* pCxt, SValueNode* pVal, SD } if (TSDB_DATA_TYPE_NULL == pVal->node.resType.type) { - // TODO - // pVal->node.resType = targetDt; pVal->translate = true; pVal->isNull = true; return DEAL_RES_CONTINUE; @@ -2409,21 +2407,10 @@ static int32_t translatePartitionBy(STranslateContext* pCxt, SNodeList* pPartiti return translateExprList(pCxt, pPartitionByList); } -static bool isDataTable(int8_t tableType) { - return TSDB_SUPER_TABLE == tableType || TSDB_CHILD_TABLE == tableType || TSDB_NORMAL_TABLE == tableType; -} - -static bool needCalcTimeRange(SSelectStmt* pSelect) { - if (QUERY_NODE_REAL_TABLE != nodeType(pSelect->pFromTable)) { - return false; - } - return isDataTable(((SRealTableNode*)pSelect->pFromTable)->pMeta->tableType); -} - static int32_t translateWhere(STranslateContext* pCxt, SSelectStmt* pSelect) { pCxt->currClause = SQL_CLAUSE_WHERE; int32_t code = translateExpr(pCxt, &pSelect->pWhere); - if (TSDB_CODE_SUCCESS == code && needCalcTimeRange(pSelect)) { + if (TSDB_CODE_SUCCESS == code) { code = getQueryTimeRange(pCxt, pSelect->pWhere, &pSelect->timeRange); } return code; -- GitLab From 80f175bdbed9cf09f5a50aaa26d6c731ff7b0e02 Mon Sep 17 00:00:00 2001 From: Ganlin Zhao Date: Wed, 13 Jul 2022 19:46:56 +0800 Subject: [PATCH 080/153] feat(query): add count function scalar version TD-17344 --- include/libs/scalar/scalar.h | 1 + source/libs/function/src/builtins.c | 1 + source/libs/scalar/src/sclfunc.c | 30 +++++++++++++++++++++++++++++ 3 files changed, 32 insertions(+) diff --git a/include/libs/scalar/scalar.h b/include/libs/scalar/scalar.h index dfc83e1ff0..b047557424 100644 --- a/include/libs/scalar/scalar.h +++ b/include/libs/scalar/scalar.h @@ -97,6 +97,7 @@ int32_t qTbnameFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pO /* Aggregation functions */ int32_t countScalarFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput); +int32_t sumScalarFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput); #ifdef __cplusplus } diff --git a/source/libs/function/src/builtins.c b/source/libs/function/src/builtins.c index af0a0261d5..8226eccf14 100644 --- a/source/libs/function/src/builtins.c +++ b/source/libs/function/src/builtins.c @@ -1902,6 +1902,7 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = { .getEnvFunc = getSumFuncEnv, .initFunc = functionSetup, .processFunc = sumFunction, + .sprocessFunc = sumScalarFunction, .finalizeFunc = functionFinalize, .invertFunc = sumInvertFunction, .combineFunc = sumCombine, diff --git a/source/libs/scalar/src/sclfunc.c b/source/libs/scalar/src/sclfunc.c index d0cad23983..ce4631b8ee 100644 --- a/source/libs/scalar/src/sclfunc.c +++ b/source/libs/scalar/src/sclfunc.c @@ -1758,3 +1758,33 @@ int32_t countScalarFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam pOutput->numOfRows = pInput->numOfRows; return TSDB_CODE_SUCCESS; } + +int32_t sumScalarFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput) { + SColumnInfoData *pInputData = pInput->columnData; + SColumnInfoData *pOutputData = pOutput->columnData; + + int32_t type = GET_PARAM_TYPE(pInput); + for (int32_t i = 0; i < pInput->numOfRows; ++i) { + if (colDataIsNull_s(pInputData, i)) { + colDataAppendNULL(pOutputData, i); + break; + } + + if (IS_SIGNED_NUMERIC_TYPE(type)) { + int64_t *in = (int64_t *)pInputData->pData; + int64_t *out = (int64_t *)pOutputData->pData; + *out += in[i]; + } else if (IS_UNSIGNED_NUMERIC_TYPE(type)) { + uint64_t *in = (uint64_t *)pInputData->pData; + uint64_t *out = (uint64_t *)pOutputData->pData; + *out += in[i]; + } else if (IS_FLOAT_TYPE(type)) { + double *in = (double *)pInputData->pData; + double *out = (double *)pOutputData->pData; + *out += in[i]; + } + } + + pOutput->numOfRows = pInput->numOfRows; + return TSDB_CODE_SUCCESS; +} -- GitLab From afb20f79c71c97a9d6b95905bb89e0161fa5689b Mon Sep 17 00:00:00 2001 From: Haojun Liao Date: Wed, 13 Jul 2022 19:58:07 +0800 Subject: [PATCH 081/153] fix(query): copy the value instead of assign data. --- source/libs/executor/src/scanoperator.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/source/libs/executor/src/scanoperator.c b/source/libs/executor/src/scanoperator.c index c7112ab8a6..8786d30007 100644 --- a/source/libs/executor/src/scanoperator.c +++ b/source/libs/executor/src/scanoperator.c @@ -1183,7 +1183,10 @@ static int32_t setBlockIntoRes(SStreamScanInfo* pInfo, const SSDataBlock* pBlock for (int32_t j = 0; j < blockDataGetNumOfCols(pBlock); ++j) { SColumnInfoData* pResCol = bdGetColumnInfoData(pBlock, j); if (pResCol->info.colId == pColMatchInfo->colId) { - taosArraySet(pInfo->pRes->pDataBlock, pColMatchInfo->targetSlotId, pResCol); + + SColumnInfoData* pDst = taosArrayGet(pInfo->pRes->pDataBlock, pColMatchInfo->targetSlotId); + colDataAssign(pDst, pResCol, pBlock->info.rows, &pInfo->pRes->info); +// taosArraySet(pInfo->pRes->pDataBlock, pColMatchInfo->targetSlotId, pResCol); colExists = true; break; } @@ -2590,9 +2593,11 @@ static SSDataBlock* getTableDataBlock(void* param) { SDataBlockInfo binfo = pBlock->info; tsdbRetrieveDataBlockInfo(reader, &binfo); - binfo.capacity = binfo.rows; blockDataEnsureCapacity(pBlock, binfo.capacity); - pBlock->info = binfo; + pBlock->info.type = binfo.type; + pBlock->info.uid = binfo.uid; + pBlock->info.window = binfo.window; + pBlock->info.rows = binfo.rows; uint32_t status = 0; int32_t code = loadDataBlockFromOneTable(pOperator, pTableScanInfo, readerIdx, pBlock, &status); -- GitLab From 2f7d6828073358a12380413063ae262fa0756b32 Mon Sep 17 00:00:00 2001 From: Shengliang Guan Date: Wed, 13 Jul 2022 20:00:07 +0800 Subject: [PATCH 082/153] test: restore some 2.0 case --- tests/script/jenkins/basic.txt | 2 +- tests/script/tsim/compute/sum.sim | 6 +++--- tests/script/tsim/field/2.sim | 4 ++-- tests/script/tsim/field/3.sim | 6 +++--- tests/script/tsim/field/4.sim | 8 ++++---- tests/script/tsim/field/5.sim | 10 +++++----- tests/script/tsim/field/6.sim | 12 ++++++------ tests/script/tsim/field/bigint.sim | 2 +- tests/script/tsim/field/bool.sim | 4 ++-- tests/script/tsim/field/double.sim | 2 +- tests/script/tsim/field/float.sim | 2 +- tests/script/tsim/field/int.sim | 2 +- tests/script/tsim/field/smallint.sim | 2 +- tests/script/tsim/field/tinyint.sim | 2 +- tests/script/tsim/field/unsigined_bigint.sim | 2 +- 15 files changed, 33 insertions(+), 33 deletions(-) diff --git a/tests/script/jenkins/basic.txt b/tests/script/jenkins/basic.txt index ba94743df8..59536f2ef6 100644 --- a/tests/script/jenkins/basic.txt +++ b/tests/script/jenkins/basic.txt @@ -242,7 +242,7 @@ #./test.sh -f tsim/compute/null.sim ./test.sh -f tsim/compute/percentile.sim ./test.sh -f tsim/compute/stddev.sim -./test.sh -f tsim/compute/sum.sim +#./test.sh -f tsim/compute/sum.sim ./test.sh -f tsim/compute/top.sim # ---- field diff --git a/tests/script/tsim/compute/sum.sim b/tests/script/tsim/compute/sum.sim index d4185f3204..c53568f98f 100644 --- a/tests/script/tsim/compute/sum.sim +++ b/tests/script/tsim/compute/sum.sim @@ -153,9 +153,9 @@ print =============== step11 $cc = 4 * 60000 $ms = 1601481600000 + $cc -sql select sum(tbcol) as b from $mt where ts <= $ms group by tgcol -print select sum(tbcol) as b from $mt where ts <= $ms group by tgcol -print ===> $data00 +sql select sum(tbcol) as b from $mt where ts <= $ms partition by tgcol interval(1d) +print select sum(tbcol) as b from $mt where ts <= $ms partition by tgcol interval(1d) +print ===> $data00 $rows if $data00 != 10 then return -1 endi diff --git a/tests/script/tsim/field/2.sim b/tests/script/tsim/field/2.sim index b5c501ceed..3161f02097 100644 --- a/tests/script/tsim/field/2.sim +++ b/tests/script/tsim/field/2.sim @@ -278,9 +278,9 @@ if $data00 != 25 then endi print =============== step12 -sql select count(tbcol), avg(tbcol), sum(tbcol), min(tbcol), max(tbcol), first(tbcol), last(tbcol) from $mt where tbcol2 = 1 group by tgcol order by tgcol desc +sql select count(tbcol), avg(tbcol), sum(tbcol), min(tbcol), max(tbcol), first(tbcol), last(tbcol) from $mt where tbcol2 = 1 partition by tgcol interval(1d) order by tgcol desc print $db -print select count(tbcol), avg(tbcol), sum(tbcol), min(tbcol), max(tbcol), first(tbcol), last(tbcol) from $mt where tbcol2 = 1 group by tgcol +print select count(tbcol), avg(tbcol), sum(tbcol), min(tbcol), max(tbcol), first(tbcol), last(tbcol) from $mt where tbcol2 = 1 partition by tgcol interval(1d) print $data00 $data01 $data02 $data03 $data04 $data05 $data06 if $data00 != 100 then return -1 diff --git a/tests/script/tsim/field/3.sim b/tests/script/tsim/field/3.sim index 661bc6a85a..72b65c7406 100644 --- a/tests/script/tsim/field/3.sim +++ b/tests/script/tsim/field/3.sim @@ -491,19 +491,19 @@ if $data00 != 25 then endi print =============== step19 -sql select count(tbcol1), avg(tbcol1), sum(tbcol1), min(tbcol1), max(tbcol1), first(tbcol1), last(tbcol1) from $mt where tbcol1 = 1 and tbcol2 = 1 and tbcol3 = 1 group by tgcol1 order by tgcol1 desc +sql select count(tbcol1), avg(tbcol1), sum(tbcol1), min(tbcol1), max(tbcol1), first(tbcol1), last(tbcol1) from $mt where tbcol1 = 1 and tbcol2 = 1 and tbcol3 = 1 partition by tgcol1 interval(1d) order by tgcol1 desc print $data00 $data01 $data02 $data03 $data04 $data05 $data06 if $data00 != 100 then return -1 endi -sql select count(tbcol1), avg(tbcol1), sum(tbcol1), min(tbcol1), max(tbcol1), first(tbcol1), last(tbcol1) from $mt where tbcol1 = 1 and tbcol2 = 1 and tbcol3 = 1 group by tgcol2 order by tgcol2 desc +sql select count(tbcol1), avg(tbcol1), sum(tbcol1), min(tbcol1), max(tbcol1), first(tbcol1), last(tbcol1) from $mt where tbcol1 = 1 and tbcol2 = 1 and tbcol3 = 1 partition by tgcol2 interval(1d) order by tgcol2 desc print $data00 $data01 $data02 $data03 $data04 $data05 $data06 if $data00 != 100 then return -1 endi -sql select count(tbcol1), avg(tbcol1), sum(tbcol1), min(tbcol1), max(tbcol1), first(tbcol1), last(tbcol1) from $mt where tbcol1 = 1 and tbcol2 = 1 and tbcol3 = 1 group by tgcol3 order by tgcol3 desc +sql select count(tbcol1), avg(tbcol1), sum(tbcol1), min(tbcol1), max(tbcol1), first(tbcol1), last(tbcol1) from $mt where tbcol1 = 1 and tbcol2 = 1 and tbcol3 = 1 partition by tgcol3 interval(1d) order by tgcol3 desc print $data00 $data01 $data02 $data03 $data04 $data05 $data06 if $data00 != 100 then return -1 diff --git a/tests/script/tsim/field/4.sim b/tests/script/tsim/field/4.sim index 734179c5bb..d37c05173c 100644 --- a/tests/script/tsim/field/4.sim +++ b/tests/script/tsim/field/4.sim @@ -675,25 +675,25 @@ if $data00 != 25 then endi print =============== step24 -sql select count(tbcol1), avg(tbcol1), sum(tbcol1), min(tbcol1), max(tbcol1), first(tbcol1), last(tbcol1) from $mt where tbcol1 = 1 and tbcol2 = 1 and tbcol3 = 1 group by tgcol1 order by tgcol1 desc +sql select count(tbcol1), avg(tbcol1), sum(tbcol1), min(tbcol1), max(tbcol1), first(tbcol1), last(tbcol1) from $mt where tbcol1 = 1 and tbcol2 = 1 and tbcol3 = 1 partition by tgcol1 interval(1d) order by tgcol1 desc print $data00 $data01 $data02 $data03 $data04 $data05 $data06 if $data00 != 100 then return -1 endi -sql select count(tbcol1), avg(tbcol1), sum(tbcol1), min(tbcol1), max(tbcol1), first(tbcol1), last(tbcol1) from $mt where tbcol1 = 1 and tbcol2 = 1 and tbcol3 = 1 group by tgcol2 order by tgcol2 desc +sql select count(tbcol1), avg(tbcol1), sum(tbcol1), min(tbcol1), max(tbcol1), first(tbcol1), last(tbcol1) from $mt where tbcol1 = 1 and tbcol2 = 1 and tbcol3 = 1 partition by tgcol2 interval(1d) order by tgcol2 desc print $data00 $data01 $data02 $data03 $data04 $data05 $data06 if $data00 != 100 then return -1 endi -sql select count(tbcol1), avg(tbcol1), sum(tbcol1), min(tbcol1), max(tbcol1), first(tbcol1), last(tbcol1) from $mt where tbcol1 = 1 and tbcol2 = 1 and tbcol3 = 1 group by tgcol3 order by tgcol3 desc +sql select count(tbcol1), avg(tbcol1), sum(tbcol1), min(tbcol1), max(tbcol1), first(tbcol1), last(tbcol1) from $mt where tbcol1 = 1 and tbcol2 = 1 and tbcol3 = 1 partition by tgcol3 interval(1d) order by tgcol3 desc print $data00 $data01 $data02 $data03 $data04 $data05 $data06 if $data00 != 100 then return -1 endi -sql select count(tbcol1), avg(tbcol1), sum(tbcol1), min(tbcol1), max(tbcol1), first(tbcol1), last(tbcol1) from $mt where tbcol1 = 1 and tbcol2 = 1 and tbcol3 = 1 and tbcol4 = 1 group by tgcol4 order by tgcol4 desc +sql select count(tbcol1), avg(tbcol1), sum(tbcol1), min(tbcol1), max(tbcol1), first(tbcol1), last(tbcol1) from $mt where tbcol1 = 1 and tbcol2 = 1 and tbcol3 = 1 and tbcol4 = 1 partition by tgcol4 interval(1d) order by tgcol4 desc print $data00 $data01 $data02 $data03 $data04 $data05 $data06 if $data00 != 100 then return -1 diff --git a/tests/script/tsim/field/5.sim b/tests/script/tsim/field/5.sim index 5185d8556e..127dcd2683 100644 --- a/tests/script/tsim/field/5.sim +++ b/tests/script/tsim/field/5.sim @@ -792,31 +792,31 @@ endi print =============== step27 -sql select count(tbcol1), avg(tbcol1), sum(tbcol1), min(tbcol1), max(tbcol1), first(tbcol1), last(tbcol1) from $mt where tbcol1 = 1 and tbcol2 = 1 and tbcol3 = 1 group by tgcol1 order by tgcol1 desc +sql select count(tbcol1), avg(tbcol1), sum(tbcol1), min(tbcol1), max(tbcol1), first(tbcol1), last(tbcol1) from $mt where tbcol1 = 1 and tbcol2 = 1 and tbcol3 = 1 partition by tgcol1 interval(1d) order by tgcol1 desc print $data00 $data01 $data02 $data03 $data04 $data05 $data06 if $data00 != 100 then return -1 endi -sql select count(tbcol1), avg(tbcol1), sum(tbcol1), min(tbcol1), max(tbcol1), first(tbcol1), last(tbcol1) from $mt where tbcol1 = 1 and tbcol2 = 1 and tbcol3 = 1 group by tgcol2 order by tgcol2 desc +sql select count(tbcol1), avg(tbcol1), sum(tbcol1), min(tbcol1), max(tbcol1), first(tbcol1), last(tbcol1) from $mt where tbcol1 = 1 and tbcol2 = 1 and tbcol3 = 1 partition by tgcol2 interval(1d) order by tgcol2 desc print $data00 $data01 $data02 $data03 $data04 $data05 $data06 if $data00 != 100 then return -1 endi -sql select count(tbcol1), avg(tbcol1), sum(tbcol1), min(tbcol1), max(tbcol1), first(tbcol1), last(tbcol1) from $mt where tbcol1 = 1 and tbcol2 = 1 and tbcol3 = 1 group by tgcol3 order by tgcol3 desc +sql select count(tbcol1), avg(tbcol1), sum(tbcol1), min(tbcol1), max(tbcol1), first(tbcol1), last(tbcol1) from $mt where tbcol1 = 1 and tbcol2 = 1 and tbcol3 = 1 partition by tgcol3 interval(1d) order by tgcol3 desc print $data00 $data01 $data02 $data03 $data04 $data05 $data06 if $data00 != 100 then return -1 endi -sql select count(tbcol1), avg(tbcol1), sum(tbcol1), min(tbcol1), max(tbcol1), first(tbcol1), last(tbcol1) from $mt where tbcol1 = 1 and tbcol2 = 1 and tbcol3 = 1 and tbcol4 = 1 group by tgcol4 order by tgcol4 desc +sql select count(tbcol1), avg(tbcol1), sum(tbcol1), min(tbcol1), max(tbcol1), first(tbcol1), last(tbcol1) from $mt where tbcol1 = 1 and tbcol2 = 1 and tbcol3 = 1 and tbcol4 = 1 partition by tgcol4 interval(1d) order by tgcol4 desc print $data00 $data01 $data02 $data03 $data04 $data05 $data06 if $data00 != 100 then return -1 endi -sql select count(tbcol1), avg(tbcol1), sum(tbcol1), min(tbcol1), max(tbcol1), first(tbcol1), last(tbcol1) from $mt where tbcol1 = 1 and tbcol2 = 1 and tbcol3 = 1 and tbcol4 = 1 and tbcol5 = 1 group by tgcol5 order by tgcol5 desc +sql select count(tbcol1), avg(tbcol1), sum(tbcol1), min(tbcol1), max(tbcol1), first(tbcol1), last(tbcol1) from $mt where tbcol1 = 1 and tbcol2 = 1 and tbcol3 = 1 and tbcol4 = 1 and tbcol5 = 1 partition by tgcol5 interval(1d) order by tgcol5 desc print $data00 $data01 $data02 $data03 $data04 $data05 $data06 if $data00 != 100 then return -1 diff --git a/tests/script/tsim/field/6.sim b/tests/script/tsim/field/6.sim index 8ceefae228..474582fcae 100644 --- a/tests/script/tsim/field/6.sim +++ b/tests/script/tsim/field/6.sim @@ -941,37 +941,37 @@ if $data00 != 25 then endi print =============== step31 -sql select count(tbcol1), avg(tbcol1), sum(tbcol1), min(tbcol1), max(tbcol1), first(tbcol1), last(tbcol1) from $mt where tbcol1 = 1 and tbcol2 = 1 and tbcol3 = 1 group by tgcol1 order by tgcol1 desc +sql select count(tbcol1), avg(tbcol1), sum(tbcol1), min(tbcol1), max(tbcol1), first(tbcol1), last(tbcol1) from $mt where tbcol1 = 1 and tbcol2 = 1 and tbcol3 = 1 partition by tgcol1 interval(1d) order by tgcol1 desc print $data00 $data01 $data02 $data03 $data04 $data05 $data06 if $data00 != 100 then return -1 endi -sql select count(tbcol1), avg(tbcol1), sum(tbcol1), min(tbcol1), max(tbcol1), first(tbcol1), last(tbcol1) from $mt where tbcol1 = 1 and tbcol2 = 1 and tbcol3 = 1 group by tgcol2 order by tgcol2 desc +sql select count(tbcol1), avg(tbcol1), sum(tbcol1), min(tbcol1), max(tbcol1), first(tbcol1), last(tbcol1) from $mt where tbcol1 = 1 and tbcol2 = 1 and tbcol3 = 1 partition by tgcol2 interval(1d) order by tgcol2 desc print $data00 $data01 $data02 $data03 $data04 $data05 $data06 if $data00 != 100 then return -1 endi -sql select count(tbcol1), avg(tbcol1), sum(tbcol1), min(tbcol1), max(tbcol1), first(tbcol1), last(tbcol1) from $mt where tbcol1 = 1 and tbcol2 = 1 and tbcol3 = 1 group by tgcol3 order by tgcol3 desc +sql select count(tbcol1), avg(tbcol1), sum(tbcol1), min(tbcol1), max(tbcol1), first(tbcol1), last(tbcol1) from $mt where tbcol1 = 1 and tbcol2 = 1 and tbcol3 = 1 partition by tgcol3 interval(1d) order by tgcol3 desc print $data00 $data01 $data02 $data03 $data04 $data05 $data06 if $data00 != 100 then return -1 endi -sql select count(tbcol1), avg(tbcol1), sum(tbcol1), min(tbcol1), max(tbcol1), first(tbcol1), last(tbcol1) from $mt where tbcol1 = 1 and tbcol2 = 1 and tbcol3 = 1 and tbcol4 = 1 group by tgcol4 order by tgcol4 desc +sql select count(tbcol1), avg(tbcol1), sum(tbcol1), min(tbcol1), max(tbcol1), first(tbcol1), last(tbcol1) from $mt where tbcol1 = 1 and tbcol2 = 1 and tbcol3 = 1 and tbcol4 = 1 partition by tgcol4 interval(1d) order by tgcol4 desc print $data00 $data01 $data02 $data03 $data04 $data05 $data06 if $data00 != 100 then return -1 endi -sql select count(tbcol1), avg(tbcol1), sum(tbcol1), min(tbcol1), max(tbcol1), first(tbcol1), last(tbcol1) from $mt where tbcol1 = 1 and tbcol2 = 1 and tbcol3 = 1 and tbcol4 = 1 and tbcol5 = 1 group by tgcol5 order by tgcol5 desc +sql select count(tbcol1), avg(tbcol1), sum(tbcol1), min(tbcol1), max(tbcol1), first(tbcol1), last(tbcol1) from $mt where tbcol1 = 1 and tbcol2 = 1 and tbcol3 = 1 and tbcol4 = 1 and tbcol5 = 1 partition by tgcol5 interval(1d) order by tgcol5 desc print $data00 $data01 $data02 $data03 $data04 $data05 $data06 if $data00 != 100 then return -1 endi -sql select count(tbcol1), avg(tbcol1), sum(tbcol1), min(tbcol1), max(tbcol1), first(tbcol1), last(tbcol1) from $mt where tbcol1 = 1 and tbcol2 = 1 and tbcol3 = 1 and tbcol4 = 1 and tbcol5 = 1 and tbcol6 = 1 group by tgcol6 order by tgcol6 desc +sql select count(tbcol1), avg(tbcol1), sum(tbcol1), min(tbcol1), max(tbcol1), first(tbcol1), last(tbcol1) from $mt where tbcol1 = 1 and tbcol2 = 1 and tbcol3 = 1 and tbcol4 = 1 and tbcol5 = 1 and tbcol6 = 1 partition by tgcol6 interval(1d) order by tgcol6 desc print $data00 $data01 $data02 $data03 $data04 $data05 $data06 if $data00 != 100 then return -1 diff --git a/tests/script/tsim/field/bigint.sim b/tests/script/tsim/field/bigint.sim index c580a4df1c..d9401ed88f 100644 --- a/tests/script/tsim/field/bigint.sim +++ b/tests/script/tsim/field/bigint.sim @@ -143,7 +143,7 @@ if $data00 != 25 then endi print =============== step8 -sql select count(tbcol), avg(tbcol), sum(tbcol), min(tbcol), max(tbcol), first(tbcol), last(tbcol) from $mt where tbcol = 1 group by tgcol order by tgcol desc +sql select count(tbcol), avg(tbcol), sum(tbcol), min(tbcol), max(tbcol), first(tbcol), last(tbcol) from $mt where tbcol = 1 partition by tgcol interval(1d) order by tgcol desc print $data00 $data01 $data02 $data03 $data04 $data05 $data06 if $data00 != 100 then return -1 diff --git a/tests/script/tsim/field/bool.sim b/tests/script/tsim/field/bool.sim index 90bb4e7c3d..04cd48ab2d 100644 --- a/tests/script/tsim/field/bool.sim +++ b/tests/script/tsim/field/bool.sim @@ -141,8 +141,8 @@ if $data00 != 25 then endi print =============== step8 -sql select count(tbcol), first(tbcol), last(tbcol) from $mt where tbcol = true group by tgcol order by tgcol desc -print select count(tbcol), first(tbcol), last(tbcol) from $mt where tbcol = true group by tgcol order by tgcol desc +sql select count(tbcol), first(tbcol), last(tbcol) from $mt where tbcol = true partition by tgcol interval(1d) order by tgcol desc +print select count(tbcol), first(tbcol), last(tbcol) from $mt where tbcol = true partition by tgcol interval(1d) order by tgcol desc print $data00 $data01 $data02 $data03 $data04 $data05 $data06 if $data00 != 100 then return -1 diff --git a/tests/script/tsim/field/double.sim b/tests/script/tsim/field/double.sim index e7b1c8e8af..c7b26add65 100644 --- a/tests/script/tsim/field/double.sim +++ b/tests/script/tsim/field/double.sim @@ -141,7 +141,7 @@ if $data00 != 25 then endi print =============== step8 -sql select count(tbcol), avg(tbcol), sum(tbcol), min(tbcol), max(tbcol), first(tbcol), last(tbcol) from $mt where tbcol = 1 group by tgcol order by tgcol desc +sql select count(tbcol), avg(tbcol), sum(tbcol), min(tbcol), max(tbcol), first(tbcol), last(tbcol) from $mt where tbcol = 1 partition by tgcol interval(1d) order by tgcol desc print $data00 $data01 $data02 $data03 $data04 $data05 $data06 if $data00 != 100 then return -1 diff --git a/tests/script/tsim/field/float.sim b/tests/script/tsim/field/float.sim index 159a4b60ab..1e11eed3be 100644 --- a/tests/script/tsim/field/float.sim +++ b/tests/script/tsim/field/float.sim @@ -142,7 +142,7 @@ if $data00 != 25 then endi print =============== step8 -sql select count(tbcol), avg(tbcol), sum(tbcol), min(tbcol), max(tbcol), first(tbcol), last(tbcol) from $mt where tbcol = 1 group by tgcol order by tgcol desc +sql select count(tbcol), avg(tbcol), sum(tbcol), min(tbcol), max(tbcol), first(tbcol), last(tbcol) from $mt where tbcol = 1 partition by tgcol interval(1d) order by tgcol desc print $data00 $data01 $data02 $data03 $data04 $data05 $data06 if $data00 != 100 then return -1 diff --git a/tests/script/tsim/field/int.sim b/tests/script/tsim/field/int.sim index 2b5b70141a..484272631b 100644 --- a/tests/script/tsim/field/int.sim +++ b/tests/script/tsim/field/int.sim @@ -142,7 +142,7 @@ if $data00 != 25 then endi print =============== step8 -sql select count(tbcol), avg(tbcol), sum(tbcol), min(tbcol), max(tbcol), first(tbcol), last(tbcol) from $mt where tbcol = 1 group by tgcol order by tgcol desc +sql select count(tbcol), avg(tbcol), sum(tbcol), min(tbcol), max(tbcol), first(tbcol), last(tbcol) from $mt where tbcol = 1 partition by tgcol interval(1d) order by tgcol desc print $data00 $data01 $data02 $data03 $data04 $data05 $data06 if $data00 != 100 then return -1 diff --git a/tests/script/tsim/field/smallint.sim b/tests/script/tsim/field/smallint.sim index 975f02bf9b..326186f6c2 100644 --- a/tests/script/tsim/field/smallint.sim +++ b/tests/script/tsim/field/smallint.sim @@ -142,7 +142,7 @@ if $data00 != 25 then endi print =============== step8 -sql select count(tbcol), avg(tbcol), sum(tbcol), min(tbcol), max(tbcol), first(tbcol), last(tbcol) from $mt where tbcol = 1 group by tgcol order by tgcol desc +sql select count(tbcol), avg(tbcol), sum(tbcol), min(tbcol), max(tbcol), first(tbcol), last(tbcol) from $mt where tbcol = 1 partition by tgcol interval(1d) order by tgcol desc print $data00 $data01 $data02 $data03 $data04 $data05 $data06 if $data00 != 100 then return -1 diff --git a/tests/script/tsim/field/tinyint.sim b/tests/script/tsim/field/tinyint.sim index ff24e484a7..cba4ac504d 100644 --- a/tests/script/tsim/field/tinyint.sim +++ b/tests/script/tsim/field/tinyint.sim @@ -142,7 +142,7 @@ if $data00 != 25 then endi print =============== step8 -sql select count(tbcol), avg(tbcol), sum(tbcol), min(tbcol), max(tbcol), first(tbcol), last(tbcol) from $mt where tbcol = 1 group by tgcol order by tgcol desc +sql select count(tbcol), avg(tbcol), sum(tbcol), min(tbcol), max(tbcol), first(tbcol), last(tbcol) from $mt where tbcol = 1 partition by tgcol interval(1d) order by tgcol desc print $data00 $data01 $data02 $data03 $data04 $data05 $data06 if $data00 != 100 then return -1 diff --git a/tests/script/tsim/field/unsigined_bigint.sim b/tests/script/tsim/field/unsigined_bigint.sim index d8421e7626..0a492ae44c 100644 --- a/tests/script/tsim/field/unsigined_bigint.sim +++ b/tests/script/tsim/field/unsigined_bigint.sim @@ -147,7 +147,7 @@ if $data00 != 25 then endi print =============== step8 -sql select count(tbcol), avg(tbcol), sum(tbcol), min(tbcol), max(tbcol), first(tbcol), last(tbcol) from $mt where tbcol = 1 group by tgcol order by tgcol desc +sql select count(tbcol), avg(tbcol), sum(tbcol), min(tbcol), max(tbcol), first(tbcol), last(tbcol) from $mt where tbcol = 1 partition by tgcol interval(1d) order by tgcol desc print $data00 $data01 $data02 $data03 $data04 $data05 $data06 if $data00 != 100 then return -1 -- GitLab From a8569fc44ba0283b6514ffbd77460d9f847d1be3 Mon Sep 17 00:00:00 2001 From: Hui Li <52318143+plum-lihui@users.noreply.github.com> Date: Wed, 13 Jul 2022 20:04:11 +0800 Subject: [PATCH 083/153] Delete tmqUpdate1.py test: del nouse script --- tests/system-test/7-tmq/tmqUpdate1.py | 175 -------------------------- 1 file changed, 175 deletions(-) delete mode 100644 tests/system-test/7-tmq/tmqUpdate1.py diff --git a/tests/system-test/7-tmq/tmqUpdate1.py b/tests/system-test/7-tmq/tmqUpdate1.py deleted file mode 100644 index 5f11090385..0000000000 --- a/tests/system-test/7-tmq/tmqUpdate1.py +++ /dev/null @@ -1,175 +0,0 @@ - -import taos -import sys -import time -import socket -import os -import threading -from enum import Enum - -from util.log import * -from util.sql import * -from util.cases import * -from util.dnodes import * -sys.path.append("./7-tmq") -from tmqCommon import * - -class TDTestCase: - def __init__(self): - self.vgroups = 4 - self.ctbNum = 1000 - self.rowsPerTbl = 1000 - - def init(self, conn, logSql): - tdLog.debug(f"start to excute {__file__}") - tdSql.init(conn.cursor(), False) - - def prepareTestEnv(self): - tdLog.printNoPrefix("======== prepare test env include database, stable, ctables, and insert data: ") - paraDict = {'dbName': 'dbt', - 'dropFlag': 1, - 'event': '', - 'vgroups': 4, - 'stbName': 'stb', - 'colPrefix': 'c', - 'tagPrefix': 't', - 'colSchema': [{'type': 'INT', 'count':1},{'type': 'BIGINT', 'count':1},{'type': 'DOUBLE', 'count':1},{'type': 'BINARY', 'len':32, 'count':1},{'type': 'NCHAR', 'len':32, 'count':1},{'type': 'TIMESTAMP', 'count':1}], - 'tagSchema': [{'type': 'INT', 'count':1},{'type': 'BIGINT', 'count':1},{'type': 'DOUBLE', 'count':1},{'type': 'BINARY', 'len':32, 'count':1},{'type': 'NCHAR', 'len':32, 'count':1}], - 'ctbPrefix': 'ctb', - 'ctbStartIdx': 0, - 'ctbNum': 1000, - 'rowsPerTbl': 1000, - 'batchNum': 400, - 'startTs': 1640966400000, # 2022-01-01 00:00:00.000 - 'pollDelay': 3, - 'showMsg': 1, - 'showRow': 1, - 'snapshot': 0} - - paraDict['vgroups'] = self.vgroups - paraDict['ctbNum'] = self.ctbNum - paraDict['rowsPerTbl'] = self.rowsPerTbl - - tmqCom.initConsumerTable() - tdCom.create_database(tdSql, paraDict["dbName"],paraDict["dropFlag"], vgroups=paraDict["vgroups"],replica=1) - tdLog.info("create stb") - tmqCom.create_stable(tdSql, dbName=paraDict["dbName"],stbName=paraDict["stbName"]) - tdLog.info("create ctb") - tmqCom.create_ctable(tdSql, dbName=paraDict["dbName"],stbName=paraDict["stbName"],ctbPrefix=paraDict['ctbPrefix'], - ctbNum=paraDict["ctbNum"],ctbStartIdx=paraDict['ctbStartIdx']) - tdLog.info("insert data") - paraDict['ctbNum'] = int(self.ctbNum / 2) - tmqCom.insert_data_interlaceByMultiTbl(tsql=tdSql,dbName=paraDict["dbName"],ctbPrefix=paraDict["ctbPrefix"], - ctbNum=paraDict["ctbNum"],rowsPerTbl=paraDict["rowsPerTbl"],batchNum=paraDict["batchNum"], - startTs=paraDict["startTs"],ctbStartIdx=paraDict['ctbStartIdx']) - tmqCom.insert_data_with_autoCreateTbl(tsql=tdSql,dbName=paraDict["dbName"],stbName=paraDict["stbName"],ctbPrefix="ctbx", - ctbNum=paraDict["ctbNum"],rowsPerTbl=paraDict["rowsPerTbl"],batchNum=paraDict["batchNum"], - startTs=paraDict["startTs"],ctbStartIdx=paraDict['ctbStartIdx']) - - # tdLog.info("restart taosd to ensure that the data falls into the disk") - # tdSql.query("flush database %s"%(paraDict['dbName'])) - return - - def tmqCase1(self): - tdLog.printNoPrefix("======== test case 1: ") - paraDict = {'dbName': 'dbt', - 'dropFlag': 1, - 'event': '', - 'vgroups': 4, - 'stbName': 'stb', - 'colPrefix': 'c', - 'tagPrefix': 't', - 'colSchema': [{'type': 'INT', 'count':1},{'type': 'BIGINT', 'count':1},{'type': 'DOUBLE', 'count':1},{'type': 'BINARY', 'len':32, 'count':1},{'type': 'NCHAR', 'len':32, 'count':1},{'type': 'TIMESTAMP', 'count':1}], - 'tagSchema': [{'type': 'INT', 'count':1},{'type': 'BIGINT', 'count':1},{'type': 'DOUBLE', 'count':1},{'type': 'BINARY', 'len':32, 'count':1},{'type': 'NCHAR', 'len':32, 'count':1}], - 'ctbPrefix': 'ctb', - 'ctbStartIdx': 0, - 'ctbNum': 1000, - 'rowsPerTbl': 1000, - 'batchNum': 1000, - 'startTs': 1640966400000, # 2022-01-01 00:00:00.000 - 'pollDelay': 5, - 'showMsg': 1, - 'showRow': 1, - 'snapshot': 1} - - paraDict['vgroups'] = self.vgroups - paraDict['ctbNum'] = self.ctbNum - paraDict['rowsPerTbl'] = self.rowsPerTbl - - tdLog.info("restart taosd to ensure that the data falls into the disk") - tdSql.query("flush database %s"%(paraDict['dbName'])) - - # update to half tables - paraDict['ctbNum'] = int(self.ctbNum / 4) - tmqCom.insert_data_with_autoCreateTbl(tsql=tdSql,dbName=paraDict["dbName"],stbName=paraDict["stbName"],ctbPrefix="ctbx", - ctbNum=paraDict["ctbNum"],rowsPerTbl=paraDict["rowsPerTbl"],batchNum=paraDict["batchNum"], - startTs=paraDict["startTs"],ctbStartIdx=paraDict['ctbStartIdx']+paraDict['ctbNum']) - tmqCom.insert_data_interlaceByMultiTbl(tsql=tdSql,dbName=paraDict["dbName"],ctbPrefix=paraDict["ctbPrefix"], - ctbNum=paraDict["ctbNum"],rowsPerTbl=paraDict["rowsPerTbl"],batchNum=paraDict["batchNum"], - startTs=paraDict["startTs"],ctbStartIdx=paraDict['ctbStartIdx']+paraDict['ctbNum']) - - tmqCom.initConsumerTable() - tdLog.info("create topics from stb1") - topicFromStb1 = 'topic_stb1' - queryString = "select ts, c1, c2 from %s.%s"%(paraDict['dbName'], paraDict['stbName']) - sqlString = "create topic %s as %s" %(topicFromStb1, queryString) - tdLog.info("create topic sql: %s"%sqlString) - tdSql.execute(sqlString) - - paraDict['ctbNum'] = self.ctbNum - consumerId = 0 - expectrowcnt = paraDict["rowsPerTbl"] * paraDict["ctbNum"] * (1 + 1) - topicList = topicFromStb1 - ifcheckdata = 0 - ifManualCommit = 0 - keyList = 'group.id:cgrp1,\ - enable.auto.commit:true,\ - auto.commit.interval.ms:1000,\ - auto.offset.reset:earliest' - tmqCom.insertConsumerInfo(consumerId, expectrowcnt + paraDict["rowsPerTbl"] * paraDict["ctbNum"],topicList,keyList,ifcheckdata,ifManualCommit) - - tdLog.info("start consume processor") - tmqCom.startTmqSimProcess(pollDelay=paraDict['pollDelay'],dbName=paraDict["dbName"],showMsg=paraDict['showMsg'], showRow=paraDict['showRow'],snapshot=paraDict['snapshot']) - - paraDict['ctbNum'] = int(self.ctbNum / 2) - paraDict['ctbStartIdx'] += paraDict['ctbNum'] - _ = tmqCom.asyncInsertDataByInterlace(paraDict) - time.sleep(3) - pthread = tmqCom.asyncInsertDataByInterlace(paraDict) - pthread.join() - - tdLog.info("insert process end, and start to check consume result") - expectRows = 1 - resultList = tmqCom.selectConsumeResult(expectRows) - totalConsumeRows = 0 - for i in range(expectRows): - totalConsumeRows += resultList[i] - - tdSql.query(queryString) - totalRowsInserted = tdSql.getRows() - - tdLog.info("act consume rows: %d, act insert rows: %d, expect consume rows: %d, "%(totalConsumeRows, totalRowsInserted, expectrowcnt)) - - if totalConsumeRows <= totalRowsInserted or totalConsumeRows != expectrowcnt: - tdLog.exit("tmq consume rows error!") - - tdSql.query("drop topic %s"%topicFromStb1) - - tdLog.printNoPrefix("======== test case 1 end ...... ") - - - def run(self): - tdSql.prepare() - self.prepareTestEnv() - self.tmqCase1() - # self.tmqCase2() - - - def stop(self): - tdSql.close() - tdLog.success(f"{__file__} successfully executed") - -event = threading.Event() - -tdCases.addLinux(__file__, TDTestCase()) -tdCases.addWindows(__file__, TDTestCase()) -- GitLab From 88d1d8fad21771ace5f654d2979e0f248bc2a3cd Mon Sep 17 00:00:00 2001 From: tomchon Date: Wed, 13 Jul 2022 20:21:13 +0800 Subject: [PATCH 084/153] test:add test case of tsbs query --- tests/system-test/2-query/tsbsQuery.py | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/tests/system-test/2-query/tsbsQuery.py b/tests/system-test/2-query/tsbsQuery.py index 63f243baa0..8180f511e2 100644 --- a/tests/system-test/2-query/tsbsQuery.py +++ b/tests/system-test/2-query/tsbsQuery.py @@ -76,9 +76,19 @@ class TDTestCase: tdSql.query("insert into testsnode(ts,c1,c2,c3,c4) SELECT ts,avg(velocity) as mean_velocity,name,driver,fleet FROM readings WHERE ts > 1451606400000 AND ts <= 1451606460000 partition BY name,driver,fleet,ts interval(10m);") - # test interval fill - tdSql.query("SELECT name,floor(avg(velocity)/10)/floor(avg(velocity)/10) AS mv FROM readings WHERE name!='' AND ts > '2016-01-01T00:00:00Z' AND ts < '2016-01-05T00:00:01Z' partition by name interval(10m) fill(value,0) ;") + # test paitition interval fill + # tdSql.query("SELECT name,floor(avg(velocity)/10)/floor(avg(velocity)/10) AS mv FROM readings WHERE name!='' AND ts > '2016-01-01T00:00:00Z' AND ts < '2016-01-05T00:00:01Z' partition by name interval(10m) fill(value,0) ;") + + # # test partition interval limit + # tdSql.query("SELECT ts,model,floor(2*(sum(nzs)/count(nzs)))/floor(2*(sum(nzs)/count(nzs))) AS broken_down FROM (SELECT ts,model, status/status AS nzs FROM diagnostics WHERE ts >= '2016-01-01T00:00:00Z' AND ts < '2016-01-05T00:00:01Z' ) WHERE ts >= '2016-01-01T00:00:00Z' AND ts < '2016-01-05T00:00:01Z' partition BY model,ts interval(10m) limit 10;") + # tdSql.checkRows(10) + + # test partition interval Pseudo time-column + tdSql.query("SELECT count(ms1)/144 FROM (SELECT _wstartts as ts1,model, fleet,avg(status) AS ms1 FROM diagnostics WHERE ts >= '2016-01-01T00:00:00Z' AND ts < '2016-01-05T00:00:01Z' partition by model, fleet interval(10m)) WHERE ts1 >= '2016-01-01T00:00:00Z' AND ts1 < '2016-01-05T00:00:01Z' AND ms1<1;") + + + # test def run(self): # sourcery skip: extract-duplicate-method, remove-redundant-fstring tdLog.printNoPrefix("==========step1:create database and table,insert data ==============") self.prepareData() -- GitLab From 26c5ac3e844090d30ad32f5eb7860fbf019d560d Mon Sep 17 00:00:00 2001 From: Shengliang Guan Date: Wed, 13 Jul 2022 20:23:33 +0800 Subject: [PATCH 085/153] test: restore some 2.0 case --- tests/script/general/vector/testSuite.sim | 11 -------- tests/script/jenkins/basic.txt | 13 ++++++++++ .../vector/metrics_field.sim | 20 +++----------- .../{general => tsim}/vector/metrics_mix.sim | 18 +++---------- .../vector/metrics_query.sim | 20 +++----------- .../{general => tsim}/vector/metrics_tag.sim | 18 +++---------- .../{general => tsim}/vector/metrics_time.sim | 18 +++---------- .../script/{general => tsim}/vector/multi.sim | 26 +++++-------------- .../{general => tsim}/vector/single.sim | 14 +++------- .../{general => tsim}/vector/table_field.sim | 18 +++---------- .../{general => tsim}/vector/table_mix.sim | 18 +++---------- .../{general => tsim}/vector/table_query.sim | 18 +++---------- .../{general => tsim}/vector/table_time.sim | 18 +++---------- 13 files changed, 58 insertions(+), 172 deletions(-) delete mode 100644 tests/script/general/vector/testSuite.sim rename tests/script/{general => tsim}/vector/metrics_field.sim (97%) rename tests/script/{general => tsim}/vector/metrics_mix.sim (98%) rename tests/script/{general => tsim}/vector/metrics_query.sim (97%) rename tests/script/{general => tsim}/vector/metrics_tag.sim (97%) rename tests/script/{general => tsim}/vector/metrics_time.sim (98%) rename tests/script/{general => tsim}/vector/multi.sim (89%) rename tests/script/{general => tsim}/vector/single.sim (96%) rename tests/script/{general => tsim}/vector/table_field.sim (97%) rename tests/script/{general => tsim}/vector/table_mix.sim (98%) rename tests/script/{general => tsim}/vector/table_query.sim (97%) rename tests/script/{general => tsim}/vector/table_time.sim (97%) diff --git a/tests/script/general/vector/testSuite.sim b/tests/script/general/vector/testSuite.sim deleted file mode 100644 index f0b9fef991..0000000000 --- a/tests/script/general/vector/testSuite.sim +++ /dev/null @@ -1,11 +0,0 @@ -run general/vector/metrics_field.sim -run general/vector/metrics_mix.sim -run general/vector/metrics_query.sim -run general/vector/metrics_tag.sim -run general/vector/metrics_time.sim -run general/vector/multi.sim -run general/vector/single.sim -run general/vector/table_field.sim -run general/vector/table_mix.sim -run general/vector/table_query.sim -run general/vector/table_time.sim diff --git a/tests/script/jenkins/basic.txt b/tests/script/jenkins/basic.txt index 59536f2ef6..5f87b8a55f 100644 --- a/tests/script/jenkins/basic.txt +++ b/tests/script/jenkins/basic.txt @@ -262,4 +262,17 @@ ./test.sh -f tsim/field/tinyint.sim ./test.sh -f tsim/field/unsigined_bigint.sim +# ---- vector +./test.sh -f tsim/vector/metrics_field.sim +./test.sh -f tsim/vector/metrics_mix.sim +./test.sh -f tsim/vector/metrics_query.sim +./test.sh -f tsim/vector/metrics_tag.sim +./test.sh -f tsim/vector/metrics_time.sim +./test.sh -f tsim/vector/multi.sim +./test.sh -f tsim/vector/single.sim +./test.sh -f tsim/vector/table_field.sim +./test.sh -f tsim/vector/table_mix.sim +./test.sh -f tsim/vector/table_query.sim +./test.sh -f tsim/vector/table_time.sim + #======================b1-end=============== diff --git a/tests/script/general/vector/metrics_field.sim b/tests/script/tsim/vector/metrics_field.sim similarity index 97% rename from tests/script/general/vector/metrics_field.sim rename to tests/script/tsim/vector/metrics_field.sim index 2719805c63..4d0f9e19fc 100644 --- a/tests/script/general/vector/metrics_field.sim +++ b/tests/script/tsim/vector/metrics_field.sim @@ -1,10 +1,6 @@ system sh/stop_dnodes.sh - system sh/deploy.sh -n dnode1 -i 1 -system sh/cfg.sh -n dnode1 -c walLevel -v 1 system sh/exec.sh -n dnode1 -s start - -sleep 2000 sql connect $dbPrefix = m_mf_db @@ -99,17 +95,9 @@ if $data00 != 0.000000000 then return -1 endi -sql select g - f from $mt where a = 5 -x step21 - return -1 -step21: - -sql select h - f from $mt where a = 5 -x step22 - return -1 -step22: - -sql select ts - f from $mt where a = 5 -x step23 - return -1 -step23: +sql select g - f from $mt where a = 5 +sql select h - f from $mt where a = 5 +sql select ts - f from $mt where a = 5 sql select a - e from $mt where a = 5 print ===> $data00 @@ -616,7 +604,7 @@ step63: print =============== clear sql drop database $db sql show databases -if $rows != 0 then +if $rows != 2 then return -1 endi diff --git a/tests/script/general/vector/metrics_mix.sim b/tests/script/tsim/vector/metrics_mix.sim similarity index 98% rename from tests/script/general/vector/metrics_mix.sim rename to tests/script/tsim/vector/metrics_mix.sim index 7c9bb3b668..fd36a62332 100644 --- a/tests/script/general/vector/metrics_mix.sim +++ b/tests/script/tsim/vector/metrics_mix.sim @@ -1,10 +1,6 @@ system sh/stop_dnodes.sh - system sh/deploy.sh -n dnode1 -i 1 -system sh/cfg.sh -n dnode1 -c walLevel -v 1 system sh/exec.sh -n dnode1 -s start - -sleep 2000 sql connect $dbPrefix = m_mx_db @@ -99,17 +95,11 @@ if $data00 != 0.000000000 then return -1 endi -sql select g - f from $mt where a = 5 and tgcol = 5 and ts > now + 4m and ts < now + 6m -x step21 - return -1 -step21: +sql select g - f from $mt where a = 5 and tgcol = 5 and ts > now + 4m and ts < now + 6m -sql select h - f from $mt where a = 5 and tgcol = 5 and ts > now + 4m and ts < now + 6m -x step22 - return -1 -step22: +sql select h - f from $mt where a = 5 and tgcol = 5 and ts > now + 4m and ts < now + 6m -sql select ts - f from $mt where a = 5 and tgcol = 5 and ts > now + 4m and ts < now + 6m -x step23 - return -1 -step23: +sql select ts - f from $mt where a = 5 and tgcol = 5 and ts > now + 4m and ts < now + 6m sql select a - e from $mt where a = 5 and tgcol = 5 and ts > now + 4m and ts < now + 6m print ===> $data00 @@ -616,7 +606,7 @@ step63: print =============== clear sql drop database $db sql show databases -if $rows != 0 then +if $rows != 2 then return -1 endi diff --git a/tests/script/general/vector/metrics_query.sim b/tests/script/tsim/vector/metrics_query.sim similarity index 97% rename from tests/script/general/vector/metrics_query.sim rename to tests/script/tsim/vector/metrics_query.sim index fd635a3104..8a334acef2 100644 --- a/tests/script/general/vector/metrics_query.sim +++ b/tests/script/tsim/vector/metrics_query.sim @@ -1,10 +1,6 @@ system sh/stop_dnodes.sh - system sh/deploy.sh -n dnode1 -i 1 -system sh/cfg.sh -n dnode1 -c walLevel -v 1 system sh/exec.sh -n dnode1 -s start - -sleep 2000 sql connect $dbPrefix = m_mq_db @@ -95,17 +91,9 @@ if $data00 != 0.000000000 then return -1 endi -sql select g - f from $mt -x step21 - return -1 -step21: - -sql select h - f from $mt -x step22 - return -1 -step22: - -sql select ts - f from $mt -x step23 - return -1 -step23: +sql select g - f from $mt +sql select h - f from $mt +sql select ts - f from $mt sql select a - e from $mt print ===> $data00 @@ -612,7 +600,7 @@ step63: print =============== clear sql drop database $db sql show databases -if $rows != 0 then +if $rows != 2 then return -1 endi diff --git a/tests/script/general/vector/metrics_tag.sim b/tests/script/tsim/vector/metrics_tag.sim similarity index 97% rename from tests/script/general/vector/metrics_tag.sim rename to tests/script/tsim/vector/metrics_tag.sim index 1d412d35d3..0b275336f9 100644 --- a/tests/script/general/vector/metrics_tag.sim +++ b/tests/script/tsim/vector/metrics_tag.sim @@ -1,10 +1,6 @@ system sh/stop_dnodes.sh - system sh/deploy.sh -n dnode1 -i 1 -system sh/cfg.sh -n dnode1 -c walLevel -v 1 system sh/exec.sh -n dnode1 -s start - -sleep 2000 sql connect $dbPrefix = m_mtg_db @@ -95,17 +91,11 @@ if $data00 != 0.000000000 then return -1 endi -sql select g - f from $mt where tgcol = 5 -x step21 - return -1 -step21: +sql select g - f from $mt where tgcol = 5 -sql select h - f from $mt where tgcol = 5 -x step22 - return -1 -step22: +sql select h - f from $mt where tgcol = 5 -sql select ts - f from $mt where tgcol = 5 -x step23 - return -1 -step23: +sql select ts - f from $mt where tgcol = 5 sql select a - e from $mt where tgcol = 5 print ===> $data00 @@ -612,7 +602,7 @@ step63: print =============== clear sql drop database $db sql show databases -if $rows != 0 then +if $rows != 2 then return -1 endi diff --git a/tests/script/general/vector/metrics_time.sim b/tests/script/tsim/vector/metrics_time.sim similarity index 98% rename from tests/script/general/vector/metrics_time.sim rename to tests/script/tsim/vector/metrics_time.sim index d0152439bf..bcd93cb582 100644 --- a/tests/script/general/vector/metrics_time.sim +++ b/tests/script/tsim/vector/metrics_time.sim @@ -1,10 +1,6 @@ system sh/stop_dnodes.sh - system sh/deploy.sh -n dnode1 -i 1 -system sh/cfg.sh -n dnode1 -c walLevel -v 1 system sh/exec.sh -n dnode1 -s start - -sleep 2000 sql connect $dbPrefix = m_mt_db @@ -95,17 +91,11 @@ if $data00 != 0.000000000 then return -1 endi -sql select g - f from $mt where tgcol = 5 and ts > now + 4m and ts < now + 6m -x step21 - return -1 -step21: +sql select g - f from $mt where tgcol = 5 and ts > now + 4m and ts < now + 6m -sql select h - f from $mt where tgcol = 5 and ts > now + 4m and ts < now + 6m -x step22 - return -1 -step22: +sql select h - f from $mt where tgcol = 5 and ts > now + 4m and ts < now + 6m -sql select ts - f from $mt where tgcol = 5 and ts > now + 4m and ts < now + 6m -x step23 - return -1 -step23: +sql select ts - f from $mt where tgcol = 5 and ts > now + 4m and ts < now + 6m sql select a - e from $mt where tgcol = 5 and ts > now + 4m and ts < now + 6m print ===> $data00 @@ -612,7 +602,7 @@ step63: print =============== clear sql drop database $db sql show databases -if $rows != 0 then +if $rows != 2 then return -1 endi diff --git a/tests/script/general/vector/multi.sim b/tests/script/tsim/vector/multi.sim similarity index 89% rename from tests/script/general/vector/multi.sim rename to tests/script/tsim/vector/multi.sim index 1101b0b0db..dcedbe73c9 100644 --- a/tests/script/general/vector/multi.sim +++ b/tests/script/tsim/vector/multi.sim @@ -1,10 +1,6 @@ system sh/stop_dnodes.sh - system sh/deploy.sh -n dnode1 -i 1 -system sh/cfg.sh -n dnode1 -c walLevel -v 1 system sh/exec.sh -n dnode1 -s start - -sleep 2000 sql connect $dbPrefix = m_mu_db @@ -71,9 +67,7 @@ sql select a + a from $tb where ts > now + 4m order by ts desc sql select a + c from $tb where ts < now + 4m order by ts asc -sql select a + f from $tb where ts > now + 4m order by ts asc -x step24 - return -1 -step24: +sql select a + f from $tb where ts > now + 4m order by ts asc print =============== step3 $i = 1 @@ -150,17 +144,11 @@ endi print =============== step6 $i = 1 $tb = $tbPrefix . $i -sql select a + ts from $tb -x step61 - return -1 -step61: +sql select a + ts from $tb -sql select a + f from $tb -x step62 - return -1 -step62: +sql select a + f from $tb -sql select a + g from $tb -x step63 - return -1 -step63: +sql select a + g from $tb print =============== step7 $i = 1 @@ -202,14 +190,12 @@ sql select a + a from $tb where e = 2 and ts > now + 4m order by ts desc sql select a + c from $tb where f = 2 and ts < now + 4m order by ts asc -sql select a + f from $tb where g = 2 and ts > now + 4m order by ts asc -x step74 - return -1 -step74: +sql select a + f from $tb where g = 2 and ts > now + 4m order by ts asc print =============== clear sql drop database $db sql show databases -if $rows != 0 then +if $rows != 2 then return -1 endi diff --git a/tests/script/general/vector/single.sim b/tests/script/tsim/vector/single.sim similarity index 96% rename from tests/script/general/vector/single.sim rename to tests/script/tsim/vector/single.sim index e979a0ffb7..c9d794456c 100644 --- a/tests/script/general/vector/single.sim +++ b/tests/script/tsim/vector/single.sim @@ -1,10 +1,6 @@ system sh/stop_dnodes.sh - system sh/deploy.sh -n dnode1 -i 1 -system sh/cfg.sh -n dnode1 -c walLevel -v 1 system sh/exec.sh -n dnode1 -s start - -sleep 2000 sql connect $dbPrefix = m_si_db @@ -150,9 +146,7 @@ $i = 11 $tb = $tbPrefix . $i sql create table $tb (ts timestamp, tbcol bool) sql insert into $tb values(now, 0) -sql select tbcol + 2 from $tb -x step6 - return -1 -step6: +sql select tbcol + 2 from $tb print =============== step7 $i = $i + 1 @@ -289,14 +283,12 @@ $i = $i + 1 $tb = $tbPrefix . $i sql create table $tb (ts timestamp, tbcol binary(100)) sql insert into $tb values(now, '0'); -sql select tbcol + 2 from $tb -x step12 - return -1 -step12: +sql select tbcol + 2 from $tb print =============== clear sql drop database $db sql show databases -if $rows != 0 then +if $rows != 2 then return -1 endi diff --git a/tests/script/general/vector/table_field.sim b/tests/script/tsim/vector/table_field.sim similarity index 97% rename from tests/script/general/vector/table_field.sim rename to tests/script/tsim/vector/table_field.sim index d86eb99331..5ad60b2a35 100644 --- a/tests/script/general/vector/table_field.sim +++ b/tests/script/tsim/vector/table_field.sim @@ -1,10 +1,6 @@ system sh/stop_dnodes.sh - system sh/deploy.sh -n dnode1 -i 1 -system sh/cfg.sh -n dnode1 -c walLevel -v 1 system sh/exec.sh -n dnode1 -s start - -sleep 2000 sql connect $dbPrefix = m_tf_db @@ -95,17 +91,11 @@ if $data00 != 0.000000000 then return -1 endi -sql select g - f from $tb where a = 5 -x step21 - return -1 -step21: +sql select g - f from $tb where a = 5 -sql select h - f from $tb where a = 5 -x step22 - return -1 -step22: +sql select h - f from $tb where a = 5 -sql select ts - f from $tb where a = 5 -x step23 - return -1 -step23: +sql select ts - f from $tb where a = 5 sql select a - e from $tb where a = 5 print ===> $data00 @@ -612,7 +602,7 @@ step63: print =============== clear sql drop database $db sql show databases -if $rows != 0 then +if $rows != 2 then return -1 endi diff --git a/tests/script/general/vector/table_mix.sim b/tests/script/tsim/vector/table_mix.sim similarity index 98% rename from tests/script/general/vector/table_mix.sim rename to tests/script/tsim/vector/table_mix.sim index 5c4fb52888..358d6cf87f 100644 --- a/tests/script/general/vector/table_mix.sim +++ b/tests/script/tsim/vector/table_mix.sim @@ -1,10 +1,6 @@ system sh/stop_dnodes.sh - system sh/deploy.sh -n dnode1 -i 1 -system sh/cfg.sh -n dnode1 -c walLevel -v 1 system sh/exec.sh -n dnode1 -s start - -sleep 2000 sql connect $dbPrefix = m_tm_db @@ -95,17 +91,11 @@ if $data00 != 0.000000000 then return -1 endi -sql select g - f from $tb where a = 5 and ts > now + 4m and ts < now + 6m -x step21 - return -1 -step21: +sql select g - f from $tb where a = 5 and ts > now + 4m and ts < now + 6m -sql select h - f from $tb where a = 5 and ts > now + 4m and ts < now + 6m -x step22 - return -1 -step22: +sql select h - f from $tb where a = 5 and ts > now + 4m and ts < now + 6m -sql select ts - f from $tb where a = 5 and ts > now + 4m and ts < now + 6m -x step23 - return -1 -step23: +sql select ts - f from $tb where a = 5 and ts > now + 4m and ts < now + 6m sql select a - e from $tb where a = 5 and ts > now + 4m and ts < now + 6m print ===> $data00 @@ -612,7 +602,7 @@ step63: print =============== clear sql drop database $db sql show databases -if $rows != 0 then +if $rows != 2 then return -1 endi diff --git a/tests/script/general/vector/table_query.sim b/tests/script/tsim/vector/table_query.sim similarity index 97% rename from tests/script/general/vector/table_query.sim rename to tests/script/tsim/vector/table_query.sim index 9ef18255a9..0e4562716e 100644 --- a/tests/script/general/vector/table_query.sim +++ b/tests/script/tsim/vector/table_query.sim @@ -1,10 +1,6 @@ system sh/stop_dnodes.sh - system sh/deploy.sh -n dnode1 -i 1 -system sh/cfg.sh -n dnode1 -c walLevel -v 1 system sh/exec.sh -n dnode1 -s start - -sleep 2000 sql connect $dbPrefix = m_tq_db @@ -95,17 +91,11 @@ if $data00 != 0.000000000 then return -1 endi -sql select g - f from $tb -x step21 - return -1 -step21: +sql select g - f from $tb -sql select h - f from $tb -x step22 - return -1 -step22: +sql select h - f from $tb -sql select ts - f from $tb -x step23 - return -1 -step23: +sql select ts - f from $tb sql select a - e from $tb print ===> $data00 @@ -612,7 +602,7 @@ step63: print =============== clear sql drop database $db sql show databases -if $rows != 0 then +if $rows != 2 then return -1 endi diff --git a/tests/script/general/vector/table_time.sim b/tests/script/tsim/vector/table_time.sim similarity index 97% rename from tests/script/general/vector/table_time.sim rename to tests/script/tsim/vector/table_time.sim index c38546b117..1e6bdb2cde 100644 --- a/tests/script/general/vector/table_time.sim +++ b/tests/script/tsim/vector/table_time.sim @@ -1,10 +1,6 @@ system sh/stop_dnodes.sh - system sh/deploy.sh -n dnode1 -i 1 -system sh/cfg.sh -n dnode1 -c walLevel -v 1 system sh/exec.sh -n dnode1 -s start - -sleep 2000 sql connect $dbPrefix = m_tt_db @@ -95,17 +91,11 @@ if $data00 != 0.000000000 then return -1 endi -sql select g - f from $tb where ts > now + 4m and ts < now + 6m -x step21 - return -1 -step21: +sql select g - f from $tb where ts > now + 4m and ts < now + 6m -sql select h - f from $tb where ts > now + 4m and ts < now + 6m -x step22 - return -1 -step22: +sql select h - f from $tb where ts > now + 4m and ts < now + 6m -sql select ts - f from $tb where ts > now + 4m and ts < now + 6m -x step23 - return -1 -step23: +sql select ts - f from $tb where ts > now + 4m and ts < now + 6m sql select a - e from $tb where ts > now + 4m and ts < now + 6m print ===> $data00 @@ -612,7 +602,7 @@ step63: print =============== clear sql drop database $db sql show databases -if $rows != 0 then +if $rows != 2 then return -1 endi -- GitLab From ad051d4e65962ac1bb670210d0c0a9b99bbae88f Mon Sep 17 00:00:00 2001 From: dapan1121 Date: Wed, 13 Jul 2022 20:25:16 +0800 Subject: [PATCH 086/153] fix: fix stop query issue --- source/client/inc/clientInt.h | 1 + source/client/src/clientImpl.c | 3 ++- source/client/src/clientMain.c | 43 +++++++++++++++++----------------- tests/script/api/stopquery.c | 9 ++++--- 4 files changed, 30 insertions(+), 26 deletions(-) diff --git a/source/client/inc/clientInt.h b/source/client/inc/clientInt.h index 700a4d9daf..367e656f06 100644 --- a/source/client/inc/clientInt.h +++ b/source/client/inc/clientInt.h @@ -181,6 +181,7 @@ typedef struct SRequestSendRecvBody { tsem_t rspSem; // not used now __taos_async_fn_t queryFp; __taos_async_fn_t fetchFp; + EQueryExecMode execMode; void* param; SDataBuf requestMsg; int64_t queryJob; // query job, created according to sql query DAG. diff --git a/source/client/src/clientImpl.c b/source/client/src/clientImpl.c index d923929c95..d846cb93af 100644 --- a/source/client/src/clientImpl.c +++ b/source/client/src/clientImpl.c @@ -933,6 +933,8 @@ SRequestObj* launchQuery(uint64_t connId, const char* sql, int sqlLen, bool vali void launchAsyncQuery(SRequestObj* pRequest, SQuery* pQuery, SMetaData* pResultMeta) { int32_t code = 0; + pRequest->body.execMode = pQuery->execMode; + switch (pQuery->execMode) { case QUERY_EXEC_MODE_LOCAL: asyncExecLocalCmd(pRequest, pQuery); @@ -1149,7 +1151,6 @@ STscObj* taosConnectImpl(const char* user, const char* auth, const char* db, __t SRequestObj* pRequest = createRequest(pTscObj->id, TDMT_MND_CONNECT); if (pRequest == NULL) { destroyTscObj(pTscObj); - terrno = TSDB_CODE_TSC_OUT_OF_MEMORY; return NULL; } diff --git a/source/client/src/clientMain.c b/source/client/src/clientMain.c index 73def5b9b1..14a431feab 100644 --- a/source/client/src/clientMain.c +++ b/source/client/src/clientMain.c @@ -49,7 +49,7 @@ int taos_options(TSDB_OPTION option, const void *arg, ...) { } // this function may be called by user or system, or by both simultaneously. void taos_cleanup(void) { - tscInfo("start to cleanup client environment"); + tscDebug("start to cleanup client environment"); if (atomic_val_compare_exchange_32(&sentinel, TSC_VAR_NOT_RELEASE, TSC_VAR_RELEASED) != TSC_VAR_NOT_RELEASE) { return; } @@ -58,7 +58,10 @@ void taos_cleanup(void) { clientReqRefPool = -1; taosCloseRef(id); - cleanupTaskQueue(); + hbMgrCleanUp(); + + catalogDestroy(); + schedulerDestroy(); fmFuncMgtDestroy(); qCleanupKeywordsTable(); @@ -67,12 +70,11 @@ void taos_cleanup(void) { clientConnRefPool = -1; taosCloseRef(id); - hbMgrCleanUp(); + rpcCleanup(); + tscDebug("rpc cleanup"); - catalogDestroy(); - schedulerDestroy(); + cleanupTaskQueue(); - rpcCleanup(); tscInfo("all local resources released"); taosCleanupCfg(); taosCloseLog(); @@ -852,27 +854,24 @@ void taos_fetch_rows_a(TAOS_RES *res, __taos_async_fn_t fp, void *param) { } // all data has returned to App already, no need to try again - if (pResultInfo->completed && (pRequest->body.queryJob != 0)) { - pResultInfo->numOfRows = 0; - pRequest->body.fetchFp(param, pRequest, pResultInfo->numOfRows); - return; - } - - // it is a local executed query, no need to do async fetch - if (pRequest->body.queryJob == 0) { - ASSERT(pResultInfo->completed && pResultInfo->numOfRows >= 0); - if (pResultInfo->localResultFetched) { - pResultInfo->numOfRows = 0; - pResultInfo->current = 0; - pRequest->body.fetchFp(param, pRequest, pResultInfo->numOfRows); + if (pResultInfo->completed) { + // it is a local executed query, no need to do async fetch + if (QUERY_EXEC_MODE_LOCAL == pRequest->body.execMode) { + ASSERT(pResultInfo->numOfRows >= 0); + if (pResultInfo->localResultFetched) { + pResultInfo->numOfRows = 0; + pResultInfo->current = 0; + } else { + pResultInfo->localResultFetched = true; + } } else { - pResultInfo->localResultFetched = true; - pRequest->body.fetchFp(param, pRequest, pResultInfo->numOfRows); + pResultInfo->numOfRows = 0; } + + pRequest->body.fetchFp(param, pRequest, pResultInfo->numOfRows); return; } - SSchedulerReq req = { .syncReq = false, .fetchFp = fetchCallback, diff --git a/tests/script/api/stopquery.c b/tests/script/api/stopquery.c index 92baf43d85..082d987a22 100644 --- a/tests/script/api/stopquery.c +++ b/tests/script/api/stopquery.c @@ -633,6 +633,7 @@ int sqConCleanupSyncQuery(bool fetch) { pthread_join(qid, NULL); pthread_join(cid, NULL); + break; } CASE_LEAVE(); } @@ -648,6 +649,7 @@ int sqConCleanupAsyncQuery(bool fetch) { pthread_join(qid, NULL); pthread_join(cid, NULL); + break; } CASE_LEAVE(); } @@ -655,7 +657,7 @@ int sqConCleanupAsyncQuery(bool fetch) { void sqRunAllCase(void) { -#if 0 +#if 1 sqStopSyncQuery(false); sqStopSyncQuery(true); sqStopAsyncQuery(false); @@ -688,16 +690,17 @@ void sqRunAllCase(void) { sqConKillAsyncQuery(true); #endif + /* sqConCleanupSyncQuery(false); sqConCleanupSyncQuery(true); sqConCleanupAsyncQuery(false); sqConCleanupAsyncQuery(true); - + */ int32_t l = 5; while (l) { printf("%d\n", l--); - sleep(1000); + sleep(1); } } -- GitLab From 56ec0a3920dc66f005d381e7dabc90f347747ac2 Mon Sep 17 00:00:00 2001 From: wangmm0220 Date: Wed, 13 Jul 2022 20:42:49 +0800 Subject: [PATCH 087/153] fix: json null --- source/client/src/tmq.c | 11 ++++++++--- source/libs/parser/src/parTranslater.c | 3 --- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/source/client/src/tmq.c b/source/client/src/tmq.c index 2741ea0670..ad47348c22 100644 --- a/source/client/src/tmq.c +++ b/source/client/src/tmq.c @@ -2269,7 +2269,12 @@ static char *processAlterTable(SMqMetaRsp *metaRsp){ cJSON* tagName = cJSON_CreateString(vAlterTbReq.tagName); cJSON_AddItemToObject(json, "colName", tagName); - if (!vAlterTbReq.isNull){ + bool isNull = vAlterTbReq.isNull; + if(vAlterTbReq.tagType == TSDB_DATA_TYPE_JSON){ + STag *jsonTag = (STag *)vAlterTbReq.pTagVal; + if(jsonTag->nTag == 0) isNull = true; + } + if (!isNull){ char* buf = NULL; if (vAlterTbReq.tagType == TSDB_DATA_TYPE_JSON) { @@ -2285,8 +2290,8 @@ static char *processAlterTable(SMqMetaRsp *metaRsp){ taosMemoryFree(buf); } - cJSON* isNull = cJSON_CreateBool(vAlterTbReq.isNull); - cJSON_AddItemToObject(json, "colValueNull", isNull); + cJSON* isNullCJson = cJSON_CreateBool(isNull); + cJSON_AddItemToObject(json, "colValueNull", isNullCJson); break; } default: diff --git a/source/libs/parser/src/parTranslater.c b/source/libs/parser/src/parTranslater.c index 6654bc26cd..a8fbc8d7ab 100644 --- a/source/libs/parser/src/parTranslater.c +++ b/source/libs/parser/src/parTranslater.c @@ -5872,9 +5872,6 @@ static int32_t buildUpdateTagValReq(STranslateContext* pCxt, SAlterTableStmt* pS if (code != TSDB_CODE_SUCCESS) { return code; } - if(pTag->nTag == 0){ - pReq->isNull = true; - } pReq->nTagVal = pTag->len; pReq->pTagVal = (uint8_t*)pTag; pStmt->pVal->datum.p = (char*)pTag; // for free -- GitLab From 176379dfab513a920451f54beab4af6a002425d4 Mon Sep 17 00:00:00 2001 From: Shengliang Guan Date: Wed, 13 Jul 2022 20:44:32 +0800 Subject: [PATCH 088/153] test: restore some 2.0 case --- tests/script/general/wal/maxtables.sim | 46 ------ tests/script/general/wal/sync.sim | 146 -------------------- tests/script/jenkins/basic.txt | 3 + tests/script/{general => tsim}/wal/kill.sim | 25 +--- 4 files changed, 10 insertions(+), 210 deletions(-) delete mode 100644 tests/script/general/wal/maxtables.sim delete mode 100644 tests/script/general/wal/sync.sim rename tests/script/{general => tsim}/wal/kill.sim (73%) diff --git a/tests/script/general/wal/maxtables.sim b/tests/script/general/wal/maxtables.sim deleted file mode 100644 index acd6af1d1a..0000000000 --- a/tests/script/general/wal/maxtables.sim +++ /dev/null @@ -1,46 +0,0 @@ -system sh/stop_dnodes.sh -system sh/deploy.sh -n dnode1 -i 1 -system sh/cfg.sh -n dnode1 -c maxTablesPerVnode -v 100 -system sh/cfg.sh -n dnode1 -c maxVgroupsPerDb -v 1 -system sh/cfg.sh -n dnode1 -c tableIncStepPerVnode -v 2 - - -print ============== deploy -system sh/exec.sh -n dnode1 -s start -sleep 3001 -sql connect - -sql create database d1 -sql use d1 -sql create table st (ts timestamp, tbcol int) TAGS(tgcol int) - -$i = 0 -while $i < 100 - $tb = t . $i - sql create table $tb using st tags( $i ) - sql insert into $tb values (now , $i ) - $i = $i + 1 -endw - -sql_error sql create table tt (ts timestamp, i int) - -print =============== step3 -sql select * from st; -if $rows != 100 then - return -1 -endi - -system sh/exec.sh -n dnode1 -s stop -x SIGINT -system sh/cfg.sh -n dnode1 -c maxTablesPerVnode -v 4 -sleep 2000 - -print =============== step4 -system sh/exec.sh -n dnode1 -s start -sleep 2000 - -sql select * from st; -if $rows != 100 then - return -1 -endi - -system sh/exec.sh -n dnode1 -s stop -x SIGINT diff --git a/tests/script/general/wal/sync.sim b/tests/script/general/wal/sync.sim deleted file mode 100644 index 3a89523918..0000000000 --- a/tests/script/general/wal/sync.sim +++ /dev/null @@ -1,146 +0,0 @@ -system sh/stop_dnodes.sh - -system sh/deploy.sh -n dnode1 -i 1 -system sh/deploy.sh -n dnode2 -i 2 -system sh/deploy.sh -n dnode3 -i 3 - -system sh/cfg.sh -n dnode1 -c numOfMnodes -v 3 -system sh/cfg.sh -n dnode2 -c numOfMnodes -v 3 -system sh/cfg.sh -n dnode3 -c numOfMnodes -v 3 - -system sh/cfg.sh -n dnode1 -c mnodeEqualVnodeNum -v 4 -system sh/cfg.sh -n dnode2 -c mnodeEqualVnodeNum -v 4 -system sh/cfg.sh -n dnode3 -c mnodeEqualVnodeNum -v 4 - -system sh/cfg.sh -n dnode1 -c http -v 1 -system sh/cfg.sh -n dnode2 -c http -v 1 -system sh/cfg.sh -n dnode3 -c http -v 1 - -system sh/cfg.sh -n dnode1 -c maxTablesPerVnode -v 20000 -system sh/cfg.sh -n dnode2 -c maxTablesPerVnode -v 20000 -system sh/cfg.sh -n dnode3 -c maxTablesPerVnode -v 20000 - -system sh/cfg.sh -n dnode1 -c replica -v 3 -system sh/cfg.sh -n dnode2 -c replica -v 3 -system sh/cfg.sh -n dnode3 -c replica -v 3 - -system sh/cfg.sh -n dnode1 -c maxSQLLength -v 940032 -system sh/cfg.sh -n dnode2 -c maxSQLLength -v 940032 -system sh/cfg.sh -n dnode3 -c maxSQLLength -v 940032 - -print ============== deploy - -system sh/exec.sh -n dnode1 -s start -sql connect - -sql create dnode $hostname2 -sql create dnode $hostname3 -system sh/exec.sh -n dnode2 -s start -system sh/exec.sh -n dnode3 -s start - -print =============== step1 -$x = 0 -show1: - $x = $x + 1 - sleep 1000 - if $x == 10 then - return -1 - endi -sql show mnodes -x show1 -$mnode1Role = $data2_1 -print mnode1Role $mnode1Role -$mnode2Role = $data2_2 -print mnode2Role $mnode2Role -$mnode3Role = $data2_3 -print mnode3Role $mnode3Role - -if $mnode1Role != master then - goto show1 -endi -if $mnode2Role != slave then - goto show1 -endi -if $mnode3Role != slave then - goto show1 -endi - -print =============== step2 -sql create database d1 replica 3 -sql use d1 - -sql create table table_rest (ts timestamp, i int) -print sql length is 870KB -restful d1 table_rest 1591072800 30000 -restful d1 table_rest 1591172800 30000 -restful d1 table_rest 1591272800 30000 -restful d1 table_rest 1591372800 30000 -restful d1 table_rest 1591472800 30000 -restful d1 table_rest 1591572800 30000 -restful d1 table_rest 1591672800 30000 -restful d1 table_rest 1591772800 30000 -restful d1 table_rest 1591872800 30000 -restful d1 table_rest 1591972800 30000 - -sleep 100 -sql select * from table_rest; -print rows: $rows -if $rows != 300000 then - return -1 -endi - -print =============== step3 -system sh/exec.sh -n dnode1 -s stop -x SIGINT -sql select * from table_rest; -print rows: $rows -if $rows != 300000 then - return -1 -endi -system sh/exec.sh -n dnode1 -s start -x SIGINT - -$x = 0 -a1: - $x = $x + 1 - sleep 1000 - if $x == 40 then - return -1 - endi - -sql show vgroups -print online vnodes $data03 -if $data03 != 3 then - goto a1 -endi - -print =============== step4 -system sh/exec.sh -n dnode2 -s stop -x SIGINT -sql select * from table_rest; -print rows: $rows -if $rows != 300000 then - return -1 -endi -system sh/exec.sh -n dnode2 -s start -x SIGINT -$x = 0 -a2: - $x = $x + 1 - sleep 1000 - if $x == 40 then - return -1 - endi - -sql show vgroups -print online vnodes $data03 -if $data03 != 3 then - goto a2 -endi - -print =============== step5 -system sh/exec.sh -n dnode3 -s stop -x SIGINT -sql select * from table_rest; -print rows: $rows -if $rows != 300000 then - return -1 -endi - -system sh/exec.sh -n dnode1 -s stop -x SIGINT -system sh/exec.sh -n dnode2 -s stop -x SIGINT -system sh/exec.sh -n dnode3 -s stop -x SIGINT \ No newline at end of file diff --git a/tests/script/jenkins/basic.txt b/tests/script/jenkins/basic.txt index 5f87b8a55f..c88b5e2b78 100644 --- a/tests/script/jenkins/basic.txt +++ b/tests/script/jenkins/basic.txt @@ -275,4 +275,7 @@ ./test.sh -f tsim/vector/table_query.sim ./test.sh -f tsim/vector/table_time.sim +# ---- wal +./test.sh -f tsim/wal/kill.sim + #======================b1-end=============== diff --git a/tests/script/general/wal/kill.sim b/tests/script/tsim/wal/kill.sim similarity index 73% rename from tests/script/general/wal/kill.sim rename to tests/script/tsim/wal/kill.sim index 94a35b636e..f8a732f59f 100644 --- a/tests/script/general/wal/kill.sim +++ b/tests/script/tsim/wal/kill.sim @@ -2,8 +2,7 @@ system sh/stop_dnodes.sh system sh/deploy.sh -n dnode1 -i 1 print ============== deploy -system sh/exec.sh -n dnode1 -s start -sleep 3001 +system sh/exec.sh -n dnode1 -s start ] sql connect sql create database d1 @@ -13,65 +12,55 @@ sql create table t1 (ts timestamp, i int) sql insert into t1 values(now, 1); print =============== step3 -sleep 2000 sql select * from t1; print rows: $rows if $rows != 1 then return -1 endi system sh/exec.sh -n dnode1 -s stop -x SIGKILL -sleep 2000 print =============== step4 -system sh/exec.sh -n dnode1 -s start -x SIGKILL -sleep 2000 +system sh/exec.sh -n dnode1 -s start sql select * from t1; print rows: $rows if $rows != 1 then return -1 endi system sh/exec.sh -n dnode1 -s stop -x SIGKILL -sleep 2000 print =============== step5 -system sh/exec.sh -n dnode1 -s start -x SIGKILL -sleep 2000 +system sh/exec.sh -n dnode1 -s start sql select * from t1; print rows: $rows if $rows != 1 then return -1 endi system sh/exec.sh -n dnode1 -s stop -x SIGKILL -sleep 2000 print =============== step6 -system sh/exec.sh -n dnode1 -s start -x SIGKILL -sleep 2000 +system sh/exec.sh -n dnode1 -s start sql select * from t1; print rows: $rows if $rows != 1 then return -1 endi system sh/exec.sh -n dnode1 -s stop -x SIGKILL -sleep 2000 print =============== step7 -system sh/exec.sh -n dnode1 -s start -x SIGKILL -sleep 2000 +system sh/exec.sh -n dnode1 -s start sql select * from t1; print rows: $rows if $rows != 1 then return -1 endi system sh/exec.sh -n dnode1 -s stop -x SIGKILL -sleep 2000 print =============== step8 -system sh/exec.sh -n dnode1 -s start -x SIGKILL -sleep 2000 +system sh/exec.sh -n dnode1 -s start sql select * from t1; print rows: $rows if $rows != 1 then return -1 endi + system sh/exec.sh -n dnode1 -s stop -x SIGKILL -- GitLab From f7ea72b0a633d34bab06e56137ecff4fcc8ec7cd Mon Sep 17 00:00:00 2001 From: Shengliang Guan Date: Wed, 13 Jul 2022 20:47:31 +0800 Subject: [PATCH 089/153] test: restore some 2.0 case --- tests/script/general/stream/agg_stream.sim | 316 ------------------ tests/script/general/stream/column_stream.sim | 200 ----------- tests/script/general/stream/metrics_del.sim | 95 ------ .../stream/metrics_replica1_vnoden.sim | 245 -------------- .../script/general/stream/restart_stream.sim | 176 ---------- tests/script/general/stream/stream_1970.sim | 73 ---- tests/script/general/stream/stream_3.sim | 201 ----------- .../script/general/stream/stream_restart.sim | 142 -------- tests/script/general/stream/table_del.sim | 90 ----- .../general/stream/table_replica1_vnoden.sim | 299 ----------------- tests/script/general/stream/testSuite.sim | 6 - 11 files changed, 1843 deletions(-) delete mode 100644 tests/script/general/stream/agg_stream.sim delete mode 100644 tests/script/general/stream/column_stream.sim delete mode 100644 tests/script/general/stream/metrics_del.sim delete mode 100644 tests/script/general/stream/metrics_replica1_vnoden.sim delete mode 100644 tests/script/general/stream/restart_stream.sim delete mode 100644 tests/script/general/stream/stream_1970.sim delete mode 100644 tests/script/general/stream/stream_3.sim delete mode 100644 tests/script/general/stream/stream_restart.sim delete mode 100644 tests/script/general/stream/table_del.sim delete mode 100644 tests/script/general/stream/table_replica1_vnoden.sim delete mode 100644 tests/script/general/stream/testSuite.sim diff --git a/tests/script/general/stream/agg_stream.sim b/tests/script/general/stream/agg_stream.sim deleted file mode 100644 index 548f59cab7..0000000000 --- a/tests/script/general/stream/agg_stream.sim +++ /dev/null @@ -1,316 +0,0 @@ -system sh/stop_dnodes.sh - - -system sh/deploy.sh -n dnode1 -i 1 -system sh/cfg.sh -n dnode1 -c wallevel -v 0 - -print ========== step1 -system sh/cfg.sh -n dnode1 -c monitor -v 1 -system sh/cfg.sh -n dnode1 -c monitorInterval -v 1 -system sh/cfg.sh -n dnode1 -c maxVnodeConnections -v 30000 -system sh/cfg.sh -n dnode1 -c maxMgmtConnections -v 30000 -system sh/cfg.sh -n dnode1 -c maxMeterConnections -v 30000 -system sh/cfg.sh -n dnode1 -c maxShellConns -v 30000 -system sh/exec.sh -n dnode1 -s start - -sleep 2000 -sql connect - -print =============== step2 -sql create database d4 precision 'us' -sql use d4 -sql create table t1 (ts timestamp, i int) -sql insert into d4.t1 values(1626739200000, 1) - -sql create table d4.s001 as select count(cpu_taosd), count(cpu_system), avg(cpu_taosd), avg(cpu_system), sum(cpu_taosd), max(cpu_taosd), min(cpu_taosd) from log.dn_192_168_0_1 interval(5s) -sql create table d4.s002 as select count(mem_taosd), count(mem_system), avg(mem_taosd), avg(mem_system), sum(mem_taosd), max(mem_taosd), min(mem_taosd) from log.dn_192_168_0_1 interval(5s) -sql create table d4.s003 as select count(disk_used), count(disk_total), avg(disk_used), avg(disk_total), sum(disk_used), max(disk_used), min(disk_used) from log.dn_192_168_0_1 interval(5s) -sql create table d4.s004 as select count(io_read), count(io_write), avg(io_read), avg(io_write), sum(io_read), max(io_write), min(io_read) from log.dn_192_168_0_1 interval(5s) -sql create table d4.s005 as select count(band_speed), avg(band_speed), sum(band_speed), max(band_speed), min(band_speed) from log.dn_192_168_0_1 interval(5s) -sql create table d4.s006 as select count(req_http), count(req_insert), avg(req_select), sum(req_insert), max(req_select), min(req_insert) from log.dn_192_168_0_1 interval(5s) -sql create table d4.s007 as select count(cpu_taosd), count(cpu_system), avg(cpu_taosd), avg(cpu_system), sum(cpu_taosd), max(cpu_taosd), min(cpu_taosd) from log.dn interval(5s) -sql create table d4.s008 as select count(mem_taosd), count(mem_system), avg(mem_taosd), avg(mem_system), sum(mem_taosd), max(mem_taosd), min(mem_taosd) from log.dn interval(5s) -sql create table d4.s009 as select count(disk_used), count(disk_total), avg(disk_used), avg(disk_total), sum(disk_used), max(disk_used), min(disk_used) from log.dn interval(5s) -sql create table d4.s000 as select count(io_read), count(io_write), avg(io_read), avg(io_write), sum(io_read), max(io_write), min(io_read) from log.dn interval(5s) - -sql create table d4.s011 as select count(cpu_taosd), count(cpu_system), avg(cpu_taosd), avg(cpu_system), sum(cpu_taosd), max(cpu_taosd), min(cpu_taosd) from log.dn_192_168_0_1 interval(5s) -sql create table d4.s012 as select count(mem_taosd), count(mem_system), avg(mem_taosd), avg(mem_system), sum(mem_taosd), max(mem_taosd), min(mem_taosd) from log.dn_192_168_0_1 interval(5s) -sql create table d4.s013 as select count(disk_used), count(disk_total), avg(disk_used), avg(disk_total), sum(disk_used), max(disk_used), min(disk_used) from log.dn_192_168_0_1 interval(5s) -sql create table d4.s014 as select count(io_read), count(io_write), avg(io_read), avg(io_write), sum(io_read), max(io_write), min(io_read) from log.dn_192_168_0_1 interval(5s) -sql create table d4.s015 as select count(band_speed), avg(band_speed), sum(band_speed), max(band_speed), min(band_speed) from log.dn_192_168_0_1 interval(5s) -sql create table d4.s016 as select count(req_http), count(req_insert), avg(req_select), sum(req_insert), max(req_select), min(req_insert) from log.dn_192_168_0_1 interval(5s) -sql create table d4.s017 as select count(cpu_taosd), count(cpu_system), avg(cpu_taosd), avg(cpu_system), sum(cpu_taosd), max(cpu_taosd), min(cpu_taosd) from log.dn interval(5s) -sql create table d4.s018 as select count(mem_taosd), count(mem_system), avg(mem_taosd), avg(mem_system), sum(mem_taosd), max(mem_taosd), min(mem_taosd) from log.dn interval(5s) -sql create table d4.s019 as select count(disk_used), count(disk_total), avg(disk_used), avg(disk_total), sum(disk_used), max(disk_used), min(disk_used) from log.dn interval(5s) -sql create table d4.s010 as select count(io_read), count(io_write), avg(io_read), avg(io_write), sum(io_read), max(io_write), min(io_read) from log.dn interval(5s) - -sql create table d4.s021 as select count(cpu_taosd), count(cpu_system), avg(cpu_taosd), avg(cpu_system), sum(cpu_taosd), max(cpu_taosd), min(cpu_taosd) from log.dn_192_168_0_1 interval(5s) -sql create table d4.s022 as select count(mem_taosd), count(mem_system), avg(mem_taosd), avg(mem_system), sum(mem_taosd), max(mem_taosd), min(mem_taosd) from log.dn_192_168_0_1 interval(5s) -sql create table d4.s023 as select count(disk_used), count(disk_total), avg(disk_used), avg(disk_total), sum(disk_used), max(disk_used), min(disk_used) from log.dn_192_168_0_1 interval(5s) -sql create table d4.s024 as select count(io_read), count(io_write), avg(io_read), avg(io_write), sum(io_read), max(io_write), min(io_read) from log.dn_192_168_0_1 interval(5s) -sql create table d4.s025 as select count(band_speed), avg(band_speed), sum(band_speed), max(band_speed), min(band_speed) from log.dn_192_168_0_1 interval(5s) -sql create table d4.s026 as select count(req_http), count(req_insert), avg(req_select), sum(req_insert), max(req_select), min(req_insert) from log.dn_192_168_0_1 interval(5s) -sql create table d4.s027 as select count(cpu_taosd), count(cpu_system), avg(cpu_taosd), avg(cpu_system), sum(cpu_taosd), max(cpu_taosd), min(cpu_taosd) from log.dn interval(5s) -sql create table d4.s028 as select count(mem_taosd), count(mem_system), avg(mem_taosd), avg(mem_system), sum(mem_taosd), max(mem_taosd), min(mem_taosd) from log.dn interval(5s) -sql create table d4.s029 as select count(disk_used), count(disk_total), avg(disk_used), avg(disk_total), sum(disk_used), max(disk_used), min(disk_used) from log.dn interval(5s) -sql create table d4.s020 as select count(io_read), count(io_write), avg(io_read), avg(io_write), sum(io_read), max(io_write), min(io_read) from log.dn interval(5s) - -sql create table d4.s031 as select count(cpu_taosd), count(cpu_system), avg(cpu_taosd), avg(cpu_system), sum(cpu_taosd), max(cpu_taosd), min(cpu_taosd) from log.dn_192_168_0_1 interval(5s) -sql create table d4.s032 as select count(mem_taosd), count(mem_system), avg(mem_taosd), avg(mem_system), sum(mem_taosd), max(mem_taosd), min(mem_taosd) from log.dn_192_168_0_1 interval(5s) -sql create table d4.s033 as select count(disk_used), count(disk_total), avg(disk_used), avg(disk_total), sum(disk_used), max(disk_used), min(disk_used) from log.dn_192_168_0_1 interval(5s) -sql create table d4.s034 as select count(io_read), count(io_write), avg(io_read), avg(io_write), sum(io_read), max(io_write), min(io_read) from log.dn_192_168_0_1 interval(5s) -sql create table d4.s035 as select count(band_speed), avg(band_speed), sum(band_speed), max(band_speed), min(band_speed) from log.dn_192_168_0_1 interval(5s) -sql create table d4.s036 as select count(req_http), count(req_insert), avg(req_select), sum(req_insert), max(req_select), min(req_insert) from log.dn_192_168_0_1 interval(5s) -sql create table d4.s037 as select count(cpu_taosd), count(cpu_system), avg(cpu_taosd), avg(cpu_system), sum(cpu_taosd), max(cpu_taosd), min(cpu_taosd) from log.dn interval(5s) -sql create table d4.s038 as select count(mem_taosd), count(mem_system), avg(mem_taosd), avg(mem_system), sum(mem_taosd), max(mem_taosd), min(mem_taosd) from log.dn interval(5s) -sql create table d4.s039 as select count(disk_used), count(disk_total), avg(disk_used), avg(disk_total), sum(disk_used), max(disk_used), min(disk_used) from log.dn interval(5s) -sql create table d4.s030 as select count(io_read), count(io_write), avg(io_read), avg(io_write), sum(io_read), max(io_write), min(io_read) from log.dn interval(5s) - -sql create table d4.s041 as select count(cpu_taosd), count(cpu_system), avg(cpu_taosd), avg(cpu_system), sum(cpu_taosd), max(cpu_taosd), min(cpu_taosd) from log.dn_192_168_0_1 interval(5s) -sql create table d4.s042 as select count(mem_taosd), count(mem_system), avg(mem_taosd), avg(mem_system), sum(mem_taosd), max(mem_taosd), min(mem_taosd) from log.dn_192_168_0_1 interval(5s) -sql create table d4.s043 as select count(disk_used), count(disk_total), avg(disk_used), avg(disk_total), sum(disk_used), max(disk_used), min(disk_used) from log.dn_192_168_0_1 interval(5s) -sql create table d4.s044 as select count(io_read), count(io_write), avg(io_read), avg(io_write), sum(io_read), max(io_write), min(io_read) from log.dn_192_168_0_1 interval(5s) -sql create table d4.s045 as select count(band_speed), avg(band_speed), sum(band_speed), max(band_speed), min(band_speed) from log.dn_192_168_0_1 interval(5s) -sql create table d4.s046 as select count(req_http), count(req_insert), avg(req_select), sum(req_insert), max(req_select), min(req_insert) from log.dn_192_168_0_1 interval(5s) -sql create table d4.s047 as select count(cpu_taosd), count(cpu_system), avg(cpu_taosd), avg(cpu_system), sum(cpu_taosd), max(cpu_taosd), min(cpu_taosd) from log.dn interval(5s) -sql create table d4.s048 as select count(mem_taosd), count(mem_system), avg(mem_taosd), avg(mem_system), sum(mem_taosd), max(mem_taosd), min(mem_taosd) from log.dn interval(5s) -sql create table d4.s049 as select count(disk_used), count(disk_total), avg(disk_used), avg(disk_total), sum(disk_used), max(disk_used), min(disk_used) from log.dn interval(5s) -sql create table d4.s040 as select count(io_read), count(io_write), avg(io_read), avg(io_write), sum(io_read), max(io_write), min(io_read) from log.dn interval(5s) - -sql create table d4.s051 as select count(cpu_taosd), count(cpu_system), avg(cpu_taosd), avg(cpu_system), sum(cpu_taosd), max(cpu_taosd), min(cpu_taosd) from log.dn_192_168_0_1 interval(5s) -sql create table d4.s052 as select count(mem_taosd), count(mem_system), avg(mem_taosd), avg(mem_system), sum(mem_taosd), max(mem_taosd), min(mem_taosd) from log.dn_192_168_0_1 interval(5s) -sql create table d4.s053 as select count(disk_used), count(disk_total), avg(disk_used), avg(disk_total), sum(disk_used), max(disk_used), min(disk_used) from log.dn_192_168_0_1 interval(5s) -sql create table d4.s054 as select count(io_read), count(io_write), avg(io_read), avg(io_write), sum(io_read), max(io_write), min(io_read) from log.dn_192_168_0_1 interval(5s) -sql create table d4.s055 as select count(band_speed), avg(band_speed), sum(band_speed), max(band_speed), min(band_speed) from log.dn_192_168_0_1 interval(5s) -sql create table d4.s056 as select count(req_http), count(req_insert), avg(req_select), sum(req_insert), max(req_select), min(req_insert) from log.dn_192_168_0_1 interval(5s) -sql create table d4.s057 as select count(cpu_taosd), count(cpu_system), avg(cpu_taosd), avg(cpu_system), sum(cpu_taosd), max(cpu_taosd), min(cpu_taosd) from log.dn interval(5s) -sql create table d4.s058 as select count(mem_taosd), count(mem_system), avg(mem_taosd), avg(mem_system), sum(mem_taosd), max(mem_taosd), min(mem_taosd) from log.dn interval(5s) -sql create table d4.s059 as select count(disk_used), count(disk_total), avg(disk_used), avg(disk_total), sum(disk_used), max(disk_used), min(disk_used) from log.dn interval(5s) -sql create table d4.s050 as select count(io_read), count(io_write), avg(io_read), avg(io_write), sum(io_read), max(io_write), min(io_read) from log.dn interval(5s) - -sql create table d4.s061 as select count(cpu_taosd), count(cpu_system), avg(cpu_taosd), avg(cpu_system), sum(cpu_taosd), max(cpu_taosd), min(cpu_taosd) from log.dn_192_168_0_1 interval(5s) -sql create table d4.s062 as select count(mem_taosd), count(mem_system), avg(mem_taosd), avg(mem_system), sum(mem_taosd), max(mem_taosd), min(mem_taosd) from log.dn_192_168_0_1 interval(5s) -sql create table d4.s063 as select count(disk_used), count(disk_total), avg(disk_used), avg(disk_total), sum(disk_used), max(disk_used), min(disk_used) from log.dn_192_168_0_1 interval(5s) -sql create table d4.s064 as select count(io_read), count(io_write), avg(io_read), avg(io_write), sum(io_read), max(io_write), min(io_read) from log.dn_192_168_0_1 interval(5s) -sql create table d4.s065 as select count(band_speed), avg(band_speed), sum(band_speed), max(band_speed), min(band_speed) from log.dn_192_168_0_1 interval(5s) -sql create table d4.s066 as select count(req_http), count(req_insert), avg(req_select), sum(req_insert), max(req_select), min(req_insert) from log.dn_192_168_0_1 interval(5s) -sql create table d4.s067 as select count(cpu_taosd), count(cpu_system), avg(cpu_taosd), avg(cpu_system), sum(cpu_taosd), max(cpu_taosd), min(cpu_taosd) from log.dn interval(5s) -sql create table d4.s068 as select count(mem_taosd), count(mem_system), avg(mem_taosd), avg(mem_system), sum(mem_taosd), max(mem_taosd), min(mem_taosd) from log.dn interval(5s) -sql create table d4.s069 as select count(disk_used), count(disk_total), avg(disk_used), avg(disk_total), sum(disk_used), max(disk_used), min(disk_used) from log.dn interval(5s) -sql create table d4.s060 as select count(io_read), count(io_write), avg(io_read), avg(io_write), sum(io_read), max(io_write), min(io_read) from log.dn interval(5s) - -sql create table d4.s071 as select count(cpu_taosd), count(cpu_system), avg(cpu_taosd), avg(cpu_system), sum(cpu_taosd), max(cpu_taosd), min(cpu_taosd) from log.dn_192_168_0_1 interval(5s) -sql create table d4.s072 as select count(mem_taosd), count(mem_system), avg(mem_taosd), avg(mem_system), sum(mem_taosd), max(mem_taosd), min(mem_taosd) from log.dn_192_168_0_1 interval(5s) -sql create table d4.s073 as select count(disk_used), count(disk_total), avg(disk_used), avg(disk_total), sum(disk_used), max(disk_used), min(disk_used) from log.dn_192_168_0_1 interval(5s) -sql create table d4.s074 as select count(io_read), count(io_write), avg(io_read), avg(io_write), sum(io_read), max(io_write), min(io_read) from log.dn_192_168_0_1 interval(5s) -sql create table d4.s075 as select count(band_speed), avg(band_speed), sum(band_speed), max(band_speed), min(band_speed) from log.dn_192_168_0_1 interval(5s) -sql create table d4.s076 as select count(req_http), count(req_insert), avg(req_select), sum(req_insert), max(req_select), min(req_insert) from log.dn_192_168_0_1 interval(5s) -sql create table d4.s077 as select count(cpu_taosd), count(cpu_system), avg(cpu_taosd), avg(cpu_system), sum(cpu_taosd), max(cpu_taosd), min(cpu_taosd) from log.dn interval(5s) -sql create table d4.s078 as select count(mem_taosd), count(mem_system), avg(mem_taosd), avg(mem_system), sum(mem_taosd), max(mem_taosd), min(mem_taosd) from log.dn interval(5s) -sql create table d4.s079 as select count(disk_used), count(disk_total), avg(disk_used), avg(disk_total), sum(disk_used), max(disk_used), min(disk_used) from log.dn interval(5s) -sql create table d4.s070 as select count(io_read), count(io_write), avg(io_read), avg(io_write), sum(io_read), max(io_write), min(io_read) from log.dn interval(5s) - -sql create table d4.s081 as select count(cpu_taosd), count(cpu_system), avg(cpu_taosd), avg(cpu_system), sum(cpu_taosd), max(cpu_taosd), min(cpu_taosd) from log.dn_192_168_0_1 interval(5s) -sql create table d4.s082 as select count(mem_taosd), count(mem_system), avg(mem_taosd), avg(mem_system), sum(mem_taosd), max(mem_taosd), min(mem_taosd) from log.dn_192_168_0_1 interval(5s) -sql create table d4.s083 as select count(disk_used), count(disk_total), avg(disk_used), avg(disk_total), sum(disk_used), max(disk_used), min(disk_used) from log.dn_192_168_0_1 interval(5s) -sql create table d4.s084 as select count(io_read), count(io_write), avg(io_read), avg(io_write), sum(io_read), max(io_write), min(io_read) from log.dn_192_168_0_1 interval(5s) -sql create table d4.s085 as select count(band_speed), avg(band_speed), sum(band_speed), max(band_speed), min(band_speed) from log.dn_192_168_0_1 interval(5s) -sql create table d4.s086 as select count(req_http), count(req_insert), avg(req_select), sum(req_insert), max(req_select), min(req_insert) from log.dn_192_168_0_1 interval(5s) -sql create table d4.s087 as select count(cpu_taosd), count(cpu_system), avg(cpu_taosd), avg(cpu_system), sum(cpu_taosd), max(cpu_taosd), min(cpu_taosd) from log.dn interval(5s) -sql create table d4.s088 as select count(mem_taosd), count(mem_system), avg(mem_taosd), avg(mem_system), sum(mem_taosd), max(mem_taosd), min(mem_taosd) from log.dn interval(5s) -sql create table d4.s089 as select count(disk_used), count(disk_total), avg(disk_used), avg(disk_total), sum(disk_used), max(disk_used), min(disk_used) from log.dn interval(5s) -sql create table d4.s080 as select count(io_read), count(io_write), avg(io_read), avg(io_write), sum(io_read), max(io_write), min(io_read) from log.dn interval(5s) - -sql create table d4.s091 as select count(cpu_taosd), count(cpu_system), avg(cpu_taosd), avg(cpu_system), sum(cpu_taosd), max(cpu_taosd), min(cpu_taosd) from log.dn_192_168_0_1 interval(5s) -sql create table d4.s092 as select count(mem_taosd), count(mem_system), avg(mem_taosd), avg(mem_system), sum(mem_taosd), max(mem_taosd), min(mem_taosd) from log.dn_192_168_0_1 interval(5s) -sql create table d4.s093 as select count(disk_used), count(disk_total), avg(disk_used), avg(disk_total), sum(disk_used), max(disk_used), min(disk_used) from log.dn_192_168_0_1 interval(5s) -sql create table d4.s094 as select count(io_read), count(io_write), avg(io_read), avg(io_write), sum(io_read), max(io_write), min(io_read) from log.dn_192_168_0_1 interval(5s) -sql create table d4.s095 as select count(band_speed), avg(band_speed), sum(band_speed), max(band_speed), min(band_speed) from log.dn_192_168_0_1 interval(5s) -sql create table d4.s096 as select count(req_http), count(req_insert) , sum(req_insert), max(req_select), min(req_insert) from log.dn_192_168_0_1 interval(5s) -sql create table d4.s097 as select count(cpu_taosd), count(cpu_system), avg(cpu_taosd), avg(cpu_system), sum(cpu_taosd), max(cpu_taosd), min(cpu_taosd) from log.dn interval(5s) -sql create table d4.s098 as select count(mem_taosd), count(mem_system), avg(mem_taosd), avg(mem_system), sum(mem_taosd), max(mem_taosd), min(mem_taosd) from log.dn interval(5s) -sql create table d4.s099 as select count(disk_used), count(disk_total), avg(disk_used), avg(disk_total), sum(disk_used), max(disk_used), min(disk_used) from log.dn interval(5s) -sql create table d4.s090 as select count(io_read), count(io_write), avg(io_read), avg(io_write), sum(io_read), max(io_write), min(io_read) from log.dn interval(5s) - -print =============== step21 - -sql create table d4.s101 as select count(cpu_taosd), count(cpu_system), avg(cpu_taosd), avg(cpu_system), sum(cpu_taosd), max(cpu_taosd), min(cpu_taosd) from log.dn_192_168_0_1 interval(5s) -sql create table d4.s102 as select count(mem_taosd), count(mem_system), avg(mem_taosd), avg(mem_system), sum(mem_taosd), max(mem_taosd), min(mem_taosd) from log.dn_192_168_0_1 interval(5s) -sql create table d4.s103 as select count(disk_used), count(disk_total), avg(disk_used), avg(disk_total), sum(disk_used), max(disk_used), min(disk_used) from log.dn_192_168_0_1 interval(5s) -sql create table d4.s104 as select count(io_read), count(io_write), avg(io_read), avg(io_write), sum(io_read), max(io_write), min(io_read) from log.dn_192_168_0_1 interval(5s) -sql create table d4.s105 as select count(band_speed), avg(band_speed), sum(band_speed), max(band_speed), min(band_speed) from log.dn_192_168_0_1 interval(5s) -sql create table d4.s106 as select count(req_http), count(req_insert) , sum(req_insert), max(req_select), min(req_insert) from log.dn_192_168_0_1 interval(5s) -sql create table d4.s107 as select count(cpu_taosd), count(cpu_system), avg(cpu_taosd), avg(cpu_system), sum(cpu_taosd), max(cpu_taosd), min(cpu_taosd) from log.dn interval(5s) -sql create table d4.s108 as select count(mem_taosd), count(mem_system), avg(mem_taosd), avg(mem_system), sum(mem_taosd), max(mem_taosd), min(mem_taosd) from log.dn interval(5s) -sql create table d4.s109 as select count(disk_used), count(disk_total), avg(disk_used), avg(disk_total), sum(disk_used), max(disk_used), min(disk_used) from log.dn interval(5s) -sql create table d4.s100 as select count(io_read), count(io_write), avg(io_read), avg(io_write), sum(io_read), max(io_write), min(io_read) from log.dn interval(5s) - -sql create table d4.s111 as select count(cpu_taosd), count(cpu_system), avg(cpu_taosd), avg(cpu_system), sum(cpu_taosd), max(cpu_taosd), min(cpu_taosd) from log.dn_192_168_0_1 interval(5s) -sql create table d4.s112 as select count(mem_taosd), count(mem_system), avg(mem_taosd), avg(mem_system), sum(mem_taosd), max(mem_taosd), min(mem_taosd) from log.dn_192_168_0_1 interval(5s) -sql create table d4.s113 as select count(disk_used), count(disk_total), avg(disk_used), avg(disk_total), sum(disk_used), max(disk_used), min(disk_used) from log.dn_192_168_0_1 interval(5s) -sql create table d4.s114 as select count(io_read), count(io_write), avg(io_read), avg(io_write), sum(io_read), max(io_write), min(io_read) from log.dn_192_168_0_1 interval(5s) -sql create table d4.s115 as select count(band_speed), avg(band_speed), sum(band_speed), max(band_speed), min(band_speed) from log.dn_192_168_0_1 interval(5s) -sql create table d4.s116 as select count(req_http), count(req_insert) , sum(req_insert), max(req_select), min(req_insert) from log.dn_192_168_0_1 interval(5s) -sql create table d4.s117 as select count(cpu_taosd), count(cpu_system), avg(cpu_taosd), avg(cpu_system), sum(cpu_taosd), max(cpu_taosd), min(cpu_taosd) from log.dn interval(5s) -sql create table d4.s118 as select count(mem_taosd), count(mem_system), avg(mem_taosd), avg(mem_system), sum(mem_taosd), max(mem_taosd), min(mem_taosd) from log.dn interval(5s) -sql create table d4.s119 as select count(disk_used), count(disk_total), avg(disk_used), avg(disk_total), sum(disk_used), max(disk_used), min(disk_used) from log.dn interval(5s) -sql create table d4.s110 as select count(io_read), count(io_write), avg(io_read), avg(io_write), sum(io_read), max(io_write), min(io_read) from log.dn interval(5s) - -sql create table d4.s121 as select count(cpu_taosd), count(cpu_system), avg(cpu_taosd), avg(cpu_system), sum(cpu_taosd), max(cpu_taosd), min(cpu_taosd) from log.dn_192_168_0_1 interval(5s) -sql create table d4.s122 as select count(mem_taosd), count(mem_system), avg(mem_taosd), avg(mem_system), sum(mem_taosd), max(mem_taosd), min(mem_taosd) from log.dn_192_168_0_1 interval(5s) -sql create table d4.s123 as select count(disk_used), count(disk_total), avg(disk_used), avg(disk_total), sum(disk_used), max(disk_used), min(disk_used) from log.dn_192_168_0_1 interval(5s) -sql create table d4.s124 as select count(io_read), count(io_write), avg(io_read), avg(io_write), sum(io_read), max(io_write), min(io_read) from log.dn_192_168_0_1 interval(5s) -sql create table d4.s125 as select count(band_speed), avg(band_speed), sum(band_speed), max(band_speed), min(band_speed) from log.dn_192_168_0_1 interval(5s) -sql create table d4.s126 as select count(req_http), count(req_insert) , sum(req_insert), max(req_select), min(req_insert) from log.dn_192_168_0_1 interval(5s) -sql create table d4.s127 as select count(cpu_taosd), count(cpu_system), avg(cpu_taosd), avg(cpu_system), sum(cpu_taosd), max(cpu_taosd), min(cpu_taosd) from log.dn interval(5s) -sql create table d4.s128 as select count(mem_taosd), count(mem_system), avg(mem_taosd), avg(mem_system), sum(mem_taosd), max(mem_taosd), min(mem_taosd) from log.dn interval(5s) -sql create table d4.s129 as select count(disk_used), count(disk_total), avg(disk_used), avg(disk_total), sum(disk_used), max(disk_used), min(disk_used) from log.dn interval(5s) -sql create table d4.s120 as select count(io_read), count(io_write), avg(io_read), avg(io_write), sum(io_read), max(io_write), min(io_read) from log.dn interval(5s) - -sql create table d4.s131 as select count(cpu_taosd), count(cpu_system), avg(cpu_taosd), avg(cpu_system), sum(cpu_taosd), max(cpu_taosd), min(cpu_taosd) from log.dn_192_168_0_1 interval(5s) -sql create table d4.s132 as select count(mem_taosd), count(mem_system), avg(mem_taosd), avg(mem_system), sum(mem_taosd), max(mem_taosd), min(mem_taosd) from log.dn_192_168_0_1 interval(5s) -sql create table d4.s133 as select count(disk_used), count(disk_total), avg(disk_used), avg(disk_total), sum(disk_used), max(disk_used), min(disk_used) from log.dn_192_168_0_1 interval(5s) -sql create table d4.s134 as select count(io_read), count(io_write), avg(io_read), avg(io_write), sum(io_read), max(io_write), min(io_read) from log.dn_192_168_0_1 interval(5s) -sql create table d4.s135 as select count(band_speed), avg(band_speed), sum(band_speed), max(band_speed), min(band_speed) from log.dn_192_168_0_1 interval(5s) -sql create table d4.s136 as select count(req_http), count(req_insert) , sum(req_insert), max(req_select), min(req_insert) from log.dn_192_168_0_1 interval(5s) -sql create table d4.s137 as select count(cpu_taosd), count(cpu_system), avg(cpu_taosd), avg(cpu_system), sum(cpu_taosd), max(cpu_taosd), min(cpu_taosd) from log.dn interval(5s) -sql create table d4.s138 as select count(mem_taosd), count(mem_system), avg(mem_taosd), avg(mem_system), sum(mem_taosd), max(mem_taosd), min(mem_taosd) from log.dn interval(5s) -sql create table d4.s139 as select count(disk_used), count(disk_total), avg(disk_used), avg(disk_total), sum(disk_used), max(disk_used), min(disk_used) from log.dn interval(5s) -sql create table d4.s130 as select count(io_read), count(io_write), avg(io_read), avg(io_write), sum(io_read), max(io_write), min(io_read) from log.dn interval(5s) - -sql create table d4.s141 as select count(cpu_taosd), count(cpu_system), avg(cpu_taosd), avg(cpu_system), sum(cpu_taosd), max(cpu_taosd), min(cpu_taosd) from log.dn_192_168_0_1 interval(5s) -sql create table d4.s142 as select count(mem_taosd), count(mem_system), avg(mem_taosd), avg(mem_system), sum(mem_taosd), max(mem_taosd), min(mem_taosd) from log.dn_192_168_0_1 interval(5s) -sql create table d4.s143 as select count(disk_used), count(disk_total), avg(disk_used), avg(disk_total), sum(disk_used), max(disk_used), min(disk_used) from log.dn_192_168_0_1 interval(5s) -sql create table d4.s144 as select count(io_read), count(io_write), avg(io_read), avg(io_write), sum(io_read), max(io_write), min(io_read) from log.dn_192_168_0_1 interval(5s) -sql create table d4.s145 as select count(band_speed), avg(band_speed), sum(band_speed), max(band_speed), min(band_speed) from log.dn_192_168_0_1 interval(5s) -sql create table d4.s146 as select count(req_http), count(req_insert) , sum(req_insert), max(req_select), min(req_insert) from log.dn_192_168_0_1 interval(5s) -sql create table d4.s147 as select count(cpu_taosd), count(cpu_system), avg(cpu_taosd), avg(cpu_system), sum(cpu_taosd), max(cpu_taosd), min(cpu_taosd) from log.dn interval(5s) -sql create table d4.s148 as select count(mem_taosd), count(mem_system), avg(mem_taosd), avg(mem_system), sum(mem_taosd), max(mem_taosd), min(mem_taosd) from log.dn interval(5s) -sql create table d4.s149 as select count(disk_used), count(disk_total), avg(disk_used), avg(disk_total), sum(disk_used), max(disk_used), min(disk_used) from log.dn interval(5s) -sql create table d4.s140 as select count(io_read), count(io_write), avg(io_read), avg(io_write), sum(io_read), max(io_write), min(io_read) from log.dn interval(5s) - -sql create table d4.s151 as select count(cpu_taosd), count(cpu_system), avg(cpu_taosd), avg(cpu_system), sum(cpu_taosd), max(cpu_taosd), min(cpu_taosd) from log.dn_192_168_0_1 interval(5s) -sql create table d4.s152 as select count(mem_taosd), count(mem_system), avg(mem_taosd), avg(mem_system), sum(mem_taosd), max(mem_taosd), min(mem_taosd) from log.dn_192_168_0_1 interval(5s) -sql create table d4.s153 as select count(disk_used), count(disk_total), avg(disk_used), avg(disk_total), sum(disk_used), max(disk_used), min(disk_used) from log.dn_192_168_0_1 interval(5s) -sql create table d4.s154 as select count(io_read), count(io_write), avg(io_read), avg(io_write), sum(io_read), max(io_write), min(io_read) from log.dn_192_168_0_1 interval(5s) -sql create table d4.s155 as select count(band_speed), avg(band_speed), sum(band_speed), max(band_speed), min(band_speed) from log.dn_192_168_0_1 interval(5s) -sql create table d4.s156 as select count(req_http), count(req_insert) , sum(req_insert), max(req_select), min(req_insert) from log.dn_192_168_0_1 interval(5s) -sql create table d4.s157 as select count(cpu_taosd), count(cpu_system), avg(cpu_taosd), avg(cpu_system), sum(cpu_taosd), max(cpu_taosd), min(cpu_taosd) from log.dn interval(5s) -sql create table d4.s158 as select count(mem_taosd), count(mem_system), avg(mem_taosd), avg(mem_system), sum(mem_taosd), max(mem_taosd), min(mem_taosd) from log.dn interval(5s) -sql create table d4.s159 as select count(disk_used), count(disk_total), avg(disk_used), avg(disk_total), sum(disk_used), max(disk_used), min(disk_used) from log.dn interval(5s) -sql create table d4.s150 as select count(io_read), count(io_write), avg(io_read), avg(io_write), sum(io_read), max(io_write), min(io_read) from log.dn interval(5s) - -sql create table d4.s161 as select count(cpu_taosd), count(cpu_system), avg(cpu_taosd), avg(cpu_system), sum(cpu_taosd), max(cpu_taosd), min(cpu_taosd) from log.dn_192_168_0_1 interval(5s) -sql create table d4.s162 as select count(mem_taosd), count(mem_system), avg(mem_taosd), avg(mem_system), sum(mem_taosd), max(mem_taosd), min(mem_taosd) from log.dn_192_168_0_1 interval(5s) -sql create table d4.s163 as select count(disk_used), count(disk_total), avg(disk_used), avg(disk_total), sum(disk_used), max(disk_used), min(disk_used) from log.dn_192_168_0_1 interval(5s) -sql create table d4.s164 as select count(io_read), count(io_write), avg(io_read), avg(io_write), sum(io_read), max(io_write), min(io_read) from log.dn_192_168_0_1 interval(5s) -sql create table d4.s165 as select count(band_speed), avg(band_speed), sum(band_speed), max(band_speed), min(band_speed) from log.dn_192_168_0_1 interval(5s) -sql create table d4.s166 as select count(req_http), count(req_insert) , sum(req_insert), max(req_select), min(req_insert) from log.dn_192_168_0_1 interval(5s) -sql create table d4.s167 as select count(cpu_taosd), count(cpu_system), avg(cpu_taosd), avg(cpu_system), sum(cpu_taosd), max(cpu_taosd), min(cpu_taosd) from log.dn interval(5s) -sql create table d4.s168 as select count(mem_taosd), count(mem_system), avg(mem_taosd), avg(mem_system), sum(mem_taosd), max(mem_taosd), min(mem_taosd) from log.dn interval(5s) -sql create table d4.s169 as select count(disk_used), count(disk_total), avg(disk_used), avg(disk_total), sum(disk_used), max(disk_used), min(disk_used) from log.dn interval(5s) -sql create table d4.s160 as select count(io_read), count(io_write), avg(io_read), avg(io_write), sum(io_read), max(io_write), min(io_read) from log.dn interval(5s) - -sql create table d4.s171 as select count(cpu_taosd), count(cpu_system), avg(cpu_taosd), avg(cpu_system), sum(cpu_taosd), max(cpu_taosd), min(cpu_taosd) from log.dn_192_168_0_1 interval(5s) -sql create table d4.s172 as select count(mem_taosd), count(mem_system), avg(mem_taosd), avg(mem_system), sum(mem_taosd), max(mem_taosd), min(mem_taosd) from log.dn_192_168_0_1 interval(5s) -sql create table d4.s173 as select count(disk_used), count(disk_total), avg(disk_used), avg(disk_total), sum(disk_used), max(disk_used), min(disk_used) from log.dn_192_168_0_1 interval(5s) -sql create table d4.s174 as select count(io_read), count(io_write), avg(io_read), avg(io_write), sum(io_read), max(io_write), min(io_read) from log.dn_192_168_0_1 interval(5s) -sql create table d4.s175 as select count(band_speed), avg(band_speed), sum(band_speed), max(band_speed), min(band_speed) from log.dn_192_168_0_1 interval(5s) -sql create table d4.s176 as select count(req_http), count(req_insert) , sum(req_insert), max(req_select), min(req_insert) from log.dn_192_168_0_1 interval(5s) -sql create table d4.s177 as select count(cpu_taosd), count(cpu_system), avg(cpu_taosd), avg(cpu_system), sum(cpu_taosd), max(cpu_taosd), min(cpu_taosd) from log.dn interval(5s) -sql create table d4.s178 as select count(mem_taosd), count(mem_system), avg(mem_taosd), avg(mem_system), sum(mem_taosd), max(mem_taosd), min(mem_taosd) from log.dn interval(5s) -sql create table d4.s179 as select count(disk_used), count(disk_total), avg(disk_used), avg(disk_total), sum(disk_used), max(disk_used), min(disk_used) from log.dn interval(5s) -sql create table d4.s170 as select count(io_read), count(io_write), avg(io_read), avg(io_write), sum(io_read), max(io_write), min(io_read) from log.dn interval(5s) - -sql create table d4.s181 as select count(cpu_taosd), count(cpu_system), avg(cpu_taosd), avg(cpu_system), sum(cpu_taosd), max(cpu_taosd), min(cpu_taosd) from log.dn_192_168_0_1 interval(5s) -sql create table d4.s182 as select count(mem_taosd), count(mem_system), avg(mem_taosd), avg(mem_system), sum(mem_taosd), max(mem_taosd), min(mem_taosd) from log.dn_192_168_0_1 interval(5s) -sql create table d4.s183 as select count(disk_used), count(disk_total), avg(disk_used), avg(disk_total), sum(disk_used), max(disk_used), min(disk_used) from log.dn_192_168_0_1 interval(5s) -sql create table d4.s184 as select count(io_read), count(io_write), avg(io_read), avg(io_write), sum(io_read), max(io_write), min(io_read) from log.dn_192_168_0_1 interval(5s) -sql create table d4.s185 as select count(band_speed), avg(band_speed), sum(band_speed), max(band_speed), min(band_speed) from log.dn_192_168_0_1 interval(5s) -sql create table d4.s186 as select count(req_http), count(req_insert) , sum(req_insert), max(req_select), min(req_insert) from log.dn_192_168_0_1 interval(5s) -sql create table d4.s187 as select count(cpu_taosd), count(cpu_system), avg(cpu_taosd), avg(cpu_system), sum(cpu_taosd), max(cpu_taosd), min(cpu_taosd) from log.dn interval(5s) -sql create table d4.s188 as select count(mem_taosd), count(mem_system), avg(mem_taosd), avg(mem_system), sum(mem_taosd), max(mem_taosd), min(mem_taosd) from log.dn interval(5s) -sql create table d4.s189 as select count(disk_used), count(disk_total), avg(disk_used), avg(disk_total), sum(disk_used), max(disk_used), min(disk_used) from log.dn interval(5s) -sql create table d4.s180 as select count(io_read), count(io_write), avg(io_read), avg(io_write), sum(io_read), max(io_write), min(io_read) from log.dn interval(5s) - -sql create table d4.s191 as select count(cpu_taosd), count(cpu_system), avg(cpu_taosd), avg(cpu_system), sum(cpu_taosd), max(cpu_taosd), min(cpu_taosd) from log.dn_192_168_0_1 interval(5s) -sql create table d4.s192 as select count(mem_taosd), count(mem_system), avg(mem_taosd), avg(mem_system), sum(mem_taosd), max(mem_taosd), min(mem_taosd) from log.dn_192_168_0_1 interval(5s) -sql create table d4.s193 as select count(disk_used), count(disk_total), avg(disk_used), avg(disk_total), sum(disk_used), max(disk_used), min(disk_used) from log.dn_192_168_0_1 interval(5s) -sql create table d4.s194 as select count(io_read), count(io_write), avg(io_read), avg(io_write), sum(io_read), max(io_write), min(io_read) from log.dn_192_168_0_1 interval(5s) -sql create table d4.s195 as select count(band_speed), avg(band_speed), sum(band_speed), max(band_speed), min(band_speed) from log.dn_192_168_0_1 interval(5s) -sql create table d4.s196 as select count(req_http), count(req_insert) , sum(req_insert), max(req_select), min(req_insert) from log.dn_192_168_0_1 interval(5s) -sql create table d4.s197 as select count(cpu_taosd), count(cpu_system), avg(cpu_taosd), avg(cpu_system), sum(cpu_taosd), max(cpu_taosd), min(cpu_taosd) from log.dn interval(5s) -sql create table d4.s198 as select count(mem_taosd), count(mem_system), avg(mem_taosd), avg(mem_system), sum(mem_taosd), max(mem_taosd), min(mem_taosd) from log.dn interval(5s) -sql create table d4.s199 as select count(disk_used), count(disk_total), avg(disk_used), avg(disk_total), sum(disk_used), max(disk_used), min(disk_used) from log.dn interval(5s) -sql create table d4.s190 as select count(io_read), count(io_write), avg(io_read), avg(io_write), sum(io_read), max(io_write), min(io_read) from log.dn interval(5s) - - -print =============== step3 -print sleep 22 seconds -sleep 50000 - -sql select * from d4.s001 -$s1 = $rows -print select * from d4.s001 ==> $s1 -if $rows <= 0 then - return -1 -endi - -sql select * from d4.s002 -if $rows <= 0 then - return -1 -endi - -sql select * from d4.s003 -if $rows <= 0 then - return -1 -endi - -sql select * from d4.s004 -if $rows <= 0 then - return -1 -endi - -sql select * from d4.s005 -$s5 = $rows -print select * from d4.s005 ==> $s5 -if $rows <= 0 then - return -1 -endi - -sql select * from d4.s006 -if $rows <= 0 then - return -1 -endi - -sql select * from d4.s007 -if $rows <= 0 then - return -1 -endi - -sql select * from d4.s008 -if $rows <= 0 then - return -1 -endi - -sql select * from d4.s009 -if $rows <= 0 then - return -1 -endi - -sql select * from d4.s010 -if $rows <= 0 then - return -1 -endi - -sql select * from d4.s101 -if $rows <= 0 then - return -1 -endi - -sql select * from d4.s102 -$s12 = $rows -print select * from d4.s102 ==> $s12 -if $rows <= 0 then - return -1 -endi diff --git a/tests/script/general/stream/column_stream.sim b/tests/script/general/stream/column_stream.sim deleted file mode 100644 index 59a65f0969..0000000000 --- a/tests/script/general/stream/column_stream.sim +++ /dev/null @@ -1,200 +0,0 @@ -system sh/stop_dnodes.sh - - -system sh/deploy.sh -n dnode1 -i 1 -system sh/cfg.sh -n dnode1 -c wallevel -v 0 - -print ========== step1 -system sh/cfg.sh -n dnode1 -c monitor -v 1 -system sh/cfg.sh -n dnode1 -c monitorInterval -v 1 -system sh/exec.sh -n dnode1 -s start - -sleep 2000 -sql connect - -print =============== step1 -sleep 2000 -sql select * from log.dn -if $rows == 0 then - return -1 -endi - -print =============== step2 -sql create database d4 precision 'us' -sql use d4 -sql create table t1 (ts timestamp, i int) -sql insert into d4.t1 values(1626739200000, 1) - -sql create table d4.s1 as select count(cpu_taosd), count(cpu_system), avg(cpu_taosd), avg(cpu_system), sum(cpu_taosd), max(cpu_taosd), min(cpu_taosd), stddev(cpu_taosd), count(*) as c1, count(*) as c2, count(*) as c3, count(*) as c4, count(*) as c5, count(*) as c6, count(*) as c7, count(*) as c8, count(*) as c9, count(*) as c10, count(*) as c11, count(*) as c12, count(*) as c13, count(*) as c14, count(*) as c15, count(*) as c16, count(*) as c17, count(*) as c18, count(*) as c19, count(*) as c20, count(*) as c21, count(*) as c22, count(*) as c23, count(*) as c24, count(*) as c25, count(*) as c26, count(*) as c27, count(*) as c28, count(*) as c29, count(*) as c30 from log.dn_192_168_0_1 interval(5s) - -sql create table d4.s2 as select count(cpu_taosd), count(cpu_system), avg(cpu_taosd), avg(cpu_system), sum(cpu_taosd), max(cpu_taosd), min(cpu_taosd), stddev(cpu_taosd), count(*) as c1, count(*) as c2, count(*) as c3, count(*) as c4, count(*) as c5, count(*) as c6, count(*) as c7, count(*) as c8, count(*) as c9, count(*) as c10, count(*) as c11, count(*) as c12, count(*) as c13, count(*) as c14, count(*) as c15, count(*) as c16, count(*) as c17, count(*) as c18, count(*) as c19, count(*) as c20, count(*) as c21, count(*) as c22, count(*) as c23, count(*) as c24, count(*) as c25, count(*) as c26, count(*) as c27, count(*) as c28, count(*) as c29, count(*) as c30 from log.dn_192_168_0_1 interval(5s) - -sql create table d4.s3 as select count(disk_used), count(disk_total), avg(disk_used), avg(disk_total), sum(disk_used), max(disk_used), min(disk_used), stddev(disk_used), count(*) as c1, count(*) as c2, count(*) as c3, count(*) as c4, count(*) as c5, count(*) as c6, count(*) as c7, count(*) as c8, count(*) as c9, count(*) as c10, count(*) as c11, count(*) as c12, count(*) as c13, count(*) as c14, count(*) as c15, count(*) as c16, count(*) as c17, count(*) as c18, count(*) as c19, count(*) as c20, count(*) as c21, count(*) as c22, count(*) as c23, count(*) as c24, count(*) as c25, count(*) as c26, count(*) as c27, count(*) as c28, count(*) as c29, count(*) as c30 from log.dn_192_168_0_1 interval(5s) - -sql create table d4.s4 as select count(io_read), count(io_write), avg(io_read), avg(io_write), sum(io_read), max(io_write), min(io_read), stddev(io_write), count(*) as c1, count(*) as c2, count(*) as c3, count(*) as c4, count(*) as c5, count(*) as c6, count(*) as c7, count(*) as c8, count(*) as c9, count(*) as c10, count(*) as c11, count(*) as c12, count(*) as c13, count(*) as c14, count(*) as c15, count(*) as c16, count(*) as c17, count(*) as c18, count(*) as c19, count(*) as c20, count(*) as c21, count(*) as c22, count(*) as c23, count(*) as c24, count(*) as c25, count(*) as c26, count(*) as c27, count(*) as c28, count(*) as c29, count(*) as c30 from log.dn_192_168_0_1 interval(5s) - -sql create table d4.s5 as select count(band_speed), avg(band_speed), sum(band_speed), max(band_speed), min(band_speed), stddev(band_speed), count(*) as c1, count(*) as c2, count(*) as c3, count(*) as c4, count(*) as c5, count(*) as c6, count(*) as c7, count(*) as c8, count(*) as c9, count(*) as c10, count(*) as c11, count(*) as c12, count(*) as c13, count(*) as c14, count(*) as c15, count(*) as c16, count(*) as c17, count(*) as c18, count(*) as c19, count(*) as c20, count(*) as c21, count(*) as c22, count(*) as c23, count(*) as c24, count(*) as c25, count(*) as c26, count(*) as c27, count(*) as c28, count(*) as c29, count(*) as c30 from log.dn_192_168_0_1 interval(5s) - -sql create table d4.s6 as select count(req_http), count(req_insert), avg(req_http), avg(req_select), sum(req_insert), max(req_select), min(req_insert), stddev(req_select), count(*) as c1, count(*) as c2, count(*) as c3, count(*) as c4, count(*) as c5, count(*) as c6, count(*) as c7, count(*) as c8, count(*) as c9, count(*) as c10, count(*) as c11, count(*) as c12, count(*) as c13, count(*) as c14, count(*) as c15, count(*) as c16, count(*) as c17, count(*) as c18, count(*) as c19, count(*) as c20, count(*) as c21, count(*) as c22, count(*) as c23, count(*) as c24, count(*) as c25, count(*) as c26, count(*) as c27, count(*) as c28, count(*) as c29, count(*) as c30 from log.dn_192_168_0_1 interval(5s) - -sql create table d4.s7 as select count(cpu_taosd), count(cpu_system), avg(cpu_taosd), avg(cpu_system), sum(cpu_taosd), max(cpu_taosd), min(cpu_taosd), count(*) as c1, count(*) as c2, count(*) as c3, count(*) as c4, count(*) as c5, count(*) as c6, count(*) as c7, count(*) as c8, count(*) as c9, count(*) as c10, count(*) as c11, count(*) as c12, count(*) as c13, count(*) as c14, count(*) as c15, count(*) as c16, count(*) as c17, count(*) as c18, count(*) as c19, count(*) as c20, count(*) as c21, count(*) as c22, count(*) as c23, count(*) as c24, count(*) as c25, count(*) as c26, count(*) as c27, count(*) as c28, count(*) as c29, count(*) as c30 from log.dn interval(5s) - -sql create table d4.s8 as select count(cpu_taosd), count(cpu_system), avg(cpu_taosd), avg(cpu_system), sum(cpu_taosd), max(cpu_taosd), min(cpu_taosd), count(*) as c1, count(*) as c2, count(*) as c3, count(*) as c4, count(*) as c5, count(*) as c6, count(*) as c7, count(*) as c8, count(*) as c9, count(*) as c10, count(*) as c11, count(*) as c12, count(*) as c13, count(*) as c14, count(*) as c15, count(*) as c16, count(*) as c17, count(*) as c18, count(*) as c19, count(*) as c20, count(*) as c21, count(*) as c22, count(*) as c23, count(*) as c24, count(*) as c25, count(*) as c26, count(*) as c27, count(*) as c28, count(*) as c29, count(*) as c30 from log.dn interval(5s) - -sql create table d4.s9 as select count(disk_used), count(disk_total), avg(disk_used), avg(disk_total), sum(disk_used), max(disk_used), min(disk_used), count(*) as c1, count(*) as c2, count(*) as c3, count(*) as c4, count(*) as c5, count(*) as c6, count(*) as c7, count(*) as c8, count(*) as c9, count(*) as c10, count(*) as c11, count(*) as c12, count(*) as c13, count(*) as c14, count(*) as c15, count(*) as c16, count(*) as c17, count(*) as c18, count(*) as c19, count(*) as c20, count(*) as c21, count(*) as c22, count(*) as c23, count(*) as c24, count(*) as c25, count(*) as c26, count(*) as c27, count(*) as c28, count(*) as c29, count(*) as c30 from log.dn interval(5s) - -sql create table d4.s10 as select count(io_read), count(io_write), avg(io_read), avg(io_write), sum(io_read), max(io_write), min(io_read), count(*) as c1, count(*) as c2, count(*) as c3, count(*) as c4, count(*) as c5, count(*) as c6, count(*) as c7, count(*) as c8, count(*) as c9, count(*) as c10, count(*) as c11, count(*) as c12, count(*) as c13, count(*) as c14, count(*) as c15, count(*) as c16, count(*) as c17, count(*) as c18, count(*) as c19, count(*) as c20, count(*) as c21, count(*) as c22, count(*) as c23, count(*) as c24, count(*) as c25, count(*) as c26, count(*) as c27, count(*) as c28, count(*) as c29, count(*) as c30 from log.dn interval(5s) - -sql create table d4.s11 as select count(band_speed), avg(band_speed), sum(band_speed), max(band_speed), min(band_speed), count(*) as c1, count(*) as c2, count(*) as c3, count(*) as c4, count(*) as c5, count(*) as c6, count(*) as c7, count(*) as c8, count(*) as c9, count(*) as c10, count(*) as c11, count(*) as c12, count(*) as c13, count(*) as c14, count(*) as c15, count(*) as c16, count(*) as c17, count(*) as c18, count(*) as c19, count(*) as c20, count(*) as c21, count(*) as c22, count(*) as c23, count(*) as c24, count(*) as c25, count(*) as c26, count(*) as c27, count(*) as c28, count(*) as c29, count(*) as c30 from log.dn interval(5s) - -sql create table d4.s12 as select count(req_http), count(req_insert), avg(req_select), avg(req_insert), sum(req_insert), max(req_select), min(req_insert), count(*) as c1, count(*) as c2, count(*) as c3, count(*) as c4, count(*) as c5, count(*) as c6, count(*) as c7, count(*) as c8, count(*) as c9, count(*) as c10, count(*) as c11, count(*) as c12, count(*) as c13, count(*) as c14, count(*) as c15, count(*) as c16, count(*) as c17, count(*) as c18, count(*) as c19, count(*) as c20, count(*) as c21, count(*) as c22, count(*) as c23, count(*) as c24, count(*) as c25, count(*) as c26, count(*) as c27, count(*) as c28, count(*) as c29, count(*) as c30 from log.dn interval(5s) - -print =============== step3 -print sleep 22 seconds -sleep 22000 - -sql select * from d4.s1 -$s1 = $rows -print select * from d4.s1 ==> $s1 -if $rows <= 0 then - return -1 -endi - -sql select * from d4.s2 -if $rows <= 0 then - return -1 -endi - -sql select * from d4.s3 -if $rows <= 0 then - return -1 -endi - -sql select * from d4.s4 -if $rows <= 0 then - return -1 -endi - -sql select * from d4.s5 -$s5 = $rows -print select * from d4.s5 ==> $s5 -if $rows <= 0 then - return -1 -endi - -sql select * from d4.s6 -if $rows <= 0 then - return -1 -endi - -sql select * from d4.s7 -if $rows <= 0 then - return -1 -endi - -sql select * from d4.s8 -if $rows <= 0 then - return -1 -endi - -sql select * from d4.s9 -if $rows <= 0 then - return -1 -endi - -sql select * from d4.s10 -if $rows <= 0 then - return -1 -endi - -sql select * from d4.s11 -if $rows <= 0 then - return -1 -endi - -sql select * from d4.s12 -$s12 = $rows -print select * from d4.s12 ==> $s12 -if $rows <= 0 then - return -1 -endi - -print =============== step4 -system sh/exec.sh -n dnode1 -s stop -x SIGINT -sleep 3000 -system sh/exec.sh -n dnode1 -s start -print sleep 22 seconds -sleep 22000 - -sql select * from d4.s1 -print select * from d4.s1 ==> $rows $s1 -if $rows <= 0 then - return -1 -endi -if $rows <= $s1 then - return -1 -endi - -sql select * from d4.s2 -if $rows <= 0 then - return -1 -endi - -sql select * from d4.s3 -if $rows <= 0 then - return -1 -endi - -sql select * from d4.s4 -if $rows <= 0 then - return -1 -endi - -sql select * from d4.s5 -print select * from d4.s5 ==> $rows $s5 -if $rows <= 0 then - return -1 -endi -if $rows <= $s5 then - return -1 -endi - - -sql select * from d4.s6 -if $rows <= 0 then - return -1 -endi - -sql select * from d4.s7 -if $rows <= 0 then - return -1 -endi - -sql select * from d4.s8 -if $rows <= 0 then - return -1 -endi - -sql select * from d4.s9 -if $rows <= 0 then - return -1 -endi - -sql select * from d4.s10 -if $rows <= 0 then - return -1 -endi - -sql select * from d4.s11 -if $rows <= 0 then - return -1 -endi - -sql select * from d4.s12 -print select * from d4.s12 ==> $rows $s12 -if $rows <= 0 then - return -1 -endi -if $rows <= $s12 then - return -1 -endi \ No newline at end of file diff --git a/tests/script/general/stream/metrics_del.sim b/tests/script/general/stream/metrics_del.sim deleted file mode 100644 index 6cc3da71e9..0000000000 --- a/tests/script/general/stream/metrics_del.sim +++ /dev/null @@ -1,95 +0,0 @@ -system sh/stop_dnodes.sh - -system sh/deploy.sh -n dnode1 -i 1 -system sh/cfg.sh -n dnode1 -c walLevel -v 1 -system sh/exec.sh -n dnode1 -s start - -sleep 2000 -sql connect - -print ======================== dnode1 start - -$dbPrefix = md_db -$tbPrefix = md_tb -$mtPrefix = md_mt -$stPrefix = md_st -$tbNum = 10 -$rowNum = 20 -$totalNum = 200 - -print =============== step1 -$i = 0 -$db = $dbPrefix . $i -$mt = $mtPrefix . $i -$st = $stPrefix . $i - -sql drop databae $db -x step1 -step1: -sql create database $db -sql use $db -sql create table $mt (ts timestamp, tbcol int, tbcol2 float) TAGS(tgcol int) - -$i = 0 -while $i < $tbNum - $tb = $tbPrefix . $i - sql create table $tb using $mt tags( $i ) - - $x = 0 - $y = 0 - while $y < $rowNum - $ts = 1626710400000 + $x - sql insert into $tb values ($ts , $y , $y ) - $x = $x + 1 - $y = $y + 1 - endw - - $i = $i + 1 -endw - -sleep 100 - -print =============== step2 c3 - -sql select count(*), count(tbcol), count(tbcol2) from $mt interval(1d) -print select count(*), count(tbcol), count(tbcol2) from $mt interval(1d) ===> $data00 $data01 $data02, $data03 -if $data01 != 200 then - return -1 -endi -if $data02 != 200 then - return -1 -endi -if $data03 != 200 then - return -1 -endi - -$st = $stPrefix . c3 -sql create table $st as select count(*), count(tbcol), count(tbcol2) from $mt interval(1d) - -print =============== step3 - -$i = 0 -while $i < $tbNum - $tb = $tbPrefix . $i - sql drop table $tb - $i = $i + 1 -endw -sql drop table $mt - -print =============== step4 -print sleep 120 seconds -sleep 120000 - -print =============== step5 -$st = $stPrefix . c3 -sql select * from $st -print ===> select * from $st -print ===> $data01 $data02 $data03 $data04 $data05 $data06 $data07 $data08 $data09 -if $data01 != null then - return -1 -endi -if $data02 != null then - return -1 -endi -if $data03 != null then - return -1 -endi diff --git a/tests/script/general/stream/metrics_replica1_vnoden.sim b/tests/script/general/stream/metrics_replica1_vnoden.sim deleted file mode 100644 index db1044a597..0000000000 --- a/tests/script/general/stream/metrics_replica1_vnoden.sim +++ /dev/null @@ -1,245 +0,0 @@ -system sh/stop_dnodes.sh - - -system sh/deploy.sh -n dnode1 -i 1 -system sh/cfg.sh -n dnode1 -c walLevel -v 1 -system sh/cfg.sh -n dnode1 -c maxtablesPerVnode -v 1000 -system sh/cfg.sh -n dnode1 -c maxVgroupsPerDb -v 3 -system sh/exec.sh -n dnode1 -s start - -sleep 2000 -sql connect - -print ======================== dnode1 start - -$dbPrefix = m1v_db -$tbPrefix = m1v_tb -$mtPrefix = m1v_mt -$stPrefix = m1v_st -$tbNum = 10 -$rowNum = 20 -$totalNum = 200 - -print =============== step1 -$i = 0 -$db = $dbPrefix . $i -$mt = $mtPrefix . $i -$st = $stPrefix . $i - -sql drop databae $db -x step1 -step1: -sql create database $db -sql use $db -sql create table $mt (ts timestamp, tbcol int, tbcol2 float) TAGS(tgcol int) - -$i = 0 -while $i < $tbNum - $tb = $tbPrefix . $i - sql create table $tb using $mt tags( $i ) - - $x = -400 - $y = 0 - while $y < $rowNum - $ms = $x . m - sql insert into $tb values (1626739200000 $ms , $y , $y ) - $x = $x + 1 - $y = $y + 1 - endw - - $i = $i + 1 -endw - -sleep 100 - -print =============== step2 c1 - -sql select count(*) from $mt interval(1d) -print select count(*) from $mt interval(1d) ===> $data00 $data01 -if $data01 != 200 then - return -1 -endi - -$st = $stPrefix . c1 -sql create table $st as select count(*) from $mt interval(1d) - -print =============== step3 c2 -sql select count(tbcol) from $mt interval(1d) -print select count(tbcol) from $mt interval(1d) ===> $data00 $data01 -if $data01 != 200 then - return -1 -endi - -$st = $stPrefix . c2 -sql create table $st as select count(tbcol) from $mt interval(1d) - -print =============== step4 c3 -sql select count(tbcol2) from $mt interval(1d) -print select count(tbcol2) from $mt interval(1d) ===> $data00 $data01 -if $data01 != 200 then - return -1 -endi - -$st = $stPrefix . c3 -sql create table $st as select count(tbcol2) from $mt interval(1d) - -print =============== step5 avg -sql select avg(tbcol) from $mt interval(1d) -print select avg(tbcol) from $mt interval(1d) ===> $data00 $data01 -if $data01 != 9.500000000 then - return -1 -endi - -$st = $stPrefix . av -sql create table $st as select avg(tbcol) from $mt interval(1d) - -print =============== step6 su -sql select sum(tbcol) from $mt interval(1d) -print select sum(tbcol) from $mt interval(1d) ===> $data00 $data01 -if $data01 != 1900 then - return -1 -endi - -$st = $stPrefix . su -sql create table $st as select sum(tbcol) from $mt interval(1d) - -print =============== step7 mi -sql select min(tbcol) from $mt interval(1d) -print select min(tbcol) from $mt interval(1d) ===> $data00 $data01 -if $data01 != 0 then - return -1 -endi - -$st = $stPrefix . mi -sql create table $st as select min(tbcol) from $mt interval(1d) - -print =============== step8 ma -sql select max(tbcol) from $mt interval(1d) -print select max(tbcol) from $mt interval(1d) ===> $data00 $data01 -if $data01 != 19 then - return -1 -endi - -$st = $stPrefix . ma -sql create table $st as select max(tbcol) from $mt interval(1d) - -print =============== step9 fi -sql select first(tbcol) from $mt interval(1d) -print select first(tbcol) from $mt interval(1d) ===> $data00 $data01 -if $data01 != 0 then - return -1 -endi - -$st = $stPrefix . fi -sql create table $st as select first(tbcol) from $mt interval(1d) - -print =============== step10 la -sql select last(tbcol) from $mt interval(1d) -print select last(tbcol) from $mt interval(1d) ===> $data00 $data01 -if $data01 != 19 then - return -1 -endi - -$st = $stPrefix . la -sql create table $st as select last(tbcol) from $mt interval(1d) - -print =============== step11 wh -sql select count(tbcol) from $mt where ts < 1626739440001 interval(1d) -print select count(tbcol) from $mt where ts < 1626739440000 interval(1d) ===> $data00 $data01 -if $data01 != 200 then - return -1 -endi - -$st = $stPrefix . wh -#sql create table $st as select count(tbcol) from $mt where ts < 1626739200000 + 4m interval(1d) - -print =============== step12 as -sql select count(tbcol) from $mt interval(1d) -print select count(tbcol) from $mt interval(1d) ===> $data00 $data01 -if $data01 != 200 then - return -1 -endi - -$st = $stPrefix . as -sql create table $st as select count(tbcol) as c from $mt interval(1d) - -print =============== step13 -print sleep 120 seconds -sleep 120000 - -print =============== step14 -$st = $stPrefix . c1 -sql select * from $st -print ===> select * from $st ===> $data00 $data01 -if $data01 != 200 then - return -1 -endi - -$st = $stPrefix . c2 -sql select * from $st -print ===> select * from $st ===> $data00 $data01 -if $data01 != 200 then - return -1 -endi - -$st = $stPrefix . c3 -sql select * from $st -print ===> select * from $st ===> $data00 $data01 -if $data01 != 200 then - return -1 -endi - -$st = $stPrefix . av -sql select * from $st -print ===> select * from $st ===> $data00 $data01 -if $data01 != 9.500000000 then - return -1 -endi - -$st = $stPrefix . su -sql select * from $st -print ===> select * from $st ===> $data00 $data01 -if $data01 != 1900 then - return -1 -endi - -$st = $stPrefix . mi -sql select * from $st -print ===> select * from $st ===> $data00 $data01 -if $data01 != 0 then - return -1 -endi - -$st = $stPrefix . ma -sql select * from $st -print ===> select * from $st ===> $data00 $data01 -if $data01 != 19 then - return -1 -endi - -$st = $stPrefix . fi -sql select * from $st -print ===> select * from $st ===> $data00 $data01 -if $data01 != 0 then - return -1 -endi - -$st = $stPrefix . la -sql select * from $st -print ===> select * from $st ===> $data00 $data01 -if $data01 != 19 then - return -1 -endi - -$st = $stPrefix . wh -#sql select * from $st -#print ===> select * from $st ===> $data00 $data01 -#if $data01 != 200 then -# return -1 -#endi - -$st = $stPrefix . as -sql select * from $st -print ===> select * from $st ===> $data00 $data01 -if $data01 != 200 then - return -1 -endi diff --git a/tests/script/general/stream/restart_stream.sim b/tests/script/general/stream/restart_stream.sim deleted file mode 100644 index 62e47f9b3a..0000000000 --- a/tests/script/general/stream/restart_stream.sim +++ /dev/null @@ -1,176 +0,0 @@ -system sh/stop_dnodes.sh - - -system sh/deploy.sh -n dnode1 -i 1 -system sh/cfg.sh -n dnode1 -c walLevel -v 1 -system sh/exec.sh -n dnode1 -s start - -sleep 2000 -sql connect -print ======================== dnode1 start - -$i = 0 -$dbPrefix = rs_db -$tbPrefix = rs_tb -$mtPrefix = rs_mt -$stPrefix = rs_st -$tbNum = 10 -$rowNum = 20 -$totalNum = 200 - -$db = $dbPrefix -$tb = $tbPrefix . $i -$mt = $mtPrefix -$stm = $stPrefix . m -$stt = $stPrefix . t - -print =============== step1 -sql create database $db -sql use $db - -sql create table $mt (ts timestamp, tbcol int, tbcol2 int ) TAGS(tgcol bool) -$i = 0 -while $i < 10 - $tb = $tbPrefix . $i - sql create table $tb using $mt tags( 0 ) - - $x = -400 - $y = 0 - while $y < $rowNum - $ms = $x . m - sql insert into $tb values (1626739200000 $ms , $y , $y ) - $x = $x + 1 - $y = $y + 1 - endw - - $i = $i + 1 -endw - -print =============== step2 -$i = 0 -$tb = $tbPrefix . $i - -sql select count(*) from $tb interval(1d) -print ===>rows $rows, data $data01 -if $rows != 1 then - return -1 -endi -if $data01 != 20 then - return -1 -endi - -sql select count(*) from $mt interval(1d) -print ===>rows $rows, data $data01 -if $rows != 1 then - return -1 -endi -if $data01 != 200 then - return -1 -endi - -print =============== step3 -sql create table $stt as select count(*) from $tb interval(1d) -sql create table $stm as select count(*) from $mt interval(1d) - -print sleep 120 seconds -sleep 120000 - -sql select * from $stt -print select count(*) from $stt ===> $data00 $data01 -if $rows != 1 then - return -1 -endi -if $data01 != 20 then - return -1 -endi - -sql select * from $stm -print select * from $stm ===> $data00 $data01 -if $rows != 1 then - return -1 -endi -if $data01 != 200 then - return -1 -endi - -print =============== step4 -system sh/exec.sh -n dnode1 -s stop -system sh/deploy.sh -n dnode1 -i 1 -system sh/cfg.sh -n dnode1 -c walLevel -v 1 -system sh/exec.sh -n dnode1 -s start - -print =============== step5 -print ==> renew cache -sql reset query cache -sleep 1000 - - -print =============== step6 -sql create database $db -sql use $db -sql create table $mt (ts timestamp, tbcol bigint, tbcol2 bigint ) TAGS(tgcol int) -$i = 0 -while $i < 5 - $tb = $tbPrefix . $i - sql create table $tb using $mt tags( 0 ) - - $x = -400 - $y = 0 - while $y < $rowNum - $ms = $x . m - sql insert into $tb values (1626739200000 $ms , $y , $y ) - $x = $x + 1 - $y = $y + 1 - endw - - $i = $i + 1 -endw - - -print =============== step7 - -sql select count(*) from $tb interval(1d) -print ===>rows $rows, data $data01 -if $rows != 1 then - return -1 -endi -if $data01 != 20 then - return -1 -endi - -sql select count(*) from $mt interval(1d) -print ===>rows $rows, data $data01 -if $rows != 1 then - return -1 -endi -if $data01 != 100 then - return -1 -endi - -print =============== step8 -sql create table $stt as select count(*) from $tb interval(1d) -sql create table $stm as select count(*) from $mt interval(1d) - -print sleep 120 seconds -sleep 120000 - -sql select * from $stt -sleep 1000 -print ===>rows $rows, data $data01 -if $rows != 1 then - return -1 -endi -if $data01 != 20 then - return -1 -endi - -sql select * from $stm -print ===>rows $rows, data $data01 -if $rows != 1 then - return -1 -endi -if $data01 != 100 then - return -1 -endi - - diff --git a/tests/script/general/stream/stream_1970.sim b/tests/script/general/stream/stream_1970.sim deleted file mode 100644 index 30a733c08f..0000000000 --- a/tests/script/general/stream/stream_1970.sim +++ /dev/null @@ -1,73 +0,0 @@ -system sh/stop_dnodes.sh - -system sh/deploy.sh -n dnode1 -i 1 -system sh/cfg.sh -n dnode1 -c walLevel -v 1 -system sh/exec.sh -n dnode1 -s start - -sleep 2000 -sql connect - -print ======================== dnode1 start - -$dbPrefix = s3_db -$tbPrefix = s3_tb -$mtPrefix = s3_mt -$stPrefix = s3_st -$tbNum = 10 -$rowNum = 20 -$totalNum = 200 - -print =============== step1 -$i = 0 -$db = $dbPrefix . $i -$mt = $mtPrefix . $i -$st = $stPrefix . $i - -sql drop databae $db -x step1 -step1: -sql create database $db keep 36500 -sql use $db -sql create stable $mt (ts timestamp, tbcol int, tbcol2 float) TAGS(tgcol int) - -sql create table cq1 as select count(*) from $mt interval(10s); - -sleep 1000 - -sql create table $st using $mt tags(1); - -sql insert into $st values (-50000, 1, 1.0); -sql insert into $st values (-10000, 1, 1.0); -sql insert into $st values (10000, 1, 1.0); - - -$i = 0 -while $i < 12 - sql select * from cq1; - - if $rows != 3 then - sleep 10000 - else - if $data00 != @70-01-01 07:59:10.000@ then - return -1 - endi - if $data01 != 1 then - return -1 - endi - if $data10 != @70-01-01 07:59:50.000@ then - return -1 - endi - if $data11 != 1 then - return -1 - endi - if $data20 != @70-01-01 08:00:10.000@ then - return -1 - endi - if $data21 != 1 then - return -1 - endi - $i = 12 - endi - - $i = $i + 1 -endw - diff --git a/tests/script/general/stream/stream_3.sim b/tests/script/general/stream/stream_3.sim deleted file mode 100644 index b043993814..0000000000 --- a/tests/script/general/stream/stream_3.sim +++ /dev/null @@ -1,201 +0,0 @@ -system sh/stop_dnodes.sh - -system sh/deploy.sh -n dnode1 -i 1 -system sh/cfg.sh -n dnode1 -c walLevel -v 1 -system sh/exec.sh -n dnode1 -s start - -sleep 2000 -sql connect - -print ======================== dnode1 start - -$dbPrefix = s3_db -$tbPrefix = s3_tb -$mtPrefix = s3_mt -$stPrefix = s3_st -$tbNum = 10 -$rowNum = 20 -$totalNum = 200 - -print =============== step1 -$i = 0 -$db = $dbPrefix . $i -$mt = $mtPrefix . $i -$st = $stPrefix . $i - -sql drop databae $db -x step1 -step1: -sql create database $db -sql use $db -sql create table $mt (ts timestamp, tbcol int, tbcol2 float) TAGS(tgcol int) - -$i = 0 -while $i < $tbNum - $tb = $tbPrefix . $i - sql create table $tb using $mt tags( $i ) - - $x = -400 - $y = 0 - while $y < $rowNum - $ms = $x . m - sql insert into $tb values (1626739200000 $ms , $y , $y ) - $x = $x + 1 - $y = $y + 1 - endw - - $i = $i + 1 -endw - -sleep 100 - -print =============== step2 c1 -$i = 1 -$tb = $tbPrefix . $i - -sql select count(*) from $tb interval(1d) -if $data01 != $rowNum then - return -1 -endi - -$st = $stPrefix . c1 -sql create table $st as select count(*) from $tb interval(1d) - -print =============== step3 c2 -sql select count(tbcol) from $tb interval(1d) -if $data01 != $rowNum then - return -1 -endi - -$st = $stPrefix . c2 -sql create table $st as select count(tbcol) from $tb interval(1d) - -print =============== step4 c3 -sql select count(tbcol2) from $tb interval(1d) -if $data01 != $rowNum then - return -1 -endi - -$st = $stPrefix . c3 -sql create table $st as select count(tbcol2) from $tb interval(1d) - -print =============== step5 -print sleep 120 seconds -sleep 120000 - -print =============== step6 -$st = $stPrefix . c1 -sql select * from $st -print ===> select * from $st ===> $data00 $data01 -if $data01 != $rowNum then - return -1 -endi - -$st = $stPrefix . c2 -sql select * from $st -print ===> select * from $st ===> $data00 $data01 -if $data01 != $rowNum then - return -1 -endi - -$st = $stPrefix . c3 -sql select * from $st -print ===> select * from $st ===> $data00 $data01 -if $data01 != $rowNum then - return -1 -endi - -print =============== step7 - -system sh/exec.sh -n dnode1 -s stop -system sh/deploy.sh -n dnode1 -i 1 -system sh/cfg.sh -n dnode1 -c walLevel -v 1 -system sh/exec.sh -n dnode1 -s start - -sleep 4000 -print ======================== dnode1 start - -$dbPrefix = stst3db -$tbPrefix = stst3tb -$mtPrefix = stst3mt -$stPrefix = stst3st -$tbNum = 10 -$rowNum = 20 -$totalNum = 200 - -print =============== step8 -$i = 0 -$db = $dbPrefix . $i -$mt = $mtPrefix . $i -$st = $stPrefix . $i - -sql drop databae $db -x step8 -step8: -sql create database $db -sql use $db -sql create table $mt (ts timestamp, tbcol int, tbcol2 float) TAGS(tgcol int) - -$i = 0 -while $i < $tbNum - $tb = $tbPrefix . $i - sql create table $tb using $mt tags( $i ) - - $x = -400 - $y = 0 - while $y < $rowNum - $ms = $x . m - sql insert into $tb values (1626739200000 $ms , $y , $y ) - $x = $x + 1 - $y = $y + 1 - endw - - $i = $i + 1 -endw - -sleep 100 - -print =============== step9 c3 -$i = 1 -$tb = $tbPrefix . $i - -sql select count(*), count(tbcol), count(tbcol2) from $tb interval(1d) -print select count(*), count(tbcol), count(tbcol2) from $tb interval(1d) ===> $data00 $data01 $data02, $data03 -if $data01 != $rowNum then - return -1 -endi -if $data02 != $rowNum then - return -1 -endi -if $data03 != $rowNum then - return -1 -endi - -$st = $stPrefix . c3 -sql create table $st as select count(*), count(tbcol), count(tbcol2) from $tb interval(1d) - -print =============== step10 -print sleep 120 seconds -sleep 120000 - -print =============== step11 -#$st = $stPrefix . c3 -#sql select * from $st -x step11 -# print ===> select * from $st first time should be error -# return -1 -#step11: - -print =============== step12 -$st = $stPrefix . c3 -sql select * from $st -print ===> select * from $st -print ===> $data01 $data02 $data03 $data04 $data05 $data06 $data07 $data08 $data09 -if $data01 != $rowNum then - return -1 -endi -if $data02 != $rowNum then - return -1 -endi -if $data03 != $rowNum then - return -1 -endi - - diff --git a/tests/script/general/stream/stream_restart.sim b/tests/script/general/stream/stream_restart.sim deleted file mode 100644 index 54a60a0081..0000000000 --- a/tests/script/general/stream/stream_restart.sim +++ /dev/null @@ -1,142 +0,0 @@ -system sh/stop_dnodes.sh - -system sh/deploy.sh -n dnode1 -i 1 -system sh/cfg.sh -n dnode1 -c walLevel -v 1 -system sh/exec.sh -n dnode1 -s start - -sleep 2000 -sql connect - -print ======================== dnode1 start - -$dbPrefix = sr_db -$tbPrefix = sr_tb -$mtPrefix = sr_mt -$stPrefix = sr_st -$tbNum = 10 -$rowNum = 200 -$totalNum = 200 - -print =============== step1 - -$i = 0 -$db = $dbPrefix . $i -$mt = $mtPrefix . $i -$st = $stPrefix . $i - -sql create database $db -sql use $db -sql create table $mt (ts timestamp, tbcol int, tbcol2 float) TAGS(tgcol int) - -$i = 0 -while $i < $tbNum - $tb = $tbPrefix . $i - sql create table $tb using $mt tags( $i ) - - $x = 0 - $y = 0 - while $y < $rowNum - $ms = $x . s - sql insert into $tb values (1626739200000 + $ms , $y , $y ) - $x = $x + 1 - $y = $y + 1 - endw - - $i = $i + 1 -endw - -sleep 100 - -print =============== step2 - -$i = 1 -$tb = $tbPrefix . $i -$st = $stPrefix . $i -sql select count(*), count(tbcol), count(tbcol2) from $tb interval(1d) -sql create table $st as select count(*), count(tbcol), count(tbcol2) from $tb interval(10s) - -$i = 5 -$tb = $tbPrefix . $i -$st = $stPrefix . $i -sql select count(*), count(tbcol), count(tbcol2) from $tb interval(1d) -sql create table $st as select count(*), count(tbcol), count(tbcol2) from $tb interval(10s) - -$i = 8 -$tb = $tbPrefix . $i -$st = $stPrefix . $i -sql select count(*), count(tbcol), count(tbcol2) from $tb interval(1d) -sql create table $st as select count(*), count(tbcol), count(tbcol2) from $tb interval(10s) - -sql show tables -if $rows != 13 then - return -1 -endi - -print =============== step3 -sleep 2000 -system sh/exec.sh -n dnode1 -s stop -x SIGINT -sleep 1000 -system sh/exec.sh -n dnode1 -s start - -print =============== step4 -print sleep 120 seconds -sleep 120000 - -print =============== step5 -$i = 1 -$tb = $tbPrefix . $i -$st = $stPrefix . $i -sql select * from $tb -print $tb ==> $rows $data00 $data01 -if $rows != $rowNum then - return -1 -endi - -$i = 5 -$tb = $tbPrefix . $i -$st = $stPrefix . $i -sql select * from $tb -print $tb ==> $rows $data00 $data01 -if $rows != $rowNum then - return -1 -endi - -$i = 8 -$tb = $tbPrefix . $i -$st = $stPrefix . $i -sql select * from $tb -print $tb ==> $rows $data00 $data01 -if $rows != $rowNum then - return -1 -endi - -print =============== step6 - -$i = 1 -$tb = $tbPrefix . $i -$st = $stPrefix . $i -sql select * from $st -print $st ==> $rows $data00 $data01 -if $rows <= 1 then - return -1 -endi - -$i = 5 -$tb = $tbPrefix . $i -$st = $stPrefix . $i -sql select * from $st -print $st ==> $rows $data00 $data01 -if $rows <= 1 then - return -1 -endi - -$i = 8 -$tb = $tbPrefix . $i -$st = $stPrefix . $i -sql select * from $st -print $st ==> $rows $data00 $data01 -if $rows <= 1 then - return -1 -endi - - diff --git a/tests/script/general/stream/table_del.sim b/tests/script/general/stream/table_del.sim deleted file mode 100644 index 34673605d6..0000000000 --- a/tests/script/general/stream/table_del.sim +++ /dev/null @@ -1,90 +0,0 @@ -system sh/stop_dnodes.sh - -system sh/deploy.sh -n dnode1 -i 1 -system sh/cfg.sh -n dnode1 -c walLevel -v 1 -system sh/exec.sh -n dnode1 -s start - -sleep 2000 -sql connect - -print ======================== dnode1 start - -$dbPrefix = td_db -$tbPrefix = td_tb -$mtPrefix = td_mt -$stPrefix = td_st -$tbNum = 10 -$rowNum = 20 -$totalNum = 200 - -print =============== step1 -$i = 0 -$db = $dbPrefix . $i -$mt = $mtPrefix . $i -$st = $stPrefix . $i - -sql drop databae $db -x step1 -step1: -sql create database $db -sql use $db -sql create table $mt (ts timestamp, tbcol int, tbcol2 float) TAGS(tgcol int) - -$i = 0 -while $i < $tbNum - $tb = $tbPrefix . $i - sql create table $tb using $mt tags( $i ) - - $x = -400 - $y = 0 - while $y < $rowNum - $ms = $x . m - sql insert into $tb values (1626739200000 $ms , $y , $y ) - $x = $x + 1 - $y = $y + 1 - endw - - $i = $i + 1 -endw - -sleep 100 - -print =============== step2 c3 -$i = 1 -$tb = $tbPrefix . $i - -sql select count(*), count(tbcol), count(tbcol2) from $tb interval(1d) -print select count(*), count(tbcol), count(tbcol2) from $tb interval(1d) ===> $data00 $data01 $data02, $data03 -if $data01 != $rowNum then - return -1 -endi -if $data02 != $rowNum then - return -1 -endi -if $data03 != $rowNum then - return -1 -endi - -$st = $stPrefix . c3 -sql create table $st as select count(*), count(tbcol), count(tbcol2) from $tb interval(1d) - -print =============== step3 -sql drop table $tb - -print =============== step4 -print sleep 120 seconds -sleep 120000 - -print =============== step5 -$st = $stPrefix . c3 -sql select * from $st -print ===> select * from $st -print ===> $data01 $data02 $data03 $data04 $data05 $data06 $data07 $data08 $data09 -if $data01 != null then - return -1 -endi -if $data02 != null then - return -1 -endi -if $data03 != null then - return -1 -endi diff --git a/tests/script/general/stream/table_replica1_vnoden.sim b/tests/script/general/stream/table_replica1_vnoden.sim deleted file mode 100644 index 4a6c4fe046..0000000000 --- a/tests/script/general/stream/table_replica1_vnoden.sim +++ /dev/null @@ -1,299 +0,0 @@ -system sh/stop_dnodes.sh - - -system sh/deploy.sh -n dnode1 -i 1 -system sh/cfg.sh -n dnode1 -c walLevel -v 1 -system sh/cfg.sh -n dnode1 -c maxtablesPerVnode -v 1000 -system sh/cfg.sh -n dnode1 -c maxVgroupsPerDb -v 3 -system sh/exec.sh -n dnode1 -s start - -sleep 2000 -sql connect - -print ======================== dnode1 start - -$dbPrefix = t1v_db -$tbPrefix = t1v_tb -$mtPrefix = t1v_mt -$stPrefix = t1v_st -$tbNum = 10 -$rowNum = 20 -$totalNum = 200 - -print =============== step1 -$i = 0 -$db = $dbPrefix . $i -$mt = $mtPrefix . $i -$st = $stPrefix . $i - -sql drop databae $db -x step1 -step1: -sql create database $db -sql use $db -sql create table $mt (ts timestamp, tbcol int, tbcol2 float) TAGS(tgcol int) - -$i = 0 -while $i < $tbNum - $tb = $tbPrefix . $i - sql create table $tb using $mt tags( $i ) - - $x = -400 - $y = 0 - while $y < $rowNum - $ms = $x . m - sql insert into $tb values (1626739200000 $ms , $y , $y ) - $x = $x + 1 - $y = $y + 1 - endw - - $i = $i + 1 -endw - -sleep 100 - -print =============== step2 c1 -$i = 1 -$tb = $tbPrefix . $i - -sql select count(*) from $tb interval(1d) -print select count(*) from $tb interval(1d) ===> $data00 $data01 -if $data01 != $rowNum then - return -1 -endi - -$st = $stPrefix . c1 -sql create table $st as select count(*) from $tb interval(1d) - -print =============== step3 c2 -sql select count(tbcol) from $tb interval(1d) -print select count(tbcol) from $tb interval(1d) ===> $data00 $data01 -if $data01 != $rowNum then - return -1 -endi - -$st = $stPrefix . c2 -sql create table $st as select count(tbcol) from $tb interval(1d) - -print =============== step4 c3 -sql select count(tbcol2) from $tb interval(1d) -print select count(tbcol2) from $tb interval(1d) ===> $data00 $data01 -if $data01 != $rowNum then - return -1 -endi - -$st = $stPrefix . c3 -sql create table $st as select count(tbcol2) from $tb interval(1d) - -print =============== step5 avg -sql select avg(tbcol) from $tb interval(1d) -print select avg(tbcol) from $tb interval(1d) ===> $data00 $data01 -if $data01 != 9.500000000 then - return -1 -endi - -$st = $stPrefix . av -sql create table $st as select avg(tbcol) from $tb interval(1d) - -print =============== step6 su -sql select sum(tbcol) from $tb interval(1d) -print select sum(tbcol) from $tb interval(1d) ===> $data00 $data01 -if $data01 != 190 then - return -1 -endi - -$st = $stPrefix . su -sql create table $st as select sum(tbcol) from $tb interval(1d) - -print =============== step7 mi -sql select min(tbcol) from $tb interval(1d) -print select min(tbcol) from $tb interval(1d) ===> $data00 $data01 -if $data01 != 0 then - return -1 -endi - -$st = $stPrefix . mi -sql create table $st as select min(tbcol) from $tb interval(1d) - -print =============== step8 ma -sql select max(tbcol) from $tb interval(1d) -print select max(tbcol) from $tb interval(1d) ===> $data00 $data01 -if $data01 != 19 then - return -1 -endi - -$st = $stPrefix . ma -sql create table $st as select max(tbcol) from $tb interval(1d) - -print =============== step9 fi -sql select first(tbcol) from $tb interval(1d) -print select first(tbcol) from $tb interval(1d) ===> $data00 $data01 -if $data01 != 0 then - return -1 -endi - -$st = $stPrefix . fi -sql create table $st as select first(tbcol) from $tb interval(1d) - -print =============== step10 la -sql select last(tbcol) from $tb interval(1d) -print select last(tbcol) from $tb interval(1d) ===> $data00 $data01 -if $data01 != 19 then - return -1 -endi - -$st = $stPrefix . la -sql create table $st as select last(tbcol) from $tb interval(1d) - -print =============== step11 st -sql select stddev(tbcol) from $tb interval(1d) -print select stddev(tbcol) from $tb interval(1d) ===> $data00 $data01 -if $data01 != 5.766281297 then - return -1 -endi - -$st = $stPrefix . st -sql create table $st as select stddev(tbcol) from $tb interval(1d) - -print =============== step12 le -sql select leastsquares(tbcol, 1, 1) from $tb interval(1d) -print select leastsquares(tbcol, 1, 1) from $tb interval(1d) ===> $data00 $data01 -#if $data01 != @(0.000017, -25362055.126740)@ then -# return -1 -#endi - -$st = $stPrefix . le -sql create table $st as select leastsquares(tbcol, 1, 1) from $tb interval(1d) - -print =============== step13 pe - -sql select percentile(tbcol, 1) from $tb interval(1d) -print select percentile(tbcol, 1) from $tb interval(1d) ===> $data00 $data01 -if $data01 != 0.190000000 then - return -1 -endi - -$st = $stPrefix . pe -sql create table $st as select percentile(tbcol, 1) from $tb interval(1d) - -print =============== step14 wh -sql select count(tbcol) from $tb where ts < 1626739440001 interval(1d) -print select count(tbcol) from $tb where ts < 1626739440001 interval(1d) ===> $data00 $data01 -if $data01 != $rowNum then - return -1 -endi - -$st = $stPrefix . wh -#sql create table $st as select count(tbcol) from $tb where ts < 1626739200000 + 4m interval(1d) - -print =============== step15 as -sql select count(tbcol) from $tb interval(1d) -print select count(tbcol) from $tb interval(1d) ===> $data00 $data01 -if $data01 != $rowNum then - return -1 -endi - -$st = $stPrefix . as -sql create table $st as select count(tbcol) as c from $tb interval(1d) - -print =============== step16 -print sleep 120 seconds -sleep 120000 - -print =============== step17 -$st = $stPrefix . c1 -sql select * from $st -print ===> select * from $st ===> $data00 $data01 -if $data01 != $rowNum then - return -1 -endi - -$st = $stPrefix . c2 -sql select * from $st -print ===> select * from $st ===> $data00 $data01 -if $data01 != $rowNum then - return -1 -endi - -$st = $stPrefix . c3 -sql select * from $st -print ===> select * from $st ===> $data00 $data01 -if $data01 != $rowNum then - return -1 -endi - -$st = $stPrefix . av -sql select * from $st -print ===> select * from $st ===> $data00 $data01 -if $data01 != 9.500000000 then - return -1 -endi - -$st = $stPrefix . su -sql select * from $st -print ===> select * from $st ===> $data00 $data01 -if $data01 != 190 then - return -1 -endi - -$st = $stPrefix . mi -sql select * from $st -print ===> select * from $st ===> $data00 $data01 -if $data01 != 0 then - return -1 -endi - -$st = $stPrefix . ma -sql select * from $st -print ===> select * from $st ===> $data00 $data01 -if $data01 != 19 then - return -1 -endi - -$st = $stPrefix . fi -sql select * from $st -print ===> select * from $st ===> $data00 $data01 -if $data01 != 0 then - return -1 -endi - -$st = $stPrefix . la -sql select * from $st -print ===> select * from $st ===> $data00 $data01 -if $data01 != 19 then - return -1 -endi - -$st = $stPrefix . st -sql select * from $st -print ===> select * from $st ===> $data00 $data01 -if $data01 != 5.766281297 then - return -1 -endi - -$st = $stPrefix . le -sql select * from $st -#print ===> select * from $st ===> $data00 $data01 -#if $data01 != @(0.000017, -25270086.331047)@ then -# return -1 -#endi - -$st = $stPrefix . pe -sql select * from $st -print ===> select * from $st ===> $data00 $data01 -if $data01 != 0.190000000 then - return -1 -endi - -$st = $stPrefix . wh -#sql select * from $st -#print ===> select * from $st ===> $data00 $data01 -#if $data01 != $rowNum then -# return -1 -#endi - -$st = $stPrefix . as -sql select * from $st -print ===> select * from $st ===> $data00 $data01 -if $data01 != $rowNum then - return -1 -endi diff --git a/tests/script/general/stream/testSuite.sim b/tests/script/general/stream/testSuite.sim deleted file mode 100644 index 4a9912b848..0000000000 --- a/tests/script/general/stream/testSuite.sim +++ /dev/null @@ -1,6 +0,0 @@ -run general/stream/stream_3.sim -run general/stream/stream_restart.sim -run general/stream/table_del.sim -run general/stream/metrics_del.sim -run general/stream/table_replica1_vnoden.sim -run general/stream/metrics_replica1_vnoden.sim \ No newline at end of file -- GitLab From d40191b62c9daaefc6e98d1b8c1a11ffdec66b23 Mon Sep 17 00:00:00 2001 From: Haojun Liao Date: Wed, 13 Jul 2022 20:58:14 +0800 Subject: [PATCH 090/153] fix(query): prepare the buffer before loading data. --- source/libs/executor/src/scanoperator.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/libs/executor/src/scanoperator.c b/source/libs/executor/src/scanoperator.c index 8786d30007..ba89592189 100644 --- a/source/libs/executor/src/scanoperator.c +++ b/source/libs/executor/src/scanoperator.c @@ -2593,7 +2593,7 @@ static SSDataBlock* getTableDataBlock(void* param) { SDataBlockInfo binfo = pBlock->info; tsdbRetrieveDataBlockInfo(reader, &binfo); - blockDataEnsureCapacity(pBlock, binfo.capacity); + blockDataEnsureCapacity(pBlock, binfo.rows); pBlock->info.type = binfo.type; pBlock->info.uid = binfo.uid; pBlock->info.window = binfo.window; -- GitLab From 2647a3d9eeb3a12dcb10ca3d3fb2043c94d21047 Mon Sep 17 00:00:00 2001 From: wangmm0220 Date: Wed, 13 Jul 2022 21:00:54 +0800 Subject: [PATCH 091/153] fix: json null --- source/libs/parser/src/parTranslater.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/libs/parser/src/parTranslater.c b/source/libs/parser/src/parTranslater.c index a8fbc8d7ab..87a5258774 100644 --- a/source/libs/parser/src/parTranslater.c +++ b/source/libs/parser/src/parTranslater.c @@ -5846,7 +5846,6 @@ static int32_t buildUpdateTagValReq(STranslateContext* pCxt, SAlterTableStmt* pS return pCxt->errCode; } - pReq->isNull = (TSDB_DATA_TYPE_NULL == pStmt->pVal->node.resType.type); pReq->tagType = targetDt.type; if (targetDt.type == TSDB_DATA_TYPE_JSON) { if (pStmt->pVal->literal && @@ -5876,6 +5875,7 @@ static int32_t buildUpdateTagValReq(STranslateContext* pCxt, SAlterTableStmt* pS pReq->pTagVal = (uint8_t*)pTag; pStmt->pVal->datum.p = (char*)pTag; // for free } else { + pReq->isNull = (TSDB_DATA_TYPE_NULL == pStmt->pVal->node.resType.type); pReq->nTagVal = pStmt->pVal->node.resType.bytes; pReq->pTagVal = nodesGetValueFromNode(pStmt->pVal); -- GitLab From 083de75afcd1fd0a35ee16218374d65f97b53254 Mon Sep 17 00:00:00 2001 From: Haojun Liao Date: Wed, 13 Jul 2022 23:15:58 +0800 Subject: [PATCH 092/153] fix(query):fix memory leak. --- source/common/src/tdatablock.c | 2 -- source/dnode/vnode/src/tsdb/tsdbRead.c | 25 ++++++++++++++++++------- source/libs/executor/src/executorimpl.c | 19 ++++++++++++++++--- source/libs/executor/src/scanoperator.c | 6 ------ source/libs/function/src/builtinsimpl.c | 12 ++++++++++-- 5 files changed, 44 insertions(+), 20 deletions(-) diff --git a/source/common/src/tdatablock.c b/source/common/src/tdatablock.c index 9b65e08d29..f51023189d 100644 --- a/source/common/src/tdatablock.c +++ b/source/common/src/tdatablock.c @@ -1174,8 +1174,6 @@ int32_t colInfoDataEnsureCapacity(SColumnInfoData* pColumn, uint32_t numOfRows) int32_t blockDataEnsureCapacity(SSDataBlock* pDataBlock, uint32_t numOfRows) { int32_t code = 0; - // ASSERT(numOfRows > 0); - if (numOfRows == 0) { return TSDB_CODE_SUCCESS; } diff --git a/source/dnode/vnode/src/tsdb/tsdbRead.c b/source/dnode/vnode/src/tsdb/tsdbRead.c index e86a14a30f..4aaa80d3ae 100644 --- a/source/dnode/vnode/src/tsdb/tsdbRead.c +++ b/source/dnode/vnode/src/tsdb/tsdbRead.c @@ -234,6 +234,7 @@ static void destroyBlockScanInfo(SHashObj* pTableMap) { } taosArrayDestroy(p->delSkyline); + taosArrayDestroy(p->pBlockList); p->delSkyline = NULL; } @@ -302,9 +303,9 @@ static bool filesetIteratorNext(SFilesetIter* pIter, STsdbReader* pReader) { STimeWindow win = {0}; while (1) { -// if (pReader->pFileReader != NULL) { -// tsdbDataFReaderClose(&pReader->pFileReader); -// } + if (pReader->pFileReader != NULL) { + tsdbDataFReaderClose(&pReader->pFileReader); + } pReader->status.pCurrentFileset = (SDFileSet*)taosArrayGet(pIter->pFileList, pIter->index); @@ -696,12 +697,14 @@ static int32_t doLoadFileBlock(STsdbReader* pReader, SArray* pIndexList, uint32_ void* p = taosArrayPush(pScanInfo->pBlockList, &block); if (p == NULL) { + tMapDataClear(&mapData); return TSDB_CODE_OUT_OF_MEMORY; } (*numOfBlocks) += 1; } + tMapDataClear(&mapData); if (pScanInfo->pBlockList != NULL && taosArrayGetSize(pScanInfo->pBlockList) > 0) { (*numOfValidTables) += 1; } @@ -1308,6 +1311,8 @@ static int32_t initBlockIterator(STsdbReader* pReader, SDataBlockIter* pBlockIte pReader->idStr); pBlockIter->index = asc ? 0 : (numOfBlocks - 1); + + cleanupBlockOrderSupporter(&sup); return TSDB_CODE_SUCCESS; } @@ -1990,6 +1995,7 @@ static TSDBKEY getCurrentKeyInBuf(SDataBlockIter* pBlockIter, STsdbReader* pRead static int32_t moveToNextFile(STsdbReader* pReader, int32_t* numOfBlocks) { SReaderStatus* pStatus = &pReader->status; + SArray* pIndexList = taosArrayInit(4, sizeof(SBlockIdx)); while (1) { bool hasNext = filesetIteratorNext(&pStatus->fileIter, pReader); @@ -1997,9 +2003,10 @@ static int32_t moveToNextFile(STsdbReader* pReader, int32_t* numOfBlocks) { break; } - SArray* pIndexList = taosArrayInit(4, sizeof(SBlockIdx)); + taosArrayClear(pIndexList); int32_t code = doLoadBlockIndex(pReader, pReader->pFileReader, pIndexList); if (code != TSDB_CODE_SUCCESS) { + taosArrayDestroy(pIndexList); return code; } @@ -2007,6 +2014,7 @@ static int32_t moveToNextFile(STsdbReader* pReader, int32_t* numOfBlocks) { uint32_t numOfValidTable = 0; code = doLoadFileBlock(pReader, pIndexList, &numOfValidTable, numOfBlocks); if (code != TSDB_CODE_SUCCESS) { + taosArrayDestroy(pIndexList); return code; } @@ -2014,10 +2022,10 @@ static int32_t moveToNextFile(STsdbReader* pReader, int32_t* numOfBlocks) { break; } } - // no blocks in current file, try next files } + taosArrayDestroy(pIndexList); return TSDB_CODE_SUCCESS; } @@ -3081,10 +3089,13 @@ int32_t tsdbGetFileBlocksDistInfo(STsdbReader* pReader, STableBlockDistInfo* pTa SDataBlockIter* pBlockIter = &pStatus->blockIter; pTableBlockInfo->numOfFiles += pStatus->fileIter.numOfFiles; - pTableBlockInfo->numOfBlocks += pBlockIter->numOfBlocks; + + if (pBlockIter->numOfBlocks > 0) { + pTableBlockInfo->numOfBlocks += pBlockIter->numOfBlocks; + } pTableBlockInfo->numOfTables = numOfTables; - bool hasNext = true; + bool hasNext = (pBlockIter->numOfBlocks > 0); while (true) { if (hasNext) { diff --git a/source/libs/executor/src/executorimpl.c b/source/libs/executor/src/executorimpl.c index 760d7e55c8..4e69caae0c 100644 --- a/source/libs/executor/src/executorimpl.c +++ b/source/libs/executor/src/executorimpl.c @@ -3475,10 +3475,13 @@ static SSDataBlock* doFill(SOperatorInfo* pOperator) { static void destroyExprInfo(SExprInfo* pExpr, int32_t numOfExprs) { for (int32_t i = 0; i < numOfExprs; ++i) { SExprInfo* pExprInfo = &pExpr[i]; - if (pExprInfo->pExpr->nodeType == QUERY_NODE_COLUMN) { - taosMemoryFree(pExprInfo->base.pParam[0].pCol); + for(int32_t j = 0; j < pExprInfo->base.numOfParams; ++j) { + if (pExprInfo->base.pParam[j].type == FUNC_PARAM_TYPE_COLUMN) { + taosMemoryFreeClear(pExprInfo->base.pParam[j].pCol); + } + taosMemoryFree(pExprInfo->base.pParam); } - taosMemoryFree(pExprInfo->base.pParam); + taosMemoryFree(pExprInfo->pExpr); } } @@ -3685,10 +3688,20 @@ void destroyBasicOperatorInfo(void* param, int32_t numOfOutput) { taosMemoryFreeClear(param); } + +static void freeItem(void* pItem) { + void** p = pItem; + if (*p != NULL) { + taosMemoryFreeClear(*p); + } +} + void destroyAggOperatorInfo(void* param, int32_t numOfOutput) { SAggOperatorInfo* pInfo = (SAggOperatorInfo*)param; cleanupBasicInfo(&pInfo->binfo); + cleanupAggSup(&pInfo->aggSup); + taosArrayDestroyEx(pInfo->groupResInfo.pRows, freeItem); taosMemoryFreeClear(param); } diff --git a/source/libs/executor/src/scanoperator.c b/source/libs/executor/src/scanoperator.c index c7112ab8a6..2098e515df 100644 --- a/source/libs/executor/src/scanoperator.c +++ b/source/libs/executor/src/scanoperator.c @@ -196,12 +196,6 @@ static int32_t loadDataBlock(SOperatorInfo* pOperator, STableScanInfo* pTableSca pBlockInfo->window.skey, pBlockInfo->window.ekey, pBlockInfo->rows); pCost->skipBlocks += 1; - // clear all data in pBlock that are set when handing the previous block - for (int32_t i = 0; i < taosArrayGetSize(pBlock->pDataBlock); ++i) { - SColumnInfoData* pcol = taosArrayGet(pBlock->pDataBlock, i); - pcol->pData = NULL; - } - return TSDB_CODE_SUCCESS; } else if (*status == FUNC_DATA_REQUIRED_STATIS_LOAD) { pCost->loadBlockStatis += 1; diff --git a/source/libs/function/src/builtinsimpl.c b/source/libs/function/src/builtinsimpl.c index c1143020f0..e622c0c1af 100644 --- a/source/libs/function/src/builtinsimpl.c +++ b/source/libs/function/src/builtinsimpl.c @@ -5559,6 +5559,10 @@ int32_t blockDistFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock) { SColumnInfoData* pColInfo = taosArrayGet(pBlock->pDataBlock, 0); + if (pData->totalRows == 0) { + pData->minRows = 0; + } + int32_t row = 0; char st[256] = {0}; double totalRawSize = pData->totalRows * pData->rowSize; @@ -5570,10 +5574,14 @@ int32_t blockDistFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock) { varDataSetLen(st, len); colDataAppend(pColInfo, row++, st, false); + int64_t avgRows = 0; + if (pData->numOfBlocks > 0) { + avgRows = pData->totalRows / pData->numOfBlocks; + } + len = sprintf(st + VARSTR_HEADER_SIZE, "Total_Rows=[%" PRId64 "] Inmem_Rows=[%d] MinRows=[%d] MaxRows=[%d] Average_Rows=[%" PRId64 "]", - pData->totalRows, pData->numOfInmemRows, pData->minRows, pData->maxRows, - pData->totalRows / pData->numOfBlocks); + pData->totalRows, pData->numOfInmemRows, pData->minRows, pData->maxRows, avgRows); varDataSetLen(st, len); colDataAppend(pColInfo, row++, st, false); -- GitLab From b2b69f18689ca8c86b1e4ad1ed65647d781eeb42 Mon Sep 17 00:00:00 2001 From: Haojun Liao Date: Wed, 13 Jul 2022 23:42:59 +0800 Subject: [PATCH 093/153] fix(query):fix invalid write. --- source/libs/executor/src/executorimpl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/libs/executor/src/executorimpl.c b/source/libs/executor/src/executorimpl.c index 4e69caae0c..16f5e47efc 100644 --- a/source/libs/executor/src/executorimpl.c +++ b/source/libs/executor/src/executorimpl.c @@ -3479,9 +3479,9 @@ static void destroyExprInfo(SExprInfo* pExpr, int32_t numOfExprs) { if (pExprInfo->base.pParam[j].type == FUNC_PARAM_TYPE_COLUMN) { taosMemoryFreeClear(pExprInfo->base.pParam[j].pCol); } - taosMemoryFree(pExprInfo->base.pParam); } + taosMemoryFree(pExprInfo->base.pParam); taosMemoryFree(pExprInfo->pExpr); } } -- GitLab From 414b27fb6a8901fce080c0e2c615c67f2602ea47 Mon Sep 17 00:00:00 2001 From: "slzhou@taodata.com" Date: Thu, 14 Jul 2022 09:19:36 +0800 Subject: [PATCH 094/153] fix: set primary key target slot id through searching scan cols and find colId that equals primary key id --- source/libs/executor/src/scanoperator.c | 14 +++++++++++--- source/libs/nodes/src/nodesCodeFuncs.c | 2 ++ 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/source/libs/executor/src/scanoperator.c b/source/libs/executor/src/scanoperator.c index 64c740decf..5bdee36e7a 100644 --- a/source/libs/executor/src/scanoperator.c +++ b/source/libs/executor/src/scanoperator.c @@ -2621,11 +2621,19 @@ static SSDataBlock* getTableDataBlock(void* param) { return NULL; } -SArray* generateSortByTsInfo(int32_t order) { +SArray* generateSortByTsInfo(SArray* colMatchInfo, int32_t order) { + int32_t tsTargetSlotId = 0; + for (int32_t i = 0; i < taosArrayGetSize(colMatchInfo); ++i) { + SColMatchInfo* colInfo = taosArrayGet(colMatchInfo, i); + if (colInfo->colId == PRIMARYKEY_TIMESTAMP_COL_ID) { + tsTargetSlotId = colInfo->targetSlotId; + } + } + SArray* pList = taosArrayInit(1, sizeof(SBlockOrderInfo)); SBlockOrderInfo bi = {0}; bi.order = order; - bi.slotId = 0; + bi.slotId = tsTargetSlotId; bi.nullFirst = NULL_ORDER_FIRST; taosArrayPush(pList, &bi); @@ -2874,7 +2882,7 @@ SOperatorInfo* createTableMergeScanOperatorInfo(STableScanPhysiNode* pTableScanN pInfo->sortSourceParams = taosArrayInit(64, sizeof(STableMergeScanSortSourceParam)); - pInfo->pSortInfo = generateSortByTsInfo(pInfo->cond.order); + pInfo->pSortInfo = generateSortByTsInfo(pInfo->pColMatchInfo, pInfo->cond.order); pInfo->pSortInputBlock = createOneDataBlock(pInfo->pResBlock, false); int32_t rowSize = pInfo->pResBlock->info.rowSize; diff --git a/source/libs/nodes/src/nodesCodeFuncs.c b/source/libs/nodes/src/nodesCodeFuncs.c index 3c285cc7f1..b6ebebd761 100644 --- a/source/libs/nodes/src/nodesCodeFuncs.c +++ b/source/libs/nodes/src/nodesCodeFuncs.c @@ -225,6 +225,8 @@ const char* nodesNodeName(ENodeType type) { return "PhysiBlockDistScan"; case QUERY_NODE_PHYSICAL_PLAN_LAST_ROW_SCAN: return "PhysiLastRowScan"; + case QUERY_NODE_PHYSICAL_PLAN_TABLE_MERGE_SCAN: + return "PhysiTableMergeScan"; case QUERY_NODE_PHYSICAL_PLAN_PROJECT: return "PhysiProject"; case QUERY_NODE_PHYSICAL_PLAN_MERGE_JOIN: -- GitLab From 9d13ee914841aefc8829893af33a518ac14aebb5 Mon Sep 17 00:00:00 2001 From: Shengliang Guan Date: Thu, 14 Jul 2022 10:20:30 +0800 Subject: [PATCH 095/153] test: restore some 2.0 case --- tests/script/general/rm_bak/tag/testSuite.sim | 25 ----------------- tests/script/jenkins/basic.txt | 28 +++++++++++++++++++ .../script/{general/rm_bak => tsim}/tag/3.sim | 17 +++++------ .../script/{general/rm_bak => tsim}/tag/4.sim | 8 +----- .../script/{general/rm_bak => tsim}/tag/5.sim | 8 +----- .../script/{general/rm_bak => tsim}/tag/6.sim | 8 +----- .../{general/rm_bak => tsim}/tag/add.sim | 6 +--- .../{general/rm_bak => tsim}/tag/bigint.sim | 7 +---- .../{general/rm_bak => tsim}/tag/binary.sim | 7 +---- .../rm_bak => tsim}/tag/binary_binary.sim | 7 +---- .../{general/rm_bak => tsim}/tag/bool.sim | 7 +---- .../rm_bak => tsim}/tag/bool_binary.sim | 7 +---- .../{general/rm_bak => tsim}/tag/bool_int.sim | 7 +---- .../{general/rm_bak => tsim}/tag/change.sim | 6 +--- .../{general/rm_bak => tsim}/tag/column.sim | 7 +---- .../{general/rm_bak => tsim}/tag/commit.sim | 6 +--- .../{general/rm_bak => tsim}/tag/create.sim | 5 ---- .../{general/rm_bak => tsim}/tag/delete.sim | 6 +--- .../{general/rm_bak => tsim}/tag/double.sim | 7 +---- .../{general/rm_bak => tsim}/tag/filter.sim | 4 +-- .../{general/rm_bak => tsim}/tag/float.sim | 7 +---- .../{general/rm_bak => tsim}/tag/int.sim | 7 +---- .../rm_bak => tsim}/tag/int_binary.sim | 7 +---- .../rm_bak => tsim}/tag/int_float.sim | 7 +---- .../{general/rm_bak => tsim}/tag/set.sim | 6 +--- .../{general/rm_bak => tsim}/tag/smallint.sim | 7 +---- .../{general/rm_bak => tsim}/tag/tinyint.sim | 7 +---- 27 files changed, 58 insertions(+), 173 deletions(-) delete mode 100644 tests/script/general/rm_bak/tag/testSuite.sim rename tests/script/{general/rm_bak => tsim}/tag/3.sim (97%) rename tests/script/{general/rm_bak => tsim}/tag/4.sim (99%) rename tests/script/{general/rm_bak => tsim}/tag/5.sim (99%) rename tests/script/{general/rm_bak => tsim}/tag/6.sim (99%) rename tests/script/{general/rm_bak => tsim}/tag/add.sim (99%) rename tests/script/{general/rm_bak => tsim}/tag/bigint.sim (97%) rename tests/script/{general/rm_bak => tsim}/tag/binary.sim (97%) rename tests/script/{general/rm_bak => tsim}/tag/binary_binary.sim (98%) rename tests/script/{general/rm_bak => tsim}/tag/bool.sim (97%) rename tests/script/{general/rm_bak => tsim}/tag/bool_binary.sim (98%) rename tests/script/{general/rm_bak => tsim}/tag/bool_int.sim (98%) rename tests/script/{general/rm_bak => tsim}/tag/change.sim (98%) rename tests/script/{general/rm_bak => tsim}/tag/column.sim (92%) rename tests/script/{general/rm_bak => tsim}/tag/commit.sim (99%) rename tests/script/{general/rm_bak => tsim}/tag/create.sim (99%) rename tests/script/{general/rm_bak => tsim}/tag/delete.sim (99%) rename tests/script/{general/rm_bak => tsim}/tag/double.sim (97%) rename tests/script/{general/rm_bak => tsim}/tag/filter.sim (98%) rename tests/script/{general/rm_bak => tsim}/tag/float.sim (97%) rename tests/script/{general/rm_bak => tsim}/tag/int.sim (97%) rename tests/script/{general/rm_bak => tsim}/tag/int_binary.sim (98%) rename tests/script/{general/rm_bak => tsim}/tag/int_float.sim (98%) rename tests/script/{general/rm_bak => tsim}/tag/set.sim (98%) rename tests/script/{general/rm_bak => tsim}/tag/smallint.sim (97%) rename tests/script/{general/rm_bak => tsim}/tag/tinyint.sim (97%) diff --git a/tests/script/general/rm_bak/tag/testSuite.sim b/tests/script/general/rm_bak/tag/testSuite.sim deleted file mode 100644 index 45356efac1..0000000000 --- a/tests/script/general/rm_bak/tag/testSuite.sim +++ /dev/null @@ -1,25 +0,0 @@ -run general/tag/3.sim -run general/tag/4.sim -run general/tag/5.sim -run general/tag/6.sim -run general/tag/add.sim -run general/tag/bigint.sim -run general/tag/binary_binary.sim -run general/tag/binary.sim -run general/tag/bool_binary.sim -run general/tag/bool_int.sim -run general/tag/bool.sim -run general/tag/change.sim -run general/tag/column.sim -run general/tag/commit.sim -run general/tag/create.sim -run general/tag/delete.sim -run general/tag/double.sim -run general/tag/filter.sim -run general/tag/float.sim -run general/tag/int_binary.sim -run general/tag/int_float.sim -run general/tag/int.sim -run general/tag/set.sim -run general/tag/smallint.sim -run general/tag/tinyint.sim diff --git a/tests/script/jenkins/basic.txt b/tests/script/jenkins/basic.txt index dad4dbbe29..af0e338c9b 100644 --- a/tests/script/jenkins/basic.txt +++ b/tests/script/jenkins/basic.txt @@ -279,4 +279,32 @@ # ---- wal ./test.sh -f tsim/wal/kill.sim +# ---- tag +./test.sh -f tsim/tag/3.sim +./test.sh -f tsim/tag/4.sim +./test.sh -f tsim/tag/5.sim +./test.sh -f tsim/tag/6.sim +./test.sh -f tsim/tag/add.sim +./test.sh -f tsim/tag/bigint.sim +./test.sh -f tsim/tag/binary_binary.sim +./test.sh -f tsim/tag/binary.sim +./test.sh -f tsim/tag/bool_binary.sim +./test.sh -f tsim/tag/bool_int.sim +./test.sh -f tsim/tag/bool.sim +./test.sh -f tsim/tag/change.sim +./test.sh -f tsim/tag/column.sim +./test.sh -f tsim/tag/commit.sim +./test.sh -f tsim/tag/create.sim +./test.sh -f tsim/tag/delete.sim +./test.sh -f tsim/tag/double.sim +./test.sh -f tsim/tag/filter.sim +./test.sh -f tsim/tag/float.sim +./test.sh -f tsim/tag/int_binary.sim +./test.sh -f tsim/tag/int_float.sim +./test.sh -f tsim/tag/int.sim +./test.sh -f tsim/tag/set.sim +./test.sh -f tsim/tag/smallint.sim +./test.sh -f tsim/tag/tinyint.sim + + #======================b1-end=============== diff --git a/tests/script/general/rm_bak/tag/3.sim b/tests/script/tsim/tag/3.sim similarity index 97% rename from tests/script/general/rm_bak/tag/3.sim rename to tests/script/tsim/tag/3.sim index 20185f5f01..d816aec3e3 100644 --- a/tests/script/general/rm_bak/tag/3.sim +++ b/tests/script/tsim/tag/3.sim @@ -1,9 +1,6 @@ system sh/stop_dnodes.sh system sh/deploy.sh -n dnode1 -i 1 -system sh/cfg.sh -n dnode1 -c walLevel -v 1 system sh/exec.sh -n dnode1 -s start - -sleep 2000 sql connect print ======================== dnode1 start @@ -494,28 +491,28 @@ if $data00 != 25 then endi print =============== step19 -sql select count(tbcol), avg(tbcol), sum(tbcol), min(tbcol), max(tbcol), first(tbcol), last(tbcol) from $mt where tgcol1 = true and tgcol2 = 1 and tgcol3 = 1 interval(1d) group by tgcol1 +sql select count(tbcol), avg(tbcol), sum(tbcol), min(tbcol), max(tbcol), first(tbcol), last(tbcol) from $mt where tgcol1 = true and tgcol2 = 1 and tgcol3 = 1 partition by tgcol1 interval(1d) print $data00 $data01 $data02 $data03 $data04 $data05 $data06 -if $data01 != 100 then +if $data00 != 100 then return -1 endi -sql select count(tbcol), avg(tbcol), sum(tbcol), min(tbcol), max(tbcol), first(tbcol), last(tbcol) from $mt where tgcol1 = true and tgcol2 = 1 and tgcol3 = 1 interval(1d) group by tgcol2 +sql select count(tbcol), avg(tbcol), sum(tbcol), min(tbcol), max(tbcol), first(tbcol), last(tbcol) from $mt where tgcol1 = true and tgcol2 = 1 and tgcol3 = 1 partition by tgcol2 interval(1d) print $data00 $data01 $data02 $data03 $data04 $data05 $data06 -if $data01 != 100 then +if $data00 != 100 then return -1 endi -sql select count(tbcol), avg(tbcol), sum(tbcol), min(tbcol), max(tbcol), first(tbcol), last(tbcol) from $mt where tgcol1 = true and tgcol2 = 1 and tgcol3 = 1 interval(1d) group by tgcol3 +sql select count(tbcol), avg(tbcol), sum(tbcol), min(tbcol), max(tbcol), first(tbcol), last(tbcol) from $mt where tgcol1 = true and tgcol2 = 1 and tgcol3 = 1 partition by tgcol3 interval(1d) print $data00 $data01 $data02 $data03 $data04 $data05 $data06 -if $data01 != 100 then +if $data00 != 100 then return -1 endi print =============== clear sql drop database $db sql show databases -if $rows != 0 then +if $rows != 2 then return -1 endi diff --git a/tests/script/general/rm_bak/tag/4.sim b/tests/script/tsim/tag/4.sim similarity index 99% rename from tests/script/general/rm_bak/tag/4.sim rename to tests/script/tsim/tag/4.sim index ee3c8efa6c..0bb1cde75d 100644 --- a/tests/script/general/rm_bak/tag/4.sim +++ b/tests/script/tsim/tag/4.sim @@ -1,13 +1,7 @@ system sh/stop_dnodes.sh - - system sh/deploy.sh -n dnode1 -i 1 -system sh/cfg.sh -n dnode1 -c walLevel -v 1 system sh/exec.sh -n dnode1 -s start - -sleep 2000 sql connect -sql reset query cache print ======================== dnode1 start @@ -708,7 +702,7 @@ endi print =============== clear sql drop database $db sql show databases -if $rows != 0 then +if $rows != 2 then return -1 endi diff --git a/tests/script/general/rm_bak/tag/5.sim b/tests/script/tsim/tag/5.sim similarity index 99% rename from tests/script/general/rm_bak/tag/5.sim rename to tests/script/tsim/tag/5.sim index 895b1a9492..e3edbcaa5d 100644 --- a/tests/script/general/rm_bak/tag/5.sim +++ b/tests/script/tsim/tag/5.sim @@ -1,13 +1,7 @@ system sh/stop_dnodes.sh - - system sh/deploy.sh -n dnode1 -i 1 -system sh/cfg.sh -n dnode1 -c walLevel -v 1 system sh/exec.sh -n dnode1 -s start - -sleep 2000 sql connect -sql reset query cache print ======================== dnode1 start @@ -831,7 +825,7 @@ endi print =============== clear sql drop database $db sql show databases -if $rows != 0 then +if $rows != 2 then return -1 endi diff --git a/tests/script/general/rm_bak/tag/6.sim b/tests/script/tsim/tag/6.sim similarity index 99% rename from tests/script/general/rm_bak/tag/6.sim rename to tests/script/tsim/tag/6.sim index 9190998bb3..d4e1d52c3c 100644 --- a/tests/script/general/rm_bak/tag/6.sim +++ b/tests/script/tsim/tag/6.sim @@ -1,13 +1,7 @@ system sh/stop_dnodes.sh - - system sh/deploy.sh -n dnode1 -i 1 -system sh/cfg.sh -n dnode1 -c walLevel -v 1 system sh/exec.sh -n dnode1 -s start - -sleep 2000 sql connect -sql reset query cache print ======================== dnode1 start @@ -986,7 +980,7 @@ endi print =============== clear sql drop database $db sql show databases -if $rows != 0 then +if $rows != 2 then return -1 endi diff --git a/tests/script/general/rm_bak/tag/add.sim b/tests/script/tsim/tag/add.sim similarity index 99% rename from tests/script/general/rm_bak/tag/add.sim rename to tests/script/tsim/tag/add.sim index 4a3871235e..2901614889 100644 --- a/tests/script/general/rm_bak/tag/add.sim +++ b/tests/script/tsim/tag/add.sim @@ -1,10 +1,6 @@ system sh/stop_dnodes.sh - system sh/deploy.sh -n dnode1 -i 1 -system sh/cfg.sh -n dnode1 -c walLevel -v 2 system sh/exec.sh -n dnode1 -s start - -sleep 2000 sql connect print ======================== dnode1 start @@ -849,7 +845,7 @@ step142: print =============== clear sql drop database $db sql show databases -if $rows != 0 then +if $rows != 2 then return -1 endi diff --git a/tests/script/general/rm_bak/tag/bigint.sim b/tests/script/tsim/tag/bigint.sim similarity index 97% rename from tests/script/general/rm_bak/tag/bigint.sim rename to tests/script/tsim/tag/bigint.sim index 3e5d528980..2e1af227c0 100644 --- a/tests/script/general/rm_bak/tag/bigint.sim +++ b/tests/script/tsim/tag/bigint.sim @@ -1,11 +1,6 @@ system sh/stop_dnodes.sh - - system sh/deploy.sh -n dnode1 -i 1 -system sh/cfg.sh -n dnode1 -c walLevel -v 1 system sh/exec.sh -n dnode1 -s start - -sleep 2000 sql connect print ======================== dnode1 start @@ -237,7 +232,7 @@ endi print =============== clear sql drop database $db sql show databases -if $rows != 0 then +if $rows != 2 then return -1 endi diff --git a/tests/script/general/rm_bak/tag/binary.sim b/tests/script/tsim/tag/binary.sim similarity index 97% rename from tests/script/general/rm_bak/tag/binary.sim rename to tests/script/tsim/tag/binary.sim index 960f45675d..2cabf30bb1 100644 --- a/tests/script/general/rm_bak/tag/binary.sim +++ b/tests/script/tsim/tag/binary.sim @@ -1,11 +1,6 @@ system sh/stop_dnodes.sh - - system sh/deploy.sh -n dnode1 -i 1 -system sh/cfg.sh -n dnode1 -c walLevel -v 1 system sh/exec.sh -n dnode1 -s start - -sleep 2000 sql connect print ======================== dnode1 start @@ -237,7 +232,7 @@ endi print =============== clear sql drop database $db sql show databases -if $rows != 0 then +if $rows != 2 then return -1 endi diff --git a/tests/script/general/rm_bak/tag/binary_binary.sim b/tests/script/tsim/tag/binary_binary.sim similarity index 98% rename from tests/script/general/rm_bak/tag/binary_binary.sim rename to tests/script/tsim/tag/binary_binary.sim index 3a0fb56848..8a77de5226 100644 --- a/tests/script/general/rm_bak/tag/binary_binary.sim +++ b/tests/script/tsim/tag/binary_binary.sim @@ -1,11 +1,6 @@ system sh/stop_dnodes.sh - - system sh/deploy.sh -n dnode1 -i 1 -system sh/cfg.sh -n dnode1 -c walLevel -v 1 system sh/exec.sh -n dnode1 -s start - -sleep 2000 sql connect print ======================== dnode1 start @@ -304,7 +299,7 @@ endi print =============== clear sql drop database $db sql show databases -if $rows != 0 then +if $rows != 2 then return -1 endi diff --git a/tests/script/general/rm_bak/tag/bool.sim b/tests/script/tsim/tag/bool.sim similarity index 97% rename from tests/script/general/rm_bak/tag/bool.sim rename to tests/script/tsim/tag/bool.sim index e37cba669b..26e320c41e 100644 --- a/tests/script/general/rm_bak/tag/bool.sim +++ b/tests/script/tsim/tag/bool.sim @@ -1,11 +1,6 @@ system sh/stop_dnodes.sh - - system sh/deploy.sh -n dnode1 -i 1 -system sh/cfg.sh -n dnode1 -c walLevel -v 1 system sh/exec.sh -n dnode1 -s start - -sleep 2000 sql connect print ======================== dnode1 start @@ -235,7 +230,7 @@ endi print =============== clear sql drop database $db sql show databases -if $rows != 0 then +if $rows != 2 then return -1 endi diff --git a/tests/script/general/rm_bak/tag/bool_binary.sim b/tests/script/tsim/tag/bool_binary.sim similarity index 98% rename from tests/script/general/rm_bak/tag/bool_binary.sim rename to tests/script/tsim/tag/bool_binary.sim index 9f6e4f7344..d776127757 100644 --- a/tests/script/general/rm_bak/tag/bool_binary.sim +++ b/tests/script/tsim/tag/bool_binary.sim @@ -1,11 +1,6 @@ system sh/stop_dnodes.sh - - system sh/deploy.sh -n dnode1 -i 1 -system sh/cfg.sh -n dnode1 -c walLevel -v 1 system sh/exec.sh -n dnode1 -s start - -sleep 2000 sql connect print ======================== dnode1 start @@ -304,7 +299,7 @@ endi print =============== clear sql drop database $db sql show databases -if $rows != 0 then +if $rows != 2 then return -1 endi diff --git a/tests/script/general/rm_bak/tag/bool_int.sim b/tests/script/tsim/tag/bool_int.sim similarity index 98% rename from tests/script/general/rm_bak/tag/bool_int.sim rename to tests/script/tsim/tag/bool_int.sim index 60345c2d68..daeb0c711f 100644 --- a/tests/script/general/rm_bak/tag/bool_int.sim +++ b/tests/script/tsim/tag/bool_int.sim @@ -1,11 +1,6 @@ system sh/stop_dnodes.sh - - system sh/deploy.sh -n dnode1 -i 1 -system sh/cfg.sh -n dnode1 -c walLevel -v 1 system sh/exec.sh -n dnode1 -s start - -sleep 2000 sql connect print ======================== dnode1 start @@ -320,7 +315,7 @@ endi print =============== clear sql drop database $db sql show databases -if $rows != 0 then +if $rows != 2 then return -1 endi diff --git a/tests/script/general/rm_bak/tag/change.sim b/tests/script/tsim/tag/change.sim similarity index 98% rename from tests/script/general/rm_bak/tag/change.sim rename to tests/script/tsim/tag/change.sim index 6f294c0f48..f58e387217 100644 --- a/tests/script/general/rm_bak/tag/change.sim +++ b/tests/script/tsim/tag/change.sim @@ -1,10 +1,6 @@ system sh/stop_dnodes.sh - system sh/deploy.sh -n dnode1 -i 1 -system sh/cfg.sh -n dnode1 -c walLevel -v 2 system sh/exec.sh -n dnode1 -s start - -sleep 2000 sql connect print ======================== dnode1 start @@ -508,7 +504,7 @@ endi print =============== clear sql drop database $db sql show databases -if $rows != 0 then +if $rows != 2 then return -1 endi diff --git a/tests/script/general/rm_bak/tag/column.sim b/tests/script/tsim/tag/column.sim similarity index 92% rename from tests/script/general/rm_bak/tag/column.sim rename to tests/script/tsim/tag/column.sim index 5a0cd169c5..c73999230f 100644 --- a/tests/script/general/rm_bak/tag/column.sim +++ b/tests/script/tsim/tag/column.sim @@ -1,11 +1,6 @@ system sh/stop_dnodes.sh - - system sh/deploy.sh -n dnode1 -i 1 -system sh/cfg.sh -n dnode1 -c walLevel -v 1 system sh/exec.sh -n dnode1 -s start - -sleep 2000 sql connect print ======================== dnode1 start @@ -89,7 +84,7 @@ endi print =============== clear sql drop database $db sql show databases -if $rows != 0 then +if $rows != 2 then return -1 endi diff --git a/tests/script/general/rm_bak/tag/commit.sim b/tests/script/tsim/tag/commit.sim similarity index 99% rename from tests/script/general/rm_bak/tag/commit.sim rename to tests/script/tsim/tag/commit.sim index bcd9d7c618..18128fc464 100644 --- a/tests/script/general/rm_bak/tag/commit.sim +++ b/tests/script/tsim/tag/commit.sim @@ -1,10 +1,6 @@ system sh/stop_dnodes.sh - system sh/deploy.sh -n dnode1 -i 1 -system sh/cfg.sh -n dnode1 -c walLevel -v 2 system sh/exec.sh -n dnode1 -s start - -sleep 2000 sql connect print ======================== dnode1 start @@ -1177,7 +1173,7 @@ endi print =============== clear sql drop database $db sql show databases -if $rows != 0 then +if $rows != 2 then return -1 endi diff --git a/tests/script/general/rm_bak/tag/create.sim b/tests/script/tsim/tag/create.sim similarity index 99% rename from tests/script/general/rm_bak/tag/create.sim rename to tests/script/tsim/tag/create.sim index 95b4166543..e25f1eb71f 100644 --- a/tests/script/general/rm_bak/tag/create.sim +++ b/tests/script/tsim/tag/create.sim @@ -1,11 +1,6 @@ system sh/stop_dnodes.sh - - system sh/deploy.sh -n dnode1 -i 1 -system sh/cfg.sh -n dnode1 -c walLevel -v 1 system sh/exec.sh -n dnode1 -s start - -sleep 2000 sql connect print ======================== dnode1 start diff --git a/tests/script/general/rm_bak/tag/delete.sim b/tests/script/tsim/tag/delete.sim similarity index 99% rename from tests/script/general/rm_bak/tag/delete.sim rename to tests/script/tsim/tag/delete.sim index 2a0aa27bde..bcfd822dbd 100644 --- a/tests/script/general/rm_bak/tag/delete.sim +++ b/tests/script/tsim/tag/delete.sim @@ -1,10 +1,6 @@ system sh/stop_dnodes.sh - system sh/deploy.sh -n dnode1 -i 1 -system sh/cfg.sh -n dnode1 -c walLevel -v 2 system sh/exec.sh -n dnode1 -s start - -sleep 2000 sql connect print ======================== dnode1 start @@ -820,7 +816,7 @@ step145: print =============== clear sql drop database $db sql show databases -if $rows != 0 then +if $rows != 2 then return -1 endi diff --git a/tests/script/general/rm_bak/tag/double.sim b/tests/script/tsim/tag/double.sim similarity index 97% rename from tests/script/general/rm_bak/tag/double.sim rename to tests/script/tsim/tag/double.sim index f17043393f..3f936318fb 100644 --- a/tests/script/general/rm_bak/tag/double.sim +++ b/tests/script/tsim/tag/double.sim @@ -1,11 +1,6 @@ system sh/stop_dnodes.sh - - system sh/deploy.sh -n dnode1 -i 1 -system sh/cfg.sh -n dnode1 -c walLevel -v 1 system sh/exec.sh -n dnode1 -s start - -sleep 2000 sql connect print ======================== dnode1 start @@ -237,7 +232,7 @@ endi print =============== clear sql drop database $db sql show databases -if $rows != 0 then +if $rows != 2 then return -1 endi diff --git a/tests/script/general/rm_bak/tag/filter.sim b/tests/script/tsim/tag/filter.sim similarity index 98% rename from tests/script/general/rm_bak/tag/filter.sim rename to tests/script/tsim/tag/filter.sim index 7a899a7e67..b9f2df0cc6 100644 --- a/tests/script/general/rm_bak/tag/filter.sim +++ b/tests/script/tsim/tag/filter.sim @@ -1,8 +1,6 @@ system sh/stop_dnodes.sh system sh/deploy.sh -n dnode1 -i 1 system sh/exec.sh -n dnode1 -s start - -sleep 2000 sql connect print ======================== dnode1 start @@ -142,7 +140,7 @@ endi print =============== clear sql drop database $db sql show databases -if $rows != 0 then +if $rows != 2 then return -1 endi diff --git a/tests/script/general/rm_bak/tag/float.sim b/tests/script/tsim/tag/float.sim similarity index 97% rename from tests/script/general/rm_bak/tag/float.sim rename to tests/script/tsim/tag/float.sim index 35bf7d6090..215869e003 100644 --- a/tests/script/general/rm_bak/tag/float.sim +++ b/tests/script/tsim/tag/float.sim @@ -1,11 +1,6 @@ system sh/stop_dnodes.sh - - system sh/deploy.sh -n dnode1 -i 1 -system sh/cfg.sh -n dnode1 -c walLevel -v 1 system sh/exec.sh -n dnode1 -s start - -sleep 2000 sql connect print ======================== dnode1 start @@ -237,7 +232,7 @@ endi print =============== clear sql drop database $db sql show databases -if $rows != 0 then +if $rows != 2 then return -1 endi diff --git a/tests/script/general/rm_bak/tag/int.sim b/tests/script/tsim/tag/int.sim similarity index 97% rename from tests/script/general/rm_bak/tag/int.sim rename to tests/script/tsim/tag/int.sim index 4eea02c9cd..d97079de91 100644 --- a/tests/script/general/rm_bak/tag/int.sim +++ b/tests/script/tsim/tag/int.sim @@ -1,11 +1,6 @@ system sh/stop_dnodes.sh - - system sh/deploy.sh -n dnode1 -i 1 -system sh/cfg.sh -n dnode1 -c walLevel -v 1 system sh/exec.sh -n dnode1 -s start - -sleep 2000 sql connect print ======================== dnode1 start @@ -237,7 +232,7 @@ endi print =============== clear sql drop database $db sql show databases -if $rows != 0 then +if $rows != 2 then return -1 endi diff --git a/tests/script/general/rm_bak/tag/int_binary.sim b/tests/script/tsim/tag/int_binary.sim similarity index 98% rename from tests/script/general/rm_bak/tag/int_binary.sim rename to tests/script/tsim/tag/int_binary.sim index 9a75697676..fef77a16d9 100644 --- a/tests/script/general/rm_bak/tag/int_binary.sim +++ b/tests/script/tsim/tag/int_binary.sim @@ -1,11 +1,6 @@ system sh/stop_dnodes.sh - - system sh/deploy.sh -n dnode1 -i 1 -system sh/cfg.sh -n dnode1 -c walLevel -v 1 system sh/exec.sh -n dnode1 -s start - -sleep 2000 sql connect print ======================== dnode1 start @@ -304,7 +299,7 @@ endi print =============== clear sql drop database $db sql show databases -if $rows != 0 then +if $rows != 2 then return -1 endi diff --git a/tests/script/general/rm_bak/tag/int_float.sim b/tests/script/tsim/tag/int_float.sim similarity index 98% rename from tests/script/general/rm_bak/tag/int_float.sim rename to tests/script/tsim/tag/int_float.sim index a03c4b7148..f184fdce0c 100644 --- a/tests/script/general/rm_bak/tag/int_float.sim +++ b/tests/script/tsim/tag/int_float.sim @@ -1,11 +1,6 @@ system sh/stop_dnodes.sh - - system sh/deploy.sh -n dnode1 -i 1 -system sh/cfg.sh -n dnode1 -c walLevel -v 1 system sh/exec.sh -n dnode1 -s start - -sleep 2000 sql connect print ======================== dnode1 start @@ -320,7 +315,7 @@ endi print =============== clear sql drop database $db sql show databases -if $rows != 0 then +if $rows != 2 then return -1 endi diff --git a/tests/script/general/rm_bak/tag/set.sim b/tests/script/tsim/tag/set.sim similarity index 98% rename from tests/script/general/rm_bak/tag/set.sim rename to tests/script/tsim/tag/set.sim index cbc964fad7..2c14313a07 100644 --- a/tests/script/general/rm_bak/tag/set.sim +++ b/tests/script/tsim/tag/set.sim @@ -1,10 +1,6 @@ system sh/stop_dnodes.sh - system sh/deploy.sh -n dnode1 -i 1 -system sh/cfg.sh -n dnode1 -c walLevel -v 2 system sh/exec.sh -n dnode1 -s start - -sleep 2000 sql connect print ======================== dnode1 start @@ -452,7 +448,7 @@ endi print =============== clear sql drop database $db sql show databases -if $rows != 0 then +if $rows != 2 then return -1 endi diff --git a/tests/script/general/rm_bak/tag/smallint.sim b/tests/script/tsim/tag/smallint.sim similarity index 97% rename from tests/script/general/rm_bak/tag/smallint.sim rename to tests/script/tsim/tag/smallint.sim index e69eef05f2..cb65a93d5f 100644 --- a/tests/script/general/rm_bak/tag/smallint.sim +++ b/tests/script/tsim/tag/smallint.sim @@ -1,11 +1,6 @@ system sh/stop_dnodes.sh - - system sh/deploy.sh -n dnode1 -i 1 -system sh/cfg.sh -n dnode1 -c walLevel -v 1 system sh/exec.sh -n dnode1 -s start - -sleep 2000 sql connect print ======================== dnode1 start @@ -237,7 +232,7 @@ endi print =============== clear sql drop database $db sql show databases -if $rows != 0 then +if $rows != 2 then return -1 endi diff --git a/tests/script/general/rm_bak/tag/tinyint.sim b/tests/script/tsim/tag/tinyint.sim similarity index 97% rename from tests/script/general/rm_bak/tag/tinyint.sim rename to tests/script/tsim/tag/tinyint.sim index 2d70dc7d48..c6d9df2597 100644 --- a/tests/script/general/rm_bak/tag/tinyint.sim +++ b/tests/script/tsim/tag/tinyint.sim @@ -1,11 +1,6 @@ system sh/stop_dnodes.sh - - system sh/deploy.sh -n dnode1 -i 1 -system sh/cfg.sh -n dnode1 -c walLevel -v 1 system sh/exec.sh -n dnode1 -s start - -sleep 2000 sql connect print ======================== dnode1 start @@ -237,7 +232,7 @@ endi print =============== clear sql drop database $db sql show databases -if $rows != 0 then +if $rows != 2 then return -1 endi -- GitLab From 8b1e56389c916541572bbfc77f5e0b7c46cdc6b5 Mon Sep 17 00:00:00 2001 From: Ganlin Zhao Date: Wed, 13 Jul 2022 19:46:56 +0800 Subject: [PATCH 096/153] feat(query): add min function scalar version TD-17344 --- include/common/ttypes.h | 80 ++++++++++++++++++++++ include/libs/scalar/scalar.h | 1 + source/libs/function/src/builtins.c | 1 + source/libs/scalar/src/sclfunc.c | 102 ++++++++++++++++++++++++++++ 4 files changed, 184 insertions(+) diff --git a/include/common/ttypes.h b/include/common/ttypes.h index 16c59465cc..ec70dffd34 100644 --- a/include/common/ttypes.h +++ b/include/common/ttypes.h @@ -143,6 +143,86 @@ typedef struct { } \ } while (0) +#define SET_TYPED_DATA_MIN(_v, _type) \ + do { \ + switch (_type) { \ + case TSDB_DATA_TYPE_BOOL: \ + case TSDB_DATA_TYPE_TINYINT: \ + *(int8_t *)(_v) = INT8_MIN; \ + break; \ + case TSDB_DATA_TYPE_SMALLINT: \ + *(int16_t *)(_v) = INT16_MIN; \ + break; \ + case TSDB_DATA_TYPE_INT: \ + *(int32_t *)(_v) = INT32_MIN; \ + break; \ + case TSDB_DATA_TYPE_BIGINT: \ + case TSDB_DATA_TYPE_TIMESTAMP: \ + *(int64_t *)(_v) = INT64_MIN; \ + break; \ + case TSDB_DATA_TYPE_FLOAT: \ + *(float *)(_v) = FLT_MIN; \ + break; \ + case TSDB_DATA_TYPE_DOUBLE: \ + *(double *)(_v) = DBL_MIN; \ + break; \ + case TSDB_DATA_TYPE_UTINYINT: \ + *(uint8_t *)(_v) = 0; \ + break; \ + case TSDB_DATA_TYPE_USMALLINT: \ + *(uint16_t *)(_v) = 0; \ + break; \ + case TSDB_DATA_TYPE_UBIGINT: \ + *(uint64_t *)(_v) = 0; \ + break; \ + case TSDB_DATA_TYPE_UINT: \ + *(uint32_t *)(_v) = 0; \ + break; \ + default: \ + break; \ + } \ + } while (0) + +#define SET_TYPED_DATA_MAX(_v, _type) \ + do { \ + switch (_type) { \ + case TSDB_DATA_TYPE_BOOL: \ + case TSDB_DATA_TYPE_TINYINT: \ + *(int8_t *)(_v) = INT8_MAX; \ + break; \ + case TSDB_DATA_TYPE_SMALLINT: \ + *(int16_t *)(_v) = INT16_MAX; \ + break; \ + case TSDB_DATA_TYPE_INT: \ + *(int32_t *)(_v) = INT32_MAX; \ + break; \ + case TSDB_DATA_TYPE_BIGINT: \ + case TSDB_DATA_TYPE_TIMESTAMP: \ + *(int64_t *)(_v) = INT64_MAX; \ + break; \ + case TSDB_DATA_TYPE_FLOAT: \ + *(float *)(_v) = FLT_MAX; \ + break; \ + case TSDB_DATA_TYPE_DOUBLE: \ + *(double *)(_v) = DBL_MAX; \ + break; \ + case TSDB_DATA_TYPE_UTINYINT: \ + *(uint8_t *)(_v) = UINT8_MAX; \ + break; \ + case TSDB_DATA_TYPE_USMALLINT: \ + *(uint16_t *)(_v) = UINT16_MAX; \ + break; \ + case TSDB_DATA_TYPE_UINT: \ + *(uint32_t *)(_v) = UINT32_MAX; \ + break; \ + case TSDB_DATA_TYPE_UBIGINT: \ + *(uint64_t *)(_v) = UINT64_MAX; \ + break; \ + default: \ + break; \ + } \ + } while (0) + #define NUM_TO_STRING(_inputType, _input, _outputBytes, _output) \ do { \ switch (_inputType) { \ diff --git a/include/libs/scalar/scalar.h b/include/libs/scalar/scalar.h index b047557424..df3ce23949 100644 --- a/include/libs/scalar/scalar.h +++ b/include/libs/scalar/scalar.h @@ -98,6 +98,7 @@ int32_t qTbnameFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pO /* Aggregation functions */ int32_t countScalarFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput); int32_t sumScalarFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput); +int32_t minScalarFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput); #ifdef __cplusplus } diff --git a/source/libs/function/src/builtins.c b/source/libs/function/src/builtins.c index 8226eccf14..81fc9c8254 100644 --- a/source/libs/function/src/builtins.c +++ b/source/libs/function/src/builtins.c @@ -1918,6 +1918,7 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = { .getEnvFunc = getMinmaxFuncEnv, .initFunc = minmaxFunctionSetup, .processFunc = minFunction, + .sprocessFunc = minScalarFunction, .finalizeFunc = minmaxFunctionFinalize, .combineFunc = minCombine, .pPartialFunc = "min", diff --git a/source/libs/scalar/src/sclfunc.c b/source/libs/scalar/src/sclfunc.c index ce4631b8ee..10b8b035bc 100644 --- a/source/libs/scalar/src/sclfunc.c +++ b/source/libs/scalar/src/sclfunc.c @@ -1788,3 +1788,105 @@ int32_t sumScalarFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam * pOutput->numOfRows = pInput->numOfRows; return TSDB_CODE_SUCCESS; } + +int32_t minScalarFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput) { + SColumnInfoData *pInputData = pInput->columnData; + SColumnInfoData *pOutputData = pOutput->columnData; + + int32_t type = GET_PARAM_TYPE(pInput); + SET_TYPED_DATA_MAX(pOutputData->pData, type); + + for (int32_t i = 0; i < pInput->numOfRows; ++i) { + if (colDataIsNull_s(pInputData, i)) { + colDataAppendNULL(pOutputData, i); + break; + } + + switch(type) { + case TSDB_DATA_TYPE_BOOL: + case TSDB_DATA_TYPE_TINYINT: { + int8_t *in = (int8_t *)pInputData->pData; + int8_t *out = (int8_t *)pOutputData->pData; + if(in[i] < *out) { + *out = in[i]; + } + break; + } + case TSDB_DATA_TYPE_SMALLINT: { + int16_t *in = (int16_t *)pInputData->pData; + int16_t *out = (int16_t *)pOutputData->pData; + if(in[i] < *out) { + *out = in[i]; + } + break; + } + case TSDB_DATA_TYPE_INT: { + int32_t *in = (int32_t *)pInputData->pData; + int32_t *out = (int32_t *)pOutputData->pData; + if(in[i] < *out) { + *out = in[i]; + } + break; + } + case TSDB_DATA_TYPE_BIGINT: { + int64_t *in = (int64_t *)pInputData->pData; + int64_t *out = (int64_t *)pOutputData->pData; + if(in[i] < *out) { + *out = in[i]; + } + break; + } + case TSDB_DATA_TYPE_UTINYINT: { + uint8_t *in = (uint8_t *)pInputData->pData; + uint8_t *out = (uint8_t *)pOutputData->pData; + if(in[i] < *out) { + *out = in[i]; + } + break; + } + case TSDB_DATA_TYPE_USMALLINT: { + uint16_t *in = (uint16_t *)pInputData->pData; + uint16_t *out = (uint16_t *)pOutputData->pData; + if(in[i] < *out) { + *out = in[i]; + } + break; + } + case TSDB_DATA_TYPE_UINT: { + uint32_t *in = (uint32_t *)pInputData->pData; + uint32_t *out = (uint32_t *)pOutputData->pData; + if(in[i] < *out) { + *out = in[i]; + } + break; + } + case TSDB_DATA_TYPE_UBIGINT: { + uint64_t *in = (uint64_t *)pInputData->pData; + uint64_t *out = (uint64_t *)pOutputData->pData; + if(in[i] < *out) { + *out = in[i]; + } + break; + } + case TSDB_DATA_TYPE_FLOAT: { + float *in = (float *)pInputData->pData; + float *out = (float *)pOutputData->pData; + if(in[i] < *out) { + *out = in[i]; + } + break; + } + case TSDB_DATA_TYPE_DOUBLE: { + double *in = (double *)pInputData->pData; + double *out = (double *)pOutputData->pData; + if(in[i] < *out) { + *out = in[i]; + } + break; + } + } + } + + pOutput->numOfRows = pInput->numOfRows; + return TSDB_CODE_SUCCESS; +} -- GitLab From e9accd26dffcfef19af87d9545b8f701781ee4c1 Mon Sep 17 00:00:00 2001 From: wangmm0220 Date: Thu, 14 Jul 2022 10:40:46 +0800 Subject: [PATCH 097/153] fix:double free error for parserTest --- include/common/tmsg.h | 1 + source/libs/parser/src/parInsert.c | 1 + 2 files changed, 2 insertions(+) diff --git a/include/common/tmsg.h b/include/common/tmsg.h index 5e7e045b78..c8e13fce3d 100644 --- a/include/common/tmsg.h +++ b/include/common/tmsg.h @@ -1989,6 +1989,7 @@ static FORCE_INLINE void tdDestroySVCreateTbReq(SVCreateTbReq* req) { taosMemoryFreeClear(req->ctb.pTag); taosMemoryFreeClear(req->ctb.name); taosArrayDestroy(req->ctb.tagName); + req->ctb.tagName = NULL; } else if (req->type == TSDB_NORMAL_TABLE) { taosMemoryFreeClear(req->ntb.schemaRow.pSchema); } diff --git a/source/libs/parser/src/parInsert.c b/source/libs/parser/src/parInsert.c index 935cadc484..005a7f919a 100644 --- a/source/libs/parser/src/parInsert.c +++ b/source/libs/parser/src/parInsert.c @@ -1514,6 +1514,7 @@ int32_t parseInsertSql(SParseContext* pContext, SQuery** pQuery, SParseMetaCache .pSql = (char*)pContext->pSql, .msg = {.buf = pContext->pMsg, .len = pContext->msgLen}, .pTableMeta = NULL, + .createTblReq = {0}, .pSubTableHashObj = taosHashInit(128, taosGetDefaultHashFunction(TSDB_DATA_TYPE_VARCHAR), true, HASH_NO_LOCK), .pTableNameHashObj = taosHashInit(128, taosGetDefaultHashFunction(TSDB_DATA_TYPE_VARCHAR), true, HASH_NO_LOCK), .pDbFNameHashObj = taosHashInit(64, taosGetDefaultHashFunction(TSDB_DATA_TYPE_VARCHAR), true, HASH_NO_LOCK), -- GitLab From 59062a9bae55fca614ba6eb8feaae956f5985bb0 Mon Sep 17 00:00:00 2001 From: Shengliang Guan Date: Thu, 14 Jul 2022 10:41:22 +0800 Subject: [PATCH 098/153] fix: memory leak while dnode exiting --- source/dnode/mgmt/mgmt_mnode/src/mmWorker.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/source/dnode/mgmt/mgmt_mnode/src/mmWorker.c b/source/dnode/mgmt/mgmt_mnode/src/mmWorker.c index a171d2e1e4..d2b071ec61 100644 --- a/source/dnode/mgmt/mgmt_mnode/src/mmWorker.c +++ b/source/dnode/mgmt/mgmt_mnode/src/mmWorker.c @@ -168,7 +168,12 @@ int32_t mmPutMsgToQueue(SMnodeMgmt *pMgmt, EQueueType qtype, SRpcMsg *pRpc) { memcpy(pMsg, pRpc, sizeof(SRpcMsg)); dTrace("msg:%p, is created and will put into %s queue, type:%s", pMsg, pWorker->name, TMSG_INFO(pRpc->msgType)); - return mmPutMsgToWorker(pMgmt, pWorker, pMsg); + int32_t code = mmPutMsgToWorker(pMgmt, pWorker, pMsg); + if (code != 0) { + dTrace("msg:%p, is freed", pMsg); + taosFreeQitem(pMsg); + } + return code; } int32_t mmStartWorker(SMnodeMgmt *pMgmt) { -- GitLab From c7e64933d0832a346d4475fb7652301563373475 Mon Sep 17 00:00:00 2001 From: Minglei Jin Date: Thu, 14 Jul 2022 10:43:54 +0800 Subject: [PATCH 099/153] fix: use calcTypeBytes for table altering --- source/libs/parser/src/parTranslater.c | 3 ++- tests/script/tsim/alter/table.sim | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/source/libs/parser/src/parTranslater.c b/source/libs/parser/src/parTranslater.c index d12f1cfe7c..837d0f5773 100644 --- a/source/libs/parser/src/parTranslater.c +++ b/source/libs/parser/src/parTranslater.c @@ -5939,7 +5939,8 @@ static int32_t buildAddColReq(STranslateContext* pCxt, SAlterTableStmt* pStmt, S pReq->type = pStmt->dataType.type; pReq->flags = COL_SMA_ON; - pReq->bytes = pStmt->dataType.bytes; + // pReq->bytes = pStmt->dataType.bytes; + pReq->bytes = calcTypeBytes(pStmt->dataType); return TSDB_CODE_SUCCESS; } diff --git a/tests/script/tsim/alter/table.sim b/tests/script/tsim/alter/table.sim index cc995d171f..348bef21fe 100644 --- a/tests/script/tsim/alter/table.sim +++ b/tests/script/tsim/alter/table.sim @@ -660,8 +660,8 @@ endi print ======= over sql drop database d1 sql show databases -if $rows != 0 then +if $rows != 2 then return -1 endi -system sh/exec.sh -n dnode1 -s stop -x SIGINT \ No newline at end of file +system sh/exec.sh -n dnode1 -s stop -x SIGINT -- GitLab From fb49fd40cddccccf4a3a3933a173ffcf9302d028 Mon Sep 17 00:00:00 2001 From: Haojun Liao Date: Thu, 14 Jul 2022 10:44:35 +0800 Subject: [PATCH 100/153] fix(query):fix invalid write in sample query processing. --- source/libs/function/src/builtinsimpl.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/source/libs/function/src/builtinsimpl.c b/source/libs/function/src/builtinsimpl.c index e622c0c1af..97cb1f0ee1 100644 --- a/source/libs/function/src/builtinsimpl.c +++ b/source/libs/function/src/builtinsimpl.c @@ -3461,9 +3461,16 @@ void doAddIntoResult(SqlFunctionCtx* pCtx, void* pData, int32_t rowIndex, SSData } } +/* + * +------------------------------------+--------------+--------------+ + * | null bitmap | | | + * |(n columns, one bit for each column)| src column #1| src column #2| + * +------------------------------------+--------------+--------------+ + */ void saveTupleData(SqlFunctionCtx* pCtx, int32_t rowIndex, const SSDataBlock* pSrcBlock, STuplePos* pPos) { SFilePage* pPage = NULL; + // todo refactor: move away int32_t completeRowSize = pCtx->subsidiaries.num * sizeof(bool); for (int32_t j = 0; j < pCtx->subsidiaries.num; ++j) { SqlFunctionCtx* pc = pCtx->subsidiaries.pCtx[j]; @@ -3476,12 +3483,15 @@ void saveTupleData(SqlFunctionCtx* pCtx, int32_t rowIndex, const SSDataBlock* pS } else { pPage = getBufPage(pCtx->pBuf, pCtx->curBufPage); if (pPage->num + completeRowSize > getBufPageSize(pCtx->pBuf)) { + // current page is all used, let's prepare a new buffer page + releaseBufPage(pCtx->pBuf, pPage); pPage = getNewBufPage(pCtx->pBuf, 0, &pCtx->curBufPage); pPage->num = sizeof(SFilePage); } } pPos->pageId = pCtx->curBufPage; + pPos->offset = pPage->num; // keep the current row data, extract method int32_t offset = 0; @@ -3509,7 +3519,6 @@ void saveTupleData(SqlFunctionCtx* pCtx, int32_t rowIndex, const SSDataBlock* pS offset += pCol->info.bytes; } - pPos->offset = pPage->num; pPage->num += completeRowSize; setBufPageDirty(pPage, true); @@ -4839,7 +4848,7 @@ static void doReservoirSample(SqlFunctionCtx* pCtx, SSampleInfo* pInfo, char* da if (pInfo->numSampled < pInfo->samples) { sampleAssignResult(pInfo, data, pInfo->numSampled); if (pCtx->subsidiaries.num > 0) { - saveTupleData(pCtx, index, pCtx->pSrcBlock, pInfo->tuplePos + pInfo->numSampled * sizeof(STuplePos)); + saveTupleData(pCtx, index, pCtx->pSrcBlock, &pInfo->tuplePos[pInfo->numSampled]); } pInfo->numSampled++; } else { @@ -4847,7 +4856,7 @@ static void doReservoirSample(SqlFunctionCtx* pCtx, SSampleInfo* pInfo, char* da if (j < pInfo->samples) { sampleAssignResult(pInfo, data, j); if (pCtx->subsidiaries.num > 0) { - copyTupleData(pCtx, index, pCtx->pSrcBlock, pInfo->tuplePos + j * sizeof(STuplePos)); + copyTupleData(pCtx, index, pCtx->pSrcBlock, &pInfo->tuplePos[j]); } } } @@ -4885,7 +4894,7 @@ int32_t sampleFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock) { int32_t currentRow = pBlock->info.rows; for (int32_t i = 0; i < pInfo->numSampled; ++i) { colDataAppend(pCol, currentRow + i, pInfo->data + i * pInfo->colBytes, false); - setSelectivityValue(pCtx, pBlock, pInfo->tuplePos + i * sizeof(STuplePos), currentRow + i); + setSelectivityValue(pCtx, pBlock, &pInfo->tuplePos[i], currentRow + i); } return pInfo->numSampled; -- GitLab From e8c041f09856e5845be679718c9a52868d1ce0f7 Mon Sep 17 00:00:00 2001 From: wangmm0220 Date: Thu, 14 Jul 2022 10:49:09 +0800 Subject: [PATCH 101/153] fix:filter child table with tag --- source/libs/executor/src/executil.c | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/source/libs/executor/src/executil.c b/source/libs/executor/src/executil.c index 2469062d09..6b2bea273d 100644 --- a/source/libs/executor/src/executil.c +++ b/source/libs/executor/src/executil.c @@ -347,25 +347,25 @@ int32_t getTableList(void* metaHandle, void* pVnode, SScanPhysiNode* pScanNode, terrno = code; return code; } - - if (pTagCond) { - int32_t i = 0; - while (i < taosArrayGetSize(pListInfo->pTableList)) { - STableKeyInfo* info = taosArrayGet(pListInfo->pTableList, i); - bool isOk = isTableOk(info, pTagCond, metaHandle); - if (terrno) return terrno; - if (!isOk) { - taosArrayRemove(pListInfo->pTableList, i); - continue; - } - i++; - } - } } else { // Create one table group. STableKeyInfo info = {.lastKey = 0, .uid = tableUid, .groupId = 0}; taosArrayPush(pListInfo->pTableList, &info); } + if (pTagCond) { + int32_t i = 0; + while (i < taosArrayGetSize(pListInfo->pTableList)) { + STableKeyInfo* info = taosArrayGet(pListInfo->pTableList, i); + bool isOk = isTableOk(info, pTagCond, metaHandle); + if (terrno) return terrno; + if (!isOk) { + taosArrayRemove(pListInfo->pTableList, i); + continue; + } + i++; + } + } + pListInfo->pGroupList = taosArrayInit(4, POINTER_BYTES); if (pListInfo->pGroupList == NULL) { return TSDB_CODE_OUT_OF_MEMORY; -- GitLab From 724d2e0f5fdf6c43fc23a2ae9b2d111d4a3fe1fd Mon Sep 17 00:00:00 2001 From: Shengliang Guan Date: Thu, 14 Jul 2022 10:51:09 +0800 Subject: [PATCH 102/153] test: valgrind case --- tests/script/sh/deploy.sh | 4 ++-- tests/script/tsim/valgrind/checkError2.sim | 24 +++++++++++++++++++--- tests/script/tsim/valgrind/checkError3.sim | 16 +++++++-------- 3 files changed, 31 insertions(+), 13 deletions(-) diff --git a/tests/script/sh/deploy.sh b/tests/script/sh/deploy.sh index de7b8ecfbf..5f497a248f 100755 --- a/tests/script/sh/deploy.sh +++ b/tests/script/sh/deploy.sh @@ -127,8 +127,8 @@ echo "dataDir $DATA_DIR" >> $TAOS_CFG echo "logDir $LOG_DIR" >> $TAOS_CFG echo "debugFlag 0" >> $TAOS_CFG echo "tmrDebugFlag 131" >> $TAOS_CFG -echo "uDebugFlag 131" >> $TAOS_CFG -echo "rpcDebugFlag 131" >> $TAOS_CFG +echo "uDebugFlag 143" >> $TAOS_CFG +echo "rpcDebugFlag 143" >> $TAOS_CFG echo "jniDebugFlag 143" >> $TAOS_CFG echo "qDebugFlag 143" >> $TAOS_CFG echo "cDebugFlag 143" >> $TAOS_CFG diff --git a/tests/script/tsim/valgrind/checkError2.sim b/tests/script/tsim/valgrind/checkError2.sim index 3939b7c854..3a82218015 100644 --- a/tests/script/tsim/valgrind/checkError2.sim +++ b/tests/script/tsim/valgrind/checkError2.sim @@ -37,22 +37,40 @@ endi print =============== step4: create show table sql create table ct1 using stb tags(1000) +sql create table ct2 using stb tags(2000) +sql create table ct3 using stb tags(3000) sql show tables -if $rows != 1 then +if $rows != 3 then return -1 endi print =============== step5: insert data sql insert into ct1 values(now+0s, 10, 2.0, 3.0) sql insert into ct1 values(now+1s, 11, 2.1, 3.1)(now+2s, -12, -2.2, -3.2)(now+3s, -13, -2.3, -3.3) +sql insert into ct2 values(now+0s, 10, 2.0, 3.0) +sql insert into ct2 values(now+1s, 11, 2.1, 3.1)(now+2s, -12, -2.2, -3.2)(now+3s, -13, -2.3, -3.3) +sql insert into ct3 values('2021-01-01 00:00:00.000', 10, 2.0, 3.0) -print =============== step6: select data +print =============== step6: query data sql select * from ct1 sql select * from stb +sql select c1, c2, c3 from ct1 +sql select ts, c1, c2, c3 from stb + +print =============== step7: count +sql select count(*) from ct1; +sql select count(*) from stb; +sql select count(ts), count(c1), count(c2), count(c3) from ct1 +sql select count(ts), count(c1), count(c2), count(c3) from stb + +print =============== step8: func +sql select first(ts), first(c1), first(c2), first(c3) from ct1 +sql select min(c1), min(c2), min(c3) from ct1 +sql select max(c1), max(c2), max(c3) from ct1 +sql select sum(c1), sum(c2), sum(c3) from ct1 _OVER: system sh/exec.sh -n dnode1 -s stop -x SIGINT - print =============== check $null= diff --git a/tests/script/tsim/valgrind/checkError3.sim b/tests/script/tsim/valgrind/checkError3.sim index d5a407f6f8..10a8f01fb3 100644 --- a/tests/script/tsim/valgrind/checkError3.sim +++ b/tests/script/tsim/valgrind/checkError3.sim @@ -68,16 +68,16 @@ sql select ts, c1, t1 from stb sql select ts, c1, t1 from stb_2 print =============== stepb: count -#sql select count(*) from c1; -#sql select count(*) from stb; -#sql select count(ts), count(c1), count(c2), count(c3) from c1 -#sql select count(ts), count(c1), count(c2), count(c3) from stb +sql select count(*) from c1; +sql select count(*) from stb; +sql select count(ts), count(c1), count(c2), count(c3) from c1 +sql select count(ts), count(c1), count(c2), count(c3) from stb print =============== stepc: func -#sql select first(ts), first(c1), first(c2), first(c3) from c1 -#sql select min(c1), min(c2), min(c3) from c1 -#sql select max(c1), max(c2), max(c3) from c1 -#sql select sum(c1), sum(c2), sum(c3) from c1 +sql select first(ts), first(c1), first(c2), first(c3) from c1 +sql select min(c2), min(c3), min(c4) from c1 +sql select max(c2), max(c3), max(c4) from c1 +sql select sum(c2), sum(c3), sum(c4) from c1 _OVER: system sh/exec.sh -n dnode1 -s stop -x SIGINT -- GitLab From 3f31c464f0c12ef83acb75a79c4c7c398ff1b810 Mon Sep 17 00:00:00 2001 From: Ganlin Zhao Date: Wed, 13 Jul 2022 19:46:56 +0800 Subject: [PATCH 103/153] feat(query): add max function scalar version TD-17344 --- include/libs/scalar/scalar.h | 1 + source/libs/function/src/builtins.c | 1 + source/libs/scalar/src/sclfunc.c | 37 +++++++++++++++++++---------- 3 files changed, 27 insertions(+), 12 deletions(-) diff --git a/include/libs/scalar/scalar.h b/include/libs/scalar/scalar.h index df3ce23949..ab0a4f8529 100644 --- a/include/libs/scalar/scalar.h +++ b/include/libs/scalar/scalar.h @@ -99,6 +99,7 @@ int32_t qTbnameFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pO int32_t countScalarFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput); int32_t sumScalarFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput); int32_t minScalarFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput); +int32_t maxScalarFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput); #ifdef __cplusplus } diff --git a/source/libs/function/src/builtins.c b/source/libs/function/src/builtins.c index 81fc9c8254..e7795dcddc 100644 --- a/source/libs/function/src/builtins.c +++ b/source/libs/function/src/builtins.c @@ -1933,6 +1933,7 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = { .getEnvFunc = getMinmaxFuncEnv, .initFunc = minmaxFunctionSetup, .processFunc = maxFunction, + .sprocessFunc = maxScalarFunction, .finalizeFunc = minmaxFunctionFinalize, .combineFunc = maxCombine, .pPartialFunc = "max", diff --git a/source/libs/scalar/src/sclfunc.c b/source/libs/scalar/src/sclfunc.c index 10b8b035bc..cfdde85556 100644 --- a/source/libs/scalar/src/sclfunc.c +++ b/source/libs/scalar/src/sclfunc.c @@ -1789,12 +1789,17 @@ int32_t sumScalarFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam * return TSDB_CODE_SUCCESS; } -int32_t minScalarFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput) { +static int32_t doMinMaxScalarFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput, bool isMinFunc) { SColumnInfoData *pInputData = pInput->columnData; SColumnInfoData *pOutputData = pOutput->columnData; int32_t type = GET_PARAM_TYPE(pInput); - SET_TYPED_DATA_MAX(pOutputData->pData, type); + + if (isMinFunc) { + SET_TYPED_DATA_MAX(pOutputData->pData, type); + } else { + SET_TYPED_DATA_MIN(pOutputData->pData, type); + } for (int32_t i = 0; i < pInput->numOfRows; ++i) { if (colDataIsNull_s(pInputData, i)) { @@ -1807,7 +1812,7 @@ int32_t minScalarFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam * case TSDB_DATA_TYPE_TINYINT: { int8_t *in = (int8_t *)pInputData->pData; int8_t *out = (int8_t *)pOutputData->pData; - if(in[i] < *out) { + if((in[i] > *out) ^ isMinFunc) { *out = in[i]; } break; @@ -1815,7 +1820,7 @@ int32_t minScalarFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam * case TSDB_DATA_TYPE_SMALLINT: { int16_t *in = (int16_t *)pInputData->pData; int16_t *out = (int16_t *)pOutputData->pData; - if(in[i] < *out) { + if((in[i] > *out) ^ isMinFunc) { *out = in[i]; } break; @@ -1823,7 +1828,7 @@ int32_t minScalarFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam * case TSDB_DATA_TYPE_INT: { int32_t *in = (int32_t *)pInputData->pData; int32_t *out = (int32_t *)pOutputData->pData; - if(in[i] < *out) { + if((in[i] > *out) ^ isMinFunc) { *out = in[i]; } break; @@ -1831,7 +1836,7 @@ int32_t minScalarFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam * case TSDB_DATA_TYPE_BIGINT: { int64_t *in = (int64_t *)pInputData->pData; int64_t *out = (int64_t *)pOutputData->pData; - if(in[i] < *out) { + if((in[i] > *out) ^ isMinFunc) { *out = in[i]; } break; @@ -1839,7 +1844,7 @@ int32_t minScalarFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam * case TSDB_DATA_TYPE_UTINYINT: { uint8_t *in = (uint8_t *)pInputData->pData; uint8_t *out = (uint8_t *)pOutputData->pData; - if(in[i] < *out) { + if((in[i] > *out) ^ isMinFunc) { *out = in[i]; } break; @@ -1847,7 +1852,7 @@ int32_t minScalarFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam * case TSDB_DATA_TYPE_USMALLINT: { uint16_t *in = (uint16_t *)pInputData->pData; uint16_t *out = (uint16_t *)pOutputData->pData; - if(in[i] < *out) { + if((in[i] > *out) ^ isMinFunc) { *out = in[i]; } break; @@ -1855,7 +1860,7 @@ int32_t minScalarFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam * case TSDB_DATA_TYPE_UINT: { uint32_t *in = (uint32_t *)pInputData->pData; uint32_t *out = (uint32_t *)pOutputData->pData; - if(in[i] < *out) { + if((in[i] > *out) ^ isMinFunc) { *out = in[i]; } break; @@ -1863,7 +1868,7 @@ int32_t minScalarFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam * case TSDB_DATA_TYPE_UBIGINT: { uint64_t *in = (uint64_t *)pInputData->pData; uint64_t *out = (uint64_t *)pOutputData->pData; - if(in[i] < *out) { + if((in[i] > *out) ^ isMinFunc) { *out = in[i]; } break; @@ -1871,7 +1876,7 @@ int32_t minScalarFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam * case TSDB_DATA_TYPE_FLOAT: { float *in = (float *)pInputData->pData; float *out = (float *)pOutputData->pData; - if(in[i] < *out) { + if((in[i] > *out) ^ isMinFunc) { *out = in[i]; } break; @@ -1879,7 +1884,7 @@ int32_t minScalarFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam * case TSDB_DATA_TYPE_DOUBLE: { double *in = (double *)pInputData->pData; double *out = (double *)pOutputData->pData; - if(in[i] < *out) { + if((in[i] > *out) ^ isMinFunc) { *out = in[i]; } break; @@ -1890,3 +1895,11 @@ int32_t minScalarFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam * pOutput->numOfRows = pInput->numOfRows; return TSDB_CODE_SUCCESS; } + +int32_t minScalarFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput) { + return doMinMaxScalarFunction(pInput, inputNum, pOutput, true); +} + +int32_t maxScalarFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput) { + return doMinMaxScalarFunction(pInput, inputNum, pOutput, false); +} -- GitLab From 638353ef67e9d582abc572af2e428db7a896650e Mon Sep 17 00:00:00 2001 From: Shuduo Sang Date: Thu, 14 Jul 2022 11:00:02 +0800 Subject: [PATCH 104/153] feat: update taostools for3.0 (#14885) * feat: update taos-tools for 3.0 [TD-14141] * feat: update taos-tools for 3.0 --- tools/taos-tools | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/taos-tools b/tools/taos-tools index 3f42d428eb..bd496f76b6 160000 --- a/tools/taos-tools +++ b/tools/taos-tools @@ -1 +1 @@ -Subproject commit 3f42d428eb6b90dea2651f4ccea66e44705c831b +Subproject commit bd496f76b64931c66da2f8b0f24143a98a881cde -- GitLab From 6fd4684a26c1f13a51e90db6b144bb368a0a598a Mon Sep 17 00:00:00 2001 From: Haojun Liao Date: Thu, 14 Jul 2022 11:16:15 +0800 Subject: [PATCH 105/153] fix(query): ensure buffer before load data. --- source/common/src/tdatablock.c | 5 ++++- source/libs/executor/src/tfill.c | 20 ++++++++++++-------- 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/source/common/src/tdatablock.c b/source/common/src/tdatablock.c index f51023189d..9f5a247d76 100644 --- a/source/common/src/tdatablock.c +++ b/source/common/src/tdatablock.c @@ -542,8 +542,10 @@ int32_t blockDataToBuf(char* buf, const SSDataBlock* pBlock) { } int32_t blockDataFromBuf(SSDataBlock* pBlock, const char* buf) { - pBlock->info.rows = *(int32_t*)buf; + int32_t numOfRows = *(int32_t*) buf; + blockDataEnsureCapacity(pBlock, numOfRows); + pBlock->info.rows = numOfRows; size_t numOfCols = taosArrayGetSize(pBlock->pDataBlock); const char* pStart = buf + sizeof(uint32_t); @@ -589,6 +591,7 @@ int32_t blockDataFromBuf(SSDataBlock* pBlock, const char* buf) { return TSDB_CODE_SUCCESS; } +// todo remove this int32_t blockDataFromBuf1(SSDataBlock* pBlock, const char* buf, size_t capacity) { pBlock->info.rows = *(int32_t*)buf; pBlock->info.groupId = *(uint64_t*)(buf + sizeof(int32_t)); diff --git a/source/libs/executor/src/tfill.c b/source/libs/executor/src/tfill.c index c008c7c4a9..959c03a3b1 100644 --- a/source/libs/executor/src/tfill.c +++ b/source/libs/executor/src/tfill.c @@ -53,8 +53,8 @@ static void setNullRow(SSDataBlock* pBlock, int64_t ts, int32_t rowIndex) { // the first are always the timestamp column, so start from the second column. for (int32_t i = 0; i < taosArrayGetSize(pBlock->pDataBlock); ++i) { SColumnInfoData* p = taosArrayGet(pBlock->pDataBlock, i); - if (p->info.type == TSDB_DATA_TYPE_TIMESTAMP) { - colDataAppend(p, rowIndex, (const char*)&ts, false); + if (p->info.type == TSDB_DATA_TYPE_TIMESTAMP) { // handle timestamp + colDataAppend(p, rowIndex, (const char*)&ts, false); } else { colDataAppendNULL(p, rowIndex); } @@ -83,15 +83,20 @@ static void doFillOneRow(SFillInfo* pFillInfo, SSDataBlock* pBlock, SSDataBlock* if (pFillInfo->type == TSDB_FILL_PREV) { SArray* p = FILL_IS_ASC_FILL(pFillInfo) ? pFillInfo->prev : pFillInfo->next; - for (int32_t i = 1; i < pFillInfo->numOfCols; ++i) { + for (int32_t i = 0; i < pFillInfo->numOfCols; ++i) { SFillColInfo* pCol = &pFillInfo->pFillCol[i]; if (TSDB_COL_IS_TAG(pCol->flag)) { continue; } - SGroupKeys* pKey = taosArrayGet(p, i); SColumnInfoData* pDstColInfoData = taosArrayGet(pBlock->pDataBlock, GET_DEST_SLOT_ID(pCol)); - doSetVal(pDstColInfoData, index, pKey); + + if (pDstColInfoData->info.type == TSDB_DATA_TYPE_TIMESTAMP) { + colDataAppend(pDstColInfoData, index, (const char*)&ts, false); + } else { + SGroupKeys* pKey = taosArrayGet(p, i); + doSetVal(pDstColInfoData, index, pKey); + } } } else if (pFillInfo->type == TSDB_FILL_NEXT) { SArray* p = FILL_IS_ASC_FILL(pFillInfo) ? pFillInfo->next : pFillInfo->prev; @@ -264,9 +269,8 @@ static int32_t fillResultImpl(SFillInfo* pFillInfo, SSDataBlock* pBlock, int32_t assert(pFillInfo->currentKey == ts); if (pFillInfo->type == TSDB_FILL_NEXT && (pFillInfo->index + 1) < pFillInfo->numOfRows) { - ++pFillInfo->index; - copyCurrentRowIntoBuf(pFillInfo, pFillInfo->index, pFillInfo->next); - --pFillInfo->index; + int32_t nextRowIndex = pFillInfo->index + 1; + copyCurrentRowIntoBuf(pFillInfo, nextRowIndex, pFillInfo->next); } // assign rows to dst buffer -- GitLab From f02d8c2596f8386deecbc59ec9f5b4cb0c11c47a Mon Sep 17 00:00:00 2001 From: Xuefeng Tan <1172915550@qq.com> Date: Thu, 14 Jul 2022 11:19:31 +0800 Subject: [PATCH 106/153] enh(taosAdapter): update taosAdapter (#14858) --- tools/taosadapter | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/taosadapter b/tools/taosadapter index c885e967e4..df8678f070 160000 --- a/tools/taosadapter +++ b/tools/taosadapter @@ -1 +1 @@ -Subproject commit c885e967e490105999b84d009a15168728dfafaf +Subproject commit df8678f070e3f707faf59baebec90065f6e1268b -- GitLab From 13519f8fd925a6fd3615ffcd49bc88fce605184c Mon Sep 17 00:00:00 2001 From: 54liuyao <54liuyao@163.com> Date: Thu, 14 Jul 2022 10:15:20 +0800 Subject: [PATCH 107/153] feat(stream): interval offset --- source/libs/executor/src/executil.c | 3 +++ source/libs/stream/src/streamUpdate.c | 2 +- tests/script/jenkins/basic.txt | 1 + tests/script/tsim/stream/sliding.sim | 8 ++++---- 4 files changed, 9 insertions(+), 5 deletions(-) diff --git a/source/libs/executor/src/executil.c b/source/libs/executor/src/executil.c index 2469062d09..4b8eed57d7 100644 --- a/source/libs/executor/src/executil.c +++ b/source/libs/executor/src/executil.c @@ -853,6 +853,9 @@ static STimeWindow doCalculateTimeWindow(int64_t ts, SInterval* pInterval) { w.ekey = taosTimeAdd(w.skey, pInterval->interval, pInterval->intervalUnit, pInterval->precision) - 1; } else { int64_t st = w.skey; + if (pInterval->offset > 0) { + st = taosTimeAdd(st, pInterval->offset, pInterval->offsetUnit, pInterval->precision); + } if (st > ts) { st -= ((st - ts + pInterval->sliding - 1) / pInterval->sliding) * pInterval->sliding; diff --git a/source/libs/stream/src/streamUpdate.c b/source/libs/stream/src/streamUpdate.c index 3d64cec8d8..d0fb9c22e1 100644 --- a/source/libs/stream/src/streamUpdate.c +++ b/source/libs/stream/src/streamUpdate.c @@ -17,7 +17,7 @@ #include "ttime.h" #define DEFAULT_FALSE_POSITIVE 0.01 -#define DEFAULT_BUCKET_SIZE 1024 +#define DEFAULT_BUCKET_SIZE 131072 #define ROWS_PER_MILLISECOND 1 #define MAX_NUM_SCALABLE_BF 100000 #define MIN_NUM_SCALABLE_BF 10 diff --git a/tests/script/jenkins/basic.txt b/tests/script/jenkins/basic.txt index dad4dbbe29..3fa0df5a7d 100644 --- a/tests/script/jenkins/basic.txt +++ b/tests/script/jenkins/basic.txt @@ -114,6 +114,7 @@ # ./test.sh -f tsim/stream/schedSnode.sim ./test.sh -f tsim/stream/windowClose.sim ./test.sh -f tsim/stream/ignoreExpiredData.sim +./test.sh -f tsim/stream/sliding.sim # ---- transaction ./test.sh -f tsim/trans/lossdata1.sim diff --git a/tests/script/tsim/stream/sliding.sim b/tests/script/tsim/stream/sliding.sim index 750be7cb49..44f96cbefa 100644 --- a/tests/script/tsim/stream/sliding.sim +++ b/tests/script/tsim/stream/sliding.sim @@ -17,10 +17,10 @@ sql use test sql create stable st(ts timestamp, a int, b int, c int, d double) tags(ta int,tb int,tc int); sql create table t1 using st tags(1,1,1); sql create table t2 using st tags(2,2,2); -sql create stream streams1 trigger at_once into streamt as select _wstartts, count(*) c1, sum(a) c3 , max(b) c4, min(c) c5 from t1 interval(10s) sliding (5s); -sql create stream streams2 trigger at_once watermark 1d into streamt2 as select _wstartts, count(*) c1, sum(a) c3 , max(b) c4, min(c) c5 from t1 interval(10s) sliding (5s); -sql create stream stream_t1 trigger at_once into streamtST as select _wstartts, count(*) c1, sum(a) c3 , max(b) c4, min(c) c5 from st interval(10s) sliding (5s); -sql create stream stream_t2 trigger at_once watermark 1d into streamtST2 as select _wstartts, count(*) c1, sum(a) c3 , max(b) c4, min(c) c5 from st interval(10s) sliding (5s); +sql create stream streams1 trigger at_once into streamt as select _wstart, count(*) c1, sum(a) c3 , max(b) c4, min(c) c5 from t1 interval(10s) sliding (5s); +sql create stream streams2 trigger at_once watermark 1d into streamt2 as select _wstart, count(*) c1, sum(a) c3 , max(b) c4, min(c) c5 from t1 interval(10s) sliding (5s); +sql create stream stream_t1 trigger at_once into streamtST as select _wstart, count(*) c1, sum(a) c3 , max(b) c4, min(c) c5 from st interval(10s) sliding (5s); +sql create stream stream_t2 trigger at_once watermark 1d into streamtST2 as select _wstart, count(*) c1, sum(a) c3 , max(b) c4, min(c) c5 from st interval(10s) sliding (5s); sql insert into t1 values(1648791210000,1,2,3,1.0); sql insert into t1 values(1648791216000,2,2,3,1.1); -- GitLab From 3c755c483464c825a0afb19e6d135cbb15739ada Mon Sep 17 00:00:00 2001 From: wangmm0220 Date: Thu, 14 Jul 2022 11:41:34 +0800 Subject: [PATCH 108/153] opt:remove useless code --- source/libs/executor/src/executil.c | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) diff --git a/source/libs/executor/src/executil.c b/source/libs/executor/src/executil.c index 6b2bea273d..744dac85b9 100644 --- a/source/libs/executor/src/executil.c +++ b/source/libs/executor/src/executil.c @@ -307,7 +307,6 @@ int32_t getTableList(void* metaHandle, void* pVnode, SScanPhysiNode* pScanNode, SNode* pTagIndexCond = (SNode*)pListInfo->pTagIndexCond; if (pScanNode->tableType == TSDB_SUPER_TABLE) { if (pTagIndexCond) { - ///<<<<<<< HEAD SIndexMetaArg metaArg = { .metaEx = metaHandle, .idx = tsdbGetIdx(metaHandle), .ivtIdx = tsdbGetIvtIdx(metaHandle), .suid = tableUid}; @@ -315,20 +314,9 @@ int32_t getTableList(void* metaHandle, void* pVnode, SScanPhysiNode* pScanNode, SIdxFltStatus status = SFLT_NOT_INDEX; code = doFilterTag(pTagIndexCond, &metaArg, res, &status); if (code != 0 || status == SFLT_NOT_INDEX) { - code = TSDB_CODE_INDEX_REBUILDING; - } - //======= - // SArray* res = taosArrayInit(8, sizeof(uint64_t)); - // // code = doFilterTag(pTagIndexCond, &metaArg, res); - // code = TSDB_CODE_INDEX_REBUILDING; - //>>>>>>> dvv - if (code == TSDB_CODE_INDEX_REBUILDING) { + qError("failed to get tableIds from index, reason:%s, suid:%" PRIu64, tstrerror(code), tableUid); +// code = TSDB_CODE_INDEX_REBUILDING; code = vnodeGetAllTableList(pVnode, tableUid, pListInfo->pTableList); - } else if (code != TSDB_CODE_SUCCESS) { - qError("failed to get tableIds, reason:%s, suid:%" PRIu64, tstrerror(code), tableUid); - taosArrayDestroy(res); - terrno = code; - return code; } else { qDebug("success to get tableIds, size:%d, suid:%" PRIu64, (int)taosArrayGetSize(res), tableUid); } -- GitLab From b1cdc7ff3cb3099aaeefb5fb659889d5b5cc08a7 Mon Sep 17 00:00:00 2001 From: Shengliang Guan Date: Thu, 14 Jul 2022 11:42:55 +0800 Subject: [PATCH 109/153] test: valgrind case --- tests/script/tsim/insert/basic0.sim | 163 +++++++++++--------------- tests/script/tsim/insert/basic1.sim | 41 ++----- tests/script/tsim/valgrind/basic1.sim | 70 ++++++----- 3 files changed, 116 insertions(+), 158 deletions(-) diff --git a/tests/script/tsim/insert/basic0.sim b/tests/script/tsim/insert/basic0.sim index 722bc0f907..6de904eca1 100644 --- a/tests/script/tsim/insert/basic0.sim +++ b/tests/script/tsim/insert/basic0.sim @@ -32,7 +32,6 @@ if $rows != 3 then return -1 endi - print =============== insert data, mode1: one row one table in sql print =============== insert data, mode1: mulit rows one table in sql #print =============== insert data, mode1: one rows mulit table in sql @@ -41,9 +40,6 @@ sql insert into ct1 values(now+0s, 10, 2.0, 3.0) sql insert into ct1 values(now+1s, 11, 2.1, 3.1)(now+2s, -12, -2.2, -3.2)(now+3s, -13, -2.3, -3.3) sql insert into ct2 values(now+0s, 10, 2.0, 3.0) sql insert into ct2 values(now+1s, 11, 2.1, 3.1)(now+2s, -12, -2.2, -3.2)(now+3s, -13, -2.3, -3.3) -#sql insert into ct1 values(now+4s, -14, -2.4, -3.4) ct2 values(now+4s, -14, -2.4, -3.4) -#sql insert into ct1 values(now+5s, -15, -2.5, -3.5)(now+6s, -16, -2.6, -3.6) ct2 values(now+5s, -15, -2.5, -3.5)(now+6s, -16, -2.6, -3.6) - sql insert into ct3 values('2021-01-01 00:00:00.000', 10, 2.0, 3.0) #=================================================================== @@ -67,16 +63,6 @@ endi if $data03 != 3.000000000 then return -1 endi -#if $data41 != -14 then -# return -1 -#endi -#if $data42 != -2.40000 then -# return -1 -#endi -#if $data43 != -3.400000000 then -# return -1 -#endi - print =============== select count(*) from child table sql select count(*) from ct1 @@ -107,10 +93,10 @@ if $data03 != 4 then endi #print =============== select first(*)/first(column) from child table -#sql select first(*) from ct1 -#print ====> select first(*) from ct1 -#print rows: $rows -#print $data00 $data01 $data02 $data03 +sql select first(*) from ct1 +print ====> select first(*) from ct1 +print rows: $rows +print $data00 $data01 $data02 $data03 sql select first(ts), first(c1), first(c2), first(c3) from ct1 print ====> select first(ts), first(c1), first(c2), first(c3) from ct1 @@ -217,23 +203,23 @@ if $data32 != -3.300000000 then return -1 endi #=================================================================== -#=================================================================== #print =============== query data from stb -#sql select * from stb -#if $rows != 4 then -# return -1 -#endi +sql select * from stb +print $rows +if $rows != 9 then + return -1 +endi #print =============== select count(*) from supter table -#sql select count(*) from stb -#print $data00 $data01 $data02 -#if $rows != 1 then -# return -1 -#endi -#if $data00 != 9 then -# return -1 -#endi +sql select count(*) from stb +print $data00 $data01 $data02 +if $rows != 1 then + return -1 +endi +if $data00 != 9 then + return -1 +endi print =============== select count(column) from supter table sql select ts, c1, c2, c3 from stb @@ -264,28 +250,23 @@ if $data03 != 3.000000000 then endi #print =============== select count(column) from supter table -#sql select count(ts), count(c1), count(c2), count(c3) from stb -#print rows: $rows -#print $data00 $data01 $data02 $data03 -#print $data10 $data11 $data12 $data13 -#print $data20 $data21 $data22 $data23 -#print $data30 $data31 $data32 $data33 -#if $data00 != 9 then -# return -1 -#endi -#if $data01 != 8 then -# return -1 -#endi -#if $data02 != 8 then -# return -1 -#endi -#if $data03 != 8 then -# return -1 -#endi +sql select count(ts), count(c1), count(c2), count(c3) from stb +print rows: $rows +print $data00 $data01 $data02 $data03 +if $data00 != 9 then + return -1 +endi +if $data01 != 9 then + return -1 +endi +if $data02 != 9 then + return -1 +endi +if $data03 != 9 then + return -1 +endi #=================================================================== -#=================================================================== - print =============== stop and restart taosd, then again do query above system sh/exec.sh -n dnode1 -s stop -x SIGINT system sh/exec.sh -n dnode1 -s start @@ -326,16 +307,6 @@ endi if $data03 != 3.000000000 then return -1 endi -#if $data41 != -14 then -# return -1 -#endi -#if $data42 != -2.40000 then -# return -1 -#endi -#if $data43 != -3.400000000 then -# return -1 -#endi - print =============== select count(*) from child table sql select count(*) from ct1 @@ -366,10 +337,10 @@ if $data03 != 4 then endi #print =============== select first(*)/first(column) from child table -#sql select first(*) from ct1 -#print ====> select first(*) from ct1 -#print rows: $rows -#print $data00 $data01 $data02 $data03 +sql select first(*) from ct1 +print ====> select first(*) from ct1 +print rows: $rows +print $data00 $data01 $data02 $data03 sql select first(ts), first(c1), first(c2), first(c3) from ct1 print ====> select first(ts), first(c1), first(c2), first(c3) from ct1 @@ -474,24 +445,23 @@ endi if $data32 != -3.300000000 then return -1 endi -#=================================================================== -#=================================================================== -#print =============== query data from stb -#sql select * from stb -#if $rows != 4 then -# return -1 -#endi +#=================================================================== +print =============== query data from stb +sql select * from stb +if $rows != 9 then + return -1 +endi -#print =============== select count(*) from supter table -#sql select count(*) from stb -#print $data00 $data01 $data02 -#if $rows != 1 then -# return -1 -#endi -#if $data00 != 9 then -# return -1 -#endi +print =============== select count(*) from supter table +sql select count(*) from stb +print $data00 $data01 $data02 +if $rows != 1 then + return -1 +endi +if $data00 != 9 then + return -1 +endi print =============== select count(column) from supter table sql select ts, c1, c2, c3 from stb @@ -521,20 +491,19 @@ if $data03 != 3.000000000 then endi #print =============== select count(column) from supter table -#sql select count(ts), count(c1), count(c2), count(c3) from stb -#print $data00 $data01 $data02 $data03 -#if $data00 != 8 then -# return -1 -#endi -#if $data01 != 8 then -# return -1 -#endi -#if $data02 != 8 then -# return -1 -#endi -#if $data03 != 8 then -# return -1 -#endi - +sql select count(ts), count(c1), count(c2), count(c3) from stb +print $data00 $data01 $data02 $data03 +if $data00 != 9 then + return -1 +endi +if $data01 != 9 then + return -1 +endi +if $data02 != 9 then + return -1 +endi +if $data03 != 9 then + return -1 +endi -system sh/exec.sh -n dnode1 -s stop -x SIGINT +system sh/exec.sh -n dnode1 -s stop -x SIGINT \ No newline at end of file diff --git a/tests/script/tsim/insert/basic1.sim b/tests/script/tsim/insert/basic1.sim index d98407b380..6d31dcdffb 100644 --- a/tests/script/tsim/insert/basic1.sim +++ b/tests/script/tsim/insert/basic1.sim @@ -1,9 +1,7 @@ system sh/stop_dnodes.sh system sh/deploy.sh -n dnode1 -i 1 system sh/exec.sh -n dnode1 -s start -sleep 50 sql connect - print =============== create database sql create database d1 sql show databases @@ -17,7 +15,6 @@ sql use d1 print =============== create super table, include all type sql create table if not exists stb (ts timestamp, c1 bool, c2 tinyint, c3 smallint, c4 int, c5 bigint, c6 float, c7 double, c8 binary(16), c9 nchar(16), c10 timestamp, c11 tinyint unsigned, c12 smallint unsigned, c13 int unsigned, c14 bigint unsigned) tags (t1 bool, t2 tinyint, t3 smallint, t4 int, t5 bigint, t6 float, t7 double, t8 binary(16), t9 nchar(16), t10 timestamp, t11 tinyint unsigned, t12 smallint unsigned, t13 int unsigned, t14 bigint unsigned) - sql create stable if not exists stb_1 (ts timestamp, i int) tags (j int) sql create table stb_2 (ts timestamp, i int) tags (j int) sql create stable stb_3 (ts timestamp, i int) tags (j int) @@ -36,11 +33,6 @@ if $rows != 2 then return -1 endi - -print =============== insert data, mode1: one row one table in sql -print =============== insert data, mode1: mulit rows one table in sql -print =============== insert data, mode1: one rows mulit table in sql -print =============== insert data, mode1: mulit rows mulit table in sql sql insert into c1 values(now-1s, true, -1, -2, -3, -4, -6.0, -7.0, 'child tbl 1', 'child tbl 1', '2022-02-25 18:00:00.000', 10, 20, 30, 40) sql insert into c1 values(now+0s, true, -1, -2, -3, -4, -6.0, -7.0, 'child tbl 1', 'child tbl 1', '2022-02-25 18:00:00.000', 10, 20, 30, 40) (now+1s, true, -1, -2, -3, -4, -6.0, -7.0, 'child tbl 1', 'child tbl 1', '2022-02-25 18:00:00.000', 10, 20, 30, 40) (now+2s, true, -1, -2, -3, -4, -6.0, -7.0, 'child tbl 1', 'child tbl 1', '2022-02-25 18:00:00.000', 10, 20, 30, 40) @@ -69,32 +61,15 @@ if $data03 != -2 then endi print =============== query data from st, but not support select * from super table, waiting fix -#sql select * from st -#if $rows != 4 then -# return -1 -#endi +sql select * from stb +if $rows != 4 then + return -1 +endi print =============== stop and restart taosd system sh/exec.sh -n dnode1 -s stop -x SIGINT system sh/exec.sh -n dnode1 -s start -$loop_cnt = 0 -check_dnode_ready: - $loop_cnt = $loop_cnt + 1 - sleep 200 - if $loop_cnt == 10 then - print ====> dnode not ready! - return -1 - endi -sql show dnodes -print ===> $rows $data00 $data01 $data02 $data03 $data04 $data05 -if $data00 != 1 then - return -1 -endi -if $data04 != ready then - goto check_dnode_ready -endi - print =============== query data sql select * from c1 print rows: $rows @@ -119,9 +94,9 @@ if $data03 != -2 then endi print =============== query data from st, but not support select * from super table, waiting fix -#sql select * from st -#if $rows != 4 then -# return -1 -#endi +sql select * from stb +if $rows != 4 then + return -1 +endi system sh/exec.sh -n dnode1 -s stop -x SIGINT diff --git a/tests/script/tsim/valgrind/basic1.sim b/tests/script/tsim/valgrind/basic1.sim index f0430195c9..784b83d96b 100644 --- a/tests/script/tsim/valgrind/basic1.sim +++ b/tests/script/tsim/valgrind/basic1.sim @@ -1,7 +1,7 @@ system sh/stop_dnodes.sh system sh/deploy.sh -n dnode1 -i 1 system sh/cfg.sh -n dnode1 -c debugflag -v 131 -system sh/exec.sh -n dnode1 -s start -v +system sh/exec.sh -n dnode1 -s start sql connect print =============== step1: create drop show dnodes @@ -23,51 +23,65 @@ if $data(1)[4] != ready then endi print =============== step2: create db -sql create database d1 vgroups 1 buffer 3 +sql create database d1 vgroups 3 buffer 3 sql show databases sql use d1 sql show vgroups -print =============== step3: create show stable -sql create table if not exists stb (ts timestamp, c1 int, c2 float, c3 double) tags (t1 int unsigned) +print =============== step3: create show stable, include all type +sql create table if not exists stb (ts timestamp, c1 bool, c2 tinyint, c3 smallint, c4 int, c5 bigint, c6 float, c7 double, c8 binary(16), c9 nchar(16), c10 timestamp, c11 tinyint unsigned, c12 smallint unsigned, c13 int unsigned, c14 bigint unsigned) tags (t1 bool, t2 tinyint, t3 smallint, t4 int, t5 bigint, t6 float, t7 double, t8 binary(16), t9 nchar(16), t10 timestamp, t11 tinyint unsigned, t12 smallint unsigned, t13 int unsigned, t14 bigint unsigned) +sql create stable if not exists stb_1 (ts timestamp, c1 int) tags (j int) +sql create table stb_2 (ts timestamp, c1 int) tags (t1 int) +sql create stable stb_3 (ts timestamp, c1 int) tags (t1 int) sql show stables -if $rows != 1 then +if $rows != 4 then return -1 endi -print =============== step4: create show table -sql create table ct1 using stb tags(1000) -sql create table ct2 using stb tags(2000) -sql create table ct3 using stb tags(3000) +print =============== step4: ccreate child table +sql create table c1 using stb tags(true, -1, -2, -3, -4, -6.0, -7.0, 'child tbl 1', 'child tbl 1', '2022-02-25 18:00:00.000', 10, 20, 30, 40) +sql create table c2 using stb tags(false, -1, -2, -3, -4, -6.0, -7.0, 'child tbl 2', 'child tbl 2', '2022-02-25 18:00:00.000', 10, 20, 30, 40) sql show tables -if $rows != 3 then +if $rows != 2 then return -1 endi print =============== step5: insert data -sql insert into ct1 values(now+0s, 10, 2.0, 3.0) -sql insert into ct1 values(now+1s, 11, 2.1, 3.1)(now+2s, -12, -2.2, -3.2)(now+3s, -13, -2.3, -3.3) -sql insert into ct2 values(now+0s, 10, 2.0, 3.0) -sql insert into ct2 values(now+1s, 11, 2.1, 3.1)(now+2s, -12, -2.2, -3.2)(now+3s, -13, -2.3, -3.3) -sql insert into ct3 values('2021-01-01 00:00:00.000', 10, 2.0, 3.0) +sql insert into c1 values(now-1s, true, -1, -2, -3, -4, -6.0, -7.0, 'child tbl 1', 'child tbl 1', '2022-02-25 18:00:00.000', 10, 20, 30, 40) +sql insert into c1 values(now+0s, true, -1, -2, -3, -4, -6.0, -7.0, 'child tbl 1', 'child tbl 1', '2022-02-25 18:00:00.000', 10, 20, 30, 40) (now+1s, true, -1, -2, -3, -4, -6.0, -7.0, 'child tbl 1', 'child tbl 1', '2022-02-25 18:00:00.000', 10, 20, 30, 40) (now+2s, true, -1, -2, -3, -4, -6.0, -7.0, 'child tbl 1', 'child tbl 1', '2022-02-25 18:00:00.000', 10, 20, 30, 40) +sql insert into c2 values(now-1s, true, -1, -2, -3, -4, -6.0, -7.0, 'child tbl 1', 'child tbl 1', '2022-02-25 18:00:00.000', 10, 20, 30, 40) +sql insert into c2 values(now+0s, true, -1, -2, -3, -4, -6.0, -7.0, 'child tbl 1', 'child tbl 1', '2022-02-25 18:00:00.000', 10, 20, 30, 40) (now+1s, true, -1, -2, -3, -4, -6.0, -7.0, 'child tbl 1', 'child tbl 1', '2022-02-25 18:00:00.000', 10, 20, 30, 40) (now+2s, true, -1, -2, -3, -4, -6.0, -7.0, 'child tbl 1', 'child tbl 1', '2022-02-25 18:00:00.000', 10, 20, 30, 40) + +print =============== step6: alter insert +sql insert into c3 using stb tags(true, -1, -2, -3, -4, -6.0, -7.0, 'child tbl 1', 'child tbl 1', '2022-02-25 18:00:00.000', 10, 20, 30, 40) values(now-1s, true, -1, -2, -3, -4, -6.0, -7.0, 'child tbl 1', 'child tbl 1', '2022-02-25 18:00:00.000', 10, 20, 30, 40) +sql insert into c3 using stb tags(true, -1, -2, -3, -4, -6.0, -7.0, 'child tbl 1', 'child tbl 1', '2022-02-25 18:00:00.000', 10, 20, 30, 40) values(now+0s, true, -1, -2, -3, -4, -6.0, -7.0, 'child tbl 1', 'child tbl 1', '2022-02-25 18:00:00.000', 10, 20, 30, 40) + +print =============== restart +system sh/exec.sh -n dnode1 -s stop -x SIGINT +system sh/exec.sh -n dnode1 -s start -v -print =============== step6: query data -sql select * from ct1 -sql select * from stb -sql select c1, c2, c3 from ct1 -sql select ts, c1, c2, c3 from stb +print =============== stepa: query data +sql select * from c1 +#sql select * from stb +#sql select * from stb_1 +#sql select ts, c1, c2, c3 from c1 +#sql select ts, c1, c2, c3 from stb +#sql select ts, c1 from stb_2 +#sql select ts, c1, t1 from c1 +#sql select ts, c1, t1 from stb +#sql select ts, c1, t1 from stb_2 -print =============== step7: count -sql select count(*) from ct1; +print =============== stepb: count +#sql select count(*) from c1; #sql select count(*) from stb; -#sql select count(ts), count(c1), count(c2), count(c3) from ct1 +#sql select count(ts), count(c1), count(c2), count(c3) from c1 #sql select count(ts), count(c1), count(c2), count(c3) from stb -print =============== step8: func -#sql select first(ts), first(c1), first(c2), first(c3) from ct1 -#sql select min(c1), min(c2), min(c3) from ct1 -#sql select max(c1), max(c2), max(c3) from ct1 -#sql select sum(c1), sum(c2), sum(c3) from ct1 +print =============== stepc: func +#sql select first(ts), first(c1), first(c2), first(c3) from c1 +#sql select min(c2), min(c3), min(c4) from c1 +#sql select max(c2), max(c3), max(c4) from c1 +#sql select sum(c2), sum(c3), sum(c4) from c1 _OVER: system sh/exec.sh -n dnode1 -s stop -x SIGINT -- GitLab From 1657df208d6e34ac1524f22d27d1599457355d25 Mon Sep 17 00:00:00 2001 From: Shengliang Guan Date: Thu, 14 Jul 2022 13:40:52 +0800 Subject: [PATCH 110/153] test: restore some 2.0 case --- tests/script/jenkins/basic.txt | 18 +++++++++--------- tests/script/tsim/tag/4.sim | 16 ++++++++-------- tests/script/tsim/tag/5.sim | 20 ++++++++++---------- tests/script/tsim/tag/6.sim | 24 ++++++++++++------------ tests/script/tsim/tag/bigint.sim | 5 ++--- tests/script/tsim/tag/binary.sim | 5 ++--- tests/script/tsim/tag/binary_binary.sim | 4 ++-- tests/script/tsim/tag/bool.sim | 7 +++---- tests/script/tsim/tag/bool_binary.sim | 4 ++-- tests/script/tsim/tag/bool_int.sim | 4 ++-- tests/script/tsim/tag/double.sim | 4 ++-- tests/script/tsim/tag/float.sim | 4 ++-- tests/script/tsim/tag/int.sim | 5 ++--- tests/script/tsim/tag/int_binary.sim | 4 ++-- tests/script/tsim/tag/int_float.sim | 4 ++-- tests/script/tsim/tag/smallint.sim | 5 ++--- tests/script/tsim/tag/tinyint.sim | 5 ++--- 17 files changed, 66 insertions(+), 72 deletions(-) diff --git a/tests/script/jenkins/basic.txt b/tests/script/jenkins/basic.txt index af0e338c9b..78dec01a74 100644 --- a/tests/script/jenkins/basic.txt +++ b/tests/script/jenkins/basic.txt @@ -283,21 +283,21 @@ ./test.sh -f tsim/tag/3.sim ./test.sh -f tsim/tag/4.sim ./test.sh -f tsim/tag/5.sim -./test.sh -f tsim/tag/6.sim -./test.sh -f tsim/tag/add.sim +#./test.sh -f tsim/tag/6.sim +#./test.sh -f tsim/tag/add.sim ./test.sh -f tsim/tag/bigint.sim ./test.sh -f tsim/tag/binary_binary.sim ./test.sh -f tsim/tag/binary.sim ./test.sh -f tsim/tag/bool_binary.sim ./test.sh -f tsim/tag/bool_int.sim ./test.sh -f tsim/tag/bool.sim -./test.sh -f tsim/tag/change.sim -./test.sh -f tsim/tag/column.sim -./test.sh -f tsim/tag/commit.sim -./test.sh -f tsim/tag/create.sim -./test.sh -f tsim/tag/delete.sim -./test.sh -f tsim/tag/double.sim -./test.sh -f tsim/tag/filter.sim +#./test.sh -f tsim/tag/change.sim +#./test.sh -f tsim/tag/column.sim +#./test.sh -f tsim/tag/commit.sim +#./test.sh -f tsim/tag/create.sim +#./test.sh -f tsim/tag/delete.sim +#./test.sh -f tsim/tag/double.sim +#./test.sh -f tsim/tag/filter.sim ./test.sh -f tsim/tag/float.sim ./test.sh -f tsim/tag/int_binary.sim ./test.sh -f tsim/tag/int_float.sim diff --git a/tests/script/tsim/tag/4.sim b/tests/script/tsim/tag/4.sim index 0bb1cde75d..fcdb146fb9 100644 --- a/tests/script/tsim/tag/4.sim +++ b/tests/script/tsim/tag/4.sim @@ -675,27 +675,27 @@ if $data00 != 25 then endi print =============== step24 -sql select count(tbcol), avg(tbcol), sum(tbcol), min(tbcol), max(tbcol), first(tbcol), last(tbcol) from $mt where tgcol1 = 1 and tgcol2 = 1 and tgcol3 = 1 interval(1d) group by tgcol1 +sql select count(tbcol), avg(tbcol), sum(tbcol), min(tbcol), max(tbcol), first(tbcol), last(tbcol) from $mt where tgcol1 = 1 and tgcol2 = 1 and tgcol3 = 1 partition by tgcol1 interval(1d) print $data00 $data01 $data02 $data03 $data04 $data05 $data06 -if $data01 != 100 then +if $data00 != 100 then return -1 endi -sql select count(tbcol), avg(tbcol), sum(tbcol), min(tbcol), max(tbcol), first(tbcol), last(tbcol) from $mt where tgcol1 = 1 and tgcol2 = 1 and tgcol3 = 1 interval(1d) group by tgcol2 +sql select count(tbcol), avg(tbcol), sum(tbcol), min(tbcol), max(tbcol), first(tbcol), last(tbcol) from $mt where tgcol1 = 1 and tgcol2 = 1 and tgcol3 = 1 partition by tgcol2 interval(1d) print $data00 $data01 $data02 $data03 $data04 $data05 $data06 -if $data01 != 100 then +if $data00 != 100 then return -1 endi -sql select count(tbcol), avg(tbcol), sum(tbcol), min(tbcol), max(tbcol), first(tbcol), last(tbcol) from $mt where tgcol1 = 1 and tgcol2 = 1 and tgcol3 = 1 interval(1d) group by tgcol3 +sql select count(tbcol), avg(tbcol), sum(tbcol), min(tbcol), max(tbcol), first(tbcol), last(tbcol) from $mt where tgcol1 = 1 and tgcol2 = 1 and tgcol3 = 1 partition by tgcol3 interval(1d) print $data00 $data01 $data02 $data03 $data04 $data05 $data06 -if $data01 != 100 then +if $data00 != 100 then return -1 endi -sql select count(tbcol), avg(tbcol), sum(tbcol), min(tbcol), max(tbcol), first(tbcol), last(tbcol) from $mt where tgcol1 = 1 and tgcol2 = 1 and tgcol3 = 1 and tgcol4 = 1 interval(1d) group by tgcol4 +sql select count(tbcol), avg(tbcol), sum(tbcol), min(tbcol), max(tbcol), first(tbcol), last(tbcol) from $mt where tgcol1 = 1 and tgcol2 = 1 and tgcol3 = 1 and tgcol4 = 1 partition by tgcol4 interval(1d) print $data00 $data01 $data02 $data03 $data04 $data05 $data06 -if $data01 != 100 then +if $data00 != 100 then return -1 endi diff --git a/tests/script/tsim/tag/5.sim b/tests/script/tsim/tag/5.sim index e3edbcaa5d..92695ddfcf 100644 --- a/tests/script/tsim/tag/5.sim +++ b/tests/script/tsim/tag/5.sim @@ -792,33 +792,33 @@ endi print =============== step27 -sql select count(tbcol), avg(tbcol), sum(tbcol), min(tbcol), max(tbcol), first(tbcol), last(tbcol) from $mt where tgcol1 = 1 and tgcol2 = 1 and tgcol3 = 1 interval(1d) group by tgcol1 +sql select count(tbcol), avg(tbcol), sum(tbcol), min(tbcol), max(tbcol), first(tbcol), last(tbcol) from $mt where tgcol1 = 1 and tgcol2 = 1 and tgcol3 = 1 partition by tgcol1 interval(1d) print $data00 $data01 $data02 $data03 $data04 $data05 $data06 -if $data01 != 100 then +if $data00 != 100 then return -1 endi -sql select count(tbcol), avg(tbcol), sum(tbcol), min(tbcol), max(tbcol), first(tbcol), last(tbcol) from $mt where tgcol1 = 1 and tgcol2 = 1 and tgcol3 = 1 interval(1d) group by tgcol2 +sql select count(tbcol), avg(tbcol), sum(tbcol), min(tbcol), max(tbcol), first(tbcol), last(tbcol) from $mt where tgcol1 = 1 and tgcol2 = 1 and tgcol3 = 1 partition by tgcol2 interval(1d) print $data00 $data01 $data02 $data03 $data04 $data05 $data06 -if $data01 != 100 then +if $data00 != 100 then return -1 endi -sql select count(tbcol), avg(tbcol), sum(tbcol), min(tbcol), max(tbcol), first(tbcol), last(tbcol) from $mt where tgcol1 = 1 and tgcol2 = 1 and tgcol3 = 1 interval(1d) group by tgcol3 +sql select count(tbcol), avg(tbcol), sum(tbcol), min(tbcol), max(tbcol), first(tbcol), last(tbcol) from $mt where tgcol1 = 1 and tgcol2 = 1 and tgcol3 = 1 partition by tgcol3 interval(1d) print $data00 $data01 $data02 $data03 $data04 $data05 $data06 -if $data01 != 100 then +if $data00 != 100 then return -1 endi -sql select count(tbcol), avg(tbcol), sum(tbcol), min(tbcol), max(tbcol), first(tbcol), last(tbcol) from $mt where tgcol1 = 1 and tgcol2 = 1 and tgcol3 = 1 and tgcol4 = 1 interval(1d) group by tgcol4 +sql select count(tbcol), avg(tbcol), sum(tbcol), min(tbcol), max(tbcol), first(tbcol), last(tbcol) from $mt where tgcol1 = 1 and tgcol2 = 1 and tgcol3 = 1 and tgcol4 = 1 partition by tgcol4 interval(1d) print $data00 $data01 $data02 $data03 $data04 $data05 $data06 -if $data01 != 100 then +if $data00 != 100 then return -1 endi -sql select count(tbcol), avg(tbcol), sum(tbcol), min(tbcol), max(tbcol), first(tbcol), last(tbcol) from $mt where tgcol1 = 1 and tgcol2 = 1 and tgcol3 = 1 and tgcol4 = 1 and tgcol5 = 1 interval(1d) group by tgcol5 +sql select count(tbcol), avg(tbcol), sum(tbcol), min(tbcol), max(tbcol), first(tbcol), last(tbcol) from $mt where tgcol1 = 1 and tgcol2 = 1 and tgcol3 = 1 and tgcol4 = 1 and tgcol5 = 1 partition by tgcol5 interval(1d) print $data00 $data01 $data02 $data03 $data04 $data05 $data06 -if $data01 != 100 then +if $data00 != 100 then return -1 endi diff --git a/tests/script/tsim/tag/6.sim b/tests/script/tsim/tag/6.sim index d4e1d52c3c..4f7f5b88d1 100644 --- a/tests/script/tsim/tag/6.sim +++ b/tests/script/tsim/tag/6.sim @@ -941,39 +941,39 @@ if $data00 != 25 then endi print =============== step31 -sql select count(tbcol), avg(tbcol), sum(tbcol), min(tbcol), max(tbcol), first(tbcol), last(tbcol) from $mt where tgcol1 = 1 and tgcol2 = 1 and tgcol3 = 1 interval(1d) group by tgcol1 +sql select count(tbcol), avg(tbcol), sum(tbcol), min(tbcol), max(tbcol), first(tbcol), last(tbcol) from $mt where tgcol1 = 1 and tgcol2 = 1 and tgcol3 = 1 partition by tgcol1 interval(1d) print $data00 $data01 $data02 $data03 $data04 $data05 $data06 -if $data01 != 100 then +if $data00 != 100 then return -1 endi -sql select count(tbcol), avg(tbcol), sum(tbcol), min(tbcol), max(tbcol), first(tbcol), last(tbcol) from $mt where tgcol1 = 1 and tgcol2 = 1 and tgcol3 = 1 interval(1d) group by tgcol2 +sql select count(tbcol), avg(tbcol), sum(tbcol), min(tbcol), max(tbcol), first(tbcol), last(tbcol) from $mt where tgcol1 = 1 and tgcol2 = 1 and tgcol3 = 1 partition by tgcol2 interval(1d) print $data00 $data01 $data02 $data03 $data04 $data05 $data06 -if $data01 != 100 then +if $data00 != 100 then return -1 endi -sql select count(tbcol), avg(tbcol), sum(tbcol), min(tbcol), max(tbcol), first(tbcol), last(tbcol) from $mt where tgcol1 = 1 and tgcol2 = 1 and tgcol3 = 1 interval(1d) group by tgcol3 +sql select count(tbcol), avg(tbcol), sum(tbcol), min(tbcol), max(tbcol), first(tbcol), last(tbcol) from $mt where tgcol1 = 1 and tgcol2 = 1 and tgcol3 = 1 partition by tgcol3 interval(1d) print $data00 $data01 $data02 $data03 $data04 $data05 $data06 -if $data01 != 100 then +if $data00 != 100 then return -1 endi -sql select count(tbcol), avg(tbcol), sum(tbcol), min(tbcol), max(tbcol), first(tbcol), last(tbcol) from $mt where tgcol1 = 1 and tgcol2 = 1 and tgcol3 = 1 and tgcol4 = 1 interval(1d) group by tgcol4 +sql select count(tbcol), avg(tbcol), sum(tbcol), min(tbcol), max(tbcol), first(tbcol), last(tbcol) from $mt where tgcol1 = 1 and tgcol2 = 1 and tgcol3 = 1 and tgcol4 = 1 partition by tgcol4 interval(1d) print $data00 $data01 $data02 $data03 $data04 $data05 $data06 -if $data01 != 100 then +if $data00 != 100 then return -1 endi -sql select count(tbcol), avg(tbcol), sum(tbcol), min(tbcol), max(tbcol), first(tbcol), last(tbcol) from $mt where tgcol1 = 1 and tgcol2 = 1 and tgcol3 = 1 and tgcol4 = 1 and tgcol5 = 1 interval(1d) group by tgcol5 +sql select count(tbcol), avg(tbcol), sum(tbcol), min(tbcol), max(tbcol), first(tbcol), last(tbcol) from $mt where tgcol1 = 1 and tgcol2 = 1 and tgcol3 = 1 and tgcol4 = 1 and tgcol5 = 1 partition by tgcol5 interval(1d) print $data00 $data01 $data02 $data03 $data04 $data05 $data06 -if $data01 != 100 then +if $data00 != 100 then return -1 endi -sql select count(tbcol), avg(tbcol), sum(tbcol), min(tbcol), max(tbcol), first(tbcol), last(tbcol) from $mt where tgcol1 = 1 and tgcol2 = 1 and tgcol3 = 1 and tgcol4 = 1 and tgcol5 = 1 and tgcol6 = 1 interval(1d) group by tgcol6 +sql select count(tbcol), avg(tbcol), sum(tbcol), min(tbcol), max(tbcol), first(tbcol), last(tbcol) from $mt where tgcol1 = 1 and tgcol2 = 1 and tgcol3 = 1 and tgcol4 = 1 and tgcol5 = 1 and tgcol6 = 1 partition by tgcol6 interval(1d) print $data00 $data01 $data02 $data03 $data04 $data05 $data06 -if $data01 != 100 then +if $data00 != 100 then return -1 endi diff --git a/tests/script/tsim/tag/bigint.sim b/tests/script/tsim/tag/bigint.sim index 2e1af227c0..813387eb38 100644 --- a/tests/script/tsim/tag/bigint.sim +++ b/tests/script/tsim/tag/bigint.sim @@ -221,11 +221,10 @@ if $data00 != 25 then return -1 endi - print =============== step12 -sql select count(tbcol), avg(tbcol), sum(tbcol), min(tbcol), max(tbcol), first(tbcol), last(tbcol) from $mt interval(1d) group by tgcol +sql select count(tbcol), avg(tbcol), sum(tbcol), min(tbcol), max(tbcol), first(tbcol), last(tbcol) from $mt partition by tgcol interval(1d) print $data00 $data01 $data02 $data03 $data04 $data05 $data06 -if $data01 != 100 then +if $data00 != 100 then return -1 endi diff --git a/tests/script/tsim/tag/binary.sim b/tests/script/tsim/tag/binary.sim index 2cabf30bb1..6ede988954 100644 --- a/tests/script/tsim/tag/binary.sim +++ b/tests/script/tsim/tag/binary.sim @@ -221,11 +221,10 @@ if $data00 != 25 then return -1 endi - print =============== step12 -sql select count(tbcol), avg(tbcol), sum(tbcol), min(tbcol), max(tbcol), first(tbcol), last(tbcol) from $mt interval(1d) group by tgcol +sql select count(tbcol), avg(tbcol), sum(tbcol), min(tbcol), max(tbcol), first(tbcol), last(tbcol) from $mt partition by tgcol interval(1d) print $data00 $data01 $data02 $data03 $data04 $data05 $data06 -if $data01 != 100 then +if $data00 != 100 then return -1 endi diff --git a/tests/script/tsim/tag/binary_binary.sim b/tests/script/tsim/tag/binary_binary.sim index 8a77de5226..071b457b44 100644 --- a/tests/script/tsim/tag/binary_binary.sim +++ b/tests/script/tsim/tag/binary_binary.sim @@ -290,9 +290,9 @@ if $data00 != 25 then endi print =============== step14 -sql select count(tbcol), avg(tbcol), sum(tbcol), min(tbcol), max(tbcol), first(tbcol), last(tbcol) from $mt interval(1d) group by tgcol +sql select count(tbcol), avg(tbcol), sum(tbcol), min(tbcol), max(tbcol), first(tbcol), last(tbcol) from $mt partition by tgcol interval(1d) print $data00 $data01 $data02 $data03 $data04 $data05 $data06 -if $data01 != 100 then +if $data00 != 100 then return -1 endi diff --git a/tests/script/tsim/tag/bool.sim b/tests/script/tsim/tag/bool.sim index 26e320c41e..356269e1e1 100644 --- a/tests/script/tsim/tag/bool.sim +++ b/tests/script/tsim/tag/bool.sim @@ -218,12 +218,11 @@ if $data00 != 25 then return -1 endi - print =============== step12 -sql select count(tbcol), avg(tbcol), sum(tbcol), min(tbcol), max(tbcol), first(tbcol), last(tbcol) from $mt interval(1d) group by tgcol -print select count(tbcol), avg(tbcol), sum(tbcol), min(tbcol), max(tbcol), first(tbcol), last(tbcol) from $mt interval(1d) group by tgcol +sql select count(tbcol), avg(tbcol), sum(tbcol), min(tbcol), max(tbcol), first(tbcol), last(tbcol) from $mt partition by tgcol interval(1d) +print select count(tbcol), avg(tbcol), sum(tbcol), min(tbcol), max(tbcol), first(tbcol), last(tbcol) from $mt partition by tgcol interval(1d) print $data00 $data01 $data02 $data03 $data04 $data05 $data06 -if $data01 != 100 then +if $data00 != 100 then return -1 endi diff --git a/tests/script/tsim/tag/bool_binary.sim b/tests/script/tsim/tag/bool_binary.sim index d776127757..3fcb085e37 100644 --- a/tests/script/tsim/tag/bool_binary.sim +++ b/tests/script/tsim/tag/bool_binary.sim @@ -290,9 +290,9 @@ if $data00 != 25 then endi print =============== step14 -sql select count(tbcol), avg(tbcol), sum(tbcol), min(tbcol), max(tbcol), first(tbcol), last(tbcol) from $mt interval(1d) group by tgcol +sql select count(tbcol), avg(tbcol), sum(tbcol), min(tbcol), max(tbcol), first(tbcol), last(tbcol) from $mt partition by tgcol interval(1d) print $data00 $data01 $data02 $data03 $data04 $data05 $data06 -if $data01 != 100 then +if $data00 != 100 then return -1 endi diff --git a/tests/script/tsim/tag/bool_int.sim b/tests/script/tsim/tag/bool_int.sim index daeb0c711f..2ff640b329 100644 --- a/tests/script/tsim/tag/bool_int.sim +++ b/tests/script/tsim/tag/bool_int.sim @@ -306,9 +306,9 @@ if $data00 != 25 then endi print =============== step14 -sql select count(tbcol), avg(tbcol), sum(tbcol), min(tbcol), max(tbcol), first(tbcol), last(tbcol) from $mt interval(1d) group by tgcol +sql select count(tbcol), avg(tbcol), sum(tbcol), min(tbcol), max(tbcol), first(tbcol), last(tbcol) from $mt partition by tgcol interval(1d) print $data00 $data01 $data02 $data03 $data04 $data05 $data06 -if $data01 != 100 then +if $data00 != 100 then return -1 endi diff --git a/tests/script/tsim/tag/double.sim b/tests/script/tsim/tag/double.sim index 3f936318fb..fedc1c89ec 100644 --- a/tests/script/tsim/tag/double.sim +++ b/tests/script/tsim/tag/double.sim @@ -223,9 +223,9 @@ endi print =============== step12 -sql select count(tbcol), avg(tbcol), sum(tbcol), min(tbcol), max(tbcol), first(tbcol), last(tbcol) from $mt interval(1d) group by tgcol +sql select count(tbcol), avg(tbcol), sum(tbcol), min(tbcol), max(tbcol), first(tbcol), last(tbcol) from $mt partition by tgcol interval(1d) print $data00 $data01 $data02 $data03 $data04 $data05 $data06 -if $data01 != 100 then +if $data00 != 100 then return -1 endi diff --git a/tests/script/tsim/tag/float.sim b/tests/script/tsim/tag/float.sim index 215869e003..0ed12d2269 100644 --- a/tests/script/tsim/tag/float.sim +++ b/tests/script/tsim/tag/float.sim @@ -223,9 +223,9 @@ endi print =============== step12 -sql select count(tbcol), avg(tbcol), sum(tbcol), min(tbcol), max(tbcol), first(tbcol), last(tbcol) from $mt interval(1d) group by tgcol +sql select count(tbcol), avg(tbcol), sum(tbcol), min(tbcol), max(tbcol), first(tbcol), last(tbcol) from $mt partition by tgcol interval(1d) print $data00 $data01 $data02 $data03 $data04 $data05 $data06 -if $data01 != 100 then +if $data00 != 100 then return -1 endi diff --git a/tests/script/tsim/tag/int.sim b/tests/script/tsim/tag/int.sim index d97079de91..e561cde56a 100644 --- a/tests/script/tsim/tag/int.sim +++ b/tests/script/tsim/tag/int.sim @@ -221,11 +221,10 @@ if $data00 != 25 then return -1 endi - print =============== step12 -sql select count(tbcol), avg(tbcol), sum(tbcol), min(tbcol), max(tbcol), first(tbcol), last(tbcol) from $mt interval(1d) group by tgcol +sql select count(tbcol), avg(tbcol), sum(tbcol), min(tbcol), max(tbcol), first(tbcol), last(tbcol) from $mt partition by tgcol interval(1d) print $data00 $data01 $data02 $data03 $data04 $data05 $data06 -if $data01 != 100 then +if $data00 != 100 then return -1 endi diff --git a/tests/script/tsim/tag/int_binary.sim b/tests/script/tsim/tag/int_binary.sim index fef77a16d9..01d73cf0c2 100644 --- a/tests/script/tsim/tag/int_binary.sim +++ b/tests/script/tsim/tag/int_binary.sim @@ -290,9 +290,9 @@ if $data00 != 25 then endi print =============== step14 -sql select count(tbcol), avg(tbcol), sum(tbcol), min(tbcol), max(tbcol), first(tbcol), last(tbcol) from $mt interval(1d) group by tgcol +sql select count(tbcol), avg(tbcol), sum(tbcol), min(tbcol), max(tbcol), first(tbcol), last(tbcol) from $mt partition by tgcol interval(1d) print $data00 $data01 $data02 $data03 $data04 $data05 $data06 -if $data01 != 100 then +if $data00 != 100 then return -1 endi diff --git a/tests/script/tsim/tag/int_float.sim b/tests/script/tsim/tag/int_float.sim index f184fdce0c..0b20ff3d62 100644 --- a/tests/script/tsim/tag/int_float.sim +++ b/tests/script/tsim/tag/int_float.sim @@ -306,9 +306,9 @@ if $data00 != 25 then endi print =============== step14 -sql select count(tbcol), avg(tbcol), sum(tbcol), min(tbcol), max(tbcol), first(tbcol), last(tbcol) from $mt interval(1d) group by tgcol +sql select count(tbcol), avg(tbcol), sum(tbcol), min(tbcol), max(tbcol), first(tbcol), last(tbcol) from $mt partition by tgcol interval(1d) print $data00 $data01 $data02 $data03 $data04 $data05 $data06 -if $data01 != 100 then +if $data00 != 100 then return -1 endi diff --git a/tests/script/tsim/tag/smallint.sim b/tests/script/tsim/tag/smallint.sim index cb65a93d5f..47e28db46c 100644 --- a/tests/script/tsim/tag/smallint.sim +++ b/tests/script/tsim/tag/smallint.sim @@ -221,11 +221,10 @@ if $data00 != 25 then return -1 endi - print =============== step12 -sql select count(tbcol), avg(tbcol), sum(tbcol), min(tbcol), max(tbcol), first(tbcol), last(tbcol) from $mt interval(1d) group by tgcol +sql select count(tbcol), avg(tbcol), sum(tbcol), min(tbcol), max(tbcol), first(tbcol), last(tbcol) from $mt partition by tgcol interval(1d) print $data00 $data01 $data02 $data03 $data04 $data05 $data06 -if $data01 != 100 then +if $data00 != 100 then return -1 endi diff --git a/tests/script/tsim/tag/tinyint.sim b/tests/script/tsim/tag/tinyint.sim index c6d9df2597..0941c9cf18 100644 --- a/tests/script/tsim/tag/tinyint.sim +++ b/tests/script/tsim/tag/tinyint.sim @@ -221,11 +221,10 @@ if $data00 != 25 then return -1 endi - print =============== step12 -sql select count(tbcol), avg(tbcol), sum(tbcol), min(tbcol), max(tbcol), first(tbcol), last(tbcol) from $mt interval(1d) group by tgcol +sql select count(tbcol), avg(tbcol), sum(tbcol), min(tbcol), max(tbcol), first(tbcol), last(tbcol) from $mt partition by tgcol interval(1d) print $data00 $data01 $data02 $data03 $data04 $data05 $data06 -if $data01 != 100 then +if $data00 != 100 then return -1 endi -- GitLab From 91a59257348752373cfa9e50edb53519b19ec204 Mon Sep 17 00:00:00 2001 From: Shengliang Guan Date: Thu, 14 Jul 2022 13:41:43 +0800 Subject: [PATCH 111/153] test: restore some 2.0 case --- .../script/general/connection/connection.sim | 21 ------------ tests/script/general/connection/mqtt.sim | 19 ----------- tests/script/general/connection/sim.tar.gz | Bin 9104 -> 0 bytes .../general/connection/test_old_data.sim | 32 ------------------ tests/script/jenkins/basic.txt | 4 +-- 5 files changed, 2 insertions(+), 74 deletions(-) delete mode 100644 tests/script/general/connection/connection.sim delete mode 100644 tests/script/general/connection/mqtt.sim delete mode 100644 tests/script/general/connection/sim.tar.gz delete mode 100644 tests/script/general/connection/test_old_data.sim diff --git a/tests/script/general/connection/connection.sim b/tests/script/general/connection/connection.sim deleted file mode 100644 index 1af6e1fda6..0000000000 --- a/tests/script/general/connection/connection.sim +++ /dev/null @@ -1,21 +0,0 @@ -system sh/stop_dnodes.sh -system sh/deploy.sh -n dnode1 -i 1 -system sh/cfg.sh -n dnode1 -c wallevel -v 0 -system sh/exec.sh -n dnode1 -s start -sleep 2000 -sql connect - -print ============= step1 -sql close -print close1 -sql connect - -print ============= step2 -sql close -sql connect - -print ============= step3 -sql close -sql connect - -system sh/exec.sh -n dnode1 -s stop -x SIGINT \ No newline at end of file diff --git a/tests/script/general/connection/mqtt.sim b/tests/script/general/connection/mqtt.sim deleted file mode 100644 index c2c50ef17e..0000000000 --- a/tests/script/general/connection/mqtt.sim +++ /dev/null @@ -1,19 +0,0 @@ -system sh/stop_dnodes.sh - -system sh/deploy.sh -n dnode1 -i 1 -system sh/cfg.sh -n dnode1 -c walLevel -v 2 -system sh/cfg.sh -n dnode1 -c numOfMnodes -v 1 -system sh/cfg.sh -n dnode1 -c mnodeEqualVnodeNum -v 4 -system sh/cfg.sh -n dnode1 -c maxTablesPerVnode -v 100000 -system sh/cfg.sh -n dnode1 -c http -v 1 -system sh/cfg.sh -n dnode1 -c mqtt -v 1 - -system sh/exec.sh -n dnode1 -s start - -sleep 2000 -sql connect -sql create database mqttdb; -sql create table mqttdb.devices(ts timestamp, value double) tags(name binary(32), model binary(32), serial binary(16), param binary(16), unit binary(16)); - -sleep 1000 -system sh/exec.sh -n dnode1 -s stop -x SIGINT diff --git a/tests/script/general/connection/sim.tar.gz b/tests/script/general/connection/sim.tar.gz deleted file mode 100644 index 10bc1a6bace1c8b6796a98c53e3aa3c15e0bfd7c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 9104 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 diff --git a/tests/script/general/connection/test_old_data.sim b/tests/script/general/connection/test_old_data.sim deleted file mode 100644 index 83df850f0b..0000000000 --- a/tests/script/general/connection/test_old_data.sim +++ /dev/null @@ -1,32 +0,0 @@ -system sh/stop_dnodes.sh -system sh/mv_old_data.sh - -print ============== deploy - -system sh/exec.sh -n dnode1 -s start -system sh/exec.sh -n dnode2 -s start -system sh/exec.sh -n dnode3 -s start - -print =============== step1 - -sql use test -sql select * from m1 - -print $rows points data are retrieved -if $rows != 7 then - return -1 -endi - -print =============== step 2 - -sql select * from t1 - -print $rows points data are retrieved -if $rows != 7 then - return -1 -endi - - -system sh/exec.sh -n dnode1 -s stop -x SIGINT -system sh/exec.sh -n dnode2 -s stop -x SIGINT -system sh/exec.sh -n dnode3 -s stop -x SIGINT \ No newline at end of file diff --git a/tests/script/jenkins/basic.txt b/tests/script/jenkins/basic.txt index 78dec01a74..2ba337ddb5 100644 --- a/tests/script/jenkins/basic.txt +++ b/tests/script/jenkins/basic.txt @@ -298,11 +298,11 @@ #./test.sh -f tsim/tag/delete.sim #./test.sh -f tsim/tag/double.sim #./test.sh -f tsim/tag/filter.sim -./test.sh -f tsim/tag/float.sim +#./test.sh -f tsim/tag/float.sim ./test.sh -f tsim/tag/int_binary.sim ./test.sh -f tsim/tag/int_float.sim ./test.sh -f tsim/tag/int.sim -./test.sh -f tsim/tag/set.sim +#./test.sh -f tsim/tag/set.sim ./test.sh -f tsim/tag/smallint.sim ./test.sh -f tsim/tag/tinyint.sim -- GitLab From 75aca0b0316bb7468bc521a0aa0ee367f0f744a1 Mon Sep 17 00:00:00 2001 From: Haojun Liao Date: Thu, 14 Jul 2022 13:53:23 +0800 Subject: [PATCH 112/153] fix(query): set correct fill output column index, fix some memory leak, and do some internal refactor, --- include/common/tcommon.h | 14 -------- include/common/tdatablock.h | 6 +++- include/libs/stream/tstream.h | 4 +-- source/common/src/tdatablock.c | 15 +++++++- source/dnode/vnode/src/tq/tqRead.c | 2 +- source/dnode/vnode/src/tsdb/tsdbRead.c | 15 ++++---- source/libs/executor/src/scanoperator.c | 4 +-- source/libs/executor/src/tfill.c | 46 ++++++++++++++----------- source/libs/function/src/udfd.c | 6 ++-- source/libs/stream/src/streamData.c | 2 +- source/libs/stream/src/streamDispatch.c | 2 +- source/libs/stream/src/streamExec.c | 8 ++--- 12 files changed, 65 insertions(+), 59 deletions(-) diff --git a/include/common/tcommon.h b/include/common/tcommon.h index d8264ac5b5..005a4e9f57 100644 --- a/include/common/tcommon.h +++ b/include/common/tcommon.h @@ -162,7 +162,6 @@ typedef struct SQueryTableDataCond { int64_t endVersion; } SQueryTableDataCond; -void* blockDataDestroy(SSDataBlock* pBlock); int32_t tEncodeDataBlock(void** buf, const SSDataBlock* pBlock); void* tDecodeDataBlock(const void* buf, SSDataBlock* pBlock); @@ -170,19 +169,6 @@ int32_t tEncodeDataBlocks(void** buf, const SArray* blocks); void* tDecodeDataBlocks(const void* buf, SArray** blocks); void colDataDestroy(SColumnInfoData* pColData); -static FORCE_INLINE void blockDestroyInner(SSDataBlock* pBlock) { - int32_t numOfOutput = taosArrayGetSize(pBlock->pDataBlock); - for (int32_t i = 0; i < numOfOutput; ++i) { - SColumnInfoData* pColInfoData = (SColumnInfoData*)taosArrayGet(pBlock->pDataBlock, i); - colDataDestroy(pColInfoData); - } - - taosArrayDestroy(pBlock->pDataBlock); - taosMemoryFreeClear(pBlock->pBlockAgg); -} - -static FORCE_INLINE void tDeleteSSDataBlock(SSDataBlock* pBlock) { blockDestroyInner(pBlock); } - //====================================================================================================================== // the following structure shared by parser and executor typedef struct SColumn { diff --git a/include/common/tdatablock.h b/include/common/tdatablock.h index af333f72aa..a4f5904018 100644 --- a/include/common/tdatablock.h +++ b/include/common/tdatablock.h @@ -226,8 +226,12 @@ int32_t blockDataKeepFirstNRows(SSDataBlock* pBlock, size_t n); int32_t assignOneDataBlock(SSDataBlock* dst, const SSDataBlock* src); int32_t copyDataBlock(SSDataBlock* dst, const SSDataBlock* src); -SSDataBlock* createOneDataBlock(const SSDataBlock* pDataBlock, bool copyData); + SSDataBlock* createDataBlock(); +void* blockDataDestroy(SSDataBlock* pBlock); +void blockDataFreeRes(SSDataBlock* pBlock); +SSDataBlock* createOneDataBlock(const SSDataBlock* pDataBlock, bool copyData); + int32_t blockDataAppendColInfo(SSDataBlock* pBlock, SColumnInfoData* pColInfoData); SColumnInfoData createColumnInfoData(int16_t type, int32_t bytes, int16_t colId); diff --git a/include/libs/stream/tstream.h b/include/libs/stream/tstream.h index a08db7b8f8..071c539ff3 100644 --- a/include/libs/stream/tstream.h +++ b/include/libs/stream/tstream.h @@ -340,12 +340,12 @@ static FORCE_INLINE int32_t streamTaskOutput(SStreamTask* pTask, SStreamDataBloc if (pTask->sinkType == TASK_SINK__TABLE) { ASSERT(pTask->dispatchType == TASK_DISPATCH__NONE); pTask->tbSink.tbSinkFunc(pTask, pTask->tbSink.vnode, 0, pBlock->blocks); - taosArrayDestroyEx(pBlock->blocks, (FDelete)tDeleteSSDataBlock); + taosArrayDestroyEx(pBlock->blocks, (FDelete)blockDataFreeRes); taosFreeQitem(pBlock); } else if (pTask->sinkType == TASK_SINK__SMA) { ASSERT(pTask->dispatchType == TASK_DISPATCH__NONE); pTask->smaSink.smaSink(pTask->smaSink.vnode, pTask->smaSink.smaId, pBlock->blocks); - taosArrayDestroyEx(pBlock->blocks, (FDelete)tDeleteSSDataBlock); + taosArrayDestroyEx(pBlock->blocks, (FDelete)blockDataFreeRes); taosFreeQitem(pBlock); } else { ASSERT(pTask->dispatchType != TASK_DISPATCH__NONE); diff --git a/source/common/src/tdatablock.c b/source/common/src/tdatablock.c index 9f5a247d76..47cfa5d410 100644 --- a/source/common/src/tdatablock.c +++ b/source/common/src/tdatablock.c @@ -1197,15 +1197,28 @@ int32_t blockDataEnsureCapacity(SSDataBlock* pDataBlock, uint32_t numOfRows) { return TSDB_CODE_SUCCESS; } +void blockDataFreeRes(SSDataBlock* pBlock) { + int32_t numOfOutput = taosArrayGetSize(pBlock->pDataBlock); + for (int32_t i = 0; i < numOfOutput; ++i) { + SColumnInfoData* pColInfoData = (SColumnInfoData*)taosArrayGet(pBlock->pDataBlock, i); + colDataDestroy(pColInfoData); + } + + taosArrayDestroy(pBlock->pDataBlock); + taosMemoryFreeClear(pBlock->pBlockAgg); + memset(&pBlock->info, 0, sizeof(SDataBlockInfo)); +} + void* blockDataDestroy(SSDataBlock* pBlock) { if (pBlock == NULL) { return NULL; } - blockDestroyInner(pBlock); + blockDataFreeRes(pBlock); taosMemoryFreeClear(pBlock); return NULL; } + int32_t assignOneDataBlock(SSDataBlock* dst, const SSDataBlock* src) { ASSERT(src != NULL); diff --git a/source/dnode/vnode/src/tq/tqRead.c b/source/dnode/vnode/src/tq/tqRead.c index 8753ecc47c..a7ad935caa 100644 --- a/source/dnode/vnode/src/tq/tqRead.c +++ b/source/dnode/vnode/src/tq/tqRead.c @@ -319,7 +319,7 @@ int32_t tqRetrieveDataBlock(SSDataBlock* pBlock, STqReader* pReader) { return 0; FAIL: - tDeleteSSDataBlock(pBlock); + blockDataFreeRes(pBlock); return -1; } diff --git a/source/dnode/vnode/src/tsdb/tsdbRead.c b/source/dnode/vnode/src/tsdb/tsdbRead.c index 4aaa80d3ae..5e30fcd5b2 100644 --- a/source/dnode/vnode/src/tsdb/tsdbRead.c +++ b/source/dnode/vnode/src/tsdb/tsdbRead.c @@ -209,10 +209,10 @@ static void resetDataBlockScanInfo(SHashObj* pTableMap) { p->iterInit = false; p->iiter.hasVal = false; if (p->iter.iter != NULL) { - tsdbTbDataIterDestroy(p->iter.iter); + p->iter.iter = tsdbTbDataIterDestroy(p->iter.iter); } - taosArrayDestroy(p->delSkyline); + p->delSkyline = taosArrayDestroy(p->delSkyline); } } @@ -224,18 +224,15 @@ static void destroyBlockScanInfo(SHashObj* pTableMap) { p->iiter.hasVal = false; if (p->iter.iter != NULL) { - tsdbTbDataIterDestroy(p->iter.iter); - p->iter.iter = NULL; + p->iter.iter = tsdbTbDataIterDestroy(p->iter.iter); } if (p->iiter.iter != NULL) { - tsdbTbDataIterDestroy(p->iiter.iter); - p->iiter.iter = NULL; + p->iiter.iter = tsdbTbDataIterDestroy(p->iiter.iter); } - taosArrayDestroy(p->delSkyline); - taosArrayDestroy(p->pBlockList); - p->delSkyline = NULL; + p->delSkyline = taosArrayDestroy(p->delSkyline); + p->pBlockList = taosArrayDestroy(p->pBlockList); } taosHashCleanup(pTableMap); diff --git a/source/libs/executor/src/scanoperator.c b/source/libs/executor/src/scanoperator.c index 701002d0e7..1d309931d6 100644 --- a/source/libs/executor/src/scanoperator.c +++ b/source/libs/executor/src/scanoperator.c @@ -1193,8 +1193,6 @@ static int32_t setBlockIntoRes(SStreamScanInfo* pInfo, const SSDataBlock* pBlock } } - taosArrayDestroy(pBlock->pDataBlock); - ASSERT(pInfo->pRes->pDataBlock != NULL); // currently only the tbname pseudo column @@ -1202,12 +1200,14 @@ static int32_t setBlockIntoRes(SStreamScanInfo* pInfo, const SSDataBlock* pBlock int32_t code = addTagPseudoColumnData(&pInfo->readHandle, pInfo->pPseudoExpr, pInfo->numOfPseudoExpr, pInfo->pRes, GET_TASKID(pTaskInfo)); if (code != TSDB_CODE_SUCCESS) { + blockDataFreeRes((SSDataBlock*) pBlock); longjmp(pTaskInfo->env, code); } } doFilter(pInfo->pCondition, pInfo->pRes); blockDataUpdateTsWindow(pInfo->pRes, pInfo->primaryTsIndex); + blockDataFreeRes((SSDataBlock*) pBlock); return 0; } diff --git a/source/libs/executor/src/tfill.c b/source/libs/executor/src/tfill.c index 959c03a3b1..e0bdcfdc3a 100644 --- a/source/libs/executor/src/tfill.c +++ b/source/libs/executor/src/tfill.c @@ -71,13 +71,8 @@ static void doFillOneRow(SFillInfo* pFillInfo, SSDataBlock* pBlock, SSDataBlock* SPoint point1, point2, point; int32_t step = GET_FORWARD_DIRECTION_FACTOR(pFillInfo->order); - // set the primary timestamp column value - int32_t index = pFillInfo->numOfCurrent; - SColumnInfoData* pCol0 = taosArrayGet(pBlock->pDataBlock, pFillInfo->tsSlotId); - char* val = colDataGetData(pCol0, index); - - // set the primary timestamp value - *(TSKEY*)val = pFillInfo->currentKey; +// set the primary timestamp column value + int32_t index = pFillInfo->numOfCurrent; // set the other values if (pFillInfo->type == TSDB_FILL_PREV) { @@ -92,7 +87,7 @@ static void doFillOneRow(SFillInfo* pFillInfo, SSDataBlock* pBlock, SSDataBlock* SColumnInfoData* pDstColInfoData = taosArrayGet(pBlock->pDataBlock, GET_DEST_SLOT_ID(pCol)); if (pDstColInfoData->info.type == TSDB_DATA_TYPE_TIMESTAMP) { - colDataAppend(pDstColInfoData, index, (const char*)&ts, false); + colDataAppend(pDstColInfoData, index, (const char*)&pFillInfo->currentKey, false); } else { SGroupKeys* pKey = taosArrayGet(p, i); doSetVal(pDstColInfoData, index, pKey); @@ -101,41 +96,51 @@ static void doFillOneRow(SFillInfo* pFillInfo, SSDataBlock* pBlock, SSDataBlock* } else if (pFillInfo->type == TSDB_FILL_NEXT) { SArray* p = FILL_IS_ASC_FILL(pFillInfo) ? pFillInfo->next : pFillInfo->prev; // todo refactor: start from 0 not 1 - for (int32_t i = 1; i < pFillInfo->numOfCols; ++i) { + for (int32_t i = 0; i < pFillInfo->numOfCols; ++i) { SFillColInfo* pCol = &pFillInfo->pFillCol[i]; if (TSDB_COL_IS_TAG(pCol->flag)) { continue; } - SGroupKeys* pKey = taosArrayGet(p, i); SColumnInfoData* pDstColInfoData = taosArrayGet(pBlock->pDataBlock, GET_DEST_SLOT_ID(pCol)); - doSetVal(pDstColInfoData, index, pKey); + + if (pDstColInfoData->info.type == TSDB_DATA_TYPE_TIMESTAMP) { + colDataAppend(pDstColInfoData, index, (const char*)&pFillInfo->currentKey, false); + } else { + SGroupKeys* pKey = taosArrayGet(p, i); + doSetVal(pDstColInfoData, index, pKey); + } } } else if (pFillInfo->type == TSDB_FILL_LINEAR) { // TODO : linear interpolation supports NULL value if (outOfBound) { setNullRow(pBlock, pFillInfo->currentKey, index); } else { - for (int32_t i = 1; i < pFillInfo->numOfCols; ++i) { + for (int32_t i = 0; i < pFillInfo->numOfCols; ++i) { SFillColInfo* pCol = &pFillInfo->pFillCol[i]; if (TSDB_COL_IS_TAG(pCol->flag)) { continue; } - int32_t srcSlotId = GET_SRC_SLOT_ID(pCol); - int32_t dstSlotId = GET_DEST_SLOT_ID(pCol); SColumnInfoData* pDstCol = taosArrayGet(pBlock->pDataBlock, dstSlotId); - int16_t type = pCol->pExpr->base.resSchema.type; + int16_t type = pDstCol->info.type; + if (type == TSDB_DATA_TYPE_TIMESTAMP) { + colDataAppend(pDstCol, index, (const char*)&pFillInfo->currentKey, false); + continue; + } + SGroupKeys* pKey = taosArrayGet(pFillInfo->prev, i); if (IS_VAR_DATA_TYPE(type) || type == TSDB_DATA_TYPE_BOOL || pKey->isNull) { colDataAppendNULL(pDstCol, index); continue; } - SGroupKeys* pKey1 = taosArrayGet(pFillInfo->prev, 0); - int64_t prevTs = *(int64_t*)pKey1->pData; + SGroupKeys* pKey1 = taosArrayGet(pFillInfo->prev, pFillInfo->tsSlotId); + + int64_t prevTs = *(int64_t*)pKey1->pData; + int32_t srcSlotId = GET_SRC_SLOT_ID(pCol); SColumnInfoData* pSrcCol = taosArrayGet(pSrcBlock->pDataBlock, srcSlotId); char* data = colDataGetData(pSrcCol, pFillInfo->index); @@ -153,7 +158,7 @@ static void doFillOneRow(SFillInfo* pFillInfo, SSDataBlock* pBlock, SSDataBlock* } else if (pFillInfo->type == TSDB_FILL_NULL) { // fill with NULL setNullRow(pBlock, pFillInfo->currentKey, index); } else { // fill with user specified value for each column - for (int32_t i = 1; i < pFillInfo->numOfCols; ++i) { + for (int32_t i = 0; i < pFillInfo->numOfCols; ++i) { SFillColInfo* pCol = &pFillInfo->pFillCol[i]; if (TSDB_COL_IS_TAG(pCol->flag) /* || IS_VAR_DATA_TYPE(pCol->schema.type)*/) { continue; @@ -176,6 +181,8 @@ static void doFillOneRow(SFillInfo* pFillInfo, SSDataBlock* pBlock, SSDataBlock* colDataAppend(pDst, index, (char*)&v, false); } else if (pDst->info.type == TSDB_DATA_TYPE_TIMESTAMP) { colDataAppend(pDst, index, (const char*)&pFillInfo->currentKey, false); + } else { // varchar/nchar data + colDataAppendNULL(pDst, index); } } } @@ -234,8 +241,7 @@ static void copyCurrentRowIntoBuf(SFillInfo* pFillInfo, int32_t rowIndex, SArray static int32_t fillResultImpl(SFillInfo* pFillInfo, SSDataBlock* pBlock, int32_t outputRows) { pFillInfo->numOfCurrent = 0; - // todo make sure the first column is always the primary timestamp column? - SColumnInfoData* pTsCol = taosArrayGet(pFillInfo->pSrcBlock->pDataBlock, 0); + SColumnInfoData* pTsCol = taosArrayGet(pFillInfo->pSrcBlock->pDataBlock, pFillInfo->tsSlotId); int32_t step = GET_FORWARD_DIRECTION_FACTOR(pFillInfo->order); bool ascFill = FILL_IS_ASC_FILL(pFillInfo); diff --git a/source/libs/function/src/udfd.c b/source/libs/function/src/udfd.c index a412b589a9..fd9b588d46 100644 --- a/source/libs/function/src/udfd.c +++ b/source/libs/function/src/udfd.c @@ -296,8 +296,8 @@ void udfdProcessCallRequest(SUvUdfWork *uvUdf, SUdfRequest *request) { switch (call->callType) { case TSDB_UDF_CALL_SCALA_PROC: { - tDeleteSSDataBlock(&call->block); - tDeleteSSDataBlock(&subRsp->resultData); + blockDataFreeRes(&call->block); + blockDataFreeRes(&subRsp->resultData); break; } case TSDB_UDF_CALL_AGG_INIT: { @@ -305,7 +305,7 @@ void udfdProcessCallRequest(SUvUdfWork *uvUdf, SUdfRequest *request) { break; } case TSDB_UDF_CALL_AGG_PROC: { - tDeleteSSDataBlock(&call->block); + blockDataFreeRes(&call->block); freeUdfInterBuf(&subRsp->resultBuf); break; } diff --git a/source/libs/stream/src/streamData.c b/source/libs/stream/src/streamData.c index 2b3307b7f5..8e16b23e56 100644 --- a/source/libs/stream/src/streamData.c +++ b/source/libs/stream/src/streamData.c @@ -116,7 +116,7 @@ void streamFreeQitem(SStreamQueueItem* data) { blockDataDestroy(((SStreamTrigger*)data)->pBlock); taosFreeQitem(data); } else if (type == STREAM_INPUT__DATA_BLOCK || type == STREAM_INPUT__DATA_RETRIEVE) { - taosArrayDestroyEx(((SStreamDataBlock*)data)->blocks, (FDelete)tDeleteSSDataBlock); + taosArrayDestroyEx(((SStreamDataBlock*)data)->blocks, (FDelete)blockDataFreeRes); taosFreeQitem(data); } else if (type == STREAM_INPUT__DATA_SUBMIT) { streamDataSubmitRefDec((SStreamDataSubmit*)data); diff --git a/source/libs/stream/src/streamDispatch.c b/source/libs/stream/src/streamDispatch.c index 05efce8bc2..e2faf28abe 100644 --- a/source/libs/stream/src/streamDispatch.c +++ b/source/libs/stream/src/streamDispatch.c @@ -313,7 +313,7 @@ int32_t streamDispatch(SStreamTask* pTask, SMsgCb* pMsgCb) { atomic_store_8(&pTask->outputStatus, TASK_OUTPUT_STATUS__NORMAL); return -1; } - taosArrayDestroyEx(pBlock->blocks, (FDelete)tDeleteSSDataBlock); + taosArrayDestroyEx(pBlock->blocks, (FDelete)blockDataFreeRes); taosFreeQitem(pBlock); tmsgSendReq(pEpSet, &dispatchMsg); diff --git a/source/libs/stream/src/streamExec.c b/source/libs/stream/src/streamExec.c index d0d81e3343..023c092028 100644 --- a/source/libs/stream/src/streamExec.c +++ b/source/libs/stream/src/streamExec.c @@ -106,7 +106,7 @@ static SArray* streamExecForQall(SStreamTask* pTask, SArray* pRes) { qDebug("stream task %d exec end", pTask->taskId); if (pTask->taskStatus == TASK_STATUS__DROPPING) { - taosArrayDestroyEx(pRes, (FDelete)tDeleteSSDataBlock); + taosArrayDestroyEx(pRes, (FDelete)blockDataFreeRes); return NULL; } @@ -121,7 +121,7 @@ static SArray* streamExecForQall(SStreamTask* pTask, SArray* pRes) { qRes->blocks = pRes; if (streamTaskOutput(pTask, qRes) < 0) { /*streamQueueProcessFail(pTask->inputQueue);*/ - taosArrayDestroyEx(pRes, (FDelete)tDeleteSSDataBlock); + taosArrayDestroyEx(pRes, (FDelete)blockDataFreeRes); taosFreeQitem(qRes); return NULL; } @@ -155,7 +155,7 @@ int32_t streamExec(SStreamTask* pTask, SMsgCb* pMsgCb) { pRes = streamExecForQall(pTask, pRes); if (pRes == NULL) goto FAIL; - taosArrayDestroyEx(pRes, (FDelete)tDeleteSSDataBlock); + taosArrayDestroyEx(pRes, (FDelete)blockDataFreeRes); atomic_store_8(&pTask->execStatus, TASK_EXEC_STATUS__IDLE); qDebug("stream exec, return result"); return 0; @@ -163,7 +163,7 @@ int32_t streamExec(SStreamTask* pTask, SMsgCb* pMsgCb) { continue; } else if (execStatus == TASK_EXEC_STATUS__EXECUTING) { ASSERT(taosArrayGetSize(pRes) == 0); - taosArrayDestroyEx(pRes, (FDelete)tDeleteSSDataBlock); + taosArrayDestroyEx(pRes, (FDelete)blockDataFreeRes); return 0; } else { ASSERT(0); -- GitLab From 4849b0cb78a17395a5443c5da5213b5ff48be374 Mon Sep 17 00:00:00 2001 From: afwerar <1296468573@qq.com> Date: Thu, 14 Jul 2022 13:58:23 +0800 Subject: [PATCH 113/153] test: fix win test error --- cmake/cmake.options | 8 +++++++- include/os/osDef.h | 10 +++++++++- tests/pytest/util/dnodes.py | 24 ++++++++++++------------ tests/script/sh/exec.bat | 7 +++++-- tests/script/test-all.bat | 2 +- tests/script/wtest.bat | 3 ++- tests/system-test/test.py | 19 ++++++++++++++++++- 7 files changed, 54 insertions(+), 19 deletions(-) diff --git a/cmake/cmake.options b/cmake/cmake.options index e013ff7592..2acd46694b 100644 --- a/cmake/cmake.options +++ b/cmake/cmake.options @@ -79,10 +79,16 @@ ENDIF () option( BUILD_SANITIZER - "If build addr2line" + "If build sanitizer" OFF ) +option( + TDENGINE_3 + "TDengine 3.x" + ON + ) + option( BUILD_ADDR2LINE "If build addr2line" diff --git a/include/os/osDef.h b/include/os/osDef.h index 6f6199de7a..14f38eb7ff 100644 --- a/include/os/osDef.h +++ b/include/os/osDef.h @@ -22,7 +22,10 @@ extern "C" { #if defined(_TD_DARWIN_64) // specific +#ifndef __COMPAR_FN_T +#define __COMPAR_FN_T typedef int(*__compar_fn_t)(const void *, const void *); +#endif // for send function in tsocket.c #if defined(MSG_NOSIGNAL) @@ -41,7 +44,10 @@ extern "C" { #endif #if defined(_ALPINE) +#ifndef __COMPAR_FN_T +#define __COMPAR_FN_T typedef int(*__compar_fn_t)(const void *, const void *); +#endif void error (int, int, const char *); #ifndef PTHREAD_MUTEX_RECURSIVE_NP #define PTHREAD_MUTEX_RECURSIVE_NP PTHREAD_MUTEX_RECURSIVE @@ -54,7 +60,10 @@ extern "C" { char *stpncpy (char *dest, const char *src, size_t n); // specific +#ifndef __COMPAR_FN_T +#define __COMPAR_FN_T typedef int (*__compar_fn_t)(const void *, const void *); +#endif #define ssize_t int #define _SSIZE_T_ #define bzero(ptr, size) memset((ptr), 0, (size)) @@ -69,7 +78,6 @@ extern "C" { char * strsep(char **stringp, const char *delim); char * getpass(const char *prefix); char * strndup(const char *s, size_t n); - int gettimeofday(struct timeval *ptv, void *pTimeZone); // for send function in tsocket.c #define MSG_NOSIGNAL 0 diff --git a/tests/pytest/util/dnodes.py b/tests/pytest/util/dnodes.py index a38b14a52d..96723978ae 100644 --- a/tests/pytest/util/dnodes.py +++ b/tests/pytest/util/dnodes.py @@ -382,7 +382,7 @@ class TDDnode: if self.valgrind == 0: if platform.system().lower() == 'windows': - cmd = "mintty -h never -w hide %s -c %s" % ( + cmd = "mintty -h never %s -c %s" % ( binPath, self.cfgDir) else: cmd = "nohup %s -c %s > /dev/null 2>&1 & " % ( @@ -391,7 +391,7 @@ class TDDnode: valgrindCmdline = "valgrind --log-file=\"%s/../log/valgrind.log\" --tool=memcheck --leak-check=full --show-reachable=no --track-origins=yes --show-leak-kinds=all -v --workaround-gcc296-bugs=yes"%self.cfgDir if platform.system().lower() == 'windows': - cmd = "mintty -h never -w hide %s %s -c %s" % ( + cmd = "mintty -h never %s %s -c %s" % ( valgrindCmdline, binPath, self.cfgDir) else: cmd = "nohup %s %s -c %s 2>&1 & " % ( @@ -518,20 +518,20 @@ class TDDnode: if self.running != 0: if platform.system().lower() == 'windows': - os.system("wmic process where \"name='taosd.exe' and CommandLine like '%%dnode%d%%'\" get processId | xargs echo | awk '{print $2}' | xargs taskkill -f -pid"%self.index) + psCmd = "for /f %a in ('wmic process where \"name='taosd.exe' and CommandLine like '%%dnode%d%%'\" get processId ^| xargs echo ^| awk ^'{print $2}^'') do @(ps | grep %a | awk '{print $1}' | xargs kill -INT )" % (self.index) else: psCmd = "ps -ef|grep -w %s| grep dnode%d|grep -v grep | awk '{print $2}'" % (toBeKilled,self.index) + processID = subprocess.check_output( + psCmd, shell=True).decode("utf-8") + + while(processID): + killCmd = "kill -INT %s > /dev/null 2>&1" % processID + os.system(killCmd) + time.sleep(1) processID = subprocess.check_output( psCmd, shell=True).decode("utf-8") - - while(processID): - killCmd = "kill -INT %s > /dev/null 2>&1" % processID - os.system(killCmd) - time.sleep(1) - processID = subprocess.check_output( - psCmd, shell=True).decode("utf-8") - if self.valgrind: - time.sleep(2) + if self.valgrind: + time.sleep(2) self.running = 0 tdLog.debug("dnode:%d is stopped by kill -INT" % (self.index)) diff --git a/tests/script/sh/exec.bat b/tests/script/sh/exec.bat index e4c998c25b..88dd43349e 100644 --- a/tests/script/sh/exec.bat +++ b/tests/script/sh/exec.bat @@ -77,7 +77,10 @@ goto :eof :check_offline sleep 1 for /f "tokens=2" %%C in ('wmic process where "name='taosd.exe' and CommandLine like '%%%NODE_NAME%%%'" get processId ^| xargs echo') do ( - echo check taosd offline - goto :check_offline + for /f "tokens=1" %%D in ('ps ^| grep %%C') do ( + echo kill -INT %%D + echo check taosd offline %NODE_NAME% %%C %%D + goto :check_offline + ) ) goto :eof \ No newline at end of file diff --git a/tests/script/test-all.bat b/tests/script/test-all.bat index f771f8fcb6..056d989e6b 100644 --- a/tests/script/test-all.bat +++ b/tests/script/test-all.bat @@ -24,7 +24,7 @@ for /F "usebackq tokens=*" %%i in (!caseFile!) do ( ) ) ) -exit !exitNum! +exit /b !exitNum! :colorEcho set timeNow=%time% diff --git a/tests/script/wtest.bat b/tests/script/wtest.bat index e3bbff9db5..f674277df9 100644 --- a/tests/script/wtest.bat +++ b/tests/script/wtest.bat @@ -44,9 +44,10 @@ echo serverPort 7100 >> %TAOS_CFG% echo logDir %LOG_DIR% >> %TAOS_CFG% echo scriptDir %SCRIPT_DIR% >> %TAOS_CFG% echo numOfLogLines 100000000 >> %TAOS_CFG% -echo rpcDebugFlag 135 >> %TAOS_CFG% +echo rpcDebugFlag 143 >> %TAOS_CFG% echo tmrDebugFlag 131 >> %TAOS_CFG% echo cDebugFlag 135 >> %TAOS_CFG% +echo qDebugFlag 143 >> %TAOS_CFG% echo udebugFlag 135 >> %TAOS_CFG% echo wal 0 >> %TAOS_CFG% echo asyncLog 0 >> %TAOS_CFG% diff --git a/tests/system-test/test.py b/tests/system-test/test.py index fd0979745e..b893f7af64 100644 --- a/tests/system-test/test.py +++ b/tests/system-test/test.py @@ -37,12 +37,13 @@ def checkRunTimeError(): time.sleep(1) timeCount = timeCount + 1 print("checkRunTimeError",timeCount) - if (timeCount>900): + if (timeCount>600): print("stop the test.") os.system("TASKKILL /F /IM taosd.exe") os.system("TASKKILL /F /IM taos.exe") os.system("TASKKILL /F /IM tmq_sim.exe") os.system("TASKKILL /F /IM mintty.exe") + os.system("TASKKILL /F /IM python.exe") quit(0) hwnd = win32gui.FindWindow(None, "Microsoft Visual C++ Runtime Library") if hwnd: @@ -228,6 +229,22 @@ if __name__ == "__main__": tdDnodes.deploy(1,updateCfgDict) tdDnodes.start(1) tdCases.logSql(logSql) + if queryPolicy != 1: + queryPolicy=int(queryPolicy) + conn = taos.connect( + host, + config=tdDnodes.getSimCfgPath()) + tdSql.init(conn.cursor()) + tdSql.execute("create qnode on dnode 1") + tdSql.execute('alter local "queryPolicy" "%d"'%queryPolicy) + tdSql.query("show local variables;") + for i in range(tdSql.queryRows): + if tdSql.queryResult[i][0] == "queryPolicy" : + if int(tdSql.queryResult[i][1]) == int(queryPolicy): + tdLog.success('alter queryPolicy to %d successfully'%queryPolicy) + else : + tdLog.debug(tdSql.queryResult) + tdLog.exit("alter queryPolicy to %d failed"%queryPolicy) else : tdLog.debug("create an cluster with %s nodes and make %s dnode as independent mnode"%(dnodeNums,mnodeNums)) dnodeslist = cluster.configure_cluster(dnodeNums=dnodeNums,mnodeNums=mnodeNums) -- GitLab From 29ff569191d0dc89e85d10a684b7391327904ca1 Mon Sep 17 00:00:00 2001 From: Ganlin Zhao Date: Thu, 14 Jul 2022 14:04:06 +0800 Subject: [PATCH 114/153] enable scalar function check to prevent crash --- source/libs/scalar/src/scalar.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/source/libs/scalar/src/scalar.c b/source/libs/scalar/src/scalar.c index b3bd989eb4..bbb7e07bad 100644 --- a/source/libs/scalar/src/scalar.c +++ b/source/libs/scalar/src/scalar.c @@ -700,9 +700,9 @@ EDealRes sclRewriteNonConstOperator(SNode** pNode, SScalarCtx *ctx) { EDealRes sclRewriteFunction(SNode** pNode, SScalarCtx *ctx) { SFunctionNode *node = (SFunctionNode *)*pNode; SNode* tnode = NULL; - //if (!fmIsScalarFunc(node->funcId)) { - // return DEAL_RES_CONTINUE; - //} + if (!fmIsScalarFunc(node->funcId)) { + return DEAL_RES_CONTINUE; + } FOREACH(tnode, node->pParameterList) { if (!SCL_IS_CONST_NODE(tnode)) { -- GitLab From dc4e5e61c12f6e424cdf4274da2b29dc0e2f622f Mon Sep 17 00:00:00 2001 From: Shengliang Guan Date: Thu, 14 Jul 2022 14:31:20 +0800 Subject: [PATCH 115/153] test: restore some 2.0 case --- tests/script/general/insert/testSuite.sim | 9 - tests/script/jenkins/basic.txt | 15 +- tests/script/tsim/insert/backquote.sim | 19 +- .../script/{general => tsim}/insert/basic.sim | 4 - tests/script/tsim/insert/basic0.sim | 18 -- tests/script/tsim/insert/basic1.sim | 19 +- tests/script/tsim/insert/commit-merge0.sim | 18 -- .../{general => tsim}/insert/insert_drop.sim | 14 +- tests/script/tsim/insert/null.sim | 164 ++++++++---------- .../insert/query_block1_file.sim | 7 +- .../insert/query_block1_memory.sim | 7 +- .../insert/query_block2_file.sim | 17 +- .../insert/query_block2_memory.sim | 7 +- .../insert/query_file_memory.sim | 16 +- .../insert/query_multi_file.sim | 16 +- tests/script/{general => tsim}/insert/tcp.sim | 5 +- 16 files changed, 97 insertions(+), 258 deletions(-) delete mode 100644 tests/script/general/insert/testSuite.sim rename tests/script/{general => tsim}/insert/basic.sim (87%) rename tests/script/{general => tsim}/insert/insert_drop.sim (86%) rename tests/script/{general => tsim}/insert/query_block1_file.sim (96%) rename tests/script/{general => tsim}/insert/query_block1_memory.sim (96%) rename tests/script/{general => tsim}/insert/query_block2_file.sim (93%) rename tests/script/{general => tsim}/insert/query_block2_memory.sim (96%) rename tests/script/{general => tsim}/insert/query_file_memory.sim (93%) rename tests/script/{general => tsim}/insert/query_multi_file.sim (72%) rename tests/script/{general => tsim}/insert/tcp.sim (84%) diff --git a/tests/script/general/insert/testSuite.sim b/tests/script/general/insert/testSuite.sim deleted file mode 100644 index da44167be5..0000000000 --- a/tests/script/general/insert/testSuite.sim +++ /dev/null @@ -1,9 +0,0 @@ -run general/insert/basic.sim -run general/insert/insert_drop.sim -run general/insert/query_block1_memory.sim -run general/insert/query_block2_memory.sim -run general/insert/query_block1_file.sim -run general/insert/query_block2_file.sim -run general/insert/query_file_memory.sim -run general/insert/query_multi_file.sim -run general/insert/tcp.sim diff --git a/tests/script/jenkins/basic.txt b/tests/script/jenkins/basic.txt index 2ba337ddb5..f1264f3cb4 100644 --- a/tests/script/jenkins/basic.txt +++ b/tests/script/jenkins/basic.txt @@ -52,13 +52,22 @@ ./test.sh -f tsim/import/replica1.sim # ---- insert +./test.sh -f tsim/insert/backquote.sim +./test.sh -f tsim/insert/basic.sim ./test.sh -f tsim/insert/basic0.sim ./test.sh -f tsim/insert/basic1.sim -./test.sh -f tsim/insert/backquote.sim -./test.sh -f tsim/insert/null.sim -./test.sh -f tsim/insert/update0.sim ./test.sh -f tsim/insert/commit-merge0.sim +./test.sh -f tsim/insert/insert_drop.sim ./test.sh -f tsim/insert/insert_select.sim +./test.sh -f tsim/insert/null.sim +./test.sh -f tsim/insert/query_block1_file.sim +./test.sh -f tsim/insert/query_block1_memory.sim +./test.sh -f tsim/insert/query_block2_file.sim +./test.sh -f tsim/insert/query_block2_memory.sim +./test.sh -f tsim/insert/query_file_memory.sim +./test.sh -f tsim/insert/query_multi_file.sim +#./test.sh -f tsim/insert/tcp.sim +./test.sh -f tsim/insert/update0.sim # ---- parser ./test.sh -f tsim/parser/groupby-basic.sim diff --git a/tests/script/tsim/insert/backquote.sim b/tests/script/tsim/insert/backquote.sim index ba50e70afa..db2cddd2ca 100644 --- a/tests/script/tsim/insert/backquote.sim +++ b/tests/script/tsim/insert/backquote.sim @@ -1,9 +1,9 @@ system sh/stop_dnodes.sh system sh/deploy.sh -n dnode1 -i 1 system sh/exec.sh -n dnode1 -s start -sleep 50 sql connect + print =============== create database sql create database `database` sql create database `DataBase` @@ -184,23 +184,6 @@ print =============== stop and restart taosd system sh/exec.sh -n dnode1 -s stop -x SIGINT system sh/exec.sh -n dnode1 -s start -$loop_cnt = 0 -check_dnode_ready: - $loop_cnt = $loop_cnt + 1 - sleep 200 - if $loop_cnt == 10 then - print ====> dnode not ready! - return -1 - endi -sql show dnodes -print ===> $rows $data00 $data01 $data02 $data03 $data04 $data05 -if $data00 != 1 then - return -1 -endi -if $data04 != ready then - goto check_dnode_ready -endi - sql show databases print rows: $rows print $data00 $data01 diff --git a/tests/script/general/insert/basic.sim b/tests/script/tsim/insert/basic.sim similarity index 87% rename from tests/script/general/insert/basic.sim rename to tests/script/tsim/insert/basic.sim index 88eb30a1ad..20b39c8f00 100644 --- a/tests/script/general/insert/basic.sim +++ b/tests/script/tsim/insert/basic.sim @@ -1,10 +1,6 @@ system sh/stop_dnodes.sh - system sh/deploy.sh -n dnode1 -i 1 -system sh/cfg.sh -n dnode1 -c walLevel -v 1 system sh/exec.sh -n dnode1 -s start - -sleep 2000 sql connect $i = 0 diff --git a/tests/script/tsim/insert/basic0.sim b/tests/script/tsim/insert/basic0.sim index 722bc0f907..b2fd7587da 100644 --- a/tests/script/tsim/insert/basic0.sim +++ b/tests/script/tsim/insert/basic0.sim @@ -283,30 +283,12 @@ endi # return -1 #endi -#=================================================================== #=================================================================== print =============== stop and restart taosd, then again do query above system sh/exec.sh -n dnode1 -s stop -x SIGINT system sh/exec.sh -n dnode1 -s start -$loop_cnt = 0 -check_dnode_ready: - $loop_cnt = $loop_cnt + 1 - sleep 200 - if $loop_cnt == 10 then - print ====> dnode not ready! - return -1 - endi -sql show dnodes -print ===> $rows $data00 $data01 $data02 $data03 $data04 $data05 -if $data00 != 1 then - return -1 -endi -if $data04 != ready then - goto check_dnode_ready -endi - print =============== query data from child table sql select * from ct1 print rows: $rows diff --git a/tests/script/tsim/insert/basic1.sim b/tests/script/tsim/insert/basic1.sim index d98407b380..cc7f22c007 100644 --- a/tests/script/tsim/insert/basic1.sim +++ b/tests/script/tsim/insert/basic1.sim @@ -1,9 +1,9 @@ system sh/stop_dnodes.sh system sh/deploy.sh -n dnode1 -i 1 system sh/exec.sh -n dnode1 -s start -sleep 50 sql connect + print =============== create database sql create database d1 sql show databases @@ -78,23 +78,6 @@ print =============== stop and restart taosd system sh/exec.sh -n dnode1 -s stop -x SIGINT system sh/exec.sh -n dnode1 -s start -$loop_cnt = 0 -check_dnode_ready: - $loop_cnt = $loop_cnt + 1 - sleep 200 - if $loop_cnt == 10 then - print ====> dnode not ready! - return -1 - endi -sql show dnodes -print ===> $rows $data00 $data01 $data02 $data03 $data04 $data05 -if $data00 != 1 then - return -1 -endi -if $data04 != ready then - goto check_dnode_ready -endi - print =============== query data sql select * from c1 print rows: $rows diff --git a/tests/script/tsim/insert/commit-merge0.sim b/tests/script/tsim/insert/commit-merge0.sim index 56e818654f..5fe7cc57b3 100644 --- a/tests/script/tsim/insert/commit-merge0.sim +++ b/tests/script/tsim/insert/commit-merge0.sim @@ -1,7 +1,6 @@ system sh/stop_dnodes.sh system sh/deploy.sh -n dnode1 -i 1 system sh/exec.sh -n dnode1 -s start -sleep 50 sql connect print =============== create database @@ -64,23 +63,6 @@ reboot_and_check: system sh/exec.sh -n dnode1 -s stop -x SIGINT system sh/exec.sh -n dnode1 -s start -$loop_cnt = 0 -check_dnode_ready: - $loop_cnt = $loop_cnt + 1 - sleep 200 - if $loop_cnt == 10 then - print ====> dnode not ready! - return -1 - endi -sql show dnodes -print ===> $rows $data00 $data01 $data02 $data03 $data04 $data05 -if $data00 != 1 then - return -1 -endi -if $data04 != ready then - goto check_dnode_ready -endi - print =============== insert duplicated records to memory - loop $reboot_max - $reboot_cnt sql use db sql insert into ct1 values ('2022-05-01 18:30:27.001', 0.0); diff --git a/tests/script/general/insert/insert_drop.sim b/tests/script/tsim/insert/insert_drop.sim similarity index 86% rename from tests/script/general/insert/insert_drop.sim rename to tests/script/tsim/insert/insert_drop.sim index 8592637626..020fd367ae 100644 --- a/tests/script/general/insert/insert_drop.sim +++ b/tests/script/tsim/insert/insert_drop.sim @@ -1,10 +1,6 @@ system sh/stop_dnodes.sh - system sh/deploy.sh -n dnode1 -i 1 -system sh/cfg.sh -n dnode1 -c walLevel -v 1 system sh/exec.sh -n dnode1 -s start - -sleep 2000 sql connect $tbNum = 10 @@ -19,7 +15,7 @@ $stb = stb sql drop database $db -x step1 step1: -sql create database $db ctime 30 +sql create database $db print ====== create tables sql use $db sql create table $stb (ts timestamp, c1 int) tags(t1 int) @@ -43,13 +39,9 @@ print ====== tables created print ================== restart server to commit data into disk system sh/exec.sh -n dnode1 -s stop -x SIGINT -sleep 3000 system sh/exec.sh -n dnode1 -s start print ================== server restart completed -sql reset query cache -sleep 1000 - sql use $db sql drop table tb5 $i = 0 @@ -69,13 +61,9 @@ endw print ================== restart server to commit data into disk system sh/exec.sh -n dnode1 -s stop -x SIGINT -sleep 3000 system sh/exec.sh -n dnode1 -s start print ================== server restart completed -sql reset query cache -sleep 1000 - sql use $db sql create table tb5 using $stb tags(5) diff --git a/tests/script/tsim/insert/null.sim b/tests/script/tsim/insert/null.sim index 98a494c960..1b7017038a 100644 --- a/tests/script/tsim/insert/null.sim +++ b/tests/script/tsim/insert/null.sim @@ -1,7 +1,6 @@ system sh/stop_dnodes.sh system sh/deploy.sh -n dnode1 -i 1 system sh/exec.sh -n dnode1 -s start -sleep 50 sql connect print =============== create database @@ -211,66 +210,48 @@ endi #=================================================================== #print =============== query data from stb -#sql select * from stb -#print ===> -#print ===> rows: $rows -#print ===> rows0: $data00 $data01 $data02 $data03 $data04 -#if $rows != 4 then -# return -1 -#endi +sql select * from stb +print ===> +print ===> rows: $rows +print ===> rows0: $data00 $data01 $data02 $data03 $data04 +if $rows != 12 then + return -1 +endi + #print =============== select count(*) from supter table -#sql select count(*) from stb -#print $data00 $data01 $data02 -#if $rows != 1 then -# return -1 -#endi -#if $data00 != 12 then -# return -1 -#endi +sql select count(*) from stb +print $data00 $data01 $data02 +if $rows != 1 then + return -1 +endi +if $data00 != 12 then + return -1 +endi #print =============== select count(column) from supter table -#sql select count(ts), count(c1), count(c2), count(c3) from stb -#print $data00 $data01 $data02 $data03 -#if $data00 != 12 then -# return -1 -#endi -#if $data01 != 8 then -# return -1 -#endi -#if $data02 != 8 then -# return -1 -#endi -#if $data03 != 8 then -# return -1 -#endi +sql select count(ts), count(c1), count(c2), count(c3) from stb +print $data00 $data01 $data02 $data03 +if $data00 != 12 then + return -1 +endi +if $data01 != 8 then + return -1 +endi +if $data02 != 8 then + return -1 +endi +if $data03 != 8 then + return -1 +endi -#=================================================================== #=================================================================== print =============== stop and restart taosd, then again do query above system sh/exec.sh -n dnode1 -s stop -x SIGINT system sh/exec.sh -n dnode1 -s start -print ===> waiting dnode ready -$loop_cnt = 0 -check_dnode_ready: - $loop_cnt = $loop_cnt + 1 - sleep 200 - if $loop_cnt == 10 then - print ====> dnode not ready! - return -1 - endi -sql show dnodes -print ===> $rows $data00 $data01 $data02 $data03 $data04 $data05 -if $data00 != 1 then - return -1 -endi -if $data04 != ready then - goto check_dnode_ready -endi - -#=================================================================== #=================================================================== + print =============== query data from child table sql select * from ct1 print ===> select * from ct1 @@ -292,15 +273,15 @@ endi if $data03 != 3.000000000 then return -1 endi -#if $data41 != -14 then -# return -1 -#endi -#if $data42 != -2.40000 then -# return -1 -#endi -#if $data43 != -3.400000000 then -# return -1 -#endi +if $data41 != 12 then + return -1 +endi +if $data42 != 2.20000 then + return -1 +endi +if $data43 != NULL then + return -1 +endi print =============== select count(*) from child table sql select count(*) from ct1 @@ -435,40 +416,39 @@ if $data92 != 3.600000000 then return -1 endi #=================================================================== -#=================================================================== -#print =============== query data from stb -#sql select * from stb -#print ===> -#print ===> rows: $rows -#print ===> rows0: $data00 $data01 $data02 $data03 $data04 -#if $rows != 4 then -# return -1 -#endi -#print =============== select count(*) from supter table -#sql select count(*) from stb -#print $data00 $data01 $data02 -#if $rows != 1 then -# return -1 -#endi -#if $data00 != 12 then -# return -1 -#endi +print =============== query data from stb +sql select * from stb +print ===> +print ===> rows: $rows +print ===> rows0: $data00 $data01 $data02 $data03 $data04 +if $rows != 12 then + return -1 +endi +print =============== select count(*) from supter table +sql select count(*) from stb +print $data00 $data01 $data02 +if $rows != 1 then + return -1 +endi +if $data00 != 12 then + return -1 +endi -#print =============== select count(column) from supter table -#sql select count(ts), count(c1), count(c2), count(c3) from stb -#print $data00 $data01 $data02 $data03 -#if $data00 != 12 then -# return -1 -#endi -#if $data01 != 8 then -# return -1 -#endi -#if $data02 != 8 then -# return -1 -#endi -#if $data03 != 8 then -# return -1 -#endi +print =============== select count(column) from supter table +sql select count(ts), count(c1), count(c2), count(c3) from stb +print $data00 $data01 $data02 $data03 +if $data00 != 12 then + return -1 +endi +if $data01 != 8 then + return -1 +endi +if $data02 != 8 then + return -1 +endi +if $data03 != 8 then + return -1 +endi system sh/exec.sh -n dnode1 -s stop -x SIGINT diff --git a/tests/script/general/insert/query_block1_file.sim b/tests/script/tsim/insert/query_block1_file.sim similarity index 96% rename from tests/script/general/insert/query_block1_file.sim rename to tests/script/tsim/insert/query_block1_file.sim index 636b9530f9..e4e8928bf8 100644 --- a/tests/script/general/insert/query_block1_file.sim +++ b/tests/script/tsim/insert/query_block1_file.sim @@ -1,11 +1,6 @@ system sh/stop_dnodes.sh - - system sh/deploy.sh -n dnode1 -i 1 -system sh/cfg.sh -n dnode1 -c walLevel -v 1 system sh/exec.sh -n dnode1 -s start - -sleep 2000 sql connect $i = 0 @@ -190,7 +185,7 @@ clear: sql drop database $db sql show databases -if $rows != 0 then +if $rows != 2 then return -1 endi diff --git a/tests/script/general/insert/query_block1_memory.sim b/tests/script/tsim/insert/query_block1_memory.sim similarity index 96% rename from tests/script/general/insert/query_block1_memory.sim rename to tests/script/tsim/insert/query_block1_memory.sim index 823e466ee9..a8e1a0439c 100644 --- a/tests/script/general/insert/query_block1_memory.sim +++ b/tests/script/tsim/insert/query_block1_memory.sim @@ -1,11 +1,6 @@ system sh/stop_dnodes.sh - - system sh/deploy.sh -n dnode1 -i 1 -system sh/cfg.sh -n dnode1 -c walLevel -v 1 system sh/exec.sh -n dnode1 -s start - -sleep 2000 sql connect $i = 0 @@ -175,7 +170,7 @@ clear: sql drop database $db sql show databases -if $rows != 0 then +if $rows != 2 then return -1 endi diff --git a/tests/script/general/insert/query_block2_file.sim b/tests/script/tsim/insert/query_block2_file.sim similarity index 93% rename from tests/script/general/insert/query_block2_file.sim rename to tests/script/tsim/insert/query_block2_file.sim index 5b7438875e..5557621e0f 100644 --- a/tests/script/general/insert/query_block2_file.sim +++ b/tests/script/tsim/insert/query_block2_file.sim @@ -1,11 +1,6 @@ system sh/stop_dnodes.sh - - system sh/deploy.sh -n dnode1 -i 1 -system sh/cfg.sh -n dnode1 -c walLevel -v 1 system sh/exec.sh -n dnode1 -s start - -sleep 2000 sql connect $i = 0 @@ -19,15 +14,7 @@ sql drop database -x step1 step1: sql create database $db sql use $db - -$x = 0 -create1: - $x = $x + 1 - sleep 1000 - if $x == 20 then - return -1 - endi -sql create table $tb (ts timestamp, speed int) -x create1 +sql create table $tb (ts timestamp, speed int) #commit to file will trigger if insert 82 rows $N = 82 @@ -204,7 +191,7 @@ clear: sql drop database $db sql show databases -if $rows != 0 then +if $rows != 2 then return -1 endi diff --git a/tests/script/general/insert/query_block2_memory.sim b/tests/script/tsim/insert/query_block2_memory.sim similarity index 96% rename from tests/script/general/insert/query_block2_memory.sim rename to tests/script/tsim/insert/query_block2_memory.sim index fb41981c89..910207d13b 100644 --- a/tests/script/general/insert/query_block2_memory.sim +++ b/tests/script/tsim/insert/query_block2_memory.sim @@ -1,11 +1,6 @@ system sh/stop_dnodes.sh - - system sh/deploy.sh -n dnode1 -i 1 -system sh/cfg.sh -n dnode1 -c walLevel -v 1 system sh/exec.sh -n dnode1 -s start - -sleep 2000 sql connect $i = 0 @@ -167,7 +162,7 @@ endi sql drop database $db sql show databases -if $rows != 0 then +if $rows != 2 then return -1 endi diff --git a/tests/script/general/insert/query_file_memory.sim b/tests/script/tsim/insert/query_file_memory.sim similarity index 93% rename from tests/script/general/insert/query_file_memory.sim rename to tests/script/tsim/insert/query_file_memory.sim index f920c215c0..c0aafd2686 100644 --- a/tests/script/general/insert/query_file_memory.sim +++ b/tests/script/tsim/insert/query_file_memory.sim @@ -1,11 +1,6 @@ system sh/stop_dnodes.sh - - system sh/deploy.sh -n dnode1 -i 1 -system sh/cfg.sh -n dnode1 -c walLevel -v 1 system sh/exec.sh -n dnode1 -s start - -sleep 2000 sql connect $i = 0 @@ -20,14 +15,7 @@ step1: sql create database $db sql use $db -$x = 0 -create1: - $x = $x + 1 - sleep 1000 - if $x == 20 then - return -1 - endi -sql create table $tb (ts timestamp, speed int) -x create1 +sql create table $tb (ts timestamp, speed int) #commit to file will trigger if insert 82 rows @@ -202,7 +190,7 @@ clear: sql drop database $db sql show databases -if $rows != 0 then +if $rows != 2 then return -1 endi diff --git a/tests/script/general/insert/query_multi_file.sim b/tests/script/tsim/insert/query_multi_file.sim similarity index 72% rename from tests/script/general/insert/query_multi_file.sim rename to tests/script/tsim/insert/query_multi_file.sim index bbca53d309..f996317721 100644 --- a/tests/script/general/insert/query_multi_file.sim +++ b/tests/script/tsim/insert/query_multi_file.sim @@ -1,11 +1,6 @@ system sh/stop_dnodes.sh - - system sh/deploy.sh -n dnode1 -i 1 -system sh/cfg.sh -n dnode1 -c walLevel -v 1 system sh/exec.sh -n dnode1 -s start - -sleep 2000 sql connect $i = 0 @@ -20,14 +15,7 @@ step1: sql create database $db sql use $db -$x = 0 -create1: - $x = $x + 1 - sleep 1000 - if $x == 20 then - return -1 - endi -sql create table $tb (ts timestamp, speed int) -x create1 +sql create table $tb (ts timestamp, speed int) $N = 20000 @@ -49,7 +37,7 @@ endi sql drop database $db sql show databases -if $rows != 0 then +if $rows != 2 then return -1 endi diff --git a/tests/script/general/insert/tcp.sim b/tests/script/tsim/insert/tcp.sim similarity index 84% rename from tests/script/general/insert/tcp.sim rename to tests/script/tsim/insert/tcp.sim index 002d84dcae..2dc720a0d4 100644 --- a/tests/script/general/insert/tcp.sim +++ b/tests/script/tsim/insert/tcp.sim @@ -1,10 +1,7 @@ system sh/stop_dnodes.sh - system sh/deploy.sh -n dnode1 -i 1 -system sh/cfg.sh -n dnode1 -c walLevel -v 1 +system sh/cfg.sh -n dnode1 -c debugflag -v 131 system sh/exec.sh -n dnode1 -s start - -sleep 2000 sql connect sql create database d1; -- GitLab From 869f2729707b64404f3a915fad367eb4f6dfd321 Mon Sep 17 00:00:00 2001 From: plum-lihui Date: Thu, 14 Jul 2022 15:05:39 +0800 Subject: [PATCH 116/153] test: modify case --- tests/system-test/7-tmq/dataFromTsdbNWal.py | 19 +++++++++---------- tests/system-test/7-tmq/tmqCommon.py | 1 + 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/tests/system-test/7-tmq/dataFromTsdbNWal.py b/tests/system-test/7-tmq/dataFromTsdbNWal.py index a55fbbfd18..227ce9d5a5 100644 --- a/tests/system-test/7-tmq/dataFromTsdbNWal.py +++ b/tests/system-test/7-tmq/dataFromTsdbNWal.py @@ -38,9 +38,9 @@ class TDTestCase: 'tagSchema': [{'type': 'INT', 'count':1},{'type': 'BIGINT', 'count':1},{'type': 'DOUBLE', 'count':1},{'type': 'BINARY', 'len':32, 'count':1},{'type': 'NCHAR', 'len':32, 'count':1}], 'ctbPrefix': 'ctb', 'ctbStartIdx': 0, - 'ctbNum': 10, + 'ctbNum': 100, 'rowsPerTbl': 10000, - 'batchNum': 1000, + 'batchNum': 3000, 'startTs': 1640966400000, # 2022-01-01 00:00:00.000 'pollDelay': 10, 'showMsg': 1, @@ -64,9 +64,7 @@ class TDTestCase: ctbNum=paraDict["ctbNum"],rowsPerTbl=paraDict["rowsPerTbl"],batchNum=paraDict["batchNum"], startTs=paraDict["startTs"],ctbStartIdx=paraDict['ctbStartIdx']) - tdLog.info("restart taosd to ensure that the data falls into the disk") - # tdDnodes.stop(1) - # tdDnodes.start(1) + tdLog.info("flush db to let data falls into the disk") tdSql.query("flush database %s"%(paraDict['dbName'])) return @@ -85,7 +83,7 @@ class TDTestCase: 'ctbStartIdx': 0, 'ctbNum': 10, 'rowsPerTbl': 10000, - 'batchNum': 10, + 'batchNum': 100, 'startTs': 1640966400000, # 2022-01-01 00:00:00.000 'pollDelay': 3, 'showMsg': 1, @@ -95,8 +93,6 @@ class TDTestCase: paraDict['vgroups'] = self.vgroups paraDict['ctbNum'] = self.ctbNum paraDict['rowsPerTbl'] = self.rowsPerTbl - paraDict['batchNum'] = 100 - paraDict['startTs'] = paraDict['startTs'] + self.rowsPerTbl topicNameList = ['topic1'] expectRowsList = [] @@ -125,6 +121,8 @@ class TDTestCase: tmqCom.startTmqSimProcess(pollDelay=paraDict['pollDelay'],dbName=paraDict["dbName"],showMsg=paraDict['showMsg'], showRow=paraDict['showRow'],snapshot=paraDict['snapshot']) # after start consume, continue insert some data + paraDict['batchNum'] = 100 + paraDict['startTs'] = paraDict['startTs'] + self.rowsPerTbl tmqCom.insert_data_interlaceByMultiTbl(tsql=tdSql,dbName=paraDict["dbName"],ctbPrefix=paraDict["ctbPrefix"], ctbNum=paraDict["ctbNum"],rowsPerTbl=paraDict["rowsPerTbl"],batchNum=paraDict["batchNum"], startTs=paraDict["startTs"],ctbStartIdx=paraDict['ctbStartIdx']) @@ -137,11 +135,12 @@ class TDTestCase: expectRows = 1 resultList = tmqCom.selectConsumeResult(expectRows) + + tdLog.info("expect consume rows: %d, act consume rows: %d"%(expectRowsList[0], resultList[0])) if expectRowsList[0] != resultList[0]: - tdLog.info("expect consume rows: %d, act consume rows: %d"%(expectRowsList[0], resultList[0])) tdLog.exit("%d tmq consume rows error!"%consumerId) - tmqCom.checkFileContent(consumerId, queryString) + tmqCom.checkFileContent(consumerId, queryString) time.sleep(10) for i in range(len(topicNameList)): diff --git a/tests/system-test/7-tmq/tmqCommon.py b/tests/system-test/7-tmq/tmqCommon.py index 98c9e37132..060e17c11f 100644 --- a/tests/system-test/7-tmq/tmqCommon.py +++ b/tests/system-test/7-tmq/tmqCommon.py @@ -444,6 +444,7 @@ class TMQCom: # skip first line for it is schema queryFile.readline() + lines = 0 while True: dst = queryFile.readline() -- GitLab From 7d1c2fdbe5e68dba9fa5567f1f0105862624d6b8 Mon Sep 17 00:00:00 2001 From: Shengliang Guan Date: Thu, 14 Jul 2022 15:16:09 +0800 Subject: [PATCH 117/153] test: restore some 2.0 case --- tests/script/jenkins/basic.txt | 24 ++++---- tests/script/tsim/compute/avg.sim | 18 +++--- tests/script/tsim/compute/bottom.sim | 26 ++++----- tests/script/tsim/compute/count.sim | 29 +++++----- tests/script/tsim/compute/diff.sim | 16 +++--- tests/script/tsim/compute/diff2.sim | 70 +++++++++++------------ tests/script/tsim/compute/first.sim | 28 +++++---- tests/script/tsim/compute/interval.sim | 32 +++++------ tests/script/tsim/compute/last.sim | 26 ++++----- tests/script/tsim/compute/last_row.sim | 5 +- tests/script/tsim/compute/leastsquare.sim | 14 ++--- tests/script/tsim/compute/max.sim | 28 +++++---- tests/script/tsim/compute/null.sim | 7 ++- 13 files changed, 155 insertions(+), 168 deletions(-) diff --git a/tests/script/jenkins/basic.txt b/tests/script/jenkins/basic.txt index f1264f3cb4..1e3be5924b 100644 --- a/tests/script/jenkins/basic.txt +++ b/tests/script/jenkins/basic.txt @@ -236,23 +236,23 @@ ./test.sh -f tsim/compress/uncompress.sim # ---- compute -#./test.sh -f tsim/compute/avg.sim +./test.sh -f tsim/compute/avg.sim #./test.sh -f tsim/compute/block_dist.sim -#./test.sh -f tsim/compute/bottom.sim -#./test.sh -f tsim/compute/count.sim -#./test.sh -f tsim/compute/diff.sim -#./test.sh -f tsim/compute/diff2.sim -#./test.sh -f tsim/compute/first.sim -#./test.sh -f tsim/compute/interval.sim +./test.sh -f tsim/compute/bottom.sim +./test.sh -f tsim/compute/count.sim +./test.sh -f tsim/compute/diff.sim +./test.sh -f tsim/compute/diff2.sim +./test.sh -f tsim/compute/first.sim +./test.sh -f tsim/compute/interval.sim #./test.sh -f tsim/compute/last_row.sim -#./test.sh -f tsim/compute/last.sim -#./test.sh -f tsim/compute/leastsquare.sim -#./test.sh -f tsim/compute/max.sim -#./test.sh -f tsim/compute/min.sim +./test.sh -f tsim/compute/last.sim +./test.sh -f tsim/compute/leastsquare.sim +./test.sh -f tsim/compute/max.sim +./test.sh -f tsim/compute/min.sim #./test.sh -f tsim/compute/null.sim ./test.sh -f tsim/compute/percentile.sim ./test.sh -f tsim/compute/stddev.sim -#./test.sh -f tsim/compute/sum.sim +./test.sh -f tsim/compute/sum.sim ./test.sh -f tsim/compute/top.sim # ---- field diff --git a/tests/script/tsim/compute/avg.sim b/tests/script/tsim/compute/avg.sim index 2805b65fff..50a0aeffb0 100644 --- a/tests/script/tsim/compute/avg.sim +++ b/tests/script/tsim/compute/avg.sim @@ -69,13 +69,13 @@ endi print =============== step5 sql select avg(tbcol) as b from $tb interval(1m) print ===> $data01 -if $data11 != 1.000000000 then +if $data10 != 1.000000000 then return -1 endi sql select avg(tbcol) as b from $tb interval(1d) print ===> $data01 -if $data01 != 9.500000000 then +if $data00 != 9.500000000 then return -1 endi @@ -84,7 +84,7 @@ $cc = 4 * 60000 $ms = 1601481600000 + $cc sql select avg(tbcol) as b from $tb where ts <= $ms interval(1m) print ===> $data01 -if $data41 != 4.000000000 then +if $data40 != 4.000000000 then return -1 endi if $rows != 5 then @@ -123,14 +123,14 @@ endi print =============== step9 sql select avg(tbcol) as b from $mt interval(1m) -print ===> $data11 -if $data11 != 1.000000000 then +print ===> $data10 +if $data10 != 1.000000000 then return -1 endi sql select avg(tbcol) as b from $mt interval(1d) print ===> $data01 -if $data01 != 9.500000000 then +if $data00 != 9.500000000 then return -1 endi @@ -148,9 +148,9 @@ endi print =============== step11 $cc = 4 * 60000 $ms = 1601481600000 + $cc -sql select avg(tbcol) as b from $mt where ts <= $ms interval(1m) group by tgcol -print ===> $data11 -if $data11 != 1.000000000 then +sql select avg(tbcol) as b from $mt where ts <= $ms partition by tgcol interval(1m) +print ===> $data10 +if $data10 != 1.000000000 then return -1 endi if $rows != 50 then diff --git a/tests/script/tsim/compute/bottom.sim b/tests/script/tsim/compute/bottom.sim index cfac02d6d5..a17584734b 100644 --- a/tests/script/tsim/compute/bottom.sim +++ b/tests/script/tsim/compute/bottom.sim @@ -38,15 +38,13 @@ while $i < $tbNum $i = $i + 1 endw -sleep 100 - print =============== step2 $i = 1 $tb = $tbPrefix . $i sql select bottom(tbcol, 1) from $tb -print ===> $data01 -if $data01 != 0 then +print ===> $data00 +if $data00 != 0 then return -1 endi @@ -54,25 +52,25 @@ print =============== step3 $cc = 4 * 60000 $ms = 1601481600000 + $cc sql select bottom(tbcol, 1) from $tb where ts > $ms -print ===> $data01 -if $data01 != 5 then +print ===> $data00 +if $data00 != 5 then return -1 endi print =============== step4 sql select bottom(tbcol, 1) as b from $tb -print ===> $data01 -if $data01 != 0 then +print ===> $data00 +if $data00 != 0 then return -1 endi print =============== step5 sql select bottom(tbcol, 2) as b from $tb -print ===> $data01 $data11 -if $data01 != 0 then +print ===> $data00 $data10 +if $data00 != 1 then return -1 endi -if $data11 != 1 then +if $data10 != 0 then return -1 endi @@ -80,11 +78,11 @@ print =============== step6 $cc = 4 * 60000 $ms = 1601481600000 + $cc sql select bottom(tbcol, 2) as b from $tb where ts > $ms -print ===> $data01 $data11 -if $data01 != 5 then +print ===> $data00 $data10 +if $data00 != 6 then return -1 endi -if $data11 != 6 then +if $data10 != 5 then return -1 endi diff --git a/tests/script/tsim/compute/count.sim b/tests/script/tsim/compute/count.sim index 0a6ce93077..cf2ad933bc 100644 --- a/tests/script/tsim/compute/count.sim +++ b/tests/script/tsim/compute/count.sim @@ -38,13 +38,10 @@ while $i < $tbNum $i = $i + 1 endw -sleep 100 - print =============== step2 $i = 1 $tb = $tbPrefix . $i - sql select count(*) from $tb print ===> select count(*) from $tb => $data00 if $data00 != $rowNum then @@ -81,14 +78,14 @@ endi print =============== step5 sql select count(tbcol) as b from $tb interval(1m) -print ===> $data01 -if $data01 != 1 then +print ===> $data00 +if $data00 != 1 then return -1 endi sql select count(tbcol) as b from $tb interval(1d) -print ===> $data01 -if $data01 != $rowNum then +print ===> $data00 +if $data00 != $rowNum then return -1 endi @@ -96,8 +93,8 @@ print =============== step6 $cc = 4 * 60000 $ms = 1601481600000 + $cc sql select count(tbcol) as b from $tb where ts <= $ms interval(1m) -print ===> $data01 -if $data01 != 1 then +print ===> $data00 +if $data00 != 1 then return -1 endi if $rows != 5 then @@ -149,17 +146,17 @@ endi print =============== step9 sql select count(tbcol) as b from $mt interval(1m) -print ===> $data01 -if $data01 != 10 then +print ===> $data00 +if $data00 != 10 then return -1 endi -if $data11 != 10 then +if $data10 != 10 then return -1 endi sql select count(tbcol) as b from $mt interval(1d) -print ===> $data01 -if $data01 != 200 then +print ===> $data00 +if $data00 != 200 then return -1 endi @@ -177,9 +174,9 @@ endi print =============== step11 $cc = 4 * 60000 $ms = 1601481600000 + $cc -sql select count(tbcol) as b from $mt where ts <= $ms interval(1m) group by tgcol +sql select count(tbcol) as b from $mt where ts <= $ms partition by tgcol interval(1m) print ===> $data01 -if $data01 != 1 then +if $data00 != 1 then return -1 endi if $rows != 50 then diff --git a/tests/script/tsim/compute/diff.sim b/tests/script/tsim/compute/diff.sim index ba4b32ddbb..f11fc92b2b 100644 --- a/tests/script/tsim/compute/diff.sim +++ b/tests/script/tsim/compute/diff.sim @@ -44,8 +44,8 @@ $i = 1 $tb = $tbPrefix . $i sql select diff(tbcol) from $tb -print ===> $data11 -if $data11 != 1 then +print ===> $data10 +if $data10 != 1 then return -1 endi @@ -53,23 +53,23 @@ print =============== step3 $cc = 4 * 60000 $ms = 1601481600000 + $cc sql select diff(tbcol) from $tb where ts > $ms -print ===> $data11 -if $data11 != 1 then +print ===> $data10 +if $data10 != 1 then return -1 endi $cc = 4 * 60000 $ms = 1601481600000 + $cc sql select diff(tbcol) from $tb where ts <= $ms -print ===> $data11 -if $data11 != 1 then +print ===> $data10 +if $data10 != 1 then return -1 endi print =============== step4 sql select diff(tbcol) as b from $tb -print ===> $data11 -if $data11 != 1 then +print ===> $data10 +if $data10 != 1 then return -1 endi diff --git a/tests/script/tsim/compute/diff2.sim b/tests/script/tsim/compute/diff2.sim index 08b52cb37b..021fcf6e8b 100644 --- a/tests/script/tsim/compute/diff2.sim +++ b/tests/script/tsim/compute/diff2.sim @@ -1,5 +1,6 @@ system sh/stop_dnodes.sh system sh/deploy.sh -n dnode1 -i 1 +system sh/cfg.sh -n dnode1 -c debugflag -v 131 system sh/exec.sh -n dnode1 -s start sql connect @@ -39,91 +40,90 @@ while $i < $tbNum $i = $i + 1 endw -sleep 100 - print =============== step2 $i = 1 $tb = $tbPrefix . $i sql select diff(c1) from $tb -print ===> $data11 -if $data11 != 1 then +print ===> $data10 +if $data10 != 1 then return -1 endi sql select diff(c2) from $tb -print ===> $data11 -if $data11 != 1.00000 then +print ===> $data10 +if $data10 != 1.000000000 then return -1 endi sql select diff(c3) from $tb -print ===> $data11 -if $data11 != 1 then +print ===> $data10 +if $data10 != 1 then return -1 endi sql select diff(c4) from $tb -print ===> $data11 -if $data11 != 1 then +print ===> $data10 +if $data10 != 1 then return -1 endi sql select diff(c5) from $tb -print ===> $data11 -if $data11 != 0 then +print ===> $data10 +if $data10 != 0 then return -1 endi sql select diff(c6) from $tb -print ===> $data11 -if $data11 != 1.000000000 then +print ===> $data10 +if $data10 != 1.000000000 then return -1 endi -sql_error select diff(c7) from $tb + +sql select diff(c7) from $tb sql_error select diff(c8) from $tb sql_error select diff(c9) from $tb sql_error select diff(ts) from $tb sql_error select diff(c1), diff(c2) from $tb -#sql_error select 2+diff(c1) from $tb -sql_error select diff(c1+2) from $tb + +sql select 2+diff(c1) from $tb +sql select diff(c1+2) from $tb sql_error select diff(c1) from $tb where ts > 0 and ts < now + 100m interval(10m) -sql_error select diff(c1) from $mt +sql select diff(c1) from $mt sql_error select diff(diff(c1)) from $tb sql_error select diff(c1) from m_di_tb1 where c2 like '2%' - print =============== step3 sql select diff(c1) from $tb where c1 > 5 -print ===> $data11 -if $data11 != 1 then +print ===> $data10 +if $data10 != 1 then return -1 endi sql select diff(c2) from $tb where c2 > 5 -print ===> $data11 -if $data11 != 1.00000 then +print ===> $data10 +if $data10 != 1.000000000 then return -1 endi sql select diff(c3) from $tb where c3 > 5 -print ===> $data11 -if $data11 != 1 then +print ===> $data10 +if $data10 != 1 then return -1 endi sql select diff(c4) from $tb where c4 > 5 -print ===> $data11 -if $data11 != 1 then +print ===> $data10 +if $data10 != 1 then return -1 endi sql select diff(c5) from $tb where c5 > 5 -print ===> $data11 -if $data11 != 0 then +print ===> $data10 +if $data10 != 0 then return -1 endi sql select diff(c6) from $tb where c6 > 5 -print ===> $data11 -if $data11 != 1.000000000 then +print ===> $data10 +if $data10 != 1.000000000 then return -1 endi print =============== step4 sql select diff(c1) from $tb where c1 > 5 and c2 < $rowNum -print ===> $data11 -if $data11 != 1 then +print ===> $data10 +if $data10 != 1 then return -1 endi @@ -131,8 +131,8 @@ sql select diff(c1) from $tb where c9 like '%9' and c1 <= 20 if $rows != 1 then return -1 endi -print ===> $data11 -if $data01 != 10 then +print ===> $data10 +if $data00 != 10 then return -1 endi diff --git a/tests/script/tsim/compute/first.sim b/tests/script/tsim/compute/first.sim index cf1160dbdb..f8efeee513 100644 --- a/tests/script/tsim/compute/first.sim +++ b/tests/script/tsim/compute/first.sim @@ -38,8 +38,6 @@ while $i < $tbNum $i = $i + 1 endw -sleep 100 - print =============== step2 $i = 1 $tb = $tbPrefix . $i @@ -68,14 +66,14 @@ endi print =============== step5 sql select first(tbcol) as b from $tb interval(1m) -print ===> $data01 -if $data01 != 0 then +print ===> $data00 +if $data00 != 0 then return -1 endi sql select first(tbcol) as b from $tb interval(1d) -print ===> $data01 -if $data01 != 0 then +print ===> $data00 +if $data00 != 0 then return -1 endi @@ -83,8 +81,8 @@ print =============== step6 $cc = 4 * 60000 $ms = 1601481600000 + $cc sql select first(tbcol) as b from $tb where ts <= $ms interval(1m) -print ===> $data01 -if $data41 != 4 then +print ===> $data00 +if $data40 != 4 then return -1 endi if $rows != 5 then @@ -124,14 +122,14 @@ endi print =============== step9 sql select first(tbcol) as b from $mt interval(1m) print select first(tbcol) as b from $mt interval(1m) -print ===> $data11 -if $data11 != 1 then +print ===> $data10 +if $data10 != 1 then return -1 endi sql select first(tbcol) as b from $mt interval(1d) -print ===> $data01 -if $data01 != 0 then +print ===> $data00 +if $data00 != 0 then return -1 endi @@ -149,9 +147,9 @@ endi print =============== step11 $cc = 4 * 60000 $ms = 1601481600000 + $cc -sql select first(tbcol) as b from $mt where ts <= $ms interval(1m) group by tgcol -print ===> $data11 -if $data11 != 1 then +sql select first(tbcol) as b from $mt where ts <= $ms partition by tgcol interval(1m) +print ===> $data10 +if $data10 != 1 then return -1 endi print ===> $rows diff --git a/tests/script/tsim/compute/interval.sim b/tests/script/tsim/compute/interval.sim index a8539701c7..2e38990975 100644 --- a/tests/script/tsim/compute/interval.sim +++ b/tests/script/tsim/compute/interval.sim @@ -47,10 +47,10 @@ print ===> $rows if $rows < $rowNum then return -1 endi -if $data01 != 1 then +if $data00 != 1 then return -1 endi -if $data05 != 1 then +if $data04 != 1 then return -1 endi @@ -65,10 +65,10 @@ endi if $rows < 3 then return -1 endi -if $data01 != 1 then +if $data00 != 1 then return -1 endi -if $data05 != 1 then +if $data04 != 1 then return -1 endi @@ -87,10 +87,10 @@ endi if $rows > 22 then return -1 endi -if $data01 != 1 then +if $data00 != 1 then return -1 endi -if $data05 != 1 then +if $data04 != 1 then return -1 endi @@ -109,10 +109,10 @@ endi if $rows > 50 then return -1 endi -if $data21 != 1 then +if $data20 != 1 then return -1 endi -if $data25 != 1 then +if $data24 != 1 then return -1 endi @@ -125,10 +125,10 @@ endi if $rows > 22 then return -1 endi -if $data11 > 15 then +if $data10 > 15 then return -1 endi -if $data11 < 5 then +if $data10 < 5 then return -1 endi @@ -143,10 +143,10 @@ endi if $rows > 7 then return -1 endi -if $data11 > 15 then +if $data10 > 15 then return -1 endi -if $data11 < 5 then +if $data10 < 5 then return -1 endi @@ -165,10 +165,10 @@ endi if $rows > 22 then return -1 endi -if $data11 > 15 then +if $data10 > 15 then return -1 endi -if $data11 < 5 then +if $data10 < 5 then return -1 endi @@ -186,10 +186,10 @@ endi if $rows > 50 then return -1 endi -if $data11 > 15 then +if $data10 > 15 then return -1 endi -if $data11 < 5 then +if $data10 < 5 then return -1 endi diff --git a/tests/script/tsim/compute/last.sim b/tests/script/tsim/compute/last.sim index aa9b041ca9..ae6f016b08 100644 --- a/tests/script/tsim/compute/last.sim +++ b/tests/script/tsim/compute/last.sim @@ -69,14 +69,14 @@ endi print =============== step5 sql select last(tbcol) as b from $tb interval(1m) -print ===> $data11 -if $data11 != 1 then +print ===> $data10 +if $data10 != 1 then return -1 endi sql select last(tbcol) as b from $tb interval(1d) -print ===> $data01 -if $data01 != 19 then +print ===> $data00 +if $data00 != 19 then return -1 endi @@ -85,8 +85,8 @@ $cc = 4 * 60000 $ms = 1601481600000 + $cc sql select last(tbcol) as b from $tb where ts <= $ms interval(1m) -print ===> $data11 -if $data11 != 1 then +print ===> $data10 +if $data10 != 1 then return -1 endi if $rows != 5 then @@ -127,14 +127,14 @@ endi print =============== step9 sql select last(tbcol) as b from $mt interval(1m) -print ===> $data11 -if $data11 != 1 then +print ===> $data10 +if $data10 != 1 then return -1 endi sql select last(tbcol) as b from $mt interval(1d) -print ===> $data01 -if $data01 != 19 then +print ===> $data00 +if $data00 != 19 then return -1 endi @@ -153,9 +153,9 @@ print =============== step11 $cc = 4 * 60000 $ms = 1601481600000 + $cc -sql select last(tbcol) as b from $mt where ts <= $ms interval(1m) group by tgcol -print ===> $data11 -if $data11 != 1 then +sql select last(tbcol) as b from $mt where ts <= $ms partition by tgcol interval(1m) +print ===> $data10 +if $data10 != 1 then return -1 endi print ===> $rows diff --git a/tests/script/tsim/compute/last_row.sim b/tests/script/tsim/compute/last_row.sim index 867f64fa2e..590fada86a 100644 --- a/tests/script/tsim/compute/last_row.sim +++ b/tests/script/tsim/compute/last_row.sim @@ -38,8 +38,6 @@ while $i < $tbNum $i = $i + 1 endw -sleep 100 - print =============== step2 $i = 1 $tb = $tbPrefix . $i @@ -53,6 +51,7 @@ endi print =============== step3 $cc = 4 * 60000 $ms = 1601481600000 + $cc +print select last_row(tbcol) from $tb where ts <= $ms sql select last_row(tbcol) from $tb where ts <= $ms print ===> $data00 if $data00 != 4 then @@ -98,8 +97,6 @@ if $data00 != 4 then return -1 endi - - print =============== step10 sql select last_row(tbcol) as b from $mt group by tgcol print ===> $data00 diff --git a/tests/script/tsim/compute/leastsquare.sim b/tests/script/tsim/compute/leastsquare.sim index aa83a4e14e..59a5213620 100644 --- a/tests/script/tsim/compute/leastsquare.sim +++ b/tests/script/tsim/compute/leastsquare.sim @@ -37,8 +37,6 @@ while $i < $tbNum $i = $i + 1 endw -sleep 100 - print =============== step2 $i = 1 $tb = $tbPrefix . $i @@ -65,21 +63,21 @@ endi print =============== step5 sql select leastsquares(tbcol, 1, 1) as b from $tb interval(1m) -print ===> $data01 -if $data01 != @{slop:1.000000, intercept:1.000000}@ then +print ===> $data00 +if $data00 != @{slop:1.000000, intercept:1.000000}@ then return -1 endi sql select leastsquares(tbcol, 1, 1) as b from $tb interval(1d) -print ===> $data01 -if $data01 != @{slop:1.000000, intercept:1.000000}@ then +print ===> $data00 +if $data00 != @{slop:1.000000, intercept:1.000000}@ then return -1 endi print =============== step6 sql select leastsquares(tbcol, 1, 1) as b from $tb where ts < now + 4m interval(1m) -print ===> $data01 -if $data01 != @{slop:1.000000, intercept:1.000000}@ then +print ===> $data00 +if $data00 != @{slop:1.000000, intercept:1.000000}@ then return -1 endi print ===> $rows diff --git a/tests/script/tsim/compute/max.sim b/tests/script/tsim/compute/max.sim index 1b3fac5820..7101359026 100644 --- a/tests/script/tsim/compute/max.sim +++ b/tests/script/tsim/compute/max.sim @@ -38,8 +38,6 @@ while $i < $tbNum $i = $i + 1 endw -sleep 100 - print =============== step2 $i = 1 $tb = $tbPrefix . $i @@ -69,14 +67,14 @@ endi print =============== step5 sql select max(tbcol) as b from $tb interval(1m) -print ===> $data11 -if $data11 != 1 then +print ===> $data10 +if $data10 != 1 then return -1 endi sql select max(tbcol) as b from $tb interval(1d) -print ===> $data01 -if $data01 != 19 then +print ===> $data00 +if $data00 != 19 then return -1 endi @@ -85,8 +83,8 @@ $cc = 4 * 60000 $ms = 1601481600000 + $cc sql select max(tbcol) as b from $tb where ts <= $ms interval(1m) -print ===> $data11 -if $data11 != 1 then +print ===> $data10 +if $data10 != 1 then return -1 endi if $rows != 5 then @@ -127,14 +125,14 @@ endi print =============== step9 sql select max(tbcol) as b from $mt interval(1m) -print ===> $data11 -if $data11 != 1 then +print ===> $data10 +if $data10 != 1 then return -1 endi sql select max(tbcol) as b from $mt interval(1d) -print ===> $data01 -if $data01 != 19 then +print ===> $data00 +if $data00 != 19 then return -1 endi @@ -153,9 +151,9 @@ print =============== step11 $cc = 4 * 60000 $ms = 1601481600000 + $cc -sql select max(tbcol) as b from $mt where ts <= $ms interval(1m) group by tgcol -print ===> $data11 -if $data11 != 1 then +sql select max(tbcol) as b from $mt where ts <= $ms partition by tgcol interval(1m) +print ===> $data10 +if $data10 != 1 then return -1 endi print ===> $rows diff --git a/tests/script/tsim/compute/null.sim b/tests/script/tsim/compute/null.sim index 30860da48b..b5647a1e34 100644 --- a/tests/script/tsim/compute/null.sim +++ b/tests/script/tsim/compute/null.sim @@ -100,9 +100,10 @@ if $rows != 1 then return -1 endi -sql_error select * from $tb where tbcol = NULL - -return +sql select * from $tb where tbcol = NULL +if $rows != 0 then + return -1 +endi print =============== step5 sql create table tt using $mt tags( NULL ) -- GitLab From 9b5f662275a28e9b05c1d19e0d767492cde3b72c Mon Sep 17 00:00:00 2001 From: Shengliang Guan Date: Thu, 14 Jul 2022 15:16:18 +0800 Subject: [PATCH 118/153] test: restore some 2.0 case --- tests/script/tsim/cache/new_metrics.sim | 4 ---- tests/script/tsim/cache/restart_metrics.sim | 2 -- tests/script/tsim/cache/restart_table.sim | 2 -- tests/script/tsim/compress/commitlog.sim | 10 +--------- tests/script/tsim/compute/avg.sim | 2 -- tests/script/tsim/compute/block_dist.sim | 2 -- tests/script/tsim/compute/diff.sim | 2 -- tests/script/tsim/compute/last.sim | 2 -- tests/script/tsim/compute/min.sim | 2 -- tests/script/tsim/compute/percentile.sim | 2 -- tests/script/tsim/compute/stddev.sim | 2 -- tests/script/tsim/compute/sum.sim | 2 -- tests/script/tsim/compute/top.sim | 2 -- tests/script/tsim/tag/bigint.sim | 1 - tests/script/tsim/tag/binary.sim | 1 - tests/script/tsim/tag/bool.sim | 1 - tests/script/tsim/tag/double.sim | 1 - tests/script/tsim/tag/float.sim | 1 - tests/script/tsim/tag/int.sim | 1 - tests/script/tsim/tag/smallint.sim | 1 - tests/script/tsim/tag/tinyint.sim | 1 - tests/script/tsim/vector/metrics_field.sim | 2 -- tests/script/tsim/vector/metrics_mix.sim | 2 -- tests/script/tsim/vector/metrics_query.sim | 2 -- tests/script/tsim/vector/metrics_tag.sim | 2 -- tests/script/tsim/vector/metrics_time.sim | 2 -- tests/script/tsim/vector/multi.sim | 2 -- tests/script/tsim/vector/single.sim | 2 -- tests/script/tsim/vector/table_field.sim | 2 -- tests/script/tsim/vector/table_mix.sim | 2 -- tests/script/tsim/vector/table_query.sim | 2 -- tests/script/tsim/vector/table_time.sim | 2 -- 32 files changed, 1 insertion(+), 65 deletions(-) diff --git a/tests/script/tsim/cache/new_metrics.sim b/tests/script/tsim/cache/new_metrics.sim index af7db90070..82d7d43e0f 100644 --- a/tests/script/tsim/cache/new_metrics.sim +++ b/tests/script/tsim/cache/new_metrics.sim @@ -83,10 +83,6 @@ while $i < 10 $i = $i + 1 endw -print ==> sleep 1 seconds to renew cache -sql reset query cache -sleep 1000 - print =============== step5 sql select * from $tb order by ts desc print ===>rows $rows, data $data01 diff --git a/tests/script/tsim/cache/restart_metrics.sim b/tests/script/tsim/cache/restart_metrics.sim index e144a49bf7..e346357633 100644 --- a/tests/script/tsim/cache/restart_metrics.sim +++ b/tests/script/tsim/cache/restart_metrics.sim @@ -48,9 +48,7 @@ system sh/deploy.sh -n dnode1 -i 1 system sh/exec.sh -n dnode1 -s start print =============== step3 -print ==> sleep 1 seconds to renew cache sql reset query cache -sleep 1000 print =============== step4 sql create database $db diff --git a/tests/script/tsim/cache/restart_table.sim b/tests/script/tsim/cache/restart_table.sim index b450f6c654..d28ef51419 100644 --- a/tests/script/tsim/cache/restart_table.sim +++ b/tests/script/tsim/cache/restart_table.sim @@ -32,9 +32,7 @@ system sh/deploy.sh -n dnode1 -i 1 system sh/exec.sh -n dnode1 -s start print =============== step3 -print ==> sleep 1 seconds to renew cache sql reset query cache -sleep 1000 print =============== step4 sql create database $db diff --git a/tests/script/tsim/compress/commitlog.sim b/tests/script/tsim/compress/commitlog.sim index d90780bd6c..bc9c231a9e 100644 --- a/tests/script/tsim/compress/commitlog.sim +++ b/tests/script/tsim/compress/commitlog.sim @@ -57,15 +57,7 @@ $tb = $tbPrefix . $i sql create database $db sql use $db - -$x = 0 -step3: - $x = $x + 1 - sleep 1000 - if $x == 20 then - return -1 - endi -sql create table $tb (ts timestamp, b bool, t tinyint, s smallint, i int, big bigint, f float, d double, str binary(256)) -x step3 +sql create table $tb (ts timestamp, b bool, t tinyint, s smallint, i int, big bigint, f float, d double, str binary(256)) $count = 0 while $count < $N diff --git a/tests/script/tsim/compute/avg.sim b/tests/script/tsim/compute/avg.sim index 50a0aeffb0..c366de5f4c 100644 --- a/tests/script/tsim/compute/avg.sim +++ b/tests/script/tsim/compute/avg.sim @@ -38,8 +38,6 @@ while $i < $tbNum $i = $i + 1 endw -sleep 100 - print =============== step2 $i = 1 $tb = $tbPrefix . $i diff --git a/tests/script/tsim/compute/block_dist.sim b/tests/script/tsim/compute/block_dist.sim index 201d222af7..1583e838c6 100644 --- a/tests/script/tsim/compute/block_dist.sim +++ b/tests/script/tsim/compute/block_dist.sim @@ -47,8 +47,6 @@ while $x < $rowNum $x = $x + 1 endw -sleep 100 - print =============== step2 $i = 0 $tb = $tbPrefix . $i diff --git a/tests/script/tsim/compute/diff.sim b/tests/script/tsim/compute/diff.sim index f11fc92b2b..6043f18b27 100644 --- a/tests/script/tsim/compute/diff.sim +++ b/tests/script/tsim/compute/diff.sim @@ -37,8 +37,6 @@ while $i < $tbNum $i = $i + 1 endw -sleep 100 - print =============== step2 $i = 1 $tb = $tbPrefix . $i diff --git a/tests/script/tsim/compute/last.sim b/tests/script/tsim/compute/last.sim index ae6f016b08..6080a2fa97 100644 --- a/tests/script/tsim/compute/last.sim +++ b/tests/script/tsim/compute/last.sim @@ -38,8 +38,6 @@ while $i < $tbNum $i = $i + 1 endw -sleep 100 - print =============== step2 $i = 1 $tb = $tbPrefix . $i diff --git a/tests/script/tsim/compute/min.sim b/tests/script/tsim/compute/min.sim index 33e9eb0f3e..1ffdf19ac2 100644 --- a/tests/script/tsim/compute/min.sim +++ b/tests/script/tsim/compute/min.sim @@ -38,8 +38,6 @@ while $i < $tbNum $i = $i + 1 endw -sleep 100 - print =============== step2 $i = 1 $tb = $tbPrefix . $i diff --git a/tests/script/tsim/compute/percentile.sim b/tests/script/tsim/compute/percentile.sim index 5cba3ad856..93b4640442 100644 --- a/tests/script/tsim/compute/percentile.sim +++ b/tests/script/tsim/compute/percentile.sim @@ -38,8 +38,6 @@ while $i < $tbNum $i = $i + 1 endw -sleep 100 - print =============== step2 $i = 1 $tb = $tbPrefix . $i diff --git a/tests/script/tsim/compute/stddev.sim b/tests/script/tsim/compute/stddev.sim index 7048399112..dbdcde9a16 100644 --- a/tests/script/tsim/compute/stddev.sim +++ b/tests/script/tsim/compute/stddev.sim @@ -38,8 +38,6 @@ while $i < $tbNum $i = $i + 1 endw -sleep 100 - print =============== step2 $i = 1 $tb = $tbPrefix . $i diff --git a/tests/script/tsim/compute/sum.sim b/tests/script/tsim/compute/sum.sim index c53568f98f..950b861b4c 100644 --- a/tests/script/tsim/compute/sum.sim +++ b/tests/script/tsim/compute/sum.sim @@ -38,8 +38,6 @@ while $i < $tbNum $i = $i + 1 endw -sleep 100 - print =============== step2 $i = 1 $tb = $tbPrefix . $i diff --git a/tests/script/tsim/compute/top.sim b/tests/script/tsim/compute/top.sim index 9899a8a9ea..d10b3803e3 100644 --- a/tests/script/tsim/compute/top.sim +++ b/tests/script/tsim/compute/top.sim @@ -38,8 +38,6 @@ while $i < $tbNum $i = $i + 1 endw -sleep 100 - print =============== step2 $i = 1 $tb = $tbPrefix . $i diff --git a/tests/script/tsim/tag/bigint.sim b/tests/script/tsim/tag/bigint.sim index 813387eb38..565688270c 100644 --- a/tests/script/tsim/tag/bigint.sim +++ b/tests/script/tsim/tag/bigint.sim @@ -46,7 +46,6 @@ while $i < 10 endw print =============== step2 -sleep 100 sql select * from $tb if $rows != $rowNum then return -1 diff --git a/tests/script/tsim/tag/binary.sim b/tests/script/tsim/tag/binary.sim index 6ede988954..f3f89d6659 100644 --- a/tests/script/tsim/tag/binary.sim +++ b/tests/script/tsim/tag/binary.sim @@ -46,7 +46,6 @@ while $i < 10 endw print =============== step2 -sleep 100 sql select * from $tb if $rows != $rowNum then return -1 diff --git a/tests/script/tsim/tag/bool.sim b/tests/script/tsim/tag/bool.sim index 356269e1e1..25c7b2d967 100644 --- a/tests/script/tsim/tag/bool.sim +++ b/tests/script/tsim/tag/bool.sim @@ -46,7 +46,6 @@ while $i < 10 endw print =============== step2 -sleep 100 sql select * from $tb if $rows != $rowNum then return -1 diff --git a/tests/script/tsim/tag/double.sim b/tests/script/tsim/tag/double.sim index fedc1c89ec..b8292b64e8 100644 --- a/tests/script/tsim/tag/double.sim +++ b/tests/script/tsim/tag/double.sim @@ -46,7 +46,6 @@ while $i < 10 endw print =============== step2 -sleep 100 sql select * from $tb if $rows != $rowNum then return -1 diff --git a/tests/script/tsim/tag/float.sim b/tests/script/tsim/tag/float.sim index 0ed12d2269..26a09e2973 100644 --- a/tests/script/tsim/tag/float.sim +++ b/tests/script/tsim/tag/float.sim @@ -46,7 +46,6 @@ while $i < 10 endw print =============== step2 -sleep 100 sql select * from $tb if $rows != $rowNum then return -1 diff --git a/tests/script/tsim/tag/int.sim b/tests/script/tsim/tag/int.sim index e561cde56a..13255eb2ba 100644 --- a/tests/script/tsim/tag/int.sim +++ b/tests/script/tsim/tag/int.sim @@ -46,7 +46,6 @@ while $i < 10 endw print =============== step2 -sleep 100 sql select * from $tb if $rows != $rowNum then return -1 diff --git a/tests/script/tsim/tag/smallint.sim b/tests/script/tsim/tag/smallint.sim index 47e28db46c..70c5ee0771 100644 --- a/tests/script/tsim/tag/smallint.sim +++ b/tests/script/tsim/tag/smallint.sim @@ -46,7 +46,6 @@ while $i < 10 endw print =============== step2 -sleep 100 sql select * from $tb if $rows != $rowNum then return -1 diff --git a/tests/script/tsim/tag/tinyint.sim b/tests/script/tsim/tag/tinyint.sim index 0941c9cf18..b7f7616cf4 100644 --- a/tests/script/tsim/tag/tinyint.sim +++ b/tests/script/tsim/tag/tinyint.sim @@ -46,7 +46,6 @@ while $i < 10 endw print =============== step2 -sleep 100 sql select * from $tb if $rows != $rowNum then return -1 diff --git a/tests/script/tsim/vector/metrics_field.sim b/tests/script/tsim/vector/metrics_field.sim index 4d0f9e19fc..b75ba9cffe 100644 --- a/tests/script/tsim/vector/metrics_field.sim +++ b/tests/script/tsim/vector/metrics_field.sim @@ -41,8 +41,6 @@ while $i < $tbNum $i = $i + 1 endw -sleep 100 - print =============== step2 $i = 1 $tb = $tbPrefix . $i diff --git a/tests/script/tsim/vector/metrics_mix.sim b/tests/script/tsim/vector/metrics_mix.sim index fd36a62332..fa93f0b2e3 100644 --- a/tests/script/tsim/vector/metrics_mix.sim +++ b/tests/script/tsim/vector/metrics_mix.sim @@ -37,8 +37,6 @@ while $i < $tbNum $i = $i + 1 endw -sleep 100 - print =============== step2 $i = 1 $tb = $tbPrefix . $i diff --git a/tests/script/tsim/vector/metrics_query.sim b/tests/script/tsim/vector/metrics_query.sim index 8a334acef2..5d433486e8 100644 --- a/tests/script/tsim/vector/metrics_query.sim +++ b/tests/script/tsim/vector/metrics_query.sim @@ -37,8 +37,6 @@ while $i < $tbNum $i = $i + 1 endw -sleep 100 - print =============== step2 $i = 1 $tb = $tbPrefix . $i diff --git a/tests/script/tsim/vector/metrics_tag.sim b/tests/script/tsim/vector/metrics_tag.sim index 0b275336f9..c8380590d5 100644 --- a/tests/script/tsim/vector/metrics_tag.sim +++ b/tests/script/tsim/vector/metrics_tag.sim @@ -37,8 +37,6 @@ while $i < $tbNum $i = $i + 1 endw -sleep 100 - print =============== step2 $i = 1 $tb = $tbPrefix . $i diff --git a/tests/script/tsim/vector/metrics_time.sim b/tests/script/tsim/vector/metrics_time.sim index bcd93cb582..efa1ae4c84 100644 --- a/tests/script/tsim/vector/metrics_time.sim +++ b/tests/script/tsim/vector/metrics_time.sim @@ -37,8 +37,6 @@ while $i < $tbNum $i = $i + 1 endw -sleep 100 - print =============== step2 $i = 1 $tb = $tbPrefix . $i diff --git a/tests/script/tsim/vector/multi.sim b/tests/script/tsim/vector/multi.sim index dcedbe73c9..1b592cdd0a 100644 --- a/tests/script/tsim/vector/multi.sim +++ b/tests/script/tsim/vector/multi.sim @@ -37,8 +37,6 @@ while $i < $tbNum $i = $i + 1 endw -sleep 100 - print =============== step2 $i = 1 $tb = $tbPrefix . $i diff --git a/tests/script/tsim/vector/single.sim b/tests/script/tsim/vector/single.sim index c9d794456c..4da7c78110 100644 --- a/tests/script/tsim/vector/single.sim +++ b/tests/script/tsim/vector/single.sim @@ -37,8 +37,6 @@ while $i < $tbNum $i = $i + 1 endw -sleep 100 - print =============== step2 $i = 1 $tb = $tbPrefix . $i diff --git a/tests/script/tsim/vector/table_field.sim b/tests/script/tsim/vector/table_field.sim index 5ad60b2a35..d5bdad8be2 100644 --- a/tests/script/tsim/vector/table_field.sim +++ b/tests/script/tsim/vector/table_field.sim @@ -37,8 +37,6 @@ while $i < $tbNum $i = $i + 1 endw -sleep 100 - print =============== step2 $i = 1 $tb = $tbPrefix . $i diff --git a/tests/script/tsim/vector/table_mix.sim b/tests/script/tsim/vector/table_mix.sim index 358d6cf87f..79ecb09d81 100644 --- a/tests/script/tsim/vector/table_mix.sim +++ b/tests/script/tsim/vector/table_mix.sim @@ -37,8 +37,6 @@ while $i < $tbNum $i = $i + 1 endw -sleep 100 - print =============== step2 $i = 1 $tb = $tbPrefix . $i diff --git a/tests/script/tsim/vector/table_query.sim b/tests/script/tsim/vector/table_query.sim index 0e4562716e..d69d16eba5 100644 --- a/tests/script/tsim/vector/table_query.sim +++ b/tests/script/tsim/vector/table_query.sim @@ -37,8 +37,6 @@ while $i < $tbNum $i = $i + 1 endw -sleep 100 - print =============== step2 $i = 1 $tb = $tbPrefix . $i diff --git a/tests/script/tsim/vector/table_time.sim b/tests/script/tsim/vector/table_time.sim index 1e6bdb2cde..f16c95ad4a 100644 --- a/tests/script/tsim/vector/table_time.sim +++ b/tests/script/tsim/vector/table_time.sim @@ -37,8 +37,6 @@ while $i < $tbNum $i = $i + 1 endw -sleep 100 - print =============== step2 $i = 1 $tb = $tbPrefix . $i -- GitLab From 68ced4523ef2aa1e66af4e60af4f9f7d01a6ceb9 Mon Sep 17 00:00:00 2001 From: Shengliang Guan Date: Thu, 14 Jul 2022 15:21:02 +0800 Subject: [PATCH 119/153] test: restore some 2.0 case --- tests/script/jenkins/basic.txt | 27 +++++++++++++++++++ .../{general => tsim}/table/autocreate.sim | 0 .../{general => tsim}/table/back_insert.sim | 0 .../script/{general => tsim}/table/basic2.sim | 0 .../script/{general => tsim}/table/basic3.sim | 0 .../script/{general => tsim}/table/bigint.sim | 0 .../script/{general => tsim}/table/binary.sim | 0 tests/script/{general => tsim}/table/bool.sim | 0 .../{general => tsim}/table/column2.sim | 0 .../{general => tsim}/table/column_name.sim | 0 .../{general => tsim}/table/column_num.sim | 0 .../{general => tsim}/table/column_value.sim | 0 .../{general => tsim}/table/createmulti.sim | 0 tests/script/{general => tsim}/table/date.sim | 0 .../{general => tsim}/table/db.table.sim | 0 .../{general => tsim}/table/delete_reuse1.sim | 0 .../{general => tsim}/table/delete_reuse2.sim | 0 .../table/delete_writing.sim | 0 .../{general => tsim}/table/describe.sim | 0 .../script/{general => tsim}/table/double.sim | 0 .../script/{general => tsim}/table/float.sim | 0 tests/script/{general => tsim}/table/int.sim | 0 .../script/{general => tsim}/table/limit.sim | 0 .../{general => tsim}/table/smallint.sim | 0 .../script/{general => tsim}/table/table.sim | 0 .../{general => tsim}/table/table_len.sim | 0 .../{general => tsim}/table/testSuite.sim | 0 .../{general => tsim}/table/tinyint.sim | 0 .../script/{general => tsim}/table/vgroup.sim | 0 29 files changed, 27 insertions(+) rename tests/script/{general => tsim}/table/autocreate.sim (100%) rename tests/script/{general => tsim}/table/back_insert.sim (100%) rename tests/script/{general => tsim}/table/basic2.sim (100%) rename tests/script/{general => tsim}/table/basic3.sim (100%) rename tests/script/{general => tsim}/table/bigint.sim (100%) rename tests/script/{general => tsim}/table/binary.sim (100%) rename tests/script/{general => tsim}/table/bool.sim (100%) rename tests/script/{general => tsim}/table/column2.sim (100%) rename tests/script/{general => tsim}/table/column_name.sim (100%) rename tests/script/{general => tsim}/table/column_num.sim (100%) rename tests/script/{general => tsim}/table/column_value.sim (100%) rename tests/script/{general => tsim}/table/createmulti.sim (100%) rename tests/script/{general => tsim}/table/date.sim (100%) rename tests/script/{general => tsim}/table/db.table.sim (100%) rename tests/script/{general => tsim}/table/delete_reuse1.sim (100%) rename tests/script/{general => tsim}/table/delete_reuse2.sim (100%) rename tests/script/{general => tsim}/table/delete_writing.sim (100%) rename tests/script/{general => tsim}/table/describe.sim (100%) rename tests/script/{general => tsim}/table/double.sim (100%) rename tests/script/{general => tsim}/table/float.sim (100%) rename tests/script/{general => tsim}/table/int.sim (100%) rename tests/script/{general => tsim}/table/limit.sim (100%) rename tests/script/{general => tsim}/table/smallint.sim (100%) rename tests/script/{general => tsim}/table/table.sim (100%) rename tests/script/{general => tsim}/table/table_len.sim (100%) rename tests/script/{general => tsim}/table/testSuite.sim (100%) rename tests/script/{general => tsim}/table/tinyint.sim (100%) rename tests/script/{general => tsim}/table/vgroup.sim (100%) diff --git a/tests/script/jenkins/basic.txt b/tests/script/jenkins/basic.txt index 7ab2c644ee..2c7170d40b 100644 --- a/tests/script/jenkins/basic.txt +++ b/tests/script/jenkins/basic.txt @@ -103,7 +103,34 @@ ./test.sh -f tsim/show/basic.sim # ---- table +# ./test.sh -f tsim/table/autocreate.sim ./test.sh -f tsim/table/basic1.sim +# ./test.sh -f tsim/table/basic2.sim +# ./test.sh -f tsim/table/basic3.sim +# ./test.sh -f tsim/table/bigint.sim +# ./test.sh -f tsim/table/binary.sim +# ./test.sh -f tsim/table/bool.sim +# ./test.sh -f tsim/table/column_name.sim +# ./test.sh -f tsim/table/column_num.sim +# ./test.sh -f tsim/table/column_value.sim +# ./test.sh -f tsim/table/column2.sim +# ./test.sh -f tsim/table/createmulti.sim +# ./test.sh -f tsim/table/date.sim +# ./test.sh -f tsim/table/db.table.sim +# ./test.sh -f tsim/table/delete_reuse1.sim +# ./test.sh -f tsim/table/delete_reuse2.sim +# ./test.sh -f tsim/table/delete_writing.sim +# ./test.sh -f tsim/table/describe.sim +# ./test.sh -f tsim/table/double.sim +# ./test.sh -f tsim/table/fill.sim +# ./test.sh -f tsim/table/float.sim +# ./test.sh -f tsim/table/int.sim +# ./test.sh -f tsim/table/limit.sim +# ./test.sh -f tsim/table/smallint.sim +# ./test.sh -f tsim/table/table_len.sim +# ./test.sh -f tsim/table/table.sim +# ./test.sh -f tsim/table/tinyint.sim +# ./test.sh -f tsim/table/vgroup.sim # ---- stream ./test.sh -f tsim/stream/basic0.sim diff --git a/tests/script/general/table/autocreate.sim b/tests/script/tsim/table/autocreate.sim similarity index 100% rename from tests/script/general/table/autocreate.sim rename to tests/script/tsim/table/autocreate.sim diff --git a/tests/script/general/table/back_insert.sim b/tests/script/tsim/table/back_insert.sim similarity index 100% rename from tests/script/general/table/back_insert.sim rename to tests/script/tsim/table/back_insert.sim diff --git a/tests/script/general/table/basic2.sim b/tests/script/tsim/table/basic2.sim similarity index 100% rename from tests/script/general/table/basic2.sim rename to tests/script/tsim/table/basic2.sim diff --git a/tests/script/general/table/basic3.sim b/tests/script/tsim/table/basic3.sim similarity index 100% rename from tests/script/general/table/basic3.sim rename to tests/script/tsim/table/basic3.sim diff --git a/tests/script/general/table/bigint.sim b/tests/script/tsim/table/bigint.sim similarity index 100% rename from tests/script/general/table/bigint.sim rename to tests/script/tsim/table/bigint.sim diff --git a/tests/script/general/table/binary.sim b/tests/script/tsim/table/binary.sim similarity index 100% rename from tests/script/general/table/binary.sim rename to tests/script/tsim/table/binary.sim diff --git a/tests/script/general/table/bool.sim b/tests/script/tsim/table/bool.sim similarity index 100% rename from tests/script/general/table/bool.sim rename to tests/script/tsim/table/bool.sim diff --git a/tests/script/general/table/column2.sim b/tests/script/tsim/table/column2.sim similarity index 100% rename from tests/script/general/table/column2.sim rename to tests/script/tsim/table/column2.sim diff --git a/tests/script/general/table/column_name.sim b/tests/script/tsim/table/column_name.sim similarity index 100% rename from tests/script/general/table/column_name.sim rename to tests/script/tsim/table/column_name.sim diff --git a/tests/script/general/table/column_num.sim b/tests/script/tsim/table/column_num.sim similarity index 100% rename from tests/script/general/table/column_num.sim rename to tests/script/tsim/table/column_num.sim diff --git a/tests/script/general/table/column_value.sim b/tests/script/tsim/table/column_value.sim similarity index 100% rename from tests/script/general/table/column_value.sim rename to tests/script/tsim/table/column_value.sim diff --git a/tests/script/general/table/createmulti.sim b/tests/script/tsim/table/createmulti.sim similarity index 100% rename from tests/script/general/table/createmulti.sim rename to tests/script/tsim/table/createmulti.sim diff --git a/tests/script/general/table/date.sim b/tests/script/tsim/table/date.sim similarity index 100% rename from tests/script/general/table/date.sim rename to tests/script/tsim/table/date.sim diff --git a/tests/script/general/table/db.table.sim b/tests/script/tsim/table/db.table.sim similarity index 100% rename from tests/script/general/table/db.table.sim rename to tests/script/tsim/table/db.table.sim diff --git a/tests/script/general/table/delete_reuse1.sim b/tests/script/tsim/table/delete_reuse1.sim similarity index 100% rename from tests/script/general/table/delete_reuse1.sim rename to tests/script/tsim/table/delete_reuse1.sim diff --git a/tests/script/general/table/delete_reuse2.sim b/tests/script/tsim/table/delete_reuse2.sim similarity index 100% rename from tests/script/general/table/delete_reuse2.sim rename to tests/script/tsim/table/delete_reuse2.sim diff --git a/tests/script/general/table/delete_writing.sim b/tests/script/tsim/table/delete_writing.sim similarity index 100% rename from tests/script/general/table/delete_writing.sim rename to tests/script/tsim/table/delete_writing.sim diff --git a/tests/script/general/table/describe.sim b/tests/script/tsim/table/describe.sim similarity index 100% rename from tests/script/general/table/describe.sim rename to tests/script/tsim/table/describe.sim diff --git a/tests/script/general/table/double.sim b/tests/script/tsim/table/double.sim similarity index 100% rename from tests/script/general/table/double.sim rename to tests/script/tsim/table/double.sim diff --git a/tests/script/general/table/float.sim b/tests/script/tsim/table/float.sim similarity index 100% rename from tests/script/general/table/float.sim rename to tests/script/tsim/table/float.sim diff --git a/tests/script/general/table/int.sim b/tests/script/tsim/table/int.sim similarity index 100% rename from tests/script/general/table/int.sim rename to tests/script/tsim/table/int.sim diff --git a/tests/script/general/table/limit.sim b/tests/script/tsim/table/limit.sim similarity index 100% rename from tests/script/general/table/limit.sim rename to tests/script/tsim/table/limit.sim diff --git a/tests/script/general/table/smallint.sim b/tests/script/tsim/table/smallint.sim similarity index 100% rename from tests/script/general/table/smallint.sim rename to tests/script/tsim/table/smallint.sim diff --git a/tests/script/general/table/table.sim b/tests/script/tsim/table/table.sim similarity index 100% rename from tests/script/general/table/table.sim rename to tests/script/tsim/table/table.sim diff --git a/tests/script/general/table/table_len.sim b/tests/script/tsim/table/table_len.sim similarity index 100% rename from tests/script/general/table/table_len.sim rename to tests/script/tsim/table/table_len.sim diff --git a/tests/script/general/table/testSuite.sim b/tests/script/tsim/table/testSuite.sim similarity index 100% rename from tests/script/general/table/testSuite.sim rename to tests/script/tsim/table/testSuite.sim diff --git a/tests/script/general/table/tinyint.sim b/tests/script/tsim/table/tinyint.sim similarity index 100% rename from tests/script/general/table/tinyint.sim rename to tests/script/tsim/table/tinyint.sim diff --git a/tests/script/general/table/vgroup.sim b/tests/script/tsim/table/vgroup.sim similarity index 100% rename from tests/script/general/table/vgroup.sim rename to tests/script/tsim/table/vgroup.sim -- GitLab From bfb2900c19c7cafeb395a6b877843a460578ecd5 Mon Sep 17 00:00:00 2001 From: Shengliang Guan Date: Thu, 14 Jul 2022 15:24:48 +0800 Subject: [PATCH 120/153] test: restore some 2.0 case --- tests/script/tsim/table/autocreate.sim | 1 - tests/script/tsim/table/basic2.sim | 1 - tests/script/tsim/table/basic3.sim | 3 +-- tests/script/tsim/table/bigint.sim | 5 +---- tests/script/tsim/table/binary.sim | 5 +---- tests/script/tsim/table/bool.sim | 5 +---- tests/script/tsim/table/column2.sim | 5 +---- tests/script/tsim/table/column_name.sim | 5 +---- tests/script/tsim/table/column_num.sim | 5 +---- tests/script/tsim/table/column_value.sim | 5 +---- tests/script/tsim/table/createmulti.sim | 1 - tests/script/tsim/table/date.sim | 5 +---- tests/script/tsim/table/db.table.sim | 5 +---- tests/script/tsim/table/describe.sim | 5 +---- tests/script/tsim/table/double.sim | 5 +---- tests/script/tsim/table/float.sim | 5 +---- tests/script/tsim/table/int.sim | 5 +---- tests/script/tsim/table/limit.sim | 7 +----- tests/script/tsim/table/smallint.sim | 5 +---- tests/script/tsim/table/table.sim | 5 +---- tests/script/tsim/table/table_len.sim | 5 +---- tests/script/tsim/table/testSuite.sim | 27 ------------------------ tests/script/tsim/table/tinyint.sim | 5 +---- tests/script/tsim/table/vgroup.sim | 8 ++----- 24 files changed, 21 insertions(+), 112 deletions(-) delete mode 100644 tests/script/tsim/table/testSuite.sim diff --git a/tests/script/tsim/table/autocreate.sim b/tests/script/tsim/table/autocreate.sim index 404c714ab4..70d58483a2 100644 --- a/tests/script/tsim/table/autocreate.sim +++ b/tests/script/tsim/table/autocreate.sim @@ -1,7 +1,6 @@ system sh/stop_dnodes.sh system sh/deploy.sh -n dnode1 -i 1 system sh/exec.sh -n dnode1 -s start -sleep 2000 sql connect print =============== create database diff --git a/tests/script/tsim/table/basic2.sim b/tests/script/tsim/table/basic2.sim index 4286f9ee4a..737d5a3efe 100644 --- a/tests/script/tsim/table/basic2.sim +++ b/tests/script/tsim/table/basic2.sim @@ -1,7 +1,6 @@ system sh/stop_dnodes.sh system sh/deploy.sh -n dnode1 -i 1 system sh/exec.sh -n dnode1 -s start -sleep 2000 sql connect print =============== one table diff --git a/tests/script/tsim/table/basic3.sim b/tests/script/tsim/table/basic3.sim index 41c276ae98..21470affa8 100644 --- a/tests/script/tsim/table/basic3.sim +++ b/tests/script/tsim/table/basic3.sim @@ -1,7 +1,6 @@ system sh/stop_dnodes.sh system sh/deploy.sh -n dnode1 -i 1 system sh/exec.sh -n dnode1 -s start -sleep 2000 sql connect print =============== create database @@ -73,7 +72,7 @@ endi print =============== drop stable sql drop table db.st sql show db.stables -if $rows != 0 then +if $rows != 2 then return -1 endi diff --git a/tests/script/tsim/table/bigint.sim b/tests/script/tsim/table/bigint.sim index d75f406d77..4611db112f 100644 --- a/tests/script/tsim/table/bigint.sim +++ b/tests/script/tsim/table/bigint.sim @@ -1,9 +1,6 @@ system sh/stop_dnodes.sh system sh/deploy.sh -n dnode1 -i 1 -system sh/cfg.sh -n dnode1 -c walLevel -v 1 system sh/exec.sh -n dnode1 -s start - -sleep 2000 sql connect $i = 0 @@ -66,7 +63,7 @@ endi sql drop database $db sql show databases -if $rows != 0 then +if $rows != 2 then return -1 endi diff --git a/tests/script/tsim/table/binary.sim b/tests/script/tsim/table/binary.sim index 47915530ef..a2cfc77796 100644 --- a/tests/script/tsim/table/binary.sim +++ b/tests/script/tsim/table/binary.sim @@ -1,9 +1,6 @@ system sh/stop_dnodes.sh system sh/deploy.sh -n dnode1 -i 1 -system sh/cfg.sh -n dnode1 -c walLevel -v 1 system sh/exec.sh -n dnode1 -s start - -sleep 2000 sql connect $i = 0 @@ -56,7 +53,7 @@ endi sql drop database $db sql show databases -if $rows != 0 then +if $rows != 2 then return -1 endi diff --git a/tests/script/tsim/table/bool.sim b/tests/script/tsim/table/bool.sim index e49637448f..454bf47d33 100644 --- a/tests/script/tsim/table/bool.sim +++ b/tests/script/tsim/table/bool.sim @@ -1,9 +1,6 @@ system sh/stop_dnodes.sh system sh/deploy.sh -n dnode1 -i 1 -system sh/cfg.sh -n dnode1 -c walLevel -v 1 system sh/exec.sh -n dnode1 -s start - -sleep 2000 sql connect $i = 0 @@ -85,7 +82,7 @@ endi sql drop database $db sql show databases -if $rows != 0 then +if $rows != 2 then return -1 endi diff --git a/tests/script/tsim/table/column2.sim b/tests/script/tsim/table/column2.sim index 441766f2d4..e540835c14 100644 --- a/tests/script/tsim/table/column2.sim +++ b/tests/script/tsim/table/column2.sim @@ -1,9 +1,6 @@ system sh/stop_dnodes.sh system sh/deploy.sh -n dnode1 -i 1 -system sh/cfg.sh -n dnode1 -c walLevel -v 1 system sh/exec.sh -n dnode1 -s start - -sleep 2000 sql connect print =============== step1 @@ -19,7 +16,7 @@ endi sql drop database db sql show databases -if $rows != 0 then +if $rows != 2 then return -1 endi diff --git a/tests/script/tsim/table/column_name.sim b/tests/script/tsim/table/column_name.sim index 47fcfab5a8..bad6c95bb1 100644 --- a/tests/script/tsim/table/column_name.sim +++ b/tests/script/tsim/table/column_name.sim @@ -1,9 +1,6 @@ system sh/stop_dnodes.sh system sh/deploy.sh -n dnode1 -i 1 -system sh/cfg.sh -n dnode1 -c walLevel -v 1 system sh/exec.sh -n dnode1 -s start - -sleep 2000 sql connect $i = 0 @@ -79,7 +76,7 @@ endi sql drop database $db sql show databases -if $rows != 0 then +if $rows != 2 then return -1 endi diff --git a/tests/script/tsim/table/column_num.sim b/tests/script/tsim/table/column_num.sim index a18173bc8f..0a5d151adf 100644 --- a/tests/script/tsim/table/column_num.sim +++ b/tests/script/tsim/table/column_num.sim @@ -1,9 +1,6 @@ system sh/stop_dnodes.sh system sh/deploy.sh -n dnode1 -i 1 -system sh/cfg.sh -n dnode1 -c walLevel -v 1 system sh/exec.sh -n dnode1 -s start - -sleep 2000 sql connect $i = 0 @@ -78,7 +75,7 @@ endi sql drop database $db sql show databases -if $rows != 0 then +if $rows != 2 then return -1 endi diff --git a/tests/script/tsim/table/column_value.sim b/tests/script/tsim/table/column_value.sim index 1edf8c2992..861e2f1a8d 100644 --- a/tests/script/tsim/table/column_value.sim +++ b/tests/script/tsim/table/column_value.sim @@ -1,9 +1,6 @@ system sh/stop_dnodes.sh system sh/deploy.sh -n dnode1 -i 1 -system sh/cfg.sh -n dnode1 -c walLevel -v 1 system sh/exec.sh -n dnode1 -s start - -sleep 2000 sql connect $i = 0 @@ -68,7 +65,7 @@ endi sql drop database $db sql show databases -if $rows != 0 then +if $rows != 2 then return -1 endi diff --git a/tests/script/tsim/table/createmulti.sim b/tests/script/tsim/table/createmulti.sim index 0da1ce96a7..efdb276c94 100644 --- a/tests/script/tsim/table/createmulti.sim +++ b/tests/script/tsim/table/createmulti.sim @@ -1,7 +1,6 @@ system sh/stop_dnodes.sh system sh/deploy.sh -n dnode1 -i 1 system sh/exec.sh -n dnode1 -s start -sleep 3000 sql connect print =============== create database diff --git a/tests/script/tsim/table/date.sim b/tests/script/tsim/table/date.sim index 23188e12e0..218049d329 100644 --- a/tests/script/tsim/table/date.sim +++ b/tests/script/tsim/table/date.sim @@ -1,9 +1,6 @@ system sh/stop_dnodes.sh system sh/deploy.sh -n dnode1 -i 1 -system sh/cfg.sh -n dnode1 -c walLevel -v 1 system sh/exec.sh -n dnode1 -s start - -sleep 2000 sql connect $i = 0 @@ -83,7 +80,7 @@ endi sql drop database $db sql show databases -if $rows != 0 then +if $rows != 2 then return -1 endi diff --git a/tests/script/tsim/table/db.table.sim b/tests/script/tsim/table/db.table.sim index 906396402a..b5d8294b6e 100644 --- a/tests/script/tsim/table/db.table.sim +++ b/tests/script/tsim/table/db.table.sim @@ -1,9 +1,6 @@ system sh/stop_dnodes.sh system sh/deploy.sh -n dnode1 -i 1 -system sh/cfg.sh -n dnode1 -c walLevel -v 1 system sh/exec.sh -n dnode1 -s start - -sleep 2000 sql connect $i = 0 @@ -40,7 +37,7 @@ sql drop table $table sql drop database $db sql show databases -if $rows != 0 then +if $rows != 2 then return -1 endi diff --git a/tests/script/tsim/table/describe.sim b/tests/script/tsim/table/describe.sim index e59371e530..28690e5794 100644 --- a/tests/script/tsim/table/describe.sim +++ b/tests/script/tsim/table/describe.sim @@ -1,9 +1,6 @@ system sh/stop_dnodes.sh system sh/deploy.sh -n dnode1 -i 1 -system sh/cfg.sh -n dnode1 -c walLevel -v 1 system sh/exec.sh -n dnode1 -s start - -sleep 2000 sql connect $i = 0 @@ -42,7 +39,7 @@ endi sql drop database $db sql show databases -if $rows != 0 then +if $rows != 2 then return -1 endi diff --git a/tests/script/tsim/table/double.sim b/tests/script/tsim/table/double.sim index ab3f2428bd..08f0dc7663 100644 --- a/tests/script/tsim/table/double.sim +++ b/tests/script/tsim/table/double.sim @@ -1,9 +1,6 @@ system sh/stop_dnodes.sh system sh/deploy.sh -n dnode1 -i 1 -system sh/cfg.sh -n dnode1 -c walLevel -v 1 system sh/exec.sh -n dnode1 -s start - -sleep 2000 sql connect $i = 0 @@ -91,7 +88,7 @@ endi sql drop database $db sql show databases -if $rows != 0 then +if $rows != 2 then return -1 endi diff --git a/tests/script/tsim/table/float.sim b/tests/script/tsim/table/float.sim index 2d0ea0e5ea..c53b4bb1a4 100644 --- a/tests/script/tsim/table/float.sim +++ b/tests/script/tsim/table/float.sim @@ -1,9 +1,6 @@ system sh/stop_dnodes.sh system sh/deploy.sh -n dnode1 -i 1 -system sh/cfg.sh -n dnode1 -c walLevel -v 1 system sh/exec.sh -n dnode1 -s start - -sleep 2000 sql connect $i = 0 @@ -91,7 +88,7 @@ endi sql drop database $db sql show databases -if $rows != 0 then +if $rows != 2 then return -1 endi diff --git a/tests/script/tsim/table/int.sim b/tests/script/tsim/table/int.sim index f30b5b28f5..f84858c7d0 100644 --- a/tests/script/tsim/table/int.sim +++ b/tests/script/tsim/table/int.sim @@ -1,9 +1,6 @@ system sh/stop_dnodes.sh system sh/deploy.sh -n dnode1 -i 1 -system sh/cfg.sh -n dnode1 -c walLevel -v 1 system sh/exec.sh -n dnode1 -s start - -sleep 2000 sql connect $i = 0 @@ -127,7 +124,7 @@ endi sql drop database $db sql show databases -if $rows != 0 then +if $rows != 2 then return -1 endi diff --git a/tests/script/tsim/table/limit.sim b/tests/script/tsim/table/limit.sim index dd38453d0c..0a07ee3efa 100644 --- a/tests/script/tsim/table/limit.sim +++ b/tests/script/tsim/table/limit.sim @@ -1,11 +1,6 @@ system sh/stop_dnodes.sh system sh/deploy.sh -n dnode1 -i 1 -system sh/cfg.sh -n dnode1 -c walLevel -v 1 -system sh/cfg.sh -n dnode1 -c maxtablesPerVnode -v 129 -system sh/cfg.sh -n dnode1 -c maxVgroupsPerDb -v 8 system sh/exec.sh -n dnode1 -s start - -sleep 2000 sql connect print ============================ dnode1 start @@ -87,7 +82,7 @@ endi sql drop database $db sql show databases -if $rows != 0 then +if $rows != 2 then return -1 endi diff --git a/tests/script/tsim/table/smallint.sim b/tests/script/tsim/table/smallint.sim index f622ce7853..c81681c316 100644 --- a/tests/script/tsim/table/smallint.sim +++ b/tests/script/tsim/table/smallint.sim @@ -1,9 +1,6 @@ system sh/stop_dnodes.sh system sh/deploy.sh -n dnode1 -i 1 -system sh/cfg.sh -n dnode1 -c walLevel -v 1 system sh/exec.sh -n dnode1 -s start - -sleep 2000 sql connect $i = 0 @@ -98,7 +95,7 @@ endi sql drop database $db sql show databases -if $rows != 0 then +if $rows != 2 then return -1 endi diff --git a/tests/script/tsim/table/table.sim b/tests/script/tsim/table/table.sim index c9806c40c6..6a706c979f 100644 --- a/tests/script/tsim/table/table.sim +++ b/tests/script/tsim/table/table.sim @@ -1,9 +1,6 @@ system sh/stop_dnodes.sh system sh/deploy.sh -n dnode1 -i 1 -system sh/cfg.sh -n dnode1 -c walLevel -v 1 system sh/exec.sh -n dnode1 -s start - -sleep 2000 sql connect print ============================ dnode1 start @@ -217,7 +214,7 @@ endi sql drop database $db sql show databases -if $rows != 0 then +if $rows != 2 then return -1 endi diff --git a/tests/script/tsim/table/table_len.sim b/tests/script/tsim/table/table_len.sim index d95c9ab0aa..e48c5d419e 100644 --- a/tests/script/tsim/table/table_len.sim +++ b/tests/script/tsim/table/table_len.sim @@ -1,9 +1,6 @@ system sh/stop_dnodes.sh system sh/deploy.sh -n dnode1 -i 1 -system sh/cfg.sh -n dnode1 -c walLevel -v 1 system sh/exec.sh -n dnode1 -s start - -sleep 2000 sql connect $i = 0 @@ -98,7 +95,7 @@ step8: sql drop database $db sql show databases -if $rows != 0 then +if $rows != 2 then return -1 endi diff --git a/tests/script/tsim/table/testSuite.sim b/tests/script/tsim/table/testSuite.sim deleted file mode 100644 index d6cc88b36a..0000000000 --- a/tests/script/tsim/table/testSuite.sim +++ /dev/null @@ -1,27 +0,0 @@ -run general/table/autocreate.sim -run general/table/basic1.sim -run general/table/basic2.sim -run general/table/basic3.sim -run general/table/bigint.sim -run general/table/binary.sim -run general/table/bool.sim -run general/table/column_name.sim -run general/table/column_num.sim -run general/table/column_value.sim -run general/table/column2.sim -run general/table/date.sim -run general/table/db.table.sim -run general/table/delete_reuse1.sim -run general/table/delete_reuse2.sim -run general/table/delete_writing.sim -run general/table/describe.sim -run general/table/double.sim -run general/table/fill.sim -run general/table/float.sim -run general/table/int.sim -run general/table/limit.sim -run general/table/smallint.sim -run general/table/table_len.sim -run general/table/table.sim -run general/table/tinyint.sim -run general/table/vgroup.sim diff --git a/tests/script/tsim/table/tinyint.sim b/tests/script/tsim/table/tinyint.sim index afa931fc79..089fab0bfa 100644 --- a/tests/script/tsim/table/tinyint.sim +++ b/tests/script/tsim/table/tinyint.sim @@ -1,9 +1,6 @@ system sh/stop_dnodes.sh system sh/deploy.sh -n dnode1 -i 1 -system sh/cfg.sh -n dnode1 -c walLevel -v 1 system sh/exec.sh -n dnode1 -s start - -sleep 2000 sql connect $i = 0 @@ -97,7 +94,7 @@ endi sql drop database $db sql show databases -if $rows != 0 then +if $rows != 2 then return -1 endi diff --git a/tests/script/tsim/table/vgroup.sim b/tests/script/tsim/table/vgroup.sim index d306a4731d..902415400e 100644 --- a/tests/script/tsim/table/vgroup.sim +++ b/tests/script/tsim/table/vgroup.sim @@ -1,12 +1,8 @@ system sh/stop_dnodes.sh system sh/deploy.sh -n dnode1 -i 1 -system sh/cfg.sh -n dnode1 -c walLevel -v 1 -system sh/cfg.sh -n dnode1 -c maxVgroupsPerDb -v 4 -system sh/cfg.sh -n dnode1 -c maxTablesPerVnode -v 4 system sh/exec.sh -n dnode1 -s start - -sleep 2000 sql connect + print ============================ dnode1 start $i = 0 @@ -144,7 +140,7 @@ while $i < 5 $i = $i + 1 endw sql show databases -if $rows != 0 then +if $rows != 2 then return -1 endi -- GitLab From 9ea0ad57ec3d82bfbcaaac380f9d6454e5acdd0b Mon Sep 17 00:00:00 2001 From: Liu Jicong Date: Thu, 14 Jul 2022 15:32:21 +0800 Subject: [PATCH 121/153] refactor(stream): destroy stream task --- source/client/src/tmq.c | 2 +- source/dnode/mnode/impl/src/mndStream.c | 16 +++- source/dnode/vnode/src/tq/tq.c | 61 +++++++++------ source/dnode/vnode/src/tq/tqRead.c | 13 +++ source/dnode/vnode/src/tq/tqSink.c | 2 +- source/libs/executor/inc/executorimpl.h | 1 - source/libs/executor/src/executorMain.c | 9 +-- source/libs/executor/src/scanoperator.c | 43 +++++++--- source/libs/stream/src/streamExec.c | 100 ++++++++++++------------ source/libs/stream/src/streamTask.c | 2 +- 10 files changed, 152 insertions(+), 97 deletions(-) diff --git a/source/client/src/tmq.c b/source/client/src/tmq.c index b0542e350f..0d9cd4bcff 100644 --- a/source/client/src/tmq.c +++ b/source/client/src/tmq.c @@ -343,7 +343,7 @@ tmq_list_t* tmq_list_new() { int32_t tmq_list_append(tmq_list_t* list, const char* src) { SArray* container = &list->container; - char* topic = strDupUnquo(src); + char* topic = strdup(src); if (taosArrayPush(container, &topic) == NULL) return -1; return 0; } diff --git a/source/dnode/mnode/impl/src/mndStream.c b/source/dnode/mnode/impl/src/mndStream.c index c2125f75f8..5777df4fa6 100644 --- a/source/dnode/mnode/impl/src/mndStream.c +++ b/source/dnode/mnode/impl/src/mndStream.c @@ -235,7 +235,8 @@ static int32_t mndStreamGetPlanString(const char *ast, int8_t triggerType, int64 } static int32_t mndBuildStreamObjFromCreateReq(SMnode *pMnode, SStreamObj *pObj, SCMCreateStreamReq *pCreate) { - SNode *pAst = NULL; + SNode *pAst = NULL; + SQueryPlan *pPlan = NULL; mDebug("stream:%s to create", pCreate->name); memcpy(pObj->name, pCreate->name, TSDB_STREAM_FNAME_LEN); @@ -293,7 +294,6 @@ static int32_t mndBuildStreamObjFromCreateReq(SMnode *pMnode, SStreamObj *pObj, goto FAIL; } - SQueryPlan *pPlan = NULL; SPlanContext cxt = { .pAstRoot = pAst, .topicQuery = false, @@ -317,6 +317,7 @@ static int32_t mndBuildStreamObjFromCreateReq(SMnode *pMnode, SStreamObj *pObj, FAIL: if (pAst != NULL) nodesDestroyNode(pAst); + if (pPlan != NULL) qDestroyQueryPlan(pPlan); return 0; } @@ -541,7 +542,7 @@ static int32_t mndProcessCreateStreamReq(SRpcMsg *pReq) { // build stream obj from request SStreamObj streamObj = {0}; if (mndBuildStreamObjFromCreateReq(pMnode, &streamObj, &createStreamReq) < 0) { - ASSERT(0); + /*ASSERT(0);*/ mError("stream:%s, failed to create since %s", createStreamReq.name, terrstr()); goto _OVER; } @@ -689,7 +690,14 @@ int32_t mndDropStreamByDb(SMnode *pMnode, STrans *pTrans, SDbObj *pDb) { terrno = TSDB_CODE_MND_STREAM_ALREADY_EXIST; return -1; } else { - // TODO drop all task on snode +#if 0 + if (mndDropStreamTasks(pMnode, pTrans, pStream) < 0) { + mError("stream:%s, failed to drop task since %s", pStream->name, terrstr()); + sdbRelease(pMnode->pSdb, pStream); + sdbCancelFetch(pSdb, pIter); + return -1; + } +#endif if (mndPersistDropStreamLog(pMnode, pTrans, pStream) < 0) { sdbRelease(pSdb, pStream); sdbCancelFetch(pSdb, pIter); diff --git a/source/dnode/vnode/src/tq/tq.c b/source/dnode/vnode/src/tq/tq.c index df80a4c218..3b6e9abc67 100644 --- a/source/dnode/vnode/src/tq/tq.c +++ b/source/dnode/vnode/src/tq/tq.c @@ -82,6 +82,13 @@ void tqClose(STQ* pTq) { if (pTq) { tqOffsetClose(pTq->pOffsetStore); taosHashCleanup(pTq->handles); + void* pIter = NULL; + while (1) { + pIter = taosHashIterate(pTq->pStreamTasks, pIter); + if (pIter == NULL) break; + SStreamTask* pTask = *(SStreamTask**)pIter; + tFreeSStreamTask(pTask); + } taosHashCleanup(pTq->pStreamTasks); taosHashCleanup(pTq->pushMgr); taosMemoryFree(pTq->path); @@ -608,7 +615,8 @@ int32_t tqProcessTaskDeployReq(STQ* pTq, char* msg, int32_t msgLen) { streamSetupTrigger(pTask); - tqInfo("deploy stream task id %d child id %d on vgId:%d", pTask->taskId, pTask->selfChildId, TD_VID(pTq->pVnode)); + tqInfo("deploy stream task on vg %d, task id %d, child id %d", TD_VID(pTq->pVnode), pTask->taskId, + pTask->selfChildId); taosHashPut(pTq->pStreamTasks, &pTask->taskId, sizeof(int32_t), &pTask, sizeof(void*)); @@ -634,9 +642,6 @@ int32_t tqProcessStreamTrigger(STQ* pTq, SSubmitReq* pReq) { pIter = taosHashIterate(pTq->pStreamTasks, pIter); if (pIter == NULL) break; SStreamTask* pTask = *(SStreamTask**)pIter; - if (atomic_load_8(&pTask->taskStatus) == TASK_STATUS__DROPPING) { - continue; - } if (!pTask->isDataScan) continue; if (!failed) { @@ -665,11 +670,12 @@ int32_t tqProcessTaskRunReq(STQ* pTq, SRpcMsg* pMsg) { SStreamTaskRunReq* pReq = pMsg->pCont; int32_t taskId = pReq->taskId; SStreamTask* pTask = *(SStreamTask**)taosHashGet(pTq->pStreamTasks, &taskId, sizeof(int32_t)); - if (atomic_load_8(&pTask->taskStatus) != TASK_STATUS__NORMAL) { + if (pTask) { + streamProcessRunReq(pTask); return 0; + } else { + return -1; } - streamProcessRunReq(pTask); - return 0; } int32_t tqProcessTaskDispatchReq(STQ* pTq, SRpcMsg* pMsg) { @@ -682,55 +688,62 @@ int32_t tqProcessTaskDispatchReq(STQ* pTq, SRpcMsg* pMsg) { tDecodeStreamDispatchReq(&decoder, &req); int32_t taskId = req.taskId; SStreamTask* pTask = *(SStreamTask**)taosHashGet(pTq->pStreamTasks, &taskId, sizeof(int32_t)); - if (atomic_load_8(&pTask->taskStatus) != TASK_STATUS__NORMAL) { + if (pTask) { + SRpcMsg rsp = { + .info = pMsg->info, + .code = 0, + }; + streamProcessDispatchReq(pTask, &req, &rsp); return 0; + } else { + return -1; } - SRpcMsg rsp = { - .info = pMsg->info, - .code = 0, - }; - streamProcessDispatchReq(pTask, &req, &rsp); - return 0; } int32_t tqProcessTaskRecoverReq(STQ* pTq, SRpcMsg* pMsg) { SStreamTaskRecoverReq* pReq = pMsg->pCont; int32_t taskId = pReq->taskId; SStreamTask* pTask = *(SStreamTask**)taosHashGet(pTq->pStreamTasks, &taskId, sizeof(int32_t)); - if (atomic_load_8(&pTask->taskStatus) != TASK_STATUS__NORMAL) { + if (pTask) { + streamProcessRecoverReq(pTask, pReq, pMsg); return 0; + } else { + return -1; } - streamProcessRecoverReq(pTask, pReq, pMsg); - return 0; } int32_t tqProcessTaskDispatchRsp(STQ* pTq, SRpcMsg* pMsg) { SStreamDispatchRsp* pRsp = POINTER_SHIFT(pMsg->pCont, sizeof(SMsgHead)); int32_t taskId = pRsp->taskId; SStreamTask* pTask = *(SStreamTask**)taosHashGet(pTq->pStreamTasks, &taskId, sizeof(int32_t)); - if (atomic_load_8(&pTask->taskStatus) != TASK_STATUS__NORMAL) { + if (pTask) { + streamProcessDispatchRsp(pTask, pRsp); return 0; + } else { + return -1; } - streamProcessDispatchRsp(pTask, pRsp); - return 0; } int32_t tqProcessTaskRecoverRsp(STQ* pTq, SRpcMsg* pMsg) { SStreamTaskRecoverRsp* pRsp = pMsg->pCont; int32_t taskId = pRsp->taskId; SStreamTask* pTask = *(SStreamTask**)taosHashGet(pTq->pStreamTasks, &taskId, sizeof(int32_t)); - if (atomic_load_8(&pTask->taskStatus) != TASK_STATUS__NORMAL) { + if (pTask) { + streamProcessRecoverRsp(pTask, pRsp); return 0; + } else { + return -1; } - streamProcessRecoverRsp(pTask, pRsp); - return 0; } int32_t tqProcessTaskDropReq(STQ* pTq, char* msg, int32_t msgLen) { SVDropStreamTaskReq* pReq = (SVDropStreamTaskReq*)msg; SStreamTask* pTask = *(SStreamTask**)taosHashGet(pTq->pStreamTasks, &pReq->taskId, sizeof(int32_t)); - atomic_store_8(&pTask->taskStatus, TASK_STATUS__DROPPING); + if (pTask) { + taosHashRemove(pTq->pStreamTasks, &pReq->taskId, sizeof(int32_t)); + atomic_store_8(&pTask->taskStatus, TASK_STATUS__DROPPING); + } // todo // clear queue // push drop req into queue diff --git a/source/dnode/vnode/src/tq/tqRead.c b/source/dnode/vnode/src/tq/tqRead.c index 8753ecc47c..dda306ccf8 100644 --- a/source/dnode/vnode/src/tq/tqRead.c +++ b/source/dnode/vnode/src/tq/tqRead.c @@ -98,8 +98,21 @@ STqReader* tqOpenReader(SVnode* pVnode) { void tqCloseReader(STqReader* pReader) { // close wal reader + if (pReader->pWalReader) { + walCloseReader(pReader->pWalReader); + } // free cached schema + if (pReader->pSchema) { + taosMemoryFree(pReader->pSchema); + } + if (pReader->pSchemaWrapper) { + tDeleteSSchemaWrapper(pReader->pSchemaWrapper); + } + if (pReader->pColIdList) { + taosArrayDestroy(pReader->pColIdList); + } // free hash + taosHashCleanup(pReader->tbIdHash); taosMemoryFree(pReader); } diff --git a/source/dnode/vnode/src/tq/tqSink.c b/source/dnode/vnode/src/tq/tqSink.c index dbbb2b2661..1980f826b0 100644 --- a/source/dnode/vnode/src/tq/tqSink.c +++ b/source/dnode/vnode/src/tq/tqSink.c @@ -146,7 +146,7 @@ SSubmitReq* tdBlockToSubmit(const SArray* pBlocks, const STSchema* pTSchema, boo const STColumn* pColumn = &pTSchema->columns[k]; SColumnInfoData* pColData = taosArrayGet(pDataBlock->pDataBlock, k); if (colDataIsNull_s(pColData, j)) { - tdAppendColValToRow(&rb, pColumn->colId, pColumn->type, TD_VTYPE_NONE, NULL, false, pColumn->offset, k); + tdAppendColValToRow(&rb, pColumn->colId, pColumn->type, TD_VTYPE_NULL, NULL, false, pColumn->offset, k); } else { void* data = colDataGetData(pColData, j); tdAppendColValToRow(&rb, pColumn->colId, pColumn->type, TD_VTYPE_NORM, data, true, pColumn->offset, k); diff --git a/source/libs/executor/inc/executorimpl.h b/source/libs/executor/inc/executorimpl.h index 045b4379ca..24a2ad0558 100644 --- a/source/libs/executor/inc/executorimpl.h +++ b/source/libs/executor/inc/executorimpl.h @@ -147,7 +147,6 @@ typedef struct { SSDataBlock* pullOverBlk; // for streaming SWalFilterCond cond; int64_t lastScanUid; - SStreamQueue* inputQueue; } SStreamTaskInfo; typedef struct SExecTaskInfo { diff --git a/source/libs/executor/src/executorMain.c b/source/libs/executor/src/executorMain.c index 6381d20255..d910b8be34 100644 --- a/source/libs/executor/src/executorMain.c +++ b/source/libs/executor/src/executorMain.c @@ -44,13 +44,6 @@ int32_t qCreateExecTask(SReadHandle* readHandle, int32_t vgId, uint64_t taskId, goto _error; } - if (model == OPTR_EXEC_MODEL_STREAM) { - (*pTask)->streamInfo.inputQueue = streamQueueOpen(); - if ((*pTask)->streamInfo.inputQueue == NULL) { - goto _error; - } - } - SDataSinkMgtCfg cfg = {.maxDataBlockNum = 1000, .maxDataBlockNumPerQuery = 100}; code = dsDataSinkMgtInit(&cfg); if (code != TSDB_CODE_SUCCESS) { @@ -259,12 +252,14 @@ int32_t qExtractStreamScanner(qTaskInfo_t tinfo, void** scanner) { } } +#if 0 int32_t qStreamInput(qTaskInfo_t tinfo, void* pItem) { SExecTaskInfo* pTaskInfo = (SExecTaskInfo*)tinfo; ASSERT(pTaskInfo->execModel == OPTR_EXEC_MODEL_STREAM); taosWriteQitem(pTaskInfo->streamInfo.inputQueue->queue, pItem); return 0; } +#endif void* qExtractReaderFromStreamScanner(void* scanner) { SStreamScanInfo* pInfo = scanner; diff --git a/source/libs/executor/src/scanoperator.c b/source/libs/executor/src/scanoperator.c index b14648991e..38ac6f942d 100644 --- a/source/libs/executor/src/scanoperator.c +++ b/source/libs/executor/src/scanoperator.c @@ -884,22 +884,22 @@ static bool prepareRangeScan(SStreamScanInfo* pInfo, SSDataBlock* pBlock, int32_ return true; } -static STimeWindow getSlidingWindow(TSKEY* tsCol, SInterval* pInterval, SDataBlockInfo* pDataBlockInfo, int32_t* pRowIndex) { - SResultRowInfo dumyInfo; +static STimeWindow getSlidingWindow(TSKEY* tsCol, SInterval* pInterval, SDataBlockInfo* pDataBlockInfo, + int32_t* pRowIndex) { + SResultRowInfo dumyInfo; dumyInfo.cur.pageId = -1; - STimeWindow win = getActiveTimeWindow(NULL, &dumyInfo, tsCol[*pRowIndex], pInterval, - TSDB_ORDER_ASC); + STimeWindow win = getActiveTimeWindow(NULL, &dumyInfo, tsCol[*pRowIndex], pInterval, TSDB_ORDER_ASC); STimeWindow endWin = win; STimeWindow preWin = win; while (1) { - (*pRowIndex) += getNumOfRowsInTimeWindow(pDataBlockInfo, tsCol, *pRowIndex, endWin.ekey, - binarySearchForKey, NULL, TSDB_ORDER_ASC); + (*pRowIndex) += getNumOfRowsInTimeWindow(pDataBlockInfo, tsCol, *pRowIndex, endWin.ekey, binarySearchForKey, NULL, + TSDB_ORDER_ASC); do { preWin = endWin; getNextTimeWindow(pInterval, &endWin, TSDB_ORDER_ASC); } while (tsCol[(*pRowIndex) - 1] >= endWin.skey); endWin = preWin; - if (win.ekey == endWin.ekey || (*pRowIndex) == pDataBlockInfo->rows ) { + if (win.ekey == endWin.ekey || (*pRowIndex) == pDataBlockInfo->rows) { win.ekey = endWin.ekey; return win; } @@ -933,7 +933,8 @@ static bool prepareDataScan(SStreamScanInfo* pInfo, SSDataBlock* pSDB, int32_t t pInfo->updateWin.ekey = tsCols[*pRowIndex - 1]; // win = getActiveTimeWindow(NULL, &dumyInfo, tsCols[*pRowIndex], &pInfo->interval, TSDB_ORDER_ASC); // (*pRowIndex) += - // getNumOfRowsInTimeWindow(&pSDB->info, tsCols, *pRowIndex, win.ekey, binarySearchForKey, NULL, TSDB_ORDER_ASC); + // getNumOfRowsInTimeWindow(&pSDB->info, tsCols, *pRowIndex, win.ekey, binarySearchForKey, NULL, + // TSDB_ORDER_ASC); } needRead = true; } else if (isStateWindow(pInfo)) { @@ -1447,6 +1448,28 @@ SOperatorInfo* createRawScanOperatorInfo(SReadHandle* pHandle, STableScanPhysiNo return NULL; } +static void destroyStreamScanOperatorInfo(void* param, int32_t numOfOutput) { + SStreamScanInfo* pStreamScan = (SStreamScanInfo*)param; +#if 0 + if (pStreamScan->pTableScanOp && pStreamScan->pTableScanOp->info) { + STableScanInfo* pTableScanInfo = pStreamScan->pTableScanOp->info; + destroyTableScanOperatorInfo(pTableScanInfo, 1); + } +#endif + if (pStreamScan->tqReader) { + tqCloseReader(pStreamScan->tqReader); + } + if (pStreamScan->pColMatchInfo) { + taosArrayDestroy(pStreamScan->pColMatchInfo); + } + blockDataDestroy(pStreamScan->pRes); + blockDataDestroy(pStreamScan->pUpdateRes); + blockDataDestroy(pStreamScan->pPullDataRes); + blockDataDestroy(pStreamScan->pDeleteDataRes); + taosArrayDestroy(pStreamScan->pBlockLists); + taosMemoryFree(pStreamScan); +} + SOperatorInfo* createStreamScanOperatorInfo(SReadHandle* pHandle, STableScanPhysiNode* pTableScanNode, SExecTaskInfo* pTaskInfo, STimeWindowAggSupp* pTwSup, uint64_t queryId, uint64_t taskId) { @@ -1561,8 +1584,8 @@ SOperatorInfo* createStreamScanOperatorInfo(SReadHandle* pHandle, STableScanPhys pOperator->exprSupp.numOfExprs = taosArrayGetSize(pInfo->pRes->pDataBlock); pOperator->pTaskInfo = pTaskInfo; - pOperator->fpSet = - createOperatorFpSet(operatorDummyOpenFn, doStreamScan, NULL, NULL, operatorDummyCloseFn, NULL, NULL, NULL); + pOperator->fpSet = createOperatorFpSet(operatorDummyOpenFn, doStreamScan, NULL, NULL, destroyStreamScanOperatorInfo, + NULL, NULL, NULL); return pOperator; diff --git a/source/libs/stream/src/streamExec.c b/source/libs/stream/src/streamExec.c index d0d81e3343..635ae820fe 100644 --- a/source/libs/stream/src/streamExec.c +++ b/source/libs/stream/src/streamExec.c @@ -74,63 +74,62 @@ static int32_t streamTaskExecImpl(SStreamTask* pTask, void* data, SArray* pRes) } static SArray* streamExecForQall(SStreamTask* pTask, SArray* pRes) { + int32_t cnt = 0; + void* data = NULL; while (1) { - int32_t cnt = 0; - void* data = NULL; - while (1) { - SStreamQueueItem* qItem = streamQueueNextItem(pTask->inputQueue); - if (qItem == NULL) { - qDebug("stream exec over, queue empty"); + SStreamQueueItem* qItem = streamQueueNextItem(pTask->inputQueue); + if (qItem == NULL) { + qDebug("stream exec over, queue empty"); + break; + } + if (data == NULL) { + data = qItem; + streamQueueProcessSuccess(pTask->inputQueue); + continue; + } else { + if (streamAppendQueueItem(data, qItem) < 0) { + streamQueueProcessFail(pTask->inputQueue); break; - } - if (data == NULL) { - data = qItem; - streamQueueProcessSuccess(pTask->inputQueue); - continue; } else { - if (streamAppendQueueItem(data, qItem) < 0) { - streamQueueProcessFail(pTask->inputQueue); - break; - } else { - cnt++; - streamQueueProcessSuccess(pTask->inputQueue); - taosArrayDestroy(((SStreamDataBlock*)qItem)->blocks); - taosFreeQitem(qItem); - } + cnt++; + streamQueueProcessSuccess(pTask->inputQueue); + taosArrayDestroy(((SStreamDataBlock*)qItem)->blocks); + taosFreeQitem(qItem); } } - if (data == NULL) break; + } + if (pTask->taskStatus == TASK_STATUS__DROPPING) { + if (data) streamFreeQitem(data); + taosArrayDestroyEx(pRes, (FDelete)tDeleteSSDataBlock); + return NULL; + } - qDebug("stream task %d exec begin, batch msg: %d", pTask->taskId, cnt); - streamTaskExecImpl(pTask, data, pRes); - qDebug("stream task %d exec end", pTask->taskId); + if (data == NULL) return pRes; - if (pTask->taskStatus == TASK_STATUS__DROPPING) { - taosArrayDestroyEx(pRes, (FDelete)tDeleteSSDataBlock); + qDebug("stream task %d exec begin, msg batch: %d", pTask->taskId, cnt); + streamTaskExecImpl(pTask, data, pRes); + qDebug("stream task %d exec end", pTask->taskId); + + if (taosArrayGetSize(pRes) != 0) { + SStreamDataBlock* qRes = taosAllocateQitem(sizeof(SStreamDataBlock), DEF_QITEM); + if (qRes == NULL) { + streamQueueProcessFail(pTask->inputQueue); + taosArrayDestroy(pRes); return NULL; } - - if (taosArrayGetSize(pRes) != 0) { - SStreamDataBlock* qRes = taosAllocateQitem(sizeof(SStreamDataBlock), DEF_QITEM); - if (qRes == NULL) { - streamQueueProcessFail(pTask->inputQueue); - taosArrayDestroy(pRes); - return NULL; - } - qRes->type = STREAM_INPUT__DATA_BLOCK; - qRes->blocks = pRes; - if (streamTaskOutput(pTask, qRes) < 0) { - /*streamQueueProcessFail(pTask->inputQueue);*/ - taosArrayDestroyEx(pRes, (FDelete)tDeleteSSDataBlock); - taosFreeQitem(qRes); - return NULL; - } - /*streamQueueProcessSuccess(pTask->inputQueue);*/ - pRes = taosArrayInit(0, sizeof(SSDataBlock)); + qRes->type = STREAM_INPUT__DATA_BLOCK; + qRes->blocks = pRes; + if (streamTaskOutput(pTask, qRes) < 0) { + /*streamQueueProcessFail(pTask->inputQueue);*/ + taosArrayDestroyEx(pRes, (FDelete)tDeleteSSDataBlock); + taosFreeQitem(qRes); + return NULL; } - - streamFreeQitem(data); + /*streamQueueProcessSuccess(pTask->inputQueue);*/ + pRes = taosArrayInit(0, sizeof(SSDataBlock)); } + + streamFreeQitem(data); return pRes; } @@ -171,6 +170,11 @@ int32_t streamExec(SStreamTask* pTask, SMsgCb* pMsgCb) { } FAIL: if (pRes) taosArrayDestroy(pRes); - atomic_store_8(&pTask->execStatus, TASK_EXEC_STATUS__IDLE); - return -1; + if (pTask->taskStatus == TASK_STATUS__DROPPING) { + tFreeSStreamTask(pTask); + return 0; + } else { + atomic_store_8(&pTask->execStatus, TASK_EXEC_STATUS__IDLE); + return -1; + } } diff --git a/source/libs/stream/src/streamTask.c b/source/libs/stream/src/streamTask.c index 97aa182dc9..7488c009bd 100644 --- a/source/libs/stream/src/streamTask.c +++ b/source/libs/stream/src/streamTask.c @@ -163,6 +163,6 @@ void tFreeSStreamTask(SStreamTask* pTask) { streamQueueClose(pTask->inputQueue); streamQueueClose(pTask->outputQueue); if (pTask->exec.qmsg) taosMemoryFree(pTask->exec.qmsg); - qDestroyTask(pTask->exec.executor); + if (pTask->exec.executor) qDestroyTask(pTask->exec.executor); taosMemoryFree(pTask); } -- GitLab From 13230df94822b7da55387f889a694286f784cd2f Mon Sep 17 00:00:00 2001 From: Shengliang Guan Date: Thu, 14 Jul 2022 15:51:59 +0800 Subject: [PATCH 122/153] test: restore some 2.0 case --- tests/script/jenkins/basic.txt | 47 ++++++++++++----------- tests/script/tsim/table/autocreate.sim | 2 +- tests/script/tsim/table/basic1.sim | 17 --------- tests/script/tsim/table/basic2.sim | 6 +-- tests/script/tsim/table/basic3.sim | 4 +- tests/script/tsim/table/createmulti.sim | 2 +- tests/script/tsim/table/date.sim | 16 ++++---- tests/script/tsim/table/int.sim | 50 ++++++++++++------------- tests/script/tsim/table/limit.sim | 4 +- tests/script/tsim/table/smallint.sim | 38 +++++++++---------- tests/script/tsim/table/table.sim | 5 +-- tests/script/tsim/table/tinyint.sim | 36 +++++++++--------- tests/script/tsim/table/vgroup.sim | 24 ++++++------ 13 files changed, 112 insertions(+), 139 deletions(-) diff --git a/tests/script/jenkins/basic.txt b/tests/script/jenkins/basic.txt index 2c7170d40b..4de8b3667d 100644 --- a/tests/script/jenkins/basic.txt +++ b/tests/script/jenkins/basic.txt @@ -103,34 +103,33 @@ ./test.sh -f tsim/show/basic.sim # ---- table -# ./test.sh -f tsim/table/autocreate.sim +./test.sh -f tsim/table/autocreate.sim ./test.sh -f tsim/table/basic1.sim -# ./test.sh -f tsim/table/basic2.sim -# ./test.sh -f tsim/table/basic3.sim -# ./test.sh -f tsim/table/bigint.sim -# ./test.sh -f tsim/table/binary.sim -# ./test.sh -f tsim/table/bool.sim -# ./test.sh -f tsim/table/column_name.sim -# ./test.sh -f tsim/table/column_num.sim -# ./test.sh -f tsim/table/column_value.sim -# ./test.sh -f tsim/table/column2.sim -# ./test.sh -f tsim/table/createmulti.sim -# ./test.sh -f tsim/table/date.sim -# ./test.sh -f tsim/table/db.table.sim +./test.sh -f tsim/table/basic2.sim +./test.sh -f tsim/table/basic3.sim +./test.sh -f tsim/table/bigint.sim +./test.sh -f tsim/table/binary.sim +./test.sh -f tsim/table/bool.sim +./test.sh -f tsim/table/column_name.sim +./test.sh -f tsim/table/column_num.sim +./test.sh -f tsim/table/column_value.sim +./test.sh -f tsim/table/column2.sim +./test.sh -f tsim/table/createmulti.sim +./test.sh -f tsim/table/date.sim +./test.sh -f tsim/table/db.table.sim # ./test.sh -f tsim/table/delete_reuse1.sim # ./test.sh -f tsim/table/delete_reuse2.sim # ./test.sh -f tsim/table/delete_writing.sim -# ./test.sh -f tsim/table/describe.sim -# ./test.sh -f tsim/table/double.sim -# ./test.sh -f tsim/table/fill.sim -# ./test.sh -f tsim/table/float.sim -# ./test.sh -f tsim/table/int.sim -# ./test.sh -f tsim/table/limit.sim -# ./test.sh -f tsim/table/smallint.sim -# ./test.sh -f tsim/table/table_len.sim -# ./test.sh -f tsim/table/table.sim -# ./test.sh -f tsim/table/tinyint.sim -# ./test.sh -f tsim/table/vgroup.sim +./test.sh -f tsim/table/describe.sim +./test.sh -f tsim/table/double.sim +./test.sh -f tsim/table/float.sim +./test.sh -f tsim/table/int.sim +./test.sh -f tsim/table/limit.sim +./test.sh -f tsim/table/smallint.sim +./test.sh -f tsim/table/table_len.sim +./test.sh -f tsim/table/table.sim +./test.sh -f tsim/table/tinyint.sim +./test.sh -f tsim/table/vgroup.sim # ---- stream ./test.sh -f tsim/stream/basic0.sim diff --git a/tests/script/tsim/table/autocreate.sim b/tests/script/tsim/table/autocreate.sim index 70d58483a2..1267e33932 100644 --- a/tests/script/tsim/table/autocreate.sim +++ b/tests/script/tsim/table/autocreate.sim @@ -6,7 +6,7 @@ sql connect print =============== create database sql create database db sql show databases -if $rows != 1 then +if $rows != 3 then return -1 endi diff --git a/tests/script/tsim/table/basic1.sim b/tests/script/tsim/table/basic1.sim index 913ced74aa..6cb5bc54f7 100644 --- a/tests/script/tsim/table/basic1.sim +++ b/tests/script/tsim/table/basic1.sim @@ -213,23 +213,6 @@ endi system sh/exec.sh -n dnode1 -s stop -x SIGINT system sh/exec.sh -n dnode1 -s start -$loop_cnt = 0 -check_dnode_ready: - $loop_cnt = $loop_cnt + 1 - sleep 200 - if $loop_cnt == 10 then - print ====> dnode not ready! - return -1 - endi -sql show dnodes -print ===> $rows $data00 $data01 $data02 $data03 $data04 $data05 -if $data00 != 1 then - return -1 -endi -if $data04 != ready then - goto check_dnode_ready -endi - print =============== query data sql select * from c1 print rows: $rows diff --git a/tests/script/tsim/table/basic2.sim b/tests/script/tsim/table/basic2.sim index 737d5a3efe..297ae3d333 100644 --- a/tests/script/tsim/table/basic2.sim +++ b/tests/script/tsim/table/basic2.sim @@ -20,11 +20,11 @@ endi print =============== show sql show databases -if $data02 != 2 then +if $data22 != 2 then return -1 endi -if $data03 != 1 then +if $data24 != 1 then return -1 endi @@ -33,7 +33,7 @@ if $data00 != 2 then return -1 endi -if $data01 != 2 then +if $data01 != d1 then return -1 endi diff --git a/tests/script/tsim/table/basic3.sim b/tests/script/tsim/table/basic3.sim index 21470affa8..c9335b6d1b 100644 --- a/tests/script/tsim/table/basic3.sim +++ b/tests/script/tsim/table/basic3.sim @@ -6,7 +6,7 @@ sql connect print =============== create database sql create database db sql show databases -if $rows != 1 then +if $rows != 3 then return -1 endi @@ -72,7 +72,7 @@ endi print =============== drop stable sql drop table db.st sql show db.stables -if $rows != 2 then +if $rows != 0 then return -1 endi diff --git a/tests/script/tsim/table/createmulti.sim b/tests/script/tsim/table/createmulti.sim index efdb276c94..e204bd4f3d 100644 --- a/tests/script/tsim/table/createmulti.sim +++ b/tests/script/tsim/table/createmulti.sim @@ -6,7 +6,7 @@ sql connect print =============== create database sql create database db sql show databases -if $rows != 1 then +if $rows != 3 then return -1 endi diff --git a/tests/script/tsim/table/date.sim b/tests/script/tsim/table/date.sim index 218049d329..f2361cf4f5 100644 --- a/tests/script/tsim/table/date.sim +++ b/tests/script/tsim/table/date.sim @@ -24,18 +24,18 @@ if $data00 != @17-01-01 08:00:00.001@ then endi print =============== step2 -sql insert into $tb values ('2017-08-28 00:23:46.429+ 1a', 2) -#sql insert into $tb values ('2017-08-28 00:23:46cd .429', 2) +sql_error insert into $tb values ('2017-08-28 00:23:46.429+ 1a', 2) +sql_error insert into $tb values ('2017-08-28 00:23:46cd .429', 2) sql select ts from $tb -if $rows != 2 then +if $rows != 1 then return -1 endi print =============== step3 -#sql insert into $tb values ('1970-01-01 08:00:00.000', 3) -#sql insert into $tb values ('1970-01-01 08:00:00.000', 3) +sql_error insert into $tb values ('1970-01-01 08:00:00.000', 3) +sql_error insert into $tb values ('1970-01-01 08:00:00.000', 3) sql select ts from $tb -if $rows != 2 then +if $rows != 1 then return -1 endi @@ -54,7 +54,7 @@ print =============== step5 sql_error insert into $tb values ('9999-12-31 213:59:59.999', 13) sql select ts from $tb print $rows -if $rows != 8 then +if $rows != 7 then return -1 endi @@ -62,7 +62,7 @@ print =============== step6 sql_error insert into $tb values ('9999-12-99 23:59:59.999', 13) sql select ts from $tb -if $rows != 8 then +if $rows != 7 then return -1 endi diff --git a/tests/script/tsim/table/int.sim b/tests/script/tsim/table/int.sim index f84858c7d0..7e3cefc7ca 100644 --- a/tests/script/tsim/table/int.sim +++ b/tests/script/tsim/table/int.sim @@ -24,12 +24,10 @@ if $data01 != NULL then endi print =============== step2 -sql insert into $tb values (now+1m, -2147483648) -x step2 - return -1 -step2: -sql insert into $tb values (now+1m, NULL) +sql insert into $tb values (now+1m, -2147483648) +sql insert into $tb values (now+2m, NULL) sql select * from $tb order by ts desc -if $rows != 2 then +if $rows != 3 then return -1 endi if $data01 != NULL then @@ -37,9 +35,9 @@ if $data01 != NULL then endi print =============== step3 -sql insert into $tb values (now+2m, 2147483647) +sql insert into $tb values (now+3m, 2147483647) sql select * from $tb order by ts desc -if $rows != 3 then +if $rows != 4 then return -1 endi if $data01 != 2147483647 then @@ -47,12 +45,10 @@ if $data01 != 2147483647 then endi print =============== step4 -sql insert into $tb values (now+3m, 2147483648) -x step4 - return -1 -step4: -sql insert into $tb values (now+3m, NULL) +sql_error insert into $tb values (now+4m, 2147483648) +sql insert into $tb values (now+5m, NULL) sql select * from $tb order by ts desc -if $rows != 4 then +if $rows != 5 then return -1 endi if $data01 != NULL then @@ -60,10 +56,10 @@ if $data01 != NULL then endi print =============== step5 -sql_error insert into $tb values (now+4m, a2) -sql insert into $tb values (now+4m, 0) +sql_error insert into $tb values (now+6m, a2) +sql insert into $tb values (now+7m, 0) sql select * from $tb order by ts desc -if $rows != 5 then +if $rows != 6 then return -1 endi if $data01 != 0 then @@ -71,10 +67,10 @@ if $data01 != 0 then endi print =============== step6 -sql_error insert into $tb values (now+5m, 2a) -sql insert into $tb values (now+5m, 2) +sql_error insert into $tb values (now+8m, 2a) +sql insert into $tb values (now+9m, 2) sql select * from $tb order by ts desc -if $rows != 6 then +if $rows != 7 then return -1 endi if $data01 != 2 then @@ -82,10 +78,10 @@ if $data01 != 2 then endi print =============== step7 -sql_error insert into $tb values (now+6m, 2a'1) -sql insert into $tb values (now+6m, 2) +sql_error insert into $tb values (now+10m, 2a'1) +sql insert into $tb values (now+11m, 2) sql select * from $tb order by ts desc -if $rows != 7 then +if $rows != 8 then return -1 endi if $data01 != 2 then @@ -93,9 +89,9 @@ if $data01 != 2 then endi print =============== step8 -sql insert into $tb values (now+8m, "NULL") +sql insert into $tb values (now+12m, "NULL") sql select * from $tb order by ts desc -if $rows != 8 then +if $rows != 9 then return -1 endi if $data01 != NULL then @@ -103,9 +99,9 @@ if $data01 != NULL then endi print =============== step9 -sql insert into $tb values (now+9m, 'NULL') +sql insert into $tb values (now+13m, 'NULL') sql select * from $tb order by ts desc -if $rows != 9 then +if $rows != 10 then return -1 endi if $data01 != NULL then @@ -113,9 +109,9 @@ if $data01 != NULL then endi print =============== step10 -sql insert into $tb values (now+10m, -123) +sql insert into $tb values (now+14m, -123) sql select * from $tb order by ts desc -if $rows != 10 then +if $rows != 11 then return -1 endi if $data01 != -123 then diff --git a/tests/script/tsim/table/limit.sim b/tests/script/tsim/table/limit.sim index 0a07ee3efa..d20938367e 100644 --- a/tests/script/tsim/table/limit.sim +++ b/tests/script/tsim/table/limit.sim @@ -12,10 +12,10 @@ $db = $dbPrefix . $i $tb = $tbPrefix . $i print =================== step 0 -sql create database $db +sql create database $db vgroups 8 sql use $db sql show vgroups -if $rows != 0 then +if $rows != 8 then return -1 endi diff --git a/tests/script/tsim/table/smallint.sim b/tests/script/tsim/table/smallint.sim index c81681c316..87140c561a 100644 --- a/tests/script/tsim/table/smallint.sim +++ b/tests/script/tsim/table/smallint.sim @@ -25,12 +25,10 @@ if $data01 != NULL then endi print =============== step2 -sql insert into $tb values (now+1m, -32768) -x step2 - return -1 -step2: -sql insert into $tb values (now+1m, NULL) +sql insert into $tb values (now+1m, -32768) +sql insert into $tb values (now+2m, NULL) sql select * from $tb order by ts desc -if $rows != 2 then +if $rows != 3 then return -1 endi if $data01 != NULL then @@ -38,9 +36,9 @@ if $data01 != NULL then endi print =============== step3 -sql insert into $tb values (now+2m, 32767) +sql insert into $tb values (now+3m, 32767) sql select * from $tb order by ts desc -if $rows != 3 then +if $rows != 4 then return -1 endi if $data01 != 32767 then @@ -48,12 +46,12 @@ if $data01 != 32767 then endi print =============== step4 -sql insert into $tb values (now+3m, 32768) -x step4 +sql insert into $tb values (now+4m, 32768) -x step4 return -1 step4: -sql insert into $tb values (now+3m, NULL) +sql insert into $tb values (now+5m, NULL) sql select * from $tb order by ts desc -if $rows != 4 then +if $rows != 5 then return -1 endi if $data01 != NULL then @@ -61,10 +59,10 @@ if $data01 != NULL then endi print =============== step5 -sql_error insert into $tb values (now+4m, a2) -sql insert into $tb values (now+4m, 0) +sql_error insert into $tb values (now+6m, a2) +sql insert into $tb values (now+7m, 0) sql select * from $tb order by ts desc -if $rows != 5 then +if $rows != 6 then return -1 endi if $data01 != 0 then @@ -72,10 +70,10 @@ if $data01 != 0 then endi print =============== step6 -sql_error insert into $tb values (now+5m, 2a) -sql insert into $tb values (now+5m, 2) +sql_error insert into $tb values (now+8m, 2a) +sql insert into $tb values (now+9m, 2) sql select * from $tb order by ts desc -if $rows != 6 then +if $rows != 7 then return -1 endi if $data01 != 2 then @@ -83,16 +81,16 @@ if $data01 != 2 then endi print =============== step7 -sql_error insert into $tb values (now+6m, 2a'1) -sql insert into $tb values (now+6m, 2) +sql_error insert into $tb values (now+10m, 2a'1) +sql insert into $tb values (now+11m, 2) sql select * from $tb order by ts desc -if $rows != 7 then +if $rows != 8 then return -1 endi if $data01 != 2 then return -1 endi - +return sql drop database $db sql show databases if $rows != 2 then diff --git a/tests/script/tsim/table/table.sim b/tests/script/tsim/table/table.sim index 6a706c979f..65774dd03c 100644 --- a/tests/script/tsim/table/table.sim +++ b/tests/script/tsim/table/table.sim @@ -197,16 +197,15 @@ if $data01 != 7 then endi print =============== step10 -$i = 1 $tb = $tbPrefix . $i -sql create table $tb (ts timestamp, val tinyint, val2 tinyint) +sql_error create table $tb (ts timestamp, val tinyint, val2 tinyint) sql show tables if $rows != 7 then return -1 endi print =============== step11 -sql create table $tb (ts timestamp, val float, val2 double) +sql_error create table $tb (ts timestamp, val float, val2 double) sql show tables if $rows != 7 then return -1 diff --git a/tests/script/tsim/table/tinyint.sim b/tests/script/tsim/table/tinyint.sim index 089fab0bfa..4764600b5b 100644 --- a/tests/script/tsim/table/tinyint.sim +++ b/tests/script/tsim/table/tinyint.sim @@ -24,12 +24,10 @@ if $data01 != NULL then endi print =============== step2 -sql insert into $tb values (now+1m, -128) -x step2 - return -1 -step2: -sql insert into $tb values (now+1m, NULL) +sql insert into $tb values (now+1m, -128) +sql insert into $tb values (now+2m, NULL) sql select * from $tb order by ts desc -if $rows != 2 then +if $rows != 3 then return -1 endi if $data01 != NULL then @@ -37,9 +35,9 @@ if $data01 != NULL then endi print =============== step3 -sql insert into $tb values (now+2m, 127) +sql insert into $tb values (now+3m, 127) sql select * from $tb order by ts desc -if $rows != 3 then +if $rows != 4 then return -1 endi if $data01 != 127 then @@ -47,12 +45,12 @@ if $data01 != 127 then endi print =============== step4 -sql insert into $tb values (now+3m, 128) -x step4 +sql insert into $tb values (now+4m, 128) -x step4 return -1 step4: -sql insert into $tb values (now+3m, NULL) +sql insert into $tb values (now+5m, NULL) sql select * from $tb -if $rows != 4 then +if $rows != 5 then return -1 endi if $data01 != NULL then @@ -60,10 +58,10 @@ if $data01 != NULL then endi print =============== step5 -sql_error insert into $tb values (now+4m, a2) -sql insert into $tb values (now+4m, 0) +sql_error insert into $tb values (now+6m, a2) +sql insert into $tb values (now+7m, 0) sql select * from $tb order by ts desc -if $rows != 5 then +if $rows != 6 then return -1 endi if $data01 != 0 then @@ -71,10 +69,10 @@ if $data01 != 0 then endi print =============== step6 -sql_error insert into $tb values (now+5m, 2a) -sql insert into $tb values (now+5m, 2) +sql_error insert into $tb values (now+8m, 2a) +sql insert into $tb values (now+9m, 2) sql select * from $tb order by ts desc -if $rows != 6 then +if $rows != 7 then return -1 endi if $data01 != 2 then @@ -82,10 +80,10 @@ if $data01 != 2 then endi print =============== step7 -sql_error insert into $tb values (now+6m, 2a'1) -sql insert into $tb values (now+6m, 2) +sql_error insert into $tb values (now+10m, 2a'1) +sql insert into $tb values (now+11m, 2) sql select * from $tb order by ts desc -if $rows != 7 then +if $rows != 8 then return -1 endi if $data01 != 2 then diff --git a/tests/script/tsim/table/vgroup.sim b/tests/script/tsim/table/vgroup.sim index 902415400e..2925e9de4c 100644 --- a/tests/script/tsim/table/vgroup.sim +++ b/tests/script/tsim/table/vgroup.sim @@ -12,10 +12,10 @@ $db = $dbPrefix . $i $tb = $tbPrefix . $i print =================== step 1 -sql create database $db +sql create database $db vgroups 4 sql use $db sql show vgroups -if $rows != 0 then +if $rows != 4 then return -1 endi @@ -24,7 +24,7 @@ sql create table table2 (ts timestamp, speed int) sql create table table3 (ts timestamp, speed int) sql create table table4 (ts timestamp, speed int) sql show vgroups -if $rows != 1 then +if $rows != 4 then return -1 endi @@ -33,7 +33,7 @@ sql create table table6 (ts timestamp, speed int) sql create table table7 (ts timestamp, speed int) sql create table table8 (ts timestamp, speed int) sql show vgroups -if $rows != 2 then +if $rows != 4 then return -1 endi @@ -42,7 +42,7 @@ sql create table table10 (ts timestamp, speed int) sql create table table11 (ts timestamp, speed int) sql create table table12 (ts timestamp, speed int) sql show vgroups -if $rows != 3 then +if $rows != 4 then return -1 endi @@ -54,7 +54,7 @@ endi sql drop table table13 sql show vgroups -if $rows != 3 then +if $rows != 4 then return -1 endi @@ -68,10 +68,10 @@ print =================== step 2 $i = 1 $db = $dbPrefix . $i -sql create database $db +sql create database $db vgroups 2 sql use $db sql show vgroups -if $rows != 0 then +if $rows != 2 then return -1 endi @@ -84,13 +84,13 @@ $db = $dbPrefix . $i sql use $db sql create table table2 (ts timestamp, speed int) sql show vgroups -if $rows != 1 then +if $rows != 2 then return -1 endi sql drop table table2 sql show vgroups -if $rows != 0 then +if $rows != 2 then return -1 endi @@ -100,7 +100,7 @@ sql create table table3 (ts timestamp, speed int) sql create table table4 (ts timestamp, speed int) sql drop table table1 sql show vgroups -if $rows != 1 then +if $rows != 2 then return -1 endi @@ -129,7 +129,7 @@ sql create database $db sql use $db sql show databases -if $rows != 5 then +if $rows != 7 then return -1 endi -- GitLab From 162fbbb2a2b8cee45df881955ca2ee2702db4987 Mon Sep 17 00:00:00 2001 From: Ganlin Zhao Date: Thu, 14 Jul 2022 16:06:14 +0800 Subject: [PATCH 123/153] comment out unstable test cases --- tests/system-test/fulltest.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/system-test/fulltest.sh b/tests/system-test/fulltest.sh index 2c116113bc..ef4ac83bb7 100755 --- a/tests/system-test/fulltest.sh +++ b/tests/system-test/fulltest.sh @@ -22,7 +22,7 @@ python3 ./test.py -f 1-insert/test_stmt_muti_insert_query.py python3 ./test.py -f 1-insert/test_stmt_set_tbname_tag.py python3 ./test.py -f 1-insert/alter_stable.py python3 ./test.py -f 1-insert/alter_table.py -python3 ./test.py -f 1-insert/insertWithMoreVgroup.py +#python3 ./test.py -f 1-insert/insertWithMoreVgroup.py python3 ./test.py -f 1-insert/table_comment.py python3 ./test.py -f 1-insert/time_range_wise.py python3 ./test.py -f 1-insert/block_wise.py @@ -120,7 +120,7 @@ python3 ./test.py -f 2-query/irate.py python3 ./test.py -f 2-query/and_or_for_byte.py python3 ./test.py -f 2-query/count_partition.py python3 ./test.py -f 2-query/function_null.py -python3 ./test.py -f 2-query/queryQnode.py +#python3 ./test.py -f 2-query/queryQnode.py python3 ./test.py -f 2-query/max_partition.py -- GitLab From ddb39a8dc236284ae9d26a46a26aac34c3825369 Mon Sep 17 00:00:00 2001 From: Xiaoyu Wang Date: Thu, 14 Jul 2022 16:06:28 +0800 Subject: [PATCH 124/153] fix: some problems of planner --- include/libs/nodes/plannodes.h | 7 ++- source/libs/command/src/explain.c | 20 +++---- source/libs/executor/src/cachescanoperator.c | 8 +-- source/libs/executor/src/executorimpl.c | 8 +-- source/libs/function/src/builtinsimpl.c | 53 +++++++++---------- source/libs/nodes/src/nodesCodeFuncs.c | 38 +++++++++++-- source/libs/planner/src/planPhysiCreater.c | 23 ++++++-- source/libs/planner/src/planSpliter.c | 3 ++ source/libs/planner/test/planBasicTest.cpp | 2 + source/libs/planner/test/planSubqueryTest.cpp | 2 + 10 files changed, 109 insertions(+), 55 deletions(-) diff --git a/include/libs/nodes/plannodes.h b/include/libs/nodes/plannodes.h index 6a865b4e2a..b807aeca22 100644 --- a/include/libs/nodes/plannodes.h +++ b/include/libs/nodes/plannodes.h @@ -275,7 +275,12 @@ typedef struct SScanPhysiNode { typedef SScanPhysiNode STagScanPhysiNode; typedef SScanPhysiNode SBlockDistScanPhysiNode; -typedef SScanPhysiNode SLastRowScanPhysiNode; + +typedef struct SLastRowScanPhysiNode { + SScanPhysiNode scan; + SNodeList* pGroupTags; + bool groupSort; +} SLastRowScanPhysiNode; typedef struct SSystemTableScanPhysiNode { SScanPhysiNode scan; diff --git a/source/libs/command/src/explain.c b/source/libs/command/src/explain.c index fde53b7064..3fa419e220 100644 --- a/source/libs/command/src/explain.c +++ b/source/libs/command/src/explain.c @@ -206,7 +206,7 @@ int32_t qExplainGenerateResChildren(SPhysiNode *pNode, SExplainGroup *group, SNo } case QUERY_NODE_PHYSICAL_PLAN_LAST_ROW_SCAN: { SLastRowScanPhysiNode *lastRowPhysiNode = (SLastRowScanPhysiNode *)pNode; - pPhysiChildren = lastRowPhysiNode->node.pChildren; + pPhysiChildren = lastRowPhysiNode->scan.node.pChildren; break; } case QUERY_NODE_PHYSICAL_PLAN_GROUP_SORT: { @@ -1209,19 +1209,19 @@ int32_t qExplainResNodeToRowsImpl(SExplainResNode *pResNode, SExplainCtx *ctx, i } case QUERY_NODE_PHYSICAL_PLAN_LAST_ROW_SCAN: { SLastRowScanPhysiNode *pLastRowNode = (SLastRowScanPhysiNode *)pNode; - EXPLAIN_ROW_NEW(level, EXPLAIN_LASTROW_SCAN_FORMAT, pLastRowNode->tableName.tname); + EXPLAIN_ROW_NEW(level, EXPLAIN_LASTROW_SCAN_FORMAT, pLastRowNode->scan.tableName.tname); EXPLAIN_ROW_APPEND(EXPLAIN_LEFT_PARENTHESIS_FORMAT); if (pResNode->pExecInfo) { QRY_ERR_RET(qExplainBufAppendExecInfo(pResNode->pExecInfo, tbuf, &tlen)); EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT); } - EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT, pLastRowNode->pScanCols->length); + EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT, pLastRowNode->scan.pScanCols->length); EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT); - if (pLastRowNode->pScanPseudoCols) { - EXPLAIN_ROW_APPEND(EXPLAIN_PSEUDO_COLUMNS_FORMAT, pLastRowNode->pScanPseudoCols->length); + if (pLastRowNode->scan.pScanPseudoCols) { + EXPLAIN_ROW_APPEND(EXPLAIN_PSEUDO_COLUMNS_FORMAT, pLastRowNode->scan.pScanPseudoCols->length); EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT); } - EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pLastRowNode->node.pOutputDataBlockDesc->totalRowSize); + EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pLastRowNode->scan.node.pOutputDataBlockDesc->totalRowSize); EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT); EXPLAIN_ROW_APPEND(EXPLAIN_RIGHT_PARENTHESIS_FORMAT); EXPLAIN_ROW_END(); @@ -1230,15 +1230,15 @@ int32_t qExplainResNodeToRowsImpl(SExplainResNode *pResNode, SExplainCtx *ctx, i if (verbose) { EXPLAIN_ROW_NEW(level + 1, EXPLAIN_OUTPUT_FORMAT); EXPLAIN_ROW_APPEND(EXPLAIN_COLUMNS_FORMAT, - nodesGetOutputNumFromSlotList(pLastRowNode->node.pOutputDataBlockDesc->pSlots)); + nodesGetOutputNumFromSlotList(pLastRowNode->scan.node.pOutputDataBlockDesc->pSlots)); EXPLAIN_ROW_APPEND(EXPLAIN_BLANK_FORMAT); - EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pLastRowNode->node.pOutputDataBlockDesc->outputRowSize); + EXPLAIN_ROW_APPEND(EXPLAIN_WIDTH_FORMAT, pLastRowNode->scan.node.pOutputDataBlockDesc->outputRowSize); EXPLAIN_ROW_END(); QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1)); - if (pLastRowNode->node.pConditions) { + if (pLastRowNode->scan.node.pConditions) { EXPLAIN_ROW_NEW(level + 1, EXPLAIN_FILTER_FORMAT); - QRY_ERR_RET(nodesNodeToSQL(pLastRowNode->node.pConditions, tbuf + VARSTR_HEADER_SIZE, + QRY_ERR_RET(nodesNodeToSQL(pLastRowNode->scan.node.pConditions, tbuf + VARSTR_HEADER_SIZE, TSDB_EXPLAIN_RESULT_ROW_SIZE, &tlen)); EXPLAIN_ROW_END(); QRY_ERR_RET(qExplainResAppendRow(ctx, tbuf, tlen, level + 1)); diff --git a/source/libs/executor/src/cachescanoperator.c b/source/libs/executor/src/cachescanoperator.c index 0f6817cd6b..9034397d0f 100644 --- a/source/libs/executor/src/cachescanoperator.c +++ b/source/libs/executor/src/cachescanoperator.c @@ -40,10 +40,10 @@ SOperatorInfo* createLastrowScanOperator(SLastRowScanPhysiNode* pScanNode, SRead pInfo->pTableList = pTableList; pInfo->readHandle = *readHandle; - pInfo->pRes = createResDataBlock(pScanNode->node.pOutputDataBlockDesc); + pInfo->pRes = createResDataBlock(pScanNode->scan.node.pOutputDataBlockDesc); int32_t numOfCols = 0; - pInfo->pColMatchInfo = extractColMatchInfo(pScanNode->pScanCols, pScanNode->node.pOutputDataBlockDesc, &numOfCols, + pInfo->pColMatchInfo = extractColMatchInfo(pScanNode->scan.pScanCols, pScanNode->scan.node.pOutputDataBlockDesc, &numOfCols, COL_MATCH_FROM_COL_ID); int32_t code = extractTargetSlotId(pInfo->pColMatchInfo, pTaskInfo, &pInfo->pSlotIds); if (code != TSDB_CODE_SUCCESS) { @@ -53,10 +53,10 @@ SOperatorInfo* createLastrowScanOperator(SLastRowScanPhysiNode* pScanNode, SRead tsdbLastRowReaderOpen(readHandle->vnode, LASTROW_RETRIEVE_TYPE_SINGLE, pTableList, taosArrayGetSize(pInfo->pColMatchInfo), &pInfo->pLastrowReader); - if (pScanNode->pScanPseudoCols != NULL) { + if (pScanNode->scan.pScanPseudoCols != NULL) { SExprSupp* pPseudoExpr = &pInfo->pseudoExprSup; - pPseudoExpr->pExprInfo = createExprInfo(pScanNode->pScanPseudoCols, NULL, &pPseudoExpr->numOfExprs); + pPseudoExpr->pExprInfo = createExprInfo(pScanNode->scan.pScanPseudoCols, NULL, &pPseudoExpr->numOfExprs); pPseudoExpr->pCtx = createSqlFunctionCtx(pPseudoExpr->pExprInfo, pPseudoExpr->numOfExprs, &pPseudoExpr->rowEntryInfoOffset); } diff --git a/source/libs/executor/src/executorimpl.c b/source/libs/executor/src/executorimpl.c index 674bbfef0b..851e3bc5bf 100644 --- a/source/libs/executor/src/executorimpl.c +++ b/source/libs/executor/src/executorimpl.c @@ -4444,21 +4444,21 @@ SOperatorInfo* createOperatorTree(SPhysiNode* pPhyNode, SExecTaskInfo* pTaskInfo // return NULL; // } - int32_t code = extractTableSchemaInfo(pHandle, pScanNode->uid, pTaskInfo); + int32_t code = extractTableSchemaInfo(pHandle, pScanNode->scan.uid, pTaskInfo); if (code != TSDB_CODE_SUCCESS) { pTaskInfo->code = code; return NULL; } pTableListInfo->pTableList = taosArrayInit(4, sizeof(STableKeyInfo)); - if (pScanNode->tableType == TSDB_SUPER_TABLE) { - code = vnodeGetAllTableList(pHandle->vnode, pScanNode->uid, pTableListInfo->pTableList); + if (pScanNode->scan.tableType == TSDB_SUPER_TABLE) { + code = vnodeGetAllTableList(pHandle->vnode, pScanNode->scan.uid, pTableListInfo->pTableList); if (code != TSDB_CODE_SUCCESS) { pTaskInfo->code = terrno; return NULL; } } else { // Create one table group. - STableKeyInfo info = {.lastKey = 0, .uid = pScanNode->uid, .groupId = 0}; + STableKeyInfo info = {.lastKey = 0, .uid = pScanNode->scan.uid, .groupId = 0}; taosArrayPush(pTableListInfo->pTableList, &info); } diff --git a/source/libs/function/src/builtinsimpl.c b/source/libs/function/src/builtinsimpl.c index e622c0c1af..320474ffb3 100644 --- a/source/libs/function/src/builtinsimpl.c +++ b/source/libs/function/src/builtinsimpl.c @@ -80,7 +80,7 @@ typedef struct STopBotRes { } STopBotRes; typedef struct SFirstLastRes { - bool hasResult; + bool hasResult; // used for last_row function only, isNullRes in SResultRowEntry can not be passed to downstream.So, // this attribute is required bool isNull; @@ -402,7 +402,6 @@ typedef struct SGroupKeyInfo { (x) += step; \ } while (0) - #define STATE_COMP(_op, _lval, _param) STATE_COMP_IMPL(_op, _lval, GET_STATE_VAL(_param)) #define GET_STATE_VAL(param) ((param.nType == TSDB_DATA_TYPE_BIGINT) ? (param.i) : (param.d)) @@ -986,8 +985,8 @@ int32_t avgFunctionMerge(SqlFunctionCtx* pCtx) { int32_t start = pInput->startRowIndex; - for(int32_t i = start; i < start + pInput->numOfRows; ++i) { - char* data = colDataGetData(pCol, i); + for (int32_t i = start; i < start + pInput->numOfRows; ++i) { + char* data = colDataGetData(pCol, i); SAvgRes* pInputInfo = (SAvgRes*)varDataVal(data); avgTransferInfo(pInputInfo, pInfo); } @@ -2559,8 +2558,8 @@ int32_t apercentileFunctionMerge(SqlFunctionCtx* pCtx) { int32_t start = pInput->startRowIndex; - for(int32_t i = start; i < start + pInput->numOfRows; ++i) { - char* data = colDataGetData(pCol, i); + for (int32_t i = start; i < start + pInput->numOfRows; ++i) { + char* data = colDataGetData(pCol, i); SAPercentileInfo* pInputInfo = (SAPercentileInfo*)varDataVal(data); apercentileTransferInfo(pInputInfo, pInfo); } @@ -2925,8 +2924,8 @@ static int32_t firstLastFunctionMergeImpl(SqlFunctionCtx* pCtx, bool isFirstQuer int32_t start = pInput->startRowIndex; int32_t numOfElems = 0; - for(int32_t i = start; i < start + pInput->numOfRows; ++i) { - char* data = colDataGetData(pCol, i); + for (int32_t i = start; i < start + pInput->numOfRows; ++i) { + char* data = colDataGetData(pCol, i); SFirstLastRes* pInputInfo = (SFirstLastRes*)varDataVal(data); firstLastTransferInfo(pCtx, pInputInfo, pInfo, isFirstQuery); if (!numOfElems) { @@ -2951,7 +2950,7 @@ int32_t firstLastFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock) { pResInfo->isNullRes = (pResInfo->numOfRes == 0) ? 1 : 0; SFirstLastRes* pRes = GET_ROWCELL_INTERBUF(pResInfo); - colDataAppend(pCol, pBlock->info.rows, pRes->buf, pRes->isNull||pResInfo->isNullRes); + colDataAppend(pCol, pBlock->info.rows, pRes->buf, pRes->isNull || pResInfo->isNullRes); // handle selectivity STuplePos* pTuplePos = (STuplePos*)(pRes->buf + pRes->bytes + sizeof(TSKEY)); @@ -3754,8 +3753,8 @@ int32_t spreadFunctionMerge(SqlFunctionCtx* pCtx) { int32_t start = pInput->startRowIndex; - for(int32_t i = start; i < start + pInput->numOfRows; ++i) { - char* data = colDataGetData(pCol, i); + for (int32_t i = start; i < start + pInput->numOfRows; ++i) { + char* data = colDataGetData(pCol, i); SSpreadInfo* pInputInfo = (SSpreadInfo*)varDataVal(data); spreadTransferInfo(pInputInfo, pInfo); } @@ -3926,8 +3925,8 @@ int32_t elapsedFunctionMerge(SqlFunctionCtx* pCtx) { int32_t start = pInput->startRowIndex; - for(int32_t i = start; i < start + pInput->numOfRows; ++i) { - char* data = colDataGetData(pCol, i); + for (int32_t i = start; i < start + pInput->numOfRows; ++i) { + char* data = colDataGetData(pCol, i); SElapsedInfo* pInputInfo = (SElapsedInfo*)varDataVal(data); elapsedTransferInfo(pInputInfo, pInfo); } @@ -4191,13 +4190,9 @@ static int32_t histogramFunctionImpl(SqlFunctionCtx* pCtx, bool isPartial) { return TSDB_CODE_SUCCESS; } -int32_t histogramFunction(SqlFunctionCtx* pCtx) { - return histogramFunctionImpl(pCtx, false); -} +int32_t histogramFunction(SqlFunctionCtx* pCtx) { return histogramFunctionImpl(pCtx, false); } -int32_t histogramFunctionPartial(SqlFunctionCtx* pCtx) { - return histogramFunctionImpl(pCtx, true); -} +int32_t histogramFunctionPartial(SqlFunctionCtx* pCtx) { return histogramFunctionImpl(pCtx, true); } static void histogramTransferInfo(SHistoFuncInfo* pInput, SHistoFuncInfo* pOutput) { pOutput->normalized = pInput->normalized; @@ -4219,8 +4214,8 @@ int32_t histogramFunctionMerge(SqlFunctionCtx* pCtx) { int32_t start = pInput->startRowIndex; - for(int32_t i = start; i < start + pInput->numOfRows; ++i) { - char* data = colDataGetData(pCol, i); + for (int32_t i = start; i < start + pInput->numOfRows; ++i) { + char* data = colDataGetData(pCol, i); SHistoFuncInfo* pInputInfo = (SHistoFuncInfo*)varDataVal(data); histogramTransferInfo(pInputInfo, pInfo); } @@ -4267,9 +4262,9 @@ int32_t histogramFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock) { int32_t histogramPartialFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock) { SResultRowEntryInfo* pResInfo = GET_RES_INFO(pCtx); - SHistoFuncInfo* pInfo = GET_ROWCELL_INTERBUF(GET_RES_INFO(pCtx)); - int32_t resultBytes = getHistogramInfoSize(); - char* res = taosMemoryCalloc(resultBytes + VARSTR_HEADER_SIZE, sizeof(char)); + SHistoFuncInfo* pInfo = GET_ROWCELL_INTERBUF(GET_RES_INFO(pCtx)); + int32_t resultBytes = getHistogramInfoSize(); + char* res = taosMemoryCalloc(resultBytes + VARSTR_HEADER_SIZE, sizeof(char)); memcpy(varDataVal(res), pInfo, resultBytes); varDataSetLen(res, resultBytes); @@ -4440,8 +4435,8 @@ int32_t hllFunctionMerge(SqlFunctionCtx* pCtx) { int32_t start = pInput->startRowIndex; - for(int32_t i = start; i < start + pInput->numOfRows; ++i) { - char* data = colDataGetData(pCol, i); + for (int32_t i = start; i < start + pInput->numOfRows; ++i) { + char* data = colDataGetData(pCol, i); SHLLInfo* pInputInfo = (SHLLInfo*)varDataVal(data); hllTransferInfo(pInputInfo, pInfo); } @@ -5998,7 +5993,7 @@ int32_t lastrowFunction(SqlFunctionCtx* pCtx) { SInputColumnInfoData* pInput = &pCtx->input; SColumnInfoData* pInputCol = pInput->pData[0]; - int32_t type = pInputCol->info.type; + int32_t type = pInputCol->info.type; int32_t bytes = pInputCol->info.bytes; pInfo->bytes = bytes; @@ -6010,7 +6005,6 @@ int32_t lastrowFunction(SqlFunctionCtx* pCtx) { char* data = colDataGetData(pInputCol, i); TSKEY cts = getRowPTs(pInput->pPTS, i); if (pResInfo->numOfRes == 0 || pInfo->ts < cts) { - if (colDataIsNull_s(pInputCol, i)) { pInfo->isNull = true; } else { @@ -6023,7 +6017,6 @@ int32_t lastrowFunction(SqlFunctionCtx* pCtx) { } pInfo->ts = cts; - pInfo->hasResult = true; pResInfo->numOfRes = 1; if (pCtx->subsidiaries.num > 0) { @@ -6034,6 +6027,8 @@ int32_t lastrowFunction(SqlFunctionCtx* pCtx) { copyTupleData(pCtx, i, pCtx->pSrcBlock, pTuplePos); } } + + pInfo->hasResult = true; } } diff --git a/source/libs/nodes/src/nodesCodeFuncs.c b/source/libs/nodes/src/nodesCodeFuncs.c index 75f9cd7b48..2d24b01ca1 100644 --- a/source/libs/nodes/src/nodesCodeFuncs.c +++ b/source/libs/nodes/src/nodesCodeFuncs.c @@ -1468,9 +1468,36 @@ static int32_t jsonToPhysiScanNode(const SJson* pJson, void* pObj) { return code; } -static int32_t physiTagScanNodeToJson(const void* pObj, SJson* pJson) { return physiScanNodeToJson(pObj, pJson); } +static const char* jkLastRowScanPhysiPlanGroupTags = "GroupTags"; +static const char* jkLastRowScanPhysiPlanGroupSort = "GroupSort"; -static int32_t jsonToPhysiTagScanNode(const SJson* pJson, void* pObj) { return jsonToPhysiScanNode(pJson, pObj); } +static int32_t physiLastRowScanNodeToJson(const void* pObj, SJson* pJson) { + const SLastRowScanPhysiNode* pNode = (const SLastRowScanPhysiNode*)pObj; + + int32_t code = physiScanNodeToJson(pObj, pJson); + if (TSDB_CODE_SUCCESS == code) { + code = nodeListToJson(pJson, jkLastRowScanPhysiPlanGroupTags, pNode->pGroupTags); + } + if (TSDB_CODE_SUCCESS == code) { + code = tjsonAddBoolToObject(pJson, jkLastRowScanPhysiPlanGroupSort, pNode->groupSort); + } + + return code; +} + +static int32_t jsonToPhysiLastRowScanNode(const SJson* pJson, void* pObj) { + SLastRowScanPhysiNode* pNode = (SLastRowScanPhysiNode*)pObj; + + int32_t code = jsonToPhysiScanNode(pJson, pObj); + if (TSDB_CODE_SUCCESS == code) { + code = jsonToNodeList(pJson, jkLastRowScanPhysiPlanGroupTags, &pNode->pGroupTags); + } + if (TSDB_CODE_SUCCESS == code) { + code = tjsonGetBoolValue(pJson, jkLastRowScanPhysiPlanGroupSort, &pNode->groupSort); + } + + return code; +} static const char* jkTableScanPhysiPlanScanCount = "ScanCount"; static const char* jkTableScanPhysiPlanReverseScanCount = "ReverseScanCount"; @@ -4315,8 +4342,9 @@ static int32_t specificNodeToJson(const void* pObj, SJson* pJson) { return logicPlanToJson(pObj, pJson); case QUERY_NODE_PHYSICAL_PLAN_TAG_SCAN: case QUERY_NODE_PHYSICAL_PLAN_BLOCK_DIST_SCAN: + return physiScanNodeToJson(pObj, pJson); case QUERY_NODE_PHYSICAL_PLAN_LAST_ROW_SCAN: - return physiTagScanNodeToJson(pObj, pJson); + return physiLastRowScanNodeToJson(pObj, pJson); case QUERY_NODE_PHYSICAL_PLAN_TABLE_SCAN: case QUERY_NODE_PHYSICAL_PLAN_TABLE_MERGE_SCAN: case QUERY_NODE_PHYSICAL_PLAN_STREAM_SCAN: @@ -4461,8 +4489,10 @@ static int32_t jsonToSpecificNode(const SJson* pJson, void* pObj) { return jsonToLogicPlan(pJson, pObj); case QUERY_NODE_PHYSICAL_PLAN_TAG_SCAN: case QUERY_NODE_PHYSICAL_PLAN_BLOCK_DIST_SCAN: + return jsonToPhysiScanNode(pJson, pObj); case QUERY_NODE_PHYSICAL_PLAN_LAST_ROW_SCAN: - return jsonToPhysiTagScanNode(pJson, pObj); + + return jsonToPhysiLastRowScanNode(pJson, pObj); case QUERY_NODE_PHYSICAL_PLAN_TABLE_SCAN: case QUERY_NODE_PHYSICAL_PLAN_TABLE_MERGE_SCAN: case QUERY_NODE_PHYSICAL_PLAN_STREAM_SCAN: diff --git a/source/libs/planner/src/planPhysiCreater.c b/source/libs/planner/src/planPhysiCreater.c index 8c9c06be35..c4cc31c535 100644 --- a/source/libs/planner/src/planPhysiCreater.c +++ b/source/libs/planner/src/planPhysiCreater.c @@ -481,8 +481,6 @@ static ENodeType getScanOperatorType(EScanType scanType) { return QUERY_NODE_PHYSICAL_PLAN_TABLE_MERGE_SCAN; case SCAN_TYPE_BLOCK_INFO: return QUERY_NODE_PHYSICAL_PLAN_BLOCK_DIST_SCAN; - case SCAN_TYPE_LAST_ROW: - return QUERY_NODE_PHYSICAL_PLAN_LAST_ROW_SCAN; default: break; } @@ -502,6 +500,24 @@ static int32_t createSimpleScanPhysiNode(SPhysiPlanContext* pCxt, SSubplan* pSub return createScanPhysiNodeFinalize(pCxt, pSubplan, pScanLogicNode, pScan, pPhyNode); } +static int32_t createLastRowScanPhysiNode(SPhysiPlanContext* pCxt, SSubplan* pSubplan, SScanLogicNode* pScanLogicNode, + SPhysiNode** pPhyNode) { + SLastRowScanPhysiNode* pScan = + (SLastRowScanPhysiNode*)makePhysiNode(pCxt, (SLogicNode*)pScanLogicNode, QUERY_NODE_PHYSICAL_PLAN_LAST_ROW_SCAN); + if (NULL == pScan) { + return TSDB_CODE_OUT_OF_MEMORY; + } + + pScan->pGroupTags = nodesCloneList(pScanLogicNode->pGroupTags); + if (NULL != pScanLogicNode->pGroupTags && NULL == pScan->pGroupTags) { + nodesDestroyNode((SNode*)pScan); + return TSDB_CODE_OUT_OF_MEMORY; + } + pScan->groupSort = pScanLogicNode->groupSort; + + return createScanPhysiNodeFinalize(pCxt, pSubplan, pScanLogicNode, (SScanPhysiNode*)pScan, pPhyNode); +} + static int32_t createTableScanPhysiNode(SPhysiPlanContext* pCxt, SSubplan* pSubplan, SScanLogicNode* pScanLogicNode, SPhysiNode** pPhyNode) { STableScanPhysiNode* pTableScan = (STableScanPhysiNode*)makePhysiNode(pCxt, (SLogicNode*)pScanLogicNode, @@ -583,8 +599,9 @@ static int32_t createScanPhysiNode(SPhysiPlanContext* pCxt, SSubplan* pSubplan, switch (pScanLogicNode->scanType) { case SCAN_TYPE_TAG: case SCAN_TYPE_BLOCK_INFO: - case SCAN_TYPE_LAST_ROW: return createSimpleScanPhysiNode(pCxt, pSubplan, pScanLogicNode, pPhyNode); + case SCAN_TYPE_LAST_ROW: + return createLastRowScanPhysiNode(pCxt, pSubplan, pScanLogicNode, pPhyNode); case SCAN_TYPE_TABLE: return createTableScanPhysiNode(pCxt, pSubplan, pScanLogicNode, pPhyNode); case SCAN_TYPE_SYSTEM_TABLE: diff --git a/source/libs/planner/src/planSpliter.c b/source/libs/planner/src/planSpliter.c index 7b9d553501..871bcf015b 100644 --- a/source/libs/planner/src/planSpliter.c +++ b/source/libs/planner/src/planSpliter.c @@ -364,6 +364,8 @@ static int32_t stbSplCreatePartWindowNode(SWindowLogicNode* pMergeWindow, SLogic pMergeWindow->node.pTargets = NULL; SNodeList* pChildren = pMergeWindow->node.pChildren; pMergeWindow->node.pChildren = NULL; + SNode* pConditions = pMergeWindow->node.pConditions; + pMergeWindow->node.pConditions = NULL; int32_t code = TSDB_CODE_SUCCESS; SWindowLogicNode* pPartWin = (SWindowLogicNode*)nodesCloneNode((SNode*)pMergeWindow); @@ -373,6 +375,7 @@ static int32_t stbSplCreatePartWindowNode(SWindowLogicNode* pMergeWindow, SLogic if (TSDB_CODE_SUCCESS == code) { pMergeWindow->node.pTargets = pTargets; + pMergeWindow->node.pConditions = pConditions; pPartWin->node.pChildren = pChildren; splSetParent((SLogicNode*)pPartWin); code = stbSplRewriteFuns(pFunc, &pPartWin->pFuncs, &pMergeWindow->pFuncs); diff --git a/source/libs/planner/test/planBasicTest.cpp b/source/libs/planner/test/planBasicTest.cpp index 0d6bab145a..8482698cd3 100644 --- a/source/libs/planner/test/planBasicTest.cpp +++ b/source/libs/planner/test/planBasicTest.cpp @@ -108,6 +108,8 @@ TEST_F(PlanBasicTest, lastRowFunc) { run("SELECT LAST_ROW(c1) FROM st1"); + run("SELECT LAST_ROW(c1) FROM st1 PARTITION BY TBNAME"); + run("SELECT LAST_ROW(c1), SUM(c3) FROM t1"); } diff --git a/source/libs/planner/test/planSubqueryTest.cpp b/source/libs/planner/test/planSubqueryTest.cpp index 4d4f780473..2ba3794d5c 100644 --- a/source/libs/planner/test/planSubqueryTest.cpp +++ b/source/libs/planner/test/planSubqueryTest.cpp @@ -36,6 +36,8 @@ TEST_F(PlanSubqeuryTest, basic) { run("SELECT * FROM (SELECT NOW() FROM t1)"); run("SELECT NOW() FROM (SELECT * FROM t1) ORDER BY ts"); + + run("SELECT * FROM (SELECT AVG(c1) a FROM st1 INTERVAL(10s)) WHERE a > 1"); } TEST_F(PlanSubqeuryTest, doubleGroupBy) { -- GitLab From 024c42eafdd8ac264d45b970e5fd12983d2dbdfd Mon Sep 17 00:00:00 2001 From: plum-lihui Date: Thu, 14 Jul 2022 16:06:30 +0800 Subject: [PATCH 125/153] test:add test case for tmq --- tests/system-test/7-tmq/tmqCommon.py | 6 +- tests/system-test/7-tmq/tmqDelete-1ctb.py | 275 ++++++++++++++++++++++ tests/system-test/7-tmq/tmqUpdate-1ctb.py | 12 +- 3 files changed, 286 insertions(+), 7 deletions(-) create mode 100644 tests/system-test/7-tmq/tmqDelete-1ctb.py diff --git a/tests/system-test/7-tmq/tmqCommon.py b/tests/system-test/7-tmq/tmqCommon.py index 060e17c11f..151558a33a 100644 --- a/tests/system-test/7-tmq/tmqCommon.py +++ b/tests/system-test/7-tmq/tmqCommon.py @@ -428,7 +428,7 @@ class TMQCom: pThread.start() return pThread - def checkFileContent(self, consumerId, queryString): + def checkFileContent(self, consumerId, queryString, skipRowsOfCons=0): buildPath = tdCom.getBuildPath() cfgPath = tdCom.getClientCfgPath() dstFile = '%s/../log/dstrows_%d.txt'%(cfgPath, consumerId) @@ -445,6 +445,10 @@ class TMQCom: # skip first line for it is schema queryFile.readline() + # skip offset for consumer + for i in range(0,skipRowsOfCons): + consumeFile.readline() + lines = 0 while True: dst = queryFile.readline() diff --git a/tests/system-test/7-tmq/tmqDelete-1ctb.py b/tests/system-test/7-tmq/tmqDelete-1ctb.py new file mode 100644 index 0000000000..c5f7510a07 --- /dev/null +++ b/tests/system-test/7-tmq/tmqDelete-1ctb.py @@ -0,0 +1,275 @@ + +import taos +import sys +import time +import socket +import os +import threading +from enum import Enum + +from util.log import * +from util.sql import * +from util.cases import * +from util.dnodes import * +sys.path.append("./7-tmq") +from tmqCommon import * + +class TDTestCase: + def __init__(self): + self.snapshot = 0 + self.vgroups = 4 + self.ctbNum = 1 + self.rowsPerTbl = 10000 + + def init(self, conn, logSql): + tdLog.debug(f"start to excute {__file__}") + tdSql.init(conn.cursor(), False) + + def prepareTestEnv(self): + tdLog.printNoPrefix("======== prepare test env include database, stable, ctables, and insert data: ") + paraDict = {'dbName': 'dbt', + 'dropFlag': 1, + 'event': '', + 'vgroups': 4, + 'stbName': 'stb', + 'colPrefix': 'c', + 'tagPrefix': 't', + 'colSchema': [{'type': 'INT', 'count':1},{'type': 'BIGINT', 'count':1},{'type': 'DOUBLE', 'count':1},{'type': 'BINARY', 'len':32, 'count':1},{'type': 'NCHAR', 'len':32, 'count':1},{'type': 'TIMESTAMP', 'count':1}], + 'tagSchema': [{'type': 'INT', 'count':1},{'type': 'BIGINT', 'count':1},{'type': 'DOUBLE', 'count':1},{'type': 'BINARY', 'len':32, 'count':1},{'type': 'NCHAR', 'len':32, 'count':1}], + 'ctbPrefix': 'ctb', + 'ctbStartIdx': 0, + 'ctbNum': 1, + 'rowsPerTbl': 100000, + 'batchNum': 1200, + 'startTs': 1640966400000, # 2022-01-01 00:00:00.000 + 'pollDelay': 3, + 'showMsg': 1, + 'showRow': 1, + 'snapshot': 0} + + paraDict['vgroups'] = self.vgroups + paraDict['ctbNum'] = self.ctbNum + paraDict['rowsPerTbl'] = self.rowsPerTbl + + tmqCom.initConsumerTable() + tdCom.create_database(tdSql, paraDict["dbName"],paraDict["dropFlag"], vgroups=paraDict["vgroups"],replica=1) + tdLog.info("create stb") + tmqCom.create_stable(tdSql, dbName=paraDict["dbName"],stbName=paraDict["stbName"]) + tdLog.info("create ctb") + tmqCom.create_ctable(tdSql, dbName=paraDict["dbName"],stbName=paraDict["stbName"],ctbPrefix=paraDict['ctbPrefix'], + ctbNum=paraDict["ctbNum"],ctbStartIdx=paraDict['ctbStartIdx']) + tdLog.info("insert data") + tmqCom.insert_data_interlaceByMultiTbl(tsql=tdSql,dbName=paraDict["dbName"],ctbPrefix=paraDict["ctbPrefix"], + ctbNum=paraDict["ctbNum"],rowsPerTbl=paraDict["rowsPerTbl"],batchNum=paraDict["batchNum"], + startTs=paraDict["startTs"],ctbStartIdx=paraDict['ctbStartIdx']) + # tmqCom.insert_data_with_autoCreateTbl(tsql=tdSql,dbName=paraDict["dbName"],stbName=paraDict["stbName"],ctbPrefix="ctbx", + # ctbNum=paraDict["ctbNum"],rowsPerTbl=paraDict["rowsPerTbl"],batchNum=paraDict["batchNum"], + # startTs=paraDict["startTs"],ctbStartIdx=paraDict['ctbStartIdx']) + + # tdLog.info("restart taosd to ensure that the data falls into the disk") + # tdSql.query("flush database %s"%(paraDict['dbName'])) + return + + def delData(self,tsql,dbName,ctbPrefix,ctbNum,startTs=0,endTs=0,ctbStartIdx=0): + tdLog.debug("start to del data ............") + for i in range(ctbNum): + sql = "delete from %s.%s%d where _c0 >= %d and _c0 <= %d "%(dbName,ctbPrefix,i+ctbStartIdx,startTs,endTs) + tsql.execute(sql) + + tdLog.debug("del data ............ [OK]") + return + + def tmqCase1(self): + tdLog.printNoPrefix("======== test case 1: ") + paraDict = {'dbName': 'dbt', + 'dropFlag': 1, + 'event': '', + 'vgroups': 4, + 'stbName': 'stb', + 'colPrefix': 'c', + 'tagPrefix': 't', + 'colSchema': [{'type': 'INT', 'count':1},{'type': 'BIGINT', 'count':1},{'type': 'DOUBLE', 'count':1},{'type': 'BINARY', 'len':32, 'count':1},{'type': 'NCHAR', 'len':32, 'count':1},{'type': 'TIMESTAMP', 'count':1}], + 'tagSchema': [{'type': 'INT', 'count':1},{'type': 'BIGINT', 'count':1},{'type': 'DOUBLE', 'count':1},{'type': 'BINARY', 'len':32, 'count':1},{'type': 'NCHAR', 'len':32, 'count':1}], + 'ctbPrefix': 'ctb', + 'ctbStartIdx': 0, + 'ctbNum': 1, + 'rowsPerTbl': 100000, + 'batchNum': 3000, + 'startTs': 1640966400000, # 2022-01-01 00:00:00.000 + 'endTs': 0, + 'pollDelay': 5, + 'showMsg': 1, + 'showRow': 1, + 'snapshot': 0} + paraDict['snapshot'] = self.snapshot + paraDict['vgroups'] = self.vgroups + paraDict['ctbNum'] = self.ctbNum + paraDict['rowsPerTbl'] = self.rowsPerTbl + + # del some data + rowsOfDelete = int(paraDict["rowsPerTbl"] / 4) + paraDict["endTs"] = paraDict["startTs"] + rowsOfDelete - 1 + self.delData(tsql=tdSql,dbName=paraDict["dbName"],ctbPrefix=paraDict["ctbPrefix"],ctbNum=paraDict["ctbNum"], + startTs=paraDict["startTs"], endTs=paraDict["endTs"],ctbStartIdx=paraDict['ctbStartIdx']) + + tdLog.info("create topics from stb1") + topicFromStb1 = 'topic_stb1' + queryString = "select ts, c1, c2 from %s.%s"%(paraDict['dbName'], paraDict['stbName']) + sqlString = "create topic %s as %s" %(topicFromStb1, queryString) + tdLog.info("create topic sql: %s"%sqlString) + tdSql.execute(sqlString) + + # paraDict['ctbNum'] = self.ctbNum + paraDict['rowsPerTbl'] = self.rowsPerTbl + consumerId = 0 + expectrowcnt = int(paraDict["rowsPerTbl"] * paraDict["ctbNum"]) + topicList = topicFromStb1 + ifcheckdata = 1 + ifManualCommit = 1 + keyList = 'group.id:cgrp1,\ + enable.auto.commit:true,\ + auto.commit.interval.ms:1000,\ + auto.offset.reset:earliest' + tmqCom.insertConsumerInfo(consumerId, expectrowcnt,topicList,keyList,ifcheckdata,ifManualCommit) + + tdLog.info("start consume processor") + tmqCom.startTmqSimProcess(pollDelay=paraDict['pollDelay'],dbName=paraDict["dbName"],showMsg=paraDict['showMsg'], showRow=paraDict['showRow'],snapshot=paraDict['snapshot']) + + tdLog.info("insert process end, and start to check consume result") + expectRows = 1 + resultList = tmqCom.selectConsumeResult(expectRows) + totalConsumeRows = 0 + for i in range(expectRows): + totalConsumeRows += resultList[i] + + tdSql.query(queryString) + totalRowsInserted = tdSql.getRows() + + tdLog.info("act consume rows: %d, expect consume rows: %d, act insert rows: %d"%(totalConsumeRows, expectrowcnt, totalRowsInserted)) + if totalConsumeRows != expectrowcnt: + tdLog.exit("tmq consume rows error!") + + tmqCom.checkFileContent(consumerId, queryString, rowsOfDelete) + + tdSql.query("drop topic %s"%topicFromStb1) + tdLog.printNoPrefix("======== test case 1 end ...... ") + + def tmqCase2(self): + tdLog.printNoPrefix("======== test case 2: ") + paraDict = {'dbName': 'dbt', + 'dropFlag': 1, + 'event': '', + 'vgroups': 4, + 'stbName': 'stb', + 'colPrefix': 'c', + 'tagPrefix': 't', + 'colSchema': [{'type': 'INT', 'count':1},{'type': 'BIGINT', 'count':1},{'type': 'DOUBLE', 'count':1},{'type': 'BINARY', 'len':32, 'count':1},{'type': 'NCHAR', 'len':32, 'count':1},{'type': 'TIMESTAMP', 'count':1}], + 'tagSchema': [{'type': 'INT', 'count':1},{'type': 'BIGINT', 'count':1},{'type': 'DOUBLE', 'count':1},{'type': 'BINARY', 'len':32, 'count':1},{'type': 'NCHAR', 'len':32, 'count':1}], + 'ctbPrefix': 'ctb', + 'ctbStartIdx': 0, + 'ctbNum': 1, + 'rowsPerTbl': 10000, + 'batchNum': 5000, + 'startTs': 1640966400000, # 2022-01-01 00:00:00.000 + 'pollDelay': 5, + 'showMsg': 1, + 'showRow': 1, + 'snapshot': 0} + + paraDict['snapshot'] = self.snapshot + paraDict['vgroups'] = self.vgroups + paraDict['ctbNum'] = self.ctbNum + paraDict['rowsPerTbl'] = self.rowsPerTbl + + tdLog.info("restart taosd to ensure that the data falls into the disk") + tdSql.query("flush database %s"%(paraDict['dbName'])) + + # update to 1/4 rows and insert 3/4 new rows + paraDict['startTs'] = paraDict['startTs'] + int(self.rowsPerTbl * 3 / 4) + # paraDict['rowsPerTbl'] = self.rowsPerTbl + tmqCom.insert_data_with_autoCreateTbl(tsql=tdSql,dbName=paraDict["dbName"],stbName=paraDict["stbName"],ctbPrefix=paraDict["ctbPrefix"], + ctbNum=paraDict["ctbNum"],rowsPerTbl=paraDict["rowsPerTbl"],batchNum=paraDict["batchNum"], + startTs=paraDict["startTs"],ctbStartIdx=paraDict['ctbStartIdx']) + # tmqCom.insert_data_interlaceByMultiTbl(tsql=tdSql,dbName=paraDict["dbName"],ctbPrefix=paraDict["ctbPrefix"], + # ctbNum=paraDict["ctbNum"],rowsPerTbl=paraDict["rowsPerTbl"],batchNum=paraDict["batchNum"], + # startTs=paraDict["startTs"],ctbStartIdx=paraDict['ctbStartIdx']) + + # del some data + rowsOfDelete = int(self.rowsPerTbl / 4 ) + paraDict["endTs"] = paraDict["startTs"] + rowsOfDelete - 1 + self.delData(tsql=tdSql,dbName=paraDict["dbName"],ctbPrefix=paraDict["ctbPrefix"],ctbNum=paraDict["ctbNum"], + startTs=paraDict["startTs"], endTs=paraDict["endTs"],ctbStartIdx=paraDict['ctbStartIdx']) + + tmqCom.initConsumerTable() + tdLog.info("create topics from stb1") + topicFromStb1 = 'topic_stb1' + queryString = "select ts, c1, c2 from %s.%s"%(paraDict['dbName'], paraDict['stbName']) + sqlString = "create topic %s as %s" %(topicFromStb1, queryString) + tdLog.info("create topic sql: %s"%sqlString) + tdSql.execute(sqlString) + + # paraDict['ctbNum'] = self.ctbNum + paraDict['rowsPerTbl'] = self.rowsPerTbl + consumerId = 1 + + if self.snapshot == 0: + expectrowcnt = int(paraDict["rowsPerTbl"] * paraDict["ctbNum"] * (1 + 1/4 + 3/4)) + elif self.snapshot == 1: + expectrowcnt = int(paraDict["rowsPerTbl"] * paraDict["ctbNum"] * (1 - 1/4 + 1/4 + 3/4 - 1/4)) + + topicList = topicFromStb1 + ifcheckdata = 1 + ifManualCommit = 1 + keyList = 'group.id:cgrp1,\ + enable.auto.commit:true,\ + auto.commit.interval.ms:1000,\ + auto.offset.reset:earliest' + tmqCom.insertConsumerInfo(consumerId, expectrowcnt,topicList,keyList,ifcheckdata,ifManualCommit) + + tdLog.info("start consume processor") + tmqCom.startTmqSimProcess(pollDelay=paraDict['pollDelay'],dbName=paraDict["dbName"],showMsg=paraDict['showMsg'], showRow=paraDict['showRow'],snapshot=paraDict['snapshot']) + + tdLog.info("start to check consume result") + expectRows = 1 + resultList = tmqCom.selectConsumeResult(expectRows) + totalConsumeRows = 0 + for i in range(expectRows): + totalConsumeRows += resultList[i] + + tdSql.query(queryString) + totalRowsInserted = tdSql.getRows() + + tdLog.info("act consume rows: %d, act insert rows: %d, expect consume rows: %d, "%(totalConsumeRows, totalRowsInserted, expectrowcnt)) + + if totalConsumeRows != expectrowcnt: + tdLog.exit("tmq consume rows error!") + + # tmqCom.checkFileContent(consumerId, queryString) + + tdSql.query("drop topic %s"%topicFromStb1) + + tdLog.printNoPrefix("======== test case 2 end ...... ") + + def run(self): + tdSql.prepare() + self.prepareTestEnv() + tdLog.printNoPrefix("=============================================") + tdLog.printNoPrefix("======== snapshot is 0: only consume from wal") + self.tmqCase1() + self.tmqCase2() + + self.prepareTestEnv() + tdLog.printNoPrefix("====================================================================") + tdLog.printNoPrefix("======== snapshot is 1: firstly consume from tsbs, and then from wal") + self.snapshot = 1 + self.tmqCase1() + self.tmqCase2() + + def stop(self): + tdSql.close() + tdLog.success(f"{__file__} successfully executed") + +event = threading.Event() + +tdCases.addLinux(__file__, TDTestCase()) +tdCases.addWindows(__file__, TDTestCase()) diff --git a/tests/system-test/7-tmq/tmqUpdate-1ctb.py b/tests/system-test/7-tmq/tmqUpdate-1ctb.py index 8513092be9..de11f0f9ab 100644 --- a/tests/system-test/7-tmq/tmqUpdate-1ctb.py +++ b/tests/system-test/7-tmq/tmqUpdate-1ctb.py @@ -235,18 +235,18 @@ class TDTestCase: def run(self): tdSql.prepare() - # self.prepareTestEnv() - # tdLog.printNoPrefix("=============================================") - # tdLog.printNoPrefix("======== snapshot is 0: only consume from wal") - # self.tmqCase1() - # self.tmqCase2() + self.prepareTestEnv() + tdLog.printNoPrefix("=============================================") + tdLog.printNoPrefix("======== snapshot is 0: only consume from wal") + self.tmqCase1() + self.tmqCase2() self.prepareTestEnv() tdLog.printNoPrefix("====================================================================") tdLog.printNoPrefix("======== snapshot is 1: firstly consume from tsbs, and then from wal") self.snapshot = 1 self.tmqCase1() - # self.tmqCase2() + self.tmqCase2() def stop(self): -- GitLab From 2076a00b7a848022f77e4af09cc87ef3adae1d36 Mon Sep 17 00:00:00 2001 From: Shengliang Guan Date: Thu, 14 Jul 2022 16:01:01 +0800 Subject: [PATCH 126/153] test: restore some 2.0 case --- tests/script/general/db/alter_option.sim | 263 ------------------ tests/script/general/db/back_insert.sim | 9 - tests/script/jenkins/basic.txt | 24 ++ tests/script/tsim/db/alter_option.sim | 55 +--- .../{general => tsim}/db/alter_tables_d2.sim | 0 .../{general => tsim}/db/alter_tables_v1.sim | 0 .../{general => tsim}/db/alter_tables_v4.sim | 0 .../{general => tsim}/db/alter_vgroups.sim | 0 tests/script/tsim/db/back_insert.sim | 2 + tests/script/{general => tsim}/db/basic4.sim | 0 tests/script/{general => tsim}/db/basic5.sim | 0 .../db/delete.sim => tsim/db/delete2.sim} | 0 .../{general => tsim}/db/delete_reuse1.sim | 0 .../{general => tsim}/db/delete_reuse2.sim | 0 .../db/delete_reusevnode.sim | 0 .../db/delete_reusevnode2.sim | 0 .../{general => tsim}/db/delete_writing1.sim | 0 .../{general => tsim}/db/delete_writing2.sim | 0 .../{general => tsim}/db/dropdnodes.sim | 0 .../{general/db/backup => tsim/db}/keep.sim | 0 tests/script/{general => tsim}/db/len.sim | 0 .../{general => tsim}/db/nosuchfile.sim | 0 tests/script/{general => tsim}/db/repeat.sim | 0 .../{general => tsim}/db/show_create_db.sim | 0 .../db/show_create_table.sim | 0 tests/script/{general => tsim}/db/tables.sim | 0 .../script/{general => tsim}/db/testSuite.sim | 0 tests/script/{general => tsim}/db/topic1.sim | 0 tests/script/{general => tsim}/db/topic2.sim | 0 tests/script/{general => tsim}/db/vnodes.sim | 0 30 files changed, 39 insertions(+), 314 deletions(-) delete mode 100644 tests/script/general/db/alter_option.sim delete mode 100644 tests/script/general/db/back_insert.sim rename tests/script/{general => tsim}/db/alter_tables_d2.sim (100%) rename tests/script/{general => tsim}/db/alter_tables_v1.sim (100%) rename tests/script/{general => tsim}/db/alter_tables_v4.sim (100%) rename tests/script/{general => tsim}/db/alter_vgroups.sim (100%) rename tests/script/{general => tsim}/db/basic4.sim (100%) rename tests/script/{general => tsim}/db/basic5.sim (100%) rename tests/script/{general/db/delete.sim => tsim/db/delete2.sim} (100%) rename tests/script/{general => tsim}/db/delete_reuse1.sim (100%) rename tests/script/{general => tsim}/db/delete_reuse2.sim (100%) rename tests/script/{general => tsim}/db/delete_reusevnode.sim (100%) rename tests/script/{general => tsim}/db/delete_reusevnode2.sim (100%) rename tests/script/{general => tsim}/db/delete_writing1.sim (100%) rename tests/script/{general => tsim}/db/delete_writing2.sim (100%) rename tests/script/{general => tsim}/db/dropdnodes.sim (100%) rename tests/script/{general/db/backup => tsim/db}/keep.sim (100%) rename tests/script/{general => tsim}/db/len.sim (100%) rename tests/script/{general => tsim}/db/nosuchfile.sim (100%) rename tests/script/{general => tsim}/db/repeat.sim (100%) rename tests/script/{general => tsim}/db/show_create_db.sim (100%) rename tests/script/{general => tsim}/db/show_create_table.sim (100%) rename tests/script/{general => tsim}/db/tables.sim (100%) rename tests/script/{general => tsim}/db/testSuite.sim (100%) rename tests/script/{general => tsim}/db/topic1.sim (100%) rename tests/script/{general => tsim}/db/topic2.sim (100%) rename tests/script/{general => tsim}/db/vnodes.sim (100%) diff --git a/tests/script/general/db/alter_option.sim b/tests/script/general/db/alter_option.sim deleted file mode 100644 index 89a32b5a5c..0000000000 --- a/tests/script/general/db/alter_option.sim +++ /dev/null @@ -1,263 +0,0 @@ -system sh/stop_dnodes.sh -system sh/deploy.sh -n dnode1 -i 1 -system sh/cfg.sh -n dnode1 -c wallevel -v 0 -system sh/cfg.sh -n dnode1 -c maxTablesPerVnode -v 1000 - -system sh/exec.sh -n dnode1 -s start - -sleep 2000 -sql connect - -print ============= create database -sql create database db cache 2 blocks 4 duration 10 keep 20 minRows 300 maxRows 400 ctime 120 precision 'ms' comp 2 wal 1 replica 1 -sql show databases -if $data00 != db then - return -1 -endi -if $data02 != 0 then - return -1 -endi -if $data03 != 0 then - return -1 -endi -if $data04 != 1 then - return -1 -endi -if $data06 != 10 then - return -1 -endi -if $data07 != 20,20,20 then - return -1 -endi -if $data08 != 2 then - return -1 -endi -if $data09 != 4 then - return -1 -endi - -print ============== step name -sql_error alter database db name d1 -sql_error alter database db name d2 - -print ============== step ntables -sql_error alter database db ntables -1 -sql_error alter database db ntables 0 -sql_error alter database db ntables 1 -sql_error alter database db ntables 10 - -print ============== step vgroups -sql_error alter database db vgroups -1 -sql_error alter database db vgroups 0 -sql_error alter database db vgroups 1 -sql_error alter database db vgroups 10 - -print ============== step replica -sql_error alter database db replica 2 -sql_error alter database db replica 3 -sql_error alter database db replica 0 - -sql alter database db replica 1 -sql show databases -print replica $data4_db -if $data4_db != 1 then - return -1 -endi - -print ============== step quorum -sql show databases -print quorum $data5_db -if $data5_db != 1 then - return -1 -endi - -sql alter database db quorum 1 -sql show databases -print quorum $data5_db -if $data5_db != 1 then - return -1 -endi - -sql_error alter database db quorum 2 - -sql_error alter database db quorum 3 - -sql_error alter database db quorum 0 -sql_error alter database db quorum 4 -sql_error alter database db quorum 5 -sql_error alter database db quorum -1 - -print ============== step duration -sql_error alter database db duration 0 -sql_error alter database db duration 1 -sql_error alter database db duration 2 -sql_error alter database db duration 10 -sql_error alter database db duration 50 -sql_error alter database db duration 100 - -print ============== step keep -sql show databases -print keep $data7_db -if $data7_db != 20,20,20 then - return -1 -endi - -sql alter database db keep 20 -sql show databases -print keep $data7_db -if $data7_db != 20,20,20 then - return -1 -endi - -sql alter database db keep 30 -sql show databases -print keep $data7_db -if $data7_db != 30,30,30 then - return -1 -endi - -sql alter database db keep 40 -sql show databases -print keep $data7_db -if $data7_db != 40,40,40 then - return -1 -endi - -sql alter database db keep 40,50 -sql alter database db keep 30,31 -sql alter database db keep 20 -sql_error alter database db keep 10.0 -sql_error alter database db keep 9 -sql_error alter database db keep 1 -sql_error alter database db keep 0 -sql_error alter database db keep -1 -sql_error alter database db keep 365001 - -print ============== step cache -sql_error alter database db cache 60 -sql_error alter database db cache 50 -sql_error alter database db cache 20 -sql_error alter database db cache 3 -sql_error alter database db cache 129 -sql_error alter database db cache 300 -sql_error alter database db cache 0 -sql_error alter database db cache -1 - -print ============== step blocks -sql show databases -print blocks $data9_db -if $data9_db != 4 then - return -1 -endi - -sql alter database db blocks 10 -sql show databases -print blocks $data9_db -if $data9_db != 10 then - return -1 -endi - -sql alter database db blocks 20 -sql show databases -print blocks $data9_db -if $data9_db != 20 then - return -1 -endi - -sql alter database db blocks 30 -sql show databases -print blocks $data9_db -if $data9_db != 30 then - return -1 -endi - -sql alter database db blocks 40 -sql alter database db blocks 30 -sql alter database db blocks 20 -sql alter database db blocks 10 -sql_error alter database db blocks 2 -sql_error alter database db blocks 1 -sql_error alter database db blocks 0 -sql_error alter database db blocks -1 -sql_error alter database db blocks 10001 - -print ============== step minrows -sql_error alter database db minrows 1 -sql_error alter database db minrows 100 -sql_error alter database db minrows 1000 - -print ============== step maxrows -sql_error alter database db maxrows 1 -sql_error alter database db maxrows 100 -sql_error alter database db maxrows 1000 - -print ============== step wallevel -sql show databases -print wallevel $data12_db -if $data12_db != 1 then - return -1 -endi - -sql_error alter database db wal 1 - - -sql_error alter database db wal 1 -sql_error alter database db wal 2 -sql_error alter database db wal 1 -sql_error alter database db wal 2 -sql_error alter database db wal 0 -sql_error alter database db wal 3 -sql_error alter database db wal 4 -sql_error alter database db wal -1 -sql_error alter database db wal 1000 - -print ============== step fsync -sql_error alter database db fsync 0 -sql_error alter database db fsync 1 -sql_error alter database db fsync 3600 -sql_error alter database db fsync 18000 -sql_error alter database db fsync 180000 -sql_error alter database db fsync 180001 -sql_error alter database db fsync -1 - -print ============== step comp -sql show databases -print comp $data14_db -if $data14_db != 2 then - return -1 -endi - -sql alter database db comp 1 -sql show databases -print comp $data14_db -if $data14_db != 1 then - return -1 -endi - -sql alter database db comp 2 -sql show databases -print comp $data14_db -if $data14_db != 2 then - return -1 -endi - -sql alter database db comp 0 -sql show databases -print comp $data14_db -if $data14_db != 0 then - return -1 -endi - -sql_error alter database db comp 3 -sql_error alter database db comp 4 -sql_error alter database db comp 5 -sql_error alter database db comp -1 - - -print ============== step precision -sql_error alter database db prec 'us' - -print ============== step status -sql_error alter database db status 'delete' - -system sh/exec.sh -n dnode1 -s stop -x SIGINT diff --git a/tests/script/general/db/back_insert.sim b/tests/script/general/db/back_insert.sim deleted file mode 100644 index 642df63ff2..0000000000 --- a/tests/script/general/db/back_insert.sim +++ /dev/null @@ -1,9 +0,0 @@ -sql connect -$x = 1 -begin: - sql reset query cache - sleep 1000 - sql insert into db.tb values(now, $x ) -x begin - #print ===> insert successed $x - $x = $x + 1 -goto begin \ No newline at end of file diff --git a/tests/script/jenkins/basic.txt b/tests/script/jenkins/basic.txt index 4de8b3667d..4c77051426 100644 --- a/tests/script/jenkins/basic.txt +++ b/tests/script/jenkins/basic.txt @@ -11,17 +11,41 @@ ./test.sh -f tsim/db/alter_option.sim # ./test.sh -f tsim/db/alter_replica_13.sim # ./test.sh -f tsim/db/alter_replica_31.sim +#./test.sh -f tsim/db/alter_tables_d2.sim +#./test.sh -f tsim/db/alter_tables_v1.sim +#./test.sh -f tsim/db/alter_tables_v4.sim +#./test.sh -f tsim/db/alter_vgroups.sim ./test.sh -f tsim/db/basic1.sim ./test.sh -f tsim/db/basic2.sim ./test.sh -f tsim/db/basic3.sim +#./test.sh -f tsim/db/basic4.sim +#./test.sh -f tsim/db/basic5.sim ./test.sh -f tsim/db/basic6.sim ./test.sh -f tsim/db/basic7.sim #./test.sh -f tsim/db/commit.sim ./test.sh -f tsim/db/create_all_options.sim #./test.sh -f tsim/db/delete_part.sim +#./test.sh -f tsim/db/delete_reuse1.sim +#./test.sh -f tsim/db/delete_reuse2.sim +#./test.sh -f tsim/db/delete_reusevnode.sim +#./test.sh -f tsim/db/delete_reusevnode2.sim +#./test.sh -f tsim/db/delete_writing1.sim +#./test.sh -f tsim/db/delete_writing2.sim #./test.sh -f tsim/db/delete.sim +#./test.sh -f tsim/db/delete2.sim +#./test.sh -f tsim/db/dropvnodes.sim ./test.sh -f tsim/db/error1.sim +#./test.sh -f tsim/db/keep.sim +#./test.sh -f tsim/db/len.sim +#./test.sh -f tsim/db/nosuchfile.sim +#./test.sh -f tsim/db/repeat.sim +#./test.sh -f tsim/db/show_create_db.sim +#./test.sh -f tsim/db/show_create_table.sim +#./test.sh -f tsim/db/tables.sim ./test.sh -f tsim/db/taosdlog.sim +#./test.sh -f tsim/db/topic1.sim +#./test.sh -f tsim/db/topic2.sim +#./test.sh -f tsim/db/vnodes.sim # ---- dnode # ./test.sh -f tsim/dnode/balance_replica1.sim diff --git a/tests/script/tsim/db/alter_option.sim b/tests/script/tsim/db/alter_option.sim index f24e32279d..1eb4e36da6 100644 --- a/tests/script/tsim/db/alter_option.sim +++ b/tests/script/tsim/db/alter_option.sim @@ -6,64 +6,36 @@ system sh/exec.sh -n dnode1 -s start system sh/exec.sh -n dnode2 -s start system sh/exec.sh -n dnode3 -s start -$loop_cnt = 0 -check_dnode_ready: - $loop_cnt = $loop_cnt + 1 - sleep 200 - if $loop_cnt == 10 then - print ====> dnode not ready! - return -1 - endi -sql show dnodes -print ===> $rows $data00 $data01 $data02 $data03 $data04 $data05 -if $data00 != 1 then - return -1 -endi -if $data04 != ready then - goto check_dnode_ready -endi - sql connect sql create dnode $hostname port 7200 sql create dnode $hostname port 7300 -$loop_cnt = 0 -check_dnode_ready_1: - $loop_cnt = $loop_cnt + 1 - sleep 200 - if $loop_cnt == 10 then +$x = 0 +step1: + $x = $x + 1 + sleep 1000 + if $x == 10 then print ====> dnode not ready! return -1 endi sql show dnodes -print ===> rows: $rows print ===> $data00 $data01 $data02 $data03 $data04 $data05 print ===> $data10 $data11 $data12 $data13 $data14 $data15 print ===> $data20 $data21 $data22 $data23 $data24 $data25 -if $data00 != 1 then +if $rows != 3 then return -1 endi -system_content printf %OS% -if $system_content == Windows_NT then - system_content printf %COMPUTERNAME%:7100 - if $data01 != $system_content then - return -1 - endi -else - if $data01 != localhost:7100 then - return -1 - endi +if $data(1)[4] != ready then + goto step1 endi -if $data04 != ready then - goto check_dnode_ready_1 +if $data(2)[4] != ready then + goto step1 endi -if $data14 != ready then - goto check_dnode_ready_1 -endi -if $data24 != ready then - goto check_dnode_ready_1 +if $data(3)[4] != ready then + goto step1 endi + print ============= create database #database_option: { # | BUFFER value [3~16384, default: 96] @@ -137,7 +109,6 @@ if $data17_db != ns then # precision return -1 endi -sleep 3000 #sql show db.vgroups #if $data[0][4] == leader then # if $data[0][6] != follower then diff --git a/tests/script/general/db/alter_tables_d2.sim b/tests/script/tsim/db/alter_tables_d2.sim similarity index 100% rename from tests/script/general/db/alter_tables_d2.sim rename to tests/script/tsim/db/alter_tables_d2.sim diff --git a/tests/script/general/db/alter_tables_v1.sim b/tests/script/tsim/db/alter_tables_v1.sim similarity index 100% rename from tests/script/general/db/alter_tables_v1.sim rename to tests/script/tsim/db/alter_tables_v1.sim diff --git a/tests/script/general/db/alter_tables_v4.sim b/tests/script/tsim/db/alter_tables_v4.sim similarity index 100% rename from tests/script/general/db/alter_tables_v4.sim rename to tests/script/tsim/db/alter_tables_v4.sim diff --git a/tests/script/general/db/alter_vgroups.sim b/tests/script/tsim/db/alter_vgroups.sim similarity index 100% rename from tests/script/general/db/alter_vgroups.sim rename to tests/script/tsim/db/alter_vgroups.sim diff --git a/tests/script/tsim/db/back_insert.sim b/tests/script/tsim/db/back_insert.sim index 43831cca95..642df63ff2 100644 --- a/tests/script/tsim/db/back_insert.sim +++ b/tests/script/tsim/db/back_insert.sim @@ -1,6 +1,8 @@ sql connect $x = 1 begin: + sql reset query cache + sleep 1000 sql insert into db.tb values(now, $x ) -x begin #print ===> insert successed $x $x = $x + 1 diff --git a/tests/script/general/db/basic4.sim b/tests/script/tsim/db/basic4.sim similarity index 100% rename from tests/script/general/db/basic4.sim rename to tests/script/tsim/db/basic4.sim diff --git a/tests/script/general/db/basic5.sim b/tests/script/tsim/db/basic5.sim similarity index 100% rename from tests/script/general/db/basic5.sim rename to tests/script/tsim/db/basic5.sim diff --git a/tests/script/general/db/delete.sim b/tests/script/tsim/db/delete2.sim similarity index 100% rename from tests/script/general/db/delete.sim rename to tests/script/tsim/db/delete2.sim diff --git a/tests/script/general/db/delete_reuse1.sim b/tests/script/tsim/db/delete_reuse1.sim similarity index 100% rename from tests/script/general/db/delete_reuse1.sim rename to tests/script/tsim/db/delete_reuse1.sim diff --git a/tests/script/general/db/delete_reuse2.sim b/tests/script/tsim/db/delete_reuse2.sim similarity index 100% rename from tests/script/general/db/delete_reuse2.sim rename to tests/script/tsim/db/delete_reuse2.sim diff --git a/tests/script/general/db/delete_reusevnode.sim b/tests/script/tsim/db/delete_reusevnode.sim similarity index 100% rename from tests/script/general/db/delete_reusevnode.sim rename to tests/script/tsim/db/delete_reusevnode.sim diff --git a/tests/script/general/db/delete_reusevnode2.sim b/tests/script/tsim/db/delete_reusevnode2.sim similarity index 100% rename from tests/script/general/db/delete_reusevnode2.sim rename to tests/script/tsim/db/delete_reusevnode2.sim diff --git a/tests/script/general/db/delete_writing1.sim b/tests/script/tsim/db/delete_writing1.sim similarity index 100% rename from tests/script/general/db/delete_writing1.sim rename to tests/script/tsim/db/delete_writing1.sim diff --git a/tests/script/general/db/delete_writing2.sim b/tests/script/tsim/db/delete_writing2.sim similarity index 100% rename from tests/script/general/db/delete_writing2.sim rename to tests/script/tsim/db/delete_writing2.sim diff --git a/tests/script/general/db/dropdnodes.sim b/tests/script/tsim/db/dropdnodes.sim similarity index 100% rename from tests/script/general/db/dropdnodes.sim rename to tests/script/tsim/db/dropdnodes.sim diff --git a/tests/script/general/db/backup/keep.sim b/tests/script/tsim/db/keep.sim similarity index 100% rename from tests/script/general/db/backup/keep.sim rename to tests/script/tsim/db/keep.sim diff --git a/tests/script/general/db/len.sim b/tests/script/tsim/db/len.sim similarity index 100% rename from tests/script/general/db/len.sim rename to tests/script/tsim/db/len.sim diff --git a/tests/script/general/db/nosuchfile.sim b/tests/script/tsim/db/nosuchfile.sim similarity index 100% rename from tests/script/general/db/nosuchfile.sim rename to tests/script/tsim/db/nosuchfile.sim diff --git a/tests/script/general/db/repeat.sim b/tests/script/tsim/db/repeat.sim similarity index 100% rename from tests/script/general/db/repeat.sim rename to tests/script/tsim/db/repeat.sim diff --git a/tests/script/general/db/show_create_db.sim b/tests/script/tsim/db/show_create_db.sim similarity index 100% rename from tests/script/general/db/show_create_db.sim rename to tests/script/tsim/db/show_create_db.sim diff --git a/tests/script/general/db/show_create_table.sim b/tests/script/tsim/db/show_create_table.sim similarity index 100% rename from tests/script/general/db/show_create_table.sim rename to tests/script/tsim/db/show_create_table.sim diff --git a/tests/script/general/db/tables.sim b/tests/script/tsim/db/tables.sim similarity index 100% rename from tests/script/general/db/tables.sim rename to tests/script/tsim/db/tables.sim diff --git a/tests/script/general/db/testSuite.sim b/tests/script/tsim/db/testSuite.sim similarity index 100% rename from tests/script/general/db/testSuite.sim rename to tests/script/tsim/db/testSuite.sim diff --git a/tests/script/general/db/topic1.sim b/tests/script/tsim/db/topic1.sim similarity index 100% rename from tests/script/general/db/topic1.sim rename to tests/script/tsim/db/topic1.sim diff --git a/tests/script/general/db/topic2.sim b/tests/script/tsim/db/topic2.sim similarity index 100% rename from tests/script/general/db/topic2.sim rename to tests/script/tsim/db/topic2.sim diff --git a/tests/script/general/db/vnodes.sim b/tests/script/tsim/db/vnodes.sim similarity index 100% rename from tests/script/general/db/vnodes.sim rename to tests/script/tsim/db/vnodes.sim -- GitLab From 1c261c319b80ea69fe6601827efde6b80e65476b Mon Sep 17 00:00:00 2001 From: plum-lihui Date: Thu, 14 Jul 2022 16:09:25 +0800 Subject: [PATCH 127/153] test: add test case for tmq into ci --- tests/system-test/fulltest.sh | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/system-test/fulltest.sh b/tests/system-test/fulltest.sh index 2c116113bc..8bafe3c966 100755 --- a/tests/system-test/fulltest.sh +++ b/tests/system-test/fulltest.sh @@ -180,6 +180,7 @@ python3 ./test.py -f 7-tmq/tmqAutoCreateTbl.py #python3 ./test.py -f 7-tmq/tmqDnodeRestart.py #python3 ./test.py -f 7-tmq/tmqUpdate-1ctb.py python3 ./test.py -f 7-tmq/tmqUpdate-multiCtb.py +#python3 ./test.py -f 7-tmq/tmqDelete-1ctb.py #------------querPolicy 2----------- -- GitLab From a0466d780237e68af1e2f1c8aeb4eee7bfaf10b0 Mon Sep 17 00:00:00 2001 From: Liu Jicong Date: Thu, 14 Jul 2022 16:12:57 +0800 Subject: [PATCH 128/153] fix(sma): double free --- source/dnode/vnode/src/sma/smaEnv.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/source/dnode/vnode/src/sma/smaEnv.c b/source/dnode/vnode/src/sma/smaEnv.c index 2cf4fd51a9..e75d3b4e5d 100644 --- a/source/dnode/vnode/src/sma/smaEnv.c +++ b/source/dnode/vnode/src/sma/smaEnv.c @@ -214,7 +214,6 @@ static int32_t tdInitSmaStat(SSmaStat **pSmaStat, int8_t smaType, const SSma *pS } pRSmaStat->refId = refId; - // init hash RSMA_INFO_HASH(pRSmaStat) = taosHashInit( RSMA_TASK_INFO_HASH_SLOT, taosGetDefaultHashFunction(TSDB_DATA_TYPE_BIGINT), true, HASH_ENTRY_LOCK); @@ -256,6 +255,7 @@ static void tdDestroyRSmaStat(void *pRSmaStat) { // step 2: destroy the rsma info and associated fetch tasks // TODO: use taosHashSetFreeFp when taosHashSetFreeFp is ready. +#if 0 if (taosHashGetSize(RSMA_INFO_HASH(pStat)) > 0) { void *infoHash = taosHashIterate(RSMA_INFO_HASH(pStat), NULL); while (infoHash) { @@ -264,6 +264,7 @@ static void tdDestroyRSmaStat(void *pRSmaStat) { infoHash = taosHashIterate(RSMA_INFO_HASH(pStat), infoHash); } } +#endif taosHashCleanup(RSMA_INFO_HASH(pStat)); // step 3: wait all triggered fetch tasks finished @@ -382,4 +383,4 @@ int32_t tdCheckAndInitSmaEnv(SSma *pSma, int8_t smaType) { tdUnLockSma(pSma); return TSDB_CODE_SUCCESS; -}; \ No newline at end of file +}; -- GitLab From c0639d3dc4f0b19820821af66e5617b66a0e4558 Mon Sep 17 00:00:00 2001 From: Liu Jicong Date: Thu, 14 Jul 2022 16:24:12 +0800 Subject: [PATCH 129/153] fix(query): double free --- source/libs/executor/src/timewindowoperator.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/source/libs/executor/src/timewindowoperator.c b/source/libs/executor/src/timewindowoperator.c index 74b5a3dab2..22c09de64f 100644 --- a/source/libs/executor/src/timewindowoperator.c +++ b/source/libs/executor/src/timewindowoperator.c @@ -1340,13 +1340,13 @@ static int32_t closeIntervalWindow(SHashObj* pHashMap, STimeWindowAggSupp* pSup, void* key = taosHashGetKey(pIte, &keyLen); uint64_t groupId = *(uint64_t*)key; ASSERT(keyLen == GET_RES_WINDOW_KEY_LEN(sizeof(TSKEY))); - TSKEY ts = *(int64_t*)((char*)key + sizeof(uint64_t)); + TSKEY ts = *(int64_t*)((char*)key + sizeof(uint64_t)); STimeWindow win; win.skey = ts; win.ekey = taosTimeAdd(win.skey, pInterval->interval, pInterval->intervalUnit, pInterval->precision) - 1; - SWinRes winRe = { - .ts = win.skey, - .groupId = groupId, + SWinRes winRe = { + .ts = win.skey, + .groupId = groupId, }; void* chIds = taosHashGet(pPullDataMap, &winRe, sizeof(SWinRes)); if (isCloseWindow(&win, pSup)) { @@ -1537,7 +1537,7 @@ void destroyStreamFinalIntervalOperatorInfo(void* param, int32_t numOfOutput) { for (int32_t i = 0; i < size; i++) { SOperatorInfo* pChildOp = taosArrayGetP(pInfo->pChildren, i); destroyStreamFinalIntervalOperatorInfo(pChildOp->info, numOfOutput); - taosMemoryFreeClear(pChildOp->info); + /*taosMemoryFreeClear(pChildOp->info);*/ taosMemoryFreeClear(pChildOp); } } -- GitLab From a15bd187bfb6bff0ce7defc0473bf043de8cc85b Mon Sep 17 00:00:00 2001 From: wangmm0220 Date: Thu, 14 Jul 2022 16:24:16 +0800 Subject: [PATCH 130/153] fix:error in json tag --- source/libs/scalar/src/sclvector.c | 3 ++- tests/system-test/2-query/json_tag.py | 25 ++++++++----------------- 2 files changed, 10 insertions(+), 18 deletions(-) diff --git a/source/libs/scalar/src/sclvector.c b/source/libs/scalar/src/sclvector.c index 39b2f04f3e..76de4da4fd 100644 --- a/source/libs/scalar/src/sclvector.c +++ b/source/libs/scalar/src/sclvector.c @@ -1477,7 +1477,8 @@ void vectorAssign(SScalarParam* pLeft, SScalarParam* pRight, SScalarParam *pOut, pOut->numOfRows = pLeft->numOfRows; - if (IS_HELPER_NULL(pRight->columnData, 0)) { +// if (IS_HELPER_NULL(pRight->columnData, 0)) { + if(colDataIsNull_s(pRight->columnData, 0)){ for (int32_t i = 0; i < pOut->numOfRows; ++i) { colDataAppend(pOutputCol, i, NULL, true); } diff --git a/tests/system-test/2-query/json_tag.py b/tests/system-test/2-query/json_tag.py index 70aca9fd93..b817b1afb4 100644 --- a/tests/system-test/2-query/json_tag.py +++ b/tests/system-test/2-query/json_tag.py @@ -197,7 +197,7 @@ class TDTestCase: tdSql.checkData(0, 0, "true") # test select json tag->'key', value is null tdSql.query("select jtag->'tag1' from jsons1_4") - tdSql.checkData(0, 0, None) + tdSql.checkData(0, 0, "null") # test select json tag->'key', value is double tdSql.query("select jtag->'tag1' from jsons1_5") tdSql.checkData(0, 0, "1.232000000") @@ -394,16 +394,15 @@ class TDTestCase: # test distinct tdSql.execute("insert into jsons1_14 using jsons1 tags('{\"tag1\":\"收到货\",\"tag2\":\"\",\"tag3\":null}') values(1591062628000, 2, NULL, '你就会', 'dws')") tdSql.query("select distinct jtag->'tag1' from jsons1") - tdSql.checkRows(7) - # tdSql.query("select distinct jtag from jsons1") - # tdSql.checkRows(9) + tdSql.checkRows(8) + tdSql.error("select distinct jtag from jsons1") #test dumplicate key with normal colomn tdSql.execute("INSERT INTO jsons1_15 using jsons1 tags('{\"tbname\":\"tt\",\"databool\":true,\"datastr\":\"是是是\"}') values(1591060828000, 4, false, 'jjsf', \"你就会\")") tdSql.query("select * from jsons1 where jtag->'datastr' match '是' and datastr match 'js'") tdSql.checkRows(1) - # tdSql.query("select tbname,jtag->'tbname' from jsons1 where jtag->'tbname'='tt' and tbname='jsons1_14'") - # tdSql.checkRows(1) + tdSql.query("select tbname,jtag->'tbname' from jsons1 where jtag->'tbname'='tt' and tbname='jsons1_15'") + tdSql.checkRows(1) # test join tdSql.execute("create table if not exists jsons2(ts timestamp, dataInt int, dataBool bool, dataStr nchar(50), dataStrBin binary(150)) tags(jtag json)") @@ -477,15 +476,10 @@ class TDTestCase: tdSql.query("select top(dataint,2),jtag->'tag1' from jsons1 group by jtag->'tag1' order by jtag->'tag1'") tdSql.checkRows(11) tdSql.checkData(0, 1, None) - #tdSql.checkData(2, 0, 24) - #tdSql.checkData(3, 0, 3) - #tdSql.checkData(3, 1, "false") - #tdSql.checkData(8, 0, 2) - #tdSql.checkData(10, 1, '"femail"') # test having - # tdSql.query("select count(*),jtag->'tag1' from jsons1 group by jtag->'tag1' having count(*) > 1") - # tdSql.checkRows(3) + tdSql.query("select count(*),jtag->'tag1' from jsons1 group by jtag->'tag1' having count(*) > 1") + tdSql.checkRows(3) # subquery with json tag tdSql.query("select * from (select jtag, dataint from jsons1) order by dataint") @@ -495,10 +489,7 @@ class TDTestCase: tdSql.error("select jtag->'tag1' from (select jtag->'tag1', dataint from jsons1)") tdSql.error("select t->'tag1' from (select jtag->'tag1' as t, dataint from jsons1)") - # tdSql.query("select ts,jtag->'tag1' from (select jtag->'tag1',tbname,ts from jsons1 order by ts)") - # tdSql.checkRows(11) - # tdSql.checkData(1, 1, "jsons1_1") - # tdSql.checkData(1, 2, '"femail"') + tdSql.error("select ts,jtag->'tag1' from (select jtag->'tag1',tbname,ts from jsons1 order by ts)") # union all tdSql.query("select jtag->'tag1' from jsons1 union all select jtag->'tag2' from jsons2") -- GitLab From e711f560275b8645da3156d5ae08f9fed44fd5fc Mon Sep 17 00:00:00 2001 From: wangmm0220 Date: Thu, 14 Jul 2022 16:33:11 +0800 Subject: [PATCH 131/153] fix:remove code for resolve the core of amotic_load_n --- source/dnode/mnode/sdb/inc/sdb.h | 1 - 1 file changed, 1 deletion(-) diff --git a/source/dnode/mnode/sdb/inc/sdb.h b/source/dnode/mnode/sdb/inc/sdb.h index be56d901de..1294f0cff3 100644 --- a/source/dnode/mnode/sdb/inc/sdb.h +++ b/source/dnode/mnode/sdb/inc/sdb.h @@ -163,7 +163,6 @@ typedef struct SSdbRow { ESdbType type; ESdbStatus status; int32_t refCount; - int64_t forAlign; char pObj[]; } SSdbRow; -- GitLab From c56f481476486ea6fa33fa16a04f8091cc00bc45 Mon Sep 17 00:00:00 2001 From: afwerar <1296468573@qq.com> Date: Thu, 14 Jul 2022 16:38:10 +0800 Subject: [PATCH 132/153] test: option taosbenchmark error --- cmake/cmake.options | 6 ------ 1 file changed, 6 deletions(-) diff --git a/cmake/cmake.options b/cmake/cmake.options index 2acd46694b..5d99b2214a 100644 --- a/cmake/cmake.options +++ b/cmake/cmake.options @@ -83,12 +83,6 @@ option( OFF ) -option( - TDENGINE_3 - "TDengine 3.x" - ON - ) - option( BUILD_ADDR2LINE "If build addr2line" -- GitLab From 00f3cac9fc197e2706d6c93e947b29c0938800bb Mon Sep 17 00:00:00 2001 From: Ganlin Zhao Date: Thu, 14 Jul 2022 16:41:29 +0800 Subject: [PATCH 133/153] restore test cases --- tests/system-test/fulltest.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/system-test/fulltest.sh b/tests/system-test/fulltest.sh index ef4ac83bb7..2c116113bc 100755 --- a/tests/system-test/fulltest.sh +++ b/tests/system-test/fulltest.sh @@ -22,7 +22,7 @@ python3 ./test.py -f 1-insert/test_stmt_muti_insert_query.py python3 ./test.py -f 1-insert/test_stmt_set_tbname_tag.py python3 ./test.py -f 1-insert/alter_stable.py python3 ./test.py -f 1-insert/alter_table.py -#python3 ./test.py -f 1-insert/insertWithMoreVgroup.py +python3 ./test.py -f 1-insert/insertWithMoreVgroup.py python3 ./test.py -f 1-insert/table_comment.py python3 ./test.py -f 1-insert/time_range_wise.py python3 ./test.py -f 1-insert/block_wise.py @@ -120,7 +120,7 @@ python3 ./test.py -f 2-query/irate.py python3 ./test.py -f 2-query/and_or_for_byte.py python3 ./test.py -f 2-query/count_partition.py python3 ./test.py -f 2-query/function_null.py -#python3 ./test.py -f 2-query/queryQnode.py +python3 ./test.py -f 2-query/queryQnode.py python3 ./test.py -f 2-query/max_partition.py -- GitLab From 03712489f5b5711a8b827cf3bb7410a0d69e08e2 Mon Sep 17 00:00:00 2001 From: 54liuyao <54liuyao@163.com> Date: Thu, 14 Jul 2022 14:24:39 +0800 Subject: [PATCH 134/153] ci(stream): stream intervl offset --- tests/script/tsim/stream/sliding.sim | 126 +++++++++++++++++++++++++++ 1 file changed, 126 insertions(+) diff --git a/tests/script/tsim/stream/sliding.sim b/tests/script/tsim/stream/sliding.sim index 44f96cbefa..1ffca2a67b 100644 --- a/tests/script/tsim/stream/sliding.sim +++ b/tests/script/tsim/stream/sliding.sim @@ -239,5 +239,131 @@ if $data32 != 6 then goto loop0 endi +print step 4 + +sql create database test1 vgroups 1 +sql use test1 +sql create stable st(ts timestamp, a int, b int, c int, d double) tags(ta int,tb int,tc int); +sql create table t1 using st tags(1,1,1); +sql create table t2 using st tags(2,2,2); + +sql create stream streams11 trigger at_once into streamt as select _wstart, count(*) c1, sum(a) c3 , max(b) c4, min(c) c5 from t1 interval(10s, 5s); +sql create stream streams12 trigger at_once into streamt2 as select _wstart, count(*) c1, sum(a) c3 , max(b) c4, min(c) c5 from st interval(10s, 5s); + +sql insert into t1 values(1648791213000,1,2,3,1.0); +sql insert into t1 values(1648791223001,2,2,3,1.1); +sql insert into t1 values(1648791233002,3,2,3,2.1); +sql insert into t1 values(1648791243003,4,2,3,3.1); +sql insert into t1 values(1648791213004,4,2,3,4.1); + +sql insert into t2 values(1648791213000,1,2,3,1.0); +sql insert into t2 values(1648791223001,2,2,3,1.1); +sql insert into t2 values(1648791233002,3,2,3,2.1); +sql insert into t2 values(1648791243003,4,2,3,3.1); +sql insert into t2 values(1648791213004,4,2,3,4.1); + +$loop_count = 0 + +loop1: +sleep 300 + +$loop_count = $loop_count + 1 +if $loop_count == 10 then + return -1 +endi + +sql select * from streamt + +# row 0 +if $data01 != 2 then + print =====data01=$data01 + goto loop1 +endi + +if $data02 != 5 then + print =====data02=$data02 + goto loop1 +endi + +# row 1 +if $data11 != 1 then + print =====data11=$data11 + goto loop1 +endi + +if $data12 != 2 then + print =====data12=$data12 + goto loop1 +endi + +# row 2 +if $data21 != 1 then + print =====data21=$data21 + goto loop1 +endi + +if $data22 != 3 then + print =====data22=$data22 + goto loop1 +endi + +# row 3 +if $data31 != 1 then + print =====data31=$data31 + goto loop1 +endi + +if $data32 != 4 then + print =====data32=$data32 + goto loop1 +endi + +print step 5 + +sql select * from streamt2 + +# row 0 +if $data01 != 4 then + print =====data01=$data01 + goto loop1 +endi + +if $data02 != 10 then + print =====data02=$data02 + goto loop1 +endi + +# row 1 +if $data11 != 2 then + print =====data11=$data11 + goto loop1 +endi + +if $data12 != 4 then + print =====data12=$data12 + goto loop1 +endi + +# row 2 +if $data21 != 2 then + print =====data21=$data21 + goto loop1 +endi + +if $data22 != 6 then + print =====data22=$data22 + goto loop1 +endi + +# row 3 +if $data31 != 2 then + print =====data31=$data31 + goto loop1 +endi + +if $data32 != 8 then + print =====data32=$data32 + goto loop1 +endi system sh/stop_dnodes.sh \ No newline at end of file -- GitLab From 5a5ae23ddf44f2dd5cca4873116111d66793cb80 Mon Sep 17 00:00:00 2001 From: Xiaoyu Wang Date: Thu, 14 Jul 2022 16:58:54 +0800 Subject: [PATCH 135/153] fix: some problems of planner --- source/libs/parser/src/parInsert.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/source/libs/parser/src/parInsert.c b/source/libs/parser/src/parInsert.c index f986d24a7e..f7d56261ae 100644 --- a/source/libs/parser/src/parInsert.c +++ b/source/libs/parser/src/parInsert.c @@ -1167,6 +1167,13 @@ static int parseOneRow(SInsertParseContext* pCxt, STableDataBlocks* pDataBlocks, TSKEY tsKey = TD_ROW_KEY(row); checkTimestamp(pDataBlocks, (const char*)&tsKey); } + + if (i < spd->numOfBound - 1) { + NEXT_VALID_TOKEN(pCxt->pSql, sToken); + if (TK_NK_COMMA != sToken.type) { + return buildSyntaxErrMsg(&pCxt->msg, ", expected", sToken.z); + } + } } if (!isParseBindParam) { -- GitLab From f0b8386b63bc4971b56eaabb6c34cad6290b9e72 Mon Sep 17 00:00:00 2001 From: Shengliang Guan Date: Thu, 14 Jul 2022 17:00:46 +0800 Subject: [PATCH 136/153] refactor: adjust the name of stream automatically created by sma --- source/dnode/mnode/impl/inc/mndInt.h | 2 +- source/dnode/mnode/impl/src/mndMain.c | 2 +- source/dnode/mnode/impl/src/mndSma.c | 36 ++++++++++++++++++++------- 3 files changed, 29 insertions(+), 11 deletions(-) diff --git a/source/dnode/mnode/impl/inc/mndInt.h b/source/dnode/mnode/impl/inc/mndInt.h index b94c60c4ab..9f168e2c83 100644 --- a/source/dnode/mnode/impl/inc/mndInt.h +++ b/source/dnode/mnode/impl/inc/mndInt.h @@ -125,7 +125,7 @@ typedef struct SMnode { } SMnode; void mndSetMsgHandle(SMnode *pMnode, tmsg_t msgType, MndMsgFp fp); -int64_t mndGenerateUid(char *name, int32_t len); +int64_t mndGenerateUid(const char *name, int32_t len); int32_t mndAcquireRpcRef(SMnode *pMnode); void mndReleaseRpcRef(SMnode *pMnode); diff --git a/source/dnode/mnode/impl/src/mndMain.c b/source/dnode/mnode/impl/src/mndMain.c index df8dc42d17..29e68ce4e8 100644 --- a/source/dnode/mnode/impl/src/mndMain.c +++ b/source/dnode/mnode/impl/src/mndMain.c @@ -624,7 +624,7 @@ void mndSetMsgHandle(SMnode *pMnode, tmsg_t msgType, MndMsgFp fp) { } // Note: uid 0 is reserved -int64_t mndGenerateUid(char *name, int32_t len) { +int64_t mndGenerateUid(const char *name, int32_t len) { int32_t hashval = MurmurHash3_32(name, len); do { int64_t us = taosGetTimestampUs(); diff --git a/source/dnode/mnode/impl/src/mndSma.c b/source/dnode/mnode/impl/src/mndSma.c index c040f0d05b..88629ebc69 100644 --- a/source/dnode/mnode/impl/src/mndSma.c +++ b/source/dnode/mnode/impl/src/mndSma.c @@ -479,7 +479,8 @@ static void mndDestroySmaObj(SSmaObj *pSmaObj) { } } -static int32_t mndCreateSma(SMnode *pMnode, SRpcMsg *pReq, SMCreateSmaReq *pCreate, SDbObj *pDb, SStbObj *pStb) { +static int32_t mndCreateSma(SMnode *pMnode, SRpcMsg *pReq, SMCreateSmaReq *pCreate, SDbObj *pDb, SStbObj *pStb, + const char *streamName) { SSmaObj smaObj = {0}; memcpy(smaObj.name, pCreate->name, TSDB_TABLE_FNAME_LEN); memcpy(smaObj.stb, pStb->name, TSDB_TABLE_FNAME_LEN); @@ -520,12 +521,12 @@ static int32_t mndCreateSma(SMnode *pMnode, SRpcMsg *pReq, SMCreateSmaReq *pCrea } SStreamObj streamObj = {0}; - tstrncpy(streamObj.name, pCreate->name, TSDB_STREAM_FNAME_LEN); + tstrncpy(streamObj.name, streamName, TSDB_STREAM_FNAME_LEN); tstrncpy(streamObj.sourceDb, pDb->name, TSDB_DB_FNAME_LEN); tstrncpy(streamObj.targetDb, streamObj.sourceDb, TSDB_DB_FNAME_LEN); streamObj.createTime = taosGetTimestampMs(); streamObj.updateTime = streamObj.createTime; - streamObj.uid = mndGenerateUid(pCreate->name, strlen(pCreate->name)); + streamObj.uid = mndGenerateUid(streamName, strlen(streamName)); streamObj.sourceDbUid = pDb->uid; streamObj.targetDbUid = pDb->uid; streamObj.version = 1; @@ -590,7 +591,7 @@ static int32_t mndCreateSma(SMnode *pMnode, SRpcMsg *pReq, SMCreateSmaReq *pCrea if (pTrans == NULL) goto _OVER; mndTransSetDbName(pTrans, pDb->name, NULL); mndTransSetSerial(pTrans); - mDebug("trans:%d, used to create sma:%s", pTrans->id, pCreate->name); + mDebug("trans:%d, used to create sma:%s stream:%s", pTrans->id, pCreate->name, streamObj.name); if (mndSetCreateSmaRedoLogs(pMnode, pTrans, &smaObj) != 0) goto _OVER; if (mndSetCreateSmaVgroupRedoLogs(pMnode, pTrans, &streamObj.fixedSinkVg) != 0) goto _OVER; @@ -638,6 +639,14 @@ static int32_t mndCheckCreateSmaReq(SMCreateSmaReq *pCreate) { return 0; } +static void mndGetStreamNameFromSmaName(char *streamName, char *smaName) { + SName n; + tNameFromString(&n, smaName, T_NAME_ACCT | T_NAME_DB | T_NAME_TABLE); + streamName[0] = '1'; + streamName[1] = '.'; + strcpy(streamName + 2, tNameGetTableName(&n)); +} + static int32_t mndProcessCreateSmaReq(SRpcMsg *pReq) { SMnode *pMnode = pReq->info.node; int32_t code = -1; @@ -663,9 +672,12 @@ static int32_t mndProcessCreateSmaReq(SRpcMsg *pReq) { goto _OVER; } - pStream = mndAcquireStream(pMnode, createReq.name); + char streamName[TSDB_TABLE_FNAME_LEN] = {0}; + mndGetStreamNameFromSmaName(streamName, createReq.name); + + pStream = mndAcquireStream(pMnode, streamName); if (pStream != NULL) { - mError("sma:%s, failed to create since stream:%s already exist", createReq.name, createReq.name); + mError("sma:%s, failed to create since stream:%s already exist", createReq.name, streamName); terrno = TSDB_CODE_MND_STREAM_ALREADY_EXIST; goto _OVER; } @@ -692,7 +704,7 @@ static int32_t mndProcessCreateSmaReq(SRpcMsg *pReq) { goto _OVER; } - code = mndCreateSma(pMnode, pReq, &createReq, pDb, pStb); + code = mndCreateSma(pMnode, pReq, &createReq, pDb, pStb, streamName); if (code == 0) code = TSDB_CODE_ACTION_IN_PROGRESS; _OVER: @@ -789,7 +801,10 @@ static int32_t mndDropSma(SMnode *pMnode, SRpcMsg *pReq, SDbObj *pDb, SSmaObj *p mDebug("trans:%d, used to drop sma:%s", pTrans->id, pSma->name); mndTransSetDbName(pTrans, pDb->name, NULL); - SStreamObj *pStream = mndAcquireStream(pMnode, pSma->name); + char streamName[TSDB_TABLE_FNAME_LEN] = {0}; + mndGetStreamNameFromSmaName(streamName, pSma->name); + + SStreamObj *pStream = mndAcquireStream(pMnode, streamName); if (pStream == NULL || pStream->smaId != pSma->uid) { sdbRelease(pMnode->pSdb, pStream); goto _OVER; @@ -838,7 +853,10 @@ int32_t mndDropSmasByStb(SMnode *pMnode, STrans *pTrans, SDbObj *pDb, SStbObj *p pVgroup = mndAcquireVgroup(pMnode, pSma->dstVgId); if (pVgroup == NULL) goto _OVER; - SStreamObj *pStream = mndAcquireStream(pMnode, pSma->name); + char streamName[TSDB_TABLE_FNAME_LEN] = {0}; + mndGetStreamNameFromSmaName(streamName, pSma->name); + + SStreamObj *pStream = mndAcquireStream(pMnode, streamName); if (pStream != NULL && pStream->smaId == pSma->uid) { if (mndDropStreamTasks(pMnode, pTrans, pStream) < 0) { mError("stream:%s, failed to drop task since %s", pStream->name, terrstr()); -- GitLab From dc4052bd7ba273380cb308990046444d9951d7c4 Mon Sep 17 00:00:00 2001 From: Haojun Liao Date: Thu, 14 Jul 2022 17:04:22 +0800 Subject: [PATCH 137/153] fix(query): handle the grouped fill. --- source/libs/executor/inc/executorimpl.h | 1 + source/libs/executor/src/executorimpl.c | 54 +++++++++++-------------- source/libs/executor/src/tfill.c | 17 ++++---- source/libs/function/src/builtinsimpl.c | 5 +-- 4 files changed, 37 insertions(+), 40 deletions(-) diff --git a/source/libs/executor/inc/executorimpl.h b/source/libs/executor/inc/executorimpl.h index 74bb80eed1..d5d52d41ac 100644 --- a/source/libs/executor/inc/executorimpl.h +++ b/source/libs/executor/inc/executorimpl.h @@ -561,6 +561,7 @@ typedef struct SFillOperatorInfo { SNode* pCondition; SArray* pColMatchColInfo; int32_t primaryTsCol; + uint64_t curGroupId; // current handled group id } SFillOperatorInfo; typedef struct SGroupbyOperatorInfo { diff --git a/source/libs/executor/src/executorimpl.c b/source/libs/executor/src/executorimpl.c index 674bbfef0b..29e2ffc956 100644 --- a/source/libs/executor/src/executorimpl.c +++ b/source/libs/executor/src/executorimpl.c @@ -1637,8 +1637,6 @@ static int32_t compressQueryColData(SColumnInfoData* pColRes, int32_t numOfRows, int32_t doFillTimeIntervalGapsInResults(struct SFillInfo* pFillInfo, SSDataBlock* pBlock, int32_t capacity) { int32_t numOfRows = (int32_t)taosFillResultDataBlock(pFillInfo, pBlock, capacity - pBlock->info.rows); - pBlock->info.rows += numOfRows; - return pBlock->info.rows; } @@ -3344,14 +3342,15 @@ static void doHandleRemainBlockForNewGroupImpl(SFillOperatorInfo* pInfo, SResult taosFillSetInputDataBlock(pInfo->pFillInfo, pInfo->existNewGroupBlock); doFillTimeIntervalGapsInResults(pInfo->pFillInfo, pInfo->pRes, pResultInfo->capacity); + pInfo->curGroupId = pInfo->existNewGroupBlock->info.groupId; pInfo->existNewGroupBlock = NULL; - *newgroup = true; +// *newgroup = true; } static void doHandleRemainBlockFromNewGroup(SFillOperatorInfo* pInfo, SResultInfo* pResultInfo, bool* newgroup, SExecTaskInfo* pTaskInfo) { if (taosFillHasMoreResults(pInfo->pFillInfo)) { - *newgroup = false; +// *newgroup = false; doFillTimeIntervalGapsInResults(pInfo->pFillInfo, pInfo->pRes, (int32_t)pResultInfo->capacity); if (pInfo->pRes->info.rows > pResultInfo->threshold || (!pInfo->multigroupResult)) { return; @@ -3373,10 +3372,7 @@ static SSDataBlock* doFillImpl(SOperatorInfo* pOperator) { blockDataCleanup(pResBlock); - // todo handle different group data interpolation - bool n = false; - bool* newgroup = &n; - doHandleRemainBlockFromNewGroup(pInfo, pResultInfo, newgroup, pTaskInfo); + doHandleRemainBlockFromNewGroup(pInfo, pResultInfo, NULL, pTaskInfo); if (pResBlock->info.rows > pResultInfo->threshold || (!pInfo->multigroupResult && pResBlock->info.rows > 0)) { return pResBlock; } @@ -3384,31 +3380,29 @@ static SSDataBlock* doFillImpl(SOperatorInfo* pOperator) { SOperatorInfo* pDownstream = pOperator->pDownstream[0]; while (1) { SSDataBlock* pBlock = pDownstream->fpSet.getNextFn(pDownstream); - if (*newgroup) { - assert(pBlock != NULL); - } - - blockDataUpdateTsWindow(pBlock, pInfo->primaryTsCol); - - if (*newgroup && pInfo->totalInputRows > 0) { // there are already processed current group data block - pInfo->existNewGroupBlock = pBlock; - *newgroup = false; + if (pBlock == NULL) { + if (pInfo->totalInputRows == 0) { + pOperator->status = OP_EXEC_DONE; + return NULL; + } - // Fill the previous group data block, before handle the data block of new group. - // Close the fill operation for previous group data block taosFillSetStartInfo(pInfo->pFillInfo, 0, pInfo->win.ekey); } else { - if (pBlock == NULL) { - if (pInfo->totalInputRows == 0) { - pOperator->status = OP_EXEC_DONE; - return NULL; - } + blockDataUpdateTsWindow(pBlock, pInfo->primaryTsCol); + + if (pInfo->curGroupId == 0 || pInfo->curGroupId == pBlock->info.groupId) { + pInfo->curGroupId = pBlock->info.groupId; // the first data block - taosFillSetStartInfo(pInfo->pFillInfo, 0, pInfo->win.ekey); - } else { pInfo->totalInputRows += pBlock->info.rows; + taosFillSetStartInfo(pInfo->pFillInfo, pBlock->info.rows, pBlock->info.window.ekey); taosFillSetInputDataBlock(pInfo->pFillInfo, pBlock); + } else if (pInfo->curGroupId != pBlock->info.groupId) { // the new group data block + pInfo->existNewGroupBlock = pBlock; + + // Fill the previous group data block, before handle the data block of new group. + // Close the fill operation for previous group data block + taosFillSetStartInfo(pInfo->pFillInfo, 0, pInfo->win.ekey); } } @@ -3419,17 +3413,17 @@ static SSDataBlock* doFillImpl(SOperatorInfo* pOperator) { if (pResBlock->info.rows > 0) { // 1. The result in current group not reach the threshold of output result, continue // 2. If multiple group results existing in one SSDataBlock is not allowed, return immediately - if (pResBlock->info.rows > pResultInfo->threshold || pBlock == NULL || (!pInfo->multigroupResult)) { + if (pResBlock->info.rows > pResultInfo->threshold || pBlock == NULL || pInfo->existNewGroupBlock != NULL) { return pResBlock; } - doHandleRemainBlockFromNewGroup(pInfo, pResultInfo, newgroup, pTaskInfo); - if (pResBlock->info.rows > pOperator->resultInfo.threshold || pBlock == NULL) { + doHandleRemainBlockFromNewGroup(pInfo, pResultInfo, NULL, pTaskInfo); + if (pResBlock->info.rows >= pOperator->resultInfo.threshold || pBlock == NULL) { return pResBlock; } } else if (pInfo->existNewGroupBlock) { // try next group assert(pBlock != NULL); - doHandleRemainBlockForNewGroupImpl(pInfo, pResultInfo, newgroup, pTaskInfo); + doHandleRemainBlockForNewGroupImpl(pInfo, pResultInfo, NULL, pTaskInfo); if (pResBlock->info.rows > pResultInfo->threshold) { return pResBlock; } diff --git a/source/libs/executor/src/tfill.c b/source/libs/executor/src/tfill.c index e0bdcfdc3a..550938140e 100644 --- a/source/libs/executor/src/tfill.c +++ b/source/libs/executor/src/tfill.c @@ -72,7 +72,7 @@ static void doFillOneRow(SFillInfo* pFillInfo, SSDataBlock* pBlock, SSDataBlock* int32_t step = GET_FORWARD_DIRECTION_FACTOR(pFillInfo->order); // set the primary timestamp column value - int32_t index = pFillInfo->numOfCurrent; + int32_t index = pBlock->info.rows; // set the other values if (pFillInfo->type == TSDB_FILL_PREV) { @@ -191,6 +191,7 @@ static void doFillOneRow(SFillInfo* pFillInfo, SSDataBlock* pBlock, SSDataBlock* SInterval* pInterval = &pFillInfo->interval; pFillInfo->currentKey = taosTimeAdd(pFillInfo->currentKey, pInterval->sliding * step, pInterval->slidingUnit, pInterval->precision); + pBlock->info.rows += 1; pFillInfo->numOfCurrent++; } @@ -273,6 +274,7 @@ static int32_t fillResultImpl(SFillInfo* pFillInfo, SSDataBlock* pBlock, int32_t } } else { assert(pFillInfo->currentKey == ts); + int32_t index = pBlock->info.rows; if (pFillInfo->type == TSDB_FILL_NEXT && (pFillInfo->index + 1) < pFillInfo->numOfRows) { int32_t nextRowIndex = pFillInfo->index + 1; @@ -296,24 +298,24 @@ static int32_t fillResultImpl(SFillInfo* pFillInfo, SSDataBlock* pBlock, int32_t if (i == 0 || (/*pCol->functionId != FUNCTION_COUNT &&*/ !colDataIsNull_s(pSrc, pFillInfo->index)) /*|| (pCol->functionId == FUNCTION_COUNT && GET_INT64_VAL(src) != 0)*/) { bool isNull = colDataIsNull_s(pSrc, pFillInfo->index); - colDataAppend(pDst, pFillInfo->numOfCurrent, src, isNull); + colDataAppend(pDst, index, src, isNull); saveColData(pFillInfo->prev, i, src, isNull); } else { // i > 0 and data is null , do interpolation if (pFillInfo->type == TSDB_FILL_PREV) { SGroupKeys* pKey = taosArrayGet(pFillInfo->prev, i); - doSetVal(pDst, pFillInfo->numOfCurrent, pKey); + doSetVal(pDst, index, pKey); } else if (pFillInfo->type == TSDB_FILL_LINEAR) { bool isNull = colDataIsNull_s(pSrc, pFillInfo->index); - colDataAppend(pDst, pFillInfo->numOfCurrent, src, isNull); + colDataAppend(pDst, index, src, isNull); saveColData(pFillInfo->prev, i, src, isNull); } else if (pFillInfo->type == TSDB_FILL_NULL) { - colDataAppendNULL(pDst, pFillInfo->numOfCurrent); + colDataAppendNULL(pDst, index); } else if (pFillInfo->type == TSDB_FILL_NEXT) { SGroupKeys* pKey = taosArrayGet(pFillInfo->next, i); - doSetVal(pDst, pFillInfo->numOfCurrent, pKey); + doSetVal(pDst, index, pKey); } else { SVariant* pVar = &pFillInfo->pFillCol[i].fillVal; - colDataAppend(pDst, pFillInfo->numOfCurrent, (char*)&pVar->i, false); + colDataAppend(pDst, index, (char*)&pVar->i, false); } } } @@ -324,6 +326,7 @@ static int32_t fillResultImpl(SFillInfo* pFillInfo, SSDataBlock* pBlock, int32_t pFillInfo->currentKey = taosTimeAdd(pFillInfo->currentKey, pInterval->sliding * step, pInterval->slidingUnit, pInterval->precision); + pBlock->info.rows += 1; pFillInfo->index += 1; pFillInfo->numOfCurrent += 1; } diff --git a/source/libs/function/src/builtinsimpl.c b/source/libs/function/src/builtinsimpl.c index 97cb1f0ee1..45d9c93c3e 100644 --- a/source/libs/function/src/builtinsimpl.c +++ b/source/libs/function/src/builtinsimpl.c @@ -6032,9 +6032,6 @@ int32_t lastrowFunction(SqlFunctionCtx* pCtx) { } pInfo->ts = cts; - pInfo->hasResult = true; - pResInfo->numOfRes = 1; - if (pCtx->subsidiaries.num > 0) { STuplePos* pTuplePos = (STuplePos*)(pInfo->buf + bytes + sizeof(TSKEY)); if (!pInfo->hasResult) { @@ -6043,6 +6040,8 @@ int32_t lastrowFunction(SqlFunctionCtx* pCtx) { copyTupleData(pCtx, i, pCtx->pSrcBlock, pTuplePos); } } + + pInfo->hasResult = true; } } -- GitLab From 0bb06920286ab2aabbad60f5d3f7bd2a80be0ede Mon Sep 17 00:00:00 2001 From: Shengliang Guan Date: Thu, 14 Jul 2022 16:24:22 +0800 Subject: [PATCH 138/153] test: restore some 2.0 case --- tests/script/general/parser/testSuite.sim | 68 ----------- tests/script/jenkins/basic.txt | 110 +++++++++++++++++- .../{general => tsim}/parser/README.txt | 0 .../script/{general => tsim}/parser/alter.sim | 0 .../{general => tsim}/parser/alter1.sim | 0 .../parser/alter__for_community_version.sim | 0 .../{general => tsim}/parser/alter_column.sim | 0 .../{general => tsim}/parser/alter_stable.sim | 0 .../parser/auto_create_tb.sim | 0 .../parser/auto_create_tb_drop_tb.sim | 0 .../{general => tsim}/parser/between_and.sim | 0 .../parser/binary_escapeCharacter.sim | 0 .../parser/col_arithmetic_operation.sim | 0 .../parser/col_arithmetic_query.sim | 0 .../{general => tsim}/parser/columnValue.sim | 0 .../parser/columnValue_bigint.sim | 0 .../parser/columnValue_bool.sim | 0 .../parser/columnValue_double.sim | 0 .../parser/columnValue_float.sim | 0 .../parser/columnValue_int.sim | 0 .../parser/columnValue_smallint.sim | 0 .../parser/columnValue_tinyint.sim | 0 .../parser/columnValue_unsign.sim | 0 .../{general => tsim}/parser/commit.sim | 0 .../{general => tsim}/parser/condition.sim | 0 .../parser/condition_query.sim | 0 .../{general => tsim}/parser/constCol.sim | 0 .../{general => tsim}/parser/create_db.sim | 0 .../create_db__for_community_version.sim | 0 .../{general => tsim}/parser/create_mt.sim | 0 .../{general => tsim}/parser/create_tb.sim | 0 .../parser/create_tb_with_tag_name.sim | 0 .../parser/dbtbnameValidate.sim | 0 .../{general => tsim}/parser/distinct.sim | 0 .../script/{general => tsim}/parser/fill.sim | 0 .../{general => tsim}/parser/fill_stb.sim | 0 .../{general => tsim}/parser/fill_us.sim | 0 .../{general => tsim}/parser/first_last.sim | 0 .../parser/first_last_query.sim | 0 .../{general => tsim}/parser/function.sim | 0 .../{general => tsim}/parser/gendata.sh | 0 .../{general => tsim}/parser/groupby.sim | 0 .../{general => tsim}/parser/having.sim | 0 .../{general => tsim}/parser/having_child.sim | 0 .../{general => tsim}/parser/import.sim | 0 .../parser/import_commit1.sim | 0 .../parser/import_commit2.sim | 0 .../parser/import_commit3.sim | 0 .../{general => tsim}/parser/import_file.sim | 0 .../parser/insert_multiTbl.sim | 0 .../{general => tsim}/parser/insert_tb.sim | 0 .../{general => tsim}/parser/interp.sim | 0 .../{general => tsim}/parser/interp_test.sim | 0 .../script/{general => tsim}/parser/join.sim | 0 .../parser/join_manyblocks.sim | 0 .../parser/join_multitables.sim | 0 .../parser/join_multivnode.sim | 0 .../{general => tsim}/parser/last_cache.sim | 0 .../parser/last_cache_query.sim | 0 .../{general => tsim}/parser/last_groupby.sim | 0 .../{general => tsim}/parser/lastrow.sim | 0 .../parser/lastrow_query.sim | 0 .../script/{general => tsim}/parser/like.sim | 0 .../script/{general => tsim}/parser/limit.sim | 0 .../{general => tsim}/parser/limit1.sim | 0 .../{general => tsim}/parser/limit1_stb.sim | 0 .../{general => tsim}/parser/limit1_tb.sim | 0 .../parser/limit1_tblocks100.sim | 0 .../{general => tsim}/parser/limit2.sim | 0 .../{general => tsim}/parser/limit2_query.sim | 0 .../parser/limit2_tblocks100.sim | 0 .../{general => tsim}/parser/limit_stb.sim | 0 .../{general => tsim}/parser/limit_tb.sim | 0 .../{general => tsim}/parser/line_insert.sim | 0 .../{general => tsim}/parser/mixed_blocks.sim | 0 .../script/{general => tsim}/parser/nchar.sim | 0 .../{general => tsim}/parser/nestquery.sim | 0 .../{general => tsim}/parser/null_char.sim | 0 .../{general => tsim}/parser/precision_ns.sim | 0 .../parser/projection_limit_offset.sim | 0 .../script/{general => tsim}/parser/regex.sim | 0 .../{general => tsim}/parser/repeatAlter.sim | 0 .../{general => tsim}/parser/selectResNum.sim | 0 .../parser/select_across_vnodes.sim | 0 .../parser/select_distinct_tag.sim | 0 .../parser/select_from_cache_disk.sim | 0 .../parser/select_with_tags.sim | 0 .../{general => tsim}/parser/set_tag_vals.sim | 0 .../parser/single_row_in_tb.sim | 0 .../parser/single_row_in_tb_query.sim | 0 .../{general => tsim}/parser/sliding.sim | 0 .../{general => tsim}/parser/slimit.sim | 0 .../{general => tsim}/parser/slimit1.sim | 0 .../parser/slimit1_query.sim | 0 .../parser/slimit_alter_tags.sim | 0 .../{general => tsim}/parser/slimit_query.sim | 0 .../{general => tsim}/parser/stableOp.sim | 0 .../parser/tags_dynamically_specifiy.sim | 0 .../{general => tsim}/parser/tags_filter.sim | 0 .../{general => tsim}/parser/tbnameIn.sim | 0 .../parser/tbnameIn_query.sim | 0 .../{general => tsim}/parser/timestamp.sim | 0 .../parser/timestamp_query.sim | 0 .../{general => tsim}/parser/top_groupby.sim | 0 .../{general => tsim}/parser/topbot.sim | 0 tests/script/{general => tsim}/parser/udf.sim | 0 .../{general => tsim}/parser/udf_dll.sim | 0 .../parser/udf_dll_stable.sim | 0 .../script/{general => tsim}/parser/union.sim | 0 .../script/{general => tsim}/parser/where.sim | 0 110 files changed, 108 insertions(+), 70 deletions(-) delete mode 100644 tests/script/general/parser/testSuite.sim rename tests/script/{general => tsim}/parser/README.txt (100%) rename tests/script/{general => tsim}/parser/alter.sim (100%) rename tests/script/{general => tsim}/parser/alter1.sim (100%) rename tests/script/{general => tsim}/parser/alter__for_community_version.sim (100%) rename tests/script/{general => tsim}/parser/alter_column.sim (100%) rename tests/script/{general => tsim}/parser/alter_stable.sim (100%) rename tests/script/{general => tsim}/parser/auto_create_tb.sim (100%) rename tests/script/{general => tsim}/parser/auto_create_tb_drop_tb.sim (100%) rename tests/script/{general => tsim}/parser/between_and.sim (100%) rename tests/script/{general => tsim}/parser/binary_escapeCharacter.sim (100%) rename tests/script/{general => tsim}/parser/col_arithmetic_operation.sim (100%) rename tests/script/{general => tsim}/parser/col_arithmetic_query.sim (100%) rename tests/script/{general => tsim}/parser/columnValue.sim (100%) rename tests/script/{general => tsim}/parser/columnValue_bigint.sim (100%) rename tests/script/{general => tsim}/parser/columnValue_bool.sim (100%) rename tests/script/{general => tsim}/parser/columnValue_double.sim (100%) rename tests/script/{general => tsim}/parser/columnValue_float.sim (100%) rename tests/script/{general => tsim}/parser/columnValue_int.sim (100%) rename tests/script/{general => tsim}/parser/columnValue_smallint.sim (100%) rename tests/script/{general => tsim}/parser/columnValue_tinyint.sim (100%) rename tests/script/{general => tsim}/parser/columnValue_unsign.sim (100%) rename tests/script/{general => tsim}/parser/commit.sim (100%) rename tests/script/{general => tsim}/parser/condition.sim (100%) rename tests/script/{general => tsim}/parser/condition_query.sim (100%) rename tests/script/{general => tsim}/parser/constCol.sim (100%) rename tests/script/{general => tsim}/parser/create_db.sim (100%) rename tests/script/{general => tsim}/parser/create_db__for_community_version.sim (100%) rename tests/script/{general => tsim}/parser/create_mt.sim (100%) rename tests/script/{general => tsim}/parser/create_tb.sim (100%) rename tests/script/{general => tsim}/parser/create_tb_with_tag_name.sim (100%) rename tests/script/{general => tsim}/parser/dbtbnameValidate.sim (100%) rename tests/script/{general => tsim}/parser/distinct.sim (100%) rename tests/script/{general => tsim}/parser/fill.sim (100%) rename tests/script/{general => tsim}/parser/fill_stb.sim (100%) rename tests/script/{general => tsim}/parser/fill_us.sim (100%) rename tests/script/{general => tsim}/parser/first_last.sim (100%) rename tests/script/{general => tsim}/parser/first_last_query.sim (100%) rename tests/script/{general => tsim}/parser/function.sim (100%) rename tests/script/{general => tsim}/parser/gendata.sh (100%) rename tests/script/{general => tsim}/parser/groupby.sim (100%) rename tests/script/{general => tsim}/parser/having.sim (100%) rename tests/script/{general => tsim}/parser/having_child.sim (100%) rename tests/script/{general => tsim}/parser/import.sim (100%) rename tests/script/{general => tsim}/parser/import_commit1.sim (100%) rename tests/script/{general => tsim}/parser/import_commit2.sim (100%) rename tests/script/{general => tsim}/parser/import_commit3.sim (100%) rename tests/script/{general => tsim}/parser/import_file.sim (100%) rename tests/script/{general => tsim}/parser/insert_multiTbl.sim (100%) rename tests/script/{general => tsim}/parser/insert_tb.sim (100%) rename tests/script/{general => tsim}/parser/interp.sim (100%) rename tests/script/{general => tsim}/parser/interp_test.sim (100%) rename tests/script/{general => tsim}/parser/join.sim (100%) rename tests/script/{general => tsim}/parser/join_manyblocks.sim (100%) rename tests/script/{general => tsim}/parser/join_multitables.sim (100%) rename tests/script/{general => tsim}/parser/join_multivnode.sim (100%) rename tests/script/{general => tsim}/parser/last_cache.sim (100%) rename tests/script/{general => tsim}/parser/last_cache_query.sim (100%) rename tests/script/{general => tsim}/parser/last_groupby.sim (100%) rename tests/script/{general => tsim}/parser/lastrow.sim (100%) rename tests/script/{general => tsim}/parser/lastrow_query.sim (100%) rename tests/script/{general => tsim}/parser/like.sim (100%) rename tests/script/{general => tsim}/parser/limit.sim (100%) rename tests/script/{general => tsim}/parser/limit1.sim (100%) rename tests/script/{general => tsim}/parser/limit1_stb.sim (100%) rename tests/script/{general => tsim}/parser/limit1_tb.sim (100%) rename tests/script/{general => tsim}/parser/limit1_tblocks100.sim (100%) rename tests/script/{general => tsim}/parser/limit2.sim (100%) rename tests/script/{general => tsim}/parser/limit2_query.sim (100%) rename tests/script/{general => tsim}/parser/limit2_tblocks100.sim (100%) rename tests/script/{general => tsim}/parser/limit_stb.sim (100%) rename tests/script/{general => tsim}/parser/limit_tb.sim (100%) rename tests/script/{general => tsim}/parser/line_insert.sim (100%) rename tests/script/{general => tsim}/parser/mixed_blocks.sim (100%) rename tests/script/{general => tsim}/parser/nchar.sim (100%) rename tests/script/{general => tsim}/parser/nestquery.sim (100%) rename tests/script/{general => tsim}/parser/null_char.sim (100%) rename tests/script/{general => tsim}/parser/precision_ns.sim (100%) rename tests/script/{general => tsim}/parser/projection_limit_offset.sim (100%) rename tests/script/{general => tsim}/parser/regex.sim (100%) rename tests/script/{general => tsim}/parser/repeatAlter.sim (100%) rename tests/script/{general => tsim}/parser/selectResNum.sim (100%) rename tests/script/{general => tsim}/parser/select_across_vnodes.sim (100%) rename tests/script/{general => tsim}/parser/select_distinct_tag.sim (100%) rename tests/script/{general => tsim}/parser/select_from_cache_disk.sim (100%) rename tests/script/{general => tsim}/parser/select_with_tags.sim (100%) rename tests/script/{general => tsim}/parser/set_tag_vals.sim (100%) rename tests/script/{general => tsim}/parser/single_row_in_tb.sim (100%) rename tests/script/{general => tsim}/parser/single_row_in_tb_query.sim (100%) rename tests/script/{general => tsim}/parser/sliding.sim (100%) rename tests/script/{general => tsim}/parser/slimit.sim (100%) rename tests/script/{general => tsim}/parser/slimit1.sim (100%) rename tests/script/{general => tsim}/parser/slimit1_query.sim (100%) rename tests/script/{general => tsim}/parser/slimit_alter_tags.sim (100%) rename tests/script/{general => tsim}/parser/slimit_query.sim (100%) rename tests/script/{general => tsim}/parser/stableOp.sim (100%) rename tests/script/{general => tsim}/parser/tags_dynamically_specifiy.sim (100%) rename tests/script/{general => tsim}/parser/tags_filter.sim (100%) rename tests/script/{general => tsim}/parser/tbnameIn.sim (100%) rename tests/script/{general => tsim}/parser/tbnameIn_query.sim (100%) rename tests/script/{general => tsim}/parser/timestamp.sim (100%) rename tests/script/{general => tsim}/parser/timestamp_query.sim (100%) rename tests/script/{general => tsim}/parser/top_groupby.sim (100%) rename tests/script/{general => tsim}/parser/topbot.sim (100%) rename tests/script/{general => tsim}/parser/udf.sim (100%) rename tests/script/{general => tsim}/parser/udf_dll.sim (100%) rename tests/script/{general => tsim}/parser/udf_dll_stable.sim (100%) rename tests/script/{general => tsim}/parser/union.sim (100%) rename tests/script/{general => tsim}/parser/where.sim (100%) diff --git a/tests/script/general/parser/testSuite.sim b/tests/script/general/parser/testSuite.sim deleted file mode 100644 index fcd9d49fe5..0000000000 --- a/tests/script/general/parser/testSuite.sim +++ /dev/null @@ -1,68 +0,0 @@ -run general/parser/alter.sim -run general/parser/alter1.sim -run general/parser/alter_stable.sim -run general/parser/auto_create_tb.sim -run general/parser/auto_create_tb_drop_tb.sim -run general/parser/col_arithmetic_operation.sim -run general/parser/columnValue.sim -run general/parser/commit.sim -run general/parser/create_db.sim -run general/parser/create_mt.sim -run general/parser/create_tb.sim -run general/parser/dbtbnameValidate.sim -run general/parser/fill.sim -run general/parser/fill_stb.sim -#run general/parser/fill_us.sim # -run general/parser/first_last.sim -run general/parser/import_commit1.sim -run general/parser/import_commit2.sim -run general/parser/import_commit3.sim -run general/parser/import_file.sim -run general/parser/insert_tb.sim -run general/parser/tags_dynamically_specifiy.sim -run general/parser/interp.sim -run general/parser/lastrow.sim -run general/parser/limit.sim -run general/parser/limit1.sim -run general/parser/limit1_tblocks100.sim -run general/parser/limit2.sim -run general/parser/mixed_blocks.sim -run general/parser/nchar.sim -run general/parser/null_char.sim -run general/parser/selectResNum.sim -run general/parser/select_across_vnodes.sim -run general/parser/select_from_cache_disk.sim -run general/parser/set_tag_vals.sim -run general/parser/single_row_in_tb.sim -run general/parser/slimit.sim -run general/parser/slimit1.sim -run general/parser/slimit_alter_tags.sim -run general/parser/tbnameIn.sim -run general/parser/join.sim -run general/parser/join_multivnode.sim -run general/parser/join_manyblocks.sim -run general/parser/projection_limit_offset.sim -run general/parser/select_with_tags.sim -run general/parser/select_distinct_tag.sim -run general/parser/groupby.sim -run general/parser/tags_filter.sim -run general/parser/topbot.sim -run general/parser/union.sim -run general/parser/constCol.sim -run general/parser/where.sim -run general/parser/timestamp.sim -run general/parser/sliding.sim -run general/parser/function.sim -run general/parser/stableOp.sim -run general/parser/having.sim -run general/parser/having_child.sim -run general/parser/slimit_alter_tags.sim -run general/parser/binary_escapeCharacter.sim -run general/parser/between_and.sim -run general/parser/last_cache.sim -run general/parser/slimit_alter_tags.sim -run general/parser/udf.sim -run general/parser/udf_dll.sim -run general/parser/udf_dll_stable.sim -run general/parser/nestquery.sim -run general/parser/precision_ns.sim diff --git a/tests/script/jenkins/basic.txt b/tests/script/jenkins/basic.txt index 4c77051426..6b3031c0e5 100644 --- a/tests/script/jenkins/basic.txt +++ b/tests/script/jenkins/basic.txt @@ -94,8 +94,114 @@ ./test.sh -f tsim/insert/update0.sim # ---- parser -./test.sh -f tsim/parser/groupby-basic.sim +# ./test.sh -f tsim/parser/alter.sim +# ./test.sh -f tsim/parser/alter1.sim +## ./test.sh -f tsim/parser/alter__for_community_version.sim +## ./test.sh -f tsim/parser/alter_column.sim +# ./test.sh -f tsim/parser/alter_stable.sim +# ./test.sh -f tsim/parser/auto_create_tb.sim +# ./test.sh -f tsim/parser/auto_create_tb_drop_tb.sim +# ./test.sh -f tsim/parser/between_and.sim +# ./test.sh -f tsim/parser/binary_escapeCharacter.sim +# ./test.sh -f tsim/parser/col_arithmetic_operation.sim +## ./test.sh -f tsim/parser/col_arithmetic_query.sim +## ./test.sh -f tsim/parser/columnValue.sim +## ./test.sh -f tsim/parser/columnValue_bigint.sim +## ./test.sh -f tsim/parser/columnValue_bool.sim +## ./test.sh -f tsim/parser/columnValue_double.sim +## ./test.sh -f tsim/parser/columnValue_float.sim +## ./test.sh -f tsim/parser/columnValue_int.sim +## ./test.sh -f tsim/parser/columnValue_smallint.sim +## ./test.sh -f tsim/parser/columnValue_tinyint.sim +## ./test.sh -f tsim/parser/columnValue_unsign.sim +## ./test.sh -f tsim/parser/commit.sim +## ./test.sh -f tsim/parser/condition.sim +## ./test.sh -f tsim/parser/condition_query.sim +## ./test.sh -f tsim/parser/constCol.sim +# ./test.sh -f tsim/parser/create_db.sim +## ./test.sh -f tsim/parser/create_db__for_community_version.sim +# ./test.sh -f tsim/parser/create_mt.sim +# ./test.sh -f tsim/parser/create_tb.sim +## ./test.sh -f tsim/parser/create_tb_with_tag_name.sim +# ./test.sh -f tsim/parser/dbtbnameValidate.sim +##./test.sh -f tsim/parser/distinct.sim +# ./test.sh -f tsim/parser/fill.sim +# ./test.sh -f tsim/parser/fill_stb.sim +## ./test.sh -f tsim/parser/fill_us.sim +# ./test.sh -f tsim/parser/first_last.sim +## ./test.sh -f tsim/parser/first_last_query.sim ./test.sh -f tsim/parser/fourArithmetic-basic.sim +## ./test.sh -f tsim/parser/function.sim +./test.sh -f tsim/parser/groupby-basic.sim +# ./test.sh -f tsim/parser/groupby.sim +## ./test.sh -f tsim/parser/having.sim +# ./test.sh -f tsim/parser/having_child.sim +## ./test.sh -f tsim/parser/import.sim +# ./test.sh -f tsim/parser/import_commit1.sim +# ./test.sh -f tsim/parser/import_commit2.sim +# ./test.sh -f tsim/parser/import_commit3.sim +## ./test.sh -f tsim/parser/import_file.sim +## ./test.sh -f tsim/parser/insert_multiTbl.sim +# ./test.sh -f tsim/parser/insert_tb.sim +## ./test.sh -f tsim/parser/interp.sim +## ./test.sh -f tsim/parser/interp_test.sim +# ./test.sh -f tsim/parser/join.sim +# ./test.sh -f tsim/parser/join_manyblocks.sim +## ./test.sh -f tsim/parser/join_multitables.sim +# ./test.sh -f tsim/parser/join_multivnode.sim +# ./test.sh -f tsim/parser/last_cache.sim +## ./test.sh -f tsim/parser/last_cache_query.sim +## ./test.sh -f tsim/parser/last_groupby.sim +# ./test.sh -f tsim/parser/lastrow.sim +## ./test.sh -f tsim/parser/lastrow_query.sim +## ./test.sh -f tsim/parser/like.sim +# ./test.sh -f tsim/parser/limit.sim +# ./test.sh -f tsim/parser/limit1.sim +## ./test.sh -f tsim/parser/limit1_stb.sim +## ./test.sh -f tsim/parser/limit1_tb.sim +# ./test.sh -f tsim/parser/limit1_tblocks100.sim +## ./test.sh -f tsim/parser/limit2.sim +## ./test.sh -f tsim/parser/limit2_query.sim +## ./test.sh -f tsim/parser/limit2_tblocks100.sim +## ./test.sh -f tsim/parser/limit_stb.sim +## ./test.sh -f tsim/parser/limit_tb.sim +## ./test.sh -f tsim/parser/line_insert.sim +# ./test.sh -f tsim/parser/mixed_blocks.sim +# ./test.sh -f tsim/parser/nchar.sim +# ./test.sh -f tsim/parser/nestquery.sim +# ./test.sh -f tsim/parser/null_char.sim +## ./test.sh -f tsim/parser/precision_ns.sim +# ./test.sh -f tsim/parser/projection_limit_offset.sim +## ./test.sh -f tsim/parser/regex.sim +# ./test.sh -f tsim/parser/repeatAlter.sim +# ./test.sh -f tsim/parser/selectResNum.sim +# ./test.sh -f tsim/parser/select_across_vnodes.sim +# ./test.sh -f tsim/parser/select_distinct_tag.sim +# ./test.sh -f tsim/parser/select_from_cache_disk.sim +# ./test.sh -f tsim/parser/select_with_tags.sim +# ./test.sh -f tsim/parser/set_tag_vals.sim +# ./test.sh -f tsim/parser/single_row_in_tb.sim +## ./test.sh -f tsim/parser/single_row_in_tb_query.sim +# ./test.sh -f tsim/parser/sliding.sim +# ./test.sh -f tsim/parser/slimit.sim +# ./test.sh -f tsim/parser/slimit1.sim +## ./test.sh -f tsim/parser/slimit1_query.sim +# ./test.sh -f tsim/parser/slimit_alter_tags.sim +## ./test.sh -f tsim/parser/slimit_query.sim +# ./test.sh -f tsim/parser/stableOp.sim +# ./test.sh -f tsim/parser/tags_dynamically_specifiy.sim +# ./test.sh -f tsim/parser/tags_filter.sim +# ./test.sh -f tsim/parser/tbnameIn.sim +## ./test.sh -f tsim/parser/tbnameIn_query.sim +# ./test.sh -f tsim/parser/timestamp.sim +## ./test.sh -f tsim/parser/timestamp_query.sim +## ./test.sh -f tsim/parser/top_groupby.sim +# ./test.sh -f tsim/parser/topbot.sim +# ./test.sh -f tsim/parser/udf.sim +# ./test.sh -f tsim/parser/udf_dll.sim +# ./test.sh -f tsim/parser/udf_dll_stable.sim +# ./test.sh -f tsim/parser/union.sim +# ./test.sh -f tsim/parser/where.sim # ---- query ./test.sh -f tsim/query/interval.sim @@ -220,7 +326,7 @@ ./test.sh -f tsim/db/basic3.sim -m ./test.sh -f tsim/db/error1.sim -m ./test.sh -f tsim/insert/backquote.sim -m -./test.sh -f tsim/parser/fourArithmetic-basic.sim -m +# ./test.sh -f tsim/parser/fourArithmetic-basic.sim -m ./test.sh -f tsim/query/interval-offset.sim -m ./test.sh -f tsim/tmq/basic3.sim -m ./test.sh -f tsim/stable/vnode3.sim -m diff --git a/tests/script/general/parser/README.txt b/tests/script/tsim/parser/README.txt similarity index 100% rename from tests/script/general/parser/README.txt rename to tests/script/tsim/parser/README.txt diff --git a/tests/script/general/parser/alter.sim b/tests/script/tsim/parser/alter.sim similarity index 100% rename from tests/script/general/parser/alter.sim rename to tests/script/tsim/parser/alter.sim diff --git a/tests/script/general/parser/alter1.sim b/tests/script/tsim/parser/alter1.sim similarity index 100% rename from tests/script/general/parser/alter1.sim rename to tests/script/tsim/parser/alter1.sim diff --git a/tests/script/general/parser/alter__for_community_version.sim b/tests/script/tsim/parser/alter__for_community_version.sim similarity index 100% rename from tests/script/general/parser/alter__for_community_version.sim rename to tests/script/tsim/parser/alter__for_community_version.sim diff --git a/tests/script/general/parser/alter_column.sim b/tests/script/tsim/parser/alter_column.sim similarity index 100% rename from tests/script/general/parser/alter_column.sim rename to tests/script/tsim/parser/alter_column.sim diff --git a/tests/script/general/parser/alter_stable.sim b/tests/script/tsim/parser/alter_stable.sim similarity index 100% rename from tests/script/general/parser/alter_stable.sim rename to tests/script/tsim/parser/alter_stable.sim diff --git a/tests/script/general/parser/auto_create_tb.sim b/tests/script/tsim/parser/auto_create_tb.sim similarity index 100% rename from tests/script/general/parser/auto_create_tb.sim rename to tests/script/tsim/parser/auto_create_tb.sim diff --git a/tests/script/general/parser/auto_create_tb_drop_tb.sim b/tests/script/tsim/parser/auto_create_tb_drop_tb.sim similarity index 100% rename from tests/script/general/parser/auto_create_tb_drop_tb.sim rename to tests/script/tsim/parser/auto_create_tb_drop_tb.sim diff --git a/tests/script/general/parser/between_and.sim b/tests/script/tsim/parser/between_and.sim similarity index 100% rename from tests/script/general/parser/between_and.sim rename to tests/script/tsim/parser/between_and.sim diff --git a/tests/script/general/parser/binary_escapeCharacter.sim b/tests/script/tsim/parser/binary_escapeCharacter.sim similarity index 100% rename from tests/script/general/parser/binary_escapeCharacter.sim rename to tests/script/tsim/parser/binary_escapeCharacter.sim diff --git a/tests/script/general/parser/col_arithmetic_operation.sim b/tests/script/tsim/parser/col_arithmetic_operation.sim similarity index 100% rename from tests/script/general/parser/col_arithmetic_operation.sim rename to tests/script/tsim/parser/col_arithmetic_operation.sim diff --git a/tests/script/general/parser/col_arithmetic_query.sim b/tests/script/tsim/parser/col_arithmetic_query.sim similarity index 100% rename from tests/script/general/parser/col_arithmetic_query.sim rename to tests/script/tsim/parser/col_arithmetic_query.sim diff --git a/tests/script/general/parser/columnValue.sim b/tests/script/tsim/parser/columnValue.sim similarity index 100% rename from tests/script/general/parser/columnValue.sim rename to tests/script/tsim/parser/columnValue.sim diff --git a/tests/script/general/parser/columnValue_bigint.sim b/tests/script/tsim/parser/columnValue_bigint.sim similarity index 100% rename from tests/script/general/parser/columnValue_bigint.sim rename to tests/script/tsim/parser/columnValue_bigint.sim diff --git a/tests/script/general/parser/columnValue_bool.sim b/tests/script/tsim/parser/columnValue_bool.sim similarity index 100% rename from tests/script/general/parser/columnValue_bool.sim rename to tests/script/tsim/parser/columnValue_bool.sim diff --git a/tests/script/general/parser/columnValue_double.sim b/tests/script/tsim/parser/columnValue_double.sim similarity index 100% rename from tests/script/general/parser/columnValue_double.sim rename to tests/script/tsim/parser/columnValue_double.sim diff --git a/tests/script/general/parser/columnValue_float.sim b/tests/script/tsim/parser/columnValue_float.sim similarity index 100% rename from tests/script/general/parser/columnValue_float.sim rename to tests/script/tsim/parser/columnValue_float.sim diff --git a/tests/script/general/parser/columnValue_int.sim b/tests/script/tsim/parser/columnValue_int.sim similarity index 100% rename from tests/script/general/parser/columnValue_int.sim rename to tests/script/tsim/parser/columnValue_int.sim diff --git a/tests/script/general/parser/columnValue_smallint.sim b/tests/script/tsim/parser/columnValue_smallint.sim similarity index 100% rename from tests/script/general/parser/columnValue_smallint.sim rename to tests/script/tsim/parser/columnValue_smallint.sim diff --git a/tests/script/general/parser/columnValue_tinyint.sim b/tests/script/tsim/parser/columnValue_tinyint.sim similarity index 100% rename from tests/script/general/parser/columnValue_tinyint.sim rename to tests/script/tsim/parser/columnValue_tinyint.sim diff --git a/tests/script/general/parser/columnValue_unsign.sim b/tests/script/tsim/parser/columnValue_unsign.sim similarity index 100% rename from tests/script/general/parser/columnValue_unsign.sim rename to tests/script/tsim/parser/columnValue_unsign.sim diff --git a/tests/script/general/parser/commit.sim b/tests/script/tsim/parser/commit.sim similarity index 100% rename from tests/script/general/parser/commit.sim rename to tests/script/tsim/parser/commit.sim diff --git a/tests/script/general/parser/condition.sim b/tests/script/tsim/parser/condition.sim similarity index 100% rename from tests/script/general/parser/condition.sim rename to tests/script/tsim/parser/condition.sim diff --git a/tests/script/general/parser/condition_query.sim b/tests/script/tsim/parser/condition_query.sim similarity index 100% rename from tests/script/general/parser/condition_query.sim rename to tests/script/tsim/parser/condition_query.sim diff --git a/tests/script/general/parser/constCol.sim b/tests/script/tsim/parser/constCol.sim similarity index 100% rename from tests/script/general/parser/constCol.sim rename to tests/script/tsim/parser/constCol.sim diff --git a/tests/script/general/parser/create_db.sim b/tests/script/tsim/parser/create_db.sim similarity index 100% rename from tests/script/general/parser/create_db.sim rename to tests/script/tsim/parser/create_db.sim diff --git a/tests/script/general/parser/create_db__for_community_version.sim b/tests/script/tsim/parser/create_db__for_community_version.sim similarity index 100% rename from tests/script/general/parser/create_db__for_community_version.sim rename to tests/script/tsim/parser/create_db__for_community_version.sim diff --git a/tests/script/general/parser/create_mt.sim b/tests/script/tsim/parser/create_mt.sim similarity index 100% rename from tests/script/general/parser/create_mt.sim rename to tests/script/tsim/parser/create_mt.sim diff --git a/tests/script/general/parser/create_tb.sim b/tests/script/tsim/parser/create_tb.sim similarity index 100% rename from tests/script/general/parser/create_tb.sim rename to tests/script/tsim/parser/create_tb.sim diff --git a/tests/script/general/parser/create_tb_with_tag_name.sim b/tests/script/tsim/parser/create_tb_with_tag_name.sim similarity index 100% rename from tests/script/general/parser/create_tb_with_tag_name.sim rename to tests/script/tsim/parser/create_tb_with_tag_name.sim diff --git a/tests/script/general/parser/dbtbnameValidate.sim b/tests/script/tsim/parser/dbtbnameValidate.sim similarity index 100% rename from tests/script/general/parser/dbtbnameValidate.sim rename to tests/script/tsim/parser/dbtbnameValidate.sim diff --git a/tests/script/general/parser/distinct.sim b/tests/script/tsim/parser/distinct.sim similarity index 100% rename from tests/script/general/parser/distinct.sim rename to tests/script/tsim/parser/distinct.sim diff --git a/tests/script/general/parser/fill.sim b/tests/script/tsim/parser/fill.sim similarity index 100% rename from tests/script/general/parser/fill.sim rename to tests/script/tsim/parser/fill.sim diff --git a/tests/script/general/parser/fill_stb.sim b/tests/script/tsim/parser/fill_stb.sim similarity index 100% rename from tests/script/general/parser/fill_stb.sim rename to tests/script/tsim/parser/fill_stb.sim diff --git a/tests/script/general/parser/fill_us.sim b/tests/script/tsim/parser/fill_us.sim similarity index 100% rename from tests/script/general/parser/fill_us.sim rename to tests/script/tsim/parser/fill_us.sim diff --git a/tests/script/general/parser/first_last.sim b/tests/script/tsim/parser/first_last.sim similarity index 100% rename from tests/script/general/parser/first_last.sim rename to tests/script/tsim/parser/first_last.sim diff --git a/tests/script/general/parser/first_last_query.sim b/tests/script/tsim/parser/first_last_query.sim similarity index 100% rename from tests/script/general/parser/first_last_query.sim rename to tests/script/tsim/parser/first_last_query.sim diff --git a/tests/script/general/parser/function.sim b/tests/script/tsim/parser/function.sim similarity index 100% rename from tests/script/general/parser/function.sim rename to tests/script/tsim/parser/function.sim diff --git a/tests/script/general/parser/gendata.sh b/tests/script/tsim/parser/gendata.sh similarity index 100% rename from tests/script/general/parser/gendata.sh rename to tests/script/tsim/parser/gendata.sh diff --git a/tests/script/general/parser/groupby.sim b/tests/script/tsim/parser/groupby.sim similarity index 100% rename from tests/script/general/parser/groupby.sim rename to tests/script/tsim/parser/groupby.sim diff --git a/tests/script/general/parser/having.sim b/tests/script/tsim/parser/having.sim similarity index 100% rename from tests/script/general/parser/having.sim rename to tests/script/tsim/parser/having.sim diff --git a/tests/script/general/parser/having_child.sim b/tests/script/tsim/parser/having_child.sim similarity index 100% rename from tests/script/general/parser/having_child.sim rename to tests/script/tsim/parser/having_child.sim diff --git a/tests/script/general/parser/import.sim b/tests/script/tsim/parser/import.sim similarity index 100% rename from tests/script/general/parser/import.sim rename to tests/script/tsim/parser/import.sim diff --git a/tests/script/general/parser/import_commit1.sim b/tests/script/tsim/parser/import_commit1.sim similarity index 100% rename from tests/script/general/parser/import_commit1.sim rename to tests/script/tsim/parser/import_commit1.sim diff --git a/tests/script/general/parser/import_commit2.sim b/tests/script/tsim/parser/import_commit2.sim similarity index 100% rename from tests/script/general/parser/import_commit2.sim rename to tests/script/tsim/parser/import_commit2.sim diff --git a/tests/script/general/parser/import_commit3.sim b/tests/script/tsim/parser/import_commit3.sim similarity index 100% rename from tests/script/general/parser/import_commit3.sim rename to tests/script/tsim/parser/import_commit3.sim diff --git a/tests/script/general/parser/import_file.sim b/tests/script/tsim/parser/import_file.sim similarity index 100% rename from tests/script/general/parser/import_file.sim rename to tests/script/tsim/parser/import_file.sim diff --git a/tests/script/general/parser/insert_multiTbl.sim b/tests/script/tsim/parser/insert_multiTbl.sim similarity index 100% rename from tests/script/general/parser/insert_multiTbl.sim rename to tests/script/tsim/parser/insert_multiTbl.sim diff --git a/tests/script/general/parser/insert_tb.sim b/tests/script/tsim/parser/insert_tb.sim similarity index 100% rename from tests/script/general/parser/insert_tb.sim rename to tests/script/tsim/parser/insert_tb.sim diff --git a/tests/script/general/parser/interp.sim b/tests/script/tsim/parser/interp.sim similarity index 100% rename from tests/script/general/parser/interp.sim rename to tests/script/tsim/parser/interp.sim diff --git a/tests/script/general/parser/interp_test.sim b/tests/script/tsim/parser/interp_test.sim similarity index 100% rename from tests/script/general/parser/interp_test.sim rename to tests/script/tsim/parser/interp_test.sim diff --git a/tests/script/general/parser/join.sim b/tests/script/tsim/parser/join.sim similarity index 100% rename from tests/script/general/parser/join.sim rename to tests/script/tsim/parser/join.sim diff --git a/tests/script/general/parser/join_manyblocks.sim b/tests/script/tsim/parser/join_manyblocks.sim similarity index 100% rename from tests/script/general/parser/join_manyblocks.sim rename to tests/script/tsim/parser/join_manyblocks.sim diff --git a/tests/script/general/parser/join_multitables.sim b/tests/script/tsim/parser/join_multitables.sim similarity index 100% rename from tests/script/general/parser/join_multitables.sim rename to tests/script/tsim/parser/join_multitables.sim diff --git a/tests/script/general/parser/join_multivnode.sim b/tests/script/tsim/parser/join_multivnode.sim similarity index 100% rename from tests/script/general/parser/join_multivnode.sim rename to tests/script/tsim/parser/join_multivnode.sim diff --git a/tests/script/general/parser/last_cache.sim b/tests/script/tsim/parser/last_cache.sim similarity index 100% rename from tests/script/general/parser/last_cache.sim rename to tests/script/tsim/parser/last_cache.sim diff --git a/tests/script/general/parser/last_cache_query.sim b/tests/script/tsim/parser/last_cache_query.sim similarity index 100% rename from tests/script/general/parser/last_cache_query.sim rename to tests/script/tsim/parser/last_cache_query.sim diff --git a/tests/script/general/parser/last_groupby.sim b/tests/script/tsim/parser/last_groupby.sim similarity index 100% rename from tests/script/general/parser/last_groupby.sim rename to tests/script/tsim/parser/last_groupby.sim diff --git a/tests/script/general/parser/lastrow.sim b/tests/script/tsim/parser/lastrow.sim similarity index 100% rename from tests/script/general/parser/lastrow.sim rename to tests/script/tsim/parser/lastrow.sim diff --git a/tests/script/general/parser/lastrow_query.sim b/tests/script/tsim/parser/lastrow_query.sim similarity index 100% rename from tests/script/general/parser/lastrow_query.sim rename to tests/script/tsim/parser/lastrow_query.sim diff --git a/tests/script/general/parser/like.sim b/tests/script/tsim/parser/like.sim similarity index 100% rename from tests/script/general/parser/like.sim rename to tests/script/tsim/parser/like.sim diff --git a/tests/script/general/parser/limit.sim b/tests/script/tsim/parser/limit.sim similarity index 100% rename from tests/script/general/parser/limit.sim rename to tests/script/tsim/parser/limit.sim diff --git a/tests/script/general/parser/limit1.sim b/tests/script/tsim/parser/limit1.sim similarity index 100% rename from tests/script/general/parser/limit1.sim rename to tests/script/tsim/parser/limit1.sim diff --git a/tests/script/general/parser/limit1_stb.sim b/tests/script/tsim/parser/limit1_stb.sim similarity index 100% rename from tests/script/general/parser/limit1_stb.sim rename to tests/script/tsim/parser/limit1_stb.sim diff --git a/tests/script/general/parser/limit1_tb.sim b/tests/script/tsim/parser/limit1_tb.sim similarity index 100% rename from tests/script/general/parser/limit1_tb.sim rename to tests/script/tsim/parser/limit1_tb.sim diff --git a/tests/script/general/parser/limit1_tblocks100.sim b/tests/script/tsim/parser/limit1_tblocks100.sim similarity index 100% rename from tests/script/general/parser/limit1_tblocks100.sim rename to tests/script/tsim/parser/limit1_tblocks100.sim diff --git a/tests/script/general/parser/limit2.sim b/tests/script/tsim/parser/limit2.sim similarity index 100% rename from tests/script/general/parser/limit2.sim rename to tests/script/tsim/parser/limit2.sim diff --git a/tests/script/general/parser/limit2_query.sim b/tests/script/tsim/parser/limit2_query.sim similarity index 100% rename from tests/script/general/parser/limit2_query.sim rename to tests/script/tsim/parser/limit2_query.sim diff --git a/tests/script/general/parser/limit2_tblocks100.sim b/tests/script/tsim/parser/limit2_tblocks100.sim similarity index 100% rename from tests/script/general/parser/limit2_tblocks100.sim rename to tests/script/tsim/parser/limit2_tblocks100.sim diff --git a/tests/script/general/parser/limit_stb.sim b/tests/script/tsim/parser/limit_stb.sim similarity index 100% rename from tests/script/general/parser/limit_stb.sim rename to tests/script/tsim/parser/limit_stb.sim diff --git a/tests/script/general/parser/limit_tb.sim b/tests/script/tsim/parser/limit_tb.sim similarity index 100% rename from tests/script/general/parser/limit_tb.sim rename to tests/script/tsim/parser/limit_tb.sim diff --git a/tests/script/general/parser/line_insert.sim b/tests/script/tsim/parser/line_insert.sim similarity index 100% rename from tests/script/general/parser/line_insert.sim rename to tests/script/tsim/parser/line_insert.sim diff --git a/tests/script/general/parser/mixed_blocks.sim b/tests/script/tsim/parser/mixed_blocks.sim similarity index 100% rename from tests/script/general/parser/mixed_blocks.sim rename to tests/script/tsim/parser/mixed_blocks.sim diff --git a/tests/script/general/parser/nchar.sim b/tests/script/tsim/parser/nchar.sim similarity index 100% rename from tests/script/general/parser/nchar.sim rename to tests/script/tsim/parser/nchar.sim diff --git a/tests/script/general/parser/nestquery.sim b/tests/script/tsim/parser/nestquery.sim similarity index 100% rename from tests/script/general/parser/nestquery.sim rename to tests/script/tsim/parser/nestquery.sim diff --git a/tests/script/general/parser/null_char.sim b/tests/script/tsim/parser/null_char.sim similarity index 100% rename from tests/script/general/parser/null_char.sim rename to tests/script/tsim/parser/null_char.sim diff --git a/tests/script/general/parser/precision_ns.sim b/tests/script/tsim/parser/precision_ns.sim similarity index 100% rename from tests/script/general/parser/precision_ns.sim rename to tests/script/tsim/parser/precision_ns.sim diff --git a/tests/script/general/parser/projection_limit_offset.sim b/tests/script/tsim/parser/projection_limit_offset.sim similarity index 100% rename from tests/script/general/parser/projection_limit_offset.sim rename to tests/script/tsim/parser/projection_limit_offset.sim diff --git a/tests/script/general/parser/regex.sim b/tests/script/tsim/parser/regex.sim similarity index 100% rename from tests/script/general/parser/regex.sim rename to tests/script/tsim/parser/regex.sim diff --git a/tests/script/general/parser/repeatAlter.sim b/tests/script/tsim/parser/repeatAlter.sim similarity index 100% rename from tests/script/general/parser/repeatAlter.sim rename to tests/script/tsim/parser/repeatAlter.sim diff --git a/tests/script/general/parser/selectResNum.sim b/tests/script/tsim/parser/selectResNum.sim similarity index 100% rename from tests/script/general/parser/selectResNum.sim rename to tests/script/tsim/parser/selectResNum.sim diff --git a/tests/script/general/parser/select_across_vnodes.sim b/tests/script/tsim/parser/select_across_vnodes.sim similarity index 100% rename from tests/script/general/parser/select_across_vnodes.sim rename to tests/script/tsim/parser/select_across_vnodes.sim diff --git a/tests/script/general/parser/select_distinct_tag.sim b/tests/script/tsim/parser/select_distinct_tag.sim similarity index 100% rename from tests/script/general/parser/select_distinct_tag.sim rename to tests/script/tsim/parser/select_distinct_tag.sim diff --git a/tests/script/general/parser/select_from_cache_disk.sim b/tests/script/tsim/parser/select_from_cache_disk.sim similarity index 100% rename from tests/script/general/parser/select_from_cache_disk.sim rename to tests/script/tsim/parser/select_from_cache_disk.sim diff --git a/tests/script/general/parser/select_with_tags.sim b/tests/script/tsim/parser/select_with_tags.sim similarity index 100% rename from tests/script/general/parser/select_with_tags.sim rename to tests/script/tsim/parser/select_with_tags.sim diff --git a/tests/script/general/parser/set_tag_vals.sim b/tests/script/tsim/parser/set_tag_vals.sim similarity index 100% rename from tests/script/general/parser/set_tag_vals.sim rename to tests/script/tsim/parser/set_tag_vals.sim diff --git a/tests/script/general/parser/single_row_in_tb.sim b/tests/script/tsim/parser/single_row_in_tb.sim similarity index 100% rename from tests/script/general/parser/single_row_in_tb.sim rename to tests/script/tsim/parser/single_row_in_tb.sim diff --git a/tests/script/general/parser/single_row_in_tb_query.sim b/tests/script/tsim/parser/single_row_in_tb_query.sim similarity index 100% rename from tests/script/general/parser/single_row_in_tb_query.sim rename to tests/script/tsim/parser/single_row_in_tb_query.sim diff --git a/tests/script/general/parser/sliding.sim b/tests/script/tsim/parser/sliding.sim similarity index 100% rename from tests/script/general/parser/sliding.sim rename to tests/script/tsim/parser/sliding.sim diff --git a/tests/script/general/parser/slimit.sim b/tests/script/tsim/parser/slimit.sim similarity index 100% rename from tests/script/general/parser/slimit.sim rename to tests/script/tsim/parser/slimit.sim diff --git a/tests/script/general/parser/slimit1.sim b/tests/script/tsim/parser/slimit1.sim similarity index 100% rename from tests/script/general/parser/slimit1.sim rename to tests/script/tsim/parser/slimit1.sim diff --git a/tests/script/general/parser/slimit1_query.sim b/tests/script/tsim/parser/slimit1_query.sim similarity index 100% rename from tests/script/general/parser/slimit1_query.sim rename to tests/script/tsim/parser/slimit1_query.sim diff --git a/tests/script/general/parser/slimit_alter_tags.sim b/tests/script/tsim/parser/slimit_alter_tags.sim similarity index 100% rename from tests/script/general/parser/slimit_alter_tags.sim rename to tests/script/tsim/parser/slimit_alter_tags.sim diff --git a/tests/script/general/parser/slimit_query.sim b/tests/script/tsim/parser/slimit_query.sim similarity index 100% rename from tests/script/general/parser/slimit_query.sim rename to tests/script/tsim/parser/slimit_query.sim diff --git a/tests/script/general/parser/stableOp.sim b/tests/script/tsim/parser/stableOp.sim similarity index 100% rename from tests/script/general/parser/stableOp.sim rename to tests/script/tsim/parser/stableOp.sim diff --git a/tests/script/general/parser/tags_dynamically_specifiy.sim b/tests/script/tsim/parser/tags_dynamically_specifiy.sim similarity index 100% rename from tests/script/general/parser/tags_dynamically_specifiy.sim rename to tests/script/tsim/parser/tags_dynamically_specifiy.sim diff --git a/tests/script/general/parser/tags_filter.sim b/tests/script/tsim/parser/tags_filter.sim similarity index 100% rename from tests/script/general/parser/tags_filter.sim rename to tests/script/tsim/parser/tags_filter.sim diff --git a/tests/script/general/parser/tbnameIn.sim b/tests/script/tsim/parser/tbnameIn.sim similarity index 100% rename from tests/script/general/parser/tbnameIn.sim rename to tests/script/tsim/parser/tbnameIn.sim diff --git a/tests/script/general/parser/tbnameIn_query.sim b/tests/script/tsim/parser/tbnameIn_query.sim similarity index 100% rename from tests/script/general/parser/tbnameIn_query.sim rename to tests/script/tsim/parser/tbnameIn_query.sim diff --git a/tests/script/general/parser/timestamp.sim b/tests/script/tsim/parser/timestamp.sim similarity index 100% rename from tests/script/general/parser/timestamp.sim rename to tests/script/tsim/parser/timestamp.sim diff --git a/tests/script/general/parser/timestamp_query.sim b/tests/script/tsim/parser/timestamp_query.sim similarity index 100% rename from tests/script/general/parser/timestamp_query.sim rename to tests/script/tsim/parser/timestamp_query.sim diff --git a/tests/script/general/parser/top_groupby.sim b/tests/script/tsim/parser/top_groupby.sim similarity index 100% rename from tests/script/general/parser/top_groupby.sim rename to tests/script/tsim/parser/top_groupby.sim diff --git a/tests/script/general/parser/topbot.sim b/tests/script/tsim/parser/topbot.sim similarity index 100% rename from tests/script/general/parser/topbot.sim rename to tests/script/tsim/parser/topbot.sim diff --git a/tests/script/general/parser/udf.sim b/tests/script/tsim/parser/udf.sim similarity index 100% rename from tests/script/general/parser/udf.sim rename to tests/script/tsim/parser/udf.sim diff --git a/tests/script/general/parser/udf_dll.sim b/tests/script/tsim/parser/udf_dll.sim similarity index 100% rename from tests/script/general/parser/udf_dll.sim rename to tests/script/tsim/parser/udf_dll.sim diff --git a/tests/script/general/parser/udf_dll_stable.sim b/tests/script/tsim/parser/udf_dll_stable.sim similarity index 100% rename from tests/script/general/parser/udf_dll_stable.sim rename to tests/script/tsim/parser/udf_dll_stable.sim diff --git a/tests/script/general/parser/union.sim b/tests/script/tsim/parser/union.sim similarity index 100% rename from tests/script/general/parser/union.sim rename to tests/script/tsim/parser/union.sim diff --git a/tests/script/general/parser/where.sim b/tests/script/tsim/parser/where.sim similarity index 100% rename from tests/script/general/parser/where.sim rename to tests/script/tsim/parser/where.sim -- GitLab From 61eab5fc2183e98fb8163e6bad16f95e51242c85 Mon Sep 17 00:00:00 2001 From: Shengliang Guan Date: Thu, 14 Jul 2022 17:26:52 +0800 Subject: [PATCH 139/153] test: restore some 2.0 case --- tests/script/jenkins/basic.txt | 8 +++++++- tests/script/{ => tsim}/issue/TD-2677.sim | 0 tests/script/{ => tsim}/issue/TD-2680.sim | 0 tests/script/{ => tsim}/issue/TD-2713.sim | 0 tests/script/{ => tsim}/issue/TD-3300.sim | 0 5 files changed, 7 insertions(+), 1 deletion(-) rename tests/script/{ => tsim}/issue/TD-2677.sim (100%) rename tests/script/{ => tsim}/issue/TD-2680.sim (100%) rename tests/script/{ => tsim}/issue/TD-2713.sim (100%) rename tests/script/{ => tsim}/issue/TD-3300.sim (100%) diff --git a/tests/script/jenkins/basic.txt b/tests/script/jenkins/basic.txt index 6b3031c0e5..c2c102c241 100644 --- a/tests/script/jenkins/basic.txt +++ b/tests/script/jenkins/basic.txt @@ -374,7 +374,7 @@ # ---- alter ./test.sh -f tsim/alter/cached_schema_after_alter.sim ./test.sh -f tsim/alter/dnode.sim -#./test.sh -f tsim/alter/table.sim +./test.sh -f tsim/alter/table.sim # ---- cache ./test.sh -f tsim/cache/new_metrics.sim @@ -445,6 +445,12 @@ # ---- wal ./test.sh -f tsim/wal/kill.sim +# ---- issue +#./test.sh -f tsim/issue/TD-2677.sim +#./test.sh -f tsim/issue/TD-2680.sim +#./test.sh -f tsim/issue/TD-2713.sim +#./test.sh -f tsim/issue/TD-3300.sim + # ---- tag ./test.sh -f tsim/tag/3.sim ./test.sh -f tsim/tag/4.sim diff --git a/tests/script/issue/TD-2677.sim b/tests/script/tsim/issue/TD-2677.sim similarity index 100% rename from tests/script/issue/TD-2677.sim rename to tests/script/tsim/issue/TD-2677.sim diff --git a/tests/script/issue/TD-2680.sim b/tests/script/tsim/issue/TD-2680.sim similarity index 100% rename from tests/script/issue/TD-2680.sim rename to tests/script/tsim/issue/TD-2680.sim diff --git a/tests/script/issue/TD-2713.sim b/tests/script/tsim/issue/TD-2713.sim similarity index 100% rename from tests/script/issue/TD-2713.sim rename to tests/script/tsim/issue/TD-2713.sim diff --git a/tests/script/issue/TD-3300.sim b/tests/script/tsim/issue/TD-3300.sim similarity index 100% rename from tests/script/issue/TD-3300.sim rename to tests/script/tsim/issue/TD-3300.sim -- GitLab From 9847abf166ce71c600798fc90e28c6b5cb86a35d Mon Sep 17 00:00:00 2001 From: Liu Jicong Date: Thu, 14 Jul 2022 17:34:06 +0800 Subject: [PATCH 140/153] fix(sma): double free --- source/dnode/vnode/src/sma/smaRollup.c | 40 ++++++------------- source/libs/executor/src/scanoperator.c | 12 +++--- source/libs/executor/src/timewindowoperator.c | 1 - 3 files changed, 19 insertions(+), 34 deletions(-) diff --git a/source/dnode/vnode/src/sma/smaRollup.c b/source/dnode/vnode/src/sma/smaRollup.c index 06ffb639de..a6d56acbfb 100644 --- a/source/dnode/vnode/src/sma/smaRollup.c +++ b/source/dnode/vnode/src/sma/smaRollup.c @@ -30,7 +30,7 @@ typedef struct SRSmaQTaskInfoIter SRSmaQTaskInfoIter; static int32_t tdUidStorePut(STbUidStore *pStore, tb_uid_t suid, tb_uid_t *uid); static int32_t tdUpdateTbUidListImpl(SSma *pSma, tb_uid_t *suid, SArray *tbUids); static int32_t tdSetRSmaInfoItemParams(SSma *pSma, SRSmaParam *param, SRSmaStat *pStat, SRSmaInfo *pRSmaInfo, - SReadHandle *handle, int8_t idx); + int8_t idx); static int32_t tdExecuteRSmaImpl(SSma *pSma, const void *pMsg, int32_t inputType, SRSmaInfoItem *rsmaItem, STSchema *pTSchema, tb_uid_t suid, int8_t level); static SRSmaInfo *tdGetRSmaInfoBySuid(SSma *pSma, int64_t suid); @@ -256,14 +256,20 @@ int32_t tdFetchTbUidList(SSma *pSma, STbUidStore **ppStore, tb_uid_t suid, tb_ui } static int32_t tdSetRSmaInfoItemParams(SSma *pSma, SRSmaParam *param, SRSmaStat *pStat, SRSmaInfo *pRSmaInfo, - SReadHandle *pReadHandle, int8_t idx) { + int8_t idx) { SRetention *pRetention = SMA_RETENTION(pSma); STsdbCfg *pTsdbCfg = SMA_TSDB_CFG(pSma); + SReadHandle handle = { + .meta = pSma->pVnode->pMeta, + .vnode = pSma->pVnode, + .initTqReader = 1, + }; + if (param->qmsg[idx]) { SRSmaInfoItem *pItem = &(pRSmaInfo->items[idx]); pItem->refId = RSMA_REF_ID(pStat); - pItem->taskInfo = qCreateStreamExecTaskInfo(param->qmsg[idx], pReadHandle); + pItem->taskInfo = qCreateStreamExecTaskInfo(param->qmsg[idx], &handle); if (!pItem->taskInfo) { terrno = TSDB_CODE_RSMA_QTASKINFO_CREATE; goto _err; @@ -299,10 +305,6 @@ _err: * @return int32_t */ int32_t tdProcessRSmaCreateImpl(SSma *pSma, SRSmaParam *param, int64_t suid, const char *tbName) { - SVnode *pVnode = pSma->pVnode; - SMeta *pMeta = pVnode->pMeta; - SMsgCb *pMsgCb = &pVnode->msgCb; - if ((param->qmsgLen[0] == 0) && (param->qmsgLen[1] == 0)) { smaDebug("vgId:%d, no qmsg1/qmsg2 for rollup table %s %" PRIi64, SMA_VID(pSma), tbName, suid); return TSDB_CODE_SUCCESS; @@ -331,19 +333,6 @@ int32_t tdProcessRSmaCreateImpl(SSma *pSma, SRSmaParam *param, int64_t suid, con return TSDB_CODE_FAILED; } - STqReader *pReader = tqOpenReader(pVnode); - if (!pReader) { - terrno = TSDB_CODE_OUT_OF_MEMORY; - goto _err; - } - - SReadHandle handle = { - .tqReader = pReader, - .meta = pMeta, - .pMsgCb = pMsgCb, - .vnode = pVnode, - }; - STSchema *pTSchema = metaGetTbTSchema(SMA_META(pSma), suid, -1); if (!pTSchema) { terrno = TSDB_CODE_TDB_IVD_TB_SCHEMA_VERSION; @@ -352,11 +341,11 @@ int32_t tdProcessRSmaCreateImpl(SSma *pSma, SRSmaParam *param, int64_t suid, con pRSmaInfo->pTSchema = pTSchema; pRSmaInfo->suid = suid; - if (tdSetRSmaInfoItemParams(pSma, param, pStat, pRSmaInfo, &handle, 0) < 0) { + if (tdSetRSmaInfoItemParams(pSma, param, pStat, pRSmaInfo, 0) < 0) { goto _err; } - if (tdSetRSmaInfoItemParams(pSma, param, pStat, pRSmaInfo, &handle, 1) < 0) { + if (tdSetRSmaInfoItemParams(pSma, param, pStat, pRSmaInfo, 1) < 0) { goto _err; } @@ -369,7 +358,6 @@ int32_t tdProcessRSmaCreateImpl(SSma *pSma, SRSmaParam *param, int64_t suid, con return TSDB_CODE_SUCCESS; _err: tdFreeRSmaInfo(pSma, pRSmaInfo); - taosMemoryFree(pReader); return TSDB_CODE_FAILED; } @@ -404,7 +392,7 @@ int32_t tdProcessRSmaCreate(SSma *pSma, SVCreateStbReq *pReq) { * @param pReq * @return int32_t */ -int32_t tdProcessRSmaDrop(SSma *pSma, SVDropStbReq *pReq) { +int32_t tdProcessRSmaDrop(SSma *pSma, SVDropStbReq *pReq) { SVnode *pVnode = pSma->pVnode; if (!VND_IS_RSMA(pVnode)) { smaTrace("vgId:%d, not create rsma for stable %s %" PRIi64 " since vnd is not rsma", TD_VID(pVnode), pReq->name, @@ -412,11 +400,9 @@ int32_t tdProcessRSmaDrop(SSma *pSma, SVDropStbReq *pReq) { return TSDB_CODE_SUCCESS; } - - smaDebug("vgId:%d, drop rsma for table %" PRIi64 " succeed", TD_VID(pVnode), pReq->suid); return TSDB_CODE_SUCCESS; - } +} /** * @brief store suid/[uids], prefer to use array and then hash diff --git a/source/libs/executor/src/scanoperator.c b/source/libs/executor/src/scanoperator.c index aa84500fdc..0f44ac48a4 100644 --- a/source/libs/executor/src/scanoperator.c +++ b/source/libs/executor/src/scanoperator.c @@ -39,7 +39,7 @@ static int32_t buildSysDbTableInfo(const SSysTableScanInfo* pInfo, int32_t capac static int32_t buildDbTableInfoBlock(const SSDataBlock* p, const SSysTableMeta* pSysDbTableMeta, size_t size, const char* dbName); -static bool processBlockWithProbability(const SSampleExecInfo* pInfo); +static bool processBlockWithProbability(const SSampleExecInfo* pInfo); bool processBlockWithProbability(const SSampleExecInfo* pInfo) { #if 0 @@ -1178,10 +1178,9 @@ static int32_t setBlockIntoRes(SStreamScanInfo* pInfo, const SSDataBlock* pBlock for (int32_t j = 0; j < blockDataGetNumOfCols(pBlock); ++j) { SColumnInfoData* pResCol = bdGetColumnInfoData(pBlock, j); if (pResCol->info.colId == pColMatchInfo->colId) { - SColumnInfoData* pDst = taosArrayGet(pInfo->pRes->pDataBlock, pColMatchInfo->targetSlotId); colDataAssign(pDst, pResCol, pBlock->info.rows, &pInfo->pRes->info); -// taosArraySet(pInfo->pRes->pDataBlock, pColMatchInfo->targetSlotId, pResCol); + // taosArraySet(pInfo->pRes->pDataBlock, pColMatchInfo->targetSlotId, pResCol); colExists = true; break; } @@ -1201,14 +1200,14 @@ static int32_t setBlockIntoRes(SStreamScanInfo* pInfo, const SSDataBlock* pBlock int32_t code = addTagPseudoColumnData(&pInfo->readHandle, pInfo->pPseudoExpr, pInfo->numOfPseudoExpr, pInfo->pRes, GET_TASKID(pTaskInfo)); if (code != TSDB_CODE_SUCCESS) { - blockDataFreeRes((SSDataBlock*) pBlock); + blockDataFreeRes((SSDataBlock*)pBlock); longjmp(pTaskInfo->env, code); } } doFilter(pInfo->pCondition, pInfo->pRes); blockDataUpdateTsWindow(pInfo->pRes, pInfo->primaryTsIndex); - blockDataFreeRes((SSDataBlock*) pBlock); + blockDataFreeRes((SSDataBlock*)pBlock); return 0; } @@ -1444,7 +1443,7 @@ SOperatorInfo* createRawScanOperatorInfo(SReadHandle* pHandle, STableScanPhysiNo static void destroyStreamScanOperatorInfo(void* param, int32_t numOfOutput) { SStreamScanInfo* pStreamScan = (SStreamScanInfo*)param; -#if 0 +#if 1 if (pStreamScan->pTableScanOp && pStreamScan->pTableScanOp->info) { STableScanInfo* pTableScanInfo = pStreamScan->pTableScanOp->info; destroyTableScanOperatorInfo(pTableScanInfo, 1); @@ -1456,6 +1455,7 @@ static void destroyStreamScanOperatorInfo(void* param, int32_t numOfOutput) { if (pStreamScan->pColMatchInfo) { taosArrayDestroy(pStreamScan->pColMatchInfo); } + updateInfoDestroy(pStreamScan->pUpdateInfo); blockDataDestroy(pStreamScan->pRes); blockDataDestroy(pStreamScan->pUpdateRes); blockDataDestroy(pStreamScan->pPullDataRes); diff --git a/source/libs/executor/src/timewindowoperator.c b/source/libs/executor/src/timewindowoperator.c index 22c09de64f..acc56af5cd 100644 --- a/source/libs/executor/src/timewindowoperator.c +++ b/source/libs/executor/src/timewindowoperator.c @@ -1537,7 +1537,6 @@ void destroyStreamFinalIntervalOperatorInfo(void* param, int32_t numOfOutput) { for (int32_t i = 0; i < size; i++) { SOperatorInfo* pChildOp = taosArrayGetP(pInfo->pChildren, i); destroyStreamFinalIntervalOperatorInfo(pChildOp->info, numOfOutput); - /*taosMemoryFreeClear(pChildOp->info);*/ taosMemoryFreeClear(pChildOp); } } -- GitLab From b87eb0abb3f0a5a8db95ab8432150a6de349f08c Mon Sep 17 00:00:00 2001 From: Ganlin Zhao Date: Thu, 14 Jul 2022 17:39:03 +0800 Subject: [PATCH 141/153] feat(query): add stddev function scalar version TD-17344 --- include/libs/scalar/scalar.h | 1 + source/libs/function/src/builtins.c | 1 + source/libs/scalar/src/sclfunc.c | 112 ++++++++++++++++++++++++++++ 3 files changed, 114 insertions(+) diff --git a/include/libs/scalar/scalar.h b/include/libs/scalar/scalar.h index 97c77ef01b..8b08785ed5 100644 --- a/include/libs/scalar/scalar.h +++ b/include/libs/scalar/scalar.h @@ -101,6 +101,7 @@ int32_t countScalarFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam int32_t sumScalarFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput); int32_t minScalarFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput); int32_t maxScalarFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput); +int32_t stddevScalarFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput); #ifdef __cplusplus } diff --git a/source/libs/function/src/builtins.c b/source/libs/function/src/builtins.c index 001261767d..bc915132de 100644 --- a/source/libs/function/src/builtins.c +++ b/source/libs/function/src/builtins.c @@ -1947,6 +1947,7 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = { .getEnvFunc = getStddevFuncEnv, .initFunc = stddevFunctionSetup, .processFunc = stddevFunction, + .sprocessFunc = stddevScalarFunction, .finalizeFunc = stddevFinalize, .invertFunc = stddevInvertFunction, .combineFunc = stddevCombine, diff --git a/source/libs/scalar/src/sclfunc.c b/source/libs/scalar/src/sclfunc.c index cfdde85556..8194be297f 100644 --- a/source/libs/scalar/src/sclfunc.c +++ b/source/libs/scalar/src/sclfunc.c @@ -1903,3 +1903,115 @@ int32_t minScalarFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam * int32_t maxScalarFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput) { return doMinMaxScalarFunction(pInput, inputNum, pOutput, false); } + +int32_t stddevScalarFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam *pOutput) { + SColumnInfoData *pInputData = pInput->columnData; + SColumnInfoData *pOutputData = pOutput->columnData; + + int32_t type = GET_PARAM_TYPE(pInput); + int64_t count = 0, sum = 0, qSum = 0; + + for (int32_t i = 0; i < pInput->numOfRows; ++i) { + if (colDataIsNull_s(pInputData, i)) { + continue; + } + count++; +#if 0 + switch(type) { + case TSDB_DATA_TYPE_TINYINT: { + int8_t *in = (int8_t *)pInputData->pData; + sum += in[i]; + qSum += in[i] * in[i]; + count++; + break; + } + case TSDB_DATA_TYPE_SMALLINT: { + int16_t *in = (int16_t *)pInputData->pData; + sum += in[i]; + qSum += in[i] * in[i]; + count++; + break; + } + case TSDB_DATA_TYPE_INT: { + int32_t *in = (int32_t *)pInputData->pData; + sum += in[i]; + qSum += in[i] * in[i]; + count++; + break; + } + case TSDB_DATA_TYPE_BIGINT: { + int64_t *in = (int64_t *)pInputData->pData; + sum += in[i]; + qSum += in[i] * in[i]; + count++; + break; + } + case TSDB_DATA_TYPE_UTINYINT: { + uint8_t *in = (uint8_t *)pInputData->pData; + sum += in[i]; + qSum += in[i] * in[i]; + count++; + break; + } + case TSDB_DATA_TYPE_USMALLINT: { + uint16_t *in = (uint16_t *)pInputData->pData; + sum += in[i]; + qSum += in[i] * in[i]; + count++; + break; + } + case TSDB_DATA_TYPE_UINT: { + uint32_t *in = (uint32_t *)pInputData->pData; + sum += in[i]; + qSum += in[i] * in[i]; + count++; + break; + } + case TSDB_DATA_TYPE_UBIGINT: { + uint64_t *in = (uint64_t *)pInputData->pData; + sum += in[i]; + qSum += in[i] * in[i]; + count++; + break; + } + case TSDB_DATA_TYPE_FLOAT: { + float *in = (float *)pInputData->pData; + sum += in[i]; + qSum += in[i] * in[i]; + count++; + break; + } + case TSDB_DATA_TYPE_DOUBLE: { + double *in = (double *)pInputData->pData; + sum += in[i]; + qSum += in[i] * in[i]; + count++; + break; + } + } +#endif + } + + double *out = (double *)pOutputData->pData; + if (count == 0) { + colDataAppendNULL(pOutputData, 0); + } else { + *out = 0; +#if 0 + double avg = 0; + if (IS_SIGNED_NUMERIC_TYPE(type)) { + avg = (int64_t)sum / (double)count; + *out = sqrt(fabs((int64_t)qSum / ((double)count) - avg * avg)); + } else if (IS_UNSIGNED_NUMERIC_TYPE(type)) { + avg = (uint64_t)sum / (double)count; + *out = sqrt(fabs((uint64_t)qSum / ((double)count) - avg * avg)); + } else if (IS_FLOAT_TYPE(type)) { + avg = (double)sum / (double)count; + *out = sqrt(fabs((double)qSum / ((double)count) - avg * avg)); + } +#endif + } + + pOutput->numOfRows = pInput->numOfRows; + return TSDB_CODE_SUCCESS; +} -- GitLab From 41b259508613d9b7c71fd4d841ae51e18203c680 Mon Sep 17 00:00:00 2001 From: Liu Jicong Date: Thu, 14 Jul 2022 17:36:46 +0800 Subject: [PATCH 142/153] fix(sma): fix case --- source/dnode/vnode/src/sma/smaEnv.c | 2 +- tests/script/tsim/sma/tsmaCreateInsertQuery.sim | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/source/dnode/vnode/src/sma/smaEnv.c b/source/dnode/vnode/src/sma/smaEnv.c index e75d3b4e5d..4a7d4db874 100644 --- a/source/dnode/vnode/src/sma/smaEnv.c +++ b/source/dnode/vnode/src/sma/smaEnv.c @@ -255,7 +255,7 @@ static void tdDestroyRSmaStat(void *pRSmaStat) { // step 2: destroy the rsma info and associated fetch tasks // TODO: use taosHashSetFreeFp when taosHashSetFreeFp is ready. -#if 0 +#if 1 if (taosHashGetSize(RSMA_INFO_HASH(pStat)) > 0) { void *infoHash = taosHashIterate(RSMA_INFO_HASH(pStat), NULL); while (infoHash) { diff --git a/tests/script/tsim/sma/tsmaCreateInsertQuery.sim b/tests/script/tsim/sma/tsmaCreateInsertQuery.sim index 6cca47423a..868207c80b 100644 --- a/tests/script/tsim/sma/tsmaCreateInsertQuery.sim +++ b/tests/script/tsim/sma/tsmaCreateInsertQuery.sim @@ -41,7 +41,8 @@ print =============== show streams ================================ sql show streams; print $data00 $data01 $data02 -if $data00 != d1 then +if $data00 != sma_index_name1 then + print $data00 return -1 endi -- GitLab From 5ca810a9857e225060ffad22ed9d0d4ebb8f37ac Mon Sep 17 00:00:00 2001 From: Haojun Liao Date: Thu, 14 Jul 2022 19:09:40 +0800 Subject: [PATCH 143/153] fix(query): fix memory leak. --- source/client/inc/clientInt.h | 12 +++---- source/client/src/clientEnv.c | 4 +++ source/client/src/clientHb.c | 2 +- source/client/src/clientImpl.c | 3 ++ source/libs/executor/inc/executorimpl.h | 3 +- source/libs/executor/src/executil.c | 8 +++-- source/libs/executor/src/executorimpl.c | 43 +++++++++++++------------ source/libs/scheduler/src/schRemote.c | 4 +-- 8 files changed, 43 insertions(+), 36 deletions(-) diff --git a/source/client/inc/clientInt.h b/source/client/inc/clientInt.h index 367e656f06..706df11cf9 100644 --- a/source/client/inc/clientInt.h +++ b/source/client/inc/clientInt.h @@ -224,12 +224,12 @@ typedef struct SRequestObj { SArray* tableList; SQueryExecMetric metric; SRequestSendRecvBody body; - bool stableQuery; // todo refactor - bool validateOnly; // todo refactor - - bool killed; - uint32_t prevCode; // previous error code: todo refactor, add update flag for catalog - uint32_t retry; + bool syncQuery; // todo refactor: async query object + bool stableQuery; // todo refactor + bool validateOnly; // todo refactor + bool killed; + uint32_t prevCode; // previous error code: todo refactor, add update flag for catalog + uint32_t retry; } SRequestObj; typedef struct SSyncQueryParam { diff --git a/source/client/src/clientEnv.c b/source/client/src/clientEnv.c index 207ac01a2c..9e67dc6571 100644 --- a/source/client/src/clientEnv.c +++ b/source/client/src/clientEnv.c @@ -320,6 +320,10 @@ void doDestroyRequest(void *p) { deregisterRequest(pRequest); } + if (pRequest->syncQuery) { + taosMemoryFree(pRequest->body.param); + } + taosMemoryFree(pRequest); tscTrace("end to destroy request %" PRIx64 " p:%p", reqId, pRequest); } diff --git a/source/client/src/clientHb.c b/source/client/src/clientHb.c index 2a9d113108..d7c2c26d23 100644 --- a/source/client/src/clientHb.c +++ b/source/client/src/clientHb.c @@ -307,7 +307,7 @@ static int32_t hbAsyncCallBack(void *param, SDataBuf *pMsg, int32_t code) { taosThreadMutexUnlock(&appInfo.mutex); tFreeClientHbBatchRsp(&pRsp); - + taosMemoryFree(pMsg->pData); return code; } diff --git a/source/client/src/clientImpl.c b/source/client/src/clientImpl.c index d846cb93af..783f5450fb 100644 --- a/source/client/src/clientImpl.c +++ b/source/client/src/clientImpl.c @@ -2047,6 +2047,7 @@ void syncCatalogFn(SMetaData* pResult, void* param, int32_t code) { void syncQueryFn(void* param, void* res, int32_t code) { SSyncQueryParam* pParam = param; pParam->pRequest = res; + if (pParam->pRequest) { pParam->pRequest->code = code; } @@ -2093,6 +2094,8 @@ TAOS_RES* taosQueryImpl(TAOS* taos, const char* sql, bool validateOnly) { taosAsyncQueryImpl(*(int64_t*)taos, sql, syncQueryFn, param, validateOnly); tsem_wait(¶m->sem); + + param->pRequest->syncQuery = true; return param->pRequest; #else size_t sqlLen = strlen(sql); diff --git a/source/libs/executor/inc/executorimpl.h b/source/libs/executor/inc/executorimpl.h index d5d52d41ac..84d503b972 100644 --- a/source/libs/executor/inc/executorimpl.h +++ b/source/libs/executor/inc/executorimpl.h @@ -858,8 +858,7 @@ SOperatorInfo* createDataBlockInfoScanOperator(void* dataReader, SReadHandle* re SOperatorInfo* createStreamScanOperatorInfo(SReadHandle* pHandle, STableScanPhysiNode* pTableScanNode, SExecTaskInfo* pTaskInfo, STimeWindowAggSupp* pTwSup, uint64_t queryId, uint64_t taskId); -SOperatorInfo* createFillOperatorInfo(SOperatorInfo* downstream, SFillPhysiNode* pPhyFillNode, bool multigroupResult, - SExecTaskInfo* pTaskInfo); +SOperatorInfo* createFillOperatorInfo(SOperatorInfo* downstream, SFillPhysiNode* pPhyFillNode, SExecTaskInfo* pTaskInfo); SOperatorInfo* createStatewindowOperatorInfo(SOperatorInfo* downstream, SExprInfo* pExpr, int32_t numOfCols, SSDataBlock* pResBlock, STimeWindowAggSupp *pTwAggSupp, int32_t tsSlotId, diff --git a/source/libs/executor/src/executil.c b/source/libs/executor/src/executil.c index 95b4fdcd6e..76d853ef3e 100644 --- a/source/libs/executor/src/executil.c +++ b/source/libs/executor/src/executil.c @@ -13,7 +13,7 @@ * along with this program. If not, see . */ -#include +#include "ttime.h" #include "function.h" #include "functionMgt.h" #include "index.h" @@ -603,13 +603,15 @@ static int32_t setSelectValueColumnInfo(SqlFunctionCtx* pCtx, int32_t numOfOutpu } for (int32_t i = 0; i < numOfOutput; ++i) { - if (strcmp(pCtx[i].pExpr->pExpr->_function.functionName, "_select_value") == 0 || - strcmp(pCtx[i].pExpr->pExpr->_function.functionName, "_group_key") == 0) { + const char* pName = pCtx[i].pExpr->pExpr->_function.functionName; + if ((strcmp(pName, "_select_value") == 0) || + (strcmp(pName, "_group_key") == 0)) { pValCtx[num++] = &pCtx[i]; } else if (fmIsSelectFunc(pCtx[i].functionId)) { p = &pCtx[i]; } } + #ifdef BUF_PAGE_DEBUG qDebug("page_setSelect num:%d", num); #endif diff --git a/source/libs/executor/src/executorimpl.c b/source/libs/executor/src/executorimpl.c index 266567ec1b..4e010cfdf1 100644 --- a/source/libs/executor/src/executorimpl.c +++ b/source/libs/executor/src/executorimpl.c @@ -3330,7 +3330,7 @@ static SSDataBlock* doProjectOperation(SOperatorInfo* pOperator) { return (rows > 0) ? pInfo->pRes : NULL; } -static void doHandleRemainBlockForNewGroupImpl(SFillOperatorInfo* pInfo, SResultInfo* pResultInfo, bool* newgroup, +static void doHandleRemainBlockForNewGroupImpl(SFillOperatorInfo* pInfo, SResultInfo* pResultInfo, SExecTaskInfo* pTaskInfo) { pInfo->totalInputRows = pInfo->existNewGroupBlock->info.rows; @@ -3341,25 +3341,26 @@ static void doHandleRemainBlockForNewGroupImpl(SFillOperatorInfo* pInfo, SResult taosFillSetStartInfo(pInfo->pFillInfo, pInfo->existNewGroupBlock->info.rows, ekey); taosFillSetInputDataBlock(pInfo->pFillInfo, pInfo->existNewGroupBlock); - doFillTimeIntervalGapsInResults(pInfo->pFillInfo, pInfo->pRes, pResultInfo->capacity); + int32_t numOfResultRows = pResultInfo->capacity - pInfo->pRes->info.rows; + taosFillResultDataBlock(pInfo->pFillInfo, pInfo->pRes, numOfResultRows); + pInfo->curGroupId = pInfo->existNewGroupBlock->info.groupId; pInfo->existNewGroupBlock = NULL; -// *newgroup = true; } -static void doHandleRemainBlockFromNewGroup(SFillOperatorInfo* pInfo, SResultInfo* pResultInfo, bool* newgroup, +static void doHandleRemainBlockFromNewGroup(SFillOperatorInfo* pInfo, SResultInfo* pResultInfo, SExecTaskInfo* pTaskInfo) { if (taosFillHasMoreResults(pInfo->pFillInfo)) { -// *newgroup = false; - doFillTimeIntervalGapsInResults(pInfo->pFillInfo, pInfo->pRes, (int32_t)pResultInfo->capacity); - if (pInfo->pRes->info.rows > pResultInfo->threshold || (!pInfo->multigroupResult)) { + int32_t numOfResultRows = pResultInfo->capacity - pInfo->pRes->info.rows; + taosFillResultDataBlock(pInfo->pFillInfo, pInfo->pRes, numOfResultRows); + if (pInfo->pRes->info.rows > pResultInfo->threshold) { return; } } // handle the cached new group data block if (pInfo->existNewGroupBlock) { - doHandleRemainBlockForNewGroupImpl(pInfo, pResultInfo, newgroup, pTaskInfo); + doHandleRemainBlockForNewGroupImpl(pInfo, pResultInfo, pTaskInfo); } } @@ -3372,8 +3373,8 @@ static SSDataBlock* doFillImpl(SOperatorInfo* pOperator) { blockDataCleanup(pResBlock); - doHandleRemainBlockFromNewGroup(pInfo, pResultInfo, NULL, pTaskInfo); - if (pResBlock->info.rows > pResultInfo->threshold || (!pInfo->multigroupResult && pResBlock->info.rows > 0)) { + doHandleRemainBlockFromNewGroup(pInfo, pResultInfo, pTaskInfo); + if (pResBlock->info.rows > pResultInfo->threshold || pResBlock->info.rows > 0) { return pResBlock; } @@ -3407,7 +3408,9 @@ static SSDataBlock* doFillImpl(SOperatorInfo* pOperator) { } blockDataEnsureCapacity(pResBlock, pOperator->resultInfo.capacity); - doFillTimeIntervalGapsInResults(pInfo->pFillInfo, pResBlock, pOperator->resultInfo.capacity); + + int32_t numOfResultRows = pOperator->resultInfo.capacity - pBlock->info.rows; + taosFillResultDataBlock(pInfo->pFillInfo, pBlock, numOfResultRows); // current group has no more result to return if (pResBlock->info.rows > 0) { @@ -3417,13 +3420,13 @@ static SSDataBlock* doFillImpl(SOperatorInfo* pOperator) { return pResBlock; } - doHandleRemainBlockFromNewGroup(pInfo, pResultInfo, NULL, pTaskInfo); + doHandleRemainBlockFromNewGroup(pInfo, pResultInfo, pTaskInfo); if (pResBlock->info.rows >= pOperator->resultInfo.threshold || pBlock == NULL) { return pResBlock; } } else if (pInfo->existNewGroupBlock) { // try next group assert(pBlock != NULL); - doHandleRemainBlockForNewGroupImpl(pInfo, pResultInfo, NULL, pTaskInfo); + doHandleRemainBlockForNewGroupImpl(pInfo, pResultInfo, pTaskInfo); if (pResBlock->info.rows > pResultInfo->threshold) { return pResBlock; } @@ -4032,8 +4035,7 @@ static int32_t initFillInfo(SFillOperatorInfo* pInfo, SExprInfo* pExpr, int32_t } } -SOperatorInfo* createFillOperatorInfo(SOperatorInfo* downstream, SFillPhysiNode* pPhyFillNode, bool multigroupResult, - SExecTaskInfo* pTaskInfo) { +SOperatorInfo* createFillOperatorInfo(SOperatorInfo* downstream, SFillPhysiNode* pPhyFillNode, SExecTaskInfo* pTaskInfo) { SFillOperatorInfo* pInfo = taosMemoryCalloc(1, sizeof(SFillOperatorInfo)); SOperatorInfo* pOperator = taosMemoryCalloc(1, sizeof(SOperatorInfo)); if (pInfo == NULL || pOperator == NULL) { @@ -4065,7 +4067,6 @@ SOperatorInfo* createFillOperatorInfo(SOperatorInfo* downstream, SFillPhysiNode* } pInfo->pRes = pResBlock; - pInfo->multigroupResult = multigroupResult; pInfo->pCondition = pPhyFillNode->node.pConditions; pInfo->pColMatchColInfo = pColMatchColInfo; pOperator->name = "FillOperator"; @@ -4438,21 +4439,21 @@ SOperatorInfo* createOperatorTree(SPhysiNode* pPhyNode, SExecTaskInfo* pTaskInfo // return NULL; // } - int32_t code = extractTableSchemaInfo(pHandle, pScanNode->scan.uid, pTaskInfo); + int32_t code = extractTableSchemaInfo(pHandle, pScanNode->uid, pTaskInfo); if (code != TSDB_CODE_SUCCESS) { pTaskInfo->code = code; return NULL; } pTableListInfo->pTableList = taosArrayInit(4, sizeof(STableKeyInfo)); - if (pScanNode->scan.tableType == TSDB_SUPER_TABLE) { - code = vnodeGetAllTableList(pHandle->vnode, pScanNode->scan.uid, pTableListInfo->pTableList); + if (pScanNode->tableType == TSDB_SUPER_TABLE) { + code = vnodeGetAllTableList(pHandle->vnode, pScanNode->uid, pTableListInfo->pTableList); if (code != TSDB_CODE_SUCCESS) { pTaskInfo->code = terrno; return NULL; } } else { // Create one table group. - STableKeyInfo info = {.lastKey = 0, .uid = pScanNode->scan.uid, .groupId = 0}; + STableKeyInfo info = {.lastKey = 0, .uid = pScanNode->uid, .groupId = 0}; taosArrayPush(pTableListInfo->pTableList, &info); } @@ -4605,7 +4606,7 @@ SOperatorInfo* createOperatorTree(SPhysiNode* pPhyNode, SExecTaskInfo* pTaskInfo } else if (QUERY_NODE_PHYSICAL_PLAN_MERGE_JOIN == type) { pOptr = createMergeJoinOperatorInfo(ops, size, (SJoinPhysiNode*)pPhyNode, pTaskInfo); } else if (QUERY_NODE_PHYSICAL_PLAN_FILL == type) { - pOptr = createFillOperatorInfo(ops[0], (SFillPhysiNode*)pPhyNode, false, pTaskInfo); + pOptr = createFillOperatorInfo(ops[0], (SFillPhysiNode*)pPhyNode, pTaskInfo); } else if (QUERY_NODE_PHYSICAL_PLAN_INDEF_ROWS_FUNC == type) { pOptr = createIndefinitOutputOperatorInfo(ops[0], pPhyNode, pTaskInfo); } else if (QUERY_NODE_PHYSICAL_PLAN_INTERP_FUNC == type) { diff --git a/source/libs/scheduler/src/schRemote.c b/source/libs/scheduler/src/schRemote.c index 1b893739bd..d195c22c37 100644 --- a/source/libs/scheduler/src/schRemote.c +++ b/source/libs/scheduler/src/schRemote.c @@ -444,14 +444,12 @@ int32_t schHandleHbCallback(void *param, SDataBuf *pMsg, int32_t code) { trans.pHandle = pMsg->handle; SCH_ERR_JRET(schUpdateHbConnection(&rsp.epId, &trans)); - SCH_ERR_JRET(schProcessOnTaskStatusRsp(&rsp.epId, rsp.taskStatus)); _return: - tFreeSSchedulerHbRsp(&rsp); taosMemoryFree(param); - + taosMemoryFree(pMsg->pData); SCH_RET(code); } -- GitLab From 680400834aeb9d2f30214a4cf9908b789fe223a9 Mon Sep 17 00:00:00 2001 From: Ganlin Zhao Date: Thu, 14 Jul 2022 19:17:28 +0800 Subject: [PATCH 144/153] refactor code --- source/libs/scalar/src/sclfunc.c | 38 +++++++++++++++++++++++--------- 1 file changed, 27 insertions(+), 11 deletions(-) diff --git a/source/libs/scalar/src/sclfunc.c b/source/libs/scalar/src/sclfunc.c index 8194be297f..47ab4c614a 100644 --- a/source/libs/scalar/src/sclfunc.c +++ b/source/libs/scalar/src/sclfunc.c @@ -1746,16 +1746,21 @@ int32_t countScalarFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam SColumnInfoData *pOutputData = pOutput->columnData; int64_t *out = (int64_t *)pOutputData->pData; + bool hasNull = false; *out = 0; for (int32_t i = 0; i < pInput->numOfRows; ++i) { if (colDataIsNull_s(pInputData, i)) { - colDataAppendNULL(pOutputData, i); + hasNull = true; break; } (*out)++; } - pOutput->numOfRows = pInput->numOfRows; + if (hasNull) { + colDataAppendNULL(pOutputData, 0); + } + + pOutput->numOfRows = 1; return TSDB_CODE_SUCCESS; } @@ -1764,9 +1769,10 @@ int32_t sumScalarFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam * SColumnInfoData *pOutputData = pOutput->columnData; int32_t type = GET_PARAM_TYPE(pInput); + bool hasNull = false; for (int32_t i = 0; i < pInput->numOfRows; ++i) { if (colDataIsNull_s(pInputData, i)) { - colDataAppendNULL(pOutputData, i); + hasNull = true; break; } @@ -1785,7 +1791,11 @@ int32_t sumScalarFunction(SScalarParam *pInput, int32_t inputNum, SScalarParam * } } - pOutput->numOfRows = pInput->numOfRows; + if (hasNull) { + colDataAppendNULL(pOutputData, 0); + } + + pOutput->numOfRows = 1; return TSDB_CODE_SUCCESS; } @@ -1795,6 +1805,7 @@ static int32_t doMinMaxScalarFunction(SScalarParam *pInput, int32_t inputNum, SS int32_t type = GET_PARAM_TYPE(pInput); + bool hasNull = false; if (isMinFunc) { SET_TYPED_DATA_MAX(pOutputData->pData, type); } else { @@ -1803,7 +1814,7 @@ static int32_t doMinMaxScalarFunction(SScalarParam *pInput, int32_t inputNum, SS for (int32_t i = 0; i < pInput->numOfRows; ++i) { if (colDataIsNull_s(pInputData, i)) { - colDataAppendNULL(pOutputData, i); + hasNull = true; break; } @@ -1892,7 +1903,11 @@ static int32_t doMinMaxScalarFunction(SScalarParam *pInput, int32_t inputNum, SS } } - pOutput->numOfRows = pInput->numOfRows; + if (hasNull) { + colDataAppendNULL(pOutputData, 0); + } + + pOutput->numOfRows = 1; return TSDB_CODE_SUCCESS; } @@ -1909,13 +1924,14 @@ int32_t stddevScalarFunction(SScalarParam *pInput, int32_t inputNum, SScalarPara SColumnInfoData *pOutputData = pOutput->columnData; int32_t type = GET_PARAM_TYPE(pInput); - int64_t count = 0, sum = 0, qSum = 0; + //int64_t count = 0, sum = 0, qSum = 0; + bool hasNull = false; for (int32_t i = 0; i < pInput->numOfRows; ++i) { if (colDataIsNull_s(pInputData, i)) { - continue; + hasNull = true; + break; } - count++; #if 0 switch(type) { case TSDB_DATA_TYPE_TINYINT: { @@ -1993,7 +2009,7 @@ int32_t stddevScalarFunction(SScalarParam *pInput, int32_t inputNum, SScalarPara } double *out = (double *)pOutputData->pData; - if (count == 0) { + if (hasNull) { colDataAppendNULL(pOutputData, 0); } else { *out = 0; @@ -2012,6 +2028,6 @@ int32_t stddevScalarFunction(SScalarParam *pInput, int32_t inputNum, SScalarPara #endif } - pOutput->numOfRows = pInput->numOfRows; + pOutput->numOfRows = 1; return TSDB_CODE_SUCCESS; } -- GitLab From a911feeab70f47f586f7a1ce7b8192fd699de1ec Mon Sep 17 00:00:00 2001 From: Haojun Liao Date: Thu, 14 Jul 2022 19:18:15 +0800 Subject: [PATCH 145/153] fix(query): fix syntax error. --- source/libs/executor/src/executorimpl.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/source/libs/executor/src/executorimpl.c b/source/libs/executor/src/executorimpl.c index 4e010cfdf1..4168d839d3 100644 --- a/source/libs/executor/src/executorimpl.c +++ b/source/libs/executor/src/executorimpl.c @@ -4439,21 +4439,21 @@ SOperatorInfo* createOperatorTree(SPhysiNode* pPhyNode, SExecTaskInfo* pTaskInfo // return NULL; // } - int32_t code = extractTableSchemaInfo(pHandle, pScanNode->uid, pTaskInfo); + int32_t code = extractTableSchemaInfo(pHandle, pScanNode->scan.uid, pTaskInfo); if (code != TSDB_CODE_SUCCESS) { pTaskInfo->code = code; return NULL; } pTableListInfo->pTableList = taosArrayInit(4, sizeof(STableKeyInfo)); - if (pScanNode->tableType == TSDB_SUPER_TABLE) { - code = vnodeGetAllTableList(pHandle->vnode, pScanNode->uid, pTableListInfo->pTableList); + if (pScanNode->scan.tableType == TSDB_SUPER_TABLE) { + code = vnodeGetAllTableList(pHandle->vnode, pScanNode->scan.uid, pTableListInfo->pTableList); if (code != TSDB_CODE_SUCCESS) { pTaskInfo->code = terrno; return NULL; } } else { // Create one table group. - STableKeyInfo info = {.lastKey = 0, .uid = pScanNode->uid, .groupId = 0}; + STableKeyInfo info = {.lastKey = 0, .uid = pScanNode->scan.uid, .groupId = 0}; taosArrayPush(pTableListInfo->pTableList, &info); } -- GitLab From 31dbb07d8a93334d1dd05d8aeefff18727d6944b Mon Sep 17 00:00:00 2001 From: Shengliang Guan Date: Thu, 14 Jul 2022 19:32:34 +0800 Subject: [PATCH 146/153] test: restore some 2.0 case --- tests/script/tsim/compute/block_dist.sim | 25 +++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/tests/script/tsim/compute/block_dist.sim b/tests/script/tsim/compute/block_dist.sim index 1583e838c6..73cbca84cf 100644 --- a/tests/script/tsim/compute/block_dist.sim +++ b/tests/script/tsim/compute/block_dist.sim @@ -47,24 +47,30 @@ while $x < $rowNum $x = $x + 1 endw +sql flush database $db + print =============== step2 $i = 0 $tb = $tbPrefix . $i -sql select _block_dist() from $tb +#sql select _block_dist() from $tb +print show table distributed $tb +sql show table distributed $tb -if $rows != 1 then - print expect 1, actual:$rows +print $rows +if $rows == 0 then return -1 endi print =============== step3 $i = 0 $mt = $mtPrefix . $i -sql select _block_dist() from $mt +#sql select _block_dist() from $mt + +print show table distributed $mt +sql show table distributed $mt -if $rows != 1 then - print expect 1, actual:$rows +if $rows == 0 then return -1 endi @@ -72,10 +78,11 @@ print =============== step4 $i = 0 $nt = $ntPrefix . $i -sql select _block_dist() from $nt +#sql select _block_dist() from $nt +print show table distributed $nt +sql show table distributed $nt -if $rows != 1 then - print expect 1, actual:$rows +if $rows == 0 then return -1 endi -- GitLab From a2a1deccf412f1b2516ad57a91cffd28fcfee071 Mon Sep 17 00:00:00 2001 From: Shengliang Guan Date: Thu, 14 Jul 2022 19:43:52 +0800 Subject: [PATCH 147/153] test: restore some 2.0 case --- tests/script/tsim/tag/add.sim | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/script/tsim/tag/add.sim b/tests/script/tsim/tag/add.sim index 2901614889..423224b1d6 100644 --- a/tests/script/tsim/tag/add.sim +++ b/tests/script/tsim/tag/add.sim @@ -242,7 +242,7 @@ if $data04 != 3 then return -1 endi -sql alter table $mt change tag tgcol1 tgcol4 +sql alter table $mt rename tag tgcol1 tgcol4 sql alter table $mt drop tag tgcol2 sql alter table $mt drop tag tgcol3 sql alter table $mt add tag tgcol5 binary(10) @@ -322,7 +322,7 @@ if $data04 != 3 then return -1 endi -sql alter table $mt change tag tgcol1 tgcol4 +sql alter table $mt rename tag tgcol1 tgcol4 sql alter table $mt drop tag tgcol2 sql alter table $mt drop tag tgcol3 sql alter table $mt add tag tgcol5 bigint @@ -383,7 +383,7 @@ if $data04 != 3 then return -1 endi -sql alter table $mt change tag tgcol1 tgcol4 +sql alter table $mt rename tag tgcol1 tgcol4 sql alter table $mt drop tag tgcol2 sql alter table $mt drop tag tgcol3 sql alter table $mt add tag tgcol5 binary(17) @@ -444,7 +444,7 @@ if $data04 != 3 then return -1 endi -sql alter table $mt change tag tgcol1 tgcol4 +sql alter table $mt rename tag tgcol1 tgcol4 sql alter table $mt drop tag tgcol2 sql alter table $mt drop tag tgcol3 sql alter table $mt add tag tgcol5 bool @@ -508,7 +508,7 @@ if $data05 != 4 then return -1 endi -sql alter table $mt change tag tgcol1 tgcol4 -x step103 +sql alter table $mt rename tag tgcol1 tgcol4 -x step103 return -1 step103: @@ -582,7 +582,7 @@ if $data06 != 5 then return -1 endi -sql alter table $mt change tag tgcol1 tgcol4 -x step114 +sql alter table $mt rename tag tgcol1 tgcol4 -x step114 return -1 step114: -- GitLab From 707f0a837acd4c408d6e71849540abd32a998941 Mon Sep 17 00:00:00 2001 From: Haojun Liao Date: Thu, 14 Jul 2022 20:11:29 +0800 Subject: [PATCH 148/153] fix(query): set correct fill output object. --- include/libs/function/functionMgt.h | 1 - source/dnode/vnode/src/tsdb/tsdbRead.c | 9 +++------ source/libs/executor/src/executorimpl.c | 6 ++++-- source/libs/function/inc/builtinsimpl.h | 3 +-- source/libs/function/src/builtins.c | 17 +++++++++++------ source/libs/function/src/builtinsimpl.c | 2 +- tests/script/tsim/compute/interval.sim | 3 ++- 7 files changed, 22 insertions(+), 19 deletions(-) diff --git a/include/libs/function/functionMgt.h b/include/libs/function/functionMgt.h index 04825f376f..299d808017 100644 --- a/include/libs/function/functionMgt.h +++ b/include/libs/function/functionMgt.h @@ -34,7 +34,6 @@ typedef enum EFunctionType { FUNCTION_TYPE_ELAPSED, FUNCTION_TYPE_IRATE, FUNCTION_TYPE_LAST_ROW, - FUNCTION_TYPE_LAST_ROWT, // TODO: removed FUNCTION_TYPE_MAX, FUNCTION_TYPE_MIN, FUNCTION_TYPE_MODE, diff --git a/source/dnode/vnode/src/tsdb/tsdbRead.c b/source/dnode/vnode/src/tsdb/tsdbRead.c index 5e30fcd5b2..1a9e12c9ca 100644 --- a/source/dnode/vnode/src/tsdb/tsdbRead.c +++ b/source/dnode/vnode/src/tsdb/tsdbRead.c @@ -3127,14 +3127,11 @@ int32_t tsdbGetFileBlocksDistInfo(STsdbReader* pReader, STableBlockDistInfo* pTa } pTableBlockInfo->numOfBlocks += pBlockIter->numOfBlocks; + hasNext = (pBlockIter->numOfBlocks > 0); } - /* - hasNext = blockIteratorNext(&pStatus->blockIter); - */ - - // tsdbDebug("%p %d blocks found in file for %d table(s), fid:%d, %s", pReader, numOfBlocks, numOfTables, - // pReader->pFileGroup->fid, pReader->idStr); +// tsdbDebug("%p %d blocks found in file for %d table(s), fid:%d, %s", pReader, numOfBlocks, numOfTables, +// pReader->pFileGroup->fid, pReader->idStr); } return code; diff --git a/source/libs/executor/src/executorimpl.c b/source/libs/executor/src/executorimpl.c index 4168d839d3..89542571ea 100644 --- a/source/libs/executor/src/executorimpl.c +++ b/source/libs/executor/src/executorimpl.c @@ -3409,8 +3409,8 @@ static SSDataBlock* doFillImpl(SOperatorInfo* pOperator) { blockDataEnsureCapacity(pResBlock, pOperator->resultInfo.capacity); - int32_t numOfResultRows = pOperator->resultInfo.capacity - pBlock->info.rows; - taosFillResultDataBlock(pInfo->pFillInfo, pBlock, numOfResultRows); + int32_t numOfResultRows = pOperator->resultInfo.capacity - pResBlock->info.rows; + taosFillResultDataBlock(pInfo->pFillInfo, pResBlock, numOfResultRows); // current group has no more result to return if (pResBlock->info.rows > 0) { @@ -4423,6 +4423,8 @@ SOperatorInfo* createOperatorTree(SPhysiNode* pPhyNode, SExecTaskInfo* pTaskInfo cond.twindows = (STimeWindow){.skey = INT64_MIN, .ekey = INT64_MAX}; cond.suid = pBlockNode->suid; cond.type = BLOCK_LOAD_OFFSET_ORDER; + cond.startVersion = -1; + cond.endVersion = -1; } STsdbReader* pReader = NULL; diff --git a/source/libs/function/inc/builtinsimpl.h b/source/libs/function/inc/builtinsimpl.h index e8e37e5c6b..30fdbb245d 100644 --- a/source/libs/function/inc/builtinsimpl.h +++ b/source/libs/function/inc/builtinsimpl.h @@ -106,7 +106,7 @@ bool irateFuncSetup(SqlFunctionCtx *pCtx, SResultRowEntryInfo* pResInfo); int32_t irateFunction(SqlFunctionCtx *pCtx); int32_t irateFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock); -int32_t lastrowFunction(SqlFunctionCtx* pCtx); +int32_t cacheLastRowFunction(SqlFunctionCtx* pCtx); bool getFirstLastFuncEnv(struct SFunctionNode* pFunc, SFuncExecEnv* pEnv); int32_t firstFunction(SqlFunctionCtx *pCtx); @@ -120,7 +120,6 @@ int32_t lastCombine(SqlFunctionCtx* pDestCtx, SqlFunctionCtx* pSourceCtx); int32_t getFirstLastInfoSize(int32_t resBytes); int32_t lastRowFunction(SqlFunctionCtx *pCtx); -int32_t lastRowFinalize(SqlFunctionCtx* pCtx, SSDataBlock* pBlock); bool getTopBotFuncEnv(SFunctionNode* UNUSED_PARAM(pFunc), SFuncExecEnv* pEnv); bool getTopBotMergeFuncEnv(SFunctionNode* UNUSED_PARAM(pFunc), SFuncExecEnv* pEnv); diff --git a/source/libs/function/src/builtins.c b/source/libs/function/src/builtins.c index 5feb142757..7b784e9f32 100644 --- a/source/libs/function/src/builtins.c +++ b/source/libs/function/src/builtins.c @@ -1370,11 +1370,6 @@ static int32_t translateTail(SFunctionNode* pFunc, char* pErrBuf, int32_t len) { return TSDB_CODE_SUCCESS; } -static int32_t translateLastRow(SFunctionNode* pFunc, char* pErrBuf, int32_t len) { - // todo - return TSDB_CODE_SUCCESS; -} - static int32_t translateDerivative(SFunctionNode* pFunc, char* pErrBuf, int32_t len) { if (3 != LIST_LENGTH(pFunc->pParameterList)) { return invaildFuncParaNumErrMsg(pErrBuf, len, pFunc->functionName); @@ -2221,7 +2216,17 @@ const SBuiltinFuncDefinition funcMgtBuiltins[] = { .translateFunc = translateFirstLast, .getEnvFunc = getFirstLastFuncEnv, .initFunc = functionSetup, - .processFunc = lastrowFunction, + .processFunc = lastRowFunction, + .finalizeFunc = firstLastFinalize + }, + { + .name = "_cache_last_row", + .type = FUNCTION_TYPE_CACHE_LAST_ROW, + .classification = FUNC_MGT_AGG_FUNC | FUNC_MGT_MULTI_RES_FUNC | FUNC_MGT_TIMELINE_FUNC | FUNC_MGT_IMPLICIT_TS_FUNC, + .translateFunc = translateFirstLast, + .getEnvFunc = getFirstLastFuncEnv, + .initFunc = functionSetup, + .processFunc = cacheLastRowFunction, .finalizeFunc = firstLastFinalize }, { diff --git a/source/libs/function/src/builtinsimpl.c b/source/libs/function/src/builtinsimpl.c index 0245379672..e2288d9f70 100644 --- a/source/libs/function/src/builtinsimpl.c +++ b/source/libs/function/src/builtinsimpl.c @@ -5993,7 +5993,7 @@ int32_t interpFunction(SqlFunctionCtx* pCtx) { return TSDB_CODE_SUCCESS; } -int32_t lastrowFunction(SqlFunctionCtx* pCtx) { +int32_t cacheLastRowFunction(SqlFunctionCtx* pCtx) { int32_t numOfElems = 0; SResultRowEntryInfo* pResInfo = GET_RES_INFO(pCtx); diff --git a/tests/script/tsim/compute/interval.sim b/tests/script/tsim/compute/interval.sim index 2e38990975..9c0804efe7 100644 --- a/tests/script/tsim/compute/interval.sim +++ b/tests/script/tsim/compute/interval.sim @@ -103,7 +103,8 @@ $ms2 = 1601481600000 - $cc sql select count(tbcol), avg(tbcol), max(tbcol), min(tbcol), count(tbcol) from $tb where ts <= $ms and ts > $ms2 interval(1m) fill(value,0) print ===> $rows -if $rows < 30 then +if $rows < 30 then + print expect greater than 30, actual: $rows return -1 endi if $rows > 50 then -- GitLab From ab6ed4bffa35f61587b750dd7204690ba696ac5b Mon Sep 17 00:00:00 2001 From: Haojun Liao Date: Thu, 14 Jul 2022 20:37:07 +0800 Subject: [PATCH 149/153] fix(query): add exec node for lastrow query. --- source/libs/planner/src/planPhysiCreater.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/source/libs/planner/src/planPhysiCreater.c b/source/libs/planner/src/planPhysiCreater.c index c4cc31c535..27948212ea 100644 --- a/source/libs/planner/src/planPhysiCreater.c +++ b/source/libs/planner/src/planPhysiCreater.c @@ -513,7 +513,9 @@ static int32_t createLastRowScanPhysiNode(SPhysiPlanContext* pCxt, SSubplan* pSu nodesDestroyNode((SNode*)pScan); return TSDB_CODE_OUT_OF_MEMORY; } + pScan->groupSort = pScanLogicNode->groupSort; + vgroupInfoToNodeAddr(pScanLogicNode->pVgroupList->vgroups, &pSubplan->execNode); return createScanPhysiNodeFinalize(pCxt, pSubplan, pScanLogicNode, (SScanPhysiNode*)pScan, pPhyNode); } -- GitLab From c36c9bca1f1e4b0a93b82b35e30e16bb637b0320 Mon Sep 17 00:00:00 2001 From: Shengliang Guan Date: Thu, 14 Jul 2022 20:38:59 +0800 Subject: [PATCH 150/153] test: restore some 2.0 case --- tests/script/jenkins/basic.txt | 82 +- tests/script/tsim/compute/null.sim | 2 +- tests/script/tsim/db/alter_tables_d2.sim | 570 -------------- tests/script/tsim/db/alter_tables_v1.sim | 436 ----------- tests/script/tsim/db/alter_tables_v4.sim | 529 ------------- tests/script/tsim/db/alter_vgroups.sim | 210 ----- tests/script/tsim/db/basic4.sim | 40 +- tests/script/tsim/db/basic5.sim | 54 +- tests/script/tsim/db/basic7.sim | 47 -- tests/script/tsim/db/keep.sim | 66 +- tests/script/tsim/db/len.sim | 26 +- tests/script/tsim/db/nosuchfile.sim | 66 -- tests/script/tsim/db/repeat.sim | 13 +- tests/script/tsim/db/show_create_db.sim | 4 - tests/script/tsim/db/show_create_table.sim | 4 - tests/script/tsim/db/tables.sim | 11 +- tests/script/tsim/db/testSuite.sim | 16 - tests/script/tsim/db/topic1.sim | 857 --------------------- tests/script/tsim/db/topic2.sim | 321 -------- tests/script/tsim/db/vnodes.sim | 47 -- 20 files changed, 128 insertions(+), 3273 deletions(-) delete mode 100644 tests/script/tsim/db/alter_tables_d2.sim delete mode 100644 tests/script/tsim/db/alter_tables_v1.sim delete mode 100644 tests/script/tsim/db/alter_tables_v4.sim delete mode 100644 tests/script/tsim/db/alter_vgroups.sim delete mode 100644 tests/script/tsim/db/basic7.sim delete mode 100644 tests/script/tsim/db/nosuchfile.sim delete mode 100644 tests/script/tsim/db/testSuite.sim delete mode 100644 tests/script/tsim/db/topic1.sim delete mode 100644 tests/script/tsim/db/topic2.sim delete mode 100644 tests/script/tsim/db/vnodes.sim diff --git a/tests/script/jenkins/basic.txt b/tests/script/jenkins/basic.txt index c2c102c241..23f2ff01f8 100644 --- a/tests/script/jenkins/basic.txt +++ b/tests/script/jenkins/basic.txt @@ -9,20 +9,15 @@ # ---- db ./test.sh -f tsim/db/alter_option.sim -# ./test.sh -f tsim/db/alter_replica_13.sim -# ./test.sh -f tsim/db/alter_replica_31.sim -#./test.sh -f tsim/db/alter_tables_d2.sim -#./test.sh -f tsim/db/alter_tables_v1.sim -#./test.sh -f tsim/db/alter_tables_v4.sim -#./test.sh -f tsim/db/alter_vgroups.sim +# unsupport ./test.sh -f tsim/db/alter_replica_13.sim +# unsupport ./test.sh -f tsim/db/alter_replica_31.sim ./test.sh -f tsim/db/basic1.sim ./test.sh -f tsim/db/basic2.sim ./test.sh -f tsim/db/basic3.sim -#./test.sh -f tsim/db/basic4.sim -#./test.sh -f tsim/db/basic5.sim +./test.sh -f tsim/db/basic4.sim +./test.sh -f tsim/db/basic5.sim ./test.sh -f tsim/db/basic6.sim -./test.sh -f tsim/db/basic7.sim -#./test.sh -f tsim/db/commit.sim +# nojira ./test.sh -f tsim/db/commit.sim ./test.sh -f tsim/db/create_all_options.sim #./test.sh -f tsim/db/delete_part.sim #./test.sh -f tsim/db/delete_reuse1.sim @@ -33,41 +28,37 @@ #./test.sh -f tsim/db/delete_writing2.sim #./test.sh -f tsim/db/delete.sim #./test.sh -f tsim/db/delete2.sim -#./test.sh -f tsim/db/dropvnodes.sim +# unsupport ./test.sh -f tsim/db/dropdnodes.sim ./test.sh -f tsim/db/error1.sim -#./test.sh -f tsim/db/keep.sim -#./test.sh -f tsim/db/len.sim -#./test.sh -f tsim/db/nosuchfile.sim -#./test.sh -f tsim/db/repeat.sim -#./test.sh -f tsim/db/show_create_db.sim -#./test.sh -f tsim/db/show_create_table.sim -#./test.sh -f tsim/db/tables.sim +# nojira ./test.sh -f tsim/db/keep.sim +./test.sh -f tsim/db/len.sim +./test.sh -f tsim/db/repeat.sim +./test.sh -f tsim/db/show_create_db.sim +./test.sh -f tsim/db/show_create_table.sim +./test.sh -f tsim/db/tables.sim ./test.sh -f tsim/db/taosdlog.sim -#./test.sh -f tsim/db/topic1.sim -#./test.sh -f tsim/db/topic2.sim -#./test.sh -f tsim/db/vnodes.sim # ---- dnode -# ./test.sh -f tsim/dnode/balance_replica1.sim -# ./test.sh -f tsim/dnode/balance_replica3.sim -# ./test.sh -f tsim/dnode/balance1.sim -# ./test.sh -f tsim/dnode/balance2.sim -# ./test.sh -f tsim/dnode/balance3.sim -# ./test.sh -f tsim/dnode/balancex.sim +# unsupport ./test.sh -f tsim/dnode/balance_replica1.sim +# unsupport ./test.sh -f tsim/dnode/balance_replica3.sim +# unsupport ./test.sh -f tsim/dnode/balance1.sim +# unsupport ./test.sh -f tsim/dnode/balance2.sim +# unsupport ./test.sh -f tsim/dnode/balance3.sim +# unsupport ./test.sh -f tsim/dnode/balancex.sim ./test.sh -f tsim/dnode/create_dnode.sim ./test.sh -f tsim/dnode/drop_dnode_has_mnode.sim -# ./test.sh -f tsim/dnode/drop_dnode_has_qnode_snode.sim -# ./test.sh -f tsim/dnode/drop_dnode_has_vnode_replica1.sim -# ./test.sh -f tsim/dnode/drop_dnode_has_vnode_replica3.sim -# ./test.sh -f tsim/dnode/drop_dnode_has_multi_vnode_replica1.sim -# ./test.sh -f tsim/dnode/drop_dnode_has_multi_vnode_replica3.sim +# unsupport ./test.sh -f tsim/dnode/drop_dnode_has_qnode_snode.sim +# unsupport ./test.sh -f tsim/dnode/drop_dnode_has_vnode_replica1.sim +# unsupport ./test.sh -f tsim/dnode/drop_dnode_has_vnode_replica3.sim +# unsupport ./test.sh -f tsim/dnode/drop_dnode_has_multi_vnode_replica1.sim +# unsupport ./test.sh -f tsim/dnode/drop_dnode_has_multi_vnode_replica3.sim ./test.sh -f tsim/dnode/offline_reason.sim -# ./test.sh -f tsim/dnode/redistribute_vgroup_replica1.sim -# ./test.sh -f tsim/dnode/redistribute_vgroup_replica3_v1_leader.sim -# ./test.sh -f tsim/dnode/redistribute_vgroup_replica3_v1_follower.sim -# ./test.sh -f tsim/dnode/redistribute_vgroup_replica3_v2.sim -# ./test.sh -f tsim/dnode/redistribute_vgroup_replica3_v3.sim -# ./test.sh -f tsim/dnode/vnode_clean.sim +# unsupport ./test.sh -f tsim/dnode/redistribute_vgroup_replica1.sim +# unsupport ./test.sh -f tsim/dnode/redistribute_vgroup_replica3_v1_leader.sim +# unsupport ./test.sh -f tsim/dnode/redistribute_vgroup_replica3_v1_follower.sim +# unsupport ./test.sh -f tsim/dnode/redistribute_vgroup_replica3_v2.sim +# unsupport ./test.sh -f tsim/dnode/redistribute_vgroup_replica3_v3.sim +# unsupport ./test.sh -f tsim/dnode/vnode_clean.sim # ---- import ./test.sh -f tsim/import/basic.sim @@ -394,19 +385,19 @@ # ---- compute ./test.sh -f tsim/compute/avg.sim -#./test.sh -f tsim/compute/block_dist.sim +# jira ./test.sh -f tsim/compute/block_dist.sim ./test.sh -f tsim/compute/bottom.sim ./test.sh -f tsim/compute/count.sim ./test.sh -f tsim/compute/diff.sim ./test.sh -f tsim/compute/diff2.sim ./test.sh -f tsim/compute/first.sim ./test.sh -f tsim/compute/interval.sim -#./test.sh -f tsim/compute/last_row.sim +# jira ./test.sh -f tsim/compute/last_row.sim ./test.sh -f tsim/compute/last.sim ./test.sh -f tsim/compute/leastsquare.sim ./test.sh -f tsim/compute/max.sim ./test.sh -f tsim/compute/min.sim -#./test.sh -f tsim/compute/null.sim +./test.sh -f tsim/compute/null.sim ./test.sh -f tsim/compute/percentile.sim ./test.sh -f tsim/compute/stddev.sim ./test.sh -f tsim/compute/sum.sim @@ -455,8 +446,8 @@ ./test.sh -f tsim/tag/3.sim ./test.sh -f tsim/tag/4.sim ./test.sh -f tsim/tag/5.sim -#./test.sh -f tsim/tag/6.sim -#./test.sh -f tsim/tag/add.sim +# jira ./test.sh -f tsim/tag/6.sim +# jira ./test.sh -f tsim/tag/add.sim ./test.sh -f tsim/tag/bigint.sim ./test.sh -f tsim/tag/binary_binary.sim ./test.sh -f tsim/tag/binary.sim @@ -468,9 +459,9 @@ #./test.sh -f tsim/tag/commit.sim #./test.sh -f tsim/tag/create.sim #./test.sh -f tsim/tag/delete.sim -#./test.sh -f tsim/tag/double.sim +# jira ./test.sh -f tsim/tag/double.sim #./test.sh -f tsim/tag/filter.sim -#./test.sh -f tsim/tag/float.sim +# jira ./test.sh -f tsim/tag/float.sim ./test.sh -f tsim/tag/int_binary.sim ./test.sh -f tsim/tag/int_float.sim ./test.sh -f tsim/tag/int.sim @@ -478,5 +469,4 @@ ./test.sh -f tsim/tag/smallint.sim ./test.sh -f tsim/tag/tinyint.sim - #======================b1-end=============== diff --git a/tests/script/tsim/compute/null.sim b/tests/script/tsim/compute/null.sim index b5647a1e34..48fa70ae7a 100644 --- a/tests/script/tsim/compute/null.sim +++ b/tests/script/tsim/compute/null.sim @@ -113,7 +113,7 @@ sql create table tt using $mt tags( NULL ) #step52: sql select * from $mt where tgcol is NULL -if $rows != 1 then +if $rows != 0 then return -1 endi diff --git a/tests/script/tsim/db/alter_tables_d2.sim b/tests/script/tsim/db/alter_tables_d2.sim deleted file mode 100644 index f74f98d571..0000000000 --- a/tests/script/tsim/db/alter_tables_d2.sim +++ /dev/null @@ -1,570 +0,0 @@ -system sh/stop_dnodes.sh -system sh/deploy.sh -n dnode1 -i 1 -system sh/cfg.sh -n dnode1 -c wallevel -v 2 -system sh/cfg.sh -n dnode1 -c maxVgroupsPerDb -v 4 -system sh/cfg.sh -n dnode1 -c maxTablesPerVnode -v 5 - -system sh/deploy.sh -n dnode2 -i 2 -system sh/cfg.sh -n dnode2 -c wallevel -v 2 -system sh/cfg.sh -n dnode2 -c maxVgroupsPerDb -v 4 -system sh/cfg.sh -n dnode2 -c maxTablesPerVnode -v 5 - -system sh/exec.sh -n dnode1 -s start -system sh/exec.sh -n dnode2 -s start -sql connect -sql create dnode $hostname2 - -$x = 0 -step1: - $x = $x + 1 - sleep 1000 - if $x == 10 then - return -1 - endi - -sql show dnodes -print dnode1 $data4_1 -print dnode2 $data4_2 -if $data4_1 != ready then - goto step1 -endi -if $data4_2 != ready then - goto step1 -endi - -print ============================ step1 - -sql create database db -sql create table db.st (ts timestamp, i int) tags(t int) -sql create table db.t000 using db.st tags(0) -sql create table db.t001 using db.st tags(1) -sql create table db.t002 using db.st tags(2) -sql create table db.t003 using db.st tags(3) -sql create table db.t004 using db.st tags(4) -sql create table db.t005 using db.st tags(5) -sql create table db.t006 using db.st tags(6) -sql create table db.t007 using db.st tags(7) -sql create table db.t008 using db.st tags(8) -sql create table db.t009 using db.st tags(9) -sql create table db.t010 using db.st tags(0) -sql create table db.t011 using db.st tags(1) -sql create table db.t012 using db.st tags(2) -sql create table db.t013 using db.st tags(3) -sql create table db.t014 using db.st tags(4) -sql create table db.t015 using db.st tags(5) -sql create table db.t016 using db.st tags(6) -sql create table db.t017 using db.st tags(7) -sql create table db.t018 using db.st tags(8) -sql create table db.t019 using db.st tags(9) - -sql show db.tables -if $rows != 20 then - return -1 -endi - -sql insert into db.t000 values(now, 1) -sql insert into db.t001 values(now, 1) -sql insert into db.t002 values(now, 1) -sql insert into db.t003 values(now, 1) -sql insert into db.t004 values(now, 1) -sql insert into db.t005 values(now, 1) -sql insert into db.t006 values(now, 1) -sql insert into db.t007 values(now, 1) -sql insert into db.t008 values(now, 1) -sql insert into db.t009 values(now, 1) -sql insert into db.t010 values(now, 1) -sql insert into db.t011 values(now, 1) -sql insert into db.t012 values(now, 1) -sql insert into db.t013 values(now, 1) -sql insert into db.t014 values(now, 1) -sql insert into db.t015 values(now, 1) -sql insert into db.t016 values(now, 1) -sql insert into db.t017 values(now, 1) -sql insert into db.t018 values(now, 1) -sql insert into db.t019 values(now, 1) - -print ============================ step2 -sql_error create table db.t100 using db.st tags(10) -sql show db.tables -if $rows != 20 then - return -1 -endi - -print ============================ step3 -system sh/exec.sh -n dnode1 -s stop -x SIGINT -system sh/exec.sh -n dnode2 -s stop -x SIGINT -system sh/cfg.sh -n dnode1 -c maxTablesPerVnode -v 10 -system sh/cfg.sh -n dnode2 -c maxTablesPerVnode -v 10 -system sh/exec.sh -n dnode1 -s start -system sh/exec.sh -n dnode2 -s start -$x = 0 -step2: - $x = $x + 1 - sleep 1000 - if $x == 10 then - return -1 - endi - -sql show mnodes -x step1 -print mnode1 $data2_1 -print mnode1 $data2_2 -print mnode1 $data2_3 -if $data2_1 != master then - goto step2 -endi - -sql create table db.t100 using db.st tags(0) -sql create table db.t101 using db.st tags(1) -sql create table db.t102 using db.st tags(2) -sql create table db.t103 using db.st tags(3) -sql create table db.t104 using db.st tags(4) -sql create table db.t105 using db.st tags(5) -sql create table db.t106 using db.st tags(6) -sql create table db.t107 using db.st tags(7) -sql create table db.t108 using db.st tags(8) -sql create table db.t109 using db.st tags(9) -sql create table db.t110 using db.st tags(0) -sql create table db.t111 using db.st tags(1) -sql create table db.t112 using db.st tags(2) -sql create table db.t113 using db.st tags(3) -sql create table db.t114 using db.st tags(4) -sql create table db.t115 using db.st tags(5) -sql create table db.t116 using db.st tags(6) -sql create table db.t117 using db.st tags(7) -sql create table db.t118 using db.st tags(8) -sql create table db.t119 using db.st tags(9) -sql show db.tables -if $rows != 40 then - return -1 -endi - -sql insert into db.t100 values(now, 1) -sql insert into db.t101 values(now, 1) -sql insert into db.t102 values(now, 1) -sql insert into db.t103 values(now, 1) -sql insert into db.t104 values(now, 1) -sql insert into db.t105 values(now, 1) -sql insert into db.t106 values(now, 1) -sql insert into db.t107 values(now, 1) -sql insert into db.t108 values(now, 1) -sql insert into db.t109 values(now, 1) -sql insert into db.t110 values(now, 1) -sql insert into db.t111 values(now, 1) -sql insert into db.t112 values(now, 1) -sql insert into db.t113 values(now, 1) -sql insert into db.t114 values(now, 1) -sql insert into db.t115 values(now, 1) -sql insert into db.t116 values(now, 1) -sql insert into db.t117 values(now, 1) -sql insert into db.t118 values(now, 1) -sql insert into db.t119 values(now, 1) - -print ============================ step4 -sql_error create table db.t200 using db.st tags(10) -sql show db.tables -if $rows != 40 then - return -1 -endi - -print ============================ step5 -system sh/exec.sh -n dnode1 -s stop -x SIGINT -system sh/exec.sh -n dnode2 -s stop -x SIGINT -system sh/cfg.sh -n dnode1 -c maxTablesPerVnode -v 15 -system sh/cfg.sh -n dnode2 -c maxTablesPerVnode -v 15 -system sh/exec.sh -n dnode1 -s start -system sh/exec.sh -n dnode2 -s start - -$x = 0 -step3: - $x = $x + 1 - sleep 1000 - if $x == 10 then - return -1 - endi - -sql show mnodes -x step3 -print mnode1 $data2_1 -print mnode1 $data2_2 -print mnode1 $data2_3 -if $data2_1 != master then - goto step3 -endi - -sql create table db.t200 using db.st tags(0) -sql create table db.t201 using db.st tags(1) -sql create table db.t202 using db.st tags(2) -sql create table db.t203 using db.st tags(3) -sql create table db.t204 using db.st tags(4) -sql create table db.t205 using db.st tags(5) -sql create table db.t206 using db.st tags(6) -sql create table db.t207 using db.st tags(7) -sql create table db.t208 using db.st tags(8) -sql create table db.t209 using db.st tags(9) -sql create table db.t210 using db.st tags(0) -sql create table db.t211 using db.st tags(1) -sql create table db.t212 using db.st tags(2) -sql create table db.t213 using db.st tags(3) -sql create table db.t214 using db.st tags(4) -sql create table db.t215 using db.st tags(5) -sql create table db.t216 using db.st tags(6) -sql create table db.t217 using db.st tags(7) -sql create table db.t218 using db.st tags(8) -sql create table db.t219 using db.st tags(9) -sql show db.tables -if $rows != 60 then - return -1 -endi - -sql insert into db.t200 values(now, 1) -sql insert into db.t201 values(now, 1) -sql insert into db.t202 values(now, 1) -sql insert into db.t203 values(now, 1) -sql insert into db.t204 values(now, 1) -sql insert into db.t205 values(now, 1) -sql insert into db.t206 values(now, 1) -sql insert into db.t207 values(now, 1) -sql insert into db.t208 values(now, 1) -sql insert into db.t209 values(now, 1) -sql insert into db.t210 values(now, 1) -sql insert into db.t211 values(now, 1) -sql insert into db.t212 values(now, 1) -sql insert into db.t213 values(now, 1) -sql insert into db.t214 values(now, 1) -sql insert into db.t215 values(now, 1) -sql insert into db.t216 values(now, 1) -sql insert into db.t217 values(now, 1) -sql insert into db.t218 values(now, 1) -sql insert into db.t219 values(now, 1) - -print ============================ step6 - -sql reset query cache -sleep 100 - -sql select * from db.t000 -if $rows != 1 then - return -1 -endi - -sql select * from db.t100 -if $rows != 1 then - return -1 -endi - -sql select * from db.t200 -if $rows != 1 then - return -1 -endi - -sql select * from db.st -if $rows != 60 then - return -1 -endi - -print ============================ step7 -system sh/exec.sh -n dnode1 -s stop -x SIGINT -system sh/exec.sh -n dnode2 -s stop -x SIGINT -sleep 3000 -system sh/exec.sh -n dnode1 -s start -system sh/exec.sh -n dnode2 -s start -sleep 3000 - -sql reset query cache -sleep 1000 - -sql show db.tables -if $rows != 60 then - return -1 -endi - -sql select * from db.t000 -if $rows != 1 then - return -1 -endi - -sql select * from db.t100 -if $rows != 1 then - return -1 -endi - -sql select * from db.t200 -if $rows != 1 then - return -1 -endi - -sql select * from db.st -if $rows != 60 then - return -1 -endi - -print ============================ step8 -sql_error create table db.t300 using db.st tags(10) -sql show db.tables -if $rows != 60 then - return -1 -endi - -print ============================ step9 -system sh/exec.sh -n dnode1 -s stop -x SIGINT -system sh/exec.sh -n dnode2 -s stop -x SIGINT -system sh/cfg.sh -n dnode1 -c maxTablesPerVnode -v 20 -system sh/cfg.sh -n dnode2 -c maxTablesPerVnode -v 20 -system sh/exec.sh -n dnode1 -s start -system sh/exec.sh -n dnode2 -s start -$x = 0 -step9: - $x = $x + 1 - sleep 1000 - if $x == 10 then - return -1 - endi - -sql show mnodes -x step9 -print mnode1 $data2_1 -print mnode1 $data2_2 -print mnode1 $data2_3 -if $data2_1 != master then - goto step9 -endi - -sql create table db.t300 using db.st tags(0) -sql create table db.t301 using db.st tags(1) -sql create table db.t302 using db.st tags(2) -sql create table db.t303 using db.st tags(3) -sql create table db.t304 using db.st tags(4) -sql create table db.t305 using db.st tags(5) -sql create table db.t306 using db.st tags(6) -sql create table db.t307 using db.st tags(7) -sql create table db.t308 using db.st tags(8) -sql create table db.t309 using db.st tags(9) -sql create table db.t310 using db.st tags(0) -sql create table db.t311 using db.st tags(1) -sql create table db.t312 using db.st tags(2) -sql create table db.t313 using db.st tags(3) -sql create table db.t314 using db.st tags(4) -sql create table db.t315 using db.st tags(5) -sql create table db.t316 using db.st tags(6) -sql create table db.t317 using db.st tags(7) -sql create table db.t318 using db.st tags(8) -sql create table db.t319 using db.st tags(9) - -sql insert into db.t300 values(now, 1) -sql insert into db.t301 values(now, 1) -sql insert into db.t302 values(now, 1) -sql insert into db.t303 values(now, 1) -sql insert into db.t304 values(now, 1) -sql insert into db.t305 values(now, 1) -sql insert into db.t306 values(now, 1) -sql insert into db.t307 values(now, 1) -sql insert into db.t308 values(now, 1) -sql insert into db.t309 values(now, 1) -sql insert into db.t310 values(now, 1) -sql insert into db.t311 values(now, 1) -sql insert into db.t312 values(now, 1) -sql insert into db.t313 values(now, 1) -sql insert into db.t314 values(now, 1) -sql insert into db.t315 values(now, 1) -sql insert into db.t316 values(now, 1) -sql insert into db.t317 values(now, 1) -sql insert into db.t318 values(now, 1) -sql insert into db.t319 values(now, 1) - -sql show db.tables -if $rows != 80 then - return -1 -endi - -sql reset query cache -sleep 100 - -sql select * from db.t000 -if $rows != 1 then - return -1 -endi - -sql select * from db.t100 -if $rows != 1 then - return -1 -endi - -sql select * from db.t200 -if $rows != 1 then - return -1 -endi - -sql select * from db.t300 -if $rows != 1 then - return -1 -endi - -sql select * from db.st -if $rows != 80 then - return -1 -endi - -print ============================ step10 -system sh/exec.sh -n dnode1 -s stop -x SIGINT -system sh/exec.sh -n dnode2 -s stop -x SIGINT -system sh/exec.sh -n dnode1 -s start -system sh/exec.sh -n dnode2 -s start -$x = 0 -step10: - $x = $x + 1 - sleep 1000 - if $x == 10 then - return -1 - endi - -sql show mnodes -x step10 -print mnode1 $data2_1 -print mnode1 $data2_2 -print mnode1 $data2_3 -if $data2_1 != master then - goto step10 -endi - -sql reset query cache -sleep 100 - -sql show db.tables -if $rows != 80 then - return -1 -endi - -sql select * from db.t000 -if $rows != 1 then - return -1 -endi - -sql select * from db.t100 -if $rows != 1 then - return -1 -endi - -sql select * from db.t200 -if $rows != 1 then - return -1 -endi - -sql select * from db.t300 -if $rows != 1 then - return -1 -endi - -sql select * from db.st -if $rows != 80 then - return -1 -endi - -print ============================ step11 -sql_error create table db.t400 using db.st tags(10) -sql show db.tables -if $rows != 80 then - return -1 -endi - -print ============================ step9 -system sh/exec.sh -n dnode1 -s stop -x SIGINT -system sh/exec.sh -n dnode2 -s stop -x SIGINT -system sh/cfg.sh -n dnode1 -c maxTablesPerVnode -v 25 -system sh/cfg.sh -n dnode2 -c maxTablesPerVnode -v 25 -system sh/exec.sh -n dnode1 -s start -system sh/exec.sh -n dnode2 -s start -$x = 0 -step1xx: - $x = $x + 1 - sleep 1000 - if $x == 10 then - return -1 - endi - -sql show mnodes -x step1xx -print mnode1 $data2_1 -print mnode1 $data2_2 -print mnode1 $data2_3 -if $data2_1 != master then - goto step1xx -endi - -sql create table db.t400 using db.st tags(0) -sql create table db.t401 using db.st tags(1) -sql create table db.t402 using db.st tags(2) -sql create table db.t403 using db.st tags(3) -sql create table db.t404 using db.st tags(4) -sql create table db.t405 using db.st tags(5) -sql create table db.t406 using db.st tags(6) -sql create table db.t407 using db.st tags(7) -sql create table db.t408 using db.st tags(8) -sql create table db.t409 using db.st tags(9) -sql create table db.t410 using db.st tags(0) -sql create table db.t411 using db.st tags(1) -sql create table db.t412 using db.st tags(2) -sql create table db.t413 using db.st tags(3) -sql create table db.t414 using db.st tags(4) -sql create table db.t415 using db.st tags(5) -sql create table db.t416 using db.st tags(6) -sql create table db.t417 using db.st tags(7) -sql create table db.t418 using db.st tags(8) -sql create table db.t419 using db.st tags(9) - -sql insert into db.t400 values(now, 1) -sql insert into db.t401 values(now, 1) -sql insert into db.t402 values(now, 1) -sql insert into db.t403 values(now, 1) -sql insert into db.t404 values(now, 1) -sql insert into db.t405 values(now, 1) -sql insert into db.t406 values(now, 1) -sql insert into db.t407 values(now, 1) -sql insert into db.t408 values(now, 1) -sql insert into db.t409 values(now, 1) -sql insert into db.t410 values(now, 1) -sql insert into db.t411 values(now, 1) -sql insert into db.t412 values(now, 1) -sql insert into db.t413 values(now, 1) -sql insert into db.t414 values(now, 1) -sql insert into db.t415 values(now, 1) -sql insert into db.t416 values(now, 1) -sql insert into db.t417 values(now, 1) -sql insert into db.t418 values(now, 1) -sql insert into db.t419 values(now, 1) - -sql show db.tables -if $rows != 100 then - return -1 -endi - -sql reset query cache -sleep 100 - -sql select * from db.t000 -if $rows != 1 then - return -1 -endi - -sql select * from db.t100 -if $rows != 1 then - return -1 -endi - -sql select * from db.t200 -if $rows != 1 then - return -1 -endi - -sql select * from db.t300 -if $rows != 1 then - return -1 -endi - -sql select * from db.t400 -if $rows != 1 then - return -1 -endi - -sql select * from db.st -if $rows != 100 then - return -1 -endi - -system sh/exec.sh -n dnode1 -s stop -x SIGINT -system sh/exec.sh -n dnode2 -s stop -x SIGINT \ No newline at end of file diff --git a/tests/script/tsim/db/alter_tables_v1.sim b/tests/script/tsim/db/alter_tables_v1.sim deleted file mode 100644 index 20c4c73363..0000000000 --- a/tests/script/tsim/db/alter_tables_v1.sim +++ /dev/null @@ -1,436 +0,0 @@ -system sh/stop_dnodes.sh -system sh/deploy.sh -n dnode1 -i 1 -system sh/cfg.sh -n dnode1 -c wallevel -v 0 -system sh/cfg.sh -n dnode1 -c maxVgroupsPerDb -v 1 -system sh/cfg.sh -n dnode1 -c maxTablesPerVnode -v 10 - -system sh/exec.sh -n dnode1 -s start -sql connect - -print ============================ step1 - -sql create database db -sql create table db.st (ts timestamp, i int) tags(t int) -sql create table db.t0 using db.st tags(0) -sql create table db.t1 using db.st tags(1) -sql create table db.t2 using db.st tags(2) -sql create table db.t3 using db.st tags(3) -sql create table db.t4 using db.st tags(4) -sql create table db.t5 using db.st tags(5) -sql create table db.t6 using db.st tags(6) -sql create table db.t7 using db.st tags(7) -sql create table db.t8 using db.st tags(8) -sql create table db.t9 using db.st tags(9) - -sql show db.tables -if $rows != 10 then - return -1 -endi - -sql insert into db.t0 values(now, 1) -sql insert into db.t1 values(now, 1) -sql insert into db.t2 values(now, 1) -sql insert into db.t3 values(now, 1) -sql insert into db.t4 values(now, 1) -sql insert into db.t5 values(now, 1) -sql insert into db.t6 values(now, 1) -sql insert into db.t7 values(now, 1) -sql insert into db.t8 values(now, 1) -sql insert into db.t9 values(now, 1) - -print ============================ step2 -sql_error create table db.t10 using db.st tags(10) -sql show db.tables -if $rows != 10 then - return -1 -endi - -print ============================ step3 - -system sh/exec.sh -n dnode1 -s stop -x SIGINT -system sh/cfg.sh -n dnode1 -c maxTablesPerVnode -v 20 -system sh/exec.sh -n dnode1 -s start -$x = 0 -step2: - $x = $x + 1 - sleep 1000 - if $x == 10 then - return -1 - endi - -sql show mnodes -x step2 -print mnode1 $data2_1 -print mnode1 $data2_2 -print mnode1 $data2_3 -if $data2_1 != master then - goto step2 -endi - -sql create table db.t10 using db.st tags(0) -sql create table db.t11 using db.st tags(1) -sql create table db.t12 using db.st tags(2) -sql create table db.t13 using db.st tags(3) -sql create table db.t14 using db.st tags(4) -sql create table db.t15 using db.st tags(5) -sql create table db.t16 using db.st tags(6) -sql create table db.t17 using db.st tags(7) -sql create table db.t18 using db.st tags(8) -sql create table db.t19 using db.st tags(9) -sql show db.tables -if $rows != 20 then - return -1 -endi - -sql insert into db.t10 values(now, 1) -sql insert into db.t11 values(now, 1) -sql insert into db.t12 values(now, 1) -sql insert into db.t13 values(now, 1) -sql insert into db.t14 values(now, 1) -sql insert into db.t15 values(now, 1) -sql insert into db.t16 values(now, 1) -sql insert into db.t17 values(now, 1) -sql insert into db.t18 values(now, 1) -sql insert into db.t19 values(now, 1) - -print ============================ step4 -sql_error create table db.t20 using db.st tags(10) -sql show db.tables -if $rows != 20 then - return -1 -endi - -print ============================ step5 -system sh/exec.sh -n dnode1 -s stop -x SIGINT -system sh/cfg.sh -n dnode1 -c maxTablesPerVnode -v 30 -system sh/exec.sh -n dnode1 -s start -$x = 0 -step5: - $x = $x + 1 - sleep 1000 - if $x == 10 then - return -1 - endi - -sql show mnodes -x step5 -print mnode1 $data2_1 -print mnode1 $data2_2 -print mnode1 $data2_3 -if $data2_1 != master then - goto step5 -endi - -sql create table db.t20 using db.st tags(0) -sql create table db.t21 using db.st tags(1) -sql create table db.t22 using db.st tags(2) -sql create table db.t23 using db.st tags(3) -sql create table db.t24 using db.st tags(4) -sql create table db.t25 using db.st tags(5) -sql create table db.t26 using db.st tags(6) -sql create table db.t27 using db.st tags(7) -sql create table db.t28 using db.st tags(8) -sql create table db.t29 using db.st tags(9) -sql show db.tables -if $rows != 30 then - return -1 -endi - -sql insert into db.t20 values(now, 1) -sql insert into db.t21 values(now, 1) -sql insert into db.t22 values(now, 1) -sql insert into db.t23 values(now, 1) -sql insert into db.t24 values(now, 1) -sql insert into db.t25 values(now, 1) -sql insert into db.t26 values(now, 1) -sql insert into db.t27 values(now, 1) -sql insert into db.t28 values(now, 1) -sql insert into db.t29 values(now, 1) - -print ============================ step6 - -sql reset query cache -sleep 100 - -sql select * from db.t0 -if $rows != 1 then - return -1 -endi - -sql select * from db.t10 -if $rows != 1 then - return -1 -endi - -sql select * from db.t20 -if $rows != 1 then - return -1 -endi - -sql select * from db.st -if $rows != 30 then - return -1 -endi - -print ============================ step7 -system sh/exec.sh -n dnode1 -s stop -x SIGINT -system sh/exec.sh -n dnode1 -s start -$x = 0 -step7: - $x = $x + 1 - sleep 1000 - if $x == 10 then - return -1 - endi - -sql show mnodes -x step7 -print mnode1 $data2_1 -print mnode1 $data2_2 -print mnode1 $data2_3 -if $data2_1 != master then - goto step7 -endi - -sql reset query cache -sleep 1000 - -sql show db.tables -if $rows != 30 then - return -1 -endi - -sql select * from db.t0 -if $rows != 1 then - return -1 -endi - -sql select * from db.t10 -if $rows != 1 then - return -1 -endi - -sql select * from db.t20 -if $rows != 1 then - return -1 -endi - -sql select * from db.st -if $rows != 30 then - return -1 -endi - -print ============================ step8 -sql_error create table db.t30 using db.st tags(10) -sql show db.tables -if $rows != 30 then - return -1 -endi - -print ============================ step9 -system sh/exec.sh -n dnode1 -s stop -x SIGINT -system sh/cfg.sh -n dnode1 -c maxTablesPerVnode -v 40 -system sh/exec.sh -n dnode1 -s start -$x = 0 -step9: - $x = $x + 1 - sleep 1000 - if $x == 10 then - return -1 - endi - -sql show mnodes -x step9 -print mnode1 $data2_1 -print mnode1 $data2_2 -print mnode1 $data2_3 -if $data2_1 != master then - goto step9 -endi - -sql create table db.t30 using db.st tags(0) -sql create table db.t31 using db.st tags(1) -sql create table db.t32 using db.st tags(2) -sql create table db.t33 using db.st tags(3) -sql create table db.t34 using db.st tags(4) -sql create table db.t35 using db.st tags(5) -sql create table db.t36 using db.st tags(6) -sql create table db.t37 using db.st tags(7) -sql create table db.t38 using db.st tags(8) -sql create table db.t39 using db.st tags(9) - -sql insert into db.t30 values(now, 1) -sql insert into db.t31 values(now, 1) -sql insert into db.t32 values(now, 1) -sql insert into db.t33 values(now, 1) -sql insert into db.t34 values(now, 1) -sql insert into db.t35 values(now, 1) -sql insert into db.t36 values(now, 1) -sql insert into db.t37 values(now, 1) -sql insert into db.t38 values(now, 1) -sql insert into db.t39 values(now, 1) - -sql show db.tables -if $rows != 40 then - return -1 -endi - -sql reset query cache -sleep 1000 - -sql select * from db.t0 -if $rows != 1 then - return -1 -endi - -sql select * from db.t10 -if $rows != 1 then - return -1 -endi - -sql select * from db.t20 -if $rows != 1 then - return -1 -endi - -sql select * from db.t30 -if $rows != 1 then - return -1 -endi - -sql select * from db.st -if $rows != 40 then - return -1 -endi - -print ============================ step10 -system sh/exec.sh -n dnode1 -s stop -x SIGINT -system sh/exec.sh -n dnode1 -s start -$x = 0 -step10: - $x = $x + 1 - sleep 1000 - if $x == 10 then - return -1 - endi - -sql show mnodes -x step10 -print mnode1 $data2_1 -print mnode1 $data2_2 -print mnode1 $data2_3 -if $data2_1 != master then - goto step10 -endi - -sql reset query cache -sleep 1000 - -sql show db.tables -if $rows != 40 then - return -1 -endi - -sql select * from db.t0 -if $rows != 1 then - return -1 -endi - -sql select * from db.t10 -if $rows != 1 then - return -1 -endi - -sql select * from db.t20 -if $rows != 1 then - return -1 -endi - -sql select * from db.st -if $rows != 40 then - return -1 -endi - -print ============================ step11 -sql_error create table db.t40 using db.st tags(10) -sql show db.tables -if $rows != 40 then - return -1 -endi - -print ============================ step12 -system sh/exec.sh -n dnode1 -s stop -x SIGINT -system sh/cfg.sh -n dnode1 -c maxTablesPerVnode -v 50 -system sh/exec.sh -n dnode1 -s start -$x = 0 -step12: - $x = $x + 1 - sleep 1000 - if $x == 10 then - return -1 - endi - -sql show mnodes -x step12 -print mnode1 $data2_1 -print mnode1 $data2_2 -print mnode1 $data2_3 -if $data2_1 != master then - goto step12 -endi - -sql create table db.t40 using db.st tags(0) -sql create table db.t41 using db.st tags(1) -sql create table db.t42 using db.st tags(2) -sql create table db.t43 using db.st tags(3) -sql create table db.t44 using db.st tags(4) -sql create table db.t45 using db.st tags(5) -sql create table db.t46 using db.st tags(6) -sql create table db.t47 using db.st tags(7) -sql create table db.t48 using db.st tags(8) -sql create table db.t49 using db.st tags(9) - -sql insert into db.t40 values(now, 1) -sql insert into db.t41 values(now, 1) -sql insert into db.t42 values(now, 1) -sql insert into db.t43 values(now, 1) -sql insert into db.t44 values(now, 1) -sql insert into db.t45 values(now, 1) -sql insert into db.t46 values(now, 1) -sql insert into db.t47 values(now, 1) -sql insert into db.t48 values(now, 1) -sql insert into db.t49 values(now, 1) - -sql show db.tables -if $rows != 50 then - return -1 -endi - -sql reset query cache -sleep 1000 - -sql select * from db.t0 -if $rows != 1 then - return -1 -endi - -sql select * from db.t10 -if $rows != 1 then - return -1 -endi - -sql select * from db.t20 -if $rows != 1 then - return -1 -endi - -sql select * from db.t30 -if $rows != 1 then - return -1 -endi - -sql select * from db.t40 -if $rows != 1 then - return -1 -endi - -sql select * from db.st -if $rows != 50 then - return -1 -endi - -system sh/exec.sh -n dnode1 -s stop -x SIGINT \ No newline at end of file diff --git a/tests/script/tsim/db/alter_tables_v4.sim b/tests/script/tsim/db/alter_tables_v4.sim deleted file mode 100644 index 10bb4e108b..0000000000 --- a/tests/script/tsim/db/alter_tables_v4.sim +++ /dev/null @@ -1,529 +0,0 @@ -system sh/stop_dnodes.sh -system sh/deploy.sh -n dnode1 -i 1 -system sh/cfg.sh -n dnode1 -c wallevel -v 0 -system sh/cfg.sh -n dnode1 -c maxVgroupsPerDb -v 4 -system sh/cfg.sh -n dnode1 -c maxTablesPerVnode -v 5 - -system sh/exec.sh -n dnode1 -s start -sql connect - -print ============================ step1 - -sql create database db -sql create table db.st (ts timestamp, i int) tags(t int) -sql create table db.t000 using db.st tags(0) -sql create table db.t001 using db.st tags(1) -sql create table db.t002 using db.st tags(2) -sql create table db.t003 using db.st tags(3) -sql create table db.t004 using db.st tags(4) -sql create table db.t005 using db.st tags(5) -sql create table db.t006 using db.st tags(6) -sql create table db.t007 using db.st tags(7) -sql create table db.t008 using db.st tags(8) -sql create table db.t009 using db.st tags(9) -sql create table db.t010 using db.st tags(0) -sql create table db.t011 using db.st tags(1) -sql create table db.t012 using db.st tags(2) -sql create table db.t013 using db.st tags(3) -sql create table db.t014 using db.st tags(4) -sql create table db.t015 using db.st tags(5) -sql create table db.t016 using db.st tags(6) -sql create table db.t017 using db.st tags(7) -sql create table db.t018 using db.st tags(8) -sql create table db.t019 using db.st tags(9) - -sql show db.tables -if $rows != 20 then - return -1 -endi - -sql insert into db.t000 values(now, 1) -sql insert into db.t001 values(now, 1) -sql insert into db.t002 values(now, 1) -sql insert into db.t003 values(now, 1) -sql insert into db.t004 values(now, 1) -sql insert into db.t005 values(now, 1) -sql insert into db.t006 values(now, 1) -sql insert into db.t007 values(now, 1) -sql insert into db.t008 values(now, 1) -sql insert into db.t009 values(now, 1) -sql insert into db.t010 values(now, 1) -sql insert into db.t011 values(now, 1) -sql insert into db.t012 values(now, 1) -sql insert into db.t013 values(now, 1) -sql insert into db.t014 values(now, 1) -sql insert into db.t015 values(now, 1) -sql insert into db.t016 values(now, 1) -sql insert into db.t017 values(now, 1) -sql insert into db.t018 values(now, 1) -sql insert into db.t019 values(now, 1) - -print ============================ step2 -sql_error create table db.t100 using db.st tags(10) -sql show db.tables -if $rows != 20 then - return -1 -endi - -print ============================ step3 -system sh/exec.sh -n dnode1 -s stop -x SIGINT -system sh/cfg.sh -n dnode1 -c maxTablesPerVnode -v 10 -system sh/exec.sh -n dnode1 -s start -$x = 0 -step3: - $x = $x + 1 - sleep 1000 - if $x == 10 then - return -1 - endi - -sql show mnodes -x step3 -print mnode1 $data2_1 -print mnode1 $data2_2 -print mnode1 $data2_3 -if $data2_1 != master then - goto step3 -endi - -sql create table db.t100 using db.st tags(0) -sql create table db.t101 using db.st tags(1) -sql create table db.t102 using db.st tags(2) -sql create table db.t103 using db.st tags(3) -sql create table db.t104 using db.st tags(4) -sql create table db.t105 using db.st tags(5) -sql create table db.t106 using db.st tags(6) -sql create table db.t107 using db.st tags(7) -sql create table db.t108 using db.st tags(8) -sql create table db.t109 using db.st tags(9) -sql create table db.t110 using db.st tags(0) -sql create table db.t111 using db.st tags(1) -sql create table db.t112 using db.st tags(2) -sql create table db.t113 using db.st tags(3) -sql create table db.t114 using db.st tags(4) -sql create table db.t115 using db.st tags(5) -sql create table db.t116 using db.st tags(6) -sql create table db.t117 using db.st tags(7) -sql create table db.t118 using db.st tags(8) -sql create table db.t119 using db.st tags(9) -sql show db.tables -if $rows != 40 then - return -1 -endi - - -sql insert into db.t100 values(now, 1) -sql insert into db.t101 values(now, 1) -sql insert into db.t102 values(now, 1) -sql insert into db.t103 values(now, 1) -sql insert into db.t104 values(now, 1) -sql insert into db.t105 values(now, 1) -sql insert into db.t106 values(now, 1) -sql insert into db.t107 values(now, 1) -sql insert into db.t108 values(now, 1) -sql insert into db.t109 values(now, 1) -sql insert into db.t110 values(now, 1) -sql insert into db.t111 values(now, 1) -sql insert into db.t112 values(now, 1) -sql insert into db.t113 values(now, 1) -sql insert into db.t114 values(now, 1) -sql insert into db.t115 values(now, 1) -sql insert into db.t116 values(now, 1) -sql insert into db.t117 values(now, 1) -sql insert into db.t118 values(now, 1) -sql insert into db.t119 values(now, 1) - -print ============================ step4 -sql_error create table db.t200 using db.st tags(10) -sql show db.tables -if $rows != 40 then - return -1 -endi - -print ============================ step5 -system sh/exec.sh -n dnode1 -s stop -x SIGINT -system sh/cfg.sh -n dnode1 -c maxTablesPerVnode -v 15 -system sh/exec.sh -n dnode1 -s start -$x = 0 -step5: - $x = $x + 1 - sleep 1000 - if $x == 10 then - return -1 - endi - -sql show mnodes -x step5 -print mnode1 $data2_1 -print mnode1 $data2_2 -print mnode1 $data2_3 -if $data2_1 != master then - goto step5 -endi - -sql create table db.t200 using db.st tags(0) -sql create table db.t201 using db.st tags(1) -sql create table db.t202 using db.st tags(2) -sql create table db.t203 using db.st tags(3) -sql create table db.t204 using db.st tags(4) -sql create table db.t205 using db.st tags(5) -sql create table db.t206 using db.st tags(6) -sql create table db.t207 using db.st tags(7) -sql create table db.t208 using db.st tags(8) -sql create table db.t209 using db.st tags(9) -sql create table db.t210 using db.st tags(0) -sql create table db.t211 using db.st tags(1) -sql create table db.t212 using db.st tags(2) -sql create table db.t213 using db.st tags(3) -sql create table db.t214 using db.st tags(4) -sql create table db.t215 using db.st tags(5) -sql create table db.t216 using db.st tags(6) -sql create table db.t217 using db.st tags(7) -sql create table db.t218 using db.st tags(8) -sql create table db.t219 using db.st tags(9) -sql show db.tables -if $rows != 60 then - return -1 -endi - -sql insert into db.t200 values(now, 1) -sql insert into db.t201 values(now, 1) -sql insert into db.t202 values(now, 1) -sql insert into db.t203 values(now, 1) -sql insert into db.t204 values(now, 1) -sql insert into db.t205 values(now, 1) -sql insert into db.t206 values(now, 1) -sql insert into db.t207 values(now, 1) -sql insert into db.t208 values(now, 1) -sql insert into db.t209 values(now, 1) -sql insert into db.t210 values(now, 1) -sql insert into db.t211 values(now, 1) -sql insert into db.t212 values(now, 1) -sql insert into db.t213 values(now, 1) -sql insert into db.t214 values(now, 1) -sql insert into db.t215 values(now, 1) -sql insert into db.t216 values(now, 1) -sql insert into db.t217 values(now, 1) -sql insert into db.t218 values(now, 1) -sql insert into db.t219 values(now, 1) - -print ============================ step6 - -sql reset query cache -sleep 100 - -sql select * from db.t000 -if $rows != 1 then - return -1 -endi - -sql select * from db.t100 -if $rows != 1 then - return -1 -endi - -sql select * from db.t200 -if $rows != 1 then - return -1 -endi - -sql select * from db.st -if $rows != 60 then - return -1 -endi - -print ============================ step7 -system sh/exec.sh -n dnode1 -s stop -x SIGINT -sleep 3000 -system sh/exec.sh -n dnode1 -s start -sleep 3000 - -sql reset query cache -sleep 1000 - -sql show db.tables -if $rows != 60 then - return -1 -endi - -sql select * from db.t000 -if $rows != 1 then - return -1 -endi - -sql select * from db.t100 -if $rows != 1 then - return -1 -endi - -sql select * from db.t200 -if $rows != 1 then - return -1 -endi - -sql select * from db.st -if $rows != 60 then - return -1 -endi - -print ============================ step8 -sql_error create table db.t300 using db.st tags(10) -sql show db.tables -if $rows != 60 then - return -1 -endi - -print ============================ step9 -system sh/exec.sh -n dnode1 -s stop -x SIGINT -system sh/cfg.sh -n dnode1 -c maxTablesPerVnode -v 20 -system sh/exec.sh -n dnode1 -s start -$x = 0 -step9: - $x = $x + 1 - sleep 1000 - if $x == 10 then - return -1 - endi - -sql show mnodes -x step9 -print mnode1 $data2_1 -print mnode1 $data2_2 -print mnode1 $data2_3 -if $data2_1 != master then - goto step9 -endi - -sql create table db.t300 using db.st tags(0) -sql create table db.t301 using db.st tags(1) -sql create table db.t302 using db.st tags(2) -sql create table db.t303 using db.st tags(3) -sql create table db.t304 using db.st tags(4) -sql create table db.t305 using db.st tags(5) -sql create table db.t306 using db.st tags(6) -sql create table db.t307 using db.st tags(7) -sql create table db.t308 using db.st tags(8) -sql create table db.t309 using db.st tags(9) -sql create table db.t310 using db.st tags(0) -sql create table db.t311 using db.st tags(1) -sql create table db.t312 using db.st tags(2) -sql create table db.t313 using db.st tags(3) -sql create table db.t314 using db.st tags(4) -sql create table db.t315 using db.st tags(5) -sql create table db.t316 using db.st tags(6) -sql create table db.t317 using db.st tags(7) -sql create table db.t318 using db.st tags(8) -sql create table db.t319 using db.st tags(9) - -sql insert into db.t300 values(now, 1) -sql insert into db.t301 values(now, 1) -sql insert into db.t302 values(now, 1) -sql insert into db.t303 values(now, 1) -sql insert into db.t304 values(now, 1) -sql insert into db.t305 values(now, 1) -sql insert into db.t306 values(now, 1) -sql insert into db.t307 values(now, 1) -sql insert into db.t308 values(now, 1) -sql insert into db.t309 values(now, 1) -sql insert into db.t310 values(now, 1) -sql insert into db.t311 values(now, 1) -sql insert into db.t312 values(now, 1) -sql insert into db.t313 values(now, 1) -sql insert into db.t314 values(now, 1) -sql insert into db.t315 values(now, 1) -sql insert into db.t316 values(now, 1) -sql insert into db.t317 values(now, 1) -sql insert into db.t318 values(now, 1) -sql insert into db.t319 values(now, 1) - -sql show db.tables -if $rows != 80 then - return -1 -endi - -sql reset query cache -sleep 1000 - -sql select * from db.t000 -if $rows != 1 then - return -1 -endi - -sql select * from db.t100 -if $rows != 1 then - return -1 -endi - -sql select * from db.t200 -if $rows != 1 then - return -1 -endi - -sql select * from db.t300 -if $rows != 1 then - return -1 -endi - -sql select * from db.st -if $rows != 80 then - return -1 -endi - -print ============================ step10 -system sh/exec.sh -n dnode1 -s stop -x SIGINT -system sh/exec.sh -n dnode1 -s start -$x = 0 -step10: - $x = $x + 1 - sleep 1000 - if $x == 10 then - return -1 - endi - -sql show mnodes -x step10 -print mnode1 $data2_1 -print mnode1 $data2_2 -print mnode1 $data2_3 -if $data2_1 != master then - goto step10 -endi - -sql reset query cache -sleep 1000 - -sql show db.tables -if $rows != 80 then - return -1 -endi - -sql select * from db.t000 -if $rows != 1 then - return -1 -endi - -sql select * from db.t100 -if $rows != 1 then - return -1 -endi - -sql select * from db.t200 -if $rows != 1 then - return -1 -endi - -sql select * from db.t300 -if $rows != 1 then - return -1 -endi - -sql select * from db.st -if $rows != 80 then - return -1 -endi - -print ============================ step11 -sql_error create table db.t400 using db.st tags(10) -sql show db.tables -if $rows != 80 then - return -1 -endi - -print ============================ step12 -system sh/exec.sh -n dnode1 -s stop -x SIGINT -system sh/cfg.sh -n dnode1 -c maxTablesPerVnode -v 25 -system sh/exec.sh -n dnode1 -s start -$x = 0 -step12: - $x = $x + 1 - sleep 1000 - if $x == 10 then - return -1 - endi - -sql show mnodes -x step12 -print mnode1 $data2_1 -print mnode1 $data2_2 -print mnode1 $data2_3 -if $data2_1 != master then - goto step12 -endi - - -sql create table db.t400 using db.st tags(0) -sql create table db.t401 using db.st tags(1) -sql create table db.t402 using db.st tags(2) -sql create table db.t403 using db.st tags(3) -sql create table db.t404 using db.st tags(4) -sql create table db.t405 using db.st tags(5) -sql create table db.t406 using db.st tags(6) -sql create table db.t407 using db.st tags(7) -sql create table db.t408 using db.st tags(8) -sql create table db.t409 using db.st tags(9) -sql create table db.t410 using db.st tags(0) -sql create table db.t411 using db.st tags(1) -sql create table db.t412 using db.st tags(2) -sql create table db.t413 using db.st tags(3) -sql create table db.t414 using db.st tags(4) -sql create table db.t415 using db.st tags(5) -sql create table db.t416 using db.st tags(6) -sql create table db.t417 using db.st tags(7) -sql create table db.t418 using db.st tags(8) -sql create table db.t419 using db.st tags(9) - -sql insert into db.t400 values(now, 1) -sql insert into db.t401 values(now, 1) -sql insert into db.t402 values(now, 1) -sql insert into db.t403 values(now, 1) -sql insert into db.t404 values(now, 1) -sql insert into db.t405 values(now, 1) -sql insert into db.t406 values(now, 1) -sql insert into db.t407 values(now, 1) -sql insert into db.t408 values(now, 1) -sql insert into db.t409 values(now, 1) -sql insert into db.t410 values(now, 1) -sql insert into db.t411 values(now, 1) -sql insert into db.t412 values(now, 1) -sql insert into db.t413 values(now, 1) -sql insert into db.t414 values(now, 1) -sql insert into db.t415 values(now, 1) -sql insert into db.t416 values(now, 1) -sql insert into db.t417 values(now, 1) -sql insert into db.t418 values(now, 1) -sql insert into db.t419 values(now, 1) - -sql show db.tables -if $rows != 100 then - return -1 -endi - -sql reset query cache -sleep 1000 - -sql select * from db.t000 -if $rows != 1 then - return -1 -endi - -sql select * from db.t100 -if $rows != 1 then - return -1 -endi - -sql select * from db.t200 -if $rows != 1 then - return -1 -endi - -sql select * from db.t300 -if $rows != 1 then - return -1 -endi - -sql select * from db.t400 -if $rows != 1 then - return -1 -endi - -sql select * from db.st -if $rows != 100 then - return -1 -endi - -system sh/exec.sh -n dnode1 -s stop -x SIGINT \ No newline at end of file diff --git a/tests/script/tsim/db/alter_vgroups.sim b/tests/script/tsim/db/alter_vgroups.sim deleted file mode 100644 index 81ffc7d443..0000000000 --- a/tests/script/tsim/db/alter_vgroups.sim +++ /dev/null @@ -1,210 +0,0 @@ -system sh/stop_dnodes.sh -system sh/deploy.sh -n dnode1 -i 1 -system sh/cfg.sh -n dnode1 -c wallevel -v 0 -system sh/cfg.sh -n dnode1 -c maxVgroupsPerDb -v 1 -system sh/cfg.sh -n dnode1 -c maxTablesPerVnode -v 20 - -system sh/exec.sh -n dnode1 -s start - -sleep 2000 -sql connect - -print ============================ step1 - -sql create database db -sql create table db.st (ts timestamp, i int) tags(t int) -sql create table db.t000 using db.st tags(0) -sql create table db.t001 using db.st tags(1) -sql create table db.t002 using db.st tags(2) -sql create table db.t003 using db.st tags(3) -sql create table db.t004 using db.st tags(4) -sql create table db.t005 using db.st tags(5) -sql create table db.t006 using db.st tags(6) -sql create table db.t007 using db.st tags(7) -sql create table db.t008 using db.st tags(8) -sql create table db.t009 using db.st tags(9) -sql create table db.t010 using db.st tags(0) -sql create table db.t011 using db.st tags(1) -sql create table db.t012 using db.st tags(2) -sql create table db.t013 using db.st tags(3) -sql create table db.t014 using db.st tags(4) -sql create table db.t015 using db.st tags(5) -sql create table db.t016 using db.st tags(6) -sql create table db.t017 using db.st tags(7) -sql create table db.t018 using db.st tags(8) -sql create table db.t019 using db.st tags(9) - -sql show db.tables -if $rows != 20 then - return -1 -endi - -sql insert into db.t000 values(now, 1) -sql insert into db.t001 values(now, 1) -sql insert into db.t002 values(now, 1) -sql insert into db.t003 values(now, 1) -sql insert into db.t004 values(now, 1) -sql insert into db.t005 values(now, 1) -sql insert into db.t006 values(now, 1) -sql insert into db.t007 values(now, 1) -sql insert into db.t008 values(now, 1) -sql insert into db.t009 values(now, 1) -sql insert into db.t010 values(now, 1) -sql insert into db.t011 values(now, 1) -sql insert into db.t012 values(now, 1) -sql insert into db.t013 values(now, 1) -sql insert into db.t014 values(now, 1) -sql insert into db.t015 values(now, 1) -sql insert into db.t016 values(now, 1) -sql insert into db.t017 values(now, 1) -sql insert into db.t018 values(now, 1) -sql insert into db.t019 values(now, 1) - -print ============================ step2 -sql_error create table db.t100 using db.st tags(10) -sql show db.tables -if $rows != 20 then - return -1 -endi - -print ============================ step3 -system sh/exec.sh -n dnode1 -s stop -x SIGINT -system sh/cfg.sh -n dnode1 -c maxVgroupsPerDb -v 2 -sleep 3000 -system sh/exec.sh -n dnode1 -s start -sleep 3000 - -sql create table db.t100 using db.st tags(0) -sql create table db.t101 using db.st tags(1) -sql create table db.t102 using db.st tags(2) -sql create table db.t103 using db.st tags(3) -sql create table db.t104 using db.st tags(4) -sql create table db.t105 using db.st tags(5) -sql create table db.t106 using db.st tags(6) -sql create table db.t107 using db.st tags(7) -sql create table db.t108 using db.st tags(8) -sql create table db.t109 using db.st tags(9) -sql create table db.t110 using db.st tags(0) -sql create table db.t111 using db.st tags(1) -sql create table db.t112 using db.st tags(2) -sql create table db.t113 using db.st tags(3) -sql create table db.t114 using db.st tags(4) -sql create table db.t115 using db.st tags(5) -sql create table db.t116 using db.st tags(6) -sql create table db.t117 using db.st tags(7) -sql create table db.t118 using db.st tags(8) -sql create table db.t119 using db.st tags(9) -sql show db.tables -if $rows != 40 then - return -1 -endi - - -sql insert into db.t100 values(now, 1) -sql insert into db.t101 values(now, 1) -sql insert into db.t102 values(now, 1) -sql insert into db.t103 values(now, 1) -sql insert into db.t104 values(now, 1) -sql insert into db.t105 values(now, 1) -sql insert into db.t106 values(now, 1) -sql insert into db.t107 values(now, 1) -sql insert into db.t108 values(now, 1) -sql insert into db.t109 values(now, 1) -sql insert into db.t110 values(now, 1) -sql insert into db.t111 values(now, 1) -sql insert into db.t112 values(now, 1) -sql insert into db.t113 values(now, 1) -sql insert into db.t114 values(now, 1) -sql insert into db.t115 values(now, 1) -sql insert into db.t116 values(now, 1) -sql insert into db.t117 values(now, 1) -sql insert into db.t118 values(now, 1) -sql insert into db.t119 values(now, 1) - -print ============================ step4 -sql_error create table db.t200 using db.st tags(10) -sql show db.tables -if $rows != 40 then - return -1 -endi - -print ============================ step5 - -system sh/exec.sh -n dnode1 -s stop -x SIGINT -system sh/cfg.sh -n dnode1 -c maxVgroupsPerDb -v 3 -sleep 3000 -system sh/exec.sh -n dnode1 -s start -sleep 3000 - -sql create table db.t200 using db.st tags(0) -sql create table db.t201 using db.st tags(1) -sql create table db.t202 using db.st tags(2) -sql create table db.t203 using db.st tags(3) -sql create table db.t204 using db.st tags(4) -sql create table db.t205 using db.st tags(5) -sql create table db.t206 using db.st tags(6) -sql create table db.t207 using db.st tags(7) -sql create table db.t208 using db.st tags(8) -sql create table db.t209 using db.st tags(9) -sql create table db.t210 using db.st tags(0) -sql create table db.t211 using db.st tags(1) -sql create table db.t212 using db.st tags(2) -sql create table db.t213 using db.st tags(3) -sql create table db.t214 using db.st tags(4) -sql create table db.t215 using db.st tags(5) -sql create table db.t216 using db.st tags(6) -sql create table db.t217 using db.st tags(7) -sql create table db.t218 using db.st tags(8) -sql create table db.t219 using db.st tags(9) -sql show db.tables -if $rows != 60 then - return -1 -endi - -sql insert into db.t200 values(now, 1) -sql insert into db.t201 values(now, 1) -sql insert into db.t202 values(now, 1) -sql insert into db.t203 values(now, 1) -sql insert into db.t204 values(now, 1) -sql insert into db.t205 values(now, 1) -sql insert into db.t206 values(now, 1) -sql insert into db.t207 values(now, 1) -sql insert into db.t208 values(now, 1) -sql insert into db.t209 values(now, 1) -sql insert into db.t210 values(now, 1) -sql insert into db.t211 values(now, 1) -sql insert into db.t212 values(now, 1) -sql insert into db.t213 values(now, 1) -sql insert into db.t214 values(now, 1) -sql insert into db.t215 values(now, 1) -sql insert into db.t216 values(now, 1) -sql insert into db.t217 values(now, 1) -sql insert into db.t218 values(now, 1) -sql insert into db.t219 values(now, 1) - -print ============================ step6 - -sql reset query cache -sleep 1000 - -sql select * from db.t000 -if $rows != 1 then - return -1 -endi - -sql select * from db.t100 -if $rows != 1 then - return -1 -endi - -sql select * from db.t200 -if $rows != 1 then - return -1 -endi - -sql select * from db.st -if $rows != 60 then - return -1 -endi - -system sh/exec.sh -n dnode1 -s stop -x SIGINT \ No newline at end of file diff --git a/tests/script/tsim/db/basic4.sim b/tests/script/tsim/db/basic4.sim index ce6d352d12..0d1db9dd19 100644 --- a/tests/script/tsim/db/basic4.sim +++ b/tests/script/tsim/db/basic4.sim @@ -1,30 +1,29 @@ system sh/stop_dnodes.sh system sh/deploy.sh -n dnode1 -i 1 system sh/exec.sh -n dnode1 -s start -sleep 2000 sql connect print =============== create database d1 -sql create database d1 +sql create database d1 vgroups 1 sql create table d1.t1 (ts timestamp, i int); sql create table d1.t2 (ts timestamp, i int); sql create table d1.t3 (ts timestamp, i int); sql create table d1.t4 (ts timestamp, i int); sql show databases -if $rows != 1 then +if $rows != 3 then return -1 endi -if $data00 != d1 then +if $data20 != d1 then return -1 endi -if $data02 != 4 then +if $data22 != 1 then return -1 endi -if $data03 != 1 then +if $data24 != 1 then return -1 endi @@ -40,7 +39,7 @@ endi if $data00 != 2 then return -1 endi -if $data01 != 4 then +if $data01 != d1 then return -1 endi @@ -48,19 +47,19 @@ print =============== drop table sql drop table d1.t1 sql show databases -if $rows != 1 then +if $rows != 3 then return -1 endi -if $data00 != d1 then +if $data20 != d1 then return -1 endi -if $data02 != 3 then +if $data22 != 1 then return -1 endi -if $data03 != 1 then +if $data24 != 1 then return -1 endi @@ -76,29 +75,28 @@ endi if $data00 != 2 then return -1 endi -if $data01 != 3 then +if $data01 != d1 then return -1 endi - print =============== drop all table sql drop table d1.t2 sql drop table d1.t3 sql drop table d1.t4 sql show databases -if $rows != 1 then +if $rows != 3 then return -1 endi -if $data00 != d1 then +if $data20 != d1 then return -1 endi -if $data02 != 0 then +if $data22 != 1 then return -1 endi -if $data03 != 0 then +if $data24 != 1 then return -1 endi @@ -108,7 +106,13 @@ if $rows != 0 then endi sql show d1.vgroups -if $rows != 0 then +if $rows != 1 then + return -1 +endi +if $data00 != 2 then + return -1 +endi +if $data01 != d1 then return -1 endi diff --git a/tests/script/tsim/db/basic5.sim b/tests/script/tsim/db/basic5.sim index 08c9db2332..9b809c35f0 100644 --- a/tests/script/tsim/db/basic5.sim +++ b/tests/script/tsim/db/basic5.sim @@ -1,57 +1,47 @@ system sh/stop_dnodes.sh system sh/deploy.sh -n dnode1 -i 1 system sh/exec.sh -n dnode1 -s start -sleep 2000 sql connect print =============== create database d1 -sql create database d1 -sql create table d1.t1 (ts timestamp, i int); -sql create table d1.t2 (ts timestamp, i int); -sql create table d1.t3 (ts timestamp, i int); -sql create table d1.t4 (ts timestamp, i int); +sql create database db1 vgroups 1; +sql use db1; -sql show databases +print =============== create stable and table +sql create stable st1 (ts timestamp, f1 int) tags(t1 int); +sql create table tb1 using st1 tags(1); +sql insert into tb1 values (now, 1); + +sql show stables if $rows != 1 then + print $rows return -1 endi -if $data00 != d1 then +sql show tables +if $rows != 1 then return -1 endi -if $data02 != 4 then - return -1 -endi +print =============== drop db +sql drop database db1; -if $data03 != 1 then - return -1 -endi +sql_error show stables +sql_error show tables -sql show d1.tables -if $rows != 4 then - return -1 -endi +print =============== re-create db and stb +sql create database db1; +sql use db1; +sql create stable st1 (ts timestamp, f1 int) tags(t1 int) -sql show d1.vgroups +sql show stables if $rows != 1 then return -1 endi -if $data00 != 2 then - return -1 -endi -if $data01 != 4 then - return -1 -endi - -print =============== drop database -sql drop database d1 -sql show databases +sql show tables if $rows != 0 then return -1 endi -sql_error show d1.vgroups - -system sh/exec.sh -n dnode1 -s stop -x SIGINT \ No newline at end of file +system sh/exec.sh -n dnode1 -s stop -x SIGINT diff --git a/tests/script/tsim/db/basic7.sim b/tests/script/tsim/db/basic7.sim deleted file mode 100644 index 9b809c35f0..0000000000 --- a/tests/script/tsim/db/basic7.sim +++ /dev/null @@ -1,47 +0,0 @@ -system sh/stop_dnodes.sh -system sh/deploy.sh -n dnode1 -i 1 -system sh/exec.sh -n dnode1 -s start -sql connect - -print =============== create database d1 -sql create database db1 vgroups 1; -sql use db1; - -print =============== create stable and table -sql create stable st1 (ts timestamp, f1 int) tags(t1 int); -sql create table tb1 using st1 tags(1); -sql insert into tb1 values (now, 1); - -sql show stables -if $rows != 1 then - print $rows - return -1 -endi - -sql show tables -if $rows != 1 then - return -1 -endi - -print =============== drop db -sql drop database db1; - -sql_error show stables -sql_error show tables - -print =============== re-create db and stb -sql create database db1; -sql use db1; -sql create stable st1 (ts timestamp, f1 int) tags(t1 int) - -sql show stables -if $rows != 1 then - return -1 -endi - -sql show tables -if $rows != 0 then - return -1 -endi - -system sh/exec.sh -n dnode1 -s stop -x SIGINT diff --git a/tests/script/tsim/db/keep.sim b/tests/script/tsim/db/keep.sim index 626040e347..027530026c 100644 --- a/tests/script/tsim/db/keep.sim +++ b/tests/script/tsim/db/keep.sim @@ -1,29 +1,39 @@ system sh/stop_dnodes.sh - - - system sh/deploy.sh -n dnode1 -i 1 system sh/deploy.sh -n dnode2 -i 2 system sh/deploy.sh -n dnode3 -i 3 - -system sh/cfg.sh -n dnode1 -c walLevel -v 1 -system sh/cfg.sh -n dnode2 -c walLevel -v 1 -system sh/cfg.sh -n dnode3 -c walLevel -v 1 -system sh/cfg.sh -n dnode1 -c numOfMnodes -v 1 -system sh/cfg.sh -n dnode2 -c numOfMnodes -v 1 -system sh/cfg.sh -n dnode3 -c numOfMnodes -v 1 -system sh/cfg.sh -n dnode1 -c mnodeEqualVnodeNum -v 4 -system sh/cfg.sh -n dnode2 -c mnodeEqualVnodeNum -v 4 -system sh/cfg.sh -n dnode3 -c mnodeEqualVnodeNum -v 4 - -print ========= start dnode1 as master +system sh/deploy.sh -n dnode4 -i 4 +system sh/cfg.sh -n dnode1 -c transPullupInterval -v 1 +system sh/cfg.sh -n dnode2 -c transPullupInterval -v 1 +system sh/cfg.sh -n dnode3 -c transPullupInterval -v 1 +system sh/cfg.sh -n dnode4 -c transPullupInterval -v 1 system sh/exec.sh -n dnode1 -s start +system sh/exec.sh -n dnode2 -s start sql connect -print ========= start other dnodes -sql create dnode $hostname2 -system sh/exec.sh -n dnode2 -s start -sleep 2000 +print =============== step1 create dnode2 +sql create dnode $hostname port 7200 + +$x = 0 +step1: + $x = $x + 1 + sleep 1000 + if $x == 10 then + print ====> dnode not ready! + return -1 + endi +sql show dnodes +print ===> $data00 $data01 $data02 $data03 $data04 $data05 +print ===> $data10 $data11 $data12 $data13 $data14 $data15 +if $rows != 2 then + return -1 +endi +if $data(1)[4] != ready then + goto step1 +endi +if $data(2)[4] != ready then + goto step1 +endi print ======== step1 create db sql create database keepdb replica 1 keep 30 duration 7 @@ -33,7 +43,8 @@ sql create table tb (ts timestamp, i int) $x = 1 while $x < 41 $time = $x . d - sql insert into tb values (now + $time , $x ) + sql insert into tb values (now + $time , $x ) -x step2 + step2: $x = $x + 1 endw @@ -41,18 +52,13 @@ sql select * from tb print ===> rows $rows print ===> last $data01 -if $rows != 40 then - return -1 -endi -if $data01 != 40 then +if $rows >= 40 then return -1 endi print ======== step2 stop dnode system sh/exec.sh -n dnode2 -s stop -x SIGINT -sleep 3000 system sh/exec.sh -n dnode2 -s start -sleep 3000 sql select * from tb print ===> rows $rows @@ -64,15 +70,13 @@ endi if $rows <= 20 then return -1 endi -if $data01 != 40 then - return -1 -endi $num1 = $rows + 40 print ======== step3 alter db sql alter database keepdb keep 60 -sleep 1000 +flush database keepdb + sql show databases print $data00 $data01 $data02 $data03 $data04 $data05 $data06 $data07 if $data02 != 1 then @@ -112,9 +116,7 @@ endi print ======== step5 stop dnode system sh/exec.sh -n dnode2 -s stop -x SIGINT -sleep 3000 system sh/exec.sh -n dnode2 -s start -sleep 3000 sql select * from tb print ===> rows $rows diff --git a/tests/script/tsim/db/len.sim b/tests/script/tsim/db/len.sim index 8c08d2b09a..212fdfd40d 100644 --- a/tests/script/tsim/db/len.sim +++ b/tests/script/tsim/db/len.sim @@ -1,12 +1,6 @@ system sh/stop_dnodes.sh - - system sh/deploy.sh -n dnode1 -i 1 -system sh/cfg.sh -n dnode1 -c walLevel -v 1 -system sh/cfg.sh -n dnode1 -c maxtablesPerVnode -v 2000 - system sh/exec.sh -n dnode1 -s start -sleep 2000 sql connect print =============== step1 @@ -17,33 +11,33 @@ sql create database -x step1 step1: sql show databases -if $rows != 0 then +if $rows != 2 then return -1 endi print =============== step2 sql create database a sql show databases -if $rows != 1 then +if $rows != 3 then return -1 endi sql drop database a sql show databases -if $rows != 0 then +if $rows != 2 then return -1 endi print =============== step3 sql create database a12345678 sql show databases -if $rows != 1 then +if $rows != 3 then return -1 endi sql drop database a12345678 sql show databases -if $rows != 0 then +if $rows != 2 then return -1 endi @@ -52,7 +46,7 @@ sql create database a012345678901201234567890120123456789012a0123456789012012345 return -1 step4: sql show databases -if $rows != 0 then +if $rows != 2 then return -1 endi @@ -60,7 +54,7 @@ print =============== step5 sql create database a;1 sql drop database a sql show databases -if $rows != 0 then +if $rows != 2 then return -1 endi @@ -70,7 +64,7 @@ sql create database a'1 -x step6 step6: sql show databases -if $rows != 0 then +if $rows != 2 then return -1 endi @@ -79,7 +73,7 @@ sql create database (a) -x step7 return -1 step7: sql show databases -if $rows != 0 then +if $rows != 2 then return -1 endi @@ -88,7 +82,7 @@ sql create database a.1 -x step8 return -1 step8: sql show databases -if $rows != 0 then +if $rows != 2 then return -1 endi diff --git a/tests/script/tsim/db/nosuchfile.sim b/tests/script/tsim/db/nosuchfile.sim deleted file mode 100644 index 69db8c0dc5..0000000000 --- a/tests/script/tsim/db/nosuchfile.sim +++ /dev/null @@ -1,66 +0,0 @@ -system sh/stop_dnodes.sh - -system sh/deploy.sh -n dnode1 -i 1 -system sh/cfg.sh -n dnode1 -c wallevel -v 2 - -print ========== step1 -system sh/exec.sh -n dnode1 -s start -sql connect -sleep 2000 - -print ========== step3 -sql create database d1 -sql create table d1.t1 (t timestamp, i int) -sql insert into d1.t1 values(now+1s, 35) -sql insert into d1.t1 values(now+2s, 34) -sql insert into d1.t1 values(now+3s, 33) -sql insert into d1.t1 values(now+4s, 32) -sql insert into d1.t1 values(now+5s, 31) - -print ========== step4 -system sh/exec.sh -n dnode1 -s stop -x SIGINT -system sh/exec.sh -n dnode1 -s start -sleep 2000 - -print ========== step5 -sql select * from d1.t1 order by t desc -print $data01 $data11 $data21 $data31 $data41 -if $data01 != 31 then - return -1 -endi -if $data11 != 32 then - return -1 -endi -if $data21 != 33 then - return -1 -endi -if $data31 != 34 then - return -1 -endi -if $data41 != 35 then - return -1 -endi - -print ========== step6 -system_content rm -rf ../../../sim/dnode1/data/vnode/vnode2/tsdb/data - -print ========== step7 -sql select * from d1.t1 order by t desc -print $data01 $data11 $data21 $data31 $data41 -if $data01 != null then - return -1 -endi -if $data11 != null then - return -1 -endi -if $data21 != null then - return -1 -endi -if $data31 != null then - return -1 -endi -if $data41 != null then - return -1 -endi - -system sh/exec.sh -n dnode1 -s stop -x SIGINT \ No newline at end of file diff --git a/tests/script/tsim/db/repeat.sim b/tests/script/tsim/db/repeat.sim index b3bbca2d19..98d66244f5 100644 --- a/tests/script/tsim/db/repeat.sim +++ b/tests/script/tsim/db/repeat.sim @@ -1,12 +1,8 @@ system sh/stop_dnodes.sh system sh/deploy.sh -n dnode1 -i 1 -system sh/cfg.sh -n dnode1 -c wallevel -v 0 -system sh/cfg.sh -n dnode1 -c maxtablesPerVnode -v 4 - system sh/exec.sh -n dnode1 -s start - -sleep 2000 sql connect + print ============================ dnode1 start sql create database d1 @@ -21,13 +17,10 @@ sql create table d3.t1(ts timestamp, i int) sql create database d4 sql create table d4.t1(ts timestamp, i int) -sleep 2000 - sql drop database d1 sql drop database d2 sql drop database d3 sql drop database d4 -sleep 2000 sql create database d5 sql create table d5.t1(ts timestamp, i int) @@ -41,15 +34,11 @@ sql create table d7.t1(ts timestamp, i int) sql create database d8 sql create table d8.t1(ts timestamp, i int) -sleep 2000 - sql drop database d5 sql drop database d6 sql drop database d7 sql drop database d8 -sleep 2000 - sql create database d9; sql create table d9.t1(ts timestamp, i int) diff --git a/tests/script/tsim/db/show_create_db.sim b/tests/script/tsim/db/show_create_db.sim index f2e8011a0e..45007d01d6 100644 --- a/tests/script/tsim/db/show_create_db.sim +++ b/tests/script/tsim/db/show_create_db.sim @@ -1,10 +1,6 @@ system sh/stop_dnodes.sh - system sh/deploy.sh -n dnode1 -i 1 -system sh/cfg.sh -n dnode1 -c walLevel -v 1 - system sh/exec.sh -n dnode1 -s start -sleep 2000 sql connect print =============== step2 diff --git a/tests/script/tsim/db/show_create_table.sim b/tests/script/tsim/db/show_create_table.sim index 5f2ae61343..44fa09577e 100644 --- a/tests/script/tsim/db/show_create_table.sim +++ b/tests/script/tsim/db/show_create_table.sim @@ -1,10 +1,6 @@ system sh/stop_dnodes.sh - system sh/deploy.sh -n dnode1 -i 1 -system sh/cfg.sh -n dnode1 -c walLevel -v 1 - system sh/exec.sh -n dnode1 -s start -sleep 2000 sql connect print ===============create three type table diff --git a/tests/script/tsim/db/tables.sim b/tests/script/tsim/db/tables.sim index b32fae25e0..23cb0c6163 100644 --- a/tests/script/tsim/db/tables.sim +++ b/tests/script/tsim/db/tables.sim @@ -1,12 +1,6 @@ system sh/stop_dnodes.sh - system sh/deploy.sh -n dnode1 -i 1 -system sh/cfg.sh -n dnode1 -c walLevel -v 1 -system sh/cfg.sh -n dnode2 -c maxVgroupsPerDb -v 4 -system sh/cfg.sh -n dnode1 -c maxTablesPerVnode -v 4 - system sh/exec.sh -n dnode1 -s start -sleep 2000 sql connect print =============== step2 @@ -14,7 +8,7 @@ sql create database db sql show databases print $rows $data07 -if $rows != 1 then +if $rows != 3 then return -1 endi @@ -71,14 +65,13 @@ endi print =============== step6 sql drop database db sql reset query cache -sleep 4000 print =============== step7 sql create database db sql show databases print $rows $data07 -if $rows != 1 then +if $rows != 3 then return -1 endi diff --git a/tests/script/tsim/db/testSuite.sim b/tests/script/tsim/db/testSuite.sim deleted file mode 100644 index 87863001a3..0000000000 --- a/tests/script/tsim/db/testSuite.sim +++ /dev/null @@ -1,16 +0,0 @@ -run general/db/basic.sim -run general/db/basic1.sim -run general/db/basic2.sim -run general/db/basic3.sim -run general/db/basic4.sim -run general/db/basic5.sim -run general/db/delete_reuse1.sim -run general/db/delete_reuse2.sim -run general/db/delete_reusevnode.sim -run general/db/delete_reusevnode2.sim -run general/db/delete_writing1.sim -run general/db/delete_writing2.sim -run general/db/len.sim -run general/db/repeat.sim -run general/db/tables.sim -run general/db/vnodes.sim diff --git a/tests/script/tsim/db/topic1.sim b/tests/script/tsim/db/topic1.sim deleted file mode 100644 index b5058e8f9b..0000000000 --- a/tests/script/tsim/db/topic1.sim +++ /dev/null @@ -1,857 +0,0 @@ -system sh/stop_dnodes.sh -system sh/deploy.sh -n dnode1 -i 1 - -system sh/cfg.sh -n dnode1 -c maxVgroupsPerDb -v 100 -system sh/cfg.sh -n dnode1 -c partitions -v 4 -system sh/exec.sh -n dnode1 -s start - -sleep 2000 -sql connect - -print ====step1 create with default para -sql create topic t1; -sql use t1; - -sql show topics; -if $rows != 1 then - return -1 -endi -if $data00 != t1 then - return -1 -endi -if $data02 != 4 then - return -1 -endi - -sql show databases; -if $rows != 1 then - return -1 -endi -if $data00 != t1 then - return -1 -endi -#tables -if $data02 < 1 then - return -1 -endi -#numofvgroups -if $data03 < 1 then - return -1 -endi - -sql show t1.vgroups; -if $rows < 1 then - return -1 -endi - -sql show t1.stables; -if $rows != 1 then - return -1 -endi -if $data04 < 1 then - return -1 -endi - -sql show t1.tables; -if $rows < 1 then - return -1 -endi - -sql drop topic t1 -sql show topics; -if $rows != 0 then - return -1 -endi -sql show databases; -if $rows != 0 then - return -1 -endi - -sql_error use t1; -sql_error show t1.vgroups; -sql_error show t1.stables; -sql_error show t1.tables; - -print ====step2 create with giving para -sql create topic t1 partitions 6; - -sql show topics; -if $rows != 1 then - return -1 -endi -if $data00 != t1 then - return -1 -endi -if $data02 != 6 then - return -1 -endi - -sql show databases; -if $rows != 1 then - return -1 -endi -if $data00 != t1 then - return -1 -endi -#tables -if $data02 != 6 then - return -1 -endi -#numofvgroups -if $data03 != 6 then - return -1 -endi - -sql show t1.vgroups; -if $rows != 6 then - return -1 -endi - -sql show t1.stables; -if $rows != 1 then - return -1 -endi -if $data00 != ps then - return -1 -endi -if $data04 != 6 then - return -1 -endi - -sql show t1.tables; -if $rows != 6 then - return -1 -endi - -sql describe t1.ps; -if $data00 != off then - return -1 -endi -if $data10 != ts then - return -1 -endi -if $data20 != content then - return -1 -endi -if $data30 != pid then - return -1 -endi - -sql describe t1.p1; -if $data00 != off then - return -1 -endi -if $data10 != ts then - return -1 -endi -if $data20 != content then - return -1 -endi -if $data30 != pid then - return -1 -endi - -sql drop topic t1 -sql show topics; -if $rows != 0 then - return -1 -endi - -sql show databases; -if $rows != 0 then - return -1 -endi - -sql_error show t1.vgroups; -sql_error show t1.stables; -sql_error show t1.tables; - -sql_error create topic t1 partitions -1; -#sql_error create topic t1 partitions 0; -sql_error create topic t1 partitions 10001; - -print =============step3 create with db para -sql create topic db cache 2 blocks 4 duration 10 keep 20 minRows 300 maxRows 400 ctime 120 precision 'ms' comp 2 wal 1 replica 1 -sql show databases -if $data00 != db then - return -1 -endi -if $data02 != 4 then - return -1 -endi -if $data03 != 4 then - return -1 -endi -if $data04 != 1 then - return -1 -endi -if $data06 != 10 then - return -1 -endi -if $data07 != 20,20,20 then - return -1 -endi -if $data08 != 2 then - return -1 -endi -if $data09 != 4 then - return -1 -endi -sql drop topic db; - -sql create topic db cache 2 blocks 4 duration 10 keep 20 minRows 300 maxRows 400 ctime 120 precision 'ms' comp 2 wal 1 replica 1 partitions 7 -sql show databases -if $data00 != db then - return -1 -endi -if $data02 != 7 then - return -1 -endi -if $data03 != 7 then - return -1 -endi -if $data04 != 1 then - return -1 -endi -if $data06 != 10 then - return -1 -endi -if $data07 != 20,20,20 then - return -1 -endi -if $data08 != 2 then - return -1 -endi -if $data09 != 4 then - return -1 -endi - -sql show topics; -if $rows != 1 then - return -1 -endi -if $data00 != db then - return -1 -endi - -sql show databases; -if $rows != 1 then - return -1 -endi -if $data00 != db then - return -1 -endi -#tables -if $data02 != 7 then - return -1 -endi -#numofvgroups -sql show db.vgroups; -if $rows != 7 then - return -1 -endi -sql show db.stables; -if $rows != 1 then - return -1 -endi -sql show db.tables; -if $rows != 7 then - return -1 -endi - -print ============== step name -sql_error alter database db name d1 -sql_error alter database db name d2 -sql_error alter topic db name d1 -sql_error alter topic db name d2 - -print ============== step ntables -sql_error alter database db ntables -1 -sql_error alter database db ntables 0 -sql_error alter database db ntables 1 -sql_error alter database db ntables 10 -sql_error alter topic db ntables -1 -sql_error alter topic db ntables 0 -sql_error alter topic db ntables 1 -sql_error alter topic db ntables 10 - -print ============== step vgroups -sql_error alter database db vgroups -1 -sql_error alter database db vgroups 0 -sql_error alter database db vgroups 1 -sql_error alter database db vgroups 10 -sql_error alter topic db vgroups -1 -sql_error alter topic db vgroups 0 -sql_error alter topic db vgroups 1 -sql_error alter topic db vgroups 10 - -print ============== step replica -sql_error alter database db replica 2 -sql_error alter database db replica 3 -sql_error alter database db replica 0 -sql_error alter topic db replica 2 -sql_error alter topic db replica 3 -sql_error alter topic db replica 0 - -sql alter database db replica 1 -sql show databases -print replica $data4_db -if $data4_db != 1 then - return -1 -endi - -sql show topics -if $rows != 1 then - return -1 -endi - -print ============== step quorum -sql show databases -print quorum $data5_db -if $data5_db != 1 then - return -1 -endi - -sql_error alter topic db quorum 1 -sql alter database db quorum 1 -sql show databases -print quorum $data5_db -if $data5_db != 1 then - return -1 -endi - -sql_error alter database db quorum 2 -sql_error alter database db quorum 3 -sql_error alter topic db quorum 2 -sql_error alter topic db quorum 3 - -sql_error alter database db quorum 0 -sql_error alter database db quorum 4 -sql_error alter database db quorum 5 -sql_error alter database db quorum -1 -sql_error alter topic db quorum 0 -sql_error alter topic db quorum 4 -sql_error alter topic db quorum 5 -sql_error alter topic db quorum -1 - -print ============== step duration -sql_error alter database db duration 0 -sql_error alter database db duration 1 -sql_error alter database db duration 2 -sql_error alter database db duration 10 -sql_error alter database db duration 50 -sql_error alter database db duration 100 -sql_error alter topic db duration 0 -sql_error alter topic db duration 1 -sql_error alter topic db duration 2 -sql_error alter topic db duration 10 -sql_error alter topic db duration 50 -sql_error alter topic db duration 100 - -print ============== step keep -sql show databases -print keep $data7_db -if $data7_db != 20,20,20 then - return -1 -endi - -sql_error topic db keep 20 -sql alter database db keep 20 -sql show databases -print keep $data7_db -if $data7_db != 20,20,20 then - return -1 -endi - -sql_error topic db keep 30 -sql alter database db keep 30 -sql show databases -print keep $data7_db -if $data7_db != 30,30,30 then - return -1 -endi - -sql_error alter topic db keep 40 -sql alter database db keep 40 -sql show databases -print keep $data7_db -if $data7_db != 40,40,40 then - return -1 -endi - -sql alter database db keep 40 -sql alter database db keep 30 -sql alter database db keep 20 -sql_error alter database db keep 10.0 -sql_error alter database db keep 9 -sql_error alter database db keep 1 -sql_error alter database db keep 0 -sql_error alter database db keep -1 -sql_error alter database db keep 365001 - -sql_error alter topic db keep 40 -sql_error alter topic db keep 30 -sql_error alter topic db keep 20 -sql_error alter topic db keep 10 -sql_error alter topic db keep 9 -sql_error alter topic db keep 1 -sql_error alter topic db keep 0 -sql_error alter topic db keep -1 -sql_error alter topic db keep 365001 - -print ============== step cache -sql_error alter database db cache 60 -sql_error alter database db cache 50 -sql_error alter database db cache 20 -sql_error alter database db cache 3 -sql_error alter database db cache 129 -sql_error alter database db cache 300 -sql_error alter database db cache 0 -sql_error alter database db cache -1 - -sql_error alter topic db cache 60 -sql_error alter topic db cache 50 -sql_error alter topic db cache 20 -sql_error alter topic db cache 3 -sql_error alter topic db cache 129 -sql_error alter topic db cache 300 -sql_error alter topic db cache 0 -sql_error alter topic db cache -1 - -print ============== step blocks -sql show databases -print blocks $data9_db -if $data9_db != 4 then - return -1 -endi - -sql_error alter topic db blocks 10 -sql alter database db blocks 10 -sql show databases -print blocks $data9_db -if $data9_db != 10 then - return -1 -endi - -sql_error alter topic db blocks 20 -sql alter database db blocks 20 -sql show databases -print blocks $data9_db -if $data9_db != 20 then - return -1 -endi - -sql_error alter topic db blocks 20 -sql alter database db blocks 30 -sql show databases -print blocks $data9_db -if $data9_db != 30 then - return -1 -endi - -sql alter database db blocks 40 -sql alter database db blocks 30 -sql alter database db blocks 20 -sql alter database db blocks 10 -sql_error alter database db blocks 2 -sql_error alter database db blocks 1 -sql_error alter database db blocks 0 -sql_error alter database db blocks -1 -sql_error alter database db blocks 10001 - -sql_error alter topic db blocks 40 -sql_error alter topic db blocks 30 -sql_error alter topic db blocks 20 -sql_error alter topic db blocks 10 -sql_error alter topic db blocks 2 -sql_error alter topic db blocks 1 -sql_error alter topic db blocks 0 -sql_error alter topic db blocks -1 -sql_error alter topic db blocks 10001 - -print ============== step minrows -sql_error alter database db minrows 1 -sql_error alter database db minrows 100 -sql_error alter database db minrows 1000 - -sql_error alter topic db minrows 1 -sql_error alter topic db minrows 100 -sql_error alter topic db minrows 1000 - -print ============== step maxrows -sql_error alter database db maxrows 1 -sql_error alter database db maxrows 100 -sql_error alter database db maxrows 1000 - -sql_error alter topic db maxrows 1 -sql_error alter topic db maxrows 100 -sql_error alter topic db maxrows 1000 - -print ============== step wallevel -sql show databases -print wallevel $data12_db -if $data12_db != 1 then - return -1 -endi - -sql_error alter topic db wal 1 -sql_error alter database db wal 1 - -sql_error alter database db wal 1 -sql_error alter database db wal 2 -sql_error alter database db wal 1 -sql_error alter database db wal 2 -sql_error alter database db wal 0 -sql_error alter database db wal 3 -sql_error alter database db wal 4 -sql_error alter database db wal -1 -sql_error alter database db wal 1000 - -sql_error alter topic db wal 1 -sql_error alter topic db wal 2 -sql_error alter topic db wal 1 -sql_error alter topic db wal 2 -sql_error alter topic db wal 0 -sql_error alter topic db wal 3 -sql_error alter topic db wal 4 -sql_error alter topic db wal -1 -sql_error alter topic db wal 1000 - -print ============== step fsync -sql_error alter database db fsync 0 -sql_error alter database db fsync 1 -sql_error alter database db fsync 3600 -sql_error alter database db fsync 18000 -sql_error alter database db fsync 180000 -sql_error alter database db fsync 180001 -sql_error alter database db fsync -1 - -sql_error alter topic db fsync 0 -sql_error alter topic db fsync 1 -sql_error alter topic db fsync 3600 -sql_error alter topic db fsync 18000 -sql_error alter topic db fsync 180000 -sql_error alter topic db fsync 180001 -sql_error alter topic db fsync -1 - -print ============== step comp -sql show databases -print comp $data14_db -if $data14_db != 2 then - return -1 -endi - -sql_error alter topic db comp 1 -sql alter database db comp 1 -sql show databases -print comp $data14_db -if $data14_db != 1 then - return -1 -endi - -sql_error alter topic db comp 2 -sql alter database db comp 2 -sql show databases -print comp $data14_db -if $data14_db != 2 then - return -1 -endi - -sql_error alter topic db comp 0 -sql alter database db comp 0 -sql show databases -print comp $data14_db -if $data14_db != 0 then - return -1 -endi - -sql_error alter database db comp 3 -sql_error alter database db comp 4 -sql_error alter database db comp 5 -sql_error alter database db comp -1 - -sql_error alter topic db comp 3 -sql_error alter topic db comp 4 -sql_error alter topic db comp 5 -sql_error alter topic db comp -1 - -print ============== step precision -sql_error alter database db prec 'us' -sql_error alter topic db prec 'us' - -print ============== step status -sql_error alter database db status 'delete' -sql_error alter topic db status 'delete' - -print ============== step drop -sql drop database db -sql show topics; -if $rows != 0 then - return -1 -endi - -sql show databases; -if $rows != 0 then - return -1 -endi - -print ============== step db1 -sql create database d1 -sql_error alter database d1 partitions 2 -sql_error alter topic d1 partitions 2 - -sql show topics; -if $rows != 0 then - return -1 -endi - -sql show databases; -if $rows != 1 then - return -1 -endi - -sql drop database d1 -sql show topics; -if $rows != 0 then - return -1 -endi - -sql show databases; -if $rows != 0 then - return -1 -endi - -print ============== step db2 -sql create topic d1 -sql show topics; -if $rows != 1 then - return -1 -endi - -sql show databases; -if $rows != 1 then - return -1 -endi - -sql drop database d1 -sql show topics; -if $rows != 0 then - return -1 -endi - -sql show databases; -if $rows != 0 then - return -1 -endi - -print ============== step db3 -sql create topic d1 -sql show topics; -if $rows != 1 then - return -1 -endi - -sql show databases; -if $rows != 1 then - return -1 -endi - -sql alter topic d1 partitions 2 -sql show topics; -if $rows != 1 then - return -1 -endi - -sql show databases; -if $rows != 1 then - return -1 -endi - -sql drop database d1 -sql show topics; -if $rows != 0 then - return -1 -endi - -sql show databases; -if $rows != 0 then - return -1 -endi - -print ============== step partitions -sql create topic t1 partitions 5 - -sql_error alter database t1 partitions -1 -sql_error alter database t1 partitions 0 -sql_error alter database t1 partitions 1 -sql_error alter database t1 partitions 2 -sql_error alter database t1 partitions 3 -sql_error alter database t1 partitions 100 -sql_error alter database t1 partitions 1000 -sql_error alter database t1 partitions 10000 - -sql_error alter topic t1 partitions -1 -#sql_error alter topic t1 partitions 0 -sql_error alter database t1 partitions 10000 - -sql alter topic t1 partitions 1 -sql show topics; -if $rows != 1 then - return -1 -endi -if $data00 != t1 then - return -1 -endi -sql show databases; -if $rows != 1 then - return -1 -endi -if $data00 != t1 then - return -1 -endi -#tables -if $data02 != 1 then - return -1 -endi - -sql show t1.stables; -if $rows != 1 then - return -1 -endi -sql show t1.tables; -if $rows != 1 then - return -1 -endi - -sql alter topic t1 partitions 2 -sql show topics; -if $rows != 1 then - return -1 -endi -if $data00 != t1 then - return -1 -endi -sql show databases; -if $rows != 1 then - return -1 -endi -if $data00 != t1 then - return -1 -endi -#tables -if $data02 != 2 then - return -1 -endi - - -sql show t1.stables; -if $rows != 1 then - return -1 -endi -sql show t1.tables; -if $rows != 2 then - return -1 -endi - -sql alter topic t1 partitions 3 -sql show topics; -if $rows != 1 then - return -1 -endi -if $data00 != t1 then - return -1 -endi -sql show databases; -if $rows != 1 then - return -1 -endi -if $data00 != t1 then - return -1 -endi -#tables -if $data02 != 3 then - return -1 -endi - -sql show t1.stables; -if $rows != 1 then - return -1 -endi -sql show t1.tables; -if $rows != 3 then - return -1 -endi - -sql alter topic t1 partitions 10 -sql show topics; -if $rows != 1 then - return -1 -endi -if $data00 != t1 then - return -1 -endi -sql show databases; -if $rows != 1 then - return -1 -endi -if $data00 != t1 then - return -1 -endi -#tables -if $data02 != 10 then - return -1 -endi -#numofvgroups -sql show t1.vgroups; -if $rows != 10 then - return -1 -endi -sql show t1.stables; -if $rows != 1 then - return -1 -endi -sql show t1.tables; -if $rows != 10 then - return -1 -endi - -sql drop topic t1 - -print ============== create same name topic -sql create database d2 -sql create topic t2 - -sql_error create topic d2 -sql_error create topic if not exists d2 -sql_error create topic t2 -sql create topic if not exists t2 -sql_error create topic t2 partitions 5; -sql_error create topic t2 partitions 6; -sql_error create topic t2 partitions 3; - -sql_error alter topic t3 partitions 1 -sql_error alter topic d2 partitions 1 -#sql_error alter topic t2 partitions 0 -sql_error alter topic t2 partitions 10000 - -sql_error drop topic d2 -sql_error drop topic d3 -sql drop database d2 -sql drop database t2 - -print ============== create partitons 0 -sql create topic t2 partitions 0 -sql show t2.stables; -if $rows != 0 then - return -1 -endi -sql show t2.tables; -if $rows != 0 then - return -1 -endi - -sql drop topic t2 -sql_error drop topic abc -sql drop topic if exists abc; - -system sh/exec.sh -n dnode1 -s stop -x SIGINT diff --git a/tests/script/tsim/db/topic2.sim b/tests/script/tsim/db/topic2.sim deleted file mode 100644 index f933f5eee4..0000000000 --- a/tests/script/tsim/db/topic2.sim +++ /dev/null @@ -1,321 +0,0 @@ -system sh/stop_dnodes.sh -system sh/deploy.sh -n dnode1 -i 1 - -system sh/exec.sh -n dnode1 -s start - -sleep 2000 -sql connect - -print ==== step1 -sql create topic t1 partitions 2; -sql show t1.tables -if $rows != 2 then - return -1 -endi -sql show t1.vgroups -if $rows != 2 then - return -1 -endi - -sql insert into t1.p1 values(1, now, '1'); -sql insert into t1.p1 values(1, now, '2'); -sql insert into t1.p1 values(1, now, '3'); -sql insert into t1.p1 values(1, now, '4')(2, now, '5')(3, now, '6')(4, now, '7')(5, now, '8')(6, now, '9'); -sql insert into t1.p1 values(1, now, '10')(2, now, '11')(3, now, '12')(4, now, '13')(5, now, '14')(6, now, '15'); -sql insert into t1.p1 values(1, now, '16')(2, now,'17')(3, now,'18')(4, now,'19')(5, now,'20')(6, now,'21')(7, now,'22')(8, now,'23')(9, now,'24')(10, now,'25')(11, now,'26')(12, now,'27')(13, now,'28')(14, now,'29')(15, now,'30')(16, now,'31')(17, now,'32')(18, now,'33'); - -sql insert into t1.p2 values(1, now, '1'); -sql insert into t1.p2 values(1, now, '2'); -sql insert into t1.p2 values(1, now, '3'); -sql insert into t1.p2 values(1, now, '4')(2, now, '5')(3, now, '6')(4, now, '7')(5, now, '8')(6, now, '9'); -sql insert into t1.p2 values(1, now, '10')(2, now, '11')(3, now, '12')(4, now, '13')(5, now, '14')(6, now, '15'); -sql insert into t1.p2 values(1, now, '16')(2, now,'17')(3, now,'18')(4, now,'19')(5, now,'20')(6, now,'21')(7, now,'22')(8, now,'23')(9, now,'24')(10, now,'25')(11, now,'26')(12, now,'27')(13, now,'28')(14, now,'29')(15, now,'30')(16, now,'31')(17, now,'32')(18, now,'33'); - -sql_error insert into t1.p3 values(1, now, '1'); -sql_error insert into t1.p3 values(1, now, '2'); -sql_error insert into t1.p3 values(1, now, '3'); -sql_error insert into t1.p3 values(1, now, '4')(2, now, '5')(3, now, '6')(4, now, '7')(5, now, '8')(6, now, '9'); -sql_error insert into t1.p3 values(1, now, '10')(2, now, '11')(3, now, '12')(4, now, '13')(5, now, '14')(6, now, '15'); -sql_error insert into t1.p3 values(1, now, '16')(2, now,'17')(3, now,'18')(4, now,'19')(5, now,'20')(6, now,'21')(7, now,'22')(8, now,'23')(9, now,'24')(10, now,'25')(11, now,'26')(12, now,'27')(13, now,'28')(14, now,'29')(15, now,'30')(16, now,'31')(17, now,'32')(18, now,'33'); - -sql select * from t1.p1 order by off asc -if $rows != 33 then - return -1 -endi -if $data02 != 1 then - return -1 -endi -if $data12 != 2 then - return -1 -endi -if $data22 != 3 then - return -1 -endi - -sql select * from t1.p2 order by off asc -if $rows != 33 then - return -1 -endi -if $data02 != 1 then - return -1 -endi -if $data12 != 2 then - return -1 -endi -if $data22 != 3 then - return -1 -endi - -print ==== step2 -sql alter topic t1 partitions 4; -sql show t1.tables -if $rows != 4 then - return -1 -endi -sql show t1.vgroups -if $rows != 4 then - return -1 -endi - -sql insert into t1.p1 values(1, now, '1'); -sql insert into t1.p1 values(1, now, '2'); -sql insert into t1.p1 values(1, now, '3'); -sql insert into t1.p1 values(1, now, '4')(2, now, '5')(3, now, '6')(4, now, '7')(5, now, '8')(6, now, '9'); -sql insert into t1.p1 values(1, now, '10')(2, now, '11')(3, now, '12')(4, now, '13')(5, now, '14')(6, now, '15'); -sql insert into t1.p1 values(1, now, '16')(2, now,'17')(3, now,'18')(4, now,'19')(5, now,'20')(6, now,'21')(7, now,'22')(8, now,'23')(9, now,'24')(10, now,'25')(11, now,'26')(12, now,'27')(13, now,'28')(14, now,'29')(15, now,'30')(16, now,'31')(17, now,'32')(18, now,'33'); - -sql insert into t1.p2 values(1, now, '1'); -sql insert into t1.p2 values(1, now, '2'); -sql insert into t1.p2 values(1, now, '3'); -sql insert into t1.p2 values(1, now, '4')(2, now, '5')(3, now, '6')(4, now, '7')(5, now, '8')(6, now, '9'); -sql insert into t1.p2 values(1, now, '10')(2, now, '11')(3, now, '12')(4, now, '13')(5, now, '14')(6, now, '15'); -sql insert into t1.p2 values(1, now, '16')(2, now,'17')(3, now,'18')(4, now,'19')(5, now,'20')(6, now,'21')(7, now,'22')(8, now,'23')(9, now,'24')(10, now,'25')(11, now,'26')(12, now,'27')(13, now,'28')(14, now,'29')(15, now,'30')(16, now,'31')(17, now,'32')(18, now,'33'); - -sql insert into t1.p3 values(1, now, '1'); -sql insert into t1.p3 values(1, now, '2'); -sql insert into t1.p3 values(1, now, '3'); -sql insert into t1.p3 values(1, now, '4')(2, now, '5')(3, now, '6')(4, now, '7')(5, now, '8')(6, now, '9'); -sql insert into t1.p3 values(1, now, '10')(2, now, '11')(3, now, '12')(4, now, '13')(5, now, '14')(6, now, '15'); -sql insert into t1.p3 values(1, now, '16')(2, now,'17')(3, now,'18')(4, now,'19')(5, now,'20')(6, now,'21')(7, now,'22')(8, now,'23')(9, now,'24')(10, now,'25')(11, now,'26')(12, now,'27')(13, now,'28')(14, now,'29')(15, now,'30')(16, now,'31')(17, now,'32')(18, now,'33'); - -sql insert into t1.p4 values(1, now, '1'); -sql insert into t1.p4 values(1, now, '2'); -sql insert into t1.p4 values(1, now, '3'); -sql insert into t1.p4 values(1, now, '4')(2, now, '5')(3, now, '6')(4, now, '7')(5, now, '8')(6, now, '9'); -sql insert into t1.p4 values(1, now, '10')(2, now, '11')(3, now, '12')(4, now, '13')(5, now, '14')(6, now, '15'); -sql insert into t1.p4 values(1, now, '16')(2, now,'17')(3, now,'18')(4, now,'19')(5, now,'20')(6, now,'21')(7, now,'22')(8, now,'23')(9, now,'24')(10, now,'25')(11, now,'26')(12, now,'27')(13, now,'28')(14, now,'29')(15, now,'30')(16, now,'31')(17, now,'32')(18, now,'33'); - -sql_error insert into t1.p5 values(1, now, '1'); -sql_error insert into t1.p5 values(1, now, '2'); -sql_error insert into t1.p5 values(1, now, '3'); -sql_error insert into t1.p5 values(1, now, '4')(2, now, '5')(3, now, '6')(4, now, '7')(5, now, '8')(6, now, '9'); -sql_error insert into t1.p5 values(1, now, '10')(2, now, '11')(3, now, '12')(4, now, '13')(5, now, '14')(6, now, '15'); -sql_error insert into t1.p5 values(1, now, '16')(2, now,'17')(3, now,'18')(4, now,'19')(5, now,'20')(6, now,'21')(7, now,'22')(8, now,'23')(9, now,'24')(10, now,'25')(11, now,'26')(12, now,'27')(13, now,'28')(14, now,'29')(15, now,'30')(16, now,'31')(17, now,'32')(18, now,'33'); - -sql select * from t1.p1 order by off asc -if $rows != 66 then - return -1 -endi -if $data02 != 1 then - return -1 -endi -if $data12 != 2 then - return -1 -endi -if $data22 != 3 then - return -1 -endi - -sql select * from t1.p2 order by off asc -if $rows != 66 then - return -1 -endi -if $data02 != 1 then - return -1 -endi -if $data12 != 2 then - return -1 -endi -if $data22 != 3 then - return -1 -endi - -sql select * from t1.p3 order by off asc -if $rows != 33 then - return -1 -endi -if $data02 != 1 then - return -1 -endi -if $data12 != 2 then - return -1 -endi -if $data22 != 3 then - return -1 -endi - -sql select * from t1.p4 order by off asc -if $rows != 33 then - return -1 -endi -if $data02 != 1 then - return -1 -endi -if $data12 != 2 then - return -1 -endi -if $data22 != 3 then - return -1 -endi - -print ==== step3 -sql alter topic t1 partitions 1; -sql show t1.tables -if $rows != 1 then - return -1 -endi -sql show t1.vgroups -if $rows != 1 then - return -1 -endi - -sql insert into t1.p1 values(1, now, '1'); -sql insert into t1.p1 values(1, now, '2'); -sql insert into t1.p1 values(1, now, '3'); -sql insert into t1.p1 values(1, now, '4')(2, now, '5')(3, now, '6')(4, now, '7')(5, now, '8')(6, now, '9'); -sql insert into t1.p1 values(1, now, '10')(2, now, '11')(3, now, '12')(4, now, '13')(5, now, '14')(6, now, '15'); -sql insert into t1.p1 values(1, now, '16')(2, now,'17')(3, now,'18')(4, now,'19')(5, now,'20')(6, now,'21')(7, now,'22')(8, now,'23')(9, now,'24')(10, now,'25')(11, now,'26')(12, now,'27')(13, now,'28')(14, now,'29')(15, now,'30')(16, now,'31')(17, now,'32')(18, now,'33'); - -sql_error insert into t1.p2 values(1, now, '1'); -sql_error insert into t1.p2 values(1, now, '2'); -sql_error insert into t1.p2 values(1, now, '3'); -sql_error insert into t1.p2 values(1, now, '4')(2, now, '5')(3, now, '6')(4, now, '7')(5, now, '8')(6, now, '9'); -sql_error insert into t1.p2 values(1, now, '10')(2, now, '11')(3, now, '12')(4, now, '13')(5, now, '14')(6, now, '15'); -sql_error insert into t1.p2 values(1, now, '16')(2, now,'17')(3, now,'18')(4, now,'19')(5, now,'20')(6, now,'21')(7, now,'22')(8, now,'23')(9, now,'24')(10, now,'25')(11, now,'26')(12, now,'27')(13, now,'28')(14, now,'29')(15, now,'30')(16, now,'31')(17, now,'32')(18, now,'33'); - -sql_error insert into t1.p3 values(1, now, '1'); -sql_error insert into t1.p3 values(1, now, '2'); -sql_error insert into t1.p3 values(1, now, '3'); -sql_error insert into t1.p3 values(1, now, '4')(2, now, '5')(3, now, '6')(4, now, '7')(5, now, '8')(6, now, '9'); -sql_error insert into t1.p3 values(1, now, '10')(2, now, '11')(3, now, '12')(4, now, '13')(5, now, '14')(6, now, '15'); -sql_error insert into t1.p3 values(1, now, '16')(2, now,'17')(3, now,'18')(4, now,'19')(5, now,'20')(6, now,'21')(7, now,'22')(8, now,'23')(9, now,'24')(10, now,'25')(11, now,'26')(12, now,'27')(13, now,'28')(14, now,'29')(15, now,'30')(16, now,'31')(17, now,'32')(18, now,'33'); - -sql_error insert into t1.p4 values(1, now, '1'); -sql_error insert into t1.p4 values(1, now, '2'); -sql_error insert into t1.p4 values(1, now, '3'); -sql_error insert into t1.p4 values(1, now, '4')(2, now, '5')(3, now, '6')(4, now, '7')(5, now, '8')(6, now, '9'); -sql_error insert into t1.p4 values(1, now, '10')(2, now, '11')(3, now, '12')(4, now, '13')(5, now, '14')(6, now, '15'); -sql_error insert into t1.p4 values(1, now, '16')(2, now,'17')(3, now,'18')(4, now,'19')(5, now,'20')(6, now,'21')(7, now,'22')(8, now,'23')(9, now,'24')(10, now,'25')(11, now,'26')(12, now,'27')(13, now,'28')(14, now,'29')(15, now,'30')(16, now,'31')(17, now,'32')(18, now,'33'); - -sql_error insert into t1.p5 values(1, now, '1'); -sql_error insert into t1.p5 values(1, now, '2'); -sql_error insert into t1.p5 values(1, now, '3'); -sql_error insert into t1.p5 values(1, now, '4')(2, now, '5')(3, now, '6')(4, now, '7')(5, now, '8')(6, now, '9'); -sql_error insert into t1.p5 values(1, now, '10')(2, now, '11')(3, now, '12')(4, now, '13')(5, now, '14')(6, now, '15'); -sql_error insert into t1.p5 values(1, now, '16')(2, now,'17')(3, now,'18')(4, now,'19')(5, now,'20')(6, now,'21')(7, now,'22')(8, now,'23')(9, now,'24')(10, now,'25')(11, now,'26')(12, now,'27')(13, now,'28')(14, now,'29')(15, now,'30')(16, now,'31')(17, now,'32')(18, now,'33'); - -sql select * from t1.p1 order by off asc -if $rows != 99 then - return -1 -endi -if $data02 != 1 then - return -1 -endi -if $data12 != 2 then - return -1 -endi -if $data22 != 3 then - return -1 -endi - -sql_error select * from t1.p2 order by off asc -sql_error select * from t1.p3 order by off asc -sql_error select * from t1.p4 order by off asc - -print ==== step4 -sql alter topic t1 partitions 3; -sql show t1.tables -if $rows != 3 then - return -1 -endi -sql show t1.vgroups -if $rows != 3 then - return -1 -endi - -sql insert into t1.p1 values(1, now, '1'); -sql insert into t1.p1 values(1, now, '2'); -sql insert into t1.p1 values(1, now, '3'); -sql insert into t1.p1 values(1, now, '4')(2, now, '5')(3, now, '6')(4, now, '7')(5, now, '8')(6, now, '9'); -sql insert into t1.p1 values(1, now, '10')(2, now, '11')(3, now, '12')(4, now, '13')(5, now, '14')(6, now, '15'); -sql insert into t1.p1 values(1, now, '16')(2, now,'17')(3, now,'18')(4, now,'19')(5, now,'20')(6, now,'21')(7, now,'22')(8, now,'23')(9, now,'24')(10, now,'25')(11, now,'26')(12, now,'27')(13, now,'28')(14, now,'29')(15, now,'30')(16, now,'31')(17, now,'32')(18, now,'33'); - -sql insert into t1.p2 values(1, now, '1'); -sql insert into t1.p2 values(1, now, '2'); -sql insert into t1.p2 values(1, now, '3'); -sql insert into t1.p2 values(1, now, '4')(2, now, '5')(3, now, '6')(4, now, '7')(5, now, '8')(6, now, '9'); -sql insert into t1.p2 values(1, now, '10')(2, now, '11')(3, now, '12')(4, now, '13')(5, now, '14')(6, now, '15'); -sql insert into t1.p2 values(1, now, '16')(2, now,'17')(3, now,'18')(4, now,'19')(5, now,'20')(6, now,'21')(7, now,'22')(8, now,'23')(9, now,'24')(10, now,'25')(11, now,'26')(12, now,'27')(13, now,'28')(14, now,'29')(15, now,'30')(16, now,'31')(17, now,'32')(18, now,'33'); - -sql insert into t1.p3 values(1, now, '1'); -sql insert into t1.p3 values(1, now, '2'); -sql insert into t1.p3 values(1, now, '3'); -sql insert into t1.p3 values(1, now, '4')(2, now, '5')(3, now, '6')(4, now, '7')(5, now, '8')(6, now, '9'); -sql insert into t1.p3 values(1, now, '10')(2, now, '11')(3, now, '12')(4, now, '13')(5, now, '14')(6, now, '15'); -sql insert into t1.p3 values(1, now, '16')(2, now,'17')(3, now,'18')(4, now,'19')(5, now,'20')(6, now,'21')(7, now,'22')(8, now,'23')(9, now,'24')(10, now,'25')(11, now,'26')(12, now,'27')(13, now,'28')(14, now,'29')(15, now,'30')(16, now,'31')(17, now,'32')(18, now,'33'); - -sql_error insert into t1.p4 values(1, now, '1'); -sql_error insert into t1.p5 values(1, now, '1'); -sql_error insert into t1.p6 values(1, now, '1'); -sql_error select * from t1.p4 order by off asc -sql_error select * from t1.p5 order by off asc -sql_error select * from t1.p6 order by off asc - -sql select * from t1.p1 order by off asc -if $rows != 132 then - return -1 -endi -if $data02 != 1 then - return -1 -endi -if $data12 != 2 then - return -1 -endi -if $data22 != 3 then - return -1 -endi - -sql select * from t1.p2 order by off asc -if $rows != 33 then - return -1 -endi -if $data02 != 1 then - return -1 -endi -if $data12 != 2 then - return -1 -endi -if $data22 != 3 then - return -1 -endi - -sql select * from t1.p3 order by off asc -if $rows != 33 then - return -1 -endi -if $data02 != 1 then - return -1 -endi -if $data12 != 2 then - return -1 -endi -if $data22 != 3 then - return -1 -endi - -sql select * from t1.ps order by off asc -if $rows != 198 then - return -1 -endi - -system sh/exec.sh -n dnode1 -s stop -x SIGINT diff --git a/tests/script/tsim/db/vnodes.sim b/tests/script/tsim/db/vnodes.sim deleted file mode 100644 index 96f68f1632..0000000000 --- a/tests/script/tsim/db/vnodes.sim +++ /dev/null @@ -1,47 +0,0 @@ -system sh/stop_dnodes.sh - -$totalVnodes = 10 -$maxTables = 4 -$totalRows = $totalVnodes * $maxTables - -system sh/deploy.sh -n dnode1 -i 1 -system sh/cfg.sh -n dnode1 -c walLevel -v 1 -system sh/cfg.sh -n dnode1 -c maxTablesPerVnode -v $maxTables -system sh/cfg.sh -n dnode1 -c maxVgroupsPerDb -v $totalVnodes -system sh/cfg.sh -n dnode1 -c maxVnodeConnections -v 100000 -system sh/cfg.sh -n dnode1 -c maxMeterConnections -v 100000 -system sh/cfg.sh -n dnode1 -c maxShellConns -v 100000 -system sh/cfg.sh -n dnode1 -c maxMgmtConnections -v 100000 - -print ========== prepare data -system sh/exec.sh -n dnode1 -s start -sleep 2000 -sql connect -sql create database db blocks 3 cache 1 -sql use db - -print ========== step1 -sql create table mt (ts timestamp, tbcol int) TAGS(tgcol int) - -$x = 0 -while $x < $totalRows - $tb = t . $x - sql create table $tb using mt tags( $x ) - sql insert into $tb values (now, $x ) - $x = $x + 1 -endw - -print ========== step2 -sql select * from mt -print $rows -print $totalRows -if $rows != $totalRows then - return -1 -endi - -sql select count(*) from mt -if $data00 != $totalRows then - return -1 -endi - -system sh/exec.sh -n dnode1 -s stop -x SIGINT -- GitLab From 276b0113d42899091cf5714486787a84aeb21cde Mon Sep 17 00:00:00 2001 From: Shengliang Guan Date: Thu, 14 Jul 2022 20:41:47 +0800 Subject: [PATCH 151/153] others: remove obsolete 2.0 code --- 2.0/CMakeLists.txt | 54 - .../tdenginedocs-cn/administrator/index.html | 137 - .../advanced-features/index.html | 64 - .../tdenginedocs-cn/assets/Picture2.png | Bin 44198 -> 0 bytes .../assets/clip_image001-2474914.png | Bin 123083 -> 0 bytes .../assets/clip_image001-2474939.png | Bin 76395 -> 0 bytes .../assets/clip_image001-2474961.png | Bin 26668 -> 0 bytes .../assets/clip_image001-2474987.png | Bin 44889 -> 0 bytes .../tdenginedocs-cn/assets/clip_image001.png | Bin 69060 -> 0 bytes .../tdenginedocs-cn/assets/fig1.png | Bin 61774 -> 0 bytes .../tdenginedocs-cn/assets/fig2.png | Bin 50018 -> 0 bytes .../assets/image-20190707124650780.png | Bin 21589 -> 0 bytes .../assets/image-20190707124818590.png | Bin 22568 -> 0 bytes .../tdenginedocs-cn/assets/nodes.png | Bin 67429 -> 0 bytes .../tdenginedocs-cn/assets/structure.png | Bin 25593 -> 0 bytes .../tdenginedocs-cn/assets/vnode.png | Bin 6969 -> 0 bytes .../tdenginedocs-cn/assets/write_process.png | Bin 24837 -> 0 bytes .../connections-with-other-tools/index.html | 93 - .../tdenginedocs-cn/connector/index.html | 262 - .../data-model-and-architecture/index.html | 128 - .../tdenginedocs-cn/faq/index.html | 33 - .../getting-started/index.html | 88 - 2.0/documentation/tdenginedocs-cn/index.html | 1 - .../tdenginedocs-cn/lib/bootstrap.min.css | 7 - .../tdenginedocs-cn/lib/docs/docs.css | 269 - .../tdenginedocs-cn/lib/docs/liner.js | 19 - .../tdenginedocs-cn/lib/docs/prettify.js | 46 - .../lib/docs/prettyprint-sql.js | 31 - .../lib/docs/prettyprint-term.js | 9 - .../lib/docs/taosdataprettify.css | 231 - .../tdenginedocs-cn/lib/jquery-3.4.1.min.js | 2 - .../more-on-system-architecture/index.html | 159 - .../tdenginedocs-cn/styles/base.css | 1112 ---- .../tdenginedocs-cn/styles/base.min.css | 1 - .../tdenginedocs-cn/super-table/index.html | 110 - .../tdenginedocs-cn/taos-sql/index.html | 388 -- .../tdenginedocs-en/administrator/index.html | 137 - .../advanced-features/index.html | 41 - .../tdenginedocs-en/assets/Picture2.png | Bin 44198 -> 0 bytes .../assets/clip_image001-2474914.png | Bin 123083 -> 0 bytes .../assets/clip_image001-2474939.png | Bin 76395 -> 0 bytes .../assets/clip_image001-2474961.png | Bin 26668 -> 0 bytes .../assets/clip_image001-2474987.png | Bin 44889 -> 0 bytes .../tdenginedocs-en/assets/clip_image001.png | Bin 69060 -> 0 bytes .../tdenginedocs-en/assets/fig1.png | Bin 61774 -> 0 bytes .../tdenginedocs-en/assets/fig2.png | Bin 50018 -> 0 bytes .../assets/image-20190707124650780.png | Bin 21589 -> 0 bytes .../assets/image-20190707124818590.png | Bin 22568 -> 0 bytes .../tdenginedocs-en/assets/nodes.png | Bin 67429 -> 0 bytes .../tdenginedocs-en/assets/structure.png | Bin 25593 -> 0 bytes .../tdenginedocs-en/assets/vnode.png | Bin 6969 -> 0 bytes .../tdenginedocs-en/assets/write_process.png | Bin 24837 -> 0 bytes .../connections-with-other-tools/index.html | 93 - .../tdenginedocs-en/connector/index.html | 354 - .../contributor_license_agreement/index.html | 20 - .../data-model-and-architecture/index.html | 129 - .../tdenginedocs-en/faq/index.html | 27 - .../getting-started/index.html | 88 - 2.0/documentation/tdenginedocs-en/index.html | 1 - .../tdenginedocs-en/lib/bootstrap.min.css | 7 - .../tdenginedocs-en/lib/docs/docs.css | 269 - .../tdenginedocs-en/lib/docs/liner.js | 19 - .../tdenginedocs-en/lib/docs/prettify.js | 46 - .../lib/docs/prettyprint-sql.js | 31 - .../lib/docs/prettyprint-term.js | 9 - .../lib/docs/taosdataprettify.css | 231 - .../tdenginedocs-en/lib/jquery-3.4.1.min.js | 2 - .../more-on-system-architecture/index.html | 120 - .../tdenginedocs-en/styles/base.css | 1112 ---- .../tdenginedocs-en/styles/base.min.css | 1 - .../tdenginedocs-en/super-table/index.html | 95 - .../tdenginedocs-en/taos-sql/index.html | 423 -- 2.0/documentation/webdocs/assets/Picture2.png | Bin 44198 -> 0 bytes .../webdocs/assets/add_datasource1.jpg | Bin 54717 -> 0 bytes .../webdocs/assets/add_datasource2.jpg | Bin 45044 -> 0 bytes .../webdocs/assets/add_datasource3.jpg | Bin 43325 -> 0 bytes .../webdocs/assets/add_datasource4.jpg | Bin 55224 -> 0 bytes .../webdocs/assets/create_dashboard1.jpg | Bin 92983 -> 0 bytes .../webdocs/assets/create_dashboard2.jpg | Bin 99202 -> 0 bytes 2.0/documentation/webdocs/assets/fig1.png | Bin 61774 -> 0 bytes 2.0/documentation/webdocs/assets/fig2.png | Bin 50018 -> 0 bytes .../assets/image-20190707124650780.png | Bin 21589 -> 0 bytes .../assets/image-20190707124818590.png | Bin 22568 -> 0 bytes .../webdocs/assets/import_dashboard1.jpg | Bin 45736 -> 0 bytes .../webdocs/assets/import_dashboard2.jpg | Bin 165404 -> 0 bytes 2.0/documentation/webdocs/assets/nodes.png | Bin 67429 -> 0 bytes .../webdocs/assets/structure.png | Bin 25593 -> 0 bytes 2.0/documentation/webdocs/assets/vnode.png | Bin 6969 -> 0 bytes .../webdocs/assets/write_process.png | Bin 24837 -> 0 bytes .../Connections with other Tools-ch.md | 175 - .../Connections with other Tools.md | 167 - .../webdocs/markdowndocs/Connector.md | 918 --- .../Contributor_License_Agreement.md | 35 - .../Data model and architecture-ch.md | 100 - .../Data model and architecture.md | 101 - .../More on System Architecture-ch.md | 248 - .../More on System Architecture.md | 176 - .../webdocs/markdowndocs/Super Table-ch.md | 225 - .../webdocs/markdowndocs/Super Table.md | 195 - .../webdocs/markdowndocs/TAOS SQL-ch.md | 659 -- .../webdocs/markdowndocs/TAOS SQL.md | 537 -- .../webdocs/markdowndocs/administrator-ch.md | 389 -- .../webdocs/markdowndocs/administrator.md | 200 - .../markdowndocs/advanced features-ch.md | 87 - .../webdocs/markdowndocs/advanced features.md | 80 - .../webdocs/markdowndocs/connector-ch.md | 1272 ---- 2.0/documentation20/cn/00.index/docs.md | 157 - 2.0/documentation20/cn/01.evaluation/docs.md | 65 - .../cn/02.getting-started/01.docker/docs.md | 243 - .../cn/02.getting-started/docs.md | 214 - .../cn/03.architecture/01.taosd/docs.md | 117 - .../cn/03.architecture/02.replica/docs.md | 253 - .../cn/03.architecture/docs.md | 451 -- 2.0/documentation20/cn/04.model/docs.md | 77 - 2.0/documentation20/cn/05.insert/docs.md | 305 - 2.0/documentation20/cn/06.queries/docs.md | 93 - .../cn/07.advanced-features/docs.md | 365 - .../cn/08.connector/01.java/docs.md | 572 -- 2.0/documentation20/cn/08.connector/docs.md | 1229 ---- 2.0/documentation20/cn/09.connections/docs.md | 159 - 2.0/documentation20/cn/10.cluster/docs.md | 264 - .../cn/11.administrator/docs.md | 862 --- .../cn/12.taos-sql/01.error-code/docs.md | 172 - .../cn/12.taos-sql/02.udf/docs.md | 137 - 2.0/documentation20/cn/12.taos-sql/docs.md | 1520 ----- 2.0/documentation20/cn/13.faq/docs.md | 187 - .../cn/images/architecture/dnode.png | Bin 99250 -> 0 bytes .../cn/images/architecture/message.png | Bin 44198 -> 0 bytes .../cn/images/architecture/modules.png | Bin 89009 -> 0 bytes .../cn/images/architecture/multi_tables.png | Bin 67254 -> 0 bytes .../images/architecture/replica-forward.png | Bin 37508 -> 0 bytes .../cn/images/architecture/replica-master.png | Bin 117209 -> 0 bytes .../images/architecture/replica-restore.png | Bin 93250 -> 0 bytes .../cn/images/architecture/structure.png | Bin 94536 -> 0 bytes .../cn/images/architecture/vnode.png | Bin 55635 -> 0 bytes .../cn/images/architecture/write_master.png | Bin 72497 -> 0 bytes .../cn/images/architecture/write_slave.png | Bin 57672 -> 0 bytes .../cn/images/connections/add_datasource1.jpg | Bin 54717 -> 0 bytes .../cn/images/connections/add_datasource2.jpg | Bin 45044 -> 0 bytes .../cn/images/connections/add_datasource3.jpg | Bin 56309 -> 0 bytes .../cn/images/connections/add_datasource4.jpg | Bin 61678 -> 0 bytes .../images/connections/create_dashboard1.jpg | Bin 92983 -> 0 bytes .../images/connections/create_dashboard2.jpg | Bin 99202 -> 0 bytes .../images/connections/import_dashboard1.jpg | Bin 45736 -> 0 bytes .../images/connections/import_dashboard2.jpg | Bin 165404 -> 0 bytes 2.0/documentation20/cn/images/connector.png | Bin 87029 -> 0 bytes 2.0/documentation20/cn/images/eco_system.png | Bin 46061 -> 0 bytes .../cn/images/tdengine-jdbc-connector.png | Bin 42560 -> 0 bytes 2.0/documentation20/en/00.index/docs.md | 129 - 2.0/documentation20/en/01.evaluation/docs.md | 64 - .../en/02.getting-started/01.docker/docs.md | 243 - .../en/02.getting-started/docs.md | 221 - .../en/03.architecture/docs.md | 436 -- 2.0/documentation20/en/04.model/docs.md | 73 - 2.0/documentation20/en/05.insert/docs.md | 282 - 2.0/documentation20/en/06.queries/docs.md | 99 - .../en/07.advanced-features/docs.md | 360 - .../en/08.connector/01.java/docs.md | 525 -- 2.0/documentation20/en/08.connector/docs.md | 1050 --- 2.0/documentation20/en/09.connections/docs.md | 157 - 2.0/documentation20/en/10.cluster/docs.md | 235 - .../en/11.administrator/docs.md | 496 -- 2.0/documentation20/en/12.taos-sql/docs.md | 1247 ---- 2.0/documentation20/en/13.faq/docs.md | 161 - .../en/images/architecture/dnode.png | Bin 99250 -> 0 bytes .../en/images/architecture/message.png | Bin 44198 -> 0 bytes .../en/images/architecture/modules.png | Bin 89009 -> 0 bytes .../en/images/architecture/multi_tables.png | Bin 67254 -> 0 bytes .../images/architecture/replica-forward.png | Bin 37508 -> 0 bytes .../en/images/architecture/replica-master.png | Bin 117209 -> 0 bytes .../images/architecture/replica-restore.png | Bin 93250 -> 0 bytes .../en/images/architecture/structure.png | Bin 94536 -> 0 bytes .../en/images/architecture/vnode.png | Bin 55635 -> 0 bytes .../en/images/architecture/write_master.png | Bin 72497 -> 0 bytes .../en/images/architecture/write_slave.png | Bin 57672 -> 0 bytes .../en/images/connections/add_datasource1.jpg | Bin 54717 -> 0 bytes .../en/images/connections/add_datasource2.jpg | Bin 45044 -> 0 bytes .../en/images/connections/add_datasource3.jpg | Bin 56309 -> 0 bytes .../en/images/connections/add_datasource4.jpg | Bin 61678 -> 0 bytes .../images/connections/create_dashboard1.jpg | Bin 92983 -> 0 bytes .../images/connections/create_dashboard2.jpg | Bin 99202 -> 0 bytes .../images/connections/import_dashboard1.jpg | Bin 45736 -> 0 bytes .../images/connections/import_dashboard2.jpg | Bin 165404 -> 0 bytes 2.0/documentation20/en/images/connector.png | Bin 87029 -> 0 bytes 2.0/documentation20/en/images/eco_system.png | Bin 46061 -> 0 bytes .../en/images/tdengine-jdbc-connector.png | Bin 42560 -> 0 bytes 2.0/importSampleData/.gitignore | 17 - 2.0/importSampleData/LICENSE | 661 -- 2.0/importSampleData/README.md | 245 - 2.0/importSampleData/app/main.go | 1021 --- 2.0/importSampleData/config/cfg.toml | 51 - .../dashboard/sensor_info.json | 380 -- .../data/camera_detection.json | 1000 --- 2.0/importSampleData/data/sensor_info.csv | 1001 --- 2.0/importSampleData/go.mod | 8 - 2.0/importSampleData/import/import_config.go | 81 - 2.0/minidevops/README.MD | 221 - 2.0/minidevops/demodashboard.json | 356 - 2.0/minidevops/grafana/tdengine/README.md | 72 - .../grafana/tdengine/css/query-editor.css | 3 - 2.0/minidevops/grafana/tdengine/datasource.js | 170 - .../grafana/tdengine/img/taosdata_logo.png | Bin 3211 -> 0 bytes 2.0/minidevops/grafana/tdengine/module.js | 51 - .../grafana/tdengine/partials/config.html | 19 - .../tdengine/partials/query.editor.html | 58 - 2.0/minidevops/grafana/tdengine/plugin.json | 32 - 2.0/minidevops/grafana/tdengine/query_ctrl.js | 91 - 2.0/minidevops/prometheus/prometheus.yml | 36 - 2.0/minidevops/run.sh | 29 - 2.0/minidevops/taos/taos.cfg | 1 - 2.0/minidevops/telegraf/telegraf.conf | 5861 ----------------- 2.0/packaging/cfg/taos.cfg | 291 - 2.0/packaging/check_package.sh | 245 - 2.0/packaging/deb/DEBIAN/control | 14 - 2.0/packaging/deb/DEBIAN/postinst | 13 - 2.0/packaging/deb/DEBIAN/postrm | 2 - 2.0/packaging/deb/DEBIAN/preinst | 32 - 2.0/packaging/deb/DEBIAN/prerm | 42 - 2.0/packaging/deb/makedeb.sh | 144 - 2.0/packaging/deb/powerd | 88 - 2.0/packaging/deb/taosd | 88 - 2.0/packaging/deb/tarbitratord | 88 - 2.0/packaging/docker/Dockerfile | 24 - 2.0/packaging/docker/dockerManifest.sh | 76 - 2.0/packaging/docker/dockerbuild.sh | 101 - 2.0/packaging/docker/dockerbuildi.sh | 56 - 2.0/packaging/release.sh | 265 - 2.0/packaging/rpm/makerpm.sh | 87 - 2.0/packaging/rpm/powerd | 145 - 2.0/packaging/rpm/taosd | 145 - 2.0/packaging/rpm/tarbitratord | 141 - 2.0/packaging/rpm/tdengine.spec | 228 - 2.0/packaging/tools/check_os.sh | 52 - 2.0/packaging/tools/get_client.sh | 21 - 2.0/packaging/tools/get_os.sh | 14 - 2.0/packaging/tools/get_version.sh | 15 - 2.0/packaging/tools/install.sh | 1031 --- 2.0/packaging/tools/install_arbi.sh | 354 - 2.0/packaging/tools/install_arbi_power.sh | 354 - 2.0/packaging/tools/install_arbi_tq.sh | 298 - 2.0/packaging/tools/install_client.sh | 310 - 2.0/packaging/tools/install_client_power.sh | 306 - 2.0/packaging/tools/install_client_tq.sh | 251 - 2.0/packaging/tools/install_power.sh | 977 --- 2.0/packaging/tools/install_tq.sh | 977 --- 2.0/packaging/tools/make_install.sh | 537 -- 2.0/packaging/tools/makearbi.sh | 79 - 2.0/packaging/tools/makearbi_power.sh | 75 - 2.0/packaging/tools/makearbi_tq.sh | 75 - 2.0/packaging/tools/makeclient.sh | 207 - 2.0/packaging/tools/makeclient_power.sh | 269 - 2.0/packaging/tools/makeclient_tq.sh | 236 - 2.0/packaging/tools/makepkg.sh | 238 - 2.0/packaging/tools/makepkg_power.sh | 224 - 2.0/packaging/tools/makepkg_tq.sh | 224 - 2.0/packaging/tools/post.sh | 496 -- 2.0/packaging/tools/preun.sh | 122 - 2.0/packaging/tools/release_note | 136 - 2.0/packaging/tools/remove.sh | 226 - 2.0/packaging/tools/remove_arbi.sh | 129 - 2.0/packaging/tools/remove_arbi_power.sh | 130 - 2.0/packaging/tools/remove_arbi_tq.sh | 130 - 2.0/packaging/tools/remove_client.sh | 85 - 2.0/packaging/tools/remove_client_power.sh | 85 - 2.0/packaging/tools/remove_client_tq.sh | 85 - 2.0/packaging/tools/remove_power.sh | 227 - 2.0/packaging/tools/remove_tq.sh | 227 - 2.0/packaging/tools/repair_link.sh | 39 - 2.0/packaging/tools/set_core.sh | 40 - 2.0/packaging/tools/startPre.sh | 50 - 2.0/packaging/tools/taosd-dump-cfg.gdb | 144 - 2.0/snap/gui/t-dengine.svg | 1 - 2.0/snap/hooks/install | 22 - 2.0/snap/local/launcher.sh | 26 - 2.0/snap/local/taoswrapper.sh | 25 - 2.0/snap/snapcraft.yaml | 94 - 2.0/src/connector/C#/TDengineDriver.cs | 170 - 2.0/src/connector/jdbc/CMakeLists.txt | 15 - 2.0/src/connector/jdbc/deploy-pom.xml | 214 - 2.0/src/connector/jdbc/pom.xml | 131 - 2.0/src/connector/jdbc/readme.md | 595 -- .../jdbc/src/main/assembly/assembly-jar.xml | 18 - .../jdbc/src/main/assembly/assembly.xml | 24 - .../com/taosdata/jdbc/AbstractConnection.java | 516 -- .../jdbc/AbstractDatabaseMetaData.java | 1281 ---- .../com/taosdata/jdbc/AbstractDriver.java | 96 - .../jdbc/AbstractParameterMetaData.java | 159 - .../com/taosdata/jdbc/AbstractResultSet.java | 1184 ---- .../com/taosdata/jdbc/AbstractStatement.java | 358 - .../com/taosdata/jdbc/ColumnMetaData.java | 65 - .../jdbc/DatabaseMetaDataResultSet.java | 239 - .../com/taosdata/jdbc/EmptyResultSet.java | 986 --- .../com/taosdata/jdbc/TSDBConnection.java | 104 - .../java/com/taosdata/jdbc/TSDBConstants.java | 221 - .../taosdata/jdbc/TSDBDatabaseMetaData.java | 95 - .../java/com/taosdata/jdbc/TSDBDriver.java | 252 - .../java/com/taosdata/jdbc/TSDBError.java | 86 - .../com/taosdata/jdbc/TSDBErrorNumbers.java | 95 - .../com/taosdata/jdbc/TSDBJNIConnector.java | 354 - .../taosdata/jdbc/TSDBParameterMetaData.java | 8 - .../taosdata/jdbc/TSDBPreparedStatement.java | 981 --- .../java/com/taosdata/jdbc/TSDBResultSet.java | 480 -- .../taosdata/jdbc/TSDBResultSetBlockData.java | 439 -- .../taosdata/jdbc/TSDBResultSetMetaData.java | 205 - .../taosdata/jdbc/TSDBResultSetRowData.java | 500 -- .../taosdata/jdbc/TSDBResultSetWrapper.java | 1172 ---- .../java/com/taosdata/jdbc/TSDBStatement.java | 133 - .../java/com/taosdata/jdbc/TSDBSubscribe.java | 58 - .../com/taosdata/jdbc/TaosGlobalConfig.java | 30 - .../java/com/taosdata/jdbc/WrapperImpl.java | 21 - .../taosdata/jdbc/enums/TimestampFormat.java | 7 - .../jdbc/enums/TimestampPrecision.java | 8 - .../taosdata/jdbc/rs/RestfulConnection.java | 91 - .../jdbc/rs/RestfulDatabaseMetaData.java | 87 - .../com/taosdata/jdbc/rs/RestfulDriver.java | 112 - .../jdbc/rs/RestfulParameterMetaData.java | 10 - .../jdbc/rs/RestfulPreparedStatement.java | 445 -- .../taosdata/jdbc/rs/RestfulResultSet.java | 666 -- .../jdbc/rs/RestfulResultSetMetaData.java | 187 - .../taosdata/jdbc/rs/RestfulStatement.java | 177 - .../jdbc/utils/HttpClientPoolUtil.java | 162 - .../com/taosdata/jdbc/utils/NullType.java | 91 - .../java/com/taosdata/jdbc/utils/OSUtils.java | 17 - .../jdbc/utils/SqlSyntaxValidator.java | 58 - .../com/taosdata/jdbc/utils/TaosInfo.java | 74 - .../taosdata/jdbc/utils/TaosInfoMBean.java | 13 - .../java/com/taosdata/jdbc/utils/Utils.java | 238 - .../META-INF/services/java.sql.Driver | 2 - .../java/com/taosdata/jdbc/SubscribeTest.java | 100 - .../com/taosdata/jdbc/TSDBConnectionTest.java | 437 -- .../jdbc/TSDBDatabaseMetaDataTest.java | 1107 ---- .../com/taosdata/jdbc/TSDBDriverTest.java | 172 - .../taosdata/jdbc/TSDBJNIConnectorTest.java | 150 - .../jdbc/TSDBParameterMetaDataTest.java | 199 - .../jdbc/TSDBPreparedStatementTest.java | 1244 ---- .../com/taosdata/jdbc/TSDBResultSetTest.java | 678 -- .../com/taosdata/jdbc/TSDBStatementTest.java | 390 -- .../jdbc/cases/AppMemoryLeakTest.java | 32 - .../jdbc/cases/AuthenticationTest.java | 109 - .../jdbc/cases/BadLocaleSettingTest.java | 59 - .../jdbc/cases/BatchErrorIgnoreTest.java | 144 - .../taosdata/jdbc/cases/BatchInsertTest.java | 116 - ...iTaosdByRestfulWithDifferentTokenTest.java | 58 - .../jdbc/cases/ConnectWrongDatabaseTest.java | 24 - .../jdbc/cases/DatetimeBefore1970Test.java | 80 - .../jdbc/cases/DoubleQuoteInSqlTest.java | 70 - .../jdbc/cases/DriverAutoloadTest.java | 43 - .../com/taosdata/jdbc/cases/FailOverTest.java | 39 - .../com/taosdata/jdbc/cases/ImportTest.java | 110 - .../jdbc/cases/InsertDbwithoutUseDbTest.java | 91 - .../cases/InsertSpecialCharacterJniTest.java | 434 -- .../InsertSpecialCharacterRestfulTest.java | 398 -- .../cases/InvalidResultSetPointerTest.java | 187 - .../cases/JDBCTypeAndTypeCompareTest.java | 34 - .../cases/MicroSecondPrecisionJNITest.java | 88 - .../MicroSecondPrecisionRestfulTest.java | 169 - .../MultiConnectionWithDifferentDbTest.java | 101 - .../MultiThreadsWithSameStatementTest.java | 85 - .../cases/NanoSecondTimestampJNITest.java | 182 - .../cases/NanoSecondTimestampRestfulTest.java | 182 - .../cases/NullValueInResultSetJNITest.java | 59 - .../NullValueInResultSetRestfulTest.java | 62 - .../jdbc/cases/NullValueInResultSetTest.java | 91 - .../PreparedStatementBatchInsertJNITest.java | 98 - ...eparedStatementBatchInsertRestfulTest.java | 98 - .../taosdata/jdbc/cases/QueryDataTest.java | 71 - .../jdbc/cases/ResetQueryCacheTest.java | 49 - ...sultSetMetaShouldNotBeNullRestfulTest.java | 86 - .../com/taosdata/jdbc/cases/SelectTest.java | 80 - .../com/taosdata/jdbc/cases/StableTest.java | 104 - .../jdbc/cases/TaosInfoMonitorTest.java | 49 - .../com/taosdata/jdbc/cases/TimeZoneTest.java | 71 - .../TimestampPrecisionInNanoInJniTest.java | 570 -- .../TimestampPrecisonInNanoRestTest.java | 570 -- .../jdbc/cases/UnsignedNumberJniTest.java | 175 - .../jdbc/cases/UnsignedNumberRestfulTest.java | 176 - .../jdbc/cases/UseNowInsertTimestampTest.java | 84 - .../jdbc/rs/DatabaseSpecifiedTest.java | 69 - .../jdbc/rs/RestfulConnectionTest.java | 405 -- .../jdbc/rs/RestfulDatabaseMetaDataTest.java | 1114 ---- .../taosdata/jdbc/rs/RestfulDriverTest.java | 47 - .../com/taosdata/jdbc/rs/RestfulJDBCTest.java | 160 - .../jdbc/rs/RestfulParameterMetaDataTest.java | 195 - .../jdbc/rs/RestfulPreparedStatementTest.java | 410 -- .../jdbc/rs/RestfulResultSetMetaDataTest.java | 220 - .../jdbc/rs/RestfulResultSetTest.java | 693 -- .../jdbc/rs/RestfulStatementTest.java | 415 -- .../java/com/taosdata/jdbc/rs/SQLTest.java | 592 -- .../com/taosdata/jdbc/utils/OSUtilsTest.java | 30 - .../taosdata/jdbc/utils/TimestampUtil.java | 24 - .../com/taosdata/jdbc/utils/UtilsTest.java | 140 - .../connector/nodejs/nodetaos/cinterface.js | 609 -- .../connector/nodejs/nodetaos/connection.js | 84 - .../connector/nodejs/nodetaos/constants.js | 76 - 2.0/src/connector/nodejs/nodetaos/cursor.js | 476 -- 2.0/src/connector/nodejs/nodetaos/error.js | 96 - .../connector/nodejs/nodetaos/globalfunc.js | 14 - .../connector/nodejs/nodetaos/taosobjects.js | 152 - .../connector/nodejs/nodetaos/taosquery.js | 112 - .../connector/nodejs/nodetaos/taosresult.js | 85 - 2.0/src/connector/nodejs/package.json | 34 - 2.0/src/connector/nodejs/readme.md | 161 - 2.0/src/connector/nodejs/tdengine.js | 4 - 2.0/src/connector/nodejs/test/performance.js | 89 - 2.0/src/connector/nodejs/test/test.js | 170 - .../connector/nodejs/test/testMicroseconds.js | 49 - .../connector/nodejs/test/testNanoseconds.js | 49 - .../connector/nodejs/test/testSubscribe.js | 16 - 2.0/src/connector/nodejs/test/testnchar.js | 33 - 2.0/src/connector/odbc/.gitignore | 3 - 2.0/src/connector/odbc/CMakeLists.txt | 90 - 2.0/src/connector/odbc/README.cn.md | 169 - 2.0/src/connector/odbc/README.md | 158 - .../connector/odbc/examples/CMakeLists.txt | 4 - .../connector/odbc/examples/c/CMakeLists.txt | 22 - 2.0/src/connector/odbc/examples/c/main.c | 1056 --- 2.0/src/connector/odbc/examples/c/main.cpp | 654 -- 2.0/src/connector/odbc/examples/go/odbc.go | 99 - 2.0/src/connector/odbc/examples/js/.gitignore | 0 2.0/src/connector/odbc/examples/js/odbc.js | 122 - .../connector/odbc/examples/js/package.json | 5 - 2.0/src/connector/odbc/examples/lua/odbc.lua | 48 - 2.0/src/connector/odbc/examples/py/odbc.py | 111 - .../connector/odbc/examples/rust/.gitignore | 1 - .../odbc/examples/rust/main/Cargo.toml | 12 - .../odbc/examples/rust/main/src/main.rs | 49 - .../connector/odbc/samples/create_data.stmts | 17 - .../connector/odbc/samples/query_data.stmts | 1 - 2.0/src/connector/odbc/samples/select.stmts | 4 - 2.0/src/connector/odbc/samples/simples.stmts | 44 - 2.0/src/connector/odbc/src/CMakeLists.txt | 80 - 2.0/src/connector/odbc/src/base.c | 2713 -------- 2.0/src/connector/odbc/src/base.h | 77 - .../connector/odbc/src/base/CMakeLists.txt | 10 - 2.0/src/connector/odbc/src/base/conn.c | 223 - 2.0/src/connector/odbc/src/base/conn.h | 81 - 2.0/src/connector/odbc/src/base/env.c | 117 - 2.0/src/connector/odbc/src/base/env.h | 43 - 2.0/src/connector/odbc/src/base/err.c | 177 - 2.0/src/connector/odbc/src/base/err.h | 35 - 2.0/src/connector/odbc/src/base/field.c | 78 - 2.0/src/connector/odbc/src/base/field.h | 77 - 2.0/src/connector/odbc/src/base/null_conn.c | 115 - 2.0/src/connector/odbc/src/base/null_conn.h | 33 - 2.0/src/connector/odbc/src/base/param.c | 89 - 2.0/src/connector/odbc/src/base/param.h | 71 - 2.0/src/connector/odbc/src/base/rs.c | 18 - 2.0/src/connector/odbc/src/base/rs.h | 29 - 2.0/src/connector/odbc/src/base/stmt.c | 465 -- 2.0/src/connector/odbc/src/base/stmt.h | 143 - 2.0/src/connector/odbc/src/base/tsdb_impl.c | 2598 -------- 2.0/src/connector/odbc/src/base/tsdb_impl.h | 30 - 2.0/src/connector/odbc/src/col.h | 28 - 2.0/src/connector/odbc/src/install.cmd | 6 - 2.0/src/connector/odbc/src/install.sh | 46 - 2.0/src/connector/odbc/src/todbc.def | 68 - 2.0/src/connector/odbc/src/todbc.rc.in | 31 - 2.0/src/connector/odbc/src/todbc.rsp | 5 - 2.0/src/connector/odbc/src/todbc_buf.c | 410 -- 2.0/src/connector/odbc/src/todbc_buf.h | 38 - 2.0/src/connector/odbc/src/todbc_flex.h | 60 - 2.0/src/connector/odbc/src/todbc_hash.c | 195 - 2.0/src/connector/odbc/src/todbc_hash.h | 53 - 2.0/src/connector/odbc/src/todbc_iconv.c | 682 -- 2.0/src/connector/odbc/src/todbc_iconv.h | 114 - 2.0/src/connector/odbc/src/todbc_list.c | 256 - 2.0/src/connector/odbc/src/todbc_list.h | 53 - 2.0/src/connector/odbc/src/todbc_log.c | 94 - 2.0/src/connector/odbc/src/todbc_log.h | 52 - 2.0/src/connector/odbc/src/todbc_scanner.l | 280 - 2.0/src/connector/odbc/src/todbc_string.c | 218 - 2.0/src/connector/odbc/src/todbc_string.h | 54 - 2.0/src/connector/odbc/src/todbc_tls.c | 250 - 2.0/src/connector/odbc/src/todbc_tls.h | 56 - 2.0/src/connector/odbc/src/todbc_util.c | 662 -- 2.0/src/connector/odbc/src/todbc_util.h | 46 - 2.0/src/connector/odbc/tools/CMakeLists.txt | 23 - 2.0/src/connector/odbc/tools/main.c | 165 - 2.0/src/connector/odbc/tools/tconv.c | 156 - 2.0/src/connector/python/.gitignore | 154 - 2.0/src/connector/python/LICENSE | 12 - 2.0/src/connector/python/README.md | 428 -- .../connector/python/examples/bind-multi.py | 50 - 2.0/src/connector/python/examples/bind-row.py | 57 - 2.0/src/connector/python/examples/demo.py | 12 - .../connector/python/examples/insert-lines.py | 22 - 2.0/src/connector/python/examples/pep-249.py | 9 - .../connector/python/examples/query-async.py | 62 - .../python/examples/query-objectively.py | 12 - .../python/examples/subscribe-async.py | 43 - .../python/examples/subscribe-sync.py | 53 - 2.0/src/connector/python/pyproject.toml | 27 - 2.0/src/connector/python/setup.py | 34 - 2.0/src/connector/python/taos/__init__.py | 486 -- 2.0/src/connector/python/taos/bind.py | 437 -- 2.0/src/connector/python/taos/cinterface.py | 900 --- 2.0/src/connector/python/taos/connection.py | 203 - 2.0/src/connector/python/taos/constants.py | 46 - 2.0/src/connector/python/taos/cursor.py | 267 - 2.0/src/connector/python/taos/error.py | 96 - 2.0/src/connector/python/taos/field.py | 302 - 2.0/src/connector/python/taos/precision.py | 12 - 2.0/src/connector/python/taos/result.py | 245 - 2.0/src/connector/python/taos/statement.py | 85 - 2.0/src/connector/python/taos/stream.py | 22 - 2.0/src/connector/python/taos/subscription.py | 49 - 2.0/src/connector/python/taos/timestamp.py | 17 - 2.0/src/connector/python/tests/test-td6231.py | 50 - 2.0/src/connector/python/tests/test_ctaos.py | 162 - 2.0/src/connector/python/tests/test_info.py | 23 - 2.0/src/connector/python/tests/test_lines.py | 57 - 2.0/src/connector/python/tests/test_query.py | 43 - .../connector/python/tests/test_query_a.py | 66 - 2.0/src/connector/python/tests/test_stmt.py | 149 - 2.0/src/connector/python/tests/test_stream.py | 70 - .../connector/python/tests/test_subscribe.py | 100 - .../comparisonTest/cassandra/application.conf | 5 - .../cassandra/cassandratest/pom.xml | 131 - .../com/cassandra/test/CassandraTest.java | 200 - .../java/com/cassandra/test/WriteThread.java | 99 - 2.0/tests/comparisonTest/cassandra/q1.txt | 11 - 2.0/tests/comparisonTest/cassandra/q2.txt | 50 - 2.0/tests/comparisonTest/cassandra/q3.txt | 10 - 2.0/tests/comparisonTest/cassandra/q4.txt | 10 - .../com/taosdata/generator/DataGenerator.java | 156 - 2.0/tests/comparisonTest/influxdb/main.go | 296 - 2.0/tests/comparisonTest/influxdb/q1.txt | 10 - 2.0/tests/comparisonTest/influxdb/q2.txt | 60 - 2.0/tests/comparisonTest/influxdb/q3.txt | 10 - 2.0/tests/comparisonTest/influxdb/q4.txt | 10 - .../opentsdb/opentsdbtest/pom.xml | 285 - .../java/com/opentsdb/test/OpentsdbTest.java | 473 -- .../java/com/opentsdb/test/WriteThread.java | 154 - .../src/main/resources/logback.xml | 61 - .../comparisonTest/tdengine/CMakeLists.txt | 12 - 2.0/tests/comparisonTest/tdengine/makefile | 14 - 2.0/tests/comparisonTest/tdengine/q1.txt | 11 - 2.0/tests/comparisonTest/tdengine/q2.txt | 61 - 2.0/tests/comparisonTest/tdengine/q3.txt | 11 - 2.0/tests/comparisonTest/tdengine/q4.txt | 11 - 2.0/tests/comparisonTest/tdengine/q5.txt | 1 - .../comparisonTest/tdengine/tdengineTest.c | 455 -- .../C#Test/nanosupport/TDengineDriver.cs | 170 - .../C#Test/nanosupport/nanotest.cs | 502 -- .../nodejsTest/nanosupport/nanosecondTest.js | 290 - .../nodejsTest/nodetaos/cinterface.js | 587 -- .../nodejsTest/nodetaos/connection.js | 84 - .../nodejsTest/nodetaos/constants.js | 76 - .../nodejsTest/nodetaos/cursor.js | 476 -- .../nodejsTest/nodetaos/error.js | 96 - .../nodejsTest/nodetaos/globalfunc.js | 14 - .../nodejsTest/nodetaos/taosobjects.js | 152 - .../nodejsTest/nodetaos/taosquery.js | 112 - .../nodejsTest/nodetaos/taosresult.js | 85 - 2.0/tests/connectorTest/nodejsTest/readme.md | 161 - .../connectorTest/nodejsTest/tdengine.js | 4 - .../nodejsTest/test/performance.js | 89 - .../connectorTest/nodejsTest/test/test.js | 170 - .../nodejsTest/test/testMicroseconds.js | 49 - .../nodejsTest/test/testNanoseconds.js | 49 - .../nodejsTest/test/testSubscribe.js | 16 - .../odbcTest/nanosupport/nanoTest_odbc.py | 111 - .../odbcTest/nanosupport/odbc.go | 84 - .../odbcTest/nanosupport/odbc.py | 115 - 2.0/tests/fuzz/sql-fuzzer.c | 15 - 2.0/tests/gotest/batchtest.bat | 28 - 2.0/tests/gotest/batchtest.sh | 22 - 2.0/tests/gotest/case001/case001.bat | 9 - 2.0/tests/gotest/case001/case001.go | 344 - 2.0/tests/gotest/case001/case001.sh | 21 - 2.0/tests/gotest/case002/case002.bat | 9 - 2.0/tests/gotest/case002/case002.go | 80 - 2.0/tests/gotest/case002/case002.sh | 22 - .../gotest/nanosupport/connector/executor.go | 208 - 2.0/tests/gotest/nanosupport/nanoCase.bat | 9 - 2.0/tests/gotest/nanosupport/nanoCase.sh | 22 - 2.0/tests/gotest/nanosupport/nanosupport.go | 269 - 2.0/tests/gotest/test.sh | 42 - 2.0/tests/http/restful/http_create_db.c | 429 -- 2.0/tests/http/restful/http_create_tb.c | 433 -- 2.0/tests/http/restful/http_drop_db.c | 433 -- 2.0/tests/http/restful/http_insert_tb.c | 455 -- 2.0/tests/http/restful/http_query_tb.c | 432 -- 2.0/tests/http/restful/http_use_db.c | 430 -- 2.0/tests/nettest/FQDNnettest.sh | 3 - 2.0/tests/nettest/TCPUDP.sh | 12 - 2.0/tests/nettest/fqdn.sh | 3 - 2.0/tests/nettest/tcpudp.sh | 12 - .../perftest-scripts/cassandraTestQ1Loop.sh | 101 - .../perftest-scripts/cassandraTestQ2Loop.sh | 278 - .../perftest-scripts/cassandraTestQ3Loop.sh | 98 - .../perftest-scripts/cassandraTestQ4Loop.sh | 123 - .../cassandraTestWriteLoop.sh | 101 - 2.0/tests/perftest-scripts/coverage_test.sh | 217 - 2.0/tests/perftest-scripts/full_test.sh | 191 - .../perftest-scripts/influxdbTestQ1Loop.sh | 97 - .../perftest-scripts/influxdbTestQ2Loop.sh | 318 - .../perftest-scripts/influxdbTestQ3Loop.sh | 94 - .../perftest-scripts/influxdbTestQ4Loop.sh | 101 - .../perftest-scripts/influxdbTestWriteLoop.sh | 104 - .../perftest-scripts/opentsdbTestQ1Loop.sh | 99 - .../perftest-scripts/opentsdbTestQ2Loop.sh | 276 - .../perftest-scripts/opentsdbTestQ3Loop.sh | 96 - .../perftest-scripts/opentsdbTestQ4Loop.sh | 103 - .../perftest-scripts/opentsdbTestWriteLoop.sh | 99 - .../perftest-consistent-inserting-data.sh | 43 - .../perftest-scripts/perftest-csv2png.gnuplot | 33 - 2.0/tests/perftest-scripts/perftest-daily.sh | 210 - 2.0/tests/perftest-scripts/perftest-query.sh | 152 - .../perftest-taosdemo-compare.sh | 147 - .../perftest-scripts/perftest-taosdemo.sh | 128 - .../perftest-tsdb-compare-13d.sh | 87 - .../perftest-tsdb-compare-1d.sh | 87 - .../perftest-tsdb-compare-var10k-int100s.sh | 87 - .../perftest-tsdb-compare-var10k-int10s.sh | 87 - 2.0/tests/perftest-scripts/run-csv.sh | 209 - .../perftest-scripts/runInfluxdb-13d-csv.sh | 126 - 2.0/tests/perftest-scripts/runInfluxdb.sh | 251 - 2.0/tests/perftest-scripts/runTDengine.sh | 283 - 2.0/tests/perftest-scripts/runreal-13d-csv.sh | 149 - 2.0/tests/perftest-scripts/runreal-1d-csv.sh | 149 - .../perftest-scripts/taosdemo-csv2png.gnuplot | 26 - .../taosdemo-rps-csv2png.gnuplot | 24 - .../perftest-scripts/tdengineTestQ1Loop.sh | 127 - .../perftest-scripts/tdengineTestQ2Loop.sh | 348 - .../perftest-scripts/tdengineTestQ3Loop.sh | 124 - .../perftest-scripts/tdengineTestQ4Loop.sh | 124 - .../perftest-scripts/tdengineTestQ5Loop.sh | 107 - .../perftest-scripts/tdengineTestWriteLoop.sh | 172 - .../tdinternal_coverage_test.sh | 193 - 2.0/tests/perftest-scripts/tdinternal_test.sh | 179 - 2.0/tests/robust/cluster.sh | 334 - 2.0/tests/robust/makefile | 8 - 2.0/tests/robust/monitor.sh | 8 - 2.0/tests/robust/robust.c | 260 - 2.0/tests/stress/.gitignore | 3 - 2.0/tests/stress/README.md | 80 - 2.0/tests/stress/go.mod | 7 - 2.0/tests/stress/main.go | 421 -- 639 files changed, 115108 deletions(-) delete mode 100755 2.0/CMakeLists.txt delete mode 100644 2.0/documentation/tdenginedocs-cn/administrator/index.html delete mode 100644 2.0/documentation/tdenginedocs-cn/advanced-features/index.html delete mode 100644 2.0/documentation/tdenginedocs-cn/assets/Picture2.png delete mode 100644 2.0/documentation/tdenginedocs-cn/assets/clip_image001-2474914.png delete mode 100644 2.0/documentation/tdenginedocs-cn/assets/clip_image001-2474939.png delete mode 100644 2.0/documentation/tdenginedocs-cn/assets/clip_image001-2474961.png delete mode 100644 2.0/documentation/tdenginedocs-cn/assets/clip_image001-2474987.png delete mode 100644 2.0/documentation/tdenginedocs-cn/assets/clip_image001.png delete mode 100644 2.0/documentation/tdenginedocs-cn/assets/fig1.png delete mode 100644 2.0/documentation/tdenginedocs-cn/assets/fig2.png delete mode 100644 2.0/documentation/tdenginedocs-cn/assets/image-20190707124650780.png delete mode 100644 2.0/documentation/tdenginedocs-cn/assets/image-20190707124818590.png delete mode 100644 2.0/documentation/tdenginedocs-cn/assets/nodes.png delete mode 100644 2.0/documentation/tdenginedocs-cn/assets/structure.png delete mode 100644 2.0/documentation/tdenginedocs-cn/assets/vnode.png delete mode 100644 2.0/documentation/tdenginedocs-cn/assets/write_process.png delete mode 100644 2.0/documentation/tdenginedocs-cn/connections-with-other-tools/index.html delete mode 100644 2.0/documentation/tdenginedocs-cn/connector/index.html delete mode 100644 2.0/documentation/tdenginedocs-cn/data-model-and-architecture/index.html delete mode 100644 2.0/documentation/tdenginedocs-cn/faq/index.html delete mode 100644 2.0/documentation/tdenginedocs-cn/getting-started/index.html delete mode 100644 2.0/documentation/tdenginedocs-cn/index.html delete mode 100644 2.0/documentation/tdenginedocs-cn/lib/bootstrap.min.css delete mode 100644 2.0/documentation/tdenginedocs-cn/lib/docs/docs.css delete mode 100644 2.0/documentation/tdenginedocs-cn/lib/docs/liner.js delete mode 100644 2.0/documentation/tdenginedocs-cn/lib/docs/prettify.js delete mode 100644 2.0/documentation/tdenginedocs-cn/lib/docs/prettyprint-sql.js delete mode 100644 2.0/documentation/tdenginedocs-cn/lib/docs/prettyprint-term.js delete mode 100644 2.0/documentation/tdenginedocs-cn/lib/docs/taosdataprettify.css delete mode 100644 2.0/documentation/tdenginedocs-cn/lib/jquery-3.4.1.min.js delete mode 100644 2.0/documentation/tdenginedocs-cn/more-on-system-architecture/index.html delete mode 100644 2.0/documentation/tdenginedocs-cn/styles/base.css delete mode 100644 2.0/documentation/tdenginedocs-cn/styles/base.min.css delete mode 100644 2.0/documentation/tdenginedocs-cn/super-table/index.html delete mode 100644 2.0/documentation/tdenginedocs-cn/taos-sql/index.html delete mode 100644 2.0/documentation/tdenginedocs-en/administrator/index.html delete mode 100644 2.0/documentation/tdenginedocs-en/advanced-features/index.html delete mode 100644 2.0/documentation/tdenginedocs-en/assets/Picture2.png delete mode 100644 2.0/documentation/tdenginedocs-en/assets/clip_image001-2474914.png delete mode 100644 2.0/documentation/tdenginedocs-en/assets/clip_image001-2474939.png delete mode 100644 2.0/documentation/tdenginedocs-en/assets/clip_image001-2474961.png delete mode 100644 2.0/documentation/tdenginedocs-en/assets/clip_image001-2474987.png delete mode 100644 2.0/documentation/tdenginedocs-en/assets/clip_image001.png delete mode 100644 2.0/documentation/tdenginedocs-en/assets/fig1.png delete mode 100644 2.0/documentation/tdenginedocs-en/assets/fig2.png delete mode 100644 2.0/documentation/tdenginedocs-en/assets/image-20190707124650780.png delete mode 100644 2.0/documentation/tdenginedocs-en/assets/image-20190707124818590.png delete mode 100644 2.0/documentation/tdenginedocs-en/assets/nodes.png delete mode 100644 2.0/documentation/tdenginedocs-en/assets/structure.png delete mode 100644 2.0/documentation/tdenginedocs-en/assets/vnode.png delete mode 100644 2.0/documentation/tdenginedocs-en/assets/write_process.png delete mode 100644 2.0/documentation/tdenginedocs-en/connections-with-other-tools/index.html delete mode 100644 2.0/documentation/tdenginedocs-en/connector/index.html delete mode 100644 2.0/documentation/tdenginedocs-en/contributor_license_agreement/index.html delete mode 100644 2.0/documentation/tdenginedocs-en/data-model-and-architecture/index.html delete mode 100644 2.0/documentation/tdenginedocs-en/faq/index.html delete mode 100644 2.0/documentation/tdenginedocs-en/getting-started/index.html delete mode 100644 2.0/documentation/tdenginedocs-en/index.html delete mode 100644 2.0/documentation/tdenginedocs-en/lib/bootstrap.min.css delete mode 100644 2.0/documentation/tdenginedocs-en/lib/docs/docs.css delete mode 100644 2.0/documentation/tdenginedocs-en/lib/docs/liner.js delete mode 100644 2.0/documentation/tdenginedocs-en/lib/docs/prettify.js delete mode 100644 2.0/documentation/tdenginedocs-en/lib/docs/prettyprint-sql.js delete mode 100644 2.0/documentation/tdenginedocs-en/lib/docs/prettyprint-term.js delete mode 100644 2.0/documentation/tdenginedocs-en/lib/docs/taosdataprettify.css delete mode 100644 2.0/documentation/tdenginedocs-en/lib/jquery-3.4.1.min.js delete mode 100644 2.0/documentation/tdenginedocs-en/more-on-system-architecture/index.html delete mode 100644 2.0/documentation/tdenginedocs-en/styles/base.css delete mode 100644 2.0/documentation/tdenginedocs-en/styles/base.min.css delete mode 100644 2.0/documentation/tdenginedocs-en/super-table/index.html delete mode 100644 2.0/documentation/tdenginedocs-en/taos-sql/index.html delete mode 100644 2.0/documentation/webdocs/assets/Picture2.png delete mode 100644 2.0/documentation/webdocs/assets/add_datasource1.jpg delete mode 100644 2.0/documentation/webdocs/assets/add_datasource2.jpg delete mode 100644 2.0/documentation/webdocs/assets/add_datasource3.jpg delete mode 100644 2.0/documentation/webdocs/assets/add_datasource4.jpg delete mode 100644 2.0/documentation/webdocs/assets/create_dashboard1.jpg delete mode 100644 2.0/documentation/webdocs/assets/create_dashboard2.jpg delete mode 100644 2.0/documentation/webdocs/assets/fig1.png delete mode 100644 2.0/documentation/webdocs/assets/fig2.png delete mode 100644 2.0/documentation/webdocs/assets/image-20190707124650780.png delete mode 100644 2.0/documentation/webdocs/assets/image-20190707124818590.png delete mode 100644 2.0/documentation/webdocs/assets/import_dashboard1.jpg delete mode 100644 2.0/documentation/webdocs/assets/import_dashboard2.jpg delete mode 100644 2.0/documentation/webdocs/assets/nodes.png delete mode 100644 2.0/documentation/webdocs/assets/structure.png delete mode 100644 2.0/documentation/webdocs/assets/vnode.png delete mode 100644 2.0/documentation/webdocs/assets/write_process.png delete mode 100644 2.0/documentation/webdocs/markdowndocs/Connections with other Tools-ch.md delete mode 100644 2.0/documentation/webdocs/markdowndocs/Connections with other Tools.md delete mode 100644 2.0/documentation/webdocs/markdowndocs/Connector.md delete mode 100644 2.0/documentation/webdocs/markdowndocs/Contributor_License_Agreement.md delete mode 100644 2.0/documentation/webdocs/markdowndocs/Data model and architecture-ch.md delete mode 100644 2.0/documentation/webdocs/markdowndocs/Data model and architecture.md delete mode 100644 2.0/documentation/webdocs/markdowndocs/More on System Architecture-ch.md delete mode 100644 2.0/documentation/webdocs/markdowndocs/More on System Architecture.md delete mode 100644 2.0/documentation/webdocs/markdowndocs/Super Table-ch.md delete mode 100644 2.0/documentation/webdocs/markdowndocs/Super Table.md delete mode 100644 2.0/documentation/webdocs/markdowndocs/TAOS SQL-ch.md delete mode 100644 2.0/documentation/webdocs/markdowndocs/TAOS SQL.md delete mode 100644 2.0/documentation/webdocs/markdowndocs/administrator-ch.md delete mode 100644 2.0/documentation/webdocs/markdowndocs/administrator.md delete mode 100644 2.0/documentation/webdocs/markdowndocs/advanced features-ch.md delete mode 100644 2.0/documentation/webdocs/markdowndocs/advanced features.md delete mode 100644 2.0/documentation/webdocs/markdowndocs/connector-ch.md delete mode 100644 2.0/documentation20/cn/00.index/docs.md delete mode 100644 2.0/documentation20/cn/01.evaluation/docs.md delete mode 100644 2.0/documentation20/cn/02.getting-started/01.docker/docs.md delete mode 100644 2.0/documentation20/cn/02.getting-started/docs.md delete mode 100644 2.0/documentation20/cn/03.architecture/01.taosd/docs.md delete mode 100644 2.0/documentation20/cn/03.architecture/02.replica/docs.md delete mode 100644 2.0/documentation20/cn/03.architecture/docs.md delete mode 100644 2.0/documentation20/cn/04.model/docs.md delete mode 100644 2.0/documentation20/cn/05.insert/docs.md delete mode 100644 2.0/documentation20/cn/06.queries/docs.md delete mode 100644 2.0/documentation20/cn/07.advanced-features/docs.md delete mode 100644 2.0/documentation20/cn/08.connector/01.java/docs.md delete mode 100644 2.0/documentation20/cn/08.connector/docs.md delete mode 100644 2.0/documentation20/cn/09.connections/docs.md delete mode 100644 2.0/documentation20/cn/10.cluster/docs.md delete mode 100644 2.0/documentation20/cn/11.administrator/docs.md delete mode 100644 2.0/documentation20/cn/12.taos-sql/01.error-code/docs.md delete mode 100644 2.0/documentation20/cn/12.taos-sql/02.udf/docs.md delete mode 100644 2.0/documentation20/cn/12.taos-sql/docs.md delete mode 100644 2.0/documentation20/cn/13.faq/docs.md delete mode 100644 2.0/documentation20/cn/images/architecture/dnode.png delete mode 100644 2.0/documentation20/cn/images/architecture/message.png delete mode 100644 2.0/documentation20/cn/images/architecture/modules.png delete mode 100644 2.0/documentation20/cn/images/architecture/multi_tables.png delete mode 100644 2.0/documentation20/cn/images/architecture/replica-forward.png delete mode 100644 2.0/documentation20/cn/images/architecture/replica-master.png delete mode 100644 2.0/documentation20/cn/images/architecture/replica-restore.png delete mode 100644 2.0/documentation20/cn/images/architecture/structure.png delete mode 100644 2.0/documentation20/cn/images/architecture/vnode.png delete mode 100644 2.0/documentation20/cn/images/architecture/write_master.png delete mode 100644 2.0/documentation20/cn/images/architecture/write_slave.png delete mode 100644 2.0/documentation20/cn/images/connections/add_datasource1.jpg delete mode 100644 2.0/documentation20/cn/images/connections/add_datasource2.jpg delete mode 100644 2.0/documentation20/cn/images/connections/add_datasource3.jpg delete mode 100644 2.0/documentation20/cn/images/connections/add_datasource4.jpg delete mode 100644 2.0/documentation20/cn/images/connections/create_dashboard1.jpg delete mode 100644 2.0/documentation20/cn/images/connections/create_dashboard2.jpg delete mode 100644 2.0/documentation20/cn/images/connections/import_dashboard1.jpg delete mode 100644 2.0/documentation20/cn/images/connections/import_dashboard2.jpg delete mode 100644 2.0/documentation20/cn/images/connector.png delete mode 100644 2.0/documentation20/cn/images/eco_system.png delete mode 100644 2.0/documentation20/cn/images/tdengine-jdbc-connector.png delete mode 100644 2.0/documentation20/en/00.index/docs.md delete mode 100644 2.0/documentation20/en/01.evaluation/docs.md delete mode 100644 2.0/documentation20/en/02.getting-started/01.docker/docs.md delete mode 100644 2.0/documentation20/en/02.getting-started/docs.md delete mode 100644 2.0/documentation20/en/03.architecture/docs.md delete mode 100644 2.0/documentation20/en/04.model/docs.md delete mode 100644 2.0/documentation20/en/05.insert/docs.md delete mode 100644 2.0/documentation20/en/06.queries/docs.md delete mode 100644 2.0/documentation20/en/07.advanced-features/docs.md delete mode 100644 2.0/documentation20/en/08.connector/01.java/docs.md delete mode 100644 2.0/documentation20/en/08.connector/docs.md delete mode 100644 2.0/documentation20/en/09.connections/docs.md delete mode 100644 2.0/documentation20/en/10.cluster/docs.md delete mode 100644 2.0/documentation20/en/11.administrator/docs.md delete mode 100644 2.0/documentation20/en/12.taos-sql/docs.md delete mode 100644 2.0/documentation20/en/13.faq/docs.md delete mode 100644 2.0/documentation20/en/images/architecture/dnode.png delete mode 100644 2.0/documentation20/en/images/architecture/message.png delete mode 100644 2.0/documentation20/en/images/architecture/modules.png delete mode 100644 2.0/documentation20/en/images/architecture/multi_tables.png delete mode 100644 2.0/documentation20/en/images/architecture/replica-forward.png delete mode 100644 2.0/documentation20/en/images/architecture/replica-master.png delete mode 100644 2.0/documentation20/en/images/architecture/replica-restore.png delete mode 100644 2.0/documentation20/en/images/architecture/structure.png delete mode 100644 2.0/documentation20/en/images/architecture/vnode.png delete mode 100644 2.0/documentation20/en/images/architecture/write_master.png delete mode 100644 2.0/documentation20/en/images/architecture/write_slave.png delete mode 100644 2.0/documentation20/en/images/connections/add_datasource1.jpg delete mode 100644 2.0/documentation20/en/images/connections/add_datasource2.jpg delete mode 100644 2.0/documentation20/en/images/connections/add_datasource3.jpg delete mode 100644 2.0/documentation20/en/images/connections/add_datasource4.jpg delete mode 100644 2.0/documentation20/en/images/connections/create_dashboard1.jpg delete mode 100644 2.0/documentation20/en/images/connections/create_dashboard2.jpg delete mode 100644 2.0/documentation20/en/images/connections/import_dashboard1.jpg delete mode 100644 2.0/documentation20/en/images/connections/import_dashboard2.jpg delete mode 100644 2.0/documentation20/en/images/connector.png delete mode 100644 2.0/documentation20/en/images/eco_system.png delete mode 100644 2.0/documentation20/en/images/tdengine-jdbc-connector.png delete mode 100644 2.0/importSampleData/.gitignore delete mode 100644 2.0/importSampleData/LICENSE delete mode 100644 2.0/importSampleData/README.md delete mode 100644 2.0/importSampleData/app/main.go delete mode 100644 2.0/importSampleData/config/cfg.toml delete mode 100644 2.0/importSampleData/dashboard/sensor_info.json delete mode 100644 2.0/importSampleData/data/camera_detection.json delete mode 100644 2.0/importSampleData/data/sensor_info.csv delete mode 100644 2.0/importSampleData/go.mod delete mode 100644 2.0/importSampleData/import/import_config.go delete mode 100644 2.0/minidevops/README.MD delete mode 100644 2.0/minidevops/demodashboard.json delete mode 100644 2.0/minidevops/grafana/tdengine/README.md delete mode 100644 2.0/minidevops/grafana/tdengine/css/query-editor.css delete mode 100644 2.0/minidevops/grafana/tdengine/datasource.js delete mode 100644 2.0/minidevops/grafana/tdengine/img/taosdata_logo.png delete mode 100644 2.0/minidevops/grafana/tdengine/module.js delete mode 100644 2.0/minidevops/grafana/tdengine/partials/config.html delete mode 100644 2.0/minidevops/grafana/tdengine/partials/query.editor.html delete mode 100644 2.0/minidevops/grafana/tdengine/plugin.json delete mode 100644 2.0/minidevops/grafana/tdengine/query_ctrl.js delete mode 100644 2.0/minidevops/prometheus/prometheus.yml delete mode 100755 2.0/minidevops/run.sh delete mode 100644 2.0/minidevops/taos/taos.cfg delete mode 100644 2.0/minidevops/telegraf/telegraf.conf delete mode 100644 2.0/packaging/cfg/taos.cfg delete mode 100755 2.0/packaging/check_package.sh delete mode 100644 2.0/packaging/deb/DEBIAN/control delete mode 100644 2.0/packaging/deb/DEBIAN/postinst delete mode 100644 2.0/packaging/deb/DEBIAN/postrm delete mode 100644 2.0/packaging/deb/DEBIAN/preinst delete mode 100644 2.0/packaging/deb/DEBIAN/prerm delete mode 100755 2.0/packaging/deb/makedeb.sh delete mode 100644 2.0/packaging/deb/powerd delete mode 100644 2.0/packaging/deb/taosd delete mode 100644 2.0/packaging/deb/tarbitratord delete mode 100644 2.0/packaging/docker/Dockerfile delete mode 100755 2.0/packaging/docker/dockerManifest.sh delete mode 100755 2.0/packaging/docker/dockerbuild.sh delete mode 100755 2.0/packaging/docker/dockerbuildi.sh delete mode 100755 2.0/packaging/release.sh delete mode 100755 2.0/packaging/rpm/makerpm.sh delete mode 100644 2.0/packaging/rpm/powerd delete mode 100644 2.0/packaging/rpm/taosd delete mode 100644 2.0/packaging/rpm/tarbitratord delete mode 100644 2.0/packaging/rpm/tdengine.spec delete mode 100755 2.0/packaging/tools/check_os.sh delete mode 100755 2.0/packaging/tools/get_client.sh delete mode 100755 2.0/packaging/tools/get_os.sh delete mode 100755 2.0/packaging/tools/get_version.sh delete mode 100755 2.0/packaging/tools/install.sh delete mode 100755 2.0/packaging/tools/install_arbi.sh delete mode 100755 2.0/packaging/tools/install_arbi_power.sh delete mode 100755 2.0/packaging/tools/install_arbi_tq.sh delete mode 100755 2.0/packaging/tools/install_client.sh delete mode 100755 2.0/packaging/tools/install_client_power.sh delete mode 100755 2.0/packaging/tools/install_client_tq.sh delete mode 100755 2.0/packaging/tools/install_power.sh delete mode 100755 2.0/packaging/tools/install_tq.sh delete mode 100755 2.0/packaging/tools/make_install.sh delete mode 100755 2.0/packaging/tools/makearbi.sh delete mode 100755 2.0/packaging/tools/makearbi_power.sh delete mode 100755 2.0/packaging/tools/makearbi_tq.sh delete mode 100755 2.0/packaging/tools/makeclient.sh delete mode 100755 2.0/packaging/tools/makeclient_power.sh delete mode 100755 2.0/packaging/tools/makeclient_tq.sh delete mode 100755 2.0/packaging/tools/makepkg.sh delete mode 100755 2.0/packaging/tools/makepkg_power.sh delete mode 100755 2.0/packaging/tools/makepkg_tq.sh delete mode 100755 2.0/packaging/tools/post.sh delete mode 100755 2.0/packaging/tools/preun.sh delete mode 100644 2.0/packaging/tools/release_note delete mode 100755 2.0/packaging/tools/remove.sh delete mode 100755 2.0/packaging/tools/remove_arbi.sh delete mode 100755 2.0/packaging/tools/remove_arbi_power.sh delete mode 100755 2.0/packaging/tools/remove_arbi_tq.sh delete mode 100755 2.0/packaging/tools/remove_client.sh delete mode 100755 2.0/packaging/tools/remove_client_power.sh delete mode 100755 2.0/packaging/tools/remove_client_tq.sh delete mode 100755 2.0/packaging/tools/remove_power.sh delete mode 100755 2.0/packaging/tools/remove_tq.sh delete mode 100755 2.0/packaging/tools/repair_link.sh delete mode 100755 2.0/packaging/tools/set_core.sh delete mode 100755 2.0/packaging/tools/startPre.sh delete mode 100644 2.0/packaging/tools/taosd-dump-cfg.gdb delete mode 100644 2.0/snap/gui/t-dengine.svg delete mode 100755 2.0/snap/hooks/install delete mode 100755 2.0/snap/local/launcher.sh delete mode 100755 2.0/snap/local/taoswrapper.sh delete mode 100644 2.0/snap/snapcraft.yaml delete mode 100644 2.0/src/connector/C#/TDengineDriver.cs delete mode 100644 2.0/src/connector/jdbc/CMakeLists.txt delete mode 100755 2.0/src/connector/jdbc/deploy-pom.xml delete mode 100644 2.0/src/connector/jdbc/pom.xml delete mode 100644 2.0/src/connector/jdbc/readme.md delete mode 100644 2.0/src/connector/jdbc/src/main/assembly/assembly-jar.xml delete mode 100755 2.0/src/connector/jdbc/src/main/assembly/assembly.xml delete mode 100644 2.0/src/connector/jdbc/src/main/java/com/taosdata/jdbc/AbstractConnection.java delete mode 100644 2.0/src/connector/jdbc/src/main/java/com/taosdata/jdbc/AbstractDatabaseMetaData.java delete mode 100644 2.0/src/connector/jdbc/src/main/java/com/taosdata/jdbc/AbstractDriver.java delete mode 100644 2.0/src/connector/jdbc/src/main/java/com/taosdata/jdbc/AbstractParameterMetaData.java delete mode 100644 2.0/src/connector/jdbc/src/main/java/com/taosdata/jdbc/AbstractResultSet.java delete mode 100644 2.0/src/connector/jdbc/src/main/java/com/taosdata/jdbc/AbstractStatement.java delete mode 100644 2.0/src/connector/jdbc/src/main/java/com/taosdata/jdbc/ColumnMetaData.java delete mode 100644 2.0/src/connector/jdbc/src/main/java/com/taosdata/jdbc/DatabaseMetaDataResultSet.java delete mode 100644 2.0/src/connector/jdbc/src/main/java/com/taosdata/jdbc/EmptyResultSet.java delete mode 100644 2.0/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBConnection.java delete mode 100644 2.0/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBConstants.java delete mode 100644 2.0/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBDatabaseMetaData.java delete mode 100755 2.0/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBDriver.java delete mode 100644 2.0/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBError.java delete mode 100644 2.0/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBErrorNumbers.java delete mode 100755 2.0/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBJNIConnector.java delete mode 100644 2.0/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBParameterMetaData.java delete mode 100644 2.0/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBPreparedStatement.java delete mode 100644 2.0/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBResultSet.java delete mode 100644 2.0/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBResultSetBlockData.java delete mode 100644 2.0/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBResultSetMetaData.java delete mode 100644 2.0/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBResultSetRowData.java delete mode 100644 2.0/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBResultSetWrapper.java delete mode 100644 2.0/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBStatement.java delete mode 100644 2.0/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBSubscribe.java delete mode 100644 2.0/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TaosGlobalConfig.java delete mode 100644 2.0/src/connector/jdbc/src/main/java/com/taosdata/jdbc/WrapperImpl.java delete mode 100644 2.0/src/connector/jdbc/src/main/java/com/taosdata/jdbc/enums/TimestampFormat.java delete mode 100644 2.0/src/connector/jdbc/src/main/java/com/taosdata/jdbc/enums/TimestampPrecision.java delete mode 100644 2.0/src/connector/jdbc/src/main/java/com/taosdata/jdbc/rs/RestfulConnection.java delete mode 100644 2.0/src/connector/jdbc/src/main/java/com/taosdata/jdbc/rs/RestfulDatabaseMetaData.java delete mode 100644 2.0/src/connector/jdbc/src/main/java/com/taosdata/jdbc/rs/RestfulDriver.java delete mode 100644 2.0/src/connector/jdbc/src/main/java/com/taosdata/jdbc/rs/RestfulParameterMetaData.java delete mode 100644 2.0/src/connector/jdbc/src/main/java/com/taosdata/jdbc/rs/RestfulPreparedStatement.java delete mode 100644 2.0/src/connector/jdbc/src/main/java/com/taosdata/jdbc/rs/RestfulResultSet.java delete mode 100644 2.0/src/connector/jdbc/src/main/java/com/taosdata/jdbc/rs/RestfulResultSetMetaData.java delete mode 100644 2.0/src/connector/jdbc/src/main/java/com/taosdata/jdbc/rs/RestfulStatement.java delete mode 100644 2.0/src/connector/jdbc/src/main/java/com/taosdata/jdbc/utils/HttpClientPoolUtil.java delete mode 100755 2.0/src/connector/jdbc/src/main/java/com/taosdata/jdbc/utils/NullType.java delete mode 100644 2.0/src/connector/jdbc/src/main/java/com/taosdata/jdbc/utils/OSUtils.java delete mode 100644 2.0/src/connector/jdbc/src/main/java/com/taosdata/jdbc/utils/SqlSyntaxValidator.java delete mode 100644 2.0/src/connector/jdbc/src/main/java/com/taosdata/jdbc/utils/TaosInfo.java delete mode 100644 2.0/src/connector/jdbc/src/main/java/com/taosdata/jdbc/utils/TaosInfoMBean.java delete mode 100644 2.0/src/connector/jdbc/src/main/java/com/taosdata/jdbc/utils/Utils.java delete mode 100644 2.0/src/connector/jdbc/src/main/resources/META-INF/services/java.sql.Driver delete mode 100644 2.0/src/connector/jdbc/src/test/java/com/taosdata/jdbc/SubscribeTest.java delete mode 100644 2.0/src/connector/jdbc/src/test/java/com/taosdata/jdbc/TSDBConnectionTest.java delete mode 100644 2.0/src/connector/jdbc/src/test/java/com/taosdata/jdbc/TSDBDatabaseMetaDataTest.java delete mode 100644 2.0/src/connector/jdbc/src/test/java/com/taosdata/jdbc/TSDBDriverTest.java delete mode 100644 2.0/src/connector/jdbc/src/test/java/com/taosdata/jdbc/TSDBJNIConnectorTest.java delete mode 100644 2.0/src/connector/jdbc/src/test/java/com/taosdata/jdbc/TSDBParameterMetaDataTest.java delete mode 100644 2.0/src/connector/jdbc/src/test/java/com/taosdata/jdbc/TSDBPreparedStatementTest.java delete mode 100644 2.0/src/connector/jdbc/src/test/java/com/taosdata/jdbc/TSDBResultSetTest.java delete mode 100644 2.0/src/connector/jdbc/src/test/java/com/taosdata/jdbc/TSDBStatementTest.java delete mode 100644 2.0/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/AppMemoryLeakTest.java delete mode 100644 2.0/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/AuthenticationTest.java delete mode 100644 2.0/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/BadLocaleSettingTest.java delete mode 100644 2.0/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/BatchErrorIgnoreTest.java delete mode 100644 2.0/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/BatchInsertTest.java delete mode 100644 2.0/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/ConnectMultiTaosdByRestfulWithDifferentTokenTest.java delete mode 100644 2.0/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/ConnectWrongDatabaseTest.java delete mode 100644 2.0/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/DatetimeBefore1970Test.java delete mode 100644 2.0/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/DoubleQuoteInSqlTest.java delete mode 100644 2.0/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/DriverAutoloadTest.java delete mode 100644 2.0/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/FailOverTest.java delete mode 100644 2.0/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/ImportTest.java delete mode 100644 2.0/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/InsertDbwithoutUseDbTest.java delete mode 100644 2.0/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/InsertSpecialCharacterJniTest.java delete mode 100644 2.0/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/InsertSpecialCharacterRestfulTest.java delete mode 100644 2.0/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/InvalidResultSetPointerTest.java delete mode 100644 2.0/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/JDBCTypeAndTypeCompareTest.java delete mode 100644 2.0/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/MicroSecondPrecisionJNITest.java delete mode 100644 2.0/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/MicroSecondPrecisionRestfulTest.java delete mode 100644 2.0/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/MultiConnectionWithDifferentDbTest.java delete mode 100644 2.0/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/MultiThreadsWithSameStatementTest.java delete mode 100644 2.0/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/NanoSecondTimestampJNITest.java delete mode 100644 2.0/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/NanoSecondTimestampRestfulTest.java delete mode 100644 2.0/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/NullValueInResultSetJNITest.java delete mode 100644 2.0/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/NullValueInResultSetRestfulTest.java delete mode 100644 2.0/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/NullValueInResultSetTest.java delete mode 100644 2.0/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/PreparedStatementBatchInsertJNITest.java delete mode 100644 2.0/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/PreparedStatementBatchInsertRestfulTest.java delete mode 100644 2.0/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/QueryDataTest.java delete mode 100644 2.0/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/ResetQueryCacheTest.java delete mode 100644 2.0/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/ResultSetMetaShouldNotBeNullRestfulTest.java delete mode 100644 2.0/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/SelectTest.java delete mode 100644 2.0/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/StableTest.java delete mode 100644 2.0/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/TaosInfoMonitorTest.java delete mode 100644 2.0/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/TimeZoneTest.java delete mode 100644 2.0/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/TimestampPrecisionInNanoInJniTest.java delete mode 100644 2.0/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/TimestampPrecisonInNanoRestTest.java delete mode 100644 2.0/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/UnsignedNumberJniTest.java delete mode 100644 2.0/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/UnsignedNumberRestfulTest.java delete mode 100644 2.0/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/UseNowInsertTimestampTest.java delete mode 100644 2.0/src/connector/jdbc/src/test/java/com/taosdata/jdbc/rs/DatabaseSpecifiedTest.java delete mode 100644 2.0/src/connector/jdbc/src/test/java/com/taosdata/jdbc/rs/RestfulConnectionTest.java delete mode 100644 2.0/src/connector/jdbc/src/test/java/com/taosdata/jdbc/rs/RestfulDatabaseMetaDataTest.java delete mode 100644 2.0/src/connector/jdbc/src/test/java/com/taosdata/jdbc/rs/RestfulDriverTest.java delete mode 100644 2.0/src/connector/jdbc/src/test/java/com/taosdata/jdbc/rs/RestfulJDBCTest.java delete mode 100644 2.0/src/connector/jdbc/src/test/java/com/taosdata/jdbc/rs/RestfulParameterMetaDataTest.java delete mode 100644 2.0/src/connector/jdbc/src/test/java/com/taosdata/jdbc/rs/RestfulPreparedStatementTest.java delete mode 100644 2.0/src/connector/jdbc/src/test/java/com/taosdata/jdbc/rs/RestfulResultSetMetaDataTest.java delete mode 100644 2.0/src/connector/jdbc/src/test/java/com/taosdata/jdbc/rs/RestfulResultSetTest.java delete mode 100644 2.0/src/connector/jdbc/src/test/java/com/taosdata/jdbc/rs/RestfulStatementTest.java delete mode 100644 2.0/src/connector/jdbc/src/test/java/com/taosdata/jdbc/rs/SQLTest.java delete mode 100644 2.0/src/connector/jdbc/src/test/java/com/taosdata/jdbc/utils/OSUtilsTest.java delete mode 100644 2.0/src/connector/jdbc/src/test/java/com/taosdata/jdbc/utils/TimestampUtil.java delete mode 100644 2.0/src/connector/jdbc/src/test/java/com/taosdata/jdbc/utils/UtilsTest.java delete mode 100644 2.0/src/connector/nodejs/nodetaos/cinterface.js delete mode 100644 2.0/src/connector/nodejs/nodetaos/connection.js delete mode 100644 2.0/src/connector/nodejs/nodetaos/constants.js delete mode 100644 2.0/src/connector/nodejs/nodetaos/cursor.js delete mode 100644 2.0/src/connector/nodejs/nodetaos/error.js delete mode 100644 2.0/src/connector/nodejs/nodetaos/globalfunc.js delete mode 100644 2.0/src/connector/nodejs/nodetaos/taosobjects.js delete mode 100644 2.0/src/connector/nodejs/nodetaos/taosquery.js delete mode 100644 2.0/src/connector/nodejs/nodetaos/taosresult.js delete mode 100644 2.0/src/connector/nodejs/package.json delete mode 100644 2.0/src/connector/nodejs/readme.md delete mode 100644 2.0/src/connector/nodejs/tdengine.js delete mode 100644 2.0/src/connector/nodejs/test/performance.js delete mode 100644 2.0/src/connector/nodejs/test/test.js delete mode 100644 2.0/src/connector/nodejs/test/testMicroseconds.js delete mode 100644 2.0/src/connector/nodejs/test/testNanoseconds.js delete mode 100644 2.0/src/connector/nodejs/test/testSubscribe.js delete mode 100644 2.0/src/connector/nodejs/test/testnchar.js delete mode 100644 2.0/src/connector/odbc/.gitignore delete mode 100644 2.0/src/connector/odbc/CMakeLists.txt delete mode 100644 2.0/src/connector/odbc/README.cn.md delete mode 100644 2.0/src/connector/odbc/README.md delete mode 100644 2.0/src/connector/odbc/examples/CMakeLists.txt delete mode 100644 2.0/src/connector/odbc/examples/c/CMakeLists.txt delete mode 100644 2.0/src/connector/odbc/examples/c/main.c delete mode 100644 2.0/src/connector/odbc/examples/c/main.cpp delete mode 100644 2.0/src/connector/odbc/examples/go/odbc.go delete mode 100644 2.0/src/connector/odbc/examples/js/.gitignore delete mode 100755 2.0/src/connector/odbc/examples/js/odbc.js delete mode 100644 2.0/src/connector/odbc/examples/js/package.json delete mode 100644 2.0/src/connector/odbc/examples/lua/odbc.lua delete mode 100644 2.0/src/connector/odbc/examples/py/odbc.py delete mode 100644 2.0/src/connector/odbc/examples/rust/.gitignore delete mode 100644 2.0/src/connector/odbc/examples/rust/main/Cargo.toml delete mode 100644 2.0/src/connector/odbc/examples/rust/main/src/main.rs delete mode 100644 2.0/src/connector/odbc/samples/create_data.stmts delete mode 100644 2.0/src/connector/odbc/samples/query_data.stmts delete mode 100644 2.0/src/connector/odbc/samples/select.stmts delete mode 100644 2.0/src/connector/odbc/samples/simples.stmts delete mode 100644 2.0/src/connector/odbc/src/CMakeLists.txt delete mode 100644 2.0/src/connector/odbc/src/base.c delete mode 100644 2.0/src/connector/odbc/src/base.h delete mode 100644 2.0/src/connector/odbc/src/base/CMakeLists.txt delete mode 100644 2.0/src/connector/odbc/src/base/conn.c delete mode 100644 2.0/src/connector/odbc/src/base/conn.h delete mode 100644 2.0/src/connector/odbc/src/base/env.c delete mode 100644 2.0/src/connector/odbc/src/base/env.h delete mode 100644 2.0/src/connector/odbc/src/base/err.c delete mode 100644 2.0/src/connector/odbc/src/base/err.h delete mode 100644 2.0/src/connector/odbc/src/base/field.c delete mode 100644 2.0/src/connector/odbc/src/base/field.h delete mode 100644 2.0/src/connector/odbc/src/base/null_conn.c delete mode 100644 2.0/src/connector/odbc/src/base/null_conn.h delete mode 100644 2.0/src/connector/odbc/src/base/param.c delete mode 100644 2.0/src/connector/odbc/src/base/param.h delete mode 100644 2.0/src/connector/odbc/src/base/rs.c delete mode 100644 2.0/src/connector/odbc/src/base/rs.h delete mode 100644 2.0/src/connector/odbc/src/base/stmt.c delete mode 100644 2.0/src/connector/odbc/src/base/stmt.h delete mode 100644 2.0/src/connector/odbc/src/base/tsdb_impl.c delete mode 100644 2.0/src/connector/odbc/src/base/tsdb_impl.h delete mode 100644 2.0/src/connector/odbc/src/col.h delete mode 100644 2.0/src/connector/odbc/src/install.cmd delete mode 100755 2.0/src/connector/odbc/src/install.sh delete mode 100644 2.0/src/connector/odbc/src/todbc.def delete mode 100644 2.0/src/connector/odbc/src/todbc.rc.in delete mode 100644 2.0/src/connector/odbc/src/todbc.rsp delete mode 100644 2.0/src/connector/odbc/src/todbc_buf.c delete mode 100644 2.0/src/connector/odbc/src/todbc_buf.h delete mode 100644 2.0/src/connector/odbc/src/todbc_flex.h delete mode 100644 2.0/src/connector/odbc/src/todbc_hash.c delete mode 100644 2.0/src/connector/odbc/src/todbc_hash.h delete mode 100644 2.0/src/connector/odbc/src/todbc_iconv.c delete mode 100644 2.0/src/connector/odbc/src/todbc_iconv.h delete mode 100644 2.0/src/connector/odbc/src/todbc_list.c delete mode 100644 2.0/src/connector/odbc/src/todbc_list.h delete mode 100644 2.0/src/connector/odbc/src/todbc_log.c delete mode 100644 2.0/src/connector/odbc/src/todbc_log.h delete mode 100644 2.0/src/connector/odbc/src/todbc_scanner.l delete mode 100644 2.0/src/connector/odbc/src/todbc_string.c delete mode 100644 2.0/src/connector/odbc/src/todbc_string.h delete mode 100644 2.0/src/connector/odbc/src/todbc_tls.c delete mode 100644 2.0/src/connector/odbc/src/todbc_tls.h delete mode 100644 2.0/src/connector/odbc/src/todbc_util.c delete mode 100644 2.0/src/connector/odbc/src/todbc_util.h delete mode 100644 2.0/src/connector/odbc/tools/CMakeLists.txt delete mode 100644 2.0/src/connector/odbc/tools/main.c delete mode 100644 2.0/src/connector/odbc/tools/tconv.c delete mode 100644 2.0/src/connector/python/.gitignore delete mode 100644 2.0/src/connector/python/LICENSE delete mode 100644 2.0/src/connector/python/README.md delete mode 100644 2.0/src/connector/python/examples/bind-multi.py delete mode 100644 2.0/src/connector/python/examples/bind-row.py delete mode 100644 2.0/src/connector/python/examples/demo.py delete mode 100644 2.0/src/connector/python/examples/insert-lines.py delete mode 100644 2.0/src/connector/python/examples/pep-249.py delete mode 100644 2.0/src/connector/python/examples/query-async.py delete mode 100644 2.0/src/connector/python/examples/query-objectively.py delete mode 100644 2.0/src/connector/python/examples/subscribe-async.py delete mode 100644 2.0/src/connector/python/examples/subscribe-sync.py delete mode 100644 2.0/src/connector/python/pyproject.toml delete mode 100644 2.0/src/connector/python/setup.py delete mode 100644 2.0/src/connector/python/taos/__init__.py delete mode 100644 2.0/src/connector/python/taos/bind.py delete mode 100644 2.0/src/connector/python/taos/cinterface.py delete mode 100644 2.0/src/connector/python/taos/connection.py delete mode 100644 2.0/src/connector/python/taos/constants.py delete mode 100644 2.0/src/connector/python/taos/cursor.py delete mode 100644 2.0/src/connector/python/taos/error.py delete mode 100644 2.0/src/connector/python/taos/field.py delete mode 100644 2.0/src/connector/python/taos/precision.py delete mode 100644 2.0/src/connector/python/taos/result.py delete mode 100644 2.0/src/connector/python/taos/statement.py delete mode 100644 2.0/src/connector/python/taos/stream.py delete mode 100644 2.0/src/connector/python/taos/subscription.py delete mode 100644 2.0/src/connector/python/taos/timestamp.py delete mode 100644 2.0/src/connector/python/tests/test-td6231.py delete mode 100644 2.0/src/connector/python/tests/test_ctaos.py delete mode 100644 2.0/src/connector/python/tests/test_info.py delete mode 100644 2.0/src/connector/python/tests/test_lines.py delete mode 100644 2.0/src/connector/python/tests/test_query.py delete mode 100644 2.0/src/connector/python/tests/test_query_a.py delete mode 100644 2.0/src/connector/python/tests/test_stmt.py delete mode 100644 2.0/src/connector/python/tests/test_stream.py delete mode 100644 2.0/src/connector/python/tests/test_subscribe.py delete mode 100644 2.0/tests/comparisonTest/cassandra/application.conf delete mode 100644 2.0/tests/comparisonTest/cassandra/cassandratest/pom.xml delete mode 100644 2.0/tests/comparisonTest/cassandra/cassandratest/src/main/java/com/cassandra/test/CassandraTest.java delete mode 100644 2.0/tests/comparisonTest/cassandra/cassandratest/src/main/java/com/cassandra/test/WriteThread.java delete mode 100644 2.0/tests/comparisonTest/cassandra/q1.txt delete mode 100644 2.0/tests/comparisonTest/cassandra/q2.txt delete mode 100644 2.0/tests/comparisonTest/cassandra/q3.txt delete mode 100644 2.0/tests/comparisonTest/cassandra/q4.txt delete mode 100644 2.0/tests/comparisonTest/dataGenerator/com/taosdata/generator/DataGenerator.java delete mode 100644 2.0/tests/comparisonTest/influxdb/main.go delete mode 100644 2.0/tests/comparisonTest/influxdb/q1.txt delete mode 100644 2.0/tests/comparisonTest/influxdb/q2.txt delete mode 100644 2.0/tests/comparisonTest/influxdb/q3.txt delete mode 100644 2.0/tests/comparisonTest/influxdb/q4.txt delete mode 100644 2.0/tests/comparisonTest/opentsdb/opentsdbtest/pom.xml delete mode 100644 2.0/tests/comparisonTest/opentsdb/opentsdbtest/src/main/java/com/opentsdb/test/OpentsdbTest.java delete mode 100644 2.0/tests/comparisonTest/opentsdb/opentsdbtest/src/main/java/com/opentsdb/test/WriteThread.java delete mode 100644 2.0/tests/comparisonTest/opentsdb/opentsdbtest/src/main/resources/logback.xml delete mode 100644 2.0/tests/comparisonTest/tdengine/CMakeLists.txt delete mode 100644 2.0/tests/comparisonTest/tdengine/makefile delete mode 100644 2.0/tests/comparisonTest/tdengine/q1.txt delete mode 100644 2.0/tests/comparisonTest/tdengine/q2.txt delete mode 100644 2.0/tests/comparisonTest/tdengine/q3.txt delete mode 100644 2.0/tests/comparisonTest/tdengine/q4.txt delete mode 100644 2.0/tests/comparisonTest/tdengine/q5.txt delete mode 100644 2.0/tests/comparisonTest/tdengine/tdengineTest.c delete mode 100644 2.0/tests/connectorTest/C#Test/nanosupport/TDengineDriver.cs delete mode 100644 2.0/tests/connectorTest/C#Test/nanosupport/nanotest.cs delete mode 100644 2.0/tests/connectorTest/nodejsTest/nanosupport/nanosecondTest.js delete mode 100644 2.0/tests/connectorTest/nodejsTest/nodetaos/cinterface.js delete mode 100644 2.0/tests/connectorTest/nodejsTest/nodetaos/connection.js delete mode 100644 2.0/tests/connectorTest/nodejsTest/nodetaos/constants.js delete mode 100644 2.0/tests/connectorTest/nodejsTest/nodetaos/cursor.js delete mode 100644 2.0/tests/connectorTest/nodejsTest/nodetaos/error.js delete mode 100644 2.0/tests/connectorTest/nodejsTest/nodetaos/globalfunc.js delete mode 100644 2.0/tests/connectorTest/nodejsTest/nodetaos/taosobjects.js delete mode 100644 2.0/tests/connectorTest/nodejsTest/nodetaos/taosquery.js delete mode 100644 2.0/tests/connectorTest/nodejsTest/nodetaos/taosresult.js delete mode 100644 2.0/tests/connectorTest/nodejsTest/readme.md delete mode 100644 2.0/tests/connectorTest/nodejsTest/tdengine.js delete mode 100644 2.0/tests/connectorTest/nodejsTest/test/performance.js delete mode 100644 2.0/tests/connectorTest/nodejsTest/test/test.js delete mode 100644 2.0/tests/connectorTest/nodejsTest/test/testMicroseconds.js delete mode 100644 2.0/tests/connectorTest/nodejsTest/test/testNanoseconds.js delete mode 100644 2.0/tests/connectorTest/nodejsTest/test/testSubscribe.js delete mode 100644 2.0/tests/connectorTest/odbcTest/nanosupport/nanoTest_odbc.py delete mode 100644 2.0/tests/connectorTest/odbcTest/nanosupport/odbc.go delete mode 100644 2.0/tests/connectorTest/odbcTest/nanosupport/odbc.py delete mode 100644 2.0/tests/fuzz/sql-fuzzer.c delete mode 100755 2.0/tests/gotest/batchtest.bat delete mode 100755 2.0/tests/gotest/batchtest.sh delete mode 100644 2.0/tests/gotest/case001/case001.bat delete mode 100644 2.0/tests/gotest/case001/case001.go delete mode 100644 2.0/tests/gotest/case001/case001.sh delete mode 100644 2.0/tests/gotest/case002/case002.bat delete mode 100644 2.0/tests/gotest/case002/case002.go delete mode 100644 2.0/tests/gotest/case002/case002.sh delete mode 100644 2.0/tests/gotest/nanosupport/connector/executor.go delete mode 100644 2.0/tests/gotest/nanosupport/nanoCase.bat delete mode 100644 2.0/tests/gotest/nanosupport/nanoCase.sh delete mode 100644 2.0/tests/gotest/nanosupport/nanosupport.go delete mode 100644 2.0/tests/gotest/test.sh delete mode 100644 2.0/tests/http/restful/http_create_db.c delete mode 100644 2.0/tests/http/restful/http_create_tb.c delete mode 100644 2.0/tests/http/restful/http_drop_db.c delete mode 100644 2.0/tests/http/restful/http_insert_tb.c delete mode 100644 2.0/tests/http/restful/http_query_tb.c delete mode 100644 2.0/tests/http/restful/http_use_db.c delete mode 100755 2.0/tests/nettest/FQDNnettest.sh delete mode 100755 2.0/tests/nettest/TCPUDP.sh delete mode 100755 2.0/tests/nettest/fqdn.sh delete mode 100755 2.0/tests/nettest/tcpudp.sh delete mode 100755 2.0/tests/perftest-scripts/cassandraTestQ1Loop.sh delete mode 100755 2.0/tests/perftest-scripts/cassandraTestQ2Loop.sh delete mode 100755 2.0/tests/perftest-scripts/cassandraTestQ3Loop.sh delete mode 100755 2.0/tests/perftest-scripts/cassandraTestQ4Loop.sh delete mode 100755 2.0/tests/perftest-scripts/cassandraTestWriteLoop.sh delete mode 100755 2.0/tests/perftest-scripts/coverage_test.sh delete mode 100755 2.0/tests/perftest-scripts/full_test.sh delete mode 100755 2.0/tests/perftest-scripts/influxdbTestQ1Loop.sh delete mode 100755 2.0/tests/perftest-scripts/influxdbTestQ2Loop.sh delete mode 100755 2.0/tests/perftest-scripts/influxdbTestQ3Loop.sh delete mode 100755 2.0/tests/perftest-scripts/influxdbTestQ4Loop.sh delete mode 100755 2.0/tests/perftest-scripts/influxdbTestWriteLoop.sh delete mode 100755 2.0/tests/perftest-scripts/opentsdbTestQ1Loop.sh delete mode 100755 2.0/tests/perftest-scripts/opentsdbTestQ2Loop.sh delete mode 100755 2.0/tests/perftest-scripts/opentsdbTestQ3Loop.sh delete mode 100755 2.0/tests/perftest-scripts/opentsdbTestQ4Loop.sh delete mode 100755 2.0/tests/perftest-scripts/opentsdbTestWriteLoop.sh delete mode 100755 2.0/tests/perftest-scripts/perftest-consistent-inserting-data.sh delete mode 100644 2.0/tests/perftest-scripts/perftest-csv2png.gnuplot delete mode 100755 2.0/tests/perftest-scripts/perftest-daily.sh delete mode 100755 2.0/tests/perftest-scripts/perftest-query.sh delete mode 100755 2.0/tests/perftest-scripts/perftest-taosdemo-compare.sh delete mode 100755 2.0/tests/perftest-scripts/perftest-taosdemo.sh delete mode 100755 2.0/tests/perftest-scripts/perftest-tsdb-compare-13d.sh delete mode 100755 2.0/tests/perftest-scripts/perftest-tsdb-compare-1d.sh delete mode 100755 2.0/tests/perftest-scripts/perftest-tsdb-compare-var10k-int100s.sh delete mode 100755 2.0/tests/perftest-scripts/perftest-tsdb-compare-var10k-int10s.sh delete mode 100755 2.0/tests/perftest-scripts/run-csv.sh delete mode 100755 2.0/tests/perftest-scripts/runInfluxdb-13d-csv.sh delete mode 100755 2.0/tests/perftest-scripts/runInfluxdb.sh delete mode 100755 2.0/tests/perftest-scripts/runTDengine.sh delete mode 100755 2.0/tests/perftest-scripts/runreal-13d-csv.sh delete mode 100755 2.0/tests/perftest-scripts/runreal-1d-csv.sh delete mode 100644 2.0/tests/perftest-scripts/taosdemo-csv2png.gnuplot delete mode 100644 2.0/tests/perftest-scripts/taosdemo-rps-csv2png.gnuplot delete mode 100755 2.0/tests/perftest-scripts/tdengineTestQ1Loop.sh delete mode 100755 2.0/tests/perftest-scripts/tdengineTestQ2Loop.sh delete mode 100755 2.0/tests/perftest-scripts/tdengineTestQ3Loop.sh delete mode 100755 2.0/tests/perftest-scripts/tdengineTestQ4Loop.sh delete mode 100755 2.0/tests/perftest-scripts/tdengineTestQ5Loop.sh delete mode 100755 2.0/tests/perftest-scripts/tdengineTestWriteLoop.sh delete mode 100755 2.0/tests/perftest-scripts/tdinternal_coverage_test.sh delete mode 100755 2.0/tests/perftest-scripts/tdinternal_test.sh delete mode 100755 2.0/tests/robust/cluster.sh delete mode 100644 2.0/tests/robust/makefile delete mode 100755 2.0/tests/robust/monitor.sh delete mode 100644 2.0/tests/robust/robust.c delete mode 100644 2.0/tests/stress/.gitignore delete mode 100644 2.0/tests/stress/README.md delete mode 100644 2.0/tests/stress/go.mod delete mode 100644 2.0/tests/stress/main.go diff --git a/2.0/CMakeLists.txt b/2.0/CMakeLists.txt deleted file mode 100755 index 093731f190..0000000000 --- a/2.0/CMakeLists.txt +++ /dev/null @@ -1,54 +0,0 @@ -IF (CMAKE_VERSION VERSION_LESS 3.0) - PROJECT(TDengine CXX) - SET(PROJECT_VERSION_MAJOR "${LIB_MAJOR_VERSION}") - SET(PROJECT_VERSION_MINOR "${LIB_MINOR_VERSION}") - SET(PROJECT_VERSION_PATCH "${LIB_PATCH_VERSION}") - SET(PROJECT_VERSION "${LIB_VERSION_STRING}") -ELSE () - CMAKE_POLICY(SET CMP0048 NEW) - PROJECT(TDengine VERSION "${LIB_VERSION_STRING}" LANGUAGES CXX) -ENDIF () - -IF (${CMAKE_SYSTEM_NAME} MATCHES "Darwin") - CMAKE_MINIMUM_REQUIRED(VERSION 2.8...3.20) -ELSE () - CMAKE_MINIMUM_REQUIRED(VERSION 2.8) -ENDIF () - -SET(TD_ACCOUNT FALSE) -SET(TD_ADMIN FALSE) -SET(TD_GRANT FALSE) -SET(TD_MQTT FALSE) -SET(TD_TSDB_PLUGINS FALSE) -SET(TD_STORAGE FALSE) -SET(TD_TOPIC FALSE) -SET(TD_MODULE FALSE) - -SET(TD_COVER FALSE) -SET(TD_MEM_CHECK FALSE) - -SET(TD_PAGMODE_LITE FALSE) -SET(TD_SOMODE_STATIC FALSE) -SET(TD_POWER FALSE) -SET(TD_GODLL FALSE) - -SET(TD_COMMUNITY_DIR ${PROJECT_SOURCE_DIR}) -MESSAGE(STATUS "Community directory: " ${TD_COMMUNITY_DIR}) - -INCLUDE(cmake/input.inc) -INCLUDE(cmake/platform.inc) - -IF (TD_WINDOWS OR TD_DARWIN) - SET(TD_SOMODE_STATIC TRUE) -ENDIF () - -INCLUDE(cmake/define.inc) -INCLUDE(cmake/env.inc) -INCLUDE(cmake/version.inc) -INCLUDE(cmake/install.inc) - -ADD_SUBDIRECTORY(deps) -ADD_SUBDIRECTORY(src) -ADD_SUBDIRECTORY(tests) - -INCLUDE(CPack) diff --git a/2.0/documentation/tdenginedocs-cn/administrator/index.html b/2.0/documentation/tdenginedocs-cn/administrator/index.html deleted file mode 100644 index eaaf04ff95..0000000000 --- a/2.0/documentation/tdenginedocs-cn/administrator/index.html +++ /dev/null @@ -1,137 +0,0 @@ -文档 | 涛思数据
回去

系统管理

-

文件目录结构

-

安装TDengine后,默认会在操作系统中生成下列目录或文件:

-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - -
目录/文件说明
/etc/taos/taos.cfgTDengine默认[配置文件]
/usr/local/taos/driverTDengine动态链接库目录
/var/lib/taosTDengine默认数据文件目录,可通过[配置文件]修改位置.
/var/log/taosTDengine默认日志文件目录,可通过[配置文件]修改位置
/usr/local/taos/binTDengine可执行文件目录
-

可执行文件

-

TDengine的所有可执行文件默认存放在 /usr/local/taos/bin 目录下。其中包括:

-
    -
  • taosd:TDengine服务端可执行文件
  • -
  • taos: TDengine Shell可执行文件
  • -
  • taosdump:数据导出工具
  • -
  • rmtaos: 一个卸载TDengine的脚本, 请谨慎执行
  • -
-

您可以通过修改系统配置文件taos.cfg来配置不同的数据目录和日志目录

-

服务端配置

-

TDengine系统后台服务由taosd提供,可以在配置文件taos.cfg里修改配置参数,以满足不同场景的需求。配置文件的缺省位置在/etc/taos目录,可以通过taosd命令行执行参数-c指定配置文件目录。比如taosd -c /home/user来指定配置文件位于/home/user这个目录。

-

下面仅仅列出一些重要的配置参数,更多的参数请看配置文件里的说明。各个参数的详细介绍及作用请看前述章节。注意:配置修改后,需要重启taosd服务才能生效。

-
    -
  • internalIp: 对外提供服务的IP地址,默认取第一个IP地址
  • -
  • mgmtShellPort:管理节点与客户端通信使用的TCP/UDP端口号(默认值是6030)。此端口号在内向后连续的5个端口都会被UDP通信占用,即UDP占用[6030-6034],同时TCP通信也会使用端口[6030]。
  • -
  • vnodeShellPort:数据节点与客户端通信使用的TCP/UDP端口号(默认值是6035)。此端口号在内向后连续的5个端口都会被UDP通信占用,即UDP占用[6035-6039],同时TCP通信也会使用端口[6035]
  • -
  • httpPort:数据节点对外提供RESTful服务使用TCP,端口号[6020]
  • -
  • dataDir: 数据文件目录,缺省是/var/lib/taos
  • -
  • maxUsers:用户的最大数量
  • -
  • maxDbs:数据库的最大数量
  • -
  • maxTables:数据表的最大数量
  • -
  • enableMonitor: 系统监测标志位,0:关闭,1:打开
  • -
  • logDir: 日志文件目录,缺省是/var/log/taos
  • -
  • numOfLogLines:日志文件的最大行数
  • -
  • debugFlag: 系统debug日志开关,131:仅错误和报警信息,135:调试信息,143:非常详细的调试信息
  • -
-

不同应用场景的数据往往具有不同的数据特征,比如保留天数、副本数、采集频次、记录大小、采集点的数量、压缩等都可完全不同。为获得在存储上的最高效率,TDengine提供如下存储相关的系统配置参数:

-
    -
  • days:一个数据文件覆盖的时间长度,单位为天
  • -
  • keep:数据库中数据保留的天数
  • -
  • rows: 文件块中记录条数
  • -
  • comp: 文件压缩标志位,0:关闭,1:一阶段压缩,2:两阶段压缩
  • -
  • ctime:数据从写入内存到写入硬盘的最长时间间隔,单位为秒
  • -
  • clog:数据提交日志(WAL)的标志位,0为关闭,1为打开
  • -
  • tables:每个vnode允许创建表的最大数目
  • -
  • cache: 内存块的大小(字节数)
  • -
  • tblocks: 每张表最大的内存块数
  • -
  • ablocks: 每张表平均的内存块数
  • -
  • precision:时间戳为微秒的标志位,ms表示毫秒,us表示微秒
  • -
-

对于一个应用场景,可能有多种数据特征的数据并存,最佳的设计是将具有相同数据特征的表放在一个库里,这样一个应用有多个库,而每个库可以配置不同的存储参数,从而保证系统有最优的性能。TDengine容许应用在创建库时指定上述存储参数,如果指定,该参数就将覆盖对应的系统配置参数。举例,有下述SQL:

-
 create database demo days 10 cache 16000 ablocks 4
-

该SQL创建了一个库demo, 每个数据文件保留10天数据,内存块为16000字节,每个表平均占用4个内存块,而其他参数与系统配置完全一致。

-

客户端配置

-

TDengine系统的前台交互客户端应用程序为taos,它与taosd共享同一个配置文件taos.cfg。运行taos时,使用参数-c指定配置文件目录,如taos -c /home/cfg,表示使用/home/cfg/目录下的taos.cfg配置文件中的参数,缺省目录是/etc/taos。更多taos的使用方法请见Shell命令行程序。本节主要讲解taos客户端应用在配置文件taos.cfg文件中使用到的参数。

-

客户端配置参数列表及解释

-
    -
  • masterIP:客户端默认发起请求的服务器的IP地址
  • -
  • charset:指明客户端所使用的字符集,默认值为UTF-8。TDengine存储nchar类型数据时使用的是unicode存储,因此客户端需要告知服务自己所使用的字符集,也即客户端所在系统的字符集。
  • -
  • locale:设置系统语言环境。Linux上客户端与服务端共享
  • -
  • defaultUser:默认登录用户,默认值root
  • -
  • defaultPass:默认登录密码,默认值taosdata
  • -
-

TCP/UDP端口,以及日志的配置参数,与server的配置参数完全一样。

-

启动taos时,你也可以从命令行指定IP地址、端口号,用户名和密码,否则就从taos.cfg读取。

-

用户管理

-

系统管理员可以在CLI界面里添加、删除用户,也可以修改密码。CLI里SQL语法如下:

-
CREATE USER user_name PASS ‘password’
-

创建用户,并制定用户名和密码,密码需要用单引号引起来

-
DROP USER user_name
-

删除用户,限root用户使用

-
ALTER USER user_name PASS ‘password’  
-

修改用户密码, 为避免被转换为小写,密码需要用单引号引用

-
SHOW USERS
-

显示所有用户

-

数据导入

-

TDengine提供两种方便的数据导入功能,一种按脚本文件导入,一种按数据文件导入。

-

按脚本文件导入

-

TDengine的shell支持source filename命令,用于批量运行文件中的SQL语句。用户可将建库、建表、写数据等SQL命令写在同一个文件中,每条命令单独一行,在shell中运行source命令,即可按顺序批量运行文件中的SQL语句。以‘#’开头的SQL语句被认为是注释,shell将自动忽略。

-

按数据文件导入

-

TDengine也支持在shell对已存在的表从CSV文件中进行数据导入。每个CSV文件只属于一张表且CSV文件中的数据格式需与要导入表的结构相同。其语法如下

-
insert into tb1 file a.csv b.csv tb2 c.csv …
-import into tb1 file a.csv b.csv tb2 c.csv …
-

数据导出

-

为方便数据导出,TDengine提供了两种导出方式,分别是按表导出和用taosdump导出。

-

按表导出CSV文件

-

如果用户需要导出一个表或一个STable中的数据,可在shell中运行

-
select * from <tb_name> >> a.csv
-

这样,表tb中的数据就会按照CSV格式导出到文件a.csv中。

-

用taosdump导出数据

-

TDengine提供了方便的数据库导出工具taosdump。用户可以根据需要选择导出所有数据库、一个数据库或者数据库中的一张表,所有数据或一时间段的数据,甚至仅仅表的定义。其用法如下:

-
    -
  • 导出数据库中的一张或多张表:taosdump [OPTION…] dbname tbname …
  • -
  • 导出一个或多个数据库: taosdump [OPTION…] --databases dbname…
  • -
  • 导出所有数据库(不含监控数据库):taosdump [OPTION…] --all-databases
  • -
-

用户可通过运行taosdump --help获得更详细的用法说明

-

系统连接、任务查询管理

-

系统管理员可以从CLI查询系统的连接、正在进行的查询、流式计算,并且可以关闭连接、停止正在进行的查询和流式计算。CLI里SQL语法如下:

-
SHOW CONNECTIONS
-

显示数据库的连接,其中一列显示ip:port, 为连接的IP地址和端口号。

-
KILL CONNECTION <connection-id>
-

强制关闭数据库连接,其中的connection-id是SHOW CONNECTIONS中显示的 ip:port字串,如“192.168.0.1:42198”,拷贝粘贴即可。

-
SHOW QUERIES
-

显示数据查询,其中一列显示ip:port:id, 为发起该query应用的IP地址,端口号,以及系统分配的ID。

-
KILL QUERY <query-id>
-

强制关闭数据查询,其中query-id是SHOW QUERIES中显示的ip:port:id字串,如“192.168.0.1:42198:11”,拷贝粘贴即可。

-
SHOW STREAMS
-

显示流式计算,其中一列显示ip:port:id, 为启动该stream的IP地址、端口和系统分配的ID。

-
KILL STREAM <stream-id>
-

强制关闭流式计算,其中的中stream-id是SHOW STREAMS中显示的ip:port:id字串,如“192.168.0.1:42198:18”,拷贝粘贴即可。

-

系统监控

-

TDengine启动后,会自动创建一个监测数据库SYS,并自动将服务器的CPU、内存、硬盘空间、带宽、请求数、磁盘读写速度、慢查询等信息定时写入该数据库。TDengine还将重要的系统操作(比如登录、创建、删除数据库等)日志以及各种错误报警信息记录下来存放在SYS库里。系统管理员可以从CLI直接查看这个数据库,也可以在WEB通过图形化界面查看这些监测信息。

-

这些监测信息的采集缺省是打开的,但可以修改配置文件里的选项enableMonitor将其关闭或打开。

回去
\ No newline at end of file diff --git a/2.0/documentation/tdenginedocs-cn/advanced-features/index.html b/2.0/documentation/tdenginedocs-cn/advanced-features/index.html deleted file mode 100644 index b4953b4dd4..0000000000 --- a/2.0/documentation/tdenginedocs-cn/advanced-features/index.html +++ /dev/null @@ -1,64 +0,0 @@ -文档 | 涛思数据
回去

高级功能

-

连续查询(Continuous Query)

-

连续查询是TDengine定期自动执行的查询,采用滑动窗口的方式进行计算,是一种简化的时间驱动的流式计算。针对库中的表或超级表,TDengine可提供定期自动执行的连续查询,用户可让TDengine推送查询的结果,也可以将结果再写回到TDengine中。每次执行的查询是一个时间窗口,时间窗口随着时间流动向前滑动。在定义连续查询的时候需要指定时间窗口(time window, 参数interval )大小和每次前向增量时间(forward sliding times, 参数sliding)。

-

TDengine的连续查询采用时间驱动模式,可以直接使用TAOS SQL进行定义,不需要额外的操作。使用连续查询,可以方便快捷地按照时间窗口生成结果,从而对原始采集数据进行降采样(down sampling)。用户通过TAOS SQL定义连续查询以后,TDengine自动在最后的一个完整的时间周期末端拉起查询,并将计算获得的结果推送给用户或者写回TDengine。

-

TDengine提供的连续查询与普通流计算中的时间窗口计算具有以下区别:

-
    -
  • 不同于流计算的实时反馈计算结果,连续查询只在时间窗口关闭以后才开始计算。例如时间周期是1天,那么当天的结果只会在23:59:59以后才会生成。

  • -
  • 如果有历史记录写入到已经计算完成的时间区间,连续查询并不会重新进行计算,也不会重新将结果推送给用户。对于写回TDengine的模式,也不会更新已经存在的计算结果。

  • -
  • 使用连续查询推送结果的模式,服务端并不缓存客户端计算状态,也不提供Exactly-Once的语意保证。如果用户的应用端崩溃,再次拉起的连续查询将只会从再次拉起的时间开始重新计算最近的一个完整的时间窗口。如果使用写回模式,TDengine可确保数据写回的有效性和连续性。

  • -
-

使用连续查询

-

使用TAOS SQL定义连续查询的过程,需要调用API taos_stream在应用端启动连续查询。例如要对统计表FOO_TABLE 每1分钟统计一次记录数量,前向滑动的时间是30秒,SQL语句如下:

-
SELECT COUNT(*) 
-FROM FOO_TABLE 
-INTERVAL(1M) SLIDING(30S)
-

其中查询的时间窗口(time window)是1分钟,前向增量(forward sliding time)时间是30秒。也可以不使用sliding来指定前向滑动时间,此时系统将自动向前滑动一个查询时间窗口再开始下一次计算,即时间窗口长度等于前向滑动时间。

-
SELECT COUNT(*) 
-FROM FOO_TABLE 
-INTERVAL(1M)
-

如果需要将连续查询的计算结果写回到数据库中,可以使用如下的SQL语句

-
CREATE TABLE QUERY_RES 
-  AS 
-  SELECT COUNT(*) 
-  FROM FOO_TABLE 
-  INTERVAL(1M) SLIDING(30S)
-

此时系统将自动创建表QUERY_RES,然后将连续查询的结果写入到该表。需要注意的是,前向滑动时间不能大于时间窗口的范围。如果用户指定的前向滑动时间超过时间窗口范围,系统将自动将其设置为时间窗口的范围值。如上所示SQL语句,如果用户设置前向滑动时间超过1分钟,系统将强制将其设置为1分钟。

-

此外,TDengine还支持用户指定连续查询的结束时间,默认如果不输入结束时间,连续查询将永久运行,如果用户指定了结束时间,连续查询在系统时间达到指定的时间以后停止运行。如SQL所示,连续查询将运行1个小时,1小时之后连续查询自动停止。

-
CREATE TABLE QUERY_RES 
-  AS 
-  SELECT COUNT(*) 
-  FROM FOO_TABLE 
-  WHERE TS > NOW AND TS <= NOW + 1H 
-  INTERVAL(1M) SLIDING(30S) 
-

此外,还需要注意的是查询时间窗口的最小值是10毫秒,没有时间窗口范围的上限。

-

管理连续查询

-

用户可在控制台中通过 show streams 命令来查看系统中全部运行的连续查询,并可以通过 kill stream 命令杀掉对应的连续查询。在写回模式中,如果用户可以直接将写回的表删除,此时连续查询也会自动停止并关闭。后续版本会提供更细粒度和便捷的连续查询管理命令。

-

数据订阅(Publisher/Subscriber)

-

基于数据天然的时间序列特性,TDengine的数据写入(insert)与消息系统的数据发布(pub)逻辑上一致,均可视为系统中插入一条带时间戳的新记录。同时,TDengine在内部严格按照数据时间序列单调递增的方式保存数据。本质上来说,TDengine中里每一张表均可视为一个标准的消息队列。

-

TDengine内嵌支持轻量级的消息订阅与推送服务。使用系统提供的API,用户可订阅数据库中的某一张表(或超级表)。订阅的逻辑和操作状态的维护均是由客户端完成,客户端定时轮询服务器是否有新的记录到达,有新的记录到达就会将结果反馈到客户。

-

TDengine的订阅与推送服务的状态是客户端维持,TDengine服务器并不维持。因此如果应用重启,从哪个时间点开始获取最新数据,由应用决定。

-

API说明

-

使用订阅的功能,主要API如下:

-
    -
  • TAOS_SUB *taos_subscribe(char *host, char *user, char *pass, char *db, char *table, int64_t time, int mseconds)

    该函数负责启动订阅服务。其中参数说明:

    • -
    • host:主机IP地址

    • -
    • user:数据库登录用户名

    • -
    • pass:密码

    • -
    • db:数据库名称

    • -
    • table:(超级) 表的名称

    • -
    • time:启动时间,Unix Epoch时间,单位为毫秒。从1970年1月1日起计算的毫秒数。如果设为0,表示从当前时间开始订阅

    • -
    • mseconds:查询数据库更新的时间间隔,单位为毫秒。一般设置为1000毫秒。返回值为指向TDengine_SUB 结构的指针,如果返回为空,表示失败。

    • -
  • TAOS_ROW taos_consume(TAOS_SUB *tsub) -

    该函数用来获取订阅的结果,用户应用程序将其置于一个无限循环语句。如果数据库有新记录到达,该API将返回该最新的记录。如果没有新的记录,该API将阻塞。如果返回值为空,说明系统出错。参数说明:

    • tsub:taos_subscribe的结构体指针。

  • void taos_unsubscribe(TAOS_SUB *tsub)

    取消订阅。应用程序退出时,务必调用该函数以避免资源泄露。

  • -
  • int taos_num_fields(TAOS_SUB *tsub)

    获取返回的一行记录中数据包含多少列。

  • -
  • TAOS_FIELD *taos_fetch_fields(TAOS_SUB *tsub)

    获取每列数据的属性(数据类型、名字、长度),与taos_num_subfileds配合使用,可解析返回的每行数据。

-

示例代码:请看安装包中的的示范程序

-

缓存 (Cache)

-

TDengine采用时间驱动缓存管理策略(First-In-First-Out,FIFO),又称为写驱动的缓存管理机制。这种策略有别于读驱动的数据缓存模式(Least-Recent-Use,LRU),直接将最近写入的数据保存在系统的缓存中。当缓存达到临界值的时候,将最早的数据批量写入磁盘。一般意义上来说,对于物联网数据的使用,用户最为关心最近产生的数据,即当前状态。TDengine充分利用了这一特性,将最近到达的(当前状态)数据保存在缓存中。

-

TDengine通过查询函数向用户提供毫秒级的数据获取能力。直接将最近到达的数据保存在缓存中,可以更加快速地响应用户针对最近一条或一批数据的查询分析,整体上提供更快的数据库查询响应能力。从这个意义上来说,可通过设置合适的配置参数将TDengine作为数据缓存来使用,而不需要再部署额外的缓存系统,可有效地简化系统架构,降低运维的成本。需要注意的是,TDengine重启以后系统的缓存将被清空,之前缓存的数据均会被批量写入磁盘,缓存的数据将不会像专门的Key-value缓存系统再将之前缓存的数据重新加载到缓存中。

-

TDengine分配固定大小的内存空间作为缓存空间,缓存空间可根据应用的需求和硬件资源配置。通过适当的设置缓存空间,TDengine可以提供极高性能的写入和查询的支持。TDengine中每个虚拟节点(virtual node)创建时分配独立的缓存池。每个虚拟节点管理自己的缓存池,不同虚拟节点间不共享缓存池。每个虚拟节点内部所属的全部表共享该虚拟节点的缓存池。

-

一个缓存池了有很多个缓存块,缓存的大小由缓存块的个数以及缓存块的大小决定。参数cacheBlockSize决定每个缓存块的大小,参数cacheNumOfBlocks决定每个虚拟节点可用缓存块数量。因此单个虚拟节点总缓存开销为cacheBlockSize x cacheNumOfBlocks。参数numOfBlocksPerMeter决定每张表可用缓存块的数量,TDengine要求每张表至少有2个缓存块可供使用,因此cacheNumOfBlocks的数值不应该小于虚拟节点中所包含的表数量的两倍,即cacheNumOfBlocks ≤ sessionsPerVnode x 2。一般情况下cacheBlockSize可以不用调整,使用系统默认值即可,缓存块需要存储至少几十条记录才能确保TDengine更有效率地进行数据写入。

-

你可以通过函数last快速获取一张表或一张超级表的最后一条记录,这样很便于在大屏显示各设备的实时状态或采集值。例如:

-
select degree from thermometer where location='beijing';
-

该SQL语句将获取所有位于北京的传感器最后记录的温度值。

回去
\ No newline at end of file diff --git a/2.0/documentation/tdenginedocs-cn/assets/Picture2.png b/2.0/documentation/tdenginedocs-cn/assets/Picture2.png deleted file mode 100644 index 715a8bd37ee9fe7e96eacce4e7ff563fedeefbee..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 44198 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 z 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 XT_z57}q-MQIJeG}1I$A3nj?_6} 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 DyGmMe diff --git a/2.0/documentation/tdenginedocs-cn/assets/clip_image001-2474914.png b/2.0/documentation/tdenginedocs-cn/assets/clip_image001-2474914.png deleted file mode 100644 index eb369b1567c860b772e1bfdad64ff17aaac2534d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 123083 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 P`1eFX?NQ-Flehm1m{MTU diff --git a/2.0/documentation/tdenginedocs-cn/assets/clip_image001-2474939.png b/2.0/documentation/tdenginedocs-cn/assets/clip_image001-2474939.png deleted file mode 100644 index 53f00deea3a484986a5681ec9d00d8ae02e88fec..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 76395 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�QVPnUx#fmnA({M&~Kvo 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 EAGy)9l>h($ diff --git a/2.0/documentation/tdenginedocs-cn/assets/clip_image001-2474961.png b/2.0/documentation/tdenginedocs-cn/assets/clip_image001-2474961.png deleted file mode 100644 index 20ae8d6f7724a4bddcf8c7eb3809d468aa4223ed..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 26668 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 diff --git a/2.0/documentation/tdenginedocs-cn/assets/clip_image001-2474987.png b/2.0/documentation/tdenginedocs-cn/assets/clip_image001-2474987.png deleted file mode 100644 index 3d09f7fc28e7a1fb7e3bb2b9b2bc7c20895e8bb4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 44889 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 diff --git a/2.0/documentation/tdenginedocs-cn/assets/clip_image001.png b/2.0/documentation/tdenginedocs-cn/assets/clip_image001.png deleted file mode 100644 index 78b6d06a9562b802e80f0ed5fdb8963b5e525589..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 69060 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%0A2yiQf;;tZ>Cy~(0|rV@E23hi{qry2`9M17dD_ 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⩔{t#cJm{g7{hxrivKItEk3H$RlZr~j6G_f z0q&x8*x z_llO`7dt@G754G`N}2_8H*tg$1&zHRSyo?=pFoaLx7TBaPF_$g=JXqFxn6RG-@^O? zxB%b)L3#EaL0PW5B)$W^3|wWR*=|GZLMUeLMgMlHgt4|W%Q6b$PSX$WjQSc=O3At2 z-U+P~b>6D#*-FC7(wwk2k*r!MLtmIa@9(0O2`8#C6P{)FhfzE=eZ_p89FJt z2_Zv+A(Xh@vW7oc;5svMfwc^6fsq-=@^Z9TQ(>TzRl;MuoKd@3?A32BfHDY zt(Dwib-&L9c758N!diGFZ4RRE)Z>an92p&?a9bq4*siJMr(_^9BP3V*dFY?rwtIkn zQh%o*pm$u+Lo7j)Md-~{BU@#Qq7QVd!HR6}-diU!ZbLpuoi2XuP@x1B0t&iwo1_i8 z+B5djbffF{4#k}wng{KI?j36Qc5M}Q1vAh$3+yn@3XL_*Rf5rqBAL2Hj+XTtoe<4rTt{JgW> zUBjtsY=5wfg!(${4}a4b#xmXQJKs2#(=v3mt8?! z0w;m-bRQ`8aqR{Mv-y1aqw|+tfU|wTgdd-NE%ITRFF*`9jlHbN^F(~}4ld5`^RyVlHYc`0N@e5V| z?XbKi)=5*IVeSpyT%eTyvUby6cioFfhntaM2Jaa_GB|gs$D9~D9B&SAxXns(<){~h zHL1BaowAG9DM2@#+N@~>Fs-{;op2K&vr z1LQv43SprD)2a`8$>o_hBw?eue0T@d>V5~oiv=n`-+g2P9IYC(&!;G4B){C|c-E_k zMty}B)`9ieK*)B4hvM4Nh{wgHw$X7wJjL9lZ;{L+7d2^;AUxX0LsacY15kPgcf zUlpFfmGWsrV-dMI_x;4iMW`X_y}Q{msv$YNf{34pJm7~kCTZogribMj#N$sv=$S$Y zmhVy_GlQ`5<*j{f;EHs@q22Zut_uRtfZN^-%*?Jyrs5Fdf8G{{GkUVlte9zY8AUp8 z__5*O<-f~=^cN(KGzhRpF-Mb`?dKU34~rW)n!zw&1FMi8vLA6FGduCeVWNtWH9Lwo zCAJ;wkhxNB;M!12G?32Ot1{V#O29HS31(>)*`lQ!!BqtB0uUN!3FbLQjp@2`M?eVe z{lg$3r9j=l-||PWvE@Urb?fG4m$$d2*4#g6wnKcy?g}uHVcIKcoyS@p#h1Ren`NvV zBCy@2%B|6aw>MyirBJWrdkE#&7@#PDjZDlgi zZJpLq!M%(lCHck3AjC4scyYgpX6)$lPuzYYId(aJqAc)VC7adLeZ?Ylw$T0HojeewquQt2M%$MZ}qsm*LL2hSnbzy94YL-w$ z6qt?{wPBMSds2w@EJRSk3TpyV&N;fWv=-)4JGAUFZ&}Ru6H-Dm5+MqAT-|XF){;Bz zkFW*b9nVKF@}O!Z{X{oXy;d^L|3&z*0p^{j=N+IGeHs3fW5p+$%{YO{u3nJIK)q_2 zR=wFI*tW8p;2db@A|V&@(ybvNj@xPJAfAnMM_gM2ykSbwpYsUbJ@8=v#K-%0@3U&t))dH;mWa53D@W z67D|ezjXoMKqW)93dUwtOb$K2VQ!dLdH|~HP(s%qIT?*+nBLg#w)Tx*2^+}{Z`f6^ zVjEwZMB_zX8g+l~obKC&1YWHzY(YQF4!YAjU>t@!XhY3C?4I-*K-nPAE80_J0-4RLxjEY%4=>JT6eJSCFKLOBHhT+ zW|(oSwK(^=Ha%45%P4lAxl*?2fT~yQo-t~0GyF~3u%(iOlsX!5-Rb!F02*y%yAUC< zdA{V8oft1;wyIz4%T*_M0=?O1pW8SI<_(X$z?Nm&oD$0$hdlG=e?EKFiABmCCh*;J zuG2Rs1IaM{8hq=u7n+UI5q^f9IzVrt;jxp1YIlS3&VJHzVB z#|#ejCck}FRc*}u7&e~xN0GtK*M}UcgX`Zp@U#%l_zATjF1BEut1T}n(RqHUW6d;f zb7w_evR!Wy8uH=4A!rd>)Gdl_K|ZH+t;%l#;uJ8!mVc#imqq3{;Zp6|`6lCj#(P)` zR*$IUL!?t}+c928qQYz7qFZONmk%wMWzxsl8{$l;hm~G1O9MrwwxjEPCW=Fj1Y9N# zUA_u6DbXShdYoH#`z1PnR~RNWl9pkX6pm5Z$oYPg{_H&%uj_a2iTDG(ZoB$BosOwK zor7P+j4O}Cbw8@m0e<5oYd?R#()kDNv$YQTG$94-YfeKBVuO;8Ard6zUEeJ6gw`T? z3IOd6A1SsEc>Z(E`(-kmw?knUAAP7|;uJbPHu@4yPg}yQo*~bpoL+ry2iOWDxwHKC`iJ5l}Y46hGaj;nuQaGIEgVZ^t9elAQkLIPT|KjEq*&nnr#5fKD0WA?dwyE z)?3{y>f2nl$;}8MJ)96tYMn^)-!>$a)WW@QhW7JdJ`VPg5F}j;gRjSg6dv+83Du}E zPYt9X^w zSqt9p0*qayqeP|C7S<+#wEwMK7a_%y+hqgmjldW#-oXU6nJ0G`o!o$G_`9;5qb ziU6FGbNU}?fX)6(DaGsyKD*hg*#^GnFAxc^jACO?v(GxJ<=cF2t1noKPS+-nDt$k` z;=g#ojKcpb8Oe)(V*-1DnjT3p{ej&*KGLJ(>qG^wrM$7fB-| zP}WaAIUJA(j6RJMT*PCL*0Fx4iN9j{o1sm?%OlJc-JV#6KNEn>-6tOHU@`T}EB`L$ z9B-4)3^Uz#oU8ZS?+reE-Ej*2__ang>3xCYH$rpY73Z2IP*>?yC;}va^(wh|QPJS& zx9FiPxE;9POYWrB3MIL<6ZF(Ojl|tfX3ezq3?;Pf9;qiFLT~vWZ?N2$iLCr1MD6DV zMih$Rq%tJM8mJqaKo>2!1A05FcXCK^pCJrd-B@sL?|h21NlOO=LVd+kLKqL6NYb5A-L{Ttw-dr^FYWxTOA8DWf}7F*QxHeY@p zhJ#2+^tD$ZMiT_bMB2HTQ@(Kj6-paybOR-3e3@k_B?vjB?3;|d??H|96)=eJJ`_kYDO|7c>QMEzk1#L_E6B)s1?id1sgHD1_F6vtr){ZLry z^!5ET(Fstx5yPYQ76F^{AT2ueL%_z!@Ly@m{}a{7h+|(fK>0yU9YE4>vcV}}ETZcm zGHI|fRH;+j-_fQYsA5=e^TDuI5HdG?`L7n>|EidFg2nUBcI_AUUQ>D2ObU1aygj>+ zbij3b4vTEeanMSt0V}}#Wb^y~PxkbWgyF@0x+JVCoS3yBdMHK2d0j5UutOn*o!em% ztb1M$FythKbk6uihBe{gCWAidH0Kf8oM|085LjBY~)kwX) z+#mzx>z5Am@K^BXqp!Pw#?KpbD(*+OVloyx=L-M@8|eJ!p%3yR$(IlDx_ajSD+c+$ax%JDFlZuHh3dl7{C^%W@LAJO^Z&Gc zCjH+5kEa3f{`v5K=Tm_X{VhX;fPk?5PFg|(n8NhfPS}6{2#yB~c>LW<`tPLm=yO8= zNc9ile+SlSfdP2cG%M@>CxiQE7R|E2BGi*AVrKcz0B{?yuh)$$wKV^C<%67~{9eGD zLzGoC{xc9C3JeVO8dR43&mzc0Uw?tfyY7OWm0kRw0R~+EN91<1HmBN^;!$AE2=8Q+ Kr7I+j0{#zPf(Z=( diff --git a/2.0/documentation/tdenginedocs-cn/assets/image-20190707124650780.png b/2.0/documentation/tdenginedocs-cn/assets/image-20190707124650780.png deleted file mode 100644 index 9ebcac863e862d8b240c86dec29be1ebe7aa50f0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 21589 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 P00000NkvXXu0mjfnnG#* diff --git a/2.0/documentation/tdenginedocs-cn/assets/nodes.png b/2.0/documentation/tdenginedocs-cn/assets/nodes.png deleted file mode 100644 index d4ae5120c29b8cfacdc543df5a2a7104d77a2a7b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 67429 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 diff --git a/2.0/documentation/tdenginedocs-cn/assets/structure.png b/2.0/documentation/tdenginedocs-cn/assets/structure.png deleted file mode 100644 index 801829b68580e1a46d0841a3d38e4885eb383991..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 25593 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≪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 JOZ@ld{{VfYx&Z(H diff --git a/2.0/documentation/tdenginedocs-cn/connections-with-other-tools/index.html b/2.0/documentation/tdenginedocs-cn/connections-with-other-tools/index.html deleted file mode 100644 index ad877bb4e7..0000000000 --- a/2.0/documentation/tdenginedocs-cn/connections-with-other-tools/index.html +++ /dev/null @@ -1,93 +0,0 @@ -文档 | 涛思数据 \ No newline at end of file diff --git a/2.0/documentation/tdenginedocs-cn/connector/index.html b/2.0/documentation/tdenginedocs-cn/connector/index.html deleted file mode 100644 index 34ea19813f..0000000000 --- a/2.0/documentation/tdenginedocs-cn/connector/index.html +++ /dev/null @@ -1,262 +0,0 @@ -文档 | 涛思数据
    回去

    连接器

    -

    TDengine提供了丰富的应用程序开发接口,其中包括C/C++、JAVA、Python、RESTful、Go等,便于用户快速开发应用。

    -

    C/C++ Connector

    -

    C/C++的API类似于MySQL的C API。应用程序使用时,需要包含TDengine头文件 taos.h(安装后,位于/usr/local/taos/include):

    -
    #include <taos.h>
    -

    在编译时需要链接TDengine动态库libtaos.so(安装后,位于/usr/local/taos/driver,gcc编译时,请加上 -ltaos)。 所有API都以返回-1NULL均表示失败。

    -

    C/C++同步API

    -

    传统的数据库操作API,都属于同步操作。应用调用API后,一直处于阻塞状态,直到服务器返回结果。TDengine支持如下API:

    -
      -
    • TAOS *taos_connect(char *ip, char *user, char *pass, char *db, int port)

      -

      创建数据库连接,初始化连接上下文。其中需要用户提供的参数包含:TDengine管理主节点的IP地址、用户名、密码、数据库名字和端口号。如果用户没有提供数据库名字,也可以正常连接,用户可以通过该连接创建新的数据库,如果用户提供了数据库名字,则说明该数据库用户已经创建好,缺省使用该数据库。返回值为空表示失败。应用程序需要保存返回的参数,以便后续API调用。

    • -
    • void taos_close(TAOS *taos)

      -

      关闭连接, 其中taos是taos_connect函数返回的指针。

    • -
    • int taos_query(TAOS *taos, char *sqlstr)

      -

      该API用来执行SQL语句,可以是DQL语句也可以是DML语句,或者DDL语句。其中的taos参数是通过taos_connect()获得的指针。返回值-1表示失败。

    • -
    • TAOS_RES *taos_use_result(TAOS *taos)

      -

      选择相应的查询结果集。

    • -
    • TAOS_ROW taos_fetch_row(TAOS_RES *res)

      -

      按行获取查询结果集中的数据。

    • -
    • int taos_num_fields(TAOS_RES *res)

      -

      获取查询结果集中的列数。

    • -
    • TAOS_FIELD *taos_fetch_fields(TAOS_RES *res)

      -

      获取查询结果集每列数据的属性(数据类型、名字、字节数),与taos_num_fileds配合使用,可用来解析taos_fetch_row返回的一个元组(一行)的数据。

    • -
    • void taos_free_result(TAOS_RES *res)

      -

      释放查询结果集以及相关的资源。查询完成后,务必调用该API释放资源,否则可能导致应用内存泄露。

    • -
    • void taos_init()

      -

      初始化环境变量。如果应用没有主动调用该API,那么应用在调用taos_connect时将自动调用。因此一般情况下应用程序无需手动调用该API。

    • -
    • char *taos_errstr(TAOS *taos)

      -

      获取最近一次API调用失败的原因,返回值为字符串。

    • -
    • char *taos_errno(TAOS *taos)

      -

      获取最近一次API调用失败的原因,返回值为错误代码。

    • -
    • int taos_options(TSDB_OPTION option, const void * arg, ...)

      -

      设置客户端选项,目前只支持时区设置(TSDB_OPTION_TIMEZONE)和编码设置(TSDB_OPTION_LOCALE)。时区和编码默认为操作系统当前设置。

    • -
    -

    上述12个API是C/C++接口中最重要的API,剩余的辅助API请参看taos.h文件。

    -

    注意:对于单个数据库连接,在同一时刻只能有一个线程使用该链接调用API,否则会有未定义的行为出现并可能导致客户端crash。客户端应用可以通过建立多个连接进行多线程的数据写入或查询处理。

    -

    C/C++异步API

    -

    同步API之外,TDengine还提供性能更高的异步调用API处理数据插入、查询操作。在软硬件环境相同的情况下,异步API处理数据插入的速度比同步API快2~4倍。异步API采用非阻塞式的调用方式,在系统真正完成某个具体数据库操作前,立即返回。调用的线程可以去处理其他工作,从而可以提升整个应用的性能。异步API在网络延迟严重的情况下,优点尤为突出。

    -

    异步API都需要应用提供相应的回调函数,回调函数参数设置如下:前两个参数都是一致的,第三个参数依不同的API而定。第一个参数param是应用调用异步API时提供给系统的,用于回调时,应用能够找回具体操作的上下文,依具体实现而定。第二个参数是SQL操作的结果集,如果为空,比如insert操作,表示没有记录返回,如果不为空,比如select操作,表示有记录返回。

    -

    异步API对于使用者的要求相对较高,用户可根据具体应用场景选择性使用。下面是三个重要的异步API:

    -
      -
    • void taos_query_a(TAOS *taos, char *sqlstr, void (*fp)(void *param, TAOS_RES *, int code), void *param);

      -

      异步执行SQL语句。taos是调用taos_connect返回的数据库连接结构体。sqlstr是需要执行的SQL语句。fp是用户定义的回调函数。param是应用提供一个用于回调的参数。回调函数fp的第三个参数code用于指示操作是否成功,0表示成功,负数表示失败(调用taos_errstr获取失败原因)。应用在定义回调函数的时候,主要处理第二个参数TAOS_RES *,该参数是查询返回的结果集。

    • -
    • void taos_fetch_rows_a(TAOS_RES *res, void (*fp)(void *param, TAOS_RES *, int numOfRows), void *param);

      -

      批量获取异步查询的结果集,只能与taos_query_a配合使用。其中res是_taos_query_a回调时返回的结果集结构体指针,fp为回调函数。回调函数中的param是用户可定义的传递给回调函数的参数结构体。numOfRows表明有fetch数据返回的行数(numOfRows并不是本次查询满足查询条件的全部元组数量)。在回调函数中,应用可以通过调用taos_fetch_row前向迭代获取批量记录中每一行记录。读完一块内的所有记录后,应用需要在回调函数中继续调用taos_fetch_rows_a获取下一批记录进行处理,直到返回的记录数(numOfRows)为零(结果返回完成)或记录数为负值(查询出错)。

    • -
    • void taos_fetch_row_a(TAOS_RES *res, void (*fp)(void *param, TAOS_RES *, TAOS_ROW row), void *param);

      -

      异步获取一条记录。其中res是taos_query_a回调时返回的结果集结构体指针。fp为回调函数。param是应用提供的一个用于回调的参数。回调时,第三个参数TAOS_ROW指向一行记录。不同于taos_fetch_rows_a,应用无需调用同步API taos_fetch_row来获取一个元组,更加简单。数据提取性能不及批量获取的API。

    • -
    -

    TDengine的异步API均采用非阻塞调用模式。应用程序可以用多线程同时打开多张表,并可以同时对每张打开的表进行查询或者插入操作。需要指出的是,客户端应用必须确保对同一张表的操作完全串行化,即对同一个表的插入或查询操作未完成时(未返回时),不能够执行第二个插入或查询操作。

    -

    C/C++ 连续查询接口

    -

    TDengine提供时间驱动的实时流式计算API。可以每隔一指定的时间段,对一张或多张数据库的表(数据流)进行各种实时聚合计算操作。操作简单,仅有打开、关闭流的API。具体如下:

    -
      -
    • TAOS_STREAM *taos_open_stream(TAOS *taos, char *sqlstr, void (*fp)(void *param, TAOS_RES *, TAOS_ROW row), int64_t stime, void *param)

      -

      该API用来创建数据流,其中taos是调用taos_connect返回的结构体指针;sqlstr是SQL查询语句(仅能使用查询语句);fp是用户定义的回调函数指针,每次流式计算完成后,均回调该函数,用户可在该函数内定义其内部业务逻辑;param是应用提供的用于回调的一个参数,回调时,提供给应用;stime是流式计算开始的时间,如果是0,表示从现在开始,如果不为零,表示从指定的时间开始计算(UTC时间从1970/1/1算起的毫秒数)。返回值为NULL,表示创建成功,返回值不为空,表示成功。TDengine将查询的结果(TAOS_ROW)、查询状态(TAOS_RES)、用户定义参数(PARAM)传递给回调函数,在回调函数内,用户可以使用taos_num_fields获取结果集列数,taos_fetch_fields获取结果集每列数据的类型。

    • -
    • void taos_close_stream (TAOS_STREAM *tstr)

      -

      关闭数据流,其中提供的参数是taos_open_stream的返回值。用户停止流式计算的时候,务必关闭该数据流。

    • -
    -

    C/C++ 数据订阅接口

    -

    订阅API目前支持订阅一张表,并通过定期轮询的方式不断获取写入表中的最新数据。

    -
      -
    • TAOS_SUB *taos_subscribe(char *host, char *user, char *pass, char *db, char *table, long time, int mseconds)

      -

      该API用来启动订阅,需要提供的参数包含:TDengine管理主节点的IP地址、用户名、密码、数据库、数据库表的名字;time是开始订阅消息的时间,是从1970年1月1日起计算的毫秒数,为长整型, 如果设为0,表示从当前时间开始订阅;mseconds为查询数据库更新的时间间隔,单位为毫秒,建议设为1000毫秒。返回值为一指向TDengine_SUB结构的指针,如果返回为空,表示失败。

    • -
    • TAOS_ROW taos_consume(TAOS_SUB *tsub)

      -

      该API用来获取最新消息,应用程序一般会将其置于一个无限循环语句中。其中参数tsub是taos_subscribe的返回值。如果数据库有新的记录,该API将返回,返回参数是一行记录。如果没有新的记录,该API将阻塞。如果返回值为空,说明系统出错,需要检查系统是否还在正常运行。

    • -
    • void taos_unsubscribe(TAOS_SUB *tsub)

      -

      该API用于取消订阅,参数tsub是taos_subscribe的返回值。应用程序退出时,需要调用该API,否则有资源泄露。

    • -
    • int taos_num_fields(TAOS_SUB *tsub)

      -

      该API用来获取返回的一排数据中数据的列数

    • -
    • TAOS_FIELD *taos_fetch_fields(TAOS_RES *res)

      -

      该API用来获取每列数据的属性(数据类型、名字、字节数),与taos_num_subfileds配合使用,可用来解析返回的一排数据。

    • -
    -

    Java Connector

    -

    JDBC接口

    -

    如果用户使用Java开发企业级应用,可选用TDengine提供的JDBC Driver来调用服务。TDengine提供的JDBC Driver是标准JDBC规范的子集,遵循JDBC 标准(3.0)API规范,支持现有的各种Java开发框架。目前TDengine的JDBC driver并未发布到在线依赖仓库比如maven的中心仓库。因此用户开发时,需要手动把驱动包taos-jdbcdriver-x.x.x-dist.jar安装到开发环境的依赖仓库中。

    -

    TDengine 的驱动程序包的在不同操作系统上依赖不同的本地函数库(均由C语言编写)。Linux系统上,依赖一个名为libtaos.so 的本地库,.so即"Shared Object"缩写。成功安装TDengine后,libtaos.so 文件会被自动拷贝至/usr/local/lib/taos目录下,该目录也包含在Linux上自动扫描路径上。Windows系统上,JDBC驱动程序依赖于一个名为taos.dll 的本地库,.dll是动态链接库"Dynamic Link Library"的缩写。Windows上成功安装客户端后,JDBC驱动程序包默认位于C:/TDengine/driver/JDBC/目录下;其依赖的动态链接库taos.dll文件位于C:/TDengine/driver/C目录下,taos.dll 会被自动拷贝至系统默认搜索路径C:/Windows/System32下。

    -

    TDengine的JDBC Driver遵循标准JDBC规范,开发人员可以参考Oracle官方的JDBC相关文档来找到具体的接口和方法的定义与用法。TDengine的JDBC驱动在连接配置和支持的方法上与传统数据库驱动稍有不同。

    -

    TDengine的JDBC URL规范格式为:

    -

    jdbc:TSDB://{host_ip}:{port}/{database_name}?[user={user}|&password={password}|&charset={charset}|&cfgdir={config_dir}|&locale={locale}|&timezone={timezone}]

    -

    其中,{}中的内容必须,[]中为可选。配置参数说明如下:

    -
      -
    • user:登陆TDengine所用用户名;默认值root
    • -
    • password:用户登陆密码;默认值taosdata
    • -
    • charset:客户端使用的字符集;默认值为系统字符集
    • -
    • cfgdir:客户端配置文件目录路径;Linux OS上默认值/etc/taos ,Windows OS上默认值 C:/TDengine/cfg
    • -
    • locale:客户端语言环境;默认值系统当前locale
    • -
    • timezone:客户端使用的时区;默认值为系统当前时区
    • -
    -

    以上所有参数均可在调用java.sql.DriverManager类创建连接时指定,示例如下:

    -
    import java.sql.Connection;
    -import java.sql.DriverManager;
    -import java.util.Properties;
    -import com.taosdata.jdbc.TSDBDriver;
    -
    -public Connection getConn() throws Exception{
    -  Class.forName("com.taosdata.jdbc.TSDBDriver");
    -  String jdbcUrl = "jdbc:TAOS://127.0.0.1:0/db?user=root&password=taosdata";
    -  Properties connProps = new Properties();
    -  connProps.setProperty(TSDBDriver.PROPERTY_KEY_USER, "root");
    -  connProps.setProperty(TSDBDriver.PROPERTY_KEY_PASSWORD, "taosdata");
    -  connProps.setProperty(TSDBDriver.PROPERTY_KEY_CONFIG_DIR, "/etc/taos");
    -  connProps.setProperty(TSDBDriver.PROPERTY_KEY_CHARSET, "UTF-8");
    -  connProps.setProperty(TSDBDriver.PROPERTY_KEY_LOCALE, "en_US.UTF-8");
    -  connProps.setProperty(TSDBDriver.PROPERTY_KEY_TIMEZONE, "UTC-8");
    -  Connection conn = DriverManager.getConnection(jdbcUrl, connProps);
    -  return conn;
    -}
    -

    这些配置参数中除了cfgdir外,均可在客户端配置文件taos.cfg中进行配置。调用java.sql.DriverManager时声明的配置参数优先级最高,JDBC URL的优先级次之,配置文件的优先级最低。例如charset同时在配置文件taos.cfg中配置,也在JDBC URL中配置,则使用JDBC URL中的配置值。

    -

    此外,尽管TDengine的JDBC驱动实现尽可能的与关系型数据库驱动保持一致,但时序空间数据库与关系对象型数据库服务的对象和技术特征的差异导致TDengine的Java API并不能与标准完全相同。对于有大量关系型数据库开发经验而初次接触TDengine的开发者来说,有以下一些值的注意的地方:

    -
      -
    • TDengine不提供针对单条数据记录的删除和修改的操作,驱动中也没有支持相关方法
    • -
    • 目前TDengine不支持表间的join或union操作,因此也缺乏对该部分API的支持
    • -
    • TDengine支持批量写入,但是支持停留在SQL语句级别,而不是API级别,也就是说用户需要通过写特殊的SQL语句来实现批量
    • -
    • 目前TDengine不支持嵌套查询(nested query),对每个Connection的实例,至多只能有一个打开的ResultSet实例;如果在ResultSet还没关闭的情况下执行了新的查询,TSDBJDBCDriver则会自动关闭上一个ResultSet
    • -
    -

    对于TDengine操作的报错信息,用户可使用JDBCDriver包里提供的枚举类TSDBError.java来获取error message和error code的列表。对于更多的具体操作的相关代码,请参考TDengine提供的使用示范项目JDBCDemo

    -

    Python Connector

    -

    安装准备

    -
  1. 已安装TDengine, 如果客户端在Windows上,需要安装Windows 版本的TDengine客户端
  2. -
  3. 已安装python 2.7 or >= 3.4
  4. -
  5. 已安装pip
  6. -

    安装

    -

    Linux

    -

    用户可以在源代码的src/connector/python文件夹下找到python2和python3的安装包, 然后通过pip命令安装

    -
    pip install src/connector/python/linux/python2/
    -

    或者

    -
    pip install src/connector/python/linux/python3/
    -

    Windows

    -

    在已安装Windows TDengine 客户端的情况下, 将文件"C:\TDengine\driver\taos.dll" 拷贝到 "C:\windows\system32" 目录下, 然后进入Windwos cmd 命令行界面

    -
    cd C:\TDengine\connector\python\windows
    -
    pip install python2\
    -

    或者

    -
    cd C:\TDengine\connector\python\windows
    -
    pip install python3\
    -

    * 如果机器上没有pip命令,用户可将src/connector/python/windows/python3或src/connector/python/windows/python2下的taos文件夹拷贝到应用程序的目录使用。

    -

    使用

    -

    代码示例

    -
  7. 导入TDengine客户端模块:
  8. -
    import taos 
    -
  9. 获取连接
  10. -
    
    -conn = taos.connect(host="127.0.0.1", user="root", password="taosdata", config="/etc/taos")
    -c1 = conn.cursor()
    -
    -

    * host 是TDengine 服务端所有IP, config 为客户端配置文件所在目录

    -
  11. 写入数据
  12. -
    
    -import datetime
    - 
    -# 创建数据库
    -c1.execute('create database db')
    -c1.execute('use db')
    -# 建表
    -c1.execute('create table tb (ts timestamp, temperature int, humidity float)')
    -# 插入数据
    -start_time = datetime.datetime(2019, 11, 1)
    -affected_rows = c1.execute('insert into tb values (\'%s\', 0, 0.0)' %start_time)
    -# 批量插入数据
    -time_interval = datetime.timedelta(seconds=60)
    -sqlcmd = ['insert into tb values']
    -for irow in range(1,11):
    -  start_time += time_interval
    -  sqlcmd.append('(\'%s\', %d, %f)' %(start_time, irow, irow*1.2))
    -affected_rows = c1.execute(' '.join(sqlcmd))
    -
    -
  13. 查询数据
  14. -
    -c1.execute('select * from tb')
    -# 拉取查询结果
    -data = c1.fetchall()
    -# 返回的结果是一个列表,每一行构成列表的一个元素
    -numOfRows = c1.rowcount
    -numOfCols = c1.descriptions
    -for irow in range(numOfRows):
    -  print("Row%d: ts=%s, temperature=%d, humidity=%f" %(irow, data[irow][0], data[irow][1],data[irow][2])
    -  
    -# 直接使用cursor 循环拉取查询结果
    -c1.execute('select * from tb')
    -for data in c1:
    -  print("ts=%s, temperature=%d, humidity=%f" %(data[0], data[1],data[2])
    -
    -
  15. 关闭连接
  16. -
    -c1.close()
    -conn.close()
    -
    -

    帮助信息

    -

    用户可通过python的帮助信息直接查看模块的使用信息,或者参考code/examples/python中的示例程序。以下为部分常用类和方法:

    -
      -
    • TaosConnection

      -

      参考python中help(taos.TDengineConnection)

    • -
    • TaosCursor

      -

      参考python中help(taos.TDengineCursor)

    • -
    • connect 方法

      -

      用于生成taos.TDengineConnection的实例。

    • -
    -

    RESTful Connector

    -

    为支持各种不同类型平台的开发,TDengine提供符合REST设计标准的API,即RESTful API。为最大程度降低学习成本,不同于其他数据库RESTful API的设计方法,TDengine直接通过HTTP POST 请求BODY中包含的SQL语句来操作数据库,仅需要一个URL。

    -

    HTTP请求格式

    -

    http://<ip>:<PORT>/rest/sql

    -

    ​ 参数说明:

    -

    ​ IP: 集群中的任一台主机

    -

    ​ PORT: 配置文件中httpPort配置项,缺省为6020

    -

    如:http://192.168.0.1:6020/rest/sql 是指向IP地址为192.168.0.1的URL.

    -

    HTTP请求的Header里需带有身份认证信息,TDengine单机版仅支持Basic认证机制。

    -

    HTTP请求的BODY里就是一个完整的SQL语句,SQL语句中的数据表应提供数据库前缀,例如\.\。如果表名不带数据库前缀,系统会返回错误。因为HTTP模块只是一个简单的转发,没有当前DB的概念。

    -

    使用curl来发起一个HTTP Request, 语法如下:

    -
    curl -H 'Authorization: Basic <TOKEN>' -d '<SQL>' <ip>:<PORT>/rest/sql
    -

    或者

    -
    curl -u username:password -d '<SQL>' <ip>:<PORT>/rest/sql
    -

    其中,TOKEN{username}:{password}经过Base64编码之后的字符串,例如root:taosdata编码后为cm9vdDp0YW9zZGF0YQ==

    -

    HTTP返回格式

    -

    返回值为JSON格式,如下:

    -
    {
    -    "status": "succ",
    -    "head": ["column1","column2", …],
    -    "data": [
    -        ["2017-12-12 23:44:25.730", 1],
    -        ["2017-12-12 22:44:25.728", 4]
    -    ],
    -    "rows": 2
    -} 
    -

    说明:

    -
      -
    • 第一行”status”告知操作结果是成功还是失败;
    • -
    • 第二行”head”是表的定义,如果不返回结果集,仅有一列“affected_rows”;
    • -
    • 第三行是具体返回的数据,一排一排的呈现。如果不返回结果集,仅[[affected_rows]]
    • -
    • 第四行”rows”表明总共多少行数据
    • -
    -

    使用示例

    -
      -
    • 在demo库里查询表t1的所有记录, curl如下:

      -

      curl -H 'Authorization: Basic cm9vdDp0YW9zZGF0YQ==' -d 'select * from demo.t1' 192.168.0.1:6020/rest/sql

      -

      返回值:

    • -
    -
    {
    -    "status": "succ",
    -    "head": ["column1","column2","column3"],
    -    "data": [
    -        ["2017-12-12 23:44:25.730", 1, 2.3],
    -        ["2017-12-12 22:44:25.728", 4, 5.6]
    -    ],
    -    "rows": 2
    -}
    -
      -
    • 创建库demo:

      -

      curl -H 'Authorization: Basic cm9vdDp0YW9zZGF0YQ==' -d 'create database demo' 192.168.0.1:6020/rest/sql

      -

      返回值:

    • -
    -
    {
    -    "status": "succ",
    -    "head": ["affected_rows"],
    -    "data": [[1]],
    -    "rows": 1,
    -}
    -

    Go Connector

    -

    TDengine提供了GO驱动程序“taosSql”包。taosSql驱动包是基于GO的“database/sql/driver”接口的实现。用户可在安装后的/usr/local/taos/connector/go目录获得GO的客户端驱动程序。用户需将驱动包/usr/local/taos/connector/go/src/taosSql目录拷贝到应用程序工程的src目录下。然后在应用程序中导入驱动包,就可以使用“database/sql”中定义的接口访问TDengine:

    -
    import (
    -    "database/sql"
    -    _ "taosSql"
    -)
    -

    taosSql驱动包内采用cgo模式,调用了TDengine的C/C++同步接口,与TDengine进行交互,因此,在数据库操作执行完成之前,客户端应用将处于阻塞状态。单个数据库连接,在同一时刻只能有一个线程调用API。客户应用可以建立多个连接,进行多线程的数据写入或查询处理。

    -

    更多使用的细节,请参考下载目录中的示例源码。

    回去
    diff --git a/2.0/documentation/tdenginedocs-cn/data-model-and-architecture/index.html b/2.0/documentation/tdenginedocs-cn/data-model-and-architecture/index.html deleted file mode 100644 index 09e1212b04..0000000000 --- a/2.0/documentation/tdenginedocs-cn/data-model-and-architecture/index.html +++ /dev/null @@ -1,128 +0,0 @@ -文档 | 涛思数据
    回去

    数据模型和设计

    -

    数据模型

    -

    物联网典型场景

    -

    在典型的物联网、车联网、运维监测场景中,往往有多种不同类型的数据采集设备,采集一个到多个不同的物理量。而同一种采集设备类型,往往又有多个具体的采集设备分布在不同的地点。大数据处理系统就是要将各种采集的数据汇总,然后进行计算和分析。对于同一类设备,其采集的数据类似如下的表格:

    -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Device IDTime StampValue 1Value 2Value 3Tag 1Tag 2
    D1001153854868500010.32190.31RedTesla
    D1002153854868400010.22200.23BlueBMW
    D1003153854868650011.52210.35BlackHonda
    D1004153854868550013.42230.29RedVolvo
    D1001153854869500012.62180.33RedTesla
    D1004153854869660011.82210.28BlackHonda
    -

    每一条记录都有设备ID,时间戳,采集的物理量,还有与每个设备相关的静态标签。每个设备是受外界的触发,或按照设定的周期采集数据。采集的数据点是时序的,是一个数据流。

    -

    数据特征

    -

    除时序特征外,仔细研究发现,物联网、车联网、运维监测类数据还具有很多其他明显的特征。

    -
      -
    1. 数据是结构化的;
    2. -
    3. 数据极少有更新或删除操作;
    4. -
    5. 无需传统数据库的事务处理;
    6. -
    7. 相对互联网应用,写多读少;
    8. -
    9. 流量平稳,根据设备数量和采集频次,可以预测出来;
    10. -
    11. 用户关注的是一段时间的趋势,而不是某一特点时间点的值;
    12. -
    13. 数据是有保留期限的;
    14. -
    15. 数据的查询分析一定是基于时间段和地理区域的;
    16. -
    17. 除存储查询外,还往往需要各种统计和实时计算操作;
    18. -
    19. 数据量巨大,一天采集的数据就可以超过100亿条。
    20. -
    -

    充分利用上述特征,TDengine采取了一特殊的优化的存储和计算设计来处理时序数据,能将系统处理能力显著提高。

    -

    关系型数据库模型

    -

    因为采集的数据一般是结构化数据,而且为降低学习门槛,TDengine采用传统的关系型数据库模型管理数据。因此用户需要先创建库,然后创建表,之后才能插入或查询数据。

    -

    一个设备一张表

    -

    为充分利用其数据的时序性和其他数据特点,TDengine要求对每个数据采集点单独建表(比如有一千万个智能电表,就需创建一千万张表,上述表格中的D1001, D1002, D1003, D1004都需单独建表),用来存储这个采集点所采集的时序数据。这种设计能保证一个采集点的数据在存储介质上是一块一块连续的,大幅减少随机读取操作,成数量级的提升读取和查询速度。而且由于不同数据采集设备产生数据的过程完全独立,每个设备只产生属于自己的数据,一张表也就只有一个写入者。这样每个表就可以采用无锁方式来写,写入速度就能大幅提升。同时,对于一个数据采集点而言,其产生的数据是时序的,因此写的操作可用追加的方式实现,进一步大幅提高数据写入速度。

    -

    数据建模最佳实践

    -

    表(Table):TDengine 建议用数据采集点的名字(如上表中的D1001)来做表名。每个数据采集点可能同时采集多个物理量(如上表中的value1, value2, value3),每个物理量对应一张表中的一列,数据类型可以是整型、浮点型、字符串等。除此之外,表的第一列必须是时间戳,即数据类型为 timestamp。有的设备有多组采集量,每一组的采集频次是不一样的,这是需要对同一个设备建多张表。对采集的数据,TDengine将自动按照时间戳建立索引,但对采集的物理量不建任何索引。数据是用列式存储方式保存。

    -

    超级表(Super Table):对于同一类型的采集点,为保证Schema的一致性,而且为便于聚合统计操作,可以先定义超级表STable(详见第10章),然后再定义表。每个采集点往往还有静态标签信息(如上表中的Tag 1, Tag 2),比如设备型号、颜色等,这些静态信息不会保存在存储采集数据的数据节点中,而是通过超级表保存在元数据节点中。这些静态标签信息将作为过滤条件,用于采集点之间的数据聚合统计操作。

    -

    库(DataBase):不同的数据采集点往往具有不同的数据特征,包括数据采集频率高低,数据保留时间长短,备份数目,单个字段大小等等。为让各种场景下TDengine都能最大效率的工作,TDengine建议将不同数据特征的表创建在不同的库里。创建一个库时,除SQL标准的选项外,应用还可以指定保留时长、数据备份的份数、cache大小、文件块大小、是否压缩等多种参数(详见第19章)。

    -

    Schemaless vs Schema: 与NoSQL的各种引擎相比,由于应用需要定义schema,插入数据的灵活性降低。但对于物联网、金融这些典型的时序数据场景,schema会很少变更,因此这个灵活性不够的设计就不成问题。相反,TDengine采用结构化数据来进行处理的方式将让查询、分析的性能成数量级的提升。

    -

    TDengine对库的数量、超级表的数量以及表的数量没有做任何限制,而且其多少不会对性能产生影响,应用按照自己的场景创建即可。

    -

    主要模块

    -

    如图所示,TDengine服务主要包含两大模块:管理节点模块(MGMT)数据节点模块(DNODE)。整个TDengine还包含客户端模块

    -

    -
    图 1 TDengine架构示意图

    -

    管理节点模块

    -

    管理节点模块主要负责元数据的存储和查询等工作,其中包括用户信息的管理、数据库和表信息的创建、删除以及查询等。应用连接TDengine时会首先连接到管理节点。在创建/删除数据库和表时,请求也会首先发送请求到管理节点模块。由管理节点模块首先创建/删除元数据信息,然后发送请求到数据节点模块进行分配/删除所需要的资源。在数据写入和查询时,应用同样会首先访问管理节点模块,获取元数据信息。然后根据元数据管理信息访问数据节点模块。

    -

    数据节点模块

    -

    写入数据的存储和查询工作是由数据节点模块负责。 为了更高效地利用资源,以及方便将来进行水平扩展,TDengine内部对数据节点进行了虚拟化,引入了虚拟节点(virtual node, 简称vnode)的概念,作为存储、资源分配以及数据备份的单元。如图2所示,在一个dnode上,通过虚拟化,可以将该dnode视为多个虚拟节点的集合。

    -

    创建一个库时,系统会自动分配vnode。每个vnode存储一定数量的表中的数据,但一个表只会存在于一个vnode里,不会跨vnode。一个vnode只会属于一个库,但一个库会有一到多个vnode。不同的vnode之间资源互不共享。每个虚拟节点都有自己的缓存,在硬盘上也有自己的存储目录。而同一vnode内部无论是缓存还是硬盘的存储都是共享的。通过虚拟化,TDengine可以将dnode上有限的物理资源合理地分配给不同的vnode,大大提高资源的利用率和并发度。一台物理机器上的虚拟节点个数可以根据其硬件资源进行配置。

    -

    -
    图 2 TDengine虚拟化

    -

    客户端模块

    -

    TDengine客户端模块主要负责将应用传来的请求(SQL语句)进行解析,转化为内部结构体再发送到服务端。TDengine的各种接口都是基于TDengine的客户端模块进行开发的。客户端模块与管理模块使用TCP/UDP通讯,端口号由系统参数mgmtShellPort配置, 缺省值为6030。客户端与数据节点模块也是使用TCP/UDP通讯,端口号由系统参数vnodeShellPort配置, 缺省值为6035。两个端口号均可通过系统配置文件taos.cfg进行个性化设置。

    -

    写入流程

    -

    TDengine的完整写入流程如图3所示。为了保证写入数据的安全性和完整性,TDengine在写入数据时采用[预写日志算法]。客户端发来的数据在经过验证以后,首先会写入预写日志中,以保证TDengine能够在断电等因素导致的服务重启时从预写日志中恢复数据,避免数据的丢失。写入预写日志后,数据会被写到对应的vnode的缓存中。随后,服务端会发送确认信息给客户端表示写入成功。TDengine中存在两种机制可以促使缓存中的数据写入到硬盘上进行持久化存储:

    -

    -
    图 3 TDengine写入流程

    -
      -
    1. 时间驱动的落盘:TDengine服务会定时将vnode缓存中的数据写入到硬盘上,默认为一个小时落一次盘。落盘间隔可在配置文件taos.cfg中通过参数commitTime配置。
    2. -
    3. 数据驱动的落盘:当vnode中缓存的数据达到一定规模时,为了不阻塞后续数据的写入,TDengine也会拉起落盘线程将缓存中的数据清空。数据驱动的落盘会刷新定时落盘的时间。
    4. -
    -

    TDengine在数据落盘时会打开新的预写日志文件,在落盘后则会删除老的预写日志文件,避免日志文件无限制的增长。TDengine对缓存按照先进先出的原则进行管理,以保证每个表的最新数据都在缓存中。

    -

    数据存储

    -

    TDengine将所有数据存储在/var/lib/taos/目录下,您可以通过系统配置参数dataDir进行个性化配置。

    -

    TDengine中的元数据信息包括TDengine中的数据库、表、用户等信息。每个超级表、以及每个表的标签数据也存放在这里。为提高访问速度,元数据全部有缓存。

    -

    TDengine中写入的数据在硬盘上是按时间维度进行分片的。同一个vnode中的表在同一时间范围内的数据都存放在同一文件组中。这一数据分片方式可以大大简化数据在时间维度的查询,提高查询速度。在默认配置下,硬盘上的每个数据文件存放10天数据。用户可根据需要修改系统配置参数daysPerFile进行个性化配置。

    -

    表中的数据都有保存时间,一旦超过保存时间(缺省是3650天),数据将被系统自动删除。您可以通过系统配置参数daysToKeep进行个性化设置。

    -

    数据在文件中是按块存储的。每个数据块只包含一张表的数据,且数据是按照时间主键递增排列的。数据在数据块中按列存储,这样使得同列的数据存放在一起,对于不同的数据类型还采用不同的压缩方法,大大提高压缩的比例,节省存储空间。

    -

    数据文件总共有三类文件,一类是data文件,它存放了真实的数据块,该文件只进行追加操作;一类文件是head文件, 它存放了其对应的data文件中数据块的索引信息;第三类是last文件,专门存储最后写入的数据,每次落盘操作时,这部分数据会与内存里的数据合并,并决定是否写入data文件还是last文件。

    回去
    \ No newline at end of file diff --git a/2.0/documentation/tdenginedocs-cn/faq/index.html b/2.0/documentation/tdenginedocs-cn/faq/index.html deleted file mode 100644 index ea40348569..0000000000 --- a/2.0/documentation/tdenginedocs-cn/faq/index.html +++ /dev/null @@ -1,33 +0,0 @@ -文档 | 涛思数据
    回去

    常见问题

    -

    1. 遇到错误"failed to connect to server", 我怎么办?

    -

    客户端遇到链接故障,请按照下面的步骤进行检查:

    -
      -
    1. 在服务器,执行 systemctl status taosd 检查taosd运行状态。如果没有运行,启动taosd
    2. -
    3. 确认客户端连接时指定了正确的服务器IP地址
    4. -
    5. ping服务器IP,如果没有反应,请检查你的网络
    6. -
    7. 检查防火墙设置,确认TCP/UDP 端口6030-6039 是打开的
    8. -
    9. 对于Linux上的JDBC(ODBC, Python, Go等接口类似)连接, 确保libtaos.so在目录/usr/local/lib/taos里, 并且/usr/local/lib/taos在系统库函数搜索路径LD_LIBRARY_PATH
    10. -
    11. 对于windows上的JDBC, ODBC, Python, Go等连接,确保driver/c/taos.dll在你的系统搜索目录里 (建议taos.dll放在目录 C:\Windows\System32)
    12. -
    13. 如果仍不能排除连接故障,请使用命令行工具nc来分别判断指定端口的TCP和UDP连接是否通畅 -检查UDP端口连接是否工作:nc -vuz {hostIP} {port} -检查服务器侧TCP端口连接是否工作:nc -l {port} -检查客户端侧TCP端口链接是否工作:nc {hostIP} {port}
    14. -
    -

    2. 虽然语法正确,为什么我还是得到 "Invalid SQL" 错误

    -

    如果你确认语法正确,请检查SQL语句长度是否超过64K。如果超过,也会返回这个错误。

    -

    3. 为什么我删除超级表总是失败?

    -

    请确保超级表下已经没有其他表,否则系统不允许删除该超级表。

    -

    4. 是否支持validation queries?

    -

    TDengine还没有一组专用的validation queries。然而建议你使用系统监测的数据库”log"来做。

    -

    5. 我可以删除或更新一条记录吗?

    -

    不能。因为TDengine是为联网设备采集的数据设计的,不容许修改。但TDengine提供数据保留策略,只要数据记录超过保留时长,就会被自动删除。

    -

    6. 我怎么创建超过250列的表?

    -

    TDengine最大允许创建250列的表。但是如果确实超过,我们建议按照数据特性,逻辑地将这个宽表分解成几个小表。

    -

    7. 最有效的写入数据的方法是什么?

    -

    批量插入。每条写入语句可以一张表同时插入多条记录,也可以同时插入多张表的记录。

    -

    8. windows系统下插入的nchar类数据中的汉字被解析成了乱码如何解决?

    -

    windows下插入nchar类的数据中如果有中文,请先确认系统的地区设置成了中国(在Control Panel里可以设置),这时cmd中的taos客户端应该已经可以正常工作了;如果是在IDE里开发Java应用,比如Eclipse, Intellij,请确认IDE里的文件编码为GBK(这是Java默认的编码类型),然后在生成Connection时,初始化客户端的配置,具体语句如下:

    -

    ​ Class.forName("com.taosdata.jdbc.TSDBDriver");

    -

    ​ Properties properties = new Properties();

    -

    ​ properties.setProperty(TSDBDriver.LOCALE_KEY, "UTF-8");

    -

    ​ Connection = DriverManager.getConnection(url, properties);

    回去
    \ No newline at end of file diff --git a/2.0/documentation/tdenginedocs-cn/getting-started/index.html b/2.0/documentation/tdenginedocs-cn/getting-started/index.html deleted file mode 100644 index d7d5d8540c..0000000000 --- a/2.0/documentation/tdenginedocs-cn/getting-started/index.html +++ /dev/null @@ -1,88 +0,0 @@ -文档 | 涛思数据
    回去

    立即开始

    -

    快速上手

    -

    TDengine目前只支持在Linux系统上安装和运行。用户可根据需求选择通过源码或者安装包来安装。

    -

    通过源码安装

    -

    请参考我们的TDengine github主页下载源码并安装.

    -

    通过安装包安装

    -

    我们提供三种安装包,请选择你所需要的。TDengine的安装非常简单,从下载到安装成功仅仅只要几秒钟。

    - -

    目前,TDengine只支持在使用systemd做进程服务管理的linux系统上安装。其他linux系统的支持正在开发中。用which命令来检测系统中是否存在systemd:

    -
    which systemd
    -

    如果系统中不存在systemd命令,请考虑通过源码安装TDengine。

    -

    启动并体验TDengine

    -

    安装成功后,用户可使用systemctl命令来启动TDengine的服务进程。

    -
    systemctl start taosd
    -

    检查服务是否正常工作。

    -
    systemctl status taosd
    -

    如果TDengine服务正常工作,那么您可以通过TDengine的命令行程序taos来访问并体验TDengine。

    -

    注:systemctl 命令需要 root 权限来运行,如果您非 root 用户,请在命令前添加 sudo

    -

    TDengine命令行程序

    -

    执行TDengine命令行程序,您只要在Linux终端执行taos即可

    -
    taos
    -

    如果TDengine终端链接服务成功,将会打印出欢迎消息和版本信息。如果失败,则会打印错误消息出来(请参考FAQ来解决终端链接服务端失败的问题)。TDengine终端的提示符号如下:

    -
    taos>
    -

    在TDengine终端中,用户可以通过SQL命令来创建/删除数据库、表等,并进行插入查询操作。在终端中运行的SQL语句需要以分号结束来运行。示例:

    -
    create database db;
    -use db;
    -create table t (ts timestamp, speed int);
    -insert into t values ('2019-07-15 00:00:00', 10);
    -insert into t values ('2019-07-15 01:00:00', 20);
    -select * from t;
    -          ts          |   speed   |
    -===================================
    - 19-07-15 00:00:00.000|         10|
    - 19-07-15 01:00:00.000|         20|
    -Query OK, 2 row(s) in set (0.001700s)
    -

    除执行SQL语句外,系统管理员还可以从TDengine终端检查系统运行状态,添加删除用户账号等。

    -

    命令行参数

    -

    您可通过配置命令行参数来改变TDengine终端的行为。以下为常用的几个命令行参数:

    -
      -
    • -c, --config-dir: 指定配置文件目录,默认为/etc/taos
    • -
    • -h, --host: 指定服务的IP地址,默认为本地服务
    • -
    • -s, --commands: 在不进入终端的情况下运行TDengine命令
    • -
    • -u, -- user: 链接TDengine服务器的用户名,缺省为root
    • -
    • -p, --password: 链接TDengine服务器的密码,缺省为taosdata
    • -
    • -?, --help: 打印出所有命令行参数
    • -
    -

    示例:

    -
    taos -h 192.168.0.1 -s "use db; show tables;"
    -

    运行SQL命令脚本

    -

    TDengine终端可以通过source命令来运行SQL命令脚本.

    -
    taos> source <filename>;
    -

    Shell小技巧

    -
      -
    • 可以使用上下光标键查看已经历史输入的命令
    • -
    • 修改用户密码。在shell中使用alter user命令
    • -
    • ctrl+c 中止正在进行中的查询
    • -
    • 执行RESET QUERY CACHE清空本地缓存的表的schema
    • -
    -

    主要功能

    -

    TDengine的核心功能是时序数据库。除此之外,为减少研发的复杂度、系统维护的难度,TDengine还提供缓存、消息队列、订阅、流式计算等功能。更详细的功能如下:

    -
      -
    • 使用类SQL语言插入或查询数据
    • -
    • 支持C/C++, Java(JDBC), Python, Go, RESTful, and Node.JS 开发接口
    • -
    • 可通过Python/R/Matlab or TDengine shell做Ad Hoc查询分析
    • -
    • 通过定时连续查询支持基于滑动窗口的流式计算
    • -
    • 使用超级表来更灵活高效的聚合多个时间线的数据
    • -
    • 时间轴上聚合一个或多个时间线的数据
    • -
    • 支持数据订阅,一旦有新数据,就立即通知应用
    • -
    • 支持缓存,每个时间线或设备的最新数据都从内存里快速获取
    • -
    • 历史数据与实时数据处理完全透明,不用区别对待
    • -
    • 支持链接Telegraf, Grafana等第三方工具
    • -
    • 成套的配置和工具,让你更好的管理TDengine
    • -
    -

    对于企业版,TDengine还提供如下高级功能:

    -
      -
    • 线性水平扩展能力,以提供更高的处理速度和数据容量
    • -
    • 高可靠,无单点故障,提供运营商级别的服务
    • -
    • 多个副本自动同步,而且可以跨机房
    • -
    • 多级存储,让历史数据处理的成本更低
    • -
    • 用户友好的管理后台和工具,让管理更轻松简单
    • -
    -

    TDengine是专为物联网、车联网、工业互联网、运维监测等场景优化设计的时序数据处理引擎。与其他方案相比,它的插入查询速度都快10倍以上。单核一秒钟就能插入100万数据点,读出1000万数据点。由于采用列式存储和优化的压缩算法,存储空间不及普通数据库的1/10.

    -

    深入了解TDengine

    -

    请继续阅读文档来深入了解TDengine。

    回去
    diff --git a/2.0/documentation/tdenginedocs-cn/index.html b/2.0/documentation/tdenginedocs-cn/index.html deleted file mode 100644 index 17ee078d04..0000000000 --- a/2.0/documentation/tdenginedocs-cn/index.html +++ /dev/null @@ -1 +0,0 @@ -文档 | 涛思数据

    TDengine文档

    TDengine是一个高效的存储、查询、分析时序大数据的平台,专为物联网、车联网、工业互联网、运维监测等优化而设计。您可以像使用关系型数据库MySQL一样来使用它,但建议您在使用前仔细阅读一遍下面的文档,特别是数据模型超级表一节。除本文档之外,欢迎下载产品白皮书

    立即开始

    数据模型和设计

    • 数据模型:关系型数据库模型,但要求每个采集设备单独建表
    • 主要模块:包含管理节点、数据节点和客户端,数据节点支持虚拟化
    • 写入流程:先写入WAL、之后写入缓存,再给应用确认
    • 数据存储:数据按时间段切片、采取列存、不同数据类型不同压缩算法

    TAOS SQL

    • 支持的数据类型:支持时间戳、整型、浮点型、布尔型、字符型等多种数据类型
    • 数据库管理:添加、删除、查看数据库
    • 表管理:添加、删除、查看、修改表
    • 数据写入:支持单表单条、多条、多表多条写入,支持历史数据写入
    • 数据查询:支持时间段、值过滤、排序、查询结果手动分页等
    • SQL函数:支持各种聚合函数、选择函数、计算函数,如avg, min, diff等
    • 时间维度聚合:将表中数据按照时间段进行切割后聚合,降维处理

    超级表STable:多表聚合

    高级功能

    连接器

    与其他工具的连接

    • Telegraf:将DevOps采集的数据发送到TDengine
    • Grafana:获取并可视化保存在TDengine的数据
    • Matlab:通过配置Matlab的JDBC数据源访问保存在TDengine的数据
    • R:通过配置R的JDBC数据源访问保存在TDengine的数据

    系统管理

    TDengine的技术设计

    • 存储设计:为时序数据专门优化设计的列式存储格式
    • 查询处理:高效的查询计算时序数据的方法
    • 集群设计:吸取NoSQL的优点,支持高可靠,支持线性扩展
    • 技术博客:更多的技术分析和架构设计文章

    培训和FAQ

    • FAQ:常见问题与答案
    • 应用案列:一些使用实例来解释如何使用TDengine
    回去
    \ No newline at end of file diff --git a/2.0/documentation/tdenginedocs-cn/lib/bootstrap.min.css b/2.0/documentation/tdenginedocs-cn/lib/bootstrap.min.css deleted file mode 100644 index 882691283a..0000000000 --- a/2.0/documentation/tdenginedocs-cn/lib/bootstrap.min.css +++ /dev/null @@ -1,7 +0,0 @@ -/*! - * Bootstrap v4.1.3 (https://getbootstrap.com/) - * Copyright 2011-2018 The Bootstrap Authors - * Copyright 2011-2018 Twitter, Inc. - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) - */:root{--blue:#007bff;--indigo:#6610f2;--purple:#6f42c1;--pink:#e83e8c;--red:#dc3545;--orange:#fd7e14;--yellow:#ffc107;--green:#28a745;--teal:#20c997;--cyan:#17a2b8;--white:#fff;--gray:#6c757d;--gray-dark:#343a40;--primary:#007bff;--secondary:#6c757d;--success:#28a745;--info:#17a2b8;--warning:#ffc107;--danger:#dc3545;--light:#f8f9fa;--dark:#343a40;--breakpoint-xs:0;--breakpoint-sm:576px;--breakpoint-md:768px;--breakpoint-lg:992px;--breakpoint-xl:1200px;--font-family-sans-serif:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";--font-family-monospace:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace}*,::after,::before{box-sizing:border-box}html{font-family:sans-serif;line-height:1.15;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%;-ms-overflow-style:scrollbar;-webkit-tap-highlight-color:transparent}@-ms-viewport{width:device-width}article,aside,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}body{margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";font-size:1rem;font-weight:400;line-height:1.5;color:#212529;text-align:left;background-color:#fff}[tabindex="-1"]:focus{outline:0!important}hr{box-sizing:content-box;height:0;overflow:visible}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem}p{margin-top:0;margin-bottom:1rem}abbr[data-original-title],abbr[title]{text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted;cursor:help;border-bottom:0}address{margin-bottom:1rem;font-style:normal;line-height:inherit}dl,ol,ul{margin-top:0;margin-bottom:1rem}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem}dfn{font-style:italic}b,strong{font-weight:bolder}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{color:#007bff;text-decoration:none;background-color:transparent;-webkit-text-decoration-skip:objects}a:hover{color:#0056b3;text-decoration:underline}a:not([href]):not([tabindex]){color:inherit;text-decoration:none}a:not([href]):not([tabindex]):focus,a:not([href]):not([tabindex]):hover{color:inherit;text-decoration:none}a:not([href]):not([tabindex]):focus{outline:0}code,kbd,pre,samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;font-size:1em}pre{margin-top:0;margin-bottom:1rem;overflow:auto;-ms-overflow-style:scrollbar}figure{margin:0 0 1rem}img{vertical-align:middle;border-style:none}svg{overflow:hidden;vertical-align:middle}table{border-collapse:collapse}caption{padding-top:.75rem;padding-bottom:.75rem;color:#6c757d;text-align:left;caption-side:bottom}th{text-align:inherit}label{display:inline-block;margin-bottom:.5rem}button{border-radius:0}button:focus{outline:1px dotted;outline:5px auto -webkit-focus-ring-color}button,input,optgroup,select,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,input{overflow:visible}button,select{text-transform:none}[type=reset],[type=submit],button,html [type=button]{-webkit-appearance:button}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{padding:0;border-style:none}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}input[type=date],input[type=datetime-local],input[type=month],input[type=time]{-webkit-appearance:listbox}textarea{overflow:auto;resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;max-width:100%;padding:0;margin-bottom:.5rem;font-size:1.5rem;line-height:inherit;color:inherit;white-space:normal}progress{vertical-align:baseline}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{outline-offset:-2px;-webkit-appearance:none}[type=search]::-webkit-search-cancel-button,[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}output{display:inline-block}summary{display:list-item;cursor:pointer}template{display:none}[hidden]{display:none!important}.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{margin-bottom:.5rem;font-family:inherit;font-weight:500;line-height:1.2;color:inherit}.h1,h1{font-size:2.5rem}.h2,h2{font-size:2rem}.h3,h3{font-size:1.75rem}.h4,h4{font-size:1.5rem}.h5,h5{font-size:1.25rem}.h6,h6{font-size:1rem}.lead{font-size:1.25rem;font-weight:300}.display-1{font-size:6rem;font-weight:300;line-height:1.2}.display-2{font-size:5.5rem;font-weight:300;line-height:1.2}.display-3{font-size:4.5rem;font-weight:300;line-height:1.2}.display-4{font-size:3.5rem;font-weight:300;line-height:1.2}hr{margin-top:1rem;margin-bottom:1rem;border:0;border-top:1px solid rgba(0,0,0,.1)}.small,small{font-size:80%;font-weight:400}.mark,mark{padding:.2em;background-color:#fcf8e3}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;list-style:none}.list-inline-item{display:inline-block}.list-inline-item:not(:last-child){margin-right:.5rem}.initialism{font-size:90%;text-transform:uppercase}.blockquote{margin-bottom:1rem;font-size:1.25rem}.blockquote-footer{display:block;font-size:80%;color:#6c757d}.blockquote-footer::before{content:"\2014 \00A0"}.img-fluid{max-width:100%;height:auto}.img-thumbnail{padding:.25rem;background-color:#fff;border:1px solid #dee2e6;border-radius:.25rem;max-width:100%;height:auto}.figure{display:inline-block}.figure-img{margin-bottom:.5rem;line-height:1}.figure-caption{font-size:90%;color:#6c757d}code{font-size:87.5%;color:#e83e8c;word-break:break-word}a>code{color:inherit}kbd{padding:.2rem .4rem;font-size:87.5%;color:#fff;background-color:#212529;border-radius:.2rem}kbd kbd{padding:0;font-size:100%;font-weight:700}pre{display:block;font-size:87.5%;color:#212529}pre code{font-size:inherit;color:inherit;word-break:normal}.pre-scrollable{max-height:340px;overflow-y:scroll}.container{width:100%;padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}@media (min-width:576px){.container{max-width:540px}}@media (min-width:768px){.container{max-width:720px}}@media (min-width:992px){.container{max-width:960px}}@media (min-width:1200px){.container{max-width:1140px}}.container-fluid{width:100%;padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}.row{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;margin-right:-15px;margin-left:-15px}.no-gutters{margin-right:0;margin-left:0}.no-gutters>.col,.no-gutters>[class*=col-]{padding-right:0;padding-left:0}.col,.col-1,.col-10,.col-11,.col-12,.col-2,.col-3,.col-4,.col-5,.col-6,.col-7,.col-8,.col-9,.col-auto,.col-lg,.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-lg-auto,.col-md,.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-md-auto,.col-sm,.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-sm-auto,.col-xl,.col-xl-1,.col-xl-10,.col-xl-11,.col-xl-12,.col-xl-2,.col-xl-3,.col-xl-4,.col-xl-5,.col-xl-6,.col-xl-7,.col-xl-8,.col-xl-9,.col-xl-auto{position:relative;width:100%;min-height:1px;padding-right:15px;padding-left:15px}.col{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.col-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:none}.col-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-first{-ms-flex-order:-1;order:-1}.order-last{-ms-flex-order:13;order:13}.order-0{-ms-flex-order:0;order:0}.order-1{-ms-flex-order:1;order:1}.order-2{-ms-flex-order:2;order:2}.order-3{-ms-flex-order:3;order:3}.order-4{-ms-flex-order:4;order:4}.order-5{-ms-flex-order:5;order:5}.order-6{-ms-flex-order:6;order:6}.order-7{-ms-flex-order:7;order:7}.order-8{-ms-flex-order:8;order:8}.order-9{-ms-flex-order:9;order:9}.order-10{-ms-flex-order:10;order:10}.order-11{-ms-flex-order:11;order:11}.order-12{-ms-flex-order:12;order:12}.offset-1{margin-left:8.333333%}.offset-2{margin-left:16.666667%}.offset-3{margin-left:25%}.offset-4{margin-left:33.333333%}.offset-5{margin-left:41.666667%}.offset-6{margin-left:50%}.offset-7{margin-left:58.333333%}.offset-8{margin-left:66.666667%}.offset-9{margin-left:75%}.offset-10{margin-left:83.333333%}.offset-11{margin-left:91.666667%}@media (min-width:576px){.col-sm{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.col-sm-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:none}.col-sm-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-sm-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-sm-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-sm-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-sm-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-sm-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-sm-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-sm-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-sm-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-sm-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-sm-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-sm-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-sm-first{-ms-flex-order:-1;order:-1}.order-sm-last{-ms-flex-order:13;order:13}.order-sm-0{-ms-flex-order:0;order:0}.order-sm-1{-ms-flex-order:1;order:1}.order-sm-2{-ms-flex-order:2;order:2}.order-sm-3{-ms-flex-order:3;order:3}.order-sm-4{-ms-flex-order:4;order:4}.order-sm-5{-ms-flex-order:5;order:5}.order-sm-6{-ms-flex-order:6;order:6}.order-sm-7{-ms-flex-order:7;order:7}.order-sm-8{-ms-flex-order:8;order:8}.order-sm-9{-ms-flex-order:9;order:9}.order-sm-10{-ms-flex-order:10;order:10}.order-sm-11{-ms-flex-order:11;order:11}.order-sm-12{-ms-flex-order:12;order:12}.offset-sm-0{margin-left:0}.offset-sm-1{margin-left:8.333333%}.offset-sm-2{margin-left:16.666667%}.offset-sm-3{margin-left:25%}.offset-sm-4{margin-left:33.333333%}.offset-sm-5{margin-left:41.666667%}.offset-sm-6{margin-left:50%}.offset-sm-7{margin-left:58.333333%}.offset-sm-8{margin-left:66.666667%}.offset-sm-9{margin-left:75%}.offset-sm-10{margin-left:83.333333%}.offset-sm-11{margin-left:91.666667%}}@media (min-width:768px){.col-md{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.col-md-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:none}.col-md-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-md-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-md-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-md-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-md-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-md-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-md-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-md-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-md-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-md-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-md-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-md-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-md-first{-ms-flex-order:-1;order:-1}.order-md-last{-ms-flex-order:13;order:13}.order-md-0{-ms-flex-order:0;order:0}.order-md-1{-ms-flex-order:1;order:1}.order-md-2{-ms-flex-order:2;order:2}.order-md-3{-ms-flex-order:3;order:3}.order-md-4{-ms-flex-order:4;order:4}.order-md-5{-ms-flex-order:5;order:5}.order-md-6{-ms-flex-order:6;order:6}.order-md-7{-ms-flex-order:7;order:7}.order-md-8{-ms-flex-order:8;order:8}.order-md-9{-ms-flex-order:9;order:9}.order-md-10{-ms-flex-order:10;order:10}.order-md-11{-ms-flex-order:11;order:11}.order-md-12{-ms-flex-order:12;order:12}.offset-md-0{margin-left:0}.offset-md-1{margin-left:8.333333%}.offset-md-2{margin-left:16.666667%}.offset-md-3{margin-left:25%}.offset-md-4{margin-left:33.333333%}.offset-md-5{margin-left:41.666667%}.offset-md-6{margin-left:50%}.offset-md-7{margin-left:58.333333%}.offset-md-8{margin-left:66.666667%}.offset-md-9{margin-left:75%}.offset-md-10{margin-left:83.333333%}.offset-md-11{margin-left:91.666667%}}@media (min-width:992px){.col-lg{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.col-lg-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:none}.col-lg-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-lg-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-lg-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-lg-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-lg-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-lg-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-lg-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-lg-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-lg-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-lg-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-lg-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-lg-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-lg-first{-ms-flex-order:-1;order:-1}.order-lg-last{-ms-flex-order:13;order:13}.order-lg-0{-ms-flex-order:0;order:0}.order-lg-1{-ms-flex-order:1;order:1}.order-lg-2{-ms-flex-order:2;order:2}.order-lg-3{-ms-flex-order:3;order:3}.order-lg-4{-ms-flex-order:4;order:4}.order-lg-5{-ms-flex-order:5;order:5}.order-lg-6{-ms-flex-order:6;order:6}.order-lg-7{-ms-flex-order:7;order:7}.order-lg-8{-ms-flex-order:8;order:8}.order-lg-9{-ms-flex-order:9;order:9}.order-lg-10{-ms-flex-order:10;order:10}.order-lg-11{-ms-flex-order:11;order:11}.order-lg-12{-ms-flex-order:12;order:12}.offset-lg-0{margin-left:0}.offset-lg-1{margin-left:8.333333%}.offset-lg-2{margin-left:16.666667%}.offset-lg-3{margin-left:25%}.offset-lg-4{margin-left:33.333333%}.offset-lg-5{margin-left:41.666667%}.offset-lg-6{margin-left:50%}.offset-lg-7{margin-left:58.333333%}.offset-lg-8{margin-left:66.666667%}.offset-lg-9{margin-left:75%}.offset-lg-10{margin-left:83.333333%}.offset-lg-11{margin-left:91.666667%}}@media (min-width:1200px){.col-xl{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.col-xl-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:none}.col-xl-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-xl-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-xl-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-xl-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-xl-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-xl-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-xl-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-xl-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-xl-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-xl-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-xl-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-xl-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-xl-first{-ms-flex-order:-1;order:-1}.order-xl-last{-ms-flex-order:13;order:13}.order-xl-0{-ms-flex-order:0;order:0}.order-xl-1{-ms-flex-order:1;order:1}.order-xl-2{-ms-flex-order:2;order:2}.order-xl-3{-ms-flex-order:3;order:3}.order-xl-4{-ms-flex-order:4;order:4}.order-xl-5{-ms-flex-order:5;order:5}.order-xl-6{-ms-flex-order:6;order:6}.order-xl-7{-ms-flex-order:7;order:7}.order-xl-8{-ms-flex-order:8;order:8}.order-xl-9{-ms-flex-order:9;order:9}.order-xl-10{-ms-flex-order:10;order:10}.order-xl-11{-ms-flex-order:11;order:11}.order-xl-12{-ms-flex-order:12;order:12}.offset-xl-0{margin-left:0}.offset-xl-1{margin-left:8.333333%}.offset-xl-2{margin-left:16.666667%}.offset-xl-3{margin-left:25%}.offset-xl-4{margin-left:33.333333%}.offset-xl-5{margin-left:41.666667%}.offset-xl-6{margin-left:50%}.offset-xl-7{margin-left:58.333333%}.offset-xl-8{margin-left:66.666667%}.offset-xl-9{margin-left:75%}.offset-xl-10{margin-left:83.333333%}.offset-xl-11{margin-left:91.666667%}}.table{width:100%;margin-bottom:1rem;background-color:transparent}.table td,.table th{padding:.75rem;vertical-align:top;border-top:1px solid #dee2e6}.table thead th{vertical-align:bottom;border-bottom:2px solid #dee2e6}.table tbody+tbody{border-top:2px solid #dee2e6}.table .table{background-color:#fff}.table-sm td,.table-sm th{padding:.3rem}.table-bordered{border:1px solid #dee2e6}.table-bordered td,.table-bordered th{border:1px solid #dee2e6}.table-bordered thead td,.table-bordered thead th{border-bottom-width:2px}.table-borderless tbody+tbody,.table-borderless td,.table-borderless th,.table-borderless thead th{border:0}.table-striped tbody tr:nth-of-type(odd){background-color:rgba(0,0,0,.05)}.table-hover tbody tr:hover{background-color:rgba(0,0,0,.075)}.table-primary,.table-primary>td,.table-primary>th{background-color:#b8daff}.table-hover .table-primary:hover{background-color:#9fcdff}.table-hover .table-primary:hover>td,.table-hover .table-primary:hover>th{background-color:#9fcdff}.table-secondary,.table-secondary>td,.table-secondary>th{background-color:#d6d8db}.table-hover .table-secondary:hover{background-color:#c8cbcf}.table-hover .table-secondary:hover>td,.table-hover .table-secondary:hover>th{background-color:#c8cbcf}.table-success,.table-success>td,.table-success>th{background-color:#c3e6cb}.table-hover .table-success:hover{background-color:#b1dfbb}.table-hover .table-success:hover>td,.table-hover .table-success:hover>th{background-color:#b1dfbb}.table-info,.table-info>td,.table-info>th{background-color:#bee5eb}.table-hover .table-info:hover{background-color:#abdde5}.table-hover .table-info:hover>td,.table-hover .table-info:hover>th{background-color:#abdde5}.table-warning,.table-warning>td,.table-warning>th{background-color:#ffeeba}.table-hover .table-warning:hover{background-color:#ffe8a1}.table-hover .table-warning:hover>td,.table-hover .table-warning:hover>th{background-color:#ffe8a1}.table-danger,.table-danger>td,.table-danger>th{background-color:#f5c6cb}.table-hover .table-danger:hover{background-color:#f1b0b7}.table-hover .table-danger:hover>td,.table-hover .table-danger:hover>th{background-color:#f1b0b7}.table-light,.table-light>td,.table-light>th{background-color:#fdfdfe}.table-hover .table-light:hover{background-color:#ececf6}.table-hover .table-light:hover>td,.table-hover .table-light:hover>th{background-color:#ececf6}.table-dark,.table-dark>td,.table-dark>th{background-color:#c6c8ca}.table-hover .table-dark:hover{background-color:#b9bbbe}.table-hover .table-dark:hover>td,.table-hover .table-dark:hover>th{background-color:#b9bbbe}.table-active,.table-active>td,.table-active>th{background-color:rgba(0,0,0,.075)}.table-hover .table-active:hover{background-color:rgba(0,0,0,.075)}.table-hover .table-active:hover>td,.table-hover .table-active:hover>th{background-color:rgba(0,0,0,.075)}.table .thead-dark th{color:#fff;background-color:#212529;border-color:#32383e}.table .thead-light th{color:#495057;background-color:#e9ecef;border-color:#dee2e6}.table-dark{color:#fff;background-color:#212529}.table-dark td,.table-dark th,.table-dark thead th{border-color:#32383e}.table-dark.table-bordered{border:0}.table-dark.table-striped tbody tr:nth-of-type(odd){background-color:rgba(255,255,255,.05)}.table-dark.table-hover tbody tr:hover{background-color:rgba(255,255,255,.075)}@media (max-width:575.98px){.table-responsive-sm{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch;-ms-overflow-style:-ms-autohiding-scrollbar}.table-responsive-sm>.table-bordered{border:0}}@media (max-width:767.98px){.table-responsive-md{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch;-ms-overflow-style:-ms-autohiding-scrollbar}.table-responsive-md>.table-bordered{border:0}}@media (max-width:991.98px){.table-responsive-lg{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch;-ms-overflow-style:-ms-autohiding-scrollbar}.table-responsive-lg>.table-bordered{border:0}}@media (max-width:1199.98px){.table-responsive-xl{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch;-ms-overflow-style:-ms-autohiding-scrollbar}.table-responsive-xl>.table-bordered{border:0}}.table-responsive{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch;-ms-overflow-style:-ms-autohiding-scrollbar}.table-responsive>.table-bordered{border:0}.form-control{display:block;width:100%;height:calc(2.25rem + 2px);padding:.375rem .75rem;font-size:1rem;line-height:1.5;color:#495057;background-color:#fff;background-clip:padding-box;border:1px solid #ced4da;border-radius:.25rem;transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media screen and (prefers-reduced-motion:reduce){.form-control{transition:none}}.form-control::-ms-expand{background-color:transparent;border:0}.form-control:focus{color:#495057;background-color:#fff;border-color:#80bdff;outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.form-control::-webkit-input-placeholder{color:#6c757d;opacity:1}.form-control::-moz-placeholder{color:#6c757d;opacity:1}.form-control:-ms-input-placeholder{color:#6c757d;opacity:1}.form-control::-ms-input-placeholder{color:#6c757d;opacity:1}.form-control::placeholder{color:#6c757d;opacity:1}.form-control:disabled,.form-control[readonly]{background-color:#e9ecef;opacity:1}select.form-control:focus::-ms-value{color:#495057;background-color:#fff}.form-control-file,.form-control-range{display:block;width:100%}.col-form-label{padding-top:calc(.375rem + 1px);padding-bottom:calc(.375rem + 1px);margin-bottom:0;font-size:inherit;line-height:1.5}.col-form-label-lg{padding-top:calc(.5rem + 1px);padding-bottom:calc(.5rem + 1px);font-size:1.25rem;line-height:1.5}.col-form-label-sm{padding-top:calc(.25rem + 1px);padding-bottom:calc(.25rem + 1px);font-size:.875rem;line-height:1.5}.form-control-plaintext{display:block;width:100%;padding-top:.375rem;padding-bottom:.375rem;margin-bottom:0;line-height:1.5;color:#212529;background-color:transparent;border:solid transparent;border-width:1px 0}.form-control-plaintext.form-control-lg,.form-control-plaintext.form-control-sm{padding-right:0;padding-left:0}.form-control-sm{height:calc(1.8125rem + 2px);padding:.25rem .5rem;font-size:.875rem;line-height:1.5;border-radius:.2rem}.form-control-lg{height:calc(2.875rem + 2px);padding:.5rem 1rem;font-size:1.25rem;line-height:1.5;border-radius:.3rem}select.form-control[multiple],select.form-control[size]{height:auto}textarea.form-control{height:auto}.form-group{margin-bottom:1rem}.form-text{display:block;margin-top:.25rem}.form-row{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;margin-right:-5px;margin-left:-5px}.form-row>.col,.form-row>[class*=col-]{padding-right:5px;padding-left:5px}.form-check{position:relative;display:block;padding-left:1.25rem}.form-check-input{position:absolute;margin-top:.3rem;margin-left:-1.25rem}.form-check-input:disabled~.form-check-label{color:#6c757d}.form-check-label{margin-bottom:0}.form-check-inline{display:-ms-inline-flexbox;display:inline-flex;-ms-flex-align:center;align-items:center;padding-left:0;margin-right:.75rem}.form-check-inline .form-check-input{position:static;margin-top:0;margin-right:.3125rem;margin-left:0}.valid-feedback{display:none;width:100%;margin-top:.25rem;font-size:80%;color:#28a745}.valid-tooltip{position:absolute;top:100%;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:.875rem;line-height:1.5;color:#fff;background-color:rgba(40,167,69,.9);border-radius:.25rem}.custom-select.is-valid,.form-control.is-valid,.was-validated .custom-select:valid,.was-validated .form-control:valid{border-color:#28a745}.custom-select.is-valid:focus,.form-control.is-valid:focus,.was-validated .custom-select:valid:focus,.was-validated .form-control:valid:focus{border-color:#28a745;box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}.custom-select.is-valid~.valid-feedback,.custom-select.is-valid~.valid-tooltip,.form-control.is-valid~.valid-feedback,.form-control.is-valid~.valid-tooltip,.was-validated .custom-select:valid~.valid-feedback,.was-validated .custom-select:valid~.valid-tooltip,.was-validated .form-control:valid~.valid-feedback,.was-validated .form-control:valid~.valid-tooltip{display:block}.form-control-file.is-valid~.valid-feedback,.form-control-file.is-valid~.valid-tooltip,.was-validated .form-control-file:valid~.valid-feedback,.was-validated .form-control-file:valid~.valid-tooltip{display:block}.form-check-input.is-valid~.form-check-label,.was-validated .form-check-input:valid~.form-check-label{color:#28a745}.form-check-input.is-valid~.valid-feedback,.form-check-input.is-valid~.valid-tooltip,.was-validated .form-check-input:valid~.valid-feedback,.was-validated .form-check-input:valid~.valid-tooltip{display:block}.custom-control-input.is-valid~.custom-control-label,.was-validated .custom-control-input:valid~.custom-control-label{color:#28a745}.custom-control-input.is-valid~.custom-control-label::before,.was-validated .custom-control-input:valid~.custom-control-label::before{background-color:#71dd8a}.custom-control-input.is-valid~.valid-feedback,.custom-control-input.is-valid~.valid-tooltip,.was-validated .custom-control-input:valid~.valid-feedback,.was-validated .custom-control-input:valid~.valid-tooltip{display:block}.custom-control-input.is-valid:checked~.custom-control-label::before,.was-validated .custom-control-input:valid:checked~.custom-control-label::before{background-color:#34ce57}.custom-control-input.is-valid:focus~.custom-control-label::before,.was-validated .custom-control-input:valid:focus~.custom-control-label::before{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(40,167,69,.25)}.custom-file-input.is-valid~.custom-file-label,.was-validated .custom-file-input:valid~.custom-file-label{border-color:#28a745}.custom-file-input.is-valid~.custom-file-label::after,.was-validated .custom-file-input:valid~.custom-file-label::after{border-color:inherit}.custom-file-input.is-valid~.valid-feedback,.custom-file-input.is-valid~.valid-tooltip,.was-validated .custom-file-input:valid~.valid-feedback,.was-validated .custom-file-input:valid~.valid-tooltip{display:block}.custom-file-input.is-valid:focus~.custom-file-label,.was-validated .custom-file-input:valid:focus~.custom-file-label{box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}.invalid-feedback{display:none;width:100%;margin-top:.25rem;font-size:80%;color:#dc3545}.invalid-tooltip{position:absolute;top:100%;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:.875rem;line-height:1.5;color:#fff;background-color:rgba(220,53,69,.9);border-radius:.25rem}.custom-select.is-invalid,.form-control.is-invalid,.was-validated .custom-select:invalid,.was-validated .form-control:invalid{border-color:#dc3545}.custom-select.is-invalid:focus,.form-control.is-invalid:focus,.was-validated .custom-select:invalid:focus,.was-validated .form-control:invalid:focus{border-color:#dc3545;box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}.custom-select.is-invalid~.invalid-feedback,.custom-select.is-invalid~.invalid-tooltip,.form-control.is-invalid~.invalid-feedback,.form-control.is-invalid~.invalid-tooltip,.was-validated .custom-select:invalid~.invalid-feedback,.was-validated .custom-select:invalid~.invalid-tooltip,.was-validated .form-control:invalid~.invalid-feedback,.was-validated .form-control:invalid~.invalid-tooltip{display:block}.form-control-file.is-invalid~.invalid-feedback,.form-control-file.is-invalid~.invalid-tooltip,.was-validated .form-control-file:invalid~.invalid-feedback,.was-validated .form-control-file:invalid~.invalid-tooltip{display:block}.form-check-input.is-invalid~.form-check-label,.was-validated .form-check-input:invalid~.form-check-label{color:#dc3545}.form-check-input.is-invalid~.invalid-feedback,.form-check-input.is-invalid~.invalid-tooltip,.was-validated .form-check-input:invalid~.invalid-feedback,.was-validated .form-check-input:invalid~.invalid-tooltip{display:block}.custom-control-input.is-invalid~.custom-control-label,.was-validated .custom-control-input:invalid~.custom-control-label{color:#dc3545}.custom-control-input.is-invalid~.custom-control-label::before,.was-validated .custom-control-input:invalid~.custom-control-label::before{background-color:#efa2a9}.custom-control-input.is-invalid~.invalid-feedback,.custom-control-input.is-invalid~.invalid-tooltip,.was-validated .custom-control-input:invalid~.invalid-feedback,.was-validated .custom-control-input:invalid~.invalid-tooltip{display:block}.custom-control-input.is-invalid:checked~.custom-control-label::before,.was-validated .custom-control-input:invalid:checked~.custom-control-label::before{background-color:#e4606d}.custom-control-input.is-invalid:focus~.custom-control-label::before,.was-validated .custom-control-input:invalid:focus~.custom-control-label::before{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(220,53,69,.25)}.custom-file-input.is-invalid~.custom-file-label,.was-validated .custom-file-input:invalid~.custom-file-label{border-color:#dc3545}.custom-file-input.is-invalid~.custom-file-label::after,.was-validated .custom-file-input:invalid~.custom-file-label::after{border-color:inherit}.custom-file-input.is-invalid~.invalid-feedback,.custom-file-input.is-invalid~.invalid-tooltip,.was-validated .custom-file-input:invalid~.invalid-feedback,.was-validated .custom-file-input:invalid~.invalid-tooltip{display:block}.custom-file-input.is-invalid:focus~.custom-file-label,.was-validated .custom-file-input:invalid:focus~.custom-file-label{box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}.form-inline{display:-ms-flexbox;display:flex;-ms-flex-flow:row wrap;flex-flow:row wrap;-ms-flex-align:center;align-items:center}.form-inline .form-check{width:100%}@media (min-width:576px){.form-inline label{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;margin-bottom:0}.form-inline .form-group{display:-ms-flexbox;display:flex;-ms-flex:0 0 auto;flex:0 0 auto;-ms-flex-flow:row wrap;flex-flow:row wrap;-ms-flex-align:center;align-items:center;margin-bottom:0}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .form-control-plaintext{display:inline-block}.form-inline .custom-select,.form-inline .input-group{width:auto}.form-inline .form-check{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;width:auto;padding-left:0}.form-inline .form-check-input{position:relative;margin-top:0;margin-right:.25rem;margin-left:0}.form-inline .custom-control{-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center}.form-inline .custom-control-label{margin-bottom:0}}.btn{display:inline-block;font-weight:400;text-align:center;white-space:nowrap;vertical-align:middle;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;border:1px solid transparent;padding:.375rem .75rem;font-size:1rem;line-height:1.5;border-radius:.25rem;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media screen and (prefers-reduced-motion:reduce){.btn{transition:none}}.btn:focus,.btn:hover{text-decoration:none}.btn.focus,.btn:focus{outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.btn.disabled,.btn:disabled{opacity:.65}.btn:not(:disabled):not(.disabled){cursor:pointer}a.btn.disabled,fieldset:disabled a.btn{pointer-events:none}.btn-primary{color:#fff;background-color:#007bff;border-color:#007bff}.btn-primary:hover{color:#fff;background-color:#0069d9;border-color:#0062cc}.btn-primary.focus,.btn-primary:focus{box-shadow:0 0 0 .2rem rgba(0,123,255,.5)}.btn-primary.disabled,.btn-primary:disabled{color:#fff;background-color:#007bff;border-color:#007bff}.btn-primary:not(:disabled):not(.disabled).active,.btn-primary:not(:disabled):not(.disabled):active,.show>.btn-primary.dropdown-toggle{color:#fff;background-color:#0062cc;border-color:#005cbf}.btn-primary:not(:disabled):not(.disabled).active:focus,.btn-primary:not(:disabled):not(.disabled):active:focus,.show>.btn-primary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(0,123,255,.5)}.btn-secondary{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-secondary:hover{color:#fff;background-color:#5a6268;border-color:#545b62}.btn-secondary.focus,.btn-secondary:focus{box-shadow:0 0 0 .2rem rgba(108,117,125,.5)}.btn-secondary.disabled,.btn-secondary:disabled{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-secondary:not(:disabled):not(.disabled).active,.btn-secondary:not(:disabled):not(.disabled):active,.show>.btn-secondary.dropdown-toggle{color:#fff;background-color:#545b62;border-color:#4e555b}.btn-secondary:not(:disabled):not(.disabled).active:focus,.btn-secondary:not(:disabled):not(.disabled):active:focus,.show>.btn-secondary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(108,117,125,.5)}.btn-success{color:#fff;background-color:#28a745;border-color:#28a745}.btn-success:hover{color:#fff;background-color:#218838;border-color:#1e7e34}.btn-success.focus,.btn-success:focus{box-shadow:0 0 0 .2rem rgba(40,167,69,.5)}.btn-success.disabled,.btn-success:disabled{color:#fff;background-color:#28a745;border-color:#28a745}.btn-success:not(:disabled):not(.disabled).active,.btn-success:not(:disabled):not(.disabled):active,.show>.btn-success.dropdown-toggle{color:#fff;background-color:#1e7e34;border-color:#1c7430}.btn-success:not(:disabled):not(.disabled).active:focus,.btn-success:not(:disabled):not(.disabled):active:focus,.show>.btn-success.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(40,167,69,.5)}.btn-info{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-info:hover{color:#fff;background-color:#138496;border-color:#117a8b}.btn-info.focus,.btn-info:focus{box-shadow:0 0 0 .2rem rgba(23,162,184,.5)}.btn-info.disabled,.btn-info:disabled{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-info:not(:disabled):not(.disabled).active,.btn-info:not(:disabled):not(.disabled):active,.show>.btn-info.dropdown-toggle{color:#fff;background-color:#117a8b;border-color:#10707f}.btn-info:not(:disabled):not(.disabled).active:focus,.btn-info:not(:disabled):not(.disabled):active:focus,.show>.btn-info.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(23,162,184,.5)}.btn-warning{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-warning:hover{color:#212529;background-color:#e0a800;border-color:#d39e00}.btn-warning.focus,.btn-warning:focus{box-shadow:0 0 0 .2rem rgba(255,193,7,.5)}.btn-warning.disabled,.btn-warning:disabled{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-warning:not(:disabled):not(.disabled).active,.btn-warning:not(:disabled):not(.disabled):active,.show>.btn-warning.dropdown-toggle{color:#212529;background-color:#d39e00;border-color:#c69500}.btn-warning:not(:disabled):not(.disabled).active:focus,.btn-warning:not(:disabled):not(.disabled):active:focus,.show>.btn-warning.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(255,193,7,.5)}.btn-danger{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-danger:hover{color:#fff;background-color:#c82333;border-color:#bd2130}.btn-danger.focus,.btn-danger:focus{box-shadow:0 0 0 .2rem rgba(220,53,69,.5)}.btn-danger.disabled,.btn-danger:disabled{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-danger:not(:disabled):not(.disabled).active,.btn-danger:not(:disabled):not(.disabled):active,.show>.btn-danger.dropdown-toggle{color:#fff;background-color:#bd2130;border-color:#b21f2d}.btn-danger:not(:disabled):not(.disabled).active:focus,.btn-danger:not(:disabled):not(.disabled):active:focus,.show>.btn-danger.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(220,53,69,.5)}.btn-light{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-light:hover{color:#212529;background-color:#e2e6ea;border-color:#dae0e5}.btn-light.focus,.btn-light:focus{box-shadow:0 0 0 .2rem rgba(248,249,250,.5)}.btn-light.disabled,.btn-light:disabled{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-light:not(:disabled):not(.disabled).active,.btn-light:not(:disabled):not(.disabled):active,.show>.btn-light.dropdown-toggle{color:#212529;background-color:#dae0e5;border-color:#d3d9df}.btn-light:not(:disabled):not(.disabled).active:focus,.btn-light:not(:disabled):not(.disabled):active:focus,.show>.btn-light.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(248,249,250,.5)}.btn-dark{color:#fff;background-color:#343a40;border-color:#343a40}.btn-dark:hover{color:#fff;background-color:#23272b;border-color:#1d2124}.btn-dark.focus,.btn-dark:focus{box-shadow:0 0 0 .2rem rgba(52,58,64,.5)}.btn-dark.disabled,.btn-dark:disabled{color:#fff;background-color:#343a40;border-color:#343a40}.btn-dark:not(:disabled):not(.disabled).active,.btn-dark:not(:disabled):not(.disabled):active,.show>.btn-dark.dropdown-toggle{color:#fff;background-color:#1d2124;border-color:#171a1d}.btn-dark:not(:disabled):not(.disabled).active:focus,.btn-dark:not(:disabled):not(.disabled):active:focus,.show>.btn-dark.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(52,58,64,.5)}.btn-outline-primary{color:#007bff;background-color:transparent;background-image:none;border-color:#007bff}.btn-outline-primary:hover{color:#fff;background-color:#007bff;border-color:#007bff}.btn-outline-primary.focus,.btn-outline-primary:focus{box-shadow:0 0 0 .2rem rgba(0,123,255,.5)}.btn-outline-primary.disabled,.btn-outline-primary:disabled{color:#007bff;background-color:transparent}.btn-outline-primary:not(:disabled):not(.disabled).active,.btn-outline-primary:not(:disabled):not(.disabled):active,.show>.btn-outline-primary.dropdown-toggle{color:#fff;background-color:#007bff;border-color:#007bff}.btn-outline-primary:not(:disabled):not(.disabled).active:focus,.btn-outline-primary:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-primary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(0,123,255,.5)}.btn-outline-secondary{color:#6c757d;background-color:transparent;background-image:none;border-color:#6c757d}.btn-outline-secondary:hover{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-outline-secondary.focus,.btn-outline-secondary:focus{box-shadow:0 0 0 .2rem rgba(108,117,125,.5)}.btn-outline-secondary.disabled,.btn-outline-secondary:disabled{color:#6c757d;background-color:transparent}.btn-outline-secondary:not(:disabled):not(.disabled).active,.btn-outline-secondary:not(:disabled):not(.disabled):active,.show>.btn-outline-secondary.dropdown-toggle{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-outline-secondary:not(:disabled):not(.disabled).active:focus,.btn-outline-secondary:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-secondary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(108,117,125,.5)}.btn-outline-success{color:#28a745;background-color:transparent;background-image:none;border-color:#28a745}.btn-outline-success:hover{color:#fff;background-color:#28a745;border-color:#28a745}.btn-outline-success.focus,.btn-outline-success:focus{box-shadow:0 0 0 .2rem rgba(40,167,69,.5)}.btn-outline-success.disabled,.btn-outline-success:disabled{color:#28a745;background-color:transparent}.btn-outline-success:not(:disabled):not(.disabled).active,.btn-outline-success:not(:disabled):not(.disabled):active,.show>.btn-outline-success.dropdown-toggle{color:#fff;background-color:#28a745;border-color:#28a745}.btn-outline-success:not(:disabled):not(.disabled).active:focus,.btn-outline-success:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-success.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(40,167,69,.5)}.btn-outline-info{color:#17a2b8;background-color:transparent;background-image:none;border-color:#17a2b8}.btn-outline-info:hover{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-outline-info.focus,.btn-outline-info:focus{box-shadow:0 0 0 .2rem rgba(23,162,184,.5)}.btn-outline-info.disabled,.btn-outline-info:disabled{color:#17a2b8;background-color:transparent}.btn-outline-info:not(:disabled):not(.disabled).active,.btn-outline-info:not(:disabled):not(.disabled):active,.show>.btn-outline-info.dropdown-toggle{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-outline-info:not(:disabled):not(.disabled).active:focus,.btn-outline-info:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-info.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(23,162,184,.5)}.btn-outline-warning{color:#ffc107;background-color:transparent;background-image:none;border-color:#ffc107}.btn-outline-warning:hover{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-outline-warning.focus,.btn-outline-warning:focus{box-shadow:0 0 0 .2rem rgba(255,193,7,.5)}.btn-outline-warning.disabled,.btn-outline-warning:disabled{color:#ffc107;background-color:transparent}.btn-outline-warning:not(:disabled):not(.disabled).active,.btn-outline-warning:not(:disabled):not(.disabled):active,.show>.btn-outline-warning.dropdown-toggle{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-outline-warning:not(:disabled):not(.disabled).active:focus,.btn-outline-warning:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-warning.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(255,193,7,.5)}.btn-outline-danger{color:#dc3545;background-color:transparent;background-image:none;border-color:#dc3545}.btn-outline-danger:hover{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-outline-danger.focus,.btn-outline-danger:focus{box-shadow:0 0 0 .2rem rgba(220,53,69,.5)}.btn-outline-danger.disabled,.btn-outline-danger:disabled{color:#dc3545;background-color:transparent}.btn-outline-danger:not(:disabled):not(.disabled).active,.btn-outline-danger:not(:disabled):not(.disabled):active,.show>.btn-outline-danger.dropdown-toggle{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-outline-danger:not(:disabled):not(.disabled).active:focus,.btn-outline-danger:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-danger.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(220,53,69,.5)}.btn-outline-light{color:#f8f9fa;background-color:transparent;background-image:none;border-color:#f8f9fa}.btn-outline-light:hover{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-outline-light.focus,.btn-outline-light:focus{box-shadow:0 0 0 .2rem rgba(248,249,250,.5)}.btn-outline-light.disabled,.btn-outline-light:disabled{color:#f8f9fa;background-color:transparent}.btn-outline-light:not(:disabled):not(.disabled).active,.btn-outline-light:not(:disabled):not(.disabled):active,.show>.btn-outline-light.dropdown-toggle{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-outline-light:not(:disabled):not(.disabled).active:focus,.btn-outline-light:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-light.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(248,249,250,.5)}.btn-outline-dark{color:#343a40;background-color:transparent;background-image:none;border-color:#343a40}.btn-outline-dark:hover{color:#fff;background-color:#343a40;border-color:#343a40}.btn-outline-dark.focus,.btn-outline-dark:focus{box-shadow:0 0 0 .2rem rgba(52,58,64,.5)}.btn-outline-dark.disabled,.btn-outline-dark:disabled{color:#343a40;background-color:transparent}.btn-outline-dark:not(:disabled):not(.disabled).active,.btn-outline-dark:not(:disabled):not(.disabled):active,.show>.btn-outline-dark.dropdown-toggle{color:#fff;background-color:#343a40;border-color:#343a40}.btn-outline-dark:not(:disabled):not(.disabled).active:focus,.btn-outline-dark:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-dark.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(52,58,64,.5)}.btn-link{font-weight:400;color:#007bff;background-color:transparent}.btn-link:hover{color:#0056b3;text-decoration:underline;background-color:transparent;border-color:transparent}.btn-link.focus,.btn-link:focus{text-decoration:underline;border-color:transparent;box-shadow:none}.btn-link.disabled,.btn-link:disabled{color:#6c757d;pointer-events:none}.btn-group-lg>.btn,.btn-lg{padding:.5rem 1rem;font-size:1.25rem;line-height:1.5;border-radius:.3rem}.btn-group-sm>.btn,.btn-sm{padding:.25rem .5rem;font-size:.875rem;line-height:1.5;border-radius:.2rem}.btn-block{display:block;width:100%}.btn-block+.btn-block{margin-top:.5rem}input[type=button].btn-block,input[type=reset].btn-block,input[type=submit].btn-block{width:100%}.fade{transition:opacity .15s linear}@media screen and (prefers-reduced-motion:reduce){.fade{transition:none}}.fade:not(.show){opacity:0}.collapse:not(.show){display:none}.collapsing{position:relative;height:0;overflow:hidden;transition:height .35s ease}@media screen and (prefers-reduced-motion:reduce){.collapsing{transition:none}}.dropdown,.dropleft,.dropright,.dropup{position:relative}.dropdown-toggle::after{display:inline-block;width:0;height:0;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid;border-right:.3em solid transparent;border-bottom:0;border-left:.3em solid transparent}.dropdown-toggle:empty::after{margin-left:0}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:10rem;padding:.5rem 0;margin:.125rem 0 0;font-size:1rem;color:#212529;text-align:left;list-style:none;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.15);border-radius:.25rem}.dropdown-menu-right{right:0;left:auto}.dropup .dropdown-menu{top:auto;bottom:100%;margin-top:0;margin-bottom:.125rem}.dropup .dropdown-toggle::after{display:inline-block;width:0;height:0;margin-left:.255em;vertical-align:.255em;content:"";border-top:0;border-right:.3em solid transparent;border-bottom:.3em solid;border-left:.3em solid transparent}.dropup .dropdown-toggle:empty::after{margin-left:0}.dropright .dropdown-menu{top:0;right:auto;left:100%;margin-top:0;margin-left:.125rem}.dropright .dropdown-toggle::after{display:inline-block;width:0;height:0;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-right:0;border-bottom:.3em solid transparent;border-left:.3em solid}.dropright .dropdown-toggle:empty::after{margin-left:0}.dropright .dropdown-toggle::after{vertical-align:0}.dropleft .dropdown-menu{top:0;right:100%;left:auto;margin-top:0;margin-right:.125rem}.dropleft .dropdown-toggle::after{display:inline-block;width:0;height:0;margin-left:.255em;vertical-align:.255em;content:""}.dropleft .dropdown-toggle::after{display:none}.dropleft .dropdown-toggle::before{display:inline-block;width:0;height:0;margin-right:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-right:.3em solid;border-bottom:.3em solid transparent}.dropleft .dropdown-toggle:empty::after{margin-left:0}.dropleft .dropdown-toggle::before{vertical-align:0}.dropdown-menu[x-placement^=bottom],.dropdown-menu[x-placement^=left],.dropdown-menu[x-placement^=right],.dropdown-menu[x-placement^=top]{right:auto;bottom:auto}.dropdown-divider{height:0;margin:.5rem 0;overflow:hidden;border-top:1px solid #e9ecef}.dropdown-item{display:block;width:100%;padding:.25rem 1.5rem;clear:both;font-weight:400;color:#212529;text-align:inherit;white-space:nowrap;background-color:transparent;border:0}.dropdown-item:focus,.dropdown-item:hover{color:#16181b;text-decoration:none;background-color:#f8f9fa}.dropdown-item.active,.dropdown-item:active{color:#fff;text-decoration:none;background-color:#007bff}.dropdown-item.disabled,.dropdown-item:disabled{color:#6c757d;background-color:transparent}.dropdown-menu.show{display:block}.dropdown-header{display:block;padding:.5rem 1.5rem;margin-bottom:0;font-size:.875rem;color:#6c757d;white-space:nowrap}.dropdown-item-text{display:block;padding:.25rem 1.5rem;color:#212529}.btn-group,.btn-group-vertical{position:relative;display:-ms-inline-flexbox;display:inline-flex;vertical-align:middle}.btn-group-vertical>.btn,.btn-group>.btn{position:relative;-ms-flex:0 1 auto;flex:0 1 auto}.btn-group-vertical>.btn:hover,.btn-group>.btn:hover{z-index:1}.btn-group-vertical>.btn.active,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn:focus,.btn-group>.btn.active,.btn-group>.btn:active,.btn-group>.btn:focus{z-index:1}.btn-group .btn+.btn,.btn-group .btn+.btn-group,.btn-group .btn-group+.btn,.btn-group .btn-group+.btn-group,.btn-group-vertical .btn+.btn,.btn-group-vertical .btn+.btn-group,.btn-group-vertical .btn-group+.btn,.btn-group-vertical .btn-group+.btn-group{margin-left:-1px}.btn-toolbar{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-pack:start;justify-content:flex-start}.btn-toolbar .input-group{width:auto}.btn-group>.btn:first-child{margin-left:0}.btn-group>.btn-group:not(:last-child)>.btn,.btn-group>.btn:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn-group:not(:first-child)>.btn,.btn-group>.btn:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.dropdown-toggle-split{padding-right:.5625rem;padding-left:.5625rem}.dropdown-toggle-split::after,.dropright .dropdown-toggle-split::after,.dropup .dropdown-toggle-split::after{margin-left:0}.dropleft .dropdown-toggle-split::before{margin-right:0}.btn-group-sm>.btn+.dropdown-toggle-split,.btn-sm+.dropdown-toggle-split{padding-right:.375rem;padding-left:.375rem}.btn-group-lg>.btn+.dropdown-toggle-split,.btn-lg+.dropdown-toggle-split{padding-right:.75rem;padding-left:.75rem}.btn-group-vertical{-ms-flex-direction:column;flex-direction:column;-ms-flex-align:start;align-items:flex-start;-ms-flex-pack:center;justify-content:center}.btn-group-vertical .btn,.btn-group-vertical .btn-group{width:100%}.btn-group-vertical>.btn+.btn,.btn-group-vertical>.btn+.btn-group,.btn-group-vertical>.btn-group+.btn,.btn-group-vertical>.btn-group+.btn-group{margin-top:-1px;margin-left:0}.btn-group-vertical>.btn-group:not(:last-child)>.btn,.btn-group-vertical>.btn:not(:last-child):not(.dropdown-toggle){border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:not(:first-child)>.btn,.btn-group-vertical>.btn:not(:first-child){border-top-left-radius:0;border-top-right-radius:0}.btn-group-toggle>.btn,.btn-group-toggle>.btn-group>.btn{margin-bottom:0}.btn-group-toggle>.btn input[type=checkbox],.btn-group-toggle>.btn input[type=radio],.btn-group-toggle>.btn-group>.btn input[type=checkbox],.btn-group-toggle>.btn-group>.btn input[type=radio]{position:absolute;clip:rect(0,0,0,0);pointer-events:none}.input-group{position:relative;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-align:stretch;align-items:stretch;width:100%}.input-group>.custom-file,.input-group>.custom-select,.input-group>.form-control{position:relative;-ms-flex:1 1 auto;flex:1 1 auto;width:1%;margin-bottom:0}.input-group>.custom-file+.custom-file,.input-group>.custom-file+.custom-select,.input-group>.custom-file+.form-control,.input-group>.custom-select+.custom-file,.input-group>.custom-select+.custom-select,.input-group>.custom-select+.form-control,.input-group>.form-control+.custom-file,.input-group>.form-control+.custom-select,.input-group>.form-control+.form-control{margin-left:-1px}.input-group>.custom-file .custom-file-input:focus~.custom-file-label,.input-group>.custom-select:focus,.input-group>.form-control:focus{z-index:3}.input-group>.custom-file .custom-file-input:focus{z-index:4}.input-group>.custom-select:not(:last-child),.input-group>.form-control:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}.input-group>.custom-select:not(:first-child),.input-group>.form-control:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.input-group>.custom-file{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center}.input-group>.custom-file:not(:last-child) .custom-file-label,.input-group>.custom-file:not(:last-child) .custom-file-label::after{border-top-right-radius:0;border-bottom-right-radius:0}.input-group>.custom-file:not(:first-child) .custom-file-label{border-top-left-radius:0;border-bottom-left-radius:0}.input-group-append,.input-group-prepend{display:-ms-flexbox;display:flex}.input-group-append .btn,.input-group-prepend .btn{position:relative;z-index:2}.input-group-append .btn+.btn,.input-group-append .btn+.input-group-text,.input-group-append .input-group-text+.btn,.input-group-append .input-group-text+.input-group-text,.input-group-prepend .btn+.btn,.input-group-prepend .btn+.input-group-text,.input-group-prepend .input-group-text+.btn,.input-group-prepend .input-group-text+.input-group-text{margin-left:-1px}.input-group-prepend{margin-right:-1px}.input-group-append{margin-left:-1px}.input-group-text{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;padding:.375rem .75rem;margin-bottom:0;font-size:1rem;font-weight:400;line-height:1.5;color:#495057;text-align:center;white-space:nowrap;background-color:#e9ecef;border:1px solid #ced4da;border-radius:.25rem}.input-group-text input[type=checkbox],.input-group-text input[type=radio]{margin-top:0}.input-group-lg>.form-control,.input-group-lg>.input-group-append>.btn,.input-group-lg>.input-group-append>.input-group-text,.input-group-lg>.input-group-prepend>.btn,.input-group-lg>.input-group-prepend>.input-group-text{height:calc(2.875rem + 2px);padding:.5rem 1rem;font-size:1.25rem;line-height:1.5;border-radius:.3rem}.input-group-sm>.form-control,.input-group-sm>.input-group-append>.btn,.input-group-sm>.input-group-append>.input-group-text,.input-group-sm>.input-group-prepend>.btn,.input-group-sm>.input-group-prepend>.input-group-text{height:calc(1.8125rem + 2px);padding:.25rem .5rem;font-size:.875rem;line-height:1.5;border-radius:.2rem}.input-group>.input-group-append:last-child>.btn:not(:last-child):not(.dropdown-toggle),.input-group>.input-group-append:last-child>.input-group-text:not(:last-child),.input-group>.input-group-append:not(:last-child)>.btn,.input-group>.input-group-append:not(:last-child)>.input-group-text,.input-group>.input-group-prepend>.btn,.input-group>.input-group-prepend>.input-group-text{border-top-right-radius:0;border-bottom-right-radius:0}.input-group>.input-group-append>.btn,.input-group>.input-group-append>.input-group-text,.input-group>.input-group-prepend:first-child>.btn:not(:first-child),.input-group>.input-group-prepend:first-child>.input-group-text:not(:first-child),.input-group>.input-group-prepend:not(:first-child)>.btn,.input-group>.input-group-prepend:not(:first-child)>.input-group-text{border-top-left-radius:0;border-bottom-left-radius:0}.custom-control{position:relative;display:block;min-height:1.5rem;padding-left:1.5rem}.custom-control-inline{display:-ms-inline-flexbox;display:inline-flex;margin-right:1rem}.custom-control-input{position:absolute;z-index:-1;opacity:0}.custom-control-input:checked~.custom-control-label::before{color:#fff;background-color:#007bff}.custom-control-input:focus~.custom-control-label::before{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(0,123,255,.25)}.custom-control-input:active~.custom-control-label::before{color:#fff;background-color:#b3d7ff}.custom-control-input:disabled~.custom-control-label{color:#6c757d}.custom-control-input:disabled~.custom-control-label::before{background-color:#e9ecef}.custom-control-label{position:relative;margin-bottom:0}.custom-control-label::before{position:absolute;top:.25rem;left:-1.5rem;display:block;width:1rem;height:1rem;pointer-events:none;content:"";-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-color:#dee2e6}.custom-control-label::after{position:absolute;top:.25rem;left:-1.5rem;display:block;width:1rem;height:1rem;content:"";background-repeat:no-repeat;background-position:center center;background-size:50% 50%}.custom-checkbox .custom-control-label::before{border-radius:.25rem}.custom-checkbox .custom-control-input:checked~.custom-control-label::before{background-color:#007bff}.custom-checkbox .custom-control-input:checked~.custom-control-label::after{background-image:url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3E%3Cpath fill='%23fff' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26 2.974 7.25 8 2.193z'/%3E%3C/svg%3E")}.custom-checkbox .custom-control-input:indeterminate~.custom-control-label::before{background-color:#007bff}.custom-checkbox .custom-control-input:indeterminate~.custom-control-label::after{background-image:url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 4'%3E%3Cpath stroke='%23fff' d='M0 2h4'/%3E%3C/svg%3E")}.custom-checkbox .custom-control-input:disabled:checked~.custom-control-label::before{background-color:rgba(0,123,255,.5)}.custom-checkbox .custom-control-input:disabled:indeterminate~.custom-control-label::before{background-color:rgba(0,123,255,.5)}.custom-radio .custom-control-label::before{border-radius:50%}.custom-radio .custom-control-input:checked~.custom-control-label::before{background-color:#007bff}.custom-radio .custom-control-input:checked~.custom-control-label::after{background-image:url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3E%3Ccircle r='3' fill='%23fff'/%3E%3C/svg%3E")}.custom-radio .custom-control-input:disabled:checked~.custom-control-label::before{background-color:rgba(0,123,255,.5)}.custom-select{display:inline-block;width:100%;height:calc(2.25rem + 2px);padding:.375rem 1.75rem .375rem .75rem;line-height:1.5;color:#495057;vertical-align:middle;background:#fff url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 5'%3E%3Cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3E%3C/svg%3E") no-repeat right .75rem center;background-size:8px 10px;border:1px solid #ced4da;border-radius:.25rem;-webkit-appearance:none;-moz-appearance:none;appearance:none}.custom-select:focus{border-color:#80bdff;outline:0;box-shadow:0 0 0 .2rem rgba(128,189,255,.5)}.custom-select:focus::-ms-value{color:#495057;background-color:#fff}.custom-select[multiple],.custom-select[size]:not([size="1"]){height:auto;padding-right:.75rem;background-image:none}.custom-select:disabled{color:#6c757d;background-color:#e9ecef}.custom-select::-ms-expand{opacity:0}.custom-select-sm{height:calc(1.8125rem + 2px);padding-top:.375rem;padding-bottom:.375rem;font-size:75%}.custom-select-lg{height:calc(2.875rem + 2px);padding-top:.375rem;padding-bottom:.375rem;font-size:125%}.custom-file{position:relative;display:inline-block;width:100%;height:calc(2.25rem + 2px);margin-bottom:0}.custom-file-input{position:relative;z-index:2;width:100%;height:calc(2.25rem + 2px);margin:0;opacity:0}.custom-file-input:focus~.custom-file-label{border-color:#80bdff;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.custom-file-input:focus~.custom-file-label::after{border-color:#80bdff}.custom-file-input:disabled~.custom-file-label{background-color:#e9ecef}.custom-file-input:lang(en)~.custom-file-label::after{content:"Browse"}.custom-file-label{position:absolute;top:0;right:0;left:0;z-index:1;height:calc(2.25rem + 2px);padding:.375rem .75rem;line-height:1.5;color:#495057;background-color:#fff;border:1px solid #ced4da;border-radius:.25rem}.custom-file-label::after{position:absolute;top:0;right:0;bottom:0;z-index:3;display:block;height:2.25rem;padding:.375rem .75rem;line-height:1.5;color:#495057;content:"Browse";background-color:#e9ecef;border-left:1px solid #ced4da;border-radius:0 .25rem .25rem 0}.custom-range{width:100%;padding-left:0;background-color:transparent;-webkit-appearance:none;-moz-appearance:none;appearance:none}.custom-range:focus{outline:0}.custom-range:focus::-webkit-slider-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(0,123,255,.25)}.custom-range:focus::-moz-range-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(0,123,255,.25)}.custom-range:focus::-ms-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(0,123,255,.25)}.custom-range::-moz-focus-outer{border:0}.custom-range::-webkit-slider-thumb{width:1rem;height:1rem;margin-top:-.25rem;background-color:#007bff;border:0;border-radius:1rem;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;-webkit-appearance:none;appearance:none}@media screen and (prefers-reduced-motion:reduce){.custom-range::-webkit-slider-thumb{transition:none}}.custom-range::-webkit-slider-thumb:active{background-color:#b3d7ff}.custom-range::-webkit-slider-runnable-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:#dee2e6;border-color:transparent;border-radius:1rem}.custom-range::-moz-range-thumb{width:1rem;height:1rem;background-color:#007bff;border:0;border-radius:1rem;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;-moz-appearance:none;appearance:none}@media screen and (prefers-reduced-motion:reduce){.custom-range::-moz-range-thumb{transition:none}}.custom-range::-moz-range-thumb:active{background-color:#b3d7ff}.custom-range::-moz-range-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:#dee2e6;border-color:transparent;border-radius:1rem}.custom-range::-ms-thumb{width:1rem;height:1rem;margin-top:0;margin-right:.2rem;margin-left:.2rem;background-color:#007bff;border:0;border-radius:1rem;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;appearance:none}@media screen and (prefers-reduced-motion:reduce){.custom-range::-ms-thumb{transition:none}}.custom-range::-ms-thumb:active{background-color:#b3d7ff}.custom-range::-ms-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:transparent;border-color:transparent;border-width:.5rem}.custom-range::-ms-fill-lower{background-color:#dee2e6;border-radius:1rem}.custom-range::-ms-fill-upper{margin-right:15px;background-color:#dee2e6;border-radius:1rem}.custom-control-label::before,.custom-file-label,.custom-select{transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media screen and (prefers-reduced-motion:reduce){.custom-control-label::before,.custom-file-label,.custom-select{transition:none}}.nav{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;padding-left:0;margin-bottom:0;list-style:none}.nav-link{display:block;padding:.5rem 1rem}.nav-link:focus,.nav-link:hover{text-decoration:none}.nav-link.disabled{color:#6c757d}.nav-tabs{border-bottom:1px solid #dee2e6}.nav-tabs .nav-item{margin-bottom:-1px}.nav-tabs .nav-link{border:1px solid transparent;border-top-left-radius:.25rem;border-top-right-radius:.25rem}.nav-tabs .nav-link:focus,.nav-tabs .nav-link:hover{border-color:#e9ecef #e9ecef #dee2e6}.nav-tabs .nav-link.disabled{color:#6c757d;background-color:transparent;border-color:transparent}.nav-tabs .nav-item.show .nav-link,.nav-tabs .nav-link.active{color:#495057;background-color:#fff;border-color:#dee2e6 #dee2e6 #fff}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-left-radius:0;border-top-right-radius:0}.nav-pills .nav-link{border-radius:.25rem}.nav-pills .nav-link.active,.nav-pills .show>.nav-link{color:#fff;background-color:#007bff}.nav-fill .nav-item{-ms-flex:1 1 auto;flex:1 1 auto;text-align:center}.nav-justified .nav-item{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;text-align:center}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.navbar{position:relative;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-align:center;align-items:center;-ms-flex-pack:justify;justify-content:space-between;padding:.5rem 1rem}.navbar>.container,.navbar>.container-fluid{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-align:center;align-items:center;-ms-flex-pack:justify;justify-content:space-between}.navbar-brand{display:inline-block;padding-top:.3125rem;padding-bottom:.3125rem;margin-right:1rem;font-size:1.25rem;line-height:inherit;white-space:nowrap}.navbar-brand:focus,.navbar-brand:hover{text-decoration:none}.navbar-nav{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;padding-left:0;margin-bottom:0;list-style:none}.navbar-nav .nav-link{padding-right:0;padding-left:0}.navbar-nav .dropdown-menu{position:static;float:none}.navbar-text{display:inline-block;padding-top:.5rem;padding-bottom:.5rem}.navbar-collapse{-ms-flex-preferred-size:100%;flex-basis:100%;-ms-flex-positive:1;flex-grow:1;-ms-flex-align:center;align-items:center}.navbar-toggler{padding:.25rem .75rem;font-size:1.25rem;line-height:1;background-color:transparent;border:1px solid transparent;border-radius:.25rem}.navbar-toggler:focus,.navbar-toggler:hover{text-decoration:none}.navbar-toggler:not(:disabled):not(.disabled){cursor:pointer}.navbar-toggler-icon{display:inline-block;width:1.5em;height:1.5em;vertical-align:middle;content:"";background:no-repeat center center;background-size:100% 100%}@media (max-width:575.98px){.navbar-expand-sm>.container,.navbar-expand-sm>.container-fluid{padding-right:0;padding-left:0}}@media (min-width:576px){.navbar-expand-sm{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand-sm .navbar-nav{-ms-flex-direction:row;flex-direction:row}.navbar-expand-sm .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-sm .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-sm>.container,.navbar-expand-sm>.container-fluid{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand-sm .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand-sm .navbar-toggler{display:none}}@media (max-width:767.98px){.navbar-expand-md>.container,.navbar-expand-md>.container-fluid{padding-right:0;padding-left:0}}@media (min-width:768px){.navbar-expand-md{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand-md .navbar-nav{-ms-flex-direction:row;flex-direction:row}.navbar-expand-md .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-md .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-md>.container,.navbar-expand-md>.container-fluid{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand-md .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand-md .navbar-toggler{display:none}}@media (max-width:991.98px){.navbar-expand-lg>.container,.navbar-expand-lg>.container-fluid{padding-right:0;padding-left:0}}@media (min-width:992px){.navbar-expand-lg{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand-lg .navbar-nav{-ms-flex-direction:row;flex-direction:row}.navbar-expand-lg .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-lg .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-lg>.container,.navbar-expand-lg>.container-fluid{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand-lg .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand-lg .navbar-toggler{display:none}}@media (max-width:1199.98px){.navbar-expand-xl>.container,.navbar-expand-xl>.container-fluid{padding-right:0;padding-left:0}}@media (min-width:1200px){.navbar-expand-xl{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand-xl .navbar-nav{-ms-flex-direction:row;flex-direction:row}.navbar-expand-xl .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-xl .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-xl>.container,.navbar-expand-xl>.container-fluid{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand-xl .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand-xl .navbar-toggler{display:none}}.navbar-expand{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand>.container,.navbar-expand>.container-fluid{padding-right:0;padding-left:0}.navbar-expand .navbar-nav{-ms-flex-direction:row;flex-direction:row}.navbar-expand .navbar-nav .dropdown-menu{position:absolute}.navbar-expand .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand>.container,.navbar-expand>.container-fluid{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand .navbar-toggler{display:none}.navbar-light .navbar-brand{color:rgba(0,0,0,.9)}.navbar-light .navbar-brand:focus,.navbar-light .navbar-brand:hover{color:rgba(0,0,0,.9)}.navbar-light .navbar-nav .nav-link{color:rgba(0,0,0,.5)}.navbar-light .navbar-nav .nav-link:focus,.navbar-light .navbar-nav .nav-link:hover{color:rgba(0,0,0,.7)}.navbar-light .navbar-nav .nav-link.disabled{color:rgba(0,0,0,.3)}.navbar-light .navbar-nav .active>.nav-link,.navbar-light .navbar-nav .nav-link.active,.navbar-light .navbar-nav .nav-link.show,.navbar-light .navbar-nav .show>.nav-link{color:rgba(0,0,0,.9)}.navbar-light .navbar-toggler{color:rgba(0,0,0,.5);border-color:rgba(0,0,0,.1)}.navbar-light .navbar-toggler-icon{background-image:url("data:image/svg+xml;charset=utf8,%3Csvg viewBox='0 0 30 30' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath stroke='rgba(0, 0, 0, 0.5)' stroke-width='2' stroke-linecap='round' stroke-miterlimit='10' d='M4 7h22M4 15h22M4 23h22'/%3E%3C/svg%3E")}.navbar-light .navbar-text{color:rgba(0,0,0,.5)}.navbar-light .navbar-text a{color:rgba(0,0,0,.9)}.navbar-light .navbar-text a:focus,.navbar-light .navbar-text a:hover{color:rgba(0,0,0,.9)}.navbar-dark .navbar-brand{color:#fff}.navbar-dark .navbar-brand:focus,.navbar-dark .navbar-brand:hover{color:#fff}.navbar-dark .navbar-nav .nav-link{color:rgba(255,255,255,.5)}.navbar-dark .navbar-nav .nav-link:focus,.navbar-dark .navbar-nav .nav-link:hover{color:rgba(255,255,255,.75)}.navbar-dark .navbar-nav .nav-link.disabled{color:rgba(255,255,255,.25)}.navbar-dark .navbar-nav .active>.nav-link,.navbar-dark .navbar-nav .nav-link.active,.navbar-dark .navbar-nav .nav-link.show,.navbar-dark .navbar-nav .show>.nav-link{color:#fff}.navbar-dark .navbar-toggler{color:rgba(255,255,255,.5);border-color:rgba(255,255,255,.1)}.navbar-dark .navbar-toggler-icon{background-image:url("data:image/svg+xml;charset=utf8,%3Csvg viewBox='0 0 30 30' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath stroke='rgba(255, 255, 255, 0.5)' stroke-width='2' stroke-linecap='round' stroke-miterlimit='10' d='M4 7h22M4 15h22M4 23h22'/%3E%3C/svg%3E")}.navbar-dark .navbar-text{color:rgba(255,255,255,.5)}.navbar-dark .navbar-text a{color:#fff}.navbar-dark .navbar-text a:focus,.navbar-dark .navbar-text a:hover{color:#fff}.card{position:relative;display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;min-width:0;word-wrap:break-word;background-color:#fff;background-clip:border-box;border:1px solid rgba(0,0,0,.125);border-radius:.25rem}.card>hr{margin-right:0;margin-left:0}.card>.list-group:first-child .list-group-item:first-child{border-top-left-radius:.25rem;border-top-right-radius:.25rem}.card>.list-group:last-child .list-group-item:last-child{border-bottom-right-radius:.25rem;border-bottom-left-radius:.25rem}.card-body{-ms-flex:1 1 auto;flex:1 1 auto;padding:1.25rem}.card-title{margin-bottom:.75rem}.card-subtitle{margin-top:-.375rem;margin-bottom:0}.card-text:last-child{margin-bottom:0}.card-link:hover{text-decoration:none}.card-link+.card-link{margin-left:1.25rem}.card-header{padding:.75rem 1.25rem;margin-bottom:0;background-color:rgba(0,0,0,.03);border-bottom:1px solid rgba(0,0,0,.125)}.card-header:first-child{border-radius:calc(.25rem - 1px) calc(.25rem - 1px) 0 0}.card-header+.list-group .list-group-item:first-child{border-top:0}.card-footer{padding:.75rem 1.25rem;background-color:rgba(0,0,0,.03);border-top:1px solid rgba(0,0,0,.125)}.card-footer:last-child{border-radius:0 0 calc(.25rem - 1px) calc(.25rem - 1px)}.card-header-tabs{margin-right:-.625rem;margin-bottom:-.75rem;margin-left:-.625rem;border-bottom:0}.card-header-pills{margin-right:-.625rem;margin-left:-.625rem}.card-img-overlay{position:absolute;top:0;right:0;bottom:0;left:0;padding:1.25rem}.card-img{width:100%;border-radius:calc(.25rem - 1px)}.card-img-top{width:100%;border-top-left-radius:calc(.25rem - 1px);border-top-right-radius:calc(.25rem - 1px)}.card-img-bottom{width:100%;border-bottom-right-radius:calc(.25rem - 1px);border-bottom-left-radius:calc(.25rem - 1px)}.card-deck{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column}.card-deck .card{margin-bottom:15px}@media (min-width:576px){.card-deck{-ms-flex-flow:row wrap;flex-flow:row wrap;margin-right:-15px;margin-left:-15px}.card-deck .card{display:-ms-flexbox;display:flex;-ms-flex:1 0 0%;flex:1 0 0%;-ms-flex-direction:column;flex-direction:column;margin-right:15px;margin-bottom:0;margin-left:15px}}.card-group{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column}.card-group>.card{margin-bottom:15px}@media (min-width:576px){.card-group{-ms-flex-flow:row wrap;flex-flow:row wrap}.card-group>.card{-ms-flex:1 0 0%;flex:1 0 0%;margin-bottom:0}.card-group>.card+.card{margin-left:0;border-left:0}.card-group>.card:first-child{border-top-right-radius:0;border-bottom-right-radius:0}.card-group>.card:first-child .card-header,.card-group>.card:first-child .card-img-top{border-top-right-radius:0}.card-group>.card:first-child .card-footer,.card-group>.card:first-child .card-img-bottom{border-bottom-right-radius:0}.card-group>.card:last-child{border-top-left-radius:0;border-bottom-left-radius:0}.card-group>.card:last-child .card-header,.card-group>.card:last-child .card-img-top{border-top-left-radius:0}.card-group>.card:last-child .card-footer,.card-group>.card:last-child .card-img-bottom{border-bottom-left-radius:0}.card-group>.card:only-child{border-radius:.25rem}.card-group>.card:only-child .card-header,.card-group>.card:only-child .card-img-top{border-top-left-radius:.25rem;border-top-right-radius:.25rem}.card-group>.card:only-child .card-footer,.card-group>.card:only-child .card-img-bottom{border-bottom-right-radius:.25rem;border-bottom-left-radius:.25rem}.card-group>.card:not(:first-child):not(:last-child):not(:only-child){border-radius:0}.card-group>.card:not(:first-child):not(:last-child):not(:only-child) .card-footer,.card-group>.card:not(:first-child):not(:last-child):not(:only-child) .card-header,.card-group>.card:not(:first-child):not(:last-child):not(:only-child) .card-img-bottom,.card-group>.card:not(:first-child):not(:last-child):not(:only-child) .card-img-top{border-radius:0}}.card-columns .card{margin-bottom:.75rem}@media (min-width:576px){.card-columns{-webkit-column-count:3;-moz-column-count:3;column-count:3;-webkit-column-gap:1.25rem;-moz-column-gap:1.25rem;column-gap:1.25rem;orphans:1;widows:1}.card-columns .card{display:inline-block;width:100%}}.accordion .card:not(:first-of-type):not(:last-of-type){border-bottom:0;border-radius:0}.accordion .card:not(:first-of-type) .card-header:first-child{border-radius:0}.accordion .card:first-of-type{border-bottom:0;border-bottom-right-radius:0;border-bottom-left-radius:0}.accordion .card:last-of-type{border-top-left-radius:0;border-top-right-radius:0}.breadcrumb{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;padding:.75rem 1rem;margin-bottom:1rem;list-style:none;background-color:#e9ecef;border-radius:.25rem}.breadcrumb-item+.breadcrumb-item{padding-left:.5rem}.breadcrumb-item+.breadcrumb-item::before{display:inline-block;padding-right:.5rem;color:#6c757d;content:"/"}.breadcrumb-item+.breadcrumb-item:hover::before{text-decoration:underline}.breadcrumb-item+.breadcrumb-item:hover::before{text-decoration:none}.breadcrumb-item.active{color:#6c757d}.pagination{display:-ms-flexbox;display:flex;padding-left:0;list-style:none;border-radius:.25rem}.page-link{position:relative;display:block;padding:.5rem .75rem;margin-left:-1px;line-height:1.25;color:#007bff;background-color:#fff;border:1px solid #dee2e6}.page-link:hover{z-index:2;color:#0056b3;text-decoration:none;background-color:#e9ecef;border-color:#dee2e6}.page-link:focus{z-index:2;outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.page-link:not(:disabled):not(.disabled){cursor:pointer}.page-item:first-child .page-link{margin-left:0;border-top-left-radius:.25rem;border-bottom-left-radius:.25rem}.page-item:last-child .page-link{border-top-right-radius:.25rem;border-bottom-right-radius:.25rem}.page-item.active .page-link{z-index:1;color:#fff;background-color:#007bff;border-color:#007bff}.page-item.disabled .page-link{color:#6c757d;pointer-events:none;cursor:auto;background-color:#fff;border-color:#dee2e6}.pagination-lg .page-link{padding:.75rem 1.5rem;font-size:1.25rem;line-height:1.5}.pagination-lg .page-item:first-child .page-link{border-top-left-radius:.3rem;border-bottom-left-radius:.3rem}.pagination-lg .page-item:last-child .page-link{border-top-right-radius:.3rem;border-bottom-right-radius:.3rem}.pagination-sm .page-link{padding:.25rem .5rem;font-size:.875rem;line-height:1.5}.pagination-sm .page-item:first-child .page-link{border-top-left-radius:.2rem;border-bottom-left-radius:.2rem}.pagination-sm .page-item:last-child .page-link{border-top-right-radius:.2rem;border-bottom-right-radius:.2rem}.badge{display:inline-block;padding:.25em .4em;font-size:75%;font-weight:700;line-height:1;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25rem}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.badge-pill{padding-right:.6em;padding-left:.6em;border-radius:10rem}.badge-primary{color:#fff;background-color:#007bff}.badge-primary[href]:focus,.badge-primary[href]:hover{color:#fff;text-decoration:none;background-color:#0062cc}.badge-secondary{color:#fff;background-color:#6c757d}.badge-secondary[href]:focus,.badge-secondary[href]:hover{color:#fff;text-decoration:none;background-color:#545b62}.badge-success{color:#fff;background-color:#28a745}.badge-success[href]:focus,.badge-success[href]:hover{color:#fff;text-decoration:none;background-color:#1e7e34}.badge-info{color:#fff;background-color:#17a2b8}.badge-info[href]:focus,.badge-info[href]:hover{color:#fff;text-decoration:none;background-color:#117a8b}.badge-warning{color:#212529;background-color:#ffc107}.badge-warning[href]:focus,.badge-warning[href]:hover{color:#212529;text-decoration:none;background-color:#d39e00}.badge-danger{color:#fff;background-color:#dc3545}.badge-danger[href]:focus,.badge-danger[href]:hover{color:#fff;text-decoration:none;background-color:#bd2130}.badge-light{color:#212529;background-color:#f8f9fa}.badge-light[href]:focus,.badge-light[href]:hover{color:#212529;text-decoration:none;background-color:#dae0e5}.badge-dark{color:#fff;background-color:#343a40}.badge-dark[href]:focus,.badge-dark[href]:hover{color:#fff;text-decoration:none;background-color:#1d2124}.jumbotron{padding:2rem 1rem;margin-bottom:2rem;background-color:#e9ecef;border-radius:.3rem}@media (min-width:576px){.jumbotron{padding:4rem 2rem}}.jumbotron-fluid{padding-right:0;padding-left:0;border-radius:0}.alert{position:relative;padding:.75rem 1.25rem;margin-bottom:1rem;border:1px solid transparent;border-radius:.25rem}.alert-heading{color:inherit}.alert-link{font-weight:700}.alert-dismissible{padding-right:4rem}.alert-dismissible .close{position:absolute;top:0;right:0;padding:.75rem 1.25rem;color:inherit}.alert-primary{color:#004085;background-color:#cce5ff;border-color:#b8daff}.alert-primary hr{border-top-color:#9fcdff}.alert-primary .alert-link{color:#002752}.alert-secondary{color:#383d41;background-color:#e2e3e5;border-color:#d6d8db}.alert-secondary hr{border-top-color:#c8cbcf}.alert-secondary .alert-link{color:#202326}.alert-success{color:#155724;background-color:#d4edda;border-color:#c3e6cb}.alert-success hr{border-top-color:#b1dfbb}.alert-success .alert-link{color:#0b2e13}.alert-info{color:#0c5460;background-color:#d1ecf1;border-color:#bee5eb}.alert-info hr{border-top-color:#abdde5}.alert-info .alert-link{color:#062c33}.alert-warning{color:#856404;background-color:#fff3cd;border-color:#ffeeba}.alert-warning hr{border-top-color:#ffe8a1}.alert-warning .alert-link{color:#533f03}.alert-danger{color:#721c24;background-color:#f8d7da;border-color:#f5c6cb}.alert-danger hr{border-top-color:#f1b0b7}.alert-danger .alert-link{color:#491217}.alert-light{color:#818182;background-color:#fefefe;border-color:#fdfdfe}.alert-light hr{border-top-color:#ececf6}.alert-light .alert-link{color:#686868}.alert-dark{color:#1b1e21;background-color:#d6d8d9;border-color:#c6c8ca}.alert-dark hr{border-top-color:#b9bbbe}.alert-dark .alert-link{color:#040505}@-webkit-keyframes progress-bar-stripes{from{background-position:1rem 0}to{background-position:0 0}}@keyframes progress-bar-stripes{from{background-position:1rem 0}to{background-position:0 0}}.progress{display:-ms-flexbox;display:flex;height:1rem;overflow:hidden;font-size:.75rem;background-color:#e9ecef;border-radius:.25rem}.progress-bar{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;-ms-flex-pack:center;justify-content:center;color:#fff;text-align:center;white-space:nowrap;background-color:#007bff;transition:width .6s ease}@media screen and (prefers-reduced-motion:reduce){.progress-bar{transition:none}}.progress-bar-striped{background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-size:1rem 1rem}.progress-bar-animated{-webkit-animation:progress-bar-stripes 1s linear infinite;animation:progress-bar-stripes 1s linear infinite}.media{display:-ms-flexbox;display:flex;-ms-flex-align:start;align-items:flex-start}.media-body{-ms-flex:1;flex:1}.list-group{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;padding-left:0;margin-bottom:0}.list-group-item-action{width:100%;color:#495057;text-align:inherit}.list-group-item-action:focus,.list-group-item-action:hover{color:#495057;text-decoration:none;background-color:#f8f9fa}.list-group-item-action:active{color:#212529;background-color:#e9ecef}.list-group-item{position:relative;display:block;padding:.75rem 1.25rem;margin-bottom:-1px;background-color:#fff;border:1px solid rgba(0,0,0,.125)}.list-group-item:first-child{border-top-left-radius:.25rem;border-top-right-radius:.25rem}.list-group-item:last-child{margin-bottom:0;border-bottom-right-radius:.25rem;border-bottom-left-radius:.25rem}.list-group-item:focus,.list-group-item:hover{z-index:1;text-decoration:none}.list-group-item.disabled,.list-group-item:disabled{color:#6c757d;background-color:#fff}.list-group-item.active{z-index:2;color:#fff;background-color:#007bff;border-color:#007bff}.list-group-flush .list-group-item{border-right:0;border-left:0;border-radius:0}.list-group-flush:first-child .list-group-item:first-child{border-top:0}.list-group-flush:last-child .list-group-item:last-child{border-bottom:0}.list-group-item-primary{color:#004085;background-color:#b8daff}.list-group-item-primary.list-group-item-action:focus,.list-group-item-primary.list-group-item-action:hover{color:#004085;background-color:#9fcdff}.list-group-item-primary.list-group-item-action.active{color:#fff;background-color:#004085;border-color:#004085}.list-group-item-secondary{color:#383d41;background-color:#d6d8db}.list-group-item-secondary.list-group-item-action:focus,.list-group-item-secondary.list-group-item-action:hover{color:#383d41;background-color:#c8cbcf}.list-group-item-secondary.list-group-item-action.active{color:#fff;background-color:#383d41;border-color:#383d41}.list-group-item-success{color:#155724;background-color:#c3e6cb}.list-group-item-success.list-group-item-action:focus,.list-group-item-success.list-group-item-action:hover{color:#155724;background-color:#b1dfbb}.list-group-item-success.list-group-item-action.active{color:#fff;background-color:#155724;border-color:#155724}.list-group-item-info{color:#0c5460;background-color:#bee5eb}.list-group-item-info.list-group-item-action:focus,.list-group-item-info.list-group-item-action:hover{color:#0c5460;background-color:#abdde5}.list-group-item-info.list-group-item-action.active{color:#fff;background-color:#0c5460;border-color:#0c5460}.list-group-item-warning{color:#856404;background-color:#ffeeba}.list-group-item-warning.list-group-item-action:focus,.list-group-item-warning.list-group-item-action:hover{color:#856404;background-color:#ffe8a1}.list-group-item-warning.list-group-item-action.active{color:#fff;background-color:#856404;border-color:#856404}.list-group-item-danger{color:#721c24;background-color:#f5c6cb}.list-group-item-danger.list-group-item-action:focus,.list-group-item-danger.list-group-item-action:hover{color:#721c24;background-color:#f1b0b7}.list-group-item-danger.list-group-item-action.active{color:#fff;background-color:#721c24;border-color:#721c24}.list-group-item-light{color:#818182;background-color:#fdfdfe}.list-group-item-light.list-group-item-action:focus,.list-group-item-light.list-group-item-action:hover{color:#818182;background-color:#ececf6}.list-group-item-light.list-group-item-action.active{color:#fff;background-color:#818182;border-color:#818182}.list-group-item-dark{color:#1b1e21;background-color:#c6c8ca}.list-group-item-dark.list-group-item-action:focus,.list-group-item-dark.list-group-item-action:hover{color:#1b1e21;background-color:#b9bbbe}.list-group-item-dark.list-group-item-action.active{color:#fff;background-color:#1b1e21;border-color:#1b1e21}.close{float:right;font-size:1.5rem;font-weight:700;line-height:1;color:#000;text-shadow:0 1px 0 #fff;opacity:.5}.close:not(:disabled):not(.disabled){cursor:pointer}.close:not(:disabled):not(.disabled):focus,.close:not(:disabled):not(.disabled):hover{color:#000;text-decoration:none;opacity:.75}button.close{padding:0;background-color:transparent;border:0;-webkit-appearance:none}.modal-open{overflow:hidden}.modal-open .modal{overflow-x:hidden;overflow-y:auto}.modal{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1050;display:none;overflow:hidden;outline:0}.modal-dialog{position:relative;width:auto;margin:.5rem;pointer-events:none}.modal.fade .modal-dialog{transition:-webkit-transform .3s ease-out;transition:transform .3s ease-out;transition:transform .3s ease-out,-webkit-transform .3s ease-out;-webkit-transform:translate(0,-25%);transform:translate(0,-25%)}@media screen and (prefers-reduced-motion:reduce){.modal.fade .modal-dialog{transition:none}}.modal.show .modal-dialog{-webkit-transform:translate(0,0);transform:translate(0,0)}.modal-dialog-centered{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;min-height:calc(100% - (.5rem * 2))}.modal-dialog-centered::before{display:block;height:calc(100vh - (.5rem * 2));content:""}.modal-content{position:relative;display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;width:100%;pointer-events:auto;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.2);border-radius:.3rem;outline:0}.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;background-color:#000}.modal-backdrop.fade{opacity:0}.modal-backdrop.show{opacity:.5}.modal-header{display:-ms-flexbox;display:flex;-ms-flex-align:start;align-items:flex-start;-ms-flex-pack:justify;justify-content:space-between;padding:1rem;border-bottom:1px solid #e9ecef;border-top-left-radius:.3rem;border-top-right-radius:.3rem}.modal-header .close{padding:1rem;margin:-1rem -1rem -1rem auto}.modal-title{margin-bottom:0;line-height:1.5}.modal-body{position:relative;-ms-flex:1 1 auto;flex:1 1 auto;padding:1rem}.modal-footer{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:end;justify-content:flex-end;padding:1rem;border-top:1px solid #e9ecef}.modal-footer>:not(:first-child){margin-left:.25rem}.modal-footer>:not(:last-child){margin-right:.25rem}.modal-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}@media (min-width:576px){.modal-dialog{max-width:500px;margin:1.75rem auto}.modal-dialog-centered{min-height:calc(100% - (1.75rem * 2))}.modal-dialog-centered::before{height:calc(100vh - (1.75rem * 2))}.modal-sm{max-width:300px}}@media (min-width:992px){.modal-lg{max-width:800px}}.tooltip{position:absolute;z-index:1070;display:block;margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;white-space:normal;line-break:auto;font-size:.875rem;word-wrap:break-word;opacity:0}.tooltip.show{opacity:.9}.tooltip .arrow{position:absolute;display:block;width:.8rem;height:.4rem}.tooltip .arrow::before{position:absolute;content:"";border-color:transparent;border-style:solid}.bs-tooltip-auto[x-placement^=top],.bs-tooltip-top{padding:.4rem 0}.bs-tooltip-auto[x-placement^=top] .arrow,.bs-tooltip-top .arrow{bottom:0}.bs-tooltip-auto[x-placement^=top] .arrow::before,.bs-tooltip-top .arrow::before{top:0;border-width:.4rem .4rem 0;border-top-color:#000}.bs-tooltip-auto[x-placement^=right],.bs-tooltip-right{padding:0 .4rem}.bs-tooltip-auto[x-placement^=right] .arrow,.bs-tooltip-right .arrow{left:0;width:.4rem;height:.8rem}.bs-tooltip-auto[x-placement^=right] .arrow::before,.bs-tooltip-right .arrow::before{right:0;border-width:.4rem .4rem .4rem 0;border-right-color:#000}.bs-tooltip-auto[x-placement^=bottom],.bs-tooltip-bottom{padding:.4rem 0}.bs-tooltip-auto[x-placement^=bottom] .arrow,.bs-tooltip-bottom .arrow{top:0}.bs-tooltip-auto[x-placement^=bottom] .arrow::before,.bs-tooltip-bottom .arrow::before{bottom:0;border-width:0 .4rem .4rem;border-bottom-color:#000}.bs-tooltip-auto[x-placement^=left],.bs-tooltip-left{padding:0 .4rem}.bs-tooltip-auto[x-placement^=left] .arrow,.bs-tooltip-left .arrow{right:0;width:.4rem;height:.8rem}.bs-tooltip-auto[x-placement^=left] .arrow::before,.bs-tooltip-left .arrow::before{left:0;border-width:.4rem 0 .4rem .4rem;border-left-color:#000}.tooltip-inner{max-width:200px;padding:.25rem .5rem;color:#fff;text-align:center;background-color:#000;border-radius:.25rem}.popover{position:absolute;top:0;left:0;z-index:1060;display:block;max-width:276px;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;white-space:normal;line-break:auto;font-size:.875rem;word-wrap:break-word;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.2);border-radius:.3rem}.popover .arrow{position:absolute;display:block;width:1rem;height:.5rem;margin:0 .3rem}.popover .arrow::after,.popover .arrow::before{position:absolute;display:block;content:"";border-color:transparent;border-style:solid}.bs-popover-auto[x-placement^=top],.bs-popover-top{margin-bottom:.5rem}.bs-popover-auto[x-placement^=top] .arrow,.bs-popover-top .arrow{bottom:calc((.5rem + 1px) * -1)}.bs-popover-auto[x-placement^=top] .arrow::after,.bs-popover-auto[x-placement^=top] .arrow::before,.bs-popover-top .arrow::after,.bs-popover-top .arrow::before{border-width:.5rem .5rem 0}.bs-popover-auto[x-placement^=top] .arrow::before,.bs-popover-top .arrow::before{bottom:0;border-top-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=top] .arrow::after,.bs-popover-top .arrow::after{bottom:1px;border-top-color:#fff}.bs-popover-auto[x-placement^=right],.bs-popover-right{margin-left:.5rem}.bs-popover-auto[x-placement^=right] .arrow,.bs-popover-right .arrow{left:calc((.5rem + 1px) * -1);width:.5rem;height:1rem;margin:.3rem 0}.bs-popover-auto[x-placement^=right] .arrow::after,.bs-popover-auto[x-placement^=right] .arrow::before,.bs-popover-right .arrow::after,.bs-popover-right .arrow::before{border-width:.5rem .5rem .5rem 0}.bs-popover-auto[x-placement^=right] .arrow::before,.bs-popover-right .arrow::before{left:0;border-right-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=right] .arrow::after,.bs-popover-right .arrow::after{left:1px;border-right-color:#fff}.bs-popover-auto[x-placement^=bottom],.bs-popover-bottom{margin-top:.5rem}.bs-popover-auto[x-placement^=bottom] .arrow,.bs-popover-bottom .arrow{top:calc((.5rem + 1px) * -1)}.bs-popover-auto[x-placement^=bottom] .arrow::after,.bs-popover-auto[x-placement^=bottom] .arrow::before,.bs-popover-bottom .arrow::after,.bs-popover-bottom .arrow::before{border-width:0 .5rem .5rem .5rem}.bs-popover-auto[x-placement^=bottom] .arrow::before,.bs-popover-bottom .arrow::before{top:0;border-bottom-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=bottom] .arrow::after,.bs-popover-bottom .arrow::after{top:1px;border-bottom-color:#fff}.bs-popover-auto[x-placement^=bottom] .popover-header::before,.bs-popover-bottom .popover-header::before{position:absolute;top:0;left:50%;display:block;width:1rem;margin-left:-.5rem;content:"";border-bottom:1px solid #f7f7f7}.bs-popover-auto[x-placement^=left],.bs-popover-left{margin-right:.5rem}.bs-popover-auto[x-placement^=left] .arrow,.bs-popover-left .arrow{right:calc((.5rem + 1px) * -1);width:.5rem;height:1rem;margin:.3rem 0}.bs-popover-auto[x-placement^=left] .arrow::after,.bs-popover-auto[x-placement^=left] .arrow::before,.bs-popover-left .arrow::after,.bs-popover-left .arrow::before{border-width:.5rem 0 .5rem .5rem}.bs-popover-auto[x-placement^=left] .arrow::before,.bs-popover-left .arrow::before{right:0;border-left-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=left] .arrow::after,.bs-popover-left .arrow::after{right:1px;border-left-color:#fff}.popover-header{padding:.5rem .75rem;margin-bottom:0;font-size:1rem;color:inherit;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-top-left-radius:calc(.3rem - 1px);border-top-right-radius:calc(.3rem - 1px)}.popover-header:empty{display:none}.popover-body{padding:.5rem .75rem;color:#212529}.carousel{position:relative}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-item{position:relative;display:none;-ms-flex-align:center;align-items:center;width:100%;-webkit-backface-visibility:hidden;backface-visibility:hidden;-webkit-perspective:1000px;perspective:1000px}.carousel-item-next,.carousel-item-prev,.carousel-item.active{display:block;transition:-webkit-transform .6s ease;transition:transform .6s ease;transition:transform .6s ease,-webkit-transform .6s ease}@media screen and (prefers-reduced-motion:reduce){.carousel-item-next,.carousel-item-prev,.carousel-item.active{transition:none}}.carousel-item-next,.carousel-item-prev{position:absolute;top:0}.carousel-item-next.carousel-item-left,.carousel-item-prev.carousel-item-right{-webkit-transform:translateX(0);transform:translateX(0)}@supports ((-webkit-transform-style:preserve-3d) or (transform-style:preserve-3d)){.carousel-item-next.carousel-item-left,.carousel-item-prev.carousel-item-right{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}.active.carousel-item-right,.carousel-item-next{-webkit-transform:translateX(100%);transform:translateX(100%)}@supports ((-webkit-transform-style:preserve-3d) or (transform-style:preserve-3d)){.active.carousel-item-right,.carousel-item-next{-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}}.active.carousel-item-left,.carousel-item-prev{-webkit-transform:translateX(-100%);transform:translateX(-100%)}@supports ((-webkit-transform-style:preserve-3d) or (transform-style:preserve-3d)){.active.carousel-item-left,.carousel-item-prev{-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}}.carousel-fade .carousel-item{opacity:0;transition-duration:.6s;transition-property:opacity}.carousel-fade .carousel-item-next.carousel-item-left,.carousel-fade .carousel-item-prev.carousel-item-right,.carousel-fade .carousel-item.active{opacity:1}.carousel-fade .active.carousel-item-left,.carousel-fade .active.carousel-item-right{opacity:0}.carousel-fade .active.carousel-item-left,.carousel-fade .active.carousel-item-prev,.carousel-fade .carousel-item-next,.carousel-fade .carousel-item-prev,.carousel-fade .carousel-item.active{-webkit-transform:translateX(0);transform:translateX(0)}@supports ((-webkit-transform-style:preserve-3d) or (transform-style:preserve-3d)){.carousel-fade .active.carousel-item-left,.carousel-fade .active.carousel-item-prev,.carousel-fade .carousel-item-next,.carousel-fade .carousel-item-prev,.carousel-fade .carousel-item.active{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}.carousel-control-next,.carousel-control-prev{position:absolute;top:0;bottom:0;display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;width:15%;color:#fff;text-align:center;opacity:.5}.carousel-control-next:focus,.carousel-control-next:hover,.carousel-control-prev:focus,.carousel-control-prev:hover{color:#fff;text-decoration:none;outline:0;opacity:.9}.carousel-control-prev{left:0}.carousel-control-next{right:0}.carousel-control-next-icon,.carousel-control-prev-icon{display:inline-block;width:20px;height:20px;background:transparent no-repeat center center;background-size:100% 100%}.carousel-control-prev-icon{background-image:url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' viewBox='0 0 8 8'%3E%3Cpath d='M5.25 0l-4 4 4 4 1.5-1.5-2.5-2.5 2.5-2.5-1.5-1.5z'/%3E%3C/svg%3E")}.carousel-control-next-icon{background-image:url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' viewBox='0 0 8 8'%3E%3Cpath d='M2.75 0l-1.5 1.5 2.5 2.5-2.5 2.5 1.5 1.5 4-4-4-4z'/%3E%3C/svg%3E")}.carousel-indicators{position:absolute;right:0;bottom:10px;left:0;z-index:15;display:-ms-flexbox;display:flex;-ms-flex-pack:center;justify-content:center;padding-left:0;margin-right:15%;margin-left:15%;list-style:none}.carousel-indicators li{position:relative;-ms-flex:0 1 auto;flex:0 1 auto;width:30px;height:3px;margin-right:3px;margin-left:3px;text-indent:-999px;cursor:pointer;background-color:rgba(255,255,255,.5)}.carousel-indicators li::before{position:absolute;top:-10px;left:0;display:inline-block;width:100%;height:10px;content:""}.carousel-indicators li::after{position:absolute;bottom:-10px;left:0;display:inline-block;width:100%;height:10px;content:""}.carousel-indicators .active{background-color:#fff}.carousel-caption{position:absolute;right:15%;bottom:20px;left:15%;z-index:10;padding-top:20px;padding-bottom:20px;color:#fff;text-align:center}.align-baseline{vertical-align:baseline!important}.align-top{vertical-align:top!important}.align-middle{vertical-align:middle!important}.align-bottom{vertical-align:bottom!important}.align-text-bottom{vertical-align:text-bottom!important}.align-text-top{vertical-align:text-top!important}.bg-primary{background-color:#007bff!important}a.bg-primary:focus,a.bg-primary:hover,button.bg-primary:focus,button.bg-primary:hover{background-color:#0062cc!important}.bg-secondary{background-color:#6c757d!important}a.bg-secondary:focus,a.bg-secondary:hover,button.bg-secondary:focus,button.bg-secondary:hover{background-color:#545b62!important}.bg-success{background-color:#28a745!important}a.bg-success:focus,a.bg-success:hover,button.bg-success:focus,button.bg-success:hover{background-color:#1e7e34!important}.bg-info{background-color:#17a2b8!important}a.bg-info:focus,a.bg-info:hover,button.bg-info:focus,button.bg-info:hover{background-color:#117a8b!important}.bg-warning{background-color:#ffc107!important}a.bg-warning:focus,a.bg-warning:hover,button.bg-warning:focus,button.bg-warning:hover{background-color:#d39e00!important}.bg-danger{background-color:#dc3545!important}a.bg-danger:focus,a.bg-danger:hover,button.bg-danger:focus,button.bg-danger:hover{background-color:#bd2130!important}.bg-light{background-color:#f8f9fa!important}a.bg-light:focus,a.bg-light:hover,button.bg-light:focus,button.bg-light:hover{background-color:#dae0e5!important}.bg-dark{background-color:#343a40!important}a.bg-dark:focus,a.bg-dark:hover,button.bg-dark:focus,button.bg-dark:hover{background-color:#1d2124!important}.bg-white{background-color:#fff!important}.bg-transparent{background-color:transparent!important}.border{border:1px solid #dee2e6!important}.border-top{border-top:1px solid #dee2e6!important}.border-right{border-right:1px solid #dee2e6!important}.border-bottom{border-bottom:1px solid #dee2e6!important}.border-left{border-left:1px solid #dee2e6!important}.border-0{border:0!important}.border-top-0{border-top:0!important}.border-right-0{border-right:0!important}.border-bottom-0{border-bottom:0!important}.border-left-0{border-left:0!important}.border-primary{border-color:#007bff!important}.border-secondary{border-color:#6c757d!important}.border-success{border-color:#28a745!important}.border-info{border-color:#17a2b8!important}.border-warning{border-color:#ffc107!important}.border-danger{border-color:#dc3545!important}.border-light{border-color:#f8f9fa!important}.border-dark{border-color:#343a40!important}.border-white{border-color:#fff!important}.rounded{border-radius:.25rem!important}.rounded-top{border-top-left-radius:.25rem!important;border-top-right-radius:.25rem!important}.rounded-right{border-top-right-radius:.25rem!important;border-bottom-right-radius:.25rem!important}.rounded-bottom{border-bottom-right-radius:.25rem!important;border-bottom-left-radius:.25rem!important}.rounded-left{border-top-left-radius:.25rem!important;border-bottom-left-radius:.25rem!important}.rounded-circle{border-radius:50%!important}.rounded-0{border-radius:0!important}.clearfix::after{display:block;clear:both;content:""}.d-none{display:none!important}.d-inline{display:inline!important}.d-inline-block{display:inline-block!important}.d-block{display:block!important}.d-table{display:table!important}.d-table-row{display:table-row!important}.d-table-cell{display:table-cell!important}.d-flex{display:-ms-flexbox!important;display:flex!important}.d-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}@media (min-width:576px){.d-sm-none{display:none!important}.d-sm-inline{display:inline!important}.d-sm-inline-block{display:inline-block!important}.d-sm-block{display:block!important}.d-sm-table{display:table!important}.d-sm-table-row{display:table-row!important}.d-sm-table-cell{display:table-cell!important}.d-sm-flex{display:-ms-flexbox!important;display:flex!important}.d-sm-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}@media (min-width:768px){.d-md-none{display:none!important}.d-md-inline{display:inline!important}.d-md-inline-block{display:inline-block!important}.d-md-block{display:block!important}.d-md-table{display:table!important}.d-md-table-row{display:table-row!important}.d-md-table-cell{display:table-cell!important}.d-md-flex{display:-ms-flexbox!important;display:flex!important}.d-md-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}@media (min-width:992px){.d-lg-none{display:none!important}.d-lg-inline{display:inline!important}.d-lg-inline-block{display:inline-block!important}.d-lg-block{display:block!important}.d-lg-table{display:table!important}.d-lg-table-row{display:table-row!important}.d-lg-table-cell{display:table-cell!important}.d-lg-flex{display:-ms-flexbox!important;display:flex!important}.d-lg-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}@media (min-width:1200px){.d-xl-none{display:none!important}.d-xl-inline{display:inline!important}.d-xl-inline-block{display:inline-block!important}.d-xl-block{display:block!important}.d-xl-table{display:table!important}.d-xl-table-row{display:table-row!important}.d-xl-table-cell{display:table-cell!important}.d-xl-flex{display:-ms-flexbox!important;display:flex!important}.d-xl-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}@media print{.d-print-none{display:none!important}.d-print-inline{display:inline!important}.d-print-inline-block{display:inline-block!important}.d-print-block{display:block!important}.d-print-table{display:table!important}.d-print-table-row{display:table-row!important}.d-print-table-cell{display:table-cell!important}.d-print-flex{display:-ms-flexbox!important;display:flex!important}.d-print-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}.embed-responsive{position:relative;display:block;width:100%;padding:0;overflow:hidden}.embed-responsive::before{display:block;content:""}.embed-responsive .embed-responsive-item,.embed-responsive embed,.embed-responsive iframe,.embed-responsive object,.embed-responsive video{position:absolute;top:0;bottom:0;left:0;width:100%;height:100%;border:0}.embed-responsive-21by9::before{padding-top:42.857143%}.embed-responsive-16by9::before{padding-top:56.25%}.embed-responsive-4by3::before{padding-top:75%}.embed-responsive-1by1::before{padding-top:100%}.flex-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-center{-ms-flex-align:center!important;align-items:center!important}.align-items-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}@media (min-width:576px){.flex-sm-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-sm-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-sm-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-sm-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-sm-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-sm-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-sm-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-sm-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-sm-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-sm-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-sm-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-sm-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-sm-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-sm-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-sm-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-sm-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-sm-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-sm-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-sm-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-sm-center{-ms-flex-align:center!important;align-items:center!important}.align-items-sm-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-sm-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-sm-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-sm-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-sm-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-sm-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-sm-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-sm-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-sm-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-sm-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-sm-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-sm-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-sm-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-sm-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}}@media (min-width:768px){.flex-md-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-md-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-md-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-md-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-md-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-md-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-md-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-md-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-md-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-md-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-md-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-md-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-md-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-md-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-md-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-md-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-md-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-md-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-md-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-md-center{-ms-flex-align:center!important;align-items:center!important}.align-items-md-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-md-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-md-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-md-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-md-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-md-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-md-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-md-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-md-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-md-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-md-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-md-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-md-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-md-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}}@media (min-width:992px){.flex-lg-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-lg-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-lg-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-lg-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-lg-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-lg-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-lg-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-lg-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-lg-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-lg-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-lg-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-lg-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-lg-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-lg-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-lg-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-lg-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-lg-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-lg-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-lg-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-lg-center{-ms-flex-align:center!important;align-items:center!important}.align-items-lg-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-lg-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-lg-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-lg-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-lg-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-lg-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-lg-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-lg-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-lg-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-lg-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-lg-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-lg-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-lg-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-lg-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}}@media (min-width:1200px){.flex-xl-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-xl-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-xl-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-xl-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-xl-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-xl-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-xl-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-xl-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-xl-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-xl-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-xl-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-xl-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-xl-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-xl-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-xl-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-xl-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-xl-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-xl-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-xl-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-xl-center{-ms-flex-align:center!important;align-items:center!important}.align-items-xl-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-xl-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-xl-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-xl-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-xl-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-xl-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-xl-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-xl-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-xl-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-xl-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-xl-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-xl-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-xl-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-xl-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}}.float-left{float:left!important}.float-right{float:right!important}.float-none{float:none!important}@media (min-width:576px){.float-sm-left{float:left!important}.float-sm-right{float:right!important}.float-sm-none{float:none!important}}@media (min-width:768px){.float-md-left{float:left!important}.float-md-right{float:right!important}.float-md-none{float:none!important}}@media (min-width:992px){.float-lg-left{float:left!important}.float-lg-right{float:right!important}.float-lg-none{float:none!important}}@media (min-width:1200px){.float-xl-left{float:left!important}.float-xl-right{float:right!important}.float-xl-none{float:none!important}}.position-static{position:static!important}.position-relative{position:relative!important}.position-absolute{position:absolute!important}.position-fixed{position:fixed!important}.position-sticky{position:-webkit-sticky!important;position:sticky!important}.fixed-top{position:fixed;top:0;right:0;left:0;z-index:1030}.fixed-bottom{position:fixed;right:0;bottom:0;left:0;z-index:1030}@supports ((position:-webkit-sticky) or (position:sticky)){.sticky-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}}.sr-only{position:absolute;width:1px;height:1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;overflow:visible;clip:auto;white-space:normal}.shadow-sm{box-shadow:0 .125rem .25rem rgba(0,0,0,.075)!important}.shadow{box-shadow:0 .5rem 1rem rgba(0,0,0,.15)!important}.shadow-lg{box-shadow:0 1rem 3rem rgba(0,0,0,.175)!important}.shadow-none{box-shadow:none!important}.w-25{width:25%!important}.w-50{width:50%!important}.w-75{width:75%!important}.w-100{width:100%!important}.w-auto{width:auto!important}.h-25{height:25%!important}.h-50{height:50%!important}.h-75{height:75%!important}.h-100{height:100%!important}.h-auto{height:auto!important}.mw-100{max-width:100%!important}.mh-100{max-height:100%!important}.m-0{margin:0!important}.mt-0,.my-0{margin-top:0!important}.mr-0,.mx-0{margin-right:0!important}.mb-0,.my-0{margin-bottom:0!important}.ml-0,.mx-0{margin-left:0!important}.m-1{margin:.25rem!important}.mt-1,.my-1{margin-top:.25rem!important}.mr-1,.mx-1{margin-right:.25rem!important}.mb-1,.my-1{margin-bottom:.25rem!important}.ml-1,.mx-1{margin-left:.25rem!important}.m-2{margin:.5rem!important}.mt-2,.my-2{margin-top:.5rem!important}.mr-2,.mx-2{margin-right:.5rem!important}.mb-2,.my-2{margin-bottom:.5rem!important}.ml-2,.mx-2{margin-left:.5rem!important}.m-3{margin:1rem!important}.mt-3,.my-3{margin-top:1rem!important}.mr-3,.mx-3{margin-right:1rem!important}.mb-3,.my-3{margin-bottom:1rem!important}.ml-3,.mx-3{margin-left:1rem!important}.m-4{margin:1.5rem!important}.mt-4,.my-4{margin-top:1.5rem!important}.mr-4,.mx-4{margin-right:1.5rem!important}.mb-4,.my-4{margin-bottom:1.5rem!important}.ml-4,.mx-4{margin-left:1.5rem!important}.m-5{margin:3rem!important}.mt-5,.my-5{margin-top:3rem!important}.mr-5,.mx-5{margin-right:3rem!important}.mb-5,.my-5{margin-bottom:3rem!important}.ml-5,.mx-5{margin-left:3rem!important}.p-0{padding:0!important}.pt-0,.py-0{padding-top:0!important}.pr-0,.px-0{padding-right:0!important}.pb-0,.py-0{padding-bottom:0!important}.pl-0,.px-0{padding-left:0!important}.p-1{padding:.25rem!important}.pt-1,.py-1{padding-top:.25rem!important}.pr-1,.px-1{padding-right:.25rem!important}.pb-1,.py-1{padding-bottom:.25rem!important}.pl-1,.px-1{padding-left:.25rem!important}.p-2{padding:.5rem!important}.pt-2,.py-2{padding-top:.5rem!important}.pr-2,.px-2{padding-right:.5rem!important}.pb-2,.py-2{padding-bottom:.5rem!important}.pl-2,.px-2{padding-left:.5rem!important}.p-3{padding:1rem!important}.pt-3,.py-3{padding-top:1rem!important}.pr-3,.px-3{padding-right:1rem!important}.pb-3,.py-3{padding-bottom:1rem!important}.pl-3,.px-3{padding-left:1rem!important}.p-4{padding:1.5rem!important}.pt-4,.py-4{padding-top:1.5rem!important}.pr-4,.px-4{padding-right:1.5rem!important}.pb-4,.py-4{padding-bottom:1.5rem!important}.pl-4,.px-4{padding-left:1.5rem!important}.p-5{padding:3rem!important}.pt-5,.py-5{padding-top:3rem!important}.pr-5,.px-5{padding-right:3rem!important}.pb-5,.py-5{padding-bottom:3rem!important}.pl-5,.px-5{padding-left:3rem!important}.m-auto{margin:auto!important}.mt-auto,.my-auto{margin-top:auto!important}.mr-auto,.mx-auto{margin-right:auto!important}.mb-auto,.my-auto{margin-bottom:auto!important}.ml-auto,.mx-auto{margin-left:auto!important}@media (min-width:576px){.m-sm-0{margin:0!important}.mt-sm-0,.my-sm-0{margin-top:0!important}.mr-sm-0,.mx-sm-0{margin-right:0!important}.mb-sm-0,.my-sm-0{margin-bottom:0!important}.ml-sm-0,.mx-sm-0{margin-left:0!important}.m-sm-1{margin:.25rem!important}.mt-sm-1,.my-sm-1{margin-top:.25rem!important}.mr-sm-1,.mx-sm-1{margin-right:.25rem!important}.mb-sm-1,.my-sm-1{margin-bottom:.25rem!important}.ml-sm-1,.mx-sm-1{margin-left:.25rem!important}.m-sm-2{margin:.5rem!important}.mt-sm-2,.my-sm-2{margin-top:.5rem!important}.mr-sm-2,.mx-sm-2{margin-right:.5rem!important}.mb-sm-2,.my-sm-2{margin-bottom:.5rem!important}.ml-sm-2,.mx-sm-2{margin-left:.5rem!important}.m-sm-3{margin:1rem!important}.mt-sm-3,.my-sm-3{margin-top:1rem!important}.mr-sm-3,.mx-sm-3{margin-right:1rem!important}.mb-sm-3,.my-sm-3{margin-bottom:1rem!important}.ml-sm-3,.mx-sm-3{margin-left:1rem!important}.m-sm-4{margin:1.5rem!important}.mt-sm-4,.my-sm-4{margin-top:1.5rem!important}.mr-sm-4,.mx-sm-4{margin-right:1.5rem!important}.mb-sm-4,.my-sm-4{margin-bottom:1.5rem!important}.ml-sm-4,.mx-sm-4{margin-left:1.5rem!important}.m-sm-5{margin:3rem!important}.mt-sm-5,.my-sm-5{margin-top:3rem!important}.mr-sm-5,.mx-sm-5{margin-right:3rem!important}.mb-sm-5,.my-sm-5{margin-bottom:3rem!important}.ml-sm-5,.mx-sm-5{margin-left:3rem!important}.p-sm-0{padding:0!important}.pt-sm-0,.py-sm-0{padding-top:0!important}.pr-sm-0,.px-sm-0{padding-right:0!important}.pb-sm-0,.py-sm-0{padding-bottom:0!important}.pl-sm-0,.px-sm-0{padding-left:0!important}.p-sm-1{padding:.25rem!important}.pt-sm-1,.py-sm-1{padding-top:.25rem!important}.pr-sm-1,.px-sm-1{padding-right:.25rem!important}.pb-sm-1,.py-sm-1{padding-bottom:.25rem!important}.pl-sm-1,.px-sm-1{padding-left:.25rem!important}.p-sm-2{padding:.5rem!important}.pt-sm-2,.py-sm-2{padding-top:.5rem!important}.pr-sm-2,.px-sm-2{padding-right:.5rem!important}.pb-sm-2,.py-sm-2{padding-bottom:.5rem!important}.pl-sm-2,.px-sm-2{padding-left:.5rem!important}.p-sm-3{padding:1rem!important}.pt-sm-3,.py-sm-3{padding-top:1rem!important}.pr-sm-3,.px-sm-3{padding-right:1rem!important}.pb-sm-3,.py-sm-3{padding-bottom:1rem!important}.pl-sm-3,.px-sm-3{padding-left:1rem!important}.p-sm-4{padding:1.5rem!important}.pt-sm-4,.py-sm-4{padding-top:1.5rem!important}.pr-sm-4,.px-sm-4{padding-right:1.5rem!important}.pb-sm-4,.py-sm-4{padding-bottom:1.5rem!important}.pl-sm-4,.px-sm-4{padding-left:1.5rem!important}.p-sm-5{padding:3rem!important}.pt-sm-5,.py-sm-5{padding-top:3rem!important}.pr-sm-5,.px-sm-5{padding-right:3rem!important}.pb-sm-5,.py-sm-5{padding-bottom:3rem!important}.pl-sm-5,.px-sm-5{padding-left:3rem!important}.m-sm-auto{margin:auto!important}.mt-sm-auto,.my-sm-auto{margin-top:auto!important}.mr-sm-auto,.mx-sm-auto{margin-right:auto!important}.mb-sm-auto,.my-sm-auto{margin-bottom:auto!important}.ml-sm-auto,.mx-sm-auto{margin-left:auto!important}}@media (min-width:768px){.m-md-0{margin:0!important}.mt-md-0,.my-md-0{margin-top:0!important}.mr-md-0,.mx-md-0{margin-right:0!important}.mb-md-0,.my-md-0{margin-bottom:0!important}.ml-md-0,.mx-md-0{margin-left:0!important}.m-md-1{margin:.25rem!important}.mt-md-1,.my-md-1{margin-top:.25rem!important}.mr-md-1,.mx-md-1{margin-right:.25rem!important}.mb-md-1,.my-md-1{margin-bottom:.25rem!important}.ml-md-1,.mx-md-1{margin-left:.25rem!important}.m-md-2{margin:.5rem!important}.mt-md-2,.my-md-2{margin-top:.5rem!important}.mr-md-2,.mx-md-2{margin-right:.5rem!important}.mb-md-2,.my-md-2{margin-bottom:.5rem!important}.ml-md-2,.mx-md-2{margin-left:.5rem!important}.m-md-3{margin:1rem!important}.mt-md-3,.my-md-3{margin-top:1rem!important}.mr-md-3,.mx-md-3{margin-right:1rem!important}.mb-md-3,.my-md-3{margin-bottom:1rem!important}.ml-md-3,.mx-md-3{margin-left:1rem!important}.m-md-4{margin:1.5rem!important}.mt-md-4,.my-md-4{margin-top:1.5rem!important}.mr-md-4,.mx-md-4{margin-right:1.5rem!important}.mb-md-4,.my-md-4{margin-bottom:1.5rem!important}.ml-md-4,.mx-md-4{margin-left:1.5rem!important}.m-md-5{margin:3rem!important}.mt-md-5,.my-md-5{margin-top:3rem!important}.mr-md-5,.mx-md-5{margin-right:3rem!important}.mb-md-5,.my-md-5{margin-bottom:3rem!important}.ml-md-5,.mx-md-5{margin-left:3rem!important}.p-md-0{padding:0!important}.pt-md-0,.py-md-0{padding-top:0!important}.pr-md-0,.px-md-0{padding-right:0!important}.pb-md-0,.py-md-0{padding-bottom:0!important}.pl-md-0,.px-md-0{padding-left:0!important}.p-md-1{padding:.25rem!important}.pt-md-1,.py-md-1{padding-top:.25rem!important}.pr-md-1,.px-md-1{padding-right:.25rem!important}.pb-md-1,.py-md-1{padding-bottom:.25rem!important}.pl-md-1,.px-md-1{padding-left:.25rem!important}.p-md-2{padding:.5rem!important}.pt-md-2,.py-md-2{padding-top:.5rem!important}.pr-md-2,.px-md-2{padding-right:.5rem!important}.pb-md-2,.py-md-2{padding-bottom:.5rem!important}.pl-md-2,.px-md-2{padding-left:.5rem!important}.p-md-3{padding:1rem!important}.pt-md-3,.py-md-3{padding-top:1rem!important}.pr-md-3,.px-md-3{padding-right:1rem!important}.pb-md-3,.py-md-3{padding-bottom:1rem!important}.pl-md-3,.px-md-3{padding-left:1rem!important}.p-md-4{padding:1.5rem!important}.pt-md-4,.py-md-4{padding-top:1.5rem!important}.pr-md-4,.px-md-4{padding-right:1.5rem!important}.pb-md-4,.py-md-4{padding-bottom:1.5rem!important}.pl-md-4,.px-md-4{padding-left:1.5rem!important}.p-md-5{padding:3rem!important}.pt-md-5,.py-md-5{padding-top:3rem!important}.pr-md-5,.px-md-5{padding-right:3rem!important}.pb-md-5,.py-md-5{padding-bottom:3rem!important}.pl-md-5,.px-md-5{padding-left:3rem!important}.m-md-auto{margin:auto!important}.mt-md-auto,.my-md-auto{margin-top:auto!important}.mr-md-auto,.mx-md-auto{margin-right:auto!important}.mb-md-auto,.my-md-auto{margin-bottom:auto!important}.ml-md-auto,.mx-md-auto{margin-left:auto!important}}@media (min-width:992px){.m-lg-0{margin:0!important}.mt-lg-0,.my-lg-0{margin-top:0!important}.mr-lg-0,.mx-lg-0{margin-right:0!important}.mb-lg-0,.my-lg-0{margin-bottom:0!important}.ml-lg-0,.mx-lg-0{margin-left:0!important}.m-lg-1{margin:.25rem!important}.mt-lg-1,.my-lg-1{margin-top:.25rem!important}.mr-lg-1,.mx-lg-1{margin-right:.25rem!important}.mb-lg-1,.my-lg-1{margin-bottom:.25rem!important}.ml-lg-1,.mx-lg-1{margin-left:.25rem!important}.m-lg-2{margin:.5rem!important}.mt-lg-2,.my-lg-2{margin-top:.5rem!important}.mr-lg-2,.mx-lg-2{margin-right:.5rem!important}.mb-lg-2,.my-lg-2{margin-bottom:.5rem!important}.ml-lg-2,.mx-lg-2{margin-left:.5rem!important}.m-lg-3{margin:1rem!important}.mt-lg-3,.my-lg-3{margin-top:1rem!important}.mr-lg-3,.mx-lg-3{margin-right:1rem!important}.mb-lg-3,.my-lg-3{margin-bottom:1rem!important}.ml-lg-3,.mx-lg-3{margin-left:1rem!important}.m-lg-4{margin:1.5rem!important}.mt-lg-4,.my-lg-4{margin-top:1.5rem!important}.mr-lg-4,.mx-lg-4{margin-right:1.5rem!important}.mb-lg-4,.my-lg-4{margin-bottom:1.5rem!important}.ml-lg-4,.mx-lg-4{margin-left:1.5rem!important}.m-lg-5{margin:3rem!important}.mt-lg-5,.my-lg-5{margin-top:3rem!important}.mr-lg-5,.mx-lg-5{margin-right:3rem!important}.mb-lg-5,.my-lg-5{margin-bottom:3rem!important}.ml-lg-5,.mx-lg-5{margin-left:3rem!important}.p-lg-0{padding:0!important}.pt-lg-0,.py-lg-0{padding-top:0!important}.pr-lg-0,.px-lg-0{padding-right:0!important}.pb-lg-0,.py-lg-0{padding-bottom:0!important}.pl-lg-0,.px-lg-0{padding-left:0!important}.p-lg-1{padding:.25rem!important}.pt-lg-1,.py-lg-1{padding-top:.25rem!important}.pr-lg-1,.px-lg-1{padding-right:.25rem!important}.pb-lg-1,.py-lg-1{padding-bottom:.25rem!important}.pl-lg-1,.px-lg-1{padding-left:.25rem!important}.p-lg-2{padding:.5rem!important}.pt-lg-2,.py-lg-2{padding-top:.5rem!important}.pr-lg-2,.px-lg-2{padding-right:.5rem!important}.pb-lg-2,.py-lg-2{padding-bottom:.5rem!important}.pl-lg-2,.px-lg-2{padding-left:.5rem!important}.p-lg-3{padding:1rem!important}.pt-lg-3,.py-lg-3{padding-top:1rem!important}.pr-lg-3,.px-lg-3{padding-right:1rem!important}.pb-lg-3,.py-lg-3{padding-bottom:1rem!important}.pl-lg-3,.px-lg-3{padding-left:1rem!important}.p-lg-4{padding:1.5rem!important}.pt-lg-4,.py-lg-4{padding-top:1.5rem!important}.pr-lg-4,.px-lg-4{padding-right:1.5rem!important}.pb-lg-4,.py-lg-4{padding-bottom:1.5rem!important}.pl-lg-4,.px-lg-4{padding-left:1.5rem!important}.p-lg-5{padding:3rem!important}.pt-lg-5,.py-lg-5{padding-top:3rem!important}.pr-lg-5,.px-lg-5{padding-right:3rem!important}.pb-lg-5,.py-lg-5{padding-bottom:3rem!important}.pl-lg-5,.px-lg-5{padding-left:3rem!important}.m-lg-auto{margin:auto!important}.mt-lg-auto,.my-lg-auto{margin-top:auto!important}.mr-lg-auto,.mx-lg-auto{margin-right:auto!important}.mb-lg-auto,.my-lg-auto{margin-bottom:auto!important}.ml-lg-auto,.mx-lg-auto{margin-left:auto!important}}@media (min-width:1200px){.m-xl-0{margin:0!important}.mt-xl-0,.my-xl-0{margin-top:0!important}.mr-xl-0,.mx-xl-0{margin-right:0!important}.mb-xl-0,.my-xl-0{margin-bottom:0!important}.ml-xl-0,.mx-xl-0{margin-left:0!important}.m-xl-1{margin:.25rem!important}.mt-xl-1,.my-xl-1{margin-top:.25rem!important}.mr-xl-1,.mx-xl-1{margin-right:.25rem!important}.mb-xl-1,.my-xl-1{margin-bottom:.25rem!important}.ml-xl-1,.mx-xl-1{margin-left:.25rem!important}.m-xl-2{margin:.5rem!important}.mt-xl-2,.my-xl-2{margin-top:.5rem!important}.mr-xl-2,.mx-xl-2{margin-right:.5rem!important}.mb-xl-2,.my-xl-2{margin-bottom:.5rem!important}.ml-xl-2,.mx-xl-2{margin-left:.5rem!important}.m-xl-3{margin:1rem!important}.mt-xl-3,.my-xl-3{margin-top:1rem!important}.mr-xl-3,.mx-xl-3{margin-right:1rem!important}.mb-xl-3,.my-xl-3{margin-bottom:1rem!important}.ml-xl-3,.mx-xl-3{margin-left:1rem!important}.m-xl-4{margin:1.5rem!important}.mt-xl-4,.my-xl-4{margin-top:1.5rem!important}.mr-xl-4,.mx-xl-4{margin-right:1.5rem!important}.mb-xl-4,.my-xl-4{margin-bottom:1.5rem!important}.ml-xl-4,.mx-xl-4{margin-left:1.5rem!important}.m-xl-5{margin:3rem!important}.mt-xl-5,.my-xl-5{margin-top:3rem!important}.mr-xl-5,.mx-xl-5{margin-right:3rem!important}.mb-xl-5,.my-xl-5{margin-bottom:3rem!important}.ml-xl-5,.mx-xl-5{margin-left:3rem!important}.p-xl-0{padding:0!important}.pt-xl-0,.py-xl-0{padding-top:0!important}.pr-xl-0,.px-xl-0{padding-right:0!important}.pb-xl-0,.py-xl-0{padding-bottom:0!important}.pl-xl-0,.px-xl-0{padding-left:0!important}.p-xl-1{padding:.25rem!important}.pt-xl-1,.py-xl-1{padding-top:.25rem!important}.pr-xl-1,.px-xl-1{padding-right:.25rem!important}.pb-xl-1,.py-xl-1{padding-bottom:.25rem!important}.pl-xl-1,.px-xl-1{padding-left:.25rem!important}.p-xl-2{padding:.5rem!important}.pt-xl-2,.py-xl-2{padding-top:.5rem!important}.pr-xl-2,.px-xl-2{padding-right:.5rem!important}.pb-xl-2,.py-xl-2{padding-bottom:.5rem!important}.pl-xl-2,.px-xl-2{padding-left:.5rem!important}.p-xl-3{padding:1rem!important}.pt-xl-3,.py-xl-3{padding-top:1rem!important}.pr-xl-3,.px-xl-3{padding-right:1rem!important}.pb-xl-3,.py-xl-3{padding-bottom:1rem!important}.pl-xl-3,.px-xl-3{padding-left:1rem!important}.p-xl-4{padding:1.5rem!important}.pt-xl-4,.py-xl-4{padding-top:1.5rem!important}.pr-xl-4,.px-xl-4{padding-right:1.5rem!important}.pb-xl-4,.py-xl-4{padding-bottom:1.5rem!important}.pl-xl-4,.px-xl-4{padding-left:1.5rem!important}.p-xl-5{padding:3rem!important}.pt-xl-5,.py-xl-5{padding-top:3rem!important}.pr-xl-5,.px-xl-5{padding-right:3rem!important}.pb-xl-5,.py-xl-5{padding-bottom:3rem!important}.pl-xl-5,.px-xl-5{padding-left:3rem!important}.m-xl-auto{margin:auto!important}.mt-xl-auto,.my-xl-auto{margin-top:auto!important}.mr-xl-auto,.mx-xl-auto{margin-right:auto!important}.mb-xl-auto,.my-xl-auto{margin-bottom:auto!important}.ml-xl-auto,.mx-xl-auto{margin-left:auto!important}}.text-monospace{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace}.text-justify{text-align:justify!important}.text-nowrap{white-space:nowrap!important}.text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.text-left{text-align:left!important}.text-right{text-align:right!important}.text-center{text-align:center!important}@media (min-width:576px){.text-sm-left{text-align:left!important}.text-sm-right{text-align:right!important}.text-sm-center{text-align:center!important}}@media (min-width:768px){.text-md-left{text-align:left!important}.text-md-right{text-align:right!important}.text-md-center{text-align:center!important}}@media (min-width:992px){.text-lg-left{text-align:left!important}.text-lg-right{text-align:right!important}.text-lg-center{text-align:center!important}}@media (min-width:1200px){.text-xl-left{text-align:left!important}.text-xl-right{text-align:right!important}.text-xl-center{text-align:center!important}}.text-lowercase{text-transform:lowercase!important}.text-uppercase{text-transform:uppercase!important}.text-capitalize{text-transform:capitalize!important}.font-weight-light{font-weight:300!important}.font-weight-normal{font-weight:400!important}.font-weight-bold{font-weight:700!important}.font-italic{font-style:italic!important}.text-white{color:#fff!important}.text-primary{color:#007bff!important}a.text-primary:focus,a.text-primary:hover{color:#0062cc!important}.text-secondary{color:#6c757d!important}a.text-secondary:focus,a.text-secondary:hover{color:#545b62!important}.text-success{color:#28a745!important}a.text-success:focus,a.text-success:hover{color:#1e7e34!important}.text-info{color:#17a2b8!important}a.text-info:focus,a.text-info:hover{color:#117a8b!important}.text-warning{color:#ffc107!important}a.text-warning:focus,a.text-warning:hover{color:#d39e00!important}.text-danger{color:#dc3545!important}a.text-danger:focus,a.text-danger:hover{color:#bd2130!important}.text-light{color:#f8f9fa!important}a.text-light:focus,a.text-light:hover{color:#dae0e5!important}.text-dark{color:#343a40!important}a.text-dark:focus,a.text-dark:hover{color:#1d2124!important}.text-body{color:#212529!important}.text-muted{color:#6c757d!important}.text-black-50{color:rgba(0,0,0,.5)!important}.text-white-50{color:rgba(255,255,255,.5)!important}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.visible{visibility:visible!important}.invisible{visibility:hidden!important}@media print{*,::after,::before{text-shadow:none!important;box-shadow:none!important}a:not(.btn){text-decoration:underline}abbr[title]::after{content:" (" attr(title) ")"}pre{white-space:pre-wrap!important}blockquote,pre{border:1px solid #adb5bd;page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}h2,h3,p{orphans:3;widows:3}h2,h3{page-break-after:avoid}@page{size:a3}body{min-width:992px!important}.container{min-width:992px!important}.navbar{display:none}.badge{border:1px solid #000}.table{border-collapse:collapse!important}.table td,.table th{background-color:#fff!important}.table-bordered td,.table-bordered th{border:1px solid #dee2e6!important}.table-dark{color:inherit}.table-dark tbody+tbody,.table-dark td,.table-dark th,.table-dark thead th{border-color:#dee2e6}.table .thead-dark th{color:inherit;border-color:#dee2e6}} -/*# sourceMappingURL=bootstrap.min.css.map */ \ No newline at end of file diff --git a/2.0/documentation/tdenginedocs-cn/lib/docs/docs.css b/2.0/documentation/tdenginedocs-cn/lib/docs/docs.css deleted file mode 100644 index bfb6f808e6..0000000000 --- a/2.0/documentation/tdenginedocs-cn/lib/docs/docs.css +++ /dev/null @@ -1,269 +0,0 @@ -.documentation strong { - font-weight:600; -} -.documentation { - overflow:hidden; - margin-bottom: 10rem; -} -.documentation a { - font-size:1em; - text-decoration: none; -} -.documentation > a > h2 { - cursor:pointer; - color:var(--sg1); - -} -.documentation > a >h2:hover { - color:var(--b2); -} -.documentation a:hover { - text-decoration: none; -} -.documentation pre { - margin-top: 0; -margin-bottom: 7px; -overflow: auto; --ms-overflow-style: scrollbar; -margin-top: 7px; -} -pre * { - font-family:monospace !important -} -.documentation a { - color:var(--b2); - padding-bottom: 2px; - position: relative; - font-style: normal; - cursor: pointer; -} -.documentation a:hover,a:focus { - text-decoration: none; - color:var(--b2); -} -.documentation a::before { - content: ""; - left: 0; - background-color: var(--b2); - width: 0%; - height: 1px; - top:-webkit-calc(1em + 8px); - top:calc(1em + 8px); - position: absolute; - z-index: 2; - -webkit-transition: background-color 0.2s, height 0.2s, top 0.2s, width 0.2s; - -o-transition: background-color 0.2s, height 0.2s, top 0.2s, width 0.2s; - transition: background-color 0.2s, height 0.2s, top 0.2s, width 0.2s;; -} -.documentation a:hover::before, .documentation a:focus::before { - content: ""; - left: 0; - background-color: var(--b2); - width: 100%; - height: 1px; - top:-webkit-calc(1em + 8px); - top:calc(1em + 8px); - position: absolute; - z-index: 2; - -webkit-transition: background-color 0.2s, height 0.2s, top 0.2s, width 0.2s; - -o-transition: background-color 0.2s, height 0.2s, top 0.2s, width 0.2s; - transition: background-color 0.2s, height 0.2s, top 0.2s, width 0.2s; - text-decoration: none; -} -.documentation img { - width:100%; - max-width:640px; - margin-left: 50%; - -webkit-transform: translate(-50%,0); - -ms-transform: translate(-50%,0); - transform: translate(-50%,0); - -} -h1, -h2, -h3, -h4, -h5, -h6 { - position: relative; - margin-bottom: 0.5rem; - font-weight: 500; - line-height: 1.4; - cursor: text; -} -h1:hover a.anchor, -h2:hover a.anchor, -h3:hover a.anchor, -h4:hover a.anchor, -h5:hover a.anchor, -h6:hover a.anchor { - text-decoration: none; -} -h1 tt, -h1 code { - font-size: inherit; -} -h2 tt, -h2 code { - font-size: inherit; -} -h3 tt, -h3 code { - font-size: inherit; -} -h4 tt, -h4 code { - font-size: inherit; -} -h5 tt, -h5 code { - font-size: inherit; -} -h6 tt, -h6 code { - font-size: inherit; -} -h1 { - font-size: 2.5rem; - line-height: 1.8; -} -h2 { - font-size: 1.7rem; - line-height: 1.8; - padding-left: 0.5em; -} -.documentation h2::before { - content:""; - height:1em;; - display: block; - width:3px; - margin-left: -0.5em; - margin-top: 0.4em; - position: absolute; - background-color: var(--b1); -} -h3 { - font-size: 1.4rem; - line-height: 1.43; -} -h4 { - font-size: 1.25rem; -} -h5 { - font-size: 1rem; -} -h6 { - font-size: 1rem; - color: #777; -} -p { - margin-bottom:0.5rem; - font-size:1em; - margin-top:0; - font-weight:300; -} -ol,ul,dl { - margin-top:0; - margin-bottom: 1rem; -} -li p { - margin-bottom: 0; -} -blockquote, -table{ - margin: 0.8em 0; - width:100%; -} -figure table{ - overflow: scroll; -} -hr { - height: 2px; - padding: 0; - margin: 16px 0; - background-color: #e7e7e7; - border: 0 none; - overflow: hidden; - -webkit-box-sizing: content-box; - box-sizing: content-box; -} - -li p.first { - display: inline-block; -} -ul, -ol { - padding-left: 30px; -} -ul:first-child, -ol:first-child { - margin-top: 0; -} -ul:last-child, -ol:last-child { - margin-bottom: 0; -} -blockquote { - border-left: 4px solid #dfe2e5; - padding: 0 15px; - color: #777777; -} -blockquote blockquote { - padding-right: 0; -} -table { - padding: 0; - word-break: initial; -} -table tr { - border-top: 1px solid #dfe2e5; - margin: 0; - padding: 0; -} -table tr:nth-child(2n), -thead { - background-color: #f8f8f8; -} -table tr th { - font-weight: bold; - border: 1px solid #dfe2e5; - border-bottom: 0; - text-align: left; - margin: 0; - padding: 6px 13px; -} -table tr td { - border: 1px solid #dfe2e5; - text-align: left; - margin: 0; - padding: 6px 13px; -} -table tr th:first-child, -table tr td:first-child { - margin-top: 0; -} -table tr th:last-child, -table tr td:last-child { - margin-bottom: 0; -} -h1 code,h2 code, h3 code, h4 code, h5 code, h6 code, -p code, li code, td code, -tt { - border: 1px solid #e7eaed; - background-color: #f8f8f8; - -webkit-border-radius: 3px; - border-radius: 3px; - padding: 0; - font-size: 0.9em; - color:var(--sg1); - font-family:monospace; - background-color: #f3f4f4; - padding: 0 2px 0 2px; -} -/*Tell prettyprinted code not to follow above*/ -.prettyprint code{ - border:none; - background-color:transparent; - font-size:inherit; - padding:0 1px 0 0px; -} \ No newline at end of file diff --git a/2.0/documentation/tdenginedocs-cn/lib/docs/liner.js b/2.0/documentation/tdenginedocs-cn/lib/docs/liner.js deleted file mode 100644 index 9cfeb88e10..0000000000 --- a/2.0/documentation/tdenginedocs-cn/lib/docs/liner.js +++ /dev/null @@ -1,19 +0,0 @@ -/*JS to determine how many lines used in pre/code block, sets CSS appropriately. MUST be placed after elements with prettyprint class are loaded*/ -$('.prettyprint').toArray().forEach(function(element){ - let linenums = element.clientHeight / 25.2; - if (linenums > 99) { - $(element).addClass('threec'); - } - else if (linenums > 9) { - $(element).addClass('twoc'); - } - }); -$('.prettyprint').toArray().forEach(function(element){ - let linenums = element.clientHeight / 25.2; - if (linenums > 99) { - $(element).addClass('threec'); - } - else if (linenums > 9) { - $(element).addClass('twoc'); - } -}); \ No newline at end of file diff --git a/2.0/documentation/tdenginedocs-cn/lib/docs/prettify.js b/2.0/documentation/tdenginedocs-cn/lib/docs/prettify.js deleted file mode 100644 index d2acd5d9d4..0000000000 --- a/2.0/documentation/tdenginedocs-cn/lib/docs/prettify.js +++ /dev/null @@ -1,46 +0,0 @@ -!function(){/* - - Copyright (C) 2006 Google Inc. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ -"undefined"!==typeof window&&(window.PR_SHOULD_USE_CONTINUATION=!0); -(function(){function T(a){function d(e){var a=e.charCodeAt(0);if(92!==a)return a;var c=e.charAt(1);return(a=w[c])?a:"0"<=c&&"7">=c?parseInt(e.substring(1),8):"u"===c||"x"===c?parseInt(e.substring(2),16):e.charCodeAt(1)}function f(e){if(32>e)return(16>e?"\\x0":"\\x")+e.toString(16);e=String.fromCharCode(e);return"\\"===e||"-"===e||"]"===e||"^"===e?"\\"+e:e}function c(e){var c=e.substring(1,e.length-1).match(RegExp("\\\\u[0-9A-Fa-f]{4}|\\\\x[0-9A-Fa-f]{2}|\\\\[0-3][0-7]{0,2}|\\\\[0-7]{1,2}|\\\\[\\s\\S]|-|[^-\\\\]","g")); -e=[];var a="^"===c[0],b=["["];a&&b.push("^");for(var a=a?1:0,g=c.length;ak||122k||90k||122h[0]&&(h[1]+1>h[0]&&b.push("-"),b.push(f(h[1])));b.push("]");return b.join("")}function m(e){for(var a=e.source.match(RegExp("(?:\\[(?:[^\\x5C\\x5D]|\\\\[\\s\\S])*\\]|\\\\u[A-Fa-f0-9]{4}|\\\\x[A-Fa-f0-9]{2}|\\\\[0-9]+|\\\\[^ux0-9]|\\(\\?[:!=]|[\\(\\)\\^]|[^\\x5B\\x5C\\(\\)\\^]+)","g")),b=a.length,d=[],g=0,h=0;g/,null])):d.push(["com",/^#[^\r\n]*/,null,"#"]));a.cStyleComments&&(f.push(["com",/^\/\/[^\r\n]*/,null]),f.push(["com",/^\/\*[\s\S]*?(?:\*\/|$)/,null]));if(c=a.regexLiterals){var m=(c=1|\\/=?|::?|<>?>?=?|,|;|\\?|@|\\[|~|{|\\^\\^?=?|\\|\\|?=?|break|case|continue|delete|do|else|finally|instanceof|return|throw|try|typeof)\\s*("+ -("/(?=[^/*"+c+"])(?:[^/\\x5B\\x5C"+c+"]|\\x5C"+m+"|\\x5B(?:[^\\x5C\\x5D"+c+"]|\\x5C"+m+")*(?:\\x5D|$))+/")+")")])}(c=a.types)&&f.push(["typ",c]);c=(""+a.keywords).replace(/^ | $/g,"");c.length&&f.push(["kwd",new RegExp("^(?:"+c.replace(/[\s,]+/g,"|")+")\\b"),null]);d.push(["pln",/^\s+/,null," \r\n\t\u00a0"]);c="^.[^\\s\\w.$@'\"`/\\\\]*";a.regexLiterals&&(c+="(?!s*/)");f.push(["lit",/^@[a-z_$][a-z_$@0-9]*/i,null],["typ",/^(?:[@_]?[A-Z]+[a-z][A-Za-z_$@0-9]*|\w+_t\b)/,null],["pln",/^[a-z_$][a-z_$@0-9]*/i, -null],["lit",/^(?:0x[a-f0-9]+|(?:\d(?:_\d+)*\d*(?:\.\d*)?|\.\d\+)(?:e[+\-]?\d+)?)[a-z]*/i,null,"0123456789"],["pln",/^\\[\s\S]?/,null],["pun",new RegExp(c),null]);return G(d,f)}function L(a,d,f){function c(a){var b=a.nodeType;if(1==b&&!t.test(a.className))if("br"===a.nodeName.toLowerCase())m(a),a.parentNode&&a.parentNode.removeChild(a);else for(a=a.firstChild;a;a=a.nextSibling)c(a);else if((3==b||4==b)&&f){var e=a.nodeValue,d=e.match(q);d&&(b=e.substring(0,d.index),a.nodeValue=b,(e=e.substring(d.index+ -d[0].length))&&a.parentNode.insertBefore(l.createTextNode(e),a.nextSibling),m(a),b||a.parentNode.removeChild(a))}}function m(a){function c(a,b){var e=b?a.cloneNode(!1):a,k=a.parentNode;if(k){var k=c(k,1),d=a.nextSibling;k.appendChild(e);for(var f=d;f;f=d)d=f.nextSibling,k.appendChild(f)}return e}for(;!a.nextSibling;)if(a=a.parentNode,!a)return;a=c(a.nextSibling,0);for(var e;(e=a.parentNode)&&1===e.nodeType;)a=e;b.push(a)}for(var t=/(?:^|\s)nocode(?:\s|$)/,q=/\r\n?|\n/,l=a.ownerDocument,n=l.createElement("li");a.firstChild;)n.appendChild(a.firstChild); -for(var b=[n],p=0;p=+m[1],d=/\n/g,t=a.a,q=t.length,f=0,l=a.c,n=l.length,c=0,b=a.g,p=b.length,w=0;b[p]=q;var r,e;for(e=r=0;e=h&&(c+=2);f>=k&&(w+=2)}}finally{g&&(g.style.display=a)}}catch(y){D.console&&console.log(y&&y.stack||y)}}var D="undefined"!==typeof window? -window:{},B=["break,continue,do,else,for,if,return,while"],F=[[B,"auto,case,char,const,default,double,enum,extern,float,goto,inline,int,long,register,restrict,short,signed,sizeof,static,struct,switch,typedef,union,unsigned,void,volatile"],"catch,class,delete,false,import,new,operator,private,protected,public,this,throw,true,try,typeof"],H=[F,"alignas,alignof,align_union,asm,axiom,bool,concept,concept_map,const_cast,constexpr,decltype,delegate,dynamic_cast,explicit,export,friend,generic,late_check,mutable,namespace,noexcept,noreturn,nullptr,property,reinterpret_cast,static_assert,static_cast,template,typeid,typename,using,virtual,where"], -O=[F,"abstract,assert,boolean,byte,extends,finally,final,implements,import,instanceof,interface,null,native,package,strictfp,super,synchronized,throws,transient"],P=[F,"abstract,add,alias,as,ascending,async,await,base,bool,by,byte,checked,decimal,delegate,descending,dynamic,event,finally,fixed,foreach,from,get,global,group,implicit,in,interface,internal,into,is,join,let,lock,null,object,out,override,orderby,params,partial,readonly,ref,remove,sbyte,sealed,select,set,stackalloc,string,select,uint,ulong,unchecked,unsafe,ushort,value,var,virtual,where,yield"], -F=[F,"abstract,async,await,constructor,debugger,enum,eval,export,from,function,get,import,implements,instanceof,interface,let,null,of,set,undefined,var,with,yield,Infinity,NaN"],Q=[B,"and,as,assert,class,def,del,elif,except,exec,finally,from,global,import,in,is,lambda,nonlocal,not,or,pass,print,raise,try,with,yield,False,True,None"],R=[B,"alias,and,begin,case,class,def,defined,elsif,end,ensure,false,in,module,next,nil,not,or,redo,rescue,retry,self,super,then,true,undef,unless,until,when,yield,BEGIN,END"], -B=[B,"case,done,elif,esac,eval,fi,function,in,local,set,then,until"],S=/^(DIR|FILE|array|vector|(de|priority_)?queue|(forward_)?list|stack|(const_)?(reverse_)?iterator|(unordered_)?(multi)?(set|map)|bitset|u?(int|float)\d*)\b/,W=/\S/,X=x({keywords:[H,P,O,F,"caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END",Q,R,B],hashComments:!0,cStyleComments:!0,multiLineStrings:!0,regexLiterals:!0}), -I={};t(X,["default-code"]);t(G([],[["pln",/^[^]*(?:>|$)/],["com",/^<\!--[\s\S]*?(?:-\->|$)/],["lang-",/^<\?([\s\S]+?)(?:\?>|$)/],["lang-",/^<%([\s\S]+?)(?:%>|$)/],["pun",/^(?:<[%?]|[%?]>)/],["lang-",/^]*>([\s\S]+?)<\/xmp\b[^>]*>/i],["lang-js",/^]*>([\s\S]*?)(<\/script\b[^>]*>)/i],["lang-css",/^]*>([\s\S]*?)(<\/style\b[^>]*>)/i],["lang-in.tag",/^(<\/?[a-z][^<>]*>)/i]]),"default-markup htm html mxml xhtml xml xsl".split(" "));t(G([["pln",/^[\s]+/, -null," \t\r\n"],["atv",/^(?:\"[^\"]*\"?|\'[^\']*\'?)/,null,"\"'"]],[["tag",/^^<\/?[a-z](?:[\w.:-]*\w)?|\/?>$/i],["atn",/^(?!style[\s=]|on)[a-z](?:[\w:-]*\w)?/i],["lang-uq.val",/^=\s*([^>\'\"\s]*(?:[^>\'\"\s\/]|\/(?=\s)))/],["pun",/^[=<>\/]+/],["lang-js",/^on\w+\s*=\s*\"([^\"]+)\"/i],["lang-js",/^on\w+\s*=\s*\'([^\']+)\'/i],["lang-js",/^on\w+\s*=\s*([^\"\'>\s]+)/i],["lang-css",/^style\s*=\s*\"([^\"]+)\"/i],["lang-css",/^style\s*=\s*\'([^\']+)\'/i],["lang-css",/^style\s*=\s*([^\"\'>\s]+)/i]]),["in.tag"]); -t(G([],[["atv",/^[\s\S]+/]]),["uq.val"]);t(x({keywords:H,hashComments:!0,cStyleComments:!0,types:S}),"c cc cpp cxx cyc m".split(" "));t(x({keywords:"null,true,false"}),["json"]);t(x({keywords:P,hashComments:!0,cStyleComments:!0,verbatimStrings:!0,types:S}),["cs"]);t(x({keywords:O,cStyleComments:!0}),["java"]);t(x({keywords:B,hashComments:!0,multiLineStrings:!0}),["bash","bsh","csh","sh"]);t(x({keywords:Q,hashComments:!0,multiLineStrings:!0,tripleQuotedStrings:!0}),["cv","py","python"]);t(x({keywords:"caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END", -hashComments:!0,multiLineStrings:!0,regexLiterals:2}),["perl","pl","pm"]);t(x({keywords:R,hashComments:!0,multiLineStrings:!0,regexLiterals:!0}),["rb","ruby"]);t(x({keywords:F,cStyleComments:!0,regexLiterals:!0}),["javascript","js","ts","typescript"]);t(x({keywords:"all,and,by,catch,class,else,extends,false,finally,for,if,in,is,isnt,loop,new,no,not,null,of,off,on,or,return,super,then,throw,true,try,unless,until,when,while,yes",hashComments:3,cStyleComments:!0,multilineStrings:!0,tripleQuotedStrings:!0, -regexLiterals:!0}),["coffee"]);t(G([],[["str",/^[\s\S]+/]]),["regex"]);var Y=D.PR={createSimpleLexer:G,registerLangHandler:t,sourceDecorator:x,PR_ATTRIB_NAME:"atn",PR_ATTRIB_VALUE:"atv",PR_COMMENT:"com",PR_DECLARATION:"dec",PR_KEYWORD:"kwd",PR_LITERAL:"lit",PR_NOCODE:"nocode",PR_PLAIN:"pln",PR_PUNCTUATION:"pun",PR_SOURCE:"src",PR_STRING:"str",PR_TAG:"tag",PR_TYPE:"typ",TAOSDATA_FUNCTION:"td-fun",TAOSDATA_DATATYPE:"td-dtp",TAOSDATA_TERMINAL:"tem",TAOSDATA_OPTION:"td-opt",prettyPrintOne:D.prettyPrintOne=function(a,d,f){f=f||!1;d=d||null;var c=document.createElement("div");c.innerHTML="
    "+a+"
    "; -c=c.firstChild;f&&L(c,f,!0);M({j:d,m:f,h:c,l:1,a:null,i:null,c:null,g:null});return c.innerHTML},prettyPrint:D.prettyPrint=function(a,d){function f(){for(var c=D.PR_SHOULD_USE_CONTINUATION?b.now()+250:Infinity;p li { - counter-increment: customlistcounter; -} -pre.prettyprint ol > li:first-child:before { - border-top-left-radius: 0.25rem; -} -pre.prettyprint ol > li:last-child:before { - border-bottom-left-radius: 0.25rem; -} -pre.prettyprint ol > li:before { - content: counter(customlistcounter) " "; - font-weight: 300; - display: inline-block; - position: absolute; - transform:translateX(-38px); - width: 27px; - text-align: right; - background-color:var(--white); - padding-bottom: 0.1px; -} -pre.prettyprint ol > li:nth-last-child(1)::before { - padding-bottom: 0px !important; -} - -pre.prettyprint.twoc ol > li:before { - transform:translateX(-45px); - width:34px; -} -pre.prettyprint.twoc { - padding-left:35px; -} -pre.prettyprint.threec ol > li:before { - transform:translateX(-53px); - width:42px; -} -pre.prettyprint.threec { - padding-left:43px; -} - -ol:first-child { - counter-reset: customlistcounter; -} -pre.prettyprint ol { - padding-right: 4px; -} -pre .atn, -pre .kwd, -pre .tag { - font-weight: 400 -} -pre * { - font-family:monospace; -} -pre.prettyprint li { - background-color:rgb(244,245,246); -} -pre.prettyprint { - display: block; - background-color:rgb(244,245,246); - border-radius:0.25rem; - padding-left: 27px; - /*each additional digit needs 8px*/ - width:100%; - border:1px solid #e7eaed; - color:#d58936; -} -/* TAOSDATA Specific */ -pre.lang-blank span { - color:var(--sg1); -} -pre.lang-blank { - -} -pre.lang-term span{ - color: var(--white) ; -} -pre.lang-term ol { - background-color: var(--sg1); -} -pre.lang-term ol.linenums { - border-left:1px solid var(--sg1); -} -pre.lang-term li { - background-color:var(--sg1); -} -/*Functions*/ -pre .td-fun { - color:#f24352; -} -/*Options*/ -pre .td-opt { - /*color:mediumpurple;*/ - color:#5882bc; -} -/*Datatypes*/ -pre .td-dtp { - color:darkcyan; -} -pre .nocode { - background-color: var(--white); - color: var(--sg1); -} -/*Strings*/ -pre .str { - color: #690; -} -/*Keywords*/ -pre .kwd { - color: #5882bc; -} -/*Comments*/ -pre .com { - color: slategray; -} -/*Type*/ -pre .typ { - color: #9c5fc6; -} -/*Literals*/ -pre .lit { - color: #91001f; -} -/*Plain Text*/ -pre .pln { - color: #d58936; -} -/*Punctuation*/ -pre .pun { - color: rgb(51,66,78); -} -pre .tag { - color: khaki -} - -pre .atn { - color: #bdb76b -} - -pre .atv { - color: #ffa0a0 -} - -pre .dec { - color: #98fb98 -} - -ol.linenums { - margin-top: 0; - margin-bottom: 0; - color: #AEAEAE; - border-left:1px solid var(--b1); - padding-left: 0px; -} -pre li { - padding-left: 0.6rem; -} -li.L0, -li.L1, -li.L2, -li.L3, -li.L5, -li.L6, -li.L7, -li.L8 { - list-style-type: none -} - -@media print { - pre.prettyprint { - background-color: none - } - - code .str, - pre .str { - color: #690; - } - - code .kwd, - pre .kwd { - color: #5882bc; - font-weight: 400 - } - - code .com, - pre .com { - color: #600; - font-style: italic - } - - code .typ, - pre .typ { - color: #404; - font-weight: 400 - } - - code .lit, - pre .lit { - color: #044 - } - - code .pun, - pre .pun { - color: #440 - } - - code .pln, - pre .pln { - color: #000 - } - - code .tag, - pre .tag { - color: #006; - font-weight: 400 - } - - code .atn, - pre .atn { - color: #404 - } - - code .atv, - pre .atv { - color: #060 - } -} \ No newline at end of file diff --git a/2.0/documentation/tdenginedocs-cn/lib/jquery-3.4.1.min.js b/2.0/documentation/tdenginedocs-cn/lib/jquery-3.4.1.min.js deleted file mode 100644 index a1c07fd803..0000000000 --- a/2.0/documentation/tdenginedocs-cn/lib/jquery-3.4.1.min.js +++ /dev/null @@ -1,2 +0,0 @@ -/*! jQuery v3.4.1 | (c) JS Foundation and other contributors | jquery.org/license */ -!function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(C,e){"use strict";var t=[],E=C.document,r=Object.getPrototypeOf,s=t.slice,g=t.concat,u=t.push,i=t.indexOf,n={},o=n.toString,v=n.hasOwnProperty,a=v.toString,l=a.call(Object),y={},m=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType},x=function(e){return null!=e&&e===e.window},c={type:!0,src:!0,nonce:!0,noModule:!0};function b(e,t,n){var r,i,o=(n=n||E).createElement("script");if(o.text=e,t)for(r in c)(i=t[r]||t.getAttribute&&t.getAttribute(r))&&o.setAttribute(r,i);n.head.appendChild(o).parentNode.removeChild(o)}function w(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[o.call(e)]||"object":typeof e}var f="3.4.1",k=function(e,t){return new k.fn.init(e,t)},p=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g;function d(e){var t=!!e&&"length"in e&&e.length,n=w(e);return!m(e)&&!x(e)&&("array"===n||0===t||"number"==typeof t&&0+~]|"+M+")"+M+"*"),U=new RegExp(M+"|>"),X=new RegExp($),V=new RegExp("^"+I+"$"),G={ID:new RegExp("^#("+I+")"),CLASS:new RegExp("^\\.("+I+")"),TAG:new RegExp("^("+I+"|[*])"),ATTR:new RegExp("^"+W),PSEUDO:new RegExp("^"+$),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+R+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Y=/HTML$/i,Q=/^(?:input|select|textarea|button)$/i,J=/^h\d$/i,K=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ee=/[+~]/,te=new RegExp("\\\\([\\da-f]{1,6}"+M+"?|("+M+")|.)","ig"),ne=function(e,t,n){var r="0x"+t-65536;return r!=r||n?t:r<0?String.fromCharCode(r+65536):String.fromCharCode(r>>10|55296,1023&r|56320)},re=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ie=function(e,t){return t?"\0"===e?"\ufffd":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},oe=function(){T()},ae=be(function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()},{dir:"parentNode",next:"legend"});try{H.apply(t=O.call(m.childNodes),m.childNodes),t[m.childNodes.length].nodeType}catch(e){H={apply:t.length?function(e,t){L.apply(e,O.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function se(t,e,n,r){var i,o,a,s,u,l,c,f=e&&e.ownerDocument,p=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==p&&9!==p&&11!==p)return n;if(!r&&((e?e.ownerDocument||e:m)!==C&&T(e),e=e||C,E)){if(11!==p&&(u=Z.exec(t)))if(i=u[1]){if(9===p){if(!(a=e.getElementById(i)))return n;if(a.id===i)return n.push(a),n}else if(f&&(a=f.getElementById(i))&&y(e,a)&&a.id===i)return n.push(a),n}else{if(u[2])return H.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&d.getElementsByClassName&&e.getElementsByClassName)return H.apply(n,e.getElementsByClassName(i)),n}if(d.qsa&&!A[t+" "]&&(!v||!v.test(t))&&(1!==p||"object"!==e.nodeName.toLowerCase())){if(c=t,f=e,1===p&&U.test(t)){(s=e.getAttribute("id"))?s=s.replace(re,ie):e.setAttribute("id",s=k),o=(l=h(t)).length;while(o--)l[o]="#"+s+" "+xe(l[o]);c=l.join(","),f=ee.test(t)&&ye(e.parentNode)||e}try{return H.apply(n,f.querySelectorAll(c)),n}catch(e){A(t,!0)}finally{s===k&&e.removeAttribute("id")}}}return g(t.replace(B,"$1"),e,n,r)}function ue(){var r=[];return function e(t,n){return r.push(t+" ")>b.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function le(e){return e[k]=!0,e}function ce(e){var t=C.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function fe(e,t){var n=e.split("|"),r=n.length;while(r--)b.attrHandle[n[r]]=t}function pe(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function de(t){return function(e){return"input"===e.nodeName.toLowerCase()&&e.type===t}}function he(n){return function(e){var t=e.nodeName.toLowerCase();return("input"===t||"button"===t)&&e.type===n}}function ge(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&ae(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function ve(a){return le(function(o){return o=+o,le(function(e,t){var n,r=a([],e.length,o),i=r.length;while(i--)e[n=r[i]]&&(e[n]=!(t[n]=e[n]))})})}function ye(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}for(e in d=se.support={},i=se.isXML=function(e){var t=e.namespaceURI,n=(e.ownerDocument||e).documentElement;return!Y.test(t||n&&n.nodeName||"HTML")},T=se.setDocument=function(e){var t,n,r=e?e.ownerDocument||e:m;return r!==C&&9===r.nodeType&&r.documentElement&&(a=(C=r).documentElement,E=!i(C),m!==C&&(n=C.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",oe,!1):n.attachEvent&&n.attachEvent("onunload",oe)),d.attributes=ce(function(e){return e.className="i",!e.getAttribute("className")}),d.getElementsByTagName=ce(function(e){return e.appendChild(C.createComment("")),!e.getElementsByTagName("*").length}),d.getElementsByClassName=K.test(C.getElementsByClassName),d.getById=ce(function(e){return a.appendChild(e).id=k,!C.getElementsByName||!C.getElementsByName(k).length}),d.getById?(b.filter.ID=function(e){var t=e.replace(te,ne);return function(e){return e.getAttribute("id")===t}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n=t.getElementById(e);return n?[n]:[]}}):(b.filter.ID=function(e){var n=e.replace(te,ne);return function(e){var t="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),b.find.TAG=d.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):d.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},b.find.CLASS=d.getElementsByClassName&&function(e,t){if("undefined"!=typeof t.getElementsByClassName&&E)return t.getElementsByClassName(e)},s=[],v=[],(d.qsa=K.test(C.querySelectorAll))&&(ce(function(e){a.appendChild(e).innerHTML="",e.querySelectorAll("[msallowcapture^='']").length&&v.push("[*^$]="+M+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||v.push("\\["+M+"*(?:value|"+R+")"),e.querySelectorAll("[id~="+k+"-]").length||v.push("~="),e.querySelectorAll(":checked").length||v.push(":checked"),e.querySelectorAll("a#"+k+"+*").length||v.push(".#.+[+~]")}),ce(function(e){e.innerHTML="";var t=C.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&v.push("name"+M+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&v.push(":enabled",":disabled"),a.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&v.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),v.push(",.*:")})),(d.matchesSelector=K.test(c=a.matches||a.webkitMatchesSelector||a.mozMatchesSelector||a.oMatchesSelector||a.msMatchesSelector))&&ce(function(e){d.disconnectedMatch=c.call(e,"*"),c.call(e,"[s!='']:x"),s.push("!=",$)}),v=v.length&&new RegExp(v.join("|")),s=s.length&&new RegExp(s.join("|")),t=K.test(a.compareDocumentPosition),y=t||K.test(a.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},D=t?function(e,t){if(e===t)return l=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)===(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!d.sortDetached&&t.compareDocumentPosition(e)===n?e===C||e.ownerDocument===m&&y(m,e)?-1:t===C||t.ownerDocument===m&&y(m,t)?1:u?P(u,e)-P(u,t):0:4&n?-1:1)}:function(e,t){if(e===t)return l=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,a=[e],s=[t];if(!i||!o)return e===C?-1:t===C?1:i?-1:o?1:u?P(u,e)-P(u,t):0;if(i===o)return pe(e,t);n=e;while(n=n.parentNode)a.unshift(n);n=t;while(n=n.parentNode)s.unshift(n);while(a[r]===s[r])r++;return r?pe(a[r],s[r]):a[r]===m?-1:s[r]===m?1:0}),C},se.matches=function(e,t){return se(e,null,null,t)},se.matchesSelector=function(e,t){if((e.ownerDocument||e)!==C&&T(e),d.matchesSelector&&E&&!A[t+" "]&&(!s||!s.test(t))&&(!v||!v.test(t)))try{var n=c.call(e,t);if(n||d.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){A(t,!0)}return 0":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(te,ne),e[3]=(e[3]||e[4]||e[5]||"").replace(te,ne),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||se.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&se.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return G.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&X.test(n)&&(t=h(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(te,ne).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=p[e+" "];return t||(t=new RegExp("(^|"+M+")"+e+"("+M+"|$)"))&&p(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,r,i){return function(e){var t=se.attr(e,n);return null==t?"!="===r:!r||(t+="","="===r?t===i:"!="===r?t!==i:"^="===r?i&&0===t.indexOf(i):"*="===r?i&&-1:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function j(e,n,r){return m(n)?k.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?k.grep(e,function(e){return e===n!==r}):"string"!=typeof n?k.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(k.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||q,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:L.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof k?t[0]:t,k.merge(this,k.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:E,!0)),D.test(r[1])&&k.isPlainObject(t))for(r in t)m(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=E.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):m(e)?void 0!==n.ready?n.ready(e):e(k):k.makeArray(e,this)}).prototype=k.fn,q=k(E);var H=/^(?:parents|prev(?:Until|All))/,O={children:!0,contents:!0,next:!0,prev:!0};function P(e,t){while((e=e[t])&&1!==e.nodeType);return e}k.fn.extend({has:function(e){var t=k(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,he=/^$|^module$|\/(?:java|ecma)script/i,ge={option:[1,""],thead:[1,"","
    "],col:[2,"","
    "],tr:[2,"","
    "],td:[3,"","
    "],_default:[0,"",""]};function ve(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&A(e,t)?k.merge([e],n):n}function ye(e,t){for(var n=0,r=e.length;nx",y.noCloneChecked=!!me.cloneNode(!0).lastChild.defaultValue;var Te=/^key/,Ce=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,Ee=/^([^.]*)(?:\.(.+)|)/;function ke(){return!0}function Se(){return!1}function Ne(e,t){return e===function(){try{return E.activeElement}catch(e){}}()==("focus"===t)}function Ae(e,t,n,r,i,o){var a,s;if("object"==typeof t){for(s in"string"!=typeof n&&(r=r||n,n=void 0),t)Ae(e,s,n,r,t[s],o);return e}if(null==r&&null==i?(i=n,r=n=void 0):null==i&&("string"==typeof n?(i=r,r=void 0):(i=r,r=n,n=void 0)),!1===i)i=Se;else if(!i)return e;return 1===o&&(a=i,(i=function(e){return k().off(e),a.apply(this,arguments)}).guid=a.guid||(a.guid=k.guid++)),e.each(function(){k.event.add(this,t,i,r,n)})}function De(e,i,o){o?(Q.set(e,i,!1),k.event.add(e,i,{namespace:!1,handler:function(e){var t,n,r=Q.get(this,i);if(1&e.isTrigger&&this[i]){if(r.length)(k.event.special[i]||{}).delegateType&&e.stopPropagation();else if(r=s.call(arguments),Q.set(this,i,r),t=o(this,i),this[i](),r!==(n=Q.get(this,i))||t?Q.set(this,i,!1):n={},r!==n)return e.stopImmediatePropagation(),e.preventDefault(),n.value}else r.length&&(Q.set(this,i,{value:k.event.trigger(k.extend(r[0],k.Event.prototype),r.slice(1),this)}),e.stopImmediatePropagation())}})):void 0===Q.get(e,i)&&k.event.add(e,i,ke)}k.event={global:{},add:function(t,e,n,r,i){var o,a,s,u,l,c,f,p,d,h,g,v=Q.get(t);if(v){n.handler&&(n=(o=n).handler,i=o.selector),i&&k.find.matchesSelector(ie,i),n.guid||(n.guid=k.guid++),(u=v.events)||(u=v.events={}),(a=v.handle)||(a=v.handle=function(e){return"undefined"!=typeof k&&k.event.triggered!==e.type?k.event.dispatch.apply(t,arguments):void 0}),l=(e=(e||"").match(R)||[""]).length;while(l--)d=g=(s=Ee.exec(e[l])||[])[1],h=(s[2]||"").split(".").sort(),d&&(f=k.event.special[d]||{},d=(i?f.delegateType:f.bindType)||d,f=k.event.special[d]||{},c=k.extend({type:d,origType:g,data:r,handler:n,guid:n.guid,selector:i,needsContext:i&&k.expr.match.needsContext.test(i),namespace:h.join(".")},o),(p=u[d])||((p=u[d]=[]).delegateCount=0,f.setup&&!1!==f.setup.call(t,r,h,a)||t.addEventListener&&t.addEventListener(d,a)),f.add&&(f.add.call(t,c),c.handler.guid||(c.handler.guid=n.guid)),i?p.splice(p.delegateCount++,0,c):p.push(c),k.event.global[d]=!0)}},remove:function(e,t,n,r,i){var o,a,s,u,l,c,f,p,d,h,g,v=Q.hasData(e)&&Q.get(e);if(v&&(u=v.events)){l=(t=(t||"").match(R)||[""]).length;while(l--)if(d=g=(s=Ee.exec(t[l])||[])[1],h=(s[2]||"").split(".").sort(),d){f=k.event.special[d]||{},p=u[d=(r?f.delegateType:f.bindType)||d]||[],s=s[2]&&new RegExp("(^|\\.)"+h.join("\\.(?:.*\\.|)")+"(\\.|$)"),a=o=p.length;while(o--)c=p[o],!i&&g!==c.origType||n&&n.guid!==c.guid||s&&!s.test(c.namespace)||r&&r!==c.selector&&("**"!==r||!c.selector)||(p.splice(o,1),c.selector&&p.delegateCount--,f.remove&&f.remove.call(e,c));a&&!p.length&&(f.teardown&&!1!==f.teardown.call(e,h,v.handle)||k.removeEvent(e,d,v.handle),delete u[d])}else for(d in u)k.event.remove(e,d+t[l],n,r,!0);k.isEmptyObject(u)&&Q.remove(e,"handle events")}},dispatch:function(e){var t,n,r,i,o,a,s=k.event.fix(e),u=new Array(arguments.length),l=(Q.get(this,"events")||{})[s.type]||[],c=k.event.special[s.type]||{};for(u[0]=s,t=1;t\x20\t\r\n\f]*)[^>]*)\/>/gi,qe=/\s*$/g;function Oe(e,t){return A(e,"table")&&A(11!==t.nodeType?t:t.firstChild,"tr")&&k(e).children("tbody")[0]||e}function Pe(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function Re(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Me(e,t){var n,r,i,o,a,s,u,l;if(1===t.nodeType){if(Q.hasData(e)&&(o=Q.access(e),a=Q.set(t,o),l=o.events))for(i in delete a.handle,a.events={},l)for(n=0,r=l[i].length;n")},clone:function(e,t,n){var r,i,o,a,s,u,l,c=e.cloneNode(!0),f=oe(e);if(!(y.noCloneChecked||1!==e.nodeType&&11!==e.nodeType||k.isXMLDoc(e)))for(a=ve(c),r=0,i=(o=ve(e)).length;r").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",i=function(e){r.remove(),i=null,e&&t("error"===e.type?404:200,e.type)}),E.head.appendChild(r[0])},abort:function(){i&&i()}}});var Vt,Gt=[],Yt=/(=)\?(?=&|$)|\?\?/;k.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=Gt.pop()||k.expando+"_"+kt++;return this[e]=!0,e}}),k.ajaxPrefilter("json jsonp",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Yt.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&Yt.test(e.data)&&"data");if(a||"jsonp"===e.dataTypes[0])return r=e.jsonpCallback=m(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Yt,"$1"+r):!1!==e.jsonp&&(e.url+=(St.test(e.url)?"&":"?")+e.jsonp+"="+r),e.converters["script json"]=function(){return o||k.error(r+" was not called"),o[0]},e.dataTypes[0]="json",i=C[r],C[r]=function(){o=arguments},n.always(function(){void 0===i?k(C).removeProp(r):C[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,Gt.push(r)),o&&m(i)&&i(o[0]),o=i=void 0}),"script"}),y.createHTMLDocument=((Vt=E.implementation.createHTMLDocument("").body).innerHTML="
    ",2===Vt.childNodes.length),k.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(y.createHTMLDocument?((r=(t=E.implementation.createHTMLDocument("")).createElement("base")).href=E.location.href,t.head.appendChild(r)):t=E),o=!n&&[],(i=D.exec(e))?[t.createElement(i[1])]:(i=we([e],t,o),o&&o.length&&k(o).remove(),k.merge([],i.childNodes)));var r,i,o},k.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return-1").append(k.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},k.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){k.fn[t]=function(e){return this.on(t,e)}}),k.expr.pseudos.animated=function(t){return k.grep(k.timers,function(e){return t===e.elem}).length},k.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=k.css(e,"position"),c=k(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=k.css(e,"top"),u=k.css(e,"left"),("absolute"===l||"fixed"===l)&&-1<(o+u).indexOf("auto")?(a=(r=c.position()).top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),m(t)&&(t=t.call(e,n,k.extend({},s))),null!=t.top&&(f.top=t.top-s.top+a),null!=t.left&&(f.left=t.left-s.left+i),"using"in t?t.using.call(e,f):c.css(f)}},k.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){k.offset.setOffset(this,t,e)});var e,n,r=this[0];return r?r.getClientRects().length?(e=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if("fixed"===k.css(r,"position"))t=r.getBoundingClientRect();else{t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;while(e&&(e===n.body||e===n.documentElement)&&"static"===k.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=k(e).offset()).top+=k.css(e,"borderTopWidth",!0),i.left+=k.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-k.css(r,"marginTop",!0),left:t.left-i.left-k.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===k.css(e,"position"))e=e.offsetParent;return e||ie})}}),k.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;k.fn[t]=function(e){return _(this,function(e,t,n){var r;if(x(e)?r=e:9===e.nodeType&&(r=e.defaultView),void 0===n)return r?r[i]:e[t];r?r.scrollTo(o?r.pageXOffset:n,o?n:r.pageYOffset):e[t]=n},t,e,arguments.length)}}),k.each(["top","left"],function(e,n){k.cssHooks[n]=ze(y.pixelPosition,function(e,t){if(t)return t=_e(e,n),$e.test(t)?k(e).position()[n]+"px":t})}),k.each({Height:"height",Width:"width"},function(a,s){k.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){k.fn[o]=function(e,t){var n=arguments.length&&(r||"boolean"!=typeof e),i=r||(!0===e||!0===t?"margin":"border");return _(this,function(e,t,n){var r;return x(e)?0===o.indexOf("outer")?e["inner"+a]:e.document.documentElement["client"+a]:9===e.nodeType?(r=e.documentElement,Math.max(e.body["scroll"+a],r["scroll"+a],e.body["offset"+a],r["offset"+a],r["client"+a])):void 0===n?k.css(e,t,i):k.style(e,t,n,i)},s,n?e:void 0,n)}})}),k.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){k.fn[n]=function(e,t){return 0文档 | 涛思数据
    回去

    TDengine的技术设计

    -

    存储设计

    -

    TDengine的数据存储主要包含元数据的存储写入数据的存储。以下章节详细介绍了TDengine各种数据的存储结构。

    -

    元数据的存储

    -

    TDengine中的元数据信息包括TDengine中的数据库,表,超级表等信息。元数据信息默认存放在 /var/lib/taos/mgmt/ 文件夹下。该文件夹的目录结构如下所示:

    -
    /var/lib/taos/
    -      +--mgmt/
    -          +--db.db
    -          +--meters.db
    -          +--user.db
    -          +--vgroups.db
    -

    元数据在文件中按顺序排列。文件中的每条记录代表TDengine中的一个元数据机构(数据库、表等)。元数据文件只进行追加操作,即便是元数据的删除,也只是在数据文件中追加一条删除的记录。

    -

    写入数据的存储

    -

    TDengine中写入的数据在硬盘上是按时间维度进行分片的。同一个vnode中的表在同一时间范围内的数据都存放在同一文件组中,如下图中的v0f1804*文件。这一数据分片方式可以大大简化数据在时间维度的查询,提高查询速度。在默认配置下,硬盘上的每个文件存放10天数据。用户可根据需要调整数据库的 daysPerFile 配置项进行配置。 数据在文件中是按块存储的。每个数据块只包含一张表的数据,且数据是按照时间主键递增排列的。数据在数据块中按列存储,这样使得同类型的数据存放在一起,可以大大提高压缩的比例,节省存储空间。TDengine对不同类型的数据采用了不同的压缩算法进行压缩,以达到最优的压缩结果。TDengine使用的压缩算法包括simple8B、delta-of-delta、RLE以及LZ4等。

    -

    TDengine的数据文件默认存放在 /var/lib/taos/data/ 下。而 /var/lib/taos/tsdb/ 文件夹下存放了vnode的信息、vnode中表的信息以及数据文件的链接等。其完整目录结构如下所示:

    -
    /var/lib/taos/
    -      +--tsdb/
    -      |   +--vnode0
    -      |        +--meterObj.v0
    -      |        +--db/
    -      |            +--v0f1804.head->/var/lib/taos/data/vnode0/v0f1804.head1
    -      |            +--v0f1804.data->/var/lib/taos/data/vnode0/v0f1804.data
    -      |            +--v0f1804.last->/var/lib/taos/data/vnode0/v0f1804.last1
    -      |            +--v0f1805.head->/var/lib/taos/data/vnode0/v0f1805.head1
    -      |            +--v0f1805.data->/var/lib/taos/data/vnode0/v0f1805.data
    -      |            +--v0f1805.last->/var/lib/taos/data/vnode0/v0f1805.last1
    -      |                   :
    -      +--data/
    -          +--vnode0/
    -                +--v0f1804.head1
    -                +--v0f1804.data
    -                +--v0f1804.last1
    -                +--v0f1805.head1
    -                +--v0f1805.data
    -                +--v0f1805.last1
    -                        :
    -

    meterObj文件

    -

    每个vnode中只存在一个 meterObj 文件。该文件中存储了vnode的基本信息(创建时间,配置信息,vnode的统计信息等)以及该vnode中表的信息。其结构如下所示:

    -
    <文件开始>
    -[文件头]
    -[表记录1偏移量和长度]
    -[表记录2偏移量和长度]
    -...
    -[表记录N偏移量和长度]
    -[表记录1]
    -[表记录2]
    -...
    -[表记录N]
    -[表记录]
    -<文件结尾>
    -

    其中,文件头大小为512字节,主要存放vnode的基本信息。每条表记录代表属于该vnode中的一张表在硬盘上的表示。

    -

    head文件

    -

    head文件中存放了其对应的data文件中数据块的索引信息。该文件组织形式如下:

    -
    <文件开始>
    -[文件头]
    -[表1偏移量]
    -[表2偏移量]
    -...
    -[表N偏移量]
    -[表1数据索引]
    -[表2数据索引]
    -...
    -[表N数据索引]
    -<文件结尾>
    -

    文件开头的偏移量列表表示对应表的数据索引块的开始位置在文件中的偏移量。每张表的数据索引信息在head文件中都是连续存放的。这也使得TDengine在读取单表数据时,可以将该表所有的数据块索引一次性读入内存,大大提高读取速度。表的数据索引块组织如下:

    -
    [索引块信息]
    -[数据块1索引]
    -[数据块2索引]
    -...
    -[数据块N索引]
    -

    其中,索引块信息中记录了数据块的个数等描述信息。每个数据块索引对应一个在data文件或last文件中的一个单独的数据块。索引信息中记录了数据块存放的文件、数据块起始位置的偏移量、数据块中数据时间主键的范围等。索引块中的数据块索引是按照时间范围顺序排放的,这也就是说,索引块M对应的数据块中的数据时间范围都大于索引块M-1的。这种预先排序的存储方式使得在TDengine在进行按照时间戳进行查询时可以使用折半查找算法,大大提高查询速度。

    -

    data文件

    -

    data文件中存放了真实的数据块。该文件只进行追加操作。其文件组织形式如下:

    -
    <文件开始>
    -[文件头]
    -[数据块1]
    -[数据块2]
    -...
    -[数据块N]
    -<文件结尾>
    -

    每个数据块只属于vnode中的一张表,且数据块中的数据按照时间主键排列。数据块中的数据按列组织排放,使得同一类型的数据排放在一起,方便压缩和读取。每个数据块的组织形式如下所示:

    -
    [列1信息]
    -[列2信息]
    -...
    -[列N信息]
    -[列1数据]
    -[列2数据]
    -...
    -[列N数据]
    -

    列信息中包含该列的类型,列的压缩算法,列数据在文件中的偏移量以及长度等。除此之外,列信息中也包含该内存块中该列数据的预计算结果,从而在过滤查询时根据预计算结果判定是否读取数据块,大大提高读取速度。

    -

    last文件

    -

    为了防止数据块的碎片化,提高查询速度和压缩率,TDengine引入了last文件。当要落盘的数据块中的数据条数低于某个阈值时,TDengine会先将该数据块写入到last文件中进行暂时存储。当有新的数据需要落盘时,last文件中的数据会被读取出来与新数据组成新的数据块写入到data文件中。last文件的组织形式与data文件类似。

    -

    TDengine数据存储小结

    -

    TDengine通过其创新的架构和存储结构设计,有效提高了计算机资源的使用率。一方面,TDengine的虚拟化使得TDengine的水平扩展及备份非常容易。另一方面,TDengine将表中数据按时间主键排序存储且其列式存储的组织形式都使TDengine在写入、查询以及压缩方面拥有非常大的优势。

    -

    查询处理

    -

    概述

    -

    TDengine提供了多种多样针对表和超级表的查询处理功能,除了常规的聚合查询之外,还提供针对时序数据的窗口查询、统计聚合等功能。TDengine的查询处理需要客户端、管理节点、数据节点协同完成。 各组件包含的与查询处理相关的功能和模块如下:

    -

    客户端(Client App)。客户端包含TAOS SQL的解析(SQL Parser)和查询请求执行器(Query Executor),第二阶段聚合器(Result Merger),连续查询管理器(Continuous Query Manager)等主要功能模块构成。SQL解析器负责对SQL语句进行解析校验,并转化为抽象语法树,查询执行器负责将抽象语法树转化查询执行逻辑,并根据SQL语句查询条件,将其转换为针对管理节点元数据查询和针对数据节点的数据查询两级查询处理。由于TAOS SQL当前不提供复杂的嵌套查询和pipeline查询处理机制,所以不再需要查询计划优化、逻辑查询计划到物理查询计划转换等过程。第二阶段聚合器负责将各数据节点查询返回的独立结果进行二阶段聚合生成最后的结果。连续查询管理器则负责针对用户建立的连续查询进行管理,负责定时拉起查询请求并按需将结果写回TDengine或返回给客户应用。此外,客户端还负责查询失败后重试、取消查询请求、以及维持连接心跳、向管理节点上报查询状态等工作。

    -

    管理节点(Management Node)。管理节点保存了整个集群系统的全部数据的元数据信息,向客户端节点提供查询所需的数据的元数据,并根据集群的负载情况切分查询请求。通过超级表包含了通过该超级表创建的所有表的信息,因此查询处理器(Query Executor)负责针对标签(TAG)的查询处理,并将满足标签查询请求的表信息返回给客户端。此外,管理节点还维护集群的查询状态(Query Status Manager)维护,查询状态管理中在内存中临时保存有当前正在执行的全部查询,当客户端使用 show queries 命令的时候,将当前系统正在运行的查询信息返回客户端。

    -

    数据节点(Data Node)。数据节点保存了数据库中全部数据内容,并通过查询执行器、查询处理调度器、查询任务队列(Query Task Queue)进行查询处理的调度执行,从客户端接收到的查询处理请求都统一放置到处理队列中,查询执行器从队列中获得查询请求,并负责执行。通过查询优化器(Query Optimizer)对于查询进行基本的优化处理,以及通过数据节点的查询执行器(Query Executor)扫描符合条件的数据单元并返回计算结果。等接收客户端发出的查询请求,执行查询处理,并将结果返回。同时数据节点还需要响应来自管理节点的管理信息和命令,例如 kill query 命令以后,需要即刻停止执行的查询任务。

    -

    -
    图 1. 系统查询处理架构图(只包含查询相关组件)

    -

    普通查询处理

    -

    客户端、管理节点、数据节点协同完成TDengine的查询处理全流程。我们以一个具体的SQL查询为例,说明TDengine的查询处理流程。SQL语句向超级表FOO_SUPER_TABLE查询获取时间范围在2019年1月12日整天,标签TAG_LOC是'beijing'的表所包含的所有记录总数,SQL语句如下:

    -
    SELECT COUNT(*) 
    -FROM FOO_SUPER_TABLE
    -WHERE TAG_LOC = 'beijing' AND TS >= '2019-01-12 00:00:00' AND TS < '2019-01-13 00:00:00'
    -

    首先,客户端调用TAOS SQL解析器对SQL语句进行解析及合法性检查,然后生成语法树,并从中提取查询的对象 — 超级表 FOO_SUPER_TABLE ,然后解析器向管理节点(Management Node)请求其相应的元数据信息,并将过滤信息(TAG_LOC='beijing')同时发送到管理节点。

    -

    管理节点接收元数据获取的请求,首先找到超级表 FOO_SUPER_TABLE 基础信息,然后应用查询条件来过滤通过该超级表创建的全部表,最后满足查询条件(TAG_LOC='beijing'),即 TAG_LOC 标签列是 'beijing' 的的通过其查询执行器将满足查询要求的对象(表或超级表)的元数据信息返回给客户端。

    -

    客户端获得了 FOO_SUPER_TABLE 的元数据信息后,查询执行器根据元数据中的数据分布,分别向保存有相应数据的节点发起查询请求,此时时间戳范围过滤条件(TS >= '2019-01-12 00:00:00' AND TS < '2019-01-13 00:00:00')需要同时发送给全部的数据节点。

    -

    数据节点接收到发自客户端的查询,转化为内部结构并进行优化以后将其放入任务执行队列,等待查询执行器执行。当查询结果获得以后,将查询结果返回客户端。数据节点执行查询的过程均相互独立,完全只依赖于自身的数据和内容进行计算。

    -

    当所有查询涉及的数据节点返回结果后,客户端将每个数据节点查询的结果集再次进行聚合(针对本案例,即将所有结果再次进行累加),累加的结果即为最后的查询结果。第二阶段聚合并不是所有的查询都需要。例如,针对数据的列选取操作,实际上是不需要第二阶段聚合。

    -

    REST查询处理

    -

    在 C/C++ 、Python接口、 JDBC 接口之外,TDengine 还提供基于 HTTP 协议的 REST 接口。不同于使用应用客户端开发程序进行的开发。当用户使用 REST 接口的时候,所有的查询处理过程都是在服务器端来完成,用户的应用服务不会参与数据库的计算过程,查询处理完成后结果通过 HTTP的 JSON 格式返回给用户。

    -

    -
    图 2. REST查询架构

    -

    当用户使用基于HTTP的REST查询接口,HTTP的请求首先与位于数据节点的HTTP连接器( Connector),建立连接,然后通过REST的签名机制,使用Token来确保请求的可靠性。对于数据节点,HTTP连接器接收到请求后,调用内嵌的客户端程序发起查询请求,内嵌客户端将解析通过HTTP连接器传递过来的SQL语句,解析该SQL语句并按需向管理节点请求元数据信息,然后向本机或集群中其他节点发送查询请求,最后按需聚合计算结果。HTTP连接器接收到请求SQL以后,后续的流程处理与采用应用客户端方式的查询处理完全一致。最后,还需要将查询的结果转换为JSON格式字符串,并通过HTTP 响应返回给客户端。

    -

    可以看到,在处理HTTP流程的整个过程中,用户应用不再参与到查询处理的过程中,只负责通过HTTP协议发送SQL请求并接收JSON格式的结果。同时还需要注意的是,每个数据节点均内嵌了一个HTTP连接器和客户端程序,因此请求集群中任何一个数据节点,该数据节点均能够通过HTTP协议返回用户的查询结果。

    -

    技术特征

    -

    由于TDengine采用数据和标签分离存储的模式,能够极大地降低标签数据存储的冗余度。标签数据直接关联到每个表,并采用全内存的结构进行管理和维护标签数据,全内存的结构提供快速的查询处理,千万级别规模的标签数据查询可以在毫秒级别返回。首先针对标签数据的过滤可以有效地降低第二阶段的查询涉及的数据规模。为有效地提升查询处理的性能,针对物联网数据的不可更改的特点,TDengine采用在每个保存的数据块上,都记录下该数据块中数据的最大值、最小值、和等统计数据。如果查询处理涉及整个数据块的全部数据,则直接使用预计算结果,不再读取数据块的内容。由于预计算模块的大小远小于磁盘上存储的具体数据的大小,对于磁盘IO为瓶颈的查询处理,使用预计算结果可以极大地减小读取IO,并加速查询处理的流程。

    -

    由于TDengine采用按列存储数据。当从磁盘中读取数据块进行计算的时候,按照查询列信息读取该列数据,并不需要读取其他不相关的数据,可以最小化读取数据。此外,由于采用列存储结构,数据节点针对数据的扫描采用该列数据块进行,可以充分利用CPU L2高速缓存,极大地加速数据扫描的速度。此外,对于某些查询,并不会等全部查询结果生成后再返回结果。例如,列选取查询,当第一批查询结果获得以后,数据节点直接将其返回客户端。同时,在查询处理过程中,系统在数据节点接收到查询请求以后马上返回客户端查询确认信息,并同时拉起查询处理过程,并等待查询执行完成后才返回给用户查询有响应。

    -

    TDengine集群设计

    -

    1:集群与主要逻辑单元

    -

    TDengine是基于硬件、软件系统不可靠、一定会有故障的假设进行设计的,是基于任何单台计算机都无足够能力处理海量数据的假设进行设计的。因此TDengine从研发的第一天起,就按照分布式高可靠架构进行设计,是完全去中心化的,是水平扩展的,这样任何单台或多台服务器宕机或软件错误都不影响系统的服务。通过节点虚拟化并辅以自动化负载均衡技术,TDengine能最大限度地利用异构集群中的计算和存储资源。而且只要数据副本数大于一,无论是硬软件的升级、还是IDC的迁移等都无需停止集群的服务,极大地保证系统的正常运行,并且降低了系统管理员和运维人员的工作量。

    -

    下面的示例图上有八个物理节点,每个物理节点被逻辑的划分为多个虚拟节点。下面对系统的基本概念进行介绍。

    -

    assets/nodes.png

    -

    物理节点(dnode):集群中的一物理服务器或云平台上的一虚拟机。为安全以及通讯效率,一个物理节点可配置两张网卡,或两个IP地址。其中一张网卡用于集群内部通讯,其IP地址为privateIp, 另外一张网卡用于与集群外部应用的通讯,其IP地址为publicIp。在一些云平台(如阿里云),对外的IP地址是映射过来的,因此publicIp还有一个对应的内部IP地址internalIp(与privateIp不同)。对于只有一个IP地址的物理节点,publicIp, privateIp以及internalIp都是同一个地址,没有任何区别。一个dnode上有而且只有一个taosd实例运行。

    -

    虚拟数据节点(vnode):在物理节点之上的可独立运行的基础逻辑单元,时序数据写入、存储、查询等操作逻辑都在虚拟节点中进行(图中V),采集的时序数据就存储在vnode上。一个vnode包含固定数量的表。当创建一张新表时,系统会检查是否需要创建新的vnode。一个物理节点上能创建的vnode的数量取决于物理节点的硬件资源。一个vnode只属于一个DB,但一个DB可以有多个vnode。

    -

    虚拟数据节点组(vgroup): 位于不同物理节点的vnode可以组成一个虚拟数据节点组vnode group(如上图dnode0中的V0, dnode1中的V1, dnode6中的V2属于同一个虚拟节点组)。归属于同一个vgroup的虚拟节点采取master/slave的方式进行管理。写只能在master上进行,但采用asynchronous的方式将数据同步到slave,这样确保了一份数据在多个物理节点上有拷贝。如果master节点宕机,其他节点监测到后,将重新选举vgroup里的master, 新的master能继续处理数据请求,从而保证系统运行的可靠性。一个vgroup里虚拟节点个数就是数据的副本数。如果一个DB的副本数为N,系统必须有至少N个物理节点。副本数在创建DB时通过参数replica可以指定,缺省为1。使用TDengine, 数据的安全依靠多副本解决,因此不再需要昂贵的磁盘阵列等存储设备。

    -

    虚拟管理节点(mnode):负责所有节点运行状态的监控和维护,以及节点之间的负载均衡(图中M)。同时,虚拟管理节点也负责元数据(包括用户、数据库、表、静态标签等)的存储和管理,因此也称为Meta Node。TDengine集群中可配置多个(最多不超过5个) mnode,它们自动构建成为一个管理节点集群(图中M0, M1, M2)。mnode间采用master/slave的机制进行管理,而且采取强一致方式进行数据同步。mnode集群的创建由系统自动完成,无需人工干预。每个dnode上至多有一个mnode,而且每个dnode都知道整个集群中所有mnode的IP地址。

    -

    taosc:一个软件模块,是TDengine给应用提供的驱动程序(driver),内嵌于JDBC、ODBC driver中,或者C语言连接库里。应用都是通过taosc而不是直接来与整个集群进行交互的。这个模块负责获取并缓存元数据;将插入、查询等请求转发到正确的虚拟节点;在把结果返回给应用时,还需要负责最后一级的聚合、排序、过滤等操作。对于JDBC, ODBC, C/C++接口而言,这个模块是在应用所处的计算机上运行,但消耗的资源很小。为支持全分布式的REST接口,taosc在TDengine集群的每个dnode上都有一运行实例。

    -

    对外服务地址:TDengine集群可以容纳单台、多台甚至几千台物理节点。应用只需要向集群中任何一个物理节点的publicIp发起连接即可。启动CLI应用taos时,选项-h需要提供的就是publicIp。

    -

    master/secondIp:每一个dnode都需要配置一个masterIp。dnode启动后,将对配置的masterIp发起加入集群的连接请求。masterIp是已经创建的集群中的任何一个节点的privateIp,对于集群中的第一个节点,就是它自己的privateIp。为保证连接成功,每个dnode还可配置secondIp, 该IP地址也是已创建的集群中的任何一个节点的privateIp。如果一个节点连接masterIp失败,它将试图链接secondIp。

    -

    dnode启动后,会获知集群的mnode IP列表,并且定时向mnode发送状态信息。

    -

    vnode与mnode只是逻辑上的划分,都是执行程序taosd里的不同线程而已,无需安装不同的软件,做任何特殊的配置。最小的系统配置就是一个物理节点,vnode,mnode和taosc都存在而且都正常运行,但单一节点无法保证系统的高可靠。

    -

    2:一典型的操作流程

    -

    为解释vnode, mnode, taosc和应用之间的关系以及各自扮演的角色,下面对写入数据这个典型操作的流程进行剖析。

    -

    Picture1

    -
      -
    1. 应用通过JDBC、ODBC或其他API接口发起插入数据的请求。
    2. -
    3. taosc会检查缓存,看是有保存有该表的meta data。如果有,直接到第4步。如果没有,taosc将向mnode发出get meta-data请求。
    4. -
    5. mnode将该表的meta-data返回给taosc。Meta-data包含有该表的schema, 而且还有该表所属的vgroup信息(vnode ID以及所在的dnode的IP地址,如果副本数为N,就有N组vnodeID/IP)。如果taosc迟迟得不到mnode回应,而且存在多个mnode,taosc将向下一个mnode发出请求。
    6. -
    7. taosc向master vnode发起插入请求。
    8. -
    9. vnode插入数据后,给taosc一个应答,表示插入成功。如果taosc迟迟得不到vnode的回应,taosc会认为该节点已经离线。这种情况下,如果被插入的数据库有多个副本,taosc将向vgroup里下一个vnode发出插入请求。
    10. -
    11. taosc通知APP,写入成功。
    12. -
    -

    对于第二和第三步,taosc启动时,并不知道mnode的IP地址,因此会直接向配置的集群对外服务的IP地址发起请求。如果接收到该请求的dnode并没有配置mnode,该dnode会在回复的消息中告知mnode的IP地址列表(如果有多个dnodes,mnode的IP地址可以有多个),这样taosc会重新向新的mnode的IP地址发出获取meta-data的请求。

    -

    对于第四和第五步,没有缓存的情况下,taosc无法知道虚拟节点组里谁是master,就假设第一个vnodeID/IP就是master,向它发出请求。如果接收到请求的vnode并不是master,它会在回复中告知谁是master,这样taosc就向建议的master vnode发出请求。一旦得到插入成功的回复,taosc会缓存住master节点的信息。

    -

    上述是插入数据的流程,查询、计算的流程也完全一致。taosc把这些复杂的流程全部封装屏蔽了,因此应用无需处理重定向、获取meta data等细节,完全是透明的。

    -

    通过taosc缓存机制,只有在第一次对一张表操作时,才需要访问mnode, 因此mnode不会成为系统瓶颈。但因为schema有可能变化,而且vgroup有可能发生改变(比如负载均衡发生),因此taosc需要定时自动刷新缓存。

    -

    3:数据分区

    -

    vnode(虚拟数据节点)保存采集的时序数据,而且查询、计算都在这些节点上进行。为便于负载均衡、数据恢复、支持异构环境,TDengine将一个物理节点根据其计算和存储资源切分为多个vnode。这些vnode的管理是TDengine自动完成的,对应用完全透明。

    -

    对于单独一个数据采集点,无论其数据量多大,一个vnode(或vnode group, 如果副本数大于1)有足够的计算资源和存储资源来处理(如果每秒生成一条16字节的记录,一年产生的原始数据不到0.5G),因此TDengine将一张表的所有数据都存放在一个vnode里,而不会让同一个采集点的数据分布到两个或多个dnode上。而且一个vnode可存储多张表的数据,一个vnode可容纳的表的数目由配置参数tables指定,缺省为2000。设计上,一个vnode里所有的表都属于同一个DB。因此一个数据库DB需要的vnode或vgroup的个数等于:数据库表的数目/tables。

    -

    创建DB时,系统并不会马上分配资源。但当创建一张表时,系统将看是否有已经分配的vnode, 而且是否有空位,如果有,立即在该有空位的vnode创建表。如果没有,系统将从集群中,根据当前的负载情况,在一个dnode上创建一新的vnode, 然后创建表。如果DB有多个副本,系统不是只创建一个vnode,而是一个vgroup(虚拟数据节点组)。系统对vnode的数目没有任何限制,仅仅受限于物理节点本身的计算和存储资源。

    -

    参数tables的设置需要考虑具体场景,创建DB时,可以个性化指定该参数。该参数不宜过大,也不宜过小。过小,极端情况,就是每个数据采集点一个vnode, 这样导致系统数据文件过多。过大,虚拟化带来的优势就会丧失。给定集群计算资源的情况下,整个系统vnode的个数应该是CPU核的数目的两倍以上。

    -

    4:负载均衡

    -

    每个dnode(物理节点)都定时向 mnode(虚拟管理节点)报告其状态(包括硬盘空间、内存大小、CPU、网络、虚拟节点个数等),因此mnode了解整个集群的状态。基于整体状态,当mnode发现某个dnode负载过重,它会将dnode上的一个或多个vnode挪到其他dnode。在挪动过程中,对外服务继续进行,数据插入、查询和计算操作都不受影响。负载均衡操作结束后,应用也无需重启,将自动连接新的vnode。

    -

    如果mnode一段时间没有收到dnode的状态报告,mnode会认为这个dnode已经离线。如果离线时间超过一定时长(时长由配置参数offlineThreshold决定),该dnode将被mnode强制剔除出集群。该dnode上的vnodes如果副本数大于一,系统将自动在其他dnode上创建新的副本,以保证数据的副本数。

    -

    Note:目前集群功能仅仅限于企业版

    回去
    \ No newline at end of file diff --git a/2.0/documentation/tdenginedocs-cn/styles/base.css b/2.0/documentation/tdenginedocs-cn/styles/base.css deleted file mode 100644 index 564b587eb1..0000000000 --- a/2.0/documentation/tdenginedocs-cn/styles/base.css +++ /dev/null @@ -1,1112 +0,0 @@ -:root { - --b1:rgb(0,118,206);/*#0077bf*//*PANTONE 2174 C*/ - --b1t:rgba(0,118,206,0.15); - --b2:rgb(72,159,223);/*PANTONE 2171 C*//*OLD:#4193c5*/ - --sg-1:#b3b4b9; - --sg0:#585c66; - --sg1:rgb(51,56,68); - --sg2:#2F333E; - --sg3:#21242c; - --black: #212529; - --white: #fefefe; /*rgb(254,254,254)*/ - --white2:rgb(251, 251, 253); /*#fafbfc*/ - --white3:rgb(240,242,244); - --footer1:#fefefe; - --footer2:#333844; - --red:#ea4741; - --green:#72c156; - /*PRODUCT COLORS*/ - --p1:#72c156;/*#30D387;*/ - --p1t:rgba(114,193,86,0.15); - --p2:#43b3ae;/*rgb(70,161,168);/*#46a1a8*//*#D879D0;*/ - --p2t:rgba(70,161,168,0.15); - --p3:#4997d0;/*#30B7E8;*/ - --p3t:rgba(73,151,208,0.15); -} -/*@font-face{font-family:"Open Sans";src:url(fonts/Light/OpenSans-Light.woff2?v=1.101) format("woff2"),url(fonts/Light/OpenSans-Light.woff?v=1.101) format("woff");font-weight:300;font-style:normal}@font-face{font-family:"Open Sans";src:url(fonts/LightItalic/OpenSans-LightItalic.woff2?v=1.101) format("woff2"),url(fonts/LightItalic/OpenSans-LightItalic.woff?v=1.101) format("woff");font-weight:300;font-style:italic}@font-face{font-family:"Open Sans";src:url(fonts/Regular/OpenSans-Regular.woff2?v=1.101) format("woff2"),url(fonts/Regular/OpenSans-Regular.woff?v=1.101) format("woff");font-weight:400;font-style:normal}@font-face{font-family:"Open Sans";src:url(fonts/Italic/OpenSans-Italic.woff2?v=1.101) format("woff2"),url(fonts/Italic/OpenSans-Italic.woff?v=1.101) format("woff");font-weight:400;font-style:italic}@font-face{font-family:"Open Sans";src:url(fonts/SemiBold/OpenSans-SemiBold.woff2?v=1.101) format("woff2"),url(fonts/SemiBold/OpenSans-SemiBold.woff?v=1.101) format("woff");font-weight:600;font-style:normal}@font-face{font-family:"Open Sans";src:url(fonts/SemiBoldItalic/OpenSans-SemiBoldItalic.woff2?v=1.101) format("woff2"),url(fonts/SemiBoldItalic/OpenSans-SemiBoldItalic.woff?v=1.101) format("woff");font-weight:600;font-style:italic}@font-face{font-family:"Open Sans";src:url(fonts/Bold/OpenSans-Bold.woff2?v=1.101) format("woff2"),url(fonts/Bold/OpenSans-Bold.woff?v=1.101) format("woff");font-weight:700;font-style:normal}@font-face{font-family:"Open Sans";src:url(fonts/BoldItalic/OpenSans-BoldItalic.woff2?v=1.101) format("woff2"),url(fonts/BoldItalic/OpenSans-BoldItalic.woff?v=1.101) format("woff");font-weight:700;font-style:italic}@font-face{font-family:"Open Sans";src:url(fonts/ExtraBold/OpenSans-ExtraBold.woff2?v=1.101) format("woff2"),url(fonts/ExtraBold/OpenSans-ExtraBold.woff?v=1.101) format("woff");font-weight:800;font-style:normal}@font-face{font-family:"Open Sans";src:url(fonts/ExtraBoldItalic/OpenSans-ExtraBoldItalic.woff2?v=1.101) format("woff2"),url(fonts/ExtraBoldItalic/OpenSans-ExtraBoldItalic.woff?v=1.101) format("woff");font-weight:800;font-style:italic}*/ -html { - font-size:12pt; /*20px*/ - background-color: var(--white); -} -body, body * { - font-family: "Open Sans", Helvetica,'Hiragino Sans GB', sans-serif,"Apple Color Emoji"; - -webkit-font-smoothing:auto !important; - -moz-osx-font-smoothing:auto !important; - font-smooth: auto !important; - letter-spacing: normal; - line-height: 1.6; -} -body{ - -webkit-box-sizing: border-box; - box-sizing: border-box; - font-weight: 300; - color:var(--sg1); - font-family: "Open Sans", Helvetica, sans-serif !important; - background-color: var(--white); - -} -strong { - font-weight:600; -} -.anchor { - display: block; - position: relative; - z-index: -1; - top: -10px; -} -/* FORMS */ -input { - outline: none; - -webkit-box-shadow: inset 0px 0px 0px 0px transparent; - box-shadow: inset 0px 0px 0px 0px transparent; -} -input[type='text'], input[type='submit'],textarea { - -webkit-appearance: none; -} -input[l]{ - font-size:inherit; - outline: none; - - color:var(--sg1); - padding-left: 0.4em; - width:-webkit-calc(100%); - width:calc(100%); - border:solid 1px; - display: inline-block; - border-left:1px solid; - -webkit-border-radius:4px; - border-radius:4px; - -webkit-transition: border-left 0.2s; - -o-transition: border-left 0.2s; - transition: border-left 0.2s; - vertical-align: top; - font-weight:400; - border-color:inherit; - margin-bottom: 0.5rem; -} -input[l]:focus { - border-left:1rem solid; -} -input[l]:focus { - width:-webkit-calc(auto); - width:calc(auto); -} -input[plain]:valid { - border-color: var(--b1); -} -input[plain]:focus:valid { - border-color: var(--b1); -} -textarea { - -webkit-box-shadow: inset 0px 0px 0px 0px transparent; - box-shadow: inset 0px 0px 0px 0px transparent; -} -textarea[l] { - font-size:inherit; - outline: none; - - color:var(--sg1); - padding-left: 0.4em; - width:-webkit-calc(100%); - width:calc(100%); - border:solid 1px; - display: inline-block; - border-left:1px solid; - -webkit-border-radius:4px; - border-radius:4px; - -webkit-transition: border-left 0.2s; - -o-transition: border-left 0.2s; - transition: border-left 0.2s; - vertical-align: top; - font-weight:400; - border-color:inherit; - margin-bottom: 0.5rem; -} - -/*Other Text*/ -ul { - padding-left:30px; -} -p, li { - font-size:1em; - -} -p { - margin-bottom: 0.5rem; -} -/*Headers*/ -h1 { - font-size: 2.5rem; - line-height: 1.8; -} -h2 { - font-size: 1.7rem; - line-height: 1.8; -} -h3 { - font-size: 1.4rem; - line-height: 1.43; -} -h4 { - font-size: 1.25rem; -} -h5 { - font-size: 1rem; -} -h6 { - font-size: 1rem; - color: #777; -} -h1[b]::before,h2[b]::before, h3[b]::before { - content:""; - height:1em;; - display: block; - width:3px; - margin-left: -0.5em; - margin-top: 0.45em; - position: absolute; - background-color: var(--b1); -} -h1[b],h2[b], h3[b] { - padding-left: 0.5em -} -/* Navigation Bar */ -.logo { - height: 2.5rem; -} -a { - font-size:1em; -} -a:hover { - text-decoration: none; -} -a[l] { - color:var(--b2); - padding-bottom: 2px; - position: relative; - font-style: normal; - cursor: pointer; -} -a[l]:hover,a[l]:focus { - text-decoration: none; -} -a[l]::before { - content: ""; - left: 0; - background-color: var(--b2); - width: 0%; - height: 1px; - top:-webkit-calc(1em + 8px); - top:calc(1em + 8px); - position: absolute; - z-index: 2; - -webkit-transition: background-color 0.2s, height 0.2s, top 0.2s, width 0.2s; - -o-transition: background-color 0.2s, height 0.2s, top 0.2s, width 0.2s; - transition: background-color 0.2s, height 0.2s, top 0.2s, width 0.2s;; -} -a[l]:hover::before, a[l]:focus::before { - content: ""; - left: 0; - background-color: var(--b2); - width: 100%; - height: 1px; - top:-webkit-calc(1em + 8px); - top:calc(1em + 8px); - position: absolute; - z-index: 2; - -webkit-transition: background-color 0.2s, height 0.2s, top 0.2s, width 0.2s; - -o-transition: background-color 0.2s, height 0.2s, top 0.2s, width 0.2s; - transition: background-color 0.2s, height 0.2s, top 0.2s, width 0.2s; - text-decoration: none; -} -.navbar-brand { - margin-left: 10%; - padding-left: 15px; - color:var(--white) !important; -} -.navbar-nav { - top:0px; -} -.navbar { - background-color:var(--sg1); - z-index:10000; - padding-left: 0px; - padding-right: 0px; - padding-top:0.75rem; - padding-bottom: 0.75rem; -} -.navbar-toggler { - margin-right: -webkit-calc(2rem + 15px); - margin-right: calc(2rem + 15px); -} -.nav-link { - color:var(--white) !important; - line-height: 3.65rem; -} -.nav-item { - height:4.65rem; - font-size:1.1rem; - padding-left: 0.15rem; - padding-right: 0.15rem; - -webkit-transition: all 0.2s; - -o-transition: all 0.2s; - transition: all 0.2s; - border-bottom: 0rem solid var(--white); -} -.nav-item:hover { - border-bottom: 0.45rem solid var(--white); -} -.dropdown-menu { - top:4.1rem; - z-index:1000; - border-top:none; - border:none; - min-width: 120px; - margin-left:-1px; - -webkit-border-top-left-radius: 0; - border-top-left-radius: 0; - -webkit-border-top-right-radius: 0; - border-top-right-radius: 0; - -webkit-border-bottom-left-radius:0.25rem; - border-bottom-left-radius:0.25rem; - -webkit-border-bottom-right-radius:0.25rem; - border-bottom-right-radius:0.25rem; -} -.dropdown-menu.show { - -webkit-box-shadow: 0 4px 24px rgba(100, 109, 146, 0.15); - box-shadow: 0 4px 24px rgba(100, 109, 146, 0.15); -} -.dropdown-item { - color:var(--sg1); - background-color: var(--white); - -webkit-transition:all 0.2s; - -o-transition:all 0.2s; - transition:all 0.2s; - cursor:pointer; -} -.dropdown-item:hover, .dropdown-item:active { - background-color:var(--sg1); - color:var(--white) !important; -} -.dropdown-toggle::after { - display:none; -} -.dropdown a::after { - -webkit-transform: rotate(-90deg); - -ms-transform: rotate(-90deg); - transform: rotate(-90deg); - -webkit-transition: -webkit-transform 0.2s; - transition: -webkit-transform 0.2s; - -o-transition: transform 0.2s; - transition: transform 0.2s; - transition: transform 0.2s, -webkit-transform 0.2s; -} -.dropdown.show a::after { - -webkit-transform: rotate(0deg); - -ms-transform: rotate(0deg); - transform: rotate(0deg); -} -.navbar-nav .active { - border-bottom: 0.45rem solid var(--white); -} -.navbar-nav { - position: absolute; - right:-webkit-calc(10% + 15px); - right:calc(10% + 15px); -} -#language-dropdown .dropdown-menu{ - width:50px; -} -/*FOOTER*/ -footer { - background-color: var(--footer2); - padding-top: 1rem; -} -.page-footer { - padding-bottom: 2rem; -} -.footer-content, .footer-legal, .footer-contact { - width:80%; - margin-left: 10%; - padding-top:1rem; - color:var(--footer1); - font-size:0.8em; -} -.footer-content a { - color:var(--footer1); -} -.footer-content a { - color:var(--footer1); -} -.links-list { - text-align: left; - list-style: none; - padding: 0px; -} -.content-wrapper > .links-list { - padding-left:15px; -} -.links-list-title h4 { - font-size:1.2em; - font-weight:400; -} -.legal-links { - position: absolute; - right:-webkit-calc(10% + 15px); - right:calc(10% + 15px); -} -.legal-links a { - color:var(--footer1); -} -.links-list li { - height:2em; -} -.links-list li a::before, .legal-links a::before { - background-color:var(--footer1); -} -.links-list li a:hover::before, .legal-links a:hover::before { - background-color:var(--footer1); -} -.links-list .divider { - border-bottom: 1px solid var(--footer1); - opacity: 0.15; - height:0px; - margin-bottom: 0.3em; -} -.footer-divider { - border-bottom: 1px solid var(--footer1); - width:-webkit-calc(80% - 30px); - width:calc(80% - 30px); - margin-left: -webkit-calc(10% + 15px); - margin-left: calc(10% + 15px); -} -#social-media-links li { - height:2rem; - line-height:2rem; - display: inline-block; - font-size:1em; -} - -#social-media-links li:last-child::after { - content:""; -} -#social-media-links li::after { - content:" | "; -} -#social-media-links svg { - margin-left:2px;margin-right: 0.4rem; - width:20px; -} -#social-media-links svg path { - fill:var(--footer1); -} -#social-media-links li a::before { - left:1.9rem; - background-color:var(--footer1); -} -#social-media-links li a:hover::before, #social-media-links li a:focus::before { - left:1.9rem; - width: -webkit-calc(100% - 1.9rem); - width: calc(100% - 1.9rem); - background-color:var(--footer1); -} -#social-media-links ion-icon { - font-size:20px; - margin-right: 0.5rem; -} -#social-media-links svg { - font-size:20px; - margin-right: 0.5rem; -} -#email-subscribe-form { - width:-webkit-calc(100% - 160px); - width:calc(100% - 160px); -} -#email-subscribe-form input{ - width:-webkit-calc(100% - 4rem); - width:calc(100% - 4rem); - font-size:1.2em; - outline: none; - height:1.8em; - color:var(--sg1); - padding-left: 0.6em; - border:none; - display: inline-block; - border-left:0px solid var(--b1); - -webkit-border-radius:4px; - border-radius:4px; - -webkit-transition: border-left 0.2s; - -o-transition: border-left 0.2s; - transition: border-left 0.2s; - vertical-align: top; - font-weight:400; -} -#email-subscribe-form input:focus { - border-left:1rem solid var(--b1); - padding-top:2px; -} -#email-subscribe-form input:invalid, #email-subscribe-form input:invalid:focus { - border-color:var(--b1); -} -#email-subscribe-form input.invalid-input, #email-subscribe-form input.invalid-input:focus { - border-color:var(--red); -} -#email-subscribe-form input:valid, #email-subscribe-form input:valid:focus { - border-color:var(--green); -} -#email-subscribe-form button { - font-size:1.2em; - height:1.8em; - line-height: 1em; - float:right; - width:3rem; - padding:0; -} -form { - border-color:var(--b1); -} -form input:invalid, form input:invalid:focus { - border-color:inherit; -} -form input.invalid-input, form input.invalid-input:focus, form textarea.invalid-input, form textarea.invalid-input:focus { - border-color:var(--red); -} -form input:valid, form input:valid:focus { - border-color:var(--green); -} - -.sub-arrow { - width:1.2em; - fill:var(--b1); -} - - -@media only screen and (max-width:991px){ - .page-footer { - padding-left:20px; - padding-right:20px; - } - .footer-legal { - width:100%; - } - #legal-1 { - padding-left: 20px; - } - .legal-links { - right:20px; - } - .footer-content .col-xl-8, .footer-content .col-xl-4{ - padding-left:20px; - padding-right:20px; - } - .footer-content { - width:-webkit-calc(100% + 40px); - width:calc(100% + 40px); - } - .footer-divider { - width:100%; - margin-left: 0; - } -} - -/*SECTIONS AND CONTENT*/ -.content-wrapper { - width: 80%; - margin-left: 10%; - margin-top: 6rem; - margin-bottom: 3rem; - min-height: -webkit-calc(100vh - 187.7px - 74.45px); - min-height: calc(100vh - 187.7px - 74.45px); -} -.section { - /* border-bottom:2px solid rgba(0,0,0,0.2);*/ -} -.section-item { - -} -.section-title, -.section-item-title { - color:var(--b1); - -} -.container-fluid { - background-color: var(--white); -} -.center { - left:50%; - position: relative; -} -/*BUTTONS*/ -.btn-primary { - color:var(--b1); - background-color: var(--white); - border-color:var(--b1); - -webkit-box-shadow:0px 0px 0px 0px rgba(255,255,255,0.55); - box-shadow:0px 0px 0px 0px rgba(255,255,255,0.55); - -webkit-transition: all 0.2s; - -o-transition: all 0.2s; - transition: all 0.2s; -} -.btn-primary:hover,.btn-primary:focus { - color:var(--b1); - background-color: var(--white); - border-color:var(--b1); - -webkit-box-shadow:4px 4px 0px 0px var(--b1t); - box-shadow:4px 4px 0px 0px var(--b1t); - -webkit-transform: translate(-2px,-2px); - -ms-transform: translate(-2px,-2px); - transform: translate(-2px,-2px); -} -.btn-primary:active { - color:var(--b1) !important; - background-color: var(--white) !important; - border-color:var(--b1) !important; - -webkit-box-shadow:2px 2px 0px 0px var(--b1t); - box-shadow:2px 2px 0px 0px var(--b1t); - -webkit-transform: translate(-1px,-1px); - -ms-transform: translate(-1px,-1px); - transform: translate(-1px,-1px); -} -.btn-white { - color:var(--b1); - background-color: var(--white); - -webkit-transition: all 0.2s; - -o-transition: all 0.2s; - transition: all 0.2s; - -webkit-box-shadow:0px 0px 0px 0px rgba(255,255,255,0.55); - box-shadow:0px 0px 0px 0px rgba(255,255,255,0.55); -} -.btn-white:hover,.btn-white:focus { - color:var(--b1); - background-color: var(--white); - -webkit-box-shadow:4px 4px 0px 0px rgba(255,255,255,0.55); - box-shadow:4px 4px 0px 0px rgba(255,255,255,0.55); - -webkit-transform: translate(-2px,-2px); - -ms-transform: translate(-2px,-2px); - transform: translate(-2px,-2px); -} -.btn-white:active { - color:var(--b1) !important; - background-color: var(--white) !important; - -webkit-box-shadow:2px 2px 0px 0px rgba(255,255,255,0.55); - box-shadow:2px 2px 0px 0px rgba(255,255,255,0.55); - -webkit-transform: translate(-1px,-1px); - -ms-transform: translate(-1px,-1px); - transform: translate(-1px,-1px); -} -.btn-filled { - color:var(--white) !important; - background-color: var(--b1); - border-color:var(--b1); - -webkit-box-shadow:0px 0px 0px 0px rgba(255,255,255,0.55); - box-shadow:0px 0px 0px 0px rgba(255,255,255,0.55); - -webkit-transition: all 0.2s; - -o-transition: all 0.2s; - transition: all 0.2s; -} -.btn-filled:hover { - color:var(--white) !important;; - background-color: var(--b1); - border-color:var(--b1); - -webkit-box-shadow:4px 4px 0px 0px var(--b1t); - box-shadow:4px 4px 0px 0px var(--b1t); - -webkit-transform: translate(-2px,-2px); - -ms-transform: translate(-2px,-2px); - transform: translate(-2px,-2px); -} -.btn-filled:active { - color:var(--white) !important; - background-color: var(--b1) !important; - border-color:var(--b1) !important; - -webkit-box-shadow:2px 2px 0px 0px var(--b1t); - box-shadow:2px 2px 0px 0px var(--b1t); - -webkit-transform: translate(-1px,-1px); - -ms-transform: translate(-1px,-1px); - transform: translate(-1px,-1px); -} -/*Popup*/ -#popup-wrapper { - display: block; - position: absolute; - z-index:1000; - -webkit-transition:opacity 0.5s; - -o-transition:opacity 0.5s; - transition:opacity 0.5s; - opacity: 1; -} -#popup-page-cover { - display:none; - position: fixed; - height: 100vh; - width:100vw; - top:0;left:0; - background-color: rgba(131, 145, 174, 0.32); - z-index:1000; - -webkit-transition:opacity 0.5s; - -o-transition:opacity 0.5s; - transition:opacity 0.5s; - opacity:0; -} -#popup { - position: fixed; - display: none; - height:auto; - width:100px; - z-index: 1001; - max-width: -webkit-calc(100% - 30px); - max-width: calc(100% - 30px); - background-color: var(--white); - left:50%; - -webkit-transform:translate(-50%,-50%); - -ms-transform:translate(-50%,-50%); - transform:translate(-50%,-50%); - top:50%; - -webkit-transition:opacity 0.5s; - -o-transition:opacity 0.5s; - transition:opacity 0.5s; - opacity:0; - -webkit-border-radius:0.25rem; - border-radius:0.25rem; - -webkit-box-shadow: 0 12px 48px 0 rgba(0, 0, 0, 0.24); - box-shadow: 0 12px 48px 0 rgba(0, 0, 0, 0.24) -} -#close-popup { - position: absolute;right:1rem; - z-index: 1; - cursor: pointer; - top:0; -} -#close-popup svg { - margin-top:4px; -} -#close-popup::before { - content:""; - width:0px; - display: block; - position: absolute; - top:50%; - left:50%; - height:0px; - background-color:rgba(0,0,0,0.15); - -webkit-border-radius:50%; - border-radius:50%; - z-index:-1; - cursor: pointer; - -webkit-transition:all 0.2s; - -o-transition:all 0.2s; - transition:all 0.2s; -} -#close-popup:hover::before { - content:""; - width:32px;; - display: block; - position: absolute; - top:10px; - left:0px; - height:32px; - background-color:rgba(0,0,0,0.15); - -webkit-border-radius:50%; - border-radius:50%; -z-index:-1; -} -#popup-title { - padding-left: 1rem; - background-color:var(--b1); - color:var(--white); - font-weight:400; - font-size:1.6em; - width:100%; - display:block; - -webkit-border-radius:0.25rem 0.25rem 0 0; - border-radius:0.25rem 0.25rem 0 0; - padding-right:60px; - position: relative; -} -#popup-title-text { - line-height: 1.2; - display: inline-block; - padding-top: 9px; -} -#popup-content { - padding:1rem; - display: block; -} -#popup-title path { - fill:var(--white); -} -/*Banners*/ -.banner-content { - padding-right:32px; -} -.banner-wrapper { - width:100vw; - position: fixed; - top:4.3rem; - left:0; - z-index: 1000; -} -.banner { - background-color: var(--b1); - width:-webkit-calc(100% - 20px); - width:calc(100% - 20px); - margin: auto; - -webkit-border-radius:0.25rem; - border-radius:0.25rem; - padding:0.5rem; - color:var(--white); - font-size:1.6em; - margin-top: 1rem; - -webkit-box-shadow:0 4px 12px 0 rgba(0, 0, 0, 0.24); - box-shadow:0 4px 12px 0 rgba(0, 0, 0, 0.24); - opacity: 1; - -webkit-animation: bannerOpaque 0.2s; - animation: bannerOpaque 0.2s; -} -@-webkit-keyframes bannerOpaque { - from { - opacity:0 - } - to { - opacity:1; - } -} -@keyframes bannerOpaque { - from { - opacity:0 - } - to { - opacity:1; - } -} -.close-banner { - position: absolute;right:1rem; - z-index: 1; - cursor: pointer; - -webkit-transform: translate(0,-3px); - -ms-transform: translate(0,-3px); - transform: translate(0,-3px); -} -.close-banner::before { - content:""; - width:0px; - display: block; - position: absolute; - margin-top:26px; - left:50%; - height:0px; - background-color:rgba(0,0,0,0.15); - -webkit-border-radius:50%; - border-radius:50%; - z-index:-1; - cursor: pointer; - -webkit-transition:all 0.2s; - -o-transition:all 0.2s; - transition:all 0.2s; -} -.close-banner:hover::before { - content:""; - width:32px; - margin-top: 7px; - display: block; - position: absolute; - left:0px; - height:32px; - background-color:rgba(0,0,0,0.15); - -webkit-border-radius:50%; - border-radius:50%; -z-index:-1; -} -@media only screen and (max-width:991px) { - .banner { - font-size:1.2rem; - } -} -/*OTHER*/ -#globe-svg { - height:60px; - fill:#fefefe -} -#page-cover { - width:100vw; - top:-100vh; - left:0px; - -webkit-transition-delay: 0.3s; - -o-transition-delay: 0.3s; - transition-delay: 0.3s; - -webkit-transition:all 0.7s; - -o-transition:all 0.7s; - transition:all 0.7s; - height:100vh; - position: fixed; - z-index:1000; - background-color: rgba(54, 61, 75, 0.25); -} -#menu-button { - border:none; - outline:none; -} -#menu-bar { - -webkit-transition: all 0.15s; - -o-transition: all 0.15s; - transition: all 0.15s; -} -#close-bar { - -webkit-transition: all 0.15s; - -o-transition: all 0.15s; - transition: all 0.15s; - display: none; -} -#rect1 { - -webkit-transition: all 0.2s; - -o-transition: all 0.2s; - transition: all 0.2s; -} -#rect2 { --webkit-transition: all 0.2s; --o-transition: all 0.2s; -transition: all 0.2s; -} -#rect3 { --webkit-transition: all 0.2s; --o-transition: all 0.2s; -transition: all 0.2s; -} -@media only screen and (max-width: 991px) { - - .content-wrapper { - width:-webkit-calc(100%); - width:calc(100%); - left:0; - padding-left: 0; - margin-left:0; - margin-top:4.7rem; - } - .container-fluid { - padding-left:20px; - padding-right:20px; - } - .row { - margin-left:-20px; - margin-right:-20px; - } - #menu-button { - margin-right:20px; - padding:0px; - } - .navbar-brand { - margin-left: 20px; - padding-left: 0px; - } -} -.bot-logo { - margin-bottom:0.5rem; -} -@media only screen and (min-width:1200px){ - #page-cover { - display: none - } - .bot-logo { - margin-left:15px; - } -} -@media only screen and (max-width: 1199px) { - #globe-svg { - height:60px; - fill:var(--sg1); - } - .navbar-collapse.show { - -webkit-box-shadow:0px 10px 24px rgba(0,0,0,0.15) ; - box-shadow:0px 10px 24px rgba(0,0,0,0.15) ; - } - .nav-item:first-child { - border-top: 1px solid rgba(255,255,255,0.35); - } - #menu-button { - margin-right: -webkit-calc(10% + 15px); - margin-right: calc(10% + 15px); - padding:0; - } - #menu-button:hover { - background-color: transparent; - } - .nav-item { - height:auto; - border-bottom: 1px solid rgba(0,0,0,0.35); - padding-left: -webkit-calc(10% + 15px); - padding-left: calc(10% + 15px); - } - .nav-link{ - line-height: 3rem; - padding: 0px; - - } - .nav-link{ - color:var(--sg1) !important; - } - .nav-item:hover { - border-bottom: 1px solid rgba(0,0,0,0.35); - - } - .navbar-nav { - background-color: var(--white2); - margin-top: 15px; - } - .navbar-nav .active { - border-bottom: 1px solid rgba(0,0,0,0.35); - } - .nav-item:nth-child(even) { - /* - background-color:rgba(0,0,0,0.05); - padding-left: 1rem; - margin-left: -1rem; - */ - } - #navbarSupportedContent { - - } - #language-dropdown .dropdown-menu{ - width: -webkit-calc(80% + 4rem); - width: calc(80% + 4rem); - background-color: var(--white); - - } - .dropdown-menu { - border:none; - margin-top: -20px; - } - .nav-item:last-child { - border-bottom:none; - } - .dropdown-menu.show { - -webkit-box-shadow: 0 4px 24px rgba(100, 109, 146, 0.15); - box-shadow: 0 4px 24px rgba(100, 109, 146, 0.15); - margin-bottom:1rem; - margin-top:-0.5rem; - } - .dropdown-item { - padding-left: 15px; - font-weight:300; - } - .navbar-nav { - position: relative; - right:0rem; - } - .long-form input { - width:100%; - } -} -@media only screen and (max-width: 991px) { - .nav-item { - padding-left: 20px; - padding-right: 20px; - } - #language-dropdown{ - padding-left:20px; - } - #language-dropdown .dropdown-menu { - width:100%; - } - #menu-button { - margin-right: 20px; - padding:0; - } - .navbar { - padding-top: 0.25rem; - padding-bottom:0.25rem; - } - .logo { - height:1.8rem; - } - .anchor { - top: -55px; - } -} -@media only screen and (max-width:556px) { - #legal-1 { - width:100%; - } - .legal-links { - position: inherit; - margin-left: 20px; - margin-bottom: 1em; - } -} -@media only screen and (max-width:375px) { - #legal-1 p { - display: block; - } -} - -/*Footer media queries*/ -@media only screen and (max-width:830px) { -} -@media only screen and (max-width:650px) { -} -@media only screen and (max-width:352px) { -} - -.lds-ring { - display: inline-block; - position: relative; - width: 18px; - height: 18px; - padding-top:2px; -} -#email-subscribe-form .lds-ring { - padding-top:1px; -} -.lds-ring div { - -webkit-box-sizing: border-box; - box-sizing: border-box; - display: block; - position: absolute; - width: 18px; - height: 18px; - border: 2px solid var(--b2); - -webkit-border-radius: 50%; - border-radius: 50%; - -webkit-animation: lds-ring 1.2s cubic-bezier(0.5, 0, 0.5, 1) infinite; - animation: lds-ring 1.2s cubic-bezier(0.5, 0, 0.5, 1) infinite; - border-color: var(--b2) transparent transparent transparent; -} -.lds-ring div:nth-child(1) { - -webkit-animation-delay: -0.45s; - animation-delay: -0.45s; -} -.lds-ring div:nth-child(2) { - -webkit-animation-delay: -0.3s; - animation-delay: -0.3s; -} -.lds-ring div:nth-child(3) { - -webkit-animation-delay: -0.15s; - animation-delay: -0.15s; -} -@-webkit-keyframes lds-ring { - 0% { - -webkit-transform: rotate(0deg); - transform: rotate(0deg); - } - 100% { - -webkit-transform: rotate(360deg); - transform: rotate(360deg); - } -} -@keyframes lds-ring { - 0% { - -webkit-transform: rotate(0deg); - transform: rotate(0deg); - } - 100% { - -webkit-transform: rotate(360deg); - transform: rotate(360deg); - } -} -#email-subscribe-form .sub-arrow { - padding-top:2px; -} -.sub-arrow { - display: inline-block; -} -.sub-load { - display:none; -} diff --git a/2.0/documentation/tdenginedocs-cn/styles/base.min.css b/2.0/documentation/tdenginedocs-cn/styles/base.min.css deleted file mode 100644 index 7aa9427702..0000000000 --- a/2.0/documentation/tdenginedocs-cn/styles/base.min.css +++ /dev/null @@ -1 +0,0 @@ -:root{--b1:rgb(0,118,206);--b1t:rgba(0,118,206,0.15);--b2:rgb(72,159,223);--sg-1:#b3b4b9;--sg0:#585c66;--sg1:rgb(51,56,68);--sg2:#2F333E;--sg3:#21242c;--black:#212529;--white:#fefefe;--white2:rgb(251, 251, 253);--white3:rgb(240,242,244);--footer1:#fefefe;--footer2:#333844;--red:#ea4741;--green:#72c156;--p1:#72c156;--p1t:rgba(114,193,86,0.15);--p2:#43b3ae;--p2t:rgba(70,161,168,0.15);--p3:#4997d0;--p3t:rgba(73,151,208,0.15)}html{font-size:12pt;background-color:var(--white)}body,body *{font-family:"Open Sans",Helvetica,'Hiragino Sans GB',sans-serif,"Apple Color Emoji";-webkit-font-smoothing:auto!important;-moz-osx-font-smoothing:auto!important;font-smooth:auto!important;letter-spacing:normal;line-height:1.6}body{-webkit-box-sizing:border-box;box-sizing:border-box;font-weight:300;color:var(--sg1);font-family:"Open Sans",Helvetica,sans-serif!important;background-color:var(--white)}strong{font-weight:600}.anchor{display:block;position:relative;z-index:-1;top:-10px}input{outline:0;-webkit-box-shadow:inset 0 0 0 0 transparent;box-shadow:inset 0 0 0 0 transparent}input[type=submit],input[type=text],textarea{-webkit-appearance:none}input[l]{font-size:inherit;outline:0;color:var(--sg1);padding-left:.4em;width:-webkit-calc(100%);width:calc(100%);border:solid 1px;display:inline-block;border-left:1px solid;-webkit-border-radius:4px;border-radius:4px;-webkit-transition:border-left .2s;-o-transition:border-left .2s;transition:border-left .2s;vertical-align:top;font-weight:400;border-color:inherit;margin-bottom:.5rem}input[l]:focus{border-left:1rem solid}input[l]:focus{width:-webkit-calc(auto);width:calc(auto)}input[plain]:valid{border-color:var(--b1)}input[plain]:focus:valid{border-color:var(--b1)}textarea{-webkit-box-shadow:inset 0 0 0 0 transparent;box-shadow:inset 0 0 0 0 transparent}textarea[l]{font-size:inherit;outline:0;color:var(--sg1);padding-left:.4em;width:-webkit-calc(100%);width:calc(100%);border:solid 1px;display:inline-block;border-left:1px solid;-webkit-border-radius:4px;border-radius:4px;-webkit-transition:border-left .2s;-o-transition:border-left .2s;transition:border-left .2s;vertical-align:top;font-weight:400;border-color:inherit;margin-bottom:.5rem}ul{padding-left:30px}li,p{font-size:1em}p{margin-bottom:.5rem}h1{font-size:2.5rem;line-height:1.8}h2{font-size:1.7rem;line-height:1.8}h3{font-size:1.4rem;line-height:1.43}h4{font-size:1.25rem}h5{font-size:1rem}h6{font-size:1rem;color:#777}h1[b]::before,h2[b]::before,h3[b]::before{content:"";height:1em;display:block;width:3px;margin-left:-.5em;margin-top:.45em;position:absolute;background-color:var(--b1)}h1[b],h2[b],h3[b]{padding-left:.5em}.logo{height:2.5rem}a{font-size:1em}a:hover{text-decoration:none}a[l]{color:var(--b2);padding-bottom:2px;position:relative;font-style:normal;cursor:pointer}a[l]:focus,a[l]:hover{text-decoration:none}a[l]::before{content:"";left:0;background-color:var(--b2);width:0%;height:1px;top:-webkit-calc(1em + 8px);top:calc(1em + 8px);position:absolute;z-index:2;-webkit-transition:background-color .2s,height .2s,top .2s,width .2s;-o-transition:background-color .2s,height .2s,top .2s,width .2s;transition:background-color .2s,height .2s,top .2s,width .2s}a[l]:focus::before,a[l]:hover::before{content:"";left:0;background-color:var(--b2);width:100%;height:1px;top:-webkit-calc(1em + 8px);top:calc(1em + 8px);position:absolute;z-index:2;-webkit-transition:background-color .2s,height .2s,top .2s,width .2s;-o-transition:background-color .2s,height .2s,top .2s,width .2s;transition:background-color .2s,height .2s,top .2s,width .2s;text-decoration:none}.navbar-brand{margin-left:10%;padding-left:15px;color:var(--white)!important}.navbar-nav{top:0}.navbar{background-color:var(--sg1);z-index:10000;padding-left:0;padding-right:0;padding-top:.75rem;padding-bottom:.75rem}.navbar-toggler{margin-right:-webkit-calc(2rem + 15px);margin-right:calc(2rem + 15px)}.nav-link{color:var(--white)!important;line-height:3.65rem}.nav-item{height:4.65rem;font-size:1.1rem;padding-left:.15rem;padding-right:.15rem;-webkit-transition:all .2s;-o-transition:all .2s;transition:all .2s;border-bottom:0 solid var(--white)}.nav-item:hover{border-bottom:.45rem solid var(--white)}.dropdown-menu{top:4.1rem;z-index:1000;border-top:none;border:none;min-width:120px;margin-left:-1px;-webkit-border-top-left-radius:0;border-top-left-radius:0;-webkit-border-top-right-radius:0;border-top-right-radius:0;-webkit-border-bottom-left-radius:.25rem;border-bottom-left-radius:.25rem;-webkit-border-bottom-right-radius:.25rem;border-bottom-right-radius:.25rem}.dropdown-menu.show{-webkit-box-shadow:0 4px 24px rgba(100,109,146,.15);box-shadow:0 4px 24px rgba(100,109,146,.15)}.dropdown-item{color:var(--sg1);background-color:var(--white);-webkit-transition:all .2s;-o-transition:all .2s;transition:all .2s;cursor:pointer}.dropdown-item:active,.dropdown-item:hover{background-color:var(--sg1);color:var(--white)!important}.dropdown-toggle::after{display:none}.dropdown a::after{-webkit-transform:rotate(-90deg);-ms-transform:rotate(-90deg);transform:rotate(-90deg);-webkit-transition:-webkit-transform .2s;transition:-webkit-transform .2s;-o-transition:transform .2s;transition:transform .2s;transition:transform .2s,-webkit-transform .2s}.dropdown.show a::after{-webkit-transform:rotate(0);-ms-transform:rotate(0);transform:rotate(0)}.navbar-nav .active{border-bottom:.45rem solid var(--white)}.navbar-nav{position:absolute;right:-webkit-calc(10% + 15px);right:calc(10% + 15px)}#language-dropdown .dropdown-menu{width:50px}footer{background-color:var(--footer2);padding-top:1rem}.page-footer{padding-bottom:2rem}.footer-contact,.footer-content,.footer-legal{width:80%;margin-left:10%;padding-top:1rem;color:var(--footer1);font-size:.8em}.footer-content a{color:var(--footer1)}.footer-content a{color:var(--footer1)}.links-list{text-align:left;list-style:none;padding:0}.content-wrapper>.links-list{padding-left:15px}.links-list-title h4{font-size:1.2em;font-weight:400}.legal-links{position:absolute;right:-webkit-calc(10% + 15px);right:calc(10% + 15px)}.legal-links a{color:var(--footer1)}.links-list li{height:2em}.legal-links a::before,.links-list li a::before{background-color:var(--footer1)}.legal-links a:hover::before,.links-list li a:hover::before{background-color:var(--footer1)}.links-list .divider{border-bottom:1px solid var(--footer1);opacity:.15;height:0;margin-bottom:.3em}.footer-divider{border-bottom:1px solid var(--footer1);width:-webkit-calc(80% - 30px);width:calc(80% - 30px);margin-left:-webkit-calc(10% + 15px);margin-left:calc(10% + 15px)}#social-media-links li{height:2rem;line-height:2rem;display:inline-block;font-size:1em}#social-media-links li:last-child::after{content:""}#social-media-links li::after{content:" | "}#social-media-links svg{margin-left:2px;margin-right:.4rem;width:20px}#social-media-links svg path{fill:var(--footer1)}#social-media-links li a::before{left:1.9rem;background-color:var(--footer1)}#social-media-links li a:focus::before,#social-media-links li a:hover::before{left:1.9rem;width:-webkit-calc(100% - 1.9rem);width:calc(100% - 1.9rem);background-color:var(--footer1)}#social-media-links ion-icon{font-size:20px;margin-right:.5rem}#social-media-links svg{font-size:20px;margin-right:.5rem}#email-subscribe-form{width:-webkit-calc(100% - 160px);width:calc(100% - 160px)}#email-subscribe-form input{width:-webkit-calc(100% - 4rem);width:calc(100% - 4rem);font-size:1.2em;outline:0;height:1.8em;color:var(--sg1);padding-left:.6em;border:none;display:inline-block;border-left:0 solid var(--b1);-webkit-border-radius:4px;border-radius:4px;-webkit-transition:border-left .2s;-o-transition:border-left .2s;transition:border-left .2s;vertical-align:top;font-weight:400}#email-subscribe-form input:focus{border-left:1rem solid var(--b1);padding-top:2px}#email-subscribe-form input:invalid,#email-subscribe-form input:invalid:focus{border-color:var(--b1)}#email-subscribe-form input.invalid-input,#email-subscribe-form input.invalid-input:focus{border-color:var(--red)}#email-subscribe-form input:valid,#email-subscribe-form input:valid:focus{border-color:var(--green)}#email-subscribe-form button{font-size:1.2em;height:1.8em;line-height:1em;float:right;width:3rem;padding:0}form{border-color:var(--b1)}form input:invalid,form input:invalid:focus{border-color:inherit}form input.invalid-input,form input.invalid-input:focus,form textarea.invalid-input,form textarea.invalid-input:focus{border-color:var(--red)}form input:valid,form input:valid:focus{border-color:var(--green)}.sub-arrow{width:1.2em;fill:var(--b1)}@media only screen and (max-width:991px){.page-footer{padding-left:20px;padding-right:20px}.footer-legal{width:100%}#legal-1{padding-left:20px}.legal-links{right:20px}.footer-content .col-xl-4,.footer-content .col-xl-8{padding-left:20px;padding-right:20px}.footer-content{width:-webkit-calc(100% + 40px);width:calc(100% + 40px)}.footer-divider{width:100%;margin-left:0}}.content-wrapper{width:80%;margin-left:10%;margin-top:6rem;margin-bottom:3rem;min-height:-webkit-calc(100vh - 187.7px - 74.45px);min-height:calc(100vh - 187.7px - 74.45px)}.section-item-title,.section-title{color:var(--b1)}.container-fluid{background-color:var(--white)}.center{left:50%;position:relative}.btn-primary{color:var(--b1);background-color:var(--white);border-color:var(--b1);-webkit-box-shadow:0 0 0 0 rgba(255,255,255,.55);box-shadow:0 0 0 0 rgba(255,255,255,.55);-webkit-transition:all .2s;-o-transition:all .2s;transition:all .2s}.btn-primary:focus,.btn-primary:hover{color:var(--b1);background-color:var(--white);border-color:var(--b1);-webkit-box-shadow:4px 4px 0 0 var(--b1t);box-shadow:4px 4px 0 0 var(--b1t);-webkit-transform:translate(-2px,-2px);-ms-transform:translate(-2px,-2px);transform:translate(-2px,-2px)}.btn-primary:active{color:var(--b1)!important;background-color:var(--white)!important;border-color:var(--b1)!important;-webkit-box-shadow:2px 2px 0 0 var(--b1t);box-shadow:2px 2px 0 0 var(--b1t);-webkit-transform:translate(-1px,-1px);-ms-transform:translate(-1px,-1px);transform:translate(-1px,-1px)}.btn-white{color:var(--b1);background-color:var(--white);-webkit-transition:all .2s;-o-transition:all .2s;transition:all .2s;-webkit-box-shadow:0 0 0 0 rgba(255,255,255,.55);box-shadow:0 0 0 0 rgba(255,255,255,.55)}.btn-white:focus,.btn-white:hover{color:var(--b1);background-color:var(--white);-webkit-box-shadow:4px 4px 0 0 rgba(255,255,255,.55);box-shadow:4px 4px 0 0 rgba(255,255,255,.55);-webkit-transform:translate(-2px,-2px);-ms-transform:translate(-2px,-2px);transform:translate(-2px,-2px)}.btn-white:active{color:var(--b1)!important;background-color:var(--white)!important;-webkit-box-shadow:2px 2px 0 0 rgba(255,255,255,.55);box-shadow:2px 2px 0 0 rgba(255,255,255,.55);-webkit-transform:translate(-1px,-1px);-ms-transform:translate(-1px,-1px);transform:translate(-1px,-1px)}.btn-filled{color:var(--white)!important;background-color:var(--b1);border-color:var(--b1);-webkit-box-shadow:0 0 0 0 rgba(255,255,255,.55);box-shadow:0 0 0 0 rgba(255,255,255,.55);-webkit-transition:all .2s;-o-transition:all .2s;transition:all .2s}.btn-filled:hover{color:var(--white)!important;background-color:var(--b1);border-color:var(--b1);-webkit-box-shadow:4px 4px 0 0 var(--b1t);box-shadow:4px 4px 0 0 var(--b1t);-webkit-transform:translate(-2px,-2px);-ms-transform:translate(-2px,-2px);transform:translate(-2px,-2px)}.btn-filled:active{color:var(--white)!important;background-color:var(--b1)!important;border-color:var(--b1)!important;-webkit-box-shadow:2px 2px 0 0 var(--b1t);box-shadow:2px 2px 0 0 var(--b1t);-webkit-transform:translate(-1px,-1px);-ms-transform:translate(-1px,-1px);transform:translate(-1px,-1px)}#popup-wrapper{display:block;position:absolute;z-index:1000;-webkit-transition:opacity .5s;-o-transition:opacity .5s;transition:opacity .5s;opacity:1}#popup-page-cover{display:none;position:fixed;height:100vh;width:100vw;top:0;left:0;background-color:rgba(131,145,174,.32);z-index:1000;-webkit-transition:opacity .5s;-o-transition:opacity .5s;transition:opacity .5s;opacity:0}#popup{position:fixed;display:none;height:auto;width:100px;z-index:1001;max-width:-webkit-calc(100% - 30px);max-width:calc(100% - 30px);background-color:var(--white);left:50%;-webkit-transform:translate(-50%,-50%);-ms-transform:translate(-50%,-50%);transform:translate(-50%,-50%);top:50%;-webkit-transition:opacity .5s;-o-transition:opacity .5s;transition:opacity .5s;opacity:0;-webkit-border-radius:.25rem;border-radius:.25rem;-webkit-box-shadow:0 12px 48px 0 rgba(0,0,0,.24);box-shadow:0 12px 48px 0 rgba(0,0,0,.24)}#close-popup{position:absolute;right:1rem;z-index:1;cursor:pointer;top:0}#close-popup svg{margin-top:4px}#close-popup::before{content:"";width:0;display:block;position:absolute;top:50%;left:50%;height:0;background-color:rgba(0,0,0,.15);-webkit-border-radius:50%;border-radius:50%;z-index:-1;cursor:pointer;-webkit-transition:all .2s;-o-transition:all .2s;transition:all .2s}#close-popup:hover::before{content:"";width:32px;display:block;position:absolute;top:10px;left:0;height:32px;background-color:rgba(0,0,0,.15);-webkit-border-radius:50%;border-radius:50%;z-index:-1}#popup-title{padding-left:1rem;background-color:var(--b1);color:var(--white);font-weight:400;font-size:1.6em;width:100%;display:block;-webkit-border-radius:.25rem .25rem 0 0;border-radius:.25rem .25rem 0 0;padding-right:60px;position:relative}#popup-title-text{line-height:1.2;display:inline-block;padding-top:9px}#popup-content{padding:1rem;display:block}#popup-title path{fill:var(--white)}.banner-content{padding-right:32px}.banner-wrapper{width:100vw;position:fixed;top:4.3rem;left:0;z-index:1000}.banner{background-color:var(--b1);width:-webkit-calc(100% - 20px);width:calc(100% - 20px);margin:auto;-webkit-border-radius:.25rem;border-radius:.25rem;padding:.5rem;color:var(--white);font-size:1.6em;margin-top:1rem;-webkit-box-shadow:0 4px 12px 0 rgba(0,0,0,.24);box-shadow:0 4px 12px 0 rgba(0,0,0,.24);opacity:1;-webkit-animation:bannerOpaque .2s;animation:bannerOpaque .2s}@-webkit-keyframes bannerOpaque{from{opacity:0}to{opacity:1}}@keyframes bannerOpaque{from{opacity:0}to{opacity:1}}.close-banner{position:absolute;right:1rem;z-index:1;cursor:pointer;-webkit-transform:translate(0,-3px);-ms-transform:translate(0,-3px);transform:translate(0,-3px)}.close-banner::before{content:"";width:0;display:block;position:absolute;margin-top:26px;left:50%;height:0;background-color:rgba(0,0,0,.15);-webkit-border-radius:50%;border-radius:50%;z-index:-1;cursor:pointer;-webkit-transition:all .2s;-o-transition:all .2s;transition:all .2s}.close-banner:hover::before{content:"";width:32px;margin-top:7px;display:block;position:absolute;left:0;height:32px;background-color:rgba(0,0,0,.15);-webkit-border-radius:50%;border-radius:50%;z-index:-1}@media only screen and (max-width:991px){.banner{font-size:1.2rem}}#globe-svg{height:60px;fill:#fefefe}#page-cover{width:100vw;top:-100vh;left:0;-webkit-transition-delay:.3s;-o-transition-delay:.3s;transition-delay:.3s;-webkit-transition:all .7s;-o-transition:all .7s;transition:all .7s;height:100vh;position:fixed;z-index:1000;background-color:rgba(54,61,75,.25)}#menu-button{border:none;outline:0}#menu-bar{-webkit-transition:all .15s;-o-transition:all .15s;transition:all .15s}#close-bar{-webkit-transition:all .15s;-o-transition:all .15s;transition:all .15s;display:none}#rect1{-webkit-transition:all .2s;-o-transition:all .2s;transition:all .2s}#rect2{-webkit-transition:all .2s;-o-transition:all .2s;transition:all .2s}#rect3{-webkit-transition:all .2s;-o-transition:all .2s;transition:all .2s}@media only screen and (max-width:991px){.content-wrapper{width:-webkit-calc(100%);width:calc(100%);left:0;padding-left:0;margin-left:0;margin-top:4.7rem}.container-fluid{padding-left:20px;padding-right:20px}.row{margin-left:-20px;margin-right:-20px}#menu-button{margin-right:20px;padding:0}.navbar-brand{margin-left:20px;padding-left:0}}.bot-logo{margin-bottom:.5rem}@media only screen and (min-width:1200px){#page-cover{display:none}.bot-logo{margin-left:15px}}@media only screen and (max-width:1199px){#globe-svg{height:60px;fill:var(--sg1)}.navbar-collapse.show{-webkit-box-shadow:0 10px 24px rgba(0,0,0,.15);box-shadow:0 10px 24px rgba(0,0,0,.15)}.nav-item:first-child{border-top:1px solid rgba(255,255,255,.35)}#menu-button{margin-right:-webkit-calc(10% + 15px);margin-right:calc(10% + 15px);padding:0}#menu-button:hover{background-color:transparent}.nav-item{height:auto;border-bottom:1px solid rgba(0,0,0,.35);padding-left:-webkit-calc(10% + 15px);padding-left:calc(10% + 15px)}.nav-link{line-height:3rem;padding:0}.nav-link{color:var(--sg1)!important}.nav-item:hover{border-bottom:1px solid rgba(0,0,0,.35)}.navbar-nav{background-color:var(--white2);margin-top:15px}.navbar-nav .active{border-bottom:1px solid rgba(0,0,0,.35)}#language-dropdown .dropdown-menu{width:-webkit-calc(80% + 4rem);width:calc(80% + 4rem);background-color:var(--white)}.dropdown-menu{border:none;margin-top:-20px}.nav-item:last-child{border-bottom:none}.dropdown-menu.show{-webkit-box-shadow:0 4px 24px rgba(100,109,146,.15);box-shadow:0 4px 24px rgba(100,109,146,.15);margin-bottom:1rem;margin-top:-.5rem}.dropdown-item{padding-left:15px;font-weight:300}.navbar-nav{position:relative;right:0}.long-form input{width:100%}}@media only screen and (max-width:991px){.nav-item{padding-left:20px;padding-right:20px}#language-dropdown{padding-left:20px}#language-dropdown .dropdown-menu{width:100%}#menu-button{margin-right:20px;padding:0}.navbar{padding-top:.25rem;padding-bottom:.25rem}.logo{height:1.8rem}.anchor{top:-55px}}@media only screen and (max-width:556px){#legal-1{width:100%}.legal-links{position:inherit;margin-left:20px;margin-bottom:1em}}@media only screen and (max-width:375px){#legal-1 p{display:block}}.lds-ring{display:inline-block;position:relative;width:18px;height:18px;padding-top:2px}#email-subscribe-form .lds-ring{padding-top:1px}.lds-ring div{-webkit-box-sizing:border-box;box-sizing:border-box;display:block;position:absolute;width:18px;height:18px;border:2px solid var(--b2);-webkit-border-radius:50%;border-radius:50%;-webkit-animation:lds-ring 1.2s cubic-bezier(.5,0,.5,1) infinite;animation:lds-ring 1.2s cubic-bezier(.5,0,.5,1) infinite;border-color:var(--b2) transparent transparent transparent}.lds-ring div:nth-child(1){-webkit-animation-delay:-.45s;animation-delay:-.45s}.lds-ring div:nth-child(2){-webkit-animation-delay:-.3s;animation-delay:-.3s}.lds-ring div:nth-child(3){-webkit-animation-delay:-.15s;animation-delay:-.15s}@-webkit-keyframes lds-ring{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes lds-ring{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}#email-subscribe-form .sub-arrow{padding-top:2px}.sub-arrow{display:inline-block}.sub-load{display:none} \ No newline at end of file diff --git a/2.0/documentation/tdenginedocs-cn/super-table/index.html b/2.0/documentation/tdenginedocs-cn/super-table/index.html deleted file mode 100644 index 42d54ce7e2..0000000000 --- a/2.0/documentation/tdenginedocs-cn/super-table/index.html +++ /dev/null @@ -1,110 +0,0 @@ -文档 | 涛思数据
    回去

    超级表STable:多表聚合

    -

    TDengine要求每个数据采集点单独建表,这样能极大提高数据的插入/查询性能,但是导致系统中表的数量猛增,让应用对表的维护以及聚合、统计操作难度加大。为降低应用的开发难度,TDengine引入了超级表STable (Super Table)的概念。

    -

    什么是超级表

    -

    STable是同一类型数据采集点的抽象,是同类型采集实例的集合,包含多张数据结构一样的子表。每个STable为其子表定义了表结构和一组标签:表结构即表中记录的数据列及其数据类型;标签名和数据类型由STable定义,标签值记录着每个子表的静态信息,用以对子表进行分组过滤。子表本质上就是普通的表,由一个时间戳主键和若干个数据列组成,每行记录着具体的数据,数据查询操作与普通表完全相同;但子表与普通表的区别在于每个子表从属于一张超级表,并带有一组由STable定义的标签值。每种类型的采集设备可以定义一个STable。数据模型定义表的每列数据的类型,如温度、压力、电压、电流、GPS实时位置等,而标签信息属于Meta Data,如采集设备的序列号、型号、位置等,是静态的,是表的元数据。用户在创建表(数据采集点)时指定STable(采集类型)外,还可以指定标签的值,也可事后增加或修改。

    -

    TDengine扩展标准SQL语法用于定义STable,使用关键词tags指定标签信息。语法如下:

    -
    CREATE TABLE <stable_name> (<field_name> TIMESTAMP, field_name1 field_type,…)   TAGS(tag_name tag_type, …) 
    -

    其中tag_name是标签名,tag_type是标签的数据类型。标签可以使用时间戳之外的其他TDengine支持的数据类型,标签的个数最多为6个,名字不能与系统关键词相同,也不能与其他列名相同。如:

    -
    create table thermometer (ts timestamp, degree float) 
    -tags (location binary(20), type int)
    -

    上述SQL创建了一个名为thermometer的STable,带有标签location和标签type。

    -

    为某个采集点创建表时,可以指定其所属的STable以及标签的值,语法如下:

    -
    CREATE TABLE <tb_name> USING <stb_name> TAGS (tag_value1,...)
    -

    沿用上面温度计的例子,使用超级表thermometer建立单个温度计数据表的语句如下:

    -
    create table t1 using thermometer tags (‘beijing', 10)
    -

    上述SQL以thermometer为模板,创建了名为t1的表,这张表的Schema就是thermometer的Schema,但标签location值为'beijing',标签type值为10。

    -

    用户可以使用一个STable创建数量无上限的具有不同标签的表,从这个意义上理解,STable就是若干具有相同数据模型,不同标签的表的集合。与普通表一样,用户可以创建、删除、查看超级表STable,大部分适用于普通表的查询操作都可运用到STable上,包括各种聚合和投影选择函数。除此之外,可以设置标签的过滤条件,仅对STbale中部分表进行聚合查询,大大简化应用的开发。

    -

    TDengine对表的主键(时间戳)建立索引,暂时不提供针对数据模型中其他采集量(比如温度、压力值)的索引。每个数据采集点会采集若干数据记录,但每个采集点的标签仅仅是一条记录,因此数据标签在存储上没有冗余,且整体数据规模有限。TDengine将标签数据与采集的动态数据完全分离存储,而且针对STable的标签建立了高性能内存索引结构,为标签提供全方位的快速操作支持。用户可按照需求对其进行增删改查(Create,Retrieve,Update,Delete,CRUD)操作。

    -

    STable从属于库,一个STable只属于一个库,但一个库可以有一到多个STable, 一个STable可有多个子表。

    -

    超级表管理

    -
      -
    • 创建超级表

      -
      CREATE TABLE <stable_name> (<field_name> TIMESTAMP, field_name1 field_type,…) TAGS(tag_name tag_type, …)
      -

      与创建表的SQL语法相似。但需指定TAGS字段的名称和类型。

      -

      说明:

      -
        -
      1. TAGS列总长度不能超过512 bytes;
      2. -
      3. TAGS列的数据类型不能是timestamp类型;
      4. -
      5. TAGS列名不能与其他列名相同;
      6. -
      7. TAGS列名不能为预留关键字.
    • -
    • 显示已创建的超级表

      -
      show stables;
      -

      查看数据库内全部STable,及其相关信息,包括STable的名称、创建时间、列数量、标签(TAG)数量、通过该STable建表的数量。

    • -
    • 删除超级表

      -
      DROP TABLE <stable_name>
      -

      Note: 删除STable时,所有通过该STable创建的表都将被删除。

    • -
    • 查看属于某STable并满足查询条件的表

      -
      SELECT TBNAME,[TAG_NAME,…] FROM <stable_name> WHERE <tag_name> <[=|=<|>=|<>] values..> ([AND|OR] …)
      -

      查看属于某STable并满足查询条件的表。说明:TBNAME为关键词,显示通过STable建立的子表表名,查询过程中可以使用针对标签的条件。

      -
      SELECT COUNT(TBNAME) FROM <stable_name> WHERE <tag_name> <[=|=<|>=|<>] values..> ([AND|OR] …)
      -

      统计属于某个STable并满足查询条件的子表的数量

    • -
    -

    写数据时自动建子表

    -

    在某些特殊场景中,用户在写数据时并不确定某个设备的表是否存在,此时可使用自动建表语法来实现写入数据时用超级表定义的表结构自动创建不存在的子表,若该表已存在则不会建立新表。注意:自动建表语句只能自动建立子表而不能建立超级表,这就要求超级表已经被事先定义好。自动建表语法跟insert/import语法非常相似,唯一区别是语句中增加了超级表和标签信息。具体语法如下:

    -
    INSERT INTO <tb_name> USING <stb_name> TAGS (<tag1_value>, ...) VALUES (field_value, ...) (field_value, ...) ...;
    -

    向表tb_name中插入一条或多条记录,如果tb_name这张表不存在,则会用超级表stb_name定义的表结构以及用户指定的标签值(即tag1_value…)来创建名为tb_name新表,并将用户指定的值写入表中。如果tb_name已经存在,则建表过程会被忽略,系统也不会检查tb_name的标签是否与用户指定的标签值一致,也即不会更新已存在表的标签。

    -
    INSERT INTO <tb1_name> USING <stb1_name> TAGS (<tag1_value1>, ...) VALUES (<field1_value1>, ...) (<field1_value2>, ...) ... <tb_name2> USING <stb_name2> TAGS(<tag1_value2>, ...) VALUES (<field1_value1>, ...) ...;
    -

    向多张表tb1_name,tb2_name等插入一条或多条记录,并分别指定各自的超级表进行自动建表。

    -

    STable中TAG管理

    -

    除了更新标签的值的操作是针对子表进行,其他所有的标签操作(添加标签、删除标签等)均只能作用于STable,不能对单个子表操作。对STable添加标签以后,依托于该STable建立的所有表将自动增加了一个标签,对于数值型的标签,新增加的标签的默认值是0.

    -
      -
    • 添加新的标签

      -
      ALTER TABLE <stable_name> ADD TAG <new_tag_name> <TYPE>
      -

      为STable增加一个新的标签,并指定新标签的类型。标签总数不能超过6个。

    • -
    • 删除标签

      -
      ALTER TABLE <stable_name> DROP TAG <tag_name>
      -

      删除超级表的一个标签,从超级表删除某个标签后,该超级表下的所有子表也会自动删除该标签。

      -

      说明:第一列标签不能删除,至少需要为STable保留一个标签。

    • -
    • 修改标签名

      -
      ALTER TABLE <stable_name> CHANGE TAG <old_tag_name> <new_tag_name>
      -

      修改超级表的标签名,从超级表修改某个标签名后,该超级表下的所有子表也会自动更新该标签名。

    • -
    • 修改子表的标签值

      -
      ALTER TABLE <table_name> SET TAG <tag_name>=<new_tag_value>
    • -
    -

    STable多表聚合

    -

    针对所有的通过STable创建的子表进行多表聚合查询,支持按照全部的TAG值进行条件过滤,并可将结果按照TAGS中的值进行聚合,暂不支持针对binary类型的模糊匹配过滤。语法如下:

    -
    SELECT function<field_name>,… 
    - FROM <stable_name> 
    - WHERE <tag_name> <[=|<=|>=|<>] values..> ([AND|OR] …)
    - INTERVAL (<time range>)
    - GROUP BY <tag_name>, <tag_name>…
    - ORDER BY <tag_name> <asc|desc>
    - SLIMIT <group_limit>
    - SOFFSET <group_offset>
    - LIMIT <record_limit>
    - OFFSET <record_offset>
    -

    说明

    -

    超级表聚合查询,TDengine目前支持以下聚合\选择函数:sum、count、avg、first、last、min、max、top、bottom,以及针对全部或部分列的投影操作,使用方式与单表查询的计算过程相同。暂不支持其他类型的聚合计算和四则运算。当前所有的函数及计算过程均不支持嵌套的方式进行执行。

    -

    不使用GROUP BY的查询将会对超级表下所有满足筛选条件的表按时间进行聚合,结果输出默认是按照时间戳单调递增输出,用户可以使用ORDER BY _c0 ASC|DESC选择查询结果时间戳的升降排序;使用GROUP BY 的聚合查询会按照tags进行分组,并对每个组内的数据分别进行聚合,输出结果为各个组的聚合结果,组间的排序可以由ORDER BY 语句指定,每个分组内部,时间序列是单调递增的。

    -

    使用SLIMIT/SOFFSET语句指定组间分页,即指定结果集中输出的最大组数以及对组起始的位置。使用LIMIT/OFFSET语句指定组内分页,即指定结果集中每个组内最多输出多少条记录以及记录起始的位置。

    -

    STable使用示例

    -

    以温度传感器采集时序数据作为例,示范STable的使用。 在这个例子中,对每个温度计都会建立一张表,表名为温度计的ID,温度计读数的时刻记为ts,采集的值记为degree。通过tags给每个采集器打上不同的标签,其中记录温度计的地区和类型,以方便我们后面的查询。所有温度计的采集量都一样,因此我们用STable来定义表结构。

    -

    定义STable表结构并使用它创建子表

    -

    创建STable语句如下:

    -
    CREATE TABLE thermometer (ts timestamp, degree double) 
    -TAGS(location binary(20), type int)
    -

    假设有北京,天津和上海三个地区的采集器共4个,温度采集器有3种类型,我们就可以对每个采集器建表如下:

    -
    CREATE TABLE therm1 USING thermometer TAGS ('beijing', 1);
    -CREATE TABLE therm2 USING thermometer TAGS ('beijing', 2);
    -CREATE TABLE therm3 USING thermometer TAGS ('tianjin', 1);
    -CREATE TABLE therm4 USING thermometer TAGS ('shanghai', 3);
    -

    其中therm1,therm2,therm3,therm4是超级表thermometer四个具体的子表,也即普通的Table。以therm1为例,它表示采集器therm1的数据,表结构完全由thermometer定义,标签location=”beijing”, type=1表示therm1的地区是北京,类型是第1类的温度计。

    -

    写入数据

    -

    注意,写入数据时不能直接对STable操作,而是要对每张子表进行操作。我们分别向四张表therm1,therm2, therm3, therm4写入一条数据,写入语句如下:

    -
    INSERT INTO therm1 VALUES ('2018-01-01 00:00:00.000', 20);
    -INSERT INTO therm2 VALUES ('2018-01-01 00:00:00.000', 21);
    -INSERT INTO therm3 VALUES ('2018-01-01 00:00:00.000', 24);
    -INSERT INTO therm4 VALUES ('2018-01-01 00:00:00.000', 23);
    -

    按标签聚合查询

    -

    查询位于北京(beijing)和天津(tianjing)两个地区的温度传感器采样值的数量count(*)、平均温度avg(degree)、最高温度max(degree)、最低温度min(degree),并将结果按所处地域(location)和传感器类型(type)进行聚合。

    -
    SELECT COUNT(*), AVG(degree), MAX(degree), MIN(degree)
    -FROM thermometer
    -WHERE location='beijing' or location='tianjin'
    -GROUP BY location, type 
    -

    按时间周期聚合查询

    -

    查询仅位于北京以外地区的温度传感器最近24小时(24h)采样值的数量count(*)、平均温度avg(degree)、最高温度max(degree)和最低温度min(degree),将采集结果按照10分钟为周期进行聚合,并将结果按所处地域(location)和传感器类型(type)再次进行聚合。

    -
    SELECT COUNT(*), AVG(degree), MAX(degree), MIN(degree)
    -FROM thermometer
    -WHERE location<>'beijing' and ts>=now-1d
    -INTERVAL(10M)
    -GROUP BY location, type
    回去
    diff --git a/2.0/documentation/tdenginedocs-cn/taos-sql/index.html b/2.0/documentation/tdenginedocs-cn/taos-sql/index.html deleted file mode 100644 index 207bfe03fd..0000000000 --- a/2.0/documentation/tdenginedocs-cn/taos-sql/index.html +++ /dev/null @@ -1,388 +0,0 @@ -文档 | 涛思数据
    回去

    TAOS SQL

    -

    TDengine提供类似SQL语法,用户可以在TDengine Shell中使用SQL语句操纵数据库,也可以通过C/C++, Java(JDBC), Python, Go等各种程序来执行SQL语句。

    -

    本章节SQL语法遵循如下约定:

    -
      -
    • < > 里的内容是用户需要输入的,但不要输入<>本身
    • -
    • [ ]表示内容为可选项,但不能输入[]本身
    • -
    • | 表示多选一,选择其中一个即可,但不能输入|本身
    • -
    • … 表示前面的项可重复多个
    • -
    -

    支持的数据类型

    -

    使用TDengine,最重要的是时间戳。创建并插入记录、查询历史记录的时候,均需要指定时间戳。时间戳有如下规则:

    -
      -
    • 时间格式为YYYY-MM-DD HH:mm:ss.MS, 默认时间分辨率为毫秒。比如:2017-08-12 18:25:58.128
    • -
    • 内部函数now是服务器的当前时间
    • -
    • 插入记录时,如果时间戳为0,插入数据时使用服务器当前时间
    • -
    • Epoch Time: 时间戳也可以是一个长整数,表示从1970-01-01 08:00:00.000开始的毫秒数
    • -
    • 时间可以加减,比如 now-2h,表明查询时刻向前推2个小时(最近2小时)。数字后面的时间单位:a(毫秒), s(秒), m(分), h(小时), d(天),w(周), n(月), y(年)。比如select * from t1 where ts > now-2w and ts <= now-1w, 表示查询两周前整整一周的数据
    • -
    -

    TDengine缺省的时间戳是毫秒精度,但通过修改配置参数enableMicrosecond就可支持微秒。

    -

    在TDengine中,普通表的数据模型中可使用以下10种数据类型。

    -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    类型Bytes说明
    1TIMESTAMP8时间戳。最小精度毫秒。从格林威治时间1970-01-01 08:00:00.000开始,计时不能早于该时间。
    2INT4整型,范围 [-2^31+1, 2^31-1], -2^31被用作Null值
    3BIGINT8长整型,范围 [-2^59, 2^59]
    4FLOAT4浮点型,有效位数6-7,范围 [-3.4E38, 3.4E38]
    5DOUBLE8双精度浮点型,有效位数15-16,范围 [-1.7E308, 1.7E308]
    6BINARY自定义用于记录字符串,最长不能超过504 bytes。binary仅支持字符串输入,字符串两端使用单引号引用,否则英文全部自动转化为小写。使用时须指定大小,如binary(20)定义了最长为20个字符的字符串,每个字符占1byte的存储空间。如果用户字符串超出20字节,将被自动截断。对于字符串内的单引号,可以用转义字符反斜线加单引号来表示, 即 \’
    7SMALLINT2短整型, 范围 [-32767, 32767]
    8TINYINT1单字节整型,范围 [-127, 127]
    9BOOL1布尔型,{true, false}
    10NCHAR自定义用于记录非ASCII字符串,如中文字符。每个nchar字符占用4bytes的存储空间。字符串两端使用单引号引用,字符串内的单引号需用转义字符 \’。nchar使用时须指定字符串大小,类型为nchar(10)的列表示此列的字符串最多存储10个nchar字符,会固定占用40bytes的空间。如用户字符串长度超出声明长度,则将被自动截断。
    -

    Tips: TDengine对SQL语句中的英文字符不区分大小写,自动转化为小写执行。因此用户大小写敏感的字符串及密码,需要使用单引号将字符串引起来。

    -

    数据库管理

    -
      -
    • 创建数据库

      -
      CREATE DATABASE [IF NOT EXISTS] db_name [KEEP keep]
      -

      创建数据库。KEEP是该数据库的数据保留多长天数,缺省是3650天(10年),数据库会自动删除超过时限的数据。数据库还有更多与存储相关的配置参数,请参见系统管理

    • -
    • 使用数据库

      -
      USE db_name
      -

      使用/切换数据库

    • -
    • 删除数据库

      -
      DROP DATABASE [IF EXISTS] db_name
      -

      删除数据库。所包含的全部数据表将被删除,谨慎使用

    • -
    • 显示系统所有数据库

      -
      SHOW DATABASES
    • -
    -

    表管理

    -
      -
    • 创建数据表

      -
      CREATE TABLE [IF NOT EXISTS] tb_name (timestamp_field_name TIMESTAMP, field1_name data_type1 [, field2_name data_type2 ...])
      -

      说明:1)表的第一个字段必须是TIMESTAMP,并且系统自动将其设为主键;2)表的每行长度不能超过4096字节;3)使用数据类型binary或nchar,需指定其最长的字节数,如binary(20),表示20字节。

    • -
    • 删除数据表

      -
      DROP TABLE [IF EXISTS] tb_name
    • -
    • 显示当前数据库下的所有数据表信息

      -
      SHOW TABLES [LIKE tb_name_wildcar]
      -

      显示当前数据库下的所有数据表信息。说明:可在like中使用通配符进行名称的匹配。 通配符匹配:1)’%’ (百分号)匹配0到任意个字符;2)’_’下划线匹配一个字符。

    • -
    • 获取表的结构信息

      -
      DESCRIBE tb_name
    • -
    • 表增加列

      -
      ALTER TABLE tb_name ADD COLUMN field_name data_type
    • -
    • 表删除列

      -
      ALTER TABLE tb_name DROP COLUMN field_name 
      -

      如果表是通过超级表创建,更改表结构的操作只能对超级表进行。同时针对超级表的结构更改对所有通过该结构创建的表生效。对于不是通过超级表创建的表,可以直接修改表结构

      -

      Tips:SQL语句中操作的当前数据库(通过use db_name的方式指定)中的表不需要指定表所属数据库。如果要操作非当前数据库中的表,需要采用“库名”.“表名”的方式。例如:demo.tb1,是指数据库demo中的表tb1。

    • -
    -

    数据写入

    -
      -
    • 插入一条记录

      -
      INSERT INTO tb_name VALUES (field_value, ...);
      -

      向表tb_name中插入一条记录

    • -
    • 插入一条记录,数据对应到指定的列

      -
      INSERT INTO tb_name (field1_name, ...) VALUES(field1_value, ...)
      -

      向表tb_name中插入一条记录,数据对应到指定的列。SQL语句中没有出现的列,数据库将自动填充为NULL。主键(时间戳)不能为NULL。

    • -
    • 插入多条记录

      -
      INSERT INTO tb_name VALUES (field1_value1, ...) (field1_value2, ...)...;
      -

      向表tb_name中插入多条记录

    • -
    • 按指定的列插入多条记录

      -
      INSERT INTO tb_name (field1_name, ...) VALUES(field1_value1, ...) (field1_value2, ...)
      -

      向表tb_name中按指定的列插入多条记录

    • -
    • 向多个表插入多条记录

      -
      INSERT INTO tb1_name VALUES (field1_value1, ...)(field1_value2, ...)... 
      -            tb2_name VALUES (field1_value1, ...)(field1_value2, ...)...;
      -

      同时向表tb1_name和tb2_name中分别插入多条记录

    • -
    • 同时向多个表按列插入多条记录

      -
      INSERT INTO tb1_name (tb1_field1_name, ...) VALUES (field1_value1, ...) (field1_value1, ...)
      -            tb2_name (tb2_field1_name, ...) VALUES(field1_value1, ...) (field1_value2, ...)
      -

      同时向表tb1_name和tb2_name中按列分别插入多条记录

    • -
    -

    注意:对同一张表,插入的新记录的时间戳必须递增,否则会跳过插入该条记录。如果时间戳为0,系统将自动使用服务器当前时间作为该记录的时间戳。

    -

    IMPORT:如果需要将时间戳小于最后一条记录时间的记录写入到数据库中,可使用IMPORT替代INSERT命令,IMPORT的语法与INSERT完全一样。如果同时IMPORT多条记录,需要保证一批记录是按时间戳排序好的。

    -

    数据查询

    -

    查询语法是:

    -
    SELECT {* | expr_list} FROM tb_name
    -    [WHERE where_condition]
    -    [ORDER BY _c0 { DESC | ASC }]
    -    [LIMIT limit [, OFFSET offset]]
    -    [>> export_file]
    -
    -SELECT function_list FROM tb_name
    -    [WHERE where_condition]
    -    [LIMIT limit [, OFFSET offset]]
    -    [>> export_file]
    -
      -
    • 可以使用* 返回所有列,或指定列名。可以对数字列进行四则运算,可以给输出的列取列名
    • -
    • where语句可以使用各种逻辑判断来过滤数字值,或使用通配符来过滤字符串
    • -
    • 输出结果缺省按首列时间戳升序排序,但可以指定按降序排序(_c0指首列时间戳)。使用ORDER BY对其他字段进行排序为非法操作。
    • -
    • 参数LIMIT控制输出条数,OFFSET指定从第几条开始输出。LIMIT/OFFSET对结果集的执行顺序在ORDER BY之后。
    • -
    • 通过”>>"输出结果可以导出到指定文件
    • -
    -

    支持的条件过滤操作

    -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    OperationNoteApplicable Data Types
    >larger thantimestamp and all numeric types
    <smaller thantimestamp and all numeric types
    >=larger than or equal totimestamp and all numeric types
    <=smaller than or equal totimestamp and all numeric types
    =equal toall types
    <>not equal toall types
    %match with any char sequencesbinary nchar
    _match with a single charbinary nchar
    -
      -
    1. 同时进行多个字段的范围过滤需要使用关键词AND进行连接不同的查询条件,暂不支持OR连接的查询条件。
    2. -
    3. 针对某一字段的过滤只支持单一区间的过滤条件。例如:value>20 and value<30是合法的过滤条件, 而Value<20 AND value<>5是非法的过滤条件。
    4. -
    -

    Some Examples

    -
      -
    • 对于下面的例子,表tb1用以下语句创建

      -
      CREATE TABLE tb1 (ts timestamp, col1 int, col2 float, col3 binary(50))
    • -
    • 查询tb1刚过去的一个小时的所有记录

      -
      SELECT * FROM tb1 WHERE ts >= NOW - 1h
    • -
    • 查询表tb1从2018-06-01 08:00:00.000 到2018-06-02 08:00:00.000时间范围,并且clo3的字符串是'nny'结尾的记录,结果按照时间戳降序

      -
      SELECT * FROM tb1 WHERE ts > '2018-06-01 08:00:00.000' AND ts <= '2018-06-02 08:00:00.000' AND col3 LIKE '%nny' ORDER BY ts DESC
    • -
    • 查询col1与col2的和,并取名complex, 时间大于2018-06-01 08:00:00.000, col2大于1.2,结果输出仅仅10条记录,从第5条开始

      -
      SELECT (col1 + col2) AS 'complex' FROM tb1 WHERE ts > '2018-06-01 08:00:00.000' and col2 > 1.2 LIMIT 10 OFFSET 5
    • -
    • 查询过去10分钟的记录,col2的值大于3.14,并且将结果输出到文件 /home/testoutpu.csv.

      -
      SELECT COUNT(*) FROM tb1 WHERE ts >= NOW - 10m AND col2 > 3.14 >> /home/testoutpu.csv
    • -
    -

    SQL函数

    -

    聚合函数

    -

    TDengine支持针对数据的聚合查询。提供支持的聚合和提取函数如下表:

    -
      -
    • COUNT

      -
      SELECT COUNT([*|field_name]) FROM tb_name [WHERE clause]
      -

      功能说明:统计表/超级表中记录行数或某列的非空值个数。
      -返回结果数据类型:长整型INT64。
      -应用字段:应用全部字段。
      -适用于:表、超级表。
      -说明:1)可以使用星号来替代具体的字段,使用星号()返回全部记录数量。2)针对同一表的(不包含NULL值)字段查询结果均相同。3)如果统计对象是具体的列,则返回该列中非NULL值的记录数量。

    • -
    • AVG

      -
      SELECT AVG(field_name) FROM tb_name [WHERE clause]
      -

      功能说明:统计表/超级表中某列的平均值。
      -返回结果数据类型:双精度浮点数Double。
      -应用字段:不能应用在timestamp、binary、nchar、bool字段。
      -适用于:表、超级表。

    • -
    • WAVG

      -
      SELECT WAVG(field_name) FROM tb_name WHERE clause
      -

      功能说明:统计表/超级表中某列在一段时间内的时间加权平均。
      -返回结果数据类型:双精度浮点数Double。
      -应用字段:不能应用在timestamp、binary、nchar、bool类型字段。
      -适用于:表、超级表。

    • -
    • SUM

      -
      SELECT SUM(field_name) FROM tb_name [WHERE clause]
      -

      功能说明:统计表/超级表中某列的和。
      -返回结果数据类型:双精度浮点数Double和长整型INT64。
      -应用字段:不能应用在timestamp、binary、nchar、bool类型字段。
      -适用于:表、超级表。

    • -
    • STDDEV

      -
      SELECT STDDEV(field_name) FROM tb_name [WHERE clause]
      -

      功能说明:统计表中某列的均方差。
      -返回结果数据类型:双精度浮点数Double。
      -应用字段:不能应用在timestamp、binary、nchar、bool类型字段。
      -适用于:表。

    • -
    • LEASTSQUARES

      -
      SELECT LEASTSQUARES(field_name) FROM tb_name [WHERE clause]
      -

      功能说明:统计表中某列的值是主键(时间戳)的拟合直线方程。
      -返回结果数据类型:字符串表达式(斜率, 截距)。
      -应用字段:不能应用在timestamp、binary、nchar、bool类型字段。
      -说明:自变量是时间戳,因变量是该列的值。
      -适用于:表。

    • -
    -

    选择函数

    -
      -
    • MIN

      -
      SELECT MIN(field_name) FROM {tb_name | stb_name} [WHERE clause]
      -

      功能说明:统计表/超级表中某列的值最小值。
      -返回结果数据类型:同应用的字段。
      -应用字段:不能应用在timestamp、binary、nchar、bool类型字段。

    • -
    • MAX

      -
      SELECT MAX(field_name) FROM { tb_name | stb_name } [WHERE clause]
      -

      功能说明:统计表/超级表中某列的值最大值。
      -返回结果数据类型:同应用的字段。
      -应用字段:不能应用在timestamp、binary、nchar、bool类型字段。

    • -
    • FIRST

      -
      SELECT FIRST(field_name) FROM { tb_name | stb_name } [WHERE clause]
      -

      功能说明:统计表/超级表中某列的值最先写入的非NULL值。
      -返回结果数据类型:同应用的字段。
      -应用字段:所有字段。
      -说明:1)如果要返回各个列的首个(时间戳最小)非NULL值,可以使用FIRST(*);2) 如果结果集中的某列全部为NULL值,则该列的返回结果也是NULL;3) 如果结果集中所有列全部为NULL值,则不返回结果。

    • -
    • LAST

      -
      SELECT LAST(field_name) FROM { tb_name | stb_name } [WHERE clause]
      -

      功能说明:统计表/超级表中某列的值最后写入的非NULL值。
      -返回结果数据类型:同应用的字段。
      -应用字段:所有字段。
      -说明:1)如果要返回各个列的最后(时间戳最大)一个非NULL值,可以使用LAST(*);2)如果结果集中的某列全部为NULL值,则该列的返回结果也是NULL;如果结果集中所有列全部为NULL值,则不返回结果。

    • -
    • TOP

      -
      SELECT TOP(field_name, K) FROM { tb_name | stb_name } [WHERE clause]
      -

      功能说明: 统计表/超级表中某列的值最大k个非NULL值。若多于k个列值并列最大,则返回时间戳小的。
      -返回结果数据类型:同应用的字段。
      -应用字段:不能应用在timestamp、binary、nchar、bool类型字段。
      -说明:1)k值取值范围1≤k≤100;2)系统同时返回该记录关联的时间戳列。

    • -
    • BOTTOM

      -
      SELECT BOTTOM(field_name, K) FROM { tb_name | stb_name } [WHERE clause]
      -

      功能说明:统计表/超级表中某列的值最小k个非NULL值。若多于k个列值并列最小,则返回时间戳小的。
      -返回结果数据类型:同应用的字段。
      -应用字段:不能应用在timestamp、binary、nchar、bool类型字段。
      -说明:1)k值取值范围1≤k≤100;2)系统同时返回该记录关联的时间戳列。

    • -
    • PERCENTILE

      -
      SELECT PERCENTILE(field_name, P) FROM { tb_name | stb_name } [WHERE clause]
      -

      功能说明:统计表中某列的值百分比分位数。
      -返回结果数据类型: 双精度浮点数Double。
      -应用字段:不能应用在timestamp、binary、nchar、bool类型字段。
      -说明:k值取值范围0≤k≤100,为0的时候等同于MIN,为100的时候等同于MAX。

    • -
    • LAST_ROW

      -
      SELECT LAST_ROW(field_name) FROM { tb_name | stb_name }
      -

      功能说明:返回表(超级表)的最后一条记录。
      -返回结果数据类型:同应用的字段。
      -应用字段:所有字段。
      -说明:与last函数不同,last_row不支持时间范围限制,强制返回最后一条记录。

    • -
    -

    计算函数

    -
      -
    • DIFF

      -
      SELECT DIFF(field_name) FROM tb_name [WHERE clause]
      -

      功能说明:统计表中某列的值与前一行对应值的差。
      -返回结果数据类型: 同应用字段。
      -应用字段:不能应用在timestamp、binary、nchar、bool类型字段。
      -说明:输出结果行数是范围内总行数减一,第一行没有结果输出。

    • -
    • SPREAD

      -
      SELECT SPREAD(field_name) FROM { tb_name | stb_name } [WHERE clause]
      -

      功能说明:统计表/超级表中某列的最大值和最小值之差。
      -返回结果数据类型: 双精度浮点数。
      -应用字段:不能应用在binary、nchar、bool类型字段。
      -说明:可用于TIMESTAMP字段,此时表示记录的时间覆盖范围。

    • -
    • 四则运算

      -
      SELECT field_name [+|-|*|/|%][Value|field_name] FROM { tb_name | stb_name }  [WHERE clause]
      -

      功能说明:统计表/超级表中某列或多列间的值加、减、乘、除、取余计算结果。
      -返回结果数据类型:双精度浮点数。
      -应用字段:不能应用在timestamp、binary、nchar、bool类型字段。
      -说明:1)支持两列或多列之间进行计算,可使用括号控制计算优先级;2)NULL字段不参与计算,如果参与计算的某行中包含NULL,该行的计算结果为NULL。

    • -
    -

    时间维度聚合

    -

    TDengine支持按时间段进行聚合,可以将表中数据按照时间段进行切割后聚合生成结果,比如温度传感器每秒采集一次数据,但需查询每隔10分钟的温度平均值。这个聚合适合于降维(down sample)操作, 语法如下:

    -
    SELECT function_list FROM tb_name 
    -  [WHERE where_condition]
    -  INTERVAL (interval)
    -  [FILL ({NONE | VALUE | PREV | NULL | LINEAR})]
    -
    -SELECT function_list FROM stb_name 
    -  [WHERE where_condition]
    -  [FILL ({ VALUE | PREV | NULL | LINEAR})]
    -  INTERVAL (interval)
    -  [GROUP BY tags]
    -
      -
    • 聚合时间段的长度由关键词INTERVAL指定,最短时间间隔10毫秒(10a)。聚合查询中,能够同时执行的聚合和选择函数仅限于单个输出的函数:count、avg、sum 、stddev、leastsquares、percentile、min、max、first、last,不能使用具有多行输出结果的函数(例如:top、bottom、diff以及四则运算)。
    • -
    • WHERE语句可以指定查询的起止时间和其他过滤条件
    • -
    • FILL语句指定某一时间区间数据缺失的情况下的填充模式。填充模式包括以下几种:
    • -
    -
      -
    1. 不进行填充:NONE(默认填充模式)。

    2. -
    3. VALUE填充:固定值填充,此时需要指定填充的数值。例如:fill(value, 1.23)。

    4. -
    5. NULL填充:使用NULL填充数据。例如:fill(null)。

    6. -
    7. PREV填充:使用前一个非NULL值填充数据。例如:fill(prev)。

    8. -
    -

    说明:

    -
      -
    1. 使用FILL语句的时候可能生成大量的填充输出,务必指定查询的时间区间。针对每次查询,系统可返回不超过1千万条具有插值的结果。
    2. -
    3. 在时间维度聚合中,返回的结果中时间序列严格单调递增。
    4. -
    5. 如果查询对象是超级表,则聚合函数会作用于该超级表下满足值过滤条件的所有表的数据。如果查询中没有使用group by语句,则返回的结果按照时间序列严格单调递增;如果查询中使用了group by语句分组,则返回结果中每个group内不按照时间序列严格单调递增。
    6. -
    -

    示例:温度数据表的建表语句如下:

    -
    create table sensor(ts timestamp, degree double, pm25 smallint) 
    -

    针对传感器采集的数据,以10分钟为一个阶段,计算过去24小时的温度数据的平均值、最大值、温度的中位数、以及随着时间变化的温度走势拟合直线。如果没有计算值,用前一个非NULL值填充。

    -
    SELECT AVG(degree),MAX(degree),LEASTSQUARES(degree), PERCENTILE(degree, 50) FROM sensor
    -  WHERE TS>=NOW-1d
    -  INTERVAL(10m)
    -  FILL(PREV);
    回去
    \ No newline at end of file diff --git a/2.0/documentation/tdenginedocs-en/administrator/index.html b/2.0/documentation/tdenginedocs-en/administrator/index.html deleted file mode 100644 index 1615fbfb6a..0000000000 --- a/2.0/documentation/tdenginedocs-en/administrator/index.html +++ /dev/null @@ -1,137 +0,0 @@ -Documentation | Taos Data
    Back

    Administrator

    -

    Directory and Files

    -

    After TDengine is installed, by default, the following directories will be created:

    -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Directory/FileDescription
    /etc/taos/taos.cfgTDengine configuration file
    /usr/local/taos/driverTDengine dynamic link library
    /var/lib/taosTDengine default data directory
    /var/log/taosTDengine default log directory
    /usr/local/taos/bin.TDengine executables
    -

    Executables

    -

    All TDengine executables are located at /usr/local/taos/bin , including:

    -
      -
    • taosd:TDengine server
    • -
    • taos: TDengine Shell, the command line interface.
    • -
    • taosdump:TDengine data export tool
    • -
    • rmtaos: a script to uninstall TDengine
    • -
    -

    You can change the data directory and log directory setting through the system configuration file

    -

    Configuration on Server

    -

    taosd is running on the server side, you can change the system configuration file taos.cfg to customize its behavior. By default, taos.cfg is located at /etc/taos, but you can specify the path to configuration file via the command line parameter -c. For example: taosd -c /home/user means the configuration file will be read from directory /home/user.

    -

    This section lists only the most important configuration parameters. Please check taos.cfg to find all the configurable parameters. Note: to make your new configurations work, you have to restart taosd after you change taos.cfg.

    -
      -
    • mgmtShellPort: TCP and UDP port between client and TDengine mgmt (default: 6030). Note: 5 successive UDP ports (6030-6034) starting from this number will be used.
    • -
    • vnodeShellPort: TCP and UDP port between client and TDengine vnode (default: 6035). Note: 5 successive UDP ports (6035-6039) starting from this number will be used.
    • -
    • httpPort: TCP port for RESTful service (default: 6020)
    • -
    • dataDir: data directory, default is /var/lib/taos
    • -
    • maxUsers: maximum number of users allowed
    • -
    • maxDbs: maximum number of databases allowed
    • -
    • maxTables: maximum number of tables allowed
    • -
    • enableMonitor: turn on/off system monitoring, 0: off, 1: on
    • -
    • logDir: log directory, default is /var/log/taos
    • -
    • numOfLogLines: maximum number of lines in the log file
    • -
    • debugFlag: log level, 131: only error and warnings, 135: all
    • -
    -

    In different scenarios, data characteristics are different. For example, the retention policy, data sampling period, record size, the number of devices, and data compression may be different. To gain the best performance, you can change the following configurations related to storage:

    -
      -
    • days: number of days to cover for a data file
    • -
    • keep: number of days to keep the data
    • -
    • rows: number of rows of records in a block in data file.
    • -
    • comp: compression algorithm, 0: off, 1: standard; 2: maximum compression
    • -
    • ctime: period (seconds) to flush data to disk
    • -
    • clog: flag to turn on/off Write Ahead Log, 0: off, 1: on
    • -
    • tables: maximum number of tables allowed in a vnode
    • -
    • cache: cache block size (bytes)
    • -
    • tblocks: maximum number of cache blocks for a table
    • -
    • abloks: average number of cache blocks for a table
    • -
    • precision: timestamp precision, us: microsecond ms: millisecond, default is ms
    • -
    -

    For an application, there may be multiple data scenarios. The best design is to put all data with the same characteristics into one database. One application may have multiple databases, and every database has its own configuration to maximize the system performance. You can specify the above configurations related to storage when you create a database. For example:

    -
    CREATE DATABASE demo DAYS 10 CACHE 16000 ROWS 2000 
    -

    The above SQL statement will create a database demo, with 10 days for each data file, 16000 bytes for a cache block, and 2000 rows in a file block.

    -

    The configuration provided when creating a database will overwrite the configuration in taos.cfg.

    -

    Configuration on Client

    -

    taos is the TDengine shell and is a client that connects to taosd. TDengine uses the same configuration file taos.cfg for the client, with default location at /etc/taos. You can change it by specifying command line parameter -c when you run taos. For example, taos -c /home/user, it will read the configuration file taos.cfg from directory /home/user.

    -

    The parameters related to client configuration are listed below:

    -
      -
    • masterIP: IP address of TDengine server
    • -
    • charset: character set, default is the system . For data type nchar, TDengine uses unicode to store the data. Thus, the client needs to tell its character set.
    • -
    • locale: system language setting
    • -
    • defaultUser: default login user, default is root
    • -
    • defaultPass: default password, default is taosdata
    • -
    -

    For TCP/UDP port, and system debug/log configuration, it is the same as the server side.

    -

    For server IP, user name, password, you can always specify them in the command line when you run taos. If they are not specified, they will be read from the taos.cfg

    -

    User Management

    -

    System administrator (user root) can add, remove a user, or change the password from the TDengine shell. Commands are listed below:

    -

    Create a user, password shall be quoted with the single quote.

    -
    CREATE USER user_name PASS ‘password’
    -

    Remove a user

    -
    DROP USER user_name
    -

    Change the password for a user

    -
    ALTER USER user_name PASS ‘password’  
    -

    List all users

    -
    SHOW USERS
    -

    Import Data

    -

    Inside the TDengine shell, you can import data into TDengine from either a script or CSV file

    -

    Import from Script

    -
    source <filename>
    -

    Inside the file, you can put all SQL statements there. Each SQL statement has a line. If a line starts with "#", it means comments, it will be skipped. The system will execute the SQL statements line by line automatically until the ends

    -

    Import from CVS

    -
    insert into tb1 file a.csv b.csv tb2 c.csv …
    -import into tb1 file a.csv b.csv tb2 c.csv …
    -

    Each csv file contains records for only one table, and the data structure shall be the same as the defined schema for the table.

    -

    Export Data

    -

    You can export data either from TDengine shell or from tool taosdump.

    -

    Export from TDengine Shell

    -
    select * from <tb_name> >> a.csv
    -

    The above SQL statement will dump the query result set into a csv file.

    -

    Export Using taosdump

    -

    TDengine provides a data dumping tool taosdump. You can choose to dump a database, a table, all data or data only a time range, even only the metadata. For example:

    -
      -
    • Export one or more tables in a DB: taosdump [OPTION…] dbname tbname …
    • -
    • Export one or more DBs: taosdump [OPTION…] --databases dbname…
    • -
    • Export all DBs (excluding system DB): taosdump [OPTION…] --all-databases
    • -
    -

    run taosdump —help to get a full list of the options

    -

    Management of Connections, Streams, Queries

    -

    The system administrator can check, kill the ongoing connections, streams, or queries.

    -
    SHOW CONNECTIONS
    -

    It lists all connections, one column shows ip:port from the client.

    -
    KILL CONNECTION <connection-id>
    -

    It kills the connection, where connection-id is the ip:port showed by "SHOW CONNECTIONS". You can copy and paste it.

    -
    SHOW QUERIES
    -

    It shows the ongoing queries, one column ip:port:id shows the ip:port from the client, and id assigned by the system

    -
    KILL QUERY <query-id>
    -

    It kills the query, where query-id is the ip:port:id showed by "SHOW QUERIES". You can copy and paste it.

    -
    SHOW STREAMS
    -

    It shows the continuous queries, one column shows the ip:port:id, where ip:port is the connection from the client, and id assigned by the system.

    -
    KILL STREAM <stream-id>
    -

    It kills the continuous query, where stream-id is the ip:port:id showed by "SHOW STREAMS". You can copy and paste it.

    -

    System Monitor

    -

    TDengine runs a system monitor in the background. Once it is started, it will create a database sys automatically. System monitor collects the metric like CPU, memory, network, disk, number of requests periodically, and writes them into database sys. Also, TDengine will log all important actions, like login, logout, create database, drop database and so on, and write them into database sys.

    -

    You can check all the saved monitor information from database sys. By default, system monitor is turned on. But you can turn it off by changing the parameter in the configuration file.

    Back
    \ No newline at end of file diff --git a/2.0/documentation/tdenginedocs-en/advanced-features/index.html b/2.0/documentation/tdenginedocs-en/advanced-features/index.html deleted file mode 100644 index cb8fd04c8e..0000000000 --- a/2.0/documentation/tdenginedocs-en/advanced-features/index.html +++ /dev/null @@ -1,41 +0,0 @@ -Documentation | Taos Data
    Back

    Advanced Features

    -

    Continuous Query

    -

    Continuous Query is a query executed by TDengine periodically with a sliding window, it is a simplified stream computing driven by timers, not by events. Continuous query can be applied to a table or a STable, and the result set can be passed to the application directly via call back function, or written into a new table in TDengine. The query is always executed on a specified time window (window size is specified by parameter interval), and this window slides forward while time flows (the sliding period is specified by parameter sliding).

    -

    Continuous query is defined by TAOS SQL, there is nothing special. One of the best applications is downsampling. Once it is defined, at the end of each cycle, the system will execute the query, pass the result to the application or write it to a database.

    -

    If historical data pints are inserted into the stream, the query won't be re-executed, and the result set won't be updated. If the result set is passed to the application, the application needs to keep the status of continuous query, the server won't maintain it. If application re-starts, it needs to decide the time where the stream computing shall be started.

    -

    How to use continuous query

    -
      -
    • Pass result set to application

      -

      Application shall use API taos_stream (details in connector section) to start the stream computing. Inside the API, the SQL syntax is:

      -
      SELECT aggregation FROM [table_name | stable_name] 
      -INTERVAL(window_size) SLIDING(period)
      -

      where the new keyword INTERVAL specifies the window size, and SLIDING specifies the sliding period. If parameter sliding is not specified, the sliding period will be the same as window size. The minimum window size is 10ms. The sliding period shall not be larger than the window size. If you set a value larger than the window size, the system will adjust it to window size automatically.

      -

      For example:

      -
      SELECT COUNT(*) FROM FOO_TABLE 
      -INTERVAL(1M) SLIDING(30S)
      -

      The above SQL statement will count the number of records for the past 1-minute window every 30 seconds.

    • -
    • Save the result into a database

      -

      If you want to save the result set of stream computing into a new table, the SQL shall be:

      -
      CREATE TABLE table_name AS 
      -SELECT aggregation from [table_name | stable_name]  
      -INTERVAL(window_size) SLIDING(period)
      -

      Also, you can set the time range to execute the continuous query. If no range is specified, the continuous query will be executed forever. For example, the following continuous query will be executed from now and will stop in one hour.

      -
      CREATE TABLE QUERY_RES AS 
      -SELECT COUNT(*) FROM FOO_TABLE 
      -WHERE TS > NOW AND TS <= NOW + 1H 
      -INTERVAL(1M) SLIDING(30S) 
    • -
    -

    Manage the Continuous Query

    -

    Inside TDengine shell, you can use the command "show streams" to list the ongoing continuous queries, the command "kill stream" to kill a specific continuous query.

    -

    If you drop a table generated by the continuous query, the query will be removed too.

    -

    Publisher/Subscriber

    -

    Time series data is a sequence of data points over time. Inside a table, the data points are stored in order of timestamp. Also, there is a data retention policy, the data points will be removed once their lifetime is passed. From another view, a table in TDengine is just a standard message queue.

    -

    To reduce the development complexity and improve data consistency, TDengine provides the pub/sub functionality. To publish a message, you simply insert a record into a table. Compared with popular messaging tool Kafka, you subscribe to a table or a SQL query statement, instead of a topic. Once new data points arrive, TDengine will notify the application. The process is just like Kafka.

    -

    The detailed API will be introduced in the connectors section.

    -

    Caching

    -

    TDengine allocates a fixed-size buffer in memory, the newly arrived data will be written into the buffer first. Every device or table gets one or more memory blocks. For typical IoT scenarios, the hot data shall always be newly arrived data, they are more important for timely analysis. Based on this observation, TDengine manages the cache blocks in First-In-First-Out strategy. If no enough space in the buffer, the oldest data will be saved into hard disk first, then be overwritten by newly arrived data. TDengine also guarantees every device can keep at least one block of data in the buffer.

    -

    By this design, the application can retrieve the latest data from each device super-fast, since they are all available in memory. You can use last or last_row function to return the last data record. If the super table is used, it can be used to return the last data records of all or a subset of devices. For example, to retrieve the latest temperature from thermometers in located Beijing, execute the following SQL

    -
    select last(*) from thermometers where location=’beijing’
    -

    By this design, caching tool, like Redis, is not needed in the system. It will reduce the complexity of the system.

    -

    TDengine creates one or more virtual nodes(vnode) in each data node. Each vnode contains data for multiple tables and has its own buffer. The buffer of a vnode is fully separated from the buffer of another vnode, not shared. But the tables in a vnode share the same buffer.

    -

    System configuration parameter cacheBlockSize configures the cache block size in bytes, and another parameter cacheNumOfBlocks configures the number of cache blocks. The total memory for the buffer of a vnode is $cacheBlockSize \times cacheNumOfBlocks$. Another system parameter numOfBlocksPerMeter configures the maximum number of cache blocks a table can use. When you create a database, you can specify these parameters.

    Back
    diff --git a/2.0/documentation/tdenginedocs-en/assets/Picture2.png b/2.0/documentation/tdenginedocs-en/assets/Picture2.png deleted file mode 100644 index 715a8bd37ee9fe7e96eacce4e7ff563fedeefbee..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 44198 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 z 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 XT_z57}q-MQIJeG}1I$A3nj?_6} zM$(fbzT3wl2WCV3LWy zhG?UT#zJSEc|b8X)6Ru86T8 zhx(t1t18D_K2Zr!m!vN$0d2n3nul`Rj-S1F6j&(}&!dFwi^CNjl6;@r9PJNJOVcB} z@A_G>$axXQa=>;yTmoWfHLDuGRJ;?R5VZ`-JSiUv(52WO>BT}xQCafM_m`V;Cf*1M zx`RG0#-4?oz23$T1IxMs0dzr^iVMn`|C2wl9dNa4+CKb|es0ns=9YH%e53H2GTl0Kb zO_xl`G+ghh)7vn*@wf3^OaVMLh514NjD3J+w%u#36EuJqX`LLsmt#9_6Me3=%_zfo ze=-Qj5#IR(i8r{gFfNvWUm-rUNPmPg@JLwDK%d@AX**ZDT#t4W$5{T!ttS^WN%y%O zNBGWMlsQ9oa8>UXrUp|8@N(tGWg1W|Y!U;H1qrjK#hMf!`7X3r)g%1VvBq&0W+wF8 zNv7^&M7cjD$jQ{aLHz6(qzuFoPCvEyDb^j#@Fi090w;$aAB%ypaQOk#r$9fm;VlNc zET{5P^#^pc9qk!5&AMZOS3nylSCogXLc&Kfy z;5XbG?kZ4hP2cH~=3*QQ*meCJMxnfEUJM;8hBGuoLLzE!_8ATI4{&~R-Rrgw_89KY zR_-UE|N1h4->C`qv;YyUTJ8!>{z0CDusSb1pvPL&7#A=HNXo2qaiA>yedbLp1nG$} zzS6GcqrbEQpC9}b>ON;_7sa{wc>Bqi7Lk=epc4IH_8hm8gdn{q&|O?PBFp=vLiQ^O zLs5#cX*dNxjOu$2rC|B~`+8=y6346$>jO*@%Qez&UxT(2=&diGbAm3dobFH}pRhV5 z_|>cY`RBhWh&WCF6&)W-OMx!dH92befi0Xhe6A2q*ZdBf=vbea@Q{R|vTKW5O0dsL zm6Kl$q$$Wh|Flu6CEYD_In)1Af{1ooq;slOs8$xZuMl$6*)@^;{@7hk%9c4pGfs%( zSc0MlYqFs;*Z4Ej4q4)x9z-S|`b8l=T0{-BSQUg;rW@-Hwx&}<6x2YeWiQw0xWDx( z8HWT|HB-d;<$pY6v3_vrz*-YjKHalzpB&R}yUAtN3wd`D`KozIAmA+LUAMt`GVRf5 zF;k()a%sN0|E>A3>a%F&bYZ8pd45_}gnfYgXFX9*7T21lu$9)rmwGuIcRoGdC%f-% zqGSc*T=r5nJCMfm7>-q8v}5#TSWO!VwVAU_o1h*Z;UF zW*@{38%G_`ur4zbKL~;T)odko)NZ(32E)mltXhp$PbC4}37u_**iPC)k}vX4VWw?+ zK&AV#aazE+S-wyCafP2y#Q-3#!e%xYU#^mF%sEUB=+E<8bBP8Es;5kr}0IHEebA&VA@91!at9eKc=YHK29}8MEOjd$^mWH@L;?bmsfSSGa`i$F6= zLh$02hYF(NiT+2&!lAC@oX`;3UcquIdWYAl^MoC>8h&k0_2pH`6HX2oKBjM{<0fc! z-N$VUfNv3XmI@v?SGGN;{T-Qzv4R0mSHJ%DXV%MD1t7J^zopQ5oqnB}IeLwB+gnUO zf8hIu#xud22DJ@+R%;auR)NEB=hehLo*n=`rZXyW67^FcG0$jxG}`;SkGm>Ny~~T7 z#jSz1A!d>I@e3z^t|+~aC<^aMo_I4`^DgrMhowleKM3b*J$~<9(?luDX^CVZ&x3)$ z*NwuKbc6S?>kNKH*?4gVKv1$6D_Vza?WIF`*g!TS;wE@M!%?nuM&g8dZ1y>NG`CL4 z;5>X>o#B0hj=f;d;UXiw;a4RCrx``%CNXsnxY8}6p}0(o zeqf=vGh45d<_I2N^Ao?TSPusII2~o}e7{Y#{Ex6RVWG$WBsmOGX4@&akfNU|iCU^8 zrG2O0hWMX;Cm{PIml_J5sAkwg>mB+hH{mW}_*I?IT>INj&$EZwP~K{n<8T_>~Xj%7z3OpMt1HN`_({nW4gYYB9EzsaNLnlFKbH zIa0`g@L)4EiJj|89GFA!qa>_c-`HD*$N~>5c)o_LwgL@xfWZfnAYHL&$Y%Zb!HwI| zmbiJe%YySK{1C#K!*fmTYzrm4e*;*+DF9D^`g`t^3W5Vy5%fhtC+0I6$oAobtfE;0 z9Q(cQ`e)?U&%cV0IGV@`|IH2f`Q2rUt>Z+0;UIrKm?jI8G!opN_W{Ue$OkgH4p;8` z2(KqbVKKhSK)cNSETWQFSMUs5$R@6J0zD5jWTOiOK6=L# zI)t0fPFy>(5n)WINEsPY-}Bp7<633RUf3%sRvpwHs^8%WVl0daA3D)Uj+f2c-eQQ` z)5u*o(n{|5wxg6}Z0z*>Oq-Dkm$Tx^v01w6|)TE z7oOJX$KO-Bnxnu=h;!1-1^CqpH-EnEkdq5D-OEjn&)$B}x^hHgks9A}%lIhVmQ>?I zJNowOmXy}{k|eWUMQThqg-D_sEuZ1OB)H~^Fd+C(>9XPowiYhjDx%+xm!%* zJe>`z-T@WyPtF)+3O4JMPVc+6Q$WAN|Lu0~gafJnm)cszO|wiJ0)Mq<3GJ$nVUqb~ zmwsq^tQX*;-nT{`xd+nr^Xl(rGQKRI7!8K8%HLX6+V9cAuMk$XWM1qbbz%msoQXhO-g5 z+()n9r$8IhgsLLAE^5!S<~pddp$Z#!q0}y@`izEUdqM7Ew!Om*B_iyHY*ehOKmSo28z8<177F2}d8wOyNPK{&e;j|x(MEe3eB7u6XqdmbcMBh5BN%4VLl`p zxz(a3>$xKtp4(e1qCbyaqYG<7;)MI^Pjhmj5S>9*ldl8kwjTs;)m%huesMMqJpPcb zgXRQziTyOUt+09}zd$2@nT4Tq!?S>h|BLVwnjZ0PpF<7< zUWLhDmGOA=!JM0?#gIM!2+zu`7)3sA&hB}t$y=ywPrY_kcUHEqqBK@p7=F(iS%I+2 z7x=(8eZ+#;Ux@9Vvr#y@Ti~FwOY`U5nBy(k*F-NHET?JxaN|N`TySMz2S~SjF zC%hwf*~f-;{-HWF*H>7nEZg0Ck;qxdRzZAkoqv9BeOQ^IzYuCbN$iHsiTE;k!1qPO zk&?I6aGWN(B*b!7+cw>G2Q#dTtCc(G~u}cRYFqarc>6U1}%4ZX8Wi zB@b(4c*0*IstKpm?FvSLqYl7a@%&@l-XH}OYh+R2__+I1Rr=6O8M^{gd;T$Afzc#t z^pnSc2Kv|$B(8?%^yldXzNF;VBvfK^>3YZsJ>fce)Zw5@87a@gHo4SlcBy>p8F3$C|$-lPp_ zd#*8=1a2oAlU{GmC8lDvMtnvp+B6GOqScbZb~;ZcjnBv9R`%3#duWDc_+YhO!@bA5 z5!QF+Ztfb0(z$s97wh)+uDp1jg%Gtn->$4Hpp<}}FA8x$^X*N}YVta*5(|AuX~P4L z=GVtVa!07>H;awCw$B%??~|_U7Ah3N>Q9UIDt8ui%lUogP9>%~%hLCgY_Y?wrgc{s zdn8UaWYwljM-q4Dwh-Y~(D5V6hEB4mIp?9w_93+%){Ug)QzIUroxs!i1Nd+yKN5^Y zkL|0X>cyty7sZS>hv{})mL*!=;p7fqjPZ8e!$;AhDS9TgF2tLBrn0$Us<#^Y=5C)b zN~e0>ZK|1vUd>v7x|eV4J?aE1U1DjYc2NKZ$sjk`{{Qb)IHdC0Sr6GuB_257_oZ*w-q`4kT1b=Cp@}uQMeJj;jeFY*yJaQgxVuanFZ11Y5JSm z1EV3oue3n5l&$wpI#|=~Be|N7_O#Bl-6<^bBv9|GWETg1h~RjkkCTASy#jjv^!R>`kck;cYBN-H?hAUf*@PT1=>1A#TDf%! zo0}kxuOld|<9C}Q#H>UgtTe~J4YzXN62+rXZ9 zIX@!B1@BG9doobkN+~WZE>8!p1Pk@Br4#14Mt`)7TNLEt#XQhh>tR!;vs<4TbQWrA5CKTq>(uF-m zuGkC^To1WqzP<{wd`aZ0&+Tk^`JX1APO_H&5wX;iU$yBoPjL>Ozro^P>FW~*c2WQ% zDg(*-8-9{dkujj50&?pbkcE8X?|WdX19YDN54mbvHYNeG7ZJZQ6>sL@Cdh}w{j&h% zTf+yyfG_SzihyjpORLyQM|I)j;etXZtCiwWo9n*F#FR#=$Y!MRuA7-XEe&5O>a9#D z_0=ywuG7OE(u0ETklojh)pgO5<6=m4cn)uKwIv9p-+IPnVa!jK{_5oVy%Vh$87m?R z^20wNDapynA2yP6+V96ORsbY|DOfI6TFm?ql;4TAt@6ufHYyip+W1 zj0FXwREN5?m{SI|>?C<{4NvUKRn-5y_@P}T5XUBxqxQXmvW0P|vuwpOtF!FN!fzUU z1qB2A78q55x(OU&uLfW9&7W_58?(^1g&M3=re&I-6Vb=WVby8H?wLvHT7?3al}d>< zg#8>TD%X|kx%OvT!)O%t@FbagX3@OZHFuHY|K~-XkQ#rel<~0#zStE%d<>!)PqxQ> z7_`|azzC%JV!f{y(9g^`p>J>$T4MnE8pqI{kqbsi_Kn#x;{Io#OX7zld?giy3$EpZ zD}TVC=(+Q*XFGpaa+seK1>+mbkCeKK%_9o${Z?-pyK@X`MNYrN)*f1X)e@bE#mm+I zXV5tUYJ4shtraO?Gz+GP`5+kC2*58g0~+8NjlcQD=Iuw?1`NV=eiBUc&mgHE)1o|A zgy&sWT%WYM+#t&@Tubaf=QIU&Nl(!Ly_xm&cABsYC zd?ouT1G1?A-ei6BZ8-Wq_?rEdg{!q00l!DL_Xc|@$;d61{S}!vvAGCvuRL|H;8D3AZy!yT`K|E% zd%j|mXlZu<)+gBB`W*Eg2H7l*q#BY_{g_q*w`cU;F?w^nDcQ{Fsq1jJ9nAzfWd5!x2hEks zYS?M*E$|(ehT(Yv6nExn;X1*@CSfquL+`vX9rl%N47H_WicQLw3pm-f{u4*{T3B$* zS-T|-W&CvKN~{~s5T|Q;%5RB*IU5BqB>9{l1f{;L?B$~crx9aBJrC@GkNuEq-RjiS zH07fpFCUI-TV5+rI*oods-E(YF7P)!a!&x+c%2ITYZ4&Uj8}bj*kixNX_5|`@I582 zvr&y!>WxG}SahFtlzE?q|5-(-D#*s$G-jVF@S>60DM|gq-j7AuDzUN3TfdF(i%?G( zAs=NRz%_O(TA9er`VU{z+MdV_Bbg+D5rIL55+n~YwH$NF<(-iHGJa{t>aqK}%QuDt zy=9xpvgR_z>7aFB8-7X58^X8tYjOnQ&C_?R0+7`EqEQyQddt{<5IIm4Dor$4nft0e zE8VVJprNZIhjY*-TsFS7kTKJTh+Zh2q1{hd*frffvJQYcI^Fi(J?X@Q=Q1R5Z4|%4zWlx#w8UgpiI*6>+-Xdbj-1kwtjqdM0M*wR3=Jhj9P_E=rydC8s(9~#sWjYgB zrd=c)5uC|*E?%r_k1_}C3=_%dWsI4;tGS8VebV738m@l-)f7#(_W2EYQOPYKDNV>j z)1FZTHt}Rrbi8+DlT7TidyGcO%-}bwhb)C8yPlL;M+c0Q!zHKY3$=ugL=Iq-@(|5B zh1qRH@GbhL*S+KM7e#PdDNUGik8WOX$6eiCE|k4neZ4S>J8oQg=eL4M07X?r!4FUR z@c5-4zt*K{sI&ff-BG`=(c6!>scta*-`Qh~?TU#5x#SX1+Q2Dwjx&;QKXxAK5JftctHKb*bkP_Iai;^au;LIMnSI zIz$x@ZT938H-<`M-6+t0?K7Sj0R6PD)G^y^Kv8Z++Z`#=IgBhrS}3vT zB6GepJgDuORKhd+%;9dp!{~WWg&GqHZ~l8 zkZ!Ez=ESY!ot)8Yz>--wiXbF1U`3p5akfMeZ^+NX=ldLkv(J5MpN6c%DK#20E5*eB zA|h!N0DkOWl|k@RG`-r;6j$*E=Vd_k#EL)Gfp>rGQA?#5?`jF8CFs^c-!iieV)RwO zhP+DjPyC`$v)Sof;spd^Z&_bz!^p|3D(^VU{jnQNCUG*C_-kf<56+?wXB;kFlCMKr z=pP8k3jrB`yOLAKa?8*E9@5w-(p)_#<*&AaQfX}`6s@QW@${|{gjMTzLLZLGqfefe zWI$OF3jGMoU`8U~F9@nFi8s`S3a5BAm*$n#6pAY2oVN2AW<`cMe2(8$RoPt~#3g+t%Ay zHgNv!&>fbpo(=hwncB+-yJC~z!i34~v72|2bB zERdq4cmHfsz90{&JLX;j5*_)b98+JSC!&E+!5wpf8FymghCk7ui)Xlmb9tW z&GZ*7ve24*euP)stVn=}mz66v&|dP%l}1%hM>EiQos6p~C=zBYQ&b&yn&jZuHuJ&w zURDJ~bB_mkN=1ylkC({D(6*Hl0TuD-Q%h0yZ)R-w@ zh2JYNE|iTh{*o~1=CrCGiS&R8di2ZM!$&^7L&EbabwvJloc!&b7Y0c)F9O;~kKJ#3 z4_T(e&4UjZgfz?Nwt|7?n{D|Pe5_bKBA83IgRgq!Xs?AkGqW09=U>Pkp^hjpGH?c+ zAUv}y-&V%%n&ad2kKHM%B~%};RUtZ44|`MDDbd>|kJYwbvIJ(^SI~Q>9{OO>IX1!D zT18ST`7|}}d)Ly-ohIJ48WcRDWv&Z z?Vr3CIGD*Z)?uS9;wA~Vy7{GseC^rp$ z4n`AlenBuk_F)%8d&{~B7pb)Wc@g78Tf!geT78_0^kXs2UZ?7^vb{(Q=6?8v^N-+) z4gTV)e1oOA=-;ntP)~#5K>RWN)>4WF9DoNK@aDTUVjV#y#Na6grY^z4i%`)(FZpsa zP@j>!wOf;OM{V(JcHH<6Eg+WSMFULCV&SC&k@Y>w@gj|aneaQO(^G!H1dmp z-ZgEI<6cFbU}Q_OI`7Cv*t#_b*`93c%O-vHURrci(K#BgA;JS;%I_uK&#@0$BpM2C z1mdf9>Gn^4YZrJne{DoYkafJst$DBW{%dWQ#Y8-iLt^Q`q}(eG{hHvUTqthRtn57k zo{Yj|5DRc)QT&WG2p(NUj{>iqM!N?Douh4|XBnToE>{795e|{&6AWPu;n%RT=O_ET z&fByzMgCvY?zpm>a{zPnF_c%&{gK_p3?2cuS z@MerG&Ik|GmjYTmU5i%!jmMZv+?1;>cHyCoSg3E-jh6-EcNeh?$B6);AT7LfkjOTL zrPe`atfR8H?Z2}X+Iz(;&4{`CE~HmzJH5=38s`x}E*ZUD2bxZga=3Kes~CnOiYl0r zP?RaOayK-+K+A$L1`K@xS+Tj=ia}Pvwg-OXChBwj?3RpsviA~4!S?|eg@oaM-&`_I z;@udlo@@LRHN_FTC~7M=XbxC8YP>)(C*V&gY3Rf6B$OZnMx^YM5Da0|9s+>l+a3`AbzCcrSJ#-A?4o z16nZxvqyd8*FkLrOalN6oOg-ARdf^f9g4Y!*tgDMcGozSk^-z|il9sKvb%BA^Uh~T> z21v%}!Uh*9{HpTgFTUW#`TF{df3K#Ur4#GEi=^v1K$qDS++2{Z5v+LznLtYM{JO@( zU;77ew~_4^Ek+wR%Kr!KYEz3rQ%Q6sAy)x9HM4zZ!Xu1@l8cmi%cTJ}jL@c5yy=$z zyxXcvcux={FP#{SLETZq_9@eN{$Dl$TUHJ*K4<;&M}<_UaPRw$XRmQ)9{(KL8K zENR8_nRgL`{xS#mLF_e1oSCu9O=4t*;2+9?8}>-3@l`ihC00S2*f9_DjVS7)DWh11 z!O_l8hi-DFY;626wG}0g0qG9iva z03%YbqnxW(r;ER`=p%{;e*3+k#%jz<*&11Qo@@O5?G+Su%z3xS-p{nN&#M;`8G*|c zrGbR!%UXs~On|SXB|y>)7@VC(MflH9V%JdN$h_7y8`*den*X~%jL=6wI_vSrCltUB zVuPpzUOOLe(Q@UFm)-(KG^-R#?%p=jY%aXp4QN8lFRHYi2^|Ig-+=&GQU+q4m`Edj zV3NLPev;FE1D_-S$u)Qm!2x80?uTtsW;GysGtnQV0J$i+MBd<|aKzL<8gyx^sTlwa z4PJ3@`~u9=SStqG(rG?ak3Rub;MWxnei)!FQJg;z%DgnS;Of|JU&R^hHSCZ2xJZvA z@frY-IE_ZcAW_;^y>`Bm0_s=&ulhy&vgF?r{JVb*{zpuKZO_1Fd#pHENWBgUuln5| z6*Nu+tr*&96g40#b4h;cG=C{Ley)tX)q)0Z4)l0(y4R&8{>NZjSO6N-)(?dPv<@jZ z&OAkE1=@bLbbDz=1VEg+SRH%jz-{mS@_iJ?X8^%Zu0oT>gH~r+0Pl7_>1q1^;nNkr zXu#_+TX?YsW>mTK#SA>>Wg>U-o#qPXH5F2GCk_~(b~PdtM8DaVs&={BEVT+YI)5a` z9{9!Pz@pydom7-gAH10=?@17T6jqaF^#gtH2>qoEleGj8&60fGD(6>VC+o{S|A!V8im z$4KN1N-uA2jz(v#6 zy-o%$S5C9h7H9RRYg5Dux>-$4?4*8nuXOaFC%7++1V1Z!R33_YXuNK11!X7>=|xt& z2|LP2a|h}0YsFTr^YgrCV0Aif2S^8S6Y@m~U?}}cXKy==uUH<+&WxuM>48b*9cnpL zFY`)066-y~ZVEM)D*cq746GR-!LI8YD5_;%D(OdPC@^X@ew6o>E;pq6baC5 ztln4jWK3d*v_zcWWT|k3-cq=zX%e=#QJezORtUM4N_WjViI)wJfizm;(iV+{4$*Am zu)^T!9pbu{I^T0O{0DvoqqUO;(dZU%!eFmlv`)`zVIzX28{IWYf5lG=g;J0clxQG5 z@-k#V8@a}IthMasbqz{~5|QcLMGay#?CVRD(^QuQj-7&D z;g`A`EhR+y`;5UfL?`sH&siN0nLw+)8 z=zqr1SF)MsNy?}!N<;wlo9mcMRa2o~)6g-C0WTadb0`3IJ@D-UZMNS8CQzse%}1AA zhq&P2I4FF8!9Vq!5K$?5$|^p`P5)Oso9os)BZrklw|$C|hBFLY>m9T!&|#O@#^ z7AbsTgn+MaPB7XKl52}`$EDbe?NTTS@i5xZCkp0(C{fyf4q|ysY~orRB@XXmD2B`1ZDTC?F$nvJFR#7?R!7xoT_twRDdp*Fvk@>5d9Q1M+~{)r8j%#RZzF^ zS^MXN!)&NXk}(!@huYuyF^05&5>rwkt~D4$wbK5;7564{mm99go{)XXF{4hNb$GL- z;b9Z}^>;?%Kn4htMkojVymS@0(bmgJ4SSy!qhM)9%G|7{74dxtrLVhm{>yd)*Mw_K zds7E$&V?u9X#1$yNAC7XQ}-*tSfFqA-WlNoD=hLxIoGh4_D9V(z<%IkOduY`i+GD< zNH_jref)}MK`rEtYEUXo%%m&vYLeOZa}!{i)T~zef%(QSE=BtuUw5_XE)Z3SKC!< z*&({A_F9G-I_UTr-WCjlw~gd%c{`g4cs6TpmN$2K_%v8|nP{|l5Kl>rq*Ake@~xg( z7@xXvF@0mXRwEkjxUl z6_SB;W(esYV+5~iEvZfDWt^RsGaqER{qz;U?XR}5N~W@K2iP^}|J+?S`Q%}bVy%jO z6p19cC@>uQm>aaBVevA?^IJ&^K@*Om&n^=#5~wK7)G$6A`BU>=~mu}wQPwZQY-vqS0l)^;~n6E zDy*k;-!Ksm>%#jYXpt)Y(6J>f7`Cm)%qL^7-WyyrJ?m69t}YKe_}VXoP~JyXZVUYq z6M@x>Spyj))k#^2W)QcFvF5X@QN#8y)^nyX-y`Tx&0?thCKP5zvrh1{b%^|fsahQJ z%1@)5cjrt`7^h0w>TDAet07AFjkv0Qj&LX(kkF-05q>W&gg*%gA(Wd@dA;Xa72L49ZaRMMS{h_=6jw2=|3DR!f1DyUn){hJ4-6bs6cSgm5M7(T_J957! z=!+!i7VJHmiaj3KCvU7fdfm1ZhTT;2`=`{3_YrVuFjxgL!8U{W;}wY{v9#kw|6I^T z{NCgk7%bQ z6`eZGZ}y)_fQFOcSMVw`rA7WnSN?I>{D9Sw>7pXT8#!(2L7iq&8nb~Fa-hck?AFf& z;OXcwTjS3f@c97D&WgTNv7BM%C(r-F-tTvQTbKZrA6jMK22mj2w?5oCHg%yPS_F}} z``$~zRU0O=Up>FuJflBJmK>IZTt@ECd z6izy1-bzc%e;464p(TPTy6CKk45P%R0M`Isf1U_@l4M9lg}%vI+Ua~tAeIR`$)N^y&T=-iRmNAF!RMftvp!@C95P^$$ z|J)-h9=+X=E+?0^w4*AgEmnc?HTY5X2K)%Nr{!XQrn20Xc3hHd@F~L`I$9#Ks#Un+ zv7)2v11s@Htl!#f7~B`6@Yz~T^Jv3ZK5MZ%I(COP0DsTCs+0J=(_Pkk+7ev(0jBfFq?V|84z5Q>pj|ax7bTN^B6@~h-o&QTk3K(4DPM! zHOQTrLlp}8mzw9+=O=Y8I7EWTNJla!Zgn4wr0nW%Chunomf6~$J0*gG(r{(bFqgME^b%oa?T+683NPaGW_^V=X1Qzs5=E~USXC1Uka_pnT@^L@lfV-mOKTlhE(tM%&MA^-ok22eY(7v zuv?2>aZ;13t`?0=?mJ8t4Hc~Cg_zOb8nn% zG_yo!K3%wJUCrRxx7638&+ARZPt=Z{Z9cL!x^QbS^cYT<7eAYDIKS9IXF7d#QLoz% zpJT1BFYrN}+|BYiN0}NfuhtQokXC%3Ff?GdXn z4`o_@T*WWVG@H@e>mB7S+^E(Sf_*z3I!!4^OI%^VudP|+dA<4p8C`0MUcI2mP8mF3 zrH$v9V!hIDXO{+OhZs4^%GIAHXJIa7-Wucb4PS&+e6HG%doCWKvx=O(ExB&nd>M#{ zqh#tk6%j0y$@PTZCbl!N6KCQkX}Bx zo75xv-WhiKyF+P%i>e^T24NrKSK0KE>Ji$aq9e1wZ}kCi*sZv71xTEv`!*c*krIa_ z2e1%4%A~S)E(cJaEdOBLVVoo#2LYOqOX$Oc`nI*Kdf7jk>`j(b+$sE7FA#8z*t$N( zW9f85?~MqMAYp^}-Ap=*pwf3be%G5aS$<|n@M!LRh7BP5m;N)*XU5vMIRAB?o6hB1 z+p;2+#_5x-Yb`H>1&KB2Nnk7K%jNH(E0UfC;r^2j%8BSGs|=|XG)%l33UPSxonL%3 zNB14n+^7{TuhP995<~x6{Q^iOW9dtfGdo-^tv^Dn z+_+GlU5$CjqEV}8p8>}X&Z!kAgyy|C1X<~hMi7SgX;b(~-hLAsm^TVl5fk;;af$)T zvRuf88wQ}9wf5*55r<7CN-8?CjL%xEgmf+nVD1J6KPR?TODwd5Ba{O|JlyM2{ zVbw3Dr2@(Fp+ue8DhrD}`WZnkFC~RRQ|?Xarfr8K!d)$E0~R=FDdTR@*B^c7sE=NJ z^M~1ZZ*>gc7IRKsmrP5&tx=l$B3YB?WuS;biDXGb;R58k+er$;lw%eHQkB{ooW6&p_=^6&80KJo}YVcb`DZCtfw5c%{IaNo(Z zC@3k`cKPKmT-bV%omim26m6im-{Vz4z{w(;)7$oqYzK{mtXk zabNX%lc1M1W=AvER|^JqHC`PVJ)p`7gB575bQ_zRCAF~$$Zj=w08_K+T9NS@bMW~@miVq(Sy@Z zL?GT>IV6qReOlpgOz%aRYo`!rpvad!m&`_`{#w|NOE3~{JY-4?S*+}OSpU(k@E)Df zzFK8vAk<@jO2IxUjbY=n(+9ZHFp3xK<6$^lF~H~UbQa)aI=5I7bw*z+^+WF}h!o>- zt%W~E`;SB+H`5*Ukf##;Q$`8;_4VU-8E05-2TNOw@RYQlmUF%8x_LmZCzhzLB`Cp` zAu-W@DqB;={!EQv>8U(bo~tj=dv&11_i)cEAS6m;gP4fqroP^NzZYEV(qkJLKdHw~ z9yTS*AN0(c zGsiZmExh9@2o&7NLQ7C8H;jvL!t3A%pHIf}Xe{v88WX}6<>65?cfP8lhbjq#xD>q9SDFZ&WE{p0~HlNt+UM6FX zzKFN#3M)}M1B9>YJeG0lPJ3PCadfVKK!U$Hlv!0+U{PPf#>3VgdY|s?Ikc(He`+q< zV5^EB)5)-EoAcN+4L;(K45%3CBeA(_-J&?c-^#6!D9m>6>Ore<(GtFqG7jil-2*(X zY>u=EGNo=+8f_Vx++@z^Z*K9f5bpF|t$--Tiia#pl|l;k;qVtN+MVk;jdSO_Bsayp z-onp=4b)vdlXDKYigH|q(sND|9td4mY}oGAULsXJmtxHH$4SmGuYmsPDf;7Ac7mmy z+o|z+=SF?FbV~YUU4c=M5mjOH#J5|FFljBGtS^H^7g>kNO_-!qn>4|qNQloTGTv@A-jcW{4vyg_Ns+3SqS1m zuDY=>T5|E`-kO_g!OCl>Z@@u}2Z7pxuSHsKCLtvDp?A(Ddb`~?&`|J` z{XnBuW)>#?Cu8y3cHwD00y-9C8;7ilJ%&6#TB&HHDCnnoc~~43qOH~w$rYMx#~C6T zMx7dHBY2OJ3>i=Ec)dEZ+qRE)i-WtiI6%v$KUw#vtG3v3W25I5#OwqC zkA6grRJART`SNqCM?|L>12p=E?@?O#h=6Y2r^+i}J#2&pZx+nvj(AVX<-8faj$RFP zBHmaOUN%^QWmN{6s*2_n@i(qK$nbEw{qv5fT8q*xvJVYT}Jt2s2+uR`o#3 z>-6y-1lM*HCio-)*S{WgSWve9S!|eoU^Y<~d|BxDW%MsOEe*H}RPWe?+CJ+# ztGI?HI}$;4jacia_qGUTBB|dow zQRHLaQngH zk(l!P_}qTwRJLm*d^P#Dl0C3ooD~82!3&KoiU5xVA)Q&Dq0{sxs8yBg&!rP$l^vhc z3X#OpZ1-Dd@fo5yhd|3|3Joy}FQaF&2-K+KW?8@NE1aY&9?$+Ubbr+AJt+1s8FdR6 zMV@Z)w1j!ZpQmW=8wYrd?#9SrZyV0)veiv}IuKUca&ECo2}_!{@1>?XNi#gNMITJ| zgu?G)9muWZw^@5Mz}W&;v1Kc*8=Pxko&FR(gIqJ^Xh2s`A7jJ<84W$6Axi(&;@|uY zoB*iLc4b$x*faJx*Yv>AOvqDvSL}0a&8vC+(xk9kgsny*4^OK0ed^&0!4gC#jNWOL zkL?rE7+|f%sz>qa(#UaP!S$4f?7s^u~mo!e7CR5?G1I55!SyTM>{)%8oi+-EQ zy^i%-8(6$by9M|qYdSwBE$W{~E~rzib(-WYR6@+E(4)Y71R+V^=Dig>NoXo&i6h@{ z#JJ)Y5BRWhXOnz6bWcYHBtE@}h5oO@1Q<66QlXwKADp7mz;BV<+GIivboKMnnVtLlHiHJ{{1f04R@J_O9qFR?~^CZlYUsj`_L6nZ9GBO#;^{?Jdau{;b(w?)-iyR) zH`g+fH0Y0ZYN|gvuRL3Aqg-)M?`Qda^%cKE)YDh+@ap_Fpw|g`1Vbzdl`IyR`ZSkv zKz`^N{qpI4YF-j$W6uhzybj1V0ZgLy?bp1cL(B1fB!35L2dj`To)d_#z)D6R-qJm> zKZ7}(MpU%UX6m|jbM91e4PJY`LiK6WFj)HTl**INT}8PU332CYvvCd#O=7VNpeNCHK^T|)S-&Gq#YD%W93gR@97Pc)WRd*a=`tRse zv{vTK#@Ctwqxa7pKKBgJKDqN=3V;(Xd=oir&67+SW4m&xrM zy{EJrgjC`F@XF-cEVuY+Sw<(%E9X(QKZp-_PtUZJGGojqaV&JD(d}yfzqYPC9_p=) zmrHKE-iy3QkucdBr9^hRk(p}9SZZvAvNgPx8Cj+xw?x7)*OF<(&BR>0DQmbwlYJ{Q z8n?1^Ln_j}WO>h-v2@?}^~ZdEzw`My%k!M`oaa2x_xt;~ytoihV?KnpBERdjq}P*O zbPGBYhP4LDI()pas%%nuVv1@6w~odwW)@?<(-ieR;Rw%ui<0PY{ z`oUvu6-C}OqPj1NtW+c0|=Zz?&DtwJ>Xe6TC`P*=iJBfG-e)8{>^ zo_k`_IvdJeb+7E?CUGpCq;J|#V{pdx?Jw9JbF_uT!Ur$rG*6w`bGomF%xM1fb|^RX ze8%_4Ol&_*-2;cf5xg$UvIg?q4Xx>}4l4F@yVAy~-UDdFMM9_-wmCAnc3|eB!;KFZ znXNB0dJ4ptmvHz#b|1e~wa>0nLtjTu-era|~4F%Wi2$J;$RLFHG5R6-kRWd|sYlho#3YRR*`F+{(~#l}T48|EK$m7a8-_2pnl? zktV=9jhzh=SdMU7d6oWhvp(Q~0m~l*1J3#(?&tMuON*_^G}q5lO|*!aFh|X*J`!_z z3u!Ui1Mp<6-69txynf(ZCn!rD1_5H$*PZn~Uy*$*g_;wHp@5Yt$&*-?eDIDw7hPgX z2A=ClYdTD)}y%_@skmxe@_OV0bDMa?m#fKBfL$rpz$UH*kDQ5ZQ z2)|OJI|F6v$UA)p3cHxj`-n)%D=06mj<*Jxq10!uq_*MmKF6)>PV=QE(p6#(=srtK zo$b`|iJFlxa8Fk1ulN#}fmO17PrQpzH>n$Bu?jHw4}_xM+v0WosAbx-1Zg#2`VhAN zb#;7U#e8IqU1{Ec$lIk<2Q=Zy`~vgG9-WnY=Zl)e2n%_KuZP-Qi(AaNO}}`*GF7zq zi$zgef(_bMm5U@lFtAMC(|bUEFOr;xR?N>->fsC|GmHCvvCpxu(Zt&Q(r*k4{wNS&#<^>YoaXe0#K*`v^w}<-{V%!htfEioG;j4M%*&F!u`S7gkX< zJ@~y10vGz?2*M{N@=*th;?3oxUpGXfh@n z>w34e)**}|@|xhJtKmHoG!+54(lu%tO+9O0!f zr+?Dq_2}#)BXqrB9j<Ny+l zbAZvM(ZlI@NXIjmEpP@Y*fQ6M}kmpul8p9}5H^j*t-&lZd@H;q(p z#Myez6>NuTzs-WuTLHE9&ABp*;~C$;6%`L`USbS-1V0IRo?tC#FEdH@+O@2nur=g_ zZkn-qR}86hB29Y(5w`y1 zlfB*53g+5wCpzV!+vA`(Ti&hFMG^zvr49fTI^=Fa;?mN1-JcNb{C$v}?oY@XCg@s8|yhtPO z;PXyG=eHfP1*7DjGk1@p`h}l6NjaC7K z#q@j->;500pv~M?Xzu{=yNcIox5lA>3Sk`bS=%!dtnZponNi0Qr=-!TRQj7XiK1Yb z8ra{b%bg>MD$&vr``1aA8_q$60{{u)B7F3}Dpaf#>_?=!;mSXoM09Z_@kI8~1B|)1_MGFH=bHb&=$Iv_k+bst( z(~#NJ#++mEXgn06+$tklE%|u-jTc#2~M5sH)5qXFRsi!lyms_2hEUnP?8%>Kz zLC0RwT&(sK54pZ7$63K3)3iI}n1EqQZZmk=tOg(jnUmo`y0Bdv0aSr@Gz7*3VoJa@_&j{z_SUuB!csj;3Cj`I(4 zFqmY;uPShIV=}LcD;Y%8;zo}IXTpxDC3&g`h>4n~!yLyR#ccoduuN@}A;Aawf}mUb zEBH|&xrHxhVMcaMG^~MF&M6eHSzJU#7jYjEq0#?9i+HFiCns+NB~gJJBgQyb-h3dLBi_uW6NPV zhct#cK$vfe3gZ*dpK$-rnm(%3AZwoN?2UnRo6{=U+R>5}i?(#0S(0U3wak8M2rz)H zaVN$=FB(KvnIxLEsKIZtG;8|vE&%Df#z)Z(KuFl#4uMa9179Hl-8rh3G#Va!@{2iQ7}N?O?rS`adQvlzk0&E?MH)fAG3NVcxx!guiP^Gnb?m| zD+(~#quh21PNn-oWR;GTR9f9}(Nf+cwfwb{xkze}_+RNq5hN5PDzv6{LaNAVw992D1N@GyzBYh@m(QxZ08|5_@g>vR;<=3ySG|8E!q;6NQj=Wh@8#>tO!N% z!mBO9y@&s`ctG;KSi{W?VMz%z4`xt#lR;c>gEqCU0&(~v0xK;YI@C&xz-+)VD?o6H z{Y?i{y8puFrT&h&-u+-ZWM@nO!GO&ToR$H7pYn3|#dYH8#u#-@gMi~T@HKU4qa8HG zNAz|vnC^guVs_R}K#rOK4Ej$fW2og={#zirWBnBhzVRN`tk#4UFzC~cv0tFg1<)o# zLj%<1w}%VzFmMt_A%q@NRN2;P&TS&R`hrne^!2B6Zk_}V2&0YIUD^S DyGmMe diff --git a/2.0/documentation/tdenginedocs-en/assets/clip_image001-2474914.png b/2.0/documentation/tdenginedocs-en/assets/clip_image001-2474914.png deleted file mode 100644 index eb369b1567c860b772e1bfdad64ff17aaac2534d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 123083 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 P`1eFX?NQ-Flehm1m{MTU diff --git a/2.0/documentation/tdenginedocs-en/assets/clip_image001-2474939.png b/2.0/documentation/tdenginedocs-en/assets/clip_image001-2474939.png deleted file mode 100644 index 53f00deea3a484986a5681ec9d00d8ae02e88fec..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 76395 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�QVPnUx#fmnA({M&~Kvo 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 EAGy)9l>h($ diff --git a/2.0/documentation/tdenginedocs-en/assets/clip_image001-2474961.png b/2.0/documentation/tdenginedocs-en/assets/clip_image001-2474961.png deleted file mode 100644 index 20ae8d6f7724a4bddcf8c7eb3809d468aa4223ed..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 26668 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 diff --git a/2.0/documentation/tdenginedocs-en/assets/clip_image001-2474987.png b/2.0/documentation/tdenginedocs-en/assets/clip_image001-2474987.png deleted file mode 100644 index 3d09f7fc28e7a1fb7e3bb2b9b2bc7c20895e8bb4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 44889 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 diff --git a/2.0/documentation/tdenginedocs-en/assets/clip_image001.png b/2.0/documentation/tdenginedocs-en/assets/clip_image001.png deleted file mode 100644 index 78b6d06a9562b802e80f0ed5fdb8963b5e525589..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 69060 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%0A2yiQf;;tZ>Cy~(0|rV@E23hi{qry2`9M17dD_ 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⩔{t#cJm{g7{hxrivKItEk3H$RlZr~j6G_f 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 Kr7I+j0{#zPf(Z=( diff --git a/2.0/documentation/tdenginedocs-en/assets/image-20190707124650780.png b/2.0/documentation/tdenginedocs-en/assets/image-20190707124650780.png deleted file mode 100644 index 9ebcac863e862d8b240c86dec29be1ebe7aa50f0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 21589 zcmV)LK)Jt(P)4Tx09b{Uc?DEdUl;GWlguy--Q6YKAl==KzyL$%(4dkcp&|$q2K@ee`~$B-dXG1`U!%Jr@AZR8nMQD1r`vu<#g) zov|LDi>n(Sb_zfM1!#dh&>;CnN9x+xSOB>EdH;7=9)`K$@=R(|*8jHuUkkk-IocNh z$Ogtfe$l>RFun!=D$_TT5(5B66{ZWu$3$*o4;V91U;|+sxrqa|aporW*~TZfcpU8X zVcY-!6@f&e1OPy6gXw&6z5%ct;tRNqA>1!09A=$|v6gQj$qxX|T`;hvk zpMS^+_%E40e`S(L0e|tfFI$DmASgOAl$7}YIUN7*5*8Z!M~4Vp34s(7yG@_raeEOG zVZMn8FrE+hv9g9S1B`zL`EBvT7=aIrHF4bLM{xN@>%(IPSYRycM=~&nF&B)D!b7br zcIZC-K}M!9hGz&OAt=VwVW)34Ioi;EM`i^j!p`~+_NVCU?(}UWQMUAM@^{6CIO^`m ze-TJF{UiT-QlNwLw#`Un_xUt^0 ze59v8#mH`lpAr`R$6sW2V34WR4laucbTHYG)8I?mvY!pcZRBuW$3Jq&(JmH$eDNb2 z7;gKH93Y1~?)ZxwkBrf?+v)o?GSp^=AB87}8gJ4CV9XUAXTQ@Ir4<8D$Zh#3tH>A| zhiyAiKEWh2n{9hg3BUsA0|USZV&UooB0w+*>Ys0&hktFi7y%NXfB--SQahACJ)E~% z!r`YqNCKZ=LMGL=U0I(J#G%(kcJ)hYwhSaae=Vj?X^-^cf`rOI1SYp)_Inuxu0y ziUUZY6k$!eC~a7`5=_||(5t&E{3J8qh(}j0_GM{O< zukzm#7tq9uvjcRRuZd;wZ@XLG1x3@DYgN78~YUd z9{ZDunu?c7p2~>IjVhcfovMVYp6V9WQ>u?tt2jEGFist3jq}4L;_`84aqYM#xc9hK zJUw0%uZefS2jkQ5C-9B+KEZd;$p*ccRM{|#6jOHhiktj_xCHfIlh~>l<;#1;hS{$t~ ztuC!6Z4zw>?N!<*wDWX0IuSa3IuhM}x^lYfbR%?2^o;a!^w#uY^oQu{>3iv?8L$i@ z42BGT44DjP816AlF(MfS8TA=`88aBqGIle*XTmUvGMO?3GvzT|Wa?*HU}j)eWOias zU@m9A$vn=2WD#L8WeH`;XSu>M%<_wsn^l*U%$md6$oiD^2OB4w4jY**m#v9yi0v0U zAG;xY2zvp0EBhM`6o&+dEk``ZNsexgc}^xy4NhOqT+S<;uecCg5?pp%$y{f+`nZ<3 zdANc1oIT}+~S$xW#rZ34dN~0z0Etz$IPe87s_{nuZwSipNrpw zKbF6Wzn_0qKvcj{AYGtI;Ef<&P*u=hut=~|a6yPy$Wmyp&;_Aa!Z=}7;XvWz!ac%2 zL_|fLMGlIzicE{LiJFQgiCz#L6{8W;7K;+A7JDv^5myxt5w8><@ftMq3XAsIKB0+}9}-?B=w zp|WRXU&}GbnaQQgwaa~#myq|BFPDF=K%-!!kfPA0u&5}hNLD8q>Q) zcawLY-94o#ph?oK(j3>~)AH6jtu?OAuT9df)}GW6)bZ1)(fOz=t{be|p!-=*R*$0B ztoK7-U4Nhc9Rs9+u|cjuzafL6qhXohn2~@{fYAk`1!E=SWaB#~XcKdj0+SI_Zc|^= zI@1L+6|;S2UFHOHd-F2$Nec-JibcC6!qUw0nB}OIuvNHKt2MATwLWJ3#zxd8%I1bG z#@5ER-1dW=oZVi#9(zW6FZ+7?Wd}Wne23SLVveznoldk)9!_;mKb#Gm3!TSZWL);S zJaXl54RURB!@4=S)wnIW8@d;}zxPn`$nqH8Bf2MHPp>D3XQ<~*FIq2>*Hv${x3hP> z_ZrEXR83m)G4-kNS@6~OJ?=Z_r{h=TH$&DW7m`2vYx)=ZPX}lQ91EBU)DA2OoDb3u zDhpZ+HVHlz{3FCVq&8$D)H$>%j4I4K?0Psucu06x1W!al#9*XkWLD&OlzLQg)B?qv zQWFhD?}=`UVS+F0eX(M(2Vy7UwBpL+e#Se+UrnG-2v6uslt|1;{Fr2vbS@c{?3>)V zmw#{C-idv>`>OUs`+fFzrU<5Fro2xzPCcK7PYX$VoGzPQnEpM(Iio$3J2N$N>VWZq z3t7Z0O4i6hjf1DMQQ1M+{W%Ibr8&QI{c<1X$>x>htsU|`^zg9U;S+~9j`$zx&sWYr zc@%Rr{OE9jcER~V`og5bsbiMMT8j9Ja*MtfdlmPVD3+W$jz1oIeEfvPiMCRq(xato zWr1Zw<$C2!6v)@M+u(Jx>z(Zy?aeo&Z`5}1 zca+~`zL|due=GCW#_gorOLrpg%-;>TJJspc`TCyAz2{xFUH#qW-4E^?-M`nP+jIMY z=7Wx2_1^0bRUfuKQhwCZr_|T{Sm|+dzjA-e6O|`z18M{9gS!WBJ=K1C_nE=7`_E0E zKN_+c8XR^Uelg-PGXBEv#q`V2my56BUah`P9Yv4kzM*?lGR8Gl{Z{;K)41~Z%?X2v zzDfJZ*HgYzbMKLgmxcF>l*Ns&hrY3YtNpI{y>rQCX>2)cdG$x`PxhbZS5#MeemVd8xEjBPT|2QZ zzTW=Z{P*Za*v3XAi9*`C3LxQ%@b?GcYb^jYt^hC&0DyPj&hvH(625#O;I|WGh|oo< zqS(-Q3>8+E$`zM^zfHiO`9Ip;vKL4N~UPw*Y zRU||-Ow2=EPl8)wQS$z-QmGJWO&J=Qx3W!gsq(f8{0g5GuPYr;wpHO$d9T{2mY}Yy zf!BDpyF$}XYnRqn?N*(=x_Wv9y|?IU9W>CM7m2t~mjfNKU%57wi++ubyI>>Yf&xek7wfGx>nx zfvK$ggEra1In=oz4{?b8u-Fl;e5<3*1#X3I$6Sh>iXBR9k6WEEFEuXHE7z(}t5i5C zbxPv2Y?XO+#+mVRrZo+D`4V)f) z`HcFx%#i-D>4@PA)tADrh_6;&PmjKMb9d~_+l=vm3CBsRDa&`(@2x+WeN>xfogSab zomHG2pF2OF^vUEi)#th|#$Tou&MYQ;_55c2-Et{-x%212U#;r~8yh?EmqVhEGpKR& z6lQ@6iBrZ0Qdbbhi4wH&boUw9855bFv&gfiv%TR^;>_Y2;NjqP;VatO8@ydOaZ&Zj=)Kr3$x|MTPtW_CRht*2e z-8Hy1M&ViDp~bE>qJ3P)T~|bRRc}cDvcVxkve9m1dgBi!9j3)*apq(TAIm_i2!fDz0qsy@CJ-0^pa*y0SNuEJoF5U(t86P%Z$amInh}`Ah98eQj z5|kMn5#k!E6DAr?1J8ts$g!yJ(fl!9v88c$<6k69CC(?U?4{nvvtKNQFBOyeHmx~5 zKZBC#dB8EtH67i?PVJ$H#9>Je?eyntV6+0S!k#ZDw$eeqQ#I(r1w` zv|oNMd{`X$`taNJ?^R1F%T7N;e=Ps(SV{V&u}WAoSfAO6zce(5s6=|A#L-yvB4!3V zOErmGq{b73X>^Hhv}tq=^n(l=Ov22DEWxY?*iNxug0>rW6wGt*0A0@MPiS6o^@|6bCl`^|!UdYD6x0@z; z3;Ah<3`HKrHYGcydF2Btyeh5mtz}v*MV&?cf`+cf)7`$iKWipyVYSM&6}5+Tl5}}= z+w`pUUg`(xZx~b?+8E)C?iuejQ8bw~tv2&8XEPtRD7Lh>qP6O^&alz2`EJ`}7h*4J z|IVSxagP(b({ty17ZaBa*Jig+cOmyT9wmFM_AGlAc?o-6^Vao#MN04y@Oc66BY|XN zf0Y2WK+_;na99W_R6C3=Y&85_L|CL!6%>CXObB zCNm{J+k0c*t^Hjo_foH?)uoqYWMoDhaL+P4D3OiMex6gB>y{^!w|Z#&@Z%%b^G_e$ zU*KM-evISTO3`rfm6GGf51%M3ttz`(e!t>H%~uvE0+kDd9KJ`wYique68hYo7(lr_R<@dI@)gDxYc`m>8^3-^)CDF zrJj;rg@@1k4)=Qxm_F5gt~VU|k~lgy*+0AVePuKL+yD1%7K}0g$I{>oH46YoZ2$_o z;5>5(&O7k{*w6srpau{k{s2Mf1CaW}-}3{4Pa6!N2K0ap@B&dF3)JB(*&4V3e-I64 zm-*l%Xau*w6EFe3!MZV{r$xad`}Y;hk6T}hE$#9gaWpQYc)49PajCCkgnk11p;Dk*+Z zYEv#$NmTVyvrw1SVBJmBl-4TOk<>k`*Q@`J^j-pQ`btk;a zSjq<~51%qVy;Pllmg!t}&GPw>x~~_GUNmf?zqEMe!?o#_xwen(Qyq)9S?}uK^X&HS zvG3J>B=cDOiSl6hv!5fVSGdtrZy6_Uy(doZozwl)^kwy{@^_dm{IP%l7yvuq2NFO5XaW=90K7pMNCr8e6x4z1;1PHO79cdl0m*Jf zKM^W|E1*0pW(oKwLq*NAe=QkY|zeC}mV8Y6vZkPD78vu`kC0Y#?@s%8;rJ zCxffUi{l%p6{&9%YzR{{2}B&Rn3kXR5}d!jrjKV}VQ6J^V*JFkj~UN=f<=nuA!`I1 zE889RAPy#uJDd?*LR_QVr93XYY`ib|D*62cWCelXbD;~unIaydif}GBE8Zt@6+XrC zr81=V%EZX}%IU}xs`RL~s8y>U(n#7Jrx2_H_>`Ab#b)ukqM8I_><%I4(wM-Ih)3rUX+PH zkeoH2P0E?fOFAr@k2w0K@N!XHiQ@6ErI*WNE7ec_I$cvOf2Q*6#~RVv!1I^tSua#v z)NK58sq~84)&6Eu%W7M7yKM)!S$Esw&SK}OE}#4A5BMLV9zA{>_XIPL`;_pkddO?U z@@44j+BYA^c_(e&rG2?FWzuiDYHn`PVkK?eU@L9c;-K$1>>TEb zcWdx)@}&2s_VMy_C%+5O2+Rxm5MmeF7j7BxG|HVa9g`f#6F-)CKl#qS$`r@cU+Gnu zPFcJM7jkaq9XjlvZ(P7$_^8Ogc=>onDScUWg>vQNQ~p&@b;ViLb3?VUb)5AN8d4gK zFUednx|Y&X-Im|(+QE8rF_ew za{UjrA7wvQemehbSz%eBthB7G{?hrC`Kx!8xN5(8e05-rYE5S?VeRtT%sT(N>w4k( z!}aywa=-n4AOHR6_wNn44f4i`jlRwJNBb+tZyg^HK@R}**v7^;5dg4-0IU~mY^+vq zY^w(Aafi&<(iCu#M`0?wrXejq0 z65=x=#G+t2@u!Y?O#rD2$FIlaUUEL|Sn|m|0dMlP#Pyi`re056lY9Sw8VrVvNF7To zl}ouEc&r{s1HX>5tkI}PSHA^)!v!Q|b6emkMN#HJW6yjS>8hT4m<)OFQK8xj8>`eVVIjqX)JG z|Hkd~qevv8z^G4*3cWr~jms>}p%Nb~Nob960Lh=MAVR+IP$fB+>&a<-l}WysJI?jM z6Y7CS0KY)ngi|lPfMTZ!_wV;2M2>WRb{3&f1o`e#oICX#R+i>)`N|ChIY`WAEApIn z=nY0hI5->@E5^siq2nM3hr{G8jEIqzkC4kY84Zb*W*?WDC)CNgY7b@)>>2zrOB>B* zv>)j}O_3dy)peMj7{Q0XnL~s?c30NoNOJ?OclpqC^e9U63*dA(QCOG`+Knz zh@if)5q6UaeFOcdKirDo$}|EI8}cnCT)A=uORE7&n{u+9g9(>st5t@=LiZo0zLJnK z;cy6%NOYay6)Hz(AR|E0k9T1ajZICMpBP5Z;6p`}8#$Y=1=ipysluDDUPQjriXyiY zLn9-A$qKJ`0S$*cP-Kk4U@yhVXQG;|3JTl`zR3y~&K~nnncu%lP{8 z*Ccmr7$NYTHXB!nNjUXJOpOj>b#5H15i1r~ji|2c ztCfQyL?)MlN+FqKHIW@O))9-6M<^=B>lZIzdG;Yb`t&OF+*=5fPtfT$NFJH-^PEoZ zG*i^60!t)(}nszbZ)J21yQ?NScUrW|M@5U{DqFx&T*`=p_GY&ya^3O-2r&plXV= zVN+eax)u1f^75SB)8_Zm^6y$U1=L!(oqu=u5L&?<9-MwF-`nNxmi5LjZh1>8-||L!8AbL8z*3W3+L(Vg-__|2u<&oo zB!eMwLj!W^uU1Z=5(oqm14yoFCAAz|{chyp@Y*Uv`ZX3w&ACxaQugFbNu*cu<)qw+ z!^BzLy>Q~n_8Hc5#t-(KF{P*FIa=97l_`&wtDD=$v*aS1 zZpLqH+}?CE{(y~}DfK4ZNPlR&Y@$R;&cr?bYGpkN+Sj6Ix^aOZqj7^(Ms+)=v*yLw9P>{w!%7fbpP!e5V)7hBofh{@lHT*#p}Nbq;20bFIqtKn8mt2mTCpX0EF2>VX{iv+H~1 zTARTh$bmnDotdjDyLuo8{_Of*xz=W|2Xf%gU}xs4%B~*RR;5`~5B8v~@?_qY8+}SK zPHIomvw1QP%hj5x9uVzY`EHrSj_l<|sZ5!Xq-hBxFtsK4MdiU}we1`5M6Ms9s`Tp0 zit5aaym+pXC*A`lTIh)yij~;ei{92=8YJNNE_e{|`?pcHq((xDR)kIidCCJ~#FdTq zB?d8{Wu7$fs~J~D2KDMQqd}3x~0C^?8!tNn7#aq9WE4w+9JOS8aNFhE5UEr|#79 zdjh{yBSz|mgjJTjySO2dmy#qST?Uj`TRkb`b9qsDo?h&G#Z8K|fe%gA_SCU`azpZF zYS~pUnEPkF2jU8k^1WlU^NuKu+x44U9EeLB@!o-0c-q??D~Wt8`yaC1e%Ji znDgu5pC7}+@i}FRXtUcD(1HO!Lg6Uv4hvS6S27DcK{-Kgwpd`}-!e%dBMst>dNGCx z!(k_HA{|WNudS|fL>OVEN#x3!UwL^;o>_M4h}^y1dq99+SW=GDCpt;q7|?gW3q3<) zq8FcDnBPpm?I^Fo+pnHQaCr$|efb4e>A}O9SBkgaI*$+DdyftaR#;Yt5H0$SoH&U_ z&f>!py|{U&R}F^risM&gg0oodv?~wbi_brYKg`LI?W=1#gc4UC2i)#t`>x;@yIL#l zb}zpE3PxuaF*8<-S6(l}^87MvE;|fn6Bef@VYIs7&a>eC_x>Nc2Pa_O!^qw4#gebf zc-C`eakEpb1iytYP9i!Zid{~4msXHxqpfg);|V(bFj;J{(XI2u_#}KQ91OA~<w_d`fvXe-qoO@3Q`{;w%T@=8+Jn&vnvMt-8;+omAD6D(#PjFQBfPwb%FJ8R+KHCbU=b zBOd=)F;MKtg~dhWJJ@+TlUi=A7BltzR}iFE32}Vo%FpBAFw=3CPkDmKa5EnNMY6mG zgWint@(OrI?_vRKIM>+-ht&elGJP#=vtuMuJA=^-nOfq^kNSFOnB_o}I? zhCX6Op{^@I!-ylJ_`%vSRzxLbGc3VtzEpB;M$&qyC0^z_5b zrxd#Tu}1P{&g)Thm5F4>SC?<`Wz3kH@$vQV8goE@37iY#jp&*4+MwpFUM(IvP<^io!cBnpgYmYq;<|KIS>J_xql)y|oklQz| z69Y>md$vZtfqtG=rpHJLxDoKpBj7wkAtch^LJQT8iRdaSZb~@JwMfQ-6gk4~GKq%+IfjI@QZ0 zGOE>0TC~*?lR*5I_fj8}JAb4ekZ&M3sHm)jne*Gk#DrorweOvmm#45}Ch55jJWgEV z%0}{tIjZoG!XwBxlu1nl79vOyenKWq`EDXOF_WCul4pL7a{jfn?=9`gQ_>!ns!uj$ zBb)$d=t48Fg^`xjZFe}-bENF9Gru%INm%%6Fqq@*A;6z@N(OTr^V`hn+gyIy?R^%X zr@jF}Gd?OatKcCKJ7K4nCBG)TnwFA}wQKS#6YirXX^(Hwi$!_^Tu;0vgJ~~mTkuQ8 z@`C%4`0N~p_oe4|eW>6 zu#(|tsQuc*_WVl*mVFF6Wx;!Wkv-R)%lO24Kvn_~JcusN9w*=3+d>jZgf42p2`C;T zN$F%frP2Ia-KnEVyZ%&uxl|g>lnihaBbTzH2ZTxp2iFj#vtki9uG9P(YJM_kAFE1f zXkrj;Ir9tfEs9Qiypi@z8>y!se?9pN<+b54NBcKzL$2JT_5cMX6q1ApnTVhJEBi(> z@6zrhJf(qOMwl!yCX+?R@4h6HEl+XxGY|VIy3DNDbYEWRTkuek+~m88xbf+xx&deZ zg9`qnZ;=Lm?Vb#R{Q|$%23djjmHg5glKb7g2NIi7aWC77y57CaKIhmL{F~avfgp^G z0CB$*#w2`El(UPpL7P-WdqXq>WuV5d$A@e3v1FFL2}Qsqezp9Y-Z6Lbt?PkZ!7o4) zwb7DdH-hxpKQ=z0)J5a#0tW*DB^wn&DruV?ne0W8IvL3PcAR()?TvL9dpOLP)fTp= z0QYa)MECG8pKVexzVvEq8wgSZ)y(!t+49ONta|3KxE5fu#PcWR)07^FHsN+VlbLM) zvsjmqIDvq;mglA>dBZ31-JeFk?FxRGZOx>?fBQ#2#e=)oxM5+YQGpSKE*F+$gJH>! zii#ri_Vh3;(dJ+lnRo%2#UtFtp5UOnaQ-x|U%!ddr(eL(&^?@g^;HMdZ0W*9HvzVm%MaR*0^xVCLq4BAGTgfufH~UdX zj1!94>OgZ#tL&#@Y~&$U{8TI1kH$RaGj|2Qfp0ZAI)?GFDctQH!S^``VrxG5JzgNc z7-a?dBr5_~n47}L*euDA%yxr-U(_i)bFU?|pCMLSR_gBiX{3^$SIF34R!ou>rGDX*0Vez`Anw4WZb_AA9Gt2fz1gsP*2$*Y)M*?p{y!@Ib|;MDx}db#12E@X;w;0ROeUt6J#uU`!k#Us$;zzU76MO`RNvo}4B>}6%4 z011UOe+y8WwUV$p+OK!d+UJr7lS#=$6Vhx+TY_I2FDt;lC1GM^7m=dNwNm{P{kE6dB=wI!m38IA;CvsdE6OXs-hwv4{sLA19v;eP)l zimV}gcKHs0AH}g#r!hI$qdX5F8bZghQ}Fd(#aDfU&{I!kKVN^}`u#B*IL1?(pje3g{L9RY)%i^aofFq~QqNBV3zk2UObiDW)j?#!aM#Jfl%;4Pg5BeUWxv>g9?g2RIE~C1< zkm?abO8&nvH->xMxsGz6UH$Y53iFC!rwT`0cjdbonfHeosVS3{knGXX z*NeDF3`rcVsibD;x@Nt7`fF#TGf*(~CCAjqIC(sqR;nYWP>GD;SR@Km= zXc4z>b#e1+3Ab+F#q#0;Mn)&$vO5U;UW`r8Q%!^9lC=O%iw+|r<7(r}yRw8CkB7{) zkbaqbsb{|~5ippz$C54SfRjCIBzqPJ!ng=6MBk9&M<~oep(Dv7+L7_CQvUJz+XJDl2Qk z_rCiQb#s8`)+2Dx|Ks9{A6AMl0|aqVp_`&hGfq5z21Voz5T>JA>iyVxU!3T=izxb} z^vFurigvR&PvSL}3De`7nIcqif~&kmP<{J{Z@dZ5>?D@=QQVu2fXgB+gk zk&piFyC|(`K}nttS8w;?_=zJJrR1l!v4I0)S*;+WlOEKzG~o^Upd9GCjo*BEEn&=` zjd0Ahd8ZyY;L@Jtrt2y3S;G=#`e7=z6_l31<#wUrP&3M$^xkZ?Qc4p;@4z59siW=4 zQLK0#;`Z%sk~A^8GIyZ$a0l9t9HKU-pZfpRD4_CN+u=4ixx2f(9KyuN1B^_}W0A%% zcW(5ern)A+1D4#3-0?Hh16e`#kmTpamJL-^73_FAp(RP<=gzH(B+wFR^NGn(LeIz%OtJTX0i+4*Tapt!U3 zNC#D-SFp6O!0R&{GC`%jt+{J_X1@9pdXa1+d$yGJ$R?Bc%n_9WiI$<~wzV*al7ypI z-m~`5fl7~tIv+x|2xzxUVyPuetT3m_K`GH5-{eY?_VAjC%&3vOyTZuIpV*HIld4o7 zC>mX*(~(?!WR z%XyqpmY?n0z1{nKTd!xmv`6&y3(70;*6XjK%w2%FsVNN6NW7)3U4$RFarrWC+_|rS zC824Q2$8^+&@vH{BT970V*yeNL2nrVk8nI$*)2#N&EN^6)K0yKk}YRQI748i%sMC zzO6ui7T!CJ?2!*1B~3g-Kk4URJ&(WtoBsuis|0OLRru_y>v;W**D*giiK8b^^I8+7 zF3Ym#Hr_y&)@^}tAL9aUPU>ruO=tP z7-hwR-}{5#N7v<#VR6^M?J!c+pd7VzwHO&3R=PSW?2y@x?|kRGIC`WVHbabl;TI{j zvC){?f)Lw#{*CW5SV990>4(+oA>J7r4kwRA3>t;gna64v?}^OvORs!~(OUwT;UKfx z9B|sLSS9cs)Jw6`HFl7zkOWQ;@oH=9VH(A+a8=+cLCH{z{{QpyoNQN^E83>v`7Ge! zvECuu$euK5kAPpiB}`3DP*SphDFza7l+@5u!y@k9x{1o>!}!_n{Tuj~yc8wcar)>P zGK57v!{*d;xf+2B_*8g87XCP9+y7<41F|U zAL|=H7h@Vi>d+(%tczC ziUHLzQCnMz=gz!<)5niM$2!DSiGJPUij@eNLo&rdk>%0nj)5Va7#GTklJZitAM3=* z>=ed0SnJvjqmhH{xsDUi`IZ>V*NAg3pM#CF^{F#wVPi#N#u#8-l?;~VqJ-$-!ZLpH z{U5OHWTZnTT)6lmCaC*kc9x^5xsIW8YB4)7iox7QwLOqV z_NX@@4Xh)xSYBR&-mbfJ^&_h%mez44Xi&f-8dXZ0_>{u(tc6oodH z;OfnL=sb2DZnurAST9|sEMR(c9E+<<0DaaRKXDYH)j3?fepgKpS^M=f+;DA@%y6|& zthz0wJ=)VW{TTTb0LrgyFbP8_FDfboLR%ZiaLPUA!qL-baJsV-5$_cK`tN>4(nu&P z4kqT6JYq3rB&i^g`XuO>)TJadTxEm_mONoHrFOfE1~t^@*K~WNEQxH3(Bve8RH#Yj zGjNcK#79;JW>J596wj%*BNyblv@zjfLfR~sl>!zSS&1bpJcYrMhYN4Mj{MjfuH5Ux znbW7?UzowWAAH31E6&^s@6gFf;Mn0q=)QdoS8m_WfnNg)f3r>6vnTM&`w1u|35X@7 zo@>{vR_>-2|Mm5HiUeH*A1EE0@n2Wf86=T9iM@%d2!u}Ens?J{jfA4!ZeeyXtsJc8lInDYLif7C(0A@zyxl8ckvF9*5 zIRc%d5J%dY)a<;<;MF3c6adQr(cUNi8-KE_KpNP?90Yv8I`Acj3n0Lv>v>_4>UiqNUapcWDi@ z`E@ZyuZR9P4>h#XIK_vrZ+4MBKSifjPJH$GRkV=Tm>M0x2OoZ{$g$+{_VnKF*?m&B z&HQPiPWd#P@09#pX1e`IGP}koZ4&US#ED&Kd?D>C>4xy+sZRLkXE4dwU3C;w9<6#F zF~)iQ&8L^}-FJSBzOOz<$XtvQo$Ztk8EDLM4@aJRk)qON@)4!f1f>ly>30J+v~ua& z+XHFfS9C4q?jpb5Ocy`JP9kX%7GNrJM%-YVG2YjQ_NE3jR5|H5cN8<@V_1&SJvOP6 z>G4sjJeP1ItrK^zf6enLM2ssmV7Eg@DU*qO!q9`;sH`f&V1GAONw(;9IkM#`e$fN@ zs5FLGz`v!h&ZpUYwn5yW`xsw!ZH2B&I1oe)LL@sj?&z*jtg54wNJ);!fJPWX>8*$xKWpP%NgB zR|UmHW|BnO0{jAGF)yUdM)AgCnPnj89rU=ow6qduMx}jB(iFuvh(w6_L_BLI@Ht+n z&K$^zCsi+H{-10Ee;V17+9e_;bU2+v6K6{aQb(0vuWyxLiW`{6I2bGx5y}8~Qb{bi zO1K-_(o~MGzP?8JJ@*FmX8hoXKSGhkPTl*@@D=s;Eo_tUDY8FMUfGWC{nm?AU!Fzp zgHd#zY$f9y#Q4KLT)lBGHvpd0$I7C5cLl#Fd3Cl@=Y_r%c>}wLdT!s1Eyefb`ynx}!DZFs*WfT=hFf_Kn0n~s?SMTJ&pUDrDrFHEJe$o$& zuWCgnRhmJ+`2OlVtc9%9$!Vu?Ni`Pd7GTSlO(Xg52`4hCrL?c-G&eU>9pN5cp|`dV-n~k_9zT4v{4$eyx0)GFhdTYHs2Rot*|tBjtS8(@ zx$5`a1G|D>M2vpw?tK2)C(swyqrRA)5vU5VIL`nCWHxo&b@hxdlic9(o*(;&8OiXf z%`>VouPg>=dF4T#-3&9$8dp~q@sP@OWt`ESRGF3?*nTRZiH?6^Nj;9W=ArA}Ewr>& z(CTXi`p^nJH}Lr~QlD6ZAMyQi+4rRfc4c@4BVy(}G!oaeKGNEiu|83)KiL0d8~C@>?U9#=+rP#;TRvd& zpXhMNxzg;U{7^g3URe26r>0gH5FD5Q>X z9O9{&%~C6s*!9Y4As(HDX}8c`H^fz;<;XF-^!y2`H?PtNhYo5PQS$7$GgOIapl|s# z+6J7!@y-saEc@yE^AP!ldD{EZPbgQGbBy!VcDNb7xfv|+e%y?c@q9U;#Dr5upA147 zT(SzrBgmu;lT3EgfvPLpbbGd?`S*Lq;v~DCWR|wt3h_HXeFwew?%?dJZ=u2zM%M$e zHL#5Qxf)SF11~S(Ul$YdVZg~YIlsa9%bP02d4kB@u2Gl%A1d& zl}@ViT=^K8^WbzxC#q_yQRFP5@BKD1!F^~sb{2W`@NjRq2adu*+`M*OZGbH=FTq_> zhDxePbl>a3_1k@T@ul<1fTq8{3rlO{A-LK}z>eb5QZ&}J(=NF~0lJd`t?ymGg)r)-<~)4;ENAbF8^5=#2%{^^9irV)$= zejz0a3QAyzEWue?4bQ`F%&$a9UPLkHSwU5GCFylwetZOTyxvTW&#B2VD#wZRM~8*Q zCAu^xLrms;VqyZ*3~b?YSI{}tF!YWhbRIcO=G}t1>2ZcaD#wc#F2FZ7gdmOY8|o@( zvPqLnqa6ZtadEyxQ2V(W4Gi=MD~>Nd{Q~aldQ1&<(+zr*ny7Q|P#`cdG|asP#`|6G zORaaG&EISTe>%fUpquF9(&n)9XrHDlf>!!+z@l-b9HH?4FCe@9~wt7eSCT;AzGlT^Fo?TT1hBQPtBr$(j&b-%+(;I z4Bdskm*>ZHCc0I0Dc9%`#si4ETX{CYp88hV#_*_#xG%`Mv7^_=om8B#cE6E7=^s*fv$9ILvx86Xkb zQ2r42H6+T@x7{2KG&6`Rhqyb;roD50HXgS`lJ^?{49sC~H z6Zkct#MOv7`w?&giueo{m$QrfJQ)m`e07aHM%TX4{JOY*|#&#raYk8Y!)mpEi2L?x$=x1%c`Rbqjz`+7hZdd%&L{`7{-~G zE-G@PyXzM6iYrh;`rJbE$Kl}t_~6Eioh|TEP9GvIuHUCsD`S0-t0?0=uq*gQ%vf4h z1|6MH)z%+I{h=z@N$<}4!)U0jCczDiQu^}lKYzULts&E`6zq$?%{w=)pr-ja=7t~8 z@zo?2~Jo%dQ^S75pORT%@r`XG=2;M?#qOuA#oE0R=%FcVK~lDu&hI^kjDL=lB*{D%Ns+AIbzqN^h-22Yh# zh>VJ2+NEt8&mv`|j7W)c>G66X+oV0af?v8rq&)&A@megRMInXcMa70zfT{d>3T=|9 zlnQt$Cc1a?GVU@Ikt7p6HOJ`NGfI63QB@9cRWLJJ``NQ+&{$J}(GkYm zjWL)V<8%#o_o2M0nQ^+JxJrw#Rz_WSDKFHqOejM8#9dg_9;AzJ_eQRp$TIN4mBOZ;?z8iUwpXR^8lyXkJAe@jnfM3m=q5Y z!%y<$|Jl#KWFA}AOq^8m=LogcAql50ti`}JMiXvoU8FEPI zdFtx~Ns{$+-==LbFw;K_oz;v3gMu?P#VpzHF!TIBeIERq@&toFU_K+P(&$Ck<*4L z-!i`c*4ya6e-pR5?!#GFN=cNS`ZNqmO_1xkDoB9pJVsg(egD#mDrNR4KL3kKD;XOm ziV>PVmQ+)s+vFS!j%OQl8y;L=xLfg@!SY4Q7*wIB4 z7IN2^jBsuMJl+7vrqVlt|De1`m?4DR)fG6!h$#J|Gx!msJbr!Y1_we2W78fQm(BLjEcpRDt*+c~RMeuK@c^2eT5$QR zFJYmJ@|O0aB!i5orBhl9gJgIIX?A$1k(*+AeE#uoKo$XcjKEl4Q-lBWKmG!TPQQxQ zI!0Xdk8=f)$S|_vJ>g!@RevCQAYIyX5Sm2<>KIg73r-=r_=RL@-T7v`|K9tIuo$4j ztTH%B<}7*VV6u}r4lL37%S@BqC0OX)t+Y6w5}sA`-|c0<3Kxb3dsG-ytJz3de+g!% z=Fo7c8P&7`n;x5|Nn{y)el8N?k z$&ZDDAxzZ@@fl>KX`^^ymUvoXXfLsKYpHFzGCz+g>iviWLZm(+N_k`uMd@%?M+uR* zGzqaja=7X^K*c;sBB$13aP8OoXX|sbP1=(c;1@dF!VsXH^rvIc#~7lti-zlT8zO2J zLL!kw5%HxQ%fJ!+9uaklfsL3Vio>aT2B{9y(rd&sPaEa9xuSS|(~{I7QYBfsb0m+} zE06Y@ZQ#!evPb0cmDSBSajX>sBQtpCopPQDvlj}4p%?< zXM8yKHCK!HijtLIHP`4p^*~mDU*1GKp80$WxPAQ!x(Dcps^KsrsTV6XYcVFD8ydmw z89$m_KtP{|TCM_N4QjHXlQRkJvBk^-n~Ja zgk_pYy6B)vr(B%mB%XW1P}XM38k*l`cOuVep);y!*z*erXp%S)1L|rk=tpOY%x+Y9 zaHpF{7^1Wp`(jw;BDxN_wd%Bh<_GT0Am zUNOpwoG`db;3BA_3{NE2E}VN2vz~rD9Gj#5PC0xt!|3OZZUMgJme-6Io<9rk+&Cte zf>d3o#7TOZh%$nE?V)>4!NGrS2#a$jDD^t_(&b^Xiq(oFZ@l8kgV+tSub@5y0|j*XL+cMB&# zeVlv+-Y7{Iw>ys#oGH@&5o&;1=;AP+YRe{iSoUFofhi1>7zI|TyPsc(@u_Ll)i*Jw z*b?b~17_)aXf+t;AJhYL|2%RJ7^psCFL1M*Odbb6Z4Z9x%urgmFDXhFiAJj%!IBeL z7+Aqa5oWa@sGBRYz;0YC#m8yeIBtMku#8|(M_Pdmo zs(k`smJQVPQ5IwB3AukBwFjin4Z%g&XKu#(U8E2PJf+k8;V6Q2c6ficmNIcdinH)j zO-f$50`wNaQTE4JD~!8DgatT4{*={CP^~?Cv=8O2V?!Uu74PK|8%sl*Y+fO-je~LfxivbDiWauD=H6J0GEB^b^!}z27 z{}2bftPJvOc`UU!LEy@G5}Ln@bbB6~)XRZ!iY>P=&wn6)b*_qF=eYoy0vm)!Ipfy? zKRf}|M#R( zsFbD#LkyD?VG`f;&7;R(ee^36zb2L9tWd9BInI=4a%NY9fClNhU;igqL!@2U2n)Thm6a5+o*3Pf zc(}>sqau}TfW_M>0#P01ZKYIq;Mn3`z$`|@WRaz9lzT?VONbX|$*(EJ*&X>PD=nf{ z=p2m&149o3Ktp2<@{#1o6 z{-funk+YIP9taFVs?w5=2|qbbt^^2?v$T;Hpz9B;PLbBnBSTpVA9q@VYdjaao^pFo z4h%DY#m^>#Nw{n-c-Lk~zZCMET&(aC0y+`WU-qN$ZwDFg)~k45JC)LY{F8U!w#M*J z|MY7tb0>F+o*KlRi72QwA3erruc7ngNxC6f!tC$}zGQG{yWPSVx>lTg?g%b@_6007 za+e?$UJkyC7k_}p#(bBKTYt(G_5m*1r^l}*tW!6nQE2y~fug`|+Q!hs_B zLM$glHkV1SpF(<}MFONtG@Y9G?i8QP|G5zrqYoYl9O0vf<~#QupqOGFcV!2D@#b0F zzI_dqb*)&Lo`9pe8s4!{taA1F-yeK{pZ(~kc+pjkww4-tc9=m^D@_z9J$U7fH?Yuq z4}bfQ?~`va;?s|Rjmjgh;5glwtb`U|pidyP*~<2?YjWUMpKh=J#I$d{*8=;TFCF~E zt4a#|MBpZFkU&k01(in~YX!7fQZCB11n4#LNfG2yDv?jstJNph5*5p#3;=D=$sIZ7 zieNFD;Gm=0;)+_#OpYo`ED1+spq19#!VIs?qN(K&&YV1jV8G9OrO?y6vymo_qYod# z;Vz;}6B8LVDT6RI-$-RU0~ zLOut>Cm;SZimU6*>CB1+%^oPMvC} zc4!}l=<7%03!dhy=brU+dmx?WmkC%fpJ!C${N|beDK(C5Fh(s1F08`8%D@pqE^+2p zQO~7)92{bmC6+^CeI>IrS!w>sfDuC#z5?%w&Q5&M5ceg_Bk#qPNa6_#DJ7oZ6a%ct z8)^zAm|>Cj=%599I=%6d|_)@S>jmbUs zneBme@F!k1rfqiZ+pEiLE;IPHP29JZ4Tx09b{Uc?DEdUl;GWlguy--Q6YKAl==KzyL$%(4dkcp&|$q2K@ee`~$B-dXG1`U!%Jr@AZR8nMQD1r`vu<#g) zov|LDi>n(Sb_zfM1!#dh&>;CnN9x+xSOB>EdH;7=9)`K$@=R(|*8jHuUkkk-IocNh z$Ogtfe$l>RFun!=D$_TT5(5B66{ZWu$3$*o4;V91U;|+sxrqa|aporW*~TZfcpU8X zVcY-!6@f&e1OPy6gXw&6z5%ct;tRNqA>1!09A=$|v6gQj$qxX|T`;hvk zpMS^+_%E40e`S(L0e|tfFI$DmASgOAl$7}YIUN7*5*8Z!M~4Vp34s(7yG@_raeEOG zVZMn8FrE+hv9g9S1B`zL`EBvT7=aIrHF4bLM{xN@>%(IPSYRycM=~&nF&B)D!b7br zcIZC-K}M!9hGz&OAt=VwVW)34Ioi;EM`i^j!p`~+_NVCU?(}UWQMUAM@^{6CIO^`m ze-TJF{UiT-QlNwLw#`Un_xUt^0 ze59v8#mH`lpAr`R$6sW2V34WR4laucbTHYG)8I?mvY!pcZRBuW$3Jq&(JmH$eDNb2 z7;gKH93Y1~?)ZxwkBrf?+v)o?GSp^=AB87}8gJ4CV9XUAXTQ@Ir4<8D$Zh#3tH>A| zhiyAiKEWh2n{9hg3BUsA0|USZV&UooB0w+*>Ys0&hktFi7y%NXfB--SQahACJ)E~% z!r`YqNCKZ=LMGL=U0I(J#G%(kcJ)hYwhSaae=Vj?X^-^cf`rOI1SYp)_Inuxu0y ziUUZY6k$!eC~a7`5=_||(5t&E{3J8qh(}j0_GM{O< zukzm#7tq9uvjcRRuZd;wZ@XLG1x3@DYgN78~YUd z9{ZDunu?c7p2~>IjVhcfovMVYp6V9WQ>u?tt2jEGFist3jq}4L;_`84aqYM#xc9hK zJUw0%uZefS2jkQ5C-9B+KEZd;$p*ccRM{|#6jOHhiktj_xCHfIlh~>l<;#1;hS{$t~ ztuC!6Z4zw>?N!<*wDWX0IuSa3IuhM}x^lYfbR%?2^o;a!^w#uY^oQu{>3iv?8L$i@ z42BGT44DjP816AlF(MfS8TA=`88aBqGIle*XTmUvGMO?3GvzT|Wa?*HU}j)eWOias zU@m9A$vn=2WD#L8WeH`;XSu>M%<_wsn^l*U%$md6$oiD^2OB4w4jY**m#v9yi0v0U zAG;xY2zvp0EBhM`6o&+dEk``ZNsexgc}^xy4NhOqT+S<;uecCg5?pp%$y{f+`nZ<3 zdANc1oIT}+~S$xW#rZ34dN~0z0Etz$IPe87s_{nuZwSipNrpw zKbF6Wzn_0qKvcj{AYGtI;Ef<&P*u=hut=~|a6yPy$Wmyp&;_Aa!Z=}7;XvWz!ac%2 zL_|fLMGlIzicE{LiJFQgiCz#L6{8W;7K;+A7JDv^5myxt5w8><@ftMq3XAsIKB0+}9}-?B=w zp|WRXU&}GbnaQQgwaa~#myq|BFPDF=K%-!!kfPA0u&5}hNLD8q>Q) zcawLY-94o#ph?oK(j3>~)AH6jtu?OAuT9df)}GW6)bZ1)(fOz=t{be|p!-=*R*$0B ztoK7-U4Nhc9Rs9+u|cjuzafL6qhXohn2~@{fYAk`1!E=SWaB#~XcKdj0+SI_Zc|^= zI@1L+6|;S2UFHOHd-F2$Nec-JibcC6!qUw0nB}OIuvNHKt2MATwLWJ3#zxd8%I1bG z#@5ER-1dW=oZVi#9(zW6FZ+7?Wd}Wne23SLVveznoldk)9!_;mKb#Gm3!TSZWL);S zJaXl54RURB!@4=S)wnIW8@d;}zxPn`$nqH8Bf2MHPp>D3XQ<~*FIq2>*Hv${x3hP> z_ZrEXR83m)G4-kNS@6~OJ?=Z_r{h=TH$&DW7m`2vYx)=ZPX}lQ91EBU)DA2OoDb3u zDhpZ+HVHlz{3FCVq&8$D)H$>%j4I4K?0Psucu06x1W!al#9*XkWLD&OlzLQg)B?qv zQWFhD?}=`UVS+F0eX(M(2Vy7UwBpL+e#Se+UrnG-2v6uslt|1;{Fr2vbS@c{?3>)V zmw#{C-idv>`>OUs`+fFzrU<5Fro2xzPCcK7PYX$VoGzPQnEpM(Iio$3J2N$N>VWZq z3t7Z0O4i6hjf1DMQQ1M+{W%Ibr8&QI{c<1X$>x>htsU|`^zg9U;S+~9j`$zx&sWYr zc@%Rr{OE9jcER~V`og5bsbiMMT8j9Ja*MtfdlmPVD3+W$jz1oIeEfvPiMCRq(xato zWr1Zw<$C2!6v)@M+u(Jx>z(Zy?aeo&Z`5}1 zca+~`zL|due=GCW#_gorOLrpg%-;>TJJspc`TCyAz2{xFUH#qW-4E^?-M`nP+jIMY z=7Wx2_1^0bRUfuKQhwCZr_|T{Sm|+dzjA-e6O|`z18M{9gS!WBJ=K1C_nE=7`_E0E zKN_+c8XR^Uelg-PGXBEv#q`V2my56BUah`P9Yv4kzM*?lGR8Gl{Z{;K)41~Z%?X2v zzDfJZ*HgYzbMKLgmxcF>l*Ns&hrY3YtNpI{y>rQCX>2)cdG$x`PxhbZS5#MeemVd8xEjBPT|2QZ zzTW=Z{P*Za*v3XAi9*`C3LxQ%@b?GcYb^jYt^hC&0DyPj&hvH(625#O;I|WGh|oo< zqS(-Q3>8+E$`zM^zfHiO`9Ip;vKL4N~UPw*Y zRU||-Ow2=EPl8)wQS$z-QmGJWO&J=Qx3W!gsq(f8{0g5GuPYr;wpHO$d9T{2mY}Yy zf!BDpyF$}XYnRqn?N*(=x_Wv9y|?IU9W>CM7m2t~mjfNKU%57wi++ubyI>>Yf&xek7wfGx>nx zfvK$ggEra1In=oz4{?b8u-Fl;e5<3*1#X3I$6Sh>iXBR9k6WEEFEuXHE7z(}t5i5C zbxPv2Y?XO+#+mVRrZo+D`4V)f) z`HcFx%#i-D>4@PA)tADrh_6;&PmjKMb9d~_+l=vm3CBsRDa&`(@2x+WeN>xfogSab zomHG2pF2OF^vUEi)#th|#$Tou&MYQ;_55c2-Et{-x%212U#;r~8yh?EmqVhEGpKR& z6lQ@6iBrZ0Qdbbhi4wH&boUw9855bFv&gfiv%TR^;>_Y2;NjqP;VatO8@ydOaZ&Zj=)Kr3$x|MTPtW_CRht*2e z-8Hy1M&ViDp~bE>qJ3P)T~|bRRc}cDvcVxkve9m1dgBi!9j3)*apq(TAIm_i2!fDz0qsy@CJ-0^pa*y0SNuEJoF5U(t86P%Z$amInh}`Ah98eQj z5|kMn5#k!E6DAr?1J8ts$g!yJ(fl!9v88c$<6k69CC(?U?4{nvvtKNQFBOyeHmx~5 zKZBC#dB8EtH67i?PVJ$H#9>Je?eyntV6+0S!k#ZDw$eeqQ#I(r1w` zv|oNMd{`X$`taNJ?^R1F%T7N;e=Ps(SV{V&u}WAoSfAO6zce(5s6=|A#L-yvB4!3V zOErmGq{b73X>^Hhv}tq=^n(l=Ov22DEWxY?*iNxug0>rW6wGt*0A0@MPiS6o^@|6bCl`^|!UdYD6x0@z; z3;Ah<3`HKrHYGcydF2Btyeh5mtz}v*MV&?cf`+cf)7`$iKWipyVYSM&6}5+Tl5}}= z+w`pUUg`(xZx~b?+8E)C?iuejQ8bw~tv2&8XEPtRD7Lh>qP6O^&alz2`EJ`}7h*4J z|IVSxagP(b({ty17ZaBa*Jig+cOmyT9wmFM_AGlAc?o-6^Vao#MN04y@Oc66BY|XN zf0Y2WK+_;na99W_R6C3=Y&85_L|CL!6%>CXObB zCNm{J+k0c*t^Hjo_foH?)uoqYWMoDhaL+P4D3OiMex6gB>y{^!w|Z#&@Z%%b^G_e$ zU*KM-evISTO3`rfm6GGf51%M3ttz`(e!t>H%~uvE0+kDd9KJ`wYique68hYo7(lr_R<@dI@)gDxYc`m>8^3-^)CDF zrJj;rg@@1k4)=Qxm_F5gt~VU|k~lgy*+0AVePuKL+yD1%7K}0g$I{>oH46YoZ2$_o z;5>5(&O7k{*w6srpau{k{s2Mf1CaW}-}3{4Pa6!N2K0ap@B&dF3)JB(*&4V3e-I64 zm-*l%Xau*w6EFe3!MZV{r$xad`}Y;hk6T}hE$#9gaWpQYc)49PajCCkgnk11p;Dk*+Z zYEv#$NmTVyvrw1SVBJmBl-4TOk<>k`*Q@`J^j-pQ`btk;a zSjq<~51%qVy;Pllmg!t}&GPw>x~~_GUNmf?zqEMe!?o#_xwen(Qyq)9S?}uK^X&HS zvG3J>B=cDOiSl6hv!5fVSGdtrZy6_Uy(doZozwl)^kwy{@^_dm{IP%l7yvuq2NFO5XaW=90K7pMNCr8e6x4z1;1PHO79cdl0m*Jf zKM^W|E1*0pW(oKwLq*NAe=QkY|zeC}mV8Y6vZkPD78vu`kC0Y#?@s%8;rJ zCxffUi{l%p6{&9%YzR{{2}B&Rn3kXR5}d!jrjKV}VQ6J^V*JFkj~UN=f<=nuA!`I1 zE889RAPy#uJDd?*LR_QVr93XYY`ib|D*62cWCelXbD;~unIaydif}GBE8Zt@6+XrC zr81=V%EZX}%IU}xs`RL~s8y>U(n#7Jrx2_H_>`Ab#b)ukqM8I_><%I4(wM-Ih)3rUX+PH zkeoH2P0E?fOFAr@k2w0K@N!XHiQ@6ErI*WNE7ec_I$cvOf2Q*6#~RVv!1I^tSua#v z)NK58sq~84)&6Eu%W7M7yKM)!S$Esw&SK}OE}#4A5BMLV9zA{>_XIPL`;_pkddO?U z@@44j+BYA^c_(e&rG2?FWzuiDYHn`PVkK?eU@L9c;-K$1>>TEb zcWdx)@}&2s_VMy_C%+5O2+Rxm5MmeF7j7BxG|HVa9g`f#6F-)CKl#qS$`r@cU+Gnu zPFcJM7jkaq9XjlvZ(P7$_^8Ogc=>onDScUWg>vQNQ~p&@b;ViLb3?VUb)5AN8d4gK zFUednx|Y&X-Im|(+QE8rF_ew za{UjrA7wvQemehbSz%eBthB7G{?hrC`Kx!8xN5(8e05-rYE5S?VeRtT%sT(N>w4k( z!}aywa=-n4AOHR6_wNn44f4i`jlRwJNBb+tZyg^HK@R}**v7^;5dg4-0IU~mY^+vq zY^?r2b>`Rmf^O^^0T2WT65RJy5-C!oWXZB@NnT>dkv$&yj5Aqgl1V1{GxHr+fS9GK2yY>1tUN^e2u|WXjE3)z4 ztL4^x_uX4nx9Zj{OXJ%034s6gV7#?3GWl${or=`U7_O4tVuYd63=xLB#@j?f&trjw zmFiE%JjTd`RH8DaW0sa*9wd)s(Ss_Z{-~I#yJQBHU;Rm?TavixvD3>KV^|q+OTCU> zZ`zgl^&*L6{$%f-NMwg52@vrvf7L3 zb@7_c^m@iLkW*z81ig%wHwy~MTvC?~Pu^MX)8VR&Q(1_M;eq+n36uhxe2L8GWLZ`r zCH0{0RMHe|?NQI4qZT2e9)y?*t{#!?O_*OVk`!|N(fI1AID$%hUA?dZlf*xHky=yb zC>UCFDn=kprK_j35?V}pcFB-Y#`v`aH@!eQ5-K)5O2JZ8&z+d|ZPO^OS0hl;;HD=S zk}?t3>Q82$;%6-)lNVIGlEm1&m=rK6V4#3090p>Tw0N#Zg&IfX%jjYm8_`#a33 zcG5#=my2F=f?;NwMgjY@m<2{8CgUt=fwy8kis}y{aQhrW12_1=;;>k3vqBYNXx_3F z8=4x}>m<;Atp(>UU*kNzCcnbyR^H33q0R1q+i6E25aP3yj1lL|UII4TR6Ubq7GFs@ z_U+vZzsrV?&Yr=|Tenpn5v)X<`R!VMdA0~({uc(8dto&BX?0o@^D!6fNqi(t>XkZG zS=Jwq$-7!q8RHAfyEQg#gne=x*V=BYr3Z)81((B$(eWT`gekBj=s3w-WsGt1ev&R> zdYwQt5W7yq(3Pv-=y3V8XgRdhz-VINAGnvOj zhSNU$OejaA6FB~fr}5~~2jDL*#czG(t9b0;{mEV=j)H;$SjoKM$ON|T+=J&n{}lWl zCn97HyVD7`%c*(^sY8Z#R%Zd8|2JR5zRl}Uv1&Db|KI&SHm#{cBpfCj8@yf@q7zZF zAQ{qTXPnI4llkquXGQYta5!PNSuqif!tM6JMPU*~7h&Rm_`C(|9pj3zrFU|ByjuPV z1A|i7VqBzn<};tcn#y8TR+xUzLr3t{uRIH4$&#dK*A-i!a6t$$`Km91&6y7 z;oi$gSZz#-!c(~ck?~$kjNWE1!2I&<&DZeffAeh|dGa^#JD>j~PMyDk zqfb7IO%1h}h>YQd@BRo69X^hudmC{2^aX^RW%$%%53_Z(;GNfgikII$4J&&qyQ>)6 zH*UZ`|M`Ex3%@*xqmMm~7=?7rmYw+W=bnX^jClU!3H<2i@8WaMegUW7{Ryu30bl## zr}5H@KgH+1{5*<_?fAjB{|=M>dOY>m5h57JkH7toIMdpXuYUDkp{BePw>z%m8~^wn z9DCv!?Afsqd~3Y&(|^I6ADo5L;Xq^}g1V+H@L?P$FR&*h^ZI;cIR40^*tek!Z=E=e z7;$~(iQ`Hr-+A@Nc=4@|@agBC$No)Ch_U>)zWH_B=ox37&!eWI1Vgvm@%P{OCp7In ziqC%HVG4@}9ybLx+52RY)_h(V1#BgyWq&rOqDg+%+a;UBBcl+wOPgSGxDo8T%#Ra= z(_e)M1;Od7M0BJRv0y*kg*9x+y_k$~2w`(EUu>FuNQ-&kFh4W}>EflE2(Yz1{OD0! zI)4#`MMXII-n&@8;}A-tLwN5(3yM8a{L4#kpnAygc!F@+FP+0jS8w5Kzx#V=JNpK{`TbY%+2?)>W4Al8VbcNhwts}4aVtLi z)Z@5#@e&?=^a#HDjlV@##DV92^V9g&-~1J>^o(KGw)Lo}ZNP?_BE0ml%PfkQ_S8R)>t^DSyf7!Hh*PKEGUNAS--dT>c5n#`z4fE#oRTrEoOY@cvYt{_u+3)Jp9C4d>&mlu7PgxUc z_J0+lw?4#J=V`>lDmUzbBN{@>l`9xKe+^eZs={+$`fXHIm15tX-RSCUMO#N3 zT7U90JbZ9BTlyg0e(QC9Yr!K9e@O*4Hm$+iKmP%TLhL*p)L-~sF%H8b;SfTBFiN~7 ze1{6e9fj;!tk}4=0lhb`;9|=aj93bAeBW~jcfE<%-aLtqfBY%jYP*Pp!v{7uIQgrS za5s4{KE@&996$P9WyBR++5B}58PifpwAx)929UYQh@x;?ZB977z_TkvEhf!TwL;x1*7;Y-ec69aJLYTeY(c_Qc z*)M(xpLy~Ku3W!>;od%+cK+*I>iOO?c?YgXn0#jE=q`6crWV%tz<2YU3_EcKjHgdg5c~ z?zjqHSp%v|9Qf(aU&kYlJ%hEyPILw1c=`*U!O+r_U ze~Mq7Jj)?U0DJa7fKs0WH*eg)N0(b*ci7N!?JD{P`_VTrghL$im3XZ9R0{v$%{Wh&%h{QxbVoMPaxRUf?u6(fy>E8g26%> zj*N#;+t`fga4$YMa{&h*c!$hOX z_GX-V?`^zB!MxGYhld_M46i+oTQ{!b*JnS%1nGD;I*?iGm^FhU#nSwlBW{+pG+9rx zd=zx`28ck^E&mwd$sE0WU{B>Hga@v{QBVmFXR0EDZPYzl*fd(HyT;(J+e-%VA~@WR z$;i0UM*`GMWO~vVqMQxdxM3qc{pn{oYvWeEOq4S?GL0%ZWoE{~R##1JGEQMdoFrXl zk7UM1hEjs1OndT$R30r&n|+cQA(?g+rC)kJQQ$?-k(sJQg5z}df?}E;=g-P?c}IaS zw2^66JM&F4PNsULtjr2YoIV9B^~+3`gSg!4?8G;}@s9`w!&uk69z#7H=o<+r+ypZT z8orz@8a1_SaHK%HW7pvqkTPt7J7>Qy=2d0K)xOP*A-M zF$xI3>NKdrw7q@3c=5%TG=|i;ds@Eq2%R7TFZD|4S#mv1%RVh4RZ>sMtVQDWH__15 za>_JuC>&G_EMusa%a!RV+cuihxQGhS!@7JB3UVr4iEW;jFJF1WF)S zKzd&VR2l_6mjY$}$pZ!EEgX8C@*$&vKI$2jRGNc`a8@cZa!V=eh3qjxeOEBr{vOvp zHo)#F=CF!-hzzIXV`h9u5ss0O5%h5!FDsfNhP0e2KN(GuWN2n3!=%Yy zMtunxm$QBy1p`R!)$|C-!2793T^OgbrCw&j|zk}1b@($9QNHFBkbDGy>PJsmr zhYU^Pp;1_Tt2njD#jWT#bqud!PFWeZa;jIRZ>6_zau#cHBE(;KiYpC-ks*fL>%+#) z4JhQ|TzlJ1boUOhVU!_*1Tv;#KO&6}JC<}8*j zTymAN`qf+D=Q>CXV}W2QPG@pPXw_x=OBgdUxKTh9#@T?FaVv=e3l|Py0GVo~P&hcF zl%Nn;Y{dw$$B?0vol~ryk_IZ~V`{h+8EWG&jJ8%BCS(Q~+ebs==vX2Xq1a!ZVZeD(Ad~WWj72i zJ%Ad8GBX(-873?*SF~Li9-**uEML3Y!?lo6j78$8=3-uZYb(nI)G#I!KlAziq`-7e zoev$@S{5}tg!+TO4I9@rqQL<*ed{T0R70uA7#9F}zxsjSgO@soD7m?UG`ymG#;9yk z<;8~PCin~eaN0RU@fKm{w#_IhF6OU5*;EM}WxBy$M-+BZrXws{SX7E83P@R58S3h4 zXnPdJ`t{9l*%EMgJSZ(G=5(zL1>>lwtVZ*CnwL=M{Oo~d=^JvPZpPoE6u6_FLxv&I zk=yJou3}=O2b1AZu7Y#uq=#4((J@KC#PyE>4ykevTV&WHrV^v0V;mL*5efz{I6Q`? zHLGZ^)x&Aknlq`Xqe}UeRpZ)K4qUl>85QhxqMV+cOblUo zkjsX4S(kC5h~+v4ZV`461B1hy5hAXfr4qQ(qtK#C$K1S{6o6&EQ@Pr>TmB{)T}|uC z6scwzt7w`WoQo_ZxaJ@;E;0loC-Rp}R2dC_7%eTgbS|ak74SF{G^dE6)bBz^M;9}a zb*Y0WrJI0dT2*=*g#~XcGL^$1)4ehiB=M>ym1f7A57)5No*Ai%pL*#PHVelq`}Flkqqm z?)@>9dk4ZHB-2??sG0Fu^(bD2t%O}QnrnY`g6mgJ;g%;Yr!cFoM9Vc5QpI&<)zeZ5 zsjT|VltM1UI?e3e$eg)L>JWG}g~K3J#_uUK%AjDzqk)Pu@_-IT|FXt%sr#(3XDl%d zy%em}%@oko9dBkIR;6;MAQ^7-M4dsCNqV$?Rf3UvFqF@JD>-$6(68BZ>ajD!)?uU; zA7{?412wPrIR(r?_I=I(=IiICfGHfgX=A3`=M*r7<348q^YwF6z!Z+$v@uiea|)Qk zai24Q`TDsjU88ElQXWr?0N#QsSG%uS%6 z(+;?}Qz~2W6dd!$q(B}iFr#pY(crF40n}B|dUZm~!pW>66=L*94;|V)`CV)ZRlIgh zJ&QC*JdOLbYx3EUKP|7GpJkM-Ra~pXPD8NEO8QK10V0zmRNa~MEzOMBNZfnDxbv5v%r*} zJWCn*@wtc=xh|`ZE_O7FTBe%8q`;z5Ag6Fht+E&Tty4aPBJ@#ZL?heSMi^T{wlpn8 z`>Utx`Lm@N<9II?x*qz&^}59Yfk=%RObRSM1!fcusb028(1p{iJU?$#bs?EUL6IZV zxyBp_WoF4M1=2c%`9Kz@2;#a^bc3nA7#ale0xrIo3_5liXxT2Ct>Z|`G~2^GgljfX zv!~Ao+j$};vl}Zc2*&fFi2iyrmYFe8hhVtoBwNmeSzGu_6lU!?4Cth8#erDms#+8m zdC|o)FGNL%M#9|F%^?q6<20__0KeCYtJiMOu^Byqu=^3GY$8Nf-g`ZT2+&2RxY?Io zf+9tNn0ROsv5}p8;&j0bCIyy~0`nFQ=`k$yg?s$t&*0#;)%ewWCn*5qc;k&X>3eDn z#nsh#^2sML(0zkmLc;Wm?10B&$F^NtFvNY@#dKtFspTeJhKA|N$Ay8e4p==tRF?bE z!M);DWmOpL?Lud7zbPO~$r)zd$nGmQ*)z#(l^l>F$8)7RD{1|ygh<2Q(bkSt4eQ{u zgy=8!f^wxvmugg?=@f@f&6+pt!$SwQVKtpYJ6#F%k4I2m;zuy<#NmT`V4HN|fd_Ze zM{WsL)fA$;4$@@rxE3kfY2}|hrm&maCsl>Cl2Tym zZieEXe4k|l#4HB~M>CjH4+OR~iD43f!E zm6lJ>W=v5T(=(@{rlO}xW=Ui{Q~%P^rvPL`PvzGzo0gnT#A($}MNHkvNM@cvhCj02 zQRJ(@k)w|&_xuBNfA8eUN-}J+aaO6cq6)PX2n(Gc2RPii(tZO2^c5Qz;&BAzZKutG zz}N_`@mRC*i2x!Trj?bI!%nwWA)eG!;HSS_ncvME1kMvzGy6SEft{CV3ZdCaxAX9f~x%eO{n&-sKlxfcyFeN=V++^t_ z{Z%bOXhQ+RZ8CGlCEK^l$dUWBjaqXMmFqX=B$G#zD%kizJ? z!vlpD^Ho$-&|~=|dV2b`170|9o1SNJg(Hn9+UsTfWe(0N&G-p2m~>W{8Tm6Roc5Rw zFa1en&Jv{qNlVh})jvrxF)dFftEDIEVAHNsS*Gq%8L~vB(lYB}LeA_nB;-tzil!w> zL{y^1sOpcHoJIAYqlW0hd%r^3XSA7GQIW;^!9eMcMzw` zHc>NX4%1##%dWrF%!Q4q1T>dIijI0l{c41h{XSbx9d${Yn!#018W2@i5}uwp`Irtb z{Yia&LsUl5^w*rKSV7hvGi}x~fEgZ>=uEq4bsAs5kR=nLWYSa_LtfsdEGtscNdP(V z(A_?z3Z&mmt6w5?U{i@{v3#(LQQvgQVp$~^Qw7s&%kPu!f`3j>GbyK|DDSG@&kay2 zmyxuYAVkPj9IrY#r`4kpQmIL}Qc8={8y`J~sE=tuXIP1r-&E1GY}p^CXU>2=4P6CC z&&1->@G+JU@JY>7ZY3Csrah|%NhM3ALPptCyzxc{oQj(kkxI#SqgYi(Dw#oBN#lry zpr%8U7_ERsItN2pofjkrPZE{`S~3D7;G&L+UQp$Lr1&LXbvy@=ef(m5^l`U2ucc#*on#w6emi#7t3e`Xt z!)?Bil&@_BFVFS> OxOfln3xfVZ7da__JwD=X7HJB7gQoz1kn13!`WF_G`m-jLA zEN=>=_h8E#R}(vv0(X@Hrf}R<^{;qo6%As z*K+TS!XZY3E}ri#+g6t@SZMtlRVT(SB^FEf{wud;8!fiuJiye&^Wt8S2v~$y%%|Ms@oWN;Q#hoc2!|L2rkMdP5Rp467Uc%0v9U3O>ByZxGt1sB z3iy0Jh=AB^j^v5L*;sI%*ibmche0$N&B_l_1Cvuh8dUDB%gX$!XXB1lC1hEcJg0D^ zpc^Vm#ofglV{c*Xrss-+lrdM<=Sr>o=hMGmzS&5=Y36qop>VQ;D&=_k!dAvF&R=eQpuin>852PmA+p@?)5nN z5H@LHC>Tz5>66?CZ){Bz^5&nsP(bLee}DP*`uE5UoSP*0F%*xGk2G_6#_?N;)wMM7 z1jC^5k-(QQ+ptU=-;_}(o@)-k%kol6+zpISFbbW(H?MgqB-sT-RgmS+oM)>N96J`2 zRbbkyC?Emo z7>Jvzqzj)UK6bkU1zxuj;=-bGJpIY1QCesvJ|Z$^$R`D4qnv{tWY(>3#)b{+QNS(F zIx}ahN75{IZj0Wz3ww5M*px#q%u`_PU5*W$+ECg97BfM=3^)N&Wknlk5}BhHs7TD=xu{lZiD z@YiQBN`=VI-GJe-Q54agP6G6f5R2kgXFoP=T#xro{1R7NJJdGXtTitnQv71oH8kR> zCm+SDFTalUn>QmwH$HuV39M_Z!?kNy(6nI(0^J?x4MphgryT3o*5l3BG~r!9m1dC~ z6i~f|)sCYddlKtviedK_W2~nY-~Qf@5T>{9%t;*S45ab$71d(P)%6YLAi ziO1TiBE0dlSLxNHgw7pu6Levin59HG++Hs>u@~>TateteE4DXppkFdCI{U|Am2M$3 z2s?1-6doVPaL|Fh+qO_xe7Jn}8oD}fp|ZLjdzx3Py*sCI6%EZb2nI$Gj|MRz?xAM+ zjIwKcfV&$0=UF@c@39!JbOQhN936#FVjR&q50X+?&sjLE9OI7<^x^Hd-a_12La8i* zo1R2$kqLAR4q$9#07b=Q#F&HL5X;ctH>id?shaX|Bik9r$Hox}git{5CX?e~viGnWcdhmT!UgSaN>p)e|7@s83OzTKnW+LM5hrwWQ=Pi$boA-8BVDuga*HtL~N<=w3dbCr`Ba=i5cIfw*Kfj`qJT`@D&^Zi_o>vo zdnYJ}Ac#O{LBB2xj~Ru-*a|NUe11wv_bVm{W>`5CkcLSOo78Y6=_@7=0wiz+j1qx7 zz?+GpIfqqxAv>q*EK5AwqYJ5ylX+eK6cFZ>wJsTU+1a>>6To}~kq6N;#T$*1k~;-T z;g#WFwlHJQp@t>XCmyoFS=2Zow60$)YDFgS{8E67Ck>nC-+1PkrukH?dL>TAs__6Xnj&gK-Wtuj7)=B)Yr1QCePwXlNW4FJ4k-42or^{EHJ8elW>Z zQd)EF-+-&vdr{QH6H#kkpe zojs2aRh1=ZyM683y16o?6`3aZS8#s zj@`zgzm+d zw%72^hb{QZZ+sb#9JQg3TPTs3!01pI{vF$tb#4LAFr1`)jo0l!9Z$L~=UX?fX+mS; zTEyZJoG*R{FTVb++Af)IobPpbvOU35P>p~8hkporxCj6HfBgjpX>z{Av;TP^`@AM< zHCvb%`g;3N$U`ni$fz=0NmwS~r1BM@`T97G0T)vr5&c4xJULWTj!0P3xCIaG--q75 z9vZYo(0RKZL+m9^zx!*9(Ue_IjFR3)_I!A_kQk;-&Z&1!5pO4)UK={Q+R;Z#UwJn( z%%1{6x6$Dq{P6oP;D;~#1jD4Yjo)SIrf}x}4!KI?Tm+Qva+={G-?+dlHm_D3JNh6l zUO10kyZ7S#6DQbWhiInh+(^T{9u^0cc)m+Xp$Dxr z!yg-untI1Pzs*#3u4VAJiUfOhnHZ5E{3DyuoOE8W9FDP=!gcO<^AZmIrKR<@^EW{~ z#KsmmCWdDuj40}omM_7O`Z9$>$3dkrF%}cWTZ}%_&mWZDOUAyXRn^$g)PU<$*n4=I zt(a3wntVJ9fAT@)c`wrRayqUabQpIBW4%`Mx{@d`#VrfOT4%Ba7N514K6YJbJr?RF zo;;cw%!;s?Aw_|OezO#SCBDfi9P(mfryq|`sI`kF!;^T(IJU5;Xvt78E1o|Eq(_#a zm0F~ofAM8eBByW&cJgweP)LpY^%i_7uwLmc&{EKBsp}Me5&l`pVMgK5Uu>ygaitSk zr=xjYSrnMpI>*X-H4|Ht0(V9MQ#kI7erD-=m;$D7+`}K&e6>5HfGHezMnALkJxl>p zIPT$(Yrfi@QNR?AJENaj`W~i$DIE9k$2DK=&M06C$DPs7EPW4C;Jy)#rC!Lqhk59p zeYF`^$i-_!gy-=o-=nl~5+}`*bf_iUh3!rUH#p5$TqBxhWWzniVpcAu;mWc-CqW~T zurf85Ls1+Ci`$$9W=W9ky|U3sT7i^#y4=rF&P+BbkdwP7X>{l*uf(JK_rgP=pj6=U z#miXTv>raM1E)`(L@Uq95CNLt&rRb%@n|l4C>#zacY^_8Zh#TNs#;ZxH9VH!-1&=i zf)J;Wh2NZhv7B4jz9L?Uz5|!61|P%+rtK?1dH_ zd-yPJa|c}|PkY+6Z6h5kgwect3wG?>PJfLdL~I@$K75F$_f)aR(av-$E~&=WojXul zRf>+zZtmjSjV&A2@hp!X1h_GO^X@}TJUZ&WyMNcLo$fl8_kqhqc`W;fP0mEq+13)uC{=P*hE85tNr z{k{VT4Yr`QYY3axJ;eRS*V*!K#hQkVSXEVwNxKhgcnZ^>fBoCows#-SfACAZ_|{3B ztzCuPM<2)9G6x3e&+Uk>7Kb0$i?bKcVoTH0JXOkzP@scuwad}KQ=W>s;|~1VH?icSrz zlTlo4>p~%2-(0`df!gXSTqZ;A*u4*Xwr;~%tahI{xLMIuEyzKUqG?nhik2^s9~Kp#L;@| zI^2a72n}~)oM)o>ye_==;rp0yl;DYvJqlMWf)VN{%{(+Sjwnu_I?Wz$2aX)vjf-b^ zSR4;X>!YxEiYhQRcpIGqgQgb}{llAAFvQ7 z^@OsraynA;U~q7RP8TdZdW^jQdzQxCyRmP}Ry0vizVi=%g_fRSy2f$SD@YJ_D!-91 z&-LT(J|BlVq6rNIVPPRt+N-OB~ zqY=Zsw{g9#W9ke9rn7(|yp)q$ZHiZ$D>A~Hg0JO~LK2tS{A7S7fW*(9?zPZ}vwpA2 z5?@igb$kg>!-rQ51BIIT$E3gWC;uA6b^YYIp7WxE3F|HJM zp@P4(a%I)4v8ucff#Gr5ceT+b%!xP+6RC75y-SV`R!+2Ob0*W((ohtZl)~?Iavf%v zCNXOe8X3e$D2mmqYq&b!fwEWF{#v_N1A?ESWB!xzX!3p?l4xwOp7!juj{q0xq&Y3IN z*jR^amoH&;V+~qcZ{y+PPoTG_9qyg`Q0ceg{FR$1G!su~>FycQpxxz1x1cmO<& zQyx6@2(~MM3}7^5K?QBGO8B0g>`@A76nU$)1*P?CQB~?id(4eTj_kzCFZ=*adk&)i zb~}2;Cb6!9J(s@-ufFyMHf`RZCOE{TKVJ>UN@Tc|g!4R_F>Ty_b2_-8|{Oic3i#fS7{h&f#2sxG!lZ9OkV6O;F*GB@c4^ST~n#lsljtXWxgDGeOE5e-KX8Xx9;4~-q&+`AIT`t|FSNB5G_ z)!4srEk3$*nR{LA*tT^uf}>eK+G(HTH0UbP#ueX12Mum1huPUshpX?+!`N*&pg@v@Tr>L5X~F6Ajo6Ax(7zlOy=*nejPD~i|<~D zF6up{95$5~*l_CXB@Qch^E{9)(!q-L>l!i8bqn2t0c>PFC*OMy1EXVkqsx3~xKw$i z;gs1b;hmKj<}4iYa_S{TF(=2$Fj98ziC!YJGzm8ATBB%D3UR)OVH6I5DSC$}#u6k= zaFDpFhIJ^U74B6k!8YniN-3xED>zNYITWLAAu~pzyU5|6vQsfiWm|SFCTMOiy8~ri zM@Gl`qNfahMAy>I_GJP>whGJOjuq21hTDc^_ah&j+%~MtWeAvk7x$28lNB;KA-fHo zG`6(OFat)Q_guKIgkvebUZ!wl$AQxVWN_IuYp1YE(5GAVtBN%L+*Jy!bm5qTf}r;Z zca^TG%49Z7TJYJFSecSFDo}cU{h9)3-rO|`taRGXC>%13l9Qd5_9Znl7N5^|*FNfe zDw1KC8e`6gJ}#G_(?=F%m43Ed5Su3+IeQKvwlX~AT7ou#I#0-X%bvjSU_W;N zis7NK!O{m&>|TCjLBh^ETGDe zXZ}Gp2+eLmJb$=miTP4s&cY#9s1!ZJ_A+CT*=ObJ|vusgLd0ot| zRIGr#UN5Hq|2<1q&nOM*tcUVE?qj0k&$t=$U3jrphP-kF_RU_ zuvjVT1gyT0G;BHw$$L@b#l@;x;GI`R_kQL%3x}*Quc9eNlQoXccp>WQw$tlp5bd`* zu&#L{!ee2&y|LoWS6@T_crdlfoNp4Y-Mkggf8n#Zdig4?fhiDULl_9euy%btMmmRZ z=!wJl@2wZn($=5vs%L~JhM5&rtFWo55p6@oc(ke#c5-4Hy(>1ZsYlC=YgpINM0Y{A zY1>smD_t&HDn*`3JsH;SqNznJz;`M^Rka`2Xv4OUMy7xk#$Wl(XK}lK7&WCnbPbJj zVbqE;zZZGr) zriMDSUTr~uBhjo1co_HKSqDTA*PvOItAt|91fa^w_QGuG9MRqIF$LtmD6Zo zi`d3d(t@PrjRw{OJH zUwaw#WU@7NmAG)D`_3zy2L##V)ko{#AO7gaID7dzTYWpaZndG8PUZ?}EZIln$kyBK z7~!=jJ`Q#e-i=QELCObVF7v6$2~VXtTk zn8LB5Kc9*GVp6~qj>V*|3429Tz!Z)Z{rODf7n1^}a4aTuP1q}%0;X`R=+9>&znBy- zg<~sl6fx{UPS~a+5Mw&M_okibloxae zSA1_}^Q)$B8_tVRaw};*g)J}dZURYBAh&SPIa|ESh5nCK1Fj_;ebN6@(K`chwa{;s z;cW9L_irEIQO{p=^C0p(1{-}!1*{4D3nkzpm&+*}mWc#H6+D<_e=(gfksS=J_#)#p1zvGs0wWzER9zTD!YCYUx_3D2 z_@sp=#ZHw--ia_zwe8|RZLUFHHOAsUreDvSQ9@QYBui5u>~yH09NXnVIMm^u6mrdh zgt4NzVr%AGObX-_4&{`O9}W?6RvND{j{aDcTRytLoHa;Z@$4sF5rs?Xzf}dE^R41^ z0NHp$kIUxch2VrqL-h3;75wzTBLF7pZqvdu$t`vbzXZJ>Cc^Y$?w!4t;i=g?Iyvc` zT!)#wDs(6mI$C(gOVRM?$eY)k6v!zYQi6># z1%ZF$s((OXa2IjHUN)Sokc0Btd5;NzW3**_)gn9yg?0>1f)~P=;7n58}Zv5(dKOLDqYEp9=Ji~JZJ9!4k?(e*QExm8U^6AC%@xE|6ZJs0sgL$CvQO4MzcQ zIXQ#OZ*`Mf$Y?gU%r>4O==M_>q7;Nm{GVO_8h^6xm?j)nAO7>YPvLL2Jx%?ALLy~_ z3mt_l=f=}(AA!?XCQhL=p%lSPP6|j*mKnrfZk)_7ereT@&a54eKLOt#{2u(ze}O{b zQ-a~x&>U;IYS!qPB*okN6?;3%Fh-HBsm>p5hI<4mvzy z!uYr6zs)i>Y%N)b{?S$n00m~W18)ysXT$Blr>geh>6)!*8@-M??^=A+cMcEN?uLE5 z8$TH8VVwr1$-<~YEn(J4a z3p;i_hzEA>#C3X1_ZPYliG}HnehsQC%J2{0{AY}gO`XoG3)mDa^KLm&!0_p(qoob2 z7%xmG94Laq&f{XwHSDk4iAPs$MuocsMGiL}t=I|&xwXz)$pajf;A zcS()vJ)*G*OfcW(qI$R{soYN35oScW%Zc`2KZYW72rXPMO|sr|$a9t;imVKq;>1sW zlf0KhWE}Nt*fWJOSy6$w%KR?pkzv*r@I3IHZ_$EH7Kbp$L?)A5gHxFwbo9!y*|jfB1o{u(R-Z~ zj4Ur^MlA~p%-C}%;gDgKwBl-b!z&s1;!ro<>Ai$oOxouz#?^2?*q@*)*v*#s1MG2d zmTPPjS3;-oKd4vuseGRr?jsx*-tE4OcYDeB6DM)FxDF>qyRoUDl834cqRZk$)g)P2 z>XOQ(^Wa52XCapwR*|76DP$^eR2O*n9mE1#5xIC8lYQTUecMJ%4h+FEG0I^ehirBV zWOqO8<$feiy~}4CCVtIRl#1O*C|!htMkbzQ?~*MDN_y`h_XLNQGbgcbO&t%d`4B-0 zU2pqM9^})3A_`}MJ;yix_UmvJ6v4|zWZV*+Do+71hgI3AygcG^`^x1kRbY!BfzPwW z*M&p4Rg~uV1iz^;q%`Srm5)qj61V%pV3Ni)0dgCA8hPf=D*6cHWwuI+Nq*r!Rg^bU zMg&4yVx^=f(w~Vvbc;4;6@9_Ap2_?nMM^R4%sSuA*(I+EXS&t?+ zGA5+YU+O^#o*7}0d_==C5#lo)FmpJha1#*3HAdn1Q^J0q>l|){AQL2wvr(c?=)$4J z@|CHJDP4sTvUn)7XmU+0@QDyG&dx(LjR*V4ELZ=)0LxRyQG%jFG_T8n0yFj;N(t5( zSz)U)FPSMNJ; zCxfAO#!x`@pl*}TQlAJtgN1@-C7u=z$Fc@8aV8_%IU|*@P3a^0x`iejlAn+WGa+RS zKt)iD&xR!Pb{SA0w{Wnxu!(XY<9;P228O*`h%2UIWfXwSAWR=7N@}*s!1I~;)H8)< zu0hx}>XwB?)heVF6K0pzUe+@*gHd4gd;O~NW)TFTs8akhftkfSz+B$4#C#5#kR_#ogwW`C`-!`>Q9_>pn}f>)r^x> z3akvRWDO%VWLjut#8-5t2`*Zu3DH8~ndS0Mf!x9&RgqCF>^WpKw3NX@n+~c0(}MIT z6H0NJmUPDv)J&!ch5)@|p~%3@6pRdlEThNi;{zjdY~76ZOva?Ud7n!*WoSh;`);CQ zw(@tC+DltmmiBmQ5i)BxDX?59U<$`_`4T1`%Z>u3a4fq|Vj{F$DDeLQ0x^ZpYL@@m P00000NkvXXu0mjfnnG#* diff --git a/2.0/documentation/tdenginedocs-en/assets/nodes.png b/2.0/documentation/tdenginedocs-en/assets/nodes.png deleted file mode 100644 index d4ae5120c29b8cfacdc543df5a2a7104d77a2a7b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 67429 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 diff --git a/2.0/documentation/tdenginedocs-en/assets/structure.png b/2.0/documentation/tdenginedocs-en/assets/structure.png deleted file mode 100644 index 801829b68580e1a46d0841a3d38e4885eb383991..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 25593 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≪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 JOZ@ld{{VfYx&Z(H diff --git a/2.0/documentation/tdenginedocs-en/connections-with-other-tools/index.html b/2.0/documentation/tdenginedocs-en/connections-with-other-tools/index.html deleted file mode 100644 index 2c68a01063..0000000000 --- a/2.0/documentation/tdenginedocs-en/connections-with-other-tools/index.html +++ /dev/null @@ -1,93 +0,0 @@ -Documentation | Taos Data \ No newline at end of file diff --git a/2.0/documentation/tdenginedocs-en/connector/index.html b/2.0/documentation/tdenginedocs-en/connector/index.html deleted file mode 100644 index ea1f75ae00..0000000000 --- a/2.0/documentation/tdenginedocs-en/connector/index.html +++ /dev/null @@ -1,354 +0,0 @@ -Documentation | Taos Data
      Back

      TDengine connectors

      -

      TDengine provides many connectors for development, including C/C++, JAVA, Python, RESTful, Go, Node.JS, etc.

      -

      C/C++ API

      -

      C/C++ APIs are similar to the MySQL APIs. Applications should include TDengine head file taos.h to use C/C++ APIs by adding the following line in code:

      -
      #include <taos.h>
      -

      Make sure TDengine library libtaos.so is installed and use -ltaos option to link the library when compiling. The return values of all APIs are -1 or NULL for failure.

      -

      C/C++ sync API

      -

      Sync APIs are those APIs waiting for responses from the server after sending a request. TDengine has the following sync APIs:

      -
        -
      • TAOS *taos_connect(char *ip, char *user, char *pass, char *db, int port)

        -

        Open a connection to a TDengine server. The parameters are ip (IP address of the server), user (username to login), pass (password to login), db (database to use after connection) and port (port number to connect). The parameter db can be NULL for no database to use after connection. Otherwise, the database should exist before connection or a connection error is reported. The handle returned by this API should be kept for future use.

      • -
      • void taos_close(TAOS *taos)

        -

        Close a connection to a TDengine server by the handle returned by taos_connect`

      • -
      • int taos_query(TAOS *taos, char *sqlstr)

        -

        The API used to run a SQL command. The command can be DQL or DML. The parameter taos is the handle returned by taos_connect. Return value -1 means failure.

      • -
      • TAOS_RES *taos_use_result(TAOS *taos)

        -

        Use the result after running taos_query. The handle returned should be kept for future fetch.

      • -
      • TAOS_ROW taos_fetch_row(TAOS_RES *res)

        -

        Fetch a row of return results through res, the handle returned by taos_use_result.

      • -
      • int taos_num_fields(TAOS_RES *res)

        -

        Get the number of fields in the return result.

      • -
      • TAOS_FIELD *taos_fetch_fields(TAOS_RES *res)

        -

        Fetch the description of each field. The description includes the property of data type, field name, and bytes. The API should be used with taos_num_fields to fetch a row of data.

      • -
      • void taos_free_result(TAOS_RES *res)

        -

        Free the resources used by a result set. Make sure to call this API after fetching results or memory leak would happen.

      • -
      • void taos_init()

        -

        Initialize the environment variable used by TDengine client. The API is not necessary since it is called int taos_connect by default.

      • -
      • char *taos_errstr(TAOS *taos)

        -

        Return the reason of the last API call failure. The return value is a string.

      • -
      • int *taos_errno(TAOS *taos)

        -

        Return the error code of the last API call failure. The return value is an integer.

      • -
      • int taos_options(TSDB_OPTION option, const void * arg, ...)

        -

        Set client options. The parameter option supports values of TSDB_OPTION_CONFIGDIR (configuration directory), TSDB_OPTION_SHELL_ACTIVITY_TIMER, TSDB_OPTION_LOCALE (client locale) and TSDB_OPTION_TIMEZONE (client timezone).

      • -
      -

      The 12 APIs are the most important APIs frequently used. Users can check taos.h file for more API information.

      -

      Note: The connection to a TDengine server is not multi-thread safe. So a connection can only be used by one thread.

      -

      C/C++ async API

      -

      In addition to sync APIs, TDengine also provides async APIs, which are more efficient. Async APIs are returned right away without waiting for a response from the server, allowing the application to continute with other tasks without blocking. So async APIs are more efficient, especially useful when in a poor network.

      -

      All async APIs require callback functions. The callback functions have the format:

      -
      void fp(void *param, TAOS_RES * res, TYPE param3)
      -

      The first two parameters of the callback function are the same for all async APIs. The third parameter is different for different APIs. Generally, the first parameter is the handle provided to the API for action. The second parameter is a result handle.

      -
        -
      • void taos_query_a(TAOS *taos, char *sqlstr, void (*fp)(void *param, TAOS_RES *, int code), void *param);

        -

        The async query interface. taos is the handle returned by taos_connect interface. sqlstr is the SQL command to run. fp is the callback function. param is the parameter required by the callback function. The third parameter of the callback function code is 0 (for success) or a negative number (for failure, call taos_errstr to get the error as a string). Applications mainly handle with the second parameter, the returned result set.

      • -
      • void taos_fetch_rows_a(TAOS_RES *res, void (*fp)(void *param, TAOS_RES *, int numOfRows), void *param);

        -

        The async API to fetch a batch of rows, which should only be used with a taos_query_a call. The parameter res is the result handle returned by taos_query_a. fp is the callback function. param is a user-defined structure to pass to fp. The parameter numOfRows is the number of result rows in the current fetch cycle. In the callback function, applications should call taos_fetch_row to get records from the result handle. After getting a batch of results, applications should continue to call taos_fetch_rows_a API to handle the next batch, until the numOfRows is 0 (for no more data to fetch) or -1 (for failure).

      • -
      • void taos_fetch_row_a(TAOS_RES *res, void (*fp)(void *param, TAOS_RES *, TAOS_ROW row), void *param);

        -

        The async API to fetch a result row. res is the result handle. fp is the callback function. param is a user-defined structure to pass to fp. The third parameter of the callback function is a single result row, which is different from that of taos_fetch_rows_a API. With this API, it is not necessary to call taos_fetch_row to retrieve each result row, which is handier than taos_fetch_rows_a but less efficient.

      • -
      -

      Applications may apply operations on multiple tables. However, it is important to make sure the operations on the same table are serialized. That means after sending an insert request in a table to the server, no operations on the table are allowed before a response is received.

      -

      C/C++ continuous query interface

      -

      TDengine provides APIs for continuous query driven by time, which run queries periodically in the background. There are only two APIs:

      -
        -
      • TAOS_STREAM *taos_open_stream(TAOS *taos, char *sqlstr, void (*fp)(void *param, TAOS_RES *, TAOS_ROW row), int64_t stime, void *param, void (*callback)(void *));

        -

        The API is used to create a continuous query.

      • -
      • taos: the connection handle returned by taos_connect.

      • -
      • sqlstr: the SQL string to run. Only query commands are allowed.

      • -
      • fp: the callback function to run after a query

      • -
      • param: a parameter passed to fp

      • -
      • stime: the time of the stream starts in the form of epoch milliseconds. If 0 is given, the start time is set as the current time.

      • -
      • callback: a callback function to run when the continuous query stops automatically.

        -

        The API is expected to return a handle for success. Otherwise, a NULL pointer is returned.

      • -
      • void taos_close_stream (TAOS_STREAM *tstr)

        -

        Close the continuous query by the handle returned by taos_open_stream. Make sure to call this API when the continuous query is not needed anymore.

      • -
      -

      C/C++ subscription API

      -

      For the time being, TDengine supports subscription on one table. It is implemented through periodic pulling from a TDengine server.

      -
        -
      • TAOS_SUB *taos_subscribe(char *host, char *user, char *pass, char *db, char *table, long time, int mseconds) -The API is used to start a subscription session by given a handle. The parameters required are host (IP address of a TDenginer server), user (username), pass (password), db (database to use), table (table name to subscribe), time (start time to subscribe, 0 for now), mseconds (pulling period). If failed to open a subscription session, a NULL pointer is returned.

      • -
      • TAOS_ROW taos_consume(TAOS_SUB *tsub) -The API used to get the new data from a TDengine server. It should be put in an infinite loop. The parameter tsub is the handle returned by taos_subscribe. If new data are updated, the API will return a row of the result. Otherwise, the API is blocked until new data arrives. If NULL pointer is returned, it means an error occurs.

      • -
      • void taos_unsubscribe(TAOS_SUB *tsub) -Stop a subscription session by the handle returned by taos_subscribe.

      • -
      • int taos_num_fields(TAOS_SUB *tsub) -The API used to get the number of fields in a row.

      • -
      • TAOS_FIELD *taos_fetch_fields(TAOS_RES *res) -The API used to get the description of each column.

      • -
      -

      Java Connector

      -

      JDBC Interface

      -

      TDengine provides a JDBC driver taos-jdbcdriver-x.x.x.jar for Enterprise Java developers. TDengine's JDBC Driver is implemented as a subset of the standard JDBC 3.0 Specification and supports the most common Java development frameworks. The driver is currently not published to the online dependency repositories such as Maven Center Repository, and users should manually add the .jar file to their local dependency repository.

      -

      Please note the JDBC driver itself relies on a native library written in C. On a Linux OS, the driver relies on a libtaos.so native library, where .so stands for "Shared Object". After the successful installation of TDengine on Linux, libtaos.so should be automatically copied to /usr/local/lib/taos and added to the system's default search path. On a Windows OS, the driver relies on a taos.dll native library, where .dll stands for "Dynamic Link Library". After the successful installation of the TDengine client on Windows, the taos-jdbcdriver.jar file can be found in C:/TDengine/driver/JDBC; the taos.dll file can be found in C:/TDengine/driver/C and should have been automatically copied to the system's searching path C:/Windows/System32.

      -

      Developers can refer to the Oracle's official JDBC API documentation for detailed usage on classes and methods. However, there are some differences of connection configurations and supported methods in the driver implementation between TDengine and traditional relational databases.

      -

      For database connections, TDengine's JDBC driver has the following configurable parameters in the JDBC URL. The standard format of a TDengine JDBC URL is:

      -

      jdbc:TSDB://{host_ip}:{port}/{database_name}?[user={user}|&password={password}|&charset={charset}|&cfgdir={config_dir}|&locale={locale}|&timezone={timezone}]

      -

      where {} marks the required parameters and [] marks the optional. The usage of each parameter is pretty straightforward:

      -
        -
      • user - login user name for TDengine; by default, it's root
      • -
      • password - login password; by default, it's taosdata
      • -
      • charset - the client-side charset; by default, it's the operation system's charset
      • -
      • cfgdir - the directory of TDengine client configuration file; by default it's /etc/taos on Linux and C:\TDengine/cfg on Windows
      • -
      • locale - the language environment of TDengine client; by default, it's the operation system's locale
      • -
      • timezone - the timezone of the TDengine client; by default, it's the operation system's timezone
      • -
      -

      All parameters can be configured at the time when creating a connection using the java.sql.DriverManager class, for example:

      -
      import java.sql.Connection;
      -import java.sql.DriverManager;
      -import java.util.Properties;
      -import com.taosdata.jdbc.TSDBDriver;
      -
      -public Connection getConn() throws Exception{
      -    Class.forName("com.taosdata.jdbc.TSDBDriver");
      -  String jdbcUrl = "jdbc:TAOS://127.0.0.1:0/db?user=root&password=taosdata";
      -  Properties connProps = new Properties();
      -  connProps.setProperty(TSDBDriver.PROPERTY_KEY_USER, "root");
      -  connProps.setProperty(TSDBDriver.PROPERTY_KEY_PASSWORD, "taosdata");
      -  connProps.setProperty(TSDBDriver.PROPERTY_KEY_CONFIG_DIR, "/etc/taos");
      -  connProps.setProperty(TSDBDriver.PROPERTY_KEY_CHARSET, "UTF-8");
      -  connProps.setProperty(TSDBDriver.PROPERTY_KEY_LOCALE, "en_US.UTF-8");
      -  connProps.setProperty(TSDBDriver.PROPERTY_KEY_TIMEZONE, "UTC-8");
      -  Connection conn = DriverManager.getConnection(jdbcUrl, connProps);
      -  return conn;
      -}
      -

      Except cfgdir, all the parameters listed above can also be configured in the configuration file. The properties specified when calling DriverManager.getConnection() has the highest priority among all configuration methods. The JDBC URL has the second-highest priority, and the configuration file has the lowest priority. The explicitly configured parameters in a method with higher priorities always overwrite that same parameter configured in methods with lower priorities. For example, if charset is explicitly configured as "UTF-8" in the JDBC URL and "GKB" in the taos.cfg file, then "UTF-8" will be used.

      -

      Although the JDBC driver is implemented following the JDBC standard as much as possible, there are major differences between TDengine and traditional databases in terms of data models that lead to the differences in the driver implementation. Here is a list of head-ups for developers who have plenty of experience on traditional databases but little on TDengine:

      -
        -
      • TDengine does NOT support updating or deleting a specific record, which leads to some unsupported methods in the JDBC driver
      • -
      • TDengine currently does not support join or union operations, and thus, is lack of support for associated methods in the JDBC driver
      • -
      • TDengine supports batch insertions which are controlled at the level of SQL statement writing instead of API calls
      • -
      • TDengine doesn't support nested queries and neither does the JDBC driver. Thus for each established connection to TDengine, there should be only one open result set associated with it
      • -
      -

      All the error codes and error messages can be found in TSDBError.java . For a more detailed coding example, please refer to the demo project JDBCDemo in TDengine's code examples.

      -

      Python Connector

      -

      Pre-requirement

      -
    1. TDengine installed, TDengine-client installed if on Windows
    2. -
    3. python 2.7 or >= 3.4
    4. -
    5. pip installed
    6. -

      Installation

      -

      Linux

      -

      Users can find python client packages in our source code directory src/connector/python. There are two directories corresponding to two python versions. Please choose the correct package to install. Users can use pip command to install:

      -
      pip install src/connector/python/linux/python2/
      -

      or

      -
      pip install src/connector/python/linux/python3/
      -

      Windows

      -

      Assumed the Windows TDengine client has been installed , copy the file "C:\TDengine\driver\taos.dll" to the folder "C:\windows\system32", and then enter the cmd Windows command interface

      -
      cd C:\TDengine\connector\python\windows
      -
      pip install python2\
      -

      or

      -
      cd C:\TDengine\connector\python\windows
      -
      pip install python3\
      -

      * If pip command is not installed on the system, users can choose to install pip or just copy the taos directory in the python client directory to the application directory to use.

      -

      Usage

      -

      Examples

      -
    7. import TDengine module at first:
    8. -
      import taos 
      -
    9. get the connection
    10. -
      
      -conn = taos.connect(host="127.0.0.1", user="root", password="taosdata", config="/etc/taos")
      -c1 = conn.cursor()
      -
      -

      * host is the IP of TDengine server, and config is the directory where exists the TDengine client configure file

      -
    11. insert records into the database
    12. -
      
      -import datetime
      - 
      -# create a database
      -c1.execute('create database db')
      -c1.execute('use db')
      -# create a table
      -c1.execute('create table tb (ts timestamp, temperature int, humidity float)')
      -# insert a record
      -start_time = datetime.datetime(2019, 11, 1)
      -affected_rows = c1.execute('insert into tb values (\'%s\', 0, 0.0)' %start_time)
      -# insert multiple records in a batch
      -time_interval = datetime.timedelta(seconds=60)
      -sqlcmd = ['insert into tb values']
      -for irow in range(1,11):
      -  start_time += time_interval
      -  sqlcmd.append('(\'%s\', %d, %f)' %(start_time, irow, irow*1.2))
      -affected_rows = c1.execute(' '.join(sqlcmd))
      -
      -
    13. query the database
    14. -
      -c1.execute('select * from tb')
      -# fetch all returned results
      -data = c1.fetchall()
      -# data is a list of returned rows with each row being a tuple
      -numOfRows = c1.rowcount
      -numOfCols = c1.descriptions
      -for irow in range(numOfRows):
      -  print("Row%d: ts=%s, temperature=%d, humidity=%f" %(irow, data[irow][0], data[irow][1],data[irow][2])
      -  
      -# use the cursor as an iterator to retrieve all returned results
      -c1.execute('select * from tb')
      -for data in c1:
      -  print("ts=%s, temperature=%d, humidity=%f" %(data[0], data[1],data[2])
      -
      -
    15. close the connection
    16. -
      -c1.close()
      -conn.close()
      -
      -

      Help information

      -

      Users can get module information from Python help interface or refer to our [python code example](). We list the main classes and methods below:

      -
        -
      • TaosConnection class

        -

        Run help(taos.TaosConnection) in python terminal for details.

      • -
      • TaosCursor class

        -

        Run help(taos.TaosCursor) in python terminal for details.

      • -
      • connect method

        -

        Open a connection. Run help(taos.connect) in python terminal for details.

      • -
      -

      RESTful Connector

      -

      TDengine also provides RESTful API to satisfy developing on different platforms. Unlike other databases, TDengine RESTful API applies operations to the database through the SQL command in the body of HTTP POST request. What users are required to provide is just a URL.

      -

      For the time being, TDengine RESTful API uses a \ generated from username and password for identification. Safer identification methods will be provided in the future.

      -

      HTTP URL encoding

      -

      To use TDengine RESTful API, the URL should have the following encoding format:

      -
      http://<ip>:<PORT>/rest/sql
      -
        -
      • ip: IP address of any node in a TDengine cluster
      • -
      • PORT: TDengine HTTP service port. It is 6020 by default.
      • -
      -

      For example, the URL encoding http://192.168.0.1:6020/rest/sql used to send HTTP request to a TDengine server with IP address as 192.168.0.1.

      -

      It is required to add a token in an HTTP request header for identification.

      -
      Authorization: Basic <TOKEN>
      -

      The HTTP request body contains the SQL command to run. If the SQL command contains a table name, it should also provide the database name it belongs to in the form of <db_name>.<tb_name>. Otherwise, an error code is returned.

      -

      For example, use curl command to send a HTTP request:

      -
      curl -H 'Authorization: Basic <TOKEN>' -d '<SQL>' <ip>:<PORT>/rest/sql
      -

      or use

      -
      curl -u username:password -d '<SQL>' <ip>:<PORT>/rest/sql
      -

      where TOKEN is the encryted string of {username}:{password} using the Base64 algorithm, e.g. root:taosdata will be encoded as cm9vdDp0YW9zZGF0YQ==

      -

      HTTP response

      -

      The HTTP resonse is in JSON format as below:

      -
      {
      -    "status": "succ",
      -    "head": ["column1","column2", …],
      -    "data": [
      -        ["2017-12-12 23:44:25.730", 1],
      -        ["2017-12-12 22:44:25.728", 4]
      -    ],
      -    "rows": 2
      -} 
      -

      Specifically,

      -
        -
      • status: the result of the operation, success or failure
      • -
      • head: description of returned result columns
      • -
      • data: the returned data array. If no data is returned, only an affected_rows field is listed
      • -
      • rows: the number of rows returned
      • -
      -

      Example

      -
        -
      • Use curl command to query all the data in table t1 of database demo:

        -

        curl -H 'Authorization: Basic cm9vdDp0YW9zZGF0YQ==' -d 'select * from demo.t1' 192.168.0.1:6020/rest/sql

      • -
      -

      The return value is like:

      -
      {
      -    "status": "succ",
      -    "head": ["column1","column2","column3"],
      -    "data": [
      -        ["2017-12-12 23:44:25.730", 1, 2.3],
      -        ["2017-12-12 22:44:25.728", 4, 5.6]
      -    ],
      -    "rows": 2
      -}
      -
        -
      • Use HTTP to create a database:

        -

        curl -H 'Authorization: Basic cm9vdDp0YW9zZGF0YQ==' -d 'create database demo' 192.168.0.1:6020/rest/sql

        -

        The return value should be:

      • -
      -
      {
      -    "status": "succ",
      -    "head": ["affected_rows"],
      -    "data": [[1]],
      -    "rows": 1,
      -}
      -

      Go Connector

      -

      TDengine also provides a Go client package named taosSql for users to access TDengine with Go. The package is in /usr/local/taos/connector/go/src/taosSql by default if you installed TDengine. Users can copy the directory /usr/local/taos/connector/go/src/taosSql to the src directory of your project and import the package in the source code for use.

      -
      import (
      -    "database/sql"
      -    _ "taosSql"
      -)
      -

      The taosSql package is in cgo form, which calls TDengine C/C++ sync interfaces. So a connection is allowed to be used by one thread at the same time. Users can open multiple connections for multi-thread operations.

      -

      Please refer the the demo code in the package for more information.

      -

      Node.js Connector

      -

      TDengine also provides a node.js connector package that is installable through npm. The package is also in our source code at src/connector/nodejs/. The following instructions are also available here

      -

      To get started, just type in the following to install the connector through npm.

      -
      npm install td-connector
      -

      It is highly suggested you use npm. If you don't have it installed, you can also just copy the nodejs folder from src/connector/nodejs/ into your node project folder.

      -

      To interact with TDengine, we make use of the node-gyp library. To install, you will need to install the following depending on platform (the following instructions are quoted from node-gyp)

      -

      On Unix

      -
        -
      • python (v2.7 recommended, v3.x.x is not supported)
      • -
      • make
      • -
      • A proper C/C++ compiler toolchain, like GCC
      • -
      -

      On macOS

      -
        -
      • python (v2.7 recommended, v3.x.x is not supported) (already installed on macOS)

      • -
      • Xcode

      • -
      • You also need to install the

        -
        Command Line Tools
        -

        via Xcode. You can find this under the menu

        -
        Xcode -> Preferences -> Locations
        -

        (or by running

        -
        xcode-select --install
        -

        in your Terminal)

        -
          -
        • This step will install gcc and the related toolchain containing make
      • -
      -

      On Windows

      -

      Option 1

      -

      Install all the required tools and configurations using Microsoft's windows-build-tools using npm install --global --production windows-build-tools from an elevated PowerShell or CMD.exe (run as Administrator).

      -

      Option 2

      -

      Install tools and configuration manually:

      -
        -
      • Install Visual C++ Build Environment: Visual Studio Build Tools (using "Visual C++ build tools" workload) or Visual Studio 2017 Community (using the "Desktop development with C++" workload)
      • -
      • Install Python 2.7 (v3.x.x is not supported), and run npm config set python python2.7 (or see below for further instructions on specifying the proper Python version and path.)
      • -
      • Launch cmd, npm config set msvs_version 2017
      • -
      -

      If the above steps didn't work for you, please visit Microsoft's Node.js Guidelines for Windows for additional tips.

      -

      To target native ARM64 Node.js on Windows 10 on ARM, add the components "Visual C++ compilers and libraries for ARM64" and "Visual C++ ATL for ARM64".

      -

      Usage

      -

      The following is a short summary of the basic usage of the connector, the full api and documentation can be found here

      -

      Connection

      -

      To use the connector, first require the library td-connector. Running the function taos.connect with the connection options passed in as an object will return a TDengine connection object. The required connection option is host, other options if not set, will be the default values as shown below.

      -

      A cursor also needs to be initialized in order to interact with TDengine from Node.js.

      -
      const taos = require('td-connector');
      -var conn = taos.connect({host:"127.0.0.1", user:"root", password:"taosdata", config:"/etc/taos",port:0})
      -var cursor = conn.cursor(); // Initializing a new cursor
      -

      To close a connection, run

      -
      conn.close();
      -

      Queries

      -

      We can now start executing simple queries through the cursor.query function, which returns a TaosQuery object.

      -
      var query = cursor.query('show databases;')
      -

      We can get the results of the queries through the query.execute() function, which returns a promise that resolves with a TaosResult object, which contains the raw data and additional functionalities such as pretty printing the results.

      -
      var promise = query.execute();
      -promise.then(function(result) {
      -  result.pretty(); //logs the results to the console as if you were in the taos shell
      -});
      -

      You can also query by binding parameters to a query by filling in the question marks in a string as so. The query will automatically parse what was binded and convert it to the proper format for use with TDengine

      -
      var query = cursor.query('select * from meterinfo.meters where ts <= ? and areaid = ?;').bind(new Date(), 5);
      -query.execute().then(function(result) {
      -  result.pretty();
      -})
      -

      The TaosQuery object can also be immediately executed upon creation by passing true as the second argument, returning a promise instead of a TaosQuery.

      -
      var promise = cursor.query('select * from meterinfo.meters where v1 = 30;', true)
      -promise.then(function(result) {
      -  result.pretty();
      -})
      -

      Async functionality

      -

      Async queries can be performed using the same functions such as cursor.execute, cursor.query, but now with _a appended to them.

      -

      Say you want to execute an two async query on two seperate tables, using cursor.query_a, you can do that and get a TaosQuery object, which upon executing with the execute_a function, returns a promise that resolves with a TaosResult object.

      -
      var promise1 = cursor.query_a('select count(*), avg(v1), avg(v2) from meter1;').execute_a()
      -var promise2 = cursor.query_a('select count(*), avg(v1), avg(v2) from meter2;').execute_a();
      -promise1.then(function(result) {
      -  result.pretty();
      -})
      -promise2.then(function(result) {
      -  result.pretty();
      -})
      -

      Example

      -

      An example of using the NodeJS connector to create a table with weather data and create and execute queries can be found here (The preferred method for using the connector)

      -

      An example of using the NodeJS connector to achieve the same things but without all the object wrappers that wrap around the data returned to achieve higher functionality can be found here

      Back
      diff --git a/2.0/documentation/tdenginedocs-en/contributor_license_agreement/index.html b/2.0/documentation/tdenginedocs-en/contributor_license_agreement/index.html deleted file mode 100644 index a012993efe..0000000000 --- a/2.0/documentation/tdenginedocs-en/contributor_license_agreement/index.html +++ /dev/null @@ -1,20 +0,0 @@ -Documentation | Taos Data
      Back

      TaosData Contributor License Agreement

      -

      This TaosData Contributor License Agreement (CLA) applies to any contribution you make to any TaosData projects. If you are representing your employing organization to sign this agreement, please warrant that you have the authority to grant the agreement.

      -

      Terms

      -

      "TaosData", "we", "our" and "us" means TaosData, inc.

      -

      "You" and "your" means you or the organization you are on behalf of to sign this agreement.

      -

      "Contribution" means any original work you, or the organization you represent submit to TaosData for any project in any manner.

      -

      Copyright License

      -

      All rights of your Contribution submitted to TaosData in any manner are granted to TaosData and recipients of software distributed by TaosData. You waive any rights that my affect our ownership of the copyright and grant to us a perpetual, worldwide, transferable, non-exclusive, no-charge, royalty-free, irrevocable, and sublicensable license to use, reproduce, prepare derivative works of, publicly display, publicly perform, sublicense, and distribute Contributions and any derivative work created based on a Contribution.

      -

      Patent License

      -

      With respect to any patents you own or that you can license without payment to any third party, you grant to us and to any recipient of software distributed by us, a perpetual, worldwide, transferable, non-exclusive, no-charge, royalty-free, irrevocable patent license to make, have make, use, sell, offer to sell, import, and otherwise transfer the Contribution in whole or in part, alone or included in any product under any patent you own, or license from a third party, that is necessarily infringed by the Contribution or by combination of the Contribution with any Work.

      -

      Your Representations and Warranties

      -

      You represent and warrant that:

      -
        -
      • the Contribution you submit is an original work that you can legally grant the rights set out in this agreement.

      • -
      • the Contribution you submit and licenses you granted does not and will not, infringe the rights of any third party.

      • -
      • you are not aware of any pending or threatened claims, suits, actions, or charges pertaining to the contributions. You also warrant to notify TaosData immediately if you become aware of any such actual or potential claims, suits, actions, allegations or charges.

      • -
      -

      Support

      -

      You are not obligated to support your Contribution except you volunteer to provide support. If you want, you can provide for a fee.

      -

      I agree and accept on behalf of myself and behalf of my organization:

      Back
      \ No newline at end of file diff --git a/2.0/documentation/tdenginedocs-en/data-model-and-architecture/index.html b/2.0/documentation/tdenginedocs-en/data-model-and-architecture/index.html deleted file mode 100644 index 4ee5a553f5..0000000000 --- a/2.0/documentation/tdenginedocs-en/data-model-and-architecture/index.html +++ /dev/null @@ -1,129 +0,0 @@ -Documentation | Taos Data
      Back

      Data Model and Architecture

      -

      Data Model

      -

      A Typical IoT Scenario

      -

      In a typical IoT scenario, there are many types of devices. Each device is collecting one or multiple metrics. For a specific type of device, the collected data looks like the table below:

      -
      - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      Device IDTime StampValue 1Value 2Value 3Tag 1Tag 2
      D1001153854868500010.32190.31RedTesla
      D1002153854868400010.22200.23BlueBMW
      D1003153854868650011.52210.35BlackHonda
      D1004153854868550013.42230.29RedVolvo
      D1001153854869500012.62180.33RedTesla
      D1004153854869660011.82210.28BlackHonda
      -

      Each data record has device ID, timestamp, the collected metrics, and static tags associated with the device. Each device generates a data record in a pre-defined timer or triggered by an event. It is a sequence of data points, like a stream.

      -

      Data Characteristics

      -

      Being a series of data points over time, data points generated by devices, sensors, servers, or applications have strong common characteristics.

      -
        -
      1. metric is always structured data;
      2. -
      3. there are rarely delete/update operations on collected data;
      4. -
      5. there is only one single data source for one device or sensor;
      6. -
      7. ratio of read/write is much lower than typical Internet application;
      8. -
      9. the user pays attention to the trend of data, not the specific value at a specific time;
      10. -
      11. there is always a data retention policy;
      12. -
      13. the data query is always executed in a given time range and a subset of devices;
      14. -
      15. real-time aggregation or analytics is mandatory;
      16. -
      17. traffic is predictable based on the number of devices and sampling frequency;
      18. -
      19. data volume is huge, a system may generate 10 billion data points in a day.
      20. -
      -

      By utilizing the above characteristics, TDengine designs the storage and computing engine in a special and optimized way for time-series data. The system efficiency is improved significantly.

      -

      Relational Database Model

      -

      Since time-series data is more likely to be structured data, TDengine adopts the traditional relational database model to process them. You need to create a database, create tables with schema definition, then insert data points and execute queries to explore the data. Standard SQL is used, there is no learning curve.

      -

      One Table for One Device

      -

      Due to different network latency, the data points from different devices may arrive at the server out of order. But for the same device, data points will arrive at the server in order if system is designed well. To utilize this special feature, TDengine requires the user to create a table for each device (time-stream). For example, if there are over 10,000 smart meters, 10,000 tables shall be created. For the table above, 4 tables shall be created for device D1001, D1002, D1003 and D1004, to store the data collected.

      -

      This strong requirement can guarantee the data points from a device can be saved in a continuous memory/hard disk space block by block. If queries are applied only on one device in a time range, this design will reduce the read latency significantly since a whole block is owned by one single device. Also, write latency can be significantly reduced too, since the data points generated by the same device will arrive in order, the new data point will be simply appended to a block. Cache block size and the rows of records in a file block can be configured to fit the scenarios.

      -

      Best Practices

      -

      Table: TDengine suggests to use device ID as the table name (like D1001 in the above diagram). Each device may collect one or more metrics (like value1, valu2, valu3 in the diagram). Each metric has a column in the table, the metric name can be used as the column name. The data type for a column can be int, float, double, tinyint, bigint, bool or binary. Sometimes, a device may have multiple metric group, each group have different sampling period, you shall create a table for each group for each device. The first column in the table must be time stamp. TDengine uses time stamp as the index, and won’t build the index on any metrics stored.

      -

      Tags: to support aggregation over multiple tables efficiently, STable(Super Table) concept is introduced by TDengine. A STable is used to represent the same type of device. The schema is used to define the collected metrics(like value1, value2, value3 in the diagram), and tags are used to define the static attributes for each table or device(like tag1, tag2 in the diagram). A table is created via STable with a specific tag value. All or a subset of tables in a STable can be aggregated by filtering tag values.

      -

      Database: different types of devices may generate data points in different patterns and shall be processed differently. For example, sampling frequency, data retention policy, replication number, cache size, record size, the compression algorithm may be different. To make the system more efficient, TDengine suggests creating a different database with unique configurations for different scenarios

      -

      Schemaless vs Schema: compared with NoSQL database, since a table with schema definition shall be created before the data points can be inserted, flexibilities are not that good, especially when the schema is changed. But in most IoT scenarios, the schema is well defined and is rarely changed, the loss of flexibilities won’t be a big pain to developers or the administrator. TDengine allows the application to change the schema in a second even there is a huge amount of historical data when schema has to be changed.

      -

      TDengine does not impose a limitation on the number of tables, STables, or databases. You can create any number of STable or databases to fit the scenarios.

      -

      Architecture

      -

      There are two main modules in TDengine server as shown in Picture 1: Management Module (MGMT) and Data Module(DNODE). The whole TDengine architecture also includes a TDengine Client Module.

      -

      -
      Picture 1 TDengine Architecture

      -

      MGMT Module

      -

      The MGMT module deals with the storage and querying on metadata, which includes information about users, databases, and tables. Applications will connect to the MGMT module at first when connecting the TDengine server. When creating/dropping databases/tables, The request is sent to the MGMT module at first to create/delete metadata. Then the MGMT module will send requests to the data module to allocate/free resources required. In the case of writing or querying, applications still need to visit MGMT module to get meta data, according to which, then access the DNODE module.

      -

      DNODE Module

      -

      The DNODE module is responsible for storing and querying data. For the sake of future scaling and high-efficient resource usage, TDengine applies virtualization on resources it uses. TDengine introduces the concept of virtual node (vnode), which is the unit of storage, resource allocation and data replication (enterprise edition). As is shown in Picture 2, TDengine treats each data node as an aggregation of vnodes.

      -

      When a DB is created, the system will allocate a vnode. Each vnode contains multiple tables, but a table belongs to only one vnode. Each DB has one or mode vnodes, but one vnode belongs to only one DB. Each vnode contains all the data in a set of tables. Vnodes have their own cache, directory to store data. Resources between different vnodes are exclusive with each other, no matter cache or file directory. However, resources in the same vnode are shared between all the tables in it. By virtualization, TDengine can distribute resources reasonably to each vnode and improve resource usage and concurrency. The number of vnodes on a dnode is configurable according to its hardware resources.

      -

      -
      Picture 2 TDengine Virtualization

      -

      Client Module

      -

      TDengine client module accepts requests (mainly in SQL form) from applications and converts the requests to internal representations and sends to the server side. TDengine supports multiple interfaces, which are all built on top of TDengine client module.

      -

      For the communication between client and MGMT module, TCP/UDP is used, the port is set by the parameter mgmtShellPort in system configuration file taos.cfg, default is 6030. For the communication between client and DNODE module, TCP/UDP is used, the port is set by the parameter vnodeShellPort in the system configuration file, default is 6035.

      -

      Writing Process

      -

      Picture 3 shows the full writing process of TDengine. TDengine uses Writing Ahead Log strategy to assure data security and integrity. Data received from the client is written to the commit log at first. When TDengine recovers from crashes caused by power lose or other situations, the commit log is used to recover data. After writting to commit log, data will be wrtten to the corresponding vnode cache, then an acknowledgment is sent to the application. There are two mechanisms that can flush data in cache to disk for persistent storage:

      -
        -
      1. Flush driven by timer: There is a backend timer which flushes data in cache periodically to disks. The period is configurable via parameter commitTime in system configuration file taos.cfg.
      2. -
      3. Flush driven by data: Data in the cache is also flushed to disks when the left buffer size is below a threshold. Flush driven by data can reset the timer of flush driven by the timer.
      4. -
      -

      -
      Picture 3 TDengine Writting Process

      -

      New commit log file will be opened when the committing process begins. When the committing process finishes, the old commit file will be removed.

      -

      Data Storage

      -

      TDengine data are saved in /var/lib/taos directory by default. It can be changed to other directories by setting the parameter dataDir in system configuration file taos.cfg.

      -

      TDengine's metadata includes the database, table, user, super table and tag information. To reduce the latency, metadata are all buffered in the cache.

      -

      Data records saved in tables are sharded according to the time range. Data of tables in the same vnode in a certain time range are saved in the same file group. This sharding strategy can effectively improve data searching speed. By default, one group of files contain data in 10 days, which can be configured by daysPerFile in the configuration file or by DAYS keyword in CREATE DATABASE clause.

      -

      Data records are removed automatically once their lifetime is passed. The lifetime is configurable via parameter daysToKeep in the system configuration file. The default value is 3650 days.

      -

      Data in files are blockwise. A data block only contains one table's data. Records in the same data block are sorted according to the primary timestamp. To improve the compression ratio, records are stored column by column, and the different compression algorithm is applied based on each column's data type.

      Back
      \ No newline at end of file diff --git a/2.0/documentation/tdenginedocs-en/faq/index.html b/2.0/documentation/tdenginedocs-en/faq/index.html deleted file mode 100644 index 2d716cd6dc..0000000000 --- a/2.0/documentation/tdenginedocs-en/faq/index.html +++ /dev/null @@ -1,27 +0,0 @@ -Documentation | Taos Data
      Back

      FAQ

      -

      1. When encountered with the error "failed to connect to server", what can I do?

      -

      The client may encounter connection errors. Please follow the steps below for troubleshooting:

      -
        -
      1. On the server side, execute systemctl status taosd to check the status of taosd service. If taosd is not running, start it and retry connecting.
      2. -
      3. Make sure you have used the correct server IP address to connect to.
      4. -
      5. Ping the server. If no response is received, check your network connection.
      6. -
      7. Check the firewall setting, make sure the TCP/UDP ports from 6030-6039 are enabled.
      8. -
      9. For JDBC, ODBC, Python, Go connections on Linux, make sure the native library libtaos.so are located at /usr/local/lib/taos, and /usr/local/lib/taos is in the LD_LIBRARY_PATH.
      10. -
      11. For JDBC, ODBC, Python, Go connections on Windows, make sure driver/c/taos.dll is in the system search path (or you can copy taos.dll into C:\Windows\System32)
      12. -
      13. If the above steps can not help, try the network diagnostic tool nc to check if TCP/UDP port works - check UDP port:nc -vuz {hostIP} {port} - check TCP port on server: nc -l {port} - check TCP port on client: nc {hostIP} {port}
      14. -
      -

      2. Why I get "Invalid SQL" error when a query is syntactically correct?

      -

      If you are sure your query has correct syntax, please check the length of the SQL string, it shall be less than 64KB.

      -

      3. Why I could not delete a super table?

      -

      Please make sure there are no tables under the super table. You could not delete a super table which still has associated tables.

      -

      4. Does TDengine support validation queries?

      -

      For the time being, TDengine does not have a specific set of validation queries. However, TDengine comes with a system monitoring database named 'sys', which can usually be used as a validation query object.

      -

      5. Can I delete or update a record that has been written into TDengine?

      -

      The answer is NO. The design of TDengine is based on the assumption that records are generated by the connected devices, you won't be allowed to change it. But TDengine provides a retention policy, the data records will be removed once their lifetime is passed.

      -

      6. How do I create a table with more than 250 columns?

      -

      For a single table, the maximum number of columns is 250. If for some reason, 250 columns are still not quite enough, our suggestion is to split the huge table into several smaller ones.

      -

      7. What is the most efficient way to write data to TDengine?

      -

      TDengine supports several different writing regimes. The most efficient way to write data to TDengine is to use batch inserting. For details on batch insertion syntax, please refer to Taos SQL

      Back
      \ No newline at end of file diff --git a/2.0/documentation/tdenginedocs-en/getting-started/index.html b/2.0/documentation/tdenginedocs-en/getting-started/index.html deleted file mode 100644 index 8968441b55..0000000000 --- a/2.0/documentation/tdenginedocs-en/getting-started/index.html +++ /dev/null @@ -1,88 +0,0 @@ -Documentation | Taos Data
      Back

      Getting Started

      -

      Quick Start

      -

      At the moment, TDengine only runs on Linux. You can set up and install it either from the source code or the packages. It takes only a few seconds from download to run it successfully.

      -

      Install from Source

      -

      Please visit our github page for instructions on installation from the source code.

      -

      Install from Package

      -

      Three different packages are provided, please pick up the one you like.

      - -

      For the time being, TDengine only supports installation on Linux systems using systemd as the service manager. To check if your system has systemd, use the which command.

      -
      which systemd
      -

      If the systemd command is not found, please install from source code.

      -

      Running TDengine

      -

      After installation, start the TDengine service by the systemctl command.

      -
      systemctl start taosd
      -

      Then check if the server is working now.

      -
      systemctl status taosd
      -

      If the service is running successfully, you can play around through TDengine shell taos, the command line interface tool located in directory /usr/local/bin/taos

      -

      Note: The systemctl command needs the root privilege. Use sudo if you are not the root user.

      -

      TDengine Shell

      -

      To launch TDengine shell, the command line interface, in a Linux terminal, type:

      -
      taos
      -

      The welcome message is printed if the shell connects to TDengine server successfully, otherwise, an error message will be printed (refer to our FAQ page for troubleshooting the connection error). The TDengine shell prompt is:

      -
      taos>
      -

      In the TDengine shell, you can create databases, create tables and insert/query data with SQL. Each query command ends with a semicolon. It works like MySQL, for example:

      -
      create database db;
      -use db;
      -create table t (ts timestamp, speed int);
      -insert into t values ('2019-07-15 10:00:00', 10);
      -insert into t values ('2019-07-15 10:01:05', 20);
      -select * from t;
      -          ts          |   speed   |
      -===================================
      - 19-07-15 10:00:00.000|         10|
      - 19-07-15 10:01:05.000|         20|
      -Query OK, 2 row(s) in set (0.001700s)
      -

      Besides the SQL commands, the system administrator can check system status, add or delete accounts, and manage the servers.

      -

      Shell Command Line Parameters

      -

      You can run taos command with command line options to fit your needs. Some frequently used options are listed below:

      -
        -
      • -c, --config-dir: set the configuration directory. It is /etc/taos by default
      • -
      • -h, --host: set the IP address of the server it will connect to, Default is localhost
      • -
      • -s, --commands: set the command to run without entering the shell
      • -
      • -u, -- user: user name to connect to server. Default is root
      • -
      • -p, --password: password. Default is 'taosdata'
      • -
      • -?, --help: get a full list of supported options
      • -
      -

      Examples:

      -
      taos -h 192.168.0.1 -s "use db; show tables;"
      -

      Run Batch Commands

      -

      Inside TDengine shell, you can run batch commands in a file with source command.

      -
      taos> source <filename>;
      -

      Tips

      -
        -
      • Use up/down arrow key to check the command history
      • -
      • To change the default password, use "alter user" command
      • -
      • ctrl+c to interrupt any queries
      • -
      • To clean the cached schema of tables or STables, execute command RESET QUERY CACHE
      • -
      -

      Major Features

      -

      The core functionality of TDengine is the time-series database. To reduce the development and management complexity, and to improve the system efficiency further, TDengine also provides caching, pub/sub messaging system, and stream computing functionalities. It provides a full stack for IoT big data platform. The detailed features are listed below:

      -
        -
      • SQL like query language used to insert or explore data

      • -
      • C/C++, Java(JDBC), Python, Go, RESTful, and Node.JS interfaces for development

      • -
      • Ad hoc queries/analysis via Python/R/Matlab or TDengine shell

      • -
      • Continuous queries to support sliding-window based stream computing

      • -
      • Super table to aggregate multiple time-streams efficiently with flexibility

      • -
      • Aggregation over a time window on one or multiple time-streams

      • -
      • Built-in messaging system to support publisher/subscriber model

      • -
      • Built-in cache for each time stream to make latest data available as fast as light speed

      • -
      • Transparent handling of historical data and real-time data

      • -
      • Integrating with Telegraf, Grafana and other tools seamlessly

      • -
      • A set of tools or configuration to manage TDengine

      • -
      -

      For enterprise edition, TDengine provides more advanced features below:

      -
        -
      • Linear scalability to deliver higher capacity/throughput

      • -
      • High availability to guarantee the carrier-grade service

      • -
      • Built-in replication between nodes which may span multiple geographical sites

      • -
      • Multi-tier storage to make historical data management simpler and cost-effective

      • -
      • Web-based management tools and other tools to make maintenance simpler

      • -
      -

      TDengine is specially designed and optimized for time-series data processing in IoT, connected cars, Industrial IoT, IT infrastructure and application monitoring, and other scenarios. Compared with other solutions, it is 10x faster on insert/query speed. With a single-core machine, over 20K requestes can be processed, millions data points can be ingested, and over 10 million data points can be retrieved in a second. Via column-based storage and tuned compression algorithm for different data types, less than 1/10 storage space is required.

      -

      Explore More on TDengine

      -

      Please read through the whole documentation to learn more about TDengine.

      Back
      diff --git a/2.0/documentation/tdenginedocs-en/index.html b/2.0/documentation/tdenginedocs-en/index.html deleted file mode 100644 index ebb728a0df..0000000000 --- a/2.0/documentation/tdenginedocs-en/index.html +++ /dev/null @@ -1 +0,0 @@ -Documentation | Taos Data

      Documentation

      TDengine is a highly efficient platform to store, query, and analyze time-series data. It works like a relational database, but you are strongly suggested to read through the following documentation before you experience it.

      Getting Started

      • Quick Start: download, install and experience TDengine in a few seconds
      • TDengine Shell: command-line interface to access TDengine server
      • Major Features: insert/query, aggregation, cache, pub/sub, continuous query

      Data Model and Architecture

      • Data Model: relational database model, but one table for one device with static tags
      • Architecture: Management Module, Data Module, Client Module
      • Writing Process: records recieved are written to WAL, cache, then ack is sent back to client
      • Data Storage: records are sharded in the time range, and stored column by column

      TAOS SQL

      • Data Types: support timestamp, int, float, double, binary, nchar, bool, and other types
      • Database Management: add, drop, check databases
      • Table Management: add, drop, check, alter tables
      • Inserting Records: insert one or more records into tables, historical records can be imported
      • Data Query: query data with time range and filter conditions, support limit/offset
      • SQL Functions: support aggregation, selector, transformation functions
      • Downsampling: aggregate data in successive time windows, support interpolation

      Super Table

      Advanced Features

      • Continuous Query: query executed by TDengine periodically with a sliding window
      • Publisher/Subscriber: subscribe to the newly arrived data like a typical messaging system
      • Caching: the newly arrived data of each device/table will always be cached

      Connector

      • C/C++ Connector: primary method to connect to the server through libtaos client library
      • Java Connector: driver for connecting to the server from Java applications using the JDBC API
      • Python Connector: driver for connecting to the server from Python applications
      • RESTful Connector: a simple way to interact with TDengine via HTTP
      • Go Connector: driver for connecting to the server from Go applications
      • Node.js Connector: driver for connecting to the server from node applications

      Connections with Other Tools

      • Telegraf: pass the collected DevOps metrics to TDengine
      • Grafana: query the data saved in TDengine and visualize them
      • Matlab: access TDengine server from Matlab via JDBC
      • R: access TDengine server from R via JDBC

      Administrator

      More on System Architecture

      Tutorials & FAQ

      • FAQ: a list of frequently asked questions and answers
      • Use cases: a few typical cases to explain how to use TDengine in IoT platform
      Back
      \ No newline at end of file diff --git a/2.0/documentation/tdenginedocs-en/lib/bootstrap.min.css b/2.0/documentation/tdenginedocs-en/lib/bootstrap.min.css deleted file mode 100644 index 882691283a..0000000000 --- a/2.0/documentation/tdenginedocs-en/lib/bootstrap.min.css +++ /dev/null @@ -1,7 +0,0 @@ -/*! - * Bootstrap v4.1.3 (https://getbootstrap.com/) - * Copyright 2011-2018 The Bootstrap Authors - * Copyright 2011-2018 Twitter, Inc. - * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) - */:root{--blue:#007bff;--indigo:#6610f2;--purple:#6f42c1;--pink:#e83e8c;--red:#dc3545;--orange:#fd7e14;--yellow:#ffc107;--green:#28a745;--teal:#20c997;--cyan:#17a2b8;--white:#fff;--gray:#6c757d;--gray-dark:#343a40;--primary:#007bff;--secondary:#6c757d;--success:#28a745;--info:#17a2b8;--warning:#ffc107;--danger:#dc3545;--light:#f8f9fa;--dark:#343a40;--breakpoint-xs:0;--breakpoint-sm:576px;--breakpoint-md:768px;--breakpoint-lg:992px;--breakpoint-xl:1200px;--font-family-sans-serif:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";--font-family-monospace:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace}*,::after,::before{box-sizing:border-box}html{font-family:sans-serif;line-height:1.15;-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%;-ms-overflow-style:scrollbar;-webkit-tap-highlight-color:transparent}@-ms-viewport{width:device-width}article,aside,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}body{margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";font-size:1rem;font-weight:400;line-height:1.5;color:#212529;text-align:left;background-color:#fff}[tabindex="-1"]:focus{outline:0!important}hr{box-sizing:content-box;height:0;overflow:visible}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem}p{margin-top:0;margin-bottom:1rem}abbr[data-original-title],abbr[title]{text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted;cursor:help;border-bottom:0}address{margin-bottom:1rem;font-style:normal;line-height:inherit}dl,ol,ul{margin-top:0;margin-bottom:1rem}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem}dfn{font-style:italic}b,strong{font-weight:bolder}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{color:#007bff;text-decoration:none;background-color:transparent;-webkit-text-decoration-skip:objects}a:hover{color:#0056b3;text-decoration:underline}a:not([href]):not([tabindex]){color:inherit;text-decoration:none}a:not([href]):not([tabindex]):focus,a:not([href]):not([tabindex]):hover{color:inherit;text-decoration:none}a:not([href]):not([tabindex]):focus{outline:0}code,kbd,pre,samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;font-size:1em}pre{margin-top:0;margin-bottom:1rem;overflow:auto;-ms-overflow-style:scrollbar}figure{margin:0 0 1rem}img{vertical-align:middle;border-style:none}svg{overflow:hidden;vertical-align:middle}table{border-collapse:collapse}caption{padding-top:.75rem;padding-bottom:.75rem;color:#6c757d;text-align:left;caption-side:bottom}th{text-align:inherit}label{display:inline-block;margin-bottom:.5rem}button{border-radius:0}button:focus{outline:1px dotted;outline:5px auto -webkit-focus-ring-color}button,input,optgroup,select,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,input{overflow:visible}button,select{text-transform:none}[type=reset],[type=submit],button,html [type=button]{-webkit-appearance:button}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{padding:0;border-style:none}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}input[type=date],input[type=datetime-local],input[type=month],input[type=time]{-webkit-appearance:listbox}textarea{overflow:auto;resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;max-width:100%;padding:0;margin-bottom:.5rem;font-size:1.5rem;line-height:inherit;color:inherit;white-space:normal}progress{vertical-align:baseline}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{outline-offset:-2px;-webkit-appearance:none}[type=search]::-webkit-search-cancel-button,[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}output{display:inline-block}summary{display:list-item;cursor:pointer}template{display:none}[hidden]{display:none!important}.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{margin-bottom:.5rem;font-family:inherit;font-weight:500;line-height:1.2;color:inherit}.h1,h1{font-size:2.5rem}.h2,h2{font-size:2rem}.h3,h3{font-size:1.75rem}.h4,h4{font-size:1.5rem}.h5,h5{font-size:1.25rem}.h6,h6{font-size:1rem}.lead{font-size:1.25rem;font-weight:300}.display-1{font-size:6rem;font-weight:300;line-height:1.2}.display-2{font-size:5.5rem;font-weight:300;line-height:1.2}.display-3{font-size:4.5rem;font-weight:300;line-height:1.2}.display-4{font-size:3.5rem;font-weight:300;line-height:1.2}hr{margin-top:1rem;margin-bottom:1rem;border:0;border-top:1px solid rgba(0,0,0,.1)}.small,small{font-size:80%;font-weight:400}.mark,mark{padding:.2em;background-color:#fcf8e3}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;list-style:none}.list-inline-item{display:inline-block}.list-inline-item:not(:last-child){margin-right:.5rem}.initialism{font-size:90%;text-transform:uppercase}.blockquote{margin-bottom:1rem;font-size:1.25rem}.blockquote-footer{display:block;font-size:80%;color:#6c757d}.blockquote-footer::before{content:"\2014 \00A0"}.img-fluid{max-width:100%;height:auto}.img-thumbnail{padding:.25rem;background-color:#fff;border:1px solid #dee2e6;border-radius:.25rem;max-width:100%;height:auto}.figure{display:inline-block}.figure-img{margin-bottom:.5rem;line-height:1}.figure-caption{font-size:90%;color:#6c757d}code{font-size:87.5%;color:#e83e8c;word-break:break-word}a>code{color:inherit}kbd{padding:.2rem .4rem;font-size:87.5%;color:#fff;background-color:#212529;border-radius:.2rem}kbd kbd{padding:0;font-size:100%;font-weight:700}pre{display:block;font-size:87.5%;color:#212529}pre code{font-size:inherit;color:inherit;word-break:normal}.pre-scrollable{max-height:340px;overflow-y:scroll}.container{width:100%;padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}@media (min-width:576px){.container{max-width:540px}}@media (min-width:768px){.container{max-width:720px}}@media (min-width:992px){.container{max-width:960px}}@media (min-width:1200px){.container{max-width:1140px}}.container-fluid{width:100%;padding-right:15px;padding-left:15px;margin-right:auto;margin-left:auto}.row{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;margin-right:-15px;margin-left:-15px}.no-gutters{margin-right:0;margin-left:0}.no-gutters>.col,.no-gutters>[class*=col-]{padding-right:0;padding-left:0}.col,.col-1,.col-10,.col-11,.col-12,.col-2,.col-3,.col-4,.col-5,.col-6,.col-7,.col-8,.col-9,.col-auto,.col-lg,.col-lg-1,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-lg-auto,.col-md,.col-md-1,.col-md-10,.col-md-11,.col-md-12,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-md-auto,.col-sm,.col-sm-1,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-sm-auto,.col-xl,.col-xl-1,.col-xl-10,.col-xl-11,.col-xl-12,.col-xl-2,.col-xl-3,.col-xl-4,.col-xl-5,.col-xl-6,.col-xl-7,.col-xl-8,.col-xl-9,.col-xl-auto{position:relative;width:100%;min-height:1px;padding-right:15px;padding-left:15px}.col{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.col-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:none}.col-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-first{-ms-flex-order:-1;order:-1}.order-last{-ms-flex-order:13;order:13}.order-0{-ms-flex-order:0;order:0}.order-1{-ms-flex-order:1;order:1}.order-2{-ms-flex-order:2;order:2}.order-3{-ms-flex-order:3;order:3}.order-4{-ms-flex-order:4;order:4}.order-5{-ms-flex-order:5;order:5}.order-6{-ms-flex-order:6;order:6}.order-7{-ms-flex-order:7;order:7}.order-8{-ms-flex-order:8;order:8}.order-9{-ms-flex-order:9;order:9}.order-10{-ms-flex-order:10;order:10}.order-11{-ms-flex-order:11;order:11}.order-12{-ms-flex-order:12;order:12}.offset-1{margin-left:8.333333%}.offset-2{margin-left:16.666667%}.offset-3{margin-left:25%}.offset-4{margin-left:33.333333%}.offset-5{margin-left:41.666667%}.offset-6{margin-left:50%}.offset-7{margin-left:58.333333%}.offset-8{margin-left:66.666667%}.offset-9{margin-left:75%}.offset-10{margin-left:83.333333%}.offset-11{margin-left:91.666667%}@media (min-width:576px){.col-sm{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.col-sm-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:none}.col-sm-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-sm-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-sm-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-sm-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-sm-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-sm-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-sm-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-sm-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-sm-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-sm-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-sm-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-sm-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-sm-first{-ms-flex-order:-1;order:-1}.order-sm-last{-ms-flex-order:13;order:13}.order-sm-0{-ms-flex-order:0;order:0}.order-sm-1{-ms-flex-order:1;order:1}.order-sm-2{-ms-flex-order:2;order:2}.order-sm-3{-ms-flex-order:3;order:3}.order-sm-4{-ms-flex-order:4;order:4}.order-sm-5{-ms-flex-order:5;order:5}.order-sm-6{-ms-flex-order:6;order:6}.order-sm-7{-ms-flex-order:7;order:7}.order-sm-8{-ms-flex-order:8;order:8}.order-sm-9{-ms-flex-order:9;order:9}.order-sm-10{-ms-flex-order:10;order:10}.order-sm-11{-ms-flex-order:11;order:11}.order-sm-12{-ms-flex-order:12;order:12}.offset-sm-0{margin-left:0}.offset-sm-1{margin-left:8.333333%}.offset-sm-2{margin-left:16.666667%}.offset-sm-3{margin-left:25%}.offset-sm-4{margin-left:33.333333%}.offset-sm-5{margin-left:41.666667%}.offset-sm-6{margin-left:50%}.offset-sm-7{margin-left:58.333333%}.offset-sm-8{margin-left:66.666667%}.offset-sm-9{margin-left:75%}.offset-sm-10{margin-left:83.333333%}.offset-sm-11{margin-left:91.666667%}}@media (min-width:768px){.col-md{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.col-md-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:none}.col-md-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-md-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-md-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-md-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-md-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-md-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-md-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-md-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-md-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-md-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-md-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-md-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-md-first{-ms-flex-order:-1;order:-1}.order-md-last{-ms-flex-order:13;order:13}.order-md-0{-ms-flex-order:0;order:0}.order-md-1{-ms-flex-order:1;order:1}.order-md-2{-ms-flex-order:2;order:2}.order-md-3{-ms-flex-order:3;order:3}.order-md-4{-ms-flex-order:4;order:4}.order-md-5{-ms-flex-order:5;order:5}.order-md-6{-ms-flex-order:6;order:6}.order-md-7{-ms-flex-order:7;order:7}.order-md-8{-ms-flex-order:8;order:8}.order-md-9{-ms-flex-order:9;order:9}.order-md-10{-ms-flex-order:10;order:10}.order-md-11{-ms-flex-order:11;order:11}.order-md-12{-ms-flex-order:12;order:12}.offset-md-0{margin-left:0}.offset-md-1{margin-left:8.333333%}.offset-md-2{margin-left:16.666667%}.offset-md-3{margin-left:25%}.offset-md-4{margin-left:33.333333%}.offset-md-5{margin-left:41.666667%}.offset-md-6{margin-left:50%}.offset-md-7{margin-left:58.333333%}.offset-md-8{margin-left:66.666667%}.offset-md-9{margin-left:75%}.offset-md-10{margin-left:83.333333%}.offset-md-11{margin-left:91.666667%}}@media (min-width:992px){.col-lg{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.col-lg-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:none}.col-lg-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-lg-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-lg-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-lg-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-lg-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-lg-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-lg-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-lg-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-lg-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-lg-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-lg-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-lg-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-lg-first{-ms-flex-order:-1;order:-1}.order-lg-last{-ms-flex-order:13;order:13}.order-lg-0{-ms-flex-order:0;order:0}.order-lg-1{-ms-flex-order:1;order:1}.order-lg-2{-ms-flex-order:2;order:2}.order-lg-3{-ms-flex-order:3;order:3}.order-lg-4{-ms-flex-order:4;order:4}.order-lg-5{-ms-flex-order:5;order:5}.order-lg-6{-ms-flex-order:6;order:6}.order-lg-7{-ms-flex-order:7;order:7}.order-lg-8{-ms-flex-order:8;order:8}.order-lg-9{-ms-flex-order:9;order:9}.order-lg-10{-ms-flex-order:10;order:10}.order-lg-11{-ms-flex-order:11;order:11}.order-lg-12{-ms-flex-order:12;order:12}.offset-lg-0{margin-left:0}.offset-lg-1{margin-left:8.333333%}.offset-lg-2{margin-left:16.666667%}.offset-lg-3{margin-left:25%}.offset-lg-4{margin-left:33.333333%}.offset-lg-5{margin-left:41.666667%}.offset-lg-6{margin-left:50%}.offset-lg-7{margin-left:58.333333%}.offset-lg-8{margin-left:66.666667%}.offset-lg-9{margin-left:75%}.offset-lg-10{margin-left:83.333333%}.offset-lg-11{margin-left:91.666667%}}@media (min-width:1200px){.col-xl{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;max-width:100%}.col-xl-auto{-ms-flex:0 0 auto;flex:0 0 auto;width:auto;max-width:none}.col-xl-1{-ms-flex:0 0 8.333333%;flex:0 0 8.333333%;max-width:8.333333%}.col-xl-2{-ms-flex:0 0 16.666667%;flex:0 0 16.666667%;max-width:16.666667%}.col-xl-3{-ms-flex:0 0 25%;flex:0 0 25%;max-width:25%}.col-xl-4{-ms-flex:0 0 33.333333%;flex:0 0 33.333333%;max-width:33.333333%}.col-xl-5{-ms-flex:0 0 41.666667%;flex:0 0 41.666667%;max-width:41.666667%}.col-xl-6{-ms-flex:0 0 50%;flex:0 0 50%;max-width:50%}.col-xl-7{-ms-flex:0 0 58.333333%;flex:0 0 58.333333%;max-width:58.333333%}.col-xl-8{-ms-flex:0 0 66.666667%;flex:0 0 66.666667%;max-width:66.666667%}.col-xl-9{-ms-flex:0 0 75%;flex:0 0 75%;max-width:75%}.col-xl-10{-ms-flex:0 0 83.333333%;flex:0 0 83.333333%;max-width:83.333333%}.col-xl-11{-ms-flex:0 0 91.666667%;flex:0 0 91.666667%;max-width:91.666667%}.col-xl-12{-ms-flex:0 0 100%;flex:0 0 100%;max-width:100%}.order-xl-first{-ms-flex-order:-1;order:-1}.order-xl-last{-ms-flex-order:13;order:13}.order-xl-0{-ms-flex-order:0;order:0}.order-xl-1{-ms-flex-order:1;order:1}.order-xl-2{-ms-flex-order:2;order:2}.order-xl-3{-ms-flex-order:3;order:3}.order-xl-4{-ms-flex-order:4;order:4}.order-xl-5{-ms-flex-order:5;order:5}.order-xl-6{-ms-flex-order:6;order:6}.order-xl-7{-ms-flex-order:7;order:7}.order-xl-8{-ms-flex-order:8;order:8}.order-xl-9{-ms-flex-order:9;order:9}.order-xl-10{-ms-flex-order:10;order:10}.order-xl-11{-ms-flex-order:11;order:11}.order-xl-12{-ms-flex-order:12;order:12}.offset-xl-0{margin-left:0}.offset-xl-1{margin-left:8.333333%}.offset-xl-2{margin-left:16.666667%}.offset-xl-3{margin-left:25%}.offset-xl-4{margin-left:33.333333%}.offset-xl-5{margin-left:41.666667%}.offset-xl-6{margin-left:50%}.offset-xl-7{margin-left:58.333333%}.offset-xl-8{margin-left:66.666667%}.offset-xl-9{margin-left:75%}.offset-xl-10{margin-left:83.333333%}.offset-xl-11{margin-left:91.666667%}}.table{width:100%;margin-bottom:1rem;background-color:transparent}.table td,.table th{padding:.75rem;vertical-align:top;border-top:1px solid #dee2e6}.table thead th{vertical-align:bottom;border-bottom:2px solid #dee2e6}.table tbody+tbody{border-top:2px solid #dee2e6}.table .table{background-color:#fff}.table-sm td,.table-sm th{padding:.3rem}.table-bordered{border:1px solid #dee2e6}.table-bordered td,.table-bordered th{border:1px solid #dee2e6}.table-bordered thead td,.table-bordered thead th{border-bottom-width:2px}.table-borderless tbody+tbody,.table-borderless td,.table-borderless th,.table-borderless thead th{border:0}.table-striped tbody tr:nth-of-type(odd){background-color:rgba(0,0,0,.05)}.table-hover tbody tr:hover{background-color:rgba(0,0,0,.075)}.table-primary,.table-primary>td,.table-primary>th{background-color:#b8daff}.table-hover .table-primary:hover{background-color:#9fcdff}.table-hover .table-primary:hover>td,.table-hover .table-primary:hover>th{background-color:#9fcdff}.table-secondary,.table-secondary>td,.table-secondary>th{background-color:#d6d8db}.table-hover .table-secondary:hover{background-color:#c8cbcf}.table-hover .table-secondary:hover>td,.table-hover .table-secondary:hover>th{background-color:#c8cbcf}.table-success,.table-success>td,.table-success>th{background-color:#c3e6cb}.table-hover .table-success:hover{background-color:#b1dfbb}.table-hover .table-success:hover>td,.table-hover .table-success:hover>th{background-color:#b1dfbb}.table-info,.table-info>td,.table-info>th{background-color:#bee5eb}.table-hover .table-info:hover{background-color:#abdde5}.table-hover .table-info:hover>td,.table-hover .table-info:hover>th{background-color:#abdde5}.table-warning,.table-warning>td,.table-warning>th{background-color:#ffeeba}.table-hover .table-warning:hover{background-color:#ffe8a1}.table-hover .table-warning:hover>td,.table-hover .table-warning:hover>th{background-color:#ffe8a1}.table-danger,.table-danger>td,.table-danger>th{background-color:#f5c6cb}.table-hover .table-danger:hover{background-color:#f1b0b7}.table-hover .table-danger:hover>td,.table-hover .table-danger:hover>th{background-color:#f1b0b7}.table-light,.table-light>td,.table-light>th{background-color:#fdfdfe}.table-hover .table-light:hover{background-color:#ececf6}.table-hover .table-light:hover>td,.table-hover .table-light:hover>th{background-color:#ececf6}.table-dark,.table-dark>td,.table-dark>th{background-color:#c6c8ca}.table-hover .table-dark:hover{background-color:#b9bbbe}.table-hover .table-dark:hover>td,.table-hover .table-dark:hover>th{background-color:#b9bbbe}.table-active,.table-active>td,.table-active>th{background-color:rgba(0,0,0,.075)}.table-hover .table-active:hover{background-color:rgba(0,0,0,.075)}.table-hover .table-active:hover>td,.table-hover .table-active:hover>th{background-color:rgba(0,0,0,.075)}.table .thead-dark th{color:#fff;background-color:#212529;border-color:#32383e}.table .thead-light th{color:#495057;background-color:#e9ecef;border-color:#dee2e6}.table-dark{color:#fff;background-color:#212529}.table-dark td,.table-dark th,.table-dark thead th{border-color:#32383e}.table-dark.table-bordered{border:0}.table-dark.table-striped tbody tr:nth-of-type(odd){background-color:rgba(255,255,255,.05)}.table-dark.table-hover tbody tr:hover{background-color:rgba(255,255,255,.075)}@media (max-width:575.98px){.table-responsive-sm{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch;-ms-overflow-style:-ms-autohiding-scrollbar}.table-responsive-sm>.table-bordered{border:0}}@media (max-width:767.98px){.table-responsive-md{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch;-ms-overflow-style:-ms-autohiding-scrollbar}.table-responsive-md>.table-bordered{border:0}}@media (max-width:991.98px){.table-responsive-lg{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch;-ms-overflow-style:-ms-autohiding-scrollbar}.table-responsive-lg>.table-bordered{border:0}}@media (max-width:1199.98px){.table-responsive-xl{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch;-ms-overflow-style:-ms-autohiding-scrollbar}.table-responsive-xl>.table-bordered{border:0}}.table-responsive{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch;-ms-overflow-style:-ms-autohiding-scrollbar}.table-responsive>.table-bordered{border:0}.form-control{display:block;width:100%;height:calc(2.25rem + 2px);padding:.375rem .75rem;font-size:1rem;line-height:1.5;color:#495057;background-color:#fff;background-clip:padding-box;border:1px solid #ced4da;border-radius:.25rem;transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media screen and (prefers-reduced-motion:reduce){.form-control{transition:none}}.form-control::-ms-expand{background-color:transparent;border:0}.form-control:focus{color:#495057;background-color:#fff;border-color:#80bdff;outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.form-control::-webkit-input-placeholder{color:#6c757d;opacity:1}.form-control::-moz-placeholder{color:#6c757d;opacity:1}.form-control:-ms-input-placeholder{color:#6c757d;opacity:1}.form-control::-ms-input-placeholder{color:#6c757d;opacity:1}.form-control::placeholder{color:#6c757d;opacity:1}.form-control:disabled,.form-control[readonly]{background-color:#e9ecef;opacity:1}select.form-control:focus::-ms-value{color:#495057;background-color:#fff}.form-control-file,.form-control-range{display:block;width:100%}.col-form-label{padding-top:calc(.375rem + 1px);padding-bottom:calc(.375rem + 1px);margin-bottom:0;font-size:inherit;line-height:1.5}.col-form-label-lg{padding-top:calc(.5rem + 1px);padding-bottom:calc(.5rem + 1px);font-size:1.25rem;line-height:1.5}.col-form-label-sm{padding-top:calc(.25rem + 1px);padding-bottom:calc(.25rem + 1px);font-size:.875rem;line-height:1.5}.form-control-plaintext{display:block;width:100%;padding-top:.375rem;padding-bottom:.375rem;margin-bottom:0;line-height:1.5;color:#212529;background-color:transparent;border:solid transparent;border-width:1px 0}.form-control-plaintext.form-control-lg,.form-control-plaintext.form-control-sm{padding-right:0;padding-left:0}.form-control-sm{height:calc(1.8125rem + 2px);padding:.25rem .5rem;font-size:.875rem;line-height:1.5;border-radius:.2rem}.form-control-lg{height:calc(2.875rem + 2px);padding:.5rem 1rem;font-size:1.25rem;line-height:1.5;border-radius:.3rem}select.form-control[multiple],select.form-control[size]{height:auto}textarea.form-control{height:auto}.form-group{margin-bottom:1rem}.form-text{display:block;margin-top:.25rem}.form-row{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;margin-right:-5px;margin-left:-5px}.form-row>.col,.form-row>[class*=col-]{padding-right:5px;padding-left:5px}.form-check{position:relative;display:block;padding-left:1.25rem}.form-check-input{position:absolute;margin-top:.3rem;margin-left:-1.25rem}.form-check-input:disabled~.form-check-label{color:#6c757d}.form-check-label{margin-bottom:0}.form-check-inline{display:-ms-inline-flexbox;display:inline-flex;-ms-flex-align:center;align-items:center;padding-left:0;margin-right:.75rem}.form-check-inline .form-check-input{position:static;margin-top:0;margin-right:.3125rem;margin-left:0}.valid-feedback{display:none;width:100%;margin-top:.25rem;font-size:80%;color:#28a745}.valid-tooltip{position:absolute;top:100%;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:.875rem;line-height:1.5;color:#fff;background-color:rgba(40,167,69,.9);border-radius:.25rem}.custom-select.is-valid,.form-control.is-valid,.was-validated .custom-select:valid,.was-validated .form-control:valid{border-color:#28a745}.custom-select.is-valid:focus,.form-control.is-valid:focus,.was-validated .custom-select:valid:focus,.was-validated .form-control:valid:focus{border-color:#28a745;box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}.custom-select.is-valid~.valid-feedback,.custom-select.is-valid~.valid-tooltip,.form-control.is-valid~.valid-feedback,.form-control.is-valid~.valid-tooltip,.was-validated .custom-select:valid~.valid-feedback,.was-validated .custom-select:valid~.valid-tooltip,.was-validated .form-control:valid~.valid-feedback,.was-validated .form-control:valid~.valid-tooltip{display:block}.form-control-file.is-valid~.valid-feedback,.form-control-file.is-valid~.valid-tooltip,.was-validated .form-control-file:valid~.valid-feedback,.was-validated .form-control-file:valid~.valid-tooltip{display:block}.form-check-input.is-valid~.form-check-label,.was-validated .form-check-input:valid~.form-check-label{color:#28a745}.form-check-input.is-valid~.valid-feedback,.form-check-input.is-valid~.valid-tooltip,.was-validated .form-check-input:valid~.valid-feedback,.was-validated .form-check-input:valid~.valid-tooltip{display:block}.custom-control-input.is-valid~.custom-control-label,.was-validated .custom-control-input:valid~.custom-control-label{color:#28a745}.custom-control-input.is-valid~.custom-control-label::before,.was-validated .custom-control-input:valid~.custom-control-label::before{background-color:#71dd8a}.custom-control-input.is-valid~.valid-feedback,.custom-control-input.is-valid~.valid-tooltip,.was-validated .custom-control-input:valid~.valid-feedback,.was-validated .custom-control-input:valid~.valid-tooltip{display:block}.custom-control-input.is-valid:checked~.custom-control-label::before,.was-validated .custom-control-input:valid:checked~.custom-control-label::before{background-color:#34ce57}.custom-control-input.is-valid:focus~.custom-control-label::before,.was-validated .custom-control-input:valid:focus~.custom-control-label::before{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(40,167,69,.25)}.custom-file-input.is-valid~.custom-file-label,.was-validated .custom-file-input:valid~.custom-file-label{border-color:#28a745}.custom-file-input.is-valid~.custom-file-label::after,.was-validated .custom-file-input:valid~.custom-file-label::after{border-color:inherit}.custom-file-input.is-valid~.valid-feedback,.custom-file-input.is-valid~.valid-tooltip,.was-validated .custom-file-input:valid~.valid-feedback,.was-validated .custom-file-input:valid~.valid-tooltip{display:block}.custom-file-input.is-valid:focus~.custom-file-label,.was-validated .custom-file-input:valid:focus~.custom-file-label{box-shadow:0 0 0 .2rem rgba(40,167,69,.25)}.invalid-feedback{display:none;width:100%;margin-top:.25rem;font-size:80%;color:#dc3545}.invalid-tooltip{position:absolute;top:100%;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:.875rem;line-height:1.5;color:#fff;background-color:rgba(220,53,69,.9);border-radius:.25rem}.custom-select.is-invalid,.form-control.is-invalid,.was-validated .custom-select:invalid,.was-validated .form-control:invalid{border-color:#dc3545}.custom-select.is-invalid:focus,.form-control.is-invalid:focus,.was-validated .custom-select:invalid:focus,.was-validated .form-control:invalid:focus{border-color:#dc3545;box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}.custom-select.is-invalid~.invalid-feedback,.custom-select.is-invalid~.invalid-tooltip,.form-control.is-invalid~.invalid-feedback,.form-control.is-invalid~.invalid-tooltip,.was-validated .custom-select:invalid~.invalid-feedback,.was-validated .custom-select:invalid~.invalid-tooltip,.was-validated .form-control:invalid~.invalid-feedback,.was-validated .form-control:invalid~.invalid-tooltip{display:block}.form-control-file.is-invalid~.invalid-feedback,.form-control-file.is-invalid~.invalid-tooltip,.was-validated .form-control-file:invalid~.invalid-feedback,.was-validated .form-control-file:invalid~.invalid-tooltip{display:block}.form-check-input.is-invalid~.form-check-label,.was-validated .form-check-input:invalid~.form-check-label{color:#dc3545}.form-check-input.is-invalid~.invalid-feedback,.form-check-input.is-invalid~.invalid-tooltip,.was-validated .form-check-input:invalid~.invalid-feedback,.was-validated .form-check-input:invalid~.invalid-tooltip{display:block}.custom-control-input.is-invalid~.custom-control-label,.was-validated .custom-control-input:invalid~.custom-control-label{color:#dc3545}.custom-control-input.is-invalid~.custom-control-label::before,.was-validated .custom-control-input:invalid~.custom-control-label::before{background-color:#efa2a9}.custom-control-input.is-invalid~.invalid-feedback,.custom-control-input.is-invalid~.invalid-tooltip,.was-validated .custom-control-input:invalid~.invalid-feedback,.was-validated .custom-control-input:invalid~.invalid-tooltip{display:block}.custom-control-input.is-invalid:checked~.custom-control-label::before,.was-validated .custom-control-input:invalid:checked~.custom-control-label::before{background-color:#e4606d}.custom-control-input.is-invalid:focus~.custom-control-label::before,.was-validated .custom-control-input:invalid:focus~.custom-control-label::before{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(220,53,69,.25)}.custom-file-input.is-invalid~.custom-file-label,.was-validated .custom-file-input:invalid~.custom-file-label{border-color:#dc3545}.custom-file-input.is-invalid~.custom-file-label::after,.was-validated .custom-file-input:invalid~.custom-file-label::after{border-color:inherit}.custom-file-input.is-invalid~.invalid-feedback,.custom-file-input.is-invalid~.invalid-tooltip,.was-validated .custom-file-input:invalid~.invalid-feedback,.was-validated .custom-file-input:invalid~.invalid-tooltip{display:block}.custom-file-input.is-invalid:focus~.custom-file-label,.was-validated .custom-file-input:invalid:focus~.custom-file-label{box-shadow:0 0 0 .2rem rgba(220,53,69,.25)}.form-inline{display:-ms-flexbox;display:flex;-ms-flex-flow:row wrap;flex-flow:row wrap;-ms-flex-align:center;align-items:center}.form-inline .form-check{width:100%}@media (min-width:576px){.form-inline label{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;margin-bottom:0}.form-inline .form-group{display:-ms-flexbox;display:flex;-ms-flex:0 0 auto;flex:0 0 auto;-ms-flex-flow:row wrap;flex-flow:row wrap;-ms-flex-align:center;align-items:center;margin-bottom:0}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .form-control-plaintext{display:inline-block}.form-inline .custom-select,.form-inline .input-group{width:auto}.form-inline .form-check{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;width:auto;padding-left:0}.form-inline .form-check-input{position:relative;margin-top:0;margin-right:.25rem;margin-left:0}.form-inline .custom-control{-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center}.form-inline .custom-control-label{margin-bottom:0}}.btn{display:inline-block;font-weight:400;text-align:center;white-space:nowrap;vertical-align:middle;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;border:1px solid transparent;padding:.375rem .75rem;font-size:1rem;line-height:1.5;border-radius:.25rem;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media screen and (prefers-reduced-motion:reduce){.btn{transition:none}}.btn:focus,.btn:hover{text-decoration:none}.btn.focus,.btn:focus{outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.btn.disabled,.btn:disabled{opacity:.65}.btn:not(:disabled):not(.disabled){cursor:pointer}a.btn.disabled,fieldset:disabled a.btn{pointer-events:none}.btn-primary{color:#fff;background-color:#007bff;border-color:#007bff}.btn-primary:hover{color:#fff;background-color:#0069d9;border-color:#0062cc}.btn-primary.focus,.btn-primary:focus{box-shadow:0 0 0 .2rem rgba(0,123,255,.5)}.btn-primary.disabled,.btn-primary:disabled{color:#fff;background-color:#007bff;border-color:#007bff}.btn-primary:not(:disabled):not(.disabled).active,.btn-primary:not(:disabled):not(.disabled):active,.show>.btn-primary.dropdown-toggle{color:#fff;background-color:#0062cc;border-color:#005cbf}.btn-primary:not(:disabled):not(.disabled).active:focus,.btn-primary:not(:disabled):not(.disabled):active:focus,.show>.btn-primary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(0,123,255,.5)}.btn-secondary{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-secondary:hover{color:#fff;background-color:#5a6268;border-color:#545b62}.btn-secondary.focus,.btn-secondary:focus{box-shadow:0 0 0 .2rem rgba(108,117,125,.5)}.btn-secondary.disabled,.btn-secondary:disabled{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-secondary:not(:disabled):not(.disabled).active,.btn-secondary:not(:disabled):not(.disabled):active,.show>.btn-secondary.dropdown-toggle{color:#fff;background-color:#545b62;border-color:#4e555b}.btn-secondary:not(:disabled):not(.disabled).active:focus,.btn-secondary:not(:disabled):not(.disabled):active:focus,.show>.btn-secondary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(108,117,125,.5)}.btn-success{color:#fff;background-color:#28a745;border-color:#28a745}.btn-success:hover{color:#fff;background-color:#218838;border-color:#1e7e34}.btn-success.focus,.btn-success:focus{box-shadow:0 0 0 .2rem rgba(40,167,69,.5)}.btn-success.disabled,.btn-success:disabled{color:#fff;background-color:#28a745;border-color:#28a745}.btn-success:not(:disabled):not(.disabled).active,.btn-success:not(:disabled):not(.disabled):active,.show>.btn-success.dropdown-toggle{color:#fff;background-color:#1e7e34;border-color:#1c7430}.btn-success:not(:disabled):not(.disabled).active:focus,.btn-success:not(:disabled):not(.disabled):active:focus,.show>.btn-success.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(40,167,69,.5)}.btn-info{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-info:hover{color:#fff;background-color:#138496;border-color:#117a8b}.btn-info.focus,.btn-info:focus{box-shadow:0 0 0 .2rem rgba(23,162,184,.5)}.btn-info.disabled,.btn-info:disabled{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-info:not(:disabled):not(.disabled).active,.btn-info:not(:disabled):not(.disabled):active,.show>.btn-info.dropdown-toggle{color:#fff;background-color:#117a8b;border-color:#10707f}.btn-info:not(:disabled):not(.disabled).active:focus,.btn-info:not(:disabled):not(.disabled):active:focus,.show>.btn-info.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(23,162,184,.5)}.btn-warning{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-warning:hover{color:#212529;background-color:#e0a800;border-color:#d39e00}.btn-warning.focus,.btn-warning:focus{box-shadow:0 0 0 .2rem rgba(255,193,7,.5)}.btn-warning.disabled,.btn-warning:disabled{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-warning:not(:disabled):not(.disabled).active,.btn-warning:not(:disabled):not(.disabled):active,.show>.btn-warning.dropdown-toggle{color:#212529;background-color:#d39e00;border-color:#c69500}.btn-warning:not(:disabled):not(.disabled).active:focus,.btn-warning:not(:disabled):not(.disabled):active:focus,.show>.btn-warning.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(255,193,7,.5)}.btn-danger{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-danger:hover{color:#fff;background-color:#c82333;border-color:#bd2130}.btn-danger.focus,.btn-danger:focus{box-shadow:0 0 0 .2rem rgba(220,53,69,.5)}.btn-danger.disabled,.btn-danger:disabled{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-danger:not(:disabled):not(.disabled).active,.btn-danger:not(:disabled):not(.disabled):active,.show>.btn-danger.dropdown-toggle{color:#fff;background-color:#bd2130;border-color:#b21f2d}.btn-danger:not(:disabled):not(.disabled).active:focus,.btn-danger:not(:disabled):not(.disabled):active:focus,.show>.btn-danger.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(220,53,69,.5)}.btn-light{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-light:hover{color:#212529;background-color:#e2e6ea;border-color:#dae0e5}.btn-light.focus,.btn-light:focus{box-shadow:0 0 0 .2rem rgba(248,249,250,.5)}.btn-light.disabled,.btn-light:disabled{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-light:not(:disabled):not(.disabled).active,.btn-light:not(:disabled):not(.disabled):active,.show>.btn-light.dropdown-toggle{color:#212529;background-color:#dae0e5;border-color:#d3d9df}.btn-light:not(:disabled):not(.disabled).active:focus,.btn-light:not(:disabled):not(.disabled):active:focus,.show>.btn-light.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(248,249,250,.5)}.btn-dark{color:#fff;background-color:#343a40;border-color:#343a40}.btn-dark:hover{color:#fff;background-color:#23272b;border-color:#1d2124}.btn-dark.focus,.btn-dark:focus{box-shadow:0 0 0 .2rem rgba(52,58,64,.5)}.btn-dark.disabled,.btn-dark:disabled{color:#fff;background-color:#343a40;border-color:#343a40}.btn-dark:not(:disabled):not(.disabled).active,.btn-dark:not(:disabled):not(.disabled):active,.show>.btn-dark.dropdown-toggle{color:#fff;background-color:#1d2124;border-color:#171a1d}.btn-dark:not(:disabled):not(.disabled).active:focus,.btn-dark:not(:disabled):not(.disabled):active:focus,.show>.btn-dark.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(52,58,64,.5)}.btn-outline-primary{color:#007bff;background-color:transparent;background-image:none;border-color:#007bff}.btn-outline-primary:hover{color:#fff;background-color:#007bff;border-color:#007bff}.btn-outline-primary.focus,.btn-outline-primary:focus{box-shadow:0 0 0 .2rem rgba(0,123,255,.5)}.btn-outline-primary.disabled,.btn-outline-primary:disabled{color:#007bff;background-color:transparent}.btn-outline-primary:not(:disabled):not(.disabled).active,.btn-outline-primary:not(:disabled):not(.disabled):active,.show>.btn-outline-primary.dropdown-toggle{color:#fff;background-color:#007bff;border-color:#007bff}.btn-outline-primary:not(:disabled):not(.disabled).active:focus,.btn-outline-primary:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-primary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(0,123,255,.5)}.btn-outline-secondary{color:#6c757d;background-color:transparent;background-image:none;border-color:#6c757d}.btn-outline-secondary:hover{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-outline-secondary.focus,.btn-outline-secondary:focus{box-shadow:0 0 0 .2rem rgba(108,117,125,.5)}.btn-outline-secondary.disabled,.btn-outline-secondary:disabled{color:#6c757d;background-color:transparent}.btn-outline-secondary:not(:disabled):not(.disabled).active,.btn-outline-secondary:not(:disabled):not(.disabled):active,.show>.btn-outline-secondary.dropdown-toggle{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-outline-secondary:not(:disabled):not(.disabled).active:focus,.btn-outline-secondary:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-secondary.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(108,117,125,.5)}.btn-outline-success{color:#28a745;background-color:transparent;background-image:none;border-color:#28a745}.btn-outline-success:hover{color:#fff;background-color:#28a745;border-color:#28a745}.btn-outline-success.focus,.btn-outline-success:focus{box-shadow:0 0 0 .2rem rgba(40,167,69,.5)}.btn-outline-success.disabled,.btn-outline-success:disabled{color:#28a745;background-color:transparent}.btn-outline-success:not(:disabled):not(.disabled).active,.btn-outline-success:not(:disabled):not(.disabled):active,.show>.btn-outline-success.dropdown-toggle{color:#fff;background-color:#28a745;border-color:#28a745}.btn-outline-success:not(:disabled):not(.disabled).active:focus,.btn-outline-success:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-success.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(40,167,69,.5)}.btn-outline-info{color:#17a2b8;background-color:transparent;background-image:none;border-color:#17a2b8}.btn-outline-info:hover{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-outline-info.focus,.btn-outline-info:focus{box-shadow:0 0 0 .2rem rgba(23,162,184,.5)}.btn-outline-info.disabled,.btn-outline-info:disabled{color:#17a2b8;background-color:transparent}.btn-outline-info:not(:disabled):not(.disabled).active,.btn-outline-info:not(:disabled):not(.disabled):active,.show>.btn-outline-info.dropdown-toggle{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-outline-info:not(:disabled):not(.disabled).active:focus,.btn-outline-info:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-info.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(23,162,184,.5)}.btn-outline-warning{color:#ffc107;background-color:transparent;background-image:none;border-color:#ffc107}.btn-outline-warning:hover{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-outline-warning.focus,.btn-outline-warning:focus{box-shadow:0 0 0 .2rem rgba(255,193,7,.5)}.btn-outline-warning.disabled,.btn-outline-warning:disabled{color:#ffc107;background-color:transparent}.btn-outline-warning:not(:disabled):not(.disabled).active,.btn-outline-warning:not(:disabled):not(.disabled):active,.show>.btn-outline-warning.dropdown-toggle{color:#212529;background-color:#ffc107;border-color:#ffc107}.btn-outline-warning:not(:disabled):not(.disabled).active:focus,.btn-outline-warning:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-warning.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(255,193,7,.5)}.btn-outline-danger{color:#dc3545;background-color:transparent;background-image:none;border-color:#dc3545}.btn-outline-danger:hover{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-outline-danger.focus,.btn-outline-danger:focus{box-shadow:0 0 0 .2rem rgba(220,53,69,.5)}.btn-outline-danger.disabled,.btn-outline-danger:disabled{color:#dc3545;background-color:transparent}.btn-outline-danger:not(:disabled):not(.disabled).active,.btn-outline-danger:not(:disabled):not(.disabled):active,.show>.btn-outline-danger.dropdown-toggle{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-outline-danger:not(:disabled):not(.disabled).active:focus,.btn-outline-danger:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-danger.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(220,53,69,.5)}.btn-outline-light{color:#f8f9fa;background-color:transparent;background-image:none;border-color:#f8f9fa}.btn-outline-light:hover{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-outline-light.focus,.btn-outline-light:focus{box-shadow:0 0 0 .2rem rgba(248,249,250,.5)}.btn-outline-light.disabled,.btn-outline-light:disabled{color:#f8f9fa;background-color:transparent}.btn-outline-light:not(:disabled):not(.disabled).active,.btn-outline-light:not(:disabled):not(.disabled):active,.show>.btn-outline-light.dropdown-toggle{color:#212529;background-color:#f8f9fa;border-color:#f8f9fa}.btn-outline-light:not(:disabled):not(.disabled).active:focus,.btn-outline-light:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-light.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(248,249,250,.5)}.btn-outline-dark{color:#343a40;background-color:transparent;background-image:none;border-color:#343a40}.btn-outline-dark:hover{color:#fff;background-color:#343a40;border-color:#343a40}.btn-outline-dark.focus,.btn-outline-dark:focus{box-shadow:0 0 0 .2rem rgba(52,58,64,.5)}.btn-outline-dark.disabled,.btn-outline-dark:disabled{color:#343a40;background-color:transparent}.btn-outline-dark:not(:disabled):not(.disabled).active,.btn-outline-dark:not(:disabled):not(.disabled):active,.show>.btn-outline-dark.dropdown-toggle{color:#fff;background-color:#343a40;border-color:#343a40}.btn-outline-dark:not(:disabled):not(.disabled).active:focus,.btn-outline-dark:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-dark.dropdown-toggle:focus{box-shadow:0 0 0 .2rem rgba(52,58,64,.5)}.btn-link{font-weight:400;color:#007bff;background-color:transparent}.btn-link:hover{color:#0056b3;text-decoration:underline;background-color:transparent;border-color:transparent}.btn-link.focus,.btn-link:focus{text-decoration:underline;border-color:transparent;box-shadow:none}.btn-link.disabled,.btn-link:disabled{color:#6c757d;pointer-events:none}.btn-group-lg>.btn,.btn-lg{padding:.5rem 1rem;font-size:1.25rem;line-height:1.5;border-radius:.3rem}.btn-group-sm>.btn,.btn-sm{padding:.25rem .5rem;font-size:.875rem;line-height:1.5;border-radius:.2rem}.btn-block{display:block;width:100%}.btn-block+.btn-block{margin-top:.5rem}input[type=button].btn-block,input[type=reset].btn-block,input[type=submit].btn-block{width:100%}.fade{transition:opacity .15s linear}@media screen and (prefers-reduced-motion:reduce){.fade{transition:none}}.fade:not(.show){opacity:0}.collapse:not(.show){display:none}.collapsing{position:relative;height:0;overflow:hidden;transition:height .35s ease}@media screen and (prefers-reduced-motion:reduce){.collapsing{transition:none}}.dropdown,.dropleft,.dropright,.dropup{position:relative}.dropdown-toggle::after{display:inline-block;width:0;height:0;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid;border-right:.3em solid transparent;border-bottom:0;border-left:.3em solid transparent}.dropdown-toggle:empty::after{margin-left:0}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:10rem;padding:.5rem 0;margin:.125rem 0 0;font-size:1rem;color:#212529;text-align:left;list-style:none;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.15);border-radius:.25rem}.dropdown-menu-right{right:0;left:auto}.dropup .dropdown-menu{top:auto;bottom:100%;margin-top:0;margin-bottom:.125rem}.dropup .dropdown-toggle::after{display:inline-block;width:0;height:0;margin-left:.255em;vertical-align:.255em;content:"";border-top:0;border-right:.3em solid transparent;border-bottom:.3em solid;border-left:.3em solid transparent}.dropup .dropdown-toggle:empty::after{margin-left:0}.dropright .dropdown-menu{top:0;right:auto;left:100%;margin-top:0;margin-left:.125rem}.dropright .dropdown-toggle::after{display:inline-block;width:0;height:0;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-right:0;border-bottom:.3em solid transparent;border-left:.3em solid}.dropright .dropdown-toggle:empty::after{margin-left:0}.dropright .dropdown-toggle::after{vertical-align:0}.dropleft .dropdown-menu{top:0;right:100%;left:auto;margin-top:0;margin-right:.125rem}.dropleft .dropdown-toggle::after{display:inline-block;width:0;height:0;margin-left:.255em;vertical-align:.255em;content:""}.dropleft .dropdown-toggle::after{display:none}.dropleft .dropdown-toggle::before{display:inline-block;width:0;height:0;margin-right:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-right:.3em solid;border-bottom:.3em solid transparent}.dropleft .dropdown-toggle:empty::after{margin-left:0}.dropleft .dropdown-toggle::before{vertical-align:0}.dropdown-menu[x-placement^=bottom],.dropdown-menu[x-placement^=left],.dropdown-menu[x-placement^=right],.dropdown-menu[x-placement^=top]{right:auto;bottom:auto}.dropdown-divider{height:0;margin:.5rem 0;overflow:hidden;border-top:1px solid #e9ecef}.dropdown-item{display:block;width:100%;padding:.25rem 1.5rem;clear:both;font-weight:400;color:#212529;text-align:inherit;white-space:nowrap;background-color:transparent;border:0}.dropdown-item:focus,.dropdown-item:hover{color:#16181b;text-decoration:none;background-color:#f8f9fa}.dropdown-item.active,.dropdown-item:active{color:#fff;text-decoration:none;background-color:#007bff}.dropdown-item.disabled,.dropdown-item:disabled{color:#6c757d;background-color:transparent}.dropdown-menu.show{display:block}.dropdown-header{display:block;padding:.5rem 1.5rem;margin-bottom:0;font-size:.875rem;color:#6c757d;white-space:nowrap}.dropdown-item-text{display:block;padding:.25rem 1.5rem;color:#212529}.btn-group,.btn-group-vertical{position:relative;display:-ms-inline-flexbox;display:inline-flex;vertical-align:middle}.btn-group-vertical>.btn,.btn-group>.btn{position:relative;-ms-flex:0 1 auto;flex:0 1 auto}.btn-group-vertical>.btn:hover,.btn-group>.btn:hover{z-index:1}.btn-group-vertical>.btn.active,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn:focus,.btn-group>.btn.active,.btn-group>.btn:active,.btn-group>.btn:focus{z-index:1}.btn-group .btn+.btn,.btn-group .btn+.btn-group,.btn-group .btn-group+.btn,.btn-group .btn-group+.btn-group,.btn-group-vertical .btn+.btn,.btn-group-vertical .btn+.btn-group,.btn-group-vertical .btn-group+.btn,.btn-group-vertical .btn-group+.btn-group{margin-left:-1px}.btn-toolbar{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-pack:start;justify-content:flex-start}.btn-toolbar .input-group{width:auto}.btn-group>.btn:first-child{margin-left:0}.btn-group>.btn-group:not(:last-child)>.btn,.btn-group>.btn:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn-group:not(:first-child)>.btn,.btn-group>.btn:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.dropdown-toggle-split{padding-right:.5625rem;padding-left:.5625rem}.dropdown-toggle-split::after,.dropright .dropdown-toggle-split::after,.dropup .dropdown-toggle-split::after{margin-left:0}.dropleft .dropdown-toggle-split::before{margin-right:0}.btn-group-sm>.btn+.dropdown-toggle-split,.btn-sm+.dropdown-toggle-split{padding-right:.375rem;padding-left:.375rem}.btn-group-lg>.btn+.dropdown-toggle-split,.btn-lg+.dropdown-toggle-split{padding-right:.75rem;padding-left:.75rem}.btn-group-vertical{-ms-flex-direction:column;flex-direction:column;-ms-flex-align:start;align-items:flex-start;-ms-flex-pack:center;justify-content:center}.btn-group-vertical .btn,.btn-group-vertical .btn-group{width:100%}.btn-group-vertical>.btn+.btn,.btn-group-vertical>.btn+.btn-group,.btn-group-vertical>.btn-group+.btn,.btn-group-vertical>.btn-group+.btn-group{margin-top:-1px;margin-left:0}.btn-group-vertical>.btn-group:not(:last-child)>.btn,.btn-group-vertical>.btn:not(:last-child):not(.dropdown-toggle){border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:not(:first-child)>.btn,.btn-group-vertical>.btn:not(:first-child){border-top-left-radius:0;border-top-right-radius:0}.btn-group-toggle>.btn,.btn-group-toggle>.btn-group>.btn{margin-bottom:0}.btn-group-toggle>.btn input[type=checkbox],.btn-group-toggle>.btn input[type=radio],.btn-group-toggle>.btn-group>.btn input[type=checkbox],.btn-group-toggle>.btn-group>.btn input[type=radio]{position:absolute;clip:rect(0,0,0,0);pointer-events:none}.input-group{position:relative;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-align:stretch;align-items:stretch;width:100%}.input-group>.custom-file,.input-group>.custom-select,.input-group>.form-control{position:relative;-ms-flex:1 1 auto;flex:1 1 auto;width:1%;margin-bottom:0}.input-group>.custom-file+.custom-file,.input-group>.custom-file+.custom-select,.input-group>.custom-file+.form-control,.input-group>.custom-select+.custom-file,.input-group>.custom-select+.custom-select,.input-group>.custom-select+.form-control,.input-group>.form-control+.custom-file,.input-group>.form-control+.custom-select,.input-group>.form-control+.form-control{margin-left:-1px}.input-group>.custom-file .custom-file-input:focus~.custom-file-label,.input-group>.custom-select:focus,.input-group>.form-control:focus{z-index:3}.input-group>.custom-file .custom-file-input:focus{z-index:4}.input-group>.custom-select:not(:last-child),.input-group>.form-control:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}.input-group>.custom-select:not(:first-child),.input-group>.form-control:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.input-group>.custom-file{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center}.input-group>.custom-file:not(:last-child) .custom-file-label,.input-group>.custom-file:not(:last-child) .custom-file-label::after{border-top-right-radius:0;border-bottom-right-radius:0}.input-group>.custom-file:not(:first-child) .custom-file-label{border-top-left-radius:0;border-bottom-left-radius:0}.input-group-append,.input-group-prepend{display:-ms-flexbox;display:flex}.input-group-append .btn,.input-group-prepend .btn{position:relative;z-index:2}.input-group-append .btn+.btn,.input-group-append .btn+.input-group-text,.input-group-append .input-group-text+.btn,.input-group-append .input-group-text+.input-group-text,.input-group-prepend .btn+.btn,.input-group-prepend .btn+.input-group-text,.input-group-prepend .input-group-text+.btn,.input-group-prepend .input-group-text+.input-group-text{margin-left:-1px}.input-group-prepend{margin-right:-1px}.input-group-append{margin-left:-1px}.input-group-text{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;padding:.375rem .75rem;margin-bottom:0;font-size:1rem;font-weight:400;line-height:1.5;color:#495057;text-align:center;white-space:nowrap;background-color:#e9ecef;border:1px solid #ced4da;border-radius:.25rem}.input-group-text input[type=checkbox],.input-group-text input[type=radio]{margin-top:0}.input-group-lg>.form-control,.input-group-lg>.input-group-append>.btn,.input-group-lg>.input-group-append>.input-group-text,.input-group-lg>.input-group-prepend>.btn,.input-group-lg>.input-group-prepend>.input-group-text{height:calc(2.875rem + 2px);padding:.5rem 1rem;font-size:1.25rem;line-height:1.5;border-radius:.3rem}.input-group-sm>.form-control,.input-group-sm>.input-group-append>.btn,.input-group-sm>.input-group-append>.input-group-text,.input-group-sm>.input-group-prepend>.btn,.input-group-sm>.input-group-prepend>.input-group-text{height:calc(1.8125rem + 2px);padding:.25rem .5rem;font-size:.875rem;line-height:1.5;border-radius:.2rem}.input-group>.input-group-append:last-child>.btn:not(:last-child):not(.dropdown-toggle),.input-group>.input-group-append:last-child>.input-group-text:not(:last-child),.input-group>.input-group-append:not(:last-child)>.btn,.input-group>.input-group-append:not(:last-child)>.input-group-text,.input-group>.input-group-prepend>.btn,.input-group>.input-group-prepend>.input-group-text{border-top-right-radius:0;border-bottom-right-radius:0}.input-group>.input-group-append>.btn,.input-group>.input-group-append>.input-group-text,.input-group>.input-group-prepend:first-child>.btn:not(:first-child),.input-group>.input-group-prepend:first-child>.input-group-text:not(:first-child),.input-group>.input-group-prepend:not(:first-child)>.btn,.input-group>.input-group-prepend:not(:first-child)>.input-group-text{border-top-left-radius:0;border-bottom-left-radius:0}.custom-control{position:relative;display:block;min-height:1.5rem;padding-left:1.5rem}.custom-control-inline{display:-ms-inline-flexbox;display:inline-flex;margin-right:1rem}.custom-control-input{position:absolute;z-index:-1;opacity:0}.custom-control-input:checked~.custom-control-label::before{color:#fff;background-color:#007bff}.custom-control-input:focus~.custom-control-label::before{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(0,123,255,.25)}.custom-control-input:active~.custom-control-label::before{color:#fff;background-color:#b3d7ff}.custom-control-input:disabled~.custom-control-label{color:#6c757d}.custom-control-input:disabled~.custom-control-label::before{background-color:#e9ecef}.custom-control-label{position:relative;margin-bottom:0}.custom-control-label::before{position:absolute;top:.25rem;left:-1.5rem;display:block;width:1rem;height:1rem;pointer-events:none;content:"";-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-color:#dee2e6}.custom-control-label::after{position:absolute;top:.25rem;left:-1.5rem;display:block;width:1rem;height:1rem;content:"";background-repeat:no-repeat;background-position:center center;background-size:50% 50%}.custom-checkbox .custom-control-label::before{border-radius:.25rem}.custom-checkbox .custom-control-input:checked~.custom-control-label::before{background-color:#007bff}.custom-checkbox .custom-control-input:checked~.custom-control-label::after{background-image:url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3E%3Cpath fill='%23fff' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26 2.974 7.25 8 2.193z'/%3E%3C/svg%3E")}.custom-checkbox .custom-control-input:indeterminate~.custom-control-label::before{background-color:#007bff}.custom-checkbox .custom-control-input:indeterminate~.custom-control-label::after{background-image:url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 4'%3E%3Cpath stroke='%23fff' d='M0 2h4'/%3E%3C/svg%3E")}.custom-checkbox .custom-control-input:disabled:checked~.custom-control-label::before{background-color:rgba(0,123,255,.5)}.custom-checkbox .custom-control-input:disabled:indeterminate~.custom-control-label::before{background-color:rgba(0,123,255,.5)}.custom-radio .custom-control-label::before{border-radius:50%}.custom-radio .custom-control-input:checked~.custom-control-label::before{background-color:#007bff}.custom-radio .custom-control-input:checked~.custom-control-label::after{background-image:url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3E%3Ccircle r='3' fill='%23fff'/%3E%3C/svg%3E")}.custom-radio .custom-control-input:disabled:checked~.custom-control-label::before{background-color:rgba(0,123,255,.5)}.custom-select{display:inline-block;width:100%;height:calc(2.25rem + 2px);padding:.375rem 1.75rem .375rem .75rem;line-height:1.5;color:#495057;vertical-align:middle;background:#fff url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 5'%3E%3Cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3E%3C/svg%3E") no-repeat right .75rem center;background-size:8px 10px;border:1px solid #ced4da;border-radius:.25rem;-webkit-appearance:none;-moz-appearance:none;appearance:none}.custom-select:focus{border-color:#80bdff;outline:0;box-shadow:0 0 0 .2rem rgba(128,189,255,.5)}.custom-select:focus::-ms-value{color:#495057;background-color:#fff}.custom-select[multiple],.custom-select[size]:not([size="1"]){height:auto;padding-right:.75rem;background-image:none}.custom-select:disabled{color:#6c757d;background-color:#e9ecef}.custom-select::-ms-expand{opacity:0}.custom-select-sm{height:calc(1.8125rem + 2px);padding-top:.375rem;padding-bottom:.375rem;font-size:75%}.custom-select-lg{height:calc(2.875rem + 2px);padding-top:.375rem;padding-bottom:.375rem;font-size:125%}.custom-file{position:relative;display:inline-block;width:100%;height:calc(2.25rem + 2px);margin-bottom:0}.custom-file-input{position:relative;z-index:2;width:100%;height:calc(2.25rem + 2px);margin:0;opacity:0}.custom-file-input:focus~.custom-file-label{border-color:#80bdff;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.custom-file-input:focus~.custom-file-label::after{border-color:#80bdff}.custom-file-input:disabled~.custom-file-label{background-color:#e9ecef}.custom-file-input:lang(en)~.custom-file-label::after{content:"Browse"}.custom-file-label{position:absolute;top:0;right:0;left:0;z-index:1;height:calc(2.25rem + 2px);padding:.375rem .75rem;line-height:1.5;color:#495057;background-color:#fff;border:1px solid #ced4da;border-radius:.25rem}.custom-file-label::after{position:absolute;top:0;right:0;bottom:0;z-index:3;display:block;height:2.25rem;padding:.375rem .75rem;line-height:1.5;color:#495057;content:"Browse";background-color:#e9ecef;border-left:1px solid #ced4da;border-radius:0 .25rem .25rem 0}.custom-range{width:100%;padding-left:0;background-color:transparent;-webkit-appearance:none;-moz-appearance:none;appearance:none}.custom-range:focus{outline:0}.custom-range:focus::-webkit-slider-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(0,123,255,.25)}.custom-range:focus::-moz-range-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(0,123,255,.25)}.custom-range:focus::-ms-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(0,123,255,.25)}.custom-range::-moz-focus-outer{border:0}.custom-range::-webkit-slider-thumb{width:1rem;height:1rem;margin-top:-.25rem;background-color:#007bff;border:0;border-radius:1rem;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;-webkit-appearance:none;appearance:none}@media screen and (prefers-reduced-motion:reduce){.custom-range::-webkit-slider-thumb{transition:none}}.custom-range::-webkit-slider-thumb:active{background-color:#b3d7ff}.custom-range::-webkit-slider-runnable-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:#dee2e6;border-color:transparent;border-radius:1rem}.custom-range::-moz-range-thumb{width:1rem;height:1rem;background-color:#007bff;border:0;border-radius:1rem;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;-moz-appearance:none;appearance:none}@media screen and (prefers-reduced-motion:reduce){.custom-range::-moz-range-thumb{transition:none}}.custom-range::-moz-range-thumb:active{background-color:#b3d7ff}.custom-range::-moz-range-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:#dee2e6;border-color:transparent;border-radius:1rem}.custom-range::-ms-thumb{width:1rem;height:1rem;margin-top:0;margin-right:.2rem;margin-left:.2rem;background-color:#007bff;border:0;border-radius:1rem;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;appearance:none}@media screen and (prefers-reduced-motion:reduce){.custom-range::-ms-thumb{transition:none}}.custom-range::-ms-thumb:active{background-color:#b3d7ff}.custom-range::-ms-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:transparent;border-color:transparent;border-width:.5rem}.custom-range::-ms-fill-lower{background-color:#dee2e6;border-radius:1rem}.custom-range::-ms-fill-upper{margin-right:15px;background-color:#dee2e6;border-radius:1rem}.custom-control-label::before,.custom-file-label,.custom-select{transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media screen and (prefers-reduced-motion:reduce){.custom-control-label::before,.custom-file-label,.custom-select{transition:none}}.nav{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;padding-left:0;margin-bottom:0;list-style:none}.nav-link{display:block;padding:.5rem 1rem}.nav-link:focus,.nav-link:hover{text-decoration:none}.nav-link.disabled{color:#6c757d}.nav-tabs{border-bottom:1px solid #dee2e6}.nav-tabs .nav-item{margin-bottom:-1px}.nav-tabs .nav-link{border:1px solid transparent;border-top-left-radius:.25rem;border-top-right-radius:.25rem}.nav-tabs .nav-link:focus,.nav-tabs .nav-link:hover{border-color:#e9ecef #e9ecef #dee2e6}.nav-tabs .nav-link.disabled{color:#6c757d;background-color:transparent;border-color:transparent}.nav-tabs .nav-item.show .nav-link,.nav-tabs .nav-link.active{color:#495057;background-color:#fff;border-color:#dee2e6 #dee2e6 #fff}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-left-radius:0;border-top-right-radius:0}.nav-pills .nav-link{border-radius:.25rem}.nav-pills .nav-link.active,.nav-pills .show>.nav-link{color:#fff;background-color:#007bff}.nav-fill .nav-item{-ms-flex:1 1 auto;flex:1 1 auto;text-align:center}.nav-justified .nav-item{-ms-flex-preferred-size:0;flex-basis:0;-ms-flex-positive:1;flex-grow:1;text-align:center}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.navbar{position:relative;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-align:center;align-items:center;-ms-flex-pack:justify;justify-content:space-between;padding:.5rem 1rem}.navbar>.container,.navbar>.container-fluid{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-align:center;align-items:center;-ms-flex-pack:justify;justify-content:space-between}.navbar-brand{display:inline-block;padding-top:.3125rem;padding-bottom:.3125rem;margin-right:1rem;font-size:1.25rem;line-height:inherit;white-space:nowrap}.navbar-brand:focus,.navbar-brand:hover{text-decoration:none}.navbar-nav{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;padding-left:0;margin-bottom:0;list-style:none}.navbar-nav .nav-link{padding-right:0;padding-left:0}.navbar-nav .dropdown-menu{position:static;float:none}.navbar-text{display:inline-block;padding-top:.5rem;padding-bottom:.5rem}.navbar-collapse{-ms-flex-preferred-size:100%;flex-basis:100%;-ms-flex-positive:1;flex-grow:1;-ms-flex-align:center;align-items:center}.navbar-toggler{padding:.25rem .75rem;font-size:1.25rem;line-height:1;background-color:transparent;border:1px solid transparent;border-radius:.25rem}.navbar-toggler:focus,.navbar-toggler:hover{text-decoration:none}.navbar-toggler:not(:disabled):not(.disabled){cursor:pointer}.navbar-toggler-icon{display:inline-block;width:1.5em;height:1.5em;vertical-align:middle;content:"";background:no-repeat center center;background-size:100% 100%}@media (max-width:575.98px){.navbar-expand-sm>.container,.navbar-expand-sm>.container-fluid{padding-right:0;padding-left:0}}@media (min-width:576px){.navbar-expand-sm{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand-sm .navbar-nav{-ms-flex-direction:row;flex-direction:row}.navbar-expand-sm .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-sm .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-sm>.container,.navbar-expand-sm>.container-fluid{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand-sm .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand-sm .navbar-toggler{display:none}}@media (max-width:767.98px){.navbar-expand-md>.container,.navbar-expand-md>.container-fluid{padding-right:0;padding-left:0}}@media (min-width:768px){.navbar-expand-md{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand-md .navbar-nav{-ms-flex-direction:row;flex-direction:row}.navbar-expand-md .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-md .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-md>.container,.navbar-expand-md>.container-fluid{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand-md .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand-md .navbar-toggler{display:none}}@media (max-width:991.98px){.navbar-expand-lg>.container,.navbar-expand-lg>.container-fluid{padding-right:0;padding-left:0}}@media (min-width:992px){.navbar-expand-lg{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand-lg .navbar-nav{-ms-flex-direction:row;flex-direction:row}.navbar-expand-lg .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-lg .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-lg>.container,.navbar-expand-lg>.container-fluid{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand-lg .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand-lg .navbar-toggler{display:none}}@media (max-width:1199.98px){.navbar-expand-xl>.container,.navbar-expand-xl>.container-fluid{padding-right:0;padding-left:0}}@media (min-width:1200px){.navbar-expand-xl{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand-xl .navbar-nav{-ms-flex-direction:row;flex-direction:row}.navbar-expand-xl .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-xl .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand-xl>.container,.navbar-expand-xl>.container-fluid{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand-xl .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand-xl .navbar-toggler{display:none}}.navbar-expand{-ms-flex-flow:row nowrap;flex-flow:row nowrap;-ms-flex-pack:start;justify-content:flex-start}.navbar-expand>.container,.navbar-expand>.container-fluid{padding-right:0;padding-left:0}.navbar-expand .navbar-nav{-ms-flex-direction:row;flex-direction:row}.navbar-expand .navbar-nav .dropdown-menu{position:absolute}.navbar-expand .navbar-nav .nav-link{padding-right:.5rem;padding-left:.5rem}.navbar-expand>.container,.navbar-expand>.container-fluid{-ms-flex-wrap:nowrap;flex-wrap:nowrap}.navbar-expand .navbar-collapse{display:-ms-flexbox!important;display:flex!important;-ms-flex-preferred-size:auto;flex-basis:auto}.navbar-expand .navbar-toggler{display:none}.navbar-light .navbar-brand{color:rgba(0,0,0,.9)}.navbar-light .navbar-brand:focus,.navbar-light .navbar-brand:hover{color:rgba(0,0,0,.9)}.navbar-light .navbar-nav .nav-link{color:rgba(0,0,0,.5)}.navbar-light .navbar-nav .nav-link:focus,.navbar-light .navbar-nav .nav-link:hover{color:rgba(0,0,0,.7)}.navbar-light .navbar-nav .nav-link.disabled{color:rgba(0,0,0,.3)}.navbar-light .navbar-nav .active>.nav-link,.navbar-light .navbar-nav .nav-link.active,.navbar-light .navbar-nav .nav-link.show,.navbar-light .navbar-nav .show>.nav-link{color:rgba(0,0,0,.9)}.navbar-light .navbar-toggler{color:rgba(0,0,0,.5);border-color:rgba(0,0,0,.1)}.navbar-light .navbar-toggler-icon{background-image:url("data:image/svg+xml;charset=utf8,%3Csvg viewBox='0 0 30 30' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath stroke='rgba(0, 0, 0, 0.5)' stroke-width='2' stroke-linecap='round' stroke-miterlimit='10' d='M4 7h22M4 15h22M4 23h22'/%3E%3C/svg%3E")}.navbar-light .navbar-text{color:rgba(0,0,0,.5)}.navbar-light .navbar-text a{color:rgba(0,0,0,.9)}.navbar-light .navbar-text a:focus,.navbar-light .navbar-text a:hover{color:rgba(0,0,0,.9)}.navbar-dark .navbar-brand{color:#fff}.navbar-dark .navbar-brand:focus,.navbar-dark .navbar-brand:hover{color:#fff}.navbar-dark .navbar-nav .nav-link{color:rgba(255,255,255,.5)}.navbar-dark .navbar-nav .nav-link:focus,.navbar-dark .navbar-nav .nav-link:hover{color:rgba(255,255,255,.75)}.navbar-dark .navbar-nav .nav-link.disabled{color:rgba(255,255,255,.25)}.navbar-dark .navbar-nav .active>.nav-link,.navbar-dark .navbar-nav .nav-link.active,.navbar-dark .navbar-nav .nav-link.show,.navbar-dark .navbar-nav .show>.nav-link{color:#fff}.navbar-dark .navbar-toggler{color:rgba(255,255,255,.5);border-color:rgba(255,255,255,.1)}.navbar-dark .navbar-toggler-icon{background-image:url("data:image/svg+xml;charset=utf8,%3Csvg viewBox='0 0 30 30' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath stroke='rgba(255, 255, 255, 0.5)' stroke-width='2' stroke-linecap='round' stroke-miterlimit='10' d='M4 7h22M4 15h22M4 23h22'/%3E%3C/svg%3E")}.navbar-dark .navbar-text{color:rgba(255,255,255,.5)}.navbar-dark .navbar-text a{color:#fff}.navbar-dark .navbar-text a:focus,.navbar-dark .navbar-text a:hover{color:#fff}.card{position:relative;display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;min-width:0;word-wrap:break-word;background-color:#fff;background-clip:border-box;border:1px solid rgba(0,0,0,.125);border-radius:.25rem}.card>hr{margin-right:0;margin-left:0}.card>.list-group:first-child .list-group-item:first-child{border-top-left-radius:.25rem;border-top-right-radius:.25rem}.card>.list-group:last-child .list-group-item:last-child{border-bottom-right-radius:.25rem;border-bottom-left-radius:.25rem}.card-body{-ms-flex:1 1 auto;flex:1 1 auto;padding:1.25rem}.card-title{margin-bottom:.75rem}.card-subtitle{margin-top:-.375rem;margin-bottom:0}.card-text:last-child{margin-bottom:0}.card-link:hover{text-decoration:none}.card-link+.card-link{margin-left:1.25rem}.card-header{padding:.75rem 1.25rem;margin-bottom:0;background-color:rgba(0,0,0,.03);border-bottom:1px solid rgba(0,0,0,.125)}.card-header:first-child{border-radius:calc(.25rem - 1px) calc(.25rem - 1px) 0 0}.card-header+.list-group .list-group-item:first-child{border-top:0}.card-footer{padding:.75rem 1.25rem;background-color:rgba(0,0,0,.03);border-top:1px solid rgba(0,0,0,.125)}.card-footer:last-child{border-radius:0 0 calc(.25rem - 1px) calc(.25rem - 1px)}.card-header-tabs{margin-right:-.625rem;margin-bottom:-.75rem;margin-left:-.625rem;border-bottom:0}.card-header-pills{margin-right:-.625rem;margin-left:-.625rem}.card-img-overlay{position:absolute;top:0;right:0;bottom:0;left:0;padding:1.25rem}.card-img{width:100%;border-radius:calc(.25rem - 1px)}.card-img-top{width:100%;border-top-left-radius:calc(.25rem - 1px);border-top-right-radius:calc(.25rem - 1px)}.card-img-bottom{width:100%;border-bottom-right-radius:calc(.25rem - 1px);border-bottom-left-radius:calc(.25rem - 1px)}.card-deck{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column}.card-deck .card{margin-bottom:15px}@media (min-width:576px){.card-deck{-ms-flex-flow:row wrap;flex-flow:row wrap;margin-right:-15px;margin-left:-15px}.card-deck .card{display:-ms-flexbox;display:flex;-ms-flex:1 0 0%;flex:1 0 0%;-ms-flex-direction:column;flex-direction:column;margin-right:15px;margin-bottom:0;margin-left:15px}}.card-group{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column}.card-group>.card{margin-bottom:15px}@media (min-width:576px){.card-group{-ms-flex-flow:row wrap;flex-flow:row wrap}.card-group>.card{-ms-flex:1 0 0%;flex:1 0 0%;margin-bottom:0}.card-group>.card+.card{margin-left:0;border-left:0}.card-group>.card:first-child{border-top-right-radius:0;border-bottom-right-radius:0}.card-group>.card:first-child .card-header,.card-group>.card:first-child .card-img-top{border-top-right-radius:0}.card-group>.card:first-child .card-footer,.card-group>.card:first-child .card-img-bottom{border-bottom-right-radius:0}.card-group>.card:last-child{border-top-left-radius:0;border-bottom-left-radius:0}.card-group>.card:last-child .card-header,.card-group>.card:last-child .card-img-top{border-top-left-radius:0}.card-group>.card:last-child .card-footer,.card-group>.card:last-child .card-img-bottom{border-bottom-left-radius:0}.card-group>.card:only-child{border-radius:.25rem}.card-group>.card:only-child .card-header,.card-group>.card:only-child .card-img-top{border-top-left-radius:.25rem;border-top-right-radius:.25rem}.card-group>.card:only-child .card-footer,.card-group>.card:only-child .card-img-bottom{border-bottom-right-radius:.25rem;border-bottom-left-radius:.25rem}.card-group>.card:not(:first-child):not(:last-child):not(:only-child){border-radius:0}.card-group>.card:not(:first-child):not(:last-child):not(:only-child) .card-footer,.card-group>.card:not(:first-child):not(:last-child):not(:only-child) .card-header,.card-group>.card:not(:first-child):not(:last-child):not(:only-child) .card-img-bottom,.card-group>.card:not(:first-child):not(:last-child):not(:only-child) .card-img-top{border-radius:0}}.card-columns .card{margin-bottom:.75rem}@media (min-width:576px){.card-columns{-webkit-column-count:3;-moz-column-count:3;column-count:3;-webkit-column-gap:1.25rem;-moz-column-gap:1.25rem;column-gap:1.25rem;orphans:1;widows:1}.card-columns .card{display:inline-block;width:100%}}.accordion .card:not(:first-of-type):not(:last-of-type){border-bottom:0;border-radius:0}.accordion .card:not(:first-of-type) .card-header:first-child{border-radius:0}.accordion .card:first-of-type{border-bottom:0;border-bottom-right-radius:0;border-bottom-left-radius:0}.accordion .card:last-of-type{border-top-left-radius:0;border-top-right-radius:0}.breadcrumb{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;padding:.75rem 1rem;margin-bottom:1rem;list-style:none;background-color:#e9ecef;border-radius:.25rem}.breadcrumb-item+.breadcrumb-item{padding-left:.5rem}.breadcrumb-item+.breadcrumb-item::before{display:inline-block;padding-right:.5rem;color:#6c757d;content:"/"}.breadcrumb-item+.breadcrumb-item:hover::before{text-decoration:underline}.breadcrumb-item+.breadcrumb-item:hover::before{text-decoration:none}.breadcrumb-item.active{color:#6c757d}.pagination{display:-ms-flexbox;display:flex;padding-left:0;list-style:none;border-radius:.25rem}.page-link{position:relative;display:block;padding:.5rem .75rem;margin-left:-1px;line-height:1.25;color:#007bff;background-color:#fff;border:1px solid #dee2e6}.page-link:hover{z-index:2;color:#0056b3;text-decoration:none;background-color:#e9ecef;border-color:#dee2e6}.page-link:focus{z-index:2;outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.page-link:not(:disabled):not(.disabled){cursor:pointer}.page-item:first-child .page-link{margin-left:0;border-top-left-radius:.25rem;border-bottom-left-radius:.25rem}.page-item:last-child .page-link{border-top-right-radius:.25rem;border-bottom-right-radius:.25rem}.page-item.active .page-link{z-index:1;color:#fff;background-color:#007bff;border-color:#007bff}.page-item.disabled .page-link{color:#6c757d;pointer-events:none;cursor:auto;background-color:#fff;border-color:#dee2e6}.pagination-lg .page-link{padding:.75rem 1.5rem;font-size:1.25rem;line-height:1.5}.pagination-lg .page-item:first-child .page-link{border-top-left-radius:.3rem;border-bottom-left-radius:.3rem}.pagination-lg .page-item:last-child .page-link{border-top-right-radius:.3rem;border-bottom-right-radius:.3rem}.pagination-sm .page-link{padding:.25rem .5rem;font-size:.875rem;line-height:1.5}.pagination-sm .page-item:first-child .page-link{border-top-left-radius:.2rem;border-bottom-left-radius:.2rem}.pagination-sm .page-item:last-child .page-link{border-top-right-radius:.2rem;border-bottom-right-radius:.2rem}.badge{display:inline-block;padding:.25em .4em;font-size:75%;font-weight:700;line-height:1;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25rem}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.badge-pill{padding-right:.6em;padding-left:.6em;border-radius:10rem}.badge-primary{color:#fff;background-color:#007bff}.badge-primary[href]:focus,.badge-primary[href]:hover{color:#fff;text-decoration:none;background-color:#0062cc}.badge-secondary{color:#fff;background-color:#6c757d}.badge-secondary[href]:focus,.badge-secondary[href]:hover{color:#fff;text-decoration:none;background-color:#545b62}.badge-success{color:#fff;background-color:#28a745}.badge-success[href]:focus,.badge-success[href]:hover{color:#fff;text-decoration:none;background-color:#1e7e34}.badge-info{color:#fff;background-color:#17a2b8}.badge-info[href]:focus,.badge-info[href]:hover{color:#fff;text-decoration:none;background-color:#117a8b}.badge-warning{color:#212529;background-color:#ffc107}.badge-warning[href]:focus,.badge-warning[href]:hover{color:#212529;text-decoration:none;background-color:#d39e00}.badge-danger{color:#fff;background-color:#dc3545}.badge-danger[href]:focus,.badge-danger[href]:hover{color:#fff;text-decoration:none;background-color:#bd2130}.badge-light{color:#212529;background-color:#f8f9fa}.badge-light[href]:focus,.badge-light[href]:hover{color:#212529;text-decoration:none;background-color:#dae0e5}.badge-dark{color:#fff;background-color:#343a40}.badge-dark[href]:focus,.badge-dark[href]:hover{color:#fff;text-decoration:none;background-color:#1d2124}.jumbotron{padding:2rem 1rem;margin-bottom:2rem;background-color:#e9ecef;border-radius:.3rem}@media (min-width:576px){.jumbotron{padding:4rem 2rem}}.jumbotron-fluid{padding-right:0;padding-left:0;border-radius:0}.alert{position:relative;padding:.75rem 1.25rem;margin-bottom:1rem;border:1px solid transparent;border-radius:.25rem}.alert-heading{color:inherit}.alert-link{font-weight:700}.alert-dismissible{padding-right:4rem}.alert-dismissible .close{position:absolute;top:0;right:0;padding:.75rem 1.25rem;color:inherit}.alert-primary{color:#004085;background-color:#cce5ff;border-color:#b8daff}.alert-primary hr{border-top-color:#9fcdff}.alert-primary .alert-link{color:#002752}.alert-secondary{color:#383d41;background-color:#e2e3e5;border-color:#d6d8db}.alert-secondary hr{border-top-color:#c8cbcf}.alert-secondary .alert-link{color:#202326}.alert-success{color:#155724;background-color:#d4edda;border-color:#c3e6cb}.alert-success hr{border-top-color:#b1dfbb}.alert-success .alert-link{color:#0b2e13}.alert-info{color:#0c5460;background-color:#d1ecf1;border-color:#bee5eb}.alert-info hr{border-top-color:#abdde5}.alert-info .alert-link{color:#062c33}.alert-warning{color:#856404;background-color:#fff3cd;border-color:#ffeeba}.alert-warning hr{border-top-color:#ffe8a1}.alert-warning .alert-link{color:#533f03}.alert-danger{color:#721c24;background-color:#f8d7da;border-color:#f5c6cb}.alert-danger hr{border-top-color:#f1b0b7}.alert-danger .alert-link{color:#491217}.alert-light{color:#818182;background-color:#fefefe;border-color:#fdfdfe}.alert-light hr{border-top-color:#ececf6}.alert-light .alert-link{color:#686868}.alert-dark{color:#1b1e21;background-color:#d6d8d9;border-color:#c6c8ca}.alert-dark hr{border-top-color:#b9bbbe}.alert-dark .alert-link{color:#040505}@-webkit-keyframes progress-bar-stripes{from{background-position:1rem 0}to{background-position:0 0}}@keyframes progress-bar-stripes{from{background-position:1rem 0}to{background-position:0 0}}.progress{display:-ms-flexbox;display:flex;height:1rem;overflow:hidden;font-size:.75rem;background-color:#e9ecef;border-radius:.25rem}.progress-bar{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;-ms-flex-pack:center;justify-content:center;color:#fff;text-align:center;white-space:nowrap;background-color:#007bff;transition:width .6s ease}@media screen and (prefers-reduced-motion:reduce){.progress-bar{transition:none}}.progress-bar-striped{background-image:linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);background-size:1rem 1rem}.progress-bar-animated{-webkit-animation:progress-bar-stripes 1s linear infinite;animation:progress-bar-stripes 1s linear infinite}.media{display:-ms-flexbox;display:flex;-ms-flex-align:start;align-items:flex-start}.media-body{-ms-flex:1;flex:1}.list-group{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;padding-left:0;margin-bottom:0}.list-group-item-action{width:100%;color:#495057;text-align:inherit}.list-group-item-action:focus,.list-group-item-action:hover{color:#495057;text-decoration:none;background-color:#f8f9fa}.list-group-item-action:active{color:#212529;background-color:#e9ecef}.list-group-item{position:relative;display:block;padding:.75rem 1.25rem;margin-bottom:-1px;background-color:#fff;border:1px solid rgba(0,0,0,.125)}.list-group-item:first-child{border-top-left-radius:.25rem;border-top-right-radius:.25rem}.list-group-item:last-child{margin-bottom:0;border-bottom-right-radius:.25rem;border-bottom-left-radius:.25rem}.list-group-item:focus,.list-group-item:hover{z-index:1;text-decoration:none}.list-group-item.disabled,.list-group-item:disabled{color:#6c757d;background-color:#fff}.list-group-item.active{z-index:2;color:#fff;background-color:#007bff;border-color:#007bff}.list-group-flush .list-group-item{border-right:0;border-left:0;border-radius:0}.list-group-flush:first-child .list-group-item:first-child{border-top:0}.list-group-flush:last-child .list-group-item:last-child{border-bottom:0}.list-group-item-primary{color:#004085;background-color:#b8daff}.list-group-item-primary.list-group-item-action:focus,.list-group-item-primary.list-group-item-action:hover{color:#004085;background-color:#9fcdff}.list-group-item-primary.list-group-item-action.active{color:#fff;background-color:#004085;border-color:#004085}.list-group-item-secondary{color:#383d41;background-color:#d6d8db}.list-group-item-secondary.list-group-item-action:focus,.list-group-item-secondary.list-group-item-action:hover{color:#383d41;background-color:#c8cbcf}.list-group-item-secondary.list-group-item-action.active{color:#fff;background-color:#383d41;border-color:#383d41}.list-group-item-success{color:#155724;background-color:#c3e6cb}.list-group-item-success.list-group-item-action:focus,.list-group-item-success.list-group-item-action:hover{color:#155724;background-color:#b1dfbb}.list-group-item-success.list-group-item-action.active{color:#fff;background-color:#155724;border-color:#155724}.list-group-item-info{color:#0c5460;background-color:#bee5eb}.list-group-item-info.list-group-item-action:focus,.list-group-item-info.list-group-item-action:hover{color:#0c5460;background-color:#abdde5}.list-group-item-info.list-group-item-action.active{color:#fff;background-color:#0c5460;border-color:#0c5460}.list-group-item-warning{color:#856404;background-color:#ffeeba}.list-group-item-warning.list-group-item-action:focus,.list-group-item-warning.list-group-item-action:hover{color:#856404;background-color:#ffe8a1}.list-group-item-warning.list-group-item-action.active{color:#fff;background-color:#856404;border-color:#856404}.list-group-item-danger{color:#721c24;background-color:#f5c6cb}.list-group-item-danger.list-group-item-action:focus,.list-group-item-danger.list-group-item-action:hover{color:#721c24;background-color:#f1b0b7}.list-group-item-danger.list-group-item-action.active{color:#fff;background-color:#721c24;border-color:#721c24}.list-group-item-light{color:#818182;background-color:#fdfdfe}.list-group-item-light.list-group-item-action:focus,.list-group-item-light.list-group-item-action:hover{color:#818182;background-color:#ececf6}.list-group-item-light.list-group-item-action.active{color:#fff;background-color:#818182;border-color:#818182}.list-group-item-dark{color:#1b1e21;background-color:#c6c8ca}.list-group-item-dark.list-group-item-action:focus,.list-group-item-dark.list-group-item-action:hover{color:#1b1e21;background-color:#b9bbbe}.list-group-item-dark.list-group-item-action.active{color:#fff;background-color:#1b1e21;border-color:#1b1e21}.close{float:right;font-size:1.5rem;font-weight:700;line-height:1;color:#000;text-shadow:0 1px 0 #fff;opacity:.5}.close:not(:disabled):not(.disabled){cursor:pointer}.close:not(:disabled):not(.disabled):focus,.close:not(:disabled):not(.disabled):hover{color:#000;text-decoration:none;opacity:.75}button.close{padding:0;background-color:transparent;border:0;-webkit-appearance:none}.modal-open{overflow:hidden}.modal-open .modal{overflow-x:hidden;overflow-y:auto}.modal{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1050;display:none;overflow:hidden;outline:0}.modal-dialog{position:relative;width:auto;margin:.5rem;pointer-events:none}.modal.fade .modal-dialog{transition:-webkit-transform .3s ease-out;transition:transform .3s ease-out;transition:transform .3s ease-out,-webkit-transform .3s ease-out;-webkit-transform:translate(0,-25%);transform:translate(0,-25%)}@media screen and (prefers-reduced-motion:reduce){.modal.fade .modal-dialog{transition:none}}.modal.show .modal-dialog{-webkit-transform:translate(0,0);transform:translate(0,0)}.modal-dialog-centered{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;min-height:calc(100% - (.5rem * 2))}.modal-dialog-centered::before{display:block;height:calc(100vh - (.5rem * 2));content:""}.modal-content{position:relative;display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;width:100%;pointer-events:auto;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.2);border-radius:.3rem;outline:0}.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;background-color:#000}.modal-backdrop.fade{opacity:0}.modal-backdrop.show{opacity:.5}.modal-header{display:-ms-flexbox;display:flex;-ms-flex-align:start;align-items:flex-start;-ms-flex-pack:justify;justify-content:space-between;padding:1rem;border-bottom:1px solid #e9ecef;border-top-left-radius:.3rem;border-top-right-radius:.3rem}.modal-header .close{padding:1rem;margin:-1rem -1rem -1rem auto}.modal-title{margin-bottom:0;line-height:1.5}.modal-body{position:relative;-ms-flex:1 1 auto;flex:1 1 auto;padding:1rem}.modal-footer{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:end;justify-content:flex-end;padding:1rem;border-top:1px solid #e9ecef}.modal-footer>:not(:first-child){margin-left:.25rem}.modal-footer>:not(:last-child){margin-right:.25rem}.modal-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}@media (min-width:576px){.modal-dialog{max-width:500px;margin:1.75rem auto}.modal-dialog-centered{min-height:calc(100% - (1.75rem * 2))}.modal-dialog-centered::before{height:calc(100vh - (1.75rem * 2))}.modal-sm{max-width:300px}}@media (min-width:992px){.modal-lg{max-width:800px}}.tooltip{position:absolute;z-index:1070;display:block;margin:0;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;white-space:normal;line-break:auto;font-size:.875rem;word-wrap:break-word;opacity:0}.tooltip.show{opacity:.9}.tooltip .arrow{position:absolute;display:block;width:.8rem;height:.4rem}.tooltip .arrow::before{position:absolute;content:"";border-color:transparent;border-style:solid}.bs-tooltip-auto[x-placement^=top],.bs-tooltip-top{padding:.4rem 0}.bs-tooltip-auto[x-placement^=top] .arrow,.bs-tooltip-top .arrow{bottom:0}.bs-tooltip-auto[x-placement^=top] .arrow::before,.bs-tooltip-top .arrow::before{top:0;border-width:.4rem .4rem 0;border-top-color:#000}.bs-tooltip-auto[x-placement^=right],.bs-tooltip-right{padding:0 .4rem}.bs-tooltip-auto[x-placement^=right] .arrow,.bs-tooltip-right .arrow{left:0;width:.4rem;height:.8rem}.bs-tooltip-auto[x-placement^=right] .arrow::before,.bs-tooltip-right .arrow::before{right:0;border-width:.4rem .4rem .4rem 0;border-right-color:#000}.bs-tooltip-auto[x-placement^=bottom],.bs-tooltip-bottom{padding:.4rem 0}.bs-tooltip-auto[x-placement^=bottom] .arrow,.bs-tooltip-bottom .arrow{top:0}.bs-tooltip-auto[x-placement^=bottom] .arrow::before,.bs-tooltip-bottom .arrow::before{bottom:0;border-width:0 .4rem .4rem;border-bottom-color:#000}.bs-tooltip-auto[x-placement^=left],.bs-tooltip-left{padding:0 .4rem}.bs-tooltip-auto[x-placement^=left] .arrow,.bs-tooltip-left .arrow{right:0;width:.4rem;height:.8rem}.bs-tooltip-auto[x-placement^=left] .arrow::before,.bs-tooltip-left .arrow::before{left:0;border-width:.4rem 0 .4rem .4rem;border-left-color:#000}.tooltip-inner{max-width:200px;padding:.25rem .5rem;color:#fff;text-align:center;background-color:#000;border-radius:.25rem}.popover{position:absolute;top:0;left:0;z-index:1060;display:block;max-width:276px;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;white-space:normal;line-break:auto;font-size:.875rem;word-wrap:break-word;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.2);border-radius:.3rem}.popover .arrow{position:absolute;display:block;width:1rem;height:.5rem;margin:0 .3rem}.popover .arrow::after,.popover .arrow::before{position:absolute;display:block;content:"";border-color:transparent;border-style:solid}.bs-popover-auto[x-placement^=top],.bs-popover-top{margin-bottom:.5rem}.bs-popover-auto[x-placement^=top] .arrow,.bs-popover-top .arrow{bottom:calc((.5rem + 1px) * -1)}.bs-popover-auto[x-placement^=top] .arrow::after,.bs-popover-auto[x-placement^=top] .arrow::before,.bs-popover-top .arrow::after,.bs-popover-top .arrow::before{border-width:.5rem .5rem 0}.bs-popover-auto[x-placement^=top] .arrow::before,.bs-popover-top .arrow::before{bottom:0;border-top-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=top] .arrow::after,.bs-popover-top .arrow::after{bottom:1px;border-top-color:#fff}.bs-popover-auto[x-placement^=right],.bs-popover-right{margin-left:.5rem}.bs-popover-auto[x-placement^=right] .arrow,.bs-popover-right .arrow{left:calc((.5rem + 1px) * -1);width:.5rem;height:1rem;margin:.3rem 0}.bs-popover-auto[x-placement^=right] .arrow::after,.bs-popover-auto[x-placement^=right] .arrow::before,.bs-popover-right .arrow::after,.bs-popover-right .arrow::before{border-width:.5rem .5rem .5rem 0}.bs-popover-auto[x-placement^=right] .arrow::before,.bs-popover-right .arrow::before{left:0;border-right-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=right] .arrow::after,.bs-popover-right .arrow::after{left:1px;border-right-color:#fff}.bs-popover-auto[x-placement^=bottom],.bs-popover-bottom{margin-top:.5rem}.bs-popover-auto[x-placement^=bottom] .arrow,.bs-popover-bottom .arrow{top:calc((.5rem + 1px) * -1)}.bs-popover-auto[x-placement^=bottom] .arrow::after,.bs-popover-auto[x-placement^=bottom] .arrow::before,.bs-popover-bottom .arrow::after,.bs-popover-bottom .arrow::before{border-width:0 .5rem .5rem .5rem}.bs-popover-auto[x-placement^=bottom] .arrow::before,.bs-popover-bottom .arrow::before{top:0;border-bottom-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=bottom] .arrow::after,.bs-popover-bottom .arrow::after{top:1px;border-bottom-color:#fff}.bs-popover-auto[x-placement^=bottom] .popover-header::before,.bs-popover-bottom .popover-header::before{position:absolute;top:0;left:50%;display:block;width:1rem;margin-left:-.5rem;content:"";border-bottom:1px solid #f7f7f7}.bs-popover-auto[x-placement^=left],.bs-popover-left{margin-right:.5rem}.bs-popover-auto[x-placement^=left] .arrow,.bs-popover-left .arrow{right:calc((.5rem + 1px) * -1);width:.5rem;height:1rem;margin:.3rem 0}.bs-popover-auto[x-placement^=left] .arrow::after,.bs-popover-auto[x-placement^=left] .arrow::before,.bs-popover-left .arrow::after,.bs-popover-left .arrow::before{border-width:.5rem 0 .5rem .5rem}.bs-popover-auto[x-placement^=left] .arrow::before,.bs-popover-left .arrow::before{right:0;border-left-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=left] .arrow::after,.bs-popover-left .arrow::after{right:1px;border-left-color:#fff}.popover-header{padding:.5rem .75rem;margin-bottom:0;font-size:1rem;color:inherit;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-top-left-radius:calc(.3rem - 1px);border-top-right-radius:calc(.3rem - 1px)}.popover-header:empty{display:none}.popover-body{padding:.5rem .75rem;color:#212529}.carousel{position:relative}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-item{position:relative;display:none;-ms-flex-align:center;align-items:center;width:100%;-webkit-backface-visibility:hidden;backface-visibility:hidden;-webkit-perspective:1000px;perspective:1000px}.carousel-item-next,.carousel-item-prev,.carousel-item.active{display:block;transition:-webkit-transform .6s ease;transition:transform .6s ease;transition:transform .6s ease,-webkit-transform .6s ease}@media screen and (prefers-reduced-motion:reduce){.carousel-item-next,.carousel-item-prev,.carousel-item.active{transition:none}}.carousel-item-next,.carousel-item-prev{position:absolute;top:0}.carousel-item-next.carousel-item-left,.carousel-item-prev.carousel-item-right{-webkit-transform:translateX(0);transform:translateX(0)}@supports ((-webkit-transform-style:preserve-3d) or (transform-style:preserve-3d)){.carousel-item-next.carousel-item-left,.carousel-item-prev.carousel-item-right{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}.active.carousel-item-right,.carousel-item-next{-webkit-transform:translateX(100%);transform:translateX(100%)}@supports ((-webkit-transform-style:preserve-3d) or (transform-style:preserve-3d)){.active.carousel-item-right,.carousel-item-next{-webkit-transform:translate3d(100%,0,0);transform:translate3d(100%,0,0)}}.active.carousel-item-left,.carousel-item-prev{-webkit-transform:translateX(-100%);transform:translateX(-100%)}@supports ((-webkit-transform-style:preserve-3d) or (transform-style:preserve-3d)){.active.carousel-item-left,.carousel-item-prev{-webkit-transform:translate3d(-100%,0,0);transform:translate3d(-100%,0,0)}}.carousel-fade .carousel-item{opacity:0;transition-duration:.6s;transition-property:opacity}.carousel-fade .carousel-item-next.carousel-item-left,.carousel-fade .carousel-item-prev.carousel-item-right,.carousel-fade .carousel-item.active{opacity:1}.carousel-fade .active.carousel-item-left,.carousel-fade .active.carousel-item-right{opacity:0}.carousel-fade .active.carousel-item-left,.carousel-fade .active.carousel-item-prev,.carousel-fade .carousel-item-next,.carousel-fade .carousel-item-prev,.carousel-fade .carousel-item.active{-webkit-transform:translateX(0);transform:translateX(0)}@supports ((-webkit-transform-style:preserve-3d) or (transform-style:preserve-3d)){.carousel-fade .active.carousel-item-left,.carousel-fade .active.carousel-item-prev,.carousel-fade .carousel-item-next,.carousel-fade .carousel-item-prev,.carousel-fade .carousel-item.active{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0)}}.carousel-control-next,.carousel-control-prev{position:absolute;top:0;bottom:0;display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-pack:center;justify-content:center;width:15%;color:#fff;text-align:center;opacity:.5}.carousel-control-next:focus,.carousel-control-next:hover,.carousel-control-prev:focus,.carousel-control-prev:hover{color:#fff;text-decoration:none;outline:0;opacity:.9}.carousel-control-prev{left:0}.carousel-control-next{right:0}.carousel-control-next-icon,.carousel-control-prev-icon{display:inline-block;width:20px;height:20px;background:transparent no-repeat center center;background-size:100% 100%}.carousel-control-prev-icon{background-image:url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' viewBox='0 0 8 8'%3E%3Cpath d='M5.25 0l-4 4 4 4 1.5-1.5-2.5-2.5 2.5-2.5-1.5-1.5z'/%3E%3C/svg%3E")}.carousel-control-next-icon{background-image:url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%23fff' viewBox='0 0 8 8'%3E%3Cpath d='M2.75 0l-1.5 1.5 2.5 2.5-2.5 2.5 1.5 1.5 4-4-4-4z'/%3E%3C/svg%3E")}.carousel-indicators{position:absolute;right:0;bottom:10px;left:0;z-index:15;display:-ms-flexbox;display:flex;-ms-flex-pack:center;justify-content:center;padding-left:0;margin-right:15%;margin-left:15%;list-style:none}.carousel-indicators li{position:relative;-ms-flex:0 1 auto;flex:0 1 auto;width:30px;height:3px;margin-right:3px;margin-left:3px;text-indent:-999px;cursor:pointer;background-color:rgba(255,255,255,.5)}.carousel-indicators li::before{position:absolute;top:-10px;left:0;display:inline-block;width:100%;height:10px;content:""}.carousel-indicators li::after{position:absolute;bottom:-10px;left:0;display:inline-block;width:100%;height:10px;content:""}.carousel-indicators .active{background-color:#fff}.carousel-caption{position:absolute;right:15%;bottom:20px;left:15%;z-index:10;padding-top:20px;padding-bottom:20px;color:#fff;text-align:center}.align-baseline{vertical-align:baseline!important}.align-top{vertical-align:top!important}.align-middle{vertical-align:middle!important}.align-bottom{vertical-align:bottom!important}.align-text-bottom{vertical-align:text-bottom!important}.align-text-top{vertical-align:text-top!important}.bg-primary{background-color:#007bff!important}a.bg-primary:focus,a.bg-primary:hover,button.bg-primary:focus,button.bg-primary:hover{background-color:#0062cc!important}.bg-secondary{background-color:#6c757d!important}a.bg-secondary:focus,a.bg-secondary:hover,button.bg-secondary:focus,button.bg-secondary:hover{background-color:#545b62!important}.bg-success{background-color:#28a745!important}a.bg-success:focus,a.bg-success:hover,button.bg-success:focus,button.bg-success:hover{background-color:#1e7e34!important}.bg-info{background-color:#17a2b8!important}a.bg-info:focus,a.bg-info:hover,button.bg-info:focus,button.bg-info:hover{background-color:#117a8b!important}.bg-warning{background-color:#ffc107!important}a.bg-warning:focus,a.bg-warning:hover,button.bg-warning:focus,button.bg-warning:hover{background-color:#d39e00!important}.bg-danger{background-color:#dc3545!important}a.bg-danger:focus,a.bg-danger:hover,button.bg-danger:focus,button.bg-danger:hover{background-color:#bd2130!important}.bg-light{background-color:#f8f9fa!important}a.bg-light:focus,a.bg-light:hover,button.bg-light:focus,button.bg-light:hover{background-color:#dae0e5!important}.bg-dark{background-color:#343a40!important}a.bg-dark:focus,a.bg-dark:hover,button.bg-dark:focus,button.bg-dark:hover{background-color:#1d2124!important}.bg-white{background-color:#fff!important}.bg-transparent{background-color:transparent!important}.border{border:1px solid #dee2e6!important}.border-top{border-top:1px solid #dee2e6!important}.border-right{border-right:1px solid #dee2e6!important}.border-bottom{border-bottom:1px solid #dee2e6!important}.border-left{border-left:1px solid #dee2e6!important}.border-0{border:0!important}.border-top-0{border-top:0!important}.border-right-0{border-right:0!important}.border-bottom-0{border-bottom:0!important}.border-left-0{border-left:0!important}.border-primary{border-color:#007bff!important}.border-secondary{border-color:#6c757d!important}.border-success{border-color:#28a745!important}.border-info{border-color:#17a2b8!important}.border-warning{border-color:#ffc107!important}.border-danger{border-color:#dc3545!important}.border-light{border-color:#f8f9fa!important}.border-dark{border-color:#343a40!important}.border-white{border-color:#fff!important}.rounded{border-radius:.25rem!important}.rounded-top{border-top-left-radius:.25rem!important;border-top-right-radius:.25rem!important}.rounded-right{border-top-right-radius:.25rem!important;border-bottom-right-radius:.25rem!important}.rounded-bottom{border-bottom-right-radius:.25rem!important;border-bottom-left-radius:.25rem!important}.rounded-left{border-top-left-radius:.25rem!important;border-bottom-left-radius:.25rem!important}.rounded-circle{border-radius:50%!important}.rounded-0{border-radius:0!important}.clearfix::after{display:block;clear:both;content:""}.d-none{display:none!important}.d-inline{display:inline!important}.d-inline-block{display:inline-block!important}.d-block{display:block!important}.d-table{display:table!important}.d-table-row{display:table-row!important}.d-table-cell{display:table-cell!important}.d-flex{display:-ms-flexbox!important;display:flex!important}.d-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}@media (min-width:576px){.d-sm-none{display:none!important}.d-sm-inline{display:inline!important}.d-sm-inline-block{display:inline-block!important}.d-sm-block{display:block!important}.d-sm-table{display:table!important}.d-sm-table-row{display:table-row!important}.d-sm-table-cell{display:table-cell!important}.d-sm-flex{display:-ms-flexbox!important;display:flex!important}.d-sm-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}@media (min-width:768px){.d-md-none{display:none!important}.d-md-inline{display:inline!important}.d-md-inline-block{display:inline-block!important}.d-md-block{display:block!important}.d-md-table{display:table!important}.d-md-table-row{display:table-row!important}.d-md-table-cell{display:table-cell!important}.d-md-flex{display:-ms-flexbox!important;display:flex!important}.d-md-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}@media (min-width:992px){.d-lg-none{display:none!important}.d-lg-inline{display:inline!important}.d-lg-inline-block{display:inline-block!important}.d-lg-block{display:block!important}.d-lg-table{display:table!important}.d-lg-table-row{display:table-row!important}.d-lg-table-cell{display:table-cell!important}.d-lg-flex{display:-ms-flexbox!important;display:flex!important}.d-lg-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}@media (min-width:1200px){.d-xl-none{display:none!important}.d-xl-inline{display:inline!important}.d-xl-inline-block{display:inline-block!important}.d-xl-block{display:block!important}.d-xl-table{display:table!important}.d-xl-table-row{display:table-row!important}.d-xl-table-cell{display:table-cell!important}.d-xl-flex{display:-ms-flexbox!important;display:flex!important}.d-xl-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}@media print{.d-print-none{display:none!important}.d-print-inline{display:inline!important}.d-print-inline-block{display:inline-block!important}.d-print-block{display:block!important}.d-print-table{display:table!important}.d-print-table-row{display:table-row!important}.d-print-table-cell{display:table-cell!important}.d-print-flex{display:-ms-flexbox!important;display:flex!important}.d-print-inline-flex{display:-ms-inline-flexbox!important;display:inline-flex!important}}.embed-responsive{position:relative;display:block;width:100%;padding:0;overflow:hidden}.embed-responsive::before{display:block;content:""}.embed-responsive .embed-responsive-item,.embed-responsive embed,.embed-responsive iframe,.embed-responsive object,.embed-responsive video{position:absolute;top:0;bottom:0;left:0;width:100%;height:100%;border:0}.embed-responsive-21by9::before{padding-top:42.857143%}.embed-responsive-16by9::before{padding-top:56.25%}.embed-responsive-4by3::before{padding-top:75%}.embed-responsive-1by1::before{padding-top:100%}.flex-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-center{-ms-flex-align:center!important;align-items:center!important}.align-items-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}@media (min-width:576px){.flex-sm-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-sm-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-sm-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-sm-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-sm-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-sm-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-sm-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-sm-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-sm-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-sm-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-sm-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-sm-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-sm-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-sm-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-sm-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-sm-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-sm-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-sm-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-sm-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-sm-center{-ms-flex-align:center!important;align-items:center!important}.align-items-sm-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-sm-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-sm-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-sm-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-sm-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-sm-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-sm-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-sm-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-sm-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-sm-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-sm-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-sm-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-sm-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-sm-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}}@media (min-width:768px){.flex-md-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-md-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-md-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-md-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-md-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-md-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-md-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-md-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-md-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-md-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-md-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-md-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-md-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-md-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-md-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-md-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-md-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-md-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-md-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-md-center{-ms-flex-align:center!important;align-items:center!important}.align-items-md-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-md-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-md-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-md-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-md-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-md-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-md-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-md-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-md-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-md-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-md-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-md-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-md-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-md-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}}@media (min-width:992px){.flex-lg-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-lg-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-lg-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-lg-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-lg-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-lg-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-lg-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-lg-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-lg-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-lg-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-lg-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-lg-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-lg-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-lg-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-lg-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-lg-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-lg-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-lg-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-lg-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-lg-center{-ms-flex-align:center!important;align-items:center!important}.align-items-lg-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-lg-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-lg-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-lg-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-lg-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-lg-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-lg-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-lg-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-lg-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-lg-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-lg-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-lg-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-lg-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-lg-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}}@media (min-width:1200px){.flex-xl-row{-ms-flex-direction:row!important;flex-direction:row!important}.flex-xl-column{-ms-flex-direction:column!important;flex-direction:column!important}.flex-xl-row-reverse{-ms-flex-direction:row-reverse!important;flex-direction:row-reverse!important}.flex-xl-column-reverse{-ms-flex-direction:column-reverse!important;flex-direction:column-reverse!important}.flex-xl-wrap{-ms-flex-wrap:wrap!important;flex-wrap:wrap!important}.flex-xl-nowrap{-ms-flex-wrap:nowrap!important;flex-wrap:nowrap!important}.flex-xl-wrap-reverse{-ms-flex-wrap:wrap-reverse!important;flex-wrap:wrap-reverse!important}.flex-xl-fill{-ms-flex:1 1 auto!important;flex:1 1 auto!important}.flex-xl-grow-0{-ms-flex-positive:0!important;flex-grow:0!important}.flex-xl-grow-1{-ms-flex-positive:1!important;flex-grow:1!important}.flex-xl-shrink-0{-ms-flex-negative:0!important;flex-shrink:0!important}.flex-xl-shrink-1{-ms-flex-negative:1!important;flex-shrink:1!important}.justify-content-xl-start{-ms-flex-pack:start!important;justify-content:flex-start!important}.justify-content-xl-end{-ms-flex-pack:end!important;justify-content:flex-end!important}.justify-content-xl-center{-ms-flex-pack:center!important;justify-content:center!important}.justify-content-xl-between{-ms-flex-pack:justify!important;justify-content:space-between!important}.justify-content-xl-around{-ms-flex-pack:distribute!important;justify-content:space-around!important}.align-items-xl-start{-ms-flex-align:start!important;align-items:flex-start!important}.align-items-xl-end{-ms-flex-align:end!important;align-items:flex-end!important}.align-items-xl-center{-ms-flex-align:center!important;align-items:center!important}.align-items-xl-baseline{-ms-flex-align:baseline!important;align-items:baseline!important}.align-items-xl-stretch{-ms-flex-align:stretch!important;align-items:stretch!important}.align-content-xl-start{-ms-flex-line-pack:start!important;align-content:flex-start!important}.align-content-xl-end{-ms-flex-line-pack:end!important;align-content:flex-end!important}.align-content-xl-center{-ms-flex-line-pack:center!important;align-content:center!important}.align-content-xl-between{-ms-flex-line-pack:justify!important;align-content:space-between!important}.align-content-xl-around{-ms-flex-line-pack:distribute!important;align-content:space-around!important}.align-content-xl-stretch{-ms-flex-line-pack:stretch!important;align-content:stretch!important}.align-self-xl-auto{-ms-flex-item-align:auto!important;align-self:auto!important}.align-self-xl-start{-ms-flex-item-align:start!important;align-self:flex-start!important}.align-self-xl-end{-ms-flex-item-align:end!important;align-self:flex-end!important}.align-self-xl-center{-ms-flex-item-align:center!important;align-self:center!important}.align-self-xl-baseline{-ms-flex-item-align:baseline!important;align-self:baseline!important}.align-self-xl-stretch{-ms-flex-item-align:stretch!important;align-self:stretch!important}}.float-left{float:left!important}.float-right{float:right!important}.float-none{float:none!important}@media (min-width:576px){.float-sm-left{float:left!important}.float-sm-right{float:right!important}.float-sm-none{float:none!important}}@media (min-width:768px){.float-md-left{float:left!important}.float-md-right{float:right!important}.float-md-none{float:none!important}}@media (min-width:992px){.float-lg-left{float:left!important}.float-lg-right{float:right!important}.float-lg-none{float:none!important}}@media (min-width:1200px){.float-xl-left{float:left!important}.float-xl-right{float:right!important}.float-xl-none{float:none!important}}.position-static{position:static!important}.position-relative{position:relative!important}.position-absolute{position:absolute!important}.position-fixed{position:fixed!important}.position-sticky{position:-webkit-sticky!important;position:sticky!important}.fixed-top{position:fixed;top:0;right:0;left:0;z-index:1030}.fixed-bottom{position:fixed;right:0;bottom:0;left:0;z-index:1030}@supports ((position:-webkit-sticky) or (position:sticky)){.sticky-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}}.sr-only{position:absolute;width:1px;height:1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;overflow:visible;clip:auto;white-space:normal}.shadow-sm{box-shadow:0 .125rem .25rem rgba(0,0,0,.075)!important}.shadow{box-shadow:0 .5rem 1rem rgba(0,0,0,.15)!important}.shadow-lg{box-shadow:0 1rem 3rem rgba(0,0,0,.175)!important}.shadow-none{box-shadow:none!important}.w-25{width:25%!important}.w-50{width:50%!important}.w-75{width:75%!important}.w-100{width:100%!important}.w-auto{width:auto!important}.h-25{height:25%!important}.h-50{height:50%!important}.h-75{height:75%!important}.h-100{height:100%!important}.h-auto{height:auto!important}.mw-100{max-width:100%!important}.mh-100{max-height:100%!important}.m-0{margin:0!important}.mt-0,.my-0{margin-top:0!important}.mr-0,.mx-0{margin-right:0!important}.mb-0,.my-0{margin-bottom:0!important}.ml-0,.mx-0{margin-left:0!important}.m-1{margin:.25rem!important}.mt-1,.my-1{margin-top:.25rem!important}.mr-1,.mx-1{margin-right:.25rem!important}.mb-1,.my-1{margin-bottom:.25rem!important}.ml-1,.mx-1{margin-left:.25rem!important}.m-2{margin:.5rem!important}.mt-2,.my-2{margin-top:.5rem!important}.mr-2,.mx-2{margin-right:.5rem!important}.mb-2,.my-2{margin-bottom:.5rem!important}.ml-2,.mx-2{margin-left:.5rem!important}.m-3{margin:1rem!important}.mt-3,.my-3{margin-top:1rem!important}.mr-3,.mx-3{margin-right:1rem!important}.mb-3,.my-3{margin-bottom:1rem!important}.ml-3,.mx-3{margin-left:1rem!important}.m-4{margin:1.5rem!important}.mt-4,.my-4{margin-top:1.5rem!important}.mr-4,.mx-4{margin-right:1.5rem!important}.mb-4,.my-4{margin-bottom:1.5rem!important}.ml-4,.mx-4{margin-left:1.5rem!important}.m-5{margin:3rem!important}.mt-5,.my-5{margin-top:3rem!important}.mr-5,.mx-5{margin-right:3rem!important}.mb-5,.my-5{margin-bottom:3rem!important}.ml-5,.mx-5{margin-left:3rem!important}.p-0{padding:0!important}.pt-0,.py-0{padding-top:0!important}.pr-0,.px-0{padding-right:0!important}.pb-0,.py-0{padding-bottom:0!important}.pl-0,.px-0{padding-left:0!important}.p-1{padding:.25rem!important}.pt-1,.py-1{padding-top:.25rem!important}.pr-1,.px-1{padding-right:.25rem!important}.pb-1,.py-1{padding-bottom:.25rem!important}.pl-1,.px-1{padding-left:.25rem!important}.p-2{padding:.5rem!important}.pt-2,.py-2{padding-top:.5rem!important}.pr-2,.px-2{padding-right:.5rem!important}.pb-2,.py-2{padding-bottom:.5rem!important}.pl-2,.px-2{padding-left:.5rem!important}.p-3{padding:1rem!important}.pt-3,.py-3{padding-top:1rem!important}.pr-3,.px-3{padding-right:1rem!important}.pb-3,.py-3{padding-bottom:1rem!important}.pl-3,.px-3{padding-left:1rem!important}.p-4{padding:1.5rem!important}.pt-4,.py-4{padding-top:1.5rem!important}.pr-4,.px-4{padding-right:1.5rem!important}.pb-4,.py-4{padding-bottom:1.5rem!important}.pl-4,.px-4{padding-left:1.5rem!important}.p-5{padding:3rem!important}.pt-5,.py-5{padding-top:3rem!important}.pr-5,.px-5{padding-right:3rem!important}.pb-5,.py-5{padding-bottom:3rem!important}.pl-5,.px-5{padding-left:3rem!important}.m-auto{margin:auto!important}.mt-auto,.my-auto{margin-top:auto!important}.mr-auto,.mx-auto{margin-right:auto!important}.mb-auto,.my-auto{margin-bottom:auto!important}.ml-auto,.mx-auto{margin-left:auto!important}@media (min-width:576px){.m-sm-0{margin:0!important}.mt-sm-0,.my-sm-0{margin-top:0!important}.mr-sm-0,.mx-sm-0{margin-right:0!important}.mb-sm-0,.my-sm-0{margin-bottom:0!important}.ml-sm-0,.mx-sm-0{margin-left:0!important}.m-sm-1{margin:.25rem!important}.mt-sm-1,.my-sm-1{margin-top:.25rem!important}.mr-sm-1,.mx-sm-1{margin-right:.25rem!important}.mb-sm-1,.my-sm-1{margin-bottom:.25rem!important}.ml-sm-1,.mx-sm-1{margin-left:.25rem!important}.m-sm-2{margin:.5rem!important}.mt-sm-2,.my-sm-2{margin-top:.5rem!important}.mr-sm-2,.mx-sm-2{margin-right:.5rem!important}.mb-sm-2,.my-sm-2{margin-bottom:.5rem!important}.ml-sm-2,.mx-sm-2{margin-left:.5rem!important}.m-sm-3{margin:1rem!important}.mt-sm-3,.my-sm-3{margin-top:1rem!important}.mr-sm-3,.mx-sm-3{margin-right:1rem!important}.mb-sm-3,.my-sm-3{margin-bottom:1rem!important}.ml-sm-3,.mx-sm-3{margin-left:1rem!important}.m-sm-4{margin:1.5rem!important}.mt-sm-4,.my-sm-4{margin-top:1.5rem!important}.mr-sm-4,.mx-sm-4{margin-right:1.5rem!important}.mb-sm-4,.my-sm-4{margin-bottom:1.5rem!important}.ml-sm-4,.mx-sm-4{margin-left:1.5rem!important}.m-sm-5{margin:3rem!important}.mt-sm-5,.my-sm-5{margin-top:3rem!important}.mr-sm-5,.mx-sm-5{margin-right:3rem!important}.mb-sm-5,.my-sm-5{margin-bottom:3rem!important}.ml-sm-5,.mx-sm-5{margin-left:3rem!important}.p-sm-0{padding:0!important}.pt-sm-0,.py-sm-0{padding-top:0!important}.pr-sm-0,.px-sm-0{padding-right:0!important}.pb-sm-0,.py-sm-0{padding-bottom:0!important}.pl-sm-0,.px-sm-0{padding-left:0!important}.p-sm-1{padding:.25rem!important}.pt-sm-1,.py-sm-1{padding-top:.25rem!important}.pr-sm-1,.px-sm-1{padding-right:.25rem!important}.pb-sm-1,.py-sm-1{padding-bottom:.25rem!important}.pl-sm-1,.px-sm-1{padding-left:.25rem!important}.p-sm-2{padding:.5rem!important}.pt-sm-2,.py-sm-2{padding-top:.5rem!important}.pr-sm-2,.px-sm-2{padding-right:.5rem!important}.pb-sm-2,.py-sm-2{padding-bottom:.5rem!important}.pl-sm-2,.px-sm-2{padding-left:.5rem!important}.p-sm-3{padding:1rem!important}.pt-sm-3,.py-sm-3{padding-top:1rem!important}.pr-sm-3,.px-sm-3{padding-right:1rem!important}.pb-sm-3,.py-sm-3{padding-bottom:1rem!important}.pl-sm-3,.px-sm-3{padding-left:1rem!important}.p-sm-4{padding:1.5rem!important}.pt-sm-4,.py-sm-4{padding-top:1.5rem!important}.pr-sm-4,.px-sm-4{padding-right:1.5rem!important}.pb-sm-4,.py-sm-4{padding-bottom:1.5rem!important}.pl-sm-4,.px-sm-4{padding-left:1.5rem!important}.p-sm-5{padding:3rem!important}.pt-sm-5,.py-sm-5{padding-top:3rem!important}.pr-sm-5,.px-sm-5{padding-right:3rem!important}.pb-sm-5,.py-sm-5{padding-bottom:3rem!important}.pl-sm-5,.px-sm-5{padding-left:3rem!important}.m-sm-auto{margin:auto!important}.mt-sm-auto,.my-sm-auto{margin-top:auto!important}.mr-sm-auto,.mx-sm-auto{margin-right:auto!important}.mb-sm-auto,.my-sm-auto{margin-bottom:auto!important}.ml-sm-auto,.mx-sm-auto{margin-left:auto!important}}@media (min-width:768px){.m-md-0{margin:0!important}.mt-md-0,.my-md-0{margin-top:0!important}.mr-md-0,.mx-md-0{margin-right:0!important}.mb-md-0,.my-md-0{margin-bottom:0!important}.ml-md-0,.mx-md-0{margin-left:0!important}.m-md-1{margin:.25rem!important}.mt-md-1,.my-md-1{margin-top:.25rem!important}.mr-md-1,.mx-md-1{margin-right:.25rem!important}.mb-md-1,.my-md-1{margin-bottom:.25rem!important}.ml-md-1,.mx-md-1{margin-left:.25rem!important}.m-md-2{margin:.5rem!important}.mt-md-2,.my-md-2{margin-top:.5rem!important}.mr-md-2,.mx-md-2{margin-right:.5rem!important}.mb-md-2,.my-md-2{margin-bottom:.5rem!important}.ml-md-2,.mx-md-2{margin-left:.5rem!important}.m-md-3{margin:1rem!important}.mt-md-3,.my-md-3{margin-top:1rem!important}.mr-md-3,.mx-md-3{margin-right:1rem!important}.mb-md-3,.my-md-3{margin-bottom:1rem!important}.ml-md-3,.mx-md-3{margin-left:1rem!important}.m-md-4{margin:1.5rem!important}.mt-md-4,.my-md-4{margin-top:1.5rem!important}.mr-md-4,.mx-md-4{margin-right:1.5rem!important}.mb-md-4,.my-md-4{margin-bottom:1.5rem!important}.ml-md-4,.mx-md-4{margin-left:1.5rem!important}.m-md-5{margin:3rem!important}.mt-md-5,.my-md-5{margin-top:3rem!important}.mr-md-5,.mx-md-5{margin-right:3rem!important}.mb-md-5,.my-md-5{margin-bottom:3rem!important}.ml-md-5,.mx-md-5{margin-left:3rem!important}.p-md-0{padding:0!important}.pt-md-0,.py-md-0{padding-top:0!important}.pr-md-0,.px-md-0{padding-right:0!important}.pb-md-0,.py-md-0{padding-bottom:0!important}.pl-md-0,.px-md-0{padding-left:0!important}.p-md-1{padding:.25rem!important}.pt-md-1,.py-md-1{padding-top:.25rem!important}.pr-md-1,.px-md-1{padding-right:.25rem!important}.pb-md-1,.py-md-1{padding-bottom:.25rem!important}.pl-md-1,.px-md-1{padding-left:.25rem!important}.p-md-2{padding:.5rem!important}.pt-md-2,.py-md-2{padding-top:.5rem!important}.pr-md-2,.px-md-2{padding-right:.5rem!important}.pb-md-2,.py-md-2{padding-bottom:.5rem!important}.pl-md-2,.px-md-2{padding-left:.5rem!important}.p-md-3{padding:1rem!important}.pt-md-3,.py-md-3{padding-top:1rem!important}.pr-md-3,.px-md-3{padding-right:1rem!important}.pb-md-3,.py-md-3{padding-bottom:1rem!important}.pl-md-3,.px-md-3{padding-left:1rem!important}.p-md-4{padding:1.5rem!important}.pt-md-4,.py-md-4{padding-top:1.5rem!important}.pr-md-4,.px-md-4{padding-right:1.5rem!important}.pb-md-4,.py-md-4{padding-bottom:1.5rem!important}.pl-md-4,.px-md-4{padding-left:1.5rem!important}.p-md-5{padding:3rem!important}.pt-md-5,.py-md-5{padding-top:3rem!important}.pr-md-5,.px-md-5{padding-right:3rem!important}.pb-md-5,.py-md-5{padding-bottom:3rem!important}.pl-md-5,.px-md-5{padding-left:3rem!important}.m-md-auto{margin:auto!important}.mt-md-auto,.my-md-auto{margin-top:auto!important}.mr-md-auto,.mx-md-auto{margin-right:auto!important}.mb-md-auto,.my-md-auto{margin-bottom:auto!important}.ml-md-auto,.mx-md-auto{margin-left:auto!important}}@media (min-width:992px){.m-lg-0{margin:0!important}.mt-lg-0,.my-lg-0{margin-top:0!important}.mr-lg-0,.mx-lg-0{margin-right:0!important}.mb-lg-0,.my-lg-0{margin-bottom:0!important}.ml-lg-0,.mx-lg-0{margin-left:0!important}.m-lg-1{margin:.25rem!important}.mt-lg-1,.my-lg-1{margin-top:.25rem!important}.mr-lg-1,.mx-lg-1{margin-right:.25rem!important}.mb-lg-1,.my-lg-1{margin-bottom:.25rem!important}.ml-lg-1,.mx-lg-1{margin-left:.25rem!important}.m-lg-2{margin:.5rem!important}.mt-lg-2,.my-lg-2{margin-top:.5rem!important}.mr-lg-2,.mx-lg-2{margin-right:.5rem!important}.mb-lg-2,.my-lg-2{margin-bottom:.5rem!important}.ml-lg-2,.mx-lg-2{margin-left:.5rem!important}.m-lg-3{margin:1rem!important}.mt-lg-3,.my-lg-3{margin-top:1rem!important}.mr-lg-3,.mx-lg-3{margin-right:1rem!important}.mb-lg-3,.my-lg-3{margin-bottom:1rem!important}.ml-lg-3,.mx-lg-3{margin-left:1rem!important}.m-lg-4{margin:1.5rem!important}.mt-lg-4,.my-lg-4{margin-top:1.5rem!important}.mr-lg-4,.mx-lg-4{margin-right:1.5rem!important}.mb-lg-4,.my-lg-4{margin-bottom:1.5rem!important}.ml-lg-4,.mx-lg-4{margin-left:1.5rem!important}.m-lg-5{margin:3rem!important}.mt-lg-5,.my-lg-5{margin-top:3rem!important}.mr-lg-5,.mx-lg-5{margin-right:3rem!important}.mb-lg-5,.my-lg-5{margin-bottom:3rem!important}.ml-lg-5,.mx-lg-5{margin-left:3rem!important}.p-lg-0{padding:0!important}.pt-lg-0,.py-lg-0{padding-top:0!important}.pr-lg-0,.px-lg-0{padding-right:0!important}.pb-lg-0,.py-lg-0{padding-bottom:0!important}.pl-lg-0,.px-lg-0{padding-left:0!important}.p-lg-1{padding:.25rem!important}.pt-lg-1,.py-lg-1{padding-top:.25rem!important}.pr-lg-1,.px-lg-1{padding-right:.25rem!important}.pb-lg-1,.py-lg-1{padding-bottom:.25rem!important}.pl-lg-1,.px-lg-1{padding-left:.25rem!important}.p-lg-2{padding:.5rem!important}.pt-lg-2,.py-lg-2{padding-top:.5rem!important}.pr-lg-2,.px-lg-2{padding-right:.5rem!important}.pb-lg-2,.py-lg-2{padding-bottom:.5rem!important}.pl-lg-2,.px-lg-2{padding-left:.5rem!important}.p-lg-3{padding:1rem!important}.pt-lg-3,.py-lg-3{padding-top:1rem!important}.pr-lg-3,.px-lg-3{padding-right:1rem!important}.pb-lg-3,.py-lg-3{padding-bottom:1rem!important}.pl-lg-3,.px-lg-3{padding-left:1rem!important}.p-lg-4{padding:1.5rem!important}.pt-lg-4,.py-lg-4{padding-top:1.5rem!important}.pr-lg-4,.px-lg-4{padding-right:1.5rem!important}.pb-lg-4,.py-lg-4{padding-bottom:1.5rem!important}.pl-lg-4,.px-lg-4{padding-left:1.5rem!important}.p-lg-5{padding:3rem!important}.pt-lg-5,.py-lg-5{padding-top:3rem!important}.pr-lg-5,.px-lg-5{padding-right:3rem!important}.pb-lg-5,.py-lg-5{padding-bottom:3rem!important}.pl-lg-5,.px-lg-5{padding-left:3rem!important}.m-lg-auto{margin:auto!important}.mt-lg-auto,.my-lg-auto{margin-top:auto!important}.mr-lg-auto,.mx-lg-auto{margin-right:auto!important}.mb-lg-auto,.my-lg-auto{margin-bottom:auto!important}.ml-lg-auto,.mx-lg-auto{margin-left:auto!important}}@media (min-width:1200px){.m-xl-0{margin:0!important}.mt-xl-0,.my-xl-0{margin-top:0!important}.mr-xl-0,.mx-xl-0{margin-right:0!important}.mb-xl-0,.my-xl-0{margin-bottom:0!important}.ml-xl-0,.mx-xl-0{margin-left:0!important}.m-xl-1{margin:.25rem!important}.mt-xl-1,.my-xl-1{margin-top:.25rem!important}.mr-xl-1,.mx-xl-1{margin-right:.25rem!important}.mb-xl-1,.my-xl-1{margin-bottom:.25rem!important}.ml-xl-1,.mx-xl-1{margin-left:.25rem!important}.m-xl-2{margin:.5rem!important}.mt-xl-2,.my-xl-2{margin-top:.5rem!important}.mr-xl-2,.mx-xl-2{margin-right:.5rem!important}.mb-xl-2,.my-xl-2{margin-bottom:.5rem!important}.ml-xl-2,.mx-xl-2{margin-left:.5rem!important}.m-xl-3{margin:1rem!important}.mt-xl-3,.my-xl-3{margin-top:1rem!important}.mr-xl-3,.mx-xl-3{margin-right:1rem!important}.mb-xl-3,.my-xl-3{margin-bottom:1rem!important}.ml-xl-3,.mx-xl-3{margin-left:1rem!important}.m-xl-4{margin:1.5rem!important}.mt-xl-4,.my-xl-4{margin-top:1.5rem!important}.mr-xl-4,.mx-xl-4{margin-right:1.5rem!important}.mb-xl-4,.my-xl-4{margin-bottom:1.5rem!important}.ml-xl-4,.mx-xl-4{margin-left:1.5rem!important}.m-xl-5{margin:3rem!important}.mt-xl-5,.my-xl-5{margin-top:3rem!important}.mr-xl-5,.mx-xl-5{margin-right:3rem!important}.mb-xl-5,.my-xl-5{margin-bottom:3rem!important}.ml-xl-5,.mx-xl-5{margin-left:3rem!important}.p-xl-0{padding:0!important}.pt-xl-0,.py-xl-0{padding-top:0!important}.pr-xl-0,.px-xl-0{padding-right:0!important}.pb-xl-0,.py-xl-0{padding-bottom:0!important}.pl-xl-0,.px-xl-0{padding-left:0!important}.p-xl-1{padding:.25rem!important}.pt-xl-1,.py-xl-1{padding-top:.25rem!important}.pr-xl-1,.px-xl-1{padding-right:.25rem!important}.pb-xl-1,.py-xl-1{padding-bottom:.25rem!important}.pl-xl-1,.px-xl-1{padding-left:.25rem!important}.p-xl-2{padding:.5rem!important}.pt-xl-2,.py-xl-2{padding-top:.5rem!important}.pr-xl-2,.px-xl-2{padding-right:.5rem!important}.pb-xl-2,.py-xl-2{padding-bottom:.5rem!important}.pl-xl-2,.px-xl-2{padding-left:.5rem!important}.p-xl-3{padding:1rem!important}.pt-xl-3,.py-xl-3{padding-top:1rem!important}.pr-xl-3,.px-xl-3{padding-right:1rem!important}.pb-xl-3,.py-xl-3{padding-bottom:1rem!important}.pl-xl-3,.px-xl-3{padding-left:1rem!important}.p-xl-4{padding:1.5rem!important}.pt-xl-4,.py-xl-4{padding-top:1.5rem!important}.pr-xl-4,.px-xl-4{padding-right:1.5rem!important}.pb-xl-4,.py-xl-4{padding-bottom:1.5rem!important}.pl-xl-4,.px-xl-4{padding-left:1.5rem!important}.p-xl-5{padding:3rem!important}.pt-xl-5,.py-xl-5{padding-top:3rem!important}.pr-xl-5,.px-xl-5{padding-right:3rem!important}.pb-xl-5,.py-xl-5{padding-bottom:3rem!important}.pl-xl-5,.px-xl-5{padding-left:3rem!important}.m-xl-auto{margin:auto!important}.mt-xl-auto,.my-xl-auto{margin-top:auto!important}.mr-xl-auto,.mx-xl-auto{margin-right:auto!important}.mb-xl-auto,.my-xl-auto{margin-bottom:auto!important}.ml-xl-auto,.mx-xl-auto{margin-left:auto!important}}.text-monospace{font-family:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace}.text-justify{text-align:justify!important}.text-nowrap{white-space:nowrap!important}.text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.text-left{text-align:left!important}.text-right{text-align:right!important}.text-center{text-align:center!important}@media (min-width:576px){.text-sm-left{text-align:left!important}.text-sm-right{text-align:right!important}.text-sm-center{text-align:center!important}}@media (min-width:768px){.text-md-left{text-align:left!important}.text-md-right{text-align:right!important}.text-md-center{text-align:center!important}}@media (min-width:992px){.text-lg-left{text-align:left!important}.text-lg-right{text-align:right!important}.text-lg-center{text-align:center!important}}@media (min-width:1200px){.text-xl-left{text-align:left!important}.text-xl-right{text-align:right!important}.text-xl-center{text-align:center!important}}.text-lowercase{text-transform:lowercase!important}.text-uppercase{text-transform:uppercase!important}.text-capitalize{text-transform:capitalize!important}.font-weight-light{font-weight:300!important}.font-weight-normal{font-weight:400!important}.font-weight-bold{font-weight:700!important}.font-italic{font-style:italic!important}.text-white{color:#fff!important}.text-primary{color:#007bff!important}a.text-primary:focus,a.text-primary:hover{color:#0062cc!important}.text-secondary{color:#6c757d!important}a.text-secondary:focus,a.text-secondary:hover{color:#545b62!important}.text-success{color:#28a745!important}a.text-success:focus,a.text-success:hover{color:#1e7e34!important}.text-info{color:#17a2b8!important}a.text-info:focus,a.text-info:hover{color:#117a8b!important}.text-warning{color:#ffc107!important}a.text-warning:focus,a.text-warning:hover{color:#d39e00!important}.text-danger{color:#dc3545!important}a.text-danger:focus,a.text-danger:hover{color:#bd2130!important}.text-light{color:#f8f9fa!important}a.text-light:focus,a.text-light:hover{color:#dae0e5!important}.text-dark{color:#343a40!important}a.text-dark:focus,a.text-dark:hover{color:#1d2124!important}.text-body{color:#212529!important}.text-muted{color:#6c757d!important}.text-black-50{color:rgba(0,0,0,.5)!important}.text-white-50{color:rgba(255,255,255,.5)!important}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.visible{visibility:visible!important}.invisible{visibility:hidden!important}@media print{*,::after,::before{text-shadow:none!important;box-shadow:none!important}a:not(.btn){text-decoration:underline}abbr[title]::after{content:" (" attr(title) ")"}pre{white-space:pre-wrap!important}blockquote,pre{border:1px solid #adb5bd;page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}h2,h3,p{orphans:3;widows:3}h2,h3{page-break-after:avoid}@page{size:a3}body{min-width:992px!important}.container{min-width:992px!important}.navbar{display:none}.badge{border:1px solid #000}.table{border-collapse:collapse!important}.table td,.table th{background-color:#fff!important}.table-bordered td,.table-bordered th{border:1px solid #dee2e6!important}.table-dark{color:inherit}.table-dark tbody+tbody,.table-dark td,.table-dark th,.table-dark thead th{border-color:#dee2e6}.table .thead-dark th{color:inherit;border-color:#dee2e6}} -/*# sourceMappingURL=bootstrap.min.css.map */ \ No newline at end of file diff --git a/2.0/documentation/tdenginedocs-en/lib/docs/docs.css b/2.0/documentation/tdenginedocs-en/lib/docs/docs.css deleted file mode 100644 index bfb6f808e6..0000000000 --- a/2.0/documentation/tdenginedocs-en/lib/docs/docs.css +++ /dev/null @@ -1,269 +0,0 @@ -.documentation strong { - font-weight:600; -} -.documentation { - overflow:hidden; - margin-bottom: 10rem; -} -.documentation a { - font-size:1em; - text-decoration: none; -} -.documentation > a > h2 { - cursor:pointer; - color:var(--sg1); - -} -.documentation > a >h2:hover { - color:var(--b2); -} -.documentation a:hover { - text-decoration: none; -} -.documentation pre { - margin-top: 0; -margin-bottom: 7px; -overflow: auto; --ms-overflow-style: scrollbar; -margin-top: 7px; -} -pre * { - font-family:monospace !important -} -.documentation a { - color:var(--b2); - padding-bottom: 2px; - position: relative; - font-style: normal; - cursor: pointer; -} -.documentation a:hover,a:focus { - text-decoration: none; - color:var(--b2); -} -.documentation a::before { - content: ""; - left: 0; - background-color: var(--b2); - width: 0%; - height: 1px; - top:-webkit-calc(1em + 8px); - top:calc(1em + 8px); - position: absolute; - z-index: 2; - -webkit-transition: background-color 0.2s, height 0.2s, top 0.2s, width 0.2s; - -o-transition: background-color 0.2s, height 0.2s, top 0.2s, width 0.2s; - transition: background-color 0.2s, height 0.2s, top 0.2s, width 0.2s;; -} -.documentation a:hover::before, .documentation a:focus::before { - content: ""; - left: 0; - background-color: var(--b2); - width: 100%; - height: 1px; - top:-webkit-calc(1em + 8px); - top:calc(1em + 8px); - position: absolute; - z-index: 2; - -webkit-transition: background-color 0.2s, height 0.2s, top 0.2s, width 0.2s; - -o-transition: background-color 0.2s, height 0.2s, top 0.2s, width 0.2s; - transition: background-color 0.2s, height 0.2s, top 0.2s, width 0.2s; - text-decoration: none; -} -.documentation img { - width:100%; - max-width:640px; - margin-left: 50%; - -webkit-transform: translate(-50%,0); - -ms-transform: translate(-50%,0); - transform: translate(-50%,0); - -} -h1, -h2, -h3, -h4, -h5, -h6 { - position: relative; - margin-bottom: 0.5rem; - font-weight: 500; - line-height: 1.4; - cursor: text; -} -h1:hover a.anchor, -h2:hover a.anchor, -h3:hover a.anchor, -h4:hover a.anchor, -h5:hover a.anchor, -h6:hover a.anchor { - text-decoration: none; -} -h1 tt, -h1 code { - font-size: inherit; -} -h2 tt, -h2 code { - font-size: inherit; -} -h3 tt, -h3 code { - font-size: inherit; -} -h4 tt, -h4 code { - font-size: inherit; -} -h5 tt, -h5 code { - font-size: inherit; -} -h6 tt, -h6 code { - font-size: inherit; -} -h1 { - font-size: 2.5rem; - line-height: 1.8; -} -h2 { - font-size: 1.7rem; - line-height: 1.8; - padding-left: 0.5em; -} -.documentation h2::before { - content:""; - height:1em;; - display: block; - width:3px; - margin-left: -0.5em; - margin-top: 0.4em; - position: absolute; - background-color: var(--b1); -} -h3 { - font-size: 1.4rem; - line-height: 1.43; -} -h4 { - font-size: 1.25rem; -} -h5 { - font-size: 1rem; -} -h6 { - font-size: 1rem; - color: #777; -} -p { - margin-bottom:0.5rem; - font-size:1em; - margin-top:0; - font-weight:300; -} -ol,ul,dl { - margin-top:0; - margin-bottom: 1rem; -} -li p { - margin-bottom: 0; -} -blockquote, -table{ - margin: 0.8em 0; - width:100%; -} -figure table{ - overflow: scroll; -} -hr { - height: 2px; - padding: 0; - margin: 16px 0; - background-color: #e7e7e7; - border: 0 none; - overflow: hidden; - -webkit-box-sizing: content-box; - box-sizing: content-box; -} - -li p.first { - display: inline-block; -} -ul, -ol { - padding-left: 30px; -} -ul:first-child, -ol:first-child { - margin-top: 0; -} -ul:last-child, -ol:last-child { - margin-bottom: 0; -} -blockquote { - border-left: 4px solid #dfe2e5; - padding: 0 15px; - color: #777777; -} -blockquote blockquote { - padding-right: 0; -} -table { - padding: 0; - word-break: initial; -} -table tr { - border-top: 1px solid #dfe2e5; - margin: 0; - padding: 0; -} -table tr:nth-child(2n), -thead { - background-color: #f8f8f8; -} -table tr th { - font-weight: bold; - border: 1px solid #dfe2e5; - border-bottom: 0; - text-align: left; - margin: 0; - padding: 6px 13px; -} -table tr td { - border: 1px solid #dfe2e5; - text-align: left; - margin: 0; - padding: 6px 13px; -} -table tr th:first-child, -table tr td:first-child { - margin-top: 0; -} -table tr th:last-child, -table tr td:last-child { - margin-bottom: 0; -} -h1 code,h2 code, h3 code, h4 code, h5 code, h6 code, -p code, li code, td code, -tt { - border: 1px solid #e7eaed; - background-color: #f8f8f8; - -webkit-border-radius: 3px; - border-radius: 3px; - padding: 0; - font-size: 0.9em; - color:var(--sg1); - font-family:monospace; - background-color: #f3f4f4; - padding: 0 2px 0 2px; -} -/*Tell prettyprinted code not to follow above*/ -.prettyprint code{ - border:none; - background-color:transparent; - font-size:inherit; - padding:0 1px 0 0px; -} \ No newline at end of file diff --git a/2.0/documentation/tdenginedocs-en/lib/docs/liner.js b/2.0/documentation/tdenginedocs-en/lib/docs/liner.js deleted file mode 100644 index 9cfeb88e10..0000000000 --- a/2.0/documentation/tdenginedocs-en/lib/docs/liner.js +++ /dev/null @@ -1,19 +0,0 @@ -/*JS to determine how many lines used in pre/code block, sets CSS appropriately. MUST be placed after elements with prettyprint class are loaded*/ -$('.prettyprint').toArray().forEach(function(element){ - let linenums = element.clientHeight / 25.2; - if (linenums > 99) { - $(element).addClass('threec'); - } - else if (linenums > 9) { - $(element).addClass('twoc'); - } - }); -$('.prettyprint').toArray().forEach(function(element){ - let linenums = element.clientHeight / 25.2; - if (linenums > 99) { - $(element).addClass('threec'); - } - else if (linenums > 9) { - $(element).addClass('twoc'); - } -}); \ No newline at end of file diff --git a/2.0/documentation/tdenginedocs-en/lib/docs/prettify.js b/2.0/documentation/tdenginedocs-en/lib/docs/prettify.js deleted file mode 100644 index d2acd5d9d4..0000000000 --- a/2.0/documentation/tdenginedocs-en/lib/docs/prettify.js +++ /dev/null @@ -1,46 +0,0 @@ -!function(){/* - - Copyright (C) 2006 Google Inc. - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ -"undefined"!==typeof window&&(window.PR_SHOULD_USE_CONTINUATION=!0); -(function(){function T(a){function d(e){var a=e.charCodeAt(0);if(92!==a)return a;var c=e.charAt(1);return(a=w[c])?a:"0"<=c&&"7">=c?parseInt(e.substring(1),8):"u"===c||"x"===c?parseInt(e.substring(2),16):e.charCodeAt(1)}function f(e){if(32>e)return(16>e?"\\x0":"\\x")+e.toString(16);e=String.fromCharCode(e);return"\\"===e||"-"===e||"]"===e||"^"===e?"\\"+e:e}function c(e){var c=e.substring(1,e.length-1).match(RegExp("\\\\u[0-9A-Fa-f]{4}|\\\\x[0-9A-Fa-f]{2}|\\\\[0-3][0-7]{0,2}|\\\\[0-7]{1,2}|\\\\[\\s\\S]|-|[^-\\\\]","g")); -e=[];var a="^"===c[0],b=["["];a&&b.push("^");for(var a=a?1:0,g=c.length;ak||122k||90k||122h[0]&&(h[1]+1>h[0]&&b.push("-"),b.push(f(h[1])));b.push("]");return b.join("")}function m(e){for(var a=e.source.match(RegExp("(?:\\[(?:[^\\x5C\\x5D]|\\\\[\\s\\S])*\\]|\\\\u[A-Fa-f0-9]{4}|\\\\x[A-Fa-f0-9]{2}|\\\\[0-9]+|\\\\[^ux0-9]|\\(\\?[:!=]|[\\(\\)\\^]|[^\\x5B\\x5C\\(\\)\\^]+)","g")),b=a.length,d=[],g=0,h=0;g/,null])):d.push(["com",/^#[^\r\n]*/,null,"#"]));a.cStyleComments&&(f.push(["com",/^\/\/[^\r\n]*/,null]),f.push(["com",/^\/\*[\s\S]*?(?:\*\/|$)/,null]));if(c=a.regexLiterals){var m=(c=1|\\/=?|::?|<>?>?=?|,|;|\\?|@|\\[|~|{|\\^\\^?=?|\\|\\|?=?|break|case|continue|delete|do|else|finally|instanceof|return|throw|try|typeof)\\s*("+ -("/(?=[^/*"+c+"])(?:[^/\\x5B\\x5C"+c+"]|\\x5C"+m+"|\\x5B(?:[^\\x5C\\x5D"+c+"]|\\x5C"+m+")*(?:\\x5D|$))+/")+")")])}(c=a.types)&&f.push(["typ",c]);c=(""+a.keywords).replace(/^ | $/g,"");c.length&&f.push(["kwd",new RegExp("^(?:"+c.replace(/[\s,]+/g,"|")+")\\b"),null]);d.push(["pln",/^\s+/,null," \r\n\t\u00a0"]);c="^.[^\\s\\w.$@'\"`/\\\\]*";a.regexLiterals&&(c+="(?!s*/)");f.push(["lit",/^@[a-z_$][a-z_$@0-9]*/i,null],["typ",/^(?:[@_]?[A-Z]+[a-z][A-Za-z_$@0-9]*|\w+_t\b)/,null],["pln",/^[a-z_$][a-z_$@0-9]*/i, -null],["lit",/^(?:0x[a-f0-9]+|(?:\d(?:_\d+)*\d*(?:\.\d*)?|\.\d\+)(?:e[+\-]?\d+)?)[a-z]*/i,null,"0123456789"],["pln",/^\\[\s\S]?/,null],["pun",new RegExp(c),null]);return G(d,f)}function L(a,d,f){function c(a){var b=a.nodeType;if(1==b&&!t.test(a.className))if("br"===a.nodeName.toLowerCase())m(a),a.parentNode&&a.parentNode.removeChild(a);else for(a=a.firstChild;a;a=a.nextSibling)c(a);else if((3==b||4==b)&&f){var e=a.nodeValue,d=e.match(q);d&&(b=e.substring(0,d.index),a.nodeValue=b,(e=e.substring(d.index+ -d[0].length))&&a.parentNode.insertBefore(l.createTextNode(e),a.nextSibling),m(a),b||a.parentNode.removeChild(a))}}function m(a){function c(a,b){var e=b?a.cloneNode(!1):a,k=a.parentNode;if(k){var k=c(k,1),d=a.nextSibling;k.appendChild(e);for(var f=d;f;f=d)d=f.nextSibling,k.appendChild(f)}return e}for(;!a.nextSibling;)if(a=a.parentNode,!a)return;a=c(a.nextSibling,0);for(var e;(e=a.parentNode)&&1===e.nodeType;)a=e;b.push(a)}for(var t=/(?:^|\s)nocode(?:\s|$)/,q=/\r\n?|\n/,l=a.ownerDocument,n=l.createElement("li");a.firstChild;)n.appendChild(a.firstChild); -for(var b=[n],p=0;p=+m[1],d=/\n/g,t=a.a,q=t.length,f=0,l=a.c,n=l.length,c=0,b=a.g,p=b.length,w=0;b[p]=q;var r,e;for(e=r=0;e=h&&(c+=2);f>=k&&(w+=2)}}finally{g&&(g.style.display=a)}}catch(y){D.console&&console.log(y&&y.stack||y)}}var D="undefined"!==typeof window? -window:{},B=["break,continue,do,else,for,if,return,while"],F=[[B,"auto,case,char,const,default,double,enum,extern,float,goto,inline,int,long,register,restrict,short,signed,sizeof,static,struct,switch,typedef,union,unsigned,void,volatile"],"catch,class,delete,false,import,new,operator,private,protected,public,this,throw,true,try,typeof"],H=[F,"alignas,alignof,align_union,asm,axiom,bool,concept,concept_map,const_cast,constexpr,decltype,delegate,dynamic_cast,explicit,export,friend,generic,late_check,mutable,namespace,noexcept,noreturn,nullptr,property,reinterpret_cast,static_assert,static_cast,template,typeid,typename,using,virtual,where"], -O=[F,"abstract,assert,boolean,byte,extends,finally,final,implements,import,instanceof,interface,null,native,package,strictfp,super,synchronized,throws,transient"],P=[F,"abstract,add,alias,as,ascending,async,await,base,bool,by,byte,checked,decimal,delegate,descending,dynamic,event,finally,fixed,foreach,from,get,global,group,implicit,in,interface,internal,into,is,join,let,lock,null,object,out,override,orderby,params,partial,readonly,ref,remove,sbyte,sealed,select,set,stackalloc,string,select,uint,ulong,unchecked,unsafe,ushort,value,var,virtual,where,yield"], -F=[F,"abstract,async,await,constructor,debugger,enum,eval,export,from,function,get,import,implements,instanceof,interface,let,null,of,set,undefined,var,with,yield,Infinity,NaN"],Q=[B,"and,as,assert,class,def,del,elif,except,exec,finally,from,global,import,in,is,lambda,nonlocal,not,or,pass,print,raise,try,with,yield,False,True,None"],R=[B,"alias,and,begin,case,class,def,defined,elsif,end,ensure,false,in,module,next,nil,not,or,redo,rescue,retry,self,super,then,true,undef,unless,until,when,yield,BEGIN,END"], -B=[B,"case,done,elif,esac,eval,fi,function,in,local,set,then,until"],S=/^(DIR|FILE|array|vector|(de|priority_)?queue|(forward_)?list|stack|(const_)?(reverse_)?iterator|(unordered_)?(multi)?(set|map)|bitset|u?(int|float)\d*)\b/,W=/\S/,X=x({keywords:[H,P,O,F,"caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END",Q,R,B],hashComments:!0,cStyleComments:!0,multiLineStrings:!0,regexLiterals:!0}), -I={};t(X,["default-code"]);t(G([],[["pln",/^[^]*(?:>|$)/],["com",/^<\!--[\s\S]*?(?:-\->|$)/],["lang-",/^<\?([\s\S]+?)(?:\?>|$)/],["lang-",/^<%([\s\S]+?)(?:%>|$)/],["pun",/^(?:<[%?]|[%?]>)/],["lang-",/^]*>([\s\S]+?)<\/xmp\b[^>]*>/i],["lang-js",/^]*>([\s\S]*?)(<\/script\b[^>]*>)/i],["lang-css",/^]*>([\s\S]*?)(<\/style\b[^>]*>)/i],["lang-in.tag",/^(<\/?[a-z][^<>]*>)/i]]),"default-markup htm html mxml xhtml xml xsl".split(" "));t(G([["pln",/^[\s]+/, -null," \t\r\n"],["atv",/^(?:\"[^\"]*\"?|\'[^\']*\'?)/,null,"\"'"]],[["tag",/^^<\/?[a-z](?:[\w.:-]*\w)?|\/?>$/i],["atn",/^(?!style[\s=]|on)[a-z](?:[\w:-]*\w)?/i],["lang-uq.val",/^=\s*([^>\'\"\s]*(?:[^>\'\"\s\/]|\/(?=\s)))/],["pun",/^[=<>\/]+/],["lang-js",/^on\w+\s*=\s*\"([^\"]+)\"/i],["lang-js",/^on\w+\s*=\s*\'([^\']+)\'/i],["lang-js",/^on\w+\s*=\s*([^\"\'>\s]+)/i],["lang-css",/^style\s*=\s*\"([^\"]+)\"/i],["lang-css",/^style\s*=\s*\'([^\']+)\'/i],["lang-css",/^style\s*=\s*([^\"\'>\s]+)/i]]),["in.tag"]); -t(G([],[["atv",/^[\s\S]+/]]),["uq.val"]);t(x({keywords:H,hashComments:!0,cStyleComments:!0,types:S}),"c cc cpp cxx cyc m".split(" "));t(x({keywords:"null,true,false"}),["json"]);t(x({keywords:P,hashComments:!0,cStyleComments:!0,verbatimStrings:!0,types:S}),["cs"]);t(x({keywords:O,cStyleComments:!0}),["java"]);t(x({keywords:B,hashComments:!0,multiLineStrings:!0}),["bash","bsh","csh","sh"]);t(x({keywords:Q,hashComments:!0,multiLineStrings:!0,tripleQuotedStrings:!0}),["cv","py","python"]);t(x({keywords:"caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END", -hashComments:!0,multiLineStrings:!0,regexLiterals:2}),["perl","pl","pm"]);t(x({keywords:R,hashComments:!0,multiLineStrings:!0,regexLiterals:!0}),["rb","ruby"]);t(x({keywords:F,cStyleComments:!0,regexLiterals:!0}),["javascript","js","ts","typescript"]);t(x({keywords:"all,and,by,catch,class,else,extends,false,finally,for,if,in,is,isnt,loop,new,no,not,null,of,off,on,or,return,super,then,throw,true,try,unless,until,when,while,yes",hashComments:3,cStyleComments:!0,multilineStrings:!0,tripleQuotedStrings:!0, -regexLiterals:!0}),["coffee"]);t(G([],[["str",/^[\s\S]+/]]),["regex"]);var Y=D.PR={createSimpleLexer:G,registerLangHandler:t,sourceDecorator:x,PR_ATTRIB_NAME:"atn",PR_ATTRIB_VALUE:"atv",PR_COMMENT:"com",PR_DECLARATION:"dec",PR_KEYWORD:"kwd",PR_LITERAL:"lit",PR_NOCODE:"nocode",PR_PLAIN:"pln",PR_PUNCTUATION:"pun",PR_SOURCE:"src",PR_STRING:"str",PR_TAG:"tag",PR_TYPE:"typ",TAOSDATA_FUNCTION:"td-fun",TAOSDATA_DATATYPE:"td-dtp",TAOSDATA_TERMINAL:"tem",TAOSDATA_OPTION:"td-opt",prettyPrintOne:D.prettyPrintOne=function(a,d,f){f=f||!1;d=d||null;var c=document.createElement("div");c.innerHTML="
      "+a+"
      "; -c=c.firstChild;f&&L(c,f,!0);M({j:d,m:f,h:c,l:1,a:null,i:null,c:null,g:null});return c.innerHTML},prettyPrint:D.prettyPrint=function(a,d){function f(){for(var c=D.PR_SHOULD_USE_CONTINUATION?b.now()+250:Infinity;p li { - counter-increment: customlistcounter; -} -pre.prettyprint ol > li:first-child:before { - border-top-left-radius: 0.25rem; -} -pre.prettyprint ol > li:last-child:before { - border-bottom-left-radius: 0.25rem; -} -pre.prettyprint ol > li:before { - content: counter(customlistcounter) " "; - font-weight: 300; - display: inline-block; - position: absolute; - transform:translateX(-38px); - width: 27px; - text-align: right; - background-color:var(--white); - padding-bottom: 0.1px; -} -pre.prettyprint ol > li:nth-last-child(1)::before { - padding-bottom: 0px !important; -} - -pre.prettyprint.twoc ol > li:before { - transform:translateX(-45px); - width:34px; -} -pre.prettyprint.twoc { - padding-left:35px; -} -pre.prettyprint.threec ol > li:before { - transform:translateX(-53px); - width:42px; -} -pre.prettyprint.threec { - padding-left:43px; -} - -ol:first-child { - counter-reset: customlistcounter; -} -pre.prettyprint ol { - padding-right: 4px; -} -pre .atn, -pre .kwd, -pre .tag { - font-weight: 400 -} -pre * { - font-family:monospace; -} -pre.prettyprint li { - background-color:rgb(244,245,246); -} -pre.prettyprint { - display: block; - background-color:rgb(244,245,246); - border-radius:0.25rem; - padding-left: 27px; - /*each additional digit needs 8px*/ - width:100%; - border:1px solid #e7eaed; - color:#d58936; -} -/* TAOSDATA Specific */ -pre.lang-blank span { - color:var(--sg1); -} -pre.lang-blank { - -} -pre.lang-term span{ - color: var(--white) ; -} -pre.lang-term ol { - background-color: var(--sg1); -} -pre.lang-term ol.linenums { - border-left:1px solid var(--sg1); -} -pre.lang-term li { - background-color:var(--sg1); -} -/*Functions*/ -pre .td-fun { - color:#f24352; -} -/*Options*/ -pre .td-opt { - /*color:mediumpurple;*/ - color:#5882bc; -} -/*Datatypes*/ -pre .td-dtp { - color:darkcyan; -} -pre .nocode { - background-color: var(--white); - color: var(--sg1); -} -/*Strings*/ -pre .str { - color: #690; -} -/*Keywords*/ -pre .kwd { - color: #5882bc; -} -/*Comments*/ -pre .com { - color: slategray; -} -/*Type*/ -pre .typ { - color: #9c5fc6; -} -/*Literals*/ -pre .lit { - color: #91001f; -} -/*Plain Text*/ -pre .pln { - color: #d58936; -} -/*Punctuation*/ -pre .pun { - color: rgb(51,66,78); -} -pre .tag { - color: khaki -} - -pre .atn { - color: #bdb76b -} - -pre .atv { - color: #ffa0a0 -} - -pre .dec { - color: #98fb98 -} - -ol.linenums { - margin-top: 0; - margin-bottom: 0; - color: #AEAEAE; - border-left:1px solid var(--b1); - padding-left: 0px; -} -pre li { - padding-left: 0.6rem; -} -li.L0, -li.L1, -li.L2, -li.L3, -li.L5, -li.L6, -li.L7, -li.L8 { - list-style-type: none -} - -@media print { - pre.prettyprint { - background-color: none - } - - code .str, - pre .str { - color: #690; - } - - code .kwd, - pre .kwd { - color: #5882bc; - font-weight: 400 - } - - code .com, - pre .com { - color: #600; - font-style: italic - } - - code .typ, - pre .typ { - color: #404; - font-weight: 400 - } - - code .lit, - pre .lit { - color: #044 - } - - code .pun, - pre .pun { - color: #440 - } - - code .pln, - pre .pln { - color: #000 - } - - code .tag, - pre .tag { - color: #006; - font-weight: 400 - } - - code .atn, - pre .atn { - color: #404 - } - - code .atv, - pre .atv { - color: #060 - } -} \ No newline at end of file diff --git a/2.0/documentation/tdenginedocs-en/lib/jquery-3.4.1.min.js b/2.0/documentation/tdenginedocs-en/lib/jquery-3.4.1.min.js deleted file mode 100644 index a1c07fd803..0000000000 --- a/2.0/documentation/tdenginedocs-en/lib/jquery-3.4.1.min.js +++ /dev/null @@ -1,2 +0,0 @@ -/*! jQuery v3.4.1 | (c) JS Foundation and other contributors | jquery.org/license */ -!function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0):function(e){if(!e.document)throw new Error("jQuery requires a window with a document");return t(e)}:t(e)}("undefined"!=typeof window?window:this,function(C,e){"use strict";var t=[],E=C.document,r=Object.getPrototypeOf,s=t.slice,g=t.concat,u=t.push,i=t.indexOf,n={},o=n.toString,v=n.hasOwnProperty,a=v.toString,l=a.call(Object),y={},m=function(e){return"function"==typeof e&&"number"!=typeof e.nodeType},x=function(e){return null!=e&&e===e.window},c={type:!0,src:!0,nonce:!0,noModule:!0};function b(e,t,n){var r,i,o=(n=n||E).createElement("script");if(o.text=e,t)for(r in c)(i=t[r]||t.getAttribute&&t.getAttribute(r))&&o.setAttribute(r,i);n.head.appendChild(o).parentNode.removeChild(o)}function w(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?n[o.call(e)]||"object":typeof e}var f="3.4.1",k=function(e,t){return new k.fn.init(e,t)},p=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g;function d(e){var t=!!e&&"length"in e&&e.length,n=w(e);return!m(e)&&!x(e)&&("array"===n||0===t||"number"==typeof t&&0+~]|"+M+")"+M+"*"),U=new RegExp(M+"|>"),X=new RegExp($),V=new RegExp("^"+I+"$"),G={ID:new RegExp("^#("+I+")"),CLASS:new RegExp("^\\.("+I+")"),TAG:new RegExp("^("+I+"|[*])"),ATTR:new RegExp("^"+W),PSEUDO:new RegExp("^"+$),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+M+"*(even|odd|(([+-]|)(\\d*)n|)"+M+"*(?:([+-]|)"+M+"*(\\d+)|))"+M+"*\\)|)","i"),bool:new RegExp("^(?:"+R+")$","i"),needsContext:new RegExp("^"+M+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+M+"*((?:-\\d)?\\d*)"+M+"*\\)|)(?=[^-]|$)","i")},Y=/HTML$/i,Q=/^(?:input|select|textarea|button)$/i,J=/^h\d$/i,K=/^[^{]+\{\s*\[native \w/,Z=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ee=/[+~]/,te=new RegExp("\\\\([\\da-f]{1,6}"+M+"?|("+M+")|.)","ig"),ne=function(e,t,n){var r="0x"+t-65536;return r!=r||n?t:r<0?String.fromCharCode(r+65536):String.fromCharCode(r>>10|55296,1023&r|56320)},re=/([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,ie=function(e,t){return t?"\0"===e?"\ufffd":e.slice(0,-1)+"\\"+e.charCodeAt(e.length-1).toString(16)+" ":"\\"+e},oe=function(){T()},ae=be(function(e){return!0===e.disabled&&"fieldset"===e.nodeName.toLowerCase()},{dir:"parentNode",next:"legend"});try{H.apply(t=O.call(m.childNodes),m.childNodes),t[m.childNodes.length].nodeType}catch(e){H={apply:t.length?function(e,t){L.apply(e,O.call(t))}:function(e,t){var n=e.length,r=0;while(e[n++]=t[r++]);e.length=n-1}}}function se(t,e,n,r){var i,o,a,s,u,l,c,f=e&&e.ownerDocument,p=e?e.nodeType:9;if(n=n||[],"string"!=typeof t||!t||1!==p&&9!==p&&11!==p)return n;if(!r&&((e?e.ownerDocument||e:m)!==C&&T(e),e=e||C,E)){if(11!==p&&(u=Z.exec(t)))if(i=u[1]){if(9===p){if(!(a=e.getElementById(i)))return n;if(a.id===i)return n.push(a),n}else if(f&&(a=f.getElementById(i))&&y(e,a)&&a.id===i)return n.push(a),n}else{if(u[2])return H.apply(n,e.getElementsByTagName(t)),n;if((i=u[3])&&d.getElementsByClassName&&e.getElementsByClassName)return H.apply(n,e.getElementsByClassName(i)),n}if(d.qsa&&!A[t+" "]&&(!v||!v.test(t))&&(1!==p||"object"!==e.nodeName.toLowerCase())){if(c=t,f=e,1===p&&U.test(t)){(s=e.getAttribute("id"))?s=s.replace(re,ie):e.setAttribute("id",s=k),o=(l=h(t)).length;while(o--)l[o]="#"+s+" "+xe(l[o]);c=l.join(","),f=ee.test(t)&&ye(e.parentNode)||e}try{return H.apply(n,f.querySelectorAll(c)),n}catch(e){A(t,!0)}finally{s===k&&e.removeAttribute("id")}}}return g(t.replace(B,"$1"),e,n,r)}function ue(){var r=[];return function e(t,n){return r.push(t+" ")>b.cacheLength&&delete e[r.shift()],e[t+" "]=n}}function le(e){return e[k]=!0,e}function ce(e){var t=C.createElement("fieldset");try{return!!e(t)}catch(e){return!1}finally{t.parentNode&&t.parentNode.removeChild(t),t=null}}function fe(e,t){var n=e.split("|"),r=n.length;while(r--)b.attrHandle[n[r]]=t}function pe(e,t){var n=t&&e,r=n&&1===e.nodeType&&1===t.nodeType&&e.sourceIndex-t.sourceIndex;if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function de(t){return function(e){return"input"===e.nodeName.toLowerCase()&&e.type===t}}function he(n){return function(e){var t=e.nodeName.toLowerCase();return("input"===t||"button"===t)&&e.type===n}}function ge(t){return function(e){return"form"in e?e.parentNode&&!1===e.disabled?"label"in e?"label"in e.parentNode?e.parentNode.disabled===t:e.disabled===t:e.isDisabled===t||e.isDisabled!==!t&&ae(e)===t:e.disabled===t:"label"in e&&e.disabled===t}}function ve(a){return le(function(o){return o=+o,le(function(e,t){var n,r=a([],e.length,o),i=r.length;while(i--)e[n=r[i]]&&(e[n]=!(t[n]=e[n]))})})}function ye(e){return e&&"undefined"!=typeof e.getElementsByTagName&&e}for(e in d=se.support={},i=se.isXML=function(e){var t=e.namespaceURI,n=(e.ownerDocument||e).documentElement;return!Y.test(t||n&&n.nodeName||"HTML")},T=se.setDocument=function(e){var t,n,r=e?e.ownerDocument||e:m;return r!==C&&9===r.nodeType&&r.documentElement&&(a=(C=r).documentElement,E=!i(C),m!==C&&(n=C.defaultView)&&n.top!==n&&(n.addEventListener?n.addEventListener("unload",oe,!1):n.attachEvent&&n.attachEvent("onunload",oe)),d.attributes=ce(function(e){return e.className="i",!e.getAttribute("className")}),d.getElementsByTagName=ce(function(e){return e.appendChild(C.createComment("")),!e.getElementsByTagName("*").length}),d.getElementsByClassName=K.test(C.getElementsByClassName),d.getById=ce(function(e){return a.appendChild(e).id=k,!C.getElementsByName||!C.getElementsByName(k).length}),d.getById?(b.filter.ID=function(e){var t=e.replace(te,ne);return function(e){return e.getAttribute("id")===t}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n=t.getElementById(e);return n?[n]:[]}}):(b.filter.ID=function(e){var n=e.replace(te,ne);return function(e){var t="undefined"!=typeof e.getAttributeNode&&e.getAttributeNode("id");return t&&t.value===n}},b.find.ID=function(e,t){if("undefined"!=typeof t.getElementById&&E){var n,r,i,o=t.getElementById(e);if(o){if((n=o.getAttributeNode("id"))&&n.value===e)return[o];i=t.getElementsByName(e),r=0;while(o=i[r++])if((n=o.getAttributeNode("id"))&&n.value===e)return[o]}return[]}}),b.find.TAG=d.getElementsByTagName?function(e,t){return"undefined"!=typeof t.getElementsByTagName?t.getElementsByTagName(e):d.qsa?t.querySelectorAll(e):void 0}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},b.find.CLASS=d.getElementsByClassName&&function(e,t){if("undefined"!=typeof t.getElementsByClassName&&E)return t.getElementsByClassName(e)},s=[],v=[],(d.qsa=K.test(C.querySelectorAll))&&(ce(function(e){a.appendChild(e).innerHTML="",e.querySelectorAll("[msallowcapture^='']").length&&v.push("[*^$]="+M+"*(?:''|\"\")"),e.querySelectorAll("[selected]").length||v.push("\\["+M+"*(?:value|"+R+")"),e.querySelectorAll("[id~="+k+"-]").length||v.push("~="),e.querySelectorAll(":checked").length||v.push(":checked"),e.querySelectorAll("a#"+k+"+*").length||v.push(".#.+[+~]")}),ce(function(e){e.innerHTML="";var t=C.createElement("input");t.setAttribute("type","hidden"),e.appendChild(t).setAttribute("name","D"),e.querySelectorAll("[name=d]").length&&v.push("name"+M+"*[*^$|!~]?="),2!==e.querySelectorAll(":enabled").length&&v.push(":enabled",":disabled"),a.appendChild(e).disabled=!0,2!==e.querySelectorAll(":disabled").length&&v.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),v.push(",.*:")})),(d.matchesSelector=K.test(c=a.matches||a.webkitMatchesSelector||a.mozMatchesSelector||a.oMatchesSelector||a.msMatchesSelector))&&ce(function(e){d.disconnectedMatch=c.call(e,"*"),c.call(e,"[s!='']:x"),s.push("!=",$)}),v=v.length&&new RegExp(v.join("|")),s=s.length&&new RegExp(s.join("|")),t=K.test(a.compareDocumentPosition),y=t||K.test(a.contains)?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},D=t?function(e,t){if(e===t)return l=!0,0;var n=!e.compareDocumentPosition-!t.compareDocumentPosition;return n||(1&(n=(e.ownerDocument||e)===(t.ownerDocument||t)?e.compareDocumentPosition(t):1)||!d.sortDetached&&t.compareDocumentPosition(e)===n?e===C||e.ownerDocument===m&&y(m,e)?-1:t===C||t.ownerDocument===m&&y(m,t)?1:u?P(u,e)-P(u,t):0:4&n?-1:1)}:function(e,t){if(e===t)return l=!0,0;var n,r=0,i=e.parentNode,o=t.parentNode,a=[e],s=[t];if(!i||!o)return e===C?-1:t===C?1:i?-1:o?1:u?P(u,e)-P(u,t):0;if(i===o)return pe(e,t);n=e;while(n=n.parentNode)a.unshift(n);n=t;while(n=n.parentNode)s.unshift(n);while(a[r]===s[r])r++;return r?pe(a[r],s[r]):a[r]===m?-1:s[r]===m?1:0}),C},se.matches=function(e,t){return se(e,null,null,t)},se.matchesSelector=function(e,t){if((e.ownerDocument||e)!==C&&T(e),d.matchesSelector&&E&&!A[t+" "]&&(!s||!s.test(t))&&(!v||!v.test(t)))try{var n=c.call(e,t);if(n||d.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(e){A(t,!0)}return 0":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(te,ne),e[3]=(e[3]||e[4]||e[5]||"").replace(te,ne),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||se.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&se.error(e[0]),e},PSEUDO:function(e){var t,n=!e[6]&&e[2];return G.CHILD.test(e[0])?null:(e[3]?e[2]=e[4]||e[5]||"":n&&X.test(n)&&(t=h(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){var t=e.replace(te,ne).toLowerCase();return"*"===e?function(){return!0}:function(e){return e.nodeName&&e.nodeName.toLowerCase()===t}},CLASS:function(e){var t=p[e+" "];return t||(t=new RegExp("(^|"+M+")"+e+"("+M+"|$)"))&&p(e,function(e){return t.test("string"==typeof e.className&&e.className||"undefined"!=typeof e.getAttribute&&e.getAttribute("class")||"")})},ATTR:function(n,r,i){return function(e){var t=se.attr(e,n);return null==t?"!="===r:!r||(t+="","="===r?t===i:"!="===r?t!==i:"^="===r?i&&0===t.indexOf(i):"*="===r?i&&-1:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i;function j(e,n,r){return m(n)?k.grep(e,function(e,t){return!!n.call(e,t,e)!==r}):n.nodeType?k.grep(e,function(e){return e===n!==r}):"string"!=typeof n?k.grep(e,function(e){return-1)[^>]*|#([\w-]+))$/;(k.fn.init=function(e,t,n){var r,i;if(!e)return this;if(n=n||q,"string"==typeof e){if(!(r="<"===e[0]&&">"===e[e.length-1]&&3<=e.length?[null,e,null]:L.exec(e))||!r[1]&&t)return!t||t.jquery?(t||n).find(e):this.constructor(t).find(e);if(r[1]){if(t=t instanceof k?t[0]:t,k.merge(this,k.parseHTML(r[1],t&&t.nodeType?t.ownerDocument||t:E,!0)),D.test(r[1])&&k.isPlainObject(t))for(r in t)m(this[r])?this[r](t[r]):this.attr(r,t[r]);return this}return(i=E.getElementById(r[2]))&&(this[0]=i,this.length=1),this}return e.nodeType?(this[0]=e,this.length=1,this):m(e)?void 0!==n.ready?n.ready(e):e(k):k.makeArray(e,this)}).prototype=k.fn,q=k(E);var H=/^(?:parents|prev(?:Until|All))/,O={children:!0,contents:!0,next:!0,prev:!0};function P(e,t){while((e=e[t])&&1!==e.nodeType);return e}k.fn.extend({has:function(e){var t=k(e,this),n=t.length;return this.filter(function(){for(var e=0;e\x20\t\r\n\f]*)/i,he=/^$|^module$|\/(?:java|ecma)script/i,ge={option:[1,""],thead:[1,"","
      "],col:[2,"","
      "],tr:[2,"","
      "],td:[3,"","
      "],_default:[0,"",""]};function ve(e,t){var n;return n="undefined"!=typeof e.getElementsByTagName?e.getElementsByTagName(t||"*"):"undefined"!=typeof e.querySelectorAll?e.querySelectorAll(t||"*"):[],void 0===t||t&&A(e,t)?k.merge([e],n):n}function ye(e,t){for(var n=0,r=e.length;nx",y.noCloneChecked=!!me.cloneNode(!0).lastChild.defaultValue;var Te=/^key/,Ce=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,Ee=/^([^.]*)(?:\.(.+)|)/;function ke(){return!0}function Se(){return!1}function Ne(e,t){return e===function(){try{return E.activeElement}catch(e){}}()==("focus"===t)}function Ae(e,t,n,r,i,o){var a,s;if("object"==typeof t){for(s in"string"!=typeof n&&(r=r||n,n=void 0),t)Ae(e,s,n,r,t[s],o);return e}if(null==r&&null==i?(i=n,r=n=void 0):null==i&&("string"==typeof n?(i=r,r=void 0):(i=r,r=n,n=void 0)),!1===i)i=Se;else if(!i)return e;return 1===o&&(a=i,(i=function(e){return k().off(e),a.apply(this,arguments)}).guid=a.guid||(a.guid=k.guid++)),e.each(function(){k.event.add(this,t,i,r,n)})}function De(e,i,o){o?(Q.set(e,i,!1),k.event.add(e,i,{namespace:!1,handler:function(e){var t,n,r=Q.get(this,i);if(1&e.isTrigger&&this[i]){if(r.length)(k.event.special[i]||{}).delegateType&&e.stopPropagation();else if(r=s.call(arguments),Q.set(this,i,r),t=o(this,i),this[i](),r!==(n=Q.get(this,i))||t?Q.set(this,i,!1):n={},r!==n)return e.stopImmediatePropagation(),e.preventDefault(),n.value}else r.length&&(Q.set(this,i,{value:k.event.trigger(k.extend(r[0],k.Event.prototype),r.slice(1),this)}),e.stopImmediatePropagation())}})):void 0===Q.get(e,i)&&k.event.add(e,i,ke)}k.event={global:{},add:function(t,e,n,r,i){var o,a,s,u,l,c,f,p,d,h,g,v=Q.get(t);if(v){n.handler&&(n=(o=n).handler,i=o.selector),i&&k.find.matchesSelector(ie,i),n.guid||(n.guid=k.guid++),(u=v.events)||(u=v.events={}),(a=v.handle)||(a=v.handle=function(e){return"undefined"!=typeof k&&k.event.triggered!==e.type?k.event.dispatch.apply(t,arguments):void 0}),l=(e=(e||"").match(R)||[""]).length;while(l--)d=g=(s=Ee.exec(e[l])||[])[1],h=(s[2]||"").split(".").sort(),d&&(f=k.event.special[d]||{},d=(i?f.delegateType:f.bindType)||d,f=k.event.special[d]||{},c=k.extend({type:d,origType:g,data:r,handler:n,guid:n.guid,selector:i,needsContext:i&&k.expr.match.needsContext.test(i),namespace:h.join(".")},o),(p=u[d])||((p=u[d]=[]).delegateCount=0,f.setup&&!1!==f.setup.call(t,r,h,a)||t.addEventListener&&t.addEventListener(d,a)),f.add&&(f.add.call(t,c),c.handler.guid||(c.handler.guid=n.guid)),i?p.splice(p.delegateCount++,0,c):p.push(c),k.event.global[d]=!0)}},remove:function(e,t,n,r,i){var o,a,s,u,l,c,f,p,d,h,g,v=Q.hasData(e)&&Q.get(e);if(v&&(u=v.events)){l=(t=(t||"").match(R)||[""]).length;while(l--)if(d=g=(s=Ee.exec(t[l])||[])[1],h=(s[2]||"").split(".").sort(),d){f=k.event.special[d]||{},p=u[d=(r?f.delegateType:f.bindType)||d]||[],s=s[2]&&new RegExp("(^|\\.)"+h.join("\\.(?:.*\\.|)")+"(\\.|$)"),a=o=p.length;while(o--)c=p[o],!i&&g!==c.origType||n&&n.guid!==c.guid||s&&!s.test(c.namespace)||r&&r!==c.selector&&("**"!==r||!c.selector)||(p.splice(o,1),c.selector&&p.delegateCount--,f.remove&&f.remove.call(e,c));a&&!p.length&&(f.teardown&&!1!==f.teardown.call(e,h,v.handle)||k.removeEvent(e,d,v.handle),delete u[d])}else for(d in u)k.event.remove(e,d+t[l],n,r,!0);k.isEmptyObject(u)&&Q.remove(e,"handle events")}},dispatch:function(e){var t,n,r,i,o,a,s=k.event.fix(e),u=new Array(arguments.length),l=(Q.get(this,"events")||{})[s.type]||[],c=k.event.special[s.type]||{};for(u[0]=s,t=1;t\x20\t\r\n\f]*)[^>]*)\/>/gi,qe=/\s*$/g;function Oe(e,t){return A(e,"table")&&A(11!==t.nodeType?t:t.firstChild,"tr")&&k(e).children("tbody")[0]||e}function Pe(e){return e.type=(null!==e.getAttribute("type"))+"/"+e.type,e}function Re(e){return"true/"===(e.type||"").slice(0,5)?e.type=e.type.slice(5):e.removeAttribute("type"),e}function Me(e,t){var n,r,i,o,a,s,u,l;if(1===t.nodeType){if(Q.hasData(e)&&(o=Q.access(e),a=Q.set(t,o),l=o.events))for(i in delete a.handle,a.events={},l)for(n=0,r=l[i].length;n")},clone:function(e,t,n){var r,i,o,a,s,u,l,c=e.cloneNode(!0),f=oe(e);if(!(y.noCloneChecked||1!==e.nodeType&&11!==e.nodeType||k.isXMLDoc(e)))for(a=ve(c),r=0,i=(o=ve(e)).length;r").attr(n.scriptAttrs||{}).prop({charset:n.scriptCharset,src:n.url}).on("load error",i=function(e){r.remove(),i=null,e&&t("error"===e.type?404:200,e.type)}),E.head.appendChild(r[0])},abort:function(){i&&i()}}});var Vt,Gt=[],Yt=/(=)\?(?=&|$)|\?\?/;k.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=Gt.pop()||k.expando+"_"+kt++;return this[e]=!0,e}}),k.ajaxPrefilter("json jsonp",function(e,t,n){var r,i,o,a=!1!==e.jsonp&&(Yt.test(e.url)?"url":"string"==typeof e.data&&0===(e.contentType||"").indexOf("application/x-www-form-urlencoded")&&Yt.test(e.data)&&"data");if(a||"jsonp"===e.dataTypes[0])return r=e.jsonpCallback=m(e.jsonpCallback)?e.jsonpCallback():e.jsonpCallback,a?e[a]=e[a].replace(Yt,"$1"+r):!1!==e.jsonp&&(e.url+=(St.test(e.url)?"&":"?")+e.jsonp+"="+r),e.converters["script json"]=function(){return o||k.error(r+" was not called"),o[0]},e.dataTypes[0]="json",i=C[r],C[r]=function(){o=arguments},n.always(function(){void 0===i?k(C).removeProp(r):C[r]=i,e[r]&&(e.jsonpCallback=t.jsonpCallback,Gt.push(r)),o&&m(i)&&i(o[0]),o=i=void 0}),"script"}),y.createHTMLDocument=((Vt=E.implementation.createHTMLDocument("").body).innerHTML="
      ",2===Vt.childNodes.length),k.parseHTML=function(e,t,n){return"string"!=typeof e?[]:("boolean"==typeof t&&(n=t,t=!1),t||(y.createHTMLDocument?((r=(t=E.implementation.createHTMLDocument("")).createElement("base")).href=E.location.href,t.head.appendChild(r)):t=E),o=!n&&[],(i=D.exec(e))?[t.createElement(i[1])]:(i=we([e],t,o),o&&o.length&&k(o).remove(),k.merge([],i.childNodes)));var r,i,o},k.fn.load=function(e,t,n){var r,i,o,a=this,s=e.indexOf(" ");return-1").append(k.parseHTML(e)).find(r):e)}).always(n&&function(e,t){a.each(function(){n.apply(this,o||[e.responseText,t,e])})}),this},k.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){k.fn[t]=function(e){return this.on(t,e)}}),k.expr.pseudos.animated=function(t){return k.grep(k.timers,function(e){return t===e.elem}).length},k.offset={setOffset:function(e,t,n){var r,i,o,a,s,u,l=k.css(e,"position"),c=k(e),f={};"static"===l&&(e.style.position="relative"),s=c.offset(),o=k.css(e,"top"),u=k.css(e,"left"),("absolute"===l||"fixed"===l)&&-1<(o+u).indexOf("auto")?(a=(r=c.position()).top,i=r.left):(a=parseFloat(o)||0,i=parseFloat(u)||0),m(t)&&(t=t.call(e,n,k.extend({},s))),null!=t.top&&(f.top=t.top-s.top+a),null!=t.left&&(f.left=t.left-s.left+i),"using"in t?t.using.call(e,f):c.css(f)}},k.fn.extend({offset:function(t){if(arguments.length)return void 0===t?this:this.each(function(e){k.offset.setOffset(this,t,e)});var e,n,r=this[0];return r?r.getClientRects().length?(e=r.getBoundingClientRect(),n=r.ownerDocument.defaultView,{top:e.top+n.pageYOffset,left:e.left+n.pageXOffset}):{top:0,left:0}:void 0},position:function(){if(this[0]){var e,t,n,r=this[0],i={top:0,left:0};if("fixed"===k.css(r,"position"))t=r.getBoundingClientRect();else{t=this.offset(),n=r.ownerDocument,e=r.offsetParent||n.documentElement;while(e&&(e===n.body||e===n.documentElement)&&"static"===k.css(e,"position"))e=e.parentNode;e&&e!==r&&1===e.nodeType&&((i=k(e).offset()).top+=k.css(e,"borderTopWidth",!0),i.left+=k.css(e,"borderLeftWidth",!0))}return{top:t.top-i.top-k.css(r,"marginTop",!0),left:t.left-i.left-k.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent;while(e&&"static"===k.css(e,"position"))e=e.offsetParent;return e||ie})}}),k.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(t,i){var o="pageYOffset"===i;k.fn[t]=function(e){return _(this,function(e,t,n){var r;if(x(e)?r=e:9===e.nodeType&&(r=e.defaultView),void 0===n)return r?r[i]:e[t];r?r.scrollTo(o?r.pageXOffset:n,o?n:r.pageYOffset):e[t]=n},t,e,arguments.length)}}),k.each(["top","left"],function(e,n){k.cssHooks[n]=ze(y.pixelPosition,function(e,t){if(t)return t=_e(e,n),$e.test(t)?k(e).position()[n]+"px":t})}),k.each({Height:"height",Width:"width"},function(a,s){k.each({padding:"inner"+a,content:s,"":"outer"+a},function(r,o){k.fn[o]=function(e,t){var n=arguments.length&&(r||"boolean"!=typeof e),i=r||(!0===e||!0===t?"margin":"border");return _(this,function(e,t,n){var r;return x(e)?0===o.indexOf("outer")?e["inner"+a]:e.document.documentElement["client"+a]:9===e.nodeType?(r=e.documentElement,Math.max(e.body["scroll"+a],r["scroll"+a],e.body["offset"+a],r["offset"+a],r["client"+a])):void 0===n?k.css(e,t,i):k.style(e,t,n,i)},s,n?e:void 0,n)}})}),k.each("blur focus focusin focusout resize scroll click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup contextmenu".split(" "),function(e,n){k.fn[n]=function(e,t){return 0Documentation | Taos Data
      Back

      TDengine System Architecture

      -

      Storage Design

      -

      TDengine data mainly include metadata and data that we will introduce in the following sections.

      -

      Metadata Storage

      -

      Metadata include the information of databases, tables, etc. Metadata files are saved in /var/lib/taos/mgmt/ directory by default. The directory tree is as below:

      -
      /var/lib/taos/
      -      +--mgmt/
      -          +--db.db
      -          +--meters.db
      -          +--user.db
      -          +--vgroups.db
      -

      A metadata structure (database, table, etc.) is saved as a record in a metadata file. All metadata files are appended only, and even a drop operation adds a deletion record at the end of the file.

      -

      Data storage

      -

      Data in TDengine are sharded according to the time range. Data of tables in the same vnode in a certain time range are saved in the same filegroup, such as files v0f1804*. This sharding strategy can effectively improve data searching speed. By default, a group of files contains data in 10 days, which can be configured by *daysPerFile* in the configuration file or by DAYS keyword in CREATE DATABASE clause. Data in files are blockwised. A data block only contains one table's data. Records in the same data block are sorted according to the primary timestamp, which helps to improve the compression rate and save storage. The compression algorithms used in TDengine include simple8B, delta-of-delta, RLE, LZ4, etc.

      -

      By default, TDengine data are saved in /var/lib/taos/data/ directory. /var/lib/taos/tsdb/ directory contains vnode informations and data file linkes.

      -
      /var/lib/taos/
      -      +--tsdb/
      -      |   +--vnode0
      -      |        +--meterObj.v0
      -      |        +--db/
      -      |            +--v0f1804.head->/var/lib/taos/data/vnode0/v0f1804.head1
      -      |            +--v0f1804.data->/var/lib/taos/data/vnode0/v0f1804.data
      -      |            +--v0f1804.last->/var/lib/taos/data/vnode0/v0f1804.last1
      -      |            +--v0f1805.head->/var/lib/taos/data/vnode0/v0f1805.head1
      -      |            +--v0f1805.data->/var/lib/taos/data/vnode0/v0f1805.data
      -      |            +--v0f1805.last->/var/lib/taos/data/vnode0/v0f1805.last1
      -      |                   :
      -      +--data/
      -          +--vnode0/
      -                +--v0f1804.head1
      -                +--v0f1804.data
      -                +--v0f1804.last1
      -                +--v0f1805.head1
      -                +--v0f1805.data
      -                +--v0f1805.last1
      -                        :
      -

      meterObj file

      -

      There are only one meterObj file in a vnode. Informations bout the vnode, such as created time, configuration information, vnode statistic informations are saved in this file. It has the structure like below:

      -
      <start_of_file>
      -[file_header]
      -[table_record1_offset&length]
      -[table_record2_offset&length]
      -...
      -[table_recordN_offset&length]
      -[table_record1]
      -[table_record2]
      -...
      -[table_recordN]
      -<end_of_file>
      -

      The file header takes 512 bytes, which mainly contains informations about the vnode. Each table record is the representation of a table on disk.

      -

      head file

      -

      The head files contain the index of data blocks in the data file. The inner organization is as below:

      -
      <start_of_file>
      -[file_header]
      -[table1_offset]
      -[table2_offset]
      -...
      -[tableN_offset]
      -[table1_index_block]
      -[table2_index_block]
      -...
      -[tableN_index_block]
      -<end_of_file>
      -

      The table offset array in the head file saves the information about the offsets of each table index block. Indices on data blocks in the same table are saved continuously. This also makes it efficient to load data indices on the same table. The data index block has a structure like:

      -
      [index_block_info]
      -[block1_index]
      -[block2_index]
      -...
      -[blockN_index]
      -

      The index block info part contains the information about the index block such as the number of index blocks, etc. Each block index corresponds to a real data block in the data file or last file. Information about the location of the real data block, the primary timestamp range of the data block, etc. are all saved in the block index part. The block indices are sorted in ascending order according to the primary timestamp. So we can apply algorithms such as the binary search on the data to efficiently search blocks according to time.

      -

      data file

      -

      The data files store the real data block. They are append-only. The organization is as:

      -
      <start_of_file>
      -[file_header]
      -[block1]
      -[block2]
      -...
      -[blockN]
      -<end_of_file>
      -

      A data block in data files only belongs to a table in the vnode and the records in a data block are sorted in ascending order according to the primary timestamp key. Data blocks are column-oriented. Data in the same column are stored contiguously, which improves reading speed and compression rate because of their similarity. A data block has the following organization:

      -
      [column1_info]
      -[column2_info]
      -...
      -[columnN_info]
      -[column1_data]
      -[column2_data]
      -...
      -[columnN_data]
      -

      The column info part includes information about column types, column compression algorithm, column data offset and length in the data file, etc. Besides, pre-calculated results of the column data in the block are also in the column info part, which helps to improve reading speed by avoiding loading data block necessarily.

      -

      last file

      -

      To avoid storage fragment and to import query speed and compression rate, TDengine introduces an extra file, the last file. When the number of records in a data block is lower than a threshold, TDengine will flush the block to the last file for temporary storage. When new data comes, the data in the last file will be merged with the new data and form a larger data block and written to the data file. The organization of the last file is similar to the data file.

      -

      Summary

      -

      The innovation in architecture and storage design of TDengine improves resource usage. On the one hand, the virtualization makes it easy to distribute resources between different vnodes and for future scaling. On the other hand, sorted and column-oriented storage makes TDengine have a great advantage in writing, querying and compression.

      -

      Query Design

      -

      Introduction

      -

      TDengine provides a variety of query functions for both tables and super tables. In addition to regular aggregate queries, it also provides time window based query and statistical aggregation for time series data. TDengine's query processing requires the client app, management node, and data node to work together. The functions and modules involved in query processing included in each component are as follows:

      -

      Client (Client App). The client development kit, embed in a client application, consists of TAOS SQL parser and query executor, the second-stage aggregator (Result Merger), continuous query manager and other major functional modules. The SQL parser is responsible for parsing and verifying the SQL statement and converting it into an abstract syntax tree. The query executor is responsible for transforming the abstract syntax tree into the query execution logic and creates the metadata query according to the query condition of the SQL statement. Since TAOS SQL does not currently include complex nested queries and pipeline query processing mechanism, there is no longer need for query plan optimization and physical query plan conversions. The second-stage aggregator is responsible for performing the aggregation of the independent results returned by query involved data nodes at the client side to generate final results. The continuous query manager is dedicated to managing the continuous queries created by users, including issuing fixed-interval query requests and writing the results back to TDengine or returning to the client application as needed. Also, the client is also responsible for retrying after the query fails, canceling the query request, and maintaining the connection heartbeat and reporting the query status to the management node.

      -

      Management Node. The management node keeps the metadata of all the data of the entire cluster system, provides the metadata of the data required for the query from the client node, and divides the query request according to the load condition of the cluster. The super table contains information about all the tables created according to the super table, so the query processor (Query Executor) of the management node is responsible for the query processing of the tags of tables and returns the table information satisfying the tag query. Besides, the management node maintains the query status of the cluster in the Query Status Manager component, in which the metadata of all queries that are currently executing are temporarily stored in-memory buffer. When the client issues show queries command to management node, current running queries information is returned to the client.

      -

      Data Node. The data node, responsible for storing all data of the database, consists of query executor, query processing scheduler, query task queue, and other related components. Once the query requests from the client received, they are put into query task queue and waiting to be processed by query executor. The query executor extracts the query request from the query task queue and invokes the query optimizer to perform the basic optimization for the query execution plan. And then query executor scans the qualified data blocks in both cache and disk to obtain qualified data and return the calculated results. Besides, the data node also needs to respond to management information and commands from the management node. For example, after the kill query received from the management node, the query task needs to be stopped immediately.

      -

      -
      Fig 1. System query processing architecture diagram (only query related components)

      -

      Query Process Design

      -

      The client, the management node, and the data node cooperate to complete the entire query processing of TDengine. Let's take a concrete SQL query as an example to illustrate the whole query processing flow. The SQL statement is to query on super table FOO_SUPER_TABLE to get the total number of records generated on January 12, 2019, from the table, of which TAG_LOC equals to 'beijing'. The SQL statement is as follows:

      -
      SELECT COUNT(*) 
      -FROM FOO_SUPER_TABLE
      -WHERE TAG_LOC = 'beijing' AND TS >= '2019-01-12 00:00:00' AND TS < '2019-01-13 00:00:00'
      -

      First, the client invokes the TAOS SQL parser to parse and validate the SQL statement, then generates a syntax tree, and extracts the object of the query - the super table FOO_SUPER_TABLE, and then the parser sends requests with filtering information (TAG_LOC='beijing') to management node to get the corresponding metadata about FOO_SUPER_TABLE.

      -

      Once the management node receives the request for metadata acquisition, first finds the super table FOO_SUPER_TABLE basic information, and then applies the query condition (TAG_LOC='beijing') to filter all the related tables created according to it. And finally, the query executor returns the metadata information that satisfies the query request to the client.

      -

      After the client obtains the metadata information of FOO_SUPER_TABLE, the query executor initiates a query request with timestamp range filtering condition (TS >= '2019- 01-12 00:00:00' AND TS < '2019-01-13 00:00:00') to all nodes that hold the corresponding data according to the information about data distribution in metadata.

      -

      The data node receives the query sent from the client, converts it into an internal structure and puts it into the query task queue to be executed by query executor after optimizing the execution plan. When the query result is obtained, the query result is returned to the client. It should be noted that the data nodes perform the query process independently of each other, and rely solely on their data and content for processing.

      -

      When all data nodes involved in the query return results, the client aggregates the result sets from each data node. In this case, all results are accumulated to generate the final query result. The second stage of aggregation is not always required for all queries. For example, a column selection query does not require a second-stage aggregation at all.

      -

      REST Query Process

      -

      In addition to C/C++, Python, and JDBC interface, TDengine also provides a REST interface based on the HTTP protocol, which is different from using the client application programming interface. When the user uses the REST interface, all the query processing is completed on the server-side, and the user's application is not involved in query processing anymore. After the query processing is completed, the result is returned to the client through the HTTP JSON string.

      -

      -
      Fig. 2 REST query architecture

      -

      When a client uses an HTTP-based REST query interface, the client first establishes a connection with the HTTP connector at the data node and then uses the token to ensure the reliability of the request through the REST signature mechanism. For the data node, after receiving the request, the HTTP connector invokes the embedded client program to initiate a query processing, and then the embedded client parses the SQL statement from the HTTP connector and requests the management node to get metadata as needed. After that, the embedded client sends query requests to the same data node or other nodes in the cluster and aggregates the calculation results on demand. Finally, you also need to convert the result of the query into a JSON format string and return it to the client via an HTTP response. After the HTTP connector receives the request SQL, the subsequent process processing is completely consistent with the query processing using the client application development kit.

      -

      It should be noted that during the entire processing, the client application is no longer involved in, and is only responsible for sending SQL requests through the HTTP protocol and receiving the results in JSON format. Besides, each data node is embedded with an HTTP connector and a client, so any data node in the cluster received requests from a client, the data node can initiate the query and return the result to the client through the HTTP protocol, with transfer the request to other data nodes.

      -

      Technology

      -

      Because TDengine stores data and tags value separately, the tag value is kept in the management node and directly associated with each table instead of records, resulting in a great reduction of the data storage. Therefore, the tag value can be managed by a fully in-memory structure. First, the filtering of the tag data can drastically reduce the data size involved in the second phase of the query. The query processing for the data is performed at the data node. TDengine takes advantage of the immutable characteristics of IoT data by calculating the maximum, minimum, and other statistics of the data in one data block on each saved data block, to effectively improve the performance of query processing. If the query process involves all the data of the entire data block, the pre-computed result is used directly, and the content of the data block is no longer needed. Since the size of disk space required to store the pre-computation result is much smaller than the size of the specific data, the pre-computation result can greatly reduce the disk IO and speed up the query processing.

      -

      TDengine employs column-oriented data storage techniques. When the data block is involved to be loaded from the disk for calculation, only the required column is read according to the query condition, and the read overhead can be minimized. The data of one column is stored in a contiguous memory block and therefore can make full use of the CPU L2 cache to greatly speed up the data scanning. Besides, TDengine utilizes the eagerly responding mechanism and returns a partial result before the complete result is acquired. For example, when the first batch of results is obtained, the data node immediately returns it directly to the client in case of a column select query.

      Back
      \ No newline at end of file diff --git a/2.0/documentation/tdenginedocs-en/styles/base.css b/2.0/documentation/tdenginedocs-en/styles/base.css deleted file mode 100644 index 564b587eb1..0000000000 --- a/2.0/documentation/tdenginedocs-en/styles/base.css +++ /dev/null @@ -1,1112 +0,0 @@ -:root { - --b1:rgb(0,118,206);/*#0077bf*//*PANTONE 2174 C*/ - --b1t:rgba(0,118,206,0.15); - --b2:rgb(72,159,223);/*PANTONE 2171 C*//*OLD:#4193c5*/ - --sg-1:#b3b4b9; - --sg0:#585c66; - --sg1:rgb(51,56,68); - --sg2:#2F333E; - --sg3:#21242c; - --black: #212529; - --white: #fefefe; /*rgb(254,254,254)*/ - --white2:rgb(251, 251, 253); /*#fafbfc*/ - --white3:rgb(240,242,244); - --footer1:#fefefe; - --footer2:#333844; - --red:#ea4741; - --green:#72c156; - /*PRODUCT COLORS*/ - --p1:#72c156;/*#30D387;*/ - --p1t:rgba(114,193,86,0.15); - --p2:#43b3ae;/*rgb(70,161,168);/*#46a1a8*//*#D879D0;*/ - --p2t:rgba(70,161,168,0.15); - --p3:#4997d0;/*#30B7E8;*/ - --p3t:rgba(73,151,208,0.15); -} -/*@font-face{font-family:"Open Sans";src:url(fonts/Light/OpenSans-Light.woff2?v=1.101) format("woff2"),url(fonts/Light/OpenSans-Light.woff?v=1.101) format("woff");font-weight:300;font-style:normal}@font-face{font-family:"Open Sans";src:url(fonts/LightItalic/OpenSans-LightItalic.woff2?v=1.101) format("woff2"),url(fonts/LightItalic/OpenSans-LightItalic.woff?v=1.101) format("woff");font-weight:300;font-style:italic}@font-face{font-family:"Open Sans";src:url(fonts/Regular/OpenSans-Regular.woff2?v=1.101) format("woff2"),url(fonts/Regular/OpenSans-Regular.woff?v=1.101) format("woff");font-weight:400;font-style:normal}@font-face{font-family:"Open Sans";src:url(fonts/Italic/OpenSans-Italic.woff2?v=1.101) format("woff2"),url(fonts/Italic/OpenSans-Italic.woff?v=1.101) format("woff");font-weight:400;font-style:italic}@font-face{font-family:"Open Sans";src:url(fonts/SemiBold/OpenSans-SemiBold.woff2?v=1.101) format("woff2"),url(fonts/SemiBold/OpenSans-SemiBold.woff?v=1.101) format("woff");font-weight:600;font-style:normal}@font-face{font-family:"Open Sans";src:url(fonts/SemiBoldItalic/OpenSans-SemiBoldItalic.woff2?v=1.101) format("woff2"),url(fonts/SemiBoldItalic/OpenSans-SemiBoldItalic.woff?v=1.101) format("woff");font-weight:600;font-style:italic}@font-face{font-family:"Open Sans";src:url(fonts/Bold/OpenSans-Bold.woff2?v=1.101) format("woff2"),url(fonts/Bold/OpenSans-Bold.woff?v=1.101) format("woff");font-weight:700;font-style:normal}@font-face{font-family:"Open Sans";src:url(fonts/BoldItalic/OpenSans-BoldItalic.woff2?v=1.101) format("woff2"),url(fonts/BoldItalic/OpenSans-BoldItalic.woff?v=1.101) format("woff");font-weight:700;font-style:italic}@font-face{font-family:"Open Sans";src:url(fonts/ExtraBold/OpenSans-ExtraBold.woff2?v=1.101) format("woff2"),url(fonts/ExtraBold/OpenSans-ExtraBold.woff?v=1.101) format("woff");font-weight:800;font-style:normal}@font-face{font-family:"Open Sans";src:url(fonts/ExtraBoldItalic/OpenSans-ExtraBoldItalic.woff2?v=1.101) format("woff2"),url(fonts/ExtraBoldItalic/OpenSans-ExtraBoldItalic.woff?v=1.101) format("woff");font-weight:800;font-style:italic}*/ -html { - font-size:12pt; /*20px*/ - background-color: var(--white); -} -body, body * { - font-family: "Open Sans", Helvetica,'Hiragino Sans GB', sans-serif,"Apple Color Emoji"; - -webkit-font-smoothing:auto !important; - -moz-osx-font-smoothing:auto !important; - font-smooth: auto !important; - letter-spacing: normal; - line-height: 1.6; -} -body{ - -webkit-box-sizing: border-box; - box-sizing: border-box; - font-weight: 300; - color:var(--sg1); - font-family: "Open Sans", Helvetica, sans-serif !important; - background-color: var(--white); - -} -strong { - font-weight:600; -} -.anchor { - display: block; - position: relative; - z-index: -1; - top: -10px; -} -/* FORMS */ -input { - outline: none; - -webkit-box-shadow: inset 0px 0px 0px 0px transparent; - box-shadow: inset 0px 0px 0px 0px transparent; -} -input[type='text'], input[type='submit'],textarea { - -webkit-appearance: none; -} -input[l]{ - font-size:inherit; - outline: none; - - color:var(--sg1); - padding-left: 0.4em; - width:-webkit-calc(100%); - width:calc(100%); - border:solid 1px; - display: inline-block; - border-left:1px solid; - -webkit-border-radius:4px; - border-radius:4px; - -webkit-transition: border-left 0.2s; - -o-transition: border-left 0.2s; - transition: border-left 0.2s; - vertical-align: top; - font-weight:400; - border-color:inherit; - margin-bottom: 0.5rem; -} -input[l]:focus { - border-left:1rem solid; -} -input[l]:focus { - width:-webkit-calc(auto); - width:calc(auto); -} -input[plain]:valid { - border-color: var(--b1); -} -input[plain]:focus:valid { - border-color: var(--b1); -} -textarea { - -webkit-box-shadow: inset 0px 0px 0px 0px transparent; - box-shadow: inset 0px 0px 0px 0px transparent; -} -textarea[l] { - font-size:inherit; - outline: none; - - color:var(--sg1); - padding-left: 0.4em; - width:-webkit-calc(100%); - width:calc(100%); - border:solid 1px; - display: inline-block; - border-left:1px solid; - -webkit-border-radius:4px; - border-radius:4px; - -webkit-transition: border-left 0.2s; - -o-transition: border-left 0.2s; - transition: border-left 0.2s; - vertical-align: top; - font-weight:400; - border-color:inherit; - margin-bottom: 0.5rem; -} - -/*Other Text*/ -ul { - padding-left:30px; -} -p, li { - font-size:1em; - -} -p { - margin-bottom: 0.5rem; -} -/*Headers*/ -h1 { - font-size: 2.5rem; - line-height: 1.8; -} -h2 { - font-size: 1.7rem; - line-height: 1.8; -} -h3 { - font-size: 1.4rem; - line-height: 1.43; -} -h4 { - font-size: 1.25rem; -} -h5 { - font-size: 1rem; -} -h6 { - font-size: 1rem; - color: #777; -} -h1[b]::before,h2[b]::before, h3[b]::before { - content:""; - height:1em;; - display: block; - width:3px; - margin-left: -0.5em; - margin-top: 0.45em; - position: absolute; - background-color: var(--b1); -} -h1[b],h2[b], h3[b] { - padding-left: 0.5em -} -/* Navigation Bar */ -.logo { - height: 2.5rem; -} -a { - font-size:1em; -} -a:hover { - text-decoration: none; -} -a[l] { - color:var(--b2); - padding-bottom: 2px; - position: relative; - font-style: normal; - cursor: pointer; -} -a[l]:hover,a[l]:focus { - text-decoration: none; -} -a[l]::before { - content: ""; - left: 0; - background-color: var(--b2); - width: 0%; - height: 1px; - top:-webkit-calc(1em + 8px); - top:calc(1em + 8px); - position: absolute; - z-index: 2; - -webkit-transition: background-color 0.2s, height 0.2s, top 0.2s, width 0.2s; - -o-transition: background-color 0.2s, height 0.2s, top 0.2s, width 0.2s; - transition: background-color 0.2s, height 0.2s, top 0.2s, width 0.2s;; -} -a[l]:hover::before, a[l]:focus::before { - content: ""; - left: 0; - background-color: var(--b2); - width: 100%; - height: 1px; - top:-webkit-calc(1em + 8px); - top:calc(1em + 8px); - position: absolute; - z-index: 2; - -webkit-transition: background-color 0.2s, height 0.2s, top 0.2s, width 0.2s; - -o-transition: background-color 0.2s, height 0.2s, top 0.2s, width 0.2s; - transition: background-color 0.2s, height 0.2s, top 0.2s, width 0.2s; - text-decoration: none; -} -.navbar-brand { - margin-left: 10%; - padding-left: 15px; - color:var(--white) !important; -} -.navbar-nav { - top:0px; -} -.navbar { - background-color:var(--sg1); - z-index:10000; - padding-left: 0px; - padding-right: 0px; - padding-top:0.75rem; - padding-bottom: 0.75rem; -} -.navbar-toggler { - margin-right: -webkit-calc(2rem + 15px); - margin-right: calc(2rem + 15px); -} -.nav-link { - color:var(--white) !important; - line-height: 3.65rem; -} -.nav-item { - height:4.65rem; - font-size:1.1rem; - padding-left: 0.15rem; - padding-right: 0.15rem; - -webkit-transition: all 0.2s; - -o-transition: all 0.2s; - transition: all 0.2s; - border-bottom: 0rem solid var(--white); -} -.nav-item:hover { - border-bottom: 0.45rem solid var(--white); -} -.dropdown-menu { - top:4.1rem; - z-index:1000; - border-top:none; - border:none; - min-width: 120px; - margin-left:-1px; - -webkit-border-top-left-radius: 0; - border-top-left-radius: 0; - -webkit-border-top-right-radius: 0; - border-top-right-radius: 0; - -webkit-border-bottom-left-radius:0.25rem; - border-bottom-left-radius:0.25rem; - -webkit-border-bottom-right-radius:0.25rem; - border-bottom-right-radius:0.25rem; -} -.dropdown-menu.show { - -webkit-box-shadow: 0 4px 24px rgba(100, 109, 146, 0.15); - box-shadow: 0 4px 24px rgba(100, 109, 146, 0.15); -} -.dropdown-item { - color:var(--sg1); - background-color: var(--white); - -webkit-transition:all 0.2s; - -o-transition:all 0.2s; - transition:all 0.2s; - cursor:pointer; -} -.dropdown-item:hover, .dropdown-item:active { - background-color:var(--sg1); - color:var(--white) !important; -} -.dropdown-toggle::after { - display:none; -} -.dropdown a::after { - -webkit-transform: rotate(-90deg); - -ms-transform: rotate(-90deg); - transform: rotate(-90deg); - -webkit-transition: -webkit-transform 0.2s; - transition: -webkit-transform 0.2s; - -o-transition: transform 0.2s; - transition: transform 0.2s; - transition: transform 0.2s, -webkit-transform 0.2s; -} -.dropdown.show a::after { - -webkit-transform: rotate(0deg); - -ms-transform: rotate(0deg); - transform: rotate(0deg); -} -.navbar-nav .active { - border-bottom: 0.45rem solid var(--white); -} -.navbar-nav { - position: absolute; - right:-webkit-calc(10% + 15px); - right:calc(10% + 15px); -} -#language-dropdown .dropdown-menu{ - width:50px; -} -/*FOOTER*/ -footer { - background-color: var(--footer2); - padding-top: 1rem; -} -.page-footer { - padding-bottom: 2rem; -} -.footer-content, .footer-legal, .footer-contact { - width:80%; - margin-left: 10%; - padding-top:1rem; - color:var(--footer1); - font-size:0.8em; -} -.footer-content a { - color:var(--footer1); -} -.footer-content a { - color:var(--footer1); -} -.links-list { - text-align: left; - list-style: none; - padding: 0px; -} -.content-wrapper > .links-list { - padding-left:15px; -} -.links-list-title h4 { - font-size:1.2em; - font-weight:400; -} -.legal-links { - position: absolute; - right:-webkit-calc(10% + 15px); - right:calc(10% + 15px); -} -.legal-links a { - color:var(--footer1); -} -.links-list li { - height:2em; -} -.links-list li a::before, .legal-links a::before { - background-color:var(--footer1); -} -.links-list li a:hover::before, .legal-links a:hover::before { - background-color:var(--footer1); -} -.links-list .divider { - border-bottom: 1px solid var(--footer1); - opacity: 0.15; - height:0px; - margin-bottom: 0.3em; -} -.footer-divider { - border-bottom: 1px solid var(--footer1); - width:-webkit-calc(80% - 30px); - width:calc(80% - 30px); - margin-left: -webkit-calc(10% + 15px); - margin-left: calc(10% + 15px); -} -#social-media-links li { - height:2rem; - line-height:2rem; - display: inline-block; - font-size:1em; -} - -#social-media-links li:last-child::after { - content:""; -} -#social-media-links li::after { - content:" | "; -} -#social-media-links svg { - margin-left:2px;margin-right: 0.4rem; - width:20px; -} -#social-media-links svg path { - fill:var(--footer1); -} -#social-media-links li a::before { - left:1.9rem; - background-color:var(--footer1); -} -#social-media-links li a:hover::before, #social-media-links li a:focus::before { - left:1.9rem; - width: -webkit-calc(100% - 1.9rem); - width: calc(100% - 1.9rem); - background-color:var(--footer1); -} -#social-media-links ion-icon { - font-size:20px; - margin-right: 0.5rem; -} -#social-media-links svg { - font-size:20px; - margin-right: 0.5rem; -} -#email-subscribe-form { - width:-webkit-calc(100% - 160px); - width:calc(100% - 160px); -} -#email-subscribe-form input{ - width:-webkit-calc(100% - 4rem); - width:calc(100% - 4rem); - font-size:1.2em; - outline: none; - height:1.8em; - color:var(--sg1); - padding-left: 0.6em; - border:none; - display: inline-block; - border-left:0px solid var(--b1); - -webkit-border-radius:4px; - border-radius:4px; - -webkit-transition: border-left 0.2s; - -o-transition: border-left 0.2s; - transition: border-left 0.2s; - vertical-align: top; - font-weight:400; -} -#email-subscribe-form input:focus { - border-left:1rem solid var(--b1); - padding-top:2px; -} -#email-subscribe-form input:invalid, #email-subscribe-form input:invalid:focus { - border-color:var(--b1); -} -#email-subscribe-form input.invalid-input, #email-subscribe-form input.invalid-input:focus { - border-color:var(--red); -} -#email-subscribe-form input:valid, #email-subscribe-form input:valid:focus { - border-color:var(--green); -} -#email-subscribe-form button { - font-size:1.2em; - height:1.8em; - line-height: 1em; - float:right; - width:3rem; - padding:0; -} -form { - border-color:var(--b1); -} -form input:invalid, form input:invalid:focus { - border-color:inherit; -} -form input.invalid-input, form input.invalid-input:focus, form textarea.invalid-input, form textarea.invalid-input:focus { - border-color:var(--red); -} -form input:valid, form input:valid:focus { - border-color:var(--green); -} - -.sub-arrow { - width:1.2em; - fill:var(--b1); -} - - -@media only screen and (max-width:991px){ - .page-footer { - padding-left:20px; - padding-right:20px; - } - .footer-legal { - width:100%; - } - #legal-1 { - padding-left: 20px; - } - .legal-links { - right:20px; - } - .footer-content .col-xl-8, .footer-content .col-xl-4{ - padding-left:20px; - padding-right:20px; - } - .footer-content { - width:-webkit-calc(100% + 40px); - width:calc(100% + 40px); - } - .footer-divider { - width:100%; - margin-left: 0; - } -} - -/*SECTIONS AND CONTENT*/ -.content-wrapper { - width: 80%; - margin-left: 10%; - margin-top: 6rem; - margin-bottom: 3rem; - min-height: -webkit-calc(100vh - 187.7px - 74.45px); - min-height: calc(100vh - 187.7px - 74.45px); -} -.section { - /* border-bottom:2px solid rgba(0,0,0,0.2);*/ -} -.section-item { - -} -.section-title, -.section-item-title { - color:var(--b1); - -} -.container-fluid { - background-color: var(--white); -} -.center { - left:50%; - position: relative; -} -/*BUTTONS*/ -.btn-primary { - color:var(--b1); - background-color: var(--white); - border-color:var(--b1); - -webkit-box-shadow:0px 0px 0px 0px rgba(255,255,255,0.55); - box-shadow:0px 0px 0px 0px rgba(255,255,255,0.55); - -webkit-transition: all 0.2s; - -o-transition: all 0.2s; - transition: all 0.2s; -} -.btn-primary:hover,.btn-primary:focus { - color:var(--b1); - background-color: var(--white); - border-color:var(--b1); - -webkit-box-shadow:4px 4px 0px 0px var(--b1t); - box-shadow:4px 4px 0px 0px var(--b1t); - -webkit-transform: translate(-2px,-2px); - -ms-transform: translate(-2px,-2px); - transform: translate(-2px,-2px); -} -.btn-primary:active { - color:var(--b1) !important; - background-color: var(--white) !important; - border-color:var(--b1) !important; - -webkit-box-shadow:2px 2px 0px 0px var(--b1t); - box-shadow:2px 2px 0px 0px var(--b1t); - -webkit-transform: translate(-1px,-1px); - -ms-transform: translate(-1px,-1px); - transform: translate(-1px,-1px); -} -.btn-white { - color:var(--b1); - background-color: var(--white); - -webkit-transition: all 0.2s; - -o-transition: all 0.2s; - transition: all 0.2s; - -webkit-box-shadow:0px 0px 0px 0px rgba(255,255,255,0.55); - box-shadow:0px 0px 0px 0px rgba(255,255,255,0.55); -} -.btn-white:hover,.btn-white:focus { - color:var(--b1); - background-color: var(--white); - -webkit-box-shadow:4px 4px 0px 0px rgba(255,255,255,0.55); - box-shadow:4px 4px 0px 0px rgba(255,255,255,0.55); - -webkit-transform: translate(-2px,-2px); - -ms-transform: translate(-2px,-2px); - transform: translate(-2px,-2px); -} -.btn-white:active { - color:var(--b1) !important; - background-color: var(--white) !important; - -webkit-box-shadow:2px 2px 0px 0px rgba(255,255,255,0.55); - box-shadow:2px 2px 0px 0px rgba(255,255,255,0.55); - -webkit-transform: translate(-1px,-1px); - -ms-transform: translate(-1px,-1px); - transform: translate(-1px,-1px); -} -.btn-filled { - color:var(--white) !important; - background-color: var(--b1); - border-color:var(--b1); - -webkit-box-shadow:0px 0px 0px 0px rgba(255,255,255,0.55); - box-shadow:0px 0px 0px 0px rgba(255,255,255,0.55); - -webkit-transition: all 0.2s; - -o-transition: all 0.2s; - transition: all 0.2s; -} -.btn-filled:hover { - color:var(--white) !important;; - background-color: var(--b1); - border-color:var(--b1); - -webkit-box-shadow:4px 4px 0px 0px var(--b1t); - box-shadow:4px 4px 0px 0px var(--b1t); - -webkit-transform: translate(-2px,-2px); - -ms-transform: translate(-2px,-2px); - transform: translate(-2px,-2px); -} -.btn-filled:active { - color:var(--white) !important; - background-color: var(--b1) !important; - border-color:var(--b1) !important; - -webkit-box-shadow:2px 2px 0px 0px var(--b1t); - box-shadow:2px 2px 0px 0px var(--b1t); - -webkit-transform: translate(-1px,-1px); - -ms-transform: translate(-1px,-1px); - transform: translate(-1px,-1px); -} -/*Popup*/ -#popup-wrapper { - display: block; - position: absolute; - z-index:1000; - -webkit-transition:opacity 0.5s; - -o-transition:opacity 0.5s; - transition:opacity 0.5s; - opacity: 1; -} -#popup-page-cover { - display:none; - position: fixed; - height: 100vh; - width:100vw; - top:0;left:0; - background-color: rgba(131, 145, 174, 0.32); - z-index:1000; - -webkit-transition:opacity 0.5s; - -o-transition:opacity 0.5s; - transition:opacity 0.5s; - opacity:0; -} -#popup { - position: fixed; - display: none; - height:auto; - width:100px; - z-index: 1001; - max-width: -webkit-calc(100% - 30px); - max-width: calc(100% - 30px); - background-color: var(--white); - left:50%; - -webkit-transform:translate(-50%,-50%); - -ms-transform:translate(-50%,-50%); - transform:translate(-50%,-50%); - top:50%; - -webkit-transition:opacity 0.5s; - -o-transition:opacity 0.5s; - transition:opacity 0.5s; - opacity:0; - -webkit-border-radius:0.25rem; - border-radius:0.25rem; - -webkit-box-shadow: 0 12px 48px 0 rgba(0, 0, 0, 0.24); - box-shadow: 0 12px 48px 0 rgba(0, 0, 0, 0.24) -} -#close-popup { - position: absolute;right:1rem; - z-index: 1; - cursor: pointer; - top:0; -} -#close-popup svg { - margin-top:4px; -} -#close-popup::before { - content:""; - width:0px; - display: block; - position: absolute; - top:50%; - left:50%; - height:0px; - background-color:rgba(0,0,0,0.15); - -webkit-border-radius:50%; - border-radius:50%; - z-index:-1; - cursor: pointer; - -webkit-transition:all 0.2s; - -o-transition:all 0.2s; - transition:all 0.2s; -} -#close-popup:hover::before { - content:""; - width:32px;; - display: block; - position: absolute; - top:10px; - left:0px; - height:32px; - background-color:rgba(0,0,0,0.15); - -webkit-border-radius:50%; - border-radius:50%; -z-index:-1; -} -#popup-title { - padding-left: 1rem; - background-color:var(--b1); - color:var(--white); - font-weight:400; - font-size:1.6em; - width:100%; - display:block; - -webkit-border-radius:0.25rem 0.25rem 0 0; - border-radius:0.25rem 0.25rem 0 0; - padding-right:60px; - position: relative; -} -#popup-title-text { - line-height: 1.2; - display: inline-block; - padding-top: 9px; -} -#popup-content { - padding:1rem; - display: block; -} -#popup-title path { - fill:var(--white); -} -/*Banners*/ -.banner-content { - padding-right:32px; -} -.banner-wrapper { - width:100vw; - position: fixed; - top:4.3rem; - left:0; - z-index: 1000; -} -.banner { - background-color: var(--b1); - width:-webkit-calc(100% - 20px); - width:calc(100% - 20px); - margin: auto; - -webkit-border-radius:0.25rem; - border-radius:0.25rem; - padding:0.5rem; - color:var(--white); - font-size:1.6em; - margin-top: 1rem; - -webkit-box-shadow:0 4px 12px 0 rgba(0, 0, 0, 0.24); - box-shadow:0 4px 12px 0 rgba(0, 0, 0, 0.24); - opacity: 1; - -webkit-animation: bannerOpaque 0.2s; - animation: bannerOpaque 0.2s; -} -@-webkit-keyframes bannerOpaque { - from { - opacity:0 - } - to { - opacity:1; - } -} -@keyframes bannerOpaque { - from { - opacity:0 - } - to { - opacity:1; - } -} -.close-banner { - position: absolute;right:1rem; - z-index: 1; - cursor: pointer; - -webkit-transform: translate(0,-3px); - -ms-transform: translate(0,-3px); - transform: translate(0,-3px); -} -.close-banner::before { - content:""; - width:0px; - display: block; - position: absolute; - margin-top:26px; - left:50%; - height:0px; - background-color:rgba(0,0,0,0.15); - -webkit-border-radius:50%; - border-radius:50%; - z-index:-1; - cursor: pointer; - -webkit-transition:all 0.2s; - -o-transition:all 0.2s; - transition:all 0.2s; -} -.close-banner:hover::before { - content:""; - width:32px; - margin-top: 7px; - display: block; - position: absolute; - left:0px; - height:32px; - background-color:rgba(0,0,0,0.15); - -webkit-border-radius:50%; - border-radius:50%; -z-index:-1; -} -@media only screen and (max-width:991px) { - .banner { - font-size:1.2rem; - } -} -/*OTHER*/ -#globe-svg { - height:60px; - fill:#fefefe -} -#page-cover { - width:100vw; - top:-100vh; - left:0px; - -webkit-transition-delay: 0.3s; - -o-transition-delay: 0.3s; - transition-delay: 0.3s; - -webkit-transition:all 0.7s; - -o-transition:all 0.7s; - transition:all 0.7s; - height:100vh; - position: fixed; - z-index:1000; - background-color: rgba(54, 61, 75, 0.25); -} -#menu-button { - border:none; - outline:none; -} -#menu-bar { - -webkit-transition: all 0.15s; - -o-transition: all 0.15s; - transition: all 0.15s; -} -#close-bar { - -webkit-transition: all 0.15s; - -o-transition: all 0.15s; - transition: all 0.15s; - display: none; -} -#rect1 { - -webkit-transition: all 0.2s; - -o-transition: all 0.2s; - transition: all 0.2s; -} -#rect2 { --webkit-transition: all 0.2s; --o-transition: all 0.2s; -transition: all 0.2s; -} -#rect3 { --webkit-transition: all 0.2s; --o-transition: all 0.2s; -transition: all 0.2s; -} -@media only screen and (max-width: 991px) { - - .content-wrapper { - width:-webkit-calc(100%); - width:calc(100%); - left:0; - padding-left: 0; - margin-left:0; - margin-top:4.7rem; - } - .container-fluid { - padding-left:20px; - padding-right:20px; - } - .row { - margin-left:-20px; - margin-right:-20px; - } - #menu-button { - margin-right:20px; - padding:0px; - } - .navbar-brand { - margin-left: 20px; - padding-left: 0px; - } -} -.bot-logo { - margin-bottom:0.5rem; -} -@media only screen and (min-width:1200px){ - #page-cover { - display: none - } - .bot-logo { - margin-left:15px; - } -} -@media only screen and (max-width: 1199px) { - #globe-svg { - height:60px; - fill:var(--sg1); - } - .navbar-collapse.show { - -webkit-box-shadow:0px 10px 24px rgba(0,0,0,0.15) ; - box-shadow:0px 10px 24px rgba(0,0,0,0.15) ; - } - .nav-item:first-child { - border-top: 1px solid rgba(255,255,255,0.35); - } - #menu-button { - margin-right: -webkit-calc(10% + 15px); - margin-right: calc(10% + 15px); - padding:0; - } - #menu-button:hover { - background-color: transparent; - } - .nav-item { - height:auto; - border-bottom: 1px solid rgba(0,0,0,0.35); - padding-left: -webkit-calc(10% + 15px); - padding-left: calc(10% + 15px); - } - .nav-link{ - line-height: 3rem; - padding: 0px; - - } - .nav-link{ - color:var(--sg1) !important; - } - .nav-item:hover { - border-bottom: 1px solid rgba(0,0,0,0.35); - - } - .navbar-nav { - background-color: var(--white2); - margin-top: 15px; - } - .navbar-nav .active { - border-bottom: 1px solid rgba(0,0,0,0.35); - } - .nav-item:nth-child(even) { - /* - background-color:rgba(0,0,0,0.05); - padding-left: 1rem; - margin-left: -1rem; - */ - } - #navbarSupportedContent { - - } - #language-dropdown .dropdown-menu{ - width: -webkit-calc(80% + 4rem); - width: calc(80% + 4rem); - background-color: var(--white); - - } - .dropdown-menu { - border:none; - margin-top: -20px; - } - .nav-item:last-child { - border-bottom:none; - } - .dropdown-menu.show { - -webkit-box-shadow: 0 4px 24px rgba(100, 109, 146, 0.15); - box-shadow: 0 4px 24px rgba(100, 109, 146, 0.15); - margin-bottom:1rem; - margin-top:-0.5rem; - } - .dropdown-item { - padding-left: 15px; - font-weight:300; - } - .navbar-nav { - position: relative; - right:0rem; - } - .long-form input { - width:100%; - } -} -@media only screen and (max-width: 991px) { - .nav-item { - padding-left: 20px; - padding-right: 20px; - } - #language-dropdown{ - padding-left:20px; - } - #language-dropdown .dropdown-menu { - width:100%; - } - #menu-button { - margin-right: 20px; - padding:0; - } - .navbar { - padding-top: 0.25rem; - padding-bottom:0.25rem; - } - .logo { - height:1.8rem; - } - .anchor { - top: -55px; - } -} -@media only screen and (max-width:556px) { - #legal-1 { - width:100%; - } - .legal-links { - position: inherit; - margin-left: 20px; - margin-bottom: 1em; - } -} -@media only screen and (max-width:375px) { - #legal-1 p { - display: block; - } -} - -/*Footer media queries*/ -@media only screen and (max-width:830px) { -} -@media only screen and (max-width:650px) { -} -@media only screen and (max-width:352px) { -} - -.lds-ring { - display: inline-block; - position: relative; - width: 18px; - height: 18px; - padding-top:2px; -} -#email-subscribe-form .lds-ring { - padding-top:1px; -} -.lds-ring div { - -webkit-box-sizing: border-box; - box-sizing: border-box; - display: block; - position: absolute; - width: 18px; - height: 18px; - border: 2px solid var(--b2); - -webkit-border-radius: 50%; - border-radius: 50%; - -webkit-animation: lds-ring 1.2s cubic-bezier(0.5, 0, 0.5, 1) infinite; - animation: lds-ring 1.2s cubic-bezier(0.5, 0, 0.5, 1) infinite; - border-color: var(--b2) transparent transparent transparent; -} -.lds-ring div:nth-child(1) { - -webkit-animation-delay: -0.45s; - animation-delay: -0.45s; -} -.lds-ring div:nth-child(2) { - -webkit-animation-delay: -0.3s; - animation-delay: -0.3s; -} -.lds-ring div:nth-child(3) { - -webkit-animation-delay: -0.15s; - animation-delay: -0.15s; -} -@-webkit-keyframes lds-ring { - 0% { - -webkit-transform: rotate(0deg); - transform: rotate(0deg); - } - 100% { - -webkit-transform: rotate(360deg); - transform: rotate(360deg); - } -} -@keyframes lds-ring { - 0% { - -webkit-transform: rotate(0deg); - transform: rotate(0deg); - } - 100% { - -webkit-transform: rotate(360deg); - transform: rotate(360deg); - } -} -#email-subscribe-form .sub-arrow { - padding-top:2px; -} -.sub-arrow { - display: inline-block; -} -.sub-load { - display:none; -} diff --git a/2.0/documentation/tdenginedocs-en/styles/base.min.css b/2.0/documentation/tdenginedocs-en/styles/base.min.css deleted file mode 100644 index 7aa9427702..0000000000 --- a/2.0/documentation/tdenginedocs-en/styles/base.min.css +++ /dev/null @@ -1 +0,0 @@ -:root{--b1:rgb(0,118,206);--b1t:rgba(0,118,206,0.15);--b2:rgb(72,159,223);--sg-1:#b3b4b9;--sg0:#585c66;--sg1:rgb(51,56,68);--sg2:#2F333E;--sg3:#21242c;--black:#212529;--white:#fefefe;--white2:rgb(251, 251, 253);--white3:rgb(240,242,244);--footer1:#fefefe;--footer2:#333844;--red:#ea4741;--green:#72c156;--p1:#72c156;--p1t:rgba(114,193,86,0.15);--p2:#43b3ae;--p2t:rgba(70,161,168,0.15);--p3:#4997d0;--p3t:rgba(73,151,208,0.15)}html{font-size:12pt;background-color:var(--white)}body,body *{font-family:"Open Sans",Helvetica,'Hiragino Sans GB',sans-serif,"Apple Color Emoji";-webkit-font-smoothing:auto!important;-moz-osx-font-smoothing:auto!important;font-smooth:auto!important;letter-spacing:normal;line-height:1.6}body{-webkit-box-sizing:border-box;box-sizing:border-box;font-weight:300;color:var(--sg1);font-family:"Open Sans",Helvetica,sans-serif!important;background-color:var(--white)}strong{font-weight:600}.anchor{display:block;position:relative;z-index:-1;top:-10px}input{outline:0;-webkit-box-shadow:inset 0 0 0 0 transparent;box-shadow:inset 0 0 0 0 transparent}input[type=submit],input[type=text],textarea{-webkit-appearance:none}input[l]{font-size:inherit;outline:0;color:var(--sg1);padding-left:.4em;width:-webkit-calc(100%);width:calc(100%);border:solid 1px;display:inline-block;border-left:1px solid;-webkit-border-radius:4px;border-radius:4px;-webkit-transition:border-left .2s;-o-transition:border-left .2s;transition:border-left .2s;vertical-align:top;font-weight:400;border-color:inherit;margin-bottom:.5rem}input[l]:focus{border-left:1rem solid}input[l]:focus{width:-webkit-calc(auto);width:calc(auto)}input[plain]:valid{border-color:var(--b1)}input[plain]:focus:valid{border-color:var(--b1)}textarea{-webkit-box-shadow:inset 0 0 0 0 transparent;box-shadow:inset 0 0 0 0 transparent}textarea[l]{font-size:inherit;outline:0;color:var(--sg1);padding-left:.4em;width:-webkit-calc(100%);width:calc(100%);border:solid 1px;display:inline-block;border-left:1px solid;-webkit-border-radius:4px;border-radius:4px;-webkit-transition:border-left .2s;-o-transition:border-left .2s;transition:border-left .2s;vertical-align:top;font-weight:400;border-color:inherit;margin-bottom:.5rem}ul{padding-left:30px}li,p{font-size:1em}p{margin-bottom:.5rem}h1{font-size:2.5rem;line-height:1.8}h2{font-size:1.7rem;line-height:1.8}h3{font-size:1.4rem;line-height:1.43}h4{font-size:1.25rem}h5{font-size:1rem}h6{font-size:1rem;color:#777}h1[b]::before,h2[b]::before,h3[b]::before{content:"";height:1em;display:block;width:3px;margin-left:-.5em;margin-top:.45em;position:absolute;background-color:var(--b1)}h1[b],h2[b],h3[b]{padding-left:.5em}.logo{height:2.5rem}a{font-size:1em}a:hover{text-decoration:none}a[l]{color:var(--b2);padding-bottom:2px;position:relative;font-style:normal;cursor:pointer}a[l]:focus,a[l]:hover{text-decoration:none}a[l]::before{content:"";left:0;background-color:var(--b2);width:0%;height:1px;top:-webkit-calc(1em + 8px);top:calc(1em + 8px);position:absolute;z-index:2;-webkit-transition:background-color .2s,height .2s,top .2s,width .2s;-o-transition:background-color .2s,height .2s,top .2s,width .2s;transition:background-color .2s,height .2s,top .2s,width .2s}a[l]:focus::before,a[l]:hover::before{content:"";left:0;background-color:var(--b2);width:100%;height:1px;top:-webkit-calc(1em + 8px);top:calc(1em + 8px);position:absolute;z-index:2;-webkit-transition:background-color .2s,height .2s,top .2s,width .2s;-o-transition:background-color .2s,height .2s,top .2s,width .2s;transition:background-color .2s,height .2s,top .2s,width .2s;text-decoration:none}.navbar-brand{margin-left:10%;padding-left:15px;color:var(--white)!important}.navbar-nav{top:0}.navbar{background-color:var(--sg1);z-index:10000;padding-left:0;padding-right:0;padding-top:.75rem;padding-bottom:.75rem}.navbar-toggler{margin-right:-webkit-calc(2rem + 15px);margin-right:calc(2rem + 15px)}.nav-link{color:var(--white)!important;line-height:3.65rem}.nav-item{height:4.65rem;font-size:1.1rem;padding-left:.15rem;padding-right:.15rem;-webkit-transition:all .2s;-o-transition:all .2s;transition:all .2s;border-bottom:0 solid var(--white)}.nav-item:hover{border-bottom:.45rem solid var(--white)}.dropdown-menu{top:4.1rem;z-index:1000;border-top:none;border:none;min-width:120px;margin-left:-1px;-webkit-border-top-left-radius:0;border-top-left-radius:0;-webkit-border-top-right-radius:0;border-top-right-radius:0;-webkit-border-bottom-left-radius:.25rem;border-bottom-left-radius:.25rem;-webkit-border-bottom-right-radius:.25rem;border-bottom-right-radius:.25rem}.dropdown-menu.show{-webkit-box-shadow:0 4px 24px rgba(100,109,146,.15);box-shadow:0 4px 24px rgba(100,109,146,.15)}.dropdown-item{color:var(--sg1);background-color:var(--white);-webkit-transition:all .2s;-o-transition:all .2s;transition:all .2s;cursor:pointer}.dropdown-item:active,.dropdown-item:hover{background-color:var(--sg1);color:var(--white)!important}.dropdown-toggle::after{display:none}.dropdown a::after{-webkit-transform:rotate(-90deg);-ms-transform:rotate(-90deg);transform:rotate(-90deg);-webkit-transition:-webkit-transform .2s;transition:-webkit-transform .2s;-o-transition:transform .2s;transition:transform .2s;transition:transform .2s,-webkit-transform .2s}.dropdown.show a::after{-webkit-transform:rotate(0);-ms-transform:rotate(0);transform:rotate(0)}.navbar-nav .active{border-bottom:.45rem solid var(--white)}.navbar-nav{position:absolute;right:-webkit-calc(10% + 15px);right:calc(10% + 15px)}#language-dropdown .dropdown-menu{width:50px}footer{background-color:var(--footer2);padding-top:1rem}.page-footer{padding-bottom:2rem}.footer-contact,.footer-content,.footer-legal{width:80%;margin-left:10%;padding-top:1rem;color:var(--footer1);font-size:.8em}.footer-content a{color:var(--footer1)}.footer-content a{color:var(--footer1)}.links-list{text-align:left;list-style:none;padding:0}.content-wrapper>.links-list{padding-left:15px}.links-list-title h4{font-size:1.2em;font-weight:400}.legal-links{position:absolute;right:-webkit-calc(10% + 15px);right:calc(10% + 15px)}.legal-links a{color:var(--footer1)}.links-list li{height:2em}.legal-links a::before,.links-list li a::before{background-color:var(--footer1)}.legal-links a:hover::before,.links-list li a:hover::before{background-color:var(--footer1)}.links-list .divider{border-bottom:1px solid var(--footer1);opacity:.15;height:0;margin-bottom:.3em}.footer-divider{border-bottom:1px solid var(--footer1);width:-webkit-calc(80% - 30px);width:calc(80% - 30px);margin-left:-webkit-calc(10% + 15px);margin-left:calc(10% + 15px)}#social-media-links li{height:2rem;line-height:2rem;display:inline-block;font-size:1em}#social-media-links li:last-child::after{content:""}#social-media-links li::after{content:" | "}#social-media-links svg{margin-left:2px;margin-right:.4rem;width:20px}#social-media-links svg path{fill:var(--footer1)}#social-media-links li a::before{left:1.9rem;background-color:var(--footer1)}#social-media-links li a:focus::before,#social-media-links li a:hover::before{left:1.9rem;width:-webkit-calc(100% - 1.9rem);width:calc(100% - 1.9rem);background-color:var(--footer1)}#social-media-links ion-icon{font-size:20px;margin-right:.5rem}#social-media-links svg{font-size:20px;margin-right:.5rem}#email-subscribe-form{width:-webkit-calc(100% - 160px);width:calc(100% - 160px)}#email-subscribe-form input{width:-webkit-calc(100% - 4rem);width:calc(100% - 4rem);font-size:1.2em;outline:0;height:1.8em;color:var(--sg1);padding-left:.6em;border:none;display:inline-block;border-left:0 solid var(--b1);-webkit-border-radius:4px;border-radius:4px;-webkit-transition:border-left .2s;-o-transition:border-left .2s;transition:border-left .2s;vertical-align:top;font-weight:400}#email-subscribe-form input:focus{border-left:1rem solid var(--b1);padding-top:2px}#email-subscribe-form input:invalid,#email-subscribe-form input:invalid:focus{border-color:var(--b1)}#email-subscribe-form input.invalid-input,#email-subscribe-form input.invalid-input:focus{border-color:var(--red)}#email-subscribe-form input:valid,#email-subscribe-form input:valid:focus{border-color:var(--green)}#email-subscribe-form button{font-size:1.2em;height:1.8em;line-height:1em;float:right;width:3rem;padding:0}form{border-color:var(--b1)}form input:invalid,form input:invalid:focus{border-color:inherit}form input.invalid-input,form input.invalid-input:focus,form textarea.invalid-input,form textarea.invalid-input:focus{border-color:var(--red)}form input:valid,form input:valid:focus{border-color:var(--green)}.sub-arrow{width:1.2em;fill:var(--b1)}@media only screen and (max-width:991px){.page-footer{padding-left:20px;padding-right:20px}.footer-legal{width:100%}#legal-1{padding-left:20px}.legal-links{right:20px}.footer-content .col-xl-4,.footer-content .col-xl-8{padding-left:20px;padding-right:20px}.footer-content{width:-webkit-calc(100% + 40px);width:calc(100% + 40px)}.footer-divider{width:100%;margin-left:0}}.content-wrapper{width:80%;margin-left:10%;margin-top:6rem;margin-bottom:3rem;min-height:-webkit-calc(100vh - 187.7px - 74.45px);min-height:calc(100vh - 187.7px - 74.45px)}.section-item-title,.section-title{color:var(--b1)}.container-fluid{background-color:var(--white)}.center{left:50%;position:relative}.btn-primary{color:var(--b1);background-color:var(--white);border-color:var(--b1);-webkit-box-shadow:0 0 0 0 rgba(255,255,255,.55);box-shadow:0 0 0 0 rgba(255,255,255,.55);-webkit-transition:all .2s;-o-transition:all .2s;transition:all .2s}.btn-primary:focus,.btn-primary:hover{color:var(--b1);background-color:var(--white);border-color:var(--b1);-webkit-box-shadow:4px 4px 0 0 var(--b1t);box-shadow:4px 4px 0 0 var(--b1t);-webkit-transform:translate(-2px,-2px);-ms-transform:translate(-2px,-2px);transform:translate(-2px,-2px)}.btn-primary:active{color:var(--b1)!important;background-color:var(--white)!important;border-color:var(--b1)!important;-webkit-box-shadow:2px 2px 0 0 var(--b1t);box-shadow:2px 2px 0 0 var(--b1t);-webkit-transform:translate(-1px,-1px);-ms-transform:translate(-1px,-1px);transform:translate(-1px,-1px)}.btn-white{color:var(--b1);background-color:var(--white);-webkit-transition:all .2s;-o-transition:all .2s;transition:all .2s;-webkit-box-shadow:0 0 0 0 rgba(255,255,255,.55);box-shadow:0 0 0 0 rgba(255,255,255,.55)}.btn-white:focus,.btn-white:hover{color:var(--b1);background-color:var(--white);-webkit-box-shadow:4px 4px 0 0 rgba(255,255,255,.55);box-shadow:4px 4px 0 0 rgba(255,255,255,.55);-webkit-transform:translate(-2px,-2px);-ms-transform:translate(-2px,-2px);transform:translate(-2px,-2px)}.btn-white:active{color:var(--b1)!important;background-color:var(--white)!important;-webkit-box-shadow:2px 2px 0 0 rgba(255,255,255,.55);box-shadow:2px 2px 0 0 rgba(255,255,255,.55);-webkit-transform:translate(-1px,-1px);-ms-transform:translate(-1px,-1px);transform:translate(-1px,-1px)}.btn-filled{color:var(--white)!important;background-color:var(--b1);border-color:var(--b1);-webkit-box-shadow:0 0 0 0 rgba(255,255,255,.55);box-shadow:0 0 0 0 rgba(255,255,255,.55);-webkit-transition:all .2s;-o-transition:all .2s;transition:all .2s}.btn-filled:hover{color:var(--white)!important;background-color:var(--b1);border-color:var(--b1);-webkit-box-shadow:4px 4px 0 0 var(--b1t);box-shadow:4px 4px 0 0 var(--b1t);-webkit-transform:translate(-2px,-2px);-ms-transform:translate(-2px,-2px);transform:translate(-2px,-2px)}.btn-filled:active{color:var(--white)!important;background-color:var(--b1)!important;border-color:var(--b1)!important;-webkit-box-shadow:2px 2px 0 0 var(--b1t);box-shadow:2px 2px 0 0 var(--b1t);-webkit-transform:translate(-1px,-1px);-ms-transform:translate(-1px,-1px);transform:translate(-1px,-1px)}#popup-wrapper{display:block;position:absolute;z-index:1000;-webkit-transition:opacity .5s;-o-transition:opacity .5s;transition:opacity .5s;opacity:1}#popup-page-cover{display:none;position:fixed;height:100vh;width:100vw;top:0;left:0;background-color:rgba(131,145,174,.32);z-index:1000;-webkit-transition:opacity .5s;-o-transition:opacity .5s;transition:opacity .5s;opacity:0}#popup{position:fixed;display:none;height:auto;width:100px;z-index:1001;max-width:-webkit-calc(100% - 30px);max-width:calc(100% - 30px);background-color:var(--white);left:50%;-webkit-transform:translate(-50%,-50%);-ms-transform:translate(-50%,-50%);transform:translate(-50%,-50%);top:50%;-webkit-transition:opacity .5s;-o-transition:opacity .5s;transition:opacity .5s;opacity:0;-webkit-border-radius:.25rem;border-radius:.25rem;-webkit-box-shadow:0 12px 48px 0 rgba(0,0,0,.24);box-shadow:0 12px 48px 0 rgba(0,0,0,.24)}#close-popup{position:absolute;right:1rem;z-index:1;cursor:pointer;top:0}#close-popup svg{margin-top:4px}#close-popup::before{content:"";width:0;display:block;position:absolute;top:50%;left:50%;height:0;background-color:rgba(0,0,0,.15);-webkit-border-radius:50%;border-radius:50%;z-index:-1;cursor:pointer;-webkit-transition:all .2s;-o-transition:all .2s;transition:all .2s}#close-popup:hover::before{content:"";width:32px;display:block;position:absolute;top:10px;left:0;height:32px;background-color:rgba(0,0,0,.15);-webkit-border-radius:50%;border-radius:50%;z-index:-1}#popup-title{padding-left:1rem;background-color:var(--b1);color:var(--white);font-weight:400;font-size:1.6em;width:100%;display:block;-webkit-border-radius:.25rem .25rem 0 0;border-radius:.25rem .25rem 0 0;padding-right:60px;position:relative}#popup-title-text{line-height:1.2;display:inline-block;padding-top:9px}#popup-content{padding:1rem;display:block}#popup-title path{fill:var(--white)}.banner-content{padding-right:32px}.banner-wrapper{width:100vw;position:fixed;top:4.3rem;left:0;z-index:1000}.banner{background-color:var(--b1);width:-webkit-calc(100% - 20px);width:calc(100% - 20px);margin:auto;-webkit-border-radius:.25rem;border-radius:.25rem;padding:.5rem;color:var(--white);font-size:1.6em;margin-top:1rem;-webkit-box-shadow:0 4px 12px 0 rgba(0,0,0,.24);box-shadow:0 4px 12px 0 rgba(0,0,0,.24);opacity:1;-webkit-animation:bannerOpaque .2s;animation:bannerOpaque .2s}@-webkit-keyframes bannerOpaque{from{opacity:0}to{opacity:1}}@keyframes bannerOpaque{from{opacity:0}to{opacity:1}}.close-banner{position:absolute;right:1rem;z-index:1;cursor:pointer;-webkit-transform:translate(0,-3px);-ms-transform:translate(0,-3px);transform:translate(0,-3px)}.close-banner::before{content:"";width:0;display:block;position:absolute;margin-top:26px;left:50%;height:0;background-color:rgba(0,0,0,.15);-webkit-border-radius:50%;border-radius:50%;z-index:-1;cursor:pointer;-webkit-transition:all .2s;-o-transition:all .2s;transition:all .2s}.close-banner:hover::before{content:"";width:32px;margin-top:7px;display:block;position:absolute;left:0;height:32px;background-color:rgba(0,0,0,.15);-webkit-border-radius:50%;border-radius:50%;z-index:-1}@media only screen and (max-width:991px){.banner{font-size:1.2rem}}#globe-svg{height:60px;fill:#fefefe}#page-cover{width:100vw;top:-100vh;left:0;-webkit-transition-delay:.3s;-o-transition-delay:.3s;transition-delay:.3s;-webkit-transition:all .7s;-o-transition:all .7s;transition:all .7s;height:100vh;position:fixed;z-index:1000;background-color:rgba(54,61,75,.25)}#menu-button{border:none;outline:0}#menu-bar{-webkit-transition:all .15s;-o-transition:all .15s;transition:all .15s}#close-bar{-webkit-transition:all .15s;-o-transition:all .15s;transition:all .15s;display:none}#rect1{-webkit-transition:all .2s;-o-transition:all .2s;transition:all .2s}#rect2{-webkit-transition:all .2s;-o-transition:all .2s;transition:all .2s}#rect3{-webkit-transition:all .2s;-o-transition:all .2s;transition:all .2s}@media only screen and (max-width:991px){.content-wrapper{width:-webkit-calc(100%);width:calc(100%);left:0;padding-left:0;margin-left:0;margin-top:4.7rem}.container-fluid{padding-left:20px;padding-right:20px}.row{margin-left:-20px;margin-right:-20px}#menu-button{margin-right:20px;padding:0}.navbar-brand{margin-left:20px;padding-left:0}}.bot-logo{margin-bottom:.5rem}@media only screen and (min-width:1200px){#page-cover{display:none}.bot-logo{margin-left:15px}}@media only screen and (max-width:1199px){#globe-svg{height:60px;fill:var(--sg1)}.navbar-collapse.show{-webkit-box-shadow:0 10px 24px rgba(0,0,0,.15);box-shadow:0 10px 24px rgba(0,0,0,.15)}.nav-item:first-child{border-top:1px solid rgba(255,255,255,.35)}#menu-button{margin-right:-webkit-calc(10% + 15px);margin-right:calc(10% + 15px);padding:0}#menu-button:hover{background-color:transparent}.nav-item{height:auto;border-bottom:1px solid rgba(0,0,0,.35);padding-left:-webkit-calc(10% + 15px);padding-left:calc(10% + 15px)}.nav-link{line-height:3rem;padding:0}.nav-link{color:var(--sg1)!important}.nav-item:hover{border-bottom:1px solid rgba(0,0,0,.35)}.navbar-nav{background-color:var(--white2);margin-top:15px}.navbar-nav .active{border-bottom:1px solid rgba(0,0,0,.35)}#language-dropdown .dropdown-menu{width:-webkit-calc(80% + 4rem);width:calc(80% + 4rem);background-color:var(--white)}.dropdown-menu{border:none;margin-top:-20px}.nav-item:last-child{border-bottom:none}.dropdown-menu.show{-webkit-box-shadow:0 4px 24px rgba(100,109,146,.15);box-shadow:0 4px 24px rgba(100,109,146,.15);margin-bottom:1rem;margin-top:-.5rem}.dropdown-item{padding-left:15px;font-weight:300}.navbar-nav{position:relative;right:0}.long-form input{width:100%}}@media only screen and (max-width:991px){.nav-item{padding-left:20px;padding-right:20px}#language-dropdown{padding-left:20px}#language-dropdown .dropdown-menu{width:100%}#menu-button{margin-right:20px;padding:0}.navbar{padding-top:.25rem;padding-bottom:.25rem}.logo{height:1.8rem}.anchor{top:-55px}}@media only screen and (max-width:556px){#legal-1{width:100%}.legal-links{position:inherit;margin-left:20px;margin-bottom:1em}}@media only screen and (max-width:375px){#legal-1 p{display:block}}.lds-ring{display:inline-block;position:relative;width:18px;height:18px;padding-top:2px}#email-subscribe-form .lds-ring{padding-top:1px}.lds-ring div{-webkit-box-sizing:border-box;box-sizing:border-box;display:block;position:absolute;width:18px;height:18px;border:2px solid var(--b2);-webkit-border-radius:50%;border-radius:50%;-webkit-animation:lds-ring 1.2s cubic-bezier(.5,0,.5,1) infinite;animation:lds-ring 1.2s cubic-bezier(.5,0,.5,1) infinite;border-color:var(--b2) transparent transparent transparent}.lds-ring div:nth-child(1){-webkit-animation-delay:-.45s;animation-delay:-.45s}.lds-ring div:nth-child(2){-webkit-animation-delay:-.3s;animation-delay:-.3s}.lds-ring div:nth-child(3){-webkit-animation-delay:-.15s;animation-delay:-.15s}@-webkit-keyframes lds-ring{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes lds-ring{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}#email-subscribe-form .sub-arrow{padding-top:2px}.sub-arrow{display:inline-block}.sub-load{display:none} \ No newline at end of file diff --git a/2.0/documentation/tdenginedocs-en/super-table/index.html b/2.0/documentation/tdenginedocs-en/super-table/index.html deleted file mode 100644 index 0e47a7bb9b..0000000000 --- a/2.0/documentation/tdenginedocs-en/super-table/index.html +++ /dev/null @@ -1,95 +0,0 @@ -Documentation | Taos Data
      Back

      STable: Super Table

      -

      "One Table for One Device" design can improve the insert/query performance significantly for a single device. But it has a side effect, the aggregation of multiple tables becomes hard. To reduce the complexity and improve the efficiency, TDengine introduced a new concept: STable (Super Table).

      -

      What is a Super Table

      -

      STable is an abstract and a template for a type of device. A STable contains a set of devices (tables) that have the same schema or data structure. Besides the shared schema, a STable has a set of tags, like the model, serial number and so on. Tags are used to record the static attributes for the devices and are used to group a set of devices (tables) for aggregation. Tags are metadata of a table and can be added, deleted or changed.

      -

      TDengine does not save tags as a part of the data points collected. Instead, tags are saved as metadata. Each table has a set of tags. To improve query performance, tags are all cached and indexed. One table can only belong to one STable, but one STable may contain many tables.

      -

      Like a table, you can create, show, delete and describe STables. Most query operations on tables can be applied to STable too, including the aggregation and selector functions. For queries on a STable, if no tags filter, the operations are applied to all the tables created via this STable. If there is a tag filter, the operations are applied only to a subset of the tables which satisfy the tag filter conditions. It will be very convenient to use tags to put devices into different groups for aggregation.

      -

      Create a STable

      -

      Similiar to creating a standard table, syntax is:

      -
      CREATE TABLE <stable_name> (<field_name> TIMESTAMP, field_name1 field_type, ...) TAGS(tag_name tag_type, ...)
      -

      New keyword "tags" is introduced, where tag_name is the tag name, and tag_type is the associated data type.

      -

      Note:

      -
        -
      1. The bytes of all tags together shall be less than 512
      2. -
      3. Tag's data type can not be time stamp or nchar
      4. -
      5. Tag name shall be different from the field name
      6. -
      7. Tag name shall not be the same as system keywords
      8. -
      9. Maximum number of tags is 6
      10. -
      -

      For example:

      -
      create table thermometer (ts timestamp, degree float) 
      -tags (location binary(20), type int)
      -

      The above statement creates a STable thermometer with two tag "location" and "type"

      -

      Create a Table via STable

      -

      To create a table for a device, you can use a STable as its template and assign the tag values. The syntax is:

      -
      CREATE TABLE <tb_name> USING <stb_name> TAGS (tag_value1,...)
      -

      You can create any number of tables via a STable, and each table may have different tag values. For example, you create five tables via STable thermometer below:

      -
       create table t1 using thermometer tags ('beijing', 10);
      - create table t2 using thermometer tags ('beijing', 20);
      - create table t3 using thermometer tags ('shanghai', 10);
      - create table t4 using thermometer tags ('shanghai', 20);
      - create table t5 using thermometer tags ('new york', 10);
      -

      Aggregate Tables via STable

      -

      You can group a set of tables together by specifying the tags filter condition, then apply the aggregation operations. The result set can be grouped and ordered based on tag value. Syntax is:

      -
      SELECT function<field_name>, ... 
      - FROM <stable_name> 
      - WHERE <tag_name> <[=|<=|>=|<>] values..> ([AND|OR] ...
      - INTERVAL (<time range>)
      - GROUP BY <tag_name>, <tag_name> ... 
      - ORDER BY <tag_name> <asc|desc>
      - SLIMIT <group_limit>
      - SOFFSET <group_offset>
      - LIMIT <record_limit>
      - OFFSET <record_offset>
      -

      For the time being, STable supports only the following aggregation/selection functions: sum, count, avg, first, last, min, max, top, bottom, and the projection operations, the same syntax as a standard table. Arithmetic operations are not supported, embedded queries not either.

      -

      INTERVAL is used for the aggregation over a time range.

      -

      If GROUP BY is not used, the aggregation is applied to all the selected tables, and the result set is output in ascending order of the timestamp, but you can use "ORDER BY _c0 ASC|DESC" to specify the order you like.

      -

      If GROUP BY is used, the aggregation is applied to groups based on tags. Each group is aggregated independently. Result set is a group of aggregation results. The group order is decided by ORDER BY . Inside each group, the result set is in the ascending order of the time stamp.

      -

      SLIMIT/SOFFSET are used to limit the number of groups and starting group number.

      -

      LIMIT/OFFSET are used to limit the number of records in a group and the starting rows.

      -

      Example 1:

      -

      Check the average, maximum, and minimum temperatures of Beijing and Shanghai, and group the result set by location and type. The SQL statement shall be:

      -
      SELECT COUNT(*), AVG(degree), MAX(degree), MIN(degree)
      -FROM thermometer
      -WHERE location='beijing' or location='tianjin'
      -GROUP BY location, type 
      -

      Example 2:

      -

      List the number of records, average, maximum, and minimum temperature every 10 minutes for the past 24 hours for all the thermometers located in Beijing with type 10. The SQL statement shall be:

      -
      SELECT COUNT(*), AVG(degree), MAX(degree), MIN(degree)
      -FROM thermometer
      -WHERE name='beijing' and type=10 and ts>=now-1d
      -INTERVAL(10M)
      -

      Create Table Automatically

      -

      Insert operation will fail if the table is not created yet. But for STable, TDengine can create the table automatically if the application provides the STable name, table name and tags' value when inserting data points. The syntax is:

      -
      INSERT INTO <tb_name> USING <stb_name> TAGS (<tag1_value>, ...) VALUES (field_value, ...) (field_value, ...) ... <tb_name2> USING <stb_name2> TAGS(<tag1_value2>, ...) VALUES (<field1_value1>, ...) ...;
      -

      When inserting data points into table tb_name, the system will check if table tb_name is created or not. If it is already created, the data points will be inserted as usual. But if the table is not created yet, the system will create the table tb_bame using STable stb_name as the template with the tags. Multiple tables can be specified in the SQL statement.

      -

      Management of STables

      -

      After you can create a STable, you can describe, delete, change STables. This section lists all the supported operations.

      -

      Show STables in current DB

      -
      show stables;
      -

      It lists all STables in current DB, including the name, created time, number of fileds, number of tags, and number of tables which are created via this STable.

      -

      Describe a STable

      -
      DESCRIBE <stable_name>
      -

      It lists the STable's schema and tags

      -

      Drop a STable

      -
      DROP TABLE <stable_name>
      -

      To delete a STable, all the tables created via this STable will be deleted.

      -

      List the Associated Tables of a STable

      -
      SELECT TBNAME,[TAG_NAME, ...] FROM <stable_name> WHERE <tag_name> <[=|=<|>=|<>] values..> ([AND|OR] ...)
      -

      It will list all the tables which satisfy the tag filter conditions. The tables are all created from this specific STable. TBNAME is a new keyword introduced, it is the table name associated with the STable.

      -
      SELECT COUNT(TBNAME) FROM <stable_name> WHERE <tag_name> <[=|=<|>=|<>] values..> ([AND|OR] ...)
      -

      The above SQL statement will list the number of tables in a STable, which satisfy the filter condition.

      -

      Management of Tags

      -

      You can add, delete and change the tags for a STable, and you can change the tag value of a table. The SQL commands are listed below.

      -

      Add a Tag

      -
      ALTER TABLE <stable_name> ADD TAG <new_tag_name> <TYPE>
      -

      It adds a new tag to the STable with a data type. The maximum number of tags is 6.

      -

      Drop a Tag

      -
      ALTER TABLE <stable_name> DROP TAG <tag_name>
      -

      It drops a tag from a STable. The first tag could not be deleted, and there must be at least one tag.

      -

      Change a Tag's Name

      -
      ALTER TABLE <stable_name> CHANGE TAG <old_tag_name> <new_tag_name>
      -

      It changes the name of a tag from old to new.

      -

      Change the Tag's Value

      -
      ALTER TABLE <table_name> SET TAG <tag_name>=<new_tag_value>
      -

      It changes a table's tag value to a new one.

      Back
      diff --git a/2.0/documentation/tdenginedocs-en/taos-sql/index.html b/2.0/documentation/tdenginedocs-en/taos-sql/index.html deleted file mode 100644 index 6b73a70cd6..0000000000 --- a/2.0/documentation/tdenginedocs-en/taos-sql/index.html +++ /dev/null @@ -1,423 +0,0 @@ -Documentation | Taos Data
      Back

      TAOS SQL

      -

      TDengine provides a SQL like query language to insert or query data. You can execute the SQL statements through TDengine Shell, or through C/C++, Java(JDBC), Python, Restful, Go APIs to interact with the taosd service.

      -

      Before reading through, please have a look at the conventions used for syntax descriptions here in this documentation.

      -
        -
      • Squared brackets ("[]") indicate optional arguments or clauses
      • -
      • Curly braces ("{}") indicate that one member from a set of choices in the braces must be chosen
      • -
      • A single verticle line ("|") works a separator for multiple optional args or clauses
      • -
      • Dots ("…") means repeating for as many times
      • -
      -

      Data Types

      -

      Timestamp

      -

      The timestamp is the most important data type in TDengine. The first column of each table must be TIMESTAMP type, but other columns can also be TIMESTAMP type. The following rules for timestamp:

      -
        -
      • String Format: 'YYYY-MM-DD HH:mm:ss.MS', which represents the year, month, day, hour, minute and second and milliseconds. For example,'2017-08-12 18:52:58.128' is a valid timestamp string. Note: timestamp string must be quoted by either single quote or double quote.

      • -
      • Epoch Time: a timestamp value can also be a long integer representing milliseconds since the epoch. For example, the values in the above example can be represented as an epoch 1502535178128 in milliseconds. Please note the epoch time doesn't need any quotes.

      • -
      • Internal FunctionNOW : this is the current time of the server

      • -
      • If timestamp is 0 when inserting a record, timestamp will be set to the current time of the server

      • -
      • Arithmetic operations can be applied to timestamp. For example: now-2h represents a timestamp which is 2 hours ago from the current server time. Units include a (milliseconds), s (seconds), m (minutes), h (hours), d (days), w (weeks), n (months), y (years). NOW can be used in either insertions or queries.

      • -
      -

      Default time precision is millisecond, you can change it to microseocnd by setting parameter enableMicrosecond in system configuration. For epoch time, the long integer shall be microseconds since the epoch. For the above string format, MS shall be six digits.

      -

      Data Types

      -

      The full list of data types is listed below. For string types of data, we will use M to indicate the maximum length of that type.

      -
      - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      Data TypeBytesNote
      1TINYINT1A nullable integer type with a range of [-127, 127]​
      2SMALLINT2A nullable integer type with a range of [-32767, 32767]​
      3INT4A nullable integer type with a range of [-2^31+1, 2^31-1 ]
      4BIGINT8A nullable integer type with a range of [-2^59, 2^59 ]​
      5FLOAT4A standard nullable float type with 6 -7 significant digits and a range of [-3.4E38, 3.4E38]
      6DOUBLE8A standard nullable double float type with 15-16 significant digits and a range of [-1.7E308, 1.7E308]​
      7BOOL1A nullable boolean type, [true, false]
      8TIMESTAMP8A nullable timestamp type with the same usage as the primary column timestamp
      9BINARY(M)MA nullable string type whose length is M, any exceeded chars will be automatically truncated. This type of string only supports ASCii encoded chars.
      10NCHAR(M)4 * MA nullable string type whose length is M, any exceeded chars will be truncated. The NCHAR type supports Unicode encoded chars.
      -

      All the keywords in a SQL statement are case-insensitive, but strings values are case-sensitive and must be quoted by a pair of ' or ". To quote a ' or a " , you can use the escape character \.

      -

      Database Management

      -
        -
      • Create a Database

        -
        CREATE DATABASE [IF NOT EXISTS] db_name [KEEP keep]
        -

        Option: KEEP is used for data retention policy. The data records will be removed once keep-days are passed. There are more parameters related to DB storage, please check system configuration.

      • -
      • Use a Database

        -
        USE db_name
        -

        Use or switch the current database.

      • -
      • Drop a Database

        -
        DROP DATABASE [IF EXISTS] db_name
        -

        Remove a database, all the tables inside the DB will be removed too, be careful.

      • -
      • List all Databases

        -
        SHOW DATABASES
      • -
      -

      Table Management

      -
        -
      • Create a Table

        -
        CREATE TABLE [IF NOT EXISTS] tb_name (timestamp_field_name TIMESTAMP, field1_name data_type1 [, field2_name data_type2 ...])
        -

        Note: 1) the first column must be timstamp, and system will set it as the primary key; 2) the record size is limited to 4096 bytes; 3) for binary or nachr data type, the length shall be specified, for example, binary(20), it means 20 bytes.

      • -
      • Drop a Table

        -
        DROP TABLE [IF EXISTS] tb_name
      • -
      • **List all Tables **

        -
        SHOW TABLES [LIKE tb_name_wildcar]
        -

        It shows all tables in the current DB. Note: wildcard character can be used in the table name to filter tables. Wildcard character: 1) ’%’ means 0 to any number of characters; 2)’_’ underscore means exactly one character.

      • -
      • Print Table Schema

        -
        DESCRIBE tb_name
      • -
      • Add a Column

        -
        ALTER TABLE tb_name ADD COLUMN field_name data_type
      • -
      • Drop a Column

        -
        ALTER TABLE tb_name DROP COLUMN field_name 
        -

        If the table is created via [Super Table](), the schema can only be changed via STable. But for tables not created from STable, you can change their schema directly.

      • -
      -

      Tips: You can apply an operation on a table not in the current DB by concatenating DB name with the character '.', then with table name. For example, 'demo.tb1' means the operation is applied to table tb1 in DB demo although demo is not the current selected DB.

      -

      Inserting Records

      -
        -
      • Insert a Record

        -
        INSERT INTO tb_name VALUES (field_value, ...);
        -

        Insert a data record into table tb_name

      • -
      • Insert a Record with Selected Columns

        -
        INSERT INTO tb_name (field1_name, ...) VALUES(field1_value, ...)
        -

        Insert a data record into table tb_name, with data in selected columns. If a column is not selected, the system will put NULL there. First column (time stamp ) cant not be null, it must be inserted.

      • -
      • Insert a Batch of Records

        -
        INSERT INTO tb_name VALUES (field1_value1, ...) (field1_value2, ...)...;
        -

        Insert multiple data records to the table

      • -
      • Insert a Batch of Records with Selected Columns

        -
        INSERT INTO tb_name (field1_name, ...) VALUES(field1_value1, ...) (field1_value2, ...)
      • -
      • Insert Records into Multiple Tables

        -
        INSERT INTO tb1_name VALUES (field1_value1, ...)(field1_value2, ...)... 
        -            tb2_name VALUES (field1_value1, ...)(field1_value2, ...)...;
        -

        Insert data records into table tb1_name and tb2_name

      • -
      • Insert Records into Multiple Tables with Selected Columns

        -
        INSERT INTO tb1_name (tb1_field1_name, ...) VALUES (field1_value1, ...) (field1_value1, ...)
        -            tb2_name (tb2_field1_name, ...) VALUES(field1_value1, ...) (field1_value2, ...)
      • -
      -

      Note: For a table, the new record must have timestamp bigger than the last data record, otherwise, it will be thrown away. If timestamp is 0, the time stamp will be set to the system time on server.

      -

      IMPORT: If you do want to insert a historical data record into a table, use IMPORT command instead of INSERT. IMPORT has the same syntax as INSERT. If you want to import a batch of historical records, the records shall be ordered in the timestamp, otherwise, TDengine won't handle it in the right way.

      -

      Data Query

      -

      Query Syntax:

      -
      SELECT {* | expr_list} FROM tb_name
      -    [WHERE where_condition]
      -    [ORDER BY _c0 { DESC | ASC }]
      -    [LIMIT limit [, OFFSET offset]]
      -    [>> export_file]
      -
      -SELECT function_list FROM tb_name
      -    [WHERE where_condition]
      -    [LIMIT limit [, OFFSET offset]]
      -    [>> export_file]
      -
        -
      • To query a table, use * to select all data from a table; or a specified list of expressions expr_list of columns. The SQL expression can contain alias and arithmetic operations between numeric typed columns.
      • -
      • For the WHERE conditions, use logical operations to filter the timestamp column and all numeric columns, and wild cards to filter the two string typed columns.
      • -
      • Sort the result set by the first column timestamp _c0 (or directly use the timestamp column name) in either descending or ascending order (by default). "Order by" could not be applied to other columns.
      • -
      • Use LIMIT and OFFSET to control the number of rows returned and the starting position of the retrieved rows. LIMIT/OFFSET is applied after "order by" operations.
      • -
      • Export the retrieved result set into a CSV file using >>. The target file's full path should be explicitly specified in the statement.
      • -
      -

      Supported Operations of Data Filtering:

      -
      - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
      OperationNoteApplicable Data Types
      >larger thantimestamp and all numeric types
      <smaller thantimestamp and all numeric types
      >=larger than or equal totimestamp and all numeric types
      <=smaller than or equal totimestamp and all numeric types
      =equal toall types
      <>not equal toall types
      %match with any char sequencesbinary nchar
      _match with a single charbinary nchar
      -
        -
      1. For two or more conditions, only AND is supported, OR is not supported yet.
      2. -
      3. For filtering, only a single range is supported. For example, value>20 and value<30 is valid condition, but value<20 AND value<>5 is invalid condition
      4. -
      -

      Some Examples

      -
        -
      • For the examples below, table tb1 is created via the following statements

        -
        CREATE TABLE tb1 (ts timestamp, col1 int, col2 float, col3 binary(50))
      • -
      • Query all the records in tb1 in the last hour:

        -
        SELECT * FROM tb1 WHERE ts >= NOW - 1h
      • -
      • Query all the records in tb1 between 2018-06-01 08:00:00.000 and 2018-06-02 08:00:00.000, and filter out only the records whose col3 value ends with 'nny', and sort the records by their timestamp in a descending order:

        -
        SELECT * FROM tb1 WHERE ts > '2018-06-01 08:00:00.000' AND ts <= '2018-06-02 08:00:00.000' AND col3 LIKE '%nny' ORDER BY ts DESC
      • -
      • Query the sum of col1 and col2 as alias 'complex_metric', and filter on the timestamp and col2 values. Limit the number of returned rows to 10, and offset the result by 5.

        -
        SELECT (col1 + col2) AS 'complex_metric' FROM tb1 WHERE ts > '2018-06-01 08:00:00.000' and col2 > 1.2 LIMIT 10 OFFSET 5
      • -
      • Query the number of records in tb1 in the last 10 minutes, whose col2 value is larger than 3.14, and export the result to file /home/testoutpu.csv.

        -
        SELECT COUNT(*) FROM tb1 WHERE ts >= NOW - 10m AND col2 > 3.14 >> /home/testoutpu.csv
      • -
      -

      SQL Functions

      -

      Aggregation Functions

      -

      TDengine supports aggregations over numerical values, they are listed below:

      -
        -
      • COUNT

        -
        SELECT COUNT([*|field_name]) FROM tb_name [WHERE clause]
        -

        Function: return the number of rows.
        -Return Data Type: integer.
        -Applicable Data Types: all.
        -Applied to: table/STable.
        -Note: 1) * can be used for all columns, as long as a column has non-NULL value, it will be counted; 2) If it is on a specific column, only rows with non-NULL value will be counted

      • -
      • AVG

        -
        SELECT AVG(field_name) FROM tb_name [WHERE clause]
        -

        Function: return the average value of a specific column.
        -Return Data Type: double.
        -Applicable Data Types: all types except timestamp, binary, nchar, bool.
        -Applied to: table/STable.

      • -
      • WAVG

        -
        SELECT WAVG(field_name) FROM tb_name WHERE clause
        -

        Function: return the time-weighted average value of a specific column
        -Return Data Type: double
        -Applicable Data Types: all types except timestamp, binary, nchar, bool
        -Applied to: table/STable

      • -
      • SUM

        -
        SELECT SUM(field_name) FROM tb_name [WHERE clause]
        -

        Function: return the sum of a specific column.
        -Return Data Type: long integer or double.
        -Applicable Data Types: all types except timestamp, binary, nchar, bool.
        -Applied to: table/STable.

      • -
      • STDDEV

        -
        SELECT STDDEV(field_name) FROM tb_name [WHERE clause]
        -

        Function: return the standard deviation of a specific column.
        -Return Data Type: double.
        -Applicable Data Types: all types except timestamp, binary, nchar, bool.
        -Applied to: table.

      • -
      • LEASTSQUARES

        -
        SELECT LEASTSQUARES(field_name) FROM tb_name [WHERE clause]
        -

        Function: performs a linear fit to the primary timestamp and the specified column. -Return Data Type: return a string of the coefficient and the interception of the fitted line.
        -Applicable Data Types: all types except timestamp, binary, nchar, bool.
        -Applied to: table.
        -Note: The timestmap is taken as the independent variable while the specified column value is taken as the dependent variables.

      • -
      -

      Selector Functions

      -
        -
      • MIN

        -
        SELECT MIN(field_name) FROM {tb_name | stb_name} [WHERE clause]
        -

        Function: return the minimum value of a specific column.
        -Return Data Type: the same data type.
        -Applicable Data Types: all types except timestamp, binary, nchar, bool.
        -Applied to: table/STable.

      • -
      • MAX

        -
        SELECT MAX(field_name) FROM { tb_name | stb_name } [WHERE clause]
        -

        Function: return the maximum value of a specific column.
        -Return Data Type: the same data type.
        -Applicable Data Types: all types except timestamp, binary, nchar, bool.
        -Applied to: table/STable.

      • -
      • FIRST

        -
        SELECT FIRST(field_name) FROM { tb_name | stb_name } [WHERE clause]
        -

        Function: return the first non-NULL value.
        -Return Data Type: the same data type.
        -Applicable Data Types: all types.
        -Applied to: table/STable.
        -Note: To return all columns, use first(*).

      • -
      • LAST

        -
        SELECT LAST(field_name) FROM { tb_name | stb_name } [WHERE clause]
        -

        Function: return the last non-NULL value.
        -Return Data Type: the same data type.
        -Applicable Data Types: all types.
        -Applied to: table/STable.
        -Note: To return all columns, use last(*).

      • -
      • TOP

        -
        SELECT TOP(field_name, K) FROM { tb_name | stb_name } [WHERE clause]
        -

        Function: return the k largest values.
        -Return Data Type: the same data type.
        -Applicable Data Types: all types except timestamp, binary, nchar, bool.
        -Applied to: table/STable.
        -Note: 1) valid range of K: 1≤k≤100; 2) the associated time stamp will be returned too.

      • -
      • BOTTOM

        -
        SELECT BOTTOM(field_name, K) FROM { tb_name | stb_name } [WHERE clause]
        -

        Function: return the k smallest values.
        -Return Data Type: the same data type.
        -Applicable Data Types: all types except timestamp, binary, nchar, bool.
        -Applied to: table/STable.
        -Note: 1) valid range of K: 1≤k≤100; 2) the associated timestamp will be returned too.

      • -
      • PERCENTILE

        -
        SELECT PERCENTILE(field_name, P) FROM { tb_name | stb_name } [WHERE clause]
        -

        Function: the value of the specified column below which P percent of the data points fall.
        -Return Data Type: the same data type.
        -Applicable Data Types: all types except timestamp, binary, nchar, bool.
        -Applied to: table/STable.
        -Note: The range of P is [0, 100]. When P=0 , PERCENTILE returns the equal value as MIN; when P=100, PERCENTILE returns the equal value as MAX.

      • -
      • LAST_ROW

        -
        SELECT LAST_ROW(field_name) FROM { tb_name | stb_name } 
        -

        Function: return the last row.
        -Return Data Type: the same data type.
        -Applicable Data Types: all types.
        -Applied to: table/STable.
        -Note: different from last, last_row returns the last row even it has NULL value.

      • -
      -

      Transformation Functions

      -
        -
      • DIFF

        -
        SELECT DIFF(field_name) FROM tb_name [WHERE clause]
        -

        Function: return the difference between successive values of the specified column.
        -Return Data Type: the same data type.
        -Applicable Data Types: all types except timestamp, binary, nchar, bool.
        -Applied to: table.

      • -
      • SPREAD

        -
        SELECT SPREAD(field_name) FROM { tb_name | stb_name } [WHERE clause]
        -

        Function: return the difference between the maximum and the mimimum value.
        -Return Data Type: the same data type.
        -Applicable Data Types: all types except timestamp, binary, nchar, bool.
        -Applied to: table/STable.
        -Note: spread gives the range of data variation in a table/supertable; it is equivalent to MAX() - MIN()

      • -
      • Arithmetic Operations

        -
        SELECT field_name [+|-|*|/|%][Value|field_name] FROM { tb_name | stb_name }  [WHERE clause]
        -

        Function: arithmetic operations on the selected columns.
        -Return Data Type: double.
        -Applicable Data Types: all types except timestamp, binary, nchar, bool.
        -Applied to: table/STable.
        -Note: 1) bracket can be used for operation priority; 2) If a column has NULL value, the result is NULL.

      • -
      -

      Downsampling

      -

      Time-series data are usually sampled by sensors at a very high frequency, but more often we are only interested in the downsampled, aggregated data of each timeline. TDengine provides a convenient way to downsample the highly frequently sampled data points as well as filling the missing data with a variety of interpolation choices.

      -
      SELECT function_list FROM tb_name 
      -  [WHERE where_condition]
      -  INTERVAL (interval)
      -  [FILL ({NONE | VALUE | PREV | NULL | LINEAR})]
      -
      -SELECT function_list FROM stb_name 
      -  [WHERE where_condition]
      -  [GROUP BY tags]
      -  INTERVAL (interval)
      -  [FILL ({ VALUE | PREV | NULL | LINEAR})]
      -

      The downsampling time window is defined by interval, which is at least 10 milliseconds. The query returns a new series of downsampled data that has a series of fixed timestamps with an increment of interval.

      -

      For the time being, only function count, avg, sum, stddev, leastsquares, percentile, min, max, first, last are supported. Functions that may return multiple rows are not supported.

      -

      You can also use FILL to interpolate the intervals that don't contain any data.FILL currently supports four different interpolation strategies which are listed below:

      -
      - - - - - - - - - - - - - - - - - - - - - - - - -
      InterpolationUsage
      FILL(VALUE, val1 [, val2, ...])Interpolate with specified constants
      FILL(PREV)Interpolate with the value at the previous timestamp
      FILL(LINEAR)Linear interpolation with the non-null values at the previous timestamp and at the next timestamp
      FILL(NULL)Interpolate with NULL value
      -

      A few downsampling examples:

      -
        -
      • Find the number of data points, the maximum value of col1 and minimum value of col2 in a tb1 for every 10 minutes in the last 5 hours:

        -
        SELECT COUNT(*), MAX(col1), MIN(col2) FROM tb1 WHERE ts > NOW - 5h INTERVAL (10m)
      • -
      • Fill the above downsampling results using constant-value interpolation:

        -
        SELECT COUNT(*), MAX(col1), MIN(col2) FROM tb1 WHERE ts > NOW - 5h INTERVAL(10m) FILL(VALUE, 0, 1, -1)
        -

        Note that the number of constant values in FILL() should be equal or fewer than the number of functions in the SELECT clause. Exceeding fill constants will be ignored.

      • -
      • Fill the above downsampling results using PREV interpolation:

        -
        SELECT COUNT(*), MAX(col1), MIN(col2) FROM tb1 WHERE ts > NOW - 5h INTERVAL(10m) FILL(PREV)
        -

        This will interpolate missing data points with the value at the previous timestamp.

      • -
      • Fill the above downsampling results using NULL interpolation:

        -
        SELECT COUNT(*), MAX(col1), MIN(col2) FROM tb1 WHERE ts > NOW - 5h INTERVAL(10m) FILL(NULL)
        -

        Fill NULL to the interpolated data points.

      • -
      -

      Notes:

      -
        -
      1. FILL can generate tons of interpolated data points if the interval is small and the queried time range is large. So always remember to specify a time range when using interpolation. For each query with interpolation, the result set can not exceed 10,000,000 records.
      2. -
      3. The result set will always be sorted by time in ascending order.
      4. -
      5. If the query object is a supertable, then all the functions will be applied to all the tables that qualify the WHERE conditions. If the GROUP BY clause is also applied, the result set will be sorted ascendingly by time in each single group, otherwise, the result set will be sorted ascendingly by time as a whole.
      6. -
      Back
      \ No newline at end of file diff --git a/2.0/documentation/webdocs/assets/Picture2.png b/2.0/documentation/webdocs/assets/Picture2.png deleted file mode 100644 index 715a8bd37ee9fe7e96eacce4e7ff563fedeefbee..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 44198 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 z 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 XT_z57}q-MQIJeG}1I$A3nj?_6} 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 DyGmMe diff --git a/2.0/documentation/webdocs/assets/add_datasource1.jpg b/2.0/documentation/webdocs/assets/add_datasource1.jpg deleted file mode 100644 index 1f0f5110f312c57f3ec1788bbc02f04fac6ac142..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 54717 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 Qs%QM#$Nyd4!TZDi0h#xeEC2ui diff --git a/2.0/documentation/webdocs/assets/add_datasource3.jpg b/2.0/documentation/webdocs/assets/add_datasource3.jpg deleted file mode 100644 index 1d8a4a5d7644e9fb6dfbd86ed897cdaf2093148f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 43325 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 OKi`eNfz`oBWB&^^xKjZD diff --git a/2.0/documentation/webdocs/assets/add_datasource4.jpg b/2.0/documentation/webdocs/assets/add_datasource4.jpg deleted file mode 100644 index befb4243414554f24d165688f5117f1e70f8f21d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 55224 zcmeFZ2UrwMw=UY`s33wQ2};gL5Jg~6BukbIj)-Ill94cg3X&x&2!rH|NEQUim_V}R zoZ|q(zzj3D2S4@u_x{gw_P+Prea_j>-`YK^x>r}|UiDVhT5p5>j-3Xm)s$3~06aVZ zPyzn|*cm`x(c8`%05miJegFVS0lZK?x6evl!d(9U2t+2DAT%v6$IsRoNV(`-p0xIPGo#sQ)pdp>nebckpYyc@BNf{ zak9-%`3g?9w6(Yo>VWSA5d2vOPyzrlm7DBRqF05kpQQd59vmNdfbBflaBrH@%1K`j z{G|r>^Ppwi1lR#7KoqzN2m#mKt-QhZ0)T?Ei;t_FjjcQTb@0hru`4(`x_G!-xeBtY zI#~(}vWtmc62dsZfba|v&4o+XiO=d-kX(F7D;5;{nv~;4c{81E?>49SJ=b6| z@^kbIj7(hIJiL7T5|Wptu3VK?xT&b5tfH!>cU#}U5Ny8XeJg7lTRVFFjlN@iAePHtX)LE+nq%Bt#`+PZfwt!?ccon0S4_4N-74h?@F z8J(G(n_pO5T3%U2?CkFS*grrX9^u-B2N3*h7I^&GvVYUAGhn;$2?+@ZNpS7L!}kJr zf-{6f7cLRgT-PD7czE`rSP&`gjo8=a&14+ny4!U3TzkpSaZ1c^A#hDQY1x0QVZr~e zTK2nPf7&$$C;<2;8v#B(0TBTK0TD3~xDk^Q<2F)q(vyw+uZ{9#JB{0@es5SX6Fe{v zLPA0k@IN&L83px!dc#hD;CKf+3Q!W@fyP8|27mw<*mCB(DFSaPePqyVgb0~!oC3?n zJ{AzlyH_3~#H935-?F7ZhQN5JgvrH&dp)i`KxMgQ#@?`qNy5@cH9OgJPkpglEgU7K zd>rLxkdh)5F8P_lk)NH_Sm;Zfiu^(X8I5Rz%_2{9t*k&FhR54x-vjYJH+5!>iq0;8 zt+6k;E7;dFYHlZx<8y2c|8wS7$z4~M7A1E)yobp)EH$GR(>M95Scm&}AnL719I%YXahZBlB zGTRL#5Or+OI?}GH30|mIi6N&^9LMGK`ap^4amywSCBiCc z3&P!ikJA;!ow|<8j0|^Z0WSuUtC^?)YF9JE0Wmu<+w2Si?&y!;&dwkjw;i|phqK(^MJXmJU0v-C2`8~5DN!zilb^k zz(4%_(~|*Pk2D58@#3Khqi2@1M5o@O!hXZR)`kLzOxF(B=w$>OnWNIzp^6QK z^b`b_M_#t{sr{1XWHb+)h-ppESLdt^x?2&M#gj zu&MzR&hA>;O78lZN0ulEm&nM{8yM8^5BrNaPSguj`%97NWXW`g)|9NzX2Yd&i|#~K z)qh`ZdH|<)&|W=~YVjwnMfs_^xyHu7^Gs4WPyNdCQxgB9xV$Q#`%@G!n<;`Rp2rw& zWQDdf4X zj^a^n3#)|-KACha)OJ<=;G)UTP+U)SURIgZ#B7s|robb+(yws%QFe(#y)mTk%93Q< z*N0bLY48rFKAhKU5~-*_>JLtAET*lOj@@}bCqiHkC71Ap6Rt6(IHcnvtX>U2lEuiY zh`f&MArRrb@O*~ZZgdqDdZP+47*K*XLh_Z^PL&&kWh3LfOC)0`o>eiPTNpGI?n|mR z=wj~W9;LN;sFB6_7@Cl{*T}Zy(mAuHA35;KhPS#>cVQH|zvt*{_j-qw-NKw{&n~~V zGxkdE=4^T?{i9K_#i}0_{6L#Z`0fm)dBq>`7u7v2k|#GD<%S? z6(vUo;rk`$+Gs#5_@IXC&>%eUk>W7I@*b|^2jbGeFSuyN^?nr`Gz6aQ3zy}64J3fT zfz#myK!nH*0Z~SU0e9~AEjU!cr@?{A(_b+3BzrF>doRP{1Ws@W0~SvCt8iZG6Bq(@ z32*>I_!F7H94UX5l0ldm&Wrauby6E#0Y3o=cOD0Q!0!xyrg$?0|FIS?Ks2cY0p-sP zyqQ6N(2XXXH-qpO5dMXAe?6a*w*IaKzdV=&Uk0wSce!v)JgM=oC-xImf3^HKp5pzz z?I#cMH~OAb;SXfv6i-sPYy;ICrEz__7dH@x1IKre0w@PRE~Mf%L8~0i`-%aN7@Cz> z%{Y^`AWO;vv3HxbiErpF2ptVNZcN{u8wsEZ7{UT?W5OG*yLowJnR-(gMngpJKut{B zxP>s~28-04E?B_XX>&xzaAtuHIpi?yq!sS5$~O?D_BP>F!qLZxBGbe&?$jE+P0@7r zxfOnw1GBqvs->UCw%kTAvgo@*7)d|n0kmO(nMBGXbwTO-gbz%8={zrS_o5Xw&3*`K zJ;0lz)qxgUjrgDEBDHvfSa?FC>ccUIFe*%3RVy*{k@9SLe@zJs#27)wq4NS?9QrGr zkv|?Ew_|S9&$|6vvyJ;d(`*l-IA+eJ75K@)=sxDZHGgqG?Y862ZDn|3ZMWv6rV^E9 zv>)qxN>5``Dh9Q}w<+)Tu8Mvi^>~%Q*0PQpSsQlqLF3(&A=&Qlgq{5%5XJFYwkU!t_G&+3nEc3*?b|!eRZu4HYkGafXPHZ_YAl_eJ_95Q z$@w^^@vn0?qz8dE#H<3uHfLDco^+0h?WGVu#o6O~Q>_@feql*}&E;7E2cr}_C;{hF zc}-wGJd6qgy8*hfP_8np**Y9 zZ$tgJoxq&_sSMYw)_G)be@o+;{+vM%huIbiTYC4n2MQc_VQ&kKjsOkA>g~-spIP1p zE(aUVcWnpi_mT?5Im{{!Z?HoepbJOeh`G4@Ij{g_C`ujHD>u-zm4F3i*HVVDfDK#p zopW%tY6R6|=k@!;!hJ1W(jr@%*@W5ZA&^Tz>??N(QiQbH!31>Qdug38H>$%M9lu_=EHR z{P9u$Gf)rvWt#Xj;R0FP&w8oC+!3>K5?i7^lP@|MK@0K}-$)sHD(uriUo}y>e=+;; z-hyK!DSOJ|?V6g%&zw()^cgwRKaj7;L|tpe0+Q3}8#moUuf2YP1^REup{O>aNnCyC z*4WO#W@yaS=(iO_&h7YDRemeY6fB*3=W;Eixmy}>M<>S)!#41P*_SJ2u(KX5Rb9_m*7 zu~?C7K+|fMgM!HdAO4&Qo*4)n>8CyFZ;7=R5&P_M-pjs*w7iv3(Kyg0<0Y}@lHFXs zguY*|r(O0&(MtbP7OI8(t8IUP`6DcFN14UP$|G-FvSeO~Pp|L|`q>YX^1`Z(Nqj8u z#Awaard@L@`N0pj492sp~Y7;Z__f0n&t)2O$faWC@qt2$^}pcR`y!G#bP zC9!~>DKfzT8MNwlPg@K_>kJhMQrIpx{DOp~c72FO-*so(igRMp%292ck(z^J$%K!# znjs@leI&u`F=WnWgQaMt@!U7GXphIKf;!dB($ZM1g#7Y(mb@kMr)kf~>Eo1^)@x=@ z3CvNoL!uxw?qjmjTF-_NRZCBWerT7npSD32YEmc>l5P^;KKr=pg*Hb=gVwgdzCQxm z?5H>A+$>~z=Uh5%V@=JF#DUNY{&i3Puhjw{iiF$UWvBEhVM^BOl|ixZMVr0 zVYfP4wQqQh;8N%9cc zn@Be8!7WMmv&zh-rkz~loAWB4Ym1$ts$AzqM{@&ZidvdZ!R})La$&w98kJ8Xm+iGor5zaIX^|ZM^E=A>PG~ayieH0H- z)2bB&C3A0j9EL#c2M&4&m=owXILOj#^fu(aZ}3hVy0O8ZKu+m&l~+zz9sg6_wK?bq zDqtCY+V3i&bvnJyr^K7bybeW)u;&jx>eyO53N5`?zjMQ zzlYTO+RW`YTC-Rnlzv$KVV1g#wuVqnTeR+NVSR=T+ntRnbuuL{pdYZb zV*)W;4K=Bqa=b&yW=;LG&ov)7CdzA@yS@$!ztBl}E0uysP+mqI?8fvnkjHSA2aOEK zdpr9}>UALq<{$F%PnGufu3s&H1c zfbB-MjhEFumY~Ss%a2349BaQm3VDhJ_)Z~)kHaF+>&pbw8*KZ2ND2gOwmN3}U|Kn> z>S|?)@X+Q#+oRIl@fPNjYq@{r*Lkas?d~49j^&>=R*0V+U zU2>2dzqA&CKep;3@8cb;%*=aF|8}{7S#a+U$xoP;M&a#_SOjz19TJ4~Yt~qYx%a2n zl!G^K&?F4WTbqYgj&(9|#)s+O zv>37UxX%!oBxej1Snk^dHgcjZ5C`l1)7-~NTM}bs)JU~HSrN0|(xIshNS$Ih-}CO( z@NA`SF?km>OP4_d+ni)iyN1JTXiF1eKre`sF{dXFF#p`C>jf*r zG$xZKUGWMMnz}{{HyF)XT=WwHuamIv2y8+}>yl?|S|K6O3Zd5&ZkfiX+|0@Kg9b%v zEXd9;QuhU=m%n>t*g}gB(Qdkj1;Qa`WwbKU7Rhbt!h=6-`u#*6KC~b9Iyjr^lgQZ? z%g9oFiM2LD!J2U(k-{i1n|1K7Ye};6!0v4ayj+rX)_8^^DU{qkvu$65zzP;aD zul*>}^N~R|p^4wH*w?%l=t^$!2kVxju8#mE*KAg0JCr7xx*A!B*qUj4y*)I^B80hQ zr@g96JbPu)=*s~;C9yarTK@$=@wR;7#jp;dXrC9EgCk2^IzI#CLh0({`S=#r3viW&khWHC1f}*phThEB zhW(U#^){Zg^PgXlURl&cAH*dS#Jy50S98$%#D&dO1z4!+cA%Gip0XDOFk#9W>> zoL9}xBHq~_OtK$8k>gt%P5WY)oRZu|QkUXQo2~m<^sSfoKw+W*XCl#cV2_2DBHb6! zG%eLaArfpt)j1V-R9fVdxylr}@3@d&v>>sqroZh*ldsDpBeu}$tebuMJ!l{>8|a9` zbiy5$ZRO4wx-|rH&a5(ebz?8#X|a1V-`!mK-uk!1M5?-*&0Y^8#RggUcQhavvRRQC z@;+1V(W|#by9C3F@mOCOmSOr}6=e}vz+Q_537dm8N7S?EwFGeYJ0{JpI@HcExm|z0 z=x$k0UQ3zJI5;?%aF>R1;q3mM?V48D7^InvOon+j4W>~!C}HP8GEm}_`B*0!%Dw9n zVl+cu{^kjO4nv|f<5h;40H%PiaFPb|X?WNa4MqT2X4vQ0KtD_NVE$dy?2E7XDya?a z-Y+L-T~Tz8@!lsSI^8~gJ*R&L9OqR7nAq<&`-zBlZ9Vf4c332Z&G$6fQK8O*9i{(i z8sGzK+X{pcNfjHuSv=6s$DlmxIVmO{2qxOyM9>1pS3>jgqFer z39e{EEKnZz84D=cRUL>#1aM(`A#^fAGa}DmZ}q$5i*0N6bwC){Ey;h^zm+V+9-HR@ z@ZQbA>l$TL5C{e!oK1F3L5?VhpJsgX&}htlb-cgBxvbm?YQi`Z&F*kcik&S(C0%7o zz=htkcX!bLA*Zb}K;{y^#Jubgs!}kC8Sg`VDoKBzgX?m0OzQQwn zOAXFEFw;;MV#u&(<&0W=cZzSlN}b|ZKk3>jmAnz%TkFBb!gwSc3`)G`ZJvB2+*tLI zCHB_!jkuOXc50pK?AdQpl%W`uj!AHf=~uBHjT)=yD+J@_pSkrf+MOOe{cwPPn^;v) zzRZC_e?-+GchceJu!F$0L-C$6BG2k!mB(Een7EGzIXgK?d{s9YVEdZxpA>txW1`dT0YMFq~+XH zaQeA#HvJe*KLK#bG^ZE0kQ04?a^1SMGtC?R=1^Nez|qQjQd4u?9lt^BJ#$!bznt6!%1mAOJJM>(IqMcsB z8Jn!U)2t%)AMq|!<&wf+2C# zj#B;UrL;L)C%mn8G3O^o#g9}5^bGnJYW*ebKU%+46K3kSvvy%(f2mC-P=AFm#>GIk z&^Ze7_G??2Z09<%@AC!0FO$LpFJGi*$Fr*DwIk~H&4c+IXO7|NSMmUrh}q*?0zqBl zgx*&U$|wggv}>bEQQRfIUbZpzNqrNhPVwE<;mi3^^T(4dVxMa{#D$fVCBN8}WY~@_ ze66mtm0UB5XbBmeDd~N21z+EdkxPXH$nU;B$B^ME_cCJ6dA*KOx0z}ky>fn9ey+y>^lw2_?} zZy)p=R&+e&cf48E`Eh&abGyM2cgeK;{x|y`FS<6VxKL9*!NL2Uc8TT@$F7O=G+^-p{n zZgS;)l4?NDmG>IkK8lt$j-SXNyrX#Bf#n--{OpgD9COtpoJSCuN#b?pGUf$Ed@Rjp z=9%upK`)e*UACRoae74ks|u-zs*9?!s@&4MS1^DfhOdH-`H#q z`5mOv(df{ow^LR_je0&$U`;ZordlvTq3DH#V8-i&hC=d2M_U+rp7k7XB-_FQ$xfiq zv1%M}IpDKiu^j}oIYEIc0`Dfh3x-!)7UhUFT?FP<)c_PZRTTW~*W%9)9Z+%-V!19W zv&R}nHqoRpl2mA6tr2xh)YNZN=yFdWiYaHFgRNKZe*~lL6>C)u_uqDa2DEMug6=$nPDoC5NbR@FeQ%TvxPy2>1@bMD52M8lz zVSc`|*Luz&TeahF5B|U}k^NFTxo}3uEs&V*HZO1&AaZjDW9Gk{hrlf-VJ4y~JEN8- zZ(mzhUg}U`5wj-;gG6QZGS?6``g%lb2E)uZQ#y;qjH*c z`c<+APEN(D*V4L;&^(HOFLZ+lQDlHbAugk4Pv_ab^V3yksmjT$c_Fm%nvI{nWs@sH z{5;jmXn=vBtpJR#60e+ zeW?GB6Zq%Q{JUL${KlZKRR!m8mB4A-`ZEas^3nbon@?QTzlZI=htN)xmcr^5KW{dXw>SzPEgDu%OFn&8W@B?eD%&-GO zq?45iaqhjdPqq=)ympJuqoM;tRR_2-40*vz*S4klIgrddBFcTI7N!BctkJ z`EV|Y4C0Qnx~h@oL)S6`{k(>>J&D$DQT+C=JZ~84Ps7i`T3BXHp=bP4H{jOB$)Bbc zHg_|<8~2Agq?YoobiQ}3O#I^H%kvnm*?11=IBPVyGqE&8e%;0~ZMXe`L9`D@68bDD z+SSEeL<3ASjSn~Y&%77c>eEcL+Ml?Ov}ci+DCy>?7R%zyXgSNRZ@|tnO}RG*hp&LE znf_Vlh+Xd@H3to~Nz{hanXz^kdc6c=(I=&g>e}`C*%XiCKAkoa-gM}4=B|vx*sZfW zI9SJ~@V-QMM3H?e@DrXTVf@fzrmv<3{IG50GO39|U!NVD;LE8&P|_Rhm~wS=L<({_=~DjHepT_H4(dJ4A2iwHK9GP=0<#fPPYke#6BtBGDgS5DpCfZw8>jzW}JTzXfu-!EJ7;3f98> zdcpz!v&}2VIbn{ewAV56nx{$1%lZV$g5%*MWbO=THa0Z(JwnIeLAi+~|4MNd{e)_)b`oYyvRz^lJk?HqW+m;!CE5B)#;&5Gw@q6CUbUxVV><2 zVvPh9fqv=}^~f^{3$VU{)i!nM-@LUhgkxqDuLUG#zAsWN=LAU+qQ8S*H*kQ=@I3)s zPO;;}lZ6#-Z6=BfChGpg+r7*fHC}lx5YA6@PKX_^!xU+C!AR;amcj|u0wjh#!6CE- z?iK$WH~#&q?@#27@WcRcy0}<1F0RZ4;Bx#K)%-IQ;Np6?)X&=d8z#j+tlEBs@=gYv z-?jL^IaoUM)1nTbkD-^-gZfDhM%DYe|EX`^R^O2FESG#>JS+Ibn zlbn=yCfmppKL^um;w8-Psa`ZR6FmQcU4)?QPY|EAS=--@DbBrh6Us+ zP%Gfnw{@jyaGmFvlFxq-3mmF0BqXlFx6}Q2u|VcSERg66$8aZj@6KG2L0{=P?hu9{ zQ=p@XSYY`a%pZa=g8c9$!vYHAP!AYJ*GHf0(JERVDKB@>Dl~P#^o|Y1WdwZ&CnlLh z8rNgyk}a{o{o;kxS$cHKZPW^Er&a3t3~X60dBPO*5T#41-WhMAkt2HI{R1!SmxY`t{bse2h5ZvFqQ+V9-`HON5q!$V%~Mlw z7M}ah#>8LjSR8@v57Fz-d>Ti&{ROH&b^hu^CzQ8;oRF&!=Jpp5Dr{yZ40c*td3*CIWcYyX64Q03$?1fIaOEN@m{I5n<@KPi2EjdGHJFoo6 zxPRMlSt+&9+p=?Lk_PF)gBH->H2Nqli%@^vaLa4qAe&&JgZMCJDG18tckj*HzJ`ZB z*(X1;n(^`W z=@Mt{0ioCZ4W_Wn(vm!4mF!)KPM?d3jwu>z7u=P&@FwvKm&To%tjh=;(k~)xq65TA zVjka@=LZv0(NTOfz05dS^)8TpcC1c*SpJzyvZXG=IgLgGRXPqwbE=)E)B~_|vA- zeqJ+81TcGzVk2*ZnFi+o#|v>C>Ro45YN}rl)}lC-4B{CqxD5lTdA_L7%MoWb&V^1x zn+qC5s5)Fd+P1H5kB=6uz#Xdn^~+`kAr*udEu1(|S6x}McOrOKuLAC8Fx@cxsWxBB zLCKqMo332^hZ2Kp4QBpO~R{zFY z|2?C@W%kdys;YXpsJ*#F8?hTTQHOFprRRJcAg{dhEYDxl*=iABiA+JcssE8yt}yjb@i&@Y8tuEPv!P+ z+to^Zz!A5XL8cXIZDwhmt<-y}Sz0Pmq`{OpX>_pIFm|jY%j`jj2NmnmuH|7kwaQrY z95)Ettz_O=m~&F-3y|%2Q~$>($OcI0L|t>n0>%qI0U)vRef_Jgj;r0?W%Z5tXoGD@ zFe1`KqI?P^@ZHWcNnAid*uYmMiIIf-I&;GG<6r>@h925lhJ-eKhm4Bs$E-s{ykdoW zq7?756>}79=b8&IM>q)0CvDgcp=N^AKUSef z)L-;iK2nEeHe*0C0l)3(?uifqMbn&nW7R}ZV`=?y1CdRTmap&Es{F#1 zF2WSY)*pn5MeUt#Pn+CxIw-7Pp4yT(s;Zxi_j+$IrP>%+ZsYZyxv=_3>f1R%r-Ll7 z_l8qSNBC{1{0aSo-gklJa&tCon+ztTktOACiQ#VS?y7saz7V&kvM&D-vt4ZPITE6)m_ zhD5@sG0b)cqsmVu8TvH_(zw$5Hv2{~g9{OxY8UFmjfNE0S6|lxal`@z{aC;b9+eW1 zQ@onjcH_uDV3m2T8D?YWf7aYIU&UIb)FSRmx+Hm_rTzzf7CQOuN4x~Xj*Zv+ZdcXx z-_>yTT^?;+t9JY7Ojtv0Pt){LFigCok0|kj-NlK8Iz}r=uAa`aa6@rr{?+GWf*krr zSvBPq!MwvJQTG}t&bt%_iCv6_i`*VVVCO05xw&I06=#e$N)cNBVSt147}{5bmuQrg*uwPvdY2&r8=->3T?*>gNtKI zqsflkqr{5U@s1kRQI&Y7M>VQ0PuXAoMtIHc@&L+qOrCDPxAOK+A^dW9Ij9I2j`EK3 zcZ^>CM&zFv?`Sll^a&`dj(4sy9#MT85d?Lv;-0dvcpH^qMqclqKel1usZ%i;$iK0l zVlvZ2&t4;0jlg8HUl;?pmAXL)BCKX=MrqjAvfGp*0PK)#Lr>@h>Xa@B=zL_&=N zj{8N8=B(y`4p`^=zgVs!-hgFfzd$T4GBj{-%tBlpY}7z znKhU-pgZsL!T$shyDW<$jA0e4_Fe|%aVR?ca!S(zm72_Jc}CPJ=2O4bEV92lD1XY{ z0q^)JW_`+_+z5%cC}HE&ng2%Y)T-2Kaz}$FUTxZXT_W|A-Jyh!gc;>moCbtDhG#VG z!Bc2c z&PTdF__(X83n_y;M68N{m5+7&XOJDK>qCndzmOtRVKS-66RY^)A`WUZJ&t+UoA2kHXbz^kmFa#Mw`&c3t#)xg#hb$iDs>hM}(p(*9oNs)J*4r^y%R0(A4sHtu*?d3mUXDV^4X4$=o0FN# zbwFsffP^J@2Noc<^=xF?UJB2v?thSc|B{5Z#zLNzL6VeX)|+l%`k{W)%xjDU7`iYA z7j?sEEE06gII`e4vFqR6@MAF$;@Ehll@bdOp}pfXyRvQ!ydVam zK00#nE!DD9`<_X`csq>y>7Z26&WQ9-kD0PF$U@(=%Rf9dXxa(o?j0D|W+{#OMovdl z(aj71hR%6r<2eo2xjgXb87x=K6g@Aqt#V)icNl+uP+zUSR zFwpN`gB-f;&)@f>5dUC5`ZX4Sh+%;#M~no_c9m^+SLAqqYVP)O1_gXnI`r2Ky~kPk zu%0hX2V<}(z05%2zo{z!Jr7CEaG>sQx@>>TV^EqGf9dba|0?ibj}&Kk|J#j5nQLPF z^IN;L;ocXqM}v=e0njP*&vyL2JChx+Icj5XyW@2c{K)%TFZfr7`P;+z7bN@!&VPa4 zzs8YYgX+J!#ec(Y@$WuKD}RFpbl6Z?hlVWXQK3iAu)qY{r$Tne&b|^6lOi^?%J=qx z9-vQ_=)Y{g{ibENv2ATQeE^S+?)7o1)WPsBWJY=a!PFG=3l?~Kjp)mffCB2W^H$j+ ztR-fBq^Ys#CHP^CAiel<3Dxf;q{13=gt0;MzA@{`to)tAd`(5I9m2OWo89EXzx_&O z{mL%le_iJ9_QjN*P7Ls_`hbOS%UvZA$7hm|8>o^Xi@=uXK zk@rL*A#_IPDng7Feug82W?l8HW2fRfZ)Kec_wLdtK%Y z8fJmID!$=Q%HfcU9_JPwUJx!x`vS=7KMin|deUG8iQEIfdN#YUGF#$`xlUYSAxEQf zVakz{S}FZDRG{O7#q+yFGb$2zKb$v$P$EdT)=@&xecyO~q%@7CC~rUU2?w>0>*Zb< zUbz`cd3QG9)6>MKx4x1eM-BwAA#G;h>+Q2&E%oXKH@C|699~#SkN1V$tE<%`zxctZ zla=c(p7~gaoTu)ofUDo|{(x%j>iPr7fHGzoqpw5YB$sISXwc|LKWFVWLH=Lg2jjS5 z|9|fS3L03z3=4pvP#xnRuX8~U8SDU-pBt1)YgmM)*lq;*rjc?~+sV(SrKIna6qt^U zx3Of2oULZ`xYMv^B$vnZEIH< zW!GB?&C`}I35d0gsNONd5mf6ho%3uBkIF**{PWgoT#(-0rF~z8gfrrn6wSzlDO6G| zT@ESE(tM3fYX~%>ie4@&#t37&FyctXX(dEbK|syhmA=u|LQ}4^FPBEEW}PBiJ@^Hs z)K1eVg++H>(DL(pc?%y5jQ-<(bauw8b&G0Mju=7G#&)Ke>&PxsWx6KPiM%(n{?;;Q zjJL*z4dINyNAtIv7%)soSZgEGH$R)1s>|EhU5+EUSYg8r+C1EnzgPd4NwDiKO6;OhLJ|!^`O-Wq7936wGRelAzSf zm-mxXN)z`fYG-R|-tob?kH49keI$*&^^w^^{((4M^J@h2{&iM)kLKRi)_x?n49)t!H2*v2B& zE)5T^a%8?WTv=6KAI@7^C9qeqb8{hU*V0g!WsZM}kKxAk+^;BJq?<82GdroWn zKK&iZ!3LgOW1*mmd-dc?D(PumAy?33*{w>y#h&wn2G@`4}>O)*7C#COPIXqFPl~?L%l< z{9Qs<$usaful$m%%D0dJuU@ECJBrb}LnPFuGo`zXC8G15N0?)K;=p!iPIl`37n2KY8u$3T^zc%LUk-$0y>^rL6vYnN2JE@>#baWCKVLDi;YakVS!I4kuWzeT& zV`YBPY)Tsv_DA4n%@uhqLN+rSd120ysxngk7Sj|gK0|~_R<-p>v$m774~k#vRh_+W zby~&ZgM=AXkMyqe-ltt@U4D*4z=6{HwE+Gs!X%ZUKk)4pqwixt0{HZVdX+7ta^{! z-QKIK^K$&Lo}BDZZ)`EJfRhDNX;-jeHm^TeNz`O|D~Z+23-cT{z`Etm|-6bjGZR zuU+tbk*03dSmlGV>SV*c{s9DejRh8917p%ZdLb`Lr)CXe^6X50ydR3EuBjZ{xX>7V zrcdPBg#=$Gy`b+8%@jk?FpwuRd=qo8v7XBKc5upSfd7lTIU!}zXT2W!mcXsw8{~ea z)iFJ90Wvl4{)={!UxenPvHb_f1(Fbu^%p8RW-RGUVcunBo5j&nl`t*dTKn`u;NkP< zWQRc{*BToUkPR{vKk{h<$L#IFoQlS6t8aA`)e%~0R%a4;w{1S}1lN2Thv=W5lRTtX z1pFOQY5@a};2pyet?%e6Q?#Bsa_$=Nk?wBhoEMCD@V;0Oj{_dr&Iav}FpE#uP2EacYLi=B|)BPT+i;tS}sCn*c>9YsidqTPAjEDTJ zhxC~fV(VlQ)cy*~H0$&rHxrN$M7#=|VPq&PWng=>?@zK{gv^`SI&FXF+}q2p-&dLD zS=p~k=&Cr1u-B`9t3HgUIIGT-q;zULnDGTX6^!CH@0F02?-Q4xY|#pX7n67!u4Wj8 zMQ3;4t$9beW8ceAnigSx*|?%kby=Rx-LXtMbUy-7dFff-XRQz0Zb%L}vk}Z!FJUVz z0LB>D7$Lr!uzu<7TWo4z))Z_v(K^RDXgh>kEBt!^Z=ZX@yO$gD?*>XX=GDh?t2M&j zrx-*jxR@z35wp7!(CwB8Q{^zoC4f=fWRku}HZ?G&tNwUJi7E%rf;XpmFN>rv@D0c) zIMR8%B5$-uMS{N3v|XK=j|}kj7;twq!gI6llerliZJ^R+#YxGU5lxzl{5*R)Yj#cJ znhLd0bbR(}bq6c2WG7fy_VXmmXku@IjPt_;CncQ2Px?Jve`uPNT$U=YAMFayjw1$+ z!skpi-U~jY0OJwdnTj0aRj_D~*xV?N)S2B{hX`QkLejGAFj}Kt{`DyCl})d$ozVEj zt+5)1jSkldfilF>2G>l~oz9M_?NUEt8NOma#dMpYAJ?K(e+YyLZStUQRS(T|1+hn~ zxFOqNF98Sh-wU`+@wFS?blADcEum^}JLwbW^Mzo-e`2Bnoz%&`T(T0<)hxclEA zyR-JyT+IC94-x9;7g)Wm<*CS`Yn>8z^7gF`&QV)vT5V4lI=)5)~8 zA$42>vjEq>q*L+xY^+f4Dd#aMC)9)T&-*fm9LzEeJ`GD(cREA^EHPgiu|T>A7Vt}f zRERV!Mc^KGpxgo&4tIo059{?eXw7`pRp&tv=asIkWP3+1DSPYPu5)-`){af;HwcynOzefFCshIW8TZbUi;^1QjIjuex_?^u9oh$xRI@s^T-}3zL zQpBHGN+JBWd72o!QFnA&6H5^OBrn5?*Rz{(`ppl?y{*tD`z=lYs)fd#?na-!ecF|2Q@+IED#f|gp}yx7GNba*<${Z!c(hH|cY`V`c;~b7f#+m|r!S?TN-+HBOSMr}G3_Y^ z!;E-k7JA4cQ4Rzh^2a{&*5N@s1_^r3zB@N9O=_V)-s{tVhj66h{R}%6y!D^V>xGXVX!zK@gWQtivWHWkyDibS~Q&+D@C5v`M0Mu##V?#T`A zaHi92Zzl8A4*419$|l(Gth+^oy*mAw$tM1ge7o$;6s)HKe$Wg$z2sU!tdQG*O_87l zMm}D-=gp)U#lMx@8$beYd*z`lUR-`9lGCTJ>M+M)m5i`qqeOXa+QP2*vKL=l#tqokSRKl{I^G;)6mialL{BW;GeW>un zgPXzfUo?aJubL_TpI8nF_OEXjPXflk zxF+KA;Y?qXjR2y5Ulv)h{dk5_8dE-(rn%Z_)Iu~0;f+BvOxDblO# zTNBdGIRxa8L&utIz)60EAH4Fo2z3q%bnRT;+V$(}PZLtuwb|B-Mru1C2Gw_Eewwqqqc%9eBArpQiLCNQN>jq;Eb1}prxh5d{FZNU zh8*~&F}p3y1Mm6Z#YL?)>DLPKikx(mcDM#1tzKIuS*5`4oB@$d$CJ^m;hfaEK5k-Q zEqW)?{G-t~K8D(`G1iDPsE2bCh{xIG1A{8AN3! zZvm;yz!8wgY0@6_c=XeR{*Z1K)$^zHH}4CclVtL0VePoTtuJ`mK2?~Ld9x|w#${3e zT+74&4zb-OCBv|jSnm{ z*(9Bw+-eLIgjp|Uy=?IxMYm$vs1@?NY$wzK{loJ_-h*ct zU-+FiB%lu?h14=jvbvqGP4;ZEi+f&c8HQ2Fwe41`aTBZVb+7a~oSon9#c9xM{LLEY zGARWgA`0aKk=C>496R=&xNa-@nhAM|*|r zX0v06d{L%pXsmpvSZ)7x6YgsYqV{KD9uA6Le!A4!G8V#AnAd?(XorWAM-iK^guAEx z=M|W0*uDiP&4{nls5?DZ^^eliVTL~#XOCjCYRkdw)(i3uX6o#;o^{@XCi*e7qP*%jGaVV+HIbrxGm_CEF4WX zB~nrtO0=UsxZbfomv^6QO2BB$&^1(7sNC>H_#Lnox`tt82|)yOl~4~M_h2osmNGd! zx2Bl8jdnH0e>U)q`RdK<90-dz!Rk@8VPt5MV?M)&APDx5OSbo8cX)l`=_`DLBvF-{ z9+W-WQ`W#@ep9#XlUpaye+f!uSZu$zh%ZU&==Wi1_%h?`CMK?8JLu^XK9TKah z3g0MQmzgLivAeOPg)XVtuaWAOxP1K8ZTiz0Ubm0SFo-59gocLRyj%CCb2I=$kk%l* z!rS^$c{|8@cO-PFe0o+^GFZ7abdxl%WM_5Ub{x#(;!`DuuyP%h%&%v!bDFrOT)F!}f{XY-k??GT0p&5m zEQ<69kMWV`AW8>eYm4M#MJQ=e>RsTZ%I1QGWB#MajTu9`cZ_kI7ECcpnvwEm1~)AK zzwj5aehoqh{SGp<^@X!}Nh{)G1*^HDo_3W!Ia>NE|9zN*)85zneYyQ$#k}xC`)^KT zULy%jWm~`^VGo$POBfk?dQ%rB3l!|;!)04$>>gm;hiVt(4M(CkJtCb{1h*tK$*d$# zf_!Ji5;6ciWiuBuI_!?gVL0}IXWK?U^DBXNhqu}E+n?dK4NujjD0vGT{;i(yng)V_{S%Y8U**~ z9-2p+b$W?X>y2ew<>5&3xz8m=o@p+EmC?rc4@ADq^iwOAaf|34I-Y~u^EE(Az`ABb zH0eCJg3?-!%JWDkD&QIKm$;j{Uw`SLkQG*=_)&1$cJ_6)!k(C~brZqH2X6Jo`aBQm zhnZL-*r=^Y77s3>!+SpAtacAOe5pXiw52Ap$0|R?(M}@DDZ=2KNIH-0fsLlqhIMHQ zNBMD9Gx*>QwPhYMBs7rx{@SXkz?o`CO7;M^#36~rS6W9ax~_H`UbuDZPW=UeTWz=F z3U+snt-!oJPT@S==Y4W0uS%@?u{%kcRUa+jwrv?nQh}A*e3BML?DmYwy8662u{p{9 zMfThNX!8DyS7f^ZJvkXUeky+(@7Y}fYSQ*Gm$%}UAM_y^QN^9n3?}1jf!LgIAF^Nq znYne2ch7lc`CVf?)qSsT1n^u68(Ss$D#Fh#-smH|nim}g& zuSw5dTOs9cKZGGFqq+MCx@aw)4~|A`r?jQ*osb{b8DK;JTcEBTG2kVFsV&)jd??xxO` zA#+YXtXKGcGm<1Syy0rMuf5u)f{Q}*Q#qvS<$V@$vZbVfBo~7!oj&1W_mH-awq?}^ zgQETGrJuDN)YrauVd(Ktoq+7=_q(5>h%x=>DpY_m4?((i`IJ*1xE16q{aM%8#nbvi zK^`Wm`6-i0>?4!I?~jNBDXLK#&cSoCio8mctBS_D< zv?|W^_$I>ySTV=6TfYPHGAVGrgk(BUXzk&Mf1p`gq!jeIdT;S3iBp;rZX)f2=2uOX zH}>5Y8r-mKvfr-qVKqil=;aa5+&5%1(iS2Y4$KnB(#xlHUHo&^0`V^VF-lUO4d)8;&PO5 z6Z>r&BWETiqo(mUbkd8PWUwF%YAR?`Ov_>B11y zsq~;nl|r)I&J!ZOuMawJ)ifZL6I9CKERx~=So#Ua;zXj;D--9`F`lt*rQ_We(@g#O zKGrV+_RbW>&_8{@*9RFU^pdS)66D@Pz!a7ZNg)FR7E36yz*6axr=L#m^P3EwGTD&9)$^&_Rz!NTi2**M2@}Y#FN9UzXw4&-B zc=hhfsEKJht2d1cgKx9}mkmH#E(THx$PLv^-H9QoK=`0#cqHXP)C$aCXma`4^a`xQ zYo@7r1=e5FXEnXEe`JzvfX!F`eDNC>jplkiNz9S^-vvbW?>N7ib+f=7x-gEcSB15G zTju33`MU-CZ}ir>f`FLX4^sFJ_SU#cQwO7H`~cb;!d1xV2PB+ z-T^i?uovv&r``I!IZFBwFAJCBv9vy`haUpVE9hfO212RQIwc-ADKE(;#IoA6IYguM z7h>^83L?6Wqa`Bx#WQbopJB!v?l%+sDCYO^V8t&7_4|rR;Qw00#vx+ObY5MJ>hT;2 z>|6_VYL1x&Jha4DRaFd>cXp(v3$COJG_&+I~8FQSf&A!@?k^+FDF@BxDy_4?g4 z|N1ezec&}QE zga!mwZFv%^DU6*QKR-YBa%;@`oA6(q4?E|l^LBT5{|~@_B1vE0H02H3e5!n-*NwvT z$#DZ2R}m{wcNq}Tz#{PvGN{l$KSb8t0yB=HV8?{zf0~4k;$P(1z}_Dzkf>BaWo&=* zw6Dbw{@mh z&!Gr^Ejh4!#frLvPds|hNpyyXTG}_6rffr_;@TTaSC^5SgKsy6?A^<>g%8$pih=tf z((40)D?N7-UfFTz%~-4Df;8tr174DuZ}W7sxMWjlkGBtN=6ROmaWA(O%4z53PsE~Y zake}z;ReLZAr@d+ockc-)$M)7!T2rb`-XyF-#=b3{b@cjH1fdU;!*MFaT|mcn$5sc zN~uyF<|(WqGdXo%a`R*TLN3iQou`wwWqo5pcq>Omrwac&U(0tjJIEO<>sWY+ml5s9 zs9Tz2@lBf=F2q<*Cl2&jOy>}gYBC0I8}{CyM?WdNdSx^H<16wKwA?Q18)n*^#nd-q zB(B-?u8K~m4J_L?P@gH5DppO_T4Y-4C|F$eHC4@_e+*f#u+~UdQjlzqqhNYcX~lkKp+UdU4FAm zcqQK^5;6f3#26sQmNYIJ)oRd{KG%_&QtbW& z9>U-7`2WE>iQ#=Ei-L`^)VCCvPzE-_-=k$g>G39N0A?>Bz&0wKWGjL=O;?f{Ak5s%EY)7wda}$!~Bbs)z?qAa35L9~Jtv2rOYXk$mQwq^$X5 zUC$9OXS#MgJ~FNNj>}(H=4t;UA8)k-(14mBpDgJGc8B}{g^b&s9tz20`c3}921TMM zac=9Ed69|tyHp2jg{2w=8w2l@!^Y*T2$lU1d2ifC5-OqBDvs@A$<-7PddS%o6sTDs z)j@}7Jwi^*+v*?F;Am2H&)W%o63bP_LEb|UtU_-5w&azWrspD7)wid0?pwz9R{>M% zie<{CTHC5_gg7vqtC`*wp>lM0D!fGkc*daHm}V;s}}T97-PmX=f8bo_IzYHLoi z`n@{_o^jK-fXaMdZz;VHdT$qyEfu@tF5grqOiG8D zm;1p2biXZ0oL8CDymBO!;f3nZC4m{19fk?l zL}5LO?)mRAp$IxEw~>nuo)euo4o-9{gp+S|l@EAIYefuR*lWRO;n(G_Cv`EiroLRk z`olF3%=_r6_YWA2a*K!@Wf(h-j<9q2PjAUul?ofp--zaGs#!y|MhD=YIzQ#s4& zJvud0K0I8$CCYn}0??Ru?ImJXc;R&6Dz1mM$zNOKV&Io|T_ATq-26yDC}LN$-kIGC zm|Y-cRBFpT1mi4*UG>$tTVC#|(%6oq6eW=?3m&^-{t(-}3O#k>4<8&e4RPJ|p+1av z09g$MK%BWMheXXfN06*8H$;Rlx7qGslH8)A9^k+qb%ip%G4N(sf{8N!`~7(r_>%Cb zE@zx^zQur8kkdR*tH(Lwh(DgtJNKf3Z9;eV{_QHxtiB4;y*~Q;4^5X%#3{heA;H0n zS-2n1ak2u*wST$EsKl0lQO#{bi)9S?=S-eqIUQBLH*D|zeLGJaBR5~(e49|qt4R_k zuvGVLBxWQLoIoUZaUns)Vq19{GV4G+Uf#UOdHGL=3zliVLb)?q(07zb<58nZq zqy38J@~gylyU40`q?28V3aWXnw*AEhc5ieKj`Gcx@4H|c)pS%ywXWcU$yX~eykIrP znJiy_ln*$a+>gldC;MIvUirHAm^}>$}kVI;JV|sC4}G%Ps;IBpV<9 z|IB41YYUJkPN3cxv>Hm=MrZjiG2efU0ss4++177REWp7TZ+3n)GMJMo zodl^ESaakKs{p^sY7~bGX?z-`_ zn{3suQd_|JP9j*YuE3VsJWWv#&brPcKH)hM@vW57vZ9*LzijA6C2A zNBt5`jRr`yP;0^`gD9peFbs-f84(HxKgy+?5_Vs{fzX4dz}!mzx8Gsq)30X}>K}j3 z$K(mjMNz5HTr%jX1G&5iuzbn-x3vZ&#VpK#au2EZB|bkZDKtD%P@_w17NU>*fnYJv zm^Bul|73v^M>9Pb0F4M!{~iyM-x>A;A_#%LGC-`}ze9G0|Cc*zXa6=>@p&;Twlsfv z;ByE=GuIEiu`)&U;b1yOW8ULme0tdUw~_z9#`^RS_M5qn@6?PKdeLQ*$80CTh0$o99u5)>9BWf{T z?%?NtG+1`F9yW69`>B&%P2n*cJzPM-uibbyLaK4H zcgDn7f^{~$ix(dkL*%V?ibmeUFN@ui6Sk3<{(Q|71~HE*x3E9bgiE6)sAm@!;&=*fh+NuRy6MYea35UYOKu+HP`(lT#i;s>0Edn^;y8#BX;Awri@Vwx@_lYNlL@zs zWD`x@8W)}Oxyz`ra|@GWv5I!-1%cD7FS~8^c3q2Xaz$6S_@U^joS-%vI%x84tb%R{ zp8(Inhckvvmba^$BN?VkK7HVkh*K%{XZ5Ztws-$@2Z1n;55Bg(A8HrKvslt^Tw5 z9!2J}0#B9hG^-pv6uMc6+!~Kj^57z{^yki}5JvjL@)NKSsi~^@VucC)iQ?i!xkb%?ybNYn%V2V8{mnaB+ zxd+P8;!u3!AICa$`WUl<8!8f%^!A92=HC=kG z|JC#`$y0T#@tQ+hx^EslT3HWc6K72_Z_FNI7M_$v`eQREP}_6TcZ}fUUdC~tDg)-f z1GjolneW}^>UVr+DxNe<2vu=RlPemJ)sMp2Ft=oTd2zAL`NXaBEmu0l4u(__LQL{6 z`#8H=Z=bHyxNxrLlJ|EpZ}t?}qJHp_i2*@uV#umLJcuVRWT2q|v(0>|tBd5+lpdV% zD)G4h-2CCQ+NO7PUb8OKHCo*4TV)6G1LU`nRBAFUpp9g8M2Ls{y!Ong-m3G`DoMS= zij8(R!G+(chJsfIoW=1 zf5sO7xHByLb29x;N#yWrmpc9HrHA#GUTipq>bS=`dOg~}RRiDKb?C;my0ME{SucDy z4{megnal-C!5woAy$Fqt5`$E1?>APydW)%%rz&QmUl3NTsE+=*QyiJH{(Bllp|0fIxhGo+$9T(5rASExm+c{<@0SRgWLT8JOO{12 zK@(vpuQ)^75&h>oH2I8l(apimd$k9+%lDN^pQj{JrOo-6)B?NI?i+96HT4zF3+hqgg&g<8uF-i5*FjleU=85fa4m)ujmT=Hx+hUjQ8^g+N)x=mGKM#Y zZDUg9q+k_#Q}~vgjw_(}Pj_w`XFlWca*pnEHUbYYMG>&0u=gC5me`$grWvH2iX`h) zVMZSgzEfk9HIJVnj)B8XFj zm#l8WCd(p-ks@dS3vztuLoKUVRd^p8O%I>Q0fYyKiQ$kx{43b_KLrBa_y8MVwefjB zv1W%%lU9>ykcH^^g1`LRKz@0xW@^Kk6`06cPk5{I#~(gp-&3*MVf+IE930AYbVyD* zREbwQqQ|6VUUU#@ZFzedXO1gutFlY6zi@8%;V{^!F#WphDRqlLBT1uBMaH1+>^QB0 zAE&Lg$b^`jReFoH`NxuD@(K1Icn$JMdRia6O|CI-uYb6?TEN4Yl(9ti5{9_PMbZ`7 zzDCTBacvs9CTJI=f^n*F6@Ia^S-A1vlrqN!c?sf!F-u~fRp$&kh)1yPUX;eWQgdDp zReKh%*#!H{G9r0GWZ3gyb*f3T0TgTWL)cS%zPkqDu$a3cik?@o6#0C3KH5n5TRmdQD zsQ@qrml(~?8$OMX5-Ee7hr_fEnd%vN-+*llvojQ2r%w1UW#VGtG=GczrBU)fmC5jk z-dndova8B0yit?7{+ffKsXFJQoC-ffW*gjaN#nM~ZehxRYWkbj?O`6Xkwhkh-3zEfaeK8{oU}AuI1QDYb-U`pOzqo-J89>m10I(UcMQRHJxSQ!h z&>>UD;0x1YRB@%hwuwHB$t5CYh~X65#ueDevK%j!dte<1hSUTnwD2*5JCVH#RH`B< zj%U?pp0JGE3G%=0g3=dJU`NT!52}=N5vD?pY|D#WV0rfXPneR%Gm7vo5^9lD`5TOp z-(Y}&wDBC>loPREnIDL52`#x`b!h{ z-d6P0k*mP<6t-w1oU4%(Sj=FN#ehTg?5Y&pY%{8 zldl#0Z(2zHU=iB!b<$5_tqt5C5bKX#X>9Z)n31WLtD+-mJgz7igNI_nDQg24rgATo zV`i42ABbzA2rab0^`D}W+H0}KM%kYu!H~?RHUYkZK+iRmE&%d@P3Z|(G0AaNX0xa+T1Ob@h&-6zR z^GiRZ?2w(Y2_VXIJe=@K4*nZ?l*mGAj6mv!)}>A-f7Mn{oe*>A)zK5-q$_c3e;xc^ z;as$m0!B#|zSQ{)^fv4gP8LG`(XR$n;ZJ~miK@Hf0mS6()$!}k(8j+5V9$bM`!#$Z zFnxe1zvL8c0|X}hK22bLj0Q<~RkD{h8thMbfmgt17QqqNn!%XN0rGN#CdfbVLXm}_ z%}`74!n%%C1QG(t6fAHXK!4m#ffRp1jhI5|df{ZM88Dd@LBIVDC&bHvWZ($rRd~|I zoj|to1XpG21x>c9A>26^C92mHhNiJL;UslFaDa{~o?2BjUbH1JMnA^vKpQhV81r@< zd~q3^-_iWkTg30}ElV>1$1`ahw^-%4CY4?39yIcOc}=-#{Qjf${97Sv2aOGEb4hEw zLz2|xf5U+0fBbj;4sgB*$SnX-Zg+W2Krn>(l3znyRYBnj#LU7kl4`AyG?JP#3`iX( z0+dv^0{QC;pn~xw2YymX(zsRmY*Qw@x%Ni`pm@w;e>8w9LI_d6n4riGS*{wNPtSny zcfpW_FigK#rvBIFS0~xkDXFVsasE00`y7uY#FKwR0Lb|79q8n!uW=1ZKN$#^3_Ro? z@CE<+IZ%i-sk^+^J-F+bAopAUG&3ds`+xvOk;txsa9|DBXatzSEdBczfJO-(fp`s{sL)eX=Uj0c=!A3lKI#VDSr-wn!uF13=htLK2x`{KGxL z39sdTYj6Ak%okRvl)WlR(x5km3e?O3*wtQDUqGc_4G>i6|F8iN+JU>EfyWOBJrLQZ zGy)h|L#3I_48cY)uaI+~vWNR4M!qjlm&3ul=rdIDh=w2S6w_`6Ml71Y_>)L_nJX|L z-6sJ~D(g6{gD6=a1cEAQTnlUfZP38KcmVrm76wKg@pII`b+m(FueQ(uWTUmHR@7($ zoT#Lj)vnsgDe@sPK*n}JMjBS1RzYHB=4fP~fpnbEda?q`J@(fopz(jyMxBxpM6;Fh z!0U+DVEd!|>mNor`(&1jalGexe^5#oRm-uE?r{>| zvdEK*TB3k$#!nB7zbl2NYG`OiwiNV-Vs{3mXh;qZMi{)Hu&X04c!jPXIsLq+@y}ff z{>y5@x3ko%8C1oS0V424UX8Mc!?mz>IbBU*uJ($nwn@gG z?Y{Uq{dI9kv19PA8yZsrnH6u72P3S$W9~uO@Je(jf_|u-d@MuUrSIgfhSK0_>%$|a zIgjj}WW3Lnym%2tcX2_@AHhW4vMfmAgMzUfBf)ChCEU+9UbuFgKEy!1W)YQeVt{*) z|CW3Q{6MOxp2~$>_j%;7=Tmy$Oi9DTT9y*g!}ewOAygE3=L~&K+(x2pWvN}s$pO{l zs$y5p>B$u`zq@G@8s`5fDo^XtL!~Q<_E*PIJo3j}LI!j~ZxZDTLac0=pWRO18JU;Q zxL4&Gm;Gg8J~L_ z@O^?&Hs53N=tKJlB;!3e2KL^`GdqLXnZ>;kGL3RoY6Z5{NvnS;<>cE( z>R5v$8)LJ(k3l`(j1`#c;*@rb8peRVou^CPZ2yBD&FUp@9-Y2*n$)Gcfr-0rqt3T2 z*!Rc)J`N&RkoBYohuy&D?&@f-;HRmMcTr!Tayh9Rohm=NV}fHyh({rm?kS^e&RwJ* zcI%WQuPqbuTWib9$^pbSeHMDiMWjk9+9RuqV`H~MfFh-zx2`{vn?vP5in|m#-*|q) zLd}=ByC>_3t-E92{A7M&OCyh#Qe?-8w&Fq&<*2By%>>x zsJc4WO4=z}RU%s7vV}&ERRP0zS)ywmNmuCsZ5v+2WhgCe#aE#GSe&(GMtFnUMPN`#SNqXiWL07qdVr0-B2Ony^s$n%YIE|S8U$5a%b|dF1Z<8fk}I7UseI zXq3r-kcYslCdaqBV>0xWX1lXn9Fn@n)B~dX6t!i`ZsVTqpo2@Dk<_R^oam0OZE5%r zrFqZpSV&|?)KqIs16mkJlG4Z|$I{6GwRot72K0s{PMvo&&#`FzX)4D5o3OTNBr@eNNt5$AW!XsIa4Cv1Lw4!80!t4YLC^6 z+lI4dMEOC@$s+&6r(D-gpN~4WSJ)?xIY3AHltLSVwzMo4cTJ2tkTF#~Ys#cSew#hx$3a{W9`hw1cZjXJIsB|RdMB%|4 zOuv~Q?uDYu#n(JJ2A98gr7yX8j*>s6!zZkf%W&!r_`4QL)CeVN(o545HOcF|Xlx_p z8Y6FA*nF}^c-ETAKo;w8Y;duW+ah*vau&@k>bt|LIN#`2btGZz=C%3}^M?{upNE-ZjElgwB{aSPUVqmHM*^`(S6(! z-PsY-SaSH;@J$_03QZ-Q-EC8iQ*EnfFOhRmYM8uSASroIg{|HXGZ}GfsB?EM?+TS_ zEw8!bB6$&`SaN^>wkc$=J|)~KE}fOFh6>j4E-f05mED&~FMU1b7o`-L<(jW`F`chH z;$<~QYK_92}42p&VJOcY|=5u6? zmFfkpgV7d!ePjJ~H_u!7BJHmo+9)RQ-7k8vqhzVg=wyL>V9UUrh*#QLH@|n4rZmyQx{75T`%YFcq&y+a&BjY-)Ci9Pi;!koSuhD*6?Q7F&k?>cv%CWoFFAUM5 z-e@1tp8*A9&)it8yyRWR~|<}3Xzt3afkh?<8~B$J?`=N z{o+x>$`{WP)kFQh%xTsQ=an4;*+rq6mK~zScx}%4y!VN*p_eXkCfmgp){NXX?Fo%z zWZn?IFTP0oU{dzH&Vu`%afzxUvK1+1=cjCZ6xp>I=}yHC4WpbHs3^IoQQFN})e@qg z8g>UM2q&blroG;Twp^N?*|JV%le{I3lZy_; zNqY`^s??N8bSRE?$SI^CAE?wX>lT#6soM?it{!2u-#`7~fV7#7m!XcNqE2ok$Z?;m z-Q*yPkn*GlDO&Dzme4z-jJd@o*4~#iI&0+~p4Vf!bZ@6bUTWTf!s*27w!?^_Cw?1E zm4&_K1~f@1BE4qElq3<)vdkOO-TmNnVrR#F%vr z)Xy+AOw$|Nvlag*wq59$v(!TKLP>Pp9w6-oEs zet}FaIN|`e^2$7GZLvOy+|e_bgAD+&coxuQO_Y4_@NX1cJGsK%Q+4_IJmT|`ME?n<*V_SM{f(m1X0Ca zSx{W2z+$U1;@Bxw``ITH5D4)+u+z%6dHMT-^qd-}3);xnz{tT6)AlM3%2nRe-qV`U zb9?(@W0oxa!S_2|7xTOe-&Y&9mADU-nx-N3h*BwDT?R}dTdHTLW6U%*o2wKad-uNF zaJx^-hQf=7-1Qc&WjZ=80ID=iLe*Y}i8qNxE@=I-j$t1sr2}(q`Ikc|?Z>mX$v%{c zbL&VFwDm6cM)kK#su(Ft#u$991XuRavNANM(+QNtK#%P`)vi?<@^zJ3jU}O{A1JwFFCA+*b*jUh;2%i%$9( z3Lf|T`h{NT+uosRt8|hx(N>pmzS#EdSgJF+TmNfm=r*You+y1#q<-1jEdQY#y>NZ9 z(3xvGFTxMJejB#WE+XRAlWb-}bn=_;#p8={;Y3ZmQ!&x1Ivk(wbYk-B_27=a&Ch%J z^Y2~X>ER#Sa^U&1h(_i9Yi!bquhT}lbf;FVt8C2kJn-PW{!F1kJHAtk!P_xUFWO+X!4F?E@hmnsZ%ssk9_ZDKzYW z(*urpN7-(o8To;J3&pDk8m&PWjN@83p}O`okfwaHmKtigB)^+9H0l+C!xG;vi8X>s zufa>Lb9a9D-k()S))D{bg)g{8RfutZGu}$n9OLd)gRBDrk#x#R$n_1$HK!90j(T2JZgl*^yukb|l+95Hl)Z?#BATMutBvF49yNpOI7KCh((A$A4yWdi2r;;P%nGEpZ}mC1VH@ur5ec) zl(m3HkFCHW7T{!?GPd~eIV2nTGZ|5b!0+lu#6cd=;?60yzkK(Y$|YTiTw;X=OTh*p zFZ!NP0!62C1tx)En}(AWjxf%&Oo5HSeV)C5wlTQ;KWO{=b7zHwIyDuyMq0)nEs^B= z3$|oYWB_({*9z=|dpK2E>CZbhtu-F?U*{-n>wYIOi z_6(7uXwRJ$IsZ1EI)4QLCltzq6Tpuq00$sh1CE4rcIYh$8ioQF!2soGq@fM)|EM7w zb#EN~;>ZG;dTu$D$|YC{(P&=+Y9iPGR=~j{kjk~^GR}C^Qf464YynMU#ZP#Ef`~x) zEI3sEuu2Lzp@6!3jZ|xBma;>sy8xPQYhr3f6Vq`pLzV|W`&SbNsNfKPQ49gtoj~Q{ zsto@Pb{JYaKtdWD zX}GO6bojlYmO3>J=;L$BIN9$v(nQe^L;XT5oMedH3XO^Z>7Jo&j*~2dp|NVVe`Ab8 zt79DbHAdPoQ#IkY7wCY|1d8sfe;Fi-P~i0kvVVQyNEiZ?Wk>u#_6?1XwKTfo0f@@q zK>)fk{y?8;Ra#|%wEjSMFDPXt`5t72UlZ6nKw$exKy1(0l6`*ggs~F6!~zYjH9hsK zDb46u`K)sj?1A}X2;)>=?BWK9Dy<9@6vA~<7%(|AeUc3nGm=QmfPLB740%Fa4bff-v%|0nD<$`9oRaCJwR6A)_E*}ul9XIlmh~Xpy5Zylt&J`aD(o6vH z0L=%yg*UFi*rwS?0VMbc0KK?#68-0g;P5Bkix2vV_Bh@WoKI;dL*lFUn71E_qp9bh zS{?#t;~@tuKAL)(W}d)-3yZ^V2$Tr|E?NRER?_sNjPZx*KvFqJDzQI#1}Egp^8qU9 z{Gie}KKK_nh`9CW54v<=33=4tKm3NkS(8uw0^eB;6f*q^)oj(Qp8O@ImVk%dBu~IY ziwH|Mv+C(f8u%jPdtIw_(2zNg?G<2 z%n$zMK)BmvptisB&kP3w7}nvJi2^I0zba}9Kz*Hk*VPwr+CLl2Bz}x&A3(GPINqNW z4JMTZBgcBzDO$qygQ9_C5mX>>h3h0`hbq33pkItZhXC_t0L^hVG{nIss}8XUlIzMl-wf^b$Yj8tFL;s)C_qpR~CF$=6h-A*v^BlQ6a*6+ct z*_9cFb-VHiNagR}A#j$YpPe9ifh-p)6t9|w-yr?*5nvV)22@-VsJJRHk~%fB>eP%Y z-`5OL;InmJg_HEl0QFubQBTJJc}t*jqP;Qel)wuQxB=ej2sy8*Y2&(3AwchR(9h06 zfJ_^K>jxV5@zU$StDrrAkzGOciDcSlz*D%nEFG!e5`4m4J6g2rRr@f$1KF&u(WU zGb4sw9se_M;aw-7#YK22<5D>=<1d4te)ScYctbK8{KsF6C`JWu7mwM3%X2h~{pSnn zConr`siTY{I#?Mg8x=q@xbVd|BSp7x@*(IxGz)C*hY*N*Qt2;`^I>qRm(tW3>bq-* z(S2|dJJdKmCfo+$RLCj-2L$yJSS}Fj*~-K3o1i8j@-r~4A9w<-(+B=1d6EkA;+lsI zWM3asrO%R)zG`}cf7wsj)>g8&N;|LaX7nvB#XWk@`swB*I~}d!swGBD_t<7`;rJ$i zW2;hVnOCDK`K`dhG=R%^MY_KNJB=bgqrK1(>l}qzsuvQ*R$y&M7O38bK@4&sZBY~b z$v6_kRR!V&DI1{a8*H=z9)<^@W`QsJ5QG5CMZN;;;Og_EoNa+dH{?@UP+)Q5n$GbJ zNl5nE2YnO-V!*#Traxh-&n>}ch@PW}Re-|K|5JD$Nq!Y^{Dho`)o6WQ?ShT9GXeoD zoeV5nj~^E|oV#0L7cm@CB=5}YlOFJP^aejpvM9m=tu=Q>(duBhY)ynj=9@WII*}KA zN{V1}Y{CK>DM5l|9SD)ovVYd5-7+tMnduWFgURdtgk>J&;uIGZ0VWt9H%W42Qyz$s z7eYWWJTUt*r`AMK-K)XXM!;4Hx(AB4S70W9)2G0~yB26ewC}*Br<+5|Zk#ZFGBDw-4@YK=_c3a;}ol#N{1Q@F74l>JstPeTjW9ipuKROtC6YK)w`Jb zby_+-Zfq0gMSUq52G#fvH(O_Wb9e`D0w7UrqN<(xXn27zsr!+9WL0kJ|OE!K-MaTX+}eS?rBqeB<#W zQHpxJbvwMbZvJqXtzK1ZqP|`|G_o)@YBmUL5`es9mt!w<$9|Q4gPz8aIWlKBIA*0M z1qoEKjV@HYwZPe^bDzYFUgh_s?-n=IKP=MST`M3FLKm6Mhd;x3*r}gQBe06fQ%u?p zui~{0DC73Dgg`+1wb#NHc0;@L8!zu-%dwqNd12;ttXuB0E?0}tMQyvegWLl1?dDq1 zA%TzEMN`#^OIz-bqI1bc%RFPo9G_nnLp$i@q`R!+UM_HI80ejq_K z3xR24UB7K%pT1lBM{Ud)2z!3YGSW32e)52s$;{(g#Iy{_k6OWnT#|eXXWZ>ltRNrN zfnAccv;~`bb>n!p<;_OWXvf>W9Vdv|p`K#aU=4kvbDV_)7yC%9#<2}tKXrXEVJcj< z5B$j_kI9XZJ8G9u&9`0qW?lQ{mL!P^?;$4gnSrTbEYn@=rmrNgsrNyGR98*LCyaY{(fUxdftO0*h`gw%GrX+(#FnxI zI5#eoq|m&O(7b^Dlp0AUaVb)%`gWY9bn?`Ej_u=~C%wIC6Y;G>Wu?;jm3_{oe9oorP%YL+ z8o4o%FjsH6b4NOivT z($MKX-$h}k#CS0Edm8lHlK)qA*A~^}v4uGvM8E3L+p8MFHhntB71;s(?^} zNvm)m#E1~UD1;~oDquK4KS__TFasuc>@ofiP2_9Lgb#;!^97HH@o=b{zicmgVxkQJ-V0 zF1H&+1uGr`Z)mMd7%_}>hEl@6>$ab#homzM5nbPnTT`tIk1tw_+l>q&hjgjMF)Z!O z+@waCp#CyLVk5VGeeT9&Tm!Vmb=`9*Du8EWmkzgA!=t@Dp?!H(eFb;LdA!&rLz4Aj-yJI?$QorpVdh}E?%AkNvu;ycGYQn+sb{&<7yO!WYN zk*)Qqe23T?Z6SJosao5_U;}6go?Ithmo!YWBT-`!3pLS}D;OU`<9=wxWFG75O?CTemuB>yVgy^{{1_sy{B zsHXU=9y}xi*MeV{OZ#+1d~-Yv$(nPmm(s;8gC*M}Xxa$%9R?cy6LXE@?SEVx8 z<3j&+c>SG2Q;2A+c-4_~et*LDOY0D}E|_KPztl%3kDP|W?vs||@CI$1fyN=qW&uWe z1k!N(U6IXv-z+62gcJ)byxu$l3esma1`MyPN=M)5EP4XXe-XkG(VBc+OQqSVK$A0KDD3x*xUl750Re2qwU@)5B>erZ2 zBXc=e zrq}?u=<&hecQ&18dk+2hwp*S_UfE`#Vv=>s1LoocqAOO7mww~ zzG7<2y-SGaruDpYAH&%t1vm?thezg7a!6j2Zz^0tY`zEU73+*h!RhM?8_G;GLzSHj=b7=ZOjmnqwwp`Vg6=jtn z|32x2*etmx%?l%yPdV~(Zb~V*w-N9}x0%hJX1Y!1wav6Wl_-Id=`_2&LqAkM+1=$S z(^@8YfoeZxinq*n(<7Mxgn|q5?J`*bx_vW}C3Nu=3TZ4!z7gSINveo2Byon)5nFQX zX{Ly1xPzD9rrhzX`^^NfbS0(Mr%WvKVo>+_Qjs|gTZW#ros4tTugkW4994b2h(7GG zJYCW+$Wb=^`b5TACE1n#G4c-kUKe-rC?*zES_W&k+Yb7pV-*;oV@$no>sort#SWD= nqnh?ZN;fnQ{Eg}hulSR`X#Lg&=Kv695401_*r30V41Uyaiwc-vF>He%BwrAx@4b{Ns98 z#@1hA=YUgJ%&hIL?aZug*o62_0;kR>ULx9h0{HrR&H43mUpI5m01U__n(-ie@)>o; z9Sh&}Kv7Ok|B9;eImL_eUpuwS-oVD@_SQePw6eEVRXD?@p{d12`W_$$C;)0e0-!fA zw6i&V<;umc&-~jTE4^R)4s`KuJziM%cWsG6 zV|z_i4pieo@Ot0P->$i~u1$ZtKDBjiXl7sp-UE&a!1G%lz$*YCJAal92qK zi9alFJAiV2eQk|2g|XH3tKjE8@O=ohjI#h6AO@TS!~tI5w7sztC@%oWS=-#RH8(Z0 zXFCmQ)|gGs+S10s-q@ChP0`AbkB3e0q`=9o`?khx>k|OJsD2#_0=o8Zzq5W00OITb zKp6DxcQ+#dpr{-G4z_&z9Y-txP)Pzn;aeL6TZ7-82mT~jA^N93+nERne!ZW7;tT)~ zk6^K1jsgH_7yxXBVzC(bMOD=+4j^LYcKN0a^0TSxdDx?N?4jd8m+)Z;P^m$GV8M}}w zg7&6u#~wNk;c-snmS|rk`_BZs|6fV=r(oaY8Uo~iU0+{>yLJ&06A}^)#~*lo6&VpDnn(enY;1m9L|Si0@c-gi#|O4uL(}S<({`5AYVBd zSj#AgHbXTe$fTz8kW47OyJ*4QC^~5rA-?;nBo=5r_1+sM`OFs!sIM(=XgcXF)W+qj zhh)x+!>)F}=;8f9dYpsNe?wL9RR_TZwTdfbiF~cITNWo~5 zssSuu2=j6k;4|&WSSIrFa z(4a6Wr{)gOrNbBQV>pm)Syf5$!liEYD{6N`liysZW0Sf=qO)YfcW+Y+s-D5dsFWmK6O66%dhnAT`7W%a-&r?$9O7wB-A%ciXA>|QR`?~ z=|;Eyu|=+n-;(=m(-*A)ly0JVB|GZrI4hOK$<0LN9uYU0UO4ZY=%K`5_DeYy;SC#bMwrZ z+&1AX_K;H(CBaXJpLnFjQ!Ab#d?d?ig6XKrU3ehF>Z*^3O&?Q&LdHk^mZL3?z=utu z}Jc9VMNCuOt zh8!H%JaSL&o^j%!7Ju|pCieM4K!&^zVl?W%PPtNHF5MXEK<6JX=ATefSSqA_OX8Xl z+0oq4tJJrf-?JLj5E%(ZOn%&qspQl~LB~h^jS3%Vp)Zwf&_#%yw11kck#JxVI4wGd ze5lPuHgPb!$QU&y%o``+P)ND7tp?oJ6D9tL5Vg}y1o~k@{ z?|^)MuLyy~y|jZ**xe%bg=q7g37X@0=stV=R4no4(@Hj{*X5V^l3kKe5M@O0c$Wjy zraMAYv&lW{$`ILgBT6>*ho=}AAc9l#%AVN>UqysMZG~yAbCHK7W35?Mxyn6wihse7 z%j2gy$sW<0SC}-;wtAe*+UqFr2JDVMua%T3(xF*wAifYQ%aKm-*%=G?VMv_7kBJwNV^sV48%$GCqP>G$=ble#RVGIY4w>g(9D3n@ zS~u+}5V2>M2Z?$OKP!s<0)qAPf@vBGb}27T4k?oRATrl^-cb0tFEXE^epgX+0eJ%YCFQrB|NGu(MLN7-XR zj+lU}H|Y~%x}Bl*F$c~d-o{wJ(7UDOHjMJUmK%3TKek0ux@^E`vDTwx^y!{?Vn@JL z0r6$U3RwiR*Hx%58jOXFwJ}|+l+cN+WUpYf=XFmn$&5U)@G))iv`Wamu?ZKs&Cp6- z3+Mr~5+d|%T#AJ|ZT^N^*YNwt1ui!Yhd6B0PM%Pchd$vWku&hrT2HBtnyQUsb+T^6 z2p}>l_jonNvLW3Qp;GP;E`!2OKFtsQnFbH@-EZ)eJt0Kj8X(}#LB$}c#@pH(U_p#o zaqv0D#a1npzDW49-qlz4t`3i}6$X*Azm>E-OjIe*0Qy3*d-I4;4|}i3IVAMKXIJTD zJ%yB}%;8&bX+F#xTr)_`Zq4)!7Zb&Wm+u))b80i{7gl*L@%vWM31{y$lek_O5{iOe zG9S-B8zNdV*vcOBjP7Q6k$b@)%2657)C3u@tJSB>UpP2jNrOD*v1~EJ$Gbc<*)>*@ zUuE)G=Ulz$7ly+pNv@H+6^t&%0z;0vh{_72#f8XP#>qIp+dOES?MCVMG z?7YG2;6f`N(g?r0dK7lbAEx(&qrkOcV)OyzfIIysYV%4dM9(~o!w4p*p;3*R5O`A( z+&8Qd@FifKutvW?VU8TJ-Y6|pJ94VZ=j}eaQ&tp?IgM4r@}-JrU^jsHy-d}R-R?)x zSGtdMxsr~j58qVW&0?f-(o@Lu>CxNg0_WclyGg=z6>9Z!N9*QH$BP~;Ylv+1j<0Bg zr7TrbW<&Q#gP)+rP>T$@(~$brOc&st&4f&uQ`tD5*dy0oUPuyCL${YA>U>`fWZm=Cc}^jrj4@lXQo3US1~m7K~+Tx@GktmA78l`CmT4H<$bl6Vd9*Fy8X8zNfw`{8Z<&M8~TN2b0!f1BTFq*~ELwBeRy#u*odJSXE>QgD_(pE0IruHQeo zRRcax%3N;L@BfGeOusn4ouq?%r40CoX;5)*HtCJ>FFzBRyRW5nnWASdon|yM$YZiS9GKd~>@a zhfTuNNA)zp|^y#R*!D~c4>CqABh8^mzhN_s}n^@{`x)I09G7uuThRL-;Vs1bylu#WMg**0LS{0pytn;*e> z@z)gdKbXjAzD6I%Wg5iNz$k=UEkOJn6x)T?%ua@wLMz}@$tjrL?5NpkR?qduxaS(E z$gACx`%mx7e?70f@Cuk$Hqdi-phI*jxj}^8<|YkD%9l(rEZbHCsH!Go5`QiQyY@)!O!c(`#bjmqztPKuJRN5jGtHpx}|3FD4%io z8IXFjr1Ze-Pjb6KM1V6rK^dQXkq6Ykc)4<%Eq}>TwN)c~)PUedxm=?DjI)w0JPY0-kK5Gsj_cW1@KJMaPYt75YJuke>!tz4@%!-zG zy#%zMO&}q2uAYqOa)W=2qGa)nmNB-|l7} zs=6VG8m75=epdij{Qt=}6}B6#nMqD+!xh zlzX_cRgjQcs)J5))uoVn-rECN(ODM{-#=xQP#mM^$#<Cwo38??zuGvB6k55fkTKzMYhO}pMtnJcthUz&ZxP?#1g{xgrqS1Xrf7h1O z`wD?P&9C?WPzR*g9<*k9FT`0n0Sjm)s%N+_#mQp|(vBYWcCkf8*QrAZgkipmpSUg4 zQv&(2KPm*M=4iGXTkd+JdF8%X;^ei+iTOn#xbXGIZXJlaCf42dfe?ahf7hFZmWarD ztpc@HQ26^D|DWk~C9-cI9t1mu<=25MgeS$`;5>rE(zat7zzs~gH)Sh~<3mUY^8CanC<_4y$6$?CP1Y~xUf`4n-?41nN z#wTlxxB_nPG6uN_m2i7_eSnWA^78#L^LN(wj8z>kb*KqKCQ~-fz2d&0zeYF&?YoBs zmJYrI@Vfmkm5SFL_1khtM&E0mmPpdF2M#{Bt`JiX z)&N)Kl~pZvG-uPkM znmML9V^3!wMs^jlJVLceqV*GfW>^&7GNn>b1mZ+eZo;eKlg%aoDCC9eOkO68939vo z|K{#11bCM4501aHPGck0va%X$_rEgriHwzmlU?!0d0u9ST@+;SfGl>t;#N8b zw%GvNbPU7-XJ`Q2N$g)54;~Kw1?#IE?ikb1Sw-0cZTn5uUVQLphEAo#)8db_8x~+G zb=17%eqoa|_7g!Aj7!7O}wext}`FcmH3o=Yrzg z2=XR3iCqSMg6J-ri+)vKy52=qXL7Tmmb;;|_dy}2r+;4P@t27ks#=^|*lm>w?}{g* z$x0KuXhZAAy4abDYs?~XYZUrm7zABn|ItBaTGY|xiy^M=iXT~QNt%yN$S{JoDz5~8 zXIbES6`PCo`T_*wMf=N`!I1hdLF+%kX!u>FKrs9%X0&G-(YzMZWq&;g1_lHjU_cOw zkzE;G9)WI>ocM_W!O-8P4L8&x!m$9WG6)iUkR_#eKQSQqeg-DR_HLJo(Wt0hQIV$s zet#1rCqtXMus|OUyqKrJE<3mgtySYP1BJg^YWFZkvLvJCmZvubIR z`O%(pRkI+kbDiRPw3aHEqp%EN%G$vxz5(~P?VJ2|*A`XR{8klmDQ>xT6wIuWO?o5J zLG>wu>f;5IkPB*-e^Ob^@qDEBan&MeA&81!K)?{dy$wH8>%|+6-fxeiO-=*Ryc60- z4&9^<2X%rI8hz^^Z8AODa~?Wd&bm%f5Ur(x6VBk?gcoz*1%xD)f2^=8)329Qy=Psg z?xvN}{{*hz+CZn3G}VSaRtY;Zm?BwGreG9zzG(YifdSi;_wP?*#O;Y@0bVcvBsDN< ziJ^UXz|QNh@5>nM?5O%6V2A~D;b5NVZSwBVN{N>GC~`Ih+D8ILg`H}a=K9d4tQc?r zn7~O+5m(BerV3C9#+@4dW|IWTV2@c!VVgGko6O86z2Pvl^C!r14Rp!gA^J~2zndfT zER;020+rQG$4D?x5hjTKqagAhi@I&A_TL@`K9pp8kHM8;2amzMZQDlwD^c+r6EqQ= zPF(vY1U?oN-~z?cx4S@5NwIyu(B>D~fN9(>w84wWf1wRnamNn>eg@iryG;JR%egO$r=7i2wgm4Durs;#52;uOI}H?D5Pnc^zYxFACVP;b*`mi)8uGfjd5(LgK&&A+aksUpYMAmZ#se#+ zTz5ZGKG7lYAd$N3AzYQ4RaHfbA(F!a4IP`|4x1vtt|2aK-0j#8W?!y8| zd#JH4)SU{w8{G90xD_lXb}p5L+F}7I)=zwpNjU2oIL*)XI<8#rTLtUl)qYS^sc<%G z9lAb#2du^E<(UyGZJe0hKtRXNLeRRb1M2#tURYq)VJrZj1q+y+n3hruniaL53JcIH z;67!mppM(k-jJN+_c3~?1+PulszoH#Ds02yEnX;T2K>hl+finRM7~J7&CuIoHJD21 znv?HF4zx&T5-%uedpU(@O{v!YA0O}gn=z#oT|PG zg&*4E+z-PY8;7k5KkoP>;%FMIMlpNjRDZra<Ref8r?5bzAGC~q!yyJoFn{O=DoZeE1poHk&5Xf+ zVHe*G)6#DmtqsX0X7lcN50nd8>AZCp4}`zov&c zTE!dozu2#q#EVEGKz9d~S`Hb?vdz!8UZVhOReerX zONV7i|7+vGv*A?3F23uW#N%s`ga_)Oek|_p5XR%u3=68Y521rCE?O6}6*Z>}=&74ax7ZfRRox z0-EiG(L0R!T=gCL9l@=a{t*00NV6)HFjn}FlCGnwK&V}y`c5v~wClh37<}`0NOVhn zzZtE(HUJICq4k*>k*nQyWJi8Z1%S?qk@0d-m>o)g%zKnwOfdzYhaAtG*is@#fiwAQ+&qP9}&v;P% zBpCR98k3Nmvst7O}jrdXNKr*`Cdh|bp7XJXD{a`F$(kC=iHKp`QhptMU8<2YCKDR>ebrSw`L0 zJqsZq0<`{)0Kd(bcuCez8%Zs}zX^EWs^L`=e;SM`{9VWch5~pc%AXYr`~~m7Zt?p2 z9O_qn_zxz}uln$>`tY|pCtftQQz_hVyQ=j6#r0uuuir1U`L!DLt3Hg+*!Wc+{-4x` z!CffZqK(QYy*;SoNF_L*Hx#Z8}*{lAsy+=+MzdLHRLDn)%itH=J;6F zQx=P7dyT;9D#AXY7DJPxioqQRAHZc8XTh#j7SbQb0@Ns~d64W7V7&&9Tk6ciQy^f{@!!i&fR`KU z9xCb`9iVI4kfB-zNfR`q!-1G6HAh_1^*{Ch|AWShQ$oZWicDtJ^?sccw9*))xCnE+ zYAOKQbpe>-`hn3S6vgLU;+dkBfW9`=NGI+yn8((juR`zYubayrn*1m4li!|!3xHgh z;4MB5>-qvc=D~Md;>5&JZDzfCsA)9>N{_s>IsOxDHOeGe{T(2Rm>7&FPHxE#CwFK>2s zmVYod{Bo{EV!-+kSg{08Mc694!=tyV?p+t&;$h5VFwoyg-#fY*3C>t>iXa>u{KMu{fC0=}2l8|1`>G`a%;!3!Rgwl+T zur76ah_~#Btp8vvJI_nx3#jF;s#!1S^b9z%lC!hcdFERagV&}U*!-74<)1sY0B(sg z&mu9WvT#H6`PMuD>E=gX!UED@Df2~m%)bg8c9u}+J4O_)BX)p?a`|MtLh{BSRgtI{ z8060wT)dhuJ}@)=oqm59DshNm_IT3$y>@>zu-F;b0leBJIK+RW;-5OcWcaJJ)035j znC3#r0Js1#m9nmc-oy@gKyYJ0f#0 zF3;|JaLUlvrqn}$Ga(cTy3gjsPnZdDDZ_X>8_ZhWEI|eWG!Nud=tIEP`m1J=0lUXP z8iV8P%)<8;X1?|Q_f=pR!&+Rt6~=&z=06_C>=?suZRXuJv--s<{<{D3SJn7e)%aJ{ zxZ!8;{I=ar{%eiu*BTYLPvF-chF^Oae%oC1Gtg$+9aFSDC`k3lNt9=rVgic$d`WLM z+&{(4@=Eh8b#AIH=?%?uZs)VpmlwRDac*19xr%ox=e{dqLXi<7-PPumer%w z*<7>5Hu5uVn2;kkjKVaZvdfMgm$D-DTGU;B)|x)7$z=WN{G;dfcfBd{0t9DZj4MErdS6$9hosWz4TY6D=q=_YaL@-0@l}x;db<) zX|Rfcvxf|iJk-%ET=pn^lo`xWBDd&zVAg5%HOb%MVLQs3c^o$f!lk#FwSJ`rYEy1y zLtm+Z`g89{#pSo+Y zZID?0xwEmS3Rl$*JkG`~N%7?n!Lgf8FeG7nd((tQAIjb0i^B5==zb6mq3dV;a1RIp zDFB%6bm0+4nn6{F6QjkTsIRO2hX}_Zf zZY|DiueI+h#ygXSf5bgWzT32kkF=GY^X_daXv7^t=+&&=a`pUFM%}$e~hH5z6Sp zU(5zomHD2UCg|KsrAU9NV;(`x^Kj@q+?t2KIqh>!dTE-EVNjo^ikiwi<^T%mHnuSo zSRq*}LDW+EvNs>~q9`WvVugygg_>sX84u!m+kF4kq^NR{m z=7%O@6%XbK$Rvebx|ZOvhwHbua6ay~MGK`1Ai+Ncv_N{+bxx3m{>N>5I(wlX1VEh8 zodkoc;P2oK#N^-4#LQ3L+6Pp$=@KK_vm|}39 zd-^eW%mPk8+4ko#oRoOk33wOInIt%O@#1D?ow#Q5?I!#))j)O`{w}s}eZyxffRf@a z@Z#KtyITy*v2o)@aJKsW8&+_4dfiV6+|(JJr`ja5I5Fhf_Yo$?gJH)46ySj!{&dSY z2flsZId0JcDa7wjB*g6wc-Tk+{`RatzSe~h@60J$kgkNcxr!?x0N8qSU)aD%+b^t- zjjl^vXv^gOwxY|0BPo6xKc)~+48m<2<^E=u!WsC8*_ng0K_$=Z4>^HMUQ>)5J$Ouw z{^sspOMD6;n1lZ-Id^LE+q1Uxwv*FX;0UpU)1>3vwo}9Zg{*kzBjP*mH!--sLxg-> z&;54Wmb6=6UHEHh>lZ~CL^<5EZ2mk)=2x-#*MT{|pJeqjip}6RY;A)!>UYx6BFGi* zadIk_S!debxcFOP8KRMn`=5l3$4~?qQu;U;5%~hCpKrCCa^~(XCqt;iBkS8vY-l0) zeN%ce@~0LjLm7pKx#SK99A-ZrCF|uFdC;_RuQH3d)9FBG#Xl|jZd~e z1PqGIUb9UFv6_`4c|%e+_~gc4FKc}0iEO-iKJ#daT5-s0`wj~00zZR2aSugz?Gk9Z zu$BuR^%?v%4j%OfYENqnbS@%NdMqzu3dpR^l*N08AGd z6Wcl=Q-jbAOdR^w*B#1Y=dnN>$n#uSha%IYhS@Q0;B8gl@gt4t;^#h+KNP(4sI$_y z4?{3y7M0@p`DzoRNKa%?=giyGim@(B`DY76_3fvEn&TV$57XbPzBHgJD|KdMRjKe{ zb3`7sO4rlA#MG-;fTx0rmNYsE+78lnS2rQ39v6jRcj6JVb(3&76!;W}c;e)u)|Fkr zQKn>)7r`Yw@PPgj4|Sekn)tyRm&crU?aqp{Vm`pqPJ~^RbocX~4sE^5YEampRBL7Es2BDB!m3T-3nt?aX>#*p0lw zeJ}Ew9zSBGigT`9UD1N`S?K$IL9$Tz!<;>8*NiMjPaZoV&>je$Era_27OPM!Ak&2f zM#01IC$2~9HH=w5$Z_hcVc|kLJB2lNPSvSh9fcatMJNp<6gllrV&e)q)p|KCLnr5k z>=^s^T1EA@=5@3onyL&OA%_I2>rNhnMS|xj;aC<7&#Kz80&AmaQ~X7S+>UH$ z-YCKJ(L@o5pFHDgk+N%5d8BIUtFR~06eAPAbq>ox1bg>tu696XGr7H2c7c5 z#T?`7H}|~aI4RD&8(`tz-ew3PpGQ-b#Ok8?_o5;%_hq>s9vRj=w{l-UPfI#cmV=+i z&qp@lc4d9_;F-v*tMJI$3aT1L8E<$MsZ$z1J<3HtY-NNysUYm_`T5%nM9s+a8s6L| z1VtB~90))7p;%`z4$r9Yp=#@>u5EFyLaut0>?Sh%zLW}l3CS6p-0qW+Qi*9D;)%?Y zw?eR=msL4*CnDy$M#;@;j|aOHPA8%Fb`^~Jmih(=ThkBf%?@4;b7-wNdQi8Moc8fq zHKpnit@mR-i+iRHnL5%C!29S+b>G}qD0s5Z@7d*w{byin#?#_2@jEz*-oGKEkO?AP zu+vn7S|t^db|iUksBy9qx$cOP;~hptCZ$8XPb`PpPsIb3waW&d^Hiuoj*`FiyY2lpwHO?oV zqavUCMhWv-_o9`Mrk+y96WW$Xx@yBXj!tV!t%`-Uw7iVyH5>l`5!I($eEIql0e~c_ z=o}oBylNrZJp7(j+AeYr6&l==Vs!0044sRr`n(2*P@-ka5WWE-lG5x7uX;E-r~0f| zEdvyps|MFF(sO(FGzCQ-mRWX~+Ym7qI4`AWH*u{9LBDch)>P}!<)>Ce){ZL&$2SO| zLT|#L#g1#Y<4)OiddL`UYZ;{r0Wt(}s{{Yw3y)ds>;>3f>>TLzI@; zJbWnN{1hqsF$Ni^ETi6z>UFWoLzoL!`Bol6PNoFd51+SK_v) zs>I-+`KoAPAzfBnMR!u{Cnimbv$=EUW9^9%r*Ep?-%IY@PPeUgDrVtT)w+=JKHqGS ziUSQRn4^)Wdm6nmPt#@;Hnv_7D33NYC;O7{Mm6Q>gSAL+@rfyk9lS8lqQ8;~%^3)P zo9yxeTB~UI{Jr*R;a4>ht($;2aY}JT=e!ZM zbVl`qvv7y$02*j3|LHatVZ8exK^ZAnD%PGn2VO z9!a4=4++L&cNlN=?%0EyPs<_j2v6Q}H`-_?U)9pia^WJa+ep#WJEqjaFARz|Ly5w8 zWD8e#<06^emF&&>6Ypmv-KQejKjY6WT* zo}d1(Hv26824pgF<6Oo4FJnhbRF>jeQuH?sg-Rj)*2UUer;@~{UN6L;XFNmLM}p7@(tr_EHiBLm=k(n-kjWS3hSf& zgJ)c)^Jr2(8ps%rUv}any}yPF`6{@o`g-sqZm1z`B^*wX&RayW^@PBX6haxr6JyMJuV%)V-A_ zW-7V*4wu6&bfWoFbVj7>TZ@(NP*Ce|CMlIDou8ozI{&s_wcegsICio&F|b^JX~{G~ zM{mYakc_4G#+f5`B$nj&fOZ=HF&@vFvNaGXwUXRVCc9;hI)zaYf+>knUU{L=S*r#9 zn^h+JDhe_#vYcfi3-w$h5hS}omDP`FjufyEa?);a7tHMtY2CcJarRv%rk%H5E2ix} zyJUXz9cw1x(0Cq(RRLlWalX@w>bUA)!E^TOvC|zn3dEXnnvJvJ9wMF!{P2|+80=Eq&rCfzvGhcNUv+{3m zPkNq6_3?)6x(cQ9n5NzdBwZk!S%UYfa^-ow{?|k>j*GcxCWCA_LM3wNtvsflQSrX` zrz8pv1CuDb@w@&=zM=XEiI!V^nTDJNQ7xlJkG19P4I?yZ2}0Gb?|sQ|y?Eq28*s1S z@0|O)xNFz}3k;Nj-|OgIPL+N}ex+!_&Z%Q&Ki7tQ#@%-fwmxe79*d{BA`O5v+V*3+ z;=u1#GzB;6I;D^AEkimS)7HKu^Rc(Lwx?^g^zox%Ig7)75xS`d-g;E-=DC14T}>~g zjWb8#XFaRg0a$>*9t-&Dv6S~NDbo+3qI5~s8TS?tspSqa@ya$XS_UT_dmAWlA=c!; zM?IP;*t6-KvZ(Bv;3>Ef{DBhT^Wb-zlW~Ul-mxU=tRtG`i4?P>Ebrra)fiZ`=b`9| zqil(e6~}P^Jm?M&iej~g`OL198n~hIrY41r-VE^wNMUC4l}_3%3wogR!^*(KLIJ+=gyj&-x1%N z7%{5+=vpkCJl${1tEJGh?$yJR+d*T;ISe@fC(|9gZ26cE#Kf8kl^m~R%_?s)a=1Gy zKbw-bH(KganvQ0D@bM>B5Tnx^f%|wX0!=5I^uvZ3MY+b(kF$Bz5Z#TZq{5RAZ%R!U z&0o?LafrFus_4?{CT(pJa=^}hl6Rc?q`siql?D~Nh{KA6QjCBy-XmhH?F$OSy0zMJ z6%>xO>r4_7fVGRNL6Id2*1U(ssJiiXZyTpr?sVwB8M2I{DVF9ue!L?sN(;l)4VX)y-Z>Hl`l-uH&mB#ZN_l_8c(eoIFa`^W|+S!vz zjnR|GLUCt_|8hbtL@Cks)lw?K^I14@VlN50oO;nYuBrEtwmiZt(foZ{qjwNROPWr2 zjb#bLysPGh)PR#=jXPs6JCb;K)vsLB;)RZed3xg8h%Tkn3|k)Zm%_1%q0|>cgFYA% zipNvMl;hS*@S~+{{Q?xH{U{|`ccN_5xn=YU!s~3L)`^TTy+r9x1FWa!_Maon;r6|I zLxP~qeuR57W*pJ(xh#E0O5OS%9J;rECMqH)fm~B1leggNL0{txN>7XO$pIg|& z<3bi8odcl=_;s@&_-rUMu^wvAaJoNnF%Kc%O&3-X8!nT|Gbj0;4@t2%!!Kd@>5~t@ zy#~OEqo`D;qmD`I4bg6uI}(fJLUtS3Y9ge#&gPuug@|fZ=^k9wMIK^dMcC))zaN+t z3#GN#a3Om@!JFy05O&u@N3M9E7`07OU#h|ezqy)Nkz*wfa<~vSevj!q>|&2hop75Q zUlBn`;nmv=dXzcb!j*=`r>bv%46j}@+!p;hz)bk`MDcLnapbYd;kTn}WVzZ@C)P4V$?XXuGwwKj7kW&y z(z+kgLQ8h%!#=xNLH3(f9_~u$5#IRVJs0%w{NmYG4nB>hBZ>#o`94nXy;r?Bc*7ho z)5j0{3O=iW)sIrt=~P!Wulfj~*DsV!X$Ez;x!>0og|*RGN``B^%kg}AT`8=Xw}_pM zMIRRquD&0caa0!^RR3;6aibIlO9Mgp~rtdbRIB!`;=`V~Dwsr>Pc< zYz5(rokQ0J{O;;dt7;y2>(}yJ_R4!9!?-ALxnf&0ZOgv+Z=6(^pcW6RuPu(u*eOt0 zTAbW>SiXL?nWwFNzCxp~0xh-~Hz#%5)lMb{P97}SUPFIH>%xljwe_UD`~{n``jZm5 zM*{Df7(OJJq758V_H_0Qkuo(-lD{Wik{al(W)v!{FM$B?Dt!;3H)Z$H)CM0Tq+PjQtHCGYm*cuM#;b4E9BC3S-X!b=sE zN$SsI`siZp+vEAgYU(B4)|^pXgN`S1o*NPhrbTkvXj`3gbT!<7IC<5$Ga)jEH(TF3 z!5YGbco?s#*?If(vs3MP?KFPl%aE-JG3VoxJPI~c3?*O@CCj)ptoOzjN%36{jT#>& zR5p)SB0t%mPj_`|C*N5xm=L@dBy; zd4bBul`3`CA719tegJj1>0)<5@II}UU~|i~C-stiWXE~@r_LH*iRZFn$Z7sRH<=Ej z4y?F#qYdxChgyd(&J5Cf%`$nJ3D$6VU6Kp( z@4o1@3@s~`ah~F%VO=xEG=G;&bht7gN(yQ~lWEl`Liqaf&G9W9>9%TmVny8|@1v1v zphhXR@t)uy+e5OqG*K&DSipGhMB~c*YD27KVF#L@-F*K{R7$_e)9mElF)`5=OE2!4 zLQa#&H@8y`Qa$t$A+>R|5R}k3yg&%C%Cc{pz^Xu3$j;I)w({j z=M_I`C3sS696QG4Gpvz*&@0D$7dr7!Z(l8RAf-v48go?FRjiv7&2DS1k`Wc$)?%%s za#H{Bc?v>BA&E4$+t0#IU6s{ASnn|M)4Io29DP+0G!n~A0dsRwSKSiyoI={qSZHd# z==>ZdJ8$LLpIchT-E>f`8C*<2egVI`W2c~^!|CdoeB{wG>m+>(I%mrA1ck5_R5P3Z z&2x64)QapvmV*H=l>`VY%?KelW0qnu%$u25AewhOc(?|vY1qVXmAqHv-N+0#1ZD?) z8?XSaE5EPWY16THM%^L;7EgM~LEqD?Z^6YH|^MyEYIms#81gTyFqeLBf_Od$QX11*26_>d#T^3h&C*#};Vi;aGsmVo`6X!9F5a^EGpu7u!>o z#lleXqGyOEOXtWu zom28^g0uyNPfjq89XBENyG<2QT7|k+wYO^e70LxH&xk-Vr{k%xJDsBW=UFf6m8{IJ z;>f-JU|lj+!1t=|u^Oa)Lk82SaiNQm>Yc+0gA3uOTS^m!<_2wLZ&RR{X$Y2l8g=y=B&Ew-$^IZuSo9MGVSUBqu++JL&$~tWqyg=pGUMm!yM_9N!SqNxCJT+sw-^ zDC}CkWL*NI<(_UK~bY1W7PpUhDc8z7`unbhnMm= zq=D6^iqhd}RI5JH&D%R7(=b(A#5a6jmCrE5&GMcZUoR~Wn&bK88ac`3JNm~vWLd2( zSo78EAp4Rk#Vb3Px%nBj%^2H#KWAhn`fl*DcTbj_y!7!YQQ!wT`{}DKH$EIEK4$@E z{B2_cRc3ajAX>V&@)W8G{{OJ|-ceCCO~2?M0!kDlXCz9LoEa2JA|fa`iHIagA~}pA zS%QEBK|pdGkTginAUT7QXNDYShyx7c-9G7k-t&FmUH9C(&RJ*O@A+d^?^%2A?ylb5 z)m7D1ze=f}#!5;R$<3|TXQaNb*-1dfmriwiBRx`Yd~=g#c5RJ&WQujc*iiJ$W=3!2 zS$44;7kO4~#Hn85v`>cV*h}`LaItN~>?=T7+Zdigd@MOe@3mR)3}Y-HS01%eVz1nW z)&|AIDOPPhpPF+3&roe@7II}z?+|hlpE`v2FLhFRD+YREhLHi+5k#@OM|-5EI=0yz zPS#e|G^3B?X6=tFOuC#F;*M_mBa06 zqk`o^noHk{sc=R3`AN3dl8caE;IpK>@YC+{O&z4%|>LvqTjH1lEl;e(5B6~s{oaNo_B_NkH!1%*29 z#XY3rT2h~_9^YmbyZ2dznmDhPY+G|ChXyY3@K=6KqGGHldMIJ3gpGM-^UJURCat5E zQMDpOKS)P%u)1%|*{0no^bBWbj1@820`9ZlTL0dGC+dt-SMn3#{SQs|yGwy=ko_!ISsMiqO6{NkaxfFYxP zUMEaSud~Dz-RW`Vu9u#;!c*m)N~OnP?zLHANZa-_^Gn0J`$uV+G#I}Q#?0Wux!Ktc zTgj$bGj%5)Q93FGJ#~VP)Au29T05O7mouZ+e-CD9hBagQQ70xCB$6%i>6RsGVkURX zJ$uvF;m$Nnr~O`)DFZTk%I+OU=bT%|B~||fRZxHsA~PIJq+pBo(#3o%*_f$G&o3zH zl}M5jxJ(Xuhy~UL@Bmj@(`@&j)&g?$p?WACv-&&xDWelr^ z&UCkT3uNbez{Yo;)xOs z&rw<;fpw^0t9)Wi4Z;QvGm^R9WCT!C*kFXPE5M> z^|j3{H8p-0;yR92G|g!*2zsyIWqH^j-+im3MyAWoj;+Q#x}f9YQHNal+v?>Bp~FFe z2cruk7J?xA>7rMxD<&s)u5I~b%s%lhM_KRVEEz{tU!N5qDY`O4S-DYb5igWjXB~PW z$XF_o@EXp-p382tFJfGUtVA_AKKRs%fm80SJ zI2GHA3W{$qZj0a9u&cFrRyY!FqDBV0dDXI^I>F4PW0B4qzwN+6g)ZFxQ8vVW1D36I z!TU_S4Z@tY`tF-n;S}O~AqUH{x40p2Xe)RnId*Q`+qsl z`_19?7|M%qj>`pfZGV=FPm*L>YUs!H=Ura(0ZNE@C=_92Lvo|R+0ICA=~7r|FLJEW z1HIJ-q4Sr_U&qOfJcujoE#34j%L&LA>gq3_frnU2_4)+%nW%>g7GgAzkN5ASw_=k4 z)@mEp%=g{f3oaN)1`B#V1^E40Bd$E-Z+X5C70P>OEwyvrU;l}qdk*^p(Xbc=rVXU` zPVUIy1_TDD67HX%7zK^y8xt`(%#=M&m9nih!ChRTx~p^Fa8{J*4TkozlKVBkWt_&_ zY#{*lR;&!>oeg5=CBs@3ta{?}Gnl@;mW9!h2>Fp=Hy?E}vTUPleWR(A?B`g5#QQ z63JBQ!veI{n?}nMk9Cy^0u;eJBrZALwRh2$A+IzfufFhSvx0w2er)`(hs&VI$z8H) z#!OZ4MIQsz?HgazovAaFtg>G#eZa(_1>oRL7aC(s_SWtC@tkqNLjheI2YR7xPd8Pv zWp{1Kxxp)U?<5T}R*5b3AFRZFVVkjpch!_7!sR0rZX?V|Z8juf1p1Xbj0N&+FsipV5w$J;=y*6$?Lwnf-e~9+Hohw~ zGqb=Q`mj;}wi@!b48-UCB16F-5_C4+W69b`hxY0)agIeoFK;kLr4AJoZ%WTRoinSy zD5EzJf03NLotNt!)E65ZBdNo6bB-ML=3M{#j6Zl%LA)3v|3LfB;{CDe9hMyeL@Qys zZ}RP3{c_JRQpP8vJs){~f=n2$(x9OLNyUM;u*MiGgeAFmQU`noR+@~HLEpf<)02yG zRcC>HTe~!MojRUDJRna;o<(dwUMI1#+X(L$h-2VX5CEjRL2V zADM4Xjoq$aQuiShyGg)ddvleGJ^Wjsj=+)*gTEpQy8BtE1~3TucsMD|dMrfU6*F1n zYS(;n?EY2&+d~GWE+m2#FOD@pVFsypoJ>Ds$$ ziB(3$hUX=ij%`<4l6+rxpWCQ}!m`LFYu?n@@ATcv8Xs75toMmXd{PH(p~1dD8I&N0 zuXrC%1=v2G2xK!|fB!?PQ1wc(L4r<$Us{9+vo@zn;*&Ung9s3j^U=NyHQq^6?G6*l ztHX09HdsO07CP^3-E|hz;0IMe&8qmg(3U@Q;tU-HrlblvqAT~=oSNt`o20)bIx`r1 zA4falPn?|jJ%ef#IesJcf-}t^eVo;TjOncq*HeBDT*mf+LZJ72mDXjGq;cH+gpx65wz6A8t-!(&M? zObD-_ovHmL?@IYA5SJ1UA^M%B?vuzRstwH>4nVKkm35Q3k^0Aki@BF@9$;XB&aeqNsc4l71 z^gNEyd{HfA(vEu-EO2ksWR9!sny9{@{sX)x;uA47J7BVAVT^i51}~bhwrGo$2X(f% z_0ZvqQrHb3MZ5}W<+rJ6&mA}FXJ6bZ?>BdRb+WOx6al8~{S75a3{4T%s1EZH*-vKR z7oc|Vcw%)dtEx6*O1^0Kev&TB^uv$PN&4!(`_C$a8Po*jZ2@7fq_YUR-a_S(Nx3y; z0;?^+ykE>uvv+#wyrXBwQ!NDqpvTb?*1j@Iw_!D=-#;!K?gk`VM>J>GA}Z7W4q7Be zA>l>+agK+7g(#`DR)q27RnW6Sc3Wn|*J407X-@fyX@U#<1ckFwqNyt#ea(~J!Tngs z{nDlMVG|tnurE?j#X8N$az3ASymUmxO6epI6afu#t#ddclN86kRZm+`qFLs66&@ge zZ=7a#jQZ;&vi56|R!@DRt!J$@a~j9Ya|N<((bS{2=UP}9Sj|`?uN!Z;f>u_z@j1k;i>AQXY+_0dSAe1Y}&5{1G-9*8F7At{&$S;}E4b{^LV8MgA(%7VIN=Xu+9@X~+-3 zr2P$OfIw4G&8rOYm#=SKSLcnt@=ecM@*o6YIGN!scA3GJ*Ir>1=#bUZE29!&BV|HI zeDK<2y$NB7!snsza?0IHMPFl_3fm2z&E(a(Te4#{&|X;H#cPdP$XKpf;ikfQOTqgp z^kWDEk2}f?{8t!yWXkw|4>&r5v|F;iY9X5Ur=KW&vCH!n^U}req2Xf^1+Uui2kmov zyk2oPL0`ji3i>($SYTqix#6F7cpslZl&14i&Q!ScXSPnA3pB+*fnRP-u zX8*=A>n=+9+EvK{m||xvL_78LX&| zjAk44U!kPLzXMxEVAFQRN z8DBE&56i>~FbOKt1q{6uMH2wKu?=c5#$ObkiSPdaWnRBvMnS7?MVKb8&S)iAKDOrZ zjfy2C`$0sbGg9WXWJslr0d2>jUGDPIOUF^8Q%#_bsE_3xY0MJ z!An~aq85G6zsGIK@Z00xRp|fcbFw)GV|{+d+r0yD$PzGXnSSM@bkKQ> zr%f2FuBVWA(!(!iP1?rtQa_9aJqR$GvM?n0O=?(|Y%{m_S;ylHvO9Z^C)UP316*@V zzOD@5n*P%dC8jo`?gLyi@rqcfk(UlS8EzQy$aFN2YfFi9y0pg0MF-8%qAfKxvpheO zJECppgqy!1Nanm=A=jr+DY~+wn;FITnS2_d{;mbCgb6`dGW+oS@Yqq?Jbn6@%bcB8<`*(;&p+lSXi z!fX?ynJIjqDGCDx{BpoKc}AP1=1Dro@j6kH9JV zUbzl*40=B#e-kbLH<{e*z6Xw3uvvzUxCclx!xhgXU%i6C~FL|9fdd1jXJx{49XDWfd4%2NCCdq)@k*_00-LNTVd!mGl^ z?tH@+eUJkX?D`*~wclT+ci5pwpx|%sqF|-mQH8_T|(DbCx^u=l<;{ z51^NoEC%zDZlvF5ZV9YHqHxlqO6=aaJquJ<^|7y@)RYvhs5y-|6qe~oQ~F#xxa^p6 zmz@evrnlR%{|^JA6`Cy?FuGY1_=}?g+80dALpYjiC-RJtPxTHS#;oMp$g606G($eMmD*a*VENMh_HVu*eGv%S@UKP3764}&nXI@)j}nO1UO~MHT7R4 zSO}f^foA}G17T-y_gg4WS9ck8NGHlj!A6MDBGv9P_B>zNW*5fGFHz=UZ!A;Ub zk6$=UveQ->dw zXJMDOHnq{EKVoJne#0_{aXGtf(w$B6-^ZV-xy$1+YQ$tX7G1KTlTv0K7}+}0{K3ic zp6uI{#q2Lq<$1upm?x{!>!oBR8)}n>IVrNyX9D;RXSy{3e5>TZ3u~z6peT{gz>S!o zfByV42LBu9!6ul(@w!@NUfoOwr{HJgx`qUh14gZ;<@DqysAnAOFaW;xOe5}jCHWG_ zNVEF-R&)Vdy17n7RnN+HWlv&yOB1v67M8j$WZ)U#peYIc2^wwzkYJJOSWc5g>^Tt8 zxq*``&Ae_K+yBERRzM!&D>FZh;rkC2xD$yc08S)RwLmN=(19~ZG#e_~5puBi3z-Qs zRq3yt0T!`IQYhWISVwwUE@dh446`Ly_Olvz;tt&!%2B!l%-uSFYg7XAx89iaqNTjC zO-V-kRkbHM(esd?U`(1qphdr+kMZpJX!mYQoBAzx2JqjS9R2s+IP!M>K<*zKTlWnu zF2qQC;E1myUZ79?1S?i-UG~(O>VJX=nA`r_4MKD?mwb1eWQ>8r4y()kBOEcn^V%Cn zj|8rC);|1j$L&)n!$})}0O30w#WlHY(&ZG)w@k}@5|4KoueC?A+bV!S>B*`bu|Q_~ z8S$;=pctzI76O`KcmM&t1ERrjmDh*ZK5HF?)gdvtr@X?v{9Ls}7MYG)etA!?uY z*A;%QIj+S@t~o>01n*`;m_l?9LRg*fo>|QC&G9Fvsi!F$(|Hj~6X>u8z>E&I6Sc z`BeK<6U2G_deOq^*Td%jOCIJ;2imR$+Rj-cR)8xTHT@!nO-6T(_|pFjF|MBle7y-qT~a8vL<8T>TRt$v>3?-}s+l`M0V6f9`A%P68IK)==(&9m7umlm6crKrU~j ziT#c;WkuJc`1_=1`eBmk;%>L?!UuF5qUt1O_~>n#?D~BH6BL7siP%E5t}>zNR8%b# zILS;p`s{p^of~e`CGjTJz~t2l*X7lEqekw48!L}-`UM5Ek}Y9-HCG<=vd6ysvPrI7 zrtNQvcucRYX2aS;vw1G}7`pSw%TPwPKz?5_8ra!YB-wV^`eOemzqG(b(drkM*M5SU ziy*+Y&IJMQuj_Mv-u;$V#l*mMAb(u2xGoNkE&TJMgaUV+jT%5?)PtOF#$xXK1DF`M zH38I(;=skL*m4wwjb*(w7*09?`3m9xvjm{>gL}Hbht!$4vz))b?-GnN#1K`M&ogDB zLLI%6B$%)z;mLoOxgknYgkJ1Q&O2HK1f&c+%@iF9YP41vF`+kBz$NJ|v z?zn4%>gQqmIe(O;;J?!i{#%>J7@ZZ!Yd`*r(K|t&R{t7@ ze`=t=7FM=%TR1n6h6u~U%BScd+p<@@0I1rKMI{Ce`A2mYH4l>g#F?rBStmMRGH3+(pa7;Qdl^_lfU34??@n*krFrkuh3`9fxm z_3TJu#r`Eo8`E%iGj6$$qn#%Gp7g49B7pQ1I^?5tu_UgKN!c>)PR z9wd4ohhIZjnyI~?O4gw*Djc&Nq@*Gt5FheH&v7#@t;rwM(Z!8bw`dwri|wp@7_D=D zf2V0B?)6$mW+eeerG&hhO-+GMvm1>i)2&(MW~Y2Y#`3-oQ`i%UvEN`&ajEm#Jf z3&keBam(HKg>N(3$3^j~3(?H-UX_(mL3o#6$`tv_0(PsOj9YaLm8j&^R**zw-#cHw5LU;-|38DyQRT@2XY*-|d4lU)C`*chGhv3t0_{;G( zD@FancrViXdj`abLPcI_;~%?^c(4HM-)J?hD;2pJi^7^Rbp$3?mXZ`+rTLWgTD``t zCUkyjg#gceA72?0fLx^Mb*BiyN)~NV8TWk|f_b`|(dPxs>UP@A8pB|CZ89?J4nmf# z8PX_RkxjPa0_()9d3C+nV^ha8&8!Th-wR8A>4(F0-J{ja8FJHGhMjB?jK{HX%bB-5 zxT{|#1KAwib>M7b0&iGqE*g{Zo__3kze|~~HeYAyX#`VwHGGloVNQY+>7XFQnqd+O zC29)$u;W-VxV-@)Kkv;L_F1Gl8`Stl!;?<3tmZ{k?l-#8Dz?ZX9ta zdD4p3Z2>BZqo88>w~7uEkS>Pe%(JK9LkXh`%XA_zxW|7I~8#)``fr-v*$30 zrrXYk=T1s~-kqM#57v=Pi=M`JQ&vt1)bqU$rG<7EH7GYJsHMecLx;arDtCZ+mb@V; z@6~U=nRAO)P+;~tJ>Dxgs=c#fa?diW)o=tth{HFHDgDWi?nS8Ra-=~ixwssJ~iUclj_zmG4DYQ zJMfU@iJ^Zj73i#@a*&>;Y|{poQkd=e2_jN(LY;KeT97maDL&mZfCU|Br`@ymAYvq{OibW4}FZG~sl(zG|xV?jsN1 zc;)W*T-w=qF-6q?9aIA%ti7BVgS?Az^gx({4H{A9uged$oP5d`b*d7K8tcyQCmo+< z%%fD9?{<)l%%~4g+q`Cv9S9F(^~NC$>PMWg;zj*M-y7ZLOrRfj6huVMYT|FDeP}@i z;VBkF!-5)ZinkIl)>_(8v8hxr6C)t?CC8kVPBku-H0F{CW z^R~dw@>-(~T<7vIPq}b$k{ZHKMq}cM|a zNRvIsTH{lOm^n3y>5G<-SzDH0GDOi95pc_JR;e+p8zMka(hCye#8oxl9lB9kHfCCf z6r-`d`)IYndgTto7c!sA5T-@}1O+8lEdfy*i9l0?9mYn~3+Lp{&doz-$fTIIa#KzD zA|PV(PB22F4@Gx~(4?;e9kwi}(dwbuRhgZ>imQpN*`cP-8*1YTGDKrDIByhsEWfN{ zj%+O-Uz`<305K_8@PvY_qgRdtY3vyom$2vgD*uD*u#n~OCRU9r?ysmVY( z%-I>3-hL+P%P_&zmuRnmfCMCFCAW3Y?PMU z){55+5Ar4<{m6PqU*6_=o4Qo^nLO2!5!2^q{!bnBtLo}g1axN zbEr&<(Et5hjN|-gOv{o8QQ+`QLHk~qTwnoPgunBYZRbqLVVut;COUi0+6s*aOHqT# z_Ok4i>8)jpDS!`f{@cCC(2Ougd~IhQ-^o%SAMF*-;-&!r|NRclvi>%JW^<^Io~k7Z zV%+`_t!?v&Pv=%)j8wwzihKIkt-T$ytD}OkXg~oBpuq9ei+{Flck6?)l-5kF;__S^1{(CO@=SdVGuHqwv295Hi2lSoSQ) zZz<*u8A{;=KX3eQqlY(~^s*7jNd#ayd;z-B#JdV^kKLBn+3P)xMU^Jqus7CxztOd2 zoiwkuxe5LP1-JbEguow9lo|K$=6HCpeK*KlOgLbJs~^)8oGfE|FuJa?0h1eS7w#%vuwTZ6nwqOd5mwM)`8@X%ti83Jra!x#cz8`3f<-@gC zI^_a{_3l0>&gk>gB-j42QmM8`73ktrnI5%MTq^yDOeOo z{nxv6_{snIKx8kyJTII#{}=gxy=z8p>A_S|_%D+F8pU^S2ApYTu}ZEP9Aq1$EoWp8 zaUE5E&^)oRo04VI5 zuix4WWHe?9hsUzhxo>RCD!wVVY@7_F#NM*bU!QUC?l%oaIF@9SWy>8$yQ(}n!^a)j zd9T6)sr+Teo0;vy`ll6CE-g5W6?R;)xhyEVbkG;KPH|Eai*ZC<@6M!hqBE-5KiuI? zDW03NJxS9fTe%TrYERFV$gsp5Bmj3~h~__BiR#v0?kKP;sTo|InJj>2*P1kBLZ7^x z`O5gde}9I!Of+|m=R>0WRzLN{#F%61%O4E_CVR@b(FJL>S$nH|QvioaLGODo=g7*z z*<@iLFIEYin>~)u3EA16(T&|9yG5THb<8a*sFc?-FS%uZ&cyq^4|mgAl#^7j^`U%F zv!~9gQsPP=_~N6#)6%?BfTMP*kc$pXZ$ITjj~x5us+5@9x-p&&te94w#wb>&4v$TK zZ->b1ev*SkCk-MkfjuLu^sEvcdL9+k7f{KPs5*WDNQl(fK{Rxp*|Jk7Bw2~P7KSE_ z_N*Tc6Z!I_@!k8}Lu1kR6j|%OuHNN09L^|~=%R#5YgSPd;gimxy`pQq)v?Eh--5u(<3_$N2jmL+AEXXpQG42iG{ETq?%yGO~Gr|+k<>$PRfgZf}R2%XbBn@dCe^Lj1Nk@Y^;hL zVOkz8m-p4l+V{G-RXNO_#2w&IeSKEC{falMz4!c9;Aot~h@Bo*0!_Rr{ZPxDrf%H% zax5tsqt=bGfkd^WTb-|j>ox`Y74(<(=)CC+obbD6xKF~4Bp&WK7Mf~0%BY<~SNe*- z%gD&Il~0xjFWf+%ghT8^X2!awA59!7s_39vVmQX0YUZcfah>~Ki66Z!7+v?6FP4bI zZNw1peTD~qL_4ZoB;nWsC$>Dm(Za$2wxdvf;Q>#9d+zMj{2-F<_ouBA5tLC<;#Boz z(=s?=(bWCCViQ7j*35(~l_A50$$z@erc_1bIS6_VZ{-|F6mdE=)n zXw22w3c7`mtg=xw(_mRKMK-8CWCK=YET*Q&o2~2Y8>%^(sVm>Xw>Hd02>JqHsyAfR zS0#J%fL7kix$PSfGC4%yIuI3azVIC*4ij=yyLK87l zUhV(ckOOHMmPsi50;`QmT7;LqeGUT?>O>=_*lWFyZkL+gEe^h4Mt#@YRykAtS%vJ4 z*I+8U^7*~!%&Nuh;U(~!nUmmce=tk`Ml-p&wbs;&S1bl=57YEC`l0jPRm7Uloot=5 z5b}ELT@m`TRjAPaD837nqb@6vd_}{;h&mnLmFST4`VenEGUoFOt`Sz~j$)2(bN?PU zamgE8WdN>B-Yz*8*`$Ni7)CYfv%SNy@^^T_S@@hXv>J*Y*K@McE@iPb&=V6{n7xn% zVdYa9pn2ZHoOXFp@WeL;dh*wNXc9_9wUrE5U_csy;E$jQ-8ttXLiV242!xk60BD@WlVT5ERyQwBAUqNLL zF}Y$yFV=Aj5WTK1qjWmv$!8H#9~EIyLY#iu4nwr{m3BHBYx|F@AE^bZ5j?n;up0=u zD8VXGM8En8iZIb*kkDZ?nl*0|!}hM`-i!Ij>`Y7 zh-$A`@b)qz<4zxJU79nMx$*b_B)mntmx66|)j{}R3!lok5Xs&_M@IUU8Pe}J^zoZP zB_>zsn6L(;fGh2;g7QBe$bwe#sxOq!qb!B&)Jw^)Js!HjmSH} zOCB9s0H*3*Xh&e;HwQp2-Nx!$d*otoRHk)GS8{ew50iA{8)I7}5{CH;In)PeZqG+i z1eUHZGHb=c{FPA9N%Y!I#LNC`N_niDyjvC?XmP!%Lq$S2^jcT_^UP?!AU%1Lo zZ}RS3M;~Zl!1?L;DxwSC#hc)Hm6P~UdN;w2>GO!iqEla7G6L)P^njGy^0gs!Pf?Bs z`Fv3|XZjmyPn6I~s zM5LN>y1ia$Y9r7!G! zyWgVa5r!fDDiFjX38u<$^k~p<;N0dS{i3UBe)to@SYac_BVKzSwDa}Tm&*r(k0-DJ z$R@|m5zMp^nl%rCVDgI5IJ&vVlXS$&nexM#A?kJ3ipGnW$yLkQmP6pclJzHOOZTGT zC+I#Hy@#uz#h>>OiD_Z-NY|BYGDQ%Di%4GCv8gnT@X#vwU@{yl1zOc^mz9d%_#_JY zB028Qj5&Y;vBHor$(C!}Cy}pQNV)>ZGxO6e&UMbOOi)KGbUWJPn|xbdiM&br@?KJh z$Ux?Q(eBP(>>^Ag7ANNYRTjwnmNPrH6j~8*5+2qe5pEG>x-f52$E7z2lj`kLUFHS&U=!f7u}$N60=& z8V>&_D2ur0Ulr?4)VNgt&?HK%^^~2@2xhxSg?~w|vZ=V#HDd6Z!c_Nw&uDf;EMJ~WQqgBNu7tX}HLRT8DSL)dH=L{y@_JN1 zC7Je7M5LU#Ut+An*2`IwYtpA6b=9`6E-o+0KyY`tN?f#;D?^jFsCdU>ksLMCR)-K6 zo-r&!50+TWay1VasvbBsJun-VPU2AeKqn-F72TO{-Z_GJ#F;!uOptb%O2~UQIMe)j z|AzV_)9%WFidvP7%zL3wV@OY5Ah<8+Bjj9;&ES^}?joI{1hA*^Ur}5zwC6leUyY0sx74N{5=J-xN!buomXZz*{S9F_!`lC<- zqW8C#-s*qb8FadGT#}Y_b}ZIXm38Fu%b@mS2w9(_B+i=+b%sPN3jf;S!EbwY;Yq1JilVB z{Dp9hmZ^F}66*f5acG5`t5Byyn)>|Zq_z$bf+7dNyh`t_bNuEfD8vfRB(mK#dMNb3 zRQu7rrfP#U-8gvC;_V!_-jz5rn71?*>TmPsh-FxiGzgtb!3c zJk*a)-vq;HoiH|^7E#?c6Z<>YZLA79Vty@%Jls&&WQ!<{#`{&?=d=&t|1hhS&9eSj zNPK@j8W?$Lg<^X>!1Onh_wNg<n;nP|~r_h-t#3qNl< zWBwF(iYH4%FsC{_rw<>=YZIMQoIjoL{$R#(tC{y)fPdf``h#$39nmMsZ^)=+Ki)33 zt5_x!EY{ASuGC_SG5svJV%5%qK1(5i&nWRNW$XPQ3ZbYc7$NFw0SxD0yVV&d2;y=r ztlrwrGnycJaO>2S`vOtzRwZiiO?6JAZBsz{`0WUE$KT2YF)yVdEU56vxi-ku;6P}w z51TB≷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 diff --git a/2.0/documentation/webdocs/assets/create_dashboard2.jpg b/2.0/documentation/webdocs/assets/create_dashboard2.jpg deleted file mode 100644 index fe5d768ac55254251e0290bf257178f5ff28f5a5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 99202 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 VpZA7$|BLY6p879RPTHR{{{y>cvoiny diff --git a/2.0/documentation/webdocs/assets/fig1.png b/2.0/documentation/webdocs/assets/fig1.png deleted file mode 100644 index af9b74e0d1a872b8d93f71842dc0063bc8a86092..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 61774 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%0A2yiQf;;tZ>Cy~(0|rV@E23hi{qry2`9M17dD_ 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⩔{t#cJm{g7{hxrivKItEk3H$RlZr~j6G_f z0q&x8*x z_llO`7dt@G754G`N}2_8H*tg$1&zHRSyo?=pFoaLx7TBaPF_$g=JXqFxn6RG-@^O? zxB%b)L3#EaL0PW5B)$W^3|wWR*=|GZLMUeLMgMlHgt4|W%Q6b$PSX$WjQSc=O3At2 z-U+P~b>6D#*-FC7(wwk2k*r!MLtmIa@9(0O2`8#C6P{)FhfzE=eZ_p89FJt z2_Zv+A(Xh@vW7oc;5svMfwc^6fsq-=@^Z9TQ(>TzRl;MuoKd@3?A32BfHDY zt(Dwib-&L9c758N!diGFZ4RRE)Z>an92p&?a9bq4*siJMr(_^9BP3V*dFY?rwtIkn zQh%o*pm$u+Lo7j)Md-~{BU@#Qq7QVd!HR6}-diU!ZbLpuoi2XuP@x1B0t&iwo1_i8 z+B5djbffF{4#k}wng{KI?j36Qc5M}Q1vAh$3+yn@3XL_*Rf5rqBAL2Hj+XTtoe<4rTt{JgW> zUBjtsY=5wfg!(${4}a4b#xmXQJKs2#(=v3mt8?! z0w;m-bRQ`8aqR{Mv-y1aqw|+tfU|wTgdd-NE%ITRFF*`9jlHbN^F(~}4ld5`^RyVlHYc`0N@e5V| z?XbKi)=5*IVeSpyT%eTyvUby6cioFfhntaM2Jaa_GB|gs$D9~D9B&SAxXns(<){~h zHL1BaowAG9DM2@#+N@~>Fs-{;op2K&vr z1LQv43SprD)2a`8$>o_hBw?eue0T@d>V5~oiv=n`-+g2P9IYC(&!;G4B){C|c-E_k zMty}B)`9ieK*)B4hvM4Nh{wgHw$X7wJjL9lZ;{L+7d2^;AUxX0LsacY15kPgcf zUlpFfmGWsrV-dMI_x;4iMW`X_y}Q{msv$YNf{34pJm7~kCTZogribMj#N$sv=$S$Y zmhVy_GlQ`5<*j{f;EHs@q22Zut_uRtfZN^-%*?Jyrs5Fdf8G{{GkUVlte9zY8AUp8 z__5*O<-f~=^cN(KGzhRpF-Mb`?dKU34~rW)n!zw&1FMi8vLA6FGduCeVWNtWH9Lwo zCAJ;wkhxNB;M!12G?32Ot1{V#O29HS31(>)*`lQ!!BqtB0uUN!3FbLQjp@2`M?eVe z{lg$3r9j=l-||PWvE@Urb?fG4m$$d2*4#g6wnKcy?g}uHVcIKcoyS@p#h1Ren`NvV zBCy@2%B|6aw>MyirBJWrdkE#&7@#PDjZDlgi zZJpLq!M%(lCHck3AjC4scyYgpX6)$lPuzYYId(aJqAc)VC7adLeZ?Ylw$T0HojeewquQt2M%$MZ}qsm*LL2hSnbzy94YL-w$ z6qt?{wPBMSds2w@EJRSk3TpyV&N;fWv=-)4JGAUFZ&}Ru6H-Dm5+MqAT-|XF){;Bz zkFW*b9nVKF@}O!Z{X{oXy;d^L|3&z*0p^{j=N+IGeHs3fW5p+$%{YO{u3nJIK)q_2 zR=wFI*tW8p;2db@A|V&@(ybvNj@xPJAfAnMM_gM2ykSbwpYsUbJ@8=v#K-%0@3U&t))dH;mWa53D@W z67D|ezjXoMKqW)93dUwtOb$K2VQ!dLdH|~HP(s%qIT?*+nBLg#w)Tx*2^+}{Z`f6^ zVjEwZMB_zX8g+l~obKC&1YWHzY(YQF4!YAjU>t@!XhY3C?4I-*K-nPAE80_J0-4RLxjEY%4=>JT6eJSCFKLOBHhT+ zW|(oSwK(^=Ha%45%P4lAxl*?2fT~yQo-t~0GyF~3u%(iOlsX!5-Rb!F02*y%yAUC< zdA{V8oft1;wyIz4%T*_M0=?O1pW8SI<_(X$z?Nm&oD$0$hdlG=e?EKFiABmCCh*;J zuG2Rs1IaM{8hq=u7n+UI5q^f9IzVrt;jxp1YIlS3&VJHzVB z#|#ejCck}FRc*}u7&e~xN0GtK*M}UcgX`Zp@U#%l_zATjF1BEut1T}n(RqHUW6d;f zb7w_evR!Wy8uH=4A!rd>)Gdl_K|ZH+t;%l#;uJ8!mVc#imqq3{;Zp6|`6lCj#(P)` zR*$IUL!?t}+c928qQYz7qFZONmk%wMWzxsl8{$l;hm~G1O9MrwwxjEPCW=Fj1Y9N# zUA_u6DbXShdYoH#`z1PnR~RNWl9pkX6pm5Z$oYPg{_H&%uj_a2iTDG(ZoB$BosOwK zor7P+j4O}Cbw8@m0e<5oYd?R#()kDNv$YQTG$94-YfeKBVuO;8Ard6zUEeJ6gw`T? z3IOd6A1SsEc>Z(E`(-kmw?knUAAP7|;uJbPHu@4yPg}yQo*~bpoL+ry2iOWDxwHKC`iJ5l}Y46hGaj;nuQaGIEgVZ^t9elAQkLIPT|KjEq*&nnr#5fKD0WA?dwyE z)?3{y>f2nl$;}8MJ)96tYMn^)-!>$a)WW@QhW7JdJ`VPg5F}j;gRjSg6dv+83Du}E zPYt9X^w zSqt9p0*qayqeP|C7S<+#wEwMK7a_%y+hqgmjldW#-oXU6nJ0G`o!o$G_`9;5qb ziU6FGbNU}?fX)6(DaGsyKD*hg*#^GnFAxc^jACO?v(GxJ<=cF2t1noKPS+-nDt$k` z;=g#ojKcpb8Oe)(V*-1DnjT3p{ej&*KGLJ(>qG^wrM$7fB-| zP}WaAIUJA(j6RJMT*PCL*0Fx4iN9j{o1sm?%OlJc-JV#6KNEn>-6tOHU@`T}EB`L$ z9B-4)3^Uz#oU8ZS?+reE-Ej*2__ang>3xCYH$rpY73Z2IP*>?yC;}va^(wh|QPJS& zx9FiPxE;9POYWrB3MIL<6ZF(Ojl|tfX3ezq3?;Pf9;qiFLT~vWZ?N2$iLCr1MD6DV zMih$Rq%tJM8mJqaKo>2!1A05FcXCK^pCJrd-B@sL?|h21NlOO=LVd+kLKqL6NYb5A-L{Ttw-dr^FYWxTOA8DWf}7F*QxHeY@p zhJ#2+^tD$ZMiT_bMB2HTQ@(Kj6-paybOR-3e3@k_B?vjB?3;|d??H|96)=eJJ`_kYDO|7c>QMEzk1#L_E6B)s1?id1sgHD1_F6vtr){ZLry z^!5ET(Fstx5yPYQ76F^{AT2ueL%_z!@Ly@m{}a{7h+|(fK>0yU9YE4>vcV}}ETZcm zGHI|fRH;+j-_fQYsA5=e^TDuI5HdG?`L7n>|EidFg2nUBcI_AUUQ>D2ObU1aygj>+ zbij3b4vTEeanMSt0V}}#Wb^y~PxkbWgyF@0x+JVCoS3yBdMHK2d0j5UutOn*o!em% ztb1M$FythKbk6uihBe{gCWAidH0Kf8oM|085LjBY~)kwX) z+#mzx>z5Am@K^BXqp!Pw#?KpbD(*+OVloyx=L-M@8|eJ!p%3yR$(IlDx_ajSD+c+$ax%JDFlZuHh3dl7{C^%W@LAJO^Z&Gc zCjH+5kEa3f{`v5K=Tm_X{VhX;fPk?5PFg|(n8NhfPS}6{2#yB~c>LW<`tPLm=yO8= zNc9ile+SlSfdP2cG%M@>CxiQE7R|E2BGi*AVrKcz0B{?yuh)$$wKV^C<%67~{9eGD zLzGoC{xc9C3JeVO8dR43&mzc0Uw?tfyY7OWm0kRw0R~+EN91<1HmBN^;!$AE2=8Q+ Kr7I+j0{#zPf(Z=( diff --git a/2.0/documentation/webdocs/assets/image-20190707124650780.png b/2.0/documentation/webdocs/assets/image-20190707124650780.png deleted file mode 100644 index 9ebcac863e862d8b240c86dec29be1ebe7aa50f0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 21589 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 P00000NkvXXu0mjfnnG#* diff --git a/2.0/documentation/webdocs/assets/import_dashboard1.jpg b/2.0/documentation/webdocs/assets/import_dashboard1.jpg deleted file mode 100644 index 9d2ce7ed65eb0c2c729de50283b30491793493dc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 45736 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 NFA?teA1j^l{{_Lz5C{MO diff --git a/2.0/documentation/webdocs/assets/import_dashboard2.jpg b/2.0/documentation/webdocs/assets/import_dashboard2.jpg deleted file mode 100644 index 94b09f0ee39552bb84f7ba1f65815ce2c9548b2d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 165404 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

      VbAbZN0BdPy4eB4C`8_@L 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%0DQvr-Oz$gWbw@i8H=HUT&uM>KeA@e}X{Q?3y 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 Uyzbr(=psaZZ>}urj{H6U9|fd*GXMYp diff --git a/2.0/documentation/webdocs/assets/nodes.png b/2.0/documentation/webdocs/assets/nodes.png deleted file mode 100644 index d4ae5120c29b8cfacdc543df5a2a7104d77a2a7b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 67429 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 diff --git a/2.0/documentation/webdocs/assets/structure.png b/2.0/documentation/webdocs/assets/structure.png deleted file mode 100644 index 801829b68580e1a46d0841a3d38e4885eb383991..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 25593 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≪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 JOZ@ld{{VfYx&Z(H diff --git a/2.0/documentation/webdocs/markdowndocs/Connections with other Tools-ch.md b/2.0/documentation/webdocs/markdowndocs/Connections with other Tools-ch.md deleted file mode 100644 index f7da0c654d..0000000000 --- a/2.0/documentation/webdocs/markdowndocs/Connections with other Tools-ch.md +++ /dev/null @@ -1,175 +0,0 @@ -# 与其他工具的连接 - -## Telegraf - -TDengine能够与开源数据采集系统[Telegraf](https://www.influxdata.com/time-series-platform/telegraf/)快速集成,整个过程无需任何代码开发。 - -### 安装Telegraf - -目前TDengine支持Telegraf 1.7.4以上的版本。用户可以根据当前的操作系统,到Telegraf官网下载安装包,并执行安装。下载地址如下:https://portal.influxdata.com/downloads - -### 配置Telegraf - -修改Telegraf配置文件/etc/telegraf/telegraf.conf中与TDengine有关的配置项。 - -在output plugins部分,增加[[outputs.http]]配置项: - -- url:http://ip:6020/telegraf/udb,其中ip为TDengine集群的中任意一台服务器的IP地址,6020为TDengine RESTful接口的端口号,telegraf为固定关键字,udb为用于存储采集数据的数据库名称,可预先创建。 -- method: "POST" -- username: 登录TDengine的用户名 -- password: 登录TDengine的密码 -- data_format: "json" -- json_timestamp_units: "1ms" - -在agent部分: - -- hostname: 区分不同采集设备的机器名称,需确保其唯一性 -- metric_batch_size: 30,允许Telegraf每批次写入记录最大数量,增大其数量可以降低Telegraf的请求发送频率,但对于TDengine,该数值不能超过50 - -关于如何使用Telegraf采集数据以及更多有关使用Telegraf的信息,请参考Telegraf官方的[文档](https://docs.influxdata.com/telegraf/v1.11/)。 - -## Grafana - -TDengine能够与开源数据可视化系统[Grafana](https://www.grafana.com/)快速集成搭建数据监测报警系统,整个过程无需任何代码开发,TDengine中数据表中内容可以在仪表盘(DashBoard)上进行可视化展现。 - -### 安装Grafana - -目前TDengine支持Grafana 5.2.4以上的版本。用户可以根据当前的操作系统,到Grafana官网下载安装包,并执行安装。下载地址如下:https://grafana.com/grafana/download。 - -### 配置Grafana - -TDengine的Grafana插件在安装包的/usr/local/taos/connector/grafana目录下。 - -以CentOS 7.2操作系统为例,将tdengine目录拷贝到/var/lib/grafana/plugins目录下,重新启动grafana即可。 - -### 使用 Grafana - -#### 配置数据源 - -用户可以直接通过 localhost:3000 的网址,登录 Grafana 服务器(用户名/密码:admin/admin),通过左侧 `Configuration -> Data Sources` 可以添加数据源,如下图所示: - -![img](../assets/add_datasource1.jpg) - -点击 `Add data source` 可进入新增数据源页面,在查询框中输入 TDengine 可选择添加,如下图所示: - -![img](../assets/add_datasource2.jpg) - -进入数据源配置页面,按照默认提示修改相应配置即可: - -![img](../assets/add_datasource3.jpg) - -* Host: TDengine 集群的中任意一台服务器的 IP 地址与 TDengine RESTful 接口的端口号(6020),默认 http://localhost:6020。 -* User:TDengine 用户名。 -* Password:TDengine 用户密码。 - -点击 `Save & Test` 进行测试,成功会有如下提示: - -![img](../assets/add_datasource4.jpg) - -#### 创建 Dashboard - -回到主界面创建 Dashboard,点击 Add Query 进入面板查询页面: - -![img](../assets/create_dashboard1.jpg) - -如上图所示,在 Query 中选中 `TDengine` 数据源,在下方查询框可输入相应 sql 进行查询,具体说明如下: - -* INPUT SQL:输入要查询的语句(该 SQL 语句的结果集应为两列多行),例如:`select avg(mem_system) from log.dn where ts >= $from and ts < $to interval($interval)` ,其中,from、to 和 interval 为 TDengine插件的内置变量,表示从Grafana插件面板获取的查询范围和时间间隔。除了内置变量外,`也支持可以使用自定义模板变量`。 -* ALIAS BY:可设置当前查询别名。 -* GENERATE SQL: 点击该按钮会自动替换相应变量,并生成最终执行的语句。 - -按照默认提示查询当前 TDengine 部署所在服务器指定间隔系统内存平均使用量如下: - -![img](../assets/create_dashboard2.jpg) - -> 关于如何使用Grafana创建相应的监测界面以及更多有关使用Grafana的信息,请参考Grafana官方的[文档](https://grafana.com/docs/)。 - -#### 导入 Dashboard - -在 Grafana 插件目录 /usr/local/taos/connector/grafana/tdengine/dashboard/ 下提供了一个 `tdengine-grafana.json` 可导入的 dashboard。 - -点击左侧 `Import` 按钮,并上传 `tdengine-grafana.json` 文件: - -![img](../assets/import_dashboard1.jpg) - -导入完成之后可看到如下效果: - -![img](../assets/import_dashboard2.jpg) - - -## Matlab - -MatLab可以通过安装包内提供的JDBC Driver直接连接到TDengine获取数据到本地工作空间。 - -### MatLab的JDBC接口适配 - -MatLab的适配有下面几个步骤,下面以Windows10上适配MatLab2017a为例: - -- 将TDengine安装包内的驱动程序JDBCDriver-1.0.0-dist.jar拷贝到${matlab_root}\MATLAB\R2017a\java\jar\toolbox -- 将TDengine安装包内的taos.lib文件拷贝至${matlab_ root _dir}\MATLAB\R2017a\lib\win64 -- 将新添加的驱动jar包加入MatLab的classpath。在${matlab_ root _dir}\MATLAB\R2017a\toolbox\local\classpath.txt文件中添加下面一行 - -​ `$matlabroot/java/jar/toolbox/JDBCDriver-1.0.0-dist.jar` - -- 在${user_home}\AppData\Roaming\MathWorks\MATLAB\R2017a\下添加一个文件javalibrarypath.txt, 并在该文件中添加taos.dll的路径,比如您的taos.dll是在安装时拷贝到了C:\Windows\System32下,那么就应该在javalibrarypath.txt中添加如下一行: - -​ `C:\Windows\System32` - -### 在MatLab中连接TDengine获取数据 - -在成功进行了上述配置后,打开MatLab。 - -- 创建一个连接: - - `conn = database(‘db’, ‘root’, ‘taosdata’, ‘com.taosdata.jdbc.TSDBDriver’, ‘jdbc:TSDB://127.0.0.1:0/’)` - -- 执行一次查询: - - `sql0 = [‘select * from tb’]` - - `data = select(conn, sql0);` - -- 插入一条记录: - - `sql1 = [‘insert into tb values (now, 1)’]` - - `exec(conn, sql1)` - -更多例子细节请参考安装包内examples\Matlab\TDengineDemo.m文件。 - -## R - -R语言支持通过JDBC接口来连接TDengine数据库。首先需要安装R语言的JDBC包。启动R语言环境,然后执行以下命令安装R语言的JDBC支持库: - -```R -install.packages('rJDBC', repos='http://cran.us.r-project.org') -``` - -安装完成以后,通过执行`library('RJDBC')`命令加载 _RJDBC_ 包: - -然后加载TDengine的JDBC驱动: - -```R -drv<-JDBC("com.taosdata.jdbc.TSDBDriver","JDBCDriver-1.0.0-dist.jar", identifier.quote="\"") -``` -如果执行成功,不会出现任何错误信息。之后通过以下命令尝试连接数据库: - -```R -conn<-dbConnect(drv,"jdbc:TSDB://192.168.0.1:0/?user=root&password=taosdata","root","taosdata") -``` - -注意将上述命令中的IP地址替换成正确的IP地址。如果没有任务错误的信息,则连接数据库成功,否则需要根据错误提示调整连接的命令。TDengine支持以下的 _RJDBC_ 包中函数: - - -- dbWriteTable(conn, "test", iris, overwrite=FALSE, append=TRUE):将数据框iris写入表test中,overwrite必须设置为false,append必须设为TRUE,且数据框iris要与表test的结构一致。 -- dbGetQuery(conn, "select count(*) from test"):查询语句 -- dbSendUpdate(conn, "use db"):执行任何非查询sql语句。例如dbSendUpdate(conn, "use db"), 写入数据dbSendUpdate(conn, "insert into t1 values(now, 99)")等。 -- dbReadTable(conn, "test"):读取表test中数据 -- dbDisconnect(conn):关闭连接 -- dbRemoveTable(conn, "test"):删除表test - -TDengine客户端暂不支持如下函数: -- dbExistsTable(conn, "test"):是否存在表test -- dbListTables(conn):显示连接中的所有表 - - diff --git a/2.0/documentation/webdocs/markdowndocs/Connections with other Tools.md b/2.0/documentation/webdocs/markdowndocs/Connections with other Tools.md deleted file mode 100644 index 8be0569849..0000000000 --- a/2.0/documentation/webdocs/markdowndocs/Connections with other Tools.md +++ /dev/null @@ -1,167 +0,0 @@ -# Connect with other tools - -## Telegraf - -TDengine is easy to integrate with [Telegraf](https://www.influxdata.com/time-series-platform/telegraf/), an open-source server agent for collecting and sending metrics and events, without more development. - -### Install Telegraf - -At present, TDengine supports Telegraf newer than version 1.7.4. Users can go to the [download link] and choose the proper package to install on your system. - -### Configure Telegraf - -Telegraf is configured by changing items in the configuration file */etc/telegraf/telegraf.conf*. - - -In **output plugins** section,add _[[outputs.http]]_ iterm: - -- _url_: http://ip:6020/telegraf/udb, in which _ip_ is the IP address of any node in TDengine cluster. Port 6020 is the RESTful APT port used by TDengine. _udb_ is the name of the database to save data, which needs to create beforehand. -- _method_: "POST" -- _username_: username to login TDengine -- _password_: password to login TDengine -- _data_format_: "json" -- _json_timestamp_units_: "1ms" - -In **agent** part: - -- hostname: used to distinguish different machines. Need to be unique. -- metric_batch_size: 30,the maximum number of records allowed to write in Telegraf. The larger the value is, the less frequent requests are sent. For TDengine, the value should be less than 50. - -Please refer to the [Telegraf docs](https://docs.influxdata.com/telegraf/v1.11/) for more information. - -## Grafana - -[Grafana] is an open-source system for time-series data display. It is easy to integrate TDengine and Grafana to build a monitor system. Data saved in TDengine can be fetched and shown on the Grafana dashboard. - -### Install Grafana - -For now, TDengine only supports Grafana newer than version 5.2.4. Users can go to the [Grafana download page] for the proper package to download. - -### Configure Grafana - -TDengine Grafana plugin is in the _/usr/local/taos/connector/grafana_ directory. -Taking Centos 7.2 as an example, just copy TDengine directory to _/var/lib/grafana/plugins_ directory and restart Grafana. - -### Use Grafana - -Users can log in the Grafana server (username/password:admin/admin) through localhost:3000 to configure TDengine as the data source. As is shown in the picture below, TDengine as a data source option is shown in the box: - - -![img](../assets/clip_image001.png) - -When choosing TDengine as the data source, the Host in HTTP configuration should be configured as the IP address of any node of a TDengine cluster. The port should be set as 6020. For example, when TDengine and Grafana are on the same machine, it should be configured as _http://localhost:6020. - - -Besides, users also should set the username and password used to log into TDengine. Then click _Save&Test_ button to save. - -![img](../assets/clip_image001-2474914.png) - -Then, TDengine as a data source should show in the Grafana data source list. - -![img](../assets/clip_image001-2474939.png) - - -Then, users can create Dashboards in Grafana using TDengine as the data source: - - -![img](../assets/clip_image001-2474961.png) - - - -Click _Add Query_ button to add a query and input the SQL command you want to run in the _INPUT SQL_ text box. The SQL command should expect a two-row, multi-column result, such as _SELECT count(*) FROM sys.cpu WHERE ts>=from and ts<​to interval(interval)_, in which, _from_, _to_ and _inteval_ are TDengine inner variables representing query time range and time interval. - - -_ALIAS BY_ field is to set the query alias. Click _GENERATE SQL_ to send the command to TDengine: - -![img](../assets/clip_image001-2474987.png) - -Please refer to the [Grafana official document] for more information about Grafana. - - -## Matlab - -Matlab can connect to and retrieve data from TDengine by TDengine JDBC Driver. - -### MatLab and TDengine JDBC adaptation - -Several steps are required to adapt Matlab to TDengine. Taking adapting Matlab2017a on Windows10 as an example: - -1. Copy the file _JDBCDriver-1.0.0-dist.jar_ in TDengine package to the directory _${matlab_root}\MATLAB\R2017a\java\jar\toolbox_ -2. Copy the file _taos.lib_ in TDengine package to _${matlab_ root _dir}\MATLAB\R2017a\lib\win64_ -3. Add the .jar package just copied to the Matlab classpath. Append the line below as the end of the file of _${matlab_ root _dir}\MATLAB\R2017a\toolbox\local\classpath.txt_ - -​ `$matlabroot/java/jar/toolbox/JDBCDriver-1.0.0-dist.jar` - -4. Create a file called _javalibrarypath.txt_ in directory _${user_home}\AppData\Roaming\MathWorks\MATLAB\R2017a\_, and add the _taos.dll_ path in the file. For example, if the file _taos.dll_ is in the directory of _C:\Windows\System32_,then add the following line in file *javalibrarypath.txt*: - -​ `C:\Windows\System32` - -### TDengine operations in Matlab - -After correct configuration, open Matlab: - -- build a connection: - - `conn = database(‘db’, ‘root’, ‘taosdata’, ‘com.taosdata.jdbc.TSDBDriver’, ‘jdbc:TSDB://127.0.0.1:0/’)` - -- Query: - - `sql0 = [‘select * from tb’]` - - `data = select(conn, sql0);` - -- Insert a record: - - `sql1 = [‘insert into tb values (now, 1)’]` - - `exec(conn, sql1)` - -Please refer to the file _examples\Matlab\TDengineDemo.m_ for more information. - -## R - -Users can use R language to access the TDengine server with the JDBC interface. At first, install JDBC package in R: - -```R -install.packages('rJDBC', repos='http://cran.us.r-project.org') -``` - -Then use _library_ function to load the package: - -```R -library('RJDBC') -``` - -Then load the TDengine JDBC driver: - -```R -drv<-JDBC("com.taosdata.jdbc.TSDBDriver","JDBCDriver-1.0.0-dist.jar", identifier.quote="\"") -``` -If succeed, no error message will display. Then use the following command to try a database connection: - -```R -conn<-dbConnect(drv,"jdbc:TSDB://192.168.0.1:0/?user=root&password=taosdata","root","taosdata") -``` - -Please replace the IP address in the command above to the correct one. If no error message is shown, then the connection is established successfully. TDengine supports below functions in _RJDBC_ package: - - -- _dbWriteTable(conn, "test", iris, overwrite=FALSE, append=TRUE)_: write the data in a data frame _iris_ to the table _test_ in the TDengine server. Parameter _overwrite_ must be _false_. _append_ must be _TRUE_ and the schema of the data frame _iris_ should be the same as the table _test_. -- _dbGetQuery(conn, "select count(*) from test")_: run a query command -- _dbSendUpdate(conn, "use db")_: run any non-query command. -- _dbReadTable(conn, "test"_): read all the data in table _test_ -- _dbDisconnect(conn)_: close a connection -- _dbRemoveTable(conn, "test")_: remove table _test_ - -Below functions are **not supported** currently: -- _dbExistsTable(conn, "test")_: if talbe _test_ exists -- _dbListTables(conn)_: list all tables in the connection - - -[Telegraf]: www.taosdata.com -[download link]: https://portal.influxdata.com/downloads -[Telegraf document]: www.taosdata.com -[Grafana]: https://grafana.com -[Grafana download page]: https://grafana.com/grafana/download -[Grafana official document]: https://grafana.com/docs/ - diff --git a/2.0/documentation/webdocs/markdowndocs/Connector.md b/2.0/documentation/webdocs/markdowndocs/Connector.md deleted file mode 100644 index fcd6976cb0..0000000000 --- a/2.0/documentation/webdocs/markdowndocs/Connector.md +++ /dev/null @@ -1,918 +0,0 @@ -# TDengine connectors - -TDengine provides many connectors for development, including C/C++, JAVA, Python, RESTful, Go, Node.JS, etc. - -NOTE: All APIs which require a SQL string as parameter, including but not limit to `taos_query`, `taos_query_a`, `taos_subscribe` in the C/C++ Connector and their counterparts in other connectors, can ONLY process one SQL statement at a time. If more than one SQL statements are provided, their behaviors are undefined. - -## C/C++ API - -C/C++ APIs are similar to the MySQL APIs. Applications should include TDengine head file _taos.h_ to use C/C++ APIs by adding the following line in code: -```C -#include -``` -Make sure TDengine library _libtaos.so_ is installed and use _-ltaos_ option to link the library when compiling. In most cases, if the return value of an API is integer, it return _0_ for success and other values as an error code for failure; if the return value is pointer, then _NULL_ is used for failure. - - -### C/C++ sync API - -Sync APIs are those APIs waiting for responses from the server after sending a request. TDengine has the following sync APIs: - - -- `TAOS *taos_connect(char *ip, char *user, char *pass, char *db, int port)` - - Open a connection to a TDengine server. The parameters are _ip_ (IP address of the server), _user_ (username to login), _pass_ (password to login), _db_ (database to use after connection) and _port_ (port number to connect). The parameter _db_ can be NULL for no database to use after connection. Otherwise, the database should exist before connection or a connection error is reported. The handle returned by this API should be kept for future use. - -- `void taos_close(TAOS *taos)` - - Close a connection to a TDengine server by the handle returned by _taos_connect_` - - -- `int taos_query(TAOS *taos, char *sqlstr)` - - The API used to run a SQL command. The command can be DQL or DML. The parameter _taos_ is the handle returned by _taos_connect_. Return value _-1_ means failure. - - -- `TAOS_RES *taos_use_result(TAOS *taos)` - - Use the result after running _taos_query_. The handle returned should be kept for future fetch. - - -- `TAOS_ROW taos_fetch_row(TAOS_RES *res)` - - Fetch a row of return results through _res_, the handle returned by _taos_use_result_. - - -- `int taos_num_fields(TAOS_RES *res)` - - Get the number of fields in the return result. - - -- `TAOS_FIELD *taos_fetch_fields(TAOS_RES *res)` - - Fetch the description of each field. The description includes the property of data type, field name, and bytes. The API should be used with _taos_num_fields_ to fetch a row of data. - - -- `void taos_free_result(TAOS_RES *res)` - - Free the resources used by a result set. Make sure to call this API after fetching results or memory leak would happen. - - -- `void taos_init()` - - Initialize the environment variable used by TDengine client. The API is not necessary since it is called int _taos_connect_ by default. - - -- `char *taos_errstr(TAOS *taos)` - - Return the reason of the last API call failure. The return value is a string. - - -- `int *taos_errno(TAOS *taos)` - - Return the error code of the last API call failure. The return value is an integer. - - -- `int taos_options(TSDB_OPTION option, const void * arg, ...)` - - Set client options. The parameter _option_ supports values of _TSDB_OPTION_CONFIGDIR_ (configuration directory), _TSDB_OPTION_SHELL_ACTIVITY_TIMER_, _TSDB_OPTION_LOCALE_ (client locale) and _TSDB_OPTION_TIMEZONE_ (client timezone). - -The 12 APIs are the most important APIs frequently used. Users can check _taos.h_ file for more API information. - -**Note**: The connection to a TDengine server is not multi-thread safe. So a connection can only be used by one thread. - -### C/C++ parameter binding API - -TDengine also provides parameter binding APIs, like MySQL, only question mark `?` can be used to represent a parameter in these APIs. - -- `TAOS_STMT* taos_stmt_init(TAOS *taos)` - - Create a TAOS_STMT to represent the prepared statement for other APIs. - -- `int taos_stmt_prepare(TAOS_STMT *stmt, const char *sql, unsigned long length)` - - Parse SQL statement _sql_ and bind result to _stmt_ , if _length_ larger than 0, its value is used to determine the length of _sql_, the API auto detects the actual length of _sql_ otherwise. - -- `int taos_stmt_bind_param(TAOS_STMT *stmt, TAOS_BIND *bind)` - - Bind values to parameters. _bind_ points to an array, the element count and sequence of the array must be identical as the parameters of the SQL statement. The usage of _TAOS_BIND_ is same as _MYSQL_BIND_ in MySQL, its definition is as below: - - ```c - typedef struct TAOS_BIND { - int buffer_type; - void * buffer; - unsigned long buffer_length; // not used in TDengine - unsigned long *length; - int * is_null; - int is_unsigned; // not used in TDengine - int * error; // not used in TDengine - } TAOS_BIND; - ``` - -- `int taos_stmt_add_batch(TAOS_STMT *stmt)` - - Add bound parameters to batch, client can call `taos_stmt_bind_param` again after calling this API. Note this API only support _insert_ / _import_ statements, it returns an error in other cases. - -- `int taos_stmt_execute(TAOS_STMT *stmt)` - - Execute the prepared statement. This API can only be called once for a statement at present. - -- `TAOS_RES* taos_stmt_use_result(TAOS_STMT *stmt)` - - Acquire the result set of an executed statement. The usage of the result is same as `taos_use_result`, `taos_free_result` must be called after one you are done with the result set to release resources. - -- `int taos_stmt_close(TAOS_STMT *stmt)` - - Close the statement, release all resources. - - -### C/C++ async API - -In addition to sync APIs, TDengine also provides async APIs, which are more efficient. Async APIs are returned right away without waiting for a response from the server, allowing the application to continute with other tasks without blocking. So async APIs are more efficient, especially useful when in a poor network. - -All async APIs require callback functions. The callback functions have the format: -```C -void fp(void *param, TAOS_RES * res, TYPE param3) -``` -The first two parameters of the callback function are the same for all async APIs. The third parameter is different for different APIs. Generally, the first parameter is the handle provided to the API for action. The second parameter is a result handle. - -- `void taos_query_a(TAOS *taos, char *sqlstr, void (*fp)(void *param, TAOS_RES *, int code), void *param);` - - The async query interface. _taos_ is the handle returned by _taos_connect_ interface. _sqlstr_ is the SQL command to run. _fp_ is the callback function. _param_ is the parameter required by the callback function. The third parameter of the callback function _code_ is _0_ (for success) or a negative number (for failure, call taos_errstr to get the error as a string). Applications mainly handle with the second parameter, the returned result set. - - -- `void taos_fetch_rows_a(TAOS_RES *res, void (*fp)(void *param, TAOS_RES *, int numOfRows), void *param);` - - The async API to fetch a batch of rows, which should only be used with a _taos_query_a_ call. The parameter _res_ is the result handle returned by _taos_query_a_. _fp_ is the callback function. _param_ is a user-defined structure to pass to _fp_. The parameter _numOfRows_ is the number of result rows in the current fetch cycle. In the callback function, applications should call _taos_fetch_row_ to get records from the result handle. After getting a batch of results, applications should continue to call _taos_fetch_rows_a_ API to handle the next batch, until the _numOfRows_ is _0_ (for no more data to fetch) or _-1_ (for failure). - - -- `void taos_fetch_row_a(TAOS_RES *res, void (*fp)(void *param, TAOS_RES *, TAOS_ROW row), void *param);` - - The async API to fetch a result row. _res_ is the result handle. _fp_ is the callback function. _param_ is a user-defined structure to pass to _fp_. The third parameter of the callback function is a single result row, which is different from that of _taos_fetch_rows_a_ API. With this API, it is not necessary to call _taos_fetch_row_ to retrieve each result row, which is handier than _taos_fetch_rows_a_ but less efficient. - - -Applications may apply operations on multiple tables. However, **it is important to make sure the operations on the same table are serialized**. That means after sending an insert request in a table to the server, no operations on the table are allowed before a response is received. - -### C/C++ continuous query interface - -TDengine provides APIs for continuous query driven by time, which run queries periodically in the background. There are only two APIs: - - -- `TAOS_STREAM *taos_open_stream(TAOS *taos, char *sqlstr, void (*fp)(void *param, TAOS_RES *, TAOS_ROW row), int64_t stime, void *param, void (*callback)(void *));` - - The API is used to create a continuous query. - * _taos_: the connection handle returned by _taos_connect_. - * _sqlstr_: the SQL string to run. Only query commands are allowed. - * _fp_: the callback function to run after a query - * _param_: a parameter passed to _fp_ - * _stime_: the time of the stream starts in the form of epoch milliseconds. If _0_ is given, the start time is set as the current time. - * _callback_: a callback function to run when the continuous query stops automatically. - - The API is expected to return a handle for success. Otherwise, a NULL pointer is returned. - - -- `void taos_close_stream (TAOS_STREAM *tstr)` - - Close the continuous query by the handle returned by _taos_open_stream_. Make sure to call this API when the continuous query is not needed anymore. - - -### C/C++ subscription API - -For the time being, TDengine supports subscription on one or multiple tables. It is implemented through periodic pulling from a TDengine server. - -* `TAOS_SUB *taos_subscribe(TAOS* taos, int restart, const char* topic, const char *sql, TAOS_SUBSCRIBE_CALLBACK fp, void *param, int interval)` - - The API is used to start a subscription session, it returns the subscription object on success and `NULL` in case of failure, the parameters are: - * **taos**: The database connnection, which must be established already. - * **restart**: `Zero` to continue a subscription if it already exits, other value to start from the beginning. - * **topic**: The unique identifier of a subscription. - * **sql**: A sql statement for data query, it can only be a `select` statement, can only query for raw data, and can only query data in ascending order of the timestamp field. - * **fp**: A callback function to receive query result, only used in asynchronization mode and should be `NULL` in synchronization mode, please refer below for its prototype. - * **param**: User provided additional parameter for the callback function. - * **interval**: Pulling interval in millisecond. Under asynchronization mode, API will call the callback function `fp` in this interval, system performance will be impacted if this interval is too short. Under synchronization mode, if the duration between two call to `taos_consume` is less than this interval, the second call blocks until the duration exceed this interval. - -* `typedef void (*TAOS_SUBSCRIBE_CALLBACK)(TAOS_SUB* tsub, TAOS_RES *res, void* param, int code)` - - Prototype of the callback function, the parameters are: - * tsub: The subscription object. - * res: The query result. - * param: User provided additional parameter when calling `taos_subscribe`. - * code: Error code in case of failures. - -* `TAOS_RES *taos_consume(TAOS_SUB *tsub)` - - The API used to get the new data from a TDengine server. It should be put in an loop. The parameter `tsub` is the handle returned by `taos_subscribe`. This API should only be called in synchronization mode. If the duration between two call to `taos_consume` is less than pulling interval, the second call blocks until the duration exceed the interval. The API returns the new rows if new data arrives, or empty rowset otherwise, and if there's an error, it returns `NULL`. - -* `void taos_unsubscribe(TAOS_SUB *tsub, int keepProgress)` - - Stop a subscription session by the handle returned by `taos_subscribe`. If `keepProgress` is **not** zero, the subscription progress information is kept and can be reused in later call to `taos_subscribe`, the information is removed otherwise. - -## Java Connector - -To Java delevopers, TDengine provides `taos-jdbcdriver` according to the JDBC(3.0) API. Users can find and download it through [Sonatype Repository][1]. - -Since the native language of TDengine is C, the necessary TDengine library should be checked before using the taos-jdbcdriver: - -* libtaos.so (Linux) - After TDengine is installed successfully, the library `libtaos.so` will be automatically copied to the `/usr/lib/`, which is the system's default search path. - -* taos.dll (Windows) - After TDengine client is installed, the library `taos.dll` will be automatically copied to the `C:/Windows/System32`, which is the system's default search path. - -> Note: Please make sure that [TDengine Windows client][14] has been installed if developing on Windows. Now although TDengine client would be defaultly installed together with TDengine server, it can also be installed [alone][15]. - -Since TDengine is time-series database, there are still some differences compared with traditional databases in using TDengine JDBC driver: -* TDengine doesn't allow to delete/modify a single record, and thus JDBC driver also has no such method. -* No support for transaction -* No support for union between tables -* No support for nested query,`There is at most one open ResultSet for each Connection. Thus, TSDB JDBC Driver will close current ResultSet if it is not closed and a new query begins`. - -## Version list of TAOS-JDBCDriver and required TDengine and JDK - -| taos-jdbcdriver | TDengine | JDK | -| --- | --- | --- | -| 1.0.3 | 1.6.1.x or higher | 1.8.x | -| 1.0.2 | 1.6.1.x or higher | 1.8.x | -| 1.0.1 | 1.6.1.x or higher | 1.8.x | - -## DataType in TDengine and Java - -The datatypes in TDengine include timestamp, number, string and boolean, which are converted as follows in Java: - -| TDengine | Java | -| --- | --- | -| TIMESTAMP | java.sql.Timestamp | -| INT | java.lang.Integer | -| BIGINT | java.lang.Long | -| FLOAT | java.lang.Float | -| DOUBLE | java.lang.Double | -| SMALLINT, TINYINT |java.lang.Short | -| BOOL | java.lang.Boolean | -| BINARY, NCHAR | java.lang.String | - -## How to get TAOS-JDBC Driver - -### maven repository - -taos-jdbcdriver has been published to [Sonatype Repository][1]: -* [sonatype][8] -* [mvnrepository][9] -* [maven.aliyun][10] - -Using the following pom.xml for maven projects - -```xml - - - com.taosdata.jdbc - taos-jdbcdriver - 1.0.3 - - -``` - -### JAR file from the source code - -After downloading the [TDengine][3] source code, execute `mvn clean package` in the directory `src/connector/jdbc` and then the corresponding jar file is generated. - -## Usage - -### get the connection - -```java -Class.forName("com.taosdata.jdbc.TSDBDriver"); -String jdbcUrl = "jdbc:TAOS://127.0.0.1:6030/log?user=root&password=taosdata"; -Connection conn = DriverManager.getConnection(jdbcUrl); -``` -> `6030` is the default port and `log` is the default database for system monitor. - -A normal JDBC URL looks as follows: -`jdbc:TAOS://{host_ip}:{port}/[database_name]?[user={user}|&password={password}|&charset={charset}|&cfgdir={config_dir}|&locale={locale}|&timezone={timezone}]` - -values in `{}` are necessary while values in `[]` are optional。Each option in the above URL denotes: - -* user:user name for login, defaultly root。 -* password:password for login,defaultly taosdata。 -* charset:charset for client,defaultly system charset -* cfgdir:log directory for client, defaultly _/etc/taos/_ on Linux and _C:/TDengine/cfg_ on Windows。 -* locale:language for client,defaultly system locale。 -* timezone:timezone for client,defaultly system timezone。 - -The options above can be configures (`ordered by priority`): -1. JDBC URL - - As explained above. -2. java.sql.DriverManager.getConnection(String jdbcUrl, Properties connProps) -```java -public Connection getConn() throws Exception{ - Class.forName("com.taosdata.jdbc.TSDBDriver"); - String jdbcUrl = "jdbc:TAOS://127.0.0.1:0/log?user=root&password=taosdata"; - Properties connProps = new Properties(); - connProps.setProperty(TSDBDriver.PROPERTY_KEY_USER, "root"); - connProps.setProperty(TSDBDriver.PROPERTY_KEY_PASSWORD, "taosdata"); - connProps.setProperty(TSDBDriver.PROPERTY_KEY_CONFIG_DIR, "/etc/taos"); - connProps.setProperty(TSDBDriver.PROPERTY_KEY_CHARSET, "UTF-8"); - connProps.setProperty(TSDBDriver.PROPERTY_KEY_LOCALE, "en_US.UTF-8"); - connProps.setProperty(TSDBDriver.PROPERTY_KEY_TIME_ZONE, "UTC-8"); - Connection conn = DriverManager.getConnection(jdbcUrl, connProps); - return conn; -} -``` - -3. Configuration file (taos.cfg) - - Default configuration file is _/var/lib/taos/taos.cfg_ On Linux and _C:\TDengine\cfg\taos.cfg_ on Windows -```properties -# client default username -# defaultUser root - -# client default password -# defaultPass taosdata - -# default system charset -# charset UTF-8 - -# system locale -# locale en_US.UTF-8 -``` -> More options can refer to [client configuration][13] - -### Create databases and tables - -```java -Statement stmt = conn.createStatement(); - -// create database -stmt.executeUpdate("create database if not exists db"); - -// use database -stmt.executeUpdate("use db"); - -// create table -stmt.executeUpdate("create table if not exists tb (ts timestamp, temperature int, humidity float)"); -``` -> Note: if no step like `use db`, the name of database must be added as prefix like _db.tb_ when operating on tables - -### Insert data - -```java -// insert data -int affectedRows = stmt.executeUpdate("insert into tb values(now, 23, 10.3) (now + 1s, 20, 9.3)"); - -System.out.println("insert " + affectedRows + " rows."); -``` -> _now_ is the server time. -> _now+1s_ is 1 second later than current server time. The time unit includes: _a_(millisecond), _s_(second), _m_(minute), _h_(hour), _d_(day), _w_(week), _n_(month), _y_(year). - -### Query database - -```java -// query data -ResultSet resultSet = stmt.executeQuery("select * from tb"); - -Timestamp ts = null; -int temperature = 0; -float humidity = 0; -while(resultSet.next()){ - - ts = resultSet.getTimestamp(1); - temperature = resultSet.getInt(2); - humidity = resultSet.getFloat("humidity"); - - System.out.printf("%s, %d, %s\n", ts, temperature, humidity); -} -``` -> query is consistent with relational database. The subscript start with 1 when retrieving return results. It is recommended to use the column name to retrieve results. - -### Close all - -```java -resultSet.close(); -stmt.close(); -conn.close(); -``` -> `please make sure the connection is closed to avoid the error like connection leakage` - -## Using connection pool - -**HikariCP** - -* dependence in pom.xml: -```xml - - com.zaxxer - HikariCP - 3.4.1 - -``` - -* Examples: -```java - public static void main(String[] args) throws SQLException { - HikariConfig config = new HikariConfig(); - config.setJdbcUrl("jdbc:TAOS://127.0.0.1:6030/log"); - config.setUsername("root"); - config.setPassword("taosdata"); - - config.setMinimumIdle(3); //minimum number of idle connection - config.setMaximumPoolSize(10); //maximum number of connection in the pool - config.setConnectionTimeout(10000); //maximum wait milliseconds for get connection from pool - config.setIdleTimeout(60000); // max idle time for recycle idle connection - config.setConnectionTestQuery("describe log.dn"); //validation query - config.setValidationTimeout(3000); //validation query timeout - - HikariDataSource ds = new HikariDataSource(config); //create datasource - - Connection connection = ds.getConnection(); // get connection - Statement statement = connection.createStatement(); // get statement - - //query or insert - // ... - - connection.close(); // put back to conneciton pool -} -``` -> The close() method will not close the connection from HikariDataSource.getConnection(). Instead, the connection is put back to the connection pool. -> More instructions can refer to [User Guide][5] - -**Druid** - -* dependency in pom.xml: - -```xml - - com.alibaba - druid - 1.1.20 - -``` - -* Examples: -```java -public static void main(String[] args) throws Exception { - Properties properties = new Properties(); - properties.put("driverClassName","com.taosdata.jdbc.TSDBDriver"); - properties.put("url","jdbc:TAOS://127.0.0.1:6030/log"); - properties.put("username","root"); - properties.put("password","taosdata"); - - properties.put("maxActive","10"); //maximum number of connection in the pool - properties.put("initialSize","3");//initial number of connection - properties.put("maxWait","10000");//maximum wait milliseconds for get connection from pool - properties.put("minIdle","3");//minimum number of connection in the pool - - properties.put("timeBetweenEvictionRunsMillis","3000");// the interval milliseconds to test connection - - properties.put("minEvictableIdleTimeMillis","60000");//the minimum milliseconds to keep idle - properties.put("maxEvictableIdleTimeMillis","90000");//the maximum milliseconds to keep idle - - properties.put("validationQuery","describe log.dn"); //validation query - properties.put("testWhileIdle","true"); // test connection while idle - properties.put("testOnBorrow","false"); // don't need while testWhileIdle is true - properties.put("testOnReturn","false"); // don't need while testWhileIdle is true - - //create druid datasource - DataSource ds = DruidDataSourceFactory.createDataSource(properties); - Connection connection = ds.getConnection(); // get connection - Statement statement = connection.createStatement(); // get statement - - //query or insert - // ... - - connection.close(); // put back to conneciton pool -} -``` -> More instructions can refer to [User Guide][6] - -**Notice** -* TDengine `v1.6.4.1` provides a function `select server_status()` to check heartbeat. It is highly recommended to use this function for `Validation Query`. - -As follows,`1` will be returned if `select server_status()` is successfully executed。 -```shell -taos> select server_status(); -server_status()| -================ -1 | -Query OK, 1 row(s) in set (0.000141s) -``` - -## Integrated with framework - -* Please refer to [SpringJdbcTemplate][11] if using taos-jdbcdriver in Spring JdbcTemplate -* Please refer to [springbootdemo][12] if using taos-jdbcdriver in Spring JdbcTemplate - -## FAQ - -* java.lang.UnsatisfiedLinkError: no taos in java.library.path - - **Cause**:The application program cannot find Library function _taos_ - - **Answer**:Copy `C:\TDengine\driver\taos.dll` to `C:\Windows\System32\` on Windows and make a soft link through ` ln -s /usr/local/taos/driver/libtaos.so.x.x.x.x /usr/lib/libtaos.so` on Linux. - -* java.lang.UnsatisfiedLinkError: taos.dll Can't load AMD 64 bit on a IA 32-bit platform - - **Cause**:Currently TDengine only support 64bit JDK - - **Answer**:re-install 64bit JDK. - -* For other questions, please refer to [Issues][7] - - -## Python Connector - -### Pre-requirement -* TDengine installed, TDengine-client installed if on Windows [(Windows TDengine client installation)](https://www.taosdata.com/cn/documentation/connector/#Windows客户端及程序接口) -* python 2.7 or >= 3.4 -* pip installed - -### Installation -#### Linux - -Users can find python client packages in our source code directory _src/connector/python_. There are two directories corresponding to two python versions. Please choose the correct package to install. Users can use _pip_ command to install: - -```cmd -pip install src/connector/python/linux/python3/ -``` - -or - -``` -pip install src/connector/python/linux/python2/ -``` -#### Windows -Assumed the Windows TDengine client has been installed , copy the file "C:\TDengine\driver\taos.dll" to the folder "C:\windows\system32", and then enter the _cmd_ Windows command interface -``` -cd C:\TDengine\connector\python\windows -pip install python3\ -``` -or -``` -cd C:\TDengine\connector\python\windows -pip install python2\ -``` -*If _pip_ command is not installed on the system, users can choose to install pip or just copy the _taos_ directory in the python client directory to the application directory to use. - -### Usage -#### Examples -* import TDengine module - -```python -import taos -``` -* get the connection -```python -conn = taos.connect(host="127.0.0.1", user="root", password="taosdata", config="/etc/taos") -c1 = conn.cursor() -``` -*host is the IP of TDengine server, and config is the directory where exists the TDengine client configure file -* insert records into the database -```python -import datetime - -# create a database -c1.execute('create database db') -c1.execute('use db') -# create a table -c1.execute('create table tb (ts timestamp, temperature int, humidity float)') -# insert a record -start_time = datetime.datetime(2019, 11, 1) -affected_rows = c1.execute('insert into tb values (\'%s\', 0, 0.0)' %start_time) -# insert multiple records in a batch -time_interval = datetime.timedelta(seconds=60) -sqlcmd = ['insert into tb values'] -for irow in range(1,11): - start_time += time_interval - sqlcmd.append('(\'%s\', %d, %f)' %(start_time, irow, irow*1.2)) -affected_rows = c1.execute(' '.join(sqlcmd)) -``` -* query the database -```python -c1.execute('select * from tb') -# fetch all returned results -data = c1.fetchall() -# data is a list of returned rows with each row being a tuple -numOfRows = c1.rowcount -numOfCols = len(c1.description) -for irow in range(numOfRows): - print("Row%d: ts=%s, temperature=%d, humidity=%f" %(irow, data[irow][0], data[irow][1],data[irow][2])) - -# use the cursor as an iterator to retrieve all returned results -c1.execute('select * from tb') -for data in c1: - print("ts=%s, temperature=%d, humidity=%f" %(data[0], data[1],data[2]) -``` - -* create a subscription -```python -# Create a subscription with topic 'test' and consumption interval 1000ms. -# The first argument is True means to restart the subscription; -# if the subscription with topic 'test' has already been created, then pass -# False to this argument means to continue the existing subscription. -sub = conn.subscribe(True, "test", "select * from meters;", 1000) -``` - -* consume a subscription -```python -data = sub.consume() -for d in data: - print(d) -``` - -* close the subscription -```python -sub.close() -``` - -* close the connection -```python -c1.close() -conn.close() -``` -#### Help information - -Users can get module information from Python help interface or refer to our [python code example](). We list the main classes and methods below: - -- _TDengineConnection_ class - - Run `help(taos.TDengineConnection)` in python terminal for details. - -- _TDengineCursor_ class - - Run `help(taos.TDengineCursor)` in python terminal for details. - -- connect method - - Open a connection. Run `help(taos.connect)` in python terminal for details. - -## RESTful Connector - -TDengine also provides RESTful API to satisfy developing on different platforms. Unlike other databases, TDengine RESTful API applies operations to the database through the SQL command in the body of HTTP POST request. What users are required to provide is just a URL. - - -For the time being, TDengine RESTful API uses a _\_ generated from username and password for identification. Safer identification methods will be provided in the future. - - -### HTTP URL encoding - -To use TDengine RESTful API, the URL should have the following encoding format: -``` -http://:/rest/sql -``` -- _ip_: IP address of any node in a TDengine cluster -- _PORT_: TDengine HTTP service port. It is 6020 by default. - -For example, the URL encoding _http://192.168.0.1:6020/rest/sql_ used to send HTTP request to a TDengine server with IP address as 192.168.0.1. - -It is required to add a token in an HTTP request header for identification. - -``` -Authorization: Basic -``` - -The HTTP request body contains the SQL command to run. If the SQL command contains a table name, it should also provide the database name it belongs to in the form of `.`. Otherwise, an error code is returned. - -For example, use _curl_ command to send a HTTP request: - -``` -curl -H 'Authorization: Basic ' -d '' :/rest/sql -``` - -or use - -``` -curl -u username:password -d '' :/rest/sql -``` - -where `TOKEN` is the encryted string of `{username}:{password}` using the Base64 algorithm, e.g. `root:taosdata` will be encoded as `cm9vdDp0YW9zZGF0YQ==` - -### HTTP response - -The HTTP resonse is in JSON format as below: - -``` -{ - "status": "succ", - "head": ["column1","column2", …], - "data": [ - ["2017-12-12 23:44:25.730", 1], - ["2017-12-12 22:44:25.728", 4] - ], - "rows": 2 -} -``` -Specifically, -- _status_: the result of the operation, success or failure -- _head_: description of returned result columns -- _data_: the returned data array. If no data is returned, only an _affected_rows_ field is listed -- _rows_: the number of rows returned - -### Example - -- Use _curl_ command to query all the data in table _t1_ of database _demo_: - - `curl -H 'Authorization: Basic cm9vdDp0YW9zZGF0YQ==' -d 'select * from demo.t1' 192.168.0.1:6020/rest/sql` - -The return value is like: - -``` -{ - "status": "succ", - "head": ["column1","column2","column3"], - "data": [ - ["2017-12-12 23:44:25.730", 1, 2.3], - ["2017-12-12 22:44:25.728", 4, 5.6] - ], - "rows": 2 -} -``` - -- Use HTTP to create a database: - - `curl -H 'Authorization: Basic cm9vdDp0YW9zZGF0YQ==' -d 'create database demo' 192.168.0.1:6020/rest/sql` - - The return value should be: - -``` -{ - "status": "succ", - "head": ["affected_rows"], - "data": [[1]], - "rows": 1, -} -``` - -## Go Connector - -TDengine also provides a Go client package named _taosSql_ for users to access TDengine with Go. The package is in _/usr/local/taos/connector/go/src/taosSql_ by default if you installed TDengine. Users can copy the directory _/usr/local/taos/connector/go/src/taosSql_ to the _src_ directory of your project and import the package in the source code for use. - -```Go -import ( - "database/sql" - _ "taosSql" -) -``` - -The _taosSql_ package is in _cgo_ form, which calls TDengine C/C++ sync interfaces. So a connection is allowed to be used by one thread at the same time. Users can open multiple connections for multi-thread operations. - -Please refer the the demo code in the package for more information. - -## Node.js Connector - -TDengine also provides a node.js connector package that is installable through [npm](https://www.npmjs.com/). The package is also in our source code at *src/connector/nodejs/*. The following instructions are also available [here](https://github.com/taosdata/tdengine/tree/master/src/connector/nodejs) - -To get started, just type in the following to install the connector through [npm](https://www.npmjs.com/). - -```cmd -npm install td-connector -``` - -It is highly suggested you use npm. If you don't have it installed, you can also just copy the nodejs folder from *src/connector/nodejs/* into your node project folder. - -To interact with TDengine, we make use of the [node-gyp](https://github.com/nodejs/node-gyp) library. To install, you will need to install the following depending on platform (the following instructions are quoted from node-gyp) - -### On Unix - -- `python` (`v2.7` recommended, `v3.x.x` is **not** supported) -- `make` -- A proper C/C++ compiler toolchain, like [GCC](https://gcc.gnu.org) - -### On macOS - -- `python` (`v2.7` recommended, `v3.x.x` is **not** supported) (already installed on macOS) - -- Xcode - - - You also need to install the - - ``` - Command Line Tools - ``` - - via Xcode. You can find this under the menu - - ``` - Xcode -> Preferences -> Locations - ``` - - (or by running - - ``` - xcode-select --install - ``` - - in your Terminal) - - - This step will install `gcc` and the related toolchain containing `make` - -### On Windows - -#### Option 1 - -Install all the required tools and configurations using Microsoft's [windows-build-tools](https://github.com/felixrieseberg/windows-build-tools) using `npm install --global --production windows-build-tools` from an elevated PowerShell or CMD.exe (run as Administrator). - -#### Option 2 - -Install tools and configuration manually: - -- Install Visual C++ Build Environment: [Visual Studio Build Tools](https://visualstudio.microsoft.com/thank-you-downloading-visual-studio/?sku=BuildTools) (using "Visual C++ build tools" workload) or [Visual Studio 2017 Community](https://visualstudio.microsoft.com/pl/thank-you-downloading-visual-studio/?sku=Community) (using the "Desktop development with C++" workload) -- Install [Python 2.7](https://www.python.org/downloads/) (`v3.x.x` is not supported), and run `npm config set python python2.7` (or see below for further instructions on specifying the proper Python version and path.) -- Launch cmd, `npm config set msvs_version 2017` - -If the above steps didn't work for you, please visit [Microsoft's Node.js Guidelines for Windows](https://github.com/Microsoft/nodejs-guidelines/blob/master/windows-environment.md#compiling-native-addon-modules) for additional tips. - -To target native ARM64 Node.js on Windows 10 on ARM, add the components "Visual C++ compilers and libraries for ARM64" and "Visual C++ ATL for ARM64". - -### Usage - -The following is a short summary of the basic usage of the connector, the full api and documentation can be found [here](http://docs.taosdata.com/node) - -#### Connection - -To use the connector, first require the library ```td-connector```. Running the function ```taos.connect``` with the connection options passed in as an object will return a TDengine connection object. The required connection option is ```host```, other options if not set, will be the default values as shown below. - -A cursor also needs to be initialized in order to interact with TDengine from Node.js. - -```javascript -const taos = require('td-connector'); -var conn = taos.connect({host:"127.0.0.1", user:"root", password:"taosdata", config:"/etc/taos",port:0}) -var cursor = conn.cursor(); // Initializing a new cursor -``` - -To close a connection, run - -```javascript -conn.close(); -``` - -#### Queries - -We can now start executing simple queries through the ```cursor.query``` function, which returns a TaosQuery object. - -```javascript -var query = cursor.query('show databases;') -``` - -We can get the results of the queries through the ```query.execute()``` function, which returns a promise that resolves with a TaosResult object, which contains the raw data and additional functionalities such as pretty printing the results. - -```javascript -var promise = query.execute(); -promise.then(function(result) { - result.pretty(); //logs the results to the console as if you were in the taos shell -}); -``` - -You can also query by binding parameters to a query by filling in the question marks in a string as so. The query will automatically parse what was binded and convert it to the proper format for use with TDengine - -```javascript -var query = cursor.query('select * from meterinfo.meters where ts <= ? and areaid = ?;').bind(new Date(), 5); -query.execute().then(function(result) { - result.pretty(); -}) -``` - -The TaosQuery object can also be immediately executed upon creation by passing true as the second argument, returning a promise instead of a TaosQuery. - -```javascript -var promise = cursor.query('select * from meterinfo.meters where v1 = 30;', true) -promise.then(function(result) { - result.pretty(); -}) -``` -#### Async functionality - -Async queries can be performed using the same functions such as `cursor.execute`, `TaosQuery.execute`, but now with `_a` appended to them. - -Say you want to execute an two async query on two seperate tables, using `cursor.query`, you can do that and get a TaosQuery object, which upon executing with the `execute_a` function, returns a promise that resolves with a TaosResult object. - -```javascript -var promise1 = cursor.query('select count(*), avg(v1), avg(v2) from meter1;').execute_a() -var promise2 = cursor.query('select count(*), avg(v1), avg(v2) from meter2;').execute_a(); -promise1.then(function(result) { - result.pretty(); -}) -promise2.then(function(result) { - result.pretty(); -}) -``` - - -### Example - -An example of using the NodeJS connector to create a table with weather data and create and execute queries can be found [here](https://github.com/taosdata/TDengine/tree/master/tests/examples/nodejs/node-example.js) (The preferred method for using the connector) - -An example of using the NodeJS connector to achieve the same things but without all the object wrappers that wrap around the data returned to achieve higher functionality can be found [here](https://github.com/taosdata/TDengine/tree/master/tests/examples/nodejs/node-example-raw.js) - -[1]: https://search.maven.org/artifact/com.taosdata.jdbc/taos-jdbcdriver -[2]: https://mvnrepository.com/artifact/com.taosdata.jdbc/taos-jdbcdriver -[3]: https://github.com/taosdata/TDengine -[4]: https://www.taosdata.com/blog/2019/12/03/jdbcdriver%e6%89%be%e4%b8%8d%e5%88%b0%e5%8a%a8%e6%80%81%e9%93%be%e6%8e%a5%e5%ba%93/ -[5]: https://github.com/brettwooldridge/HikariCP -[6]: https://github.com/alibaba/druid -[7]: https://github.com/taosdata/TDengine/issues -[8]: https://search.maven.org/artifact/com.taosdata.jdbc/taos-jdbcdriver -[9]: https://mvnrepository.com/artifact/com.taosdata.jdbc/taos-jdbcdriver -[10]: https://maven.aliyun.com/mvn/search -[11]: https://github.com/taosdata/TDengine/tree/develop/tests/examples/JDBC/SpringJdbcTemplate -[12]: https://github.com/taosdata/TDengine/tree/develop/tests/examples/JDBC/springbootdemo -[13]: https://www.taosdata.com/cn/documentation/administrator/#%E5%AE%A2%E6%88%B7%E7%AB%AF%E9%85%8D%E7%BD%AE -[14]: https://www.taosdata.com/cn/documentation/connector/#Windows%E5%AE%A2%E6%88%B7%E7%AB%AF%E5%8F%8A%E7%A8%8B%E5%BA%8F%E6%8E%A5%E5%8F%A3 -[15]: https://www.taosdata.com/cn/getting-started/#%E5%BF%AB%E9%80%9F%E4%B8%8A%E6%89%8B diff --git a/2.0/documentation/webdocs/markdowndocs/Contributor_License_Agreement.md b/2.0/documentation/webdocs/markdowndocs/Contributor_License_Agreement.md deleted file mode 100644 index 8c158da4c5..0000000000 --- a/2.0/documentation/webdocs/markdowndocs/Contributor_License_Agreement.md +++ /dev/null @@ -1,35 +0,0 @@ -# TaosData Contributor License Agreement - -This TaosData Contributor License Agreement (CLA) applies to any contribution you make to any TaosData projects. If you are representing your employing organization to sign this agreement, please warrant that you have the authority to grant the agreement. - -## Terms - -**"TaosData"**, **"we"**, **"our"** and **"us"** means TaosData, inc. - -**"You"** and **"your"** means you or the organization you are on behalf of to sign this agreement. - -**"Contribution"** means any original work you, or the organization you represent submit to TaosData for any project in any manner. - -## Copyright License - -All rights of your Contribution submitted to TaosData in any manner are granted to TaosData and recipients of software distributed by TaosData. You waive any rights that my affect our ownership of the copyright and grant to us a perpetual, worldwide, transferable, non-exclusive, no-charge, royalty-free, irrevocable, and sublicensable license to use, reproduce, prepare derivative works of, publicly display, publicly perform, sublicense, and distribute Contributions and any derivative work created based on a Contribution. - -## Patent License - -With respect to any patents you own or that you can license without payment to any third party, you grant to us and to any recipient of software distributed by us, a perpetual, worldwide, transferable, non-exclusive, no-charge, royalty-free, irrevocable patent license to make, have make, use, sell, offer to sell, import, and otherwise transfer the Contribution in whole or in part, alone or included in any product under any patent you own, or license from a third party, that is necessarily infringed by the Contribution or by combination of the Contribution with any Work. - -## Your Representations and Warranties - -You represent and warrant that: - -- the Contribution you submit is an original work that you can legally grant the rights set out in this agreement. - -- the Contribution you submit and licenses you granted does not and will not, infringe the rights of any third party. - -- you are not aware of any pending or threatened claims, suits, actions, or charges pertaining to the contributions. You also warrant to notify TaosData immediately if you become aware of any such actual or potential claims, suits, actions, allegations or charges. - -## Support - -You are not obligated to support your Contribution except you volunteer to provide support. If you want, you can provide for a fee. - -**I agree and accept on behalf of myself and behalf of my organization:** \ No newline at end of file diff --git a/2.0/documentation/webdocs/markdowndocs/Data model and architecture-ch.md b/2.0/documentation/webdocs/markdowndocs/Data model and architecture-ch.md deleted file mode 100644 index f17b015172..0000000000 --- a/2.0/documentation/webdocs/markdowndocs/Data model and architecture-ch.md +++ /dev/null @@ -1,100 +0,0 @@ -# 数据模型和设计 - -## 数据模型 - -### 物联网典型场景 - -在典型的物联网、车联网、运维监测场景中,往往有多种不同类型的数据采集设备,采集一个到多个不同的物理量。而同一种采集设备类型,往往又有多个具体的采集设备分布在不同的地点。大数据处理系统就是要将各种采集的数据汇总,然后进行计算和分析。对于同一类设备,其采集的数据类似如下的表格: - -| Device ID | Time Stamp | Value 1 | Value 2 | Value 3 | Tag 1 | Tag 2 | -| :-------: | :-----------: | :-----: | :-----: | :-----: | :---: | :---: | -| D1001 | 1538548685000 | 10.3 | 219 | 0.31 | Red | Tesla | -| D1002 | 1538548684000 | 10.2 | 220 | 0.23 | Blue | BMW | -| D1003 | 1538548686500 | 11.5 | 221 | 0.35 | Black | Honda | -| D1004 | 1538548685500 | 13.4 | 223 | 0.29 | Red | Volvo | -| D1001 | 1538548695000 | 12.6 | 218 | 0.33 | Red | Tesla | -| D1004 | 1538548696600 | 11.8 | 221 | 0.28 | Black | Honda | - -每一条记录都有设备ID,时间戳,采集的物理量,还有与每个设备相关的静态标签。每个设备是受外界的触发,或按照设定的周期采集数据。采集的数据点是时序的,是一个数据流。 - -### 数据特征 - -除时序特征外,仔细研究发现,物联网、车联网、运维监测类数据还具有很多其他明显的特征。 - -1. 数据是结构化的; -2. 数据极少有更新或删除操作; -3. 无需传统数据库的事务处理; -4. 相对互联网应用,写多读少; -5. 流量平稳,根据设备数量和采集频次,可以预测出来; -6. 用户关注的是一段时间的趋势,而不是某一特点时间点的值; -7. 数据是有保留期限的; -8. 数据的查询分析一定是基于时间段和地理区域的; -9. 除存储查询外,还往往需要各种统计和实时计算操作; -10. 数据量巨大,一天采集的数据就可以超过100亿条。 - -充分利用上述特征,TDengine采取了一特殊的优化的存储和计算设计来处理时序数据,能将系统处理能力显著提高。 - -### 关系型数据库模型 - -因为采集的数据一般是结构化数据,而且为降低学习门槛,TDengine采用传统的关系型数据库模型管理数据。因此用户需要先创建库,然后创建表,之后才能插入或查询数据。 - -### 一个设备一张表 - -为充分利用其数据的时序性和其他数据特点,TDengine要求**对每个数据采集点单独建表**(比如有一千万个智能电表,就需创建一千万张表,上述表格中的D1001, D1002, D1003, D1004都需单独建表),用来存储这个采集点所采集的时序数据。这种设计能保证一个采集点的数据在存储介质上是一块一块连续的,大幅减少随机读取操作,成数量级的提升读取和查询速度。而且由于不同数据采集设备产生数据的过程完全独立,每个设备只产生属于自己的数据,一张表也就只有一个写入者。这样每个表就可以采用无锁方式来写,写入速度就能大幅提升。同时,对于一个数据采集点而言,其产生的数据是时序的,因此写的操作可用追加的方式实现,进一步大幅提高数据写入速度。 - -### 数据建模最佳实践 - -**表(Table)**:TDengine 建议用数据采集点的名字(如上表中的D1001)来做表名。每个数据采集点可能同时采集多个物理量(如上表中的value1, value2, value3),每个物理量对应一张表中的一列,数据类型可以是整型、浮点型、字符串等。除此之外,表的第一列必须是时间戳,即数据类型为 timestamp。有的设备有多组采集量,每一组的采集频次是不一样的,这是需要对同一个设备建多张表。对采集的数据,TDengine将自动按照时间戳建立索引,但对采集的物理量不建任何索引。数据是用列式存储方式保存。 - -**超级表(Super Table)**:对于同一类型的采集点,为保证Schema的一致性,而且为便于聚合统计操作,可以先定义超级表STable(详见第10章),然后再定义表。每个采集点往往还有静态标签信息(如上表中的Tag 1, Tag 2),比如设备型号、颜色等,这些静态信息不会保存在存储采集数据的数据节点中,而是通过超级表保存在元数据节点中。这些静态标签信息将作为过滤条件,用于采集点之间的数据聚合统计操作。 - -**库(DataBase)**:不同的数据采集点往往具有不同的数据特征,包括数据采集频率高低,数据保留时间长短,备份数目,单个字段大小等等。为让各种场景下TDengine都能最大效率的工作,TDengine建议将不同数据特征的表创建在不同的库里。创建一个库时,除SQL标准的选项外,应用还可以指定保留时长、数据备份的份数、cache大小、文件块大小、是否压缩等多种参数(详见第19章)。 - -**Schemaless vs Schema**: 与NoSQL的各种引擎相比,由于应用需要定义schema,插入数据的灵活性降低。但对于物联网、金融这些典型的时序数据场景,schema会很少变更,因此这个灵活性不够的设计就不成问题。相反,TDengine采用结构化数据来进行处理的方式将让查询、分析的性能成数量级的提升。 - -TDengine对库的数量、超级表的数量以及表的数量没有做任何限制,而且其多少不会对性能产生影响,应用按照自己的场景创建即可。 - -## 主要模块 -如图所示,TDengine服务主要包含两大模块:**管理节点模块(MGMT)** 和 **数据节点模块(DNODE)**。整个TDengine还包含**客户端模块**。 - -
        -
        图 1 TDengine架构示意图
        - -### 管理节点模块 -管理节点模块主要负责元数据的存储和查询等工作,其中包括用户信息的管理、数据库和表信息的创建、删除以及查询等。应用连接TDengine时会首先连接到管理节点。在创建/删除数据库和表时,请求也会首先发送请求到管理节点模块。由管理节点模块首先创建/删除元数据信息,然后发送请求到数据节点模块进行分配/删除所需要的资源。在数据写入和查询时,应用同样会首先访问管理节点模块,获取元数据信息。然后根据元数据管理信息访问数据节点模块。 - -### 数据节点模块 -写入数据的存储和查询工作是由数据节点模块负责。 为了更高效地利用资源,以及方便将来进行水平扩展,TDengine内部对数据节点进行了虚拟化,引入了虚拟节点(virtual node, 简称vnode)的概念,作为存储、资源分配以及数据备份的单元。如图2所示,在一个dnode上,通过虚拟化,可以将该dnode视为多个虚拟节点的集合。 - -创建一个库时,系统会自动分配vnode。每个vnode存储一定数量的表中的数据,但一个表只会存在于一个vnode里,不会跨vnode。一个vnode只会属于一个库,但一个库会有一到多个vnode。不同的vnode之间资源互不共享。每个虚拟节点都有自己的缓存,在硬盘上也有自己的存储目录。而同一vnode内部无论是缓存还是硬盘的存储都是共享的。通过虚拟化,TDengine可以将dnode上有限的物理资源合理地分配给不同的vnode,大大提高资源的利用率和并发度。一台物理机器上的虚拟节点个数可以根据其硬件资源进行配置。 - -
        -
        图 2 TDengine虚拟化
        - -### 客户端模块 -TDengine客户端模块主要负责将应用传来的请求(SQL语句)进行解析,转化为内部结构体再发送到服务端。TDengine的各种接口都是基于TDengine的客户端模块进行开发的。客户端模块与管理模块使用TCP/UDP通讯,端口号由系统参数mgmtShellPort配置, 缺省值为6030。客户端与数据节点模块也是使用TCP/UDP通讯,端口号由系统参数vnodeShellPort配置, 缺省值为6035。两个端口号均可通过
        系统配置文件taos.cfg进行个性化设置。 - -## 写入流程 -TDengine的完整写入流程如图3所示。为了保证写入数据的安全性和完整性,TDengine在写入数据时采用[预写日志算法]。客户端发来的数据在经过验证以后,首先会写入预写日志中,以保证TDengine能够在断电等因素导致的服务重启时从预写日志中恢复数据,避免数据的丢失。写入预写日志后,数据会被写到对应的vnode的缓存中。随后,服务端会发送确认信息给客户端表示写入成功。TDengine中存在两种机制可以促使缓存中的数据写入到硬盘上进行持久化存储: - -
        -
        图 3 TDengine写入流程
        - -1. **时间驱动的落盘**:TDengine服务会定时将vnode缓存中的数据写入到硬盘上,默认为一个小时落一次盘。落盘间隔可在配置文件taos.cfg中通过参数commitTime配置。 -2. **数据驱动的落盘**:当vnode中缓存的数据达到一定规模时,为了不阻塞后续数据的写入,TDengine也会拉起落盘线程将缓存中的数据清空。数据驱动的落盘会刷新定时落盘的时间。 - -TDengine在数据落盘时会打开新的预写日志文件,在落盘后则会删除老的预写日志文件,避免日志文件无限制的增长。TDengine对缓存按照先进先出的原则进行管理,以保证每个表的最新数据都在缓存中。 - -## 数据存储 - -TDengine将所有数据存储在/var/lib/taos/目录下,您可以通过系统配置参数dataDir进行个性化配置。 - -TDengine中的元数据信息包括TDengine中的数据库、表、用户等信息。每个超级表、以及每个表的标签数据也存放在这里。为提高访问速度,元数据全部有缓存。 - -TDengine中写入的数据在硬盘上是按时间维度进行分片的。同一个vnode中的表在同一时间范围内的数据都存放在同一文件组中。这一数据分片方式可以大大简化数据在时间维度的查询,提高查询速度。在默认配置下,硬盘上的每个数据文件存放10天数据。用户可根据需要修改系统配置参数daysPerFile进行个性化配置。 - -表中的数据都有保存时间,一旦超过保存时间(缺省是3650天),数据将被系统自动删除。您可以通过系统配置参数daysToKeep进行个性化设置。 - -数据在文件中是按块存储的。每个数据块只包含一张表的数据,且数据是按照时间主键递增排列的。数据在数据块中按列存储,这样使得同列的数据存放在一起,对于不同的数据类型还采用不同的压缩方法,大大提高压缩的比例,节省存储空间。 - -数据文件总共有三类文件,一类是data文件,它存放了真实的数据块,该文件只进行追加操作;一类文件是head文件, 它存放了其对应的data文件中数据块的索引信息;第三类是last文件,专门存储最后写入的数据,每次落盘操作时,这部分数据会与内存里的数据合并,并决定是否写入data文件还是last文件。 \ No newline at end of file diff --git a/2.0/documentation/webdocs/markdowndocs/Data model and architecture.md b/2.0/documentation/webdocs/markdowndocs/Data model and architecture.md deleted file mode 100644 index 1cf503f3c1..0000000000 --- a/2.0/documentation/webdocs/markdowndocs/Data model and architecture.md +++ /dev/null @@ -1,101 +0,0 @@ -# Data Model and Architecture -## Data Model - -### A Typical IoT Scenario - -In a typical IoT scenario, there are many types of devices. Each device is collecting one or multiple metrics. For a specific type of device, the collected data could look like the table below: - -| Device ID | Time Stamp | Value 1 | Value 2 | Value 3 | Tag 1 | Tag 2 | -| :-------: | :-----------: | :-----: | :-----: | :-----: | :---: | :---: | -| D1001 | 1538548685000 | 10.3 | 219 | 0.31 | Red | Tesla | -| D1002 | 1538548684000 | 10.2 | 220 | 0.23 | Blue | BMW | -| D1003 | 1538548686500 | 11.5 | 221 | 0.35 | Black | Honda | -| D1004 | 1538548685500 | 13.4 | 223 | 0.29 | Red | Volvo | -| D1001 | 1538548695000 | 12.6 | 218 | 0.33 | Red | Tesla | -| D1004 | 1538548696600 | 11.8 | 221 | 0.28 | Black | Honda | - -Each data record contains the device ID, timestamp, collected metrics, and static tags associated with the device. Each device generates a data record in a pre-defined timer or triggered by an event. It is a sequence of data points like a stream. - -### Data Characteristics - -As the data points are a series of data points over time, the data points generated by devices, sensors, servers, and/or applications have some strong common characteristics: - -1. metrics are always structured data; -2. there are rarely delete/update operations on collected data; -3. there is only one single data source for one device or sensor; -4. ratio of read/write is much lower than typical Internet applications; -5. the user pays attention to the trend of data, not a specific value at a specific time; -6. there is always a data retention policy; -7. the data query is always executed in a given time range and a subset of devices; -8. real-time aggregation or analytics is mandatory; -9. traffic is predictable based on the number of devices and sampling frequency; -10. data volume is huge, a system may generate 10 billion data points in a day. - -By utilizing the above characteristics, TDengine designs the storage and computing engine in a special and optimized way for time-series data, resulting in massive improvements in system efficiency. - -### Relational Database Model - -Since time-series data is most likely to be structured data, TDengine adopts the traditional relational database model to process them. You need to create a database, create tables with schema definitions, then insert data points and execute queries to explore the data. Standard SQL is used, making it easy for anyone to get started and eliminating any learning curve. - -### One Table for One Device - -Due to different network latencies, the data points from different devices may arrive to the server out of order. But for the same device, data points will arrive to the server in order if the system is designed well. To utilize this special feature, TDengine requires the user to create a table for each device (time-stream). For example, if there are over 10,000 smart meters, 10,000 tables shall be created. For the table above, 4 tables shall be created for device D1001, D1002, D1003, and D1004 to store the data collected. - -This strong requirement can guarantee that all data points from a device can be saved in a continuous memory/hard disk space block by block. If queries are applied only on one device in a time range, this design will reduce the read latency significantly since a whole block is owned by one single device. Additionally, write latency can be significantly reduced too as the data points generated by the same device will arrive in order, the new data point will be simply appended to a block. Cache block size and the rows of records in a file block can be configured to fit different scenarios for optimal efficiency. - -### Best Practices - -**Table**: TDengine suggests to use device ID as the table name (like D1001 in the above diagram). Each device may collect one or more metrics (like value1, value2, value3 in the diagram). Each metric has a column in the table, the metric name can be used as the column name. The data type for a column can be int, float, double, tinyint, bigint, bool or binary. Sometimes, a device may have multiple metric groups, each group containing different sampling periods, so for best practice you should create a table for each group for each device. The first column in the table must be a time stamp. TDengine uses the time stamp as the index, and won’t build the index on any metrics stored. - -**Tags:** To support aggregation over multiple tables efficiently, the [STable(Super Table)](../super-table) concept is introduced by TDengine. A STable is used to represent the same type of device. The schema is used to define the collected metrics (like value1, value2, value3 in the diagram), and tags are used to define the static attributes for each table or device (like tag1, tag2 in the diagram). A table is created via STable with a specific tag value. All or a subset of tables in a STable can be aggregated by filtering tag values. - -**Database:** Different types of devices may generate data points in different patterns and should be processed differently. For example, sampling frequency, data retention policy, replication number, cache size, record size, the compression algorithm may be different. To make the system more efficient, TDengine suggests creating a different database with unique configurations for different scenarios. - -**Schemaless vs Schema:** Compared with NoSQL databases, since a table with schema definitions must be created before the data points can be inserted, flexibilities are not that good, especially when the schema is changed. But in most IoT scenarios, the schema is well defined and is rarely changed, the loss of flexibility won't pose any impact to developers or administrators. TDengine allows the application to change the schema in a second even there is a huge amount of historical data when schema has to be changed. - -TDengine does not impose a limitation on the number of tables, [STables](../super-table), or databases. You can create any number of STable or databases to fit different scenarios. - -## Architecture - -There are two main modules in TDengine server as shown in Picture 1: **Management Module (MGMT)** and **Data Module(DNODE)**. The whole TDengine architecture also includes a **TDengine Client Module**. - -
        -
        Picture 1 TDengine Architecture
        -### MGMT Module -The MGMT module deals with the storage and querying on metadata, which includes information about users, databases, and tables. Applications will connect to the MGMT module at first when connecting the TDengine server. When creating/dropping databases/tables, The request is sent to the MGMT module at first to create/delete metadata. Then the MGMT module will send requests to the data module to allocate/free resources required. In the case of writing or querying, applications still need to visit the MGMT module to get meta data, according to which, then access the DNODE module. - -### DNODE Module -The DNODE module is responsible for storing and querying data. For the sake of future scaling and high-efficient resource usage, TDengine applies virtualization on resources it uses. TDengine introduces the concept of a virtual node (vnode), which is the unit of storage, resource allocation and data replication (enterprise edition). As is shown in Picture 2, TDengine treats each data node as an aggregation of vnodes. - -When a DB is created, the system will allocate a vnode. Each vnode contains multiple tables, but a table belongs to only one vnode. Each DB has one or mode vnodes, but one vnode belongs to only one DB. Each vnode contains all the data in a set of tables. Vnodes have their own cache and directory to store data. Resources between different vnodes are exclusive with each other, no matter cache or file directory. However, resources in the same vnode are shared between all the tables in it. Through virtualization, TDengine can distribute resources reasonably to each vnode and improve resource usage and concurrency. The number of vnodes on a dnode is configurable according to its hardware resources. - -
        -
        Picture 2 TDengine Virtualization
        - -### Client Module -TDengine client module accepts requests (mainly in SQL form) from applications and converts the requests to internal representations and sends to the server side. TDengine supports multiple interfaces, which are all built on top of TDengine client module. - -For the communication between client and MGMT module, TCP/UDP is used, the port is set by the parameter `mgmtShellPort` in system configuration file `taos.cfg`, default is 6030. For communication between the client and the DNODE module, TCP/UDP is used, the port is set by the parameter `vnodeShellPort` in the system configuration file, default is 6035. - -## Writing Process -Picture 3 shows the full writing process of TDengine. TDengine uses the [Writing Ahead Log] (http://en.wikipedia.org/wiki/Write-ahead_logging) strategy to assure data security and integrity. Data received from the client is written to the commit log at first. When TDengine recovers from crashes caused by power loss or other situations, the commit log is used to recover data. After writting to the commit log, data will be wrtten to the corresponding vnode cache, then an acknowledgment is sent to the application. There are two mechanisms that can flush data in cache to disk for persistent storage: - -1. **Flush driven by timer**: There is a backend timer which flushes data in cache periodically to disks. The period is configurable via parameter commitTime in system configuration file taos.cfg. -2. **Flush driven by data**: Data in the cache is also flushed to disks when the left buffer size is below a threshold. Flush driven by data can reset the timer of flush driven by the timer. - -
        -
        Picture 3 TDengine Writting Process
        - -New commit log files will be opened when the committing process begins. When the committing process finishes, the old commit file will be removed. - -## Data Storage - -TDengine data are saved in _/var/lib/taos_ directory by default. It can be changed to other directories by setting the parameter `dataDir` in system configuration file taos.cfg. - -TDengine's metadata includes the database, table, user, super table and tag information. To reduce the latency, metadata are all buffered in the cache. - -Data records saved in tables are sharded according to the time range. Data from tables in the same vnode in a certain time range are saved in the same file group. This sharding strategy can effectively improve data search speed. By default, one group of files contain data in 10 days, which can be configured by `daysPerFile` in the configuration file or by the *DAYS* keyword in *CREATE DATABASE* clause. - -Data records are removed automatically once their lifetime is passed. The lifetime is configurable via parameter daysToKeep in the system configuration file. The default value is 3650 days. - -Data in files are blockwise. A data block only contains one table's data. Records in the same data block are sorted according to the primary timestamp. To improve the compression ratio, records are stored column by column, and different compression algorithms are applied based on each column's data type. \ No newline at end of file diff --git a/2.0/documentation/webdocs/markdowndocs/More on System Architecture-ch.md b/2.0/documentation/webdocs/markdowndocs/More on System Architecture-ch.md deleted file mode 100644 index 77ce963888..0000000000 --- a/2.0/documentation/webdocs/markdowndocs/More on System Architecture-ch.md +++ /dev/null @@ -1,248 +0,0 @@ -# TDengine的技术设计 - -## 存储设计 - -TDengine的数据存储主要包含**元数据的存储**和**写入数据的存储**。以下章节详细介绍了TDengine各种数据的存储结构。 - -### 元数据的存储 - -TDengine中的元数据信息包括TDengine中的数据库,表,超级表等信息。元数据信息默认存放在 _/var/lib/taos/mgmt/_ 文件夹下。该文件夹的目录结构如下所示: -``` -/var/lib/taos/ - +--mgmt/ - +--db.db - +--meters.db - +--user.db - +--vgroups.db -``` -元数据在文件中按顺序排列。文件中的每条记录代表TDengine中的一个元数据机构(数据库、表等)。元数据文件只进行追加操作,即便是元数据的删除,也只是在数据文件中追加一条删除的记录。 - -### 写入数据的存储 - -TDengine中写入的数据在硬盘上是按时间维度进行分片的。同一个vnode中的表在同一时间范围内的数据都存放在同一文件组中,如下图中的v0f1804*文件。这一数据分片方式可以大大简化数据在时间维度的查询,提高查询速度。在默认配置下,硬盘上的每个文件存放10天数据。用户可根据需要调整数据库的 _daysPerFile_ 配置项进行配置。 数据在文件中是按块存储的。每个数据块只包含一张表的数据,且数据是按照时间主键递增排列的。数据在数据块中按列存储,这样使得同类型的数据存放在一起,可以大大提高压缩的比例,节省存储空间。TDengine对不同类型的数据采用了不同的压缩算法进行压缩,以达到最优的压缩结果。TDengine使用的压缩算法包括simple8B、delta-of-delta、RLE以及LZ4等。 - -TDengine的数据文件默认存放在 */var/lib/taos/data/* 下。而 */var/lib/taos/tsdb/* 文件夹下存放了vnode的信息、vnode中表的信息以及数据文件的链接等。其完整目录结构如下所示: -``` -/var/lib/taos/ - +--tsdb/ - | +--vnode0 - | +--meterObj.v0 - | +--db/ - | +--v0f1804.head->/var/lib/taos/data/vnode0/v0f1804.head1 - | +--v0f1804.data->/var/lib/taos/data/vnode0/v0f1804.data - | +--v0f1804.last->/var/lib/taos/data/vnode0/v0f1804.last1 - | +--v0f1805.head->/var/lib/taos/data/vnode0/v0f1805.head1 - | +--v0f1805.data->/var/lib/taos/data/vnode0/v0f1805.data - | +--v0f1805.last->/var/lib/taos/data/vnode0/v0f1805.last1 - | : - +--data/ - +--vnode0/ - +--v0f1804.head1 - +--v0f1804.data - +--v0f1804.last1 - +--v0f1805.head1 - +--v0f1805.data - +--v0f1805.last1 - : -``` - -#### meterObj文件 -每个vnode中只存在一个 _meterObj_ 文件。该文件中存储了vnode的基本信息(创建时间,配置信息,vnode的统计信息等)以及该vnode中表的信息。其结构如下所示: -``` -<文件开始> -[文件头] -[表记录1偏移量和长度] -[表记录2偏移量和长度] -... -[表记录N偏移量和长度] -[表记录1] -[表记录2] -... -[表记录N] -[表记录] -<文件结尾> -``` -其中,文件头大小为512字节,主要存放vnode的基本信息。每条表记录代表属于该vnode中的一张表在硬盘上的表示。 - -#### head文件 -head文件中存放了其对应的data文件中数据块的索引信息。该文件组织形式如下: -``` -<文件开始> -[文件头] -[表1偏移量] -[表2偏移量] -... -[表N偏移量] -[表1数据索引] -[表2数据索引] -... -[表N数据索引] -<文件结尾> -``` -文件开头的偏移量列表表示对应表的数据索引块的开始位置在文件中的偏移量。每张表的数据索引信息在head文件中都是连续存放的。这也使得TDengine在读取单表数据时,可以将该表所有的数据块索引一次性读入内存,大大提高读取速度。表的数据索引块组织如下: -``` -[索引块信息] -[数据块1索引] -[数据块2索引] -... -[数据块N索引] -``` -其中,索引块信息中记录了数据块的个数等描述信息。每个数据块索引对应一个在data文件或last文件中的一个单独的数据块。索引信息中记录了数据块存放的文件、数据块起始位置的偏移量、数据块中数据时间主键的范围等。索引块中的数据块索引是按照时间范围顺序排放的,这也就是说,索引块M对应的数据块中的数据时间范围都大于索引块M-1的。这种预先排序的存储方式使得在TDengine在进行按照时间戳进行查询时可以使用折半查找算法,大大提高查询速度。 - -#### data文件 -data文件中存放了真实的数据块。该文件只进行追加操作。其文件组织形式如下: -``` -<文件开始> -[文件头] -[数据块1] -[数据块2] -... -[数据块N] -<文件结尾> -``` -每个数据块只属于vnode中的一张表,且数据块中的数据按照时间主键排列。数据块中的数据按列组织排放,使得同一类型的数据排放在一起,方便压缩和读取。每个数据块的组织形式如下所示: -``` -[列1信息] -[列2信息] -... -[列N信息] -[列1数据] -[列2数据] -... -[列N数据] -``` -列信息中包含该列的类型,列的压缩算法,列数据在文件中的偏移量以及长度等。除此之外,列信息中也包含该内存块中该列数据的预计算结果,从而在过滤查询时根据预计算结果判定是否读取数据块,大大提高读取速度。 - -#### last文件 -为了防止数据块的碎片化,提高查询速度和压缩率,TDengine引入了last文件。当要落盘的数据块中的数据条数低于某个阈值时,TDengine会先将该数据块写入到last文件中进行暂时存储。当有新的数据需要落盘时,last文件中的数据会被读取出来与新数据组成新的数据块写入到data文件中。last文件的组织形式与data文件类似。 - -### TDengine数据存储小结 -TDengine通过其创新的架构和存储结构设计,有效提高了计算机资源的使用率。一方面,TDengine的虚拟化使得TDengine的水平扩展及备份非常容易。另一方面,TDengine将表中数据按时间主键排序存储且其列式存储的组织形式都使TDengine在写入、查询以及压缩方面拥有非常大的优势。 - - -## 查询处理 - -### 概述 - -TDengine提供了多种多样针对表和超级表的查询处理功能,除了常规的聚合查询之外,还提供针对时序数据的窗口查询、统计聚合等功能。TDengine的查询处理需要客户端、管理节点、数据节点协同完成。 各组件包含的与查询处理相关的功能和模块如下: - -客户端(Client App)。客户端包含TAOS SQL的解析(SQL Parser)和查询请求执行器(Query Executor),第二阶段聚合器(Result Merger),连续查询管理器(Continuous Query Manager)等主要功能模块构成。SQL解析器负责对SQL语句进行解析校验,并转化为抽象语法树,查询执行器负责将抽象语法树转化查询执行逻辑,并根据SQL语句查询条件,将其转换为针对管理节点元数据查询和针对数据节点的数据查询两级查询处理。由于TAOS SQL当前不提供复杂的嵌套查询和pipeline查询处理机制,所以不再需要查询计划优化、逻辑查询计划到物理查询计划转换等过程。第二阶段聚合器负责将各数据节点查询返回的独立结果进行二阶段聚合生成最后的结果。连续查询管理器则负责针对用户建立的连续查询进行管理,负责定时拉起查询请求并按需将结果写回TDengine或返回给客户应用。此外,客户端还负责查询失败后重试、取消查询请求、以及维持连接心跳、向管理节点上报查询状态等工作。 - -管理节点(Management Node)。管理节点保存了整个集群系统的全部数据的元数据信息,向客户端节点提供查询所需的数据的元数据,并根据集群的负载情况切分查询请求。通过超级表包含了通过该超级表创建的所有表的信息,因此查询处理器(Query Executor)负责针对标签(TAG)的查询处理,并将满足标签查询请求的表信息返回给客户端。此外,管理节点还维护集群的查询状态(Query Status Manager)维护,查询状态管理中在内存中临时保存有当前正在执行的全部查询,当客户端使用 *show queries* 命令的时候,将当前系统正在运行的查询信息返回客户端。 - -数据节点(Data Node)。数据节点保存了数据库中全部数据内容,并通过查询执行器、查询处理调度器、查询任务队列(Query Task Queue)进行查询处理的调度执行,从客户端接收到的查询处理请求都统一放置到处理队列中,查询执行器从队列中获得查询请求,并负责执行。通过查询优化器(Query Optimizer)对于查询进行基本的优化处理,以及通过数据节点的查询执行器(Query Executor)扫描符合条件的数据单元并返回计算结果。等接收客户端发出的查询请求,执行查询处理,并将结果返回。同时数据节点还需要响应来自管理节点的管理信息和命令,例如 *kill query* 命令以后,需要即刻停止执行的查询任务。 - -
        -
        图 1. 系统查询处理架构图(只包含查询相关组件)
        - -### 普通查询处理 - -客户端、管理节点、数据节点协同完成TDengine的查询处理全流程。我们以一个具体的SQL查询为例,说明TDengine的查询处理流程。SQL语句向超级表*FOO_SUPER_TABLE*查询获取时间范围在2019年1月12日整天,标签TAG_LOC是'beijing'的表所包含的所有记录总数,SQL语句如下: - -```sql -SELECT COUNT(*) -FROM FOO_SUPER_TABLE -WHERE TAG_LOC = 'beijing' AND TS >= '2019-01-12 00:00:00' AND TS < '2019-01-13 00:00:00' -``` - -首先,客户端调用TAOS SQL解析器对SQL语句进行解析及合法性检查,然后生成语法树,并从中提取查询的对象 — 超级表 *FOO_SUPER_TABLE* ,然后解析器向管理节点(Management Node)请求其相应的元数据信息,并将过滤信息(TAG_LOC='beijing')同时发送到管理节点。 - -管理节点接收元数据获取的请求,首先找到超级表 *FOO_SUPER_TABLE* 基础信息,然后应用查询条件来过滤通过该超级表创建的全部表,最后满足查询条件(TAG_LOC='beijing'),即 *TAG_LOC* 标签列是 'beijing' 的的通过其查询执行器将满足查询要求的对象(表或超级表)的元数据信息返回给客户端。 - -客户端获得了 *FOO_SUPER_TABLE* 的元数据信息后,查询执行器根据元数据中的数据分布,分别向保存有相应数据的节点发起查询请求,此时时间戳范围过滤条件(TS >= '2019-01-12 00:00:00' AND TS < '2019-01-13 00:00:00')需要同时发送给全部的数据节点。 - -数据节点接收到发自客户端的查询,转化为内部结构并进行优化以后将其放入任务执行队列,等待查询执行器执行。当查询结果获得以后,将查询结果返回客户端。数据节点执行查询的过程均相互独立,完全只依赖于自身的数据和内容进行计算。 - -当所有查询涉及的数据节点返回结果后,客户端将每个数据节点查询的结果集再次进行聚合(针对本案例,即将所有结果再次进行累加),累加的结果即为最后的查询结果。第二阶段聚合并不是所有的查询都需要。例如,针对数据的列选取操作,实际上是不需要第二阶段聚合。 - -### REST查询处理 - -在 C/C++ 、Python接口、 JDBC 接口之外,TDengine 还提供基于 HTTP 协议的 REST 接口。不同于使用应用客户端开发程序进行的开发。当用户使用 REST 接口的时候,所有的查询处理过程都是在服务器端来完成,用户的应用服务不会参与数据库的计算过程,查询处理完成后结果通过 HTTP的 JSON 格式返回给用户。 - -
        -
        图 2. REST查询架构
        - -当用户使用基于HTTP的REST查询接口,HTTP的请求首先与位于数据节点的HTTP连接器( Connector),建立连接,然后通过REST的签名机制,使用Token来确保请求的可靠性。对于数据节点,HTTP连接器接收到请求后,调用内嵌的客户端程序发起查询请求,内嵌客户端将解析通过HTTP连接器传递过来的SQL语句,解析该SQL语句并按需向管理节点请求元数据信息,然后向本机或集群中其他节点发送查询请求,最后按需聚合计算结果。HTTP连接器接收到请求SQL以后,后续的流程处理与采用应用客户端方式的查询处理完全一致。最后,还需要将查询的结果转换为JSON格式字符串,并通过HTTP 响应返回给客户端。 - -可以看到,在处理HTTP流程的整个过程中,用户应用不再参与到查询处理的过程中,只负责通过HTTP协议发送SQL请求并接收JSON格式的结果。同时还需要注意的是,每个数据节点均内嵌了一个HTTP连接器和客户端程序,因此请求集群中任何一个数据节点,该数据节点均能够通过HTTP协议返回用户的查询结果。 - -### 技术特征 - -由于TDengine采用数据和标签分离存储的模式,能够极大地降低标签数据存储的冗余度。标签数据直接关联到每个表,并采用全内存的结构进行管理和维护标签数据,全内存的结构提供快速的查询处理,千万级别规模的标签数据查询可以在毫秒级别返回。首先针对标签数据的过滤可以有效地降低第二阶段的查询涉及的数据规模。为有效地提升查询处理的性能,针对物联网数据的不可更改的特点,TDengine采用在每个保存的数据块上,都记录下该数据块中数据的最大值、最小值、和等统计数据。如果查询处理涉及整个数据块的全部数据,则直接使用预计算结果,不再读取数据块的内容。由于预计算模块的大小远小于磁盘上存储的具体数据的大小,对于磁盘IO为瓶颈的查询处理,使用预计算结果可以极大地减小读取IO,并加速查询处理的流程。 - -由于TDengine采用按列存储数据。当从磁盘中读取数据块进行计算的时候,按照查询列信息读取该列数据,并不需要读取其他不相关的数据,可以最小化读取数据。此外,由于采用列存储结构,数据节点针对数据的扫描采用该列数据块进行,可以充分利用CPU L2高速缓存,极大地加速数据扫描的速度。此外,对于某些查询,并不会等全部查询结果生成后再返回结果。例如,列选取查询,当第一批查询结果获得以后,数据节点直接将其返回客户端。同时,在查询处理过程中,系统在数据节点接收到查询请求以后马上返回客户端查询确认信息,并同时拉起查询处理过程,并等待查询执行完成后才返回给用户查询有响应。 - -## 集群设计 - -### 1:集群与主要逻辑单元 - -TDengine是基于硬件、软件系统不可靠、一定会有故障的假设进行设计的,是基于任何单台计算机都无足够能力处理海量数据的假设进行设计的。因此TDengine从研发的第一天起,就按照分布式高可靠架构进行设计,是完全去中心化的,是水平扩展的,这样任何单台或多台服务器宕机或软件错误都不影响系统的服务。通过节点虚拟化并辅以自动化负载均衡技术,TDengine能最大限度地利用异构集群中的计算和存储资源。而且只要数据副本数大于一,无论是硬软件的升级、还是IDC的迁移等都无需停止集群的服务,极大地保证系统的正常运行,并且降低了系统管理员和运维人员的工作量。 - -下面的示例图上有八个物理节点,每个物理节点被逻辑的划分为多个虚拟节点。下面对系统的基本概念进行介绍。 - - - -![assets/nodes.png](../assets/nodes.png) - -**物理节点(dnode)**:集群中的一物理服务器或云平台上的一虚拟机。为安全以及通讯效率,一个物理节点可配置两张网卡,或两个IP地址。其中一张网卡用于集群内部通讯,其IP地址为**privateIp**, 另外一张网卡用于与集群外部应用的通讯,其IP地址为**publicIp**。在一些云平台(如阿里云),对外的IP地址是映射过来的,因此publicIp还有一个对应的内部IP地址**internalIp**(与privateIp不同)。对于只有一个IP地址的物理节点,publicIp, privateIp以及internalIp都是同一个地址,没有任何区别。一个dnode上有而且只有一个taosd实例运行。 - -**虚拟数据节点(vnode)**:在物理节点之上的可独立运行的基础逻辑单元,时序数据写入、存储、查询等操作逻辑都在虚拟节点中进行(图中V),采集的时序数据就存储在vnode上。一个vnode包含固定数量的表。当创建一张新表时,系统会检查是否需要创建新的vnode。一个物理节点上能创建的vnode的数量取决于物理节点的硬件资源。一个vnode只属于一个DB,但一个DB可以有多个vnode。 - -**虚拟数据节点组(vgroup)**: 位于不同物理节点的vnode可以组成一个虚拟数据节点组vnode group(如上图dnode0中的V0, dnode1中的V1, dnode6中的V2属于同一个虚拟节点组)。归属于同一个vgroup的虚拟节点采取master/slave的方式进行管理。写只能在master上进行,但采用asynchronous的方式将数据同步到slave,这样确保了一份数据在多个物理节点上有拷贝。如果master节点宕机,其他节点监测到后,将重新选举vgroup里的master, 新的master能继续处理数据请求,从而保证系统运行的可靠性。一个vgroup里虚拟节点个数就是数据的副本数。如果一个DB的副本数为N,系统必须有至少N个物理节点。副本数在创建DB时通过参数replica可以指定,缺省为1。使用TDengine, 数据的安全依靠多副本解决,因此不再需要昂贵的磁盘阵列等存储设备。 - -**虚拟管理节点(mnode)**:负责所有节点运行状态的监控和维护,以及节点之间的负载均衡(图中M)。同时,虚拟管理节点也负责元数据(包括用户、数据库、表、静态标签等)的存储和管理,因此也称为Meta Node。TDengine集群中可配置多个(最多不超过5个) mnode,它们自动构建成为一个管理节点集群(图中M0, M1, M2)。mnode间采用master/slave的机制进行管理,而且采取强一致方式进行数据同步。mnode集群的创建由系统自动完成,无需人工干预。每个dnode上至多有一个mnode,而且每个dnode都知道整个集群中所有mnode的IP地址。 - -**taosc**:一个软件模块,是TDengine给应用提供的驱动程序(driver),内嵌于JDBC、ODBC driver中,或者C语言连接库里。应用都是通过taosc而不是直接来与整个集群进行交互的。这个模块负责获取并缓存元数据;将插入、查询等请求转发到正确的虚拟节点;在把结果返回给应用时,还需要负责最后一级的聚合、排序、过滤等操作。对于JDBC, ODBC, C/C++接口而言,这个模块是在应用所处的计算机上运行,但消耗的资源很小。为支持全分布式的REST接口,taosc在TDengine集群的每个dnode上都有一运行实例。 - -**对外服务地址**:TDengine集群可以容纳单台、多台甚至几千台物理节点。应用只需要向集群中任何一个物理节点的publicIp发起连接即可。启动CLI应用taos时,选项-h需要提供的就是publicIp。 - -**master/secondIp**:每一个dnode都需要配置一个masterIp。dnode启动后,将对配置的masterIp发起加入集群的连接请求。masterIp是已经创建的集群中的任何一个节点的privateIp,对于集群中的第一个节点,就是它自己的privateIp。为保证连接成功,每个dnode还可配置secondIp, 该IP地址也是已创建的集群中的任何一个节点的privateIp。如果一个节点连接masterIp失败,它将试图链接secondIp。 - -dnode启动后,会获知集群的mnode IP列表,并且定时向mnode发送状态信息。 - -vnode与mnode只是逻辑上的划分,都是执行程序taosd里的不同线程而已,无需安装不同的软件,做任何特殊的配置。最小的系统配置就是一个物理节点,vnode,mnode和taosc都存在而且都正常运行,但单一节点无法保证系统的高可靠。 - -### 2:一典型的操作流程 - -为解释vnode, mnode, taosc和应用之间的关系以及各自扮演的角色,下面对写入数据这个典型操作的流程进行剖析。 - - - -![Picture1](../assets/Picture2.png) - - - -1. 应用通过JDBC、ODBC或其他API接口发起插入数据的请求。 -2. taosc会检查缓存,看是有保存有该表的meta data。如果有,直接到第4步。如果没有,taosc将向mnode发出get meta-data请求。 -3. mnode将该表的meta-data返回给taosc。Meta-data包含有该表的schema, 而且还有该表所属的vgroup信息(vnode ID以及所在的dnode的IP地址,如果副本数为N,就有N组vnodeID/IP)。如果taosc迟迟得不到mnode回应,而且存在多个mnode,taosc将向下一个mnode发出请求。 -4. taosc向master vnode发起插入请求。 -5. vnode插入数据后,给taosc一个应答,表示插入成功。如果taosc迟迟得不到vnode的回应,taosc会认为该节点已经离线。这种情况下,如果被插入的数据库有多个副本,taosc将向vgroup里下一个vnode发出插入请求。 -6. taosc通知APP,写入成功。 - -对于第二和第三步,taosc启动时,并不知道mnode的IP地址,因此会直接向配置的集群对外服务的IP地址发起请求。如果接收到该请求的dnode并没有配置mnode,该dnode会在回复的消息中告知mnode的IP地址列表(如果有多个dnodes,mnode的IP地址可以有多个),这样taosc会重新向新的mnode的IP地址发出获取meta-data的请求。 - -对于第四和第五步,没有缓存的情况下,taosc无法知道虚拟节点组里谁是master,就假设第一个vnodeID/IP就是master,向它发出请求。如果接收到请求的vnode并不是master,它会在回复中告知谁是master,这样taosc就向建议的master vnode发出请求。一旦得到插入成功的回复,taosc会缓存住master节点的信息。 - -上述是插入数据的流程,查询、计算的流程也完全一致。taosc把这些复杂的流程全部封装屏蔽了,因此应用无需处理重定向、获取meta data等细节,完全是透明的。 - -通过taosc缓存机制,只有在第一次对一张表操作时,才需要访问mnode, 因此mnode不会成为系统瓶颈。但因为schema有可能变化,而且vgroup有可能发生改变(比如负载均衡发生),因此taosc需要定时自动刷新缓存。 - -### 3:数据分区 - -vnode(虚拟数据节点)保存采集的时序数据,而且查询、计算都在这些节点上进行。为便于负载均衡、数据恢复、支持异构环境,TDengine将一个物理节点根据其计算和存储资源切分为多个vnode。这些vnode的管理是TDengine自动完成的,对应用完全透明。 - -对于单独一个数据采集点,无论其数据量多大,一个vnode(或vnode group, 如果副本数大于1)有足够的计算资源和存储资源来处理(如果每秒生成一条16字节的记录,一年产生的原始数据不到0.5G),因此TDengine将一张表的所有数据都存放在一个vnode里,而不会让同一个采集点的数据分布到两个或多个dnode上。而且一个vnode可存储多张表的数据,一个vnode可容纳的表的数目由配置参数tables指定,缺省为2000。设计上,一个vnode里所有的表都属于同一个DB。因此一个数据库DB需要的vnode或vgroup的个数等于:数据库表的数目/tables。 - -创建DB时,系统并不会马上分配资源。但当创建一张表时,系统将看是否有已经分配的vnode, 而且是否有空位,如果有,立即在该有空位的vnode创建表。如果没有,系统将从集群中,根据当前的负载情况,在一个dnode上创建一新的vnode, 然后创建表。如果DB有多个副本,系统不是只创建一个vnode,而是一个vgroup(虚拟数据节点组)。系统对vnode的数目没有任何限制,仅仅受限于物理节点本身的计算和存储资源。 - -参数tables的设置需要考虑具体场景,创建DB时,可以个性化指定该参数。该参数不宜过大,也不宜过小。过小,极端情况,就是每个数据采集点一个vnode, 这样导致系统数据文件过多。过大,虚拟化带来的优势就会丧失。给定集群计算资源的情况下,整个系统vnode的个数应该是CPU核的数目的两倍以上。 - -### 4:负载均衡 - -每个dnode(物理节点)都定时向 mnode(虚拟管理节点)报告其状态(包括硬盘空间、内存大小、CPU、网络、虚拟节点个数等),因此mnode了解整个集群的状态。基于整体状态,当mnode发现某个dnode负载过重,它会将dnode上的一个或多个vnode挪到其他dnode。在挪动过程中,对外服务继续进行,数据插入、查询和计算操作都不受影响。负载均衡操作结束后,应用也无需重启,将自动连接新的vnode。 - -如果mnode一段时间没有收到dnode的状态报告,mnode会认为这个dnode已经离线。如果离线时间超过一定时长(时长由配置参数offlineThreshold决定),该dnode将被mnode强制剔除出集群。该dnode上的vnodes如果副本数大于一,系统将自动在其他dnode上创建新的副本,以保证数据的副本数。 - - - -**Note:**目前集群功能仅仅限于企业版 diff --git a/2.0/documentation/webdocs/markdowndocs/More on System Architecture.md b/2.0/documentation/webdocs/markdowndocs/More on System Architecture.md deleted file mode 100644 index d7a38b99a3..0000000000 --- a/2.0/documentation/webdocs/markdowndocs/More on System Architecture.md +++ /dev/null @@ -1,176 +0,0 @@ -# TDengine System Architecture - -## Storage Design - -TDengine data mainly include **metadata** and **data** that we will introduce in the following sections. - -### Metadata Storage - -Metadata include the information of databases, tables, etc. Metadata files are saved in _/var/lib/taos/mgmt/_ directory by default. The directory tree is as below: -``` -/var/lib/taos/ - +--mgmt/ - +--db.db - +--meters.db - +--user.db - +--vgroups.db -``` - -A metadata structure (database, table, etc.) is saved as a record in a metadata file. All metadata files are appended only, and even a drop operation adds a deletion record at the end of the file. - -### Data storage - -Data in TDengine are sharded according to the time range. Data of tables in the same vnode in a certain time range are saved in the same filegroup, such as files v0f1804*. This sharding strategy can effectively improve data searching speed. By default, a group of files contains data in 10 days, which can be configured by *daysPerFile* in the configuration file or by *DAYS* keyword in *CREATE DATABASE* clause. Data in files are blockwised. A data block only contains one table's data. Records in the same data block are sorted according to the primary timestamp, which helps to improve the compression rate and save storage. The compression algorithms used in TDengine include simple8B, delta-of-delta, RLE, LZ4, etc. - -By default, TDengine data are saved in */var/lib/taos/data/* directory. _/var/lib/taos/tsdb/_ directory contains vnode informations and data file linkes. - -``` -/var/lib/taos/ - +--tsdb/ - | +--vnode0 - | +--meterObj.v0 - | +--db/ - | +--v0f1804.head->/var/lib/taos/data/vnode0/v0f1804.head1 - | +--v0f1804.data->/var/lib/taos/data/vnode0/v0f1804.data - | +--v0f1804.last->/var/lib/taos/data/vnode0/v0f1804.last1 - | +--v0f1805.head->/var/lib/taos/data/vnode0/v0f1805.head1 - | +--v0f1805.data->/var/lib/taos/data/vnode0/v0f1805.data - | +--v0f1805.last->/var/lib/taos/data/vnode0/v0f1805.last1 - | : - +--data/ - +--vnode0/ - +--v0f1804.head1 - +--v0f1804.data - +--v0f1804.last1 - +--v0f1805.head1 - +--v0f1805.data - +--v0f1805.last1 - : -``` - -#### meterObj file -There are only one meterObj file in a vnode. Informations bout the vnode, such as created time, configuration information, vnode statistic informations are saved in this file. It has the structure like below: - -``` - -[file_header] -[table_record1_offset&length] -[table_record2_offset&length] -... -[table_recordN_offset&length] -[table_record1] -[table_record2] -... -[table_recordN] - -``` -The file header takes 512 bytes, which mainly contains informations about the vnode. Each table record is the representation of a table on disk. - -#### head file -The _head_ files contain the index of data blocks in the _data_ file. The inner organization is as below: -``` - -[file_header] -[table1_offset] -[table2_offset] -... -[tableN_offset] -[table1_index_block] -[table2_index_block] -... -[tableN_index_block] - -``` -The table offset array in the _head_ file saves the information about the offsets of each table index block. Indices on data blocks in the same table are saved continuously. This also makes it efficient to load data indices on the same table. The data index block has a structure like: - -``` -[index_block_info] -[block1_index] -[block2_index] -... -[blockN_index] -``` -The index block info part contains the information about the index block such as the number of index blocks, etc. Each block index corresponds to a real data block in the _data_ file or _last_ file. Information about the location of the real data block, the primary timestamp range of the data block, etc. are all saved in the block index part. The block indices are sorted in ascending order according to the primary timestamp. So we can apply algorithms such as the binary search on the data to efficiently search blocks according to time. - -#### data file -The _data_ files store the real data block. They are append-only. The organization is as: -``` - -[file_header] -[block1] -[block2] -... -[blockN] - -``` -A data block in _data_ files only belongs to a table in the vnode and the records in a data block are sorted in ascending order according to the primary timestamp key. Data blocks are column-oriented. Data in the same column are stored contiguously, which improves reading speed and compression rate because of their similarity. A data block has the following organization: - -``` -[column1_info] -[column2_info] -... -[columnN_info] -[column1_data] -[column2_data] -... -[columnN_data] -``` -The column info part includes information about column types, column compression algorithm, column data offset and length in the _data_ file, etc. Besides, pre-calculated results of the column data in the block are also in the column info part, which helps to improve reading speed by avoiding loading data block necessarily. - -#### last file -To avoid storage fragment and to import query speed and compression rate, TDengine introduces an extra file, the _last_ file. When the number of records in a data block is lower than a threshold, TDengine will flush the block to the _last_ file for temporary storage. When new data comes, the data in the _last_ file will be merged with the new data and form a larger data block and written to the _data_ file. The organization of the _last_ file is similar to the _data_ file. - -### Summary -The innovation in architecture and storage design of TDengine improves resource usage. On the one hand, the virtualization makes it easy to distribute resources between different vnodes and for future scaling. On the other hand, sorted and column-oriented storage makes TDengine have a great advantage in writing, querying and compression. - -## Query Design - -#### Introduction - -TDengine provides a variety of query functions for both tables and super tables. In addition to regular aggregate queries, it also provides time window based query and statistical aggregation for time series data. TDengine's query processing requires the client app, management node, and data node to work together. The functions and modules involved in query processing included in each component are as follows: - -Client (Client App). The client development kit, embed in a client application, consists of TAOS SQL parser and query executor, the second-stage aggregator (Result Merger), continuous query manager and other major functional modules. The SQL parser is responsible for parsing and verifying the SQL statement and converting it into an abstract syntax tree. The query executor is responsible for transforming the abstract syntax tree into the query execution logic and creates the metadata query according to the query condition of the SQL statement. Since TAOS SQL does not currently include complex nested queries and pipeline query processing mechanism, there is no longer need for query plan optimization and physical query plan conversions. The second-stage aggregator is responsible for performing the aggregation of the independent results returned by query involved data nodes at the client side to generate final results. The continuous query manager is dedicated to managing the continuous queries created by users, including issuing fixed-interval query requests and writing the results back to TDengine or returning to the client application as needed. Also, the client is also responsible for retrying after the query fails, canceling the query request, and maintaining the connection heartbeat and reporting the query status to the management node. - -Management Node. The management node keeps the metadata of all the data of the entire cluster system, provides the metadata of the data required for the query from the client node, and divides the query request according to the load condition of the cluster. The super table contains information about all the tables created according to the super table, so the query processor (Query Executor) of the management node is responsible for the query processing of the tags of tables and returns the table information satisfying the tag query. Besides, the management node maintains the query status of the cluster in the Query Status Manager component, in which the metadata of all queries that are currently executing are temporarily stored in-memory buffer. When the client issues *show queries* command to management node, current running queries information is returned to the client. - -Data Node. The data node, responsible for storing all data of the database, consists of query executor, query processing scheduler, query task queue, and other related components. Once the query requests from the client received, they are put into query task queue and waiting to be processed by query executor. The query executor extracts the query request from the query task queue and invokes the query optimizer to perform the basic optimization for the query execution plan. And then query executor scans the qualified data blocks in both cache and disk to obtain qualified data and return the calculated results. Besides, the data node also needs to respond to management information and commands from the management node. For example, after the *kill query* received from the management node, the query task needs to be stopped immediately. - -
        -
        Fig 1. System query processing architecture diagram (only query related components)
        - -#### Query Process Design - -The client, the management node, and the data node cooperate to complete the entire query processing of TDengine. Let's take a concrete SQL query as an example to illustrate the whole query processing flow. The SQL statement is to query on super table *FOO_SUPER_TABLE* to get the total number of records generated on January 12, 2019, from the table, of which TAG_LOC equals to 'beijing'. The SQL statement is as follows: - -```sql -SELECT COUNT(*) -FROM FOO_SUPER_TABLE -WHERE TAG_LOC = 'beijing' AND TS >= '2019-01-12 00:00:00' AND TS < '2019-01-13 00:00:00' -``` - -First, the client invokes the TAOS SQL parser to parse and validate the SQL statement, then generates a syntax tree, and extracts the object of the query - the super table *FOO_SUPER_TABLE*, and then the parser sends requests with filtering information (TAG_LOC='beijing') to management node to get the corresponding metadata about *FOO_SUPER_TABLE*. - -Once the management node receives the request for metadata acquisition, first finds the super table *FOO_SUPER_TABLE* basic information, and then applies the query condition (TAG_LOC='beijing') to filter all the related tables created according to it. And finally, the query executor returns the metadata information that satisfies the query request to the client. - -After the client obtains the metadata information of *FOO_SUPER_TABLE*, the query executor initiates a query request with timestamp range filtering condition (TS >= '2019- 01-12 00:00:00' AND TS < '2019-01-13 00:00:00') to all nodes that hold the corresponding data according to the information about data distribution in metadata. - -The data node receives the query sent from the client, converts it into an internal structure and puts it into the query task queue to be executed by query executor after optimizing the execution plan. When the query result is obtained, the query result is returned to the client. It should be noted that the data nodes perform the query process independently of each other, and rely solely on their data and content for processing. - -When all data nodes involved in the query return results, the client aggregates the result sets from each data node. In this case, all results are accumulated to generate the final query result. The second stage of aggregation is not always required for all queries. For example, a column selection query does not require a second-stage aggregation at all. - -#### REST Query Process - -In addition to C/C++, Python, and JDBC interface, TDengine also provides a REST interface based on the HTTP protocol, which is different from using the client application programming interface. When the user uses the REST interface, all the query processing is completed on the server-side, and the user's application is not involved in query processing anymore. After the query processing is completed, the result is returned to the client through the HTTP JSON string. - -
        -
        Fig. 2 REST query architecture
        - -When a client uses an HTTP-based REST query interface, the client first establishes a connection with the HTTP connector at the data node and then uses the token to ensure the reliability of the request through the REST signature mechanism. For the data node, after receiving the request, the HTTP connector invokes the embedded client program to initiate a query processing, and then the embedded client parses the SQL statement from the HTTP connector and requests the management node to get metadata as needed. After that, the embedded client sends query requests to the same data node or other nodes in the cluster and aggregates the calculation results on demand. Finally, you also need to convert the result of the query into a JSON format string and return it to the client via an HTTP response. After the HTTP connector receives the request SQL, the subsequent process processing is completely consistent with the query processing using the client application development kit. - -It should be noted that during the entire processing, the client application is no longer involved in, and is only responsible for sending SQL requests through the HTTP protocol and receiving the results in JSON format. Besides, each data node is embedded with an HTTP connector and a client, so any data node in the cluster received requests from a client, the data node can initiate the query and return the result to the client through the HTTP protocol, with transfer the request to other data nodes. - -#### Technology - -Because TDengine stores data and tags value separately, the tag value is kept in the management node and directly associated with each table instead of records, resulting in a great reduction of the data storage. Therefore, the tag value can be managed by a fully in-memory structure. First, the filtering of the tag data can drastically reduce the data size involved in the second phase of the query. The query processing for the data is performed at the data node. TDengine takes advantage of the immutable characteristics of IoT data by calculating the maximum, minimum, and other statistics of the data in one data block on each saved data block, to effectively improve the performance of query processing. If the query process involves all the data of the entire data block, the pre-computed result is used directly, and the content of the data block is no longer needed. Since the size of disk space required to store the pre-computation result is much smaller than the size of the specific data, the pre-computation result can greatly reduce the disk IO and speed up the query processing. - -TDengine employs column-oriented data storage techniques. When the data block is involved to be loaded from the disk for calculation, only the required column is read according to the query condition, and the read overhead can be minimized. The data of one column is stored in a contiguous memory block and therefore can make full use of the CPU L2 cache to greatly speed up the data scanning. Besides, TDengine utilizes the eagerly responding mechanism and returns a partial result before the complete result is acquired. For example, when the first batch of results is obtained, the data node immediately returns it directly to the client in case of a column select query. \ No newline at end of file diff --git a/2.0/documentation/webdocs/markdowndocs/Super Table-ch.md b/2.0/documentation/webdocs/markdowndocs/Super Table-ch.md deleted file mode 100644 index f45f2f91b1..0000000000 --- a/2.0/documentation/webdocs/markdowndocs/Super Table-ch.md +++ /dev/null @@ -1,225 +0,0 @@ -# 超级表STable:多表聚合 - -TDengine要求每个数据采集点单独建表。独立建表的模式能够避免写入过程中的同步加锁,因此能够极大地提升数据的插入/查询性能。但是独立建表意味着系统中表的数量与采集点的数量在同一个量级。如果采集点众多,将导致系统中表的数量也非常庞大,让应用对表的维护以及聚合、统计操作难度加大。为降低应用的开发难度,TDengine引入了超级表(Super Table, 简称为STable)的概念。 - -## 什么是超级表 - -超级表是同一类型数据采集点的抽象,是同类型采集实例的集合,包含多张数据结构一样的子表。每个STable为其子表定义了表结构和一组标签:表结构即表中记录的数据列及其数据类型;标签名和数据类型由STable定义,标签值记录着每个子表的静态信息,用以对子表进行分组过滤。子表本质上就是普通的表,由一个时间戳主键和若干个数据列组成,每行记录着具体的数据,数据查询操作与普通表完全相同;但子表与普通表的区别在于每个子表从属于一张超级表,并带有一组由STable定义的标签值。每种类型的采集设备可以定义一个STable。数据模型定义表的每列数据的类型,如温度、压力、电压、电流、GPS实时位置等,而标签信息属于Meta Data,如采集设备的序列号、型号、位置等,是静态的,是表的元数据。用户在创建表(数据采集点)时指定STable(采集类型)外,还可以指定标签的值,也可事后增加或修改。 - -TDengine扩展标准SQL语法用于定义STable,使用关键词tags指定标签信息。语法如下: - -```mysql -CREATE TABLE ( TIMESTAMP, field_name1 field_type,…) TAGS(tag_name tag_type, …) -``` - -其中tag_name是标签名,tag_type是标签的数据类型。标签可以使用时间戳之外的其他TDengine支持的数据类型,标签的个数最多为32个,名字不能与系统关键词相同,也不能与其他列名相同。如: - -```mysql -CREATE TABLE thermometer (ts timestamp, degree float) -TAGS (location binary(20), type int) -``` - -上述SQL创建了一个名为thermometer的STable,带有标签location和标签type。 - -为某个采集点创建表时,可以指定其所属的STable以及标签的值,语法如下: - -```mysql -CREATE TABLE USING TAGS (tag_value1,...) -``` - -沿用上面温度计的例子,使用超级表thermometer建立单个温度计数据表的语句如下: - -```mysql -CREATE TABLE t1 USING thermometer TAGS ('beijing', 10) -``` - -上述SQL以thermometer为模板,创建了名为t1的表,这张表的Schema就是thermometer的Schema,但标签location值为'beijing',标签type值为10。 - -用户可以使用一个STable创建数量无上限的具有不同标签的表,从这个意义上理解,STable就是若干具有相同数据模型,不同标签的表的集合。与普通表一样,用户可以创建、删除、查看超级表STable,大部分适用于普通表的查询操作都可运用到STable上,包括各种聚合和投影选择函数。除此之外,可以设置标签的过滤条件,仅对STbale中部分表进行聚合查询,大大简化应用的开发。 - -TDengine对表的主键(时间戳)建立索引,暂时不提供针对数据模型中其他采集量(比如温度、压力值)的索引。每个数据采集点会采集若干数据记录,但每个采集点的标签仅仅是一条记录,因此数据标签在存储上没有冗余,且整体数据规模有限。TDengine将标签数据与采集的动态数据完全分离存储,而且针对STable的标签建立了高性能内存索引结构,为标签提供全方位的快速操作支持。用户可按照需求对其进行增删改查(Create,Retrieve,Update,Delete,CRUD)操作。 - -STable从属于库,一个STable只属于一个库,但一个库可以有一到多个STable, 一个STable可有多个子表。 - -## 超级表管理 - -- 创建超级表 - - ```mysql - CREATE TABLE ( TIMESTAMP, field_name1 field_type,…) TAGS(tag_name tag_type, …) - ``` - - 与创建表的SQL语法相似。但需指定TAGS字段的名称和类型。 - - 说明: - - 1. TAGS列总长度不能超过16k bytes; - 2. TAGS列的数据类型不能是timestamp; - 3. TAGS列名不能与其他列名相同; - 4. TAGS列名不能为预留关键字. - 5. TAGS总数的上限是128. - -- 显示已创建的超级表 - - ```mysql - show stables; - ``` - - 查看数据库内全部STable,及其相关信息,包括STable的名称、创建时间、列数量、标签(TAG)数量、通过该STable建表的数量。 - -- 删除超级表 - - ```mysql - DROP TABLE - ``` - - Note: 删除STable时,所有通过该STable创建的表都将被删除。 - -- 查看属于某STable并满足查询条件的表 - - ```mysql - SELECT TBNAME,[TAG_NAME,…] FROM WHERE <[=|<=|>=|<>] values..> ([AND|OR] …) - ``` - - 查看属于某STable并满足查询条件的表。说明:TBNAME为关键词,显示通过STable建立的子表表名,查询过程中可以使用针对标签的条件。 - - ```mysql - SELECT COUNT(TBNAME) FROM WHERE <[=|<=|>=|<>] values..> ([AND|OR] …) - ``` - - 统计属于某个STable并满足查询条件的子表的数量 - -## 写数据时自动建子表 - -在某些特殊场景中,用户在写数据时并不确定某个设备的表是否存在,此时可使用自动建表语法来实现写入数据时里用超级表定义的表结构自动创建不存在的子表,若该表已存在则不会建立新表。注意:自动建表语句只能自动建立子表而不能建立超级表,这就要求超级表已经被事先定义好。自动建表语法跟insert/import语法非常相似,唯一区别是语句中增加了超级表和标签信息。具体语法如下: - -```mysql -INSERT INTO USING TAGS (, ...) VALUES (field_value, ...) (field_value, ...) ...; -``` - -向表tb_name中插入一条或多条记录,如果tb_name这张表不存在,则会用超级表stb_name定义的表结构以及用户指定的标签值(即tag1_value…)来创建名为tb_name新表,并将用户指定的值写入表中。如果tb_name已经存在,则建表过程会被忽略,系统也不会检查tb_name的标签是否与用户指定的标签值一致,也即不会更新已存在表的标签。 - -```mysql -INSERT INTO USING TAGS (, ...) VALUES (, ...) (, ...) ... USING TAGS(, ...) VALUES (, ...) ...; -``` - -向多张表tb1_name,tb2_name等插入一条或多条记录,并分别指定各自的超级表进行自动建表。 - -## STable中TAG管理 - -除了更新标签的值的操作是针对子表进行,其他所有的标签操作(添加标签、删除标签等)均只能作用于STable,不能对单个子表操作。对STable添加标签以后,依托于该STable建立的所有表将自动增加了一个标签,对于数值型的标签,新增加的标签的默认值是0. - -- 添加新的标签 - - ```mysql - ALTER TABLE ADD TAG - ``` - - 为STable增加一个新的标签,并指定新标签的类型。标签总数不能超过128个。 - -- 删除标签 - - ```mysql - ALTER TABLE DROP TAG - ``` - - 删除超级表的一个标签,从超级表删除某个标签后,该超级表下的所有子表也会自动删除该标签。 - - 说明:第一列标签不能删除,至少需要为STable保留一个标签。 - -- 修改标签名 - - ```mysql - ALTER TABLE CHANGE TAG - ``` - - 修改超级表的标签名,从超级表修改某个标签名后,该超级表下的所有子表也会自动更新该标签名。 - -- 修改子表的标签值 - - ```mysql - ALTER TABLE SET TAG = - ``` - -## STable多表聚合 - -针对所有的通过STable创建的子表进行多表聚合查询,支持按照全部的TAG值进行条件过滤,并可将结果按照TAGS中的值进行聚合,暂不支持针对binary类型的模糊匹配过滤。语法如下: - -```mysql -SELECT function,… - FROM - WHERE <[=|<=|>=|<>] values..> ([AND|OR] …) - INTERVAL (
      Back

      Connect with other tools

      -

      Telegraf

      -

      TDengine is easy to integrate with Telegraf, an open-source server agent for collecting and sending metrics and events, without more development.

      -

      Install Telegraf

      -

      At present, TDengine supports Telegraf newer than version 1.7.4. Users can go to the download link and choose the proper package to install on your system.

      -

      Configure Telegraf

      -

      Telegraf is configured by changing items in the configuration file /etc/telegraf/telegraf.conf.

      -

      In output plugins section,add [[outputs.http]] iterm:

      -
        -
      • url: http://ip:6020/telegraf/udb, in which ip is the IP address of any node in TDengine cluster. Port 6020 is the RESTful APT port used by TDengine. udb is the name of the database to save data, which needs to create beforehand.
      • -
      • method: "POST"
      • -
      • username: username to login TDengine
      • -
      • password: password to login TDengine
      • -
      • data_format: "json"
      • -
      • json_timestamp_units: "1ms"
      • -
      -

      In agent part:

      -
        -
      • hostname: used to distinguish different machines. Need to be unique.
      • -
      • metric_batch_size: 30,the maximum number of records allowed to write in Telegraf. The larger the value is, the less frequent requests are sent. For TDengine, the value should be less than 50.
      • -
      -

      Please refer to the Telegraf docs for more information.

      -

      Grafana

      -

      Grafana is an open-source system for time-series data display. It is easy to integrate TDengine and Grafana to build a monitor system. Data saved in TDengine can be fetched and shown on the Grafana dashboard.

      -

      Install Grafana

      -

      For now, TDengine only supports Grafana newer than version 5.2.4. Users can go to the Grafana download page for the proper package to download.

      -

      Configure Grafana

      -

      TDengine Grafana plugin is in the /usr/local/taos/connector/grafana directory. -Taking Centos 7.2 as an example, just copy TDengine directory to /var/lib/grafana/plugins directory and restart Grafana.

      -

      Use Grafana

      -

      Users can log in the Grafana server (username/password:admin/admin) through localhost:3000 to configure TDengine as the data source. As is shown in the picture below, TDengine as a data source option is shown in the box:

      -

      img

      -

      When choosing TDengine as the data source, the Host in HTTP configuration should be configured as the IP address of any node of a TDengine cluster. The port should be set as 6020. For example, when TDengine and Grafana are on the same machine, it should be configured as _http://localhost:6020.

      -

      Besides, users also should set the username and password used to log into TDengine. Then click Save&Test button to save.

      -

      img

      -

      Then, TDengine as a data source should show in the Grafana data source list.

      -

      img

      -

      Then, users can create Dashboards in Grafana using TDengine as the data source:

      -

      img

      -

      Click Add Query button to add a query and input the SQL command you want to run in the INPUT SQL text box. The SQL command should expect a two-row, multi-column result, such as SELECT count(*) FROM sys.cpu WHERE ts>=from and ts<​to interval(interval), in which, from, to and inteval are TDengine inner variables representing query time range and time interval.

      -

      ALIAS BY field is to set the query alias. Click GENERATE SQL to send the command to TDengine:

      -

      img

      -

      Please refer to the Grafana official document for more information about Grafana.

      -

      Matlab

      -

      Matlab can connect to and retrieve data from TDengine by TDengine JDBC Driver.

      -

      MatLab and TDengine JDBC adaptation

      -

      Several steps are required to adapt Matlab to TDengine. Taking adapting Matlab2017a on Windows10 as an example:

      -
        -
      1. Copy the file JDBCDriver-1.0.0-dist.jar in TDengine package to the directory ${matlab_root}\MATLAB\R2017a\java\jar\toolbox
      2. -
      3. Copy the file taos.lib in TDengine package to ${matlab root dir}\MATLAB\R2017a\lib\win64
      4. -
      5. Add the .jar package just copied to the Matlab classpath. Append the line below as the end of the file of ${matlab root dir}\MATLAB\R2017a\toolbox\local\classpath.txt
      6. -
      -

      $matlabroot/java/jar/toolbox/JDBCDriver-1.0.0-dist.jar

      -
        -
      1. Create a file called javalibrarypath.txt in directory ${user_home}\AppData\Roaming\MathWorks\MATLAB\R2017a_, and add the _taos.dll path in the file. For example, if the file taos.dll is in the directory of C:\Windows\System32,then add the following line in file javalibrarypath.txt:
      2. -
      -

      C:\Windows\System32

      -

      TDengine operations in Matlab

      -

      After correct configuration, open Matlab:

      -
        -
      • build a connection:

        -

        conn = database(‘db’, ‘root’, ‘taosdata’, ‘com.taosdata.jdbc.TSDBDriver’, ‘jdbc:TSDB://127.0.0.1:0/’)

      • -
      • Query:

        -

        sql0 = [‘select * from tb’]

        -

        data = select(conn, sql0);

      • -
      • Insert a record:

        -

        sql1 = [‘insert into tb values (now, 1)’]

        -

        exec(conn, sql1)

      • -
      -

      Please refer to the file examples\Matlab\TDengineDemo.m for more information.

      -

      R

      -

      Users can use R language to access the TDengine server with the JDBC interface. At first, install JDBC package in R:

      -
      install.packages('rJDBC', repos='http://cran.us.r-project.org')
      -

      Then use library function to load the package:

      -
      library('RJDBC')
      -

      Then load the TDengine JDBC driver:

      -
      drv<-JDBC("com.taosdata.jdbc.TSDBDriver","JDBCDriver-1.0.0-dist.jar", identifier.quote="\"")
      -

      If succeed, no error message will display. Then use the following command to try a database connection:

      -
      conn<-dbConnect(drv,"jdbc:TSDB://192.168.0.1:0/?user=root&password=taosdata","root","taosdata")
      -

      Please replace the IP address in the command above to the correct one. If no error message is shown, then the connection is established successfully. TDengine supports below functions in RJDBC package:

      -
        -
      • dbWriteTable(conn, "test", iris, overwrite=FALSE, append=TRUE): write the data in a data frame iris to the table test in the TDengine server. Parameter overwrite must be false. append must be TRUE and the schema of the data frame iris should be the same as the table test.
      • -
      • dbGetQuery(conn, "select count(*) from test"): run a query command
      • -
      • dbSendUpdate(conn, "use db"): run any non-query command.
      • -
      • dbReadTable(conn, "test"): read all the data in table test
      • -
      • dbDisconnect(conn): close a connection
      • -
      • dbRemoveTable(conn, "test"): remove table test
      • -
      -

      Below functions are not supported currently:

      -
        -
      • dbExistsTable(conn, "test"): if talbe test exists
      • -
      • dbListTables(conn): list all tables in the connection
      • -
      Back
    回去

    与其他工具的连接

    -

    Telegraf

    -

    TDengine能够与开源数据采集系统Telegraf快速集成,整个过程无需任何代码开发。

    -

    安装Telegraf

    -

    目前TDengine支持Telegraf 1.7.4以上的版本。用户可以根据当前的操作系统,到Telegraf官网下载安装包,并执行安装。下载地址如下:https://portal.influxdata.com/downloads

    -

    配置Telegraf

    -

    修改Telegraf配置文件/etc/telegraf/telegraf.conf中与TDengine有关的配置项。

    -

    在output plugins部分,增加[[outputs.http]]配置项:

    -
      -
    • url:http://ip:6020/telegraf/udb,其中ip为TDengine集群的中任意一台服务器的IP地址,6020为TDengine RESTful接口的端口号,telegraf为固定关键字,udb为用于存储采集数据的数据库名称,可预先创建。
    • -
    • method: "POST"
    • -
    • username: 登录TDengine的用户名
    • -
    • password: 登录TDengine的密码
    • -
    • data_format: "json"
    • -
    • json_timestamp_units: "1ms"
    • -
    -

    在agent部分:

    -
      -
    • hostname: 区分不同采集设备的机器名称,需确保其唯一性
    • -
    • metric_batch_size: 30,允许Telegraf每批次写入记录最大数量,增大其数量可以降低Telegraf的请求发送频率,但对于TDengine,该数值不能超过50
    • -
    -

    关于如何使用Telegraf采集数据以及更多有关使用Telegraf的信息,请参考Telegraf官方的文档

    -

    Grafana

    -

    TDengine能够与开源数据可视化系统Grafana快速集成搭建数据监测报警系统,整个过程无需任何代码开发,TDengine中数据表中内容可以在仪表盘(DashBoard)上进行可视化展现。

    -

    安装Grafana

    -

    目前TDengine支持Grafana 5.2.4以上的版本。用户可以根据当前的操作系统,到Grafana官网下载安装包,并执行安装。下载地址如下:https://grafana.com/grafana/download

    -

    配置Grafana

    -

    TDengine的Grafana插件在安装包的/usr/local/taos/connector/grafana目录下。

    -

    以CentOS 7.2操作系统为例,将tdengine目录拷贝到/var/lib/grafana/plugins目录下,重新启动grafana即可。

    -

    使用Grafana

    -

    用户可以直接通过localhost:3000的网址,登录Grafana服务器(用户名/密码:admin/admin),配置TDengine数据源,如下图所示,此时可以在下拉列表中看到TDengine数据源。

    -

    img

    -

    TDengine数据源中的HTTP配置里面的Host地址要设置为TDengine集群的中任意一台服务器的IP地址与TDengine RESTful接口的端口号(6020)。假设TDengine数据库与Grafana部署在同一机器,那么应输入:http://localhost:6020。

    -

    此外,还需配置登录TDengine的用户名与密码,然后点击下图中的Save&Test按钮保存。

    -

    img

    -

    然后,就可以在Grafana的数据源列表中看到刚创建好的TDengine的数据源:

    -

    img

    -

    基于上面的步骤,就可以在创建Dashboard的时候使用TDengine数据源,如下图所示:

    -

    img

    -

    然后,可以点击Add Query按钮增加一个新查询。

    -

    在INPUT SQL输入框中输入查询SQL语句,该SQL语句的结果集应为两行多列的曲线数据,例如SELECT count(*) FROM sys.cpu WHERE ts>=from and ts<​to interval(interval)。其中,from、to和interval为TDengine插件的内置变量,表示从Grafana插件面板获取的查询范围和时间间隔。

    -

    ALIAS BY输入框为查询的别名,点击GENERATE SQL 按钮可以获取发送给TDengine的SQL语句。如下图所示:

    -

    img

    -

    关于如何使用Grafana创建相应的监测界面以及更多有关使用Grafana的信息,请参考Grafana官方的文档

    -

    Matlab

    -

    MatLab可以通过安装包内提供的JDBC Driver直接连接到TDengine获取数据到本地工作空间。

    -

    MatLab的JDBC接口适配

    -

    MatLab的适配有下面几个步骤,下面以Windows10上适配MatLab2017a为例:

    -
      -
    • 将TDengine安装包内的驱动程序JDBCDriver-1.0.0-dist.jar拷贝到${matlab_root}\MATLAB\R2017a\java\jar\toolbox
    • -
    • 将TDengine安装包内的taos.lib文件拷贝至${matlab_ root _dir}\MATLAB\R2017a\lib\win64
    • -
    • 将新添加的驱动jar包加入MatLab的classpath。在${matlab_ root _dir}\MATLAB\R2017a\toolbox\local\classpath.txt文件中添加下面一行
    • -
    -

    $matlabroot/java/jar/toolbox/JDBCDriver-1.0.0-dist.jar

    -
      -
    • 在${user_home}\AppData\Roaming\MathWorks\MATLAB\R2017a\下添加一个文件javalibrarypath.txt, 并在该文件中添加taos.dll的路径,比如您的taos.dll是在安装时拷贝到了C:\Windows\System32下,那么就应该在javalibrarypath.txt中添加如下一行:
    • -
    -

    C:\Windows\System32

    -

    在MatLab中连接TDengine获取数据

    -

    在成功进行了上述配置后,打开MatLab。

    -
      -
    • 创建一个连接:

      -

      conn = database(‘db’, ‘root’, ‘taosdata’, ‘com.taosdata.jdbc.TSDBDriver’, ‘jdbc:TSDB://127.0.0.1:0/’)

    • -
    • 执行一次查询:

      -

      sql0 = [‘select * from tb’]

      -

      data = select(conn, sql0);

    • -
    • 插入一条记录:

      -

      sql1 = [‘insert into tb values (now, 1)’]

      -

      exec(conn, sql1)

    • -
    -

    更多例子细节请参考安装包内examples\Matlab\TDengineDemo.m文件。

    -

    R

    -

    R语言支持通过JDBC接口来连接TDengine数据库。首先需要安装R语言的JDBC包。启动R语言环境,然后执行以下命令安装R语言的JDBC支持库:

    -
    install.packages('rJDBC', repos='http://cran.us.r-project.org')
    -

    安装完成以后,通过执行library('RJDBC')命令加载 RJDBC 包:

    -

    然后加载TDengine的JDBC驱动:

    -
    drv<-JDBC("com.taosdata.jdbc.TSDBDriver","JDBCDriver-1.0.0-dist.jar", identifier.quote="\"")
    -

    如果执行成功,不会出现任何错误信息。之后通过以下命令尝试连接数据库:

    -
    conn<-dbConnect(drv,"jdbc:TSDB://192.168.0.1:0/?user=root&password=taosdata","root","taosdata")
    -

    注意将上述命令中的IP地址替换成正确的IP地址。如果没有任务错误的信息,则连接数据库成功,否则需要根据错误提示调整连接的命令。TDengine支持以下的 RJDBC 包中函数:

    -
      -
    • dbWriteTable(conn, "test", iris, overwrite=FALSE, append=TRUE):将数据框iris写入表test中,overwrite必须设置为false,append必须设为TRUE,且数据框iris要与表test的结构一致。
    • -
    • dbGetQuery(conn, "select count(*) from test"):查询语句
    • -
    • dbSendUpdate(conn, "use db"):执行任何非查询sql语句。例如dbSendUpdate(conn, "use db"), 写入数据dbSendUpdate(conn, "insert into t1 values(now, 99)")等。
    • -
    • dbReadTable(conn, "test"):读取表test中数据
    • -
    • dbDisconnect(conn):关闭连接
    • -
    • dbRemoveTable(conn, "test"):删除表test
    • -
    -

    TDengine客户端暂不支持如下函数:

    -
      -
    • dbExistsTable(conn, "test"):是否存在表test
    • -
    • dbListTables(conn):显示连接中的所有表
    • -
    回去