From: Paul Ramsey Date: Tue, 10 Nov 2009 23:58:57 +0000 (+0000) Subject: Make the = operator do a pure equality test X-Git-Tag: 1.5.0b1~261 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=7707e9686d754aa12ea13057165f28a221c8aa8a;p=postgis Make the = operator do a pure equality test git-svn-id: http://svn.osgeo.org/postgis/trunk@4783 b70326c6-7e19-0410-871a-916f4a2858ee --- diff --git a/postgis/geography_btree.c b/postgis/geography_btree.c index e892f8eba..d3e2eda2d 100644 --- a/postgis/geography_btree.c +++ b/postgis/geography_btree.c @@ -26,6 +26,7 @@ #include "access/gist.h" /* For GiST */ #include "access/itup.h" #include "access/skey.h" +#include "access/hash.h" #include "../postgis_config.h" @@ -40,6 +41,15 @@ Datum geography_ge(PG_FUNCTION_ARGS); 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(g, VARSIZE(g))); +} + /* ** Utility function to return the center point of a ** geocentric bounding box. We don't divide by two @@ -180,23 +190,15 @@ 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; + 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); - /* 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_FREE_IF_COPY(g1,0); + PG_FREE_IF_COPY(g2,0); + + if( h1 == h2 ) PG_RETURN_BOOL(TRUE); PG_RETURN_BOOL(FALSE);