Comparing a decimal with a negative scale to an integer literal panics in `unwrap_cast`
- Dominant language
- Rust
- Stars
- 9.3k
- Forks
- 2.4k
- Avg merge
- 3d 7h
- Merged PRs (30d)
- 344
Description
### Describe the bug
`try_cast_numeric_literal` in `datafusion/expr-common/src/casts.rs` computes `10_i128.pow(scale as u32)` for the target decimal type (and again for a decimal literal's own scale). A negative scale is cast to a huge `u32` exponent, so the multiplication overflows and panics in debug builds (wraps in release builds).
The function is reached from the `unwrap_cast` expression simplifier whenever a cast to a decimal is compared with a numeric literal.
### To Reproduce
Debug build of `datafusion-cli`:
```sql
SELECT arrow_cast(1, 'Decimal128(10, -2)') = 100;
```
```text
thread 'main' panicked at library/core/src/num/mod.rs:475:5:
attempt to multiply with overflow
```
Backtrace goes through `datafusion_expr_common::casts::try_cast_numeric_literal` → `try_cast_literal_to_type` → `unwrap_cast.rs`.
### Expected behavior
No panic. `try_cast_literal_to_type` already returns `None` for casts it cannot express; a negative scale (the decimal holds multiples of `10^-scale`, so there is no integer `10^scale` to rescale by) should be one of them, leaving the cast in place.
### Additional context
Found while running a corpus of extreme-value literals against a debug build of `datafusion-cli`.
Contributor guide
Research direction
Start in datafusion/expr-common/src/casts.rs at try_cast_numeric_literal, then follow its callers through try_cast_literal_to_type and unwrap_cast.rs. Reproduce the SQL query in a debug build of datafusion-cli and verify that negative-scale decimal comparisons no longer panic and leave unexpressible casts in place.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- databases
- Issue type
- Bug
- Difficulty
- 2/5
- Estimated time
- 1-3 hours
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 86/100