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

Reply via email to