Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,8 @@ object Cast {
case (DateType, TimestampType) => true
case (_: NumericType, TimestampType) => true

case (_, DateType) => true
case (StringType, DateType) => true
case (TimestampType, DateType) => true

case (StringType, CalendarIntervalType) => true

Expand Down Expand Up @@ -228,18 +229,12 @@ case class Cast(child: Expression, dataType: DataType) extends UnaryExpression w
// throw valid precision more than seconds, according to Hive.
// Timestamp.nanos is in 0 to 999,999,999, no more than a second.
buildCast[Long](_, t => DateTimeUtils.millisToDays(t / 1000L))
// Hive throws this exception as a Semantic Exception
// It is never possible to compare result when hive return with exception,
// so we can return null
// NULL is more reasonable here, since the query itself obeys the grammar.
case _ => _ => null
}

// IntervalConverter
private[this] def castToInterval(from: DataType): Any => Any = from match {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cc @yhuai @liancheng , do you remember why we have this behaviour at the beginning?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like a design decision made in the original PR. See here: https://github.com/apache/spark/pull/2344/files#diff-258b71121d8d168e4d53cb5b6dc53ffeR166

I don't think we've ever discussed this case explicitly. This change seems reasonable to me.

case StringType =>
buildCast[UTF8String](_, s => CalendarInterval.fromString(s.toString))
case _ => _ => null
}

// LongConverter
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,8 @@ class CastSuite extends SparkFunSuite with ExpressionEvalHelper {
checkNullCast(DateType, TimestampType)
numericTypes.foreach(dt => checkNullCast(dt, TimestampType))

atomicTypes.foreach(dt => checkNullCast(dt, DateType))
checkNullCast(StringType, DateType)
checkNullCast(TimestampType, DateType)

checkNullCast(StringType, CalendarIntervalType)
numericTypes.foreach(dt => checkNullCast(StringType, dt))
Expand Down Expand Up @@ -366,7 +367,6 @@ class CastSuite extends SparkFunSuite with ExpressionEvalHelper {
checkEvaluation(cast("2012-12-11", DoubleType), null)
checkEvaluation(cast(123, IntegerType), 123)


checkEvaluation(cast(Literal.create(null, IntegerType), ShortType), null)
}

Expand Down Expand Up @@ -783,4 +783,16 @@ class CastSuite extends SparkFunSuite with ExpressionEvalHelper {
checkEvaluation(cast("abc", BooleanType), null)
checkEvaluation(cast("", BooleanType), null)
}

test("SPARK-16729 type checking for casting to date type") {
assert(cast("1234", DateType).checkInputDataTypes().isSuccess)
assert(cast(new Timestamp(1), DateType).checkInputDataTypes().isSuccess)
assert(cast(false, DateType).checkInputDataTypes().isFailure)
assert(cast(1.toByte, DateType).checkInputDataTypes().isFailure)
assert(cast(1.toShort, DateType).checkInputDataTypes().isFailure)
assert(cast(1, DateType).checkInputDataTypes().isFailure)
assert(cast(1L, DateType).checkInputDataTypes().isFailure)
assert(cast(1.0.toFloat, DateType).checkInputDataTypes().isFailure)
assert(cast(1.0, DateType).checkInputDataTypes().isFailure)
}
}