You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@shardingsphere.apache.org by zh...@apache.org on 2026/07/13 10:47:56 UTC

(shardingsphere) branch master updated: Remove ClassificationResult compatibility constructor (#39087)

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

terrymanu 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 497fb3121da Remove ClassificationResult compatibility constructor (#39087)
497fb3121da is described below

commit 497fb3121dab5fdff9fd4ec1be1d05894f94da84
Author: Liang Zhang <zh...@apache.org>
AuthorDate: Mon Jul 13 18:47:50 2026 +0800

    Remove ClassificationResult compatibility constructor (#39087)
---
 .../tool/handler/execute/ClassificationResult.java |  5 ---
 .../tool/handler/execute/StatementClassifier.java  |  5 ++-
 .../core/protocol/error/MCPErrorConverterTest.java | 23 ++++++++--
 .../execute/MCPJdbcStatementExecutorTest.java      | 50 ++++++++++++----------
 .../MCPJdbcTransactionStatementExecutorTest.java   |  3 +-
 .../handler/execute/MCPSQLExecutionFacadeTest.java | 26 +++++++----
 .../execute/RuleDistSQLExecutionExceptionTest.java |  3 +-
 7 files changed, 70 insertions(+), 45 deletions(-)

diff --git a/mcp/core/src/main/java/org/apache/shardingsphere/mcp/core/tool/handler/execute/ClassificationResult.java b/mcp/core/src/main/java/org/apache/shardingsphere/mcp/core/tool/handler/execute/ClassificationResult.java
index f1cf58c8498..2fcb3f9af96 100644
--- a/mcp/core/src/main/java/org/apache/shardingsphere/mcp/core/tool/handler/execute/ClassificationResult.java
+++ b/mcp/core/src/main/java/org/apache/shardingsphere/mcp/core/tool/handler/execute/ClassificationResult.java
@@ -58,11 +58,6 @@ public final class ClassificationResult {
     
     private final String savepointName;
     
-    public ClassificationResult(final SupportedMCPStatement statementClass, final String statementType, final String normalizedSql, final String targetObjectName, final String savepointName) {
-        this(statementClass, statementType, normalizedSql, savepointName,
-                targetObjectName.isEmpty() ? List.of() : List.of(SQLStatementObjectName.fromNormalizedName(targetObjectName)));
-    }
-    
     ClassificationResult(final SupportedMCPStatement statementClass, final String statementType, final String normalizedSql, final String savepointName,
                          final Collection<SQLStatementObjectName> referencedObjects) {
         this.statementClass = statementClass;
diff --git a/mcp/core/src/main/java/org/apache/shardingsphere/mcp/core/tool/handler/execute/StatementClassifier.java b/mcp/core/src/main/java/org/apache/shardingsphere/mcp/core/tool/handler/execute/StatementClassifier.java
index 94dbec4bb2b..3243f0770a1 100644
--- a/mcp/core/src/main/java/org/apache/shardingsphere/mcp/core/tool/handler/execute/StatementClassifier.java
+++ b/mcp/core/src/main/java/org/apache/shardingsphere/mcp/core/tool/handler/execute/StatementClassifier.java
@@ -20,6 +20,7 @@ package org.apache.shardingsphere.mcp.core.tool.handler.execute;
 import org.apache.shardingsphere.infra.exception.ShardingSpherePreconditions;
 import org.apache.shardingsphere.mcp.support.database.capability.SupportedMCPStatement;
 
+import java.util.List;
 import java.util.Locale;
 
 /**
@@ -52,10 +53,10 @@ public final class StatementClassifier {
             String statementType = extractStatementType(upperLeadingSql);
             String savepointName = extractSavepointName(leadingSql);
             validateSavepointName(statementType, savepointName);
-            return new ClassificationResult(SupportedMCPStatement.SAVEPOINT, statementType, actualSql, "", savepointName);
+            return new ClassificationResult(SupportedMCPStatement.SAVEPOINT, statementType, actualSql, savepointName, List.of());
         }
         if (isTransactionControlStatement(upperLeadingSql)) {
-            return new ClassificationResult(SupportedMCPStatement.TRANSACTION_CONTROL, extractStatementType(upperLeadingSql), actualSql, "", "");
+            return new ClassificationResult(SupportedMCPStatement.TRANSACTION_CONTROL, extractStatementType(upperLeadingSql), actualSql, "", List.of());
         }
         SQLStatementStructure statementStructure = structureResolver.resolve(actualSql);
         SupportedMCPStatement statementClass = statementClassResolver.resolve(statementStructure);
diff --git a/mcp/core/src/test/java/org/apache/shardingsphere/mcp/core/protocol/error/MCPErrorConverterTest.java b/mcp/core/src/test/java/org/apache/shardingsphere/mcp/core/protocol/error/MCPErrorConverterTest.java
index bd5421f79bc..3dae5977253 100644
--- a/mcp/core/src/test/java/org/apache/shardingsphere/mcp/core/protocol/error/MCPErrorConverterTest.java
+++ b/mcp/core/src/test/java/org/apache/shardingsphere/mcp/core/protocol/error/MCPErrorConverterTest.java
@@ -59,12 +59,15 @@ import java.sql.SQLTransientConnectionException;
 import java.util.Collection;
 import java.util.List;
 import java.util.Map;
+import java.util.Optional;
 import java.util.stream.Stream;
 
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.is;
 import static org.junit.jupiter.api.Assertions.assertFalse;
 import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
 
 class MCPErrorConverterTest {
     
@@ -271,7 +274,12 @@ class MCPErrorConverterTest {
     
     @Test
     void assertConvertSQLToolMismatchWithRecovery() {
-        ClassificationResult classificationResult = new ClassificationResult(SupportedMCPStatement.DML, "UPDATE", "UPDATE orders SET status = 'PAID'", "orders", "");
+        ClassificationResult classificationResult = mock(ClassificationResult.class);
+        when(classificationResult.getStatementClass()).thenReturn(SupportedMCPStatement.DML);
+        when(classificationResult.getStatementType()).thenReturn("UPDATE");
+        when(classificationResult.getNormalizedSql()).thenReturn("UPDATE orders SET status = 'PAID'");
+        when(classificationResult.getTargetObjectName()).thenReturn(Optional.of("orders"));
+        when(classificationResult.getSavepointName()).thenReturn(Optional.empty());
         Map<String, Object> suggestedArguments = Map.of("database", "logic_db", "schema", "public", "sql", "UPDATE orders SET status = 'PAID'", "execution_mode", "preview");
         Map<String, Object> actual = MCPErrorConverter.convert(new SQLToolMismatchException(
                 "database_gateway_execute_query only supports classifier-approved QUERY statements. "
@@ -304,7 +312,12 @@ class MCPErrorConverterTest {
     
     @Test
     void assertConvertReadOnlySQLToolMismatchWithRecovery() {
-        ClassificationResult classificationResult = new ClassificationResult(SupportedMCPStatement.QUERY, "SELECT", "SELECT * FROM orders", "orders", "");
+        ClassificationResult classificationResult = mock(ClassificationResult.class);
+        when(classificationResult.getStatementClass()).thenReturn(SupportedMCPStatement.QUERY);
+        when(classificationResult.getStatementType()).thenReturn("SELECT");
+        when(classificationResult.getNormalizedSql()).thenReturn("SELECT * FROM orders");
+        when(classificationResult.getTargetObjectName()).thenReturn(Optional.of("orders"));
+        when(classificationResult.getSavepointName()).thenReturn(Optional.empty());
         Map<String, Object> suggestedArguments = Map.of("database", "logic_db", "sql", "SELECT * FROM orders");
         Map<String, Object> actual = MCPErrorConverter.convert(new SQLToolMismatchException(
                 "database_gateway_execute_update does not accept read-only SQL. Use database_gateway_execute_query for read-only SQL.",
@@ -318,8 +331,10 @@ class MCPErrorConverterTest {
     
     @Test
     void assertConvertRuleDistSQLExecutionWithRecovery() {
-        ClassificationResult classificationResult = new ClassificationResult(SupportedMCPStatement.DDL, "CREATE",
-                "CREATE SHARDING TABLE RULE t_order(DATANODES('ds_${0..1}.t_order_${0..1}'))", "", "");
+        ClassificationResult classificationResult = mock(ClassificationResult.class);
+        when(classificationResult.getStatementClass()).thenReturn(SupportedMCPStatement.DDL);
+        when(classificationResult.getStatementType()).thenReturn("CREATE");
+        when(classificationResult.getSideEffectScope()).thenReturn("rule-metadata");
         Map<String, Object> actual = MCPErrorConverter.convert(new RuleDistSQLExecutionException(
                 "sharding_db", classificationResult, new SQLSyntaxErrorException("syntax error"))).toPayload();
         assertThat(actual.get("message"),
diff --git a/mcp/core/src/test/java/org/apache/shardingsphere/mcp/core/tool/handler/execute/MCPJdbcStatementExecutorTest.java b/mcp/core/src/test/java/org/apache/shardingsphere/mcp/core/tool/handler/execute/MCPJdbcStatementExecutorTest.java
index 032dcf401a1..37a64d299fb 100644
--- a/mcp/core/src/test/java/org/apache/shardingsphere/mcp/core/tool/handler/execute/MCPJdbcStatementExecutorTest.java
+++ b/mcp/core/src/test/java/org/apache/shardingsphere/mcp/core/tool/handler/execute/MCPJdbcStatementExecutorTest.java
@@ -101,7 +101,8 @@ class MCPJdbcStatementExecutorTest {
         MCPJdbcStatementExecutor statementExecutor = new MCPJdbcStatementExecutor(Collections.emptyMap(), transactionResourceManager);
         SQLExecutionResponse actual = statementExecutor.execute(new SQLExecutionRequest("session-1",
                 "logic_db", "public", "UPDATE orders SET status = 'DONE'", 10, 1000),
-                new ClassificationResult(SupportedMCPStatement.DML, "UPDATE", "UPDATE orders SET status = 'DONE'", "", ""), createDatabaseCapability(SchemaExecutionSemantics.FIXED_TO_DATABASE));
+                new ClassificationResult(SupportedMCPStatement.DML, "UPDATE", "UPDATE orders SET status = 'DONE'", "", List.of()),
+                createDatabaseCapability(SchemaExecutionSemantics.FIXED_TO_DATABASE));
         assertThat(actual.getAffectedRows(), is(2));
         verify(connection, never()).close();
     }
@@ -122,7 +123,7 @@ class MCPJdbcStatementExecutorTest {
         MCPJdbcStatementExecutor statementExecutor = new MCPJdbcStatementExecutor(Map.of("logic_db", databaseConfig), transactionResourceManager);
         SQLExecutionResponse actual = statementExecutor.execute(new SQLExecutionRequest("session-1",
                 "logic_db", "public", "SELECT status FROM orders", 10, 1000, true),
-                new ClassificationResult(SupportedMCPStatement.QUERY, "SELECT", "SELECT status FROM orders", "", ""), createDatabaseCapability(SchemaExecutionSemantics.FIXED_TO_DATABASE));
+                new ClassificationResult(SupportedMCPStatement.QUERY, "SELECT", "SELECT status FROM orders", "", List.of()), createDatabaseCapability(SchemaExecutionSemantics.FIXED_TO_DATABASE));
         assertThat(actual.getRows().size(), is(1));
         verify(connection).setReadOnly(true);
         verify(connection).setAutoCommit(false);
@@ -140,7 +141,7 @@ class MCPJdbcStatementExecutorTest {
         MCPJdbcStatementExecutor statementExecutor = new MCPJdbcStatementExecutor(Collections.emptyMap(), transactionResourceManager);
         SQLExecutionResponse actual = statementExecutor.execute(new SQLExecutionRequest("session-1",
                 "logic_db", "public", "SELECT status FROM orders", 10, 1000, true),
-                new ClassificationResult(SupportedMCPStatement.QUERY, "SELECT", "SELECT status FROM orders", "", ""), createDatabaseCapability(SchemaExecutionSemantics.FIXED_TO_DATABASE));
+                new ClassificationResult(SupportedMCPStatement.QUERY, "SELECT", "SELECT status FROM orders", "", List.of()), createDatabaseCapability(SchemaExecutionSemantics.FIXED_TO_DATABASE));
         assertThat(actual.getRows().size(), is(1));
         verify(connection, never()).setReadOnly(true);
         verify(connection, never()).rollback();
@@ -163,7 +164,7 @@ class MCPJdbcStatementExecutorTest {
         MCPJdbcStatementExecutor statementExecutor = new MCPJdbcStatementExecutor(Map.of("logic_db", databaseConfig), transactionResourceManager);
         SQLExecutionResponse actual = statementExecutor.execute(new SQLExecutionRequest("session-1",
                 "logic_db", " ", "SELECT status FROM orders", 0, 0),
-                new ClassificationResult(SupportedMCPStatement.QUERY, "SELECT", "SELECT status FROM orders", "", ""), createDatabaseCapability(SchemaExecutionSemantics.FIXED_TO_DATABASE));
+                new ClassificationResult(SupportedMCPStatement.QUERY, "SELECT", "SELECT status FROM orders", "", List.of()), createDatabaseCapability(SchemaExecutionSemantics.FIXED_TO_DATABASE));
         assertThat(actual.getRows().size(), is(2));
         assertFalse(actual.isTruncated());
         verify(connection, never()).setSchema(anyString());
@@ -185,7 +186,7 @@ class MCPJdbcStatementExecutorTest {
         MCPJdbcStatementExecutor statementExecutor = new MCPJdbcStatementExecutor(Map.of("logic_db", databaseConfig), transactionResourceManager);
         SQLExecutionResponse actual = statementExecutor.execute(new SQLExecutionRequest("session-1",
                 "logic_db", "public", "SELECT status FROM orders", Integer.MAX_VALUE, 1000),
-                new ClassificationResult(SupportedMCPStatement.QUERY, "SELECT", "SELECT status FROM orders", "", ""), createDatabaseCapability(SchemaExecutionSemantics.FIXED_TO_DATABASE));
+                new ClassificationResult(SupportedMCPStatement.QUERY, "SELECT", "SELECT status FROM orders", "", List.of()), createDatabaseCapability(SchemaExecutionSemantics.FIXED_TO_DATABASE));
         assertThat(actual.getRows().size(), is(0));
         assertFalse(actual.isTruncated());
         verify(statement).setMaxRows(Integer.MAX_VALUE);
@@ -206,7 +207,7 @@ class MCPJdbcStatementExecutorTest {
         SQLExecutionResponse actual = statementExecutor.execute(new SQLExecutionRequest("session-1",
                 "logic_db", "public", "WITH updated_orders AS (UPDATE orders SET status = 'DONE' RETURNING *) SELECT * FROM updated_orders", 10, 1000),
                 new ClassificationResult(SupportedMCPStatement.DML, "SELECT",
-                        "WITH updated_orders AS (UPDATE orders SET status = 'DONE' RETURNING *) SELECT * FROM updated_orders", "", ""),
+                        "WITH updated_orders AS (UPDATE orders SET status = 'DONE' RETURNING *) SELECT * FROM updated_orders", "", List.of()),
                 createDatabaseCapability(SchemaExecutionSemantics.FIXED_TO_DATABASE));
         assertThat(actual.getResultKind(), is(ExecuteQueryResultKind.RESULT_SET));
         assertThat(actual.getStatementClass(), is(SupportedMCPStatement.DML));
@@ -224,7 +225,8 @@ class MCPJdbcStatementExecutorTest {
         MCPJdbcStatementExecutor statementExecutor = new MCPJdbcStatementExecutor(Map.of("logic_db", databaseConfig), transactionResourceManager);
         SQLExecutionResponse actual = statementExecutor.execute(new SQLExecutionRequest("session-1",
                 "logic_db", "logic_db", "UPDATE orders SET status = 'DONE'", 10, 1000),
-                new ClassificationResult(SupportedMCPStatement.DML, "UPDATE", "UPDATE orders SET status = 'DONE'", "", ""), createDatabaseCapability(SchemaExecutionSemantics.FIXED_TO_DATABASE));
+                new ClassificationResult(SupportedMCPStatement.DML, "UPDATE", "UPDATE orders SET status = 'DONE'", "", List.of()),
+                createDatabaseCapability(SchemaExecutionSemantics.FIXED_TO_DATABASE));
         assertThat(actual.getAffectedRows(), is(1));
         verify(connection, never()).setSchema(anyString());
     }
@@ -240,7 +242,7 @@ class MCPJdbcStatementExecutorTest {
         MCPJdbcStatementExecutor statementExecutor = new MCPJdbcStatementExecutor(Map.of("logic_db", databaseConfig), transactionResourceManager);
         MCPUnsupportedException actual = assertThrows(MCPUnsupportedException.class, () -> statementExecutor.execute(new SQLExecutionRequest("session-1",
                 "logic_db", "public", "UPDATE orders SET status = 'DONE'", 10, 1000),
-                new ClassificationResult(SupportedMCPStatement.DML, "UPDATE", "UPDATE orders SET status = 'DONE'", "", ""), createDatabaseCapability(SchemaExecutionSemantics.BEST_EFFORT)));
+                new ClassificationResult(SupportedMCPStatement.DML, "UPDATE", "UPDATE orders SET status = 'DONE'", "", List.of()), createDatabaseCapability(SchemaExecutionSemantics.BEST_EFFORT)));
         assertThat(actual.getMessage(), is("schema"));
         verify(connection).setSchema("public");
         verify(connection, never()).createStatement();
@@ -257,7 +259,7 @@ class MCPJdbcStatementExecutorTest {
         MCPJdbcStatementExecutor statementExecutor = new MCPJdbcStatementExecutor(Map.of("logic_db", databaseConfig), transactionResourceManager);
         QueryDidNotReturnResultSetException actual = assertThrows(QueryDidNotReturnResultSetException.class, () -> statementExecutor.execute(new SQLExecutionRequest("session-1",
                 "logic_db", "public", "SELECT status FROM orders", 10, 1000),
-                new ClassificationResult(SupportedMCPStatement.QUERY, "SELECT", "SELECT status FROM orders", "", ""), createDatabaseCapability(SchemaExecutionSemantics.FIXED_TO_DATABASE)));
+                new ClassificationResult(SupportedMCPStatement.QUERY, "SELECT", "SELECT status FROM orders", "", List.of()), createDatabaseCapability(SchemaExecutionSemantics.FIXED_TO_DATABASE)));
         assertThat(actual.getMessage(), is("Query did not return a result set."));
     }
     
@@ -271,7 +273,7 @@ class MCPJdbcStatementExecutorTest {
         MCPJdbcStatementExecutor statementExecutor = new MCPJdbcStatementExecutor(Map.of("logic_db", databaseConfig), transactionResourceManager);
         StatementClassNotSupportedException actual = assertThrows(StatementClassNotSupportedException.class, () -> statementExecutor.execute(new SQLExecutionRequest("session-1",
                 "logic_db", "public", "BEGIN", 10, 1000),
-                new ClassificationResult(SupportedMCPStatement.TRANSACTION_CONTROL, "BEGIN", "BEGIN", "", ""), createDatabaseCapability(SchemaExecutionSemantics.FIXED_TO_DATABASE)));
+                new ClassificationResult(SupportedMCPStatement.TRANSACTION_CONTROL, "BEGIN", "BEGIN", "", List.of()), createDatabaseCapability(SchemaExecutionSemantics.FIXED_TO_DATABASE)));
         assertThat(actual.getMessage(), is("Statement class is not supported."));
     }
     
@@ -287,7 +289,7 @@ class MCPJdbcStatementExecutorTest {
         when(databaseConfig.openConnection(anyString())).thenReturn(connection);
         MCPJdbcStatementExecutor statementExecutor = new MCPJdbcStatementExecutor(Map.of("sharding_db", databaseConfig), transactionResourceManager);
         ClassificationResult classificationResult = new ClassificationResult(SupportedMCPStatement.DDL, "CREATE",
-                "CREATE SHARDING TABLE RULE t_order(DATANODES('ds_${0..1}.t_order_${0..1}'))", "", "");
+                "CREATE SHARDING TABLE RULE t_order(DATANODES('ds_${0..1}.t_order_${0..1}'))", "", List.of());
         RuleDistSQLExecutionException actual = assertThrows(RuleDistSQLExecutionException.class, () -> statementExecutor.execute(new SQLExecutionRequest("session-1",
                 "sharding_db", "public", "CREATE SHARDING TABLE RULE t_order(DATANODES('ds_${0..1}.t_order_${0..1}'))", 10, 1000),
                 classificationResult, createDatabaseCapability(SchemaExecutionSemantics.FIXED_TO_DATABASE)));
@@ -313,7 +315,7 @@ class MCPJdbcStatementExecutorTest {
         MCPJdbcStatementExecutor statementExecutor = new MCPJdbcStatementExecutor(Map.of("logic_db", databaseConfig), transactionResourceManager);
         ShardingSphereMCPException actual = assertThrows(expectedExceptionClass, () -> statementExecutor.execute(new SQLExecutionRequest("session-1",
                 "logic_db", "public", "SELECT status FROM orders", 10, 1000),
-                new ClassificationResult(SupportedMCPStatement.QUERY, "SELECT", "SELECT status FROM orders", "", ""), createDatabaseCapability(SchemaExecutionSemantics.FIXED_TO_DATABASE)));
+                new ClassificationResult(SupportedMCPStatement.QUERY, "SELECT", "SELECT status FROM orders", "", List.of()), createDatabaseCapability(SchemaExecutionSemantics.FIXED_TO_DATABASE)));
         assertThat(actual.getClass(), is(expectedExceptionClass));
         assertThat(actual.getMessage(), is(expectedMessage));
         assertThat(actual.getCause(), is(sqlException));
@@ -327,7 +329,7 @@ class MCPJdbcStatementExecutorTest {
         MCPJdbcStatementExecutor statementExecutor = new MCPJdbcStatementExecutor(Collections.emptyMap(), transactionResourceManager);
         MCPTransactionStateException actual = assertThrows(MCPTransactionStateException.class, () -> statementExecutor.execute(new SQLExecutionRequest("session-1",
                 "logic_db", "public", "SELECT status FROM orders", 10, 1000),
-                new ClassificationResult(SupportedMCPStatement.QUERY, "SELECT", "SELECT status FROM orders", "", ""), createDatabaseCapability(SchemaExecutionSemantics.FIXED_TO_DATABASE)));
+                new ClassificationResult(SupportedMCPStatement.QUERY, "SELECT", "SELECT status FROM orders", "", List.of()), createDatabaseCapability(SchemaExecutionSemantics.FIXED_TO_DATABASE)));
         assertThat(actual.getMessage(), is("Transaction already active."));
         assertThat(actual.getCause(), is(cause));
     }
@@ -339,7 +341,7 @@ class MCPJdbcStatementExecutorTest {
         MCPJdbcStatementExecutor statementExecutor = new MCPJdbcStatementExecutor(Collections.emptyMap(), transactionResourceManager);
         MCPUnavailableException actual = assertThrows(MCPUnavailableException.class, () -> statementExecutor.execute(new SQLExecutionRequest("session-1",
                 "missing_db", "public", "SELECT status FROM orders", 10, 1000),
-                new ClassificationResult(SupportedMCPStatement.QUERY, "SELECT", "SELECT status FROM orders", "", ""), createDatabaseCapability(SchemaExecutionSemantics.FIXED_TO_DATABASE)));
+                new ClassificationResult(SupportedMCPStatement.QUERY, "SELECT", "SELECT status FROM orders", "", List.of()), createDatabaseCapability(SchemaExecutionSemantics.FIXED_TO_DATABASE)));
         assertThat(actual.getMessage(), is("Database `missing_db` is not configured."));
     }
     
@@ -357,7 +359,8 @@ class MCPJdbcStatementExecutorTest {
         MCPJdbcStatementExecutor statementExecutor = new MCPJdbcStatementExecutor(Map.of("logic_db", databaseConfig), transactionResourceManager);
         MCPQueryFailedException actual = assertThrows(MCPQueryFailedException.class, () -> statementExecutor.execute(new SQLExecutionRequest("session-1", "logic_db",
                 "public", "UPDATE orders SET status = 'DONE'", 10, 1000),
-                new ClassificationResult(SupportedMCPStatement.DML, "UPDATE", "UPDATE orders SET status = 'DONE'", "", ""), createDatabaseCapability(SchemaExecutionSemantics.FIXED_TO_DATABASE)));
+                new ClassificationResult(SupportedMCPStatement.DML, "UPDATE", "UPDATE orders SET status = 'DONE'", "", List.of()),
+                createDatabaseCapability(SchemaExecutionSemantics.FIXED_TO_DATABASE)));
         assertThat(actual.getMessage(), is("statement close failed"));
     }
     
@@ -372,7 +375,8 @@ class MCPJdbcStatementExecutorTest {
         MCPJdbcStatementExecutor statementExecutor = new MCPJdbcStatementExecutor(Map.of("logic_db", databaseConfig), transactionResourceManager);
         SQLExecutionResponse actual = statementExecutor.execute(new SQLExecutionRequest("session-1",
                 "logic_db", "public", "UPDATE orders SET status = 'DONE'", 10, 1000),
-                new ClassificationResult(SupportedMCPStatement.DML, "UPDATE", "UPDATE orders SET status = 'DONE'", "", ""), createDatabaseCapability(SchemaExecutionSemantics.FIXED_TO_DATABASE));
+                new ClassificationResult(SupportedMCPStatement.DML, "UPDATE", "UPDATE orders SET status = 'DONE'", "", List.of()),
+                createDatabaseCapability(SchemaExecutionSemantics.FIXED_TO_DATABASE));
         assertThat(actual.getAffectedRows(), is(1));
         verify(connection).close();
     }
@@ -386,7 +390,7 @@ class MCPJdbcStatementExecutorTest {
         MCPJdbcStatementExecutor statementExecutor = new MCPJdbcStatementExecutor(Map.of("logic_db", databaseConfig), transactionResourceManager);
         assertThrows(NullPointerException.class, () -> statementExecutor.execute(new SQLExecutionRequest("session-1",
                 "logic_db", "", "SELECT status FROM orders", 0, 0),
-                new ClassificationResult(SupportedMCPStatement.QUERY, "SELECT", "SELECT status FROM orders", "", ""), createDatabaseCapability(SchemaExecutionSemantics.FIXED_TO_DATABASE)));
+                new ClassificationResult(SupportedMCPStatement.QUERY, "SELECT", "SELECT status FROM orders", "", List.of()), createDatabaseCapability(SchemaExecutionSemantics.FIXED_TO_DATABASE)));
     }
     
     @Test
@@ -400,7 +404,7 @@ class MCPJdbcStatementExecutorTest {
         MCPJdbcStatementExecutor statementExecutor = new MCPJdbcStatementExecutor(Map.of("logic_db", databaseConfig), transactionResourceManager);
         assertThrows(NullPointerException.class, () -> statementExecutor.execute(new SQLExecutionRequest("session-1",
                 "logic_db", "", "SELECT status FROM orders", 0, 0),
-                new ClassificationResult(SupportedMCPStatement.QUERY, "SELECT", "SELECT status FROM orders", "", ""), createDatabaseCapability(SchemaExecutionSemantics.FIXED_TO_DATABASE)));
+                new ClassificationResult(SupportedMCPStatement.QUERY, "SELECT", "SELECT status FROM orders", "", List.of()), createDatabaseCapability(SchemaExecutionSemantics.FIXED_TO_DATABASE)));
     }
     
     private static MCPDatabaseCapability createDatabaseCapability(final SchemaExecutionSemantics schemaExecutionSemantics) {
@@ -447,21 +451,21 @@ class MCPJdbcStatementExecutorTest {
     private static Stream<Arguments> assertExecuteCases() throws SQLException {
         return Stream.of(
                 Arguments.of("query result set", new SQLExecutionRequest("session-1", "logic_db", "public", "SELECT status FROM orders ORDER BY order_id", 1, 1000),
-                        new ClassificationResult(SupportedMCPStatement.QUERY, "SELECT", "SELECT status FROM orders ORDER BY order_id", "", ""),
+                        new ClassificationResult(SupportedMCPStatement.QUERY, "SELECT", "SELECT status FROM orders ORDER BY order_id", "", List.of()),
                         createStatementConnection(true, 0, createResultSet(createColumns(), List.of(List.of(1, "NEW"), List.of(2, "DONE")))),
                         ExecuteQueryResultKind.RESULT_SET, "SELECT", 1, 0, "", true),
                 Arguments.of("explain result set", new SQLExecutionRequest("session-1", "logic_db", "public", "EXPLAIN SELECT * FROM orders", 10, 1000),
-                        new ClassificationResult(SupportedMCPStatement.EXPLAIN, "EXPLAIN", "EXPLAIN SELECT * FROM orders", "", ""),
+                        new ClassificationResult(SupportedMCPStatement.EXPLAIN, "EXPLAIN", "EXPLAIN SELECT * FROM orders", "", List.of()),
                         createStatementConnection(true, 0, createResultSet(List.of(new ExecuteQueryColumnDefinition("plan", "VARCHAR", "VARCHAR", true)), List.of(List.of("plan")))),
                         ExecuteQueryResultKind.RESULT_SET, "EXPLAIN", 1, 0, "", false),
                 Arguments.of("dml update count", new SQLExecutionRequest("session-1", "logic_db", "public", "UPDATE orders SET status = 'DONE'", 10, 1000),
-                        new ClassificationResult(SupportedMCPStatement.DML, "UPDATE", "UPDATE orders SET status = 'DONE'", "", ""), createStatementConnection(false, 3, null),
+                        new ClassificationResult(SupportedMCPStatement.DML, "UPDATE", "UPDATE orders SET status = 'DONE'", "", List.of()), createStatementConnection(false, 3, null),
                         ExecuteQueryResultKind.UPDATE_COUNT, "UPDATE", 0, 3, "", false),
                 Arguments.of("ddl ack", new SQLExecutionRequest("session-1", "logic_db", "public", "CREATE TABLE orders_archive", 10, 1000),
-                        new ClassificationResult(SupportedMCPStatement.DDL, "CREATE", "CREATE TABLE orders_archive", "", ""), createStatementConnection(false, 0, null),
+                        new ClassificationResult(SupportedMCPStatement.DDL, "CREATE", "CREATE TABLE orders_archive", "", List.of()), createStatementConnection(false, 0, null),
                         ExecuteQueryResultKind.STATEMENT_ACK, "CREATE", 0, 0, "Statement executed.", false),
                 Arguments.of("dcl ack", new SQLExecutionRequest("session-1", "logic_db", "public", "GRANT SELECT ON orders TO app_user", 10, 1000),
-                        new ClassificationResult(SupportedMCPStatement.DCL, "GRANT", "GRANT SELECT ON orders TO app_user", "", ""), createStatementConnection(false, 0, null),
+                        new ClassificationResult(SupportedMCPStatement.DCL, "GRANT", "GRANT SELECT ON orders TO app_user", "", List.of()), createStatementConnection(false, 0, null),
                         ExecuteQueryResultKind.STATEMENT_ACK, "GRANT", 0, 0, "Statement executed.", false));
     }
     
diff --git a/mcp/core/src/test/java/org/apache/shardingsphere/mcp/core/tool/handler/execute/MCPJdbcTransactionStatementExecutorTest.java b/mcp/core/src/test/java/org/apache/shardingsphere/mcp/core/tool/handler/execute/MCPJdbcTransactionStatementExecutorTest.java
index 812dc9e4049..dc8a9137244 100644
--- a/mcp/core/src/test/java/org/apache/shardingsphere/mcp/core/tool/handler/execute/MCPJdbcTransactionStatementExecutorTest.java
+++ b/mcp/core/src/test/java/org/apache/shardingsphere/mcp/core/tool/handler/execute/MCPJdbcTransactionStatementExecutorTest.java
@@ -36,6 +36,7 @@ import java.sql.Connection;
 import java.sql.SQLException;
 import java.sql.Savepoint;
 import java.util.Collections;
+import java.util.List;
 import java.util.Map;
 import java.util.stream.Stream;
 
@@ -125,7 +126,7 @@ class MCPJdbcTransactionStatementExecutorTest {
         MCPJdbcTransactionStatementExecutor executor = new MCPJdbcTransactionStatementExecutor(sessionManager);
         MCPInvalidRequestException actual = assertThrows(MCPInvalidRequestException.class,
                 () -> executor.execute("session-1", "logic_db", createCapability(),
-                        new ClassificationResult(SupportedMCPStatement.SAVEPOINT, statementType, sql, "", "")));
+                        new ClassificationResult(SupportedMCPStatement.SAVEPOINT, statementType, sql, "", List.of())));
         assertThat(actual.getMessage(), is("Savepoint name is required."));
     }
     
diff --git a/mcp/core/src/test/java/org/apache/shardingsphere/mcp/core/tool/handler/execute/MCPSQLExecutionFacadeTest.java b/mcp/core/src/test/java/org/apache/shardingsphere/mcp/core/tool/handler/execute/MCPSQLExecutionFacadeTest.java
index 10f9c2ef0e9..c6671b35894 100644
--- a/mcp/core/src/test/java/org/apache/shardingsphere/mcp/core/tool/handler/execute/MCPSQLExecutionFacadeTest.java
+++ b/mcp/core/src/test/java/org/apache/shardingsphere/mcp/core/tool/handler/execute/MCPSQLExecutionFacadeTest.java
@@ -42,6 +42,7 @@ import org.mockito.ArgumentCaptor;
 import java.sql.SQLException;
 import java.sql.SQLSyntaxErrorException;
 import java.util.Collections;
+import java.util.List;
 import java.util.Optional;
 import java.util.Set;
 import java.util.function.Supplier;
@@ -88,7 +89,7 @@ class MCPSQLExecutionFacadeTest {
         SQLExecutionTraceFactory traceFactory = mock(SQLExecutionTraceFactory.class);
         SQLExecutionRequest request = createExecutionRequest("SELECT 1");
         MCPDatabaseCapability capability = createCapability(Set.of(SupportedMCPStatement.QUERY));
-        ClassificationResult classification = new ClassificationResult(SupportedMCPStatement.QUERY, "SELECT", "SELECT 1", "", "");
+        ClassificationResult classification = new ClassificationResult(SupportedMCPStatement.QUERY, "SELECT", "SELECT 1", "", List.of());
         SQLExecutionResponse response = mock(SQLExecutionResponse.class);
         ArgumentCaptor<Supplier<SQLExecutionResponse>> lockedExecution = ArgumentCaptor.forClass(Supplier.class);
         when(coordinator.executeWithSessionLock(eq("session-1"), lockedExecution.capture())).thenReturn(response);
@@ -151,7 +152,8 @@ class MCPSQLExecutionFacadeTest {
         MCPJdbcStatementExecutor statementExecutor = mock(MCPJdbcStatementExecutor.class);
         SQLExecutionTraceFactory traceFactory = mock(SQLExecutionTraceFactory.class);
         SQLExecutionRequest request = createExecutionRequest("SELECT 1");
-        ClassificationResult classification = new ClassificationResult(SupportedMCPStatement.QUERY, "SELECT", "SELECT 1", "orders", "");
+        ClassificationResult classification = new ClassificationResult(SupportedMCPStatement.QUERY, "SELECT", "SELECT 1", "",
+                List.of(SQLStatementObjectName.fromNormalizedName("orders")));
         MCPSQLExecutionFacade facade = createFacade(capabilityProvider, coordinator, transactionExecutor, statementExecutor, traceFactory, createStatementClassifier(classification));
         MCPDatabaseCapability capability = createCapability(Set.of(SupportedMCPStatement.DML));
         mockSessionLock(coordinator);
@@ -168,7 +170,7 @@ class MCPSQLExecutionFacadeTest {
         MCPSessionExecutionCoordinator coordinator = mock(MCPSessionExecutionCoordinator.class);
         MCPJdbcTransactionStatementExecutor transactionExecutor = mock(MCPJdbcTransactionStatementExecutor.class);
         MCPDatabaseCapability capability = createCapability(Set.of(SupportedMCPStatement.TRANSACTION_CONTROL));
-        ClassificationResult classification = new ClassificationResult(SupportedMCPStatement.TRANSACTION_CONTROL, "BEGIN", "BEGIN", "", "");
+        ClassificationResult classification = new ClassificationResult(SupportedMCPStatement.TRANSACTION_CONTROL, "BEGIN", "BEGIN", "", List.of());
         SQLExecutionResponse response = SQLExecutionResponse.statementAck(SupportedMCPStatement.TRANSACTION_CONTROL, "BEGIN", "Transaction started.");
         mockSessionLock(coordinator);
         when(capabilityProvider.provide("logic_db")).thenReturn(Optional.of(capability));
@@ -190,7 +192,8 @@ class MCPSQLExecutionFacadeTest {
         MCPSessionExecutionCoordinator coordinator = mock(MCPSessionExecutionCoordinator.class);
         MCPJdbcStatementExecutor statementExecutor = mock(MCPJdbcStatementExecutor.class);
         MCPDatabaseCapability capability = createCapability(Set.of(SupportedMCPStatement.QUERY));
-        ClassificationResult classification = new ClassificationResult(SupportedMCPStatement.QUERY, "SELECT", "SELECT 1", "orders", "");
+        ClassificationResult classification = new ClassificationResult(SupportedMCPStatement.QUERY, "SELECT", "SELECT 1", "",
+                List.of(SQLStatementObjectName.fromNormalizedName("orders")));
         SQLExecutionResponse response = SQLExecutionResponse.resultSet(SupportedMCPStatement.QUERY, "SELECT", Collections.emptyList(), Collections.emptyList(), false);
         mockSessionLock(coordinator);
         when(capabilityProvider.provide("logic_db")).thenReturn(Optional.of(capability));
@@ -215,7 +218,8 @@ class MCPSQLExecutionFacadeTest {
         SQLExecutionTraceFactory traceFactory = mock(SQLExecutionTraceFactory.class);
         MCPDatabaseCapability capability = createCapability(Set.of(SupportedMCPStatement.QUERY));
         SQLExecutionRequest request = createExecutionRequest("SELECT * FROM other_db.orders");
-        ClassificationResult classification = new ClassificationResult(SupportedMCPStatement.QUERY, "SELECT", "SELECT * FROM other_db.orders", "other_db.orders", "");
+        ClassificationResult classification = new ClassificationResult(SupportedMCPStatement.QUERY, "SELECT", "SELECT * FROM other_db.orders", "",
+                List.of(SQLStatementObjectName.fromNormalizedName("other_db.orders")));
         MCPSQLExecutionFacade facade = createFacade(capabilityProvider, coordinator, transactionExecutor, statementExecutor, traceFactory, createStatementClassifier(classification));
         mockSessionLock(coordinator);
         when(capabilityProvider.provide("logic_db")).thenReturn(Optional.of(capability));
@@ -271,7 +275,8 @@ class MCPSQLExecutionFacadeTest {
         SQLExecutionTraceFactory traceFactory = mock(SQLExecutionTraceFactory.class);
         MCPDatabaseCapability capability = createCapability(Set.of(SupportedMCPStatement.DML));
         SQLExecutionRequest request = createExecutionRequest("UPDATE other_db.orders SET status = 'DONE'");
-        ClassificationResult classification = new ClassificationResult(SupportedMCPStatement.DML, "UPDATE", "UPDATE other_db.orders SET status = 'DONE'", "other_db.orders", "");
+        ClassificationResult classification = new ClassificationResult(SupportedMCPStatement.DML, "UPDATE", "UPDATE other_db.orders SET status = 'DONE'", "",
+                List.of(SQLStatementObjectName.fromNormalizedName("other_db.orders")));
         MCPSQLExecutionFacade facade = createFacade(capabilityProvider, coordinator, transactionExecutor, statementExecutor, traceFactory, createStatementClassifier(classification));
         mockSessionLock(coordinator);
         when(capabilityProvider.provide("logic_db")).thenReturn(Optional.of(capability));
@@ -287,7 +292,8 @@ class MCPSQLExecutionFacadeTest {
         MCPSessionExecutionCoordinator coordinator = mock(MCPSessionExecutionCoordinator.class);
         MCPJdbcStatementExecutor statementExecutor = mock(MCPJdbcStatementExecutor.class);
         MCPDatabaseCapability capability = createCapability(Set.of(SupportedMCPStatement.QUERY));
-        ClassificationResult classification = new ClassificationResult(SupportedMCPStatement.QUERY, "SELECT", "SELECT * FROM logic_db.orders", "logic_db.orders", "");
+        ClassificationResult classification = new ClassificationResult(SupportedMCPStatement.QUERY, "SELECT", "SELECT * FROM logic_db.orders", "",
+                List.of(SQLStatementObjectName.fromNormalizedName("logic_db.orders")));
         SQLExecutionResponse response = SQLExecutionResponse.resultSet(SupportedMCPStatement.QUERY, "SELECT", Collections.emptyList(), Collections.emptyList(), false);
         mockSessionLock(coordinator);
         when(capabilityProvider.provide("logic_db")).thenReturn(Optional.of(capability));
@@ -340,7 +346,8 @@ class MCPSQLExecutionFacadeTest {
         MCPSessionExecutionCoordinator coordinator = mock(MCPSessionExecutionCoordinator.class);
         MCPJdbcStatementExecutor statementExecutor = mock(MCPJdbcStatementExecutor.class);
         MCPDatabaseCapability capability = createCapability(Set.of(SupportedMCPStatement.QUERY), SchemaExecutionSemantics.BEST_EFFORT);
-        ClassificationResult classification = new ClassificationResult(SupportedMCPStatement.QUERY, "SELECT", "SELECT * FROM other_db.orders", "other_db.orders", "");
+        ClassificationResult classification = new ClassificationResult(SupportedMCPStatement.QUERY, "SELECT", "SELECT * FROM other_db.orders", "",
+                List.of(SQLStatementObjectName.fromNormalizedName("other_db.orders")));
         SQLExecutionResponse response = SQLExecutionResponse.resultSet(SupportedMCPStatement.QUERY, "SELECT", Collections.emptyList(), Collections.emptyList(), false);
         mockSessionLock(coordinator);
         when(capabilityProvider.provide("logic_db")).thenReturn(Optional.of(capability));
@@ -362,7 +369,8 @@ class MCPSQLExecutionFacadeTest {
         MCPSessionExecutionCoordinator coordinator = mock(MCPSessionExecutionCoordinator.class);
         MCPDatabaseCapability capability = createCapability(Set.of(SupportedMCPStatement.QUERY));
         SQLExecutionRequest request = createExecutionRequest("SELECT 1");
-        ClassificationResult classification = new ClassificationResult(SupportedMCPStatement.QUERY, "SELECT", "SELECT 1", "orders", "");
+        ClassificationResult classification = new ClassificationResult(SupportedMCPStatement.QUERY, "SELECT", "SELECT 1", "",
+                List.of(SQLStatementObjectName.fromNormalizedName("orders")));
         mockSessionLock(coordinator);
         when(capabilityProvider.provide("logic_db")).thenReturn(Optional.of(capability));
         MCPJdbcStatementExecutor statementExecutor = mock(MCPJdbcStatementExecutor.class);
diff --git a/mcp/core/src/test/java/org/apache/shardingsphere/mcp/core/tool/handler/execute/RuleDistSQLExecutionExceptionTest.java b/mcp/core/src/test/java/org/apache/shardingsphere/mcp/core/tool/handler/execute/RuleDistSQLExecutionExceptionTest.java
index e3970ac37d4..777c0e1d3ce 100644
--- a/mcp/core/src/test/java/org/apache/shardingsphere/mcp/core/tool/handler/execute/RuleDistSQLExecutionExceptionTest.java
+++ b/mcp/core/src/test/java/org/apache/shardingsphere/mcp/core/tool/handler/execute/RuleDistSQLExecutionExceptionTest.java
@@ -21,6 +21,7 @@ import org.apache.shardingsphere.mcp.support.database.capability.SupportedMCPSta
 import org.junit.jupiter.api.Test;
 
 import java.sql.SQLSyntaxErrorException;
+import java.util.List;
 
 import static org.hamcrest.MatcherAssert.assertThat;
 import static org.hamcrest.Matchers.is;
@@ -30,7 +31,7 @@ class RuleDistSQLExecutionExceptionTest {
     @Test
     void assertRuleDistSQLExecutionException() {
         ClassificationResult classificationResult = new ClassificationResult(SupportedMCPStatement.DDL, "CREATE",
-                "CREATE SHARDING TABLE RULE t_order(DATANODES('ds_${0..1}.t_order_${0..1}'))", "", "");
+                "CREATE SHARDING TABLE RULE t_order(DATANODES('ds_${0..1}.t_order_${0..1}'))", "", List.of());
         SQLSyntaxErrorException cause = new SQLSyntaxErrorException("syntax error");
         RuleDistSQLExecutionException actual = new RuleDistSQLExecutionException("sharding_db", classificationResult, cause);
         assertThat(actual.getMessage(),