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 8597726a5e8 mysql-proxy: skip admin for no-FROM multi-expression
selects; add tests (#37391)
8597726a5e8 is described below
commit 8597726a5e82b8d14f6c398f5f21348188dc180c
Author: Quanye Yang <[email protected]>
AuthorDate: Tue Dec 16 12:41:44 2025 +0800
mysql-proxy: skip admin for no-FROM multi-expression selects; add tests
(#37391)
---
...MySQLSelectWithoutFromAdminExecutorFactory.java | 8 ++++
.../admin/MySQLAdminExecutorCreatorTest.java | 45 ++++++++++++++++++++++
2 files changed, 53 insertions(+)
diff --git
a/proxy/backend/dialect/mysql/src/main/java/org/apache/shardingsphere/proxy/backend/mysql/handler/admin/factory/withoutfrom/MySQLSelectWithoutFromAdminExecutorFactory.java
b/proxy/backend/dialect/mysql/src/main/java/org/apache/shardingsphere/proxy/backend/mysql/handler/admin/factory/withoutfrom/MySQLSelectWithoutFromAdminExecutorFactory.java
index 470c536a131..c544e89bee7 100644
---
a/proxy/backend/dialect/mysql/src/main/java/org/apache/shardingsphere/proxy/backend/mysql/handler/admin/factory/withoutfrom/MySQLSelectWithoutFromAdminExecutorFactory.java
+++
b/proxy/backend/dialect/mysql/src/main/java/org/apache/shardingsphere/proxy/backend/mysql/handler/admin/factory/withoutfrom/MySQLSelectWithoutFromAdminExecutorFactory.java
@@ -93,9 +93,17 @@ public final class
MySQLSelectWithoutFromAdminExecutorFactory {
return Optional.of(new NoResourceShowExecutor(sqlStatement));
}
boolean isUseDatabase = null != databaseName ||
sqlStatement.getFrom().isPresent();
+ if (!isUseDatabase && hasMultipleProjections(sqlStatement)) {
+ return Optional.empty();
+ }
return isUseDatabase ? Optional.empty() : Optional.of(new
UnicastResourceShowExecutor(sqlStatement, sql));
}
+ private static boolean hasMultipleProjections(final SelectStatement
sqlStatement) {
+ Collection<ProjectionSegment> projections =
sqlStatement.getProjections().getProjections();
+ return projections.size() > 1;
+ }
+
private static boolean isEmptyResource(final ShardingSphereMetaData
metaData) {
Collection<ShardingSphereDatabase> databases =
metaData.getAllDatabases();
return databases.isEmpty() ||
databases.stream().noneMatch(ShardingSphereDatabase::containsDataSource);
diff --git
a/proxy/backend/dialect/mysql/src/test/java/org/apache/shardingsphere/proxy/backend/mysql/handler/admin/MySQLAdminExecutorCreatorTest.java
b/proxy/backend/dialect/mysql/src/test/java/org/apache/shardingsphere/proxy/backend/mysql/handler/admin/MySQLAdminExecutorCreatorTest.java
index 3a4b72859bc..7f69967391c 100644
---
a/proxy/backend/dialect/mysql/src/test/java/org/apache/shardingsphere/proxy/backend/mysql/handler/admin/MySQLAdminExecutorCreatorTest.java
+++
b/proxy/backend/dialect/mysql/src/test/java/org/apache/shardingsphere/proxy/backend/mysql/handler/admin/MySQLAdminExecutorCreatorTest.java
@@ -73,6 +73,7 @@ import
org.apache.shardingsphere.test.infra.framework.extension.mock.StaticMockS
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
+import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Optional;
@@ -405,4 +406,48 @@ class MySQLAdminExecutorCreatorTest {
Optional<DatabaseAdminExecutor> actual = new
MySQLAdminExecutorCreator().create(sqlStatementContext, "DELETE FROM t", "",
Collections.emptyList());
assertThat(actual, is(Optional.empty()));
}
+
+ @Test
+ void assertCreateWithNoFromAndMultiProjectionsSkipsAdmin() {
+ ResourceMetaData resourceMetaData = new
ResourceMetaData(Collections.singletonMap("ds_0", new MockedDataSource()));
+ ShardingSphereDatabase database = new ShardingSphereDatabase("db_0",
databaseType, resourceMetaData, mock(RuleMetaData.class),
Collections.emptyList());
+ initProxyContext(Collections.singleton(database));
+
+ SelectStatement selectStatement = mock(SelectStatement.class);
+ when(selectStatement.getFrom()).thenReturn(Optional.empty());
+ ProjectionsSegment projectionsSegment = mock(ProjectionsSegment.class);
+ when(projectionsSegment.getProjections()).thenReturn(Arrays.asList(
+ new ExpressionProjectionSegment(0, 10, "database()"),
+ new ExpressionProjectionSegment(0, 10, "schema()"),
+ new ExpressionProjectionSegment(0, 10,
"left(user(),instr(concat(user(),'@'),'@')-1)")));
+ when(selectStatement.getProjections()).thenReturn(projectionsSegment);
+ SelectStatementContext sqlStatementContext =
mock(SelectStatementContext.class);
+
when(sqlStatementContext.getSqlStatement()).thenReturn(selectStatement);
+
+ Optional<DatabaseAdminExecutor> actual =
+ new MySQLAdminExecutorCreator().create(sqlStatementContext,
"SELECT database(),schema(),left(user(),instr(concat(user(),'@'),'@')-1)",
null, Collections.emptyList());
+ assertThat(actual, is(Optional.empty()));
+ }
+
+ @Test
+ void assertCreateWithMultiSystemVariablesUseSysVarExecutor() {
+ initProxyContext(Collections.emptyList());
+ SelectStatement selectStatement = mock(SelectStatement.class);
+ when(selectStatement.getFrom()).thenReturn(Optional.empty());
+ ProjectionsSegment projectionsSegment = mock(ProjectionsSegment.class);
+ VariableSegment v1 = new VariableSegment(0, 0, "version", "SESSION");
+ VariableSegment v2 = new VariableSegment(0, 0,
"transaction_isolation", "SESSION");
+ when(projectionsSegment.getProjections()).thenReturn(Arrays.asList(
+ new ExpressionProjectionSegment(0, 10, "@@session.version",
v1),
+ new ExpressionProjectionSegment(0, 10,
"@@session.transaction_isolation", v2)));
+ when(selectStatement.getProjections()).thenReturn(projectionsSegment);
+
+ SelectStatementContext sqlStatementContext =
mock(SelectStatementContext.class);
+
when(sqlStatementContext.getSqlStatement()).thenReturn(selectStatement);
+
+ Optional<DatabaseAdminExecutor> actual = new
MySQLAdminExecutorCreator().create(
+ sqlStatementContext, "SELECT @@session.version,
@@session.transaction_isolation", null, Collections.emptyList());
+ assertTrue(actual.isPresent());
+ assertThat(actual.get(), isA(MySQLSystemVariableQueryExecutor.class));
+ }
}