JackieTien97 commented on code in PR #14656:
URL: https://github.com/apache/iotdb/pull/14656#discussion_r1944048513


##########
iotdb-client/jdbc/src/main/java/org/apache/iotdb/jdbc/relational/IoTDBRelationalDatabaseMetadata.java:
##########
@@ -0,0 +1,279 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.iotdb.jdbc.relational;
+
+import org.apache.iotdb.jdbc.Field;
+import org.apache.iotdb.jdbc.IoTDBAbstractDatabaseMetadata;
+import org.apache.iotdb.jdbc.IoTDBConnection;
+import org.apache.iotdb.jdbc.IoTDBJDBCResultSet;
+import org.apache.iotdb.service.rpc.thrift.IClientRPCService;
+
+import org.apache.tsfile.enums.TSDataType;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.sql.ResultSet;
+import java.sql.ResultSetMetaData;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.time.ZoneId;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class IoTDBRelationalDatabaseMetadata extends 
IoTDBAbstractDatabaseMetadata {
+
+  private static final Logger LOGGER =
+      LoggerFactory.getLogger(IoTDBRelationalDatabaseMetadata.class);
+
+  private static final String DATABASE_VERSION =
+      
IoTDBRelationalDatabaseMetadata.class.getPackage().getImplementationVersion() 
!= null
+          ? 
IoTDBRelationalDatabaseMetadata.class.getPackage().getImplementationVersion()
+          : "UNKNOWN";
+
+  public static final String SHOW_TABLES_ERROR_MSG = "Show tables error: {}";
+
+  public IoTDBRelationalDatabaseMetadata(
+      IoTDBConnection connection, IClientRPCService.Iface client, long 
sessionId, ZoneId zoneId) {
+    super(connection, client, sessionId, zoneId);
+  }
+
+  @Override
+  public String getDriverVersion() throws SQLException {
+    return DATABASE_VERSION;
+  }
+
+  @Override
+  public ResultSet getTables(
+      String catalog, String schemaPattern, String tableNamePattern, String[] 
types)
+      throws SQLException {
+    LOGGER.info(
+        "GetTables:: catalog:{}, schemaPattern:{}, tableNamePattern:{}, 
types:{}",
+        catalog,
+        schemaPattern,
+        tableNamePattern,
+        types);

Review Comment:
   ```suggestion
   ```



##########
iotdb-client/jdbc/src/main/java/org/apache/iotdb/jdbc/IoTDBStatement.java:
##########
@@ -48,6 +49,8 @@
 
 public class IoTDBStatement implements Statement {
 
+  public static final Logger logger = 
org.slf4j.LoggerFactory.getLogger(IoTDBStatement.class);
+

Review Comment:
   what's this used for? You should define the logger for each class



##########
iotdb-client/jdbc/src/main/java/org/apache/iotdb/jdbc/IoTDBAbstractDatabaseMetadata.java:
##########
@@ -0,0 +1,3194 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.iotdb.jdbc;
+
+import org.apache.iotdb.service.rpc.thrift.IClientRPCService;
+
+import org.apache.thrift.TException;
+import org.apache.tsfile.common.conf.TSFileConfig;
+import org.apache.tsfile.enums.TSDataType;
+import org.apache.tsfile.read.common.block.TsBlock;
+import org.apache.tsfile.read.common.block.TsBlockBuilder;
+import org.apache.tsfile.read.common.block.column.TsBlockSerde;
+import org.apache.tsfile.utils.Binary;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.sql.Connection;
+import java.sql.DatabaseMetaData;
+import java.sql.ResultSet;
+import java.sql.RowIdLifetime;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.sql.Types;
+import java.time.ZoneId;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.TreeMap;
+
+public abstract class IoTDBAbstractDatabaseMetadata implements 
DatabaseMetaData {
+
+  private static final Logger LOGGER = 
LoggerFactory.getLogger(IoTDBAbstractDatabaseMetadata.class);
+  private static final String METHOD_NOT_SUPPORTED_STRING = "Method not 
supported";
+  protected static final String CONVERT_ERROR_MSG = "Convert tsBlock error: 
{}";
+
+  protected IoTDBConnection connection;
+  protected IClientRPCService.Iface client;
+  protected long sessionId;
+  protected ZoneId zoneId;
+
+  protected static final String BOOLEAN = "BOOLEAN";
+  protected static final String DOUBLE = "DOUBLE";
+  protected static final String FLOAT = "FLOAT";
+  protected static final String INT32 = "INT32";
+  protected static final String INT64 = "INT64";
+  protected static final String STRING = "STRING";
+  protected static final String BLOB = "BLOB";
+  protected static final String TIMESTAMP = "TIMESTAMP";
+  protected static final String DATE = "DATE";
+
+  protected static final String sqlKeywordsThatArentSQL92;
+
+  protected static final String BUFFER_LENGTH = "BUFFER_LENGTH";
+  protected static final String CHAR_OCTET_LENGTH = "CHAR_OCTET_LENGTH";
+  protected static final String COLUMN_NAME = "COLUMN_NAME";
+  protected static final String COLUMN_SIZE = "COLUMN_SIZE";
+  private static final String COLUMN_TYPE = "COLUMN_TYPE";
+  protected static final String DATA_TYPE = "DATA_TYPE";
+  protected static final String DECIMAL_DIGITS = "DECIMAL_DIGITS";
+  private static final String DEFERRABILITY = "DEFERRABILITY";
+  private static final String DELETE_RULE = "DELETE_RULE";
+  private static final String FK_NAME = "FK_NAME";
+  private static final String FKCOLUMN_NAME = "FKCOLUMN_NAME";
+  private static final String FKTABLE_CAT = "FKTABLE_CAT";
+  private static final String FKTABLE_NAME = "FKTABLE_NAME";
+  private static final String FKTABLE_SCHEM = "FKTABLE_SCHEM";
+  private static final String FUNCTION_CAT = "FUNCTION_CAT";
+  private static final String FUNCTION_NAME = "FUNCTION_NAME";
+  private static final String FUNCTION_SCHEM = "FUNCTION_SCHEM";
+  private static final String FUNCTION_TYPE = "FUNCTION_TYPE";
+  private static final String GRANTEE = "GRANTEE";
+  private static final String GRANTOR = "GRANTOR";
+  protected static final String IS_AUTOINCREMENT = "IS_AUTOINCREMENT";
+  private static final String IS_GRANTABLE = "IS_GRANTABLE";
+  protected static final String IS_NULLABLE = "IS_NULLABLE";
+  private static final String KEY_SEQ = "KEY_SEQ";
+  private static final String LENGTH = "LENGTH";
+  protected static final String NULLABLE = "NULLABLE";
+  protected static final String NUM_PREC_RADIX = "NUM_PREC_RADIX";
+  protected static final String ORDINAL_POSITION = "ORDINAL_POSITION";
+  private static final String PK_NAME = "PK_NAME";
+  private static final String PKCOLUMN_NAME = "PKCOLUMN_NAME";
+  private static final String PKTABLE_CAT = "PKTABLE_CAT";
+  private static final String PKTABLE_NAME = "PKTABLE_NAME";
+  private static final String PKTABLE_SCHEM = "PKTABLE_SCHEM";
+  protected static final String PRECISION = "PRECISION";
+  protected static final String PRIMARY = "PRIMARY";
+  private static final String PRIVILEGE = "PRIVILEGE";
+  private static final String PROCEDURE_CAT = "PROCEDURE_CAT";
+  private static final String PROCEDURE_NAME = "PROCEDURE_NAME";
+  private static final String PROCEDURE_SCHEM = "PROCEDURE_SCHEM";
+  private static final String PROCEDURE_TYPE = "PROCEDURE_TYPE";
+  private static final String PSEUDO_COLUMN = "PSEUDO_COLUMN";
+  private static final String RADIX = "RADIX";
+  protected static final String REMARKS = "REMARKS";
+  private static final String SCALE = "SCALE";
+  private static final String SCOPE = "SCOPE";
+  private static final String SPECIFIC_NAME = "SPECIFIC_NAME";
+  protected static final String SQL_DATA_TYPE = "SQL_DATA_TYPE";
+  protected static final String SQL_DATETIME_SUB = "SQL_DATETIME_SUB";
+  protected static final String TABLE_CAT = "TABLE_CAT";
+  protected static final String TABLE_SCHEM = "TABLE_SCHEM";
+  protected static final String TABLE_NAME = "TABLE_NAME";
+  protected static final String TABLE_TYPE = "TABLE_TYPE";
+  protected static final String TYPE_CAT = "TYPE_CAT";
+  protected static final String TYPE_NAME = "TYPE_NAME";
+  protected static final String TYPE_SCHEM = "TYPE_SCHEM";
+  private static final String UPDATE_RULE = "UPDATE_RULE";
+
+  private static final String SHOW_FUNCTIONS = "show functions";
+  private static final String SHOW_DATABASES_SQL = "SHOW DATABASES ";
+
+  private static TsBlockSerde serde = new TsBlockSerde();
+
+  public IoTDBAbstractDatabaseMetadata(
+      IoTDBConnection connection, IClientRPCService.Iface client, long 
sessionId, ZoneId zoneId) {
+    this.connection = connection;
+    this.client = client;
+    this.sessionId = sessionId;
+    this.zoneId = zoneId;
+  }
+
+  static {
+    String[] allIotdbSQLKeywords = {

Review Comment:
   keywords of table and tree model are different, you can find keywords of 
table model in https://timechor.feishu.cn/docx/U5OHdYQs1oR0hVxvy5Ucw0KUnBf



##########
iotdb-client/jdbc/src/main/java/org/apache/iotdb/jdbc/relational/IoTDBRelationalDatabaseMetadata.java:
##########
@@ -0,0 +1,279 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.iotdb.jdbc.relational;
+
+import org.apache.iotdb.jdbc.Field;
+import org.apache.iotdb.jdbc.IoTDBAbstractDatabaseMetadata;
+import org.apache.iotdb.jdbc.IoTDBConnection;
+import org.apache.iotdb.jdbc.IoTDBJDBCResultSet;
+import org.apache.iotdb.service.rpc.thrift.IClientRPCService;
+
+import org.apache.tsfile.enums.TSDataType;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.sql.ResultSet;
+import java.sql.ResultSetMetaData;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.time.ZoneId;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class IoTDBRelationalDatabaseMetadata extends 
IoTDBAbstractDatabaseMetadata {
+
+  private static final Logger LOGGER =
+      LoggerFactory.getLogger(IoTDBRelationalDatabaseMetadata.class);
+
+  private static final String DATABASE_VERSION =
+      
IoTDBRelationalDatabaseMetadata.class.getPackage().getImplementationVersion() 
!= null
+          ? 
IoTDBRelationalDatabaseMetadata.class.getPackage().getImplementationVersion()
+          : "UNKNOWN";
+
+  public static final String SHOW_TABLES_ERROR_MSG = "Show tables error: {}";
+
+  public IoTDBRelationalDatabaseMetadata(
+      IoTDBConnection connection, IClientRPCService.Iface client, long 
sessionId, ZoneId zoneId) {
+    super(connection, client, sessionId, zoneId);
+  }
+
+  @Override
+  public String getDriverVersion() throws SQLException {
+    return DATABASE_VERSION;
+  }
+
+  @Override
+  public ResultSet getTables(
+      String catalog, String schemaPattern, String tableNamePattern, String[] 
types)

Review Comment:
   `schemaPattern` and `tableNamePattern` are botn pattern, you should use like 
to do that filter. And the interface definition also tells the order of the 
result, you should order by database, table_name.
   
   you can use information_schema.tables to do that. 
https://timechor.feishu.cn/docx/Mqi9dCcu2oXLo4xxZVbcn8SKnKh



##########
iotdb-client/jdbc/src/main/java/org/apache/iotdb/jdbc/relational/IoTDBRelationalDatabaseMetadata.java:
##########
@@ -0,0 +1,279 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.iotdb.jdbc.relational;
+
+import org.apache.iotdb.jdbc.Field;
+import org.apache.iotdb.jdbc.IoTDBAbstractDatabaseMetadata;
+import org.apache.iotdb.jdbc.IoTDBConnection;
+import org.apache.iotdb.jdbc.IoTDBJDBCResultSet;
+import org.apache.iotdb.service.rpc.thrift.IClientRPCService;
+
+import org.apache.tsfile.enums.TSDataType;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.sql.ResultSet;
+import java.sql.ResultSetMetaData;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.time.ZoneId;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class IoTDBRelationalDatabaseMetadata extends 
IoTDBAbstractDatabaseMetadata {
+
+  private static final Logger LOGGER =
+      LoggerFactory.getLogger(IoTDBRelationalDatabaseMetadata.class);
+
+  private static final String DATABASE_VERSION =
+      
IoTDBRelationalDatabaseMetadata.class.getPackage().getImplementationVersion() 
!= null
+          ? 
IoTDBRelationalDatabaseMetadata.class.getPackage().getImplementationVersion()
+          : "UNKNOWN";
+
+  public static final String SHOW_TABLES_ERROR_MSG = "Show tables error: {}";
+
+  public IoTDBRelationalDatabaseMetadata(
+      IoTDBConnection connection, IClientRPCService.Iface client, long 
sessionId, ZoneId zoneId) {
+    super(connection, client, sessionId, zoneId);
+  }
+
+  @Override
+  public String getDriverVersion() throws SQLException {
+    return DATABASE_VERSION;
+  }
+
+  @Override
+  public ResultSet getTables(
+      String catalog, String schemaPattern, String tableNamePattern, String[] 
types)
+      throws SQLException {
+    LOGGER.info(
+        "GetTables:: catalog:{}, schemaPattern:{}, tableNamePattern:{}, 
types:{}",
+        catalog,
+        schemaPattern,
+        tableNamePattern,
+        types);
+
+    Statement stmt = this.connection.createStatement();
+
+    ResultSet rs;
+    String sql = "SHOW TABLES IN " + schemaPattern;
+    try {
+      rs = stmt.executeQuery(sql);
+    } catch (SQLException e) {
+      stmt.close();
+      LOGGER.error(SHOW_TABLES_ERROR_MSG, e.getMessage());
+      throw e;
+    }
+
+    // Setup Fields
+    Field[] fields = new Field[3];
+    fields[0] = new Field("", TABLE_NAME, "TEXT");
+    fields[1] = new Field("", TABLE_TYPE, "TEXT");
+    fields[2] = new Field("", REMARKS, "TEXT");
+    List<TSDataType> tsDataTypeList =
+        Arrays.asList(TSDataType.TEXT, TSDataType.TEXT, TSDataType.TEXT);
+    List<String> columnNameList = new ArrayList<>();
+    List<String> columnTypeList = new ArrayList<>();
+    Map<String, Integer> columnNameIndex = new HashMap<>();
+    List<List<Object>> valuesList = new ArrayList<>();
+    for (int i = 0; i < fields.length; i++) {
+      columnNameList.add(fields[i].getName());
+      columnTypeList.add(fields[i].getSqlType());
+      columnNameIndex.put(fields[i].getName(), i);
+    }
+
+    // Extract Values
+    boolean hasResultSet = false;
+    while (rs.next()) {
+      hasResultSet = true;
+      List<Object> valueInRow = new ArrayList<>();
+      for (int i = 0; i < fields.length; i++) {
+        if (i == 0) {
+          valueInRow.add(rs.getString(1));
+        } else if (i == 1) {
+          valueInRow.add("TABLE");
+        } else {
+          valueInRow.add("TTL(ms): " + rs.getString(2));
+        }
+      }
+      valuesList.add(valueInRow);
+    }
+
+    // Convert Values to ByteBuffer
+    ByteBuffer tsBlock = null;
+    try {
+      tsBlock = convertTsBlock(valuesList, tsDataTypeList);
+    } catch (IOException e) {
+      LOGGER.error(CONVERT_ERROR_MSG, e.getMessage());
+    } finally {
+      close(rs, stmt);
+    }
+
+    return hasResultSet
+        ? new IoTDBJDBCResultSet(
+            stmt,
+            columnNameList,
+            columnTypeList,
+            columnNameIndex,
+            true,
+            client,
+            null,
+            -1,
+            sessionId,
+            Collections.singletonList(tsBlock),
+            null,
+            (long) 60 * 1000,
+            false,
+            zoneId)
+        : null;
+  }
+
+  @Override
+  public ResultSet getColumns(
+      String catalog, String schemaPattern, String tableNamePattern, String 
columnNamePattern)

Review Comment:
   use `information_schema.columns` to do that.



##########
iotdb-client/jdbc/src/main/java/org/apache/iotdb/jdbc/relational/IoTDBRelationalDatabaseMetadata.java:
##########
@@ -0,0 +1,279 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.iotdb.jdbc.relational;
+
+import org.apache.iotdb.jdbc.Field;
+import org.apache.iotdb.jdbc.IoTDBAbstractDatabaseMetadata;
+import org.apache.iotdb.jdbc.IoTDBConnection;
+import org.apache.iotdb.jdbc.IoTDBJDBCResultSet;
+import org.apache.iotdb.service.rpc.thrift.IClientRPCService;
+
+import org.apache.tsfile.enums.TSDataType;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.sql.ResultSet;
+import java.sql.ResultSetMetaData;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.time.ZoneId;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+public class IoTDBRelationalDatabaseMetadata extends 
IoTDBAbstractDatabaseMetadata {
+
+  private static final Logger LOGGER =
+      LoggerFactory.getLogger(IoTDBRelationalDatabaseMetadata.class);
+
+  private static final String DATABASE_VERSION =
+      
IoTDBRelationalDatabaseMetadata.class.getPackage().getImplementationVersion() 
!= null
+          ? 
IoTDBRelationalDatabaseMetadata.class.getPackage().getImplementationVersion()
+          : "UNKNOWN";
+
+  public static final String SHOW_TABLES_ERROR_MSG = "Show tables error: {}";
+
+  public IoTDBRelationalDatabaseMetadata(
+      IoTDBConnection connection, IClientRPCService.Iface client, long 
sessionId, ZoneId zoneId) {
+    super(connection, client, sessionId, zoneId);
+  }
+
+  @Override
+  public String getDriverVersion() throws SQLException {
+    return DATABASE_VERSION;
+  }
+
+  @Override
+  public ResultSet getTables(
+      String catalog, String schemaPattern, String tableNamePattern, String[] 
types)
+      throws SQLException {
+    LOGGER.info(
+        "GetTables:: catalog:{}, schemaPattern:{}, tableNamePattern:{}, 
types:{}",
+        catalog,
+        schemaPattern,
+        tableNamePattern,
+        types);
+
+    Statement stmt = this.connection.createStatement();
+
+    ResultSet rs;
+    String sql = "SHOW TABLES IN " + schemaPattern;
+    try {
+      rs = stmt.executeQuery(sql);
+    } catch (SQLException e) {
+      stmt.close();
+      LOGGER.error(SHOW_TABLES_ERROR_MSG, e.getMessage());
+      throw e;
+    }
+
+    // Setup Fields
+    Field[] fields = new Field[3];
+    fields[0] = new Field("", TABLE_NAME, "TEXT");
+    fields[1] = new Field("", TABLE_TYPE, "TEXT");
+    fields[2] = new Field("", REMARKS, "TEXT");
+    List<TSDataType> tsDataTypeList =
+        Arrays.asList(TSDataType.TEXT, TSDataType.TEXT, TSDataType.TEXT);
+    List<String> columnNameList = new ArrayList<>();
+    List<String> columnTypeList = new ArrayList<>();
+    Map<String, Integer> columnNameIndex = new HashMap<>();
+    List<List<Object>> valuesList = new ArrayList<>();
+    for (int i = 0; i < fields.length; i++) {
+      columnNameList.add(fields[i].getName());
+      columnTypeList.add(fields[i].getSqlType());
+      columnNameIndex.put(fields[i].getName(), i);
+    }
+
+    // Extract Values
+    boolean hasResultSet = false;
+    while (rs.next()) {
+      hasResultSet = true;
+      List<Object> valueInRow = new ArrayList<>();
+      for (int i = 0; i < fields.length; i++) {
+        if (i == 0) {
+          valueInRow.add(rs.getString(1));
+        } else if (i == 1) {
+          valueInRow.add("TABLE");
+        } else {
+          valueInRow.add("TTL(ms): " + rs.getString(2));
+        }
+      }
+      valuesList.add(valueInRow);
+    }
+
+    // Convert Values to ByteBuffer
+    ByteBuffer tsBlock = null;
+    try {
+      tsBlock = convertTsBlock(valuesList, tsDataTypeList);
+    } catch (IOException e) {
+      LOGGER.error(CONVERT_ERROR_MSG, e.getMessage());
+    } finally {
+      close(rs, stmt);
+    }
+
+    return hasResultSet
+        ? new IoTDBJDBCResultSet(
+            stmt,
+            columnNameList,
+            columnTypeList,
+            columnNameIndex,
+            true,
+            client,
+            null,
+            -1,
+            sessionId,
+            Collections.singletonList(tsBlock),
+            null,
+            (long) 60 * 1000,
+            false,
+            zoneId)
+        : null;
+  }
+
+  @Override
+  public ResultSet getColumns(
+      String catalog, String schemaPattern, String tableNamePattern, String 
columnNamePattern)
+      throws SQLException {
+
+    LOGGER.info(
+        "GetColumns:: catalog:{}, schemaPattern:{}, tableNamePattern:{}, 
columnNamePattern:{}",
+        catalog,
+        schemaPattern,
+        tableNamePattern,
+        columnNamePattern);

Review Comment:
   ```suggestion
   ```



##########
iotdb-client/jdbc/src/main/java/org/apache/iotdb/jdbc/IoTDBAbstractDatabaseMetadata.java:
##########
@@ -0,0 +1,3194 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.iotdb.jdbc;
+
+import org.apache.iotdb.service.rpc.thrift.IClientRPCService;
+
+import org.apache.thrift.TException;
+import org.apache.tsfile.common.conf.TSFileConfig;
+import org.apache.tsfile.enums.TSDataType;
+import org.apache.tsfile.read.common.block.TsBlock;
+import org.apache.tsfile.read.common.block.TsBlockBuilder;
+import org.apache.tsfile.read.common.block.column.TsBlockSerde;
+import org.apache.tsfile.utils.Binary;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.sql.Connection;
+import java.sql.DatabaseMetaData;
+import java.sql.ResultSet;
+import java.sql.RowIdLifetime;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.sql.Types;
+import java.time.ZoneId;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.TreeMap;
+
+public abstract class IoTDBAbstractDatabaseMetadata implements 
DatabaseMetaData {
+
+  private static final Logger LOGGER = 
LoggerFactory.getLogger(IoTDBAbstractDatabaseMetadata.class);
+  private static final String METHOD_NOT_SUPPORTED_STRING = "Method not 
supported";
+  protected static final String CONVERT_ERROR_MSG = "Convert tsBlock error: 
{}";
+
+  protected IoTDBConnection connection;
+  protected IClientRPCService.Iface client;
+  protected long sessionId;
+  protected ZoneId zoneId;
+
+  protected static final String BOOLEAN = "BOOLEAN";
+  protected static final String DOUBLE = "DOUBLE";
+  protected static final String FLOAT = "FLOAT";
+  protected static final String INT32 = "INT32";
+  protected static final String INT64 = "INT64";
+  protected static final String STRING = "STRING";
+  protected static final String BLOB = "BLOB";
+  protected static final String TIMESTAMP = "TIMESTAMP";
+  protected static final String DATE = "DATE";
+
+  protected static final String sqlKeywordsThatArentSQL92;
+
+  protected static final String BUFFER_LENGTH = "BUFFER_LENGTH";
+  protected static final String CHAR_OCTET_LENGTH = "CHAR_OCTET_LENGTH";
+  protected static final String COLUMN_NAME = "COLUMN_NAME";
+  protected static final String COLUMN_SIZE = "COLUMN_SIZE";
+  private static final String COLUMN_TYPE = "COLUMN_TYPE";
+  protected static final String DATA_TYPE = "DATA_TYPE";
+  protected static final String DECIMAL_DIGITS = "DECIMAL_DIGITS";
+  private static final String DEFERRABILITY = "DEFERRABILITY";
+  private static final String DELETE_RULE = "DELETE_RULE";
+  private static final String FK_NAME = "FK_NAME";
+  private static final String FKCOLUMN_NAME = "FKCOLUMN_NAME";
+  private static final String FKTABLE_CAT = "FKTABLE_CAT";
+  private static final String FKTABLE_NAME = "FKTABLE_NAME";
+  private static final String FKTABLE_SCHEM = "FKTABLE_SCHEM";
+  private static final String FUNCTION_CAT = "FUNCTION_CAT";
+  private static final String FUNCTION_NAME = "FUNCTION_NAME";
+  private static final String FUNCTION_SCHEM = "FUNCTION_SCHEM";
+  private static final String FUNCTION_TYPE = "FUNCTION_TYPE";
+  private static final String GRANTEE = "GRANTEE";
+  private static final String GRANTOR = "GRANTOR";
+  protected static final String IS_AUTOINCREMENT = "IS_AUTOINCREMENT";
+  private static final String IS_GRANTABLE = "IS_GRANTABLE";
+  protected static final String IS_NULLABLE = "IS_NULLABLE";
+  private static final String KEY_SEQ = "KEY_SEQ";
+  private static final String LENGTH = "LENGTH";
+  protected static final String NULLABLE = "NULLABLE";
+  protected static final String NUM_PREC_RADIX = "NUM_PREC_RADIX";
+  protected static final String ORDINAL_POSITION = "ORDINAL_POSITION";
+  private static final String PK_NAME = "PK_NAME";
+  private static final String PKCOLUMN_NAME = "PKCOLUMN_NAME";
+  private static final String PKTABLE_CAT = "PKTABLE_CAT";
+  private static final String PKTABLE_NAME = "PKTABLE_NAME";
+  private static final String PKTABLE_SCHEM = "PKTABLE_SCHEM";
+  protected static final String PRECISION = "PRECISION";
+  protected static final String PRIMARY = "PRIMARY";
+  private static final String PRIVILEGE = "PRIVILEGE";
+  private static final String PROCEDURE_CAT = "PROCEDURE_CAT";
+  private static final String PROCEDURE_NAME = "PROCEDURE_NAME";
+  private static final String PROCEDURE_SCHEM = "PROCEDURE_SCHEM";
+  private static final String PROCEDURE_TYPE = "PROCEDURE_TYPE";
+  private static final String PSEUDO_COLUMN = "PSEUDO_COLUMN";
+  private static final String RADIX = "RADIX";
+  protected static final String REMARKS = "REMARKS";
+  private static final String SCALE = "SCALE";
+  private static final String SCOPE = "SCOPE";
+  private static final String SPECIFIC_NAME = "SPECIFIC_NAME";
+  protected static final String SQL_DATA_TYPE = "SQL_DATA_TYPE";
+  protected static final String SQL_DATETIME_SUB = "SQL_DATETIME_SUB";
+  protected static final String TABLE_CAT = "TABLE_CAT";
+  protected static final String TABLE_SCHEM = "TABLE_SCHEM";
+  protected static final String TABLE_NAME = "TABLE_NAME";
+  protected static final String TABLE_TYPE = "TABLE_TYPE";
+  protected static final String TYPE_CAT = "TYPE_CAT";
+  protected static final String TYPE_NAME = "TYPE_NAME";
+  protected static final String TYPE_SCHEM = "TYPE_SCHEM";
+  private static final String UPDATE_RULE = "UPDATE_RULE";
+
+  private static final String SHOW_FUNCTIONS = "show functions";
+  private static final String SHOW_DATABASES_SQL = "SHOW DATABASES ";
+
+  private static TsBlockSerde serde = new TsBlockSerde();
+
+  public IoTDBAbstractDatabaseMetadata(
+      IoTDBConnection connection, IClientRPCService.Iface client, long 
sessionId, ZoneId zoneId) {
+    this.connection = connection;
+    this.client = client;
+    this.sessionId = sessionId;
+    this.zoneId = zoneId;
+  }
+
+  static {
+    String[] allIotdbSQLKeywords = {
+      "ALTER",
+      "ADD",
+      "ALIAS",
+      "ALL",
+      "AVG",
+      "ALIGN",
+      "ATTRIBUTES",
+      "AS",
+      "ASC",
+      "BY",
+      BOOLEAN,
+      "BITMAP",
+      "CREATE",
+      "CONFIGURATION",
+      "COMPRESSOR",
+      "CHILD",
+      "COUNT",
+      "COMPRESSION",
+      "CLEAR",
+      "CACHE",
+      "CONTAIN",
+      "CONCAT",
+      "DELETE",
+      "DEVICE",
+      "DESCRIBE",
+      "DATATYPE",
+      DOUBLE,
+      "DIFF",
+      "DROP",
+      "DEVICES",
+      "DISABLE",
+      "DESC",
+      "ENCODING",
+      "FROM",
+      "FILL",
+      FLOAT,
+      "FLUSH",
+      "FIRST_VALUE",
+      "FULL",
+      "FALSE",
+      "FOR",
+      "FUNCTION",
+      "FUNCTIONS",
+      "GRANT",
+      "GROUP",
+      "GORILLA",
+      "GLOBAL",
+      "GZIP",
+      "INSERT",
+      "INTO",
+      INT32,
+      INT64,
+      "INDEX",
+      "INFO",
+      "KILL",
+      "LIMIT",
+      "LINEAR",
+      "LABEL",
+      "LINK",
+      "LIST",
+      "LOAD",
+      "LEVEL",
+      "LAST_VALUE",
+      "LAST",
+      "LZO",
+      "LZ4",
+      "ZSTD",
+      "LZMA2",
+      "LATEST",
+      "LIKE",
+      "MAX_BY",
+      "MIN_BY",
+      "METADATA",
+      "MOVE",
+      "MIN_TIME",
+      "MAX_TIME",
+      "MIN_VALUE",
+      "MAX_VALUE",
+      "NOW",
+      "NODES",
+      "ORDER",
+      "OFFSET",
+      "ON",
+      "OFF",
+      "OF",
+      "PROCESSLIST",
+      "PREVIOUS",
+      "PREVIOUSUNTILLAST",
+      "PROPERTY",
+      "PLAIN",
+      "PLAIN_DICTIONARY",
+      "PRIVILEGES",
+      "PASSWORD",
+      "PATHS",
+      "PAA",
+      "PLA",
+      "PARTITION",
+      "QUERY",
+      "ROOT",
+      "RLE",
+      "REGULAR",
+      "ROLE",
+      "REVOKE",
+      "REMOVE",
+      "RENAME",
+      "SELECT",
+      "SHOW",
+      "SET",
+      "SLIMIT",
+      "SOFFSET",
+      "STDDEV",
+      "STDDEV_POP",
+      "STDDEV_SAMP",
+      "STORAGE",
+      "SUM",
+      "SNAPPY",
+      "SNAPSHOT",
+      "SCHEMA",
+      "TO",
+      "TIMESERIES",
+      "TIMESTAMP",
+      "TEXT",
+      "TS_2DIFF",
+      "TRACING",
+      "TTL",
+      "TASK",
+      "TIME",
+      "TAGS",
+      "TRUE",
+      "TEMPORARY",
+      "TOP",
+      "TOLERANCE",
+      "UPDATE",
+      "UNLINK",
+      "UPSERT",
+      "USING",
+      "USER",
+      "UNSET",
+      "UNCOMPRESSED",
+      "VALUES",
+      "VARIANCE",
+      "VAR_POP",
+      "VAR_SAMP",
+      "VERSION",
+      "WHERE",
+      "WITH",
+      "WATERMARK_EMBEDDING"
+    };
+
+    String[] sql92Keywords = {
+      "ABSOLUTE",
+      "EXEC",
+      "OVERLAPS",
+      "ACTION",
+      "EXECUTE",
+      "PAD",
+      "ADA",
+      "EXISTS",
+      "PARTIAL",
+      "ADD",
+      "EXTERNAL",
+      "PASCAL",
+      "ALL",
+      "EXTRACT",
+      "POSITION",
+      "ALLOCATE",
+      "FALSE",
+      PRECISION,
+      "ALTER",
+      "FETCH",
+      "PREPARE",
+      "AND",
+      "FIRST",
+      "PRESERVE",
+      "ANY",
+      FLOAT,
+      PRIMARY,
+      "ARE",
+      "FOR",
+      "PRIOR",
+      "AS",
+      "FOREIGN",
+      "PRIVILEGES",
+      "ASC",
+      "FORTRAN",
+      "PROCEDURE",
+      "ASSERTION",
+      "FOUND",
+      "PUBLIC",
+      "AT",
+      "FROM",
+      "READ",
+      "AUTHORIZATION",
+      "FULL",
+      "REAL",
+      "AVG",
+      "GET",
+      "REFERENCES",
+      "BEGIN",
+      "GLOBAL",
+      "RELATIVE",
+      "BETWEEN",
+      "GO",
+      "RESTRICT",
+      "BIT",
+      "GOTO",
+      "REVOKE",
+      "BIT_LENGTH",
+      "GRANT",
+      "RIGHT",
+      "BOTH",
+      "GROUP",
+      "ROLLBACK",
+      "BY",
+      "HAVING",
+      "ROWS",
+      "CASCADE",
+      "HOUR",
+      "SCHEMA",
+      "CASCADED",
+      "IDENTITY",
+      "SCROLL",
+      "CASE",
+      "IMMEDIATE",
+      "SECOND",
+      "CAST",
+      "IN",
+      "SECTION",
+      "CATALOG",
+      "INCLUDE",
+      "SELECT",
+      "CHAR",
+      "INDEX",
+      "SESSION",
+      "CHAR_LENGTH",
+      "INDICATOR",
+      "SESSION_USER",
+      "CHARACTER",
+      "INITIALLY",
+      "SET",
+      "CHARACTER_LENGTH",
+      "INNER",
+      "SIZE",
+      "CHECK",
+      "INPUT",
+      "SMALLINT",
+      "CLOSE",
+      "INSENSITIVE",
+      "SOME",
+      "COALESCE",
+      "INSERT",
+      "SPACE",
+      "COLLATE",
+      "INT",
+      "SQL",
+      "COLLATION",
+      "INTEGER",
+      "SQLCA",
+      "COLUMN",
+      "INTERSECT",
+      "SQLCODE",
+      "COMMIT",
+      "INTERVAL",
+      "SQLERROR",
+      "CONNECT",
+      "INTO",
+      "SQLSTATE",
+      "CONNECTION",
+      "IS",
+      "SQLWARNING",
+      "CONSTRAINT",
+      "ISOLATION",
+      "SUBSTRING",
+      "CONSTRAINTS",
+      "JOIN",
+      "SUM",
+      "CONTINUE",
+      "KEY",
+      "SYSTEM_USER",
+      "CONVERT",
+      "LANGUAGE",
+      "TABLE",
+      "CORRESPONDING",
+      "LAST",
+      "TEMPORARY",
+      "COUNT",
+      "LEADING",
+      "THEN",
+      "CREATE",
+      "LEFT",
+      "TIME",
+      "CROSS",
+      "LEVEL",
+      "TIMESTAMP",
+      "CURRENT",
+      "LIKE",
+      "TIMEZONE_HOUR",
+      "CURRENT_DATE",
+      "LOCAL",
+      "TIMEZONE_MINUTE",
+      "CURRENT_TIME",
+      "LOWER",
+      "TO",
+      "CURRENT_TIMESTAMP",
+      "MATCH",
+      "TRAILING",
+      "CURRENT_USER",
+      "MAX",
+      "TRANSACTION",
+      "CURSOR",
+      "MIN",
+      "TRANSLATE",
+      "DATE",
+      "MINUTE",
+      "TRANSLATION",
+      "DAY",
+      "MODULE",
+      "TRIM",
+      "DEALLOCATE",
+      "MONTH",
+      "TRUE",
+      "DEC",
+      "NAMES",
+      "UNION",
+      "DECIMAL",
+      "NATIONAL",
+      "UNIQUE",
+      "DECLARE",
+      "NATURAL",
+      "UNKNOWN",
+      "DEFAULT",
+      "NCHAR",
+      "UPDATE",
+      "DEFERRABLE",
+      "NEXT",
+      "UPPER",
+      "DEFERRED",
+      "NO",
+      "USAGE",
+      "DELETE",
+      "NONE",
+      "USER",
+      "DESC",
+      "NOT",
+      "USING",
+      "DESCRIBE",
+      "NULL",
+      "VALUE",
+      "DESCRIPTOR",
+      "NULLIF",
+      "VALUES",
+      "DIAGNOSTICS",
+      "NUMERIC",
+      "VARCHAR",
+      "DISCONNECT",
+      "OCTET_LENGTH",
+      "VARYING",
+      "DISTINCT",
+      "OF",
+      "VIEW",
+      "DOMAIN",
+      "ON",
+      "WHEN",
+      DOUBLE,
+      "ONLY",
+      "WHENEVER",
+      "DROP",
+      "OPEN",
+      "WHERE",
+      "ELSE",
+      "OPTION",
+      "WITH",
+      "END",
+      "OR",
+      "WORK",
+      "END-EXEC",
+      "ORDER",
+      "WRITE",
+      "ESCAPE",
+      "OUTER",
+      "YEAR",
+      "EXCEPT",
+      "OUTPUT",
+      "ZONE",
+      "EXCEPTION"
+    };
+
+    try {
+      TreeMap<String, String> myKeywordMap = new TreeMap<>();
+      for (String allIotdbSQLKeyword : allIotdbSQLKeywords) {
+        myKeywordMap.put(allIotdbSQLKeyword, null);
+      }
+
+      HashMap<String, String> sql92KeywordMap = new 
HashMap<>(sql92Keywords.length);
+      for (String sql92Keyword : sql92Keywords) {
+        sql92KeywordMap.put(sql92Keyword, null);
+      }
+
+      Iterator<String> it = sql92KeywordMap.keySet().iterator();
+      while (it.hasNext()) {
+        myKeywordMap.remove(it.next());
+      }
+
+      StringBuilder keywordBuf = new StringBuilder();
+      it = myKeywordMap.keySet().iterator();
+      if (it.hasNext()) {
+        keywordBuf.append(it.next());
+      }
+      while (it.hasNext()) {
+        keywordBuf.append(",");
+        keywordBuf.append(it.next());
+      }
+      sqlKeywordsThatArentSQL92 = keywordBuf.toString();
+
+    } catch (Exception e) {
+      LOGGER.error("Error when initializing SQL keywords: ", e);
+      throw new RuntimeException(e);
+    }
+  }
+
+  public static ByteBuffer convertTsBlock(
+      List<List<Object>> valuesList, List<TSDataType> tsDataTypeList) throws 
IOException {
+    TsBlockBuilder tsBlockBuilder = new TsBlockBuilder(tsDataTypeList);
+    for (List<Object> valuesInRow : valuesList) {
+      tsBlockBuilder.getTimeColumnBuilder().writeLong(0);
+      for (int j = 0; j < tsDataTypeList.size(); j++) {
+        TSDataType columnType = tsDataTypeList.get(j);
+        switch (columnType) {
+          case TEXT:
+          case STRING:
+          case BLOB:
+            tsBlockBuilder
+                .getColumnBuilder(j)
+                .writeBinary(
+                    new Binary(valuesInRow.get(j).toString(), 
TSFileConfig.STRING_CHARSET));
+            break;
+          case FLOAT:
+            tsBlockBuilder.getColumnBuilder(j).writeFloat((float) 
valuesInRow.get(j));
+            break;
+          case INT32:
+          case DATE:
+            tsBlockBuilder.getColumnBuilder(j).writeInt((int) 
valuesInRow.get(j));
+            break;
+          case INT64:
+          case TIMESTAMP:
+            tsBlockBuilder.getColumnBuilder(j).writeLong((long) 
valuesInRow.get(j));
+            break;
+          case DOUBLE:
+            tsBlockBuilder.getColumnBuilder(j).writeDouble((double) 
valuesInRow.get(j));
+            break;
+          case BOOLEAN:
+            tsBlockBuilder.getColumnBuilder(j).writeBoolean((boolean) 
valuesInRow.get(j));
+            break;
+          default:
+            LOGGER.error("No data type was matched: {}", columnType);
+            break;
+        }
+      }
+      tsBlockBuilder.declarePosition();
+    }
+    TsBlock tsBlock = tsBlockBuilder.build();
+    if (tsBlock == null) {
+      return null;
+    } else {
+      return serde.serialize(tsBlock);
+    }
+  }
+
+  protected void close(ResultSet rs, Statement stmt) {
+    try {
+      if (rs != null) {
+        rs.close();
+      }
+    } catch (Exception ex) {
+      rs = null;
+    }
+    try {
+      if (stmt != null) {
+        stmt.close();
+      }
+    } catch (Exception ex) {
+      stmt = null;
+    }
+  }
+
+  protected int getSQLType(String columnType) {
+    switch (columnType.toUpperCase()) {
+      case BOOLEAN:
+        return Types.BOOLEAN;
+      case INT32:
+        return Types.INTEGER;
+      case INT64:
+        return Types.BIGINT;
+      case FLOAT:
+        return Types.FLOAT;
+      case DOUBLE:
+        return Types.DOUBLE;
+      case "TEXT":
+        return Types.LONGVARCHAR;
+      case STRING:
+        return Types.VARCHAR;
+      case BLOB:
+        return Types.BLOB;
+      case TIMESTAMP:
+        return Types.TIMESTAMP;
+      case DATE:
+        return Types.DATE;
+      default:
+        break;
+    }
+    return 0;
+  }
+
+  protected int getTypePrecision(String columnType) {
+    switch (columnType.toUpperCase()) {
+      case BOOLEAN:
+        return 1;
+      case INT32:
+        return 10;
+      case INT64:
+        return 19;
+      case FLOAT:
+        return 38;
+      case DOUBLE:
+        return 308;
+      case "TEXT":
+      case BLOB:
+      case STRING:
+        return Integer.MAX_VALUE;
+      case TIMESTAMP:
+        return 3;
+      case DATE:
+        return 0;
+      default:
+        break;
+    }
+    return 0;
+  }
+
+  protected int getTypeScale(String columnType) {
+    switch (columnType.toUpperCase()) {
+      case BOOLEAN:
+      case INT32:
+      case INT64:
+      case "TEXT":
+      case BLOB:
+      case STRING:
+      case TIMESTAMP:
+      case DATE:
+        return 0;
+      case FLOAT:
+        return 6;
+      case DOUBLE:
+        return 15;
+      default:
+        break;
+    }
+    return 0;
+  }
+
+  @Override
+  public boolean allProceduresAreCallable() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean allTablesAreSelectable() throws SQLException {
+    return true;
+  }
+
+  @Override
+  public String getURL() throws SQLException {
+    // TODO: Return the URL for this DBMS or null if it cannot be generated
+    return this.connection.getUrl();
+  }
+
+  @Override
+  public String getUserName() throws SQLException {
+    return connection.getUserName();
+  }
+
+  @Override
+  public boolean isReadOnly() throws SQLException {
+    try {
+      return client.getProperties().isReadOnly;
+    } catch (TException e) {
+      LOGGER.error("Get is readOnly error: {}", e.getMessage());
+    }
+    throw new SQLException("Can not get the read-only mode");
+  }
+
+  @Override
+  public boolean nullsAreSortedHigh() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean nullsAreSortedLow() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean nullsAreSortedAtStart() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean nullsAreSortedAtEnd() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public String getDatabaseProductName() throws SQLException {
+    return Constant.GLOBAL_DB_NAME;
+  }
+
+  @Override
+  public String getDatabaseProductVersion() throws SQLException {
+    return getDriverVersion();
+  }
+
+  @Override
+  public String getDriverName() throws SQLException {
+    return org.apache.iotdb.jdbc.IoTDBDriver.class.getName();
+  }
+
+  @Override
+  public abstract String getDriverVersion() throws SQLException;
+
+  @Override
+  public int getDriverMajorVersion() {
+    return 4;
+  }
+
+  @Override
+  public int getDriverMinorVersion() {
+    return 3;
+  }
+
+  @Override
+  public boolean usesLocalFiles() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean usesLocalFilePerTable() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean supportsMixedCaseIdentifiers() throws SQLException {
+    return true;
+  }
+
+  @Override
+  public boolean storesUpperCaseIdentifiers() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean storesLowerCaseIdentifiers() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean storesMixedCaseIdentifiers() throws SQLException {
+    return true;
+  }
+
+  @Override
+  public boolean supportsMixedCaseQuotedIdentifiers() throws SQLException {
+    return true;
+  }
+
+  @Override
+  public boolean storesUpperCaseQuotedIdentifiers() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean storesLowerCaseQuotedIdentifiers() throws SQLException {
+    return false;
+  }
+
+  @Override
+  public boolean storesMixedCaseQuotedIdentifiers() throws SQLException {
+    return true;
+  }
+
+  @Override
+  public String getIdentifierQuoteString() throws SQLException {
+    return "";
+  }
+
+  @Override
+  public String getSQLKeywords() throws SQLException {
+    return sqlKeywordsThatArentSQL92;
+  }
+
+  @Override
+  public String getNumericFunctions() throws SQLException {
+    ResultSet resultSet = null;
+    Statement statement = null;
+    String result = "";
+    try {
+      statement = connection.createStatement();
+      StringBuilder str = new StringBuilder("");
+      resultSet = statement.executeQuery(SHOW_FUNCTIONS);
+      List<String> listFunction = Arrays.asList("MAX_TIME", "MIN_TIME", 
"TIME_DIFFERENCE", "NOW");
+      while (resultSet.next()) {
+        if (listFunction.contains(resultSet.getString(1))) {
+          continue;
+        }
+        str.append(resultSet.getString(1)).append(",");
+      }
+      result = str.toString();
+      if (!result.isEmpty()) {
+        result = result.substring(0, result.length() - 1);
+      }
+    } catch (Exception e) {
+      LOGGER.error("Get numeric functions error: {}", e.getMessage());
+    } finally {
+      close(resultSet, statement);
+    }
+    return result;
+  }

Review Comment:
   not right



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


Reply via email to