From 8ecac94bb21570ee45245f440171b5ffb4efe68c Mon Sep 17 00:00:00 2001
From: Tom Lane <tgl@sss.pgh.pa.us>
Date: Thu, 6 Jul 2000 05:48:31 +0000
Subject: [PATCH] Functions on 'text' type updated to new fmgr style.  'text'
 is now TOAST-able.

---
 src/backend/utils/adt/cash.c          |  33 ++--
 src/backend/utils/adt/float.c         |  62 +++---
 src/backend/utils/adt/like.c          |  66 ++++---
 src/backend/utils/adt/lztext.c        |  16 +-
 src/backend/utils/adt/mac.c           |  43 +++--
 src/backend/utils/adt/network.c       | 121 ++++++------
 src/backend/utils/adt/oracle_compat.c | 251 +++++++++++-------------
 src/backend/utils/adt/regexp.c        | 173 +++++++++--------
 src/backend/utils/adt/ruleutils.c     |  20 +-
 src/backend/utils/adt/selfuncs.c      |   5 +-
 src/backend/utils/adt/varlena.c       | 265 +++++++++++++-------------
 src/backend/utils/adt/version.c       |  21 +-
 src/backend/utils/fmgr/fmgr.c         |  32 +++-
 src/include/catalog/catversion.h      |   4 +-
 src/include/catalog/pg_proc.h         | 118 ++++++------
 src/include/catalog/pg_type.h         |   4 +-
 src/include/fmgr.h                    |  60 ++++--
 src/include/utils/builtins.h          | 124 ++++++------
 src/include/utils/cash.h              |   2 +-
 src/include/utils/inet.h              |  17 +-
 20 files changed, 750 insertions(+), 687 deletions(-)

diff --git a/src/backend/utils/adt/cash.c b/src/backend/utils/adt/cash.c
index 09237e52755..bfca7ff5135 100644
--- a/src/backend/utils/adt/cash.c
+++ b/src/backend/utils/adt/cash.c
@@ -9,7 +9,7 @@
  * workings can be found in the book "Software Solutions in C" by
  * Dale Schumacher, Academic Press, ISBN: 0-12-632360-7.
  *
- * $Header: /cvsroot/pgsql/src/backend/utils/adt/cash.c,v 1.41 2000/07/03 23:09:50 wieck Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/adt/cash.c,v 1.42 2000/07/06 05:48:11 tgl Exp $
  */
 
 #include <limits.h>
@@ -41,7 +41,7 @@ static struct lconv *lconvert = NULL;
  * Cash is a pass-by-ref SQL type, so we must pass and return pointers.
  * These macros and support routine hide the pass-by-refness.
  */
-#define PG_GETARG_CASH(n)  (* ((Cash *) DatumGetPointer(fcinfo->arg[n])))
+#define PG_GETARG_CASH(n)  (* ((Cash *) PG_GETARG_POINTER(n)))
 #define PG_RETURN_CASH(x)  return CashGetDatum(x)
 
 static Datum
@@ -677,10 +677,11 @@ cashsmaller(Cash *c1, Cash *c2)
  * This converts a int4 as well but to a representation using words
  * Obviously way North American centric - sorry
  */
-text *
-cash_words_out(Cash *value)
+Datum
+cash_words_out(PG_FUNCTION_ARGS)
 {
-	static char buf[128];
+	Cash		value = PG_GETARG_CASH(0);
+	char		buf[128];
 	char	   *p = buf;
 	Cash		m0;
 	Cash		m1;
@@ -689,19 +690,19 @@ cash_words_out(Cash *value)
 	text	   *result;
 
 	/* work with positive numbers */
-	if (*value < 0)
+	if (value < 0)
 	{
-		*value *= -1;
+		value = -value;
 		strcpy(buf, "minus ");
 		p += 6;
 	}
 	else
-		*buf = 0;
+		buf[0] = '\0';
 
-	m0 = *value % 100;			/* cents */
-	m1 = (*value / 100) % 1000; /* hundreds */
-	m2 = (*value / 100000) % 1000;		/* thousands */
-	m3 = *value / 100000000 % 1000;		/* millions */
+	m0 = value % 100;			/* cents */
+	m1 = (value / 100) % 1000; /* hundreds */
+	m2 = (value / 100000) % 1000;		/* thousands */
+	m3 = value / 100000000 % 1000;		/* millions */
 
 	if (m3)
 	{
@@ -721,20 +722,20 @@ cash_words_out(Cash *value)
 	if (!*p)
 		strcat(buf, "zero");
 
-	strcat(buf, (int) (*value / 100) == 1 ? " dollar and " : " dollars and ");
+	strcat(buf, (int) (value / 100) == 1 ? " dollar and " : " dollars and ");
 	strcat(buf, num_word(m0));
 	strcat(buf, m0 == 1 ? " cent" : " cents");
 
 	/* capitalize output */
-	*buf = toupper(*buf);
+	buf[0] = toupper(buf[0]);
 
 	/* make a text type for output */
 	result = (text *) palloc(strlen(buf) + VARHDRSZ);
 	VARATT_SIZEP(result) = strlen(buf) + VARHDRSZ;
 	memcpy(VARDATA(result), buf, strlen(buf));
 
-	return result;
-}	/* cash_words_out() */
+	PG_RETURN_TEXT_P(result);
+}
 
 
 /*************************************************************************
diff --git a/src/backend/utils/adt/float.c b/src/backend/utils/adt/float.c
index f618a10eb8e..0d53401c960 100644
--- a/src/backend/utils/adt/float.c
+++ b/src/backend/utils/adt/float.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/utils/adt/float.c,v 1.62 2000/07/03 23:09:50 wieck Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/utils/adt/float.c,v 1.63 2000/07/06 05:48:11 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -941,91 +941,99 @@ i2tof(PG_FUNCTION_ARGS)
 /*
  *		float8_text		- converts a float8 number to a text string
  */
-text *
-float8_text(float64 num)
+Datum
+float8_text(PG_FUNCTION_ARGS)
 {
+	float8		num = PG_GETARG_FLOAT8(0);
 	text	   *result;
 	int			len;
 	char	   *str;
 
-	str = float8out(num);
-	len = (strlen(str) + VARHDRSZ);
+	str = float8out(&num);		/* XXX temporary hack */
+	len = strlen(str) + VARHDRSZ;
 
-	result = palloc(len);
+	result = (text *) palloc(len);
 
 	VARATT_SIZEP(result) = len;
-	memmove(VARDATA(result), str, (len - VARHDRSZ));
+	memcpy(VARDATA(result), str, (len - VARHDRSZ));
 
 	pfree(str);
-	return result;
-}	/* float8_text() */
+
+	PG_RETURN_TEXT_P(result);
+}
 
 
 /*
  *		text_float8		- converts a text string to a float8 number
  */
-float64
-text_float8(text *string)
+Datum
+text_float8(PG_FUNCTION_ARGS)
 {
+	text	   *string = PG_GETARG_TEXT_P(0);
 	float64		result;
 	int			len;
 	char	   *str;
 
 	len = (VARSIZE(string) - VARHDRSZ);
 	str = palloc(len + 1);
-	memmove(str, VARDATA(string), len);
+	memcpy(str, VARDATA(string), len);
 	*(str + len) = '\0';
 
 	result = float8in(str);
+
 	pfree(str);
 
-	return result;
-}	/* text_float8() */
+	return PointerGetDatum(result);
+}
 
 
 /*
  *		float4_text		- converts a float4 number to a text string
  */
-text *
-float4_text(float32 num)
+Datum
+float4_text(PG_FUNCTION_ARGS)
 {
+	float4		num = PG_GETARG_FLOAT4(0);
 	text	   *result;
 	int			len;
 	char	   *str;
 
-	str = float4out(num);
-	len = (strlen(str) + VARHDRSZ);
+	str = float4out(&num);		/* XXX temporary hack */
+	len = strlen(str) + VARHDRSZ;
 
-	result = palloc(len);
+	result = (text *) palloc(len);
 
 	VARATT_SIZEP(result) = len;
-	memmove(VARDATA(result), str, (len - VARHDRSZ));
+	memcpy(VARDATA(result), str, (len - VARHDRSZ));
 
 	pfree(str);
-	return result;
-}	/* float4_text() */
+
+	PG_RETURN_TEXT_P(result);
+}
 
 
 /*
  *		text_float4		- converts a text string to a float4 number
  */
-float32
-text_float4(text *string)
+Datum
+text_float4(PG_FUNCTION_ARGS)
 {
+	text	   *string = PG_GETARG_TEXT_P(0);
 	float32		result;
 	int			len;
 	char	   *str;
 
 	len = (VARSIZE(string) - VARHDRSZ);
 	str = palloc(len + 1);
-	memmove(str, VARDATA(string), len);
+	memcpy(str, VARDATA(string), len);
 	*(str + len) = '\0';
 
 	result = float4in(str);
+
 	pfree(str);
 
-	return result;
-}	/* text_float4() */
+	return PointerGetDatum(result);
+}
 
 
 /*
diff --git a/src/backend/utils/adt/like.c b/src/backend/utils/adt/like.c
index e2cd89e6eea..6fbd95ffe25 100644
--- a/src/backend/utils/adt/like.c
+++ b/src/backend/utils/adt/like.c
@@ -11,15 +11,16 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *	$Header: /cvsroot/pgsql/src/backend/utils/adt/like.c,v 1.35 2000/06/14 18:59:42 momjian Exp $
+ *	$Header: /cvsroot/pgsql/src/backend/utils/adt/like.c,v 1.36 2000/07/06 05:48:11 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
 #include "postgres.h"
+
 #include "mb/pg_wchar.h"
 #include "utils/builtins.h"
 
-static int	like(pg_wchar * text, pg_wchar * p);
+static bool like(pg_wchar * text, pg_wchar * p);
 
 /*
  *	interface routines called by the function manager
@@ -30,20 +31,17 @@ static int	like(pg_wchar * text, pg_wchar * p);
 
    a generic fixed length like routine
 		 s		- the string to match against  (not necessarily null-terminated)
-		 p		   - the pattern
+		 p		   - the pattern (as text*)
 		 charlen   - the length of the string
 */
 static bool
-fixedlen_like(char *s, struct varlena * p, int charlen)
+fixedlen_like(char *s, text *p, int charlen)
 {
 	pg_wchar   *sterm,
 			   *pterm;
-	int			result;
+	bool		result;
 	int			len;
 
-	if (!s || !p)
-		return FALSE;
-
 	/* be sure sterm is null-terminated */
 #ifdef MULTIBYTE
 	sterm = (pg_wchar *) palloc((charlen + 1) * sizeof(pg_wchar));
@@ -54,7 +52,7 @@ fixedlen_like(char *s, struct varlena * p, int charlen)
 #endif
 
 	/*
-	 * p is a text = varlena, not a string so we have to make a string
+	 * p is a text, not a string so we have to make a string
 	 * from the vl_data field of the struct.
 	 */
 
@@ -65,8 +63,8 @@ fixedlen_like(char *s, struct varlena * p, int charlen)
 	(void) pg_mb2wchar_with_len((unsigned char *) VARDATA(p), pterm, len);
 #else
 	pterm = (char *) palloc(len + 1);
-	memmove(pterm, VARDATA(p), len);
-	*(pterm + len) = (char) NULL;
+	memcpy(pterm, VARDATA(p), len);
+	*(pterm + len) = '\0';
 #endif
 
 	/* do the regexp matching */
@@ -75,35 +73,43 @@ fixedlen_like(char *s, struct varlena * p, int charlen)
 	pfree(sterm);
 	pfree(pterm);
 
-	return (bool) result;
+	return result;
 }
 
-bool
-namelike(NameData *n, struct varlena * p)
+Datum
+namelike(PG_FUNCTION_ARGS)
 {
-	if (!n)
-		return FALSE;
-	return fixedlen_like(NameStr(*n), p, NAMEDATALEN);
+	Name		n = PG_GETARG_NAME(0);
+	text	   *p = PG_GETARG_TEXT_P(1);
+
+	PG_RETURN_BOOL(fixedlen_like(NameStr(*n), p, strlen(NameStr(*n))));
 }
 
-bool
-namenlike(NameData *s, struct varlena * p)
+Datum
+namenlike(PG_FUNCTION_ARGS)
 {
-	return !namelike(s, p);
+	Name		n = PG_GETARG_NAME(0);
+	text	   *p = PG_GETARG_TEXT_P(1);
+
+	PG_RETURN_BOOL(! fixedlen_like(NameStr(*n), p, strlen(NameStr(*n))));
 }
 
-bool
-textlike(struct varlena * s, struct varlena * p)
+Datum
+textlike(PG_FUNCTION_ARGS)
 {
-	if (!s)
-		return FALSE;
-	return fixedlen_like(VARDATA(s), p, VARSIZE(s) - VARHDRSZ);
+	text	   *s = PG_GETARG_TEXT_P(0);
+	text	   *p = PG_GETARG_TEXT_P(1);
+
+	PG_RETURN_BOOL(fixedlen_like(VARDATA(s), p, VARSIZE(s) - VARHDRSZ));
 }
 
-bool
-textnlike(struct varlena * s, struct varlena * p)
+Datum
+textnlike(PG_FUNCTION_ARGS)
 {
-	return !textlike(s, p);
+	text	   *s = PG_GETARG_TEXT_P(0);
+	text	   *p = PG_GETARG_TEXT_P(1);
+
+	PG_RETURN_BOOL(! fixedlen_like(VARDATA(s), p, VARSIZE(s) - VARHDRSZ));
 }
 
 
@@ -221,11 +227,11 @@ DoMatch(pg_wchar * text, pg_wchar * p)
 /*
 **	User-level routine.  Returns TRUE or FALSE.
 */
-static int
+static bool
 like(pg_wchar * text, pg_wchar * p)
 {
 	/* Fast path for match-everything pattern */
 	if (p[0] == '%' && p[1] == '\0')
-		return TRUE;
+		return true;
 	return DoMatch(text, p) == LIKE_TRUE;
 }
diff --git a/src/backend/utils/adt/lztext.c b/src/backend/utils/adt/lztext.c
index 694940a8570..e1f80f63dac 100644
--- a/src/backend/utils/adt/lztext.c
+++ b/src/backend/utils/adt/lztext.c
@@ -1,7 +1,7 @@
 /* ----------
  * lztext.c -
  *
- * $Header: /cvsroot/pgsql/src/backend/utils/adt/Attic/lztext.c,v 1.9 2000/07/05 10:09:53 wieck Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/adt/Attic/lztext.c,v 1.10 2000/07/06 05:48:11 tgl Exp $
  *
  *	Text type with internal LZ compressed representation. Uses the
  *	standard PostgreSQL compression method.
@@ -174,19 +174,13 @@ lztextoctetlen(lztext *lz)
  *	Convert text to lztext
  * ----------
  */
