From aa697cca053c78fec829f1ec5f3bfbcb45c58e5f Mon Sep 17 00:00:00 2001 From: zhaojinchao Date: Fri, 24 Mar 2023 22:57:42 +0800 Subject: [PATCH] Cherry-pick c6dd048 and 1025a5e (#24817) * Avoid repeat call findRules method (#24797) * Avoid repeat call findRules method * Fix chekystyle * Avoid repeat call findRules method * Adjust single table to isTransparentStatement * Change method name * Refactor DatabaseConnector avoid repeat call findRules method (#24816) * Refactor DatabaseConnector avoid repeat call findRules method * Update * Fix index --- .../identifier/type/ColumnContainedRule.java | 1 + .../adapter/AbstractResultSetAdapter.java | 7 ++- .../resultset/ShardingSphereResultSet.java | 11 +++-- .../ShardingSphereResultSetMetaData.java | 24 ++-------- .../ShardingSpherePreparedStatement.java | 35 +++++++++++++- .../statement/ShardingSphereStatement.java | 33 ++++++++++++- .../jdbc/adapter/ResultSetAdapterTest.java | 15 +----- .../adapter/ResultSetGetterAdapterTest.java | 2 +- .../ShardingSphereResultSetTest.java | 2 +- .../UnsupportedOperationResultSetTest.java | 2 +- ...supportedUpdateOperationResultSetTest.java | 2 +- .../backend/connector/DatabaseConnector.java | 46 ++++++++++++------- 12 files changed, 117 insertions(+), 63 deletions(-) diff --git a/infra/common/src/main/java/org/apache/shardingsphere/infra/rule/identifier/type/ColumnContainedRule.java b/infra/common/src/main/java/org/apache/shardingsphere/infra/rule/identifier/type/ColumnContainedRule.java index cd15c9f768b23..b327f8d23c6ce 100644 --- a/infra/common/src/main/java/org/apache/shardingsphere/infra/rule/identifier/type/ColumnContainedRule.java +++ b/infra/common/src/main/java/org/apache/shardingsphere/infra/rule/identifier/type/ColumnContainedRule.java @@ -21,6 +21,7 @@ import java.util.Collection; +//TODO Consider introducing transparent table and enhance table. /** * ShardingSphere rule which contains column. */ diff --git a/jdbc/core/src/main/java/org/apache/shardingsphere/driver/jdbc/adapter/AbstractResultSetAdapter.java b/jdbc/core/src/main/java/org/apache/shardingsphere/driver/jdbc/adapter/AbstractResultSetAdapter.java index e4002e8363bdd..324fa22daad1b 100644 --- a/jdbc/core/src/main/java/org/apache/shardingsphere/driver/jdbc/adapter/AbstractResultSetAdapter.java +++ b/jdbc/core/src/main/java/org/apache/shardingsphere/driver/jdbc/adapter/AbstractResultSetAdapter.java @@ -46,6 +46,8 @@ public abstract class AbstractResultSetAdapter extends AbstractUnsupportedOperat @Getter private final Statement statement; + private final boolean transparentStatement; + private boolean closed; private final ForceExecuteTemplate forceExecuteTemplate = new ForceExecuteTemplate<>(); @@ -53,16 +55,17 @@ public abstract class AbstractResultSetAdapter extends AbstractUnsupportedOperat @Getter private final ExecutionContext executionContext; - protected AbstractResultSetAdapter(final List resultSets, final Statement statement, final ExecutionContext executionContext) { + protected AbstractResultSetAdapter(final List resultSets, final Statement statement, final boolean transparentStatement, final ExecutionContext executionContext) { Preconditions.checkArgument(!resultSets.isEmpty()); this.resultSets = resultSets; this.statement = statement; + this.transparentStatement = transparentStatement; this.executionContext = executionContext; } @Override public final ResultSetMetaData getMetaData() throws SQLException { - return new ShardingSphereResultSetMetaData(resultSets.get(0).getMetaData(), getDatabase(), executionContext.getSqlStatementContext()); + return new ShardingSphereResultSetMetaData(resultSets.get(0).getMetaData(), getDatabase(), transparentStatement, executionContext.getSqlStatementContext()); } private ShardingSphereDatabase getDatabase() { diff --git a/jdbc/core/src/main/java/org/apache/shardingsphere/driver/jdbc/core/resultset/ShardingSphereResultSet.java b/jdbc/core/src/main/java/org/apache/shardingsphere/driver/jdbc/core/resultset/ShardingSphereResultSet.java index 3e6149a3d54f1..67f8dedf34685 100644 --- a/jdbc/core/src/main/java/org/apache/shardingsphere/driver/jdbc/core/resultset/ShardingSphereResultSet.java +++ b/jdbc/core/src/main/java/org/apache/shardingsphere/driver/jdbc/core/resultset/ShardingSphereResultSet.java @@ -62,15 +62,16 @@ public final class ShardingSphereResultSet extends AbstractResultSetAdapter { private final Map columnLabelAndIndexMap; - public ShardingSphereResultSet(final List resultSets, final MergedResult mergeResultSet, final Statement statement, final ExecutionContext executionContext) throws SQLException { - super(resultSets, statement, executionContext); + public ShardingSphereResultSet(final List resultSets, final MergedResult mergeResultSet, final Statement statement, final boolean transparentStatement, + final ExecutionContext executionContext) throws SQLException { + super(resultSets, statement, transparentStatement, executionContext); this.mergeResultSet = mergeResultSet; columnLabelAndIndexMap = ShardingSphereResultSetUtil.createColumnLabelAndIndexMap(executionContext.getSqlStatementContext(), resultSets.get(0).getMetaData()); } - public ShardingSphereResultSet(final List resultSets, final MergedResult mergeResultSet, final Statement statement, final ExecutionContext executionContext, - final Map columnLabelAndIndexMap) { - super(resultSets, statement, executionContext); + public ShardingSphereResultSet(final List resultSets, final MergedResult mergeResultSet, final Statement statement, final boolean transparentStatement, + final ExecutionContext executionContext, final Map columnLabelAndIndexMap) { + super(resultSets, statement, transparentStatement, executionContext); this.mergeResultSet = mergeResultSet; this.columnLabelAndIndexMap = columnLabelAndIndexMap; } diff --git a/jdbc/core/src/main/java/org/apache/shardingsphere/driver/jdbc/core/resultset/ShardingSphereResultSetMetaData.java b/jdbc/core/src/main/java/org/apache/shardingsphere/driver/jdbc/core/resultset/ShardingSphereResultSetMetaData.java index 87b8f90dadc64..cc0bef694c731 100644 --- a/jdbc/core/src/main/java/org/apache/shardingsphere/driver/jdbc/core/resultset/ShardingSphereResultSetMetaData.java +++ b/jdbc/core/src/main/java/org/apache/shardingsphere/driver/jdbc/core/resultset/ShardingSphereResultSetMetaData.java @@ -28,9 +28,7 @@ import org.apache.shardingsphere.infra.binder.statement.dml.SelectStatementContext; import org.apache.shardingsphere.infra.database.DefaultDatabase; import org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase; -import org.apache.shardingsphere.infra.rule.identifier.type.ColumnContainedRule; import org.apache.shardingsphere.infra.rule.identifier.type.DataNodeContainedRule; -import org.apache.shardingsphere.infra.rule.identifier.type.MutableDataNodeRule; import java.sql.ResultSetMetaData; import java.sql.SQLException; @@ -47,12 +45,14 @@ public final class ShardingSphereResultSetMetaData extends WrapperAdapter implem private final ShardingSphereDatabase database; + private final boolean transparentStatement; + private final SQLStatementContext sqlStatementContext; @Override public int getColumnCount() throws SQLException { if (sqlStatementContext instanceof SelectStatementContext) { - if (isAllSingleTable()) { + if (transparentStatement) { return resultSetMetaData.getColumnCount(); } if (hasSelectExpandProjections()) { @@ -100,7 +100,7 @@ public int getColumnDisplaySize(final int column) throws SQLException { @Override public String getColumnLabel(final int column) throws SQLException { - if (isAllSingleTable()) { + if (transparentStatement) { return resultSetMetaData.getColumnLabel(column); } if (hasSelectExpandProjections()) { @@ -115,7 +115,7 @@ public String getColumnLabel(final int column) throws SQLException { @Override public String getColumnName(final int column) throws SQLException { - if (isAllSingleTable()) { + if (transparentStatement) { return resultSetMetaData.getColumnName(column); } if (hasSelectExpandProjections()) { @@ -135,20 +135,6 @@ private boolean hasSelectExpandProjections() { return sqlStatementContext instanceof SelectStatementContext && !((SelectStatementContext) sqlStatementContext).getProjectionsContext().getExpandProjections().isEmpty(); } - private boolean isAllSingleTable() { - return sqlStatementContext.getTablesContext().getTableNames().stream().allMatch(each -> !containsInImmutableDataNodeContainedRule(each) - && !containsInColumnContainedRule(each)); - } - - private boolean containsInImmutableDataNodeContainedRule(final String tableName) { - return database.getRuleMetaData().findRules(DataNodeContainedRule.class).stream() - .filter(each -> !(each instanceof MutableDataNodeRule)).anyMatch(each -> each.getAllTables().contains(tableName)); - } - - private boolean containsInColumnContainedRule(final String tableName) { - return database.getRuleMetaData().findRules(ColumnContainedRule.class).stream().anyMatch(each -> each.getTables().contains(tableName)); - } - private void checkColumnIndex(final int column) throws SQLException { List actualProjections = ((SelectStatementContext) sqlStatementContext).getProjectionsContext().getExpandProjections(); if (column > actualProjections.size()) { diff --git a/jdbc/core/src/main/java/org/apache/shardingsphere/driver/jdbc/core/statement/ShardingSpherePreparedStatement.java b/jdbc/core/src/main/java/org/apache/shardingsphere/driver/jdbc/core/statement/ShardingSpherePreparedStatement.java index 1219ac4313a57..e013cdba59979 100644 --- a/jdbc/core/src/main/java/org/apache/shardingsphere/driver/jdbc/core/statement/ShardingSpherePreparedStatement.java +++ b/jdbc/core/src/main/java/org/apache/shardingsphere/driver/jdbc/core/statement/ShardingSpherePreparedStatement.java @@ -81,6 +81,8 @@ import org.apache.shardingsphere.infra.route.context.RouteContext; import org.apache.shardingsphere.infra.rule.ShardingSphereRule; import org.apache.shardingsphere.infra.rule.identifier.type.DataNodeContainedRule; +import org.apache.shardingsphere.infra.rule.identifier.type.ColumnContainedRule; +import org.apache.shardingsphere.infra.rule.identifier.type.MutableDataNodeRule; import org.apache.shardingsphere.infra.rule.identifier.type.RawExecutionRule; import org.apache.shardingsphere.infra.rule.identifier.type.StorageConnectorReusableRule; import org.apache.shardingsphere.mode.metadata.MetaDataContexts; @@ -152,6 +154,9 @@ public final class ShardingSpherePreparedStatement extends AbstractPreparedState @Getter(AccessLevel.PROTECTED) private final StatementManager statementManager; + @Getter + private final boolean transparentStatement; + private ExecutionContext executionContext; private Map columnLabelAndIndexMap; @@ -207,6 +212,7 @@ private ShardingSpherePreparedStatement(final ShardingSphereConnection connectio kernelProcessor = new KernelProcessor(); statementsCacheable = isStatementsCacheable(metaDataContexts.getMetaData().getDatabase(connection.getDatabaseName()).getRuleMetaData()); trafficRule = metaDataContexts.getMetaData().getGlobalRuleMetaData().getSingleRule(TrafficRule.class); + transparentStatement = isTransparentStatement(metaDataContexts.getMetaData().getDatabase(connection.getDatabaseName()).getRuleMetaData()); statementManager = new StatementManager(); } @@ -214,6 +220,31 @@ private boolean isStatementsCacheable(final ShardingSphereRuleMetaData databaseR return databaseRuleMetaData.findRules(StorageConnectorReusableRule.class).size() == databaseRuleMetaData.getRules().size() && !HintManager.isInstantiated(); } + private boolean isTransparentStatement(final ShardingSphereRuleMetaData ruleMetaData) { + Optional dataNodeContainedRule = getDataNodeContainedRuleForShardingRule(ruleMetaData.findRules(DataNodeContainedRule.class)); + Collection columnContainedRules = ruleMetaData.findRules(ColumnContainedRule.class); + for (String each : sqlStatementContext.getTablesContext().getTableNames()) { + return (!dataNodeContainedRule.isPresent() || !dataNodeContainedRule.get().getAllTables().contains(each)) && !containsInColumnContainedRule(each, columnContainedRules); + } + return true; + } + + private Optional getDataNodeContainedRuleForShardingRule(final Collection dataNodeContainedRules) { + for (DataNodeContainedRule each : dataNodeContainedRules) { + if (!(each instanceof MutableDataNodeRule)) { + return Optional.of(each); + } + } + return Optional.empty(); + } + + private boolean containsInColumnContainedRule(final String tableName, final Collection columnContainedRules) { + for (ColumnContainedRule each : columnContainedRules) { + return each.getTables().contains(tableName); + } + return false; + } + @Override public ResultSet executeQuery() throws SQLException { ResultSet result; @@ -240,7 +271,7 @@ public ResultSet executeQuery() throws SQLException { List resultSets = getResultSets(); Map columnLabelAndIndexMap = null != this.columnLabelAndIndexMap ? this.columnLabelAndIndexMap : (this.columnLabelAndIndexMap = ShardingSphereResultSetUtil.createColumnLabelAndIndexMap(sqlStatementContext, resultSets.get(0).getMetaData())); - result = new ShardingSphereResultSet(resultSets, mergedResult, this, executionContext, columnLabelAndIndexMap); + result = new ShardingSphereResultSet(resultSets, mergedResult, this, transparentStatement, executionContext, columnLabelAndIndexMap); // CHECKSTYLE:OFF } catch (final Exception ex) { // CHECKSTYLE:ON @@ -521,7 +552,7 @@ public ResultSet getResultSet() throws SQLException { MergedResult mergedResult = mergeQuery(getQueryResults(resultSets)); Map columnLabelAndIndexMap = null != this.columnLabelAndIndexMap ? this.columnLabelAndIndexMap : (this.columnLabelAndIndexMap = ShardingSphereResultSetUtil.createColumnLabelAndIndexMap(sqlStatementContext, resultSets.get(0).getMetaData())); - currentResultSet = new ShardingSphereResultSet(resultSets, mergedResult, this, executionContext, columnLabelAndIndexMap); + currentResultSet = new ShardingSphereResultSet(resultSets, mergedResult, this, transparentStatement, executionContext, columnLabelAndIndexMap); } return currentResultSet; } diff --git a/jdbc/core/src/main/java/org/apache/shardingsphere/driver/jdbc/core/statement/ShardingSphereStatement.java b/jdbc/core/src/main/java/org/apache/shardingsphere/driver/jdbc/core/statement/ShardingSphereStatement.java index 67a1e8a26d678..281a61960e2c4 100644 --- a/jdbc/core/src/main/java/org/apache/shardingsphere/driver/jdbc/core/statement/ShardingSphereStatement.java +++ b/jdbc/core/src/main/java/org/apache/shardingsphere/driver/jdbc/core/statement/ShardingSphereStatement.java @@ -75,7 +75,9 @@ import org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase; import org.apache.shardingsphere.infra.metadata.database.rule.ShardingSphereRuleMetaData; import org.apache.shardingsphere.infra.route.context.RouteContext; +import org.apache.shardingsphere.infra.rule.identifier.type.ColumnContainedRule; import org.apache.shardingsphere.infra.rule.identifier.type.DataNodeContainedRule; +import org.apache.shardingsphere.infra.rule.identifier.type.MutableDataNodeRule; import org.apache.shardingsphere.infra.rule.identifier.type.RawExecutionRule; import org.apache.shardingsphere.mode.metadata.MetaDataContexts; import org.apache.shardingsphere.parser.rule.SQLParserRule; @@ -177,7 +179,8 @@ public ResultSet executeQuery(final String sql) throws SQLException { executionContext = createExecutionContext(queryContext); List queryResults = executeQuery0(); MergedResult mergedResult = mergeQuery(queryResults); - result = new ShardingSphereResultSet(getResultSets(), mergedResult, this, executionContext); + result = new ShardingSphereResultSet(getResultSets(), mergedResult, this, isTransparentStatement(queryContext.getSqlStatementContext(), + metaDataContexts.getMetaData().getDatabase(connection.getDatabaseName()).getRuleMetaData()), executionContext); // CHECKSTYLE:OFF } catch (final Exception ex) { // CHECKSTYLE:ON @@ -242,6 +245,31 @@ private DriverExecutionPrepareEngine createDriver metaDataContexts.getMetaData().getDatabase(connection.getDatabaseName()).getResourceMetaData().getStorageTypes()); } + private boolean isTransparentStatement(final SQLStatementContext sqlStatementContext, final ShardingSphereRuleMetaData ruleMetaData) { + Optional dataNodeContainedRule = getDataNodeContainedRuleForShardingRule(ruleMetaData.findRules(DataNodeContainedRule.class)); + Collection columnContainedRules = ruleMetaData.findRules(ColumnContainedRule.class); + for (String each : sqlStatementContext.getTablesContext().getTableNames()) { + return (!dataNodeContainedRule.isPresent() || !dataNodeContainedRule.get().getAllTables().contains(each)) && !containsInColumnContainedRule(each, columnContainedRules); + } + return true; + } + + private Optional getDataNodeContainedRuleForShardingRule(final Collection dataNodeContainedRules) { + for (DataNodeContainedRule each : dataNodeContainedRules) { + if (!(each instanceof MutableDataNodeRule)) { + return Optional.of(each); + } + } + return Optional.empty(); + } + + private boolean containsInColumnContainedRule(final String tableName, final Collection columnContainedRules) { + for (ColumnContainedRule each : columnContainedRules) { + return each.getTables().contains(tableName); + } + return false; + } + @Override public int executeUpdate(final String sql) throws SQLException { try { @@ -615,7 +643,8 @@ public ResultSet getResultSet() throws SQLException { return currentResultSet; } MergedResult mergedResult = mergeQuery(getQueryResults(resultSets)); - currentResultSet = new ShardingSphereResultSet(resultSets, mergedResult, this, executionContext); + currentResultSet = new ShardingSphereResultSet(resultSets, mergedResult, this, isTransparentStatement(executionContext.getSqlStatementContext(), + metaDataContexts.getMetaData().getDatabase(connection.getDatabaseName()).getRuleMetaData()), executionContext); } return currentResultSet; } diff --git a/jdbc/core/src/test/java/org/apache/shardingsphere/driver/jdbc/adapter/ResultSetAdapterTest.java b/jdbc/core/src/test/java/org/apache/shardingsphere/driver/jdbc/adapter/ResultSetAdapterTest.java index d131f855397fd..b60fb76cde05e 100644 --- a/jdbc/core/src/test/java/org/apache/shardingsphere/driver/jdbc/adapter/ResultSetAdapterTest.java +++ b/jdbc/core/src/test/java/org/apache/shardingsphere/driver/jdbc/adapter/ResultSetAdapterTest.java @@ -19,8 +19,6 @@ import org.apache.shardingsphere.driver.jdbc.core.resultset.ShardingSphereResultSet; import org.apache.shardingsphere.driver.jdbc.core.statement.ShardingSphereStatement; -import org.apache.shardingsphere.infra.binder.segment.table.TablesContext; -import org.apache.shardingsphere.infra.binder.statement.SQLStatementContext; import org.apache.shardingsphere.infra.executor.sql.context.ExecutionContext; import org.apache.shardingsphere.infra.merge.result.MergedResult; import org.junit.jupiter.api.Test; @@ -113,16 +111,7 @@ private ShardingSphereResultSet mockShardingSphereResultSet(final ResultSet resu when(resultSetMetaData.getColumnLabel(1)).thenReturn("col"); when(resultSetMetaData.getColumnCount()).thenReturn(1); when(resultSet.getMetaData()).thenReturn(resultSetMetaData); - return new ShardingSphereResultSet(Collections.singletonList(resultSet), mock(MergedResult.class), mock(ShardingSphereStatement.class, RETURNS_DEEP_STUBS), createExecutionContext()); - } - - private ExecutionContext createExecutionContext() { - ExecutionContext result = mock(ExecutionContext.class); - SQLStatementContext sqlStatementContext = mock(SQLStatementContext.class); - TablesContext tablesContext = mock(TablesContext.class); - when(tablesContext.getTableNames()).thenReturn(Collections.emptyList()); - when(sqlStatementContext.getTablesContext()).thenReturn(tablesContext); - when(result.getSqlStatementContext()).thenReturn(sqlStatementContext); - return result; + return new ShardingSphereResultSet(Collections.singletonList(resultSet), mock(MergedResult.class), mock(ShardingSphereStatement.class, RETURNS_DEEP_STUBS), + true, mock(ExecutionContext.class)); } } diff --git a/jdbc/core/src/test/java/org/apache/shardingsphere/driver/jdbc/adapter/ResultSetGetterAdapterTest.java b/jdbc/core/src/test/java/org/apache/shardingsphere/driver/jdbc/adapter/ResultSetGetterAdapterTest.java index cfc5ce7221f69..36281fd6a55f9 100644 --- a/jdbc/core/src/test/java/org/apache/shardingsphere/driver/jdbc/adapter/ResultSetGetterAdapterTest.java +++ b/jdbc/core/src/test/java/org/apache/shardingsphere/driver/jdbc/adapter/ResultSetGetterAdapterTest.java @@ -439,6 +439,6 @@ private ShardingSphereResultSet mockShardingSphereResultSet(final MergedResult m ResultSet resultSet = mock(ResultSet.class); when(resultSetMetaData.getColumnCount()).thenReturn(1); when(resultSet.getMetaData()).thenReturn(resultSetMetaData); - return new ShardingSphereResultSet(Collections.singletonList(resultSet), mergedResult, mock(Statement.class), mock(ExecutionContext.class)); + return new ShardingSphereResultSet(Collections.singletonList(resultSet), mergedResult, mock(Statement.class), true, mock(ExecutionContext.class)); } } diff --git a/jdbc/core/src/test/java/org/apache/shardingsphere/driver/jdbc/core/resultset/ShardingSphereResultSetTest.java b/jdbc/core/src/test/java/org/apache/shardingsphere/driver/jdbc/core/resultset/ShardingSphereResultSetTest.java index 99f61be481415..c3b715011cdad 100644 --- a/jdbc/core/src/test/java/org/apache/shardingsphere/driver/jdbc/core/resultset/ShardingSphereResultSetTest.java +++ b/jdbc/core/src/test/java/org/apache/shardingsphere/driver/jdbc/core/resultset/ShardingSphereResultSetTest.java @@ -70,7 +70,7 @@ public final class ShardingSphereResultSetTest { @BeforeEach public void setUp() throws SQLException { mergeResultSet = mock(MergedResult.class); - shardingSphereResultSet = new ShardingSphereResultSet(getResultSets(), mergeResultSet, getShardingSphereStatement(), createExecutionContext()); + shardingSphereResultSet = new ShardingSphereResultSet(getResultSets(), mergeResultSet, getShardingSphereStatement(), true, createExecutionContext()); } private ExecutionContext createExecutionContext() { diff --git a/jdbc/core/src/test/java/org/apache/shardingsphere/driver/jdbc/unsupported/UnsupportedOperationResultSetTest.java b/jdbc/core/src/test/java/org/apache/shardingsphere/driver/jdbc/unsupported/UnsupportedOperationResultSetTest.java index 44ba8965171e5..bbc82b8da84af 100644 --- a/jdbc/core/src/test/java/org/apache/shardingsphere/driver/jdbc/unsupported/UnsupportedOperationResultSetTest.java +++ b/jdbc/core/src/test/java/org/apache/shardingsphere/driver/jdbc/unsupported/UnsupportedOperationResultSetTest.java @@ -40,7 +40,7 @@ public final class UnsupportedOperationResultSetTest { @BeforeEach public void init() throws SQLException { shardingSphereResultSet = new ShardingSphereResultSet( - Collections.singletonList(mock(ResultSet.class, RETURNS_DEEP_STUBS)), mock(MergedResult.class), mock(Statement.class), mock(ExecutionContext.class)); + Collections.singletonList(mock(ResultSet.class, RETURNS_DEEP_STUBS)), mock(MergedResult.class), mock(Statement.class), true, mock(ExecutionContext.class)); } @Test diff --git a/jdbc/core/src/test/java/org/apache/shardingsphere/driver/jdbc/unsupported/UnsupportedUpdateOperationResultSetTest.java b/jdbc/core/src/test/java/org/apache/shardingsphere/driver/jdbc/unsupported/UnsupportedUpdateOperationResultSetTest.java index b9269a7b4d3fb..0c94850251b28 100644 --- a/jdbc/core/src/test/java/org/apache/shardingsphere/driver/jdbc/unsupported/UnsupportedUpdateOperationResultSetTest.java +++ b/jdbc/core/src/test/java/org/apache/shardingsphere/driver/jdbc/unsupported/UnsupportedUpdateOperationResultSetTest.java @@ -48,7 +48,7 @@ public final class UnsupportedUpdateOperationResultSetTest { @BeforeEach public void init() throws SQLException { shardingSphereResultSet = new ShardingSphereResultSet( - Collections.singletonList(mock(ResultSet.class, RETURNS_DEEP_STUBS)), mock(MergedResult.class), mock(Statement.class), mock(ExecutionContext.class)); + Collections.singletonList(mock(ResultSet.class, RETURNS_DEEP_STUBS)), mock(MergedResult.class), mock(Statement.class), true, mock(ExecutionContext.class)); } @Test diff --git a/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/connector/DatabaseConnector.java b/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/connector/DatabaseConnector.java index a261fac31aa68..f74dcb4ec2035 100644 --- a/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/connector/DatabaseConnector.java +++ b/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/connector/DatabaseConnector.java @@ -111,6 +111,8 @@ public final class DatabaseConnector implements DatabaseBackendHandler { private final ShardingSphereDatabase database; + private final boolean transparentStatement; + private final QueryContext queryContext; private final BackendConnection backendConnection; @@ -126,6 +128,7 @@ public DatabaseConnector(final String driverType, final ShardingSphereDatabase d failedIfBackendNotReady(backendConnection.getConnectionSession(), sqlStatementContext); this.driverType = driverType; this.database = database; + this.transparentStatement = isTransparentStatement(sqlStatementContext); this.queryContext = queryContext; this.backendConnection = backendConnection; if (sqlStatementContext instanceof CursorAvailable) { @@ -143,6 +146,31 @@ private void failedIfBackendNotReady(final ConnectionSession connectionSession, } } + private boolean isTransparentStatement(final SQLStatementContext sqlStatementContext) { + Optional dataNodeContainedRule = getDataNodeContainedRuleForShardingRule(database.getRuleMetaData().findRules(DataNodeContainedRule.class)); + Collection columnContainedRules = database.getRuleMetaData().findRules(ColumnContainedRule.class); + for (String each : sqlStatementContext.getTablesContext().getTableNames()) { + return (!dataNodeContainedRule.isPresent() || !dataNodeContainedRule.get().getAllTables().contains(each)) && !containsInColumnContainedRule(each, columnContainedRules); + } + return true; + } + + private Optional getDataNodeContainedRuleForShardingRule(final Collection dataNodeContainedRules) { + for (DataNodeContainedRule each : dataNodeContainedRules) { + if (!(each instanceof MutableDataNodeRule)) { + return Optional.of(each); + } + } + return Optional.empty(); + } + + private boolean containsInColumnContainedRule(final String tableName, final Collection columnContainedRules) { + for (ColumnContainedRule each : columnContainedRules) { + return each.getTables().contains(tableName); + } + return false; + } + /** * Add statement. * @@ -327,7 +355,7 @@ private List createQueryHeaders(final ExecutionContext executionCon } private int getColumnCount(final ExecutionContext executionContext, final QueryResult queryResultSample) throws SQLException { - if (isAllSingleTable(executionContext.getSqlStatementContext())) { + if (transparentStatement) { return queryResultSample.getMetaData().getColumnCount(); } return hasSelectExpandProjections(executionContext.getSqlStatementContext()) @@ -335,27 +363,13 @@ private int getColumnCount(final ExecutionContext executionContext, final QueryR : queryResultSample.getMetaData().getColumnCount(); } - private boolean isAllSingleTable(final SQLStatementContext sqlStatementContext) { - return sqlStatementContext.getTablesContext().getTableNames().stream().allMatch(each -> !containsInImmutableDataNodeContainedRule(each) - && !containsInColumnContainedRule(each)); - } - - private boolean containsInImmutableDataNodeContainedRule(final String tableName) { - return database.getRuleMetaData().findRules(DataNodeContainedRule.class).stream() - .filter(each -> !(each instanceof MutableDataNodeRule)).anyMatch(each -> each.getAllTables().contains(tableName)); - } - - private boolean containsInColumnContainedRule(final String tableName) { - return database.getRuleMetaData().findRules(ColumnContainedRule.class).stream().anyMatch(each -> each.getTables().contains(tableName)); - } - private boolean hasSelectExpandProjections(final SQLStatementContext sqlStatementContext) { return sqlStatementContext instanceof SelectStatementContext && !((SelectStatementContext) sqlStatementContext).getProjectionsContext().getExpandProjections().isEmpty(); } private QueryHeader createQueryHeader(final QueryHeaderBuilderEngine queryHeaderBuilderEngine, final ExecutionContext executionContext, final QueryResult queryResultSample, final ShardingSphereDatabase database, final int columnIndex) throws SQLException { - if (isAllSingleTable(executionContext.getSqlStatementContext())) { + if (transparentStatement) { return queryHeaderBuilderEngine.build(queryResultSample.getMetaData(), database, columnIndex); } return hasSelectExpandProjections(executionContext.getSqlStatementContext())