spark-test commented on code in PR #59889:
URL: https://github.com/apache/spark/pull/59889#discussion_r4419695574


##########
sql/api/src/main/scala/org/apache/spark/sql/types/Decimal.scala:
##########
@@ -556,9 +556,29 @@ final class Decimal extends Ordered[Decimal] with 
Serializable {
     if (that.isZero) null
     else Decimal(toJavaBigDecimal.divide(that.toJavaBigDecimal, scale, 
RoundingMode.HALF_UP))
 
-  def %(that: Decimal): Decimal =
-    if (that.isZero) null
-    else Decimal(toJavaBigDecimal.remainder(that.toJavaBigDecimal, 
MATH_CONTEXT))
+  def %(that: Decimal): Decimal = {
+    if (that.isZero) {
+      null
+    } else {
+      val dividend = toJavaBigDecimal
+      val divisor = that.toJavaBigDecimal
+      // Try the context first for speed and for huge trailing-zero quotients 
that exact division
+      // cannot materialize. On failure, retry without its quotient precision 
limit: a quotient
+      // wider than the context may still have a representable remainder.
+      val remainder = try {
+        dividend.remainder(divisor, MATH_CONTEXT)
+      } catch {
+        case error: ArithmeticException =>
+          // Exact division materializes the integral quotient. Two maximum 
SQL decimal
+          // precisions cover ordinary decimal operands; keep the original 
failure for larger
+          // legacy scale gaps instead of attempting a potentially enormous 
allocation.

Review Comment:
   **Nit (P3):** This comment says the original failure is kept for "larger 
legacy scale gaps", but the guard below never reads the legacy config. It 
rethrows whenever `dividend.precision - dividend.scale + divisor.scale` exceeds 
76. That also covers non-legacy `Decimal` values outside SQL bounds:
   
   - `Decimal(1L) % Decimal("3E-100")`: `Decimal(String)` keeps scale 100 
without any config, so the estimate is 101. The new `decimal remainder bounds 
exact retries by divisor scale` test asserts this rethrow outside any 
`withSQLConf`.
   - `Decimal("1" + "0" * 77) % Decimal(3)`: precision 78 and scale 0 give an 
estimate of 78.
   
   The divisor-scale case matters. For a divisor such as `3E-100000000`, the 
exact retry would materialize a quotient of about 10^8 digits. The test's own 
comment states that role ("exact division would succeed here and allow enormous 
quotients for smaller divisors"), but the production comment presents the bound 
as a legacy-only safeguard. A maintainer who trusts it could narrow the guard 
or gate it on the legacy config. For SQL-typed operands the legacy wording does 
hold, because only the legacy negative-scale config lets them exceed the bound. 
The gap is direct `Decimal` values. The divisor-scale test would catch such a 
change, so this is documentation only, and `%` behavior does not need to change.
   
   Suggested comment-only change:
   
   ```suggestion
             // precisions cover in-range SQL operands; wider estimates (legacy 
negative scales or
             // values beyond SQL bounds) keep the original failure to avoid a 
huge allocation.
   ```
   
   **Verification:**
   - **Inspection:** The comment above the quotient-size guard names the 
condition the guard tests, and it no longer presents the rejected inputs as 
limited to legacy negative-scale gaps.
   - **Inspection:** The change touches only comment text, leaving the guard 
expression and the surrounding remainder logic byte-for-byte unchanged.



-- 
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