Skip to content

Commit a9e99bd

Browse files
wangyumfishcus
authored andcommitted
[SPARK-37451][3.1][SQL] Fix cast string type to decimal type if spark.sql.legacy.allowNegativeScaleOfDecimal is enabled
Backport apache#34811 ### What changes were proposed in this pull request? Fix cast string type to decimal type only if `spark.sql.legacy.allowNegativeScaleOfDecimal` is enabled. For example: ```scala import org.apache.spark.sql.types._ import org.apache.spark.sql.Row spark.conf.set("spark.sql.legacy.allowNegativeScaleOfDecimal", true) val data = Seq(Row("7.836725755512218E38")) val schema = StructType(Array(StructField("a", StringType, false))) val df =spark.createDataFrame(spark.sparkContext.parallelize(data), schema) df.select(col("a").cast(DecimalType(37,-17))).show ``` The result is null since [SPARK-32706](https://issues.apache.org/jira/browse/SPARK-32706). ### Why are the changes needed? Fix regression bug. ### Does this PR introduce _any_ user-facing change? No. ### How was this patch tested? Unit test. Closes apache#34851 from wangyum/SPARK-37451-branch-3.1. Authored-by: Yuming Wang <[email protected]> Signed-off-by: Dongjoon Hyun <[email protected]>
1 parent 9157b18 commit a9e99bd

File tree

2 files changed

+19
-2
lines changed

2 files changed

+19
-2
lines changed

sql/catalyst/src/main/scala/org/apache/spark/sql/types/Decimal.scala

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -601,7 +601,8 @@ object Decimal {
601601
val bigDecimal = stringToJavaBigDecimal(str)
602602
// We fast fail because constructing a very large JavaBigDecimal to Decimal is very slow.
603603
// For example: Decimal("6.0790316E+25569151")
604-
if (numDigitsInIntegralPart(bigDecimal) > DecimalType.MAX_PRECISION) {
604+
if (numDigitsInIntegralPart(bigDecimal) > DecimalType.MAX_PRECISION &&
605+
!SQLConf.get.allowNegativeScaleOfDecimalEnabled) {
605606
null
606607
} else {
607608
Decimal(bigDecimal)
@@ -617,7 +618,8 @@ object Decimal {
617618
val bigDecimal = stringToJavaBigDecimal(str)
618619
// We fast fail because constructing a very large JavaBigDecimal to Decimal is very slow.
619620
// For example: Decimal("6.0790316E+25569151")
620-
if (numDigitsInIntegralPart(bigDecimal) > DecimalType.MAX_PRECISION) {
621+
if (numDigitsInIntegralPart(bigDecimal) > DecimalType.MAX_PRECISION &&
622+
!SQLConf.get.allowNegativeScaleOfDecimalEnabled) {
621623
throw new ArithmeticException(s"out of decimal type range: $str")
622624
} else {
623625
Decimal(bigDecimal)

sql/catalyst/src/test/scala/org/apache/spark/sql/types/DecimalSuite.scala

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -299,4 +299,19 @@ class DecimalSuite extends SparkFunSuite with PrivateMethodTester with SQLHelper
299299
assert(Decimal.fromStringANSI(UTF8String.fromString(string)) === Decimal(string))
300300
}
301301
}
302+
303+
test("SPARK-37451: Performance improvement regressed String to Decimal cast") {
304+
val values = Array("7.836725755512218E38")
305+
for (string <- values) {
306+
assert(Decimal.fromString(UTF8String.fromString(string)) === null)
307+
intercept[ArithmeticException](Decimal.fromStringANSI(UTF8String.fromString(string)))
308+
}
309+
310+
withSQLConf(SQLConf.LEGACY_ALLOW_NEGATIVE_SCALE_OF_DECIMAL_ENABLED.key -> "true") {
311+
for (string <- values) {
312+
assert(Decimal.fromString(UTF8String.fromString(string)) === Decimal(string))
313+
assert(Decimal.fromStringANSI(UTF8String.fromString(string)) === Decimal(string))
314+
}
315+
}
316+
}
302317
}

0 commit comments

Comments
 (0)