Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitd1fc750

Browse files
committed
Make numeric power() handle NaNs according to the modern POSIX spec.
In commit6bdf130, we ensured that power()/^ for float8 would honorthe NaN behaviors specified by POSIX standards released in this century,ie NaN ^ 0 = 1 and 1 ^ NaN = 1. However, numeric_power() was nottouched and continued to follow the once-common behavior that everycase involving NaN input produces NaN. For consistency, let's switchthe numeric behavior to the modern spec in the same release that ensuresthat behavior for float8.(Note that while6bdf130 was initially back-patched, we later undidthat, concluding that any behavioral change should appear only in v11.)Discussion:https://postgr.es/m/10898.1526421338@sss.pgh.pa.us
1 parentb2b8222 commitd1fc750

File tree

3 files changed

+57
-2
lines changed

3 files changed

+57
-2
lines changed

‎src/backend/utils/adt/numeric.c

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2972,10 +2972,27 @@ numeric_power(PG_FUNCTION_ARGS)
29722972
NumericVarresult;
29732973

29742974
/*
2975-
* Handle NaN
2975+
* Handle NaN cases. We follow the POSIX spec for pow(3), which says that
2976+
* NaN ^ 0 = 1, and 1 ^ NaN = 1, while all other cases with NaN inputs
2977+
* yield NaN (with no error).
29762978
*/
2977-
if (NUMERIC_IS_NAN(num1)||NUMERIC_IS_NAN(num2))
2979+
if (NUMERIC_IS_NAN(num1))
2980+
{
2981+
if (!NUMERIC_IS_NAN(num2))
2982+
{
2983+
init_var_from_num(num2,&arg2);
2984+
if (cmp_var(&arg2,&const_zero)==0)
2985+
PG_RETURN_NUMERIC(make_result(&const_one));
2986+
}
29782987
PG_RETURN_NUMERIC(make_result(&const_nan));
2988+
}
2989+
if (NUMERIC_IS_NAN(num2))
2990+
{
2991+
init_var_from_num(num1,&arg1);
2992+
if (cmp_var(&arg1,&const_one)==0)
2993+
PG_RETURN_NUMERIC(make_result(&const_one));
2994+
PG_RETURN_NUMERIC(make_result(&const_nan));
2995+
}
29792996

29802997
/*
29812998
* Initialize things

‎src/test/regress/expected/numeric.out

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1664,6 +1664,37 @@ select 0.0 ^ 12.34;
16641664
0.0000000000000000
16651665
(1 row)
16661666

1667+
-- NaNs
1668+
select 'NaN'::numeric ^ 'NaN'::numeric;
1669+
?column?
1670+
----------
1671+
NaN
1672+
(1 row)
1673+
1674+
select 'NaN'::numeric ^ 0;
1675+
?column?
1676+
----------
1677+
1
1678+
(1 row)
1679+
1680+
select 'NaN'::numeric ^ 1;
1681+
?column?
1682+
----------
1683+
NaN
1684+
(1 row)
1685+
1686+
select 0 ^ 'NaN'::numeric;
1687+
?column?
1688+
----------
1689+
NaN
1690+
(1 row)
1691+
1692+
select 1 ^ 'NaN'::numeric;
1693+
?column?
1694+
----------
1695+
1
1696+
(1 row)
1697+
16671698
-- invalid inputs
16681699
select 0.0 ^ (-12.34);
16691700
ERROR: zero raised to a negative power is undefined

‎src/test/regress/sql/numeric.sql

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -911,6 +911,13 @@ select (-12.34) ^ 0.0;
911911
select12.34 ^0.0;
912912
select0.0 ^12.34;
913913

914+
-- NaNs
915+
select'NaN'::numeric ^'NaN'::numeric;
916+
select'NaN'::numeric ^0;
917+
select'NaN'::numeric ^1;
918+
select0 ^'NaN'::numeric;
919+
select1 ^'NaN'::numeric;
920+
914921
-- invalid inputs
915922
select0.0 ^ (-12.34);
916923
select (-12.34) ^1.2;

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp