This is an automated email from the ASF dual-hosted git repository.

jackietien pushed a commit to branch ty/TEXT2STRING
in repository https://gitbox.apache.org/repos/asf/iotdb.git

commit 72ba229b592bcfa68a979311dac7fc8a0e981f1f
Author: JackieTien97 <[email protected]>
AuthorDate: Fri Jun 28 20:37:20 2024 +0800

    Add IT for table management and change type of ID and ATTRIBUTE column from 
TEXT to STRING
---
 .../iotdb/itbase/runtime/ClusterTestStatement.java |  11 +-
 .../relational/it/schema/IoTDBDatabaseIT.java      |   4 +-
 .../iotdb/relational/it/schema/IoTDBTableIT.java   | 203 +++++++++++++++++++++
 .../CnToDnInternalServiceAsyncRequestManager.java  |   5 +
 .../impl/schema/table/CreateTableProcedure.java    |   8 +-
 .../execution/config/TableConfigTaskVisitor.java   |  46 ++++-
 .../config/executor/ClusterConfigTaskExecutor.java |  13 +-
 .../relational/AlterTableAddColumnTask.java        |  14 +-
 .../config/metadata/relational/ShowTablesTask.java |   7 +-
 .../relational/metadata/TableMetadataImpl.java     |   4 +-
 .../db/schemaengine/table/DataNodeTableCache.java  |  10 +-
 .../apache/iotdb/db/utils/ErrorHandlingUtils.java  |   6 +-
 .../plan/relational/analyzer/TestMatadata.java     |  12 +-
 .../apache/iotdb/commons/schema/table/TsTable.java |   4 +
 14 files changed, 310 insertions(+), 37 deletions(-)

diff --git 
a/integration-test/src/main/java/org/apache/iotdb/itbase/runtime/ClusterTestStatement.java
 
