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

strongduanmu pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/shardingsphere.git


The following commit(s) were added to refs/heads/master by this push:
     new 4d36017e8c9 Add a check to verify database name naming conventions. 
(#38883)
4d36017e8c9 is described below

commit 4d36017e8c9b6dbefda0a2983c0dcd53798cb140
Author: zhaojinchao <[email protected]>
AuthorDate: Tue Jun 23 09:01:11 2026 +0800

    Add a check to verify database name naming conventions. (#38883)
    
    * Add a check to verify database name naming conventions.
    
    * Update RELEASE-NOTES.md
    
    * Fix transaction e2e
    
    * Fix transaction e2e
    
    * Update RELEASE-NOTES.md
    
    * Refactor ConvertYamlConfigurationExecutor
    
    * CreateDatabaseProxyBackendHandler add checker
    
    * Fix checkstyle
    
    * Fix transaction e2e
    
    * Update RELEASE-NOTES.md
---
 RELEASE-NOTES.md                                   |  1 +
 .../metadata/database/DatabaseNameValidator.java   | 44 ++++++++++++++
 .../database/DatabaseNameValidatorTest.java        | 71 ++++++++++++++++++++++
 .../yaml/YamlShardingSphereDataSourceFactory.java  |  2 +
 .../YamlShardingSphereDataSourceFactoryTest.java   |  9 +++
 .../backend/config/ProxyConfigurationLoader.java   |  2 +
 .../type/CreateDatabaseProxyBackendHandler.java    |  2 +
 .../yaml/ConvertYamlConfigurationExecutor.java     |  2 +
 .../YamlDatabaseConfigurationImportExecutor.java   |  2 +
 .../config/ProxyConfigurationLoaderTest.java       |  9 +++
 .../CreateDatabaseProxyBackendHandlerTest.java     |  9 +++
 .../ReadwriteSplittingInTransactionTestCase.java   |  2 +-
 .../src/test/resources/env/e2e-env.properties      |  2 +-
 .../data/actual/databases.xml                      |  0
 .../data/actual/dataset.xml                        |  0
 .../init-sql/mysql/50-scenario-actual-init.sql     |  0
 .../init-sql/opengauss/50-scenario-actual-init.sql |  0
 .../postgresql/50-scenario-actual-init.sql         |  0
 .../data/expected/databases.xml                    |  0
 .../data/expected/dataset.xml                      |  0
 .../init-sql/mysql/60-scenario-expected-init.sql   |  0
 .../opengauss/60-scenario-expected-init.sql        |  0
 .../postgresql/60-scenario-expected-init.sql       |  0
 .../mysql/database-readwrite-splitting-local.yaml  |  6 +-
 .../database-readwrite-splitting-xa-atomikos.yaml  |  6 +-
 .../database-readwrite-splitting-xa-narayana.yaml  |  6 +-
 .../conf/mysql/database-readwrite-splitting.yaml   | 10 +--
 .../opengauss/database-readwrite-splitting.yaml    |  2 +-
 .../postgresql/database-readwrite-splitting.yaml   |  2 +-
 29 files changed, 171 insertions(+), 18 deletions(-)

diff --git a/RELEASE-NOTES.md b/RELEASE-NOTES.md
index 317ca39fd12..2ecd39ef27b 100644
--- a/RELEASE-NOTES.md
+++ b/RELEASE-NOTES.md
@@ -58,6 +58,7 @@
 1. Proxy: Support driverClassName config in proxy storage unit to solve mysql 
and mariadb jdbc url conflict - 
[#38582](https://github.com/apache/shardingsphere/pull/38582)
 1. Proxy: Support Firebird prepared statement cache reuse for held connections 
- [#38644](https://github.com/apache/shardingsphere/pull/38644)
 1. JDBC: Bump the ClickHouse JDBC Driver used by optional modules to version 
`0.9.8` - [#38878](https://github.com/apache/shardingsphere/pull/38878)
+1. JDBC & Proxy: Add a check to verify database name naming conventions. - 
[#38883](https://github.com/apache/shardingsphere/pull/38883)
 1. Proxy Native: Support building Proxy Native via GraalVM CE for JDK 25 - 
[#38682](https://github.com/apache/shardingsphere/pull/38682)
 
 ## Release 5.5.3
diff --git 
a/infra/common/src/main/java/org/apache/shardingsphere/infra/metadata/database/DatabaseNameValidator.java
 
b/infra/common/src/main/java/org/apache/shardingsphere/infra/metadata/database/DatabaseNameValidator.java
new file mode 100644
index 00000000000..80fb9ab3557
--- /dev/null
+++ 
b/infra/common/src/main/java/org/apache/shardingsphere/infra/metadata/database/DatabaseNameValidator.java
@@ -0,0 +1,44 @@
+/*
+ * 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.metadata.database;
+
+import com.google.common.base.Preconditions;
+
+import lombok.AccessLevel;
+import lombok.NoArgsConstructor;
+
+import java.util.regex.Pattern;
+
+/**
+ * Database name validator.
+ */
+@NoArgsConstructor(access = AccessLevel.PRIVATE)
+public final class DatabaseNameValidator {
+    
+    private static final Pattern DATABASE_NAME_PATTERN = 
Pattern.compile("[A-Za-z][A-Za-z0-9_]*");
+    
+    /**
+     * Validate database name.
+     *
+     * @param databaseName database name
+     */
+    public static void validate(final String databaseName) {
+        Preconditions.checkArgument(null == databaseName || 
databaseName.isEmpty() || DATABASE_NAME_PATTERN.matcher(databaseName).matches(),
+                "Database name `%s` is invalid, the database name should start 
with a letter and can contain letters, numbers and underscores only.", 
databaseName);
+    }
+}
diff --git 
a/infra/common/src/test/java/org/apache/shardingsphere/infra/metadata/database/DatabaseNameValidatorTest.java
 
b/infra/common/src/test/java/org/apache/shardingsphere/infra/metadata/database/DatabaseNameValidatorTest.java
new file mode 100644
index 00000000000..e96de7c0785
--- /dev/null
+++ 
b/infra/common/src/test/java/org/apache/shardingsphere/infra/metadata/database/DatabaseNameValidatorTest.java
@@ -0,0 +1,71 @@
+/*
+ * 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.metadata.database;
+
+import org.junit.jupiter.api.Test;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.is;
+import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
+import static org.junit.jupiter.api.Assertions.assertThrows;
+
+class DatabaseNameValidatorTest {
+    
+    @Test
+    void assertValidate() {
+        assertDoesNotThrow(() -> DatabaseNameValidator.validate("foo_db"));
+    }
+    
+    @Test
+    void assertValidateWithNumber() {
+        assertDoesNotThrow(() -> DatabaseNameValidator.validate("foo_db_1"));
+    }
+    
+    @Test
+    void assertValidateWithUpperCaseLetter() {
+        assertDoesNotThrow(() -> DatabaseNameValidator.validate("Foo_DB"));
+    }
+    
+    @Test
+    void assertValidateWithEmptyDatabaseName() {
+        assertDoesNotThrow(() -> DatabaseNameValidator.validate(""));
+    }
+    
+    @Test
+    void assertValidateWithNullDatabaseName() {
+        assertDoesNotThrow(() -> DatabaseNameValidator.validate(null));
+    }
+    
+    @Test
+    void assertValidateWithHyphenDatabaseName() {
+        IllegalArgumentException actual = 
assertThrows(IllegalArgumentException.class, () -> 
DatabaseNameValidator.validate("foo-db"));
+        assertThat(actual.getMessage(), is("Database name `foo-db` is invalid, 
the database name should start with a letter and can contain letters, numbers 
and underscores only."));
+    }
+    
+    @Test
+    void assertValidateWithNumberFirstDatabaseName() {
+        IllegalArgumentException actual = 
assertThrows(IllegalArgumentException.class, () -> 
DatabaseNameValidator.validate("1foo_db"));
+        assertThat(actual.getMessage(), is("Database name `1foo_db` is 
invalid, the database name should start with a letter and can contain letters, 
numbers and underscores only."));
+    }
+    
+    @Test
+    void assertValidateWithBlankDatabaseName() {
+        IllegalArgumentException actual = 
assertThrows(IllegalArgumentException.class, () -> 
DatabaseNameValidator.validate("foo db"));
+        assertThat(actual.getMessage(), is("Database name `foo db` is invalid, 
the database name should start with a letter and can contain letters, numbers 
and underscores only."));
+    }
+}
diff --git 
a/jdbc/src/main/java/org/apache/shardingsphere/driver/api/yaml/YamlShardingSphereDataSourceFactory.java
 
b/jdbc/src/main/java/org/apache/shardingsphere/driver/api/yaml/YamlShardingSphereDataSourceFactory.java
index 22f728fe966..9625ff138af 100644
--- 
a/jdbc/src/main/java/org/apache/shardingsphere/driver/api/yaml/YamlShardingSphereDataSourceFactory.java
+++ 
b/jdbc/src/main/java/org/apache/shardingsphere/driver/api/yaml/YamlShardingSphereDataSourceFactory.java
@@ -25,6 +25,7 @@ import 
org.apache.shardingsphere.driver.api.ShardingSphereDataSourceFactory;
 import org.apache.shardingsphere.driver.yaml.YamlJDBCConfiguration;
 import org.apache.shardingsphere.infra.config.mode.ModeConfiguration;
 import org.apache.shardingsphere.infra.config.rule.RuleConfiguration;
+import org.apache.shardingsphere.infra.metadata.database.DatabaseNameValidator;
 import org.apache.shardingsphere.infra.util.yaml.YamlEngine;
 import 
org.apache.shardingsphere.infra.yaml.config.swapper.mode.YamlModeConfigurationSwapper;
 import 
org.apache.shardingsphere.infra.yaml.config.swapper.resource.YamlDataSourceConfigurationSwapper;
@@ -130,6 +131,7 @@ public final class YamlShardingSphereDataSourceFactory {
     }
     
     private static DataSource createDataSource(final Map<String, DataSource> 
dataSourceMap, final YamlJDBCConfiguration jdbcConfig) throws SQLException {
+        DatabaseNameValidator.validate(jdbcConfig.getDatabaseName());
         ModeConfiguration modeConfig = null == jdbcConfig.getMode() ? null : 
new YamlModeConfigurationSwapper().swapToObject(jdbcConfig.getMode());
         jdbcConfig.rebuild();
         Collection<RuleConfiguration> ruleConfigs = new 
YamlRuleConfigurationSwapperEngine().swapToRuleConfigurations(jdbcConfig.getRules());
diff --git 
a/jdbc/src/test/java/org/apache/shardingsphere/driver/api/yaml/YamlShardingSphereDataSourceFactoryTest.java
 
b/jdbc/src/test/java/org/apache/shardingsphere/driver/api/yaml/YamlShardingSphereDataSourceFactoryTest.java
index a8e3d4f5baa..1237f0a6dad 100644
--- 
a/jdbc/src/test/java/org/apache/shardingsphere/driver/api/yaml/YamlShardingSphereDataSourceFactoryTest.java
+++ 
b/jdbc/src/test/java/org/apache/shardingsphere/driver/api/yaml/YamlShardingSphereDataSourceFactoryTest.java
@@ -32,6 +32,7 @@ import java.util.Map;
 
 import static org.hamcrest.Matchers.is;
 import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.jupiter.api.Assertions.assertThrows;
 
 class YamlShardingSphereDataSourceFactoryTest {
     
@@ -73,6 +74,14 @@ class YamlShardingSphereDataSourceFactoryTest {
         
assertDataSource(YamlShardingSphereDataSourceFactory.createDataSource(new 
MockedDataSource(), SystemResourceFileUtils.readFile(YAML_FILE).getBytes()));
     }
     
+    @Test
+    void assertCreateDataSourceWithHyphenDatabaseName() {
+        IllegalArgumentException actual = 
assertThrows(IllegalArgumentException.class,
+                () -> YamlShardingSphereDataSourceFactory.createDataSource(new 
MockedDataSource(), "databaseName: logic-db".getBytes()));
+        assertThat(actual.getMessage(),
+                is("Database name `logic-db` is invalid, the database name 
should start with a letter and can contain letters, numbers and underscores 
only."));
+    }
+    
     @SneakyThrows(ReflectiveOperationException.class)
     private void assertDataSource(final DataSource dataSource) {
         
assertThat(Plugins.getMemberAccessor().get(ShardingSphereDataSource.class.getDeclaredField("databaseName"),
 dataSource), is("logic_db"));
diff --git 
a/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/config/ProxyConfigurationLoader.java
 
b/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/config/ProxyConfigurationLoader.java
index a7d1a7164ad..aebfd57c4f6 100644
--- 
a/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/config/ProxyConfigurationLoader.java
+++ 
b/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/config/ProxyConfigurationLoader.java
@@ -22,6 +22,7 @@ import lombok.AccessLevel;
 import lombok.NoArgsConstructor;
 import lombok.SneakyThrows;
 import org.apache.shardingsphere.infra.config.rule.RuleConfiguration;
+import org.apache.shardingsphere.infra.metadata.database.DatabaseNameValidator;
 import org.apache.shardingsphere.infra.spi.ShardingSphereServiceLoader;
 import org.apache.shardingsphere.infra.util.yaml.YamlEngine;
 import 
org.apache.shardingsphere.infra.yaml.config.pojo.rule.YamlGlobalRuleConfiguration;
@@ -162,6 +163,7 @@ public final class ProxyConfigurationLoader {
             return Optional.empty();
         }
         Preconditions.checkNotNull(result.getDatabaseName(), "Property 
`databaseName` in file `%s` is required.", yamlFile.getName());
+        DatabaseNameValidator.validate(result.getDatabaseName());
         checkDuplicateRule(result.getRules(), yamlFile);
         return Optional.of(result);
     }
diff --git 
a/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/handler/database/type/CreateDatabaseProxyBackendHandler.java
 
b/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/handler/database/type/CreateDatabaseProxyBackendHandler.java
index cdcc0ae5978..bccd9134abc 100644
--- 
a/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/handler/database/type/CreateDatabaseProxyBackendHandler.java
+++ 
b/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/handler/database/type/CreateDatabaseProxyBackendHandler.java
@@ -20,6 +20,7 @@ package 
org.apache.shardingsphere.proxy.backend.handler.database.type;
 import lombok.RequiredArgsConstructor;
 import 
org.apache.shardingsphere.database.exception.core.exception.syntax.database.DatabaseCreateExistsException;
 import org.apache.shardingsphere.infra.exception.ShardingSpherePreconditions;
+import org.apache.shardingsphere.infra.metadata.database.DatabaseNameValidator;
 import org.apache.shardingsphere.mode.manager.ContextManager;
 import org.apache.shardingsphere.proxy.backend.handler.ProxyBackendHandler;
 import org.apache.shardingsphere.proxy.backend.response.header.ResponseHeader;
@@ -38,6 +39,7 @@ public final class CreateDatabaseProxyBackendHandler 
implements ProxyBackendHand
     
     @Override
     public ResponseHeader execute() {
+        DatabaseNameValidator.validate(sqlStatement.getDatabaseName());
         ShardingSpherePreconditions.checkState(sqlStatement.isIfNotExists() || 
!contextManager.getMetaDataContexts().getMetaData().containsDatabase(sqlStatement.getDatabaseName()),
                 () -> new 
DatabaseCreateExistsException(sqlStatement.getDatabaseName()));
         
contextManager.getPersistServiceFacade().getModeFacade().getMetaDataManagerService().createDatabase(sqlStatement.getDatabaseName());
diff --git 
a/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/handler/distsql/ral/queryable/yaml/ConvertYamlConfigurationExecutor.java
 
b/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/handler/distsql/ral/queryable/yaml/ConvertYamlConfigurationExecutor.java
index ef73881c4a7..ec86f3393e0 100644
--- 
a/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/handler/distsql/ral/queryable/yaml/ConvertYamlConfigurationExecutor.java
+++ 
b/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/handler/distsql/ral/queryable/yaml/ConvertYamlConfigurationExecutor.java
@@ -31,6 +31,7 @@ import 
org.apache.shardingsphere.infra.datasource.pool.props.domain.custom.Custo
 import 
org.apache.shardingsphere.infra.datasource.pool.props.domain.synonym.PoolPropertySynonyms;
 import org.apache.shardingsphere.infra.exception.generic.FileIOException;
 import 
org.apache.shardingsphere.infra.merge.result.impl.local.LocalDataQueryResultRow;
+import org.apache.shardingsphere.infra.metadata.database.DatabaseNameValidator;
 import org.apache.shardingsphere.infra.spi.type.ordered.OrderedSPILoader;
 import org.apache.shardingsphere.infra.spi.type.typed.TypedSPILoader;
 import org.apache.shardingsphere.infra.util.yaml.YamlEngine;
@@ -74,6 +75,7 @@ public final class ConvertYamlConfigurationExecutor 
implements DistSQLQueryExecu
         }
         Preconditions.checkNotNull(yamlConfig, "Invalid yaml file `%s`", 
file.getName());
         Preconditions.checkNotNull(yamlConfig.getDatabaseName(), 
"`databaseName` in file `%s` is required.", file.getName());
+        DatabaseNameValidator.validate(yamlConfig.getDatabaseName());
         return Collections.singleton(new 
LocalDataQueryResultRow(convertYamlConfigurationToDistSQL(yamlConfig)));
     }
     
diff --git 
a/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/util/YamlDatabaseConfigurationImportExecutor.java
 
b/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/util/YamlDatabaseConfigurationImportExecutor.java
index acf3c6973ac..e57b7bb263d 100644
--- 
a/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/util/YamlDatabaseConfigurationImportExecutor.java
+++ 
b/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/util/YamlDatabaseConfigurationImportExecutor.java
@@ -34,6 +34,7 @@ import 
org.apache.shardingsphere.infra.exception.external.sql.ShardingSphereSQLE
 import 
org.apache.shardingsphere.infra.exception.kernel.metadata.MissingRequiredDatabaseException;
 import 
org.apache.shardingsphere.infra.exception.kernel.metadata.resource.storageunit.EmptyStorageUnitException;
 import org.apache.shardingsphere.infra.instance.ComputeNodeInstanceContext;
+import org.apache.shardingsphere.infra.metadata.database.DatabaseNameValidator;
 import 
org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase;
 import 
org.apache.shardingsphere.infra.metadata.database.resource.node.StorageNode;
 import 
org.apache.shardingsphere.infra.metadata.database.resource.unit.StorageUnit;
@@ -78,6 +79,7 @@ public final class YamlDatabaseConfigurationImportExecutor {
     public void importDatabaseConfiguration(final 
YamlProxyDatabaseConfiguration yamlConfig) {
         String databaseName = yamlConfig.getDatabaseName();
         checkDatabase(databaseName);
+        DatabaseNameValidator.validate(databaseName);
         checkDataSources(databaseName, yamlConfig.getDataSources());
         addDatabase(databaseName);
         try {
diff --git 
a/proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/config/ProxyConfigurationLoaderTest.java
 
b/proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/config/ProxyConfigurationLoaderTest.java
index 899153a998f..3f0c5c76962 100644
--- 
a/proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/config/ProxyConfigurationLoaderTest.java
+++ 
b/proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/config/ProxyConfigurationLoaderTest.java
@@ -161,6 +161,15 @@ class ProxyConfigurationLoaderTest {
         assertTrue(actual.getDatabaseConfigurations().isEmpty());
     }
     
+    @Test
+    void assertLoadWithHyphenDatabaseName(@TempDir final Path tempDir) throws 
IOException {
+        writeConfigurationFile(tempDir, "global.yaml", "");
+        writeConfigurationFile(tempDir, "database-invalid.yaml", 
"databaseName: invalid-db\n");
+        IllegalArgumentException actual = 
assertThrows(IllegalArgumentException.class, () -> 
ProxyConfigurationLoader.load(tempDir.toString()));
+        assertThat(actual.getMessage(),
+                is("Database name `invalid-db` is invalid, the database name 
should start with a letter and can contain letters, numbers and underscores 
only."));
+    }
+    
     @Test
     void assertLoadWithCompatibleServerYamlOnly(@TempDir final Path tempDir) 
throws IOException {
         writeConfigurationFile(tempDir, "server.yaml", "authority:\n"
diff --git 
a/proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/handler/database/type/CreateDatabaseProxyBackendHandlerTest.java
 
b/proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/handler/database/type/CreateDatabaseProxyBackendHandlerTest.java
index 59706183f29..775c776e367 100644
--- 
a/proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/handler/database/type/CreateDatabaseProxyBackendHandlerTest.java
+++ 
b/proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/handler/database/type/CreateDatabaseProxyBackendHandlerTest.java
@@ -28,6 +28,7 @@ import org.mockito.Mock;
 import org.mockito.junit.jupiter.MockitoExtension;
 
 import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.is;
 import static org.hamcrest.Matchers.isA;
 import static org.junit.jupiter.api.Assertions.assertThrows;
 import static org.mockito.Mockito.RETURNS_DEEP_STUBS;
@@ -46,6 +47,14 @@ class CreateDatabaseProxyBackendHandlerTest {
         assertThat(new CreateDatabaseProxyBackendHandler(statement, 
mock(ContextManager.class, RETURNS_DEEP_STUBS)).execute(), 
isA(UpdateResponseHeader.class));
     }
     
+    @Test
+    void assertExecuteCreateDatabaseWithInvalidName() {
+        when(statement.getDatabaseName()).thenReturn("foo-db");
+        IllegalArgumentException actual = 
assertThrows(IllegalArgumentException.class,
+                () -> new CreateDatabaseProxyBackendHandler(statement, 
mock(ContextManager.class, RETURNS_DEEP_STUBS)).execute());
+        assertThat(actual.getMessage(), is("Database name `foo-db` is invalid, 
the database name should start with a letter and can contain letters, numbers 
and underscores only."));
+    }
+    
     @Test
     void assertExecuteCreateExistDatabase() {
         when(statement.getDatabaseName()).thenReturn("foo_db");
diff --git 
a/test/e2e/operation/transaction/src/test/java/org/apache/shardingsphere/test/e2e/operation/transaction/cases/readwritesplitting/ReadwriteSplittingInTransactionTestCase.java
 
b/test/e2e/operation/transaction/src/test/java/org/apache/shardingsphere/test/e2e/operation/transaction/cases/readwritesplitting/ReadwriteSplittingInTransactionTestCase.java
index 2a28d32c91d..902eb078a9d 100644
--- 
a/test/e2e/operation/transaction/src/test/java/org/apache/shardingsphere/test/e2e/operation/transaction/cases/readwritesplitting/ReadwriteSplittingInTransactionTestCase.java
+++ 
b/test/e2e/operation/transaction/src/test/java/org/apache/shardingsphere/test/e2e/operation/transaction/cases/readwritesplitting/ReadwriteSplittingInTransactionTestCase.java
@@ -32,7 +32,7 @@ import static org.hamcrest.Matchers.is;
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 
-@TransactionTestCase(dbTypes = TransactionTestConstants.MYSQL, scenario = 
"readwrite-splitting", adapters = TransactionTestConstants.PROXY)
+@TransactionTestCase(dbTypes = TransactionTestConstants.MYSQL, scenario = 
"readwrite_splitting", adapters = TransactionTestConstants.PROXY)
 public final class ReadwriteSplittingInTransactionTestCase extends 
BaseTransactionTestCase {
     
     public ReadwriteSplittingInTransactionTestCase(final 
TransactionTestCaseParameter testCaseParam) {
diff --git 
a/test/e2e/operation/transaction/src/test/resources/env/e2e-env.properties 
b/test/e2e/operation/transaction/src/test/resources/env/e2e-env.properties
index 54b445774f8..187926ee2a8 100644
--- a/test/e2e/operation/transaction/src/test/resources/env/e2e-env.properties
+++ b/test/e2e/operation/transaction/src/test/resources/env/e2e-env.properties
@@ -15,7 +15,7 @@
 # limitations under the License.
 #
 
-e2e.scenarios=default,cursor,readwrite-splitting
+e2e.scenarios=default,cursor,readwrite_splitting
 
 #e2e.run.type=DOCKER,NATIVE
 e2e.run.type=
diff --git 
a/test/e2e/operation/transaction/src/test/resources/env/scenario/readwrite-splitting/data/actual/databases.xml
 
b/test/e2e/operation/transaction/src/test/resources/env/scenario/readwrite_splitting/data/actual/databases.xml
similarity index 100%
rename from 
test/e2e/operation/transaction/src/test/resources/env/scenario/readwrite-splitting/data/actual/databases.xml
rename to 
test/e2e/operation/transaction/src/test/resources/env/scenario/readwrite_splitting/data/actual/databases.xml
diff --git 
a/test/e2e/operation/transaction/src/test/resources/env/scenario/readwrite-splitting/data/actual/dataset.xml
 
b/test/e2e/operation/transaction/src/test/resources/env/scenario/readwrite_splitting/data/actual/dataset.xml
similarity index 100%
rename from 
test/e2e/operation/transaction/src/test/resources/env/scenario/readwrite-splitting/data/actual/dataset.xml
rename to 
test/e2e/operation/transaction/src/test/resources/env/scenario/readwrite_splitting/data/actual/dataset.xml
diff --git 
a/test/e2e/operation/transaction/src/test/resources/env/scenario/readwrite-splitting/data/actual/init-sql/mysql/50-scenario-actual-init.sql
 
b/test/e2e/operation/transaction/src/test/resources/env/scenario/readwrite_splitting/data/actual/init-sql/mysql/50-scenario-actual-init.sql
similarity index 100%
rename from 
test/e2e/operation/transaction/src/test/resources/env/scenario/readwrite-splitting/data/actual/init-sql/mysql/50-scenario-actual-init.sql
rename to 
test/e2e/operation/transaction/src/test/resources/env/scenario/readwrite_splitting/data/actual/init-sql/mysql/50-scenario-actual-init.sql
diff --git 
a/test/e2e/operation/transaction/src/test/resources/env/scenario/readwrite-splitting/data/actual/init-sql/opengauss/50-scenario-actual-init.sql
 
b/test/e2e/operation/transaction/src/test/resources/env/scenario/readwrite_splitting/data/actual/init-sql/opengauss/50-scenario-actual-init.sql
similarity index 100%
rename from 
test/e2e/operation/transaction/src/test/resources/env/scenario/readwrite-splitting/data/actual/init-sql/opengauss/50-scenario-actual-init.sql
rename to 
test/e2e/operation/transaction/src/test/resources/env/scenario/readwrite_splitting/data/actual/init-sql/opengauss/50-scenario-actual-init.sql
diff --git 
a/test/e2e/operation/transaction/src/test/resources/env/scenario/readwrite-splitting/data/actual/init-sql/postgresql/50-scenario-actual-init.sql
 
b/test/e2e/operation/transaction/src/test/resources/env/scenario/readwrite_splitting/data/actual/init-sql/postgresql/50-scenario-actual-init.sql
similarity index 100%
rename from 
test/e2e/operation/transaction/src/test/resources/env/scenario/readwrite-splitting/data/actual/init-sql/postgresql/50-scenario-actual-init.sql
rename to 
test/e2e/operation/transaction/src/test/resources/env/scenario/readwrite_splitting/data/actual/init-sql/postgresql/50-scenario-actual-init.sql
diff --git 
a/test/e2e/operation/transaction/src/test/resources/env/scenario/readwrite-splitting/data/expected/databases.xml
 
b/test/e2e/operation/transaction/src/test/resources/env/scenario/readwrite_splitting/data/expected/databases.xml
similarity index 100%
rename from 
test/e2e/operation/transaction/src/test/resources/env/scenario/readwrite-splitting/data/expected/databases.xml
rename to 
test/e2e/operation/transaction/src/test/resources/env/scenario/readwrite_splitting/data/expected/databases.xml
diff --git 
a/test/e2e/operation/transaction/src/test/resources/env/scenario/readwrite-splitting/data/expected/dataset.xml
 
b/test/e2e/operation/transaction/src/test/resources/env/scenario/readwrite_splitting/data/expected/dataset.xml
similarity index 100%
rename from 
test/e2e/operation/transaction/src/test/resources/env/scenario/readwrite-splitting/data/expected/dataset.xml
rename to 
test/e2e/operation/transaction/src/test/resources/env/scenario/readwrite_splitting/data/expected/dataset.xml
diff --git 
a/test/e2e/operation/transaction/src/test/resources/env/scenario/readwrite-splitting/data/expected/init-sql/mysql/60-scenario-expected-init.sql
 
b/test/e2e/operation/transaction/src/test/resources/env/scenario/readwrite_splitting/data/expected/init-sql/mysql/60-scenario-expected-init.sql
similarity index 100%
rename from 
test/e2e/operation/transaction/src/test/resources/env/scenario/readwrite-splitting/data/expected/init-sql/mysql/60-scenario-expected-init.sql
rename to 
test/e2e/operation/transaction/src/test/resources/env/scenario/readwrite_splitting/data/expected/init-sql/mysql/60-scenario-expected-init.sql
diff --git 
a/test/e2e/operation/transaction/src/test/resources/env/scenario/readwrite-splitting/data/expected/init-sql/opengauss/60-scenario-expected-init.sql
 
b/test/e2e/operation/transaction/src/test/resources/env/scenario/readwrite_splitting/data/expected/init-sql/opengauss/60-scenario-expected-init.sql
similarity index 100%
rename from 
test/e2e/operation/transaction/src/test/resources/env/scenario/readwrite-splitting/data/expected/init-sql/opengauss/60-scenario-expected-init.sql
rename to 
test/e2e/operation/transaction/src/test/resources/env/scenario/readwrite_splitting/data/expected/init-sql/opengauss/60-scenario-expected-init.sql
diff --git 
a/test/e2e/operation/transaction/src/test/resources/env/scenario/readwrite-splitting/data/expected/init-sql/postgresql/60-scenario-expected-init.sql
 
b/test/e2e/operation/transaction/src/test/resources/env/scenario/readwrite_splitting/data/expected/init-sql/postgresql/60-scenario-expected-init.sql
similarity index 100%
rename from 
test/e2e/operation/transaction/src/test/resources/env/scenario/readwrite-splitting/data/expected/init-sql/postgresql/60-scenario-expected-init.sql
rename to 
test/e2e/operation/transaction/src/test/resources/env/scenario/readwrite_splitting/data/expected/init-sql/postgresql/60-scenario-expected-init.sql
diff --git 
a/test/e2e/operation/transaction/src/test/resources/env/scenario/readwrite-splitting/jdbc/conf/mysql/database-readwrite-splitting-local.yaml
 
b/test/e2e/operation/transaction/src/test/resources/env/scenario/readwrite_splitting/jdbc/conf/mysql/database-readwrite-splitting-local.yaml
similarity index 92%
rename from 
test/e2e/operation/transaction/src/test/resources/env/scenario/readwrite-splitting/jdbc/conf/mysql/database-readwrite-splitting-local.yaml
rename to 
test/e2e/operation/transaction/src/test/resources/env/scenario/readwrite_splitting/jdbc/conf/mysql/database-readwrite-splitting-local.yaml
index 33282f334e4..c6b47e18f1f 100644
--- 
a/test/e2e/operation/transaction/src/test/resources/env/scenario/readwrite-splitting/jdbc/conf/mysql/database-readwrite-splitting-local.yaml
+++ 
b/test/e2e/operation/transaction/src/test/resources/env/scenario/readwrite_splitting/jdbc/conf/mysql/database-readwrite-splitting-local.yaml
@@ -24,7 +24,7 @@
 databaseName: sharding_db
 dataSources:
   write_ds:
-    url: 
jdbc:mysql://mysql.readwrite-splitting.host:3306/write_ds?useSSL=false&characterEncoding=utf-8
+    url: 
jdbc:mysql://mysql.readwrite_splitting.host:3306/write_ds?useSSL=false&characterEncoding=utf-8
     driverClassName: com.mysql.cj.jdbc.Driver
     username: test_user
     password: Test@9876
@@ -34,7 +34,7 @@ dataSources:
     maxPoolSize: 2
     minPoolSize: 2
   read_ds_0:
-    url: 
jdbc:mysql://mysql.readwrite-splitting.host:3306/read_ds_0?useSSL=false&characterEncoding=utf-8
+    url: 
jdbc:mysql://mysql.readwrite_splitting.host:3306/read_ds_0?useSSL=false&characterEncoding=utf-8
     driverClassName: com.mysql.cj.jdbc.Driver
     username: test_user
     password: Test@9876
@@ -44,7 +44,7 @@ dataSources:
     maxPoolSize: 2
     minPoolSize: 2
   read_ds_1:
-    url: 
jdbc:mysql://mysql.readwrite-splitting.host:3306/read_ds_1?useSSL=false&characterEncoding=utf-8
+    url: 
jdbc:mysql://mysql.readwrite_splitting.host:3306/read_ds_1?useSSL=false&characterEncoding=utf-8
     driverClassName: com.mysql.cj.jdbc.Driver
     username: test_user
     password: Test@9876
diff --git 
a/test/e2e/operation/transaction/src/test/resources/env/scenario/readwrite-splitting/jdbc/conf/mysql/database-readwrite-splitting-xa-atomikos.yaml
 
b/test/e2e/operation/transaction/src/test/resources/env/scenario/readwrite_splitting/jdbc/conf/mysql/database-readwrite-splitting-xa-atomikos.yaml
similarity index 92%
rename from 
test/e2e/operation/transaction/src/test/resources/env/scenario/readwrite-splitting/jdbc/conf/mysql/database-readwrite-splitting-xa-atomikos.yaml
rename to 
test/e2e/operation/transaction/src/test/resources/env/scenario/readwrite_splitting/jdbc/conf/mysql/database-readwrite-splitting-xa-atomikos.yaml
index d69e84eb45c..055f816725f 100644
--- 
a/test/e2e/operation/transaction/src/test/resources/env/scenario/readwrite-splitting/jdbc/conf/mysql/database-readwrite-splitting-xa-atomikos.yaml
+++ 
b/test/e2e/operation/transaction/src/test/resources/env/scenario/readwrite_splitting/jdbc/conf/mysql/database-readwrite-splitting-xa-atomikos.yaml
@@ -24,7 +24,7 @@
 databaseName: sharding_db
 dataSources:
   write_ds:
-    url: 
jdbc:mysql://mysql.readwrite-splitting.host:3306/write_ds?useSSL=false&characterEncoding=utf-8
+    url: 
jdbc:mysql://mysql.readwrite_splitting.host:3306/write_ds?useSSL=false&characterEncoding=utf-8
     driverClassName: com.mysql.cj.jdbc.Driver
     username: test_user
     password: Test@9876
@@ -34,7 +34,7 @@ dataSources:
     maxPoolSize: 2
     minPoolSize: 2
   read_ds_0:
-    url: 
jdbc:mysql://mysql.readwrite-splitting.host:3306/read_ds_0?useSSL=false&characterEncoding=utf-8
+    url: 
jdbc:mysql://mysql.readwrite_splitting.host:3306/read_ds_0?useSSL=false&characterEncoding=utf-8
     driverClassName: com.mysql.cj.jdbc.Driver
     username: test_user
     password: Test@9876
@@ -44,7 +44,7 @@ dataSources:
     maxPoolSize: 2
     minPoolSize: 2
   read_ds_1:
-    url: 
jdbc:mysql://mysql.readwrite-splitting.host:3306/read_ds_1?useSSL=false&characterEncoding=utf-8
+    url: 
jdbc:mysql://mysql.readwrite_splitting.host:3306/read_ds_1?useSSL=false&characterEncoding=utf-8
     driverClassName: com.mysql.cj.jdbc.Driver
     username: test_user
     password: Test@9876
diff --git 
a/test/e2e/operation/transaction/src/test/resources/env/scenario/readwrite-splitting/jdbc/conf/mysql/database-readwrite-splitting-xa-narayana.yaml
 
b/test/e2e/operation/transaction/src/test/resources/env/scenario/readwrite_splitting/jdbc/conf/mysql/database-readwrite-splitting-xa-narayana.yaml
similarity index 92%
rename from 
test/e2e/operation/transaction/src/test/resources/env/scenario/readwrite-splitting/jdbc/conf/mysql/database-readwrite-splitting-xa-narayana.yaml
rename to 
test/e2e/operation/transaction/src/test/resources/env/scenario/readwrite_splitting/jdbc/conf/mysql/database-readwrite-splitting-xa-narayana.yaml
index 255fb326d7c..d5c66b2cf8e 100644
--- 
a/test/e2e/operation/transaction/src/test/resources/env/scenario/readwrite-splitting/jdbc/conf/mysql/database-readwrite-splitting-xa-narayana.yaml
+++ 
b/test/e2e/operation/transaction/src/test/resources/env/scenario/readwrite_splitting/jdbc/conf/mysql/database-readwrite-splitting-xa-narayana.yaml
@@ -24,7 +24,7 @@
 databaseName: sharding_db
 dataSources:
   write_ds:
-    url: 
jdbc:mysql://mysql.readwrite-splitting.host:3306/write_ds?useSSL=false&characterEncoding=utf-8
+    url: 
jdbc:mysql://mysql.readwrite_splitting.host:3306/write_ds?useSSL=false&characterEncoding=utf-8
     driverClassName: com.mysql.cj.jdbc.Driver
     username: test_user
     password: Test@9876
@@ -34,7 +34,7 @@ dataSources:
     maxPoolSize: 2
     minPoolSize: 2
   read_ds_0:
-    url: 
jdbc:mysql://mysql.readwrite-splitting.host:3306/read_ds_0?useSSL=false&characterEncoding=utf-8
+    url: 
jdbc:mysql://mysql.readwrite_splitting.host:3306/read_ds_0?useSSL=false&characterEncoding=utf-8
     driverClassName: com.mysql.cj.jdbc.Driver
     username: test_user
     password: Test@9876
@@ -44,7 +44,7 @@ dataSources:
     maxPoolSize: 2
     minPoolSize: 2
   read_ds_1:
-    url: 
jdbc:mysql://mysql.readwrite-splitting.host:3306/read_ds_1?useSSL=false&characterEncoding=utf-8
+    url: 
jdbc:mysql://mysql.readwrite_splitting.host:3306/read_ds_1?useSSL=false&characterEncoding=utf-8
     driverClassName: com.mysql.cj.jdbc.Driver
     username: test_user
     password: Test@9876
diff --git 
a/test/e2e/operation/transaction/src/test/resources/env/scenario/readwrite-splitting/proxy/conf/mysql/database-readwrite-splitting.yaml
 
b/test/e2e/operation/transaction/src/test/resources/env/scenario/readwrite_splitting/proxy/conf/mysql/database-readwrite-splitting.yaml
similarity index 90%
rename from 
test/e2e/operation/transaction/src/test/resources/env/scenario/readwrite-splitting/proxy/conf/mysql/database-readwrite-splitting.yaml
rename to 
test/e2e/operation/transaction/src/test/resources/env/scenario/readwrite_splitting/proxy/conf/mysql/database-readwrite-splitting.yaml
index 529b76ebcb0..a4fc894ad13 100644
--- 
a/test/e2e/operation/transaction/src/test/resources/env/scenario/readwrite-splitting/proxy/conf/mysql/database-readwrite-splitting.yaml
+++ 
b/test/e2e/operation/transaction/src/test/resources/env/scenario/readwrite_splitting/proxy/conf/mysql/database-readwrite-splitting.yaml
@@ -21,11 +21,11 @@
 # 
 
######################################################################################################
 
-databaseName: readwrite-splitting
+databaseName: readwrite_splitting
 dataSources:
   write_ds:
     driverClassName: com.mysql.cj.jdbc.Driver
-    url: 
jdbc:mysql://mysql.readwrite-splitting.host:3306/write_ds?useSSL=false&characterEncoding=utf-8
+    url: 
jdbc:mysql://mysql.readwrite_splitting.host:3306/write_ds?useSSL=false&characterEncoding=utf-8
     username: test_user
     password: Test@9876
     connectionTimeoutMilliseconds: 30000
@@ -35,7 +35,7 @@ dataSources:
     minPoolSize: 2
   read_ds_0:
     driverClassName: com.mysql.cj.jdbc.Driver
-    url: 
jdbc:mysql://mysql.readwrite-splitting.host:3306/read_ds_0?useSSL=false&characterEncoding=utf-8
+    url: 
jdbc:mysql://mysql.readwrite_splitting.host:3306/read_ds_0?useSSL=false&characterEncoding=utf-8
     username: test_user
     password: Test@9876
     connectionTimeoutMilliseconds: 30000
@@ -45,7 +45,7 @@ dataSources:
     minPoolSize: 2
   read_ds_1:
     driverClassName: com.mysql.cj.jdbc.Driver
-    url: 
jdbc:mysql://mysql.readwrite-splitting.host:3306/read_ds_1?useSSL=false&characterEncoding=utf-8
+    url: 
jdbc:mysql://mysql.readwrite_splitting.host:3306/read_ds_1?useSSL=false&characterEncoding=utf-8
     username: test_user
     password: Test@9876
     connectionTimeoutMilliseconds: 30000
@@ -55,7 +55,7 @@ dataSources:
     minPoolSize: 2
   read_ds_error:
     driverClassName: com.mysql.cj.jdbc.Driver
-    url: 
jdbc:mysql://mysql.readwrite-splitting.host:3306/read_ds_error?useSSL=false&characterEncoding=utf-8
+    url: 
jdbc:mysql://mysql.readwrite_splitting.host:3306/read_ds_error?useSSL=false&characterEncoding=utf-8
     username: test_user
     password: wrong_password
     connectionTimeoutMilliseconds: 5000
diff --git 
a/test/e2e/operation/transaction/src/test/resources/env/scenario/readwrite-splitting/proxy/conf/opengauss/database-readwrite-splitting.yaml
 
b/test/e2e/operation/transaction/src/test/resources/env/scenario/readwrite_splitting/proxy/conf/opengauss/database-readwrite-splitting.yaml
similarity index 98%
rename from 
test/e2e/operation/transaction/src/test/resources/env/scenario/readwrite-splitting/proxy/conf/opengauss/database-readwrite-splitting.yaml
rename to 
test/e2e/operation/transaction/src/test/resources/env/scenario/readwrite_splitting/proxy/conf/opengauss/database-readwrite-splitting.yaml
index 77701139fab..cd19fb639a7 100644
--- 
a/test/e2e/operation/transaction/src/test/resources/env/scenario/readwrite-splitting/proxy/conf/opengauss/database-readwrite-splitting.yaml
+++ 
b/test/e2e/operation/transaction/src/test/resources/env/scenario/readwrite_splitting/proxy/conf/opengauss/database-readwrite-splitting.yaml
@@ -21,7 +21,7 @@
 # 
 
######################################################################################################
 
-databaseName: readwrite-splitting
+databaseName: readwrite_splitting
 dataSources:
   write_ds:
     url: jdbc:opengauss://opengauss.default.host:5432/write_ds
diff --git 
a/test/e2e/operation/transaction/src/test/resources/env/scenario/readwrite-splitting/proxy/conf/postgresql/database-readwrite-splitting.yaml
 
b/test/e2e/operation/transaction/src/test/resources/env/scenario/readwrite_splitting/proxy/conf/postgresql/database-readwrite-splitting.yaml
similarity index 98%
rename from 
test/e2e/operation/transaction/src/test/resources/env/scenario/readwrite-splitting/proxy/conf/postgresql/database-readwrite-splitting.yaml
rename to 
test/e2e/operation/transaction/src/test/resources/env/scenario/readwrite_splitting/proxy/conf/postgresql/database-readwrite-splitting.yaml
index b9a55eda5cc..13d75c3c649 100644
--- 
a/test/e2e/operation/transaction/src/test/resources/env/scenario/readwrite-splitting/proxy/conf/postgresql/database-readwrite-splitting.yaml
+++ 
b/test/e2e/operation/transaction/src/test/resources/env/scenario/readwrite_splitting/proxy/conf/postgresql/database-readwrite-splitting.yaml
@@ -21,7 +21,7 @@
 # 
 
######################################################################################################
 
-databaseName: readwrite-splitting
+databaseName: readwrite_splitting
 dataSources:
   write_ds:
     url: jdbc:postgresql://postgresql.default.host:5432/write_ds


Reply via email to