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 d8181cf9b6f Add MySQLSelectAdminExecutorFactory (#36849)
d8181cf9b6f is described below

commit d8181cf9b6ff6b20063042394aad590bfbb504d3
Author: Liang Zhang <[email protected]>
AuthorDate: Sat Oct 11 19:03:59 2025 +0800

    Add MySQLSelectAdminExecutorFactory (#36849)
    
    * Add MySQLSelectAdminExecutorFactory
    
    * Add MySQLSelectAdminExecutorFactory
---
 .../handler/admin/MySQLAdminExecutorCreator.java   |  97 +-------------------
 .../MySQLInformationSchemaExecutorFactory.java     |   2 +-
 .../MySQLMySQLSchemaExecutorFactory.java           |   2 +-
 .../MySQLPerformanceSchemaExecutorFactory.java     |   2 +-
 .../factory/MySQLSelectAdminExecutorFactory.java   |  70 +++++++++++++++
 ...MySQLSelectWithoutFromAdminExecutorFactory.java | 100 +++++++++++++++++++++
 .../MySQLSysSchemaExecutorFactory.java             |   2 +-
 7 files changed, 176 insertions(+), 99 deletions(-)

diff --git 
a/proxy/backend/dialect/mysql/src/main/java/org/apache/shardingsphere/proxy/backend/mysql/handler/admin/MySQLAdminExecutorCreator.java
 
b/proxy/backend/dialect/mysql/src/main/java/org/apache/shardingsphere/proxy/backend/mysql/handler/admin/MySQLAdminExecutorCreator.java
index ff6584798b7..3c9cca998d1 100644
--- 
a/proxy/backend/dialect/mysql/src/main/java/org/apache/shardingsphere/proxy/backend/mysql/handler/admin/MySQLAdminExecutorCreator.java
+++ 
b/proxy/backend/dialect/mysql/src/main/java/org/apache/shardingsphere/proxy/backend/mysql/handler/admin/MySQLAdminExecutorCreator.java
@@ -19,30 +19,20 @@ package 
org.apache.shardingsphere.proxy.backend.mysql.handler.admin;
 
 import 
org.apache.shardingsphere.infra.binder.context.statement.SQLStatementContext;
 import 
org.apache.shardingsphere.infra.binder.context.statement.type.dml.SelectStatementContext;
-import org.apache.shardingsphere.proxy.backend.context.ProxyContext;
 import 
org.apache.shardingsphere.proxy.backend.handler.admin.executor.DatabaseAdminExecutor;
 import 
org.apache.shardingsphere.proxy.backend.handler.admin.executor.DatabaseAdminExecutorCreator;
 import 
org.apache.shardingsphere.proxy.backend.mysql.handler.admin.executor.KillProcessExecutor;
 import 
org.apache.shardingsphere.proxy.backend.mysql.handler.admin.executor.MySQLSetVariableAdminExecutor;
-import 
org.apache.shardingsphere.proxy.backend.mysql.handler.admin.executor.MySQLSystemVariableQueryExecutor;
-import 
org.apache.shardingsphere.proxy.backend.mysql.handler.admin.executor.NoResourceShowExecutor;
-import 
org.apache.shardingsphere.proxy.backend.mysql.handler.admin.executor.ShowConnectionIdExecutor;
 import 
org.apache.shardingsphere.proxy.backend.mysql.handler.admin.executor.ShowCreateDatabaseExecutor;
-import 
org.apache.shardingsphere.proxy.backend.mysql.handler.admin.executor.ShowCurrentDatabaseExecutor;
-import 
org.apache.shardingsphere.proxy.backend.mysql.handler.admin.executor.ShowCurrentUserExecutor;
 import 
org.apache.shardingsphere.proxy.backend.mysql.handler.admin.executor.ShowDatabasesExecutor;
 import 
org.apache.shardingsphere.proxy.backend.mysql.handler.admin.executor.ShowFunctionStatusExecutor;
 import 
org.apache.shardingsphere.proxy.backend.mysql.handler.admin.executor.ShowProcedureStatusExecutor;
 import 
org.apache.shardingsphere.proxy.backend.mysql.handler.admin.executor.ShowProcessListExecutor;
 import 
org.apache.shardingsphere.proxy.backend.mysql.handler.admin.executor.ShowTablesExecutor;
-import 
org.apache.shardingsphere.proxy.backend.mysql.handler.admin.executor.ShowVersionExecutor;
-import 
org.apache.shardingsphere.proxy.backend.mysql.handler.admin.executor.UnicastResourceShowExecutor;
 import 
org.apache.shardingsphere.proxy.backend.mysql.handler.admin.executor.UseDatabaseExecutor;
-import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.item.ExpressionProjectionSegment;
-import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.item.ProjectionSegment;
+import 
org.apache.shardingsphere.proxy.backend.mysql.handler.admin.factory.MySQLSelectAdminExecutorFactory;
 import 
org.apache.shardingsphere.sql.parser.statement.core.statement.SQLStatement;
 import 
org.apache.shardingsphere.sql.parser.statement.core.statement.type.dal.SetStatement;
-import 
org.apache.shardingsphere.sql.parser.statement.core.statement.type.dml.SelectStatement;
 import 
org.apache.shardingsphere.sql.parser.statement.mysql.dal.MySQLKillStatement;
 import 
org.apache.shardingsphere.sql.parser.statement.mysql.dal.MySQLUseStatement;
 import 
org.apache.shardingsphere.sql.parser.statement.mysql.dal.show.database.MySQLShowCreateDatabaseStatement;
@@ -52,8 +42,6 @@ import 
org.apache.shardingsphere.sql.parser.statement.mysql.dal.show.procedure.M
 import 
org.apache.shardingsphere.sql.parser.statement.mysql.dal.show.process.MySQLShowProcessListStatement;
 import 
org.apache.shardingsphere.sql.parser.statement.mysql.dal.show.table.MySQLShowTablesStatement;
 
-import java.util.Collection;
-import java.util.Iterator;
 import java.util.List;
 import java.util.Optional;
 
@@ -62,18 +50,10 @@ import java.util.Optional;
  */
 public final class MySQLAdminExecutorCreator implements 
DatabaseAdminExecutorCreator {
     
-    private static final String INFORMATION_SCHEMA = "information_schema";
-    
-    private static final String MYSQL_SCHEMA = "mysql";
-    
-    private static final String PERFORMANCE_SCHEMA = "performance_schema";
-    
-    private static final String SYS_SCHEMA = "sys";
-    
     @Override
     public Optional<DatabaseAdminExecutor> create(final SQLStatementContext 
sqlStatementContext, final String sql, final String databaseName, final 
List<Object> parameters) {
         if (sqlStatementContext instanceof SelectStatementContext) {
-            return createExecutorForSelectStatement((SelectStatementContext) 
sqlStatementContext, sql, databaseName, parameters);
+            return 
MySQLSelectAdminExecutorFactory.newInstance((SelectStatementContext) 
sqlStatementContext, sql, databaseName, parameters);
         }
         SQLStatement sqlStatement = sqlStatementContext.getSqlStatement();
         if (sqlStatement instanceof MySQLUseStatement) {
@@ -106,79 +86,6 @@ public final class MySQLAdminExecutorCreator implements 
DatabaseAdminExecutorCre
         return Optional.empty();
     }
     
-    private Optional<DatabaseAdminExecutor> 
createExecutorForSelectStatement(final SelectStatementContext 
selectStatementContext, final String sql,
-                                                                             
final String databaseName, final List<Object> parameters) {
-        if (!selectStatementContext.getSqlStatement().getFrom().isPresent()) {
-            return 
findAdminExecutorForSelectWithoutFrom(selectStatementContext.getSqlStatement(), 
sql, databaseName);
-        }
-        if (INFORMATION_SCHEMA.equalsIgnoreCase(databaseName) && 
!ProxyContext.getInstance().getContextManager().getDatabase(databaseName).isComplete())
 {
-            return 
MySQLInformationSchemaExecutorFactory.newInstance(selectStatementContext, sql, 
parameters);
-        }
-        if (PERFORMANCE_SCHEMA.equalsIgnoreCase(databaseName) && 
!ProxyContext.getInstance().getContextManager().getDatabase(databaseName).isComplete())
 {
-            return 
MySQLPerformanceSchemaExecutorFactory.newInstance(selectStatementContext, sql, 
parameters);
-        }
-        if (MYSQL_SCHEMA.equalsIgnoreCase(databaseName) && 
!ProxyContext.getInstance().getContextManager().getDatabase(databaseName).isComplete())
 {
-            return 
MySQLMySQLSchemaExecutorFactory.newInstance(selectStatementContext, sql, 
parameters);
-        }
-        if (SYS_SCHEMA.equalsIgnoreCase(databaseName) && 
!ProxyContext.getInstance().getContextManager().getDatabase(databaseName).isComplete())
 {
-            return 
MySQLSysSchemaExecutorFactory.newInstance(selectStatementContext, sql, 
parameters);
-        }
-        return Optional.empty();
-    }
-    
-    private Optional<DatabaseAdminExecutor> 
findAdminExecutorForSelectWithoutFrom(final SelectStatement selectStatement, 
final String sql, final String databaseName) {
-        Optional<DatabaseAdminExecutor> result = 
MySQLSystemVariableQueryExecutor.tryGetSystemVariableQueryExecutor(selectStatement);
-        return result.isPresent() ? result : 
getSelectFunctionOrVariableExecutor(selectStatement, sql, databaseName);
-    }
-    
-    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());
-        }
-        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) {
-        Iterator<ProjectionSegment> segmentIterator = 
sqlStatement.getProjections().getProjections().iterator();
-        ProjectionSegment firstProjection = segmentIterator.next();
-        if (segmentIterator.hasNext() || !(firstProjection instanceof 
ExpressionProjectionSegment)) {
-            return false;
-        }
-        String projectionText = ((ExpressionProjectionSegment) 
firstProjection).getText();
-        String trimmedText = projectionText.replaceAll("\\s+\\(", "(");
-        return functionName.equalsIgnoreCase(trimmedText);
-    }
-    
-    private Optional<DatabaseAdminExecutor> mockExecutor(final String 
databaseName, final SelectStatement sqlStatement, final String sql) {
-        if (hasNoResource()) {
-            return Optional.of(new NoResourceShowExecutor(sqlStatement));
-        }
-        boolean isUseSchema = null != databaseName || 
sqlStatement.getFrom().isPresent();
-        return isUseSchema ? Optional.empty() : Optional.of(new 
UnicastResourceShowExecutor(sqlStatement, sql));
-    }
-    
-    private boolean hasNoResource() {
-        Collection<String> databaseNames = 
ProxyContext.getInstance().getContextManager().getAllDatabaseNames();
-        if (databaseNames.isEmpty()) {
-            return true;
-        }
-        for (String each : databaseNames) {
-            if 
(ProxyContext.getInstance().getContextManager().getDatabase(each).containsDataSource())
 {
-                return false;
-            }
-        }
-        return true;
-    }
-    
     @Override
     public String getDatabaseType() {
         return "MySQL";
diff --git 
a/proxy/backend/dialect/mysql/src/main/java/org/apache/shardingsphere/proxy/backend/mysql/handler/admin/MySQLInformationSchemaExecutorFactory.java
 
b/proxy/backend/dialect/mysql/src/main/java/org/apache/shardingsphere/proxy/backend/mysql/handler/admin/factory/MySQLInformationSchemaExecutorFactory.java
similarity index 99%
rename from 
proxy/backend/dialect/mysql/src/main/java/org/apache/shardingsphere/proxy/backend/mysql/handler/admin/MySQLInformationSchemaExecutorFactory.java
rename to 
proxy/backend/dialect/mysql/src/main/java/org/apache/shardingsphere/proxy/backend/mysql/handler/admin/factory/MySQLInformationSchemaExecutorFactory.java
index 78817f54f7f..91d5103f369 100644
--- 
a/proxy/backend/dialect/mysql/src/main/java/org/apache/shardingsphere/proxy/backend/mysql/handler/admin/MySQLInformationSchemaExecutorFactory.java
+++ 
b/proxy/backend/dialect/mysql/src/main/java/org/apache/shardingsphere/proxy/backend/mysql/handler/admin/factory/MySQLInformationSchemaExecutorFactory.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-package org.apache.shardingsphere.proxy.backend.mysql.handler.admin;
+package org.apache.shardingsphere.proxy.backend.mysql.handler.admin.factory;
 
 import lombok.AccessLevel;
 import lombok.NoArgsConstructor;
diff --git 
a/proxy/backend/dialect/mysql/src/main/java/org/apache/shardingsphere/proxy/backend/mysql/handler/admin/MySQLMySQLSchemaExecutorFactory.java
 
b/proxy/backend/dialect/mysql/src/main/java/org/apache/shardingsphere/proxy/backend/mysql/handler/admin/factory/MySQLMySQLSchemaExecutorFactory.java
similarity index 99%
rename from 
proxy/backend/dialect/mysql/src/main/java/org/apache/shardingsphere/proxy/backend/mysql/handler/admin/MySQLMySQLSchemaExecutorFactory.java
rename to 
proxy/backend/dialect/mysql/src/main/java/org/apache/shardingsphere/proxy/backend/mysql/handler/admin/factory/MySQLMySQLSchemaExecutorFactory.java
index 1e460c4d4ff..7d1ddfca2f2 100644
--- 
a/proxy/backend/dialect/mysql/src/main/java/org/apache/shardingsphere/proxy/backend/mysql/handler/admin/MySQLMySQLSchemaExecutorFactory.java
+++ 
b/proxy/backend/dialect/mysql/src/main/java/org/apache/shardingsphere/proxy/backend/mysql/handler/admin/factory/MySQLMySQLSchemaExecutorFactory.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-package org.apache.shardingsphere.proxy.backend.mysql.handler.admin;
+package org.apache.shardingsphere.proxy.backend.mysql.handler.admin.factory;
 
 import lombok.AccessLevel;
 import lombok.NoArgsConstructor;
diff --git 
a/proxy/backend/dialect/mysql/src/main/java/org/apache/shardingsphere/proxy/backend/mysql/handler/admin/MySQLPerformanceSchemaExecutorFactory.java
 
b/proxy/backend/dialect/mysql/src/main/java/org/apache/shardingsphere/proxy/backend/mysql/handler/admin/factory/MySQLPerformanceSchemaExecutorFactory.java
similarity index 99%
rename from 
proxy/backend/dialect/mysql/src/main/java/org/apache/shardingsphere/proxy/backend/mysql/handler/admin/MySQLPerformanceSchemaExecutorFactory.java
rename to 
proxy/backend/dialect/mysql/src/main/java/org/apache/shardingsphere/proxy/backend/mysql/handler/admin/factory/MySQLPerformanceSchemaExecutorFactory.java
index fc421c026e3..1079a58d686 100644
--- 
a/proxy/backend/dialect/mysql/src/main/java/org/apache/shardingsphere/proxy/backend/mysql/handler/admin/MySQLPerformanceSchemaExecutorFactory.java
+++ 
b/proxy/backend/dialect/mysql/src/main/java/org/apache/shardingsphere/proxy/backend/mysql/handler/admin/factory/MySQLPerformanceSchemaExecutorFactory.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-package org.apache.shardingsphere.proxy.backend.mysql.handler.admin;
+package org.apache.shardingsphere.proxy.backend.mysql.handler.admin.factory;
 
 import lombok.AccessLevel;
 import lombok.NoArgsConstructor;
diff --git 
a/proxy/backend/dialect/mysql/src/main/java/org/apache/shardingsphere/proxy/backend/mysql/handler/admin/factory/MySQLSelectAdminExecutorFactory.java
 
b/proxy/backend/dialect/mysql/src/main/java/org/apache/shardingsphere/proxy/backend/mysql/handler/admin/factory/MySQLSelectAdminExecutorFactory.java
new file mode 100644
index 00000000000..0576b13fb76
--- /dev/null
+++ 
b/proxy/backend/dialect/mysql/src/main/java/org/apache/shardingsphere/proxy/backend/mysql/handler/admin/factory/MySQLSelectAdminExecutorFactory.java
@@ -0,0 +1,70 @@
+/*
+ * 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.mysql.handler.admin.factory;
+
+import lombok.AccessLevel;
+import lombok.NoArgsConstructor;
+import 
org.apache.shardingsphere.infra.binder.context.statement.type.dml.SelectStatementContext;
+import org.apache.shardingsphere.proxy.backend.context.ProxyContext;
+import 
org.apache.shardingsphere.proxy.backend.handler.admin.executor.DatabaseAdminExecutor;
+
+import java.util.List;
+import java.util.Optional;
+
+/**
+ * Select admin executor factory for MySQL.
+ */
+@NoArgsConstructor(access = AccessLevel.PRIVATE)
+public final class MySQLSelectAdminExecutorFactory {
+    
+    private static final String INFORMATION_SCHEMA = "information_schema";
+    
+    private static final String PERFORMANCE_SCHEMA = "performance_schema";
+    
+    private static final String MYSQL_SCHEMA = "mysql";
+    
+    private static final String SYS_SCHEMA = "sys";
+    
+    /**
+     * New instance of select admin executor for MySQL.
+     *
+     * @param selectStatementContext select statement context
+     * @param sql SQL
+     * @param databaseName database name
+     * @param parameters  SQL parameters
+     * @return created instance
+     */
+    public static Optional<DatabaseAdminExecutor> newInstance(final 
SelectStatementContext selectStatementContext, final String sql, final String 
databaseName, final List<Object> parameters) {
+        if (!selectStatementContext.getSqlStatement().getFrom().isPresent()) {
+            return 
MySQLSelectWithoutFromAdminExecutorFactory.newInstance(selectStatementContext, 
sql, databaseName);
+        }
+        if (INFORMATION_SCHEMA.equalsIgnoreCase(databaseName) && 
!ProxyContext.getInstance().getContextManager().getDatabase(databaseName).isComplete())
 {
+            return 
MySQLInformationSchemaExecutorFactory.newInstance(selectStatementContext, sql, 
parameters);
+        }
+        if (PERFORMANCE_SCHEMA.equalsIgnoreCase(databaseName) && 
!ProxyContext.getInstance().getContextManager().getDatabase(databaseName).isComplete())
 {
+            return 
MySQLPerformanceSchemaExecutorFactory.newInstance(selectStatementContext, sql, 
parameters);
+        }
+        if (MYSQL_SCHEMA.equalsIgnoreCase(databaseName) && 
!ProxyContext.getInstance().getContextManager().getDatabase(databaseName).isComplete())
 {
+            return 
MySQLMySQLSchemaExecutorFactory.newInstance(selectStatementContext, sql, 
parameters);
+        }
+        if (SYS_SCHEMA.equalsIgnoreCase(databaseName) && 
!ProxyContext.getInstance().getContextManager().getDatabase(databaseName).isComplete())
 {
+            return 
MySQLSysSchemaExecutorFactory.newInstance(selectStatementContext, sql, 
parameters);
+        }
+        return Optional.empty();
+    }
+}
diff --git 
a/proxy/backend/dialect/mysql/src/main/java/org/apache/shardingsphere/proxy/backend/mysql/handler/admin/factory/MySQLSelectWithoutFromAdminExecutorFactory.java
 
b/proxy/backend/dialect/mysql/src/main/java/org/apache/shardingsphere/proxy/backend/mysql/handler/admin/factory/MySQLSelectWithoutFromAdminExecutorFactory.java
new file mode 100644
index 00000000000..8b22c653d70
--- /dev/null
+++ 
b/proxy/backend/dialect/mysql/src/main/java/org/apache/shardingsphere/proxy/backend/mysql/handler/admin/factory/MySQLSelectWithoutFromAdminExecutorFactory.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.mysql.handler.admin.factory;
+
+import lombok.AccessLevel;
+import lombok.NoArgsConstructor;
+import 
org.apache.shardingsphere.infra.binder.context.statement.type.dml.SelectStatementContext;
+import 
org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase;
+import org.apache.shardingsphere.proxy.backend.context.ProxyContext;
+import 
org.apache.shardingsphere.proxy.backend.handler.admin.executor.DatabaseAdminExecutor;
+import 
org.apache.shardingsphere.proxy.backend.mysql.handler.admin.executor.MySQLSystemVariableQueryExecutor;
+import 
org.apache.shardingsphere.proxy.backend.mysql.handler.admin.executor.NoResourceShowExecutor;
+import 
org.apache.shardingsphere.proxy.backend.mysql.handler.admin.executor.ShowConnectionIdExecutor;
+import 
org.apache.shardingsphere.proxy.backend.mysql.handler.admin.executor.ShowCurrentDatabaseExecutor;
+import 
org.apache.shardingsphere.proxy.backend.mysql.handler.admin.executor.ShowCurrentUserExecutor;
+import 
org.apache.shardingsphere.proxy.backend.mysql.handler.admin.executor.ShowVersionExecutor;
+import 
org.apache.shardingsphere.proxy.backend.mysql.handler.admin.executor.UnicastResourceShowExecutor;
+import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.item.ExpressionProjectionSegment;
+import 
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.item.ProjectionSegment;
+import 
org.apache.shardingsphere.sql.parser.statement.core.statement.type.dml.SelectStatement;
+
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.Optional;
+
+/**
+ * Select without from admin executor factory for MySQL.
+ */
+@NoArgsConstructor(access = AccessLevel.PRIVATE)
+public final class MySQLSelectWithoutFromAdminExecutorFactory {
+    
+    /**
+     * New instance of select without from admin executor factory for MySQL.
+     *
+     * @param selectStatementContext select statement context
+     * @param sql SQL
+     * @param databaseName database name
+     * @return created instance
+     */
+    public static Optional<DatabaseAdminExecutor> newInstance(final 
SelectStatementContext selectStatementContext, final String sql, final String 
databaseName) {
+        SelectStatement selectStatement = 
selectStatementContext.getSqlStatement();
+        Optional<DatabaseAdminExecutor> result = 
MySQLSystemVariableQueryExecutor.tryGetSystemVariableQueryExecutor(selectStatement);
+        return result.isPresent() ? result : 
getSelectFunctionOrVariableExecutor(selectStatement, sql, databaseName);
+    }
+    
+    private static 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());
+        }
+        if (isShowSpecialFunction(selectStatement, 
ShowCurrentDatabaseExecutor.FUNCTION_NAME)) {
+            return Optional.of(new ShowCurrentDatabaseExecutor());
+        }
+        return mockExecutor(databaseName, selectStatement, sql);
+    }
+    
+    private static boolean isShowSpecialFunction(final SelectStatement 
sqlStatement, final String functionName) {
+        Iterator<ProjectionSegment> segmentIterator = 
sqlStatement.getProjections().getProjections().iterator();
+        ProjectionSegment firstProjection = segmentIterator.next();
+        if (segmentIterator.hasNext() || !(firstProjection instanceof 
ExpressionProjectionSegment)) {
+            return false;
+        }
+        String projectionText = ((ExpressionProjectionSegment) 
firstProjection).getText();
+        String trimmedText = projectionText.replaceAll("\\s+\\(", "(");
+        return functionName.equalsIgnoreCase(trimmedText);
+    }
+    
+    private static Optional<DatabaseAdminExecutor> mockExecutor(final String 
databaseName, final SelectStatement sqlStatement, final String sql) {
+        if (isEmptyResource()) {
+            return Optional.of(new NoResourceShowExecutor(sqlStatement));
+        }
+        boolean isUseDatabase = null != databaseName || 
sqlStatement.getFrom().isPresent();
+        return isUseDatabase ? Optional.empty() : Optional.of(new 
UnicastResourceShowExecutor(sqlStatement, sql));
+    }
+    
+    private static boolean isEmptyResource() {
+        Collection<ShardingSphereDatabase> databases = 
ProxyContext.getInstance().getContextManager().getMetaDataContexts().getMetaData().getAllDatabases();
+        return databases.isEmpty() || 
databases.stream().noneMatch(ShardingSphereDatabase::containsDataSource);
+    }
+}
diff --git 
a/proxy/backend/dialect/mysql/src/main/java/org/apache/shardingsphere/proxy/backend/mysql/handler/admin/MySQLSysSchemaExecutorFactory.java
 