-lztext *
-text_lztext(text *txt)
+Datum
+text_lztext(PG_FUNCTION_ARGS)
 {
+	text	   *txt = PG_GETARG_TEXT_P(0);
 	lztext	   *result;
 	int32		rawsize;
 
-	/* ----------
-	 * Handle NULL
-	 * ----------
-	 */
-	if (txt == NULL)
-		return NULL;
-
 	/* ----------
 	 * Copy the entire attribute
 	 * ----------
@@ -196,7 +190,7 @@ text_lztext(text *txt)
 	VARATT_SIZEP(result) = rawsize + VARHDRSZ;
 	memcpy(VARATT_DATA(result), VARATT_DATA(txt), rawsize);
 
-	return result;
+	PG_RETURN_POINTER(result);
 }
 
 
diff --git a/src/backend/utils/adt/mac.c b/src/backend/utils/adt/mac.c
index 9d880a4aa69..5b542504643 100644
--- a/src/backend/utils/adt/mac.c
+++ b/src/backend/utils/adt/mac.c
@@ -1,14 +1,30 @@
 /*
  *	PostgreSQL type definitions for MAC addresses.
  *
- *	$Id: mac.c,v 1.15 2000/07/03 23:09:52 wieck Exp $
+ *	$Header: /cvsroot/pgsql/src/backend/utils/adt/mac.c,v 1.16 2000/07/06 05:48:11 tgl Exp $
  */
 
-
 #include "postgres.h"
+
 #include "utils/builtins.h"
 
-manufacturer manufacturers[] = {
+
+/*
+ * macaddr is a pass-by-reference datatype.
+ */
+#define PG_GETARG_MACADDR_P(n)  ((macaddr *) PG_GETARG_POINTER(n))
+#define PG_RETURN_MACADDR_P(x)  return PointerGetDatum(x)
+
+
+typedef struct manufacturer
+{
+	unsigned char a;
+	unsigned char b;
+	unsigned char c;
+	char	   *name;
+} manufacturer;
+
+static manufacturer manufacturers[] = {
 	{0x00, 0x00, 0x0C, "Cisco"},
 	{0x00, 0x00, 0x0E, "Fujitsu"},
 	{0x00, 0x00, 0x0F, "NeXT"},
@@ -290,19 +306,17 @@ macaddr_cmp(macaddr *a1, macaddr *a2)
 }
 
 /*
- *	The special manufacturer fetching function.  See "mac.h".
+ *	The special manufacturer fetching function.
  */
 
-text *
-macaddr_manuf(macaddr *addr)
+Datum
+macaddr_manuf(PG_FUNCTION_ARGS)
 {
+	macaddr	   *addr = PG_GETARG_MACADDR_P(0);
 	manufacturer *manuf;
 	int			length;
 	text	   *result;
 
-	if (!PointerIsValid(addr))
-		return NULL;
-
 	for (manuf = manufacturers; manuf->name != NULL; manuf++)
 	{
 		if ((manuf->a == addr->a) &&
@@ -312,17 +326,16 @@ macaddr_manuf(macaddr *addr)
 	}
 	if (manuf->name == NULL)
 	{
-		result = palloc(VARHDRSZ + 1);
-		memset(result, 0, VARHDRSZ + 1);
-		VARATT_SIZEP(result) = VARHDRSZ + 1;
+		/* Not known, so return empty string */
+		result = palloc(VARHDRSZ);
+		VARATT_SIZEP(result) = VARHDRSZ;
 	}
 	else
 	{
-		length = strlen(manuf->name) + 1;
+		length = strlen(manuf->name);
 		result = palloc(length + VARHDRSZ);
-		memset(result, 0, length + VARHDRSZ);
 		VARATT_SIZEP(result) = length + VARHDRSZ;
 		memcpy(VARDATA(result), manuf->name, length);
 	}
-	return result;
+	PG_RETURN_TEXT_P(result);
 }
diff --git a/src/backend/utils/adt/network.c b/src/backend/utils/adt/network.c
index a5127ece26f..eb489d9cd71 100644
--- a/src/backend/utils/adt/network.c
+++ b/src/backend/utils/adt/network.c
@@ -3,21 +3,29 @@
  *	is for IP V4 CIDR notation, but prepared for V6: just
  *	add the necessary bits where the comments indicate.
  *
- *	$Id: network.c,v 1.22 2000/07/03 23:09:52 wieck Exp $
+ *	$Header: /cvsroot/pgsql/src/backend/utils/adt/network.c,v 1.23 2000/07/06 05:48:11 tgl Exp $
+ *
  *	Jon Postel RIP 16 Oct 1998
  */
 
-#include <sys/types.h>
-#include <sys/socket.h>
+#include "postgres.h"
 
 #include <errno.h>
-
+#include <sys/types.h>
+#include <sys/socket.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
 
-#include "postgres.h"
 #include "utils/builtins.h"
 
+/*
+ * inet is a pass-by-reference datatype.  It's not toastable, and we
+ * don't try to hide the pass-by-refness, so these macros are simple.
+ */
+#define PG_GETARG_INET_P(n)  ((inet *) PG_GETARG_POINTER(n))
+#define PG_RETURN_INET_P(x)  return PointerGetDatum(x)
+
+
 static int	v4bitncmp(unsigned int a1, unsigned int a2, int bits);
 
 /*
@@ -315,17 +323,15 @@ network_cmp(inet *a1, inet *a2)
 	return 0;
 }
 
-text *
-network_host(inet *ip)
+Datum
+network_host(PG_FUNCTION_ARGS)
 {
+	inet	   *ip = PG_GETARG_INET_P(0);
 	text	   *ret;
 	int			len;
 	char	   *ptr,
 				tmp[sizeof("255.255.255.255/32")];
 
-	if (!PointerIsValid(ip))
-		return NULL;
-
 	if (ip_type(ip))
 		elog(ERROR, "CIDR type has no host part");
 
@@ -339,16 +345,16 @@ network_host(inet *ip)
 		/* Go for an IPV6 address here, before faulting out: */
 		elog(ERROR, "unknown address family (%d)", ip_family(ip));
 
+	/* Suppress /n if present */
 	if ((ptr = strchr(tmp, '/')) != NULL)
-		*ptr = 0;
-	len = VARHDRSZ + strlen(tmp) + 1;
-	ret = palloc(len);
-	if (ret == NULL)
-		elog(ERROR, "unable to allocate memory in network_host()");
-
-	VARATT_SIZEP(ret) = len;
-	strcpy(VARDATA(ret), tmp);
-	return (ret);
+		*ptr = '\0';
+
+	/* Return string as a text datum */
+	len = strlen(tmp);
+	ret = (text *) palloc(len + VARHDRSZ);
+	VARATT_SIZEP(ret) = len + VARHDRSZ;
+	memcpy(VARDATA(ret), tmp, len);
+	PG_RETURN_TEXT_P(ret);
 }
 
 int4
@@ -360,17 +366,15 @@ network_masklen(inet *ip)
 	return ip_bits(ip);
 }
 
-text *
-network_broadcast(inet *ip)
+Datum
+network_broadcast(PG_FUNCTION_ARGS)
 {
+	inet	   *ip = PG_GETARG_INET_P(0);
 	text	   *ret;
 	int			len;
 	char	   *ptr,
 				tmp[sizeof("255.255.255.255/32")];
 
-	if (!PointerIsValid(ip))
-		return NULL;
-
 	if (ip_family(ip) == AF_INET)
 	{
 		/* It's an IP V4 address: */
@@ -383,34 +387,31 @@ network_broadcast(inet *ip)
 
 		if (inet_net_ntop(AF_INET, &addr, 32, tmp, sizeof(tmp)) == NULL)
 			elog(ERROR, "unable to print address (%s)", strerror(errno));
-
 	}
 	else
 		/* Go for an IPV6 address here, before faulting out: */
 		elog(ERROR, "unknown address family (%d)", ip_family(ip));
 
+	/* Suppress /n if present */
 	if ((ptr = strchr(tmp, '/')) != NULL)
-		*ptr = 0;
-	len = VARHDRSZ + strlen(tmp) + 1;
-	ret = palloc(len);
-	if (ret == NULL)
-		elog(ERROR, "unable to allocate memory in network_broadcast()");
-
-	VARATT_SIZEP(ret) = len;
-	strcpy(VARDATA(ret), tmp);
-	return (ret);
+		*ptr = '\0';
+
+	/* Return string as a text datum */
+	len = strlen(tmp);
+	ret = (text *) palloc(len + VARHDRSZ);
+	VARATT_SIZEP(ret) = len + VARHDRSZ;
+	memcpy(VARDATA(ret), tmp, len);
+	PG_RETURN_TEXT_P(ret);
 }
 
-text *
-network_network(inet *ip)
+Datum
+network_network(PG_FUNCTION_ARGS)
 {
+	inet	   *ip = PG_GETARG_INET_P(0);
 	text	   *ret;
 	int			len;
 	char		tmp[sizeof("255.255.255.255/32")];
 
-	if (!PointerIsValid(ip))
-		return NULL;
-
 	if (ip_family(ip) == AF_INET)
 	{
 		/* It's an IP V4 address: */
@@ -418,33 +419,28 @@ network_network(inet *ip)
 
 		if (inet_cidr_ntop(AF_INET, &addr, ip_bits(ip), tmp, sizeof(tmp)) == NULL)
 			elog(ERROR, "unable to print network (%s)", strerror(errno));
-
 	}
 	else
 		/* Go for an IPV6 address here, before faulting out: */
 		elog(ERROR, "unknown address family (%d)", ip_family(ip));
 
-	len = VARHDRSZ + strlen(tmp) + 1;
-	ret = palloc(len);
-	if (ret == NULL)
-		elog(ERROR, "unable to allocate memory in network_network()");
-
-	VARATT_SIZEP(ret) = len;
-	strcpy(VARDATA(ret), tmp);
-	return (ret);
+	/* Return string as a text datum */
+	len = strlen(tmp);
+	ret = (text *) palloc(len + VARHDRSZ);
+	VARATT_SIZEP(ret) = len + VARHDRSZ;
+	memcpy(VARDATA(ret), tmp, len);
+	PG_RETURN_TEXT_P(ret);
 }
 
-text *
-network_netmask(inet *ip)
+Datum
+network_netmask(PG_FUNCTION_ARGS)
 {
+	inet	   *ip = PG_GETARG_INET_P(0);
 	text	   *ret;
 	int			len;
 	char	   *ptr,
 				tmp[sizeof("255.255.255.255/32")];
 
-	if (!PointerIsValid(ip))
-		return NULL;
-
 	if (ip_family(ip) == AF_INET)
 	{
 		/* It's an IP V4 address: */
@@ -453,22 +449,21 @@ network_netmask(inet *ip)
 
 		if (inet_net_ntop(AF_INET, &addr, 32, tmp, sizeof(tmp)) == NULL)
 			elog(ERROR, "unable to print netmask (%s)", strerror(errno));
-
 	}
 	else
 		/* Go for an IPV6 address here, before faulting out: */
 		elog(ERROR, "unknown address family (%d)", ip_family(ip));
 
+	/* Suppress /n if present */
 	if ((ptr = strchr(tmp, '/')) != NULL)
-		*ptr = 0;
-	len = VARHDRSZ + strlen(tmp) + 1;
-	ret = palloc(len);
-	if (ret == NULL)
-		elog(ERROR, "unable to allocate memory in network_netmask()");
-
-	VARATT_SIZEP(ret) = len;
-	strcpy(VARDATA(ret), tmp);
-	return (ret);
+		*ptr = '\0';
+
+	/* Return string as a text datum */
+	len = strlen(tmp);
+	ret = (text *) palloc(len + VARHDRSZ);
+	VARATT_SIZEP(ret) = len + VARHDRSZ;
+	memcpy(VARDATA(ret), tmp, len);
+	PG_RETURN_TEXT_P(ret);
 }
 
 /*
diff --git a/src/backend/utils/adt/oracle_compat.c b/src/backend/utils/adt/oracle_compat.c
index 5f0b1fa776a..db49f7d9e8b 100644
--- a/src/backend/utils/adt/oracle_compat.c
+++ b/src/backend/utils/adt/oracle_compat.c
@@ -1,13 +1,14 @@
 /*
  *	Edmund Mergl <E.Mergl@bawue.de>
  *
- *	$Id: oracle_compat.c,v 1.26 2000/07/03 23:09:52 wieck Exp $
+ *	$Header: /cvsroot/pgsql/src/backend/utils/adt/oracle_compat.c,v 1.27 2000/07/06 05:48:11 tgl Exp $
  *
  */
 
-
 #include <ctype.h>
+
 #include "postgres.h"
+
 #include "utils/builtins.h"
 
 
@@ -17,7 +18,7 @@
  *
  * Syntax:
  *
- *	 text *lower(text *string)
+ *	 text lower(text string)
  *
  * Purpose:
  *
@@ -25,27 +26,24 @@
  *
  ********************************************************************/
 
-text *
-lower(text *string)
+Datum
+lower(PG_FUNCTION_ARGS)
 {
-	text	   *ret;
-	char	   *ptr,
-			   *ptr_ret;
+	text	   *string = PG_GETARG_TEXT_P_COPY(0);
+	char	   *ptr;
 	int			m;
 
-	if ((string == (text *) NULL) || ((m = VARSIZE(string) - VARHDRSZ) <= 0))
-		return string;
-
-	ret = (text *) palloc(VARSIZE(string));
-	VARATT_SIZEP(ret) = VARSIZE(string);
-
+	/* Since we copied the string, we can scribble directly on the value */
 	ptr = VARDATA(string);
-	ptr_ret = VARDATA(ret);
+	m = VARSIZE(string) - VARHDRSZ;
 
-	while (m--)
-		*ptr_ret++ = tolower((unsigned char) *ptr++);
+	while (m-- > 0)
+	{
+		*ptr = tolower((unsigned char) *ptr);
+		ptr++;
+	}
 
-	return ret;
+	PG_RETURN_TEXT_P(string);
 }
 
 
@@ -55,7 +53,7 @@ lower(text *string)
  *
  * Syntax:
  *
- *	 text *upper(text *string)
+ *	 text upper(text string)
  *
  * Purpose:
  *
@@ -63,27 +61,24 @@ lower(text *string)
  *
  ********************************************************************/
 
-text *
-upper(text *string)
+Datum
+upper(PG_FUNCTION_ARGS)
 {
-	text	   *ret;
-	char	   *ptr,
-			   *ptr_ret;
+	text	   *string = PG_GETARG_TEXT_P_COPY(0);
+	char	   *ptr;
 	int			m;
 
-	if ((string == (text *) NULL) || ((m = VARSIZE(string) - VARHDRSZ) <= 0))
-		return string;
-
-	ret = (text *) palloc(VARSIZE(string));
-	VARATT_SIZEP(ret) = VARSIZE(string);
-
+	/* Since we copied the string, we can scribble directly on the value */
 	ptr = VARDATA(string);
-	ptr_ret = VARDATA(ret);
+	m = VARSIZE(string) - VARHDRSZ;
 
-	while (m--)
-		*ptr_ret++ = toupper((unsigned char) *ptr++);
+	while (m-- > 0)
+	{
+		*ptr = toupper((unsigned char) *ptr);
+		ptr++;
+	}
 
-	return ret;
+	PG_RETURN_TEXT_P(string);
 }
 
 
@@ -93,7 +88,7 @@ upper(text *string)
  *
  * Syntax:
  *
- *	 text *initcap(text *string)
+ *	 text initcap(text string)
  *
  * Purpose:
  *
@@ -103,35 +98,34 @@ upper(text *string)
  *
  ********************************************************************/
 
-text *
-initcap(text *string)
+Datum
+initcap(PG_FUNCTION_ARGS)
 {
-	text	   *ret;
-	char	   *ptr,
-			   *ptr_ret;
+	text	   *string = PG_GETARG_TEXT_P_COPY(0);
+	char	   *ptr;
 	int			m;
 
-	if ((string == (text *) NULL) || ((m = VARSIZE(string) - VARHDRSZ) <= 0))
-		return string;
-
-	ret = (text *) palloc(VARSIZE(string));
-	VARATT_SIZEP(ret) = VARSIZE(string);
-
+	/* Since we copied the string, we can scribble directly on the value */
 	ptr = VARDATA(string);
-	ptr_ret = VARDATA(ret);
+	m = VARSIZE(string) - VARHDRSZ;
 
-	*ptr_ret++ = toupper((unsigned char) *ptr++);
-	--m;
+	if (m > 0)
+	{
+		*ptr = toupper((unsigned char) *ptr);
+		ptr++;
+		m--;
+	}
 
-	while (m--)
+	while (m-- > 0)
 	{
-		if (*(ptr_ret - 1) == ' ' || *(ptr_ret - 1) == '	')
-			*ptr_ret++ = toupper((unsigned char) *ptr++);
+		if (isspace(ptr[-1]))
+			*ptr = toupper((unsigned char) *ptr);
 		else
-			*ptr_ret++ = tolower((unsigned char) *ptr++);
+			*ptr = tolower((unsigned char) *ptr);
+		ptr++;
 	}
 
-	return ret;
+	PG_RETURN_TEXT_P(string);
 }
 
 
@@ -141,7 +135,7 @@ initcap(text *string)
  *
  * Syntax:
  *
- *	 text *lpad(text *string1, int4 len, text *string2)
+ *	 text lpad(text string1, int4 len, text string2)
  *
  * Purpose:
  *
@@ -196,7 +190,7 @@ lpad(PG_FUNCTION_ARGS)
  *
  * Syntax:
  *
- *	 text *rpad(text *string1, int4 len, text *string2)
+ *	 text rpad(text string1, int4 len, text string2)
  *
  * Purpose:
  *
@@ -251,7 +245,7 @@ rpad(PG_FUNCTION_ARGS)
  *
  * Syntax:
  *
- *	 text *btrim(text *string, text *set)
+ *	 text btrim(text string, text set)
  *
  * Purpose:
  *
@@ -260,9 +254,11 @@ rpad(PG_FUNCTION_ARGS)
  *
  ********************************************************************/
 
-text *
-btrim(text *string, text *set)
+Datum
+btrim(PG_FUNCTION_ARGS)
 {
+	text	   *string = PG_GETARG_TEXT_P(0);
+	text	   *set = PG_GETARG_TEXT_P(1);
 	text	   *ret;
 	char	   *ptr,
 			   *end,
@@ -270,18 +266,17 @@ btrim(text *string, text *set)
 			   *end2;
 	int			m;
 
-	if ((string == (text *) NULL) ||
-		((m = VARSIZE(string) - VARHDRSZ) <= 0) ||
-		(set == (text *) NULL) ||
-		((VARSIZE(set) - VARHDRSZ) <= 0))
-		return string;
+	if ((m = VARSIZE(string) - VARHDRSZ) <= 0 ||
+		(VARSIZE(set) - VARHDRSZ) <= 0)
+		PG_RETURN_TEXT_P(string);
 
 	ptr = VARDATA(string);
-	ptr2 = VARDATA(set);
+	end = VARDATA(string) + VARSIZE(string) - VARHDRSZ - 1;
 	end2 = VARDATA(set) + VARSIZE(set) - VARHDRSZ - 1;
 
-	while (m--)
+	while (m > 0)
 	{
+		ptr2 = VARDATA(set);
 		while (ptr2 <= end2)
 		{
 			if (*ptr == *ptr2)
@@ -291,16 +286,12 @@ btrim(text *string, text *set)
 		if (ptr2 > end2)
 			break;
 		ptr++;
-		ptr2 = VARDATA(set);
+		m--;
 	}
 
-	++m;
-
-	end = VARDATA(string) + VARSIZE(string) - VARHDRSZ - 1;
-	ptr2 = VARDATA(set);
-
-	while (m--)
+	while (m > 0)
 	{
+		ptr2 = VARDATA(set);
 		while (ptr2 <= end2)
 		{
 			if (*end == *ptr2)
@@ -309,18 +300,16 @@ btrim(text *string, text *set)
 		}
 		if (ptr2 > end2)
 			break;
-		--end;
-		ptr2 = VARDATA(set);
+		end--;
+		m--;
 	}
 
-	++m;
-
 	ret = (text *) palloc(VARHDRSZ + m);
 	VARATT_SIZEP(ret) = VARHDRSZ + m;
 	memcpy(VARDATA(ret), ptr, m);
 
-	return ret;
-}	/* btrim() */
+	PG_RETURN_TEXT_P(ret);
+}
 
 
 /********************************************************************
@@ -329,7 +318,7 @@ btrim(text *string, text *set)
  *
  * Syntax:
  *
- *	 text *ltrim(text *string, text *set)
+ *	 text ltrim(text string, text set)
  *
  * Purpose:
  *
@@ -338,27 +327,27 @@ btrim(text *string, text *set)
  *
  ********************************************************************/
 
-text *
-ltrim(text *string, text *set)
+Datum
+ltrim(PG_FUNCTION_ARGS)
 {
+	text	   *string = PG_GETARG_TEXT_P(0);
+	text	   *set = PG_GETARG_TEXT_P(1);
 	text	   *ret;
 	char	   *ptr,
 			   *ptr2,
 			   *end2;
 	int			m;
 
-	if ((string == (text *) NULL) ||
-		((m = VARSIZE(string) - VARHDRSZ) <= 0) ||
-		(set == (text *) NULL) ||
-		((VARSIZE(set) - VARHDRSZ) <= 0))
-		return string;
+	if ((m = VARSIZE(string) - VARHDRSZ) <= 0 ||
+		(VARSIZE(set) - VARHDRSZ) <= 0)
+		PG_RETURN_TEXT_P(string);
 
 	ptr = VARDATA(string);
-	ptr2 = VARDATA(set);
 	end2 = VARDATA(set) + VARSIZE(set) - VARHDRSZ - 1;
 
-	while (m--)
+	while (m > 0)
 	{
+		ptr2 = VARDATA(set);
 		while (ptr2 <= end2)
 		{
 			if (*ptr == *ptr2)
@@ -368,17 +357,14 @@ ltrim(text *string, text *set)
 		if (ptr2 > end2)
 			break;
 		ptr++;
-		ptr2 = VARDATA(set);
+		m--;
 	}
 
-	++m;
-
 	ret = (text *) palloc(VARHDRSZ + m);
 	VARATT_SIZEP(ret) = VARHDRSZ + m;
-
 	memcpy(VARDATA(ret), ptr, m);
 
-	return ret;
+	PG_RETURN_TEXT_P(ret);
 }
 
 
@@ -388,7 +374,7 @@ ltrim(text *string, text *set)
  *
  * Syntax:
  *
- *	 text *rtrim(text *string, text *set)
+ *	 text rtrim(text string, text set)
  *
  * Purpose:
  *
@@ -397,54 +383,46 @@ ltrim(text *string, text *set)
  *
  ********************************************************************/
 
-text *
-rtrim(text *string, text *set)
+Datum
+rtrim(PG_FUNCTION_ARGS)
 {
+	text	   *string = PG_GETARG_TEXT_P(0);
+	text	   *set = PG_GETARG_TEXT_P(1);
 	text	   *ret;
 	char	   *ptr,
+			   *end,
 			   *ptr2,
-			   *end2,
-			   *ptr_ret;
+			   *end2;
 	int			m;
 
-	if ((string == (text *) NULL) ||
-		((m = VARSIZE(string) - VARHDRSZ) <= 0) ||
-		(set == (text *) NULL) ||
-		((VARSIZE(set) - VARHDRSZ) <= 0))
-		return string;
+	if ((m = VARSIZE(string) - VARHDRSZ) <= 0 ||
+		(VARSIZE(set) - VARHDRSZ) <= 0)
+		PG_RETURN_TEXT_P(string);
 
-	ptr = VARDATA(string) + VARSIZE(string) - VARHDRSZ - 1;
-	ptr2 = VARDATA(set);
+	ptr = VARDATA(string);
+	end = VARDATA(string) + VARSIZE(string) - VARHDRSZ - 1;
 	end2 = VARDATA(set) + VARSIZE(set) - VARHDRSZ - 1;
 
-	while (m--)
+	while (m > 0)
 	{
+		ptr2 = VARDATA(set);
 		while (ptr2 <= end2)
 		{
-			if (*ptr == *ptr2)
+			if (*end == *ptr2)
 				break;
 			++ptr2;
 		}
 		if (ptr2 > end2)
 			break;
-		--ptr;
-		ptr2 = VARDATA(set);
+		end--;
+		m--;
 	}
 
-	++m;
-
 	ret = (text *) palloc(VARHDRSZ + m);
 	VARATT_SIZEP(ret) = VARHDRSZ + m;
-#ifdef NOT_USED
-	memcpy(VARDATA(ret), ptr - VARSIZE(ret) + m, m);
-#endif
-
-	ptr_ret = VARDATA(ret) + m - 1;
-
-	while (m--)
-		*ptr_ret-- = *ptr--;
+	memcpy(VARDATA(ret), ptr, m);
 
-	return ret;
+	PG_RETURN_TEXT_P(ret);
 }
 
 
@@ -454,7 +432,7 @@ rtrim(text *string, text *set)
  *
  * Syntax:
  *
- *	 text *translate(text *string, text *from, text *to)
+ *	 text translate(text string, text from, text to)
  *
  * Purpose:
  *
@@ -465,9 +443,12 @@ rtrim(text *string, text *set)
  *
  ********************************************************************/
 
-text *
-translate(text *string, text *from, text *to)
+Datum
+translate(PG_FUNCTION_ARGS)
 {
+	text	   *string = PG_GETARG_TEXT_P(0);
+	text	   *from = PG_GETARG_TEXT_P(1);
+	text	   *to = PG_GETARG_TEXT_P(2);
 	text	   *result;
 	char	   *from_ptr,
 			   *to_ptr;
@@ -479,13 +460,8 @@ translate(text *string, text *from, text *to)
 				retlen,
 				i;
 
-	if (string == (text *) NULL ||
-		from == (text *) NULL ||
-		to == (text *) NULL)
-		return (text *) NULL;
-
 	if ((m = VARSIZE(string) - VARHDRSZ) <= 0)
-		return string;
+		PG_RETURN_TEXT_P(string);
 
 	fromlen = VARSIZE(from) - VARHDRSZ;
 	from_ptr = VARDATA(from);
@@ -536,21 +512,20 @@ translate(text *string, text *from, text *to)
 	 * won't live long anyway.
 	 */
 
-	return result;
+	PG_RETURN_TEXT_P(result);
 }
 
 
-int4
-ascii(text *string)
+Datum
+ascii(PG_FUNCTION_ARGS)
 {
-	if (!PointerIsValid(string))
-		return 0;
+	text	   *string = PG_GETARG_TEXT_P(0);
 
 	if (VARSIZE(string) <= VARHDRSZ)
-		return 0;
+		PG_RETURN_INT32(0);
 
-	return ((int) *(VARDATA(string)));
-}	/* ascii() */
+	PG_RETURN_INT32((int32) *((unsigned char *) VARDATA(string)));
+}
 
 
 Datum
diff --git a/src/backend/utils/adt/regexp.c b/src/backend/utils/adt/regexp.c
index 6bb7bac705d..dcf158c7a28 100644
--- a/src/backend/utils/adt/regexp.c
+++ b/src/backend/utils/adt/regexp.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/utils/adt/regexp.c,v 1.31 2000/07/05 23:11:35 tgl Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/utils/adt/regexp.c,v 1.32 2000/07/06 05:48:11 tgl Exp $
  *
  *		Alistair Crooks added the code for the regex caching
  *		agc - cached the regular expressions used - there's a good chance
@@ -25,12 +25,10 @@
  *		instead of `oldest' when compiling regular expressions - benign
  *		results mostly, although occasionally it bit you...
  *
- *
  *-------------------------------------------------------------------------
  */
 #include "postgres.h"
 
-
 #include "regex/regex.h"
 #include "utils/builtins.h"
 
@@ -46,7 +44,6 @@
 /* this structure describes a cached regular expression */
 struct cached_re_str
 {
-	struct varlena *cre_text;	/* pattern as a text* */
 	char	   *cre_s;			/* pattern as null-terminated string */
 	int			cre_type;		/* compiled-type: extended,icase etc */
 	regex_t		cre_re;			/* the compiled regular expression */
@@ -59,38 +56,35 @@ static unsigned long lru;		/* system lru tag */
 
 /* attempt to compile `re' as an re, then match it against text */
 /* cflags - flag to regcomp indicates case sensitivity */
-static int
-RE_compile_and_execute(struct varlena * text_re, char *text, int cflags)
+static bool
+RE_compile_and_execute(text *text_re, char *text, int cflags)
 {
+	char	   *re;
 	int			oldest;
-	int			n;
 	int			i;
-	char	   *re;
 	int			regcomp_result;
 
+	/* Convert 'text' pattern to null-terminated string */
 	re = DatumGetCString(DirectFunctionCall1(textout,
 											 PointerGetDatum(text_re)));
+
 	/* find a previously compiled regular expression */
 	for (i = 0; i < rec; i++)
 	{
 		if (rev[i].cre_s)
 		{
-			if (strcmp(rev[i].cre_s, re) == 0)
+			if (strcmp(rev[i].cre_s, re) == 0 &&
+				rev[i].cre_type == cflags)
 			{
-				if (rev[i].cre_type == cflags)
-				{
-					rev[i].cre_lru = ++lru;
-					pfree(re);
-					return (pg95_regexec(&rev[i].cre_re,
-										 text, 0,
-										 (regmatch_t *) NULL, 0) == 0);
-				}
+				rev[i].cre_lru = ++lru;
+				pfree(re);
+				return (pg95_regexec(&rev[i].cre_re,
+									 text, 0,
+									 (regmatch_t *) NULL, 0) == 0);
 			}
 		}
 	}
 
-
-
 	/* we didn't find it - make room in the cache for it */
 	if (rec == MAX_CACHED_RES)
 	{
@@ -120,22 +114,18 @@ RE_compile_and_execute(struct varlena * text_re, char *text, int cflags)
 		 * persist across transactions
 		 */
 		free(rev[oldest].cre_s);
+		rev[oldest].cre_s = (char *) NULL;
 	}
 
 	/* compile the re */
 	regcomp_result = pg95_regcomp(&rev[oldest].cre_re, re, cflags);
 	if (regcomp_result == 0)
 	{
-		n = strlen(re);
-
 		/*
 		 * use malloc/free for the cre_s field because the storage has to
 		 * persist across transactions
 		 */
-		rev[oldest].cre_s = (char *) malloc(n + 1);
-		memmove(rev[oldest].cre_s, re, n);
-		rev[oldest].cre_s[n] = 0;
-		rev[oldest].cre_text = text_re;
+		rev[oldest].cre_s = strdup(re);
 		rev[oldest].cre_lru = ++lru;
 		rev[oldest].cre_type = cflags;
 		pfree(re);
@@ -148,38 +138,29 @@ RE_compile_and_execute(struct varlena * text_re, char *text, int cflags)
 		char		errMsg[1000];
 
 		/* re didn't compile */
-		rev[oldest].cre_s = (char *) NULL;
 		pg95_regerror(regcomp_result, &rev[oldest].cre_re, errMsg,
 					  sizeof(errMsg));
 		elog(ERROR, "regcomp failed with error %s", errMsg);
 	}
 
 	/* not reached */
-	return 0;
+	return false;
 }
 
 
-
-/*
- *	interface routines called by the function manager
- */
-
 /*
    fixedlen_regexeq:
 
    a generic fixed length regexp routine
 		 s		- the string to match against (not necessarily null-terminated)
-		 p		- the pattern
+		 p		- the pattern (as a text*)
 		 charlen   - the length of the string
 */
 static bool
-fixedlen_regexeq(char *s, struct varlena * p, int charlen, int cflags)
+fixedlen_regexeq(char *s, text *p, int charlen, int cflags)
 {
 	char	   *sterm;
-	int			result;
-
-	if (!s || !p)
-		return FALSE;
+	bool		result;
 
 	/* be sure sterm is null-terminated */
 	sterm = (char *) palloc(charlen + 1);
@@ -189,73 +170,113 @@ fixedlen_regexeq(char *s, struct varlena * p, int charlen, int cflags)
 
 	pfree(sterm);
 
-	return (bool) result;
-
+	return result;
 }
 
 
 /*
- *	routines that use the regexp stuff
+ *	interface routines called by the function manager
  */
-bool
-nameregexeq(NameData *n, struct varlena * p)
+
+Datum
+nameregexeq(PG_FUNCTION_ARGS)
 {
-	if (!n)
-		return FALSE;
-	return fixedlen_regexeq(NameStr(*n), p, NAMEDATALEN, REG_EXTENDED);
+	Name		n = PG_GETARG_NAME(0);
+	text	   *p = PG_GETARG_TEXT_P(1);
+
+	PG_RETURN_BOOL(fixedlen_regexeq(NameStr(*n),
+									p,
+									strlen(NameStr(*n)),
+									REG_EXTENDED));
 }
 
-bool
-nameregexne(NameData *s, struct varlena * p)
+Datum
+nameregexne(PG_FUNCTION_ARGS)
 {
-	return !nameregexeq(s, p);
+	Name		n = PG_GETARG_NAME(0);
+	text	   *p = PG_GETARG_TEXT_P(1);
+
+	PG_RETURN_BOOL(! fixedlen_regexeq(NameStr(*n),
+									  p,
+									  strlen(NameStr(*n)),
+									  REG_EXTENDED));
 }
 
-bool
-textregexeq(struct varlena * s, struct varlena * p)
+Datum
+textregexeq(PG_FUNCTION_ARGS)
 {
-	if (!s)
-		return FALSE;
-	return fixedlen_regexeq(VARDATA(s), p, VARSIZE(s) - VARHDRSZ, REG_EXTENDED);
+	text	   *s = PG_GETARG_TEXT_P(0);
+	text	   *p = PG_GETARG_TEXT_P(1);
+
+	PG_RETURN_BOOL(fixedlen_regexeq(VARDATA(s),
+									p,
+									VARSIZE(s) - VARHDRSZ,
+									REG_EXTENDED));
 }
 
-bool
-textregexne(struct varlena * s, struct varlena * p)
+Datum
+textregexne(PG_FUNCTION_ARGS)
 {
-	return !textregexeq(s, p);
+	text	   *s = PG_GETARG_TEXT_P(0);
+	text	   *p = PG_GETARG_TEXT_P(1);
+
+	PG_RETURN_BOOL(! fixedlen_regexeq(VARDATA(s),
+									  p,
+									  VARSIZE(s) - VARHDRSZ,
+									  REG_EXTENDED));
 }
 
 
 /*
-*  routines that use the regexp stuff, but ignore the case.
+ *  routines that use the regexp stuff, but ignore the case.
  *	for this, we use the REG_ICASE flag to pg95_regcomp
  */
-bool
-texticregexeq(struct varlena * s, struct varlena * p)
+
+
+Datum
+texticregexeq(PG_FUNCTION_ARGS)
 {
-	if (!s)
-		return FALSE;
-	return (fixedlen_regexeq(VARDATA(s), p, VARSIZE(s) - VARHDRSZ,
-							 REG_ICASE | REG_EXTENDED));
+	text	   *s = PG_GETARG_TEXT_P(0);
+	text	   *p = PG_GETARG_TEXT_P(1);
+
+	PG_RETURN_BOOL(fixedlen_regexeq(VARDATA(s),
+									p,
+									VARSIZE(s) - VARHDRSZ,
+									REG_ICASE | REG_EXTENDED));
 }
 
-bool
-texticregexne(struct varlena * s, struct varlena * p)
+Datum
+texticregexne(PG_FUNCTION_ARGS)
 {
-	return !texticregexeq(s, p);
+	text	   *s = PG_GETARG_TEXT_P(0);
+	text	   *p = PG_GETARG_TEXT_P(1);
+
+	PG_RETURN_BOOL(! fixedlen_regexeq(VARDATA(s),
+									  p,
+									  VARSIZE(s) - VARHDRSZ,
+									  REG_ICASE | REG_EXTENDED));
 }
 
-bool
-nameicregexeq(NameData *n, struct varlena * p)
+Datum
+nameicregexeq(PG_FUNCTION_ARGS)
 {
-	if (!n)
-		return FALSE;
-	return (fixedlen_regexeq(NameStr(*n), p, NAMEDATALEN,
-							 REG_ICASE | REG_EXTENDED));
+	Name		n = PG_GETARG_NAME(0);
+	text	   *p = PG_GETARG_TEXT_P(1);
+
+	PG_RETURN_BOOL(fixedlen_regexeq(NameStr(*n),
+									p,
+									strlen(NameStr(*n)),
+									REG_ICASE | REG_EXTENDED));
 }
 
-bool
-nameicregexne(NameData *s, struct varlena * p)
+Datum
+nameicregexne(PG_FUNCTION_ARGS)
 {
-	return !nameicregexeq(s, p);
+	Name		n = PG_GETARG_NAME(0);
+	text	   *p = PG_GETARG_TEXT_P(1);
+
+	PG_RETURN_BOOL(! fixedlen_regexeq(NameStr(*n),
+									  p,
+									  strlen(NameStr(*n)),
+									  REG_ICASE | REG_EXTENDED));
 }
diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c
index 5bd339a5cc9..aa54143374d 100644
--- a/src/backend/utils/adt/ruleutils.c
+++ b/src/backend/utils/adt/ruleutils.c
@@ -3,7 +3,7 @@
  *			  out of its tuple
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/utils/adt/ruleutils.c,v 1.55 2000/07/03 23:09:52 wieck Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/utils/adt/ruleutils.c,v 1.56 2000/07/06 05:48:11 tgl Exp $
  *
  *	  This software is copyrighted by Jan Wieck - Hamburg.
  *
@@ -123,9 +123,10 @@ static bool check_if_rte_used_walker(Node *node,
  *				  to recreate the rule
  * ----------
  */
-text *
-pg_get_ruledef(NameData *rname)
+Datum
+pg_get_ruledef(PG_FUNCTION_ARGS)
 {
+	Name		rname = PG_GETARG_NAME(0);
 	text	   *ruledef;
 	Datum		args[1];
 	char		nulls[2];
@@ -180,10 +181,10 @@ pg_get_ruledef(NameData *rname)
 	{
 		if (SPI_finish() != SPI_OK_FINISH)
 			elog(ERROR, "get_ruledef: SPI_finish() failed");
-		ruledef = SPI_palloc(VARHDRSZ + 1);
+		ruledef = palloc(VARHDRSZ + 1);
 		VARATT_SIZEP(ruledef) = VARHDRSZ + 1;
 		VARDATA(ruledef)[0] = '-';
-		return ruledef;
+		PG_RETURN_TEXT_P(ruledef);
 	}
 
 	ruletup = SPI_tuptable->vals[0];
@@ -212,7 +213,7 @@ pg_get_ruledef(NameData *rname)
 	 * Easy - isn't it?
 	 * ----------
 	 */
-	return ruledef;
+	PG_RETURN_TEXT_P(ruledef);
 }
 
 
@@ -221,9 +222,10 @@ pg_get_ruledef(NameData *rname)
  *				  only return the SELECT part of a view
  * ----------
  */
-text *
-pg_get_viewdef(NameData *rname)
+Datum
+pg_get_viewdef(PG_FUNCTION_ARGS)
 {
+	Name		rname = PG_GETARG_NAME(0);
 	text	   *ruledef;
 	Datum		args[2];
 	char		nulls[3];
@@ -311,7 +313,7 @@ pg_get_viewdef(NameData *rname)
 	 * Easy - isn't it?
 	 * ----------
 	 */
-	return ruledef;
+	PG_RETURN_TEXT_P(ruledef);
 }
 
 
diff --git a/src/backend/utils/adt/selfuncs.c b/src/backend/utils/adt/selfuncs.c
index d46c81157da..3d82487f7e7 100644
--- a/src/backend/utils/adt/selfuncs.c
+++ b/src/backend/utils/adt/selfuncs.c
@@ -15,7 +15,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/utils/adt/selfuncs.c,v 1.74 2000/07/05 23:11:35 tgl Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/utils/adt/selfuncs.c,v 1.75 2000/07/06 05:48:11 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -1820,7 +1820,8 @@ string_lessthan(const char *str1, const char *str2, Oid datatype)
 	switch (datatype)
 	{
 		case TEXTOID:
-			result = text_lt((text *) datum1, (text *) datum2);
+			result = DatumGetBool(DirectFunctionCall2(text_lt,
+													  datum1, datum2));
 			break;
 
 		case BPCHAROID:
diff --git a/src/backend/utils/adt/varlena.c b/src/backend/utils/adt/varlena.c
index 8ddabdb4ee4..8247e16812d 100644
--- a/src/backend/utils/adt/varlena.c
+++ b/src/backend/utils/adt/varlena.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/utils/adt/varlena.c,v 1.62 2000/07/05 23:11:35 tgl Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/utils/adt/varlena.c,v 1.63 2000/07/06 05:48:11 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -196,21 +196,16 @@ textout(PG_FUNCTION_ARGS)
  *	  returns the logical length of a text*
  *	   (which is less than the VARSIZE of the text*)
  */
-int32
-textlen(text *t)
+Datum
+textlen(PG_FUNCTION_ARGS)
 {
+	text	   *t = PG_GETARG_TEXT_P(0);
 #ifdef MULTIBYTE
 	unsigned char *s;
 	int			len,
 				l,
 				wl;
 
-#endif
-
-	if (!PointerIsValid(t))
-		return 0;
-
-#ifdef MULTIBYTE
 	len = 0;
 	s = VARDATA(t);
 	l = VARSIZE(t) - VARHDRSZ;
@@ -221,30 +216,35 @@ textlen(text *t)
 		s += wl;
 		len++;
 	}
-	return (len);
+	PG_RETURN_INT32(len);
 #else
-	return VARSIZE(t) - VARHDRSZ;
+	PG_RETURN_INT32(VARSIZE(t) - VARHDRSZ);
 #endif
-
-}	/* textlen() */
+}
 
 /*
  * textoctetlen -
  *	  returns the physical length of a text*
  *	   (which is less than the VARSIZE of the text*)
+ *
+ * XXX is it actually appropriate to return the compressed length
+ * when the value is compressed?  It's not at all clear to me that
+ * this is what SQL92 has in mind ...
  */
-int32
-textoctetlen(text *t)
+Datum
+textoctetlen(PG_FUNCTION_ARGS)
 {
-	if (!PointerIsValid(t))
-		return 0;
+	struct varattrib   *t = (struct varattrib *) PG_GETARG_RAW_VARLENA_P(0);
 
-	return VARSIZE(t) - VARHDRSZ;
-}	/* textoctetlen() */
+	if (!VARATT_IS_EXTERNAL(t))
+	    PG_RETURN_INT32(VARATT_SIZE(t) - VARHDRSZ);
+
+	PG_RETURN_INT32(t->va_content.va_external.va_extsize);
+}
 
 /*
  * textcat -
- *	  takes two text* and returns a text* that is the concatentation of
+ *	  takes two text* and returns a text* that is the concatenation of
  *	  the two.
  *
  * Rewritten by Sapa, sapa@hq.icb.chel.su. 8-Jul-96.
@@ -252,32 +252,27 @@ textoctetlen(text *t)
  * Allocate space for output in all cases.
  * XXX - thomas 1997-07-10
  */
