This is an automated email from the ASF dual-hosted git repository.

jianglongtao pushed a commit to branch fix-33341
in repository https://gitbox.apache.org/repos/asf/shardingsphere.git

commit a668c3cb401c6330d024d1b4a80447cb39043bb6
Author: RaigorJiang <[email protected]>
AuthorDate: Mon Jul 22 09:59:38 2024 +0800

    Pick #32044, Check privilege when register or alter storage unit
---
 .../core/advice/SQLParseCountAdviceTest.java       |   2 +-
 ...ion.java => StorageUnitsValidateException.java} |   8 +-
 .../DataSourcePoolPropertiesValidator.java         |  35 +++++--
 .../DataSourcePoolPropertiesValidatorTest.java     |   2 +-
 .../checker/DialectDatabaseEnvironmentChecker.java |  27 ++---
 .../database/core/checker/PrivilegeCheckType.java  |  17 +---
 .../CheckDatabaseEnvironmentFailedException.java   |  22 ++--
 .../MissingRequiredPrivilegeException.java         |  20 ++--
 .../checker/MySQLDatabaseEnvironmentChecker.java   | 112 +++++++++++++++++++++
 .../metadata/data/loader/MySQLMetaDataLoader.java  |   3 +-
 ....core.checker.DialectDatabaseEnvironmentChecker |  18 ++++
 .../rdl/resource/AlterStorageUnitExecutor.java     |  13 ++-
 .../rdl/resource/RegisterStorageUnitExecutor.java  |  11 +-
 .../DistSQLDataSourcePoolPropertiesValidator.java  |  21 +++-
 .../rdl/resource/AlterStorageUnitExecutorTest.java |   5 +-
 .../resource/RegisterStorageUnitExecutorTest.java  |   5 +-
 .../transaction/util/AutoCommitUtilsTest.java      |   9 +-
 .../engine/src/main/antlr4/imports/Keyword.g4      |   4 +
 .../engine/src/main/antlr4/imports/RDLStatement.g4 |  16 ++-
 .../core/kernel/KernelDistSQLStatementVisitor.java |  15 ++-
 .../unit/type/AlterStorageUnitStatement.java       |   2 +
 .../unit/type/RegisterStorageUnitStatement.java    |   2 +
 22 files changed, 285 insertions(+), 84 deletions(-)

diff --git 
a/agent/plugins/metrics/core/src/test/java/org/apache/shardingsphere/agent/plugin/metrics/core/advice/SQLParseCountAdviceTest.java
 
