@@ -25,6 +25,7 @@ import scala.util.Random
2525import org .apache .spark .SparkFunSuite
2626import org .apache .spark .sql .Row
2727import org .apache .spark .sql .catalyst .InternalRow
28+ import org .apache .spark .sql .catalyst .analysis .TypeCoercion .numericPrecedence
2829import org .apache .spark .sql .catalyst .expressions .codegen .CodegenContext
2930import org .apache .spark .sql .catalyst .util .DateTimeTestUtils ._
3031import org .apache .spark .sql .catalyst .util .DateTimeUtils
@@ -955,4 +956,39 @@ class CastSuite extends SparkFunSuite with ExpressionEvalHelper {
955956 val ret6 = cast(Literal .create((1 , Map (1 -> " a" , 2 -> " b" , 3 -> " c" ))), StringType )
956957 checkEvaluation(ret6, " [1, [1 -> a, 2 -> b, 3 -> c]]" )
957958 }
959+
960+ test(" SPARK-26706: Fix Cast.mayTruncate for bytes" ) {
961+ assert(! Cast .mayTruncate(ByteType , ByteType ))
962+ assert(! Cast .mayTruncate(DecimalType .ByteDecimal , ByteType ))
963+ assert(Cast .mayTruncate(ShortType , ByteType ))
964+ assert(Cast .mayTruncate(IntegerType , ByteType ))
965+ assert(Cast .mayTruncate(LongType , ByteType ))
966+ assert(Cast .mayTruncate(FloatType , ByteType ))
967+ assert(Cast .mayTruncate(DoubleType , ByteType ))
968+ assert(Cast .mayTruncate(DecimalType .IntDecimal , ByteType ))
969+ }
970+
971+ test(" canSafeCast and mayTruncate must be consistent for numeric types" ) {
972+ import DataTypeTestUtils ._
973+
974+ def isCastSafe (from : NumericType , to : NumericType ): Boolean = (from, to) match {
975+ case (_, dt : DecimalType ) => dt.isWiderThan(from)
976+ case (dt : DecimalType , _) => dt.isTighterThan(to)
977+ case _ => numericPrecedence.indexOf(from) <= numericPrecedence.indexOf(to)
978+ }
979+
980+ numericTypes.foreach { from =>
981+ val (safeTargetTypes, unsafeTargetTypes) = numericTypes.partition(to => isCastSafe(from, to))
982+
983+ safeTargetTypes.foreach { to =>
984+ assert(Cast .canSafeCast(from, to), s " It should be possible to safely cast $from to $to" )
985+ assert(! Cast .mayTruncate(from, to), s " No truncation is expected when casting $from to $to" )
986+ }
987+
988+ unsafeTargetTypes.foreach { to =>
989+ assert(! Cast .canSafeCast(from, to), s " It shouldn't be possible to safely cast $from to $to" )
990+ assert(Cast .mayTruncate(from, to), s " Truncation is expected when casting $from to $to" )
991+ }
992+ }
993+ }
958994}
0 commit comments