diff --git a/.gitignore b/.gitignore
index 2c37aa92f77dd14bd274be94568dfe904f48c5f4..0458aa3415dc61005fe77b38c7c3366b1fcf461c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -82,6 +82,10 @@ tests/comparisonTest/opentsdb/opentsdbtest/.settings/
tests/examples/JDBC/JDBCDemo/.classpath
tests/examples/JDBC/JDBCDemo/.project
tests/examples/JDBC/JDBCDemo/.settings/
+tests/script/api/batchprepare
+tests/script/api/stmt
+tests/script/api/stmtBatchTest
+tests/script/api/stmtTest
# Emacs
# -*- mode: gitignore; -*-
diff --git a/Jenkinsfile b/Jenkinsfile
index 9cc65d24f8aae3a97890e6676ff1091d32f7dc59..297dde63e196ff3ae4083926f51bd6a88c1c9f3a 100644
--- a/Jenkinsfile
+++ b/Jenkinsfile
@@ -455,17 +455,18 @@ pipeline {
npm install td2.0-connector > /dev/null 2>&1
node nodejsChecker.js host=localhost
node test1970.js
- cd ${WKC}/tests/connectorTest/nodejsTest/nanosupport
- npm install td2.0-connector > /dev/null 2>&1
+ cd ${WKC}/tests/connectorTest/nodejsTest/nanosupport
+ npm install td2.0-connector > /dev/null 2>&1
node nanosecondTest.js
'''
-
- sh '''
- cd ${WKC}/tests/examples/C#/taosdemo
- mcs -out:taosdemo *.cs > /dev/null 2>&1
- echo '' |./taosdemo -c /etc/taos
- '''
+ catchError(buildResult: 'SUCCESS', stageResult: 'FAILURE') {
+ sh '''
+ cd ${WKC}/tests/examples/C#/taosdemo
+ mcs -out:taosdemo *.cs > /dev/null 2>&1
+ echo '' |./taosdemo -c /etc/taos
+ '''
+ }
sh '''
cd ${WKC}/tests/gotest
bash batchtest.sh
diff --git a/cmake/define.inc b/cmake/define.inc
index b381853eba57aa7b9efb905790e77b1d1fdcf900..92044b8c2dd3710c5a1808abcecd7d2358230e7a 100755
--- a/cmake/define.inc
+++ b/cmake/define.inc
@@ -135,6 +135,8 @@ IF ("${BUILD_HTTP}" STREQUAL "")
ELSE ()
SET(BUILD_HTTP "false")
ENDIF ()
+ ELSEIF (TD_DARWIN)
+ SET(BUILD_HTTP "false")
ELSE ()
SET(BUILD_HTTP "true")
ENDIF ()
diff --git a/cmake/platform.inc b/cmake/platform.inc
index 328c5f23ee95af54daa7e4a925c33ce09acd3cfb..2a0aace8d08e9dba1451daa051df4b614a21d398 100755
--- a/cmake/platform.inc
+++ b/cmake/platform.inc
@@ -36,7 +36,13 @@ IF (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
# Get OS information and store in variable TD_OS_INFO.
#
execute_process(COMMAND chmod 777 ${TD_COMMUNITY_DIR}/packaging/tools/get_os.sh)
- execute_process(COMMAND sh ${TD_COMMUNITY_DIR}/packaging/tools/get_os.sh "" OUTPUT_VARIABLE TD_OS_INFO)
+ execute_process(COMMAND readlink /bin/sh OUTPUT_VARIABLE SHELL_LINK)
+ MESSAGE(STATUS "The shell is: " ${SHELL_LINK})
+ IF (${SHELL_LINK} MATCHES "dash")
+ execute_process(COMMAND ${TD_COMMUNITY_DIR}/packaging/tools/get_os.sh "" OUTPUT_VARIABLE TD_OS_INFO)
+ ELSE ()
+ execute_process(COMMAND sh ${TD_COMMUNITY_DIR}/packaging/tools/get_os.sh "" OUTPUT_VARIABLE TD_OS_INFO)
+ ENDIF()
MESSAGE(STATUS "The current os is " ${TD_OS_INFO})
SET(TD_LINUX TRUE)
diff --git a/cmake/version.inc b/cmake/version.inc
index 94ff39f5e655d89b16b57a4b8c8fbe275c82a49a..ee3d1e356d15ba6484aa67df9d8dc09625b777d7 100755
--- a/cmake/version.inc
+++ b/cmake/version.inc
@@ -4,7 +4,7 @@ PROJECT(TDengine)
IF (DEFINED VERNUMBER)
SET(TD_VER_NUMBER ${VERNUMBER})
ELSE ()
- SET(TD_VER_NUMBER "2.3.1.0")
+ SET(TD_VER_NUMBER "2.3.2.0")
ENDIF ()
IF (DEFINED VERCOMPATIBLE)
diff --git a/deps/CMakeLists.txt b/deps/CMakeLists.txt
index 773a791a2527712270f569d5c04aa7f8ef066e40..38f36c4ed6678675cecfa9c0da1a3d065b58da86 100644
--- a/deps/CMakeLists.txt
+++ b/deps/CMakeLists.txt
@@ -55,6 +55,7 @@ IF (TD_LINUX_64 AND JEMALLOC_ENABLED)
MESSAGE("")
MESSAGE("setup deps/jemalloc, current source dir:" ${CMAKE_CURRENT_SOURCE_DIR})
MESSAGE("binary dir:" ${CMAKE_BINARY_DIR})
+ include(ExternalProject)
ExternalProject_Add(jemalloc
PREFIX "jemalloc"
SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/jemalloc
@@ -62,6 +63,7 @@ IF (TD_LINUX_64 AND JEMALLOC_ENABLED)
CONFIGURE_COMMAND ./autogen.sh COMMAND ./configure --prefix=${CMAKE_BINARY_DIR}/build/
BUILD_COMMAND ${MAKE}
)
+ INCLUDE_DIRECTORIES(${CMAKE_BINARY_DIR}/build/include)
ENDIF ()
IF (${TSZ_ENABLED} MATCHES "true")
diff --git a/documentation20/cn/00.index/docs.md b/documentation20/cn/00.index/docs.md
index 70a6b7c5281e1a96f8348ff3a3bb81892b80c93c..a4fba357bbc47bd84ea7c2a6931a64bf274e5d9b 100644
--- a/documentation20/cn/00.index/docs.md
+++ b/documentation20/cn/00.index/docs.md
@@ -121,10 +121,11 @@ TDengine是一个高效的存储、查询、分析时序大数据的平台,专
* [数据复制](/architecture/replica):支持实时同步、异步复制,保证系统的High Availibility
* [技术博客](https://www.taosdata.com/cn/blog/?categories=3):更多的技术分析和架构设计文章
-## [应用 TDengine 快速搭建 IT 运维系统](/devops)
+## 应用 TDengine 快速搭建 IT 运维系统
* [devops](/devops/telegraf):使用 TDengine + Telegraf + Grafana 快速搭建 IT 运维系统
* [devops](/devops/collectd):使用 TDengine + collectd_statsd + Grafana 快速搭建 IT 运维系统
+* [最佳实践](/devops/immigrate):OpenTSDB 应用迁移到 TDengine 的最佳实践
## 常用工具
diff --git a/documentation20/cn/05.insert/docs.md b/documentation20/cn/05.insert/docs.md
index 24ac6c52e19e24697c8ad35fdaf822adbd614a0a..a82aecd97c832f9b7f276ec27832097e46845dfc 100644
--- a/documentation20/cn/05.insert/docs.md
+++ b/documentation20/cn/05.insert/docs.md
@@ -145,27 +145,27 @@ st,t1=3,t2=4,t3=t3 c1=3i64,c6="passit" 1626006833640000000
如果是无模式写入过程中的数据本身错误,应用会得到 TSDB_CODE_TSC_LINE_SYNTAX_ERROR 错误信息,该错误信息表明错误发生在写入文本中。其他的错误码与原系统一致,可以通过 taos_errstr 获取具体的错误原因。
**后续升级计划**
-
当前版本只提供了 C 版本的 API,后续将提供 其他高级语言的 API,例如 Java/Go/Python/C# 等。此外,在TDengine v2.3及后续版本中,您还可以通过 BLM v3 采用 REST 的方式直接写入无模式数据。
+
当前版本只提供了 C 版本的 API,后续将提供 其他高级语言的 API,例如 Java/Go/Python/C# 等。此外,在TDengine v2.3及后续版本中,您还可以通过 Taos Adapter 采用 REST 的方式直接写入无模式数据。
## Prometheus 直接写入
[Prometheus](https://www.prometheus.io/)作为Cloud Native Computing Fundation毕业的项目,在性能监控以及K8S性能监控领域有着非常广泛的应用。TDengine提供一个小工具[Bailongma](https://github.com/taosdata/Bailongma),只需对Prometheus做简单配置,无需任何代码,就可将Prometheus采集的数据直接写入TDengine,并按规则在TDengine自动创建库和相关表项。博文[用Docker容器快速搭建一个Devops监控Demo](https://www.taosdata.com/blog/2020/02/03/1189.html)即是采用Bailongma将Prometheus和Telegraf的数据写入TDengine中的示例,可以参考。
-### 从源代码编译 taosadapter_prometheus
+### 从源代码编译 blm_prometheus
用户需要从github下载[Bailongma](https://github.com/taosdata/Bailongma)的源码,使用Golang语言编译器编译生成可执行文件。在开始编译前,需要准备好以下条件:
- Linux操作系统的服务器
- 安装好Golang,1.14版本以上
- 对应的TDengine版本。因为用到了TDengine的客户端动态链接库,因此需要安装好和服务端相同版本的TDengine程序;比如服务端版本是TDengine 2.0.0, 则在Bailongma所在的Linux服务器(可以与TDengine在同一台服务器,或者不同服务器)
-Bailongma项目中有一个文件夹taosadapter_prometheus,存放了prometheus的写入API程序。编译过程如下:
+Bailongma项目中有一个文件夹blm_prometheus,存放了prometheus的写入API程序。编译过程如下:
```bash
-cd taosadapter_prometheus
+cd blm_prometheus
go build
```
-一切正常的情况下,就会在对应的目录下生成一个taosadapter_prometheus的可执行程序。
+一切正常的情况下,就会在对应的目录下生成一个blm_prometheus的可执行程序。
### 安装 Prometheus
@@ -176,23 +176,23 @@ go build
参考Prometheus的[配置文档](https://prometheus.io/docs/prometheus/latest/configuration/configuration/),在Prometheus的配置文件中的部分,增加以下配置:
```
- - url: "bailongma API服务提供的URL"(参考下面的taosadapter_prometheus启动示例章节)
+ - url: "bailongma API服务提供的URL"(参考下面的blm_prometheus启动示例章节)
```
启动Prometheus后,可以通过taos客户端查询确认数据是否成功写入。
-### 启动 taosadapter_prometheus 程序
+### 启动 blm_prometheus 程序
-taosadapter_prometheus程序有以下选项,在启动taosadapter_prometheus程序时可以通过设定这些选项来设定taosadapter_prometheus的配置。
+blm_prometheus程序有以下选项,在启动blm_prometheus程序时可以通过设定这些选项来设定blm_prometheus的配置。
```bash
--tdengine-name
如果TDengine安装在一台具备域名的服务器上,也可以通过配置TDengine的域名来访问TDengine。在K8S环境下,可以配置成TDengine所运行的service name。
--batch-size
-taosadapter_prometheus会将收到的prometheus的数据拼装成TDengine的写入请求,这个参数控制一次发给TDengine的写入请求中携带的数据条数。
+blm_prometheus会将收到的prometheus的数据拼装成TDengine的写入请求,这个参数控制一次发给TDengine的写入请求中携带的数据条数。
--dbname
-设置在TDengine中创建的数据库名称,taosadapter_prometheus会自动在TDengine中创建一个以dbname为名称的数据库,缺省值是prometheus。
+设置在TDengine中创建的数据库名称,blm_prometheus会自动在TDengine中创建一个以dbname为名称的数据库,缺省值是prometheus。
--dbuser
设置访问TDengine的用户名,缺省值是'root'。
@@ -201,16 +201,16 @@ taosadapter_prometheus会将收到的prometheus的数据拼装成TDengine的写
设置访问TDengine的密码,缺省值是'taosdata'。
--port
-taosadapter_prometheus对prometheus提供服务的端口号。
+blm_prometheus对prometheus提供服务的端口号。
```
### 启动示例
-通过以下命令启动一个taosadapter_prometheus的API服务
+通过以下命令启动一个blm_prometheus的API服务
```bash
-./taosadapter_prometheus -port 8088
+./blm_prometheus -port 8088
```
-假设taosadapter_prometheus所在服务器的IP地址为"10.1.2.3",则在prometheus的配置文件中部分增加url为
+假设blm_prometheus所在服务器的IP地址为"10.1.2.3",则在prometheus的配置文件中部分增加url为
```yaml
remote_write:
- url: "http://10.1.2.3:8088/receive"
@@ -235,7 +235,7 @@ prometheus产生的数据格式如下:
}
}
```
-其中,apiserver_request_latencies_bucket为prometheus采集的时序数据的名称,后面{}中的为该时序数据的标签。taosadapter_prometheus会以时序数据的名称在TDengine中自动创建一个超级表,并将{}中的标签转换成TDengine的tag值,Timestamp作为时间戳,value作为该时序数据的值。因此在TDengine的客户端中,可以通过以下指令查到这个数据是否成功写入。
+其中,apiserver_request_latencies_bucket为prometheus采集的时序数据的名称,后面{}中的为该时序数据的标签。blm_prometheus会以时序数据的名称在TDengine中自动创建一个超级表,并将{}中的标签转换成TDengine的tag值,Timestamp作为时间戳,value作为该时序数据的值。因此在TDengine的客户端中,可以通过以下指令查到这个数据是否成功写入。
```mysql
use prometheus;
select * from apiserver_request_latencies_bucket;
@@ -314,7 +314,7 @@ taosadapter 相关配置参数请参考 taosadapter --help 命令输出以及相
[Telegraf](https://www.influxdata.com/time-series-platform/telegraf/)是一流行的IT运维数据采集开源工具,TDengine提供一个小工具[Bailongma](https://github.com/taosdata/Bailongma),只需在Telegraf做简单配置,无需任何代码,就可将Telegraf采集的数据直接写入TDengine,并按规则在TDengine自动创建库和相关表项。博文[用Docker容器快速搭建一个Devops监控Demo](https://www.taosdata.com/blog/2020/02/03/1189.html)即是采用bailongma将Prometheus和Telegraf的数据写入TDengine中的示例,可以参考。
-### 从源代码编译 taosadapter_telegraf
+### 从源代码编译 blm_telegraf
用户需要从github下载[Bailongma](https://github.com/taosdata/Bailongma)的源码,使用Golang语言编译器编译生成可执行文件。在开始编译前,需要准备好以下条件:
@@ -322,14 +322,14 @@ taosadapter 相关配置参数请参考 taosadapter --help 命令输出以及相
- 安装好Golang,1.10版本以上
- 对应的TDengine版本。因为用到了TDengine的客户端动态链接库,因此需要安装好和服务端相同版本的TDengine程序;比如服务端版本是TDengine 2.0.0, 则在Bailongma所在的Linux服务器(可以与TDengine在同一台服务器,或者不同服务器)
-Bailongma项目中有一个文件夹taosadapter_telegraf,存放了Telegraf的写入API程序。编译过程如下:
+Bailongma项目中有一个文件夹blm_telegraf,存放了Telegraf的写入API程序。编译过程如下:
```bash
-cd taosadapter_telegraf
+cd blm_telegraf
go build
```
-一切正常的情况下,就会在对应的目录下生成一个taosadapter_telegraf的可执行程序。
+一切正常的情况下,就会在对应的目录下生成一个blm_telegraf的可执行程序。
### 安装 Telegraf
@@ -352,19 +352,19 @@ go build
关于如何使用Telegraf采集数据以及更多有关使用Telegraf的信息,请参考Telegraf官方的[文档](https://docs.influxdata.com/telegraf/v1.11/)。
-### 启动 taosadapter_telegraf 程序
+### 启动 blm_telegraf 程序
-taosadapter_telegraf程序有以下选项,在启动taosadapter_telegraf程序时可以通过设定这些选项来设定taosadapter_telegraf的配置。
+blm_telegraf程序有以下选项,在启动blm_telegraf程序时可以通过设定这些选项来设定blm_telegraf的配置。
```bash
--host
TDengine服务端的IP地址,缺省值为空。
--batch-size
-taosadapter_telegraf会将收到的telegraf的数据拼装成TDengine的写入请求,这个参数控制一次发给TDengine的写入请求中携带的数据条数。
+blm_telegraf会将收到的telegraf的数据拼装成TDengine的写入请求,这个参数控制一次发给TDengine的写入请求中携带的数据条数。
--dbname
-设置在TDengine中创建的数据库名称,taosadapter_telegraf会自动在TDengine中创建一个以dbname为名称的数据库,缺省值是prometheus。
+设置在TDengine中创建的数据库名称,blm_telegraf会自动在TDengine中创建一个以dbname为名称的数据库,缺省值是prometheus。
--dbuser
设置访问TDengine的用户名,缺省值是'root'。
@@ -373,17 +373,17 @@ taosadapter_telegraf会将收到的telegraf的数据拼装成TDengine的写入
设置访问TDengine的密码,缺省值是'taosdata'。
--port
-taosadapter_telegraf对telegraf提供服务的端口号。
+blm_telegraf对telegraf提供服务的端口号。
```
### 启动示例
-通过以下命令启动一个taosadapter_telegraf的API服务:
+通过以下命令启动一个blm_telegraf的API服务:
```bash
-./taosadapter_telegraf -host 127.0.0.1 -port 8089
+./blm_telegraf -host 127.0.0.1 -port 8089
```
-假设taosadapter_telegraf所在服务器的IP地址为"10.1.2.3",则在telegraf的配置文件中, 在output plugins部分,增加[[outputs.http]]配置项:
+假设blm_telegraf所在服务器的IP地址为"10.1.2.3",则在telegraf的配置文件中, 在output plugins部分,增加[[outputs.http]]配置项:
```yaml
url = "http://10.1.2.3:8089/telegraf"
@@ -416,7 +416,7 @@ telegraf产生的数据格式如下:
}
```
-其中,name字段为telegraf采集的时序数据的名称,tags字段为该时序数据的标签。taosadapter_telegraf会以时序数据的名称在TDengine中自动创建一个超级表,并将tags字段中的标签转换成TDengine的tag值,timestamp作为时间戳,fields字段中的值作为该时序数据的值。因此在TDengine的客户端中,可以通过以下指令查到这个数据是否成功写入。
+其中,name字段为telegraf采集的时序数据的名称,tags字段为该时序数据的标签。blm_telegraf会以时序数据的名称在TDengine中自动创建一个超级表,并将tags字段中的标签转换成TDengine的tag值,timestamp作为时间戳,fields字段中的值作为该时序数据的值。因此在TDengine的客户端中,可以通过以下指令查到这个数据是否成功写入。
```mysql
use telegraf;
diff --git a/documentation20/cn/08.connector/docs.md b/documentation20/cn/08.connector/docs.md
index b4543111b22008467ba749018fa2c19321f4f18e..a1689151aabd82b93821a11cb6de107090db0fae 100644
--- a/documentation20/cn/08.connector/docs.md
+++ b/documentation20/cn/08.connector/docs.md
@@ -328,7 +328,7 @@ TDengine的异步API均采用非阻塞调用模式。应用程序可以用多线
除 C/C++ 语言外,TDengine 的 Java 语言 JNI Connector 也提供参数绑定接口支持,具体请另外参见:[参数绑定接口的 Java 用法](https://www.taosdata.com/cn/documentation/connector/java#stmt-java)。
-接口相关的具体函数如下(也可以参考 [apitest.c](https://github.com/taosdata/TDengine/blob/develop/tests/examples/c/apitest.c) 文件中使用对应函数的方式):
+接口相关的具体函数如下(也可以参考 [prepare.c](https://github.com/taosdata/TDengine/blob/develop/tests/examples/c/prepare.c) 文件中使用对应函数的方式):
- `TAOS_STMT* taos_stmt_init(TAOS *taos)`
diff --git a/documentation20/cn/11.administrator/docs.md b/documentation20/cn/11.administrator/docs.md
index 448df75d808e06996ef61814692c7948adb11e32..4ef1c60112018cb29289314e199feda75ca7c2ba 100644
--- a/documentation20/cn/11.administrator/docs.md
+++ b/documentation20/cn/11.administrator/docs.md
@@ -1,4 +1,4 @@
-# TDengine的运营与运维
+# TDengine的运营与维护
## 容量规划
@@ -157,7 +157,7 @@ taosd -C
| 39 | keep | | **S** | 天 | 数据保留的天数 | | 3650 | |
| 40 | minRows | | **S** | | 文件块中记录的最小条数 | | 100 | |
| 41 | maxRows | | **S** | | 文件块中记录的最大条数 | | 4096 | |
-| 42 | quorum | | **S** | | 异步写入成功所需应答之法定数 | 1-3 | 1 | |
+| 42 | quorum | | **S** | | 多副本环境下指令执行的确认数要求 | 1,2 | 1 | |
| 43 | comp | | **S** | | 文件压缩标志位 | 0:关闭,1:一阶段压缩,2:两阶段压缩 | 2 | |
| 44 | walLevel | | **S** | | WAL级别 | 1:写wal, 但不执行fsync; 2:写wal, 而且执行fsync | 1 | |
| 45 | fsync | | **S** | 毫秒 | 当wal设置为2时,执行fsync的周期 | 最小为0,表示每次写入,立即执行fsync;最大为180000(三分钟) | 3000 | |
diff --git a/documentation20/cn/12.taos-sql/docs.md b/documentation20/cn/12.taos-sql/docs.md
index 4ba496d575e0f680c2dbd2820d3dfc062c56cb1c..18c39d665483997f1680f0253baddd8ceabcf1d9 100644
--- a/documentation20/cn/12.taos-sql/docs.md
+++ b/documentation20/cn/12.taos-sql/docs.md
@@ -124,7 +124,7 @@ TDengine 缺省的时间戳是毫秒精度,但通过在 CREATE DATABASE 时传
```mysql
ALTER DATABASE db_name QUORUM 2;
```
- QUORUM 参数是指数据写入成功所需要的确认数,取值范围 [1, 2]。对于异步复制,quorum 设为 1,具有 master 角色的虚拟节点自己确认即可。对于同步复制,需要至少大于等于 2。原则上,Quorum >= 1 并且 Quorum <= replica(副本数),这个参数在启动一个同步模块实例时需要提供。
+ QUORUM 参数是指数据写入成功所需要的确认数,取值范围 [1, 2]。对于异步复制,quorum 设为 1,具有 master 角色的虚拟节点自己确认即可。对于同步复制,quorum 设为 2。原则上,Quorum >= 1 并且 Quorum <= replica(副本数),这个参数在启动一个同步模块实例时需要提供。
```mysql
ALTER DATABASE db_name BLOCKS 100;
@@ -719,7 +719,7 @@ Query OK, 1 row(s) in set (0.001091s)
* 暂不支持含列名的四则运算表达式用于条件过滤算子(例如,不支持 `where a*2>6;`,但可以写 `where a>6/2;`)。
* 暂不支持含列名的四则运算表达式作为 SQL 函数的应用对象(例如,不支持 `select min(2*a) from t;`,但可以写 `select 2*min(a) from t;`)。
- WHERE 语句可以使用各种逻辑判断来过滤数字值,或使用通配符来过滤字符串。
-- 输出结果缺省按首列时间戳升序排序,但可以指定按降序排序( _c0 指首列时间戳)。使用 ORDER BY 对其他字段进行排序为非法操作。
+- 输出结果缺省按首列时间戳升序排序,但可以指定按降序排序( _c0 指首列时间戳)。使用 ORDER BY 对其他字段进行排序,排序结果顺序不确定。
- 参数 LIMIT 控制输出条数,OFFSET 指定从第几条开始输出。LIMIT/OFFSET 对结果集的执行顺序在 ORDER BY 之后。且 `LIMIT 5 OFFSET 2` 可以简写为 `LIMIT 2, 5`。
* 在有 GROUP BY 子句的情况下,LIMIT 参数控制的是每个分组中至多允许输出的条数。
- 参数 SLIMIT 控制由 GROUP BY 指令划分的分组中,至多允许输出几个分组的数据。且 `SLIMIT 5 SOFFSET 2` 可以简写为 `SLIMIT 2, 5`。
@@ -743,7 +743,7 @@ Query OK, 1 row(s) in set (0.001091s)
1. <> 算子也可以写为 != ,请注意,这个算子不能用于数据表第一列的 timestamp 字段。
2. like 算子使用通配符字符串进行匹配检查。
- * 在通配符字符串中:'%'(百分号)匹配 0 到任意个字符;'\_'(下划线)匹配单个任意字符。
+ * 在通配符字符串中:'%'(百分号)匹配 0 到任意个字符;'\_'(下划线)匹配单个任意ASCII字符。
* 如果希望匹配字符串中原本就带有的 \_(下划线)字符,那么可以在通配符字符串中写作 `\_`,也即加一个反斜线来进行转义。(从 2.2.0.0 版本开始支持)
* 通配符字符串最长不能超过 20 字节。(从 2.1.6.1 版本开始,通配符字符串的长度放宽到了 100 字节,并可以通过 taos.cfg 中的 maxWildCardsLength 参数来配置这一长度限制。但不建议使用太长的通配符字符串,将有可能严重影响 LIKE 操作的执行性能。)
3. 同时进行多个字段的范围过滤,需要使用关键词 AND 来连接不同的查询条件,暂不支持 OR 连接的不同列之间的查询过滤条件。
diff --git a/documentation20/cn/14.devops/02.collectd/docs.md b/documentation20/cn/14.devops/02.collectd/docs.md
index a35772bb498d426a1f44a9e7eb0bea61b51f92a5..5860e70ceafafadc21c5772c96515e0925897e3a 100644
--- a/documentation20/cn/14.devops/02.collectd/docs.md
+++ b/documentation20/cn/14.devops/02.collectd/docs.md
@@ -40,7 +40,7 @@ IT 运维监测数据通常都是对时间特性比较敏感的数据,例如
```
### 配置 collectd
-在 /etc/collectd/collectd.conf 文件中增加如下内容,其中 host 和 port 请填写 TDengine 和 BLM3 配置的实际值:
+在 /etc/collectd/collectd.conf 文件中增加如下内容,其中 host 和 port 请填写 TDengine 和 Taos Adapter 配置的实际值:
```
LoadPlugin network
@@ -51,7 +51,7 @@ sudo systemctl start collectd
```
### 配置 StatsD
-在 config.js 文件中增加如下内容后启动 StatsD,其中 host 和 port 请填写 TDengine 和 BLM3 配置的实际值:
+在 config.js 文件中增加如下内容后启动 StatsD,其中 host 和 port 请填写 TDengine 和 Taos Adapter 配置的实际值:
```
backends 部分添加 "./backends/repeater"
repeater 部分添加 { host:'', port: }
diff --git a/documentation20/cn/14.devops/03.immigrate/docs.md b/documentation20/cn/14.devops/03.immigrate/docs.md
new file mode 100644
index 0000000000000000000000000000000000000000..b2a68e1b15acef2d574600e59d1b18d890938ac6
--- /dev/null
+++ b/documentation20/cn/14.devops/03.immigrate/docs.md
@@ -0,0 +1,435 @@
+# OpenTSDB 应用迁移到 TDengine 的最佳实践
+
+作为一个分布式、可伸缩、基于HBase 的分布式时序数据库系统,得益于其先发优势,OpenTSDB被 DevOps 领域的人员引入并广泛地应用在了运维监控领域。但最近几年,随着云计算、微服务、容器化等新技术快速落地发展,企业级服务种类变得越来越多,架构也越来越复杂,应用运行基础环境日益多样化,给系统和运行监控带来的压力也越来越大。从这一现状出发,使用 OpenTSDB 作为DevOps的监控后端存储,越来越受困于其性能问题以及迟缓的功能升级,以及由此而衍生出来的应用部署成本上升和运行效率降低等问题,这些问题随着系统规模的扩大日益严重。
+
+在这一背景下,为满足高速增长的物联网大数据市场和技术需求,在吸取众多传统关系型数据库、NoSQL 数据库、流计算引擎、消息队列等软件的优点之后,涛思数据自主开发出创新型大数据处理产品TDengine。在时序大数据处理上,TDengine 有着自己独特的优势。就 OpenTSDB 当前遇到的问题来说,TDengine 能够有效解决。
+
+相对于 OpenTSDB,TDengine 具有如下显著特点:
+
+- 数据写入和查询的性能远超 OpenTSDB;
+- 针对时序数据的高效压缩机制,压缩后在磁盘上的存储空间不到 1/5;
+- 安装部署非常简单,单一安装包完成安装部署,除了 taosadapter 需要依赖 Go 运行环境外,不依赖其他的第三方软件,整个安装部署过程秒级搞定;
+- 提供的内建函数覆盖 OpenTSDB 支持的全部查询函数,还支持更多的时序数据查询函数、标量函数及聚合函数,支持多种时间窗口聚合、连接查询、表达式运算、多种分组聚合、用户定义排序、以及用户定义函数等高级查询功能。采用类 SQL 的语法规则,更加简单易学,基本上没有学习成本。
+- 支持多达 128 个标签,标签总长度可达到 16 KB;
+- 除 HTTP 之外,还提供 Java、Python、C、Rust、Go 等多种语言的接口,支持 JDBC 等多种企业级标准连接器协议。
+
+如果我们将原本运行在 OpenTSDB 上的应用迁移到 TDengine 上,不仅可以有效地降低计算和存储资源的占用、减少部署服务器的规模,还能够极大减少运行维护的成本的输出,让运维管理工作更简单、更轻松,大幅降低总拥有成本。与OpenTSDB一样,TDengine也已经进行了开源,不同的是,除了单机版,后者还实现了集群版开源,被厂商绑定的顾虑一扫而空。
+
+在下文中我们将就“使用最典型并广泛应用的运维监控(DevOps)场景”来说明,如何在不编码的情况下将 OpenTSDB 的应用快速、安全、可靠地迁移到 TDengine之上。后续的章节会做更深度的介绍,以便于进行非DevOps场景的迁移。
+
+## DevOps应用快速迁移
+
+### 1、典型应用场景
+
+一个典型的 DevOps 应用场景的系统整体的架构如下图(图1) 所示。
+
+
+图1. DevOps场景中典型架构
+
+在该应用场景中,包含了部署在应用环境中负责收集机器度量(Metrics)、网络度量(Metrics)以及应用度量(Metrics)的 Agent 工具、汇聚agent收集信息的数据收集器,数据持久化存储和管理的系统以及监控数据可视化工具(例如:Grafana等)。
+
+其中,部署在应用节点的 Agents 负责向 collectd/Statsd 提供不同来源的运行指标,collectd/StatsD则负责将汇聚的数据推送到 OpenTSDB 集群系统,然后使用可视化看板 Grafana 将数据可视化呈现出来。
+
+### 2、迁移服务
+
+- **TDengine 安装部署**
+
+首先是TDengine的安装,从官网上下载TDengine最新稳定版,解压缩后运行install.sh进行安装。各种安装包的使用帮助请参见博客[《 TDengine多种安装包的安装和卸载》](https://www.taosdata.com/blog/2019/08/09/566.html)。
+
+注意,安装完成以后,不要立即启动 taosd 服务,在正确配置完成参数以后再启动。
+
+- **调整数据收集器配置**
+
+在 TDengine 2.3 版本中,后台服务 taosd 启动后一个 HTTP 的服务 taosadapter 也会自动启用*。*利用 taosadapter 能够兼容 Influxdb 的 Line Protocol 和 OpenTSDB 的 telnet/Json 写入协议,可以将 collectd 和 StatsD 收集的数据直接推送到TDengine。
+
+如果使用 collectd,修改其默认位置 `/etc/collectd/collectd.conf` 的配置文件为指向 taosadapter 部署的节点 IP 地址和端口。假设 taosadapter 的 IP 地址为192.168.1.130,端口为 6046,配置如下:
+
+```html
+LoadPlugin write_tsdb
+
+
+ Host "192.168.1.130"
+ Port "6046"
+ HostTags "status=production"
+ StoreRates false
+ AlwaysAppendDS false
+
+
+```
+
+即可让 collectd 将数据使用推送到 OpenTSDB 的插件方式推送到 taosadapter, taosadapter 将调用 API 将数据写入到 taosd 中,从而完成数据的写入工作。如果你使用的是 StatsD 相应地调整配置文件信息。
+
+- **调整看板(Dashborad)系统**
+
+在数据能够正常写入TDengine 后,可以调整适配 Grafana 将写入 TDengine 的数据可视化呈现出来。Grafana 暂时还不能够直接连接 TDengine,在 TDengine 的安装目录下 connector/grafanaplugin 有为 Grafana 提供的连接插件。使用该插件的方式很简单:
+
+首先将grafanaplugin目录下的dist目录整体拷贝到Grafana的插件目录(默认地址为 `/var/lib/grafana/plugins/`),然后重启 Grafana 即可在 **Add Data Source** 菜单下看见 TDengine 数据源。
+
+```shell
+sudo cp -r . /var/lib/grafana/plugins/tdengine
+sudo chown grafana:grafana -R /var/lib/grafana/plugins/tdengine
+echo -e "[plugins]\nallow_loading_unsigned_plugins = taosdata-tdengine-datasource\n" | sudo tee -a /etc/grafana/grafana.ini
+
+# start grafana service
+sudo service grafana-server restart
+# or with systemd
+sudo systemctl start grafana-server
+```
+
+
+
+此外,TDengine 还提供了默认的两套Dashboard 模板,供用户快速查看保存到TDengine库里的信息。你只需要将 Grafana 目录下的模板导入到Grafana中即可激活使用。
+
+
+
+图2. 导入Grafana模板
+
+操作完以上步骤后,就完成了将OpenTSDB替换成为TDengine的迁移工作。可以看到整个流程非常简单,不需要写代码,只需要对某些配置文件进行调整即可完成全部的迁移工作。
+
+### 3、迁移后架构
+
+完成迁移以后,此时的系统整体的架构如下图(图3)所示,而整个过程中采集端、数据写入端、以及监控呈现端均保持了稳定,除了极少的配置调整外,不涉及任何重要的更改和变动。OpenTSDB 大量的应用场景均为 DevOps ,这种场景下,简单的参数设置即可完成 OpenTSDB 到 TDengine 迁移动作,使用上 TDengine 更加强大的处理能力和查询性能。
+
+在绝大多数的 DevOps 场景中,如果你拥有一个小规模的 OpenTSDB 集群(3台及以下的节点)作为 DevOps 的存储端,依赖于 OpenTSDB 为系统持久化层提供数据存储和查询功能,那么你可以安全地将其替换为 TDengine,并节约更多的计算和存储资源。在同等计算资源配置情况下,单台 TDengine 即可满足 3 ~ 5 台 OpenTSDB 节点提供的服务能力。如果规模比较大,那便需要采用TDengine集群。
+
+如果你的应用特别复杂,或者应用领域并不是 DevOps 场景,你可以继续阅读后续的章节,更加全面深入地了解将 OpenTSDB 的应用迁移到 TDengine 的高级话题。
+
+
+
+图3. 迁移完成后的系统架构
+
+## 其他场景的迁移评估与策略
+
+### 1、TDengine 与 OpenTSDB 的差异
+
+本章将详细介绍 OpenTSDB 与 TDengine 在系统功能层面上存在的差异。阅读完本章的内容,你可以全面地评估是否能够将某些基于 OpenTSDB 的复杂应用迁移到TDengine上,以及迁移之后应该注意的问题。
+
+TDengine 当前只支持 Grafana 的可视化看板呈现,所以如果你的应用中使用了 Grafana 以外的前端看板(例如[TSDash](https://github.com/facebook/tsdash)、[Status Wolf](https://github.com/box/StatusWolf)等),那么前端看板将无法直接迁移到 TDengine,需要将前端看板重新适配到 Grafana 才可以正常运行。
+
+截止到 2.3.0.x 版本,TDengine 只能够支持 collectd 和 StatsD 作为数据收集汇聚软件,当然后面会陆续提供更多的数据收集聚合软件的接入支持。如果您的收集端使用了其他类型的数据汇聚器,您的应用需要适配到这两个数据汇聚端系统,才能够将数据正常写入。除了上述两个数据汇聚端软件协议以外,TDengine 还支持通过 InfluxDB 的行协议和 OpenTSDB 的数据写入协议、Json 格式将数据直接写入,您可以重写数据推送端的逻辑,使用 TDengine 支持的行协议来写入数据。
+
+此外,如果你的应用中使用了 OpenTSDB 以下特性,在将应用迁移到 TDengine 之前你还需要了解以下注意事项:
+
+1. ` /api/stats`:如果你的应用中使用了该项特性来监控OpenTSDB的服务状态,并在应用中建立了相关的逻辑来联动处理,那么这部分状态读取和获取的逻辑需要重新适配到TDengine。TDengine 提供了全新的处理集群状态监控机制,来满足你的应用对其进行的监控和维护的需求。
+2. `/api/tree`:如果你依赖于OpenTSDB的该项特性来进行时间线的层级化组织和维护,那么便无法将其直接迁移至TDengine。TDengine 采用了数据库->超级表->子表这样的层级来组织和维护时间线,归属于同一个超级表的所有的时间线在系统中同一个层级,但是可以通过不同标签值的特殊构造来模拟应用逻辑上的多级结构。
+3. `Rollup And PreAggregates`:采用了 Rollup 和 PreAggregates 需要应用来决定在合适的地方访问 Rollup 的结果,在某些场景下又要访问原始的结果,这种结构的不透明性让应用处理逻辑变得极为复杂而且完全不具有移植性。我们认为这种策略是时序数据库无法提供高性能聚合情况下的妥协与折中。TDengine 暂不支持多个时间线的自动降采样和(时间段范围的)预聚合,由于 其拥有的高性能查询处理逻辑,即使不依赖于Rollup 和 (时间段)预聚合计算结果,也能够提供很高性能的查询响应,而且让你的应用查询处理逻辑更加简单。
+4. `Rate`: TDengine提供了两个计算数值变化率的函数,分别是Derivative(其计算结果与InfluxDB的Derivative行为一致)和IRate(其计算结果与Prometheus中的IRate函数计算结果一致)。但是这两个函数的计算结果与 Rate 有细微的差别,但整体上功能更强大。此外,**OpenTSDB提供的所有计算函数,TDengine 均有对应的查询函数支持,并且TDengine的查询函数功能远超过OpenTSDB支持的查询函数,**可以极大地简化你的应用处理逻辑。
+
+通过上面的介绍,相信你应该能够了解OpenTSDB迁移到TDengine带来的变化,这些信息也有助于你正确地判断是否可以接受将应用 迁移到TDengine之上,体验TDengine提供的强大的时序数据处理能力和便捷的使用体验。
+
+### 2、迁移策略
+
+首先将基于OpenTSDB的系统进行迁移涉及到的数据模式设计、系统规模估算、数据写入端改造,进行数据分流、应用适配工作;之后将两个系统并行运行一段时间,再将历史数据迁移到 TDengine 中。当然如果你的应用中有部分功能强依赖于上述OpenTSDB特性,同时又不希望停止使用,可以考虑保持原有的OpenTSDB系统运行,同时启动 TDengine来提供主要的服务。
+
+## 数据模型设计
+
+一方面,TDengine 要求其入库的数据具有严格的模式定义。另一方面,TDengine 的数据模型相对于 OpenTSDB 来说又更加丰富,多值模型能够兼容全部的单值模型的建立需求。
+
+现在让我们假设一个 DevOps 的场景,我们使用了 collectd 收集设备的基础度量(metrics),包含了 memory 、swap、disk 等几个度量,其在 OpenTSDB 中的模式如下:
+
+| 序号 | 测量(metric) | 值名称 | 类型 | tag1 | tag2 | tag3 | tag4 | tag5 |
+| ---- | -------------- | ------ | ------ | ---- | ----------- | -------------------- | --------- | ------ |
+| 1 | memory | value | double | host | memory_type | memory_type_instance | source | |
+| 2 | swap | value | double | host | swap_type | swap_type_instance | source | |
+| 3 | disk | value | double | host | disk_point | disk_instance | disk_type | source |
+
+
+
+TDengine 要求存储的数据具有数据模式,即写入数据之前需创建超级表并指定超级表的模式。对于数据模式的建立,你有两种方式来完成此项工作:1)充分利用TDengine对 OpenTSDB 的数据原生写入的支持,调用 TDengine 提供的 API 将(文本行或 JSON 格式)数据写入,并自动化地建立单值模型。采用这种方式不需要对数据写入应用进行较大的调整,也不需要对写入的数据格式进行转换。
+
+在 C 语言层面,TDengine提供了 taos_insert_lines 来直接写入OpenTSDB格式的数据(在2.3.x 版本中该函数对应的是 taos_schemaless_insert )。其代码参考示例请参见安装包目录下示例代码 schemaless.c。
+
+ 2)在充分理解 TDengine 的数据模型基础上,结合生成数据的特点,手动方式建立 OpenTSDB 到 TDengine 的数据模型调整的映射关系。TDengine 能够支持多值模型和单值模型,考虑到OpenTSDB 均为单值映射模型,这里推荐使用单值模型在 TDengine 中进行建模。
+
+- **单值模型**。
+
+具体步骤如下:将度量(metrics)的名称作为 TDengine 超级表的名称,该超级表建成后具有两个基础的数据列—时间戳(timestamp)和值(value),超级表的标签等效于 度量 的标签信息,标签数量等同于度量 的标签的数量。子表的表名采用具有固定规则的方式进行命名:`metric + '_' + tags1_value + '_' + tag2_value + '_' + tag3_value ... `作为子表名称。
+
+在TDengine中建立3个超级表:
+
+```sql
+create stable memory(ts timestamp, val float) tags(host binary(12),memory_type binary(20), memory_type_instance binary(20), source binary(20));
+create stable swap(ts timestamp, val double) tags(host binary(12), swap_type binary(20), swap_type_binary binary(20), source binary(20));
+create stable disk(ts timestamp, val double) tags(host binary(12), disk_point binary(20), disk_instance binary(20), disk_type binary(20), source binary(20));
+```
+
+
+
+对于子表使用动态建表的方式创建如下所示:
+
+```sql
+insert into memory_vm130_memory_bufferred_collectd using memory tags(‘vm130’, ‘memory’, 'buffer', 'collectd') values(1632979445, 3.0656);
+```
+
+最终系统中会建立 340 个左右的子表,3个超级表。需要注意的是,如果采用串联标签值的方式导致子表名称超过系统限制(191字节),那么需要采用一定的编码方式(例如 MD5)将其转化为可接受长度。
+
+- **多值模型**
+
+如果你想要利用 TDengine 的多值模型能力,需要首先满足以下要求:不同的采集量具有相同的采集频率,且能够通过消息队列**同时到达**数据写入端,从而确保使用SQL语句将多个指标一次性写入。将度量的名称作为超级表的名称,建立具有相同采集频率且能够同时到达的数据多列模型。子表的表名采用具有固定规则的方式进行命名。上述每个度量均只包含一个测量值,因此无法将其转化为多值模型。
+
+
+
+## 数据分流与应用适配
+
+从消息队列中订阅数据,并启动调整后的写入程序写入数据。
+
+数据开始写入持续一段时间后,可以采用SQL语句检查写入的数据量是否符合预计的写入要求。统计数据量使用如下SQL语句:
+
+```sql
+select count(*) from memory
+```
+
+完成查询后,如果写入的数据与预期的相比没有差别,同时写入程序本身没有异常的报错信息,那么可用确认数据写入是完整有效的。
+
+TDengine不支持采用OpenTSDB的查询语法进行查询或数据获取处理,但是针对OpenTSDB的每种查询都提供对应的支持。你可以用检查附件2获取对应的查询处理的调整和应用使用的方式,如果需要全面了解TDengine支持的查询类型,请参阅TDengine的用户手册。
+
+TDengine支持标准的JDBC 3.0接口操纵数据库,你也可以使用其他类型的高级语言的连接器来查询读取数据,以适配你的应用。具体的操作和使用帮助也请参阅用户手册。
+
+## 历史数据迁移
+
+### 1、使用工具自动迁移数据
+
+为了方便历史数据的迁移工作,我们为数据同步工具DataX提供了插件,能够将数据自动写入到TDengine中,需要注意的是DataX的自动化数据迁移只能够支持单值模型的数据迁移过程。
+
+DataX 具体的使用方式及如何使用DataX将数据写入TDengine请参见其使用帮助手册 [github.com/taosdata/datax](http://github.com/taosdata/datax)。
+
+### 2、手动迁移数据
+
+如果你需要使用多值模型进行数据写入,就需要自行开发一个将数据从OpenTSDB导出的工具,然后确认哪些时间线能够合并导入到同一个时间线,再将可以同时导入的时间通过SQL语句的写入到数据库中。
+
+手动迁移数据需要注意以下两个问题:
+
+1)在磁盘中存储导出数据时,磁盘需要有足够的存储空间以便能够充分容纳导出的数据文件。为了避免全量数据导出后导致磁盘文件存储紧张,可以采用部分导入的模式,对于归属于同一个超级表的时间线优先导出,然后将导出部分的数据文件导入到TDengine系统中。
+
+2)在系统全负载运行下,如果有足够的剩余计算和IO资源,可以建立多线程的导入机制,最大限度地提升数据迁移的效率。考虑到数据解析对于CPU带来的巨大负载,需要控制最大的并行任务数量,以避免因导入历史数据而触发的系统整体过载。
+
+由于TDegnine本身操作简易性,所以不需要在整个过程中进行索引维护、数据格式的变化处理等工作,整个过程只需要顺序执行即可。
+
+当历史数据完全导入到TDengine以后,此时两个系统处于同时运行的状态,之后便可以将查询请求切换到TDengine上,从而实现无缝的应用切换。
+
+## 附录1: OpenTSDB查询函数对应表
+
+**Avg**
+
+等效函数:avg
+
+示例:
+
+SELECT avg(val) FROM (SELECT first(val) FROM super_table WHERE ts >= startTime and ts <= endTime INTERVAL(20s) Fill(linear)) INTERVAL(20s)
+
+备注:
+
+1. Interval内的数值与外层查询的 interval 数值需要相同。
+2. 在TDengine中插值处理需要使用子查询来协助完成,如上所示,在内层查询中指明插值类型即可,由于 OpenTSDB 中数值的插值使用了线性插值,因此在插值子句中使用fill(linear) 来声明插值类型。以下有相同插值计算需求的函数,均采用该方法处理。
+3. Interval中参数20s表示将内层查询按照20秒一个时间窗口生成结果。在真实的查询中,需要调整为不同的记录之间的时间间隔。这样可确保等效于原始数据生成了插值结果。
+4. 由于 OpenTSDB 特殊的插值策略和机制,聚合查询(Aggregate)中先插值再计算的方式导致其计算结果与 TDengine 不可能完全一致。但是在降采样(Downsample)的情况下,TDengine 和 OpenTSDB 能够获得一致的结果(由于 OpenTSDB 在聚合查询和降采样查询中采用了完全不同的插值策略)。
+
+
+
+**Count**
+
+等效函数:count
+
+示例:
+
+select count(*) from super_table_name;
+
+
+
+**Dev**
+
+等效函数:stddev
+
+示例:
+
+Select stddev(val) from table_name
+
+
+
+**Estimated percentiles**
+
+等效函数:apercentile
+
+示例:
+
+Select apercentile(col1, 50, “t-digest”) from table_name
+
+备注:
+
+1. 近似查询处理过程中,OpenTSDB默认采用t-digest算法,所以为了获得相同的计算结果,需要在apercentile函数中指明使用的算法。TDengine能够支持两种不同的近似处理算法,分别通过”default”和”t-digest”来声明。
+
+
+
+**First**
+
+等效函数:first
+
+示例:
+
+Select first(col1) from table_name
+
+
+
+**Last**
+
+等效函数:last
+
+示例:
+
+Select last(col1) from table_name
+
+
+
+**Max**
+
+等效函数:max
+
+示例:
+
+Select max(value) from (select first(val) value from table_name interval(10s) fill(linear)) interval(10s)
+
+备注:Max函数需要插值,原因见上。
+
+
+
+**Min**
+
+等效函数:min
+
+示例:
+
+Select min(value) from (select first(val) value from table_name interval(10s) fill(linear)) interval(10s);
+
+
+
+**MinMax**
+
+等效函数:max
+
+Select max(val) from table_name
+
+备注:该函数无插值需求,因此可用直接计算。
+
+
+
+**MimMin**
+
+等效函数:min
+
+Select min(val) from table_name
+
+备注:该函数无插值需求,因此可用直接计算。
+
+
+
+**Percentile**
+
+等效函数:percentile
+
+备注:
+
+
+
+**Sum**
+
+等效函数:sum
+
+Select max(value) from (select first(val) value from table_name interval(10s) fill(linear)) interval(10s)
+
+备注:该函数无插值需求,因此可用直接计算。
+
+
+
+**Zimsum**
+
+等效函数:sum
+
+Select sum(val) from table_name
+
+备注:该函数无插值需求,因此可用直接计算。
+
+
+
+完整示例:
+
+```json
+//OpenTSDB查询Json
+query = {
+“start”:1510560000,
+“end”: 1515000009,
+“queries”:[{
+“aggregator”: “count”,
+“metric”:”cpu.usage_user”,
+}]
+}
+
+//等效查询SQL:
+SELECT count(*)
+FROM `cpu.usage_user`
+WHERE ts>=1510560000 AND ts<=1515000009
+```
+
+
+
+## 附录2: 资源估算方法
+
+### 数据生成环境
+
+我们仍然使用第 4 章中的假设环境,3个测量值。分别是:温度和湿度的数据写入的速率是每 5 秒一条记录,时间线 10万个。空气质量的写入速率是10 秒一条记录,时间线1万个,查询的请求频率 500 QPS。
+
+### 存储资源估算
+
+假设产生数据并需要存储的传感器设备数量为 `n`,数据生成的频率为` t `条/秒,每条记录的长度为 `L` bytes,则每天产生的数据规模为 `n×t×L` bytes。假设压缩比为 C,则每日产生数据规模为 `(n×t×L)/C` bytes。存储资源预估为能够容纳1.5年的数据规模,生产环境下 TDengine 的压缩比 C 一般在 5 ~ 7 之间,同时为最后结果增加 20% 的冗余,可计算得到需要存储资源:
+
+```matlab
+(n×t×L)×(365×1.5)×(1+20%)/C
+```
+
+结合以上的计算公式,将参数带入计算公式,在不考虑标签信息的情况下,每年产生的原始数据规模是11.8TB。需要注意的是,由于标签信息在TDengine中关联到每个时间线,并不是每条记录。所以需要记录的数据量规模相对于产生的数据有一定的降低,而这部分标签数据整体上可以忽略不记。假设压缩比为5,则保留的数据规模最终为 2.56 TB。
+
+### 存储设备选型考虑
+
+硬盘应该选用具有较好随机读性能的硬盘设备,如果能够有SSD,尽可能考虑使用SSD。较好的随机读性能的磁盘对于提升系统查询性能具有极大的帮助,能够整体上提升系统的查询响应性能。为了获得较好的查询性能,硬盘设备的单线程随机读IOPS的性能指标不应该低于1000,能够达到5000 IOPS以上为佳。为了获得当前的设备随机读取的IO性能的评估,建议使用fio软件对其进行运行性能评估(具体的使用方式请参阅附录1),确认其是否能够满足大文件随机读性能要求。
+
+硬盘写性能对于TDengine的影响不大。TDengine写入过程采用了追加写的模式,所以只要有较好的顺序写性能即可,一般意义上的SAS硬盘和SSD均能够很好地满足TDengine对于磁盘写入性能的要求。
+
+### 计算资源估算
+
+由于物联网数据的特殊性,数据产生的频率固定以后,TDengine写入的过程对于(计算和存储)资源消耗都保持一个相对固定的量。《[TDengine的运营与维护](https://www.taosdata.com/cn/documentation/administrator)》上的描述,该系统中每秒 22000个写入,消耗CPU不到 1个核。
+
+在针对查询所需要消耗的CPU资源的估算上,假设应用要求数据库提供的QPS为 10000,每次查询消耗的CPU时间约 1 ms,那么每个核每秒提供的查询为 1000 QPS,满足10000 QPS的查询请求,至少需要10个核。为了让系统整体上CPU负载小于 50%,整个集群需要10个核的两倍,即 20 个核。
+
+### 内存资源估算
+
+数据库默认为每个Vnode分配内存 16MB*3缓冲区,集群系统包括22个CPU核,则默认会建立22个虚拟节点Vnode,每个Vnode包含1000张表,则可以容纳所有的表。则约1个半小时写满一个block,从而触发落盘,可以不做调整。22个Vnode共计需要内存缓存约 1GB。考虑到查询所需要的内存,假设每次查询的内存开销约50MB,则500个查询并发需要的内存约25GB。
+
+综上所述,可使用单台16核32GB的机器,或者使用2台 8核 16GB机器构成的集群。
+
+## 附录3: 集群部署及启动
+
+TDengine提供了丰富的帮助文档说明集群安装、部署的诸多方面的内容,这里提供响应的文档索引,供你参考。
+
+### 集群部署
+
+首先是安装 TDengine,从官网上下载 TDengine 最新稳定版,解压缩后运行 install.sh 进行安装。各种安装包的使用帮助请参见博客[《 TDengine多种安装包的安装和卸载》](https://www.taosdata.com/blog/2019/08/09/566.html)。
+
+注意安装完成以后,不要立即启动taosd服务,在正确配置完成参数以后才启动taosd服务。
+
+### 设置运行参数并启动服务
+
+为确保系统能够正常获取运行的必要信息。请在服务端正确设置以下关键参数:
+
+FQDN、firstEp、secondEP、dataDir、logDir、tmpDir、serverPort。各参数的具体含义及设置的要求,可参见文档《[TDengine 集群安装、管理](https://www.taosdata.com/cn/documentation/cluster)》
+
+按照相同的步骤,在需要运行的节点上设置参数,并启动taosd服务,然后添加Dnode到集群中。
+
+最后启动taos,执行命令 show dnodes,如果能看到所有的加入集群的节点,那么集群顺利搭建完成。具体的操作流程及注意事项,请参阅文档《[TDengine 集群安装、管理](https://www.taosdata.com/cn/documentation/cluster)》
+
+## 附录4: 超级表名称
+
+由于OpenTSDB的metric名称中带有点号(“.“),例如”cpu.usage_user”这种名称的metric。但是点号在TDengine中具有特殊含义,是用来分隔数据库和表名称的分隔符。TDengine也提供转义符,以允许用户在(超级)表名称中使用关键词或特殊分隔符(如:点号)。为了使用特殊字符,需要采用转义字符将表的名称括起来,例如:`cpu.usage_user`这样就是合法的(超级)表名称。
+
+## 附录5:参考文章
+
+1. [使用 TDengine + collectd/StatsD + Grafana 快速搭建 IT 运维监控系统](https://www.taosdata.com/cn/documentation20/devops/collectd)
+2. [通过 collectd 将采集数据直接写入TDengine](https://www.taosdata.com/cn/documentation20/insert#collectd)
diff --git a/documentation20/cn/images/IT-DevOps-Solutions-Immigrate-OpenTSDB-Arch.jpg b/documentation20/cn/images/IT-DevOps-Solutions-Immigrate-OpenTSDB-Arch.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..d3de5fb7a10a1cb22693468029bc26ad63a96d71
Binary files /dev/null and b/documentation20/cn/images/IT-DevOps-Solutions-Immigrate-OpenTSDB-Arch.jpg differ
diff --git a/documentation20/cn/images/IT-DevOps-Solutions-Immigrate-OpenTSDB-Dashboard.jpg b/documentation20/cn/images/IT-DevOps-Solutions-Immigrate-OpenTSDB-Dashboard.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..be3704cb72d6c2614614852bfef17147ce49d061
Binary files /dev/null and b/documentation20/cn/images/IT-DevOps-Solutions-Immigrate-OpenTSDB-Dashboard.jpg differ
diff --git a/documentation20/cn/images/IT-DevOps-Solutions-Immigrate-TDengine-Arch.jpg b/documentation20/cn/images/IT-DevOps-Solutions-Immigrate-TDengine-Arch.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..fd406a140beea43fbfe2c417c85b872cfd6a2219
Binary files /dev/null and b/documentation20/cn/images/IT-DevOps-Solutions-Immigrate-TDengine-Arch.jpg differ
diff --git a/importSampleData/app/main.go b/importSampleData/app/main.go
index e45e33e159f8636f8bdc5156b3b9b0947453bab4..3589c8c2a98f31e78c4dac3496f804605a0b2314 100644
--- a/importSampleData/app/main.go
+++ b/importSampleData/app/main.go
@@ -628,7 +628,7 @@ func insertData(threadIndex, start, end int, wg *sync.WaitGroup, successRows []i
buffer.WriteString(",")
for _, field := range subTableInfo.config.Fields {
- buffer.WriteString(getFieldValue(currentRow[strings.ToLower(field.Name)]))
+ buffer.WriteString(getFieldValue(currentRow[strings.ToLower(field.Name)],field.Type))
buffer.WriteString(",")
}
@@ -708,7 +708,10 @@ func executeBatchInsert(insertSql string, connection *sql.DB) int64 {
return affected
}
-func getFieldValue(fieldValue interface{}) string {
+func getFieldValue(fieldValue interface{},fieldtype interface{}) string {
+ if fieldtype == "timestamp" || fieldtype == "bigint" {
+ return fmt.Sprintf("%v", fieldValue)
+ }
return fmt.Sprintf("'%v'", fieldValue)
}
diff --git a/importSampleData/config/cfg.toml b/importSampleData/config/cfg.toml
index 52a5d5f3169d21ce17039ead956250a636b37a01..545bab071ad66af2f59447b3449c6606e2ff1078 100644
--- a/importSampleData/config/cfg.toml
+++ b/importSampleData/config/cfg.toml
@@ -18,6 +18,8 @@ tags = [
fields = [
# 字段列表,name 为字段名称,type 为字段类型
+ # 除主键外,其他field如果也要设置为timestamp,可以是type ="timestamp" 类型,此时value可同时支持'2006-01-02 15:04:05.000'和millisecond格式
+ # 也可以是type = "bigint",此时value只支持millisecond格式
{ name = "ts", type = "timestamp" },
{ name = "temperature", type = "int" },
{ name = "humidity", type = "float" },
diff --git a/packaging/cfg/taos.cfg b/packaging/cfg/taos.cfg
index e42212ff0f55420dfa5f23638a69439be795e43a..59f87b0a1f8d3aa192383457a85e1d53b1a3bf54 100644
--- a/packaging/cfg/taos.cfg
+++ b/packaging/cfg/taos.cfg
@@ -299,8 +299,8 @@ keepColumnName 1
# percent of redundant data in tsdb meta will compact meta data,0 means donot compact
# tsdbMetaCompactRatio 0
-# default string type used for storing JSON String, options can be binary/nchar, default is binary
-# defaultJSONStrType binary
+# default string type used for storing JSON String, options can be binary/nchar, default is nchar
+# defaultJSONStrType nchar
# force TCP transmission
# rpcForceTcp 0
diff --git a/packaging/deb/makedeb.sh b/packaging/deb/makedeb.sh
index f753668b3b1a83d15c126ae6b0d94c06e97c80aa..f28d98ba9a6fae4390bfa301760aff9583ba4e40 100755
--- a/packaging/deb/makedeb.sh
+++ b/packaging/deb/makedeb.sh
@@ -45,10 +45,10 @@ mkdir -p ${pkg_dir}${install_home_path}/script
cp ${compile_dir}/../packaging/cfg/taos.cfg ${pkg_dir}${install_home_path}/cfg
if [ -f "${compile_dir}/test/cfg/taosadapter.toml" ]; then
- cp ${compile_dir}/test/cfg/taosadapter.toml ${pkg_dir}${install_home_path}/cfg
+ cp ${compile_dir}/test/cfg/taosadapter.toml ${pkg_dir}${install_home_path}/cfg || :
fi
if [ -f "${compile_dir}/test/cfg/taosadapter.service" ]; then
- cp ${compile_dir}/test/cfg/taosadapter.service ${pkg_dir}${install_home_path}/cfg ||:
+ cp ${compile_dir}/test/cfg/taosadapter.service ${pkg_dir}${install_home_path}/cfg || :
fi
cp ${compile_dir}/../packaging/deb/taosd ${pkg_dir}${install_home_path}/init.d
diff --git a/packaging/release.sh b/packaging/release.sh
index b9fe25ec08e8dcd1170867fa20f4a4fe5a1ef2d1..c82d5704ac5c4d89837f5afe4b1f6e27419279cc 100755
--- a/packaging/release.sh
+++ b/packaging/release.sh
@@ -194,6 +194,7 @@ fi
if [[ "$dbName" == "pro" ]]; then
sed -i "s/taos config/prodb config/g" ${top_dir}/src/util/src/tconfig.c
+ sed -i "s/TDengine/ProDB/g" ${top_dir}/src/dnode/src/dnodeSystem.c
fi
echo "build ${pagMode} package ..."
@@ -213,7 +214,12 @@ else
exit 1
fi
-make -j8 && ${csudo} make install
+if [[ "$allocator" == "jemalloc" ]]; then
+ # jemalloc need compile first, so disable parallel build
+ make V=1 && ${csudo} make install
+else
+ make -j8 && ${csudo} make install
+fi
cd ${curr_dir}
diff --git a/packaging/tools/install.sh b/packaging/tools/install.sh
index 61fcd3e51982dab6a72245fe0ffb9de5ac51a664..dcd4a83da8929d76aa61d848985b5c4ffe46b9c5 100755
--- a/packaging/tools/install.sh
+++ b/packaging/tools/install.sh
@@ -757,8 +757,12 @@ function install_service_on_systemd() {
}
function install_taosadapter_service() {
- [ -f ${script_dir}/cfg/taosadapter.service ] &&\
- ${csudo} cp ${script_dir}/cfg/taosadapter.service ${service_config_dir}/
+ if ((${service_mod}==0)); then
+ [ -f ${script_dir}/cfg/taosadapter.service ] &&\
+ ${csudo} cp ${script_dir}/cfg/taosadapter.service \
+ ${service_config_dir}/ || :
+ ${csudo} systemctl daemon-reload
+ fi
}
function install_service() {
diff --git a/packaging/tools/make_install.sh b/packaging/tools/make_install.sh
index 8309fa516c4ffdcd9e5a17056304427543dad0a9..093b2bb0a7ea8033b7509e231200b8b4ad6901be 100755
--- a/packaging/tools/make_install.sh
+++ b/packaging/tools/make_install.sh
@@ -62,12 +62,14 @@ NC='\033[0m'
csudo=""
+service_mod=2
+os_type=0
+
if [ "$osType" != "Darwin" ]; then
if command -v sudo > /dev/null; then
csudo="sudo"
fi
initd_mod=0
- service_mod=2
if pidof systemd &> /dev/null; then
service_mod=0
elif $(which service &> /dev/null); then
@@ -91,7 +93,6 @@ if [ "$osType" != "Darwin" ]; then
#osinfo=$(awk -F= '/^NAME/{print $2}' /etc/os-release)
osinfo=$(cat /etc/os-release | grep "NAME" | cut -d '"' -f2)
#echo "osinfo: ${osinfo}"
- os_type=0
if echo $osinfo | grep -qwi "ubuntu" ; then
echo "this is ubuntu system"
os_type=1
@@ -122,7 +123,8 @@ function kill_taosadapter() {
}
function kill_taosd() {
- pid=$(ps -ef | grep "taosd" | grep -v "grep" | awk '{print $2}')
+ ps -ef | grep "taosd"
+ pid=$(ps -ef | grep -w "taosd" | grep -v "grep" | awk '{print $2}')
if [ -n "$pid" ]; then
${csudo} kill -9 $pid || :
fi
@@ -202,31 +204,31 @@ function install_jemalloc() {
/usr/bin/install -c -d /usr/local/bin
if [ -f "${binary_dir}/build/bin/jemalloc-config" ]; then
- /usr/bin/install -c -m 755 ${binary_dir}/build/bin/jemalloc-config /usr/local/bin
+ ${csudo} /usr/bin/install -c -m 755 ${binary_dir}/build/bin/jemalloc-config /usr/local/bin
fi
if [ -f "${binary_dir}/build/bin/jemalloc.sh" ]; then
- /usr/bin/install -c -m 755 ${binary_dir}/build/bin/jemalloc.sh /usr/local/bin
+ ${csudo} /usr/bin/install -c -m 755 ${binary_dir}/build/bin/jemalloc.sh /usr/local/bin
fi
if [ -f "${binary_dir}/build/bin/jeprof" ]; then
- /usr/bin/install -c -m 755 ${binary_dir}/build/bin/jeprof /usr/local/bin
+ ${csudo} /usr/bin/install -c -m 755 ${binary_dir}/build/bin/jeprof /usr/local/bin
fi
if [ -f "${binary_dir}/build/include/jemalloc/jemalloc.h" ]; then
- /usr/bin/install -c -d /usr/local/include/jemalloc
- /usr/bin/install -c -m 644 ${binary_dir}/build/include/jemalloc/jemalloc.h\
+ ${csudo} /usr/bin/install -c -d /usr/local/include/jemalloc
+ ${csudo} /usr/bin/install -c -m 644 ${binary_dir}/build/include/jemalloc/jemalloc.h\
/usr/local/include/jemalloc
fi
if [ -f "${binary_dir}/build/lib/libjemalloc.so.2" ]; then
- /usr/bin/install -c -d /usr/local/lib
- /usr/bin/install -c -m 755 ${binary_dir}/build/lib/libjemalloc.so.2 /usr/local/lib
- ln -sf libjemalloc.so.2 /usr/local/lib/libjemalloc.so
- /usr/bin/install -c -d /usr/local/lib
+ ${csudo} /usr/bin/install -c -d /usr/local/lib
+ ${csudo} /usr/bin/install -c -m 755 ${binary_dir}/build/lib/libjemalloc.so.2 /usr/local/lib
+ ${csudo} ln -sf libjemalloc.so.2 /usr/local/lib/libjemalloc.so
+ ${csudo} /usr/bin/install -c -d /usr/local/lib
[ -f ${binary_dir}/build/lib/libjemalloc.a ] &&
- /usr/bin/install -c -m 755 ${binary_dir}/build/lib/libjemalloc.a /usr/local/lib
+ ${csudo} /usr/bin/install -c -m 755 ${binary_dir}/build/lib/libjemalloc.a /usr/local/lib
[ -f ${binary_dir}/build/lib/libjemalloc_pic.a ] &&
- /usr/bin/install -c -m 755 ${binary_dir}/build/lib/libjemalloc_pic.a /usr/local/lib
+ ${csudo} /usr/bin/install -c -m 755 ${binary_dir}/build/lib/libjemalloc_pic.a /usr/local/lib
if [ -f "${binary_dir}/build/lib/pkgconfig/jemalloc.pc" ]; then
- /usr/bin/install -c -d /usr/local/lib/pkgconfig
- /usr/bin/install -c -m 644 ${binary_dir}/build/lib/pkgconfig/jemalloc.pc\
+ ${csudo} /usr/bin/install -c -d /usr/local/lib/pkgconfig
+ ${csudo} /usr/bin/install -c -m 644 ${binary_dir}/build/lib/pkgconfig/jemalloc.pc\
/usr/local/lib/pkgconfig
fi
if [ -d /etc/ld.so.conf.d ]; then
@@ -237,29 +239,28 @@ function install_jemalloc() {
fi
fi
if [ -f "${binary_dir}/build/share/doc/jemalloc/jemalloc.html" ]; then
- /usr/bin/install -c -d /usr/local/share/doc/jemalloc
- /usr/bin/install -c -m 644 ${binary_dir}/build/share/doc/jemalloc/jemalloc.html\
+ ${csudo} /usr/bin/install -c -d /usr/local/share/doc/jemalloc
+ ${csudo} /usr/bin/install -c -m 644 ${binary_dir}/build/share/doc/jemalloc/jemalloc.html\
/usr/local/share/doc/jemalloc
fi
if [ -f "${binary_dir}/build/share/man/man3/jemalloc.3" ]; then
- /usr/bin/install -c -d /usr/local/share/man/man3
- /usr/bin/install -c -m 644 ${binary_dir}/build/share/man/man3/jemalloc.3\
+ ${csudo} /usr/bin/install -c -d /usr/local/share/man/man3
+ ${csudo} /usr/bin/install -c -m 644 ${binary_dir}/build/share/man/man3/jemalloc.3\
/usr/local/share/man/man3
fi
-
fi
}
function install_avro() {
if [ "$osType" != "Darwin" ]; then
if [ -f "${binary_dir}/build/$1/libavro.so.23.0.0" ]; then
- /usr/bin/install -c -d /usr/local/$1
- /usr/bin/install -c -m 755 ${binary_dir}/build/$1/libavro.so.23.0.0 /usr/local/$1
- ln -sf libavro.so.23.0.0 /usr/local/$1/libavro.so.23
- ln -sf libavro.so.23 /usr/local/$1/libavro.so
- /usr/bin/install -c -d /usr/local/$1
+ ${csudo} /usr/bin/install -c -d /usr/local/$1
+ ${csudo} /usr/bin/install -c -m 755 ${binary_dir}/build/$1/libavro.so.23.0.0 /usr/local/$1
+ ${csudo} ln -sf libavro.so.23.0.0 /usr/local/$1/libavro.so.23
+ ${csudo} ln -sf libavro.so.23 /usr/local/$1/libavro.so
+ ${csudo} /usr/bin/install -c -d /usr/local/$1
[ -f ${binary_dir}/build/$1/libavro.a ] &&
- /usr/bin/install -c -m 755 ${binary_dir}/build/$1/libavro.a /usr/local/$1
+ ${csudo} /usr/bin/install -c -m 755 ${binary_dir}/build/$1/libavro.a /usr/local/$1
if [ -d /etc/ld.so.conf.d ]; then
echo "/usr/local/$1" | ${csudo} tee /etc/ld.so.conf.d/libavro.conf
@@ -455,11 +456,11 @@ function install_service_on_sysvinit() {
# Install taosd service
if ((${os_type}==1)); then
- ${csudo} cp -f ${script_dir}/../deb/taosd ${install_main_dir}/init.d
- ${csudo} cp ${script_dir}/../deb/taosd ${service_config_dir} && ${csudo} chmod a+x ${service_config_dir}/taosd
+ ${csudo} cp -f ${script_dir}/../deb/taosd ${install_main_dir}/init.d
+ ${csudo} cp ${script_dir}/../deb/taosd ${service_config_dir} && ${csudo} chmod a+x ${service_config_dir}/taosd
elif ((${os_type}==2)); then
- ${csudo} cp -f ${script_dir}/../rpm/taosd ${install_main_dir}/init.d
- ${csudo} cp ${script_dir}/../rpm/taosd ${service_config_dir} && ${csudo} chmod a+x ${service_config_dir}/taosd
+ ${csudo} cp -f ${script_dir}/../rpm/taosd ${install_main_dir}/init.d
+ ${csudo} cp ${script_dir}/../rpm/taosd ${service_config_dir} && ${csudo} chmod a+x ${service_config_dir}/taosd
fi
#restart_config_str="taos:2345:respawn:${service_config_dir}/taosd start"
@@ -523,9 +524,8 @@ function install_taosadapter_service() {
if ((${service_mod}==0)); then
[ -f ${binary_dir}/test/cfg/taosadapter.service ] &&\
${csudo} cp ${binary_dir}/test/cfg/taosadapter.service\
- ${service_config_dir}/ || :
- else
- kill_taosadapter
+ ${service_config_dir}/ || :
+ ${csudo} systemctl daemon-reload
fi
}
@@ -544,7 +544,6 @@ function update_TDengine() {
echo -e "${GREEN}Start to update TDengine...${NC}"
# Stop the service if running
- if [ "$osType" != "Darwin" ]; then
if pidof taosd &> /dev/null; then
if ((${service_mod}==0)); then
${csudo} systemctl stop taosd || :
@@ -556,7 +555,6 @@ function update_TDengine() {
fi
sleep 1
fi
- fi
install_main_path
@@ -567,50 +565,35 @@ function update_TDengine() {
install_examples
install_bin
- if [ "$osType" != "Darwin" ]; then
- install_service
- install_taosadapter_service
- fi
+ install_service
+ install_taosadapter_service
install_config
install_taosadapter_config
- if [ "$osType" != "Darwin" ]; then
- echo
- echo -e "\033[44;32;1mTDengine is updated successfully!${NC}"
- echo
-
- echo -e "${GREEN_DARK}To configure TDengine ${NC}: edit /etc/taos/taos.cfg"
- echo -e "${GREEN_DARK}To configure taosadapter (if has) ${NC}: edit /etc/taos/taosadapter.toml"
- if ((${service_mod}==0)); then
- echo -e "${GREEN_DARK}To start TDengine ${NC}: ${csudo} systemctl start taosd${NC}"
- elif ((${service_mod}==1)); then
- echo -e "${GREEN_DARK}To start TDengine ${NC}: ${csudo} service taosd start${NC}"
- else
- echo -e "${GREEN_DARK}To start TDengine ${NC}: ./taosd${NC}"
- fi
+ echo
+ echo -e "\033[44;32;1mTDengine is updated successfully!${NC}"
+ echo
- echo -e "${GREEN_DARK}To access TDengine ${NC}: use ${GREEN_UNDERLINE}taos${NC} in shell${NC}"
- echo
- echo -e "\033[44;32;1mTDengine is updated successfully!${NC}"
+ echo -e "${GREEN_DARK}To configure TDengine ${NC}: edit /etc/taos/taos.cfg"
+ echo -e "${GREEN_DARK}To configure Taos Adapter (if has) ${NC}: edit /etc/taos/taosadapter.toml"
+ if ((${service_mod}==0)); then
+ echo -e "${GREEN_DARK}To start TDengine ${NC}: ${csudo} systemctl start taosd${NC}"
+ elif ((${service_mod}==1)); then
+ echo -e "${GREEN_DARK}To start TDengine ${NC}: ${csudo} service taosd start${NC}"
else
- echo
- echo -e "\033[44;32;1mTDengine Client is updated successfully!${NC}"
- echo
-
- echo -e "${GREEN_DARK}To access TDengine Client ${NC}: use ${GREEN_UNDERLINE}taos${NC} in shell${NC}"
- echo
- echo -e "\033[44;32;1mTDengine Client is updated successfully!${NC}"
+ echo -e "${GREEN_DARK}To start Taos Adapter (if has)${NC}: taosadapter &${NC}"
+ echo -e "${GREEN_DARK}To start TDengine ${NC}: taosd${NC}"
fi
+
+ echo -e "${GREEN_DARK}To access TDengine ${NC}: use ${GREEN_UNDERLINE}taos${NC} in shell${NC}"
+ echo
+ echo -e "\033[44;32;1mTDengine is updated successfully!${NC}"
}
function install_TDengine() {
# Start to install
- if [ "$osType" != "Darwin" ]; then
- echo -e "${GREEN}Start to install TDEngine...${NC}"
- else
- echo -e "${GREEN}Start to install TDEngine Client ...${NC}"
- fi
+ echo -e "${GREEN}Start to install TDengine...${NC}"
install_main_path
@@ -622,37 +605,29 @@ function install_TDengine() {
install_examples
install_bin
- if [ "$osType" != "Darwin" ]; then
- install_service
- install_taosadapter_service
- fi
+ install_service
+ install_taosadapter_service
install_config
install_taosadapter_config
- if [ "$osType" != "Darwin" ]; then
- # Ask if to start the service
- echo
- echo -e "\033[44;32;1mTDengine is installed successfully!${NC}"
- echo
- echo -e "${GREEN_DARK}To configure TDengine ${NC}: edit /etc/taos/taos.cfg"
- echo -e "${GREEN_DARK}To configure taosadapter (if has) ${NC}: edit /etc/taos/taosadapter.toml"
- if ((${service_mod}==0)); then
- echo -e "${GREEN_DARK}To start TDengine ${NC}: ${csudo} systemctl start taosd${NC}"
- elif ((${service_mod}==1)); then
- echo -e "${GREEN_DARK}To start TDengine ${NC}: ${csudo} service taosd start${NC}"
- else
- echo -e "${GREEN_DARK}To start TDengine ${NC}: ./taosd${NC}"
- fi
-
- echo -e "${GREEN_DARK}To access TDengine ${NC}: use ${GREEN_UNDERLINE}taos${NC} in shell${NC}"
- echo
- echo -e "\033[44;32;1mTDengine is installed successfully!${NC}"
+ # Ask if to start the service
+ echo
+ echo -e "\033[44;32;1mTDengine is installed successfully!${NC}"
+ echo
+ echo -e "${GREEN_DARK}To configure TDengine ${NC}: edit /etc/taos/taos.cfg"
+ echo -e "${GREEN_DARK}To configure taosadapter (if has) ${NC}: edit /etc/taos/taosadapter.toml"
+ if ((${service_mod}==0)); then
+ echo -e "${GREEN_DARK}To start TDengine ${NC}: ${csudo} systemctl start taosd${NC}"
+ elif ((${service_mod}==1)); then
+ echo -e "${GREEN_DARK}To start TDengine ${NC}: ${csudo} service taosd start${NC}"
else
- echo -e "${GREEN_DARK}To access TDengine ${NC}: use ${GREEN_UNDERLINE}taos${NC} in shell${NC}"
- echo
- echo -e "\033[44;32;1mTDengine Client is installed successfully!${NC}"
+ echo -e "${GREEN_DARK}To start TDengine ${NC}: ./taosd${NC}"
fi
+
+ echo -e "${GREEN_DARK}To access TDengine ${NC}: use ${GREEN_UNDERLINE}taos${NC} in shell${NC}"
+ echo
+ echo -e "\033[44;32;1mTDengine is installed successfully!${NC}"
}
## ==============================Main program starts from here============================
diff --git a/packaging/tools/makepkg.sh b/packaging/tools/makepkg.sh
index 05b49ff6a9599c6050d2ccad778f63d285981420..7ad703be86016bd0c0ce55c80b76bf34914c54bb 100755
--- a/packaging/tools/makepkg.sh
+++ b/packaging/tools/makepkg.sh
@@ -78,7 +78,13 @@ mkdir -p ${install_dir}
mkdir -p ${install_dir}/inc && cp ${header_files} ${install_dir}/inc
mkdir -p ${install_dir}/cfg && cp ${cfg_dir}/taos.cfg ${install_dir}/cfg/taos.cfg
-[ -f ${cfg_dir}/taosadapter.toml ] && cp ${cfg_dir}/taosadapter.toml ${install_dir}/cfg/taosadapter.toml
+if [ -f "${compile_dir}/test/cfg/taosadapter.toml" ]; then
+ cp ${compile_dir}/test/cfg/taosadapter.toml ${install_dir}/cfg || :
+fi
+
+if [ -f "${compile_dir}/test/cfg/taosadapter.service" ]; then
+ cp ${compile_dir}/test/cfg/taosadapter.service ${install_dir}/cfg || :
+fi
mkdir -p ${install_dir}/bin && cp ${bin_files} ${install_dir}/bin && chmod a+x ${install_dir}/bin/* || :
mkdir -p ${install_dir}/init.d && cp ${init_file_deb} ${install_dir}/init.d/taosd.deb
diff --git a/packaging/tools/post.sh b/packaging/tools/post.sh
index c3db7e417adb11b92d55464b69c715e3aee2d6bb..2f4b07067fd08ee3a9591f97e7291305307ff498 100755
--- a/packaging/tools/post.sh
+++ b/packaging/tools/post.sh
@@ -467,7 +467,12 @@ function install_service_on_systemd() {
}
function install_taosadapter_service() {
- [ -f ${cfg_dir}/taosadapter.service ] && ${csudo} cp ${cfg_dir}/taosadapter.service ${service_config_dir}
+ if ((${service_mod}==0)); then
+ [ -f ${script_dir}/cfg/taosadapter.service ] &&\
+ ${csudo} cp ${script_dir}/cfg/taosadapter.service \
+ ${service_config_dir}/ || :
+ ${csudo} systemctl daemon-reload
+ fi
}
function install_service() {
diff --git a/snap/snapcraft.yaml b/snap/snapcraft.yaml
index 64e3af498cedd25dea90055426110522bc4a4086..66ec851dc945d4897ef40d6a361468dd1d16a5a2 100644
--- a/snap/snapcraft.yaml
+++ b/snap/snapcraft.yaml
@@ -1,6 +1,6 @@
name: tdengine
base: core20
-version: '2.3.1.0'
+version: '2.3.2.0'
icon: snap/gui/t-dengine.svg
summary: an open-source big data platform designed and optimized for IoT.
description: |
diff --git a/src/client/inc/tscUtil.h b/src/client/inc/tscUtil.h
index 04ee1b7953946565007e8a30f43fa4a600e63b19..b183598fcceff926cfba235e42d8634546b36a48 100644
--- a/src/client/inc/tscUtil.h
+++ b/src/client/inc/tscUtil.h
@@ -83,6 +83,11 @@ typedef struct SJoinSupporter {
int32_t totalLen;
int32_t num;
SArray* pVgroupTables;
+
+ int16_t fillType; // final result fill type
+ int64_t * fillVal; // default value for fill
+ int32_t numOfFillVal; // fill value size
+
} SJoinSupporter;
@@ -119,7 +124,8 @@ typedef struct SBlockKeyInfo {
int32_t converToStr(char *str, int type, void *buf, int32_t bufSize, int32_t *len);
int32_t tscCreateDataBlock(size_t initialSize, int32_t rowSize, int32_t startOffset, SName* name, STableMeta* pTableMeta, STableDataBlocks** dataBlocks);
-void tscDestroyDataBlock(SSqlObj *pSql, STableDataBlocks* pDataBlock, bool removeMeta);
+int32_t tscCreateDataBlockData(STableDataBlocks* dataBuf, size_t defaultSize, int32_t rowSize, int32_t startOffset);
+void tscDestroyDataBlock(SSqlObj *pSql, STableDataBlocks* pDataBlock, bool removeMeta);
void tscSortRemoveDataBlockDupRowsRaw(STableDataBlocks* dataBuf);
int tscSortRemoveDataBlockDupRows(STableDataBlocks* dataBuf, SBlockKeyInfo* pBlkKeyInfo);
int32_t tsSetBlockInfo(SSubmitBlk *pBlocks, const STableMeta *pTableMeta, int32_t numOfRows);
@@ -147,6 +153,7 @@ int32_t tscGetDataBlockFromList(SHashObj* pHashList, int64_t id, int32_t size, i
* @return
*/
bool tscIsPointInterpQuery(SQueryInfo* pQueryInfo);
+bool tscGetPointInterpQuery(SQueryInfo* pQueryInfo);
bool tscIsTWAQuery(SQueryInfo* pQueryInfo);
bool tscIsIrateQuery(SQueryInfo* pQueryInfo);
bool tscQueryContainsFunction(SQueryInfo* pQueryInfo, int16_t functionId);
diff --git a/src/client/src/tscAsync.c b/src/client/src/tscAsync.c
index 08e08cc6599efd0a2f0fe6de0ef52b1fbdfb6d88..2ddae0f903a6c42235343a6dd526d37e53147734 100644
--- a/src/client/src/tscAsync.c
+++ b/src/client/src/tscAsync.c
@@ -237,7 +237,7 @@ void taos_fetch_rows_a(TAOS_RES *tres, __async_cb_func_t fp, void *param) {
return;
}
- if (pRes->qId == 0) {
+ if (pRes->qId == 0 && pSql->cmd.command != TSDB_SQL_RETRIEVE_EMPTY_RESULT) {
tscError("qhandle is invalid");
pRes->code = TSDB_CODE_TSC_INVALID_QHANDLE;
tscAsyncResultOnError(pSql);
diff --git a/src/client/src/tscGlobalmerge.c b/src/client/src/tscGlobalmerge.c
index 0b660c592c84eb4605a1fb76afd3b180fc5daa07..a6edac0659c9a8f1670b05bd0d53d2ad6ca84e7c 100644
--- a/src/client/src/tscGlobalmerge.c
+++ b/src/client/src/tscGlobalmerge.c
@@ -968,7 +968,6 @@ SSDataBlock* doGlobalAggregate(void* param, bool* newgroup) {
if (pOperator->pRuntimeEnv->pQueryAttr->order.order == TSDB_ORDER_DESC) {
SWAP(w->skey, w->ekey, TSKEY);
- assert(w->skey <= w->ekey);
}
}
}
diff --git a/src/client/src/tscParseInsert.c b/src/client/src/tscParseInsert.c
index d7ceee630217acc72f8cebc464b3e38aaf440a4e..94f9a3018aae175f0f27c1c24b735f5a0392102d 100644
--- a/src/client/src/tscParseInsert.c
+++ b/src/client/src/tscParseInsert.c
@@ -314,8 +314,6 @@ int32_t tsParseOneColumn(SSchema *pSchema, SStrToken *pToken, char *payload, cha
ret = tStrToInteger(pToken->z, pToken->type, pToken->n, &iv, false);
if (ret != TSDB_CODE_SUCCESS) {
return tscInvalidOperationMsg(msg, "invalid unsigned bigint data", pToken->z);
- } else if (!IS_VALID_UBIGINT((uint64_t)iv)) {
- return tscInvalidOperationMsg(msg, "unsigned bigint data overflow", pToken->z);
}
*((uint64_t *)payload) = iv;
@@ -1419,6 +1417,11 @@ int tsParseInsertSql(SSqlObj *pSql) {
goto _clean;
}
+ if (sToken.type == TK_ILLEGAL) { // ,,,, like => insert into t values(now,1),,,,(now+1s,2);
+ code = tscSQLSyntaxErrMsg(pInsertParam->msg, NULL, str);
+ goto _clean;
+ }
+
/*
* if no data has been generated during parsing the sql string, error msg will return
* Otherwise, create the first submit block and submit to virtual node.
diff --git a/src/client/src/tscParseOpenTSDB.c b/src/client/src/tscParseOpenTSDB.c
index e78abf0596447df0ee58db88ca87b19011293c6c..98a836810a9a2501761dfce38b48be1498267561 100644
--- a/src/client/src/tscParseOpenTSDB.c
+++ b/src/client/src/tscParseOpenTSDB.c
@@ -195,8 +195,9 @@ static int32_t parseTelnetMetricValue(TAOS_SML_KV **pKVs, int *num_kvs, const ch
}
tfree(value);
- pVal->key = tcalloc(sizeof(key), 1);
+ pVal->key = tcalloc(sizeof(key) + TS_ESCAPE_CHAR_SIZE, 1);
memcpy(pVal->key, key, sizeof(key));
+ addEscapeCharToString(pVal->key, (int32_t)strlen(pVal->key));
*num_kvs += 1;
*index = cur + 1;
@@ -881,8 +882,9 @@ static int32_t parseMetricValueFromJSON(cJSON *root, TAOS_SML_KV **pKVs, int *nu
return ret;
}
- pVal->key = tcalloc(sizeof(key), 1);
+ pVal->key = tcalloc(sizeof(key) + TS_ESCAPE_CHAR_SIZE, 1);
memcpy(pVal->key, key, sizeof(key));
+ addEscapeCharToString(pVal->key, (int32_t)strlen(pVal->key));
*num_kvs += 1;
return TSDB_CODE_SUCCESS;
diff --git a/src/client/src/tscPrepare.c b/src/client/src/tscPrepare.c
index 04dd7f57cabe8f01ade992cfe1d4a3122a26d130..66286476024d465e2c08bf83f06195640c5315d3 100644
--- a/src/client/src/tscPrepare.c
+++ b/src/client/src/tscPrepare.c
@@ -48,12 +48,14 @@ typedef struct SMultiTbStmt {
bool nameSet;
bool tagSet;
bool subSet;
+ bool tagColSet;
uint64_t currentUid;
char *sqlstr;
uint32_t tbNum;
SStrToken tbname;
SStrToken stbname;
SStrToken values;
+ SStrToken tagCols;
SArray *tags;
STableDataBlocks *lastBlock;
SHashObj *pTableHash;
@@ -1250,6 +1252,12 @@ static void insertBatchClean(STscStmt* pStmt) {
pCmd->insertParam.pDataBlocks = tscDestroyBlockArrayList(pSql, pCmd->insertParam.pDataBlocks);
pCmd->insertParam.numOfTables = 0;
+ STableDataBlocks** p = taosHashIterate(pCmd->insertParam.pTableBlockHashList, NULL);
+ while(p) {
+ tfree((*p)->pData);
+ p = taosHashIterate(pCmd->insertParam.pTableBlockHashList, p);
+ }
+
taosHashClear(pCmd->insertParam.pTableBlockHashList);
tscFreeSqlResult(pSql);
tscFreeSubobj(pSql);
@@ -1343,9 +1351,40 @@ int stmtParseInsertTbTags(SSqlObj* pSql, STscStmt* pStmt) {
pStmt->mtb.stbname = sToken;
sToken = tStrGetToken(pCmd->insertParam.sql, &index, false);
- if (sToken.n <= 0 || sToken.type != TK_TAGS) {
- tscError("keyword TAGS expected, sql:%s", pCmd->insertParam.sql);
- return tscSQLSyntaxErrMsg(pCmd->payload, "keyword TAGS expected", sToken.z ? sToken.z : pCmd->insertParam.sql);
+ if (sToken.n <= 0 || ((sToken.type != TK_TAGS) && (sToken.type != TK_LP))) {
+ tscError("invalid token, sql:%s", pCmd->insertParam.sql);
+ return tscSQLSyntaxErrMsg(pCmd->payload, "invalid token", sToken.z ? sToken.z : pCmd->insertParam.sql);
+ }
+
+ // ... (tag_col_list) TAGS(tag_val_list) ...
+ int32_t tagColsCnt = 0;
+ if (sToken.type == TK_LP) {
+ pStmt->mtb.tagColSet = true;
+ pStmt->mtb.tagCols = sToken;
+ int32_t tagColsStart = index;
+ while (1) {
+ sToken = tStrGetToken(pCmd->insertParam.sql, &index, false);
+ if (sToken.type == TK_ILLEGAL) {
+ return tscSQLSyntaxErrMsg(pCmd->payload, "unrecognized token", sToken.z);
+ }
+ if (sToken.type == TK_ID) {
+ ++tagColsCnt;
+ }
+ if (sToken.type == TK_RP) {
+ break;
+ }
+ }
+ if (tagColsCnt == 0) {
+ tscError("tag column list expected, sql:%s", pCmd->insertParam.sql);
+ return tscSQLSyntaxErrMsg(pCmd->payload, "tag column list expected", pCmd->insertParam.sql);
+ }
+ pStmt->mtb.tagCols.n = index - tagColsStart + 1;
+
+ sToken = tStrGetToken(pCmd->insertParam.sql, &index, false);
+ if (sToken.n <= 0 || sToken.type != TK_TAGS) {
+ tscError("keyword TAGS expected, sql:%s", pCmd->insertParam.sql);
+ return tscSQLSyntaxErrMsg(pCmd->payload, "keyword TAGS expected", sToken.z ? sToken.z : pCmd->insertParam.sql);
+ }
}
sToken = tStrGetToken(pCmd->insertParam.sql, &index, false);
@@ -1385,6 +1424,11 @@ int stmtParseInsertTbTags(SSqlObj* pSql, STscStmt* pStmt) {
return tscSQLSyntaxErrMsg(pCmd->payload, "no tags", pCmd->insertParam.sql);
}
+ if (tagColsCnt > 0 && taosArrayGetSize(pStmt->mtb.tags) != tagColsCnt) {
+ tscError("not match tags, sql:%s", pCmd->insertParam.sql);
+ return tscSQLSyntaxErrMsg(pCmd->payload, "not match tags", pCmd->insertParam.sql);
+ }
+
sToken = tStrGetToken(pCmd->insertParam.sql, &index, false);
if (sToken.n <= 0 || (sToken.type != TK_VALUES && sToken.type != TK_LP)) {
tscError("sql error, sql:%s", pCmd->insertParam.sql);
@@ -1407,7 +1451,13 @@ int stmtGenInsertStatement(SSqlObj* pSql, STscStmt* pStmt, const char* name, TAO
int32_t j = 0;
while (1) {
- len = (size_t)snprintf(str, size - 1, "insert into %s using %.*s tags(", name, pStmt->mtb.stbname.n, pStmt->mtb.stbname.z);
+ if (pStmt->mtb.tagColSet) {
+ len = (size_t)snprintf(str, size - 1, "insert into %s using %.*s %.*s tags(",
+ name, pStmt->mtb.stbname.n, pStmt->mtb.stbname.z, pStmt->mtb.tagCols.n, pStmt->mtb.tagCols.z);
+ } else {
+ len = (size_t)snprintf(str, size - 1, "insert into %s using %.*s tags(", name, pStmt->mtb.stbname.n, pStmt->mtb.stbname.z);
+ }
+
if (len >= (size -1)) {
size *= 2;
free(str);
@@ -1659,6 +1709,13 @@ int taos_stmt_set_tbname_tags(TAOS_STMT* stmt, const char* name, TAOS_BIND* tags
STMT_RET(TSDB_CODE_TSC_APP_ERROR);
}
+ if ((*t1)->pData == NULL) {
+ code = tscCreateDataBlockData(*t1, TSDB_PAYLOAD_SIZE, (*t1)->pTableMeta->tableInfo.rowSize, sizeof(SSubmitBlk));
+ if (code != TSDB_CODE_SUCCESS) {
+ STMT_RET(code);
+ }
+ }
+
SSubmitBlk* pBlk = (SSubmitBlk*) (*t1)->pData;
pCmd->batchSize = pBlk->numOfRows;
if (pBlk->numOfRows == 0) {
@@ -1784,7 +1841,6 @@ int taos_stmt_set_tbname_tags(TAOS_STMT* stmt, const char* name, TAOS_BIND* tags
STMT_RET(code);
}
-
int taos_stmt_set_sub_tbname(TAOS_STMT* stmt, const char* name) {
STscStmt* pStmt = (STscStmt*)stmt;
STMT_CHECK
@@ -1792,8 +1848,6 @@ int taos_stmt_set_sub_tbname(TAOS_STMT* stmt, const char* name) {
return taos_stmt_set_tbname_tags(stmt, name, NULL);
}
-
-
int taos_stmt_set_tbname(TAOS_STMT* stmt, const char* name) {
STscStmt* pStmt = (STscStmt*)stmt;
STMT_CHECK
@@ -1801,7 +1855,6 @@ int taos_stmt_set_tbname(TAOS_STMT* stmt, const char* name) {
return taos_stmt_set_tbname_tags(stmt, name, NULL);
}
-
int taos_stmt_close(TAOS_STMT* stmt) {
STscStmt* pStmt = (STscStmt*)stmt;
if (pStmt == NULL || pStmt->taos == NULL) {
@@ -1868,7 +1921,6 @@ int taos_stmt_bind_param(TAOS_STMT* stmt, TAOS_BIND* bind) {
}
}
-
int taos_stmt_bind_param_batch(TAOS_STMT* stmt, TAOS_MULTI_BIND* bind) {
STscStmt* pStmt = (STscStmt*)stmt;
@@ -1932,8 +1984,6 @@ int taos_stmt_bind_single_param_batch(TAOS_STMT* stmt, TAOS_MULTI_BIND* bind, in
STMT_RET(insertStmtBindParamBatch(pStmt, bind, colIdx));
}
-
-
int taos_stmt_add_batch(TAOS_STMT* stmt) {
STscStmt* pStmt = (STscStmt*)stmt;
STMT_CHECK
@@ -2086,7 +2136,6 @@ int taos_stmt_get_param(TAOS_STMT *stmt, int idx, int *type, int *bytes) {
}
}
-
char *taos_stmt_errstr(TAOS_STMT *stmt) {
STscStmt* pStmt = (STscStmt*)stmt;
@@ -2097,8 +2146,6 @@ char *taos_stmt_errstr(TAOS_STMT *stmt) {
return taos_errstr(pStmt->pSql);
}
-
-
const char *taos_data_type(int type) {
switch (type) {
case TSDB_DATA_TYPE_NULL: return "TSDB_DATA_TYPE_NULL";
@@ -2115,4 +2162,3 @@ const char *taos_data_type(int type) {
default: return "UNKNOWN";
}
}
-
diff --git a/src/client/src/tscSQLParser.c b/src/client/src/tscSQLParser.c
index b82bf7bbd520d0649390715952515bdc1f418eae..b2316bf39e950417ee978d3bf3d106084dc320a4 100644
--- a/src/client/src/tscSQLParser.c
+++ b/src/client/src/tscSQLParser.c
@@ -101,6 +101,7 @@ static int32_t addProjectionExprAndResultField(SSqlCmd* pCmd, SQueryInfo* pQuery
static int32_t validateWhereNode(SQueryInfo* pQueryInfo, tSqlExpr** pExpr, SSqlObj* pSql);
static int32_t validateFillNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode* pSqlNode);
+static int32_t validateRangeNode(SSqlObj* pSql, SQueryInfo* pQueryInfo, SSqlNode* pSqlNode);
static int32_t validateOrderbyNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode* pSqlNode, SSchema* pSchema);
static int32_t tsRewriteFieldNameIfNecessary(SSqlCmd* pCmd, SQueryInfo* pQueryInfo);
@@ -116,7 +117,6 @@ static int32_t setKillInfo(SSqlObj* pSql, struct SSqlInfo* pInfo, int32_t killTy
static int32_t setCompactVnodeInfo(SSqlObj* pSql, struct SSqlInfo* pInfo);
static int32_t validateOneTag(SSqlCmd* pCmd, TAOS_FIELD* pTagField);
-static bool hasTimestampForPointInterpQuery(SQueryInfo* pQueryInfo);
static bool hasNormalColumnFilter(SQueryInfo* pQueryInfo);
static int32_t validateLimitNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode* pSqlNode, SSqlObj* pSql);
@@ -1120,7 +1120,8 @@ int32_t validateIntervalNode(SSqlObj* pSql, SQueryInfo* pQueryInfo, SSqlNode* pS
const char* msg1 = "sliding cannot be used without interval";
const char* msg2 = "interval cannot be less than 1 us";
const char* msg3 = "interval value is too small";
- const char* msg4 = "only point interpolation query requires keyword EVERY";
+ const char* msg4 = "invalid usage of EVERY";
+ const char* msg5 = "EVERY instead of INTERVAL required for interp clause";
SSqlCmd* pCmd = &pSql->cmd;
@@ -1132,6 +1133,12 @@ int32_t validateIntervalNode(SSqlObj* pSql, SQueryInfo* pQueryInfo, SSqlNode* pS
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1);
}
+ bool interpQuery = tscGetPointInterpQuery(pQueryInfo);
+
+ if (interpQuery) {
+ return addPrimaryTsColumnForTimeWindowQuery(pQueryInfo, pCmd);
+ }
+
return TSDB_CODE_SUCCESS;
}
@@ -1166,11 +1173,15 @@ int32_t validateIntervalNode(SSqlObj* pSql, SQueryInfo* pQueryInfo, SSqlNode* pS
return TSDB_CODE_TSC_INVALID_OPERATION;
}
- bool interpQuery = tscIsPointInterpQuery(pQueryInfo);
- if ((pSqlNode->interval.token == TK_EVERY && (!interpQuery)) || (pSqlNode->interval.token == TK_INTERVAL && interpQuery)) {
+ bool interpQuery = tscGetPointInterpQuery(pQueryInfo);
+ if (pSqlNode->interval.token == TK_EVERY && (!interpQuery)) {
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg4);
}
+ if (pSqlNode->interval.token == TK_INTERVAL && interpQuery) {
+ return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg5);
+ }
+
// The following part is used to check for the invalid query expression.
return checkInvalidExprForTimeWindow(pCmd, pQueryInfo);
}
@@ -1182,6 +1193,7 @@ static int32_t validateStateWindowNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SS
const char* msg3 = "not support state_window with group by ";
const char* msg4 = "function not support for super table query";
const char* msg5 = "not support state_window on tag column";
+ const char* msg6 = "function not support for state_window";
SStrToken *col = &(pSqlNode->windowstateVal.col) ;
if (col->z == NULL || col->n <= 0) {
@@ -1227,6 +1239,11 @@ static int32_t validateStateWindowNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SS
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg2);
}
+ bool interpQuery = tscGetPointInterpQuery(pQueryInfo);
+ if (interpQuery) {
+ return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg6);
+ }
+
tscColumnListInsert(pQueryInfo->colList, index.columnIndex, pTableMeta->id.uid, pSchema);
SColIndex colIndex = { .colIndex = index.columnIndex, .flag = TSDB_COL_NORMAL, .colId = pSchema->colId };
taosArrayPush(pGroupExpr->columnInfo, &colIndex);
@@ -1240,6 +1257,7 @@ int32_t validateSessionNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode * pS
const char* msg2 = "only one type time window allowed";
const char* msg3 = "invalid column name";
const char* msg4 = "invalid time window";
+ const char* msg5 = "function not support for session";
STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
STableComInfo tinfo = tscGetTableInfo(pTableMetaInfo->pTableMeta);
@@ -1275,6 +1293,11 @@ int32_t validateSessionNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode * pS
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg3);
}
+ bool interpQuery = tscGetPointInterpQuery(pQueryInfo);
+ if (interpQuery) {
+ return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg5);
+ }
+
pQueryInfo->sessionWindow.primaryColId = PRIMARYKEY_TIMESTAMP_COL_INDEX;
// The following part is used to check for the invalid query expression.
@@ -1285,6 +1308,7 @@ int32_t parseIntervalOffset(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SStrToken* of
const char* msg1 = "interval offset cannot be negative";
const char* msg2 = "interval offset should be shorter than interval";
const char* msg3 = "cannot use 'year' as offset when interval is 'month'";
+ const char* msg4 = "wrong every format";
STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
STableComInfo tinfo = tscGetTableInfo(pTableMetaInfo->pTableMeta);
@@ -1296,6 +1320,11 @@ int32_t parseIntervalOffset(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SStrToken* of
return TSDB_CODE_SUCCESS;
}
+ bool interpQuery = tscIsPointInterpQuery(pQueryInfo);
+ if (interpQuery) {
+ return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg4);
+ }
+
if (parseNatualDuration(t->z, t->n, &pQueryInfo->interval.offset,
&pQueryInfo->interval.offsetUnit, tinfo.precision) != TSDB_CODE_SUCCESS) {
return TSDB_CODE_TSC_INVALID_OPERATION;
@@ -1334,6 +1363,7 @@ int32_t parseSlidingClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SStrToken* pSl
const char* msg1 = "sliding value no larger than the interval value";
const char* msg2 = "sliding value can not less than 1% of interval value";
const char* msg3 = "does not support sliding when interval is natural month/year";
+ const char* msg4 = "sliding not support for interp query";
const static int32_t INTERVAL_SLIDING_FACTOR = 100;
@@ -1347,6 +1377,11 @@ int32_t parseSlidingClause(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SStrToken* pSl
return TSDB_CODE_SUCCESS;
}
+ bool interpQuery = tscIsPointInterpQuery(pQueryInfo);
+ if (interpQuery) {
+ return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg4);
+ }
+
if (pInterval->intervalUnit == 'n' || pInterval->intervalUnit == 'y') {
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg3);
}
@@ -2019,6 +2054,7 @@ int32_t validateSelectNodeList(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SArray* pS
const char* msg8 = "not support distinct in nest query";
const char* msg9 = "_block_dist not support subquery, only support stable/table";
const char* msg10 = "not support group by in block func";
+ const char* msg11 = "invalid alias name";
// too many result columns not support order by in query
if (taosArrayGetSize(pSelNodeList) > TSDB_MAX_COLUMNS) {
@@ -2038,9 +2074,12 @@ int32_t validateSelectNodeList(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SArray* pS
int32_t outputIndex = (int32_t)tscNumOfExprs(pQueryInfo);
tSqlExprItem* pItem = taosArrayGet(pSelNodeList, i);
if (hasDistinct == false) {
- hasDistinct = (pItem->distinct == true);
- distIdx = hasDistinct ? i : -1;
- }
+ hasDistinct = (pItem->distinct == true);
+ distIdx = hasDistinct ? i : -1;
+ }
+ if(pItem->aliasName != NULL && validateColumnName(pItem->aliasName) != TSDB_CODE_SUCCESS){
+ return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg11);
+ }
int32_t type = pItem->pNode->type;
if (type == SQL_NODE_SQLFUNCTION) {
@@ -2346,6 +2385,12 @@ static int32_t setExprInfoForFunctions(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SS
invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1);
return -1;
}
+ } else if (f == TSDB_FUNC_INTERP) {
+ int32_t t1 = pSchema->type;
+ if (!IS_NUMERIC_TYPE(t1)) {
+ invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1);
+ return -1;
+ }
}
int16_t resType = 0;
@@ -3181,6 +3226,7 @@ static int16_t doGetColumnIndex(SQueryInfo* pQueryInfo, int32_t index, SStrToken
char tmpTokenBuf[TSDB_MAX_BYTES_PER_ROW] = {0}; // create tmp buf to avoid alter orginal sqlstr
strncpy(tmpTokenBuf, pToken->z, pToken->n);
+
pToken->z = tmpTokenBuf;
if (pToken->type == TK_ID) {
@@ -3498,8 +3544,8 @@ void tscRestoreFuncForSTableQuery(SQueryInfo* pQueryInfo) {
}
bool hasUnsupportFunctionsForSTableQuery(SSqlCmd* pCmd, SQueryInfo* pQueryInfo) {
- const char* msg1 = "TWA/Diff/Derivative/Irate/CSUM/MAVG/SAMPLE are not allowed to apply to super table directly";
- const char* msg2 = "TWA/Diff/Derivative/Irate/CSUM/MAVG/SAMPLE only support group by tbname for super table query";
+ const char* msg1 = "TWA/Diff/Derivative/Irate/CSUM/MAVG/SAMPLE/INTERP are not allowed to apply to super table directly";
+ const char* msg2 = "TWA/Diff/Derivative/Irate/CSUM/MAVG/SAMPLE/INTERP only support group by tbname for super table query";
const char* msg3 = "functions not support for super table query";
// filter sql function not supported by metric query yet.
@@ -3517,7 +3563,7 @@ bool hasUnsupportFunctionsForSTableQuery(SSqlCmd* pCmd, SQueryInfo* pQueryInfo)
}
if (tscIsTWAQuery(pQueryInfo) || tscIsDiffDerivLikeQuery(pQueryInfo) || tscIsIrateQuery(pQueryInfo) ||
- tscQueryContainsFunction(pQueryInfo, TSDB_FUNC_SAMPLE)) {
+ tscQueryContainsFunction(pQueryInfo, TSDB_FUNC_SAMPLE) || tscGetPointInterpQuery(pQueryInfo)) {
if (pQueryInfo->groupbyExpr.numOfGroupCols == 0) {
invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1);
return true;
@@ -3528,6 +3574,11 @@ bool hasUnsupportFunctionsForSTableQuery(SSqlCmd* pCmd, SQueryInfo* pQueryInfo)
invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg2);
return true;
}
+
+ if (tscGetPointInterpQuery(pQueryInfo) && taosArrayGetSize(pQueryInfo->groupbyExpr.columnInfo) > 1) {
+ invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg2);
+ return true;
+ }
} else if (tscIsSessionWindowQuery(pQueryInfo)) {
invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg3);
return true;
@@ -3705,6 +3756,10 @@ int32_t validateGroupbyNode(SQueryInfo* pQueryInfo, SArray* pList, SSqlCmd* pCmd
SStrToken token = {pVar->nLen, pVar->nType, pVar->pz};
+ if (pVar->nType != TSDB_DATA_TYPE_BINARY){
+ return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg2);
+ }
+
SColumnIndex index = COLUMN_INDEX_INITIALIZER;
if (getColumnIndexByName(&token, pQueryInfo, &index, tscGetErrorMsgPayload(pCmd)) != TSDB_CODE_SUCCESS) {
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg2);
@@ -4023,7 +4078,7 @@ static int32_t getColQueryCondExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, tSqlEx
UNUSED(code);
// TODO: more error handling
} END_TRY
-
+
// add to required table column list
STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, i);
int64_t uid = pTableMetaInfo->pTableMeta->id.uid;
@@ -5208,7 +5263,7 @@ static int32_t getTagQueryCondExpr(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SCondE
UNUSED(code);
// TODO: more error handling
} END_TRY
-
+
// add to required table column list
STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, i);
int64_t uid = pTableMetaInfo->pTableMeta->id.uid;
@@ -5417,7 +5472,7 @@ int32_t validateWhereNode(SQueryInfo* pQueryInfo, tSqlExpr** pExpr, SSqlObj* pSq
if (taosArrayGetSize(pQueryInfo->pUpstream) > 0 && condExpr.pTimewindow != NULL) {
setNormalExprToCond(&condExpr.pColumnCond, condExpr.pTimewindow, TK_AND);
- condExpr.pTimewindow = NULL;
+ condExpr.pTimewindow = tSqlExprClone(condExpr.pTimewindow);
}
tSqlExprCompact(pExpr);
@@ -5600,13 +5655,14 @@ int32_t validateFillNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode* pSqlNo
const char* msg3 = "top/bottom/sample not support fill";
const char* msg4 = "illegal value or data overflow";
const char* msg5 = "fill only available for interval query";
- const char* msg6 = "not supported function now";
const char* msg7 = "join query not supported fill operation";
- if ((!isTimeWindowQuery(pQueryInfo)) && (!tscIsPointInterpQuery(pQueryInfo))) {
+ bool pointInterp = tscIsPointInterpQuery(pQueryInfo);
+ if ((!isTimeWindowQuery(pQueryInfo)) && (!pointInterp)) {
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg5);
}
- if(QUERY_IS_JOIN_QUERY(pQueryInfo->type)) {
+
+ if (QUERY_IS_JOIN_QUERY(pQueryInfo->type) && (!pointInterp)) {
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg7);
}
@@ -5614,11 +5670,10 @@ int32_t validateFillNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode* pSqlNo
* fill options are set at the end position, when all columns are set properly
* the columns may be increased due to group by operation
*/
- if (checkQueryRangeForFill(pCmd, pQueryInfo) != TSDB_CODE_SUCCESS) {
+ if ((!pointInterp) && checkQueryRangeForFill(pCmd, pQueryInfo) != TSDB_CODE_SUCCESS) {
return TSDB_CODE_TSC_INVALID_OPERATION;
}
-
if (pItem->pVar.nType != TSDB_DATA_TYPE_BINARY) {
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg2);
}
@@ -5643,9 +5698,6 @@ int32_t validateFillNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode* pSqlNo
}
} else if (strncasecmp(pItem->pVar.pz, "prev", 4) == 0 && pItem->pVar.nLen == 4) {
pQueryInfo->fillType = TSDB_FILL_PREV;
- if (tscIsPointInterpQuery(pQueryInfo) && pQueryInfo->order.order == TSDB_ORDER_DESC) {
- return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg6);
- }
} else if (strncasecmp(pItem->pVar.pz, "next", 4) == 0 && pItem->pVar.nLen == 4) {
pQueryInfo->fillType = TSDB_FILL_NEXT;
} else if (strncasecmp(pItem->pVar.pz, "linear", 6) == 0 && pItem->pVar.nLen == 6) {
@@ -5662,7 +5714,7 @@ int32_t validateFillNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode* pSqlNo
int32_t numOfFillVal = (int32_t)(num - 1);
/* for point interpolation query, we do not have the timestamp column */
- if (tscIsPointInterpQuery(pQueryInfo)) {
+ if (pointInterp) {
startPos = 0;
if (numOfFillVal > numOfFields) {
@@ -5689,7 +5741,7 @@ int32_t validateFillNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode* pSqlNo
}
}
- if ((num < numOfFields) || ((num - 1 < numOfFields) && (tscIsPointInterpQuery(pQueryInfo)))) {
+ if ((num < numOfFields) || ((num - 1 < numOfFields) && pointInterp)) {
tVariantListItem* lastItem = taosArrayGetLast(pFillToken);
for (int32_t i = numOfFillVal; i < numOfFields; ++i) {
@@ -5718,6 +5770,55 @@ int32_t validateFillNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode* pSqlNo
return TSDB_CODE_SUCCESS;
}
+
+
+int32_t validateRangeNode(SSqlObj* pSql, SQueryInfo* pQueryInfo, SSqlNode* pSqlNode) {
+ const char *msg0 = "invalid usage of range clause";
+ const char* msg1 = "invalid timestamp in range";
+ SSqlCmd* pCmd = &pSql->cmd;
+
+ bool interpQuery = tscIsPointInterpQuery(pQueryInfo);
+
+ if ((!interpQuery) && (pSqlNode->pRange.start || pSqlNode->pRange.end)) {
+ return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg0);
+ }
+
+ if (pSqlNode->pRange.start == NULL || pSqlNode->pRange.end == NULL) {
+ pQueryInfo->range.skey = INT64_MIN;
+ pQueryInfo->range.ekey = INT64_MIN;
+
+ tscDebug("0x%"PRIx64" range [%"PRId64",%"PRId64"], ts [%"PRId64",%"PRId64"]", pSql->self, pQueryInfo->range.skey, pQueryInfo->range.ekey, pQueryInfo->window.skey, pQueryInfo->window.ekey);
+ return TSDB_CODE_SUCCESS;
+ }
+
+ STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
+ STableComInfo tinfo = tscGetTableInfo(pTableMetaInfo->pTableMeta);
+
+ if (getTimeRange(&pQueryInfo->range, pSqlNode->pRange.start, TK_GE, tinfo.precision) != TSDB_CODE_SUCCESS) {
+ return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1);
+ }
+
+ if (getTimeRange(&pQueryInfo->range, pSqlNode->pRange.end, TK_LE, tinfo.precision) != TSDB_CODE_SUCCESS) {
+ return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1);
+ }
+
+ if (pQueryInfo->range.ekey < pQueryInfo->range.skey) {
+ return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1);
+ }
+
+ if ((pQueryInfo->range.skey > pQueryInfo->window.ekey && (pQueryInfo->fillType == TSDB_FILL_NONE || pQueryInfo->fillType == TSDB_FILL_LINEAR || pQueryInfo->fillType == TSDB_FILL_NEXT))
+ || (pQueryInfo->range.ekey < pQueryInfo->window.skey && (pQueryInfo->fillType == TSDB_FILL_NONE || pQueryInfo->fillType == TSDB_FILL_LINEAR || pQueryInfo->fillType == TSDB_FILL_PREV))) {
+ tscDebug("0x%"PRIx64" range [%"PRId64",%"PRId64"], ts [%"PRId64",%"PRId64"], no output result", pSql->self, pQueryInfo->range.skey, pQueryInfo->range.ekey, pQueryInfo->window.skey, pQueryInfo->window.ekey);
+ pQueryInfo->command = TSDB_SQL_RETRIEVE_EMPTY_RESULT;
+ return TSDB_CODE_SUCCESS;
+ }
+
+ tscDebug("0x%"PRIx64" range [%"PRId64",%"PRId64"], ts [%"PRId64",%"PRId64"]", pSql->self, pQueryInfo->range.skey, pQueryInfo->range.ekey, pQueryInfo->window.skey, pQueryInfo->window.ekey);
+
+ return TSDB_CODE_SUCCESS;
+}
+
+
static void setDefaultOrderInfo(SQueryInfo* pQueryInfo) {
/* set default timestamp order information for all queries */
STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
@@ -6070,14 +6171,19 @@ int32_t setAlterTableInfo(SSqlObj* pSql, struct SSqlInfo* pInfo) {
STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, DEFAULT_TABLE_INDEX);
bool dbIncluded = false;
- if (tscValidateName(&(pAlterSQL->name), true, &dbIncluded) != TSDB_CODE_SUCCESS) {
+ SStrToken tmpToken = pAlterSQL->name;
+ tmpToken.z= strndup(pAlterSQL->name.z, pAlterSQL->name.n);
+ if (tscValidateName(&tmpToken, true, &dbIncluded) != TSDB_CODE_SUCCESS) {
+ free(tmpToken.z);
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1);
}
- code = tscSetTableFullName(&pTableMetaInfo->name, &(pAlterSQL->name), pSql, dbIncluded);
+ code = tscSetTableFullName(&pTableMetaInfo->name, &tmpToken, pSql, dbIncluded);
if (code != TSDB_CODE_SUCCESS) {
+ free(tmpToken.z);
return code;
}
+ free(tmpToken.z);
code = tscGetTableMeta(pSql, pTableMetaInfo);
if (code != TSDB_CODE_SUCCESS) {
@@ -6692,18 +6798,6 @@ int32_t validateColumnName(char* name) {
return TSDB_CODE_SUCCESS;
}
-bool hasTimestampForPointInterpQuery(SQueryInfo* pQueryInfo) {
- if (!tscIsPointInterpQuery(pQueryInfo)) {
- return true;
- }
-
- if (pQueryInfo->window.skey == INT64_MIN || pQueryInfo->window.ekey == INT64_MAX) {
- return false;
- }
-
- return !(pQueryInfo->window.skey != pQueryInfo->window.ekey && pQueryInfo->interval.interval == 0);
-}
-
int32_t validateLimitNode(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, SSqlNode* pSqlNode, SSqlObj* pSql) {
STableMetaInfo* pTableMetaInfo = tscGetMetaInfo(pQueryInfo, 0);
@@ -7185,7 +7279,7 @@ static int32_t checkUpdateTagPrjFunctions(SQueryInfo* pQueryInfo, char* msg) {
continue;
}
- if ((functionId == TSDB_FUNC_LAST_ROW) ||
+ if ((functionId == TSDB_FUNC_LAST_ROW) || (functionId == TSDB_FUNC_INTERP) ||
(functionId == TSDB_FUNC_LAST_DST && (pExpr->base.colInfo.flag & TSDB_COL_NULL) != 0)) {
// do nothing
} else {
@@ -7441,6 +7535,10 @@ int32_t doFunctionsCompatibleCheck(SSqlCmd* pCmd, SQueryInfo* pQueryInfo, char*
int32_t validateFunctionFromUpstream(SQueryInfo* pQueryInfo, char* msg) {
const char* msg1 = "TWA/Diff/Derivative/Irate are not allowed to apply to super table without group by tbname";
+ const char* msg2 = "group by not supported in nested interp query";
+ const char* msg3 = "order by not supported in nested interp query";
+ const char* msg4 = "first column should be timestamp for interp query";
+ const char* msg5 = "interp input may be invalid";
int32_t numOfExprs = (int32_t)tscNumOfExprs(pQueryInfo);
size_t upNum = taosArrayGetSize(pQueryInfo->pUpstream);
@@ -7460,6 +7558,54 @@ int32_t validateFunctionFromUpstream(SQueryInfo* pQueryInfo, char* msg) {
}
return invalidOperationMsg(msg, msg1);
+ } else if (f == TSDB_FUNC_INTERP) {
+ if (pQueryInfo->groupbyExpr.columnInfo) {
+ return invalidOperationMsg(msg, msg2);
+ }
+
+ if (pQueryInfo->order.order == TSDB_ORDER_DESC || (pQueryInfo->order.orderColId != INT32_MIN && pQueryInfo->order.orderColId != PRIMARYKEY_TIMESTAMP_COL_INDEX)) {
+ return invalidOperationMsg(msg, msg3);
+ }
+
+ for (int32_t j = 0; j < upNum; ++j) {
+ SQueryInfo* pUp = taosArrayGetP(pQueryInfo->pUpstream, j);
+ if (pUp->groupbyExpr.columnInfo) {
+ return invalidOperationMsg(msg, msg2);
+ }
+
+ if (pUp->order.order == TSDB_ORDER_DESC || (pUp->order.orderColId != INT32_MIN && pUp->order.orderColId != PRIMARYKEY_TIMESTAMP_COL_INDEX)) {
+ return invalidOperationMsg(msg, msg3);
+ }
+
+ int32_t exprNum = (int32_t)taosArrayGetSize(pUp->exprList);
+ if (exprNum > 0) {
+ SSqlExpr* expr = taosArrayGetP(pUp->exprList, 0);
+ if (expr->resType != TSDB_DATA_TYPE_TIMESTAMP) {
+ return invalidOperationMsg(msg, msg4);
+ }
+
+ STableMetaInfo *pTableMetaInfo = tscGetMetaInfo(pUp, 0);
+ bool isSTable = UTIL_TABLE_IS_SUPER_TABLE(pTableMetaInfo);
+ if (!isSTable) {
+ continue;
+ }
+
+ if (TSDB_QUERY_HAS_TYPE(pUp->type, TSDB_QUERY_TYPE_PROJECTION_QUERY)) {
+ return invalidOperationMsg(msg, msg5);
+ }
+
+ for (int32_t n = 0; n < exprNum; ++n) {
+ expr = taosArrayGetP(pUp->exprList, n);
+ if (expr->functionId == TSDB_FUNC_TOP ||
+ expr->functionId == TSDB_FUNC_BOTTOM ||
+ expr->functionId == TSDB_FUNC_SAMPLE) {
+ if (expr->param[0].i64 > 1) {
+ return invalidOperationMsg(msg, msg5);
+ }
+ }
+ }
+ }
+ }
}
}
@@ -8919,7 +9065,6 @@ static int32_t doValidateSubquery(SSqlNode* pSqlNode, int32_t index, SSqlObj* pS
int32_t validateSqlNode(SSqlObj* pSql, SSqlNode* pSqlNode, SQueryInfo* pQueryInfo) {
assert(pSqlNode != NULL && (pSqlNode->from == NULL || taosArrayGetSize(pSqlNode->from->list) > 0));
- const char* msg1 = "point interpolation query needs timestamp";
const char* msg2 = "too many tables in from clause";
const char* msg3 = "start(end) time of query range required or time range too large";
const char* msg4 = "interval query not supported, since the result of sub query not include valid timestamp column";
@@ -8989,7 +9134,7 @@ int32_t validateSqlNode(SSqlObj* pSql, SSqlNode* pSqlNode, SQueryInfo* pQueryInf
for (int32_t i = 0; i < tscNumOfExprs(pQueryInfo); ++i) {
SExprInfo* pExpr = tscExprGet(pQueryInfo, i);
int32_t f = pExpr->base.functionId;
- if (f == TSDB_FUNC_STDDEV || f == TSDB_FUNC_PERCT || f == TSDB_FUNC_INTERP) {
+ if (f == TSDB_FUNC_STDDEV || f == TSDB_FUNC_PERCT) {
return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg6);
}
@@ -9092,6 +9237,10 @@ int32_t validateSqlNode(SSqlObj* pSql, SSqlNode* pSqlNode, SQueryInfo* pQueryInf
if ((code = validateFillNode(pCmd, pQueryInfo, pSqlNode)) != TSDB_CODE_SUCCESS) {
return code;
}
+
+ if ((code = validateRangeNode(pSql, pQueryInfo, pSqlNode)) != TSDB_CODE_SUCCESS) {
+ return code;
+ }
} else {
pQueryInfo->command = TSDB_SQL_SELECT;
@@ -9199,10 +9348,6 @@ int32_t validateSqlNode(SSqlObj* pSql, SSqlNode* pSqlNode, SQueryInfo* pQueryInf
return TSDB_CODE_SUCCESS;
}
- if (!hasTimestampForPointInterpQuery(pQueryInfo)) {
- return invalidOperationMsg(tscGetErrorMsgPayload(pCmd), msg1);
- }
-
// in case of join query, time range is required.
if (QUERY_IS_JOIN_QUERY(pQueryInfo->type)) {
uint64_t timeRange = (uint64_t)pQueryInfo->window.ekey - pQueryInfo->window.skey;
@@ -9226,6 +9371,11 @@ int32_t validateSqlNode(SSqlObj* pSql, SSqlNode* pSqlNode, SQueryInfo* pQueryInf
if ((code = validateFillNode(pCmd, pQueryInfo, pSqlNode)) != TSDB_CODE_SUCCESS) {
return code;
}
+
+ if ((code = validateRangeNode(pSql, pQueryInfo, pSqlNode)) != TSDB_CODE_SUCCESS) {
+ return code;
+ }
+
}
{ // set the query info
diff --git a/src/client/src/tscServer.c b/src/client/src/tscServer.c
index 0eba04ffb2e500e0d7a0ab6f005a217b6027f41c..52a918bbe22589d85fc89cbff8249065129f1618 100644
--- a/src/client/src/tscServer.c
+++ b/src/client/src/tscServer.c
@@ -916,7 +916,9 @@ int tscBuildQueryMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
pQueryMsg->window.skey = htobe64(query.window.skey);
pQueryMsg->window.ekey = htobe64(query.window.ekey);
-
+ pQueryMsg->range.skey = htobe64(query.range.skey);
+ pQueryMsg->range.ekey = htobe64(query.range.ekey);
+
pQueryMsg->order = htons(query.order.order);
pQueryMsg->orderColId = htons(query.order.orderColId);
pQueryMsg->fillType = htons(query.fillType);
@@ -975,7 +977,7 @@ int tscBuildQueryMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
if (pQueryInfo->colCond && taosArrayGetSize(pQueryInfo->colCond) > 0 && !onlyQueryTags(&query) ) {
STblCond *pCond = tsGetTableFilter(pQueryInfo->colCond, pTableMeta->id.uid, 0);
if (pCond != NULL && pCond->cond != NULL) {
- pQueryMsg->colCondLen = htons(pCond->len);
+ pQueryMsg->colCondLen = htonl(pCond->len);
memcpy(pMsg, pCond->cond, pCond->len);
pMsg += pCond->len;
@@ -1056,7 +1058,7 @@ int tscBuildQueryMsg(SSqlObj *pSql, SSqlInfo *pInfo) {
SCond *pCond = tsGetSTableQueryCond(pTagCond, pTableMeta->id.uid);
if (pCond != NULL && pCond->cond != NULL) {
- pQueryMsg->tagCondLen = htons(pCond->len);
+ pQueryMsg->tagCondLen = htonl(pCond->len);
memcpy(pMsg, pCond->cond, pCond->len);
pMsg += pCond->len;
diff --git a/src/client/src/tscSub.c b/src/client/src/tscSub.c
index 5e70c814133fd93b7619022a1d564050c3c0502a..5a26397c5a260f8ee527a05bbfc700b53a23951c 100644
--- a/src/client/src/tscSub.c
+++ b/src/client/src/tscSub.c
@@ -468,7 +468,7 @@ SSqlObj* recreateSqlObj(SSub* pSub) {
}
registerSqlObj(pSql);
-
+ pSql->rootObj = pSql;
code = tsParseSql(pSql, true);
if (code == TSDB_CODE_TSC_ACTION_IN_PROGRESS) {
tsem_wait(&pSub->sem);
diff --git a/src/client/src/tscSubquery.c b/src/client/src/tscSubquery.c
index f5702b4e35d69ced9bf024285f86dfb306900a60..2412b8336efbcf289fc4d2e11796b01b02f8174d 100644
--- a/src/client/src/tscSubquery.c
+++ b/src/client/src/tscSubquery.c
@@ -394,6 +394,12 @@ SJoinSupporter* tscCreateJoinSupporter(SSqlObj* pSql, int32_t index) {
memcpy(&pSupporter->interval, &pQueryInfo->interval, sizeof(pSupporter->interval));
pSupporter->limit = pQueryInfo->limit;
+ if (tscIsPointInterpQuery(pQueryInfo)) {
+ pSupporter->fillType = pQueryInfo->fillType;
+ pSupporter->fillVal = pQueryInfo->fillVal;
+ pSupporter->numOfFillVal = pQueryInfo->numOfFillVal;
+ }
+
STableMetaInfo* pTableMetaInfo = tscGetTableMetaInfoFromCmd(&pSql->cmd, index);
pSupporter->uid = pTableMetaInfo->pTableMeta->id.uid;
assert (pSupporter->uid != 0);
@@ -579,6 +585,13 @@ static int32_t tscLaunchRealSubqueries(SSqlObj* pSql) {
pQueryInfo->fieldsInfo = pSupporter->fieldsInfo;
pQueryInfo->groupbyExpr = pSupporter->groupInfo;
pQueryInfo->pUpstream = taosArrayInit(4, sizeof(POINTER_BYTES));
+
+ if (tscIsPointInterpQuery(pQueryInfo)) {
+ pQueryInfo->fillType = pSupporter->fillType;
+ pQueryInfo->numOfFillVal = pSupporter->numOfFillVal;
+ pQueryInfo->fillVal = malloc(pQueryInfo->numOfFillVal * sizeof(*pSupporter->fillVal));
+ memcpy(pQueryInfo->fillVal, pSupporter->fillVal, sizeof(*pSupporter->fillVal) * pQueryInfo->numOfFillVal);
+ }
assert(pNew->subState.numOfSub == 0 && pQueryInfo->numOfTables == 1);
diff --git a/src/client/src/tscUtil.c b/src/client/src/tscUtil.c
index b03aef9e188b96d2bd3203720317a68f81c0a960..50b9a8fd7eea703dffe34f8ad5eb204b310f0d7e 100644
--- a/src/client/src/tscUtil.c
+++ b/src/client/src/tscUtil.c
@@ -187,7 +187,7 @@ bool tscQueryTags(SQueryInfo* pQueryInfo) {
continue;
}
- if (functId != TSDB_FUNC_TAGPRJ && functId != TSDB_FUNC_TID_TAG) {
+ if (functId != TSDB_FUNC_TAGPRJ && functId != TSDB_FUNC_TID_TAG && functId != TSDB_FUNC_BLKINFO) {
return false;
}
}
@@ -367,7 +367,7 @@ bool tscIsPointInterpQuery(SQueryInfo* pQueryInfo) {
assert(pExpr != NULL);
int32_t functionId = pExpr->base.functionId;
- if (functionId == TSDB_FUNC_TAG || functionId == TSDB_FUNC_TS) {
+ if (functionId == TSDB_FUNC_TAG || functionId == TSDB_FUNC_TAG_DUMMY || functionId == TSDB_FUNC_TS || functionId == TSDB_FUNC_TS_DUMMY) {
continue;
}
@@ -379,6 +379,23 @@ bool tscIsPointInterpQuery(SQueryInfo* pQueryInfo) {
return true;
}
+bool tscGetPointInterpQuery(SQueryInfo* pQueryInfo) {
+ size_t size = tscNumOfExprs(pQueryInfo);
+ for (int32_t i = 0; i < size; ++i) {
+ SExprInfo* pExpr = tscExprGet(pQueryInfo, i);
+ assert(pExpr != NULL);
+
+ int32_t functionId = pExpr->base.functionId;
+
+ if (functionId == TSDB_FUNC_INTERP) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+
bool tsIsArithmeticQueryOnAggResult(SQueryInfo* pQueryInfo) {
if (tscIsProjectionQuery(pQueryInfo)) {
return false;
@@ -942,23 +959,30 @@ SSDataBlock* doGetDataBlock(void* param, bool* newgroup) {
pBlock->info.rows = pRes->numOfRows;
if (pRes->numOfRows != 0) {
doSetupSDataBlock(pRes, pBlock, pInput->pFilterInfo);
- *newgroup = false;
- return pBlock;
+ if (pBlock->info.rows > 0) {
+ *newgroup = false;
+ return pBlock;
+ }
}
- // No data block exists. So retrieve and transfer it into to SSDataBlock
- TAOS_ROW pRow = NULL;
- taos_fetch_block(pSql, &pRow);
+ SSDataBlock* result = NULL;
+ do {
+ // No data block exists. So retrieve and transfer it into to SSDataBlock
+ TAOS_ROW pRow = NULL;
+ taos_fetch_block(pSql, &pRow);
- if (pRes->numOfRows == 0) {
- pOperator->status = OP_EXEC_DONE;
- return NULL;
- }
+ if (pRes->numOfRows == 0) {
+ pOperator->status = OP_EXEC_DONE;
+ result = NULL;
+ break;
+ }
+ pBlock->info.rows = pRes->numOfRows;
+ doSetupSDataBlock(pRes, pBlock, pInput->pFilterInfo);
+ *newgroup = false;
+ result = pBlock;
+ } while (result->info.rows == 0);
- pBlock->info.rows = pRes->numOfRows;
- doSetupSDataBlock(pRes, pBlock, pInput->pFilterInfo);
- *newgroup = false;
- return pBlock;
+ return result;
}
static void fetchNextBlockIfCompleted(SOperatorInfo* pOperator, bool* newgroup) {
@@ -1838,6 +1862,32 @@ int32_t tscCreateDataBlock(size_t defaultSize, int32_t rowSize, int32_t startOff
return TSDB_CODE_TSC_OUT_OF_MEMORY;
}
+ int32_t code = tscCreateDataBlockData(dataBuf, defaultSize, rowSize, startOffset);
+ if (code != TSDB_CODE_SUCCESS) {
+ tfree(dataBuf);
+ return code;
+ }
+
+ //Here we keep the tableMeta to avoid it to be remove by other threads.
+ dataBuf->pTableMeta = tscTableMetaDup(pTableMeta);
+
+ SParsedDataColInfo* pColInfo = &dataBuf->boundColumnInfo;
+ SSchema* pSchema = tscGetTableSchema(dataBuf->pTableMeta);
+ tscSetBoundColumnInfo(pColInfo, pSchema, dataBuf->pTableMeta->tableInfo.numOfColumns);
+
+ dataBuf->vgId = dataBuf->pTableMeta->vgId;
+
+ tNameAssign(&dataBuf->tableName, name);
+
+ assert(defaultSize > 0 && pTableMeta != NULL && dataBuf->pTableMeta != NULL);
+
+ *dataBlocks = dataBuf;
+ return TSDB_CODE_SUCCESS;
+}
+
+int32_t tscCreateDataBlockData(STableDataBlocks* dataBuf, size_t defaultSize, int32_t rowSize, int32_t startOffset) {
+ assert(dataBuf != NULL);
+
dataBuf->nAllocSize = (uint32_t)defaultSize;
dataBuf->headerSize = startOffset;
@@ -1850,30 +1900,16 @@ int32_t tscCreateDataBlock(size_t defaultSize, int32_t rowSize, int32_t startOff
dataBuf->pData = malloc(dataBuf->nAllocSize);
if (dataBuf->pData == NULL) {
tscError("failed to allocated memory, reason:%s", strerror(errno));
- tfree(dataBuf);
return TSDB_CODE_TSC_OUT_OF_MEMORY;
}
memset(dataBuf->pData, 0, sizeof(SSubmitBlk));
- //Here we keep the tableMeta to avoid it to be remove by other threads.
- dataBuf->pTableMeta = tscTableMetaDup(pTableMeta);
-
- SParsedDataColInfo* pColInfo = &dataBuf->boundColumnInfo;
- SSchema* pSchema = tscGetTableSchema(dataBuf->pTableMeta);
- tscSetBoundColumnInfo(pColInfo, pSchema, dataBuf->pTableMeta->tableInfo.numOfColumns);
-
dataBuf->ordered = true;
dataBuf->prevTS = INT64_MIN;
dataBuf->rowSize = rowSize;
dataBuf->size = startOffset;
dataBuf->tsSource = -1;
- dataBuf->vgId = dataBuf->pTableMeta->vgId;
-
- tNameAssign(&dataBuf->tableName, name);
- assert(defaultSize > 0 && pTableMeta != NULL && dataBuf->pTableMeta != NULL);
-
- *dataBlocks = dataBuf;
return TSDB_CODE_SUCCESS;
}
@@ -2953,6 +2989,11 @@ int32_t tscValidateName(SStrToken* pToken, bool escapeEnabled, bool *dbIncluded)
}
} else if (pToken->type == TK_ID) {
tscRmEscapeAndTrimToken(pToken);
+
+ if (pToken->n == 0) {
+ return TSDB_CODE_TSC_INVALID_OPERATION;
+ }
+
return TSDB_CODE_SUCCESS;
} else {
if (isNumber(pToken)) {
@@ -3417,7 +3458,7 @@ int32_t tscQueryInfoCopy(SQueryInfo* pQueryInfo, const SQueryInfo* pSrc) {
pQueryInfo->clauseLimit = pSrc->clauseLimit;
pQueryInfo->prjOffset = pSrc->prjOffset;
pQueryInfo->numOfTables = 0;
- pQueryInfo->window = pSrc->window;
+ pQueryInfo->range = pSrc->range;
pQueryInfo->sessionWindow = pSrc->sessionWindow;
pQueryInfo->pTableMetaInfo = NULL;
pQueryInfo->multigroupResult = pSrc->multigroupResult;
@@ -3810,6 +3851,7 @@ SSqlObj* createSubqueryObj(SSqlObj* pSql, int16_t tableIndex, __async_cb_func_t
memcpy(&pNewQueryInfo->interval, &pQueryInfo->interval, sizeof(pNewQueryInfo->interval));
pNewQueryInfo->type = pQueryInfo->type;
pNewQueryInfo->window = pQueryInfo->window;
+ pNewQueryInfo->range = pQueryInfo->range;
pNewQueryInfo->limit = pQueryInfo->limit;
pNewQueryInfo->slimit = pQueryInfo->slimit;
pNewQueryInfo->order = pQueryInfo->order;
@@ -5029,6 +5071,7 @@ int32_t tscCreateQueryFromQueryInfo(SQueryInfo* pQueryInfo, SQueryAttr* pQueryAt
pQueryAttr->fillType = pQueryInfo->fillType;
pQueryAttr->havingNum = pQueryInfo->havingFieldNum;
pQueryAttr->pUdfInfo = pQueryInfo->pUdfInfo;
+ pQueryAttr->range = pQueryInfo->range;
if (pQueryInfo->order.order == TSDB_ORDER_ASC) { // TODO refactor
pQueryAttr->window = pQueryInfo->window;
@@ -5328,4 +5371,3 @@ char* cloneCurrentDBName(SSqlObj* pSql) {
return p;
}
-
diff --git a/src/common/src/tdataformat.c b/src/common/src/tdataformat.c
index bdb4e743a0db92074bdfd45431619019725be2c7..bce9474b6d4fb9f783947ba2e27382d8c1d46429 100644
--- a/src/common/src/tdataformat.c
+++ b/src/common/src/tdataformat.c
@@ -253,9 +253,10 @@ int dataColAppendVal(SDataCol *pCol, const void *value, int numOfRows, int maxPo
}
if(tdAllocMemForCol(pCol, maxPoints) < 0) return -1;
- if (numOfRows > 0) {
+
+ if (((rowOffset == 0) && (numOfRows > 0)) || ((rowOffset == -1) && (numOfRows >= 0))) {
// Find the first not null value, fill all previouse values as NULL
- dataColSetNEleNull(pCol, numOfRows);
+ dataColSetNEleNull(pCol, numOfRows - rowOffset);
}
}
@@ -463,9 +464,7 @@ static void tdAppendDataRowToDataCol(SDataRow row, STSchema *pSchema, SDataCols
int rcol = 0;
int dcol = 0;
-
while (dcol < pCols->numOfCols) {
- bool setCol = 0;
SDataCol *pDataCol = &(pCols->cols[dcol]);
if (rcol >= schemaNCols(pSchema)) {
dataColAppendVal(pDataCol, getNullValue(pDataCol->type), pCols->numOfRows, pCols->maxPoints, rowOffset);
@@ -476,14 +475,22 @@ static void tdAppendDataRowToDataCol(SDataRow row, STSchema *pSchema, SDataCols
STColumn *pRowCol = schemaColAt(pSchema, rcol);
if (pRowCol->colId == pDataCol->colId) {
void *value = tdGetRowDataOfCol(row, pRowCol->type, pRowCol->offset + TD_DATA_ROW_HEAD_SIZE);
- if(!isNull(value, pDataCol->type)) setCol = 1;
- dataColAppendVal(pDataCol, value, pCols->numOfRows, pCols->maxPoints, rowOffset);
+ if (rowOffset == 0) {
+ dataColAppendVal(pDataCol, value, pCols->numOfRows, pCols->maxPoints, rowOffset);
+ } else if (rowOffset == -1) {
+ // for update 2
+ if (!isNull(value, pDataCol->type)) {
+ dataColAppendVal(pDataCol, value, pCols->numOfRows, pCols->maxPoints, rowOffset);
+ }
+ } else {
+ ASSERT(0);
+ }
dcol++;
rcol++;
} else if (pRowCol->colId < pDataCol->colId) {
rcol++;
} else {
- if(forceSetNull || setCol) {
+ if(forceSetNull) {
dataColAppendVal(pDataCol, getNullValue(pDataCol->type), pCols->numOfRows, pCols->maxPoints, rowOffset);
}
dcol++;
@@ -501,7 +508,6 @@ static void tdAppendKvRowToDataCol(SKVRow row, STSchema *pSchema, SDataCols *pCo
int nRowCols = kvRowNCols(row);
while (dcol < pCols->numOfCols) {
- bool setCol = 0;
SDataCol *pDataCol = &(pCols->cols[dcol]);
if (rcol >= nRowCols || rcol >= schemaNCols(pSchema)) {
dataColAppendVal(pDataCol, getNullValue(pDataCol->type), pCols->numOfRows, pCols->maxPoints, rowOffset);
@@ -513,14 +519,22 @@ static void tdAppendKvRowToDataCol(SKVRow row, STSchema *pSchema, SDataCols *pCo
if (colIdx->colId == pDataCol->colId) {
void *value = tdGetKvRowDataOfCol(row, colIdx->offset);
- if(!isNull(value, pDataCol->type)) setCol = 1;
- dataColAppendVal(pDataCol, value, pCols->numOfRows, pCols->maxPoints, rowOffset);
+ if (rowOffset == 0) {
+ dataColAppendVal(pDataCol, value, pCols->numOfRows, pCols->maxPoints, rowOffset);
+ } else if (rowOffset == -1) {
+ // for update 2
+ if (!isNull(value, pDataCol->type)) {
+ dataColAppendVal(pDataCol, value, pCols->numOfRows, pCols->maxPoints, rowOffset);
+ }
+ } else {
+ ASSERT(0);
+ }
++dcol;
++rcol;
} else if (colIdx->colId < pDataCol->colId) {
++rcol;
} else {
- if(forceSetNull || setCol) {
+ if (forceSetNull) {
dataColAppendVal(pDataCol, getNullValue(pDataCol->type), pCols->numOfRows, pCols->maxPoints, rowOffset);
}
++dcol;
diff --git a/src/common/src/tglobal.c b/src/common/src/tglobal.c
index c1a254b4ebd5fdfe1d29e02ab7cacbe3195058f1..f13a35f0b9ae287f04cccf1785fce77f8d5c0678 100644
--- a/src/common/src/tglobal.c
+++ b/src/common/src/tglobal.c
@@ -73,7 +73,7 @@ int32_t tsMaxBinaryDisplayWidth = 30;
* -1: all data are not compressed
* other values: if the message payload size is greater than the tsCompressMsgSize, the message will be compressed.
*/
-int32_t tsCompressMsgSize = -1;
+int32_t tsCompressMsgSize = 512 * 1024;
/* denote if server needs to compress the retrieved column data before adding to the rpc response message body.
* 0: all data are compressed
@@ -289,7 +289,7 @@ char Compressor[32] = "ZSTD_COMPRESSOR"; // ZSTD_COMPRESSOR or GZIP_COMPRES
int8_t tsDeadLockKillQuery = 0;
// default JSON string type
-char tsDefaultJSONStrType[7] = "binary";
+char tsDefaultJSONStrType[7] = "nchar";
char tsSmlChildTableName[TSDB_TABLE_NAME_LEN] = ""; //user defined child table name can be specified in tag value. If set to empty system will generate table name using MD5 hash.
int32_t (*monStartSystemFp)() = NULL;
diff --git a/src/connector/C#/TDengineDriver.cs b/src/connector/C#/TDengineDriver.cs
index e6c3a598adc0bc4bcf5ea84953f649b418199555..f9a5890eedb8714616cb4d624f9036ffdeef35fb 100644
--- a/src/connector/C#/TDengineDriver.cs
+++ b/src/connector/C#/TDengineDriver.cs
@@ -163,8 +163,12 @@ namespace TDengineDriver
[DllImport("taos", EntryPoint = "taos_close", CallingConvention = CallingConvention.Cdecl)]
static extern public int Close(IntPtr taos);
- //get precisionin parameter restultset
+ //get precision in restultset
[DllImport("taos", EntryPoint = "taos_result_precision", CallingConvention = CallingConvention.Cdecl)]
static extern public int ResultPrecision(IntPtr taos);
+
+ //schemaless API
+ [DllImport("taos",SetLastError = true, EntryPoint = "taos_schemaless_insert", CallingConvention = CallingConvention.Cdecl)]
+ static extern public IntPtr SchemalessInsert(IntPtr taos, string[] lines, int numLines, int protocol, int precision);
}
}
diff --git a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/AbstractConnection.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/AbstractConnection.java
index 67652b1c7ada63a8336fdc44dc9814f0a266c086..c992cf58ba43eb0e052d9bc80824d94e98b725ca 100644
--- a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/AbstractConnection.java
+++ b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/AbstractConnection.java
@@ -413,8 +413,7 @@ public abstract class AbstractConnection extends WrapperImpl implements Connecti
status = future.get();
else
status = future.get(timeout, TimeUnit.SECONDS);
- } catch (InterruptedException | ExecutionException e) {
- e.printStackTrace();
+ } catch (InterruptedException | ExecutionException ignored) {
} catch (TimeoutException e) {
future.cancel(true);
status = false;
diff --git a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/AbstractDatabaseMetaData.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/AbstractDatabaseMetaData.java
index f6ec70fbac555b97b2cb342edfaa5fde56245c5a..6343a802af280415b4d21f56476eb4403b4608ac 100644
--- a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/AbstractDatabaseMetaData.java
+++ b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/AbstractDatabaseMetaData.java
@@ -597,7 +597,7 @@ public abstract class AbstractDatabaseMetaData extends WrapperImpl implements Da
return col4;
}
- public ResultSet getSchemas() throws SQLException {
+ public ResultSet getSchemas() {
return getEmptyResultSet();
}
@@ -629,7 +629,7 @@ public abstract class AbstractDatabaseMetaData extends WrapperImpl implements Da
public abstract ResultSet getColumns(String catalog, String schemaPattern, String tableNamePattern, String columnNamePattern) throws SQLException;
- protected ResultSet getColumns(String catalog, String schemaPattern, String tableNamePattern, String columnNamePattern, Connection conn) {
+ protected ResultSet getColumns(String catalog, String schemaPattern, String tableNamePattern, String columnNamePattern, Connection conn) throws SQLException {
if (catalog == null || catalog.isEmpty())
return null;
if (!isAvailableCatalog(conn, catalog))
@@ -682,8 +682,6 @@ public abstract class AbstractDatabaseMetaData extends WrapperImpl implements Da
rowIndex++;
}
resultSet.setRowDataList(rowDataList);
- } catch (SQLException e) {
- e.printStackTrace();
}
return resultSet;
}
@@ -1220,7 +1218,7 @@ public abstract class AbstractDatabaseMetaData extends WrapperImpl implements Da
return col6;
}
- private boolean isAvailableCatalog(Connection connection, String catalog) {
+ private boolean isAvailableCatalog(Connection connection, String catalog) throws SQLException {
try (Statement stmt = connection.createStatement();
ResultSet databases = stmt.executeQuery("show databases")) {
while (databases.next()) {
@@ -1229,8 +1227,6 @@ public abstract class AbstractDatabaseMetaData extends WrapperImpl implements Da
if (dbname.equalsIgnoreCase(catalog))
return true;
}
- } catch (SQLException e) {
- e.printStackTrace();
}
return false;
}
diff --git a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBJNIConnector.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBJNIConnector.java
index a5c7f26a266f81e3a7915503d2983efe077765c2..ee2c8141a81bb9dc2aa51ba14247dfbb834ec746 100755
--- a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBJNIConnector.java
+++ b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBJNIConnector.java
@@ -21,6 +21,7 @@ import com.taosdata.jdbc.enums.SchemalessProtocolType;
import com.taosdata.jdbc.enums.SchemalessTimestampType;
import com.taosdata.jdbc.utils.TaosInfo;
+import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
import java.sql.SQLException;
import java.sql.SQLWarning;
@@ -107,8 +108,7 @@ public class TSDBJNIConnector {
try {
pSql = this.executeQueryImp(sql.getBytes(TaosGlobalConfig.getCharset()), this.taos);
taosInfo.stmt_count_increment();
- } catch (Exception e) {
- e.printStackTrace();
+ } catch (UnsupportedEncodingException e) {
this.freeResultSetImp(this.taos, pSql);
throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_ENCODING);
}
diff --git a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBPreparedStatement.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBPreparedStatement.java
index 42ebedf4027b0e333b9e79b8045f1bae0d338ac7..5fd8f181388824bccd4a2ab2b488667af117b172 100644
--- a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBPreparedStatement.java
+++ b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBPreparedStatement.java
@@ -611,7 +611,7 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat
try {
this.tagValueLength += value.getBytes(charset).length;
} catch (UnsupportedEncodingException e) {
- e.printStackTrace();
+ throw new RuntimeException(e.getMessage());
}
}
@@ -786,7 +786,7 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat
b = val.getBytes(charset);
}
} catch (UnsupportedEncodingException e) {
- e.printStackTrace();
+ throw new RuntimeException(e.getMessage());
}
tagDataList.put(b);
@@ -921,7 +921,7 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat
b = val.getBytes(charset);
}
} catch (UnsupportedEncodingException e) {
- e.printStackTrace();
+ throw new RuntimeException(e.getMessage());
}
if (val.length() > col1.bytes) {
@@ -980,8 +980,10 @@ public class TSDBPreparedStatement extends TSDBStatement implements PreparedStat
@Override
public void close() throws SQLException {
- this.columnDataClearBatchInternal();
- this.columnDataCloseBatch();
+ if (this.nativeStmtHandle != 0L) {
+ this.columnDataClearBatchInternal();
+ this.columnDataCloseBatch();
+ }
super.close();
}
}
diff --git a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBResultSetBlockData.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBResultSetBlockData.java
index ff49677b01fa1c3a4d482cebd51269d5f1589e43..e404db64e3dffbdcc0d2c2845279723874f6b5d8 100644
--- a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBResultSetBlockData.java
+++ b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBResultSetBlockData.java
@@ -92,75 +92,71 @@ public class TSDBResultSetBlockData {
}
public void setByteArray(int col, int length, byte[] value) {
- try {
- switch (this.columnMetaDataList.get(col).getColType()) {
- case TSDBConstants.TSDB_DATA_TYPE_BOOL: {
- ByteBuffer buf = ByteBuffer.wrap(value, 0, length);
- buf.order(ByteOrder.LITTLE_ENDIAN).asCharBuffer();
- this.colData.set(col, buf);
- break;
- }
- case TSDBConstants.TSDB_DATA_TYPE_UTINYINT:
- case TSDBConstants.TSDB_DATA_TYPE_TINYINT: {
- ByteBuffer buf = ByteBuffer.wrap(value, 0, length);
- buf.order(ByteOrder.LITTLE_ENDIAN);
- this.colData.set(col, buf);
- break;
- }
- case TSDBConstants.TSDB_DATA_TYPE_USMALLINT:
- case TSDBConstants.TSDB_DATA_TYPE_SMALLINT: {
- ByteBuffer buf = ByteBuffer.wrap(value, 0, length);
- ShortBuffer sb = buf.order(ByteOrder.LITTLE_ENDIAN).asShortBuffer();
- this.colData.set(col, sb);
- break;
- }
- case TSDBConstants.TSDB_DATA_TYPE_UINT:
- case TSDBConstants.TSDB_DATA_TYPE_INT: {
- ByteBuffer buf = ByteBuffer.wrap(value, 0, length);
- IntBuffer ib = buf.order(ByteOrder.LITTLE_ENDIAN).asIntBuffer();
- this.colData.set(col, ib);
- break;
- }
- case TSDBConstants.TSDB_DATA_TYPE_UBIGINT:
- case TSDBConstants.TSDB_DATA_TYPE_BIGINT: {
- ByteBuffer buf = ByteBuffer.wrap(value, 0, length);
- LongBuffer lb = buf.order(ByteOrder.LITTLE_ENDIAN).asLongBuffer();
- this.colData.set(col, lb);
- break;
- }
- case TSDBConstants.TSDB_DATA_TYPE_FLOAT: {
- ByteBuffer buf = ByteBuffer.wrap(value, 0, length);
- FloatBuffer fb = buf.order(ByteOrder.LITTLE_ENDIAN).asFloatBuffer();
- this.colData.set(col, fb);
- break;
- }
- case TSDBConstants.TSDB_DATA_TYPE_DOUBLE: {
- ByteBuffer buf = ByteBuffer.wrap(value, 0, length);
- DoubleBuffer db = buf.order(ByteOrder.LITTLE_ENDIAN).asDoubleBuffer();
- this.colData.set(col, db);
- break;
- }
- case TSDBConstants.TSDB_DATA_TYPE_BINARY: {
- ByteBuffer buf = ByteBuffer.wrap(value, 0, length);
- buf.order(ByteOrder.LITTLE_ENDIAN);
- this.colData.set(col, buf);
- break;
- }
- case TSDBConstants.TSDB_DATA_TYPE_TIMESTAMP: {
- ByteBuffer buf = ByteBuffer.wrap(value, 0, length);
- LongBuffer lb = buf.order(ByteOrder.LITTLE_ENDIAN).asLongBuffer();
- this.colData.set(col, lb);
- break;
- }
- case TSDBConstants.TSDB_DATA_TYPE_NCHAR: {
- ByteBuffer buf = ByteBuffer.wrap(value, 0, length);
- buf.order(ByteOrder.LITTLE_ENDIAN);
- this.colData.set(col, buf);
- break;
- }
+ switch (this.columnMetaDataList.get(col).getColType()) {
+ case TSDBConstants.TSDB_DATA_TYPE_BOOL: {
+ ByteBuffer buf = ByteBuffer.wrap(value, 0, length);
+ buf.order(ByteOrder.LITTLE_ENDIAN).asCharBuffer();
+ this.colData.set(col, buf);
+ break;
+ }
+ case TSDBConstants.TSDB_DATA_TYPE_UTINYINT:
+ case TSDBConstants.TSDB_DATA_TYPE_TINYINT: {
+ ByteBuffer buf = ByteBuffer.wrap(value, 0, length);
+ buf.order(ByteOrder.LITTLE_ENDIAN);
+ this.colData.set(col, buf);
+ break;
+ }
+ case TSDBConstants.TSDB_DATA_TYPE_USMALLINT:
+ case TSDBConstants.TSDB_DATA_TYPE_SMALLINT: {
+ ByteBuffer buf = ByteBuffer.wrap(value, 0, length);
+ ShortBuffer sb = buf.order(ByteOrder.LITTLE_ENDIAN).asShortBuffer();
+ this.colData.set(col, sb);
+ break;
+ }
+ case TSDBConstants.TSDB_DATA_TYPE_UINT:
+ case TSDBConstants.TSDB_DATA_TYPE_INT: {
+ ByteBuffer buf = ByteBuffer.wrap(value, 0, length);
+ IntBuffer ib = buf.order(ByteOrder.LITTLE_ENDIAN).asIntBuffer();
+ this.colData.set(col, ib);
+ break;
+ }
+ case TSDBConstants.TSDB_DATA_TYPE_UBIGINT:
+ case TSDBConstants.TSDB_DATA_TYPE_BIGINT: {
+ ByteBuffer buf = ByteBuffer.wrap(value, 0, length);
+ LongBuffer lb = buf.order(ByteOrder.LITTLE_ENDIAN).asLongBuffer();
+ this.colData.set(col, lb);
+ break;
+ }
+ case TSDBConstants.TSDB_DATA_TYPE_FLOAT: {
+ ByteBuffer buf = ByteBuffer.wrap(value, 0, length);
+ FloatBuffer fb = buf.order(ByteOrder.LITTLE_ENDIAN).asFloatBuffer();
+ this.colData.set(col, fb);
+ break;
+ }
+ case TSDBConstants.TSDB_DATA_TYPE_DOUBLE: {
+ ByteBuffer buf = ByteBuffer.wrap(value, 0, length);
+ DoubleBuffer db = buf.order(ByteOrder.LITTLE_ENDIAN).asDoubleBuffer();
+ this.colData.set(col, db);
+ break;
+ }
+ case TSDBConstants.TSDB_DATA_TYPE_BINARY: {
+ ByteBuffer buf = ByteBuffer.wrap(value, 0, length);
+ buf.order(ByteOrder.LITTLE_ENDIAN);
+ this.colData.set(col, buf);
+ break;
+ }
+ case TSDBConstants.TSDB_DATA_TYPE_TIMESTAMP: {
+ ByteBuffer buf = ByteBuffer.wrap(value, 0, length);
+ LongBuffer lb = buf.order(ByteOrder.LITTLE_ENDIAN).asLongBuffer();
+ this.colData.set(col, lb);
+ break;
+ }
+ case TSDBConstants.TSDB_DATA_TYPE_NCHAR: {
+ ByteBuffer buf = ByteBuffer.wrap(value, 0, length);
+ buf.order(ByteOrder.LITTLE_ENDIAN);
+ this.colData.set(col, buf);
+ break;
}
- } catch (Exception e) {
- e.printStackTrace();
}
}
@@ -283,14 +279,8 @@ public class TSDBResultSetBlockData {
return 0;
}
- public Timestamp getTimestamp(int col) {
- try {
- return new Timestamp(getLong(col));
- } catch (SQLException e) {
- e.printStackTrace();
- }
-
- return null;
+ public Timestamp getTimestamp(int col) throws SQLException {
+ return new Timestamp(getLong(col));
}
public double getDouble(int col) {
@@ -429,7 +419,7 @@ public class TSDBResultSetBlockData {
String charset = TaosGlobalConfig.getCharset();
return new String(dest, charset);
} catch (UnsupportedEncodingException e) {
- e.printStackTrace();
+ throw new RuntimeException(e.getMessage());
}
}
}
diff --git a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBResultSetRowData.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBResultSetRowData.java
index 5cdaa3c70c334bc7bd97be08f2318e6fc548d22a..d8ac10d839651bb476a8688f28917aa356b5b1fe 100644
--- a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBResultSetRowData.java
+++ b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBResultSetRowData.java
@@ -16,6 +16,7 @@ package com.taosdata.jdbc;
import com.taosdata.jdbc.utils.NullType;
+import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.sql.SQLException;
import java.sql.Timestamp;
@@ -378,8 +379,8 @@ public class TSDBResultSetRowData {
// this setByteArr(int, byte[]) to handle NCHAR value, we need to build a String with charsetEncoding by TaosGlobalConfig
try {
data.set(col, new String(value, TaosGlobalConfig.getCharset()));
- } catch (Exception e) {
- e.printStackTrace();
+ } catch (UnsupportedEncodingException e) {
+ throw new RuntimeException(e.getMessage());
}
}
diff --git a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/utils/HttpClientPoolUtil.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/utils/HttpClientPoolUtil.java
index fc116b32c2a154c9479e4933d887ac7ddcedbe9f..cdadcd2d28a03d3db4b490049a4e84f2fc38ea02 100644
--- a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/utils/HttpClientPoolUtil.java
+++ b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/utils/HttpClientPoolUtil.java
@@ -5,6 +5,7 @@ import com.taosdata.jdbc.TSDBErrorNumbers;
import org.apache.http.HeaderElement;
import org.apache.http.HeaderElementIterator;
import org.apache.http.HttpEntity;
+import org.apache.http.NoHttpResponseException;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.*;
diff --git a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/utils/TaosInfo.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/utils/TaosInfo.java
index d4664f2678013b3de87bcd3f0dc24631be511ede..583c2c3236574b8474b834513b28160c37d5b250 100644
--- a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/utils/TaosInfo.java
+++ b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/utils/TaosInfo.java
@@ -16,8 +16,8 @@ public class TaosInfo implements TaosInfoMBean {
MBeanServer server = ManagementFactory.getPlatformMBeanServer();
ObjectName name = new ObjectName("TaosInfoMBean:name=TaosInfo");
server.registerMBean(TaosInfo.getInstance(), name);
- } catch (MalformedObjectNameException | InstanceAlreadyExistsException | MBeanRegistrationException | NotCompliantMBeanException e) {
- e.printStackTrace();
+ } catch (MalformedObjectNameException | InstanceAlreadyExistsException | MBeanRegistrationException | NotCompliantMBeanException ignored) {
+ throw new RuntimeException("registerMBean failed");
}
}
diff --git a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/TSDBConnectionTest.java b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/TSDBConnectionTest.java
index 7cdda572a7e6950005d47798bece6cc5c6fef7d1..64b7ab1cabe2c5815ff87d9881873150f21049c6 100644
--- a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/TSDBConnectionTest.java
+++ b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/TSDBConnectionTest.java
@@ -30,42 +30,6 @@ public class TSDBConnectionTest {
}
}
- @Test
- public void runSubscribe() {
- try {
- // given
- TSDBConnection unwrap = conn.unwrap(TSDBConnection.class);
- TSDBSubscribe subscribe = unwrap.subscribe("topic1", "select * from log.log", false);
- // when
- TSDBResultSet rs = subscribe.consume();
- ResultSetMetaData metaData = rs.getMetaData();
-
- // then
- Assert.assertNotNull(rs);
- Assert.assertEquals(4, metaData.getColumnCount());
- Assert.assertEquals("ts", metaData.getColumnLabel(1));
- Assert.assertEquals("level", metaData.getColumnLabel(2));
- Assert.assertEquals("content", metaData.getColumnLabel(3));
- Assert.assertEquals("ipaddr", metaData.getColumnLabel(4));
- rs.next();
- // row 1
- {
- Assert.assertNotNull(rs.getTimestamp(1));
- Assert.assertNotNull(rs.getTimestamp("ts"));
- Assert.assertNotNull(rs.getByte(2));
- Assert.assertNotNull(rs.getByte("level"));
- Assert.assertNotNull(rs.getString(3));
- Assert.assertNotNull(rs.getString("content"));
- Assert.assertNotNull(rs.getString(4));
- Assert.assertNotNull(rs.getString("ipaddr"));
- }
- subscribe.close(false);
- } catch (SQLException e) {
- e.printStackTrace();
- }
-
- }
-
@Test
public void prepareStatement() throws SQLException {
PreparedStatement pstmt = conn.prepareStatement("select server_status()");
@@ -391,13 +355,9 @@ public class TSDBConnectionTest {
}
@Test
- public void unwrap() {
- try {
- TSDBConnection tsdbConnection = conn.unwrap(TSDBConnection.class);
- Assert.assertNotNull(tsdbConnection);
- } catch (SQLException e) {
- e.printStackTrace();
- }
+ public void unwrap() throws SQLException {
+ TSDBConnection tsdbConnection = conn.unwrap(TSDBConnection.class);
+ Assert.assertNotNull(tsdbConnection);
}
@Test
@@ -406,32 +366,22 @@ public class TSDBConnectionTest {
}
@BeforeClass
- public static void beforeClass() {
- try {
- Class.forName("com.taosdata.jdbc.TSDBDriver");
- Properties properties = new Properties();
- 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");
- conn = DriverManager.getConnection("jdbc:TAOS://" + host + ":6030/log?user=root&password=taosdata", properties);
- // create test database for test cases
- try (Statement stmt = conn.createStatement()) {
- stmt.execute("create database if not exists test");
- }
-
- } catch (ClassNotFoundException | SQLException e) {
- e.printStackTrace();
+ public static void beforeClass() throws SQLException {
+ Properties properties = new Properties();
+ 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");
+ conn = DriverManager.getConnection("jdbc:TAOS://" + host + ":6030/log?user=root&password=taosdata", properties);
+ // create test database for test cases
+ try (Statement stmt = conn.createStatement()) {
+ stmt.execute("create database if not exists test");
}
}
@AfterClass
- public static void afterClass() {
- try {
- if (conn != null)
- conn.close();
- } catch (SQLException e) {
- e.printStackTrace();
- }
+ public static void afterClass() throws SQLException {
+ if (conn != null)
+ conn.close();
}
}
\ No newline at end of file
diff --git a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/TSDBDriverTest.java b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/TSDBDriverTest.java
index 671ecd723d6fea8d6b9b8ccf94cba06689ce26b8..9f297955d687f3cfcc3acef626e1f905ecee6bdf 100644
--- a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/TSDBDriverTest.java
+++ b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/TSDBDriverTest.java
@@ -33,7 +33,6 @@ public class TSDBDriverTest {
conn = DriverManager.getConnection(url);
assertNotNull("failure - connection should not be null", conn);
} catch (SQLException e) {
- e.printStackTrace();
fail("failure - should not throw Exception");
}
}
@@ -49,7 +48,6 @@ public class TSDBDriverTest {
conn = DriverManager.getConnection(jdbcUrl, connProps);
assertNotNull("failure - connection should not be null", conn);
} catch (SQLException e) {
- e.printStackTrace();
fail("failure - should not throw Exception");
}
}
@@ -65,7 +63,6 @@ public class TSDBDriverTest {
conn = DriverManager.getConnection(jdbcUrl, connProps);
assertNotNull("failure - connection should not be null", conn);
} catch (SQLException e) {
- e.printStackTrace();
fail("failure - should not throw Exception");
}
}
@@ -157,16 +154,8 @@ public class TSDBDriverTest {
}
@Test
- public void getParentLogger() throws SQLFeatureNotSupportedException {
+ public void getParentLogger() {
assertNull(new TSDBDriver().getParentLogger());
}
- @BeforeClass
- public static void before() {
- try {
- Class.forName("com.taosdata.jdbc.TSDBDriver");
- } catch (ClassNotFoundException e) {
- e.printStackTrace();
- }
- }
}
\ No newline at end of file
diff --git a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/AuthenticationTest.java b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/AuthenticationTest.java
index 0ea46dade29316b99447a6ea4e372bc8057670e8..5b38f9b0640bb6eec6d1c9749db0abf0388c04ce 100644
--- a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/AuthenticationTest.java
+++ b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/AuthenticationTest.java
@@ -57,44 +57,31 @@ public class AuthenticationTest {
@Ignore
@Test
- public void test() {
+ public void test() throws SQLException {
// change password
- try {
- conn = DriverManager.getConnection("jdbc:TAOS-RS://" + host + ":6041/restful_test?user=" + user + "&password=taosdata");
- Statement stmt = conn.createStatement();
+ String url = "jdbc:TAOS-RS://" + host + ":6041/restful_test?user=" + user + "&password=taosdata";
+ try (Connection conn = DriverManager.getConnection(url);
+ Statement stmt = conn.createStatement();) {
stmt.execute("alter user " + user + " pass '" + password + "'");
- stmt.close();
- conn.close();
- } catch (SQLException e) {
- e.printStackTrace();
}
+
// use new to login and execute query
- try {
- conn = DriverManager.getConnection("jdbc:TAOS-RS://" + host + ":6041/restful_test?user=" + user + "&password=" + password);
- Statement stmt = conn.createStatement();
+ url = "jdbc:TAOS-RS://" + host + ":6041/restful_test?user=" + user + "&password=" + password;
+ try (Connection conn = DriverManager.getConnection(url);
+ Statement stmt = conn.createStatement()) {
stmt.execute("show databases");
ResultSet rs = stmt.getResultSet();
ResultSetMetaData meta = rs.getMetaData();
while (rs.next()) {
- for (int i = 1; i <= meta.getColumnCount(); i++) {
- System.out.print(meta.getColumnLabel(i) + ":" + rs.getString(i) + "\t");
- }
- System.out.println();
}
- } catch (SQLException e) {
- e.printStackTrace();
}
+
// change password back
- try {
- conn = DriverManager.getConnection("jdbc:TAOS-RS://" + host + ":6041/restful_test?user=" + user + "&password=" + password);
- Statement stmt = conn.createStatement();
+ url = "jdbc:TAOS-RS://" + host + ":6041/restful_test?user=" + user + "&password=" + password;
+ try (Connection conn = DriverManager.getConnection(url);
+ Statement stmt = conn.createStatement()) {
stmt.execute("alter user " + user + " pass 'taosdata'");
- stmt.close();
- conn.close();
- } catch (SQLException e) {
- e.printStackTrace();
}
-
}
@Before
diff --git a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/BadLocaleSettingTest.java b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/BadLocaleSettingTest.java
deleted file mode 100644
index 2211e0fa176c67329ac13ee4374daf4667da933b..0000000000000000000000000000000000000000
--- a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/BadLocaleSettingTest.java
+++ /dev/null
@@ -1,59 +0,0 @@
-package com.taosdata.jdbc.cases;
-
-
-import com.taosdata.jdbc.TSDBDriver;
-import org.junit.AfterClass;
-import org.junit.BeforeClass;
-import org.junit.Test;
-
-import java.sql.Connection;
-import java.sql.DriverManager;
-import java.sql.SQLException;
-import java.sql.Statement;
-import java.util.Properties;
-
-public class BadLocaleSettingTest {
-
- private static final String host = "127.0.0.1";
- private static final String dbName = "bad_locale_test";
- private static Connection conn;
-
- @Test
- public void canSetLocale() {
- try {
- Properties properties = new Properties();
- 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");
-
- String url = "jdbc:TAOS://" + host + ":6030/?user=root&password=taosdata";
- conn = DriverManager.getConnection(url, properties);
- Statement stmt = conn.createStatement();
- stmt.execute("drop database if exists " + dbName);
- stmt.execute("create database if not exists " + dbName);
- stmt.execute("use " + dbName);
- stmt.execute("drop table if exists weather");
- stmt.execute("create table weather(ts timestamp, temperature float, humidity int)");
- stmt.executeUpdate("insert into weather values(1624071506435, 12.3, 4)");
- stmt.close();
- } catch (SQLException e) {
- e.printStackTrace();
- }
- }
-
- @BeforeClass
- public static void beforeClass() {
- System.setProperty("sun.jnu.encoding", "ANSI_X3.4-1968");
- System.setProperty("file.encoding", "ANSI_X3.4-1968");
- }
-
- @AfterClass
- public static void afterClass() {
- try {
- if (conn != null)
- conn.close();
- } catch (SQLException e) {
- e.printStackTrace();
- }
- }
-}
\ No newline at end of file
diff --git a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/BatchErrorIgnoreTest.java b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/BatchErrorIgnoreTest.java
index 2934b54b5bd2e7f5450a9a1a00cb5bddca37e945..548c1cff240a811ba998373167588185305a0d59 100644
--- a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/BatchErrorIgnoreTest.java
+++ b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/BatchErrorIgnoreTest.java
@@ -19,16 +19,14 @@ public class BatchErrorIgnoreTest {
IntStream.range(1, 6).mapToObj(i -> "insert into test.t" + i + " values(now, " + i + ")").forEach(sql -> {
try {
stmt.addBatch(sql);
- } catch (SQLException e) {
- e.printStackTrace();
+ } catch (SQLException ignored) {
}
});
stmt.addBatch("insert into t11 values(now, 11)");
IntStream.range(6, 11).mapToObj(i -> "insert into test.t" + i + " values(now, " + i + "),(now + 1s, " + (10 * i) + ")").forEach(sql -> {
try {
stmt.addBatch(sql);
- } catch (SQLException e) {
- e.printStackTrace();
+ } catch (SQLException ignored) {
}
});
stmt.addBatch("select count(*) from test.weather");
@@ -57,23 +55,19 @@ public class BatchErrorIgnoreTest {
IntStream.range(1, 6).mapToObj(i -> "insert into test.t" + i + " values(now, " + i + ")").forEach(sql -> {
try {
stmt.addBatch(sql);
- } catch (SQLException e) {
- e.printStackTrace();
+ } catch (SQLException ignored) {
}
});
stmt.addBatch("insert into t11 values(now, 11)");
IntStream.range(6, 11).mapToObj(i -> "insert into test.t" + i + " values(now, " + i + "),(now + 1s, " + (10 * i) + ")").forEach(sql -> {
try {
stmt.addBatch(sql);
- } catch (SQLException e) {
- e.printStackTrace();
+ } catch (SQLException ignored) {
}
});
stmt.addBatch("select count(*) from test.weather");
results = stmt.executeBatch();
- } catch (SQLException e) {
- e.printStackTrace();
}
// then
@@ -94,10 +88,10 @@ public class BatchErrorIgnoreTest {
}
@Before
- public void before() {
- try {
- Connection conn = DriverManager.getConnection("jdbc:TAOS://" + host + ":6030/?user=root&password=taosdata");
- Statement stmt = conn.createStatement();
+ public void before() throws SQLException {
+ try (Connection conn = DriverManager.getConnection("jdbc:TAOS://" + host + ":6030/?user=root&password=taosdata");
+ Statement stmt = conn.createStatement();) {
+
stmt.execute("use test");
stmt.execute("drop table if exists weather");
stmt.execute("create table weather (ts timestamp, f1 float) tags(t1 int)");
@@ -108,37 +102,25 @@ public class BatchErrorIgnoreTest {
e.printStackTrace();
}
});
- stmt.close();
- conn.close();
- } catch (SQLException e) {
- e.printStackTrace();
}
}
@BeforeClass
- public static void beforeClass() {
- try {
- Connection conn = DriverManager.getConnection("jdbc:TAOS://" + host + ":6030/?user=root&password=taosdata");
- Statement stmt = conn.createStatement();
+ public static void beforeClass() throws SQLException {
+ try (Connection conn = DriverManager.getConnection("jdbc:TAOS://" + host + ":6030/?user=root&password=taosdata");
+ Statement stmt = conn.createStatement()) {
+
stmt.execute("drop database if exists test");
stmt.execute("create database if not exists test");
- stmt.close();
- conn.close();
- } catch (SQLException e) {
- e.printStackTrace();
}
}
@AfterClass
- public static void afterClass() {
- try {
- Connection conn = DriverManager.getConnection("jdbc:TAOS://" + host + ":6030/?user=root&password=taosdata");
- Statement stmt = conn.createStatement();
+ public static void afterClass() throws SQLException {
+ try (Connection conn = DriverManager.getConnection("jdbc:TAOS://" + host + ":6030/?user=root&password=taosdata");
+ Statement stmt = conn.createStatement()) {
+
stmt.execute("drop database if exists test");
- stmt.close();
- conn.close();
- } catch (SQLException e) {
- e.printStackTrace();
}
}
}
diff --git a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/ConnectMultiTaosdByRestfulWithDifferentTokenTest.java b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/ConnectMultiTaosdByRestfulWithDifferentTokenTest.java
index fcb6ab7aaff2406acf59262a9cdef90b628b8934..8299cfebec6ba54be42dc1fbe8dcff1b14034860 100644
--- a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/ConnectMultiTaosdByRestfulWithDifferentTokenTest.java
+++ b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/ConnectMultiTaosdByRestfulWithDifferentTokenTest.java
@@ -20,22 +20,20 @@ public class ConnectMultiTaosdByRestfulWithDifferentTokenTest {
private Connection conn2;
@Test
- public void test() {
+ public void test() throws SQLException {
//when
executeSelectStatus(conn1);
executeSelectStatus(conn2);
executeSelectStatus(conn1);
}
- private void executeSelectStatus(Connection connection) {
+ private void executeSelectStatus(Connection connection) throws SQLException {
try (Statement stmt = connection.createStatement()) {
ResultSet rs = stmt.executeQuery("select server_status()");
ResultSetMetaData meta = rs.getMetaData();
Assert.assertNotNull(meta);
while (rs.next()) {
}
- } catch (SQLException e) {
- e.printStackTrace();
}
}
diff --git a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/ConnectWrongDatabaseTest.java b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/ConnectWrongDatabaseTest.java
index d8d8f1eae42f555b2bc0be12e8a3a943071da3c6..d60ee14fbc87ba5d2bd2e851b5195b513fc4e028 100644
--- a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/ConnectWrongDatabaseTest.java
+++ b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/ConnectWrongDatabaseTest.java
@@ -1,7 +1,5 @@
package com.taosdata.jdbc.cases;
-import com.taosdata.jdbc.TSDBErrorNumbers;
-import org.junit.Assert;
import org.junit.Test;
import java.sql.DriverManager;
@@ -9,16 +7,9 @@ import java.sql.SQLException;
public class ConnectWrongDatabaseTest {
- @Test
- public void connect() {
- try {
- Class.forName("com.taosdata.jdbc.TSDBDriver");
- DriverManager.getConnection("jdbc:TAOS://localhost:6030/wrong_db?user=root&password=taosdata");
- } catch (ClassNotFoundException e) {
- e.printStackTrace();
- } catch (SQLException e) {
- Assert.assertEquals(TSDBErrorNumbers.ERROR_JNI_CONNECTION_NULL, e.getErrorCode());
- }
+ @Test(expected = SQLException.class)
+ public void connect() throws SQLException {
+ DriverManager.getConnection("jdbc:TAOS://localhost:6030/wrong_db?user=root&password=taosdata");
}
}
diff --git a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/DatetimeBefore1970Test.java b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/DatetimeBefore1970Test.java
index 14c76985484857a92e174955c943caa21bdd2e72..bfffaa4a129dc7fe19a92c34abbcc886d5e4e22f 100644
--- a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/DatetimeBefore1970Test.java
+++ b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/DatetimeBefore1970Test.java
@@ -11,7 +11,7 @@ public class DatetimeBefore1970Test {
private Connection conn;
@Test
- public void test() {
+ public void test() throws SQLException {
try (Statement stmt = conn.createStatement()) {
// given
stmt.executeUpdate("insert into weather(ts) values('1969-12-31 23:59:59.999')");
@@ -45,36 +45,25 @@ public class DatetimeBefore1970Test {
// then
ts = rs.getTimestamp("ts");
Assert.assertEquals("1970-01-01 07:59:59.999", TimestampUtil.longToDatetime(ts.getTime()));
-
- } catch (SQLException e) {
- e.printStackTrace();
}
}
@Before
- public void before() {
- try {
- conn = DriverManager.getConnection("jdbc:TAOS://" + host + ":6030/?user=root&password=taosdata");
- Statement stmt = conn.createStatement();
- stmt.execute("drop database if exists test_timestamp");
- stmt.execute("create database if not exists test_timestamp keep 36500");
- stmt.execute("use test_timestamp");
- stmt.execute("create table weather(ts timestamp,f1 float)");
- stmt.close();
- } catch (SQLException e) {
- e.printStackTrace();
- }
+ public void before() throws SQLException {
+ conn = DriverManager.getConnection("jdbc:TAOS://" + host + ":6030/?user=root&password=taosdata");
+ Statement stmt = conn.createStatement();
+ stmt.execute("drop database if exists test_timestamp");
+ stmt.execute("create database if not exists test_timestamp keep 36500");
+ stmt.execute("use test_timestamp");
+ stmt.execute("create table weather(ts timestamp,f1 float)");
+ stmt.close();
}
@After
- public void after() {
- try {
- Statement stmt = conn.createStatement();
- stmt.execute("drop database if exists test_timestamp");
- if (conn != null)
- conn.close();
- } catch (SQLException e) {
- e.printStackTrace();
- }
+ public void after() throws SQLException {
+ Statement stmt = conn.createStatement();
+ stmt.execute("drop database if exists test_timestamp");
+ if (conn != null)
+ conn.close();
}
}
diff --git a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/ImportTest.java b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/ImportTest.java
index 1297a6b4c4eb0eca208950363c13e9bb4d1cd3a9..a8fdf4f2caa88d2651bebf2a1c46b95644b488d2 100644
--- a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/ImportTest.java
+++ b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/ImportTest.java
@@ -17,29 +17,6 @@ public class ImportTest {
static String host = "127.0.0.1";
private static long ts;
- @BeforeClass
- public static void before() {
- try {
- Properties properties = new Properties();
- 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);
-
- Statement stmt = connection.createStatement();
- stmt.execute("create database if not exists " + dbName);
- stmt.execute("create table if not exists " + dbName + "." + tName + " (ts timestamp, k int, v int)");
- stmt.close();
-
- ts = System.currentTimeMillis();
- } catch (SQLException e) {
- e.printStackTrace();
- }
-
- }
-
@Test
public void case001_insertData() throws Exception {
try (Statement stmt = connection.createStatement()) {
@@ -52,28 +29,25 @@ public class ImportTest {
}
@Test
- public void case002_checkSum() {
+ public void case002_checkSum() throws SQLException {
Assert.assertEquals(50, select());
}
- private int select() {
+ private int select() throws SQLException {
int count = 0;
try (Statement stmt = connection.createStatement()) {
-
String sql = "select * from " + dbName + "." + tName;
ResultSet rs = stmt.executeQuery(sql);
while (rs.next()) {
count++;
}
rs.close();
- } catch (SQLException e) {
- e.printStackTrace();
}
return count;
}
@Test
- public void case003_importData() {
+ public void case003_importData() throws SQLException {
// 避免时间重复
try (Statement stmt = connection.createStatement()) {
StringBuilder sqlBuilder = new StringBuilder("import into ").append(dbName).append(".").append(tName).append(" values ");
@@ -84,27 +58,40 @@ public class ImportTest {
}
int rows = stmt.executeUpdate(sqlBuilder.toString());
assertEquals(50, rows);
- } catch (SQLException e) {
- e.printStackTrace();
}
}
@Test
- public void case004_checkSum() {
+ public void case004_checkSum() throws SQLException {
Assert.assertEquals(100, select());
}
+
+ @BeforeClass
+ public static void before() throws SQLException {
+ Properties properties = new Properties();
+ 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);
+
+ Statement stmt = connection.createStatement();
+ stmt.execute("create database if not exists " + dbName);
+ stmt.execute("create table if not exists " + dbName + "." + tName + " (ts timestamp, k int, v int)");
+ stmt.close();
+
+ ts = System.currentTimeMillis();
+ }
+
@AfterClass
- public static void close() {
- try {
- if (connection != null) {
- Statement statement = connection.createStatement();
- statement.executeUpdate("drop database " + dbName);
- statement.close();
- connection.close();
- }
- } catch (SQLException e) {
- e.printStackTrace();
+ public static void close() throws SQLException {
+ if (connection != null) {
+ Statement statement = connection.createStatement();
+ statement.executeUpdate("drop database " + dbName);
+ statement.close();
+ connection.close();
}
}
}
diff --git a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/MicroSecondPrecisionRestfulTest.java b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/MicroSecondPrecisionRestfulTest.java
index 7e9f04cd6360431a3fe6c29a2f0eb61fbdc9e7c4..f418436a4afac5f16b27789eb43081f131bf1f92 100644
--- a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/MicroSecondPrecisionRestfulTest.java
+++ b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/MicroSecondPrecisionRestfulTest.java
@@ -23,7 +23,7 @@ public class MicroSecondPrecisionRestfulTest {
private static Connection conn3;
@Test
- public void testCase1() {
+ public void testCase1() throws SQLException {
try (Statement stmt = conn1.createStatement()) {
ResultSet rs = stmt.executeQuery("select last_row(ts) from " + ms_timestamp_db + ".weather");
rs.next();
@@ -31,13 +31,11 @@ public class MicroSecondPrecisionRestfulTest {
Assert.assertEquals(timestamp1, ts);
ts = rs.getLong(1);
Assert.assertEquals(timestamp1, ts);
- } catch (SQLException e) {
- e.printStackTrace();
}
}
@Test
- public void testCase2() {
+ public void testCase2() throws SQLException {
try (Statement stmt = conn1.createStatement()) {
ResultSet rs = stmt.executeQuery("select last_row(ts) from " + us_timestamp_db + ".weather");
rs.next();
@@ -50,13 +48,11 @@ public class MicroSecondPrecisionRestfulTest {
ts = rs.getLong(1);
Assert.assertEquals(timestamp1, ts);
- } catch (SQLException e) {
- e.printStackTrace();
}
}
@Test
- public void testCase3() {
+ public void testCase3() throws SQLException {
try (Statement stmt = conn2.createStatement()) {
ResultSet rs = stmt.executeQuery("select last_row(ts) from " + ms_timestamp_db + ".weather");
rs.next();
@@ -65,13 +61,11 @@ public class MicroSecondPrecisionRestfulTest {
Assert.assertEquals(timestamp1, ts);
ts = rs.getLong(1);
Assert.assertEquals(timestamp1, ts);
- } catch (SQLException e) {
- e.printStackTrace();
}
}
@Test
- public void testCase4() {
+ public void testCase4() throws SQLException {
try (Statement stmt = conn2.createStatement()) {
ResultSet rs = stmt.executeQuery("select last_row(ts) from " + us_timestamp_db + ".weather");
rs.next();
@@ -84,13 +78,11 @@ public class MicroSecondPrecisionRestfulTest {
ts = rs.getLong(1);
Assert.assertEquals(timestamp1, ts);
- } catch (SQLException e) {
- e.printStackTrace();
}
}
@Test
- public void testCase5() {
+ public void testCase5() throws SQLException {
try (Statement stmt = conn3.createStatement()) {
ResultSet rs = stmt.executeQuery("select last_row(ts) from " + ms_timestamp_db + ".weather");
rs.next();
@@ -99,13 +91,11 @@ public class MicroSecondPrecisionRestfulTest {
Assert.assertEquals(timestamp1, ts);
ts = rs.getLong(1);
Assert.assertEquals(timestamp1, ts);
- } catch (SQLException e) {
- e.printStackTrace();
}
}
@Test
- public void testCase6() {
+ public void testCase6() throws SQLException {
try (Statement stmt = conn3.createStatement()) {
ResultSet rs = stmt.executeQuery("select last_row(ts) from " + us_timestamp_db + ".weather");
rs.next();
@@ -118,8 +108,6 @@ public class MicroSecondPrecisionRestfulTest {
ts = rs.getLong(1);
Assert.assertEquals(timestamp1, ts);
- } catch (SQLException e) {
- e.printStackTrace();
}
}
@@ -154,16 +142,12 @@ public class MicroSecondPrecisionRestfulTest {
}
@AfterClass
- public static void afterClass() {
- try {
- if (conn1 != null)
- conn1.close();
- if (conn2 != null)
- conn2.close();
- if (conn3 != null)
- conn3.close();
- } catch (SQLException e) {
- e.printStackTrace();
- }
+ public static void afterClass() throws SQLException {
+ if (conn1 != null)
+ conn1.close();
+ if (conn2 != null)
+ conn2.close();
+ if (conn3 != null)
+ conn3.close();
}
}
diff --git a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/MultiConnectionWithDifferentDbTest.java b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/MultiConnectionWithDifferentDbTest.java
index 18a2c32aca0535567dd42e886bc87ae618596a40..0bf8334079e630bf61b7955a37c74401da24a947 100644
--- a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/MultiConnectionWithDifferentDbTest.java
+++ b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/MultiConnectionWithDifferentDbTest.java
@@ -9,8 +9,7 @@ import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.*;
public class MultiConnectionWithDifferentDbTest {
@@ -26,16 +25,17 @@ public class MultiConnectionWithDifferentDbTest {
@Override
public void run() {
for (int j = 0; j < 10; j++) {
- queryDb();
try {
+ queryDb();
TimeUnit.SECONDS.sleep(1);
- } catch (InterruptedException e) {
- e.printStackTrace();
+ } catch (InterruptedException ignored) {
+ } catch (SQLException throwables) {
+ fail();
}
}
}
- private void queryDb() {
+ private void queryDb() throws SQLException {
String url = "jdbc:TAOS-RS://" + host + ":6041/db" + i + "?user=root&password=taosdata";
try (Connection connection = DriverManager.getConnection(url)) {
Statement stmt = connection.createStatement();
@@ -54,8 +54,6 @@ public class MultiConnectionWithDifferentDbTest {
assertEquals(loc, loc_actual);
stmt.close();
- } catch (SQLException e) {
- e.printStackTrace();
}
}
}, "thread-" + i)).collect(Collectors.toList());
@@ -73,12 +71,10 @@ public class MultiConnectionWithDifferentDbTest {
}
@Before
- public void before() {
+ public void before() throws SQLException {
ts = System.currentTimeMillis();
- try {
- Connection conn = DriverManager.getConnection("jdbc:TAOS-RS://" + host + ":6041/?user=root&password=taosdata");
-
+ try (Connection conn = DriverManager.getConnection("jdbc:TAOS-RS://" + host + ":6041/?user=root&password=taosdata")) {
Statement stmt = conn.createStatement();
stmt.execute("drop database if exists " + db1);
stmt.execute("create database if not exists " + db1);
@@ -91,10 +87,6 @@ public class MultiConnectionWithDifferentDbTest {
stmt.execute("use " + db2);
stmt.execute("create table weather(ts timestamp, f1 int) tags(loc nchar(10))");
stmt.execute("insert into t1 using weather tags('shanghai') values(" + ts + ", 2)");
-
- conn.close();
- } catch (SQLException e) {
- e.printStackTrace();
}
}
diff --git a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/MultiThreadsWithSameStatementTest.java b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/MultiThreadsWithSameStatementTest.java
deleted file mode 100644
index 73da79f357b1c066943e2f39bf9f8bdc86382d7e..0000000000000000000000000000000000000000
--- a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/MultiThreadsWithSameStatementTest.java
+++ /dev/null
@@ -1,85 +0,0 @@
-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 MultiThreadsWithSameStatementTest {
-
- private static class Service {
- public Connection conn;
- public Statement stmt;
-
- public Service() {
- try {
- 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 (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();
- }
- 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() {
- }
-}
diff --git a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/NanoSecondTimestampJNITest.java b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/NanoSecondTimestampJNITest.java
index 4f2c87966ad6bb8390bab47b795e7d952725baf5..a84f5233974e9bd9acdbbe3ca8ae0404c11b34a1 100644
--- a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/NanoSecondTimestampJNITest.java
+++ b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/NanoSecondTimestampJNITest.java
@@ -17,7 +17,7 @@ public class NanoSecondTimestampJNITest {
private static Connection conn;
@Test
- public void insertUsingLongValue() {
+ public void insertUsingLongValue() throws SQLException {
// given
long ms = System.currentTimeMillis();
long ns = ms * 1000_000 + random.nextInt(1000_000);
@@ -26,8 +26,6 @@ public class NanoSecondTimestampJNITest {
int ret = 0;
try (Statement stmt = conn.createStatement()) {
ret = stmt.executeUpdate("insert into weather(ts, temperature, humidity) values(" + ns + ", 12.3, 4)");
- } catch (SQLException e) {
- e.printStackTrace();
}
// then
@@ -35,15 +33,13 @@ public class NanoSecondTimestampJNITest {
}
@Test
- public void insertUsingStringValue() {
+ public void insertUsingStringValue() throws SQLException {
// given
// when
int ret = 0;
try (Statement stmt = conn.createStatement()) {
ret = stmt.executeUpdate("insert into weather(ts, temperature, humidity) values('2021-01-01 12:00:00.123456789', 12.3, 4)");
- } catch (SQLException e) {
- e.printStackTrace();
}
// then
@@ -51,7 +47,7 @@ public class NanoSecondTimestampJNITest {
}
@Test
- public void insertUsingTimestampValue() {
+ public void insertUsingTimestampValue() throws SQLException {
// given
long epochSec = System.currentTimeMillis() / 1000;
long nanoAdjustment = random.nextInt(1000_000_000);
@@ -65,8 +61,6 @@ public class NanoSecondTimestampJNITest {
pstmt.setFloat(2, 12.34f);
pstmt.setInt(3, 55);
ret = pstmt.executeUpdate();
- } catch (SQLException e) {
- e.printStackTrace();
}
// then
@@ -85,8 +79,6 @@ public class NanoSecondTimestampJNITest {
stmt.executeUpdate("insert into weather(ts, temperature, humidity) values(" + ns + ", 12.3, 4)");
rs = stmt.executeQuery("select * from weather");
rs.next();
- } catch (SQLException e) {
- e.printStackTrace();
}
// then
@@ -102,13 +94,11 @@ public class NanoSecondTimestampJNITest {
String timestampStr = "2021-01-01 12:00:00.123456789";
// when
- ResultSet rs = null;
+ ResultSet rs;
try (Statement stmt = conn.createStatement()) {
stmt.executeUpdate("insert into weather(ts, temperature, humidity) values('" + timestampStr + "', 12.3, 4)");
rs = stmt.executeQuery("select * from weather");
rs.next();
- } catch (SQLException e) {
- e.printStackTrace();
}
// then
@@ -133,8 +123,6 @@ public class NanoSecondTimestampJNITest {
pstmt.setFloat(2, 12.34f);
pstmt.setInt(3, 55);
pstmt.executeUpdate();
- } catch (SQLException e) {
- e.printStackTrace();
}
// when
@@ -142,8 +130,6 @@ public class NanoSecondTimestampJNITest {
try (Statement stmt = conn.createStatement()) {
rs = stmt.executeQuery("select * from weather");
rs.next();
- } catch (SQLException e) {
- e.printStackTrace();
}
// then
@@ -156,26 +142,21 @@ public class NanoSecondTimestampJNITest {
}
@Before
- public void before() {
+ public void before() throws SQLException {
try (Statement stmt = conn.createStatement()) {
stmt.execute("drop table if exists weather");
stmt.execute("create table weather(ts timestamp, temperature float, humidity int)");
- } catch (SQLException e) {
- e.printStackTrace();
}
}
@BeforeClass
- public static void beforeClass() {
+ public static void beforeClass() throws SQLException {
final String url = "jdbc:TAOS://" + host + ":6030/?user=root&password=taosdata";
- try {
- conn = DriverManager.getConnection(url);
- Statement stmt = conn.createStatement();
+ conn = DriverManager.getConnection(url);
+ try (Statement stmt = conn.createStatement()) {
stmt.execute("drop database if exists " + dbname);
stmt.execute("create database if not exists " + dbname + " precision 'ns'");
stmt.execute("use " + dbname);
- } catch (SQLException e) {
- e.printStackTrace();
}
}
diff --git a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/NanoSecondTimestampRestfulTest.java b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/NanoSecondTimestampRestfulTest.java
index 4271f918b9b096000cc59b730d7b70f032a0ab29..c8aaf5c6788d18e782e431ba4ed97fb69f4702ab 100644
--- a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/NanoSecondTimestampRestfulTest.java
+++ b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/NanoSecondTimestampRestfulTest.java
@@ -17,7 +17,7 @@ public class NanoSecondTimestampRestfulTest {
private static Connection conn;
@Test
- public void insertUsingLongValue() {
+ public void insertUsingLongValue() throws SQLException {
// given
long ms = System.currentTimeMillis();
long ns = ms * 1000_000 + random.nextInt(1000_000);
@@ -26,8 +26,6 @@ public class NanoSecondTimestampRestfulTest {
int ret = 0;
try (Statement stmt = conn.createStatement()) {
ret = stmt.executeUpdate("insert into weather(ts, temperature, humidity) values(" + ns + ", 12.3, 4)");
- } catch (SQLException e) {
- e.printStackTrace();
}
// then
@@ -35,15 +33,13 @@ public class NanoSecondTimestampRestfulTest {
}
@Test
- public void insertUsingStringValue() {
+ public void insertUsingStringValue() throws SQLException {
// given
// when
int ret = 0;
try (Statement stmt = conn.createStatement()) {
ret = stmt.executeUpdate("insert into weather(ts, temperature, humidity) values('2021-01-01 12:00:00.123456789', 12.3, 4)");
- } catch (SQLException e) {
- e.printStackTrace();
}
// then
@@ -51,7 +47,7 @@ public class NanoSecondTimestampRestfulTest {
}
@Test
- public void insertUsingTimestampValue() {
+ public void insertUsingTimestampValue() throws SQLException {
// given
long epochSec = System.currentTimeMillis() / 1000;
long nanoAdjustment = random.nextInt(1000_000_000);
@@ -65,8 +61,6 @@ public class NanoSecondTimestampRestfulTest {
pstmt.setFloat(2, 12.34f);
pstmt.setInt(3, 55);
ret = pstmt.executeUpdate();
- } catch (SQLException e) {
- e.printStackTrace();
}
// then
@@ -80,13 +74,11 @@ public class NanoSecondTimestampRestfulTest {
long ns = ms * 1000_000L + random.nextInt(1000_000);
// when
- ResultSet rs = null;
+ ResultSet rs;
try (Statement stmt = conn.createStatement()) {
stmt.executeUpdate("insert into weather(ts, temperature, humidity) values(" + ns + ", 12.3, 4)");
rs = stmt.executeQuery("select * from weather");
rs.next();
- } catch (SQLException e) {
- e.printStackTrace();
}
// then
@@ -102,13 +94,11 @@ public class NanoSecondTimestampRestfulTest {
String timestampStr = "2021-01-01 12:00:00.123456789";
// when
- ResultSet rs = null;
+ ResultSet rs;
try (Statement stmt = conn.createStatement()) {
stmt.executeUpdate("insert into weather(ts, temperature, humidity) values('" + timestampStr + "', 12.3, 4)");
rs = stmt.executeQuery("select * from weather");
rs.next();
- } catch (SQLException e) {
- e.printStackTrace();
}
// then
@@ -133,8 +123,6 @@ public class NanoSecondTimestampRestfulTest {
pstmt.setFloat(2, 12.34f);
pstmt.setInt(3, 55);
pstmt.executeUpdate();
- } catch (SQLException e) {
- e.printStackTrace();
}
// when
@@ -142,8 +130,6 @@ public class NanoSecondTimestampRestfulTest {
try (Statement stmt = conn.createStatement()) {
rs = stmt.executeQuery("select * from weather");
rs.next();
- } catch (SQLException e) {
- e.printStackTrace();
}
// then
@@ -156,26 +142,21 @@ public class NanoSecondTimestampRestfulTest {
}
@Before
- public void before() {
+ public void before() throws SQLException {
try (Statement stmt = conn.createStatement()) {
stmt.execute("drop table if exists weather");
stmt.execute("create table weather(ts timestamp, temperature float, humidity int)");
- } catch (SQLException e) {
- e.printStackTrace();
}
}
@BeforeClass
- public static void beforeClass() {
+ public static void beforeClass() throws SQLException {
final String url = "jdbc:TAOS-RS://" + host + ":6041/?user=root&password=taosdata";
- try {
- conn = DriverManager.getConnection(url);
- Statement stmt = conn.createStatement();
+ conn = DriverManager.getConnection(url);
+ try (Statement stmt = conn.createStatement()) {
stmt.execute("drop database if exists " + dbname);
stmt.execute("create database if not exists " + dbname + " precision 'ns'");
stmt.execute("use " + dbname);
- } catch (SQLException e) {
- e.printStackTrace();
}
}
diff --git a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/NullValueInResultSetJNITest.java b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/NullValueInResultSetJNITest.java
index ae0241bf31eea85083bf102c4123f7e30c2bd693..6efd9f5ebee29a122c2106439117738c44241597 100644
--- a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/NullValueInResultSetJNITest.java
+++ b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/NullValueInResultSetJNITest.java
@@ -12,15 +12,13 @@ public class NullValueInResultSetJNITest {
Connection conn;
@Test
- public void test() {
+ public void test() throws SQLException {
try (Statement stmt = conn.createStatement()) {
ResultSet rs = stmt.executeQuery("select * from weather");
ResultSetMetaData meta = rs.getMetaData();
while (rs.next()) {
}
- } catch (SQLException e) {
- e.printStackTrace();
}
}
@@ -42,18 +40,12 @@ public class NullValueInResultSetJNITest {
stmt.executeUpdate("insert into weather(ts, f7) values(now+7s, true)");
stmt.executeUpdate("insert into weather(ts, f8) values(now+8s, 'hello')");
stmt.executeUpdate("insert into weather(ts, f9) values(now+9s, '涛思数据')");
- } catch (SQLException e) {
- e.printStackTrace();
}
}
@After
- public void after() {
- try {
- if (conn != null)
- conn.close();
- } catch (SQLException e) {
- e.printStackTrace();
- }
+ public void after() throws SQLException {
+ if (conn != null)
+ conn.close();
}
}
diff --git a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/NullValueInResultSetRestfulTest.java b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/NullValueInResultSetRestfulTest.java
index 7fbb30a5244a53129807cd76472674ff1cfd6ae4..f331a58583db832124465492d07f24f1772348ce 100644
--- a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/NullValueInResultSetRestfulTest.java
+++ b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/NullValueInResultSetRestfulTest.java
@@ -12,7 +12,7 @@ public class NullValueInResultSetRestfulTest {
Connection conn;
@Test
- public void test() {
+ public void test() throws SQLException {
try (Statement stmt = conn.createStatement()) {
ResultSet rs = stmt.executeQuery("select * from weather");
ResultSetMetaData meta = rs.getMetaData();
@@ -21,9 +21,6 @@ public class NullValueInResultSetRestfulTest {
Object value = rs.getObject(i);
}
}
-
- } catch (SQLException e) {
- e.printStackTrace();
}
}
@@ -45,18 +42,12 @@ public class NullValueInResultSetRestfulTest {
stmt.executeUpdate("insert into weather(ts, f7) values(now+7s, true)");
stmt.executeUpdate("insert into weather(ts, f8) values(now+8s, 'hello')");
stmt.executeUpdate("insert into weather(ts, f9) values(now+9s, '涛思数据')");
- } catch (SQLException e) {
- e.printStackTrace();
}
}
@After
- public void after() {
- try {
- if (conn != null)
- conn.close();
- } catch (SQLException e) {
- e.printStackTrace();
- }
+ public void after() throws SQLException {
+ if (conn != null)
+ conn.close();
}
}
diff --git a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/PreparedStatementBatchInsertRestfulTest.java b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/PreparedStatementBatchInsertRestfulTest.java
index 90b285381a2ab57b170da327a95dde4c8991ce21..85fbeef1b589434dc17267af20510bc2a8ebd554 100644
--- a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/PreparedStatementBatchInsertRestfulTest.java
+++ b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/PreparedStatementBatchInsertRestfulTest.java
@@ -20,7 +20,7 @@ public class PreparedStatementBatchInsertRestfulTest {
private Connection conn;
@Test
- public void test() {
+ public void test() throws SQLException {
// given
long ts = System.currentTimeMillis();
List