This is an automated email from the ASF dual-hosted git repository.
panjuan 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 18d7817214a Transparently pass SQL to database when configure data
source in system database (#24646)
18d7817214a is described below
commit 18d7817214aa181dc7311d4aac9245687a485372
Author: Zhengqiang Duan <[email protected]>
AuthorDate: Thu Mar 16 15:34:45 2023 +0800
Transparently pass SQL to database when configure data source in system
database (#24646)
* Transparently pass SQL to database when configure data source in system
database
* fix unit test
* fix unit test
---
.../decider/engine/SQLFederationDeciderEngine.java | 2 +-
.../metadata/database/ShardingSphereDatabase.java | 9 ++++-----
.../schema/loader/common/SchemaMetaDataLoader.java | 6 +++++-
.../loader/common/SchemaMetaDataLoaderTest.java | 2 +-
.../infra/context/kernel/KernelProcessor.java | 4 ++--
.../datanode/SingleTableDataNodeLoaderTest.java | 6 +++++-
.../shardingsphere/single/rule/SingleRuleTest.java | 6 +++++-
.../handler/admin/MySQLAdminExecutorCreator.java | 23 +++++++---------------
.../executor/MySQLAdminExecutorCreatorTest.java | 7 +++++--
9 files changed, 35 insertions(+), 30 deletions(-)
diff --git
a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/decider/engine/SQLFederationDeciderEngine.java
b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/decider/engine/SQLFederationDeciderEngine.java
index b3248a62646..28325561d99 100644
---
a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/decider/engine/SQLFederationDeciderEngine.java
+++
b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/decider/engine/SQLFederationDeciderEngine.java
@@ -61,7 +61,7 @@ public final class SQLFederationDeciderEngine {
public SQLFederationDeciderContext decide(final QueryContext queryContext,
final ShardingSphereRuleMetaData globalRuleMetaData, final
ShardingSphereDatabase database) {
SQLFederationDeciderContext result = new SQLFederationDeciderContext();
SQLStatementContext<?> sqlStatementContext =
queryContext.getSqlStatementContext();
- // TODO move this logic to SQLFederationDecider implement class when
we remove sqlFederationEnabled
+ // TODO move this logic to SQLFederationDecider implement class when
we remove sql federation type
if (isSelectStatementContainsSystemSchema(sqlStatementContext,
database)) {
result.setUseSQLFederation(true);
return result;
diff --git
a/infra/common/src/main/java/org/apache/shardingsphere/infra/metadata/database/ShardingSphereDatabase.java
b/infra/common/src/main/java/org/apache/shardingsphere/infra/metadata/database/ShardingSphereDatabase.java
index 1d1977bdcfe..9cd34c143d6 100644
---
a/infra/common/src/main/java/org/apache/shardingsphere/infra/metadata/database/ShardingSphereDatabase.java
+++
b/infra/common/src/main/java/org/apache/shardingsphere/infra/metadata/database/ShardingSphereDatabase.java
@@ -85,11 +85,10 @@ public final class ShardingSphereDatabase {
public static ShardingSphereDatabase create(final String name, final
DatabaseType protocolType, final Map<String, DatabaseType> storageTypes,
final DatabaseConfiguration
databaseConfig, final ConfigurationProperties props, final InstanceContext
instanceContext) throws SQLException {
Collection<ShardingSphereRule> databaseRules =
DatabaseRulesBuilder.build(name, databaseConfig, instanceContext);
- Map<String, ShardingSphereSchema> schemas = new ConcurrentHashMap<>();
- schemas.putAll(GenericSchemaBuilder.build(new
GenericSchemaBuilderMaterial(protocolType, storageTypes,
-
DataSourceStateManager.getInstance().getEnabledDataSourceMap(name,
databaseConfig.getDataSources()), databaseRules, props,
- DatabaseTypeEngine.getDefaultSchemaName(protocolType, name))));
- schemas.putAll(SystemSchemaBuilder.build(name, protocolType));
+ Map<String, ShardingSphereSchema> schemas = new
ConcurrentHashMap<>(GenericSchemaBuilder
+ .build(new GenericSchemaBuilderMaterial(protocolType,
storageTypes,
DataSourceStateManager.getInstance().getEnabledDataSourceMap(name,
databaseConfig.getDataSources()), databaseRules,
+ props,
DatabaseTypeEngine.getDefaultSchemaName(protocolType, name))));
+ SystemSchemaBuilder.build(name,
protocolType).forEach(schemas::putIfAbsent);
return create(name, protocolType, databaseConfig, databaseRules,
schemas);
}
diff --git
a/infra/common/src/main/java/org/apache/shardingsphere/infra/metadata/database/schema/loader/common/SchemaMetaDataLoader.java
b/infra/common/src/main/java/org/apache/shardingsphere/infra/metadata/database/schema/loader/common/SchemaMetaDataLoader.java
index f1be915f889..2e53645c9c0 100644
---
a/infra/common/src/main/java/org/apache/shardingsphere/infra/metadata/database/schema/loader/common/SchemaMetaDataLoader.java
+++
b/infra/common/src/main/java/org/apache/shardingsphere/infra/metadata/database/schema/loader/common/SchemaMetaDataLoader.java
@@ -44,6 +44,10 @@ public final class SchemaMetaDataLoader {
private static final String VIEW_TYPE = "VIEW";
+ private static final String SYSTEM_TABLE_TYPE = "SYSTEM TABLE";
+
+ private static final String SYSTEM_VIEW_TYPE = "SYSTEM VIEW";
+
private static final String TABLE_NAME = "TABLE_NAME";
private static final String TABLE_SCHEME = "TABLE_SCHEM";
@@ -95,7 +99,7 @@ public final class SchemaMetaDataLoader {
private static Collection<String> loadTableNames(final Connection
connection, final String schemaName) throws SQLException {
Collection<String> result = new LinkedList<>();
- try (ResultSet resultSet =
connection.getMetaData().getTables(connection.getCatalog(), schemaName, null,
new String[]{TABLE_TYPE, VIEW_TYPE})) {
+ try (ResultSet resultSet =
connection.getMetaData().getTables(connection.getCatalog(), schemaName, null,
new String[]{TABLE_TYPE, VIEW_TYPE, SYSTEM_TABLE_TYPE, SYSTEM_VIEW_TYPE})) {
while (resultSet.next()) {
String table = resultSet.getString(TABLE_NAME);
if (!isSystemTable(table)) {
diff --git
a/infra/common/src/test/java/org/apache/shardingsphere/infra/metadata/database/schema/loader/common/SchemaMetaDataLoaderTest.java
b/infra/common/src/test/java/org/apache/shardingsphere/infra/metadata/database/schema/loader/common/SchemaMetaDataLoaderTest.java
index 5e53e67e31c..93ffd337f6a 100644
---
a/infra/common/src/test/java/org/apache/shardingsphere/infra/metadata/database/schema/loader/common/SchemaMetaDataLoaderTest.java
+++
b/infra/common/src/test/java/org/apache/shardingsphere/infra/metadata/database/schema/loader/common/SchemaMetaDataLoaderTest.java
@@ -54,7 +54,7 @@ public final class SchemaMetaDataLoaderTest {
@BeforeEach
public void setUp() throws SQLException {
ResultSet tableResultSet = mockTableResultSet();
- when(dataSource.getConnection().getMetaData().getTables("catalog",
"public", null, new String[]{"TABLE", "VIEW"})).thenReturn(tableResultSet);
+ when(dataSource.getConnection().getMetaData().getTables("catalog",
"public", null, new String[]{"TABLE", "VIEW", "SYSTEM TABLE", "SYSTEM
VIEW"})).thenReturn(tableResultSet);
when(dataSource.getConnection().getCatalog()).thenReturn("catalog");
when(dataSource.getConnection().getSchema()).thenReturn("public");
ResultSet schemaResultSet = mockSchemaResultSet();
diff --git
a/infra/context/src/main/java/org/apache/shardingsphere/infra/context/kernel/KernelProcessor.java
b/infra/context/src/main/java/org/apache/shardingsphere/infra/context/kernel/KernelProcessor.java
index 4b0d918f111..a1448ff69c9 100644
---
a/infra/context/src/main/java/org/apache/shardingsphere/infra/context/kernel/KernelProcessor.java
+++
b/infra/context/src/main/java/org/apache/shardingsphere/infra/context/kernel/KernelProcessor.java
@@ -51,7 +51,7 @@ public final class KernelProcessor {
RouteContext routeContext = route(queryContext, database,
globalRuleMetaData, props, connectionContext);
SQLRewriteResult rewriteResult = rewrite(queryContext, database,
globalRuleMetaData, props, routeContext, connectionContext);
ExecutionContext result = createExecutionContext(queryContext,
database, routeContext, rewriteResult);
- logSQL(queryContext, globalRuleMetaData, props, result);
+ logSQL(queryContext, props, result);
return result;
}
@@ -70,7 +70,7 @@ public final class KernelProcessor {
return new ExecutionContext(queryContext,
ExecutionContextBuilder.build(database, rewriteResult,
queryContext.getSqlStatementContext()), routeContext);
}
- private void logSQL(final QueryContext queryContext, final
ShardingSphereRuleMetaData globalRuleMetaData, final ConfigurationProperties
props, final ExecutionContext executionContext) {
+ private void logSQL(final QueryContext queryContext, final
ConfigurationProperties props, final ExecutionContext executionContext) {
if (props.<Boolean>getValue(ConfigurationPropertyKey.SQL_SHOW)) {
SQLLogger.logSQL(queryContext,
props.<Boolean>getValue(ConfigurationPropertyKey.SQL_SIMPLE), executionContext);
}
diff --git
a/kernel/single/core/src/test/java/org/apache/shardingsphere/single/datanode/SingleTableDataNodeLoaderTest.java
b/kernel/single/core/src/test/java/org/apache/shardingsphere/single/datanode/SingleTableDataNodeLoaderTest.java
index f298565517f..eb724f759c1 100644
---
a/kernel/single/core/src/test/java/org/apache/shardingsphere/single/datanode/SingleTableDataNodeLoaderTest.java
+++
b/kernel/single/core/src/test/java/org/apache/shardingsphere/single/datanode/SingleTableDataNodeLoaderTest.java
@@ -50,6 +50,10 @@ public final class SingleTableDataNodeLoaderTest {
private static final String VIEW_TYPE = "VIEW";
+ private static final String SYSTEM_TABLE_TYPE = "SYSTEM TABLE";
+
+ private static final String SYSTEM_VIEW_TYPE = "SYSTEM VIEW";
+
private static final String TABLE_NAME = "TABLE_NAME";
private Map<String, DataSource> dataSourceMap;
@@ -65,7 +69,7 @@ public final class SingleTableDataNodeLoaderTest {
Connection connection = mock(Connection.class, RETURNS_DEEP_STUBS);
when(connection.getCatalog()).thenReturn(dataSourceName);
ResultSet resultSet = mockResultSet(tableNames);
- when(connection.getMetaData().getTables(dataSourceName, null, null,
new String[]{TABLE_TYPE, VIEW_TYPE})).thenReturn(resultSet);
+ when(connection.getMetaData().getTables(dataSourceName, null, null,
new String[]{TABLE_TYPE, VIEW_TYPE, SYSTEM_TABLE_TYPE,
SYSTEM_VIEW_TYPE})).thenReturn(resultSet);
return new MockedDataSource(connection);
}
diff --git
a/kernel/single/core/src/test/java/org/apache/shardingsphere/single/rule/SingleRuleTest.java
b/kernel/single/core/src/test/java/org/apache/shardingsphere/single/rule/SingleRuleTest.java
index 2314075ecf9..65c57317ae9 100644
---
a/kernel/single/core/src/test/java/org/apache/shardingsphere/single/rule/SingleRuleTest.java
+++
b/kernel/single/core/src/test/java/org/apache/shardingsphere/single/rule/SingleRuleTest.java
@@ -56,6 +56,10 @@ public final class SingleRuleTest {
private static final String VIEW_TYPE = "VIEW";
+ private static final String SYSTEM_TABLE_TYPE = "SYSTEM TABLE";
+
+ private static final String SYSTEM_VIEW_TYPE = "SYSTEM VIEW";
+
private static final String TABLE_NAME = "TABLE_NAME";
private Map<String, DataSource> dataSourceMap;
@@ -73,7 +77,7 @@ public final class SingleRuleTest {
when(connection.getMetaData().getURL()).thenReturn(String.format("jdbc:h2:mem:%s",
dataSourceName));
DataSource result = new MockedDataSource(connection);
ResultSet resultSet = mockResultSet(tableNames);
- when(result.getConnection().getMetaData().getTables(dataSourceName,
null, null, new String[]{TABLE_TYPE, VIEW_TYPE})).thenReturn(resultSet);
+ when(result.getConnection().getMetaData().getTables(dataSourceName,
null, null, new String[]{TABLE_TYPE, VIEW_TYPE, SYSTEM_TABLE_TYPE,
SYSTEM_VIEW_TYPE})).thenReturn(resultSet);
return result;
}
diff --git
a/proxy/backend/type/mysql/src/main/java/org/apache/shardingsphere/proxy/backend/mysql/handler/admin/MySQLAdminExecutorCreator.java
b/proxy/backend/type/mysql/src/main/java/org/apache/shardingsphere/proxy/backend/mysql/handler/admin/MySQLAdminExecutorCreator.java
index d8eb14e1f17..005325e9e90 100644
---
a/proxy/backend/type/mysql/src/main/java/org/apache/shardingsphere/proxy/backend/mysql/handler/admin/MySQLAdminExecutorCreator.java
+++
b/proxy/backend/type/mysql/src/main/java/org/apache/shardingsphere/proxy/backend/mysql/handler/admin/MySQLAdminExecutorCreator.java
@@ -38,8 +38,6 @@ import
org.apache.shardingsphere.proxy.backend.mysql.handler.admin.executor.Unic
import
org.apache.shardingsphere.proxy.backend.mysql.handler.admin.executor.UseDatabaseExecutor;
import
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.item.ExpressionProjectionSegment;
import
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.item.ProjectionSegment;
-import
org.apache.shardingsphere.sql.parser.sql.common.segment.generic.table.SimpleTableSegment;
-import
org.apache.shardingsphere.sql.parser.sql.common.segment.generic.table.TableSegment;
import org.apache.shardingsphere.sql.parser.sql.common.statement.SQLStatement;
import
org.apache.shardingsphere.sql.parser.sql.common.statement.dal.SetStatement;
import
org.apache.shardingsphere.sql.parser.sql.common.statement.dal.UseStatement;
@@ -106,10 +104,10 @@ public final class MySQLAdminExecutorCreator implements
DatabaseAdminExecutorCre
if (null == selectStatement.getFrom()) {
return getSelectFunctionOrVariableExecutor(selectStatement,
sql, databaseName);
}
- if (isQueryInformationSchema(selectStatement)) {
+ if (isQueryInformationSchema(databaseName)) {
return
MySQLInformationSchemaExecutorFactory.newInstance(selectStatement, sql);
}
- if (isQueryPerformanceSchema(selectStatement)) {
+ if (isQueryPerformanceSchema(databaseName)) {
// TODO
return Optional.empty();
}
@@ -148,20 +146,13 @@ public final class MySQLAdminExecutorCreator implements
DatabaseAdminExecutorCre
&&
functionName.equalsIgnoreCase(((ExpressionProjectionSegment)
firstProjection).getText());
}
- private boolean isQueryInformationSchema(final SelectStatement
sqlStatement) {
- return isQuerySpecialSchema(sqlStatement, INFORMATION_SCHEMA);
+ private boolean isQueryInformationSchema(final String databaseName) {
+ // TODO remove DefaultDatabaseMetaDataExecutor when sql federation can
support all system table query
+ return INFORMATION_SCHEMA.equalsIgnoreCase(databaseName) &&
!ProxyContext.getInstance().getDatabase(databaseName).isComplete();
}
- private boolean isQueryPerformanceSchema(final SelectStatement
sqlStatement) {
- return isQuerySpecialSchema(sqlStatement, PERFORMANCE_SCHEMA);
- }
-
- private boolean isQuerySpecialSchema(final SelectStatement sqlStatement,
final String specialSchemaName) {
- TableSegment tableSegment = sqlStatement.getFrom();
- if (!(tableSegment instanceof SimpleTableSegment)) {
- return false;
- }
- return ((SimpleTableSegment) tableSegment).getOwner().isPresent() &&
specialSchemaName.equalsIgnoreCase(((SimpleTableSegment)
tableSegment).getOwner().get().getIdentifier().getValue());
+ private boolean isQueryPerformanceSchema(final String databaseName) {
+ return PERFORMANCE_SCHEMA.equalsIgnoreCase(databaseName);
}
private Optional<DatabaseAdminExecutor> mockExecutor(final String
databaseName, final SelectStatement sqlStatement, final String sql) {
diff --git
a/proxy/backend/type/mysql/src/test/java/org/apache/shardingsphere/proxy/backend/mysql/handler/admin/executor/MySQLAdminExecutorCreatorTest.java
b/proxy/backend/type/mysql/src/test/java/org/apache/shardingsphere/proxy/backend/mysql/handler/admin/executor/MySQLAdminExecutorCreatorTest.java
index 391f2d67d79..c62fe79ec97 100644
---
a/proxy/backend/type/mysql/src/test/java/org/apache/shardingsphere/proxy/backend/mysql/handler/admin/executor/MySQLAdminExecutorCreatorTest.java
+++
b/proxy/backend/type/mysql/src/test/java/org/apache/shardingsphere/proxy/backend/mysql/handler/admin/executor/MySQLAdminExecutorCreatorTest.java
@@ -287,7 +287,7 @@ public final class MySQLAdminExecutorCreatorTest {
MySQLSelectStatement mySQLSelectStatement =
mock(MySQLSelectStatement.class);
when(mySQLSelectStatement.getFrom()).thenReturn(tableSegment);
when(sqlStatementContext.getSqlStatement()).thenReturn(mySQLSelectStatement);
- Optional<DatabaseAdminExecutor> actual = new
MySQLAdminExecutorCreator().create(sqlStatementContext, "select ENGINE from
ENGINES", "");
+ Optional<DatabaseAdminExecutor> actual = new
MySQLAdminExecutorCreator().create(sqlStatementContext, "select ENGINE from
ENGINES", "information_schema");
assertTrue(actual.isPresent());
assertThat(actual.get(),
instanceOf(DefaultDatabaseMetaDataExecutor.class));
}
@@ -300,9 +300,12 @@ public final class MySQLAdminExecutorCreatorTest {
MySQLSelectStatement mySQLSelectStatement =
mock(MySQLSelectStatement.class);
when(mySQLSelectStatement.getFrom()).thenReturn(tableSegment);
when(sqlStatementContext.getSqlStatement()).thenReturn(mySQLSelectStatement);
- Optional<DatabaseAdminExecutor> actual = new
MySQLAdminExecutorCreator().create(sqlStatementContext, "select SCHEMA_NAME
from SCHEMATA", "");
+ Optional<DatabaseAdminExecutor> actual = new
MySQLAdminExecutorCreator().create(sqlStatementContext, "select SCHEMA_NAME
from SCHEMATA", "information_schema");
assertTrue(actual.isPresent());
assertThat(actual.get(),
instanceOf(SelectInformationSchemataExecutor.class));
+
when(ProxyContext.getInstance().getDatabase("information_schema").isComplete()).thenReturn(true);
+ actual = new MySQLAdminExecutorCreator().create(sqlStatementContext,
"select SCHEMA_NAME from SCHEMATA", "information_schema");
+ assertFalse(actual.isPresent());
}
@Test