On 10 April 2018 at 20:30, Huong Dangminh <huo-dangm...@ys.jp.nec.com> wrote: > Hi, > > There are some cases that power() function does not work > correctly with 'NaN' arguments in Windows environment. > Something like, > > postgres=# select power('NaN',11); > ERROR: value out of range: underflow > postgres=# select power('NaN','NaN'); > ERROR: value out of range: underflow > postgres=# select power(11,'NaN'); > ERROR: value out of range: underflow > > In Linux environment, instead of ERROR it returns 'NaN'. > > The reason here is, > When pow() in float.c:dpow() is called with 'NaN' arguments, > pow() returns 'NaN' but in Windows environment errno is set to > EDOM(invalid floating-point exception). > So, PostgreSQL update "result" and cause an ERROR in CHECKFLOATVAL macro.
I can recreate this when building with MSVC 2012. I confirm that I see the same as you. Microsoft are setting errno to EDOM in the above 3 cases, where in Linux the result is still NaN, just the errno is not set. Looking at [1], it says: * If x or y is a NaN, a NaN shall be returned (unless specified elsewhere in this description). * For any value of y (including NaN), if x is +1, 1.0 shall be returned. * For any value of x (including NaN), if y is ±0, 1.0 shall be returned. Which Microsoft seem to not have broken, they're just also setting the errno to EDOM in the first case, which seems a little strange, but the standard there does not seem to mention that it shouldn't do that. You patch fixes the problem for me, and importantly the two following cases still work: postgres=# select power(1,'NaN'); power ------- 1 (1 row) postgres=# select power('NaN', 0); power ------- 1 (1 row) There's no mention in the SQL standard about NaN handling in the above two cases, but I wonder if it's worth also adding a couple of tests for the above two cases to ensure all platforms are doing the same thing... ? I'd also rather see this line: if (errno == EDOM && isnan(result) && !(isnan(arg1) || isnan(arg2))) written as: if (errno == EDOM && isnan(result) && !isnan(arg1) && !isnan(arg2)) [1] http://pubs.opengroup.org/onlinepubs/9699919799/functions/pow.html -- David Rowley http://www.2ndQuadrant.com/ PostgreSQL Development, 24x7 Support, Training & Services