This is an automated email from the ASF dual-hosted git repository.
rong 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 285ee5b5b6b Load: Fixed the bug that an empty table database may not
check privilege for auto-creation (#15366)
285ee5b5b6b is described below
commit 285ee5b5b6b500c038ae71099ac94fba7fa1595c
Author: Caideyipi <[email protected]>
AuthorDate: Tue Apr 22 19:56:14 2025 +0800
Load: Fixed the bug that an empty table database may not check privilege
for auto-creation (#15366)
---
.../org/apache/iotdb/db/it/IoTDBLoadTsFileIT.java | 54 ++++++++++++++++++++++
.../iotdb/confignode/manager/ConfigManager.java | 2 +-
.../persistence/schema/ClusterSchemaInfo.java | 15 ++++--
.../db/schemaengine/table/DataNodeTableCache.java | 18 ++++++--
4 files changed, 78 insertions(+), 11 deletions(-)
diff --git
a/integration-test/src/test/java/org/apache/iotdb/db/it/IoTDBLoadTsFileIT.java
b/integration-test/src/test/java/org/apache/iotdb/db/it/IoTDBLoadTsFileIT.java
index b8e431356f5..d474d5d5833 100644
---
a/integration-test/src/test/java/org/apache/iotdb/db/it/IoTDBLoadTsFileIT.java
+++
b/integration-test/src/test/java/org/apache/iotdb/db/it/IoTDBLoadTsFileIT.java
@@ -972,6 +972,60 @@ public class IoTDBLoadTsFileIT {
return pairs;
}
+ @Test
+ public void testLoadWithEmptyDatabaseForTableModel() throws Exception {
+ final int lineCount = 10000;
+
+ final List<Pair<MeasurementSchema, MeasurementSchema>> measurementSchemas =
+ generateMeasurementSchemasForDataTypeConvertion();
+ final List<Tablet.ColumnCategory> columnCategories =
+ generateTabletColumnCategory(0, measurementSchemas.size());
+
+ final File file = new File(tmpDir, "1-0-0-0.tsfile");
+
+ final List<IMeasurementSchema> schemaList =
+ measurementSchemas.stream().map(pair ->
pair.right).collect(Collectors.toList());
+
+ try (final TsFileTableGenerator generator = new
TsFileTableGenerator(file)) {
+ generator.registerTable(SchemaConfig.TABLE_0, schemaList,
columnCategories);
+
+ generator.generateData(SchemaConfig.TABLE_0, lineCount,
PARTITION_INTERVAL / 10_000);
+ }
+
+ // Prepare normal user
+ try (final Connection adminCon =
EnvFactory.getEnv().getConnection(BaseEnv.TABLE_SQL_DIALECT);
+ final Statement adminStmt = adminCon.createStatement()) {
+ adminStmt.execute("create user test 'password'");
+ adminStmt.execute(
+ String.format(
+ "grant create, insert on %s.%s to user test",
+ SchemaConfig.DATABASE_0, SchemaConfig.TABLE_0));
+
+ // auto-create table
+ adminStmt.execute(String.format("create database if not exists %s",
SchemaConfig.DATABASE_0));
+ }
+
+ try (final Connection connection =
+ EnvFactory.getEnv().getConnection("test", "password",
BaseEnv.TABLE_SQL_DIALECT);
+ final Statement statement = connection.createStatement()) {
+ statement.execute(String.format("use %s", SchemaConfig.DATABASE_0));
+ statement.execute(String.format("load '%s'", file.getAbsolutePath()));
+ }
+
+ try (final Connection adminCon =
EnvFactory.getEnv().getConnection(BaseEnv.TABLE_SQL_DIALECT);
+ final Statement adminStmt = adminCon.createStatement()) {
+ adminStmt.execute(String.format("use %s", SchemaConfig.DATABASE_0));
+ try (final ResultSet resultSet =
+ adminStmt.executeQuery(String.format("select count(*) from %s",
SchemaConfig.TABLE_0))) {
+ if (resultSet.next()) {
+ Assert.assertEquals(lineCount, resultSet.getLong(1));
+ } else {
+ Assert.fail("This ResultSet is empty.");
+ }
+ }
+ }
+ }
+
@Test
public void testLoadWithConvertOnTypeMismatchForTableModel() throws
Exception {
final int lineCount = 10000;
diff --git
a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/ConfigManager.java
b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/ConfigManager.java
index b9b946d6cc5..8e559591e96 100644
---
a/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/ConfigManager.java
+++
b/iotdb-core/confignode/src/main/java/org/apache/iotdb/confignode/manager/ConfigManager.java
@@ -2866,7 +2866,7 @@ public class ConfigManager implements IManager {
.checkDuplicateTableTask(
entry.getKey(), null, table, null,
null)
.getRight());
- return !entry.getValue().isEmpty();
+ return true;
})
.collect(Collectors.toMap(Map.Entry::getKey,
Map.Entry::getValue)))
: new TFetchTableResp(status);
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 0a9c91f118c..9430f93b1a8 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
@@ -85,6 +85,7 @@ import
org.apache.iotdb.confignode.exception.DatabaseNotExistsException;
import org.apache.iotdb.confignode.rpc.thrift.TDatabaseSchema;
import org.apache.iotdb.confignode.rpc.thrift.TTableColumnInfo;
import org.apache.iotdb.confignode.rpc.thrift.TTableInfo;
+import org.apache.iotdb.db.exception.metadata.DatabaseNotSetException;
import org.apache.iotdb.db.exception.metadata.SchemaQuotaExceededException;
import org.apache.iotdb.db.exception.sql.SemanticException;
import org.apache.iotdb.db.schemaengine.template.Template;
@@ -1297,11 +1298,15 @@ public class ClusterSchemaInfo implements
SnapshotProcessor {
final Map<String, Map<String, TsTable>> result = new HashMap<>();
for (final Map.Entry<String, Set<String>> database2Tables :
plan.getFetchTableMap().entrySet()) {
- result.put(
- database2Tables.getKey(),
- tableModelMTree.getSpecificTablesUnderSpecificDatabase(
- getQualifiedDatabasePartialPath(database2Tables.getKey()),
- database2Tables.getValue()));
+ try {
+ result.put(
+ database2Tables.getKey(),
+ tableModelMTree.getSpecificTablesUnderSpecificDatabase(
+ getQualifiedDatabasePartialPath(database2Tables.getKey()),
+ database2Tables.getValue()));
+ } catch (final DatabaseNotSetException ignore) {
+ // continue
+ }
}
return new FetchTableResp(StatusUtils.OK, result);
} catch (final MetadataException e) {
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 73c1d230d68..22026601abc 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
@@ -476,12 +476,20 @@ public class DataNodeTableCache implements ITableCache {
}
public boolean isDatabaseExist(final String database) {
- readWriteLock.readLock().lock();
- try {
- return databaseTableMap.containsKey(database);
- } finally {
- readWriteLock.readLock().unlock();
+ if (databaseTableMap.containsKey(database)) {
+ return true;
+ }
+ if (getTablesInConfigNode(Collections.singletonMap(database,
Collections.emptyMap()))
+ .containsKey(database)) {
+ readWriteLock.readLock().lock();
+ try {
+ databaseTableMap.computeIfAbsent(database, k -> new
ConcurrentHashMap<>());
+ return true;
+ } finally {
+ readWriteLock.readLock().unlock();
+ }
}
+ return false;
}
// Database shall not start with "root"