You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@spark.apache.org by we...@apache.org on 2020/05/18 05:02:33 UTC

[spark] branch branch-3.0 updated: [SPARK-31727][SQL] Fix error message of casting timestamp to int in ANSI non-codegen mode

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

wenchen pushed a commit to branch branch-3.0
in repository https://gitbox.apache.org/repos/asf/spark.git


The following commit(s) were added to refs/heads/branch-3.0 by this push:
     new 5955933  [SPARK-31727][SQL] Fix error message of casting timestamp to int in ANSI non-codegen mode
5955933 is described below

commit 5955933cd037cc2cc0b0b0aaab19457ff050b4fe
Author: Max Gekk <ma...@gmail.com>
AuthorDate: Mon May 18 05:00:50 2020 +0000

    [SPARK-31727][SQL] Fix error message of casting timestamp to int in ANSI non-codegen mode
    
    ### What changes were proposed in this pull request?
    Change timestamp casting to int in ANSI and non-codegen mode, and make the error message consistent to the error messages in the codegen mode. In particular, casting to int is implemented in the same way as casting to short and byte.
    
    ### Why are the changes needed?
    1. The error message in the non-codegen mode is diversed from the error message in the codegen mode.
    2. The error message contains intermediate results that could confuse.
    
    ### Does this PR introduce _any_ user-facing change?
    Yes. Before the changes, the error message of casting timestamp to int contains intermediate result but after the changes it contains the input values which causes arithmetic overflow.
    
    ### How was this patch tested?
    By running the modified test suite `AnsiCastSuite`.
    
    Closes #28549 from MaxGekk/fix-error-msg-cast-timestamp.
    
    Authored-by: Max Gekk <ma...@gmail.com>
    Signed-off-by: Wenchen Fan <we...@databricks.com>
    (cherry picked from commit fc5b90243ca1cd460988735dd4170b533d73e8e5)
    Signed-off-by: Wenchen Fan <we...@databricks.com>
---
 .../scala/org/apache/spark/sql/catalyst/expressions/Cast.scala |  9 ++++++++-
 .../org/apache/spark/sql/catalyst/expressions/CastSuite.scala  | 10 ++++------
 2 files changed, 12 insertions(+), 7 deletions(-)

diff --git a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/Cast.scala b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/Cast.scala
index fa615d7..9bc86d4 100644
--- a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/Cast.scala
+++ b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/Cast.scala
@@ -511,7 +511,14 @@ abstract class CastBase extends UnaryExpression with TimeZoneAwareExpression wit
     case DateType =>
       buildCast[Int](_, d => null)
     case TimestampType if ansiEnabled =>
-      buildCast[Long](_, t => LongExactNumeric.toInt(timestampToLong(t)))
+      buildCast[Long](_, t => {
+        val longValue = timestampToLong(t)
+        if (longValue == longValue.toInt) {
+          longValue.toInt
+        } else {
+          throw new ArithmeticException(s"Casting $t to int causes overflow")
+        }
+      })
     case TimestampType =>
       buildCast[Long](_, t => timestampToLong(t).toInt)
     case x: NumericType if ansiEnabled =>
diff --git a/sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/expressions/CastSuite.scala b/sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/expressions/CastSuite.scala
index 334b43e..fd0ba67 100644
--- a/sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/expressions/CastSuite.scala
+++ b/sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/expressions/CastSuite.scala
@@ -1355,16 +1355,14 @@ class AnsiCastSuite extends CastSuiteBase {
   }
 
   test("cast a timestamp before the epoch 1970-01-01 00:00:00Z") {
+    def errMsg(t: String): String = s"Casting -2198208303900000 to $t causes overflow"
     withDefaultTimeZone(UTC) {
       val negativeTs = Timestamp.valueOf("1900-05-05 18:34:56.1")
       assert(negativeTs.getTime < 0)
       val expectedSecs = Math.floorDiv(negativeTs.getTime, MILLIS_PER_SECOND)
-      checkExceptionInExpression[ArithmeticException](
-        cast(negativeTs, ByteType), "to byte causes overflow")
-      checkExceptionInExpression[ArithmeticException](
-        cast(negativeTs, ShortType), "to short causes overflow")
-      checkExceptionInExpression[ArithmeticException](
-        cast(negativeTs, IntegerType), "to int causes overflow")
+      checkExceptionInExpression[ArithmeticException](cast(negativeTs, ByteType), errMsg("byte"))
+      checkExceptionInExpression[ArithmeticException](cast(negativeTs, ShortType), errMsg("short"))
+      checkExceptionInExpression[ArithmeticException](cast(negativeTs, IntegerType), errMsg("int"))
       checkEvaluation(cast(negativeTs, LongType), expectedSecs)
     }
   }


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@spark.apache.org
For additional commands, e-mail: commits-help@spark.apache.org