diff --git a/doc/src/sgml/datatype.sgml b/doc/src/sgml/datatype.sgml
index 8dda7ec5d633d0270c427bd68ef27da76419c199..07d7cec29b5791f51016d209a1ad695cbdb12069 100644
--- a/doc/src/sgml/datatype.sgml
+++ b/doc/src/sgml/datatype.sgml
@@ -1,5 +1,5 @@
 <!--
-$Header: /cvsroot/pgsql/doc/src/sgml/datatype.sgml,v 1.31 2000/07/14 15:26:21 thomas Exp $
+$Header: /cvsroot/pgsql/doc/src/sgml/datatype.sgml,v 1.32 2000/07/29 18:45:51 tgl Exp $
 -->
 
  <chapter id="datatype">
@@ -1641,13 +1641,6 @@ January 8 04:05:06 1999 PST
 
     <para>
      Paths are output using the first syntax.
-     Note that <productname>Postgres</productname> versions prior to
-     v6.1 used a format for paths which had a single leading parenthesis, 
-     a "closed" flag,
-     an integer count of the number of points, then the list of points followed by a
-     closing parenthesis. 
-     The built-in function <function>upgradepath</function> is supplied to convert
-     paths dumped and reloaded from pre-v6.1 databases.
     </para>
    </sect2>
 
@@ -1687,12 +1680,6 @@ January 8 04:05:06 1999 PST
 
     <para>
      Polygons are output using the first syntax.
-     Note that <productname>Postgres</productname> versions prior to
-     v6.1 used a format for polygons which had a single leading parenthesis, the list
-     of x-axis coordinates, the list of y-axis coordinates,
-     followed by a closing parenthesis.
-     The built-in function <function>upgradepoly</function> is supplied to convert
-     polygons dumped and reloaded from pre-v6.1 databases.
     </para>
    </sect2>
 
diff --git a/doc/src/sgml/func.sgml b/doc/src/sgml/func.sgml
index 09524f8518d314fe786986120ebfa0532fe86231..2e7144b147baba4d287070bfa771bd2aa11772e0 100644
--- a/doc/src/sgml/func.sgml
+++ b/doc/src/sgml/func.sgml
@@ -1423,48 +1423,6 @@ Not defined by this name. Implements the intersection operator '#'
      </tgroup>
     </table>
    </para>
-
-   <para>
-    <table tocentry="1">
-     <title>Geometric Upgrade Functions</title>
-     <tgroup cols="4">
-      <thead>
-       <row>
-	<entry>Function</entry>
-	<entry>Returns</entry>
-	<entry>Description</entry>
-	<entry>Example</entry>
-       </row>
-      </thead>
-      <tbody>
-       <row>
-	<entry>isoldpath(path)</entry>
-	<entry>path</entry>
-	<entry>test path for pre-v6.1 form</entry>
-	<entry>isoldpath('(1,3,0,0,1,1,2,0)'::path)</entry>
-       </row>
-       <row>
-	<entry>revertpoly(polygon)</entry>
-	<entry>polygon</entry>
-	<entry>to pre-v6.1</entry>
-	<entry>revertpoly('((0,0),(1,1),(2,0))'::polygon)</entry>
-       </row>
-       <row>
-	<entry>upgradepath(path)</entry>
-	<entry>path</entry>
-	<entry>to pre-v6.1</entry>
-	<entry>upgradepath('(1,3,0,0,1,1,2,0)'::path)</entry>
-       </row>
-       <row>
-	<entry>upgradepoly(polygon)</entry>
-	<entry>polygon</entry>
-	<entry>to pre-v6.1</entry>
-	<entry>upgradepoly('(0,1,2,0,1,0)'::polygon)</entry>
-       </row>
-      </tbody>
-     </tgroup>
-    </table>
-   </para>
   </sect1>
 
   <sect1>
diff --git a/src/backend/access/rtree/rtproc.c b/src/backend/access/rtree/rtproc.c
index f69e9977332862a900e829244fbea1d97166476d..3cb7efc64a06530217b3d2230ef6e7d913bd9acc 100644
--- a/src/backend/access/rtree/rtproc.c
+++ b/src/backend/access/rtree/rtproc.c
@@ -8,14 +8,14 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/access/rtree/Attic/rtproc.c,v 1.27 2000/06/14 05:24:43 tgl Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/access/rtree/Attic/rtproc.c,v 1.28 2000/07/29 18:45:52 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
 
 #include "postgres.h"
 
-#include "utils/builtins.h"
+#include "utils/geo_decls.h"
 
 
 BOX *
@@ -81,16 +81,15 @@ rt_bigbox_size(BOX *a, float *size)
 	rt_box_size(a, size);
 }
 
-POLYGON    *
-rt_poly_union(POLYGON *a, POLYGON *b)
+Datum
+rt_poly_union(PG_FUNCTION_ARGS)
 {
+	POLYGON	   *a = PG_GETARG_POLYGON_P(0);
+	POLYGON	   *b = PG_GETARG_POLYGON_P(1);
 	POLYGON    *p;
 
 	p = (POLYGON *) palloc(sizeof(POLYGON));
 
-	if (!PointerIsValid(p))
-		elog(ERROR, "Cannot allocate polygon for union");
-
 	MemSet((char *) p, 0, sizeof(POLYGON));		/* zero any holes */
 	p->size = sizeof(POLYGON);
 	p->npts = 0;
@@ -98,7 +97,12 @@ rt_poly_union(POLYGON *a, POLYGON *b)
 	p->boundbox.high.y = Max(a->boundbox.high.y, b->boundbox.high.y);
 	p->boundbox.low.x = Min(a->boundbox.low.x, b->boundbox.low.x);
 	p->boundbox.low.y = Min(a->boundbox.low.y, b->boundbox.low.y);
-	return p;
+
+	/* Avoid leaking memory when handed toasted input. */
+	PG_FREE_IF_COPY(a, 0);
+	PG_FREE_IF_COPY(b, 1);
+
+	PG_RETURN_POLYGON_P(p);
 }
 
 Datum
@@ -125,16 +129,15 @@ rt_poly_size(PG_FUNCTION_ARGS)
 	PG_RETURN_VOID();
 }
 
-POLYGON    *
-rt_poly_inter(POLYGON *a, POLYGON *b)
+Datum
+rt_poly_inter(PG_FUNCTION_ARGS)
 {
+	POLYGON	   *a = PG_GETARG_POLYGON_P(0);
+	POLYGON	   *b = PG_GETARG_POLYGON_P(1);
 	POLYGON    *p;
 
 	p = (POLYGON *) palloc(sizeof(POLYGON));
 
-	if (!PointerIsValid(p))
-		elog(ERROR, "Cannot allocate polygon for intersection");
-
 	MemSet((char *) p, 0, sizeof(POLYGON));		/* zero any holes */
 	p->size = sizeof(POLYGON);
 	p->npts = 0;
@@ -143,11 +146,16 @@ rt_poly_inter(POLYGON *a, POLYGON *b)
 	p->boundbox.low.x = Max(a->boundbox.low.x, b->boundbox.low.x);
 	p->boundbox.low.y = Max(a->boundbox.low.y, b->boundbox.low.y);
 
-	if (p->boundbox.high.x < p->boundbox.low.x || p->boundbox.high.y < p->boundbox.low.y)
+	/* Avoid leaking memory when handed toasted input. */
+	PG_FREE_IF_COPY(a, 0);
+	PG_FREE_IF_COPY(b, 1);
+
+	if (p->boundbox.high.x < p->boundbox.low.x ||
+		p->boundbox.high.y < p->boundbox.low.y)
 	{
 		pfree(p);
-		return (POLYGON *) NULL;
+		PG_RETURN_NULL();
 	}
 
-	return p;
+	PG_RETURN_POLYGON_P(p);
 }
diff --git a/src/backend/utils/adt/geo_ops.c b/src/backend/utils/adt/geo_ops.c
index 37dff3b90892fb9ba8b2aa011015227b147bdb6b..5eef1458aa2dac1157b115c2c87878ef70fdd43c 100644
--- a/src/backend/utils/adt/geo_ops.c
+++ b/src/backend/utils/adt/geo_ops.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/utils/adt/geo_ops.c,v 1.52 2000/06/14 18:17:42 petere Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/utils/adt/geo_ops.c,v 1.53 2000/07/29 18:45:53 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -41,7 +41,6 @@ static CIRCLE *circle_copy(CIRCLE *circle);
 static LINE *line_construct_pm(Point *pt, double m);
 static double lseg_dt(LSEG *l1, LSEG *l2);
 static void make_bound_box(POLYGON *poly);
-static PATH *path_copy(PATH *path);
 static bool plist_same(int npts, Point *p1, Point *p2);
 static Point *point_construct(double x, double y);
 static Point *point_copy(Point *pt);
@@ -434,9 +433,9 @@ box_fill(BOX *result, double x1, double x2, double y1, double y2)
 static BOX *
 box_copy(BOX *box)
 {
-	BOX		   *result = palloc(sizeof(BOX));
+	BOX		   *result = (BOX *) palloc(sizeof(BOX));
 
-	memmove((char *) result, (char *) box, sizeof(BOX));
+	memcpy((char *) result, (char *) box, sizeof(BOX));
 
 	return result;
 }
@@ -1139,20 +1138,17 @@ line_interpt(LINE *l1, LINE *l2)
  *				"(closed, npts, xcoord, ycoord,... )"
  *---------------------------------------------------------*/
 
-PATH *
-path_in(char *str)
+Datum
+path_in(PG_FUNCTION_ARGS)
 {
+	char	   *str = PG_GETARG_CSTRING(0);
 	PATH	   *path;
-
 	int			isopen;
 	char	   *s;
 	int			npts;
 	int			size;
 	int			depth = 0;
 
-	if (!PointerIsValid(str))
-		elog(ERROR, "Bad (null) path external representation");
-
 	if ((npts = pair_count(str, ',')) <= 0)
 		elog(ERROR, "Bad path external representation '%s'", str);
 
@@ -1167,7 +1163,7 @@ path_in(char *str)
 		depth++;
 	}
 
-	size = offsetof(PATH, p[0]) +(sizeof(path->p[0]) * npts);
+	size = offsetof(PATH, p[0]) + sizeof(path->p[0]) * npts;
 	path = palloc(size);
 
 	path->size = size;
@@ -1179,18 +1175,17 @@ path_in(char *str)
 
 	path->closed = (!isopen);
 
-	return path;
-}	/* path_in() */
+	PG_RETURN_PATH_P(path);
+}
 
 
-char *
-path_out(PATH *path)
+Datum
+path_out(PG_FUNCTION_ARGS)
 {
-	if (!PointerIsValid(path))
-		return NULL;
+	PATH	   *path = PG_GETARG_PATH_P(0);
 
-	return path_encode(path->closed, path->npts, (Point *) &(path->p[0]));
-}	/* path_out() */
+	PG_RETURN_CSTRING(path_encode(path->closed, path->npts, path->p));
+}
 
 
 /*----------------------------------------------------------
@@ -1201,111 +1196,99 @@ path_out(PATH *path)
  *		Better relops and access methods coming soon.
  *---------------------------------------------------------*/
 
-bool
-path_n_lt(PATH *p1, PATH *p2)
+Datum
+path_n_lt(PG_FUNCTION_ARGS)
 {
-	return (p1->npts < p2->npts);
+	PATH	   *p1 = PG_GETARG_PATH_P(0);
+	PATH	   *p2 = PG_GETARG_PATH_P(1);
+
+	PG_RETURN_BOOL(p1->npts < p2->npts);
 }
 
-bool
-path_n_gt(PATH *p1, PATH *p2)
+Datum
+path_n_gt(PG_FUNCTION_ARGS)
 {
-	return (p1->npts > p2->npts);
+	PATH	   *p1 = PG_GETARG_PATH_P(0);
+	PATH	   *p2 = PG_GETARG_PATH_P(1);
+
+	PG_RETURN_BOOL(p1->npts > p2->npts);
 }
 
-bool
-path_n_eq(PATH *p1, PATH *p2)
+Datum
+path_n_eq(PG_FUNCTION_ARGS)
 {
-	return (p1->npts == p2->npts);
+	PATH	   *p1 = PG_GETARG_PATH_P(0);
+	PATH	   *p2 = PG_GETARG_PATH_P(1);
+
+	PG_RETURN_BOOL(p1->npts == p2->npts);
 }
 
-bool
-path_n_le(PATH *p1, PATH *p2)
+Datum
+path_n_le(PG_FUNCTION_ARGS)
 {
-	return (p1->npts <= p2->npts);
+	PATH	   *p1 = PG_GETARG_PATH_P(0);
+	PATH	   *p2 = PG_GETARG_PATH_P(1);
+
+	PG_RETURN_BOOL(p1->npts <= p2->npts);
 }
 
