diff --git a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/analysis/Analyzer.scala b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/analysis/Analyzer.scala index e55cdfedd3234..85fcdb7c1704a 100644 --- a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/analysis/Analyzer.scala +++ b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/analysis/Analyzer.scala @@ -2454,7 +2454,7 @@ class Analyzer( } else { // always add an UpCast. it will be removed in the optimizer if it is unnecessary. Some(Alias( - UpCast(queryExpr, tableAttr.dataType), tableAttr.name + Cast(queryExpr, tableAttr.dataType), tableAttr.name )( explicitMetadata = Option(tableAttr.metadata) )) diff --git a/sql/catalyst/src/main/scala/org/apache/spark/sql/types/DataType.scala b/sql/catalyst/src/main/scala/org/apache/spark/sql/types/DataType.scala index a35e971d08823..e51d7eb5e2a51 100644 --- a/sql/catalyst/src/main/scala/org/apache/spark/sql/types/DataType.scala +++ b/sql/catalyst/src/main/scala/org/apache/spark/sql/types/DataType.scala @@ -442,14 +442,16 @@ object DataType { fieldCompatible case (w: AtomicType, r: AtomicType) => - if (!Cast.canUpCast(w, r)) { - addError(s"Cannot safely cast '$context': $w to $r") + if (!canWriteAtomicType(w, r)) { + addError(s"Cannot assign '$context': $w to $r") false } else { true } - case (w, r) if w.sameType(r) && !w.isInstanceOf[NullType] => + case (NullType, _) => true + + case (w, r) if w.sameType(r) => true case (w, r) => @@ -457,4 +459,17 @@ object DataType { false } } + + private def canWriteAtomicType(from: AtomicType, to: AtomicType): Boolean = (from, to) match { + case _ if from == to => true + case (_: NumericType, _: NumericType) => true + case (_, StringType) => true + case (DateType, TimestampType) => true + case (TimestampType, DateType) => true + // Spark supports casting between long and timestamp, please see `longToTimestamp` and + // `timestampToLong` for details. + case (TimestampType, LongType) => true + case (LongType, TimestampType) => true + case _ => false + } }