-text *
-textcat(text *t1, text *t2)
+Datum
+textcat(PG_FUNCTION_ARGS)
 {
+	text	   *t1 = PG_GETARG_TEXT_P(0);
+	text	   *t2 = PG_GETARG_TEXT_P(1);
 	int			len1,
 				len2,
 				len;
-	char	   *ptr;
 	text	   *result;
-
-	if (!PointerIsValid(t1) || !PointerIsValid(t2))
-		return NULL;
+	char	   *ptr;
 
 	len1 = (VARSIZE(t1) - VARHDRSZ);
 	if (len1 < 0)
 		len1 = 0;
-	while (len1 > 0 && VARDATA(t1)[len1 - 1] == '\0')
-		len1--;
 
 	len2 = (VARSIZE(t2) - VARHDRSZ);
 	if (len2 < 0)
 		len2 = 0;
-	while (len2 > 0 && VARDATA(t2)[len2 - 1] == '\0')
-		len2--;
 
 	len = len1 + len2 + VARHDRSZ;
-	result = palloc(len);
+	result = (text *) palloc(len);
 
 	/* Set size of result string... */
 	VARATT_SIZEP(result) = len;
@@ -289,8 +284,8 @@ textcat(text *t1, text *t2)
 	if (len2 > 0)
 		memcpy(ptr + len1, VARDATA(t2), len2);
 
-	return result;
-}	/* textcat() */
+	PG_RETURN_TEXT_P(result);
+}
 
 /*
  * text_substr()
@@ -383,9 +378,11 @@ text_substr(PG_FUNCTION_ARGS)
  * Added multi-byte support.
  * - Tatsuo Ishii 1998-4-21
  */
