diff options
Diffstat (limited to 'src/backend/utils/adt/numeric.c')
-rw-r--r-- | src/backend/utils/adt/numeric.c | 21 |
1 files changed, 19 insertions, 2 deletions
diff --git a/src/backend/utils/adt/numeric.c b/src/backend/utils/adt/numeric.c index dcf31e340c1..8dfdffcfbd1 100644 --- a/src/backend/utils/adt/numeric.c +++ b/src/backend/utils/adt/numeric.c @@ -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 |