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

zhangliang 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 8eaa9d5fb4d Add SQLFederationEngineTest (#37293)
8eaa9d5fb4d is described below

commit 8eaa9d5fb4d83bd1afbd46a43a118617409f6d8d
Author: Liang Zhang <[email protected]>
AuthorDate: Sun Dec 7 20:23:10 2025 +0800

    Add SQLFederationEngineTest (#37293)
    
    * Refactor SQLFederationEngineTest
    
    * Add SQLFederationEngineTest
---
 .../executor/engine/DriverExecuteExecutor.java     |   2 +-
 .../sqlfederation/engine/SQLFederationEngine.java  |  62 ++-
 .../engine/SQLFederationEngineTest.java            | 475 +++++++++++----------
 .../connector/StandardDatabaseProxyConnector.java  |   2 +-
 4 files changed, 271 insertions(+), 270 deletions(-)

diff --git 
a/jdbc/src/main/java/org/apache/shardingsphere/driver/executor/engine/DriverExecuteExecutor.java
 
b/jdbc/src/main/java/org/apache/shardingsphere/driver/executor/engine/DriverExecuteExecutor.java
index c535725882a..ca27491e354 100644
--- 
a/jdbc/src/main/java/org/apache/shardingsphere/driver/executor/engine/DriverExecuteExecutor.java
+++ 
b/jdbc/src/main/java/org/apache/shardingsphere/driver/executor/engine/DriverExecuteExecutor.java
@@ -101,7 +101,7 @@ public final class DriverExecuteExecutor {
             return null != resultSet;
         }
         FederationMetaDataRefreshEngine federationMetaDataRefreshEngine = new 
FederationMetaDataRefreshEngine(queryContext.getSqlStatementContext());
-        if (sqlFederationEngine.isSqlFederationEnabled() && 
federationMetaDataRefreshEngine.isNeedRefresh()) {
+        if (sqlFederationEngine.isSQLFederationEnabled() && 
federationMetaDataRefreshEngine.isNeedRefresh()) {
             
federationMetaDataRefreshEngine.refresh(connection.getContextManager().getPersistServiceFacade().getModeFacade().getMetaDataManagerService(),
 database);
             return true;
         }
diff --git 
a/kernel/sql-federation/core/src/main/java/org/apache/shardingsphere/sqlfederation/engine/SQLFederationEngine.java
 
b/kernel/sql-federation/core/src/main/java/org/apache/shardingsphere/sqlfederation/engine/SQLFederationEngine.java
index e91f2f85a00..186fac5fbd1 100644
--- 
a/kernel/sql-federation/core/src/main/java/org/apache/shardingsphere/sqlfederation/engine/SQLFederationEngine.java
+++ 
b/kernel/sql-federation/core/src/main/java/org/apache/shardingsphere/sqlfederation/engine/SQLFederationEngine.java
@@ -84,8 +84,8 @@ import java.util.Optional;
 /**
  * SQL federation engine.
  */
-@Slf4j
 @Getter
+@Slf4j
 public final class SQLFederationEngine implements AutoCloseable {
     
     private static final Collection<Class<?>> NEED_THROW_EXCEPTION_TYPES = 
Arrays.asList(SQLExecutionInterruptedException.class, 
SQLIntegrityConstraintViolationException.class);
@@ -119,11 +119,11 @@ public final class SQLFederationEngine implements 
AutoCloseable {
     }
     
     /**
-     * Judge whether SQL federation enabled or not.
+     * Judge whether SQL federation enabled.
      *
-     * @return whether SQL federation enabled or not
+     * @return SQL federation enabled or disabled
      */
-    public boolean isSqlFederationEnabled() {
+    public boolean isSQLFederationEnabled() {
         return sqlFederationRule.getConfiguration().isSqlFederationEnabled();
     }
     
@@ -137,7 +137,7 @@ public final class SQLFederationEngine implements 
AutoCloseable {
     @SuppressWarnings({"unchecked", "rawtypes"})
     public boolean decide(final QueryContext queryContext, final RuleMetaData 
globalRuleMetaData) {
         SQLStatementContext sqlStatementContext = 
queryContext.getSqlStatementContext();
-        if (!sqlFederationRule.getConfiguration().isSqlFederationEnabled() || 
!isSupportedSQLStatementContext(sqlStatementContext)) {
+        if (!isSQLFederationEnabled() || 
!isSupportedSQLStatementContext(sqlStatementContext)) {
             return false;
         }
         boolean allQueryUseSQLFederation = 
sqlFederationRule.getConfiguration().isAllQueryUseSQLFederation();
@@ -160,11 +160,9 @@ public final class SQLFederationEngine implements 
AutoCloseable {
     }
     
     private boolean isSupportedSQLStatementContext(final SQLStatementContext 
sqlStatementContext) {
-        if (sqlStatementContext instanceof ExplainStatementContext) {
-            ExplainStatement explainStatement = ((ExplainStatementContext) 
sqlStatementContext).getSqlStatement();
-            return 
isSupportedSQLStatement(explainStatement.getExplainableSQLStatement());
-        }
-        return isSupportedSQLStatement(sqlStatementContext.getSqlStatement());
+        return isSupportedSQLStatement(sqlStatementContext instanceof 
ExplainStatementContext
+                ? ((ExplainStatementContext) 
sqlStatementContext).getSqlStatement().getExplainableSQLStatement()
+                : sqlStatementContext.getSqlStatement());
     }
     
     private boolean isSupportedSQLStatement(final SQLStatement sqlStatement) {
@@ -179,13 +177,13 @@ public final class SQLFederationEngine implements 
AutoCloseable {
      * @param federationContext federation context
      * @return result set
      */
-    public ResultSet executeQuery(final 
DriverExecutionPrepareEngine<JDBCExecutionUnit, Connection> prepareEngine, 
final JDBCExecutorCallback<? extends ExecuteResult> callback,
-                                  final SQLFederationContext 
federationContext) {
+    public ResultSet executeQuery(final 
DriverExecutionPrepareEngine<JDBCExecutionUnit, Connection> prepareEngine,
+                                  final JDBCExecutorCallback<? extends 
ExecuteResult> callback, final SQLFederationContext federationContext) {
         return execute0(prepareEngine, callback, federationContext);
     }
     
-    private ResultSet execute0(final 
DriverExecutionPrepareEngine<JDBCExecutionUnit, Connection> prepareEngine, 
final JDBCExecutorCallback<? extends ExecuteResult> queryCallback,
-                               final SQLFederationContext federationContext) {
+    private ResultSet execute0(final 
DriverExecutionPrepareEngine<JDBCExecutionUnit, Connection> prepareEngine,
+                               final JDBCExecutorCallback<? extends 
ExecuteResult> queryCallback, final SQLFederationContext federationContext) {
         queryContext = federationContext.getQueryContext();
         logSQL(queryContext, federationContext.getMetaData().getProps());
         try {
@@ -209,22 +207,13 @@ public final class SQLFederationEngine implements 
AutoCloseable {
             // CHECKSTYLE:ON
             log.error("SQL Federation execute failed, sql {}, parameters {}", 
queryContext.getSql(), queryContext.getParameters(), ex);
             closeResources(federationContext);
-            if (isNeedThrowException(ex)) {
+            if (NEED_THROW_EXCEPTION_TYPES.stream().anyMatch(each -> 
each.isAssignableFrom(ex.getClass()))) {
                 throw ex;
             }
             throw new 
SQLFederationUnsupportedSQLException(queryContext.getSql(), ex);
         }
     }
     
-    private boolean isNeedThrowException(final Exception ex) {
-        for (Class<?> each : NEED_THROW_EXCEPTION_TYPES) {
-            if (each.isAssignableFrom(ex.getClass())) {
-                return true;
-            }
-        }
-        return false;
-    }
-    
     private void closeResources(final SQLFederationContext federationContext) {
         try {
             
processEngine.completeSQLExecution(federationContext.getProcessId());
@@ -248,10 +237,9 @@ public final class SQLFederationEngine implements 
AutoCloseable {
     }
     
     private void logExecutionPlan(final SQLFederationExecutionPlan 
executionPlan, final ConfigurationProperties props) {
-        if (!props.<Boolean>getValue(ConfigurationPropertyKey.SQL_SHOW)) {
-            return;
+        if (props.<Boolean>getValue(ConfigurationPropertyKey.SQL_SHOW)) {
+            log.info("SQL Federation Execution Plan: {}", 
RelOptUtil.toString(executionPlan.getPhysicalPlan(), 
SqlExplainLevel.ALL_ATTRIBUTES).replaceAll(", id = \\d+", ""));
         }
-        log.info("SQL Federation Execution Plan: {}", 
RelOptUtil.toString(executionPlan.getPhysicalPlan(), 
SqlExplainLevel.ALL_ATTRIBUTES).replaceAll(", id = \\d+", ""));
     }
     
     private List<String> getSchemaPath(final SQLStatementContext 
sqlStatementContext) {
@@ -286,6 +274,16 @@ public final class SQLFederationEngine implements 
AutoCloseable {
         return result;
     }
     
+    /**
+     * Get result set.
+     *
+     * @return result set
+     */
+    public ResultSet getResultSet() {
+        SQLStatement sqlStatement = 
queryContext.getSqlStatementContext().getSqlStatement();
+        return sqlStatement instanceof SelectStatement || sqlStatement 
instanceof ExplainStatement ? resultSet : null;
+    }
+    
     @Override
     public void close() throws SQLException {
         Collection<SQLException> result = new LinkedList<>();
@@ -315,14 +313,4 @@ public final class SQLFederationEngine implements 
AutoCloseable {
             processor.release(currentDatabaseName, currentSchemaName, 
queryContext, schemaPlus);
         }
     }
-    
-    /**
-     * Get result set.
-     *
-     * @return result set
-     */
-    public ResultSet getResultSet() {
-        SQLStatement sqlStatement = 
queryContext.getSqlStatementContext().getSqlStatement();
-        return sqlStatement instanceof SelectStatement || sqlStatement 
instanceof ExplainStatement ? resultSet : null;
-    }
 }
diff --git 
a/kernel/sql-federation/core/src/test/java/org/apache/shardingsphere/sqlfederation/engine/SQLFederationEngineTest.java
 
b/kernel/sql-federation/core/src/test/java/org/apache/shardingsphere/sqlfederation/engine/SQLFederationEngineTest.java
index be220cab6cc..4c063d90e3b 100644
--- 
a/kernel/sql-federation/core/src/test/java/org/apache/shardingsphere/sqlfederation/engine/SQLFederationEngineTest.java
+++ 
b/kernel/sql-federation/core/src/test/java/org/apache/shardingsphere/sqlfederation/engine/SQLFederationEngineTest.java
@@ -17,19 +17,20 @@
 
 package org.apache.shardingsphere.sqlfederation.engine;
 
-import org.apache.calcite.plan.Convention;
 import org.apache.calcite.plan.RelOptUtil;
 import org.apache.calcite.rel.RelNode;
 import org.apache.calcite.schema.SchemaPlus;
 import org.apache.calcite.sql.SqlExplainLevel;
+import 
org.apache.shardingsphere.database.connector.core.metadata.database.metadata.DialectDatabaseMetaData;
+import 
org.apache.shardingsphere.database.connector.core.metadata.database.metadata.option.schema.DialectSchemaOption;
 import org.apache.shardingsphere.database.connector.core.type.DatabaseType;
+import 
org.apache.shardingsphere.database.connector.core.type.DatabaseTypeRegistry;
 import 
org.apache.shardingsphere.infra.binder.context.segment.table.TablesContext;
 import 
org.apache.shardingsphere.infra.binder.context.statement.SQLStatementContext;
 import 
org.apache.shardingsphere.infra.binder.context.statement.type.dal.ExplainStatementContext;
 import 
org.apache.shardingsphere.infra.binder.context.statement.type.dml.SelectStatementContext;
 import org.apache.shardingsphere.infra.config.props.ConfigurationProperties;
 import org.apache.shardingsphere.infra.config.props.ConfigurationPropertyKey;
-import 
org.apache.shardingsphere.infra.exception.kernel.connection.SQLExecutionInterruptedException;
 import 
org.apache.shardingsphere.infra.executor.sql.execute.engine.driver.jdbc.JDBCExecutionUnit;
 import 
org.apache.shardingsphere.infra.executor.sql.execute.engine.driver.jdbc.JDBCExecutor;
 import 
org.apache.shardingsphere.infra.executor.sql.execute.engine.driver.jdbc.JDBCExecutorCallback;
@@ -47,6 +48,8 @@ import 
org.apache.shardingsphere.infra.rule.ShardingSphereRule;
 import org.apache.shardingsphere.infra.session.connection.ConnectionContext;
 import org.apache.shardingsphere.infra.session.query.QueryContext;
 import org.apache.shardingsphere.infra.spi.type.typed.TypedSPILoader;
+import org.apache.shardingsphere.infra.util.props.PropertiesBuilder;
+import org.apache.shardingsphere.infra.util.props.PropertiesBuilder.Property;
 import 
org.apache.shardingsphere.sql.parser.statement.core.segment.generic.OwnerSegment;
 import 
org.apache.shardingsphere.sql.parser.statement.core.segment.generic.bound.TableSegmentBoundInfo;
 import 
org.apache.shardingsphere.sql.parser.statement.core.segment.generic.table.SimpleTableSegment;
@@ -68,374 +71,333 @@ import 
org.apache.shardingsphere.sqlfederation.engine.fixture.rule.SQLFederation
 import 
org.apache.shardingsphere.sqlfederation.engine.processor.SQLFederationProcessor;
 import 
org.apache.shardingsphere.sqlfederation.engine.processor.SQLFederationProcessorFactory;
 import org.apache.shardingsphere.sqlfederation.rule.SQLFederationRule;
-import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.ExtendWith;
-import org.mockito.Answers;
 import org.mockito.ArgumentCaptor;
-import org.mockito.Mock;
 import org.mockito.MockedConstruction;
 import org.mockito.MockedStatic;
-import org.mockito.junit.jupiter.MockitoExtension;
+import org.mockito.internal.configuration.plugins.Plugins;
 
 import java.sql.Connection;
 import java.sql.ResultSet;
 import java.sql.SQLException;
+import java.sql.SQLIntegrityConstraintViolationException;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
-import java.util.LinkedList;
+import java.util.List;
+import java.util.Optional;
 import java.util.Properties;
+import java.util.concurrent.atomic.AtomicReference;
 
+import static org.hamcrest.CoreMatchers.is;
+import static org.hamcrest.MatcherAssert.assertThat;
 import static org.junit.jupiter.api.Assertions.assertFalse;
 import static org.junit.jupiter.api.Assertions.assertNull;
-import static org.junit.jupiter.api.Assertions.assertSame;
 import static org.junit.jupiter.api.Assertions.assertThrows;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.RETURNS_DEEP_STUBS;
+import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.doThrow;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.mockConstruction;
 import static org.mockito.Mockito.mockStatic;
+import static org.mockito.Mockito.never;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.when;
 
-@ExtendWith(MockitoExtension.class)
 class SQLFederationEngineTest {
     
     private final DatabaseType databaseType = 
TypedSPILoader.getService(DatabaseType.class, "FIXTURE");
     
-    @Mock(answer = Answers.RETURNS_DEEP_STUBS)
-    private ShardingSphereMetaData metaData;
+    private final SQLFederationCacheOption cacheOption = new 
SQLFederationCacheOption(1, 1L);
     
     @Test
-    void assertDecideWhenNotConfigSqlFederationEnabled() throws SQLException {
-        Collection<ShardingSphereRule> globalRules = Collections.singleton(
-                new SQLFederationRule(new 
SQLFederationRuleConfiguration(false, false, new SQLFederationCacheOption(1, 
1)), Collections.emptyList()));
-        SQLFederationEngine engine = createSQLFederationEngine(globalRules, 
Collections.emptyList());
-        RuleMetaData globalRuleMetaData = new RuleMetaData(globalRules);
-        assertFalse(engine.decide(mock(QueryContext.class), 
globalRuleMetaData));
-        engine.close();
-    }
-    
-    private SQLFederationEngine createSQLFederationEngine(final 
Collection<ShardingSphereRule> globalRules, final 
Collection<ShardingSphereRule> databaseRules) {
-        
when(metaData.getDatabase("foo_db").getRuleMetaData().getRules()).thenReturn(databaseRules);
-        when(metaData.getGlobalRuleMetaData()).thenReturn(new 
RuleMetaData(globalRules));
-        return new SQLFederationEngine("foo_db", "foo_db", metaData, 
mock(ShardingSphereStatistics.class), mock(JDBCExecutor.class));
+    void assertDecideWhenSQLFederationDisabled() throws SQLException {
+        Collection<ShardingSphereRule> globalRules = Collections.singleton(new 
SQLFederationRule(new SQLFederationRuleConfiguration(false, false, 
cacheOption), Collections.emptyList()));
+        try (SQLFederationEngine engine = 
createSQLFederationEngine(globalRules, Collections.emptyList())) {
+            assertFalse(engine.decide(mock(QueryContext.class), new 
RuleMetaData(globalRules)));
+        }
     }
     
     @Test
-    void assertDecideWhenConfigAllQueryUseSQLFederation() throws SQLException {
-        Collection<ShardingSphereRule> globalRules = Collections.singleton(
-                new SQLFederationRule(new SQLFederationRuleConfiguration(true, 
true, new SQLFederationCacheOption(1, 1)), Collections.emptyList()));
-        SelectStatementContext selectStatementContext = 
mock(SelectStatementContext.class, RETURNS_DEEP_STUBS);
-        
when(selectStatementContext.getSqlStatement().getDatabaseType()).thenReturn(databaseType);
-        
when(selectStatementContext.getTablesContext().getDatabaseNames()).thenReturn(Collections.emptyList());
+    void assertDecideWhenEnableAllQueryUseSQLFederation() throws SQLException {
+        Collection<ShardingSphereRule> globalRules = Collections.singleton(new 
SQLFederationRule(new SQLFederationRuleConfiguration(true, true, cacheOption), 
Collections.emptyList()));
         QueryContext queryContext = mock(QueryContext.class);
-        
when(queryContext.getSqlStatementContext()).thenReturn(selectStatementContext);
-        SQLFederationEngine engine = createSQLFederationEngine(globalRules, 
Collections.emptyList());
-        RuleMetaData globalRuleMetaData = new RuleMetaData(globalRules);
-        assertTrue(engine.decide(queryContext, globalRuleMetaData));
-        engine.close();
+        
when(queryContext.getSqlStatementContext()).thenReturn(mock(SelectStatementContext.class,
 RETURNS_DEEP_STUBS));
+        try (SQLFederationEngine engine = 
createSQLFederationEngine(globalRules, Collections.emptyList())) {
+            assertTrue(engine.decide(queryContext, new 
RuleMetaData(globalRules)));
+        }
     }
     
     @Test
     void assertDecideWhenExecuteNotSelectStatement() throws SQLException {
-        Collection<ShardingSphereRule> globalRules = Collections.singleton(
-                new SQLFederationRule(new SQLFederationRuleConfiguration(true, 
false, new SQLFederationCacheOption(1, 1)), Collections.emptyList()));
-        SQLFederationEngine engine = createSQLFederationEngine(globalRules, 
Collections.emptyList());
-        RuleMetaData globalRuleMetaData = new RuleMetaData(globalRules);
+        Collection<ShardingSphereRule> globalRules = Collections.singleton(new 
SQLFederationRule(new SQLFederationRuleConfiguration(true, false, cacheOption), 
Collections.emptyList()));
         QueryContext queryContext = mock(QueryContext.class, 
RETURNS_DEEP_STUBS);
         
when(queryContext.getSqlStatementContext().getSqlStatement()).thenReturn(mock(CreateTableStatement.class));
-        assertFalse(engine.decide(queryContext, globalRuleMetaData));
-        engine.close();
-    }
-    
-    @Test
-    void assertDecideWhenConfigSingleMatchedRule() throws SQLException {
-        Collection<ShardingSphereRule> globalRules = Collections.singleton(
-                new SQLFederationRule(new SQLFederationRuleConfiguration(true, 
false, new SQLFederationCacheOption(1, 1)), Collections.emptyList()));
-        Collection<ShardingSphereRule> databaseRules = 
Collections.singleton(new SQLFederationDeciderRuleMatchFixture());
-        ShardingSphereDatabase database = new ShardingSphereDatabase("foo_db",
-                databaseType, mock(ResourceMetaData.class, 
RETURNS_DEEP_STUBS), new RuleMetaData(globalRules), Collections.emptyList());
-        SelectStatementContext selectStatementContext = 
mock(SelectStatementContext.class, RETURNS_DEEP_STUBS);
-        
when(selectStatementContext.getSqlStatement().getDatabaseType()).thenReturn(databaseType);
-        
when(selectStatementContext.getTablesContext().getDatabaseNames()).thenReturn(Collections.singleton("foo_db"));
-        QueryContext queryContext = mock(QueryContext.class);
-        
when(queryContext.getSqlStatementContext()).thenReturn(selectStatementContext);
-        when(queryContext.getUsedDatabase()).thenReturn(database);
-        SQLFederationEngine engine = createSQLFederationEngine(globalRules, 
databaseRules);
-        RuleMetaData globalRuleMetaData = new RuleMetaData(globalRules);
-        assertTrue(engine.decide(queryContext, globalRuleMetaData));
-        engine.close();
+        try (SQLFederationEngine engine = 
createSQLFederationEngine(globalRules, Collections.emptyList())) {
+            assertFalse(engine.decide(queryContext, new 
RuleMetaData(globalRules)));
+        }
     }
     
     @Test
-    void assertDecideWhenConfigSingleNotMatchedRule() throws SQLException {
-        Collection<ShardingSphereRule> globalRules = Collections.singleton(
-                new SQLFederationRule(new SQLFederationRuleConfiguration(true, 
false, new SQLFederationCacheOption(1, 1)), Collections.emptyList()));
+    void assertDecideWithNotMatchedRule() throws SQLException {
+        Collection<ShardingSphereRule> globalRules = Collections.singleton(new 
SQLFederationRule(new SQLFederationRuleConfiguration(true, false, cacheOption), 
Collections.emptyList()));
         Collection<ShardingSphereRule> databaseRules = 
Collections.singleton(new SQLFederationDeciderRuleNotMatchFixture());
-        ShardingSphereDatabase database = new ShardingSphereDatabase("foo_db", 
databaseType, mock(), new RuleMetaData(databaseRules), Collections.emptyList());
         SelectStatementContext selectStatementContext = 
mock(SelectStatementContext.class, RETURNS_DEEP_STUBS);
-        
when(selectStatementContext.getSqlStatement().getDatabaseType()).thenReturn(databaseType);
         
when(selectStatementContext.getTablesContext().getDatabaseNames()).thenReturn(Collections.singleton("foo_db"));
         QueryContext queryContext = mock(QueryContext.class);
         
when(queryContext.getSqlStatementContext()).thenReturn(selectStatementContext);
-        when(queryContext.getUsedDatabase()).thenReturn(database);
-        SQLFederationEngine engine = createSQLFederationEngine(globalRules, 
databaseRules);
-        assertFalse(engine.decide(queryContext, new 
RuleMetaData(globalRules)));
-        engine.close();
+        when(queryContext.getUsedDatabase()).thenReturn(new 
ShardingSphereDatabase("foo_db", databaseType, mock(), new 
RuleMetaData(databaseRules), Collections.emptyList()));
+        try (SQLFederationEngine engine = 
createSQLFederationEngine(globalRules, databaseRules)) {
+            assertFalse(engine.decide(queryContext, new 
RuleMetaData(globalRules)));
+        }
     }
     
     @Test
-    void assertDecideWhenConfigMultiRule() throws SQLException {
-        Collection<ShardingSphereRule> globalRules =
-                Collections.singletonList(new SQLFederationRule(new 
SQLFederationRuleConfiguration(true, false, new SQLFederationCacheOption(1, 
1)), Collections.emptyList()));
-        Collection<ShardingSphereRule> databaseRules = Arrays.asList(new 
SQLFederationDeciderRuleNotMatchFixture(),
-                new SQLFederationDeciderRuleMatchFixture());
-        ShardingSphereDatabase database = new ShardingSphereDatabase("foo_db",
-                databaseType, mock(ResourceMetaData.class, 
RETURNS_DEEP_STUBS), new RuleMetaData(databaseRules), Collections.emptyList());
+    void assertDecideWithMultipleRules() throws SQLException {
+        Collection<ShardingSphereRule> globalRules = Collections.singleton(new 
SQLFederationRule(new SQLFederationRuleConfiguration(true, false, cacheOption), 
Collections.emptyList()));
+        Collection<ShardingSphereRule> databaseRules = Arrays.asList(new 
SQLFederationDeciderRuleNotMatchFixture(), new 
SQLFederationDeciderRuleMatchFixture());
         SelectStatementContext selectStatementContext = 
mock(SelectStatementContext.class, RETURNS_DEEP_STUBS);
-        
when(selectStatementContext.getSqlStatement().getDatabaseType()).thenReturn(databaseType);
         
when(selectStatementContext.getTablesContext().getDatabaseNames()).thenReturn(Collections.singleton("foo_db"));
         QueryContext queryContext = mock(QueryContext.class);
         
when(queryContext.getSqlStatementContext()).thenReturn(selectStatementContext);
-        when(queryContext.getParameters()).thenReturn(Collections.emptyList());
-        when(queryContext.getUsedDatabase()).thenReturn(database);
-        SQLFederationEngine engine = createSQLFederationEngine(globalRules, 
databaseRules);
-        assertTrue(engine.decide(queryContext, new RuleMetaData(globalRules)));
-        engine.close();
+        when(queryContext.getUsedDatabase()).thenReturn(new 
ShardingSphereDatabase("foo_db", databaseType, mock(), new 
RuleMetaData(databaseRules), Collections.emptyList()));
+        try (SQLFederationEngine engine = 
createSQLFederationEngine(globalRules, databaseRules)) {
+            assertTrue(engine.decide(queryContext, new 
RuleMetaData(globalRules)));
+        }
     }
     
     @Test
     void assertDecideWithMultipleDatabases() throws SQLException {
-        Collection<ShardingSphereRule> globalRules =
-                Collections.singletonList(new SQLFederationRule(new 
SQLFederationRuleConfiguration(true, false, new SQLFederationCacheOption(1, 
1)), Collections.emptyList()));
+        Collection<ShardingSphereRule> globalRules = Collections.singleton(new 
SQLFederationRule(new SQLFederationRuleConfiguration(true, false, cacheOption), 
Collections.emptyList()));
         SelectStatementContext selectStatementContext = 
mock(SelectStatementContext.class, RETURNS_DEEP_STUBS);
-        
when(selectStatementContext.getSqlStatement().getDatabaseType()).thenReturn(databaseType);
-        
when(selectStatementContext.getTablesContext().getDatabaseNames()).thenReturn(new
 LinkedList<>(Arrays.asList("foo_db", "bar_db")));
+        
when(selectStatementContext.getTablesContext().getDatabaseNames()).thenReturn(Arrays.asList("foo_db",
 "bar_db"));
         QueryContext queryContext = mock(QueryContext.class);
         
when(queryContext.getSqlStatementContext()).thenReturn(selectStatementContext);
-        SQLFederationEngine engine = createSQLFederationEngine(globalRules, 
Collections.emptyList());
-        assertTrue(engine.decide(queryContext, new RuleMetaData(globalRules)));
-        engine.close();
+        try (SQLFederationEngine engine = 
createSQLFederationEngine(globalRules, Collections.emptyList())) {
+            assertTrue(engine.decide(queryContext, new 
RuleMetaData(globalRules)));
+        }
     }
     
     @Test
     void assertDecideWithExplainStatement() throws SQLException {
-        Collection<ShardingSphereRule> globalRules = Collections.singleton(
-                new SQLFederationRule(new SQLFederationRuleConfiguration(true, 
false, new SQLFederationCacheOption(1, 1)), Collections.emptyList()));
+        Collection<ShardingSphereRule> globalRules = Collections.singleton(new 
SQLFederationRule(new SQLFederationRuleConfiguration(true, false, cacheOption), 
Collections.emptyList()));
         ExplainStatementContext explainStatementContext = 
mock(ExplainStatementContext.class, RETURNS_DEEP_STUBS);
         ExplainStatement explainStatement = mock(ExplainStatement.class, 
RETURNS_DEEP_STUBS);
-        SelectStatement selectStatement = mock(SelectStatement.class);
-        
when(explainStatement.getExplainableSQLStatement()).thenReturn(selectStatement);
         
when(explainStatementContext.getSqlStatement()).thenReturn(explainStatement);
         
when(explainStatementContext.getTablesContext().getDatabaseNames()).thenReturn(Collections.emptyList());
         QueryContext queryContext = mock(QueryContext.class);
         
when(queryContext.getSqlStatementContext()).thenReturn(explainStatementContext);
-        SQLFederationEngine engine = createSQLFederationEngine(globalRules, 
Collections.emptyList());
-        assertFalse(engine.decide(queryContext, new 
RuleMetaData(globalRules)));
-        engine.close();
+        try (SQLFederationEngine engine = 
createSQLFederationEngine(globalRules, Collections.emptyList())) {
+            assertFalse(engine.decide(queryContext, new 
RuleMetaData(globalRules)));
+        }
     }
     
+    @SuppressWarnings("unchecked")
     @Test
-    void assertExecuteQueryWithLoggingAndRelease() throws SQLException {
-        Properties props = new Properties();
-        props.setProperty(ConfigurationPropertyKey.SQL_SHOW.getKey(), 
Boolean.TRUE.toString());
-        SQLFederationRuleConfiguration config = new 
SQLFederationRuleConfiguration(true, false, new SQLFederationCacheOption(1, 1));
-        ShardingSphereTable table = new ShardingSphereTable("t_order", 
Collections.emptyList(), Collections.emptyList(), Collections.emptyList());
-        ShardingSphereMetaData actualMetaData = createMetaData(config, 
Collections.emptyList(), Collections.singleton(table), 
TypedSPILoader.getService(DatabaseType.class, "PostgreSQL"), props);
-        SQLFederationProcessor processor = mock(SQLFederationProcessor.class);
-        when(processor.getConvention()).thenReturn(mock(Convention.class));
-        ShardingSphereStatistics statistics = 
mock(ShardingSphereStatistics.class);
-        JDBCExecutor jdbcExecutor = mock(JDBCExecutor.class);
-        SQLFederationEngine engine = createEngineWithProcessor(processor, 
actualMetaData, statistics, jdbcExecutor);
-        SimpleTableSegment simpleTableSegment = new SimpleTableSegment(new 
TableNameSegment(0, 0, new IdentifierValue("t_order")));
+    void assertExecuteQueryWithDefaultSchemaButWithoutOwner() throws 
SQLException {
+        ShardingSphereMetaData actualMetaData = 
createMetaData(PropertiesBuilder.build(new 
Property(ConfigurationPropertyKey.SQL_SHOW.getKey(), 
Boolean.FALSE.toString())));
         TablesContext tablesContext = mock(TablesContext.class);
-        
when(tablesContext.getSimpleTables()).thenReturn(Collections.singleton(simpleTableSegment));
+        
when(tablesContext.getSimpleTables()).thenReturn(Collections.singleton(new 
SimpleTableSegment(new TableNameSegment(0, 0, new 
IdentifierValue("foo_tbl")))));
+        SQLStatementContext selectStatementContext = 
mock(SQLStatementContext.class, RETURNS_DEEP_STUBS);
+        
when(selectStatementContext.getTablesContext()).thenReturn(tablesContext);
+        QueryContext queryContext = mock(QueryContext.class);
+        
when(queryContext.getSqlStatementContext()).thenReturn(selectStatementContext);
+        when(queryContext.getSql()).thenReturn("SELECT * FROM foo_tbl");
+        when(queryContext.getConnectionContext()).thenReturn(new 
ConnectionContext(Collections::emptyList, new Grantee("root", "localhost")));
+        SQLFederationContext federationContext = new 
SQLFederationContext(false, queryContext, actualMetaData, 
"process_schema_path");
+        AtomicReference<List<String>> actualSchemaPath = new 
AtomicReference<>();
+        try (
+                SQLFederationEngine engine = createSQLFederationEngine(mock(), 
actualMetaData);
+                MockedConstruction<DatabaseTypeRegistry> ignoredRegistry = 
mockConstruction(DatabaseTypeRegistry.class, (mock, context) -> {
+                    DialectSchemaOption schemaOption = 
mock(DialectSchemaOption.class);
+                    
when(schemaOption.getDefaultSchema()).thenReturn(Optional.of("public"));
+                    DialectDatabaseMetaData dialectDatabaseMetaData = 
mock(DialectDatabaseMetaData.class);
+                    
when(dialectDatabaseMetaData.getSchemaOption()).thenReturn(schemaOption);
+                    
when(mock.getDialectDatabaseMetaData()).thenReturn(dialectDatabaseMetaData);
+                });
+                MockedConstruction<SQLFederationRelConverter> ignoredConverter 
= mockConstruction(SQLFederationRelConverter.class, (mock, context) -> {
+                    actualSchemaPath.set((List<String>) 
context.arguments().get(1));
+                    
when(mock.getSchemaPlus()).thenReturn(mock(SchemaPlus.class));
+                });
+                MockedConstruction<SQLFederationCompilerEngine> 
ignoredCompiler = mockConstruction(SQLFederationCompilerEngine.class,
+                        (mock, context) -> 
when(mock.compile(any(ExecutionPlanCacheKey.class), 
eq(false))).thenReturn(mock(SQLFederationExecutionPlan.class)));
+                MockedStatic<RelOptUtil> relOptUtil = 
mockStatic(RelOptUtil.class)) {
+            relOptUtil.when(() -> RelOptUtil.toString(any(RelNode.class), 
eq(SqlExplainLevel.ALL_ATTRIBUTES))).thenReturn("plan");
+            engine.executeQuery(mock(), mock(), federationContext);
+            assertThat(actualSchemaPath.get(), is(Arrays.asList("foo_db", 
"foo_schema")));
+        }
+    }
+    
+    @SuppressWarnings("unchecked")
+    @Test
+    void assertExecuteQueryWithLoggingAndRelease() throws SQLException {
         SelectStatement selectStatement = mock(SelectStatement.class);
-        
when(selectStatement.getDatabaseType()).thenReturn(TypedSPILoader.getService(DatabaseType.class,
 "PostgreSQL"));
+        when(selectStatement.getDatabaseType()).thenReturn(databaseType);
         SQLStatementContext selectStatementContext = 
mock(SQLStatementContext.class, RETURNS_DEEP_STUBS);
         
when(selectStatementContext.getSqlStatement()).thenReturn(selectStatement, 
selectStatement, selectStatement, selectStatement, 
mock(CreateTableStatement.class));
-        
when(selectStatementContext.getTablesContext()).thenReturn(tablesContext);
-        ExplainStatementContext explainStatementContext = 
mock(ExplainStatementContext.class, RETURNS_DEEP_STUBS);
-        ExplainStatement explainStatement = mock(ExplainStatement.class, 
RETURNS_DEEP_STUBS);
+        
when(selectStatementContext.getTablesContext().getSimpleTables()).thenReturn(Collections.singleton(new
 SimpleTableSegment(new TableNameSegment(0, 0, new 
IdentifierValue("foo_tbl")))));
+        ExplainStatementContext explainStatementContext = 
mock(ExplainStatementContext.class);
+        ExplainStatement explainStatement = mock(ExplainStatement.class);
         
when(explainStatement.getExplainableSQLStatement()).thenReturn(selectStatement);
         
when(explainStatementContext.getSqlStatement()).thenReturn(explainStatement);
         
when(explainStatementContext.getExplainableSQLStatementContext()).thenReturn(selectStatementContext);
         QueryContext queryContext = mock(QueryContext.class);
         
when(queryContext.getSqlStatementContext()).thenReturn(explainStatementContext);
-        when(queryContext.getSql()).thenReturn("SELECT * FROM t_order");
-        when(queryContext.getParameters()).thenReturn(Collections.emptyList());
+        when(queryContext.getSql()).thenReturn("SELECT * FROM foo_tbl");
         ConnectionContext connectionContext = new 
ConnectionContext(Collections::emptyList, new Grantee("root", "localhost"));
         connectionContext.setCurrentDatabaseName("foo_db");
         
when(queryContext.getConnectionContext()).thenReturn(connectionContext);
+        ShardingSphereMetaData actualMetaData = 
createMetaData(PropertiesBuilder.build(new 
Property(ConfigurationPropertyKey.SQL_SHOW.getKey(), Boolean.TRUE.toString())));
         SQLFederationContext federationContext = new 
SQLFederationContext(false, queryContext, actualMetaData, "process_1");
         DriverExecutionPrepareEngine<JDBCExecutionUnit, Connection> 
prepareEngine = mock(DriverExecutionPrepareEngine.class);
         JDBCExecutorCallback<? extends ExecuteResult> callback = 
mock(JDBCExecutorCallback.class);
         ResultSet resultSet = mock(ResultSet.class);
+        SQLFederationProcessor processor = mock(SQLFederationProcessor.class);
         when(processor.executePlan(eq(prepareEngine), eq(callback), 
any(SQLFederationExecutionPlan.class), any(SQLFederationRelConverter.class), 
eq(federationContext), any())).thenReturn(resultSet);
-        SQLFederationExecutionPlan executionPlan = 
mock(SQLFederationExecutionPlan.class);
-        when(executionPlan.getPhysicalPlan()).thenReturn(mock(RelNode.class));
+        SQLFederationEngine engine = createSQLFederationEngine(processor, 
actualMetaData);
         try (
                 MockedConstruction<SQLFederationRelConverter> converterMocked 
= mockConstruction(SQLFederationRelConverter.class,
                         (mock, context) -> 
when(mock.getSchemaPlus()).thenReturn(mock(SchemaPlus.class)));
                 MockedConstruction<SQLFederationCompilerEngine> compilerMocked 
= mockConstruction(SQLFederationCompilerEngine.class,
-                        (mock, context) -> 
when(mock.compile(any(ExecutionPlanCacheKey.class), 
eq(false))).thenReturn(executionPlan));
+                        (mock, context) -> 
when(mock.compile(any(ExecutionPlanCacheKey.class), 
eq(false))).thenReturn(mock(SQLFederationExecutionPlan.class, 
RETURNS_DEEP_STUBS)));
                 MockedStatic<RelOptUtil> relOptUtil = 
mockStatic(RelOptUtil.class)) {
             relOptUtil.when(() -> RelOptUtil.toString(any(RelNode.class), 
eq(SqlExplainLevel.ALL_ATTRIBUTES))).thenReturn("plan");
-            assertSame(resultSet, engine.executeQuery(prepareEngine, callback, 
federationContext));
+            assertThat(engine.executeQuery(prepareEngine, callback, 
federationContext), is(resultSet));
             ArgumentCaptor<ExecutionPlanCacheKey> cacheKeyCaptor = 
ArgumentCaptor.forClass(ExecutionPlanCacheKey.class);
             
verify(compilerMocked.constructed().get(0)).compile(cacheKeyCaptor.capture(), 
eq(false));
-            Assertions.assertEquals(1, 
cacheKeyCaptor.getValue().getTableMetaDataVersions().size());
-            assertSame(resultSet, engine.getResultSet());
+            
assertThat(cacheKeyCaptor.getValue().getTableMetaDataVersions().size(), is(1));
+            assertThat(engine.getResultSet(), is(resultSet));
             engine.close();
             verify(processor).release("foo_db", "foo_schema", queryContext, 
converterMocked.constructed().get(0).getSchemaPlus());
         }
     }
     
+    @SuppressWarnings("unchecked")
     @Test
     void assertExecuteQueryWithParametersAndOwner() {
-        Properties props = new Properties();
-        props.setProperty(ConfigurationPropertyKey.SQL_SHOW.getKey(), 
Boolean.TRUE.toString());
-        SQLFederationRuleConfiguration config = new 
SQLFederationRuleConfiguration(true, false, new SQLFederationCacheOption(1, 1));
-        ShardingSphereTable table = new ShardingSphereTable("t_order", 
Collections.emptyList(), Collections.emptyList(), Collections.emptyList());
-        ShardingSphereMetaData actualMetaData = createMetaData(config, 
Collections.emptyList(), Collections.singleton(table), 
TypedSPILoader.getService(DatabaseType.class, "PostgreSQL"), props);
-        SQLFederationProcessor processor = mock(SQLFederationProcessor.class);
-        when(processor.getConvention()).thenReturn(mock(Convention.class));
-        final SQLFederationEngine engine = 
createEngineWithProcessor(processor, actualMetaData, 
mock(ShardingSphereStatistics.class), mock(JDBCExecutor.class));
-        TableNameSegment tableNameSegment = new TableNameSegment(0, 0, new 
IdentifierValue("t_order"));
+        TableNameSegment tableNameSegment = new TableNameSegment(0, 0, new 
IdentifierValue("foo_tbl"));
         tableNameSegment.setTableBoundInfo(new TableSegmentBoundInfo(new 
IdentifierValue("foo_db"), new IdentifierValue("foo_schema")));
         SimpleTableSegment simpleTableSegment = new 
SimpleTableSegment(tableNameSegment);
         simpleTableSegment.setOwner(new OwnerSegment(0, 0, new 
IdentifierValue("foo_schema")));
         TablesContext tablesContext = mock(TablesContext.class);
         
when(tablesContext.getSimpleTables()).thenReturn(Collections.singleton(simpleTableSegment));
         SelectStatement selectStatement = mock(SelectStatement.class);
-        
when(selectStatement.getDatabaseType()).thenReturn(TypedSPILoader.getService(DatabaseType.class,
 "PostgreSQL"));
-        SQLStatementContext selectStatementContext = 
mock(SQLStatementContext.class, RETURNS_DEEP_STUBS);
+        when(selectStatement.getDatabaseType()).thenReturn(databaseType);
+        SQLStatementContext selectStatementContext = 
mock(SQLStatementContext.class);
         
when(selectStatementContext.getSqlStatement()).thenReturn(selectStatement, 
selectStatement, selectStatement, mock(CreateTableStatement.class));
         
when(selectStatementContext.getTablesContext()).thenReturn(tablesContext);
         QueryContext queryContext = mock(QueryContext.class);
         
when(queryContext.getSqlStatementContext()).thenReturn(selectStatementContext);
-        when(queryContext.getSql()).thenReturn("SELECT * FROM t_order");
+        when(queryContext.getSql()).thenReturn("SELECT * FROM foo_tbl");
         
when(queryContext.getParameters()).thenReturn(Collections.singletonList(1));
         when(queryContext.getConnectionContext()).thenReturn(new 
ConnectionContext(Collections::emptyList, new Grantee("root", "localhost")));
-        SQLFederationContext federationContext = new 
SQLFederationContext(false, queryContext, actualMetaData, "process_2");
-        DriverExecutionPrepareEngine<JDBCExecutionUnit, Connection> 
prepareEngine = mock(DriverExecutionPrepareEngine.class);
-        JDBCExecutorCallback<? extends ExecuteResult> callback = 
mock(JDBCExecutorCallback.class);
-        ResultSet resultSet = mock(ResultSet.class);
-        when(processor.executePlan(eq(prepareEngine), eq(callback), 
any(SQLFederationExecutionPlan.class), any(SQLFederationRelConverter.class), 
eq(federationContext), any())).thenReturn(resultSet);
-        SQLFederationExecutionPlan executionPlan = 
mock(SQLFederationExecutionPlan.class);
-        when(executionPlan.getPhysicalPlan()).thenReturn(mock(RelNode.class));
+        ShardingSphereMetaData actualMetaData = 
createMetaData(PropertiesBuilder.build(new 
Property(ConfigurationPropertyKey.SQL_SHOW.getKey(), Boolean.TRUE.toString())));
+        SQLFederationEngine engine = createSQLFederationEngine(mock(), 
actualMetaData);
         try (
                 MockedConstruction<SQLFederationRelConverter> ignoredConverter 
= mockConstruction(SQLFederationRelConverter.class,
                         (mock, context) -> 
when(mock.getSchemaPlus()).thenReturn(mock(SchemaPlus.class)));
                 MockedConstruction<SQLFederationCompilerEngine> 
ignoredCompiler = mockConstruction(SQLFederationCompilerEngine.class,
-                        (mock, context) -> 
when(mock.compile(any(ExecutionPlanCacheKey.class), 
eq(false))).thenReturn(executionPlan));
+                        (mock, context) -> 
when(mock.compile(any(ExecutionPlanCacheKey.class), 
eq(false))).thenReturn(mock(SQLFederationExecutionPlan.class, 
RETURNS_DEEP_STUBS)));
                 MockedStatic<RelOptUtil> relOptUtil = 
mockStatic(RelOptUtil.class)) {
             relOptUtil.when(() -> RelOptUtil.toString(any(RelNode.class), 
eq(SqlExplainLevel.ALL_ATTRIBUTES))).thenReturn("plan");
-            engine.executeQuery(prepareEngine, callback, federationContext);
+            engine.executeQuery(mock(), mock(), new 
SQLFederationContext(false, queryContext, actualMetaData, "process_2"));
             assertNull(engine.getResultSet());
         }
     }
     
+    @SuppressWarnings("unchecked")
     @Test
-    void assertExecuteQueryWithMissingTableThrowsUnsupported() {
-        Properties props = new Properties();
-        props.setProperty(ConfigurationPropertyKey.SQL_SHOW.getKey(), 
Boolean.FALSE.toString());
-        SQLFederationRuleConfiguration config = new 
SQLFederationRuleConfiguration(true, false, new SQLFederationCacheOption(1, 1));
-        ShardingSphereMetaData actualMetaData = createMetaData(config, 
Collections.emptyList(), Collections.emptyList(), databaseType, props);
-        SQLFederationProcessor processor = mock(SQLFederationProcessor.class);
-        when(processor.getConvention()).thenReturn(mock(Convention.class));
-        final SQLFederationEngine engine = 
createEngineWithProcessor(processor, actualMetaData, 
mock(ShardingSphereStatistics.class), mock(JDBCExecutor.class));
-        SimpleTableSegment simpleTableSegment = new SimpleTableSegment(new 
TableNameSegment(0, 0, new IdentifierValue("t_order")));
-        TablesContext tablesContext = mock(TablesContext.class);
-        
when(tablesContext.getSimpleTables()).thenReturn(Collections.singleton(simpleTableSegment));
-        SelectStatement selectStatement = mock(SelectStatement.class);
-        when(selectStatement.getDatabaseType()).thenReturn(databaseType);
+    void assertGetSchemaPathWithDefaultSchemaAndOwner() throws SQLException {
+        SimpleTableSegment simpleTableSegment = new SimpleTableSegment(new 
TableNameSegment(0, 0, new IdentifierValue("foo_tbl")));
+        simpleTableSegment.setOwner(new OwnerSegment(0, 0, new 
IdentifierValue("foo_schema")));
         SQLStatementContext selectStatementContext = 
mock(SQLStatementContext.class, RETURNS_DEEP_STUBS);
-        
when(selectStatementContext.getSqlStatement()).thenReturn(selectStatement);
-        
when(selectStatementContext.getTablesContext()).thenReturn(tablesContext);
+        
when(selectStatementContext.getTablesContext().getSimpleTables()).thenReturn(Collections.singleton(simpleTableSegment));
         QueryContext queryContext = mock(QueryContext.class);
         
when(queryContext.getSqlStatementContext()).thenReturn(selectStatementContext);
-        when(queryContext.getSql()).thenReturn("SELECT * FROM t_order");
-        when(queryContext.getParameters()).thenReturn(Collections.emptyList());
+        when(queryContext.getSql()).thenReturn("SELECT * FROM foo_tbl");
         when(queryContext.getConnectionContext()).thenReturn(new 
ConnectionContext(Collections::emptyList, new Grantee("root", "localhost")));
-        SQLFederationContext federationContext = new 
SQLFederationContext(false, queryContext, actualMetaData, "process_3");
+        ShardingSphereMetaData actualMetaData = createMetaData(new 
Properties());
+        SQLFederationContext federationContext = new 
SQLFederationContext(false, queryContext, actualMetaData, 
"process_schema_path_owner");
         DriverExecutionPrepareEngine<JDBCExecutionUnit, Connection> 
prepareEngine = mock(DriverExecutionPrepareEngine.class);
         JDBCExecutorCallback<? extends ExecuteResult> callback = 
mock(JDBCExecutorCallback.class);
-        assertThrows(SQLFederationUnsupportedSQLException.class, () -> {
-            try (
-                    MockedConstruction<SQLFederationRelConverter> ignored = 
mockConstruction(SQLFederationRelConverter.class,
-                            (mock, context) -> 
when(mock.getSchemaPlus()).thenReturn(mock(SchemaPlus.class)))) {
-                engine.executeQuery(prepareEngine, callback, 
federationContext);
-            }
-        });
+        SQLFederationExecutionPlan executionPlan = 
mock(SQLFederationExecutionPlan.class);
+        AtomicReference<List<String>> actualSchemaPath = new 
AtomicReference<>();
+        try (
+                SQLFederationEngine engine = createSQLFederationEngine(mock(), 
actualMetaData);
+                MockedConstruction<DatabaseTypeRegistry> ignoredRegistry = 
mockConstruction(DatabaseTypeRegistry.class, (mock, context) -> {
+                    DialectSchemaOption schemaOption = 
mock(DialectSchemaOption.class);
+                    
when(schemaOption.getDefaultSchema()).thenReturn(Optional.of("public"));
+                    DialectDatabaseMetaData dialectDatabaseMetaData = 
mock(DialectDatabaseMetaData.class);
+                    
when(dialectDatabaseMetaData.getSchemaOption()).thenReturn(schemaOption);
+                    
when(mock.getDialectDatabaseMetaData()).thenReturn(dialectDatabaseMetaData);
+                });
+                MockedConstruction<SQLFederationRelConverter> ignoredConverter 
= mockConstruction(SQLFederationRelConverter.class,
+                        (mock, context) -> actualSchemaPath.set((List<String>) 
context.arguments().get(1)));
+                MockedConstruction<SQLFederationCompilerEngine> 
ignoredCompiler = mockConstruction(SQLFederationCompilerEngine.class,
+                        (mock, context) -> 
when(mock.compile(any(ExecutionPlanCacheKey.class), 
eq(false))).thenReturn(executionPlan));
+                MockedStatic<RelOptUtil> relOptUtil = 
mockStatic(RelOptUtil.class)) {
+            relOptUtil.when(() -> RelOptUtil.toString(any(RelNode.class), 
eq(SqlExplainLevel.ALL_ATTRIBUTES))).thenReturn("plan");
+            engine.executeQuery(prepareEngine, callback, federationContext);
+        }
+        assertThat(actualSchemaPath.get(), 
is(Collections.singletonList("foo_db")));
     }
     
+    @SuppressWarnings("unchecked")
     @Test
-    void assertExecuteQueryWhenExecutionInterrupted() {
-        Properties props = new Properties();
-        props.setProperty(ConfigurationPropertyKey.SQL_SHOW.getKey(), 
Boolean.FALSE.toString());
-        SQLFederationRuleConfiguration config = new 
SQLFederationRuleConfiguration(true, false, new SQLFederationCacheOption(1, 1));
-        ShardingSphereTable table = new ShardingSphereTable("t_order", 
Collections.emptyList(), Collections.emptyList(), Collections.emptyList());
-        ShardingSphereMetaData actualMetaData = createMetaData(config, 
Collections.emptyList(), Collections.singleton(table), databaseType, props);
-        SQLFederationProcessor processor = mock(SQLFederationProcessor.class);
-        when(processor.getConvention()).thenReturn(mock(Convention.class));
-        SimpleTableSegment simpleTableSegment = new SimpleTableSegment(new 
TableNameSegment(0, 0, new IdentifierValue("t_order")));
-        TablesContext tablesContext = mock(TablesContext.class);
-        
when(tablesContext.getSimpleTables()).thenReturn(Collections.singleton(simpleTableSegment));
+    void assertExecuteQueryWithoutSQLShow() throws SQLException {
+        ShardingSphereMetaData actualMetaData = 
createMetaData(PropertiesBuilder.build(new 
Property(ConfigurationPropertyKey.SQL_SHOW.getKey(), 
Boolean.FALSE.toString())));
         SelectStatement selectStatement = mock(SelectStatement.class);
         when(selectStatement.getDatabaseType()).thenReturn(databaseType);
         SQLStatementContext selectStatementContext = 
mock(SQLStatementContext.class, RETURNS_DEEP_STUBS);
         
when(selectStatementContext.getSqlStatement()).thenReturn(selectStatement);
-        
when(selectStatementContext.getTablesContext()).thenReturn(tablesContext);
+        
when(selectStatementContext.getTablesContext().getSimpleTables()).thenReturn(Collections.singleton(new
 SimpleTableSegment(new TableNameSegment(0, 0, new 
IdentifierValue("foo_tbl")))));
         QueryContext queryContext = mock(QueryContext.class);
         
when(queryContext.getSqlStatementContext()).thenReturn(selectStatementContext);
-        when(queryContext.getSql()).thenReturn("SELECT * FROM t_order");
-        when(queryContext.getParameters()).thenReturn(Collections.emptyList());
+        when(queryContext.getSql()).thenReturn("SELECT * FROM foo_tbl");
         when(queryContext.getConnectionContext()).thenReturn(new 
ConnectionContext(Collections::emptyList, new Grantee("root", "localhost")));
-        SQLFederationContext federationContext = new 
SQLFederationContext(false, queryContext, actualMetaData, "process_4");
+        SQLFederationContext federationContext = new 
SQLFederationContext(false, queryContext, actualMetaData, "process_6");
         DriverExecutionPrepareEngine<JDBCExecutionUnit, Connection> 
prepareEngine = mock(DriverExecutionPrepareEngine.class);
         JDBCExecutorCallback<? extends ExecuteResult> callback = 
mock(JDBCExecutorCallback.class);
+        ResultSet resultSet = mock(ResultSet.class);
+        when(resultSet.isClosed()).thenReturn(true);
         SQLFederationExecutionPlan executionPlan = 
mock(SQLFederationExecutionPlan.class);
-        SQLFederationEngine engine = createEngineWithProcessor(processor, 
actualMetaData, mock(ShardingSphereStatistics.class), mock(JDBCExecutor.class));
-        assertThrows(SQLExecutionInterruptedException.class, () -> 
executeWithInterruptedPlan(engine, processor, prepareEngine, callback, 
federationContext, executionPlan));
+        SQLFederationProcessor processor = mock(SQLFederationProcessor.class);
+        when(processor.executePlan(eq(prepareEngine), eq(callback), 
eq(executionPlan), any(SQLFederationRelConverter.class), eq(federationContext), 
any())).thenReturn(resultSet);
+        try (
+                SQLFederationEngine engine = 
createSQLFederationEngine(processor, actualMetaData);
+                MockedConstruction<SQLFederationRelConverter> ignored = 
mockConstruction(SQLFederationRelConverter.class,
+                        (mock, context) -> 
when(mock.getSchemaPlus()).thenReturn(mock(SchemaPlus.class)));
+                MockedConstruction<SQLFederationCompilerEngine> 
ignoredCompiler = mockConstruction(SQLFederationCompilerEngine.class,
+                        (mock, context) -> 
when(mock.compile(any(ExecutionPlanCacheKey.class), 
eq(false))).thenReturn(executionPlan));
+                MockedStatic<RelOptUtil> relOptUtil = 
mockStatic(RelOptUtil.class)) {
+            relOptUtil.when(() -> RelOptUtil.toString(any(RelNode.class), 
eq(SqlExplainLevel.ALL_ATTRIBUTES))).thenReturn("plan");
+            engine.executeQuery(prepareEngine, callback, federationContext);
+        }
     }
     
+    @SuppressWarnings("unchecked")
     @Test
-    void assertCloseCollectsSQLException() throws SQLException {
-        Properties props = new Properties();
-        props.setProperty(ConfigurationPropertyKey.SQL_SHOW.getKey(), 
Boolean.TRUE.toString());
-        SQLFederationRuleConfiguration config = new 
SQLFederationRuleConfiguration(true, false, new SQLFederationCacheOption(1, 
1L));
-        ShardingSphereTable table = new ShardingSphereTable("t_order", 
Collections.emptyList(), Collections.emptyList(), Collections.emptyList());
-        ShardingSphereMetaData actualMetaData = createMetaData(config, 
Collections.emptyList(), Collections.singleton(table), 
TypedSPILoader.getService(DatabaseType.class, "PostgreSQL"), props);
-        SQLFederationProcessor processor = mock(SQLFederationProcessor.class);
-        when(processor.getConvention()).thenReturn(mock(Convention.class));
-        SQLFederationEngine engine = createEngineWithProcessor(processor, 
actualMetaData, mock(ShardingSphereStatistics.class), mock(JDBCExecutor.class));
-        SimpleTableSegment simpleTableSegment = new SimpleTableSegment(new 
TableNameSegment(0, 0, new IdentifierValue("t_order")));
-        TablesContext tablesContext = mock(TablesContext.class);
-        
when(tablesContext.getSimpleTables()).thenReturn(Collections.singleton(simpleTableSegment));
+    void assertThrowIntegrityConstraintViolationDirectly() {
+        ShardingSphereMetaData actualMetaData = 
createMetaData(PropertiesBuilder.build(new 
Property(ConfigurationPropertyKey.SQL_SHOW.getKey(), 
Boolean.FALSE.toString())));
         SelectStatement selectStatement = mock(SelectStatement.class);
-        
when(selectStatement.getDatabaseType()).thenReturn(TypedSPILoader.getService(DatabaseType.class,
 "PostgreSQL"));
+        when(selectStatement.getDatabaseType()).thenReturn(databaseType);
         SQLStatementContext selectStatementContext = 
mock(SQLStatementContext.class, RETURNS_DEEP_STUBS);
-        
when(selectStatementContext.getSqlStatement()).thenReturn(selectStatement, 
selectStatement);
-        
when(selectStatementContext.getTablesContext()).thenReturn(tablesContext);
+        
when(selectStatementContext.getSqlStatement()).thenReturn(selectStatement);
+        
when(selectStatementContext.getTablesContext().getSimpleTables()).thenReturn(Collections.singleton(new
 SimpleTableSegment(new TableNameSegment(0, 0, new 
IdentifierValue("foo_tbl")))));
         QueryContext queryContext = mock(QueryContext.class);
         
when(queryContext.getSqlStatementContext()).thenReturn(selectStatementContext);
-        when(queryContext.getSql()).thenReturn("SELECT * FROM t_order");
-        when(queryContext.getParameters()).thenReturn(Collections.emptyList());
+        when(queryContext.getSql()).thenReturn("SELECT * FROM foo_tbl");
         when(queryContext.getConnectionContext()).thenReturn(new 
ConnectionContext(Collections::emptyList, new Grantee("root", "localhost")));
-        SQLFederationContext federationContext = new 
SQLFederationContext(false, queryContext, actualMetaData, "process_5");
+        SQLFederationContext federationContext = new 
SQLFederationContext(false, queryContext, actualMetaData, "process_8");
+        SQLFederationProcessor processor = mock(SQLFederationProcessor.class);
         DriverExecutionPrepareEngine<JDBCExecutionUnit, Connection> 
prepareEngine = mock(DriverExecutionPrepareEngine.class);
         JDBCExecutorCallback<? extends ExecuteResult> callback = 
mock(JDBCExecutorCallback.class);
-        ResultSet resultSet = mock(ResultSet.class);
-        doThrow(new SQLException("close error")).when(resultSet).close();
-        when(processor.executePlan(eq(prepareEngine), eq(callback), 
any(SQLFederationExecutionPlan.class), any(SQLFederationRelConverter.class), 
eq(federationContext), any())).thenReturn(resultSet);
         SQLFederationExecutionPlan executionPlan = 
mock(SQLFederationExecutionPlan.class);
-        when(executionPlan.getPhysicalPlan()).thenReturn(mock(RelNode.class));
+        SQLFederationEngine engine = createSQLFederationEngine(processor, 
actualMetaData);
         try (
                 MockedConstruction<SQLFederationRelConverter> ignored = 
mockConstruction(SQLFederationRelConverter.class,
                         (mock, context) -> 
when(mock.getSchemaPlus()).thenReturn(mock(SchemaPlus.class)));
@@ -443,45 +405,96 @@ class SQLFederationEngineTest {
                         (mock, context) -> 
when(mock.compile(any(ExecutionPlanCacheKey.class), 
eq(false))).thenReturn(executionPlan));
                 MockedStatic<RelOptUtil> relOptUtil = 
mockStatic(RelOptUtil.class)) {
             relOptUtil.when(() -> RelOptUtil.toString(any(RelNode.class), 
eq(SqlExplainLevel.ALL_ATTRIBUTES))).thenReturn("plan");
-            engine.executeQuery(prepareEngine, callback, federationContext);
-            SQLException actual = assertThrows(SQLException.class, 
engine::close);
-            Assertions.assertEquals("close error", 
actual.getNextException().getMessage());
-            verify(processor).release(eq("foo_db"), eq("foo_schema"), 
eq(queryContext), any());
+            doAnswer(invocation -> {
+                throw new SQLIntegrityConstraintViolationException();
+            }).when(processor).executePlan(eq(prepareEngine), eq(callback), 
eq(executionPlan), any(SQLFederationRelConverter.class), eq(federationContext), 
any());
+            assertThrows(SQLIntegrityConstraintViolationException.class, () -> 
engine.executeQuery(prepareEngine, callback, federationContext));
+        }
+    }
+    
+    @Test
+    void assertGetResultSetForSelectStatement() throws 
ReflectiveOperationException {
+        ShardingSphereMetaData actualMetaData = 
createMetaData(Collections.emptyList(), new Properties());
+        SQLStatementContext selectStatementContext = 
mock(SQLStatementContext.class, RETURNS_DEEP_STUBS);
+        
when(selectStatementContext.getSqlStatement()).thenReturn(mock(SelectStatement.class));
+        QueryContext selectQueryContext = mock(QueryContext.class);
+        
when(selectQueryContext.getSqlStatementContext()).thenReturn(selectStatementContext);
+        ResultSet expectedResultSet = mock(ResultSet.class);
+        SQLFederationEngine engine = createSQLFederationEngine(mock(), 
actualMetaData);
+        
Plugins.getMemberAccessor().set(SQLFederationEngine.class.getDeclaredField("queryContext"),
 engine, selectQueryContext);
+        
Plugins.getMemberAccessor().set(SQLFederationEngine.class.getDeclaredField("resultSet"),
 engine, expectedResultSet);
+        assertThat(engine.getResultSet(), is(expectedResultSet));
+    }
+    
+    @Test
+    void assertCloseWithoutSchema() throws SQLException, 
ReflectiveOperationException {
+        ShardingSphereMetaData actualMetaData = 
createMetaData(Collections.emptyList(), new Properties());
+        SQLFederationProcessor processor = mock(SQLFederationProcessor.class);
+        try (SQLFederationEngine engine = createSQLFederationEngine(processor, 
actualMetaData)) {
+            
Plugins.getMemberAccessor().set(SQLFederationEngine.class.getDeclaredField("queryContext"),
 engine, mock(QueryContext.class));
+            verify(processor, never()).release(any(), any(), any(), any());
         }
     }
     
-    private void executeWithInterruptedPlan(final SQLFederationEngine engine, 
final SQLFederationProcessor processor,
-                                            final 
DriverExecutionPrepareEngine<JDBCExecutionUnit, Connection> prepareEngine,
-                                            final JDBCExecutorCallback<? 
extends ExecuteResult> callback, final SQLFederationContext federationContext,
-                                            final SQLFederationExecutionPlan 
executionPlan) {
+    @SuppressWarnings("unchecked")
+    @Test
+    void assertCloseWhenThrowsException() throws SQLException, 
ReflectiveOperationException {
+        SQLStatementContext selectStatementContext = 
mock(SQLStatementContext.class, RETURNS_DEEP_STUBS);
+        
when(selectStatementContext.getTablesContext().getSimpleTables()).thenReturn(Collections.singleton(new
 SimpleTableSegment(new TableNameSegment(0, 0, new 
IdentifierValue("foo_tbl")))));
+        QueryContext queryContext = mock(QueryContext.class);
+        
when(queryContext.getSqlStatementContext()).thenReturn(selectStatementContext);
+        when(queryContext.getSql()).thenReturn("SELECT * FROM foo_tbl");
+        when(queryContext.getConnectionContext()).thenReturn(new 
ConnectionContext(Collections::emptyList, new Grantee("root", "localhost")));
+        ShardingSphereMetaData actualMetaData = createMetaData(new 
Properties());
+        SQLFederationContext federationContext = new 
SQLFederationContext(false, queryContext, actualMetaData, "warning_process");
+        DriverExecutionPrepareEngine<JDBCExecutionUnit, Connection> 
prepareEngine = mock(DriverExecutionPrepareEngine.class);
+        JDBCExecutorCallback<? extends ExecuteResult> callback = 
mock(JDBCExecutorCallback.class);
+        SQLFederationProcessor processor = mock(SQLFederationProcessor.class);
+        SQLFederationEngine engine = createSQLFederationEngine(processor, 
actualMetaData);
+        ResultSet closableResultSet = mock(ResultSet.class);
+        doThrow(SQLException.class).when(closableResultSet).close();
+        
Plugins.getMemberAccessor().set(SQLFederationEngine.class.getDeclaredField("resultSet"),
 engine, closableResultSet);
         try (
-                MockedConstruction<SQLFederationRelConverter> ignored = 
mockConstruction(SQLFederationRelConverter.class,
+                MockedConstruction<SQLFederationRelConverter> ignoredConverter 
= mockConstruction(SQLFederationRelConverter.class,
                         (mock, context) -> 
when(mock.getSchemaPlus()).thenReturn(mock(SchemaPlus.class)));
                 MockedConstruction<SQLFederationCompilerEngine> 
ignoredCompiler = mockConstruction(SQLFederationCompilerEngine.class,
-                        (mock, context) -> 
when(mock.compile(any(ExecutionPlanCacheKey.class), 
eq(false))).thenReturn(executionPlan))) {
-            when(processor.executePlan(eq(prepareEngine), eq(callback), 
eq(executionPlan), any(SQLFederationRelConverter.class), eq(federationContext), 
any()))
-                    .thenThrow(new SQLExecutionInterruptedException());
-            engine.executeQuery(prepareEngine, callback, federationContext);
+                        (mock, context) -> 
when(mock.compile(any(ExecutionPlanCacheKey.class), 
eq(false))).thenReturn(mock(SQLFederationExecutionPlan.class)));
+                MockedStatic<RelOptUtil> relOptUtil = 
mockStatic(RelOptUtil.class)) {
+            relOptUtil.when(() -> RelOptUtil.toString(any(RelNode.class), 
eq(SqlExplainLevel.ALL_ATTRIBUTES))).thenReturn("plan");
+            
doThrow(RuntimeException.class).when(processor).prepare(eq(prepareEngine), 
eq(callback), anyString(), anyString(), eq(federationContext), any(), 
any(SchemaPlus.class));
+            assertThrows(SQLFederationUnsupportedSQLException.class, () -> 
engine.executeQuery(prepareEngine, callback, federationContext));
         }
     }
     
-    private ShardingSphereMetaData createMetaData(final 
SQLFederationRuleConfiguration config, final Collection<ShardingSphereRule> 
databaseRules,
-                                                  final 
Collection<ShardingSphereTable> tables, final DatabaseType protocolType, final 
Properties props) {
-        ShardingSphereSchema schema = new ShardingSphereSchema("foo_schema", 
tables, Collections.emptyList());
-        ResourceMetaData resourceMetaData = new 
ResourceMetaData(Collections.emptyMap());
-        RuleMetaData databaseRuleMetaData = new RuleMetaData(databaseRules);
-        ShardingSphereDatabase database = new ShardingSphereDatabase("foo_db", 
protocolType, resourceMetaData, databaseRuleMetaData, 
Collections.singleton(schema));
-        Collection<ShardingSphereRule> globalRules = Collections.singleton(new 
SQLFederationRule(config, Collections.singletonList(database)));
-        return new ShardingSphereMetaData(Collections.singletonList(database), 
new ResourceMetaData(Collections.emptyMap()), new RuleMetaData(globalRules), 
new ConfigurationProperties(props));
+    private SQLFederationEngine createSQLFederationEngine(final 
Collection<ShardingSphereRule> globalRules, final 
Collection<ShardingSphereRule> databaseRules) {
+        ShardingSphereMetaData metaData = mock(ShardingSphereMetaData.class, 
RETURNS_DEEP_STUBS);
+        when(metaData.getGlobalRuleMetaData()).thenReturn(new 
RuleMetaData(globalRules));
+        
when(metaData.getDatabase("foo_db").getRuleMetaData().getRules()).thenReturn(databaseRules);
+        return new SQLFederationEngine("foo_db", "foo_db", metaData, mock(), 
mock());
     }
     
-    private SQLFederationEngine createEngineWithProcessor(final 
SQLFederationProcessor processor, final ShardingSphereMetaData metaData,
-                                                          final 
ShardingSphereStatistics statistics, final JDBCExecutor jdbcExecutor) {
+    private SQLFederationEngine createSQLFederationEngine(final 
SQLFederationProcessor processor, final ShardingSphereMetaData metaData) {
+        ShardingSphereStatistics statistics = 
mock(ShardingSphereStatistics.class);
+        JDBCExecutor jdbcExecutor = mock(JDBCExecutor.class);
         try (MockedStatic<SQLFederationProcessorFactory> factoryMock = 
mockStatic(SQLFederationProcessorFactory.class)) {
             SQLFederationProcessorFactory factory = 
mock(SQLFederationProcessorFactory.class);
-            
factoryMock.when(SQLFederationProcessorFactory::getInstance).thenReturn(factory);
             when(factory.newInstance(statistics, 
jdbcExecutor)).thenReturn(processor);
+            
factoryMock.when(SQLFederationProcessorFactory::getInstance).thenReturn(factory);
             return new SQLFederationEngine("foo_db", "foo_schema", metaData, 
statistics, jdbcExecutor);
         }
     }
+    
+    private ShardingSphereMetaData createMetaData(final Properties props) {
+        ShardingSphereTable table = new ShardingSphereTable("foo_tbl", 
Collections.emptyList(), Collections.emptyList(), Collections.emptyList());
+        return createMetaData(Collections.singleton(table), props);
+    }
+    
+    private ShardingSphereMetaData createMetaData(final 
Collection<ShardingSphereTable> tables, final Properties props) {
+        ShardingSphereSchema schema = new ShardingSphereSchema("foo_schema", 
tables, Collections.emptyList());
+        ShardingSphereDatabase database = new ShardingSphereDatabase(
+                "foo_db", databaseType, new 
ResourceMetaData(Collections.emptyMap()), new 
RuleMetaData(Collections.emptyList()), Collections.singleton(schema));
+        SQLFederationRuleConfiguration ruleConfig = new 
SQLFederationRuleConfiguration(true, false, cacheOption);
+        Collection<ShardingSphereRule> globalRules = Collections.singleton(new 
SQLFederationRule(ruleConfig, Collections.singleton(database)));
+        return new ShardingSphereMetaData(Collections.singleton(database), new 
ResourceMetaData(Collections.emptyMap()), new RuleMetaData(globalRules), new 
ConfigurationProperties(props));
+    }
 }
diff --git 
a/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/connector/StandardDatabaseProxyConnector.java
 
b/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/connector/StandardDatabaseProxyConnector.java
index 2b1e06e3b16..7cf6aff54c5 100644
--- 
a/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/connector/StandardDatabaseProxyConnector.java
+++ 
b/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/connector/StandardDatabaseProxyConnector.java
@@ -184,7 +184,7 @@ public final class StandardDatabaseProxyConnector 
implements DatabaseProxyConnec
             return doExecuteFederation();
         }
         FederationMetaDataRefreshEngine federationMetaDataRefreshEngine = new 
FederationMetaDataRefreshEngine(queryContext.getSqlStatementContext());
-        if (proxySQLExecutor.getSqlFederationEngine().isSqlFederationEnabled() 
&& federationMetaDataRefreshEngine.isNeedRefresh()) {
+        if (proxySQLExecutor.getSqlFederationEngine().isSQLFederationEnabled() 
&& federationMetaDataRefreshEngine.isNeedRefresh()) {
             
federationMetaDataRefreshEngine.refresh(contextManager.getPersistServiceFacade().getModeFacade().getMetaDataManagerService(),
 database);
             return new 
UpdateResponseHeader(queryContext.getSqlStatementContext().getSqlStatement());
         }

Reply via email to