diff --git a/src/backend/utils/adt/float.c b/src/backend/utils/adt/float.c
index e58ee1609cb4d583e23181232356ba444c3dc313..080d7977a199b3798cbf237d9ec5c2fc3d7e947e 100644
--- a/src/backend/utils/adt/float.c
+++ b/src/backend/utils/adt/float.c
@@ -1461,6 +1461,25 @@ dpow(PG_FUNCTION_ARGS)
 	float8		arg2 = PG_GETARG_FLOAT8(1);
 	float8		result;
 
+	/*
+	 * The POSIX spec says that NaN ^ 0 = 1, and 1 ^ NaN = 1, while all other
+	 * cases with NaN inputs yield NaN (with no error).  Many older platforms
+	 * get one or more of these cases wrong, so deal with them via explicit
+	 * logic rather than trusting pow(3).
+	 */
+	if (isnan(arg1))
+	{
+		if (isnan(arg2) || arg2 != 0.0)
+			PG_RETURN_FLOAT8(get_float8_nan());
+		PG_RETURN_FLOAT8(1.0);
+	}
+	if (isnan(arg2))
+	{
+		if (arg1 != 1.0)
+			PG_RETURN_FLOAT8(get_float8_nan());
+		PG_RETURN_FLOAT8(1.0);
+	}
+
 	/*
 	 * The SQL spec requires that we emit a particular SQLSTATE error code for
 	 * certain error conditions.  Specifically, we don't return a
@@ -1482,12 +1501,11 @@ dpow(PG_FUNCTION_ARGS)
 	 * 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.  Also, some versions
-	 * of MSVC return errno == EDOM and result == NaN for NaN inputs.
+	 * (HUGE_VAL) but finite result to signal overflow.
 	 */
 	errno = 0;
 	result = pow(arg1, arg2);
-	if (errno == EDOM && isnan(result) && !isnan(arg1) && !isnan(arg2))
+	if (errno == EDOM && isnan(result))
 	{
 		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 3fe50b4bf008ee7478a9698a73be7f22b2cfb9c2..3896cdec7216296b19a796884f6242d8b6499219 100644
--- a/src/test/regress/expected/float8-exp-three-digits-win32.out
+++ b/src/test/regress/expected/float8-exp-three-digits-win32.out
@@ -358,6 +358,12 @@ SELECT power(float8 'NaN', float8 'NaN');
    NaN
 (1 row)
 
+SELECT power(float8 '-1', float8 'NaN');
+ power 
+-------
+   NaN
+(1 row)
+
 SELECT power(float8 '1', float8 'NaN');
  power 
 -------
diff --git a/src/test/regress/expected/float8-small-is-zero.out b/src/test/regress/expected/float8-small-is-zero.out
index 46adbe1c4ba9a35be65b47c72247486f11f18013..f8e09390f518c054569594db469e110788de2d6d 100644
--- a/src/test/regress/expected/float8-small-is-zero.out
+++ b/src/test/regress/expected/float8-small-is-zero.out
@@ -362,6 +362,12 @@ SELECT power(float8 'NaN', float8 'NaN');
    NaN
 (1 row)
 
+SELECT power(float8 '-1', float8 'NaN');
+ power 
+-------
+   NaN
+(1 row)
+
 SELECT power(float8 '1', float8 'NaN');
  power 
 -------
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 f215eede103817684cb856c5a189aa362a5a3569..ebfec4cdb6899ba5a53834751c014e999a5dafee 100644
--- a/src/test/regress/expected/float8-small-is-zero_1.out
+++ b/src/test/regress/expected/float8-small-is-zero_1.out
@@ -362,6 +362,12 @@ SELECT power(float8 'NaN', float8 'NaN');
    NaN
 (1 row)
 
+SELECT power(float8 '-1', float8 'NaN');
+ power 
+-------
+   NaN
+(1 row)
+
 SELECT power(float8 '1', float8 'NaN');
  power 
 -------
diff --git a/src/test/regress/expected/float8.out b/src/test/regress/expected/float8.out
index 7159e78d4a7d440c28398b794a42f61b56772042..b05831d45c954918bc65f0f168fb6f711a6fd4d9 100644
--- a/src/test/regress/expected/float8.out
+++ b/src/test/regress/expected/float8.out
@@ -358,6 +358,12 @@ SELECT power(float8 'NaN', float8 'NaN');
    NaN
 (1 row)
 
+SELECT power(float8 '-1', float8 'NaN');
+ power 
+-------
+   NaN
+(1 row)
+
 SELECT power(float8 '1', float8 'NaN');
  power 
 -------
diff --git a/src/test/regress/sql/float8.sql b/src/test/regress/sql/float8.sql
index 5510fe9d3456cd171e9b24439b26c18322e718ad..eeebddd4b78d334ee73a777403b55060475c101a 100644
--- a/src/test/regress/sql/float8.sql
+++ b/src/test/regress/sql/float8.sql
@@ -111,6 +111,7 @@ 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 '1', float8 'NaN');
 SELECT power(float8 'NaN', float8 '0');