This is an automated email from the ASF dual-hosted git repository.
yao pushed a commit to branch branch-4.1
in repository https://gitbox.apache.org/repos/asf/spark.git
The following commit(s) were added to refs/heads/branch-4.1 by this push:
new 94431221bbf2 [SPARK-54750][SQL] Fix ROUND returning NULL for Decimal
values with l…
94431221bbf2 is described below
commit 94431221bbf2a951be6bdf6769eb14015f287bf2
Author: qindongliang <[email protected]>
AuthorDate: Sat Dec 20 00:39:51 2025 +0800
[SPARK-54750][SQL] Fix ROUND returning NULL for Decimal values with l…
### What changes were proposed in this pull request?
Fixed a bug in `RoundBase` where `ROUND` function incorrectly returns
`NULL` for certain Decimal values. The issue was caused by using the input
decimal's runtime precision instead of the target type's precision when calling
`toPrecision()`.
For example, `ROUND(PERCENTILE_APPROX(2150 / 1000.0, 0.95), 3)` incorrectly
returned `NULL` instead of `2.15`.
### Why are the changes needed?
The fix changes `decimal.toPrecision(decimal.precision, s, mode)` to
`decimal.toPrecision(p, s, mode)` in both `nullSafeEval` and `doGenCode`
methods, where `p` is the target DecimalType's precision.
### Does this PR introduce _any_ user-facing change?
Yes, this fixes a bug where ROUND could return NULL for valid decimal
inputs.
### How was this patch tested?
Added regression test in `ApproximatePercentileQuerySuite`.
### Was this patch authored or co-authored using generative AI tooling?
No.
Closes #53529 from qindongliang/SPARK-54750-fix-round-precision.
Lead-authored-by: qindongliang <[email protected]>
Co-authored-by: Kent Yao <[email protected]>
Signed-off-by: Kent Yao <[email protected]>
(cherry picked from commit 1e6d743c7ae235b3a23700d9cfdf924cb5e25d61)
Signed-off-by: Kent Yao <[email protected]>
---
.../spark/sql/catalyst/expressions/mathExpressions.scala | 7 +++----
.../apache/spark/sql/ApproximatePercentileQuerySuite.scala | 12 ++++++++++++
2 files changed, 15 insertions(+), 4 deletions(-)
diff --git
a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/mathExpressions.scala
b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/mathExpressions.scala
index ee3e3e027276..0643e5fba2f3 100644
---
a/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/mathExpressions.scala
+++
b/sql/catalyst/src/main/scala/org/apache/spark/sql/catalyst/expressions/mathExpressions.scala
@@ -1572,7 +1572,7 @@ abstract class RoundBase(child: Expression, scale:
Expression,
val decimal = input1.asInstanceOf[Decimal]
if (_scale >= 0) {
// Overflow cannot happen, so no need to control nullOnOverflow
- decimal.toPrecision(decimal.precision, s, mode)
+ decimal.toPrecision(p, s, mode)
} else {
Decimal(decimal.toBigDecimal.setScale(_scale, mode), p, s)
}
@@ -1644,10 +1644,9 @@ abstract class RoundBase(child: Expression, scale:
Expression,
case DecimalType.Fixed(p, s) =>
if (_scale >= 0) {
s"""
- ${ev.value} = ${ce.value}.toPrecision(${ce.value}.precision(), $s,
- Decimal.$modeStr(), true, null);
+ ${ev.value} = ${ce.value}.toPrecision($p, $s, Decimal.$modeStr(),
true, null);
${ev.isNull} = ${ev.value} == null;"""
- } else {
+ } else {
s"""
${ev.value} = new Decimal().set(${ce.value}.toBigDecimal()
.setScale(${_scale}, Decimal.$modeStr()), $p, $s);
diff --git
a/sql/core/src/test/scala/org/apache/spark/sql/ApproximatePercentileQuerySuite.scala
b/sql/core/src/test/scala/org/apache/spark/sql/ApproximatePercentileQuerySuite.scala
index 3b987529afcb..a92218e1f1de 100644
---
a/sql/core/src/test/scala/org/apache/spark/sql/ApproximatePercentileQuerySuite.scala
+++
b/sql/core/src/test/scala/org/apache/spark/sql/ApproximatePercentileQuerySuite.scala
@@ -370,4 +370,16 @@ class ApproximatePercentileQuerySuite extends QueryTest
with SharedSparkSession
context = ExpectedContext(
"", "", 8, 40, "percentile_approx(col, NULL, 100)"))
}
+
+ test("SPARK-54750: percentile_approx returns NULL for certain decimal
values") {
+ // Regression test: ROUND(PERCENTILE_APPROX(2150/1000.0, 0.95), 3) should
return 2.15
+ checkAnswer(
+ spark.sql("SELECT ROUND(PERCENTILE_APPROX(2150 / 1000.0, 0.95), 3) as
p95"),
+ Row(2.15)
+ )
+ checkAnswer(
+ spark.sql("SELECT ROUND(PERCENTILE_APPROX(2151 / 1000.0, 0.95), 3) as
p95"),
+ Row(2.151)
+ )
+ }
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]