-bool
-path_n_ge(PATH *p1, PATH *p2)
+Datum
+path_n_ge(PG_FUNCTION_ARGS)
 {
-	return (p1->npts >= p2->npts);
-}
+	PATH	   *p1 = PG_GETARG_PATH_P(0);
+	PATH	   *p2 = PG_GETARG_PATH_P(1);
 
+	PG_RETURN_BOOL(p1->npts >= p2->npts);
+}
 
 /*----------------------------------------------------------
  * Conversion operators.
  *---------------------------------------------------------*/
 
-bool
-path_isclosed(PATH *path)
-{
-	if (!PointerIsValid(path))
-		return FALSE;
-
-	return path->closed;
-}	/* path_isclosed() */
-
-bool
-path_isopen(PATH *path)
+Datum
+path_isclosed(PG_FUNCTION_ARGS)
 {
-	if (!PointerIsValid(path))
-		return FALSE;
-
-	return !path->closed;
-}	/* path_isopen() */
+	PATH	   *path = PG_GETARG_PATH_P(0);
 
+	PG_RETURN_BOOL(path->closed);
+}
 
-int4
-path_npoints(PATH *path)
+Datum
+path_isopen(PG_FUNCTION_ARGS)
 {
-	if (!PointerIsValid(path))
-		return 0;
+	PATH	   *path = PG_GETARG_PATH_P(0);
 
-	return path->npts;
-}	/* path_npoints() */
+	PG_RETURN_BOOL(! path->closed);
+}
 
-PATH *
-path_close(PATH *path)
+Datum
+path_npoints(PG_FUNCTION_ARGS)
 {
-	PATH	   *result;
-
-	if (!PointerIsValid(path))
-		return NULL;
+	PATH	   *path = PG_GETARG_PATH_P(0);
 
-	result = path_copy(path);
-	result->closed = TRUE;
-
-	return result;
-}	/* path_close() */
+	PG_RETURN_INT32(path->npts);
+}
 
 
-PATH *
-path_open(PATH *path)
+Datum
+path_close(PG_FUNCTION_ARGS)
 {
-	PATH	   *result;
-
-	if (!PointerIsValid(path))
-		return NULL;
-
-	result = path_copy(path);
-	result->closed = FALSE;
+	PATH	   *path = PG_GETARG_PATH_P_COPY(0);
 
-	return result;
-}	/* path_open() */
+	path->closed = TRUE;
 
+	PG_RETURN_PATH_P(path);
+}
 
-static PATH *
-path_copy(PATH *path)
+Datum
+path_open(PG_FUNCTION_ARGS)
 {
-	PATH	   *result;
-	int			size;
+	PATH	   *path = PG_GETARG_PATH_P_COPY(0);
 
-	size = offsetof(PATH, p[0]) +(sizeof(path->p[0]) * path->npts);
-	result = palloc(size);
+	path->closed = FALSE;
 
-	memmove((char *) result, (char *) path, size);
-	return result;
-}	/* path_copy() */
+	PG_RETURN_PATH_P(path);
+}
 
 
 /* path_inter -
@@ -1313,9 +1296,11 @@ path_copy(PATH *path)
  *		Use bounding boxes for a quick (O(n)) check, then do a
  *		O(n^2) iterative edge check.
  */
-bool
-path_inter(PATH *p1, PATH *p2)
+Datum
+path_inter(PG_FUNCTION_ARGS)
 {
+	PATH	   *p1 = PG_GETARG_PATH_P(0);
+	PATH	   *p2 = PG_GETARG_PATH_P(1);
 	BOX			b1,
 				b2;
 	int			i,
@@ -1342,7 +1327,7 @@ path_inter(PATH *p1, PATH *p2)
 		b2.low.y = Min(p2->p[i].y, b2.low.y);
 	}
 	if (!box_overlap(&b1, &b2))
-		return FALSE;
+		PG_RETURN_BOOL(false);
 
 	/* pairwise check lseg intersections */
 	for (i = 0; i < p1->npts - 1; i++)
@@ -1352,90 +1337,71 @@ path_inter(PATH *p1, PATH *p2)
 			statlseg_construct(&seg1, &p1->p[i], &p1->p[i + 1]);
 			statlseg_construct(&seg2, &p2->p[j], &p2->p[j + 1]);
 			if (lseg_intersect(&seg1, &seg2))
-				return TRUE;
+				PG_RETURN_BOOL(true);
 		}
 	}
 
 	/* if we dropped through, no two segs intersected */
-	return FALSE;
-}	/* path_inter() */
+	PG_RETURN_BOOL(false);
+}
 
 /* path_distance()
  * This essentially does a cartesian product of the lsegs in the
- *	two paths, and finds the min distance between any two lsegs
+ *	two paths, and finds the max distance between any two lsegs
  */
-double *
-path_distance(PATH *p1, PATH *p2)
+Datum
+path_distance(PG_FUNCTION_ARGS)
 {
-	double	   *min = NULL,
-			   *tmp;
+	PATH	   *p1 = PG_GETARG_PATH_P(0);
+	PATH	   *p2 = PG_GETARG_PATH_P(1);
+	bool		have_max = false;
+	float8		max = 0.0;		/* initialize to keep compiler quiet */
+	float8		tmp;
 	int			i,
 				j;
 	LSEG		seg1,
 				seg2;
 
-/*
-	statlseg_construct(&seg1, &p1->p[0], &p1->p[1]);
-	statlseg_construct(&seg2, &p2->p[0], &p2->p[1]);
-	min = lseg_distance(&seg1, &seg2);
-*/
-
 	for (i = 0; i < p1->npts - 1; i++)
+	{
 		for (j = 0; j < p2->npts - 1; j++)
 		{
 			statlseg_construct(&seg1, &p1->p[i], &p1->p[i + 1]);
 			statlseg_construct(&seg2, &p2->p[j], &p2->p[j + 1]);
 
-			tmp = lseg_distance(&seg1, &seg2);
-			if ((min == NULL) || (*min < *tmp))
+			tmp = *lseg_distance(&seg1, &seg2);
+			if (!have_max || max < tmp)
 			{
-				if (min != NULL)
-					pfree(min);
-				min = tmp;
+				max = tmp;
+				have_max = true;
 			}
-			else
-				pfree(tmp);
 		}
+	}
 
-	return min;
-}	/* path_distance() */
+	if (! have_max)
+		PG_RETURN_NULL();
+
+	PG_RETURN_FLOAT8(max);
+}
 
 
 /*----------------------------------------------------------
  *	"Arithmetic" operations.
  *---------------------------------------------------------*/
 
-double *
-path_length(PATH *path)
-{
-	double	   *result;
-	int			i;
-
-	result = palloc(sizeof(double));
-
-	*result = 0;
-	for (i = 0; i < (path->npts - 1); i++)
-		*result += point_dt(&path->p[i], &path->p[i + 1]);
-
-	return result;
-}	/* path_length() */
-
-
-#ifdef NOT_USED
-double
-path_ln(PATH *path)
+Datum
+path_length(PG_FUNCTION_ARGS)
 {
-	double		result;
+	PATH	   *path = PG_GETARG_PATH_P(0);
+	float8		result;
 	int			i;
 
-	result = 0;
+	result = 0.0;
 	for (i = 0; i < (path->npts - 1); i++)
 		result += point_dt(&path->p[i], &path->p[i + 1]);
 
-	return result;
-}	/* path_ln() */
-
-#endif
+	PG_RETURN_FLOAT8(result);
+}
 
 /***********************************************************************
  **
@@ -2058,11 +2024,13 @@ dist_ps(Point *pt, LSEG *lseg)
 /*
  ** Distance from a point to a path
  */
-double *
-dist_ppath(Point *pt, PATH *path)
+Datum
+dist_ppath(PG_FUNCTION_ARGS)
 {
-	double	   *result;
-	double	   *tmp;
+	Point	   *pt = PG_GETARG_POINT_P(0);
+	PATH	   *path = PG_GETARG_PATH_P(1);
+	float8		result = 0.0;	/* keep compiler quiet */
+	float8		tmp;
 	int			i;
 	LSEG		lseg;
 
@@ -2070,11 +2038,10 @@ dist_ppath(Point *pt, PATH *path)
 	{
 			/* no points in path? then result is undefined... */
 		case 0:
-			result = NULL;
-			break;
+			PG_RETURN_NULL();
 			/* one point in path? then get distance between two points... */
 		case 1:
-			result = point_distance(pt, &path->p[0]);
+			result = *point_distance(pt, &path->p[0]);
 			break;
 		default:
 			/* make sure the path makes sense... */
@@ -2084,18 +2051,16 @@ dist_ppath(Point *pt, PATH *path)
 			 * the distance from a point to a path is the smallest
 			 * distance from the point to any of its constituent segments.
 			 */
-			result = palloc(sizeof(double));
 			for (i = 0; i < path->npts - 1; i++)
 			{
 				statlseg_construct(&lseg, &path->p[i], &path->p[i + 1]);
-				tmp = dist_ps(pt, &lseg);
-				if (i == 0 || *tmp < *result)
-					*result = *tmp;
-				pfree(tmp);
+				tmp = *dist_ps(pt, &lseg);
+				if (i == 0 || tmp < result)
+					result = tmp;
 			}
 			break;
 	}
-	return result;
+	PG_RETURN_FLOAT8(result);
 }
 
 double *
@@ -2185,26 +2150,22 @@ dist_lb(LINE *line, BOX *box)
 }
 
 
-double *
-dist_cpoly(CIRCLE *circle, POLYGON *poly)
+Datum
+dist_cpoly(PG_FUNCTION_ARGS)
 {
-	double	   *result;
+	CIRCLE	   *circle = PG_GETARG_CIRCLE_P(0);
+	POLYGON	   *poly = PG_GETARG_POLYGON_P(1);
+	float8		result;
+	float8		d;
 	int			i;
-	double	   *d;
 	LSEG		seg;
 
-	if (!PointerIsValid(circle) || !PointerIsValid(poly))
-		elog(ERROR, "Invalid (null) input for distance");
-
-	if (point_inside(&(circle->center), poly->npts, poly->p))
+	if (point_inside(&(circle->center), poly->npts, poly->p) != 0)
 	{
 #ifdef GEODEBUG
 		printf("dist_cpoly- center inside of polygon\n");
 #endif
-		result = palloc(sizeof(double));
-
-		*result = 0;
-		return result;
+		PG_RETURN_FLOAT8(0.0);
 	}
 
 	/* initialize distance with segment between first and last points */
@@ -2212,9 +2173,9 @@ dist_cpoly(CIRCLE *circle, POLYGON *poly)
 	seg.p[0].y = poly->p[0].y;
 	seg.p[1].x = poly->p[poly->npts - 1].x;
 	seg.p[1].y = poly->p[poly->npts - 1].y;
-	result = dist_ps(&(circle->center), &seg);
+	result = *dist_ps(&(circle->center), &seg);
 #ifdef GEODEBUG
-	printf("dist_cpoly- segment 0/n distance is %f\n", *result);
+	printf("dist_cpoly- segment 0/n distance is %f\n", result);
 #endif
 
 	/* check distances for other segments */
@@ -2224,21 +2185,20 @@ dist_cpoly(CIRCLE *circle, POLYGON *poly)
 		seg.p[0].y = poly->p[i].y;
 		seg.p[1].x = poly->p[i + 1].x;
 		seg.p[1].y = poly->p[i + 1].y;
-		d = dist_ps(&(circle->center), &seg);
+		d = *dist_ps(&(circle->center), &seg);
 #ifdef GEODEBUG
-		printf("dist_cpoly- segment %d distance is %f\n", (i + 1), *d);
+		printf("dist_cpoly- segment %d distance is %f\n", (i + 1), d);
 #endif
-		if (*d < *result)
-			*result = *d;
-		pfree(d);
+		if (d < result)
+			result = d;
 	}
 
-	*result -= circle->radius;
-	if (*result < 0)
-		*result = 0;
+	result -= circle->radius;
+	if (result < 0)
+		result = 0;
 
-	return result;
-}	/* dist_cpoly() */
+	PG_RETURN_FLOAT8(result);
+}
 
 
 /*---------------------------------------------------------------------
@@ -2728,19 +2688,18 @@ on_pb(Point *pt, BOX *box)
  *				but not cross.
  *				(we can do p-in-p in lg(n), but it takes preprocessing)
  */
-#define NEXT(A) ((A+1) % path->npts)	/* cyclic "i+1" */
+#define NEXT(A) (((A)+1) % path->npts)	/* cyclic "i+1" */
 
