diff --git a/src/backend/access/hash/hashfunc.c b/src/backend/access/hash/hashfunc.c
index 362738e6764990bd101f3ed306768ba79865b3e2..d431cbafa237099216579f801824b8ee569da2b7 100644
--- a/src/backend/access/hash/hashfunc.c
+++ b/src/backend/access/hash/hashfunc.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/access/hash/hashfunc.c,v 1.27 2000/06/19 03:54:17 tgl Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/access/hash/hashfunc.c,v 1.28 2000/12/08 23:57:02 tgl Exp $
  *
  * NOTES
  *	  These functions are stored in pg_amproc.	For each operator class
@@ -106,8 +106,14 @@ Datum
 hashvarlena(PG_FUNCTION_ARGS)
 {
 	struct varlena *key = PG_GETARG_VARLENA_P(0);
+	Datum		result;
 
-	return hash_any(VARDATA(key), VARSIZE(key) - VARHDRSZ);
+	result = hash_any(VARDATA(key), VARSIZE(key) - VARHDRSZ);
+
+	/* Avoid leaking memory for toasted inputs */
+	PG_FREE_IF_COPY(key, 0);
+
+	return result;
 }
 
 
diff --git a/src/backend/access/rtree/rtproc.c b/src/backend/access/rtree/rtproc.c
index dfe5805a6b0471b1df1b42bf0adabe5c67ff4702..6ee95fbc44543fe29193efacd113a254dee5d2e6 100644
--- a/src/backend/access/rtree/rtproc.c
+++ b/src/backend/access/rtree/rtproc.c
@@ -15,7 +15,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/access/rtree/Attic/rtproc.c,v 1.29 2000/07/30 20:43:40 tgl Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/access/rtree/Attic/rtproc.c,v 1.30 2000/12/08 23:57:01 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -183,5 +183,8 @@ rt_poly_size(PG_FUNCTION_ARGS)
 		*size = (float) (xdim * ydim);
 	}
 
+	/* Avoid leaking memory when handed toasted input. */
+	PG_FREE_IF_COPY(a, 0);
+
 	PG_RETURN_VOID();
 }
diff --git a/src/backend/utils/adt/geo_ops.c b/src/backend/utils/adt/geo_ops.c
index 3a5591ba5d226343aa75ec8ee68a0ad5f2cf30f7..d120442cc5a10e138e3b798e06e6a42ac1dce013 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.55 2000/12/03 20:45:35 tgl Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/utils/adt/geo_ops.c,v 1.56 2000/12/08 23:57:03 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -3097,8 +3097,15 @@ poly_left(PG_FUNCTION_ARGS)
 {
 	POLYGON	   *polya = PG_GETARG_POLYGON_P(0);
 	POLYGON	   *polyb = PG_GETARG_POLYGON_P(1);
+	bool		result;
 
-	PG_RETURN_BOOL(polya->boundbox.high.x < polyb->boundbox.low.x);
+	result = polya->boundbox.high.x < polyb->boundbox.low.x;
+
+	/* Avoid leaking memory for toasted inputs ... needed for rtree indexes */
+	PG_FREE_IF_COPY(polya, 0);
+	PG_FREE_IF_COPY(polyb, 1);
+
+	PG_RETURN_BOOL(result);
 }
 
 /*-------------------------------------------------------
@@ -3111,8 +3118,15 @@ poly_overleft(PG_FUNCTION_ARGS)
 {
 	POLYGON	   *polya = PG_GETARG_POLYGON_P(0);
 	POLYGON	   *polyb = PG_GETARG_POLYGON_P(1);
+	bool		result;
+
+	result = polya->boundbox.low.x <= polyb->boundbox.high.x;
 
-	PG_RETURN_BOOL(polya->boundbox.low.x <= polyb->boundbox.high.x);
+	/* Avoid leaking memory for toasted inputs ... needed for rtree indexes */
+	PG_FREE_IF_COPY(polya, 0);
+	PG_FREE_IF_COPY(polyb, 1);
+
+	PG_RETURN_BOOL(result);
 }
 
 /*-------------------------------------------------------
@@ -3125,8 +3139,15 @@ poly_right(PG_FUNCTION_ARGS)
 {
 	POLYGON	   *polya = PG_GETARG_POLYGON_P(0);
 	POLYGON	   *polyb = PG_GETARG_POLYGON_P(1);
+	bool		result;
+
+	result = polya->boundbox.low.x > polyb->boundbox.high.x;
+
+	/* Avoid leaking memory for toasted inputs ... needed for rtree indexes */
+	PG_FREE_IF_COPY(polya, 0);
+	PG_FREE_IF_COPY(polyb, 1);
 
