This is an automated email from the ASF dual-hosted git repository.
terrymanu 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 46527c8df6d Add Firebird to SQL E2E (#40237)
46527c8df6d is described below
commit 46527c8df6d90481608c9452a965aeb83f22f565
Author: Maxim Igoshin <[email protected]>
AuthorDate: Wed Oct 21 11:14:41 2026 +0300
Add Firebird to SQL E2E (#40237)
* Add Firebird to SQL E2E
* Validate Firebird E2E connections with a test query instead of
Connection.isValid
* Compare DDL E2E column names in upper case instead of equalToIgnoringCase
* Add Firebird to nightly SQL E2E matrix
* Add Firebird SQL E2E to release notes
* Compare E2E DDL column names exactly with expected names normalized by
database rules
* Retrigger CI
* Retrigger CI
---
.github/workflows/nightly-e2e-sql.yml | 4 +
RELEASE-NOTES.md | 1 +
.../option/StorageContainerConnectOption.java | 11 ++
.../FirebirdStorageContainerConnectOption.java | 48 ++++++
.../FirebirdStorageContainerCreateOption.java | 89 ++++++++++
.../firebird/FirebirdStorageContainerOption.java | 39 +++++
.../env/container/util/StorageContainerUtils.java | 5 +-
...container.storage.option.StorageContainerOption | 1 +
.../firebird/init-sql/00-common-init-authority.sql | 19 +++
.../firebird/init-sql/99-common-check-ready.sql | 18 ++
test/e2e/fixture/pom.xml | 17 ++
test/e2e/sql/pom.xml | 4 +
.../e2e/sql/env/DataSetEnvironmentManager.java | 5 +-
.../metadata/DialectQueryBehaviorProvider.java | 11 ++
.../FirebirdDialectQueryBehaviorProvider.java} | 34 ++--
.../test/e2e/sql/it/sql/ddl/DDLE2EIT.java | 23 ++-
...framework.metadata.DialectQueryBehaviorProvider | 1 +
.../resources/cases/ddl/e2e-ddl-alter-table.xml | 2 +-
.../resources/cases/ddl/e2e-ddl-create-table.xml | 2 +-
.../resources/cases/ddl/e2e-ddl-drop-table.xml | 2 +-
.../test/resources/cases/dml/e2e-dml-delete.xml | 4 +-
.../test/resources/cases/dml/e2e-dml-insert.xml | 2 +-
.../test/resources/cases/dml/e2e-dml-update.xml | 4 +-
.../cases/dql/e2e-dql-select-order-by.xml | 4 +-
.../test/resources/cases/dql/e2e-dql-select.xml | 4 +-
.../init-sql/firebird/50-scenario-actual-init.sql | 111 +++++++++++++
.../firebird/60-scenario-expected-init.sql | 30 ++++
.../db/proxy/conf/firebird/database-db.yaml | 182 +++++++++++++++++++++
28 files changed, 640 insertions(+), 37 deletions(-)
diff --git a/.github/workflows/nightly-e2e-sql.yml
b/.github/workflows/nightly-e2e-sql.yml
index 5bd2503b2f8..bcbb8feffe6 100644
--- a/.github/workflows/nightly-e2e-sql.yml
+++ b/.github/workflows/nightly-e2e-sql.yml
@@ -113,6 +113,10 @@ jobs:
mode: Standalone
database: Hive
scenario: mask
+ - adapter: proxy
+ mode: Cluster
+ database: Firebird
+ scenario: db
exclude:
- adapter: jdbc
scenario: passthrough
diff --git a/RELEASE-NOTES.md b/RELEASE-NOTES.md
index 4e9a49e1e12..4a70e841528 100644
--- a/RELEASE-NOTES.md
+++ b/RELEASE-NOTES.md
@@ -190,6 +190,7 @@
1. Encrypt: Support SqlServer for Using the UPDATE statement with information
from another table when use encrypt feature -
[#38926](https://github.com/apache/shardingsphere/pull/38926)
1. Sharding: Fix HASH_MOD routing mismatch for same negative numeric values
across numeric Java types with compatibility switch
`normalize-numeric-int-range` -
[#38327](https://github.com/apache/shardingsphere/pull/38327)
1. SQL Parser: Support parsing SYSTEM_USER in SQL92 dialect and bind it as a
niladic function instead of a column -
[#39102](https://github.com/apache/shardingsphere/pull/39102)
+1. E2E: Add Firebird to SQL E2E tests through ShardingSphere-Proxy
## Release 5.5.3
diff --git
a/test/e2e/env/src/test/java/org/apache/shardingsphere/test/e2e/env/container/storage/option/StorageContainerConnectOption.java
b/test/e2e/env/src/test/java/org/apache/shardingsphere/test/e2e/env/container/storage/option/StorageContainerConnectOption.java
index b78abeebdeb..7693b570827 100644
---
a/test/e2e/env/src/test/java/org/apache/shardingsphere/test/e2e/env/container/storage/option/StorageContainerConnectOption.java
+++
b/test/e2e/env/src/test/java/org/apache/shardingsphere/test/e2e/env/container/storage/option/StorageContainerConnectOption.java
@@ -17,6 +17,8 @@
package org.apache.shardingsphere.test.e2e.env.container.storage.option;
+import java.util.Optional;
+
/**
* Storage container connect option.
*/
@@ -60,4 +62,13 @@ public interface StorageContainerConnectOption {
default String getProxyURL(final String host, final int port, final String
dataSourceName) {
return getURL(host, port, dataSourceName);
}
+
+ /**
+ * Get connection test query.
+ *
+ * @return connection test query, empty means JDBC 4 Connection.isValid
+ */
+ default Optional<String> getConnectionTestQuery() {
+ return Optional.empty();
+ }
}
diff --git
a/test/e2e/env/src/test/java/org/apache/shardingsphere/test/e2e/env/container/storage/option/dialect/firebird/FirebirdStorageContainerConnectOption.java
b/test/e2e/env/src/test/java/org/apache/shardingsphere/test/e2e/env/container/storage/option/dialect/firebird/FirebirdStorageContainerConnectOption.java
new file mode 100644
index 00000000000..83b01c6c499
--- /dev/null
+++
b/test/e2e/env/src/test/java/org/apache/shardingsphere/test/e2e/env/container/storage/option/dialect/firebird/FirebirdStorageContainerConnectOption.java
@@ -0,0 +1,48 @@
+/*
+ * 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.test.e2e.env.container.storage.option.dialect.firebird;
+
+import
org.apache.shardingsphere.test.e2e.env.container.storage.option.StorageContainerConnectOption;
+
+import java.util.Optional;
+
+/**
+ * Storage container connect option for Firebird.
+ */
+public final class FirebirdStorageContainerConnectOption implements
StorageContainerConnectOption {
+
+ @Override
+ public String getDriverClassName() {
+ return "org.firebirdsql.jdbc.FBDriver";
+ }
+
+ @Override
+ public String getURL(final String host, final int port) {
+ return String.format("jdbc:firebirdsql://%s:%s/", host, port);
+ }
+
+ @Override
+ public String getURL(final String host, final int port, final String
dataSourceName) {
+ return String.format("jdbc:firebirdsql://%s:%s/%s?encoding=UTF8",
host, port, dataSourceName);
+ }
+
+ @Override
+ public Optional<String> getConnectionTestQuery() {
+ return Optional.of("SELECT 1 FROM RDB$DATABASE");
+ }
+}
diff --git
a/test/e2e/env/src/test/java/org/apache/shardingsphere/test/e2e/env/container/storage/option/dialect/firebird/FirebirdStorageContainerCreateOption.java
b/test/e2e/env/src/test/java/org/apache/shardingsphere/test/e2e/env/container/storage/option/dialect/firebird/FirebirdStorageContainerCreateOption.java
new file mode 100644
index 00000000000..ca5741c0182
--- /dev/null
+++
b/test/e2e/env/src/test/java/org/apache/shardingsphere/test/e2e/env/container/storage/option/dialect/firebird/FirebirdStorageContainerCreateOption.java
@@ -0,0 +1,89 @@
+/*
+ * 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.test.e2e.env.container.storage.option.dialect.firebird;
+
+import
org.apache.shardingsphere.test.e2e.env.container.storage.option.StorageContainerCreateOption;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Optional;
+
+/**
+ * Storage container create option for Firebird.
+ */
+public final class FirebirdStorageContainerCreateOption implements
StorageContainerCreateOption {
+
+ private static final String DEFAULT_DATABASE_NAME = "firebird";
+
+ @Override
+ public int getPort() {
+ return 3050;
+ }
+
+ @Override
+ public String getDefaultImageName() {
+ return "firebirdsql/firebird:5.0.4";
+ }
+
+ @Override
+ public String getCommand() {
+ return "";
+ }
+
+ @Override
+ public Map<String, String> getEnvironments() {
+ Map<String, String> result = new HashMap<>(3, 1F);
+ result.put("FIREBIRD_DATABASE", DEFAULT_DATABASE_NAME);
+ result.put("FIREBIRD_DATABASE_DEFAULT_CHARSET", "UTF8");
+ result.put("ISC_PATH", "/var/lib/firebird/data");
+ return result;
+ }
+
+ @Override
+ public Collection<String> getMountedConfigurationResources() {
+ return Collections.emptyList();
+ }
+
+ @Override
+ public Collection<String> getAdditionalEnvMountedSQLResources(final int
majorVersion) {
+ return Collections.emptyList();
+ }
+
+ @Override
+ public List<Integer> getSupportedMajorVersions() {
+ return Collections.emptyList();
+ }
+
+ @Override
+ public boolean withPrivilegedMode() {
+ return false;
+ }
+
+ @Override
+ public Optional<String> getDefaultDatabaseName(final int majorVersion) {
+ return Optional.of(DEFAULT_DATABASE_NAME);
+ }
+
+ @Override
+ public long getStartupTimeoutSeconds() {
+ return 120L;
+ }
+}
diff --git
a/test/e2e/env/src/test/java/org/apache/shardingsphere/test/e2e/env/container/storage/option/dialect/firebird/FirebirdStorageContainerOption.java
b/test/e2e/env/src/test/java/org/apache/shardingsphere/test/e2e/env/container/storage/option/dialect/firebird/FirebirdStorageContainerOption.java
new file mode 100644
index 00000000000..4ce26328c0f
--- /dev/null
+++
b/test/e2e/env/src/test/java/org/apache/shardingsphere/test/e2e/env/container/storage/option/dialect/firebird/FirebirdStorageContainerOption.java
@@ -0,0 +1,39 @@
+/*
+ * 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.test.e2e.env.container.storage.option.dialect.firebird;
+
+import lombok.Getter;
+import
org.apache.shardingsphere.test.e2e.env.container.storage.option.StorageContainerConnectOption;
+import
org.apache.shardingsphere.test.e2e.env.container.storage.option.StorageContainerCreateOption;
+import
org.apache.shardingsphere.test.e2e.env.container.storage.option.StorageContainerOption;
+
+/**
+ * Storage container option for Firebird.
+ */
+@Getter
+public final class FirebirdStorageContainerOption implements
StorageContainerOption {
+
+ private final StorageContainerCreateOption createOption = new
FirebirdStorageContainerCreateOption();
+
+ private final StorageContainerConnectOption connectOption = new
FirebirdStorageContainerConnectOption();
+
+ @Override
+ public String getDatabaseType() {
+ return "Firebird";
+ }
+}
diff --git
a/test/e2e/env/src/test/java/org/apache/shardingsphere/test/e2e/env/container/util/StorageContainerUtils.java
b/test/e2e/env/src/test/java/org/apache/shardingsphere/test/e2e/env/container/util/StorageContainerUtils.java
index 6890e49e92f..2a47fc61ac2 100644
---
a/test/e2e/env/src/test/java/org/apache/shardingsphere/test/e2e/env/container/util/StorageContainerUtils.java
+++
b/test/e2e/env/src/test/java/org/apache/shardingsphere/test/e2e/env/container/util/StorageContainerUtils.java
@@ -22,6 +22,7 @@ import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import
org.apache.shardingsphere.database.connector.core.spi.DatabaseTypedSPILoader;
import
org.apache.shardingsphere.database.connector.core.type.DatabaseTypeFactory;
+import
org.apache.shardingsphere.test.e2e.env.container.storage.option.StorageContainerConnectOption;
import
org.apache.shardingsphere.test.e2e.env.container.storage.option.StorageContainerOption;
import javax.sql.DataSource;
@@ -43,7 +44,9 @@ public final class StorageContainerUtils {
*/
public static DataSource generateDataSource(final String jdbcUrl, final
String username, final String password, final int maximumPoolSize) {
HikariDataSource result = new HikariDataSource();
-
result.setDriverClassName(DatabaseTypedSPILoader.getService(StorageContainerOption.class,
DatabaseTypeFactory.get(jdbcUrl)).getConnectOption().getDriverClassName());
+ StorageContainerConnectOption connectOption =
DatabaseTypedSPILoader.getService(StorageContainerOption.class,
DatabaseTypeFactory.get(jdbcUrl)).getConnectOption();
+ result.setDriverClassName(connectOption.getDriverClassName());
+
connectOption.getConnectionTestQuery().ifPresent(result::setConnectionTestQuery);
result.setJdbcUrl(jdbcUrl);
result.setUsername(username);
result.setPassword(password);
diff --git
a/test/e2e/env/src/test/resources/META-INF/services/org.apache.shardingsphere.test.e2e.env.container.storage.option.StorageContainerOption
b/test/e2e/env/src/test/resources/META-INF/services/org.apache.shardingsphere.test.e2e.env.container.storage.option.StorageContainerOption
index 6ef86592c34..61fe5f1c3eb 100644
---
a/test/e2e/env/src/test/resources/META-INF/services/org.apache.shardingsphere.test.e2e.env.container.storage.option.StorageContainerOption
+++
b/test/e2e/env/src/test/resources/META-INF/services/org.apache.shardingsphere.test.e2e.env.container.storage.option.StorageContainerOption
@@ -20,3 +20,4 @@
org.apache.shardingsphere.test.e2e.env.container.storage.option.dialect.postgres
org.apache.shardingsphere.test.e2e.env.container.storage.option.dialect.mariadb.MariaDBStorageContainerOption
org.apache.shardingsphere.test.e2e.env.container.storage.option.dialect.opengauss.OpenGaussStorageContainerOption
org.apache.shardingsphere.test.e2e.env.container.storage.option.dialect.hive.HiveStorageContainerOption
+org.apache.shardingsphere.test.e2e.env.container.storage.option.dialect.firebird.FirebirdStorageContainerOption
diff --git
a/test/e2e/env/src/test/resources/container/firebird/init-sql/00-common-init-authority.sql
b/test/e2e/env/src/test/resources/container/firebird/init-sql/00-common-init-authority.sql
new file mode 100644
index 00000000000..dd611b84b7b
--- /dev/null
+++
b/test/e2e/env/src/test/resources/container/firebird/init-sql/00-common-init-authority.sql
@@ -0,0 +1,19 @@
+--
+-- 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.
+--
+
+CREATE USER test_user PASSWORD 'Test@9876';
+GRANT CREATE DATABASE TO USER test_user;
diff --git
a/test/e2e/env/src/test/resources/container/firebird/init-sql/99-common-check-ready.sql
b/test/e2e/env/src/test/resources/container/firebird/init-sql/99-common-check-ready.sql
new file mode 100644
index 00000000000..185e3d0ef0e
--- /dev/null
+++
b/test/e2e/env/src/test/resources/container/firebird/init-sql/99-common-check-ready.sql
@@ -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.
+--
+
+CREATE USER ready_user PASSWORD 'Ready@123';
diff --git a/test/e2e/fixture/pom.xml b/test/e2e/fixture/pom.xml
index f0e7cc53a19..a1a26f08760 100644
--- a/test/e2e/fixture/pom.xml
+++ b/test/e2e/fixture/pom.xml
@@ -121,6 +121,12 @@
<version>${project.version}</version>
<scope>runtime</scope>
</dependency>
+ <dependency>
+ <groupId>org.apache.shardingsphere</groupId>
+ <artifactId>shardingsphere-proxy-dialect-firebird</artifactId>
+ <version>${project.version}</version>
+ <scope>runtime</scope>
+ </dependency>
<dependency>
<groupId>org.apache.shardingsphere</groupId>
<artifactId>shardingsphere-standalone-mode-repository-memory</artifactId>
@@ -178,6 +184,11 @@
<artifactId>opengauss-jdbc</artifactId>
<scope>runtime</scope>
</dependency>
+ <dependency>
+ <groupId>org.firebirdsql.jdbc</groupId>
+ <artifactId>jaybird</artifactId>
+ <scope>runtime</scope>
+ </dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
@@ -263,6 +274,12 @@
<version>${project.version}</version>
<scope>runtime</scope>
</dependency>
+ <dependency>
+ <groupId>org.apache.shardingsphere</groupId>
+
<artifactId>shardingsphere-proxy-dialect-firebird</artifactId>
+ <version>${project.version}</version>
+ <scope>runtime</scope>
+ </dependency>
<dependency>
<groupId>org.apache.shardingsphere</groupId>
<artifactId>shardingsphere-standalone-mode-repository-memory</artifactId>
diff --git a/test/e2e/sql/pom.xml b/test/e2e/sql/pom.xml
index 97464448022..928cfcc0816 100644
--- a/test/e2e/sql/pom.xml
+++ b/test/e2e/sql/pom.xml
@@ -60,6 +60,10 @@
<groupId>com.microsoft.sqlserver</groupId>
<artifactId>mssql-jdbc</artifactId>
</dependency>
+ <dependency>
+ <groupId>org.firebirdsql.jdbc</groupId>
+ <artifactId>jaybird</artifactId>
+ </dependency>
<dependency>
<groupId>com.zaxxer</groupId>
diff --git
a/test/e2e/sql/src/test/java/org/apache/shardingsphere/test/e2e/sql/env/DataSetEnvironmentManager.java
b/test/e2e/sql/src/test/java/org/apache/shardingsphere/test/e2e/sql/env/DataSetEnvironmentManager.java
index f56ec3858ea..2f5a85231e4 100644
---
a/test/e2e/sql/src/test/java/org/apache/shardingsphere/test/e2e/sql/env/DataSetEnvironmentManager.java
+++
b/test/e2e/sql/src/test/java/org/apache/shardingsphere/test/e2e/sql/env/DataSetEnvironmentManager.java
@@ -25,6 +25,7 @@ import
org.apache.shardingsphere.database.connector.core.metadata.database.metad
import
org.apache.shardingsphere.database.connector.core.metadata.identifier.IdentifierCasePolicy;
import
org.apache.shardingsphere.database.connector.core.metadata.identifier.IdentifierNormalizeEngine;
import
org.apache.shardingsphere.database.connector.core.metadata.identifier.IdentifierScope;
+import
org.apache.shardingsphere.database.connector.core.spi.DatabaseTypedSPILoader;
import org.apache.shardingsphere.database.connector.core.type.DatabaseType;
import
org.apache.shardingsphere.database.connector.core.type.DatabaseTypeFactory;
import
org.apache.shardingsphere.database.connector.core.type.DatabaseTypeRegistry;
@@ -41,6 +42,7 @@ import
org.apache.shardingsphere.test.e2e.sql.cases.dataset.metadata.DataSetMeta
import org.apache.shardingsphere.test.e2e.sql.cases.dataset.row.DataSetRow;
import org.apache.shardingsphere.test.e2e.sql.cases.value.SQLValue;
import org.apache.shardingsphere.test.e2e.sql.cases.value.SQLValueGroup;
+import
org.apache.shardingsphere.test.e2e.sql.framework.metadata.DialectQueryBehaviorProvider;
import javax.sql.DataSource;
import java.sql.Connection;
@@ -213,7 +215,8 @@ public final class DataSetEnvironmentManager {
}
private String getTruncateSQL(final String tableName, final DatabaseType
databaseType) {
- return TRUNCATE_SQL_CACHE.computeIfAbsent(databaseType.getType() + ':'
+ tableName, unused -> String.format("TRUNCATE TABLE %s",
getQuotedTableName(tableName, databaseType)));
+ return TRUNCATE_SQL_CACHE.computeIfAbsent(databaseType.getType() + ':'
+ tableName, unused ->
String.format(DatabaseTypedSPILoader.findService(DialectQueryBehaviorProvider.class,
databaseType)
+
.flatMap(DialectQueryBehaviorProvider::getDeleteAllRowsSQLTemplate).orElse("TRUNCATE
TABLE %s"), getQuotedTableName(tableName, databaseType)));
}
private static String getQuotedTableName(final String tableName, final
DatabaseType databaseType) {
diff --git
a/test/e2e/sql/src/test/java/org/apache/shardingsphere/test/e2e/sql/framework/metadata/DialectQueryBehaviorProvider.java
b/test/e2e/sql/src/test/java/org/apache/shardingsphere/test/e2e/sql/framework/metadata/DialectQueryBehaviorProvider.java
index f50b6ad8565..ea2c909a38c 100644
---
a/test/e2e/sql/src/test/java/org/apache/shardingsphere/test/e2e/sql/framework/metadata/DialectQueryBehaviorProvider.java
+++
b/test/e2e/sql/src/test/java/org/apache/shardingsphere/test/e2e/sql/framework/metadata/DialectQueryBehaviorProvider.java
@@ -39,4 +39,15 @@ public interface DialectQueryBehaviorProvider extends
DatabaseTypedSPI {
default Optional<String> getFallbackOrderByWhenNoPrimaryKey() {
return Optional.empty();
}
+
+ /**
+ * Get delete all rows SQL template when TRUNCATE TABLE is unsupported.
+ *
+ * <p>Template contains one "%s" placeholder for the quoted table name,
for example: "DELETE FROM %s". Empty means TRUNCATE TABLE.</p>
+ *
+ * @return optional delete all rows SQL template
+ */
+ default Optional<String> getDeleteAllRowsSQLTemplate() {
+ return Optional.empty();
+ }
}
diff --git
a/test/e2e/sql/src/test/java/org/apache/shardingsphere/test/e2e/sql/framework/metadata/DialectQueryBehaviorProvider.java
b/test/e2e/sql/src/test/java/org/apache/shardingsphere/test/e2e/sql/framework/metadata/dialect/FirebirdDialectQueryBehaviorProvider.java
similarity index 55%
copy from
test/e2e/sql/src/test/java/org/apache/shardingsphere/test/e2e/sql/framework/metadata/DialectQueryBehaviorProvider.java
copy to
test/e2e/sql/src/test/java/org/apache/shardingsphere/test/e2e/sql/framework/metadata/dialect/FirebirdDialectQueryBehaviorProvider.java
index f50b6ad8565..835ec7d4e32 100644
---
a/test/e2e/sql/src/test/java/org/apache/shardingsphere/test/e2e/sql/framework/metadata/DialectQueryBehaviorProvider.java
+++
b/test/e2e/sql/src/test/java/org/apache/shardingsphere/test/e2e/sql/framework/metadata/dialect/FirebirdDialectQueryBehaviorProvider.java
@@ -15,28 +15,30 @@
* limitations under the License.
*/
-package org.apache.shardingsphere.test.e2e.sql.framework.metadata;
+package org.apache.shardingsphere.test.e2e.sql.framework.metadata.dialect;
-import org.apache.shardingsphere.database.connector.core.spi.DatabaseTypedSPI;
-import org.apache.shardingsphere.infra.spi.annotation.SingletonSPI;
+import
org.apache.shardingsphere.test.e2e.sql.framework.metadata.DialectQueryBehaviorProvider;
import java.util.Optional;
/**
- * Dialect query behavior provider for E2E assertions.
+ * Firebird dialect query behavior provider.
*/
-@SingletonSPI
-public interface DialectQueryBehaviorProvider extends DatabaseTypedSPI {
+public final class FirebirdDialectQueryBehaviorProvider implements
DialectQueryBehaviorProvider {
- /**
- * Get fallback ORDER BY clause when primary key is unknown.
- *
- * <p>Return value should not contain the leading "ORDER BY" keyword.
- * For example: "1 ASC" or "some_column ASC". Empty means no fallback.</p>
- *
- * @return optional fallback ORDER BY clause (without leading ORDER BY)
- */
- default Optional<String> getFallbackOrderByWhenNoPrimaryKey() {
- return Optional.empty();
+ @Override
+ public Optional<String> getFallbackOrderByWhenNoPrimaryKey() {
+ return Optional.of("1 ASC");
+ }
+
+ // TODO Remove getDeleteAllRowsSQLTemplate and restore TRUNCATE TABLE in
DataSetEnvironmentManager when Firebird 6 with TRUNCATE TABLE is released.
+ @Override
+ public Optional<String> getDeleteAllRowsSQLTemplate() {
+ return Optional.of("DELETE FROM %s");
+ }
+
+ @Override
+ public String getDatabaseType() {
+ return "Firebird";
}
}
diff --git
a/test/e2e/sql/src/test/java/org/apache/shardingsphere/test/e2e/sql/it/sql/ddl/DDLE2EIT.java
b/test/e2e/sql/src/test/java/org/apache/shardingsphere/test/e2e/sql/it/sql/ddl/DDLE2EIT.java
index 4abca18e3bc..756160af951 100644
---
a/test/e2e/sql/src/test/java/org/apache/shardingsphere/test/e2e/sql/it/sql/ddl/DDLE2EIT.java
+++
b/test/e2e/sql/src/test/java/org/apache/shardingsphere/test/e2e/sql/it/sql/ddl/DDLE2EIT.java
@@ -88,6 +88,8 @@ class DDLE2EIT implements SQLE2EIT {
private final Map<DataSource, IdentifierCasePolicy>
tableIdentifierPolicies = new HashMap<>();
+ private final Map<DataSource, IdentifierCasePolicy>
columnIdentifierPolicies = new HashMap<>();
+
private SQLE2EEnvironmentEngine environmentEngine;
@ParameterizedTest(name = "{0}", allowZeroInvocations = true)
@@ -302,11 +304,13 @@ class DDLE2EIT implements SQLE2EIT {
assertNotContainsTable(environmentEngine, dataNodes,
testParam.getDatabaseType());
return;
}
- assertTableMetaData(testParam, getActualColumns(dataNodes,
testParam.getDatabaseType()), getActualIndexes(dataNodes), expected);
+ assertTableMetaData(testParam, getActualColumns(dataNodes,
testParam.getDatabaseType()), getActualIndexes(dataNodes), expected,
+ getColumnIdentifierPolicy(testParam.getDatabaseType(),
dataNodes.iterator().next()));
}
- private void assertTableMetaData(final AssertionTestParameter testParam,
final List<DataSetColumn> actualColumns, final List<DataSetIndex>
actualIndexes, final DataSetMetaData expected) {
- assertColumnMetaData(testParam, actualColumns, expected.getColumns());
+ private void assertTableMetaData(final AssertionTestParameter testParam,
final List<DataSetColumn> actualColumns, final List<DataSetIndex>
actualIndexes, final DataSetMetaData expected,
+ final IdentifierCasePolicy
columnIdentifierPolicy) {
+ assertColumnMetaData(testParam, actualColumns, expected.getColumns(),
columnIdentifierPolicy);
assertIndexMetaData(actualIndexes, expected.getIndexes());
}
@@ -388,15 +392,20 @@ class DDLE2EIT implements SQLE2EIT {
}
}
- private void assertColumnMetaData(final AssertionTestParameter testParam,
final List<DataSetColumn> actual, final List<DataSetColumn> expected) {
+ private IdentifierCasePolicy getColumnIdentifierPolicy(final DatabaseType
databaseType, final DataNode dataNode) {
+ DataSource dataSource =
environmentEngine.getActualDataSourceMap().get(dataNode.getDataSourceName());
+ return columnIdentifierPolicies.computeIfAbsent(dataSource, unused ->
IdentifierNormalizeEngine.resolvePolicy(databaseType, dataSource,
IdentifierScope.COLUMN));
+ }
+
+ private void assertColumnMetaData(final AssertionTestParameter testParam,
final List<DataSetColumn> actual, final List<DataSetColumn> expected, final
IdentifierCasePolicy columnIdentifierPolicy) {
assertThat("Size of actual columns is different with size of expected
columns.", actual.size(), is(expected.size()));
for (int i = 0; i < actual.size(); i++) {
- assertColumnMetaData(testParam, actual.get(i), expected.get(i));
+ assertColumnMetaData(testParam, actual.get(i), expected.get(i),
columnIdentifierPolicy);
}
}
- private void assertColumnMetaData(final AssertionTestParameter testParam,
final DataSetColumn actual, final DataSetColumn expected) {
- assertThat("Mismatched column name.", actual.getName(),
is(expected.getName()));
+ private void assertColumnMetaData(final AssertionTestParameter testParam,
final DataSetColumn actual, final DataSetColumn expected, final
IdentifierCasePolicy columnIdentifierPolicy) {
+ assertThat("Mismatched column name.", actual.getName(),
is(IdentifierNormalizeEngine.normalize(columnIdentifierPolicy,
expected.getName())));
if ("MySQL".equals(testParam.getDatabaseType().getType()) &&
"integer".equals(expected.getType())) {
assertThat("Mismatched column type.", actual.getType(), is("int"));
} else if ("PostgreSQL".equals(testParam.getDatabaseType().getType())
&& "integer".equals(expected.getType())) {
diff --git
a/test/e2e/sql/src/test/resources/META-INF/services/org.apache.shardingsphere.test.e2e.sql.framework.metadata.DialectQueryBehaviorProvider
b/test/e2e/sql/src/test/resources/META-INF/services/org.apache.shardingsphere.test.e2e.sql.framework.metadata.DialectQueryBehaviorProvider
index 8b3b354a253..79cdea514bd 100644
---
a/test/e2e/sql/src/test/resources/META-INF/services/org.apache.shardingsphere.test.e2e.sql.framework.metadata.DialectQueryBehaviorProvider
+++
b/test/e2e/sql/src/test/resources/META-INF/services/org.apache.shardingsphere.test.e2e.sql.framework.metadata.DialectQueryBehaviorProvider
@@ -16,3 +16,4 @@
#
org.apache.shardingsphere.test.e2e.sql.framework.metadata.dialect.HiveDialectQueryBehaviorProvider
+org.apache.shardingsphere.test.e2e.sql.framework.metadata.dialect.FirebirdDialectQueryBehaviorProvider
diff --git a/test/e2e/sql/src/test/resources/cases/ddl/e2e-ddl-alter-table.xml
b/test/e2e/sql/src/test/resources/cases/ddl/e2e-ddl-alter-table.xml
index ba4b6f6d220..21489c05a13 100644
--- a/test/e2e/sql/src/test/resources/cases/ddl/e2e-ddl-alter-table.xml
+++ b/test/e2e/sql/src/test/resources/cases/ddl/e2e-ddl-alter-table.xml
@@ -17,7 +17,7 @@
-->
<e2e-test-cases>
- <test-case sql="ALTER TABLE t_order_details ADD name varchar(10)"
db-types="MySQL,PostgreSQL,openGauss"
scenario-types="db,tbl,dbtbl_with_readwrite_splitting,readwrite_splitting">
+ <test-case sql="ALTER TABLE t_order_details ADD name varchar(10)"
db-types="MySQL,PostgreSQL,openGauss,Firebird"
scenario-types="db,tbl,dbtbl_with_readwrite_splitting,readwrite_splitting">
<assertion expected-data-file="alter_add.xml">
<initial-sql sql="CREATE TABLE t_order_details(id int, description
varchar(10))" affected-table="t_order_details" />
<destroy-sql sql="DROP TABLE t_order_details" />
diff --git a/test/e2e/sql/src/test/resources/cases/ddl/e2e-ddl-create-table.xml
b/test/e2e/sql/src/test/resources/cases/ddl/e2e-ddl-create-table.xml
index 59a8d492aca..f42afc55f12 100644
--- a/test/e2e/sql/src/test/resources/cases/ddl/e2e-ddl-create-table.xml
+++ b/test/e2e/sql/src/test/resources/cases/ddl/e2e-ddl-create-table.xml
@@ -17,7 +17,7 @@
-->
<e2e-test-cases>
- <test-case sql="CREATE TABLE t_order_details(id int, description
varchar(10))" db-types="MySQL,PostgreSQL,openGauss"
scenario-types="db,tbl,dbtbl_with_readwrite_splitting,readwrite_splitting">
+ <test-case sql="CREATE TABLE t_order_details(id int, description
varchar(10))" db-types="MySQL,PostgreSQL,openGauss,Firebird"
scenario-types="db,tbl,dbtbl_with_readwrite_splitting,readwrite_splitting">
<assertion expected-data-file="create_table.xml">
<initial-sql affected-table="t_order_details" />
<destroy-sql sql="DROP TABLE t_order_details" />
diff --git a/test/e2e/sql/src/test/resources/cases/ddl/e2e-ddl-drop-table.xml
b/test/e2e/sql/src/test/resources/cases/ddl/e2e-ddl-drop-table.xml
index 2ddff0b2a9e..c9cd6827ed6 100644
--- a/test/e2e/sql/src/test/resources/cases/ddl/e2e-ddl-drop-table.xml
+++ b/test/e2e/sql/src/test/resources/cases/ddl/e2e-ddl-drop-table.xml
@@ -17,7 +17,7 @@
-->
<e2e-test-cases>
- <test-case sql="DROP TABLE t_order_details"
db-types="MySQL,PostgreSQL,openGauss"
scenario-types="db,tbl,dbtbl_with_readwrite_splitting,readwrite_splitting">
+ <test-case sql="DROP TABLE t_order_details"
db-types="MySQL,PostgreSQL,openGauss,Firebird"
scenario-types="db,tbl,dbtbl_with_readwrite_splitting,readwrite_splitting">
<assertion expected-data-file="drop_table.xml">
<initial-sql sql="CREATE TABLE t_order_details(id int, description
varchar(10))" affected-table="t_order_details" />
</assertion>
diff --git a/test/e2e/sql/src/test/resources/cases/dml/e2e-dml-delete.xml
b/test/e2e/sql/src/test/resources/cases/dml/e2e-dml-delete.xml
index 88823781533..f35bbd2d565 100644
--- a/test/e2e/sql/src/test/resources/cases/dml/e2e-dml-delete.xml
+++ b/test/e2e/sql/src/test/resources/cases/dml/e2e-dml-delete.xml
@@ -17,7 +17,7 @@
-->
<e2e-test-cases>
- <test-case sql="DELETE FROM t_order WHERE order_id = ? AND user_id = ? AND
status= ?" db-types="MySQL,PostgreSQL,openGauss"
scenario-types="db,tbl,dbtbl_with_readwrite_splitting,readwrite_splitting">
+ <test-case sql="DELETE FROM t_order WHERE order_id = ? AND user_id = ? AND
status= ?" db-types="MySQL,PostgreSQL,openGauss,Firebird"
scenario-types="db,tbl,dbtbl_with_readwrite_splitting,readwrite_splitting">
<assertion parameters="1000:int, 10:int, init:String"
expected-data-file="delete_with_sharding_value.xml" />
</test-case>
@@ -28,7 +28,7 @@
<assertion parameters="2900:int, 29:int, init:String"
expected-data-file="delete_with_sharding_value_batch_4.xml" />
</test-case>
- <test-case sql="DELETE FROM t_order WHERE status= ?"
db-types="MySQL,PostgreSQL,openGauss"
scenario-types="db,tbl,dbtbl_with_readwrite_splitting,readwrite_splitting">
+ <test-case sql="DELETE FROM t_order WHERE status= ?"
db-types="MySQL,PostgreSQL,openGauss,Firebird"
scenario-types="db,tbl,dbtbl_with_readwrite_splitting,readwrite_splitting">
<assertion parameters="init:String"
expected-data-file="delete_without_sharding_value.xml" />
</test-case>
diff --git a/test/e2e/sql/src/test/resources/cases/dml/e2e-dml-insert.xml
b/test/e2e/sql/src/test/resources/cases/dml/e2e-dml-insert.xml
index f9c903ce673..fc33332ebd9 100644
--- a/test/e2e/sql/src/test/resources/cases/dml/e2e-dml-insert.xml
+++ b/test/e2e/sql/src/test/resources/cases/dml/e2e-dml-insert.xml
@@ -17,7 +17,7 @@
-->
<e2e-test-cases>
- <test-case sql="INSERT INTO t_order (order_id, user_id, status,
merchant_id, remark, creation_date) VALUES (?, ?, ?, 1, 'test', '2017-08-08')"
db-types="MySQL,PostgreSQL,openGauss"
scenario-types="db,tbl,dbtbl_with_readwrite_splitting,readwrite_splitting">
+ <test-case sql="INSERT INTO t_order (order_id, user_id, status,
merchant_id, remark, creation_date) VALUES (?, ?, ?, 1, 'test', '2017-08-08')"
db-types="MySQL,PostgreSQL,openGauss,Firebird"
scenario-types="db,tbl,dbtbl_with_readwrite_splitting,readwrite_splitting">
<assertion parameters="1:int, 1:int, insert:String"
expected-data-file="insert_for_order_1.xml" />
<assertion parameters="2:int, 2:int, insert:String"
expected-data-file="insert_for_order_2.xml" />
<assertion parameters="3:int, 3:int, insert:String"
expected-data-file="insert_for_order_3.xml" />
diff --git a/test/e2e/sql/src/test/resources/cases/dml/e2e-dml-update.xml
b/test/e2e/sql/src/test/resources/cases/dml/e2e-dml-update.xml
index fc021b341a3..7e28e7f658e 100644
--- a/test/e2e/sql/src/test/resources/cases/dml/e2e-dml-update.xml
+++ b/test/e2e/sql/src/test/resources/cases/dml/e2e-dml-update.xml
@@ -17,7 +17,7 @@
-->
<e2e-test-cases>
- <test-case sql="UPDATE t_order SET status = ? WHERE order_id = ? AND
user_id = ?" db-types="MySQL,PostgreSQL,openGauss"
scenario-types="db,tbl,dbtbl_with_readwrite_splitting,readwrite_splitting">
+ <test-case sql="UPDATE t_order SET status = ? WHERE order_id = ? AND
user_id = ?" db-types="MySQL,PostgreSQL,openGauss,Firebird"
scenario-types="db,tbl,dbtbl_with_readwrite_splitting,readwrite_splitting">
<assertion parameters="update:String, 1000:int, 10:int"
expected-data-file="update.xml" />
</test-case>
@@ -36,7 +36,7 @@
<assertion expected-data-file="update_without_condition.xml" />
</test-case>
- <test-case sql="UPDATE t_order SET status = 'update' WHERE order_id = 1000
AND user_id = 10" db-types="MySQL,PostgreSQL,openGauss"
scenario-types="db,tbl,dbtbl_with_readwrite_splitting,readwrite_splitting">
+ <test-case sql="UPDATE t_order SET status = 'update' WHERE order_id = 1000
AND user_id = 10" db-types="MySQL,PostgreSQL,openGauss,Firebird"
scenario-types="db,tbl,dbtbl_with_readwrite_splitting,readwrite_splitting">
<assertion expected-data-file="update.xml" />
</test-case>
diff --git
a/test/e2e/sql/src/test/resources/cases/dql/e2e-dql-select-order-by.xml
b/test/e2e/sql/src/test/resources/cases/dql/e2e-dql-select-order-by.xml
index 89569e18807..53a4f3057cb 100644
--- a/test/e2e/sql/src/test/resources/cases/dql/e2e-dql-select-order-by.xml
+++ b/test/e2e/sql/src/test/resources/cases/dql/e2e-dql-select-order-by.xml
@@ -17,7 +17,7 @@
-->
<e2e-test-cases>
- <test-case sql="SELECT * FROM t_order_item WHERE item_id <> ? ORDER
BY item_id" db-types="MySQL,PostgreSQL,openGauss"
scenario-types="db,tbl,dbtbl_with_readwrite_splitting,readwrite_splitting">
+ <test-case sql="SELECT * FROM t_order_item WHERE item_id <> ? ORDER
BY item_id" db-types="MySQL,PostgreSQL,openGauss,Firebird"
scenario-types="db,tbl,dbtbl_with_readwrite_splitting,readwrite_splitting">
<assertion parameters="100001:int"
expected-data-source-name="read_dataset" />
</test-case>
@@ -47,7 +47,7 @@
<assertion parameters="10:int, 12:int, 1309:int, 1408:int"
expected-data-source-name="read_dataset" />
</test-case>
- <test-case sql="SELECT * FROM t_order WHERE user_id >= ? AND user_id
<= ? AND order_id >= ? AND order_id <= ? ORDER BY user_id, order_id"
db-types="MySQL,PostgreSQL,openGauss"
scenario-types="db,tbl,dbtbl_with_readwrite_splitting,readwrite_splitting">
+ <test-case sql="SELECT * FROM t_order WHERE user_id >= ? AND user_id
<= ? AND order_id >= ? AND order_id <= ? ORDER BY user_id, order_id"
db-types="MySQL,PostgreSQL,openGauss,Firebird"
scenario-types="db,tbl,dbtbl_with_readwrite_splitting,readwrite_splitting">
<assertion parameters="10:int, 12:int, 1009:int, 1108:int"
expected-data-source-name="read_dataset" />
<assertion parameters="10:int, 12:int, 1309:int, 1408:int"
expected-data-source-name="read_dataset" />
</test-case>
diff --git a/test/e2e/sql/src/test/resources/cases/dql/e2e-dql-select.xml
b/test/e2e/sql/src/test/resources/cases/dql/e2e-dql-select.xml
index ca6021682ba..6ed305cc326 100644
--- a/test/e2e/sql/src/test/resources/cases/dql/e2e-dql-select.xml
+++ b/test/e2e/sql/src/test/resources/cases/dql/e2e-dql-select.xml
@@ -35,7 +35,7 @@
<assertion parameters="12:int, 1000:int"
expected-data-source-name="read_dataset" />
</test-case>
- <test-case sql="SELECT * FROM t_order WHERE user_id = ? AND order_id = ?"
db-types="MySQL,PostgreSQL,openGauss"
scenario-types="db,tbl,dbtbl_with_readwrite_splitting,readwrite_splitting">
+ <test-case sql="SELECT * FROM t_order WHERE user_id = ? AND order_id = ?"
db-types="MySQL,PostgreSQL,openGauss,Firebird"
scenario-types="db,tbl,dbtbl_with_readwrite_splitting,readwrite_splitting">
<assertion parameters="10:int, 1000:int"
expected-data-source-name="read_dataset" />
<assertion parameters="12:int, 1000:int"
expected-data-source-name="read_dataset" />
</test-case>
@@ -171,7 +171,7 @@
<!-- <assertion parameters="0:int"
expected-data-source-name="shadow_dataset" />-->
<!-- </test-case>-->
- <test-case sql="SELECT * FROM t_merchant WHERE business_code LIKE '%18'"
db-types="MySQL,PostgreSQL,openGauss" scenario-types="db,encrypt"
+ <test-case sql="SELECT * FROM t_merchant WHERE business_code LIKE '%18'"
db-types="MySQL,PostgreSQL,openGauss,Firebird" scenario-types="db,encrypt"
scenario-comments="Test single table's LIKE operator percentage
wildcard in simple select statement when use sharding feature.|Test encrypt
table's LIKE operator percentage wildcard in simple select statement when use
encrypt feature.">
<assertion expected-data-source-name="read_dataset" />
</test-case>
diff --git
a/test/e2e/sql/src/test/resources/env/scenario/db/data/actual/init-sql/firebird/50-scenario-actual-init.sql
b/test/e2e/sql/src/test/resources/env/scenario/db/data/actual/init-sql/firebird/50-scenario-actual-init.sql
new file mode 100644
index 00000000000..e3282b1aba9
--- /dev/null
+++
b/test/e2e/sql/src/test/resources/env/scenario/db/data/actual/init-sql/firebird/50-scenario-actual-init.sql
@@ -0,0 +1,111 @@
+--
+-- 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.
+--
+
+CREATE DATABASE 'db_0' USER 'test_user' PASSWORD 'Test@9876' DEFAULT CHARACTER
SET UTF8;
+CREATE DATABASE 'db_1' USER 'test_user' PASSWORD 'Test@9876' DEFAULT CHARACTER
SET UTF8;
+CREATE DATABASE 'db_2' USER 'test_user' PASSWORD 'Test@9876' DEFAULT CHARACTER
SET UTF8;
+CREATE DATABASE 'db_3' USER 'test_user' PASSWORD 'Test@9876' DEFAULT CHARACTER
SET UTF8;
+CREATE DATABASE 'db_4' USER 'test_user' PASSWORD 'Test@9876' DEFAULT CHARACTER
SET UTF8;
+CREATE DATABASE 'db_5' USER 'test_user' PASSWORD 'Test@9876' DEFAULT CHARACTER
SET UTF8;
+CREATE DATABASE 'db_6' USER 'test_user' PASSWORD 'Test@9876' DEFAULT CHARACTER
SET UTF8;
+CREATE DATABASE 'db_7' USER 'test_user' PASSWORD 'Test@9876' DEFAULT CHARACTER
SET UTF8;
+CREATE DATABASE 'db_8' USER 'test_user' PASSWORD 'Test@9876' DEFAULT CHARACTER
SET UTF8;
+CREATE DATABASE 'db_9' USER 'test_user' PASSWORD 'Test@9876' DEFAULT CHARACTER
SET UTF8;
+
+CONNECT 'db_0' USER 'test_user' PASSWORD 'Test@9876';
+
+CREATE TABLE t_order (order_id BIGINT PRIMARY KEY, user_id INT NOT NULL,
status VARCHAR(50) NOT NULL, merchant_id INT, remark VARCHAR(50) NOT NULL,
creation_date DATE NOT NULL);
+CREATE TABLE t_order_item (item_id BIGINT PRIMARY KEY, order_id BIGINT NOT
NULL, user_id INT NOT NULL, product_id INT NOT NULL, quantity INT NOT NULL,
creation_date DATE NOT NULL);
+CREATE TABLE t_user (user_id INT PRIMARY KEY, user_name VARCHAR(50) NOT NULL,
password VARCHAR(50) NOT NULL, email VARCHAR(50) NOT NULL, telephone CHAR(11)
NOT NULL, creation_date DATE NOT NULL);
+CREATE TABLE t_product (product_id INT PRIMARY KEY, product_name VARCHAR(50)
NOT NULL, category_id INT NOT NULL, price DECIMAL(10, 2) NOT NULL, status
VARCHAR(50) NOT NULL, creation_date DATE NOT NULL);
+CREATE TABLE t_product_category (category_id INT PRIMARY KEY, category_name
VARCHAR(50) NOT NULL, parent_id INT NOT NULL, level SMALLINT NOT NULL,
creation_date DATE NOT NULL);
+CREATE TABLE t_country (country_id SMALLINT PRIMARY KEY, country_name
VARCHAR(50), continent_name VARCHAR(50), creation_date DATE NOT NULL);
+CREATE INDEX order_index_t_order ON t_order (order_id);
+
+CONNECT 'db_1' USER 'test_user' PASSWORD 'Test@9876';
+
+CREATE TABLE t_order (order_id BIGINT PRIMARY KEY, user_id INT NOT NULL,
status VARCHAR(50) NOT NULL, merchant_id INT, remark VARCHAR(50) NOT NULL,
creation_date DATE NOT NULL);
+CREATE TABLE t_order_item (item_id BIGINT PRIMARY KEY, order_id BIGINT NOT
NULL, user_id INT NOT NULL, product_id INT NOT NULL, quantity INT NOT NULL,
creation_date DATE NOT NULL);
+CREATE TABLE t_merchant (merchant_id INT PRIMARY KEY, country_id SMALLINT NOT
NULL, merchant_name VARCHAR(50) NOT NULL, business_code VARCHAR(50) NOT NULL,
telephone CHAR(11) NOT NULL, creation_date DATE NOT NULL);
+CREATE TABLE t_product_detail (detail_id INT PRIMARY KEY, product_id INT NOT
NULL, description VARCHAR(50) NOT NULL, creation_date DATE NOT NULL);
+CREATE TABLE t_product_category (category_id INT PRIMARY KEY, category_name
VARCHAR(50) NOT NULL, parent_id INT NOT NULL, level SMALLINT NOT NULL,
creation_date DATE NOT NULL);
+CREATE TABLE t_country (country_id SMALLINT PRIMARY KEY, country_name
VARCHAR(50), continent_name VARCHAR(50), creation_date DATE NOT NULL);
+CREATE INDEX order_index_t_order ON t_order (order_id);
+
+CONNECT 'db_2' USER 'test_user' PASSWORD 'Test@9876';
+
+CREATE TABLE t_order (order_id BIGINT PRIMARY KEY, user_id INT NOT NULL,
status VARCHAR(50) NOT NULL, merchant_id INT, remark VARCHAR(50) NOT NULL,
creation_date DATE NOT NULL);
+CREATE TABLE t_order_item (item_id BIGINT PRIMARY KEY, order_id BIGINT NOT
NULL, user_id INT NOT NULL, product_id INT NOT NULL, quantity INT NOT NULL,
creation_date DATE NOT NULL);
+CREATE TABLE t_product_category (category_id INT PRIMARY KEY, category_name
VARCHAR(50) NOT NULL, parent_id INT NOT NULL, level SMALLINT NOT NULL,
creation_date DATE NOT NULL);
+CREATE TABLE t_country (country_id SMALLINT PRIMARY KEY, country_name
VARCHAR(50), continent_name VARCHAR(50), creation_date DATE NOT NULL);
+CREATE INDEX order_index_t_order ON t_order (order_id);
+
+CONNECT 'db_3' USER 'test_user' PASSWORD 'Test@9876';
+
+CREATE TABLE t_order (order_id BIGINT PRIMARY KEY, user_id INT NOT NULL,
status VARCHAR(50) NOT NULL, merchant_id INT, remark VARCHAR(50) NOT NULL,
creation_date DATE NOT NULL);
+CREATE TABLE t_order_item (item_id BIGINT PRIMARY KEY, order_id BIGINT NOT
NULL, user_id INT NOT NULL, product_id INT NOT NULL, quantity INT NOT NULL,
creation_date DATE NOT NULL);
+CREATE TABLE t_product_category (category_id INT PRIMARY KEY, category_name
VARCHAR(50) NOT NULL, parent_id INT NOT NULL, level SMALLINT NOT NULL,
creation_date DATE NOT NULL);
+CREATE TABLE t_country (country_id SMALLINT PRIMARY KEY, country_name
VARCHAR(50), continent_name VARCHAR(50), creation_date DATE NOT NULL);
+CREATE INDEX order_index_t_order ON t_order (order_id);
+
+CONNECT 'db_4' USER 'test_user' PASSWORD 'Test@9876';
+
+CREATE TABLE t_order (order_id BIGINT PRIMARY KEY, user_id INT NOT NULL,
status VARCHAR(50) NOT NULL, merchant_id INT, remark VARCHAR(50) NOT NULL,
creation_date DATE NOT NULL);
+CREATE TABLE t_order_item (item_id BIGINT PRIMARY KEY, order_id BIGINT NOT
NULL, user_id INT NOT NULL, product_id INT NOT NULL, quantity INT NOT NULL,
creation_date DATE NOT NULL);
+CREATE TABLE t_product_category (category_id INT PRIMARY KEY, category_name
VARCHAR(50) NOT NULL, parent_id INT NOT NULL, level SMALLINT NOT NULL,
creation_date DATE NOT NULL);
+CREATE TABLE t_country (country_id SMALLINT PRIMARY KEY, country_name
VARCHAR(50), continent_name VARCHAR(50), creation_date DATE NOT NULL);
+CREATE INDEX order_index_t_order ON t_order (order_id);
+
+CONNECT 'db_5' USER 'test_user' PASSWORD 'Test@9876';
+
+CREATE TABLE t_order (order_id BIGINT PRIMARY KEY, user_id INT NOT NULL,
status VARCHAR(50) NOT NULL, merchant_id INT, remark VARCHAR(50) NOT NULL,
creation_date DATE NOT NULL);
+CREATE TABLE t_order_item (item_id BIGINT PRIMARY KEY, order_id BIGINT NOT
NULL, user_id INT NOT NULL, product_id INT NOT NULL, quantity INT NOT NULL,
creation_date DATE NOT NULL);
+CREATE TABLE t_product_category (category_id INT PRIMARY KEY, category_name
VARCHAR(50) NOT NULL, parent_id INT NOT NULL, level SMALLINT NOT NULL,
creation_date DATE NOT NULL);
+CREATE TABLE t_country (country_id SMALLINT PRIMARY KEY, country_name
VARCHAR(50), continent_name VARCHAR(50), creation_date DATE NOT NULL);
+CREATE INDEX order_index_t_order ON t_order (order_id);
+
+CONNECT 'db_6' USER 'test_user' PASSWORD 'Test@9876';
+
+CREATE TABLE t_order (order_id BIGINT PRIMARY KEY, user_id INT NOT NULL,
status VARCHAR(50) NOT NULL, merchant_id INT, remark VARCHAR(50) NOT NULL,
creation_date DATE NOT NULL);
+CREATE TABLE t_order_item (item_id BIGINT PRIMARY KEY, order_id BIGINT NOT
NULL, user_id INT NOT NULL, product_id INT NOT NULL, quantity INT NOT NULL,
creation_date DATE NOT NULL);
+CREATE TABLE t_product_category (category_id INT PRIMARY KEY, category_name
VARCHAR(50) NOT NULL, parent_id INT NOT NULL, level SMALLINT NOT NULL,
creation_date DATE NOT NULL);
+CREATE TABLE t_country (country_id SMALLINT PRIMARY KEY, country_name
VARCHAR(50), continent_name VARCHAR(50), creation_date DATE NOT NULL);
+CREATE INDEX order_index_t_order ON t_order (order_id);
+
+CONNECT 'db_7' USER 'test_user' PASSWORD 'Test@9876';
+
+CREATE TABLE t_order (order_id BIGINT PRIMARY KEY, user_id INT NOT NULL,
status VARCHAR(50) NOT NULL, merchant_id INT, remark VARCHAR(50) NOT NULL,
creation_date DATE NOT NULL);
+CREATE TABLE t_order_item (item_id BIGINT PRIMARY KEY, order_id BIGINT NOT
NULL, user_id INT NOT NULL, product_id INT NOT NULL, quantity INT NOT NULL,
creation_date DATE NOT NULL);
+CREATE TABLE t_product_category (category_id INT PRIMARY KEY, category_name
VARCHAR(50) NOT NULL, parent_id INT NOT NULL, level SMALLINT NOT NULL,
creation_date DATE NOT NULL);
+CREATE TABLE t_country (country_id SMALLINT PRIMARY KEY, country_name
VARCHAR(50), continent_name VARCHAR(50), creation_date DATE NOT NULL);
+CREATE INDEX order_index_t_order ON t_order (order_id);
+
+CONNECT 'db_8' USER 'test_user' PASSWORD 'Test@9876';
+
+CREATE TABLE t_order (order_id BIGINT PRIMARY KEY, user_id INT NOT NULL,
status VARCHAR(50) NOT NULL, merchant_id INT, remark VARCHAR(50) NOT NULL,
creation_date DATE NOT NULL);
+CREATE TABLE t_order_item (item_id BIGINT PRIMARY KEY, order_id BIGINT NOT
NULL, user_id INT NOT NULL, product_id INT NOT NULL, quantity INT NOT NULL,
creation_date DATE NOT NULL);
+CREATE TABLE t_product_category (category_id INT PRIMARY KEY, category_name
VARCHAR(50) NOT NULL, parent_id INT NOT NULL, level SMALLINT NOT NULL,
creation_date DATE NOT NULL);
+CREATE TABLE t_country (country_id SMALLINT PRIMARY KEY, country_name
VARCHAR(50), continent_name VARCHAR(50), creation_date DATE NOT NULL);
+CREATE INDEX order_index_t_order ON t_order (order_id);
+
+CONNECT 'db_9' USER 'test_user' PASSWORD 'Test@9876';
+
+CREATE TABLE t_order (order_id BIGINT PRIMARY KEY, user_id INT NOT NULL,
status VARCHAR(50) NOT NULL, merchant_id INT, remark VARCHAR(50) NOT NULL,
creation_date DATE NOT NULL);
+CREATE TABLE t_order_item (item_id BIGINT PRIMARY KEY, order_id BIGINT NOT
NULL, user_id INT NOT NULL, product_id INT NOT NULL, quantity INT NOT NULL,
creation_date DATE NOT NULL);
+CREATE TABLE t_product_category (category_id INT PRIMARY KEY, category_name
VARCHAR(50) NOT NULL, parent_id INT NOT NULL, level SMALLINT NOT NULL,
creation_date DATE NOT NULL);
+CREATE TABLE t_country (country_id SMALLINT PRIMARY KEY, country_name
VARCHAR(50), continent_name VARCHAR(50), creation_date DATE NOT NULL);
+CREATE INDEX order_index_t_order ON t_order (order_id);
diff --git
a/test/e2e/sql/src/test/resources/env/scenario/db/data/expected/init-sql/firebird/60-scenario-expected-init.sql
b/test/e2e/sql/src/test/resources/env/scenario/db/data/expected/init-sql/firebird/60-scenario-expected-init.sql
new file mode 100644
index 00000000000..58e6f821da7
--- /dev/null
+++
b/test/e2e/sql/src/test/resources/env/scenario/db/data/expected/init-sql/firebird/60-scenario-expected-init.sql
@@ -0,0 +1,30 @@
+--
+-- 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.
+--
+
+CREATE DATABASE 'expected_dataset' USER 'test_user' PASSWORD 'Test@9876'
DEFAULT CHARACTER SET UTF8;
+
+CONNECT 'expected_dataset' USER 'test_user' PASSWORD 'Test@9876';
+
+CREATE TABLE t_order (order_id BIGINT PRIMARY KEY, user_id INT NOT NULL,
status VARCHAR(50) NOT NULL, merchant_id INT, remark VARCHAR(50) NOT NULL,
creation_date DATE NOT NULL);
+CREATE TABLE t_order_item (item_id BIGINT PRIMARY KEY, order_id BIGINT NOT
NULL, user_id INT NOT NULL, product_id INT NOT NULL, quantity INT NOT NULL,
creation_date DATE NOT NULL);
+CREATE TABLE t_user (user_id INT PRIMARY KEY, user_name VARCHAR(50) NOT NULL,
password VARCHAR(50) NOT NULL, email VARCHAR(50) NOT NULL, telephone CHAR(11)
NOT NULL, creation_date DATE NOT NULL);
+CREATE TABLE t_merchant (merchant_id INT PRIMARY KEY, country_id SMALLINT NOT
NULL, merchant_name VARCHAR(50) NOT NULL, business_code VARCHAR(50) NOT NULL,
telephone CHAR(11) NOT NULL, creation_date DATE NOT NULL);
+CREATE TABLE t_product (product_id INT PRIMARY KEY, product_name VARCHAR(50)
NOT NULL, category_id INT NOT NULL, price DECIMAL(10, 2) NOT NULL, status
VARCHAR(50) NOT NULL, creation_date DATE NOT NULL);
+CREATE TABLE t_product_detail (detail_id INT PRIMARY KEY, product_id INT NOT
NULL, description VARCHAR(50) NOT NULL, creation_date DATE NOT NULL);
+CREATE TABLE t_product_category (category_id INT PRIMARY KEY, category_name
VARCHAR(50) NOT NULL, parent_id INT NOT NULL, level SMALLINT NOT NULL,
creation_date DATE NOT NULL);
+CREATE TABLE t_country (country_id SMALLINT PRIMARY KEY, country_name
VARCHAR(50), continent_name VARCHAR(50), creation_date DATE NOT NULL);
+CREATE INDEX order_index_t_order ON t_order (order_id);
diff --git
a/test/e2e/sql/src/test/resources/env/scenario/db/proxy/conf/firebird/database-db.yaml
b/test/e2e/sql/src/test/resources/env/scenario/db/proxy/conf/firebird/database-db.yaml
new file mode 100644
index 00000000000..d9193a632b8
--- /dev/null
+++
b/test/e2e/sql/src/test/resources/env/scenario/db/proxy/conf/firebird/database-db.yaml
@@ -0,0 +1,182 @@
+#
+# 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.
+#
+
+databaseName: db
+
+dataSources:
+ ds_0:
+ url: jdbc:firebirdsql://firebird.db.host:3050/db_0?encoding=UTF8
+ driverClassName: org.firebirdsql.jdbc.FBDriver
+ username: test_user
+ password: Test@9876
+ connectionTimeoutMilliseconds: 30000
+ idleTimeoutMilliseconds: 60000
+ maxLifetimeMilliseconds: 1800000
+ maxPoolSize: 50
+ minPoolSize: 2
+ ds_1:
+ url: jdbc:firebirdsql://firebird.db.host:3050/db_1?encoding=UTF8
+ driverClassName: org.firebirdsql.jdbc.FBDriver
+ username: test_user
+ password: Test@9876
+ connectionTimeoutMilliseconds: 30000
+ idleTimeoutMilliseconds: 60000
+ maxLifetimeMilliseconds: 1800000
+ maxPoolSize: 50
+ minPoolSize: 2
+ ds_2:
+ url: jdbc:firebirdsql://firebird.db.host:3050/db_2?encoding=UTF8
+ driverClassName: org.firebirdsql.jdbc.FBDriver
+ username: test_user
+ password: Test@9876
+ connectionTimeoutMilliseconds: 30000
+ idleTimeoutMilliseconds: 60000
+ maxLifetimeMilliseconds: 1800000
+ maxPoolSize: 50
+ minPoolSize: 2
+ ds_3:
+ url: jdbc:firebirdsql://firebird.db.host:3050/db_3?encoding=UTF8
+ driverClassName: org.firebirdsql.jdbc.FBDriver
+ username: test_user
+ password: Test@9876
+ connectionTimeoutMilliseconds: 30000
+ idleTimeoutMilliseconds: 60000
+ maxLifetimeMilliseconds: 1800000
+ maxPoolSize: 50
+ minPoolSize: 2
+ ds_4:
+ url: jdbc:firebirdsql://firebird.db.host:3050/db_4?encoding=UTF8
+ driverClassName: org.firebirdsql.jdbc.FBDriver
+ username: test_user
+ password: Test@9876
+ connectionTimeoutMilliseconds: 30000
+ idleTimeoutMilliseconds: 60000
+ maxLifetimeMilliseconds: 1800000
+ maxPoolSize: 50
+ minPoolSize: 2
+ ds_5:
+ url: jdbc:firebirdsql://firebird.db.host:3050/db_5?encoding=UTF8
+ driverClassName: org.firebirdsql.jdbc.FBDriver
+ username: test_user
+ password: Test@9876
+ connectionTimeoutMilliseconds: 30000
+ idleTimeoutMilliseconds: 60000
+ maxLifetimeMilliseconds: 1800000
+ maxPoolSize: 50
+ minPoolSize: 2
+ ds_6:
+ url: jdbc:firebirdsql://firebird.db.host:3050/db_6?encoding=UTF8
+ driverClassName: org.firebirdsql.jdbc.FBDriver
+ username: test_user
+ password: Test@9876
+ connectionTimeoutMilliseconds: 30000
+ idleTimeoutMilliseconds: 60000
+ maxLifetimeMilliseconds: 1800000
+ maxPoolSize: 50
+ minPoolSize: 2
+ ds_7:
+ url: jdbc:firebirdsql://firebird.db.host:3050/db_7?encoding=UTF8
+ driverClassName: org.firebirdsql.jdbc.FBDriver
+ username: test_user
+ password: Test@9876
+ connectionTimeoutMilliseconds: 30000
+ idleTimeoutMilliseconds: 60000
+ maxLifetimeMilliseconds: 1800000
+ maxPoolSize: 50
+ minPoolSize: 2
+ ds_8:
+ url: jdbc:firebirdsql://firebird.db.host:3050/db_8?encoding=UTF8
+ driverClassName: org.firebirdsql.jdbc.FBDriver
+ username: test_user
+ password: Test@9876
+ connectionTimeoutMilliseconds: 30000
+ idleTimeoutMilliseconds: 60000
+ maxLifetimeMilliseconds: 1800000
+ maxPoolSize: 50
+ minPoolSize: 2
+ ds_9:
+ url: jdbc:firebirdsql://firebird.db.host:3050/db_9?encoding=UTF8
+ driverClassName: org.firebirdsql.jdbc.FBDriver
+ username: test_user
+ password: Test@9876
+ connectionTimeoutMilliseconds: 30000
+ idleTimeoutMilliseconds: 60000
+ maxLifetimeMilliseconds: 1800000
+ maxPoolSize: 50
+ minPoolSize: 2
+
+rules:
+- !SINGLE
+ tables:
+ - "*.*"
+- !SHARDING
+ tables:
+ T_ORDER:
+ actualDataNodes: ds_${0..9}.T_ORDER
+ databaseStrategy:
+ standard:
+ shardingColumn: user_id
+ shardingAlgorithmName: e2e_standard_fixture
+ T_ORDER_ITEM:
+ actualDataNodes: ds_${0..9}.T_ORDER_ITEM
+ databaseStrategy:
+ standard:
+ shardingColumn: user_id
+ shardingAlgorithmName: e2e_standard_fixture
+ auditStrategy:
+ auditorNames:
+ - auditor_constant
+ allowHintDisable: true
+ T_ORDER_SHARDING_VIEW:
+ actualDataNodes: ds_${0..9}.T_ORDER_SHARDING_VIEW
+ databaseStrategy:
+ standard:
+ shardingColumn: user_id
+ shardingAlgorithmName: e2e_standard_fixture
+ T_ORDER_DETAILS:
+ actualDataNodes: ds_${0..9}.T_ORDER_DETAILS
+ databaseStrategy:
+ standard:
+ shardingColumn: user_id
+ shardingAlgorithmName: e2e_standard_fixture
+ keyGenerateStrategies:
+ t_order_item_item_id:
+ keyGenerateType: column
+ keyGeneratorName: auto_increment
+ logicTable: T_ORDER_ITEM
+ keyGenerateColumn: item_id
+
+ bindingTables:
+ - ref_0:T_ORDER,T_ORDER_ITEM,T_ORDER_SHARDING_VIEW,T_ORDER_DETAILS
+ shardingAlgorithms:
+ e2e_standard_fixture:
+ type: E2E.SHARDING.STANDARD.FIXTURE
+
+ keyGenerators:
+ auto_increment:
+ type: E2E.AUTO_INCREMENT.FIXTURE
+
+ auditors:
+ auditor_constant:
+ type: E2E.AUDITOR.FIXTURE
+
+- !BROADCAST
+ tables:
+ - T_BROADCAST_TABLE
+ - T_BROADCAST_TABLE_FOR_DDL
+ - T_COUNTRY
+ - T_PRODUCT_CATEGORY