-bool
-on_ppath(Point *pt, PATH *path)
+Datum
+on_ppath(PG_FUNCTION_ARGS)
 {
+	Point	   *pt = PG_GETARG_POINT_P(0);
+	PATH	   *path = PG_GETARG_PATH_P(1);
 	int			i,
 				n;
 	double		a,
 				b;
 
-	if (!PointerIsValid(pt) || !PointerIsValid(path))
-		return FALSE;
-
 	/*-- OPEN --*/
 	if (!path->closed)
 	{
@@ -2751,15 +2710,15 @@ on_ppath(Point *pt, PATH *path)
 			b = point_dt(pt, &path->p[i + 1]);
 			if (FPeq(a + b,
 					 point_dt(&path->p[i], &path->p[i + 1])))
-				return TRUE;
+				PG_RETURN_BOOL(true);
 			a = b;
 		}
-		return FALSE;
+		PG_RETURN_BOOL(false);
 	}
 
 	/*-- CLOSED --*/
-	return point_inside(pt, path->npts, path->p);
-}	/* on_ppath() */
+	PG_RETURN_BOOL(point_inside(pt, path->npts, path->p) != 0);
+}
 
 
 bool
@@ -2951,23 +2910,21 @@ make_bound_box(POLYGON *poly)
  *				"x0,y0,...,xn,yn"
  *				also supports the older style "(x1,...,xn,y1,...yn)"
  *------------------------------------------------------------------*/
-POLYGON    *
-poly_in(char *str)
+Datum
+poly_in(PG_FUNCTION_ARGS)
 {
+	char	   *str = PG_GETARG_CSTRING(0);
 	POLYGON    *poly;
 	int			npts;
 	int			size;
 	int			isopen;
 	char	   *s;
 
-	if (!PointerIsValid(str))
-		elog(ERROR, " Bad (null) polygon external representation");
-
 	if ((npts = pair_count(str, ',')) <= 0)
 		elog(ERROR, "Bad polygon external representation '%s'", str);
 
-	size = offsetof(POLYGON, p[0]) +(sizeof(poly->p[0]) * npts);
-	poly = palloc(size);
+	size = offsetof(POLYGON, p[0]) + sizeof(poly->p[0]) * npts;
+	poly = (POLYGON *) palloc(size);
 
 	MemSet((char *) poly, 0, size);		/* zero any holes */
 	poly->size = size;
@@ -2979,22 +2936,20 @@ poly_in(char *str)
 
 	make_bound_box(poly);
 
-	return poly;
-}	/* poly_in() */
+	PG_RETURN_POLYGON_P(poly);
+}
 
 /*---------------------------------------------------------------
  * poly_out - convert internal POLYGON representation to the
  *			  character string format "((f8,f8),...,(f8,f8))"
- *			  also support old format "(f8,f8,...,f8,f8)"
  *---------------------------------------------------------------*/
-char *
-poly_out(POLYGON *poly)
+Datum
+poly_out(PG_FUNCTION_ARGS)
 {
-	if (!PointerIsValid(poly))
-		return NULL;
+	POLYGON	   *poly = PG_GETARG_POLYGON_P(0);
 
-	return path_encode(TRUE, poly->npts, &(poly->p[0]));
-}	/* poly_out() */
+	PG_RETURN_CSTRING(path_encode(TRUE, poly->npts, poly->p));
+}
 
 
 /*-------------------------------------------------------
@@ -3002,10 +2957,13 @@ poly_out(POLYGON *poly)
  * the right most point of A left of the left most point
  * of B?
  *-------------------------------------------------------*/
-bool
-poly_left(POLYGON *polya, POLYGON *polyb)
+Datum
+poly_left(PG_FUNCTION_ARGS)
 {
-	return polya->boundbox.high.x < polyb->boundbox.low.x;
+	POLYGON	   *polya = PG_GETARG_POLYGON_P(0);
+	POLYGON	   *polyb = PG_GETARG_POLYGON_P(1);
+
+	PG_RETURN_BOOL(polya->boundbox.high.x < polyb->boundbox.low.x);
 }
 
 /*-------------------------------------------------------
@@ -3013,10 +2971,13 @@ poly_left(POLYGON *polya, POLYGON *polyb)
  * the left most point of A left of the right most point
  * of B?
  *-------------------------------------------------------*/
-bool
-poly_overleft(POLYGON *polya, POLYGON *polyb)
+Datum
+poly_overleft(PG_FUNCTION_ARGS)
 {
-	return polya->boundbox.low.x <= polyb->boundbox.high.x;
+	POLYGON	   *polya = PG_GETARG_POLYGON_P(0);
+	POLYGON	   *polyb = PG_GETARG_POLYGON_P(1);
+
+	PG_RETURN_BOOL(polya->boundbox.low.x <= polyb->boundbox.high.x);
 }
 
 /*-------------------------------------------------------
@@ -3024,10 +2985,13 @@ poly_overleft(POLYGON *polya, POLYGON *polyb)
  * the left most point of A right of the right most point
  * of B?
  *-------------------------------------------------------*/
-bool
-poly_right(POLYGON *polya, POLYGON *polyb)
+Datum
+poly_right(PG_FUNCTION_ARGS)
 {
-	return polya->boundbox.low.x > polyb->boundbox.high.x;
+	POLYGON	   *polya = PG_GETARG_POLYGON_P(0);
+	POLYGON	   *polyb = PG_GETARG_POLYGON_P(1);
+
+	PG_RETURN_BOOL(polya->boundbox.low.x > polyb->boundbox.high.x);
 }
 
 /*-------------------------------------------------------
@@ -3035,10 +2999,13 @@ poly_right(POLYGON *polya, POLYGON *polyb)
  * the right most point of A right of the left most point
  * of B?
  *-------------------------------------------------------*/
-bool
-poly_overright(POLYGON *polya, POLYGON *polyb)
+Datum
+poly_overright(PG_FUNCTION_ARGS)
 {
-	return polya->boundbox.high.x > polyb->boundbox.low.x;
+	POLYGON	   *polya = PG_GETARG_POLYGON_P(0);
+	POLYGON	   *polyb = PG_GETARG_POLYGON_P(1);
+
+	PG_RETURN_BOOL(polya->boundbox.high.x > polyb->boundbox.low.x);
 }
 
 /*-------------------------------------------------------
@@ -3048,60 +3015,47 @@ poly_overright(POLYGON *polya, POLYGON *polyb)
  *	direction since polygons are non-directional and are
  *	closed shapes.
  *-------------------------------------------------------*/
-bool
-poly_same(POLYGON *polya, POLYGON *polyb)
+Datum
+poly_same(PG_FUNCTION_ARGS)
 {
-	if (!PointerIsValid(polya) || !PointerIsValid(polyb))
-		return FALSE;
+	POLYGON	   *polya = PG_GETARG_POLYGON_P(0);
+	POLYGON	   *polyb = PG_GETARG_POLYGON_P(1);
 
 	if (polya->npts != polyb->npts)
-		return FALSE;
-
-	return plist_same(polya->npts, polya->p, polyb->p);
+		PG_RETURN_BOOL(false);
 
-#ifdef NOT_USED
-	for (i = 0; i < polya->npts; i++)
-	{
-		if ((polya->p[i].x != polyb->p[i].x)
-			|| (polya->p[i].y != polyb->p[i].y))
-			return FALSE;
-	}
-	return TRUE;
-#endif
-}	/* poly_same() */
+	PG_RETURN_BOOL(plist_same(polya->npts, polya->p, polyb->p));
+}
 
 /*-----------------------------------------------------------------
  * Determine if polygon A overlaps polygon B by determining if
  * their bounding boxes overlap.
+ *
+ * XXX ought to do a more correct check?
  *-----------------------------------------------------------------*/
-bool
-poly_overlap(POLYGON *polya, POLYGON *polyb)
+Datum
+poly_overlap(PG_FUNCTION_ARGS)
 {
-	return box_overlap(&(polya->boundbox), &(polyb->boundbox));
+	POLYGON	   *polya = PG_GETARG_POLYGON_P(0);
+	POLYGON	   *polyb = PG_GETARG_POLYGON_P(1);
+
+	PG_RETURN_BOOL(box_overlap(&(polya->boundbox), &(polyb->boundbox)));
 }
 
 
 /*-----------------------------------------------------------------
- * Determine if polygon A contains polygon B by determining if A's
- * bounding box contains B's bounding box.
+ * Determine if polygon A contains polygon B.
  *-----------------------------------------------------------------*/
-#ifdef NOT_USED
-bool
-poly_contain(POLYGON *polya, POLYGON *polyb)
-{
-	return box_contain(&(polya->boundbox), &(polyb->boundbox));
-}
-
-#endif
-
-bool
-poly_contain(POLYGON *polya, POLYGON *polyb)
+Datum
+poly_contain(PG_FUNCTION_ARGS)
 {
+	POLYGON	   *polya = PG_GETARG_POLYGON_P(0);
+	POLYGON	   *polyb = PG_GETARG_POLYGON_P(1);
 	int			i;
 
-	if (!PointerIsValid(polya) || !PointerIsValid(polyb))
-		return FALSE;
-
+	/*
+	 * Quick check to see if bounding box is contained.
+	 */
 	if (box_contain(&(polya->boundbox), &(polyb->boundbox)))
 	{
 		for (i = 0; i < polyb->npts; i++)
@@ -3111,7 +3065,7 @@ poly_contain(POLYGON *polya, POLYGON *polyb)
 #if GEODEBUG
 				printf("poly_contain- point (%f,%f) not in polygon\n", polyb->p[i].x, polyb->p[i].y);
 #endif
-				return FALSE;
+				PG_RETURN_BOOL(false);
 			}
 		}
 		for (i = 0; i < polya->npts; i++)
@@ -3121,38 +3075,33 @@ poly_contain(POLYGON *polya, POLYGON *polyb)
 #if GEODEBUG
 				printf("poly_contain- point (%f,%f) in polygon\n", polya->p[i].x, polya->p[i].y);
 #endif
-				return FALSE;
+				PG_RETURN_BOOL(false);
 			}
 		}
-		return TRUE;
+		PG_RETURN_BOOL(true);
 	}
+
 #if GEODEBUG
 	printf("poly_contain- bound box ((%f,%f),(%f,%f)) not inside ((%f,%f),(%f,%f))\n",
 		   polyb->boundbox.low.x, polyb->boundbox.low.y, polyb->boundbox.high.x, polyb->boundbox.high.y,
 		   polya->boundbox.low.x, polya->boundbox.low.y, polya->boundbox.high.x, polya->boundbox.high.y);
 #endif
-	return FALSE;
-}	/* poly_contain() */
+	PG_RETURN_BOOL(false);
+}
 
 
 /*-----------------------------------------------------------------
  * Determine if polygon A is contained by polygon B by determining
  * if A's bounding box is contained by B's bounding box.
  *-----------------------------------------------------------------*/
-#ifdef NOT_USED
-bool
-poly_contained(POLYGON *polya, POLYGON *polyb)
+Datum
+poly_contained(PG_FUNCTION_ARGS)
 {
-	return box_contained(&(polya->boundbox), &(polyb->boundbox));
-}
-
-#endif
+	Datum		polya = PG_GETARG_DATUM(0);
+	Datum		polyb = PG_GETARG_DATUM(1);
 
-bool
-poly_contained(POLYGON *polya, POLYGON *polyb)
-{
-	return poly_contain(polyb, polya);
-}	/* poly_contained() */
+	PG_RETURN_DATUM(DirectFunctionCall2(poly_contain, polyb, polya));
+}
 
 
 /* poly_contain_pt()
@@ -3165,39 +3114,37 @@ poly_contained(POLYGON *polya, POLYGON *polyb)
  * (code offered for use by J. Franks in Linux Journal letter.)
  */
 
-bool
-poly_contain_pt(POLYGON *poly, Point *p)
+Datum
+poly_contain_pt(PG_FUNCTION_ARGS)
 {
-	if (!PointerIsValid(poly) || !PointerIsValid(p))
-		return FALSE;
+	POLYGON	   *poly = PG_GETARG_POLYGON_P(0);
+	Point	   *p = PG_GETARG_POINT_P(1);
 
-	return point_inside(p, poly->npts, &(poly->p[0])) != 0;
-}	/* poly_contain_pt() */
+	PG_RETURN_BOOL(point_inside(p, poly->npts, poly->p) != 0);
+}
 
