diff --git a/contrib/earthdistance/Makefile b/contrib/earthdistance/Makefile
index 94ad370d599cbccde6bfd3a408d5c5d1c26bce79..49d1505f0418ee2e2c070283687b8da0ee307fbc 100644
--- a/contrib/earthdistance/Makefile
+++ b/contrib/earthdistance/Makefile
@@ -1,4 +1,4 @@
-# $Header: /cvsroot/pgsql/contrib/earthdistance/Makefile,v 1.11 2001/09/06 10:49:29 petere Exp $
+# $Header: /cvsroot/pgsql/contrib/earthdistance/Makefile,v 1.12 2002/09/20 03:47:22 momjian Exp $
 
 subdir = contrib/earthdistance
 top_builddir = ../..
@@ -7,5 +7,6 @@ include $(top_builddir)/src/Makefile.global
 MODULES = earthdistance
 DATA_built = earthdistance.sql
 DOCS = README.earthdistance
+REGRESS = earthdistance
 
 include $(top_srcdir)/contrib/contrib-global.mk
diff --git a/contrib/earthdistance/README.earthdistance b/contrib/earthdistance/README.earthdistance
index f4ecef80fef74847bc930f10f09770bac999ff1c..2ed5c2816595c30c726bfbcff48a83c56a5fb284 100644
--- a/contrib/earthdistance/README.earthdistance
+++ b/contrib/earthdistance/README.earthdistance
@@ -1,3 +1,13 @@
+---------------------------------------------------------------------
+I corrected a bug in the geo_distance code where two double constants
+were declared as int. I changed the distance function to use the
+haversine formula which is more accurate for small distances.
+I added a regression test to the package. I added a grant statement
+to give execute access for geo_distance to public.
+
+Bruno Wolff III
+September 2002
+---------------------------------------------------------------------
 Date: Wed, 1 Apr 1998 15:19:32 -0600 (CST)
 From: Hal Snyder <hal@vailsys.com>
 To: vmehr@ctp.com
diff --git a/contrib/earthdistance/earthdistance.c b/contrib/earthdistance/earthdistance.c
index c1962272f4fb64775e21a858d40f43d9f6dbee02..f069edf13102fde6b629e0e01a3141c4254bd1dd 100644
--- a/contrib/earthdistance/earthdistance.c
+++ b/contrib/earthdistance/earthdistance.c
@@ -6,8 +6,8 @@
 
 
 /* Earth's radius is in statute miles. */
-const int	EARTH_RADIUS = 3958.747716;
-const int	TWO_PI = 2.0 * M_PI;
+const double	EARTH_RADIUS = 3958.747716;
+const double	TWO_PI = 2.0 * M_PI;
 
 double	   *geo_distance(Point *pt1, Point *pt2);
 
@@ -50,6 +50,7 @@ geo_distance(Point *pt1, Point *pt2)
 				long2,
 				lat2;
 	double		longdiff;
+        double		sino;
 	double	   *resultp = palloc(sizeof(double));
 
 	/* convert degrees to radians */
@@ -65,8 +66,10 @@ geo_distance(Point *pt1, Point *pt2)
 	if (longdiff > M_PI)
 		longdiff = TWO_PI - longdiff;
 
-	*resultp = EARTH_RADIUS * acos
-		(sin(lat1) * sin(lat2) + cos(lat1) * cos(lat2) * cos(longdiff));
+        sino = sqrt(sin(fabs(lat1-lat2)/2.)*sin(fabs(lat1-lat2)/2.) +
+                cos(lat1) * cos(lat2) * sin(longdiff/2.)*sin(longdiff/2.));
+        if (sino > 1.) sino = 1.;
+        *resultp = 2. * EARTH_RADIUS * asin(sino);
 
 	return resultp;
 }
diff --git a/contrib/earthdistance/earthdistance.sql.in b/contrib/earthdistance/earthdistance.sql.in
index 087484da5158dae95dcdd87a9e530f92f98fbae6..04485589c74f7041f6a3b062ef3f303fa4f0f9bf 100644
--- a/contrib/earthdistance/earthdistance.sql.in
+++ b/contrib/earthdistance/earthdistance.sql.in
@@ -1,16 +1,12 @@
+begin;
 
 --------------- geo_distance
 
-DROP FUNCTION geo_distance (point, point);
-CREATE FUNCTION geo_distance (point, point) RETURNS float8
-  AS 'MODULE_PATHNAME' LANGUAGE 'c'
-  WITH (isstrict);
-
-SELECT geo_distance ('(1,2)'::point, '(3,4)'::point);
+CREATE OR REPLACE FUNCTION geo_distance (point, point) RETURNS float8
+  LANGUAGE 'c' IMMUTABLE STRICT AS 'MODULE_PATHNAME';
 
 --------------- geo_distance as operator <@>
 
-DROP OPERATOR <@> (point, point);
 CREATE OPERATOR <@> (
   leftarg = point,
   rightarg = point,
@@ -18,7 +14,11 @@ CREATE OPERATOR <@> (
   commutator = <@>
 );
 
--- ( 87.6, 41.8) is in Chicago
--- (106.7, 35.1) is in Albuquerque
--- The cities are about 1100 miles apart
-SELECT '(87.6,41.8)'::point <@> '(106.7,35.1)'::point;
+--
+-- By default this function is made executable by anyone. To restrict
+-- access by default, comment out the following grant command.
+--
+
+grant execute on function geo_distance(point, point) to public;
+
+commit;