-int32
-textpos(text *t1, text *t2)
+Datum
+textpos(PG_FUNCTION_ARGS)
 {
+	text	   *t1 = PG_GETARG_TEXT_P(0);
+	text	   *t2 = PG_GETARG_TEXT_P(1);
 	int			pos;
 	int			px,
 				p;
@@ -393,18 +390,13 @@ textpos(text *t1, text *t2)
 				len2;
 	pg_wchar   *p1,
 			   *p2;
-
 #ifdef MULTIBYTE
 	pg_wchar   *ps1,
 			   *ps2;
-
 #endif
 
-	if (!PointerIsValid(t1) || !PointerIsValid(t2))
-		return 0;
-
-	if (VARSIZE(t2) <= 0)
-		return 1;
+	if (VARSIZE(t2) <= VARHDRSZ)
+		PG_RETURN_INT32(1);		/* result for empty pattern */
 
 	len1 = (VARSIZE(t1) - VARHDRSZ);
 	len2 = (VARSIZE(t2) - VARHDRSZ);
@@ -438,43 +430,51 @@ textpos(text *t1, text *t2)
 	pfree(ps1);
 	pfree(ps2);
 #endif
-	return pos;
-}	/* textpos() */
+	PG_RETURN_INT32(pos);
+}
 
 /*
- *		texteq			- returns 1 iff arguments are equal
- *		textne			- returns 1 iff arguments are not equal
+ *		texteq			- returns true iff arguments are equal
+ *		textne			- returns true iff arguments are not equal
  */
