diff --git a/src/backend/utils/adt/float.c b/src/backend/utils/adt/float.c index 8aa17e1dcb..e58ee1609c 100644 --- a/src/backend/utils/adt/float.c +++ b/src/backend/utils/adt/float.c @@ -1479,14 +1479,15 @@ dpow(PG_FUNCTION_ARGS) * pow() sets errno only on some platforms, depending on whether it * follows _IEEE_, _POSIX_, _XOPEN_, or _SVID_, so we try to avoid using * errno. However, some platform/CPU combinations return errno == EDOM - * and result == Nan for negative arg1 and very large arg2 (they must be + * and result == NaN for negative arg1 and very large arg2 (they must be * using something different from our floor() test to decide it's * invalid). Other platforms (HPPA) return errno == ERANGE and a large - * (HUGE_VAL) but finite result to signal overflow. + * (HUGE_VAL) but finite result to signal overflow. Also, some versions + * of MSVC return errno == EDOM and result == NaN for NaN inputs. */ errno = 0; result = pow(arg1, arg2); - if (errno == EDOM && isnan(result)) + if (errno == EDOM && isnan(result) && !isnan(arg1) && !isnan(arg2)) { if ((fabs(arg1) > 1 && arg2 >= 0) || (fabs(arg1) < 1 && arg2 < 0)) /* The sign of Inf is not significant in this case. */ diff --git a/src/test/regress/expected/float8-exp-three-digits-win32.out b/src/test/regress/expected/float8-exp-three-digits-win32.out index 7e1153308f..3fe50b4bf0 100644 --- a/src/test/regress/expected/float8-exp-three-digits-win32.out +++ b/src/test/regress/expected/float8-exp-three-digits-win32.out @@ -340,6 +340,36 @@ SELECT power(float8 '144', float8 '0.5'); 12 (1 row) +SELECT power(float8 'NaN', float8 '0.5'); + power +------- + NaN +(1 row) + +SELECT power(float8 '144', float8 'NaN'); + power +------- + NaN +(1 row) + +SELECT power(float8 'NaN', float8 'NaN'); + power +------- + NaN +(1 row) + +SELECT power(float8 '1', float8 'NaN'); + power +------- + 1 +(1 row) + +SELECT power(float8 'NaN', float8 '0'); + power +------- + 1 +(1 row) + -- take exp of ln(f.f1) SELECT '' AS three, f.f1, exp(ln(f.f1)) AS exp_ln_f1 FROM FLOAT8_TBL f diff --git a/src/test/regress/expected/float8-small-is-zero.out b/src/test/regress/expected/float8-small-is-zero.out index 26b8378150..46adbe1c4b 100644 --- a/src/test/regress/expected/float8-small-is-zero.out +++ b/src/test/regress/expected/float8-small-is-zero.out @@ -344,6 +344,36 @@ SELECT power(float8 '144', float8 '0.5'); 12 (1 row) +SELECT power(float8 'NaN', float8 '0.5'); + power +------- + NaN +(1 row) + +SELECT power(float8 '144', float8 'NaN'); + power +------- + NaN +(1 row) + +SELECT power(float8 'NaN', float8 'NaN'); + power +------- + NaN +(1 row) + +SELECT power(float8 '1', float8 'NaN'); + power +------- + 1 +(1 row) + +SELECT power(float8 'NaN', float8 '0'); + power +------- + 1 +(1 row) + -- take exp of ln(f.f1) SELECT '' AS three, f.f1, exp(ln(f.f1)) AS exp_ln_f1 FROM FLOAT8_TBL f diff --git a/src/test/regress/expected/float8-small-is-zero_1.out b/src/test/regress/expected/float8-small-is-zero_1.out index cea27908eb..f215eede10 100644 --- a/src/test/regress/expected/float8-small-is-zero_1.out +++ b/src/test/regress/expected/float8-small-is-zero_1.out @@ -344,6 +344,36 @@ SELECT power(float8 '144', float8 '0.5'); 12 (1 row) +SELECT power(float8 'NaN', float8 '0.5'); + power +------- + NaN +(1 row) + +SELECT power(float8 '144', float8 'NaN'); + power +------- + NaN +(1 row) + +SELECT power(float8 'NaN', float8 'NaN'); + power +------- + NaN +(1 row) + +SELECT power(float8 '1', float8 'NaN'); + power +------- + 1 +(1 row) + +SELECT power(float8 'NaN', float8 '0'); + power +------- + 1 +(1 row) + -- take exp of ln(f.f1) SELECT '' AS three, f.f1, exp(ln(f.f1)) AS exp_ln_f1 FROM FLOAT8_TBL f diff --git a/src/test/regress/expected/float8.out b/src/test/regress/expected/float8.out index 20c985e5df..7159e78d4a 100644 --- a/src/test/regress/expected/float8.out +++ b/src/test/regress/expected/float8.out @@ -340,6 +340,36 @@ SELECT power(float8 '144', float8 '0.5'); 12 (1 row) +SELECT power(float8 'NaN', float8 '0.5'); + power +------- + NaN +(1 row) + +SELECT power(float8 '144', float8 'NaN'); + power +------- + NaN +(1 row) + +SELECT power(float8 'NaN', float8 'NaN'); + power +------- + NaN +(1 row) + +SELECT power(float8 '1', float8 'NaN'); + power +------- + 1 +(1 row) + +SELECT power(float8 'NaN', float8 '0'); + power +------- + 1 +(1 row) + -- take exp of ln(f.f1) SELECT '' AS three, f.f1, exp(ln(f.f1)) AS exp_ln_f1 FROM FLOAT8_TBL f diff --git a/src/test/regress/sql/float8.sql b/src/test/regress/sql/float8.sql index 215e7a4784..5510fe9d34 100644 --- a/src/test/regress/sql/float8.sql +++ b/src/test/regress/sql/float8.sql @@ -108,6 +108,11 @@ SELECT '' AS three, f.f1, |/f.f1 AS sqrt_f1 -- power SELECT power(float8 '144', float8 '0.5'); +SELECT power(float8 'NaN', float8 '0.5'); +SELECT power(float8 '144', float8 'NaN'); +SELECT power(float8 'NaN', float8 'NaN'); +SELECT power(float8 '1', float8 'NaN'); +SELECT power(float8 'NaN', float8 '0'); -- take exp of ln(f.f1) SELECT '' AS three, f.f1, exp(ln(f.f1)) AS exp_ln_f1