-	PG_RETURN_BOOL(polya->boundbox.low.x > polyb->boundbox.high.x);
+	PG_RETURN_BOOL(result);
 }
 
 /*-------------------------------------------------------
@@ -3139,8 +3160,15 @@ poly_overright(PG_FUNCTION_ARGS)
 {
 	POLYGON	   *polya = PG_GETARG_POLYGON_P(0);
 	POLYGON	   *polyb = PG_GETARG_POLYGON_P(1);
+	bool		result;
 
-	PG_RETURN_BOOL(polya->boundbox.high.x > polyb->boundbox.low.x);
+	result = polya->boundbox.high.x > polyb->boundbox.low.x;
+
+	/* Avoid leaking memory for toasted inputs ... needed for rtree indexes */
+	PG_FREE_IF_COPY(polya, 0);
+	PG_FREE_IF_COPY(polyb, 1);
+
+	PG_RETURN_BOOL(result);
 }
 
 /*-------------------------------------------------------
@@ -3155,11 +3183,18 @@ poly_same(PG_FUNCTION_ARGS)
 {
 	POLYGON	   *polya = PG_GETARG_POLYGON_P(0);
 	POLYGON	   *polyb = PG_GETARG_POLYGON_P(1);
+	bool		result;
 
 	if (polya->npts != polyb->npts)
-		PG_RETURN_BOOL(false);
+		result = false;
+	else
+		result = plist_same(polya->npts, polya->p, polyb->p);
+
+	/* Avoid leaking memory for toasted inputs ... needed for rtree indexes */
+	PG_FREE_IF_COPY(polya, 0);
+	PG_FREE_IF_COPY(polyb, 1);
 
-	PG_RETURN_BOOL(plist_same(polya->npts, polya->p, polyb->p));
+	PG_RETURN_BOOL(result);
 }
 
 /*-----------------------------------------------------------------
@@ -3173,8 +3208,15 @@ poly_overlap(PG_FUNCTION_ARGS)
 {
 	POLYGON	   *polya = PG_GETARG_POLYGON_P(0);
 	POLYGON	   *polyb = PG_GETARG_POLYGON_P(1);
+	bool		result;
+
+	result = box_ov(&polya->boundbox, &polyb->boundbox);
 
-	PG_RETURN_BOOL(box_ov(&polya->boundbox, &polyb->boundbox));
+	/* Avoid leaking memory for toasted inputs ... needed for rtree indexes */
+	PG_FREE_IF_COPY(polya, 0);
+	PG_FREE_IF_COPY(polyb, 1);
+
+	PG_RETURN_BOOL(result);
 }
 
 
@@ -3186,6 +3228,7 @@ poly_contain(PG_FUNCTION_ARGS)
 {
 	POLYGON	   *polya = PG_GETARG_POLYGON_P(0);
 	POLYGON	   *polyb = PG_GETARG_POLYGON_P(1);
+	bool		result;
 	int			i;
 
 	/*
@@ -3195,6 +3238,7 @@ poly_contain(PG_FUNCTION_ARGS)
 										 BoxPGetDatum(&polya->boundbox),
 										 BoxPGetDatum(&polyb->boundbox))))
 	{
+		result = true;			/* assume true for now */
 		for (i = 0; i < polyb->npts; i++)
 		{
 			if (point_inside(&(polyb->p[i]), polya->npts, &(polya->p[0])) == 0)
@@ -3202,28 +3246,40 @@ poly_contain(PG_FUNCTION_ARGS)
 #if GEODEBUG
 				printf("poly_contain- point (%f,%f) not in polygon\n", polyb->p[i].x, polyb->p[i].y);
 #endif
-				PG_RETURN_BOOL(false);
+				result = false;
+				break;
 			}
 		}