-bool
-texteq(text *arg1, text *arg2)
+Datum
+texteq(PG_FUNCTION_ARGS)
 {
+	text	   *arg1 = PG_GETARG_TEXT_P(0);
+	text	   *arg2 = PG_GETARG_TEXT_P(1);
 	int			len;
 	char	   *a1p,
 			   *a2p;
 
-	if (arg1 == NULL || arg2 == NULL)
-		return (bool) NULL;
-	if ((len = arg1->vl_len) != arg2->vl_len)
-		return (bool) 0;
-	a1p = arg1->vl_dat;
-	a2p = arg2->vl_dat;
+	if (VARSIZE(arg1) != VARSIZE(arg2))
+		PG_RETURN_BOOL(false);
 
-	/*
-	 * Varlenas are stored as the total size (data + size variable)
-	 * followed by the data. Use VARHDRSZ instead of explicit sizeof() -
-	 * thomas 1997-07-10
-	 */
-	len -= VARHDRSZ;
-	while (len-- != 0)
-		if (*a1p++ != *a2p++)
-			return (bool) 0;
-	return (bool) 1;
-}	/* texteq() */
-
-bool
-textne(text *arg1, text *arg2)
+	len = VARSIZE(arg1) - VARHDRSZ;
+
+	a1p = VARDATA(arg1);
+	a2p = VARDATA(arg2);
+
+	PG_RETURN_BOOL(memcmp(a1p, a2p, len) == 0);
+}
+
+Datum
+textne(PG_FUNCTION_ARGS)
 {
-	return (bool) !texteq(arg1, arg2);
+	text	   *arg1 = PG_GETARG_TEXT_P(0);
+	text	   *arg2 = PG_GETARG_TEXT_P(1);
+	int			len;
+	char	   *a1p,
+			   *a2p;
+
+	if (VARSIZE(arg1) != VARSIZE(arg2))
+		PG_RETURN_BOOL(true);
+
+	len = VARSIZE(arg1) - VARHDRSZ;
+
+	a1p = VARDATA(arg1);
+	a2p = VARDATA(arg2);
+
+	PG_RETURN_BOOL(memcmp(a1p, a2p, len) != 0);
 }
 
 /* varstr_cmp()
@@ -515,7 +515,7 @@ varstr_cmp(char *arg1, int len1, char *arg2, int len2)
 #endif
 
 	return result;
-}	/* varstr_cmp() */
+}
 
 
 /* text_cmp()
@@ -534,9 +534,6 @@ text_cmp(text *arg1, text *arg2)
 	int			len1,
 				len2;
 
-	if (arg1 == NULL || arg2 == NULL)
-		return (bool) FALSE;
-
 	a1p = VARDATA(arg1);
 	a2p = VARDATA(arg2);
 
@@ -544,68 +541,82 @@ text_cmp(text *arg1, text *arg2)
 	len2 = VARSIZE(arg2) - VARHDRSZ;
 
 	return varstr_cmp(a1p, len1, a2p, len2);
-}	/* text_cmp() */
+}
 
-/* text_lt()
- * Comparison function for text strings.
+/*
+ * Comparison functions for text strings.
  */
-bool
-text_lt(text *arg1, text *arg2)
+
+Datum
+text_lt(PG_FUNCTION_ARGS)
 {
-	return (bool) (text_cmp(arg1, arg2) < 0);
-}	/* text_lt() */
+	text	   *arg1 = PG_GETARG_TEXT_P(0);
+	text	   *arg2 = PG_GETARG_TEXT_P(1);
 
-/* text_le()
- * Comparison function for text strings.
- */
-bool
-text_le(text *arg1, text *arg2)
+	PG_RETURN_BOOL(text_cmp(arg1, arg2) < 0);
+}
+
+Datum
+text_le(PG_FUNCTION_ARGS)
 {
-	return (bool) (text_cmp(arg1, arg2) <= 0);
-}	/* text_le() */
+	text	   *arg1 = PG_GETARG_TEXT_P(0);
+	text	   *arg2 = PG_GETARG_TEXT_P(1);
 
-bool
-text_gt(text *arg1, text *arg2)
+	PG_RETURN_BOOL(text_cmp(arg1, arg2) <= 0);
+}
+
+Datum
+text_gt(PG_FUNCTION_ARGS)
 {
-	return (bool) !text_le(arg1, arg2);
+	text	   *arg1 = PG_GETARG_TEXT_P(0);
+	text	   *arg2 = PG_GETARG_TEXT_P(1);
+
+	PG_RETURN_BOOL(text_cmp(arg1, arg2) > 0);
 }
 
-bool
-text_ge(text *arg1, text *arg2)
+Datum
+text_ge(PG_FUNCTION_ARGS)
 {
-	return (bool) !text_lt(arg1, arg2);
+	text	   *arg1 = PG_GETARG_TEXT_P(0);
+	text	   *arg2 = PG_GETARG_TEXT_P(1);
+
+	PG_RETURN_BOOL(text_cmp(arg1, arg2) >= 0);
 }
 
-text *
-text_larger(text *arg1, text *arg2)
+Datum
+text_larger(PG_FUNCTION_ARGS)
 {
+	text	   *arg1 = PG_GETARG_TEXT_P(0);
+	text	   *arg2 = PG_GETARG_TEXT_P(1);
 	text	   *result;
 	text	   *temp;
 
-	temp = ((text_cmp(arg1, arg2) <= 0) ? arg2 : arg1);
+	temp = ((text_cmp(arg1, arg2) > 0) ? arg1 : arg2);
 
-	/* Make a copy */
+	/* Make a copy --- temporary hack until nodeAgg.c is smarter */
 
 	result = (text *) palloc(VARSIZE(temp));
-	memmove((char *) result, (char *) temp, VARSIZE(temp));
+	memcpy((char *) result, (char *) temp, VARSIZE(temp));
 
-	return (result);
+	PG_RETURN_TEXT_P(result);
 }
 
-text *
-text_smaller(text *arg1, text *arg2)
+Datum
+text_smaller(PG_FUNCTION_ARGS)
 {
+	text	   *arg1 = PG_GETARG_TEXT_P(0);
+	text	   *arg2 = PG_GETARG_TEXT_P(1);
 	text	   *result;
 	text	   *temp;
 
-	temp = ((text_cmp(arg1, arg2) > 0) ? arg2 : arg1);
+	temp = ((text_cmp(arg1, arg2) < 0) ? arg1 : arg2);
 
-	/* Make a copy */
+	/* Make a copy --- temporary hack until nodeAgg.c is smarter */
 
 	result = (text *) palloc(VARSIZE(temp));
-	memmove((char *) result, (char *) temp, VARSIZE(temp));
+	memcpy((char *) result, (char *) temp, VARSIZE(temp));
 
-	return (result);
+	PG_RETURN_TEXT_P(result);
 }
 
 /*-------------------------------------------------------------
@@ -780,28 +791,28 @@ byteaSetBit(PG_FUNCTION_ARGS)
 
 
 /* text_name()
- * Converts a text() type to a NameData type.
+ * Converts a text type to a Name type.
  */
-NameData   *
-text_name(text *s)
+Datum
+text_name(PG_FUNCTION_ARGS)
 {
-	NameData   *result;
+	text	   *s = PG_GETARG_TEXT_P(0);
+	Name		result;
 	int			len;
 
-	if (s == NULL)
-		return NULL;
-
 	len = VARSIZE(s) - VARHDRSZ;
-	if (len > NAMEDATALEN)
-		len = NAMEDATALEN;
+
+	/* Truncate oversize input */
+	if (len >= NAMEDATALEN)
+		len = NAMEDATALEN-1;
 
 #ifdef STRINGDEBUG
 	printf("text- convert string length %d (%d) ->%d\n",
 		   VARSIZE(s) - VARHDRSZ, VARSIZE(s), len);
 #endif
 
-	result = palloc(NAMEDATALEN);
-	StrNCpy(NameStr(*result), VARDATA(s), NAMEDATALEN);
+	result = (Name) palloc(NAMEDATALEN);
+	memcpy(NameStr(*result), VARDATA(s), len);
 
 	/* now null pad to full length... */
 	while (len < NAMEDATALEN)
@@ -810,21 +821,19 @@ text_name(text *s)
 		len++;
 	}
 
-	return result;
-}	/* text_name() */
+	PG_RETURN_NAME(result);
+}
 
 /* name_text()
- * Converts a NameData type to a text type.
+ * Converts a Name type to a text type.
  */
-text *
-name_text(NameData *s)
+Datum
+name_text(PG_FUNCTION_ARGS)
 {
+	Name		s = PG_GETARG_NAME(0);
 	text	   *result;
 	int			len;
 
-	if (s == NULL)
-		return NULL;
-
 	len = strlen(NameStr(*s));
 
 #ifdef STRINGDEBUG
@@ -833,8 +842,8 @@ name_text(NameData *s)
 #endif
 
 	result = palloc(VARHDRSZ + len);
-	strncpy(VARDATA(result), NameStr(*s), len);
-	VARATT_SIZEP(result) = len + VARHDRSZ;
+	VARATT_SIZEP(result) = VARHDRSZ + len;
+	memcpy(VARDATA(result), NameStr(*s), len);
 
-	return result;
-}	/* name_text() */
+	PG_RETURN_TEXT_P(result);
+}
diff --git a/src/backend/utils/adt/version.c b/src/backend/utils/adt/version.c
index 0cf0b7859e8..778a0f0cd7b 100644
--- a/src/backend/utils/adt/version.c
+++ b/src/backend/utils/adt/version.c
@@ -1,29 +1,28 @@
 /*-------------------------------------------------------------------------
  *
  * version.c
- *	 Returns the version string
+ *	 Returns the PostgreSQL version string
  *
  * IDENTIFICATION
  *
- * $Header: /cvsroot/pgsql/src/backend/utils/adt/version.c,v 1.11 2000/07/03 23:09:54 wieck Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/adt/version.c,v 1.12 2000/07/06 05:48:11 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
 
-
 #include "postgres.h"
 
+#include "utils/builtins.h"
 
-text	   *version(void);
 
-text *
-version(void)
+Datum
+pgsql_version(PG_FUNCTION_ARGS)
 {
-	int			n = strlen(PG_VERSION_STR) + VARHDRSZ;
-	text	   *ret = (text *) palloc(n);
+	int			n = strlen(PG_VERSION_STR);
+	text	   *ret = (text *) palloc(n + VARHDRSZ);
 
-	VARATT_SIZEP(ret) = n;
-	memcpy(VARDATA(ret), PG_VERSION_STR, strlen(PG_VERSION_STR));
+	VARATT_SIZEP(ret) = n + VARHDRSZ;
+	memcpy(VARDATA(ret), PG_VERSION_STR, n);
 
-	return ret;
+	PG_RETURN_TEXT_P(ret);
 }
diff --git a/src/backend/utils/fmgr/fmgr.c b/src/backend/utils/fmgr/fmgr.c
index fd732c8f94d..7b8aca3feb4 100644
--- a/src/backend/utils/fmgr/fmgr.c
+++ b/src/backend/utils/fmgr/fmgr.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/utils/fmgr/fmgr.c,v 1.44 2000/07/05 23:11:40 tgl Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/utils/fmgr/fmgr.c,v 1.45 2000/07/06 05:48:13 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -1284,3 +1284,33 @@ Float8GetDatum(float8 X)
 	*retval = X;
 	return PointerGetDatum(retval);
 }
+
+/*-------------------------------------------------------------------------
+ *		Support routines for toastable datatypes
+ *-------------------------------------------------------------------------
+ */
+
+struct varlena *
+pg_detoast_datum(struct varlena * datum)
+{
+	if (VARATT_IS_EXTENDED(datum))
+		return (struct varlena *) heap_tuple_untoast_attr((varattrib *) datum);
+	else
+		return datum;
+}
+
+struct varlena *
+pg_detoast_datum_copy(struct varlena * datum)
+{
+	if (VARATT_IS_EXTENDED(datum))
+		return (struct varlena *) heap_tuple_untoast_attr((varattrib *) datum);
+	else
+	{
+		/* Make a modifiable copy of the varlena object */
+		Size			len = VARSIZE(datum);
+		struct varlena *result = (struct varlena *) palloc(len);
+
+		memcpy(result, datum, len);
+		return result;
+	}
+}
diff --git a/src/include/catalog/catversion.h b/src/include/catalog/catversion.h
index eb0632ff0d8..1fd691784b6 100644
--- a/src/include/catalog/catversion.h
+++ b/src/include/catalog/catversion.h
@@ -37,7 +37,7 @@
  * Portions Copyright (c) 1996-2000, PostgreSQL, Inc
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: catversion.h,v 1.34 2000/07/03 23:19:04 wieck Exp $
+ * $Id: catversion.h,v 1.35 2000/07/06 05:48:22 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -53,6 +53,6 @@
  */
 
 /*							yyyymmddN */
-#define CATALOG_VERSION_NO	200007041
+#define CATALOG_VERSION_NO	200007061
 
 #endif
diff --git a/src/include/catalog/pg_proc.h b/src/include/catalog/pg_proc.h
index b4af7610159..d65bee7c545 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.142 2000/07/05 23:11:45 tgl Exp $
+ * $Id: pg_proc.h,v 1.143 2000/07/06 05:48:22 tgl Exp $
  *
  * NOTES
  *	  The script catalog/genbki.sh reads this file and generates .bki
