@@ -1142,28 +1142,6 @@ class DateExpressionsSuite extends SparkFunSuite with ExpressionEvalHelper {
11421142 }
11431143 }
11441144
1145- test(" SPARK-31710:Adds TIMESTAMP_SECONDS, " +
1146- " TIMESTAMP_MILLIS and TIMESTAMP_MICROS functions" ) {
1147- checkEvaluation(SecondsToTimestamp (Literal (1230219000 )), 1230219000L * MICROS_PER_SECOND )
1148- checkEvaluation(SecondsToTimestamp (Literal (- 1230219000 )), - 1230219000L * MICROS_PER_SECOND )
1149- checkEvaluation(SecondsToTimestamp (Literal (null , IntegerType )), null )
1150- checkEvaluation(MillisToTimestamp (Literal (1230219000123L )), 1230219000123L * MICROS_PER_MILLIS )
1151- checkEvaluation(MillisToTimestamp (
1152- Literal (- 1230219000123L )), - 1230219000123L * MICROS_PER_MILLIS )
1153- checkEvaluation(MillisToTimestamp (Literal (null , IntegerType )), null )
1154- checkEvaluation(MicrosToTimestamp (Literal (1230219000123123L )), 1230219000123123L )
1155- checkEvaluation(MicrosToTimestamp (Literal (- 1230219000123123L )), - 1230219000123123L )
1156- checkEvaluation(MicrosToTimestamp (Literal (null , IntegerType )), null )
1157- checkExceptionInExpression[ArithmeticException ](
1158- SecondsToTimestamp (Literal (1230219000123123L )), " long overflow" )
1159- checkExceptionInExpression[ArithmeticException ](
1160- SecondsToTimestamp (Literal (- 1230219000123123L )), " long overflow" )
1161- checkExceptionInExpression[ArithmeticException ](
1162- MillisToTimestamp (Literal (92233720368547758L )), " long overflow" )
1163- checkExceptionInExpression[ArithmeticException ](
1164- MillisToTimestamp (Literal (- 92233720368547758L )), " long overflow" )
1165- }
1166-
11671145 test(" Consistent error handling for datetime formatting and parsing functions" ) {
11681146
11691147 def checkException [T <: Exception : ClassTag ](c : String ): Unit = {
@@ -1194,4 +1172,118 @@ class DateExpressionsSuite extends SparkFunSuite with ExpressionEvalHelper {
11941172 new ParseToTimestamp (Literal (" 11:11 PM" ), Literal (" mm:ss a" )).child,
11951173 Timestamp .valueOf(" 1970-01-01 12:11:11.0" ))
11961174 }
1175+
1176+ def testIntegralInput (testFunc : Number => Unit ): Unit = {
1177+ def checkResult (input : Long ): Unit = {
1178+ if (input.toByte == input) {
1179+ testFunc(input.toByte)
1180+ } else if (input.toShort == input) {
1181+ testFunc(input.toShort)
1182+ } else if (input.toInt == input) {
1183+ testFunc(input.toInt)
1184+ } else {
1185+ testFunc(input)
1186+ }
1187+ }
1188+ checkResult(0 )
1189+ checkResult(Byte .MaxValue )
1190+ checkResult(Byte .MinValue )
1191+ checkResult(Short .MaxValue )
1192+ checkResult(Short .MinValue )
1193+ checkResult(Int .MaxValue )
1194+ checkResult(Int .MinValue )
1195+ checkResult(Int .MaxValue .toLong + 100 )
1196+ checkResult(Int .MinValue .toLong - 100 )
1197+ }
1198+
1199+ test(" TIMESTAMP_SECONDS" ) {
1200+ def testIntegralFunc (value : Number ): Unit = {
1201+ checkEvaluation(
1202+ SecondsToTimestamp (Literal (value)),
1203+ Instant .ofEpochSecond(value.longValue()))
1204+ }
1205+
1206+ // test null input
1207+ checkEvaluation(
1208+ SecondsToTimestamp (Literal (null , IntegerType )),
1209+ null )
1210+
1211+ // test integral input
1212+ testIntegralInput(testIntegralFunc)
1213+ // test overflow
1214+ checkExceptionInExpression[ArithmeticException ](
1215+ SecondsToTimestamp (Literal (Long .MaxValue , LongType )), EmptyRow , " long overflow" )
1216+
1217+ def testFractionalInput (input : String ): Unit = {
1218+ Seq (input.toFloat, input.toDouble, Decimal (input)).foreach { value =>
1219+ checkEvaluation(
1220+ SecondsToTimestamp (Literal (value)),
1221+ (input.toDouble * MICROS_PER_SECOND ).toLong)
1222+ }
1223+ }
1224+
1225+ testFractionalInput(" 1.0" )
1226+ testFractionalInput(" -1.0" )
1227+ testFractionalInput(" 1.234567" )
1228+ testFractionalInput(" -1.234567" )
1229+
1230+ // test overflow for decimal input
1231+ checkExceptionInExpression[ArithmeticException ](
1232+ SecondsToTimestamp (Literal (Decimal (" 9" * 38 ))), " Overflow"
1233+ )
1234+ // test truncation error for decimal input
1235+ checkExceptionInExpression[ArithmeticException ](
1236+ SecondsToTimestamp (Literal (Decimal (" 0.1234567" ))), " Rounding necessary"
1237+ )
1238+
1239+ // test NaN
1240+ checkEvaluation(
1241+ SecondsToTimestamp (Literal (Double .NaN )),
1242+ null )
1243+ checkEvaluation(
1244+ SecondsToTimestamp (Literal (Float .NaN )),
1245+ null )
1246+ // double input can truncate
1247+ checkEvaluation(
1248+ SecondsToTimestamp (Literal (123.456789123 )),
1249+ Instant .ofEpochSecond(123 , 456789000 ))
1250+ }
1251+
1252+ test(" TIMESTAMP_MILLIS" ) {
1253+ def testIntegralFunc (value : Number ): Unit = {
1254+ checkEvaluation(
1255+ MillisToTimestamp (Literal (value)),
1256+ Instant .ofEpochMilli(value.longValue()))
1257+ }
1258+
1259+ // test null input
1260+ checkEvaluation(
1261+ MillisToTimestamp (Literal (null , IntegerType )),
1262+ null )
1263+
1264+ // test integral input
1265+ testIntegralInput(testIntegralFunc)
1266+ // test overflow
1267+ checkExceptionInExpression[ArithmeticException ](
1268+ MillisToTimestamp (Literal (Long .MaxValue , LongType )), EmptyRow , " long overflow" )
1269+ }
1270+
1271+ test(" TIMESTAMP_MICROS" ) {
1272+ def testIntegralFunc (value : Number ): Unit = {
1273+ checkEvaluation(
1274+ MicrosToTimestamp (Literal (value)),
1275+ value.longValue())
1276+ }
1277+
1278+ // test null input
1279+ checkEvaluation(
1280+ MicrosToTimestamp (Literal (null , IntegerType )),
1281+ null )
1282+
1283+ // test integral input
1284+ testIntegralInput(testIntegralFunc)
1285+ // test max/min input
1286+ testIntegralFunc(Long .MaxValue )
1287+ testIntegralFunc(Long .MinValue )
1288+ }
11971289}
0 commit comments