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"

Reply via email to