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

FrankChen021 pushed a commit to branch codex/fix-invalid-timestamp-constant
in repository https://gitbox.apache.org/repos/asf/druid.git

commit 077a3d030f5ac268af876c2023bf688f1724d657
Author: Frank Chen <[email protected]>
AuthorDate: Fri Sep 11 18:16:03 2026 +0800

    test(sql): cover invalid timestamp expression forms
---
 .../sql/calcite/planner/DruidRexExecutor.java      | 13 +++++--
 .../org/apache/druid/sql/http/SqlResourceTest.java | 40 ++++++++++++++++++++++
 2 files changed, 50 insertions(+), 3 deletions(-)

diff --git 
a/sql/src/main/java/org/apache/druid/sql/calcite/planner/DruidRexExecutor.java 
b/sql/src/main/java/org/apache/druid/sql/calcite/planner/DruidRexExecutor.java
index 7c14c98ac67..378a89f25b8 100644
--- 
a/sql/src/main/java/org/apache/druid/sql/calcite/planner/DruidRexExecutor.java
+++ 
b/sql/src/main/java/org/apache/druid/sql/calcite/planner/DruidRexExecutor.java
@@ -118,7 +118,10 @@ public class DruidRexExecutor implements RexExecutor
               // There can be implicit casts of VARCHAR to TIMESTAMP where the 
VARCHAR is an invalid timestamp, but the
               // TIMESTAMP type is not nullable. In this case it's best to 
throw an error, since it likely means the
               // user's SQL query contains an invalid literal.
-              throw InvalidSqlInput.exception("Invalid TIMESTAMP value [%s]", 
getTimestampValue(constExp));
+              throw InvalidSqlInput.exception(
+                  "Invalid TIMESTAMP value [%s]",
+                  getInputValueOrExpression(constExp)
+              );
             }
           } else {
             try {
@@ -130,7 +133,11 @@ public class DruidRexExecutor implements RexExecutor
               );
             }
             catch (IllegalArgumentException e) {
-              throw InvalidSqlInput.exception(e, "Invalid TIMESTAMP value 
[%s]", getTimestampValue(constExp));
+              throw InvalidSqlInput.exception(
+                  e,
+                  "Invalid TIMESTAMP value [%s]",
+                  getInputValueOrExpression(constExp)
+              );
             }
           }
         } else if (SqlTypeName.NUMERIC_TYPES.contains(sqlTypeName)) {
@@ -229,7 +236,7 @@ public class DruidRexExecutor implements RexExecutor
     }
   }
 
-  private static String getTimestampValue(final RexNode constExp)
+  private static String getInputValueOrExpression(final RexNode constExp)
   {
     if (constExp.isA(SqlKind.CAST)) {
       final RexNode operand = ((RexCall) constExp).getOperands().get(0);
diff --git a/sql/src/test/java/org/apache/druid/sql/http/SqlResourceTest.java 
b/sql/src/test/java/org/apache/druid/sql/http/SqlResourceTest.java
index 668d3dcd792..0909be0671c 100644
--- a/sql/src/test/java/org/apache/druid/sql/http/SqlResourceTest.java
+++ b/sql/src/test/java/org/apache/druid/sql/http/SqlResourceTest.java
@@ -1619,6 +1619,46 @@ public class SqlResourceTest extends CalciteTestBase
     );
   }
 
+  @Test
+  public void testInvalidTimestampExpressionWithoutCast() throws Exception
+  {
+    final ErrorResponse errorResponse = postSyncForException(
+        "SELECT MILLIS_TO_TIMESTAMP(253402300800000)",
+        Status.BAD_REQUEST.getStatusCode()
+    );
+
+    validateInvalidSqlError(
+        errorResponse,
+        "Invalid TIMESTAMP value [MILLIS_TO_TIMESTAMP(253402300800000:BIGINT)]"
+    );
+    Assertions.assertTrue(lifecycleManager.getAll("id").isEmpty());
+    stubServiceEmitter.verifyEmitted("sqlQuery/time", 1);
+    Assertions.assertEquals(
+        Status.BAD_REQUEST.getStatusCode(),
+        
stubServiceEmitter.getMetricEvents("sqlQuery/time").get(0).toMap().get(DruidMetrics.STATUS_CODE)
+    );
+  }
+
+  @Test
+  public void testInvalidTimestampLiteralWithExplicitCast() throws Exception
+  {
+    final ErrorResponse errorResponse = postSyncForException(
+        "SELECT CAST('20260-09-11 00:00:00' AS TIMESTAMP)",
+        Status.BAD_REQUEST.getStatusCode()
+    );
+
+    validateInvalidSqlError(
+        errorResponse,
+        "Invalid TIMESTAMP value [20260-09-11 00:00:00]"
+    );
+    Assertions.assertTrue(lifecycleManager.getAll("id").isEmpty());
+    stubServiceEmitter.verifyEmitted("sqlQuery/time", 1);
+    Assertions.assertEquals(
+        Status.BAD_REQUEST.getStatusCode(),
+        
stubServiceEmitter.getMetricEvents("sqlQuery/time").get(0).toMap().get(DruidMetrics.STATUS_CODE)
+    );
+  }
+
   @Test
   public void testResourceLimitExceeded() throws Exception
   {


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to