viirya commented on code in PR #59334:
URL: https://github.com/apache/spark/pull/59334#discussion_r4251417666


##########
sql/api/src/main/scala/org/apache/spark/sql/types/Decimal.scala:
##########
@@ -648,8 +649,10 @@ object Decimal {
     try {
       val bigDecimal = stringToJavaBigDecimal(str)
       // We fast fail because constructing a very large JavaBigDecimal to 
Decimal is very slow.
-      // For example: Decimal("6.0790316E+25569151")
-      if (numDigitsInIntegralPart(bigDecimal) > DecimalType.MAX_PRECISION &&
+      // For example: Decimal("6.0790316E+25569151"). Zero fits any decimal 
type whatever its
+      // exponent, e.g. "0e39", so it is not checked.
+      if (bigDecimal.signum != 0 &&

Review Comment:
   Done. When negative scales are not allowed, a zero's negative scale is 
dropped before `Decimal.set`, so the result has precision 1 and scale 0; 
`'0.00'` keeps scale 2.



##########
sql/catalyst/src/test/scala/org/apache/spark/sql/types/DecimalSuite.scala:
##########
@@ -446,6 +446,24 @@ class DecimalSuite extends SparkFunSuite with 
PrivateMethodTester with SQLHelper
     }
   }
 
+  test("UTF8String to Decimal with exponent near Int.MaxValue") {
+    // The number of integral digits (precision - scale) of these values 
overflows Int.
+    Seq("1e2147483647", "-1E+2147483647", "12e2147483647",
+      "1.5e2147483647").foreach { string =>
+      assert(Decimal.fromString(UTF8String.fromString(string)) === null)
+      checkError(
+        exception = intercept[SparkArithmeticException](
+          Decimal.fromStringANSI(UTF8String.fromString(string))),
+        condition = "NUMERIC_OUT_OF_SUPPORTED_RANGE",
+        parameters = Map("value" -> string))
+    }
+    // Zero fits any decimal type whatever its exponent.
+    Seq("0e39", "-0E+100", "0e2147483647").foreach { string =>
+      assert(Decimal.fromString(UTF8String.fromString(string)) === Decimal(0))

Review Comment:
   Done. The test now also asserts precision 1 and scale 0 for these zeros, and 
fails with "40 did not equal 1" without the normalization.



##########
sql/api/src/main/scala/org/apache/spark/sql/types/Decimal.scala:
##########
@@ -668,8 +671,10 @@ object Decimal {
     try {
       val bigDecimal = stringToJavaBigDecimal(str)
       // We fast fail because constructing a very large JavaBigDecimal to 
Decimal is very slow.
-      // For example: Decimal("6.0790316E+25569151")
-      if (numDigitsInIntegralPart(bigDecimal) > DecimalType.MAX_PRECISION &&
+      // For example: Decimal("6.0790316E+25569151"). Zero fits any decimal 
type whatever its
+      // exponent, e.g. "0e39", so it is not checked.
+      if (bigDecimal.signum != 0 &&

Review Comment:
   Done. Moved into one private helper, `stringBigDecimalToDecimal`, which also 
holds the zero rule.



##########
sql/catalyst/src/test/scala/org/apache/spark/sql/catalyst/expressions/CastWithAnsiOnSuite.scala:
##########
@@ -475,6 +475,14 @@ class CastWithAnsiOnSuite extends CastSuiteBase with 
QueryErrorsBase {
     checkExceptionInExpression[ArithmeticException](
       cast("6E+37", DecimalType(38, 1)),
       "cannot be represented as Decimal(38, 1)")
+    Seq("1e2147483647", "1.5e2147483647", "12e2147483647").foreach { s =>
+      checkExceptionInExpression[ArithmeticException](
+        cast(s, DecimalType(10, 2)),
+        "NUMERIC_OUT_OF_SUPPORTED_RANGE")
+    }
+    Seq("0e39", "0e2147483647").foreach { s =>

Review Comment:
   Done. Moved to `CastSuiteBase`, so they run for ANSI on, ANSI off and 
`try_cast`.



##########
sql/catalyst/src/test/scala/org/apache/spark/sql/types/DecimalSuite.scala:
##########
@@ -446,6 +446,24 @@ class DecimalSuite extends SparkFunSuite with 
PrivateMethodTester with SQLHelper
     }
   }
 
+  test("UTF8String to Decimal with exponent near Int.MaxValue") {

Review Comment:
   Done.



-- 
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: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to