diff --git a/.travis.yml b/.travis.yml index 8c57085296041effcbbfee76e868e0eeb85c2407..9aac6c597cd9608c293b3d0f9b49c0db3fa5d9a4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -34,6 +34,7 @@ matrix: - psmisc - unixodbc - unixodbc-dev + - mono-complete before_script: - export TZ=Asia/Harbin @@ -59,6 +60,18 @@ matrix: pip3 install guppy3 pip3 install --user ${TRAVIS_BUILD_DIR}/src/connector/python/linux/python3/ + cd ${TRAVIS_BUILD_DIR}/tests/examples/C#/taosdemo + mcs -out:taosdemo *.cs || travis_terminate $? + pkill -TERM -x taosd + fuser -k -n tcp 6030 + sleep 1 + ${TRAVIS_BUILD_DIR}/debug/build/bin/taosd -c ${TRAVIS_BUILD_DIR}/debug/test/cfg > /dev/null & + sleep 5 + mono taosdemo -Q DEFAULT -y || travis_terminate $? + pkill -KILL -x taosd + fuser -k -n tcp 6030 + sleep 1 + cd ${TRAVIS_BUILD_DIR}/tests ./test-all.sh smoke || travis_terminate $? sleep 1 @@ -74,6 +87,7 @@ matrix: ./valgrind-test.sh 2>&1 > mem-error-out.log sleep 1 + # Color setting RED='\033[0;31m' GREEN='\033[1;32m' diff --git a/CMakeLists.txt b/CMakeLists.txt index ea704985d0d85051a331c2022f3b7a636501251c..73900af8525796876536ace233c9752fc555eece 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,4 @@ -CMAKE_MINIMUM_REQUIRED(VERSION 2.8) +CMAKE_MINIMUM_REQUIRED(VERSION 3.5) IF (CMAKE_VERSION VERSION_LESS 3.0) PROJECT(TDengine CXX) SET(PROJECT_VERSION_MAJOR "${LIB_MAJOR_VERSION}") diff --git a/deps/CMakeLists.txt b/deps/CMakeLists.txt index 8c6c73c4400da973726109aa66a50c97e3a2a6f6..1d725add214f0e96d1a60aa9b889899790a4aef1 100644 --- a/deps/CMakeLists.txt +++ b/deps/CMakeLists.txt @@ -1,4 +1,4 @@ -CMAKE_MINIMUM_REQUIRED(VERSION 2.8) +CMAKE_MINIMUM_REQUIRED(VERSION 3.5) PROJECT(TDengine) ADD_SUBDIRECTORY(zlib-1.2.11) diff --git a/deps/MQTT-C/CMakeLists.txt b/deps/MQTT-C/CMakeLists.txt index 15b35525210ec90e6e2efbdcd0e6128cb4d34f91..36ede467acfa05f893cbe99ed518458d57986c79 100644 --- a/deps/MQTT-C/CMakeLists.txt +++ b/deps/MQTT-C/CMakeLists.txt @@ -1,4 +1,4 @@ -CMAKE_MINIMUM_REQUIRED(VERSION 2.8) +CMAKE_MINIMUM_REQUIRED(VERSION 3.5) # MQTT-C build options option(MQTT_C_OpenSSL_SUPPORT "Build MQTT-C with OpenSSL support?" OFF) diff --git a/deps/MsvcLibX/CMakeLists.txt b/deps/MsvcLibX/CMakeLists.txt index 4428579e1c098425c9d72d7d58a5fda15cd34c93..c02e4c7a4d89cdf657756ec9786d5a624419d182 100644 --- a/deps/MsvcLibX/CMakeLists.txt +++ b/deps/MsvcLibX/CMakeLists.txt @@ -1,4 +1,4 @@ -CMAKE_MINIMUM_REQUIRED(VERSION 2.8) +CMAKE_MINIMUM_REQUIRED(VERSION 3.5) PROJECT(TDengine) IF (TD_WINDOWS) diff --git a/deps/iconv/CMakeLists.txt b/deps/iconv/CMakeLists.txt index 286070fa9071f8fcd1949850cec87c1ced3245d7..f26f109735ee81bc999b9539185ce60ccb976bfd 100644 --- a/deps/iconv/CMakeLists.txt +++ b/deps/iconv/CMakeLists.txt @@ -1,4 +1,4 @@ -CMAKE_MINIMUM_REQUIRED(VERSION 2.8) +CMAKE_MINIMUM_REQUIRED(VERSION 3.5) PROJECT(TDengine) IF (TD_WINDOWS) diff --git a/deps/pthread/CMakeLists.txt b/deps/pthread/CMakeLists.txt index 04e5be7472a9b8cbdb384348697b919bf2dd0ece..dcd9ed035814ac9efd66340b58b287ccbabe61df 100644 --- a/deps/pthread/CMakeLists.txt +++ b/deps/pthread/CMakeLists.txt @@ -1,4 +1,4 @@ -CMAKE_MINIMUM_REQUIRED(VERSION 2.8) +CMAKE_MINIMUM_REQUIRED(VERSION 3.5) PROJECT(TDengine) IF (TD_WINDOWS) diff --git a/deps/regex/CMakeLists.txt b/deps/regex/CMakeLists.txt index 054b093d07c386d7ff9b0ffc4c05909d79b33129..c7e983b992fe8a2dd21b8420e652358976663a37 100644 --- a/deps/regex/CMakeLists.txt +++ b/deps/regex/CMakeLists.txt @@ -1,4 +1,4 @@ -CMAKE_MINIMUM_REQUIRED(VERSION 2.8) +CMAKE_MINIMUM_REQUIRED(VERSION 3.5) PROJECT(TDengine) IF (TD_WINDOWS) diff --git a/deps/wepoll/CMakeLists.txt b/deps/wepoll/CMakeLists.txt index a81fd782bbc4b05a1158273a7fcc6701bc4d980d..a8b34112215fae0df7bcac034622015fd72d337b 100644 --- a/deps/wepoll/CMakeLists.txt +++ b/deps/wepoll/CMakeLists.txt @@ -1,4 +1,4 @@ -CMAKE_MINIMUM_REQUIRED(VERSION 2.8) +CMAKE_MINIMUM_REQUIRED(VERSION 3.5) PROJECT(TDengine) IF (TD_WINDOWS) diff --git a/deps/zlib-1.2.11/CMakeLists.txt b/deps/zlib-1.2.11/CMakeLists.txt index f83aa70085491fb6575c0a6bf93252192cddd040..a8750471d694bcfa98b711348861449e3fc7b23a 100644 --- a/deps/zlib-1.2.11/CMakeLists.txt +++ b/deps/zlib-1.2.11/CMakeLists.txt @@ -1,4 +1,4 @@ -CMAKE_MINIMUM_REQUIRED(VERSION 2.8) +CMAKE_MINIMUM_REQUIRED(VERSION 3.5) PROJECT(TDengine) IF (TD_WINDOWS) diff --git a/documentation20/webdocs/markdowndocs/TAOS SQL-ch.md b/documentation20/webdocs/markdowndocs/TAOS SQL-ch.md index f879c66e4e0d63c512abac3ebe54a2b290683097..bee3d99b2630e53c7a2154f0f605077bcc56b267 100644 --- a/documentation20/webdocs/markdowndocs/TAOS SQL-ch.md +++ b/documentation20/webdocs/markdowndocs/TAOS SQL-ch.md @@ -68,7 +68,9 @@ TDengine缺省的时间戳是毫秒精度,但通过修改配置参数enableMic 2) UPDATE 标志数据库支持更新相同时间戳数据; 3) 数据库名最大长度为33; + 4) 一条SQL 语句的最大长度为65480个字符; + 5) 数据库还有更多与存储相关的配置参数,请参见系统管理。 - **显示系统当前参数** @@ -130,19 +132,37 @@ TDengine缺省的时间戳是毫秒精度,但通过修改配置参数enableMic CREATE TABLE [IF NOT EXISTS] tb_name (timestamp_field_name TIMESTAMP, field1_name data_type1 [, field2_name data_type2 ...]); ``` 说明: + 1) 表的第一个字段必须是TIMESTAMP,并且系统自动将其设为主键; - 2) 表名最大长度为193; + + 2) 表名最大长度为192; + 3) 表的每行长度不能超过16k个字符; + 4) 子表名只能由字母、数字和下划线组成,且不能以数字开头 + 5) 使用数据类型binary或nchar,需指定其最长的字节数,如binary(20),表示20字节; - **以超级表为模板创建数据表** ```mysql - CREATE TABLE [IF NOT EXISTS] tb_name USING stb_name TAGS (tag_value1 [, tag_value2 ...]); + CREATE TABLE [IF NOT EXISTS] tb_name USING stb_name TAGS (tag_value1, ...); ``` 以指定的超级表为模板,指定 tags 的值来创建数据表。 +- **批量创建数据表** + + ```mysql + CREATE TABLE [IF NOT EXISTS] tb_name1 USING stb_name TAGS (tag_value1, ...) tb_name2 USING stb_name TAGS (tag_value2, ...) ...; + ``` + 以更快的速度批量创建大量数据表。(服务器端 2.0.14 及以上版本) + + 说明: + + 1)批量建表方式要求数据表必须以超级表为模板。 + + 2)在不超出 SQL 语句长度限制的前提下,单条语句中的建表数量建议控制在 1000~3000 之间,将会获得比较理想的建表速度。 + - **删除数据表** ```mysql @@ -155,7 +175,11 @@ TDengine缺省的时间戳是毫秒精度,但通过修改配置参数enableMic SHOW TABLES [LIKE tb_name_wildcar]; ``` - 显示当前数据库下的所有数据表信息。说明:可在 like 中使用通配符进行名称的匹配。 通配符匹配:1)“%”(百分号)匹配 0 到任意个字符;2)“\_”(下划线)匹配一个字符。 + 显示当前数据库下的所有数据表信息。 + + 说明:可在like中使用通配符进行名称的匹配,这一通配符字符串最长不能超过24字节。 + + 通配符匹配:1)’%’ (百分号)匹配0到任意个字符;2)’\_’下划线匹配一个字符。 - **在线修改显示字符宽度** @@ -175,8 +199,10 @@ TDengine缺省的时间戳是毫秒精度,但通过修改配置参数enableMic ALTER TABLE tb_name ADD COLUMN field_name data_type; ``` 说明: + 1) 列的最大个数为1024,最小个数为2; - 2) 列名最大长度为65; + + 2) 列名最大长度为64; - **表删除列** @@ -194,9 +220,13 @@ TDengine缺省的时间戳是毫秒精度,但通过修改配置参数enableMic 创建STable, 与创建表的SQL语法相似,但需指定TAGS字段的名称和类型 说明: + 1) TAGS 列的数据类型不能是timestamp类型; + 2) TAGS 列名不能与其他列名相同; + 3) TAGS 列名不能为预留关键字; + 4) TAGS 最多允许128个,至少1个,总长度不超过16k个字符。 - **删除超级表** @@ -323,7 +353,9 @@ SELECT select_expr [, select_expr ...] [LIMIT limit_val [, OFFSET offset_val]] [>> export_file] ``` + 说明:针对 insert 类型的 SQL 语句,我们采用的流式解析策略,在发现后面的错误之前,前面正确的部分SQL仍会执行。下面的sql中,insert语句是无效的,但是d1001仍会被创建。 + ```mysql taos> CREATE TABLE meters(ts TIMESTAMP, current FLOAT, voltage INT, phase FLOAT) TAGS(location BINARY(30), groupId INT); Query OK, 0 row(s) affected (0.008245s) @@ -604,10 +636,20 @@ TDengine支持针对数据的聚合查询。提供支持的聚合和选择函数 SELECT COUNT([*|field_name]) FROM tb_name [WHERE clause]; ``` 功能说明:统计表/超级表中记录行数或某列的非空值个数。 + 返回结果数据类型:长整型INT64。 + 应用字段:应用全部字段。 + 适用于:表、超级表。 - 说明:1)可以使用星号*来替代具体的字段,使用星号(*)返回全部记录数量。2)针对同一表的(不包含NULL值)字段查询结果均相同。3)如果统计对象是具体的列,则返回该列中非NULL值的记录数量。 + + 说明: + + 1)可以使用星号*来替代具体的字段,使用星号(*)返回全部记录数量。 + + 2)针对同一表的(不包含NULL值)字段查询结果均相同。 + + 3)如果统计对象是具体的列,则返回该列中非NULL值的记录数量。 示例: ```mysql @@ -629,8 +671,11 @@ TDengine支持针对数据的聚合查询。提供支持的聚合和选择函数 SELECT AVG(field_name) FROM tb_name [WHERE clause]; ``` 功能说明:统计表/超级表中某列的平均值。 + 返回结果数据类型:双精度浮点数Double。 + 应用字段:不能应用在timestamp、binary、nchar、bool字段。 + 适用于:表、超级表。 示例: @@ -653,9 +698,11 @@ TDengine支持针对数据的聚合查询。提供支持的聚合和选择函数 SELECT TWA(field_name) FROM tb_name WHERE clause; ``` 功能说明:时间加权平均函数。统计表/超级表中某列在一段时间内的时间加权平均。 + 返回结果数据类型:双精度浮点数Double。 + 应用字段:不能应用在timestamp、binary、nchar、bool类型字段。 - 说明:时间加权平均(time weighted average, TWA)查询需要指定查询时间段的 _开始时间_ 和 _结束时间_ 。 + 适用于:表、超级表。 - **SUM** @@ -663,8 +710,11 @@ TDengine支持针对数据的聚合查询。提供支持的聚合和选择函数 SELECT SUM(field_name) FROM tb_name [WHERE clause]; ``` 功能说明:统计表/超级表中某列的和。 + 返回结果数据类型:双精度浮点数Double和长整型INT64。 + 应用字段:不能应用在timestamp、binary、nchar、bool类型字段。 + 适用于:表、超级表。 示例: @@ -687,8 +737,11 @@ TDengine支持针对数据的聚合查询。提供支持的聚合和选择函数 SELECT STDDEV(field_name) FROM tb_name [WHERE clause]; ``` 功能说明:统计表中某列的均方差。 + 返回结果数据类型:双精度浮点数Double。 + 应用字段:不能应用在timestamp、binary、nchar、bool类型字段。 + 适用于:表。 示例: @@ -705,9 +758,13 @@ TDengine支持针对数据的聚合查询。提供支持的聚合和选择函数 SELECT LEASTSQUARES(field_name, start_val, step_val) FROM tb_name [WHERE clause]; ``` 功能说明:统计表中某列的值是主键(时间戳)的拟合直线方程。start_val是自变量初始值,step_val是自变量的步长值。 + 返回结果数据类型:字符串表达式(斜率, 截距)。 + 应用字段:不能应用在timestamp、binary、nchar、bool类型字段。 + 说明:自变量是时间戳,因变量是该列的值。 + 适用于:表。 示例: @@ -726,7 +783,9 @@ TDengine支持针对数据的聚合查询。提供支持的聚合和选择函数 SELECT MIN(field_name) FROM {tb_name | stb_name} [WHERE clause]; ``` 功能说明:统计表/超级表中某列的值最小值。 + 返回结果数据类型:同应用的字段。 + 应用字段:不能应用在timestamp、binary、nchar、bool类型字段。 示例: @@ -749,7 +808,9 @@ TDengine支持针对数据的聚合查询。提供支持的聚合和选择函数 SELECT MAX(field_name) FROM { tb_name | stb_name } [WHERE clause]; ``` 功能说明:统计表/超级表中某列的值最大值。 + 返回结果数据类型:同应用的字段。 + 应用字段:不能应用在timestamp、binary、nchar、bool类型字段。 示例: @@ -772,9 +833,18 @@ TDengine支持针对数据的聚合查询。提供支持的聚合和选择函数 SELECT FIRST(field_name) FROM { tb_name | stb_name } [WHERE clause]; ``` 功能说明:统计表/超级表中某列的值最先写入的非NULL值。 + 返回结果数据类型:同应用的字段。 + 应用字段:所有字段。 - 说明:1)如果要返回各个列的首个(时间戳最小)非NULL值,可以使用FIRST(\*);2) 如果结果集中的某列全部为NULL值,则该列的返回结果也是NULL;3) 如果结果集中所有列全部为NULL值,则不返回结果。 + + 说明: + + 1)如果要返回各个列的首个(时间戳最小)非NULL值,可以使用FIRST(\*); + + 2) 如果结果集中的某列全部为NULL值,则该列的返回结果也是NULL; + + 3) 如果结果集中所有列全部为NULL值,则不返回结果。 示例: ```mysql @@ -796,9 +866,16 @@ TDengine支持针对数据的聚合查询。提供支持的聚合和选择函数 SELECT LAST(field_name) FROM { tb_name | stb_name } [WHERE clause]; ``` 功能说明:统计表/超级表中某列的值最后写入的非NULL值。 + 返回结果数据类型:同应用的字段。 + 应用字段:所有字段。 - 说明:1)如果要返回各个列的最后(时间戳最大)一个非NULL值,可以使用LAST(\*);2)如果结果集中的某列全部为NULL值,则该列的返回结果也是NULL;如果结果集中所有列全部为NULL值,则不返回结果。 + + 说明: + + 1)如果要返回各个列的最后(时间戳最大)一个非NULL值,可以使用LAST(\*); + + 2)如果结果集中的某列全部为NULL值,则该列的返回结果也是NULL;如果结果集中所有列全部为NULL值,则不返回结果。 示例: ```mysql @@ -820,9 +897,16 @@ TDengine支持针对数据的聚合查询。提供支持的聚合和选择函数 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)系统同时返回该记录关联的时间戳列。 + + 说明: + + 1)*k*值取值范围1≤*k*≤100; + + 2)系统同时返回该记录关联的时间戳列。 示例: ```mysql @@ -847,9 +931,16 @@ TDengine支持针对数据的聚合查询。提供支持的聚合和选择函数 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)系统同时返回该记录关联的时间戳列。 + + 说明: + + 1)*k*值取值范围1≤*k*≤100; + + 2)系统同时返回该记录关联的时间戳列。 示例: ```mysql @@ -873,8 +964,11 @@ TDengine支持针对数据的聚合查询。提供支持的聚合和选择函数 SELECT PERCENTILE(field_name, P) FROM { tb_name } [WHERE clause]; ``` 功能说明:统计表中某列的值百分比分位数。 + 返回结果数据类型: 双精度浮点数Double。 + 应用字段:不能应用在timestamp、binary、nchar、bool类型字段。 + 说明:*P*值取值范围0≤*P*≤100,为0的时候等同于MIN,为100的时候等同于MAX。 示例: @@ -891,9 +985,13 @@ TDengine支持针对数据的聚合查询。提供支持的聚合和选择函数 SELECT APERCENTILE(field_name, P) FROM { tb_name | stb_name } [WHERE clause]; ``` 功能说明:统计表中某列的值百分比分位数,与PERCENTILE函数相似,但是返回近似结果。 + 返回结果数据类型: 双精度浮点数Double。 + 应用字段:不能应用在timestamp、binary、nchar、bool类型字段。 + 说明:*P*值取值范围0≤*P*≤100,为0的时候等同于MIN,为100的时候等同于MAX。推荐使用```APERCENTILE```函数,该函数性能远胜于```PERCENTILE```函数 + ```mysql taos> SELECT APERCENTILE(current, 20) FROM d1001; apercentile(current, 20) | @@ -907,8 +1005,11 @@ TDengine支持针对数据的聚合查询。提供支持的聚合和选择函数 SELECT LAST_ROW(field_name) FROM { tb_name | stb_name }; ``` 功能说明:返回表(超级表)的最后一条记录。 + 返回结果数据类型:同应用的字段。 + 应用字段:所有字段。 + 说明:与last函数不同,last_row不支持时间范围限制,强制返回最后一条记录。 示例: @@ -932,8 +1033,11 @@ TDengine支持针对数据的聚合查询。提供支持的聚合和选择函数 SELECT DIFF(field_name) FROM tb_name [WHERE clause]; ``` 功能说明:统计表中某列的值与前一行对应值的差。 + 返回结果数据类型: 同应用字段。 + 应用字段:不能应用在timestamp、binary、nchar、bool类型字段。 + 说明:输出结果行数是范围内总行数减一,第一行没有结果输出。 示例: @@ -951,8 +1055,11 @@ TDengine支持针对数据的聚合查询。提供支持的聚合和选择函数 SELECT SPREAD(field_name) FROM { tb_name | stb_name } [WHERE clause]; ``` 功能说明:统计表/超级表中某列的最大值和最小值之差。 + 返回结果数据类型: 双精度浮点数。 + 应用字段:不能应用在binary、nchar、bool类型字段。 + 说明:可用于TIMESTAMP字段,此时表示记录的时间覆盖范围。 示例: @@ -976,9 +1083,16 @@ TDengine支持针对数据的聚合查询。提供支持的聚合和选择函数 SELECT field_name [+|-|*|/|%][Value|field_name] FROM { tb_name | stb_name } [WHERE clause]; ``` 功能说明:统计表/超级表中某列或多列间的值加、减、乘、除、取余计算结果。 + 返回结果数据类型:双精度浮点数。 + 应用字段:不能应用在timestamp、binary、nchar、bool类型字段。 - 说明:1)支持两列或多列之间进行计算,可使用括号控制计算优先级;2)NULL字段不参与计算,如果参与计算的某行中包含NULL,该行的计算结果为NULL。 + + 说明: + + 1)支持两列或多列之间进行计算,可使用括号控制计算优先级; + + 2)NULL字段不参与计算,如果参与计算的某行中包含NULL,该行的计算结果为NULL。 ```mysql taos> SELECT current + voltage * phase FROM d1001; diff --git a/documentation20/webdocs/markdowndocs/administrator-ch.md b/documentation20/webdocs/markdowndocs/administrator-ch.md index 383822789f5dbd08133affafd23963d52ebbda9f..9eee5b2b69cad573f62a1fa4890ff73c43026bd1 100644 --- a/documentation20/webdocs/markdowndocs/administrator-ch.md +++ b/documentation20/webdocs/markdowndocs/administrator-ch.md @@ -255,7 +255,7 @@ taos -C 或 taos --dump-config CREATE USER PASS <'password'>; ``` -创建用户,并指定用户名和密码,密码需要用单引号引起来,单引号为英文半角 +创建用户,并指定用户名和密码,密码需要用单引号引起来,单引号为英文半角 ```sql DROP USER ; @@ -267,13 +267,15 @@ DROP USER ; ALTER USER PASS <'password'>; ``` -修改用户密码, 为避免被转换为小写,密码需要用单引号引用,单引号为英文半角 +修改用户密码,为避免被转换为小写,密码需要用单引号引用,单引号为英文半角 ```sql -ALTER USER PRIVILEGE ; +ALTER USER PRIVILEGE ; ``` -修改用户权限为:super/write/read,不需要添加单引号 +修改用户权限为:write 或 read,不需要添加单引号 + +说明:系统内共有 super/write/read 三种权限级别,但目前不允许通过 alter 指令把 super 权限赋予用户。 ```mysql SHOW USERS; @@ -432,11 +434,12 @@ TDengine的所有可执行文件默认存放在 _/usr/local/taos/bin_ 目录下 - 数据库名:不能包含“.”以及特殊字符,不能超过32个字符 - 表名:不能包含“.”以及特殊字符,与所属数据库名一起,不能超过192个字符 - 表的列名:不能包含特殊字符,不能超过64个字符 +- 数据库名、表名、列名,都不能以数字开头 - 表的列数:不能超过1024列 - 记录的最大长度:包括时间戳8 byte,不能超过16KB - 单条SQL语句默认最大字符串长度:65480 byte - 数据库副本数:不能超过3 -- 用户名:不能超过20个byte +- 用户名:不能超过23个byte - 用户密码:不能超过15个byte - 标签(Tags)数量:不能超过128个 - 标签的总长度:不能超过16Kbyte diff --git a/documentation20/webdocs/markdowndocs/cluster.md b/documentation20/webdocs/markdowndocs/cluster.md index f5fa6af48c9bb0a4062c9de74ee3555561ac26ba..08206a85a8954689efb824fed6ed7e9572000a0b 100644 --- a/documentation20/webdocs/markdowndocs/cluster.md +++ b/documentation20/webdocs/markdowndocs/cluster.md @@ -89,6 +89,8 @@ SHOW DNODES; ``` 它将列出集群中所有的dnode,每个dnode的fqdn:port, 状态(ready, offline等),vnode数目,还未使用的vnode数目等信息。在添加或删除一个节点后,可以使用该命令查看。 +如果集群配置了Arbitrator,那么它也会在这个节点列表中显示出来,其role列的值会是“arb”。 + ###查看虚拟节点组 为充分利用多核技术,并提供scalability,数据需要分片处理。因此TDengine会将一个DB的数据切分成多份,存放在多个vnode里。这些vnode可能分布在多个dnode里,这样就实现了水平扩展。一个vnode仅仅属于一个DB,但一个DB可以有多个vnode。vnode的是mnode根据当前系统资源的情况,自动进行分配的,无需任何人工干预。 @@ -139,4 +141,6 @@ SHOW MNODES; 如果副本数为偶数,当一个vnode group里一半vnode不工作时,是无法从中选出master的。同理,一半mnode不工作时,是无法选出mnode的master的,因为存在“split brain”问题。为解决这个问题,TDengine引入了arbitrator的概念。Arbitrator模拟一个vnode或mnode在工作,但只简单的负责网络连接,不处理任何数据插入或访问。只要包含arbitrator在内,超过半数的vnode或mnode工作,那么该vnode group或mnode组就可以正常的提供数据插入或查询服务。比如对于副本数为2的情形,如果一个节点A离线,但另外一个节点B正常,而且能连接到arbitrator, 那么节点B就能正常工作。 -TDengine安装包里带有一个执行程序tarbitrator, 找任何一台Linux服务器运行它即可。该程序对系统资源几乎没有要求,只需要保证有网络连接即可。该应用的命令行参数`-p`可以指定其对外服务的端口号,缺省是6030。配置每个taosd实例时,可以在配置文件taos.cfg里将参数arbitrator设置为arbitrator的End Point。如果该参数配置了,当副本数为偶数数,系统将自动连接配置的arbitrator。 +TDengine安装包里带有一个执行程序tarbitrator, 找任何一台Linux服务器运行它即可。该程序对系统资源几乎没有要求,只需要保证有网络连接即可。该应用的命令行参数`-p`可以指定其对外服务的端口号,缺省是6030。配置每个taosd实例时,可以在配置文件taos.cfg里将参数arbitrator设置为Arbitrator的End Point。如果该参数配置了,当副本数为偶数数,系统将自动连接配置的Arbitrator。 + +在配置了Arbitrator的情况下,它也会显示在“show dnodes;”指令给出的节点列表中。 diff --git a/documentation20/webdocs/markdowndocs/connector-ch.md b/documentation20/webdocs/markdowndocs/connector-ch.md index 7848ceabc49d618bc5fbc332e3ed1803188bc783..da9c2e5a119e56243e517e9de0e248184d3c3c93 100644 --- a/documentation20/webdocs/markdowndocs/connector-ch.md +++ b/documentation20/webdocs/markdowndocs/connector-ch.md @@ -252,7 +252,7 @@ C/C++的API类似于MySQL的C API。应用程序使用时,需要包含TDengine - `void taos_free_result(TAOS_RES *res)` - 释放查询结果集以及相关的资源。查询完成后,务必调用该API释放资源,否则可能导致应用内存泄露。 + 释放查询结果集以及相关的资源。查询完成后,务必调用该API释放资源,否则可能导致应用内存泄露。但也需注意,释放资源后,如果再调用`taos_consume`等获取查询结果的函数,将导致应用Crash。 - `char *taos_errstr(TAOS_RES *res)` @@ -262,11 +262,11 @@ C/C++的API类似于MySQL的C API。应用程序使用时,需要包含TDengine 获取最近一次API调用失败的原因,返回值为错误代码。 -**注意**:对于每个数据库应用,2.0及以上版本 TDengine 推荐只建立一个连接。同时在应用中将该连接 (TAOS*) 结构体传递到不同的线程共享使用。基于 TAOS 结构体发出的查询、写入等操作具有多线程安全性。C 语言的连接器可以按照需求动态建立面向数据库的新连接(该过程对用户不可见),同时建议只有在程序最后退出的时候才调用 taos_close 关闭连接。 +**注意**:2.0及以上版本 TDengine 推荐数据库应用的每个线程都建立一个独立的连接,或基于线程建立连接池。而不推荐在应用中将该连接 (TAOS\*) 结构体传递到不同的线程共享使用。基于 TAOS 结构体发出的查询、写入等操作具有多线程安全性,但 “USE statement” 等状态量有可能在线程之间相互干扰。此外,C 语言的连接器可以按照需求动态建立面向数据库的新连接(该过程对用户不可见),同时建议只有在程序最后退出的时候才调用 taos_close 关闭连接。 ### 异步查询API -同步API之外,TDengine还提供性能更高的异步调用API处理数据插入、查询操作。在软硬件环境相同的情况下,异步API处理数据插入的速度比同步API快2~4倍。异步API采用非阻塞式的调用方式,在系统真正完成某个具体数据库操作前,立即返回。调用的线程可以去处理其他工作,从而可以提升整个应用的性能。异步API在网络延迟严重的情况下,优点尤为突出。 +同步API之外,TDengine还提供性能更高的异步调用API处理数据插入、查询操作。在软硬件环境相同的情况下,异步API处理数据插入的速度比同步API快2\~4倍。异步API采用非阻塞式的调用方式,在系统真正完成某个具体数据库操作前,立即返回。调用的线程可以去处理其他工作,从而可以提升整个应用的性能。异步API在网络延迟严重的情况下,优点尤为突出。 异步API都需要应用提供相应的回调函数,回调函数参数设置如下:前两个参数都是一致的,第三个参数依不同的API而定。第一个参数param是应用调用异步API时提供给系统的,用于回调时,应用能够找回具体操作的上下文,依具体实现而定。第二个参数是SQL操作的结果集,如果为空,比如insert操作,表示没有记录返回,如果不为空,比如select操作,表示有记录返回。 @@ -425,7 +425,7 @@ cd C:\TDengine\connector\python\windows python -m pip install python3\ ``` -*如果机器上没有pip命令,用户可将src/connector/python/python3或src/connector/python/python2下的taos文件夹拷贝到应用程序的目录使用。 +* 如果机器上没有pip命令,用户可将src/connector/python/python3或src/connector/python/python2下的taos文件夹拷贝到应用程序的目录使用。 对于windows 客户端,安装TDengine windows 客户端后,将C:\TDengine\driver\taos.dll拷贝到C:\windows\system32目录下即可。 ### 使用 @@ -442,7 +442,7 @@ import taos conn = taos.connect(host="127.0.0.1", user="root", password="taosdata", config="/etc/taos") c1 = conn.cursor() ``` -*host 是TDengine 服务端所有IP, config 为客户端配置文件所在目录 +* host 是TDengine 服务端所有IP, config 为客户端配置文件所在目录 * 写入数据 ```python @@ -510,17 +510,17 @@ conn.close() 用户可通过python的帮助信息直接查看模块的使用信息,或者参考tests/examples/python中的示例程序。以下为部分常用类和方法: -- _TDengineConnection_类 +- _TDengineConnection_ 类 参考python中help(taos.TDengineConnection)。 - 这个类对应客户端和TDengine建立的一个连接。在客户端多线程的场景下,这个连接实例可以是每个线程申请一个,也可以多线程共享一个连接。 + 这个类对应客户端和TDengine建立的一个连接。在客户端多线程的场景下,推荐每个线程申请一个独立的连接实例,而不建议多线程共享一个连接。 -- _TDengineCursor_类 +- _TDengineCursor_ 类 参考python中help(taos.TDengineCursor)。 这个类对应客户端进行的写入、查询操作。在客户端多线程的场景下,这个游标实例必须保持线程独享,不能夸线程共享使用,否则会导致返回结果出现错误。 -- _connect_方法 +- _connect_ 方法 用于生成taos.TDengineConnection的实例。 @@ -800,7 +800,7 @@ go env -w GOPROXY=https://goproxy.io,direct - `sql.Open(DRIVER_NAME string, dataSourceName string) *DB` - 该API用来打开DB,返回一个类型为*DB的对象,一般情况下,DRIVER_NAME设置为字符串`taosSql`, dataSourceName设置为字符串`user:password@/tcp(host:port)/dbname`,如果客户想要用多个goroutine并发访问TDengine, 那么需要在各个goroutine中分别创建一个sql.Open对象并用之访问TDengine + 该API用来打开DB,返回一个类型为\*DB的对象,一般情况下,DRIVER_NAME设置为字符串`taosSql`, dataSourceName设置为字符串`user:password@/tcp(host:port)/dbname`,如果客户想要用多个goroutine并发访问TDengine, 那么需要在各个goroutine中分别创建一个sql.Open对象并用之访问TDengine **注意**: 该API成功创建的时候,并没有做权限等检查,只有在真正执行Query或者Exec的时候才能真正的去创建连接,并同时检查user/password/host/port是不是合法。 另外,由于整个驱动程序大部分实现都下沉到taosSql所依赖的libtaos中。所以,sql.Open本身特别轻量。 @@ -822,7 +822,7 @@ go env -w GOPROXY=https://goproxy.io,direct - `func (s *Stmt) Query(args ...interface{}) (*Rows, error)` - sql.Open内置的方法,Query executes a prepared query statement with the given arguments and returns the query results as a *Rows. + sql.Open内置的方法,Query executes a prepared query statement with the given arguments and returns the query results as a \*Rows. - `func (s *Stmt) Close() error` @@ -894,7 +894,7 @@ Node-example-raw.js 验证方法: -1. 新建安装验证目录,例如:~/tdengine-test,拷贝github上nodejsChecker.js源程序。下载地址:(https://github.com/taosdata/TDengine/tree/develop/tests/examples/nodejs/nodejsChecker.js)。 +1. 新建安装验证目录,例如:\~/tdengine-test,拷贝github上nodejsChecker.js源程序。下载地址:(https://github.com/taosdata/TDengine/tree/develop/tests/examples/nodejs/nodejsChecker.js)。 2. 在命令中执行以下命令: diff --git a/packaging/cfg/taos.cfg b/packaging/cfg/taos.cfg index 73fa915abdde8e0940f142fc56124f66e32a6d25..ccce496d2dc0767ed65b54415d6c9b096a839875 100644 --- a/packaging/cfg/taos.cfg +++ b/packaging/cfg/taos.cfg @@ -72,9 +72,6 @@ # time interval of heart beat from shell to dnode, seconds # shellActivityTimer 3 -# time of keeping table meta data in cache, seconds -# tableMetaKeepTimer 7200 - # minimum sliding window time, milli-second # minSlidingTime 10 diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index b0f2cc0a48f906b40d7be5185ae5f081c2ed4418..d67aba4b66be6ec2f13e994248c8214178b55663 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,4 +1,4 @@ -CMAKE_MINIMUM_REQUIRED(VERSION 2.8) +CMAKE_MINIMUM_REQUIRED(VERSION 3.5) PROJECT(TDengine) # Base compile diff --git a/src/balance/CMakeLists.txt b/src/balance/CMakeLists.txt index 6c26e50b873d30b95c67a7988e83140106f609eb..fdc43ea32fd8913b984005f30621a801e50c45d4 100644 --- a/src/balance/CMakeLists.txt +++ b/src/balance/CMakeLists.txt @@ -1,4 +1,4 @@ -CMAKE_MINIMUM_REQUIRED(VERSION 2.8) +CMAKE_MINIMUM_REQUIRED(VERSION 3.5) PROJECT(TDengine) INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/src/mnode/inc) diff --git a/src/client/CMakeLists.txt b/src/client/CMakeLists.txt index daf7c5e5349f42730721b3f2b6baad5d0485361e..4049c0d72908486d289631362c19e7caa25f99f8 100644 --- a/src/client/CMakeLists.txt +++ b/src/client/CMakeLists.txt @@ -1,4 +1,4 @@ -CMAKE_MINIMUM_REQUIRED(VERSION 2.8) +CMAKE_MINIMUM_REQUIRED(VERSION 3.5) PROJECT(TDengine) INCLUDE_DIRECTORIES(inc) diff --git a/src/client/inc/tscSubquery.h b/src/client/inc/tscSubquery.h index d3996ccf7fe85a6405addfcbef023aa2ae6bf08b..43c9b009bfdc537b033b7cffbe00bb673c627847 100644 --- a/src/client/inc/tscSubquery.h +++ b/src/client/inc/tscSubquery.h @@ -43,6 +43,11 @@ TAOS_ROW doSetResultRowData(SSqlObj *pSql); char *getArithmeticInputSrc(void *param, const char *name, int32_t colId); +void tscLockByThread(int64_t *lockedBy); + +void tscUnlockByThread(int64_t *lockedBy); + + #ifdef __cplusplus } #endif diff --git a/src/client/inc/tsclient.h b/src/client/inc/tsclient.h index a3a086ce779701e8a7c31c3c7fb4e398f95d97ba..900fab53a2f6c93933f50e11307d92ce7393960c 100644 --- a/src/client/inc/tsclient.h +++ b/src/client/inc/tsclient.h @@ -300,8 +300,8 @@ typedef struct STscObj { void * pTimer; char user[TSDB_USER_LEN]; char pass[TSDB_KEY_LEN]; - char acctId[TSDB_ACCT_LEN]; - char db[TSDB_ACCT_LEN + TSDB_DB_NAME_LEN]; + char acctId[TSDB_ACCT_ID_LEN]; + char db[TSDB_ACCT_ID_LEN + TSDB_DB_NAME_LEN]; char sversion[TSDB_VERSION_LEN]; char writeAuth : 1; char superAuth : 1; @@ -347,6 +347,11 @@ typedef struct SSqlObj { SSubqueryState subState; struct SSqlObj **pSubs; + int64_t metaRid; + int64_t svgroupRid; + + int64_t squeryLock; + struct SSqlObj *prev, *next; int64_t self; } SSqlObj; diff --git a/src/client/src/tscAsync.c b/src/client/src/tscAsync.c index b4dd8d77148e4289fcd94fe195f29b858a2c8067..37207858a80786d60c97397bb7d579be0e25d685 100644 --- a/src/client/src/tscAsync.c +++ b/src/client/src/tscAsync.c @@ -402,8 +402,10 @@ void tscAsyncResultOnError(SSqlObj *pSql) { int tscSendMsgToServer(SSqlObj *pSql); void tscTableMetaCallBack(void *param, TAOS_RES *res, int code) { - SSqlObj *pSql = (SSqlObj *)param; - if (pSql == NULL || pSql->signature != pSql) return; + SSqlObj* pSql = (SSqlObj*)taosAcquireRef(tscObjRef, (int64_t)param); + if (pSql == NULL) return; + + assert(pSql->signature == pSql && (int64_t)param == pSql->self); SSqlCmd *pCmd = &pSql->cmd; SSqlRes *pRes = &pSql->res; @@ -428,7 +430,8 @@ void tscTableMetaCallBack(void *param, TAOS_RES *res, int code) { code = tscGetTableMeta(pSql, pTableMetaInfo); assert(code == TSDB_CODE_TSC_ACTION_IN_PROGRESS || code == TSDB_CODE_SUCCESS); - if (code == TSDB_CODE_TSC_ACTION_IN_PROGRESS) { + if (code == TSDB_CODE_TSC_ACTION_IN_PROGRESS) { + taosReleaseRef(tscObjRef, pSql->self); return; } @@ -436,6 +439,7 @@ void tscTableMetaCallBack(void *param, TAOS_RES *res, int code) { // tscProcessSql can add error into async res tscProcessSql(pSql); + taosReleaseRef(tscObjRef, pSql->self); return; } else { // continue to process normal async query if (pCmd->parseFinished) { @@ -446,6 +450,7 @@ void tscTableMetaCallBack(void *param, TAOS_RES *res, int code) { assert(code == TSDB_CODE_TSC_ACTION_IN_PROGRESS || code == TSDB_CODE_SUCCESS); if (code == TSDB_CODE_TSC_ACTION_IN_PROGRESS) { + taosReleaseRef(tscObjRef, pSql->self); return; } @@ -458,6 +463,7 @@ void tscTableMetaCallBack(void *param, TAOS_RES *res, int code) { code = tsParseSql(pSql, true); if (code == TSDB_CODE_TSC_ACTION_IN_PROGRESS) { + taosReleaseRef(tscObjRef, pSql->self); return; } else if (code != TSDB_CODE_SUCCESS) { goto _error; @@ -468,12 +474,14 @@ void tscTableMetaCallBack(void *param, TAOS_RES *res, int code) { tscProcessSql(pSql); } + taosReleaseRef(tscObjRef, pSql->self); return; } else { tscDebug("%p continue parse sql after get table meta", pSql); code = tsParseSql(pSql, false); if (code == TSDB_CODE_TSC_ACTION_IN_PROGRESS) { + taosReleaseRef(tscObjRef, pSql->self); return; } else if (code != TSDB_CODE_SUCCESS) { goto _error; @@ -483,12 +491,14 @@ void tscTableMetaCallBack(void *param, TAOS_RES *res, int code) { STableMetaInfo* pTableMetaInfo = tscGetTableMetaInfoFromCmd(pCmd, pCmd->clauseIndex, 0); code = tscGetTableMeta(pSql, pTableMetaInfo); if (code == TSDB_CODE_TSC_ACTION_IN_PROGRESS) { + taosReleaseRef(tscObjRef, pSql->self); return; } else { assert(code == TSDB_CODE_SUCCESS); } (*pSql->fp)(pSql->param, pSql, code); + taosReleaseRef(tscObjRef, pSql->self); return; } @@ -501,6 +511,7 @@ void tscTableMetaCallBack(void *param, TAOS_RES *res, int code) { code = tscGetTableMeta(pSql, pTableMetaInfo); if (code == TSDB_CODE_TSC_ACTION_IN_PROGRESS) { + taosReleaseRef(tscObjRef, pSql->self); return; } else if (code != TSDB_CODE_SUCCESS) { goto _error; @@ -509,6 +520,7 @@ void tscTableMetaCallBack(void *param, TAOS_RES *res, int code) { if (UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo)) { code = tscGetSTableVgroupInfo(pSql, pCmd->clauseIndex); if (code == TSDB_CODE_TSC_ACTION_IN_PROGRESS) { + taosReleaseRef(tscObjRef, pSql->self); return; } else if (code != TSDB_CODE_SUCCESS) { goto _error; @@ -521,10 +533,16 @@ void tscTableMetaCallBack(void *param, TAOS_RES *res, int code) { } (*pSql->fp)(pSql->param, pSql, code); + + taosReleaseRef(tscObjRef, pSql->self); + return; } tscDoQuery(pSql); + + taosReleaseRef(tscObjRef, pSql->self); + return; _error: @@ -532,4 +550,6 @@ void tscTableMetaCallBack(void *param, TAOS_RES *res, int code) { pSql->res.code = code; tscAsyncResultOnError(pSql); } + + taosReleaseRef(tscObjRef, pSql->self); } diff --git a/src/client/src/tscParseInsert.c b/src/client/src/tscParseInsert.c index dbb807ad06c6af061c5d966144a71ee552285fd4..7151c33393577e877dd011b27df44dfc69be089d 100644 --- a/src/client/src/tscParseInsert.c +++ b/src/client/src/tscParseInsert.c @@ -762,6 +762,8 @@ static int32_t tscCheckIfCreateTable(char **sqlstr, SSqlObj *pSql) { char *sql = *sqlstr; + pSql->cmd.autoCreated = false; + // get the token of specified table index = 0; tableToken = tStrGetToken(sql, &index, false, 0, NULL); @@ -945,11 +947,15 @@ static int32_t tscCheckIfCreateTable(char **sqlstr, SSqlObj *pSql) { SKVRow row = tdGetKVRowFromBuilder(&kvRowBuilder); tdDestroyKVRowBuilder(&kvRowBuilder); if (row == NULL) { - return TSDB_CODE_TSC_OUT_OF_MEMORY; + return tscInvalidSQLErrMsg(pCmd->payload, "tag value expected", NULL); } tdSortKVRowByColIdx(row); pCmd->tagData.dataLen = kvRowLen(row); + if (pCmd->tagData.dataLen <= 0){ + return tscInvalidSQLErrMsg(pCmd->payload, "tag value expected", NULL); + } + char* pTag = realloc(pCmd->tagData.data, pCmd->tagData.dataLen); if (pTag == NULL) { return TSDB_CODE_TSC_OUT_OF_MEMORY; diff --git a/src/client/src/tscSQLParser.c b/src/client/src/tscSQLParser.c index a08482f57068496f11ab28c81aee24ace67999df..ffb2927cbdbd15023572912551dfcf3646b1e60e 100644 --- a/src/client/src/tscSQLParser.c +++ b/src/client/src/tscSQLParser.c @@ -221,7 +221,7 @@ static int32_t handlePassword(SSqlCmd* pCmd, SStrToken* pPwd) { return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg1); } - if (pPwd->n >= TSDB_PASSWORD_LEN) { + if (pPwd->n >= TSDB_KEY_LEN) { return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2); } @@ -1242,7 +1242,7 @@ int32_t setObjFullName(char* fullName, const char* account, SStrToken* pDB, SStr /* db name is not specified, the tableName dose not include db name */ if (pDB != NULL) { - if (pDB->n >= TSDB_ACCT_LEN + TSDB_DB_NAME_LEN || pDB->n == 0) { + if (pDB->n >= TSDB_ACCT_ID_LEN + TSDB_DB_NAME_LEN || pDB->n == 0) { return TSDB_CODE_TSC_INVALID_SQL; } @@ -6022,9 +6022,9 @@ int32_t tscCheckCreateDbParams(SSqlCmd* pCmd, SCreateDbMsg* pCreate) { } if (pCreate->quorum != -1 && - (pCreate->quorum < TSDB_MIN_DB_REPLICA_OPTION || pCreate->quorum > TSDB_MAX_DB_REPLICA_OPTION)) { + (pCreate->quorum < TSDB_MIN_DB_QUORUM_OPTION || pCreate->quorum > TSDB_MAX_DB_QUORUM_OPTION)) { snprintf(msg, tListLen(msg), "invalid db option quorum: %d valid range: [%d, %d]", pCreate->quorum, - TSDB_MIN_DB_REPLICA_OPTION, TSDB_MAX_DB_REPLICA_OPTION); + TSDB_MIN_DB_QUORUM_OPTION, TSDB_MAX_DB_QUORUM_OPTION); return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg); } @@ -6101,7 +6101,9 @@ void tscPrintSelectClause(SSqlObj* pSql, int32_t subClauseIndex) { int32_t tmpLen = 0; tmpLen = sprintf(tmpBuf, "%s(uid:%" PRId64 ", %d)", aAggs[pExpr->functionId].aName, pExpr->uid, pExpr->colInfo.colId); - if (tmpLen + offset > totalBufSize) break; + + if (tmpLen + offset >= totalBufSize - 1) break; + offset += sprintf(str + offset, "%s", tmpBuf); @@ -6110,7 +6112,9 @@ void tscPrintSelectClause(SSqlObj* pSql, int32_t subClauseIndex) { } } + assert(offset < totalBufSize); str[offset] = ']'; + assert(offset < totalBufSize); tscDebug("%p select clause:%s", pSql, str); } diff --git a/src/client/src/tscServer.c b/src/client/src/tscServer.c index cc2621958f0713967b3a8aa62328c0212a062a5a..15dd77faebdb4167a9d13f21b2606a0946199b8e 100644 --- a/src/client/src/tscServer.c +++ b/src/client/src/tscServer.c @@ -423,7 +423,7 @@ void tscProcessMsgFromServer(SRpcMsg *rpcMsg, SRpcEpSet *pEpSet) { if (shouldFree) { // in case of table-meta/vgrouplist query, automatically free it taosRemoveRef(tscObjRef, pSql->self); - tscDebug("%p sqlObj is automatically freed", pSql); + tscDebug("%p sqlObj is automatically freed", pSql); } rpcFreeCont(rpcMsg->pCont); @@ -1975,9 +1975,6 @@ int tscProcessMultiMeterMetaRsp(SSqlObj *pSql) { // // rsp += tagLen; // int32_t size = (int32_t)(rsp - ((char *)pMeta)); // Consistent with STableMeta in cache - // - // pMeta->index = 0; - // (void)taosCachePut(tscMetaCache, pMeta->tableId, (char *)pMeta, size, tsTableMetaKeepTimer); // } } @@ -1990,16 +1987,20 @@ int tscProcessMultiMeterMetaRsp(SSqlObj *pSql) { } int tscProcessSTableVgroupRsp(SSqlObj *pSql) { + // master sqlObj locates in param + SSqlObj* parent = (SSqlObj*)taosAcquireRef(tscObjRef, (int64_t)pSql->param); + if(parent == NULL) { + return pSql->res.code; + } + + assert(parent->signature == parent && (int64_t)pSql->param == parent->self); + SSqlRes* pRes = &pSql->res; // NOTE: the order of several table must be preserved. SSTableVgroupRspMsg *pStableVgroup = (SSTableVgroupRspMsg *)pRes->pRsp; pStableVgroup->numOfTables = htonl(pStableVgroup->numOfTables); char *pMsg = pRes->pRsp + sizeof(SSTableVgroupRspMsg); - - // master sqlObj locates in param - SSqlObj* parent = pSql->param; - assert(parent != NULL); SSqlCmd* pCmd = &parent->cmd; for(int32_t i = 0; i < pStableVgroup->numOfTables; ++i) { @@ -2033,6 +2034,8 @@ int tscProcessSTableVgroupRsp(SSqlObj *pSql) { pMsg += size; } + + taosReleaseRef(tscObjRef, parent->self); return pSql->res.code; } @@ -2326,10 +2329,14 @@ static int32_t getTableMetaFromMnode(SSqlObj *pSql, STableMetaInfo *pTableMetaIn tscDebug("%p new pSqlObj:%p to get tableMeta, auto create:%d", pSql, pNew, pNew->cmd.autoCreated); + registerSqlObj(pNew); + pNew->fp = tscTableMetaCallBack; - pNew->param = pSql; + pNew->param = (void *)pSql->self; - registerSqlObj(pNew); + tscDebug("%p metaRid from %" PRId64 " to %" PRId64 , pSql, pSql->metaRid, pNew->self); + + pSql->metaRid = pNew->self; int32_t code = tscProcessSql(pNew); if (code == TSDB_CODE_SUCCESS) { @@ -2346,6 +2353,7 @@ int32_t tscGetTableMeta(SSqlObj *pSql, STableMetaInfo *pTableMetaInfo) { uint32_t size = tscGetTableMetaMaxSize(); pTableMetaInfo->pTableMeta = calloc(1, size); + pTableMetaInfo->pTableMeta->tableType = -1; pTableMetaInfo->pTableMeta->tableInfo.numOfColumns = -1; int32_t len = (int32_t) strlen(pTableMetaInfo->name); @@ -2445,10 +2453,15 @@ int tscGetSTableVgroupInfo(SSqlObj *pSql, int32_t clauseIndex) { pNewQueryInfo->numOfTables = pQueryInfo->numOfTables; registerSqlObj(pNew); + tscDebug("%p svgroupRid from %" PRId64 " to %" PRId64 , pSql, pSql->svgroupRid, pNew->self); + + pSql->svgroupRid = pNew->self; + + tscDebug("%p new sqlObj:%p to get vgroupInfo, numOfTables:%d", pSql, pNew, pNewQueryInfo->numOfTables); pNew->fp = tscTableMetaCallBack; - pNew->param = pSql; + pNew->param = (void *)pSql->self; code = tscProcessSql(pNew); if (code == TSDB_CODE_SUCCESS) { code = TSDB_CODE_TSC_ACTION_IN_PROGRESS; diff --git a/src/client/src/tscSql.c b/src/client/src/tscSql.c index da86b4cb1963c0cd4a535976b59f99161cff0ada..3f25d7a14d90a4d8aac6ca33b53d34f721b9847b 100644 --- a/src/client/src/tscSql.c +++ b/src/client/src/tscSql.c @@ -47,7 +47,7 @@ static bool validUserName(const char* user) { } static bool validPassword(const char* passwd) { - return validImpl(passwd, TSDB_PASSWORD_LEN - 1); + return validImpl(passwd, TSDB_KEY_LEN - 1); } static SSqlObj *taosConnectImpl(const char *ip, const char *user, const char *pass, const char *auth, const char *db, @@ -238,11 +238,11 @@ TAOS *taos_connect_c(const char *ip, uint8_t ipLen, const char *user, uint8_t us uint8_t passLen, const char *db, uint8_t dbLen, uint16_t port) { char ipBuf[TSDB_EP_LEN] = {0}; char userBuf[TSDB_USER_LEN] = {0}; - char passBuf[TSDB_PASSWORD_LEN] = {0}; + char passBuf[TSDB_KEY_LEN] = {0}; char dbBuf[TSDB_DB_NAME_LEN] = {0}; strncpy(ipBuf, ip, MIN(TSDB_EP_LEN - 1, ipLen)); strncpy(userBuf, user, MIN(TSDB_USER_LEN - 1, userLen)); - strncpy(passBuf, pass, MIN(TSDB_PASSWORD_LEN - 1, passLen)); + strncpy(passBuf, pass, MIN(TSDB_KEY_LEN - 1, passLen)); strncpy(dbBuf, db, MIN(TSDB_DB_NAME_LEN - 1, dbLen)); return taos_connect(ipBuf, userBuf, passBuf, dbBuf, port); } @@ -694,6 +694,8 @@ static void tscKillSTableQuery(SSqlObj *pSql) { // set the master sqlObj flag to cancel query pSql->res.code = TSDB_CODE_TSC_QUERY_CANCELLED; + tscLockByThread(&pSql->squeryLock); + for (int i = 0; i < pSql->subState.numOfSub; ++i) { // NOTE: pSub may have been released already here SSqlObj *pSub = pSql->pSubs[i]; @@ -713,6 +715,12 @@ static void tscKillSTableQuery(SSqlObj *pSql) { taosReleaseRef(tscObjRef, pSubObj->self); } + if (pSql->subState.numOfSub <= 0) { + tscAsyncResultOnError(pSql); + } + + tscUnlockByThread(&pSql->squeryLock); + tscDebug("%p super table query cancelled", pSql); } @@ -978,7 +986,7 @@ static int tscParseTblNameList(SSqlObj *pSql, const char *tblNameList, int32_t t return code; } - if (++pCmd->count > TSDB_MULTI_METERMETA_MAX_NUM) { + if (++pCmd->count > TSDB_MULTI_TABLEMETA_MAX_NUM) { code = TSDB_CODE_TSC_INVALID_TABLE_ID_LENGTH; sprintf(pCmd->payload, "tables over the max number"); return code; diff --git a/src/client/src/tscStream.c b/src/client/src/tscStream.c index 1c85938c641702973ac2a60bc5102b6affb9e9a3..a39fbc94202d3c1940b8631c9f95a38381857946 100644 --- a/src/client/src/tscStream.c +++ b/src/client/src/tscStream.c @@ -551,7 +551,6 @@ static void tscCreateStream(void *param, TAOS_RES *res, int code) { int64_t starttime = tscGetLaunchTimestamp(pStream); pCmd->command = TSDB_SQL_SELECT; - registerSqlObj(pSql); tscAddIntoStreamList(pStream); taosTmrReset(tscProcessStreamTimer, (int32_t)starttime, pStream, tscTmr, &pStream->pTimer); @@ -610,12 +609,15 @@ TAOS_STREAM *taos_open_stream(TAOS *taos, const char *sqlstr, void (*fp)(void *p pSql->fp = tscCreateStream; pSql->fetchFp = tscCreateStream; + + registerSqlObj(pSql); + int32_t code = tsParseSql(pSql, true); if (code == TSDB_CODE_SUCCESS) { tscCreateStream(pStream, pSql, code); } else if (code != TSDB_CODE_TSC_ACTION_IN_PROGRESS) { tscError("%p open stream failed, sql:%s, code:%s", pSql, sqlstr, tstrerror(pRes->code)); - tscFreeSqlObj(pSql); + taosReleaseRef(tscObjRef, pSql->self); free(pStream); return NULL; } diff --git a/src/client/src/tscSubquery.c b/src/client/src/tscSubquery.c index d4f962063011910aa242c82146a5a3094da89c05..a00ea68bd0c176501a01e309890f06c6c24fd79a 100644 --- a/src/client/src/tscSubquery.c +++ b/src/client/src/tscSubquery.c @@ -533,7 +533,7 @@ static void quitAllSubquery(SSqlObj* pSqlObj, SJoinSupporter* pSupporter) { freeJoinSubqueryObj(pSqlObj); } - tscDestroyJoinSupporter(pSupporter); + //tscDestroyJoinSupporter(pSupporter); } // update the query time range according to the join results on timestamp @@ -1362,14 +1362,23 @@ void tscJoinQueryCallback(void* param, TAOS_RES* tres, int code) { SJoinSupporter* pSupporter = (SJoinSupporter*)param; SSqlObj* pParentSql = pSupporter->pObj; - + // There is only one subquery and table for each subquery. SQueryInfo* pQueryInfo = tscGetQueryInfoDetail(&pSql->cmd, 0); + STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0); + assert(pQueryInfo->numOfTables == 1 && pSql->cmd.numOfClause == 1); // retrieve actual query results from vnode during the second stage join subquery if (pParentSql->res.code != TSDB_CODE_SUCCESS) { tscError("%p abort query due to other subquery failure. code:%d, global code:%d", pSql, code, pParentSql->res.code); + + if (!(pTableMetaInfo->vgroupIndex > 0 && tscNonOrderedProjectionQueryOnSTable(pQueryInfo, 0))) { + if (atomic_sub_fetch_32(&pParentSql->subState.numOfRemain, 1) > 0) { + return; + } + } + quitAllSubquery(pParentSql, pSupporter); tscAsyncResultOnError(pParentSql); @@ -1383,6 +1392,12 @@ void tscJoinQueryCallback(void* param, TAOS_RES* tres, int code) { tscError("%p abort query, code:%s, global code:%s", pSql, tstrerror(code), tstrerror(pParentSql->res.code)); pParentSql->res.code = code; + if (!(pTableMetaInfo->vgroupIndex > 0 && tscNonOrderedProjectionQueryOnSTable(pQueryInfo, 0))) { + if (atomic_sub_fetch_32(&pParentSql->subState.numOfRemain, 1) > 0) { + return; + } + } + quitAllSubquery(pParentSql, pSupporter); tscAsyncResultOnError(pParentSql); @@ -1405,9 +1420,6 @@ void tscJoinQueryCallback(void* param, TAOS_RES* tres, int code) { return; } - - STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0); - // In case of consequence query from other vnode, do not wait for other query response here. if (!(pTableMetaInfo->vgroupIndex > 0 && tscNonOrderedProjectionQueryOnSTable(pQueryInfo, 0))) { if (atomic_sub_fetch_32(&pParentSql->subState.numOfRemain, 1) > 0) { @@ -1658,6 +1670,25 @@ static void doCleanupSubqueries(SSqlObj *pSql, int32_t numOfSubs) { } } +void tscLockByThread(int64_t *lockedBy) { + int64_t tid = taosGetSelfPthreadId(); + int i = 0; + while (atomic_val_compare_exchange_64(lockedBy, 0, tid) != 0) { + if (++i % 100 == 0) { + sched_yield(); + } + } +} + +void tscUnlockByThread(int64_t *lockedBy) { + int64_t tid = taosGetSelfPthreadId(); + if (atomic_val_compare_exchange_64(lockedBy, tid, 0) != tid) { + assert(false); + } +} + + + int32_t tscHandleMasterSTableQuery(SSqlObj *pSql) { SSqlRes *pRes = &pSql->res; SSqlCmd *pCmd = &pSql->cmd; diff --git a/src/client/src/tscUtil.c b/src/client/src/tscUtil.c index b44ebb3c98c7bd63a3814aede2b1bf3c2ccb4d95..9a8aa917e70f978c2d5c4f0038223479eb10bbd3 100644 --- a/src/client/src/tscUtil.c +++ b/src/client/src/tscUtil.c @@ -468,6 +468,18 @@ void tscFreeRegisteredSqlObj(void *pSql) { } +void tscFreeMetaSqlObj(int64_t *rid){ + if (RID_VALID(*rid)) { + SSqlObj* pSql = (SSqlObj*)taosAcquireRef(tscObjRef, *rid); + if (pSql) { + taosRemoveRef(tscObjRef, *rid); + taosReleaseRef(tscObjRef, *rid); + } + + *rid = 0; + } +} + void tscFreeSqlObj(SSqlObj* pSql) { if (pSql == NULL || pSql->signature != pSql) { return; @@ -477,6 +489,9 @@ void tscFreeSqlObj(SSqlObj* pSql) { pSql->res.code = TSDB_CODE_TSC_QUERY_CANCELLED; + tscFreeMetaSqlObj(&pSql->metaRid); + tscFreeMetaSqlObj(&pSql->svgroupRid); + tscFreeSubobj(pSql); SSqlCmd* pCmd = &pSql->cmd; @@ -505,6 +520,7 @@ void tscFreeSqlObj(SSqlObj* pSql) { pCmd->allocSize = 0; tsem_destroy(&pSql->rspSem); + memset(pSql, 0, sizeof(*pSql)); free(pSql); } @@ -2193,7 +2209,9 @@ void tscDoQuery(SSqlObj* pSql) { tscProcessSql(pSql); } else { // secondary stage join query. if (tscIsTwoStageSTableQuery(pQueryInfo, 0)) { // super table query + tscLockByThread(&pSql->squeryLock); tscHandleMasterSTableQuery(pSql); + tscUnlockByThread(&pSql->squeryLock); } else { tscProcessSql(pSql); } @@ -2202,7 +2220,9 @@ void tscDoQuery(SSqlObj* pSql) { return; } else if (tscIsTwoStageSTableQuery(pQueryInfo, 0)) { // super table query + tscLockByThread(&pSql->squeryLock); tscHandleMasterSTableQuery(pSql); + tscUnlockByThread(&pSql->squeryLock); return; } diff --git a/src/client/tests/CMakeLists.txt b/src/client/tests/CMakeLists.txt index f07af85e255eaa5e285d9a4ce0853251e0fdaa21..4ea0b80bf7c1c870532f1bc3cac313c43f1a57f0 100644 --- a/src/client/tests/CMakeLists.txt +++ b/src/client/tests/CMakeLists.txt @@ -1,4 +1,4 @@ -CMAKE_MINIMUM_REQUIRED(VERSION 2.8) +CMAKE_MINIMUM_REQUIRED(VERSION 3.5) PROJECT(TDengine) FIND_PATH(HEADER_GTEST_INCLUDE_DIR gtest.h /usr/include/gtest /usr/local/include/gtest) diff --git a/src/client/tests/timeParseTest.cpp b/src/client/tests/timeParseTest.cpp index bee01b5cecdf5f42a6cd0105fa6b808a23957012..d7325430cd1d859ab9dd3e86f8dd55ab0dd1355d 100644 --- a/src/client/tests/timeParseTest.cpp +++ b/src/client/tests/timeParseTest.cpp @@ -162,6 +162,10 @@ TEST(testCase, parse_time) { taosParseTime(t13, &time, strlen(t13), TSDB_TIME_PRECISION_MILLI, 0); EXPECT_EQ(time, -28800 * MILLISECOND_PER_SECOND); + + char* t = "2021-01-08T02:11:40.000+00:00"; + taosParseTime(t, &time, strlen(t), TSDB_TIME_PRECISION_MILLI, 0); + printf("%ld\n", time); } diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index 0da7bda994db83882e36e9d52a7983635ad85330..df0ac7986599da3e53d97f64c0c5113a357f9177 100644 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt @@ -1,4 +1,4 @@ -CMAKE_MINIMUM_REQUIRED(VERSION 2.8) +CMAKE_MINIMUM_REQUIRED(VERSION 3.5) PROJECT(TDengine) INCLUDE_DIRECTORIES(inc) diff --git a/src/common/inc/tglobal.h b/src/common/inc/tglobal.h index 18b23315a0db54bbb208cd28c10f3b23b9abbe89..80800ee42d55bf7977867bbc37321059f323e19a 100644 --- a/src/common/inc/tglobal.h +++ b/src/common/inc/tglobal.h @@ -63,7 +63,6 @@ extern int32_t tsRetrieveBlockingModel;// retrieve threads will be blocked extern int8_t tsKeepOriginalColumnName; // client -extern int32_t tsTableMetaKeepTimer; extern int32_t tsMaxSQLStringLen; extern int8_t tsTscEnableRecordSql; extern int32_t tsMaxNumOfOrderedResults; diff --git a/src/common/src/tglobal.c b/src/common/src/tglobal.c index 4afc83cc75bfe0c4fbb3b34543f2519ab557e577..0551f280a6d6bd7eef7129af9587f70c41722a8f 100644 --- a/src/common/src/tglobal.c +++ b/src/common/src/tglobal.c @@ -72,7 +72,6 @@ char tsTempDir[TSDB_FILENAME_LEN] = "/tmp/"; int32_t tsCompressMsgSize = -1; // client -int32_t tsTableMetaKeepTimer = 7200; // second int32_t tsMaxSQLStringLen = TSDB_MAX_SQL_LEN; int8_t tsTscEnableRecordSql = 0; @@ -637,16 +636,6 @@ static void doInitGlobalConfig(void) { cfg.unitType = TAOS_CFG_UTYPE_SECOND; taosInitConfigOption(cfg); - cfg.option = "tableMetaKeepTimer"; - cfg.ptr = &tsTableMetaKeepTimer; - cfg.valType = TAOS_CFG_VTYPE_INT32; - cfg.cfgType = TSDB_CFG_CTYPE_B_CONFIG | TSDB_CFG_CTYPE_B_CLIENT; - cfg.minValue = 1; - cfg.maxValue = 8640000; - cfg.ptrLength = 0; - cfg.unitType = TAOS_CFG_UTYPE_SECOND; - taosInitConfigOption(cfg); - cfg.option = "minSlidingTime"; cfg.ptr = &tsMinSlidingTime; cfg.valType = TAOS_CFG_VTYPE_INT32; @@ -852,8 +841,8 @@ static void doInitGlobalConfig(void) { cfg.ptr = &tsQuorum; cfg.valType = TAOS_CFG_VTYPE_INT32; cfg.cfgType = TSDB_CFG_CTYPE_B_CONFIG | TSDB_CFG_CTYPE_B_SHOW; - cfg.minValue = TSDB_MIN_DB_REPLICA_OPTION; - cfg.maxValue = TSDB_MAX_DB_REPLICA_OPTION; + cfg.minValue = TSDB_MIN_DB_QUORUM_OPTION; + cfg.maxValue = TSDB_MAX_DB_QUORUM_OPTION; cfg.ptrLength = 0; cfg.unitType = TAOS_CFG_UTYPE_NONE; taosInitConfigOption(cfg); diff --git a/src/common/src/tvariant.c b/src/common/src/tvariant.c index fdfa933cdeb2be89c20a5e617c082ff28378701f..09c5c761637ee40ea22fc899d517389594c2c98d 100644 --- a/src/common/src/tvariant.c +++ b/src/common/src/tvariant.c @@ -399,6 +399,7 @@ static int32_t toNchar(tVariant *pVariant, char **pDest, int32_t *pDestSize) { pVariant->wpz = (wchar_t *)tmp; } else { int32_t output = 0; + bool ret = taosMbsToUcs4(pDst, nLen, *pDest, (nLen + 1) * TSDB_NCHAR_SIZE, &output); if (!ret) { return -1; diff --git a/src/connector/jdbc/CMakeLists.txt b/src/connector/jdbc/CMakeLists.txt index e289f1ae1b4823ad5c6fd580551a9ee3f9800d9e..22d3d31547d0653a0ce0afe7b4128219fef35098 100644 --- a/src/connector/jdbc/CMakeLists.txt +++ b/src/connector/jdbc/CMakeLists.txt @@ -1,4 +1,4 @@ -CMAKE_MINIMUM_REQUIRED(VERSION 2.8) +CMAKE_MINIMUM_REQUIRED(VERSION 3.5) PROJECT(TDengine) diff --git a/src/connector/odbc/CMakeLists.txt b/src/connector/odbc/CMakeLists.txt index 0d8c07041aa741793b7a1b8db20c3a3b470cf193..2e1e39ef123c901b36050a9e239fe58d26869e8e 100644 --- a/src/connector/odbc/CMakeLists.txt +++ b/src/connector/odbc/CMakeLists.txt @@ -1,4 +1,4 @@ -CMAKE_MINIMUM_REQUIRED(VERSION 2.8) +CMAKE_MINIMUM_REQUIRED(VERSION 3.5) PROJECT(TDengine) IF (TD_LINUX_64) diff --git a/src/connector/odbc/src/CMakeLists.txt b/src/connector/odbc/src/CMakeLists.txt index 2699e1bc90e162c80d27d690e1f7163747616526..67357cb4698b2885b563fd54133f36aace38c54b 100644 --- a/src/connector/odbc/src/CMakeLists.txt +++ b/src/connector/odbc/src/CMakeLists.txt @@ -1,4 +1,4 @@ -CMAKE_MINIMUM_REQUIRED(VERSION 2.8) +CMAKE_MINIMUM_REQUIRED(VERSION 3.5) PROJECT(TDengine) IF (TD_LINUX_64) diff --git a/src/cq/CMakeLists.txt b/src/cq/CMakeLists.txt index e6313973484467e4b67be88ffc21225923739b71..9da831c9c137a0551306d343dd112189816ead5b 100644 --- a/src/cq/CMakeLists.txt +++ b/src/cq/CMakeLists.txt @@ -1,4 +1,4 @@ -CMAKE_MINIMUM_REQUIRED(VERSION 2.8) +CMAKE_MINIMUM_REQUIRED(VERSION 3.5) PROJECT(TDengine) INCLUDE_DIRECTORIES(inc) diff --git a/src/cq/src/cqMain.c b/src/cq/src/cqMain.c index a0df8247b7136412c3f497b3443bdd77c5b8bf4d..0fe5ea78d46e6d2796c1d71531c87ec44cb8ee0d 100644 --- a/src/cq/src/cqMain.c +++ b/src/cq/src/cqMain.c @@ -43,7 +43,7 @@ typedef struct { int32_t master; int32_t num; // number of continuous streams char user[TSDB_USER_LEN]; - char pass[TSDB_PASSWORD_LEN]; + char pass[TSDB_KEY_LEN]; char db[TSDB_DB_NAME_LEN]; FCqWrite cqWrite; struct SCqObj *pHead; diff --git a/src/cq/test/CMakeLists.txt b/src/cq/test/CMakeLists.txt index 59c0ac79cfffd35a40beb58a2a172a9bf27dca15..87a8705fcd53be733d7ecec840ce38355c00d737 100644 --- a/src/cq/test/CMakeLists.txt +++ b/src/cq/test/CMakeLists.txt @@ -1,4 +1,4 @@ -CMAKE_MINIMUM_REQUIRED(VERSION 2.8) +CMAKE_MINIMUM_REQUIRED(VERSION 3.5) PROJECT(TDengine) LIST(APPEND CQTEST_SRC ./cqtest.c) diff --git a/src/dnode/CMakeLists.txt b/src/dnode/CMakeLists.txt index ebb25bf85879e5ab1a53bd8ae4ae9ad3579bd6eb..699ca00a250866122023d8a4cd789f91bd038609 100644 --- a/src/dnode/CMakeLists.txt +++ b/src/dnode/CMakeLists.txt @@ -1,4 +1,4 @@ -CMAKE_MINIMUM_REQUIRED(VERSION 2.8) +CMAKE_MINIMUM_REQUIRED(VERSION 3.5) PROJECT(TDengine) INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/src/query/inc) diff --git a/src/dnode/src/dnodeVWrite.c b/src/dnode/src/dnodeVWrite.c index 775ced09900612da76fff5a60d42839b83fcb133..ab5a4ccaad5fa3e5969776c75db26a30d3e32e8e 100644 --- a/src/dnode/src/dnodeVWrite.c +++ b/src/dnode/src/dnodeVWrite.c @@ -202,13 +202,14 @@ static void *dnodeProcessVWriteQueue(void *wparam) { for (int32_t i = 0; i < numOfMsgs; ++i) { taosGetQitem(pWorker->qall, &qtype, (void **)&pWrite); dTrace("msg:%p, app:%p type:%s will be processed in vwrite queue, qtype:%s hver:%" PRIu64, pWrite, - pWrite->rpcMsg.ahandle, taosMsg[pWrite->pHead->msgType], qtypeStr[qtype], pWrite->pHead->version); + pWrite->rpcMsg.ahandle, taosMsg[pWrite->pHead.msgType], qtypeStr[qtype], pWrite->pHead.version); - pWrite->code = vnodeProcessWrite(pVnode, pWrite->pHead, qtype, &pWrite->rspRet); + pWrite->code = vnodeProcessWrite(pVnode, &pWrite->pHead, qtype, pWrite); if (pWrite->code <= 0) pWrite->processedCount = 1; - if (pWrite->code == 0 && pWrite->pHead->msgType != TSDB_MSG_TYPE_SUBMIT) forceFsync = true; + if (pWrite->code > 0) pWrite->code = 0; + if (pWrite->code == 0 && pWrite->pHead.msgType != TSDB_MSG_TYPE_SUBMIT) forceFsync = true; - dTrace("msg:%p is processed in vwrite queue, result:%s", pWrite, tstrerror(pWrite->code)); + dTrace("msg:%p is processed in vwrite queue, code:0x%x", pWrite, pWrite->code); } walFsync(vnodeGetWal(pVnode), forceFsync); @@ -221,7 +222,7 @@ static void *dnodeProcessVWriteQueue(void *wparam) { dnodeSendRpcVWriteRsp(pVnode, pWrite, pWrite->code); } else { if (qtype == TAOS_QTYPE_FWD) { - vnodeConfirmForward(pVnode, pWrite->pHead->version, 0); + vnodeConfirmForward(pVnode, pWrite->pHead.version, 0); } if (pWrite->rspRet.rsp) { rpcFreeCont(pWrite->rspRet.rsp); diff --git a/src/inc/taosdef.h b/src/inc/taosdef.h index 9a52cb3beea5e37b6e62081fe8088e770eceede8..493b8091e93b59f823b11fc021365c9aa90e620c 100644 --- a/src/inc/taosdef.h +++ b/src/inc/taosdef.h @@ -256,10 +256,8 @@ int32_t tStrToInteger(const char* z, int16_t type, int32_t n, int64_t* value, bo #define TSDB_USER_LEN TSDB_UNI_LEN // ACCOUNT is a 32 bit positive integer -// this is the length of its string representation -// including the terminator zero -#define TSDB_ACCT_LEN 11 -#define TSDB_PASSWORD_LEN TSDB_UNI_LEN +// this is the length of its string representation, including the terminator zero +#define TSDB_ACCT_ID_LEN 11 #define TSDB_MAX_COLUMNS 1024 #define TSDB_MIN_COLUMNS 2 //PRIMARY COLUMN(timestamp) + other columns @@ -267,7 +265,7 @@ int32_t tStrToInteger(const char* z, int16_t type, int32_t n, int64_t* value, bo #define TSDB_NODE_NAME_LEN 64 #define TSDB_TABLE_NAME_LEN 193 // it is a null-terminated string #define TSDB_DB_NAME_LEN 33 -#define TSDB_TABLE_FNAME_LEN (TSDB_ACCT_LEN + TSDB_DB_NAME_LEN + TSDB_TABLE_NAME_LEN) +#define TSDB_TABLE_FNAME_LEN (TSDB_ACCT_ID_LEN + TSDB_DB_NAME_LEN + TSDB_TABLE_NAME_LEN) #define TSDB_COL_NAME_LEN 65 #define TSDB_MAX_SAVED_SQL_LEN TSDB_MAX_COLUMNS * 64 #define TSDB_MAX_SQL_LEN TSDB_PAYLOAD_SIZE @@ -293,11 +291,6 @@ int32_t tStrToInteger(const char* z, int16_t type, int32_t n, int64_t* value, bo #define TSDB_EP_LEN (TSDB_FQDN_LEN+6) #define TSDB_IPv4ADDR_LEN 16 #define TSDB_FILENAME_LEN 128 -#define TSDB_METER_VNODE_BITS 20 -#define TSDB_METER_SID_MASK 0xFFFFF -#define TSDB_SHELL_VNODE_BITS 24 -#define TSDB_SHELL_SID_MASK 0xFF -#define TSDB_HTTP_TOKEN_LEN 20 #define TSDB_SHOW_SQL_LEN 512 #define TSDB_SLOW_QUERY_SQL_LEN 512 @@ -311,9 +304,6 @@ int32_t tStrToInteger(const char* z, int16_t type, int32_t n, int64_t* value, bo #define TSDB_MQTT_TOPIC_LEN 64 #define TSDB_MQTT_CLIENT_ID_LEN 32 -#define TSDB_METER_STATE_OFFLINE 0 -#define TSDB_METER_STATE_ONLLINE 1 - #define TSDB_DEFAULT_PKT_SIZE 65480 //same as RPC_MAX_UDP_SIZE #define TSDB_PAYLOAD_SIZE TSDB_DEFAULT_PKT_SIZE @@ -333,7 +323,7 @@ int32_t tStrToInteger(const char* z, int16_t type, int32_t n, int64_t* value, bo #define TSDB_TBNAME_COLUMN_INDEX (-1) #define TSDB_UD_COLUMN_INDEX (-100) -#define TSDB_MULTI_METERMETA_MAX_NUM 100000 // maximum batch size allowed to load metermeta +#define TSDB_MULTI_TABLEMETA_MAX_NUM 100000 // maximum batch size allowed to load table meta #define TSDB_MIN_CACHE_BLOCK_SIZE 1 #define TSDB_MAX_CACHE_BLOCK_SIZE 128 // 128MB for each vnode @@ -395,6 +385,9 @@ int32_t tStrToInteger(const char* z, int16_t type, int32_t n, int64_t* value, bo #define TSDB_MIN_DB_REPLICA_OPTION 1 #define TSDB_MAX_DB_REPLICA_OPTION 3 #define TSDB_DEFAULT_DB_REPLICA_OPTION 1 + +#define TSDB_MIN_DB_QUORUM_OPTION 1 +#define TSDB_MAX_DB_QUORUM_OPTION 2 #define TSDB_DEFAULT_DB_QUORUM_OPTION 1 #define TSDB_MAX_JOIN_TABLE_NUM 5 diff --git a/src/inc/taosmsg.h b/src/inc/taosmsg.h index 2dee6dc3bb20c7397ef435d4b7f37e5861f8891e..905867fbc7355b34f87e62ab71f8172e4b7bf93e 100644 --- a/src/inc/taosmsg.h +++ b/src/inc/taosmsg.h @@ -268,7 +268,7 @@ typedef struct { typedef struct { int32_t len; // one create table message char tableId[TSDB_TABLE_FNAME_LEN]; - char db[TSDB_ACCT_LEN + TSDB_DB_NAME_LEN]; + char db[TSDB_ACCT_ID_LEN + TSDB_DB_NAME_LEN]; int8_t igExists; int8_t getMeta; int16_t numOfTags; @@ -290,7 +290,7 @@ typedef struct { typedef struct { char tableId[TSDB_TABLE_FNAME_LEN]; - char db[TSDB_ACCT_LEN + TSDB_DB_NAME_LEN]; + char db[TSDB_ACCT_ID_LEN + TSDB_DB_NAME_LEN]; int16_t type; /* operation type */ int16_t numOfCols; /* number of schema */ int32_t tagValLen; @@ -322,7 +322,7 @@ typedef struct { } SConnectMsg; typedef struct { - char acctId[TSDB_ACCT_LEN]; + char acctId[TSDB_ACCT_ID_LEN]; char serverVersion[TSDB_VERSION_LEN]; char clusterId[TSDB_CLUSTER_ID_LEN]; int8_t writeAuth; @@ -534,7 +534,7 @@ typedef struct { } SVnodeLoad; typedef struct { - char db[TSDB_ACCT_LEN + TSDB_DB_NAME_LEN]; + char db[TSDB_ACCT_ID_LEN + TSDB_DB_NAME_LEN]; int32_t cacheBlockSize; //MB int32_t totalBlocks; int32_t maxTables; @@ -682,7 +682,7 @@ typedef struct { } SVnodeDesc; typedef struct { - char db[TSDB_ACCT_LEN + TSDB_DB_NAME_LEN]; + char db[TSDB_ACCT_ID_LEN + TSDB_DB_NAME_LEN]; SVnodeCfg cfg; SVnodeDesc nodes[TSDB_MAX_REPLICA]; } SCreateVnodeMsg, SAlterVnodeMsg; @@ -761,7 +761,7 @@ typedef struct { */ typedef struct { int8_t type; - char db[TSDB_ACCT_LEN + TSDB_DB_NAME_LEN]; + char db[TSDB_ACCT_ID_LEN + TSDB_DB_NAME_LEN]; uint16_t payloadLen; char payload[]; } SShowMsg; diff --git a/src/inc/tcq.h b/src/inc/tcq.h index ad123d4080e23d2c7933dcea2981fd2376b99afe..1941649d0a02e7c75f4781cad5dedfa185127752 100644 --- a/src/inc/tcq.h +++ b/src/inc/tcq.h @@ -26,7 +26,7 @@ typedef int32_t (*FCqWrite)(int32_t vgId, void *pHead, int32_t qtype, void *pMsg typedef struct { int32_t vgId; char user[TSDB_USER_LEN]; - char pass[TSDB_PASSWORD_LEN]; + char pass[TSDB_KEY_LEN]; char db[TSDB_DB_NAME_LEN]; FCqWrite cqWrite; } SCqCfg; diff --git a/src/inc/vnode.h b/src/inc/vnode.h index cbe64484b11462fcf3f107625cb0e00b0ac682f4..7c9ebd8a0b9d96090134bd23c2061c857dfcd5f1 100644 --- a/src/inc/vnode.h +++ b/src/inc/vnode.h @@ -49,7 +49,7 @@ typedef struct { SRpcMsg rpcMsg; SRspRet rspRet; char reserveForSync[24]; - SWalHead pHead[]; + SWalHead pHead; } SVWriteMsg; // vnodeStatus diff --git a/src/kit/CMakeLists.txt b/src/kit/CMakeLists.txt index bf5278430054598b31e591ff728412556dabc6f0..bf77d856f9f772aeffb42f7f85d51a5841943076 100644 --- a/src/kit/CMakeLists.txt +++ b/src/kit/CMakeLists.txt @@ -1,4 +1,4 @@ -CMAKE_MINIMUM_REQUIRED(VERSION 2.8) +CMAKE_MINIMUM_REQUIRED(VERSION 3.5) PROJECT(TDengine) ADD_SUBDIRECTORY(shell) diff --git a/src/kit/shell/CMakeLists.txt b/src/kit/shell/CMakeLists.txt index c86cac281c0283aac691555927d679b0ef4f4f64..45da99e5722968591ffccf16432a8cb84d3557ff 100644 --- a/src/kit/shell/CMakeLists.txt +++ b/src/kit/shell/CMakeLists.txt @@ -1,4 +1,4 @@ -CMAKE_MINIMUM_REQUIRED(VERSION 2.8) +CMAKE_MINIMUM_REQUIRED(VERSION 3.5) PROJECT(TDengine) INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/src/client/inc) diff --git a/src/kit/taosdemo/CMakeLists.txt b/src/kit/taosdemo/CMakeLists.txt index ab02bdb64d1338ae2cf92a9784eddf9453a4e849..91c743939c26ce9bb20e18dd1f701f6eb75fd573 100644 --- a/src/kit/taosdemo/CMakeLists.txt +++ b/src/kit/taosdemo/CMakeLists.txt @@ -1,4 +1,4 @@ -CMAKE_MINIMUM_REQUIRED(VERSION 2.8) +CMAKE_MINIMUM_REQUIRED(VERSION 3.5) PROJECT(TDengine) INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/src/client/inc) diff --git a/src/kit/taosdemox/CMakeLists.txt b/src/kit/taosdemox/CMakeLists.txt index 3f5e725aeaf9fa957e8aa9cdd54978df7fbd94ed..7db6c04b281aa6dea3e9b51fc47a8796fd64371b 100644 --- a/src/kit/taosdemox/CMakeLists.txt +++ b/src/kit/taosdemox/CMakeLists.txt @@ -1,4 +1,4 @@ -CMAKE_MINIMUM_REQUIRED(VERSION 2.8) +CMAKE_MINIMUM_REQUIRED(VERSION 3.5) PROJECT(TDengine) INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/src/client/inc) diff --git a/src/kit/taosdump/CMakeLists.txt b/src/kit/taosdump/CMakeLists.txt index dcdbd486154b2673459e25754dc75457851a4df4..dc9ac6d4a789c4292480f522240690e13b47245b 100644 --- a/src/kit/taosdump/CMakeLists.txt +++ b/src/kit/taosdump/CMakeLists.txt @@ -1,4 +1,4 @@ -CMAKE_MINIMUM_REQUIRED(VERSION 2.8) +CMAKE_MINIMUM_REQUIRED(VERSION 3.5) PROJECT(TDengine) INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/src/client/inc) diff --git a/src/mnode/CMakeLists.txt b/src/mnode/CMakeLists.txt index ff5c9335b654edbdb7bbf6c081b38b265923d645..41230986948c7ddbd746e2bd2c6e5fcece66c041 100644 --- a/src/mnode/CMakeLists.txt +++ b/src/mnode/CMakeLists.txt @@ -1,4 +1,4 @@ -CMAKE_MINIMUM_REQUIRED(VERSION 2.8) +CMAKE_MINIMUM_REQUIRED(VERSION 3.5) PROJECT(TDengine) IF (TD_LINUX) diff --git a/src/mnode/inc/mnodeDef.h b/src/mnode/inc/mnodeDef.h index d29a738a10f6734ee62b45867582ed75c667f78f..5eeac97209634206d42e1c4aebec129e67ee38e5 100644 --- a/src/mnode/inc/mnodeDef.h +++ b/src/mnode/inc/mnodeDef.h @@ -138,7 +138,7 @@ typedef struct SVgObj { int64_t createdTime; int32_t lbDnodeId; int32_t lbTime; - char dbName[TSDB_ACCT_LEN + TSDB_DB_NAME_LEN]; + char dbName[TSDB_ACCT_ID_LEN + TSDB_DB_NAME_LEN]; int8_t inUse; int8_t accessState; int8_t status; @@ -179,7 +179,7 @@ typedef struct { } SDbCfg; typedef struct SDbObj { - char name[TSDB_ACCT_LEN + TSDB_DB_NAME_LEN]; + char name[TSDB_ACCT_ID_LEN + TSDB_DB_NAME_LEN]; int8_t reserved0[4]; char acct[TSDB_USER_LEN]; int64_t createdTime; diff --git a/src/mnode/src/mnodeDb.c b/src/mnode/src/mnodeDb.c index 8a03b1cd0e1029ef650f13f21a4c3548557b0527..fbcad151bc5f8f7f9168e12db02059b0c86d0f2c 100644 --- a/src/mnode/src/mnodeDb.c +++ b/src/mnode/src/mnodeDb.c @@ -316,9 +316,14 @@ static int32_t mnodeCheckDbCfg(SDbCfg *pCfg) { return TSDB_CODE_MND_INVALID_DB_OPTION; } - if (pCfg->quorum < TSDB_MIN_DB_REPLICA_OPTION || pCfg->quorum > TSDB_MAX_DB_REPLICA_OPTION) { - mError("invalid db option quorum:%d valid range: [%d, %d]", pCfg->quorum, TSDB_MIN_DB_REPLICA_OPTION, - TSDB_MAX_DB_REPLICA_OPTION); + if (pCfg->quorum > pCfg->replications) { + mError("invalid db option quorum:%d larger than replica:%d", pCfg->quorum, pCfg->replications); + return TSDB_CODE_MND_INVALID_DB_OPTION; + } + + if (pCfg->quorum < TSDB_MIN_DB_QUORUM_OPTION || pCfg->quorum > TSDB_MAX_DB_QUORUM_OPTION) { + mError("invalid db option quorum:%d valid range: [%d, %d]", pCfg->quorum, TSDB_MIN_DB_QUORUM_OPTION, + TSDB_MAX_DB_QUORUM_OPTION); return TSDB_CODE_MND_INVALID_DB_OPTION; } diff --git a/src/mnode/src/mnodeVgroup.c b/src/mnode/src/mnodeVgroup.c index 827be0687dbac338d660d07fefaf563d5c5d0341..881ef95fca0ac327d75ab00007b1bab3c8980578 100644 --- a/src/mnode/src/mnodeVgroup.c +++ b/src/mnode/src/mnodeVgroup.c @@ -565,7 +565,7 @@ int32_t mnodeCreateVgroup(SMnodeMsg *pMsg) { SDbObj *pDb = pMsg->pDb; SVgObj *pVgroup = (SVgObj *)calloc(1, sizeof(SVgObj)); - tstrncpy(pVgroup->dbName, pDb->name, TSDB_ACCT_LEN + TSDB_DB_NAME_LEN); + tstrncpy(pVgroup->dbName, pDb->name, TSDB_ACCT_ID_LEN + TSDB_DB_NAME_LEN); pVgroup->numOfVnodes = pDb->cfg.replications; pVgroup->createdTime = taosGetTimestampMs(); pVgroup->accessState = TSDB_VN_ALL_ACCCESS; diff --git a/src/os/CMakeLists.txt b/src/os/CMakeLists.txt index 4e44d29a025eee1eb8b850494b235dc48e9c050a..f41719f2404297070656910653b65a3fbffa7916 100644 --- a/src/os/CMakeLists.txt +++ b/src/os/CMakeLists.txt @@ -1,4 +1,4 @@ -CMAKE_MINIMUM_REQUIRED(VERSION 2.8) +CMAKE_MINIMUM_REQUIRED(VERSION 3.5) PROJECT(TDengine) IF (TD_LINUX) @@ -10,3 +10,5 @@ ELSEIF (TD_WINDOWS) ENDIF () ADD_SUBDIRECTORY(src/detail) +ADD_SUBDIRECTORY(tests) + diff --git a/src/os/src/alpine/CMakeLists.txt b/src/os/src/alpine/CMakeLists.txt index b5e739c24ce7ec3ef3ffc537ca8769706f7b56de..daa0b3cf43d0de60fafc960e48e3ad8aeec1a9ad 100644 --- a/src/os/src/alpine/CMakeLists.txt +++ b/src/os/src/alpine/CMakeLists.txt @@ -1,4 +1,4 @@ -CMAKE_MINIMUM_REQUIRED(VERSION 2.8) +CMAKE_MINIMUM_REQUIRED(VERSION 3.5) PROJECT(TDengine) AUX_SOURCE_DIRECTORY(. SRC) diff --git a/src/os/src/darwin/CMakeLists.txt b/src/os/src/darwin/CMakeLists.txt index c4cb28aa05e4716ca98c2687ce41d436b1300bb2..7f05ddd64b87f69e5fa03c874bb2bc401e5094cc 100644 --- a/src/os/src/darwin/CMakeLists.txt +++ b/src/os/src/darwin/CMakeLists.txt @@ -1,4 +1,4 @@ -CMAKE_MINIMUM_REQUIRED(VERSION 2.8) +CMAKE_MINIMUM_REQUIRED(VERSION 3.5) PROJECT(TDengine) AUX_SOURCE_DIRECTORY(. SRC) diff --git a/src/os/src/detail/CMakeLists.txt b/src/os/src/detail/CMakeLists.txt index 0d5c130d6eddce07b967e3fe15762f01d6e1e97b..e4052a4fb32d4d8bda1ea05443cf95c276251e57 100644 --- a/src/os/src/detail/CMakeLists.txt +++ b/src/os/src/detail/CMakeLists.txt @@ -1,4 +1,4 @@ -CMAKE_MINIMUM_REQUIRED(VERSION 2.8) +CMAKE_MINIMUM_REQUIRED(VERSION 3.5) PROJECT(TDengine) INCLUDE_DIRECTORIES(.) diff --git a/src/os/src/detail/osTime.c b/src/os/src/detail/osTime.c index b78627f46f2124912338f3b029b5a0fd341e729c..1710c469fb48506f21d914ac586fa8356f044619 100644 --- a/src/os/src/detail/osTime.c +++ b/src/os/src/detail/osTime.c @@ -486,7 +486,7 @@ int64_t taosTimeTruncate(int64_t t, const SInterval* pInterval, int32_t precisio start = (delta / pInterval->sliding + factor) * pInterval->sliding; if (pInterval->intervalUnit == 'd' || pInterval->intervalUnit == 'w') { - /* + /* * here we revised the start time of day according to the local time zone, * but in case of DST, the start time of one day need to be dynamically decided. */ @@ -501,9 +501,24 @@ int64_t taosTimeTruncate(int64_t t, const SInterval* pInterval, int32_t precisio start += (int64_t)(timezone * TSDB_TICK_PER_SECOND(precision)); } - int64_t end = start + pInterval->interval - 1; - if (end < t) { - start += pInterval->sliding; + int64_t end = 0; + + // not enough time range + if (INT64_MAX - start > pInterval->interval - 1) { + end = start + pInterval->interval - 1; + + while(end < t && ((start + pInterval->sliding) <= INT64_MAX)) { // move forward to the correct time window + start += pInterval->sliding; + + if (INT64_MAX - start > pInterval->interval - 1) { + end = start + pInterval->interval - 1; + } else { + end = INT64_MAX; + break; + } + } + } else { + end = INT64_MAX; } } diff --git a/src/os/src/linux/CMakeLists.txt b/src/os/src/linux/CMakeLists.txt index b1a7ebf54e58bbbdeea6d5cc219904916cc2ba03..8ab8f554672843eec34ed1880ba672e61e54aa7b 100644 --- a/src/os/src/linux/CMakeLists.txt +++ b/src/os/src/linux/CMakeLists.txt @@ -1,4 +1,4 @@ -CMAKE_MINIMUM_REQUIRED(VERSION 2.8) +CMAKE_MINIMUM_REQUIRED(VERSION 3.5) PROJECT(TDengine) AUX_SOURCE_DIRECTORY(. SRC) diff --git a/src/os/src/windows/CMakeLists.txt b/src/os/src/windows/CMakeLists.txt index 9dcc9e7e6d93ff200b7571d98724f898712658eb..a430dd3b3f968cd845732ead4aa1b780aea10c22 100644 --- a/src/os/src/windows/CMakeLists.txt +++ b/src/os/src/windows/CMakeLists.txt @@ -1,4 +1,4 @@ -CMAKE_MINIMUM_REQUIRED(VERSION 2.8) +CMAKE_MINIMUM_REQUIRED(VERSION 3.5) PROJECT(TDengine) AUX_SOURCE_DIRECTORY(. SRC) diff --git a/src/os/tests/CMakeLists.txt b/src/os/tests/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..1a18a72b40677f1e21b2431499b17c4c745fad7d --- /dev/null +++ b/src/os/tests/CMakeLists.txt @@ -0,0 +1,15 @@ +CMAKE_MINIMUM_REQUIRED(VERSION 2.8) +PROJECT(TDengine) + +FIND_PATH(HEADER_GTEST_INCLUDE_DIR gtest.h /usr/include/gtest /usr/local/include/gtest) +FIND_LIBRARY(LIB_GTEST_STATIC_DIR libgtest.a /usr/lib/ /usr/local/lib) + +IF (HEADER_GTEST_INCLUDE_DIR AND LIB_GTEST_STATIC_DIR) + MESSAGE(STATUS "gTest library found, build unit test") + + INCLUDE_DIRECTORIES(${HEADER_GTEST_INCLUDE_DIR}) + AUX_SOURCE_DIRECTORY(${CMAKE_CURRENT_SOURCE_DIR} SOURCE_LIST) + + ADD_EXECUTABLE(osTest ${SOURCE_LIST}) + TARGET_LINK_LIBRARIES(osTest taos osdetail tutil common gtest pthread) +ENDIF() \ No newline at end of file diff --git a/src/os/tests/test.cpp b/src/os/tests/test.cpp new file mode 100644 index 0000000000000000000000000000000000000000..600e5d71a760653f8a932985f0d14a60081575b6 --- /dev/null +++ b/src/os/tests/test.cpp @@ -0,0 +1,34 @@ +#include "os.h" +#include +#include +#include + +#include "taos.h" +#include "tstoken.h" +#include "tutil.h" + +int main(int argc, char** argv) { + testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} + +// test function in os module +TEST(testCase, parse_time) { + taos_options(TSDB_OPTION_TIMEZONE, "GMT-8"); + deltaToUtcInitOnce(); + + // window: 1500000001000, 1500002000000 + // pQuery->interval: interval: 86400000, sliding:3600000 + int64_t key = 1500000001000; + SInterval interval = {0}; + interval.interval = 86400000; + interval.intervalUnit = 'd'; + interval.sliding = 3600000; + interval.slidingUnit = 'h'; + + int64_t s = taosTimeTruncate(key, &interval, TSDB_TIME_PRECISION_MILLI); + ASSERT_TRUE(s + interval.interval >= key); +} + + + diff --git a/src/plugins/CMakeLists.txt b/src/plugins/CMakeLists.txt index 742235894a8781e4dcfa09cb86985c73df74d046..d03717b6e155913e4d0f9bfe442ea7dd77b47a3e 100644 --- a/src/plugins/CMakeLists.txt +++ b/src/plugins/CMakeLists.txt @@ -1,4 +1,4 @@ -CMAKE_MINIMUM_REQUIRED(VERSION 2.8) +CMAKE_MINIMUM_REQUIRED(VERSION 3.5) PROJECT(TDengine) ADD_SUBDIRECTORY(monitor) diff --git a/src/plugins/http/CMakeLists.txt b/src/plugins/http/CMakeLists.txt index 5d8b52986a6bb1cc451dac10cd92c8c37a352c4b..56c3c25d7c8522d2d31522f4d1b6dce4df1af42b 100644 --- a/src/plugins/http/CMakeLists.txt +++ b/src/plugins/http/CMakeLists.txt @@ -1,4 +1,4 @@ -CMAKE_MINIMUM_REQUIRED(VERSION 2.8) +CMAKE_MINIMUM_REQUIRED(VERSION 3.5) PROJECT(TDengine) INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/deps/zlib-1.2.11/inc) diff --git a/src/plugins/http/inc/httpInt.h b/src/plugins/http/inc/httpInt.h index ebdfabf3101001d020e24bf63c3d699492ff21d0..ac182b707b585adf76b92cf4fbc027d22277f220 100644 --- a/src/plugins/http/inc/httpInt.h +++ b/src/plugins/http/inc/httpInt.h @@ -39,7 +39,7 @@ #define HTTP_GC_TARGET_SIZE 512 #define HTTP_WRITE_RETRY_TIMES 500 #define HTTP_WRITE_WAIT_TIME_MS 5 -#define HTTP_SESSION_ID_LEN (TSDB_USER_LEN + TSDB_PASSWORD_LEN) +#define HTTP_SESSION_ID_LEN (TSDB_USER_LEN + TSDB_KEY_LEN) typedef enum HttpReqType { HTTP_REQTYPE_OTHERS = 0, @@ -147,7 +147,7 @@ typedef struct HttpContext { uint8_t parsed; char ipstr[22]; char user[TSDB_USER_LEN]; // parsed from auth token or login message - char pass[TSDB_PASSWORD_LEN]; + char pass[TSDB_KEY_LEN]; TAOS * taos; void * ppContext; HttpSession *session; diff --git a/src/plugins/http/src/httpAuth.c b/src/plugins/http/src/httpAuth.c index 8beef7c042ba6f0194d814753e15387e3d2b4a2b..56da8a7089e635effa0fc54e1aeb7137ea391c23 100644 --- a/src/plugins/http/src/httpAuth.c +++ b/src/plugins/http/src/httpAuth.c @@ -51,7 +51,7 @@ int32_t httpParseBasicAuthToken(HttpContext *pContext, char *token, int32_t len) char *password = user + 1; int32_t pass_len = (int32_t)((base64 + outlen) - password); - if (pass_len < 1 || pass_len >= TSDB_PASSWORD_LEN) { + if (pass_len < 1 || pass_len >= TSDB_KEY_LEN) { httpError("context:%p, fd:%d, basic token:%s parse password error", pContext, pContext->fd, token); free(base64); return -1; @@ -73,7 +73,7 @@ int32_t httpParseTaosdAuthToken(HttpContext *pContext, char *token, int32_t len) if (base64) free(base64); return 01; } - if (outlen != (TSDB_USER_LEN + TSDB_PASSWORD_LEN)) { + if (outlen != (TSDB_USER_LEN + TSDB_KEY_LEN)) { httpError("context:%p, fd:%d, taosd token:%s length error", pContext, pContext->fd, token); free(base64); return -1; @@ -103,8 +103,8 @@ int32_t httpGenTaosdAuthToken(HttpContext *pContext, char *token, int32_t maxLen size = sizeof(pContext->pass); tstrncpy(buffer + sizeof(pContext->user), pContext->pass, size); - char *encrypt = taosDesEncode(KEY_DES_4, buffer, TSDB_USER_LEN + TSDB_PASSWORD_LEN); - char *base64 = base64_encode((const unsigned char *)encrypt, TSDB_USER_LEN + TSDB_PASSWORD_LEN); + char *encrypt = taosDesEncode(KEY_DES_4, buffer, TSDB_USER_LEN + TSDB_KEY_LEN); + char *base64 = base64_encode((const unsigned char *)encrypt, TSDB_USER_LEN + TSDB_KEY_LEN); size_t len = strlen(base64); tstrncpy(token, base64, len + 1); diff --git a/src/plugins/http/src/httpGcHandle.c b/src/plugins/http/src/httpGcHandle.c index 5d4cb0c6809d063107cb37ccaac1200f2c87ee9d..c21799e736027eb4a021032d670f1b542500fe8f 100644 --- a/src/plugins/http/src/httpGcHandle.c +++ b/src/plugins/http/src/httpGcHandle.c @@ -59,11 +59,11 @@ bool gcGetUserFromUrl(HttpContext* pContext) { bool gcGetPassFromUrl(HttpContext* pContext) { HttpParser* pParser = pContext->parser; - if (pParser->path[GC_PASS_URL_POS].pos >= TSDB_PASSWORD_LEN || pParser->path[GC_PASS_URL_POS].pos <= 0) { + if (pParser->path[GC_PASS_URL_POS].pos >= TSDB_KEY_LEN || pParser->path[GC_PASS_URL_POS].pos <= 0) { return false; } - tstrncpy(pContext->pass, pParser->path[GC_PASS_URL_POS].str, TSDB_PASSWORD_LEN); + tstrncpy(pContext->pass, pParser->path[GC_PASS_URL_POS].str, TSDB_KEY_LEN); return true; } diff --git a/src/plugins/http/src/httpRestHandle.c b/src/plugins/http/src/httpRestHandle.c index 0a28c431ef313d36bd54b686e583e0dfb2313c0f..66f1db1a541322a0018e741dd537cd7b518f4bb5 100644 --- a/src/plugins/http/src/httpRestHandle.c +++ b/src/plugins/http/src/httpRestHandle.c @@ -72,11 +72,11 @@ bool restGetUserFromUrl(HttpContext* pContext) { bool restGetPassFromUrl(HttpContext* pContext) { HttpParser* pParser = pContext->parser; - if (pParser->path[REST_PASS_URL_POS].pos >= TSDB_PASSWORD_LEN || pParser->path[REST_PASS_URL_POS].pos <= 0) { + if (pParser->path[REST_PASS_URL_POS].pos >= TSDB_KEY_LEN || pParser->path[REST_PASS_URL_POS].pos <= 0) { return false; } - tstrncpy(pContext->pass, pParser->path[REST_PASS_URL_POS].str, TSDB_PASSWORD_LEN); + tstrncpy(pContext->pass, pParser->path[REST_PASS_URL_POS].str, TSDB_KEY_LEN); return true; } diff --git a/src/plugins/http/src/httpTgHandle.c b/src/plugins/http/src/httpTgHandle.c index e2b57b87bb3a10ee50edbf55ae2590289f940bf6..0a3ef539e37acd576596e5444ea3989602c00e90 100644 --- a/src/plugins/http/src/httpTgHandle.c +++ b/src/plugins/http/src/httpTgHandle.c @@ -324,7 +324,7 @@ bool tgGetUserFromUrl(HttpContext *pContext) { bool tgGetPassFromUrl(HttpContext *pContext) { HttpParser *pParser = pContext->parser; - if (pParser->path[TG_PASS_URL_POS].pos >= TSDB_PASSWORD_LEN || pParser->path[TG_PASS_URL_POS].pos <= 0) { + if (pParser->path[TG_PASS_URL_POS].pos >= TSDB_KEY_LEN || pParser->path[TG_PASS_URL_POS].pos <= 0) { return false; } diff --git a/src/plugins/monitor/CMakeLists.txt b/src/plugins/monitor/CMakeLists.txt index edea2187ea23caa5d809346a43d14f6ffaf8a309..90189c9d75b16a3689a8b6447d4ece4eb9766e1b 100644 --- a/src/plugins/monitor/CMakeLists.txt +++ b/src/plugins/monitor/CMakeLists.txt @@ -1,4 +1,4 @@ -CMAKE_MINIMUM_REQUIRED(VERSION 2.8) +CMAKE_MINIMUM_REQUIRED(VERSION 3.5) PROJECT(TDengine) INCLUDE_DIRECTORIES(inc) diff --git a/src/plugins/mqtt/CMakeLists.txt b/src/plugins/mqtt/CMakeLists.txt index cf5729d6087065bd38a5bed140ec01b1b531f454..3761f70134501a5db7b7d5080e5a5bcf5f592858 100644 --- a/src/plugins/mqtt/CMakeLists.txt +++ b/src/plugins/mqtt/CMakeLists.txt @@ -1,4 +1,4 @@ -CMAKE_MINIMUM_REQUIRED(VERSION 2.8) +CMAKE_MINIMUM_REQUIRED(VERSION 3.5) PROJECT(TDengine) INCLUDE_DIRECTORIES(inc) diff --git a/src/query/CMakeLists.txt b/src/query/CMakeLists.txt index c1024f008095be76dba0d8dd59447a489c015772..e403251858bdea2c89cc050ab3dbe3a5110843e3 100644 --- a/src/query/CMakeLists.txt +++ b/src/query/CMakeLists.txt @@ -1,4 +1,4 @@ -CMAKE_MINIMUM_REQUIRED(VERSION 2.8) +CMAKE_MINIMUM_REQUIRED(VERSION 3.5) PROJECT(TDengine) INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/src/tsdb/inc) diff --git a/src/query/inc/qPercentile.h b/src/query/inc/qPercentile.h index c34c24c5b2883391f94d87db4f778907cc13d62c..f5b770593c1e30df8c3459676ffa42bbfc9cf0ae 100644 --- a/src/query/inc/qPercentile.h +++ b/src/query/inc/qPercentile.h @@ -16,32 +16,36 @@ #ifndef TDENGINE_QPERCENTILE_H #define TDENGINE_QPERCENTILE_H +#ifdef __cplusplus +extern "C" { +#endif + #include "qExtbuffer.h" #include "qResultbuf.h" #include "qTsbuf.h" typedef struct MinMaxEntry { union { - double dMinVal; - int32_t iMinVal; - int64_t i64MinVal; + double dMinVal; + int64_t i64MinVal; + uint64_t u64MinVal; }; union { double dMaxVal; - int32_t iMaxVal; int64_t i64MaxVal; + int64_t u64MaxVal; }; } MinMaxEntry; typedef struct { - int32_t size; - int32_t pageId; + int32_t size; + int32_t pageId; tFilePage *data; } SSlotInfo; typedef struct tMemBucketSlot { - SSlotInfo info; - MinMaxEntry range; + SSlotInfo info; + MinMaxEntry range; } tMemBucketSlot; struct tMemBucket; @@ -52,16 +56,16 @@ typedef struct tMemBucket { int16_t type; int16_t bytes; int32_t total; - int32_t elemPerPage; // number of elements for each object - int32_t maxCapacity; // maximum allowed number of elements that can be sort directly to get the result - int32_t bufPageSize; // disk page size - MinMaxEntry range; // value range - int32_t times; // count that has been checked for deciding the correct data value buckets. + int32_t elemPerPage; // number of elements for each object + int32_t maxCapacity; // maximum allowed number of elements that can be sort directly to get the result + int32_t bufPageSize; // disk page size + MinMaxEntry range; // value range + int32_t times; // count that has been checked for deciding the correct data value buckets. __compar_fn_t comparFn; - tMemBucketSlot *pSlots; + tMemBucketSlot * pSlots; SDiskbasedResultBuf *pBuffer; - __perc_hash_func_t hashFunc; + __perc_hash_func_t hashFunc; } tMemBucket; tMemBucket *tMemBucketCreate(int16_t nElemSize, int16_t dataType, double minval, double maxval); @@ -73,3 +77,7 @@ int32_t tMemBucketPut(tMemBucket *pBucket, const void *data, size_t size); double getPercentile(tMemBucket *pMemBucket, double percent); #endif // TDENGINE_QPERCENTILE_H + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/src/query/src/qAggMain.c b/src/query/src/qAggMain.c index 0427d65561ab48dc9bf5cb460a82510b4a97b4ce..3c7fd794bf88e0fee53e7d7c40bdf91a832b89f3 100644 --- a/src/query/src/qAggMain.c +++ b/src/query/src/qAggMain.c @@ -2545,7 +2545,7 @@ static void percentile_next_step(SQLFunctionCtx *pCtx) { if (pInfo->numOfElems == 0) { pResInfo->complete = true; } else { - pInfo->pMemBucket = tMemBucketCreate(pCtx->inputBytes, pCtx->inputType, GET_DOUBLE_VAL(&pInfo->minval), GET_DOUBLE_VAL(&pInfo->maxval)); + pInfo->pMemBucket = tMemBucketCreate(pCtx->inputBytes, pCtx->inputType, pInfo->minval, pInfo->maxval); } pInfo->stage += 1; diff --git a/src/query/src/qExecutor.c b/src/query/src/qExecutor.c index 261ba86bdae44eaf4c6ecb2e678ca1b6af99d33c..4978a27d4f415a95f70b60aa2fd1b419a786c2b8 100644 --- a/src/query/src/qExecutor.c +++ b/src/query/src/qExecutor.c @@ -3168,6 +3168,10 @@ void copyResToQueryResultBuf(SQInfo *pQInfo, SQuery *pQuery) { // all results in current group have been returned to client, try next group if (pGroupResInfo->index >= taosArrayGetSize(pGroupResInfo->pRows)) { // current results of group has been sent to client, try next group + pGroupResInfo->index = 0; + pGroupResInfo->rowId = 0; + taosArrayClear(pGroupResInfo->pRows); + if (mergeGroupResult(pQInfo) != TSDB_CODE_SUCCESS) { return; // failed to save data in the disk } diff --git a/src/query/src/qPercentile.c b/src/query/src/qPercentile.c index 51125d62b92e022369d9332b78cb12a8650c75d9..3e4891092a9696f871f2295555156730bd7b224a 100644 --- a/src/query/src/qPercentile.c +++ b/src/query/src/qPercentile.c @@ -12,14 +12,14 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ +#include "os.h" #include "qPercentile.h" #include "qResultbuf.h" -#include "os.h" #include "queryLog.h" #include "taosdef.h" -#include "tulog.h" #include "tcompare.h" +#include "ttype.h" #define DEFAULT_NUM_OF_SLOT 1024 @@ -48,25 +48,15 @@ static tFilePage *loadDataFromFilePage(tMemBucket *pMemBucket, int32_t slotIdx) } static void resetBoundingBox(MinMaxEntry* range, int32_t type) { - switch (type) { - case TSDB_DATA_TYPE_BIGINT: { - range->i64MaxVal = INT64_MIN; - range->i64MinVal = INT64_MAX; - break; - }; - case TSDB_DATA_TYPE_INT: - case TSDB_DATA_TYPE_SMALLINT: - case TSDB_DATA_TYPE_TINYINT: { - range->iMaxVal = INT32_MIN; - range->iMinVal = INT32_MAX; - break; - }; - case TSDB_DATA_TYPE_DOUBLE: - case TSDB_DATA_TYPE_FLOAT: { - range->dMaxVal = -DBL_MAX; - range->dMinVal = DBL_MAX; - break; - } + if (IS_SIGNED_NUMERIC_TYPE(type)) { + range->i64MaxVal = INT64_MIN; + range->i64MinVal = INT64_MAX; + } else if (IS_UNSIGNED_NUMERIC_TYPE(type)) { + range->u64MaxVal = 0; + range->u64MinVal = UINT64_MAX; + } else { + range->dMaxVal = -DBL_MAX; + range->dMinVal = DBL_MAX; } } @@ -75,23 +65,15 @@ static int32_t setBoundingBox(MinMaxEntry* range, int16_t type, double minval, d return -1; } - switch(type) { - case TSDB_DATA_TYPE_TINYINT: - case TSDB_DATA_TYPE_SMALLINT: - case TSDB_DATA_TYPE_INT: - range->iMinVal = (int32_t) minval; - range->iMaxVal = (int32_t) maxval; - break; - - case TSDB_DATA_TYPE_BIGINT: - range->i64MinVal = (int64_t) minval; - range->i64MaxVal = (int64_t) maxval; - break; - case TSDB_DATA_TYPE_FLOAT: - case TSDB_DATA_TYPE_DOUBLE: - range->dMinVal = minval; - range->dMaxVal = maxval; - break; + if (IS_SIGNED_NUMERIC_TYPE(type)) { + range->i64MinVal = (int64_t) minval; + range->i64MaxVal = (int64_t) maxval; + } else if (IS_UNSIGNED_NUMERIC_TYPE(type)){ + range->u64MinVal = (uint64_t) minval; + range->u64MaxVal = (uint64_t) maxval; + } else { + range->dMinVal = minval; + range->dMaxVal = maxval; } return 0; @@ -120,117 +102,56 @@ double findOnlyResult(tMemBucket *pMemBucket) { tFilePage* pPage = getResBufPage(pMemBucket->pBuffer, pgInfo->pageId); assert(pPage->num == 1); - switch (pMemBucket->type) { - case TSDB_DATA_TYPE_INT: - return *(int32_t *)pPage->data; - case TSDB_DATA_TYPE_SMALLINT: - return *(int16_t *)pPage->data; - case TSDB_DATA_TYPE_TINYINT: - return *(int8_t *)pPage->data; - case TSDB_DATA_TYPE_BIGINT: - return (double)(*(int64_t *)pPage->data); - case TSDB_DATA_TYPE_DOUBLE: { - double dv = GET_DOUBLE_VAL(pPage->data); - return dv; - } - case TSDB_DATA_TYPE_FLOAT: { - float fv = GET_FLOAT_VAL(pPage->data); - return fv; - } - default: - return 0; - } + double v = 0; + GET_TYPED_DATA(v, double, pMemBucket->type, pPage->data); + return v; } return 0; } -int32_t tBucketBigIntHash(tMemBucket *pBucket, const void *value) { - int64_t v = *(int64_t *)value; - int32_t index = -1; - - int32_t halfSlot = pBucket->numOfSlots >> 1; -// int32_t bits = 32;//bitsOfNumber(pBucket->numOfSlots) - 1; - - if (pBucket->range.i64MaxVal == INT64_MIN) { - if (v >= 0) { - index = (v >> (64 - 9)) + halfSlot; - } else { // v<0 - index = ((-v) >> (64 - 9)); - index = -index + (halfSlot - 1); - } +int32_t tBucketIntHash(tMemBucket *pBucket, const void *value) { + int64_t v = 0; + GET_TYPED_DATA(v, int64_t, pBucket->type, value); - return index; + int32_t index = -1; + // divide the value range into 1024 buckets + uint64_t span = pBucket->range.i64MaxVal - pBucket->range.i64MinVal; + if (span < pBucket->numOfSlots) { + int64_t delta = v - pBucket->range.i64MinVal; + index = (delta % pBucket->numOfSlots); } else { - // out of range - if (v < pBucket->range.i64MinVal || v > pBucket->range.i64MaxVal) { - return -1; + double slotSpan = (double)span / pBucket->numOfSlots; + index = (int32_t)((v - pBucket->range.i64MinVal) / slotSpan); + if (v == pBucket->range.i64MaxVal) { + index -= 1; } - - // todo hash for bigint and float and double - int64_t span = pBucket->range.i64MaxVal - pBucket->range.i64MinVal; - if (span < pBucket->numOfSlots) { - int32_t delta = (int32_t)(v - pBucket->range.i64MinVal); - index = delta % pBucket->numOfSlots; - } else { - double slotSpan = (double)span / pBucket->numOfSlots; - index = (int32_t)((v - pBucket->range.i64MinVal) / slotSpan); - if (v == pBucket->range.i64MaxVal) { - index -= 1; - } - } - - return index; } + + assert(v >= pBucket->range.i64MinVal && v <= pBucket->range.i64MaxVal && index >= 0 && index < pBucket->numOfSlots); + return index; } -// todo refactor to more generic -int32_t tBucketIntHash(tMemBucket *pBucket, const void *value) { - int32_t v = 0; - switch(pBucket->type) { - case TSDB_DATA_TYPE_SMALLINT: v = *(int16_t*) value; break; - case TSDB_DATA_TYPE_TINYINT: v = *(int8_t*) value; break; - default: v = *(int32_t*) value;break; - } +int32_t tBucketUintHash(tMemBucket *pBucket, const void *value) { + int64_t v = 0; + GET_TYPED_DATA(v, uint64_t, pBucket->type, value); int32_t index = -1; - if (pBucket->range.iMaxVal == INT32_MIN) { - /* - * taking negative integer into consideration, - * there is only half of pBucket->segs available for non-negative integer - */ - int32_t halfSlot = pBucket->numOfSlots >> 1; - int32_t bits = 32;//bitsOfNumber(pBucket->numOfSlots) - 1; - - if (v >= 0) { - index = (v >> (bits - 9)) + halfSlot; - } else { // v < 0 - index = ((-v) >> (32 - 9)); - index = -index + (halfSlot - 1); - } - - return index; + // divide the value range into 1024 buckets + uint64_t span = pBucket->range.u64MaxVal - pBucket->range.u64MinVal; + if (span < pBucket->numOfSlots) { + int64_t delta = v - pBucket->range.u64MinVal; + index = (int32_t) (delta % pBucket->numOfSlots); } else { - // out of range - if (v < pBucket->range.iMinVal || v > pBucket->range.iMaxVal) { - return -1; + double slotSpan = (double)span / pBucket->numOfSlots; + index = (int32_t)((v - pBucket->range.u64MinVal) / slotSpan); + if (v == pBucket->range.u64MaxVal) { + index -= 1; } - - // divide a range of [iMinVal, iMaxVal] into 1024 buckets - int32_t span = pBucket->range.iMaxVal - pBucket->range.iMinVal; - if (span < pBucket->numOfSlots) { - int32_t delta = v - pBucket->range.iMinVal; - index = (delta % pBucket->numOfSlots); - } else { - double slotSpan = (double)span / pBucket->numOfSlots; - index = (int32_t)((v - pBucket->range.iMinVal) / slotSpan); - if (v == pBucket->range.iMaxVal) { - index -= 1; - } - } - - return index; } + + assert(v >= pBucket->range.u64MinVal && v <= pBucket->range.i64MaxVal && index >= 0 && index < pBucket->numOfSlots); + return index; } int32_t tBucketDoubleHash(tMemBucket *pBucket, const void *value) { @@ -243,62 +164,30 @@ int32_t tBucketDoubleHash(tMemBucket *pBucket, const void *value) { int32_t index = -1; - if (pBucket->range.dMinVal == DBL_MAX) { - /* - * taking negative integer into consideration, - * there is only half of pBucket->segs available for non-negative integer - */ - double x = DBL_MAX / (pBucket->numOfSlots >> 1); - double posx = (v + DBL_MAX) / x; - return ((int32_t)posx) % pBucket->numOfSlots; + // divide a range of [dMinVal, dMaxVal] into 1024 buckets + double span = pBucket->range.dMaxVal - pBucket->range.dMinVal; + if (span < pBucket->numOfSlots) { + int32_t delta = (int32_t)(v - pBucket->range.dMinVal); + index = (delta % pBucket->numOfSlots); } else { - - // out of range - if (v < pBucket->range.dMinVal || v > pBucket->range.dMaxVal) { - return -1; + double slotSpan = span / pBucket->numOfSlots; + index = (int32_t)((v - pBucket->range.dMinVal) / slotSpan); + if (v == pBucket->range.dMaxVal) { + index -= 1; } - - // divide a range of [dMinVal, dMaxVal] into 1024 buckets - double span = pBucket->range.dMaxVal - pBucket->range.dMinVal; - if (span < pBucket->numOfSlots) { - int32_t delta = (int32_t)(v - pBucket->range.dMinVal); - index = (delta % pBucket->numOfSlots); - } else { - double slotSpan = span / pBucket->numOfSlots; - index = (int32_t)((v - pBucket->range.dMinVal) / slotSpan); - if (v == pBucket->range.dMaxVal) { - index -= 1; - } - } - - if (index < 0 || index > pBucket->numOfSlots) { - uError("error in hash process. slot id: %d", index); - } - - return index; } + + assert(v >= pBucket->range.dMinVal && v <= pBucket->range.dMaxVal && index >= 0 && index < pBucket->numOfSlots); + return index; } static __perc_hash_func_t getHashFunc(int32_t type) { - switch (type) { - case TSDB_DATA_TYPE_INT: - case TSDB_DATA_TYPE_SMALLINT: - case TSDB_DATA_TYPE_TINYINT: { - return tBucketIntHash; - }; - - case TSDB_DATA_TYPE_DOUBLE: - case TSDB_DATA_TYPE_FLOAT: { - return tBucketDoubleHash; - }; - - case TSDB_DATA_TYPE_BIGINT: { - return tBucketBigIntHash; - }; - - default: { - return NULL; - } + if (IS_SIGNED_NUMERIC_TYPE(type)) { + return tBucketIntHash; + } else if (IS_UNSIGNED_NUMERIC_TYPE(type)) { + return tBucketUintHash; + } else { + return tBucketDoubleHash; } } @@ -328,7 +217,7 @@ tMemBucket *tMemBucketCreate(int16_t nElemSize, int16_t dataType, double minval, pBucket->maxCapacity = 200000; if (setBoundingBox(&pBucket->range, pBucket->type, minval, maxval) != 0) { - uError("MemBucket:%p, invalid value range: %f-%f", pBucket, minval, maxval); + qError("MemBucket:%p, invalid value range: %f-%f", pBucket, minval, maxval); free(pBucket); return NULL; } @@ -338,7 +227,7 @@ tMemBucket *tMemBucketCreate(int16_t nElemSize, int16_t dataType, double minval, pBucket->hashFunc = getHashFunc(pBucket->type); if (pBucket->hashFunc == NULL) { - uError("MemBucket:%p, not support data type %d, failed", pBucket, pBucket->type); + qError("MemBucket:%p, not support data type %d, failed", pBucket, pBucket->type); free(pBucket); return NULL; } @@ -357,7 +246,7 @@ tMemBucket *tMemBucketCreate(int16_t nElemSize, int16_t dataType, double minval, return NULL; } - uDebug("MemBucket:%p, elem size:%d", pBucket, pBucket->bytes); + qDebug("MemBucket:%p, elem size:%d", pBucket, pBucket->bytes); return pBucket; } @@ -372,77 +261,41 @@ void tMemBucketDestroy(tMemBucket *pBucket) { } void tMemBucketUpdateBoundingBox(MinMaxEntry *r, const char *data, int32_t dataType) { - switch (dataType) { - case TSDB_DATA_TYPE_INT: { - int32_t val = *(int32_t *)data; - if (r->iMinVal > val) { - r->iMinVal = val; - } + if (IS_SIGNED_NUMERIC_TYPE(dataType)) { + int64_t v = 0; + GET_TYPED_DATA(v, int64_t, dataType, data); - if (r->iMaxVal < val) { - r->iMaxVal = val; - } - break; - }; - case TSDB_DATA_TYPE_BIGINT: { - int64_t val = *(int64_t *)data; - if (r->i64MinVal > val) { - r->i64MinVal = val; - } - - if (r->i64MaxVal < val) { - r->i64MaxVal = val; - } - break; - }; - case TSDB_DATA_TYPE_SMALLINT: { - int32_t val = *(int16_t *)data; - if (r->iMinVal > val) { - r->iMinVal = val; - } - - if (r->iMaxVal < val) { - r->iMaxVal = val; - } - break; - }; - case TSDB_DATA_TYPE_TINYINT: { - int32_t val = *(int8_t *)data; - if (r->iMinVal > val) { - r->iMinVal = val; - } + if (r->i64MinVal > v) { + r->i64MinVal = v; + } - if (r->iMaxVal < val) { - r->iMaxVal = val; - } + if (r->i64MaxVal < v) { + r->i64MaxVal = v; + } + } else if (IS_UNSIGNED_NUMERIC_TYPE(dataType)) { + uint64_t v = 0; + GET_TYPED_DATA(v, uint64_t, dataType, data); - break; - }; - case TSDB_DATA_TYPE_DOUBLE: { - // double val = *(double *)data; - double val = GET_DOUBLE_VAL(data); - if (r->dMinVal > val) { - r->dMinVal = val; - } + if (r->i64MinVal > v) { + r->i64MinVal = v; + } - if (r->dMaxVal < val) { - r->dMaxVal = val; - } - break; - }; - case TSDB_DATA_TYPE_FLOAT: { - double val = GET_FLOAT_VAL(data); + if (r->i64MaxVal < v) { + r->i64MaxVal = v; + } + } else if (IS_FLOAT_TYPE(dataType)) { + double v = 0; + GET_TYPED_DATA(v, double, dataType, data); - if (r->dMinVal > val) { - r->dMinVal = val; - } + if (r->dMinVal > v) { + r->dMinVal = v; + } - if (r->dMaxVal < val) { - r->dMaxVal = val; - } - break; - }; - default: { assert(false); } + if (r->dMaxVal < v) { + r->dMaxVal = v; + } + } else { + assert(0); } } @@ -452,16 +305,13 @@ void tMemBucketUpdateBoundingBox(MinMaxEntry *r, const char *data, int32_t dataT int32_t tMemBucketPut(tMemBucket *pBucket, const void *data, size_t size) { assert(pBucket != NULL && data != NULL && size > 0); - pBucket->total += (int32_t)size; - + int32_t count = 0; int32_t bytes = pBucket->bytes; for (int32_t i = 0; i < size; ++i) { char *d = (char *) data + i * bytes; + count += 1; int32_t index = (pBucket->hashFunc)(pBucket, d); - if (index == -1) { // the value is out of range, do not add it into bucket - return -1; - } tMemBucketSlot *pSlot = &pBucket->pSlots[index]; tMemBucketUpdateBoundingBox(&pSlot->range, d, pBucket->type); @@ -489,64 +339,11 @@ int32_t tMemBucketPut(tMemBucket *pBucket, const void *data, size_t size) { pSlot->info.size += 1; } + pBucket->total += count; return 0; } //////////////////////////////////////////////////////////////////////////////////////////// -static UNUSED_FUNC void findMaxMinValue(tMemBucket *pMemBucket, double *maxVal, double *minVal) { - *minVal = DBL_MAX; - *maxVal = -DBL_MAX; - - for (int32_t i = 0; i < pMemBucket->numOfSlots; ++i) { - tMemBucketSlot *pSlot = &pMemBucket->pSlots[i]; - if (pSlot->info.size == 0) { - continue; - } - - switch (pMemBucket->type) { - case TSDB_DATA_TYPE_INT: - case TSDB_DATA_TYPE_SMALLINT: - case TSDB_DATA_TYPE_TINYINT: { - double minv = pSlot->range.iMinVal; - double maxv = pSlot->range.iMaxVal; - - if (*minVal > minv) { - *minVal = minv; - } - if (*maxVal < maxv) { - *maxVal = maxv; - } - break; - } - case TSDB_DATA_TYPE_DOUBLE: - case TSDB_DATA_TYPE_FLOAT: { - double minv = pSlot->range.dMinVal; - double maxv = pSlot->range.dMaxVal; - - if (*minVal > minv) { - *minVal = minv; - } - if (*maxVal < maxv) { - *maxVal = maxv; - } - break; - } - case TSDB_DATA_TYPE_BIGINT: { - double minv = (double)pSlot->range.i64MinVal; - double maxv = (double)pSlot->range.i64MaxVal; - - if (*minVal > minv) { - *minVal = minv; - } - if (*maxVal < maxv) { - *maxVal = maxv; - } - break; - } - } - } -} - /* * * now, we need to find the minimum value of the next slot for @@ -565,7 +362,6 @@ static MinMaxEntry getMinMaxEntryOfNextSlotWithData(tMemBucket *pMemBucket, int3 } static bool isIdenticalData(tMemBucket *pMemBucket, int32_t index); -char *getFirstElemOfMemBuffer(tMemBucketSlot *pSeg, int32_t slotIdx, tFilePage *pPage); static double getIdenticalDataVal(tMemBucket* pMemBucket, int32_t slotIndex) { assert(isIdenticalData(pMemBucket, slotIndex)); @@ -573,24 +369,12 @@ static double getIdenticalDataVal(tMemBucket* pMemBucket, int32_t slotIndex) { tMemBucketSlot *pSlot = &pMemBucket->pSlots[slotIndex]; double finalResult = 0.0; - switch (pMemBucket->type) { - case TSDB_DATA_TYPE_SMALLINT: - case TSDB_DATA_TYPE_TINYINT: - case TSDB_DATA_TYPE_INT: { - finalResult = pSlot->range.iMinVal; - break; - } - - case TSDB_DATA_TYPE_FLOAT: - case TSDB_DATA_TYPE_DOUBLE: { - finalResult = pSlot->range.dMinVal; - break; - }; - - case TSDB_DATA_TYPE_BIGINT: { - finalResult = (double)pSlot->range.i64MinVal; - break; - } + if (IS_SIGNED_NUMERIC_TYPE(pMemBucket->type)) { + finalResult = (double) pSlot->range.i64MinVal; + } else if (IS_UNSIGNED_NUMERIC_TYPE(pMemBucket->type)) { + finalResult = (double) pSlot->range.u64MinVal; + } else { + finalResult = (double) pSlot->range.dMinVal; } return finalResult; @@ -616,26 +400,16 @@ double getPercentileImpl(tMemBucket *pMemBucket, int32_t count, double fraction) double maxOfThisSlot = 0; double minOfNextSlot = 0; - switch (pMemBucket->type) { - case TSDB_DATA_TYPE_INT: - case TSDB_DATA_TYPE_SMALLINT: - case TSDB_DATA_TYPE_TINYINT: { - maxOfThisSlot = pSlot->range.iMaxVal; - minOfNextSlot = next.iMinVal; - break; - }; - case TSDB_DATA_TYPE_FLOAT: - case TSDB_DATA_TYPE_DOUBLE: { - maxOfThisSlot = pSlot->range.dMaxVal; - minOfNextSlot = next.dMinVal; - break; - }; - case TSDB_DATA_TYPE_BIGINT: { - maxOfThisSlot = (double)pSlot->range.i64MaxVal; - minOfNextSlot = (double)next.i64MinVal; - break; - } - }; + if (IS_SIGNED_NUMERIC_TYPE(pMemBucket->type)) { + maxOfThisSlot = (double) pSlot->range.i64MaxVal; + minOfNextSlot = (double) next.i64MinVal; + } else if (IS_UNSIGNED_NUMERIC_TYPE(pMemBucket->type)) { + maxOfThisSlot = (double) pSlot->range.u64MaxVal; + minOfNextSlot = (double) next.u64MinVal; + } else { + maxOfThisSlot = (double) pSlot->range.dMaxVal; + minOfNextSlot = (double) next.dMinVal; + } assert(minOfNextSlot > maxOfThisSlot); @@ -652,38 +426,8 @@ double getPercentileImpl(tMemBucket *pMemBucket, int32_t count, double fraction) char *nextVal = thisVal + pMemBucket->bytes; double td = 1.0, nd = 1.0; - switch (pMemBucket->type) { - case TSDB_DATA_TYPE_SMALLINT: { - td = *(int16_t *)thisVal; - nd = *(int16_t *)nextVal; - break; - } - case TSDB_DATA_TYPE_TINYINT: { - td = *(int8_t *)thisVal; - nd = *(int8_t *)nextVal; - break; - } - case TSDB_DATA_TYPE_INT: { - td = *(int32_t *)thisVal; - nd = *(int32_t *)nextVal; - break; - }; - case TSDB_DATA_TYPE_FLOAT: { - td = GET_FLOAT_VAL(thisVal); - nd = GET_FLOAT_VAL(nextVal); - break; - } - case TSDB_DATA_TYPE_DOUBLE: { - td = GET_DOUBLE_VAL(thisVal); - nd = GET_DOUBLE_VAL(nextVal); - break; - } - case TSDB_DATA_TYPE_BIGINT: { - td = (double)*(int64_t *)thisVal; - nd = (double)*(int64_t *)nextVal; - break; - } - } + GET_TYPED_DATA(td, double, pMemBucket->type, thisVal); + GET_TYPED_DATA(nd, double, pMemBucket->type, nextVal); double val = (1 - fraction) * td + fraction * nd; tfree(buffer); @@ -696,7 +440,7 @@ double getPercentileImpl(tMemBucket *pMemBucket, int32_t count, double fraction) // try next round pMemBucket->times += 1; - uDebug("MemBucket:%p, start next round data bucketing, time:%d", pMemBucket, pMemBucket->times); + qDebug("MemBucket:%p, start next round data bucketing, time:%d", pMemBucket, pMemBucket->times); pMemBucket->range = pSlot->range; pMemBucket->total = 0; @@ -741,20 +485,14 @@ double getPercentile(tMemBucket *pMemBucket, double percent) { if (fabs(percent - 100.0) < DBL_EPSILON || (percent < DBL_EPSILON)) { MinMaxEntry* pRange = &pMemBucket->range; - switch(pMemBucket->type) { - case TSDB_DATA_TYPE_TINYINT: - case TSDB_DATA_TYPE_SMALLINT: - case TSDB_DATA_TYPE_INT: - return fabs(percent - 100) < DBL_EPSILON? pRange->iMaxVal:pRange->iMinVal; - case TSDB_DATA_TYPE_BIGINT: { - double v = (double)(fabs(percent - 100) < DBL_EPSILON ? pRange->i64MaxVal : pRange->i64MinVal); - return v; - } - case TSDB_DATA_TYPE_FLOAT: - case TSDB_DATA_TYPE_DOUBLE: - return fabs(percent - 100) < DBL_EPSILON? pRange->dMaxVal:pRange->dMinVal; - default: - return -1; + if (IS_SIGNED_NUMERIC_TYPE(pMemBucket->type)) { + double v = (double)(fabs(percent - 100) < DBL_EPSILON ? pRange->i64MaxVal : pRange->i64MinVal); + return v; + } else if (IS_UNSIGNED_NUMERIC_TYPE(pMemBucket->type)) { + double v = (double)(fabs(percent - 100) < DBL_EPSILON ? pRange->u64MaxVal : pRange->u64MinVal); + return v; + } else { + return fabs(percent - 100) < DBL_EPSILON? pRange->dMaxVal:pRange->dMinVal; } } @@ -771,40 +509,9 @@ double getPercentile(tMemBucket *pMemBucket, double percent) { bool isIdenticalData(tMemBucket *pMemBucket, int32_t index) { tMemBucketSlot *pSeg = &pMemBucket->pSlots[index]; - if (pMemBucket->type == TSDB_DATA_TYPE_INT || pMemBucket->type == TSDB_DATA_TYPE_BIGINT || - pMemBucket->type == TSDB_DATA_TYPE_SMALLINT || pMemBucket->type == TSDB_DATA_TYPE_TINYINT) { - return pSeg->range.i64MinVal == pSeg->range.i64MaxVal; - } - - if (pMemBucket->type == TSDB_DATA_TYPE_FLOAT || pMemBucket->type == TSDB_DATA_TYPE_DOUBLE) { + if (IS_FLOAT_TYPE(pMemBucket->type)) { return fabs(pSeg->range.dMaxVal - pSeg->range.dMinVal) < DBL_EPSILON; + } else { + return pSeg->range.i64MinVal == pSeg->range.i64MaxVal; } - - return false; -} - -/* - * get the first element of one slot into memory. - * if no data of current slot in memory, load it from disk - */ -char *getFirstElemOfMemBuffer(tMemBucketSlot *pSeg, int32_t slotIdx, tFilePage *pPage) { -// STSBuf *pMemBuffer = pSeg->pBuffer[slotIdx]; - char *thisVal = NULL; - -// if (pSeg->pBuffer[slotIdx]->numOfTotal != 0) { -//// thisVal = pSeg->pBuffer[slotIdx]->pHead->item.data; -// } else { -// /* -// * no data in memory, load one page into memory -// */ -// tFlushoutInfo *pFlushInfo = &pMemBuffer->fileMeta.flushoutData.pFlushoutInfo[0]; -// assert(pFlushInfo->numOfPages == pMemBuffer->fileMeta.nFileSize); -// int32_t ret; -// ret = fseek(pMemBuffer->file, pFlushInfo->startPageId * pMemBuffer->pageSize, SEEK_SET); -// UNUSED(ret); -// size_t sz = fread(pPage, pMemBuffer->pageSize, 1, pMemBuffer->file); -// UNUSED(sz); -// thisVal = pPage->data; -// } - return thisVal; } diff --git a/src/query/tests/CMakeLists.txt b/src/query/tests/CMakeLists.txt index 1856223391ae719ef98492160da9810826b983a9..c3798b869eb6c02008043346d70b52592239cad0 100644 --- a/src/query/tests/CMakeLists.txt +++ b/src/query/tests/CMakeLists.txt @@ -1,4 +1,4 @@ -CMAKE_MINIMUM_REQUIRED(VERSION 2.8) +CMAKE_MINIMUM_REQUIRED(VERSION 3.5) PROJECT(TDengine) FIND_PATH(HEADER_GTEST_INCLUDE_DIR gtest.h /usr/include/gtest /usr/local/include/gtest) diff --git a/src/query/tests/percentileTest.cpp b/src/query/tests/percentileTest.cpp new file mode 100644 index 0000000000000000000000000000000000000000..f1fc45850138ba287b4597c51c4bb5220626ad8b --- /dev/null +++ b/src/query/tests/percentileTest.cpp @@ -0,0 +1,254 @@ +#include +#include + +#include "qResultbuf.h" +#include "taos.h" +#include "taosdef.h" + +#include "qPercentile.h" + +namespace { +tMemBucket *createBigIntDataBucket(int32_t start, int32_t end) { + tMemBucket *pBucket = tMemBucketCreate(sizeof(int64_t), TSDB_DATA_TYPE_BIGINT, start, end); + for (int32_t i = start; i <= end; ++i) { + int64_t val = i; + tMemBucketPut(pBucket, &val, 1); + } + + return pBucket; +} + +tMemBucket *createIntDataBucket(int32_t start, int32_t end) { + tMemBucket *pBucket = tMemBucketCreate(sizeof(int32_t), TSDB_DATA_TYPE_INT, start, end); + + for (int32_t i = start; i <= end; ++i) { + int32_t val = i; + tMemBucketPut(pBucket, &val, 1); + } + + return pBucket; +} + +tMemBucket *createDoubleDataBucket(int32_t start, int32_t end) { + tMemBucket *pBucket = tMemBucketCreate(sizeof(double), TSDB_DATA_TYPE_DOUBLE, start, end); + for (int32_t i = start; i <= end; ++i) { + double val = i; + int32_t ret = tMemBucketPut(pBucket, &val, 1); + if (ret != 0) { + printf("value out of range:%f", val); + } + } + + return pBucket; +} + +tMemBucket *createUnsignedDataBucket(int32_t start, int32_t end, int32_t type) { + tMemBucket *pBucket = tMemBucketCreate(tDataTypeDesc[type].nSize, type, start, end); + for (int32_t i = start; i <= end; ++i) { + uint64_t k = i; + int32_t ret = tMemBucketPut(pBucket, &k, 1); + if (ret != 0) { + printf("value out of range:%f", k); + } + } + + return pBucket; +} + +void intDataTest() { + printf("running %s\n", __FUNCTION__); + + tMemBucket *pBucket = NULL; + double result = 0.; + + pBucket = createIntDataBucket(0, 0); + result = getPercentile(pBucket, 0); + ASSERT_DOUBLE_EQ(result, 0); + tMemBucketDestroy(pBucket); + + pBucket = createIntDataBucket(0, 1); + result = getPercentile(pBucket, 100); + ASSERT_DOUBLE_EQ(result, 1); + + result = getPercentile(pBucket, 0); + ASSERT_DOUBLE_EQ(result, 0); + tMemBucketDestroy(pBucket); + + pBucket = createIntDataBucket(-1, 1); + + result = getPercentile(pBucket, 50); + ASSERT_DOUBLE_EQ(result, 0); + + result = getPercentile(pBucket, 0); + ASSERT_DOUBLE_EQ(result, -1); + + result = getPercentile(pBucket, 75); + ASSERT_DOUBLE_EQ(result, 0.5); + + result = getPercentile(pBucket, 100); + ASSERT_DOUBLE_EQ(result, 1); + tMemBucketDestroy(pBucket); + + pBucket = createIntDataBucket(0, 99999); + result = getPercentile(pBucket, 50); + ASSERT_DOUBLE_EQ(result, 49999.5); + + tMemBucketDestroy(pBucket); +} + +void bigintDataTest() { + printf("running %s\n", __FUNCTION__); + + tMemBucket *pBucket = NULL; + double result = 0.0; + + pBucket = createBigIntDataBucket(-1000, 1000); + result = getPercentile(pBucket, 50); + ASSERT_DOUBLE_EQ(result, 0.); + tMemBucketDestroy(pBucket); + + pBucket = createBigIntDataBucket(-10000, 10000); + result = getPercentile(pBucket, 100); + ASSERT_DOUBLE_EQ(result, 10000.0); + tMemBucketDestroy(pBucket); + + pBucket = createBigIntDataBucket(-10000, 10000); + result = getPercentile(pBucket, 75); + ASSERT_DOUBLE_EQ(result, 5000.0); + + tMemBucketDestroy(pBucket); +} + +void doubleDataTest() { + printf("running %s\n", __FUNCTION__); + + tMemBucket *pBucket = NULL; + double result = 0; + + pBucket = createDoubleDataBucket(-10, 10); + result = getPercentile(pBucket, 0); + ASSERT_DOUBLE_EQ(result, -10.0); + + printf("result is: %lf\n", result); + tMemBucketDestroy(pBucket); + + pBucket = createDoubleDataBucket(-100000, 100000); + result = getPercentile(pBucket, 25); + ASSERT_DOUBLE_EQ(result, -50000); + + printf("result is: %lf\n", result); + + tMemBucketDestroy(pBucket); + + pBucket = createDoubleDataBucket(-100000, 100000); + result = getPercentile(pBucket, 50); + ASSERT_DOUBLE_EQ(result, 0); + + tMemBucketDestroy(pBucket); + + pBucket = createDoubleDataBucket(-100000, 100000); + result = getPercentile(pBucket, 75); + ASSERT_DOUBLE_EQ(result, 50000); + tMemBucketDestroy(pBucket); + + pBucket = createDoubleDataBucket(-100000, 100000); + + result = getPercentile(pBucket, 100); + ASSERT_DOUBLE_EQ(result, 100000.0); + + printf("result is: %lf\n", result); + tMemBucketDestroy(pBucket); +} + +/* + * large data test, we employ 0.1billion double data to calculated the percentile + * which is 800MB data + */ +void largeDataTest() { + printf("running : %s\n", __FUNCTION__); + + tMemBucket *pBucket = NULL; + double result = 0; + + struct timeval tv; + gettimeofday(&tv, NULL); + + int64_t start = tv.tv_sec; + printf("start time: %" PRId64 "\n", tv.tv_sec); + pBucket = createDoubleDataBucket(0, 100000000); + result = getPercentile(pBucket, 50); + ASSERT_DOUBLE_EQ(result, 50000000); + + gettimeofday(&tv, NULL); + + printf("total elapsed time: %" PRId64 " sec.", -start + tv.tv_sec); + printf("the result of %d is: %lf\n", 50, result); + tMemBucketDestroy(pBucket); +} + +void qsortTest() { + printf("running : %s\n", __FUNCTION__); + + SSchema field[1] = { + {TSDB_DATA_TYPE_INT, "k", sizeof(int32_t)}, + }; + + const int32_t num = 2000; + + int32_t *d = (int32_t *)malloc(sizeof(int32_t) * num); + for (int32_t i = 0; i < num; ++i) { + d[i] = i % 4; + } + + const int32_t numOfOrderCols = 1; + int32_t orderColIdx = 0; + SColumnModel * pModel = createColumnModel(field, 1, 1000); + tOrderDescriptor *pDesc = tOrderDesCreate(&orderColIdx, numOfOrderCols, pModel, 1); + + tColDataQSort(pDesc, num, 0, num - 1, (char *)d, 1); + + for (int32_t i = 0; i < num; ++i) { + printf("%d\t", d[i]); + } + printf("\n"); + + destroyColumnModel(pModel); +} + +void unsignedDataTest() { + printf("running %s\n", __FUNCTION__); + + tMemBucket *pBucket = NULL; + double result = 0.0; + + pBucket = createUnsignedDataBucket(0, 1000, TSDB_DATA_TYPE_UINT); + result = getPercentile(pBucket, 50); + ASSERT_DOUBLE_EQ(result, 500.0); + tMemBucketDestroy(pBucket); + + pBucket = createUnsignedDataBucket(0, 10000, TSDB_DATA_TYPE_UBIGINT); + result = getPercentile(pBucket, 100); + ASSERT_DOUBLE_EQ(result, 10000.0); + + result = getPercentile(pBucket, 0); + ASSERT_DOUBLE_EQ(result, 0.0); + + result = getPercentile(pBucket, 50); + ASSERT_DOUBLE_EQ(result, 5000); + + result = getPercentile(pBucket, 75); + ASSERT_DOUBLE_EQ(result, 7500); + tMemBucketDestroy(pBucket); + +} + +} // namespace + +TEST(testCase, percentileTest) { + // qsortTest(); + intDataTest(); + bigintDataTest(); + doubleDataTest(); + unsignedDataTest(); + largeDataTest(); +} diff --git a/src/rpc/CMakeLists.txt b/src/rpc/CMakeLists.txt index f94b4aeb6d21277b6b845587cd35a2c98e0bc0b0..02a1e7c2d81d13194ca819c703657df5e1f3fb3b 100644 --- a/src/rpc/CMakeLists.txt +++ b/src/rpc/CMakeLists.txt @@ -1,4 +1,4 @@ -CMAKE_MINIMUM_REQUIRED(VERSION 2.8) +CMAKE_MINIMUM_REQUIRED(VERSION 3.5) PROJECT(TDengine) INCLUDE_DIRECTORIES(inc) diff --git a/src/rpc/src/rpcMain.c b/src/rpc/src/rpcMain.c index af51733c21fa417c9a8de6d53e15ec92555f35cd..17b80a0afb6f175a73dce5cb361674030561c96e 100644 --- a/src/rpc/src/rpcMain.c +++ b/src/rpc/src/rpcMain.c @@ -1390,7 +1390,7 @@ static void rpcProcessRetryTimer(void *param, void *tmrId) { pConn->pContext->code = TSDB_CODE_RPC_NETWORK_UNAVAIL; pConn->pContext->pConn = NULL; pConn->pReqMsg = NULL; - taosTmrStart(rpcProcessConnError, 0, pConn->pContext, pRpc->tmrCtrl); + taosTmrStart(rpcProcessConnError, 1, pConn->pContext, pRpc->tmrCtrl); rpcReleaseConn(pConn); } } diff --git a/src/rpc/src/rpcTcp.c b/src/rpc/src/rpcTcp.c index 178b96c423641ccc6be84c57ca71fe7b85fd7a33..daf3bd86c168ea75c29f5229cecea1acd0c66cd3 100644 --- a/src/rpc/src/rpcTcp.c +++ b/src/rpc/src/rpcTcp.c @@ -241,7 +241,7 @@ static void *taosAcceptTcpConnection(void *arg) { } taosKeepTcpAlive(connFd); - struct timeval to={1, 0}; + struct timeval to={5, 0}; int32_t ret = taosSetSockOpt(connFd, SOL_SOCKET, SO_RCVTIMEO, &to, sizeof(to)); if (ret != 0) { taosCloseSocket(connFd); diff --git a/src/rpc/test/CMakeLists.txt b/src/rpc/test/CMakeLists.txt index 383ce1b0f64cb218800211de3576af58056c6af1..9a4bcc353d9bd1ad8ee8b6ef546f8e4a44f75559 100644 --- a/src/rpc/test/CMakeLists.txt +++ b/src/rpc/test/CMakeLists.txt @@ -1,4 +1,4 @@ -CMAKE_MINIMUM_REQUIRED(VERSION 2.8) +CMAKE_MINIMUM_REQUIRED(VERSION 3.5) PROJECT(TDengine) INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/src/rpc/inc) diff --git a/src/sync/CMakeLists.txt b/src/sync/CMakeLists.txt index aa38a56f38146bafda8a10ca786bf085bb4ea339..6a533808415929776be46a96266dd7cdaeca0bf3 100644 --- a/src/sync/CMakeLists.txt +++ b/src/sync/CMakeLists.txt @@ -1,4 +1,4 @@ -CMAKE_MINIMUM_REQUIRED(VERSION 2.8) +CMAKE_MINIMUM_REQUIRED(VERSION 3.5) PROJECT(TDengine) INCLUDE_DIRECTORIES(inc) diff --git a/src/sync/test/CMakeLists.txt b/src/sync/test/CMakeLists.txt index 27614454f9f8924de561f0907f06078b03708363..256e87580d9372f0ade7200591303211f0140952 100644 --- a/src/sync/test/CMakeLists.txt +++ b/src/sync/test/CMakeLists.txt @@ -1,4 +1,4 @@ -CMAKE_MINIMUM_REQUIRED(VERSION 2.8) +CMAKE_MINIMUM_REQUIRED(VERSION 3.5) PROJECT(TDengine) IF (TD_LINUX) diff --git a/src/tsdb/CMakeLists.txt b/src/tsdb/CMakeLists.txt index 13205e2212d189588fc33e9f470929d9cd829788..a78d6d6470488e99f69de25878994295b6a24bb7 100644 --- a/src/tsdb/CMakeLists.txt +++ b/src/tsdb/CMakeLists.txt @@ -1,4 +1,4 @@ -CMAKE_MINIMUM_REQUIRED(VERSION 2.8) +CMAKE_MINIMUM_REQUIRED(VERSION 3.5) PROJECT(TDengine) INCLUDE_DIRECTORIES(inc) diff --git a/src/util/CMakeLists.txt b/src/util/CMakeLists.txt index 3e212ba2d30fb6abb1177fb6883fedeb3626bcbb..ef9a5d7ce6ee78df2eb0d77844895150fdfaf7dc 100644 --- a/src/util/CMakeLists.txt +++ b/src/util/CMakeLists.txt @@ -1,4 +1,4 @@ -CMAKE_MINIMUM_REQUIRED(VERSION 2.8) +CMAKE_MINIMUM_REQUIRED(VERSION 3.5) PROJECT(TDengine) INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/src/rpc/inc) diff --git a/src/util/src/tcompare.c b/src/util/src/tcompare.c index 4216d6e790876d147a0fce945586abd15b830349..ba48f13b29e058f077b0d6ce044247fb541ea552 100644 --- a/src/util/src/tcompare.c +++ b/src/util/src/tcompare.c @@ -30,24 +30,32 @@ int32_t compareInt8Val(const void *pLeft, const void *pRight) { return 0; } -int32_t compareIntDoubleVal(const void *pLeft, const void *pRight) { - int64_t lhs = GET_INT64_VAL(pLeft); - double rhs = GET_DOUBLE_VAL(pRight); - if (fabs(lhs - rhs) < FLT_EPSILON) { - return 0; - } else { - return (lhs > rhs) ? 1 : -1; - } +int32_t compareUint32Val(const void *pLeft, const void *pRight) { + int32_t left = GET_UINT32_VAL(pLeft), right = GET_UINT32_VAL(pRight); + if (left > right) return 1; + if (left < right) return -1; + return 0; } -int32_t compareDoubleIntVal(const void *pLeft, const void *pRight) { - double lhs = GET_DOUBLE_VAL(pLeft); - int64_t rhs = GET_INT64_VAL(pRight); - if (fabs(lhs - rhs) < FLT_EPSILON) { - return 0; - } else { - return (lhs > rhs) ? 1 : -1; - } +int32_t compareUint64Val(const void *pLeft, const void *pRight) { + int64_t left = GET_UINT64_VAL(pLeft), right = GET_UINT64_VAL(pRight); + if (left > right) return 1; + if (left < right) return -1; + return 0; +} + +int32_t compareUint16Val(const void *pLeft, const void *pRight) { + int16_t left = GET_UINT16_VAL(pLeft), right = GET_UINT16_VAL(pRight); + if (left > right) return 1; + if (left < right) return -1; + return 0; +} + +int32_t compareUint8Val(const void* pLeft, const void* pRight) { + uint8_t left = GET_UINT8_VAL(pLeft), right = GET_UINT8_VAL(pRight); + if (left > right) return 1; + if (left < right) return -1; + return 0; } int32_t compareFloatVal(const void *pLeft, const void *pRight) { @@ -369,15 +377,24 @@ __compar_fn_t getKeyComparFunc(int32_t keyType) { case TSDB_DATA_TYPE_DOUBLE: comparFn = compareDoubleVal; break; - + case TSDB_DATA_TYPE_UTINYINT: + comparFn = compareUint8Val; + break; + case TSDB_DATA_TYPE_USMALLINT: + comparFn = compareUint16Val; + break; + case TSDB_DATA_TYPE_UINT: + comparFn = compareUint32Val; + break; + case TSDB_DATA_TYPE_UBIGINT: + comparFn = compareUint64Val; + break; case TSDB_DATA_TYPE_BINARY: comparFn = compareLenPrefixedStr; break; - case TSDB_DATA_TYPE_NCHAR: comparFn = compareLenPrefixedWStr; break; - default: comparFn = compareInt32Val; break; diff --git a/src/util/src/tsocket.c b/src/util/src/tsocket.c index 1a5c3bd64da3274773196da4a03c8c0613810f89..49b69ea0a13de346136b6196e4535afe3b7f337b 100644 --- a/src/util/src/tsocket.c +++ b/src/util/src/tsocket.c @@ -283,6 +283,7 @@ SOCKET taosOpenTcpClientSocket(uint32_t destIp, uint16_t destPort, uint32_t clie SOCKET sockFd = 0; int32_t ret; struct sockaddr_in serverAddr, clientAddr; + int32_t bufSize = 1024 * 1024; sockFd = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); @@ -300,6 +301,18 @@ SOCKET taosOpenTcpClientSocket(uint32_t destIp, uint16_t destPort, uint32_t clie return -1; } + if (taosSetSockOpt(sockFd, SOL_SOCKET, SO_SNDBUF, (void *)&bufSize, sizeof(bufSize)) != 0) { + uError("failed to set the send buffer size for TCP socket\n"); + taosCloseSocket(sockFd); + return -1; + } + + if (taosSetSockOpt(sockFd, SOL_SOCKET, SO_RCVBUF, (void *)&bufSize, sizeof(bufSize)) != 0) { + uError("failed to set the receive buffer size for TCP socket\n"); + taosCloseSocket(sockFd); + return -1; + } + if (clientIp != 0) { memset((char *)&clientAddr, 0, sizeof(clientAddr)); clientAddr.sin_family = AF_INET; diff --git a/src/util/tests/CMakeLists.txt b/src/util/tests/CMakeLists.txt index 0c96ed2a2f3dfb7f03268c9f8fbb1b0afa2397b9..6066d58416e8a5ad905e3b0706f03adc013fa445 100644 --- a/src/util/tests/CMakeLists.txt +++ b/src/util/tests/CMakeLists.txt @@ -1,4 +1,4 @@ -CMAKE_MINIMUM_REQUIRED(VERSION 2.8) +CMAKE_MINIMUM_REQUIRED(VERSION 3.5) PROJECT(TDengine) FIND_PATH(HEADER_GTEST_INCLUDE_DIR gtest.h /usr/include/gtest /usr/local/include/gtest) diff --git a/src/vnode/CMakeLists.txt b/src/vnode/CMakeLists.txt index 4b4ca708c728328d7db32fcb97b2820df5a50e75..30a38653d950d44f5ff36b825a024b40a62c1e63 100644 --- a/src/vnode/CMakeLists.txt +++ b/src/vnode/CMakeLists.txt @@ -1,4 +1,4 @@ -CMAKE_MINIMUM_REQUIRED(VERSION 2.8) +CMAKE_MINIMUM_REQUIRED(VERSION 3.5) PROJECT(TDengine) INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/src/query/inc) diff --git a/src/vnode/inc/vnodeInt.h b/src/vnode/inc/vnodeInt.h index 7adeda590a509df9554c5dc83fa66758ed8ed9d2..3ec77bbc122341935a804448eca61258c634cf58 100644 --- a/src/vnode/inc/vnodeInt.h +++ b/src/vnode/inc/vnodeInt.h @@ -67,7 +67,7 @@ typedef struct { void * qMgmt; char * rootDir; tsem_t sem; - char db[TSDB_ACCT_LEN + TSDB_DB_NAME_LEN]; + char db[TSDB_ACCT_ID_LEN + TSDB_DB_NAME_LEN]; pthread_mutex_t statusMutex; } SVnodeObj; diff --git a/src/vnode/src/vnodeWrite.c b/src/vnode/src/vnodeWrite.c index 4f6ce9d2e431d4998252741bf475d1549af0eb7a..4b9f59279cf1025e1f1fadaa30b4c5e2f9eea66f 100644 --- a/src/vnode/src/vnodeWrite.c +++ b/src/vnode/src/vnodeWrite.c @@ -52,7 +52,10 @@ int32_t vnodeProcessWrite(void *vparam, void *wparam, int32_t qtype, void *rpara int32_t code = 0; SVnodeObj *pVnode = vparam; SWalHead * pHead = wparam; - SRspRet * pRspRet = rparam; + SVWriteMsg*pWrite = rparam; + + SRspRet *pRspRet = NULL; + if (pWrite != NULL) pRspRet = &pWrite->rspRet; if (vnodeProcessWriteMsgFp[pHead->msgType] == NULL) { vError("vgId:%d, msg:%s not processed since no handle, qtype:%s hver:%" PRIu64, pVnode->vgId, @@ -85,7 +88,7 @@ int32_t vnodeProcessWrite(void *vparam, void *wparam, int32_t qtype, void *rpara // forward to peers, even it is WAL/FWD, it shall be called to update version in sync int32_t syncCode = 0; - syncCode = syncForwardToPeer(pVnode->sync, pHead, pRspRet, qtype); + syncCode = syncForwardToPeer(pVnode->sync, pHead, pWrite, qtype); if (syncCode < 0) return syncCode; // write into WAL @@ -230,7 +233,7 @@ static SVWriteMsg *vnodeBuildVWriteMsg(SVnodeObj *pVnode, SWalHead *pHead, int32 pWrite->rpcMsg = *pRpcMsg; } - memcpy(pWrite->pHead, pHead, sizeof(SWalHead) + pHead->len); + memcpy(&pWrite->pHead, pHead, sizeof(SWalHead) + pHead->len); pWrite->pVnode = pVnode; pWrite->qtype = qtype; diff --git a/src/wal/CMakeLists.txt b/src/wal/CMakeLists.txt index 359e09287a9409a7acffe27d934884cce0510bb0..681bed54258353b7ceff6df3c84909cbcadaa6b8 100644 --- a/src/wal/CMakeLists.txt +++ b/src/wal/CMakeLists.txt @@ -1,4 +1,4 @@ -CMAKE_MINIMUM_REQUIRED(VERSION 2.8) +CMAKE_MINIMUM_REQUIRED(VERSION 3.5) PROJECT(TDengine) INCLUDE_DIRECTORIES(inc) diff --git a/src/wal/test/CMakeLists.txt b/src/wal/test/CMakeLists.txt index 6c232ce4b91eecf7e8818922bbdbebbfe380e444..b8338b1738a840d43d6f073e5562f0e1ffacf851 100644 --- a/src/wal/test/CMakeLists.txt +++ b/src/wal/test/CMakeLists.txt @@ -1,4 +1,4 @@ -CMAKE_MINIMUM_REQUIRED(VERSION 2.8) +CMAKE_MINIMUM_REQUIRED(VERSION 3.5) PROJECT(TDengine) IF (TD_LINUX) diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 4e7e9a87ea6810c362bd676cd9152f61bc08e29d..57fc8b1953d155c6ab45c8adc9e4146d00fb0b39 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -3,7 +3,7 @@ # generate release version: # mkdir release; cd release; cmake -DCMAKE_BUILD_TYPE=Release .. -CMAKE_MINIMUM_REQUIRED(VERSION 2.8) +CMAKE_MINIMUM_REQUIRED(VERSION 3.5) PROJECT(TDengine) SET(CMAKE_C_STANDARD 11) diff --git a/tests/comparisonTest/tdengine/CMakeLists.txt b/tests/comparisonTest/tdengine/CMakeLists.txt index 990612b8c37a47fb9f4dc29e25f3e5c6840ff199..aaa18592ed29b6e39c97a55e68e4867684817bbf 100644 --- a/tests/comparisonTest/tdengine/CMakeLists.txt +++ b/tests/comparisonTest/tdengine/CMakeLists.txt @@ -1,4 +1,4 @@ -CMAKE_MINIMUM_REQUIRED(VERSION 2.8) +CMAKE_MINIMUM_REQUIRED(VERSION 3.5) PROJECT(TDengine) IF (TD_LINUX) diff --git a/tests/examples/C#/taosdemo/README.md b/tests/examples/C#/taosdemo/README.md index 82a8dc674af9ecd83d6e777a0e2739cabf598536..2d125fb140076c46c9abc4c60db330b28b494802 100644 --- a/tests/examples/C#/taosdemo/README.md +++ b/tests/examples/C#/taosdemo/README.md @@ -10,30 +10,27 @@ run C# version taosdemo === Usage: mono taosdemo.exe [OPTION...] - --help Show usage. + --help Show usage. - -h host, The host to connect to TDengine. Default is localhost. - -p port, The TCP/IP port number to use for the connection. Default is 0. - -u user, The user name to use when connecting to the server. Default is 'root'. - -P password, The password to use when connecting to the server. Default is 'taosdata'. - -d database, Destination database. Default is 'test'. - -a replica, Set the replica parameters of the database, Default 1, min: 1, max: 5. - -m table_prefix, Table prefix name. Default is 't'. - -s sql file, The select sql file. - -M stable, Use super table. - -o outputfile, Direct output to the named file. Default is './output.txt'. - -q query_mode, Query mode--0: SYNC, 1: ASYNC. Default is SYNC. - -b type_of_cols, data_type of columns: 'INT', 'TINYINT', 'SMALLINT', 'BIGINT', 'FLOAT', 'DOUBLE', 'BINARY'. Default is 'INT'. - -w length_of_binary, The length of data_type 'BINARY'. Only applicable when type of cols is 'BINARY'. Default is 8 - -l num_of_cols_per_record, The number of columns per record. Default is 3. - -T num_of_threads, The number of threads. Default is 10. - -r num_of_records_per_req, The number of records per request. Default is 1000. - -t num_of_tables, The number of tables. Default is 1. - -n num_of_records_per_table, The number of records per table. Default is 1. - -c config_directory, Configuration directory. Default is '/etc/taos/'. - -x flag, Insert only flag. - -O order, Insert mode--0: In order, 1: Out of order. Default is in order. - -R rate, Out of order data's rate--if order=1 Default 10, min: 0, max: 50. - -D Delete data methods 0: don't delete, 1: delete by table, 2: delete by stable, 3: delete by database. - -v Print verbose output - -y Skip read key for continous test, default is not skip + -h host, The host to connect to TDengine. Default is localhost. + -p port, The TCP/IP port number to use for the connection. Default is 0. + -u user, The user name to use when connecting to the server. Default is 'root'. + -P password, The password to use when connecting to the server. Default is 'taosdata'. + -d database, Destination database. Default is 'test'. + -a replica, Set the replica parameters of the database, Default 1, min: 1, max: 5. + -m table_prefix, Table prefix name. Default is 't'. + -M stable, Use super table. + -s stable_prefix, STable prefix name. Default is 'st' + -Q query, Execute query command. set 'DEFAULT' means select * from each table + -T num_of_threads, The number of threads. Default is 10. + -r num_of_records_per_req, The number of records per request. Default is 1000. + -t num_of_tables, The number of tables. Default is 1. + -n num_of_records_per_table, The number of records per table. Default is 1. + -c config_directory, Configuration directory. Default is '/etc/taos/'. + -x flag, Insert only flag. + -O order, Insert mode--0: In order, 1: Out of order. Default is in order. + -R rate, Out of order data's rate--if order=1 Default 10, min: 0, max: 50. + -D Delete data methods 0: don't delete, 1: delete by table, 2: delete by stable, 3: delete by database. + -v Print verbose output + -g Print debug output + -y Skip read key for continous test, default is not skip diff --git a/tests/examples/C#/taosdemo/taosdemo.cs b/tests/examples/C#/taosdemo/taosdemo.cs index 7e7c18db26c49c6c7a349fe497d6c9c792756a0c..df52acc99dcfeffacbc896d27b81efa66b45fa5f 100644 --- a/tests/examples/C#/taosdemo/taosdemo.cs +++ b/tests/examples/C#/taosdemo/taosdemo.cs @@ -34,11 +34,12 @@ namespace TDengineDriver //sql parameters private string dbName = "db"; - private string stableName = "st"; + private string stablePrefix = "st"; private string tablePrefix = "t"; private bool isInsertOnly = false; - private int queryMode = 1; + private string query = "NONE"; + private short queryMode = 1; private long recordsPerTable = 1; private int recordsPerRequest = 1; @@ -52,12 +53,19 @@ namespace TDengineDriver private bool useStable = false; private short methodOfDelete = 0; private long numOfThreads = 1; - private long rateOfOutorder = 0; + private short rateOfOutorder = 10; private bool order = true; private bool skipReadKey = false; private bool verbose = false; + private bool debug = false; + static void HelpPrint(string arg, string desc) + { + string indent = " "; + Console.WriteLine("{0}{1}", indent, arg.PadRight(25)+desc); + } + static void PrintHelp(String[] argv) { for (int i = 0; i < argv.Length; ++i) @@ -66,59 +74,38 @@ namespace TDengineDriver { Console.WriteLine("Usage: mono taosdemo.exe [OPTION...]"); Console.WriteLine(""); - string indent = " "; - Console.WriteLine("{0}{1}", indent, "--help Show usage."); + HelpPrint("--help", "Show usage."); Console.WriteLine(""); - Console.Write("{0}{1}", indent, "-h"); - Console.Write("{0}{1}{2}\n", indent, indent, "host, The host to connect to TDengine. Default is localhost."); - Console.Write("{0}{1}", indent, "-p"); - Console.Write("{0}{1}{2}\n", indent, indent, "port, The TCP/IP port number to use for the connection. Default is 0."); - Console.Write("{0}{1}", indent, "-u"); - Console.Write("{0}{1}{2}\n", indent, indent, "user, The user name to use when connecting to the server. Default is 'root'."); - Console.Write("{0}{1}", indent, "-P"); - Console.Write("{0}{1}{2}\n", indent, indent, "password, The password to use when connecting to the server. Default is 'taosdata'."); - Console.Write("{0}{1}", indent, "-d"); - Console.Write("{0}{1}{2}\n", indent, indent, "database, Destination database. Default is 'test'."); - Console.Write("{0}{1}", indent, "-a"); - Console.Write("{0}{1}{2}\n", indent, indent, "replica, Set the replica parameters of the database, Default 1, min: 1, max: 5."); - Console.Write("{0}{1}", indent, "-m"); - Console.Write("{0}{1}{2}\n", indent, indent, "table_prefix, Table prefix name. Default is 't'."); - Console.Write("{0}{1}", indent, "-s"); - Console.Write("{0}{1}{2}\n", indent, indent, "sql file, The select sql file."); - Console.Write("{0}{1}", indent, "-M"); - Console.Write("{0}{1}{2}\n", indent, indent, "stable, Use super table."); - Console.Write("{0}{1}", indent, "-o"); - Console.Write("{0}{1}{2}\n", indent, indent, "outputfile, Direct output to the named file. Default is './output.txt'."); - Console.Write("{0}{1}", indent, "-q"); - Console.Write("{0}{1}{2}\n", indent, indent, "query_mode, Query mode--0: SYNC, 1: ASYNC. Default is SYNC."); - Console.Write("{0}{1}", indent, "-b"); - Console.Write("{0}{1}{2}\n", indent, indent, "type_of_cols, data_type of columns: 'INT', 'TINYINT', 'SMALLINT', 'BIGINT', 'FLOAT', 'DOUBLE', 'BINARY'. Default is 'INT'."); - Console.Write("{0}{1}", indent, "-w"); - Console.Write("{0}{1}{2}\n", indent, indent, "length_of_binary, The length of data_type 'BINARY'. Only applicable when type of cols is 'BINARY'. Default is 8"); - Console.Write("{0}{1}", indent, "-l"); - Console.Write("{0}{1}{2}\n", indent, indent, "num_of_cols_per_record, The number of columns per record. Default is 3."); - Console.Write("{0}{1}", indent, "-T"); - Console.Write("{0}{1}{2}\n", indent, indent, "num_of_threads, The number of threads. Default is 10."); - Console.Write("{0}{1}", indent, "-r"); - Console.Write("{0}{1}{2}\n", indent, indent, "num_of_records_per_req, The number of records per request. Default is 1000."); - Console.Write("{0}{1}", indent, "-t"); - Console.Write("{0}{1}{2}\n", indent, indent, "num_of_tables, The number of tables. Default is 1."); - Console.Write("{0}{1}", indent, "-n"); - Console.Write("{0}{1}{2}\n", indent, indent, "num_of_records_per_table, The number of records per table. Default is 1."); - Console.Write("{0}{1}", indent, "-c"); - Console.Write("{0}{1}{2}\n", indent, indent, "config_directory, Configuration directory. Default is '/etc/taos/'."); - Console.Write("{0}{1}", indent, "-x"); - Console.Write("{0}{1}{2}\n", indent, indent, "flag, Insert only flag."); - Console.Write("{0}{1}", indent, "-O"); - Console.Write("{0}{1}{2}\n", indent, indent, "order, Insert mode--0: In order, 1: Out of order. Default is in order."); - Console.Write("{0}{1}", indent, "-R"); - Console.Write("{0}{1}{2}\n", indent, indent, "rate, Out of order data's rate--if order=1 Default 10, min: 0, max: 50."); - Console.Write("{0}{1}", indent, "-D"); - Console.Write("{0}{1}{2}\n", indent, indent, "Delete data methods 0: don't delete, 1: delete by table, 2: delete by stable, 3: delete by database."); - Console.Write("{0}{1}", indent, "-v"); - Console.Write("{0}{1}{2}\n", indent, indent, "Print verbose output"); - Console.Write("{0}{1}", indent, "-y"); - Console.Write("{0}{1}{2}\n", indent, indent, "Skip read key for continous test, default is not skip"); + + HelpPrint("-h ", "host, The host to connect to TDengine. Default is localhost."); + HelpPrint("-p ", "port, The TCP/IP port number to use for the connection. Default is 0."); + HelpPrint("-u ", "user, The user name to use when connecting to the server. Default is 'root'."); + HelpPrint("-P ", "password, The password to use when connecting to the server. Default is 'taosdata'."); + HelpPrint("-d ", "database, Destination database. Default is 'test'."); + HelpPrint("-a ", "replica, Set the replica parameters of the database, Default 1, min: 1, max: 5."); + HelpPrint("-m
", "table_prefix, Table prefix name. Default is 't'."); + HelpPrint("-M", "stable, Use super table."); + HelpPrint("-s ", "stable_prefix, STable prefix name. Default is 'st'"); + HelpPrint("-Q ", "query, Execute query command. set 'DEFAULT' means select * from each table"); + /* NOT SUPPORT SO FAR + HelpPrint("-o", "outputfile, Direct output to the named file. Default is './output.txt'."); + HelpPrint("-q", "query_mode, Query mode--0: SYNC, 1: ASYNC. Default is SYNC."); + HelpPrint("-b", "type_of_cols, data_type of columns: 'INT', 'TINYINT', 'SMALLINT', 'BIGINT', 'FLOAT', 'DOUBLE', 'BINARY'. Default is 'INT'."); + HelpPrint("-w", "length_of_binary, The length of data_type 'BINARY'. Only applicable when type of cols is 'BINARY'. Default is 8"); + HelpPrint("-l", "num_of_cols_per_record, The number of columns per record. Default is 3."); + */ + HelpPrint("-T ", "num_of_threads, The number of threads. Default is 10."); + HelpPrint("-r ", "num_of_records_per_req, The number of records per request. Default is 1000."); + HelpPrint("-t ", "num_of_tables, The number of tables. Default is 1."); + HelpPrint("-n ", "num_of_records_per_table, The number of records per table. Default is 1."); + HelpPrint("-c ", "config_directory, Configuration directory. Default is '/etc/taos/'."); + HelpPrint("-x", "flag, Insert only flag."); + HelpPrint("-O", "order, Insert mode--0: In order, 1: Out of order. Default is in order."); + HelpPrint("-R ", "rate, Out of order data's rate--if order=1 Default 10, min: 0, max: 50."); + HelpPrint("-D ", "Delete data methods 0: don't delete, 1: delete by table, 2: delete by stable, 3: delete by database."); + HelpPrint("-v", "Print verbose output"); + HelpPrint("-g", "Print debug output"); + HelpPrint("-y", "Skip read key for continous test, default is not skip"); System.Environment.Exit(0); } @@ -132,49 +119,56 @@ namespace TDengineDriver user = this.GetArgumentAsString(argv, "-u", "root"); password = this.GetArgumentAsString(argv, "-P", "taosdata"); dbName = this.GetArgumentAsString(argv, "-d", "db"); - stableName = this.GetArgumentAsString(argv, "-s", "st"); + stablePrefix = this.GetArgumentAsString(argv, "-s", "st"); tablePrefix = this.GetArgumentAsString(argv, "-m", "t"); - isInsertOnly = this.GetArgumentAsFlag(argv, "-x"); - queryMode = (int)this.GetArgumentAsLong(argv, "-q", 0, 1, 0); + isInsertOnly = this.GetArgumentAsFlag(argv, "-x", true); + query = this.GetArgumentAsString(argv, "-Q", "NONE"); + queryMode = (short)this.GetArgumentAsLong(argv, "-q", 0, 1, 0); numOfTables = this.GetArgumentAsLong(argv, "-t", 1, 1000000000, 1); batchRows = this.GetArgumentAsLong(argv, "-r", 1, 10000, 1000); recordsPerTable = this.GetArgumentAsLong(argv, "-n", 1, 100000000000, 1); recordsPerRequest = (int)this.GetArgumentAsLong(argv, "-r", 1, 10000, 1); colsPerRecord = (int)this.GetArgumentAsLong(argv, "-l", 1, 1024, 3); configDir = this.GetArgumentAsString(argv, "-c", "C:/TDengine/cfg"); - useStable = this.GetArgumentAsFlag(argv, "-M"); + useStable = this.GetArgumentAsFlag(argv, "-M", true); replica = (short)this.GetArgumentAsLong(argv, "-a", 1, 5, 1); methodOfDelete = (short)this.GetArgumentAsLong(argv, "-D", 0, 3, 0); numOfThreads = (short)this.GetArgumentAsLong(argv, "-T", 1, 10000, 1); - order = this.GetArgumentAsFlag(argv, "-O"); - rateOfOutorder = this.GetArgumentAsLong(argv, "-R", 0, 100, 0); - - skipReadKey = this.GetArgumentAsFlag(argv, "-y"); - verbose = this.GetArgumentAsFlag(argv, "-v"); - - Console.Write("###################################################################\n"); - Console.Write("# Server IP: {0}\n", host); - Console.Write("# User: {0}\n", user); - Console.Write("# Password: {0}\n", password); - Console.Write("# Number of Columns per record: {0}\n", colsPerRecord); - Console.Write("# Number of Threads: {0}\n", numOfThreads); - Console.Write("# Number of Tables: {0}\n", numOfTables); - Console.Write("# Number of Data per Table: {0}\n", recordsPerTable); - Console.Write("# Records/Request: {0}\n", recordsPerRequest); - Console.Write("# Database name: {0}\n", dbName); - Console.Write("# Replica: {0}\n", replica); - Console.Write("# Use STable: {0}\n", useStable); - Console.Write("# Table prefix: {0}\n", tablePrefix); - Console.Write("# Data order: {0}\n", order); - Console.Write("# Data out of order rate: {0}\n", rateOfOutorder); - Console.Write("# Delete method: {0}\n", methodOfDelete); - Console.Write("# Query Mode: {0}\n", queryMode); - Console.Write("# Insert Only: {0}\n", isInsertOnly); - Console.Write("# Verbose output {0}\n", verbose); - Console.Write("# Test time: {0}\n", DateTime.Now.ToString("h:mm:ss tt")); - - Console.Write("###################################################################\n"); + order = this.GetArgumentAsFlag(argv, "-O", false); + rateOfOutorder = (short)this.GetArgumentAsLong(argv, "-R", 0, 50, 10); + + skipReadKey = this.GetArgumentAsFlag(argv, "-y", true); + verbose = this.GetArgumentAsFlag(argv, "-v", true); + debug = this.GetArgumentAsFlag(argv, "-g", true); + + VerbosePrint ("###################################################################\n"); + VerbosePrintFormat ("# Server IP: {0}\n", host); + VerbosePrintFormat ("# User: {0}\n", user); + VerbosePrintFormat ("# Password: {0}\n", password); + VerbosePrintFormat ("# Number of Columns per record: {0}\n", colsPerRecord); + VerbosePrintFormat ("# Number of Threads: {0}\n", numOfThreads); + VerbosePrintFormat ("# Number of Tables: {0}\n", numOfTables); + VerbosePrintFormat ("# Number of records per Table: {0}\n", recordsPerTable); + VerbosePrintFormat ("# Records/Request: {0}\n", recordsPerRequest); + VerbosePrintFormat ("# Database name: {0}\n", dbName); + VerbosePrintFormat ("# Replica: {0}\n", replica); + VerbosePrintFormat ("# Use STable: {0}\n", useStable); + VerbosePrintFormat ("# Table prefix: {0}\n", tablePrefix); + if (useStable == true) + { + VerbosePrintFormat("# STable prefix: {0}\n", stablePrefix); + } + VerbosePrintFormat ("# Data order: {0}\n", order); + VerbosePrintFormat ("# Data out of order rate: {0}\n", rateOfOutorder); + VerbosePrintFormat ("# Delete method: {0}\n", methodOfDelete); + VerbosePrintFormat ("# Query command: {0}\n", query); + VerbosePrintFormat ("# Query Mode: {0}\n", queryMode); + VerbosePrintFormat ("# Insert Only: {0}\n", isInsertOnly); + VerbosePrintFormat ("# Verbose output {0}\n", verbose); + VerbosePrintFormat ("# Test time: {0}\n", DateTime.Now.ToString("h:mm:ss tt")); + + VerbosePrint ("###################################################################\n"); if (skipReadKey == false) { @@ -183,17 +177,17 @@ namespace TDengineDriver } } - public bool GetArgumentAsFlag(String[] argv, String argName) + public bool GetArgumentAsFlag(String[] argv, String argName, bool defaultValue) { int argc = argv.Length; for (int i = 0; i < argc; ++i) { if (argName == argv[i]) { - return true; + return defaultValue; } } - return false; + return !defaultValue; } public long GetArgumentAsLong(String[] argv, String argName, int minVal, long maxVal, int defaultValue) @@ -210,15 +204,15 @@ namespace TDengineDriver String tmp = argv[i + 1]; if (tmp[0] == '-') { - Console.WriteLine("option {0:G} requires an argument", tmp); - ExitProgram(); + Console.WriteLine("option {0:G} requires an argument", argName); + ExitProgram(1); } long tmpVal = Convert.ToInt64(tmp); if (tmpVal < minVal || tmpVal > maxVal) { - Console.WriteLine("option {0:G} should in range [{1:G}, {2:G}]", argName, minVal, maxVal); - ExitProgram(); + Console.WriteLine("option {0:G} value should in range [{1:G}, {2:G}]", argName, minVal, maxVal); + ExitProgram(1); } return tmpVal; @@ -242,8 +236,8 @@ namespace TDengineDriver String tmp = argv[i + 1]; if (tmp[0] == '-') { - Console.WriteLine("option {0:G} requires an argument", tmp); - ExitProgram(); + Console.WriteLine("option {0:G} requires an argument", argName); + ExitProgram(1); } return tmp; } @@ -252,13 +246,18 @@ namespace TDengineDriver return defaultValue; } - static void ExitProgram() + static void CleanAndExitProgram(int ret) { TDengine.Cleanup(); - System.Environment.Exit(0); + System.Environment.Exit(ret); } - private void DebugPrintFormat(string format, params object[] parameters) + static void ExitProgram(int ret) + { + System.Environment.Exit(ret); + } + + private void VerbosePrintFormat(string format, params object[] parameters) { if (verbose == true) { @@ -266,7 +265,7 @@ namespace TDengineDriver } } - private void DebugPrint(string str) + private void VerbosePrint(string str) { if (verbose == true) { @@ -274,28 +273,44 @@ namespace TDengineDriver } } + private void DebugPrintFormat(string format, params object[] parameters) + { + if (debug == true) + { + Console.Write(format, parameters); + } + } + + private void DebugPrint(string str) + { + if (debug == true) + { + Console.Write(str); + } + } + public void InitTDengine() { TDengine.Options((int)TDengineInitOption.TDDB_OPTION_CONFIGDIR, this.configDir); TDengine.Options((int)TDengineInitOption.TDDB_OPTION_SHELL_ACTIVITY_TIMER, "60"); TDengine.Init(); - DebugPrint("TDengine Initialization finished\n"); + VerbosePrint("TDengine Initialization finished\n"); } public void ConnectTDengine() { string db = ""; - DebugPrintFormat("host:{0} user:{1}, pass:{2}; db:{3}, port:{4}\n", + VerbosePrintFormat("host:{0} user:{1}, pass:{2}; db:{3}, port:{4}\n", this.host, this.user, this.password, db, this.port); this.conn = TDengine.Connect(this.host, this.user, this.password, db, this.port); if (this.conn == IntPtr.Zero) { Console.WriteLine("Connect to TDengine failed"); - ExitProgram(); + CleanAndExitProgram(1); } else { - DebugPrint("Connect to TDengine success\n"); + VerbosePrint("Connect to TDengine success\n"); } } @@ -323,12 +338,13 @@ namespace TDengineDriver CreateTableThread createTableThread = new CreateTableThread(); createTableThread.id = i; createTableThread.verbose = verbose; + createTableThread.debug = debug; createTableThread.dbName = this.dbName; createTableThread.tablePrefix = this.tablePrefix; createTableThread.useStable = useStable; if (useStable) { - createTableThread.stableName = stableName; + createTableThread.stablePrefix = stablePrefix; } createTableThread.conn = conn; @@ -356,12 +372,12 @@ namespace TDengineDriver IntPtr res = TDengine.Query(this.conn, sql.ToString()); if (res != IntPtr.Zero) { - DebugPrint(sql.ToString() + " success\n"); + VerbosePrint(sql.ToString() + " success\n"); } else { Console.WriteLine(sql.ToString() + " failure, reason: " + TDengine.Error(res)); - ExitProgram(); + CleanAndExitProgram(1); } } @@ -373,12 +389,12 @@ namespace TDengineDriver IntPtr res = TDengine.Query(this.conn, sql.ToString()); if (res != IntPtr.Zero) { - DebugPrint(sql.ToString() + " success\n"); + VerbosePrint(sql.ToString() + " success\n"); } else { Console.WriteLine(sql.ToString() + " failure, reason: " + TDengine.Error(res)); - ExitProgram(); + CleanAndExitProgram(1); } TDengine.FreeResult(res); } @@ -389,17 +405,17 @@ namespace TDengineDriver sql.Clear(); sql.Append("CREATE TABLE IF NOT EXISTS "). - Append(this.dbName).Append(".").Append(this.stableName). + Append(this.dbName).Append(".").Append(this.stablePrefix). Append("(ts timestamp, v1 bool, v2 tinyint, v3 smallint, v4 int, v5 bigint, v6 float, v7 double, v8 binary(10), v9 nchar(10)) tags(t1 int)"); IntPtr res = TDengine.Query(this.conn, sql.ToString()); if (res != IntPtr.Zero) { - DebugPrint(sql.ToString() + " success\n"); + VerbosePrint(sql.ToString() + " success\n"); } else { Console.WriteLine(sql.ToString() + " failure, reason: " + TDengine.Error(res)); - ExitProgram(); + CleanAndExitProgram(1); } TDengine.FreeResult(res); } @@ -431,11 +447,14 @@ namespace TDengineDriver insertThread.batchRows = batchRows; insertThread.numOfTables = numOfTables; insertThread.verbose = verbose; + insertThread.debug = debug; insertThread.dbName = this.dbName; insertThread.tablePrefix = this.tablePrefix; + insertThread.order = this.order; + insertThread.rateOfOutorder = this.rateOfOutorder; if (useStable) { - // insertThread.stableName = stableName; + insertThread.stablePrefix = stablePrefix; } insertThread.conn = conn; @@ -458,33 +477,43 @@ namespace TDengineDriver public void ExecuteQuery() { - // System.DateTime start = new System.DateTime(); long queryRows = 0; - for (int i = 0; i < 1/*this.numOfTables*/; ++i) + for (int i = 0; i < this.numOfTables; ++i) { - String sql = "select * from " + this.dbName + "." + tablePrefix + i; - // Console.WriteLine(sql); + string sql; + + if (query == "DEFAULT") + { + sql = "select * from " + this.dbName + "." + tablePrefix + i; + } + else + { + sql = query; + } + DebugPrintFormat("query: {0}, sql:{1}\n", query, sql); IntPtr res = TDengine.Query(conn, sql); + DebugPrintFormat("res: {0}\n", res); if (res == IntPtr.Zero) { Console.WriteLine(sql + " failure, reason: " + TDengine.Error(res)); - ExitProgram(); + CleanAndExitProgram(1); } int fieldCount = TDengine.FieldCount(res); - // Console.WriteLine("field count: " + fieldCount); + DebugPrint("field count: " + fieldCount + "\n"); List metas = TDengine.FetchFields(res); for (int j = 0; j < metas.Count; j++) { TDengineMeta meta = (TDengineMeta)metas[j]; - // Console.WriteLine("index:" + j + ", type:" + meta.type + ", typename:" + meta.TypeName() + ", name:" + meta.name + ", size:" + meta.size); + DebugPrint("index:" + j + ", type:" + meta.type + ", typename:" + meta.TypeName() + ", name:" + meta.name + ", size:" + meta.size + "\n"); } IntPtr rowdata; StringBuilder builder = new StringBuilder(); + while ((rowdata = TDengine.FetchRows(res)) != IntPtr.Zero) { queryRows++; @@ -548,10 +577,7 @@ namespace TDengineDriver } builder.Append("---"); - if (queryRows <= 10) - { - Console.WriteLine(builder.ToString()); - } + VerbosePrint(builder.ToString() + "\n"); builder.Clear(); } @@ -563,13 +589,6 @@ namespace TDengineDriver TDengine.FreeResult(res); } - /* - System.DateTime end = new System.DateTime(); - TimeSpan ts = end - start; - - Console.Write("Total {0:G} rows inserted, {1:G} rows query, time spend {2:G} seconds.\n" - , this.rowsInserted, queryRows, ts.TotalSeconds); - */ } public void CloseConnection() @@ -610,13 +629,24 @@ namespace TDengineDriver watch.Stop(); double elapsedMs = watch.Elapsed.TotalMilliseconds; - Console.WriteLine("Spent {0} seconds to insert {1} records with {2} record(s) per request: {3} records/second", + Console.WriteLine("C# taosdemo: Spent {0} seconds to insert {1} records with {2} record(s) per request: {3} records/second", elapsedMs / 1000, tester.recordsPerTable * tester.numOfTables, tester.batchRows, (tester.recordsPerTable * tester.numOfTables * 1000) / elapsedMs); - tester.ExecuteQuery(); + tester.DebugPrintFormat("query command:{0}\n", tester.query); + if (tester.query != "NONE") + { + watch = Stopwatch.StartNew(); + tester.ExecuteQuery(); + watch.Stop(); + elapsedMs = watch.Elapsed.TotalMilliseconds; + Console.WriteLine("C# taosdemo: Spent {0} seconds to query {1} records.\n", + elapsedMs/1000, + tester.recordsPerTable * tester.numOfTables + ); + } tester.CloseConnection(); Console.WriteLine("End."); @@ -630,13 +660,16 @@ namespace TDengineDriver public string dbName { set; get; } public IntPtr conn { set; get; } public string tablePrefix { set; get; } - // public string stableName { set; get; } + public string stablePrefix { set; get; } public long recordsPerTable { set; get; } public long batchRows { set; get; } public long numOfTables { set; get; } public bool verbose { set; get; } + public bool debug { set; get; } + public bool order { set; get; } + public short rateOfOutorder { set; get; } - private void DebugPrintFormat(string format, params object[] parameters) + private void VerbosePrintFormat(string format, params object[] parameters) { if (verbose == true) { @@ -644,7 +677,7 @@ namespace TDengineDriver } } - private void DebugPrint(string str) + private void VerbosePrint(string str) { if (verbose == true) { @@ -652,9 +685,25 @@ namespace TDengineDriver } } + private void DebugPrintFormat(string format, params object[] parameters) + { + if (debug == true) + { + Console.Write(format, parameters); + } + } + + private void DebugPrint(string str) + { + if (debug == true) + { + Console.Write(str); + } + } + public void ThreadMain() { - DebugPrintFormat("InsertDataThread {0} from {1} to {2}\n", id, start, end); + VerbosePrintFormat("InsertDataThread {0} from {1} to {2}\n", id, start, end); StringBuilder sql = new StringBuilder(); DateTime now = DateTime.Now; @@ -663,12 +712,12 @@ namespace TDengineDriver int s = now.Second; long baseTimestamp = 1609430400000; // 2021/01/01 0:0:0 - DebugPrintFormat("beginTime is {0} + {1}h:{2}m:{3}s\n", baseTimestamp, h, m, s); + VerbosePrintFormat("beginTime is {0} + {1}h:{2}m:{3}s\n", baseTimestamp, h, m, s); long beginTimestamp = baseTimestamp + ((h*60 + m) * 60 + s) * 1000; + Random random = new Random(); long rowsInserted = 0; - // System.DateTime startTime = new System.DateTime(); long i = 0; while (i < recordsPerTable) { @@ -686,8 +735,25 @@ namespace TDengineDriver } for (int batch = 0; batch < batchRows; ++batch) { + long writeTimeStamp = beginTimestamp + i + batch; + int rnd = 100; + if (this.order == false) + { + rnd = random.Next(1, 100); + if (rnd <= this.rateOfOutorder) + { + writeTimeStamp = writeTimeStamp + rnd * 10000; + DebugPrint("### "); + } + DebugPrintFormat("order:{0} rnd:{1} timestamp:{2}\n", this.order, rnd, writeTimeStamp); + } + else + { + DebugPrintFormat("order:{0} timestamp:{1}\n", this.order, writeTimeStamp); + } + sql.Append("(") - .Append(beginTimestamp + i + batch) + .Append(writeTimeStamp) .Append(", 1, 2, 3,") .Append(i + batch) .Append(", 5, 6, 7, 'abc', 'def')"); @@ -696,7 +762,7 @@ namespace TDengineDriver IntPtr res = TDengine.Query(this.conn, sql.ToString()); if (res == IntPtr.Zero) { - DebugPrint(sql.ToString() + " failure, reason: " + TDengine.Error(res) + "\n"); + VerbosePrint(sql.ToString() + " failure, reason: " + TDengine.Error(res) + "\n"); } inserted += this.batchRows; @@ -723,11 +789,12 @@ namespace TDengineDriver public string dbName { set; get; } public IntPtr conn { set; get; } public string tablePrefix { set; get; } - public string stableName { set; get; } + public string stablePrefix { set; get; } public bool verbose { set; get; } + public bool debug { set; get; } public bool useStable { set; get; } - private void DebugPrintFormat(string format, params object[] parameters) + private void VerbosePrintFormat(string format, params object[] parameters) { if (verbose == true) { @@ -735,7 +802,7 @@ namespace TDengineDriver } } - private void DebugPrint(string str) + private void VerbosePrint(string str) { if (verbose == true) { @@ -743,9 +810,17 @@ namespace TDengineDriver } } + private void DebugPrintFormat(string format, params object[] parameters) + { + if (debug == true) + { + Console.Write(format, parameters); + } + } + public void ThreadMain() { - DebugPrintFormat("CreateTable {0} from {1} to {2}\n", id, start, end); + VerbosePrintFormat("CreateTable {0} from {1} to {2}\n", id, start, end); StringBuilder sql = new StringBuilder(); @@ -756,7 +831,7 @@ namespace TDengineDriver Append(this.dbName).Append(".").Append(this.tablePrefix).Append(tableId); if (useStable == true) { - sql = sql.Append(" USING ").Append(this.dbName).Append(".").Append(this.stableName). + sql = sql.Append(" USING ").Append(this.dbName).Append(".").Append(this.stablePrefix). Append(" TAGS(").Append(tableId).Append(")"); } else @@ -766,12 +841,12 @@ namespace TDengineDriver IntPtr res = TDengine.Query(this.conn, sql.ToString()); if (res != IntPtr.Zero) { - DebugPrint(sql.ToString() + " success\n"); + VerbosePrint(sql.ToString() + " success\n"); } else { - DebugPrint(sql.ToString() + " failure, reason: " + TDengine.Error(res) + "\n"); - ExitProgram(); + VerbosePrint(sql.ToString() + " failure, reason: " + TDengine.Error(res) + "\n"); + CleanAndExitProgram(1); } TDengine.FreeResult(res); } diff --git a/tests/pytest/alter/alter_table.py b/tests/pytest/alter/alter_table.py index f1d1da29900b4d703ef6a011a46650a2e05c2f9d..2982492f6567ad54a62a3fcca44d4f1ac9560697 100644 --- a/tests/pytest/alter/alter_table.py +++ b/tests/pytest/alter/alter_table.py @@ -131,7 +131,7 @@ class TDTestCase: tdSql.execute("alter table t0 set tag t1=2.1") tdSql.query("show tables") - tdSql.checkRows(1) + tdSql.checkRows(2) def stop(self): tdSql.close() diff --git a/tests/pytest/client/alterDatabase.py b/tests/pytest/client/alterDatabase.py index 8191312cc060f9c20632911c956065f777d47079..bc8c4fc17ee956ad21525adb0587f925bb35d2bf 100644 --- a/tests/pytest/client/alterDatabase.py +++ b/tests/pytest/client/alterDatabase.py @@ -35,10 +35,9 @@ class TDTestCase: tdSql.execute("alter database db keep 365,365,365") tdSql.query("show databases") tdSql.checkData(0, 7, "365,365,365") - - tdSql.execute("alter database db quorum 2") - tdSql.query("show databases") - tdSql.checkData(0, 5, 2) + + tdSql.error("alter database db quorum 2") + tdSql.execute("alter database db blocks 100") tdSql.query("show databases") diff --git a/tests/pytest/fulltest.sh b/tests/pytest/fulltest.sh index cb233f85b8132910b316fd130983769e99452bf9..d9bc185b6c326b79d933dafc50cd7db0e0d396f4 100755 --- a/tests/pytest/fulltest.sh +++ b/tests/pytest/fulltest.sh @@ -190,6 +190,7 @@ python3 ./test.py -f stream/table_n.py #alter table python3 ./test.py -f alter/alter_table_crash.py +python3 ./test.py -f alter/alter_table.py # client python3 ./test.py -f client/client.py diff --git a/tests/pytest/multilevel/basic.py b/tests/pytest/multilevel/basic.py new file mode 100644 index 0000000000000000000000000000000000000000..95549409c9f1a1b287fc872260d33f956ccf3510 --- /dev/null +++ b/tests/pytest/multilevel/basic.py @@ -0,0 +1,51 @@ +################################################################### +# Copyright (c) 2016 by TAOS Technologies, Inc. +# All rights reserved. +# +# This file is proprietary and confidential to TAOS Technologies. +# No part of this file may be reproduced, stored, transmitted, +# disclosed or used in any form or by any means other than as +# expressly provided by the written permission from Jianhui Tao +# +################################################################### + +# -*- coding: utf-8 -*- + +import sys +import taos +from util.log import * +from util.cases import * +from util.sql import * +from util.dnodes import * + + +class TDTestCase: + def init(self, conn, logSql): + tdLog.debug("start to execute %s" % __file__) + tdSql.init(conn.cursor(), logSql) + + def run(self): + cfg={ + '/mnt/data1' : 'dataDir', + '/mnt/data2 0 0' : 'dataDir' + } + tdSql.createDir('/mnt/data1') + tdSql.createDir('/mnt/data2') + + tdLog.info("================= step1") + tdDnodes.stop(1) + tdDnodes.deploy(1,cfg) + tdDnodes.startWithoutSleep(1) + + tdLog.info("================= step2") + tdSql.haveFile('/mnt/data1',1) + tdSql.haveFile('/mnt/data2',1) + + + def stop(self): + tdSql.close() + tdLog.success("%s successfully executed" % __file__) + + +tdCases.addWindows(__file__, TDTestCase()) +tdCases.addLinux(__file__, TDTestCase()) diff --git a/tests/pytest/multilevel/dirNotExist.py b/tests/pytest/multilevel/dirNotExist.py new file mode 100644 index 0000000000000000000000000000000000000000..e895ac31ad1d6361cddfe867e39cea370412cb58 --- /dev/null +++ b/tests/pytest/multilevel/dirNotExist.py @@ -0,0 +1,50 @@ +################################################################### +# Copyright (c) 2016 by TAOS Technologies, Inc. +# All rights reserved. +# +# This file is proprietary and confidential to TAOS Technologies. +# No part of this file may be reproduced, stored, transmitted, +# disclosed or used in any form or by any means other than as +# expressly provided by the written permission from Jianhui Tao +# +################################################################### + +# -*- coding: utf-8 -*- + +import sys +import taos +from util.log import * +from util.cases import * +from util.sql import * +from util.dnodes import * + + +class TDTestCase: + def init(self, conn, logSql): + tdLog.debug("start to execute %s" % __file__) + tdSql.init(conn.cursor(), logSql) + + def run(self): + cfg={ + '/mnt/data1 0 0' : 'dataDir', + '/mnt/data2 0 0' : 'dataDir' + } + tdSql.createDir('/mnt/data1') + os.system('rm -rf /mnt/data2') + + + tdLog.info("================= step1") + tdDnodes.stop(1) + tdDnodes.deploy(1,cfg) + tdDnodes.startWithoutSleep(1) + + tdLog.info("================= step2") + tdSql.taosdStatus(0) + + def stop(self): + tdSql.close() + tdLog.success("%s successfully executed" % __file__) + + +tdCases.addWindows(__file__, TDTestCase()) +tdCases.addLinux(__file__, TDTestCase()) diff --git a/tests/pytest/multilevel/dirPermissionDenied.py b/tests/pytest/multilevel/dirPermissionDenied.py new file mode 100644 index 0000000000000000000000000000000000000000..db2cdcf757121c501e33f605aceebdf875d5f944 --- /dev/null +++ b/tests/pytest/multilevel/dirPermissionDenied.py @@ -0,0 +1,51 @@ +################################################################### +# Copyright (c) 2016 by TAOS Technologies, Inc. +# All rights reserved. +# +# This file is proprietary and confidential to TAOS Technologies. +# No part of this file may be reproduced, stored, transmitted, +# disclosed or used in any form or by any means other than as +# expressly provided by the written permission from Jianhui Tao +# +################################################################### + +# -*- coding: utf-8 -*- + +import sys +import taos +from util.log import * +from util.cases import * +from util.sql import * +from util.dnodes import * + + +class TDTestCase: + def init(self, conn, logSql): + tdLog.debug("start to execute %s" % __file__) + tdSql.init(conn.cursor(), logSql) + + def run(self): + cfg={ + '/mnt/data1 0 0' : 'dataDir', + '/mnt/data2 0 0' : 'dataDir' + } + tdSql.createDir('/mnt/data1') + tdSql.createDir('/mnt/data2') + os.system('chmod 111 /mnt/data2') + + tdLog.info("================= step1") + tdDnodes.stop(1) + tdDnodes.deploy(1,cfg) + tdDnodes.startWithoutSleep(1) + + tdLog.info("================= step2") + tdSql.taosdStatus(0) + + + def stop(self): + tdSql.close() + tdLog.success("%s successfully executed" % __file__) + + +tdCases.addWindows(__file__, TDTestCase()) +tdCases.addLinux(__file__, TDTestCase()) diff --git a/tests/pytest/multilevel/fileDistributionSameLevel.py b/tests/pytest/multilevel/fileDistributionSameLevel.py new file mode 100644 index 0000000000000000000000000000000000000000..e2880283b5b6a76942ac9ac5abba50f8c5bfda1e --- /dev/null +++ b/tests/pytest/multilevel/fileDistributionSameLevel.py @@ -0,0 +1,71 @@ +################################################################### +# Copyright (c) 2016 by TAOS Technologies, Inc. +# All rights reserved. +# +# This file is proprietary and confidential to TAOS Technologies. +# No part of this file may be reproduced, stored, transmitted, +# disclosed or used in any form or by any means other than as +# expressly provided by the written permission from Jianhui Tao +# +################################################################### + +# -*- coding: utf-8 -*- + +import sys +import taos +from util.log import * +from util.cases import * +from util.sql import * +from util.dnodes import * + + +class TDTestCase: + def init(self, conn, logSql): + tdLog.debug("start to execute %s" % __file__) + tdSql.init(conn.cursor(), logSql) + + def run(self): + self.ntables = 10 + self.rowsPerTable = 10 + self.ts = 1520000010000 + + tdDnodes.stop(1) + # Test1 1 dataDir + cfg={ + '10' : 'maxVgroupsPerDb', + '/mnt/data00 0 1' : 'dataDir', + '/mnt/data01 0 0' : 'dataDir', + '/mnt/data02 0 0' : 'dataDir', + '/mnt/data03 1 0' : 'dataDir', + '/mnt/data04 1 0' : 'dataDir' + } + tdSql.createDir('/mnt/data00') + tdSql.createDir('/mnt/data01') + tdSql.createDir('/mnt/data02') + tdSql.createDir('/mnt/data03') + tdSql.createDir('/mnt/data04') + + tdDnodes.deploy(1,cfg) + tdDnodes.startWithoutSleep(1) + + tdSql.execute("create database test days 1") + tdSql.execute("use test") + + tdSql.execute("create table tb(ts timestamp, c int)") + + for i in range(self.rowsPerTable): + tdSql.execute("insert into tb values(%d, 1)" % (self.ts + i * 86400000)) + + tdDnodes.stop(1) + tdDnodes.start(1) + + tdSql.query("select * from test.tb") + tdSql.checkRows(10) + + + def stop(self): + tdSql.close() + tdLog.success("%s successfully executed" % __file__) + +tdCases.addWindows(__file__, TDTestCase()) +tdCases.addLinux(__file__, TDTestCase()) diff --git a/tests/pytest/multilevel/illegelLevelMountPoint.py b/tests/pytest/multilevel/illegelLevelMountPoint.py new file mode 100644 index 0000000000000000000000000000000000000000..cbf7fc1fe908fa528713576921555380d4a68ed8 --- /dev/null +++ b/tests/pytest/multilevel/illegelLevelMountPoint.py @@ -0,0 +1,59 @@ +################################################################### +# Copyright (c) 2016 by TAOS Technologies, Inc. +# All rights reserved. +# +# This file is proprietary and confidential to TAOS Technologies. +# No part of this file may be reproduced, stored, transmitted, +# disclosed or used in any form or by any means other than as +# expressly provided by the written permission from Jianhui Tao +# +################################################################### + +# -*- coding: utf-8 -*- + +import sys +import taos +from util.log import * +from util.cases import * +from util.sql import * +from util.dnodes import * + + +class TDTestCase: + def init(self, conn, logSql): + tdLog.debug("start to execute %s" % __file__) + tdSql.init(conn.cursor(), logSql) + + def run(self): + self.ntables = 10 + self.rowsPerTable = 10 + self.startTime = 1520000010000 + + tdDnodes.stop(1) + # Test1 1 dataDir + cfg={ + '/mnt/data1 3 0' : 'dataDir' + } + tdSql.createDir('/mnt/data1') + + tdDnodes.deploy(1,cfg) + tdDnodes.startWithoutSleep(1) + + tdDnodes.stop(1) + # Test1 1 dataDir + cfg={ + '/mnt/data1 -1 0' : 'dataDir' + } + tdSql.createDir('/mnt/data1') + + tdDnodes.deploy(1,cfg) + tdDnodes.startWithoutSleep(1) + + tdSql.taosdStatus(0) + + def stop(self): + tdSql.close() + tdLog.success("%s successfully executed" % __file__) + +tdCases.addWindows(__file__, TDTestCase()) +tdCases.addLinux(__file__, TDTestCase()) diff --git a/tests/pytest/multilevel/middleLevelMissing.py b/tests/pytest/multilevel/middleLevelMissing.py new file mode 100644 index 0000000000000000000000000000000000000000..727c2380ae0f3a148a475ae8ebdd01e8ff1f543f --- /dev/null +++ b/tests/pytest/multilevel/middleLevelMissing.py @@ -0,0 +1,64 @@ +################################################################### +# Copyright (c) 2016 by TAOS Technologies, Inc. +# All rights reserved. +# +# This file is proprietary and confidential to TAOS Technologies. +# No part of this file may be reproduced, stored, transmitted, +# disclosed or used in any form or by any means other than as +# expressly provided by the written permission from Jianhui Tao +# +################################################################### + +# -*- coding: utf-8 -*- + +import sys +import taos +from util.log import * +from util.cases import * +from util.sql import * +from util.dnodes import * + + +class TDTestCase: + def init(self, conn, logSql): + tdLog.debug("start to execute %s" % __file__) + tdSql.init(conn.cursor(), logSql) + + def run(self): + self.ntables = 10 + self.rowsPerTable = 10 + self.startTime = 1520000010000 + + tdDnodes.stop(1) + # Test1 1 dataDir + cfg={ + '/mnt/data1 1 0' : 'dataDir' + } + tdSql.createDir('/mnt/data1') + + tdDnodes.deploy(1,cfg) + tdDnodes.startWithoutSleep(1) + + tdSql.taosdStatus(0) + + + tdDnodes.stop(1) + # Test2 2 dataDir + cfg={ + '/mnt/data1 0 1' : 'dataDir', + '/mnt/data1 2 0' : 'dataDir' + } + tdSql.createDir('/mnt/data1') + + tdDnodes.deploy(1,cfg) + tdDnodes.startWithoutSleep(1) + + tdSql.taosdStatus(0) + + def stop(self): + tdSql.close() + tdLog.success("%s successfully executed" % __file__) + + +tdCases.addWindows(__file__, TDTestCase()) +tdCases.addLinux(__file__, TDTestCase()) diff --git a/tests/pytest/multilevel/moreThan16disks.py b/tests/pytest/multilevel/moreThan16disks.py new file mode 100644 index 0000000000000000000000000000000000000000..407e5aa6970781ce5b511faa1f4f74e7a18e75a8 --- /dev/null +++ b/tests/pytest/multilevel/moreThan16disks.py @@ -0,0 +1,53 @@ +################################################################### +# Copyright (c) 2016 by TAOS Technologies, Inc. +# All rights reserved. +# +# This file is proprietary and confidential to TAOS Technologies. +# No part of this file may be reproduced, stored, transmitted, +# disclosed or used in any form or by any means other than as +# expressly provided by the written permission from Jianhui Tao +# +################################################################### + +# -*- coding: utf-8 -*- + +import sys +import taos +from util.log import * +from util.cases import * +from util.sql import * +from util.dnodes import * + + +class TDTestCase: + def init(self, conn, logSql): + tdLog.debug("start to execute %s" % __file__) + tdSql.init(conn.cursor(), logSql) + + def run(self): + cfg={} + for i in range(17): + if i == 0 : + datadir = '/mnt/data%d 0 1' % (i+1) + else: + datadir = '/mnt/data%d 0 0' % (i+1) + cfg.update({ datadir : 'dataDir' }) + tdSql.createDir('/mnt/data%d' % (i+1)) + + + tdLog.info("================= step1") + tdDnodes.stop(1) + tdDnodes.deploy(1,cfg) + tdDnodes.startWithoutSleep(1) + + tdLog.info("================= step2") + + tdSql.taosdStatus(0) + + def stop(self): + tdSql.close() + tdLog.success("%s successfully executed" % __file__) + + +tdCases.addWindows(__file__, TDTestCase()) +tdCases.addLinux(__file__, TDTestCase()) diff --git a/tests/pytest/multilevel/multiMainMountPoint.py b/tests/pytest/multilevel/multiMainMountPoint.py new file mode 100644 index 0000000000000000000000000000000000000000..c5af816205cdbd325c11d600c560104ca1801b93 --- /dev/null +++ b/tests/pytest/multilevel/multiMainMountPoint.py @@ -0,0 +1,49 @@ +################################################################### +# Copyright (c) 2016 by TAOS Technologies, Inc. +# All rights reserved. +# +# This file is proprietary and confidential to TAOS Technologies. +# No part of this file may be reproduced, stored, transmitted, +# disclosed or used in any form or by any means other than as +# expressly provided by the written permission from Jianhui Tao +# +################################################################### + +# -*- coding: utf-8 -*- + +import sys +import taos +from util.log import * +from util.cases import * +from util.sql import * +from util.dnodes import * + + +class TDTestCase: + def init(self, conn, logSql): + tdLog.debug("start to execute %s" % __file__) + tdSql.init(conn.cursor(), logSql) + + def run(self): + cfg={ + '/mnt/data1' : 'dataDir', + '/mnt/data2' : 'dataDir' + } + tdSql.createDir('/mnt/data1') + tdSql.createDir('/mnt/data2') + + tdLog.info("================= step1") + tdDnodes.stop(1) + tdDnodes.deploy(1,cfg) + tdDnodes.startWithoutSleep(1) + + tdLog.info("================= step2") + tdSql.taosdStatus(0) + + def stop(self): + tdSql.close() + tdLog.success("%s successfully executed" % __file__) + + +tdCases.addWindows(__file__, TDTestCase()) +tdCases.addLinux(__file__, TDTestCase()) diff --git a/tests/pytest/multilevel/noneMainMountPoint.py b/tests/pytest/multilevel/noneMainMountPoint.py new file mode 100644 index 0000000000000000000000000000000000000000..67fab7c7a24510244a663dbc20f2c212012f712d --- /dev/null +++ b/tests/pytest/multilevel/noneMainMountPoint.py @@ -0,0 +1,49 @@ +################################################################### +# Copyright (c) 2016 by TAOS Technologies, Inc. +# All rights reserved. +# +# This file is proprietary and confidential to TAOS Technologies. +# No part of this file may be reproduced, stored, transmitted, +# disclosed or used in any form or by any means other than as +# expressly provided by the written permission from Jianhui Tao +# +################################################################### + +# -*- coding: utf-8 -*- + +import sys +import taos +from util.log import * +from util.cases import * +from util.sql import * +from util.dnodes import * + + +class TDTestCase: + def init(self, conn, logSql): + tdLog.debug("start to execute %s" % __file__) + tdSql.init(conn.cursor(), logSql) + + def run(self): + cfg={ + '/mnt/data1 0 0' : 'dataDir', + '/mnt/data2 0 0' : 'dataDir' + } + tdSql.createDir('/mnt/data1') + tdSql.createDir('/mnt/data2') + + tdLog.info("================= step1") + tdDnodes.stop(1) + tdDnodes.deploy(1,cfg) + tdDnodes.startWithoutSleep(1) + + tdLog.info("================= step2") + tdSql.taosdStatus(0) + + def stop(self): + tdSql.close() + tdLog.success("%s successfully executed" % __file__) + + +tdCases.addWindows(__file__, TDTestCase()) +tdCases.addLinux(__file__, TDTestCase()) diff --git a/tests/pytest/multilevel/retentionTest.py b/tests/pytest/multilevel/retentionTest.py new file mode 100644 index 0000000000000000000000000000000000000000..9ea59d9d5918d851f69acc69704926d97f3f5375 --- /dev/null +++ b/tests/pytest/multilevel/retentionTest.py @@ -0,0 +1,82 @@ +################################################################### +# Copyright (c) 2016 by TAOS Technologies, Inc. +# All rights reserved. +# +# This file is proprietary and confidential to TAOS Technologies. +# No part of this file may be reproduced, stored, transmitted, +# disclosed or used in any form or by any means other than as +# expressly provided by the written permission from Jianhui Tao +# +################################################################### + +# -*- coding: utf-8 -*- + +import sys +import taos +import os +from util.log import * +from util.cases import * +from util.sql import * +from util.dnodes import * + + +class TDTestCase: + def init(self, conn, logSql): + tdLog.debug("start to execute %s" % __file__) + tdSql.init(conn.cursor(), logSql) + + def run(self): + self.ntables = 10 + self.rowsPerTable = 10 + self.startTime = 1520000010000 + + tdDnodes.stop(1) + # Test1 1 dataDir + cfg={ + '/mnt/data00 0 1' : 'dataDir', + '/mnt/data01 0 0' : 'dataDir', + '/mnt/data02 0 0' : 'dataDir', + '/mnt/data10 1 0' : 'dataDir', + '/mnt/data11 1 0' : 'dataDir', + '/mnt/data12 1 0' : 'dataDir', + '/mnt/data20 2 0' : 'dataDir', + '/mnt/data21 2 0' : 'dataDir', + '/mnt/data22 2 0' : 'dataDir' + } + tdSql.createDir('/mnt/data00') + tdSql.createDir('/mnt/data01') + tdSql.createDir('/mnt/data02') + tdSql.createDir('/mnt/data10') + tdSql.createDir('/mnt/data11') + tdSql.createDir('/mnt/data12') + tdSql.createDir('/mnt/data20') + tdSql.createDir('/mnt/data21') + tdSql.createDir('/mnt/data22') + + tdDnodes.deploy(1,cfg) + tdDnodes.startWithoutSleep(1) + + tdSql.execute("create database test days 1 keep 15,5,10") + tdSql.execute("use test") + + tdSql.execute("create table tb(ts timestamp, c int)") + + count = 0 + os.system("sudo timedatectl set-ntp false") + + for i in range(self.rowsPerTable): + tdSql.execute("insert into tb values(now, 1)") + count += 1 + tdSql.query("select * from tb") + tdSql.checkRows(count) + tdDnodes.stop(1) + os.system("sudo date -s $(date -d \"${DATE} 1 day\" \"+%Y%m%d\")") + tdDnodes.start(1) + + def stop(self): + os.system("sudo timedatectl set-ntp true") + tdSql.close() + tdLog.success("%s successfully executed" % __file__) + +tdCases.addWindows(__file__, TDTestCase()) +tdCases.addLinux(__file__, TDTestCase()) diff --git a/tests/pytest/multilevel/threeLevelMountPoint.py b/tests/pytest/multilevel/threeLevelMountPoint.py new file mode 100644 index 0000000000000000000000000000000000000000..ccaf95f47d389e053c042a4a20cefad2c7d08776 --- /dev/null +++ b/tests/pytest/multilevel/threeLevelMountPoint.py @@ -0,0 +1,65 @@ +################################################################### +# Copyright (c) 2016 by TAOS Technologies, Inc. +# All rights reserved. +# +# This file is proprietary and confidential to TAOS Technologies. +# No part of this file may be reproduced, stored, transmitted, +# disclosed or used in any form or by any means other than as +# expressly provided by the written permission from Jianhui Tao +# +################################################################### + +# -*- coding: utf-8 -*- + +import sys +import taos +from util.log import * +from util.cases import * +from util.sql import * +from util.dnodes import * + + +class TDTestCase: + def init(self, conn, logSql): + tdLog.debug("start to execute %s" % __file__) + tdSql.init(conn.cursor(), logSql) + + def run(self): + self.ntables = 10 + self.rowsPerTable = 10 + self.startTime = 1520000010000 + + tdDnodes.stop(1) + # Test1 1 dataDir + cfg={ + '/mnt/data00 0 1' : 'dataDir', + '/mnt/data01 0 0' : 'dataDir', + '/mnt/data02 0 0' : 'dataDir', + '/mnt/data10 1 0' : 'dataDir', + '/mnt/data11 1 0' : 'dataDir', + '/mnt/data12 1 0' : 'dataDir', + '/mnt/data20 2 0' : 'dataDir', + '/mnt/data21 2 0' : 'dataDir', + '/mnt/data22 2 0' : 'dataDir' + } + tdSql.createDir('/mnt/data00') + tdSql.createDir('/mnt/data01') + tdSql.createDir('/mnt/data02') + tdSql.createDir('/mnt/data10') + tdSql.createDir('/mnt/data11') + tdSql.createDir('/mnt/data12') + tdSql.createDir('/mnt/data20') + tdSql.createDir('/mnt/data21') + tdSql.createDir('/mnt/data22') + + tdDnodes.deploy(1,cfg) + tdDnodes.startWithoutSleep(1) + + tdSql.taosdStatus(1) + + def stop(self): + tdSql.close() + tdLog.success("%s successfully executed" % __file__) + +tdCases.addWindows(__file__, TDTestCase()) +tdCases.addLinux(__file__, TDTestCase()) diff --git a/tests/pytest/multilevel/wrongLevelMountPoint.py b/tests/pytest/multilevel/wrongLevelMountPoint.py new file mode 100644 index 0000000000000000000000000000000000000000..00b9eb89c69a21a9d02f4927d508b8275e07a7f7 --- /dev/null +++ b/tests/pytest/multilevel/wrongLevelMountPoint.py @@ -0,0 +1,49 @@ +################################################################### +# Copyright (c) 2016 by TAOS Technologies, Inc. +# All rights reserved. +# +# This file is proprietary and confidential to TAOS Technologies. +# No part of this file may be reproduced, stored, transmitted, +# disclosed or used in any form or by any means other than as +# expressly provided by the written permission from Jianhui Tao +# +################################################################### + +# -*- coding: utf-8 -*- + +import sys +import taos +from util.log import * +from util.cases import * +from util.sql import * +from util.dnodes import * + + +class TDTestCase: + def init(self, conn, logSql): + tdLog.debug("start to execute %s" % __file__) + tdSql.init(conn.cursor(), logSql) + + def run(self): + self.ntables = 10 + self.rowsPerTable = 10 + self.startTime = 1520000010000 + + tdDnodes.stop(1) + # Test1 1 dataDir + cfg={ + '/mnt/data1 1 1' : 'dataDir' + } + tdSql.createDir('/mnt/data1') + + tdDnodes.deploy(1,cfg) + tdDnodes.startWithoutSleep(1) + + tdSql.taosdStatus(0) + + def stop(self): + tdSql.close() + tdLog.success("%s successfully executed" % __file__) + +tdCases.addWindows(__file__, TDTestCase()) +tdCases.addLinux(__file__, TDTestCase()) diff --git a/tests/pytest/query/query.py b/tests/pytest/query/query.py index d0750ac4a5cbe631e38017e6c81746659ad16e49..756aa0eda998aaa0aad30e94b2a7192d7d53bb65 100644 --- a/tests/pytest/query/query.py +++ b/tests/pytest/query/query.py @@ -23,6 +23,8 @@ class TDTestCase: tdLog.debug("start to execute %s" % __file__) tdSql.init(conn.cursor(), logSql) + self.ts = 1538548685000 + def run(self): tdSql.prepare() @@ -77,7 +79,37 @@ class TDTestCase: tdSql.checkRows(1) tdSql.checkData(0, 0, 1) + ## test case for https://jira.taosdata.com:18080/browse/TD-1930 + tdSql.execute("create table tb(ts timestamp, c1 int, c2 binary(10), c3 nchar(10), c4 float, c5 bool)") + for i in range(10): + tdSql.execute("insert into tb values(%d, %d, 'binary%d', 'nchar%d', %f, %d)" % (self.ts + i, i, i, i, i + 0.1, i % 2)) + + tdSql.error("select * from tb where c2 = binary2") + tdSql.error("select * from tb where c3 = nchar2") + + tdSql.query("select * from tb where c2 = 'binary2' ") + tdSql.checkRows(1) + + tdSql.query("select * from tb where c3 = 'nchar2' ") + tdSql.checkRows(1) + + tdSql.query("select * from tb where c1 = '2' ") + tdSql.checkRows(1) + + tdSql.query("select * from tb where c1 = 2 ") + tdSql.checkRows(1) + + tdSql.query("select * from tb where c4 = '0.1' ") + tdSql.checkRows(1) + + tdSql.query("select * from tb where c4 = 0.1 ") + tdSql.checkRows(1) + + tdSql.query("select * from tb where c5 = true ") + tdSql.checkRows(5) + tdSql.query("select * from tb where c5 = 'true' ") + tdSql.checkRows(5) def stop(self): tdSql.close() diff --git a/tests/pytest/stream/new.py b/tests/pytest/stream/new.py index 12ec6d4507710869632eac77d719217b3b0ed7b3..70f300e937b2ed422231a774d2bca1183ce6fd0a 100644 --- a/tests/pytest/stream/new.py +++ b/tests/pytest/stream/new.py @@ -43,7 +43,7 @@ class TDTestCase: tdLog.info("=============== step3") start = time.time() tdSql.waitedQuery("select * from st", 1, 120) - delay = int(time.time() - start) + 20 + delay = int(time.time() - start) + 80 v = tdSql.getData(0, 3) if v >= 51: tdLog.exit("value is %d, which is larger than 51" % v) diff --git a/tests/pytest/table/create.py b/tests/pytest/table/create.py index a0991d674a23065cbec5ae3b69d6bdf37ee363ac..ecd4d011418ed7eca0d028262159c5614c0f490c 100644 --- a/tests/pytest/table/create.py +++ b/tests/pytest/table/create.py @@ -56,6 +56,12 @@ class TDTestCase: tdSql.query("show stables like 'st%' ") tdSql.checkRows(3) + # case for defect: https://jira.taosdata.com:18080/browse/TD-2693 + tdSql.execute("create database db2") + tdSql.execute("use db2") + tdSql.execute("create table stb(ts timestamp, c int) tags(t int)") + tdSql.error("insert into db2.tb6 using db2.stb tags(1) values(now 1) tb2 using db2. tags( )values(now 2)") + def stop(self): tdSql.close() tdLog.success("%s successfully executed" % __file__) diff --git a/tests/pytest/util/dnodes.py b/tests/pytest/util/dnodes.py index afea23372f5bd13949bb6967392167df59c3d2b2..91c75efe9762a18042660423708e6dd9475166dd 100644 --- a/tests/pytest/util/dnodes.py +++ b/tests/pytest/util/dnodes.py @@ -208,14 +208,24 @@ class TDDnode: self.cfg("publicIp", "192.168.0.%d" % (self.index)) self.cfg("internalIp", "192.168.0.%d" % (self.index)) self.cfg("privateIp", "192.168.0.%d" % (self.index)) - - self.cfg("dataDir",self.dataDir) - self.cfg("logDir",self.logDir) - print(updatecfgDict) + self.cfgDict["dataDir"] = self.dataDir + self.cfgDict["logDir"] = self.logDir + # self.cfg("dataDir",self.dataDir) + # self.cfg("logDir",self.logDir) + # print(updatecfgDict) + isFirstDir = 1 if updatecfgDict[0] and updatecfgDict[0][0]: print(updatecfgDict[0][0]) for key,value in updatecfgDict[0][0].items(): - self.addExtraCfg(key,value) + if value == 'dataDir' : + if isFirstDir: + self.cfgDict.pop('dataDir') + self.cfg(value,key) + isFirstDir = 0 + else: + self.cfg(value,key) + else: + self.addExtraCfg(key,value) for key, value in self.cfgDict.items(): self.cfg(key, value) @@ -282,13 +292,15 @@ class TDDnode: break popen = subprocess.Popen('tail -f ' + logFile, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True) pid = popen.pid - print('Popen.pid:' + str(pid)) + # print('Popen.pid:' + str(pid)) + timeout = time.time() + 60*2 while True: line = popen.stdout.readline().strip() if bkey in line: - print(line) popen.kill() break + if time.time() > timeout: + tdLog.exit('wait too long for taosd start') tdLog.debug("the dnode:%d has been started." % (self.index)) else: tdLog.debug("wait 10 seconds for the dnode:%d to start." % (self.index)) diff --git a/tests/pytest/util/sql.py b/tests/pytest/util/sql.py index b2ed6212fd643c158f7ed6f4cc6cb2449a512a2e..4f7607fc6c000d7ca55035e6973bfb5577a67964 100644 --- a/tests/pytest/util/sql.py +++ b/tests/pytest/util/sql.py @@ -16,9 +16,12 @@ import os import time import datetime import inspect +import psutil +import shutil from util.log import * + class TDSql: def __init__(self): self.queryRows = 0 @@ -183,6 +186,50 @@ class TDSql: tdLog.exit("%s(%d) failed: sql:%s, affectedRows:%d != expect:%d" % args) tdLog.info("sql:%s, affectedRows:%d == expect:%d" % (self.sql, self.affectedRows, expectAffectedRows)) - - + + def taosdStatus(self, state): + tdLog.sleep(5) + pstate = 0 + for i in range(30): + pstate = 0 + pl = psutil.pids() + for pid in pl: + if psutil.Process(pid).name == 'taosd': + pstate = 1 + break + if pstate: + tdLog.sleep(5) + continue + pstate = 0 + break + + args=(pstate,state) + if pstate == state: + tdLog.info("taosd state is %d == expect:%d" %args) + else: + tdLog.exit("taosd state is %d != expect:%d" %args) + pass + + def haveFile(self, dir, state): + if os.path.exists(dir) and os.path.isdir(dir): + if not os.listdir(dir): + if state : + tdLog.exit("dir: %s is empty, expect: not empty" %dir) + else: + tdLog.info("dir: %s is empty, expect: empty" %dir) + else: + if state : + tdLog.info("dir: %s is empty, expect: not empty" %dir) + else: + tdLog.exit("dir: %s is empty, expect: empty" %dir) + else: + tdLog.exit("dir: %s doesn't exist" %dir) + def createDir(self, dir): + if os.path.exists(dir): + shutil.rmtree(dir) + tdLog.info("dir: %s is removed" %dir) + os.makedirs( dir, 755 ) + tdLog.info("dir: %s is created" %dir) + pass + tdSql = TDSql() diff --git a/tests/script/general/cache/new_metrics.sim b/tests/script/general/cache/new_metrics.sim index 0e304d9acb0ec3ceba18993846f9f6d8269ff966..84f9e40de39b6946984204f4e3cb6f7e395af0e2 100644 --- a/tests/script/general/cache/new_metrics.sim +++ b/tests/script/general/cache/new_metrics.sim @@ -3,7 +3,6 @@ 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 tableMetaKeepTimer -v 10 system sh/exec.sh -n dnode1 -s start sleep 3000 diff --git a/tests/script/general/cache/restart_metrics.sim b/tests/script/general/cache/restart_metrics.sim index 18c514acbf5a038f998035302cca8bb0fbd95a0b..f24768859fe8b771b9c03e0ea328d0066174909d 100644 --- a/tests/script/general/cache/restart_metrics.sim +++ b/tests/script/general/cache/restart_metrics.sim @@ -3,7 +3,6 @@ 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 tableMetaKeepTimer -v 10 system sh/exec.sh -n dnode1 -s start sleep 3000 @@ -53,7 +52,6 @@ system sh/exec.sh -n dnode1 -s stop sleep 5000 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 tableMetaKeepTimer -v 10 system sh/exec.sh -n dnode1 -s start print =============== step3 diff --git a/tests/script/general/cache/restart_table.sim b/tests/script/general/cache/restart_table.sim index c4e6c6f2acc8f0fb0902a6a6adf8d9b91984a712..8697c26bc3d7708a4eca1c3480d6cdb248c072dc 100644 --- a/tests/script/general/cache/restart_table.sim +++ b/tests/script/general/cache/restart_table.sim @@ -3,7 +3,6 @@ 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 tableMetaKeepTimer -v 10 system sh/exec.sh -n dnode1 -s start sleep 3000 @@ -37,7 +36,6 @@ system sh/exec.sh -n dnode1 -s stop sleep 5000 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 tableMetaKeepTimer -v 10 system sh/exec.sh -n dnode1 -s start print =============== step3 diff --git a/tests/script/general/parser/alter.sim b/tests/script/general/parser/alter.sim index aec519085c1116a51b810d343d5dd31b57419cce..eae9b88be95ed91b1e0889c8640909a6bc70f592 100644 --- a/tests/script/general/parser/alter.sim +++ b/tests/script/general/parser/alter.sim @@ -2,7 +2,6 @@ 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 tableMetaKeepTimer -v 3 system sh/exec.sh -n dnode1 -s start sleep 100 sql connect diff --git a/tests/script/general/parser/alter_stable.sim b/tests/script/general/parser/alter_stable.sim index 52916ebadada05eda4bf6e8165f374175e01312b..17fc8d984a8899c136cb8451f0fa1e9038bf2cbd 100644 --- a/tests/script/general/parser/alter_stable.sim +++ b/tests/script/general/parser/alter_stable.sim @@ -2,7 +2,6 @@ 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 tableMetaKeepTimer -v 3 system sh/exec.sh -n dnode1 -s start sleep 100 sql connect diff --git a/tests/script/general/parser/binary_escapeCharacter.sim b/tests/script/general/parser/binary_escapeCharacter.sim index 7c5a8f9319bda3f80487425866aa389f6c3c1489..dc54add763e5cf34595c479373020c7c4baae63c 100644 --- a/tests/script/general/parser/binary_escapeCharacter.sim +++ b/tests/script/general/parser/binary_escapeCharacter.sim @@ -2,7 +2,6 @@ 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 tableMetaKeepTimer -v 3 system sh/exec.sh -n dnode1 -s start sleep 100 sql connect diff --git a/tests/script/general/parser/columnValue.sim b/tests/script/general/parser/columnValue.sim index 5f8152b3f0fa0a2171ca97a0e2e7d4f4e6073ccc..4e6c6640042a80ffafd008538f2c46e5f43c0318 100644 --- a/tests/script/general/parser/columnValue.sim +++ b/tests/script/general/parser/columnValue.sim @@ -3,7 +3,6 @@ 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 tableMetaKeepTimer -v 3 system sh/exec.sh -n dnode1 -s start sleep 100 sql connect diff --git a/tests/script/general/parser/columnValue_unsign.sim b/tests/script/general/parser/columnValue_unsign.sim index 22ef5c42a38bc67e3b4cb4a7705bd95344ab09fd..895b13961ef729544a9ac14c85e4e37e6f723423 100644 --- a/tests/script/general/parser/columnValue_unsign.sim +++ b/tests/script/general/parser/columnValue_unsign.sim @@ -106,4 +106,70 @@ if $data01 != 1 then return -1 endi -sql select a+b+c from mt_unsigned_1 where a is null; \ No newline at end of file +sql select a+b+c from mt_unsigned_1 where a is null; +if $rows != 1 then + return -1 +endi + +if $data00 != 6.000000000 then + return -1 +endi + +sql select count(*), a from mt_unsigned_1 group by a; +if $rows != 1 then + return -1 +endi + +if $data00 != 1 then + return -1 +endi + +if $data01 != 1 then + return -1 +endi + +sql select count(*), b from mt_unsigned_1 group by b; +if $rows != 1 then + return -1 +endi + +if $data00 != 1 then + return -1 +endi + +if $data01 != 2 then + return -1 +endi + +sql select count(*), c from mt_unsigned_1 group by c; +if $rows != 1 then + return -1 +endi + +if $data00 != 1 then + return -1 +endi + +if $data01 != 3 then + return -1 +endi + +sql select count(*), d from mt_unsigned_1 group by d; +if $rows != 1 then + return -1 +endi + +if $data00 != 1 then + return -1 +endi + +if $data01 != 4 then + return -1 +endi + +// todo insert more rows and chec it +sql select first(a),count(b),last(c),sum(b),spread(d),avg(c),min(b),max(a),stddev(a) from mt_unsigned_1; +if $rows != 1 then + return -1 +endi + diff --git a/tests/script/general/parser/function.sim b/tests/script/general/parser/function.sim index 1c255b92a2d0665fe05cb818eaf6a9a545e08e70..7d702e989e6f816832adbd92507efbef68fdb088 100644 --- a/tests/script/general/parser/function.sim +++ b/tests/script/general/parser/function.sim @@ -2,7 +2,6 @@ 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 tableMetaKeepTimer -v 3 system sh/exec.sh -n dnode1 -s start sleep 100 sql connect @@ -228,7 +227,7 @@ sql select twa(k),avg(k),count(1) from t1 where ts>='2015-8-18 00:00:00' and ts< sql select twa(k),avg(k),count(1) from t1 where ts>='2015-8-18 00:00:00' and ts<='2015-8-18 00:30:00' interval(10m) order by ts desc -#todo add test case while column filter exists. +#todo add test case while column filter exists for twa query #sql select count(*),TWA(k) from tm0 where ts>='1970-1-1 13:43:00' and ts<='1970-1-1 13:44:10' interval(9s) @@ -373,3 +372,14 @@ sql select twa(k) from tm2 where ts='2020-12-29 18:46:19.109' if $rows != 0 then return -1 endi + +print ========================> TD-1787 +sql create table cars(ts timestamp, c int) tags(id int); +sql create table car1 using cars tags(1); +sql create table car2 using cars tags(2); +sql insert into car1 (ts, c) values (now,1) car2(ts, c) values(now, 2); +sql drop table cars; +sql create table cars(ts timestamp, c int) tags(id int); +sql create table car1 using cars tags(1); +sql create table car2 using cars tags(2); +sql insert into car1 (ts, c) values (now,1) car2(ts, c) values(now, 2); \ No newline at end of file diff --git a/tests/script/general/parser/null_char.sim b/tests/script/general/parser/null_char.sim index b3200da88e0a9d77899031d71271e580cb279c3b..4e7c8ab3548a54a465801c602c0d6572b347b284 100644 --- a/tests/script/general/parser/null_char.sim +++ b/tests/script/general/parser/null_char.sim @@ -3,7 +3,6 @@ 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 tableMetaKeepTimer -v 3 system sh/exec.sh -n dnode1 -s start sleep 100 diff --git a/tests/script/general/stream/restart_stream.sim b/tests/script/general/stream/restart_stream.sim index 138e2a6e2ef6e6aeb46c14b7e8fceb851e36eaa8..b5a2038d9b207217f9a41250939b9853e2e822d1 100644 --- a/tests/script/general/stream/restart_stream.sim +++ b/tests/script/general/stream/restart_stream.sim @@ -3,7 +3,6 @@ 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 tableMetaKeepTimer -v 1 system sh/exec.sh -n dnode1 -s start sleep 3000 @@ -98,7 +97,6 @@ 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 0 -system sh/cfg.sh -n dnode1 -c tableMetaKeepTimer -v 1 system sh/exec.sh -n dnode1 -s start print =============== step5 diff --git a/tests/script/issue/TD-2677.sim b/tests/script/issue/TD-2677.sim new file mode 100644 index 0000000000000000000000000000000000000000..8d2058a3851e456dd85f8d6a295ce45b7a6fd3bd --- /dev/null +++ b/tests/script/issue/TD-2677.sim @@ -0,0 +1,111 @@ +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 + +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 +step1: + $x = $x + 1 + sleep 1000 + if $x == 10 then + return -1 + endi + +sql show dnodes +print dnode1 $data4_1 +print dnode2 $data4_2 +print dnode3 $data4_3 + +if $data4_1 != ready then + goto step1 +endi +if $data4_2 != ready then + goto step1 +endi +if $data4_3 != ready then + goto step1 +endi + +sql show mnodes +$mnode1Role = $data2_1 +print mnode1Role $mnode1Role +$mnode2Role = $data2_2 +print mnode2Role $mnode2Role +$mnode3Role = $data2_3 +print mnode3Role $mnode3Role + +if $mnode1Role != master then + goto step1 +endi +if $mnode2Role != slave then + goto step1 +endi +if $mnode3Role != slave then + goto step1 +endi + +$x = 1 +show2: + +print =============== step1 +sql create database d1 replica 2 quorum 2 +sql create table d1.t1 (ts timestamp, i int) +sql_error create table d1.t1 (ts timestamp, i int) +sql insert into d1.t1 values(now, 1) +sql select * from d1.t1; +if $rows != 1 then + return -1 +endi + +print =============== step2 +sql create database d2 replica 3 quorum 2 +sql create table d2.t1 (ts timestamp, i int) +sql_error create table d2.t1 (ts timestamp, i int) +sql insert into d2.t1 values(now, 1) +sql select * from d2.t1; +if $rows != 1 then + return -1 +endi + +print =============== step3 +sql create database d4 replica 1 quorum 1 +sql_error create database d5 replica 1 quorum 2 +sql_error create database d6 replica 1 quorum 3 +sql_error create database d7 replica 1 quorum 4 +sql_error create database d8 replica 1 quorum 0 +sql create database d9 replica 2 quorum 1 +sql create database d10 replica 2 quorum 2 +sql_error create database d11 replica 2 quorum 3 +sql_error create database d12 replica 2 quorum 4 +sql_error create database d12 replica 2 quorum 0 +sql create database d13 replica 3 quorum 1 +sql create database d14 replica 3 quorum 2 +sql_error create database d15 replica 3 quorum 3 +sql_error create database d16 replica 3 quorum 4 +sql_error create database d17 replica 3 quorum 0 + + +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 +system sh/exec.sh -n dnode4 -s stop -x SIGINT diff --git a/tests/script/jenkins/basic.txt b/tests/script/jenkins/basic.txt index 73996a67e9ef2c5b152b861506cadab189f168c5..90d01b7215cc559a3c543c5b46c80e1518a3acdb 100644 --- a/tests/script/jenkins/basic.txt +++ b/tests/script/jenkins/basic.txt @@ -1,6 +1,7 @@ cd ../../../debug; cmake .. cd ../../../debug; make +./test.sh -f issue/TD-2677.sim ./test.sh -f issue/TD-2680.sim ./test.sh -f issue/TD-2713.sim diff --git a/tests/script/test.sh b/tests/script/test.sh index a68ac4736dc8e7c0fa3b458c722ea58e4c9aec8e..1c7a7527abc90b3acc98fdf481b847258dfda489 100755 --- a/tests/script/test.sh +++ b/tests/script/test.sh @@ -113,7 +113,6 @@ echo "rpcDebugFlag 143" >> $TAOS_CFG echo "tmrDebugFlag 131" >> $TAOS_CFG echo "cDebugFlag 143" >> $TAOS_CFG echo "udebugFlag 143" >> $TAOS_CFG -echo "tablemetakeeptimer 5" >> $TAOS_CFG echo "wal 0" >> $TAOS_CFG echo "asyncLog 0" >> $TAOS_CFG echo "locale en_US.UTF-8" >> $TAOS_CFG diff --git a/tests/script/tmp/mnodes.sim b/tests/script/tmp/mnodes.sim index e11140028d474b131c472d6c0ff0f9a56587e3a9..23f59d1d00c296d5fc9d3724ce428375a419938e 100644 --- a/tests/script/tmp/mnodes.sim +++ b/tests/script/tmp/mnodes.sim @@ -35,7 +35,6 @@ system sh/cfg.sh -n dnode3 -c replica -v 3 print ============== deploy system sh/exec.sh -n dnode1 -s start -sleep 5001 sql connect sql create dnode $hostname2 @@ -45,13 +44,29 @@ system sh/exec.sh -n dnode3 -s start print =============== step1 $x = 0 -show1: +step1: $x = $x + 1 - sleep 2000 - if $x == 5 then - return -1 + sleep 1000 + if $x == 10 then + return -1 endi -sql show mnodes -x show1 + +sql show dnodes +print dnode1 $data4_1 +print dnode2 $data4_2 +print dnode3 $data4_3 + +if $data4_1 != ready then + goto step1 +endi +if $data4_2 != ready then + goto step1 +endi +if $data4_3 != ready then + goto step1 +endi + +sql show mnodes $mnode1Role = $data2_1 print mnode1Role $mnode1Role $mnode2Role = $data2_2 @@ -60,13 +75,13 @@ $mnode3Role = $data2_3 print mnode3Role $mnode3Role if $mnode1Role != master then - goto show1 + goto step1 endi if $mnode2Role != slave then - goto show1 + goto step1 endi if $mnode3Role != slave then - goto show1 + goto step1 endi $x = 1 @@ -75,9 +90,21 @@ show2: print =============== step $x sql show mnodes print $data0_1 $data2_1 -print $data0_2 $data2_2 -print $data0_3 $data2_3 +sql show dnodes +print dnode1 $data4_1 +print dnode2 $data4_2 +print dnode3 $data4_3 + +if $data4_1 != ready then + goto step1 +endi +if $data4_2 != ready then + goto step1 +endi +if $data4_3 != ready then + goto step1 +endi $x = $x + 1 sleep 5000 diff --git a/tests/script/unique/stream/metrics_balance.sim b/tests/script/unique/stream/metrics_balance.sim index 36086fe4b85b0a6cbf9710af6104d697c1bb59dc..3cb0d73ab862178e5d648ddd1342e0b930e1f6a0 100644 --- a/tests/script/unique/stream/metrics_balance.sim +++ b/tests/script/unique/stream/metrics_balance.sim @@ -14,8 +14,6 @@ system sh/cfg.sh -n dnode1 -c mnodeEqualVnodeNum -v 0 system sh/cfg.sh -n dnode2 -c mnodeEqualVnodeNum -v 0 system sh/cfg.sh -n dnode1 -c maxTablesPerVnode -v 4 system sh/cfg.sh -n dnode2 -c maxTablesPerVnode -v 4 -system sh/cfg.sh -n dnode1 -c tableMetaKeepTimer -v 5 -system sh/cfg.sh -n dnode2 -c tableMetaKeepTimer -v 5 system sh/cfg.sh -n dnode1 -c numOfMnodes -v 2 system sh/cfg.sh -n dnode2 -c numOfMnodes -v 2 diff --git a/tests/test/c/CMakeLists.txt b/tests/test/c/CMakeLists.txt index 2eb8ee1614b286f3827705865cf073a7eded0c88..33e1528b70b5525da23723dc9bf6309870d172ee 100644 --- a/tests/test/c/CMakeLists.txt +++ b/tests/test/c/CMakeLists.txt @@ -1,4 +1,4 @@ -CMAKE_MINIMUM_REQUIRED(VERSION 2.8) +CMAKE_MINIMUM_REQUIRED(VERSION 3.5) PROJECT(TDengine) INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/src/inc)