Skip to content

Commit 9a299df

Browse files
committed
Fix numeric_power() when the exponent is INT_MIN.
In power_var_int(), the computation of the number of significant digits to use in the computation used log(Abs(exp)), which isn't safe because Abs(exp) returns INT_MIN when exp is INT_MIN. Use fabs() instead of Abs(), so that the exponent is cast to a double before the absolute value is taken. Back-patch to 9.6, where this was introduced (by 7d9a473). Discussion: https://postgr.es/m/CAEZATCVd6pMkz=BrZEgBKyqqJrt2xghr=fNc8+Z=5xC6cgWrWA@mail.gmail.com
1 parent 0709b64 commit 9a299df

File tree

3 files changed

+8
-1
lines changed

3 files changed

+8
-1
lines changed

src/backend/utils/adt/numeric.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -8182,7 +8182,7 @@ power_var_int(NumericVar *base, int exp, NumericVar *result, int rscale)
81828182
* to around log10(abs(exp)) digits, so work with this many extra digits
81838183
* of precision (plus a few more for good measure).
81848184
*/
8185-
sig_digits += (int) log(Abs(exp)) + 8;
8185+
sig_digits += (int) log(fabs(exp)) + 8;
81868186

81878187
/*
81888188
* Now we can proceed with the multiplications.

src/test/regress/expected/numeric.out

+6
Original file line numberDiff line numberDiff line change
@@ -1506,6 +1506,12 @@ select 0.12 ^ (-20);
15061506
2608405330458882702.5529619561355838
15071507
(1 row)
15081508

1509+
select 1.000000000123 ^ (-2147483648);
1510+
?column?
1511+
--------------------
1512+
0.7678656556403084
1513+
(1 row)
1514+
15091515
-- cases that used to error out
15101516
select 0.12 ^ (-25);
15111517
?column?

src/test/regress/sql/numeric.sql

+1
Original file line numberDiff line numberDiff line change
@@ -873,6 +873,7 @@ select 3.789 ^ 21;
873873
select 3.789 ^ 35;
874874
select 1.2 ^ 345;
875875
select 0.12 ^ (-20);
876+
select 1.000000000123 ^ (-2147483648);
876877

877878
-- cases that used to error out
878879
select 0.12 ^ (-25);

0 commit comments

Comments
 (0)