diff --git a/documentation20/cn/04.model/docs.md b/documentation20/cn/04.model/docs.md
index 7ecfa6128f1e70d2c8bf33417e8f10b22f9737bd..1a25e4407d0ed77c71040f676656fdc1451e2f81 100644
--- a/documentation20/cn/04.model/docs.md
+++ b/documentation20/cn/04.model/docs.md
@@ -43,7 +43,7 @@ CREATE STABLE meters (ts timestamp, current float, voltage int, phase float) TAG
## 创建表
TDengine对每个数据采集点需要独立建表。与标准的关系型数据一样,一张表有表名,Schema,但除此之外,还可以带有一到多个标签。创建时,需要使用超级表做模板,同时指定标签的具体值。以表一中的智能电表为例,可以使用如下的SQL命令建表:
-```cmd
+```mysql
CREATE TABLE d1001 USING meters TAGS ("Beijing.Chaoyang", 2);
```
其中d1001是表名,meters是超级表的表名,后面紧跟标签Location的具体标签值”Beijing.Chaoyang",标签groupId的具体标签值2。虽然在创建表时,需要指定标签值,但可以事后修改。详细细则请见 [TAOS SQL 的表管理](https://www.taosdata.com/cn/documentation/taos-sql#table) 章节。
@@ -54,10 +54,12 @@ TDengine建议将数据采集点的全局唯一ID作为表名(比如设备序列
**自动建表**:在某些特殊场景中,用户在写数据时并不确定某个数据采集点的表是否存在,此时可在写入数据时使用自动建表语法来创建不存在的表,若该表已存在则不会建立新表。比如:
-```cmd
+```mysql
INSERT INTO d1001 USING METERS TAGS ("Beijng.Chaoyang", 2) VALUES (now, 10.2, 219, 0.32);
```
-上述SQL语句将记录(now, 10.2, 219, 0.32) 插入进表d1001。如果表d1001还未创建,则使用超级表meters做模板自动创建,同时打上标签值“Beijing.Chaoyang", 2。
+上述SQL语句将记录 (now, 10.2, 219, 0.32) 插入表d1001。如果表d1001还未创建,则使用超级表meters做模板自动创建,同时打上标签值“Beijing.Chaoyang", 2。
+
+关于自动建表的详细语法请参见 [插入记录时自动建表](https://www.taosdata.com/cn/documentation/taos-sql#auto_create_table) 章节。
## 多列模型 vs 单列模型
diff --git a/documentation20/cn/12.taos-sql/docs.md b/documentation20/cn/12.taos-sql/docs.md
index 18f57c6a80b9f159153819bd4ac288dca5b92c31..3aee7da7dbdf3120afc2b15da3376cab94c7657d 100644
--- a/documentation20/cn/12.taos-sql/docs.md
+++ b/documentation20/cn/12.taos-sql/docs.md
@@ -152,6 +152,14 @@ TDengine缺省的时间戳是毫秒精度,但通过修改配置参数enableMic
```
以指定的超级表为模板,指定 tags 的值来创建数据表。
+- **以超级表为模板创建数据表,并指定具体的 tags 列**
+
+ ```mysql
+ CREATE TABLE [IF NOT EXISTS] tb_name USING stb_name (tag_name1, ...) TAGS (tag_value1, ...);
+ ```
+ 以指定的超级表为模板,指定一部分 tags 列的值来创建数据表。(没被指定的 tags 列会设为空值。)
+ 说明:从 2.0.17 版本开始支持这种方式。在之前的版本中,不允许指定 tags 列,而必须显式给出所有 tags 列的取值。
+
- **批量创建数据表**
```mysql
@@ -306,7 +314,7 @@ TDengine缺省的时间戳是毫秒精度,但通过修改配置参数enableMic
- **插入一条记录,数据对应到指定的列**
```mysql
- INSERT INTO tb_name (field1_name, ...) VALUES (field1_value, ...)
+ INSERT INTO tb_name (field1_name, ...) VALUES (field1_value1, ...);
```
向表tb_name中插入一条记录,数据对应到指定的列。SQL语句中没有出现的列,数据库将自动填充为NULL。主键(时间戳)不能为NULL。
@@ -340,6 +348,18 @@ TDengine缺省的时间戳是毫秒精度,但通过修改配置参数enableMic
1) 如果时间戳为0,系统将自动使用服务器当前时间作为该记录的时间戳;
2) 允许插入的最老记录的时间戳,是相对于当前服务器时间,减去配置的keep值(数据保留的天数),允许插入的最新记录的时间戳,是相对于当前服务器时间,加上配置的days值(数据文件存储数据的时间跨度,单位为天)。keep和days都是可以在创建数据库时指定的,缺省值分别是3650天和10天。
+- **插入记录时自动建表**
+ ```mysql
+ INSERT INTO tb_name USING stb_name TAGS (tag_value1, ...) VALUES (field_value1, ...);
+ ```
+ 如果用户在写数据时并不确定某个表是否存在,此时可以在写入数据时使用自动建表语法来创建不存在的表,若该表已存在则不会建立新表。自动建表时,要求必须以超级表为模板,并写明数据表的 tags 取值。
+
+- **插入记录时自动建表,并指定具体的 tags 列**
+ ```mysql
+ INSERT INTO tb_name USING stb_name (tag_name1, ...) TAGS (tag_value1, ...) VALUES (field_value1, ...);
+ ```
+ 在自动建表时,可以只是指定部分 tags 列的取值,未被指定的 tags 列将取为空值。
+
**历史记录写入**:可使用IMPORT或者INSERT命令,IMPORT的语法,功能与INSERT完全一样。
说明:针对 insert 类型的 SQL 语句,我们采用的流式解析策略,在发现后面的错误之前,前面正确的部分SQL仍会执行。下面的sql中,insert语句是无效的,但是d1001仍会被创建。
@@ -383,7 +403,7 @@ SELECT select_expr [, select_expr ...]
[ORDER BY col_list { DESC | ASC }]
[SLIMIT limit_val [, SOFFSET offset_val]]
[LIMIT limit_val [, OFFSET offset_val]]
- [>> export_file]
+ [>> export_file];
```
#### SELECT子句
diff --git a/src/connector/jdbc/pom.xml b/src/connector/jdbc/pom.xml
index fb97c1455da8aa8129e7535be89b35df548e1780..8ebf8aa5cceb1060f735ec498c913c7606747fd5 100755
--- a/src/connector/jdbc/pom.xml
+++ b/src/connector/jdbc/pom.xml
@@ -128,6 +128,7 @@
**/AppMemoryLeakTest.java
+ **/AuthenticationTest.java
**/TaosInfoMonitorTest.java
**/FailOverTest.java
**/InvalidResultSetPointerTest.java
diff --git a/src/connector/jdbc/src/main/java/com/taosdata/jdbc/AbstractConnection.java b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/AbstractConnection.java
new file mode 100644
index 0000000000000000000000000000000000000000..bb621bd1308e18d7d404fcc7b53e9fa07d487d73
--- /dev/null
+++ b/src/connector/jdbc/src/main/java/com/taosdata/jdbc/AbstractConnection.java
@@ -0,0 +1,529 @@
+package com.taosdata.jdbc;
+
+import java.sql.*;
+import java.util.Enumeration;
+import java.util.Map;
+import java.util.Properties;
+import java.util.concurrent.*;
+
+public abstract class AbstractConnection extends WrapperImpl implements Connection {
+
+ protected volatile boolean isClosed;
+ protected volatile String catalog;
+ protected volatile Properties clientInfoProps = new Properties();
+
+ @Override
+ public abstract Statement createStatement() throws SQLException;
+
+ @Override
+ public abstract PreparedStatement prepareStatement(String sql) throws SQLException;
+
+ @Override
+ public CallableStatement prepareCall(String sql) throws SQLException {
+ if (isClosed())
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
+ }
+
+ @Override
+ public String nativeSQL(String sql) throws SQLException {
+ if (isClosed())
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
+ // do nothing
+ return sql;
+ }
+
+ @Override
+ public void setAutoCommit(boolean autoCommit) throws SQLException {
+ if (isClosed())
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
+
+ //do nothing
+ }
+
+ @Override
+ public boolean getAutoCommit() throws SQLException {
+ if (isClosed())
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
+
+ return true;
+ }
+
+ @Override
+ public void commit() throws SQLException {
+ if (isClosed())
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
+
+ // do nothing
+ }
+
+ @Override
+ public void rollback() throws SQLException {
+ if (isClosed())
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
+
+ // do nothing
+ }
+
+ @Override
+ public abstract void close() throws SQLException;
+
+ @Override
+ public abstract boolean isClosed() throws SQLException;
+
+ @Override
+ public abstract DatabaseMetaData getMetaData() throws SQLException;
+
+ @Override
+ public void setReadOnly(boolean readOnly) throws SQLException {
+ if (isClosed())
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
+
+ //do nothing
+ }
+
+ @Override
+ public boolean isReadOnly() throws SQLException {
+ if (isClosed())
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
+ return true;
+ }
+
+ @Override
+ public void setCatalog(String catalog) throws SQLException {
+ if (isClosed())
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
+ /*
+ try (Statement stmt = createStatement()) {
+ boolean execute = stmt.execute("use " + catalog);
+ if (execute)
+ this.catalog = catalog;
+ } catch (SQLException e) {
+ // do nothing
+ }
+ */
+
+ this.catalog = catalog;
+ }
+
+ @Override
+ public String getCatalog() throws SQLException {
+ if (isClosed())
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
+
+ return this.catalog;
+ }
+
+ @Override
+ public void setTransactionIsolation(int level) throws SQLException {
+ if (isClosed())
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
+
+ switch (level) {
+ case Connection.TRANSACTION_NONE:
+ break;
+ case Connection.TRANSACTION_READ_UNCOMMITTED:
+ case Connection.TRANSACTION_READ_COMMITTED:
+ case Connection.TRANSACTION_REPEATABLE_READ:
+ case Connection.TRANSACTION_SERIALIZABLE:
+ throw new SQLFeatureNotSupportedException(TSDBConstants.UNSUPPORTED_METHOD_EXCEPTION_MSG);
+ default:
+ throw new SQLException(TSDBConstants.INVALID_VARIABLES);
+ }
+ //do nothing
+ }
+
+ @Override
+ public int getTransactionIsolation() throws SQLException {
+ if (isClosed())
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
+
+ return Connection.TRANSACTION_NONE;
+ }
+
+ @Override
+ public SQLWarning getWarnings() throws SQLException {
+ if (isClosed())
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
+
+ return null;
+ }
+
+ @Override
+ public void clearWarnings() throws SQLException {
+ if (isClosed())
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
+
+ // do nothing
+ }
+
+ @Override
+ public Statement createStatement(int resultSetType, int resultSetConcurrency) throws SQLException {
+ if (isClosed())
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
+
+ switch (resultSetType) {
+ case ResultSet.TYPE_FORWARD_ONLY:
+ break;
+ case ResultSet.TYPE_SCROLL_INSENSITIVE:
+ case ResultSet.TYPE_SCROLL_SENSITIVE:
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
+ default:
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_INVALID_VARIABLE);
+ }
+
+ switch (resultSetConcurrency) {
+ case ResultSet.CONCUR_READ_ONLY:
+ break;
+ case ResultSet.CONCUR_UPDATABLE:
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
+ default:
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_INVALID_VARIABLE);
+ }
+
+ return createStatement();
+ }
+
+ @Override
+ public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency) throws SQLException {
+ if (isClosed())
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
+
+ switch (resultSetType) {
+ case ResultSet.TYPE_FORWARD_ONLY:
+ break;
+ case ResultSet.TYPE_SCROLL_INSENSITIVE:
+ case ResultSet.TYPE_SCROLL_SENSITIVE:
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
+ default:
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_INVALID_VARIABLE);
+ }
+
+ switch (resultSetConcurrency) {
+ case ResultSet.CONCUR_READ_ONLY:
+ break;
+ case ResultSet.CONCUR_UPDATABLE:
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
+ default:
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_INVALID_VARIABLE);
+ }
+ return prepareStatement(sql);
+ }
+
+ @Override
+ public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency) throws SQLException {
+ if (isClosed())
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
+
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
+ }
+
+ @Override
+ public Map> getTypeMap() throws SQLException {
+ if (isClosed())
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
+
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
+ }
+
+ @Override
+ public void setTypeMap(Map> map) throws SQLException {
+ if (isClosed())
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
+
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
+ }
+
+ @Override
+ public void setHoldability(int holdability) throws SQLException {
+ if (isClosed())
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
+
+ switch (holdability) {
+ case ResultSet.HOLD_CURSORS_OVER_COMMIT:
+ break;
+ case ResultSet.CLOSE_CURSORS_AT_COMMIT:
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
+ default:
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_INVALID_VARIABLE);
+ }
+ //do nothing
+ }
+
+ @Override
+ public int getHoldability() throws SQLException {
+ if (isClosed())
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
+
+ return ResultSet.HOLD_CURSORS_OVER_COMMIT;
+ }
+
+ @Override
+ public Savepoint setSavepoint() throws SQLException {
+ if (isClosed())
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
+
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
+ }
+
+ @Override
+ public Savepoint setSavepoint(String name) throws SQLException {
+ if (isClosed())
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
+
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
+ }
+
+ @Override
+ public void rollback(Savepoint savepoint) throws SQLException {
+ if (isClosed())
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
+
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
+ }
+
+ @Override
+ public void releaseSavepoint(Savepoint savepoint) throws SQLException {
+ if (isClosed())
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
+
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
+ }
+
+ @Override
+ public Statement createStatement(int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException {
+ if (isClosed())
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
+
+ switch (resultSetHoldability) {
+ case ResultSet.HOLD_CURSORS_OVER_COMMIT:
+ break;
+ case ResultSet.CLOSE_CURSORS_AT_COMMIT:
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
+ default:
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_INVALID_VARIABLE);
+ }
+
+ return createStatement(resultSetType, resultSetConcurrency);
+ }
+
+ @Override
+ public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability)
+ throws SQLException {
+ if (isClosed())
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
+
+ switch (resultSetHoldability) {
+ case ResultSet.HOLD_CURSORS_OVER_COMMIT:
+ break;
+ case ResultSet.CLOSE_CURSORS_AT_COMMIT:
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
+ default:
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_INVALID_VARIABLE);
+ }
+ return prepareStatement(sql, resultSetType, resultSetConcurrency);
+ }
+
+ @Override
+ public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException {
+ if (isClosed())
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
+
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
+ }
+
+ @Override
+ public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys) throws SQLException {
+ if (isClosed())
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
+
+ switch (autoGeneratedKeys) {
+ case Statement.RETURN_GENERATED_KEYS:
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
+ case Statement.NO_GENERATED_KEYS:
+ break;
+ }
+ return prepareStatement(sql, ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY, ResultSet.HOLD_CURSORS_OVER_COMMIT);
+ }
+
+ @Override
+ public PreparedStatement prepareStatement(String sql, int[] columnIndexes) throws SQLException {
+ if (isClosed())
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
+
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
+ }
+
+ @Override
+ public PreparedStatement prepareStatement(String sql, String[] columnNames) throws SQLException {
+ if (isClosed())
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
+
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
+ }
+
+ @Override
+ public Clob createClob() throws SQLException {
+ if (isClosed())
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
+
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
+ }
+
+ @Override
+ public Blob createBlob() throws SQLException {
+ if (isClosed())
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
+
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
+ }
+
+ @Override
+ public NClob createNClob() throws SQLException {
+ if (isClosed())
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
+
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
+ }
+
+ @Override
+ public SQLXML createSQLXML() throws SQLException {
+ if (isClosed())
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
+
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_UNSUPPORTED_METHOD);
+ }
+
+ @Override
+ public boolean isValid(int timeout) throws SQLException {
+ //true if the connection is valid, false otherwise
+ if (isClosed())
+ return false;
+ if (timeout < 0) //SQLException - if the value supplied for timeout is less then 0
+ throw TSDBError.createSQLException(TSDBErrorNumbers.ERROR_INVALID_VARIABLE);
+
+ ExecutorService executor = Executors.newCachedThreadPool();
+ Future future = executor.submit(() -> {
+ int status;
+ try (Statement stmt = createStatement()) {
+ ResultSet resultSet = stmt.executeQuery("select server_status()");
+ resultSet.next();
+ status = resultSet.getInt("server_status()");
+ resultSet.close();
+ }
+ return status == 1 ? true : false;
+ });
+
+ boolean status = false;
+ try {
+ if (timeout == 0)
+ status = future.get();
+ else
+ status = future.get(timeout, TimeUnit.SECONDS);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ } catch (ExecutionException e) {
+ e.printStackTrace();
+ } catch (TimeoutException e) {
+ future.cancel(true);
+ status = false;
+ } finally {
+ executor.shutdownNow();
+ }
+ return status;
+ }
+
+ @Override
+ public void setClientInfo(String name, String value) throws SQLClientInfoException {
+ if (isClosed)
+ throw TSDBError.createSQLClientInfoException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
+
+ if (clientInfoProps == null)
+ clientInfoProps = new Properties();
+ clientInfoProps.setProperty(name, value);
+ }
+
+ @Override
+ public void setClientInfo(Properties properties) throws SQLClientInfoException {
+ if (isClosed)
+ throw TSDBError.createSQLClientInfoException(TSDBErrorNumbers.ERROR_CONNECTION_CLOSED);
+
+ for (Enumeration