aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/backend/utils/adt/numeric.c21
-rw-r--r--src/test/regress/expected/numeric.out31
-rw-r--r--src/test/regress/sql/numeric.sql7
3 files changed, 57 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
diff --git a/src/test/regress/expected/numeric.out b/src/test/regress/expected/numeric.out
index 17985e85401..1cb3c3bfab7 100644
--- a/src/test/regress/expected/numeric.out
+++ b/src/test/regress/expected/numeric.out
@@ -1664,6 +1664,37 @@ select 0.0 ^ 12.34;
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.sql
index d77504e6246..a9394123596 100644
--- a/src/test/regress/sql/numeric.sql
+++ b/src/test/regress/sql/numeric.sql
@@ -911,6 +911,13 @@ select (-12.34) ^ 0.0;
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;