Repository: spark
Updated Branches:
  refs/heads/branch-1.6 6fc968754 -> 9c8e17984


[SPARK-11724][SQL] Change casting between int and timestamp to consistently 
treat int in seconds.

Hive has since changed this behavior as well. 
https://issues.apache.org/jira/browse/HIVE-3454

Author: Nong Li <n...@databricks.com>
Author: Nong Li <non...@gmail.com>
Author: Yin Huai <yh...@databricks.com>

Closes #9685 from nongli/spark-11724.

(cherry picked from commit 9ed4ad4265cf9d3135307eb62dae6de0b220fc21)
Signed-off-by: Yin Huai <yh...@databricks.com>


Project: http://git-wip-us.apache.org/repos/asf/spark/repo
Commit: http://git-wip-us.apache.org/repos/asf/spark/commit/9c8e1798
Tree: http://git-wip-us.apache.org/repos/asf/spark/tree/9c8e1798
Diff: http://git-wip-us.apache.org/repos/asf/spark/diff/9c8e1798

Branch: refs/heads/branch-1.6
Commit: 9c8e17984d95a8d225525a592a921a5af81e4440
Parents: 6fc9687
Author: Nong Li <n...@databricks.com>
Authored: Fri Nov 20 14:19:34 2015 -0800
Committer: Yin Huai <yh...@databricks.com>
Committed: Fri Nov 20 14:19:44 2015 -0800

----------------------------------------------------------------------
 .../spark/sql/catalyst/expressions/Cast.scala   |  6 ++--
 .../sql/catalyst/expressions/CastSuite.scala    | 16 +++++----
 .../apache/spark/sql/DateFunctionsSuite.scala   |  3 ++
 ...l testing-0-237a6af90a857da1efcbe98f6bbbf9d6 |  1 +
 ...l testing-0-9a02bc7de09bcabcbd4c91f54a814c20 |  1 -
 ...mp cast #3-0-76ee270337f664b36cacfc6528ac109 |  1 -
 ...p cast #5-0-dbd7bcd167d322d6617b884c02c7f247 |  1 -
 ...p cast #7-0-1d70654217035f8ce5f64344f4c5a80f |  1 -
 .../sql/hive/execution/HiveQuerySuite.scala     | 34 +++++++++++++-------
 9 files changed, 39 insertions(+), 25 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/spark/blob/9c8e1798/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/Cast.scala
----------------------------------------------------------------------
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 5564e24..533d17e 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
@@ -204,8 +204,8 @@ case class Cast(child: Expression, dataType: DataType)
     if (d.isNaN || d.isInfinite) null else (d * 1000000L).toLong
   }
 
-  // converting milliseconds to us
-  private[this] def longToTimestamp(t: Long): Long = t * 1000L
+  // converting seconds to us
+  private[this] def longToTimestamp(t: Long): Long = t * 1000000L
   // converting us to seconds
   private[this] def timestampToLong(ts: Long): Long = math.floor(ts.toDouble / 
1000000L).toLong
   // converting us to seconds in double
@@ -647,7 +647,7 @@ case class Cast(child: Expression, dataType: DataType)
 
   private[this] def decimalToTimestampCode(d: String): String =
     s"($d.toBigDecimal().bigDecimal().multiply(new 
java.math.BigDecimal(1000000L))).longValue()"
-  private[this] def longToTimeStampCode(l: String): String = s"$l * 1000L"
+  private[this] def longToTimeStampCode(l: String): String = s"$l * 1000000L"
   private[this] def timestampToIntegerCode(ts: String): String =
     s"java.lang.Math.floor((double) $ts / 1000000L)"
   private[this] def timestampToDoubleCode(ts: String): String = s"$ts / 
1000000.0"

