@@ -113,7 +113,7 @@ case class Cast(child: Expression, dataType: DataType) extends UnaryExpression w
113
113
// UDFToString
114
114
private [this ] def castToString (from : DataType ): Any => Any = from match {
115
115
case BinaryType => buildCast[Array [Byte ]](_, new String (_, " UTF-8" ))
116
- case DateType => buildCast[Int ](_, d => DateUtils .toString(d) )
116
+ case DateType => buildCast[Date ](_, dateToString )
117
117
case TimestampType => buildCast[Timestamp ](_, timestampToString)
118
118
case _ => buildCast[Any ](_, _.toString)
119
119
}
@@ -131,7 +131,7 @@ case class Cast(child: Expression, dataType: DataType) extends UnaryExpression w
131
131
buildCast[Timestamp ](_, t => t.getTime() != 0 || t.getNanos() != 0 )
132
132
case DateType =>
133
133
// Hive would return null when cast from date to boolean
134
- buildCast[Int ](_, d => null )
134
+ buildCast[Date ](_, d => null )
135
135
case LongType =>
136
136
buildCast[Long ](_, _ != 0 )
137
137
case IntegerType =>
@@ -171,7 +171,7 @@ case class Cast(child: Expression, dataType: DataType) extends UnaryExpression w
171
171
case ByteType =>
172
172
buildCast[Byte ](_, b => new Timestamp (b))
173
173
case DateType =>
174
- buildCast[Int ](_, d => new Timestamp (DateUtils .toJavaDate(d) .getTime))
174
+ buildCast[Date ](_, d => new Timestamp (d .getTime))
175
175
// TimestampWritable.decimalToTimestamp
176
176
case DecimalType () =>
177
177
buildCast[Decimal ](_, d => decimalToTimestamp(d))
@@ -224,24 +224,37 @@ case class Cast(child: Expression, dataType: DataType) extends UnaryExpression w
224
224
}
225
225
}
226
226
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
+
227
232
// DateConverter
228
233
private [this ] def castToDate (from : DataType ): Any => Any = from match {
229
234
case StringType =>
230
235
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 })
234
237
case TimestampType =>
235
238
// throw valid precision more than seconds, according to Hive.
236
239
// 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 ))
238
241
// 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
241
243
// NULL is more reasonable here, since the query itself obeys the grammar.
242
244
case _ => _ => null
243
245
}
244
246
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
+
245
258
// LongConverter
246
259
private [this ] def castToLong (from : DataType ): Any => Any = from match {
247
260
case StringType =>
@@ -251,7 +264,7 @@ case class Cast(child: Expression, dataType: DataType) extends UnaryExpression w
251
264
case BooleanType =>
252
265
buildCast[Boolean ](_, b => if (b) 1L else 0L )
253
266
case DateType =>
254
- buildCast[Int ](_, d => null )
267
+ buildCast[Date ](_, d => dateToLong(d) )
255
268
case TimestampType =>
256
269
buildCast[Timestamp ](_, t => timestampToLong(t))
257
270
case x : NumericType =>
@@ -267,7 +280,7 @@ case class Cast(child: Expression, dataType: DataType) extends UnaryExpression w
267
280
case BooleanType =>
268
281
buildCast[Boolean ](_, b => if (b) 1 else 0 )
269
282
case DateType =>
270
- buildCast[Int ](_, d => null )
283
+ buildCast[Date ](_, d => dateToLong(d) )
271
284
case TimestampType =>
272
285
buildCast[Timestamp ](_, t => timestampToLong(t).toInt)
273
286
case x : NumericType =>
@@ -283,7 +296,7 @@ case class Cast(child: Expression, dataType: DataType) extends UnaryExpression w
283
296
case BooleanType =>
284
297
buildCast[Boolean ](_, b => if (b) 1 .toShort else 0 .toShort)
285
298
case DateType =>
286
- buildCast[Int ](_, d => null )
299
+ buildCast[Date ](_, d => dateToLong(d) )
287
300
case TimestampType =>
288
301
buildCast[Timestamp ](_, t => timestampToLong(t).toShort)
289
302
case x : NumericType =>
@@ -299,7 +312,7 @@ case class Cast(child: Expression, dataType: DataType) extends UnaryExpression w
299
312
case BooleanType =>
300
313
buildCast[Boolean ](_, b => if (b) 1 .toByte else 0 .toByte)
301
314
case DateType =>
302
- buildCast[Int ](_, d => null )
315
+ buildCast[Date ](_, d => dateToLong(d) )
303
316
case TimestampType =>
304
317
buildCast[Timestamp ](_, t => timestampToLong(t).toByte)
305
318
case x : NumericType =>
@@ -329,7 +342,7 @@ case class Cast(child: Expression, dataType: DataType) extends UnaryExpression w
329
342
case BooleanType =>
330
343
buildCast[Boolean ](_, b => changePrecision(if (b) Decimal (1 ) else Decimal (0 ), target))
331
344
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
333
346
case TimestampType =>
334
347
// Note that we lose precision here.
335
348
buildCast[Timestamp ](_, t => changePrecision(Decimal (timestampToDouble(t)), target))
@@ -354,7 +367,7 @@ case class Cast(child: Expression, dataType: DataType) extends UnaryExpression w
354
367
case BooleanType =>
355
368
buildCast[Boolean ](_, b => if (b) 1d else 0d )
356
369
case DateType =>
357
- buildCast[Int ](_, d => null )
370
+ buildCast[Date ](_, d => dateToDouble(d) )
358
371
case TimestampType =>
359
372
buildCast[Timestamp ](_, t => timestampToDouble(t))
360
373
case x : NumericType =>
@@ -370,7 +383,7 @@ case class Cast(child: Expression, dataType: DataType) extends UnaryExpression w
370
383
case BooleanType =>
371
384
buildCast[Boolean ](_, b => if (b) 1f else 0f )
372
385
case DateType =>
373
- buildCast[Int ](_, d => null )
386
+ buildCast[Date ](_, d => dateToDouble(d) )
374
387
case TimestampType =>
375
388
buildCast[Timestamp ](_, t => timestampToDouble(t).toFloat)
376
389
case x : NumericType =>
@@ -429,16 +442,16 @@ case class Cast(child: Expression, dataType: DataType) extends UnaryExpression w
429
442
430
443
object Cast {
431
444
// `SimpleDateFormat` is not thread-safe.
432
- private [sql] val threadLocalTimestampFormat = new ThreadLocal [DateFormat ] {
445
+ private [sql] val threadLocalDateFormat = new ThreadLocal [DateFormat ] {
433
446
override def initialValue () = {
434
- new SimpleDateFormat (" yyyy-MM-dd HH:mm:ss " )
447
+ new SimpleDateFormat (" yyyy-MM-dd" )
435
448
}
436
449
}
437
450
438
451
// `SimpleDateFormat` is not thread-safe.
439
- private [sql] val threadLocalDateFormat = new ThreadLocal [DateFormat ] {
452
+ private [sql] val threadLocalTimestampFormat = new ThreadLocal [DateFormat ] {
440
453
override def initialValue () = {
441
- new SimpleDateFormat (" yyyy-MM-dd" )
454
+ new SimpleDateFormat (" yyyy-MM-dd HH:mm:ss " )
442
455
}
443
456
}
444
457
}
0 commit comments