diff --git a/.gitignore b/.gitignore index b400d719cc967fd4c1270355f876bd3c39cfc2f3..1ff11080569e9312369f6e9c00463e25853fd38b 100644 --- a/.gitignore +++ b/.gitignore @@ -27,7 +27,6 @@ tests/hdfs/ nmake/ sln/ hdfs/ -c/ taoshebei/ taosdalipu/ Target/ diff --git a/Jenkinsfile b/Jenkinsfile index 976812bd0a4bd48c6a53f9e8e7b9d01a1031e81f..8d2429c137414fdb63260f94c0c99a6d264d8c48 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -227,6 +227,8 @@ pipeline { ./test-all.sh p4 cd ${WKC}/tests ./test-all.sh full jdbc + cd ${WKC}/tests + ./test-all.sh full unit date''' } } diff --git a/documentation20/cn/00.index/docs.md b/documentation20/cn/00.index/docs.md index 7e5f98d909adbe1b558fcf87c85f94e0d703dc07..b4dbc30cdaec12934d1084479db816602eaa8d2b 100644 --- a/documentation20/cn/00.index/docs.md +++ b/documentation20/cn/00.index/docs.md @@ -31,6 +31,20 @@ TDengine是一个高效的存储、查询、分析时序大数据的平台,专 * [创建超级表](/model#create-stable):为同一类型的数据采集点创建一个超级表 * [创建表](/model#create-table):使用超级表做模板,为每一个具体的数据采集点单独建表 +## [TAOS SQL](/taos-sql) + +* [支持的数据类型](/taos-sql#data-type):支持时间戳、整型、浮点型、布尔型、字符型等多种数据类型 +* [数据库管理](/taos-sql#management):添加、删除、查看数据库 +* [表管理](/taos-sql#table):添加、删除、查看、修改表 +* [超级表管理](/taos-sql#super-table):添加、删除、查看、修改超级表 +* [标签管理](/taos-sql#tags):增加、删除、修改标签 +* [数据写入](/taos-sql#insert):支持单表单条、多条、多表多条写入,支持历史数据写入 +* [数据查询](/taos-sql#select):支持时间段、值过滤、排序、查询结果手动分页等 +* [SQL函数](/taos-sql#functions):支持各种聚合函数、选择函数、计算函数,如avg, min, diff等 +* [时间维度聚合](/taos-sql#aggregation):将表中数据按照时间段进行切割后聚合,降维处理 +* [边界限制](/taos-sql#limitation):库、表、SQL等边界限制条件 +* [错误码](/taos-sql/error-code):TDengine 2.0 错误码以及对应的十进制码 + ## [高效写入数据](/insert) * [SQL写入](/insert#sql):使用SQL insert命令向一张或多张表写入单条或多条记录 @@ -94,20 +108,6 @@ TDengine是一个高效的存储、查询、分析时序大数据的平台,专 * [文件目录结构](/administrator#directories):TDengine数据文件、配置文件等所在目录 * [参数限制与保留关键字](/administrator#keywords):TDengine的参数限制与保留关键字列表 -## [TAOS SQL](/taos-sql) - -* [支持的数据类型](/taos-sql#data-type):支持时间戳、整型、浮点型、布尔型、字符型等多种数据类型 -* [数据库管理](/taos-sql#management):添加、删除、查看数据库 -* [表管理](/taos-sql#table):添加、删除、查看、修改表 -* [超级表管理](/taos-sql#super-table):添加、删除、查看、修改超级表 -* [标签管理](/taos-sql#tags):增加、删除、修改标签 -* [数据写入](/taos-sql#insert):支持单表单条、多条、多表多条写入,支持历史数据写入 -* [数据查询](/taos-sql#select):支持时间段、值过滤、排序、查询结果手动分页等 -* [SQL函数](/taos-sql#functions):支持各种聚合函数、选择函数、计算函数,如avg, min, diff等 -* [时间维度聚合](/taos-sql#aggregation):将表中数据按照时间段进行切割后聚合,降维处理 -* [边界限制](/taos-sql#limitation):库、表、SQL等边界限制条件 -* [错误码](/taos-sql/error-code):TDengine 2.0 错误码以及对应的十进制码 - ## TDengine的技术设计 * [系统模块](/architecture/taosd):taosd的功能和模块划分 diff --git a/packaging/docker/Dockerfile b/packaging/docker/Dockerfile index e13cad41204c3f28ed678a664bf7b9b7f5f8715d..230741d036a3012db1ea6351a2f30ca4b704d350 100644 --- a/packaging/docker/Dockerfile +++ b/packaging/docker/Dockerfile @@ -13,9 +13,8 @@ WORKDIR /root/${dirName}/ RUN /bin/bash install.sh -e no ENV LD_LIBRARY_PATH="$LD_LIBRARY_PATH:/usr/lib" -ENV LANG=en_US.UTF-8 -ENV LANGUAGE=en_US:en -ENV LC_ALL=en_US.UTF-8 +ENV LANG=C.UTF-8 +ENV LC_ALL=C.UTF-8 EXPOSE 6030 6031 6032 6033 6034 6035 6036 6037 6038 6039 6040 6041 6042 CMD ["taosd"] VOLUME [ "/var/lib/taos", "/var/log/taos","/etc/taos/" ] diff --git a/src/client/inc/tscUtil.h b/src/client/inc/tscUtil.h index e78e259eb21ac2bc3a57b261481635c288f328dc..502d044d7540169497b682df96424ca3304f4668 100644 --- a/src/client/inc/tscUtil.h +++ b/src/client/inc/tscUtil.h @@ -270,7 +270,7 @@ void tscPrintSelectClause(SSqlObj* pSql, int32_t subClauseIndex); bool hasMoreVnodesToTry(SSqlObj *pSql); bool hasMoreClauseToTry(SSqlObj* pSql); -void tscFreeQueryInfo(SSqlCmd* pCmd); +void tscFreeQueryInfo(SSqlCmd* pCmd, bool removeMeta); void tscTryQueryNextVnode(SSqlObj *pSql, __async_cb_func_t fp); void tscAsyncQuerySingleRowForNextVnode(void *param, TAOS_RES *tres, int numOfRows); diff --git a/src/client/inc/tsclient.h b/src/client/inc/tsclient.h index 8f76f812acff2efbe3da4ea05b7f1d87003db28b..0bfbf3f946a4a1428549a493ab990a2be2173266 100644 --- a/src/client/inc/tsclient.h +++ b/src/client/inc/tsclient.h @@ -442,6 +442,8 @@ void tscCloseTscObj(void *pObj); TAOS *taos_connect_a(char *ip, char *user, char *pass, char *db, uint16_t port, void (*fp)(void *, TAOS_RES *, int), void *param, TAOS **taos); TAOS_RES* taos_query_h(TAOS* taos, const char *sqlstr, int64_t* res); +TAOS_RES * taos_query_ra(TAOS *taos, const char *sqlstr, __async_cb_func_t fp, void *param); + void waitForQueryRsp(void *param, TAOS_RES *tres, int code); void doAsyncQuery(STscObj *pObj, SSqlObj *pSql, __async_cb_func_t fp, void *param, const char *sqlstr, size_t sqlLen); diff --git a/src/client/src/tscAsync.c b/src/client/src/tscAsync.c index 7d5b76cc2b3be68ae751e61b4b6c9870120c7d66..5cba897b3028a2d6301e9363ca6180f6b41022f8 100644 --- a/src/client/src/tscAsync.c +++ b/src/client/src/tscAsync.c @@ -74,12 +74,16 @@ void doAsyncQuery(STscObj* pObj, SSqlObj* pSql, __async_cb_func_t fp, void* para // TODO return the correct error code to client in tscQueueAsyncError void taos_query_a(TAOS *taos, const char *sqlstr, __async_cb_func_t fp, void *param) { + taos_query_ra(taos, sqlstr, fp, param); +} + +TAOS_RES * taos_query_ra(TAOS *taos, const char *sqlstr, __async_cb_func_t fp, void *param) { STscObj *pObj = (STscObj *)taos; if (pObj == NULL || pObj->signature != pObj) { tscError("bug!!! pObj:%p", pObj); terrno = TSDB_CODE_TSC_DISCONNECTED; tscQueueAsyncError(fp, param, TSDB_CODE_TSC_DISCONNECTED); - return; + return NULL; } int32_t sqlLen = (int32_t)strlen(sqlstr); @@ -87,7 +91,7 @@ void taos_query_a(TAOS *taos, const char *sqlstr, __async_cb_func_t fp, void *pa tscError("sql string exceeds max length:%d", tsMaxSQLStringLen); terrno = TSDB_CODE_TSC_EXCEED_SQL_LIMIT; tscQueueAsyncError(fp, param, terrno); - return; + return NULL; } nPrintTsc("%s", sqlstr); @@ -96,12 +100,15 @@ void taos_query_a(TAOS *taos, const char *sqlstr, __async_cb_func_t fp, void *pa if (pSql == NULL) { tscError("failed to malloc sqlObj"); tscQueueAsyncError(fp, param, TSDB_CODE_TSC_OUT_OF_MEMORY); - return; + return NULL; } doAsyncQuery(pObj, pSql, fp, param, sqlstr, sqlLen); + + return pSql; } + static void tscAsyncFetchRowsProxy(void *param, TAOS_RES *tres, int numOfRows) { if (tres == NULL) { return; diff --git a/src/client/src/tscSubquery.c b/src/client/src/tscSubquery.c index 812027aa65bb3a4a2d35d630c2c8d112df9a7cc0..78e9c6829081cb61f5fa8e2ed55397242ba357a4 100644 --- a/src/client/src/tscSubquery.c +++ b/src/client/src/tscSubquery.c @@ -2802,7 +2802,7 @@ static void multiVnodeInsertFinalize(void* param, TAOS_RES* tres, int numOfRows) numOfFailed += 1; // clean up tableMeta in cache - tscFreeQueryInfo(&pSql->cmd); + tscFreeQueryInfo(&pSql->cmd, false); SQueryInfo* pQueryInfo = tscGetQueryInfoDetailSafely(&pSql->cmd, 0); STableMetaInfo* pMasterTableMetaInfo = tscGetTableMetaInfoFromCmd(&pParentObj->cmd, pSql->cmd.clauseIndex, 0); tscAddTableMetaInfo(pQueryInfo, &pMasterTableMetaInfo->name, NULL, NULL, NULL, NULL); diff --git a/src/client/src/tscUtil.c b/src/client/src/tscUtil.c index cfa73b969d5a144822d83c9922a2ff55c97c2015..578a7df1493b23792791a29bf0acf43c6e38b719 100644 --- a/src/client/src/tscUtil.c +++ b/src/client/src/tscUtil.c @@ -30,7 +30,7 @@ #include "ttokendef.h" static void freeQueryInfoImpl(SQueryInfo* pQueryInfo); -static void clearAllTableMetaInfo(SQueryInfo* pQueryInfo); +static void clearAllTableMetaInfo(SQueryInfo* pQueryInfo, bool removeMeta); static void tscStrToLower(char *str, int32_t n) { if (str == NULL || n <= 0) { return;} @@ -367,7 +367,7 @@ static void tscDestroyResPointerInfo(SSqlRes* pRes) { pRes->data = NULL; // pRes->data points to the buffer of pRsp, no need to free } -void tscFreeQueryInfo(SSqlCmd* pCmd) { +void tscFreeQueryInfo(SSqlCmd* pCmd, bool removeMeta) { if (pCmd == NULL || pCmd->numOfClause == 0) { return; } @@ -376,7 +376,7 @@ void tscFreeQueryInfo(SSqlCmd* pCmd) { SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(pCmd, i); freeQueryInfoImpl(pQueryInfo); - clearAllTableMetaInfo(pQueryInfo); + clearAllTableMetaInfo(pQueryInfo, removeMeta); tfree(pQueryInfo); } @@ -404,7 +404,7 @@ void tscResetSqlCmd(SSqlCmd* pCmd, bool removeMeta) { pCmd->pTableBlockHashList = tscDestroyBlockHashTable(pCmd->pTableBlockHashList, removeMeta); pCmd->pDataBlocks = tscDestroyBlockArrayList(pCmd->pDataBlocks); - tscFreeQueryInfo(pCmd); + tscFreeQueryInfo(pCmd, removeMeta); } void tscFreeSqlResult(SSqlObj* pSql) { @@ -1847,10 +1847,17 @@ SArray* tscVgroupTableInfoDup(SArray* pVgroupTables) { return pa; } -void clearAllTableMetaInfo(SQueryInfo* pQueryInfo) { +void clearAllTableMetaInfo(SQueryInfo* pQueryInfo, bool removeMeta) { for(int32_t i = 0; i < pQueryInfo->numOfTables; ++i) { STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, i); + if (removeMeta) { + char name[TSDB_TABLE_FNAME_LEN] = {0}; + tNameExtractFullName(&pTableMetaInfo->name, name); + + taosHashRemove(tscTableMetaInfo, name, strnlen(name, TSDB_TABLE_FNAME_LEN)); + } + tscFreeVgroupTableInfo(pTableMetaInfo->pVgroupTables); tscClearTableMetaInfo(pTableMetaInfo); free(pTableMetaInfo); @@ -2714,7 +2721,11 @@ STableMeta* createSuperTableMeta(STableMetaMsg* pChild) { uint32_t tscGetTableMetaSize(STableMeta* pTableMeta) { assert(pTableMeta != NULL); - int32_t totalCols = pTableMeta->tableInfo.numOfColumns + pTableMeta->tableInfo.numOfTags; + int32_t totalCols = 0; + if (pTableMeta->tableInfo.numOfColumns >= 0 && pTableMeta->tableInfo.numOfTags >= 0) { + totalCols = pTableMeta->tableInfo.numOfColumns + pTableMeta->tableInfo.numOfTags; + } + return sizeof(STableMeta) + totalCols * sizeof(SSchema); } diff --git a/src/inc/taosdef.h b/src/inc/taosdef.h index 9f3c31f22595d6dc6007dc9517390b970b781943..f4712198ee9c2aee97eda1a03085032c81c53b84 100644 --- a/src/inc/taosdef.h +++ b/src/inc/taosdef.h @@ -286,7 +286,7 @@ do { \ #define TSDB_MAX_COMP_LEVEL 2 #define TSDB_DEFAULT_COMP_LEVEL 2 -#define TSDB_MIN_WAL_LEVEL 1 +#define TSDB_MIN_WAL_LEVEL 0 #define TSDB_MAX_WAL_LEVEL 2 #define TSDB_DEFAULT_WAL_LEVEL 1 diff --git a/src/mnode/src/mnodeTable.c b/src/mnode/src/mnodeTable.c index b1ae118b4b8174d1ac9427a290e6b49efddbb33a..1378847d0b472bb65621fc88951d4fbd6e7d0790 100644 --- a/src/mnode/src/mnodeTable.c +++ b/src/mnode/src/mnodeTable.c @@ -832,12 +832,13 @@ static int32_t mnodeProcessBatchCreateTableMsg(SMnodeMsg *pMsg) { return code; } else if (code != TSDB_CODE_MND_ACTION_IN_PROGRESS) { ++pMsg->pBatchMasterMsg->received; + pMsg->pBatchMasterMsg->code = code; mnodeDestroySubMsg(pMsg); } if (pMsg->pBatchMasterMsg->successed + pMsg->pBatchMasterMsg->received >= pMsg->pBatchMasterMsg->expected) { - dnodeSendRpcMWriteRsp(pMsg->pBatchMasterMsg, TSDB_CODE_SUCCESS); + dnodeSendRpcMWriteRsp(pMsg->pBatchMasterMsg, pMsg->pBatchMasterMsg->code); } return TSDB_CODE_MND_ACTION_IN_PROGRESS; @@ -1908,7 +1909,8 @@ static int32_t mnodeDoCreateChildTableCb(SMnodeMsg *pMsg, int32_t code) { sdbDeleteRow(&desc); if (pMsg->pBatchMasterMsg) { - ++pMsg->pBatchMasterMsg->successed; + ++pMsg->pBatchMasterMsg->received; + pMsg->pBatchMasterMsg->code = code; if (pMsg->pBatchMasterMsg->successed + pMsg->pBatchMasterMsg->received >= pMsg->pBatchMasterMsg->expected) { dnodeSendRpcMWriteRsp(pMsg->pBatchMasterMsg, code); @@ -2690,6 +2692,7 @@ static void mnodeProcessCreateChildTableRsp(SRpcMsg *rpcMsg) { if (pMsg->pBatchMasterMsg) { ++pMsg->pBatchMasterMsg->received; + pMsg->pBatchMasterMsg->code = code; if (pMsg->pBatchMasterMsg->successed + pMsg->pBatchMasterMsg->received >= pMsg->pBatchMasterMsg->expected) { dnodeSendRpcMWriteRsp(pMsg->pBatchMasterMsg, code); @@ -2728,6 +2731,7 @@ static void mnodeProcessCreateChildTableRsp(SRpcMsg *rpcMsg) { if (pMsg->pBatchMasterMsg) { ++pMsg->pBatchMasterMsg->received; + pMsg->pBatchMasterMsg->code = rpcMsg->code; if (pMsg->pBatchMasterMsg->successed + pMsg->pBatchMasterMsg->received >= pMsg->pBatchMasterMsg->expected) { dnodeSendRpcMWriteRsp(pMsg->pBatchMasterMsg, rpcMsg->code); diff --git a/src/mnode/src/mnodeVgroup.c b/src/mnode/src/mnodeVgroup.c index 67ee11640b04c355f0a15d0df12eacc5f1837d7b..98eab3f1ed07545974bc3247275530c81fd34e84 100644 --- a/src/mnode/src/mnodeVgroup.c +++ b/src/mnode/src/mnodeVgroup.c @@ -537,6 +537,7 @@ static int32_t mnodeCreateVgroupCb(SMnodeMsg *pMsg, int32_t code) { if (pMsg->pBatchMasterMsg) { ++pMsg->pBatchMasterMsg->received; + pMsg->pBatchMasterMsg->code = pMsg->code; if (pMsg->pBatchMasterMsg->successed + pMsg->pBatchMasterMsg->received >= pMsg->pBatchMasterMsg->expected) { dnodeSendRpcMWriteRsp(pMsg->pBatchMasterMsg, pMsg->code); @@ -1002,6 +1003,7 @@ static void mnodeProcessCreateVnodeRsp(SRpcMsg *rpcMsg) { if (mnodeMsg->pBatchMasterMsg) { ++mnodeMsg->pBatchMasterMsg->received; + mnodeMsg->pBatchMasterMsg->code = code; if (mnodeMsg->pBatchMasterMsg->successed + mnodeMsg->pBatchMasterMsg->received >= mnodeMsg->pBatchMasterMsg->expected) { dnodeSendRpcMWriteRsp(mnodeMsg->pBatchMasterMsg, code); @@ -1024,6 +1026,7 @@ static void mnodeProcessCreateVnodeRsp(SRpcMsg *rpcMsg) { if (mnodeMsg->pBatchMasterMsg) { ++mnodeMsg->pBatchMasterMsg->received; + mnodeMsg->pBatchMasterMsg->code = mnodeMsg->code; if (mnodeMsg->pBatchMasterMsg->successed + mnodeMsg->pBatchMasterMsg->received >= mnodeMsg->pBatchMasterMsg->expected) { dnodeSendRpcMWriteRsp(mnodeMsg->pBatchMasterMsg, mnodeMsg->code); diff --git a/src/os/inc/osDef.h b/src/os/inc/osDef.h index cb91b0526bdec17af1d5d86bfb24f8f95b56e01c..bbe0f98ec0b632deb39691f74350bced6d2a6515 100644 --- a/src/os/inc/osDef.h +++ b/src/os/inc/osDef.h @@ -83,6 +83,20 @@ extern "C" { } \ } while (0) +#define DEFAULT_DOUBLE_COMP(x, y) \ + do { \ + if (isnan(x) && isnan(y)) { return 0; } \ + if (isnan(x)) { return -1; } \ + if (isnan(y)) { return 1; } \ + if ((x) == (y)) { \ + return 0; \ + } else { \ + return (x) < (y) ? -1 : 1; \ + } \ + } while (0) + +#define DEFAULT_FLOAT_COMP(x, y) DEFAULT_DOUBLE_COMP(x, y) + #define ALIGN_NUM(n, align) (((n) + ((align)-1)) & (~((align)-1))) // align to 8bytes diff --git a/src/query/src/qExtbuffer.c b/src/query/src/qExtbuffer.c index e4c62d90e38407954af1fe00454e6df99cb288bd..a73f38528266bfa70790414a2963eb0a8290d7b9 100644 --- a/src/query/src/qExtbuffer.c +++ b/src/query/src/qExtbuffer.c @@ -362,20 +362,10 @@ static FORCE_INLINE int32_t columnValueAscendingComparator(char *f1, char *f2, i return (first < second) ? -1 : 1; }; case TSDB_DATA_TYPE_DOUBLE: { - double first = GET_DOUBLE_VAL(f1); - double second = GET_DOUBLE_VAL(f2); - if (first == second) { - return 0; - } - return (first < second) ? -1 : 1; + DEFAULT_DOUBLE_COMP(GET_DOUBLE_VAL(f1), GET_DOUBLE_VAL(f2)); }; case TSDB_DATA_TYPE_FLOAT: { - float first = GET_FLOAT_VAL(f1); - float second = GET_FLOAT_VAL(f2); - if (first == second) { - return 0; - } - return (first < second) ? -1 : 1; + DEFAULT_FLOAT_COMP(GET_FLOAT_VAL(f1), GET_FLOAT_VAL(f2)); }; case TSDB_DATA_TYPE_BIGINT: { int64_t first = *(int64_t *)f1; diff --git a/src/query/src/qParserImpl.c b/src/query/src/qParserImpl.c index 2416250dce4c57fd91a76843ed0f86103345c583..5937fdb68f0fb7d8915b427cacd627f96bc02d1c 100644 --- a/src/query/src/qParserImpl.c +++ b/src/query/src/qParserImpl.c @@ -58,6 +58,15 @@ SSqlInfo qSQLParse(const char *pStr) { sqlInfo.valid = false; goto abort_parse; } + + case TK_HEX: + case TK_OCT: + case TK_BIN:{ + snprintf(sqlInfo.msg, tListLen(sqlInfo.msg), "unsupported token: \"%s\"", t0.z); + sqlInfo.valid = false; + goto abort_parse; + } + default: Parse(pParser, t0.type, t0, &sqlInfo); if (sqlInfo.valid == false) { diff --git a/src/query/tests/percentileTest.cpp b/src/query/tests/percentileTest.cpp index f2b457e7dd686af16ae4a1192fe52a6f8090274f..104bfb3c06a9613bafcd4e0b3f39af4f9d102b04 100644 --- a/src/query/tests/percentileTest.cpp +++ b/src/query/tests/percentileTest.cpp @@ -48,7 +48,7 @@ tMemBucket *createUnsignedDataBucket(int32_t start, int32_t end, int32_t type) { uint64_t k = i; int32_t ret = tMemBucketPut(pBucket, &k, 1); if (ret != 0) { - printf("value out of range:%f", k); + printf("value out of range:%" PRId64, k); } } @@ -245,7 +245,7 @@ void unsignedDataTest() { } // namespace TEST(testCase, percentileTest) { - // qsortTest(); +// qsortTest(); intDataTest(); bigintDataTest(); doubleDataTest(); diff --git a/src/query/tests/unitTest.cpp b/src/query/tests/unitTest.cpp index a8500364dceaef97d215b72ef805163e726bdaf9..3406d8309023118d16cfc4dfbdab58defc6f005a 100644 --- a/src/query/tests/unitTest.cpp +++ b/src/query/tests/unitTest.cpp @@ -227,10 +227,10 @@ TEST(testCase, db_table_name) { EXPECT_EQ(testValidateName(t60_1), TSDB_CODE_TSC_INVALID_SQL); char t61[] = "' ABC '"; - EXPECT_EQ(testValidateName(t61), TSDB_CODE_SUCCESS); + EXPECT_EQ(testValidateName(t61), TSDB_CODE_TSC_INVALID_SQL); char t61_1[] = "' ABC '"; - EXPECT_EQ(testValidateName(t61_1), TSDB_CODE_SUCCESS); + EXPECT_EQ(testValidateName(t61_1), TSDB_CODE_TSC_INVALID_SQL); char t62[] = " ABC . def "; EXPECT_EQ(testValidateName(t62), TSDB_CODE_TSC_INVALID_SQL); @@ -249,13 +249,13 @@ TEST(testCase, db_table_name) { EXPECT_EQ(testValidateName(t65), TSDB_CODE_TSC_INVALID_SQL); char t66[] = "' ABC '.' DEF '"; - EXPECT_EQ(testValidateName(t66), TSDB_CODE_SUCCESS); + EXPECT_EQ(testValidateName(t66), TSDB_CODE_TSC_INVALID_SQL); char t67[] = "abc . ' DEF '"; EXPECT_EQ(testValidateName(t67), TSDB_CODE_TSC_INVALID_SQL); char t68[] = "' abc '.' DEF '"; - EXPECT_EQ(testValidateName(t68), TSDB_CODE_SUCCESS); + EXPECT_EQ(testValidateName(t68), TSDB_CODE_TSC_INVALID_SQL); // do not use key words char t69[] = "table.'DEF'"; @@ -265,7 +265,7 @@ TEST(testCase, db_table_name) { EXPECT_EQ(testValidateName(t70), TSDB_CODE_TSC_INVALID_SQL); char t71[] = "'_abXYZ1234 '.' deFF '"; - EXPECT_EQ(testValidateName(t71), TSDB_CODE_SUCCESS); + EXPECT_EQ(testValidateName(t71), TSDB_CODE_TSC_INVALID_SQL); char t72[] = "'_abDEF&^%1234'.' DIef'"; EXPECT_EQ(testValidateName(t72), TSDB_CODE_TSC_INVALID_SQL); diff --git a/src/tsdb/src/tsdbRead.c b/src/tsdb/src/tsdbRead.c index 486ff49f097df971d1a1130181a1c14b79f9fc01..e0648c33a050fcdb5a6cd83517283092b1061d5e 100644 --- a/src/tsdb/src/tsdbRead.c +++ b/src/tsdb/src/tsdbRead.c @@ -285,17 +285,24 @@ static SArray* createCheckInfoFromTableGroup(STsdbQueryHandle* pQueryHandle, STa assert(info.lastKey <= pQueryHandle->window.skey); } - taosArrayPush(pTable, &pKeyInfo->pTable); - taosArrayPush(pTableCheckInfo, &info); tsdbDebug("%p check table uid:%"PRId64", tid:%d from lastKey:%"PRId64" %p", pQueryHandle, info.tableId.uid, info.tableId.tid, info.lastKey, pQueryHandle->qinfo); } } - *psTable = pTable; - taosArraySort(pTableCheckInfo, tsdbCheckInfoCompar); + + size_t gsize = taosArrayGetSize(pTableCheckInfo); + + for (int32_t i = 0; i < gsize; ++i) { + STableCheckInfo* pInfo = (STableCheckInfo*) taosArrayGet(pTableCheckInfo, i); + + taosArrayPush(pTable, &pInfo->pTableObj); + } + + *psTable = pTable; + return pTableCheckInfo; } diff --git a/src/util/src/tcompare.c b/src/util/src/tcompare.c index cd3428ddc54fd8d4f4589b6d24db032e4d313ca0..4d18ef14e2a1985259b11ff65391616c9d4706b2 100644 --- a/src/util/src/tcompare.c +++ b/src/util/src/tcompare.c @@ -392,8 +392,8 @@ __compar_fn_t getKeyComparFunc(int32_t keyType) { int32_t doCompare(const char* f1, const char* f2, int32_t type, size_t size) { switch (type) { case TSDB_DATA_TYPE_INT: DEFAULT_COMP(GET_INT32_VAL(f1), GET_INT32_VAL(f2)); - case TSDB_DATA_TYPE_DOUBLE: DEFAULT_COMP(GET_DOUBLE_VAL(f1), GET_DOUBLE_VAL(f2)); - case TSDB_DATA_TYPE_FLOAT: DEFAULT_COMP(GET_FLOAT_VAL(f1), GET_FLOAT_VAL(f2)); + case TSDB_DATA_TYPE_DOUBLE: DEFAULT_DOUBLE_COMP(GET_DOUBLE_VAL(f1), GET_DOUBLE_VAL(f2)); + case TSDB_DATA_TYPE_FLOAT: DEFAULT_FLOAT_COMP(GET_FLOAT_VAL(f1), GET_FLOAT_VAL(f2)); case TSDB_DATA_TYPE_BIGINT: DEFAULT_COMP(GET_INT64_VAL(f1), GET_INT64_VAL(f2)); case TSDB_DATA_TYPE_SMALLINT: DEFAULT_COMP(GET_INT16_VAL(f1), GET_INT16_VAL(f2)); case TSDB_DATA_TYPE_TINYINT: diff --git a/tests/Jenkinsfile b/tests/Jenkinsfile index 2f8b0de09d928404ae5e2f2925a452b4e1bfa150..7cdcfb2e24f92a96e2d3cc15324ca4f3ac4bc7a8 100644 --- a/tests/Jenkinsfile +++ b/tests/Jenkinsfile @@ -55,9 +55,15 @@ pipeline { sh ''' cd ${WKC}/tests ./test-all.sh b1 + date''' + sh ''' cd ${WKC}/tests ./test-all.sh full jdbc date''' + sh ''' + cd ${WKC}/tests + ./test-all.sh full unit + date''' } } diff --git a/tests/examples/c/demo.c b/tests/examples/c/demo.c index 3853d81fb251809e1e6b18ffa1fad5c8ca882d16..e074e6496607bf2046496c7b6766b6f3dedf9dbc 100644 --- a/tests/examples/c/demo.c +++ b/tests/examples/c/demo.c @@ -92,15 +92,14 @@ void Test(TAOS *taos, char *qstr, int index) { // printf("insert row: %i, reason:%s\n", i, taos_errstr(taos)); // } TAOS_RES *result1 = taos_query(taos, qstr); - if (result1) { - printf("insert row: %i\n", i); - } else { - printf("failed to insert row: %i, reason:%s\n", i, "null result"/*taos_errstr(result)*/); + if (result1 == NULL || taos_errno(result1) != 0) { + printf("failed to insert row, reason:%s\n", taos_errstr(result1)); taos_free_result(result1); exit(1); + } else { + printf("insert row: %i\n", i); } taos_free_result(result1); - } printf("success to insert rows, total %d rows\n", i); diff --git a/tests/pytest/cluster/clusterSetup.py b/tests/pytest/cluster/clusterSetup.py index dbda5657b6528402cc898762cccc78d74a196cd8..8a264270219232447a598768b45a37779edba698 100644 --- a/tests/pytest/cluster/clusterSetup.py +++ b/tests/pytest/cluster/clusterSetup.py @@ -11,15 +11,9 @@ # -*- coding: utf-8 -*- -import os -import sys -sys.path.insert(0, os.getcwd()) from fabric import Connection -from util.sql import * -from util.log import * -import taos import random -import threading +import time import logging class Node: @@ -76,6 +70,19 @@ class Node: print("remove taosd error for node %d " % self.index) logging.exception(e) + def forceStopOneTaosd(self): + try: + self.conn.run("kill -9 $(ps -ax|grep taosd|awk '{print $1}')") + except Exception as e: + print("kill taosd error on node%d " % self.index) + + def startOneTaosd(self): + try: + self.conn.run("nohup taosd -c /etc/taos/ > /dev/null 2>&1 &") + except Exception as e: + print("start taosd error on node%d " % self.index) + logging.exception(e) + def installTaosd(self, packagePath): self.conn.put(packagePath, self.homeDir) self.conn.cd(self.homeDir) @@ -122,100 +129,51 @@ class Node: class Nodes: def __init__(self): - self.node1 = Node(1, 'root', '52.151.60.239', 'node1', 'r', '/root/') - self.node2 = Node(2, 'root', '52.183.32.246', 'node1', 'r', '/root/') - self.node3 = Node(3, 'root', '51.143.46.79', 'node1', 'r', '/root/') - self.node4 = Node(4, 'root', '52.183.2.76', 'node1', 'r', '/root/') - self.node5 = Node(5, 'root', '13.66.225.87', 'node1', 'r', '/root/') + self.tdnodes = [] + self.tdnodes.append(Node(0, 'root', '52.143.103.7', 'node1', 'a', '/root/')) + self.tdnodes.append(Node(1, 'root', '52.250.48.222', 'node2', 'a', '/root/')) + self.tdnodes.append(Node(2, 'root', '51.141.167.23', 'node3', 'a', '/root/')) + self.tdnodes.append(Node(3, 'root', '52.247.207.173', 'node4', 'a', '/root/')) + self.tdnodes.append(Node(4, 'root', '51.141.166.100', 'node5', 'a', '/root/')) + + def stopOneNode(self, index): + self.tdnodes[index].forceStopOneTaosd() + + def startOneNode(self, index): + self.tdnodes[index].startOneTaosd() def stopAllTaosd(self): - self.node1.stopTaosd() - self.node2.stopTaosd() - self.node3.stopTaosd() - + for i in range(len(self.tdnodes)): + self.tdnodes[i].stopTaosd() + def startAllTaosd(self): - self.node1.startTaosd() - self.node2.startTaosd() - self.node3.startTaosd() + for i in range(len(self.tdnodes)): + self.tdnodes[i].startTaosd() def restartAllTaosd(self): - self.node1.restartTaosd() - self.node2.restartTaosd() - self.node3.restartTaosd() + for i in range(len(self.tdnodes)): + self.tdnodes[i].restartTaosd() def addConfigs(self, configKey, configValue): - self.node1.configTaosd(configKey, configValue) - self.node2.configTaosd(configKey, configValue) - self.node3.configTaosd(configKey, configValue) + for i in range(len(self.tdnodes)): + self.tdnodes[i].configTaosd(configKey, configValue) - def removeConfigs(self, configKey, configValue): - self.node1.removeTaosConfig(configKey, configValue) - self.node2.removeTaosConfig(configKey, configValue) - self.node3.removeTaosConfig(configKey, configValue) + def removeConfigs(self, configKey, configValue): + for i in range(len(self.tdnodes)): + self.tdnodes[i].removeTaosConfig(configKey, configValue) def removeAllDataFiles(self): - self.node1.removeData() - self.node2.removeData() - self.node3.removeData() - -class ClusterTest: - def __init__(self, hostName): - self.host = hostName - self.user = "root" - self.password = "taosdata" - self.config = "/etc/taos" - self.dbName = "mytest" - self.stbName = "meters" - self.numberOfThreads = 20 - self.numberOfTables = 10000 - self.numberOfRecords = 1000 - self.tbPrefix = "t" - self.ts = 1538548685000 - self.repeat = 1 - - def connectDB(self): - self.conn = taos.connect( - host=self.host, - user=self.user, - password=self.password, - config=self.config) - - def createSTable(self, replica): - cursor = self.conn.cursor() - tdLog.info("drop database if exists %s" % self.dbName) - cursor.execute("drop database if exists %s" % self.dbName) - tdLog.info("create database %s replica %d" % (self.dbName, replica)) - cursor.execute("create database %s replica %d" % (self.dbName, replica)) - tdLog.info("use %s" % self.dbName) - cursor.execute("use %s" % self.dbName) - tdLog.info("drop table if exists %s" % self.stbName) - cursor.execute("drop table if exists %s" % self.stbName) - tdLog.info("create table %s(ts timestamp, current float, voltage int, phase int) tags(id int)" % self.stbName) - cursor.execute("create table %s(ts timestamp, current float, voltage int, phase int) tags(id int)" % self.stbName) - cursor.close() - - def insertData(self, threadID): - print("Thread %d: starting" % threadID) - cursor = self.conn.cursor() - tablesPerThread = int(self.numberOfTables / self.numberOfThreads) - baseTableID = tablesPerThread * threadID - for i in range (tablesPerThread): - cursor.execute("create table %s%d using %s tags(%d)" % (self.tbPrefix, baseTableID + i, self.stbName, baseTableID + i)) - query = "insert into %s%d values" % (self.tbPrefix, baseTableID + i) - base = self.numberOfRecords * i - for j in range(self.numberOfRecords): - query += "(%d, %f, %d, %d)" % (self.ts + base + j, random.random(), random.randint(210, 230), random.randint(0, 10)) - cursor.execute(query) - cursor.close() - print("Thread %d: finishing" % threadID) - - def run(self): - threads = [] - tdLog.info("Inserting data") - for i in range(self.numberOfThreads): - thread = threading.Thread(target=self.insertData, args=(i,)) - threads.append(thread) - thread.start() - - for i in range(self.numberOfThreads): - threads[i].join() \ No newline at end of file + for i in range(len(self.tdnodes)): + self.tdnodes[i].removeData() + +# kill taosd randomly every 10 mins +nodes = Nodes() +loop = 0 +while True: + loop = loop + 1 + index = random.randint(0, 4) + print("loop: %d, kill taosd on node%d" %(loop, index)) + nodes.stopOneNode(index) + time.sleep(60) + nodes.startOneNode(index) + time.sleep(600) \ No newline at end of file diff --git a/tests/pytest/insert/metadataUpdate.py b/tests/pytest/insert/metadataUpdate.py index c3ea5c6a7e7b5dbff9ded75394793e7fc4a7fd6c..77795d13f139987559de3639f566cc8866b0ece0 100644 --- a/tests/pytest/insert/metadataUpdate.py +++ b/tests/pytest/insert/metadataUpdate.py @@ -54,10 +54,11 @@ class TDTestCase: p.terminate() tdSql.execute("insert into tb values(%d, 1, 2)" % (self.ts + 1)) + tdSql.execute("insert into tb(ts, col1, col2) values(%d, 1, 2)" % (self.ts + 2)) print("==============step2") tdSql.query("select * from tb") - tdSql.checkRows(2) + tdSql.checkRows(3) def stop(self): tdSql.close() diff --git a/tests/script/general/db/alter_option.sim b/tests/script/general/db/alter_option.sim index 9d4dedfce0e081345d8659abdcdebf3cce2efb74..170ba21c28b7ff4a79a8f2375dc1d36ba91e6120 100644 --- a/tests/script/general/db/alter_option.sim +++ b/tests/script/general/db/alter_option.sim @@ -209,7 +209,7 @@ sql alter database db wal 1 sql alter database db wal 2 sql alter database db wal 1 sql alter database db wal 2 -sql_error alter database db wal 0 +sql 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 diff --git a/tests/script/general/parser/create_db.sim b/tests/script/general/parser/create_db.sim index 6cf08a5ac4231ea715c1892842b0e4d122d2520c..ea1cc17a6a779391c8dfa064bf98bf70715d9e70 100644 --- a/tests/script/general/parser/create_db.sim +++ b/tests/script/general/parser/create_db.sim @@ -169,8 +169,8 @@ sql_error create database $db cache 0 sql_error create database $db ctime 29 sql_error create database $db ctime 40961 -# wal {1, 2} -sql_error create database $db wal 0 +# wal {0, 2} +#sql_error create database $db wal 0 sql_error create database $db wal -1 sql_error create database $db wal 3 diff --git a/tests/test-all.sh b/tests/test-all.sh index 3ebdffebf238706d6c3cad18f4ed996b85de49cd..4f7afe7d17bc57d6f62a5d68cac3277914dedb50 100755 --- a/tests/test-all.sh +++ b/tests/test-all.sh @@ -160,9 +160,10 @@ function runPyCaseOneByOnefq { totalFailed=0 totalPyFailed=0 totalJDBCFailed=0 +totalUnitFailed=0 corepath=`grep -oP '.*(?=core_)' /proc/sys/kernel/core_pattern||grep -oP '.*(?=core-)' /proc/sys/kernel/core_pattern` -if [ "$2" != "jdbc" ] && [ "$2" != "python" ]; then +if [ "$2" != "jdbc" ] && [ "$2" != "python" ] && [ "$2" != "unit" ]; then echo "### run TSIM test case ###" cd $tests_dir/script @@ -231,7 +232,7 @@ if [ "$2" != "jdbc" ] && [ "$2" != "python" ]; then fi fi -if [ "$2" != "sim" ] && [ "$2" != "jdbc" ] ; then +if [ "$2" != "sim" ] && [ "$2" != "jdbc" ] && [ "$2" != "unit" ]; then echo "### run Python test case ###" cd $tests_dir @@ -300,8 +301,8 @@ if [ "$2" != "sim" ] && [ "$2" != "jdbc" ] ; then fi -if [ "$2" != "sim" ] && [ "$2" != "python" ] && [ "$1" == "full" ]; then - echo "### run JDBC test case ###" +if [ "$2" != "sim" ] && [ "$2" != "python" ] && [ "$2" != "unit" ] && [ "$1" == "full" ]; then + echo "### run JDBC test cases ###" cd $tests_dir @@ -318,7 +319,7 @@ if [ "$2" != "sim" ] && [ "$2" != "python" ] && [ "$1" == "full" ]; then nohup build/bin/taosd -c /etc/taos/ > /dev/null 2>&1 & sleep 30 - cd $tests_dir/../src/connector/jdbc + cd $tests_dir/../src/connector/jdbc mvn test > jdbc-out.log 2>&1 tail -n 20 jdbc-out.log @@ -343,4 +344,40 @@ if [ "$2" != "sim" ] && [ "$2" != "python" ] && [ "$1" == "full" ]; then dohavecore 1 fi -exit $(($totalFailed + $totalPyFailed + $totalJDBCFailed)) +if [ "$2" != "sim" ] && [ "$2" != "python" ] && [ "$2" != "jdbc" ] && [ "$1" == "full" ]; then + echo "### run Unit tests ###" + + stopTaosd + cd $tests_dir + + if [[ "$tests_dir" == *"$IN_TDINTERNAL"* ]]; then + cd ../../ + else + cd ../ + fi + + pwd + cd debug/build/bin + nohup ./taosd -c /etc/taos/ > /dev/null 2>&1 & + sleep 30 + + pwd + ./queryTest > unittest-out.log 2>&1 + tail -n 20 unittest-out.log + + totalUnitTests=`grep "Running" unittest-out.log | awk '{print $3}'` + totalUnitSuccess=`grep 'PASSED' unittest-out.log | awk '{print $4}'` + totalUnitFailed=`expr $totalUnitTests - $totalUnitSuccess` + + if [ "$totalUnitSuccess" -gt "0" ]; then + echo -e "\n${GREEN} ### Total $totalUnitSuccess Unit test succeed! ### ${NC}" + fi + + if [ "$totalUnitFailed" -ne "0" ]; then + echo -e "\n${RED} ### Total $totalUnitFailed Unit test failed! ### ${NC}" + fi + dohavecore 1 +fi + + +exit $(($totalFailed + $totalPyFailed + $totalJDBCFailed + $totalUnitFailed))