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 346af31db5e Rewrite the permission & Fixed the bug of show/desc tables 
details for Information schema
346af31db5e is described below

commit 346af31db5e8906d27260b85037c14d25525d60f
Author: Caideyipi <[email protected]>
AuthorDate: Fri Mar 21 09:34:53 2025 +0800

    Rewrite the permission & Fixed the bug of show/desc tables details for 
Information schema
---
 .../it/query/recent/IoTDBMaintainAuthIT.java       |  3 --
 .../relational/it/schema/IoTDBDatabaseIT.java      | 39 ++++++++++++++++++++--
 .../iotdb/relational/it/schema/IoTDBTableIT.java   |  4 +++
 .../db/queryengine/plan/analyze/AnalyzeUtils.java  |  2 --
 .../plan/analyze/schema/SchemaValidator.java       |  2 +-
 .../execution/config/TableConfigTaskVisitor.java   | 28 ++++++----------
 .../relational/analyzer/StatementAnalyzer.java     |  3 --
 .../fetcher/TableHeaderSchemaValidator.java        |  3 --
 .../relational/security/AccessControlImpl.java     | 32 ++++++++++++++++++
 .../schemaengine/table/InformationSchemaUtils.java |  2 ++
 10 files changed, 87 insertions(+), 31 deletions(-)

diff --git 
a/integration-test/src/test/java/org/apache/iotdb/relational/it/query/recent/IoTDBMaintainAuthIT.java
 
b/integration-test/src/test/java/org/apache/iotdb/relational/it/query/recent/IoTDBMaintainAuthIT.java
index 81bee0064b2..800af040335 100644
--- 
a/integration-test/src/test/java/org/apache/iotdb/relational/it/query/recent/IoTDBMaintainAuthIT.java
+++ 
b/integration-test/src/test/java/org/apache/iotdb/relational/it/query/recent/IoTDBMaintainAuthIT.java
@@ -53,7 +53,6 @@ public class IoTDBMaintainAuthIT {
         "INSERT INTO table1(time,device_id,s1) values(1, 'd1', 1)",
         String.format(CREATE_USER_FORMAT, USER_1, PASSWORD),
         "GRANT SELECT ON TABLE table1 TO USER " + USER_1,
-        "GRANT SELECT ON information_schema.queries TO USER " + USER_1,
         String.format(CREATE_USER_FORMAT, USER_2, PASSWORD)
       };
 
