This is an automated email from the ASF dual-hosted git repository.
jackietien pushed a commit to branch ty/TableModelGrammar
in repository https://gitbox.apache.org/repos/asf/iotdb.git
The following commit(s) were added to refs/heads/ty/TableModelGrammar by this
push:
new 388083a5032 Add IT for table management and change type of ID and
ATTRIBUTE column from TEXT to STRING
388083a5032 is described below
commit 388083a5032e729273038ffe381b422295317493
Author: Jackie Tien <[email protected]>
AuthorDate: Fri Jun 28 21:46:14 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..80ae31d9c54 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 testManageTable() {
+ 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);