From 1ebe1da296419b07377058ffad0e75bb330de8d1 Mon Sep 17 00:00:00 2001
From: Tom Lane <tgl@sss.pgh.pa.us>
Date: Sat, 29 Jul 2000 03:26:51 +0000
Subject: [PATCH] bpchar, varchar, bytea, numeric are toastable --- if you
 initdb, which I did not force.  I marked numeric as
 compressable-but-not-move-off-able, partly to test that storage mode and
 partly because I've got doubts that numerics are large enough to need
 external storage.

---
 src/backend/commands/trigger.c     |   8 +-
 src/backend/utils/adt/formatting.c |  14 +-
 src/backend/utils/adt/numeric.c    | 731 +++++++++++++----------------
 src/backend/utils/adt/selfuncs.c   |  11 +-
 src/backend/utils/adt/varchar.c    | 393 +++++++++-------
 src/backend/utils/adt/varlena.c    |  72 +--
 src/include/catalog/pg_proc.h      | 128 ++---
 src/include/catalog/pg_type.h      |  10 +-
 src/include/fmgr.h                 |   3 +-
 src/include/utils/builtins.h       | 110 ++---
 10 files changed, 727 insertions(+), 753 deletions(-)

diff --git a/src/backend/commands/trigger.c b/src/backend/commands/trigger.c
index 36b2019bd99..8abd930b1b9 100644
--- a/src/backend/commands/trigger.c
+++ b/src/backend/commands/trigger.c
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/commands/trigger.c,v 1.72 2000/07/03 03:57:03 tgl Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/commands/trigger.c,v 1.73 2000/07/29 03:26:40 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -240,12 +240,14 @@ CreateTrigger(CreateTrigStmt *stmt)
 			strcat(args, "\\000");
 		}
 		values[Anum_pg_trigger_tgnargs - 1] = Int16GetDatum(nargs);
-		values[Anum_pg_trigger_tgargs - 1] = PointerGetDatum(byteain(args));
+		values[Anum_pg_trigger_tgargs - 1] = DirectFunctionCall1(byteain,
+													CStringGetDatum(args));
 	}
 	else
 	{
 		values[Anum_pg_trigger_tgnargs - 1] = Int16GetDatum(0);
-		values[Anum_pg_trigger_tgargs - 1] = PointerGetDatum(byteain(""));
+		values[Anum_pg_trigger_tgargs - 1] = DirectFunctionCall1(byteain,
+													CStringGetDatum(""));
 	}
 	MemSet(tgattr, 0, FUNC_MAX_ARGS * sizeof(int16));
 	values[Anum_pg_trigger_tgattr - 1] = PointerGetDatum(tgattr);
diff --git a/src/backend/utils/adt/formatting.c b/src/backend/utils/adt/formatting.c
index 3df0fe35579..864c3867ba5 100644
--- a/src/backend/utils/adt/formatting.c
+++ b/src/backend/utils/adt/formatting.c
@@ -1,7 +1,7 @@
 /* -----------------------------------------------------------------------
  * formatting.c
  *
- * $Header: /cvsroot/pgsql/src/backend/utils/adt/formatting.c,v 1.19 2000/07/05 23:11:35 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/adt/formatting.c,v 1.20 2000/07/29 03:26:41 tgl Exp $
  *
  *
  *	 Portions Copyright (c) 1999-2000, PostgreSQL, Inc
@@ -4066,7 +4066,9 @@ numeric_to_char(PG_FUNCTION_ARGS)
 		x = DatumGetNumeric(DirectFunctionCall2(numeric_round,
 					NumericGetDatum(value),
 					Int32GetDatum(0)));
-		numstr = orgnum = int_to_roman(numeric_int4(x));
+		numstr = orgnum =
+			int_to_roman(DatumGetInt32(DirectFunctionCall1(numeric_int4,
+													NumericGetDatum(x))));
 		pfree(x);
 	}
 	else
@@ -4080,8 +4082,12 @@ numeric_to_char(PG_FUNCTION_ARGS)
 			Numeric		b = DatumGetNumeric(DirectFunctionCall1(int4_numeric,
 							Int32GetDatum(Num.multi)));
 
-			x = numeric_power(a, b);
-			val = numeric_mul(value, x);
+			x = DatumGetNumeric(DirectFunctionCall2(numeric_power,
+													NumericGetDatum(a),
+													NumericGetDatum(b)));
+			val = DatumGetNumeric(DirectFunctionCall2(numeric_mul,
+													  NumericGetDatum(value),
+													  NumericGetDatum(x)));
 			pfree(x);
 			pfree(a);
 			pfree(b);
diff --git a/src/backend/utils/adt/numeric.c b/src/backend/utils/adt/numeric.c
index 437bb69b832..bc9a6fe6b31 100644
--- a/src/backend/utils/adt/numeric.c
+++ b/src/backend/utils/adt/numeric.c
@@ -5,7 +5,7 @@
  *
  *	1998 Jan Wieck
  *
- * $Header: /cvsroot/pgsql/src/backend/utils/adt/numeric.c,v 1.32 2000/07/17 03:05:18 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/adt/numeric.c,v 1.33 2000/07/29 03:26:41 tgl Exp $
  *
  * ----------
  */
@@ -351,25 +351,18 @@ numeric(PG_FUNCTION_ARGS)
  * ----------------------------------------------------------------------
  */
 
-
-Numeric
-numeric_abs(Numeric num)
+Datum
+numeric_abs(PG_FUNCTION_ARGS)
 {
+	Numeric		num = PG_GETARG_NUMERIC(0);
 	Numeric		res;
 
-	/* ----------
-	 * Handle NULL
-	 * ----------
-	 */
-	if (num == NULL)
-		return NULL;
-
 	/* ----------
 	 * Handle NaN
 	 * ----------
 	 */
 	if (NUMERIC_IS_NAN(num))
-		return make_result(&const_nan);
+		PG_RETURN_NUMERIC(make_result(&const_nan));
 
 	/* ----------
 	 * Do it the easy way directly on the packed format
@@ -380,28 +373,22 @@ numeric_abs(Numeric num)
 
 	res->n_sign_dscale = NUMERIC_POS | NUMERIC_DSCALE(num);
 
-	return res;
+	PG_RETURN_NUMERIC(res);
 }
 
 
-Numeric
-numeric_uminus(Numeric num)
+Datum
+numeric_uminus(PG_FUNCTION_ARGS)
 {
+	Numeric		num = PG_GETARG_NUMERIC(0);
 	Numeric		res;
 
-	/* ----------
-	 * Handle NULL
-	 * ----------
-	 */
-	if (num == NULL)
-		return NULL;
-
 	/* ----------
 	 * Handle NaN
 	 * ----------
 	 */
 	if (NUMERIC_IS_NAN(num))
-		return make_result(&const_nan);
+		PG_RETURN_NUMERIC(make_result(&const_nan));
 
 	/* ----------
 	 * Do it the easy way directly on the packed format
@@ -425,29 +412,23 @@ numeric_uminus(Numeric num)
 			res->n_sign_dscale = NUMERIC_POS | NUMERIC_DSCALE(num);
 	}
 
-	return res;
+	PG_RETURN_NUMERIC(res);
 }
 
 
-Numeric
-numeric_sign(Numeric num)
+Datum
+numeric_sign(PG_FUNCTION_ARGS)
 {
+	Numeric		num = PG_GETARG_NUMERIC(0);
 	Numeric		res;
 	NumericVar	result;
 
-	/* ----------
-	 * Handle NULL
-	 * ----------
-	 */
-	if (num == NULL)
-		return NULL;
-
 	/* ----------
 	 * Handle NaN
 	 * ----------
 	 */
 	if (NUMERIC_IS_NAN(num))
-		return make_result(&const_nan);
+		PG_RETURN_NUMERIC(make_result(&const_nan));
 
 	init_var(&result);
 
@@ -473,7 +454,7 @@ numeric_sign(Numeric num)
 	res = make_result(&result);
 	free_var(&result);
 
-	return res;
+	PG_RETURN_NUMERIC(res);
 }
 
 
@@ -633,17 +614,15 @@ numeric_trunc(PG_FUNCTION_ARGS)
  *	Return the smallest integer greater than or equal to the argument
  * ----------
  */
-Numeric
-numeric_ceil(Numeric num)
+Datum
+numeric_ceil(PG_FUNCTION_ARGS)
 {
+	Numeric		num = PG_GETARG_NUMERIC(0);
 	Numeric		res;
 	NumericVar	result;
 
-	if (num == NULL)
-		return NULL;
-
 	if (NUMERIC_IS_NAN(num))
-		return make_result(&const_nan);
+		PG_RETURN_NUMERIC(make_result(&const_nan));
 
 	init_var(&result);
 
@@ -655,7 +634,7 @@ numeric_ceil(Numeric num)
 	res = make_result(&result);
 	free_var(&result);
 
-	return res;
+	PG_RETURN_NUMERIC(res);
 }
 
 
@@ -665,17 +644,15 @@ numeric_ceil(Numeric num)
  *	Return the largest integer equal to or less than the argument
  * ----------
  */
-Numeric
-numeric_floor(Numeric num)
+Datum
+numeric_floor(PG_FUNCTION_ARGS)
 {
+	Numeric		num = PG_GETARG_NUMERIC(0);
 	Numeric		res;
 	NumericVar	result;
 
-	if (num == NULL)
-		return NULL;
-
 	if (NUMERIC_IS_NAN(num))
-		return make_result(&const_nan);
+		PG_RETURN_NUMERIC(make_result(&const_nan));
 
 	init_var(&result);
 
@@ -687,7 +664,7 @@ numeric_floor(Numeric num)
 	res = make_result(&result);
 	free_var(&result);
 
-	return res;
+	PG_RETURN_NUMERIC(res);
 }
 
 
@@ -695,203 +672,236 @@ numeric_floor(Numeric num)
  *
  * Comparison functions
  *
+ * Note: btree indexes need these routines not to leak memory; therefore,
+ * be careful to free working copies of toasted datums.  Most places don't
+ * need to be so careful.
  * ----------------------------------------------------------------------
  */
 
 
-int32
-numeric_cmp(Numeric num1, Numeric num2)
+Datum
+numeric_cmp(PG_FUNCTION_ARGS)
 {
+	Numeric		num1 = PG_GETARG_NUMERIC(0);
+	Numeric		num2 = PG_GETARG_NUMERIC(1);
 	int			result;
-	NumericVar	arg1;
-	NumericVar	arg2;
-
-	if (num1 == NULL || num2 == NULL)
-		return (int32) 0;
 
 	if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
-		return (int32) 0;
+		result = 0;
+	else
+	{
+		NumericVar	arg1;
+		NumericVar	arg2;
 
-	init_var(&arg1);
-	init_var(&arg2);
+		init_var(&arg1);
+		init_var(&arg2);
 
-	set_var_from_num(num1, &arg1);
-	set_var_from_num(num2, &arg2);
+		set_var_from_num(num1, &arg1);
+		set_var_from_num(num2, &arg2);
 
-	result = cmp_var(&arg1, &arg2);
+		result = cmp_var(&arg1, &arg2);
 
-	free_var(&arg1);
-	free_var(&arg2);
+		free_var(&arg1);
+		free_var(&arg2);
+	}
+
+	PG_FREE_IF_COPY(num1, 0);
+	PG_FREE_IF_COPY(num2, 1);
 
-	return (int32) ((result == 0) ? 0 : ((result < 0) ? -1 : 1));
+	PG_RETURN_INT32(result);
 }
 
 
-bool
-numeric_eq(Numeric num1, Numeric num2)
+Datum
+numeric_eq(PG_FUNCTION_ARGS)
 {
-	int			result;
-	NumericVar	arg1;
-	NumericVar	arg2;
-
-	if (num1 == NULL || num2 == NULL)
-		return FALSE;
+	Numeric		num1 = PG_GETARG_NUMERIC(0);
+	Numeric		num2 = PG_GETARG_NUMERIC(1);
+	bool		result;
 
 	if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
-		return FALSE;
+		result = false;
+	else
+	{
+		NumericVar	arg1;
+		NumericVar	arg2;
 
-	init_var(&arg1);
-	init_var(&arg2);
+		init_var(&arg1);
+		init_var(&arg2);
 
-	set_var_from_num(num1, &arg1);
-	set_var_from_num(num2, &arg2);
+		set_var_from_num(num1, &arg1);
+		set_var_from_num(num2, &arg2);
 
-	result = cmp_var(&arg1, &arg2);
+		result = cmp_var(&arg1, &arg2) == 0;
 
-	free_var(&arg1);
-	free_var(&arg2);
+		free_var(&arg1);
+		free_var(&arg2);
+	}
 
-	return (result == 0);
-}
+	PG_FREE_IF_COPY(num1, 0);
+	PG_FREE_IF_COPY(num2, 1);
 
+	PG_RETURN_BOOL(result);
+}
 
-bool
-numeric_ne(Numeric num1, Numeric num2)
+Datum
+numeric_ne(PG_FUNCTION_ARGS)
 {
-	int			result;
-	NumericVar	arg1;
-	NumericVar	arg2;
-
-	if (num1 == NULL || num2 == NULL)
-		return FALSE;
+	Numeric		num1 = PG_GETARG_NUMERIC(0);
+	Numeric		num2 = PG_GETARG_NUMERIC(1);
+	bool		result;
 
 	if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
-		return FALSE;
+		result = false;
+	else
+	{
+		NumericVar	arg1;
+		NumericVar	arg2;
 
-	init_var(&arg1);
-	init_var(&arg2);
+		init_var(&arg1);
+		init_var(&arg2);
 
-	set_var_from_num(num1, &arg1);
-	set_var_from_num(num2, &arg2);
+		set_var_from_num(num1, &arg1);
+		set_var_from_num(num2, &arg2);
 
-	result = cmp_var(&arg1, &arg2);
+		result = cmp_var(&arg1, &arg2) != 0;
 
-	free_var(&arg1);
-	free_var(&arg2);
+		free_var(&arg1);
+		free_var(&arg2);
+	}
 
-	return (result != 0);
-}
+	PG_FREE_IF_COPY(num1, 0);
+	PG_FREE_IF_COPY(num2, 1);
 
+	PG_RETURN_BOOL(result);
+}
 
