Further portability tweaks for float4/float8 hash functions.

Attempting to make hashfloat4() look as much as possible like
hashfloat8(), I'd figured I could replace NaNs with get_float4_nan()
before widening to float8.  However, results from protosciurus
and topminnow show that on some platforms that produces a different
bit-pattern from get_float8_nan(), breaking the intent of ce773f230.
Rearrange so that we use the result of get_float8_nan() for all NaN
cases.  As before, back-patch.
This commit is contained in:
Tom Lane 2021-09-04 16:29:08 -04:00
parent 5edbcbd5b9
commit 718978d9da
1 changed files with 12 additions and 10 deletions

View File

@ -151,14 +151,6 @@ hashfloat4(PG_FUNCTION_ARGS)
if (key == (float4) 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_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.
@ -168,6 +160,16 @@ hashfloat4(PG_FUNCTION_ARGS)
*/
key8 = key;
/*
* 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 float8 NaN. (You'd think we could
* replace key with a float4 NaN and then widen it; but on some old
* platforms, that way produces a different bit pattern.)
*/
if (isnan(key8))
key8 = get_float8_nan();
return hash_any((unsigned char *) &key8, sizeof(key8));
}
@ -181,9 +183,9 @@ hashfloat4extended(PG_FUNCTION_ARGS)
/* Same approach as hashfloat4 */
if (key == (float4) 0)
PG_RETURN_UINT64(seed);
if (isnan(key))
key = get_float4_nan();
key8 = key;
if (isnan(key8))
key8 = get_float8_nan();
return hash_any_extended((unsigned char *) &key8, sizeof(key8), seed);
}