b/proxy/backend/dialect/mysql/src/main/java/org/apache/shardingsphere/proxy/backend/mysql/handler/admin/factory/MySQLSysSchemaExecutorFactory.java
similarity index 99%
rename from 
proxy/backend/dialect/mysql/src/main/java/org/apache/shardingsphere/proxy/backend/mysql/handler/admin/MySQLSysSchemaExecutorFactory.java
rename to 
proxy/backend/dialect/mysql/src/main/java/org/apache/shardingsphere/proxy/backend/mysql/handler/admin/factory/MySQLSysSchemaExecutorFactory.java
index 0b806283dd3..faee54662b3 100644
--- 
a/proxy/backend/dialect/mysql/src/main/java/org/apache/shardingsphere/proxy/backend/mysql/handler/admin/MySQLSysSchemaExecutorFactory.java
+++ 
b/proxy/backend/dialect/mysql/src/main/java/org/apache/shardingsphere/proxy/backend/mysql/handler/admin/factory/MySQLSysSchemaExecutorFactory.java
@@ -15,7 +15,7 @@
  * limitations under the License.
  */
 
-package org.apache.shardingsphere.proxy.backend.mysql.handler.admin;
+package org.apache.shardingsphere.proxy.backend.mysql.handler.admin.factory;
 
 import lombok.AccessLevel;
 import lombok.NoArgsConstructor;

Reply via email to