b/agent/plugins/metrics/core/src/test/java/org/apache/shardingsphere/agent/plugin/metrics/core/advice/SQLParseCountAdviceTest.java
index ffc6d334589..b6f74cb6063 100644
--- 
a/agent/plugins/metrics/core/src/test/java/org/apache/shardingsphere/agent/plugin/metrics/core/advice/SQLParseCountAdviceTest.java
+++ 
b/agent/plugins/metrics/core/src/test/java/org/apache/shardingsphere/agent/plugin/metrics/core/advice/SQLParseCountAdviceTest.java
@@ -102,7 +102,7 @@ class SQLParseCountAdviceTest {
     
     @Test
     void assertParseRDL() {
-        assertParse(new RegisterStorageUnitStatement(false, 
Collections.emptyList()), "RDL=1");
+        assertParse(new RegisterStorageUnitStatement(false, 
Collections.emptyList(), Collections.emptySet()), "RDL=1");
     }
     
     @Test
diff --git 
a/infra/common/src/main/java/org/apache/shardingsphere/infra/exception/kernel/metadata/resource/storageunit/StorageUnitsConnectException.java
 
b/infra/common/src/main/java/org/apache/shardingsphere/infra/exception/kernel/metadata/resource/storageunit/StorageUnitsValidateException.java
similarity index 82%
rename from 
infra/common/src/main/java/org/apache/shardingsphere/infra/exception/kernel/metadata/resource/storageunit/StorageUnitsConnectException.java
rename to 
infra/common/src/main/java/org/apache/shardingsphere/infra/exception/kernel/metadata/resource/storageunit/StorageUnitsValidateException.java
index 95cdd19514e..80ccacc50ab 100644
--- 
a/infra/common/src/main/java/org/apache/shardingsphere/infra/exception/kernel/metadata/resource/storageunit/StorageUnitsConnectException.java
+++ 
b/infra/common/src/main/java/org/apache/shardingsphere/infra/exception/kernel/metadata/resource/storageunit/StorageUnitsValidateException.java
@@ -24,14 +24,14 @@ import java.util.Map;
 import java.util.stream.Collectors;
 
 /**
- * Storage units connect exception.
+ * Storage units validate exception.
  */
-public final class StorageUnitsConnectException extends 
ResourceDefinitionException {
+public final class StorageUnitsValidateException extends 
ResourceDefinitionException {
     
     private static final long serialVersionUID = 1824912697040264268L;
     
-    public StorageUnitsConnectException(final Map<String, Exception> causes) {
-        super(XOpenSQLState.CONNECTION_EXCEPTION, 10, "Storage units can not 
connect, error messages are: %s.", causes.entrySet().stream().map(entry -> 
String.format(
+    public StorageUnitsValidateException(final Map<String, Exception> causes) {
+        super(XOpenSQLState.CONNECTION_EXCEPTION, 10, "Storage units validate 
error, messages are: %s.", causes.entrySet().stream().map(entry -> 
String.format(
                 "Storage unit name: '%s', error message is: %s", 
entry.getKey(), 
entry.getValue().getMessage())).collect(Collectors.joining(System.lineSeparator())));
     }
 }
diff --git 
a/infra/data-source-pool/core/src/main/java/org/apache/shardingsphere/infra/datasource/pool/props/validator/DataSourcePoolPropertiesValidator.java
 
b/infra/data-source-pool/core/src/main/java/org/apache/shardingsphere/infra/datasource/pool/props/validator/DataSourcePoolPropertiesValidator.java
index d936cb0fc10..c2ae0a408fc 100644
--- 
a/infra/data-source-pool/core/src/main/java/org/apache/shardingsphere/infra/datasource/pool/props/validator/DataSourcePoolPropertiesValidator.java
+++ 
b/infra/data-source-pool/core/src/main/java/org/apache/shardingsphere/infra/datasource/pool/props/validator/DataSourcePoolPropertiesValidator.java
@@ -19,6 +19,11 @@ package 
org.apache.shardingsphere.infra.datasource.pool.props.validator;
 
 import lombok.AccessLevel;
 import lombok.NoArgsConstructor;
+import 
org.apache.shardingsphere.infra.database.core.checker.DialectDatabaseEnvironmentChecker;
+import 
org.apache.shardingsphere.infra.database.core.checker.PrivilegeCheckType;
+import 
org.apache.shardingsphere.infra.database.core.spi.DatabaseTypedSPILoader;
+import org.apache.shardingsphere.infra.database.core.type.DatabaseType;
+import org.apache.shardingsphere.infra.database.core.type.DatabaseTypeFactory;
 import 
org.apache.shardingsphere.infra.datasource.pool.creator.DataSourcePoolCreator;
 import 
org.apache.shardingsphere.infra.datasource.pool.destroyer.DataSourcePoolDestroyer;
 import 
org.apache.shardingsphere.infra.datasource.pool.props.domain.DataSourcePoolProperties;
@@ -27,9 +32,11 @@ import 
org.apache.shardingsphere.infra.spi.type.typed.TypedSPILoader;
 import javax.sql.DataSource;
 import java.sql.Connection;
 import java.sql.SQLException;
+import java.util.Collection;
 import java.util.LinkedHashMap;
 import java.util.Map;
 import java.util.Map.Entry;
+import java.util.Optional;
 
 /**
  * Data source pool properties validator.
@@ -39,16 +46,17 @@ public final class DataSourcePoolPropertiesValidator {
     
     /**
      * Validate data source pool properties map.
-     * 
+     *
      * @param propsMap data source pool properties map
+     * @param expectedPrivileges excepted privileges
      * @return data source name and exception map
      */
-    public static Map<String, Exception> validate(final Map<String, 
DataSourcePoolProperties> propsMap) {
-        Map<String, Exception> result = new LinkedHashMap<>();
+    public static Map<String, Exception> validate(final Map<String, 
DataSourcePoolProperties> propsMap, final Collection<PrivilegeCheckType> 
expectedPrivileges) {
+        Map<String, Exception> result = new LinkedHashMap<>(propsMap.size(), 
1F);
         for (Entry<String, DataSourcePoolProperties> entry : 
propsMap.entrySet()) {
             try {
                 validateProperties(entry.getKey(), entry.getValue());
-                validateConnection(entry.getKey(), entry.getValue());
+                validateConnection(entry.getKey(), entry.getValue(), 
expectedPrivileges);
             } catch (final InvalidDataSourcePoolPropertiesException ex) {
                 result.put(entry.getKey(), ex);
             }
@@ -64,11 +72,16 @@ public final class DataSourcePoolPropertiesValidator {
         }
     }
     
-    private static void validateConnection(final String dataSourceName, final 
DataSourcePoolProperties props) throws InvalidDataSourcePoolPropertiesException 
{
+    private static void validateConnection(final String dataSourceName, final 
DataSourcePoolProperties props,
+                                           final 
Collection<PrivilegeCheckType> expectedPrivileges) throws 
InvalidDataSourcePoolPropertiesException {
         DataSource dataSource = null;
         try {
             dataSource = DataSourcePoolCreator.create(props);
-            checkFailFast(dataSource);
+            if (expectedPrivileges.isEmpty() || 
expectedPrivileges.contains(PrivilegeCheckType.NONE)) {
+                checkFailFast(dataSource);
+                return;
+            }
+            checkPrivileges(dataSource, props, expectedPrivileges);
             // CHECKSTYLE:OFF
         } catch (final SQLException | RuntimeException ex) {
             // CHECKSTYLE:ON
@@ -87,4 +100,14 @@ public final class DataSourcePoolPropertiesValidator {
             // CHECKSTYLE:ON
         }
     }
+    
+    private static void checkPrivileges(final DataSource dataSource, final 
DataSourcePoolProperties props, final Collection<PrivilegeCheckType> 
expectedPrivileges) {
+        DatabaseType databaseType = DatabaseTypeFactory.get((String) 
props.getConnectionPropertySynonyms().getStandardProperties().get("url"));
+        Optional<DialectDatabaseEnvironmentChecker> checker = 
DatabaseTypedSPILoader.findService(DialectDatabaseEnvironmentChecker.class, 
databaseType);
+        if (checker.isPresent()) {
+            for (PrivilegeCheckType each : expectedPrivileges) {
+                checker.get().checkPrivilege(dataSource, each);
+            }
+        }
+    }
 }
diff --git 
a/infra/data-source-pool/core/src/test/java/org/apache/shardingsphere/infra/datasource/pool/props/validator/DataSourcePoolPropertiesValidatorTest.java
 
b/infra/data-source-pool/core/src/test/java/org/apache/shardingsphere/infra/datasource/pool/props/validator/DataSourcePoolPropertiesValidatorTest.java
index 548c50901f8..cdbaae15bff 100644
--- 
a/infra/data-source-pool/core/src/test/java/org/apache/shardingsphere/infra/datasource/pool/props/validator/DataSourcePoolPropertiesValidatorTest.java
+++ 
b/infra/data-source-pool/core/src/test/java/org/apache/shardingsphere/infra/datasource/pool/props/validator/DataSourcePoolPropertiesValidatorTest.java
@@ -37,6 +37,6 @@ class DataSourcePoolPropertiesValidatorTest {
     @Test
     void assertValidate() {
         assertTrue(DataSourcePoolPropertiesValidator.validate(
-                Collections.singletonMap("name", new 
DataSourcePoolProperties(HikariDataSource.class.getName(), 
Collections.singletonMap("jdbcUrl", "jdbc:mock")))).isEmpty());
+                Collections.singletonMap("name", new 
DataSourcePoolProperties(HikariDataSource.class.getName(), 
Collections.singletonMap("jdbcUrl", "jdbc:mock"))), 
Collections.emptySet()).isEmpty());
     }
 }
diff --git 
a/parser/distsql/statement/src/main/java/org/apache/shardingsphere/distsql/statement/rdl/resource/unit/type/RegisterStorageUnitStatement.java
 
b/infra/database/core/src/main/java/org/apache/shardingsphere/infra/database/core/checker/DialectDatabaseEnvironmentChecker.java
similarity index 57%
copy from 
parser/distsql/statement/src/main/java/org/apache/shardingsphere/distsql/statement/rdl/resource/unit/type/RegisterStorageUnitStatement.java
copy to 
infra/database/core/src/main/java/org/apache/shardingsphere/infra/database/core/checker/DialectDatabaseEnvironmentChecker.java
index 84795ad9340..84cc9724e19 100644
--- 
a/parser/distsql/statement/src/main/java/org/apache/shardingsphere/distsql/statement/rdl/resource/unit/type/RegisterStorageUnitStatement.java
+++ 
b/infra/database/core/src/main/java/org/apache/shardingsphere/infra/database/core/checker/DialectDatabaseEnvironmentChecker.java
@@ -15,23 +15,24 @@
  * limitations under the License.
  */
 
-package org.apache.shardingsphere.distsql.statement.rdl.resource.unit.type;
+package org.apache.shardingsphere.infra.database.core.checker;
 
-import lombok.Getter;
-import lombok.RequiredArgsConstructor;
-import org.apache.shardingsphere.distsql.segment.DataSourceSegment;
-import 
org.apache.shardingsphere.distsql.statement.rdl.resource.unit.StorageUnitDefinitionStatement;
+import org.apache.shardingsphere.infra.database.core.spi.DatabaseTypedSPI;
+import org.apache.shardingsphere.infra.spi.annotation.SingletonSPI;
 
-import java.util.Collection;
+import javax.sql.DataSource;
 
 /**
- * Register storage unit statement.
+ * Dialect database environment checker.
  */
-@RequiredArgsConstructor
-@Getter
-public final class RegisterStorageUnitStatement extends 
StorageUnitDefinitionStatement {
+@SingletonSPI
+public interface DialectDatabaseEnvironmentChecker extends DatabaseTypedSPI {
     
-    private final boolean ifNotExists;
-    
-    private final Collection<DataSourceSegment> storageUnits;
+    /**
+     * Check user privileges.
+     *
+     * @param dataSource data source to be checked
+     * @param privilegeCheckType privilege check type
+     */
+    void checkPrivilege(DataSource dataSource, PrivilegeCheckType 
privilegeCheckType);
 }
diff --git 
a/parser/distsql/statement/src/main/java/org/apache/shardingsphere/distsql/statement/rdl/resource/unit/type/AlterStorageUnitStatement.java
 
b/infra/database/core/src/main/java/org/apache/shardingsphere/infra/database/core/checker/PrivilegeCheckType.java
similarity index 59%
copy from 
parser/distsql/statement/src/main/java/org/apache/shardingsphere/distsql/statement/rdl/resource/unit/type/AlterStorageUnitStatement.java
copy to 
infra/database/core/src/main/java/org/apache/shardingsphere/infra/database/core/checker/PrivilegeCheckType.java
index 7a26c867c4d..8ce96c4b468 100644
--- 
a/parser/distsql/statement/src/main/java/org/apache/shardingsphere/distsql/statement/rdl/resource/unit/type/AlterStorageUnitStatement.java
+++ 
b/infra/database/core/src/main/java/org/apache/shardingsphere/infra/database/core/checker/PrivilegeCheckType.java
@@ -15,21 +15,12 @@
  * limitations under the License.
  */
 
-package org.apache.shardingsphere.distsql.statement.rdl.resource.unit.type;
-
-import lombok.Getter;
-import lombok.RequiredArgsConstructor;
-import org.apache.shardingsphere.distsql.segment.DataSourceSegment;
-import 
org.apache.shardingsphere.distsql.statement.rdl.resource.unit.StorageUnitDefinitionStatement;
-
-import java.util.Collection;
+package org.apache.shardingsphere.infra.database.core.checker;
 
 /**
- * Alter storage unit statement.
+ * Privilege check type.
  */
-@RequiredArgsConstructor
-@Getter
-public final class AlterStorageUnitStatement extends 
StorageUnitDefinitionStatement {
+public enum PrivilegeCheckType {
     
-    private final Collection<DataSourceSegment> storageUnits;
+    NONE, PIPELINE, SELECT, XA
 }
diff --git 
a/parser/distsql/statement/src/main/java/org/apache/shardingsphere/distsql/statement/rdl/resource/unit/type/RegisterStorageUnitStatement.java
 
b/infra/database/core/src/main/java/org/apache/shardingsphere/infra/database/core/exception/CheckDatabaseEnvironmentFailedException.java
similarity index 54%
copy from 
parser/distsql/statement/src/main/java/org/apache/shardingsphere/distsql/statement/rdl/resource/unit/type/RegisterStorageUnitStatement.java
copy to 
infra/database/core/src/main/java/org/apache/shardingsphere/infra/database/core/exception/CheckDatabaseEnvironmentFailedException.java
index 84795ad9340..ffa2387a35d 100644
--- 
a/parser/distsql/statement/src/main/java/org/apache/shardingsphere/distsql/statement/rdl/resource/unit/type/RegisterStorageUnitStatement.java
+++ 
b/infra/database/core/src/main/java/org/apache/shardingsphere/infra/database/core/exception/CheckDatabaseEnvironmentFailedException.java
@@ -15,23 +15,21 @@
  * limitations under the License.
  */
 
-package org.apache.shardingsphere.distsql.statement.rdl.resource.unit.type;
+package org.apache.shardingsphere.infra.database.core.exception;
 
-import lombok.Getter;
-import lombok.RequiredArgsConstructor;
-import org.apache.shardingsphere.distsql.segment.DataSourceSegment;
-import 
org.apache.shardingsphere.distsql.statement.rdl.resource.unit.StorageUnitDefinitionStatement;
+import 
org.apache.shardingsphere.infra.exception.core.external.sql.sqlstate.XOpenSQLState;
+import 
org.apache.shardingsphere.infra.exception.core.external.sql.type.kernel.category.MetaDataSQLException;
 
-import java.util.Collection;
+import java.sql.SQLException;
 
 /**
- * Register storage unit statement.
+ * Check database environment failed exception.
  */
-@RequiredArgsConstructor
-@Getter
-public final class RegisterStorageUnitStatement extends 
StorageUnitDefinitionStatement {
+public final class CheckDatabaseEnvironmentFailedException extends 
MetaDataSQLException {
     
-    private final boolean ifNotExists;
+    private static final long serialVersionUID = 3913140870320566898L;
     
-    private final Collection<DataSourceSegment> storageUnits;
+    public CheckDatabaseEnvironmentFailedException(final SQLException cause) {
+        super(XOpenSQLState.CONNECTION_EXCEPTION, 5, "Check database 
environment failed", cause);
+    }
 }
diff --git 
a/parser/distsql/statement/src/main/java/org/apache/shardingsphere/distsql/statement/rdl/resource/unit/type/RegisterStorageUnitStatement.java
 
b/infra/database/core/src/main/java/org/apache/shardingsphere/infra/database/core/exception/MissingRequiredPrivilegeException.java
similarity index 56%
copy from 
parser/distsql/statement/src/main/java/org/apache/shardingsphere/distsql/statement/rdl/resource/unit/type/RegisterStorageUnitStatement.java
copy to 
infra/database/core/src/main/java/org/apache/shardingsphere/infra/database/core/exception/MissingRequiredPrivilegeException.java
index 84795ad9340..0acc5b92c75 100644
--- 
a/parser/distsql/statement/src/main/java/org/apache/shardingsphere/distsql/statement/rdl/resource/unit/type/RegisterStorageUnitStatement.java
+++ 
b/infra/database/core/src/main/java/org/apache/shardingsphere/infra/database/core/exception/MissingRequiredPrivilegeException.java
@@ -15,23 +15,21 @@
  * limitations under the License.
  */
 
-package org.apache.shardingsphere.distsql.statement.rdl.resource.unit.type;
+package org.apache.shardingsphere.infra.database.core.exception;
 
-import lombok.Getter;
-import lombok.RequiredArgsConstructor;
-import org.apache.shardingsphere.distsql.segment.DataSourceSegment;
-import 
org.apache.shardingsphere.distsql.statement.rdl.resource.unit.StorageUnitDefinitionStatement;
+import 
org.apache.shardingsphere.infra.exception.core.external.sql.sqlstate.XOpenSQLState;
+import 
org.apache.shardingsphere.infra.exception.core.external.sql.type.kernel.category.MetaDataSQLException;
 
 import java.util.Collection;
 
 /**
- * Register storage unit statement.
+ * Missing required privilege exception.
  */
-@RequiredArgsConstructor
-@Getter
-public final class RegisterStorageUnitStatement extends 
StorageUnitDefinitionStatement {
+public final class MissingRequiredPrivilegeException extends 
MetaDataSQLException {
     
-    private final boolean ifNotExists;
+    private static final long serialVersionUID = 3755362278200749857L;
     
-    private final Collection<DataSourceSegment> storageUnits;
+    public MissingRequiredPrivilegeException(final Collection<String> 
privileges) {
+        super(XOpenSQLState.PRIVILEGE_NOT_GRANTED, 6, "Missing required 
privilege(s) `%s`", privileges);
+    }
 }
diff --git 
a/infra/database/type/mysql/src/main/java/org/apache/shardingsphere/infra/database/mysql/checker/MySQLDatabaseEnvironmentChecker.java
 
b/infra/database/type/mysql/src/main/java/org/apache/shardingsphere/infra/database/mysql/checker/MySQLDatabaseEnvironmentChecker.java
new file mode 100644
index 00000000000..358071b6a3d
--- /dev/null
+++ 
b/infra/database/type/mysql/src/main/java/org/apache/shardingsphere/infra/database/mysql/checker/MySQLDatabaseEnvironmentChecker.java
@@ -0,0 +1,112 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.infra.database.mysql.checker;
+
+import 
org.apache.shardingsphere.infra.database.core.checker.DialectDatabaseEnvironmentChecker;
+import 
org.apache.shardingsphere.infra.database.core.checker.PrivilegeCheckType;
+import 
org.apache.shardingsphere.infra.database.core.exception.CheckDatabaseEnvironmentFailedException;
+import 
org.apache.shardingsphere.infra.database.core.exception.MissingRequiredPrivilegeException;
+
+import javax.sql.DataSource;
+import java.sql.Connection;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.EnumMap;
+import java.util.Map;
+
+/**
+ * Database environment checker for MySQL.
+ */
+public final class MySQLDatabaseEnvironmentChecker implements 
DialectDatabaseEnvironmentChecker {
+    
+    private static final String SHOW_GRANTS_SQL = "SHOW GRANTS";
+    
+    private static final int MYSQL_MAJOR_VERSION_8 = 8;
+    
+    // BINLOG MONITOR is a synonym for REPLICATION CLIENT for MariaDB
+    private static final String[][] PIPELINE_REQUIRED_PRIVILEGES =
+            {{"ALL PRIVILEGES", "ON *.*"}, {"REPLICATION SLAVE", "REPLICATION 
CLIENT", "ON *.*"}, {"REPLICATION SLAVE", "BINLOG MONITOR", "ON *.*"}};
+    
+    private static final String[][] XA_REQUIRED_PRIVILEGES = {{"ALL 
PRIVILEGES", "ON *.*"}, {"XA_RECOVER_ADMIN", "ON *.*"}};
+    
+    private static final Map<PrivilegeCheckType, Collection<String>> 
REQUIRED_PRIVILEGES_FOR_MESSAGE = new EnumMap<>(PrivilegeCheckType.class);
+    
+    static {
+        REQUIRED_PRIVILEGES_FOR_MESSAGE.put(PrivilegeCheckType.PIPELINE, 
Arrays.asList("REPLICATION SLAVE", "REPLICATION CLIENT"));
+        REQUIRED_PRIVILEGES_FOR_MESSAGE.put(PrivilegeCheckType.SELECT, 
Collections.singleton("SELECT ON DATABASE"));
+        REQUIRED_PRIVILEGES_FOR_MESSAGE.put(PrivilegeCheckType.XA, 
Collections.singleton("XA_RECOVER_ADMIN"));
+    }
+    
+    @Override
+    public void checkPrivilege(final DataSource dataSource, final 
PrivilegeCheckType privilegeCheckType) {
+        try (Connection connection = dataSource.getConnection()) {
+            if (PrivilegeCheckType.XA == privilegeCheckType && 
MYSQL_MAJOR_VERSION_8 != connection.getMetaData().getDatabaseMajorVersion()) {
+                return;
+            }
+            checkPrivilege(connection, privilegeCheckType);
+        } catch (final SQLException ex) {
+            throw new CheckDatabaseEnvironmentFailedException(ex);
+        }
+    }
+    
+    private void checkPrivilege(final Connection connection, final 
PrivilegeCheckType privilegeCheckType) {
+        try (
+                PreparedStatement preparedStatement = 
connection.prepareStatement(SHOW_GRANTS_SQL);
+                ResultSet resultSet = preparedStatement.executeQuery()) {
+            while (resultSet.next()) {
+                String privilege = resultSet.getString(1).toUpperCase();
+                if (matchPrivileges(privilege, 
getRequiredPrivileges(connection, privilegeCheckType))) {
+                    return;
+                }
+            }
+        } catch (final SQLException ex) {
+            throw new CheckDatabaseEnvironmentFailedException(ex);
+        }
+        throw new 
MissingRequiredPrivilegeException(REQUIRED_PRIVILEGES_FOR_MESSAGE.get(privilegeCheckType));
+    }
+    
+    private String[][] getRequiredPrivileges(final Connection connection, 
final PrivilegeCheckType privilegeCheckType) throws SQLException {
+        switch (privilegeCheckType) {
+            case PIPELINE:
+                return PIPELINE_REQUIRED_PRIVILEGES;
+            case SELECT:
+                return getSelectRequiredPrivilege(connection);
+            case XA:
+                return XA_REQUIRED_PRIVILEGES;
+            default:
+                return new String[0][0];
+        }
+    }
+    
+    private String[][] getSelectRequiredPrivilege(final Connection connection) 
throws SQLException {
+        return new String[][]{{"ALL PRIVILEGES", "ON *.*"}, {"SELECT", "ON 
*.*"}, {"SELECT", String.format("ON `%s`.*", 
connection.getCatalog()).toUpperCase()}};
+    }
+    
+    private boolean matchPrivileges(final String grantedPrivileges, final 
String[][] requiredPrivileges) {
+        return Arrays.stream(requiredPrivileges).anyMatch(each -> 
Arrays.stream(each).allMatch(grantedPrivileges::contains));
+    }
+    
+    @Override
+    public String getDatabaseType() {
+        return "MySQL";
+    }
+}
diff --git 
a/infra/database/type/mysql/src/main/java/org/apache/shardingsphere/infra/database/mysql/metadata/data/loader/MySQLMetaDataLoader.java
 
b/infra/database/type/mysql/src/main/java/org/apache/shardingsphere/infra/database/mysql/metadata/data/loader/MySQLMetaDataLoader.java
index 223d712d939..748f04d32cf 100644
--- 
a/infra/database/type/mysql/src/main/java/org/apache/shardingsphere/infra/database/mysql/metadata/data/loader/MySQLMetaDataLoader.java
+++ 
b/infra/database/type/mysql/src/main/java/org/apache/shardingsphere/infra/database/mysql/metadata/data/loader/MySQLMetaDataLoader.java
@@ -69,8 +69,7 @@ public final class MySQLMetaDataLoader implements 
DialectMetaDataLoader {
     public Collection<SchemaMetaData> load(final MetaDataLoaderMaterial 
material) throws SQLException {
         Collection<TableMetaData> tableMetaDataList = new LinkedList<>();
         Map<String, Collection<ColumnMetaData>> columnMetaDataMap = 
loadColumnMetaDataMap(material.getDataSource(), material.getActualTableNames());
-        Collection<String> viewNames = loadViewNames(material.getDataSource(), 
columnMetaDataMap.keySet());
-        Map<String, Collection<IndexMetaData>> indexMetaDataMap = 
columnMetaDataMap.isEmpty() ? Collections.emptyMap() : 
loadIndexMetaData(material.getDataSource(), columnMetaDataMap.keySet());
+        Collection<String> viewNames = columnMetaDataMap.isEmpty() ? 
Collections.emptySet() : loadViewNames(material.getDataSource(), 
columnMetaDataMap.keySet());        Map<String, Collection<IndexMetaData>> 
indexMetaDataMap = columnMetaDataMap.isEmpty() ? Collections.emptyMap() : 
loadIndexMetaData(material.getDataSource(), columnMetaDataMap.keySet());
         Map<String, Collection<ConstraintMetaData>> constraintMetaDataMap =
                 columnMetaDataMap.isEmpty() ? Collections.emptyMap() : 
loadConstraintMetaDataMap(material.getDataSource(), columnMetaDataMap.keySet());
         for (Entry<String, Collection<ColumnMetaData>> entry : 
columnMetaDataMap.entrySet()) {
diff --git 
a/infra/database/type/mysql/src/main/resources/META-INF/services/org.apache.shardingsphere.infra.database.core.checker.DialectDatabaseEnvironmentChecker
 
b/infra/database/type/mysql/src/main/resources/META-INF/services/org.apache.shardingsphere.infra.database.core.checker.DialectDatabaseEnvironmentChecker
new file mode 100644
index 00000000000..631900c3ccc
--- /dev/null
+++ 
b/infra/database/type/mysql/src/main/resources/META-INF/services/org.apache.shardingsphere.infra.database.core.checker.DialectDatabaseEnvironmentChecker
@@ -0,0 +1,18 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements.  See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License.  You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+org.apache.shardingsphere.infra.database.mysql.checker.MySQLDatabaseEnvironmentChecker
diff --git 
a/infra/distsql-handler/src/main/java/org/apache/shardingsphere/distsql/handler/executor/rdl/resource/AlterStorageUnitExecutor.java
 
b/infra/distsql-handler/src/main/java/org/apache/shardingsphere/distsql/handler/executor/rdl/resource/AlterStorageUnitExecutor.java
index 4f70b7c0e49..11f5fabffcf 100644
--- 
a/infra/distsql-handler/src/main/java/org/apache/shardingsphere/distsql/handler/executor/rdl/resource/AlterStorageUnitExecutor.java
+++ 
b/infra/distsql-handler/src/main/java/org/apache/shardingsphere/distsql/handler/executor/rdl/resource/AlterStorageUnitExecutor.java
@@ -27,6 +27,7 @@ import 
org.apache.shardingsphere.distsql.segment.HostnameAndPortBasedDataSourceS
 import org.apache.shardingsphere.distsql.segment.URLBasedDataSourceSegment;
 import 
org.apache.shardingsphere.distsql.segment.converter.DataSourceSegmentsConverter;
 import 
org.apache.shardingsphere.distsql.statement.rdl.resource.unit.type.AlterStorageUnitStatement;
+import 
org.apache.shardingsphere.infra.database.core.checker.PrivilegeCheckType;
 import 
org.apache.shardingsphere.infra.database.core.connector.ConnectionProperties;
 import org.apache.shardingsphere.infra.database.core.connector.url.JdbcUrl;
 import 
org.apache.shardingsphere.infra.database.core.connector.url.StandardJdbcUrlParser;
@@ -35,8 +36,8 @@ import 
org.apache.shardingsphere.infra.exception.core.ShardingSpherePrecondition
 import 
org.apache.shardingsphere.infra.exception.core.external.ShardingSphereExternalException;
 import 
org.apache.shardingsphere.infra.exception.kernel.metadata.resource.storageunit.AlterStorageUnitConnectionInfoException;
 import 
org.apache.shardingsphere.infra.exception.kernel.metadata.resource.storageunit.DuplicateStorageUnitException;
-import 
org.apache.shardingsphere.infra.exception.kernel.metadata.resource.storageunit.StorageUnitsOperateException;
 import 
org.apache.shardingsphere.infra.exception.kernel.metadata.resource.storageunit.MissingRequiredStorageUnitsException;
+import 
org.apache.shardingsphere.infra.exception.kernel.metadata.resource.storageunit.StorageUnitsOperateException;
 import 
org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase;
 import 
org.apache.shardingsphere.infra.metadata.database.resource.unit.StorageUnit;
 import org.apache.shardingsphere.mode.manager.ContextManager;
@@ -63,7 +64,7 @@ public final class AlterStorageUnitExecutor implements 
DistSQLUpdateExecutor<Alt
     public void executeUpdate(final AlterStorageUnitStatement sqlStatement, 
final ContextManager contextManager) {
         checkBefore(sqlStatement);
         Map<String, DataSourcePoolProperties> propsMap = 
DataSourceSegmentsConverter.convert(database.getProtocolType(), 
sqlStatement.getStorageUnits());
-        validateHandler.validate(propsMap);
+        validateHandler.validate(propsMap, 
getExpectedPrivileges(sqlStatement));
         try {
             
contextManager.getInstanceContext().getModeContextManager().alterStorageUnits(database.getName(),
 propsMap);
         } catch (final SQLException | ShardingSphereExternalException ex) {
@@ -112,6 +113,14 @@ public final class AlterStorageUnitExecutor implements 
DistSQLUpdateExecutor<Alt
         return Objects.equals(hostName, connectionProps.getHostname()) && 
Objects.equals(port, String.valueOf(connectionProps.getPort())) && 
Objects.equals(database, connectionProps.getCatalog());
     }
     
+    private Collection<PrivilegeCheckType> getExpectedPrivileges(final 
AlterStorageUnitStatement sqlStatement) {
+        Collection<PrivilegeCheckType> result = 
sqlStatement.getExpectedPrivileges().stream().map(each -> 
PrivilegeCheckType.valueOf(each.toUpperCase())).collect(Collectors.toSet());
+        if (result.isEmpty()) {
+            result.add(PrivilegeCheckType.SELECT);
+        }
+        return result;
+    }
+    
     @Override
     public Class<AlterStorageUnitStatement> getType() {
         return AlterStorageUnitStatement.class;
diff --git 
a/infra/distsql-handler/src/main/java/org/apache/shardingsphere/distsql/handler/executor/rdl/resource/RegisterStorageUnitExecutor.java
 
b/infra/distsql-handler/src/main/java/org/apache/shardingsphere/distsql/handler/executor/rdl/resource/RegisterStorageUnitExecutor.java
index 3b4e820b969..f343abba791 100644
--- 
a/infra/distsql-handler/src/main/java/org/apache/shardingsphere/distsql/handler/executor/rdl/resource/RegisterStorageUnitExecutor.java
+++ 
b/infra/distsql-handler/src/main/java/org/apache/shardingsphere/distsql/handler/executor/rdl/resource/RegisterStorageUnitExecutor.java
@@ -25,6 +25,7 @@ import 
org.apache.shardingsphere.distsql.handler.validate.DistSQLDataSourcePoolP
 import org.apache.shardingsphere.distsql.segment.DataSourceSegment;
 import 
org.apache.shardingsphere.distsql.segment.converter.DataSourceSegmentsConverter;
 import 
org.apache.shardingsphere.distsql.statement.rdl.resource.unit.type.RegisterStorageUnitStatement;
+import 
org.apache.shardingsphere.infra.database.core.checker.PrivilegeCheckType;
 import 
org.apache.shardingsphere.infra.datasource.pool.props.domain.DataSourcePoolProperties;
 import 
org.apache.shardingsphere.infra.exception.core.ShardingSpherePreconditions;
 import 
org.apache.shardingsphere.infra.exception.core.external.ShardingSphereExternalException;
@@ -65,7 +66,7 @@ public final class RegisterStorageUnitExecutor implements 
DistSQLUpdateExecutor<
         if (propsMap.isEmpty()) {
             return;
         }
-        validateHandler.validate(propsMap);
+        validateHandler.validate(propsMap, 
getExpectedPrivileges(sqlStatement));
         try {
             
contextManager.getInstanceContext().getModeContextManager().registerStorageUnits(database.getName(),
 propsMap);
         } catch (final SQLException | ShardingSphereExternalException ex) {
@@ -109,6 +110,14 @@ public final class RegisterStorageUnitExecutor implements 
DistSQLUpdateExecutor<
         return 
database.getRuleMetaData().getAttributes(DataSourceMapperRuleAttribute.class).stream().flatMap(each
 -> each.getDataSourceMapper().keySet().stream()).collect(Collectors.toList());
     }
     
+    private Collection<PrivilegeCheckType> getExpectedPrivileges(final 
RegisterStorageUnitStatement sqlStatement) {
+        Collection<PrivilegeCheckType> result = 
sqlStatement.getExpectedPrivileges().stream().map(each -> 
PrivilegeCheckType.valueOf(each.toUpperCase())).collect(Collectors.toSet());
+        if (result.isEmpty()) {
+            result.add(PrivilegeCheckType.SELECT);
+        }
+        return result;
+    }
+    
     @Override
     public Class<RegisterStorageUnitStatement> getType() {
         return RegisterStorageUnitStatement.class;
diff --git 
a/infra/distsql-handler/src/main/java/org/apache/shardingsphere/distsql/handler/validate/DistSQLDataSourcePoolPropertiesValidator.java
 
b/infra/distsql-handler/src/main/java/org/apache/shardingsphere/distsql/handler/validate/DistSQLDataSourcePoolPropertiesValidator.java
index 55e755c69e0..8c1f9ecfd08 100644
--- 
a/infra/distsql-handler/src/main/java/org/apache/shardingsphere/distsql/handler/validate/DistSQLDataSourcePoolPropertiesValidator.java
+++ 
b/infra/distsql-handler/src/main/java/org/apache/shardingsphere/distsql/handler/validate/DistSQLDataSourcePoolPropertiesValidator.java
@@ -17,11 +17,14 @@
 
 package org.apache.shardingsphere.distsql.handler.validate;
 
+import 
org.apache.shardingsphere.infra.database.core.checker.PrivilegeCheckType;
 import 
org.apache.shardingsphere.infra.datasource.pool.props.domain.DataSourcePoolProperties;
 import 
org.apache.shardingsphere.infra.datasource.pool.props.validator.DataSourcePoolPropertiesValidator;
 import 
org.apache.shardingsphere.infra.exception.core.ShardingSpherePreconditions;
-import 
org.apache.shardingsphere.infra.exception.kernel.metadata.resource.storageunit.StorageUnitsConnectException;
+import 
org.apache.shardingsphere.infra.exception.kernel.metadata.resource.storageunit.StorageUnitsValidateException;
 
+import java.util.Collection;
+import java.util.Collections;
 import java.util.Map;
 
 /**
@@ -31,11 +34,21 @@ public final class DistSQLDataSourcePoolPropertiesValidator 
{
     
     /**
      * Validate data source properties map.
-     * 
+     *
      * @param propsMap data source pool properties map
      */
     public void validate(final Map<String, DataSourcePoolProperties> propsMap) 
{
-        Map<String, Exception> exceptions = 
DataSourcePoolPropertiesValidator.validate(propsMap);
-        ShardingSpherePreconditions.checkState(exceptions.isEmpty(), () -> new 
StorageUnitsConnectException(exceptions));
+        validate(propsMap, Collections.emptySet());
+    }
+    
+    /**
+     * Validate data source properties map.
+     *
+     * @param propsMap data source pool properties map
+     * @param expectedPrivileges expected privileges
+     */
+    public void validate(final Map<String, DataSourcePoolProperties> propsMap, 
final Collection<PrivilegeCheckType> expectedPrivileges) {
+        Map<String, Exception> exceptions = 
DataSourcePoolPropertiesValidator.validate(propsMap, expectedPrivileges);
+        ShardingSpherePreconditions.checkState(exceptions.isEmpty(), () -> new 
StorageUnitsValidateException(exceptions));
     }
 }
diff --git 
a/infra/distsql-handler/src/test/java/org/apache/shardingsphere/distsql/handler/executor/rdl/resource/AlterStorageUnitExecutorTest.java
 
b/infra/distsql-handler/src/test/java/org/apache/shardingsphere/distsql/handler/executor/rdl/resource/AlterStorageUnitExecutorTest.java
index 1d2a5f9c46c..c9c47ae891d 100644
--- 
a/infra/distsql-handler/src/test/java/org/apache/shardingsphere/distsql/handler/executor/rdl/resource/AlterStorageUnitExecutorTest.java
+++ 
b/infra/distsql-handler/src/test/java/org/apache/shardingsphere/distsql/handler/executor/rdl/resource/AlterStorageUnitExecutorTest.java
@@ -103,13 +103,14 @@ class AlterStorageUnitExecutorTest {
     }
     
     private AlterStorageUnitStatement createAlterStorageUnitStatement(final 
String resourceName) {
-        return new AlterStorageUnitStatement(Collections.singleton(new 
URLBasedDataSourceSegment(resourceName, "jdbc:mysql://127.0.0.1:3306/ds_0", 
"root", "", new Properties())));
+        return new AlterStorageUnitStatement(Collections.singleton(new 
URLBasedDataSourceSegment(resourceName, "jdbc:mysql://127.0.0.1:3306/ds_0", 
"root", "", new Properties())),
+                Collections.emptySet());
     }
     
     private AlterStorageUnitStatement 
createAlterStorageUnitStatementWithDuplicateStorageUnitNames() {
         return new AlterStorageUnitStatement(Arrays.asList(
                 new HostnameAndPortBasedDataSourceSegment("ds_0", "127.0.0.1", 
"3306", "ds_0", "root", "", new Properties()),
-                new URLBasedDataSourceSegment("ds_0", 
"jdbc:mysql://127.0.0.1:3306/ds_1", "root", "", new Properties())));
+                new URLBasedDataSourceSegment("ds_0", 
"jdbc:mysql://127.0.0.1:3306/ds_1", "root", "", new Properties())), 
Collections.emptySet());
     }
     
     private ConnectionProperties mockConnectionProperties(final String 
catalog) {
diff --git 
a/infra/distsql-handler/src/test/java/org/apache/shardingsphere/distsql/handler/executor/rdl/resource/RegisterStorageUnitExecutorTest.java
 
b/infra/distsql-handler/src/test/java/org/apache/shardingsphere/distsql/handler/executor/rdl/resource/RegisterStorageUnitExecutorTest.java
index fffdbfe5a3f..e06efe08be8 100644
--- 
a/infra/distsql-handler/src/test/java/org/apache/shardingsphere/distsql/handler/executor/rdl/resource/RegisterStorageUnitExecutorTest.java
+++ 
b/infra/distsql-handler/src/test/java/org/apache/shardingsphere/distsql/handler/executor/rdl/resource/RegisterStorageUnitExecutorTest.java
@@ -91,12 +91,13 @@ class RegisterStorageUnitExecutorTest {
     }
     
     private RegisterStorageUnitStatement createRegisterStorageUnitStatement() {
-        return new RegisterStorageUnitStatement(false, 
Collections.singleton(new URLBasedDataSourceSegment("ds_0", 
"jdbc:mysql://127.0.0.1:3306/test0", "root", "", new Properties())));
+        return new RegisterStorageUnitStatement(false, 
Collections.singleton(new URLBasedDataSourceSegment("ds_0", 
"jdbc:mysql://127.0.0.1:3306/test0", "root", "", new Properties())),
+                Collections.emptySet());
     }
     
     private RegisterStorageUnitStatement 
createRegisterStorageUnitStatementWithDuplicateStorageUnitNames() {
         return new RegisterStorageUnitStatement(false, Arrays.asList(
                 new HostnameAndPortBasedDataSourceSegment("ds_0", "127.0.0.1", 
"3306", "ds_0", "root", "", new Properties()),
-                new URLBasedDataSourceSegment("ds_0", 
"jdbc:mysql://127.0.0.1:3306/ds_1", "root", "", new Properties())));
+                new URLBasedDataSourceSegment("ds_0", 
"jdbc:mysql://127.0.0.1:3306/ds_1", "root", "", new Properties())), 
Collections.emptySet());
     }
 }
diff --git 
a/kernel/transaction/core/src/test/java/org/apache/shardingsphere/transaction/util/AutoCommitUtilsTest.java
 
b/kernel/transaction/core/src/test/java/org/apache/shardingsphere/transaction/util/AutoCommitUtilsTest.java
index 151f4aa73af..6cd7b6fcba6 100644
--- 
a/kernel/transaction/core/src/test/java/org/apache/shardingsphere/transaction/util/AutoCommitUtilsTest.java
+++ 
b/kernel/transaction/core/src/test/java/org/apache/shardingsphere/transaction/util/AutoCommitUtilsTest.java
@@ -19,18 +19,15 @@ package org.apache.shardingsphere.transaction.util;
 
 import 
org.apache.shardingsphere.distsql.statement.rdl.resource.unit.type.RegisterStorageUnitStatement;
 import 
org.apache.shardingsphere.sql.parser.sql.common.segment.generic.table.SimpleTableSegment;
-import 
org.apache.shardingsphere.sql.parser.sql.common.segment.generic.table.TableNameSegment;
 import 
org.apache.shardingsphere.sql.parser.sql.common.statement.dml.SelectStatement;
-import 
org.apache.shardingsphere.sql.parser.sql.common.value.identifier.IdentifierValue;
 import 
org.apache.shardingsphere.sql.parser.sql.dialect.statement.mysql.ddl.MySQLCreateTableStatement;
 import 
org.apache.shardingsphere.sql.parser.sql.dialect.statement.mysql.dml.MySQLInsertStatement;
 import 
org.apache.shardingsphere.sql.parser.sql.dialect.statement.mysql.dml.MySQLSelectStatement;
 import org.junit.jupiter.api.Test;
 
-import java.util.LinkedList;
-
 import static org.junit.jupiter.api.Assertions.assertFalse;
 import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.mockito.Mockito.mock;
 
 class AutoCommitUtilsTest {
     
@@ -38,7 +35,7 @@ class AutoCommitUtilsTest {
     void assertNeedOpenTransactionForSelectStatement() {
         SelectStatement selectStatement = new MySQLSelectStatement();
         assertFalse(AutoCommitUtils.needOpenTransaction(selectStatement));
-        selectStatement.setFrom(new SimpleTableSegment(new TableNameSegment(0, 
5, new IdentifierValue("foo"))));
+        selectStatement.setFrom(mock(SimpleTableSegment.class));
         assertTrue(AutoCommitUtils.needOpenTransaction(selectStatement));
     }
     
@@ -50,6 +47,6 @@ class AutoCommitUtilsTest {
     
     @Test
     void assertNeedOpenTransactionForOtherStatement() {
-        assertFalse(AutoCommitUtils.needOpenTransaction(new 
RegisterStorageUnitStatement(false, new LinkedList<>())));
+        
assertFalse(AutoCommitUtils.needOpenTransaction(mock(RegisterStorageUnitStatement.class)));
     }
 }
diff --git a/parser/distsql/engine/src/main/antlr4/imports/Keyword.g4 
b/parser/distsql/engine/src/main/antlr4/imports/Keyword.g4
index e2bdb512195..6f096e6417f 100644
--- a/parser/distsql/engine/src/main/antlr4/imports/Keyword.g4
+++ b/parser/distsql/engine/src/main/antlr4/imports/Keyword.g4
@@ -346,3 +346,7 @@ ALGORITHM
 FORCE
     : F O R C E
     ;
+
+CHECK_PRIVILEGES
+    : C H E C K UL_ P R I V I L E G E S
+    ;
diff --git a/parser/distsql/engine/src/main/antlr4/imports/RDLStatement.g4 
b/parser/distsql/engine/src/main/antlr4/imports/RDLStatement.g4
index 418dd843b7c..5dfb4f7a0bd 100644
--- a/parser/distsql/engine/src/main/antlr4/imports/RDLStatement.g4
+++ b/parser/distsql/engine/src/main/antlr4/imports/RDLStatement.g4
@@ -20,17 +20,21 @@ grammar RDLStatement;
 import BaseRule;
 
 registerStorageUnit
-    : REGISTER STORAGE UNIT ifNotExists? storageUnitDefinition (COMMA_ 
storageUnitDefinition)*
+    : REGISTER STORAGE UNIT ifNotExists? storageUnitsDefinition (COMMA_ 
checkPrivileges)?
     ;
 
 alterStorageUnit
-    : ALTER STORAGE UNIT storageUnitDefinition (COMMA_ storageUnitDefinition)*
+    : ALTER STORAGE UNIT storageUnitsDefinition (COMMA_ checkPrivileges)?
     ;
 
 unregisterStorageUnit
     : UNREGISTER STORAGE UNIT ifExists? storageUnitName (COMMA_ 
storageUnitName)* ignoreTables?
     ;
 
+storageUnitsDefinition
+    : storageUnitDefinition (COMMA_ storageUnitDefinition)*
+    ;
+
 storageUnitDefinition
     : storageUnitName LP_ (simpleSource | urlSource) COMMA_ USER EQ_ user 
(COMMA_ PASSWORD EQ_ password)? (COMMA_ propertiesDefinition)? RP_
     ;
@@ -80,3 +84,11 @@ ifExists
 ifNotExists
     : IF NOT EXISTS
     ;
+
+checkPrivileges
+    : CHECK_PRIVILEGES EQ_ privilegeType (COMMA_ privilegeType)*
+    ;
+
+privilegeType
+    : IDENTIFIER_
+    ;
diff --git 
a/parser/distsql/engine/src/main/java/org/apache/shardingsphere/distsql/parser/core/kernel/KernelDistSQLStatementVisitor.java
 
b/parser/distsql/engine/src/main/java/org/apache/shardingsphere/distsql/parser/core/kernel/KernelDistSQLStatementVisitor.java
index 0ecce27e2da..67f09b2f851 100644
--- 
a/parser/distsql/engine/src/main/java/org/apache/shardingsphere/distsql/parser/core/kernel/KernelDistSQLStatementVisitor.java
+++ 
b/parser/distsql/engine/src/main/java/org/apache/shardingsphere/distsql/parser/core/kernel/KernelDistSQLStatementVisitor.java
@@ -22,6 +22,7 @@ import 
org.apache.shardingsphere.distsql.parser.autogen.KernelDistSQLStatementBa
 import 
org.apache.shardingsphere.distsql.parser.autogen.KernelDistSQLStatementParser.AlgorithmDefinitionContext;
 import 
org.apache.shardingsphere.distsql.parser.autogen.KernelDistSQLStatementParser.AlterComputeNodeContext;
 import 
org.apache.shardingsphere.distsql.parser.autogen.KernelDistSQLStatementParser.AlterStorageUnitContext;
+import 
org.apache.shardingsphere.distsql.parser.autogen.KernelDistSQLStatementParser.CheckPrivilegesContext;
 import 
org.apache.shardingsphere.distsql.parser.autogen.KernelDistSQLStatementParser.ConvertYamlConfigurationContext;
 import 
org.apache.shardingsphere.distsql.parser.autogen.KernelDistSQLStatementParser.DatabaseNameContext;
 import 
org.apache.shardingsphere.distsql.parser.autogen.KernelDistSQLStatementParser.DisableComputeNodeContext;
@@ -58,6 +59,7 @@ import 
org.apache.shardingsphere.distsql.parser.autogen.KernelDistSQLStatementPa
 import 
org.apache.shardingsphere.distsql.parser.autogen.KernelDistSQLStatementParser.ShowStorageUnitsContext;
 import 
org.apache.shardingsphere.distsql.parser.autogen.KernelDistSQLStatementParser.ShowTableMetadataContext;
 import 
org.apache.shardingsphere.distsql.parser.autogen.KernelDistSQLStatementParser.StorageUnitDefinitionContext;
+import 
org.apache.shardingsphere.distsql.parser.autogen.KernelDistSQLStatementParser.StorageUnitsDefinitionContext;
 import 
org.apache.shardingsphere.distsql.parser.autogen.KernelDistSQLStatementParser.UnlabelComputeNodeContext;
 import 
org.apache.shardingsphere.distsql.parser.autogen.KernelDistSQLStatementParser.UnlockClusterContext;
 import 
org.apache.shardingsphere.distsql.parser.autogen.KernelDistSQLStatementParser.UnregisterStorageUnitContext;
@@ -100,6 +102,7 @@ import 
org.apache.shardingsphere.sql.parser.sql.common.value.identifier.Identifi
 import 
org.apache.shardingsphere.sql.parser.sql.common.value.literal.impl.StringLiteralValue;
 
 import java.util.Collection;
+import java.util.Collections;
 import java.util.Objects;
 import java.util.Properties;
 import java.util.stream.Collectors;
@@ -111,12 +114,20 @@ public final class KernelDistSQLStatementVisitor extends 
KernelDistSQLStatementB
     
     @Override
     public ASTNode visitRegisterStorageUnit(final RegisterStorageUnitContext 
ctx) {
-        return new RegisterStorageUnitStatement(null != ctx.ifNotExists(), 
ctx.storageUnitDefinition().stream().map(each -> (DataSourceSegment) 
visit(each)).collect(Collectors.toList()));
+        return new RegisterStorageUnitStatement(null != ctx.ifNotExists(), 
getStorageUnits(ctx.storageUnitsDefinition()), 
getExpectedPrivileges(ctx.checkPrivileges()));
     }
     
     @Override
     public ASTNode visitAlterStorageUnit(final AlterStorageUnitContext ctx) {
-        return new 
AlterStorageUnitStatement(ctx.storageUnitDefinition().stream().map(each -> 
(DataSourceSegment) visit(each)).collect(Collectors.toList()));
+        return new 
AlterStorageUnitStatement(getStorageUnits(ctx.storageUnitsDefinition()), 
getExpectedPrivileges(ctx.checkPrivileges()));
+    }
+    
+    private Collection<DataSourceSegment> getStorageUnits(final 
StorageUnitsDefinitionContext ctx) {
+        return ctx.storageUnitDefinition().stream().map(each -> 
(DataSourceSegment) visit(each)).collect(Collectors.toList());
+    }
+    
+    private Collection<String> getExpectedPrivileges(final 
CheckPrivilegesContext ctx) {
+        return null == ctx ? Collections.emptySet() : 
ctx.privilegeType().stream().map(this::getIdentifierValue).collect(Collectors.toSet());
     }
     
     @Override
diff --git 
a/parser/distsql/statement/src/main/java/org/apache/shardingsphere/distsql/statement/rdl/resource/unit/type/AlterStorageUnitStatement.java
 
b/parser/distsql/statement/src/main/java/org/apache/shardingsphere/distsql/statement/rdl/resource/unit/type/AlterStorageUnitStatement.java
index 7a26c867c4d..0bf3cb2f506 100644
--- 
a/parser/distsql/statement/src/main/java/org/apache/shardingsphere/distsql/statement/rdl/resource/unit/type/AlterStorageUnitStatement.java
+++ 
b/parser/distsql/statement/src/main/java/org/apache/shardingsphere/distsql/statement/rdl/resource/unit/type/AlterStorageUnitStatement.java
@@ -32,4 +32,6 @@ import java.util.Collection;
 public final class AlterStorageUnitStatement extends 
StorageUnitDefinitionStatement {
     
     private final Collection<DataSourceSegment> storageUnits;
+    
+    private final Collection<String> expectedPrivileges;
 }
diff --git 
a/parser/distsql/statement/src/main/java/org/apache/shardingsphere/distsql/statement/rdl/resource/unit/type/RegisterStorageUnitStatement.java
 
b/parser/distsql/statement/src/main/java/org/apache/shardingsphere/distsql/statement/rdl/resource/unit/type/RegisterStorageUnitStatement.java
index 84795ad9340..90418b0d600 100644
--- 
a/parser/distsql/statement/src/main/java/org/apache/shardingsphere/distsql/statement/rdl/resource/unit/type/RegisterStorageUnitStatement.java
+++ 
b/parser/distsql/statement/src/main/java/org/apache/shardingsphere/distsql/statement/rdl/resource/unit/type/RegisterStorageUnitStatement.java
@@ -34,4 +34,6 @@ public final class RegisterStorageUnitStatement extends 
StorageUnitDefinitionSta
     private final boolean ifNotExists;
     
     private final Collection<DataSourceSegment> storageUnits;
+    
+    private final Collection<String> expectedPrivileges;
 }

Reply via email to