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 47f4a2dbceb Support multiple logical databases in SQL E2E adapters
(#39831)
47f4a2dbceb is described below
commit 47f4a2dbceb9d8272cc5aed420b64c109fd2171d
Author: Liang Zhang <[email protected]>
AuthorDate: Sun Sep 13 19:16:22 2026 +0800
Support multiple logical databases in SQL E2E adapters (#39831)
---
.../env/container/adapter/AdapterContainer.java | 17 +++++++++++
.../impl/ShardingSphereJdbcEmbeddedContainer.java | 25 +++++++++++-----
.../impl/ShardingSphereProxyDockerContainer.java | 29 +++++++++++++-----
.../impl/ShardingSphereProxyEmbeddedContainer.java | 31 +++++++++++++------
.../casse/assertion/SQLE2ETestCaseAssertion.java | 3 ++
.../test/e2e/sql/env/SQLE2EEnvironmentEngine.java | 11 +++++++
.../env/container/compose/ContainerComposer.java | 16 ++++++++++
.../compose/ContainerComposerRegistry.java | 11 +++++--
.../compose/mode/ClusterContainerComposer.java | 13 +++++++-
.../compose/mode/StandaloneContainerComposer.java | 13 +++++++-
.../e2e/sql/it/sql/dml/AdditionalDMLE2EIT.java | 14 ++++-----
.../test/e2e/sql/it/sql/dml/BaseDMLE2EIT.java | 4 +--
.../test/e2e/sql/it/sql/dml/BatchDMLE2EIT.java | 10 +++++--
.../test/e2e/sql/it/sql/dml/GeneralDMLE2EIT.java | 4 +--
.../e2e/sql/it/sql/dql/AdditionalDQLE2EIT.java | 8 ++---
.../test/e2e/sql/it/sql/dql/GeneralDQLE2EIT.java | 12 ++++----
.../test/resources/cases/dml/e2e-dml-update.xml | 2 +-
.../passthrough/e2e-dql-select-for-passthrough.xml | 5 ++++
.../passthrough/mysql/select_default_database.xml | 24 +++++++++++++++
.../mysql/select_secondary_database.xml | 24 +++++++++++++++
.../conf/mysql/database-passthrough-secondary.yaml | 35 ++++++++++++++++++++++
21 files changed, 257 insertions(+), 54 deletions(-)
diff --git
a/test/e2e/env/src/test/java/org/apache/shardingsphere/test/e2e/env/container/adapter/AdapterContainer.java
b/test/e2e/env/src/test/java/org/apache/shardingsphere/test/e2e/env/container/adapter/AdapterContainer.java
index b55086c53d9..9dd980ebf70 100644
---
a/test/e2e/env/src/test/java/org/apache/shardingsphere/test/e2e/env/container/adapter/AdapterContainer.java
+++
b/test/e2e/env/src/test/java/org/apache/shardingsphere/test/e2e/env/container/adapter/AdapterContainer.java
@@ -20,6 +20,7 @@ package
org.apache.shardingsphere.test.e2e.env.container.adapter;
import org.apache.shardingsphere.test.e2e.env.container.E2EContainer;
import javax.sql.DataSource;
+import java.util.Collection;
/**
* Adapter container.
@@ -33,4 +34,20 @@ public interface AdapterContainer extends E2EContainer {
* @return target data source
*/
DataSource getTargetDataSource(String serverLists);
+
+ /**
+ * Get target data source.
+ *
+ * @param serverLists server lists
+ * @param dataSourceName data source name
+ * @return target data source
+ */
+ DataSource getTargetDataSource(String serverLists, String dataSourceName);
+
+ /**
+ * Get target data sources.
+ *
+ * @return target data sources
+ */
+ Collection<DataSource> getTargetDataSources();
}
diff --git
a/test/e2e/env/src/test/java/org/apache/shardingsphere/test/e2e/env/container/adapter/impl/ShardingSphereJdbcEmbeddedContainer.java
b/test/e2e/env/src/test/java/org/apache/shardingsphere/test/e2e/env/container/adapter/impl/ShardingSphereJdbcEmbeddedContainer.java
index f247973c450..0f42e53a610 100644
---
a/test/e2e/env/src/test/java/org/apache/shardingsphere/test/e2e/env/container/adapter/impl/ShardingSphereJdbcEmbeddedContainer.java
+++
b/test/e2e/env/src/test/java/org/apache/shardingsphere/test/e2e/env/container/adapter/impl/ShardingSphereJdbcEmbeddedContainer.java
@@ -17,6 +17,7 @@
package org.apache.shardingsphere.test.e2e.env.container.adapter.impl;
+import com.google.common.base.Strings;
import com.zaxxer.hikari.HikariDataSource;
import lombok.RequiredArgsConstructor;
import lombok.SneakyThrows;
@@ -31,9 +32,10 @@ import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
+import java.util.Collection;
import java.util.Map;
import java.util.Map.Entry;
-import java.util.concurrent.atomic.AtomicReference;
+import java.util.concurrent.ConcurrentHashMap;
/**
* ShardingSphere JDBC embedded container.
@@ -43,7 +45,7 @@ public final class ShardingSphereJdbcEmbeddedContainer
implements EmbeddedE2ECon
private final StorageContainer storageContainer;
- private final AtomicReference<DataSource> targetDataSourceProvider = new
AtomicReference<>();
+ private final Map<String, DataSource> targetDataSources = new
ConcurrentHashMap<>();
private final String configPath;
@@ -53,14 +55,21 @@ public final class ShardingSphereJdbcEmbeddedContainer
implements EmbeddedE2ECon
@Override
public DataSource getTargetDataSource(final String serverLists) {
- DataSource dataSource = targetDataSourceProvider.get();
- if (null == dataSource) {
- targetDataSourceProvider.set(createTargetDataSource());
- }
- return targetDataSourceProvider.get();
+ return getTargetDataSource(serverLists, configPath);
+ }
+
+ @Override
+ public DataSource getTargetDataSource(final String serverLists, final
String dataSourceName) {
+ String effectiveDataSourceName = Strings.isNullOrEmpty(dataSourceName)
? configPath : dataSourceName;
+ return targetDataSources.computeIfAbsent(effectiveDataSourceName,
this::createTargetDataSource);
+ }
+
+ @Override
+ public Collection<DataSource> getTargetDataSources() {
+ return targetDataSources.values();
}
- private DataSource createTargetDataSource() {
+ private DataSource createTargetDataSource(final String dataSourceName) {
HikariDataSource result = new HikariDataSource();
result.setDriverClassName("org.apache.shardingsphere.driver.ShardingSphereDriver");
result.setJdbcUrl("jdbc:shardingsphere:absolutepath:" +
processFile(configPath, storageContainer.getLinkReplacements()));
diff --git
a/test/e2e/env/src/test/java/org/apache/shardingsphere/test/e2e/env/container/adapter/impl/ShardingSphereProxyDockerContainer.java
b/test/e2e/env/src/test/java/org/apache/shardingsphere/test/e2e/env/container/adapter/impl/ShardingSphereProxyDockerContainer.java
index 0e49ac7274e..7708e607b31 100644
---
a/test/e2e/env/src/test/java/org/apache/shardingsphere/test/e2e/env/container/adapter/impl/ShardingSphereProxyDockerContainer.java
+++
b/test/e2e/env/src/test/java/org/apache/shardingsphere/test/e2e/env/container/adapter/impl/ShardingSphereProxyDockerContainer.java
@@ -33,7 +33,9 @@ import javax.sql.DataSource;
import java.sql.DriverManager;
import java.time.Duration;
import java.time.temporal.ChronoUnit;
-import java.util.concurrent.atomic.AtomicReference;
+import java.util.Collection;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
/**
* ShardingSphere proxy docker container.
@@ -44,7 +46,7 @@ public final class ShardingSphereProxyDockerContainer extends
DockerE2EContainer
private final StorageContainerConnectOption storageContainerConnectOption;
- private final AtomicReference<DataSource> targetDataSourceProvider = new
AtomicReference<>();
+ private final Map<String, DataSource> targetDataSources = new
ConcurrentHashMap<>();
public ShardingSphereProxyDockerContainer(final DatabaseType databaseType,
final AdaptorContainerConfiguration config) {
super(ProxyContainerConstants.PROXY_CONTAINER_NAME_PREFIX,
config.getAdapterContainerImage());
@@ -70,12 +72,23 @@ public final class ShardingSphereProxyDockerContainer
extends DockerE2EContainer
@Override
public DataSource getTargetDataSource(final String serverLists) {
- DataSource dataSource = targetDataSourceProvider.get();
- if (null == dataSource) {
-
targetDataSourceProvider.set(StorageContainerUtils.generateDataSource(
- storageContainerConnectOption.getProxyURL(getHost(),
getMappedPort(3307), config.getProxyDataSourceName()),
ProxyContainerConstants.USER, ProxyContainerConstants.PASSWORD, 2));
- }
- return targetDataSourceProvider.get();
+ return getTargetDataSource(serverLists,
config.getProxyDataSourceName());
+ }
+
+ @Override
+ public DataSource getTargetDataSource(final String serverLists, final
String dataSourceName) {
+ String effectiveDataSourceName = Strings.isNullOrEmpty(dataSourceName)
? config.getProxyDataSourceName() : dataSourceName;
+ return targetDataSources.computeIfAbsent(effectiveDataSourceName,
this::createTargetDataSource);
+ }
+
+ private DataSource createTargetDataSource(final String dataSourceName) {
+ return StorageContainerUtils.generateDataSource(
+ storageContainerConnectOption.getProxyURL(getHost(),
getMappedPort(3307), dataSourceName), ProxyContainerConstants.USER,
ProxyContainerConstants.PASSWORD, 2);
+ }
+
+ @Override
+ public Collection<DataSource> getTargetDataSources() {
+ return targetDataSources.values();
}
@Override
diff --git
a/test/e2e/env/src/test/java/org/apache/shardingsphere/test/e2e/env/container/adapter/impl/ShardingSphereProxyEmbeddedContainer.java
b/test/e2e/env/src/test/java/org/apache/shardingsphere/test/e2e/env/container/adapter/impl/ShardingSphereProxyEmbeddedContainer.java
index 5083042d5db..b44226dcbad 100644
---
a/test/e2e/env/src/test/java/org/apache/shardingsphere/test/e2e/env/container/adapter/impl/ShardingSphereProxyEmbeddedContainer.java
+++
b/test/e2e/env/src/test/java/org/apache/shardingsphere/test/e2e/env/container/adapter/impl/ShardingSphereProxyEmbeddedContainer.java
@@ -17,6 +17,7 @@
package org.apache.shardingsphere.test.e2e.env.container.adapter.impl;
+import com.google.common.base.Strings;
import io.netty.channel.ChannelFuture;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
@@ -59,6 +60,7 @@ import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.sql.SQLException;
+import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedHashMap;
@@ -67,7 +69,7 @@ import java.util.Map;
import java.util.Map.Entry;
import java.util.Objects;
import java.util.Set;
-import java.util.concurrent.atomic.AtomicReference;
+import java.util.concurrent.ConcurrentHashMap;
/**
* ShardingSphere proxy embedded container.
@@ -87,7 +89,7 @@ public final class ShardingSphereProxyEmbeddedContainer
implements EmbeddedE2ECo
private final int proxyPort;
- private final AtomicReference<DataSource> targetDataSourceProvider = new
AtomicReference<>();
+ private final Map<String, DataSource> targetDataSources = new
ConcurrentHashMap<>();
@Getter
private final Set<Startable> dependencies = new HashSet<>();
@@ -240,13 +242,24 @@ public final class ShardingSphereProxyEmbeddedContainer
implements EmbeddedE2ECo
@Override
public DataSource getTargetDataSource(final String serverLists) {
- DataSource dataSource = targetDataSourceProvider.get();
- if (null == dataSource) {
- StorageContainerConnectOption storageContainerConnectOption =
DatabaseTypedSPILoader.getService(StorageContainerOption.class,
databaseType).getConnectOption();
-
targetDataSourceProvider.set(StorageContainerUtils.generateDataSource(storageContainerConnectOption.getURL(
- "127.0.0.1", getProxyPort(),
config.getProxyDataSourceName()), ProxyContainerConstants.USER,
ProxyContainerConstants.PASSWORD, 2));
- }
- return targetDataSourceProvider.get();
+ return getTargetDataSource(serverLists,
config.getProxyDataSourceName());
+ }
+
+ @Override
+ public DataSource getTargetDataSource(final String serverLists, final
String dataSourceName) {
+ String effectiveDataSourceName = Strings.isNullOrEmpty(dataSourceName)
? config.getProxyDataSourceName() : dataSourceName;
+ return targetDataSources.computeIfAbsent(effectiveDataSourceName,
this::createTargetDataSource);
+ }
+
+ private DataSource createTargetDataSource(final String dataSourceName) {
+ StorageContainerConnectOption storageContainerConnectOption =
DatabaseTypedSPILoader.getService(StorageContainerOption.class,
databaseType).getConnectOption();
+ return
StorageContainerUtils.generateDataSource(storageContainerConnectOption.getURL(
+ "127.0.0.1", getProxyPort(), dataSourceName),
ProxyContainerConstants.USER, ProxyContainerConstants.PASSWORD, 2);
+ }
+
+ @Override
+ public Collection<DataSource> getTargetDataSources() {
+ return targetDataSources.values();
}
@Override
diff --git
a/test/e2e/sql/src/test/java/org/apache/shardingsphere/test/e2e/sql/cases/casse/assertion/SQLE2ETestCaseAssertion.java
b/test/e2e/sql/src/test/java/org/apache/shardingsphere/test/e2e/sql/cases/casse/assertion/SQLE2ETestCaseAssertion.java
index ebe7edb1ede..db07ec6f634 100644
---
a/test/e2e/sql/src/test/java/org/apache/shardingsphere/test/e2e/sql/cases/casse/assertion/SQLE2ETestCaseAssertion.java
+++
b/test/e2e/sql/src/test/java/org/apache/shardingsphere/test/e2e/sql/cases/casse/assertion/SQLE2ETestCaseAssertion.java
@@ -42,6 +42,9 @@ public final class SQLE2ETestCaseAssertion {
@XmlAttribute(name = "expected-data-source-name")
private String expectedDataSourceName;
+ @XmlAttribute(name = "target-data-source-name")
+ private String targetDataSourceName;
+
@XmlAttribute(name = "expected-data-file")
private String expectedDataFile;
diff --git
a/test/e2e/sql/src/test/java/org/apache/shardingsphere/test/e2e/sql/env/SQLE2EEnvironmentEngine.java
b/test/e2e/sql/src/test/java/org/apache/shardingsphere/test/e2e/sql/env/SQLE2EEnvironmentEngine.java
index db29f45cae6..e916f927d6a 100644
---
a/test/e2e/sql/src/test/java/org/apache/shardingsphere/test/e2e/sql/env/SQLE2EEnvironmentEngine.java
+++
b/test/e2e/sql/src/test/java/org/apache/shardingsphere/test/e2e/sql/env/SQLE2EEnvironmentEngine.java
@@ -17,6 +17,7 @@
package org.apache.shardingsphere.test.e2e.sql.env;
+import com.google.common.base.Strings;
import lombok.AccessLevel;
import lombok.Getter;
import org.apache.shardingsphere.database.connector.core.DefaultDatabase;
@@ -63,6 +64,16 @@ public final class SQLE2EEnvironmentEngine {
executeLogicDatabaseInitSQLFileOnlyOnce(key, scenario, databaseType);
}
+ /**
+ * Get target data source.
+ *
+ * @param dataSourceName data source name
+ * @return target data source
+ */
+ public DataSource getTargetDataSource(final String dataSourceName) {
+ return Strings.isNullOrEmpty(dataSourceName) ? targetDataSource :
containerComposer.getTargetDataSource(dataSourceName);
+ }
+
private void executeLogicDatabaseInitSQLFileOnlyOnce(final String key,
final String scenario, final DatabaseType databaseType) {
Optional<String> logicDatabaseInitSQLFile = new
ScenarioDataPath(scenario,
Type.TARGETS).findTargetDatabaseInitSQLFile(DefaultDatabase.LOGIC_NAME,
databaseType);
if (!logicDatabaseInitSQLFile.isPresent()) {
diff --git
a/test/e2e/sql/src/test/java/org/apache/shardingsphere/test/e2e/sql/env/container/compose/ContainerComposer.java
b/test/e2e/sql/src/test/java/org/apache/shardingsphere/test/e2e/sql/env/container/compose/ContainerComposer.java
index c0a5633bf95..ba199d875ca 100644
---
a/test/e2e/sql/src/test/java/org/apache/shardingsphere/test/e2e/sql/env/container/compose/ContainerComposer.java
+++
b/test/e2e/sql/src/test/java/org/apache/shardingsphere/test/e2e/sql/env/container/compose/ContainerComposer.java
@@ -20,6 +20,7 @@ package
org.apache.shardingsphere.test.e2e.sql.env.container.compose;
import org.testcontainers.lifecycle.Startable;
import javax.sql.DataSource;
+import java.util.Collection;
import java.util.Map;
/**
@@ -34,6 +35,21 @@ public interface ContainerComposer extends Startable {
*/
DataSource getTargetDataSource();
+ /**
+ * Get target data source.
+ *
+ * @param dataSourceName data source name
+ * @return target data source
+ */
+ DataSource getTargetDataSource(String dataSourceName);
+
+ /**
+ * Get target data sources.
+ *
+ * @return target data sources
+ */
+ Collection<DataSource> getTargetDataSources();
+
/**
* Get actual data source map.
*
diff --git
a/test/e2e/sql/src/test/java/org/apache/shardingsphere/test/e2e/sql/env/container/compose/ContainerComposerRegistry.java
b/test/e2e/sql/src/test/java/org/apache/shardingsphere/test/e2e/sql/env/container/compose/ContainerComposerRegistry.java
index 65c10e5639d..30fc49c54da 100644
---
a/test/e2e/sql/src/test/java/org/apache/shardingsphere/test/e2e/sql/env/container/compose/ContainerComposerRegistry.java
+++
b/test/e2e/sql/src/test/java/org/apache/shardingsphere/test/e2e/sql/env/container/compose/ContainerComposerRegistry.java
@@ -26,6 +26,7 @@ import
org.apache.shardingsphere.test.e2e.sql.env.container.compose.mode.Cluster
import
org.apache.shardingsphere.test.e2e.sql.env.container.compose.mode.StandaloneContainerComposer;
import javax.sql.DataSource;
+import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
@@ -89,10 +90,8 @@ public final class ContainerComposerRegistry implements
AutoCloseable {
@Override
public void close() {
synchronized (containerComposers) {
- for (DataSource each : targetDataSources.values()) {
- closeTargetDataSource(each);
- }
for (ContainerComposer each : containerComposers.values()) {
+ closeTargetDataSources(each.getTargetDataSources());
closeDataSourceMap(each.getActualDataSourceMap());
closeDataSourceMap(each.getExpectedDataSourceMap());
closeContainer(each);
@@ -102,6 +101,12 @@ public final class ContainerComposerRegistry implements
AutoCloseable {
}
}
+ private void closeTargetDataSources(final Collection<DataSource>
targetDataSources) {
+ for (DataSource each : targetDataSources) {
+ closeTargetDataSource(each);
+ }
+ }
+
@SneakyThrows(Exception.class)
private void closeTargetDataSource(final DataSource targetDataSource) {
Preconditions.checkState(targetDataSource instanceof AutoCloseable,
"target data source is not implement AutoCloseable");
diff --git
a/test/e2e/sql/src/test/java/org/apache/shardingsphere/test/e2e/sql/env/container/compose/mode/ClusterContainerComposer.java
b/test/e2e/sql/src/test/java/org/apache/shardingsphere/test/e2e/sql/env/container/compose/mode/ClusterContainerComposer.java
index e7d361095ce..005f72c134a 100644
---
a/test/e2e/sql/src/test/java/org/apache/shardingsphere/test/e2e/sql/env/container/compose/mode/ClusterContainerComposer.java
+++
b/test/e2e/sql/src/test/java/org/apache/shardingsphere/test/e2e/sql/env/container/compose/mode/ClusterContainerComposer.java
@@ -39,6 +39,7 @@ import
org.apache.shardingsphere.test.e2e.sql.env.container.compose.ContainerCom
import
org.apache.shardingsphere.test.e2e.sql.env.container.config.SQLE2EProxyContainerConfigurationFactory;
import javax.sql.DataSource;
+import java.util.Collection;
import java.util.Map;
/**
@@ -81,7 +82,17 @@ public final class ClusterContainerComposer implements
ContainerComposer {
@Override
public DataSource getTargetDataSource() {
- return
adapterContainer.getTargetDataSource(governanceContainer.getServerLists());
+ return getTargetDataSource(null);
+ }
+
+ @Override
+ public DataSource getTargetDataSource(final String dataSourceName) {
+ return
adapterContainer.getTargetDataSource(governanceContainer.getServerLists(),
dataSourceName);
+ }
+
+ @Override
+ public Collection<DataSource> getTargetDataSources() {
+ return adapterContainer.getTargetDataSources();
}
@Override
diff --git
a/test/e2e/sql/src/test/java/org/apache/shardingsphere/test/e2e/sql/env/container/compose/mode/StandaloneContainerComposer.java
b/test/e2e/sql/src/test/java/org/apache/shardingsphere/test/e2e/sql/env/container/compose/mode/StandaloneContainerComposer.java
index 96ba69fdf42..9677aac8b77 100644
---
a/test/e2e/sql/src/test/java/org/apache/shardingsphere/test/e2e/sql/env/container/compose/mode/StandaloneContainerComposer.java
+++
b/test/e2e/sql/src/test/java/org/apache/shardingsphere/test/e2e/sql/env/container/compose/mode/StandaloneContainerComposer.java
@@ -35,6 +35,7 @@ import
org.apache.shardingsphere.test.e2e.sql.env.container.compose.ContainerCom
import
org.apache.shardingsphere.test.e2e.sql.env.container.config.SQLE2EProxyContainerConfigurationFactory;
import javax.sql.DataSource;
+import java.util.Collection;
import java.util.Map;
/**
@@ -70,7 +71,17 @@ public final class StandaloneContainerComposer implements
ContainerComposer {
@Override
public DataSource getTargetDataSource() {
- return adapterContainer.getTargetDataSource(null);
+ return getTargetDataSource(null);
+ }
+
+ @Override
+ public DataSource getTargetDataSource(final String dataSourceName) {
+ return adapterContainer.getTargetDataSource(null, dataSourceName);
+ }
+
+ @Override
+ public Collection<DataSource> getTargetDataSources() {
+ return adapterContainer.getTargetDataSources();
}
@Override
diff --git
a/test/e2e/sql/src/test/java/org/apache/shardingsphere/test/e2e/sql/it/sql/dml/AdditionalDMLE2EIT.java
b/test/e2e/sql/src/test/java/org/apache/shardingsphere/test/e2e/sql/it/sql/dml/AdditionalDMLE2EIT.java
index 48cc51f5c2a..898912a319a 100644
---
a/test/e2e/sql/src/test/java/org/apache/shardingsphere/test/e2e/sql/it/sql/dml/AdditionalDMLE2EIT.java
+++
b/test/e2e/sql/src/test/java/org/apache/shardingsphere/test/e2e/sql/it/sql/dml/AdditionalDMLE2EIT.java
@@ -54,7 +54,7 @@ class AdditionalDMLE2EIT extends BaseDMLE2EIT {
init(testParam);
try {
int actualUpdateCount;
- try (Connection connection =
getEnvironmentEngine().getTargetDataSource().getConnection()) {
+ try (Connection connection =
getEnvironmentEngine().getTargetDataSource(context.getAssertion().getTargetDataSourceName()).getConnection())
{
actualUpdateCount = SQLExecuteType.LITERAL ==
context.getSqlExecuteType()
?
executeUpdateForStatementWithAutoGeneratedKeys(testParam, context, connection)
:
executeUpdateForPreparedStatementWithAutoGeneratedKeys(testParam, context,
connection);
@@ -118,7 +118,7 @@ class AdditionalDMLE2EIT extends BaseDMLE2EIT {
init(testParam);
try {
int actualUpdateCount;
- try (Connection connection =
getEnvironmentEngine().getTargetDataSource().getConnection()) {
+ try (Connection connection =
getEnvironmentEngine().getTargetDataSource(context.getAssertion().getTargetDataSourceName()).getConnection())
{
actualUpdateCount = SQLExecuteType.LITERAL ==
context.getSqlExecuteType()
? executeUpdateForStatementWithColumnIndexes(context,
connection)
:
executeUpdateForPreparedStatementWithColumnIndexes(context, connection);
@@ -156,7 +156,7 @@ class AdditionalDMLE2EIT extends BaseDMLE2EIT {
init(testParam);
try {
int actualUpdateCount;
- try (Connection connection =
getEnvironmentEngine().getTargetDataSource().getConnection()) {
+ try (Connection connection =
getEnvironmentEngine().getTargetDataSource(context.getAssertion().getTargetDataSourceName()).getConnection())
{
actualUpdateCount = SQLExecuteType.LITERAL ==
context.getSqlExecuteType()
? executeUpdateForStatementWithColumnNames(context,
connection)
:
executeUpdateForPreparedStatementWithColumnNames(context, connection);
@@ -193,7 +193,7 @@ class AdditionalDMLE2EIT extends BaseDMLE2EIT {
init(testParam);
try {
int actualUpdateCount;
- try (Connection connection =
getEnvironmentEngine().getTargetDataSource().getConnection()) {
+ try (Connection connection =
getEnvironmentEngine().getTargetDataSource(context.getAssertion().getTargetDataSourceName()).getConnection())
{
actualUpdateCount = SQLExecuteType.LITERAL ==
context.getSqlExecuteType()
? executeForStatementWithoutAutoGeneratedKeys(context,
connection)
:
executeForPreparedStatementWithoutAutoGeneratedKeys(context, connection);
@@ -232,7 +232,7 @@ class AdditionalDMLE2EIT extends BaseDMLE2EIT {
init(testParam);
try {
int actualUpdateCount;
- try (Connection connection =
getEnvironmentEngine().getTargetDataSource().getConnection()) {
+ try (Connection connection =
getEnvironmentEngine().getTargetDataSource(context.getAssertion().getTargetDataSourceName()).getConnection())
{
actualUpdateCount = SQLExecuteType.LITERAL ==
context.getSqlExecuteType()
? executeForStatementWithAutoGeneratedKeys(testParam,
context, connection)
:
executeForPreparedStatementWithAutoGeneratedKeys(testParam, context,
connection);
@@ -276,7 +276,7 @@ class AdditionalDMLE2EIT extends BaseDMLE2EIT {
init(testParam);
try {
int actualUpdateCount;
- try (Connection connection =
getEnvironmentEngine().getTargetDataSource().getConnection()) {
+ try (Connection connection =
getEnvironmentEngine().getTargetDataSource(context.getAssertion().getTargetDataSourceName()).getConnection())
{
actualUpdateCount = SQLExecuteType.LITERAL ==
context.getSqlExecuteType()
? executeForStatementWithColumnIndexes(context,
connection)
:
executeForPreparedStatementWithColumnIndexes(context, connection);
@@ -316,7 +316,7 @@ class AdditionalDMLE2EIT extends BaseDMLE2EIT {
init(testParam);
try {
int actualUpdateCount;
- try (Connection connection =
getEnvironmentEngine().getTargetDataSource().getConnection()) {
+ try (Connection connection =
getEnvironmentEngine().getTargetDataSource(context.getAssertion().getTargetDataSourceName()).getConnection())
{
actualUpdateCount = SQLExecuteType.LITERAL ==
context.getSqlExecuteType()
? executeForStatementWithColumnNames(context,
connection)
: executeForPreparedStatementWithColumnNames(context,
connection);
diff --git
a/test/e2e/sql/src/test/java/org/apache/shardingsphere/test/e2e/sql/it/sql/dml/BaseDMLE2EIT.java
b/test/e2e/sql/src/test/java/org/apache/shardingsphere/test/e2e/sql/it/sql/dml/BaseDMLE2EIT.java
index 81aa2ee8cc9..4c20312a5df 100644
---
a/test/e2e/sql/src/test/java/org/apache/shardingsphere/test/e2e/sql/it/sql/dml/BaseDMLE2EIT.java
+++
b/test/e2e/sql/src/test/java/org/apache/shardingsphere/test/e2e/sql/it/sql/dml/BaseDMLE2EIT.java
@@ -378,7 +378,7 @@ public abstract class BaseDMLE2EIT implements SQLE2EIT {
if (null == assertion.getInitialSQL()) {
return;
}
- try (Connection connection =
getEnvironmentEngine().getTargetDataSource().getConnection()) {
+ try (Connection connection =
getEnvironmentEngine().getTargetDataSource(assertion.getTargetDataSourceName()).getConnection())
{
executeInitSQLs(assertion, connection);
}
}
@@ -401,7 +401,7 @@ public abstract class BaseDMLE2EIT implements SQLE2EIT {
protected void executeDestroySQLs(final SQLE2ETestCaseAssertion assertion)
throws SQLException {
if (null != assertion.getDestroySQL()) {
- try (Connection connection =
getEnvironmentEngine().getTargetDataSource().getConnection()) {
+ try (Connection connection =
getEnvironmentEngine().getTargetDataSource(assertion.getTargetDataSourceName()).getConnection())
{
executeDestroySQLs(assertion, connection);
}
}
diff --git
a/test/e2e/sql/src/test/java/org/apache/shardingsphere/test/e2e/sql/it/sql/dml/BatchDMLE2EIT.java
b/test/e2e/sql/src/test/java/org/apache/shardingsphere/test/e2e/sql/it/sql/dml/BatchDMLE2EIT.java
index 919f6324bab..6f689d1bcbe 100644
---
a/test/e2e/sql/src/test/java/org/apache/shardingsphere/test/e2e/sql/it/sql/dml/BatchDMLE2EIT.java
+++
b/test/e2e/sql/src/test/java/org/apache/shardingsphere/test/e2e/sql/it/sql/dml/BatchDMLE2EIT.java
@@ -28,6 +28,7 @@ import org.junit.jupiter.api.condition.EnabledIf;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ArgumentsSource;
+import javax.sql.DataSource;
import javax.xml.bind.JAXBException;
import java.io.IOException;
import java.sql.Connection;
@@ -47,7 +48,7 @@ class BatchDMLE2EIT extends BaseDMLE2EIT {
init(testParam);
try {
int[] actualUpdateCounts;
- try (Connection connection =
getEnvironmentEngine().getTargetDataSource().getConnection()) {
+ try (Connection connection =
getTargetDataSource(testParam).getConnection()) {
actualUpdateCounts =
executeBatchForPreparedStatement(testParam, connection);
}
assertDataSet(actualUpdateCounts, testParam);
@@ -61,6 +62,11 @@ class BatchDMLE2EIT extends BaseDMLE2EIT {
executeInitSQLs(testParam);
}
+ private DataSource getTargetDataSource(final CaseTestParameter testParam) {
+ SQLE2ETestCaseAssertion assertion =
testParam.getTestCaseContext().getTestCase().getAssertions().iterator().next();
+ return
getEnvironmentEngine().getTargetDataSource(assertion.getTargetDataSourceName());
+ }
+
void tearDown(final CaseTestParameter testParam) throws SQLException {
tearDown();
executeDestroySQLs(testParam);
@@ -99,7 +105,7 @@ class BatchDMLE2EIT extends BaseDMLE2EIT {
@ArgumentsSource(SQLE2EITArgumentsProvider.class)
void assertClearBatch(final CaseTestParameter testParam) throws
SQLException {
try (
- Connection connection =
getEnvironmentEngine().getTargetDataSource().getConnection();
+ Connection connection =
getTargetDataSource(testParam).getConnection();
PreparedStatement preparedStatement =
connection.prepareStatement(testParam.getTestCaseContext().getTestCase().getSql()))
{
for (SQLE2ETestCaseAssertion each :
testParam.getTestCaseContext().getTestCase().getAssertions()) {
addBatch(preparedStatement, each);
diff --git
a/test/e2e/sql/src/test/java/org/apache/shardingsphere/test/e2e/sql/it/sql/dml/GeneralDMLE2EIT.java
b/test/e2e/sql/src/test/java/org/apache/shardingsphere/test/e2e/sql/it/sql/dml/GeneralDMLE2EIT.java
index 55d2b0c9363..642b9f26d86 100644
---
a/test/e2e/sql/src/test/java/org/apache/shardingsphere/test/e2e/sql/it/sql/dml/GeneralDMLE2EIT.java
+++
b/test/e2e/sql/src/test/java/org/apache/shardingsphere/test/e2e/sql/it/sql/dml/GeneralDMLE2EIT.java
@@ -49,7 +49,7 @@ class GeneralDMLE2EIT extends BaseDMLE2EIT {
init(testParam);
try {
int actualUpdateCount;
- try (Connection connection =
getEnvironmentEngine().getTargetDataSource().getConnection()) {
+ try (Connection connection =
getEnvironmentEngine().getTargetDataSource(context.getAssertion().getTargetDataSourceName()).getConnection())
{
actualUpdateCount = SQLExecuteType.LITERAL ==
context.getSqlExecuteType()
? executeUpdateForStatement(context, connection)
: executeUpdateForPreparedStatement(context,
connection);
@@ -93,7 +93,7 @@ class GeneralDMLE2EIT extends BaseDMLE2EIT {
init(testParam);
try {
int actualUpdateCount;
- try (Connection connection =
getEnvironmentEngine().getTargetDataSource().getConnection()) {
+ try (Connection connection =
getEnvironmentEngine().getTargetDataSource(context.getAssertion().getTargetDataSourceName()).getConnection())
{
actualUpdateCount = SQLExecuteType.LITERAL ==
context.getSqlExecuteType()
? executeForStatement(context, connection)
: executeForPreparedStatement(context, connection);
diff --git
a/test/e2e/sql/src/test/java/org/apache/shardingsphere/test/e2e/sql/it/sql/dql/AdditionalDQLE2EIT.java
b/test/e2e/sql/src/test/java/org/apache/shardingsphere/test/e2e/sql/it/sql/dql/AdditionalDQLE2EIT.java
index 05eb6c28b97..bfe243e99a8 100644
---
a/test/e2e/sql/src/test/java/org/apache/shardingsphere/test/e2e/sql/it/sql/dql/AdditionalDQLE2EIT.java
+++
b/test/e2e/sql/src/test/java/org/apache/shardingsphere/test/e2e/sql/it/sql/dql/AdditionalDQLE2EIT.java
@@ -118,7 +118,7 @@ class AdditionalDQLE2EIT extends BaseDQLE2EIT {
return;
}
try (
- Connection connection =
getEnvironmentEngine().getTargetDataSource().getConnection();
+ Connection connection =
getEnvironmentEngine().getTargetDataSource(context.getAssertion().getTargetDataSourceName()).getConnection();
Statement statement = 2 == resultSetTypes.length ?
connection.createStatement(resultSetTypes[0], resultSetTypes[1])
: connection.createStatement(resultSetTypes[0],
resultSetTypes[1], resultSetTypes[2]);
ResultSet resultSet =
statement.executeQuery(context.getSQL())) {
@@ -128,7 +128,7 @@ class AdditionalDQLE2EIT extends BaseDQLE2EIT {
private void assertExecuteQueryWithExpectedDataSource(final
AssertionTestParameter testParam, final SQLE2EITContext context, final int...
resultSetTypes) throws SQLException {
try (
- Connection actualConnection =
getEnvironmentEngine().getTargetDataSource().getConnection();
+ Connection actualConnection =
getEnvironmentEngine().getTargetDataSource(context.getAssertion().getTargetDataSourceName()).getConnection();
Connection expectedConnection =
getExpectedDataSource().getConnection()) {
if (SQLExecuteType.LITERAL == context.getSqlExecuteType()) {
assertExecuteQueryForStatementWithResultSetTypes(context,
actualConnection, expectedConnection, testParam, resultSetTypes);
@@ -177,7 +177,7 @@ class AdditionalDQLE2EIT extends BaseDQLE2EIT {
return;
}
try (
- Connection connection =
getEnvironmentEngine().getTargetDataSource().getConnection();
+ Connection connection =
getEnvironmentEngine().getTargetDataSource(context.getAssertion().getTargetDataSourceName()).getConnection();
Statement statement = 2 == resultSetTypes.length ?
connection.createStatement(resultSetTypes[0], resultSetTypes[1])
: connection.createStatement(resultSetTypes[0],
resultSetTypes[1], resultSetTypes[2])) {
assertTrue(statement.execute(context.getSQL()), "Not a query
statement.");
@@ -188,7 +188,7 @@ class AdditionalDQLE2EIT extends BaseDQLE2EIT {
private void assertExecuteWithExpectedDataSource(final
AssertionTestParameter testParam, final SQLE2EITContext context, final int...
resultSetTypes) throws SQLException {
try (
- Connection actualConnection =
getEnvironmentEngine().getTargetDataSource().getConnection();
+ Connection actualConnection =
getEnvironmentEngine().getTargetDataSource(context.getAssertion().getTargetDataSourceName()).getConnection();
Connection expectedConnection =
getExpectedDataSource().getConnection()) {
if (SQLExecuteType.LITERAL == context.getSqlExecuteType()) {
assertExecuteForStatementWithResultSetTypes(context,
actualConnection, expectedConnection, testParam, resultSetTypes);
diff --git
a/test/e2e/sql/src/test/java/org/apache/shardingsphere/test/e2e/sql/it/sql/dql/GeneralDQLE2EIT.java
b/test/e2e/sql/src/test/java/org/apache/shardingsphere/test/e2e/sql/it/sql/dql/GeneralDQLE2EIT.java
index 5ceb68de638..994529e38d5 100644
---
a/test/e2e/sql/src/test/java/org/apache/shardingsphere/test/e2e/sql/it/sql/dql/GeneralDQLE2EIT.java
+++
b/test/e2e/sql/src/test/java/org/apache/shardingsphere/test/e2e/sql/it/sql/dql/GeneralDQLE2EIT.java
@@ -82,7 +82,7 @@ class GeneralDQLE2EIT extends BaseDQLE2EIT {
private void assertQueryForStatementWithXmlExpected(final SQLE2EITContext
context) throws SQLException {
try (
- Connection connection =
getEnvironmentEngine().getTargetDataSource().getConnection();
+ Connection connection =
getEnvironmentEngine().getTargetDataSource(context.getAssertion().getTargetDataSourceName()).getConnection();
Statement statement = connection.createStatement();
ResultSet resultSet =
statement.executeQuery(context.getSQL())) {
assertResultSet(context, resultSet);
@@ -91,7 +91,7 @@ class GeneralDQLE2EIT extends BaseDQLE2EIT {
private void assertQueryForPreparedStatementWithXmlExpected(final
SQLE2EITContext context) throws SQLException {
try (
- Connection connection =
getEnvironmentEngine().getTargetDataSource().getConnection();
+ Connection connection =
getEnvironmentEngine().getTargetDataSource(context.getAssertion().getTargetDataSourceName()).getConnection();
PreparedStatement preparedStatement =
connection.prepareStatement(context.getSQL())) {
for (SQLValue each : context.getAssertion().getSQLValues()) {
preparedStatement.setObject(each.getIndex(), each.getValue());
@@ -105,7 +105,7 @@ class GeneralDQLE2EIT extends BaseDQLE2EIT {
private void assertExecuteQueryWithExpectedDataSource(final
AssertionTestParameter testParam, final SQLE2EITContext context) throws
SQLException {
try (
Connection expectedConnection =
getExpectedDataSource().getConnection();
- Connection actualConnection =
getEnvironmentEngine().getTargetDataSource().getConnection()) {
+ Connection actualConnection =
getEnvironmentEngine().getTargetDataSource(context.getAssertion().getTargetDataSourceName()).getConnection())
{
if (SQLExecuteType.LITERAL == context.getSqlExecuteType()) {
assertExecuteQueryForStatement(context, actualConnection,
expectedConnection, testParam);
} else {
@@ -182,7 +182,7 @@ class GeneralDQLE2EIT extends BaseDQLE2EIT {
private void assertExecuteForStatementWithXmlExpected(final
SQLE2EITContext context) throws SQLException {
try (
- Connection connection =
getEnvironmentEngine().getTargetDataSource().getConnection();
+ Connection connection =
getEnvironmentEngine().getTargetDataSource(context.getAssertion().getTargetDataSourceName()).getConnection();
Statement statement = connection.createStatement()) {
assertTrue(statement.execute(context.getSQL()), "Not a query
statement.");
ResultSet resultSet = statement.getResultSet();
@@ -192,7 +192,7 @@ class GeneralDQLE2EIT extends BaseDQLE2EIT {
private void assertExecuteForPreparedStatementWithXmlExpected(final
SQLE2EITContext context) throws SQLException {
try (
- Connection connection =
getEnvironmentEngine().getTargetDataSource().getConnection();
+ Connection connection =
getEnvironmentEngine().getTargetDataSource(context.getAssertion().getTargetDataSourceName()).getConnection();
PreparedStatement preparedStatement =
connection.prepareStatement(context.getSQL())) {
for (SQLValue each : context.getAssertion().getSQLValues()) {
preparedStatement.setObject(each.getIndex(), each.getValue());
@@ -206,7 +206,7 @@ class GeneralDQLE2EIT extends BaseDQLE2EIT {
private void assertExecuteWithExpectedDataSource(final
AssertionTestParameter testParam, final SQLE2EITContext context) throws
SQLException {
try (
- Connection actualConnection =
getEnvironmentEngine().getTargetDataSource().getConnection();
+ Connection actualConnection =
getEnvironmentEngine().getTargetDataSource(context.getAssertion().getTargetDataSourceName()).getConnection();
Connection expectedConnection =
getExpectedDataSource().getConnection()) {
if (SQLExecuteType.LITERAL == context.getSqlExecuteType()) {
assertExecuteForStatement(context, actualConnection,
expectedConnection, testParam);
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 597ec3cf9e1..fc021b341a3 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
@@ -107,7 +107,7 @@
</test-case>
<test-case sql="UPDATE t_data_type_date SET creation_date = ?, update_date
= ? where id = ?" db-types="MySQL" scenario-types="passthrough">
- <assertion parameters="2018-08-08:Date, 2018-08-08:datetime, 1:int"
expected-data-file="update_date_values.xml"/>
+ <assertion target-data-source-name="passthrough_secondary"
parameters="2018-08-08:Date, 2018-08-08:datetime, 1:int"
expected-data-file="update_date_values.xml"/>
</test-case>
<test-case sql="UPDATE t_user SET password = ? WHERE user_id = ?"
db-types="Hive" scenario-types="encrypt" skip-batch="true">
diff --git
a/test/e2e/sql/src/test/resources/cases/dql/cases/passthrough/e2e-dql-select-for-passthrough.xml
b/test/e2e/sql/src/test/resources/cases/dql/cases/passthrough/e2e-dql-select-for-passthrough.xml
index 67fb9f08fd5..db6b0622554 100644
---
a/test/e2e/sql/src/test/resources/cases/dql/cases/passthrough/e2e-dql-select-for-passthrough.xml
+++
b/test/e2e/sql/src/test/resources/cases/dql/cases/passthrough/e2e-dql-select-for-passthrough.xml
@@ -21,6 +21,11 @@
<assertion />
</test-case>
+ <test-case sql="SELECT DATABASE()" db-types="MySQL"
scenario-types="passthrough" adapters="proxy">
+ <assertion expected-data-file="select_default_database.xml" />
+ <assertion target-data-source-name="passthrough_secondary"
expected-data-file="select_secondary_database.xml" />
+ </test-case>
+
<test-case sql="SELECT 1 as a" db-types="PostgreSQL,openGauss"
smoke="true" scenario-types="passthrough" >
<assertion />
</test-case>
diff --git
a/test/e2e/sql/src/test/resources/cases/dql/dataset/passthrough/mysql/select_default_database.xml
b/test/e2e/sql/src/test/resources/cases/dql/dataset/passthrough/mysql/select_default_database.xml
new file mode 100644
index 00000000000..030894da231
--- /dev/null
+++
b/test/e2e/sql/src/test/resources/cases/dql/dataset/passthrough/mysql/select_default_database.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ 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.
+ -->
+
+<dataset>
+ <metadata>
+ <column name="database()" />
+ </metadata>
+ <row values="passthrough" />
+</dataset>
diff --git
a/test/e2e/sql/src/test/resources/cases/dql/dataset/passthrough/mysql/select_secondary_database.xml
b/test/e2e/sql/src/test/resources/cases/dql/dataset/passthrough/mysql/select_secondary_database.xml
new file mode 100644
index 00000000000..bcc73730120
--- /dev/null
+++
b/test/e2e/sql/src/test/resources/cases/dql/dataset/passthrough/mysql/select_secondary_database.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+ ~ 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.
+ -->
+
+<dataset>
+ <metadata>
+ <column name="database()" />
+ </metadata>
+ <row values="passthrough_secondary" />
+</dataset>
diff --git
a/test/e2e/sql/src/test/resources/env/scenario/passthrough/proxy/conf/mysql/database-passthrough-secondary.yaml
b/test/e2e/sql/src/test/resources/env/scenario/passthrough/proxy/conf/mysql/database-passthrough-secondary.yaml
new file mode 100644
index 00000000000..d1ca0308ea2
--- /dev/null
+++
b/test/e2e/sql/src/test/resources/env/scenario/passthrough/proxy/conf/mysql/database-passthrough-secondary.yaml
@@ -0,0 +1,35 @@
+#
+# 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: passthrough_secondary
+
+dataSources:
+ passthrough:
+ url:
jdbc:mysql://mysql.passthrough.host:3306/passthrough?useSSL=false&characterEncoding=utf-8
+ driverClassName: com.mysql.cj.jdbc.Driver
+ username: test_user
+ password: Test@9876
+ connectionTimeoutMilliseconds: 30000
+ idleTimeoutMilliseconds: 60000
+ maxLifetimeMilliseconds: 1800000
+ maxPoolSize: 8
+ minPoolSize: 2
+
+rules:
+- !SINGLE
+ tables:
+ - "*.*"