@@ -113,7 +113,7 @@ case class Cast(child: Expression, dataType: DataType) extends UnaryExpression w
113113 // UDFToString
114114 private [this ] def castToString (from : DataType ): Any => Any = from match {
115115 case BinaryType => buildCast[Array [Byte ]](_, new String (_, " UTF-8" ))
116- case DateType => buildCast[Int ](_, d => DateUtils .toString(d) )
116+ case DateType => buildCast[Date ](_, dateToString )
117117 case TimestampType => buildCast[Timestamp ](_, timestampToString)
118118 case _ => buildCast[Any ](_, _.toString)
119119 }
@@ -131,7 +131,7 @@ case class Cast(child: Expression, dataType: DataType) extends UnaryExpression w
131131 buildCast[Timestamp ](_, t => t.getTime() != 0 || t.getNanos() != 0 )
132132 case DateType =>
133133 // Hive would return null when cast from date to boolean
134- buildCast[Int ](_, d => null )
134+ buildCast[Date ](_, d => null )
135135 case LongType =>
136136 buildCast[Long ](_, _ != 0 )
137137 case IntegerType =>
@@ -171,7 +171,7 @@ case class Cast(child: Expression, dataType: DataType) extends UnaryExpression w
171171 case ByteType =>
172172 buildCast[Byte ](_, b => new Timestamp (b))
173173 case DateType =>
174- buildCast[Int ](_, d => new Timestamp (DateUtils .toJavaDate(d) .getTime))
174+ buildCast[Date ](_, d => new Timestamp (d .getTime))
175175 // TimestampWritable.decimalToTimestamp
176176 case DecimalType () =>
177177 buildCast[Decimal ](_, d => decimalToTimestamp(d))
@@ -224,24 +224,37 @@ case class Cast(child: Expression, dataType: DataType) extends UnaryExpression w
224224 }
225225 }
226226
227+ // Converts Timestamp to string according to Hive TimestampWritable convention
228+ private [this ] def timestampToDateString (ts : Timestamp ): String = {
229+ Cast .threadLocalDateFormat.get.format(ts)
230+ }
231+
227232 // DateConverter
228233 private [this ] def castToDate (from : DataType ): Any => Any = from match {
229234 case StringType =>
230235 buildCast[String ](_, s =>
231- try DateUtils .fromJavaDate(Date .valueOf(s))
232- catch { case _ : java.lang.IllegalArgumentException => null }
233- )
236+ try Date .valueOf(s) catch { case _ : java.lang.IllegalArgumentException => null })
234237 case TimestampType =>
235238 // throw valid precision more than seconds, according to Hive.
236239 // Timestamp.nanos is in 0 to 999,999,999, no more than a second.
237- buildCast[Timestamp ](_, t => DateUtils .millisToDays (t.getTime))
240+ buildCast[Timestamp ](_, t => new Date ( Math .floor (t.getTime / 1000.0 ).toLong * 1000 ))
238241 // Hive throws this exception as a Semantic Exception
239- // It is never possible to compare result when hive return with exception,
240- // so we can return null
242+ // It is never possible to compare result when hive return with exception, so we can return null
241243 // NULL is more reasonable here, since the query itself obeys the grammar.
242244 case _ => _ => null
243245 }
244246
247+ // Date cannot be cast to long, according to hive
248+ private [this ] def dateToLong (d : Date ) = null
249+
250+ // Date cannot be cast to double, according to hive
251+ private [this ] def dateToDouble (d : Date ) = null
252+
253+ // Converts Date to string according to Hive DateWritable convention
254+ private [this ] def dateToString (d : Date ): String = {
255+ Cast .threadLocalDateFormat.get.format(d)
256+ }
257+
245258 // LongConverter
246259 private [this ] def castToLong (from : DataType ): Any => Any = from match {
247260 case StringType =>
@@ -251,7 +264,7 @@ case class Cast(child: Expression, dataType: DataType) extends UnaryExpression w
251264 case BooleanType =>
252265 buildCast[Boolean ](_, b => if (b) 1L else 0L )
253266 case DateType =>
254- buildCast[Int ](_, d => null )
267+ buildCast[Date ](_, d => dateToLong(d) )
255268 case TimestampType =>
256269 buildCast[Timestamp ](_, t => timestampToLong(t))
257270 case x : NumericType =>
@@ -267,7 +280,7 @@ case class Cast(child: Expression, dataType: DataType) extends UnaryExpression w
267280 case BooleanType =>
268281 buildCast[Boolean ](_, b => if (b) 1 else 0 )
269282 case DateType =>
270- buildCast[Int ](_, d => null )
283+ buildCast[Date ](_, d => dateToLong(d) )
271284 case TimestampType =>
272285 buildCast[Timestamp ](_, t => timestampToLong(t).toInt)
273286 case x : NumericType =>
@@ -283,7 +296,7 @@ case class Cast(child: Expression, dataType: DataType) extends UnaryExpression w
283296 case BooleanType =>
284297 buildCast[Boolean ](_, b => if (b) 1 .toShort else 0 .toShort)
285298 case DateType =>
286- buildCast[Int ](_, d => null )
299+ buildCast[Date ](_, d => dateToLong(d) )
287300 case TimestampType =>
288301 buildCast[Timestamp ](_, t => timestampToLong(t).toShort)
289302 case x : NumericType =>
@@ -299,7 +312,7 @@ case class Cast(child: Expression, dataType: DataType) extends UnaryExpression w
299312 case BooleanType =>
300313 buildCast[Boolean ](_, b => if (b) 1 .toByte else 0 .toByte)
301314 case DateType =>
302- buildCast[Int ](_, d => null )
315+ buildCast[Date ](_, d => dateToLong(d) )
303316 case TimestampType =>
304317 buildCast[Timestamp ](_, t => timestampToLong(t).toByte)
305318 case x : NumericType =>
@@ -329,7 +342,7 @@ case class Cast(child: Expression, dataType: DataType) extends UnaryExpression w
329342 case BooleanType =>
330343 buildCast[Boolean ](_, b => changePrecision(if (b) Decimal (1 ) else Decimal (0 ), target))
331344 case DateType =>
332- buildCast[Int ](_, d => null ) // date can't cast to decimal in Hive
345+ buildCast[Date ](_, d => null ) // date can't cast to decimal in Hive
333346 case TimestampType =>
334347 // Note that we lose precision here.
335348 buildCast[Timestamp ](_, t => changePrecision(Decimal (timestampToDouble(t)), target))
@@ -354,7 +367,7 @@ case class Cast(child: Expression, dataType: DataType) extends UnaryExpression w
354367 case BooleanType =>
355368 buildCast[Boolean ](_, b => if (b) 1d else 0d )
356369 case DateType =>
357- buildCast[Int ](_, d => null )
370+ buildCast[Date ](_, d => dateToDouble(d) )
358371 case TimestampType =>
359372 buildCast[Timestamp ](_, t => timestampToDouble(t))
360373 case x : NumericType =>
@@ -370,7 +383,7 @@ case class Cast(child: Expression, dataType: DataType) extends UnaryExpression w
370383 case BooleanType =>
371384 buildCast[Boolean ](_, b => if (b) 1f else 0f )
372385 case DateType =>
373- buildCast[Int ](_, d => null )
386+ buildCast[Date ](_, d => dateToDouble(d) )
374387 case TimestampType =>
375388 buildCast[Timestamp ](_, t => timestampToDouble(t).toFloat)
376389 case x : NumericType =>
@@ -429,16 +442,16 @@ case class Cast(child: Expression, dataType: DataType) extends UnaryExpression w
429442
430443object Cast {
431444 // `SimpleDateFormat` is not thread-safe.
432- private [sql] val threadLocalTimestampFormat = new ThreadLocal [DateFormat ] {
445+ private [sql] val threadLocalDateFormat = new ThreadLocal [DateFormat ] {
433446 override def initialValue () = {
434- new SimpleDateFormat (" yyyy-MM-dd HH:mm:ss " )
447+ new SimpleDateFormat (" yyyy-MM-dd" )
435448 }
436449 }
437450
438451 // `SimpleDateFormat` is not thread-safe.
439- private [sql] val threadLocalDateFormat = new ThreadLocal [DateFormat ] {
452+ private [sql] val threadLocalTimestampFormat = new ThreadLocal [DateFormat ] {
440453 override def initialValue () = {
441- new SimpleDateFormat (" yyyy-MM-dd" )
454+ new SimpleDateFormat (" yyyy-MM-dd HH:mm:ss " )
442455 }
443456 }
444457}
0 commit comments