提交 0759bbb2 编写于 作者: F freemine

Merge remote-tracking branch 'upstream/develop' into mac

......@@ -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'
......
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}")
......
......@@ -32,7 +32,7 @@ ELSEIF (TD_WINDOWS)
#INSTALL(TARGETS taos RUNTIME DESTINATION driver)
#INSTALL(TARGETS shell RUNTIME DESTINATION .)
IF (TD_MVN_INSTALLED)
INSTALL(FILES ${LIBRARY_OUTPUT_PATH}/taos-jdbcdriver-2.0.15-dist.jar DESTINATION connector/jdbc)
INSTALL(FILES ${LIBRARY_OUTPUT_PATH}/taos-jdbcdriver-2.0.16-dist.jar DESTINATION connector/jdbc)
ENDIF ()
ELSEIF (TD_DARWIN)
SET(TD_MAKE_INSTALL_SH "${TD_COMMUNITY_DIR}/packaging/tools/make_install.sh")
......
......@@ -4,7 +4,7 @@ PROJECT(TDengine)
IF (DEFINED VERNUMBER)
SET(TD_VER_NUMBER ${VERNUMBER})
ELSE ()
SET(TD_VER_NUMBER "2.0.13.0")
SET(TD_VER_NUMBER "2.0.14.0")
ENDIF ()
IF (DEFINED VERCOMPATIBLE)
......
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
CMAKE_MINIMUM_REQUIRED(VERSION 3.5)
PROJECT(TDengine)
ADD_SUBDIRECTORY(zlib-1.2.11)
......
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)
......
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
CMAKE_MINIMUM_REQUIRED(VERSION 3.5)
PROJECT(TDengine)
IF (TD_WINDOWS)
......
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
CMAKE_MINIMUM_REQUIRED(VERSION 3.5)
PROJECT(TDengine)
IF (TD_WINDOWS)
......
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
CMAKE_MINIMUM_REQUIRED(VERSION 3.5)
PROJECT(TDengine)
IF (TD_WINDOWS)
......
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
CMAKE_MINIMUM_REQUIRED(VERSION 3.5)
PROJECT(TDengine)
IF (TD_WINDOWS)
......
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
CMAKE_MINIMUM_REQUIRED(VERSION 3.5)
PROJECT(TDengine)
IF (TD_WINDOWS)
......
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
CMAKE_MINIMUM_REQUIRED(VERSION 3.5)
PROJECT(TDengine)
IF (TD_WINDOWS)
......
......@@ -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;
......
......@@ -255,7 +255,7 @@ taos -C 或 taos --dump-config
CREATE USER <user_name> PASS <'password'>;
```
创建用户,并指定用户名和密码,密码需要用单引号引起来,单引号为英文半角
创建用户,并指定用户名和密码,密码需要用单引号引起来单引号为英文半角
```sql
DROP USER <user_name>;
......@@ -267,13 +267,15 @@ DROP USER <user_name>;
ALTER USER <user_name> PASS <'password'>;
```
修改用户密码, 为避免被转换为小写,密码需要用单引号引用,单引号为英文半角
修改用户密码,为避免被转换为小写,密码需要用单引号引用,单引号为英文半角
```sql
ALTER USER <user_name> PRIVILEGE <super|write|read>;
ALTER USER <user_name> PRIVILEGE <write|read>;
```
修改用户权限为: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
......
......@@ -218,7 +218,7 @@ SHOW MNODES;
如果一个数据节点离线,TDengine集群将自动检测到。有如下两种情况:
- 该数据节点离线超过一定时间(taos.cfg里配置参数offlineThreshold控制时长),系统将自动把该数据节点删除,产生系统报警信息,触发负载均衡流程。如果该被删除的数据节点重上线时,它将无法加入集群,需要系统管理员重新将其添加进集群才会开始工作。
- 该数据节点离线超过一定时间(taos.cfg里配置参数offlineThreshold控制时长),系统将自动把该数据节点删除,产生系统报警信息,触发负载均衡流程。如果该被删除的数据节点重上线时,它将无法加入集群,需要系统管理员重新将其添加进集群才会开始工作。
- 离线后,在offlineThreshold的时长内重新上线,系统将自动启动数据恢复流程,等数据完全恢复后,该节点将开始正常工作。
**注意:**如果一个虚拟节点组(包括mnode组)里所归属的每个数据节点都处于离线或unsynced状态,必须等该虚拟节点组里的所有数据节点都上线、都能交换状态信息后,才能选出Master,该虚拟节点组才能对外提供服务。比如整个集群有3个数据节点,副本数为3,如果3个数据节点都宕机,然后2个数据节点重启,是无法工作的,只有等3个数据节点都重启成功,才能对外服务。
......
......@@ -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;”指令给出的节点列表中。
......@@ -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()
```
*<em>host</em> 是TDengine 服务端所有IP, <em>config</em> 为客户端配置文件所在目录
* <em>host</em> 是TDengine 服务端所有IP, <em>config</em> 为客户端配置文件所在目录
* 写入数据
```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. 在命令中执行以下命令:
......
# 常见问题
## 0. 怎么报告问题?
如果 FAQ 中的信息不能够帮到您,需要 TDengine 技术团队的技术支持与协助,请将以下两个目录中内容打包:
1. /var/log/taos (如果没有修改过默认路径)
2. /etc/taos
附上必要的问题描述,包括使用的 TDengine 版本信息、平台环境信息、发生该问题的执行操作、出现问题的表征及大概的时间,在<a href='https://github.com/taosdata/TDengine'> GitHub</a>提交Issue。
为了保证有足够的debug信息,如果问题能够重复,请修改/etc/taos/taos.cfg文件,最后面添加一行“debugFlag 135"(不带引号本身),然后重启taosd, 重复问题,然后再递交。也可以通过如下SQL语句,临时设置taosd的日志级别。
```
alter dnode <dnode_id> debugFlag 135;
```
但系统正常运行时,请一定将debugFlag设置为131,否则会产生大量的日志信息,降低系统效率。
## 1. TDengine2.0之前的版本升级到2.0及以上的版本应该注意什么?☆☆☆
2.0版本在之前版本的基础上,进行了完全的重构,配置文件和数据文件是不兼容的。在升级之前务必进行如下操作:
......@@ -118,16 +132,8 @@ TDengine是根据hostname唯一标志一台机器的,在数据文件从机器A
- 2.0.7.0 及以后的版本,到/var/lib/taos/dnode下,修复dnodeEps.json的dnodeId对应的FQDN,重启。确保机器内所有机器的此文件是完全相同的。
- 1.x 和 2.x 版本的存储结构不兼容,需要使用迁移工具或者自己开发应用导出导入数据。
## 17. 怎么报告问题
## 17. TDengine 是否支持删除或更新已经写入的数据
如果 FAQ 中的信息不能够帮到您,需要 TDengine 技术团队的技术支持与协助,请将以下两个目录中内容打包:
1. /var/log/taos
2. /etc/taos
TDengine 目前尚不支持删除功能,未来根据用户需求可能会支持。
附上必要的问题描述,以及发生该问题的执行操作,出现问题的表征及大概的时间,在<a href='https://github.com/taosdata/TDengine'> GitHub</a>提交Issue。
为了保证有足够的debug信息,如果问题能够重复,请修改/etc/taos/taos.cfg文件,最后面添加一行“debugFlag 135"(不带引号本身),然后重启taosd, 重复问题,然后再递交。也可以通过如下SQL语句,临时设置taosd的日志级别。
```
alter dnode <dnode_id> debugFlag 135;
```
但系统正常运行时,请一定将debugFlag设置为131,否则会产生大量的日志信息,降低系统效率。
从 2.0.8.0 开始,TDengine 支持更新已经写入数据的功能。使用更新功能需要在创建数据库时使用 UPDATE 1 参数,之后可以使用 INSERT INTO 命令更新已经写入的相同时间戳数据。UPDATE 参数不支持 ALTER DATABASE 命令修改。没有使用 UPDATE 1 参数创建的数据库,写入相同时间戳的数据不会修改之前的数据,也不会报错。
\ No newline at end of file
......@@ -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
......@@ -162,10 +159,10 @@
# stop writing logs when the disk size of the log folder is less than this value
# minimalLogDirGB 0.1
# stop writing temporary files when the disk size of the log folder is less than this value
# stop writing temporary files when the disk size of the tmp folder is less than this value
# minimalTmpDirGB 0.1
# stop writing data when the disk size of the log folder is less than this value
# if disk free space is less than this value, taosd service exit directly within startup process
# minimalDataDirGB 0.1
# One mnode is equal to the number of vnode consumed
......
name: tdengine
base: core18
version: '2.0.13.0'
version: '2.0.14.0'
icon: snap/gui/t-dengine.svg
summary: an open-source big data platform designed and optimized for IoT.
description: |
......@@ -72,7 +72,7 @@ parts:
- usr/bin/taosd
- usr/bin/taos
- usr/bin/taosdemo
- usr/lib/libtaos.so.2.0.13.0
- usr/lib/libtaos.so.2.0.14.0
- usr/lib/libtaos.so.1
- usr/lib/libtaos.so
......
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
CMAKE_MINIMUM_REQUIRED(VERSION 3.5)
PROJECT(TDengine)
# Base compile
......
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
CMAKE_MINIMUM_REQUIRED(VERSION 3.5)
PROJECT(TDengine)
INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/src/mnode/inc)
......
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
CMAKE_MINIMUM_REQUIRED(VERSION 3.5)
PROJECT(TDengine)
INCLUDE_DIRECTORIES(inc)
......
......@@ -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
......
......@@ -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;
......
......@@ -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;
......@@ -429,6 +431,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;
}
......@@ -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);
}
......@@ -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;
......
......@@ -223,7 +223,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);
}
......@@ -1244,7 +1244,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;
}
......@@ -6024,9 +6024,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);
}
......@@ -6103,7 +6103,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);
......@@ -6112,7 +6114,9 @@ void tscPrintSelectClause(SSqlObj* pSql, int32_t subClauseIndex) {
}
}
assert(offset < totalBufSize);
str[offset] = ']';
assert(offset < totalBufSize);
tscDebug("%p select clause:%s", pSql, str);
}
......
......@@ -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,6 +1987,14 @@ 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.
......@@ -1997,10 +2002,6 @@ int tscProcessSTableVgroupRsp(SSqlObj *pSql) {
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) {
STableMetaInfo *pInfo = tscGetTableMetaInfoFromCmd(pCmd, pCmd->clauseIndex, i);
......@@ -2034,6 +2035,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;
......
......@@ -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;
......
......@@ -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;
}
......
......@@ -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
......@@ -1365,6 +1365,8 @@ void tscJoinQueryCallback(void* param, TAOS_RES* tres, int code) {
// 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
......@@ -1382,7 +1384,6 @@ 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;
quitAllSubquery(pParentSql, pSupporter);
tscAsyncResultOnError(pParentSql);
......@@ -1405,9 +1406,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 +1656,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;
......
......@@ -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;
}
......
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)
......
......@@ -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);
}
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
CMAKE_MINIMUM_REQUIRED(VERSION 3.5)
PROJECT(TDengine)
INCLUDE_DIRECTORIES(inc)
......
......@@ -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;
......
......@@ -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;
......@@ -596,16 +595,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;
......@@ -811,8 +800,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);
......
......@@ -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;
......
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" output="target/classes" path="src/main/java">
<attributes>
<attribute name="optional" value="true"/>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry excluding="**" kind="src" output="target/classes" path="src/main/resources">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="src" output="target/test-classes" path="src/test/java">
<attributes>
<attribute name="optional" value="true"/>
<attribute name="maven.pomderived" value="true"/>
<attribute name="test" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="output" path="target/classes"/>
</classpath>
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>taos-jdbcdriver</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.m2e.core.maven2Builder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
<nature>org.eclipse.m2e.core.maven2Nature</nature>
</natures>
</projectDescription>
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
CMAKE_MINIMUM_REQUIRED(VERSION 3.5)
PROJECT(TDengine)
......@@ -8,7 +8,7 @@ IF (TD_MVN_INSTALLED)
ADD_CUSTOM_COMMAND(OUTPUT ${JDBC_CMD_NAME}
POST_BUILD
COMMAND mvn -Dmaven.test.skip=true install -f ${CMAKE_CURRENT_SOURCE_DIR}/pom.xml
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/target/taos-jdbcdriver-2.0.15-dist.jar ${LIBRARY_OUTPUT_PATH}
COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/target/taos-jdbcdriver-2.0.16-dist.jar ${LIBRARY_OUTPUT_PATH}
COMMAND mvn -Dmaven.test.skip=true clean -f ${CMAKE_CURRENT_SOURCE_DIR}/pom.xml
COMMENT "build jdbc driver")
ADD_CUSTOM_TARGET(${JDBC_TARGET_NAME} ALL WORKING_DIRECTORY ${EXECUTABLE_OUTPUT_PATH} DEPENDS ${JDBC_CMD_NAME})
......
......@@ -5,7 +5,7 @@
<groupId>com.taosdata.jdbc</groupId>
<artifactId>taos-jdbcdriver</artifactId>
<version>2.0.15</version>
<version>2.0.16</version>
<packaging>jar</packaging>
<name>JDBCDriver</name>
......
......@@ -3,7 +3,7 @@
<modelVersion>4.0.0</modelVersion>
<groupId>com.taosdata.jdbc</groupId>
<artifactId>taos-jdbcdriver</artifactId>
<version>2.0.15</version>
<version>2.0.16</version>
<packaging>jar</packaging>
<name>JDBCDriver</name>
<url>https://github.com/taosdata/TDengine/tree/master/src/connector/jdbc</url>
......@@ -49,6 +49,7 @@
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
......@@ -56,12 +57,6 @@
<scope>test</scope>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
<!-- for restful -->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
......@@ -79,12 +74,6 @@
<version>1.2.58</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.49</version>
</dependency>
</dependencies>
<build>
......
......@@ -497,12 +497,12 @@ public abstract class AbstractDatabaseMetaData implements DatabaseMetaData {
public ResultSet getProcedures(String catalog, String schemaPattern, String procedureNamePattern)
throws SQLException {
throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
return null;
}
public ResultSet getProcedureColumns(String catalog, String schemaPattern, String procedureNamePattern,
String columnNamePattern) throws SQLException {
throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
return null;
}
public abstract ResultSet getTables(String catalog, String schemaPattern, String tableNamePattern, String[] types)
......
......@@ -20,13 +20,11 @@ import java.util.List;
public class TSDBDatabaseMetaData implements java.sql.DatabaseMetaData {
private String dbProductName = null;
private String url = null;
private String userName = null;
private Connection conn = null;
private String url;
private String userName;
private Connection conn;
public TSDBDatabaseMetaData(String dbProductName, String url, String userName) {
this.dbProductName = dbProductName;
public TSDBDatabaseMetaData(String url, String userName) {
this.url = url;
this.userName = userName;
}
......@@ -35,12 +33,17 @@ public class TSDBDatabaseMetaData implements java.sql.DatabaseMetaData {
this.conn = conn;
}
@Override
public <T> T unwrap(Class<T> iface) throws SQLException {
return null;
try {
return iface.cast(this);
} catch (ClassCastException cce) {
throw new SQLException("Unable to unwrap to " + iface.toString());
}
}
public boolean isWrapperFor(Class<?> iface) throws SQLException {
return false;
return iface.isInstance(this);
}
public boolean allProceduresAreCallable() throws SQLException {
......@@ -80,11 +83,11 @@ public class TSDBDatabaseMetaData implements java.sql.DatabaseMetaData {
}
public String getDatabaseProductName() throws SQLException {
return this.dbProductName;
return "TDengine";
}
public String getDatabaseProductVersion() throws SQLException {
return "1.5.1";
return "2.0.x.x";
}
public String getDriverName() throws SQLException {
......@@ -92,7 +95,7 @@ public class TSDBDatabaseMetaData implements java.sql.DatabaseMetaData {
}
public String getDriverVersion() throws SQLException {
return "1.0.0";
return "2.0.x";
}
public int getDriverMajorVersion() {
......@@ -111,7 +114,9 @@ public class TSDBDatabaseMetaData implements java.sql.DatabaseMetaData {
return false;
}
public boolean supportsMixedCaseIdentifiers() throws SQLException {
//像database、table这些对象的标识符,在存储时是否采用大小写混合的模式
return false;
}
......@@ -120,7 +125,7 @@ public class TSDBDatabaseMetaData implements java.sql.DatabaseMetaData {
}
public boolean storesLowerCaseIdentifiers() throws SQLException {
return false;
return true;
}
public boolean storesMixedCaseIdentifiers() throws SQLException {
......@@ -128,6 +133,7 @@ public class TSDBDatabaseMetaData implements java.sql.DatabaseMetaData {
}
public boolean supportsMixedCaseQuotedIdentifiers() throws SQLException {
//像database、table这些对象的标识符,在存储时是否采用大小写混合、并带引号的模式
return false;
}
......@@ -188,10 +194,12 @@ public class TSDBDatabaseMetaData implements java.sql.DatabaseMetaData {
}
public boolean nullPlusNonNullIsNull() throws SQLException {
// null + non-null != null
return false;
}
public boolean supportsConvert() throws SQLException {
// 是否支持转换函数convert
return false;
}
......@@ -216,7 +224,7 @@ public class TSDBDatabaseMetaData implements java.sql.DatabaseMetaData {
}
public boolean supportsGroupBy() throws SQLException {
return false;
return true;
}
public boolean supportsGroupByUnrelated() throws SQLException {
......@@ -488,7 +496,7 @@ public class TSDBDatabaseMetaData implements java.sql.DatabaseMetaData {
}
public int getDefaultTransactionIsolation() throws SQLException {
return 0;
return Connection.TRANSACTION_NONE;
}
public boolean supportsTransactions() throws SQLException {
......@@ -496,6 +504,8 @@ public class TSDBDatabaseMetaData implements java.sql.DatabaseMetaData {
}
public boolean supportsTransactionIsolationLevel(int level) throws SQLException {
if (level == Connection.TRANSACTION_NONE)
return true;
return false;
}
......@@ -517,28 +527,27 @@ public class TSDBDatabaseMetaData implements java.sql.DatabaseMetaData {
public ResultSet getProcedures(String catalog, String schemaPattern, String procedureNamePattern)
throws SQLException {
throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
return null;
}
public ResultSet getProcedureColumns(String catalog, String schemaPattern, String procedureNamePattern,
String columnNamePattern) throws SQLException {
throw new SQLException(TSDBConstants.UNSUPPORT_METHOD_EXCEPTIONZ_MSG);
return null;
}
public ResultSet getTables(String catalog, String schemaPattern, String tableNamePattern, String[] types)
throws SQLException {
Statement stmt = null;
if (null != conn && !conn.isClosed()) {
stmt = conn.createStatement();
if (catalog == null || catalog.length() < 1) {
catalog = conn.getCatalog();
public ResultSet getTables(String catalog, String schemaPattern, String tableNamePattern, String[] types) throws SQLException {
if (conn == null || conn.isClosed()) {
throw new SQLException(TSDBConstants.FixErrMsg(TSDBConstants.JNI_CONNECTION_NULL));
}
try (Statement stmt = conn.createStatement()) {
if (catalog == null || catalog.isEmpty())
return null;
stmt.executeUpdate("use " + catalog);
ResultSet resultSet0 = stmt.executeQuery("show tables");
GetTablesResultSet getTablesResultSet = new GetTablesResultSet(resultSet0, catalog, schemaPattern, tableNamePattern, types);
return getTablesResultSet;
} else {
throw new SQLException(TSDBConstants.FixErrMsg(TSDBConstants.JNI_CONNECTION_NULL));
}
}
......@@ -547,14 +556,12 @@ public class TSDBDatabaseMetaData implements java.sql.DatabaseMetaData {
}
public ResultSet getCatalogs() throws SQLException {
if (conn == null || conn.isClosed())
throw new SQLException(TSDBConstants.FixErrMsg(TSDBConstants.JNI_CONNECTION_NULL));
if (conn != null && !conn.isClosed()) {
Statement stmt = conn.createStatement();
ResultSet resultSet0 = stmt.executeQuery("show databases");
CatalogResultSet resultSet = new CatalogResultSet(resultSet0);
return resultSet;
} else {
return getEmptyResultSet();
try (Statement stmt = conn.createStatement()) {
ResultSet rs = stmt.executeQuery("show databases");
return new CatalogResultSet(rs);
}
}
......@@ -562,7 +569,7 @@ public class TSDBDatabaseMetaData implements java.sql.DatabaseMetaData {
DatabaseMetaDataResultSet resultSet = new DatabaseMetaDataResultSet();
// set up ColumnMetaDataList
List<ColumnMetaData> columnMetaDataList = new ArrayList<ColumnMetaData>(1);
List<ColumnMetaData> columnMetaDataList = new ArrayList<>(1);
ColumnMetaData colMetaData = new ColumnMetaData();
colMetaData.setColIndex(0);
colMetaData.setColName("TABLE_TYPE");
......@@ -571,7 +578,7 @@ public class TSDBDatabaseMetaData implements java.sql.DatabaseMetaData {
columnMetaDataList.add(colMetaData);
// set up rowDataList
List<TSDBResultSetRowData> rowDataList = new ArrayList<TSDBResultSetRowData>(2);
List<TSDBResultSetRowData> rowDataList = new ArrayList<>(2);
TSDBResultSetRowData rowData = new TSDBResultSetRowData();
rowData.setString(0, "TABLE");
rowDataList.add(rowData);
......@@ -591,11 +598,10 @@ public class TSDBDatabaseMetaData implements java.sql.DatabaseMetaData {
Statement stmt = null;
if (null != conn && !conn.isClosed()) {
stmt = conn.createStatement();
if (catalog == null || catalog.length() < 1) {
catalog = conn.getCatalog();
}
stmt.executeUpdate("use " + catalog);
if (catalog == null || catalog.isEmpty())
return null;
stmt.executeUpdate("use " + catalog);
DatabaseMetaDataResultSet resultSet = new DatabaseMetaDataResultSet();
// set up ColumnMetaDataList
List<ColumnMetaData> columnMetaDataList = new ArrayList<>(24);
......@@ -851,7 +857,7 @@ public class TSDBDatabaseMetaData implements java.sql.DatabaseMetaData {
}
public Connection getConnection() throws SQLException {
return null;
return this.conn;
}
public boolean supportsSavepoints() throws SQLException {
......@@ -884,15 +890,17 @@ public class TSDBDatabaseMetaData implements java.sql.DatabaseMetaData {
}
public boolean supportsResultSetHoldability(int holdability) throws SQLException {
if (holdability == ResultSet.HOLD_CURSORS_OVER_COMMIT)
return true;
return false;
}
public int getResultSetHoldability() throws SQLException {
return 0;
return ResultSet.HOLD_CURSORS_OVER_COMMIT;
}
public int getDatabaseMajorVersion() throws SQLException {
return 0;
return 2;
}
public int getDatabaseMinorVersion() throws SQLException {
......@@ -900,7 +908,7 @@ public class TSDBDatabaseMetaData implements java.sql.DatabaseMetaData {
}
public int getJDBCMajorVersion() throws SQLException {
return 0;
return 2;
}
public int getJDBCMinorVersion() throws SQLException {
......
......@@ -214,7 +214,7 @@ public class TSDBDriver extends AbstractTaosDriver {
urlProps.setProperty(TSDBDriver.PROPERTY_KEY_HOST, url);
}
this.dbMetaData = new TSDBDatabaseMetaData(dbProductName, urlForMeta, urlProps.getProperty(TSDBDriver.PROPERTY_KEY_USER));
this.dbMetaData = new TSDBDatabaseMetaData(urlForMeta, urlProps.getProperty(TSDBDriver.PROPERTY_KEY_USER));
return urlProps;
}
......
......@@ -39,7 +39,6 @@ import java.util.Iterator;
import java.util.List;
import java.util.Map;
@SuppressWarnings("unused")
public class TSDBResultSet implements ResultSet {
private TSDBJNIConnector jniConnector = null;
......@@ -104,6 +103,7 @@ public class TSDBResultSet implements ResultSet {
}
public TSDBResultSet() {
}
public TSDBResultSet(TSDBJNIConnector connector, long resultSetPointer) throws SQLException {
......
......@@ -17,6 +17,7 @@ package com.taosdata.jdbc;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
public class TSDBStatement implements Statement {
private TSDBJNIConnector connector = null;
......@@ -68,7 +69,6 @@ public class TSDBStatement implements Statement {
pSql = this.connector.executeQuery(sql);
long resultSetPointer = this.connector.getResultSet();
if (resultSetPointer == TSDBConstants.JNI_CONNECTION_NULL) {
this.connector.freeResultSet(pSql);
throw new SQLException(TSDBConstants.FixErrMsg(TSDBConstants.JNI_CONNECTION_NULL));
......
......@@ -8,7 +8,6 @@ import java.util.List;
public class RestfulDatabaseMetaData extends AbstractDatabaseMetaData {
private final String url;
private final String userName;
private final Connection connection;
......
package com.taosdata.jdbc;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import java.sql.*;
import java.util.Properties;
public class DatabaseMetaDataTest {
static Connection connection = null;
static PreparedStatement statement = null;
static String dbName = "test";
static String tName = "t0";
static String host = "localhost";
@BeforeClass
public static void createConnection() throws SQLException {
try {
Class.forName("com.taosdata.jdbc.TSDBDriver");
} catch (ClassNotFoundException e) {
return;
}
Properties properties = new Properties();
properties.setProperty(TSDBDriver.PROPERTY_KEY_HOST, host);
properties.setProperty(TSDBDriver.PROPERTY_KEY_USER, "root");
properties.setProperty(TSDBDriver.PROPERTY_KEY_PASSWORD, "taosdata");
properties.setProperty(TSDBDriver.PROPERTY_KEY_CHARSET, "UTF-8");
properties.setProperty(TSDBDriver.PROPERTY_KEY_LOCALE, "en_US.UTF-8");
properties.setProperty(TSDBDriver.PROPERTY_KEY_TIME_ZONE, "UTC-8");
connection = DriverManager.getConnection("jdbc:TAOS://" + host + ":0/", properties);
String sql = "drop database if exists " + dbName;
statement = connection.prepareStatement(sql);
statement.executeUpdate("create database if not exists " + dbName);
statement.executeUpdate("create table if not exists " + dbName + "." + tName + " (ts timestamp, k int, v int)");
}
@Test
public void testMetaDataTest() throws SQLException {
DatabaseMetaData databaseMetaData = connection.getMetaData();
ResultSet resultSet = databaseMetaData.getTables(dbName, "t*", "t*", new String[]{"t"});
while (resultSet.next()) {
for (int i = 1; i <= resultSet.getMetaData().getColumnCount(); i++) {
System.out.printf("%d: %s\n", i, resultSet.getString(i));
}
}
resultSet.close();
databaseMetaData.isWrapperFor(null);
databaseMetaData.allProceduresAreCallable();
databaseMetaData.allTablesAreSelectable();
databaseMetaData.getURL();
databaseMetaData.getUserName();
databaseMetaData.isReadOnly();
databaseMetaData.nullsAreSortedHigh();
databaseMetaData.nullsAreSortedLow();
databaseMetaData.nullsAreSortedAtStart();
databaseMetaData.nullsAreSortedAtEnd();
databaseMetaData.getDatabaseProductName();
databaseMetaData.getDatabaseProductVersion();
databaseMetaData.getDriverName();
databaseMetaData.getDriverVersion();
databaseMetaData.getDriverMajorVersion();
databaseMetaData.getDriverMinorVersion();
databaseMetaData.usesLocalFiles();
databaseMetaData.usesLocalFilePerTable();
databaseMetaData.supportsMixedCaseIdentifiers();
databaseMetaData.storesUpperCaseIdentifiers();
databaseMetaData.storesLowerCaseIdentifiers();
databaseMetaData.storesMixedCaseIdentifiers();
databaseMetaData.supportsMixedCaseQuotedIdentifiers();
databaseMetaData.storesUpperCaseQuotedIdentifiers();
databaseMetaData.storesLowerCaseQuotedIdentifiers();
databaseMetaData.storesMixedCaseQuotedIdentifiers();
databaseMetaData.getIdentifierQuoteString();
databaseMetaData.getSQLKeywords();
databaseMetaData.getNumericFunctions();
databaseMetaData.getStringFunctions();
databaseMetaData.getSystemFunctions();
databaseMetaData.getTimeDateFunctions();
databaseMetaData.getSearchStringEscape();
databaseMetaData.getExtraNameCharacters();
databaseMetaData.supportsAlterTableWithAddColumn();
databaseMetaData.supportsAlterTableWithDropColumn();
databaseMetaData.supportsColumnAliasing();
databaseMetaData.nullPlusNonNullIsNull();
databaseMetaData.supportsConvert();
databaseMetaData.supportsConvert(0, 0);
databaseMetaData.supportsTableCorrelationNames();
databaseMetaData.supportsDifferentTableCorrelationNames();
databaseMetaData.supportsExpressionsInOrderBy();
databaseMetaData.supportsOrderByUnrelated();
databaseMetaData.supportsGroupBy();
databaseMetaData.supportsGroupByUnrelated();
databaseMetaData.supportsGroupByBeyondSelect();
databaseMetaData.supportsLikeEscapeClause();
databaseMetaData.supportsMultipleResultSets();
databaseMetaData.supportsMultipleTransactions();
databaseMetaData.supportsNonNullableColumns();
databaseMetaData.supportsMinimumSQLGrammar();
databaseMetaData.supportsCoreSQLGrammar();
databaseMetaData.supportsExtendedSQLGrammar();
databaseMetaData.supportsANSI92EntryLevelSQL();
databaseMetaData.supportsANSI92IntermediateSQL();
databaseMetaData.supportsANSI92FullSQL();
databaseMetaData.supportsIntegrityEnhancementFacility();
databaseMetaData.supportsOuterJoins();
databaseMetaData.supportsFullOuterJoins();
databaseMetaData.supportsLimitedOuterJoins();
databaseMetaData.getSchemaTerm();
databaseMetaData.getProcedureTerm();
databaseMetaData.getCatalogTerm();
databaseMetaData.isCatalogAtStart();
databaseMetaData.getCatalogSeparator();
databaseMetaData.supportsSchemasInDataManipulation();
databaseMetaData.supportsSchemasInProcedureCalls();
databaseMetaData.supportsSchemasInTableDefinitions();
databaseMetaData.supportsSchemasInIndexDefinitions();
databaseMetaData.supportsSchemasInPrivilegeDefinitions();
databaseMetaData.supportsCatalogsInDataManipulation();
databaseMetaData.supportsCatalogsInProcedureCalls();
databaseMetaData.supportsCatalogsInTableDefinitions();
databaseMetaData.supportsCatalogsInIndexDefinitions();
databaseMetaData.supportsCatalogsInPrivilegeDefinitions();
databaseMetaData.supportsPositionedDelete();
databaseMetaData.supportsPositionedUpdate();
databaseMetaData.supportsSelectForUpdate();
databaseMetaData.supportsStoredProcedures();
databaseMetaData.supportsSubqueriesInComparisons();
databaseMetaData.supportsSubqueriesInExists();
databaseMetaData.supportsSubqueriesInIns();
databaseMetaData.supportsSubqueriesInQuantifieds();
databaseMetaData.supportsCorrelatedSubqueries();
databaseMetaData.supportsUnion();
databaseMetaData.supportsUnionAll();
databaseMetaData.supportsOpenCursorsAcrossCommit();
databaseMetaData.supportsOpenCursorsAcrossRollback();
databaseMetaData.supportsOpenStatementsAcrossCommit();
databaseMetaData.supportsOpenStatementsAcrossRollback();
databaseMetaData.getMaxBinaryLiteralLength();
databaseMetaData.getMaxCharLiteralLength();
databaseMetaData.getMaxColumnNameLength();
databaseMetaData.getMaxColumnsInGroupBy();
databaseMetaData.getMaxColumnsInIndex();
databaseMetaData.getMaxColumnsInOrderBy();
databaseMetaData.getMaxColumnsInSelect();
databaseMetaData.getMaxColumnsInTable();
databaseMetaData.getMaxConnections();
databaseMetaData.getMaxCursorNameLength();
databaseMetaData.getMaxIndexLength();
databaseMetaData.getMaxSchemaNameLength();
databaseMetaData.getMaxProcedureNameLength();
databaseMetaData.getMaxCatalogNameLength();
databaseMetaData.getMaxRowSize();
databaseMetaData.doesMaxRowSizeIncludeBlobs();
databaseMetaData.getMaxStatementLength();
databaseMetaData.getMaxStatements();
databaseMetaData.getMaxTableNameLength();
databaseMetaData.getMaxTablesInSelect();
databaseMetaData.getMaxUserNameLength();
databaseMetaData.getDefaultTransactionIsolation();
databaseMetaData.supportsTransactions();
databaseMetaData.supportsTransactionIsolationLevel(0);
databaseMetaData.supportsDataDefinitionAndDataManipulationTransactions();
databaseMetaData.supportsDataManipulationTransactionsOnly();
databaseMetaData.dataDefinitionCausesTransactionCommit();
databaseMetaData.dataDefinitionIgnoredInTransactions();
try {
databaseMetaData.getProcedures("", "", "");
} catch (Exception e) {
}
try {
databaseMetaData.getProcedureColumns("", "", "", "");
} catch (Exception e) {
}
try {
databaseMetaData.getTables("", "", "", new String[]{""});
} catch (Exception e) {
}
databaseMetaData.getSchemas();
databaseMetaData.getCatalogs();
// databaseMetaData.getTableTypes();
databaseMetaData.getColumns(dbName, "", tName, "");
databaseMetaData.getColumnPrivileges("", "", "", "");
databaseMetaData.getTablePrivileges("", "", "");
databaseMetaData.getBestRowIdentifier("", "", "", 0, false);
databaseMetaData.getVersionColumns("", "", "");
databaseMetaData.getPrimaryKeys("", "", "");
databaseMetaData.getImportedKeys("", "", "");
databaseMetaData.getExportedKeys("", "", "");
databaseMetaData.getCrossReference("", "", "", "", "", "");
databaseMetaData.getTypeInfo();
databaseMetaData.getIndexInfo("", "", "", false, false);
databaseMetaData.supportsResultSetType(0);
databaseMetaData.supportsResultSetConcurrency(0, 0);
databaseMetaData.ownUpdatesAreVisible(0);
databaseMetaData.ownDeletesAreVisible(0);
databaseMetaData.ownInsertsAreVisible(0);
databaseMetaData.othersUpdatesAreVisible(0);
databaseMetaData.othersDeletesAreVisible(0);
databaseMetaData.othersInsertsAreVisible(0);
databaseMetaData.updatesAreDetected(0);
databaseMetaData.deletesAreDetected(0);
databaseMetaData.insertsAreDetected(0);
databaseMetaData.supportsBatchUpdates();
databaseMetaData.getUDTs("", "", "", new int[]{0});
databaseMetaData.getConnection();
databaseMetaData.supportsSavepoints();
databaseMetaData.supportsNamedParameters();
databaseMetaData.supportsMultipleOpenResults();
databaseMetaData.supportsGetGeneratedKeys();
databaseMetaData.getSuperTypes("", "", "");
databaseMetaData.getSuperTables("", "", "");
databaseMetaData.getAttributes("", "", "", "");
databaseMetaData.supportsResultSetHoldability(0);
databaseMetaData.getResultSetHoldability();
databaseMetaData.getDatabaseMajorVersion();
databaseMetaData.getDatabaseMinorVersion();
databaseMetaData.getJDBCMajorVersion();
databaseMetaData.getJDBCMinorVersion();
databaseMetaData.getSQLStateType();
databaseMetaData.locatorsUpdateCopy();
databaseMetaData.supportsStatementPooling();
databaseMetaData.getRowIdLifetime();
databaseMetaData.getSchemas("", "");
databaseMetaData.supportsStoredFunctionsUsingCallSyntax();
databaseMetaData.autoCommitFailureClosesAllResultSets();
databaseMetaData.getClientInfoProperties();
databaseMetaData.getFunctions("", "", "");
databaseMetaData.getFunctionColumns("", "", "", "");
databaseMetaData.getPseudoColumns("", "", "", "");
databaseMetaData.generatedKeyAlwaysReturned();
}
@AfterClass
public static void close() throws Exception {
statement.executeUpdate("drop database " + dbName);
statement.close();
connection.close();
Thread.sleep(10);
}
}
package com.taosdata.jdbc;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Properties;
public class TSDBDatabaseMetaDataTest {
private TSDBDatabaseMetaData metaData;
private static final String host = "localhost";
@Before
public void before() throws ClassNotFoundException, SQLException {
Class.forName("com.taosdata.jdbc.TSDBDriver");
Properties properties = new Properties();
properties.setProperty(TSDBDriver.PROPERTY_KEY_HOST, host);
properties.setProperty(TSDBDriver.PROPERTY_KEY_CHARSET, "UTF-8");
properties.setProperty(TSDBDriver.PROPERTY_KEY_LOCALE, "en_US.UTF-8");
properties.setProperty(TSDBDriver.PROPERTY_KEY_TIME_ZONE, "UTC-8");
metaData = (TSDBDatabaseMetaData) DriverManager.getConnection("jdbc:TAOS://" + host + ":6030/?user=root&password=taosdata", properties).getMetaData();
}
@Test
public void unwrap() throws SQLException {
TSDBDatabaseMetaData unwrap = metaData.unwrap(TSDBDatabaseMetaData.class);
Assert.assertNotNull(unwrap);
}
@Test
public void isWrapperFor() throws SQLException {
Assert.assertTrue(metaData.isWrapperFor(TSDBDatabaseMetaData.class));
}
@Test
public void allProceduresAreCallable() throws SQLException {
Assert.assertFalse(metaData.allProceduresAreCallable());
}
@Test
public void allTablesAreSelectable() throws SQLException {
Assert.assertFalse(metaData.allTablesAreSelectable());
}
@Test
public void getURL() throws SQLException {
Assert.assertEquals("jdbc:TAOS://localhost:6030/?user=root&password=taosdata", metaData.getURL());
}
@Test
public void getUserName() throws SQLException {
Assert.assertEquals("root", metaData.getUserName());
}
@Test
public void isReadOnly() throws SQLException {
Assert.assertFalse(metaData.isReadOnly());
}
@Test
public void nullsAreSortedHigh() throws SQLException {
Assert.assertFalse(metaData.nullsAreSortedHigh());
}
@Test
public void nullsAreSortedLow() throws SQLException {
Assert.assertTrue(metaData.nullsAreSortedLow());
}
@Test
public void nullsAreSortedAtStart() throws SQLException {
Assert.assertTrue(metaData.nullsAreSortedAtStart());
}
@Test
public void nullsAreSortedAtEnd() throws SQLException {
Assert.assertFalse(metaData.nullsAreSortedAtEnd());
}
@Test
public void getDatabaseProductName() throws SQLException {
Assert.assertEquals("TDengine", metaData.getDatabaseProductName());
}
@Test
public void getDatabaseProductVersion() throws SQLException {
Assert.assertEquals("2.0.x.x", metaData.getDatabaseProductVersion());
}
@Test
public void getDriverName() throws SQLException {
Assert.assertEquals("com.taosdata.jdbc.TSDBDriver", metaData.getDriverName());
}
@Test
public void getDriverVersion() throws SQLException {
Assert.assertEquals("2.0.x", metaData.getDriverVersion());
}
@Test
public void getDriverMajorVersion() {
Assert.assertEquals(2, metaData.getDriverMajorVersion());
}
@Test
public void getDriverMinorVersion() {
Assert.assertEquals(0, metaData.getDriverMinorVersion());
}
@Test
public void usesLocalFiles() throws SQLException {
Assert.assertFalse(metaData.usesLocalFiles());
}
@Test
public void usesLocalFilePerTable() throws SQLException {
Assert.assertFalse(metaData.usesLocalFilePerTable());
}
@Test
public void supportsMixedCaseIdentifiers() throws SQLException {
Assert.assertFalse(metaData.supportsMixedCaseIdentifiers());
}
@Test
public void storesUpperCaseIdentifiers() throws SQLException {
Assert.assertFalse(metaData.storesUpperCaseIdentifiers());
}
@Test
public void storesLowerCaseIdentifiers() throws SQLException {
Assert.assertTrue(metaData.storesLowerCaseIdentifiers());
}
@Test
public void storesMixedCaseIdentifiers() throws SQLException {
Assert.assertFalse(metaData.storesMixedCaseIdentifiers());
}
@Test
public void supportsMixedCaseQuotedIdentifiers() throws SQLException {
Assert.assertFalse(metaData.supportsMixedCaseQuotedIdentifiers());
}
@Test
public void storesUpperCaseQuotedIdentifiers() throws SQLException {
Assert.assertFalse(metaData.storesUpperCaseQuotedIdentifiers());
}
@Test
public void storesLowerCaseQuotedIdentifiers() throws SQLException {
Assert.assertFalse(metaData.storesLowerCaseQuotedIdentifiers());
}
@Test
public void storesMixedCaseQuotedIdentifiers() throws SQLException {
Assert.assertFalse(metaData.storesMixedCaseQuotedIdentifiers());
}
@Test
public void getIdentifierQuoteString() throws SQLException {
Assert.assertEquals(" ", metaData.getIdentifierQuoteString());
}
@Test
public void getSQLKeywords() throws SQLException {
Assert.assertEquals(null, metaData.getSQLKeywords());
}
@Test
public void getNumericFunctions() throws SQLException {
Assert.assertEquals(null, metaData.getNumericFunctions());
}
@Test
public void getStringFunctions() throws SQLException {
Assert.assertEquals(null, metaData.getStringFunctions());
}
@Test
public void getSystemFunctions() throws SQLException {
Assert.assertEquals(null, metaData.getSystemFunctions());
}
@Test
public void getTimeDateFunctions() throws SQLException {
Assert.assertEquals(null, metaData.getTimeDateFunctions());
}
@Test
public void getSearchStringEscape() throws SQLException {
Assert.assertEquals(null, metaData.getSearchStringEscape());
}
@Test
public void getExtraNameCharacters() throws SQLException {
Assert.assertEquals(null, metaData.getExtraNameCharacters());
}
@Test
public void supportsAlterTableWithAddColumn() throws SQLException {
Assert.assertTrue(metaData.supportsAlterTableWithAddColumn());
}
@Test
public void supportsAlterTableWithDropColumn() throws SQLException {
Assert.assertTrue(metaData.supportsAlterTableWithDropColumn());
}
@Test
public void supportsColumnAliasing() throws SQLException {
Assert.assertTrue(metaData.supportsColumnAliasing());
}
@Test
public void nullPlusNonNullIsNull() throws SQLException {
Assert.assertFalse(metaData.nullPlusNonNullIsNull());
}
@Test
public void supportsConvert() throws SQLException {
Assert.assertFalse(metaData.supportsConvert());
}
@Test
public void testSupportsConvert() throws SQLException {
Assert.assertFalse(metaData.supportsConvert(1, 1));
}
@Test
public void supportsTableCorrelationNames() throws SQLException {
Assert.assertFalse(metaData.supportsTableCorrelationNames());
}
@Test
public void supportsDifferentTableCorrelationNames() throws SQLException {
Assert.assertFalse(metaData.supportsDifferentTableCorrelationNames());
}
@Test
public void supportsExpressionsInOrderBy() throws SQLException {
Assert.assertFalse(metaData.supportsExpressionsInOrderBy());
}
@Test
public void supportsOrderByUnrelated() throws SQLException {
Assert.assertFalse(metaData.supportsOrderByUnrelated());
}
@Test
public void supportsGroupBy() throws SQLException {
Assert.assertTrue(metaData.supportsGroupBy());
}
@Test
public void supportsGroupByUnrelated() throws SQLException {
Assert.assertFalse(metaData.supportsGroupByUnrelated());
}
@Test
public void supportsGroupByBeyondSelect() throws SQLException {
Assert.assertFalse(metaData.supportsGroupByBeyondSelect());
}
@Test
public void supportsLikeEscapeClause() throws SQLException {
Assert.assertFalse(metaData.supportsLikeEscapeClause());
}
@Test
public void supportsMultipleResultSets() throws SQLException {
Assert.assertFalse(metaData.supportsMultipleResultSets());
}
@Test
public void supportsMultipleTransactions() throws SQLException {
Assert.assertFalse(metaData.supportsMultipleTransactions());
}
@Test
public void supportsNonNullableColumns() throws SQLException {
Assert.assertFalse(metaData.supportsNonNullableColumns());
}
@Test
public void supportsMinimumSQLGrammar() throws SQLException {
Assert.assertFalse(metaData.supportsMinimumSQLGrammar());
}
@Test
public void supportsCoreSQLGrammar() throws SQLException {
Assert.assertFalse(metaData.supportsCoreSQLGrammar());
}
@Test
public void supportsExtendedSQLGrammar() throws SQLException {
Assert.assertFalse(metaData.supportsExtendedSQLGrammar());
}
@Test
public void supportsANSI92EntryLevelSQL() throws SQLException {
Assert.assertFalse(metaData.supportsANSI92EntryLevelSQL());
}
@Test
public void supportsANSI92IntermediateSQL() throws SQLException {
Assert.assertFalse(metaData.supportsANSI92IntermediateSQL());
}
@Test
public void supportsANSI92FullSQL() throws SQLException {
Assert.assertFalse(metaData.supportsANSI92FullSQL());
}
@Test
public void supportsIntegrityEnhancementFacility() throws SQLException {
Assert.assertFalse(metaData.supportsIntegrityEnhancementFacility());
}
@Test
public void supportsOuterJoins() throws SQLException {
Assert.assertFalse(metaData.supportsOuterJoins());
}
@Test
public void supportsFullOuterJoins() throws SQLException {
Assert.assertFalse(metaData.supportsFullOuterJoins());
}
@Test
public void supportsLimitedOuterJoins() throws SQLException {
Assert.assertFalse(metaData.supportsLimitedOuterJoins());
}
@Test
public void getSchemaTerm() throws SQLException {
Assert.assertNull(metaData.getSchemaTerm());
}
@Test
public void getProcedureTerm() throws SQLException {
Assert.assertNull(metaData.getProcedureTerm());
}
@Test
public void getCatalogTerm() throws SQLException {
Assert.assertEquals("database", metaData.getCatalogTerm());
}
@Test
public void isCatalogAtStart() throws SQLException {
Assert.assertTrue(metaData.isCatalogAtStart());
}
@Test
public void getCatalogSeparator() throws SQLException {
Assert.assertEquals(".", metaData.getCatalogSeparator());
}
@Test
public void supportsSchemasInDataManipulation() throws SQLException {
Assert.assertFalse(metaData.supportsSchemasInDataManipulation());
}
@Test
public void supportsSchemasInProcedureCalls() throws SQLException {
Assert.assertFalse(metaData.supportsSchemasInProcedureCalls());
}
@Test
public void supportsSchemasInTableDefinitions() throws SQLException {
Assert.assertFalse(metaData.supportsSchemasInTableDefinitions());
}
@Test
public void supportsSchemasInIndexDefinitions() throws SQLException {
Assert.assertFalse(metaData.supportsSchemasInIndexDefinitions());
}
@Test
public void supportsSchemasInPrivilegeDefinitions() throws SQLException {
Assert.assertFalse(metaData.supportsSchemasInPrivilegeDefinitions());
}
@Test
public void supportsCatalogsInDataManipulation() throws SQLException {
Assert.assertTrue(metaData.supportsCatalogsInDataManipulation());
}
@Test
public void supportsCatalogsInProcedureCalls() throws SQLException {
Assert.assertFalse(metaData.supportsCatalogsInProcedureCalls());
}
@Test
public void supportsCatalogsInTableDefinitions() throws SQLException {
Assert.assertFalse(metaData.supportsCatalogsInTableDefinitions());
}
@Test
public void supportsCatalogsInIndexDefinitions() throws SQLException {
Assert.assertFalse(metaData.supportsCatalogsInIndexDefinitions());
}
@Test
public void supportsCatalogsInPrivilegeDefinitions() throws SQLException {
Assert.assertFalse(metaData.supportsCatalogsInPrivilegeDefinitions());
}
@Test
public void supportsPositionedDelete() throws SQLException {
Assert.assertFalse(metaData.supportsPositionedDelete());
}
@Test
public void supportsPositionedUpdate() throws SQLException {
Assert.assertFalse(metaData.supportsPositionedUpdate());
}
@Test
public void supportsSelectForUpdate() throws SQLException {
Assert.assertFalse(metaData.supportsSelectForUpdate());
}
@Test
public void supportsStoredProcedures() throws SQLException {
Assert.assertFalse(metaData.supportsStoredProcedures());
}
@Test
public void supportsSubqueriesInComparisons() throws SQLException {
Assert.assertFalse(metaData.supportsSubqueriesInComparisons());
}
@Test
public void supportsSubqueriesInExists() throws SQLException {
Assert.assertFalse(metaData.supportsSubqueriesInExists());
}
@Test
public void supportsSubqueriesInIns() throws SQLException {
Assert.assertFalse(metaData.supportsSubqueriesInIns());
}
@Test
public void supportsSubqueriesInQuantifieds() throws SQLException {
Assert.assertFalse(metaData.supportsSubqueriesInQuantifieds());
}
@Test
public void supportsCorrelatedSubqueries() throws SQLException {
Assert.assertFalse(metaData.supportsCorrelatedSubqueries());
}
@Test
public void supportsUnion() throws SQLException {
Assert.assertFalse(metaData.supportsUnion());
}
@Test
public void supportsUnionAll() throws SQLException {
Assert.assertFalse(metaData.supportsUnionAll());
}
@Test
public void supportsOpenCursorsAcrossCommit() throws SQLException {
Assert.assertFalse(metaData.supportsOpenCursorsAcrossCommit());
}
@Test
public void supportsOpenCursorsAcrossRollback() throws SQLException {
Assert.assertFalse(metaData.supportsOpenCursorsAcrossRollback());
}
@Test
public void supportsOpenStatementsAcrossCommit() throws SQLException {
Assert.assertFalse(metaData.supportsOpenStatementsAcrossCommit());
}
@Test
public void supportsOpenStatementsAcrossRollback() throws SQLException {
Assert.assertFalse(metaData.supportsOpenStatementsAcrossRollback());
}
@Test
public void getMaxBinaryLiteralLength() throws SQLException {
Assert.assertEquals(0, metaData.getMaxBinaryLiteralLength());
}
@Test
public void getMaxCharLiteralLength() throws SQLException {
Assert.assertEquals(0, metaData.getMaxCharLiteralLength());
}
@Test
public void getMaxColumnNameLength() throws SQLException {
Assert.assertEquals(0, metaData.getMaxColumnNameLength());
}
@Test
public void getMaxColumnsInGroupBy() throws SQLException {
Assert.assertEquals(0, metaData.getMaxColumnsInGroupBy());
}
@Test
public void getMaxColumnsInIndex() throws SQLException {
Assert.assertEquals(0, metaData.getMaxColumnsInIndex());
}
@Test
public void getMaxColumnsInOrderBy() throws SQLException {
Assert.assertEquals(0, metaData.getMaxColumnsInOrderBy());
}
@Test
public void getMaxColumnsInSelect() throws SQLException {
Assert.assertEquals(0, metaData.getMaxColumnsInSelect());
}
@Test
public void getMaxColumnsInTable() throws SQLException {
Assert.assertEquals(0, metaData.getMaxColumnsInTable());
}
@Test
public void getMaxConnections() throws SQLException {
Assert.assertEquals(0, metaData.getMaxConnections());
}
@Test
public void getMaxCursorNameLength() throws SQLException {
Assert.assertEquals(0, metaData.getMaxCursorNameLength());
}
@Test
public void getMaxIndexLength() throws SQLException {
Assert.assertEquals(0, metaData.getMaxIndexLength());
}
@Test
public void getMaxSchemaNameLength() throws SQLException {
Assert.assertEquals(0, metaData.getMaxSchemaNameLength());
}
@Test
public void getMaxProcedureNameLength() throws SQLException {
Assert.assertEquals(0, metaData.getMaxProcedureNameLength());
}
@Test
public void getMaxCatalogNameLength() throws SQLException {
Assert.assertEquals(0, metaData.getMaxCatalogNameLength());
}
@Test
public void getMaxRowSize() throws SQLException {
Assert.assertEquals(0, metaData.getMaxRowSize());
}
@Test
public void doesMaxRowSizeIncludeBlobs() throws SQLException {
Assert.assertFalse(metaData.doesMaxRowSizeIncludeBlobs());
}
@Test
public void getMaxStatementLength() throws SQLException {
Assert.assertEquals(0, metaData.getMaxStatementLength());
}
@Test
public void getMaxStatements() throws SQLException {
Assert.assertEquals(0, metaData.getMaxStatements());
}
@Test
public void getMaxTableNameLength() throws SQLException {
Assert.assertEquals(0, metaData.getMaxTableNameLength());
}
@Test
public void getMaxTablesInSelect() throws SQLException {
Assert.assertEquals(0, metaData.getMaxTablesInSelect());
}
@Test
public void getMaxUserNameLength() throws SQLException {
Assert.assertEquals(0, metaData.getMaxUserNameLength());
}
@Test
public void getDefaultTransactionIsolation() throws SQLException {
Assert.assertEquals(Connection.TRANSACTION_NONE, metaData.getDefaultTransactionIsolation());
}
@Test
public void supportsTransactions() throws SQLException {
Assert.assertFalse(metaData.supportsTransactions());
}
@Test
public void supportsTransactionIsolationLevel() throws SQLException {
Assert.assertTrue(metaData.supportsTransactionIsolationLevel(Connection.TRANSACTION_NONE));
Assert.assertFalse(metaData.supportsTransactionIsolationLevel(Connection.TRANSACTION_READ_COMMITTED));
Assert.assertFalse(metaData.supportsTransactionIsolationLevel(Connection.TRANSACTION_READ_UNCOMMITTED));
Assert.assertFalse(metaData.supportsTransactionIsolationLevel(Connection.TRANSACTION_REPEATABLE_READ));
Assert.assertFalse(metaData.supportsTransactionIsolationLevel(Connection.TRANSACTION_SERIALIZABLE));
}
@Test
public void supportsDataDefinitionAndDataManipulationTransactions() throws SQLException {
Assert.assertFalse(metaData.supportsDataDefinitionAndDataManipulationTransactions());
}
@Test
public void supportsDataManipulationTransactionsOnly() throws SQLException {
Assert.assertFalse(metaData.supportsDataManipulationTransactionsOnly());
}
@Test
public void dataDefinitionCausesTransactionCommit() throws SQLException {
Assert.assertFalse(metaData.dataDefinitionCausesTransactionCommit());
}
@Test
public void dataDefinitionIgnoredInTransactions() throws SQLException {
Assert.assertFalse(metaData.dataDefinitionIgnoredInTransactions());
}
@Test
public void getProcedures() throws SQLException {
Assert.assertNull(metaData.getProcedures("*", "*", "*"));
}
@Test
public void getProcedureColumns() throws SQLException {
Assert.assertNull(metaData.getProcedureColumns("*", "*", "*", "*"));
}
@Test
public void getTables() throws SQLException {
Assert.assertNull(metaData.getTables("", "", "*", null));
}
@Test
public void getSchemas() throws SQLException {
Assert.assertNotNull(metaData.getSchemas());
}
@Test
public void getCatalogs() throws SQLException {
Assert.assertNotNull(metaData.getCatalogs());
}
@Test
public void getTableTypes() throws SQLException {
Assert.assertNotNull(metaData.getTableTypes());
}
@Test
public void getColumns() throws SQLException {
Assert.assertNotNull(metaData.getColumns("", "", "", ""));
}
@Test
public void getColumnPrivileges() throws SQLException {
Assert.assertNotNull(metaData.getColumnPrivileges("", "", "", ""));
}
@Test
public void getTablePrivileges() throws SQLException {
Assert.assertNotNull(metaData.getTablePrivileges("", "", ""));
}
@Test
public void getBestRowIdentifier() throws SQLException {
Assert.assertNotNull(metaData.getBestRowIdentifier("", "", "", 0, false));
}
@Test
public void getVersionColumns() throws SQLException {
Assert.assertNotNull(metaData.getVersionColumns("", "", ""));
}
@Test
public void getPrimaryKeys() throws SQLException {
Assert.assertNotNull(metaData.getPrimaryKeys("", "", ""));
}
@Test
public void getImportedKeys() throws SQLException {
Assert.assertNotNull(metaData.getImportedKeys("", "", ""));
}
@Test
public void getExportedKeys() throws SQLException {
Assert.assertNotNull(metaData.getExportedKeys("", "", ""));
}
@Test
public void getCrossReference() throws SQLException {
Assert.assertNotNull(metaData.getCrossReference("", "", "", "", "", ""));
}
@Test
public void getTypeInfo() throws SQLException {
Assert.assertNotNull(metaData.getTypeInfo());
}
@Test
public void getIndexInfo() throws SQLException {
Assert.assertNotNull(metaData.getIndexInfo("", "", "", false, false));
}
@Test
public void supportsResultSetType() throws SQLException {
Assert.assertFalse(metaData.supportsResultSetType(0));
}
@Test
public void supportsResultSetConcurrency() throws SQLException {
Assert.assertFalse(metaData.supportsResultSetConcurrency(0, 0));
}
@Test
public void ownUpdatesAreVisible() throws SQLException {
Assert.assertFalse(metaData.ownUpdatesAreVisible(0));
}
@Test
public void ownDeletesAreVisible() throws SQLException {
Assert.assertFalse(metaData.ownDeletesAreVisible(0));
}
@Test
public void ownInsertsAreVisible() throws SQLException {
Assert.assertFalse(metaData.ownInsertsAreVisible(0));
}
@Test
public void othersUpdatesAreVisible() throws SQLException {
Assert.assertFalse(metaData.othersUpdatesAreVisible(0));
}
@Test
public void othersDeletesAreVisible() throws SQLException {
Assert.assertFalse(metaData.othersDeletesAreVisible(0));
}
@Test
public void othersInsertsAreVisible() throws SQLException {
Assert.assertFalse(metaData.othersInsertsAreVisible(0));
}
@Test
public void updatesAreDetected() throws SQLException {
Assert.assertFalse(metaData.updatesAreDetected(0));
}
@Test
public void deletesAreDetected() throws SQLException {
Assert.assertFalse(metaData.deletesAreDetected(0));
}
@Test
public void insertsAreDetected() throws SQLException {
Assert.assertFalse(metaData.insertsAreDetected(0));
}
@Test
public void supportsBatchUpdates() throws SQLException {
Assert.assertFalse(metaData.supportsBatchUpdates());
}
@Test
public void getUDTs() throws SQLException {
Assert.assertNotNull(metaData.getUDTs("", "", "", null));
}
@Test
public void getConnection() throws SQLException {
Assert.assertNotNull(metaData.getConnection());
}
@Test
public void supportsSavepoints() throws SQLException {
Assert.assertFalse(metaData.supportsSavepoints());
}
@Test
public void supportsNamedParameters() throws SQLException {
Assert.assertFalse(metaData.supportsNamedParameters());
}
@Test
public void supportsMultipleOpenResults() throws SQLException {
Assert.assertFalse(metaData.supportsMultipleOpenResults());
}
@Test
public void supportsGetGeneratedKeys() throws SQLException {
Assert.assertFalse(metaData.supportsGetGeneratedKeys());
}
@Test
public void getSuperTypes() throws SQLException {
Assert.assertNotNull(metaData.getSuperTypes("", "", ""));
}
@Test
public void getSuperTables() throws SQLException {
Assert.assertNotNull(metaData.getSuperTables("", "", ""));
}
@Test
public void getAttributes() throws SQLException {
Assert.assertNotNull(metaData.getAttributes("", "", "", ""));
}
@Test
public void supportsResultSetHoldability() throws SQLException {
Assert.assertTrue(metaData.supportsResultSetHoldability(ResultSet.HOLD_CURSORS_OVER_COMMIT));
Assert.assertFalse(metaData.supportsResultSetHoldability(ResultSet.CLOSE_CURSORS_AT_COMMIT));
}
@Test
public void getResultSetHoldability() throws SQLException {
Assert.assertEquals(1, metaData.getResultSetHoldability());
}
@Test
public void getDatabaseMajorVersion() throws SQLException {
Assert.assertEquals(2, metaData.getDatabaseMajorVersion());
}
@Test
public void getDatabaseMinorVersion() throws SQLException {
Assert.assertEquals(0, metaData.getDatabaseMinorVersion());
}
@Test
public void getJDBCMajorVersion() throws SQLException {
Assert.assertEquals(2, metaData.getJDBCMajorVersion());
}
@Test
public void getJDBCMinorVersion() throws SQLException {
Assert.assertEquals(0, metaData.getJDBCMinorVersion());
}
@Test
public void getSQLStateType() throws SQLException {
Assert.assertEquals(0, metaData.getSQLStateType());
}
@Test
public void locatorsUpdateCopy() throws SQLException {
Assert.assertFalse(metaData.locatorsUpdateCopy());
}
@Test
public void supportsStatementPooling() throws SQLException {
Assert.assertFalse(metaData.supportsStatementPooling());
}
@Test
public void getRowIdLifetime() throws SQLException {
Assert.assertNull(metaData.getRowIdLifetime());
}
@Test
public void testGetSchemas() throws SQLException {
Assert.assertNull(metaData.getSchemas());
}
@Test
public void supportsStoredFunctionsUsingCallSyntax() throws SQLException {
Assert.assertFalse(metaData.supportsStoredFunctionsUsingCallSyntax());
}
@Test
public void autoCommitFailureClosesAllResultSets() throws SQLException {
Assert.assertFalse(metaData.autoCommitFailureClosesAllResultSets());
}
@Test
public void getClientInfoProperties() throws SQLException {
Assert.assertNotNull(metaData.getClientInfoProperties());
}
@Test
public void getFunctions() throws SQLException {
Assert.assertNotNull(metaData.getFunctions("", "", ""));
}
@Test
public void getFunctionColumns() throws SQLException {
Assert.assertNotNull(metaData.getFunctionColumns("", "", "", ""));
}
@Test
public void getPseudoColumns() throws SQLException {
Assert.assertNotNull(metaData.getPseudoColumns("", "", "", ""));
}
@Test
public void generatedKeyAlwaysReturned() throws SQLException {
Assert.assertFalse(metaData.generatedKeyAlwaysReturned());
}
}
\ No newline at end of file
package com.taosdata.jdbc.cases;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.sql.*;
import java.util.concurrent.TimeUnit;
public class MultiThreadsWithSameStatmentTest {
private class Service {
public Connection conn;
public Statement stmt;
public Service() {
try {
Class.forName("com.taosdata.jdbc.TSDBDriver");
conn = DriverManager.getConnection("jdbc:TAOS://localhost:6030/?user=root&password=taosdata");
stmt = conn.createStatement();
stmt.execute("create database if not exists jdbctest");
stmt.executeUpdate("create table if not exists jdbctest.weather (ts timestamp, f1 int)");
} catch (ClassNotFoundException | SQLException e) {
e.printStackTrace();
}
}
public void release() {
try {
stmt.close();
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
@Before
public void before() {
}
@Test
public void test() {
Thread t1 = new Thread(() -> {
try {
Service service = new Service();
ResultSet resultSet = service.stmt.executeQuery("select * from jdbctest.weather");
while (resultSet.next()) {
ResultSetMetaData metaData = resultSet.getMetaData();
for (int i = 1; i <= metaData.getColumnCount(); i++) {
System.out.print(metaData.getColumnLabel(i) + ": " + resultSet.getString(i));
}
System.out.println();
}
resultSet.close();
service.release();
} catch (SQLException e) {
e.printStackTrace();
}
});
Thread t2 = new Thread(() -> {
while (true) {
try {
Service service = new Service();
service.stmt.executeUpdate("insert into jdbctest.weather values(now,1)");
service.release();
} catch (SQLException e) {
e.printStackTrace();
}
}
});
t1.start();
sleep(1000);
t2.start();
}
private void sleep(long mills) {
try {
TimeUnit.MILLISECONDS.sleep(mills);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
@After
public void after() {
}
}
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
CMAKE_MINIMUM_REQUIRED(VERSION 3.5)
PROJECT(TDengine)
IF (TD_LINUX_64)
......
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
CMAKE_MINIMUM_REQUIRED(VERSION 3.5)
PROJECT(TDengine)
IF (TD_LINUX_64)
......
......@@ -5,7 +5,7 @@ with open("README.md", "r") as fh:
setuptools.setup(
name="taos",
version="2.0.3",
version="2.0.4",
author="Taosdata Inc.",
author_email="support@taosdata.com",
description="TDengine python client package",
......
......@@ -184,7 +184,7 @@ class TDengineCursor(object):
return False
def fetchall(self):
def fetchall_row(self):
"""Fetch all (remaining) rows of a query result, returning them as a sequence of sequences (e.g. a list of tuples). Note that the cursor's arraysize attribute can affect the performance of this operation.
"""
if self._result is None or self._fields is None:
......@@ -203,7 +203,7 @@ class TDengineCursor(object):
for i in range(len(self._fields)):
buffer[i].extend(block[i])
return list(map(tuple, zip(*buffer)))
def fetchall_block(self):
def fetchall(self):
if self._result is None or self._fields is None:
raise OperationalError("Invalid use of fetchall")
......
......@@ -5,7 +5,7 @@ with open("README.md", "r") as fh:
setuptools.setup(
name="taos",
version="2.0.3",
version="2.0.4",
author="Taosdata Inc.",
author_email="support@taosdata.com",
description="TDengine python client package",
......
......@@ -192,7 +192,7 @@ class TDengineCursor(object):
return False
def fetchall(self):
def fetchall_row(self):
"""Fetch all (remaining) rows of a query result, returning them as a sequence of sequences (e.g. a list of tuples). Note that the cursor's arraysize attribute can affect the performance of this operation.
"""
if self._result is None or self._fields is None:
......@@ -212,7 +212,7 @@ class TDengineCursor(object):
buffer[i].extend(block[i])
return list(map(tuple, zip(*buffer)))
def fetchall_block(self):
def fetchall(self):
if self._result is None or self._fields is None:
raise OperationalError("Invalid use of fetchall")
......
......@@ -5,7 +5,7 @@ with open("README.md", "r") as fh:
setuptools.setup(
name="taos",
version="2.0.3",
version="2.0.4",
author="Taosdata Inc.",
author_email="support@taosdata.com",
description="TDengine python client package",
......
......@@ -138,7 +138,7 @@ class TDengineCursor(object):
def fetchmany(self):
pass
def fetchall(self):
def fetchall_row(self):
"""Fetch all (remaining) rows of a query result, returning them as a sequence of sequences (e.g. a list of tuples). Note that the cursor's arraysize attribute can affect the performance of this operation.
"""
if self._result is None or self._fields is None:
......@@ -158,7 +158,7 @@ class TDengineCursor(object):
buffer[i].extend(block[i])
return list(map(tuple, zip(*buffer)))
def fetchall_block(self):
def fetchall(self):
if self._result is None or self._fields is None:
raise OperationalError("Invalid use of fetchall")
......
......@@ -5,7 +5,7 @@ with open("README.md", "r") as fh:
setuptools.setup(
name="taos",
version="2.0.3",
version="2.0.4",
author="Taosdata Inc.",
author_email="support@taosdata.com",
description="TDengine python client package",
......
......@@ -139,7 +139,7 @@ class TDengineCursor(object):
def fetchmany(self):
pass
def fetchall(self):
def fetchall_row(self):
"""Fetch all (remaining) rows of a query result, returning them as a sequence of sequences (e.g. a list of tuples). Note that the cursor's arraysize attribute can affect the performance of this operation.
"""
if self._result is None or self._fields is None:
......@@ -159,7 +159,7 @@ class TDengineCursor(object):
buffer[i].extend(block[i])
return list(map(tuple, zip(*buffer)))
def fetchall_block(self):
def fetchall(self):
if self._result is None or self._fields is None:
raise OperationalError("Invalid use of fetchall")
......
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
CMAKE_MINIMUM_REQUIRED(VERSION 3.5)
PROJECT(TDengine)
INCLUDE_DIRECTORIES(inc)
......
......@@ -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;
......
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
CMAKE_MINIMUM_REQUIRED(VERSION 3.5)
PROJECT(TDengine)
LIST(APPEND CQTEST_SRC ./cqtest.c)
......
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
CMAKE_MINIMUM_REQUIRED(VERSION 3.5)
PROJECT(TDengine)
INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/src/query/inc)
......
......@@ -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);
......
......@@ -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
......@@ -451,7 +444,7 @@ int32_t tStrToInteger(const char* z, int16_t type, int32_t n, int64_t* value, bo
#define TSDB_PORT_HTTP 11
#define TSDB_PORT_ARBITRATOR 12
#define TSDB_MAX_WAL_SIZE (1024*1024*2)
#define TSDB_MAX_WAL_SIZE (1024*1024*3)
typedef enum {
TAOS_QTYPE_RPC = 0,
......
......@@ -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;
......
......@@ -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;
......
......@@ -49,7 +49,7 @@ typedef struct {
SRpcMsg rpcMsg;
SRspRet rspRet;
char reserveForSync[24];
SWalHead pHead[];
SWalHead pHead;
} SVWriteMsg;
// vnodeStatus
......
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
CMAKE_MINIMUM_REQUIRED(VERSION 3.5)
PROJECT(TDengine)
ADD_SUBDIRECTORY(shell)
......
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
CMAKE_MINIMUM_REQUIRED(VERSION 3.5)
PROJECT(TDengine)
INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/src/client/inc)
......
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
CMAKE_MINIMUM_REQUIRED(VERSION 3.5)
PROJECT(TDengine)
INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/src/client/inc)
......
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
CMAKE_MINIMUM_REQUIRED(VERSION 3.5)
PROJECT(TDengine)
INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/src/client/inc)
......
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
CMAKE_MINIMUM_REQUIRED(VERSION 3.5)
PROJECT(TDengine)
INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/src/client/inc)
......
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
CMAKE_MINIMUM_REQUIRED(VERSION 3.5)
PROJECT(TDengine)
IF (TD_LINUX)
......
......@@ -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;
......
......@@ -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;
}
......
......@@ -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;
......
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)
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
CMAKE_MINIMUM_REQUIRED(VERSION 3.5)
PROJECT(TDengine)
AUX_SOURCE_DIRECTORY(. SRC)
......
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
CMAKE_MINIMUM_REQUIRED(VERSION 3.5)
PROJECT(TDengine)
AUX_SOURCE_DIRECTORY(. SRC)
......
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
CMAKE_MINIMUM_REQUIRED(VERSION 3.5)
PROJECT(TDengine)
INCLUDE_DIRECTORIES(.)
......
......@@ -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) {
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;
}
}
......
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
CMAKE_MINIMUM_REQUIRED(VERSION 3.5)
PROJECT(TDengine)
AUX_SOURCE_DIRECTORY(. SRC)
......
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
CMAKE_MINIMUM_REQUIRED(VERSION 3.5)
PROJECT(TDengine)
AUX_SOURCE_DIRECTORY(. SRC)
......
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
#include "os.h"
#include <gtest/gtest.h>
#include <cassert>
#include <iostream>
#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);
}
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
CMAKE_MINIMUM_REQUIRED(VERSION 3.5)
PROJECT(TDengine)
ADD_SUBDIRECTORY(monitor)
......
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)
......
......@@ -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;
......
......@@ -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);
......
......@@ -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;
}
......
......@@ -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;
}
......
......@@ -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;
}
......
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
CMAKE_MINIMUM_REQUIRED(VERSION 3.5)
PROJECT(TDengine)
INCLUDE_DIRECTORIES(inc)
......
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
CMAKE_MINIMUM_REQUIRED(VERSION 3.5)
PROJECT(TDengine)
INCLUDE_DIRECTORIES(inc)
......
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
CMAKE_MINIMUM_REQUIRED(VERSION 3.5)
PROJECT(TDengine)
INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/src/tsdb/inc)
......
......@@ -16,6 +16,10 @@
#ifndef TDENGINE_QPERCENTILE_H
#define TDENGINE_QPERCENTILE_H
#ifdef __cplusplus
extern "C" {
#endif
#include "qExtbuffer.h"
#include "qResultbuf.h"
#include "qTsbuf.h"
......@@ -23,13 +27,13 @@
typedef struct MinMaxEntry {
union {
double dMinVal;
int32_t iMinVal;
int64_t i64MinVal;
uint64_t u64MinVal;
};
union {
double dMaxVal;
int32_t iMaxVal;
int64_t i64MaxVal;
int64_t u64MaxVal;
};
} MinMaxEntry;
......@@ -59,7 +63,7 @@ typedef struct tMemBucket {
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;
} tMemBucket;
......@@ -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
......@@ -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;
......
......@@ -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
}
......@@ -6928,11 +6932,12 @@ static size_t getResultSize(SQInfo *pQInfo, int64_t *numOfRows) {
*/
if (isTSCompQuery(pQuery) && (*numOfRows) > 0) {
struct stat fStat;
if (fstat(fileno(*(FILE **)pQuery->sdata[0]->data), &fStat) == 0) {
FILE *f = *(FILE **)pQuery->sdata[0]->data;
if ((f != NULL) && (fstat(fileno(f), &fStat) == 0)) {
*numOfRows = fStat.st_size;
return fStat.st_size;
} else {
qError("QInfo:%p failed to get file info, path:%s, reason:%s", pQInfo, pQuery->sdata[0]->data, strerror(errno));
qError("QInfo:%p failed to get file info, file:%p, reason:%s", pQInfo, f, strerror(errno));
return 0;
}
} else {
......@@ -6947,7 +6952,7 @@ static int32_t doDumpQueryResult(SQInfo *pQInfo, char *data) {
// load data from file to msg buffer
if (isTSCompQuery(pQuery)) {
FILE *f = *(FILE **)pQuery->sdata[0]->data;
FILE *f = *(FILE **)pQuery->sdata[0]->data; // TODO refactor
// make sure file exist
if (f) {
......
......@@ -12,14 +12,14 @@
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "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: {
if (IS_SIGNED_NUMERIC_TYPE(type)) {
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: {
} else if (IS_UNSIGNED_NUMERIC_TYPE(type)) {
range->u64MaxVal = 0;
range->u64MinVal = UINT64_MAX;
} else {
range->dMaxVal = -DBL_MAX;
range->dMinVal = DBL_MAX;
break;
}
}
}
......@@ -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:
if (IS_SIGNED_NUMERIC_TYPE(type)) {
range->i64MinVal = (int64_t) minval;
range->i64MaxVal = (int64_t) maxval;
break;
case TSDB_DATA_TYPE_FLOAT:
case TSDB_DATA_TYPE_DOUBLE:
} else if (IS_UNSIGNED_NUMERIC_TYPE(type)){
range->u64MinVal = (uint64_t) minval;
range->u64MaxVal = (uint64_t) maxval;
} else {
range->dMinVal = minval;
range->dMaxVal = maxval;
break;
}
return 0;
......@@ -120,58 +102,24 @@ 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);
}
return index;
} else {
// out of range
if (v < pBucket->range.i64MinVal || v > pBucket->range.i64MaxVal) {
return -1;
}
int32_t tBucketIntHash(tMemBucket *pBucket, const void *value) {
int64_t v = 0;
GET_TYPED_DATA(v, int64_t, pBucket->type, value);
// todo hash for bigint and float and double
int64_t span = pBucket->range.i64MaxVal - pBucket->range.i64MinVal;
int32_t index = -1;
// divide the value range into 1024 buckets
uint64_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;
int64_t delta = v - pBucket->range.i64MinVal;
index = (delta % pBucket->numOfSlots);
} else {
double slotSpan = (double)span / pBucket->numOfSlots;
index = (int32_t)((v - pBucket->range.i64MinVal) / slotSpan);
......@@ -180,57 +128,30 @@ int32_t tBucketBigIntHash(tMemBucket *pBucket, const void *value) {
}
}
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;
} else {
// out of range
if (v < pBucket->range.iMinVal || v > pBucket->range.iMaxVal) {
return -1;
}
// divide a range of [iMinVal, iMaxVal] into 1024 buckets
int32_t span = pBucket->range.iMaxVal - pBucket->range.iMinVal;
// divide the value range into 1024 buckets
uint64_t span = pBucket->range.u64MaxVal - pBucket->range.u64MinVal;
if (span < pBucket->numOfSlots) {
int32_t delta = v - pBucket->range.iMinVal;
index = (delta % pBucket->numOfSlots);
int64_t delta = v - pBucket->range.u64MinVal;
index = (int32_t) (delta % pBucket->numOfSlots);
} else {
double slotSpan = (double)span / pBucket->numOfSlots;
index = (int32_t)((v - pBucket->range.iMinVal) / slotSpan);
if (v == pBucket->range.iMaxVal) {
index = (int32_t)((v - pBucket->range.u64MinVal) / slotSpan);
if (v == pBucket->range.u64MaxVal) {
index -= 1;
}
}
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,21 +164,6 @@ 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;
} else {
// out of range
if (v < pBucket->range.dMinVal || v > pBucket->range.dMaxVal) {
return -1;
}
// divide a range of [dMinVal, dMaxVal] into 1024 buckets
double span = pBucket->range.dMaxVal - pBucket->range.dMinVal;
if (span < pBucket->numOfSlots) {
......@@ -271,34 +177,17 @@ int32_t tBucketDoubleHash(tMemBucket *pBucket, const void *value) {
}
}
if (index < 0 || index > pBucket->numOfSlots) {
uError("error in hash process. slot id: %d", 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: {
if (IS_SIGNED_NUMERIC_TYPE(type)) {
return tBucketIntHash;
};
case TSDB_DATA_TYPE_DOUBLE:
case TSDB_DATA_TYPE_FLOAT: {
} else if (IS_UNSIGNED_NUMERIC_TYPE(type)) {
return tBucketUintHash;
} else {
return tBucketDoubleHash;
};
case TSDB_DATA_TYPE_BIGINT: {
return tBucketBigIntHash;
};
default: {
return NULL;
}
}
}
......@@ -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 (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 (IS_SIGNED_NUMERIC_TYPE(dataType)) {
int64_t v = 0;
GET_TYPED_DATA(v, int64_t, dataType, data);
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->i64MinVal > v) {
r->i64MinVal = v;
}
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->i64MaxVal < v) {
r->i64MaxVal = v;
}
} else if (IS_UNSIGNED_NUMERIC_TYPE(dataType)) {
uint64_t v = 0;
GET_TYPED_DATA(v, uint64_t, dataType, data);
if (r->iMaxVal < val) {
r->iMaxVal = val;
if (r->i64MinVal > v) {
r->i64MinVal = v;
}
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->i64MaxVal < v) {
r->i64MaxVal = v;
}
} else if (IS_FLOAT_TYPE(dataType)) {
double v = 0;
GET_TYPED_DATA(v, double, dataType, data);
if (r->dMaxVal < val) {
r->dMaxVal = val;
}
break;
};
case TSDB_DATA_TYPE_FLOAT: {
double val = GET_FLOAT_VAL(data);
if (r->dMinVal > val) {
r->dMinVal = val;
if (r->dMinVal > v) {
r->dMinVal = v;
}
if (r->dMaxVal < val) {
r->dMaxVal = val;
if (r->dMaxVal < v) {
r->dMaxVal = v;
}
break;
};
default: { assert(false); }
} 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: {
if (IS_SIGNED_NUMERIC_TYPE(pMemBucket->type)) {
double v = (double)(fabs(percent - 100) < DBL_EPSILON ? pRange->i64MaxVal : pRange->i64MinVal);
return v;
}
case TSDB_DATA_TYPE_FLOAT:
case TSDB_DATA_TYPE_DOUBLE:
} 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;
default:
return -1;
}
}
......@@ -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;
}
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)
......
#include <gtest/gtest.h>
#include <iostream>
#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();
}
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
CMAKE_MINIMUM_REQUIRED(VERSION 3.5)
PROJECT(TDengine)
INCLUDE_DIRECTORIES(inc)
......
......@@ -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);
}
}
......
......@@ -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);
......
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
CMAKE_MINIMUM_REQUIRED(VERSION 3.5)
PROJECT(TDengine)
INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/src/rpc/inc)
......
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
CMAKE_MINIMUM_REQUIRED(VERSION 3.5)
PROJECT(TDengine)
INCLUDE_DIRECTORIES(inc)
......
......@@ -475,7 +475,8 @@ void *syncRetrieveData(void *param) {
SSyncNode *pNode = pPeer->pSyncNode;
taosBlockSIGPIPE();
sInfo("%s, start to retrieve data, sstatus:%s", pPeer->id, syncStatus[pPeer->sstatus]);
sInfo("%s, start to retrieve data, sstatus:%s, numOfRetrieves:%d", pPeer->id, syncStatus[pPeer->sstatus],
pPeer->numOfRetrieves);
if (pNode->notifyFlowCtrl) (*pNode->notifyFlowCtrl)(pNode->vgId, pPeer->numOfRetrieves);
......@@ -497,9 +498,11 @@ void *syncRetrieveData(void *param) {
pPeer->numOfRetrieves++;
} else {
pPeer->numOfRetrieves = 0;
if (pNode->notifyFlowCtrl) (*pNode->notifyFlowCtrl)(pNode->vgId, 0);
// if (pNode->notifyFlowCtrl) (*pNode->notifyFlowCtrl)(pNode->vgId, 0);
}
if (pNode->notifyFlowCtrl) (*pNode->notifyFlowCtrl)(pNode->vgId, 0);
pPeer->fileChanged = 0;
taosClose(pPeer->syncFd);
......
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
CMAKE_MINIMUM_REQUIRED(VERSION 3.5)
PROJECT(TDengine)
IF (TD_LINUX)
......
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
CMAKE_MINIMUM_REQUIRED(VERSION 3.5)
PROJECT(TDengine)
INCLUDE_DIRECTORIES(inc)
......
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
CMAKE_MINIMUM_REQUIRED(VERSION 3.5)
PROJECT(TDengine)
INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/src/rpc/inc)
......
......@@ -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) {
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;
} else {
return (lhs > rhs) ? 1 : -1;
}
}
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) {
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;
} else {
return (lhs > rhs) ? 1 : -1;
}
}
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;
......
......@@ -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;
......
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)
......
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
CMAKE_MINIMUM_REQUIRED(VERSION 3.5)
PROJECT(TDengine)
INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/src/query/inc)
......
......@@ -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;
......
......@@ -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;
......@@ -305,7 +308,7 @@ static void vnodeFlowCtrlMsgToWQueue(void *param, void *tmrId) {
if (pVnode->flowctrlLevel <= 0) code = TSDB_CODE_VND_IS_FLOWCTRL;
pWrite->processedCount++;
if (pWrite->processedCount > 100) {
if (pWrite->processedCount >= 100) {
vError("vgId:%d, msg:%p, failed to process since %s, retry:%d", pVnode->vgId, pWrite, tstrerror(code),
pWrite->processedCount);
pWrite->processedCount = 1;
......
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
CMAKE_MINIMUM_REQUIRED(VERSION 3.5)
PROJECT(TDengine)
INCLUDE_DIRECTORIES(inc)
......
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
CMAKE_MINIMUM_REQUIRED(VERSION 3.5)
PROJECT(TDengine)
IF (TD_LINUX)
......
......@@ -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)
......
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
CMAKE_MINIMUM_REQUIRED(VERSION 3.5)
PROJECT(TDengine)
IF (TD_LINUX)
......
......@@ -12,28 +12,25 @@ Usage: mono taosdemo.exe [OPTION...]
--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.
-h <hostname> host, The host to connect to TDengine. Default is localhost.
-p <port> port, The TCP/IP port number to use for the connection. Default is 0.
-u <username> user, The user name to use when connecting to the server. Default is 'root'.
-P <password> password, The password to use when connecting to the server. Default is 'taosdata'.
-d <dbname> database, Destination database. Default is 'test'.
-a <replications> replica, Set the replica parameters of the database, Default 1, min: 1, max: 5.
-m <table prefix> table_prefix, Table prefix name. Default is 't'.
-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/'.
-s <stable prefix> stable_prefix, STable prefix name. Default is 'st'
-Q <DEFAULT | command> query, Execute query command. set 'DEFAULT' means select * from each table
-T <number> num_of_threads, The number of threads. Default is 10.
-r <number> num_of_records_per_req, The number of records per request. Default is 1000.
-t <number> num_of_tables, The number of tables. Default is 1.
-n <number> num_of_records_per_table, The number of records per table. Default is 1.
-c <path> 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.
-R <number> rate, Out of order data's rate--if order=1 Default 10, min: 0, max: 50.
-D <number> 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
......@@ -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 <hostname>", "host, The host to connect to TDengine. Default is localhost.");
HelpPrint("-p <port>", "port, The TCP/IP port number to use for the connection. Default is 0.");
HelpPrint("-u <username>", "user, The user name to use when connecting to the server. Default is 'root'.");
HelpPrint("-P <password>", "password, The password to use when connecting to the server. Default is 'taosdata'.");
HelpPrint("-d <dbname>", "database, Destination database. Default is 'test'.");
HelpPrint("-a <replications>", "replica, Set the replica parameters of the database, Default 1, min: 1, max: 5.");
HelpPrint("-m <table prefix>", "table_prefix, Table prefix name. Default is 't'.");
HelpPrint("-M", "stable, Use super table.");
HelpPrint("-s <stable prefix>", "stable_prefix, STable prefix name. Default is 'st'");
HelpPrint("-Q <DEFAULT | command>", "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 <number>", "num_of_threads, The number of threads. Default is 10.");
HelpPrint("-r <number>", "num_of_records_per_req, The number of records per request. Default is 1000.");
HelpPrint("-t <number>", "num_of_tables, The number of tables. Default is 1.");
HelpPrint("-n <number>", "num_of_records_per_table, The number of records per table. Default is 1.");
HelpPrint("-c <path>", "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 <number>", "rate, Out of order data's rate--if order=1 Default 10, min: 0, max: 50.");
HelpPrint("-D <number>", "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;
if (query == "DEFAULT")
{
sql = "select * from " + this.dbName + "." + tablePrefix + i;
}
else
{
String sql = "select * from " + this.dbName + "." + tablePrefix + i;
// Console.WriteLine(sql);
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<TDengineMeta> 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.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);
}
......
需求:
1. 可以读lowa的配置文件
2. 支持对JNI方式和Restful方式的taos-driver
\ No newline at end of file
2. 支持JDBC-JNI和JDBC-restful
3. 读取配置文件,持续执行查询
\ No newline at end of file
......@@ -19,14 +19,13 @@ import java.util.Map;
public class TaosDemoApplication {
private static Logger logger = Logger.getLogger(TaosDemoApplication.class);
private static final Logger logger = Logger.getLogger(TaosDemoApplication.class);
public static void main(String[] args) throws IOException {
// 读配置参数
JdbcTaosdemoConfig config = new JdbcTaosdemoConfig(args);
boolean isHelp = Arrays.asList(args).contains("--help");
if (isHelp || config.host == null || config.host.isEmpty()) {
// if (isHelp) {
JdbcTaosdemoConfig.printHelp();
System.exit(0);
}
......@@ -75,7 +74,7 @@ public class TaosDemoApplication {
}
}
end = System.currentTimeMillis();
logger.error(">>> create table time cost : " + (end - start) + " ms.");
logger.info(">>> create table time cost : " + (end - start) + " ms.");
/**********************************************************************************/
// 插入
long tableSize = config.numOfTables;
......@@ -90,7 +89,7 @@ public class TaosDemoApplication {
// multi threads to insert
int affectedRows = subTableService.insertMultiThreads(superTableMeta, threadSize, tableSize, startTime, gap, config);
end = System.currentTimeMillis();
logger.error("insert " + affectedRows + " rows, time cost: " + (end - start) + " ms");
logger.info("insert " + affectedRows + " rows, time cost: " + (end - start) + " ms");
/**********************************************************************************/
// 删除表
if (config.dropTable) {
......@@ -108,5 +107,4 @@ public class TaosDemoApplication {
return startTime;
}
}
......@@ -21,27 +21,27 @@ public class DatabaseMapperImpl implements DatabaseMapper {
public void createDatabase(String dbname) {
String sql = "create database if not exists " + dbname;
jdbcTemplate.execute(sql);
logger.info("SQL >>> " + sql);
logger.debug("SQL >>> " + sql);
}
@Override
public void dropDatabase(String dbname) {
String sql = "drop database if exists " + dbname;
jdbcTemplate.update(sql);
logger.info("SQL >>> " + sql);
logger.debug("SQL >>> " + sql);
}
@Override
public void createDatabaseWithParameters(Map<String, String> map) {
String sql = SqlSpeller.createDatabase(map);
jdbcTemplate.execute(sql);
logger.info("SQL >>> " + sql);
logger.debug("SQL >>> " + sql);
}
@Override
public void useDatabase(String dbname) {
String sql = "use " + dbname;
jdbcTemplate.execute(sql);
logger.info("SQL >>> " + sql);
logger.debug("SQL >>> " + sql);
}
}
......@@ -21,14 +21,14 @@ public class SubTableMapperImpl implements SubTableMapper {
@Override
public void createUsingSuperTable(SubTableMeta subTableMeta) {
String sql = SqlSpeller.createTableUsingSuperTable(subTableMeta);
logger.info("SQL >>> " + sql);
logger.debug("SQL >>> " + sql);
jdbcTemplate.execute(sql);
}
@Override
public int insertOneTableMultiValues(SubTableValue subTableValue) {
String sql = SqlSpeller.insertOneTableMultiValues(subTableValue);
logger.info("SQL >>> " + sql);
logger.debug("SQL >>> " + sql);
int affectRows = 0;
try {
......@@ -42,7 +42,7 @@ public class SubTableMapperImpl implements SubTableMapper {
@Override
public int insertOneTableMultiValuesUsingSuperTable(SubTableValue subTableValue) {
String sql = SqlSpeller.insertOneTableMultiValuesUsingSuperTable(subTableValue);
logger.info("SQL >>> " + sql);
logger.debug("SQL >>> " + sql);
int affectRows = 0;
try {
......@@ -56,7 +56,7 @@ public class SubTableMapperImpl implements SubTableMapper {
@Override
public int insertMultiTableMultiValues(List<SubTableValue> tables) {
String sql = SqlSpeller.insertMultiSubTableMultiValues(tables);
logger.info("SQL >>> " + sql);
logger.debug("SQL >>> " + sql);
int affectRows = 0;
try {
affectRows = jdbcTemplate.update(sql);
......@@ -69,7 +69,7 @@ public class SubTableMapperImpl implements SubTableMapper {
@Override
public int insertMultiTableMultiValuesUsingSuperTable(List<SubTableValue> tables) {
String sql = SqlSpeller.insertMultiTableMultiValuesUsingSuperTable(tables);
logger.info("SQL >>> " + sql);
logger.debug("SQL >>> " + sql);
int affectRows = 0;
try {
affectRows = jdbcTemplate.update(sql);
......
......@@ -18,14 +18,14 @@ public class SuperTableMapperImpl implements SuperTableMapper {
@Override
public void createSuperTable(SuperTableMeta tableMetadata) {
String sql = SqlSpeller.createSuperTable(tableMetadata);
logger.info("SQL >>> " + sql);
logger.debug("SQL >>> " + sql);
jdbcTemplate.execute(sql);
}
@Override
public void dropSuperTable(String database, String name) {
String sql = "drop table if exists " + database + "." + name;
logger.info("SQL >>> " + sql);
logger.debug("SQL >>> " + sql);
jdbcTemplate.execute(sql);
}
}
package com.taosdata.taosdemo.dao;
import com.taosdata.taosdemo.dao.TableMapper;
import com.taosdata.taosdemo.domain.TableMeta;
import com.taosdata.taosdemo.domain.TableValue;
import com.taosdata.taosdemo.utils.SqlSpeller;
import org.apache.log4j.Logger;
import org.springframework.jdbc.core.JdbcTemplate;
import java.util.List;
public class TableMapperImpl implements TableMapper {
private static final Logger logger = Logger.getLogger(TableMapperImpl.class);
private JdbcTemplate template;
@Override
public void create(TableMeta tableMeta) {
String sql = SqlSpeller.createTable(tableMeta);
logger.debug("SQL >>> " + sql);
template.execute(sql);
}
@Override
public int insertOneTableMultiValues(TableValue values) {
String sql = SqlSpeller.insertOneTableMultiValues(values);
logger.debug("SQL >>> " + sql);
return template.update(sql);
}
@Override
public int insertOneTableMultiValuesWithColumns(TableValue values) {
String sql = SqlSpeller.insertOneTableMultiValuesWithColumns(values);
logger.debug("SQL >>> " + sql);
return template.update(sql);
}
@Override
public int insertMultiTableMultiValues(List<TableValue> tables) {
String sql = SqlSpeller.insertMultiTableMultiValues(tables);
logger.debug("SQL >>> " + sql);
return template.update(sql);
}
@Override
public int insertMultiTableMultiValuesWithColumns(List<TableValue> tables) {
String sql = SqlSpeller.insertMultiTableMultiValuesWithColumns(tables);
logger.debug("SQL >>> " + sql);
return template.update(sql);
}
}
### 设置###
log4j.rootLogger=error,stdout
log4j.rootLogger=info,stdout
### 输出信息到控制抬 ###
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
......
......@@ -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()
......
......@@ -36,9 +36,8 @@ class TDTestCase:
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")
......
......@@ -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
......
###################################################################
# 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())
###################################################################
# 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())
###################################################################
# 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())
###################################################################
# 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())
###################################################################
# 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())
###################################################################
# 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())
###################################################################
# 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())
###################################################################
# 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())
###################################################################
# 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())
###################################################################
# 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())
###################################################################
# 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())
###################################################################
# 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())
......@@ -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()
......
......@@ -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)
......
......@@ -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__)
......
......@@ -208,13 +208,23 @@ 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():
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))
......
......@@ -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
......@@ -184,5 +187,49 @@ class TDSql:
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()
......@@ -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
......
......@@ -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
......
......@@ -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
......
......@@ -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
......
......@@ -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
......
......@@ -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
......
......@@ -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
......
......@@ -107,3 +107,69 @@ if $data01 != 1 then
endi
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
......@@ -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
......@@ -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
......
......@@ -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
......
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
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
......
......@@ -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
......
......@@ -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
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
......
......@@ -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
......
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
CMAKE_MINIMUM_REQUIRED(VERSION 3.5)
PROJECT(TDengine)
INCLUDE_DIRECTORIES(${TD_COMMUNITY_DIR}/src/inc)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册