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 7c34e857164 Simplify MCP validation and verify runtime limits (#39299)
7c34e857164 is described below

commit 7c34e8571640da5c1a6098733e6f780c03ba35b0
Author: Liang Zhang <[email protected]>
AuthorDate: Sat Aug 1 11:49:11 2026 +0800

    Simplify MCP validation and verify runtime limits (#39299)
    
    * Fix Oracle pre-12.2 column case sensitivity
    
    Use Oracle's default case-sensitive behavior for character columns
    when COLLATION metadata is unavailable before version 12.2.
    
    Reuse the Oracle data type classification for non-character columns
    and preserve the existing 12.2+ collation handling.
    
    * Fix Oracle pre-12.2 column case sensitivity
    
    Use Oracle's default case-sensitive behavior for character columns
    when COLLATION metadata is unavailable before version 12.2.
    
    Reuse the Oracle data type classification for non-character columns
    and preserve the existing 12.2+ collation handling.
    
    * Simplify MCP validation and verify runtime limits
    
    Simplify create and drop workflow state checks by comparing the
    expected and actual rule state directly.
    
    Verify that SQL execution tool descriptors remain aligned with MCP
    runtime row and timeout limits.
    
    * Simplify MCP validation and verify runtime limits
    
    Simplify create and drop workflow state checks by comparing the
    expected and actual rule state directly.
    
    Verify that SQL execution tool descriptors remain aligned with MCP
    runtime row and timeout limits.
---
 .github/workflows/e2e-mcp.yml                            |  2 ++
 .../core/tool/handler/ToolDefinitionRegistryTest.java    | 15 +++++++++++++++
 .../tool/service/BroadcastWorkflowValidationService.java |  3 ++-
 .../ReadwriteSplittingRuleWorkflowValidationService.java | 11 ++++++-----
 .../tool/service/ShardingWorkflowValidationService.java  | 16 ++++++++++------
 5 files changed, 35 insertions(+), 12 deletions(-)

diff --git a/.github/workflows/e2e-mcp.yml b/.github/workflows/e2e-mcp.yml
index 1f727ad1736..e587e63192d 100644
--- a/.github/workflows/e2e-mcp.yml
+++ b/.github/workflows/e2e-mcp.yml
@@ -311,6 +311,8 @@ jobs:
           restore-maven-repository: 'false'
           docker-image-archives: mcp-llm-runtime-image.tar
       - name: Run MCP LLM E2E
+        env:
+          TESTCONTAINERS_RYUK_DISABLED: 'true'
         run: ./mvnw -pl test/e2e/mcp test -Pe2e.mcp.llm -DskipITs 
-Dspotless.skip=true -Dtest='${{ matrix.test }}' -Dmcp.llm.artifact-root="${{ 
github.workspace }}/test/e2e/mcp/target/llm-e2e" -Dmcp.llm.run-id=gha-${{ 
github.run_id }}-${{ github.run_attempt }}-${{ matrix.id }} -B -ntp
       - name: Upload MCP LLM E2E Artifacts
         if: always()
diff --git 
a/mcp/core/src/test/java/org/apache/shardingsphere/mcp/core/tool/handler/ToolDefinitionRegistryTest.java
 
b/mcp/core/src/test/java/org/apache/shardingsphere/mcp/core/tool/handler/ToolDefinitionRegistryTest.java
index 4526ba00b2b..6df3f9e4ff8 100644
--- 
a/mcp/core/src/test/java/org/apache/shardingsphere/mcp/core/tool/handler/ToolDefinitionRegistryTest.java
+++ 
b/mcp/core/src/test/java/org/apache/shardingsphere/mcp/core/tool/handler/ToolDefinitionRegistryTest.java
@@ -35,6 +35,7 @@ import 
org.apache.shardingsphere.mcp.core.protocol.exception.MCPToolArgumentCont
 import 
org.apache.shardingsphere.mcp.core.protocol.exception.UnsupportedToolException;
 import org.apache.shardingsphere.mcp.core.resource.ResourceTestDataFactory;
 import 
