aboutsummaryrefslogtreecommitdiff
path: root/src/backend/utils/adt/numeric.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/utils/adt/numeric.c')
-rw-r--r--src/backend/utils/adt/numeric.c21
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