-		for (i = 0; i < polya->npts; i++)
+		if (result)
 		{
-			if (point_inside(&(polya->p[i]), polyb->npts, &(polyb->p[0])) == 1)
+			for (i = 0; i < polya->npts; i++)
 			{
+				if (point_inside(&(polya->p[i]), polyb->npts, &(polyb->p[0])) == 1)
+				{
 #if GEODEBUG
-				printf("poly_contain- point (%f,%f) in polygon\n", polya->p[i].x, polya->p[i].y);
+					printf("poly_contain- point (%f,%f) in polygon\n", polya->p[i].x, polya->p[i].y);
 #endif
-				PG_RETURN_BOOL(false);
+					result = false;
+					break;
+				}
 			}
 		}
-		PG_RETURN_BOOL(true);
 	}
-
+	else
+	{
 #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);
+		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
-	PG_RETURN_BOOL(false);
+		result = false;
+	}
+
+	/* Avoid leaking memory for toasted inputs ... needed for rtree indexes */
+	PG_FREE_IF_COPY(polya, 0);
+	PG_FREE_IF_COPY(polyb, 1);
+
+	PG_RETURN_BOOL(result);
 }
 
 
diff --git a/src/backend/utils/adt/mac.c b/src/backend/utils/adt/mac.c
index 5e949ea2e6e88980a6fab15302e0e0ff40813f4b..17754588e9798c6486821bad1f953e4c8f0d6efb 100644
--- a/src/backend/utils/adt/mac.c
+++ b/src/backend/utils/adt/mac.c
@@ -1,11 +1,12 @@
 /*
  *	PostgreSQL type definitions for MAC addresses.
  *
- *	$Header: /cvsroot/pgsql/src/backend/utils/adt/mac.c,v 1.18 2000/08/23 06:04:33 thomas Exp $
+ *	$Header: /cvsroot/pgsql/src/backend/utils/adt/mac.c,v 1.19 2000/12/08 23:57:03 tgl Exp $
  */
 
 #include "postgres.h"
 
+#include "access/hash.h"
 #include "utils/builtins.h"
 #include "utils/inet.h"
 
@@ -236,11 +237,21 @@ macaddr_ne(PG_FUNCTION_ARGS)
 	PG_RETURN_BOOL(macaddr_cmp_internal(a1, a2) != 0);
 }
 
+/*
+ * Support function for hash indexes on macaddr.
+ */
+Datum
+hashmacaddr(PG_FUNCTION_ARGS)
+{
+	macaddr	   *key = PG_GETARG_MACADDR_P(0);
+
+	return hash_any((char *) key, sizeof(macaddr));
+}
+
 /*
  *	Truncation function to allow comparing mac manufacturers.
  *	From suggestion by Alex Pilosov <alex@pilosoft.com>
  */
-
 Datum
 macaddr_trunc(PG_FUNCTION_ARGS)
 {
diff --git a/src/backend/utils/adt/varchar.c b/src/backend/utils/adt/varchar.c
index 3c58a25461965158b8fe296ceab558a45e554c68..750d3dd665eda5f65d8fb78585db4bf30ad79bbb 100644
--- a/src/backend/utils/adt/varchar.c
+++ b/src/backend/utils/adt/varchar.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/utils/adt/varchar.c,v 1.71 2000/11/26 11:35:23 ishii Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/utils/adt/varchar.c,v 1.72 2000/12/08 23:57:03 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -663,11 +663,17 @@ hashbpchar(PG_FUNCTION_ARGS)
 	BpChar	   *key = PG_GETARG_BPCHAR_P(0);
 	char	   *keydata;
 	int			keylen;
+	Datum		result;
 
 	keydata = VARDATA(key);
 	keylen = bcTruelen(key);
 
-	return hash_any(keydata, keylen);
+	result = hash_any(keydata, keylen);
+
+	/* Avoid leaking memory for toasted inputs */
+	PG_FREE_IF_COPY(key, 0);
+
+	return result;
 }
 
 