http://git-wip-us.apache.org/repos/asf/spark/blob/9c8e1798/sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/expressions/CastSuite.scala
----------------------------------------------------------------------
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 f4db4da..ab77a76 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
@@ -258,8 +258,8 @@ class CastSuite extends SparkFunSuite with 
ExpressionEvalHelper {
 
   test("cast from int 2") {
     checkEvaluation(cast(1, LongType), 1.toLong)
-    checkEvaluation(cast(cast(1000, TimestampType), LongType), 1.toLong)
-    checkEvaluation(cast(cast(-1200, TimestampType), LongType), -2.toLong)
+    checkEvaluation(cast(cast(1000, TimestampType), LongType), 1000.toLong)
+    checkEvaluation(cast(cast(-1200, TimestampType), LongType), -1200.toLong)
 
     checkEvaluation(cast(123, DecimalType.USER_DEFAULT), Decimal(123))
     checkEvaluation(cast(123, DecimalType(3, 0)), Decimal(123))
@@ -348,14 +348,14 @@ class CastSuite extends SparkFunSuite with 
ExpressionEvalHelper {
     checkEvaluation(
       cast(cast(cast(cast(cast(cast("5", ByteType), TimestampType),
         DecimalType.SYSTEM_DEFAULT), LongType), StringType), ShortType),
-      0.toShort)
+      5.toShort)
     checkEvaluation(
       cast(cast(cast(cast(cast(cast("5", TimestampType), ByteType),
         DecimalType.SYSTEM_DEFAULT), LongType), StringType), ShortType),
       null)
     checkEvaluation(cast(cast(cast(cast(cast(cast("5", 
DecimalType.SYSTEM_DEFAULT),
       ByteType), TimestampType), LongType), StringType), ShortType),
-      0.toShort)
+      5.toShort)
 
     checkEvaluation(cast("23", DoubleType), 23d)
     checkEvaluation(cast("23", IntegerType), 23)
@@ -479,10 +479,12 @@ class CastSuite extends SparkFunSuite with 
ExpressionEvalHelper {
     checkEvaluation(cast(ts, LongType), 15.toLong)
     checkEvaluation(cast(ts, FloatType), 15.003f)
     checkEvaluation(cast(ts, DoubleType), 15.003)
-    checkEvaluation(cast(cast(tss, ShortType), TimestampType), 
DateTimeUtils.fromJavaTimestamp(ts))
+    checkEvaluation(cast(cast(tss, ShortType), TimestampType),
+      DateTimeUtils.fromJavaTimestamp(ts) * 1000)
     checkEvaluation(cast(cast(tss, IntegerType), TimestampType),
-      DateTimeUtils.fromJavaTimestamp(ts))
-    checkEvaluation(cast(cast(tss, LongType), TimestampType), 
DateTimeUtils.fromJavaTimestamp(ts))
+      DateTimeUtils.fromJavaTimestamp(ts) * 1000)
+    checkEvaluation(cast(cast(tss, LongType), TimestampType),
+      DateTimeUtils.fromJavaTimestamp(ts) * 1000)
     checkEvaluation(
       cast(cast(millis.toFloat / 1000, TimestampType), FloatType),
       millis.toFloat / 1000)

http://git-wip-us.apache.org/repos/asf/spark/blob/9c8e1798/sql/core/src/test/scala/org/apache/spark/sql/DateFunctionsSuite.scala
----------------------------------------------------------------------
diff --git 
a/sql/core/src/test/scala/org/apache/spark/sql/DateFunctionsSuite.scala 
b/sql/core/src/test/scala/org/apache/spark/sql/DateFunctionsSuite.scala
index 241cbd0..a61c3aa 100644
--- a/sql/core/src/test/scala/org/apache/spark/sql/DateFunctionsSuite.scala
+++ b/sql/core/src/test/scala/org/apache/spark/sql/DateFunctionsSuite.scala
@@ -448,6 +448,9 @@ class DateFunctionsSuite extends QueryTest with 
SharedSQLContext {
       Row(date1.getTime / 1000L), Row(date2.getTime / 1000L)))
     checkAnswer(df.selectExpr(s"unix_timestamp(s, '$fmt')"), Seq(
       Row(ts1.getTime / 1000L), Row(ts2.getTime / 1000L)))
