Skip to content

Commit

Permalink
[SPARK-37451][SQL] Fix cast string type to decimal type if spark.sql.…
Browse files Browse the repository at this point in the history
…legacy.allowNegativeScaleOfDecimal is enabled

### 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#34811 from wangyum/SPARK-37451.

Authored-by: Yuming Wang <yumwang@ebay.com>
Signed-off-by: Dongjoon Hyun <dongjoon@apache.org>
  • Loading branch information
wangyum authored and dongjoon-hyun committed Dec 9, 2021
1 parent 8f6e439 commit a1214a9
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -602,7 +602,8 @@ object Decimal {
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) {
if (numDigitsInIntegralPart(bigDecimal) > DecimalType.MAX_PRECISION &&
!SQLConf.get.allowNegativeScaleOfDecimalEnabled) {
null
} else {
Decimal(bigDecimal)
Expand All @@ -618,7 +619,8 @@ object Decimal {
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) {
if (numDigitsInIntegralPart(bigDecimal) > DecimalType.MAX_PRECISION &&
!SQLConf.get.allowNegativeScaleOfDecimalEnabled) {
throw QueryExecutionErrors.outOfDecimalTypeRangeError(str)
} else {
Decimal(bigDecimal)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -299,4 +299,19 @@ class DecimalSuite extends SparkFunSuite with PrivateMethodTester with SQLHelper
assert(Decimal.fromStringANSI(UTF8String.fromString(string)) === Decimal(string))
}
}

test("SPARK-37451: Performance improvement regressed String to Decimal cast") {
val values = Array("7.836725755512218E38")
for (string <- values) {
assert(Decimal.fromString(UTF8String.fromString(string)) === null)
intercept[ArithmeticException](Decimal.fromStringANSI(UTF8String.fromString(string)))
}

withSQLConf(SQLConf.LEGACY_ALLOW_NEGATIVE_SCALE_OF_DECIMAL_ENABLED.key -> "true") {
for (string <- values) {
assert(Decimal.fromString(UTF8String.fromString(string)) === Decimal(string))
assert(Decimal.fromStringANSI(UTF8String.fromString(string)) === Decimal(string))
}
}
}
}

0 comments on commit a1214a9

Please sign in to comment.