From: Paul Ramsey Date: Sun, 15 Nov 2009 19:23:21 +0000 (+0000) Subject: Make the _cmp and _eq methods use the same equality conditions so that X-Git-Tag: 1.5.0b1~246 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=876c48433a4c40f42458e7067a4e362fdbe40ee1;p=postgis Make the _cmp and _eq methods use the same equality conditions so that indexed and unindexed answers will be the same. (#292) git-svn-id: http://svn.osgeo.org/postgis/trunk@4814 b70326c6-7e19-0410-871a-916f4a2858ee --- diff --git a/postgis/geography_btree.c b/postgis/geography_btree.c index a6d24fae4..f806f3cfc 100644 --- a/postgis/geography_btree.c +++ b/postgis/geography_btree.c @@ -26,14 +26,6 @@ Datum geography_gt(PG_FUNCTION_ARGS); Datum geography_cmp(PG_FUNCTION_ARGS); -/* -** Calculate a hash code based on the geometry data alone -*/ -static uint32 geography_hash(GSERIALIZED *g) -{ - return DatumGetUInt32(hash_any((void*)g, VARSIZE(g))); -} - /* ** Utility function to return the center point of a ** geocentric bounding box. We don't divide by two @@ -166,16 +158,27 @@ Datum geography_ge(PG_FUNCTION_ARGS) PG_RETURN_BOOL(FALSE); } + +#if 0 +/* +** Calculate a hash code based on the geometry data alone +*/ +static uint32 geography_hash(GSERIALIZED *g) +{ + return DatumGetUInt32(hash_any((void*)g, VARSIZE(g))); +} /* ** BTree support function. Based on two geographies return true if -** they are "equal" and false otherwise. +** they are "equal" and false otherwise. This version uses a hash +** function to try and shoot for a more exact equality test. */ PG_FUNCTION_INFO_V1(geography_eq); Datum geography_eq(PG_FUNCTION_ARGS) { - /* Put aside some stack memory and use it for GIDX pointers. */ + /* Perfect equals test based on hash */ GSERIALIZED *g1 = (GSERIALIZED*)PG_DETOAST_DATUM(PG_GETARG_DATUM(0)); GSERIALIZED *g2 = (GSERIALIZED*)PG_DETOAST_DATUM(PG_GETARG_DATUM(1)); + uint32 h1 = geography_hash(g1); uint32 h2 = geography_hash(g2); @@ -185,7 +188,39 @@ Datum geography_eq(PG_FUNCTION_ARGS) if( h1 == h2 ) PG_RETURN_BOOL(TRUE); + PG_RETURN_BOOL(FALSE); +} +#endif + +/* +** BTree support function. Based on two geographies return true if +** they are "equal" and false otherwise. +*/ +PG_FUNCTION_INFO_V1(geography_eq); +Datum geography_eq(PG_FUNCTION_ARGS) +{ + /* Put aside some stack memory and use it for GIDX pointers. */ + char gboxmem1[GIDX_MAX_SIZE]; + char gboxmem2[GIDX_MAX_SIZE]; + GIDX *gbox1 = (GIDX*)gboxmem1; + GIDX *gbox2 = (GIDX*)gboxmem2; + POINT3D p1, p2; + + /* Must be able to build box for each argument (ie, not empty geometry) */ + if( ! geography_datum_gidx(PG_GETARG_DATUM(0), gbox1) || + ! geography_datum_gidx(PG_GETARG_DATUM(1), gbox2) ) + { + PG_RETURN_BOOL(FALSE); + } + + geography_gidx_center(gbox1, &p1); + geography_gidx_center(gbox2, &p2); + + if( FP_EQUALS(p1.x, p2.x) && FP_EQUALS(p1.y, p2.y) && FP_EQUALS(p1.z, p2.z) ) + PG_RETURN_BOOL(TRUE); + PG_RETURN_BOOL(FALSE); + } /*