-bool
-numeric_gt(Numeric num1, Numeric num2)
+Datum
+numeric_gt(PG_FUNCTION_ARGS)
 {
-	int			result;
-	NumericVar	arg1;
-	NumericVar	arg2;
-
-	if (num1 == NULL || num2 == NULL)
-		return FALSE;
+	Numeric		num1 = PG_GETARG_NUMERIC(0);
+	Numeric		num2 = PG_GETARG_NUMERIC(1);
+	bool		result;
 
 	if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
-		return FALSE;
+		result = false;
+	else
+	{
+		NumericVar	arg1;
+		NumericVar	arg2;
 
-	init_var(&arg1);
-	init_var(&arg2);
+		init_var(&arg1);
+		init_var(&arg2);
 
-	set_var_from_num(num1, &arg1);
-	set_var_from_num(num2, &arg2);
+		set_var_from_num(num1, &arg1);
+		set_var_from_num(num2, &arg2);
 
-	result = cmp_var(&arg1, &arg2);
+		result = cmp_var(&arg1, &arg2) > 0;
 
-	free_var(&arg1);
-	free_var(&arg2);
+		free_var(&arg1);
+		free_var(&arg2);
+	}
 
-	return (result > 0);
-}
+	PG_FREE_IF_COPY(num1, 0);
+	PG_FREE_IF_COPY(num2, 1);
 
+	PG_RETURN_BOOL(result);
+}
 
-bool
-numeric_ge(Numeric num1, Numeric num2)
+Datum
+numeric_ge(PG_FUNCTION_ARGS)
 {
-	int			result;
-	NumericVar	arg1;
-	NumericVar	arg2;
-
-	if (num1 == NULL || num2 == NULL)
-		return FALSE;
+	Numeric		num1 = PG_GETARG_NUMERIC(0);
+	Numeric		num2 = PG_GETARG_NUMERIC(1);
+	bool		result;
 
 	if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
-		return FALSE;
+		result = false;
+	else
+	{
+		NumericVar	arg1;
+		NumericVar	arg2;
 
-	init_var(&arg1);
-	init_var(&arg2);
+		init_var(&arg1);
+		init_var(&arg2);
 
-	set_var_from_num(num1, &arg1);
-	set_var_from_num(num2, &arg2);
+		set_var_from_num(num1, &arg1);
+		set_var_from_num(num2, &arg2);
 
-	result = cmp_var(&arg1, &arg2);
+		result = cmp_var(&arg1, &arg2) >= 0;
 
-	free_var(&arg1);
-	free_var(&arg2);
+		free_var(&arg1);
+		free_var(&arg2);
+	}
 
-	return (result >= 0);
-}
+	PG_FREE_IF_COPY(num1, 0);
+	PG_FREE_IF_COPY(num2, 1);
 
+	PG_RETURN_BOOL(result);
+}
 
-bool
-numeric_lt(Numeric num1, Numeric num2)
+Datum
+numeric_lt(PG_FUNCTION_ARGS)
 {
-	int			result;
-	NumericVar	arg1;
-	NumericVar	arg2;
-
-	if (num1 == NULL || num2 == NULL)
-		return FALSE;
+	Numeric		num1 = PG_GETARG_NUMERIC(0);
+	Numeric		num2 = PG_GETARG_NUMERIC(1);
+	bool		result;
 
 	if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
-		return FALSE;
+		result = false;
+	else
+	{
+		NumericVar	arg1;
+		NumericVar	arg2;
 
-	init_var(&arg1);
-	init_var(&arg2);
+		init_var(&arg1);
+		init_var(&arg2);
 
-	set_var_from_num(num1, &arg1);
-	set_var_from_num(num2, &arg2);
+		set_var_from_num(num1, &arg1);
+		set_var_from_num(num2, &arg2);
 
-	result = cmp_var(&arg1, &arg2);
+		result = cmp_var(&arg1, &arg2) < 0;
 
-	free_var(&arg1);
-	free_var(&arg2);
+		free_var(&arg1);
+		free_var(&arg2);
+	}
 
-	return (result < 0);
-}
+	PG_FREE_IF_COPY(num1, 0);
+	PG_FREE_IF_COPY(num2, 1);
 
+	PG_RETURN_BOOL(result);
+}
 
-bool
-numeric_le(Numeric num1, Numeric num2)
+Datum
+numeric_le(PG_FUNCTION_ARGS)
 {
-	int			result;
-	NumericVar	arg1;
-	NumericVar	arg2;
-
-	if (num1 == NULL || num2 == NULL)
-		return FALSE;
+	Numeric		num1 = PG_GETARG_NUMERIC(0);
+	Numeric		num2 = PG_GETARG_NUMERIC(1);
+	bool		result;
 
 	if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
-		return FALSE;
+		result = false;
+	else
+	{
+		NumericVar	arg1;
+		NumericVar	arg2;
 
-	init_var(&arg1);
-	init_var(&arg2);
+		init_var(&arg1);
+		init_var(&arg2);
 
-	set_var_from_num(num1, &arg1);
-	set_var_from_num(num2, &arg2);
+		set_var_from_num(num1, &arg1);
+		set_var_from_num(num2, &arg2);
 
-	result = cmp_var(&arg1, &arg2);
+		result = cmp_var(&arg1, &arg2) <= 0;
 
-	free_var(&arg1);
-	free_var(&arg2);
+		free_var(&arg1);
+		free_var(&arg2);
+	}
 
-	return (result <= 0);
+	PG_FREE_IF_COPY(num1, 0);
+	PG_FREE_IF_COPY(num2, 1);
+
+	PG_RETURN_BOOL(result);
 }
 
 
@@ -909,27 +919,22 @@ numeric_le(Numeric num1, Numeric num2)
  *	Add two numerics
  * ----------
  */
