You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@shardingsphere.apache.org by du...@apache.org on 2022/07/28 07:49:38 UTC

[shardingsphere] branch master updated: Refactor MySQLAdminExecutorCreator (#19638)

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

duanzhengqiang 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 903e9007128 Refactor MySQLAdminExecutorCreator (#19638)
903e9007128 is described below

commit 903e9007128b59ddb4c963c670914089ec508fdc
Author: 吴伟杰 <wu...@apache.org>
AuthorDate: Thu Jul 28 15:49:32 2022 +0800

    Refactor MySQLAdminExecutorCreator (#19638)
    
    * Refactor MySQLAdminExecutorCreator
    
    * Add MySQLAdminExecutorCreatorTest
---
 .../admin/mysql/MySQLAdminExecutorCreator.java     |  83 +++++++++--------
 .../admin/mysql/MySQLAdminExecutorCreatorTest.java | 100 +++++++++++++++++++++
 2 files changed, 147 insertions(+), 36 deletions(-)

diff --git a/shardingsphere-proxy/shardingsphere-proxy-backend/src/main/java/org/apache/shardingsphere/proxy/backend/text/admin/mysql/MySQLAdminExecutorCreator.java b/shardingsphere-proxy/shardingsphere-proxy-backend/src/main/java/org/apache/shardingsphere/proxy/backend/text/admin/mysql/MySQLAdminExecutorCreator.java
index a4311987a3e..d96885d3554 100644
--- a/shardingsphere-proxy/shardingsphere-proxy-backend/src/main/java/org/apache/shardingsphere/proxy/backend/text/admin/mysql/MySQLAdminExecutorCreator.java
+++ b/shardingsphere-proxy/shardingsphere-proxy-backend/src/main/java/org/apache/shardingsphere/proxy/backend/text/admin/mysql/MySQLAdminExecutorCreator.java
@@ -51,6 +51,7 @@ import org.apache.shardingsphere.sql.parser.sql.dialect.statement.mysql.dal.MySQ
 import org.apache.shardingsphere.sql.parser.sql.dialect.statement.mysql.dal.MySQLShowProcessListStatement;
 import org.apache.shardingsphere.sql.parser.sql.dialect.statement.mysql.dal.MySQLShowTablesStatement;
 
+import java.util.Collection;
 import java.util.Optional;
 
 /**
@@ -96,37 +97,45 @@ public final class MySQLAdminExecutorCreator implements DatabaseAdminExecutorCre
             return Optional.of(new MySQLSetVariableAdminExecutor((SetStatement) sqlStatement));
         }
         if (sqlStatement instanceof SelectStatement) {
-            if (isShowSpecialFunction((SelectStatement) sqlStatement, ShowConnectionIdExecutor.FUNCTION_NAME)) {
-                return Optional.of(new ShowConnectionIdExecutor((SelectStatement) sqlStatement));
+            SelectStatement selectStatement = (SelectStatement) sqlStatement;
+            if (null == selectStatement.getFrom()) {
+                return getSelectFunctionOrVariableExecutor(selectStatement, sql, databaseName);
             }
-            if (isShowSpecialFunction((SelectStatement) sqlStatement, ShowVersionExecutor.FUNCTION_NAME)) {
-                return Optional.of(new ShowVersionExecutor((SelectStatement) sqlStatement));
+            if (isQueryInformationSchema(selectStatement)) {
+                return MySQLInformationSchemaExecutorFactory.newInstance(selectStatement, sql);
             }
-            if (isShowSpecialFunction((SelectStatement) sqlStatement, ShowCurrentUserExecutor.FUNCTION_NAME)
-                    || isShowSpecialFunction((SelectStatement) sqlStatement, ShowCurrentUserExecutor.FUNCTION_NAME_ALIAS)) {
-                return Optional.of(new ShowCurrentUserExecutor());
-            }
-            if ((!hasDatabases() || !hasResources()) && isShowSpecialFunction((SelectStatement) sqlStatement, ShowTransactionExecutor.TRANSACTION_READ_ONLY)) {
-                return Optional.of(new ShowTransactionExecutor(ShowTransactionExecutor.TRANSACTION_READ_ONLY));
-            }
-            if ((!hasDatabases() || !hasResources()) && isShowSpecialFunction((SelectStatement) sqlStatement, ShowTransactionExecutor.TRANSACTION_ISOLATION)) {
-                return Optional.of(new ShowTransactionExecutor(ShowTransactionExecutor.TRANSACTION_ISOLATION));
-            }
-            if (isShowSpecialFunction((SelectStatement) sqlStatement, ShowCurrentDatabaseExecutor.FUNCTION_NAME)) {
-                return Optional.of(new ShowCurrentDatabaseExecutor());
-            }
-            if (isQueryInformationSchema((SelectStatement) sqlStatement)) {
-                return MySQLInformationSchemaExecutorFactory.newInstance((SelectStatement) sqlStatement, sql);
-            }
-            if (isQueryPerformanceSchema((SelectStatement) sqlStatement)) {
+            if (isQueryPerformanceSchema(selectStatement)) {
                 // TODO
                 return Optional.empty();
             }
-            return Optional.ofNullable(mockExecutor(databaseName, (SelectStatement) sqlStatement, sql));
         }
         return Optional.empty();
     }
     
+    private Optional<DatabaseAdminExecutor> getSelectFunctionOrVariableExecutor(final SelectStatement selectStatement, final String sql, final String databaseName) {
+        if (isShowSpecialFunction(selectStatement, ShowConnectionIdExecutor.FUNCTION_NAME)) {
+            return Optional.of(new ShowConnectionIdExecutor(selectStatement));
+        }
+        if (isShowSpecialFunction(selectStatement, ShowVersionExecutor.FUNCTION_NAME)) {
+            return Optional.of(new ShowVersionExecutor(selectStatement));
+        }
+        if (isShowSpecialFunction(selectStatement, ShowCurrentUserExecutor.FUNCTION_NAME)
+                || isShowSpecialFunction(selectStatement, ShowCurrentUserExecutor.FUNCTION_NAME_ALIAS)) {
+            return Optional.of(new ShowCurrentUserExecutor());
+        }
+        boolean hasNoResource = hasNoResource();
+        if (hasNoResource && isShowSpecialFunction(selectStatement, ShowTransactionExecutor.TRANSACTION_READ_ONLY)) {
+            return Optional.of(new ShowTransactionExecutor(ShowTransactionExecutor.TRANSACTION_READ_ONLY));
+        }
+        if (hasNoResource && isShowSpecialFunction(selectStatement, ShowTransactionExecutor.TRANSACTION_ISOLATION)) {
+            return Optional.of(new ShowTransactionExecutor(ShowTransactionExecutor.TRANSACTION_ISOLATION));
+        }
+        if (isShowSpecialFunction(selectStatement, ShowCurrentDatabaseExecutor.FUNCTION_NAME)) {
+            return Optional.of(new ShowCurrentDatabaseExecutor());
+        }
+        return mockExecutor(databaseName, selectStatement, sql);
+    }
+    
     private boolean isShowSpecialFunction(final SelectStatement sqlStatement, final String functionName) {
         ProjectionSegment firstProjection = sqlStatement.getProjections().getProjections().iterator().next();
         return firstProjection instanceof ExpressionProjectionSegment && functionName.equalsIgnoreCase(((ExpressionProjectionSegment) firstProjection).getText());
@@ -148,24 +157,26 @@ public final class MySQLAdminExecutorCreator implements DatabaseAdminExecutorCre
         return ((SimpleTableSegment) tableSegment).getOwner().isPresent() && specialSchemaName.equalsIgnoreCase(((SimpleTableSegment) tableSegment).getOwner().get().getIdentifier().getValue());
     }
     
-    private DatabaseAdminExecutor mockExecutor(final String databaseName, final SelectStatement sqlStatement, final String sql) {
-        boolean isNotUseSchema = !Optional.ofNullable(databaseName).isPresent() && sqlStatement.getFrom() == null;
-        if (!hasDatabases() || !hasResources()) {
-            return new NoResourceShowExecutor(sqlStatement);
+    private Optional<DatabaseAdminExecutor> mockExecutor(final String databaseName, final SelectStatement sqlStatement, final String sql) {
+        boolean isNotUseSchema = null == databaseName && null == sqlStatement.getFrom();
+        if (hasNoResource()) {
+            return Optional.of(new NoResourceShowExecutor(sqlStatement));
         }
         String driverType = ProxyContext.getInstance().getContextManager().getMetaDataContexts().getMetaData().getProps().getValue(ConfigurationPropertyKey.PROXY_BACKEND_DRIVER_TYPE);
-        if (isNotUseSchema) {
-            return "ExperimentalVertx".equals(driverType) ? null : new UnicastResourceShowExecutor(sqlStatement, sql);
-        }
-        return null;
+        return isNotUseSchema && !"ExperimentalVertx".equals(driverType) ? Optional.of(new UnicastResourceShowExecutor(sqlStatement, sql)) : Optional.empty();
     }
     
-    private boolean hasDatabases() {
-        return !ProxyContext.getInstance().getAllDatabaseNames().isEmpty();
-    }
-    
-    private boolean hasResources() {
-        return ProxyContext.getInstance().getAllDatabaseNames().stream().anyMatch(each -> ProxyContext.getInstance().getDatabase(each).containsDataSource());
+    private boolean hasNoResource() {
+        Collection<String> databaseNames = ProxyContext.getInstance().getAllDatabaseNames();
+        if (databaseNames.isEmpty()) {
+            return true;
+        }
+        for (String each : databaseNames) {
+            if (ProxyContext.getInstance().getDatabase(each).containsDataSource()) {
+                return false;
+            }
+        }
+        return true;
     }
     
     @Override
diff --git a/shardingsphere-proxy/shardingsphere-proxy-backend/src/test/java/org/apache/shardingsphere/proxy/backend/text/admin/mysql/MySQLAdminExecutorCreatorTest.java b/shardingsphere-proxy/shardingsphere-proxy-backend/src/test/java/org/apache/shardingsphere/proxy/backend/text/admin/mysql/MySQLAdminExecutorCreatorTest.java
new file mode 100644
index 00000000000..acd802210b1
--- /dev/null
+++ b/shardingsphere-proxy/shardingsphere-proxy-backend/src/test/java/org/apache/shardingsphere/proxy/backend/text/admin/mysql/MySQLAdminExecutorCreatorTest.java
@@ -0,0 +1,100 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.proxy.backend.text.admin.mysql;
+
+import org.apache.shardingsphere.infra.binder.statement.SQLStatementContext;
+import org.apache.shardingsphere.proxy.backend.text.admin.executor.DatabaseAdminExecutor;
+import org.apache.shardingsphere.proxy.backend.text.admin.mysql.executor.ShowFunctionStatusExecutor;
+import org.apache.shardingsphere.proxy.backend.text.admin.mysql.executor.ShowProcedureStatusExecutor;
+import org.apache.shardingsphere.proxy.backend.text.admin.mysql.executor.ShowTablesExecutor;
+import org.apache.shardingsphere.proxy.backend.text.admin.mysql.executor.UseDatabaseExecutor;
+import org.apache.shardingsphere.sql.parser.sql.dialect.statement.mysql.dal.MySQLShowFunctionStatusStatement;
+import org.apache.shardingsphere.sql.parser.sql.dialect.statement.mysql.dal.MySQLShowProcedureStatusStatement;
+import org.apache.shardingsphere.sql.parser.sql.dialect.statement.mysql.dal.MySQLShowTablesStatement;
+import org.apache.shardingsphere.sql.parser.sql.dialect.statement.mysql.dal.MySQLUseStatement;
+import org.apache.shardingsphere.sql.parser.sql.dialect.statement.mysql.dml.MySQLDeleteStatement;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.junit.MockitoJUnitRunner;
+
+import java.util.Optional;
+
+import static org.hamcrest.CoreMatchers.instanceOf;
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.when;
+
+// TODO Cover more lines in MySQLAdminExecutorCreator
+@RunWith(MockitoJUnitRunner.class)
+public final class MySQLAdminExecutorCreatorTest {
+    
+    @SuppressWarnings("rawtypes")
+    @Mock
+    private SQLStatementContext sqlStatementContext;
+    
+    @Test
+    public void assertCreateWithMySQLShowFunctionStatus() {
+        when(sqlStatementContext.getSqlStatement()).thenReturn(new MySQLShowFunctionStatusStatement());
+        Optional<DatabaseAdminExecutor> actual = new MySQLAdminExecutorCreator().create(sqlStatementContext);
+        assertTrue(actual.isPresent());
+        assertThat(actual.get(), instanceOf(ShowFunctionStatusExecutor.class));
+    }
+    
+    @Test
+    public void assertCreateWithShowProcedureStatus() {
+        when(sqlStatementContext.getSqlStatement()).thenReturn(new MySQLShowProcedureStatusStatement());
+        Optional<DatabaseAdminExecutor> actual = new MySQLAdminExecutorCreator().create(sqlStatementContext);
+        assertTrue(actual.isPresent());
+        assertThat(actual.get(), instanceOf(ShowProcedureStatusExecutor.class));
+    }
+    
+    @Test
+    public void assertCreateWithShowTables() {
+        when(sqlStatementContext.getSqlStatement()).thenReturn(new MySQLShowTablesStatement());
+        Optional<DatabaseAdminExecutor> actual = new MySQLAdminExecutorCreator().create(sqlStatementContext);
+        assertTrue(actual.isPresent());
+        assertThat(actual.get(), instanceOf(ShowTablesExecutor.class));
+    }
+    
+    @Test
+    public void assertCreateWithOtherSQLStatementContext() {
+        assertThat(new MySQLAdminExecutorCreator().create(sqlStatementContext), is(Optional.empty()));
+    }
+    
+    @Test
+    public void assertCreateWithUse() {
+        when(sqlStatementContext.getSqlStatement()).thenReturn(new MySQLUseStatement());
+        Optional<DatabaseAdminExecutor> actual = new MySQLAdminExecutorCreator().create(sqlStatementContext, "use db", "");
+        assertTrue(actual.isPresent());
+        assertThat(actual.get(), instanceOf(UseDatabaseExecutor.class));
+    }
+    
+    @Test
+    public void assertCreateWithDMLStatement() {
+        when(sqlStatementContext.getSqlStatement()).thenReturn(new MySQLDeleteStatement());
+        Optional<DatabaseAdminExecutor> actual = new MySQLAdminExecutorCreator().create(sqlStatementContext, "delete from t", "");
+        assertThat(actual, is(Optional.empty()));
+    }
+    
+    @Test
+    public void assertGetType() {
+        assertThat(new MySQLAdminExecutorCreator().getType(), is("MySQL"));
+    }
+}