@@ -167,7 +167,7 @@ DATA(insert OID =  65 (  int4eq			   PGUID 12 f t t t 2 f 16 "23 23" 100 0 0 100
 DESCR("equal");
 DATA(insert OID =  66 (  int4lt			   PGUID 12 f t t t 2 f 16 "23 23" 100 0 0 100  int4lt - ));
 DESCR("less-than");
-DATA(insert OID =  67 (  texteq			   PGUID 11 f t t t 2 f 16 "25 25" 100 0 0 0	texteq - ));
+DATA(insert OID =  67 (  texteq			   PGUID 12 f t t t 2 f 16 "25 25" 100 0 0 0	texteq - ));
 DESCR("equal");
 DATA(insert OID =  68 (  xideq			   PGUID 12 f t t t 2 f 16 "28 28" 100 0 0 100  xideq - ));
 DESCR("equal");
@@ -192,22 +192,22 @@ DESCR("multiply");
 DATA(insert OID =  78 (  chardiv		   PGUID 12 f t t t 2 f 18 "18 18" 100 0 0 100  chardiv - ));
 DESCR("divide");
 
-DATA(insert OID =  79 (  nameregexeq	   PGUID 11 f t t t 2 f 16 "19 25" 100 0 0 100  nameregexeq - ));
+DATA(insert OID =  79 (  nameregexeq	   PGUID 12 f t t t 2 f 16 "19 25" 100 0 0 100  nameregexeq - ));
 DESCR("matches regex., case-sensitive");
-DATA(insert OID = 1252 (  nameregexne	   PGUID 11 f t t t 2 f 16 "19 25" 100 0 0 100  nameregexne - ));
+DATA(insert OID = 1252 (  nameregexne	   PGUID 12 f t t t 2 f 16 "19 25" 100 0 0 100  nameregexne - ));
 DESCR("does not match regex., case-sensitive");
-DATA(insert OID = 1254 (  textregexeq	   PGUID 11 f t t t 2 f 16 "25 25" 100 0 1 0	textregexeq - ));
+DATA(insert OID = 1254 (  textregexeq	   PGUID 12 f t t t 2 f 16 "25 25" 100 0 1 0	textregexeq - ));
 DESCR("matches regex., case-sensitive");
-DATA(insert OID = 1256 (  textregexne	   PGUID 11 f t t t 2 f 16 "25 25" 100 0 1 0	textregexne - ));
+DATA(insert OID = 1256 (  textregexne	   PGUID 12 f t t t 2 f 16 "25 25" 100 0 1 0	textregexne - ));
 DESCR("does not match regex., case-sensitive");
-DATA(insert OID = 1257 (  textlen		   PGUID 11 f t t t 1 f 23 "25" 100 0 1 0  textlen - ));
+DATA(insert OID = 1257 (  textlen		   PGUID 12 f t t t 1 f 23 "25" 100 0 1 0  textlen - ));
 DESCR("length");
-DATA(insert OID = 1258 (  textcat		   PGUID 11 f t t t 2 f 25 "25 25" 100 0 1 0	textcat - ));
+DATA(insert OID = 1258 (  textcat		   PGUID 12 f t t t 2 f 25 "25 25" 100 0 1 0	textcat - ));
 DESCR("concatenate");
 
 DATA(insert OID =  84 (  boolne			   PGUID 12 f t t t 2 f 16 "16 16" 100 0 0 100  boolne - ));
 DESCR("not equal");
-DATA(insert OID =  89 (  version		   PGUID 11 f t f t 0 f 25 "" 100 0 0 100 version - ));
+DATA(insert OID =  89 (  version		   PGUID 12 f t f t 0 f 25 "" 100 0 0 100 pgsql_version - ));
 DESCR("PostgreSQL version string");
 
 DATA(insert OID = 1265 (  rtcostestimate   PGUID 12 f t f t 7 f 0 "0 0 0 0 0 0 0" 100 0 0 100  rtcostestimate - ));
@@ -328,7 +328,7 @@ DATA(insert OID = 155 (  int2mod		   PGUID 12 f t t t 2 f 21 "21 21" 100 0 0 100
 DESCR("modulus");
 DATA(insert OID = 156 (  int4mod		   PGUID 12 f t t t 2 f 23 "23 23" 100 0 0 100  int4mod - ));
 DESCR("modulus");
-DATA(insert OID = 157 (  textne			   PGUID 11 f t t t 2 f 16 "25 25" 100 0 0 0	textne - ));
+DATA(insert OID = 157 (  textne			   PGUID 12 f t t t 2 f 16 "25 25" 100 0 0 0	textne - ));
 DESCR("not equal");
 DATA(insert OID = 158 (  int24eq		   PGUID 12 f t t t 2 f 16 "21 23" 100 0 0 100  int24eq - ));
 DESCR("equal");
@@ -782,9 +782,9 @@ DESCR("intersects?");
 
 /* OIDS 400 - 499 */
 
-DATA(insert OID =  406 (  text			   PGUID 11 f t t t 1 f	25 "19" 100 0 0 100 name_text - ));
+DATA(insert OID =  406 (  text			   PGUID 12 f t t t 1 f	25 "19" 100 0 0 100 name_text - ));
 DESCR("convert name to text");
-DATA(insert OID =  407 (  name			   PGUID 11 f t t t 1 f	19 "25" 100 0 0 100 text_name - ));
+DATA(insert OID =  407 (  name			   PGUID 12 f t t t 1 f	19 "25" 100 0 0 100 text_name - ));
 DESCR("convert text to name");
 DATA(insert OID =  408 (  bpchar		   PGUID 11 f t t t 1 f 1042 "19" 100 0 0 100 name_bpchar - ));
 DESCR("convert name to char()");
@@ -832,9 +832,9 @@ 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 = 458 (  text_larger	   PGUID 11 f t t t 2 f 25 "25 25" 100 0 0 100  text_larger - ));
+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 11 f t t t 2 f 25 "25 25" 100 0 0 100  text_smaller - ));
+DATA(insert OID = 459 (  text_smaller	   PGUID 12 f t t t 2 f 25 "25 25" 100 0 0 100  text_smaller - ));
 DESCR("smaller of two");
 
 DATA(insert OID = 460 (  int8in			   PGUID 12 f t t t 1 f 20 "0" 100 0 0 100  int8in - ));
@@ -968,13 +968,13 @@ DESCR("distance between");
 DATA(insert OID = 730 (  pqtest			   PGUID 11 f t f t 1 f 23 "25" 100 0 0 100  pqtest - ));
 DESCR("");
 
-DATA(insert OID = 740 (  text_lt		   PGUID 11 f t t t 2 f 16 "25 25" 100 0 0 0	text_lt - ));
+DATA(insert OID = 740 (  text_lt		   PGUID 12 f t t t 2 f 16 "25 25" 100 0 0 0	text_lt - ));
 DESCR("less-than");
-DATA(insert OID = 741 (  text_le		   PGUID 11 f t t t 2 f 16 "25 25" 100 0 0 0	text_le - ));
+DATA(insert OID = 741 (  text_le		   PGUID 12 f t t t 2 f 16 "25 25" 100 0 0 0	text_le - ));
 DESCR("less-than-or-equal");
-DATA(insert OID = 742 (  text_gt		   PGUID 11 f t t t 2 f 16 "25 25" 100 0 0 0	text_gt - ));
+DATA(insert OID = 742 (  text_gt		   PGUID 12 f t t t 2 f 16 "25 25" 100 0 0 0	text_gt - ));
 DESCR("greater-than");
-DATA(insert OID = 743 (  text_ge		   PGUID 11 f t t t 2 f 16 "25 25" 100 0 0 0	text_ge - ));
+DATA(insert OID = 743 (  text_ge		   PGUID 12 f t t t 2 f 16 "25 25" 100 0 0 0	text_ge - ));
 DESCR("greater-than-or-equal");
 
 DATA(insert OID = 744 (  array_eq		   PGUID 12 f t t t 2 f 16 "0 0" 100 0 0 100 array_eq -));
@@ -1061,13 +1061,13 @@ DESCR("convert text to int2");
 DATA(insert OID = 819 (  int4			   PGUID 12 f t t t 1 f 23 "25" 100 0 0 100  text_int4 -));
 DESCR("convert text to int4");
 
-DATA(insert OID = 838 (  float8			   PGUID 11 f t t t 1 f 701 "25" 100 0 0 100	text_float8 -));
+DATA(insert OID = 838 (  float8			   PGUID 12 f t t t 1 f 701 "25" 100 0 0 100	text_float8 -));
 DESCR("convert text to float8");
-DATA(insert OID = 839 (  float4			   PGUID 11 f t t t 1 f 700 "25" 100 0 0 100	text_float4 -));
+DATA(insert OID = 839 (  float4			   PGUID 12 f t t t 1 f 700 "25" 100 0 0 100	text_float4 -));
 DESCR("convert text to float4");
-DATA(insert OID = 840 (  text			   PGUID 11 f t t t 1 f  25 "701" 100 0 0 100  float8_text -));
+DATA(insert OID = 840 (  text			   PGUID 12 f t t t 1 f  25 "701" 100 0 0 100  float8_text -));
 DESCR("convert float8 to text");
-DATA(insert OID = 841 (  text			   PGUID 11 f t t t 1 f  25 "700" 100 0 0 100  float4_text -));
+DATA(insert OID = 841 (  text			   PGUID 12 f t t t 1 f  25 "700" 100 0 0 100  float4_text -));
 DESCR("convert float4 to text");
 
 DATA(insert OID =  846 (  cash_mul_flt4    PGUID 11 f t t t 2 f 790 "790 700" 100 0 0 100  cash_mul_flt4 - ));
@@ -1077,11 +1077,11 @@ DESCR("divide");
 DATA(insert OID =  848 (  flt4_mul_cash    PGUID 11 f t t t 2 f 790 "700 790" 100 0 0 100  flt4_mul_cash - ));
 DESCR("multiply");
 
-DATA(insert OID =  849 (  position		   PGUID 11 f t t t 2 f 23 "25 25" 100 0 1 0 textpos - ));
+DATA(insert OID =  849 (  position		   PGUID 12 f t t t 2 f 23 "25 25" 100 0 1 0 textpos - ));
 DESCR("return position of substring");
-DATA(insert OID =  850 (  textlike		   PGUID 11 f t t t 2 f 16 "25 25" 100 0 1 0 textlike - ));
+DATA(insert OID =  850 (  textlike		   PGUID 12 f t t t 2 f 16 "25 25" 100 0 1 0 textlike - ));
 DESCR("matches LIKE expression");
-DATA(insert OID =  851 (  textnlike		   PGUID 11 f t t t 2 f 16 "25 25" 100 0 1 0 textnlike - ));
+DATA(insert OID =  851 (  textnlike		   PGUID 12 f t t t 2 f 16 "25 25" 100 0 1 0 textnlike - ));
 DESCR("does not match LIKE expression");
 
 DATA(insert OID =  852 (  int48eq		   PGUID 12 f t t t 2 f 16 "23 20" 100 0 0 100  int48eq - ));
@@ -1097,9 +1097,9 @@ DESCR("less-than-or-equal");
 DATA(insert OID =  857 (  int48ge		   PGUID 12 f t t t 2 f 16 "23 20" 100 0 0 100  int48ge - ));
 DESCR("greater-than-or-equal");
 
-DATA(insert OID =  858 (  namelike		   PGUID 11 f t t t 2 f 16 "19 25" 100 0 0 100  namelike - ));
+DATA(insert OID =  858 (  namelike		   PGUID 12 f t t t 2 f 16 "19 25" 100 0 0 100  namelike - ));
 DESCR("matches LIKE expression");
-DATA(insert OID =  859 (  namenlike		   PGUID 11 f t t t 2 f 16 "19 25" 100 0 0 100  namenlike - ));
+DATA(insert OID =  859 (  namenlike		   PGUID 12 f t t t 2 f 16 "19 25" 100 0 0 100  namenlike - ));
 DESCR("does not match LIKE expression");
 
 DATA(insert OID =  860 (  bpchar		   PGUID 12 f t t t 1 f 1042 "18" 100 0 0 100  char_bpchar - ));
@@ -1124,7 +1124,7 @@ DATA(insert OID =  886 (  cash_in		   PGUID 11 f t t t 1 f 790 "0" 100 0 0 100
 DESCR("(internal)");
 DATA(insert OID =  887 (  cash_out		   PGUID 11 f t t t 1 f  23 "0" 100 0 0 100  cash_out - ));
 DESCR("(internal)");
-DATA(insert OID =  1273 (  cash_words_out  PGUID 11 f t t t 1 f  25 "790" 100 0 0 100  cash_words_out - ));
+DATA(insert OID =  1273 (  cash_words_out  PGUID 12 f t t t 1 f  25 "790" 100 0 0 100  cash_words_out - ));
 DESCR("output amount as words");
 DATA(insert OID =  888 (  cash_eq		   PGUID 11 f t t t 2 f  16 "790 790" 100 0 0 100  cash_eq - ));
 DESCR("equal");
@@ -1494,13 +1494,13 @@ DESCR("larger of two");
 DATA(insert OID = 1237 (  int8smaller	   PGUID 12 f t t t 2 f 20 "20 20" 100 0 0 100  int8smaller - ));
 DESCR("smaller of two");
 
-DATA(insert OID = 1238 (  texticregexeq    PGUID 11 f t t t 2 f 16 "25 25" 100 0 1 0	texticregexeq - ));
+DATA(insert OID = 1238 (  texticregexeq    PGUID 12 f t t t 2 f 16 "25 25" 100 0 1 0	texticregexeq - ));
 DESCR("matches regex., case-insensitive");
-DATA(insert OID = 1239 (  texticregexne    PGUID 11 f t t t 2 f 16 "25 25" 100 0 1 0	texticregexne - ));
+DATA(insert OID = 1239 (  texticregexne    PGUID 12 f t t t 2 f 16 "25 25" 100 0 1 0	texticregexne - ));
 DESCR("does not match regex., case-insensitive");
-DATA(insert OID = 1240 (  nameicregexeq    PGUID 11 f t t t 2 f 16 "19 25" 100 0 0 100  nameicregexeq - ));
+DATA(insert OID = 1240 (  nameicregexeq    PGUID 12 f t t t 2 f 16 "19 25" 100 0 0 100  nameicregexeq - ));
 DESCR("matches regex., case-insensitive");
-DATA(insert OID = 1241 (  nameicregexne    PGUID 11 f t t t 2 f 16 "19 25" 100 0 0 100  nameicregexne - ));
+DATA(insert OID = 1241 (  nameicregexne    PGUID 12 f t t t 2 f 16 "19 25" 100 0 0 100  nameicregexne - ));
 DESCR("does not match regex., case-insensitive");
 
 DATA(insert OID = 1251 (  int4abs		   PGUID 12 f t t t 1 f 23 "23" 100 0 0 100  int4abs - ));
@@ -1595,7 +1595,7 @@ DESCR("less-equal-greater");
 DATA(insert OID = 1316 (  time				 PGUID 12 f t f t 1 f 1083 "1184" 100 0 0 100  timestamp_time - ));
 DESCR("convert timestamp to time");
 
-DATA(insert OID = 1317 (  length			 PGUID 11 f t t t 1 f   23 "25" 100 0 1 0  textlen - ));
+DATA(insert OID = 1317 (  length			 PGUID 12 f t t t 1 f   23 "25" 100 0 1 0  textlen - ));
 DESCR("length");
 DATA(insert OID = 1318 (  length			 PGUID 11 f t t t 1 f   23 "1042" 100 0 0 100  bpcharlen - ));
 DESCR("character length");
@@ -1672,7 +1672,7 @@ DESCR("character length");
 DATA(insert OID = 1373 (  char_length		 PGUID 11 f t t t 1 f   23   "1043" 100 0 0 100  varcharlen - ));
 DESCR("character length");
 
-DATA(insert OID = 1374 (  octet_length			 PGUID 11 f t t t 1 f   23   "25" 100 0 0 100  textoctetlen - ));
+DATA(insert OID = 1374 (  octet_length			 PGUID 12 f t t t 1 f   23   "25" 100 0 0 100  textoctetlen - ));
 DESCR("octet length");
 DATA(insert OID = 1375 (  octet_length			 PGUID 11 f t t t 1 f   23   "1042" 100 0 0 100  bpcharoctetlen - ));
 DESCR("octet length");
@@ -1688,7 +1688,7 @@ DESCR("larger of two");
 DATA(insert OID = 1380 (  timetz_smaller   PGUID 12 f t t t 2 f 1266 "1266 1266" 100 0 0 100	timetz_smaller - ));
 DESCR("smaller of two");
 
-DATA(insert OID = 1381 (  char_length	   PGUID 11 f t t t 1 f 23 "25" 100 0 1 0  textlen - ));
+DATA(insert OID = 1381 (  char_length	   PGUID 12 f t t t 1 f 23 "25" 100 0 1 0  textlen - ));
 DESCR("length");
 
 DATA(insert OID = 1382 (  date_part    PGUID 14 f t f t 2 f  701 "25 702" 100 0 0 100  "select date_part($1, timestamp($2))" - ));
@@ -1732,10 +1732,10 @@ DESCR("absolute value");
 
 /* OIDS 1400 - 1499 */
 
-DATA(insert OID = 1400 (  name		   PGUID 11 f t t t 1 f	19 "1043" 100 0 0 100  text_name - ));
+DATA(insert OID = 1400 (  name		   PGUID 12 f t t t 1 f	19 "1043" 100 0 0 100  text_name - ));
 DESCR("convert varchar to name");
-DATA(insert OID = 1401 (  varchar	   PGUID 11 f t t t 1 f 1043 "19" 100 0 0 100  name_text - ));
-DESCR("convert convert name to varchar");
+DATA(insert OID = 1401 (  varchar	   PGUID 12 f t t t 1 f 1043 "19" 100 0 0 100  name_text - ));
+DESCR("convert name to varchar");
 
 DATA(insert OID = 1402 (  float4	   PGUID 14 f t t t 1 f  700	"700" 100 0 0 100  "select $1" - ));
 DESCR("convert float4 to float4 (no-op)");
@@ -1976,13 +1976,13 @@ DESCR("(internal)");
 DATA(insert OID = 1565 (  zpbit_out			PGUID 11 f t t t 1 f	 23 "0" 100 0 0 100  zpbit_out - ));
 DESCR("(internal)");
 
-DATA(insert OID = 1569 (  like				PGUID 11 f t t t 2 f 16 "25 25" 100 0 1 0  textlike - ));
+DATA(insert OID = 1569 (  like				PGUID 12 f t t t 2 f 16 "25 25" 100 0 1 0  textlike - ));
 DESCR("matches LIKE expression");
-DATA(insert OID = 1570 (  notlike			PGUID 11 f t t t 2 f 16 "25 25" 100 0 1 0  textnlike - ));
+DATA(insert OID = 1570 (  notlike			PGUID 12 f t t t 2 f 16 "25 25" 100 0 1 0  textnlike - ));
 DESCR("does not match LIKE expression");
-DATA(insert OID = 1571 (  like				PGUID 11 f t t t 2 f 16 "19 25" 100 0 0 100  namelike - ));
+DATA(insert OID = 1571 (  like				PGUID 12 f t t t 2 f 16 "19 25" 100 0 0 100  namelike - ));
 DESCR("matches LIKE expression");
-DATA(insert OID = 1572 (  notlike			PGUID 11 f t t t 2 f 16 "19 25" 100 0 0 100  namenlike - ));
+DATA(insert OID = 1572 (  notlike			PGUID 12 f t t t 2 f 16 "19 25" 100 0 0 100  namenlike - ));
 DESCR("does not match LIKE expression");
 DATA(insert OID = 1573 (  int8				PGUID 14 f t t t 1 f	20 "20" 100 0 0 100  "select $1" - ));
 DESCR("convert int8 to int8 (no-op)");
@@ -2051,7 +2051,7 @@ DESCR("multiply interval");
 DATA(insert OID = 1619 (  varchar			PGUID 12 f t t t 1 f 1043 "23" 100 0 0 100  int4_text - ));
 DESCR("convert int4 to varchar");
 
-DATA(insert OID = 1620 (  ascii				PGUID 11 f t t t 1 f 23 "25" 100 0 0 100	ascii - ));
+DATA(insert OID = 1620 (  ascii				PGUID 12 f t t t 1 f 23 "25" 100 0 0 100	ascii - ));
 DESCR("convert first char to int4");
 DATA(insert OID = 1621 (  ichar				PGUID 12 f t t t 1 f 25 "23" 100 0 0 100	ichar - ));
 DESCR("convert int4 to char");
@@ -2069,7 +2069,7 @@ DATA(insert OID = 1627 ( lztextout			  PGUID 11 f t t t 1 f 23 "0" 100 0 0 100
 DESCR("(internal)");
 DATA(insert OID = 1629 ( text				  PGUID 11 f t t t 1 f 25 "1625" 100 0 0 100	lztext_text -));
 DESCR("convert lztext to text");
-DATA(insert OID = 1631 ( lztext				  PGUID 11 f t t t 1 f 1625 "25" 100 0 0 100	text_lztext -));
+DATA(insert OID = 1631 ( lztext				  PGUID 12 f t t t 1 f 1625 "25" 100 0 0 100	text_lztext -));
 DESCR("convert text to lztext");
 DATA(insert OID = 1632 ( lztext				  PGUID 14 f t t t 1 f 1625 "1625" 100 0 0 100  "select $1" -));
 DESCR("convert text to lztext");
@@ -2098,25 +2098,25 @@ DATA(insert OID = 1689 (  update_pg_pwd       PGUID 12 f t f t 0 f 0  ""  100 0
 DESCR("update pg_pwd file");
 
 /* Oracle Compatibility Related Functions - By Edmund Mergl <E.Mergl@bawue.de> */
-DATA(insert OID =  868 (  strpos	   PGUID 11 f t t t 2 f 23 "25 25" 100 0 0 100  textpos - ));
+DATA(insert OID =  868 (  strpos	   PGUID 12 f t t t 2 f 23 "25 25" 100 0 0 100  textpos - ));
 DESCR("find position of substring");
-DATA(insert OID =  870 (  lower		   PGUID 11 f t t t 1 f 25 "25" 100 0 0 100  lower - ));
+DATA(insert OID =  870 (  lower		   PGUID 12 f t t t 1 f 25 "25" 100 0 0 100  lower - ));
 DESCR("lowercase");
-DATA(insert OID =  871 (  upper		   PGUID 11 f t t t 1 f 25 "25" 100 0 0 100  upper - ));
+DATA(insert OID =  871 (  upper		   PGUID 12 f t t t 1 f 25 "25" 100 0 0 100  upper - ));
 DESCR("uppercase");
-DATA(insert OID =  872 (  initcap	   PGUID 11 f t t t 1 f 25 "25" 100 0 0 100  initcap - ));
+DATA(insert OID =  872 (  initcap	   PGUID 12 f t t t 1 f 25 "25" 100 0 0 100  initcap - ));
 DESCR("capitalize each word");
 DATA(insert OID =  873 (  lpad		   PGUID 12 f t t t 3 f 25 "25 23 25" 100 0 0 100  lpad - ));
 DESCR("left-pad string to length");
 DATA(insert OID =  874 (  rpad		   PGUID 12 f t t t 3 f 25 "25 23 25" 100 0 0 100  rpad - ));
 DESCR("right-pad string to length");
-DATA(insert OID =  875 (  ltrim		   PGUID 11 f t t t 2 f 25 "25 25" 100 0 0 100  ltrim - ));
+DATA(insert OID =  875 (  ltrim		   PGUID 12 f t t t 2 f 25 "25 25" 100 0 0 100  ltrim - ));
 DESCR("left-pad string to length");
-DATA(insert OID =  876 (  rtrim		   PGUID 11 f t t t 2 f 25 "25 25" 100 0 0 100  rtrim - ));
+DATA(insert OID =  876 (  rtrim		   PGUID 12 f t t t 2 f 25 "25 25" 100 0 0 100  rtrim - ));
 DESCR("right-pad string to length");
 DATA(insert OID =  877 (  substr	   PGUID 12 f t t t 3 f 25 "25 23 23" 100 0 0 100  text_substr - ));
 DESCR("return portion of string");
-DATA(insert OID =  878 (  translate    PGUID 11 f t t t 3 f 25 "25 25 25" 100 0 0 100  translate - ));
+DATA(insert OID =  878 (  translate    PGUID 12 f t t t 3 f 25 "25 25 25" 100 0 0 100  translate - ));
 DESCR("modify string by substring replacement");
 DATA(insert OID =  879 (  lpad		   PGUID 14 f t t t 2 f 25 "25 23" 100 0 0 100  "select lpad($1, $2, \' \')" - ));
 DESCR("left-pad string to length");
@@ -2128,7 +2128,7 @@ DATA(insert OID =  882 (  rtrim		   PGUID 14 f t t t 1 f 25 "25" 100 0 0 100  "s
 DESCR("remove trailing characters from string");
 DATA(insert OID =  883 (  substr	   PGUID 14 f t t t 2 f 25 "25 23" 100 0 0 100  "select substr($1, $2, -1)" - ));
 DESCR("return portion of string");
-DATA(insert OID =  884 (  btrim		   PGUID 11 f t t t 2 f 25 "25 25" 100 0 0 100  btrim - ));
+DATA(insert OID =  884 (  btrim		   PGUID 12 f t t t 2 f 25 "25 25" 100 0 0 100  btrim - ));
 DESCR("trim both ends of string");
 DATA(insert OID =  885 (  btrim		   PGUID 14 f t t t 1 f 25 "25" 100 0 0 100  "select btrim($1, \' \')" - ));
 DESCR("trim both ends of string");
@@ -2144,9 +2144,9 @@ DATA(insert OID = 1597 (  pg_encoding_to_char	   PGUID 12 f t f t 1 f 19 "23" 10
 DESCR("convert encoding id to encoding name");
 
 /* System-view support functions */
-DATA(insert OID = 1640 (  pg_get_ruledef	   PGUID 11 f t f t 1 f 25 "19" 100 0 0 100  pg_get_ruledef - ));
+DATA(insert OID = 1640 (  pg_get_ruledef	   PGUID 12 f t f t 1 f 25 "19" 100 0 0 100  pg_get_ruledef - ));
 DESCR("source text of a rule");
-DATA(insert OID = 1641 (  pg_get_viewdef	   PGUID 11 f t f t 1 f 25 "19" 100 0 0 100  pg_get_viewdef - ));
+DATA(insert OID = 1641 (  pg_get_viewdef	   PGUID 12 f t f t 1 f 25 "19" 100 0 0 100  pg_get_viewdef - ));
 DESCR("select statement of a view");
 DATA(insert OID = 1642 (  pg_get_userbyid	   PGUID 12 f t f t 1 f 19 "23" 100 0 0 100  pg_get_userbyid - ));
 DESCR("user name by UID (with fallback)");
@@ -2248,7 +2248,7 @@ DATA(insert OID = 835 (  macaddr_ne		   PGUID 11 f t t t 2 f 16 "829 829" 100 0
 DESCR("not equal");
 DATA(insert OID = 836 (  macaddr_cmp	   PGUID 11 f t t t 2 f 23 "829 829" 100 0 0 100	macaddr_cmp - ));
 DESCR("less-equal-greater");
-DATA(insert OID = 837 (  macaddr_manuf	   PGUID 11 f t t t 1 f 25 "829" 100 0 0 100	macaddr_manuf - ));
+DATA(insert OID = 837 (  macaddr_manuf	   PGUID 12 f t t t 1 f 25 "829" 100 0 0 100	macaddr_manuf - ));
 DESCR("MAC manufacturer");
 
 /* for inet type support */
@@ -2288,15 +2288,15 @@ DATA(insert OID = 930 (  network_supeq		   PGUID 11 f t t t 2 f 16 "869 869" 100
 DESCR("is-supernet-or-equal");
 
 /* inet/cidr versions */
-DATA(insert OID = 696 (  netmask				PGUID 11 f t t t 1 f 25 "869" 100 0 0 100  network_netmask - ));
+DATA(insert OID = 696 (  netmask				PGUID 12 f t t t 1 f 25 "869" 100 0 0 100  network_netmask - ));
 DESCR("netmask of address");
 DATA(insert OID = 697 (  masklen				PGUID 11 f t t t 1 f 23 "869" 100 0 0 100  network_masklen - ));
 DESCR("netmask length");
-DATA(insert OID = 698 (  broadcast				PGUID 11 f t t t 1 f 25 "869" 100 0 0 100  network_broadcast - ));
+DATA(insert OID = 698 (  broadcast				PGUID 12 f t t t 1 f 25 "869" 100 0 0 100  network_broadcast - ));
 DESCR("broadcast address");
-DATA(insert OID = 699 (  host					PGUID 11 f t t t 1 f 25 "869" 100 0 0 100  network_host - ));
+DATA(insert OID = 699 (  host					PGUID 12 f t t t 1 f 25 "869" 100 0 0 100  network_host - ));
 DESCR("host address");
-DATA(insert OID = 683 (  network				PGUID 11 f t t t 1 f 25 "869" 100 0 0 100  network_network - ));
+DATA(insert OID = 683 (  network				PGUID 12 f t t t 1 f 25 "869" 100 0 0 100  network_network - ));
 DESCR("network address");
 
 DATA(insert OID =  1691 (  boolle			   PGUID 12 f t t t 2 f 16 "16 16" 100 0 0 100  boolle - ));
diff --git a/src/include/catalog/pg_type.h b/src/include/catalog/pg_type.h
index b7a41b6a72d..69e37eb9969 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.90 2000/07/03 23:10:05 wieck Exp $
+ * $Id: pg_type.h,v 1.91 2000/07/06 05:48:27 tgl Exp $
  *
  * NOTES
  *	  the genbki.sh script reads this file and generates .bki
@@ -200,7 +200,7 @@ DATA(insert OID = 24 (	regproc    PGUID  4  16 t b t \054 0   0 regprocin regpro
 DESCR("registered procedure");
 #define REGPROCOID		24
 
-DATA(insert OID = 25 (	text	   PGUID -1  -1 f b t \054 0  18 textin textout textin textout i p _null_ ));
+DATA(insert OID = 25 (	text	   PGUID -1  -1 f b t \054 0  18 textin textout textin textout i x _null_ ));
 DESCR("variable-length string, no limit specified");
 #define TEXTOID			25
 
diff --git a/src/include/fmgr.h b/src/include/fmgr.h
index c68abfcf85e..b0aea5df09e 100644
--- a/src/include/fmgr.h
+++ b/src/include/fmgr.h
@@ -11,7 +11,7 @@
  * Portions Copyright (c) 1996-2000, PostgreSQL, Inc
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: fmgr.h,v 1.6 2000/06/14 05:24:50 tgl Exp $
+ * $Id: fmgr.h,v 1.7 2000/07/06 05:48:17 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -94,22 +94,30 @@ extern void fmgr_info(Oid functionId, FmgrInfo *finfo);
 /* Standard parameter list for fmgr-compatible functions */
 #define PG_FUNCTION_ARGS	FunctionCallInfo fcinfo
 
-/* If function is not marked "proisstrict" in pg_proc, it must check for
+/*
+ * If function is not marked "proisstrict" in pg_proc, it must check for
  * null arguments using this macro.  Do not try to GETARG a null argument!
  */
 #define PG_ARGISNULL(n)  (fcinfo->argnull[n])
 
-#if 1
-/* VERY TEMPORARY until some TOAST support is committed ... */
-#define PG_DETOAST_DATUM(datum)  \
-	 ((struct varlena *) DatumGetPointer(datum))
-#else
-/* Eventually it will look more like this... */
-#define PG_DETOAST_DATUM(datum)  \
-	(VARATT_IS_EXTENDED(DatumGetPointer(datum)) ?  \
-	 (struct varlena *) heap_tuple_untoast_attr((varattrib *) DatumGetPointer(datum)) :  \
-	 (struct varlena *) DatumGetPointer(datum))
-#endif
+/*
+ * Support for fetching detoasted copies of toastable datatypes (all of
+ * which are varlena types).  pg_detoast_datum() gives you either the input
+ * datum (if not toasted) or a detoasted copy allocated with palloc().
+ * pg_detoast_datum_copy() always gives you a palloc'd copy --- use it
+ * if you need a modifiable copy of the input.  Caller is expected to have
+ * checked for null inputs first, if necessary.
+ *
+ * Note: it'd be nice if these could be macros, but I see no way to do that
+ * without evaluating the arguments multiple times, which is NOT acceptable.
+ */
+extern struct varlena * pg_detoast_datum(struct varlena * datum);
+extern struct varlena * pg_detoast_datum_copy(struct varlena * datum);
+
+#define PG_DETOAST_DATUM(datum) \
+	pg_detoast_datum((struct varlena *) DatumGetPointer(datum))
+#define PG_DETOAST_DATUM_COPY(datum) \
+	pg_detoast_datum_copy((struct varlena *) DatumGetPointer(datum))
 
 /* Macros for fetching arguments of standard types */
 
@@ -133,15 +141,25 @@ extern void fmgr_info(Oid functionId, FmgrInfo *finfo);
 /* use this if you want the input datum de-toasted: */
 #define PG_GETARG_VARLENA_P(n) PG_DETOAST_DATUM(PG_GETARG_DATUM(n))
 /* DatumGetFoo macros for varlena types will typically look like this: */
-#define DatumGetByteaP(X)    ((bytea *) PG_DETOAST_DATUM(X))
-#define DatumGetTextP(X)     ((text *) PG_DETOAST_DATUM(X))
-#define DatumGetBpCharP(X)   ((BpChar *) PG_DETOAST_DATUM(X))
-#define DatumGetVarCharP(X)  ((VarChar *) PG_DETOAST_DATUM(X))
+#define DatumGetByteaP(X)           ((bytea *) PG_DETOAST_DATUM(X))
+#define DatumGetTextP(X)            ((text *) PG_DETOAST_DATUM(X))
+#define DatumGetBpCharP(X)          ((BpChar *) PG_DETOAST_DATUM(X))
+#define DatumGetVarCharP(X)         ((VarChar *) PG_DETOAST_DATUM(X))
+/* And we also offer variants that return an OK-to-write copy */
+#define DatumGetByteaPCopy(X)       ((bytea *) PG_DETOAST_DATUM_COPY(X))
+#define DatumGetTextPCopy(X)        ((text *) PG_DETOAST_DATUM_COPY(X))
+#define DatumGetBpCharPCopy(X)      ((BpChar *) PG_DETOAST_DATUM_COPY(X))
+#define DatumGetVarCharPCopy(X)     ((VarChar *) PG_DETOAST_DATUM_COPY(X))
 /* GETARG macros for varlena types will typically look like this: */
-#define PG_GETARG_BYTEA_P(n)   DatumGetByteaP(PG_GETARG_DATUM(n))
-#define PG_GETARG_TEXT_P(n)    DatumGetTextP(PG_GETARG_DATUM(n))
-#define PG_GETARG_BPCHAR_P(n)  DatumGetBpCharP(PG_GETARG_DATUM(n))
-#define PG_GETARG_VARCHAR_P(n) DatumGetVarCharP(PG_GETARG_DATUM(n))
+#define PG_GETARG_BYTEA_P(n)        DatumGetByteaP(PG_GETARG_DATUM(n))
+#define PG_GETARG_TEXT_P(n)         DatumGetTextP(PG_GETARG_DATUM(n))
+#define PG_GETARG_BPCHAR_P(n)       DatumGetBpCharP(PG_GETARG_DATUM(n))
+#define PG_GETARG_VARCHAR_P(n)      DatumGetVarCharP(PG_GETARG_DATUM(n))
+/* And we also offer variants that return an OK-to-write copy */
+#define PG_GETARG_BYTEA_P_COPY(n)   DatumGetByteaPCopy(PG_GETARG_DATUM(n))
+#define PG_GETARG_TEXT_P_COPY(n)    DatumGetTextPCopy(PG_GETARG_DATUM(n))
+#define PG_GETARG_BPCHAR_P_COPY(n)  DatumGetBpCharPCopy(PG_GETARG_DATUM(n))
+#define PG_GETARG_VARCHAR_P_COPY(n) DatumGetVarCharPCopy(PG_GETARG_DATUM(n))
 
 /* To return a NULL do this: */
 #define PG_RETURN_NULL()  \
diff --git a/src/include/utils/builtins.h b/src/include/utils/builtins.h
index 9e7e995ee16..f6838a59382 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.119 2000/07/05 23:11:51 tgl Exp $
+ * $Id: builtins.h,v 1.120 2000/07/06 05:48:30 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -243,10 +243,10 @@ extern Datum i4tof(PG_FUNCTION_ARGS);
 extern Datum i2tof(PG_FUNCTION_ARGS);
 extern int32 ftoi4(float32 num);
 extern Datum ftoi2(PG_FUNCTION_ARGS);
-extern float64 text_float8(text *str);
-extern float32 text_float4(text *str);
-extern text *float8_text(float64 num);
-extern text *float4_text(float32 num);
+extern Datum text_float8(PG_FUNCTION_ARGS);
+extern Datum text_float4(PG_FUNCTION_ARGS);
+extern Datum float8_text(PG_FUNCTION_ARGS);
+extern Datum float4_text(PG_FUNCTION_ARGS);
 extern float64 dround(float64 arg1);
 extern float64 dtrunc(float64 arg1);
 extern float64 dsqrt(float64 arg1);
@@ -321,15 +321,14 @@ extern Datum oid_text(PG_FUNCTION_ARGS);
 extern Datum text_oid(PG_FUNCTION_ARGS);
 
 /* regexp.c */
-extern bool nameregexeq(NameData *n, struct varlena * p);
-extern bool nameregexne(NameData *s, struct varlena * p);
-extern bool textregexeq(struct varlena * s, struct varlena * p);
-extern bool textregexne(struct varlena * s, struct varlena * p);
-extern bool nameicregexeq(NameData *s, struct varlena * p);
-extern bool nameicregexne(NameData *s, struct varlena * p);
-extern bool texticregexeq(struct varlena * s, struct varlena * p);
-extern bool texticregexne(struct varlena * s, struct varlena * p);
-
+extern Datum nameregexeq(PG_FUNCTION_ARGS);
+extern Datum nameregexne(PG_FUNCTION_ARGS);
+extern Datum textregexeq(PG_FUNCTION_ARGS);
+extern Datum textregexne(PG_FUNCTION_ARGS);
+extern Datum nameicregexeq(PG_FUNCTION_ARGS);
+extern Datum nameicregexne(PG_FUNCTION_ARGS);
+extern Datum texticregexeq(PG_FUNCTION_ARGS);
+extern Datum texticregexne(PG_FUNCTION_ARGS);
 
 /* regproc.c */
 extern Datum regprocin(PG_FUNCTION_ARGS);
@@ -341,8 +340,8 @@ extern Datum regproctooid(PG_FUNCTION_ARGS);
 #define RegprocToOid(rp) ((Oid) (rp))
 
 /* ruleutils.c */
-extern text *pg_get_ruledef(NameData *rname);
-extern text *pg_get_viewdef(NameData *rname);
+extern Datum pg_get_ruledef(PG_FUNCTION_ARGS);
+extern Datum pg_get_viewdef(PG_FUNCTION_ARGS);
 extern Datum pg_get_indexdef(PG_FUNCTION_ARGS);
 extern Datum pg_get_userbyid(PG_FUNCTION_ARGS);
 extern char *deparse_expression(Node *expr, List *rangetables,
@@ -438,22 +437,22 @@ extern int32 varcharoctetlen(char *arg);
 /* varlena.c */
 extern Datum textin(PG_FUNCTION_ARGS);
 extern Datum textout(PG_FUNCTION_ARGS);
-extern text *textcat(text *arg1, text *arg2);
-extern bool texteq(text *arg1, text *arg2);
-extern bool textne(text *arg1, text *arg2);
-extern int	varstr_cmp(char *arg1, int len1, char *arg2, int len2);
-extern bool text_lt(text *arg1, text *arg2);
-extern bool text_le(text *arg1, text *arg2);
-extern bool text_gt(text *arg1, text *arg2);
-extern bool text_ge(text *arg1, text *arg2);
-extern text *text_larger(text *arg1, text *arg2);
-extern text *text_smaller(text *arg1, text *arg2);
-extern int32 textlen(text *arg);
-extern int32 textoctetlen(text *arg);
-extern int32 textpos(text *arg1, text *arg2);
+extern Datum textcat(PG_FUNCTION_ARGS);
+extern Datum texteq(PG_FUNCTION_ARGS);
+extern Datum textne(PG_FUNCTION_ARGS);
+extern Datum text_lt(PG_FUNCTION_ARGS);
+extern Datum text_le(PG_FUNCTION_ARGS);
+extern Datum text_gt(PG_FUNCTION_ARGS);
+extern Datum text_ge(PG_FUNCTION_ARGS);
+extern Datum text_larger(PG_FUNCTION_ARGS);
+extern Datum text_smaller(PG_FUNCTION_ARGS);
+extern Datum textlen(PG_FUNCTION_ARGS);
+extern Datum textoctetlen(PG_FUNCTION_ARGS);
+extern Datum textpos(PG_FUNCTION_ARGS);
 extern Datum text_substr(PG_FUNCTION_ARGS);
-extern text *name_text(NameData *s);
-extern NameData *text_name(text *s);
+extern Datum name_text(PG_FUNCTION_ARGS);
+extern Datum text_name(PG_FUNCTION_ARGS);
+extern int	varstr_cmp(char *arg1, int len1, char *arg2, int len2);
 
 extern bytea *byteain(char *inputText);
 extern char *byteaout(bytea *vlena);
@@ -463,26 +462,29 @@ extern Datum byteaGetBit(PG_FUNCTION_ARGS);
 extern Datum byteaSetByte(PG_FUNCTION_ARGS);
 extern Datum byteaSetBit(PG_FUNCTION_ARGS);
 
+/* version.c */
+extern Datum pgsql_version(PG_FUNCTION_ARGS);
+
 /* like.c */
-extern bool namelike(NameData *n, struct varlena * p);
-extern bool namenlike(NameData *s, struct varlena * p);
-extern bool textlike(struct varlena * s, struct varlena * p);
-extern bool textnlike(struct varlena * s, struct varlena * p);
+extern Datum namelike(PG_FUNCTION_ARGS);
+extern Datum namenlike(PG_FUNCTION_ARGS);
+extern Datum textlike(PG_FUNCTION_ARGS);
+extern Datum textnlike(PG_FUNCTION_ARGS);
 
 /* oracle_compat.c */
 
-extern text *lower(text *string);
-extern text *upper(text *string);
-extern text *initcap(text *string);
+extern Datum lower(PG_FUNCTION_ARGS);
+extern Datum upper(PG_FUNCTION_ARGS);
+extern Datum initcap(PG_FUNCTION_ARGS);
 extern Datum lpad(PG_FUNCTION_ARGS);
 extern Datum rpad(PG_FUNCTION_ARGS);
-extern text *btrim(text *string, text *set);
-extern text *ltrim(text *string, text *set);
-extern text *rtrim(text *string, text *set);
-extern text *translate(text *string, text *from, text *to);
+extern Datum btrim(PG_FUNCTION_ARGS);
+extern Datum ltrim(PG_FUNCTION_ARGS);
+extern Datum rtrim(PG_FUNCTION_ARGS);
+extern Datum translate(PG_FUNCTION_ARGS);
 extern Datum ichar(PG_FUNCTION_ARGS);
 extern Datum repeat(PG_FUNCTION_ARGS);
-extern int4 ascii(text *string);
+extern Datum ascii(PG_FUNCTION_ARGS);
 
 /* acl.c */
 
@@ -510,11 +512,11 @@ extern bool network_sup(inet *a1, inet *a2);
 extern bool network_supeq(inet *a1, inet *a2);
 extern int4 network_cmp(inet *a1, inet *a2);
 
-extern text *network_network(inet *addr);
-extern text *network_netmask(inet *addr);
+extern Datum network_network(PG_FUNCTION_ARGS);
+extern Datum network_netmask(PG_FUNCTION_ARGS);
 extern int4 network_masklen(inet *addr);
-extern text *network_broadcast(inet *addr);
-extern text *network_host(inet *addr);
+extern Datum network_broadcast(PG_FUNCTION_ARGS);
+extern Datum network_host(PG_FUNCTION_ARGS);
 
 /* mac.c */
 extern macaddr *macaddr_in(char *str);
@@ -526,7 +528,7 @@ extern bool macaddr_ge(macaddr *a1, macaddr *a2);
 extern bool macaddr_gt(macaddr *a1, macaddr *a2);
 extern bool macaddr_ne(macaddr *a1, macaddr *a2);
 extern int4 macaddr_cmp(macaddr *a1, macaddr *a2);
-extern text *macaddr_manuf(macaddr *addr);
+extern Datum macaddr_manuf(PG_FUNCTION_ARGS);
 
 /* numeric.c */
 extern Datum numeric_in(PG_FUNCTION_ARGS);
@@ -572,19 +574,19 @@ extern Numeric float8_numeric(float64 val);
 extern float64 numeric_float8(Numeric num);
 
 /* lztext.c */
-lztext	   *lztextin(char *str);
-char	   *lztextout(lztext *lz);
-text	   *lztext_text(lztext *lz);
-lztext	   *text_lztext(text *txt);
-int32		lztextlen(lztext *lz);
-int32		lztextoctetlen(lztext *lz);
-int32		lztext_cmp(lztext *lz1, lztext *lz2);
-bool		lztext_eq(lztext *lz1, lztext *lz2);
-bool		lztext_ne(lztext *lz1, lztext *lz2);
-bool		lztext_gt(lztext *lz1, lztext *lz2);
-bool		lztext_ge(lztext *lz1, lztext *lz2);
-bool		lztext_lt(lztext *lz1, lztext *lz2);
-bool		lztext_le(lztext *lz1, lztext *lz2);
+extern lztext  *lztextin(char *str);
+extern char	   *lztextout(lztext *lz);
+extern text	   *lztext_text(lztext *lz);
+extern Datum	text_lztext(PG_FUNCTION_ARGS);
+extern int32	lztextlen(lztext *lz);
+extern int32	lztextoctetlen(lztext *lz);
+extern int32	lztext_cmp(lztext *lz1, lztext *lz2);
+extern bool		lztext_eq(lztext *lz1, lztext *lz2);
+extern bool		lztext_ne(lztext *lz1, lztext *lz2);
+extern bool		lztext_gt(lztext *lz1, lztext *lz2);
+extern bool		lztext_ge(lztext *lz1, lztext *lz2);
+extern bool		lztext_lt(lztext *lz1, lztext *lz2);
+extern bool		lztext_le(lztext *lz1, lztext *lz2);
 
 /* ri_triggers.c */
 extern Datum RI_FKey_check_ins(PG_FUNCTION_ARGS);
diff --git a/src/include/utils/cash.h b/src/include/utils/cash.h
index 7eca3f9147a..58f906aacc1 100644
--- a/src/include/utils/cash.h
+++ b/src/include/utils/cash.h
@@ -44,6 +44,6 @@ extern Datum cash_div_int2(PG_FUNCTION_ARGS);
 extern Cash *cashlarger(Cash *c1, Cash *c2);
 extern Cash *cashsmaller(Cash *c1, Cash *c2);
 
-extern text *cash_words_out(Cash *value);
+extern Datum cash_words_out(PG_FUNCTION_ARGS);
 
 #endif	 /* CASH_H */
diff --git a/src/include/utils/inet.h b/src/include/utils/inet.h
index 4cc13f06a8e..075d66aa6b3 100644
--- a/src/include/utils/inet.h
+++ b/src/include/utils/inet.h
@@ -1,13 +1,13 @@
 /*-------------------------------------------------------------------------
  *
- * builtins.h
- *	  Declarations for operations on built-in types.
+ * inet.h
+ *	  Declarations for operations on INET datatypes.
  *
  *
  * Portions Copyright (c) 1996-2000, PostgreSQL, Inc
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: inet.h,v 1.6 2000/01/26 05:58:38 momjian Exp $
+ * $Id: inet.h,v 1.7 2000/07/06 05:48:31 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -45,15 +45,4 @@ typedef struct macaddr
 	unsigned char f;
 } macaddr;
 
-
-typedef struct manufacturer
-{
-	unsigned char a;
-	unsigned char b;
-	unsigned char c;
-	char	   *name;
-} manufacturer;
-
-extern manufacturer manufacturers[];
-
 #endif	 /* MAC_H */
-- 
GitLab