-Numeric
-numeric_add(Numeric num1, Numeric num2)
+Datum
+numeric_add(PG_FUNCTION_ARGS)
 {
+	Numeric		num1 = PG_GETARG_NUMERIC(0);
+	Numeric		num2 = PG_GETARG_NUMERIC(1);
 	NumericVar	arg1;
 	NumericVar	arg2;
 	NumericVar	result;
 	Numeric		res;
 
-	/* ----------
-	 * Handle NULL
-	 * ----------
-	 */
-	if (num1 == NULL || num2 == NULL)
-		return NULL;
-
 	/* ----------
 	 * Handle NaN
 	 * ----------
 	 */
 	if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
-		return make_result(&const_nan);
+		PG_RETURN_NUMERIC(make_result(&const_nan));
 
 	/* ----------
 	 * Unpack the values, let add_var() compute the result
@@ -951,7 +956,7 @@ numeric_add(Numeric num1, Numeric num2)
 	free_var(&arg2);
 	free_var(&result);
 
-	return res;
+	PG_RETURN_NUMERIC(res);
 }
 
 
@@ -961,27 +966,22 @@ numeric_add(Numeric num1, Numeric num2)
  *	Subtract one numeric from another
  * ----------
  */
-Numeric
-numeric_sub(Numeric num1, Numeric num2)
+Datum
+numeric_sub(PG_FUNCTION_ARGS)
 {
+	Numeric		num1 = PG_GETARG_NUMERIC(0);
+	Numeric		num2 = PG_GETARG_NUMERIC(1);
 	NumericVar	arg1;
 	NumericVar	arg2;
 	NumericVar	result;
 	Numeric		res;
 
-	/* ----------
-	 * Handle NULL
-	 * ----------
-	 */
-	if (num1 == NULL || num2 == NULL)
-		return NULL;
-
 	/* ----------
 	 * Handle NaN
 	 * ----------
 	 */
 	if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
-		return make_result(&const_nan);
+		PG_RETURN_NUMERIC(make_result(&const_nan));
 
 	/* ----------
 	 * Unpack the two arguments, let sub_var() compute the
@@ -1002,7 +1002,7 @@ numeric_sub(Numeric num1, Numeric num2)
 	free_var(&arg2);
 	free_var(&result);
 
-	return res;
+	PG_RETURN_NUMERIC(res);
 }
 
 
@@ -1012,27 +1012,22 @@ numeric_sub(Numeric num1, Numeric num2)
  *	Calculate the product of two numerics
  * ----------
  */
-Numeric
-numeric_mul(Numeric num1, Numeric num2)
+Datum
+numeric_mul(PG_FUNCTION_ARGS)
 {
+	Numeric		num1 = PG_GETARG_NUMERIC(0);
+	Numeric		num2 = PG_GETARG_NUMERIC(1);
 	NumericVar	arg1;
 	NumericVar	arg2;
 	NumericVar	result;
 	Numeric		res;
 
-	/* ----------
-	 * Handle NULL
-	 * ----------
-	 */
-	if (num1 == NULL || num2 == NULL)
-		return NULL;
-
 	/* ----------
 	 * Handle NaN
 	 * ----------
 	 */
 	if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
-		return make_result(&const_nan);
+		PG_RETURN_NUMERIC(make_result(&const_nan));
 
 	/* ----------
 	 * Unpack the arguments, let mul_var() compute the result
@@ -1063,7 +1058,7 @@ numeric_mul(Numeric num1, Numeric num2)
 	free_var(&arg2);
 	free_var(&result);
 
-	return res;
+	PG_RETURN_NUMERIC(res);
 }
 
 
@@ -1073,28 +1068,23 @@ numeric_mul(Numeric num1, Numeric num2)
  *	Divide one numeric into another
  * ----------
  */
-Numeric
-numeric_div(Numeric num1, Numeric num2)
+Datum
+numeric_div(PG_FUNCTION_ARGS)
 {
+	Numeric		num1 = PG_GETARG_NUMERIC(0);
+	Numeric		num2 = PG_GETARG_NUMERIC(1);
 	NumericVar	arg1;
 	NumericVar	arg2;
 	NumericVar	result;
 	Numeric		res;
 	int			res_dscale;
 
-	/* ----------
-	 * Handle NULL
-	 * ----------
-	 */
-	if (num1 == NULL || num2 == NULL)
-		return NULL;
-
 	/* ----------
 	 * Handle NaN
 	 * ----------
 	 */
 	if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
-		return make_result(&const_nan);
+		PG_RETURN_NUMERIC(make_result(&const_nan));
 
 	/* ----------
 	 * Unpack the arguments
@@ -1144,7 +1134,7 @@ numeric_div(Numeric num1, Numeric num2)
 	free_var(&arg2);
 	free_var(&result);
 
-	return res;
+	PG_RETURN_NUMERIC(res);
 }
 
 
@@ -1154,19 +1144,18 @@ numeric_div(Numeric num1, Numeric num2)
  *	Calculate the modulo of two numerics
  * ----------
  */
-Numeric
-numeric_mod(Numeric num1, Numeric num2)
+Datum
+numeric_mod(PG_FUNCTION_ARGS)
 {
+	Numeric		num1 = PG_GETARG_NUMERIC(0);
+	Numeric		num2 = PG_GETARG_NUMERIC(1);
 	Numeric		res;
 	NumericVar	arg1;
 	NumericVar	arg2;
 	NumericVar	result;
 
-	if (num1 == NULL || num2 == NULL)
-		return NULL;
-
 	if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
-		return make_result(&const_nan);
+		PG_RETURN_NUMERIC(make_result(&const_nan));
 
 	init_var(&arg1);
 	init_var(&arg2);
@@ -1184,7 +1173,7 @@ numeric_mod(Numeric num1, Numeric num2)
 	free_var(&arg2);
 	free_var(&arg1);
 
-	return res;
+	PG_RETURN_NUMERIC(res);
 }
 
 
@@ -1194,25 +1183,19 @@ numeric_mod(Numeric num1, Numeric num2)
  *	Increment a number by one
  * ----------
  */
-Numeric
-numeric_inc(Numeric num)
+Datum
+numeric_inc(PG_FUNCTION_ARGS)
 {
+	Numeric		num = PG_GETARG_NUMERIC(0);
 	NumericVar	arg;
 	Numeric		res;
 
-	/* ----------
-	 * Handle NULL
-	 * ----------
-	 */
-	if (num == NULL)
-		return NULL;
-
 	/* ----------
 	 * Handle NaN
 	 * ----------
 	 */
 	if (NUMERIC_IS_NAN(num))
-		return make_result(&const_nan);
+		PG_RETURN_NUMERIC(make_result(&const_nan));
 
 	/* ----------
 	 * Compute the result and return it
@@ -1227,7 +1210,7 @@ numeric_inc(Numeric num)
 
 	free_var(&arg);
 
-	return res;
+	PG_RETURN_NUMERIC(res);
 }
 
 
@@ -1237,26 +1220,21 @@ numeric_inc(Numeric num)
  *	Return the smaller of two numbers
  * ----------
  */
-Numeric
-numeric_smaller(Numeric num1, Numeric num2)
+Datum
+numeric_smaller(PG_FUNCTION_ARGS)
 {
+	Numeric		num1 = PG_GETARG_NUMERIC(0);
+	Numeric		num2 = PG_GETARG_NUMERIC(1);
 	NumericVar	arg1;
 	NumericVar	arg2;
 	Numeric		res;
 
-	/* ----------
-	 * Handle NULL
-	 * ----------
-	 */
-	if (num1 == NULL || num2 == NULL)
-		return NULL;
-
 	/* ----------
 	 * Handle NaN
 	 * ----------
 	 */
 	if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
-		return make_result(&const_nan);
+		PG_RETURN_NUMERIC(make_result(&const_nan));
 
 	/* ----------
 	 * Unpack the values, and decide which is the smaller one
@@ -1276,7 +1254,7 @@ numeric_smaller(Numeric num1, Numeric num2)
 	free_var(&arg1);
 	free_var(&arg2);
 
-	return res;
+	PG_RETURN_NUMERIC(res);
 }
 
 
@@ -1286,26 +1264,21 @@ numeric_smaller(Numeric num1, Numeric num2)
  *	Return the larger of two numbers
  * ----------
  */
-Numeric
-numeric_larger(Numeric num1, Numeric num2)
+Datum
+numeric_larger(PG_FUNCTION_ARGS)
 {
+	Numeric		num1 = PG_GETARG_NUMERIC(0);
+	Numeric		num2 = PG_GETARG_NUMERIC(1);
 	NumericVar	arg1;
 	NumericVar	arg2;
 	Numeric		res;
 
-	/* ----------
-	 * Handle NULL
-	 * ----------
-	 */
-	if (num1 == NULL || num2 == NULL)
-		return NULL;
-
 	/* ----------
 	 * Handle NaN
 	 * ----------
 	 */
 	if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
-		return make_result(&const_nan);
+		PG_RETURN_NUMERIC(make_result(&const_nan));
 
 	/* ----------
 	 * Unpack the values, and decide which is the larger one
@@ -1325,7 +1298,7 @@ numeric_larger(Numeric num1, Numeric num2)
 	free_var(&arg1);
 	free_var(&arg2);
 
-	return res;
+	PG_RETURN_NUMERIC(res);
 }
 
 
@@ -1343,27 +1316,21 @@ numeric_larger(Numeric num1, Numeric num2)
  *	Compute the square root of a numeric.
  * ----------
  */
-Numeric
-numeric_sqrt(Numeric num)
+Datum
+numeric_sqrt(PG_FUNCTION_ARGS)
 {
+	Numeric		num = PG_GETARG_NUMERIC(0);
 	Numeric		res;
 	NumericVar	arg;
 	NumericVar	result;
 	int			res_dscale;
 
-	/* ----------
-	 * Handle NULL
-	 * ----------
-	 */
-	if (num == NULL)
-		return NULL;
-
 	/* ----------
 	 * Handle NaN
 	 * ----------
 	 */
 	if (NUMERIC_IS_NAN(num))
-		return make_result(&const_nan);
+		PG_RETURN_NUMERIC(make_result(&const_nan));
 
 	/* ----------
 	 * Unpack the argument, determine the scales like for divide,
@@ -1390,7 +1357,7 @@ numeric_sqrt(Numeric num)
 	free_var(&result);
 	free_var(&arg);
 
-	return res;
+	PG_RETURN_NUMERIC(res);
 }
 
 
@@ -1400,27 +1367,21 @@ numeric_sqrt(Numeric num)
  *	Raise e to the power of x
  * ----------
  */
-Numeric
-numeric_exp(Numeric num)
+Datum
+numeric_exp(PG_FUNCTION_ARGS)
 {
+	Numeric		num = PG_GETARG_NUMERIC(0);
 	Numeric		res;
 	NumericVar	arg;
 	NumericVar	result;
 	int			res_dscale;
 
-	/* ----------
-	 * Handle NULL
-	 * ----------
-	 */
-	if (num == NULL)
-		return NULL;
-
 	/* ----------
 	 * Handle NaN
 	 * ----------
 	 */
 	if (NUMERIC_IS_NAN(num))
-		return make_result(&const_nan);
+		PG_RETURN_NUMERIC(make_result(&const_nan));
 
 	/* ----------
 	 * Same procedure like for sqrt().
@@ -1445,7 +1406,7 @@ numeric_exp(Numeric num)
 	free_var(&result);
 	free_var(&arg);
 
-	return res;
+	PG_RETURN_NUMERIC(res);
 }
 
 
@@ -1455,27 +1416,21 @@ numeric_exp(Numeric num)
  *	Compute the natural logarithm of x
  * ----------
  */
-Numeric
-numeric_ln(Numeric num)
+Datum
+numeric_ln(PG_FUNCTION_ARGS)
 {
+	Numeric		num = PG_GETARG_NUMERIC(0);
 	Numeric		res;
 	NumericVar	arg;
 	NumericVar	result;
 	int			res_dscale;
 
-	/* ----------
-	 * Handle NULL
-	 * ----------
-	 */
-	if (num == NULL)
-		return NULL;
-
 	/* ----------
 	 * Handle NaN
 	 * ----------
 	 */
 	if (NUMERIC_IS_NAN(num))
-		return make_result(&const_nan);
+		PG_RETURN_NUMERIC(make_result(&const_nan));
 
 	/* ----------
 	 * Same procedure like for sqrt()
@@ -1500,7 +1455,7 @@ numeric_ln(Numeric num)
 	free_var(&result);
 	free_var(&arg);
 
-	return res;
+	PG_RETURN_NUMERIC(res);
 }
 
 
@@ -1510,28 +1465,23 @@ numeric_ln(Numeric num)
  *	Compute the logarithm of x in a given base
  * ----------
  */
-Numeric
-numeric_log(Numeric num1, Numeric num2)
+Datum
+numeric_log(PG_FUNCTION_ARGS)
 {
+	Numeric		num1 = PG_GETARG_NUMERIC(0);
+	Numeric		num2 = PG_GETARG_NUMERIC(1);
 	Numeric		res;
 	NumericVar	arg1;
 	NumericVar	arg2;
 	NumericVar	result;
 	int			res_dscale;
 
-	/* ----------
-	 * Handle NULL
-	 * ----------
-	 */
-	if (num1 == NULL || num2 == NULL)
-		return NULL;
-
 	/* ----------
 	 * Handle NaN
 	 * ----------
 	 */
 	if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
-		return make_result(&const_nan);
+		PG_RETURN_NUMERIC(make_result(&const_nan));
 
 	/* ----------
 	 * Initialize things and calculate scales
@@ -1563,7 +1513,7 @@ numeric_log(Numeric num1, Numeric num2)
 	free_var(&arg2);
 	free_var(&arg1);
 
-	return res;
+	PG_RETURN_NUMERIC(res);
 }
 
 
@@ -1573,28 +1523,23 @@ numeric_log(Numeric num1, Numeric num2)
  *	Raise m to the power of x
  * ----------
  */
-Numeric
-numeric_power(Numeric num1, Numeric num2)
+Datum
+numeric_power(PG_FUNCTION_ARGS)
 {
+	Numeric		num1 = PG_GETARG_NUMERIC(0);
+	Numeric		num2 = PG_GETARG_NUMERIC(1);
 	Numeric		res;
 	NumericVar	arg1;
 	NumericVar	arg2;
 	NumericVar	result;
 	int			res_dscale;
 
-	/* ----------
-	 * Handle NULL
-	 * ----------
-	 */
-	if (num1 == NULL || num2 == NULL)
-		return NULL;
-
 	/* ----------
 	 * Handle NaN
 	 * ----------
 	 */
 	if (NUMERIC_IS_NAN(num1) || NUMERIC_IS_NAN(num2))
-		return make_result(&const_nan);
+		PG_RETURN_NUMERIC(make_result(&const_nan));
 
 	/* ----------
 	 * Initialize things and calculate scales
@@ -1626,7 +1571,7 @@ numeric_power(Numeric num1, Numeric num2)
 	free_var(&arg2);
 	free_var(&arg1);
 
-	return res;
+	PG_RETURN_NUMERIC(res);
 }
 
 
@@ -1660,16 +1605,15 @@ int4_numeric(PG_FUNCTION_ARGS)
 }
 
 
-int32
-numeric_int4(Numeric num)
+Datum
+numeric_int4(PG_FUNCTION_ARGS)
 {
+	Numeric		num = PG_GETARG_NUMERIC(0);
 	NumericVar	x;
 	char	   *str;
 	Datum		result;
 
-	if (num == NULL)
-		return 0;
-
+	/* XXX would it be better to return NULL? */
 	if (NUMERIC_IS_NAN(num))
 		elog(ERROR, "Cannot convert NaN to int4");
 
@@ -1687,7 +1631,7 @@ numeric_int4(Numeric num)
 	result = DirectFunctionCall1(int4in, CStringGetDatum(str));
 	pfree(str);
 
-	return result;
+	PG_RETURN_DATUM(result);
 }
 
 
@@ -1712,16 +1656,15 @@ int8_numeric(PG_FUNCTION_ARGS)
 }
 
 
-int64 *
-numeric_int8(Numeric num)
+Datum
+numeric_int8(PG_FUNCTION_ARGS)
 {
+	Numeric		num = PG_GETARG_NUMERIC(0);
 	NumericVar	x;
 	char	   *str;
 	Datum		result;
 
-	if (num == NULL)
-		return NULL;
-
+	/* XXX would it be better to return NULL? */
 	if (NUMERIC_IS_NAN(num))
 		elog(ERROR, "Cannot convert NaN to int8");
 
@@ -1737,10 +1680,9 @@ numeric_int8(Numeric num)
 	free_var(&x);
 
 	result = DirectFunctionCall1(int8in, CStringGetDatum(str));
-
 	pfree(str);
 
-	return (int64 *) (result);
+	PG_RETURN_DATUM(result);
 }
 
 
@@ -1795,20 +1737,18 @@ numeric_int2(PG_FUNCTION_ARGS)
 }
 
 
-Numeric
-float8_numeric(float64 val)
+Datum
+float8_numeric(PG_FUNCTION_ARGS)
 {
+	float8		val = PG_GETARG_FLOAT8(0);
 	Numeric		res;
 	NumericVar	result;
 	char		buf[DBL_DIG + 100];
 
-	if (val == NULL)
-		return NULL;
-
-	if (isnan(*val))
-		return make_result(&const_nan);
+	if (isnan(val))
+		PG_RETURN_NUMERIC(make_result(&const_nan));
 
-	sprintf(buf, "%.*g", DBL_DIG, *val);
+	sprintf(buf, "%.*g", DBL_DIG, val);
 
 	init_var(&result);
 
@@ -1817,49 +1757,41 @@ float8_numeric(float64 val)
 
 	free_var(&result);
 
-	return res;
+	PG_RETURN_NUMERIC(res);
 }
 
 
-float64
-numeric_float8(Numeric num)
+Datum
+numeric_float8(PG_FUNCTION_ARGS)
 {
+	Numeric		num = PG_GETARG_NUMERIC(0);
 	char	   *tmp;
 	float64		result;
 
-	if (num == NULL)
-		return NULL;
-
 	if (NUMERIC_IS_NAN(num))
-	{
-		result = (float64) palloc(sizeof(float64data));
-		*result = NAN;
-		return result;
-	}
+		PG_RETURN_FLOAT8(NAN);
 
 	tmp = DatumGetCString(DirectFunctionCall1(numeric_out,
 											  NumericGetDatum(num)));
 	result = float8in(tmp);
 	pfree(tmp);
 
-	return result;
+	PG_RETURN_POINTER(result);
 }
 
 
-Numeric
-float4_numeric(float32 val)
+Datum
+float4_numeric(PG_FUNCTION_ARGS)
 {
+	float4		val = PG_GETARG_FLOAT4(0);
 	Numeric		res;
 	NumericVar	result;
 	char		buf[FLT_DIG + 100];
 
-	if (val == NULL)
-		return NULL;
-
-	if (isnan(*val))
-		return make_result(&const_nan);
+	if (isnan(val))
+		PG_RETURN_NUMERIC(make_result(&const_nan));
 
-	sprintf(buf, "%.*g", FLT_DIG, *val);
+	sprintf(buf, "%.*g", FLT_DIG, val);
 
 	init_var(&result);
 
@@ -1868,32 +1800,26 @@ float4_numeric(float32 val)
 
 	free_var(&result);
 
-	return res;
+	PG_RETURN_NUMERIC(res);
 }
 
 
-float32
-numeric_float4(Numeric num)
+Datum
+numeric_float4(PG_FUNCTION_ARGS)
 {
+	Numeric		num = PG_GETARG_NUMERIC(0);
 	char	   *tmp;
 	float32		result;
 
-	if (num == NULL)
-		return NULL;
-
 	if (NUMERIC_IS_NAN(num))
-	{
-		result = (float32) palloc(sizeof(float32data));
-		*result = NAN;
-		return result;
-	}
+		PG_RETURN_FLOAT4(NAN);
 
 	tmp = DatumGetCString(DirectFunctionCall1(numeric_out,
 											  NumericGetDatum(num)));
 	result = float4in(tmp);
 	pfree(tmp);
 
-	return result;
+	PG_RETURN_POINTER(result);
 }
 
 
@@ -1915,7 +1841,7 @@ do_numeric_accum(ArrayType *transarray, Numeric newval)
 {
 	Datum	   *transdatums;
 	int			ndatums;
-	Numeric		N,
+	Datum		N,
 				sumX,
 				sumX2;
 	ArrayType  *result;
@@ -1926,17 +1852,21 @@ do_numeric_accum(ArrayType *transarray, Numeric newval)
 					  &transdatums, &ndatums);
 	if (ndatums != 3)
 		elog(ERROR, "do_numeric_accum: expected 3-element numeric array");
-	N = DatumGetNumeric(transdatums[0]);
-	sumX = DatumGetNumeric(transdatums[1]);
-	sumX2 = DatumGetNumeric(transdatums[2]);
-
-	N = numeric_inc(N);
-	sumX = numeric_add(sumX, newval);
-	sumX2 = numeric_add(sumX2, numeric_mul(newval, newval));
-
-	transdatums[0] = NumericGetDatum(N);
-	transdatums[1] = NumericGetDatum(sumX);
-	transdatums[2] = NumericGetDatum(sumX2);
+	N = transdatums[0];
+	sumX = transdatums[1];
+	sumX2 = transdatums[2];
+
+	N = DirectFunctionCall1(numeric_inc, N);
+	sumX = DirectFunctionCall2(numeric_add, sumX,
+							   NumericGetDatum(newval));
+	sumX2 = DirectFunctionCall2(numeric_add, sumX2,
+								DirectFunctionCall2(numeric_mul,
+													NumericGetDatum(newval),
+													NumericGetDatum(newval)));
+
+	transdatums[0] = N;
+	transdatums[1] = sumX;
+	transdatums[2] = sumX2;
 
 	result = construct_array(transdatums, 3,
 							 false, -1, 'i');
@@ -2018,7 +1948,9 @@ numeric_avg(PG_FUNCTION_ARGS)
 	if (N->varlen == NUMERIC_HDRSZ)
 		PG_RETURN_NULL();
 
-	PG_RETURN_NUMERIC(numeric_div(sumX, N));
+	PG_RETURN_DATUM(DirectFunctionCall2(numeric_div,
+										NumericGetDatum(sumX),
+										NumericGetDatum(N)));
 }
 
 Datum
@@ -2172,8 +2104,8 @@ numeric_stddev(PG_FUNCTION_ARGS)
 Datum
 int2_sum(PG_FUNCTION_ARGS)
 {
-	Numeric		oldsum,
-				newval;
+	Numeric		oldsum;
+	Datum		newval;
 
 	if (PG_ARGISNULL(0))
 	{
@@ -2181,9 +2113,8 @@ int2_sum(PG_FUNCTION_ARGS)
 		if (PG_ARGISNULL(1))
 			PG_RETURN_NULL();	/* still no non-null */
 		/* This is the first non-null input. */
-		newval = DatumGetNumeric(DirectFunctionCall1(int2_numeric,
-													 PG_GETARG_DATUM(1)));
-		PG_RETURN_NUMERIC(newval);
+		newval = DirectFunctionCall1(int2_numeric, PG_GETARG_DATUM(1));
+		PG_RETURN_DATUM(newval);
 	}
 
 	oldsum = PG_GETARG_NUMERIC(0);
@@ -2193,17 +2124,17 @@ int2_sum(PG_FUNCTION_ARGS)
 		PG_RETURN_NUMERIC(oldsum);
 
 	/* OK to do the addition. */
-	newval = DatumGetNumeric(DirectFunctionCall1(int2_numeric,
-												 PG_GETARG_DATUM(1)));
+	newval = DirectFunctionCall1(int2_numeric, PG_GETARG_DATUM(1));
 
-	PG_RETURN_NUMERIC(numeric_add(oldsum, newval));
+	PG_RETURN_DATUM(DirectFunctionCall2(numeric_add,
+										NumericGetDatum(oldsum), newval));
 }
 
 Datum
 int4_sum(PG_FUNCTION_ARGS)
 {
-	Numeric		oldsum,
-				newval;
+	Numeric		oldsum;
+	Datum		newval;
 
 	if (PG_ARGISNULL(0))
 	{
@@ -2211,9 +2142,8 @@ int4_sum(PG_FUNCTION_ARGS)
 		if (PG_ARGISNULL(1))
 			PG_RETURN_NULL();	/* still no non-null */
 		/* This is the first non-null input. */
-		newval = DatumGetNumeric(DirectFunctionCall1(int4_numeric,
-													 PG_GETARG_DATUM(1)));
-		PG_RETURN_NUMERIC(newval);
+		newval = DirectFunctionCall1(int4_numeric, PG_GETARG_DATUM(1));
+		PG_RETURN_DATUM(newval);
 	}
 
 	oldsum = PG_GETARG_NUMERIC(0);
@@ -2223,17 +2153,17 @@ int4_sum(PG_FUNCTION_ARGS)
 		PG_RETURN_NUMERIC(oldsum);
 
 	/* OK to do the addition. */
-	newval = DatumGetNumeric(DirectFunctionCall1(int4_numeric,
-												 PG_GETARG_DATUM(1)));
+	newval = DirectFunctionCall1(int4_numeric, PG_GETARG_DATUM(1));
 
-	PG_RETURN_NUMERIC(numeric_add(oldsum, newval));
+	PG_RETURN_DATUM(DirectFunctionCall2(numeric_add,
+										NumericGetDatum(oldsum), newval));
 }
 
 Datum
 int8_sum(PG_FUNCTION_ARGS)
 {
-	Numeric		oldsum,
-				newval;
+	Numeric		oldsum;
+	Datum		newval;
 
 	if (PG_ARGISNULL(0))
 	{
@@ -2241,9 +2171,8 @@ int8_sum(PG_FUNCTION_ARGS)
 		if (PG_ARGISNULL(1))
 			PG_RETURN_NULL();	/* still no non-null */
 		/* This is the first non-null input. */
-		newval = DatumGetNumeric(DirectFunctionCall1(int8_numeric,
-													 PG_GETARG_DATUM(1)));
-		PG_RETURN_NUMERIC(newval);
+		newval = DirectFunctionCall1(int8_numeric, PG_GETARG_DATUM(1));
+		PG_RETURN_DATUM(newval);
 	}
 
 	oldsum = PG_GETARG_NUMERIC(0);
@@ -2253,10 +2182,10 @@ int8_sum(PG_FUNCTION_ARGS)
 		PG_RETURN_NUMERIC(oldsum);
 
 	/* OK to do the addition. */
-	newval = DatumGetNumeric(DirectFunctionCall1(int8_numeric,
-												 PG_GETARG_DATUM(1)));
+	newval = DirectFunctionCall1(int8_numeric, PG_GETARG_DATUM(1));
 
-	PG_RETURN_NUMERIC(numeric_add(oldsum, newval));
+	PG_RETURN_DATUM(DirectFunctionCall2(numeric_add,
+										NumericGetDatum(oldsum), newval));
 }
 
 
diff --git a/src/backend/utils/adt/selfuncs.c b/src/backend/utils/adt/selfuncs.c
index 3d82487f7e7..04d9d9f6a9e 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.75 2000/07/06 05:48:11 tgl Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/utils/adt/selfuncs.c,v 1.76 2000/07/29 03:26:42 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -818,7 +818,8 @@ convert_numeric_to_scalar(Datum value, Oid typid)
 		case FLOAT8OID:
 			return (double) DatumGetFloat8(value);
 		case NUMERICOID:
-			return (double) (*numeric_float8((Numeric) DatumGetPointer(value)));
+			return (double) DatumGetFloat8(DirectFunctionCall1(numeric_float8,
+															   value));
 		case OIDOID:
 		case REGPROCOID:
 			/* we can treat OIDs as integers... */
@@ -1825,11 +1826,13 @@ string_lessthan(const char *str1, const char *str2, Oid datatype)
 			break;
 
 		case BPCHAROID:
-			result = bpcharlt((char *) datum1, (char *) datum2);
+			result = DatumGetBool(DirectFunctionCall2(bpcharlt,
+													  datum1, datum2));
 			break;
 
 		case VARCHAROID:
-			result = varcharlt((char *) datum1, (char *) datum2);
+			result = DatumGetBool(DirectFunctionCall2(varcharlt,
+													  datum1, datum2));
 			break;
 
 		case NAMEOID:
diff --git a/src/backend/utils/adt/varchar.c b/src/backend/utils/adt/varchar.c
index 58b24f339e1..804ab8c5caa 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.68 2000/07/07 21:12:50 tgl Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/utils/adt/varchar.c,v 1.69 2000/07/29 03:26:42 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -260,19 +260,20 @@ char_bpchar(PG_FUNCTION_ARGS)
 /* bpchar_name()
  * Converts a bpchar() type to a NameData type.
  */
-NameData   *
-bpchar_name(char *s)
+Datum
+bpchar_name(PG_FUNCTION_ARGS)
 {
-	NameData   *result;
+	BpChar	   *s = PG_GETARG_BPCHAR_P(0);
+	Name		result;
 	int			len;
 
-	if (s == NULL)
-		return NULL;
-
 	len = VARSIZE(s) - VARHDRSZ;
+
+	/* Truncate to max length for a Name */
 	if (len >= NAMEDATALEN)
 		len = NAMEDATALEN-1;
 
+	/* Remove trailing blanks */
 	while (len > 0)
 	{
 		if (*(VARDATA(s) + len - 1) != ' ')
@@ -280,49 +281,36 @@ bpchar_name(char *s)
 		len--;
 	}
 
-#ifdef STRINGDEBUG
-	printf("bpchar- convert string length %d (%d) ->%d\n",
-		   VARSIZE(s) - VARHDRSZ, VARSIZE(s), len);
-#endif
-
 	result = (NameData *) palloc(NAMEDATALEN);
 	memcpy(NameStr(*result), VARDATA(s), len);
 
-	/* now null pad to full length... */
+	/* Now null pad to full length... */
 	while (len < NAMEDATALEN)
 	{
 		*(NameStr(*result) + len) = '\0';
 		len++;
 	}
 
-	return result;
-}	/* bpchar_name() */
+	PG_RETURN_NAME(result);
+}
 
 /* name_bpchar()
  * Converts a NameData type to a bpchar type.
  */
-char *
-name_bpchar(NameData *s)
+Datum
+name_bpchar(PG_FUNCTION_ARGS)
 {
-	char	   *result;
+	Name		s = PG_GETARG_NAME(0);
+	BpChar	   *result;
 	int			len;
 
-	if (s == NULL)
-		return NULL;
-
 	len = strlen(NameStr(*s));
-
-#ifdef STRINGDEBUG
-	printf("bpchar- convert string length %d (%d) ->%d\n",
-		   VARSIZE(s) - VARHDRSZ, VARSIZE(s), len);
-#endif
-
-	result = (char *) palloc(VARHDRSZ + len);
+	result = (BpChar *) palloc(VARHDRSZ + len);
 	memcpy(VARDATA(result), NameStr(*s), len);
 	VARATT_SIZEP(result) = len + VARHDRSZ;
 
-	return result;
-}	/* name_bpchar() */
+	PG_RETURN_BPCHAR_P(result);
+}
 
 
 /*****************************************************************************
@@ -446,13 +434,9 @@ _varchar(PG_FUNCTION_ARGS)
 	return array_map(&locfcinfo, VARCHAROID, VARCHAROID);
 }
 
-
-/*****************************************************************************
- *	Comparison Functions used for bpchar
- *****************************************************************************/
-
+/* "True" length (not counting trailing blanks) of a BpChar */
 static int
-bcTruelen(char *arg)
+bcTruelen(BpChar *arg)
 {
 	char	   *s = VARDATA(arg);
 	int			i;
@@ -467,19 +451,16 @@ bcTruelen(char *arg)
 	return i + 1;
 }
 
-int32
-bpcharlen(char *arg)
+Datum
+bpcharlen(PG_FUNCTION_ARGS)
 {
+	BpChar	   *arg = PG_GETARG_BPCHAR_P(0);
 #ifdef MULTIBYTE
 	unsigned char *s;
 	int			len,
 				l,
 				wl;
 
-#endif
-	if (!PointerIsValid(arg))
-		elog(ERROR, "Bad (null) char() external representation");
-#ifdef MULTIBYTE
 	l = VARSIZE(arg) - VARHDRSZ;
 	len = 0;
 	s = VARDATA(arg);
@@ -490,134 +471,160 @@ bpcharlen(char *arg)
 		s += wl;
 		len++;
 	}
-	return (len);
+	PG_RETURN_INT32(len);
 #else
-	return (VARSIZE(arg) - VARHDRSZ);
+	PG_RETURN_INT32(VARSIZE(arg) - VARHDRSZ);
 #endif
 }
 
-int32
-bpcharoctetlen(char *arg)
+Datum
+bpcharoctetlen(PG_FUNCTION_ARGS)
 {
-	if (!PointerIsValid(arg))
-		elog(ERROR, "Bad (null) char() external representation");
+	BpChar	   *arg = PG_GETARG_BPCHAR_P(0);
 
-	return (VARSIZE(arg) - VARHDRSZ);
+	PG_RETURN_INT32(VARSIZE(arg) - VARHDRSZ);
 }
 
-bool
-bpchareq(char *arg1, char *arg2)
+
+/*****************************************************************************
+ *	Comparison Functions used for bpchar
+ *
+ * Note: btree indexes need these routines not to leak memory; therefore,
+ * be careful to free working copies of toasted datums.  Most places don't
+ * need to be so careful.
+ *****************************************************************************/
+
+Datum
+bpchareq(PG_FUNCTION_ARGS)
 {
+	BpChar	   *arg1 = PG_GETARG_BPCHAR_P(0);
+	BpChar	   *arg2 = PG_GETARG_BPCHAR_P(1);
 	int			len1,
 				len2;
+	bool		result;
 
-	if (arg1 == NULL || arg2 == NULL)
-		return (bool) 0;
 	len1 = bcTruelen(arg1);
 	len2 = bcTruelen(arg2);
 
 	if (len1 != len2)
-		return 0;
+		result = false;
+	else
+		result = (strncmp(VARDATA(arg1), VARDATA(arg2), len1) == 0);
 
-	return strncmp(VARDATA(arg1), VARDATA(arg2), len1) == 0;
+	PG_FREE_IF_COPY(arg1, 0);
+	PG_FREE_IF_COPY(arg2, 1);
+
+	PG_RETURN_BOOL(result);
 }
 
-bool
-bpcharne(char *arg1, char *arg2)
+Datum
+bpcharne(PG_FUNCTION_ARGS)
 {
+	BpChar	   *arg1 = PG_GETARG_BPCHAR_P(0);
+	BpChar	   *arg2 = PG_GETARG_BPCHAR_P(1);
 	int			len1,
 				len2;
+	bool		result;
 
-	if (arg1 == NULL || arg2 == NULL)
-		return (bool) 0;
 	len1 = bcTruelen(arg1);
 	len2 = bcTruelen(arg2);
 
 	if (len1 != len2)
-		return 1;
+		result = true;
+	else
+		result = (strncmp(VARDATA(arg1), VARDATA(arg2), len1) != 0);
+
+	PG_FREE_IF_COPY(arg1, 0);
+	PG_FREE_IF_COPY(arg2, 1);
 
-	return strncmp(VARDATA(arg1), VARDATA(arg2), len1) != 0;
+	PG_RETURN_BOOL(result);
 }
 
-bool
-bpcharlt(char *arg1, char *arg2)
+Datum
+bpcharlt(PG_FUNCTION_ARGS)
 {
+	BpChar	   *arg1 = PG_GETARG_BPCHAR_P(0);
+	BpChar	   *arg2 = PG_GETARG_BPCHAR_P(1);
 	int			len1,
 				len2;
 	int			cmp;
 
-	if (arg1 == NULL || arg2 == NULL)
-		return (bool) 0;
 	len1 = bcTruelen(arg1);
 	len2 = bcTruelen(arg2);
 
 	cmp = varstr_cmp(VARDATA(arg1), len1, VARDATA(arg2), len2);
-	if (cmp == 0)
-		return len1 < len2;
-	else
-		return cmp < 0;
+
+	PG_FREE_IF_COPY(arg1, 0);
+	PG_FREE_IF_COPY(arg2, 1);
+
+	PG_RETURN_BOOL(cmp < 0);
 }
 
-bool
-bpcharle(char *arg1, char *arg2)
+Datum
+bpcharle(PG_FUNCTION_ARGS)
 {
+	BpChar	   *arg1 = PG_GETARG_BPCHAR_P(0);
+	BpChar	   *arg2 = PG_GETARG_BPCHAR_P(1);
 	int			len1,
 				len2;
 	int			cmp;
 
-	if (arg1 == NULL || arg2 == NULL)
-		return (bool) 0;
 	len1 = bcTruelen(arg1);
 	len2 = bcTruelen(arg2);
 
 	cmp = varstr_cmp(VARDATA(arg1), len1, VARDATA(arg2), len2);
-	if (0 == cmp)
-		return (bool) (len1 <= len2 ? 1 : 0);
-	else
-		return (bool) (cmp <= 0);
+
+	PG_FREE_IF_COPY(arg1, 0);
+	PG_FREE_IF_COPY(arg2, 1);
+
+	PG_RETURN_BOOL(cmp <= 0);
 }
 
-bool
-bpchargt(char *arg1, char *arg2)
+Datum
+bpchargt(PG_FUNCTION_ARGS)
 {
+	BpChar	   *arg1 = PG_GETARG_BPCHAR_P(0);
+	BpChar	   *arg2 = PG_GETARG_BPCHAR_P(1);
 	int			len1,
 				len2;
 	int			cmp;
 
-	if (arg1 == NULL || arg2 == NULL)
-		return (bool) 0;
 	len1 = bcTruelen(arg1);
 	len2 = bcTruelen(arg2);
 
 	cmp = varstr_cmp(VARDATA(arg1), len1, VARDATA(arg2), len2);
-	if (cmp == 0)
-		return len1 > len2;
-	else
-		return cmp > 0;
+
+	PG_FREE_IF_COPY(arg1, 0);
+	PG_FREE_IF_COPY(arg2, 1);
+
+	PG_RETURN_BOOL(cmp > 0);
 }
 
-bool
-bpcharge(char *arg1, char *arg2)
+Datum
+bpcharge(PG_FUNCTION_ARGS)
 {
+	BpChar	   *arg1 = PG_GETARG_BPCHAR_P(0);
+	BpChar	   *arg2 = PG_GETARG_BPCHAR_P(1);
 	int			len1,
 				len2;
 	int			cmp;
 
-	if (arg1 == NULL || arg2 == NULL)
-		return (bool) 0;
 	len1 = bcTruelen(arg1);
 	len2 = bcTruelen(arg2);
 
 	cmp = varstr_cmp(VARDATA(arg1), len1, VARDATA(arg2), len2);
-	if (0 == cmp)
-		return (bool) (len1 >= len2 ? 1 : 0);
-	else
-		return (bool) (cmp >= 0);
+
+	PG_FREE_IF_COPY(arg1, 0);
+	PG_FREE_IF_COPY(arg2, 1);
+
+	PG_RETURN_BOOL(cmp >= 0);
 }
 
-int32
-bpcharcmp(char *arg1, char *arg2)
+Datum
+bpcharcmp(PG_FUNCTION_ARGS)
 {
+	BpChar	   *arg1 = PG_GETARG_BPCHAR_P(0);
+	BpChar	   *arg2 = PG_GETARG_BPCHAR_P(1);
 	int			len1,
 				len2;
 	int			cmp;
@@ -626,30 +633,46 @@ bpcharcmp(char *arg1, char *arg2)
 	len2 = bcTruelen(arg2);
 
 	cmp = varstr_cmp(VARDATA(arg1), len1, VARDATA(arg2), len2);
-	if ((0 == cmp) && (len1 != len2))
-		return (int32) (len1 < len2 ? -1 : 1);
-	else
-		return cmp;
+
+	PG_FREE_IF_COPY(arg1, 0);
+	PG_FREE_IF_COPY(arg2, 1);
+
+	PG_RETURN_INT32(cmp);
 }
 
+
+/*
+ * bpchar needs a specialized hash function because we want to ignore
+ * trailing blanks in comparisons.  (varchar can use plain hashvarlena.)
+ */
+Datum
+hashbpchar(PG_FUNCTION_ARGS)
+{
+	BpChar	   *key = PG_GETARG_BPCHAR_P(0);
+	char	   *keydata;
+	int			keylen;
+
+	keydata = VARDATA(key);
+	keylen = bcTruelen(key);
+
+	return hash_any(keydata, keylen);
+}
+
+
 /*****************************************************************************
- *	Comparison Functions used for varchar
+ *	Functions used for varchar
  *****************************************************************************/
 
-int32
-varcharlen(char *arg)
+Datum
+varcharlen(PG_FUNCTION_ARGS)
 {
+	VarChar	   *arg = PG_GETARG_VARCHAR_P(0);
 #ifdef MULTIBYTE
 	unsigned char *s;
 	int			len,
 				l,
 				wl;
 
-#endif
-	if (!PointerIsValid(arg))
-		elog(ERROR, "Bad (null) varchar() external representation");
-
-#ifdef MULTIBYTE
 	len = 0;
 	s = VARDATA(arg);
 	l = VARSIZE(arg) - VARHDRSZ;
@@ -660,161 +683,171 @@ varcharlen(char *arg)
 		s += wl;
 		len++;
 	}
-	return (len);
+	PG_RETURN_INT32(len);
 #else
-	return VARSIZE(arg) - VARHDRSZ;
+	PG_RETURN_INT32(VARSIZE(arg) - VARHDRSZ);
 #endif
 }
 
-int32
-varcharoctetlen(char *arg)
+Datum
+varcharoctetlen(PG_FUNCTION_ARGS)
 {
-	if (!PointerIsValid(arg))
-		elog(ERROR, "Bad (null) varchar() external representation");
-	return VARSIZE(arg) - VARHDRSZ;
+	VarChar	   *arg = PG_GETARG_VARCHAR_P(0);
+
+	PG_RETURN_INT32(VARSIZE(arg) - VARHDRSZ);
 }
 
-bool
-varchareq(char *arg1, char *arg2)
+
+/*****************************************************************************
+ *	Comparison Functions used for varchar
+ *
+ * Note: btree indexes need these routines not to leak memory; therefore,
+ * be careful to free working copies of toasted datums.  Most places don't
+ * need to be so careful.
+ *****************************************************************************/
+
+Datum
+varchareq(PG_FUNCTION_ARGS)
 {
+	VarChar	   *arg1 = PG_GETARG_VARCHAR_P(0);
+	VarChar	   *arg2 = PG_GETARG_VARCHAR_P(1);
 	int			len1,
 				len2;
-
-	if (arg1 == NULL || arg2 == NULL)
-		return (bool) 0;
+	bool		result;
 
 	len1 = VARSIZE(arg1) - VARHDRSZ;
 	len2 = VARSIZE(arg2) - VARHDRSZ;
 
 	if (len1 != len2)
-		return 0;
+		result = false;
+	else
+		result = (strncmp(VARDATA(arg1), VARDATA(arg2), len1) == 0);
 
-	return strncmp(VARDATA(arg1), VARDATA(arg2), len1) == 0;
+	PG_FREE_IF_COPY(arg1, 0);
+	PG_FREE_IF_COPY(arg2, 1);
+
+	PG_RETURN_BOOL(result);
 }
 
-bool
-varcharne(char *arg1, char *arg2)
+Datum
+varcharne(PG_FUNCTION_ARGS)
 {
+	VarChar	   *arg1 = PG_GETARG_VARCHAR_P(0);
+	VarChar	   *arg2 = PG_GETARG_VARCHAR_P(1);
 	int			len1,
 				len2;
+	bool		result;
 
-	if (arg1 == NULL || arg2 == NULL)
-		return (bool) 0;
 	len1 = VARSIZE(arg1) - VARHDRSZ;
 	len2 = VARSIZE(arg2) - VARHDRSZ;
 
 	if (len1 != len2)
-		return 1;
+		result = true;
+	else
+		result = (strncmp(VARDATA(arg1), VARDATA(arg2), len1) != 0);
+
+	PG_FREE_IF_COPY(arg1, 0);
+	PG_FREE_IF_COPY(arg2, 1);
 
-	return strncmp(VARDATA(arg1), VARDATA(arg2), len1) != 0;
+	PG_RETURN_BOOL(result);
 }
 
-bool
-varcharlt(char *arg1, char *arg2)
+Datum
+varcharlt(PG_FUNCTION_ARGS)
 {
+	VarChar	   *arg1 = PG_GETARG_VARCHAR_P(0);
+	VarChar	   *arg2 = PG_GETARG_VARCHAR_P(1);
 	int			len1,
 				len2;
 	int			cmp;
 
-	if (arg1 == NULL || arg2 == NULL)
-		return (bool) 0;
 	len1 = VARSIZE(arg1) - VARHDRSZ;
 	len2 = VARSIZE(arg2) - VARHDRSZ;
 
 	cmp = varstr_cmp(VARDATA(arg1), len1, VARDATA(arg2), len2);
-	if (cmp == 0)
-		return len1 < len2;
-	else
-		return cmp < 0;
+
+	PG_FREE_IF_COPY(arg1, 0);
+	PG_FREE_IF_COPY(arg2, 1);
+
+	PG_RETURN_BOOL(cmp < 0);
 }
 
-bool
-varcharle(char *arg1, char *arg2)
+Datum
+varcharle(PG_FUNCTION_ARGS)
 {
+	VarChar	   *arg1 = PG_GETARG_VARCHAR_P(0);
+	VarChar	   *arg2 = PG_GETARG_VARCHAR_P(1);
 	int			len1,
 				len2;
 	int			cmp;
 
-	if (arg1 == NULL || arg2 == NULL)
-		return (bool) 0;
 	len1 = VARSIZE(arg1) - VARHDRSZ;
 	len2 = VARSIZE(arg2) - VARHDRSZ;
 
 	cmp = varstr_cmp(VARDATA(arg1), len1, VARDATA(arg2), len2);
-	if (0 == cmp)
-		return (bool) (len1 <= len2 ? 1 : 0);
-	else
-		return (bool) (cmp <= 0);
+
+	PG_FREE_IF_COPY(arg1, 0);
+	PG_FREE_IF_COPY(arg2, 1);
+
+	PG_RETURN_BOOL(cmp <= 0);
 }
 
-bool
-varchargt(char *arg1, char *arg2)
+Datum
+varchargt(PG_FUNCTION_ARGS)
 {
+	VarChar	   *arg1 = PG_GETARG_VARCHAR_P(0);
+	VarChar	   *arg2 = PG_GETARG_VARCHAR_P(1);
 	int			len1,
 				len2;
 	int			cmp;
 
-	if (arg1 == NULL || arg2 == NULL)
-		return (bool) 0;
 	len1 = VARSIZE(arg1) - VARHDRSZ;
 	len2 = VARSIZE(arg2) - VARHDRSZ;
 
 	cmp = varstr_cmp(VARDATA(arg1), len1, VARDATA(arg2), len2);
-	if (cmp == 0)
-		return len1 > len2;
-	else
-		return cmp > 0;
+
+	PG_FREE_IF_COPY(arg1, 0);
+	PG_FREE_IF_COPY(arg2, 1);
+
+	PG_RETURN_BOOL(cmp > 0);
 }
 
-bool
-varcharge(char *arg1, char *arg2)
+Datum
+varcharge(PG_FUNCTION_ARGS)
 {
+	VarChar	   *arg1 = PG_GETARG_VARCHAR_P(0);
+	VarChar	   *arg2 = PG_GETARG_VARCHAR_P(1);
 	int			len1,
 				len2;
 	int			cmp;
 
-	if (arg1 == NULL || arg2 == NULL)
-		return (bool) 0;
 	len1 = VARSIZE(arg1) - VARHDRSZ;
 	len2 = VARSIZE(arg2) - VARHDRSZ;
 
 	cmp = varstr_cmp(VARDATA(arg1), len1, VARDATA(arg2), len2);
-	if (0 == cmp)
-		return (bool) (len1 >= len2 ? 1 : 0);
-	else
-		return (bool) (cmp >= 0);
 
+	PG_FREE_IF_COPY(arg1, 0);
+	PG_FREE_IF_COPY(arg2, 1);
+
+	PG_RETURN_BOOL(cmp >= 0);
 }
 
-int32
-varcharcmp(char *arg1, char *arg2)
+Datum
+varcharcmp(PG_FUNCTION_ARGS)
 {
+	VarChar	   *arg1 = PG_GETARG_VARCHAR_P(0);
+	VarChar	   *arg2 = PG_GETARG_VARCHAR_P(1);
 	int			len1,
 				len2;
 	int			cmp;
 
 	len1 = VARSIZE(arg1) - VARHDRSZ;
 	len2 = VARSIZE(arg2) - VARHDRSZ;
-	cmp = varstr_cmp(VARDATA(arg1), len1, VARDATA(arg2), len2);
-	if ((0 == cmp) && (len1 != len2))
-		return (int32) (len1 < len2 ? -1 : 1);
-	else
-		return (int32) (cmp);
-}
 
-/*
- * bpchar needs a specialized hash function because we want to ignore
- * trailing blanks in comparisons.  (varchar can use plain hashvarlena.)
- */
-Datum
-hashbpchar(PG_FUNCTION_ARGS)
-{
-	BpChar	   *key = PG_GETARG_BPCHAR_P(0);
-	char	   *keydata;
-	int			keylen;
+	cmp = varstr_cmp(VARDATA(arg1), len1, VARDATA(arg2), len2);
 
-	keydata = VARDATA(key);
-	keylen = bcTruelen((char *) key);
+	PG_FREE_IF_COPY(arg1, 0);
+	PG_FREE_IF_COPY(arg2, 1);
 
-	return hash_any(keydata, keylen);
+	PG_RETURN_INT32(cmp);
 }
diff --git a/src/backend/utils/adt/varlena.c b/src/backend/utils/adt/varlena.c
index b5380a8c52a..b075bf91112 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.64 2000/07/12 02:37:19 tgl Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/utils/adt/varlena.c,v 1.65 2000/07/29 03:26:42 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -41,18 +41,17 @@ static int	text_cmp(text *arg1, text *arg2);
  *				The input is scaned twice.
  *				The error checking of input is minimal.
  */
-bytea *
-byteain(char *inputText)
+Datum
+byteain(PG_FUNCTION_ARGS)
 {
+	char	   *inputText = PG_GETARG_CSTRING(0);
 	char	   *tp;
 	char	   *rp;
 	int			byte;
 	bytea	   *result;
 
-	if (inputText == NULL)
-		elog(ERROR, "Bad input string for type bytea");
-
 	for (byte = 0, tp = inputText; *tp != '\0'; byte++)
+	{
 		if (*tp++ == '\\')
 		{
 			if (*tp == '\\')
@@ -62,12 +61,16 @@ byteain(char *inputText)
 					 !isdigit((int) *tp++))
 				elog(ERROR, "Bad input string for type bytea");
 		}
-	tp = inputText;
+	}
+
 	byte += VARHDRSZ;
 	result = (bytea *) palloc(byte);
-	result->vl_len = byte;		/* varlena? */
+	result->vl_len = byte;		/* set varlena length */
+
+	tp = inputText;
 	rp = result->vl_dat;
 	while (*tp != '\0')
+	{
 		if (*tp != '\\' || *++tp == '\\')
 			*rp++ = *tp++;
 		else
@@ -78,7 +81,9 @@ byteain(char *inputText)
 			byte <<= 3;
 			*rp++ = byte + VAL(*tp++);
 		}
-	return result;
+	}
+
+	PG_RETURN_BYTEA_P(result);
 }
 
 /*
@@ -89,9 +94,10 @@ byteain(char *inputText)
  *
  *		NULL vlena should be an error--returning string with NULL for now.
  */
-char *
-byteaout(bytea *vlena)
+Datum
+byteaout(PG_FUNCTION_ARGS)
 {
+	bytea	   *vlena = PG_GETARG_BYTEA_P(0);
 	char	   *result;
 	char	   *vp;
 	char	   *rp;
@@ -99,47 +105,42 @@ byteaout(bytea *vlena)
 	int			i;
 	int			len;
 
-	if (vlena == NULL)
-	{
-		result = (char *) palloc(2);
-		result[0] = '-';
-		result[1] = '\0';
-		return result;
-	}
-	vp = vlena->vl_dat;
 	len = 1;					/* empty string has 1 char */
+	vp = vlena->vl_dat;
 	for (i = vlena->vl_len - VARHDRSZ; i != 0; i--, vp++)
+	{
 		if (*vp == '\\')
 			len += 2;
 		else if (isascii((int) *vp) && isprint((int) *vp))
 			len++;
 		else
-			len += VARHDRSZ;
+			len += 4;
+	}
 	rp = result = (char *) palloc(len);
 	vp = vlena->vl_dat;
-	for (i = vlena->vl_len - VARHDRSZ; i != 0; i--)
+	for (i = vlena->vl_len - VARHDRSZ; i != 0; i--, vp++)
+	{
 		if (*vp == '\\')
 		{
-			vp++;
 			*rp++ = '\\';
 			*rp++ = '\\';
 		}
 		else if (isascii((int) *vp) && isprint((int) *vp))
-			*rp++ = *vp++;
+			*rp++ = *vp;
 		else
 		{
-			val = *vp++;
-			*rp = '\\';
-			rp += 3;
-			*rp-- = DIG(val & 07);
+			val = *vp;
+			rp[0] = '\\';
+			rp[3] = DIG(val & 07);
 			val >>= 3;
-			*rp-- = DIG(val & 07);
+			rp[2] = DIG(val & 07);
 			val >>= 3;
-			*rp = DIG(val & 03);
-			rp += 3;
+			rp[1] = DIG(val & 03);
+			rp += 4;
 		}
+	}
 	*rp = '\0';
-	return result;
+	PG_RETURN_CSTRING(result);
 }
 
 
@@ -663,13 +664,12 @@ text_smaller(PG_FUNCTION_ARGS)
  * get the number of bytes contained in an instance of type 'bytea'
  *-------------------------------------------------------------
  */
-int32
-byteaoctetlen(bytea *v)
+Datum
+byteaoctetlen(PG_FUNCTION_ARGS)
 {
-	if (!PointerIsValid(v))
-		return 0;
+	bytea	   *v = PG_GETARG_BYTEA_P(0);
 
-	return VARSIZE(v) - VARHDRSZ;
+	PG_RETURN_INT32(VARSIZE(v) - VARHDRSZ);
 }
 
 /*-------------------------------------------------------------
diff --git a/src/include/catalog/pg_proc.h b/src/include/catalog/pg_proc.h
index 56654c9f329..9f4ed9f87bb 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.149 2000/07/28 05:07:42 tgl Exp $
+ * $Id: pg_proc.h,v 1.150 2000/07/29 03:26:43 tgl Exp $
  *
  * NOTES
  *	  The script catalog/genbki.sh reads this file and generates .bki
@@ -101,9 +101,9 @@ DATA(insert OID = 1242 (  boolin		   PGUID 12 f t t t 1 f 16 "0" 100 0 0  100  b
 DESCR("(internal)");
 DATA(insert OID = 1243 (  boolout		   PGUID 12 f t t t 1 f 23 "0" 100 0 0 100  boolout - ));
 DESCR("(internal)");
-DATA(insert OID = 1244 (  byteain		   PGUID 11 f t t t 1 f 17 "0" 100 0 0 100  byteain - ));
+DATA(insert OID = 1244 (  byteain		   PGUID 12 f t t t 1 f 17 "0" 100 0 0 100  byteain - ));
 DESCR("(internal)");
-DATA(insert OID =  31 (  byteaout		   PGUID 11 f t t t 1 f 23 "0" 100 0 0 100  byteaout - ));
+DATA(insert OID =  31 (  byteaout		   PGUID 12 f t t t 1 f 23 "0" 100 0 0 100  byteaout - ));
 DESCR("(internal)");
 DATA(insert OID = 1245 (  charin		   PGUID 12 f t t t 1 f 18 "0" 100 0 0 100  charin - ));
 DESCR("(internal)");
@@ -786,9 +786,9 @@ DATA(insert OID =  406 (  text			   PGUID 12 f t t t 1 f	25 "19" 100 0 0 100 nam
 DESCR("convert name to text");
 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 - ));
+DATA(insert OID =  408 (  bpchar		   PGUID 12 f t t t 1 f 1042 "19" 100 0 0 100 name_bpchar - ));
 DESCR("convert name to char()");
-DATA(insert OID =  409 (  name			   PGUID 11 f t t t 1 f	19 "1042" 100 0 0 100	bpchar_name - ));
+DATA(insert OID =  409 (  name			   PGUID 12 f t t t 1 f	19 "1042" 100 0 0 100	bpchar_name - ));
 DESCR("convert char() to name");
 
 DATA(insert OID =  438 (  hashcostestimate PGUID 12 f t f t 7 f 0 "0 0 0 0 0 0 0" 100 0 0 100  hashcostestimate - ));
@@ -943,7 +943,7 @@ DESCR("equal");
 DATA(insert OID = 717 (  int4eqoid		   PGUID 12 f t t t 2 f 16 "23 26" 100 0 0 100  int4eqoid - ));
 DESCR("equal");
 
-DATA(insert OID = 720 (  octet_length	   PGUID 11 f t t t 1 f 23 "17" 100 0 0 100  byteaoctetlen - ));
+DATA(insert OID = 720 (  octet_length	   PGUID 12 f t t t 1 f 23 "17" 100 0 0 100  byteaoctetlen - ));
 DESCR("");
 DATA(insert OID = 721 (  get_byte		   PGUID 12 f t t t 2 f 23 "17 23" 100 0 0 100  byteaGetByte - ));
 DESCR("");
@@ -1293,33 +1293,33 @@ DATA(insert OID = 1046 (  varcharin		   PGUID 12 f t t t 3 f 1043 "0 26 23" 100
 DESCR("(internal)");
 DATA(insert OID = 1047 (  varcharout	   PGUID 12 f t t t 1 f 23 "0" 100 0 0 100  varcharout - ));
 DESCR("(internal)");
-DATA(insert OID = 1048 (  bpchareq		   PGUID 11 f t t t 2 f 16 "1042 1042" 100 0 0 100  bpchareq - ));
+DATA(insert OID = 1048 (  bpchareq		   PGUID 12 f t t t 2 f 16 "1042 1042" 100 0 0 100  bpchareq - ));
 DESCR("equal");
-DATA(insert OID = 1049 (  bpcharlt		   PGUID 11 f t t t 2 f 16 "1042 1042" 100 0 0 100  bpcharlt - ));
+DATA(insert OID = 1049 (  bpcharlt		   PGUID 12 f t t t 2 f 16 "1042 1042" 100 0 0 100  bpcharlt - ));
 DESCR("less-than");
-DATA(insert OID = 1050 (  bpcharle		   PGUID 11 f t t t 2 f 16 "1042 1042" 100 0 0 100  bpcharle - ));
+DATA(insert OID = 1050 (  bpcharle		   PGUID 12 f t t t 2 f 16 "1042 1042" 100 0 0 100  bpcharle - ));
 DESCR("less-than-or-equal");
-DATA(insert OID = 1051 (  bpchargt		   PGUID 11 f t t t 2 f 16 "1042 1042" 100 0 0 100  bpchargt - ));
+DATA(insert OID = 1051 (  bpchargt		   PGUID 12 f t t t 2 f 16 "1042 1042" 100 0 0 100  bpchargt - ));
 DESCR("greater-than");
-DATA(insert OID = 1052 (  bpcharge		   PGUID 11 f t t t 2 f 16 "1042 1042" 100 0 0 100  bpcharge - ));
+DATA(insert OID = 1052 (  bpcharge		   PGUID 12 f t t t 2 f 16 "1042 1042" 100 0 0 100  bpcharge - ));
 DESCR("greater-than-or-equal");
-DATA(insert OID = 1053 (  bpcharne		   PGUID 11 f t t t 2 f 16 "1042 1042" 100 0 0 100  bpcharne - ));
+DATA(insert OID = 1053 (  bpcharne		   PGUID 12 f t t t 2 f 16 "1042 1042" 100 0 0 100  bpcharne - ));
 DESCR("not equal");
-DATA(insert OID = 1070 (  varchareq		   PGUID 11 f t t t 2 f 16 "1043 1043" 100 0 0 100  varchareq - ));
+DATA(insert OID = 1070 (  varchareq		   PGUID 12 f t t t 2 f 16 "1043 1043" 100 0 0 100  varchareq - ));
 DESCR("equal");
-DATA(insert OID = 1071 (  varcharlt		   PGUID 11 f t t t 2 f 16 "1043 1043" 100 0 0 100  varcharlt - ));
+DATA(insert OID = 1071 (  varcharlt		   PGUID 12 f t t t 2 f 16 "1043 1043" 100 0 0 100  varcharlt - ));
 DESCR("less-than");
-DATA(insert OID = 1072 (  varcharle		   PGUID 11 f t t t 2 f 16 "1043 1043" 100 0 0 100  varcharle - ));
+DATA(insert OID = 1072 (  varcharle		   PGUID 12 f t t t 2 f 16 "1043 1043" 100 0 0 100  varcharle - ));
 DESCR("less-than-or-equal");
-DATA(insert OID = 1073 (  varchargt		   PGUID 11 f t t t 2 f 16 "1043 1043" 100 0 0 100  varchargt - ));
+DATA(insert OID = 1073 (  varchargt		   PGUID 12 f t t t 2 f 16 "1043 1043" 100 0 0 100  varchargt - ));
 DESCR("greater-than");
-DATA(insert OID = 1074 (  varcharge		   PGUID 11 f t t t 2 f 16 "1043 1043" 100 0 0 100  varcharge - ));
+DATA(insert OID = 1074 (  varcharge		   PGUID 12 f t t t 2 f 16 "1043 1043" 100 0 0 100  varcharge - ));
 DESCR("greater-than-or-equal");
-DATA(insert OID = 1075 (  varcharne		   PGUID 11 f t t t 2 f 16 "1043 1043" 100 0 0 100  varcharne - ));
+DATA(insert OID = 1075 (  varcharne		   PGUID 12 f t t t 2 f 16 "1043 1043" 100 0 0 100  varcharne - ));
 DESCR("not equal");
-DATA(insert OID = 1078 (  bpcharcmp		   PGUID 11 f t t t 2 f 23 "1042 1042" 100 0 0 100  bpcharcmp - ));
+DATA(insert OID = 1078 (  bpcharcmp		   PGUID 12 f t t t 2 f 23 "1042 1042" 100 0 0 100  bpcharcmp - ));
 DESCR("less-equal-greater");
-DATA(insert OID = 1079 (  varcharcmp	   PGUID 11 f t t t 2 f 23 "1043 1043" 100 0 0 100  varcharcmp - ));
+DATA(insert OID = 1079 (  varcharcmp	   PGUID 12 f t t t 2 f 23 "1043 1043" 100 0 0 100  varcharcmp - ));
 DESCR("less-equal-greater");
 DATA(insert OID = 1080 (  hashbpchar	   PGUID 12 f t t t 1 f 23 "1042" 100 0 0 100  hashbpchar - ));
 DESCR("hash");
@@ -1591,9 +1591,9 @@ DESCR("convert timestamp to time");
 
 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 - ));
+DATA(insert OID = 1318 (  length			 PGUID 12 f t t t 1 f   23 "1042" 100 0 0 100  bpcharlen - ));
 DESCR("character length");
-DATA(insert OID = 1319 (  length			 PGUID 11 f t t t 1 f   23 "1043" 100 0 0 100  varcharlen - ));
+DATA(insert OID = 1319 (  length			 PGUID 12 f t t t 1 f   23 "1043" 100 0 0 100  varcharlen - ));
 DESCR("character length");
 
 DATA(insert OID = 1326 (  interval_div		 PGUID 12 f t f t 2 f 1186 "1186 701" 100 0 0 100  interval_div - ));
@@ -1661,16 +1661,16 @@ DATA(insert OID = 1370 (  interval			 PGUID 12 f t f t 1 f 1186 "1083" 100 0 0 1
 DESCR("convert time to interval");
 DATA(insert OID = 1371 (  date				 PGUID 14 f t t t 1 f 1082 "1082" 100 0 0 100  "select $1" - ));
 DESCR("convert (noop)");
-DATA(insert OID = 1372 (  char_length		 PGUID 11 f t t t 1 f   23   "1042" 100 0 0 100  bpcharlen - ));
+DATA(insert OID = 1372 (  char_length		 PGUID 12 f t t t 1 f   23   "1042" 100 0 0 100  bpcharlen - ));
 DESCR("character length");
-DATA(insert OID = 1373 (  char_length		 PGUID 11 f t t t 1 f   23   "1043" 100 0 0 100  varcharlen - ));
+DATA(insert OID = 1373 (  char_length		 PGUID 12 f t t t 1 f   23   "1043" 100 0 0 100  varcharlen - ));
 DESCR("character length");
 
 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 - ));
+DATA(insert OID = 1375 (  octet_length			 PGUID 12 f t t t 1 f   23   "1042" 100 0 0 100  bpcharoctetlen - ));
 DESCR("octet length");
-DATA(insert OID = 1376 (  octet_length			 PGUID 11 f t t t 1 f   23   "1043" 100 0 0 100  varcharoctetlen - ));
+DATA(insert OID = 1376 (  octet_length			 PGUID 12 f t t t 1 f   23   "1043" 100 0 0 100  varcharoctetlen - ));
 DESCR("octet length");
 
 DATA(insert OID = 1377 (  time_larger	   PGUID 12 f t t t 2 f 1083 "1083 1083" 100 0 0 100	time_larger - ));
@@ -2313,11 +2313,11 @@ DATA(insert OID = 1702 ( numeric_out			PGUID 12 f t t t 1 f 23 "0" 100 0 0 100
 DESCR("(internal)");
 DATA(insert OID = 1703 ( numeric				PGUID 12 f t t t 2 f 1700 "1700 23" 100 0 0 100  numeric - ));
 DESCR("adjust numeric to typmod precision/scale");
-DATA(insert OID = 1704 ( numeric_abs			PGUID 11 f t t t 1 f 1700 "1700" 100 0 0 100	numeric_abs - ));
+DATA(insert OID = 1704 ( numeric_abs			PGUID 12 f t t t 1 f 1700 "1700" 100 0 0 100	numeric_abs - ));
 DESCR("absolute value");
-DATA(insert OID = 1705 ( abs					PGUID 11 f t t t 1 f 1700 "1700" 100 0 0 100	numeric_abs - ));
+DATA(insert OID = 1705 ( abs					PGUID 12 f t t t 1 f 1700 "1700" 100 0 0 100	numeric_abs - ));
 DESCR("absolute value");
-DATA(insert OID = 1706 ( sign					PGUID 11 f t t t 1 f 1700 "1700" 100 0 0 100	numeric_sign - ));
+DATA(insert OID = 1706 ( sign					PGUID 12 f t t t 1 f 1700 "1700" 100 0 0 100	numeric_sign - ));
 DESCR("sign of value");
 DATA(insert OID = 1707 ( round					PGUID 12 f t t t 2 f 1700 "1700 23" 100 0 0 100  numeric_round - ));
 DESCR("value rounded to 'scale'");
@@ -2327,79 +2327,79 @@ DATA(insert OID = 1709 ( trunc					PGUID 12 f t t t 2 f 1700 "1700 23" 100 0 0 1
 DESCR("value truncated to 'scale'");
 DATA(insert OID = 1710 ( trunc					PGUID 14 f t t t 1 f 1700 "1700" 100 0 0 100	"select trunc($1,0)" - ));
 DESCR("value truncated to 'scale' of zero");
-DATA(insert OID = 1711 ( ceil					PGUID 11 f t t t 1 f 1700 "1700" 100 0 0 100	numeric_ceil - ));
+DATA(insert OID = 1711 ( ceil					PGUID 12 f t t t 1 f 1700 "1700" 100 0 0 100	numeric_ceil - ));
 DESCR("smallest integer >= value");
-DATA(insert OID = 1712 ( floor					PGUID 11 f t t t 1 f 1700 "1700" 100 0 0 100	numeric_floor - ));
+DATA(insert OID = 1712 ( floor					PGUID 12 f t t t 1 f 1700 "1700" 100 0 0 100	numeric_floor - ));
 DESCR("largest integer <= value");
-DATA(insert OID = 1718 ( numeric_eq				PGUID 11 f t t t 2 f 16 "1700 1700" 100 0 0 100  numeric_eq - ));
+DATA(insert OID = 1718 ( numeric_eq				PGUID 12 f t t t 2 f 16 "1700 1700" 100 0 0 100  numeric_eq - ));
 DESCR("equal");
-DATA(insert OID = 1719 ( numeric_ne				PGUID 11 f t t t 2 f 16 "1700 1700" 100 0 0 100  numeric_ne - ));
+DATA(insert OID = 1719 ( numeric_ne				PGUID 12 f t t t 2 f 16 "1700 1700" 100 0 0 100  numeric_ne - ));
 DESCR("not equal");
-DATA(insert OID = 1720 ( numeric_gt				PGUID 11 f t t t 2 f 16 "1700 1700" 100 0 0 100  numeric_gt - ));
+DATA(insert OID = 1720 ( numeric_gt				PGUID 12 f t t t 2 f 16 "1700 1700" 100 0 0 100  numeric_gt - ));
 DESCR("greater-than");
-DATA(insert OID = 1721 ( numeric_ge				PGUID 11 f t t t 2 f 16 "1700 1700" 100 0 0 100  numeric_ge - ));
+DATA(insert OID = 1721 ( numeric_ge				PGUID 12 f t t t 2 f 16 "1700 1700" 100 0 0 100  numeric_ge - ));
 DESCR("greater-than-or-equal");
-DATA(insert OID = 1722 ( numeric_lt				PGUID 11 f t t t 2 f 16 "1700 1700" 100 0 0 100  numeric_lt - ));
+DATA(insert OID = 1722 ( numeric_lt				PGUID 12 f t t t 2 f 16 "1700 1700" 100 0 0 100  numeric_lt - ));
 DESCR("lower-than");
-DATA(insert OID = 1723 ( numeric_le				PGUID 11 f t t t 2 f 16 "1700 1700" 100 0 0 100  numeric_le - ));
+DATA(insert OID = 1723 ( numeric_le				PGUID 12 f t t t 2 f 16 "1700 1700" 100 0 0 100  numeric_le - ));
 DESCR("lower-than-or-equal");
-DATA(insert OID = 1724 ( numeric_add			PGUID 11 f t t t 2 f 1700 "1700 1700" 100 0 0 100  numeric_add - ));
+DATA(insert OID = 1724 ( numeric_add			PGUID 12 f t t t 2 f 1700 "1700 1700" 100 0 0 100  numeric_add - ));
 DESCR("addition");
-DATA(insert OID = 1725 ( numeric_sub			PGUID 11 f t t t 2 f 1700 "1700 1700" 100 0 0 100  numeric_sub - ));
+DATA(insert OID = 1725 ( numeric_sub			PGUID 12 f t t t 2 f 1700 "1700 1700" 100 0 0 100  numeric_sub - ));
 DESCR("subtract");
-DATA(insert OID = 1726 ( numeric_mul			PGUID 11 f t t t 2 f 1700 "1700 1700" 100 0 0 100  numeric_mul - ));
+DATA(insert OID = 1726 ( numeric_mul			PGUID 12 f t t t 2 f 1700 "1700 1700" 100 0 0 100  numeric_mul - ));
 DESCR("multiply");
-DATA(insert OID = 1727 ( numeric_div			PGUID 11 f t t t 2 f 1700 "1700 1700" 100 0 0 100  numeric_div - ));
+DATA(insert OID = 1727 ( numeric_div			PGUID 12 f t t t 2 f 1700 "1700 1700" 100 0 0 100  numeric_div - ));
 DESCR("divide");
-DATA(insert OID = 1728 ( mod					PGUID 11 f t t t 2 f 1700 "1700 1700" 100 0 0 100  numeric_mod - ));
+DATA(insert OID = 1728 ( mod					PGUID 12 f t t t 2 f 1700 "1700 1700" 100 0 0 100  numeric_mod - ));
 DESCR("modulus");
-DATA(insert OID = 1729 ( numeric_mod			PGUID 11 f t t t 2 f 1700 "1700 1700" 100 0 0 100  numeric_mod - ));
+DATA(insert OID = 1729 ( numeric_mod			PGUID 12 f t t t 2 f 1700 "1700 1700" 100 0 0 100  numeric_mod - ));
 DESCR("modulus");
-DATA(insert OID = 1730 ( sqrt					PGUID 11 f t t t 1 f 1700 "1700" 100 0 0 100	numeric_sqrt - ));
+DATA(insert OID = 1730 ( sqrt					PGUID 12 f t t t 1 f 1700 "1700" 100 0 0 100	numeric_sqrt - ));
 DESCR("square root");
-DATA(insert OID = 1731 ( numeric_sqrt			PGUID 11 f t t t 1 f 1700 "1700" 100 0 0 100	numeric_sqrt - ));
+DATA(insert OID = 1731 ( numeric_sqrt			PGUID 12 f t t t 1 f 1700 "1700" 100 0 0 100	numeric_sqrt - ));
 DESCR("square root");
-DATA(insert OID = 1732 ( exp					PGUID 11 f t t t 1 f 1700 "1700" 100 0 0 100	numeric_exp - ));
+DATA(insert OID = 1732 ( exp					PGUID 12 f t t t 1 f 1700 "1700" 100 0 0 100	numeric_exp - ));
 DESCR("e raised to the power of n");
-DATA(insert OID = 1733 ( numeric_exp			PGUID 11 f t t t 1 f 1700 "1700" 100 0 0 100	numeric_exp - ));
+DATA(insert OID = 1733 ( numeric_exp			PGUID 12 f t t t 1 f 1700 "1700" 100 0 0 100	numeric_exp - ));
 DESCR("e raised to the power of n");
-DATA(insert OID = 1734 ( ln						PGUID 11 f t t t 1 f 1700 "1700" 100 0 0 100	numeric_ln - ));
+DATA(insert OID = 1734 ( ln						PGUID 12 f t t t 1 f 1700 "1700" 100 0 0 100	numeric_ln - ));
 DESCR("natural logarithm of n");
-DATA(insert OID = 1735 ( numeric_ln				PGUID 11 f t t t 1 f 1700 "1700" 100 0 0 100	numeric_ln - ));
+DATA(insert OID = 1735 ( numeric_ln				PGUID 12 f t t t 1 f 1700 "1700" 100 0 0 100	numeric_ln - ));
 DESCR("natural logarithm of n");
-DATA(insert OID = 1736 ( log					PGUID 11 f t t t 2 f 1700 "1700 1700" 100 0 0 100  numeric_log - ));
+DATA(insert OID = 1736 ( log					PGUID 12 f t t t 2 f 1700 "1700 1700" 100 0 0 100  numeric_log - ));
 DESCR("logarithm base m of n");
-DATA(insert OID = 1737 ( numeric_log			PGUID 11 f t t t 2 f 1700 "1700 1700" 100 0 0 100  numeric_log - ));
+DATA(insert OID = 1737 ( numeric_log			PGUID 12 f t t t 2 f 1700 "1700 1700" 100 0 0 100  numeric_log - ));
 DESCR("logarithm base m of n");
-DATA(insert OID = 1738 ( pow					PGUID 11 f t t t 2 f 1700 "1700 1700" 100 0 0 100  numeric_power - ));
+DATA(insert OID = 1738 ( pow					PGUID 12 f t t t 2 f 1700 "1700 1700" 100 0 0 100  numeric_power - ));
 DESCR("m raised to the power of n");
-DATA(insert OID = 1739 ( numeric_power			PGUID 11 f t t t 2 f 1700 "1700 1700" 100 0 0 100  numeric_power - ));
+DATA(insert OID = 1739 ( numeric_power			PGUID 12 f t t t 2 f 1700 "1700 1700" 100 0 0 100  numeric_power - ));
 DESCR("m raised to the power of n");
 DATA(insert OID = 1740 ( numeric				PGUID 12 f t t t 1 f 1700 "23" 100 0 0 100  int4_numeric - ));
 DESCR("(internal)");
 DATA(insert OID = 1741 ( log					PGUID 14 f t t t 1 f 1700 "1700" 100 0 0 100	"select log(10, $1)" - ));
 DESCR("logarithm base 10 of n");
-DATA(insert OID = 1742 ( numeric				PGUID 11 f t t t 1 f 1700 "700" 100 0 0 100  float4_numeric - ));
+DATA(insert OID = 1742 ( numeric				PGUID 12 f t t t 1 f 1700 "700" 100 0 0 100  float4_numeric - ));
 DESCR("(internal)");
-DATA(insert OID = 1743 ( numeric				PGUID 11 f t t t 1 f 1700 "701" 100 0 0 100  float8_numeric - ));
+DATA(insert OID = 1743 ( numeric				PGUID 12 f t t t 1 f 1700 "701" 100 0 0 100  float8_numeric - ));
 DESCR("(internal)");
-DATA(insert OID = 1744 ( int4					PGUID 11 f t t t 1 f 23 "1700" 100 0 0 100  numeric_int4 - ));
+DATA(insert OID = 1744 ( int4					PGUID 12 f t t t 1 f 23 "1700" 100 0 0 100  numeric_int4 - ));
 DESCR("(internal)");
-DATA(insert OID = 1745 ( float4					PGUID 11 f t t t 1 f 700 "1700" 100 0 0 100  numeric_float4 - ));
+DATA(insert OID = 1745 ( float4					PGUID 12 f t t t 1 f 700 "1700" 100 0 0 100  numeric_float4 - ));
 DESCR("(internal)");
-DATA(insert OID = 1746 ( float8					PGUID 11 f t t t 1 f 701 "1700" 100 0 0 100  numeric_float8 - ));
+DATA(insert OID = 1746 ( float8					PGUID 12 f t t t 1 f 701 "1700" 100 0 0 100  numeric_float8 - ));
 DESCR("(internal)");
-DATA(insert OID = 1764 ( numeric_inc			PGUID 11 f t t t 1 f 1700 "1700" 100 0 0 100	numeric_inc - ));
+DATA(insert OID = 1764 ( numeric_inc			PGUID 12 f t t t 1 f 1700 "1700" 100 0 0 100	numeric_inc - ));
 DESCR("increment by one");
-DATA(insert OID = 1766 ( numeric_smaller		PGUID 11 f t t t 2 f 1700 "1700 1700" 100 0 0 100  numeric_smaller - ));
+DATA(insert OID = 1766 ( numeric_smaller		PGUID 12 f t t t 2 f 1700 "1700 1700" 100 0 0 100  numeric_smaller - ));
 DESCR("smaller of two numbers");
-DATA(insert OID = 1767 ( numeric_larger			PGUID 11 f t t t 2 f 1700 "1700 1700" 100 0 0 100  numeric_larger - ));
+DATA(insert OID = 1767 ( numeric_larger			PGUID 12 f t t t 2 f 1700 "1700 1700" 100 0 0 100  numeric_larger - ));
 DESCR("larger of two numbers");
-DATA(insert OID = 1769 ( numeric_cmp			PGUID 11 f t t t 2 f 23 "1700 1700" 100 0 0 100  numeric_cmp - ));
+DATA(insert OID = 1769 ( numeric_cmp			PGUID 12 f t t t 2 f 23 "1700 1700" 100 0 0 100  numeric_cmp - ));
 DESCR("compare two numbers");
-DATA(insert OID = 1771 ( numeric_uminus			PGUID 11 f t t t 1 f 1700 "1700" 100 0 0 100	numeric_uminus - ));
+DATA(insert OID = 1771 ( numeric_uminus			PGUID 12 f t t t 1 f 1700 "1700" 100 0 0 100	numeric_uminus - ));
 DESCR("negate");
-DATA(insert OID = 1779 ( int8					PGUID 11 f t t t 1 f 20 "1700" 100 0 0 100  numeric_int8 - ));
+DATA(insert OID = 1779 ( int8					PGUID 12 f t t t 1 f 20 "1700" 100 0 0 100  numeric_int8 - ));
 DESCR("(internal)");
 DATA(insert OID = 1781 ( numeric				PGUID 12 f t t t 1 f 1700 "20" 100 0 0 100  int8_numeric - ));
 DESCR("(internal)");
diff --git a/src/include/catalog/pg_type.h b/src/include/catalog/pg_type.h
index d14f9287e24..04457d7296e 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.93 2000/07/22 03:34:28 tgl Exp $
+ * $Id: pg_type.h,v 1.94 2000/07/29 03:26:43 tgl Exp $
  *
  * NOTES
  *	  the genbki.sh script reads this file and generates .bki
@@ -174,7 +174,7 @@ DATA(insert OID = 16 (	bool	   PGUID  1   1 t b t \054 0   0 boolin boolout bool
 DESCR("boolean, 'true'/'false'");
 #define BOOLOID			16
 
-DATA(insert OID = 17 (	bytea	   PGUID -1  -1 f b t \054 0  0 byteain byteaout byteain byteaout i p _null_ ));
+DATA(insert OID = 17 (	bytea	   PGUID -1  -1 f b t \054 0  0 byteain byteaout byteain byteaout i x _null_ ));
 DESCR("variable-length string, binary values escaped");
 #define BYTEAOID		17
 
@@ -368,10 +368,10 @@ DATA(insert OID = 1034 (  _aclitem	 PGUID -1 -1 f b t \054 0 1033 array_in array
 DATA(insert OID = 1040 (  _macaddr	 PGUID -1 -1 f b t \054 0  829 array_in array_out array_in array_out i x _null_ ));
 DATA(insert OID = 1041 (  _inet    PGUID -1 -1 f b t \054 0  869 array_in array_out array_in array_out i x _null_ ));
 DATA(insert OID = 651  (  _cidr    PGUID -1 -1 f b t \054 0  650 array_in array_out array_in array_out i x _null_ ));
-DATA(insert OID = 1042 ( bpchar		 PGUID -1  -1 f b t \054 0	0 bpcharin bpcharout bpcharin bpcharout i p _null_ ));
+DATA(insert OID = 1042 ( bpchar		 PGUID -1  -1 f b t \054 0	0 bpcharin bpcharout bpcharin bpcharout i x _null_ ));
 DESCR("char(length), blank-padded string, fixed storage length");
 #define BPCHAROID		1042
-DATA(insert OID = 1043 ( varchar	 PGUID -1  -1 f b t \054 0	0 varcharin varcharout varcharin varcharout i p _null_ ));
+DATA(insert OID = 1043 ( varchar	 PGUID -1  -1 f b t \054 0	0 varcharin varcharout varcharin varcharout i x _null_ ));
 DESCR("varchar(length), non-blank-padded string, variable storage length");
 #define VARCHAROID		1043
 
@@ -417,7 +417,7 @@ DESCR("variable-length string, stored compressed");
 #define LZTEXTOID	  1625
 
 /* OIDS 1700 - 1799 */
-DATA(insert OID = 1700 ( numeric	   PGUID -1  -1 f b t \054 0  0 numeric_in numeric_out numeric_in numeric_out i p _null_ ));
+DATA(insert OID = 1700 ( numeric	   PGUID -1  -1 f b t \054 0  0 numeric_in numeric_out numeric_in numeric_out i m _null_ ));
 DESCR("numeric(precision, decimal), arbitrary precision number");
 #define NUMERICOID		1700
 
diff --git a/src/include/fmgr.h b/src/include/fmgr.h
index 03d13e3d4ed..274f8f959d8 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.8 2000/07/12 02:37:25 tgl Exp $
+ * $Id: fmgr.h,v 1.9 2000/07/29 03:26:47 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -185,6 +185,7 @@ extern struct varlena * pg_detoast_datum_copy(struct varlena * datum);
 
 /* Macros for returning results of standard types */
 
+#define PG_RETURN_DATUM(x)   return (x)
 #define PG_RETURN_INT32(x)   return Int32GetDatum(x)
 #define PG_RETURN_UINT32(x)  return UInt32GetDatum(x)
 #define PG_RETURN_INT16(x)   return Int16GetDatum(x)
diff --git a/src/include/utils/builtins.h b/src/include/utils/builtins.h
index db772d6ecf2..9b19a3ae85c 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.124 2000/07/17 03:05:32 tgl Exp $
+ * $Id: builtins.h,v 1.125 2000/07/29 03:26:51 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -400,32 +400,32 @@ extern Datum bpchar(PG_FUNCTION_ARGS);
 extern Datum _bpchar(PG_FUNCTION_ARGS);
 extern Datum char_bpchar(PG_FUNCTION_ARGS);
 extern Datum bpchar_char(PG_FUNCTION_ARGS);
-extern char *name_bpchar(NameData *s);
-extern NameData *bpchar_name(char *s);
-extern bool bpchareq(char *arg1, char *arg2);
-extern bool bpcharne(char *arg1, char *arg2);
-extern bool bpcharlt(char *arg1, char *arg2);
-extern bool bpcharle(char *arg1, char *arg2);
-extern bool bpchargt(char *arg1, char *arg2);
-extern bool bpcharge(char *arg1, char *arg2);
-extern int32 bpcharcmp(char *arg1, char *arg2);
-extern int32 bpcharlen(char *arg);
-extern int32 bpcharoctetlen(char *arg);
+extern Datum name_bpchar(PG_FUNCTION_ARGS);
+extern Datum bpchar_name(PG_FUNCTION_ARGS);
+extern Datum bpchareq(PG_FUNCTION_ARGS);
+extern Datum bpcharne(PG_FUNCTION_ARGS);
+extern Datum bpcharlt(PG_FUNCTION_ARGS);
+extern Datum bpcharle(PG_FUNCTION_ARGS);
+extern Datum bpchargt(PG_FUNCTION_ARGS);
+extern Datum bpcharge(PG_FUNCTION_ARGS);
+extern Datum bpcharcmp(PG_FUNCTION_ARGS);
+extern Datum bpcharlen(PG_FUNCTION_ARGS);
+extern Datum bpcharoctetlen(PG_FUNCTION_ARGS);
 extern Datum hashbpchar(PG_FUNCTION_ARGS);
 
 extern Datum varcharin(PG_FUNCTION_ARGS);
 extern Datum varcharout(PG_FUNCTION_ARGS);
 extern Datum varchar(PG_FUNCTION_ARGS);
 extern Datum _varchar(PG_FUNCTION_ARGS);
-extern bool varchareq(char *arg1, char *arg2);
-extern bool varcharne(char *arg1, char *arg2);
-extern bool varcharlt(char *arg1, char *arg2);
-extern bool varcharle(char *arg1, char *arg2);
-extern bool varchargt(char *arg1, char *arg2);
-extern bool varcharge(char *arg1, char *arg2);
-extern int32 varcharcmp(char *arg1, char *arg2);
-extern int32 varcharlen(char *arg);
-extern int32 varcharoctetlen(char *arg);
+extern Datum varchareq(PG_FUNCTION_ARGS);
+extern Datum varcharne(PG_FUNCTION_ARGS);
+extern Datum varcharlt(PG_FUNCTION_ARGS);
+extern Datum varcharle(PG_FUNCTION_ARGS);
+extern Datum varchargt(PG_FUNCTION_ARGS);
+extern Datum varcharge(PG_FUNCTION_ARGS);
+extern Datum varcharcmp(PG_FUNCTION_ARGS);
+extern Datum varcharlen(PG_FUNCTION_ARGS);
+extern Datum varcharoctetlen(PG_FUNCTION_ARGS);
 
 /* varlena.c */
 extern Datum textin(PG_FUNCTION_ARGS);
@@ -447,9 +447,9 @@ 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);
-extern int32 byteaoctetlen(bytea *v);
+extern Datum byteain(PG_FUNCTION_ARGS);
+extern Datum byteaout(PG_FUNCTION_ARGS);
+extern Datum byteaoctetlen(PG_FUNCTION_ARGS);
 extern Datum byteaGetByte(PG_FUNCTION_ARGS);
 extern Datum byteaGetBit(PG_FUNCTION_ARGS);
 extern Datum byteaSetByte(PG_FUNCTION_ARGS);
@@ -527,43 +527,43 @@ extern Datum macaddr_manuf(PG_FUNCTION_ARGS);
 extern Datum numeric_in(PG_FUNCTION_ARGS);
 extern Datum numeric_out(PG_FUNCTION_ARGS);
 extern Datum numeric(PG_FUNCTION_ARGS);
-extern Numeric numeric_abs(Numeric num);
-extern Numeric numeric_uminus(Numeric num);
-extern Numeric numeric_sign(Numeric num);
+extern Datum numeric_abs(PG_FUNCTION_ARGS);
+extern Datum numeric_uminus(PG_FUNCTION_ARGS);
+extern Datum numeric_sign(PG_FUNCTION_ARGS);
 extern Datum numeric_round(PG_FUNCTION_ARGS);
 extern Datum numeric_trunc(PG_FUNCTION_ARGS);
-extern Numeric numeric_ceil(Numeric num);
-extern Numeric numeric_floor(Numeric num);
-extern int32 numeric_cmp(Numeric num1, Numeric num2);
-extern bool numeric_eq(Numeric num1, Numeric num2);
-extern bool numeric_ne(Numeric num1, Numeric num2);
-extern bool numeric_gt(Numeric num1, Numeric num2);
-extern bool numeric_ge(Numeric num1, Numeric num2);
-extern bool numeric_lt(Numeric num1, Numeric num2);
-extern bool numeric_le(Numeric num1, Numeric num2);
-extern Numeric numeric_add(Numeric num1, Numeric num2);
-extern Numeric numeric_sub(Numeric num1, Numeric num2);
-extern Numeric numeric_mul(Numeric num1, Numeric num2);
-extern Numeric numeric_div(Numeric num1, Numeric num2);
-extern Numeric numeric_mod(Numeric num1, Numeric num2);
-extern Numeric numeric_inc(Numeric num);
-extern Numeric numeric_smaller(Numeric num1, Numeric num2);
-extern Numeric numeric_larger(Numeric num1, Numeric num2);
-extern Numeric numeric_sqrt(Numeric num);
-extern Numeric numeric_exp(Numeric num);
-extern Numeric numeric_ln(Numeric num);
-extern Numeric numeric_log(Numeric num1, Numeric num2);
-extern Numeric numeric_power(Numeric num1, Numeric num2);
+extern Datum numeric_ceil(PG_FUNCTION_ARGS);
+extern Datum numeric_floor(PG_FUNCTION_ARGS);
+extern Datum numeric_cmp(PG_FUNCTION_ARGS);
+extern Datum numeric_eq(PG_FUNCTION_ARGS);
+extern Datum numeric_ne(PG_FUNCTION_ARGS);
+extern Datum numeric_gt(PG_FUNCTION_ARGS);
+extern Datum numeric_ge(PG_FUNCTION_ARGS);
+extern Datum numeric_lt(PG_FUNCTION_ARGS);
+extern Datum numeric_le(PG_FUNCTION_ARGS);
+extern Datum numeric_add(PG_FUNCTION_ARGS);
+extern Datum numeric_sub(PG_FUNCTION_ARGS);
+extern Datum numeric_mul(PG_FUNCTION_ARGS);
+extern Datum numeric_div(PG_FUNCTION_ARGS);
+extern Datum numeric_mod(PG_FUNCTION_ARGS);
+extern Datum numeric_inc(PG_FUNCTION_ARGS);
+extern Datum numeric_smaller(PG_FUNCTION_ARGS);
+extern Datum numeric_larger(PG_FUNCTION_ARGS);
+extern Datum numeric_sqrt(PG_FUNCTION_ARGS);
+extern Datum numeric_exp(PG_FUNCTION_ARGS);
+extern Datum numeric_ln(PG_FUNCTION_ARGS);
+extern Datum numeric_log(PG_FUNCTION_ARGS);
+extern Datum numeric_power(PG_FUNCTION_ARGS);
 extern Datum int4_numeric(PG_FUNCTION_ARGS);
-extern int32 numeric_int4(Numeric num);
+extern Datum numeric_int4(PG_FUNCTION_ARGS);
 extern Datum int8_numeric(PG_FUNCTION_ARGS);
-extern int64 *numeric_int8(Numeric num);
+extern Datum numeric_int8(PG_FUNCTION_ARGS);
 extern Datum int2_numeric(PG_FUNCTION_ARGS);
 extern Datum numeric_int2(PG_FUNCTION_ARGS);
-extern Numeric float8_numeric(float64 val);
-extern float64 numeric_float8(Numeric num);
-extern Numeric float4_numeric(float32 val);
-extern float32 numeric_float4(Numeric num);
+extern Datum float8_numeric(PG_FUNCTION_ARGS);
+extern Datum numeric_float8(PG_FUNCTION_ARGS);
+extern Datum float4_numeric(PG_FUNCTION_ARGS);
+extern Datum numeric_float4(PG_FUNCTION_ARGS);
 extern Datum numeric_accum(PG_FUNCTION_ARGS);
 extern Datum int2_accum(PG_FUNCTION_ARGS);
 extern Datum int4_accum(PG_FUNCTION_ARGS);
-- 
GitLab