-bool
-pt_contained_poly(Point *p, POLYGON *poly)
+Datum
+pt_contained_poly(PG_FUNCTION_ARGS)
 {
-	if (!PointerIsValid(p) || !PointerIsValid(poly))
-		return FALSE;
+	Point	   *p = PG_GETARG_POINT_P(0);
+	POLYGON	   *poly = PG_GETARG_POLYGON_P(1);
 
-	return poly_contain_pt(poly, p);
-}	/* pt_contained_poly() */
+	PG_RETURN_BOOL(point_inside(p, poly->npts, poly->p) != 0);
+}
 
 
-double *
-poly_distance(POLYGON *polya, POLYGON *polyb)
+Datum
+poly_distance(PG_FUNCTION_ARGS)
 {
-	double	   *result;
-
-	if (!PointerIsValid(polya) || !PointerIsValid(polyb))
-		return NULL;
-
-	result = palloc(sizeof(double));
+#ifdef NOT_USED
+	POLYGON	   *polya = PG_GETARG_POLYGON_P(0);
+	POLYGON	   *polyb = PG_GETARG_POLYGON_P(1);
+#endif
 
-	*result = 0;
+	elog(ERROR, "poly_distance not implemented");
 
-	return result;
-}	/* poly_distance() */
+	PG_RETURN_NULL();
+}
 
 
 /***********************************************************************
@@ -3384,19 +3331,20 @@ box_div(BOX *box, Point *p)
 /* path_add()
  * Concatenate two paths (only if they are both open).
  */
-PATH *
-path_add(PATH *p1, PATH *p2)
+Datum
+path_add(PG_FUNCTION_ARGS)
 {
+	PATH	   *p1 = PG_GETARG_PATH_P(0);
+	PATH	   *p2 = PG_GETARG_PATH_P(1);
 	PATH	   *result;
 	int			size;
 	int			i;
 
-	if (!(PointerIsValid(p1) && PointerIsValid(p2))
-		|| p1->closed || p2->closed)
-		return NULL;
+	if (p1->closed || p2->closed)
+		PG_RETURN_NULL();
 
-	size = offsetof(PATH, p[0]) +(sizeof(p1->p[0]) * (p1->npts + p2->npts));
-	result = palloc(size);
+	size = offsetof(PATH, p[0]) + sizeof(p1->p[0]) * (p1->npts + p2->npts);
+	result = (PATH *) palloc(size);
 
 	result->size = size;
 	result->npts = (p1->npts + p2->npts);
@@ -3413,134 +3361,112 @@ path_add(PATH *p1, PATH *p2)
 		result->p[i + p1->npts].y = p2->p[i].y;
 	}
 
-	return result;
-}	/* path_add() */
+	PG_RETURN_PATH_P(result);
+}
 
 /* path_add_pt()
- * Translation operator.
+ * Translation operators.
  */
-PATH *
-path_add_pt(PATH *path, Point *point)
+Datum
+path_add_pt(PG_FUNCTION_ARGS)
 {
-	PATH	   *result;
+	PATH	   *path = PG_GETARG_PATH_P_COPY(0);
+	Point	   *point = PG_GETARG_POINT_P(1);
 	int			i;
 
-	if ((!PointerIsValid(path)) || (!PointerIsValid(point)))
-		return NULL;
-
-	result = path_copy(path);
-
 	for (i = 0; i < path->npts; i++)
 	{
-		result->p[i].x += point->x;
-		result->p[i].y += point->y;
+		path->p[i].x += point->x;
+		path->p[i].y += point->y;
 	}
 
-	return result;
-}	/* path_add_pt() */
+	PG_RETURN_PATH_P(path);
+}
 
-PATH *
-path_sub_pt(PATH *path, Point *point)
+Datum
+path_sub_pt(PG_FUNCTION_ARGS)
 {
-	PATH	   *result;
+	PATH	   *path = PG_GETARG_PATH_P_COPY(0);
+	Point	   *point = PG_GETARG_POINT_P(1);
 	int			i;
 
-	if ((!PointerIsValid(path)) || (!PointerIsValid(point)))
-		return NULL;
-
-	result = path_copy(path);
-
 	for (i = 0; i < path->npts; i++)
 	{
-		result->p[i].x -= point->x;
-		result->p[i].y -= point->y;
+		path->p[i].x -= point->x;
+		path->p[i].y -= point->y;
 	}
 
-	return result;
-}	/* path_sub_pt() */
-
+	PG_RETURN_PATH_P(path);
+}
 
 /* path_mul_pt()
  * Rotation and scaling operators.
  */
-PATH *
-path_mul_pt(PATH *path, Point *point)
+Datum
+path_mul_pt(PG_FUNCTION_ARGS)
 {
-	PATH	   *result;
+	PATH	   *path = PG_GETARG_PATH_P_COPY(0);
+	Point	   *point = PG_GETARG_POINT_P(1);
 	Point	   *p;
 	int			i;
 
-	if ((!PointerIsValid(path)) || (!PointerIsValid(point)))
-		return NULL;
-
-	result = path_copy(path);
-
 	for (i = 0; i < path->npts; i++)
 	{
 		p = point_mul(&path->p[i], point);
-		result->p[i].x = p->x;
-		result->p[i].y = p->y;
+		path->p[i].x = p->x;
+		path->p[i].y = p->y;
 		pfree(p);
 	}
 
-	return result;
-}	/* path_mul_pt() */
+	PG_RETURN_PATH_P(path);
+}
 
-PATH *
-path_div_pt(PATH *path, Point *point)
+Datum
+path_div_pt(PG_FUNCTION_ARGS)
 {
-	PATH	   *result;
+	PATH	   *path = PG_GETARG_PATH_P_COPY(0);
+	Point	   *point = PG_GETARG_POINT_P(1);
 	Point	   *p;
 	int			i;
 
-	if ((!PointerIsValid(path)) || (!PointerIsValid(point)))
-		return NULL;
-
-	result = path_copy(path);
-
 	for (i = 0; i < path->npts; i++)
 	{
 		p = point_div(&path->p[i], point);
-		result->p[i].x = p->x;
-		result->p[i].y = p->y;
+		path->p[i].x = p->x;
+		path->p[i].y = p->y;
 		pfree(p);
 	}
 
-	return result;
-}	/* path_div_pt() */
+	PG_RETURN_PATH_P(path);
+}
 
 
-Point *
-path_center(PATH *path)
+Datum
+path_center(PG_FUNCTION_ARGS)
 {
-	Point	   *result;
-
-	if (!PointerIsValid(path))
-		return NULL;
+#ifdef NOT_USED
+	PATH	   *path = PG_GETARG_PATH_P(0);
+#endif
 
 	elog(ERROR, "path_center not implemented");
 
-	result = palloc(sizeof(Point));
-	result = NULL;
-
-	return result;
-}	/* path_center() */
+	PG_RETURN_NULL();
+}
 
-POLYGON    *
-path_poly(PATH *path)
+Datum
+path_poly(PG_FUNCTION_ARGS)
 {
+	PATH	   *path = PG_GETARG_PATH_P(0);
 	POLYGON    *poly;
 	int			size;
 	int			i;
 
-	if (!PointerIsValid(path))
-		return NULL;
-
+	/* This is not very consistent --- other similar cases return NULL ... */
 	if (!path->closed)
 		elog(ERROR, "Open path cannot be converted to polygon");
 
-	size = offsetof(POLYGON, p[0]) +(sizeof(poly->p[0]) * path->npts);
-	poly = palloc(size);
+	size = offsetof(POLYGON, p[0]) + sizeof(poly->p[0]) * path->npts;
+	poly = (POLYGON *) palloc(size);
 
 	poly->size = size;
 	poly->npts = path->npts;
@@ -3553,57 +3479,8 @@ path_poly(PATH *path)
 
 	make_bound_box(poly);
 
-	return poly;
-}	/* path_polygon() */
-
-
-/* upgradepath()
- * Convert path read from old-style string into correct representation.
- *
- * Old-style: '(closed,#pts,x1,y1,...)' where closed is a boolean flag
- * New-style: '((x1,y1),...)' for closed path
- *			  '[(x1,y1),...]' for open path
- */
-PATH *
-upgradepath(PATH *path)
-{
-	PATH	   *result;
-	int			size,
-				npts;
-	int			i;
-
-	if (!PointerIsValid(path) || (path->npts < 2))
-		return NULL;
-
-	if (!isoldpath(path))
-		elog(ERROR, "upgradepath: path already upgraded?");
-
-	npts = (path->npts - 1);
-	size = offsetof(PATH, p[0]) +(sizeof(path->p[0]) * npts);
-	result = palloc(size);
-	MemSet((char *) result, 0, size);
-
-	result->size = size;
-	result->npts = npts;
-	result->closed = (path->p[0].x != 0);
-
-	for (i = 0; i < result->npts; i++)
-	{
-		result->p[i].x = path->p[i + 1].x;
-		result->p[i].y = path->p[i + 1].y;
-	}
-
-	return result;
-}	/* upgradepath() */
-
-bool
-isoldpath(PATH *path)
-{
-	if (!PointerIsValid(path) || (path->npts < 2))
-		return FALSE;
-
-	return path->npts == (path->p[0].y + 1);
-}	/* isoldpath() */
+	PG_RETURN_POLYGON_P(poly);
+}
 
 
 /***********************************************************************
@@ -3612,67 +3489,64 @@ isoldpath(PATH *path)
  **
  ***********************************************************************/
 
-int4
-poly_npoints(POLYGON *poly)
+Datum
+poly_npoints(PG_FUNCTION_ARGS)
 {
-	if (!PointerIsValid(poly))
-		return FALSE;
+	POLYGON	   *poly = PG_GETARG_POLYGON_P(0);
 
-	return poly->npts;
-}	/* poly_npoints() */
+	PG_RETURN_INT32(poly->npts);
+}
 
 
-Point *
-poly_center(POLYGON *poly)
+Datum
+poly_center(PG_FUNCTION_ARGS)
 {
+	POLYGON	   *poly = PG_GETARG_POLYGON_P(0);
 	Point	   *result;
 	CIRCLE	   *circle;
 
-	if (!PointerIsValid(poly))
-		return NULL;
-
-	if (PointerIsValid(circle = poly_circle(poly)))
+	circle = DatumGetCircleP(DirectFunctionCall1(poly_circle,
+												 PolygonPGetDatum(poly)));
+	if (PointerIsValid(circle))
 	{
 		result = circle_center(circle);
 		pfree(circle);
-
 	}
 	else
-		result = NULL;
+		PG_RETURN_NULL();
 
-	return result;
-}	/* poly_center() */
+	PG_RETURN_POINT_P(result);
+}
 
 
-BOX *
-poly_box(POLYGON *poly)
+Datum
+poly_box(PG_FUNCTION_ARGS)
 {
+	POLYGON	   *poly = PG_GETARG_POLYGON_P(0);
 	BOX		   *box;
 
-	if (!PointerIsValid(poly) || (poly->npts < 1))
-		return NULL;
+	if (poly->npts < 1)
+		PG_RETURN_NULL();
 
 	box = box_copy(&poly->boundbox);
 
-	return box;
-}	/* poly_box() */
+	PG_RETURN_BOX_P(box);
+}
 
 
 /* box_poly()
  * Convert a box to a polygon.
  */
-POLYGON    *
-box_poly(BOX *box)
+Datum
+box_poly(PG_FUNCTION_ARGS)
 {
+	BOX		   *box = PG_GETARG_BOX_P(0);
 	POLYGON    *poly;
 	int			size;
 
-	if (!PointerIsValid(box))
-		return NULL;
-
 	/* map four corners of the box to a polygon */
-	size = offsetof(POLYGON, p[0]) +(sizeof(poly->p[0]) * 4);
-	poly = palloc(size);
+	size = offsetof(POLYGON, p[0]) + sizeof(poly->p[0]) * 4;
+	poly = (POLYGON *) palloc(size);
 
 	poly->size = size;
 	poly->npts = 4;
@@ -3686,24 +3560,23 @@ box_poly(BOX *box)
 	poly->p[3].x = box->high.x;
 	poly->p[3].y = box->low.y;
 
-	box_fill(&poly->boundbox, box->high.x, box->low.x, box->high.y, box->low.y);
+	box_fill(&poly->boundbox, box->high.x, box->low.x,
+			 box->high.y, box->low.y);
 
-	return poly;
-}	/* box_poly() */
+	PG_RETURN_POLYGON_P(poly);
+}
 
 
-PATH *
-poly_path(POLYGON *poly)
+Datum
+poly_path(PG_FUNCTION_ARGS)
 {
+	POLYGON	   *poly = PG_GETARG_POLYGON_P(0);
 	PATH	   *path;
 	int			size;
 	int			i;
 
-	if (!PointerIsValid(poly) || (poly->npts < 0))
-		return NULL;
-
-	size = offsetof(PATH, p[0]) +(sizeof(path->p[0]) * poly->npts);
-	path = palloc(size);
+	size = offsetof(PATH, p[0]) + sizeof(path->p[0]) * poly->npts;
+	path = (PATH *) palloc(size);
 
 	path->size = size;
 	path->npts = poly->npts;
@@ -3715,103 +3588,8 @@ poly_path(POLYGON *poly)
 		path->p[i].y = poly->p[i].y;
 	}
 
