sarutak commented on PR #58786:
URL: https://github.com/apache/spark/pull/58786#issuecomment-5674830279

   Thank you for the fix, @shrirangmhalgi.
   One correction to the overflow behavior, since it makes the case for gating 
stronger. I traced the read path and it does not degrade to `NULL` in non-ANSI 
mode; it is an unconditional failure regardless of ANSI:
   
   - `JDBCValueGetter.DecimalGetter.apply` -> 
`nullSafeConvert(rs.getBigDecimal(...), d => Decimal(d, precision, scale))`
   - `Decimal(d, 38, 18)` -> `Decimal.set(BigDecimal, 38, 18)`, which does 
`setScale(18, ROUND_HALF_UP)` and then throws 
`SparkArithmeticException("NUMERIC_VALUE_OUT_OF_RANGE...")` whenever 
`decimalVal.precision > 38`.
   
   `nullSafeConvert` only guards the `null` input case, so the exception 
propagates. With `Decimal(38,18)` the integer part shrinks from 28 to 20 
digits, so a bare `NUMBER` holding a 21-28 digit integer (large IDs / counters 
/ epoch nanos, common in Oracle) that reads fine today would fail the query 
after this change, in both ANSI and non-ANSI. So the regression is a hard read 
failure, not a silent `NULL`.
   
   Given that, I would second the two requests and add a couple:
   
   1. Gate behind a legacy config. There is a direct precedent in this same 
dialect: `spark.sql.legacy.oracle.timestampMapping.enabled` / 
`spark.sql.legacy.oracle.timestampNTZMapping.enabled` (`SQLConf`), for exactly 
this kind of Oracle type-mapping change. A 
`spark.sql.legacy.oracle.numberMapping`-style flag that restores `scale=10` 
would let users with large-magnitude bare `NUMBER` columns opt out.
   2. Document in `docs/sql-migration-guide.md`, mirroring the existing Oracle 
`TIMESTAMP` entries, and explicitly note the integer-range reduction (28 -> 20 
digits), not just the fractional gain.
   3. On the Teradata comparison: `TeradataDialect` uses `SYSTEM_DEFAULT` to 
work around JDBC reporting precision 40 (above `MAX_PRECISION`), which is a 
different situation from Oracle's `NUMBER` that already fits in 38. The closer 
precedent is the gated `TIMESTAMP` change in this dialect.
   4. Tests: beyond folding the duplicated assertions into the existing 
`OracleDialect jdbc type mapping` test as noted, the most valuable missing 
coverage is the boundary itself: a 21-28 digit integer now failing, and an 
11-18 digit fraction now preserved. The current additions do not exercise the 
actual behavior change.
   
   Net: the one-line change is mechanically correct, but as an unconditional 
change to a long-standing JDBC mapping that can break existing reads, I think 
it needs the config gate + migration note before merge.


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