diff --git a/src/include/catalog/pg_amproc.h b/src/include/catalog/pg_amproc.h
index dcca94f7f83afd42ecf82bdd13b202982a23eacc..02b891cda4cffa6cc954a3b18ef2782d3060e4a9 100644
--- a/src/include/catalog/pg_amproc.h
+++ b/src/include/catalog/pg_amproc.h
@@ -10,7 +10,7 @@
  * Portions Copyright (c) 1996-2000, PostgreSQL, Inc
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: pg_amproc.h,v 1.25 2000/08/21 04:48:51 tgl Exp $
+ * $Id: pg_amproc.h,v 1.26 2000/12/08 23:57:02 tgl Exp $
  *
  * NOTES
  *	  the genbki.sh script reads this file and generates .bki
@@ -114,7 +114,7 @@ DATA(insert OID = 0 (405  431  456 1));
 DATA(insert OID = 0 (405  435  457 1));
 DATA(insert OID = 0 (405  652  456 1));
 DATA(insert OID = 0 (405  754  949 1));
-DATA(insert OID = 0 (405  810  456 1));
+DATA(insert OID = 0 (405  810  399 1));
 DATA(insert OID = 0 (405  935  456 1));
 DATA(insert OID = 0 (405 1076 1080 1));
 DATA(insert OID = 0 (405 1077  456 1));
diff --git a/src/include/catalog/pg_proc.h b/src/include/catalog/pg_proc.h
index 0807ade9efa1ff54dfdbf70be556bbd52f2f8921..fca0093025965b49decd0412a4fe940b4d31b2f1 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.177 2000/12/07 18:38:58 tgl Exp $
+ * $Id: pg_proc.h,v 1.178 2000/12/08 23:57:02 tgl Exp $
  *
  * NOTES
  *	  The script catalog/genbki.sh reads this file and generates .bki
@@ -830,6 +830,8 @@ DATA(insert OID = 456 (  hashvarlena	   PGUID 12 f t t t 1 f 23 "0" 100 0 0 100
 DESCR("hash any varlena type");
 DATA(insert OID = 457 (  hashoidvector	   PGUID 12 f t t t 1 f 23 "30" 100 0 0 100  hashoidvector - ));
 DESCR("hash");
+DATA(insert OID = 399 (  hashmacaddr	   PGUID 12 f t t t 1 f 23 "829" 100 0 0 100  hashmacaddr - ));
+DESCR("hash");
 DATA(insert OID = 458 (  text_larger	   PGUID 12 f t t t 2 f 25 "25 25" 100 0 0 100  text_larger - ));
 DESCR("larger of two");
 DATA(insert OID = 459 (  text_smaller	   PGUID 12 f t t t 2 f 25 "25 25" 100 0 0 100  text_smaller - ));
diff --git a/src/include/utils/builtins.h b/src/include/utils/builtins.h
index 7caf379a11564314cfb5e8f08ff2f01ced3918e3..97f03b75a2d485e4faec9e0b023568e1ee046244 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.143 2000/11/25 20:33:54 tgl Exp $
+ * $Id: builtins.h,v 1.144 2000/12/08 23:57:00 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -522,6 +522,7 @@ extern Datum macaddr_ne(PG_FUNCTION_ARGS);
 extern Datum macaddr_trunc(PG_FUNCTION_ARGS);
 extern Datum macaddr_text(PG_FUNCTION_ARGS);
 extern Datum text_macaddr(PG_FUNCTION_ARGS);
+extern Datum hashmacaddr(PG_FUNCTION_ARGS);
 
 /* numeric.c */
 extern Datum numeric_in(PG_FUNCTION_ARGS);