-	return path;
-}	/* poly_path() */
-
-
-/* upgradepoly()
- * Convert polygon read as pre-v6.1 string to new interpretation.
- * Old-style: '(x1,x2,...,y1,y2,...)'
- * New-style: '(x1,y1,x2,y2,...)'
- */
-POLYGON    *
-upgradepoly(POLYGON *poly)
-{
-	POLYGON    *result;
-	int			size;
-	int			n2,
-				i,
-				ii;
-
-	if (!PointerIsValid(poly) || (poly->npts < 1))
-		return NULL;
-
-	size = offsetof(POLYGON, p[0]) +(sizeof(poly->p[0]) * poly->npts);
-	result = palloc(size);
-	MemSet((char *) result, 0, size);
-
-	result->size = size;
-	result->npts = poly->npts;
-
-	n2 = poly->npts / 2;
-
-	for (i = 0; i < n2; i++)
-	{
-		result->p[2 * i].x = poly->p[i].x;		/* even indices */
-		result->p[2 * i + 1].x = poly->p[i].y;	/* odd indices */
-	}
-
-	if ((ii = ((poly->npts % 2) ? 1 : 0)))
-	{
-		result->p[poly->npts - 1].x = poly->p[n2].x;
-		result->p[0].y = poly->p[n2].y;
-	}
-
-	for (i = 0; i < n2; i++)
-	{
-		result->p[2 * i + ii].y = poly->p[i + n2 + ii].x;		/* even (+offset)
-																 * indices */
-		result->p[2 * i + ii + 1].y = poly->p[i + n2 + ii].y;	/* odd (+offset) indices */
-	}
-
-	return result;
-}	/* upgradepoly() */
-
-/* revertpoly()
- * Reverse effect of upgradepoly().
- */
-POLYGON    *
-revertpoly(POLYGON *poly)
-{
-	POLYGON    *result;
-	int			size;
-	int			n2,
-				i,
-				ii;
-
-	if (!PointerIsValid(poly) || (poly->npts < 1))
-		return NULL;
-
-	size = offsetof(POLYGON, p[0]) +(sizeof(poly->p[0]) * poly->npts);
-	result = palloc(size);
-	MemSet((char *) result, 0, size);
-
-	result->size = size;
-	result->npts = poly->npts;
-
-	n2 = poly->npts / 2;
-
-	for (i = 0; i < n2; i++)
-	{
-		result->p[i].x = poly->p[2 * i].x;		/* even indices */
-		result->p[i].y = poly->p[2 * i + 1].x;	/* odd indices */
-	}
-
-	if ((ii = ((poly->npts % 2) ? 1 : 0)))
-	{
-		result->p[n2].x = poly->p[poly->npts - 1].x;
-		result->p[n2].y = poly->p[0].y;
-	}
-
-	for (i = 0; i < n2; i++)
-	{
-		result->p[i + n2 + ii].x = poly->p[2 * i + ii].y;		/* even (+offset)
-																 * indices */
-		result->p[i + n2 + ii].y = poly->p[2 * i + ii + 1].y;	/* odd (+offset) indices */
-	}
-
-	return result;
-}	/* revertpoly() */
+	PG_RETURN_PATH_P(path);
+}
 
 
 /***********************************************************************
@@ -4398,19 +4176,17 @@ circle_poly(PG_FUNCTION_ARGS)
  * XXX This algorithm should use weighted means of line segments
  *	rather than straight average values of points - tgl 97/01/21.
  */
-CIRCLE *
-poly_circle(POLYGON *poly)
+Datum
+poly_circle(PG_FUNCTION_ARGS)
 {
+	POLYGON	   *poly = PG_GETARG_POLYGON_P(0);
 	CIRCLE	   *circle;
 	int			i;
 
-	if (!PointerIsValid(poly))
-		return NULL;
-
 	if (poly->npts < 2)
 		elog(ERROR, "Unable to convert polygon to circle");
 
-	circle = palloc(sizeof(CIRCLE));
+	circle = (CIRCLE *) palloc(sizeof(CIRCLE));
 
 	circle->center.x = 0;
 	circle->center.y = 0;
@@ -4431,8 +4207,8 @@ poly_circle(POLYGON *poly)
 	if (FPzero(circle->radius))
 		elog(ERROR, "Unable to convert polygon to circle");
 
-	return circle;
-}	/* poly_circle() */
+	PG_RETURN_CIRCLE_P(circle);
+}
 
 
 /***********************************************************************
@@ -4450,7 +4226,6 @@ point_inside(Point *p, int npts, Point *plist)
 				y0;
 	double		px,
 				py;
-
 	int			i;
 	double		x,
 				y;
@@ -4494,7 +4269,7 @@ point_inside(Point *p, int npts, Point *plist)
 	if (crossnum != 0)
 		return 1;
 	return 0;
-}	/* point_inside() */
+}
 
 
 /* lseg_crossing()
diff --git a/src/backend/utils/adt/geo_selfuncs.c b/src/backend/utils/adt/geo_selfuncs.c
index e5f239612eb5139a78d46233267db2cfca0dcb94..d4122e89b191ea5c9ccd1184135c96f9a447e369 100644
--- a/src/backend/utils/adt/geo_selfuncs.c
+++ b/src/backend/utils/adt/geo_selfuncs.c
@@ -9,7 +9,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/utils/adt/geo_selfuncs.c,v 1.16 2000/06/05 07:28:52 tgl Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/utils/adt/geo_selfuncs.c,v 1.17 2000/07/29 18:45:53 tgl Exp $
  *
  *	XXX These are totally bogus.  Perhaps someone will make them do
  *	something reasonable, someday.
@@ -18,7 +18,7 @@
  */
 #include "postgres.h"
 
-#include "utils/builtins.h"
+#include "utils/geo_decls.h"
 
 
 /*
diff --git a/src/include/catalog/pg_proc.h b/src/include/catalog/pg_proc.h
index 9f4ed9f87bba69feabdde7947475f089ac12d104..8e96586d57511355f9d8da9e70fe4ecc26e5edc8 100644
--- a/src/include/catalog/pg_proc.h
+++ b/src/include/catalog/pg_proc.h
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2000, PostgreSQL, Inc
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: pg_proc.h,v 1.150 2000/07/29 03:26:43 tgl Exp $
+ * $Id: pg_proc.h,v 1.151 2000/07/29 18:45:57 tgl Exp $
  *
  * NOTES
  *	  The script catalog/genbki.sh reads this file and generates .bki
@@ -256,9 +256,9 @@ DATA(insert OID = 119 (  lseg_in		   PGUID 11 f t t t 1 f 601 "0" 100 0 0 100  l
 DESCR("(internal)");
 DATA(insert OID = 120 (  lseg_out		   PGUID 11 f t t t 1 f 23  "0" 100 0 0 100  lseg_out - ));
 DESCR("(internal)");
-DATA(insert OID = 121 (  path_in		   PGUID 11 f t t t 1 f 602 "0" 100 0 0 100  path_in - ));
+DATA(insert OID = 121 (  path_in		   PGUID 12 f t t t 1 f 602 "0" 100 0 0 100  path_in - ));
 DESCR("(internal)");
-DATA(insert OID = 122 (  path_out		   PGUID 11 f t t t 1 f 23  "0" 100 0 0 100  path_out - ));
+DATA(insert OID = 122 (  path_out		   PGUID 12 f t t t 1 f 23  "0" 100 0 0 100  path_out - ));
 DESCR("(internal)");
 DATA(insert OID = 123 (  box_in			   PGUID 11 f t t t 1 f 603 "0" 100 0 0 100  box_in - ));
 DESCR("(internal)");
@@ -288,7 +288,7 @@ DATA(insert OID = 135 (  point_eq		   PGUID 11 f t t t 2 f 16 "600 600" 100 0 0
 DESCR("same as");
 DATA(insert OID = 136 (  on_pb			   PGUID 11 f t t t 2 f 16 "600 603" 100 0 0 100	on_pb - ));
 DESCR("point is inside");
-DATA(insert OID = 137 (  on_ppath		   PGUID 11 f t t t 2 f 16 "600 602" 100 0 1 0  on_ppath - ));
+DATA(insert OID = 137 (  on_ppath		   PGUID 12 f t t t 2 f 16 "600 602" 100 0 1 0  on_ppath - ));
 DESCR("contained in");
 DATA(insert OID = 138 (  box_center		   PGUID 11 f t t t 1 f 600 "603" 100 1 0 100  box_center - ));
 DESCR("center of");
@@ -408,9 +408,9 @@ DATA(insert OID = 195 (  rt_box_size	   PGUID 11 f t t t 2 f 700 "603 700" 100 0
 DESCR("r-tree");
 DATA(insert OID = 196 (  rt_bigbox_size    PGUID 11 f t t t 2 f 700 "603 700" 100 0 0 100  rt_bigbox_size - ));
 DESCR("r-tree");
-DATA(insert OID = 197 (  rt_poly_union	   PGUID 11 f t t t 2 f 604 "604 604" 100 0 0 100  rt_poly_union - ));
+DATA(insert OID = 197 (  rt_poly_union	   PGUID 12 f t t t 2 f 604 "604 604" 100 0 0 100  rt_poly_union - ));
 DESCR("r-tree");
-DATA(insert OID = 198 (  rt_poly_inter	   PGUID 11 f t t t 2 f 604 "604 604" 100 0 0 100  rt_poly_inter - ));
+DATA(insert OID = 198 (  rt_poly_inter	   PGUID 12 f t t t 2 f 604 "604 604" 100 0 0 100  rt_poly_inter - ));
 DESCR("r-tree");
 DATA(insert OID = 199 (  rt_poly_size	   PGUID 12 f t t t 2 f 23 "604 700" 100 0 0 100  rt_poly_size - ));
 DESCR("r-tree");
@@ -470,9 +470,9 @@ DESCR("smaller of two");
 
 DATA(insert OID = 225 (  lseg_center	   PGUID 11 f t t t 1 f 600 "601" 100 0 0 100  lseg_center - ));
 DESCR("center of");
-DATA(insert OID = 226 (  path_center	   PGUID 11 f t t t 1 f 600 "602" 100 0 0 100  path_center - ));
+DATA(insert OID = 226 (  path_center	   PGUID 12 f t t t 1 f 600 "602" 100 0 0 100  path_center - ));
 DESCR("center of");
-DATA(insert OID = 227 (  poly_center	   PGUID 11 f t t t 1 f 600 "604" 100 0 0 100  poly_center - ));
+DATA(insert OID = 227 (  poly_center	   PGUID 12 f t t t 1 f 600 "604" 100 0 0 100  poly_center - ));
 DESCR("center of");
 
 DATA(insert OID = 228 (  dround			   PGUID 11 f t t t 1 f 701 "701" 100 0 0 100  dround - ));
@@ -709,25 +709,25 @@ DESCR("btree(internal)");
 DATA(insert OID = 338 (  btbuild		   PGUID 12 f t f t 5 f 23 "0 0 0 0 0" 100 0 0 100  btbuild - ));
 DESCR("btree(internal)");
 
-DATA(insert OID = 339 (  poly_same		   PGUID 11 f t t t 2 f 16 "604 604" 100 0 1 0  poly_same - ));
+DATA(insert OID = 339 (  poly_same		   PGUID 12 f t t t 2 f 16 "604 604" 100 0 1 0  poly_same - ));
 DESCR("same as");
-DATA(insert OID = 340 (  poly_contain	   PGUID 11 f t t t 2 f 16 "604 604" 100 0 1 0  poly_contain - ));
+DATA(insert OID = 340 (  poly_contain	   PGUID 12 f t t t 2 f 16 "604 604" 100 0 1 0  poly_contain - ));
 DESCR("contains");
-DATA(insert OID = 341 (  poly_left		   PGUID 11 f t t t 2 f 16 "604 604" 100 0 1 0  poly_left - ));
+DATA(insert OID = 341 (  poly_left		   PGUID 12 f t t t 2 f 16 "604 604" 100 0 1 0  poly_left - ));
 DESCR("is left of");
-DATA(insert OID = 342 (  poly_overleft	   PGUID 11 f t t t 2 f 16 "604 604" 100 0 1 0  poly_overleft - ));
+DATA(insert OID = 342 (  poly_overleft	   PGUID 12 f t t t 2 f 16 "604 604" 100 0 1 0  poly_overleft - ));
 DESCR("overlaps, but does not extend to right of");
-DATA(insert OID = 343 (  poly_overright    PGUID 11 f t t t 2 f 16 "604 604" 100 0 1 0  poly_overright - ));
+DATA(insert OID = 343 (  poly_overright    PGUID 12 f t t t 2 f 16 "604 604" 100 0 1 0  poly_overright - ));
 DESCR("overlaps, but does not extend to left of");
-DATA(insert OID = 344 (  poly_right		   PGUID 11 f t t t 2 f 16 "604 604" 100 0 1 0  poly_right - ));
-DESCR("is left of");
-DATA(insert OID = 345 (  poly_contained    PGUID 11 f t t t 2 f 16 "604 604" 100 0 1 0  poly_contained - ));
+DATA(insert OID = 344 (  poly_right		   PGUID 12 f t t t 2 f 16 "604 604" 100 0 1 0  poly_right - ));
+DESCR("is right of");
+DATA(insert OID = 345 (  poly_contained    PGUID 12 f t t t 2 f 16 "604 604" 100 0 1 0  poly_contained - ));
 DESCR("contained in");
-DATA(insert OID = 346 (  poly_overlap	   PGUID 11 f t t t 2 f 16 "604 604" 100 0 1 0  poly_overlap - ));
+DATA(insert OID = 346 (  poly_overlap	   PGUID 12 f t t t 2 f 16 "604 604" 100 0 1 0  poly_overlap - ));
 DESCR("overlaps");
-DATA(insert OID = 347 (  poly_in		   PGUID 11 f t t t 1 f 604 "0" 100 0 1 0  poly_in - ));
+DATA(insert OID = 347 (  poly_in		   PGUID 12 f t t t 1 f 604 "0" 100 0 1 0  poly_in - ));
 DESCR("(internal)");
-DATA(insert OID = 348 (  poly_out		   PGUID 11 f t t t 1 f 23  "0" 100 0 1 0  poly_out - ));
+DATA(insert OID = 348 (  poly_out		   PGUID 12 f t t t 1 f 23  "0" 100 0 1 0  poly_out - ));
 DESCR("(internal)");
 
 DATA(insert OID = 350 (  btint2cmp		   PGUID 12 f t t t 2 f 23 "21 21" 100 0 0 100  btint2cmp - ));
@@ -771,10 +771,10 @@ DATA(insert OID = 368 (  close_sb		   PGUID 11 f t t t 2 f 600 "601 603" 100 0 0
 DESCR("closest point to line segment on box");
 DATA(insert OID = 369 (  on_ps			   PGUID 11 f t t t 2 f 16 "600 601" 100 0 0 100	on_ps - ));
 DESCR("point contained in segment");
-DATA(insert OID = 370 (  path_distance	   PGUID 11 f t t t 2 f 701 "602 602" 100 0 1 0  path_distance - ));
+DATA(insert OID = 370 (  path_distance	   PGUID 12 f t t t 2 f 701 "602 602" 100 0 1 0  path_distance - ));
 DESCR("distance between paths");
-DATA(insert OID = 371 (  dist_ppath		   PGUID 11 f t t t 2 f 701 "600 602" 100 0 1 0  dist_ppath - ));
-DESCR("distance between point and patch");
+DATA(insert OID = 371 (  dist_ppath		   PGUID 12 f t t t 2 f 701 "600 602" 100 0 1 0  dist_ppath - ));
+DESCR("distance between point and path");
 DATA(insert OID = 372 (  on_sb			   PGUID 11 f t t t 2 f 16 "601 603" 100 0 0 100	on_sb - ));
 DESCR("contained in");
 DATA(insert OID = 373 (  inter_sb		   PGUID 11 f t t t 2 f 16 "601 603" 100 0 0 100	inter_sb - ));
@@ -960,9 +960,9 @@ DATA(insert OID = 726 (  dist_lb		   PGUID 11 f t t t 2 f 701 "628 603" 100 0 0
 DESCR("distance between line and box");
 DATA(insert OID = 727 (  dist_sl		   PGUID 11 f t t t 2 f 701 "601 628" 100 0 0 100  dist_sl - ));
 DESCR("distance between lseg and line");
-DATA(insert OID = 728 (  dist_cpoly		   PGUID 11 f t t t 2 f 701 "718 604" 100 0 0 100  dist_cpoly - ));
+DATA(insert OID = 728 (  dist_cpoly		   PGUID 12 f t t t 2 f 701 "718 604" 100 0 0 100  dist_cpoly - ));
 DESCR("distance between");
-DATA(insert OID = 729 (  poly_distance	   PGUID 11 f t t t 2 f 701 "604 604" 100 0 0 100  poly_distance - ));
+DATA(insert OID = 729 (  poly_distance	   PGUID 12 f t t t 2 f 701 "604 604" 100 0 0 100  poly_distance - ));
 DESCR("distance between");
 
 DATA(insert OID = 740 (  text_lt		   PGUID 12 f t t t 2 f 16 "25 25" 100 0 0 0	text_lt - ));
@@ -1151,16 +1151,6 @@ DESCR("multiply");
 
 /* OIDS 900 - 999 */
 
