diff --git a/Jenkinsfile b/Jenkinsfile
index ebac32cb24..73bb832d8e 100644
--- a/Jenkinsfile
+++ b/Jenkinsfile
@@ -41,13 +41,10 @@ def pre_test(){
cd ${WKC}
git checkout develop
- git reset --hard HEAD~10
+ git reset --hard HEAD~10 >/dev/null
git pull
- git fetch
- git checkout ${CHANGE_BRANCH}
- git reset --hard HEAD~10
- git pull
- git merge develop
+ git fetch origin +refs/pull/${CHANGE_ID}/merge
+ git checkout -qf FETCH_HEAD
cd ${WK}
git reset --hard HEAD~10
git checkout develop
@@ -87,11 +84,14 @@ pipeline {
steps {
pre_test()
- sh '''
- cd ${WKC}/tests
- find pytest -name '*'sql|xargs rm -rf
- ./test-all.sh p1
- date'''
+ timeout(time: 90, unit: 'MINUTES'){
+ sh '''
+ cd ${WKC}/tests
+ find pytest -name '*'sql|xargs rm -rf
+ ./test-all.sh p1
+ date'''
+ }
+
}
}
stage('python_2') {
@@ -112,12 +112,14 @@ pipeline {
}
stage('test_b1') {
agent{label 'b1'}
- steps {
- pre_test()
- sh '''
- cd ${WKC}/tests
- ./test-all.sh b1fq
- date'''
+ steps {
+ timeout(time: 90, unit: 'MINUTES'){
+ pre_test()
+ sh '''
+ cd ${WKC}/tests
+ ./test-all.sh b1fq
+ date'''
+ }
}
}
@@ -137,12 +139,14 @@ pipeline {
./handle_crash_gen_val_log.sh
'''
}
- sh '''
- date
- cd ${WKC}/tests
- ./test-all.sh b2fq
- date
- '''
+ timeout(time: 90, unit: 'MINUTES'){
+ sh '''
+ date
+ cd ${WKC}/tests
+ ./test-all.sh b2fq
+ date
+ '''
+ }
}
}
@@ -157,12 +161,14 @@ pipeline {
./valgrind-test.sh 2>&1 > mem-error-out.log
./handle_val_log.sh
'''
- }
- sh '''
- date
- cd ${WKC}/tests
- ./test-all.sh b3fq
- date'''
+ }
+ timeout(time: 90, unit: 'MINUTES'){
+ sh '''
+ date
+ cd ${WKC}/tests
+ ./test-all.sh b3fq
+ date'''
+ }
}
}
diff --git a/cmake/install.inc b/cmake/install.inc
index b0e5c71022..a5b01f43cb 100755
--- a/cmake/install.inc
+++ b/cmake/install.inc
@@ -32,7 +32,7 @@ ELSEIF (TD_WINDOWS)
#INSTALL(TARGETS taos RUNTIME DESTINATION driver)
#INSTALL(TARGETS shell RUNTIME DESTINATION .)
IF (TD_MVN_INSTALLED)
- INSTALL(FILES ${LIBRARY_OUTPUT_PATH}/taos-jdbcdriver-2.0.16-dist.jar DESTINATION connector/jdbc)
+ INSTALL(FILES ${LIBRARY_OUTPUT_PATH}/taos-jdbcdriver-2.0.17-dist.jar DESTINATION connector/jdbc)
ENDIF ()
ELSEIF (TD_DARWIN)
SET(TD_MAKE_INSTALL_SH "${TD_COMMUNITY_DIR}/packaging/tools/make_install.sh")
diff --git a/cmake/version.inc b/cmake/version.inc
old mode 100644
new mode 100755
index 0509a5ce1b..f9927bf1c6
--- a/cmake/version.inc
+++ b/cmake/version.inc
@@ -16,13 +16,25 @@ ENDIF ()
IF (DEFINED GITINFO)
SET(TD_VER_GIT ${GITINFO})
ELSE ()
- SET(TD_VER_GIT "community")
+ execute_process(
+ COMMAND git log -1 --format=%H
+ WORKING_DIRECTORY ${TD_COMMUNITY_DIR}
+ OUTPUT_VARIABLE GIT_COMMITID
+ )
+ string (REGEX REPLACE "[\n\t\r]" "" GIT_COMMITID ${GIT_COMMITID})
+ SET(TD_VER_GIT ${GIT_COMMITID})
ENDIF ()
IF (DEFINED GITINFOI)
SET(TD_VER_GIT_INTERNAL ${GITINFOI})
ELSE ()
- SET(TD_VER_GIT_INTERNAL "internal")
+ execute_process(
+ COMMAND git log -1 --format=%H
+ WORKING_DIRECTORY ${PROJECT_SOURCE_DIR}
+ OUTPUT_VARIABLE GIT_COMMITID
+ )
+ string (REGEX REPLACE "[\n\t\r]" "" GIT_COMMITID ${GIT_COMMITID})
+ SET(TD_VER_GIT_INTERNAL ${GIT_COMMITID})
ENDIF ()
IF (DEFINED VERDATE)
diff --git a/documentation20/webdocs/assets/tdengine-jdbc-connector.png b/documentation20/webdocs/assets/tdengine-jdbc-connector.png
new file mode 100644
index 0000000000..fdf1dd3fcc
Binary files /dev/null and b/documentation20/webdocs/assets/tdengine-jdbc-connector.png differ
diff --git a/documentation20/webdocs/markdowndocs/Getting Started-ch.md b/documentation20/webdocs/markdowndocs/Getting Started-ch.md
index b53c014ba6..b8b298b950 100644
--- a/documentation20/webdocs/markdowndocs/Getting Started-ch.md
+++ b/documentation20/webdocs/markdowndocs/Getting Started-ch.md
@@ -179,7 +179,7 @@ taos> select avg(f1), max(f2), min(f3) from test.t10 interval(10s);
-## **支持平台列表**
+## 支持平台列表
### TDengine服务器支持的平台列表
diff --git a/documentation20/webdocs/markdowndocs/Queries-ch.md b/documentation20/webdocs/markdowndocs/Queries-ch.md
index 960bb39e63..839809ccba 100644
--- a/documentation20/webdocs/markdowndocs/Queries-ch.md
+++ b/documentation20/webdocs/markdowndocs/Queries-ch.md
@@ -9,7 +9,7 @@
TDengine 采用 SQL 作为查询语言。应用程序可以通过 C/C++, Java, Go, Python 连接器发送 SQL 语句,用户可以通过 TDengine 提供的命令行(Command Line Interface, CLI)工具 TAOS Shell 手动执行 SQL 即席查询(Ad-Hoc Query)。TDengine 支持如下查询功能:
- 单列、多列数据查询
-- 标签和数值的多种过滤条件:\>, \<, =, \<>, like 等
+- 标签和数值的多种过滤条件:>, <, =, <>, like 等
- 聚合结果的分组(Group by)、排序(Order by)、约束输出(Limit/Offset)
- 数值列及聚合结果的四则运算
- 时间戳对齐的连接查询(Join Query: 隐式连接)操作
diff --git a/documentation20/webdocs/markdowndocs/TAOS SQL-ch.md b/documentation20/webdocs/markdowndocs/TAOS SQL-ch.md
index 4563b5b5fc..3333bbc450 100644
--- a/documentation20/webdocs/markdowndocs/TAOS SQL-ch.md
+++ b/documentation20/webdocs/markdowndocs/TAOS SQL-ch.md
@@ -58,26 +58,26 @@ TDengine缺省的时间戳是毫秒精度,但通过修改配置参数enableMic
- **创建数据库**
- ```mysql
- CREATE DATABASE [IF NOT EXISTS] db_name [KEEP keep] [UPDATE 1];
- ```
- 说明:
-
- 1) KEEP是该数据库的数据保留多长天数,缺省是3650天(10年),数据库会自动删除超过时限的数据;
-
- 2) UPDATE 标志数据库支持更新相同时间戳数据;
-
- 3) 数据库名最大长度为33;
-
- 4) 一条SQL 语句的最大长度为65480个字符;
-
- 5) 数据库还有更多与存储相关的配置参数,请参见系统管理。
+ ```mysql
+ CREATE DATABASE [IF NOT EXISTS] db_name [KEEP keep] [UPDATE 1];
+ ```
+ 说明:
+
+ 1) KEEP是该数据库的数据保留多长天数,缺省是3650天(10年),数据库会自动删除超过时限的数据;
+
+ 2) UPDATE 标志数据库支持更新相同时间戳数据;
+
+ 3) 数据库名最大长度为33;
+
+ 4) 一条SQL 语句的最大长度为65480个字符;
+
+ 5) 数据库还有更多与存储相关的配置参数,请参见系统管理。
- **显示系统当前参数**
- ```mysql
- SHOW VARIABLES;
- ```
+ ```mysql
+ SHOW VARIABLES;
+ ```
- **使用数据库**
@@ -698,13 +698,13 @@ TDengine支持针对数据的聚合查询。提供支持的聚合和选择函数
```mysql
SELECT TWA(field_name) FROM tb_name WHERE clause;
```
- 功能说明:时间加权平均函数。统计表/超级表中某列在一段时间内的时间加权平均。
+ 功能说明:时间加权平均函数。统计表中某列在一段时间内的时间加权平均。
返回结果数据类型:双精度浮点数Double。
应用字段:不能应用在timestamp、binary、nchar、bool类型字段。
- 适用于:表、超级表。
+ 适用于:表。
- **SUM**
```mysql
@@ -1125,11 +1125,8 @@ SELECT function_list FROM stb_name
- WHERE语句可以指定查询的起止时间和其他过滤条件
- FILL语句指定某一时间区间数据缺失的情况下的填充模式。填充模式包括以下几种:
1. 不进行填充:NONE(默认填充模式)。
-
2. VALUE填充:固定值填充,此时需要指定填充的数值。例如:fill(value, 1.23)。
-
3. NULL填充:使用NULL填充数据。例如:fill(null)。
-
4. PREV填充:使用前一个非NULL值填充数据。例如:fill(prev)。
说明:
diff --git a/documentation20/webdocs/markdowndocs/administrator-ch.md b/documentation20/webdocs/markdowndocs/administrator-ch.md
index 9eee5b2b69..a343f7e970 100644
--- a/documentation20/webdocs/markdowndocs/administrator-ch.md
+++ b/documentation20/webdocs/markdowndocs/administrator-ch.md
@@ -124,10 +124,10 @@ taosd -C
对于一个应用场景,可能有多种数据特征的数据并存,最佳的设计是将具有相同数据特征的表放在一个库里,这样一个应用有多个库,而每个库可以配置不同的存储参数,从而保证系统有最优的性能。TDengine允许应用在创建库时指定上述存储参数,如果指定,该参数就将覆盖对应的系统配置参数。举例,有下述SQL:
```
- create database demo days 10 cache 32 blocks 8 replica 3;
+ create database demo days 10 cache 32 blocks 8 replica 3 update 1;
```
-该SQL创建了一个库demo, 每个数据文件存储10天数据,内存块为32兆字节,每个VNODE占用8个内存块,副本数为3,而其他参数与系统配置完全一致。
+该SQL创建了一个库demo, 每个数据文件存储10天数据,内存块为32兆字节,每个VNODE占用8个内存块,副本数为3,允许更新,而其他参数与系统配置完全一致。
TDengine集群中加入一个新的dnode时,涉及集群相关的一些参数必须与已有集群的配置相同,否则不能成功加入到集群中。会进行校验的参数如下:
diff --git a/documentation20/webdocs/markdowndocs/advanced features-ch.md b/documentation20/webdocs/markdowndocs/advanced features-ch.md
index cdd9ee8104..0ca8428ece 100644
--- a/documentation20/webdocs/markdowndocs/advanced features-ch.md
+++ b/documentation20/webdocs/markdowndocs/advanced features-ch.md
@@ -197,7 +197,7 @@ select * from meters where ts > now - 1d and current > 10;
且`restart`是 **false**(**0**),用户程序就不会读到之前已经读取的数据了。
`taos_subscribe`的最后一个参数是以毫秒为单位的轮询周期。
-在同步模式下,如过前后两次调用`taos_consume`的时间间隔小于此时间,
+在同步模式下,如果前后两次调用`taos_consume`的时间间隔小于此时间,
`taos_consume`会阻塞,直到间隔超过此时间。
异步模式下,这个时间是两次调用回调函数的最小时间间隔。
@@ -414,7 +414,7 @@ TDengine通过查询函数向用户提供毫秒级的数据获取能力。直接
TDengine分配固定大小的内存空间作为缓存空间,缓存空间可根据应用的需求和硬件资源配置。通过适当的设置缓存空间,TDengine可以提供极高性能的写入和查询的支持。TDengine中每个虚拟节点(virtual node)创建时分配独立的缓存池。每个虚拟节点管理自己的缓存池,不同虚拟节点间不共享缓存池。每个虚拟节点内部所属的全部表共享该虚拟节点的缓存池。
-TDengine将内存池按块划分进行管理,数据在内存块里按照列式存储。一个vnode的内存池是在vnode创建时按块分配好的,而且每个内存块按照先进先出的原则进行管理。一张表所需要的内存块是从vnode的内存池中进行分配的,块的大小由系统配置参数cache决定。每张表最大内存块的数目由配置参数tblocks决定,每张表平均的内存块的个数由配置参数ablocks决定。因此对于一个vnode, 总的内存大小为: `cache * ablocks * tables`。内存块参数cache不宜过小,一个cache block需要能存储至少几十条以上记录,才会有效率。参数ablocks最小为2,保证每张表平均至少能分配两个内存块。
+TDengine将内存池按块划分进行管理,数据在内存块里是以行(row)的形式存储。一个vnode的内存池是在vnode创建时按块分配好,而且每个内存块按照先进先出的原则进行管理。在创建内存池时,块的大小由系统配置参数cache决定;每个vnode中内存块的数目则由配置参数blocks决定。因此对于一个vnode,总的内存大小为:`cache * blocks`。一个cache block需要保证每张表能存储至少几十条以上记录,才会有效率。
你可以通过函数last_row快速获取一张表或一张超级表的最后一条记录,这样很便于在大屏显示各设备的实时状态或采集值。例如:
diff --git a/documentation20/webdocs/markdowndocs/cluster-ch.md b/documentation20/webdocs/markdowndocs/cluster-ch.md
index f3f6f2b300..f6019b1a5a 100644
--- a/documentation20/webdocs/markdowndocs/cluster-ch.md
+++ b/documentation20/webdocs/markdowndocs/cluster-ch.md
@@ -225,7 +225,7 @@ SHOW MNODES;
## Arbitrator的使用
-如果副本数为偶数,当一个vnode group里一半vnode不工作时,是无法从中选出master的。同理,一半mnode不工作时,是无法选出mnode的master的,因为存在“split brain”问题。为解决这个问题,TDengine引入了arbitrator的概念。Arbitrator模拟一个vnode或mnode在工作,但只简单的负责网络连接,不处理任何数据插入或访问。只要包含arbitrator在内,超过半数的vnode或mnode工作,那么该vnode group或mnode组就可以正常的提供数据插入或查询服务。比如对于副本数为2的情形,如果一个节点A离线,但另外一个节点B正常,而且能连接到arbitrator, 那么节点B就能正常工作。
+如果副本数为偶数,当一个vnode group里一半vnode不工作时,是无法从中选出master的。同理,一半mnode不工作时,是无法选出mnode的master的,因为存在“split brain”问题。为解决这个问题,TDengine引入了Arbitrator的概念。Arbitrator模拟一个vnode或mnode在工作,但只简单的负责网络连接,不处理任何数据插入或访问。只要包含Arbitrator在内,超过半数的vnode或mnode工作,那么该vnode group或mnode组就可以正常的提供数据插入或查询服务。比如对于副本数为2的情形,如果一个节点A离线,但另外一个节点B正常,而且能连接到Arbitrator,那么节点B就能正常工作。
-TDengine提供一个执行程序tarbitrator, 找任何一台Linux服务器运行它即可。请点击[安装包下载](https://www.taosdata.com/cn/all-downloads/),在TDengine Arbitrator Linux一节中,选择适合的版本下载并安装。该程序对系统资源几乎没有要求,只需要保证有网络连接即可。该应用的命令行参数`-p`可以指定其对外服务的端口号,缺省是6042。配置每个taosd实例时,可以在配置文件taos.cfg里将参数arbitrator设置为arbitrator的End Point。如果该参数配置了,当副本数为偶数时,系统将自动连接配置的arbitrator。如果副本数为奇数,即使配置了arbitrator, 系统也不会去建立连接。
+TDengine提供一个执行程序,名为 tarbitrator,找任何一台Linux服务器运行它即可。请点击[安装包下载](https://www.taosdata.com/cn/all-downloads/),在TDengine Arbitrator Linux一节中,选择适合的版本下载并安装。该程序对系统资源几乎没有要求,只需要保证有网络连接即可。该应用的命令行参数`-p`可以指定其对外服务的端口号,缺省是6042。配置每个taosd实例时,可以在配置文件taos.cfg里将参数arbitrator设置为Arbitrator的End Point。如果该参数配置了,当副本数为偶数时,系统将自动连接配置的Arbitrator。如果副本数为奇数,即使配置了Arbitrator,系统也不会去建立连接。
diff --git a/documentation20/webdocs/markdowndocs/cluster.md b/documentation20/webdocs/markdowndocs/cluster.md
deleted file mode 100644
index 8cf7065f72..0000000000
--- a/documentation20/webdocs/markdowndocs/cluster.md
+++ /dev/null
@@ -1,146 +0,0 @@
-#集群安装、管理
-
-多个taosd的运行实例可以组成一个集群,以保证TDengine的高可靠运行,并提供水平扩展能力。要了解TDengine 2.0的集群管理,需要对集群的基本概念有所了解,请看TDengine 2.0整体架构一章。
-
-集群的每个节点是由End Point来唯一标识的,End Point是由FQDN(Fully Qualified Domain Name)外加Port组成,比如 h1.taosdata.com:6030。一般FQDN就是服务器的hostname,可通过Linux命令“hostname"获取。端口是这个节点对外服务的端口号,缺省是6030,但可以通过taos.cfg里配置参数serverPort进行修改。
-
-TDengine的集群管理极其简单,除添加和删除节点需要人工干预之外,其他全部是自动完成,最大程度的降低了运维的工作量。本章对集群管理的操作做详细的描述。
-
-##安装、创建第一个节点
-
-集群是由一个一个dnode组成的,是从一个dnode的创建开始的。创建第一个节点很简单,就按照["立即开始“](https://www.taosdata.com/cn/getting-started/)一章的方法进行安装、启动即可。
-
-启动后,请执行taos, 启动taos shell,从shell里执行命令"show dnodes;",如下所示:
- ```
-Welcome to the TDengine shell from Linux, Client Version:2.0.0.0
-Copyright (c) 2017 by TAOS Data, Inc. All rights reserved.
-
-taos> show dnodes;
- id | end_point | vnodes | cores | status | role | create_time |
-=====================================================================================
- 1 | h1.taos.com:6030 | 0 | 2 | ready | any | 2020-07-31 03:49:29.202 |
-Query OK, 1 row(s) in set (0.006385s)
-
-taos>
- ```
-上述命令里,可以看到这个刚启动的这个节点的End Point是:h1.taos.com:6030
-
-## 安装、创建后续节点
-
-将新的节点添加到现有集群,具体有以下几步:
-
-1. 按照["立即开始“](https://www.taosdata.com/cn/getting-started/)一章的方法进行安装,但不要启动taosd
-
-2. 如果是使用涛思数据的官方安装包进行安装,在安装结束时,会询问集群的End Port, 输入第一个节点的End Point即可。如果是源码安装,请编辑配置文件taos.cfg(缺省是在/etc/taos/目录),增加一行:
-
- ```
- firstEp h1.taos.com:6030
- ```
-
- 请注意将示例的“h1.taos.com:6030" 替换为你自己第一个节点的End Point
-
-3. 按照["立即开始“](https://www.taosdata.com/cn/getting-started/)一章的方法启动taosd
-
-4. 在Linux shell里执行命令"hostname"找出本机的FQDN, 假设为h2.taos.com。如果无法找到,可以查看taosd日志文件taosdlog.0里前面几行日志(一般在/var/log/taos目录),fqdn以及port都会打印出来。
-
-5. 在第一个节点,使用CLI程序taos, 登录进TDengine系统, 使用命令:
-
- ```
- CREATE DNODE "h2.taos.com:6030";
- ```
-
- 将新节点的End Point添加进集群的EP列表。**"fqdn:port"需要用双引号引起来**,否则出错。请注意将示例的“h2.taos.com:6030" 替换为你自己第一个节点的End Point
-
-6. 使用命令
-
- ```
- SHOW DNODES;
- ```
-
- 查看新节点是否被成功加入。
-
-按照上述步骤可以源源不断的将新的节点加入到集群。
-
-**提示:**
-
-- firstEp, secondEp这两个参数仅仅在该节点第一次加入集群时有作用,加入集群后,该节点会保存最新的mnode的End Point列表,不再依赖这两个参数。
-- 两个没有配置first, second参数的dnode启动后,会独立运行起来。这个时候,无法将其中一个节点加入到另外一个节点,形成集群。**无法将两个独立的集群合并成为新的集群**。
-
-##节点管理
-
-###添加节点
-执行CLI程序taos, 使用root账号登录进系统, 执行:
-```
-CREATE DNODE "fqdn:port";
-```
-将新节点的End Point添加进集群的EP列表。**"fqdn:port"需要用双引号引起来**,否则出错。一个节点对外服务的fqdn和port可以通过配置文件taos.cfg进行配置,缺省是自动获取。
-
-###删除节点
-执行CLI程序taos, 使用root账号登录进TDengine系统,执行:
-```
-DROP DNODE "fqdn:port";
-```
-其中fqdn是被删除的节点的FQDN,port是其对外服务器的端口号
-
-###查看节点
-执行CLI程序taos,使用root账号登录进TDengine系统,执行:
-```
-SHOW DNODES;
-```
-它将列出集群中所有的dnode,每个dnode的fqdn:port, 状态(ready, offline等),vnode数目,还未使用的vnode数目等信息。在添加或删除一个节点后,可以使用该命令查看。
-
-如果集群配置了Arbitrator,那么它也会在这个节点列表中显示出来,其role列的值会是“arb”。
-
-###查看虚拟节点组
-
-为充分利用多核技术,并提供scalability,数据需要分片处理。因此TDengine会将一个DB的数据切分成多份,存放在多个vnode里。这些vnode可能分布在多个dnode里,这样就实现了水平扩展。一个vnode仅仅属于一个DB,但一个DB可以有多个vnode。vnode的是mnode根据当前系统资源的情况,自动进行分配的,无需任何人工干预。
-
-执行CLI程序taos,使用root账号登录进TDengine系统,执行:
-```
-SHOW VGROUPS;
-```
-##高可用性
-TDengine通过多副本的机制来提供系统的高可用性。副本数是与DB关联的,一个集群里可以有多个DB,根据运营的需求,每个DB可以配置不同的副本数。创建数据库时,通过参数replica 指定副本数(缺省为1)。如果副本数为1,系统的可靠性无法保证,只要数据所在的节点宕机,就将无法提供服务。集群的节点数必须大于等于副本数,否则创建表时将返回错误“more dnodes are needed"。比如下面的命令将创建副本数为3的数据库demo:
-```
-CREATE DATABASE demo replica 3;
-```
-一个DB里的数据会被切片分到多个vnode group,vnode group里的vnode数目就是DB的副本数,同一个vnode group里各vnode的数据是完全一致的。为保证高可用性,vnode group里的vnode一定要分布在不同的dnode里(实际部署时,需要在不同的物理机上),只要一个vgroup里超过半数的vnode处于工作状态,这个vgroup就能正常的对外服务。
-
-一个dnode里可能有多个DB的数据,因此一个dnode离线时,可能会影响到多个DB。如果一个vnode group里的一半或一半以上的vnode不工作,那么该vnode group就无法对外服务,无法插入或读取数据,这样会影响到它所属的DB的一部分表的d读写操作。
-
-因为vnode的引入,无法简单的给出结论:“集群中过半dnode工作,集群就应该工作”。但是对于简单的情形,很好下结论。比如副本数为3,只有三个dnode,那如果仅有一个节点不工作,整个集群还是可以正常工作的,但如果有两个节点不工作,那整个集群就无法正常工作了。
-
-##Mnode的高可用
-TDengine集群是由mnode (taosd的一个模块,逻辑节点) 负责管理的,为保证mnode的高可用,可以配置多个mnode副本,副本数由系统配置参数numOfMnodes决定,有效范围为1-3。为保证元数据的强一致性,mnode副本之间是通过同步的方式进行数据复制的。
-
-一个集群有多个dnode, 但一个dnode至多运行一个mnode实例。多个dnode情况下,哪个dnode可以作为mnode呢?这是完全由系统根据整个系统资源情况,自动指定的。用户可通过CLI程序taos,在TDengine的console里,执行如下命令:
-```
-SHOW MNODES;
-```
-来查看mnode列表,该列表将列出mnode所处的dnode的End Point和角色(master, slave, unsynced 或offline)。
-当集群中第一个节点启动时,该节点一定会运行一个mnode实例,否则该dnode无法正常工作,因为一个系统是必须有至少一个mnode的。如果numOfMnodes配置为2,启动第二个dnode时,该dnode也将运行一个mnode实例。
-
-为保证mnode服务的高可用性,numOfMnodes必须设置为2或更大。因为mnode保存的元数据必须是强一致的,如果numOfMnodes大于2,复制参数quorum自动设为2,也就是说,至少要保证有两个副本写入数据成功,才通知客户端应用写入成功。
-
-##负载均衡
-
-有三种情况,将触发负载均衡,而且都无需人工干预。
-
-- 当一个新节点添加进集群时,系统将自动触发负载均衡,一些节点上的数据将被自动转移到新节点上,无需任何人工干预。
-- 当一个节点从集群中移除时,系统将自动把该节点上的数据转移到其他节点,无需任何人工干预。
-- 如果一个节点过热(数据量过大),系统将自动进行负载均衡,将该节点的一些vnode自动挪到其他节点。
-
-当上述三种情况发生时,系统将启动一各个节点的负载计算,从而决定如何挪动。
-
-##节点离线处理
-如果一个节点离线,TDengine集群将自动检测到。有如下两种情况:
-- 改节点离线超过一定时间(taos.cfg里配置参数offlineThreshold控制时长),系统将自动把该节点删除,产生系统报警信息,触发负载均衡流程。如果该被删除的节点重现上线时,它将无法加入集群,需要系统管理员重新将其添加进集群才会开始工作。
-- 离线后,在offlineThreshold的时长内重新上线,系统将自动启动数据恢复流程,等数据完全恢复后,该节点将开始正常工作。
-
-##Arbitrator的使用
-
-如果副本数为偶数,当一个vnode group里一半vnode不工作时,是无法从中选出master的。同理,一半mnode不工作时,是无法选出mnode的master的,因为存在“split brain”问题。为解决这个问题,TDengine引入了arbitrator的概念。Arbitrator模拟一个vnode或mnode在工作,但只简单的负责网络连接,不处理任何数据插入或访问。只要包含arbitrator在内,超过半数的vnode或mnode工作,那么该vnode group或mnode组就可以正常的提供数据插入或查询服务。比如对于副本数为2的情形,如果一个节点A离线,但另外一个节点B正常,而且能连接到arbitrator, 那么节点B就能正常工作。
-
-TDengine安装包里带有一个执行程序tarbitrator, 找任何一台Linux服务器运行它即可。该程序对系统资源几乎没有要求,只需要保证有网络连接即可。该应用的命令行参数`-p`可以指定其对外服务的端口号,缺省是6030。配置每个taosd实例时,可以在配置文件taos.cfg里将参数arbitrator设置为Arbitrator的End Point。如果该参数配置了,当副本数为偶数时,系统将自动连接配置的Arbitrator。
-
-在配置了Arbitrator的情况下,它也会显示在“show dnodes;”指令给出的节点列表中。
diff --git a/documentation20/webdocs/markdowndocs/connector-java-ch.md b/documentation20/webdocs/markdowndocs/connector-java-ch.md
index 7ba573d2e4..b8390e7af5 100644
--- a/documentation20/webdocs/markdowndocs/connector-java-ch.md
+++ b/documentation20/webdocs/markdowndocs/connector-java-ch.md
@@ -1,62 +1,62 @@
# Java Connector
-Java连接器支持的系统有:
-| **CPU类型** | x64(64bit) | | | ARM64 | ARM32 |
-| ------------ | ------------ | -------- | -------- | -------- | -------- |
-| **OS类型** | Linux | Win64 | Win32 | Linux | Linux |
-| **支持与否** | **支持** | **支持** | **支持** | **支持** | **支持** |
+TDengine 提供了遵循 JDBC 标准(3.0)API 规范的 `taos-jdbcdriver` 实现,可在 maven 的中央仓库 [Sonatype Repository][1] 搜索下载。
-Java连接器的使用请参见视频教程。
+`taos-jdbcdriver` 的实现包括 2 种形式: JDBC-JNI 和 JDBC-RESTful(taos-jdbcdriver-2.0.17 开始支持 JDBC-RESTful)。 JDBC-JNI 通过调用客户端 libtaos.so(或 taos.dll )的本地方法实现, JDBC-RESTful 则在内部封装了 RESTful 接口实现。
-TDengine 为了方便 Java 应用使用,提供了遵循 JDBC 标准(3.0)API 规范的 `taos-jdbcdriver` 实现。目前可以通过 [Sonatype Repository][1] 搜索并下载。
+
-由于 TDengine 是使用 c 语言开发的,使用 taos-jdbcdriver 驱动包时需要依赖系统对应的本地函数库。
+上图显示了 3 种 Java 应用使用连接器访问 TDengine 的方式:
-* libtaos.so
- 在 linux 系统中成功安装 TDengine 后,依赖的本地函数库 libtaos.so 文件会被自动拷贝至 /usr/lib/libtaos.so,该目录包含在 Linux 自动扫描路径上,无需单独指定。
+* JDBC-JNI:Java 应用在物理节点1(pnode1)上使用 JDBC-JNI 的 API ,直接调用客户端 API(libtaos.so 或 taos.dll)将写入和查询请求发送到位于物理节点2(pnode2)上的 taosd 实例。
+* RESTful:应用将 SQL 发送给位于物理节点2(pnode2)上的 RESTful 连接器,再调用客户端 API(libtaos.so)。
+* JDBC-RESTful:Java 应用通过 JDBC-RESTful 的 API ,将 SQL 封装成一个 RESTful 请求,发送给物理节点2的 RESTful 连接器。
-* taos.dll
- 在 windows 系统中安装完客户端之后,驱动包依赖的 taos.dll 文件会自动拷贝到系统默认搜索路径 C:/Windows/System32 下,同样无需要单独指定。
+TDengine 的 JDBC 驱动实现尽可能与关系型数据库驱动保持一致,但时序空间数据库与关系对象型数据库服务的对象和技术特征存在差异,导致 `taos-jdbcdriver` 与传统的 JDBC driver 也存在一定差异。在使用时需要注意以下几点:
-> 注意:在 windows 环境开发时需要安装 TDengine 对应的 [windows 客户端][14],Linux 服务器安装完 TDengine 之后默认已安装 client,也可以单独安装 [Linux 客户端][15] 连接远程 TDengine Server。
-
-TDengine 的 JDBC 驱动实现尽可能的与关系型数据库驱动保持一致,但时序空间数据库与关系对象型数据库服务的对象和技术特征的差异导致 taos-jdbcdriver 并未完全实现 JDBC 标准规范。在使用时需要注意以下几点:
-
-* TDengine 不提供针对单条数据记录的删除和修改的操作,驱动中也没有支持相关方法。
-* 由于不支持删除和修改,所以也不支持事务操作。
+* TDengine 目前不支持针对单条数据记录的删除操作。
+* 目前不支持事务操作。
* 目前不支持表间的 union 操作。
-* 目前不支持嵌套查询(nested query),对每个 Connection 的实例,至多只能有一个打开的 ResultSet 实例;如果在 ResultSet还没关闭的情况下执行了新的查询,TSDBJDBCDriver 则会自动关闭上一个 ResultSet。
+* 目前不支持嵌套查询(nested query)。
+* 对每个 Connection 的实例,至多只能有一个打开的 ResultSet 实例;如果在 ResultSet 还没关闭的情况下执行了新的查询,taos-jdbcdriver 会自动关闭上一个 ResultSet。
-## TAOS-JDBCDriver 版本以及支持的 TDengine 版本和 JDK 版本
-| taos-jdbcdriver 版本 | TDengine 版本 | JDK 版本 |
-| --- | --- | --- |
-| 2.0.12 及以上 | 2.0.8.0 及以上 | 1.8.x |
-| 2.0.4 - 2.0.11 | 2.0.0.0 - 2.0.7.x | 1.8.x |
-| 1.0.3 | 1.6.1.x 及以上 | 1.8.x |
-| 1.0.2 | 1.6.1.x 及以上 | 1.8.x |
-| 1.0.1 | 1.6.1.x 及以上 | 1.8.x |
+## JDBC-JNI和JDBC-RESTful的对比
-## TDengine DataType 和 Java DataType
+
+对比项 | JDBC-JNI | JDBC-RESTful |
+
+ 支持的操作系统 |
+ linux、windows |
+ 全平台 |
+
+
+ 是否需要安装 client |
+ 需要 |
+ 不需要 |
+
+
+ server 升级后是否需要升级 client |
+ 需要 |
+ 不需要 |
+
+
+ 写入性能 |
+ JDBC-RESTful 是 JDBC-JNI 的 50%~90% |
+
+
+ 查询性能 |
+ JDBC-RESTful 与 JDBC-JNI 没有差别 |
+
+
-TDengine 目前支持时间戳、数字、字符、布尔类型,与 Java 对应类型转换如下:
-| TDengine DataType | Java DataType |
-| --- | --- |
-| TIMESTAMP | java.sql.Timestamp |
-| INT | java.lang.Integer |
-| BIGINT | java.lang.Long |
-| FLOAT | java.lang.Float |
-| DOUBLE | java.lang.Double |
-| SMALLINT, TINYINT |java.lang.Short |
-| BOOL | java.lang.Boolean |
-| BINARY, NCHAR | java.lang.String |
-
-## 如何获取 TAOS-JDBCDriver
+## 如何获取 taos-jdbcdriver
### maven 仓库
目前 taos-jdbcdriver 已经发布到 [Sonatype Repository][1] 仓库,且各大仓库都已同步。
+
* [sonatype][8]
* [mvnrepository][9]
* [maven.aliyun][10]
@@ -67,30 +67,63 @@ maven 项目中使用如下 pom.xml 配置即可:
com.taosdata.jdbc
taos-jdbcdriver
- 2.0.4
+ 2.0.17
```
### 源码编译打包
-下载 [TDengine][3] 源码之后,进入 taos-jdbcdriver 源码目录 `src/connector/jdbc` 执行 `mvn clean package` 即可生成相应 jar 包。
+下载 [TDengine][3] 源码之后,进入 taos-jdbcdriver 源码目录 `src/connector/jdbc` 执行 `mvn clean package -Dmaven.test.skip=true` 即可生成相应 jar 包。
-## 使用说明
+
+
+## JDBC的使用说明
### 获取连接
-#### 通过JdbcUrl获取连接
+#### 指定URL获取连接
+
+通过指定URL获取连接,如下所示:
+
+```java
+Class.forName("com.taosdata.jdbc.rs.RestfulDriver");
+String jdbcUrl = "jdbc:TAOS-RS://taosdemo.com:6041/test?user=root&password=taosdata";
+Connection conn = DriverManager.getConnection(jdbcUrl);
+```
+
+以上示例,使用 **JDBC-RESTful** 的 driver,建立了到 hostname 为 taosdemo.com,端口为 6041,数据库名为 test 的连接。这个 URL 中指定用户名(user)为 root,密码(password)为 taosdata。
+
+使用 JDBC-RESTful 接口,不需要依赖本地函数库。与 JDBC-JNI 相比,仅需要:
+
+1. driverClass 指定为“com.taosdata.jdbc.rs.RestfulDriver”;
+2. jdbcUrl 以“jdbc:TAOS-RS://”开头;
+3. 使用 6041 作为连接端口。
+
+如果希望获得更好的写入和查询性能,Java 应用可以使用 **JDBC-JNI** 的driver,如下所示:
-通过指定的jdbcUrl获取连接,如下所示:
```java
Class.forName("com.taosdata.jdbc.TSDBDriver");
String jdbcUrl = "jdbc:TAOS://taosdemo.com:6030/test?user=root&password=taosdata";
Connection conn = DriverManager.getConnection(jdbcUrl);
```
-以上示例,建立了到hostname为taosdemo.com,端口为6030(TDengine的默认端口),数据库名为test的连接。这个url中指定用户名(user)为root,密码(password)为taosdata。
+
+以上示例,使用了 JDBC-JNI 的 driver,建立了到 hostname 为 taosdemo.com,端口为 6030(TDengine 的默认端口),数据库名为 test 的连接。这个 URL 中指定用户名(user)为 root,密码(password)为 taosdata。
+
+**注意**:使用 JDBC-JNI 的 driver,taos-jdbcdriver 驱动包时需要依赖系统对应的本地函数库。
+
+* libtaos.so
+ 在 linux 系统中成功安装 TDengine 后,依赖的本地函数库 libtaos.so 文件会被自动拷贝至 /usr/lib/libtaos.so,该目录包含在 Linux 自动扫描路径上,无需单独指定。
+
+* taos.dll
+ 在 windows 系统中安装完客户端之后,驱动包依赖的 taos.dll 文件会自动拷贝到系统默认搜索路径 C:/Windows/System32 下,同样无需要单独指定。
+
+> 在 windows 环境开发时需要安装 TDengine 对应的 [windows 客户端][14],Linux 服务器安装完 TDengine 之后默认已安装 client,也可以单独安装 [Linux 客户端][15] 连接远程 TDengine Server。
+
+JDBC-JNI 的使用请参见视频教程。
TDengine 的 JDBC URL 规范格式为:
-`jdbc:TAOS://[host_name]:[port]/[database_name]?[user={user}|&password={password}|&charset={charset}|&cfgdir={config_dir}|&locale={locale}|&timezone={timezone}]`
+`jdbc:[TAOS|TAOS-RS]://[host_name]:[port]/[database_name]?[user={user}|&password={password}|&charset={charset}|&cfgdir={config_dir}|&locale={locale}|&timezone={timezone}]`
+
url中的配置参数如下:
* user:登录 TDengine 用户名,默认值 root。
* password:用户登录密码,默认值 taosdata。
@@ -99,13 +132,17 @@ url中的配置参数如下:
* locale:客户端语言环境,默认值系统当前 locale。
* timezone:客户端使用的时区,默认值为系统当前时区。
-#### 使用JdbcUrl和Properties获取连接
-除了通过指定的jdbcUrl获取连接,还可以使用Properties指定建立连接时的参数,如下所示:
+
+#### 指定URL和Properties获取连接
+
+除了通过指定的 URL 获取连接,还可以使用 Properties 指定建立连接时的参数,如下所示:
```java
public Connection getConn() throws Exception{
Class.forName("com.taosdata.jdbc.TSDBDriver");
+ // Class.forName("com.taosdata.jdbc.rs.RestfulDriver");
String jdbcUrl = "jdbc:TAOS://taosdemo.com:6030/test?user=root&password=taosdata";
+ // String jdbcUrl = "jdbc:TAOS-RS://taosdemo.com:6041/test?user=root&password=taosdata";
Properties connProps = new Properties();
connProps.setProperty(TSDBDriver.PROPERTY_KEY_CHARSET, "UTF-8");
connProps.setProperty(TSDBDriver.PROPERTY_KEY_LOCALE, "en_US.UTF-8");
@@ -114,9 +151,10 @@ public Connection getConn() throws Exception{
return conn;
}
```
-以上示例,建立一个到hostname为taosdemo.com,端口为6030,数据库名为test的连接。这个连接在url中指定了用户名(user)为root,密码(password)为taosdata,并在connProps中指定了使用的字符集、语言环境、时区等信息。
-properties中的配置参数如下:
+以上示例,建立一个到 hostname 为 taosdemo.com,端口为 6030,数据库名为 test 的连接。注释为使用 JDBC-RESTful 时的方法。这个连接在 url 中指定了用户名(user)为 root,密码(password)为 taosdata,并在 connProps 中指定了使用的字符集、语言环境、时区等信息。
+
+properties 中的配置参数如下:
* TSDBDriver.PROPERTY_KEY_USER:登录 TDengine 用户名,默认值 root。
* TSDBDriver.PROPERTY_KEY_PASSWORD:用户登录密码,默认值 taosdata。
* TSDBDriver.PROPERTY_KEY_CONFIG_DIR:客户端配置文件目录路径,Linux OS 上默认值 /etc/taos ,Windows OS 上默认值 C:/TDengine/cfg。
@@ -124,10 +162,14 @@ properties中的配置参数如下:
* TSDBDriver.PROPERTY_KEY_LOCALE:客户端语言环境,默认值系统当前 locale。
* TSDBDriver.PROPERTY_KEY_TIME_ZONE:客户端使用的时区,默认值为系统当前时区。
+
+
#### 使用客户端配置文件建立连接
-当使用JDBC连接TDengine集群时,可以使用客户端配置文件,在客户端配置文件中指定集群的firstEp、secondEp参数。
+
+当使用 JDBC-JNI 连接 TDengine 集群时,可以使用客户端配置文件,在客户端配置文件中指定集群的 firstEp、secondEp参数。
如下所示:
-1. 在java中不指定hostname和port
+
+1. 在 Java 应用中不指定 hostname 和 port
```java
public Connection getConn() throws Exception{
Class.forName("com.taosdata.jdbc.TSDBDriver");
@@ -140,7 +182,7 @@ public Connection getConn() throws Exception{
return conn;
}
```
-2. 在配置文件中指定firstEp和secondEp
+2. 在配置文件中指定 firstEp 和 secondEp
```
# first fully qualified domain name (FQDN) for TDengine system
firstEp cluster_node1:6030
@@ -155,17 +197,19 @@ secondEp cluster_node2:6030
# locale en_US.UTF-8
```
-以上示例,jdbc会使用客户端的配置文件,建立到hostname为cluster_node1,端口为6030,数据库名为test的连接。当集群中firstEp节点失效时,JDBC会尝试使用secondEp连接集群。
-TDengine中,只要保证firstEp和secondEp中一个节点有效,就可以正常建立到集群的连接。
+以上示例,jdbc 会使用客户端的配置文件,建立到 hostname 为 cluster_node1、端口为 6030、数据库名为 test 的连接。当集群中 firstEp 节点失效时,JDBC 会尝试使用 secondEp 连接集群。
+TDengine 中,只要保证 firstEp 和 secondEp 中一个节点有效,就可以正常建立到集群的连接。
-> 注意:这里的配置文件指的是调用JDBC Connector的应用程序所在机器上的配置文件,Linux OS 上默认值 /etc/taos/taos.cfg ,Windows OS 上默认值 C://TDengine/cfg/taos.cfg。
+> 注意:这里的配置文件指的是调用 JDBC Connector 的应用程序所在机器上的配置文件,Linux OS 上默认值 /etc/taos/taos.cfg ,Windows OS 上默认值 C://TDengine/cfg/taos.cfg。
#### 配置参数的优先级
-通过以上3种方式获取连接,如果配置参数在url、Properties、客户端配置文件中有重复,则参数的`优先级由高到低`分别如下:
+
+通过以上 3 种方式获取连接,如果配置参数在 url、Properties、客户端配置文件中有重复,则参数的`优先级由高到低`分别如下:
1. JDBC URL 参数,如上所述,可以在 JDBC URL 的参数中指定。
2. Properties connProps
3. 客户端配置文件 taos.cfg
-例如:在url中指定了password为taosdata,在Properties中指定了password为taosdemo,那么,JDBC会使用url中的password建立连接。
+
+例如:在 url 中指定了 password 为 taosdata,在 Properties 中指定了 password 为 taosdemo,那么,JDBC 会使用 url 中的 password 建立连接。
> 更多详细配置请参考[客户端配置][13]
@@ -183,6 +227,7 @@ stmt.executeUpdate("use db");
// create table
stmt.executeUpdate("create table if not exists tb (ts timestamp, temperature int, humidity float)");
```
+
> 注意:如果不使用 `use db` 指定数据库,则后续对表的操作都需要增加数据库名称作为前缀,如 db.tb。
### 插入数据
@@ -193,6 +238,7 @@ int affectedRows = stmt.executeUpdate("insert into tb values(now, 23, 10.3) (now
System.out.println("insert " + affectedRows + " rows.");
```
+
> now 为系统内部函数,默认为服务器当前时间。
> `now + 1s` 代表服务器当前时间往后加 1 秒,数字后面代表时间单位:a(毫秒), s(秒), m(分), h(小时), d(天),w(周), n(月), y(年)。
@@ -214,6 +260,7 @@ while(resultSet.next()){
System.out.printf("%s, %d, %s\n", ts, temperature, humidity);
}
```
+
> 查询和操作关系型数据库一致,使用下标获取返回字段内容时从 1 开始,建议使用字段名称获取。
### 订阅
@@ -248,7 +295,7 @@ while(true) {
}
```
-`consume` 方法返回一个结果集,其中包含从上次 `consume` 到目前为止的所有新数据。请务必按需选择合理的调用 `consume` 的频率(如例子中的`Thread.sleep(1000)`),否则会给服务端造成不必要的压力。
+`consume` 方法返回一个结果集,其中包含从上次 `consume` 到目前为止的所有新数据。请务必按需选择合理的调用 `consume` 的频率(如例子中的 `Thread.sleep(1000)`),否则会给服务端造成不必要的压力。
#### 关闭订阅
@@ -265,8 +312,11 @@ resultSet.close();
stmt.close();
conn.close();
```
+
> `注意务必要将 connection 进行关闭`,否则会出现连接泄露。
+
+
## 与连接池使用
**HikariCP**
@@ -306,6 +356,7 @@ conn.close();
connection.close(); // put back to conneciton pool
}
```
+
> 通过 HikariDataSource.getConnection() 获取连接后,使用完成后需要调用 close() 方法,实际上它并不会关闭连接,只是放回连接池中。
> 更多 HikariCP 使用问题请查看[官方说明][5]
@@ -356,6 +407,7 @@ public static void main(String[] args) throws Exception {
connection.close(); // put back to conneciton pool
}
```
+
> 更多 druid 使用问题请查看[官方说明][6]
**注意事项**
@@ -370,10 +422,43 @@ server_status()|
Query OK, 1 row(s) in set (0.000141s)
```
+
+
## 与框架使用
* Spring JdbcTemplate 中使用 taos-jdbcdriver,可参考 [SpringJdbcTemplate][11]
-* Springboot + Mybatis 中使用,可参考 [springbootdemo][12]
+* Springboot + Mybatis 中使用,可参考 [springbootdemo
+
+
+
+## TAOS-JDBCDriver 版本以及支持的 TDengine 版本和 JDK 版本
+
+| taos-jdbcdriver 版本 | TDengine 版本 | JDK 版本 |
+| -------------------- | ----------------- | -------- |
+| 2.0.12 及以上 | 2.0.8.0 及以上 | 1.8.x |
+| 2.0.4 - 2.0.11 | 2.0.0.0 - 2.0.7.x | 1.8.x |
+| 1.0.3 | 1.6.1.x 及以上 | 1.8.x |
+| 1.0.2 | 1.6.1.x 及以上 | 1.8.x |
+| 1.0.1 | 1.6.1.x 及以上 | 1.8.x |
+
+
+
+## TDengine DataType 和 Java DataType
+
+TDengine 目前支持时间戳、数字、字符、布尔类型,与 Java 对应类型转换如下:
+
+| TDengine DataType | Java DataType |
+| ----------------- | ------------------ |
+| TIMESTAMP | java.sql.Timestamp |
+| INT | java.lang.Integer |
+| BIGINT | java.lang.Long |
+| FLOAT | java.lang.Float |
+| DOUBLE | java.lang.Double |
+| SMALLINT, TINYINT | java.lang.Short |
+| BOOL | java.lang.Boolean |
+| BINARY, NCHAR | java.lang.String |
+
+
## 常见问题
@@ -381,7 +466,7 @@ Query OK, 1 row(s) in set (0.000141s)
**原因**:程序没有找到依赖的本地函数库 taos。
- **解决方法**:windows 下可以将 C:\TDengine\driver\taos.dll 拷贝到 C:\Windows\System32\ 目录下,linux 下将建立如下软链 ` ln -s /usr/local/taos/driver/libtaos.so.x.x.x.x /usr/lib/libtaos.so` 即可。
+ **解决方法**:windows 下可以将 C:\TDengine\driver\taos.dll 拷贝到 C:\Windows\System32\ 目录下,linux 下将建立如下软链 `ln -s /usr/local/taos/driver/libtaos.so.x.x.x.x /usr/lib/libtaos.so` 即可。
* java.lang.UnsatisfiedLinkError: taos.dll Can't load AMD 64 bit on a IA 32-bit platform
@@ -406,3 +491,4 @@ Query OK, 1 row(s) in set (0.000141s)
[13]: https://www.taosdata.com/cn/documentation20/administrator/#%E5%AE%A2%E6%88%B7%E7%AB%AF%E9%85%8D%E7%BD%AE
[14]: https://www.taosdata.com/cn/all-downloads/#TDengine-Windows-Client
[15]: https://www.taosdata.com/cn/getting-started/#%E5%BF%AB%E9%80%9F%E4%B8%8A%E6%89%8B
+
diff --git a/documentation20/webdocs/markdowndocs/faq-ch.md b/documentation20/webdocs/markdowndocs/faq-ch.md
index 79139078c1..cd6f0ae08c 100644
--- a/documentation20/webdocs/markdowndocs/faq-ch.md
+++ b/documentation20/webdocs/markdowndocs/faq-ch.md
@@ -85,7 +85,9 @@ TDengine还没有一组专用的validation queries。然而建议你使用系统
## 9. 我可以删除或更新一条记录吗?
-不能。因为TDengine是为联网设备采集的数据设计的,不容许修改。但TDengine提供数据保留策略,只要数据记录超过保留时长,就会被自动删除。
+TDengine 目前尚不支持删除功能,未来根据用户需求可能会支持。
+
+从 2.0.8.0 开始,TDengine 支持更新已经写入数据的功能。使用更新功能需要在创建数据库时使用 UPDATE 1 参数,之后可以使用 INSERT INTO 命令更新已经写入的相同时间戳数据。UPDATE 参数不支持 ALTER DATABASE 命令修改。没有使用 UPDATE 1 参数创建的数据库,写入相同时间戳的数据不会修改之前的数据,也不会报错。
## 10. 我怎么创建超过1024列的表?
@@ -132,8 +134,3 @@ TDengine是根据hostname唯一标志一台机器的,在数据文件从机器A
- 2.0.7.0 及以后的版本,到/var/lib/taos/dnode下,修复dnodeEps.json的dnodeId对应的FQDN,重启。确保机器内所有机器的此文件是完全相同的。
- 1.x 和 2.x 版本的存储结构不兼容,需要使用迁移工具或者自己开发应用导出导入数据。
-## 17. TDengine 是否支持删除或更新已经写入的数据?
-
-TDengine 目前尚不支持删除功能,未来根据用户需求可能会支持。
-
-从 2.0.8.0 开始,TDengine 支持更新已经写入数据的功能。使用更新功能需要在创建数据库时使用 UPDATE 1 参数,之后可以使用 INSERT INTO 命令更新已经写入的相同时间戳数据。UPDATE 参数不支持 ALTER DATABASE 命令修改。没有使用 UPDATE 1 参数创建的数据库,写入相同时间戳的数据不会修改之前的数据,也不会报错。
\ No newline at end of file
diff --git a/documentation20/webdocs/markdowndocs/insert-ch.md b/documentation20/webdocs/markdowndocs/insert-ch.md
index 3fa48c1f50..7d380ac952 100644
--- a/documentation20/webdocs/markdowndocs/insert-ch.md
+++ b/documentation20/webdocs/markdowndocs/insert-ch.md
@@ -222,7 +222,7 @@ MQTT是一流行的物联网数据传输协议,TDengine 可以很方便的接
## EMQ Broker 直接写入
-EMQ是一开源的MQTT Broker软件,无需任何代码,只需要在EMQ Dashboard里使用“规则”做简单配置,即可将MQTT的数据直接写入TDengine。EMQ X 支持通过 发送到 Web 服务 的方式保存数据到 TDengine,也在企业版上提供原生的 TDEngine 驱动实现直接保存。详细使用方法请参考EMQ 官方文档。
+EMQ是一开源的MQTT Broker软件,无需任何代码,只需要在EMQ Dashboard里使用“规则”做简单配置,即可将MQTT的数据直接写入TDengine。EMQ X 支持通过 发送到 Web 服务 的方式保存数据到 TDengine,也在企业版上提供原生的 TDengine 驱动实现直接保存。详细使用方法请参考EMQ 官方文档。
## HiveMQ Broker 直接写入
diff --git a/packaging/cfg/taos.cfg b/packaging/cfg/taos.cfg
index 2908a8a21e..73004fe7b7 100644
--- a/packaging/cfg/taos.cfg
+++ b/packaging/cfg/taos.cfg
@@ -265,9 +265,6 @@
# maximum display width of binary and nchar fields in the shell. The parts exceeding this limit will be hidden
# maxBinaryDisplayWidth 30
-# enable/disable telemetry reporting
-# telemetryReporting 1
-
# enable/disable stream (continuous query)
# stream 1
diff --git a/packaging/docker/Dockerfile b/packaging/docker/Dockerfile
index 44ccafd044..e13cad4120 100644
--- a/packaging/docker/Dockerfile
+++ b/packaging/docker/Dockerfile
@@ -1,14 +1,16 @@
-FROM ubuntu:20.04
+FROM ubuntu:18.04
WORKDIR /root
-ARG version
-RUN echo $version
-COPY tdengine.tar.gz /root/
-RUN tar -zxf tdengine.tar.gz
-WORKDIR /root/TDengine-server-$version/
-RUN /bin/bash install.sh -e no
+ARG pkgFile
+ARG dirName
+RUN echo ${pkgFile}
+RUN echo ${dirName}
+COPY ${pkgFile} /root/
+RUN tar -zxf ${pkgFile}
+WORKDIR /root/${dirName}/
+RUN /bin/bash install.sh -e no
ENV LD_LIBRARY_PATH="$LD_LIBRARY_PATH:/usr/lib"
ENV LANG=en_US.UTF-8
diff --git a/packaging/docker/dockerManifest.sh b/packaging/docker/dockerManifest.sh
new file mode 100755
index 0000000000..ca2c3c66c9
--- /dev/null
+++ b/packaging/docker/dockerManifest.sh
@@ -0,0 +1,44 @@
+#!/bin/bash
+set -e
+#set -x
+
+# dockerbuild.sh
+# -n [version number]
+# -p [xxxx]
+
+# set parameters by default value
+verNumber=""
+passWord=""
+
+while getopts "hn:p:" arg
+do
+ case $arg in
+ n)
+ #echo "verNumber=$OPTARG"
+ verNumber=$(echo $OPTARG)
+ ;;
+ p)
+ #echo "passWord=$OPTARG"
+ passWord=$(echo $OPTARG)
+ ;;
+ h)
+ echo "Usage: `basename $0` -n [version number] "
+ echo " -p [password for docker hub] "
+ exit 0
+ ;;
+ ?) #unknow option
+ echo "unkonw argument"
+ exit 1
+ ;;
+ esac
+done
+
+echo "verNumber=${verNumber}"
+
+docker manifest create -a tdengine/tdengine:${verNumber} tdengine/tdengine-amd64:${verNumber} tdengine/tdengine-aarch64:${verNumber} tdengine/tdengine-aarch32:${verNumber}
+
+docker login -u tdengine -p ${passWord} #replace the docker registry username and password
+
+docker manifest push tdengine/tdengine:${verNumber}
+
+# how set latest version ???
diff --git a/packaging/docker/dockerbuild-aarch64.sh b/packaging/docker/dockerbuild-aarch64.sh
deleted file mode 100755
index 795eaed549..0000000000
--- a/packaging/docker/dockerbuild-aarch64.sh
+++ /dev/null
@@ -1,5 +0,0 @@
-#!/bin/bash
-set -x
-docker build --rm -f "Dockerfile" -t tdengine/tdengine-aarch64:$1 "." --build-arg version=$1
-docker login -u tdengine -p $2 #replace the docker registry username and password
-docker push tdengine/tdengine-aarch64:$1
diff --git a/packaging/docker/dockerbuild.sh b/packaging/docker/dockerbuild.sh
index 48e2f7ead6..b7991465b0 100755
--- a/packaging/docker/dockerbuild.sh
+++ b/packaging/docker/dockerbuild.sh
@@ -1,5 +1,63 @@
#!/bin/bash
-set -x
-docker build --rm -f "Dockerfile" -t tdengine/tdengine:$1 "." --build-arg version=$1
-docker login -u tdengine -p $2 #replace the docker registry username and password
-docker push tdengine/tdengine:$1
+set -e
+#set -x
+
+# dockerbuild.sh
+# -c [aarch32 | aarch64 | amd64 | x86 | mips64 ...]
+# -f [pkg file]
+# -n [version number]
+# -p [password for docker hub]
+
+# set parameters by default value
+cpuType=amd64
+verNumber=""
+passWord=""
+pkgFile=""
+
+while getopts "hc:n:p:f:" arg
+do
+ case $arg in
+ c)
+ #echo "cpuType=$OPTARG"
+ cpuType=$(echo $OPTARG)
+ ;;
+ n)
+ #echo "verNumber=$OPTARG"
+ verNumber=$(echo $OPTARG)
+ ;;
+ p)
+ #echo "passWord=$OPTARG"
+ passWord=$(echo $OPTARG)
+ ;;
+ f)
+ #echo "pkgFile=$OPTARG"
+ pkgFile=$(echo $OPTARG)
+ ;;
+ h)
+ echo "Usage: `basename $0` -c [aarch32 | aarch64 | amd64 | x86 | mips64 ...] "
+ echo " -f [pkg file] "
+ echo " -n [version number] "
+ echo " -p [password for docker hub] "
+ exit 0
+ ;;
+ ?) #unknow option
+ echo "unkonw argument"
+ exit 1
+ ;;
+ esac
+done
+
+echo "cpuType=${cpuType} verNumber=${verNumber} pkgFile=${pkgFile} "
+echo "$(pwd)"
+echo "====NOTES: ${pkgFile} must be in the same directory as dockerbuild.sh===="
+
+dirName=${pkgFile%-Linux*}
+#echo "dirName=${dirName}"
+
+docker build --rm -f "Dockerfile" -t tdengine/tdengine-${cpuType}:${verNumber} "." --build-arg pkgFile=${pkgFile} --build-arg dirName=${dirName}
+docker login -u tdengine -p ${passWord} #replace the docker registry username and password
+docker push tdengine/tdengine-${cpuType}:${verNumber}
+
+# set this version to latest version
+docker tag tdengine/tdengine-${cpuType}:${verNumber} tdengine/tdengine-${cpuType}:latest
+docker push tdengine/tdengine-${cpuType}:latest
diff --git a/packaging/docker/dockerbuildi.sh b/packaging/docker/dockerbuildi.sh
new file mode 100755
index 0000000000..a0a954e30f
--- /dev/null
+++ b/packaging/docker/dockerbuildi.sh
@@ -0,0 +1,56 @@
+#!/bin/bash
+#
+
+set -e
+#set -x
+
+# dockerbuild.sh
+# -c [aarch32 | aarch64 | amd64 | x86 | mips64 ...]
+# -n [version number]
+# -p [password for docker hub]
+
+# set parameters by default value
+cpuType=aarch64
+verNumber=""
+passWord=""
+
+while getopts "hc:n:p:f:" arg
+do
+ case $arg in
+ c)
+ #echo "cpuType=$OPTARG"
+ cpuType=$(echo $OPTARG)
+ ;;
+ n)
+ #echo "verNumber=$OPTARG"
+ verNumber=$(echo $OPTARG)
+ ;;
+ p)
+ #echo "passWord=$OPTARG"
+ passWord=$(echo $OPTARG)
+ ;;
+ h)
+ echo "Usage: `basename $0` -c [aarch32 | aarch64 | amd64 | x86 | mips64 ...] "
+ echo " -n [version number] "
+ echo " -p [password for docker hub] "
+ exit 0
+ ;;
+ ?) #unknow option
+ echo "unkonw argument"
+ exit 1
+ ;;
+ esac
+done
+
+pkgFile=TDengine-server-${verNumber}-Linux-${cpuType}.tar.gz
+
+echo "cpuType=${cpuType} verNumber=${verNumber} pkgFile=${pkgFile} "
+
+scriptDir=`pwd`
+pkgDir=$scriptDir/../../release/
+
+cp -f ${pkgDir}/${pkgFile} .
+
+./dockerbuild.sh -c ${cpuType} -f ${pkgFile} -n ${verNumber} -p ${passWord}
+
+rm -f ${pkgFile}
diff --git a/packaging/tools/taosd-dump-cfg.gdb b/packaging/tools/taosd-dump-cfg.gdb
new file mode 100644
index 0000000000..9774ccf822
--- /dev/null
+++ b/packaging/tools/taosd-dump-cfg.gdb
@@ -0,0 +1,144 @@
+# Usage:
+# sudo gdb -x ./taosd-dump-cfg.gdb
+
+define attach_pidof
+ if $argc != 1
+ help attach_pidof
+ else
+ shell echo -e "\
+set \$PID = "$(echo $(pidof $arg0) 0 | cut -d " " -f 1)"\n\
+if \$PID > 0\n\
+ attach "$(pidof -s $arg0)"\n\
+else\n\
+ print \"Process '"$arg0"' not found\"\n\
+end" > /tmp/gdb.pidof
+ source /tmp/gdb.pidof
+ end
+end
+
+document attach_pidof
+Attach to process by name
+Usage: attach_pidof PROG_NAME
+end
+
+set $TAOS_CFG_VTYPE_INT8 = 0
+set $TAOS_CFG_VTYPE_INT16 = 1
+set $TAOS_CFG_VTYPE_INT32 = 2
+set $TAOS_CFG_VTYPE_FLOAT = 3
+set $TAOS_CFG_VTYPE_STRING = 4
+set $TAOS_CFG_VTYPE_IPSTR = 5
+set $TAOS_CFG_VTYPE_DIRECTORY = 6
+
+set $TSDB_CFG_CTYPE_B_CONFIG = 1U
+set $TSDB_CFG_CTYPE_B_SHOW = 2U
+set $TSDB_CFG_CTYPE_B_LOG = 4U
+set $TSDB_CFG_CTYPE_B_CLIENT = 8U
+set $TSDB_CFG_CTYPE_B_OPTION = 16U
+set $TSDB_CFG_CTYPE_B_NOT_PRINT = 32U
+
+set $TSDB_CFG_PRINT_LEN = 53
+
+define print_blank
+ if $argc == 1
+ set $blank_len = $arg0
+ while $blank_len > 0
+ printf "%s", " "
+ set $blank_len = $blank_len - 1
+ end
+ end
+end
+
+define dump_cfg
+ if $argc != 1
+ help dump_cfg
+ else
+ set $blen = $TSDB_CFG_PRINT_LEN - (int)strlen($arg0.option)
+ if $blen < 0
+ $blen = 0
+ end
+ #printf "%s: %d\n", "******blen: ", $blen
+ printf "%s: ", $arg0.option
+ print_blank $blen
+
+ if $arg0.valType == $TAOS_CFG_VTYPE_INT8
+ printf "%d\n", *((int8_t *) $arg0.ptr)
+ else
+ if $arg0.valType == $TAOS_CFG_VTYPE_INT16
+ printf "%d\n", *((int16_t *) $arg0.ptr)
+ else
+ if $arg0.valType == $TAOS_CFG_VTYPE_INT32
+ printf "%d\n", *((int32_t *) $arg0.ptr)
+ else
+ if $arg0.valType == $TAOS_CFG_VTYPE_FLOAT
+ printf "%f\n", *((float *) $arg0.ptr)
+ else
+ printf "%s\n", $arg0.ptr
+ end
+ end
+ end
+ end
+ end
+end
+
+document dump_cfg
+Dump a cfg entry
+Usage: dump_cfg cfg
+end
+
+set pagination off
+
+attach_pidof taosd
+
+set $idx=0
+#print tsGlobalConfigNum
+#set $end=$1
+set $end=tsGlobalConfigNum
+
+p "*=*=*=*=*=*=*=*=*= taos global config:"
+#while ($idx .lt. $end)
+while ($idx < $end)
+ # print tsGlobalConfig[$idx].option
+ set $cfg = tsGlobalConfig[$idx]
+ set $tsce = tscEmbedded
+# p "1"
+ if ($tsce == 0)
+ if !($cfg.cfgType & $TSDB_CFG_CTYPE_B_CLIENT)
+ end
+ else
+ if $cfg.cfgType & $TSDB_CFG_CTYPE_B_NOT_PRINT
+ else
+ if !($cfg.cfgType & $TSDB_CFG_CTYPE_B_SHOW)
+ else
+ dump_cfg $cfg
+ end
+ end
+ end
+
+ set $idx=$idx+1
+end
+
+set $idx=0
+
+p "*=*=*=*=*=*=*=*=*= taos local config:"
+while ($idx < $end)
+ set $cfg = tsGlobalConfig[$idx]
+ set $tsce = tscEmbedded
+ if ($tsce == 0)
+ if !($cfg.cfgType & $TSDB_CFG_CTYPE_B_CLIENT)
+ end
+ else
+ if $cfg.cfgType & $TSDB_CFG_CTYPE_B_NOT_PRINT
+ else
+ if ($cfg.cfgType & $TSDB_CFG_CTYPE_B_SHOW)
+ else
+ dump_cfg $cfg
+ end
+ end
+ end
+
+ set $idx=$idx+1
+end
+
+detach
+
+quit
diff --git a/src/balance/src/bnThread.c b/src/balance/src/bnThread.c
index 84f8694fca..3931acd053 100644
--- a/src/balance/src/bnThread.c
+++ b/src/balance/src/bnThread.c
@@ -56,7 +56,7 @@ int32_t bnInitThread() {
pthread_attr_destroy(&thattr);
if (ret != 0) {
- mError("failed to create balance thread since %s", strerror(errno));
+ mError("failed to create balance thread since %s", strerror(ret));
return -1;
}
diff --git a/src/client/src/tscSQLParser.c b/src/client/src/tscSQLParser.c
index bdbe9d39c9..04d27d9c44 100644
--- a/src/client/src/tscSQLParser.c
+++ b/src/client/src/tscSQLParser.c
@@ -902,13 +902,17 @@ int32_t parseSlidingClause(SSqlObj* pSql, SQueryInfo* pQueryInfo, SQuerySQL* pQu
int32_t tscSetTableFullName(STableMetaInfo* pTableMetaInfo, SStrToken* pTableName, SSqlObj* pSql) {
const char* msg1 = "name too long";
+ const char* msg2 = "acctId too long";
SSqlCmd* pCmd = &pSql->cmd;
int32_t code = TSDB_CODE_SUCCESS;
if (hasSpecifyDB(pTableName)) { // db has been specified in sql string so we ignore current db path
- tNameSetAcctId(&pTableMetaInfo->name, getAccountId(pSql));
-
+ code = tNameSetAcctId(&pTableMetaInfo->name, getAccountId(pSql));
+ if (code != 0) {
+ return invalidSqlErrMsg(tscGetErrorMsgPayload(pCmd), msg2);
+ }
+
char name[TSDB_TABLE_FNAME_LEN] = {0};
strncpy(name, pTableName->z, pTableName->n);
diff --git a/src/client/src/tscServer.c b/src/client/src/tscServer.c
index 4b8fa45619..8403876566 100644
--- a/src/client/src/tscServer.c
+++ b/src/client/src/tscServer.c
@@ -2228,6 +2228,8 @@ int tscProcessRetrieveRspFromNode(SSqlObj *pSql) {
SSqlRes *pRes = &pSql->res;
SSqlCmd *pCmd = &pSql->cmd;
+ assert(pRes->rspLen >= sizeof(SRetrieveTableRsp));
+
SRetrieveTableRsp *pRetrieve = (SRetrieveTableRsp *)pRes->pRsp;
if (pRetrieve == NULL) {
pRes->code = TSDB_CODE_TSC_OUT_OF_MEMORY;
diff --git a/src/client/src/tscSql.c b/src/client/src/tscSql.c
index 7e7007444a..6b4d980945 100644
--- a/src/client/src/tscSql.c
+++ b/src/client/src/tscSql.c
@@ -110,6 +110,7 @@ static SSqlObj *taosConnectImpl(const char *ip, const char *user, const char *pa
rpcClose(pDnodeConn);
free(pObj->tscCorMgmtEpSet);
free(pObj);
+ return NULL;
}
memcpy(pObj->tscCorMgmtEpSet, &corMgmtEpSet, sizeof(SRpcCorEpSet));
diff --git a/src/common/src/tname.c b/src/common/src/tname.c
index 5c49e2e102..bbb0a8c082 100644
--- a/src/common/src/tname.c
+++ b/src/common/src/tname.c
@@ -367,6 +367,9 @@ int32_t tNameSetAcctId(SName* dst, const char* acct) {
}
tstrncpy(dst->acctId, acct, tListLen(dst->acctId));
+
+ assert(strlen(dst->acctId) > 0);
+
return 0;
}
@@ -383,12 +386,14 @@ int32_t tNameFromString(SName* dst, const char* str, uint32_t type) {
int32_t len = (int32_t)(p - str);
// too long account id or too long db name
- if (len >= tListLen(dst->acctId) || len == 0) {
+ if ((len >= tListLen(dst->acctId)) || (len <= 0)) {
return -1;
}
memcpy (dst->acctId, str, len);
dst->acctId[len] = 0;
+
+ assert(strlen(dst->acctId) > 0);
}
if ((type & T_NAME_DB) == T_NAME_DB) {
@@ -404,7 +409,7 @@ int32_t tNameFromString(SName* dst, const char* str, uint32_t type) {
}
// too long account id or too long db name
- if (len >= tListLen(dst->dbname) || len == 0) {
+ if ((len >= tListLen(dst->dbname)) || (len <= 0)) {
return -1;
}
@@ -419,7 +424,7 @@ int32_t tNameFromString(SName* dst, const char* str, uint32_t type) {
int32_t len = (int32_t) strlen(start);
// too long account id or too long db name
- if (len >= tListLen(dst->tname) || len == 0) {
+ if ((len >= tListLen(dst->tname)) || (len <= 0)) {
return -1;
}
diff --git a/src/connector/jdbc/CMakeLists.txt b/src/connector/jdbc/CMakeLists.txt
index 7097e9bc5a..b64161e2e4 100644
--- a/src/connector/jdbc/CMakeLists.txt
+++ b/src/connector/jdbc/CMakeLists.txt
@@ -8,7 +8,7 @@ IF (TD_MVN_INSTALLED)
ADD_CUSTOM_COMMAND(OUTPUT ${JDBC_CMD_NAME}
POST_BUILD
COMMAND mvn -Dmaven.test.skip=true install -f ${CMAKE_CURRENT_SOURCE_DIR}/pom.xml
- COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/target/taos-jdbcdriver-2.0.16-dist.jar ${LIBRARY_OUTPUT_PATH}
+ COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_CURRENT_SOURCE_DIR}/target/taos-jdbcdriver-2.0.17-dist.jar ${LIBRARY_OUTPUT_PATH}
COMMAND mvn -Dmaven.test.skip=true clean -f ${CMAKE_CURRENT_SOURCE_DIR}/pom.xml
COMMENT "build jdbc driver")
ADD_CUSTOM_TARGET(${JDBC_TARGET_NAME} ALL WORKING_DIRECTORY ${EXECUTABLE_OUTPUT_PATH} DEPENDS ${JDBC_CMD_NAME})
diff --git a/src/connector/jdbc/deploy-pom.xml b/src/connector/jdbc/deploy-pom.xml
index 5aa60c0df9..1f03c3c6fe 100755
--- a/src/connector/jdbc/deploy-pom.xml
+++ b/src/connector/jdbc/deploy-pom.xml
@@ -5,7 +5,7 @@
com.taosdata.jdbc
taos-jdbcdriver
- 2.0.16
+ 2.0.17
jar
JDBCDriver
diff --git a/src/connector/jdbc/pom.xml b/src/connector/jdbc/pom.xml
index d18d86258a..6be0ca036e 100755
--- a/src/connector/jdbc/pom.xml
+++ b/src/connector/jdbc/pom.xml
@@ -3,7 +3,7 @@
4.0.0
com.taosdata.jdbc
taos-jdbcdriver
- 2.0.16
+ 2.0.17
jar
JDBCDriver
https://github.com/taosdata/TDengine/tree/master/src/connector/jdbc
@@ -74,6 +74,14 @@
1.2.58
+
+
+ org.apache.commons
+ commons-dbcp2
+ 2.7.0
+
+
+
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 8ab0e4429a..08414d05e9 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
@@ -1,28 +1,13 @@
-/***************************************************************************
- * Copyright (c) 2019 TAOS Data, Inc.
- *
- * This program is free software: you can use, redistribute, and/or modify
- * it under the terms of the GNU Affero General Public License, version 3
- * or later ("AGPL"), as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see .
- *****************************************************************************/
package com.taosdata.jdbc;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
-public abstract class AbstractDatabaseMetaData implements DatabaseMetaData {
+public abstract class AbstractDatabaseMetaData implements DatabaseMetaData, Wrapper {
private final static String PRODUCT_NAME = "TDengine";
private final static String PRODUCT_VESION = "2.0.x.x";
- private final static String DRIVER_NAME = "taos-jdbcdriver";
private final static String DRIVER_VERSION = "2.0.x";
private final static int DRIVER_MAJAR_VERSION = 2;
private final static int DRIVER_MINOR_VERSION = 0;
@@ -67,9 +52,7 @@ public abstract class AbstractDatabaseMetaData implements DatabaseMetaData {
return PRODUCT_VESION;
}
- public String getDriverName() throws SQLException {
- return DRIVER_NAME;
- }
+ public abstract String getDriverName() throws SQLException;
public String getDriverVersion() throws SQLException {
return DRIVER_VERSION;
@@ -92,6 +75,7 @@ public abstract class AbstractDatabaseMetaData implements DatabaseMetaData {
}
public boolean supportsMixedCaseIdentifiers() throws SQLException {
+ //像database、table这些对象的标识符,在存储时是否采用大小写混合的模式
return false;
}
@@ -100,7 +84,7 @@ public abstract class AbstractDatabaseMetaData implements DatabaseMetaData {
}
public boolean storesLowerCaseIdentifiers() throws SQLException {
- return false;
+ return true;
}
public boolean storesMixedCaseIdentifiers() throws SQLException {
@@ -168,10 +152,12 @@ public abstract class AbstractDatabaseMetaData implements DatabaseMetaData {
}
public boolean nullPlusNonNullIsNull() throws SQLException {
+ // null + non-null != null
return false;
}
public boolean supportsConvert() throws SQLException {
+ // 是否支持转换函数convert
return false;
}
@@ -196,7 +182,7 @@ public abstract class AbstractDatabaseMetaData implements DatabaseMetaData {
}
public boolean supportsGroupBy() throws SQLException {
- return false;
+ return true;
}
public boolean supportsGroupByUnrelated() throws SQLException {
@@ -468,7 +454,7 @@ public abstract class AbstractDatabaseMetaData implements DatabaseMetaData {
}
public int getDefaultTransactionIsolation() throws SQLException {
- return 0;
+ return Connection.TRANSACTION_NONE;
}
public boolean supportsTransactions() throws SQLException {
@@ -476,6 +462,8 @@ public abstract class AbstractDatabaseMetaData implements DatabaseMetaData {
}
public boolean supportsTransactionIsolationLevel(int level) throws SQLException {
+ if (level == Connection.TRANSACTION_NONE)
+ return true;
return false;
}
@@ -495,18 +483,113 @@ public abstract class AbstractDatabaseMetaData implements DatabaseMetaData {
return false;
}
- public ResultSet getProcedures(String catalog, String schemaPattern, String procedureNamePattern)
- throws SQLException {
+ public ResultSet getProcedures(String catalog, String schemaPattern, String procedureNamePattern) throws SQLException {
return null;
}
- public ResultSet getProcedureColumns(String catalog, String schemaPattern, String procedureNamePattern,
- String columnNamePattern) throws SQLException {
+ public ResultSet getProcedureColumns(String catalog, String schemaPattern, String procedureNamePattern, String columnNamePattern) throws SQLException {
return null;
}
- public abstract ResultSet getTables(String catalog, String schemaPattern, String tableNamePattern, String[] types)
- throws SQLException;
+ public abstract ResultSet getTables(String catalog, String schemaPattern, String tableNamePattern, String[] types) throws SQLException;
+
+ protected ResultSet getTables(String catalog, String schemaPattern, String tableNamePattern, String[] types, Connection connection) throws SQLException {
+ try (Statement stmt = connection.createStatement()) {
+ if (catalog == null || catalog.isEmpty())
+ return null;
+
+ ResultSet databases = stmt.executeQuery("show databases");
+ String dbname = null;
+ while (databases.next()) {
+ dbname = databases.getString("name");
+ if (dbname.equalsIgnoreCase(catalog))
+ break;
+ }
+ databases.close();
+ if (dbname == null)
+ return null;
+
+ stmt.execute("use " + dbname);
+ DatabaseMetaDataResultSet resultSet = new DatabaseMetaDataResultSet();
+ List columnMetaDataList = new ArrayList<>();
+ ColumnMetaData col1 = new ColumnMetaData();
+ col1.setColIndex(1);
+ col1.setColName("TABLE_CAT");
+ col1.setColType(TSDBConstants.TSDB_DATA_TYPE_NCHAR);
+ columnMetaDataList.add(col1);
+ ColumnMetaData col2 = new ColumnMetaData();
+ col2.setColIndex(2);
+ col2.setColName("TABLE_SCHEM");
+ col2.setColType(TSDBConstants.TSDB_DATA_TYPE_NCHAR);
+ columnMetaDataList.add(col2);
+ ColumnMetaData col3 = new ColumnMetaData();
+ col3.setColIndex(3);
+ col3.setColName("TABLE_NAME");
+ col3.setColType(TSDBConstants.TSDB_DATA_TYPE_NCHAR);
+ columnMetaDataList.add(col3);
+ ColumnMetaData col4 = new ColumnMetaData();
+ col4.setColIndex(4);
+ col4.setColName("TABLE_TYPE");
+ col4.setColType(TSDBConstants.TSDB_DATA_TYPE_NCHAR);
+ columnMetaDataList.add(col4);
+ ColumnMetaData col5 = new ColumnMetaData();
+ col5.setColIndex(5);
+ col5.setColName("REMARKS");
+ col5.setColType(TSDBConstants.TSDB_DATA_TYPE_NCHAR);
+ columnMetaDataList.add(col5);
+ ColumnMetaData col6 = new ColumnMetaData();
+ col6.setColIndex(6);
+ col6.setColName("TYPE_CAT");
+ col6.setColType(TSDBConstants.TSDB_DATA_TYPE_NCHAR);
+ columnMetaDataList.add(col6);
+ ColumnMetaData col7 = new ColumnMetaData();
+ col7.setColIndex(7);
+ col7.setColName("TYPE_SCHEM");
+ col7.setColType(TSDBConstants.TSDB_DATA_TYPE_NCHAR);
+ columnMetaDataList.add(col7);
+ ColumnMetaData col8 = new ColumnMetaData();
+ col8.setColIndex(8);
+ col8.setColName("TYPE_NAME");
+ col8.setColType(TSDBConstants.TSDB_DATA_TYPE_NCHAR);
+ columnMetaDataList.add(col8);
+ ColumnMetaData col9 = new ColumnMetaData();
+ col9.setColIndex(9);
+ col9.setColName("SELF_REFERENCING_COL_NAME");
+ col9.setColType(TSDBConstants.TSDB_DATA_TYPE_NCHAR);
+ columnMetaDataList.add(col9);
+ ColumnMetaData col10 = new ColumnMetaData();
+ col10.setColIndex(10);
+ col10.setColName("REF_GENERATION");
+ col10.setColType(TSDBConstants.TSDB_DATA_TYPE_NCHAR);
+ columnMetaDataList.add(col10);
+ resultSet.setColumnMetaDataList(columnMetaDataList);
+
+ List rowDataList = new ArrayList<>();
+ ResultSet tables = stmt.executeQuery("show tables");
+ while (tables.next()) {
+ TSDBResultSetRowData rowData = new TSDBResultSetRowData(10);
+ rowData.setString(0, dbname); //table_cat
+ rowData.setString(1, null); //TABLE_SCHEM
+ rowData.setString(2, tables.getString("table_name")); //TABLE_NAME
+ rowData.setString(3, "TABLE"); //TABLE_TYPE
+ rowData.setString(4, ""); //REMARKS
+ rowDataList.add(rowData);
+ }
+
+ ResultSet stables = stmt.executeQuery("show stables");
+ while (stables.next()) {
+ TSDBResultSetRowData rowData = new TSDBResultSetRowData(10);
+ rowData.setString(0, dbname); //TABLE_CAT
+ rowData.setString(1, null); //TABLE_SCHEM
+ rowData.setString(2, stables.getString("name")); //TABLE_NAME
+ rowData.setString(3, "TABLE"); //TABLE_TYPE
+ rowData.setString(4, "STABLE"); //REMARKS
+ rowDataList.add(rowData);
+ }
+ resultSet.setRowDataList(rowDataList);
+ return resultSet;
+ }
+ }
public ResultSet getSchemas() throws SQLException {
return getEmptyResultSet();
@@ -516,32 +599,239 @@ public abstract class AbstractDatabaseMetaData implements DatabaseMetaData {
public ResultSet getTableTypes() throws SQLException {
DatabaseMetaDataResultSet resultSet = new DatabaseMetaDataResultSet();
-
// set up ColumnMetaDataList
- List columnMetaDataList = new ArrayList(1);
+ List columnMetaDataList = new ArrayList<>();
ColumnMetaData colMetaData = new ColumnMetaData();
colMetaData.setColIndex(0);
colMetaData.setColName("TABLE_TYPE");
colMetaData.setColSize(10);
- colMetaData.setColType(TSDBConstants.TSDB_DATA_TYPE_BINARY);
+ colMetaData.setColType(TSDBConstants.TSDB_DATA_TYPE_NCHAR);
columnMetaDataList.add(colMetaData);
+ resultSet.setColumnMetaDataList(columnMetaDataList);
// set up rowDataList
- List rowDataList = new ArrayList(2);
- TSDBResultSetRowData rowData = new TSDBResultSetRowData();
+ List rowDataList = new ArrayList<>();
+ TSDBResultSetRowData rowData = new TSDBResultSetRowData(1);
rowData.setString(0, "TABLE");
rowDataList.add(rowData);
- rowData = new TSDBResultSetRowData();
+ rowData = new TSDBResultSetRowData(1);
rowData.setString(0, "STABLE");
rowDataList.add(rowData);
-
- resultSet.setColumnMetaDataList(columnMetaDataList);
resultSet.setRowDataList(rowDataList);
+
return resultSet;
}
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) {
+ try (Statement stmt = conn.createStatement()) {
+ if (catalog == null || catalog.isEmpty())
+ return null;
+
+ ResultSet databases = stmt.executeQuery("show databases");
+ String dbname = null;
+ while (databases.next()) {
+ dbname = databases.getString("name");
+ if (dbname.equalsIgnoreCase(catalog))
+ break;
+ }
+ databases.close();
+ if (dbname == null)
+ return null;
+
+ stmt.execute("use " + dbname);
+ DatabaseMetaDataResultSet resultSet = new DatabaseMetaDataResultSet();
+ // set up ColumnMetaDataList
+
+ List columnMetaDataList = new ArrayList<>();
+ // TABLE_CAT
+ ColumnMetaData col1 = new ColumnMetaData();
+ col1.setColIndex(1);
+ col1.setColName("TABLE_CAT");
+ col1.setColType(TSDBConstants.TSDB_DATA_TYPE_NCHAR);
+ columnMetaDataList.add(col1);
+ // TABLE_SCHEM
+ ColumnMetaData col2 = new ColumnMetaData();
+ col2.setColIndex(2);
+ col2.setColName("TABLE_SCHEM");
+ col2.setColType(TSDBConstants.TSDB_DATA_TYPE_NCHAR);
+ columnMetaDataList.add(col2);
+ // TABLE_NAME
+ ColumnMetaData col3 = new ColumnMetaData();
+ col3.setColIndex(3);
+ col3.setColName("TABLE_NAME");
+ col3.setColSize(193);
+ col3.setColType(TSDBConstants.TSDB_DATA_TYPE_NCHAR);
+ columnMetaDataList.add(col3);
+ // COLUMN_NAME
+ ColumnMetaData col4 = new ColumnMetaData();
+ col4.setColIndex(4);
+ col4.setColName("COLUMN_NAME");
+ col4.setColSize(65);
+ col4.setColType(TSDBConstants.TSDB_DATA_TYPE_NCHAR);
+ columnMetaDataList.add(col4);
+ // DATA_TYPE
+ ColumnMetaData col5 = new ColumnMetaData();
+ col5.setColIndex(5);
+ col5.setColName("DATA_TYPE");
+ col5.setColType(TSDBConstants.TSDB_DATA_TYPE_INT);
+ columnMetaDataList.add(col5);
+ // TYPE_NAME
+ ColumnMetaData col6 = new ColumnMetaData();
+ col6.setColIndex(6);
+ col6.setColName("TYPE_NAME");
+ col6.setColType(TSDBConstants.TSDB_DATA_TYPE_NCHAR);
+ columnMetaDataList.add(col6);
+ // COLUMN_SIZE
+ ColumnMetaData col7 = new ColumnMetaData();
+ col7.setColIndex(7);
+ col7.setColName("COLUMN_SIZE");
+ col7.setColType(TSDBConstants.TSDB_DATA_TYPE_INT);
+ columnMetaDataList.add(col7);
+ // BUFFER_LENGTH, not used
+ ColumnMetaData col8 = new ColumnMetaData();
+ col8.setColIndex(8);
+ col8.setColName("BUFFER_LENGTH");
+ columnMetaDataList.add(col8);
+ // DECIMAL_DIGITS
+ ColumnMetaData col9 = new ColumnMetaData();
+ col9.setColIndex(9);
+ col9.setColName("DECIMAL_DIGITS");
+ col9.setColType(TSDBConstants.TSDB_DATA_TYPE_INT);
+ columnMetaDataList.add(col9);
+ // add NUM_PREC_RADIX
+ ColumnMetaData col10 = new ColumnMetaData();
+ col10.setColIndex(10);
+ col10.setColName("NUM_PREC_RADIX");
+ col10.setColType(TSDBConstants.TSDB_DATA_TYPE_INT);
+ columnMetaDataList.add(col10);
+ // NULLABLE
+ ColumnMetaData col11 = new ColumnMetaData();
+ col11.setColIndex(11);
+ col11.setColName("NULLABLE");
+ col11.setColType(TSDBConstants.TSDB_DATA_TYPE_INT);
+ columnMetaDataList.add(col11);
+ // REMARKS
+ ColumnMetaData col12 = new ColumnMetaData();
+ col12.setColIndex(12);
+ col12.setColName("REMARKS");
+ col12.setColType(TSDBConstants.TSDB_DATA_TYPE_NCHAR);
+ columnMetaDataList.add(col12);
+ // COLUMN_DEF
+ ColumnMetaData col13 = new ColumnMetaData();
+ col13.setColIndex(13);
+ col13.setColName("COLUMN_DEF");
+ col13.setColType(TSDBConstants.TSDB_DATA_TYPE_NCHAR);
+ columnMetaDataList.add(col13);
+ //SQL_DATA_TYPE
+ ColumnMetaData col14 = new ColumnMetaData();
+ col14.setColIndex(14);
+ col14.setColName("SQL_DATA_TYPE");
+ col14.setColType(TSDBConstants.TSDB_DATA_TYPE_INT);
+ columnMetaDataList.add(col14);
+ //SQL_DATETIME_SUB
+ ColumnMetaData col15 = new ColumnMetaData();
+ col15.setColIndex(15);
+ col15.setColName("SQL_DATETIME_SUB");
+ col15.setColType(TSDBConstants.TSDB_DATA_TYPE_INT);
+ columnMetaDataList.add(col15);
+ //CHAR_OCTET_LENGTH
+ ColumnMetaData col16 = new ColumnMetaData();
+ col16.setColIndex(16);
+ col16.setColName("CHAR_OCTET_LENGTH");
+ col16.setColType(TSDBConstants.TSDB_DATA_TYPE_INT);
+ columnMetaDataList.add(col16);
+ //ORDINAL_POSITION
+ ColumnMetaData col17 = new ColumnMetaData();
+ col17.setColIndex(17);
+ col17.setColName("ORDINAL_POSITION");
+ col17.setColType(TSDBConstants.TSDB_DATA_TYPE_INT);
+ columnMetaDataList.add(col17);
+ // IS_NULLABLE
+ ColumnMetaData col18 = new ColumnMetaData();
+ col18.setColIndex(18);
+ col18.setColName("IS_NULLABLE");
+ col18.setColType(TSDBConstants.TSDB_DATA_TYPE_NCHAR);
+ columnMetaDataList.add(col18);
+ //SCOPE_CATALOG
+ ColumnMetaData col19 = new ColumnMetaData();
+ col19.setColIndex(19);
+ col19.setColName("SCOPE_CATALOG");
+ col19.setColType(TSDBConstants.TSDB_DATA_TYPE_NCHAR);
+ columnMetaDataList.add(col19);
+ //SCOPE_SCHEMA
+ ColumnMetaData col20 = new ColumnMetaData();
+ col20.setColIndex(20);
+ col20.setColName("SCOPE_SCHEMA");
+ col20.setColType(TSDBConstants.TSDB_DATA_TYPE_NCHAR);
+ columnMetaDataList.add(col20);
+ //SCOPE_TABLE
+ ColumnMetaData col21 = new ColumnMetaData();
+ col21.setColIndex(21);
+ col21.setColName("SCOPE_TABLE");
+ col21.setColType(TSDBConstants.TSDB_DATA_TYPE_NCHAR);
+ columnMetaDataList.add(col21);
+ //SOURCE_DATA_TYPE
+ ColumnMetaData col22 = new ColumnMetaData();
+ col22.setColIndex(22);
+ col22.setColName("SOURCE_DATA_TYPE");
+ col22.setColType(TSDBConstants.TSDB_DATA_TYPE_SMALLINT);
+ columnMetaDataList.add(col22);
+ //IS_AUTOINCREMENT
+ ColumnMetaData col23 = new ColumnMetaData();
+ col23.setColIndex(23);
+ col23.setColName("IS_AUTOINCREMENT");
+ col23.setColType(TSDBConstants.TSDB_DATA_TYPE_NCHAR);
+ columnMetaDataList.add(col23);
+ //IS_GENERATEDCOLUMN
+ ColumnMetaData col24 = new ColumnMetaData();
+ col24.setColIndex(24);
+ col24.setColName("IS_GENERATEDCOLUMN");
+ col24.setColType(TSDBConstants.TSDB_DATA_TYPE_NCHAR);
+ columnMetaDataList.add(col24);
+
+ resultSet.setColumnMetaDataList(columnMetaDataList);
+ // set up rowDataList
+ ResultSet rs = stmt.executeQuery("describe " + dbname + "." + tableNamePattern);
+ List rowDataList = new ArrayList<>();
+ int index = 0;
+ while (rs.next()) {
+ TSDBResultSetRowData rowData = new TSDBResultSetRowData(24);
+ // set TABLE_CAT
+ rowData.setString(0, dbname);
+ // set TABLE_NAME
+ rowData.setString(2, tableNamePattern);
+ // set COLUMN_NAME
+ rowData.setString(3, rs.getString("Field"));
+ // set DATA_TYPE
+ String typeName = rs.getString("Type");
+ rowData.setInt(4, getDataType(typeName));
+ // set TYPE_NAME
+ rowData.setString(5, typeName);
+ // set COLUMN_SIZE
+ int length = rs.getInt("Length");
+ rowData.setInt(6, getColumnSize(typeName, length));
+ // set DECIMAL_DIGITS
+ rowData.setInt(8, getDecimalDigits(typeName));
+ // set NUM_PREC_RADIX
+ rowData.setInt(9, 10);
+ // set NULLABLE
+ rowData.setInt(10, getNullable(index, typeName));
+ // set REMARKS
+ rowData.setString(11, rs.getString("Note"));
+ rowDataList.add(rowData);
+ index++;
+ }
+ resultSet.setRowDataList(rowDataList);
+ return resultSet;
+
+ } catch (SQLException e) {
+ e.printStackTrace();
+ }
+ return null;
+ }
+
protected int getNullable(int index, String typeName) {
if (index == 0 && "TIMESTAMP".equals(typeName))
return DatabaseMetaData.columnNoNulls;
@@ -552,7 +842,6 @@ public abstract class AbstractDatabaseMetaData implements DatabaseMetaData {
switch (typeName) {
case "TIMESTAMP":
return 23;
-
default:
return 0;
}
@@ -615,9 +904,7 @@ public abstract class AbstractDatabaseMetaData implements DatabaseMetaData {
return getEmptyResultSet();
}
- public ResultSet getPrimaryKeys(String catalog, String schema, String table) throws SQLException {
- return getEmptyResultSet();
- }
+ public abstract ResultSet getPrimaryKeys(String catalog, String schema, String table) throws SQLException;
public ResultSet getImportedKeys(String catalog, String schema, String table) throws SQLException {
return getEmptyResultSet();
@@ -718,9 +1005,7 @@ public abstract class AbstractDatabaseMetaData implements DatabaseMetaData {
return getEmptyResultSet();
}
- public ResultSet getSuperTables(String catalog, String schemaPattern, String tableNamePattern) throws SQLException {
- return getEmptyResultSet();
- }
+ public abstract ResultSet getSuperTables(String catalog, String schemaPattern, String tableNamePattern) throws SQLException;
public ResultSet getAttributes(String catalog, String schemaPattern, String typeNamePattern,
String attributeNamePattern) throws SQLException {
@@ -728,15 +1013,17 @@ public abstract class AbstractDatabaseMetaData implements DatabaseMetaData {
}
public boolean supportsResultSetHoldability(int holdability) throws SQLException {
+ if (holdability == ResultSet.HOLD_CURSORS_OVER_COMMIT)
+ return true;
return false;
}
public int getResultSetHoldability() throws SQLException {
- return 0;
+ return ResultSet.HOLD_CURSORS_OVER_COMMIT;
}
public int getDatabaseMajorVersion() throws SQLException {
- return 0;
+ return 2;
}
public int getDatabaseMinorVersion() throws SQLException {
@@ -744,7 +1031,7 @@ public abstract class AbstractDatabaseMetaData implements DatabaseMetaData {
}
public int getJDBCMajorVersion() throws SQLException {
- return 0;
+ return 2;
}
public int getJDBCMinorVersion() throws SQLException {
@@ -768,7 +1055,7 @@ public abstract class AbstractDatabaseMetaData implements DatabaseMetaData {
}
public ResultSet getSchemas(String catalog, String schemaPattern) throws SQLException {
- return null;
+ return getEmptyResultSet();
}
public boolean supportsStoredFunctionsUsingCallSyntax() throws SQLException {
@@ -805,4 +1092,180 @@ public abstract class AbstractDatabaseMetaData implements DatabaseMetaData {
private ResultSet getEmptyResultSet() {
return new EmptyResultSet();
}
+
+ @Override
+ public T unwrap(Class iface) throws SQLException {
+ try {
+ return iface.cast(this);
+ } catch (ClassCastException cce) {
+ throw new SQLException("Unable to unwrap to " + iface.toString());
+ }
+ }
+
+ @Override
+ public boolean isWrapperFor(Class> iface) throws SQLException {
+ return iface.isInstance(this);
+ }
+
+ protected ResultSet getCatalogs(Connection conn) throws SQLException {
+ try (Statement stmt = conn.createStatement()) {
+ DatabaseMetaDataResultSet resultSet = new DatabaseMetaDataResultSet();
+ // set up ColumnMetaDataList
+ List columnMetaDataList = new ArrayList<>();
+ // TABLE_CAT
+ ColumnMetaData col1 = new ColumnMetaData();
+ col1.setColIndex(1);
+ col1.setColName("TABLE_CAT");
+ col1.setColType(TSDBConstants.TSDB_DATA_TYPE_NCHAR);
+ columnMetaDataList.add(col1);
+
+ resultSet.setColumnMetaDataList(columnMetaDataList);
+
+ List rowDataList = new ArrayList<>();
+ ResultSet rs = stmt.executeQuery("show databases");
+ while (rs.next()) {
+ TSDBResultSetRowData rowData = new TSDBResultSetRowData(1);
+ rowData.setString(0, rs.getString("name"));
+ rowDataList.add(rowData);
+ }
+ resultSet.setRowDataList(rowDataList);
+ return resultSet;
+ }
+ }
+
+
+ protected ResultSet getPrimaryKeys(String catalog, String schema, String table, Connection conn) throws SQLException {
+ try (Statement stmt = conn.createStatement()) {
+ if (catalog == null || catalog.isEmpty())
+ return null;
+
+ ResultSet databases = stmt.executeQuery("show databases");
+ String dbname = null;
+ while (databases.next()) {
+ dbname = databases.getString("name");
+ if (dbname.equalsIgnoreCase(catalog))
+ break;
+ }
+ databases.close();
+ if (dbname == null)
+ return null;
+
+ stmt.execute("use " + dbname);
+ DatabaseMetaDataResultSet resultSet = new DatabaseMetaDataResultSet();
+ // set up ColumnMetaDataList
+ List columnMetaDataList = new ArrayList<>();
+ // TABLE_CAT
+ ColumnMetaData col1 = new ColumnMetaData();
+ col1.setColIndex(0);
+ col1.setColName("TABLE_CAT");
+ col1.setColType(TSDBConstants.TSDB_DATA_TYPE_NCHAR);
+ columnMetaDataList.add(col1);
+ // TABLE_SCHEM
+ ColumnMetaData col2 = new ColumnMetaData();
+ col2.setColIndex(1);
+ col2.setColName("TABLE_SCHEM");
+ col2.setColType(TSDBConstants.TSDB_DATA_TYPE_NCHAR);
+ columnMetaDataList.add(col2);
+ // TABLE_NAME
+ ColumnMetaData col3 = new ColumnMetaData();
+ col3.setColIndex(2);
+ col3.setColName("TABLE_NAME");
+ col3.setColType(TSDBConstants.TSDB_DATA_TYPE_NCHAR);
+ columnMetaDataList.add(col3);
+ // COLUMN_NAME
+ ColumnMetaData col4 = new ColumnMetaData();
+ col4.setColIndex(3);
+ col4.setColName("COLUMN_NAME");
+ col4.setColType(TSDBConstants.TSDB_DATA_TYPE_NCHAR);
+ columnMetaDataList.add(col4);
+ // KEY_SEQ
+ ColumnMetaData col5 = new ColumnMetaData();
+ col5.setColIndex(4);
+ col5.setColName("KEY_SEQ");
+ col5.setColType(TSDBConstants.TSDB_DATA_TYPE_INT);
+ columnMetaDataList.add(col5);
+ // PK_NAME
+ ColumnMetaData col6 = new ColumnMetaData();
+ col6.setColIndex(5);
+ col6.setColName("PK_NAME");
+ col6.setColType(TSDBConstants.TSDB_DATA_TYPE_NCHAR);
+ columnMetaDataList.add(col6);
+ resultSet.setColumnMetaDataList(columnMetaDataList);
+
+ // set rowData
+ List rowDataList = new ArrayList<>();
+ ResultSet rs = stmt.executeQuery("describe " + dbname + "." + table);
+ rs.next();
+ TSDBResultSetRowData rowData = new TSDBResultSetRowData(6);
+ rowData.setString(0, null);
+ rowData.setString(1, null);
+ rowData.setString(2, table);
+ String pkName = rs.getString(1);
+ rowData.setString(3, pkName);
+ rowData.setInt(4, 1);
+ rowData.setString(5, pkName);
+ rowDataList.add(rowData);
+ resultSet.setRowDataList(rowDataList);
+ return resultSet;
+ }
+ }
+
+ protected ResultSet getSuperTables(String catalog, String schemaPattern, String tableNamePattern, Connection conn) throws SQLException {
+ try (Statement stmt = conn.createStatement()) {
+ if (catalog == null || catalog.isEmpty())
+ return null;
+
+ ResultSet databases = stmt.executeQuery("show databases");
+ String dbname = null;
+ while (databases.next()) {
+ dbname = databases.getString("name");
+ if (dbname.equalsIgnoreCase(catalog))
+ break;
+ }
+ databases.close();
+ if (dbname == null)
+ return null;
+
+ stmt.execute("use " + dbname);
+ DatabaseMetaDataResultSet resultSet = new DatabaseMetaDataResultSet();
+ // set up ColumnMetaDataList
+ List columnMetaDataList = new ArrayList<>();
+ // TABLE_CAT
+ ColumnMetaData col1 = new ColumnMetaData();
+ col1.setColIndex(0);
+ col1.setColName("TABLE_CAT");
+ col1.setColType(TSDBConstants.TSDB_DATA_TYPE_NCHAR);
+ columnMetaDataList.add(col1);
+ // TABLE_SCHEM
+ ColumnMetaData col2 = new ColumnMetaData();
+ col2.setColIndex(1);
+ col2.setColName("TABLE_SCHEM");
+ col2.setColType(TSDBConstants.TSDB_DATA_TYPE_NCHAR);
+ columnMetaDataList.add(col2);
+ // TABLE_NAME
+ ColumnMetaData col3 = new ColumnMetaData();
+ col3.setColIndex(2);
+ col3.setColName("TABLE_NAME");
+ col3.setColType(TSDBConstants.TSDB_DATA_TYPE_NCHAR);
+ columnMetaDataList.add(col3);
+ // SUPERTABLE_NAME
+ ColumnMetaData col4 = new ColumnMetaData();
+ col4.setColIndex(3);
+ col4.setColName("SUPERTABLE_NAME");
+ col4.setColType(TSDBConstants.TSDB_DATA_TYPE_NCHAR);
+ columnMetaDataList.add(col4);
+ resultSet.setColumnMetaDataList(columnMetaDataList);
+
+ ResultSet rs = stmt.executeQuery("show tables like '" + tableNamePattern + "'");
+ List rowDataList = new ArrayList<>();
+ while (rs.next()) {
+ TSDBResultSetRowData rowData = new TSDBResultSetRowData(4);
+ rowData.setString(2, rs.getString(1));
+ rowData.setString(3, rs.getString(4));
+ rowDataList.add(rowData);
+ }
+ resultSet.setRowDataList(rowDataList);
+ return resultSet;
+ }
+ }
}
\ No newline at end of file
diff --git a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/CatalogResultSet.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/CatalogResultSet.java
deleted file mode 100644
index 3a01e2e092..0000000000
--- a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/CatalogResultSet.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/***************************************************************************
- * Copyright (c) 2019 TAOS Data, Inc.
- *
- * This program is free software: you can use, redistribute, and/or modify
- * it under the terms of the GNU Affero General Public License, version 3
- * or later ("AGPL"), as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see .
- *****************************************************************************/
-package com.taosdata.jdbc;
-
-import java.sql.ResultSet;
-import java.sql.SQLException;
-
-/*
- * TDengine only supports a subset of the standard SQL, thus this implemetation of the
- * standard JDBC API contains more or less some adjustments customized for certain
- * compatibility needs.
- */
-public class CatalogResultSet extends TSDBResultSetWrapper {
-
-
- public CatalogResultSet(ResultSet resultSet) {
- super.setOriginalResultSet(resultSet);
- }
-
- @Override
- public String getString(int columnIndex) throws SQLException {
- if (columnIndex <= 1) {
- return super.getString(columnIndex);
- } else {
- return null;
- }
- }
-
- @Override
- public boolean getBoolean(int columnIndex) throws SQLException {
- if (columnIndex <= 1) {
- return super.getBoolean(columnIndex);
- } else {
- return false;
- }
- }
-
- @Override
- public byte[] getBytes(int columnIndex) throws SQLException {
- if (columnIndex <= 1) {
- return super.getBytes(columnIndex);
- } else {
- return null;
- }
- }
-
- @Override
- public Object getObject(int columnIndex) throws SQLException {
- if (columnIndex <= 1) {
- return super.getObject(columnIndex);
- } else {
- return null;
- }
- }
-
-}
diff --git a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/ColumnMetaData.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/ColumnMetaData.java
index 633fdcd5ab..fe16aa6535 100644
--- a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/ColumnMetaData.java
+++ b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/ColumnMetaData.java
@@ -16,40 +16,40 @@ package com.taosdata.jdbc;
public class ColumnMetaData {
- private int colType = 0;
- private String colName = null;
- private int colSize = -1;
- private int colIndex = 0;
+ private int colType = 0;
+ private String colName = null;
+ private int colSize = -1;
+ private int colIndex = 0;
- public int getColSize() {
- return colSize;
- }
+ public int getColSize() {
+ return colSize;
+ }
- public void setColSize(int colSize) {
- this.colSize = colSize;
- }
+ public void setColSize(int colSize) {
+ this.colSize = colSize;
+ }
- public int getColType() {
- return colType;
- }
+ public int getColType() {
+ return colType;
+ }
- public void setColType(int colType) {
- this.colType = colType;
- }
+ public void setColType(int colType) {
+ this.colType = colType;
+ }
- public String getColName() {
- return colName;
- }
+ public String getColName() {
+ return colName;
+ }
- public void setColName(String colName) {
- this.colName = colName;
- }
+ public void setColName(String colName) {
+ this.colName = colName;
+ }
- public int getColIndex() {
- return colIndex;
- }
+ public int getColIndex() {
+ return colIndex;
+ }
- public void setColIndex(int colIndex) {
- this.colIndex = colIndex;
- }
+ public void setColIndex(int colIndex) {
+ this.colIndex = colIndex;
+ }
}
diff --git a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/GetColumnsResultSet.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/GetColumnsResultSet.java
deleted file mode 100644
index e15415e037..0000000000
--- a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/GetColumnsResultSet.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/***************************************************************************
- * Copyright (c) 2019 TAOS Data, Inc.
- *
- * This program is free software: you can use, redistribute, and/or modify
- * it under the terms of the GNU Affero General Public License, version 3
- * or later ("AGPL"), as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see .
- *****************************************************************************/
-package com.taosdata.jdbc;
-
-import java.sql.ResultSet;
-
-/*
- * TDengine only supports a subset of the standard SQL, thus this implemetation of the
- * standard JDBC API contains more or less some adjustments customized for certain
- * compatibility needs.
- */
-public class GetColumnsResultSet extends TSDBResultSetWrapper {
- private String catalog;
- private String schemaPattern;
- private String tableNamePattern;
- private String columnNamePattern;
-
- public GetColumnsResultSet(ResultSet resultSet, String catalog, String schemaPattern, String tableNamePattern, String columnNamePattern) {
- super.setOriginalResultSet(resultSet);
- this.catalog = catalog;
- this.schemaPattern = schemaPattern;
- this.tableNamePattern = tableNamePattern;
- this.columnNamePattern = columnNamePattern;
- }
-
- @Override
- public String getString(int columnIndex) {
- switch (columnIndex) {
- case 1:
- return catalog;
- case 2:
- return null;
- case 3:
- return tableNamePattern;
- default:
- return null;
- }
- }
-}
diff --git a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/GetTablesResultSet.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/GetTablesResultSet.java
deleted file mode 100644
index e28f6e3c9a..0000000000
--- a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/GetTablesResultSet.java
+++ /dev/null
@@ -1,53 +0,0 @@
-/***************************************************************************
- * Copyright (c) 2019 TAOS Data, Inc.
- *
- * This program is free software: you can use, redistribute, and/or modify
- * it under the terms of the GNU Affero General Public License, version 3
- * or later ("AGPL"), as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see .
- *****************************************************************************/
-package com.taosdata.jdbc;
-
-import java.sql.ResultSet;
-import java.sql.SQLException;
-
-/*
- * TDengine only supports a subset of the standard SQL, thus this implemetation of the
- * standard JDBC API contains more or less some adjustments customized for certain
- * compatibility needs.
- */
-public class GetTablesResultSet extends TSDBResultSetWrapper {
-
- private String catalog;
- private String schemaPattern;
- private String tableNamePattern;
- private String[] types;
-
- public GetTablesResultSet(ResultSet resultSet, String catalog, String schemaPattern, String tableNamePattern, String[] types) {
- super.setOriginalResultSet(resultSet);
- this.catalog = catalog;
- this.schemaPattern = schemaPattern;
- this.tableNamePattern = tableNamePattern;
- this.types = types;
- }
-
- @Override
- public String getString(int columnIndex) throws SQLException {
- String ret = null;
- switch (columnIndex) {
- case 3:
- return super.getString(1);
- case 4:
- return "table";
- default:
- return null;
- }
- }
-
-}
diff --git a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBDatabaseMetaData.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBDatabaseMetaData.java
index 4ea0fc7950..d1f1e77b1c 100644
--- a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBDatabaseMetaData.java
+++ b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBDatabaseMetaData.java
@@ -14,11 +14,11 @@
*****************************************************************************/
package com.taosdata.jdbc;
-import java.sql.*;
-import java.util.ArrayList;
-import java.util.List;
+import java.sql.Connection;
+import java.sql.ResultSet;
+import java.sql.SQLException;
-public class TSDBDatabaseMetaData implements java.sql.DatabaseMetaData {
+public class TSDBDatabaseMetaData extends AbstractDatabaseMetaData {
private String url;
private String userName;
@@ -29,31 +29,14 @@ public class TSDBDatabaseMetaData implements java.sql.DatabaseMetaData {
this.userName = userName;
}
+ public Connection getConnection() throws SQLException {
+ return this.conn;
+ }
+
public void setConnection(Connection conn) {
this.conn = conn;
}
- @Override
- public T unwrap(Class iface) throws SQLException {
- try {
- return iface.cast(this);
- } catch (ClassCastException cce) {
- throw new SQLException("Unable to unwrap to " + iface.toString());
- }
- }
-
- public boolean isWrapperFor(Class> iface) throws SQLException {
- return iface.isInstance(this);
- }
-
- public boolean allProceduresAreCallable() throws SQLException {
- return false;
- }
-
- public boolean allTablesAreSelectable() throws SQLException {
- return false;
- }
-
public String getURL() throws SQLException {
return this.url;
}
@@ -62,911 +45,52 @@ public class TSDBDatabaseMetaData implements java.sql.DatabaseMetaData {
return this.userName;
}
- public boolean isReadOnly() throws SQLException {
- return false;
- }
-
- public boolean nullsAreSortedHigh() throws SQLException {
- return false;
- }
-
- public boolean nullsAreSortedLow() throws SQLException {
- return !nullsAreSortedHigh();
- }
-
- public boolean nullsAreSortedAtStart() throws SQLException {
- return true;
- }
-
- public boolean nullsAreSortedAtEnd() throws SQLException {
- return !nullsAreSortedAtStart();
- }
-
- public String getDatabaseProductName() throws SQLException {
- return "TDengine";
- }
-
- public String getDatabaseProductVersion() throws SQLException {
- return "2.0.x.x";
- }
-
public String getDriverName() throws SQLException {
return TSDBDriver.class.getName();
}
- public String getDriverVersion() throws SQLException {
- return "2.0.x";
- }
-
- public int getDriverMajorVersion() {
- return 2;
- }
-
- public int getDriverMinorVersion() {
- return 0;
- }
-
- public boolean usesLocalFiles() throws SQLException {
- return false;
- }
-
- public boolean usesLocalFilePerTable() throws SQLException {
- return false;
- }
-
-
- public boolean supportsMixedCaseIdentifiers() throws SQLException {
- //像database、table这些对象的标识符,在存储时是否采用大小写混合的模式
- return false;
- }
-
- public boolean storesUpperCaseIdentifiers() throws SQLException {
- return false;
- }
-
- public boolean storesLowerCaseIdentifiers() throws SQLException {
- return true;
- }
-
- public boolean storesMixedCaseIdentifiers() throws SQLException {
- return false;
- }
-
- public boolean supportsMixedCaseQuotedIdentifiers() throws SQLException {
- //像database、table这些对象的标识符,在存储时是否采用大小写混合、并带引号的模式
- return false;
- }
-
- public boolean storesUpperCaseQuotedIdentifiers() throws SQLException {
- return false;
- }
-
- public boolean storesLowerCaseQuotedIdentifiers() throws SQLException {
- return false;
- }
-
- public boolean storesMixedCaseQuotedIdentifiers() throws SQLException {
- return false;
- }
-
- public String getIdentifierQuoteString() throws SQLException {
- return " ";
- }
-
- public String getSQLKeywords() throws SQLException {
- return null;
- }
-
- public String getNumericFunctions() throws SQLException {
- return null;
- }
-
- public String getStringFunctions() throws SQLException {
- return null;
- }
-
- public String getSystemFunctions() throws SQLException {
- return null;
- }
-
- public String getTimeDateFunctions() throws SQLException {
- return null;
- }
-
- public String getSearchStringEscape() throws SQLException {
- return null;
- }
-
- public String getExtraNameCharacters() throws SQLException {
- return null;
- }
-
- public boolean supportsAlterTableWithAddColumn() throws SQLException {
- return true;
- }
-
- public boolean supportsAlterTableWithDropColumn() throws SQLException {
- return true;
- }
-
- public boolean supportsColumnAliasing() throws SQLException {
- return true;
- }
-
- public boolean nullPlusNonNullIsNull() throws SQLException {
- // null + non-null != null
- return false;
- }
-
- public boolean supportsConvert() throws SQLException {
- // 是否支持转换函数convert
- return false;
- }
-
- public boolean supportsConvert(int fromType, int toType) throws SQLException {
- return false;
- }
-
- public boolean supportsTableCorrelationNames() throws SQLException {
- return false;
- }
-
- public boolean supportsDifferentTableCorrelationNames() throws SQLException {
- return false;
- }
-
- public boolean supportsExpressionsInOrderBy() throws SQLException {
- return false;
- }
-
- public boolean supportsOrderByUnrelated() throws SQLException {
- return false;
- }
-
- public boolean supportsGroupBy() throws SQLException {
- return true;
- }
-
- public boolean supportsGroupByUnrelated() throws SQLException {
- return false;
- }
-
- public boolean supportsGroupByBeyondSelect() throws SQLException {
- return false;
- }
-
- public boolean supportsLikeEscapeClause() throws SQLException {
- return false;
- }
-
- public boolean supportsMultipleResultSets() throws SQLException {
- return false;
- }
-
- public boolean supportsMultipleTransactions() throws SQLException {
- return false;
- }
-
- public boolean supportsNonNullableColumns() throws SQLException {
- return false;
- }
-
- public boolean supportsMinimumSQLGrammar() throws SQLException {
- return false;
- }
-
- public boolean supportsCoreSQLGrammar() throws SQLException {
- return false;
- }
-
- public boolean supportsExtendedSQLGrammar() throws SQLException {
- return false;
- }
-
- public boolean supportsANSI92EntryLevelSQL() throws SQLException {
- return false;
- }
-
- public boolean supportsANSI92IntermediateSQL() throws SQLException {
- return false;
- }
-
- public boolean supportsANSI92FullSQL() throws SQLException {
- return false;
- }
-
- public boolean supportsIntegrityEnhancementFacility() throws SQLException {
- return false;
- }
-
- public boolean supportsOuterJoins() throws SQLException {
- return false;
- }
-
- public boolean supportsFullOuterJoins() throws SQLException {
- return false;
- }
-
- public boolean supportsLimitedOuterJoins() throws SQLException {
- return false;
- }
-
- public String getSchemaTerm() throws SQLException {
- return null;
- }
-
- public String getProcedureTerm() throws SQLException {
- return null;
- }
-
- public String getCatalogTerm() throws SQLException {
- return "database";
- }
-
- public boolean isCatalogAtStart() throws SQLException {
- return true;
- }
-
- public String getCatalogSeparator() throws SQLException {
- return ".";
- }
-
- public boolean supportsSchemasInDataManipulation() throws SQLException {
- return false;
- }
-
- public boolean supportsSchemasInProcedureCalls() throws SQLException {
- return false;
- }
-
- public boolean supportsSchemasInTableDefinitions() throws SQLException {
- return false;
- }
-
- public boolean supportsSchemasInIndexDefinitions() throws SQLException {
- return false;
- }
-
- public boolean supportsSchemasInPrivilegeDefinitions() throws SQLException {
- return false;
- }
-
- public boolean supportsCatalogsInDataManipulation() throws SQLException {
- return true;
- }
-
- public boolean supportsCatalogsInProcedureCalls() throws SQLException {
- return false;
- }
-
- public boolean supportsCatalogsInTableDefinitions() throws SQLException {
- return false;
- }
-
- public boolean supportsCatalogsInIndexDefinitions() throws SQLException {
- return false;
- }
-
- public boolean supportsCatalogsInPrivilegeDefinitions() throws SQLException {
- return false;
- }
-
- public boolean supportsPositionedDelete() throws SQLException {
- return false;
- }
-
- public boolean supportsPositionedUpdate() throws SQLException {
- return false;
- }
-
- public boolean supportsSelectForUpdate() throws SQLException {
- return false;
- }
-
- public boolean supportsStoredProcedures() throws SQLException {
- return false;
- }
-
- public boolean supportsSubqueriesInComparisons() throws SQLException {
- return false;
- }
-
- public boolean supportsSubqueriesInExists() throws SQLException {
- return false;
- }
-
- public boolean supportsSubqueriesInIns() throws SQLException {
- return false;
- }
-
- public boolean supportsSubqueriesInQuantifieds() throws SQLException {
- return false;
- }
-
- public boolean supportsCorrelatedSubqueries() throws SQLException {
- return false;
- }
-
- public boolean supportsUnion() throws SQLException {
- return false;
- }
-
- public boolean supportsUnionAll() throws SQLException {
- return false;
- }
-
- public boolean supportsOpenCursorsAcrossCommit() throws SQLException {
- return false;
- }
-
- public boolean supportsOpenCursorsAcrossRollback() throws SQLException {
- return false;
- }
-
- public boolean supportsOpenStatementsAcrossCommit() throws SQLException {
- return false;
- }
-
- public boolean supportsOpenStatementsAcrossRollback() throws SQLException {
- return false;
- }
-
- public int getMaxBinaryLiteralLength() throws SQLException {
- return 0;
- }
-
- public int getMaxCharLiteralLength() throws SQLException {
- return 0;
- }
-
- public int getMaxColumnNameLength() throws SQLException {
- return 0;
- }
-
- public int getMaxColumnsInGroupBy() throws SQLException {
- return 0;
- }
-
- public int getMaxColumnsInIndex() throws SQLException {
- return 0;
- }
-
- public int getMaxColumnsInOrderBy() throws SQLException {
- return 0;
- }
-
- public int getMaxColumnsInSelect() throws SQLException {
- return 0;
- }
-
- public int getMaxColumnsInTable() throws SQLException {
- return 0;
- }
-
- public int getMaxConnections() throws SQLException {
- return 0;
- }
-
- public int getMaxCursorNameLength() throws SQLException {
- return 0;
- }
-
- public int getMaxIndexLength() throws SQLException {
- return 0;
- }
-
- public int getMaxSchemaNameLength() throws SQLException {
- return 0;
- }
-
- public int getMaxProcedureNameLength() throws SQLException {
- return 0;
- }
-
- public int getMaxCatalogNameLength() throws SQLException {
- return 0;
- }
-
- public int getMaxRowSize() throws SQLException {
- return 0;
- }
-
- public boolean doesMaxRowSizeIncludeBlobs() throws SQLException {
- return false;
- }
-
- public int getMaxStatementLength() throws SQLException {
- return 0;
- }
-
- public int getMaxStatements() throws SQLException {
- return 0;
- }
-
- public int getMaxTableNameLength() throws SQLException {
- return 0;
- }
-
- public int getMaxTablesInSelect() throws SQLException {
- return 0;
- }
-
- public int getMaxUserNameLength() throws SQLException {
- return 0;
- }
-
- public int getDefaultTransactionIsolation() throws SQLException {
- return Connection.TRANSACTION_NONE;
- }
-
- public boolean supportsTransactions() throws SQLException {
- return false;
- }
-
- public boolean supportsTransactionIsolationLevel(int level) throws SQLException {
- if (level == Connection.TRANSACTION_NONE)
- return true;
- return false;
- }
-
- public boolean supportsDataDefinitionAndDataManipulationTransactions() throws SQLException {
- return false;
- }
-
- public boolean supportsDataManipulationTransactionsOnly() throws SQLException {
- return false;
- }
-
- public boolean dataDefinitionCausesTransactionCommit() throws SQLException {
- return false;
- }
-
- public boolean dataDefinitionIgnoredInTransactions() throws SQLException {
- return false;
- }
-
- public ResultSet getProcedures(String catalog, String schemaPattern, String procedureNamePattern)
- throws SQLException {
- return null;
- }
-
- public ResultSet getProcedureColumns(String catalog, String schemaPattern, String procedureNamePattern,
- String columnNamePattern) throws SQLException {
- return null;
- }
-
+ /**
+ * @Param catalog : database名称,"" 表示不属于任何database的table,null表示不使用database来缩小范围
+ * @Param schemaPattern : schema名称,""表示
+ * @Param tableNamePattern : 表名满足tableNamePattern的表, null表示返回所有表
+ * @Param types : 表类型,null表示返回所有类型
+ */
public ResultSet getTables(String catalog, String schemaPattern, String tableNamePattern, String[] types) throws SQLException {
if (conn == null || conn.isClosed()) {
throw new SQLException(TSDBConstants.FixErrMsg(TSDBConstants.JNI_CONNECTION_NULL));
}
-
- try (Statement stmt = conn.createStatement()) {
- if (catalog == null || catalog.isEmpty())
- return null;
-
- stmt.executeUpdate("use " + catalog);
- ResultSet resultSet0 = stmt.executeQuery("show tables");
- GetTablesResultSet getTablesResultSet = new GetTablesResultSet(resultSet0, catalog, schemaPattern, tableNamePattern, types);
- return getTablesResultSet;
- }
+ return super.getTables(catalog, schemaPattern, tableNamePattern, types, conn);
}
- public ResultSet getSchemas() throws SQLException {
- return getEmptyResultSet();
- }
public ResultSet getCatalogs() throws SQLException {
if (conn == null || conn.isClosed())
throw new SQLException(TSDBConstants.FixErrMsg(TSDBConstants.JNI_CONNECTION_NULL));
-
- try (Statement stmt = conn.createStatement()) {
- ResultSet rs = stmt.executeQuery("show databases");
- return new CatalogResultSet(rs);
- }
+ return super.getCatalogs(conn);
}
public ResultSet getTableTypes() throws SQLException {
- DatabaseMetaDataResultSet resultSet = new DatabaseMetaDataResultSet();
-
- // set up ColumnMetaDataList
- List columnMetaDataList = new ArrayList<>(1);
- ColumnMetaData colMetaData = new ColumnMetaData();
- colMetaData.setColIndex(0);
- colMetaData.setColName("TABLE_TYPE");
- colMetaData.setColSize(10);
- colMetaData.setColType(TSDBConstants.TSDB_DATA_TYPE_BINARY);
- columnMetaDataList.add(colMetaData);
-
- // set up rowDataList
- List rowDataList = new ArrayList<>(2);
- TSDBResultSetRowData rowData = new TSDBResultSetRowData();
- rowData.setString(0, "TABLE");
- rowDataList.add(rowData);
- rowData = new TSDBResultSetRowData();
- rowData.setString(0, "STABLE");
- rowDataList.add(rowData);
-
- resultSet.setColumnMetaDataList(columnMetaDataList);
- resultSet.setRowDataList(rowDataList);
- return resultSet;
- }
-
- public ResultSet getColumns(String catalog, String schemaPattern, String tableNamePattern, String columnNamePattern)
- throws SQLException {
-
- /** add by zyyang **********/
- Statement stmt = null;
- if (null != conn && !conn.isClosed()) {
- stmt = conn.createStatement();
- if (catalog == null || catalog.isEmpty())
- return null;
-
- stmt.executeUpdate("use " + catalog);
- DatabaseMetaDataResultSet resultSet = new DatabaseMetaDataResultSet();
- // set up ColumnMetaDataList
- List columnMetaDataList = new ArrayList<>(24);
- columnMetaDataList.add(null);
- columnMetaDataList.add(null);
- // add TABLE_NAME
- ColumnMetaData colMetaData = new ColumnMetaData();
- colMetaData.setColIndex(3);
- colMetaData.setColName("TABLE_NAME");
- colMetaData.setColSize(193);
- colMetaData.setColType(TSDBConstants.TSDB_DATA_TYPE_BINARY);
- columnMetaDataList.add(colMetaData);
- // add COLUMN_NAME
- colMetaData = new ColumnMetaData();
- colMetaData.setColIndex(4);
- colMetaData.setColName("COLUMN_NAME");
- colMetaData.setColSize(65);
- colMetaData.setColType(TSDBConstants.TSDB_DATA_TYPE_BINARY);
- columnMetaDataList.add(colMetaData);
- // add DATA_TYPE
- colMetaData = new ColumnMetaData();
- colMetaData.setColIndex(5);
- colMetaData.setColName("DATA_TYPE");
- colMetaData.setColType(TSDBConstants.TSDB_DATA_TYPE_INT);
- columnMetaDataList.add(colMetaData);
- // add TYPE_NAME
- colMetaData = new ColumnMetaData();
- colMetaData.setColIndex(6);
- colMetaData.setColName("TYPE_NAME");
- colMetaData.setColType(TSDBConstants.TSDB_DATA_TYPE_BINARY);
- columnMetaDataList.add(colMetaData);
- // add COLUMN_SIZE
- colMetaData = new ColumnMetaData();
- colMetaData.setColIndex(7);
- colMetaData.setColName("COLUMN_SIZE");
- colMetaData.setColType(TSDBConstants.TSDB_DATA_TYPE_INT);
- columnMetaDataList.add(colMetaData);
- // add BUFFER_LENGTH ,not used
- columnMetaDataList.add(null);
- // add DECIMAL_DIGITS
- colMetaData = new ColumnMetaData();
- colMetaData.setColIndex(9);
- colMetaData.setColName("DECIMAL_DIGITS");
- colMetaData.setColType(TSDBConstants.TSDB_DATA_TYPE_INT);
- columnMetaDataList.add(colMetaData);
- // add NUM_PREC_RADIX
- colMetaData = new ColumnMetaData();
- colMetaData.setColIndex(10);
- colMetaData.setColName("NUM_PREC_RADIX");
- colMetaData.setColType(TSDBConstants.TSDB_DATA_TYPE_INT);
- columnMetaDataList.add(colMetaData);
- // add NULLABLE
- colMetaData = new ColumnMetaData();
- colMetaData.setColIndex(11);
- colMetaData.setColName("NULLABLE");
- colMetaData.setColType(TSDBConstants.TSDB_DATA_TYPE_INT);
- columnMetaDataList.add(colMetaData);
-
- resultSet.setColumnMetaDataList(columnMetaDataList);
-
- // set up rowDataList
- ResultSet resultSet0 = stmt.executeQuery("describe " + tableNamePattern);
- List rowDataList = new ArrayList<>();
- int index = 0;
- while (resultSet0.next()) {
- TSDBResultSetRowData rowData = new TSDBResultSetRowData(24);
- // set TABLE_NAME
- rowData.setString(2, tableNamePattern);
- // set COLUMN_NAME
- rowData.setString(3, resultSet0.getString(1));
- // set DATA_TYPE
- String typeName = resultSet0.getString(2);
- rowData.setInt(4, getDataType(typeName));
- // set TYPE_NAME
- rowData.setString(5, typeName);
- // set COLUMN_SIZE
- int length = resultSet0.getInt(3);
- rowData.setInt(6, getColumnSize(typeName, length));
- // set DECIMAL_DIGITS
- rowData.setInt(8, getDecimalDigits(typeName));
- // set NUM_PREC_RADIX
- rowData.setInt(9, 10);
- // set NULLABLE
- rowData.setInt(10, getNullable(index, typeName));
- rowDataList.add(rowData);
- index++;
- }
- resultSet.setRowDataList(rowDataList);
-
-// GetColumnsResultSet getColumnsResultSet = new GetColumnsResultSet(resultSet0, catalog, schemaPattern, tableNamePattern, columnNamePattern);
-// return getColumnsResultSet;
-// DatabaseMetaDataResultSet resultSet = new DatabaseMetaDataResultSet();
- return resultSet;
- } else {
+ if (conn == null || conn.isClosed())
throw new SQLException(TSDBConstants.FixErrMsg(TSDBConstants.JNI_CONNECTION_NULL));
- }
-
- /*************************/
-
-// return getEmptyResultSet();
+ return super.getTableTypes();
}
- private int getNullable(int index, String typeName) {
- if (index == 0 && "TIMESTAMP".equals(typeName))
- return DatabaseMetaData.columnNoNulls;
- return DatabaseMetaData.columnNullable;
- }
-
- private int getColumnSize(String typeName, int length) {
- switch (typeName) {
- case "TIMESTAMP":
- return 23;
-
- default:
- return 0;
- }
- }
-
- private int getDecimalDigits(String typeName) {
- switch (typeName) {
- case "FLOAT":
- return 5;
- case "DOUBLE":
- return 9;
- default:
- return 0;
- }
- }
-
- private int getDataType(String typeName) {
- switch (typeName) {
- case "TIMESTAMP":
- return Types.TIMESTAMP;
- case "INT":
- return Types.INTEGER;
- case "BIGINT":
- return Types.BIGINT;
- case "FLOAT":
- return Types.FLOAT;
- case "DOUBLE":
- return Types.DOUBLE;
- case "BINARY":
- return Types.BINARY;
- case "SMALLINT":
- return Types.SMALLINT;
- case "TINYINT":
- return Types.TINYINT;
- case "BOOL":
- return Types.BOOLEAN;
- case "NCHAR":
- return Types.NCHAR;
- default:
- return Types.NULL;
- }
- }
-
- public ResultSet getColumnPrivileges(String catalog, String schema, String table, String columnNamePattern)
- throws SQLException {
- return getEmptyResultSet();
- }
-
- public ResultSet getTablePrivileges(String catalog, String schemaPattern, String tableNamePattern)
- throws SQLException {
- return getEmptyResultSet();
- }
-
- public ResultSet getBestRowIdentifier(String catalog, String schema, String table, int scope, boolean nullable)
- throws SQLException {
- return getEmptyResultSet();
- }
-
- public ResultSet getVersionColumns(String catalog, String schema, String table) throws SQLException {
- return getEmptyResultSet();
+ public ResultSet getColumns(String catalog, String schemaPattern, String tableNamePattern, String columnNamePattern) throws SQLException {
+ if (conn == null || conn.isClosed())
+ throw new SQLException(TSDBConstants.FixErrMsg(TSDBConstants.JNI_CONNECTION_NULL));
+ return super.getColumns(catalog, schemaPattern, tableNamePattern, columnNamePattern, conn);
}
public ResultSet getPrimaryKeys(String catalog, String schema, String table) throws SQLException {
- return getEmptyResultSet();
- }
-
- public ResultSet getImportedKeys(String catalog, String schema, String table) throws SQLException {
- return getEmptyResultSet();
- }
-
- public ResultSet getExportedKeys(String catalog, String schema, String table) throws SQLException {
- return getEmptyResultSet();
- }
-
- public ResultSet getCrossReference(String parentCatalog, String parentSchema, String parentTable,
- String foreignCatalog, String foreignSchema, String foreignTable) throws SQLException {
- return getEmptyResultSet();
- }
-
- public ResultSet getTypeInfo() throws SQLException {
- return getEmptyResultSet();
- }
-
- public ResultSet getIndexInfo(String catalog, String schema, String table, boolean unique, boolean approximate)
- throws SQLException {
- return getEmptyResultSet();
- }
-
- public boolean supportsResultSetType(int type) throws SQLException {
- return false;
- }
-
- public boolean supportsResultSetConcurrency(int type, int concurrency) throws SQLException {
- return false;
- }
-
- public boolean ownUpdatesAreVisible(int type) throws SQLException {
- return false;
- }
-
- public boolean ownDeletesAreVisible(int type) throws SQLException {
- return false;
- }
-
- public boolean ownInsertsAreVisible(int type) throws SQLException {
- return false;
- }
-
- public boolean othersUpdatesAreVisible(int type) throws SQLException {
- return false;
- }
-
- public boolean othersDeletesAreVisible(int type) throws SQLException {
- return false;
- }
-
- public boolean othersInsertsAreVisible(int type) throws SQLException {
- return false;
- }
-
- public boolean updatesAreDetected(int type) throws SQLException {
- return false;
- }
-
- public boolean deletesAreDetected(int type) throws SQLException {
- return false;
- }
-
- public boolean insertsAreDetected(int type) throws SQLException {
- return false;
- }
-
- public boolean supportsBatchUpdates() throws SQLException {
- return false;
- }
-
- public ResultSet getUDTs(String catalog, String schemaPattern, String typeNamePattern, int[] types)
- throws SQLException {
- return getEmptyResultSet();
- }
-
- public Connection getConnection() throws SQLException {
- return this.conn;
- }
-
- public boolean supportsSavepoints() throws SQLException {
- return false;
- }
-
- public boolean supportsNamedParameters() throws SQLException {
- return false;
- }
-
- public boolean supportsMultipleOpenResults() throws SQLException {
- return false;
- }
-
- public boolean supportsGetGeneratedKeys() throws SQLException {
- return false;
- }
-
- public ResultSet getSuperTypes(String catalog, String schemaPattern, String typeNamePattern) throws SQLException {
- return getEmptyResultSet();
+ if (conn == null || conn.isClosed())
+ throw new SQLException(TSDBConstants.FixErrMsg(TSDBConstants.JNI_CONNECTION_NULL));
+ return super.getPrimaryKeys(catalog, schema, table, conn);
}
public ResultSet getSuperTables(String catalog, String schemaPattern, String tableNamePattern) throws SQLException {
- return getEmptyResultSet();
+ if (conn == null || conn.isClosed())
+ throw new SQLException(TSDBConstants.FixErrMsg(TSDBConstants.JNI_CONNECTION_NULL));
+ return super.getSuperTables(catalog, schemaPattern, tableNamePattern, conn);
}
- public ResultSet getAttributes(String catalog, String schemaPattern, String typeNamePattern,
- String attributeNamePattern) throws SQLException {
- return getEmptyResultSet();
- }
-
- public boolean supportsResultSetHoldability(int holdability) throws SQLException {
- if (holdability == ResultSet.HOLD_CURSORS_OVER_COMMIT)
- return true;
- return false;
- }
-
- public int getResultSetHoldability() throws SQLException {
- return ResultSet.HOLD_CURSORS_OVER_COMMIT;
- }
-
- public int getDatabaseMajorVersion() throws SQLException {
- return 2;
- }
-
- public int getDatabaseMinorVersion() throws SQLException {
- return 0;
- }
-
- public int getJDBCMajorVersion() throws SQLException {
- return 2;
- }
-
- public int getJDBCMinorVersion() throws SQLException {
- return 0;
- }
-
- public int getSQLStateType() throws SQLException {
- return 0;
- }
-
- public boolean locatorsUpdateCopy() throws SQLException {
- return false;
- }
-
- public boolean supportsStatementPooling() throws SQLException {
- return false;
- }
-
- public RowIdLifetime getRowIdLifetime() throws SQLException {
- return null;
- }
-
- public ResultSet getSchemas(String catalog, String schemaPattern) throws SQLException {
- return null;
- }
-
- public boolean supportsStoredFunctionsUsingCallSyntax() throws SQLException {
- return false;
- }
-
- public boolean autoCommitFailureClosesAllResultSets() throws SQLException {
- return false;
- }
-
- public ResultSet getClientInfoProperties() throws SQLException {
- return getEmptyResultSet();
- }
-
- public ResultSet getFunctions(String catalog, String schemaPattern, String functionNamePattern)
- throws SQLException {
- return getEmptyResultSet();
- }
-
- public ResultSet getFunctionColumns(String catalog, String schemaPattern, String functionNamePattern,
- String columnNamePattern) throws SQLException {
- return getEmptyResultSet();
- }
-
- public ResultSet getPseudoColumns(String catalog, String schemaPattern, String tableNamePattern,
- String columnNamePattern) throws SQLException {
- return getEmptyResultSet();
- }
-
- public boolean generatedKeyAlwaysReturned() throws SQLException {
- return false;
- }
-
- private ResultSet getEmptyResultSet() {
- return new EmptyResultSet();
- }
}
\ No newline at end of file
diff --git a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBParameterMetaData.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBParameterMetaData.java
deleted file mode 100644
index d9227523d4..0000000000
--- a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/TSDBParameterMetaData.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/***************************************************************************
- * Copyright (c) 2019 TAOS Data, Inc.
- *
- * This program is free software: you can use, redistribute, and/or modify
- * it under the terms of the GNU Affero General Public License, version 3
- * or later ("AGPL"), as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program. If not, see .
- *****************************************************************************/
-package com.taosdata.jdbc;
-
-import java.sql.ParameterMetaData;
-import java.sql.SQLException;
-
-public class TSDBParameterMetaData implements ParameterMetaData {
- @Override
- public int getParameterCount() throws SQLException {
- return 0;
- }
-
- @Override
- public int isNullable(int param) throws SQLException {
- return 0;
- }
-
- @Override
- public boolean isSigned(int param) throws SQLException {
- return false;
- }
-
- @Override
- public int getPrecision(int param) throws SQLException {
- return 0;
- }
-
- @Override
- public int getScale(int param) throws SQLException {
- return 0;
- }
-
- @Override
- public int getParameterType(int param) throws SQLException {
- return 0;
- }
-
- @Override
- public String getParameterTypeName(int param) throws SQLException {
- return null;
- }
-
- @Override
- public String getParameterClassName(int param) throws SQLException {
- return null;
- }
-
- @Override
- public int getParameterMode(int param) throws SQLException {
- return 0;
- }
-
- @Override
- public T unwrap(Class iface) throws SQLException {
- return null;
- }
-
- @Override
- public boolean isWrapperFor(Class> iface) throws SQLException {
- return false;
- }
-}
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 c57f19550d..6518bf10e4 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
@@ -26,9 +26,9 @@ public class TSDBResultSetRowData {
public TSDBResultSetRowData(int colSize) {
this.setColSize(colSize);
}
-
+
public TSDBResultSetRowData() {
- this.data = new ArrayList