Make numeric power() handle NaNs according to the modern POSIX spec.
In commit6bdf1303b
, we ensured that power()/^ for float8 would honor the NaN behaviors specified by POSIX standards released in this century, ie NaN ^ 0 = 1 and 1 ^ NaN = 1. However, numeric_power() was not touched and continued to follow the once-common behavior that every case involving NaN input produces NaN. For consistency, let's switch the numeric behavior to the modern spec in the same release that ensures that behavior for float8. (Note that while6bdf1303b
was initially back-patched, we later undid that, concluding that any behavioral change should appear only in v11.) Discussion: https://postgr.es/m/10898.1526421338@sss.pgh.pa.us
This commit is contained in:
parent
b2b82228ee
commit
d1fc750b51
|
@ -2972,10 +2972,27 @@ numeric_power(PG_FUNCTION_ARGS)
|
|||
NumericVar result;
|
||||
|
||||
/*
|
||||
* Handle NaN
|
||||
* Handle NaN cases. We follow the POSIX spec for pow(3), which says that
|
||||
* NaN ^ 0 = 1, and 1 ^ NaN = 1, while all other cases with NaN inputs
|
||||
* yield NaN (with no error).
|
||||
*/
|
||||
if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
|
||||
if (NUMERIC_IS_NAN(num1))
|
||||
{
|
||||
if (!NUMERIC_IS_NAN(num2))
|
||||
{
|
||||
init_var_from_num(num2, &arg2);
|
||||
if (cmp_var(&arg2, &const_zero) == 0)
|
||||
PG_RETURN_NUMERIC(make_result(&const_one));
|
||||
}
|
||||
PG_RETURN_NUMERIC(make_result(&const_nan));
|
||||
}
|
||||
if (NUMERIC_IS_NAN(num2))
|
||||
{
|
||||
init_var_from_num(num1, &arg1);
|
||||
if (cmp_var(&arg1, &const_one) == 0)
|
||||
PG_RETURN_NUMERIC(make_result(&const_one));
|
||||
PG_RETURN_NUMERIC(make_result(&const_nan));
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize things
|
||||
|
|
|
@ -1664,6 +1664,37 @@ select 0.0 ^ 12.34;
|
|||
0.0000000000000000
|
||||
(1 row)
|
||||
|
||||
-- NaNs
|
||||
select 'NaN'::numeric ^ 'NaN'::numeric;
|
||||
?column?
|
||||
----------
|
||||
NaN
|
||||
(1 row)
|
||||
|
||||
select 'NaN'::numeric ^ 0;
|
||||
?column?
|
||||
----------
|
||||
1
|
||||
(1 row)
|
||||
|
||||
select 'NaN'::numeric ^ 1;
|
||||
?column?
|
||||
----------
|
||||
NaN
|
||||
(1 row)
|
||||
|
||||
select 0 ^ 'NaN'::numeric;
|
||||
?column?
|
||||
----------
|
||||
NaN
|
||||
(1 row)
|
||||
|
||||
select 1 ^ 'NaN'::numeric;
|
||||
?column?
|
||||
----------
|
||||
1
|
||||
(1 row)
|
||||
|
||||
-- invalid inputs
|
||||
select 0.0 ^ (-12.34);
|
||||
ERROR: zero raised to a negative power is undefined
|
||||
|
|
|
@ -911,6 +911,13 @@ select (-12.34) ^ 0.0;
|
|||
select 12.34 ^ 0.0;
|
||||
select 0.0 ^ 12.34;
|
||||
|
||||
-- NaNs
|
||||
select 'NaN'::numeric ^ 'NaN'::numeric;
|
||||
select 'NaN'::numeric ^ 0;
|
||||
select 'NaN'::numeric ^ 1;
|
||||
select 0 ^ 'NaN'::numeric;
|
||||
select 1 ^ 'NaN'::numeric;
|
||||
|
||||
-- invalid inputs
|
||||
select 0.0 ^ (-12.34);
|
||||
select (-12.34) ^ 1.2;
|
||||
|
|
Loading…
Reference in New Issue