-/* isoldpath, upgradepath, upgradepoly, revertpoly are used to update pre-v6.1 to v6.1 - tgl 97/06/03 */
-DATA(insert OID = 936 (  isoldpath		   PGUID 11 f t f t 1 f  16 "602" 100 0 0 100  isoldpath - ));
-DESCR("");
-DATA(insert OID = 937 (  upgradepath	   PGUID 11 f t f t 1 f 602 "602" 100 0 0 100  upgradepath - ));
-DESCR("");
-DATA(insert OID = 938 (  upgradepoly	   PGUID 11 f t f t 1 f 604 "604" 100 0 0 100  upgradepoly - ));
-DESCR("");
-DATA(insert OID = 939 (  revertpoly		   PGUID 11 f t f t 1 f 604 "604" 100 0 0 100  revertpoly - ));
-DESCR("");
-
 DATA(insert OID = 940 (  mod			   PGUID 12 f t t t 2 f 21 "21 21" 100 0 0 100  int2mod - ));
 DESCR("modulus");
 DATA(insert OID = 941 (  mod			   PGUID 12 f t t t 2 f 23 "23 23" 100 0 0 100  int4mod - ));
@@ -1216,7 +1206,7 @@ DESCR("large object unlink(delete)");
 DATA(insert OID = 972 (  regproctooid	   PGUID 12 f t t t 1 f  26 "24" 100 0 0 100	regproctooid - ));
 DESCR("get oid for regproc");
 
-DATA(insert OID = 973 (  path_inter		   PGUID 11 f t t t 2 f  16 "602 602" 100 0 10 100  path_inter - ));
+DATA(insert OID = 973 (  path_inter		   PGUID 12 f t t t 2 f  16 "602 602" 100 0 10 100  path_inter - ));
 DESCR("paths intersect?");
 DATA(insert OID = 975 (  area			   PGUID 11 f t t t 1 f 701 "603" 100 0 0 100  box_area - ));
 DESCR("box area");