+
+    val now = sql("select unix_timestamp()").collect().head.getLong(0)
+    checkAnswer(sql(s"select cast ($now as timestamp)"), Row(new 
java.util.Date(now * 1000)))
   }
 
   test("to_unix_timestamp") {

http://git-wip-us.apache.org/repos/asf/spark/blob/9c8e1798/sql/hive/src/test/resources/golden/constant
 null testing-0-237a6af90a857da1efcbe98f6bbbf9d6
----------------------------------------------------------------------
diff --git a/sql/hive/src/test/resources/golden/constant null 
testing-0-237a6af90a857da1efcbe98f6bbbf9d6 
b/sql/hive/src/test/resources/golden/constant null 
testing-0-237a6af90a857da1efcbe98f6bbbf9d6
new file mode 100644
index 0000000..a01c262
--- /dev/null
+++ b/sql/hive/src/test/resources/golden/constant null 
testing-0-237a6af90a857da1efcbe98f6bbbf9d6       
@@ -0,0 +1 @@
+1      NULL    1       NULL    1.0     NULL    true    NULL    1       NULL    
1.0     NULL    1       NULL    1       NULL    1       NULL    1970-01-01      
NULL    NULL    1       NULL

http://git-wip-us.apache.org/repos/asf/spark/blob/9c8e1798/sql/hive/src/test/resources/golden/constant
 null testing-0-9a02bc7de09bcabcbd4c91f54a814c20
----------------------------------------------------------------------
diff --git a/sql/hive/src/test/resources/golden/constant null 
testing-0-9a02bc7de09bcabcbd4c91f54a814c20 
b/sql/hive/src/test/resources/golden/constant null 
testing-0-9a02bc7de09bcabcbd4c91f54a814c20
deleted file mode 100644
index 7c41615..0000000
--- a/sql/hive/src/test/resources/golden/constant null 
testing-0-9a02bc7de09bcabcbd4c91f54a814c20       
+++ /dev/null
@@ -1 +0,0 @@
-1      NULL    1       NULL    1.0     NULL    true    NULL    1       NULL    
1.0     NULL    1       NULL    1       NULL    1       NULL    1970-01-01      
NULL    1969-12-31 16:00:00.001 NULL    1       NULL

http://git-wip-us.apache.org/repos/asf/spark/blob/9c8e1798/sql/hive/src/test/resources/golden/timestamp
 cast #3-0-76ee270337f664b36cacfc6528ac109
----------------------------------------------------------------------
diff --git a/sql/hive/src/test/resources/golden/timestamp cast 
#3-0-76ee270337f664b36cacfc6528ac109 
b/sql/hive/src/test/resources/golden/timestamp cast 
#3-0-76ee270337f664b36cacfc6528ac109
deleted file mode 100644
index d00491f..0000000
--- a/sql/hive/src/test/resources/golden/timestamp cast 
#3-0-76ee270337f664b36cacfc6528ac109    
+++ /dev/null
@@ -1 +0,0 @@
-1

http://git-wip-us.apache.org/repos/asf/spark/blob/9c8e1798/sql/hive/src/test/resources/golden/timestamp
 cast #5-0-dbd7bcd167d322d6617b884c02c7f247
----------------------------------------------------------------------
diff --git a/sql/hive/src/test/resources/golden/timestamp cast 
#5-0-dbd7bcd167d322d6617b884c02c7f247 
b/sql/hive/src/test/resources/golden/timestamp cast 
#5-0-dbd7bcd167d322d6617b884c02c7f247
deleted file mode 100644
index 84a31a5..0000000
--- a/sql/hive/src/test/resources/golden/timestamp cast 
#5-0-dbd7bcd167d322d6617b884c02c7f247   
+++ /dev/null
@@ -1 +0,0 @@
--0.001

http://git-wip-us.apache.org/repos/asf/spark/blob/9c8e1798/sql/hive/src/test/resources/golden/timestamp
 cast #7-0-1d70654217035f8ce5f64344f4c5a80f
----------------------------------------------------------------------
diff --git a/sql/hive/src/test/resources/golden/timestamp cast 
#7-0-1d70654217035f8ce5f64344f4c5a80f 
b/sql/hive/src/test/resources/golden/timestamp cast 
#7-0-1d70654217035f8ce5f64344f4c5a80f
deleted file mode 100644
index 3fbedf6..0000000
--- a/sql/hive/src/test/resources/golden/timestamp cast 
#7-0-1d70654217035f8ce5f64344f4c5a80f   
+++ /dev/null
@@ -1 +0,0 @@
--2

http://git-wip-us.apache.org/repos/asf/spark/blob/9c8e1798/sql/hive/src/test/scala/org/apache/spark/sql/hive/execution/HiveQuerySuite.scala
----------------------------------------------------------------------
diff --git 
a/sql/hive/src/test/scala/org/apache/spark/sql/hive/execution/HiveQuerySuite.scala
 
b/sql/hive/src/test/scala/org/apache/spark/sql/hive/execution/HiveQuerySuite.scala
index f0a7a6c..8a5acaf 100644
--- 
a/sql/hive/src/test/scala/org/apache/spark/sql/hive/execution/HiveQuerySuite.scala
+++ 
b/sql/hive/src/test/scala/org/apache/spark/sql/hive/execution/HiveQuerySuite.scala
@@ -18,6 +18,7 @@
 package org.apache.spark.sql.hive.execution
 
 import java.io.File
+import java.sql.Timestamp
 import java.util.{Locale, TimeZone}
 
 import scala.util.Try
@@ -248,12 +249,17 @@ class HiveQuerySuite extends HiveComparisonTest with 
BeforeAndAfter {
       |IF(TRUE, CAST(NULL AS BINARY), CAST("1" AS BINARY)) AS COL18,
       |IF(FALSE, CAST(NULL AS DATE), CAST("1970-01-01" AS DATE)) AS COL19,
       |IF(TRUE, CAST(NULL AS DATE), CAST("1970-01-01" AS DATE)) AS COL20,
-      |IF(FALSE, CAST(NULL AS TIMESTAMP), CAST(1 AS TIMESTAMP)) AS COL21,
-      |IF(TRUE, CAST(NULL AS TIMESTAMP), CAST(1 AS TIMESTAMP)) AS COL22,
-      |IF(FALSE, CAST(NULL AS DECIMAL), CAST(1 AS DECIMAL)) AS COL23,
-      |IF(TRUE, CAST(NULL AS DECIMAL), CAST(1 AS DECIMAL)) AS COL24
+      |IF(TRUE, CAST(NULL AS TIMESTAMP), CAST(1 AS TIMESTAMP)) AS COL21,
+      |IF(FALSE, CAST(NULL AS DECIMAL), CAST(1 AS DECIMAL)) AS COL22,
+      |IF(TRUE, CAST(NULL AS DECIMAL), CAST(1 AS DECIMAL)) AS COL23
       |FROM src LIMIT 1""".stripMargin)
 
+  test("constant null testing timestamp") {
+    val r1 = sql("SELECT IF(FALSE, CAST(NULL AS TIMESTAMP), CAST(1 AS 
TIMESTAMP)) AS COL20")
+      .collect().head
+    assert(new Timestamp(1000) == r1.getTimestamp(0))
+  }
+
   createQueryTest("constant array",
   """
     |SELECT sort_array(
@@ -603,26 +609,32 @@ class HiveQuerySuite extends HiveComparisonTest with 
BeforeAndAfter {
   // Jdk version leads to different query output for double, so not use 
createQueryTest here
   test("timestamp cast #1") {
     val res = sql("SELECT CAST(CAST(1 AS TIMESTAMP) AS DOUBLE) FROM src LIMIT 
1").collect().head
-    assert(0.001 == res.getDouble(0))
+    assert(1 == res.getDouble(0))
   }
 
   createQueryTest("timestamp cast #2",
     "SELECT CAST(CAST(1.2 AS TIMESTAMP) AS DOUBLE) FROM src LIMIT 1")
 
-  createQueryTest("timestamp cast #3",
-    "SELECT CAST(CAST(1200 AS TIMESTAMP) AS INT) FROM src LIMIT 1")
+  test("timestamp cast #3") {
+    val res = sql("SELECT CAST(CAST(1200 AS TIMESTAMP) AS INT) FROM src LIMIT 
1").collect().head
+    assert(1200 == res.getInt(0))
+  }
 
   createQueryTest("timestamp cast #4",
     "SELECT CAST(CAST(1.2 AS TIMESTAMP) AS DOUBLE) FROM src LIMIT 1")
 
-  createQueryTest("timestamp cast #5",
-    "SELECT CAST(CAST(-1 AS TIMESTAMP) AS DOUBLE) FROM src LIMIT 1")
+  test("timestamp cast #5") {
+    val res = sql("SELECT CAST(CAST(-1 AS TIMESTAMP) AS DOUBLE) FROM src LIMIT 
1").collect().head
+    assert(-1 == res.get(0))
+  }
 
   createQueryTest("timestamp cast #6",
     "SELECT CAST(CAST(-1.2 AS TIMESTAMP) AS DOUBLE) FROM src LIMIT 1")
 
-  createQueryTest("timestamp cast #7",
-    "SELECT CAST(CAST(-1200 AS TIMESTAMP) AS INT) FROM src LIMIT 1")
+  test("timestamp cast #7") {
+    val res = sql("SELECT CAST(CAST(-1200 AS TIMESTAMP) AS INT) FROM src LIMIT 
1").collect().head
+    assert(-1200 == res.getInt(0))
+  }
 
   createQueryTest("timestamp cast #8",
     "SELECT CAST(CAST(-1.2 AS TIMESTAMP) AS DOUBLE) FROM src LIMIT 1")


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

Reply via email to