Skip to content

Commit 6f9a86e

Browse files
committed
Fix spherepoint_hash32 on 32 bit platforms
1 parent 94e498d commit 6f9a86e

File tree

2 files changed

+30
-4
lines changed

2 files changed

+30
-4
lines changed

src/point.c

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
#include "point.h"
22
#include "pgs_util.h"
3+
#include <utils/float.h>
4+
#include <common/hashfn.h>
35
#include <catalog/namespace.h>
46

57
/* This file contains definitions for spherical point functions. */
@@ -314,9 +316,31 @@ spherepoint_equal(PG_FUNCTION_ARGS)
314316
Datum
315317
spherepoint_hash32(PG_FUNCTION_ARGS)
316318
{
317-
SPoint *p1 = (SPoint *) PG_GETARG_POINTER(0);
318-
Datum h1 = DirectFunctionCall1(hashfloat8, p1->lat);
319-
Datum h2 = DirectFunctionCall1(hashfloat8, p1->lng);
319+
SPoint *p1 = (SPoint *) PG_GETARG_POINTER(0);
320+
const uint32 h1 = pgs_hashfloat8(p1->lat);
321+
const uint32 h2 = pgs_hashfloat8(p1->lng);
322+
323+
PG_RETURN_INT32(h1 ^ h2);
324+
}
320325

321-
PG_RETURN_INT32(DatumGetInt32(h1) ^ DatumGetInt32(h2));
326+
uint32
327+
pgs_hashfloat8(float8 key)
328+
{
329+
/*
330+
* On IEEE-float machines, minus zero and zero have different bit patterns
331+
* but should compare as equal. We must ensure that they have the same
332+
* hash value, which is most reliably done this way:
333+
*/
334+
if (key == (float8) 0)
335+
PG_RETURN_UINT32(0);
336+
337+
/*
338+
* Similarly, NaNs can have different bit patterns but they should all
339+
* compare as equal. For backwards-compatibility reasons we force them to
340+
* have the hash value of a standard NaN.
341+
*/
342+
if (isnan(key))
343+
key = get_float8_nan();
344+
345+
return hash_bytes((unsigned char *) &key, sizeof(key));
322346
}

src/point.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ typedef struct
1717

1818
Oid get_spoint_type_oid(void);
1919

20+
extern uint32 pgs_hashfloat8(float8 key);
21+
2022
/*
2123
* Calculate the distance between two spherical points in radians.
2224
*/

0 commit comments

Comments
 (0)