org.apache.shardingsphere.mcp.core.resource.ResourceTestDataFactory.RequestContextFixture;
+import 
org.apache.shardingsphere.mcp.support.security.MCPRuntimeProtectionPolicy;
 import org.junit.jupiter.api.Test;
 import org.mockito.MockedStatic;
 import org.mockito.internal.configuration.plugins.Plugins;
@@ -81,6 +82,20 @@ class ToolDefinitionRegistryTest {
         assertField(actual.get(5), "approved_steps", "array", List.of(), 
false);
     }
     
+    @Test
+    void assertGetSupportedToolDescriptorsWithRuntimeProtectionLimits() {
+        List<MCPToolDescriptor> descriptors = 
ToolDefinitionRegistry.getSupportedToolDescriptors();
+        for (String each : List.of("database_gateway_execute_query", 
"database_gateway_execute_explain_query", "database_gateway_execute_update")) {
+            MCPToolDescriptor descriptor = descriptors.stream().filter(tool -> 
each.equals(tool.getName())).findFirst().orElseThrow();
+            Map<?, ?> actualMaxRows = findField(descriptor, "max_rows");
+            assertThat(actualMaxRows.get("default"), 
is(MCPRuntimeProtectionPolicy.DEFAULT_MAX_ROWS));
+            assertThat(actualMaxRows.get("maximum"), 
is(MCPRuntimeProtectionPolicy.MAX_ROWS_LIMIT));
+            Map<?, ?> actualTimeout = findField(descriptor, "timeout_ms");
+            assertThat(actualTimeout.get("default"), 
is(MCPRuntimeProtectionPolicy.DEFAULT_TIMEOUT_MILLISECONDS));
+            assertThat(actualTimeout.get("maximum"), 
is(MCPRuntimeProtectionPolicy.MAX_TIMEOUT_MILLISECONDS));
+        }
+    }
+    
     @Test
     void assertGetToolDefinition() {
         
assertThat(ToolDefinitionRegistry.getToolDefinition("database_gateway_search_metadata").getDescriptor().getName(),
 is("database_gateway_search_metadata"));
diff --git 
a/mcp/features/broadcast/src/main/java/org/apache/shardingsphere/mcp/feature/broadcast/tool/service/BroadcastWorkflowValidationService.java
 
b/mcp/features/broadcast/src/main/java/org/apache/shardingsphere/mcp/feature/broadcast/tool/service/BroadcastWorkflowValidationService.java
index 14fc41c2309..ccee76bb073 100644
--- 
a/mcp/features/broadcast/src/main/java/org/apache/shardingsphere/mcp/feature/broadcast/tool/service/BroadcastWorkflowValidationService.java
+++ 
b/mcp/features/broadcast/src/main/java/org/apache/shardingsphere/mcp/feature/broadcast/tool/service/BroadcastWorkflowValidationService.java
@@ -75,10 +75,11 @@ public final class BroadcastWorkflowValidationService 
implements MCPWorkflowRunt
                                             final ValidationReport 
validationReport, final MCPFeatureQueryFacade queryFacade) {
         BroadcastWorkflowRequest request = (BroadcastWorkflowRequest) 
snapshot.getRequest();
         boolean dropWorkflow = WorkflowLifecycleUtils.isDropWorkflow(snapshot);
+        boolean expectedRuleExists = !dropWorkflow;
         for (String each : request.getTargetTables()) {
             boolean ruleExists = broadcastRules.stream().anyMatch(rule -> 
queryFacade.isSameIdentifier(
                     request.getDatabase(), IdentifierScope.TABLE, each, 
WorkflowRuleValueUtils.getRuleValue(rule, "broadcast_table")));
-            if (dropWorkflow && ruleExists || !dropWorkflow && !ruleExists) {
+            if (expectedRuleExists != ruleExists) {
                 addRuleMismatch(validationReport, dropWorkflow, each);
                 return new ValidationSection(WorkflowLifecycle.STATUS_FAILED, 
broadcastRules, "Broadcast rule state does not match the planned DistSQL 
artifact.");
             }
diff --git 
a/mcp/features/readwrite-splitting/src/main/java/org/apache/shardingsphere/mcp/feature/readwritesplitting/tool/service/ReadwriteSplittingRuleWorkflowValidationService.java
 
b/mcp/features/readwrite-splitting/src/main/java/org/apache/shardingsphere/mcp/feature/readwritesplitting/tool/service/ReadwriteSplittingRuleWorkflowValidationService.java
index 9b6f329392f..daafcaa809e 100644
--- 
a/mcp/features/readwrite-splitting/src/main/java/org/apache/shardingsphere/mcp/feature/readwritesplitting/tool/service/ReadwriteSplittingRuleWorkflowValidationService.java
+++ 
b/mcp/features/readwrite-splitting/src/main/java/org/apache/shardingsphere/mcp/feature/readwritesplitting/tool/service/ReadwriteSplittingRuleWorkflowValidationService.java
@@ -81,10 +81,9 @@ public final class 
ReadwriteSplittingRuleWorkflowValidationService implements MC
     }
     
     private void addRuleDistSQLIssues(final List<Map<String, Object>> issues, 
final WorkflowContextSnapshot snapshot, final String sql, final String 
displaySql) {
-        if (!isReadwriteSplittingRuleDistSQL(sql) || !(snapshot.getRequest() 
instanceof ReadwriteSplittingRuleWorkflowRequest)) {
+        if (!isReadwriteSplittingRuleDistSQL(sql) || !(snapshot.getRequest() 
instanceof final ReadwriteSplittingRuleWorkflowRequest request)) {
             return;
         }
-        ReadwriteSplittingRuleWorkflowRequest request = 
(ReadwriteSplittingRuleWorkflowRequest) snapshot.getRequest();
         addLoadBalancerIssue(issues, request, displaySql);
         addWeightIssues(issues, request, displaySql);
     }
@@ -142,11 +141,13 @@ public final class 
ReadwriteSplittingRuleWorkflowValidationService implements MC
                                             final ValidationReport 
validationReport, final MCPFeatureQueryFacade queryFacade) {
         ReadwriteSplittingRuleWorkflowRequest request = 
(ReadwriteSplittingRuleWorkflowRequest) snapshot.getRequest();
         boolean ruleExists = containsRule(rules, queryFacade, 
request.getDatabase(), request.getRuleName());
-        if (WorkflowLifecycleUtils.isDropWorkflow(snapshot) && ruleExists || 
!WorkflowLifecycleUtils.isDropWorkflow(snapshot) && !ruleExists) {
-            addRuleMismatch(validationReport, request.getRuleName(), 
WorkflowLifecycleUtils.isDropWorkflow(snapshot));
+        boolean dropWorkflow = WorkflowLifecycleUtils.isDropWorkflow(snapshot);
+        boolean expectedRuleExists = !dropWorkflow;
+        if (expectedRuleExists != ruleExists) {
+            addRuleMismatch(validationReport, request.getRuleName(), 
dropWorkflow);
             return new ValidationSection(WorkflowLifecycle.STATUS_FAILED, 
rules, "Readwrite-splitting rule state does not match the planned DistSQL 
artifact.");
         }
-        if (!WorkflowLifecycleUtils.isDropWorkflow(snapshot) && 
!matchesRuleShape(rules, queryFacade, request)) {
+        if (!dropWorkflow && !matchesRuleShape(rules, queryFacade, request)) {
             addRuleShapeMismatch(validationReport, request.getRuleName());
             return new ValidationSection(WorkflowLifecycle.STATUS_FAILED, 
rules, "Readwrite-splitting rule fields do not match the planned DistSQL 
artifact.");
         }
diff --git 
a/mcp/features/sharding/src/main/java/org/apache/shardingsphere/mcp/feature/sharding/tool/service/ShardingWorkflowValidationService.java
 
b/mcp/features/sharding/src/main/java/org/apache/shardingsphere/mcp/feature/sharding/tool/service/ShardingWorkflowValidationService.java
index 5b68ec393d2..1b5d3786dc9 100644
--- 
a/mcp/features/sharding/src/main/java/org/apache/shardingsphere/mcp/feature/sharding/tool/service/ShardingWorkflowValidationService.java
+++ 
b/mcp/features/sharding/src/main/java/org/apache/shardingsphere/mcp/feature/sharding/tool/service/ShardingWorkflowValidationService.java
@@ -110,12 +110,14 @@ public final class ShardingWorkflowValidationService 
implements MCPWorkflowRunti
     private ValidationSection validateNamedState(final WorkflowContextSnapshot 
snapshot, final ValidationReport validationReport,
                                                  final List<Map<String, 
Object>> rows, final MCPFeatureQueryFacade queryFacade, final String 
databaseName,
                                                  final String fieldName, final 
String expected, final boolean shapeMatches) {
-        boolean exists = containsNamedRow(rows, queryFacade, databaseName, 
fieldName, expected);
-        if (WorkflowLifecycleUtils.isDropWorkflow(snapshot) && exists || 
!WorkflowLifecycleUtils.isDropWorkflow(snapshot) && !exists) {
+        boolean ruleExists = containsNamedRow(rows, queryFacade, databaseName, 
fieldName, expected);
+        boolean dropWorkflow = WorkflowLifecycleUtils.isDropWorkflow(snapshot);
+        boolean expectedRuleExists = !dropWorkflow;
+        if (expectedRuleExists != ruleExists) {
             addMismatch(validationReport, fieldName, expected);
             return new ValidationSection(WorkflowLifecycle.STATUS_FAILED, 
rows, "Sharding rule state does not match the planned DistSQL artifact.");
         }
-        if (!WorkflowLifecycleUtils.isDropWorkflow(snapshot) && !shapeMatches) 
{
+        if (!dropWorkflow && !shapeMatches) {
             addMismatch(validationReport, fieldName, expected);
             return new ValidationSection(WorkflowLifecycle.STATUS_FAILED, 
rows, "Sharding rule fields do not match the planned DistSQL artifact.");
         }
@@ -216,13 +218,15 @@ public final class ShardingWorkflowValidationService 
implements MCPWorkflowRunti
     
     private ValidationSection validateDefaultStrategy(final 
WorkflowContextSnapshot snapshot, final ValidationReport validationReport,
                                                       final List<Map<String, 
Object>> rows, final MCPFeatureQueryFacade queryFacade, final 
ShardingWorkflowRequest request) {
-        boolean exists = rows.stream().anyMatch(each -> 
queryFacade.isSameIdentifier(request.getDatabase(), IdentifierScope.TABLE, 
request.getDefaultStrategyType(),
+        boolean strategyExists = rows.stream().anyMatch(each -> 
queryFacade.isSameIdentifier(request.getDatabase(), IdentifierScope.TABLE, 
request.getDefaultStrategyType(),
                 WorkflowRuleValueUtils.getRuleValue(each, "name")) && 
!WorkflowRuleValueUtils.getRuleValue(each, "type").isEmpty());
-        if (WorkflowLifecycleUtils.isDropWorkflow(snapshot) && exists || 
!WorkflowLifecycleUtils.isDropWorkflow(snapshot) && !exists) {
+        boolean dropWorkflow = WorkflowLifecycleUtils.isDropWorkflow(snapshot);
+        boolean expectedStrategyExists = !dropWorkflow;
+        if (expectedStrategyExists != strategyExists) {
             addMismatch(validationReport, "name", 
request.getDefaultStrategyType());
             return new ValidationSection(WorkflowLifecycle.STATUS_FAILED, 
rows, "Default sharding strategy state does not match the planned DistSQL 
artifact.");
         }
-        if (!WorkflowLifecycleUtils.isDropWorkflow(snapshot) && 
!matchesDefaultStrategy(rows, queryFacade, request)) {
+        if (!dropWorkflow && !matchesDefaultStrategy(rows, queryFacade, 
request)) {
             addMismatch(validationReport, "name", 
request.getDefaultStrategyType());
             return new ValidationSection(WorkflowLifecycle.STATUS_FAILED, 
rows, "Default sharding strategy fields do not match the planned DistSQL 
artifact.");
         }

Reply via email to