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

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


The following commit(s) were added to refs/heads/master by this push:
     new 82a1dc3990a Fixed the bug that set table properties ttl='inf' cannot 
be parsed && ttl='INF' does not take effect && set to default may generate NPE 
on dataNodes && some minor bugs of delete devices && Enable "inf" in 
databaseSchema / show ttl for databases in table model / table default ttl = 
database ttl (#14147)
82a1dc3990a is described below

commit 82a1dc3990ac1cafad8d1e8002adba432ee1945f
Author: Caideyipi <[email protected]>
AuthorDate: Thu Nov 21 11:39:49 2024 +0800

    Fixed the bug that set table properties ttl='inf' cannot be parsed && 
ttl='INF' does not take effect && set to default may generate NPE on dataNodes 
&& some minor bugs of delete devices && Enable "inf" in databaseSchema / show 
ttl for databases in table model / table default ttl = database ttl (#14147)
---
 .../it/tablemodel/IoTDBTablePatternFormatIT.java   |  2 +-
 .../relational/it/schema/IoTDBDatabaseIT.java      | 30 +++++++++-------
 .../iotdb/relational/it/schema/IoTDBTableIT.java   | 30 +++++++++++++---
 .../manager/schema/ClusterSchemaManager.java       |  7 +++-
 .../persistence/schema/ClusterSchemaInfo.java      |  9 ++---
 .../confignode/persistence/schema/ConfigMTree.java | 10 +++++-
 .../impl/schema/table/CreateTableProcedure.java    |  9 ++++-
 .../impl/schema/table/DeleteDevicesProcedure.java  | 20 +++++------
 .../common/header/ColumnHeaderConstant.java        |  2 ++
 .../execution/config/TableConfigTaskVisitor.java   | 40 ++++++++++++++++------
 .../config/metadata/relational/ShowDBTask.java     | 35 +++++++++++++++----
 .../relational/analyzer/StatementAnalyzer.java     |  9 +++--
 .../TableModelCompactionWithTTLTest.java           |  3 +-
 .../apache/iotdb/commons/schema/table/TsTable.java | 20 +++--------
 14 files changed, 150 insertions(+), 76 deletions(-)

diff --git 
a/integration-test/src/test/java/org/apache/iotdb/pipe/it/tablemodel/IoTDBTablePatternFormatIT.java
 
b/integration-test/src/test/java/org/apache/iotdb/pipe/it/tablemodel/IoTDBTablePatternFormatIT.java
index 62b66aba5fe..fcacd8cce06 100644
--- 
a/integration-test/src/test/java/org/apache/iotdb/pipe/it/tablemodel/IoTDBTablePatternFormatIT.java
+++ 
b/integration-test/src/test/java/org/apache/iotdb/pipe/it/tablemodel/IoTDBTablePatternFormatIT.java
@@ -564,7 +564,7 @@ public class IoTDBTablePatternFormatIT extends 
AbstractPipeTableModelTestIT {
       TestUtils.assertDataEventuallyOnEnv(
           receiverEnv,
           "show databases",
-          
"Database,SchemaReplicationFactor,DataReplicationFactor,TimePartitionInterval,",
+          
"Database,TTL(ms),SchemaReplicationFactor,DataReplicationFactor,TimePartitionInterval,",
           Collections.emptySet(),
           null);
     }
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 1c8683f6c32..098054e09b7 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
@@ -67,7 +67,7 @@ public class IoTDBDatabaseIT {
         final Statement statement = connection.createStatement()) {
 
       // create
-      statement.execute("create database test");
+      statement.execute("create database test with (ttl='INF')");
 
       // create duplicated database without IF NOT EXISTS
       try {
@@ -81,6 +81,7 @@ public class IoTDBDatabaseIT {
       statement.execute("create database IF NOT EXISTS test");
 
       String[] databaseNames = new String[] {"test"};
+      String[] TTLs = new String[] {"INF"};
       int[] schemaReplicaFactors = new int[] {1};
       int[] dataReplicaFactors = new int[] {1};
       int[] timePartitionInterval = new int[] {604800000};
@@ -96,9 +97,10 @@ public class IoTDBDatabaseIT {
         }
         while (resultSet.next()) {
           assertEquals(databaseNames[cnt], resultSet.getString(1));
-          assertEquals(schemaReplicaFactors[cnt], resultSet.getInt(2));
-          assertEquals(dataReplicaFactors[cnt], resultSet.getInt(3));
-          assertEquals(timePartitionInterval[cnt], resultSet.getLong(4));
+          assertEquals(TTLs[cnt], resultSet.getString(2));
+          assertEquals(schemaReplicaFactors[cnt], resultSet.getInt(3));
+          assertEquals(dataReplicaFactors[cnt], resultSet.getInt(4));
+          assertEquals(timePartitionInterval[cnt], resultSet.getLong(5));
           cnt++;
         }
         assertEquals(databaseNames.length, cnt);
@@ -115,10 +117,11 @@ public class IoTDBDatabaseIT {
         }
         while (resultSet.next()) {
           assertEquals(databaseNames[cnt], resultSet.getString(1));
-          assertEquals(schemaReplicaFactors[cnt], resultSet.getInt(2));
-          assertEquals(dataReplicaFactors[cnt], resultSet.getInt(3));
-          assertEquals(timePartitionInterval[cnt], resultSet.getLong(4));
-          assertEquals(model[cnt], resultSet.getString(5));
+          assertEquals(TTLs[cnt], resultSet.getString(2));
+          assertEquals(schemaReplicaFactors[cnt], resultSet.getInt(3));
+          assertEquals(dataReplicaFactors[cnt], resultSet.getInt(4));
+          assertEquals(timePartitionInterval[cnt], resultSet.getLong(5));
+          assertEquals(model[cnt], resultSet.getString(6));
           cnt++;
         }
         assertEquals(databaseNames.length, cnt);
@@ -154,9 +157,9 @@ public class IoTDBDatabaseIT {
 
       // Test create database with properties
       statement.execute(
-          "create database test_prop with (schema_replication_factor=DEFAULT, 
data_replication_factor=3, time_partition_interval=100000)");
-
+          "create database test_prop with (ttl=300, 
schema_replication_factor=DEFAULT, data_replication_factor=3, 
time_partition_interval=100000)");
       databaseNames = new String[] {"test_prop"};
+      TTLs = new String[] {"300"};
       dataReplicaFactors = new int[] {3};
       timePartitionInterval = new int[] {100000};
 
@@ -170,9 +173,10 @@ public class IoTDBDatabaseIT {
         }
         while (resultSet.next()) {
           assertEquals(databaseNames[cnt], resultSet.getString(1));
-          assertEquals(schemaReplicaFactors[cnt], resultSet.getInt(2));
-          assertEquals(dataReplicaFactors[cnt], resultSet.getInt(3));
-          assertEquals(timePartitionInterval[cnt], resultSet.getLong(4));
+          assertEquals(TTLs[cnt], resultSet.getString(2));
+          assertEquals(schemaReplicaFactors[cnt], resultSet.getInt(3));
+          assertEquals(dataReplicaFactors[cnt], resultSet.getInt(4));
+          assertEquals(timePartitionInterval[cnt], resultSet.getLong(5));
           cnt++;
         }
         assertEquals(databaseNames.length, cnt);
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 3931000846c..e3470ce8c79 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
@@ -68,7 +68,7 @@ public class IoTDBTableIT {
         final Statement statement = connection.createStatement()) {
 
       statement.execute("create database test1");
-      statement.execute("create database test2");
+      statement.execute("create database test2 with (ttl=300)");
 
       // should specify database before create table
       try {
@@ -287,8 +287,11 @@ public class IoTDBTableIT {
 
       statement.execute("alter table if exists table3 add column speed DOUBLE 
MEASUREMENT");
 
-      tableNames = new String[] {"table2"};
-      ttls = new String[] {"6600000"};
+      // Test create table with only time column
+      statement.execute("create table table3()");
+
+      tableNames = new String[] {"table3", "table2"};
+      ttls = new String[] {"300", "6600000"};
 
       // show tables from current database
       try (final ResultSet resultSet = statement.executeQuery("SHOW tables")) {
@@ -307,8 +310,25 @@ public class IoTDBTableIT {
         assertEquals(tableNames.length, cnt);
       }
 
-      // Test create table with only time column
-      statement.execute("create table table3()");
+      statement.execute("alter table table3 set properties ttl=300");
+      statement.execute("alter table table3 set properties ttl=DEFAULT");
+
+      // The table3's ttl shall be also 300
+      try (final 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.getString(2));
+          cnt++;
+        }
+        assertEquals(tableNames.length, cnt);
+      }
 
       // show tables from a non-exist database
       try {
diff --git 
a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/schema/ClusterSchemaManager.java
 
b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/schema/ClusterSchemaManager.java
index 46f71275080..d282bbcfd5a 100644
--- 
a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/schema/ClusterSchemaManager.java
+++ 
b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/schema/ClusterSchemaManager.java
@@ -360,6 +360,7 @@ public class ClusterSchemaManager {
       final String database = databaseSchema.getName();
       final TDatabaseInfo databaseInfo = new TDatabaseInfo();
       databaseInfo.setName(database);
+      databaseInfo.setTTL(databaseSchema.isSetTTL() ? databaseSchema.getTTL() 
: Long.MAX_VALUE);
       
databaseInfo.setSchemaReplicationFactor(databaseSchema.getSchemaReplicationFactor());
       
databaseInfo.setDataReplicationFactor(databaseSchema.getDataReplicationFactor());
       
databaseInfo.setTimePartitionOrigin(databaseSchema.getTimePartitionOrigin());
@@ -1321,7 +1322,11 @@ public class ClusterSchemaManager {
     updatedProperties.forEach(
         (k, v) -> {
           originalProperties.put(k, 
originalTable.getPropValue(k).orElse(null));
-          updatedTable.addProp(k, v);
+          if (Objects.nonNull(v)) {
+            updatedTable.addProp(k, v);
+          } else {
+            updatedTable.removeProp(k);
+          }
         });
 
     return new Pair<>(RpcUtils.SUCCESS_STATUS, updatedTable);
diff --git 
a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/persistence/schema/ClusterSchemaInfo.java
 
b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/persistence/schema/ClusterSchemaInfo.java
index f6828ae4d3f..c78feaef2bc 100644
--- 
a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/persistence/schema/ClusterSchemaInfo.java
+++ 
b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/persistence/schema/ClusterSchemaInfo.java
@@ -101,7 +101,6 @@ import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
-import java.util.Locale;
 import java.util.Map;
 import java.util.Optional;
 import java.util.Set;
@@ -1125,9 +1124,7 @@ public class ClusterSchemaInfo implements 
SnapshotProcessor {
                         final TTableInfo info =
                             new TTableInfo(
                                 pair.getLeft().getTableName(),
-                                pair.getLeft()
-                                    
.getPropValue(TTL_PROPERTY.toLowerCase(Locale.ENGLISH))
-                                    .orElse(TTL_INFINITE));
+                                
pair.getLeft().getPropValue(TTL_PROPERTY).orElse(TTL_INFINITE));
                         info.setState(pair.getRight().ordinal());
                         return info;
                       })
@@ -1140,9 +1137,7 @@ public class ClusterSchemaInfo implements 
SnapshotProcessor {
                       tsTable ->
                           new TTableInfo(
                               tsTable.getTableName(),
-                              tsTable
-                                  
.getPropValue(TTL_PROPERTY.toLowerCase(Locale.ENGLISH))
-                                  .orElse(TTL_INFINITE)))
+                              
tsTable.getPropValue(TTL_PROPERTY).orElse(TTL_INFINITE)))
                   .collect(Collectors.toList()));
     } catch (final MetadataException e) {
       return new ShowTableResp(
diff --git 
a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/persistence/schema/ConfigMTree.java
 
b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/persistence/schema/ConfigMTree.java
index a80e6c56c5e..c0fa6c98d94 100644
--- 
a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/persistence/schema/ConfigMTree.java
+++ 
b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/persistence/schema/ConfigMTree.java
@@ -816,11 +816,19 @@ public class ConfigMTree {
   public void setTableProperties(
       final PartialPath database, final String tableName, final Map<String, 
String> tableProperties)
       throws MetadataException {
-    final TsTable table = getTable(database, tableName);
+    final IConfigMNode databaseNode = 
getDatabaseNodeByDatabasePath(database).getAsMNode();
+    if (!databaseNode.hasChild(tableName)) {
+      throw new TableNotExistsException(
+          database.getFullPath().substring(ROOT.length() + 1), tableName);
+    }
+    final TsTable table = ((ConfigTableNode) 
databaseNode.getChild(tableName)).getTable();
     tableProperties.forEach(
         (k, v) -> {
           if (Objects.nonNull(v)) {
             table.addProp(k, v);
+          } else if (k.equals(TsTable.TTL_PROPERTY)
+              && databaseNode.getDatabaseSchema().isSetTTL()) {
+            table.addProp(k, 
String.valueOf(databaseNode.getDatabaseSchema().getTTL()));
           } else {
             table.removeProp(k);
           }
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 5b176c00501..dedd9349d3a 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
@@ -32,6 +32,7 @@ import 
org.apache.iotdb.confignode.client.async.CnToDnAsyncRequestType;
 import 
org.apache.iotdb.confignode.consensus.request.write.table.CommitCreateTablePlan;
 import 
org.apache.iotdb.confignode.consensus.request.write.table.PreCreateTablePlan;
 import 
org.apache.iotdb.confignode.consensus.request.write.table.RollbackCreateTablePlan;
+import org.apache.iotdb.confignode.exception.DatabaseNotExistsException;
 import org.apache.iotdb.confignode.procedure.env.ConfigNodeProcedureEnv;
 import org.apache.iotdb.confignode.procedure.exception.ProcedureException;
 import 
org.apache.iotdb.confignode.procedure.exception.ProcedureSuspendedException;
@@ -41,6 +42,7 @@ import 
org.apache.iotdb.confignode.procedure.impl.schema.DataNodeRegionTaskExecu
 import org.apache.iotdb.confignode.procedure.impl.schema.SchemaUtils;
 import org.apache.iotdb.confignode.procedure.state.schema.CreateTableState;
 import org.apache.iotdb.confignode.procedure.store.ProcedureType;
+import org.apache.iotdb.confignode.rpc.thrift.TDatabaseSchema;
 import org.apache.iotdb.mpp.rpc.thrift.TCheckTimeSeriesExistenceReq;
 import org.apache.iotdb.mpp.rpc.thrift.TCheckTimeSeriesExistenceResp;
 import org.apache.iotdb.rpc.TSStatusCode;
@@ -141,9 +143,14 @@ public class CreateTableProcedure
                         database.substring(ROOT.length() + 1), 
table.getTableName()),
                     TABLE_ALREADY_EXISTS.getStatusCode())));
       } else {
+        final TDatabaseSchema schema =
+            
env.getConfigManager().getClusterSchemaManager().getDatabaseSchemaByName(database);
+        if (schema.isSetTTL() && 
!table.getPropValue(TsTable.TTL_PROPERTY).isPresent()) {
+          table.addProp(TsTable.TTL_PROPERTY, String.valueOf(schema.getTTL()));
+        }
         setNextState(CreateTableState.PRE_CREATE);
       }
-    } catch (final MetadataException e) {
+    } catch (final MetadataException | DatabaseNotExistsException e) {
       setFailure(new ProcedureException(e));
     }
   }
diff --git 
a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/impl/schema/table/DeleteDevicesProcedure.java
 
b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/impl/schema/table/DeleteDevicesProcedure.java
index 8d7dcee9933..fdb3a12b1d6 100644
--- 
a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/impl/schema/table/DeleteDevicesProcedure.java
+++ 
b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/impl/schema/table/DeleteDevicesProcedure.java
@@ -61,11 +61,12 @@ import java.util.Set;
 
 import static 
org.apache.iotdb.commons.conf.IoTDBConstant.MULTI_LEVEL_PATH_WILDCARD;
 import static org.apache.iotdb.commons.schema.SchemaConstant.ROOT;
+import static 
org.apache.iotdb.confignode.procedure.state.schema.DeleteDevicesState.CHECK_TABLE_EXISTENCE;
 import static 
org.apache.iotdb.confignode.procedure.state.schema.DeleteDevicesState.CLEAN_DATANODE_SCHEMA_CACHE;
 import static 
org.apache.iotdb.confignode.procedure.state.schema.DeleteDevicesState.CONSTRUCT_BLACK_LIST;
 import static 
org.apache.iotdb.confignode.procedure.state.schema.DeleteDevicesState.DELETE_DATA;
 import static 
org.apache.iotdb.confignode.procedure.state.schema.DeleteDevicesState.DELETE_DEVICE_SCHEMA;
-import static org.apache.iotdb.rpc.TSStatusCode.TABLE_ALREADY_EXISTS;
+import static org.apache.iotdb.rpc.TSStatusCode.TABLE_NOT_EXISTS;
 
 public class DeleteDevicesProcedure extends 
AbstractAlterOrDropTableProcedure<DeleteDevicesState> {
   private static final Logger LOGGER = 
LoggerFactory.getLogger(DeleteDevicesProcedure.class);
@@ -103,7 +104,7 @@ public class DeleteDevicesProcedure extends 
AbstractAlterOrDropTableProcedure<De
     try {
       switch (state) {
         case CHECK_TABLE_EXISTENCE:
-          LOGGER.info("Check the existence of table {}.{}", database, 
table.getTableName());
+          LOGGER.info("Check the existence of table {}.{}", database, 
tableName);
           checkTableExistence(env);
           break;
         case CONSTRUCT_BLACK_LIST:
@@ -133,24 +134,23 @@ public class DeleteDevicesProcedure extends 
AbstractAlterOrDropTableProcedure<De
       }
       return Flow.HAS_MORE_STATE;
     } finally {
-      LOGGER.info(
-          "DeleteTimeSeries-[{}] costs {}ms", state, 
(System.currentTimeMillis() - startTime));
+      LOGGER.info("DeleteDevices-[{}] costs {}ms", state, 
(System.currentTimeMillis() - startTime));
     }
   }
 
   private void checkTableExistence(final ConfigNodeProcedureEnv env) {
     try {
-      if (env.getConfigManager()
+      if (!env.getConfigManager()
           .getClusterSchemaManager()
-          .getTableIfExists(database, table.getTableName())
+          .getTableIfExists(database, tableName)
           .isPresent()) {
         setFailure(
             new ProcedureException(
                 new IoTDBException(
                     String.format(
-                        "Table '%s.%s' already exists.",
-                        database.substring(ROOT.length() + 1), 
table.getTableName()),
-                    TABLE_ALREADY_EXISTS.getStatusCode())));
+                        "Table '%s.%s' not exists.",
+                        database.substring(ROOT.length() + 1), tableName),
+                    TABLE_NOT_EXISTS.getStatusCode())));
       } else {
         setNextState(CONSTRUCT_BLACK_LIST);
       }
@@ -328,7 +328,7 @@ public class DeleteDevicesProcedure extends 
AbstractAlterOrDropTableProcedure<De
 
   @Override
   protected DeleteDevicesState getInitialState() {
-    return CONSTRUCT_BLACK_LIST;
+    return CHECK_TABLE_EXISTENCE;
   }
 
   @Override
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/common/header/ColumnHeaderConstant.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/common/header/ColumnHeaderConstant.java
index 70e03b9c70e..96454706b4b 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/common/header/ColumnHeaderConstant.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/common/header/ColumnHeaderConstant.java
@@ -545,6 +545,7 @@ public class ColumnHeaderConstant {
   public static final List<ColumnHeader> showDBColumnHeaders =
       ImmutableList.of(
           new ColumnHeader(DATABASE, TSDataType.TEXT),
+          new ColumnHeader(COLUMN_TTL, TSDataType.TEXT),
           new ColumnHeader(SCHEMA_REPLICATION_FACTOR, TSDataType.INT32),
           new ColumnHeader(DATA_REPLICATION_FACTOR, TSDataType.INT32),
           new ColumnHeader(TIME_PARTITION_INTERVAL, TSDataType.INT64));
@@ -552,6 +553,7 @@ public class ColumnHeaderConstant {
   public static final List<ColumnHeader> showDBDetailsColumnHeaders =
       ImmutableList.of(
           new ColumnHeader(DATABASE, TSDataType.TEXT),
+          new ColumnHeader(COLUMN_TTL, TSDataType.TEXT),
           new ColumnHeader(SCHEMA_REPLICATION_FACTOR, TSDataType.INT32),
           new ColumnHeader(DATA_REPLICATION_FACTOR, TSDataType.INT32),
           new ColumnHeader(TIME_PARTITION_INTERVAL, TSDataType.INT64),
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 ceb6489a3a2..e91984f17da 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
@@ -128,7 +128,9 @@ import 
org.apache.iotdb.db.queryengine.plan.statement.metadata.ShowRegionStateme
 import org.apache.iotdb.db.queryengine.plan.statement.sys.FlushStatement;
 import 
org.apache.iotdb.db.queryengine.plan.statement.sys.SetConfigurationStatement;
 
+import org.apache.tsfile.common.conf.TSFileConfig;
 import org.apache.tsfile.enums.TSDataType;
+import org.apache.tsfile.utils.Binary;
 import org.apache.tsfile.utils.Pair;
 
 import java.util.Collections;
@@ -137,9 +139,11 @@ import java.util.List;
 import java.util.Locale;
 import java.util.Map;
 import java.util.Objects;
+import java.util.Optional;
 
 import static 
org.apache.iotdb.commons.conf.IoTDBConstant.MAX_DATABASE_NAME_LENGTH;
-import static 
org.apache.iotdb.commons.schema.table.TsTable.TABLE_ALLOWED_PROPERTIES_2_DEFAULT_VALUE_MAP;
+import static org.apache.iotdb.commons.conf.IoTDBConstant.TTL_INFINITE;
+import static 
org.apache.iotdb.commons.schema.table.TsTable.TABLE_ALLOWED_PROPERTIES;
 import static org.apache.iotdb.commons.schema.table.TsTable.TTL_PROPERTY;
 import static 
org.apache.iotdb.db.queryengine.plan.execution.config.metadata.relational.CreateDBTask.DATA_REGION_GROUP_NUM_KEY;
 import static 
org.apache.iotdb.db.queryengine.plan.execution.config.metadata.relational.CreateDBTask.DATA_REPLICATION_FACTOR_KEY;
@@ -205,6 +209,14 @@ public class TableConfigTaskVisitor extends 
AstVisitor<IConfigTask, MPPQueryCont
 
       switch (key) {
         case TTL_KEY:
+          final Optional<String> strValue = 
parseStringFromLiteralIfBinary(value);
+          if (strValue.isPresent()) {
+            if (!strValue.get().equalsIgnoreCase(TTL_INFINITE)) {
+              throw new SemanticException(
+                  "ttl value must be 'INF' or a long literal, but now is: " + 
value);
+            }
+            break;
+          }
           schema.setTTL(parseLongFromLiteral(value, TTL_KEY));
           break;
         case SCHEMA_REPLICATION_FACTOR_KEY:
@@ -443,21 +455,20 @@ public class TableConfigTaskVisitor extends 
AstVisitor<IConfigTask, MPPQueryCont
     final Map<String, String> map = new HashMap<>();
     for (final Property property : propertyList) {
       final String key = 
property.getName().getValue().toLowerCase(Locale.ENGLISH);
-      if (TABLE_ALLOWED_PROPERTIES_2_DEFAULT_VALUE_MAP.containsKey(key)) {
+      if (TABLE_ALLOWED_PROPERTIES.contains(key)) {
         if (!property.isSetToDefault()) {
           final Expression value = property.getNonDefaultValue();
-          if (value instanceof Literal
-              && Objects.equals(
-                  ((Literal) value).getTsValue(),
-                  TABLE_ALLOWED_PROPERTIES_2_DEFAULT_VALUE_MAP.get(key))) {
-            // Ignore default values
+          final Optional<String> strValue = 
parseStringFromLiteralIfBinary(value);
+          if (strValue.isPresent()) {
+            if (!strValue.get().equalsIgnoreCase(TTL_INFINITE)) {
+              throw new SemanticException(
+                  "ttl value must be 'INF' or a long literal, but now is: " + 
value);
+            }
+            map.put(key, strValue.get());
             continue;
           }
           // TODO: support validation for other properties
-          map.put(
-              key,
-              String.valueOf(
-                  parseLongFromLiteral(value, 
TTL_PROPERTY.toLowerCase(Locale.ENGLISH))));
+          map.put(key, String.valueOf(parseLongFromLiteral(value, 
TTL_PROPERTY)));
         } else if (serializeDefault) {
           map.put(key, null);
         }
@@ -542,6 +553,13 @@ public class TableConfigTaskVisitor extends 
AstVisitor<IConfigTask, MPPQueryCont
     return new SetConfigurationTask(((SetConfigurationStatement) 
node.getInnerTreeStatement()));
   }
 
+  private Optional<String> parseStringFromLiteralIfBinary(final Object value) {
+    return value instanceof Literal && ((Literal) value).getTsValue() 
instanceof Binary
+        ? Optional.of(
+            ((Binary) ((Literal) 
value).getTsValue()).getStringValue(TSFileConfig.STRING_CHARSET))
+        : Optional.empty();
+  }
+
   private long parseLongFromLiteral(final Object value, final String name) {
     if (!(value instanceof LongLiteral)) {
       throw new SemanticException(
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/metadata/relational/ShowDBTask.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/metadata/relational/ShowDBTask.java
index 64580a97528..d0516a14dac 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/metadata/relational/ShowDBTask.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/execution/config/metadata/relational/ShowDBTask.java
@@ -19,6 +19,7 @@
 
 package 
org.apache.iotdb.db.queryengine.plan.execution.config.metadata.relational;
 
+import org.apache.iotdb.commons.conf.IoTDBConstant;
 import org.apache.iotdb.confignode.rpc.thrift.TDatabaseInfo;
 import org.apache.iotdb.db.queryengine.common.header.ColumnHeader;
 import org.apache.iotdb.db.queryengine.common.header.ColumnHeaderConstant;
@@ -81,9 +82,19 @@ public class ShowDBTask implements IConfigTask {
       builder.getTimeColumnBuilder().writeLong(0L);
       builder.getColumnBuilder(0).writeBinary(new Binary(dbName, 
TSFileConfig.STRING_CHARSET));
 
-      
builder.getColumnBuilder(1).writeInt(storageGroupInfo.getSchemaReplicationFactor());
-      
builder.getColumnBuilder(2).writeInt(storageGroupInfo.getDataReplicationFactor());
-      
builder.getColumnBuilder(3).writeLong(storageGroupInfo.getTimePartitionInterval());
+      if (Long.MAX_VALUE == storageGroupInfo.getTTL()) {
+        builder
+            .getColumnBuilder(1)
+            .writeBinary(new Binary(IoTDBConstant.TTL_INFINITE, 
TSFileConfig.STRING_CHARSET));
+      } else {
+        builder
+            .getColumnBuilder(1)
+            .writeBinary(
+                new Binary(String.valueOf(storageGroupInfo.getTTL()), 
TSFileConfig.STRING_CHARSET));
+      }
+      
builder.getColumnBuilder(2).writeInt(storageGroupInfo.getSchemaReplicationFactor());
+      
builder.getColumnBuilder(3).writeInt(storageGroupInfo.getDataReplicationFactor());
+      
builder.getColumnBuilder(4).writeLong(storageGroupInfo.getTimePartitionInterval());
       builder.declarePosition();
     }
 
@@ -106,11 +117,21 @@ public class ShowDBTask implements IConfigTask {
       builder.getTimeColumnBuilder().writeLong(0L);
       builder.getColumnBuilder(0).writeBinary(new Binary(dbName, 
TSFileConfig.STRING_CHARSET));
 
-      
builder.getColumnBuilder(1).writeInt(storageGroupInfo.getSchemaReplicationFactor());
-      
builder.getColumnBuilder(2).writeInt(storageGroupInfo.getDataReplicationFactor());
-      
builder.getColumnBuilder(3).writeLong(storageGroupInfo.getTimePartitionInterval());
+      if (Long.MAX_VALUE == storageGroupInfo.getTTL()) {
+        builder
+            .getColumnBuilder(1)
+            .writeBinary(new Binary(IoTDBConstant.TTL_INFINITE, 
TSFileConfig.STRING_CHARSET));
+      } else {
+        builder
+            .getColumnBuilder(1)
+            .writeBinary(
+                new Binary(String.valueOf(storageGroupInfo.getTTL()), 
TSFileConfig.STRING_CHARSET));
+      }
+      
builder.getColumnBuilder(2).writeInt(storageGroupInfo.getSchemaReplicationFactor());
+      
builder.getColumnBuilder(3).writeInt(storageGroupInfo.getDataReplicationFactor());
+      
builder.getColumnBuilder(4).writeLong(storageGroupInfo.getTimePartitionInterval());
       builder
-          .getColumnBuilder(4)
+          .getColumnBuilder(5)
           .writeBinary(
               new Binary(
                   storageGroupInfo.isIsTableModel() ? "TABLE" : "TREE",
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/StatementAnalyzer.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/StatementAnalyzer.java
index 2e6808d37c5..0cc2f485607 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/StatementAnalyzer.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/analyzer/StatementAnalyzer.java
@@ -181,7 +181,7 @@ import static java.lang.Math.toIntExact;
 import static java.util.Collections.emptyList;
 import static java.util.Locale.ENGLISH;
 import static java.util.Objects.requireNonNull;
-import static 
org.apache.iotdb.commons.schema.table.TsTable.TABLE_ALLOWED_PROPERTIES_2_DEFAULT_VALUE_MAP;
+import static 
org.apache.iotdb.commons.schema.table.TsTable.TABLE_ALLOWED_PROPERTIES;
 import static org.apache.iotdb.commons.schema.table.TsTable.TIME_COLUMN_NAME;
 import static 
org.apache.iotdb.db.queryengine.execution.warnings.StandardWarningCode.REDUNDANT_ORDER_BY;
 import static 
org.apache.iotdb.db.queryengine.plan.relational.analyzer.AggregationAnalyzer.verifyOrderByAggregations;
@@ -455,6 +455,11 @@ public class StatementAnalyzer {
       node.parseTable(sessionContext);
       final TsTable table =
           DataNodeTableCache.getInstance().getTable(node.getDatabase(), 
node.getTableName());
+      if (Objects.isNull(table)) {
+        throw new SemanticException(
+            String.format(
+                "Table '%s.%s' does not exist.", node.getDatabase(), 
node.getTableName()));
+      }
       node.parseModEntries(table);
       analyzeTraverseDevice(node, context, node.getWhere().isPresent());
       node.parseRawExpression(
@@ -2820,7 +2825,7 @@ public class StatementAnalyzer {
       final Set<String> propertyNames = new HashSet<>();
       for (final Property property : properties) {
         final String key = 
property.getName().getValue().toLowerCase(Locale.ENGLISH);
-        if (!TABLE_ALLOWED_PROPERTIES_2_DEFAULT_VALUE_MAP.containsKey(key)) {
+        if (!TABLE_ALLOWED_PROPERTIES.contains(key)) {
           throw new SemanticException("Table property " + key + " is currently 
not allowed.");
         }
         if (!propertyNames.add(key)) {
diff --git 
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/storageengine/dataregion/compaction/tablemodel/TableModelCompactionWithTTLTest.java
 
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/storageengine/dataregion/compaction/tablemodel/TableModelCompactionWithTTLTest.java
index af7ea63cce3..c5ac8d6a2c9 100644
--- 
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/storageengine/dataregion/compaction/tablemodel/TableModelCompactionWithTTLTest.java
+++ 
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/storageengine/dataregion/compaction/tablemodel/TableModelCompactionWithTTLTest.java
@@ -50,7 +50,6 @@ import org.junit.runners.Parameterized;
 import java.io.IOException;
 import java.util.Arrays;
 import java.util.Collection;
-import java.util.Locale;
 import java.util.concurrent.TimeUnit;
 
 @RunWith(Parameterized.class)
@@ -184,7 +183,7 @@ public class TableModelCompactionWithTTLTest extends 
AbstractCompactionTest {
     tsTable.addColumnSchema(
         new MeasurementColumnSchema(
             "s1", TSDataType.STRING, TSEncoding.PLAIN, CompressionType.LZ4));
-    tsTable.addProp(TsTable.TTL_PROPERTY.toLowerCase(Locale.ENGLISH), ttl + 
"");
+    tsTable.addProp(TsTable.TTL_PROPERTY, ttl + "");
     DataNodeTableCache.getInstance().preUpdateTable(this.COMPACTION_TEST_SG, 
tsTable);
     
DataNodeTableCache.getInstance().commitUpdateTable(this.COMPACTION_TEST_SG, 
tableName);
   }
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 014f92a0c59..dc8f372daf5 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
@@ -27,9 +27,7 @@ import 
org.apache.iotdb.commons.schema.table.column.TsTableColumnSchema;
 import org.apache.iotdb.commons.schema.table.column.TsTableColumnSchemaUtil;
 import org.apache.iotdb.commons.utils.CommonDateTimeUtils;
 
-import org.apache.tsfile.common.conf.TSFileConfig;
 import org.apache.tsfile.enums.TSDataType;
-import org.apache.tsfile.utils.Binary;
 import org.apache.tsfile.utils.ReadWriteIOUtils;
 
 import javax.annotation.concurrent.ThreadSafe;
@@ -40,13 +38,14 @@ import java.io.InputStream;
 import java.io.OutputStream;
 import java.nio.ByteBuffer;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.LinkedHashMap;
 import java.util.List;
-import java.util.Locale;
 import java.util.Map;
 import java.util.Objects;
 import java.util.Optional;
+import java.util.Set;
 import java.util.concurrent.locks.ReadWriteLock;
 import java.util.concurrent.locks.ReentrantReadWriteLock;
 
@@ -57,16 +56,8 @@ public class TsTable {
   private static final TimeColumnSchema TIME_COLUMN_SCHEMA =
       new TimeColumnSchema(TIME_COLUMN_NAME, TSDataType.TIMESTAMP);
 
-  public static final Map<String, Object> 
TABLE_ALLOWED_PROPERTIES_2_DEFAULT_VALUE_MAP =
-      new HashMap<>();
-
-  public static final String TTL_PROPERTY = "TTL";
-
-  static {
-    TABLE_ALLOWED_PROPERTIES_2_DEFAULT_VALUE_MAP.put(
-        TTL_PROPERTY.toLowerCase(Locale.ENGLISH), new Binary("INF", 
TSFileConfig.STRING_CHARSET));
-  }
-
+  public static final String TTL_PROPERTY = "ttl";
+  public static final Set<String> TABLE_ALLOWED_PROPERTIES = 
Collections.singleton(TTL_PROPERTY);
   private final String tableName;
 
   private final Map<String, TsTableColumnSchema> columnSchemaMap = new 
LinkedHashMap<>();
@@ -197,8 +188,7 @@ public class TsTable {
   }
 
   public long getTableTTLInMS() {
-    return Long.parseLong(
-        
getPropValue(TTL_PROPERTY.toLowerCase(Locale.ENGLISH)).orElse(Long.MAX_VALUE + 
""));
+    return Long.parseLong(getPropValue(TTL_PROPERTY).orElse(Long.MAX_VALUE + 
""));
   }
 
   public Optional<String> getPropValue(final String propKey) {


Reply via email to