cloud-fan commented on a change in pull request #35060: URL: https://github.com/apache/spark/pull/35060#discussion_r787790548
########## File path: sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/expressions/StringExpressionsSuite.scala ########## @@ -888,6 +889,158 @@ class StringExpressionsSuite extends SparkFunSuite with ExpressionEvalHelper { Literal.create(null, IntegerType), Literal.create(null, IntegerType)), null) } + test("ToNumber") { + ToNumber(Literal("454"), Literal("")).checkInputDataTypes() match { + case TypeCheckResult.TypeCheckFailure(msg) => + assert(msg.contains("Number format cannot be empty")) + } + ToNumber(Literal("454"), NonFoldableLiteral.create("999", StringType)) + .checkInputDataTypes() match { + case TypeCheckResult.TypeCheckFailure(msg) => + assert(msg.contains("Format expression must be foldable")) + } + + // Test '0' and '9' + + Seq("454", "054", "54", "450").foreach { input => + val invalidFormat1 = 0.until(input.length - 1).map(_ => '0').mkString + val invalidFormat2 = 0.until(input.length - 2).map(_ => '0').mkString + val invalidFormat3 = 0.until(input.length - 1).map(_ => '9').mkString + val invalidFormat4 = 0.until(input.length - 2).map(_ => '9').mkString + Seq(invalidFormat1, invalidFormat2, invalidFormat3, invalidFormat4) + .filter(_.nonEmpty).foreach { format => + checkExceptionInExpression[IllegalArgumentException]( + ToNumber(Literal(input), Literal(format)), + s"The input string '$input' does not match the given number format: '$format'") + } + + val format1 = 0.until(input.length).map(_ => '0').mkString + val format2 = 0.until(input.length).map(_ => '9').mkString + val format3 = 0.until(input.length).map(i => i % 2 * 9).mkString + val format4 = 0.until(input.length + 1).map(_ => '0').mkString + val format5 = 0.until(input.length + 1).map(_ => '9').mkString + val format6 = 0.until(input.length + 1).map(i => i % 2 * 9).mkString + Seq(format1, format2, format3, format4, format5, format6).foreach { format => + checkEvaluation(ToNumber(Literal(input), Literal(format)), Decimal(input)) + } + } + + // Test '.' and 'D' + checkExceptionInExpression[IllegalArgumentException]( + ToNumber(Literal("454.2"), Literal("999")), + "The input string '454.2' does not match the given number format: '999'") + Seq("999.9", "000.0", "99.99", "00.00", "0000.0", "9999.9", "00.000", "99.999") + .foreach { format => + checkExceptionInExpression[IllegalArgumentException]( + ToNumber(Literal("454.23"), Literal(format)), + s"The input string '454.23' does not match the given number format: '$format'") + val format2 = format.replace('.', 'D') + checkExceptionInExpression[IllegalArgumentException]( + ToNumber(Literal("454.23"), Literal(format2)), + s"The input string '454.23' does not match the given number format: '$format2'") + } + + Seq( + ("454.2", "000.0") -> Decimal(454.2), + ("454.2", "000D0") -> Decimal(454.2), + ("454.23", "000.00") -> Decimal(454.23), + ("454.23", "000D00") -> Decimal(454.23), + ("454.2", "000.00") -> Decimal(454.2), + ("454.2", "000D00") -> Decimal(454.2), + ("454.0", "000.0") -> Decimal(454), + ("454.0", "000D0") -> Decimal(454), + ("454.00", "000.00") -> Decimal(454), + ("454.00", "000D00") -> Decimal(454), + (".4542", ".0000") -> Decimal(0.4542), + (".4542", "D0000") -> Decimal(0.4542), + ("4542.", "0000.") -> Decimal(4542), + ("4542.", "0000D") -> Decimal(4542) + ).foreach { case ((str, format), expected) => + checkEvaluation(ToNumber(Literal(str), Literal(format)), expected) + } + + Seq("999.9.9", "999D9D9", "999.9D9", "999D9.9").foreach { str => + ToNumber(Literal("454.3.2"), Literal(str)).checkInputDataTypes() match { + case TypeCheckResult.TypeCheckFailure(msg) => + assert(msg.contains(s"At most one 'D' or '.' is allowed in the number format: '$str'")) + } + } + + // Test ',' and 'G' + checkExceptionInExpression[IllegalArgumentException]( + ToNumber(Literal("123,456"), Literal("9G9")), + "The input string '123,456' does not match the given number format: '9G9'") + + Seq( + ("12,454", "99,999") -> Decimal(12454), Review comment: ditto, no need to repeat the test cases manually, we can replace `0` with `9` in the loop body. -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: reviews-unsubscr...@spark.apache.org For queries about this service, please contact Infrastructure at: us...@infra.apache.org --------------------------------------------------------------------- To unsubscribe, e-mail: reviews-unsubscr...@spark.apache.org For additional commands, e-mail: reviews-h...@spark.apache.org