diff --git a/documentation20/cn/11.administrator/docs.md b/documentation20/cn/11.administrator/docs.md
index 7c9cde2d7c39ae75d50ca8915ec3d559392a7900..52a0da6551a332b9b578d3830d1bb8135eb30692 100644
--- a/documentation20/cn/11.administrator/docs.md
+++ b/documentation20/cn/11.administrator/docs.md
@@ -2,52 +2,52 @@
## 容量规划
-使用TDengine来搭建一个物联网大数据平台,计算资源、存储资源需要根据业务场景进行规划。下面分别讨论系统运行所需要的内存、CPU以及硬盘空间。
+使用 TDengine 来搭建一个物联网大数据平台,计算资源、存储资源需要根据业务场景进行规划。下面分别讨论系统运行所需要的内存、CPU 以及硬盘空间。
### 内存需求
-每个DB可以创建固定数目的vgroup,默认与CPU核数相同,可通过maxVgroupsPerDb配置;vgroup中的每个副本会是一个vnode;每个vnode会占用固定大小的内存(大小与数据库的配置参数blocks和cache有关);每个Table会占用与标签总长度有关的内存;此外,系统会有一些固定的内存开销。因此,每个DB需要的系统内存可通过如下公式计算:
+每个 DB 可以创建固定数目的 vgroup,默认与 CPU 核数相同,可通过 maxVgroupsPerDb 配置;vgroup 中的每个副本会是一个 vnode;每个 vnode 会占用固定大小的内存(大小与数据库的配置参数 blocks 和 cache 有关);每个 Table 会占用与标签总长度有关的内存;此外,系统会有一些固定的内存开销。因此,每个 DB 需要的系统内存可通过如下公式计算:
```
-Memory Size = maxVgroupsPerDb * (blocks * cache + 10Mb) + numOfTables * (tagSizePerTable + 0.5Kb)
+Memory Size = maxVgroupsPerDb * (blocks * cache + 10MB) + numOfTables * (tagSizePerTable + 0.5KB)
```
-示例:假设是4核机器,cache是缺省大小16M, blocks是缺省值6,假设有10万张表,标签总长度是256字节,则总的内存需求为:4\*(16\*6+10) + 100000\*(0.25+0.5)/1000 = 499M。
+示例:假设是 4 核机器,cache 是缺省大小 16M, blocks 是缺省值 6,假设有 10 万张表,标签总长度是 256 字节,则总的内存需求为:4 \* (16 \* 6 + 10) + 100000 \* (0.25 + 0.5) / 1000 = 499M。
-实际运行的系统往往会根据数据特点的不同,将数据存放在不同的DB里。因此做规划时,也需要考虑。
+实际运行的系统往往会根据数据特点的不同,将数据存放在不同的 DB 里。因此做规划时,也需要考虑。
-如果内存充裕,可以加大Blocks的配置,这样更多数据将保存在内存里,提高查询速度。
+如果内存充裕,可以加大 Blocks 的配置,这样更多数据将保存在内存里,提高查询速度。
-### CPU需求
+### CPU 需求
-CPU的需求取决于如下两方面:
+CPU 的需求取决于如下两方面:
-* __数据插入__ TDengine单核每秒能至少处理一万个插入请求。每个插入请求可以带多条记录,一次插入一条记录与插入10条记录,消耗的计算资源差别很小。因此每次插入,条数越大,插入效率越高。如果一个插入请求带200条以上记录,单核就能达到每秒插入100万条记录的速度。但对前端数据采集的要求越高,因为需要缓存记录,然后一批插入。
-* __查询需求__ TDengine提供高效的查询,但是每个场景的查询差异很大,查询频次变化也很大,难以给出客观数字。需要用户针对自己的场景,写一些查询语句,才能确定。
+* __数据插入__ TDengine 单核每秒能至少处理一万个插入请求。每个插入请求可以带多条记录,一次插入一条记录与插入 10 条记录,消耗的计算资源差别很小。因此每次插入,条数越大,插入效率越高。如果一个插入请求带 200 条以上记录,单核就能达到每秒插入 100 万条记录的速度。但对前端数据采集的要求越高,因为需要缓存记录,然后一批插入。
+* __查询需求__ TDengine 提供高效的查询,但是每个场景的查询差异很大,查询频次变化也很大,难以给出客观数字。需要用户针对自己的场景,写一些查询语句,才能确定。
-因此仅对数据插入而言,CPU是可以估算出来的,但查询所耗的计算资源无法估算。在实际运营过程中,不建议CPU使用率超过50%,超过后,需要增加新的节点,以获得更多计算资源。
+因此仅对数据插入而言,CPU 是可以估算出来的,但查询所耗的计算资源无法估算。在实际运营过程中,不建议 CPU 使用率超过 50%,超过后,需要增加新的节点,以获得更多计算资源。
### 存储需求
-TDengine相对于通用数据库,有超高的压缩比,在绝大多数场景下,TDengine的压缩比不会低于5倍,有的场合,压缩比可达到10倍以上,取决于实际场景的数据特征。压缩前的原始数据大小可通过如下方式计算:
+TDengine 相对于通用数据库,有超高的压缩比,在绝大多数场景下,TDengine 的压缩比不会低于 5 倍,有的场合,压缩比可达到 10 倍以上,取决于实际场景的数据特征。压缩前的原始数据大小可通过如下方式计算:
```
Raw DataSize = numOfTables * rowSizePerTable * rowsPerTable
```
-示例:1000万台智能电表,每台电表每15分钟采集一次数据,每次采集的数据128字节,那么一年的原始数据量是:10000000\*128\*24\*60/15\*365 = 44.8512T。TDengine大概需要消耗44.851/5=8.97024T空间。
+示例:1000 万台智能电表,每台电表每 15 分钟采集一次数据,每次采集的数据 128 字节,那么一年的原始数据量是:10000000 \* 128 \* 24 \* 60 / 15 \* 365 = 44.8512T。TDengine大概需要消耗 44.851 / 5 = 8.97024T 空间。
-用户可以通过参数keep,设置数据在磁盘中的最大保存时长。为进一步减少存储成本,TDengine还提供多级存储,最冷的数据可以存放在最廉价的存储介质上,应用的访问不用做任何调整,只是读取速度降低了。
+用户可以通过参数 keep,设置数据在磁盘中的最大保存时长。为进一步减少存储成本,TDengine 还提供多级存储,最冷的数据可以存放在最廉价的存储介质上,应用的访问不用做任何调整,只是读取速度降低了。
-为提高速度,可以配置多块硬盘,这样可以并发写入或读取数据。需要提醒的是,TDengine采取多副本的方式提供数据的高可靠,因此不再需要采用昂贵的磁盘阵列。
+为提高速度,可以配置多块硬盘,这样可以并发写入或读取数据。需要提醒的是,TDengine 采取多副本的方式提供数据的高可靠,因此不再需要采用昂贵的磁盘阵列。
### 物理机或虚拟机台数
-根据上面的内存、CPU、存储的预估,就可以知道整个系统需要多少核、多少内存、多少存储空间。如果数据副本数不为1,总需求量需要再乘以副本数。
+根据上面的内存、CPU、存储的预估,就可以知道整个系统需要多少核、多少内存、多少存储空间。如果数据副本数不为 1,总需求量需要再乘以副本数。
-因为TDengine具有很好的水平扩展能力,根据总量,再根据单个物理机或虚拟机的资源,就可以轻松决定需要购置多少台物理机或虚拟机了。
+因为 TDengine 具有很好的水平扩展能力,根据总量,再根据单个物理机或虚拟机的资源,就可以轻松决定需要购置多少台物理机或虚拟机了。
-**立即计算CPU、内存、存储,请参见:[资源估算方法](https://www.taosdata.com/config/config.html)**
+**立即计算 CPU、内存、存储,请参见:[资源估算方法](https://www.taosdata.com/config/config.html)**
## 容错和灾备
diff --git a/documentation20/cn/12.taos-sql/docs.md b/documentation20/cn/12.taos-sql/docs.md
index 1002ffa01c860b2cabd27ddeb4e0b0e9ca967c58..c89dbda7a02c243e62d6bd81b6c0d78b14f67d2c 100644
--- a/documentation20/cn/12.taos-sql/docs.md
+++ b/documentation20/cn/12.taos-sql/docs.md
@@ -115,7 +115,7 @@ TDengine缺省的时间戳是毫秒精度,但通过修改配置参数enableMic
```mysql
ALTER DATABASE db_name QUORUM 2;
```
- QUORUM 参数是指数据写入成功所需要的确认数,取值范围 [1, 3]。对于异步复制,quorum 设为 1,具有 master 角色的虚拟节点自己确认即可。对于同步复制,需要至少大于等于 2。原则上,Quorum >= 1 并且 Quorum <= replica(副本数),这个参数在启动一个同步模块实例时需要提供。
+ QUORUM 参数是指数据写入成功所需要的确认数,取值范围 [1, 2]。对于异步复制,quorum 设为 1,具有 master 角色的虚拟节点自己确认即可。对于同步复制,需要至少大于等于 2。原则上,Quorum >= 1 并且 Quorum <= replica(副本数),这个参数在启动一个同步模块实例时需要提供。
```mysql
ALTER DATABASE db_name BLOCKS 100;
diff --git a/src/connector/jdbc/pom.xml b/src/connector/jdbc/pom.xml
index 7a421eff2296cc8b61ec6e07174747ef8e224ff0..f1e013e864f4617e04be0c8c5b892c4396c66e79 100755
--- a/src/connector/jdbc/pom.xml
+++ b/src/connector/jdbc/pom.xml
@@ -102,6 +102,7 @@
**/*Test.java
+ **/DatetimeBefore1970Test.java
**/AppMemoryLeakTest.java
**/AuthenticationTest.java
**/TaosInfoMonitorTest.java
diff --git a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/TSDBJNIConnectorTest.java b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/TSDBJNIConnectorTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..5e4f16a73c3c93456ed67450752af094cd96938c
--- /dev/null
+++ b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/TSDBJNIConnectorTest.java
@@ -0,0 +1,130 @@
+package com.taosdata.jdbc;
+
+import org.junit.Test;
+
+import java.sql.SQLException;
+import java.sql.SQLWarning;
+import java.util.ArrayList;
+import java.util.List;
+
+import static org.junit.Assert.*;
+
+public class TSDBJNIConnectorTest {
+
+ public static void main(String[] args) {
+ try {
+ TSDBJNIConnector.init("/etc/taos/taos.cfg", "en_US.UTF-8", "", "");
+ TSDBJNIConnector connector = new TSDBJNIConnector();
+ connector.connect("127.0.0.1", 6030, "test", "root", "taosdata");
+ long pSql = connector.executeQuery("show dnodes");
+ // if pSql is create/insert/update/delete/alter SQL
+ if (connector.isUpdateQuery(pSql)) {
+ connector.freeResultSet(pSql);
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_INVALID_WITH_EXECUTEQUERY);
+ }
+
+ List columnMetaDataList = new ArrayList<>();
+
+ int code = connector.getSchemaMetaData(pSql, columnMetaDataList);
+ if (code == TSDBConstants.JNI_CONNECTION_NULL) {
+ throw new SQLException(TSDBConstants.FixErrMsg(TSDBConstants.JNI_CONNECTION_NULL));
+ }
+ if (code == TSDBConstants.JNI_RESULT_SET_NULL) {
+ throw new SQLException(TSDBConstants.FixErrMsg(TSDBConstants.JNI_RESULT_SET_NULL));
+ }
+ if (code == TSDBConstants.JNI_NUM_OF_FIELDS_0) {
+ throw new SQLException(TSDBConstants.FixErrMsg(TSDBConstants.JNI_NUM_OF_FIELDS_0));
+ }
+
+ } catch (SQLWarning throwables) {
+ throwables.printStackTrace();
+ } catch (SQLException e) {
+ e.printStackTrace();
+ }
+ }
+
+
+ @Test
+ public void isClosed() {
+ }
+
+ @Test
+ public void isResultsetClosed() {
+ }
+
+ @Test
+ public void init() {
+ }
+
+ @Test
+ public void initImp() {
+ }
+
+ @Test
+ public void setOptions() {
+ }
+
+ @Test
+ public void getTsCharset() {
+ }
+
+ @Test
+ public void connect() {
+ }
+
+ @Test
+ public void executeQuery() {
+ }
+
+ @Test
+ public void getErrCode() {
+ }
+
+ @Test
+ public void getErrMsg() {
+ }
+
+ @Test
+ public void isUpdateQuery() {
+ }
+
+ @Test
+ public void freeResultSet() {
+ }
+
+ @Test
+ public void getAffectedRows() {
+ }
+
+ @Test
+ public void getSchemaMetaData() {
+ }
+
+ @Test
+ public void fetchRow() {
+ }
+
+ @Test
+ public void fetchBlock() {
+ }
+
+ @Test
+ public void closeConnection() {
+ }
+
+ @Test
+ public void subscribe() {
+ }
+
+ @Test
+ public void consume() {
+ }
+
+ @Test
+ public void unsubscribe() {
+ }
+
+ @Test
+ public void validateCreateTableSql() {
+ }
+}
\ No newline at end of file
diff --git a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/FailOverTest.java b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/FailOverTest.java
index 83295df5274a669ca2fc7fdbba506a97a01cc55c..be2ff94e02e10c14f1229b63762f5a6af7082318 100644
--- a/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/FailOverTest.java
+++ b/src/connector/jdbc/src/test/java/com/taosdata/jdbc/cases/FailOverTest.java
@@ -4,7 +4,6 @@ import org.junit.Test;
import java.sql.*;
import java.text.SimpleDateFormat;
-import java.util.Date;
import java.util.concurrent.TimeUnit;
public class FailOverTest {
@@ -18,13 +17,17 @@ public class FailOverTest {
long end = System.currentTimeMillis() + 1000 * 60 * 5;
while (System.currentTimeMillis() < end) {
- try (Connection conn = DriverManager.getConnection(url)) {
- Statement stmt = conn.createStatement();
- ResultSet resultSet = stmt.executeQuery("select server_status()");
- resultSet.next();
- int status = resultSet.getInt("server_status()");
- System.out.println(">>>>>>>>>" + sdf.format(new Date()) + " status : " + status);
- stmt.close();
+ try (Connection conn = DriverManager.getConnection(url); Statement stmt = conn.createStatement()) {
+ ResultSet rs = stmt.executeQuery("show dnodes");
+ ResultSetMetaData meta = rs.getMetaData();
+ while (rs.next()) {
+ for (int i = 1; i <= meta.getColumnCount(); i++) {
+ System.out.print(meta.getColumnLabel(i) + ": " + rs.getString(i) + "\t");
+ }
+ System.out.println();
+ }
+ System.out.println("=======================");
+ rs.close();
TimeUnit.SECONDS.sleep(5);
} catch (SQLException | InterruptedException e) {
e.printStackTrace();