You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@iotdb.apache.org by ca...@apache.org on 2024/07/30 03:08:23 UTC
(iotdb) branch ty/TableModelGrammar updated: Fixed the bug that duplicate table creation may delete the original table
This is an automated email from the ASF dual-hosted git repository.
caogaofei 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 b9c9603470c Fixed the bug that duplicate table creation may delete the original table
b9c9603470c is described below
commit b9c9603470c1cbb91b54099a228aaef317263d29
Author: Caideyipi <87...@users.noreply.github.com>
AuthorDate: Tue Jul 30 11:08:18 2024 +0800
Fixed the bug that duplicate table creation may delete the original table
---
.../iotdb/relational/it/schema/IoTDBTableIT.java | 97 ++++++++++++----------
.../manager/schema/ClusterSchemaManager.java | 3 +-
.../persistence/schema/ClusterSchemaInfo.java | 3 +-
.../confignode/persistence/schema/ConfigMTree.java | 13 +--
.../impl/schema/table/CreateTableProcedure.java | 24 +++++-
.../procedure/state/schema/CreateTableState.java | 1 +
.../table/TableAlreadyExistsException.java | 2 +-
7 files changed, 90 insertions(+), 53 deletions(-)
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 76bda1ee3a0..f34f051f397 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
@@ -69,12 +69,12 @@ public class IoTDBTableIT {
// 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)");
+ "create table table1(region_id STRING ID, plant_id STRING ID, device_id STRING ID, model STRING ATTRIBUTE, temperature FLOAT MEASUREMENT, humidity DOUBLE MEASUREMENT)");
} catch (final SQLException e) {
assertEquals("701: database is not specified", e.getMessage());
}
- // Show tables shall succeed in a newly created database
+ // Show tables shall succeed in a newly created database with no tables
try (final ResultSet resultSet = statement.executeQuery("SHOW tables from test1")) {
ResultSetMetaData metaData = resultSet.getMetaData();
assertEquals(showTablesColumnHeaders.size(), metaData.getColumnCount());
@@ -87,10 +87,59 @@ public class IoTDBTableIT {
// 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)");
+ "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)");
+
+ try {
+ 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)");
+ } catch (final SQLException e) {
+ assertEquals("551: Table 'test1.table1' already exists.", e.getMessage());
+ }
+
+ String[] tableNames = new String[] {"table1"};
+ String[] ttls = new String[] {"INF"};
statement.execute("use test2");
+ // show tables by specifying another database
+ // Check duplicate create table won't affect table state
+ // using SHOW tables in
+ try (final 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.getString(2));
+ cnt++;
+ }
+ assertEquals(tableNames.length, cnt);
+ }
+
+ // using SHOW tables from
+ try (final ResultSet resultSet = statement.executeQuery("SHOW tables from test1")) {
+ int cnt = 0;
+ final 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);
+ }
+
+ statement.execute(
+ "create table if not exists test1.table1(region_id STRING ID, plant_id STRING ID, device_id STRING ID, model STRING ATTRIBUTE, temperature FLOAT MEASUREMENT, humidity DOUBLE MEASUREMENT)");
+
try {
statement.execute(
"create table table2(region_id STRING ID, plant_id STRING ID, device_id STRING ID, model STRING ATTRIBUTE, temperature FLOAT MEASUREMENT, humidity DOUBLE MEASUREMENT, time2 INT64 TIME) with (TTL=3600000)");
@@ -143,8 +192,8 @@ public class IoTDBTableIT {
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"};
- String[] ttls = new String[] {"6600000"};
+ tableNames = new String[] {"table2"};
+ ttls = new String[] {"6600000"};
// show tables from current database
try (final ResultSet resultSet = statement.executeQuery("SHOW tables")) {
@@ -163,44 +212,6 @@ public class IoTDBTableIT {
assertEquals(tableNames.length, cnt);
}
- // show tables by specifying another database
- tableNames = new String[] {"table1"};
- ttls = new String[] {"3600000"};
-
- // using SHOW tables in
- try (final 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.getString(2));
- cnt++;
- }
- assertEquals(tableNames.length, cnt);
- }
-
- // using SHOW tables from
- try (final 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.getString(2));
- cnt++;
- }
- assertEquals(tableNames.length, cnt);
- }
-
// show tables from a non-exist database
try {
statement.executeQuery("SHOW tables from test3");
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 924ffbc763c..c1f028a1049 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
@@ -99,6 +99,7 @@ import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
+import java.util.Optional;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.locks.ReentrantLock;
@@ -1106,7 +1107,7 @@ public class ClusterSchemaManager {
schemaQuotaStatistics.setSeriesThreshold(seriesThreshold);
}
- public TsTable getTable(String database, String tableName) {
+ public Optional<TsTable> getTable(final String database, final String tableName) {
return clusterSchemaInfo.getTsTable(database, tableName);
}
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 02c97416698..e565ac48f35 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
@@ -92,6 +92,7 @@ import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
+import java.util.Optional;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.locks.ReentrantReadWriteLock;
@@ -1118,7 +1119,7 @@ public class ClusterSchemaInfo implements SnapshotProcessor {
}
}
- public TsTable getTsTable(String database, String tableName) {
+ public Optional<TsTable> getTsTable(String database, String tableName) {
databaseReadWriteLock.readLock().lock();
try {
return mTree.getTable(new PartialPath(database), tableName);
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 bfa0adb60fd..ca617748e01 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
@@ -64,6 +64,7 @@ import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
+import java.util.Optional;
import java.util.Set;
import java.util.Stack;
import java.util.TreeSet;
@@ -718,14 +719,14 @@ public class ConfigMTree {
return result;
}
- public TsTable getTable(PartialPath database, String tableName) throws MetadataException {
- IConfigMNode databaseNode = getDatabaseNodeByDatabasePath(database).getAsMNode();
+ public Optional<TsTable> getTable(final PartialPath database, final String tableName)
+ throws MetadataException {
+ final IConfigMNode databaseNode = getDatabaseNodeByDatabasePath(database).getAsMNode();
if (!databaseNode.hasChild(tableName)) {
- throw new TableNotExistsException(
- database.getFullPath().substring(ROOT.length() + 1), tableName);
+ return Optional.empty();
}
- ConfigTableNode tableNode = (ConfigTableNode) databaseNode.getChild(tableName);
- return tableNode.getTable();
+ final ConfigTableNode tableNode = (ConfigTableNode) databaseNode.getChild(tableName);
+ return Optional.of(tableNode.getTable());
}
public void addTableColumn(
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 ab002e20f8e..3d5546b476b 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
@@ -66,6 +66,7 @@ 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.rpc.TSStatusCode.TABLE_ALREADY_EXISTS;
public class CreateTableProcedure
extends StateMachineProcedure<ConfigNodeProcedureEnv, CreateTableState> {
@@ -91,6 +92,10 @@ public class CreateTableProcedure
final long startTime = System.currentTimeMillis();
try {
switch (state) {
+ case CHECK_TABLE_EXISTENCE:
+ LOGGER.info("Check the existence of table {}.{}", database, table.getTableName());
+ checkTableExistence(env);
+ break;
case PRE_CREATE:
LOGGER.info("Pre create table {}.{}", database, table.getTableName());
preCreateTable(env);
@@ -127,6 +132,23 @@ public class CreateTableProcedure
}
}
+ private void checkTableExistence(final ConfigNodeProcedureEnv env) {
+ if (env.getConfigManager()
+ .getClusterSchemaManager()
+ .getTable(database, table.getTableName())
+ .isPresent()) {
+ setFailure(
+ new ProcedureException(
+ new IoTDBException(
+ String.format(
+ "Table '%s.%s' already exists.",
+ database.substring(ROOT.length() + 1), table.getTableName()),
+ TABLE_ALREADY_EXISTS.getStatusCode())));
+ } else {
+ setNextState(CreateTableState.PRE_CREATE);
+ }
+ }
+
private void preCreateTable(final ConfigNodeProcedureEnv env) {
final PreCreateTablePlan plan = new PreCreateTablePlan(database, table);
TSStatus status;
@@ -390,7 +412,7 @@ public class CreateTableProcedure
@Override
protected CreateTableState getInitialState() {
- return CreateTableState.PRE_CREATE;
+ return CreateTableState.CHECK_TABLE_EXISTENCE;
}
public String getDatabase() {
diff --git a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/state/schema/CreateTableState.java b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/state/schema/CreateTableState.java
index ba22c4a892d..9d09a09cfb8 100644
--- a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/state/schema/CreateTableState.java
+++ b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/procedure/state/schema/CreateTableState.java
@@ -20,6 +20,7 @@
package org.apache.iotdb.confignode.procedure.state.schema;
public enum CreateTableState {
+ CHECK_TABLE_EXISTENCE,
PRE_CREATE,
PRE_RELEASE,
VALIDATE_TIMESERIES_EXISTENCE,
diff --git a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/exception/metadata/table/TableAlreadyExistsException.java b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/exception/metadata/table/TableAlreadyExistsException.java
index d745b6eb0a3..31f91d98cf0 100644
--- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/exception/metadata/table/TableAlreadyExistsException.java
+++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/exception/metadata/table/TableAlreadyExistsException.java
@@ -26,7 +26,7 @@ public class TableAlreadyExistsException extends MetadataException {
public TableAlreadyExistsException(String database, String tableName) {
super(
- String.format("Table %s.%s already exists.", database, tableName),
+ String.format("Table '%s.%s' already exists.", database, tableName),
TSStatusCode.TABLE_ALREADY_EXISTS.getStatusCode());
}
}