@@ -167,8 +166,6 @@ public class IoTDBMaintainAuthIT {
 
     // case 12: show queries
     // user1 with select on information_schema.queries
-    expectedHeader =
-        new String[] {"query_id", "start_time", "datanode_id", "elapsed_time", 
"statement", "user"};
     tableAssertTestFail(
         "SHOW QUERIES",
         TSStatusCode.NO_PERMISSION.getStatusCode()
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 6243c4fa28f..6235172841f 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
@@ -328,8 +328,14 @@ public class IoTDBDatabaseIT {
 
   @Test
   public void testInformationSchema() throws SQLException {
+    // Use a normal user to test visibility
+    try (final Connection adminCon = 
EnvFactory.getEnv().getConnection(BaseEnv.TABLE_SQL_DIALECT);
+        final Statement adminStmt = adminCon.createStatement()) {
+      adminStmt.execute("create user test 'password'");
+    }
+
     try (final Connection connection =
-            EnvFactory.getEnv().getConnection(BaseEnv.TABLE_SQL_DIALECT);
+            EnvFactory.getEnv().getConnection("test", "password", 
BaseEnv.TABLE_SQL_DIALECT);
         final Statement statement = connection.createStatement()) {
       // Test unsupported write plans
       final Set<String> writeSQLs =
@@ -456,7 +462,20 @@ public class IoTDBDatabaseIT {
                   "consumer_group_name,STRING,TAG,",
                   "subscribed_consumers,STRING,ATTRIBUTE,")));
 
+      // Currently only root can query information_schema
+      Assert.assertThrows(
+          SQLException.class,
+          () -> {
+            statement.execute("select * from databases");
+          });
+    }
+
+    try (final Connection connection =
+            EnvFactory.getEnv().getConnection(BaseEnv.TABLE_SQL_DIALECT);
+        final Statement statement = connection.createStatement()) {
       // Test table query
+      statement.execute("use information_schema");
+
       statement.execute("create database test");
       statement.execute(
           "create table test.test (a tag, b attribute, c int32 comment 
'turbine') comment 'test'");
@@ -604,12 +623,25 @@ public class IoTDBDatabaseIT {
       TestUtils.assertResultSetEqual(
           userStmt.executeQuery("show databases"),
           
"Database,TTL(ms),SchemaReplicationFactor,DataReplicationFactor,TimePartitionInterval,",
-          Collections.emptySet());
+          Collections.singleton("information_schema,INF,null,null,null,"));
     }
 
     try (final Connection adminCon = 
EnvFactory.getEnv().getConnection(BaseEnv.TABLE_SQL_DIALECT);
         final Statement adminStmt = adminCon.createStatement()) {
       adminStmt.execute("GRANT SELECT ON DATABASE DB to user test");
+
+      // Information_schema does not support grant & revoke
+      Assert.assertThrows(
+          SQLException.class,
+          () -> {
+            adminStmt.execute("GRANT SELECT ON DATABASE information_schema to 
user test");
+          });
+
+      Assert.assertThrows(
+          SQLException.class,
+          () -> {
+            adminStmt.execute("REVOKE SELECT ON information_schema.tables from 
user test");
+          });
     }
 
     try (final Connection userCon =
@@ -622,6 +654,9 @@ public class IoTDBDatabaseIT {
           assertEquals(showDBColumnHeaders.get(i).getColumnName(), 
metaData.getColumnName(i + 1));
         }
         Assert.assertTrue(resultSet.next());
+        if (resultSet.getString(1).equals("information_schema")) {
+          assertTrue(resultSet.next());
+        }
         assertEquals("db", resultSet.getString(1));
         Assert.assertFalse(resultSet.next());
       }
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 104f324a820..3c8aa4db542 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
@@ -47,6 +47,7 @@ import static 
org.apache.iotdb.commons.schema.column.ColumnHeaderConstant.showTa
 import static 
org.apache.iotdb.commons.schema.column.ColumnHeaderConstant.showTablesDetailsColumnHeaders;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
 import static org.junit.Assert.fail;
 
 @RunWith(IoTDBTestRunner.class)
@@ -613,6 +614,9 @@ public class IoTDBTableIT {
           assertEquals(showDBColumnHeaders.get(i).getColumnName(), 
metaData.getColumnName(i + 1));
         }
         Assert.assertTrue(resultSet.next());
+        if (resultSet.getString(1).equals("information_schema")) {
+          assertTrue(resultSet.next());
+        }
         assertEquals("db", resultSet.getString(1));
         Assert.assertFalse(resultSet.next());
       }
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/AnalyzeUtils.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/AnalyzeUtils.java
index 99c1dad2c53..744b3eb1083 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/AnalyzeUtils.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/AnalyzeUtils.java
@@ -51,7 +51,6 @@ import 
org.apache.iotdb.db.queryengine.plan.statement.crud.InsertRowStatement;
 import org.apache.iotdb.db.queryengine.plan.statement.crud.InsertRowsStatement;
 import 
org.apache.iotdb.db.queryengine.plan.statement.crud.InsertTabletStatement;
 import org.apache.iotdb.db.schemaengine.table.DataNodeTableCache;
-import org.apache.iotdb.db.schemaengine.table.InformationSchemaUtils;
 import 
org.apache.iotdb.db.storageengine.dataregion.modification.DeletionPredicate;
 import org.apache.iotdb.db.storageengine.dataregion.modification.IDPredicate;
 import 
org.apache.iotdb.db.storageengine.dataregion.modification.IDPredicate.And;
@@ -344,7 +343,6 @@ public class AnalyzeUtils {
   private static void validateSchema(final Delete node, final MPPQueryContext 
queryContext) {
     final String tableName = node.getTable().getName().getSuffix();
     final String databaseName = getDatabaseName(node, queryContext);
-    InformationSchemaUtils.checkDBNameInWrite(databaseName);
     node.setDatabaseName(databaseName);
 
     final TsTable table = 
DataNodeTableCache.getInstance().getTable(databaseName, tableName);
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/schema/SchemaValidator.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/schema/SchemaValidator.java
index 6023ea4bea2..c79b54146fe 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/schema/SchemaValidator.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/analyze/schema/SchemaValidator.java
@@ -71,12 +71,12 @@ public class SchemaValidator {
       final MPPQueryContext context,
       AccessControl accessControl) {
     try {
-      insertStatement.validateTableSchema(metadata, context);
       accessControl.checkCanInsertIntoTable(
           context.getSession().getUserName(),
           new QualifiedObjectName(
               unQualifyDatabaseName(insertStatement.getDatabase()),
               insertStatement.getTableName()));
+      insertStatement.validateTableSchema(metadata, context);
       insertStatement.updateAfterSchemaValidation(context);
       insertStatement.validateDeviceSchema(metadata, context);
       insertStatement.removeAttributeColumns();
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 b3c8a5e01a2..14d30af6340 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
@@ -190,7 +190,6 @@ import 
org.apache.iotdb.db.queryengine.plan.statement.sys.SetConfigurationStatem
 import 
org.apache.iotdb.db.queryengine.plan.statement.sys.SetSystemStatusStatement;
 import 
org.apache.iotdb.db.queryengine.plan.statement.sys.StartRepairDataStatement;
 import 
org.apache.iotdb.db.queryengine.plan.statement.sys.StopRepairDataStatement;
-import org.apache.iotdb.db.schemaengine.table.InformationSchemaUtils;
 import org.apache.iotdb.pipe.api.customizer.parameter.PipeParameters;
 
 import org.apache.tsfile.common.conf.TSFileConfig;
@@ -338,7 +337,6 @@ public class TableConfigTaskVisitor extends 
AstVisitor<IConfigTask, MPPQueryCont
   @Override
   protected IConfigTask visitDropDB(final DropDB node, final MPPQueryContext 
context) {
     context.setQueryType(QueryType.WRITE);
-    InformationSchemaUtils.checkDBNameInWrite(node.getDbName().getValue());
     accessControl.checkCanDropDatabase(
         context.getSession().getUserName(), node.getDbName().getValue());
     return new DropDBTask(node);
@@ -445,7 +443,7 @@ public class TableConfigTaskVisitor extends 
AstVisitor<IConfigTask, MPPQueryCont
   @Override
   protected IConfigTask visitCreateTable(final CreateTable node, final 
MPPQueryContext context) {
     context.setQueryType(QueryType.WRITE);
-    final Pair<String, String> databaseTablePair = 
splitQualifiedName(node.getName(), true);
+    final Pair<String, String> databaseTablePair = 
splitQualifiedName(node.getName());
     final String database = databaseTablePair.getLeft();
     final String tableName = databaseTablePair.getRight();
 
@@ -514,7 +512,7 @@ public class TableConfigTaskVisitor extends 
AstVisitor<IConfigTask, MPPQueryCont
   @Override
   protected IConfigTask visitRenameTable(final RenameTable node, final 
MPPQueryContext context) {
     context.setQueryType(QueryType.WRITE);
-    final Pair<String, String> databaseTablePair = 
splitQualifiedName(node.getSource(), true);
+    final Pair<String, String> databaseTablePair = 
splitQualifiedName(node.getSource());
     final String database = databaseTablePair.getLeft();
     final String tableName = databaseTablePair.getRight();
 
@@ -537,7 +535,7 @@ public class TableConfigTaskVisitor extends 
AstVisitor<IConfigTask, MPPQueryCont
   @Override
   protected IConfigTask visitAddColumn(final AddColumn node, final 
MPPQueryContext context) {
     context.setQueryType(QueryType.WRITE);
-    final Pair<String, String> databaseTablePair = 
splitQualifiedName(node.getTableName(), true);
+    final Pair<String, String> databaseTablePair = 
splitQualifiedName(node.getTableName());
     final String database = databaseTablePair.getLeft();
     final String tableName = databaseTablePair.getRight();
 
@@ -562,7 +560,7 @@ public class TableConfigTaskVisitor extends 
AstVisitor<IConfigTask, MPPQueryCont
   @Override
   protected IConfigTask visitRenameColumn(final RenameColumn node, final 
MPPQueryContext context) {
     context.setQueryType(QueryType.WRITE);
-    final Pair<String, String> databaseTablePair = 
splitQualifiedName(node.getTable(), true);
+    final Pair<String, String> databaseTablePair = 
splitQualifiedName(node.getTable());
     final String database = databaseTablePair.getLeft();
     final String tableName = databaseTablePair.getRight();
 
@@ -588,7 +586,7 @@ public class TableConfigTaskVisitor extends 
AstVisitor<IConfigTask, MPPQueryCont
   @Override
   protected IConfigTask visitDropColumn(final DropColumn node, final 
MPPQueryContext context) {
     context.setQueryType(QueryType.WRITE);
-    final Pair<String, String> databaseTablePair = 
splitQualifiedName(node.getTable(), true);
+    final Pair<String, String> databaseTablePair = 
splitQualifiedName(node.getTable());
     final String database = databaseTablePair.getLeft();
     final String tableName = databaseTablePair.getRight();
 
@@ -608,7 +606,7 @@ public class TableConfigTaskVisitor extends 
AstVisitor<IConfigTask, MPPQueryCont
   protected IConfigTask visitSetProperties(
       final SetProperties node, final MPPQueryContext context) {
     context.setQueryType(QueryType.WRITE);
-    final Pair<String, String> databaseTablePair = 
splitQualifiedName(node.getName(), true);
+    final Pair<String, String> databaseTablePair = 
splitQualifiedName(node.getName());
     final String database = databaseTablePair.getLeft();
     final String tableName = databaseTablePair.getRight();
 
@@ -627,7 +625,7 @@ public class TableConfigTaskVisitor extends 
AstVisitor<IConfigTask, MPPQueryCont
   protected IConfigTask visitSetTableComment(
       final SetTableComment node, final MPPQueryContext context) {
     context.setQueryType(QueryType.WRITE);
-    final Pair<String, String> databaseTablePair = 
splitQualifiedName(node.getTableName(), true);
+    final Pair<String, String> databaseTablePair = 
splitQualifiedName(node.getTableName());
     final String database = databaseTablePair.getLeft();
     final String tableName = databaseTablePair.getRight();
 
@@ -642,7 +640,7 @@ public class TableConfigTaskVisitor extends 
AstVisitor<IConfigTask, MPPQueryCont
   protected IConfigTask visitSetColumnComment(
       final SetColumnComment node, final MPPQueryContext context) {
     context.setQueryType(QueryType.WRITE);
-    final Pair<String, String> databaseTablePair = 
splitQualifiedName(node.getTable(), true);
+    final Pair<String, String> databaseTablePair = 
splitQualifiedName(node.getTable());
     final String database = databaseTablePair.getLeft();
     final String tableName = databaseTablePair.getRight();
 
@@ -660,7 +658,6 @@ public class TableConfigTaskVisitor extends 
AstVisitor<IConfigTask, MPPQueryCont
   }
 
   public static void validateDatabaseName(final String dbName) throws 
SemanticException {
-    InformationSchemaUtils.checkDBNameInWrite(dbName);
     // Check database length here
     if (dbName.contains(PATH_SEPARATOR)
         || !IoTDBConfig.STORAGE_GROUP_PATTERN.matcher(dbName).matches()
@@ -674,7 +671,7 @@ public class TableConfigTaskVisitor extends 
AstVisitor<IConfigTask, MPPQueryCont
     }
   }
 
-  public Pair<String, String> splitQualifiedName(final QualifiedName name, 
final boolean isWrite) {
+  public Pair<String, String> splitQualifiedName(final QualifiedName name) {
     String database = clientSession.getDatabaseName();
     if (name.getPrefix().isPresent()) {
       database = name.getPrefix().get().toString();
@@ -682,9 +679,6 @@ public class TableConfigTaskVisitor extends 
AstVisitor<IConfigTask, MPPQueryCont
     if (database == null) {
       throw new SemanticException(DATABASE_NOT_SPECIFIED);
     }
-    if (isWrite) {
-      InformationSchemaUtils.checkDBNameInWrite(database);
-    }
     return new Pair<>(database, name.getSuffix());
   }
 
@@ -728,7 +722,7 @@ public class TableConfigTaskVisitor extends 
AstVisitor<IConfigTask, MPPQueryCont
   @Override
   protected IConfigTask visitDropTable(final DropTable node, final 
MPPQueryContext context) {
     context.setQueryType(QueryType.WRITE);
-    final Pair<String, String> databaseTablePair = 
splitQualifiedName(node.getTableName(), true);
+    final Pair<String, String> databaseTablePair = 
splitQualifiedName(node.getTableName());
     final String database = databaseTablePair.getLeft();
     final String tableName = databaseTablePair.getRight();
 
@@ -787,7 +781,7 @@ public class TableConfigTaskVisitor extends 
AstVisitor<IConfigTask, MPPQueryCont
   protected IConfigTask visitDescribeTable(
       final DescribeTable node, final MPPQueryContext context) {
     context.setQueryType(QueryType.READ);
-    final Pair<String, String> databaseTablePair = 
splitQualifiedName(node.getTable(), false);
+    final Pair<String, String> databaseTablePair = 
splitQualifiedName(node.getTable());
     final String database = databaseTablePair.getLeft();
     final String tableName = databaseTablePair.getRight();
 
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 62691ca4069..584028698d6 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
@@ -175,7 +175,6 @@ import 
org.apache.iotdb.db.queryengine.plan.relational.type.TypeManager;
 import org.apache.iotdb.db.queryengine.plan.statement.component.FillPolicy;
 import org.apache.iotdb.db.queryengine.plan.statement.crud.InsertBaseStatement;
 import org.apache.iotdb.db.schemaengine.table.DataNodeTableCache;
-import org.apache.iotdb.db.schemaengine.table.InformationSchemaUtils;
 import org.apache.iotdb.rpc.RpcUtils;
 import org.apache.iotdb.rpc.TSStatusCode;
 import org.apache.iotdb.udf.api.relational.TableFunction;
@@ -467,7 +466,6 @@ public class StatementAnalyzer {
           sessionContext.getUserName(),
           new QualifiedObjectName(node.getDatabase(), node.getTableName()));
       final TranslationMap translationMap = analyzeTraverseDevice(node, 
context, true);
-      InformationSchemaUtils.checkDBNameInWrite(node.getDatabase());
       final TsTable table =
           DataNodeTableCache.getInstance().getTable(node.getDatabase(), 
node.getTableName());
       node.parseRawExpression(
@@ -523,7 +521,6 @@ public class StatementAnalyzer {
       accessControl.checkCanDeleteFromTable(
           sessionContext.getUserName(),
           new QualifiedObjectName(node.getDatabase(), node.getTableName()));
-      InformationSchemaUtils.checkDBNameInWrite(node.getDatabase());
       final TsTable table =
           DataNodeTableCache.getInstance().getTable(node.getDatabase(), 
node.getTableName());
       if (Objects.isNull(table)) {
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/metadata/fetcher/TableHeaderSchemaValidator.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/metadata/fetcher/TableHeaderSchemaValidator.java
index 73eefb1cf8e..8981f18d226 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/metadata/fetcher/TableHeaderSchemaValidator.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/metadata/fetcher/TableHeaderSchemaValidator.java
@@ -45,7 +45,6 @@ import 
org.apache.iotdb.db.queryengine.plan.relational.metadata.TableSchema;
 import org.apache.iotdb.db.queryengine.plan.relational.security.AccessControl;
 import 
org.apache.iotdb.db.queryengine.plan.relational.type.InternalTypeManager;
 import org.apache.iotdb.db.schemaengine.table.DataNodeTableCache;
-import org.apache.iotdb.db.schemaengine.table.InformationSchemaUtils;
 import org.apache.iotdb.rpc.TSStatusCode;
 
 import com.google.common.util.concurrent.ListenableFuture;
@@ -96,8 +95,6 @@ public class TableHeaderSchemaValidator {
       final boolean allowCreateTable,
       final boolean isStrictIdColumn)
       throws LoadAnalyzeTableColumnDisorderException {
-    InformationSchemaUtils.checkDBNameInWrite(database);
-
     // The schema cache R/W and fetch operation must be locked together thus 
the cache clean
     // operation executed by delete timeSeries will be effective.
     DataNodeSchemaLockManager.getInstance()
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/security/AccessControlImpl.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/security/AccessControlImpl.java
index ac22a4fd74e..8b0bc62e75d 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/security/AccessControlImpl.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/queryengine/plan/relational/security/AccessControlImpl.java
@@ -21,10 +21,13 @@ package 
org.apache.iotdb.db.queryengine.plan.relational.security;
 
 import org.apache.iotdb.commons.auth.entity.PrivilegeType;
 import org.apache.iotdb.commons.exception.auth.AccessDeniedException;
+import org.apache.iotdb.commons.schema.table.InformationSchema;
 import org.apache.iotdb.db.auth.AuthorityChecker;
+import org.apache.iotdb.db.exception.sql.SemanticException;
 import 
org.apache.iotdb.db.queryengine.plan.relational.metadata.QualifiedObjectName;
 import 
org.apache.iotdb.db.queryengine.plan.relational.sql.ast.RelationalAuthorStatement;
 import org.apache.iotdb.db.queryengine.plan.relational.type.AuthorRType;
+import org.apache.iotdb.db.schemaengine.table.InformationSchemaUtils;
 
 import java.util.Objects;
 
@@ -40,46 +43,62 @@ public class AccessControlImpl implements AccessControl {
 
   @Override
   public void checkCanCreateDatabase(String userName, String databaseName) {
+    InformationSchemaUtils.checkDBNameInWrite(databaseName);
     authChecker.checkDatabasePrivilege(userName, databaseName, 
TableModelPrivilege.CREATE);
   }
 
   @Override
   public void checkCanDropDatabase(String userName, String databaseName) {
+    InformationSchemaUtils.checkDBNameInWrite(databaseName);
     authChecker.checkDatabasePrivilege(userName, databaseName, 
TableModelPrivilege.DROP);
   }
 
   @Override
   public void checkCanAlterDatabase(String userName, String databaseName) {
+    InformationSchemaUtils.checkDBNameInWrite(databaseName);
     authChecker.checkDatabasePrivilege(userName, databaseName, 
TableModelPrivilege.ALTER);
   }
 
   @Override
   public void checkCanShowOrUseDatabase(String userName, String databaseName) {
+    // Information_schema is visible to any user
+    if (databaseName.equals(InformationSchema.INFORMATION_DATABASE)) {
+      return;
+    }
     authChecker.checkDatabaseVisibility(userName, databaseName);
   }
 
   @Override
   public void checkCanCreateTable(String userName, QualifiedObjectName 
tableName) {
+    InformationSchemaUtils.checkDBNameInWrite(tableName.getDatabaseName());
     authChecker.checkTablePrivilege(userName, tableName, 
TableModelPrivilege.CREATE);
   }
 
   @Override
   public void checkCanDropTable(String userName, QualifiedObjectName 
tableName) {
+    InformationSchemaUtils.checkDBNameInWrite(tableName.getDatabaseName());
     authChecker.checkTablePrivilege(userName, tableName, 
TableModelPrivilege.DROP);
   }
 
   @Override
   public void checkCanAlterTable(String userName, QualifiedObjectName 
tableName) {
+    InformationSchemaUtils.checkDBNameInWrite(tableName.getDatabaseName());
     authChecker.checkTablePrivilege(userName, tableName, 
TableModelPrivilege.ALTER);
   }
 
   @Override
   public void checkCanInsertIntoTable(String userName, QualifiedObjectName 
tableName) {
+    InformationSchemaUtils.checkDBNameInWrite(tableName.getDatabaseName());
     authChecker.checkTablePrivilege(userName, tableName, 
TableModelPrivilege.INSERT);
   }
 
   @Override
   public void checkCanSelectFromTable(String userName, QualifiedObjectName 
tableName) {
+    if 
(tableName.getDatabaseName().equals(InformationSchema.INFORMATION_DATABASE)) {
+      // Currently only root user can select from information schema
+      checkUserIsAdmin(userName);
+      return;
+    }
     authChecker.checkTablePrivilege(userName, tableName, 
TableModelPrivilege.SELECT);
   }
 
@@ -99,11 +118,16 @@ public class AccessControlImpl implements AccessControl {
 
   @Override
   public void checkCanDeleteFromTable(String userName, QualifiedObjectName 
tableName) {
+    InformationSchemaUtils.checkDBNameInWrite(tableName.getDatabaseName());
     authChecker.checkTablePrivilege(userName, tableName, 
TableModelPrivilege.DELETE);
   }
 
   @Override
   public void checkCanShowOrDescTable(String userName, QualifiedObjectName 
tableName) {
+    // Information_schema is visible to any user
+    if 
(tableName.getDatabaseName().equals(InformationSchema.INFORMATION_DATABASE)) {
+      return;
+    }
     authChecker.checkTableVisibility(userName, tableName);
   }
 
@@ -246,6 +270,10 @@ public class AccessControlImpl implements AccessControl {
         if (AuthorityChecker.SUPER_USER.equals(statement.getUserName())) {
           throw new AccessDeniedException("Cannot grant/revoke privileges of 
admin user");
         }
+        if 
(InformationSchema.INFORMATION_DATABASE.equals(statement.getDatabase())) {
+          throw new SemanticException(
+              "Cannot grant or revoke any privileges to information_schema");
+        }
         if (AuthorityChecker.SUPER_USER.equals(userName)) {
           return;
         }
@@ -263,6 +291,10 @@ public class AccessControlImpl implements AccessControl {
         if (AuthorityChecker.SUPER_USER.equals(statement.getUserName())) {
           throw new AccessDeniedException("Cannot grant/revoke privileges of 
admin user");
         }
+        if 
(InformationSchema.INFORMATION_DATABASE.equals(statement.getDatabase())) {
+          throw new SemanticException(
+              "Cannot grant or revoke any privileges to information_schema");
+        }
         if (AuthorityChecker.SUPER_USER.equals(userName)) {
           return;
         }
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/table/InformationSchemaUtils.java
 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/table/InformationSchemaUtils.java
index 54f5769aead..d54698b2735 100644
--- 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/table/InformationSchemaUtils.java
+++ 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/schemaengine/table/InformationSchemaUtils.java
@@ -120,6 +120,7 @@ public class InformationSchemaUtils {
       builder.getColumnBuilder(1).writeBinary(new Binary("INF", 
TSFileConfig.STRING_CHARSET));
       if (isDetails) {
         builder.getColumnBuilder(2).writeBinary(new Binary("USING", 
TSFileConfig.STRING_CHARSET));
+        builder.getColumnBuilder(3).writeBinary(new Binary("", 
TSFileConfig.STRING_CHARSET));
       }
       builder.declarePosition();
     }
@@ -171,6 +172,7 @@ public class InformationSchemaUtils {
               new Binary(columnSchema.getColumnCategory().name(), 
TSFileConfig.STRING_CHARSET));
       if (isDetails) {
         builder.getColumnBuilder(3).writeBinary(new Binary("USING", 
TSFileConfig.STRING_CHARSET));
+        builder.getColumnBuilder(4).writeBinary(new Binary("", 
TSFileConfig.STRING_CHARSET));
       }
       builder.declarePosition();
     }

Reply via email to