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 9d31ee55253 Upgrade Jackson to 2.22.3 and fix MCP date validation 
(#40121)
9d31ee55253 is described below

commit 9d31ee5525337fde6fdff9ef41bc08dd0d00fb84
Author: Liang Zhang <[email protected]>
AuthorDate: Sat Oct 10 10:12:58 2026 +0800

    Upgrade Jackson to 2.22.3 and fix MCP date validation (#40121)
---
 .../capability/tool/MCPCallToolResultFactory.java  |  3 +-
 .../tool/MCPCallToolResultFactoryTest.java         | 35 ++++++++++++++++++++++
 pom.xml                                            |  2 +-
 3 files changed, 38 insertions(+), 2 deletions(-)

diff --git 
a/mcp/bootstrap/src/main/java/org/apache/shardingsphere/mcp/bootstrap/transport/capability/tool/MCPCallToolResultFactory.java
 
b/mcp/bootstrap/src/main/java/org/apache/shardingsphere/mcp/bootstrap/transport/capability/tool/MCPCallToolResultFactory.java
index d73f2321aee..348af79b8f1 100644
--- 
a/mcp/bootstrap/src/main/java/org/apache/shardingsphere/mcp/bootstrap/transport/capability/tool/MCPCallToolResultFactory.java
+++ 
b/mcp/bootstrap/src/main/java/org/apache/shardingsphere/mcp/bootstrap/transport/capability/tool/MCPCallToolResultFactory.java
@@ -18,6 +18,7 @@
 package org.apache.shardingsphere.mcp.bootstrap.transport.capability.tool;
 
 import io.modelcontextprotocol.json.McpJsonMapper;
+import io.modelcontextprotocol.json.jackson2.JacksonMcpJsonMapper;
 import io.modelcontextprotocol.json.schema.JsonSchemaValidator;
 import 
io.modelcontextprotocol.json.schema.JsonSchemaValidator.ValidationResponse;
 import io.modelcontextprotocol.json.schema.jackson2.DefaultJsonSchemaValidator;
@@ -41,7 +42,7 @@ final class MCPCallToolResultFactory {
     
     private final McpJsonMapper jsonMapper = 
MCPTransportJsonMapperFactory.create();
     
-    private final JsonSchemaValidator outputSchemaValidator = new 
DefaultJsonSchemaValidator();
+    private final JsonSchemaValidator outputSchemaValidator = new 
DefaultJsonSchemaValidator(((JacksonMcpJsonMapper) 
jsonMapper).getObjectMapper());
     
     CallToolResult create(final MCPToolDescriptor descriptor, final 
MCPSuccessPayload successPayload) {
         Map<String, Object> payload = successPayload.toPayload();
diff --git 
a/mcp/bootstrap/src/test/java/org/apache/shardingsphere/mcp/bootstrap/transport/capability/tool/MCPCallToolResultFactoryTest.java
 
b/mcp/bootstrap/src/test/java/org/apache/shardingsphere/mcp/bootstrap/transport/capability/tool/MCPCallToolResultFactoryTest.java
index e561d13ea06..5e51e8b991b 100644
--- 
a/mcp/bootstrap/src/test/java/org/apache/shardingsphere/mcp/bootstrap/transport/capability/tool/MCPCallToolResultFactoryTest.java
+++ 
b/mcp/bootstrap/src/test/java/org/apache/shardingsphere/mcp/bootstrap/transport/capability/tool/MCPCallToolResultFactoryTest.java
@@ -60,6 +60,7 @@ import 
org.apache.shardingsphere.mcp.support.workflow.service.WorkflowPlanPayloa
 import org.junit.jupiter.api.Test;
 import org.mockito.MockedStatic;
 
+import java.time.OffsetDateTime;
 import java.util.List;
 import java.util.Map;
 
@@ -144,6 +145,40 @@ class MCPCallToolResultFactoryTest extends 
AbstractMCPToolSpecificationFactoryTe
                         + "Use a separate read-only query if more data is 
needed."));
     }
     
+    @Test
+    void assertCreateWithPreEpochOffsetDateTime() {
+        OffsetDateTime expectedDate = 
OffsetDateTime.parse("1969-12-31T23:59:59.500Z");
+        SQLExecutionColumnDefinition column = new 
SQLExecutionColumnDefinition("foo_observed_at", "TIMESTAMP_WITH_TIMEZONE", 
"TIMESTAMP WITH TIME ZONE", false);
+        MCPSuccessPayload response = 
SQLExecutionPayload.query(SQLExecutionResult.resultSet(SupportedMCPStatement.QUERY,
 "SELECT",
+                List.of(column), List.of(List.of(expectedDate)), false, 1, 0, 
"SELECT foo_observed_at FROM foo_table"));
+        MCPToolDescriptor descriptor = 
ToolDefinitionRegistry.getToolDefinition(CoreToolNames.EXECUTE_QUERY).getDescriptor();
+        CallToolResult actual = new 
MCPCallToolResultFactory().create(descriptor, response);
+        assertFalse(actual.isError(), () -> String.valueOf(actual.content()));
+        Map<String, Object> actualPayload = getStructuredContent(actual);
+        assertThat(actualPayload.get("rows"), 
is(List.of(List.of(expectedDate))));
+        assertThat(actualPayload.get("row_objects"), 
is(List.of(Map.of("foo_observed_at", expectedDate))));
+        Map<String, Object> actualTextPayload = getTextContentPayload(actual);
+        assertThat(actualTextPayload.get("rows"), is(List.of(List.of(-0.5D))));
+        assertThat(actualTextPayload.get("row_objects"), 
is(List.of(Map.of("foo_observed_at", -0.5D))));
+    }
+    
+    @Test
+    void assertCreateWithPostEpochOffsetDateTime() {
+        OffsetDateTime expectedDate = 
OffsetDateTime.parse("1970-01-01T00:00:00.500Z");
+        SQLExecutionColumnDefinition column = new 
SQLExecutionColumnDefinition("foo_observed_at", "TIMESTAMP_WITH_TIMEZONE", 
"TIMESTAMP WITH TIME ZONE", false);
+        MCPSuccessPayload response = 
SQLExecutionPayload.query(SQLExecutionResult.resultSet(SupportedMCPStatement.QUERY,
 "SELECT",
+                List.of(column), List.of(List.of(expectedDate)), false, 1, 0, 
"SELECT foo_observed_at FROM foo_table"));
+        MCPToolDescriptor descriptor = 
ToolDefinitionRegistry.getToolDefinition(CoreToolNames.EXECUTE_QUERY).getDescriptor();
+        CallToolResult actual = new 
MCPCallToolResultFactory().create(descriptor, response);
+        assertFalse(actual.isError(), () -> String.valueOf(actual.content()));
+        Map<String, Object> actualPayload = getStructuredContent(actual);
+        assertThat(actualPayload.get("rows"), 
is(List.of(List.of(expectedDate))));
+        assertThat(actualPayload.get("row_objects"), 
is(List.of(Map.of("foo_observed_at", expectedDate))));
+        Map<String, Object> actualTextPayload = getTextContentPayload(actual);
+        assertThat(actualTextPayload.get("rows"), is(List.of(List.of(0.5D))));
+        assertThat(actualTextPayload.get("row_objects"), 
is(List.of(Map.of("foo_observed_at", 0.5D))));
+    }
+    
     @Test
     void assertCreateWithMaskWorkflowPlanSchema() {
         CallToolResult actual = 
createRealDescriptorCallToolResult(MaskFeatureDefinition.PLAN_TOOL_NAME, 
createMaskPlanResponse());
diff --git a/pom.xml b/pom.xml
index 816efd76d69..47b2026e8a8 100644
--- a/pom.xml
+++ b/pom.xml
@@ -94,7 +94,7 @@
         <antlr4.version>4.13.2</antlr4.version>
         <snakeyaml.version>2.2</snakeyaml.version>
         <gson.version>2.10.1</gson.version>
-        <jackson.version>2.18.6</jackson.version>
+        <jackson.version>2.22.3</jackson.version>
         <json-path.version>2.10.0</json-path.version>
         <json-smart.version>2.6.0</json-smart.version>
         <accessors-smart.version>2.6.0</accessors-smart.version>

Reply via email to