From: Tom Lane <tgl@sss.pgh.pa.us>
To: David Rowley <david.rowley@2ndquadrant.com>
Cc: Bruce Momjian <bruce@momjian.us>
Cc: Đặng Minh Hướng <kakalot49@gmail.com>
Cc: PostgreSQL-development <pgsql-hackers@postgresql.org>
Subject: NaNs in numeric_power (was Re: Postgres 11 release notes)
Date: Tue, 15 May 2018 17:55:38 -0400
Message-ID: <10898.1526421338@sss.pgh.pa.us> (raw)
In-Reply-To: <CAKJS1f_xVHwGkR0iL=AsFbJERm6-di=B3z4YW1DZMs4WgfQwyQ@mail.gmail.com>
References: <20180511150852.GA18510@momjian.us>
<CANHVJ5cOKO6M9iTio0sG_pyrPnifUiGrcXC_gjmVtirX2Wpu+w@mail.gmail.com>
<20180514202850.GE5217@momjian.us>
<CAKJS1f-XnmWDfuAibBGObmCGRoHo7tbuMebzAMUtxfJg+bUOcg@mail.gmail.com>
<18049.1526392887@sss.pgh.pa.us>
<CAKJS1f_xVHwGkR0iL=AsFbJERm6-di=B3z4YW1DZMs4WgfQwyQ@mail.gmail.com>
David Rowley <david.rowley@2ndquadrant.com> writes:
> On 16 May 2018 at 02:01, Tom Lane <tgl@sss.pgh.pa.us> wrote:
>> I'm not particularly fussed about getting credit for that. However,
>> looking again at how that patch series turned out --- ie, that
>> we ensured POSIX behavior for NaNs only in HEAD --- I wonder
>> whether we shouldn't do what was mentioned in the commit log for
>> 6bdf1303, and teach numeric_pow() about these same special cases.
>> It seems like it would be more consistent to change both functions
>> for v11, rather than letting that other shoe drop in some future
>> major release.
> I'm inclined to agree. It's hard to imagine these two functions
> behaving differently in regards to NaN input is useful to anyone.
Here's a proposed patch for that.
regards, tom lane
Attachments:make-numeric_power-handle-NaNs-per-POSIX.patch (text/x-diff, 2.5K) downloaddiff --git a/src/backend/utils/adt/numeric.c b/src/backend/utils/adt/numeric.cindex dcf31e3..8dfdffc 100644
*** a/src/backend/utils/adt/numeric.c
--- b/src/backend/utils/adt/numeric.c
*************** numeric_power(PG_FUNCTION_ARGS)
*** 2972,2981 ****
NumericVar result;
/*
! * Handle NaN
*/
! if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
PG_RETURN_NUMERIC(make_result(&const_nan));
/*
* Initialize things
--- 2972,2998 ----
NumericVar result;
/*
! * 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))
! {
! 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
diff --git a/src/test/regress/expected/numeric.out b/src/test/regress/expected/numeric.outindex 17985e8..1cb3c3b 100644
*** a/src/test/regress/expected/numeric.out
--- b/src/test/regress/expected/numeric.out
*************** select 0.0 ^ 12.34;
*** 1664,1669 ****
--- 1664,1700 ----
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
diff --git a/src/test/regress/sql/numeric.sql b/src/test/regress/sql/numeric.sqlindex d77504e..a939412 100644
*** a/src/test/regress/sql/numeric.sql
--- b/src/test/regress/sql/numeric.sql
*************** select (-12.34) ^ 0.0;
*** 911,916 ****
--- 911,923 ----
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;
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Reply to all the recipients using the --to and --cc options:
reply via email
To: pgsql-www@postgresql.org
Cc: tgl@sss.pgh.pa.us, david.rowley@2ndquadrant.com, bruce@momjian.us, kakalot49@gmail.com, pgsql-hackers@postgresql.org
Subject: Re: NaNs in numeric_power (was Re: Postgres 11 release notes)
In-Reply-To: <10898.1526421338@sss.pgh.pa.us>
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
This inbox is served by DDX for PostgreSQL; see mirroring instructions
for how to clone and mirror all data and code used for this inbox