@@ -1230,17 +1220,17 @@ DATA(insert OID = 980 (  box_intersect	   PGUID 11 f t t t 2 f 603 "603 603" 100
 DESCR("box intersection (another box)");
 DATA(insert OID = 981 (  diagonal		   PGUID 11 f t t t 1 f 601 "603" 100 0 0 100  box_diagonal - ));
 DESCR("box diagonal");
-DATA(insert OID = 982 (  path_n_lt		   PGUID 11 f t t t 2 f 16 "602 602" 100 0 0 100	path_n_lt - ));
+DATA(insert OID = 982 (  path_n_lt		   PGUID 12 f t t t 2 f 16 "602 602" 100 0 0 100	path_n_lt - ));
 DESCR("less-than");
-DATA(insert OID = 983 (  path_n_gt		   PGUID 11 f t t t 2 f 16 "602 602" 100 0 0 100	path_n_gt - ));
+DATA(insert OID = 983 (  path_n_gt		   PGUID 12 f t t t 2 f 16 "602 602" 100 0 0 100	path_n_gt - ));
 DESCR("greater-than");
-DATA(insert OID = 984 (  path_n_eq		   PGUID 11 f t t t 2 f 16 "602 602" 100 0 0 100	path_n_eq - ));
+DATA(insert OID = 984 (  path_n_eq		   PGUID 12 f t t t 2 f 16 "602 602" 100 0 0 100	path_n_eq - ));
 DESCR("equal");
-DATA(insert OID = 985 (  path_n_le		   PGUID 11 f t t t 2 f 16 "602 602" 100 0 0 100	path_n_le - ));
+DATA(insert OID = 985 (  path_n_le		   PGUID 12 f t t t 2 f 16 "602 602" 100 0 0 100	path_n_le - ));
 DESCR("less-than-or-equal");
-DATA(insert OID = 986 (  path_n_ge		   PGUID 11 f t t t 2 f 16 "602 602" 100 0 0 100	path_n_ge - ));
+DATA(insert OID = 986 (  path_n_ge		   PGUID 12 f t t t 2 f 16 "602 602" 100 0 0 100	path_n_ge - ));
 DESCR("greater-than-or-equal");
-DATA(insert OID = 987 (  path_length	   PGUID 11 f t t t 1 f 701 "602" 100 0 1 0  path_length - ));
+DATA(insert OID = 987 (  path_length	   PGUID 12 f t t t 1 f 701 "602" 100 0 1 0  path_length - ));
 DESCR("sum of path segments");
 DATA(insert OID = 988 (  point_ne		   PGUID 11 f t t t 2 f 16 "600 600" 100 0 0 100	point_ne - ));
 DESCR("not equal");
@@ -1780,36 +1770,36 @@ DATA(insert OID = 1425 (  box_div			PGUID 11 f t t t 2 f 603 "603 600" 100 0 0 1
 DESCR("divide box by point (scale)");
 DATA(insert OID = 1426 (  path_contain_pt	PGUID 14 f t t t 2 f	16 "602 600" 100 0 0 100  "select on_ppath($2, $1)" - ));
 DESCR("path contains point?");
-DATA(insert OID = 1428 (  poly_contain_pt	PGUID 11 f t t t 2 f	16 "604 600" 100 0 0 100  poly_contain_pt - ));
+DATA(insert OID = 1428 (  poly_contain_pt	PGUID 12 f t t t 2 f	16 "604 600" 100 0 0 100  poly_contain_pt - ));
 DESCR("polygon contains point?");
-DATA(insert OID = 1429 (  pt_contained_poly PGUID 11 f t t t 2 f	16 "600 604" 100 0 0 100  pt_contained_poly - ));
+DATA(insert OID = 1429 (  pt_contained_poly PGUID 12 f t t t 2 f	16 "600 604" 100 0 0 100  pt_contained_poly - ));
 DESCR("point contained by polygon?");
 
-DATA(insert OID = 1430 (  isclosed			PGUID 11 f t t t 1 f	16 "602" 100 0 0 100  path_isclosed - ));
+DATA(insert OID = 1430 (  isclosed			PGUID 12 f t t t 1 f	16 "602" 100 0 0 100  path_isclosed - ));
 DESCR("path closed?");
-DATA(insert OID = 1431 (  isopen			PGUID 11 f t t t 1 f	16 "602" 100 0 0 100  path_isopen - ));
+DATA(insert OID = 1431 (  isopen			PGUID 12 f t t t 1 f	16 "602" 100 0 0 100  path_isopen - ));
 DESCR("path open?");
-DATA(insert OID = 1432 (  path_npoints		PGUID 11 f t t t 1 f	23 "602" 100 0 0 100  path_npoints - ));
+DATA(insert OID = 1432 (  path_npoints		PGUID 12 f t t t 1 f	23 "602" 100 0 0 100  path_npoints - ));
 DESCR("# points in path");
 
 /* pclose and popen might better be named close and open, but that crashes initdb.
  * - thomas 97/04/20
  */
 
-DATA(insert OID = 1433 (  pclose			PGUID 11 f t t t 1 f 602 "602" 100 0 0 100  path_close - ));
+DATA(insert OID = 1433 (  pclose			PGUID 12 f t t t 1 f 602 "602" 100 0 0 100  path_close - ));
 DESCR("close path");
-DATA(insert OID = 1434 (  popen				PGUID 11 f t t t 1 f 602 "602" 100 0 0 100  path_open - ));
+DATA(insert OID = 1434 (  popen				PGUID 12 f t t t 1 f 602 "602" 100 0 0 100  path_open - ));
 DESCR("open path");
-DATA(insert OID = 1435 (  path_add			PGUID 11 f t t t 2 f 602 "602 602" 100 0 0 100  path_add - ));
-DESCR("addition");
-DATA(insert OID = 1436 (  path_add_pt		PGUID 11 f t t t 2 f 602 "602 600" 100 0 0 100  path_add_pt - ));
-DESCR("addition");
-DATA(insert OID = 1437 (  path_sub_pt		PGUID 11 f t t t 2 f 602 "602 600" 100 0 0 100  path_sub_pt - ));
-DESCR("subtract");
-DATA(insert OID = 1438 (  path_mul_pt		PGUID 11 f t t t 2 f 602 "602 600" 100 0 0 100  path_mul_pt - ));
-DESCR("multiply");
-DATA(insert OID = 1439 (  path_div_pt		PGUID 11 f t t t 2 f 602 "602 600" 100 0 0 100  path_div_pt - ));
-DESCR("divide");
+DATA(insert OID = 1435 (  path_add			PGUID 12 f t t t 2 f 602 "602 602" 100 0 0 100  path_add - ));
+DESCR("concatenate open paths");
+DATA(insert OID = 1436 (  path_add_pt		PGUID 12 f t t t 2 f 602 "602 600" 100 0 0 100  path_add_pt - ));
+DESCR("add (translate path)");
+DATA(insert OID = 1437 (  path_sub_pt		PGUID 12 f t t t 2 f 602 "602 600" 100 0 0 100  path_sub_pt - ));
+DESCR("subtract (translate path)");
+DATA(insert OID = 1438 (  path_mul_pt		PGUID 12 f t t t 2 f 602 "602 600" 100 0 0 100  path_mul_pt - ));
+DESCR("multiply (rotate/scale path)");
+DATA(insert OID = 1439 (  path_div_pt		PGUID 12 f t t t 2 f 602 "602 600" 100 0 0 100  path_div_pt - ));
+DESCR("divide (rotate/scale path)");
 
 DATA(insert OID = 1440 (  point				PGUID 11 f t t t 2 f 600 "701 701" 100 0 0 100  point - ));
 DESCR("convert x, y to point");
@@ -1822,15 +1812,15 @@ DESCR("multiply points (scale/rotate)");
 DATA(insert OID = 1444 (  point_div			PGUID 11 f t t t 2 f 600 "600 600" 100 0 0 100  point_div - ));
 DESCR("divide points (scale/rotate)");
 
-DATA(insert OID = 1445 (  poly_npoints		PGUID 11 f t t t 1 f	23 "604" 100 0 0 100  poly_npoints - ));
+DATA(insert OID = 1445 (  poly_npoints		PGUID 12 f t t t 1 f	23 "604" 100 0 0 100  poly_npoints - ));
 DESCR("number of points in polygon");
-DATA(insert OID = 1446 (  box				PGUID 11 f t t t 1 f 603 "604" 100 0 0 100  poly_box - ));
+DATA(insert OID = 1446 (  box				PGUID 12 f t t t 1 f 603 "604" 100 0 0 100  poly_box - ));
 DESCR("convert polygon to bounding box");
-DATA(insert OID = 1447 (  path				PGUID 11 f t t t 1 f 602 "604" 100 0 0 100  poly_path - ));
+DATA(insert OID = 1447 (  path				PGUID 12 f t t t 1 f 602 "604" 100 0 0 100  poly_path - ));
 DESCR("convert polygon to path");
-DATA(insert OID = 1448 (  polygon			PGUID 11 f t t t 1 f 604 "603" 100 0 0 100  box_poly - ));
+DATA(insert OID = 1448 (  polygon			PGUID 12 f t t t 1 f 604 "603" 100 0 0 100  box_poly - ));
 DESCR("convert box to polygon");
-DATA(insert OID = 1449 (  polygon			PGUID 11 f t t t 1 f 604 "602" 100 0 0 100  path_poly - ));
+DATA(insert OID = 1449 (  polygon			PGUID 12 f t t t 1 f 604 "602" 100 0 0 100  path_poly - ));
 DESCR("convert path to polygon");
 
 DATA(insert OID = 1450 (  circle_in			PGUID 11 f t t t 1 f 718 "0" 100 0 1 0  circle_in - ));
@@ -1881,7 +1871,7 @@ DATA(insert OID = 1472 (  circle_center		PGUID 11 f t t t 1 f 600 "718" 100 0 1
 DESCR("center of");
 DATA(insert OID = 1473 (  circle			PGUID 11 f t t t 2 f 718 "600 701" 100 0 1 0	circle - ));
 DESCR("convert point and radius to circle");
-DATA(insert OID = 1474 (  circle			PGUID 11 f t t t 1 f 718 "604" 100 0 1 0	poly_circle - ));
+DATA(insert OID = 1474 (  circle			PGUID 12 f t t t 1 f 718 "604" 100 0 1 0	poly_circle - ));
 DESCR("convert polygon to circle");
 DATA(insert OID = 1475 (  polygon			PGUID 12 f t t t 2 f 604 "23 718" 100 0 1 0  circle_poly - ));
 DESCR("convert vertex count and circle to polygon");
@@ -1940,17 +1930,17 @@ DESCR("lines horizontal?");
 
 DATA(insert OID = 1530 (  length			PGUID 11 f t t t 1 f 701 "601" 100 0 1 0	lseg_length - ));
 DESCR("distance between endpoints");
-DATA(insert OID = 1531 (  length			PGUID 11 f t t t 1 f 701 "602" 100 0 1 0	path_length - ));
+DATA(insert OID = 1531 (  length			PGUID 12 f t t t 1 f 701 "602" 100 0 1 0	path_length - ));
 DESCR("sum of path segments");
 
 
 DATA(insert OID = 1532 (  point				PGUID 11 f t t t 1 f 600 "601" 100 0 0 100  lseg_center - ));
 DESCR("center of");
-DATA(insert OID = 1533 (  point				PGUID 11 f t t t 1 f 600 "602" 100 0 0 100  path_center - ));
+DATA(insert OID = 1533 (  point				PGUID 12 f t t t 1 f 600 "602" 100 0 0 100  path_center - ));
 DESCR("center of");
 DATA(insert OID = 1534 (  point				PGUID 11 f t t t 1 f 600 "603" 100 1 0 100  box_center - ));
 DESCR("center of");
-DATA(insert OID = 1540 (  point				PGUID 11 f t t t 1 f 600 "604" 100 0 0 100  poly_center - ));
+DATA(insert OID = 1540 (  point				PGUID 12 f t t t 1 f 600 "604" 100 0 0 100  poly_center - ));
 DESCR("center of");
 DATA(insert OID = 1541 (  lseg				PGUID 11 f t t t 1 f 601 "603" 100 0 0 100  box_diagonal - ));
 DESCR("");
@@ -1960,9 +1950,9 @@ DATA(insert OID = 1543 (  center			PGUID 11 f t t t 1 f 600 "718" 100 0 1 0	circ
 DESCR("center of");
 DATA(insert OID = 1544 (  polygon			PGUID 14 f t t t 1 f 604 "718" 100 0 0 100  "select polygon(12, $1)" - ));
 DESCR("convert circle to 12-vertex polygon");
-DATA(insert OID = 1545 (  npoints			PGUID 11 f t t t 1 f	23 "602" 100 0 0 100  path_npoints - ));
+DATA(insert OID = 1545 (  npoints			PGUID 12 f t t t 1 f	23 "602" 100 0 0 100  path_npoints - ));
 DESCR("# points in path");
-DATA(insert OID = 1556 (  npoints			PGUID 11 f t t t 1 f	23 "604" 100 0 0 100  poly_npoints - ));
+DATA(insert OID = 1556 (  npoints			PGUID 12 f t t t 1 f	23 "604" 100 0 0 100  poly_npoints - ));
 DESCR("number of points in polygon");
 
 DATA(insert OID = 1564 (  zpbit_in			PGUID 11 f t t t 1 f 1560 "0" 100 0 0 100  zpbit_in - ));
diff --git a/src/include/catalog/pg_type.h b/src/include/catalog/pg_type.h
index 04457d7296ee1fdd1525c1e2c67bd56d1bb728bb..0dfc5c9f19d8f70a1f13ac5c377b246217e6979d 100644
--- a/src/include/catalog/pg_type.h
+++ b/src/include/catalog/pg_type.h
@@ -8,7 +8,7 @@
  * Portions Copyright (c) 1996-2000, PostgreSQL, Inc
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: pg_type.h,v 1.94 2000/07/29 03:26:43 tgl Exp $
+ * $Id: pg_type.h,v 1.95 2000/07/29 18:46:00 tgl Exp $
  *
  * NOTES
  *	  the genbki.sh script reads this file and generates .bki
@@ -267,13 +267,13 @@ DESCR("geometric point '(x, y)'");
 DATA(insert OID = 601 (  lseg	   PGUID 32  48 f b t \054 0 600 lseg_in lseg_out lseg_in lseg_out d p _null_ ));
 DESCR("geometric line segment '(pt1,pt2)'");
 #define LSEGOID			601
-DATA(insert OID = 602 (  path	   PGUID -1  -1 f b t \054 0 0 path_in path_out path_in path_out d p _null_ ));
+DATA(insert OID = 602 (  path	   PGUID -1  -1 f b t \054 0 0 path_in path_out path_in path_out d x _null_ ));
 DESCR("geometric path '(pt1,...)'");
 #define PATHOID			602
 DATA(insert OID = 603 (  box	   PGUID 32 100 f b t \073 0 600 box_in box_out box_in box_out d p _null_ ));
 DESCR("geometric box '(lower left,upper right)'");
 #define BOXOID			603
-DATA(insert OID = 604 (  polygon   PGUID -1  -1 f b t \054 0   0 poly_in poly_out poly_in poly_out d p _null_ ));
+DATA(insert OID = 604 (  polygon   PGUID -1  -1 f b t \054 0   0 poly_in poly_out poly_in poly_out d x _null_ ));
 DESCR("geometric polygon '(pt1,...)'");
 #define POLYGONOID		604
 DATA(insert OID = 605 (  filename  PGUID 256 -1 f b t \054 0  18 filename_in filename_out filename_in filename_out i p _null_ ));
diff --git a/src/include/utils/builtins.h b/src/include/utils/builtins.h
index 9b19a3ae85cbb493d691d740c6bccc98784611f9..4d5aeff643d9a9fe5119a48583873102cde2d90c 100644
--- a/src/include/utils/builtins.h
+++ b/src/include/utils/builtins.h
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2000, PostgreSQL, Inc
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: builtins.h,v 1.125 2000/07/29 03:26:51 tgl Exp $
+ * $Id: builtins.h,v 1.126 2000/07/29 18:46:05 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -17,7 +17,6 @@
 #include "nodes/relation.h"		/* for amcostestimate parameters */
 #include "storage/itemptr.h"
 #include "utils/inet.h"
-#include "utils/geo_decls.h"
 #include "utils/numeric.h"
 #include "utils/lztext.h"
 
@@ -174,17 +173,6 @@ extern Datum btcharcmp(PG_FUNCTION_ARGS);
 extern Datum btnamecmp(PG_FUNCTION_ARGS);
 extern Datum bttextcmp(PG_FUNCTION_ARGS);
 
-/* support routines for the rtree access method, by opclass */
-extern BOX *rt_box_union(BOX *a, BOX *b);
-extern BOX *rt_box_inter(BOX *a, BOX *b);
-extern void rt_box_size(BOX *a, float *size);
-extern void rt_bigbox_size(BOX *a, float *size);
-extern Datum rt_poly_size(PG_FUNCTION_ARGS);
-extern POLYGON *rt_poly_union(POLYGON *a, POLYGON *b);
-extern POLYGON *rt_poly_inter(POLYGON *a, POLYGON *b);
-
-/* arrayfuncs.c */
-
 /* filename.c */
 extern char *filename_in(char *file);
 extern char *filename_out(char *s);
@@ -393,7 +381,6 @@ extern Datum currtid_byreloid(PG_FUNCTION_ARGS);
 extern Datum currtid_byrelname(PG_FUNCTION_ARGS);
 
 /* varchar.c */
-
 extern Datum bpcharin(PG_FUNCTION_ARGS);
 extern Datum bpcharout(PG_FUNCTION_ARGS);
 extern Datum bpchar(PG_FUNCTION_ARGS);
diff --git a/src/include/utils/geo_decls.h b/src/include/utils/geo_decls.h
index a204d617579029bd7da761f4daa11cd1db232768..f23f3b64968cb5a58cba3e5d3e1bedcda1c10466 100644
--- a/src/include/utils/geo_decls.h
+++ b/src/include/utils/geo_decls.h
@@ -6,7 +6,7 @@
  * Portions Copyright (c) 1996-2000, PostgreSQL, Inc
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: geo_decls.h,v 1.29 2000/06/13 07:35:30 tgl Exp $
+ * $Id: geo_decls.h,v 1.30 2000/07/29 18:46:05 tgl Exp $
  *
  * NOTE
  *	  These routines do *not* use the float types from adt/.
@@ -152,10 +152,12 @@ typedef struct
 #define PG_GETARG_LSEG_P(n) DatumGetLsegP(PG_GETARG_DATUM(n))
 #define PG_RETURN_LSEG_P(x) return LsegPGetDatum(x)
 
-#define DatumGetPathP(X)    ((PATH *) PG_DETOAST_DATUM(X))
-#define PathPGetDatum(X)    PointerGetDatum(X)
-#define PG_GETARG_PATH_P(n) DatumGetPathP(PG_GETARG_DATUM(n))
-#define PG_RETURN_PATH_P(x) return PathPGetDatum(x)
+#define DatumGetPathP(X)         ((PATH *) PG_DETOAST_DATUM(X))
+#define DatumGetPathPCopy(X)     ((PATH *) PG_DETOAST_DATUM_COPY(X))
+#define PathPGetDatum(X)         PointerGetDatum(X)
+#define PG_GETARG_PATH_P(n)      DatumGetPathP(PG_GETARG_DATUM(n))
+#define PG_GETARG_PATH_P_COPY(n) DatumGetPathPCopy(PG_GETARG_DATUM(n))
+#define PG_RETURN_PATH_P(x)      return PathPGetDatum(x)
 
 #define DatumGetLineP(X)    ((LINE *) DatumGetPointer(X))
 #define LinePGetDatum(X)    PointerGetDatum(X)
@@ -167,10 +169,12 @@ typedef struct
 #define PG_GETARG_BOX_P(n) DatumGetBoxP(PG_GETARG_DATUM(n))
 #define PG_RETURN_BOX_P(x) return BoxPGetDatum(x)
 
-#define DatumGetPolygonP(X)    ((POLYGON *) PG_DETOAST_DATUM(X))
-#define PolygonPGetDatum(X)    PointerGetDatum(X)
-#define PG_GETARG_POLYGON_P(n) DatumGetPolygonP(PG_GETARG_DATUM(n))
-#define PG_RETURN_POLYGON_P(x) return PolygonPGetDatum(x)
+#define DatumGetPolygonP(X)         ((POLYGON *) PG_DETOAST_DATUM(X))
+#define DatumGetPolygonPCopy(X)     ((POLYGON *) PG_DETOAST_DATUM_COPY(X))
+#define PolygonPGetDatum(X)         PointerGetDatum(X)
+#define PG_GETARG_POLYGON_P(n)      DatumGetPolygonP(PG_GETARG_DATUM(n))
+#define PG_GETARG_POLYGON_P_COPY(n) DatumGetPolygonPCopy(PG_GETARG_DATUM(n))
+#define PG_RETURN_POLYGON_P(x)      return PolygonPGetDatum(x)
 
 #define DatumGetCircleP(X)    ((CIRCLE *) DatumGetPointer(X))
 #define CirclePGetDatum(X)    PointerGetDatum(X)
@@ -228,7 +232,7 @@ extern Point *lseg_center(LSEG *lseg);
 extern Point *lseg_interpt(LSEG *l1, LSEG *l2);
 extern double *dist_pl(Point *pt, LINE *line);
 extern double *dist_ps(Point *pt, LSEG *lseg);
-extern double *dist_ppath(Point *pt, PATH *path);
+extern Datum dist_ppath(PG_FUNCTION_ARGS);
 extern double *dist_pb(Point *pt, BOX *box);
 extern double *dist_sl(LSEG *lseg, LINE *line);
 extern double *dist_sb(LSEG *lseg, BOX *box);
@@ -244,7 +248,7 @@ extern Point *close_lb(LINE *line, BOX *box);
 extern bool on_pl(Point *pt, LINE *line);
 extern bool on_ps(Point *pt, LSEG *lseg);
 extern bool on_pb(Point *pt, BOX *box);
-extern bool on_ppath(Point *pt, PATH *path);
+extern Datum on_ppath(PG_FUNCTION_ARGS);
 extern bool on_sl(LSEG *lseg, LINE *line);
 extern bool on_sb(LSEG *lseg, BOX *box);
 extern bool inter_sl(LSEG *lseg, LINE *line);
@@ -294,72 +298,62 @@ extern double *box_distance(BOX *box1, BOX *box2);
 extern Point *box_center(BOX *box);
 extern BOX *box_intersect(BOX *box1, BOX *box2);
 extern LSEG *box_diagonal(BOX *box);
-
-/* private routines */
-
-extern double box_dt(BOX *box1, BOX *box2);
-
 extern BOX *box(Point *p1, Point *p2);
 extern BOX *box_add(BOX *box, Point *p);
 extern BOX *box_sub(BOX *box, Point *p);
 extern BOX *box_mul(BOX *box, Point *p);
 extern BOX *box_div(BOX *box, Point *p);
 
+/* private routines */
+extern double box_dt(BOX *box1, BOX *box2);
+
 /* public path routines */
-extern PATH *path_in(char *str);
-extern char *path_out(PATH *path);
-extern bool path_n_lt(PATH *p1, PATH *p2);
-extern bool path_n_gt(PATH *p1, PATH *p2);
-extern bool path_n_eq(PATH *p1, PATH *p2);
-extern bool path_n_le(PATH *p1, PATH *p2);
-extern bool path_n_ge(PATH *p1, PATH *p2);
-extern bool path_inter(PATH *p1, PATH *p2);
-extern double *path_distance(PATH *p1, PATH *p2);
-extern double *path_length(PATH *path);
-
-extern bool path_isclosed(PATH *path);
-extern bool path_isopen(PATH *path);
-extern int4 path_npoints(PATH *path);
-
-extern PATH *path_close(PATH *path);
-extern PATH *path_open(PATH *path);
-extern PATH *path_add(PATH *p1, PATH *p2);
-extern PATH *path_add_pt(PATH *path, Point *point);
-extern PATH *path_sub_pt(PATH *path, Point *point);
-extern PATH *path_mul_pt(PATH *path, Point *point);
-extern PATH *path_div_pt(PATH *path, Point *point);
-
-extern Point *path_center(PATH *path);
-extern POLYGON *path_poly(PATH *path);
-
-extern PATH *upgradepath(PATH *path);
-extern bool isoldpath(PATH *path);
+extern Datum path_in(PG_FUNCTION_ARGS);
+extern Datum path_out(PG_FUNCTION_ARGS);
+extern Datum path_n_lt(PG_FUNCTION_ARGS);
+extern Datum path_n_gt(PG_FUNCTION_ARGS);
+extern Datum path_n_eq(PG_FUNCTION_ARGS);
+extern Datum path_n_le(PG_FUNCTION_ARGS);
+extern Datum path_n_ge(PG_FUNCTION_ARGS);
+extern Datum path_inter(PG_FUNCTION_ARGS);
+extern Datum path_distance(PG_FUNCTION_ARGS);
+extern Datum path_length(PG_FUNCTION_ARGS);
+
+extern Datum path_isclosed(PG_FUNCTION_ARGS);
+extern Datum path_isopen(PG_FUNCTION_ARGS);
+extern Datum path_npoints(PG_FUNCTION_ARGS);
+
+extern Datum path_close(PG_FUNCTION_ARGS);
+extern Datum path_open(PG_FUNCTION_ARGS);
+extern Datum path_add(PG_FUNCTION_ARGS);
+extern Datum path_add_pt(PG_FUNCTION_ARGS);
+extern Datum path_sub_pt(PG_FUNCTION_ARGS);
+extern Datum path_mul_pt(PG_FUNCTION_ARGS);
+extern Datum path_div_pt(PG_FUNCTION_ARGS);
+
+extern Datum path_center(PG_FUNCTION_ARGS);
+extern Datum path_poly(PG_FUNCTION_ARGS);
 
 /* public polygon routines */
-extern POLYGON *poly_in(char *s);
-extern char *poly_out(POLYGON *poly);
-extern bool poly_left(POLYGON *polya, POLYGON *polyb);
-extern bool poly_overleft(POLYGON *polya, POLYGON *polyb);
-extern bool poly_right(POLYGON *polya, POLYGON *polyb);
-extern bool poly_overright(POLYGON *polya, POLYGON *polyb);
-extern bool poly_same(POLYGON *polya, POLYGON *polyb);
-extern bool poly_overlap(POLYGON *polya, POLYGON *polyb);
-extern bool poly_contain(POLYGON *polya, POLYGON *polyb);
-extern bool poly_contained(POLYGON *polya, POLYGON *polyb);
-extern bool poly_contain_pt(POLYGON *poly, Point *p);
-extern bool pt_contained_poly(Point *p, POLYGON *poly);
-
-extern double *poly_distance(POLYGON *polya, POLYGON *polyb);
-extern int4 poly_npoints(POLYGON *poly);
-extern Point *poly_center(POLYGON *poly);
-extern BOX *poly_box(POLYGON *poly);
-extern PATH *poly_path(POLYGON *poly);
-extern POLYGON *box_poly(BOX *box);
-
-extern POLYGON *upgradepoly(POLYGON *poly);
-extern POLYGON *revertpoly(POLYGON *poly);
-
-/* private polygon routines */
+extern Datum poly_in(PG_FUNCTION_ARGS);
+extern Datum poly_out(PG_FUNCTION_ARGS);
+extern Datum poly_left(PG_FUNCTION_ARGS);
+extern Datum poly_overleft(PG_FUNCTION_ARGS);
+extern Datum poly_right(PG_FUNCTION_ARGS);
+extern Datum poly_overright(PG_FUNCTION_ARGS);
+extern Datum poly_same(PG_FUNCTION_ARGS);
+extern Datum poly_overlap(PG_FUNCTION_ARGS);
+extern Datum poly_contain(PG_FUNCTION_ARGS);
+extern Datum poly_contained(PG_FUNCTION_ARGS);
+extern Datum poly_contain_pt(PG_FUNCTION_ARGS);
+extern Datum pt_contained_poly(PG_FUNCTION_ARGS);
+
+extern Datum poly_distance(PG_FUNCTION_ARGS);
+extern Datum poly_npoints(PG_FUNCTION_ARGS);
+extern Datum poly_center(PG_FUNCTION_ARGS);
+extern Datum poly_box(PG_FUNCTION_ARGS);
+extern Datum poly_path(PG_FUNCTION_ARGS);
+extern Datum box_poly(PG_FUNCTION_ARGS);
 
 /* public circle routines */
 extern CIRCLE *circle_in(char *str);
@@ -391,18 +385,27 @@ extern double *circle_diameter(CIRCLE *circle);
 extern double *circle_radius(CIRCLE *circle);
 extern double *circle_distance(CIRCLE *circle1, CIRCLE *circle2);
 extern double *dist_pc(Point *point, CIRCLE *circle);
-extern double *dist_cpoly(CIRCLE *circle, POLYGON *poly);
+extern Datum dist_cpoly(PG_FUNCTION_ARGS);
 extern Point *circle_center(CIRCLE *circle);
 extern CIRCLE *circle(Point *center, float8 *radius);
 extern CIRCLE *box_circle(BOX *box);
 extern BOX *circle_box(CIRCLE *circle);
-extern CIRCLE *poly_circle(POLYGON *poly);
+extern Datum poly_circle(PG_FUNCTION_ARGS);
 extern Datum circle_poly(PG_FUNCTION_ARGS);
 
 /* private routines */
 extern double *circle_area(CIRCLE *circle);
 extern double circle_dt(CIRCLE *circle1, CIRCLE *circle2);
 
+/* support routines for the rtree access method (rtproc.c) */
+extern BOX *rt_box_union(BOX *a, BOX *b);
+extern BOX *rt_box_inter(BOX *a, BOX *b);
+extern void rt_box_size(BOX *a, float *size);
+extern void rt_bigbox_size(BOX *a, float *size);
+extern Datum rt_poly_size(PG_FUNCTION_ARGS);
+extern Datum rt_poly_union(PG_FUNCTION_ARGS);
+extern Datum rt_poly_inter(PG_FUNCTION_ARGS);
+
 /* geo_selfuncs.c */
 extern Datum areasel(PG_FUNCTION_ARGS);
 extern Datum areajoinsel(PG_FUNCTION_ARGS);
diff --git a/src/test/regress/regress.c b/src/test/regress/regress.c
index ca2f0a69caa24da47a415defafdf1fe379d426f8..964e83466701cee7b569bd7fa9cbb2d56ac6db79 100644
--- a/src/test/regress/regress.c
+++ b/src/test/regress/regress.c
@@ -1,5 +1,5 @@
 /*
- * $Header: /cvsroot/pgsql/src/test/regress/regress.c,v 1.41 2000/07/05 23:12:09 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/test/regress/regress.c,v 1.42 2000/07/29 18:46:12 tgl Exp $
  */
 
 #include <float.h>				/* faked on sunos */
@@ -120,7 +120,8 @@ POLYGON    *poly;
 
 	sprintf(buf, "%c", RDELIM);
 	strcat(output, buf);
-	return path_in(output);
+	return DatumGetPathP(DirectFunctionCall1(path_in,
+											 CStringGetDatum(output)));
 }
 
 /* return the point where two paths intersect.	Assumes that they do. */