Skip to content

Commit 76a4527

Browse files
author
B Vadlamani
committed
cinnit
1 parent 4bd664e commit 76a4527

2 files changed

Lines changed: 43 additions & 9 deletions

File tree

native/spark-expr/src/conversion_funcs/cast.rs

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2350,6 +2350,11 @@ fn parse_string_to_decimal(s: &str, precision: u8, scale: i8) -> SparkResult<Opt
23502350
// validate and parse mantissa and exponent
23512351
match parse_decimal_str(trimmed) {
23522352
Ok((mantissa, exponent)) => {
2353+
// Special case: zero always fits regardless of scale
2354+
if mantissa == 0 {
2355+
return Ok(Some(0));
2356+
}
2357+
23532358
// Convert to target scale
23542359
let target_scale = scale as i32;
23552360
let scale_adjustment = target_scale - exponent;
@@ -2392,20 +2397,31 @@ fn parse_string_to_decimal(s: &str, precision: u8, scale: i8) -> SparkResult<Opt
23922397

23932398
match scaled_value {
23942399
Some(value) => {
2395-
// Check if it fits target precision
23962400
if is_validate_decimal_precision(value, precision) {
23972401
Ok(Some(value))
23982402
} else {
2399-
Ok(None)
2403+
// Value parsed successfully but exceeds target precision
2404+
Err(SparkError::NumericValueOutOfRange {
2405+
value: trimmed.to_string(),
2406+
precision,
2407+
scale,
2408+
})
24002409
}
24012410
}
24022411
None => {
2403-
// Overflow while scaling
2404-
Ok(None)
2412+
// Overflow while scaling . Throw error and let caller handle it based on EVAL mode
2413+
Err(SparkError::NumericValueOutOfRange {
2414+
value: trimmed.to_string(),
2415+
precision,
2416+
scale,
2417+
})
24052418
}
24062419
}
24072420
}
2408-
Err(_) => Ok(None),
2421+
Err(e) => {
2422+
// raise malformed input
2423+
Err(SparkError::Internal(e))
2424+
}
24092425
}
24102426
}
24112427

spark/src/test/scala/org/apache/comet/CometCastSuite.scala

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -719,9 +719,17 @@ class CometCastSuite extends CometTestBase with AdaptiveSparkPlanHelper {
719719

720720
test("cast StringType to DecimalType(2,2)") {
721721
withSQLConf(CometConf.getExprAllowIncompatConfigKey(classOf[Cast]) -> "true") {
722-
// TODO fix for Spark 4.0.0
723-
assume(!isSpark40Plus)
724-
val values = gen.generateStrings(dataSize, numericPattern, 12).toDF("a")
722+
println("testing with simple input")
723+
val values = Seq(" 3").toDF("a")
724+
Seq(true, false).foreach(ansiEnabled =>
725+
castTest(values, DataTypes.createDecimalType(2, 2), testAnsi = ansiEnabled))
726+
}
727+
}
728+
729+
test("cast StringType to DecimalType(2,2) check if right exception is being thrown") {
730+
withSQLConf(CometConf.getExprAllowIncompatConfigKey(classOf[Cast]) -> "true") {
731+
println("testing with simple input")
732+
val values = Seq(" 3").toDF("a")
725733
Seq(true, false).foreach(ansiEnabled =>
726734
castTest(values, DataTypes.createDecimalType(2, 2), testAnsi = ansiEnabled))
727735
}
@@ -731,7 +739,17 @@ class CometCastSuite extends CometTestBase with AdaptiveSparkPlanHelper {
731739
withSQLConf(CometConf.getExprAllowIncompatConfigKey(classOf[Cast]) -> "true") {
732740
// TODO fix for Spark 4.0.0
733741
assume(!isSpark40Plus)
734-
val values = gen.generateStrings(dataSize, numericPattern, 38).toDF("a")
742+
val values = Seq("0e31").toDF("a")
743+
Seq(true, false).foreach(ansiEnabled =>
744+
castTest(values, DataTypes.createDecimalType(38, 10), testAnsi = ansiEnabled))
745+
}
746+
}
747+
748+
test("cast StringType to DecimalType(38,10) high precision - 0 mantissa") {
749+
withSQLConf(CometConf.getExprAllowIncompatConfigKey(classOf[Cast]) -> "true") {
750+
// TODO fix for Spark 4.0.0
751+
assume(!isSpark40Plus)
752+
val values = Seq("0e31").toDF("a")
735753
Seq(true, false).foreach(ansiEnabled =>
736754
castTest(values, DataTypes.createDecimalType(38, 10), testAnsi = ansiEnabled))
737755
}

0 commit comments

Comments
 (0)