b/integration-test/src/main/java/org/apache/iotdb/itbase/runtime/ClusterTestStatement.java
index c6b139a3eeb..f8c3e38ea57 100644
--- 
a/integration-test/src/main/java/org/apache/iotdb/itbase/runtime/ClusterTestStatement.java
+++ 
b/integration-test/src/main/java/org/apache/iotdb/itbase/runtime/ClusterTestStatement.java
@@ -187,7 +187,16 @@ public class ClusterTestStatement implements Statement {
 
   @Override
   public boolean execute(String sql) throws SQLException {
-    return writeStatement.execute(sql);
+    sql = sql.trim();
+    boolean result = writeStatement.execute(sql);
+    // if use XXXX, sendRequest to all statements
+    if (sql.length() > 4 && "use ".equalsIgnoreCase(sql.substring(0, 4))) {
+      for (Statement readStatement : readStatements) {
+        boolean tmp = readStatement.execute(sql);
+        result = result && tmp;
+      }
+    }
+    return result;
   }
 
   @Override
diff --git 
a/integration-test/src/test/java/org/apache/iotdb/relational/it/schema/IoTDBDatabaseIT.java
 
b/integration-test/src/test/java/org/apache/iotdb/relational/it/schema/IoTDBDatabaseIT.java
index d2450039a70..3260d4b27f6 100644
--- 
a/integration-test/src/test/java/org/apache/iotdb/relational/it/schema/IoTDBDatabaseIT.java
+++ 
b/integration-test/src/test/java/org/apache/iotdb/relational/it/schema/IoTDBDatabaseIT.java
@@ -147,9 +147,9 @@ public class IoTDBDatabaseIT {
       }
       //
       //      // TODO fix it, should succeed
-      statement.execute("create database \"a.b\"");
+      //      statement.execute("create database \"a.b\"");
       //      statement.execute("use \"a.b\"");
-      statement.execute("drop database \"a.b\"");
+      //      statement.execute("drop database \"a.b\"");
 
     } catch (SQLException e) {
       e.printStackTrace();
diff --git 
a/integration-test/src/test/java/org/apache/iotdb/relational/it/schema/IoTDBTableIT.java
 
b/integration-test/src/test/java/org/apache/iotdb/relational/it/schema/IoTDBTableIT.java
index a01741d2cda..d55fc3300fe 100644
--- 
a/integration-test/src/test/java/org/apache/iotdb/relational/it/schema/IoTDBTableIT.java
+++ 
b/integration-test/src/test/java/org/apache/iotdb/relational/it/schema/IoTDBTableIT.java
@@ -23,12 +23,25 @@ import org.apache.iotdb.it.env.EnvFactory;
 import org.apache.iotdb.it.framework.IoTDBTestRunner;
 import org.apache.iotdb.itbase.category.ClusterIT;
 import org.apache.iotdb.itbase.category.LocalStandaloneIT;
+import org.apache.iotdb.itbase.env.BaseEnv;
 
 import org.junit.AfterClass;
 import org.junit.BeforeClass;
+import org.junit.Test;
 import org.junit.experimental.categories.Category;
 import org.junit.runner.RunWith;
 
+import java.sql.Connection;
+import java.sql.ResultSet;
+import java.sql.ResultSetMetaData;
+import java.sql.SQLException;
+import java.sql.Statement;
+
+import static 
org.apache.iotdb.db.queryengine.common.header.ColumnHeaderConstant.describeTableColumnHeaders;
+import static 
org.apache.iotdb.db.queryengine.common.header.ColumnHeaderConstant.showTablesColumnHeaders;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
 @RunWith(IoTDBTestRunner.class)
 @Category({LocalStandaloneIT.class, ClusterIT.class})
 public class IoTDBTableIT {
@@ -42,4 +55,194 @@ public class IoTDBTableIT {
   public static void tearDown() throws Exception {
     EnvFactory.getEnv().cleanClusterEnvironment();
   }
+
+  @Test
+  public void testManageDatabase() {
+    try (Connection connection = 
EnvFactory.getEnv().getConnection(BaseEnv.TABLE_SQL_DIALECT);
+        Statement statement = connection.createStatement()) {
+
+      statement.execute("create database test1");
+      statement.execute("create database test2");
+
+      // should specify database before create table
+      try {
+        statement.execute(
+            "create table table1(region_id STRING ID, plant_id STRING ID, 
device_id STRING ID, model STRING ATTRIBUTE, temperature FLOAT MEASUREMENT, 
humidity DOUBLE MEASUREMENT) with (TTL=3600000)");
+      } catch (SQLException e) {
+        assertEquals("701: database is not specified", e.getMessage());
+      }
+
+      // or use full qualified table name
+      statement.execute(
+          "create table test1.table1(region_id STRING ID, plant_id STRING ID, 
device_id STRING ID, model STRING ATTRIBUTE, temperature FLOAT MEASUREMENT, 
humidity DOUBLE MEASUREMENT) with (TTL=3600000)");
+
+      statement.execute("use test2");
+
+      try {
+        statement.execute(
+            "create table table2(region_id TEXT ID, plant_id STRING ID, 
device_id STRING ID, model STRING ATTRIBUTE, temperature FLOAT MEASUREMENT, 
humidity DOUBLE MEASUREMENT) with (TTL=3600000)");
+      } catch (SQLException e) {
+        assertEquals(
+            "701: DataType of ID Column should only be STRING, current is 
TEXT", e.getMessage());
+      }
+
+      try {
+        statement.execute(
+            "create table table2(region_id INT32 ID, plant_id STRING ID, 
device_id STRING ID, model STRING ATTRIBUTE, temperature FLOAT MEASUREMENT, 
humidity DOUBLE MEASUREMENT) with (TTL=3600000)");
+      } catch (SQLException e) {
+        assertEquals(
+            "701: DataType of ID Column should only be STRING, current is 
INT32", e.getMessage());
+      }
+
+      try {
+        statement.execute(
+            "create table table2(region_id STRING ID, plant_id STRING ID, 
device_id STRING ID, model TEXT ATTRIBUTE, temperature FLOAT MEASUREMENT, 
humidity DOUBLE MEASUREMENT) with (TTL=3600000)");
+      } catch (SQLException e) {
+        assertEquals(
+            "701: DataType of ATTRIBUTE Column should only be STRING, current 
is TEXT",
+            e.getMessage());
+      }
+
+      try {
+        statement.execute(
+            "create table table2(region_id STRING ID, plant_id STRING ID, 
device_id STRING ID, model DOUBLE ATTRIBUTE, temperature FLOAT MEASUREMENT, 
humidity DOUBLE MEASUREMENT) with (TTL=3600000)");
+      } catch (SQLException e) {
+        assertEquals(
+            "701: DataType of ATTRIBUTE Column should only be STRING, current 
is DOUBLE",
+            e.getMessage());
+      }
+
+      statement.execute(
+          "create table table2(region_id STRING ID, plant_id STRING ID, color 
STRING ATTRIBUTE, temperature FLOAT MEASUREMENT, speed DOUBLE MEASUREMENT) with 
(TTL=6600000)");
+
+      String[] tableNames = new String[] {"table2"};
+      long[] ttls = new long[] {6600000L};
+
+      // show tables from current database
+      try (ResultSet resultSet = statement.executeQuery("SHOW tables")) {
+        int cnt = 0;
+        ResultSetMetaData metaData = resultSet.getMetaData();
+        assertEquals(showTablesColumnHeaders.size(), 
metaData.getColumnCount());
+        for (int i = 0; i < showTablesColumnHeaders.size(); i++) {
+          assertEquals(
+              showTablesColumnHeaders.get(i).getColumnName(), 
metaData.getColumnName(i + 1));
+        }
+        while (resultSet.next()) {
+          assertEquals(tableNames[cnt], resultSet.getString(1));
+          assertEquals(ttls[cnt], resultSet.getInt(2));
+          cnt++;
+        }
+        assertEquals(tableNames.length, cnt);
+      }
+
+      // show tables by specifying another database
+      tableNames = new String[] {"table1"};
+      ttls = new long[] {3600000L};
+
+      // using SHOW tables in
+      try (ResultSet resultSet = statement.executeQuery("SHOW tables in 
test1")) {
+        int cnt = 0;
+        ResultSetMetaData metaData = resultSet.getMetaData();
+        assertEquals(showTablesColumnHeaders.size(), 
metaData.getColumnCount());
+        for (int i = 0; i < showTablesColumnHeaders.size(); i++) {
+          assertEquals(
+              showTablesColumnHeaders.get(i).getColumnName(), 
metaData.getColumnName(i + 1));
+        }
+        while (resultSet.next()) {
+          assertEquals(tableNames[cnt], resultSet.getString(1));
+          assertEquals(ttls[cnt], resultSet.getInt(2));
+          cnt++;
+        }
+        assertEquals(tableNames.length, cnt);
+      }
+
+      // using SHOW tables from
+      try (ResultSet resultSet = statement.executeQuery("SHOW tables from 
test1")) {
+        int cnt = 0;
+        ResultSetMetaData metaData = resultSet.getMetaData();
+        assertEquals(showTablesColumnHeaders.size(), 
metaData.getColumnCount());
+        for (int i = 0; i < showTablesColumnHeaders.size(); i++) {
+          assertEquals(
+              showTablesColumnHeaders.get(i).getColumnName(), 
metaData.getColumnName(i + 1));
+        }
+        while (resultSet.next()) {
+          assertEquals(tableNames[cnt], resultSet.getString(1));
+          assertEquals(ttls[cnt], resultSet.getInt(2));
+          cnt++;
+        }
+        assertEquals(tableNames.length, cnt);
+      }
+
+      // show tables from a non-exist database
+      try {
+        statement.executeQuery("SHOW tables from test3");
+      } catch (SQLException e) {
+        assertEquals("500: Database test3 doesn't exists.", e.getMessage());
+      }
+
+      // describe
+      try {
+        statement.executeQuery("describe table1");
+      } catch (SQLException e) {
+        assertEquals("550: Table test2.table1 not exists.", e.getMessage());
+      }
+
+      String[] columnNames =
+          new String[] {
+            "Time", "region_id", "plant_id", "device_id", "model", 
"temperature", "humidity"
+          };
+      String[] dataTypes =
+          new String[] {"INT64", "STRING", "STRING", "STRING", "STRING", 
"FLOAT", "DOUBLE"};
+      String[] categories =
+          new String[] {"TIME", "ID", "ID", "ID", "ATTRIBUTE", "MEASUREMENT", 
"MEASUREMENT"};
+
+      try (ResultSet resultSet = statement.executeQuery("describe 
test1.table1")) {
+        int cnt = 0;
+        ResultSetMetaData metaData = resultSet.getMetaData();
+        assertEquals(describeTableColumnHeaders.size(), 
metaData.getColumnCount());
+        for (int i = 0; i < describeTableColumnHeaders.size(); i++) {
+          assertEquals(
+              describeTableColumnHeaders.get(i).getColumnName(), 
metaData.getColumnName(i + 1));
+        }
+        while (resultSet.next()) {
+          assertEquals(columnNames[cnt], resultSet.getString(1));
+          assertEquals(dataTypes[cnt], resultSet.getString(2));
+          assertEquals(categories[cnt], resultSet.getString(3));
+          cnt++;
+        }
+        assertEquals(columnNames.length, cnt);
+      }
+
+      columnNames = new String[] {"Time", "region_id", "plant_id", "color", 
"temperature", "speed"};
+      dataTypes = new String[] {"INT64", "STRING", "STRING", "STRING", 
"FLOAT", "DOUBLE"};
+      categories = new String[] {"TIME", "ID", "ID", "ATTRIBUTE", 
"MEASUREMENT", "MEASUREMENT"};
+
+      try (ResultSet resultSet = statement.executeQuery("desc table2")) {
+        int cnt = 0;
+        ResultSetMetaData metaData = resultSet.getMetaData();
+        assertEquals(describeTableColumnHeaders.size(), 
metaData.getColumnCount());
+        for (int i = 0; i < describeTableColumnHeaders.size(); i++) {
+          assertEquals(
+              describeTableColumnHeaders.get(i).getColumnName(), 
metaData.getColumnName(i + 1));
+        }
+        while (resultSet.next()) {
+          assertEquals(columnNames[cnt], resultSet.getString(1));
+          assertEquals(dataTypes[cnt], resultSet.getString(2));
+          assertEquals(categories[cnt], resultSet.getString(3));
+          cnt++;
+        }
+        assertEquals(columnNames.length, cnt);
+      }
+
+      try {
+        statement.executeQuery("describe test3.table3");
+      } catch (SQLException e) {
+        assertEquals("550: Table test3.table3 not exists.", e.getMessage());
+      }
+
+    } catch (SQLException e) {
+      e.printStackTrace();
+      fail(e.getMessage());
+    }
+  }
 }
diff --git 
a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/client/async/CnToDnInternalServiceAsyncRequestManager.java
 
b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/client/async/CnToDnInternalServiceAsyncRequestManager.java
index 8f3e7c720fc..020cb503cce 100644
--- 
a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/client/async/CnToDnInternalServiceAsyncRequestManager.java
+++ 
b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/client/async/CnToDnInternalServiceAsyncRequestManager.java
@@ -82,6 +82,7 @@ import org.apache.iotdb.mpp.rpc.thrift.TResetPeerListReq;
 import org.apache.iotdb.mpp.rpc.thrift.TRollbackSchemaBlackListReq;
 import org.apache.iotdb.mpp.rpc.thrift.TRollbackSchemaBlackListWithTemplateReq;
 import org.apache.iotdb.mpp.rpc.thrift.TRollbackViewSchemaBlackListReq;
+import org.apache.iotdb.mpp.rpc.thrift.TUpdateTableReq;
 import org.apache.iotdb.mpp.rpc.thrift.TUpdateTemplateReq;
 import org.apache.iotdb.mpp.rpc.thrift.TUpdateTriggerLocationReq;
 
@@ -350,6 +351,10 @@ public class CnToDnInternalServiceAsyncRequestManager
         CnToDnRequestType.TEST_CONNECTION,
         (req, client, handler) ->
             client.testConnectionEmptyRPC((DataNodeTSStatusRPCHandler) 
handler));
+    actionMapBuilder.put(
+        CnToDnRequestType.UPDATE_TABLE,
+        (req, client, handler) ->
+            client.updateTable((TUpdateTableReq) req, 
(DataNodeTSStatusRPCHandler) handler));
   }
 
   @Override
diff --git 
a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/impl/schema/table/CreateTableProcedure.java
 
b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/impl/schema/table/CreateTableProcedure.java
index 29dade50ca4..f3b48bb544e 100644
--- 
a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/impl/schema/table/CreateTableProcedure.java
+++ 
b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/impl/schema/table/CreateTableProcedure.java
@@ -23,7 +23,6 @@ import org.apache.iotdb.common.rpc.thrift.TConsensusGroupId;
 import org.apache.iotdb.common.rpc.thrift.TDataNodeLocation;
 import org.apache.iotdb.common.rpc.thrift.TRegionReplicaSet;
 import org.apache.iotdb.common.rpc.thrift.TSStatus;
-import org.apache.iotdb.commons.exception.IllegalPathException;
 import org.apache.iotdb.commons.exception.IoTDBException;
 import org.apache.iotdb.commons.exception.MetadataException;
 import org.apache.iotdb.commons.path.PartialPath;
@@ -66,7 +65,6 @@ import java.util.Objects;
 import java.util.Set;
 
 import static 
org.apache.iotdb.commons.conf.IoTDBConstant.MULTI_LEVEL_PATH_WILDCARD;
-import static org.apache.iotdb.commons.conf.IoTDBConstant.PATH_SEPARATOR;
 import static org.apache.iotdb.commons.schema.SchemaConstant.ROOT;
 
 public class CreateTableProcedure
@@ -177,12 +175,12 @@ public class CreateTableProcedure
     DataOutputStream dataOutputStream = new 
DataOutputStream(byteArrayOutputStream);
     PartialPath path = null;
     try {
-      path =
-          new PartialPath(ROOT + PATH_SEPARATOR + database + PATH_SEPARATOR + 
table.getTableName());
+      path = new PartialPath(new String[] {ROOT, database, 
table.getTableName()});
       patternTree.appendPathPattern(path);
       
patternTree.appendPathPattern(path.concatNode(MULTI_LEVEL_PATH_WILDCARD));
       patternTree.serialize(dataOutputStream);
-    } catch (IllegalPathException | IOException ignored) {
+    } catch (IOException e) {
+      LOGGER.warn("failed to serialize request for table {}.{}", database, 
table.getTableName(), e);
     }
     ByteBuffer patternTreeBytes = 
ByteBuffer.wrap(byteArrayOutputStream.toByteArray());
 
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/TableConfigTaskVisitor.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/TableConfigTaskVisitor.java
index 657512ef824..f1dc7ba7403 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/TableConfigTaskVisitor.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/TableConfigTaskVisitor.java
@@ -45,7 +45,10 @@ import 
org.apache.iotdb.db.queryengine.plan.relational.sql.ast.DataType;
 import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.DescribeTable;
 import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.DropDB;
 import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.DropTable;
+import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.Expression;
+import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.LongLiteral;
 import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.Node;
+import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.Property;
 import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.ShowDB;
 import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.ShowTables;
 import org.apache.iotdb.db.queryengine.plan.relational.sql.ast.Use;
@@ -54,12 +57,27 @@ import 
org.apache.iotdb.db.queryengine.plan.relational.type.TypeNotFoundExceptio
 import org.apache.tsfile.common.conf.TSFileDescriptor;
 import org.apache.tsfile.enums.TSDataType;
 
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Set;
+
+import static 
org.apache.iotdb.db.queryengine.common.header.ColumnHeaderConstant.COLUMN_TTL;
 import static 
org.apache.iotdb.db.queryengine.plan.relational.type.InternalTypeManager.getTSDataType;
 import static 
org.apache.iotdb.db.queryengine.plan.relational.type.TypeSignatureTranslator.toTypeSignature;
 import static 
org.apache.iotdb.db.utils.EncodingInferenceUtils.getDefaultEncoding;
 
 public class TableConfigTaskVisitor extends AstVisitor<IConfigTask, 
MPPQueryContext> {
 
+  private static final String DATABASE_NOT_SPECIFIED = "database is not 
specified";
+
+  private static final Set<String> TABLE_ALLOWED_PROPERTIES = new HashSet<>();
+
+  static {
+    TABLE_ALLOWED_PROPERTIES.add(COLUMN_TTL.toLowerCase(Locale.ENGLISH));
+  }
+
   private final IClientSession clientSession;
 
   private final Metadata metadata;
@@ -107,9 +125,23 @@ public class TableConfigTaskVisitor extends 
AstVisitor<IConfigTask, MPPQueryCont
       database = node.getName().getPrefix().get().toString();
     }
     if (database == null) {
-      throw new SemanticException("unknown database");
+      throw new SemanticException(DATABASE_NOT_SPECIFIED);
     }
     TsTable table = new TsTable(node.getName().getSuffix());
+    Map<String, String> map = new HashMap<>();
+    for (Property property : node.getProperties()) {
+      String key = property.getName().getValue().toLowerCase(Locale.ENGLISH);
+      if (TABLE_ALLOWED_PROPERTIES.contains(key) && 
!property.isSetToDefault()) {
+        Expression value = property.getNonDefaultValue();
+        if (!(value instanceof LongLiteral)) {
+          throw new SemanticException(
+              "TTL' value must be a LongLiteral, but now is: " + 
value.toString());
+        }
+        map.put(key, String.valueOf(((LongLiteral) value).getParsedValue()));
+      }
+    }
+    table.setProps(map);
+
     for (ColumnDefinition columnDefinition : node.getElements()) {
       TsTableColumnCategory category = columnDefinition.getColumnCategory();
       String columnName = columnDefinition.getName().getValue();
@@ -120,9 +152,17 @@ public class TableConfigTaskVisitor extends 
AstVisitor<IConfigTask, MPPQueryCont
       TSDataType dataType = getDataType(columnDefinition.getType());
       switch (category) {
         case ID:
+          if (!TSDataType.STRING.equals(dataType)) {
+            throw new SemanticException(
+                "DataType of ID Column should only be STRING, current is " + 
dataType);
+          }
           table.addColumnSchema(new IdColumnSchema(columnName, dataType));
           break;
         case ATTRIBUTE:
+          if (!TSDataType.STRING.equals(dataType)) {
+            throw new SemanticException(
+                "DataType of ATTRIBUTE Column should only be STRING, current 
is " + dataType);
+          }
           table.addColumnSchema(new AttributeColumnSchema(columnName, 
dataType));
           break;
         case TIME:
@@ -163,7 +203,7 @@ public class TableConfigTaskVisitor extends 
AstVisitor<IConfigTask, MPPQueryCont
       database = node.getDbName().get().toString();
     }
     if (database == null) {
-      throw new SemanticException("unknown database");
+      throw new SemanticException(DATABASE_NOT_SPECIFIED);
     }
     return new ShowTablesTask(database);
   }
@@ -176,7 +216,7 @@ public class TableConfigTaskVisitor extends 
AstVisitor<IConfigTask, MPPQueryCont
       database = node.getTable().getPrefix().get().toString();
     }
     if (database == null) {
-      throw new SemanticException("unknown database");
+      throw new SemanticException(DATABASE_NOT_SPECIFIED);
     }
     return new DescribeTableTask(database, node.getTable().getSuffix());
   }
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/executor/ClusterConfigTaskExecutor.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/executor/ClusterConfigTaskExecutor.java
index ef900fddafe..aea0ab14e5e 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/executor/ClusterConfigTaskExecutor.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/executor/ClusterConfigTaskExecutor.java
@@ -268,6 +268,7 @@ import java.util.Arrays;
 import java.util.Collections;
 import java.util.List;
 import java.util.Map;
+import java.util.Optional;
 import java.util.TreeMap;
 import java.util.stream.Collectors;
 
@@ -2933,8 +2934,16 @@ public class ClusterConfigTaskExecutor implements 
IConfigTaskExecutor {
   @Override
   public SettableFuture<ConfigTaskResult> showTables(String database) {
     SettableFuture<ConfigTaskResult> future = SettableFuture.create();
-    List<TsTable> tableList = 
DataNodeTableCache.getInstance().getTables(database);
-    ShowTablesTask.buildTsBlock(tableList, future);
+
+    Optional<List<TsTable>> tableList = 
DataNodeTableCache.getInstance().getTables(database);
+    if (tableList.isPresent()) {
+      ShowTablesTask.buildTsBlock(tableList.get(), future);
+    } else {
+      future.setException(
+          new IoTDBException(
+              String.format("Database %s doesn't exists.", database),
+              TSStatusCode.DATABASE_NOT_EXIST.getStatusCode()));
+    }
     return future;
   }
 
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/metadata/relational/AlterTableAddColumnTask.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/metadata/relational/AlterTableAddColumnTask.java
index febd54cc8a7..17058e6f6c0 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/metadata/relational/AlterTableAddColumnTask.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/metadata/relational/AlterTableAddColumnTask.java
@@ -33,7 +33,7 @@ import 
org.apache.iotdb.db.queryengine.plan.relational.type.InternalTypeManager;
 import com.google.common.util.concurrent.ListenableFuture;
 import org.apache.tsfile.common.conf.TSFileDescriptor;
 import org.apache.tsfile.enums.TSDataType;
-import org.apache.tsfile.read.common.type.BinaryType;
+import org.apache.tsfile.read.common.type.StringType;
 
 import java.util.ArrayList;
 import java.util.List;
@@ -69,16 +69,16 @@ public class AlterTableAddColumnTask implements IConfigTask 
{
     for (ColumnSchema inputColumn : inputColumnList) {
       switch (inputColumn.getColumnCategory()) {
         case ID:
-          if (!inputColumn.getType().equals(BinaryType.TEXT)) {
-            throw new SemanticException("Id column only support data type 
TEXT.");
+          if (!inputColumn.getType().equals(StringType.STRING)) {
+            throw new SemanticException("Id column only support data type 
STRING.");
           }
-          columnSchemaList.add(new IdColumnSchema(inputColumn.getName(), 
TSDataType.TEXT));
+          columnSchemaList.add(new IdColumnSchema(inputColumn.getName(), 
TSDataType.STRING));
           break;
         case ATTRIBUTE:
-          if (!inputColumn.getType().equals(BinaryType.TEXT)) {
-            throw new SemanticException("Attribute column only support data 
type TEXT.");
+          if (!inputColumn.getType().equals(StringType.STRING)) {
+            throw new SemanticException("Attribute column only support data 
type STRING.");
           }
-          columnSchemaList.add(new 
AttributeColumnSchema(inputColumn.getName(), TSDataType.TEXT));
+          columnSchemaList.add(new 
AttributeColumnSchema(inputColumn.getName(), TSDataType.STRING));
           break;
         case MEASUREMENT:
           TSDataType dataType = 
InternalTypeManager.getTSDataType(inputColumn.getType());
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/metadata/relational/ShowTablesTask.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/metadata/relational/ShowTablesTask.java
index 65dbe9adfd0..fc7c1e491de 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/metadata/relational/ShowTablesTask.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/metadata/relational/ShowTablesTask.java
@@ -37,8 +37,11 @@ import org.apache.tsfile.read.common.block.TsBlockBuilder;
 import org.apache.tsfile.utils.Binary;
 
 import java.util.List;
+import java.util.Locale;
 import java.util.stream.Collectors;
 
+import static 
org.apache.iotdb.db.queryengine.common.header.ColumnHeaderConstant.COLUMN_TTL;
+
 public class ShowTablesTask implements IConfigTask {
 
   private final String database;
@@ -67,7 +70,9 @@ public class ShowTablesTask implements IConfigTask {
       builder
           .getColumnBuilder(0)
           .writeBinary(new Binary(table.getTableName(), 
TSFileConfig.STRING_CHARSET));
-      builder.getColumnBuilder(1).appendNull();
+      builder
+          .getColumnBuilder(1)
+          
.writeLong(Long.parseLong(table.getPropValue(COLUMN_TTL.toLowerCase(Locale.ENGLISH))));
       builder.declarePosition();
     }
 
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/metadata/TableMetadataImpl.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/metadata/TableMetadataImpl.java
index dcc5f671687..b017f8d3d72 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/metadata/TableMetadataImpl.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/metadata/TableMetadataImpl.java
@@ -169,7 +169,7 @@ public class TableMetadataImpl implements Metadata {
         throw new SemanticException(
             "Scalar function: "
                 + functionName.toLowerCase(Locale.ENGLISH)
-                + " only supports text data type.");
+                + " only supports text or string data type.");
       }
       return argumentTypes.get(0);
     } else if 
(BuiltinScalarFunction.SUBSTRING.getFunctionName().equalsIgnoreCase(functionName))
 {
@@ -183,7 +183,7 @@ public class TableMetadataImpl implements Metadata {
         throw new SemanticException(
             "Scalar function"
                 + functionName.toLowerCase(Locale.ENGLISH)
-                + " only supports text data type.");
+                + " only supports text or string data type.");
       }
       return argumentTypes.get(0);
     }
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/table/DataNodeTableCache.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/table/DataNodeTableCache.java
index d1f4d75ba31..ffe32fd0870 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/table/DataNodeTableCache.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/table/DataNodeTableCache.java
@@ -29,9 +29,9 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import java.util.ArrayList;
-import java.util.Collections;
 import java.util.List;
 import java.util.Map;
+import java.util.Optional;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.locks.ReentrantReadWriteLock;
 
@@ -222,13 +222,11 @@ public class DataNodeTableCache implements ITableCache {
     }
   }
 
-  public List<TsTable> getTables(String database) {
+  public Optional<List<TsTable>> getTables(String database) {
     readWriteLock.readLock().lock();
     try {
-      if (databaseTableMap.containsKey(database)) {
-        return new ArrayList<>(databaseTableMap.get(database).values());
-      }
-      return Collections.emptyList();
+      Map<String, TsTable> tableMap = databaseTableMap.get(database);
+      return tableMap != null ? Optional.of(new 
ArrayList<>(tableMap.values())) : Optional.empty();
     } finally {
       readWriteLock.readLock().unlock();
     }
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/utils/ErrorHandlingUtils.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/utils/ErrorHandlingUtils.java
index e698ba8487e..34fd8b96bb0 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/utils/ErrorHandlingUtils.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/utils/ErrorHandlingUtils.java
@@ -97,8 +97,10 @@ public class ErrorHandlingUtils {
       if (status.getCode() != 
TSStatusCode.STORAGE_ENGINE_NOT_READY.getStatusCode()) {
         String message =
             String.format(
-                "Status code: %s, Query Statement: %s failed", 
status.getCode(), operation);
-        if (status.getCode() == TSStatusCode.SQL_PARSE_ERROR.getStatusCode()) {
+                "Status code: %s, Query Statement: %s failed because %s",
+                status.getCode(), operation, status.getMessage());
+        if (status.getCode() == TSStatusCode.SQL_PARSE_ERROR.getStatusCode()
+            || status.getCode() == 
TSStatusCode.SEMANTIC_ERROR.getStatusCode()) {
           LOGGER.warn(message);
         } else {
           LOGGER.warn(message, e);
diff --git 
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/TestMatadata.java
 
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/TestMatadata.java
index faa5509c9c2..0584cf62dfb 100644
--- 
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/TestMatadata.java
+++ 
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/TestMatadata.java
@@ -43,7 +43,7 @@ import org.apache.iotdb.mpp.rpc.thrift.TRegionRouteReq;
 
 import org.apache.tsfile.file.metadata.IDeviceID;
 import org.apache.tsfile.file.metadata.StringArrayDeviceID;
-import org.apache.tsfile.read.common.type.BinaryType;
+import org.apache.tsfile.read.common.type.StringType;
 import org.apache.tsfile.read.common.type.Type;
 
 import java.util.Arrays;
@@ -77,11 +77,11 @@ public class TestMatadata implements Metadata {
   private static final String S2 = "s2";
   private static final String S3 = "s3";
   private static final ColumnMetadata TIME_CM = new ColumnMetadata(TIME, 
INT64);
-  private static final ColumnMetadata TAG1_CM = new ColumnMetadata(TAG1, 
BinaryType.TEXT);
-  private static final ColumnMetadata TAG2_CM = new ColumnMetadata(TAG2, 
BinaryType.TEXT);
-  private static final ColumnMetadata TAG3_CM = new ColumnMetadata(TAG3, 
BinaryType.TEXT);
-  private static final ColumnMetadata ATTR1_CM = new ColumnMetadata(ATTR1, 
BinaryType.TEXT);
-  private static final ColumnMetadata ATTR2_CM = new ColumnMetadata(ATTR2, 
BinaryType.TEXT);
+  private static final ColumnMetadata TAG1_CM = new ColumnMetadata(TAG1, 
StringType.STRING);
+  private static final ColumnMetadata TAG2_CM = new ColumnMetadata(TAG2, 
StringType.STRING);
+  private static final ColumnMetadata TAG3_CM = new ColumnMetadata(TAG3, 
StringType.STRING);
+  private static final ColumnMetadata ATTR1_CM = new ColumnMetadata(ATTR1, 
StringType.STRING);
+  private static final ColumnMetadata ATTR2_CM = new ColumnMetadata(ATTR2, 
StringType.STRING);
   private static final ColumnMetadata S1_CM = new ColumnMetadata(S1, INT64);
   private static final ColumnMetadata S2_CM = new ColumnMetadata(S2, INT64);
   private static final ColumnMetadata S3_CM = new ColumnMetadata(S3, DOUBLE);
diff --git 
a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/schema/table/TsTable.java
 
b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/schema/table/TsTable.java
index dd0d4662cc7..919f96e1708 100644
--- 
a/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/schema/table/TsTable.java
+++ 
b/iotdb-core/node-commons/src/main/java/org/apache/iotdb/commons/schema/table/TsTable.java
@@ -147,6 +147,10 @@ public class TsTable {
     return table;
   }
 
+  public void setProps(Map<String, String> props) {
+    this.props = props;
+  }
+
   @Override
   public boolean equals(Object o) {
     return super.equals(o);

Reply via email to