summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/backend/access/hash/hashfunc.c21
1 files changed, 21 insertions, 0 deletions
diff --git a/src/backend/access/hash/hashfunc.c b/src/backend/access/hash/hashfunc.c
index a127f3f8b1b..8d4c450b934 100644
--- a/src/backend/access/hash/hashfunc.c
+++ b/src/backend/access/hash/hashfunc.c
@@ -26,6 +26,11 @@
#include "postgres.h"
+#ifdef _MSC_VER
+#include <float.h> /* for _isnan */
+#endif
+#include <math.h>
+
#include "access/hash.h"
#include "utils/builtins.h"
@@ -105,6 +110,14 @@ hashfloat4(PG_FUNCTION_ARGS)
PG_RETURN_UINT32(0);
/*
+ * Similarly, NaNs can have different bit patterns but they should all
+ * compare as equal. For backwards-compatibility reasons we force them to
+ * have the hash value of a standard NaN.
+ */
+ if (isnan(key))
+ key = get_float4_nan();
+
+ /*
* To support cross-type hashing of float8 and float4, we want to return
* the same hash value hashfloat8 would produce for an equal float8 value.
* So, widen the value to float8 and hash that. (We must do this rather
@@ -129,6 +142,14 @@ hashfloat8(PG_FUNCTION_ARGS)
if (key == (float8) 0)
PG_RETURN_UINT32(0);
+ /*
+ * Similarly, NaNs can have different bit patterns but they should all
+ * compare as equal. For backwards-compatibility reasons we force them to
+ * have the hash value of a standard NaN.
+ */
+ if (isnan(key))
+ key = get_float8_nan();
+
return hash_any((unsigned char *) &key, sizeof(key));
}