Commit 1d5d63c
authored
Feat: Allow pow with negative & non-integer exponent on decimals (#19369)
## Which issue does this PR close?
Closes #19348
## Rationale for this change
Previously, pow() on decimal types would error for negative exponents
and non-integer exponents with messages like:
- Arrow error: Arithmetic overflow: Unsupported exp value: -5
- Compute error: Cannot use non-integer exp
- This was a regression from when decimals were cast to float before
pow(). The efficient integer-based algorithm for computing power on
scaled integers cannot handle these cases.
## What changes are included in this PR?
- Modified pow_decimal_int to fallback to pow_decimal_float for negative
exponents
- Modified pow_decimal_float to use an efficient integer path for
non-negative integer exponents, otherwise fallback to f64 computation
Added pow_decimal_float_fallback function that:
- Converts the decimal to f64
- Computes powf(exp)
- Converts back to the original decimal type with proper scaling
- Added decimal_from_i128 helper to convert i128 results back to generic
decimal types (needed for Decimal256 support)
- Updated sqllogictests to expect success for negative/non-integer
exponents
## Are these changes tested?
Yes:
Unit tests for pow_decimal_float_fallback covering negative exponents,
fractional exponents, cube roots
Updated SQL logic tests in decimal.slt
## Are there any user-facing changes?
Yes. The following queries now work instead of returning errors:
```sql
-- Negative exponent
SELECT power(4::decimal(38, 5), -1); -- Returns 0.25
-- Non-integer exponent
SELECT power(2.5, 4.2); -- Returns 46.9
-- Square root via power
SELECT power(4::decimal, 0.5); -- Returns 21 parent d18e670 commit 1d5d63c
File tree
2 files changed
+306
-43
lines changed- datafusion
- functions/src/math
- sqllogictest/test_files
2 files changed
+306
-43
lines changed
0 commit comments