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());
}