diff --git a/src/backend/access/common/heaptuple.c b/src/backend/access/common/heaptuple.c
index f93bf34db90aa8a8ed85b3a32e63433feb8c97d9..319cfff7ca39f71d1f5c34bdec059b9e1f46bff2 100644
--- a/src/backend/access/common/heaptuple.c
+++ b/src/backend/access/common/heaptuple.c
@@ -9,7 +9,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/access/common/heaptuple.c,v 1.63 2000/07/02 22:00:24 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/access/common/heaptuple.c,v 1.64 2000/07/03 23:09:10 wieck Exp $
  *
  * NOTES
  *	  The old interface functions have been converted to macros
@@ -119,7 +119,11 @@ DataFill(char *data,
 		{
 			case -1:
 				*infomask |= HEAP_HASVARLENA;
-				data_length = VARSIZE(DatumGetPointer(value[i]));
+				if (VARATT_IS_EXTERNAL(value[i]))
+					*infomask |= HEAP_HASEXTERNAL;
+				if (VARATT_IS_COMPRESSED(value[i]))
+					*infomask |= HEAP_HASCOMPRESSED;
+				data_length = VARATT_SIZE(DatumGetPointer(value[i]));
 				memmove(data, DatumGetPointer(value[i]), data_length);
 				break;
 			case sizeof(char):
@@ -816,7 +820,7 @@ heap_freetuple(HeapTuple htup)
 	if (htup->t_data != NULL)
 		if (htup->t_datamcxt != NULL && (char *) (htup->t_data) !=
 			((char *) htup + HEAPTUPLESIZE))
-			elog(NOTICE, "TELL Jan Wieck: heap_freetuple() found separate t_data");
+			pfree(htup->t_data);
 
 	pfree(htup);
 }
diff --git a/src/backend/access/common/tupdesc.c b/src/backend/access/common/tupdesc.c
index 433bbe6b06baa38fdae12dc23da8e3f3f9a37d37..c878c50e0af58523fecfc0aaa74d7e74d4290399 100644
--- a/src/backend/access/common/tupdesc.c
+++ b/src/backend/access/common/tupdesc.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/access/common/tupdesc.c,v 1.65 2000/05/30 00:49:38 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/access/common/tupdesc.c,v 1.66 2000/07/03 23:09:10 wieck Exp $
  *
  * NOTES
  *	  some of the executor utility code such as "ExecTypeFromTL" should be
@@ -434,23 +434,16 @@ TupleDescInitEntry(TupleDesc desc,
 
 		att->attlen = typeLen(t);
 		att->attbyval = typeByVal(t);
-		att->attstorage = 'p';
 	}
 	else
 	{
 		att->attlen = typeForm->typlen;
 		att->attbyval = typeForm->typbyval;
 /*
- * This will enable ALL variable size attributes of user
- * relations for automatic move off into "secondary" relation.
- * Jan
+ * Default to the types storage
  */
 #ifdef TUPLE_TOASTER_ACTIVE
-#ifdef TUPLE_TOASTER_ALL_TYPES
-		att->attstorage = (att->attlen == -1) ? 'e' : 'p';
-#else
-		att->attstorage = 'p';
-#endif
+		att->attstorage = typeForm->typstorage;
 #else
 		att->attstorage = 'p';
 #endif
diff --git a/src/backend/access/gist/gist.c b/src/backend/access/gist/gist.c
index 4bf737dcd3678a3dab98fff9ffa8d8c3f2734960..794685da2e12c6ea7aac72295b15a02fc80400eb 100644
--- a/src/backend/access/gist/gist.c
+++ b/src/backend/access/gist/gist.c
@@ -6,7 +6,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/access/gist/gist.c,v 1.59 2000/06/17 23:41:12 tgl Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/access/gist/gist.c,v 1.60 2000/07/03 23:09:11 wieck Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -546,7 +546,7 @@ gistAdjustKeys(Relation r,
 	oldud += sizeof(IndexTupleData);
 
 	evec = (bytea *) palloc(2 * sizeof(GISTENTRY) + VARHDRSZ);
-	VARSIZE(evec) = 2 * sizeof(GISTENTRY) + VARHDRSZ;
+	VARATT_SIZEP(evec) = 2 * sizeof(GISTENTRY) + VARHDRSZ;
 
 	/* insert decompressed oldud into entry vector */
 	gistdentryinit(giststate, &((GISTENTRY *) VARDATA(evec))[0],
@@ -741,7 +741,7 @@ gistSplit(Relation r,
 	else
 		decompvec[maxoff + 1] = FALSE;
 
-	VARSIZE(entryvec) = (maxoff + 2) * sizeof(GISTENTRY) + VARHDRSZ;
+	VARATT_SIZEP(entryvec) = (maxoff + 2) * sizeof(GISTENTRY) + VARHDRSZ;
 
 	/* now let the user-defined picksplit function set up the split vector */
 	FunctionCall2(&giststate->picksplitFn,
diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c
index 9f3a7ac7140b0539ae4e64a13adc25b613b2b48b..1ece416e874ed8e83e145c8e4d43698fa107fce6 100644
--- a/src/backend/access/heap/heapam.c
+++ b/src/backend/access/heap/heapam.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/access/heap/heapam.c,v 1.75 2000/07/03 02:54:15 vadim Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/access/heap/heapam.c,v 1.76 2000/07/03 23:09:16 wieck Exp $
  *
  *
  * INTERFACE ROUTINES
@@ -1299,6 +1299,17 @@ heap_insert(Relation relation, HeapTuple tup)
 	tup->t_data->t_infomask &= ~(HEAP_XACT_MASK);
 	tup->t_data->t_infomask |= HEAP_XMAX_INVALID;
 
+#ifdef TUPLE_TOASTER_ACTIVE
+	/* ----------
+	 * If the new tuple is too big for storage or contains already
+	 * toasted attributes from some other relation, invoke the toaster.
+	 * ----------
+	 */
+    if (HeapTupleHasExtended(tup) ||
+				(MAXALIGN(tup->t_len) > (MaxTupleSize / 4)))
+		heap_tuple_toast_attrs(relation, tup, NULL);
+#endif
+
 	/* Find buffer for this tuple */
 	buffer = RelationGetBufferForTuple(relation, tup->t_len, InvalidBuffer);
 
@@ -1328,8 +1339,8 @@ heap_insert(Relation relation, HeapTuple tup)
 	}
 #endif
 
-	LockBuffer(buffer, BUFFER_LOCK_UNLOCK);
 	WriteBuffer(buffer);
+	LockBuffer(buffer, BUFFER_LOCK_UNLOCK);
 
 	if (IsSystemRelationName(RelationGetRelationName(relation)))
 		RelationMark4RollbackHeapTuple(relation, tup);
@@ -1441,6 +1452,16 @@ l1:
 	tp.t_data->t_infomask &= ~(HEAP_XMAX_COMMITTED |
 							 HEAP_XMAX_INVALID | HEAP_MARKED_FOR_UPDATE);
 
+#ifdef TUPLE_TOASTER_ACTIVE
+	/* ----------
+	 * If the relation has toastable attributes, we need to delete
+	 * no longer needed items there too.
+	 * ----------
+	 */
+	if (HeapTupleHasExtended(&tp))
+		heap_tuple_toast_attrs(relation, NULL, &(tp));
+#endif
+
 	LockBuffer(buffer, BUFFER_LOCK_UNLOCK);
 
 	/* invalidate caches */
@@ -1559,6 +1580,19 @@ l2:
 	oldtup.t_data->t_infomask &= ~(HEAP_XMAX_COMMITTED |
 							 HEAP_XMAX_INVALID | HEAP_MARKED_FOR_UPDATE);
 
+#ifdef TUPLE_TOASTER_ACTIVE
+	/* ----------
+	 * If this relation is enabled for toasting, let the toaster
+	 * delete not any longer needed entries and create new ones to
+	 * make the new tuple fit again.
+	 * ----------
+	 */
+	if (HeapTupleHasExtended(&oldtup) || 
+			HeapTupleHasExtended(newtup) ||
+			(MAXALIGN(newtup->t_len) > (MaxTupleSize / 4)))
+		heap_tuple_toast_attrs(relation, newtup, &oldtup);
+#endif
+
 	/* record address of new tuple in t_ctid of old one */
 	oldtup.t_data->t_ctid = newtup->t_self;
 
diff --git a/src/backend/access/heap/tuptoaster.c b/src/backend/access/heap/tuptoaster.c
index 0af5db0cafde7b8038fbe11439aec1e5bc8ab599..3221ed5b134afc493dd7701622a04a05a9b9397b 100644
--- a/src/backend/access/heap/tuptoaster.c
+++ b/src/backend/access/heap/tuptoaster.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/access/heap/tuptoaster.c,v 1.4 2000/05/30 00:49:39 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/access/heap/tuptoaster.c,v 1.5 2000/07/03 23:09:19 wieck Exp $
  *
  *
  * INTERFACE ROUTINES
@@ -16,26 +16,992 @@
  *			Try to make a given tuple fit into one page by compressing
  *			or moving off attributes
  *
+ *		heap_tuple_untoast_attr -
+ *			Fetch back a given value from the "secondary" relation
+ *
  *-------------------------------------------------------------------------
  */
 
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
 #include "postgres.h"
 
+#include "access/heapam.h"
+#include "access/genam.h"
+#include "access/tuptoaster.h"
+#include "catalog/catalog.h"
+#include "utils/rel.h"
+#include "utils/builtins.h"
+#include "utils/fmgroids.h"
+#include "utils/pg_lzcompress.h"
 
 
 #ifdef TUPLE_TOASTER_ACTIVE
+#undef TOAST_DEBUG
+
+static void			toast_delete(Relation rel, HeapTuple oldtup);
+static void			toast_delete_datum(Relation rel, Datum value);
+static void			toast_insert_or_update(Relation rel, HeapTuple newtup,
+								HeapTuple oldtup);
+static Datum		toast_compress_datum(Datum value);
+static Datum		toast_save_datum(Relation rel, Oid mainoid, int16 attno, Datum value);
+								
+static varattrib   *toast_fetch_datum(varattrib *attr);
+
 
+/* ----------
+ * heap_tuple_toast_attrs -
+ *
+ *	This is the central public entry point for toasting from heapam.
+ *
+ *	Calls the appropriate event specific action.
+ * ----------
+ */
 void
 heap_tuple_toast_attrs(Relation rel, HeapTuple newtup, HeapTuple oldtup)
 {
+	if (newtup == NULL)
+		toast_delete(rel, oldtup);
+	else
+		toast_insert_or_update(rel, newtup, oldtup);
+}
+
+
+/* ----------
+ * heap_tuple_untoast_attr -
+ *
+ *	Public entry point to get back a toasted value from compression
+ *	or external storage.
+ * ----------
+ */
+varattrib *
+heap_tuple_untoast_attr(varattrib *attr)
+{
+	varattrib	*result;
+
+	if (VARATT_IS_EXTERNAL(attr))
+	{
+		if (VARATT_IS_COMPRESSED(attr))
+		{
+			/* ----------
+			 * This is an external stored compressed value
+			 * Fetch it from the toast heap and decompress.
+			 * ----------
+			 */
+			varattrib *tmp;
+
+			tmp = toast_fetch_datum(attr);
+			result = (varattrib *)palloc(attr->va_content.va_external.va_rawsize
+								+ VARHDRSZ);
+			VARATT_SIZEP(result) = attr->va_content.va_external.va_rawsize
+								+ VARHDRSZ;
+			pglz_decompress((PGLZ_Header *)tmp, VARATT_DATA(result));
+
+			pfree(tmp);
+		}
+		else
+		{
+			/* ----------
+			 * This is an external stored plain value
+			 * ----------
+			 */
+			result = toast_fetch_datum(attr);
+		}
+	}
+	else if (VARATT_IS_COMPRESSED(attr))
+	{
+		/* ----------
+		 * This is a compressed value inside of the main tuple
+		 * ----------
+		 */
+		result = (varattrib *)palloc(attr->va_content.va_compressed.va_rawsize
+							+ VARHDRSZ);
+		VARATT_SIZEP(result) = attr->va_content.va_compressed.va_rawsize
+							+ VARHDRSZ;
+		pglz_decompress((PGLZ_Header *)attr, VARATT_DATA(result));
+	}
+	else
+		/* ----------
+		 * This is a plain value inside of the main tuple - why am I called?
+		 * ----------
+		 */
+		return attr;
+
+	return result;
+}
+
+
+/* ----------
+ * toast_delete -
+ *
+ *	Cascaded delete toast-entries on DELETE
+ * ----------
+ */
+static void
+toast_delete(Relation rel, HeapTuple oldtup)
+{
+	TupleDesc			tupleDesc;
+	Form_pg_attribute  *att;
+	int					numAttrs;
+	int					i;
+	Datum				value;
+	bool				isnull;
+
+	/* ----------
+	 * Get the tuple descriptor, the number of and attribute
+	 * descriptors.
+	 * ----------
+	 */
+	tupleDesc	= rel->rd_att;
+	numAttrs	= tupleDesc->natts;
+	att			= tupleDesc->attrs;
+
+	/* ----------
+	 * Check for external stored attributes and delete them
+	 * from the secondary relation.
+	 * ----------
+	 */
+	for (i = 0; i < numAttrs; i++)
+	{
+		value = heap_getattr(oldtup, i + 1, tupleDesc, &isnull);
+		if (!isnull && att[i]->attlen == -1)
+			if (VARATT_IS_EXTERNAL(value))
+				toast_delete_datum(rel, value);
+	}
+}
+
+
+/* ----------
+ * toast_insert_or_update -
+ *
+ *	Delete no more used toast-entries and create new ones to
+ *	make the new tuple fit on INSERT or UPDATE
+ * ----------
+ */
+static void
+toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup)
+{
+	TupleDesc			tupleDesc;
+	Form_pg_attribute  *att;
+	int					numAttrs;
+	int					i;
+	bool				old_isnull;
+	bool				new_isnull;
+
+	bool				need_change = false;
+	bool				need_free   = false;
+	bool				need_delold = false;
+	bool				has_nulls   = false;
+
+	Size				maxDataLen;
+
+	char				toast_action[MaxHeapAttributeNumber];
+	char				toast_nulls[MaxHeapAttributeNumber];
+	Datum				toast_values[MaxHeapAttributeNumber];
+	int32				toast_sizes[MaxHeapAttributeNumber];
+	bool				toast_free[MaxHeapAttributeNumber];
+	bool				toast_delold[MaxHeapAttributeNumber];
+
+	/* ----------
+	 * Get the tuple descriptor, the number of and attribute
+	 * descriptors and the location of the tuple values.
+	 * ----------
+	 */
+	tupleDesc	= rel->rd_att;
+	numAttrs	= tupleDesc->natts;
+	att			= tupleDesc->attrs;
+
+	/* ----------
+	 * Then collect information about the values given
+	 * ----------
+	 */
+	memset(toast_action, ' ', numAttrs * sizeof(char));
+	memset(toast_nulls,  ' ', numAttrs * sizeof(char));
+	memset(toast_free,   0,   numAttrs * sizeof(bool));
+	memset(toast_delold, 0,   numAttrs * sizeof(bool));
+	for (i = 0; i < numAttrs; i++)
+	{
+		varattrib	   *old_value;
+		varattrib	   *new_value;
+
+		if (oldtup != NULL)
+		{
+			/* ----------
+			 * For UPDATE get the old and new values of this attribute
+			 * ----------
+			 */
+			old_value = (varattrib *)DatumGetPointer(
+						heap_getattr(oldtup, i + 1, tupleDesc, &old_isnull));
+			toast_values[i] = 
+						heap_getattr(newtup, i + 1, tupleDesc, &new_isnull);
+			new_value = (varattrib *)DatumGetPointer(toast_values[i]);
+
+			/* ----------
+			 * If the old value is an external stored one, check if it
+			 * has changed so we have to detele it later.
+			 * ----------
+			 */
+			if (!old_isnull && att[i]->attlen == -1 && 
+						VARATT_IS_EXTERNAL(old_value))
+			{
+				if (new_isnull || !VARATT_IS_EXTERNAL(new_value) ||
+						old_value->va_content.va_external.va_rowid !=
+						new_value->va_content.va_external.va_rowid ||
+						old_value->va_content.va_external.va_attno !=
+						new_value->va_content.va_external.va_attno)
+				{
+					/* ----------
+					 * The old external store value isn't needed any
+					 * more after the update
+					 * ----------
+					 */
+					toast_delold[i] = true;
+					need_delold = true;
+				}
+				else
+				{
+					/* ----------
+					 * This attribute isn't changed by this update
+					 * so we reuse the original reference to the old
+					 * value in the new tuple.
+					 * ----------
+					 */
+					toast_action[i] = 'p';
+					toast_sizes[i] = VARATT_SIZE(toast_values[i]);
+					continue;
+				}
+			}
+		}
+		else
+		{
+			/* ----------
+			 * For INSERT simply get the new value
+			 * ----------
+			 */
+			toast_values[i] = 
+						heap_getattr(newtup, i + 1, tupleDesc, &new_isnull);
+		}
+
+		/* ----------
+		 * Handle NULL attributes
+		 * ----------
+		 */
+		if (new_isnull)
+		{
+			toast_action[i] = 'p';
+			toast_nulls[i] = 'n';
+			has_nulls = true;
+			continue;
+		}
+
+		/* ----------
+		 * Now look at varsize attributes
+		 * ----------
+		 */
+		if (att[i]->attlen == -1)
+		{
+			/* ----------
+			 * If the tables attribute say's PLAIN allways, we
+			 * do so below.
+			 * ----------
+			 */
+			if (att[i]->attstorage == 'p')
+				toast_action[i] = 'p';
+
+			/* ----------
+			 * We're running for UPDATE, so any TOASTed value we find
+			 * still in the tuple must be someone elses we cannot reuse.
+			 * Expand it to plain and eventually toast it again below.
+			 * ----------
+			 */
+			if (VARATT_IS_EXTENDED(DatumGetPointer(toast_values[i])))
+			{
+				toast_values[i] = PointerGetDatum(heap_tuple_untoast_attr(
+					(varattrib *)DatumGetPointer(toast_values[i])));
+				toast_free[i] = true;
+				need_change = true;
+				need_free = true;
+			}
+
+			/* ----------
+			 * Remember the size of this attribute
+			 * ----------
+			 */
+			toast_sizes[i]  = VARATT_SIZE(DatumGetPointer(toast_values[i]));
+		}
+		else
+		{
+			/* ----------
+			 * Not a variable size attribute, plain storage allways
+			 * ----------
+			 */
+			toast_action[i] = 'p';
+			toast_sizes[i]  = att[i]->attlen;
+		}
+	}
+
+	/* ----------
+	 * Compress and/or save external until data fits
+	 *
+	 *	1: Inline compress attributes with attstorage 'x'
+	 *	2: Store attributes with attstorage 'x' or 'e' external
+	 *  3: Inline compress attributes with attstorage 'm'
+	 *	4: Store attributes with attstorage 'm' external
+	 * ----------
+	 */
+	maxDataLen = offsetof(HeapTupleHeaderData, t_bits);
+	if (has_nulls)
+		maxDataLen += BITMAPLEN(numAttrs);
+	maxDataLen = (MaxTupleSize / 4) - MAXALIGN(maxDataLen);
+
+	/* ----------
+	 * Look for attributes with attstorage 'x' to compress
+	 * ----------
+	 */
+	while (MAXALIGN(ComputeDataSize(tupleDesc, toast_values, toast_nulls)) >
+				maxDataLen)
+	{
+		int		biggest_attno = -1;
+		int32	biggest_size  = MAXALIGN(sizeof(varattrib));
+		Datum	old_value;
+
+		/* ----------
+		 * Search for the biggest yet uncompressed internal attribute
+		 * ----------
+		 */
+		for (i = 0; i < numAttrs; i++)
+		{
+			if (toast_action[i] == 'p')
+				continue;
+			if (VARATT_IS_EXTENDED(toast_values[i]))
+				continue;
+			if (att[i]->attstorage != 'x')
+				continue;
+			if (toast_sizes[i] > biggest_size)
+			{
+				biggest_attno = i;
+				biggest_size  = toast_sizes[i];
+			}
+		}
+
+		if (biggest_attno < 0)
+			break;
+
+		/* ----------
+		 * Compress it inline
+		 * ----------
+		 */
+		i					= biggest_attno;
+		old_value			= toast_values[i];
+
+		toast_values[i]		= toast_compress_datum(toast_values[i]);
+									
+		if (toast_free[i])
+			pfree(DatumGetPointer(old_value));
+
+		toast_free[i]		= true;
+		toast_sizes[i]		= VARATT_SIZE(toast_values[i]);
+
+		need_change = true;
+		need_free   = true;
+	}
+
+	/* ----------
+	 * Second we look for attributes of attstorage 'x' or 'e' that
+	 * are still inline.
+	 * ----------
+	 */
+	while (MAXALIGN(ComputeDataSize(tupleDesc, toast_values, toast_nulls)) >
+				maxDataLen && rel->rd_rel->reltoastrelid != InvalidOid)
+	{
+		int		biggest_attno = -1;
+		int32	biggest_size  = MAXALIGN(sizeof(varattrib));
+		Datum	old_value;
+
+		/* ----------
+		 * Search for the biggest yet inlined attribute with
+		 * attstorage = 'x' or 'e'
+		 * ----------
+		 */
+		for (i = 0; i < numAttrs; i++)
+		{
+			if (toast_action[i] == 'p')
+				continue;
+			if (VARATT_IS_EXTERNAL(toast_values[i]))
+				continue;
+			if (att[i]->attstorage != 'x' && att[i]->attstorage != 'e')
+				continue;
+			if (toast_sizes[i] > biggest_size)
+			{
+				biggest_attno = i;
+				biggest_size  = toast_sizes[i];
+			}
+		}
+
+		if (biggest_attno < 0)
+			break;
+
+		/* ----------
+		 * Store this external
+		 * ----------
+		 */
+		i					= biggest_attno;
+		old_value			= toast_values[i];
+		toast_action[i]		= 'p';
+		toast_values[i]		= toast_save_datum(rel,
+									newtup->t_data->t_oid,
+									i + 1,
+									toast_values[i]);
+		if (toast_free[i])
+			pfree(DatumGetPointer(old_value));
+
+		toast_free[i]		= true;
+		toast_sizes[i]		= VARATT_SIZE(toast_values[i]);
+
+		need_change = true;
+		need_free   = true;
+	}
+
+	/* ----------
+	 * Round 3 - this time we take attributes with storage
+	 * 'm' into compression
+	 * ----------
+	 */
+	while (MAXALIGN(ComputeDataSize(tupleDesc, toast_values, toast_nulls)) >
+				maxDataLen)
+	{
+		int		biggest_attno = -1;
+		int32	biggest_size  = MAXALIGN(sizeof(varattrib));
+		Datum	old_value;
+
+		/* ----------
+		 * Search for the biggest yet uncompressed internal attribute
+		 * ----------
+		 */
+		for (i = 0; i < numAttrs; i++)
+		{
+			if (toast_action[i] == 'p')
+				continue;
+			if (VARATT_IS_EXTENDED(toast_values[i]))
+				continue;
+			if (att[i]->attstorage != 'm')
+				continue;
+			if (toast_sizes[i] > biggest_size)
+			{
+				biggest_attno = i;
+				biggest_size  = toast_sizes[i];
+			}
+		}
+
+		if (biggest_attno < 0)
+			break;
+
+		/* ----------
+		 * Compress it inline
+		 * ----------
+		 */
+		i					= biggest_attno;
+		old_value			= toast_values[i];
+
+		toast_values[i]		= toast_compress_datum(toast_values[i]);
+									
+		if (toast_free[i])
+			pfree(DatumGetPointer(old_value));
+
+		toast_free[i]		= true;
+		toast_sizes[i]		= VARATT_SIZE(toast_values[i]);
+
+		need_change = true;
+		need_free   = true;
+	}
+
+	/* ----------
+	 * Finally we store attributes of type 'm' external
+	 * ----------
+	 */
+	while (MAXALIGN(ComputeDataSize(tupleDesc, toast_values, toast_nulls)) >
+				maxDataLen && rel->rd_rel->reltoastrelid != InvalidOid)
+	{
+		int		biggest_attno = -1;
+		int32	biggest_size  = MAXALIGN(sizeof(varattrib));
+		Datum	old_value;
+
+		/* ----------
+		 * Search for the biggest yet inlined attribute with
+		 * attstorage = 'x' or 'e'
+		 * ----------
+		 */
+		for (i = 0; i < numAttrs; i++)
+		{
+			if (toast_action[i] == 'p')
+				continue;
+			if (VARATT_IS_EXTERNAL(toast_values[i]))
+				continue;
+			if (att[i]->attstorage != 'm')
+				continue;
+			if (toast_sizes[i] > biggest_size)
+			{
+				biggest_attno = i;
+				biggest_size  = toast_sizes[i];
+			}
+		}
+
+		if (biggest_attno < 0)
+			break;
+
+		/* ----------
+		 * Store this external
+		 * ----------
+		 */
+		i					= biggest_attno;
+		old_value			= toast_values[i];
+		toast_action[i]		= 'p';
+		toast_values[i]		= toast_save_datum(rel,
+									newtup->t_data->t_oid,
+									i + 1,
+									toast_values[i]);
+		if (toast_free[i])
+			pfree(DatumGetPointer(old_value));
+
+		toast_free[i]		= true;
+		toast_sizes[i]		= VARATT_SIZE(toast_values[i]);
+
+		need_change = true;
+		need_free   = true;
+	}
+
+	/* ----------
+	 * In the case we toasted any values, we need to build
+	 * a new heap tuple with the changed values.
+	 * ----------
+	 */
+	if (need_change)
+	{
+		char		   *new_data;
+		int32			new_len;
+		MemoryContext	oldcxt;
+		HeapTupleHeader	olddata;
+
+		/* ----------
+		 * Calculate the new size of the tuple
+		 * ----------
+		 */
+		new_len = offsetof(HeapTupleHeaderData, t_bits);
+		if (has_nulls)
+			new_len += BITMAPLEN(numAttrs);
+		new_len = MAXALIGN(new_len);
+		new_len += ComputeDataSize(tupleDesc, toast_values, toast_nulls);
+
+		/* ----------
+		 * Remember the old memory location of the tuple (for below),
+		 * switch to the memory context of the HeapTuple structure
+		 * and allocate the new tuple.
+		 * ----------
+		 */
+		olddata = newtup->t_data;
+		oldcxt = MemoryContextSwitchTo(newtup->t_datamcxt);
+		new_data = palloc(new_len);
+
+		/* ----------
+		 * Put the tuple header and the changed values into place
+		 * ----------
+		 */
+		memcpy(new_data, newtup->t_data, newtup->t_data->t_hoff);
+		newtup->t_data = (HeapTupleHeader)new_data;
+		newtup->t_len = new_len;
+
+		DataFill((char *)(MAXALIGN((long)new_data +
+						offsetof(HeapTupleHeaderData, t_bits) + 
+						((has_nulls) ? BITMAPLEN(numAttrs) : 0))),
+				tupleDesc,
+				toast_values,
+				toast_nulls,
+				&(newtup->t_data->t_infomask),
+				HeapTupleNoNulls(newtup) ? NULL : new_data);
+
+		/* ----------
+		 * In the case we modified a previously modified tuple again,
+		 * free the memory from the previous run
+		 * ----------
+		 */
+		if ((char *)olddata != ((char *)newtup + HEAPTUPLESIZE))
+			pfree(olddata);
+
+		/* ----------
+		 * Switch back to the old memory context
+		 * ----------
+		 */
+		MemoryContextSwitchTo(oldcxt);
+	}
+
+
+	/* ----------
+	 * Free allocated temp values
+	 * ----------
+	 */
+	if (need_free)
+		for (i = 0; i < numAttrs; i++)
+			if (toast_free[i])
+				pfree(DatumGetPointer(toast_values[i]));
+
+	/* ----------
+	 * Delete external values from the old tuple
+	 * ----------
+	 */
+	if (need_delold)
+		for (i = 0; i < numAttrs; i++)
+			if (toast_delold[i])
+				toast_delete_datum(rel,
+					heap_getattr(oldtup, i + 1, tupleDesc, &old_isnull));
+
+	return;
+}
+
+
+/* ----------
+ * toast_compress_datum -
+ *
+ *	Create a compressed version of a datum
+ * ----------
+ */
+static Datum
+toast_compress_datum(Datum value)
+{
+	varattrib	   *tmp;
+
+	tmp = (varattrib *)palloc(sizeof(PGLZ_Header) + VARATT_SIZE(value));
+	pglz_compress(VARATT_DATA(value), VARATT_SIZE(value) - VARHDRSZ,
+				(PGLZ_Header *)tmp,
+				PGLZ_strategy_default);
+	VARATT_SIZEP(tmp) |= VARATT_FLAG_COMPRESSED;
+
+	return PointerGetDatum(tmp);
+}
+
+
+/* ----------
+ * toast_save_datum -
+ *
+ *	Save one single datum into the secondary relation and return
+ *	a varattrib reference for it.
+ * ----------
+ */
+static Datum
+toast_save_datum(Relation rel, Oid mainoid, int16 attno, Datum value)
+{
+	Relation			toastrel;
+	Relation			toastidx;
+	HeapTuple			toasttup;
+	InsertIndexResult	idxres;
+	TupleDesc			toasttupDesc;
+	Datum				t_values[3];
+	char				t_nulls[4];
+	varattrib		   *result;
+	char				chunk_data[MaxTupleSize];
+	int32				chunk_size;
+	int32				chunk_seq = 0;
+	char			   *data_p;
+	int32				data_todo;
+
+	/* ----------
+	 * Create the varattrib reference
+	 * ----------
+	 */
+	result = (varattrib *)palloc(sizeof(varattrib));
+
+	result->va_header	= sizeof(varattrib) | VARATT_FLAG_EXTERNAL;
+	if (VARATT_IS_COMPRESSED(value))
+	{
+		result->va_header |= VARATT_FLAG_COMPRESSED;
+		result->va_content.va_external.va_rawsize = 
+					((varattrib *)value)->va_content.va_compressed.va_rawsize;
+	}
+	else
+		result->va_content.va_external.va_rawsize = VARATT_SIZE(value);
+					
+	result->va_content.va_external.va_extsize		= 
+					VARATT_SIZE(value) - VARHDRSZ;
+	result->va_content.va_external.va_valueid		= newoid();
+	result->va_content.va_external.va_toastrelid	= 
+					rel->rd_rel->reltoastrelid;
+	result->va_content.va_external.va_toastidxid	= 
+					rel->rd_rel->reltoastidxid;
+	result->va_content.va_external.va_rowid			= mainoid;
+	result->va_content.va_external.va_attno			= attno;
+
+	/* ----------
+	 * Initialize constant parts of the tuple data
+	 * ----------
+	 */
+	t_values[0] = ObjectIdGetDatum(result->va_content.va_external.va_valueid);
+	t_values[2] = PointerGetDatum(chunk_data);
+	t_nulls[0] = ' ';
+	t_nulls[1] = ' ';
+	t_nulls[2] = ' ';
+	t_nulls[3] = '\0';
+
+	/* ----------
+	 * Get the data to process
+	 * ----------
+	 */
+	data_p		= VARATT_DATA(value);
+	data_todo	= VARATT_SIZE(value) - VARHDRSZ;
+
+	/* ----------
+	 * Open the toast relation
+	 * ----------
+	 */
+	toastrel = heap_open(rel->rd_rel->reltoastrelid, RowExclusiveLock);
+	if (toastrel == NULL)
+		elog(ERROR, "Failed to open secondary relation of %s",
+					nameout(&(rel->rd_rel->relname)));
+	toasttupDesc = toastrel->rd_att;
+	toastidx = index_open(rel->rd_rel->reltoastidxid);
+	if (toastidx == NULL)
+		elog(ERROR, "Failed to open index for secondary relation of %s",
+					nameout(&(rel->rd_rel->relname)));
+	
+	/* ----------
+	 * Split up the item into chunks 
+	 * ----------
+	 */
+	while (data_todo > 0)
+	{
+		/* ----------
+		 * Calculate the size of this chunk
+		 * ----------
+		 */
+		chunk_size = (TOAST_MAX_CHUNK_SIZE < data_todo) ? 
+						TOAST_MAX_CHUNK_SIZE : data_todo;
+
+		/* ----------
+		 * Build a tuple
+		 * ----------
+		 */
+		t_values[1] = (Datum)(chunk_seq++);
+		VARATT_SIZEP(chunk_data) = chunk_size + VARHDRSZ;
+		memcpy(VARATT_DATA(chunk_data), data_p, chunk_size);
+		toasttup = heap_formtuple(toasttupDesc, t_values, t_nulls);
+		if (!HeapTupleIsValid(toasttup))
+			elog(ERROR, "Failed to build TOAST tuple");
+
+		/* ----------
+		 * Store it and create the index entry
+		 * ----------
+		 */
+		heap_insert(toastrel, toasttup);
+		idxres = index_insert(toastidx, t_values, t_nulls,
+						&(toasttup->t_self),
+						toastrel);
+		if (idxres == NULL)
+			elog(ERROR, "Failed to insert index entry for TOAST tuple");
+
+		/* ----------
+		 * Free memory
+		 * ----------
+		 */
+		heap_freetuple(toasttup);
+		pfree(idxres);
+
+		/* ----------
+		 * Move on to next chunk
+		 * ----------
+		 */
+		data_todo -= chunk_size;
+		data_p += chunk_size;
+	}
+
+	/* ----------
+	 * Done - close toast relation and return the reference
+	 * ----------
+	 */
+	index_close(toastidx);
+	heap_close(toastrel, RowExclusiveLock);
+
+	return PointerGetDatum(result);
+}
+
+
+/* ----------
+ * toast_delete_datum -
+ *
+ *	Delete a single external stored value.
+ * ----------
+ */
+static void
+toast_delete_datum(Relation rel, Datum value)
+{
+	register varattrib	   *attr = (varattrib *)value;
+	Relation				toastrel;
+	Relation				toastidx;
+	ScanKeyData				toastkey;
+	IndexScanDesc			toastscan;
+	HeapTupleData			toasttup;
+	RetrieveIndexResult		indexRes;
+	Buffer					buffer;
+
+	if (!VARATT_IS_EXTERNAL(attr))
+		return;
+
+	/* ----------
+	 * Open the toast relation and it's index
+	 * ----------
+	 */
+	toastrel	= heap_open(attr->va_content.va_external.va_toastrelid,
+					RowExclusiveLock);
+	if (toastrel == NULL)
+		elog(ERROR, "Failed to open secondary relation at TOAST fetch");
+	toastidx = index_open(attr->va_content.va_external.va_toastidxid);
+	if (toastidx == NULL)
+		elog(ERROR, "Failed to open index of secondary relation at TOAST fetch");
+
+	/* ----------
+	 * Setup a scan key to fetch from the index by va_valueid
+	 * ----------
+	 */
+	ScanKeyEntryInitialize(&toastkey,
+					(bits16) 0, 
+					(AttrNumber) 1, 
+					(RegProcedure) F_OIDEQ, 
+					ObjectIdGetDatum(attr->va_content.va_external.va_valueid));
+
+	/* ----------
+	 * Read the chunks by index
+	 * ----------
+	 */
+	toastscan = index_beginscan(toastidx, false, 1, &toastkey);
+	while ((indexRes = index_getnext(toastscan, ForwardScanDirection)) != NULL)
+	{
+		toasttup.t_self = indexRes->heap_iptr;
+		heap_fetch(toastrel, SnapshotAny, &toasttup, &buffer);
+		pfree(indexRes);
+
+		if (!toasttup.t_data)
+			continue;
+
+		/* ----------
+		 * Have a chunk, delete it
+		 * ----------
+		 */
+		heap_delete(toastrel, &toasttup.t_self, NULL);
+
+		ReleaseBuffer(buffer);
+	}
+
+	/* ----------
+	 * End scan and close relations
+	 * ----------
+	 */
+	index_endscan(toastscan);
+	index_close(toastidx);
+	heap_close(toastrel, RowExclusiveLock);
+
 	return;
 }
 
 
-varattrib  *
-heap_tuple_untoast_attr(varattrib * attr)
+/* ----------
+ * toast_fetch_datum -
+ *
+ *	Reconstruct an in memory varattrib from the chunks saved
+ *	in the toast relation
+ * ----------
+ */
+static varattrib *
+toast_fetch_datum(varattrib *attr)
 {
-	elog(ERROR, "heap_tuple_untoast_attr() called");
+	Relation				toastrel;
+	Relation				toastidx;
+	ScanKeyData				toastkey;
+	IndexScanDesc			toastscan;
+	HeapTupleData			toasttup;
+	HeapTuple				ttup;
+	TupleDesc				toasttupDesc;
+	RetrieveIndexResult		indexRes;
+	Buffer					buffer;
+
+	varattrib			   *result;
+	int32					ressize;
+	int32					residx;
+	int						numchunks;
+	Datum					chunk;
+	bool					isnull;
+
+	ressize = attr->va_content.va_external.va_extsize;
+    numchunks = (ressize / TOAST_MAX_CHUNK_SIZE) + 1;
+
+	result = (varattrib *)palloc(ressize + VARHDRSZ);
+	VARATT_SIZEP(result) = ressize + VARHDRSZ;
+	if (VARATT_IS_COMPRESSED(attr))
+		VARATT_SIZEP(result) |= VARATT_FLAG_COMPRESSED;
+
+	/* ----------
+	 * Open the toast relation and it's index
+	 * ----------
+	 */
+	toastrel	= heap_open(attr->va_content.va_external.va_toastrelid,
+					AccessShareLock);
+	if (toastrel == NULL)
+		elog(ERROR, "Failed to open secondary relation at TOAST fetch");
+	toasttupDesc = toastrel->rd_att;
+	toastidx = index_open(attr->va_content.va_external.va_toastidxid);
+	if (toastidx == NULL)
+		elog(ERROR, "Failed to open index of secondary relation at TOAST fetch");
+
+	/* ----------
+	 * Setup a scan key to fetch from the index by va_valueid
+	 * ----------
+	 */
+	ScanKeyEntryInitialize(&toastkey,
+					(bits16) 0, 
+					(AttrNumber) 1, 
+					(RegProcedure) F_OIDEQ, 
+					ObjectIdGetDatum(attr->va_content.va_external.va_valueid));
+
+	/* ----------
+	 * Read the chunks by index
+	 * ----------
+	 */
+	toastscan = index_beginscan(toastidx, false, 1, &toastkey);
+	while ((indexRes = index_getnext(toastscan, ForwardScanDirection)) != NULL)
+	{
+		toasttup.t_self = indexRes->heap_iptr;
+		heap_fetch(toastrel, SnapshotAny, &toasttup, &buffer);
+		pfree(indexRes);
+
+		if (!toasttup.t_data)
+			continue;
+		ttup = &toasttup;
+
+		/* ----------
+		 * Have a chunk, extract the sequence number and the data
+		 * ----------
+		 */
+		residx = (int32)heap_getattr(ttup, 2, toasttupDesc, &isnull);
+		chunk = heap_getattr(ttup, 3, toasttupDesc, &isnull);
+
+		/* ----------
+		 * Copy the data into our result
+		 * ----------
+		 */
+		memcpy(((char *)VARATT_DATA(result)) + residx * TOAST_MAX_CHUNK_SIZE,
+					VARATT_DATA(chunk),
+					VARATT_SIZE(chunk) - VARHDRSZ);
+
+		ReleaseBuffer(buffer);
+	}
+
+	/* ----------
+	 * End scan and close relations
+	 * ----------
+	 */
+	index_endscan(toastscan);
+	index_close(toastidx);
+	heap_close(toastrel, AccessShareLock);
+
+	return result;
 }
 
 
diff --git a/src/backend/bootstrap/bootstrap.c b/src/backend/bootstrap/bootstrap.c
index 854b68e00d24a094c4542564d5cfa58ddb51e2b7..1c52d098a1aaa559cdf68ab6e30df2c20e2caac3 100644
--- a/src/backend/bootstrap/bootstrap.c
+++ b/src/backend/bootstrap/bootstrap.c
@@ -8,7 +8,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/bootstrap/bootstrap.c,v 1.89 2000/07/03 20:48:27 petere Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/bootstrap/bootstrap.c,v 1.90 2000/07/03 23:09:23 wieck Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -571,7 +571,7 @@ DefineAttr(char *name, char *type, int attnum)
 		attrtypes[attnum]->attnum = 1 + attnum; /* fillatt */
 		attlen = attrtypes[attnum]->attlen = Ap->am_typ.typlen;
 		attrtypes[attnum]->attbyval = Ap->am_typ.typbyval;
-		attrtypes[attnum]->attstorage = 'p';
+		attrtypes[attnum]->attstorage = Ap->am_typ.typstorage;;
 		attrtypes[attnum]->attalign = Ap->am_typ.typalign;
 	}
 	else
diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 721297680edabd2289c8d84318736606a1d72e2c..2187b8db4439037a7be86fac91c9d6dba604dc29 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.136 2000/07/02 22:00:34 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.137 2000/07/03 23:09:27 wieck Exp $
  *
  *
  * INTERFACE ROUTINES
@@ -730,7 +730,8 @@ AddNewRelationType(char *typeName, Oid new_rel_oid)
 							  NULL,		/* array element type - irrelevent */
 							  "-",		/* default type value */
 							  (bool) 1, /* passed by value */
-							  'i');		/* default alignment */
+							  'i',		/* default alignment */
+							  'p');		/* Not TOASTable */
 }
 
 /* --------------------------------
@@ -1423,6 +1424,7 @@ heap_drop_with_catalog(const char *relname)
 	Relation	rel;
 	Oid			rid;
 	bool		istemp = (get_temp_rel_by_username(relname) != NULL);
+	bool		has_toasttable;
 
 	/* ----------------
 	 *	Open and lock the relation.
@@ -1520,6 +1522,11 @@ heap_drop_with_catalog(const char *relname)
 		smgrunlink(DEFAULT_SMGR, rel);
 	rel->rd_unlinked = true;
 
+	/*
+	 * Remember if there is a toast relation for below
+	 */
+	has_toasttable = rel->rd_rel->reltoastrelid != InvalidOid;
+
 	/*
 	 * Close relcache entry, but *keep* AccessExclusiveLock on the
 	 * relation until transaction commit.  This ensures no one else will
@@ -1535,6 +1542,20 @@ heap_drop_with_catalog(const char *relname)
 
 	if (istemp)
 		remove_temp_relation(rid);
+
+	if (has_toasttable)
+	{
+		char	toast_relname[NAMEDATALEN];
+		bool	old_allow;
+
+		old_allow = allowSystemTableMods;
+		allowSystemTableMods = true;
+
+		sprintf(toast_relname, "pg_toast_%d", rid);
+		heap_drop_with_catalog(toast_relname);
+
+		allowSystemTableMods = old_allow;
+	}
 }
 
 
diff --git a/src/backend/catalog/pg_type.c b/src/backend/catalog/pg_type.c
index bf706d5146ccb874bbf118f8d60b04553c1db7f4..bd34ee0a20061917308b6b2b68267636be0e7050 100644
--- a/src/backend/catalog/pg_type.c
+++ b/src/backend/catalog/pg_type.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/catalog/pg_type.c,v 1.52 2000/06/13 07:34:52 tgl Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/catalog/pg_type.c,v 1.53 2000/07/03 23:09:28 wieck Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -186,7 +186,8 @@ TypeShellMakeWithOpenRelation(Relation pg_type_desc, char *typeName)
 	values[i++] = (Datum) InvalidOid;	/* 12 */
 	values[i++] = (Datum) InvalidOid;	/* 13 */
 	values[i++] = (Datum) InvalidOid;	/* 14 */
-	values[i++] = (Datum) 'i';	/* 15 */
+	values[i++] = (Datum) 'p';			/* 15 */
+	values[i++] = (Datum) 'i';			/* 16 */
 
 	/*
 	 * ... and fill typdefault with a bogus value
@@ -287,7 +288,8 @@ TypeCreate(char *typeName,
 		   char *elementTypeName,
 		   char *defaultTypeValue,		/* internal rep */
 		   bool passedByValue,
-		   char alignment)
+		   char alignment,
+		   char storage)
 {
 	int			i,
 				j;
@@ -448,11 +450,17 @@ TypeCreate(char *typeName,
 	 */
 	values[i++] = (Datum) alignment;	/* 15 */
 
+	/* ----------------
+	 *	set default storage for TOAST
+	 * ----------------
+	 */
+	values[i++] = (Datum) storage; /* 16 */
+
 	/* ----------------
 	 *	initialize the default value for this type.
 	 * ----------------
 	 */
-	values[i] = (Datum) textin(PointerIsValid(defaultTypeValue)	/* 16 */
+	values[i] = (Datum) textin(PointerIsValid(defaultTypeValue)	/* 17 */
 							   ? defaultTypeValue : "-"); /* XXX default
 														   * typdefault */
 
diff --git a/src/backend/commands/command.c b/src/backend/commands/command.c
index d0bd89fdfd2efbb67c041dfe7bcd9c243555c62b..595c09dc4ec88859ed8519c7e4e374b075b3ed42 100644
--- a/src/backend/commands/command.c
+++ b/src/backend/commands/command.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/commands/Attic/command.c,v 1.81 2000/06/28 03:31:28 tgl Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/commands/Attic/command.c,v 1.82 2000/07/03 23:09:33 wieck Exp $
  *
  * NOTES
  *	  The PerformAddAttribute() code, like most of the relation
@@ -35,6 +35,7 @@
 #include "catalog/pg_index.h"
 #include "parser/parse.h"
 #endif	 /* _DROP_COLUMN_HACK__ */
+#include "access/genam.h"
 
 
 /* --------------------------------
@@ -438,7 +439,7 @@ AlterTableAddColumn(const char *relationName,
 		attribute->attbyval = tform->typbyval;
 		attribute->attnelems = attnelems;
 		attribute->attisset = (bool) (tform->typtype == 'c');
-		attribute->attstorage = 'p';
+		attribute->attstorage = tform->typstorage;
 		attribute->attalign = tform->typalign;
 		attribute->attnotnull = false;
 		attribute->atthasdef = (colDef->raw_default != NULL ||
@@ -1170,6 +1171,159 @@ AlterTableDropConstraint(const char *relationName,
 
 
 
+/*
+ * ALTER TABLE CREATE TOAST TABLE
+ */
+void
+AlterTableCreateToastTable(const char *relationName)
+{
+	Relation			rel;
+	Oid					myrelid;
+	HeapTuple			reltup;
+	TupleDesc			tupdesc;
+	Form_pg_attribute  *att;
+	Relation			class_rel;
+	Relation			ridescs[Num_pg_class_indices];
+	Oid					toast_relid = 2;
+	Oid					toast_idxid = 2;
+	bool				has_toastable_attrs = false;
+	bool				old_allow;
+	int					i;
+
+	char				toast_relname[NAMEDATALEN];
+	char				toast_idxname[NAMEDATALEN];
+	char				tmp_query[1024];
+	Relation			toast_rel;
+
+	/*
+	 * permissions checking.  this would normally be done in utility.c,
+	 * but this particular routine is recursive.
+	 *
+	 * normally, only the owner of a class can change its schema.
+	 */
+/*
+	if (!allowSystemTableMods && IsSystemRelationName(relationName))
+		elog(ERROR, "ALTER TABLE: relation \"%s\" is a system catalog",
+			 relationName);
+*/
+#ifndef NO_SECURITY
+	if (!pg_ownercheck(UserName, relationName, RELNAME))
+		elog(ERROR, "ALTER TABLE: permission denied");
+#endif
+
+	/*
+	 * Grab an exclusive lock on the target table, which we will NOT
+	 * release until end of transaction.
+	 */
+	rel = heap_openr(relationName, RowExclusiveLock);
+	myrelid = RelationGetRelid(rel);
+
+	/*
+	 * Check if there are any toastable attributes on the table
+	 */
+	tupdesc = rel->rd_att;
+	att = tupdesc->attrs;
+	for (i = 0; i < tupdesc->natts; i++)
+	{
+		if (att[i]->attstorage != 'p')
+		{
+			has_toastable_attrs = true;
+			break;
+		}
+	}
+
+	if (!has_toastable_attrs)
+		elog(ERROR, "ALTER TABLE: relation \"%s\" has no toastable attributes",
+				relationName);
+
+	/*
+	 * Get the pg_class tuple for the relation
+	 */
+	reltup = SearchSysCacheTuple(RELNAME,
+									 PointerGetDatum(relationName),
+									 0, 0, 0);
+
+	if (!HeapTupleIsValid(reltup))
+		elog(ERROR, "ALTER TABLE: relation \"%s\" not found",
+			 relationName);
+
+	/*
+	 * XXX is the following check sufficient?
+	 */
+	if (((Form_pg_class) GETSTRUCT(reltup))->relkind != RELKIND_RELATION)
+	{
+		elog(ERROR, "ALTER TABLE: relation \"%s\" is not a table",
+				relationName);
+	}
+
+	if (((Form_pg_class) GETSTRUCT(reltup))->reltoastrelid != InvalidOid)
+		elog(ERROR, "ALTER TABLE: relation \"%s\" already has a toast table",
+				relationName);
+
+	/*
+	 * Create the toast table and it's index
+	 * This is bad and ugly, because we need to override
+	 * allowSystemTableMods in order to keep the toast
+	 * table- and index-name out of the users namespace.
+	 */
+	sprintf(toast_relname, "pg_toast_%d", myrelid);
+	sprintf(toast_idxname, "pg_toast_%d_idx", myrelid);
+
+	old_allow = allowSystemTableMods;
+	allowSystemTableMods = true;
+
+	sprintf(tmp_query, "create table \"%s\" (chunk_id oid, chunk_seq int4, chunk_data text)",
+			toast_relname);
+	pg_exec_query_dest(tmp_query, None, CurrentMemoryContext);
+
+	sprintf(tmp_query, "create index \"%s\" on \"%s\" (chunk_id)",
+			toast_idxname, toast_relname);
+	pg_exec_query_dest(tmp_query, None, CurrentMemoryContext);
+
+	allowSystemTableMods = old_allow;
+
+	/*
+	 * Get the OIDs of the newly created objects
+	 */
+	toast_rel = heap_openr(toast_relname, NoLock);
+	toast_relid = RelationGetRelid(toast_rel);
+	heap_close(toast_rel, NoLock);
+	toast_rel = index_openr(toast_idxname);
+	toast_idxid = RelationGetRelid(toast_rel);
+	index_close(toast_rel);
+
+	/*
+	 * Get the pg_class tuple for the relation
+	 */
+	class_rel = heap_openr(RelationRelationName, RowExclusiveLock);
+
+	reltup = SearchSysCacheTupleCopy(RELNAME,
+									 PointerGetDatum(relationName),
+									 0, 0, 0);
+	if (!HeapTupleIsValid(reltup))
+		elog(ERROR, "ALTER TABLE: relation \"%s\" not found",
+			 relationName);
+
+	/*
+	 * Store the toast table- and index-Oid's in the relation tuple
+	 */
+	((Form_pg_class) GETSTRUCT(reltup))->reltoastrelid = toast_relid;
+	((Form_pg_class) GETSTRUCT(reltup))->reltoastidxid = toast_idxid;
+	heap_update(class_rel, &reltup->t_self, reltup, NULL);
+
+	/* keep catalog indices current */
+	CatalogOpenIndices(Num_pg_class_indices, Name_pg_class_indices, ridescs);
+	CatalogIndexInsert(ridescs, Num_pg_class_indices, rel, reltup);
+	CatalogCloseIndices(Num_pg_class_indices, ridescs);
+
+	heap_freetuple(reltup);
+
+	heap_close(rel, NoLock);
+	heap_close(class_rel, NoLock);
+}
+
+
+
 /*
  *
  * LOCK TABLE
diff --git a/src/backend/commands/define.c b/src/backend/commands/define.c
index da8728721756d8728cd5b864880b7f5d810ad2aa..d3da6cc2b27202e766ebd934835fc527372fbc0d 100644
--- a/src/backend/commands/define.c
+++ b/src/backend/commands/define.c
@@ -10,7 +10,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/commands/define.c,v 1.43 2000/05/28 17:55:55 tgl Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/commands/define.c,v 1.44 2000/07/03 23:09:33 wieck Exp $
  *
  * DESCRIPTION
  *	  The "DefineFoo" routines take the parse tree and pick out the
@@ -597,6 +597,7 @@ DefineType(char *typeName, List *parameters)
 	char	   *shadow_type;
 	List	   *pl;
 	char		alignment = 'i';/* default alignment */
+	char		storage = 'p'; /* default storage in TOAST */
 
 	/*
 	 * Type names can only be 15 characters long, so that the shadow type
@@ -650,6 +651,24 @@ DefineType(char *typeName, List *parameters)
 					 a);
 			}
 		}
+		else if (!strcasecmp(defel->defname, "storage"))
+		{
+			char	   *a = defGetString(defel);
+
+			if (!strcasecmp(a, "plain"))
+				storage = 'p';
+			else if (!strcasecmp(a, "external"))
+				storage = 'e';
+			else if (!strcasecmp(a, "extended"))
+				storage = 'x';
+			else if (!strcasecmp(a, "main"))
+				storage = 'm';
+			else
+			{
+				elog(ERROR, "DefineType: \"%s\" storage not recognized",
+					 a);
+			}
+		}
 		else
 		{
 			elog(NOTICE, "DefineType: attribute \"%s\" not recognized",
@@ -665,6 +684,9 @@ DefineType(char *typeName, List *parameters)
 	if (outputName == NULL)
 		elog(ERROR, "Define: \"output\" unspecified");
 
+	if (internalLength != -1 && storage != 'p')
+		elog(ERROR, "Define: fixed size types must have storage PLAIN");
+
 	/* ----------------
 	 *	now have TypeCreate do all the real work.
 	 * ----------------
@@ -682,7 +704,8 @@ DefineType(char *typeName, List *parameters)
 			   elemName,		/* element type name */
 			   defaultValue,	/* default type value */
 			   byValue,			/* passed by value */
-			   alignment);
+			   alignment,
+			   storage);		/* TOAST strategy */
 
 	/* ----------------
 	 *	When we create a true type (as opposed to a complex type)
@@ -704,7 +727,8 @@ DefineType(char *typeName, List *parameters)
 			   typeName,		/* element type name */
 			   defaultValue,	/* default type value */
 			   false,			/* never passed by value */
-			   alignment);
+			   alignment,
+			   'p');			/* ARRAY doesn't support TOAST yet */
 
 	pfree(shadow_type);
 }
diff --git a/src/backend/libpq/be-fsstubs.c b/src/backend/libpq/be-fsstubs.c
index 75f6562a8f6c7062d89ac6b41f56867243554470..91769120f959edfa2a3972e0d0c75e8b119c2d85 100644
--- a/src/backend/libpq/be-fsstubs.c
+++ b/src/backend/libpq/be-fsstubs.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/libpq/be-fsstubs.c,v 1.47 2000/06/28 03:31:41 tgl Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/libpq/be-fsstubs.c,v 1.48 2000/07/03 23:09:37 wieck Exp $
  *
  * NOTES
  *	  This should be moved to a more appropriate place.  It is here
@@ -331,7 +331,7 @@ loread(PG_FUNCTION_ARGS)
 
 	retval = (struct varlena *) palloc(VARHDRSZ + len);
 	totalread = lo_read(fd, VARDATA(retval), len);
-	VARSIZE(retval) = totalread + VARHDRSZ;
+	VARATT_SIZEP(retval) = totalread + VARHDRSZ;
 
 	PG_RETURN_POINTER(retval);
 }
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index b17185e4639efd8bf8386f5e0fccbba2d366c249..98a00acb8fc0df88d39346a558167afe67d981d9 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -11,7 +11,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.174 2000/06/22 22:31:18 petere Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/parser/gram.y,v 2.175 2000/07/03 23:09:41 wieck Exp $
  *
  * HISTORY
  *	  AUTHOR			DATE			MAJOR EVENT
@@ -350,7 +350,7 @@ static void doNegateFloat(Value *v);
 		OFFSET, OIDS, OPERATOR, PASSWORD, PROCEDURAL,
 		REINDEX, RENAME, RESET, RETURNS, ROW, RULE,
 		SEQUENCE, SERIAL, SETOF, SHARE, SHOW, START, STATEMENT, STDIN, STDOUT, SYSID,
-		TEMP, TRUNCATE, TRUSTED, 
+		TEMP, TOAST, TRUNCATE, TRUSTED, 
 		UNLISTEN, UNTIL, VACUUM, VALID, VERBOSE, VERSION
 
 /* Special keywords, not in the query language - see the "lex" file */
@@ -931,6 +931,14 @@ AlterTableStmt:
 					n->behavior = $8;
 					$$ = (Node *)n;
 				}
+/* ALTER TABLE <name> CREATE TOAST TABLE */
+		| ALTER TABLE relation_name CREATE TOAST TABLE
+				{
+					AlterTableStmt *n = makeNode(AlterTableStmt);
+					n->subtype = 'E';
+					n->relname = $3;
+					$$ = (Node *)n;
+				}
 		;
 
 alter_column_action:
@@ -5460,6 +5468,7 @@ TokenId:  ABSOLUTE						{ $$ = "absolute"; }
 		| TEMPORARY						{ $$ = "temporary"; }
 		| TIMEZONE_HOUR					{ $$ = "timezone_hour"; }
 		| TIMEZONE_MINUTE				{ $$ = "timezone_minute"; }
+		| TOAST							{ $$ = "toast"; }
 		| TRIGGER						{ $$ = "trigger"; }
 		| TRUNCATE						{ $$ = "truncate"; }
 		| TRUSTED						{ $$ = "trusted"; }
diff --git a/src/backend/parser/keywords.c b/src/backend/parser/keywords.c
index 76428b969c54ede44a2c39127cb5fb75dc1213ac..982ca9116dc481a1eeec5fad34380c6bcfae404a 100644
--- a/src/backend/parser/keywords.c
+++ b/src/backend/parser/keywords.c
@@ -9,9 +9,9 @@
  *
  * IDENTIFICATION
 <<<<<<< keywords.c
- *	  $Header: /cvsroot/pgsql/src/backend/parser/keywords.c,v 1.77 2000/06/12 19:40:41 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/parser/keywords.c,v 1.78 2000/07/03 23:09:43 wieck Exp $
 =======
- *	  $Header: /cvsroot/pgsql/src/backend/parser/keywords.c,v 1.77 2000/06/12 19:40:41 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/parser/keywords.c,v 1.78 2000/07/03 23:09:43 wieck Exp $
 >>>>>>> 1.73
  *
  *-------------------------------------------------------------------------
@@ -245,6 +245,7 @@ static ScanKeyword ScanKeywords[] = {
 	{"timezone_hour", TIMEZONE_HOUR},
 	{"timezone_minute", TIMEZONE_MINUTE},
 	{"to", TO},
+	{"toast", TOAST},
 	{"trailing", TRAILING},
 	{"transaction", TRANSACTION},
 	{"trigger", TRIGGER},
diff --git a/src/backend/tcop/fastpath.c b/src/backend/tcop/fastpath.c
index cbba1223555731e93243bfe1d07f5c625a042b8c..fd30bd58ac555ce04a75719a9be659041b1df76a 100644
--- a/src/backend/tcop/fastpath.c
+++ b/src/backend/tcop/fastpath.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/tcop/fastpath.c,v 1.42 2000/06/15 04:10:18 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/tcop/fastpath.c,v 1.43 2000/07/03 23:09:46 wieck Exp $
  *
  * NOTES
  *	  This cruft is the server side of PQfn.
@@ -349,7 +349,7 @@ HandleFunctionRequest()
 				p = palloc(argsize + VARHDRSZ + 1);	/* Added +1 to solve
 													 * memory leak - Peter
 													 * 98 Jan 6 */
-				VARSIZE(p) = argsize + VARHDRSZ;
+				VARATT_SIZEP(p) = argsize + VARHDRSZ;
 				if (pq_getbytes(VARDATA(p), argsize))
 					return EOF;
 			}
diff --git a/src/backend/tcop/utility.c b/src/backend/tcop/utility.c
index 2459b6507cdbb29f82340051232b31b0a6cd3723..17c77da8504b93190c7bb58a43dc548efc5fde10 100644
--- a/src/backend/tcop/utility.c
+++ b/src/backend/tcop/utility.c
@@ -10,7 +10,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/tcop/utility.c,v 1.89 2000/06/04 01:44:33 petere Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/tcop/utility.c,v 1.90 2000/07/03 23:09:46 wieck Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -360,6 +360,9 @@ ProcessUtility(Node *parsetree,
 					case 'X':	/* DROP CONSTRAINT */
 						AlterTableDropConstraint(stmt->relname, stmt->inh, stmt->name, stmt->behavior);
 						break;
+					case 'E':	/* CREATE TOAST TABLE */
+						AlterTableCreateToastTable(stmt->relname);
+						break;
 					default:	/* oops */
 						elog(ERROR, "T_AlterTableStmt: unknown subtype");
 						break;
diff --git a/src/backend/utils/adt/arrayfuncs.c b/src/backend/utils/adt/arrayfuncs.c
index fe96d77f43a780ee015659428a657992adb33659..3fc0061304251770df9fd82d6bba92121130f100 100644
--- a/src/backend/utils/adt/arrayfuncs.c
+++ b/src/backend/utils/adt/arrayfuncs.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/utils/adt/arrayfuncs.c,v 1.59 2000/06/14 18:17:42 petere Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/utils/adt/arrayfuncs.c,v 1.60 2000/07/03 23:09:50 wieck Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -813,7 +813,7 @@ array_dims(PG_FUNCTION_ARGS)
 		sprintf(p, "[%d:%d]", lb[i], dimv[i] + lb[i] - 1);
 		p += strlen(p);
 	}
-	VARSIZE(result) = strlen(VARDATA(result)) + VARHDRSZ;
+	VARATT_SIZEP(result) = strlen(VARDATA(result)) + VARHDRSZ;
 
 	PG_RETURN_TEXT_P(result);
 }
@@ -1151,7 +1151,7 @@ array_set(ArrayType *array,
 							  Int32GetDatum(SEEK_SET))) < 0)
 			return array;
 		v = (struct varlena *) palloc(elmlen + VARHDRSZ);
-		VARSIZE(v) = elmlen + VARHDRSZ;
+		VARATT_SIZEP(v) = elmlen + VARHDRSZ;
 		ArrayCastAndSet(dataValue, elmbyval, elmlen, VARDATA(v));
 #ifdef LOARRAY
 		if (DatumGetInt32(DirectFunctionCall2(lowrite,
diff --git a/src/backend/utils/adt/cash.c b/src/backend/utils/adt/cash.c
index 484b8e8f94283ad5457d795c11247a82c068ef92..09237e5275512a956322f376c26b69609a64f863 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.40 2000/06/15 03:32:28 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/adt/cash.c,v 1.41 2000/07/03 23:09:50 wieck Exp $
  */
 
 #include <limits.h>
@@ -730,7 +730,7 @@ cash_words_out(Cash *value)
 
 	/* make a text type for output */
 	result = (text *) palloc(strlen(buf) + VARHDRSZ);
-	VARSIZE(result) = strlen(buf) + VARHDRSZ;
+	VARATT_SIZEP(result) = strlen(buf) + VARHDRSZ;
 	memcpy(VARDATA(result), buf, strlen(buf));
 
 	return result;
diff --git a/src/backend/utils/adt/char.c b/src/backend/utils/adt/char.c
index 04e40406f8bfa01fe4c4869dcb12a63bb99d3bbe..b2c3080ca3c833f71655b5ea05b043dc7e2b93ff 100644
--- a/src/backend/utils/adt/char.c
+++ b/src/backend/utils/adt/char.c
@@ -9,7 +9,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/utils/adt/char.c,v 1.28 2000/06/05 07:28:51 tgl Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/utils/adt/char.c,v 1.29 2000/07/03 23:09:50 wieck Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -162,7 +162,7 @@ char_text(PG_FUNCTION_ARGS)
 	char		arg1 = PG_GETARG_CHAR(0);
 	text	   *result = palloc(VARHDRSZ + 1);
 
-	VARSIZE(result) = VARHDRSZ + 1;
+	VARATT_SIZEP(result) = VARHDRSZ + 1;
 	*(VARDATA(result)) = arg1;
 
 	PG_RETURN_TEXT_P(result);
diff --git a/src/backend/utils/adt/float.c b/src/backend/utils/adt/float.c
index f8c3a3f1560892588870622032cc8282a49a8775..f618a10eb8ecce6e3e6b0896866d439c49e9bcb6 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.61 2000/06/14 18:17:42 petere Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/utils/adt/float.c,v 1.62 2000/07/03 23:09:50 wieck Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -953,7 +953,7 @@ float8_text(float64 num)
 
 	result = palloc(len);
 
-	VARSIZE(result) = len;
+	VARATT_SIZEP(result) = len;
 	memmove(VARDATA(result), str, (len - VARHDRSZ));
 
 	pfree(str);
@@ -998,7 +998,7 @@ float4_text(float32 num)
 
 	result = palloc(len);
 
-	VARSIZE(result) = len;
+	VARATT_SIZEP(result) = len;
 	memmove(VARDATA(result), str, (len - VARHDRSZ));
 
 	pfree(str);
diff --git a/src/backend/utils/adt/formatting.c b/src/backend/utils/adt/formatting.c
index 2d1ae16c5eb452c739f25d6a5af7a4fcff5156d7..cf7d3618426a004de6ffdd12eaf640828ef5affc 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.17 2000/07/03 16:01:30 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/adt/formatting.c,v 1.18 2000/07/03 23:09:50 wieck Exp $
  *
  *
  *	 Portions Copyright (c) 1999-2000, PostgreSQL, Inc
@@ -2526,7 +2526,7 @@ timestamp_to_char(PG_FUNCTION_ARGS)
 	result = (text *) palloc(len + 1 + VARHDRSZ);
 
 	strcpy(VARDATA(result), VARDATA(result_tmp));
-	VARSIZE(result) = len + VARHDRSZ;
+	VARATT_SIZEP(result) = len + VARHDRSZ;
 	pfree(result_tmp);
 
 	PG_RETURN_TEXT_P(result);
@@ -3987,7 +3987,7 @@ do { \
 	result		= (text *) palloc( len + 1 + VARHDRSZ);		\
 									\
 	strcpy( VARDATA(result), VARDATA(result_tmp));			\
-	VARSIZE(result) = len + VARHDRSZ;				\
+	VARATT_SIZEP(result) = len + VARHDRSZ;				\
 	pfree(result_tmp);						\
 } while(0)
 
diff --git a/src/backend/utils/adt/int.c b/src/backend/utils/adt/int.c
index b5f66f1118835f3849902cda87c3bc131887be69..7029ca73b893b7a3b0138fe8a591ee8563365576 100644
--- a/src/backend/utils/adt/int.c
+++ b/src/backend/utils/adt/int.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/utils/adt/int.c,v 1.38 2000/06/14 18:17:44 petere Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/utils/adt/int.c,v 1.39 2000/07/03 23:09:52 wieck Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -263,7 +263,7 @@ int2_text(PG_FUNCTION_ARGS)
 	text	   *result = (text *) palloc(7+VARHDRSZ); /* sign,5 digits, '\0' */
 
 	itoa((int) arg1, VARDATA(result));
-	VARSIZE(result) = strlen(VARDATA(result)) + VARHDRSZ;
+	VARATT_SIZEP(result) = strlen(VARDATA(result)) + VARHDRSZ;
 	PG_RETURN_TEXT_P(result);
 }
 
@@ -294,7 +294,7 @@ int4_text(PG_FUNCTION_ARGS)
 	text	   *result = (text *) palloc(12+VARHDRSZ); /* sign,10 digits,'\0' */
 
 	ltoa(arg1, VARDATA(result));
-	VARSIZE(result) = strlen(VARDATA(result)) + VARHDRSZ;
+	VARATT_SIZEP(result) = strlen(VARDATA(result)) + VARHDRSZ;
 	PG_RETURN_TEXT_P(result);
 }
 
diff --git a/src/backend/utils/adt/int8.c b/src/backend/utils/adt/int8.c
index ea29ffaff55f60d8c4d87880c9e40b3bb5e6671c..63c0938461269633b52609511c23b608331c5233 100644
--- a/src/backend/utils/adt/int8.c
+++ b/src/backend/utils/adt/int8.c
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/utils/adt/int8.c,v 1.21 2000/06/14 18:17:44 petere Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/utils/adt/int8.c,v 1.22 2000/07/03 23:09:52 wieck Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -581,7 +581,7 @@ int8_text(PG_FUNCTION_ARGS)
 
 	result = (text *) palloc(VARHDRSZ + len);
 
-	VARSIZE(result) = len + VARHDRSZ;
+	VARATT_SIZEP(result) = len + VARHDRSZ;
 	memcpy(VARDATA(result), s, len);
 
 	pfree(s);
diff --git a/src/backend/utils/adt/lztext.c b/src/backend/utils/adt/lztext.c
index 4442d00351f35db8f9e2f0cba76d7936c7fe6852..412445e727f10153409ef676ca72d5386dc0f70d 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.7 2000/05/30 00:49:53 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/adt/Attic/lztext.c,v 1.8 2000/07/03 23:09:52 wieck Exp $
  *
  *	Text type with internal LZ compressed representation. Uses the
  *	standard PostgreSQL compression method.
@@ -34,8 +34,6 @@ lztextin(char *str)
 {
 	lztext	   *result;
 	int32		rawsize;
-	lztext	   *tmp;
-	int			tmp_size;
 
 	/* ----------
 	 * Handle NULL
@@ -44,35 +42,11 @@ lztextin(char *str)
 	if (str == NULL)
 		return NULL;
 
-	/* ----------
-	 * Determine input size and maximum output Datum size
-	 * ----------
-	 */
 	rawsize = strlen(str);
-	tmp_size = PGLZ_MAX_OUTPUT(rawsize);
-
-	/* ----------
-	 * Allocate a temporary result and compress into it
-	 * ----------
-	 */
-	tmp = (lztext *) palloc(tmp_size);
-	pglz_compress(str, rawsize, tmp, NULL);
+	result  = (lztext *)palloc(VARHDRSZ + rawsize);
 
-	/* ----------
-	 * If we miss less than 25% bytes at the end of the temp value,
-	 * so be it. Therefore we save a palloc()/memcpy()/pfree()
-	 * sequence.
-	 * ----------
-	 */
-	if (tmp_size - tmp->varsize < 256 ||
-		tmp_size - tmp->varsize < tmp_size / 4)
-		result = tmp;
-	else
-	{
-		result = (lztext *) palloc(tmp->varsize);
-		memcpy(result, tmp, tmp->varsize);
-		pfree(tmp);
-	}
+	VARATT_SIZEP(result) = VARHDRSZ + rawsize;
+	memcpy(VARATT_DATA(result), str, rawsize);
 
 	return result;
 }
@@ -88,6 +62,8 @@ char *
 lztextout(lztext *lz)
 {
 	char	   *result;
+	void	   *tmp;
+	int32		rawsize;
 
 	/* ----------
 	 * Handle NULL
@@ -101,25 +77,15 @@ lztextout(lztext *lz)
 		return result;
 	}
 
-	/* ----------
-	 * Allocate the result string - the required size is remembered
-	 * in the lztext header so we don't need a temporary buffer or
-	 * have to diddle with realloc's.
-	 * ----------
-	 */
-	result = (char *) palloc(PGLZ_RAW_SIZE(lz) + 1);
+	VARATT_GETPLAIN(lz, tmp);
 
-	/* ----------
-	 * Decompress and add terminating ZERO
-	 * ----------
-	 */
-	pglz_decompress(lz, result);
-	result[lz->rawsize] = '\0';
+	rawsize = VARATT_SIZE(tmp) - VARHDRSZ;
+	result  = (char *)palloc(rawsize + 1);
+	memcpy(result, VARATT_DATA(tmp), rawsize);
+	result[rawsize] = '\0';
+
+	VARATT_FREE(lz, tmp);
 
-	/* ----------
-	 * Return the result
-	 * ----------
-	 */
 	return result;
 }
 
@@ -167,7 +133,13 @@ lztextlen(lztext *lz)
 	 * without multibyte support, it's the remembered rawsize
 	 * ----------
 	 */
-	return PGLZ_RAW_SIZE(lz);
+	if (!VARATT_IS_EXTENDED(lz))
+	    return VARATT_SIZE(lz) - VARHDRSZ;
+
+    if (VARATT_IS_EXTERNAL(lz))
+	    return lz->va_content.va_external.va_rawsize;
+
+	return lz->va_content.va_compressed.va_rawsize;
 #endif
 }
 
@@ -189,11 +161,10 @@ lztextoctetlen(lztext *lz)
 	if (lz == NULL)
 		return 0;
 
-	/* ----------
-	 * Return the varsize minus the VARSIZE field itself.
-	 * ----------
-	 */
-	return VARSIZE(lz) - VARHDRSZ;
+	if (!VARATT_IS_EXTERNAL(lz))
+	    return VARATT_SIZE(lz) - VARHDRSZ;
+
+	return lz->va_content.va_external.va_extsize;
 }
 
 
@@ -208,9 +179,6 @@ text_lztext(text *txt)
 {
 	lztext	   *result;
 	int32		rawsize;
-	lztext	   *tmp;
-	int			tmp_size;
-	char	   *str;
 
 	/* ----------
 	 * Handle NULL
@@ -220,35 +188,13 @@ text_lztext(text *txt)
 		return NULL;
 
 	/* ----------
-	 * Determine input size and eventually tuple size
+	 * Copy the entire attribute
 	 * ----------
 	 */
 	rawsize = VARSIZE(txt) - VARHDRSZ;
-	str = VARDATA(txt);
-	tmp_size = PGLZ_MAX_OUTPUT(rawsize);
-
-	/* ----------
-	 * Allocate a temporary result and compress into it
-	 * ----------
-	 */
-	tmp = (lztext *) palloc(tmp_size);
-	pglz_compress(str, rawsize, tmp, NULL);
-
-	/* ----------
-	 * If we miss less than 25% bytes at the end of the temp value,
-	 * so be it. Therefore we save a palloc()/memcpy()/pfree()
-	 * sequence.
-	 * ----------
-	 */
-	if (tmp_size - tmp->varsize < 256 ||
-		tmp_size - tmp->varsize < tmp_size / 4)
-		result = tmp;
-	else
-	{
-		result = (lztext *) palloc(tmp->varsize);
-		memcpy(result, tmp, tmp->varsize);
-		pfree(tmp);
-	}
+	result  = (lztext *)palloc(rawsize + VARHDRSZ);
+	VARATT_SIZEP(result) = rawsize + VARHDRSZ;
+	memcpy(VARATT_DATA(result), VARATT_DATA(txt), rawsize);
 
 	return result;
 }
@@ -264,6 +210,8 @@ text *
 lztext_text(lztext *lz)
 {
 	text	   *result;
+	lztext	   *tmp;
+	int32		rawsize;
 
 	/* ----------
 	 * Handle NULL
@@ -272,19 +220,14 @@ lztext_text(lztext *lz)
 	if (lz == NULL)
 		return NULL;
 
-	/* ----------
-	 * Allocate and initialize the text result
-	 * ----------
-	 */
-	result = (text *) palloc(PGLZ_RAW_SIZE(lz) + VARHDRSZ + 1);
-	VARSIZE(result) = lz->rawsize + VARHDRSZ;
+	VARATT_GETPLAIN(lz, tmp);
+	
+	rawsize = VARATT_SIZE(tmp) - VARHDRSZ;
+	result  = (text *)palloc(rawsize + VARHDRSZ);
+	VARATT_SIZEP(result) = rawsize + VARHDRSZ;
+	memcpy(VARATT_DATA(result), VARATT_DATA(tmp), rawsize);
 
-	/* ----------
-	 * Decompress directly into the text data area.
-	 * ----------
-	 */
-	VARDATA(result)[lz->rawsize] = 0;
-	pglz_decompress(lz, VARDATA(result));
+	VARATT_FREE(lz, tmp);
 
 	return result;
 }
@@ -322,43 +265,32 @@ lztext_cmp(lztext *lz1, lztext *lz2)
 
 #else							/* !USE_LOCALE */
 
-	PGLZ_DecompState ds1;
-	PGLZ_DecompState ds2;
-	int			c1;
-	int			c2;
-	int32		result = (int32) 0;
+	int		result;
+	char   *p1 = NULL;
+	char   *p2 = NULL;
+	int		size1;
+	int		size2;
 
 	if (lz1 == NULL || lz2 == NULL)
-		return (int32) 0;
-
-	pglz_decomp_init(&ds1, lz1);
-	pglz_decomp_init(&ds2, lz2);
-
-	for (;;)
-	{
-		c1 = pglz_decomp_getchar(&ds1);
-		c2 = pglz_decomp_getchar(&ds2);
-
-		if (c1 == EOF)
-		{
-			if (c2 != EOF)
-				result = (int32) -1;
-			break;
-		}
-		else
-		{
-			if (c2 == EOF)
-				result = (int32) 1;
-		}
-		if (c1 != c2)
-		{
-			result = (int32) (c1 - c2);
-			break;
-		}
-	}
+		return 0;
 
-	pglz_decomp_end(&ds1);
-	pglz_decomp_end(&ds2);
+	VARATT_GETPLAIN(lz1, p1);
+	VARATT_GETPLAIN(lz2, p2);
+
+    size1 = VARATT_SIZE(p1) - VARHDRSZ;
+    size2 = VARATT_SIZE(p2) - VARHDRSZ;
+    result = memcmp(VARATT_DATA(p1), VARATT_DATA(p2),
+                (size1 < size2) ? size1 : size2);
+    if (result == 0)
+    {
+        if (size1 > size2)
+            result = 1;
+        else if (size1 < size2)
+            result = -1;
+    }
+
+    VARATT_FREE(lz2, p2);
+    VARATT_FREE(lz1, p1);
 
 	return result;
 
diff --git a/src/backend/utils/adt/mac.c b/src/backend/utils/adt/mac.c
index 02fc1863b60055b6fbfb14d01da1ca93457a5fe4..9d880a4aa69a1586d6cab1d433efc0891c77662b 100644
--- a/src/backend/utils/adt/mac.c
+++ b/src/backend/utils/adt/mac.c
@@ -1,7 +1,7 @@
 /*
  *	PostgreSQL type definitions for MAC addresses.
  *
- *	$Id: mac.c,v 1.14 1999/12/16 01:30:49 momjian Exp $
+ *	$Id: mac.c,v 1.15 2000/07/03 23:09:52 wieck Exp $
  */
 
 
@@ -314,14 +314,14 @@ macaddr_manuf(macaddr *addr)
 	{
 		result = palloc(VARHDRSZ + 1);
 		memset(result, 0, VARHDRSZ + 1);
-		VARSIZE(result) = VARHDRSZ + 1;
+		VARATT_SIZEP(result) = VARHDRSZ + 1;
 	}
 	else
 	{
 		length = strlen(manuf->name) + 1;
 		result = palloc(length + VARHDRSZ);
 		memset(result, 0, length + VARHDRSZ);
-		VARSIZE(result) = length + VARHDRSZ;
+		VARATT_SIZEP(result) = length + VARHDRSZ;
 		memcpy(VARDATA(result), manuf->name, length);
 	}
 	return result;
diff --git a/src/backend/utils/adt/nabstime.c b/src/backend/utils/adt/nabstime.c
index 9a666ebd7088ee0bb7f4bb2cff0bf4819ccbf004..720517c953651db32d8a36ab98da59a8b5849154 100644
--- a/src/backend/utils/adt/nabstime.c
+++ b/src/backend/utils/adt/nabstime.c
@@ -9,7 +9,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/utils/adt/nabstime.c,v 1.70 2000/06/27 18:08:49 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/utils/adt/nabstime.c,v 1.71 2000/07/03 23:09:52 wieck Exp $
  *
  * NOTES
  *
@@ -1945,7 +1945,7 @@ timeofday(PG_FUNCTION_ARGS)
 
 	len = VARHDRSZ + strlen(buf);
 	result = (text *) palloc(len);
-	VARSIZE(result) = len;
+	VARATT_SIZEP(result) = len;
 	memcpy(VARDATA(result), buf, strlen(buf));
 	PG_RETURN_TEXT_P(result);
 }
diff --git a/src/backend/utils/adt/network.c b/src/backend/utils/adt/network.c
index 7e1a9ead6664840788bd7bb61ecc307f24cf8d24..a5127ece26f4cd537ad53dc0c78fbd0545125fc1 100644
--- a/src/backend/utils/adt/network.c
+++ b/src/backend/utils/adt/network.c
@@ -3,7 +3,7 @@
  *	is for IP V4 CIDR notation, but prepared for V6: just
  *	add the necessary bits where the comments indicate.
  *
- *	$Id: network.c,v 1.21 2000/04/12 17:15:50 momjian Exp $
+ *	$Id: network.c,v 1.22 2000/07/03 23:09:52 wieck Exp $
  *	Jon Postel RIP 16 Oct 1998
  */
 
@@ -61,7 +61,7 @@ network_in(char *src, int type)
 		/* Go for an IPV6 address here, before faulting out: */
 		elog(ERROR, "could not parse \"%s\"", src);
 
-	VARSIZE(dst) = VARHDRSZ
+	VARATT_SIZEP(dst) = VARHDRSZ
 		+ ((char *) &ip_v4addr(dst) - (char *) VARDATA(dst))
 		+ ip_addrsize(dst);
 	ip_bits(dst) = bits;
@@ -346,7 +346,7 @@ network_host(inet *ip)
 	if (ret == NULL)
 		elog(ERROR, "unable to allocate memory in network_host()");
 
-	VARSIZE(ret) = len;
+	VARATT_SIZEP(ret) = len;
 	strcpy(VARDATA(ret), tmp);
 	return (ret);
 }
@@ -396,7 +396,7 @@ network_broadcast(inet *ip)
 	if (ret == NULL)
 		elog(ERROR, "unable to allocate memory in network_broadcast()");
 
-	VARSIZE(ret) = len;
+	VARATT_SIZEP(ret) = len;
 	strcpy(VARDATA(ret), tmp);
 	return (ret);
 }
@@ -429,7 +429,7 @@ network_network(inet *ip)
 	if (ret == NULL)
 		elog(ERROR, "unable to allocate memory in network_network()");
 
-	VARSIZE(ret) = len;
+	VARATT_SIZEP(ret) = len;
 	strcpy(VARDATA(ret), tmp);
 	return (ret);
 }
@@ -466,7 +466,7 @@ network_netmask(inet *ip)
 	if (ret == NULL)
 		elog(ERROR, "unable to allocate memory in network_netmask()");
 
-	VARSIZE(ret) = len;
+	VARATT_SIZEP(ret) = len;
 	strcpy(VARDATA(ret), tmp);
 	return (ret);
 }
diff --git a/src/backend/utils/adt/oid.c b/src/backend/utils/adt/oid.c
index 156237862b18f79f91e869ce7d98604f083ff2e7..a51eadfc5ef5969ee70cf0224b34731f6c338e27 100644
--- a/src/backend/utils/adt/oid.c
+++ b/src/backend/utils/adt/oid.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/utils/adt/oid.c,v 1.36 2000/06/14 18:17:45 petere Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/utils/adt/oid.c,v 1.37 2000/07/03 23:09:52 wieck Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -231,7 +231,7 @@ oid_text(PG_FUNCTION_ARGS)
 
 	result = (text *) palloc(len);
 
-	VARSIZE(result) = len;
+	VARATT_SIZEP(result) = len;
 	memcpy(VARDATA(result), str, (len - VARHDRSZ));
 	pfree(str);
 
diff --git a/src/backend/utils/adt/oracle_compat.c b/src/backend/utils/adt/oracle_compat.c
index 4455c04c55651a37e0abf70151a02d31aaf4b355..5f0b1fa776a3062e6bd423345cef42413d317eef 100644
--- a/src/backend/utils/adt/oracle_compat.c
+++ b/src/backend/utils/adt/oracle_compat.c
@@ -1,7 +1,7 @@
 /*
  *	Edmund Mergl <E.Mergl@bawue.de>
  *
- *	$Id: oracle_compat.c,v 1.25 2000/06/13 07:35:07 tgl Exp $
+ *	$Id: oracle_compat.c,v 1.26 2000/07/03 23:09:52 wieck Exp $
  *
  */
 
@@ -37,7 +37,7 @@ lower(text *string)
 		return string;
 
 	ret = (text *) palloc(VARSIZE(string));
-	VARSIZE(ret) = VARSIZE(string);
+	VARATT_SIZEP(ret) = VARSIZE(string);
 
 	ptr = VARDATA(string);
 	ptr_ret = VARDATA(ret);
@@ -75,7 +75,7 @@ upper(text *string)
 		return string;
 
 	ret = (text *) palloc(VARSIZE(string));
-	VARSIZE(ret) = VARSIZE(string);
+	VARATT_SIZEP(ret) = VARSIZE(string);
 
 	ptr = VARDATA(string);
 	ptr_ret = VARDATA(ret);
@@ -115,7 +115,7 @@ initcap(text *string)
 		return string;
 
 	ret = (text *) palloc(VARSIZE(string));
-	VARSIZE(ret) = VARSIZE(string);
+	VARATT_SIZEP(ret) = VARSIZE(string);
 
 	ptr = VARDATA(string);
 	ptr_ret = VARDATA(ret);
@@ -169,7 +169,7 @@ lpad(PG_FUNCTION_ARGS)
 		PG_RETURN_TEXT_P(string1);
 
 	ret = (text *) palloc(VARHDRSZ + len);
-	VARSIZE(ret) = VARHDRSZ + len;
+	VARATT_SIZEP(ret) = VARHDRSZ + len;
 
 	ptr2 = VARDATA(string2);
 	ptr_ret = VARDATA(ret);
@@ -224,7 +224,7 @@ rpad(PG_FUNCTION_ARGS)
 		PG_RETURN_TEXT_P(string1);
 
 	ret = (text *) palloc(VARHDRSZ + len);
-	VARSIZE(ret) = VARHDRSZ + len;
+	VARATT_SIZEP(ret) = VARHDRSZ + len;
 
 	n = VARSIZE(string1) - VARHDRSZ;
 	ptr1 = VARDATA(string1);
@@ -316,7 +316,7 @@ btrim(text *string, text *set)
 	++m;
 
 	ret = (text *) palloc(VARHDRSZ + m);
-	VARSIZE(ret) = VARHDRSZ + m;
+	VARATT_SIZEP(ret) = VARHDRSZ + m;
 	memcpy(VARDATA(ret), ptr, m);
 
 	return ret;
@@ -374,7 +374,7 @@ ltrim(text *string, text *set)
 	++m;
 
 	ret = (text *) palloc(VARHDRSZ + m);
-	VARSIZE(ret) = VARHDRSZ + m;
+	VARATT_SIZEP(ret) = VARHDRSZ + m;
 
 	memcpy(VARDATA(ret), ptr, m);
 
@@ -434,7 +434,7 @@ rtrim(text *string, text *set)
 	++m;
 
 	ret = (text *) palloc(VARHDRSZ + m);
-	VARSIZE(ret) = VARHDRSZ + m;
+	VARATT_SIZEP(ret) = VARHDRSZ + m;
 #ifdef NOT_USED
 	memcpy(VARDATA(ret), ptr - VARSIZE(ret) + m, m);
 #endif
@@ -528,7 +528,7 @@ translate(text *string, text *from, text *to)
 		}
 	}
 
-	VARSIZE(result) = retlen + VARHDRSZ;
+	VARATT_SIZEP(result) = retlen + VARHDRSZ;
 
 	/*
 	 * There may be some wasted space in the result if deletions occurred,
@@ -560,7 +560,7 @@ ichar(PG_FUNCTION_ARGS)
 	text	   *result;
 
 	result = (text *) palloc(VARHDRSZ + 1);
-	VARSIZE(result) = VARHDRSZ + 1;
+	VARATT_SIZEP(result) = VARHDRSZ + 1;
 	*VARDATA(result) = (char) cvalue;
 
 	PG_RETURN_TEXT_P(result);
@@ -586,7 +586,7 @@ repeat(PG_FUNCTION_ARGS)
 
 	result = (text *) palloc(tlen);
 
-	VARSIZE(result) = tlen;
+	VARATT_SIZEP(result) = tlen;
 	cp = VARDATA(result);
 	for (i = 0; i < count; i++)
 	{
diff --git a/src/backend/utils/adt/pg_lzcompress.c b/src/backend/utils/adt/pg_lzcompress.c
index f4e6ac5be37dbd3a89d5540f991ba1d46d61446e..493b4e6446582aaf3cc230a4b4afc006779941e1 100644
--- a/src/backend/utils/adt/pg_lzcompress.c
+++ b/src/backend/utils/adt/pg_lzcompress.c
@@ -1,7 +1,7 @@
 /* ----------
  * pg_lzcompress.c -
  *
- * $Header: /cvsroot/pgsql/src/backend/utils/adt/pg_lzcompress.c,v 1.5 2000/05/30 00:49:53 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/adt/pg_lzcompress.c,v 1.6 2000/07/03 23:09:52 wieck Exp $
  *
  *		This is an implementation of LZ compression for PostgreSQL.
  *		It uses a simple history table and generates 2-3 byte tags
@@ -582,11 +582,15 @@ pglz_compress(char *source, int slen, PGLZ_Header *dest, PGLZ_Strategy *strategy
 	 * ----------
 	 */
 	if (do_compress)
-		return (dest->varsize = result_size + sizeof(PGLZ_Header));
+	{
+		dest->varsize = result_size + sizeof(PGLZ_Header);
+		return VARATT_SIZE(dest);
+	}
 	else
 	{
 		memcpy(((char *) dest) + sizeof(PGLZ_Header), source, slen);
-		return (dest->varsize = slen + sizeof(PGLZ_Header));
+		dest->varsize = slen + sizeof(PGLZ_Header);
+		return VARATT_SIZE(dest);
 	}
 }
 
@@ -609,10 +613,10 @@ pglz_decompress(PGLZ_Header *source, char *dest)
 	int32		off;
 
 	dp = ((unsigned char *) source) + sizeof(PGLZ_Header);
-	dend = ((unsigned char *) source) + source->varsize;
+	dend = ((unsigned char *) source) + VARATT_SIZE(source);
 	bp = (unsigned char *) dest;
 
-	if (source->varsize == source->rawsize + sizeof(PGLZ_Header))
+	if (VARATT_SIZE(source) == source->rawsize + sizeof(PGLZ_Header))
 	{
 		memcpy(dest, dp, source->rawsize);
 		return source->rawsize;
diff --git a/src/backend/utils/adt/regproc.c b/src/backend/utils/adt/regproc.c
index c5fbeadff6a3f565d8df5d951c0f9f867226f444..6660d15f1d6a3a72a21cb39301cd6a03a5306bbb 100644
--- a/src/backend/utils/adt/regproc.c
+++ b/src/backend/utils/adt/regproc.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/utils/adt/regproc.c,v 1.56 2000/06/05 07:28:52 tgl Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/utils/adt/regproc.c,v 1.57 2000/07/03 23:09:52 wieck Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -282,7 +282,7 @@ oidvectortypes(PG_FUNCTION_ARGS)
 		else
 			strcat(VARDATA(result), "- ");
 	}
-	VARSIZE(result) = strlen(VARDATA(result)) + VARHDRSZ;
+	VARATT_SIZEP(result) = strlen(VARDATA(result)) + VARHDRSZ;
 	PG_RETURN_TEXT_P(result);
 }
 
diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c
index 5b2a2ea0163af414074802a3f0824ddfe394592d..5bd339a5cc988415b25e7793ef35eb9510f7e603 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.54 2000/06/13 07:35:08 tgl Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/utils/adt/ruleutils.c,v 1.55 2000/07/03 23:09:52 wieck Exp $
  *
  *	  This software is copyrighted by Jan Wieck - Hamburg.
  *
@@ -181,7 +181,7 @@ pg_get_ruledef(NameData *rname)
 		if (SPI_finish() != SPI_OK_FINISH)
 			elog(ERROR, "get_ruledef: SPI_finish() failed");
 		ruledef = SPI_palloc(VARHDRSZ + 1);
-		VARSIZE(ruledef) = VARHDRSZ + 1;
+		VARATT_SIZEP(ruledef) = VARHDRSZ + 1;
 		VARDATA(ruledef)[0] = '-';
 		return ruledef;
 	}
@@ -197,7 +197,7 @@ pg_get_ruledef(NameData *rname)
 	make_ruledef(&buf, ruletup, rulettc);
 	len = buf.len + VARHDRSZ;
 	ruledef = SPI_palloc(len);
-	VARSIZE(ruledef) = len;
+	VARATT_SIZEP(ruledef) = len;
 	memcpy(VARDATA(ruledef), buf.data, buf.len);
 	pfree(buf.data);
 
@@ -296,7 +296,7 @@ pg_get_viewdef(NameData *rname)
 	}
 	len = buf.len + VARHDRSZ;
 	ruledef = SPI_palloc(len);
-	VARSIZE(ruledef) = len;
+	VARATT_SIZEP(ruledef) = len;
 	memcpy(VARDATA(ruledef), buf.data, buf.len);
 	pfree(buf.data);
 
@@ -530,7 +530,7 @@ pg_get_indexdef(PG_FUNCTION_ARGS)
 	 */
 	len = buf.len + VARHDRSZ;
 	indexdef = SPI_palloc(len);
-	VARSIZE(indexdef) = len;
+	VARATT_SIZEP(indexdef) = len;
 	memcpy(VARDATA(indexdef), buf.data, buf.len);
 	pfree(buf.data);
 	pfree(keybuf.data);
diff --git a/src/backend/utils/adt/timestamp.c b/src/backend/utils/adt/timestamp.c
index 71549bb9256cbd7fde18fe3c8ef015f263375676..4b3f498a2af665f5f5f9d60a500810fa24f454a6 100644
--- a/src/backend/utils/adt/timestamp.c
+++ b/src/backend/utils/adt/timestamp.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/utils/adt/timestamp.c,v 1.30 2000/06/19 03:54:27 tgl Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/utils/adt/timestamp.c,v 1.31 2000/07/03 23:09:53 wieck Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -1375,7 +1375,7 @@ timestamp_text(PG_FUNCTION_ARGS)
 
 	result = palloc(len);
 
-	VARSIZE(result) = len;
+	VARATT_SIZEP(result) = len;
 	memmove(VARDATA(result), str, (len - VARHDRSZ));
 
 	pfree(str);
@@ -1430,7 +1430,7 @@ interval_text(PG_FUNCTION_ARGS)
 
 	result = palloc(len);
 
-	VARSIZE(result) = len;
+	VARATT_SIZEP(result) = len;
 	memmove(VARDATA(result), str, (len - VARHDRSZ));
 
 	pfree(str);
@@ -2101,7 +2101,7 @@ timestamp_zone(PG_FUNCTION_ARGS)
 
 		result = palloc(len);
 
-		VARSIZE(result) = len;
+		VARATT_SIZEP(result) = len;
 		memmove(VARDATA(result), buf, (len - VARHDRSZ));
 	}
 	else
diff --git a/src/backend/utils/adt/varbit.c b/src/backend/utils/adt/varbit.c
index 3e4abe828bb0405bf1c4186b102fea449d58badf..b5d2e18e104ca106baddbd5f7f6be9c0d5a74592 100644
--- a/src/backend/utils/adt/varbit.c
+++ b/src/backend/utils/adt/varbit.c
@@ -4,7 +4,7 @@
  *	  Functions for the built-in type bit() and varying bit().
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/utils/adt/varbit.c,v 1.3 2000/06/15 03:32:29 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/utils/adt/varbit.c,v 1.4 2000/07/03 23:09:53 wieck Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -122,7 +122,7 @@ zpbit_in(char *s, int dummy, int32 atttypmod)
 	result = (bits8 *) palloc(len);
 	/* set to 0 so that *r is always initialised and strin is zero-padded */
 	memset(result, 0, len);
-	VARSIZE(result) = len;
+	VARATT_SIZEP(result) = len;
 	VARBITLEN(result) = atttypmod;
 
 	/*
@@ -353,7 +353,7 @@ varbit_in(char *s, int dummy, int32 atttypmod)
 	result = (bits8 *) palloc(len);
 	/* set to 0 so that *r is always initialised and strin is zero-padded */
 	memset(result, 0, len);
-	VARSIZE(result) = len;
+	VARATT_SIZEP(result) = len;
 	VARBITLEN(result) = bitlen;
 
 	/*
@@ -561,7 +561,7 @@ bitcat(bits8 *arg1, bits8 *arg2)
 	bytelen = VARBITDATALEN(bitlen1 + bitlen2);
 
 	result = (bits8 *) palloc(bytelen * sizeof(bits8));
-	VARSIZE(result) = bytelen;
+	VARATT_SIZEP(result) = bytelen;
 	VARBITLEN(result) = bitlen1 + bitlen2;
 	/* Copy the first bitstring in */
 	memcpy(VARBITS(result), VARBITS(arg1), VARBITBYTES(arg1));
@@ -625,7 +625,7 @@ bitsubstr(bits8 *arg, int32 s, int32 l)
 		len = VARBITDATALEN(0);
 		result = (bits8 *) palloc(len);
 		VARBITLEN(result) = 0;
-		VARSIZE(result) = len;
+		VARATT_SIZEP(result) = len;
 	}
 	else
 	{
@@ -638,7 +638,7 @@ bitsubstr(bits8 *arg, int32 s, int32 l)
 		len = VARBITDATALEN(rbitlen);
 		result = (bits8 *) palloc(len);
 		VARBITLEN(result) = rbitlen;
-		VARSIZE(result) = len;
+		VARATT_SIZEP(result) = len;
 		len -= VARHDRSZ + VARBITHDRSZ;
 		/* Are we copying from a byte boundary? */
 		if ((s1 - 1) % BITSPERBYTE == 0)
@@ -691,7 +691,7 @@ bitand(bits8 *arg1, bits8 *arg2)
 
 	len = Min(VARSIZE(arg1), VARSIZE(arg2));
 	result = (bits8 *) palloc(len);
-	VARSIZE(result) = len;
+	VARATT_SIZEP(result) = len;
 	VARBITLEN(result) = Min(VARBITLEN(arg1), VARBITLEN(arg2));
 
 	p1 = (bits8 *) VARBITS(arg1);
@@ -725,7 +725,7 @@ bitor(bits8 *arg1, bits8 *arg2)
 
 	len = Min(VARSIZE(arg1), VARSIZE(arg2));
 	result = (bits8 *) palloc(len);
-	VARSIZE(result) = len;
+	VARATT_SIZEP(result) = len;
 	VARBITLEN(result) = Min(VARBITLEN(arg1), VARBITLEN(arg2));
 
 	p1 = (bits8 *) VARBITS(arg1);
@@ -761,7 +761,7 @@ bitxor(bits8 *arg1, bits8 *arg2)
 
 	len = Min(VARSIZE(arg1), VARSIZE(arg2));
 	result = (bits8 *) palloc(len);
-	VARSIZE(result) = len;
+	VARATT_SIZEP(result) = len;
 	VARBITLEN(result) = Min(VARBITLEN(arg1), VARBITLEN(arg2));
 
 	p1 = (bits8 *) VARBITS(arg1);
@@ -792,7 +792,7 @@ bitnot(bits8 *arg)
 		return (bool) 0;
 
 	result = (bits8 *) palloc(VARSIZE(arg));
-	VARSIZE(result) = VARSIZE(arg);
+	VARATT_SIZEP(result) = VARSIZE(arg);
 	VARBITLEN(result) = VARBITLEN(arg);
 
 	p = (bits8 *) VARBITS(arg);
@@ -828,7 +828,7 @@ bitshiftleft(bits8 *arg, int shft)
 		return bitshiftright(arg, -shft);
 
 	result = (bits8 *) palloc(VARSIZE(arg));
-	VARSIZE(result) = VARSIZE(arg);
+	VARATT_SIZEP(result) = VARSIZE(arg);
 	VARBITLEN(result) = VARBITLEN(arg);
 	r = (bits8 *) VARBITS(result);
 
@@ -879,7 +879,7 @@ bitshiftright(bits8 *arg, int shft)
 		return bitshiftleft(arg, -shft);
 
 	result = (bits8 *) palloc(VARSIZE(arg));
-	VARSIZE(result) = VARSIZE(arg);
+	VARATT_SIZEP(result) = VARSIZE(arg);
 	VARBITLEN(result) = VARBITLEN(arg);
 	r = (bits8 *) VARBITS(result);
 
diff --git a/src/backend/utils/adt/varchar.c b/src/backend/utils/adt/varchar.c
index 53c6ec41677eea47326366eef1b1b2c3cab97e54..6f17cb589ae60f59a8b19c50a59299ae0ebca655 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.66 2000/06/19 03:54:28 tgl Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/utils/adt/varchar.c,v 1.67 2000/07/03 23:09:53 wieck Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -88,7 +88,7 @@ bpcharin(PG_FUNCTION_ARGS)
 		len = atttypmod - VARHDRSZ;
 
 	result = (BpChar *) palloc(atttypmod);
-	VARSIZE(result) = atttypmod;
+	VARATT_SIZEP(result) = atttypmod;
 	r = VARDATA(result);
 	for (i = 0; i < len; i++, r++, s++)
 	{
@@ -154,7 +154,7 @@ bpchar(PG_FUNCTION_ARGS)
 #endif
 
 	result = (BpChar *) palloc(len);
-	VARSIZE(result) = len;
+	VARATT_SIZEP(result) = len;
 	r = VARDATA(result);
 
 #ifdef MULTIBYTE
@@ -248,7 +248,7 @@ char_bpchar(PG_FUNCTION_ARGS)
 
 	result = (BpChar *) palloc(VARHDRSZ + 1);
 
-	VARSIZE(result) = VARHDRSZ + 1;
+	VARATT_SIZEP(result) = VARHDRSZ + 1;
 	*(VARDATA(result)) = c;
 
 	PG_RETURN_BPCHAR_P(result);
@@ -317,7 +317,7 @@ name_bpchar(NameData *s)
 
 	result = (char *) palloc(VARHDRSZ + len);
 	strncpy(VARDATA(result), NameStr(*s), len);
-	VARSIZE(result) = len + VARHDRSZ;
+	VARATT_SIZEP(result) = len + VARHDRSZ;
 
 	return result;
 }	/* name_bpchar() */
@@ -348,7 +348,7 @@ varcharin(PG_FUNCTION_ARGS)
 		len = atttypmod;		/* clip the string at max length */
 
 	result = (VarChar *) palloc(len);
-	VARSIZE(result) = len;
+	VARATT_SIZEP(result) = len;
 	memcpy(VARDATA(result), s, len - VARHDRSZ);
 
 #ifdef CYR_RECODE
@@ -407,7 +407,7 @@ varchar(PG_FUNCTION_ARGS)
 #endif
 
 	result = (VarChar *) palloc(slen);
-	VARSIZE(result) = slen;
+	VARATT_SIZEP(result) = slen;
 	memcpy(VARDATA(result), VARDATA(s), len);
 
 	PG_RETURN_VARCHAR_P(result);
diff --git a/src/backend/utils/adt/varlena.c b/src/backend/utils/adt/varlena.c
index fedd29f0c3e51c19011f0f62d0f01f7d5e6c1547..114bcff29a4ab914cfacb5d68794808ee0c7d3bf 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.60 2000/06/14 18:17:45 petere Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/utils/adt/varlena.c,v 1.61 2000/07/03 23:09:54 wieck Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -157,7 +157,7 @@ textin(char *inputText)
 
 	len = strlen(inputText) + VARHDRSZ;
 	result = (text *) palloc(len);
-	VARSIZE(result) = len;
+	VARATT_SIZEP(result) = len;
 
 	memmove(VARDATA(result), inputText, len - VARHDRSZ);
 
@@ -288,7 +288,7 @@ textcat(text *t1, text *t2)
 	result = palloc(len);
 
 	/* Set size of result string... */
-	VARSIZE(result) = len;
+	VARATT_SIZEP(result) = len;
 
 	/* Fill data field of result string... */
 	ptr = VARDATA(result);
@@ -374,7 +374,7 @@ text_substr(PG_FUNCTION_ARGS)
 #endif
 
 	ret = (text *) palloc(VARHDRSZ + n);
-	VARSIZE(ret) = VARHDRSZ + n;
+	VARATT_SIZEP(ret) = VARHDRSZ + n;
 
 	memcpy(VARDATA(ret), VARDATA(string) + m, n);
 
@@ -842,7 +842,7 @@ name_text(NameData *s)
 
 	result = palloc(VARHDRSZ + len);
 	strncpy(VARDATA(result), NameStr(*s), len);
-	VARSIZE(result) = len + VARHDRSZ;
+	VARATT_SIZEP(result) = len + VARHDRSZ;
 
 	return result;
 }	/* name_text() */
diff --git a/src/backend/utils/adt/version.c b/src/backend/utils/adt/version.c
index 4914acc8e3512df179293fcdc22ee7bb12c6b23b..0cf0b7859e8b90f2d2f48601e011827dfbcf5d32 100644
--- a/src/backend/utils/adt/version.c
+++ b/src/backend/utils/adt/version.c
@@ -5,7 +5,7 @@
  *
  * IDENTIFICATION
  *
- * $Header: /cvsroot/pgsql/src/backend/utils/adt/version.c,v 1.10 2000/07/02 15:20:51 petere Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/adt/version.c,v 1.11 2000/07/03 23:09:54 wieck Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -22,7 +22,7 @@ version(void)
 	int			n = strlen(PG_VERSION_STR) + VARHDRSZ;
 	text	   *ret = (text *) palloc(n);
 
-	VARSIZE(ret) = n;
+	VARATT_SIZEP(ret) = n;
 	memcpy(VARDATA(ret), PG_VERSION_STR, strlen(PG_VERSION_STR));
 
 	return ret;
diff --git a/src/include/access/tuptoaster.h b/src/include/access/tuptoaster.h
index 9c4f1a505785a55aad244f786855d1f0c9765b88..024bb1de91439116192f7e711dbed53aae877805 100644
--- a/src/include/access/tuptoaster.h
+++ b/src/include/access/tuptoaster.h
@@ -6,7 +6,7 @@
  *
  * Copyright (c) 2000, PostgreSQL Development Team
  *
- * $Id: tuptoaster.h,v 1.2 2000/04/12 17:16:26 momjian Exp $
+ * $Id: tuptoaster.h,v 1.3 2000/07/03 23:09:58 wieck Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -22,11 +22,23 @@
 #include "utils/rel.h"
 
 
+#define	TOAST_MAX_CHUNK_SIZE	((MaxTupleSize -							\
+				MAXALIGN(												\
+					MAXALIGN(offsetof(HeapTupleHeaderData, t_bits)) +	\
+					MAXALIGN(sizeof(Oid)) +								\
+					MAXALIGN(sizeof(int32)) +							\
+					MAXALIGN(VARHDRSZ))) / 4)
+
+
 extern void heap_tuple_toast_attrs(Relation rel,
-					   HeapTuple newtup, HeapTuple oldtup);
+				HeapTuple newtup, HeapTuple oldtup);
 
 extern varattrib *heap_tuple_untoast_attr(varattrib * attr);
 
+extern void heap_create_toast_table(Oid new_reloid,
+				TupleDesc new_tupdesc, bool istemp);
+				
+
 #endif	 /* TUPLE_TOASTER_ACTIVE */
 
 
diff --git a/src/include/catalog/pg_attribute.h b/src/include/catalog/pg_attribute.h
index 899b2496420617d2516523ab025e4606ca0aa0e7..925328e2bd9b564d11c626dd633759fd8d83597c 100644
--- a/src/include/catalog/pg_attribute.h
+++ b/src/include/catalog/pg_attribute.h
@@ -8,7 +8,7 @@
  * Portions Copyright (c) 1996-2000, PostgreSQL, Inc
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: pg_attribute.h,v 1.60 2000/07/02 22:01:08 momjian Exp $
+ * $Id: pg_attribute.h,v 1.61 2000/07/03 23:10:05 wieck Exp $
  *
  * NOTES
  *	  the genbki.sh script reads this file and generates .bki
@@ -243,7 +243,8 @@ typedef FormData_pg_attribute *Form_pg_attribute;
 { 1247, {"typreceive"},    24, 0,	4, 13, 0, -1, -1, '\001', 'p', '\0', 'i', '\0', '\0' }, \
 { 1247, {"typsend"},	   24, 0,	4, 14, 0, -1, -1, '\001', 'p', '\0', 'i', '\0', '\0' }, \
 { 1247, {"typalign"},	   18, 0,	1, 15, 0, -1, -1, '\001', 'p', '\0', 'c', '\0', '\0' }, \
-{ 1247, {"typdefault"},    25, 0,  -1, 16, 0, -1, -1, '\0'	, 'p', '\0', 'i', '\0', '\0' }
+{ 1247, {"typstorage"},	   18, 0,	1, 16, 0, -1, -1, '\001', 'p', '\0', 'c', '\0', '\0' }, \
+{ 1247, {"typdefault"},    25, 0,  -1, 17, 0, -1, -1, '\0'	, 'p', '\0', 'i', '\0', '\0' }
 
 DATA(insert OID = 0 ( 1247 typname			19 0 NAMEDATALEN   1 0 -1 -1 f p f i f f));
 DATA(insert OID = 0 ( 1247 typowner			23 0  4   2 0 -1 -1 t p f i f f));
@@ -260,7 +261,8 @@ DATA(insert OID = 0 ( 1247 typoutput		24 0  4  12 0 -1 -1 t p f i f f));
 DATA(insert OID = 0 ( 1247 typreceive		24 0  4  13 0 -1 -1 t p f i f f));
 DATA(insert OID = 0 ( 1247 typsend			24 0  4  14 0 -1 -1 t p f i f f));
 DATA(insert OID = 0 ( 1247 typalign			18 0  1  15 0 -1 -1 t p f c f f));
-DATA(insert OID = 0 ( 1247 typdefault		25 0 -1  16 0 -1 -1 f p f i f f));
+DATA(insert OID = 0 ( 1247 typstorage		18 0  1  16 0 -1 -1 t p f c f f));
+DATA(insert OID = 0 ( 1247 typdefault		25 0 -1  17 0 -1 -1 f p f i f f));
 DATA(insert OID = 0 ( 1247 ctid				27 0  6  -1 0 -1 -1 f p f i f f));
 DATA(insert OID = 0 ( 1247 oid				26 0  4  -2 0 -1 -1 t p f i f f));
 DATA(insert OID = 0 ( 1247 xmin				28 0  4  -3 0 -1 -1 t p f i f f));
@@ -423,20 +425,21 @@ DATA(insert OID = 0 ( 1249 tableoid			26 0  4  -7 0 -1 -1 t p f i f f));
 { 1259, {"relam"},		   26, 0,	4,	4, 0, -1, -1, '\001', 'p', '\0', 'i', '\0', '\0' }, \
 { 1259, {"relpages"},	   23, 0,	4,	5, 0, -1, -1, '\001', 'p', '\0', 'i', '\0', '\0' }, \
 { 1259, {"reltuples"},	   23, 0,	4,	6, 0, -1, -1, '\001', 'p', '\0', 'i', '\0', '\0' }, \
-{ 1259, {"rellongrelid"},  26, 0,	4,	7, 0, -1, -1, '\001', 'p', '\0', 'i', '\0', '\0' }, \
-{ 1259, {"relhasindex"},   16, 0,	1,	8, 0, -1, -1, '\001', 'p', '\0', 'c', '\0', '\0' }, \
-{ 1259, {"relisshared"},   16, 0,	1,	9, 0, -1, -1, '\001', 'p', '\0', 'c', '\0', '\0' }, \
-{ 1259, {"relkind"},	   18, 0,	1, 10, 0, -1, -1, '\001', 'p', '\0', 'c', '\0', '\0' }, \
-{ 1259, {"relnatts"},	   21, 0,	2, 11, 0, -1, -1, '\001', 'p', '\0', 's', '\0', '\0' }, \
-{ 1259, {"relchecks"},	   21, 0,	2, 12, 0, -1, -1, '\001', 'p', '\0', 's', '\0', '\0' }, \
-{ 1259, {"reltriggers"},   21, 0,	2, 13, 0, -1, -1, '\001', 'p', '\0', 's', '\0', '\0' }, \
-{ 1259, {"relukeys"},	   21, 0,	2, 14, 0, -1, -1, '\001', 'p', '\0', 's', '\0', '\0' }, \
-{ 1259, {"relfkeys"},	   21, 0,	2, 15, 0, -1, -1, '\001', 'p', '\0', 's', '\0', '\0' }, \
-{ 1259, {"relrefs"},	   21, 0,	2, 16, 0, -1, -1, '\001', 'p', '\0', 's', '\0', '\0' }, \
-{ 1259, {"relhaspkey"},    16, 0,	1, 17, 0, -1, -1, '\001', 'p', '\0', 'c', '\0', '\0' }, \
-{ 1259, {"relhasrules"},   16, 0,	1, 18, 0, -1, -1, '\001', 'p', '\0', 'c', '\0', '\0' }, \
-{ 1259, {"relhassubclass"},16, 0,	1, 19, 0, -1, -1, '\001', 'p', '\0', 'c', '\0', '\0' }, \
-{ 1259, {"relacl"},		 1034, 0,  -1, 20, 0, -1, -1,	'\0', 'p', '\0', 'i', '\0', '\0' }
+{ 1259, {"reltoastrelid"}, 26, 0,	4,	7, 0, -1, -1, '\001', 'p', '\0', 'i', '\0', '\0' }, \
+{ 1259, {"reltoastidxid"}, 26, 0,	4,	8, 0, -1, -1, '\001', 'p', '\0', 'i', '\0', '\0' }, \
+{ 1259, {"relhasindex"},   16, 0,	1,	9, 0, -1, -1, '\001', 'p', '\0', 'c', '\0', '\0' }, \
+{ 1259, {"relisshared"},   16, 0,	1, 10, 0, -1, -1, '\001', 'p', '\0', 'c', '\0', '\0' }, \
+{ 1259, {"relkind"},	   18, 0,	1, 11, 0, -1, -1, '\001', 'p', '\0', 'c', '\0', '\0' }, \
+{ 1259, {"relnatts"},	   21, 0,	2, 12, 0, -1, -1, '\001', 'p', '\0', 's', '\0', '\0' }, \
+{ 1259, {"relchecks"},	   21, 0,	2, 13, 0, -1, -1, '\001', 'p', '\0', 's', '\0', '\0' }, \
+{ 1259, {"reltriggers"},   21, 0,	2, 14, 0, -1, -1, '\001', 'p', '\0', 's', '\0', '\0' }, \
+{ 1259, {"relukeys"},	   21, 0,	2, 15, 0, -1, -1, '\001', 'p', '\0', 's', '\0', '\0' }, \
+{ 1259, {"relfkeys"},	   21, 0,	2, 16, 0, -1, -1, '\001', 'p', '\0', 's', '\0', '\0' }, \
+{ 1259, {"relrefs"},	   21, 0,	2, 17, 0, -1, -1, '\001', 'p', '\0', 's', '\0', '\0' }, \
+{ 1259, {"relhaspkey"},    16, 0,	1, 18, 0, -1, -1, '\001', 'p', '\0', 'c', '\0', '\0' }, \
+{ 1259, {"relhasrules"},   16, 0,	1, 19, 0, -1, -1, '\001', 'p', '\0', 'c', '\0', '\0' }, \
+{ 1259, {"relhassubclass"},16, 0,	1, 20, 0, -1, -1, '\001', 'p', '\0', 'c', '\0', '\0' }, \
+{ 1259, {"relacl"},		 1034, 0,  -1, 21, 0, -1, -1,	'\0', 'p', '\0', 'i', '\0', '\0' }
 
 DATA(insert OID = 0 ( 1259 relname			19 0 NAMEDATALEN   1 0 -1 -1 f p f i f f));
 DATA(insert OID = 0 ( 1259 reltype			26 0  4   2 0 -1 -1 t p f i f f));
@@ -444,20 +447,21 @@ DATA(insert OID = 0 ( 1259 relowner			23 0  4   3 0 -1 -1 t p f i f f));
 DATA(insert OID = 0 ( 1259 relam			26 0  4   4 0 -1 -1 t p f i f f));
 DATA(insert OID = 0 ( 1259 relpages			23 0  4   5 0 -1 -1 t p f i f f));
 DATA(insert OID = 0 ( 1259 reltuples		23 0  4   6 0 -1 -1 t p f i f f));
-DATA(insert OID = 0 ( 1259 rellongrelid		26 0  4   7 0 -1 -1 t p f i f f));
-DATA(insert OID = 0 ( 1259 relhasindex		16 0  1   8 0 -1 -1 t p f c f f));
-DATA(insert OID = 0 ( 1259 relisshared		16 0  1   9 0 -1 -1 t p f c f f));
-DATA(insert OID = 0 ( 1259 relkind			18 0  1  10 0 -1 -1 t p f c f f));
-DATA(insert OID = 0 ( 1259 relnatts			21 0  2  11 0 -1 -1 t p f s f f));
-DATA(insert OID = 0 ( 1259 relchecks		21 0  2  12 0 -1 -1 t p f s f f));
-DATA(insert OID = 0 ( 1259 reltriggers		21 0  2  13 0 -1 -1 t p f s f f));
-DATA(insert OID = 0 ( 1259 relukeys			21 0  2  14 0 -1 -1 t p f s f f));
-DATA(insert OID = 0 ( 1259 relfkeys			21 0  2  15 0 -1 -1 t p f s f f));
-DATA(insert OID = 0 ( 1259 relrefs			21 0  2  16 0 -1 -1 t p f s f f));
-DATA(insert OID = 0 ( 1259 relhaspkey		16 0  1  17 0 -1 -1 t p f c f f));
-DATA(insert OID = 0 ( 1259 relhasrules		16 0  1  18 0 -1 -1 t p f c f f));
-DATA(insert OID = 0 ( 1259 relhassubclass	16 0  1   19 0 -1 -1 t p f c f f));
-DATA(insert OID = 0 ( 1259 relacl		  1034 0 -1  20 0 -1 -1 f p f i f f));
+DATA(insert OID = 0 ( 1259 reltoastrelid	26 0  4   7 0 -1 -1 t p f i f f));
+DATA(insert OID = 0 ( 1259 reltoastidxid	26 0  4   8 0 -1 -1 t p f i f f));
+DATA(insert OID = 0 ( 1259 relhasindex		16 0  1   9 0 -1 -1 t p f c f f));
+DATA(insert OID = 0 ( 1259 relisshared		16 0  1  10 0 -1 -1 t p f c f f));
+DATA(insert OID = 0 ( 1259 relkind			18 0  1  11 0 -1 -1 t p f c f f));
+DATA(insert OID = 0 ( 1259 relnatts			21 0  2  12 0 -1 -1 t p f s f f));
+DATA(insert OID = 0 ( 1259 relchecks		21 0  2  13 0 -1 -1 t p f s f f));
+DATA(insert OID = 0 ( 1259 reltriggers		21 0  2  14 0 -1 -1 t p f s f f));
+DATA(insert OID = 0 ( 1259 relukeys			21 0  2  15 0 -1 -1 t p f s f f));
+DATA(insert OID = 0 ( 1259 relfkeys			21 0  2  16 0 -1 -1 t p f s f f));
+DATA(insert OID = 0 ( 1259 relrefs			21 0  2  17 0 -1 -1 t p f s f f));
+DATA(insert OID = 0 ( 1259 relhaspkey		16 0  1  18 0 -1 -1 t p f c f f));
+DATA(insert OID = 0 ( 1259 relhasrules		16 0  1  19 0 -1 -1 t p f c f f));
+DATA(insert OID = 0 ( 1259 relhassubclass	16 0  1  20 0 -1 -1 t p f c f f));
+DATA(insert OID = 0 ( 1259 relacl		  1034 0 -1  21 0 -1 -1 f p f i f f));
 DATA(insert OID = 0 ( 1259 ctid				27 0  6  -1 0 -1 -1 f p f i f f));
 DATA(insert OID = 0 ( 1259 oid				26 0  4  -2 0 -1 -1 t p f i f f));
 DATA(insert OID = 0 ( 1259 xmin				28 0  4  -3 0 -1 -1 t p f i f f));
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index 27444959602e382b29b52b45be4b774b2dd57361..1ea5b7b7792f96781d0518a788f8eaf4af420a65 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -8,7 +8,7 @@
  * Portions Copyright (c) 1996-2000, PostgreSQL, Inc
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: pg_class.h,v 1.38 2000/06/17 04:56:31 tgl Exp $
+ * $Id: pg_class.h,v 1.39 2000/07/03 23:10:05 wieck Exp $
  *
  * NOTES
  *	  the genbki.sh script reads this file and generates .bki
@@ -52,7 +52,8 @@ CATALOG(pg_class) BOOTSTRAP
 	Oid			relam;
 	int4		relpages;
 	int4		reltuples;
-	Oid			rellongrelid;
+	Oid			reltoastrelid;
+	Oid			reltoastidxid;
 	bool		relhasindex;
 	bool		relisshared;
 	char		relkind;
@@ -98,59 +99,60 @@ typedef FormData_pg_class *Form_pg_class;
  *		relacl field.
  * ----------------
  */
-#define Natts_pg_class_fixed			19
-#define Natts_pg_class					20
+#define Natts_pg_class_fixed			20
+#define Natts_pg_class					21
 #define Anum_pg_class_relname			1
 #define Anum_pg_class_reltype			2
 #define Anum_pg_class_relowner			3
 #define Anum_pg_class_relam				4
 #define Anum_pg_class_relpages			5
 #define Anum_pg_class_reltuples			6
-#define Anum_pg_class_rellongrelid		7
-#define Anum_pg_class_relhasindex		8
-#define Anum_pg_class_relisshared		9
-#define Anum_pg_class_relkind			10
-#define Anum_pg_class_relnatts			11
-#define Anum_pg_class_relchecks			12
-#define Anum_pg_class_reltriggers		13
-#define Anum_pg_class_relukeys			14
-#define Anum_pg_class_relfkeys			15
-#define Anum_pg_class_relrefs			16
-#define Anum_pg_class_relhaspkey		17
-#define Anum_pg_class_relhasrules		18
-#define Anum_pg_class_relhassubclass	19
-#define Anum_pg_class_relacl			20
+#define Anum_pg_class_reltoastrelid		7
+#define Anum_pg_class_reltoastidxid		8
+#define Anum_pg_class_relhasindex		9
+#define Anum_pg_class_relisshared		10
+#define Anum_pg_class_relkind			11
+#define Anum_pg_class_relnatts			12
+#define Anum_pg_class_relchecks			13
+#define Anum_pg_class_reltriggers		14
+#define Anum_pg_class_relukeys			15
+#define Anum_pg_class_relfkeys			16
+#define Anum_pg_class_relrefs			17
+#define Anum_pg_class_relhaspkey		18
+#define Anum_pg_class_relhasrules		19
+#define Anum_pg_class_relhassubclass	20
+#define Anum_pg_class_relacl			21
 
 /* ----------------
  *		initial contents of pg_class
  * ----------------
  */
 
-DATA(insert OID = 1247 (  pg_type 71		  PGUID 0 0 0 0 f f r 16 0 0 0 0 0 f f f _null_ ));
+DATA(insert OID = 1247 (  pg_type 71		  PGUID 0 0 0 0 0 f f r 17 0 0 0 0 0 f f f _null_ ));
 DESCR("");
-DATA(insert OID = 1249 (  pg_attribute 75	  PGUID 0 0 0 0 f f r 15 0 0 0 0 0 f f f _null_ ));
+DATA(insert OID = 1249 (  pg_attribute 75	  PGUID 0 0 0 0 0 f f r 15 0 0 0 0 0 f f f _null_ ));
 DESCR("");
-DATA(insert OID = 1255 (  pg_proc 81		  PGUID 0 0 0 0 f f r 17 0 0 0 0 0 f f f _null_ ));
+DATA(insert OID = 1255 (  pg_proc 81		  PGUID 0 0 0 0 0 f f r 17 0 0 0 0 0 f f f _null_ ));
 DESCR("");
-DATA(insert OID = 1259 (  pg_class 83		  PGUID 0 0 0 0 f f r 20 0 0 0 0 0 f f f _null_ ));
+DATA(insert OID = 1259 (  pg_class 83		  PGUID 0 0 0 0 0 f f r 21 0 0 0 0 0 f f f _null_ ));
 DESCR("");
-DATA(insert OID = 1260 (  pg_shadow 86		  PGUID 0 0 0 0 f t r 8  0 0 0 0 0 f f f _null_ ));
+DATA(insert OID = 1260 (  pg_shadow 86		  PGUID 0 0 0 0 0 f t r 8  0 0 0 0 0 f f f _null_ ));
 DESCR("");
-DATA(insert OID = 1261 (  pg_group 87		  PGUID 0 0 0 0 f t r 3  0 0 0 0 0 f f f _null_ ));
+DATA(insert OID = 1261 (  pg_group 87		  PGUID 0 0 0 0 0 f t r 3  0 0 0 0 0 f f f _null_ ));
 DESCR("");
-DATA(insert OID = 1262 (  pg_database 88	  PGUID 0 0 0 0 f t r 4  0 0 0 0 0 f f f _null_ ));
+DATA(insert OID = 1262 (  pg_database 88	  PGUID 0 0 0 0 0 f t r 4  0 0 0 0 0 f f f _null_ ));
 DESCR("");
-DATA(insert OID = 1264 (  pg_variable 90	  PGUID 0 0 0 0 f t s 1  0 0 0 0 0 f f f _null_ ));
+DATA(insert OID = 1264 (  pg_variable 90	  PGUID 0 0 0 0 0 f t s 1  0 0 0 0 0 f f f _null_ ));
 DESCR("");
-DATA(insert OID = 1269 (  pg_log  99		  PGUID 0 0 0 0 f t s 1  0 0 0 0 0 f f f _null_ ));
+DATA(insert OID = 1269 (  pg_log  99		  PGUID 0 0 0 0 0 f t s 1  0 0 0 0 0 f f f _null_ ));
 DESCR("");
-DATA(insert OID = 376  (  pg_xactlock  0	  PGUID 0 0 0 0 f t s 1  0 0 0 0 0 f f f _null_ ));
+DATA(insert OID = 376  (  pg_xactlock  0	  PGUID 0 0 0 0 0 f t s 1  0 0 0 0 0 f f f _null_ ));
 DESCR("");
-DATA(insert OID = 1215 (  pg_attrdef 109	  PGUID 0 0 0 0 t t r 4  0 0 0 0 0 f f f _null_ ));
+DATA(insert OID = 1215 (  pg_attrdef 109	  PGUID 0 0 0 0 0 t t r 4  0 0 0 0 0 f f f _null_ ));
 DESCR("");
-DATA(insert OID = 1216 (  pg_relcheck 110	  PGUID 0 0 0 0 t t r 4  0 0 0 0 0 f f f _null_ ));
+DATA(insert OID = 1216 (  pg_relcheck 110	  PGUID 0 0 0 0 0 t t r 4  0 0 0 0 0 f f f _null_ ));
 DESCR("");
-DATA(insert OID = 1219 (  pg_trigger 111	  PGUID 0 0 0 0 t t r 13  0 0 0 0 0 f f f _null_ ));
+DATA(insert OID = 1219 (  pg_trigger 111	  PGUID 0 0 0 0 0 t t r 13  0 0 0 0 0 f f f _null_ ));
 DESCR("");
 
 #define RelOid_pg_type			1247
@@ -175,6 +177,6 @@ DESCR("");
 #define		  RELKIND_SPECIAL		  's'		/* special (non-heap) */
 #define		  RELKIND_SEQUENCE		  'S'		/* SEQUENCE relation */
 #define		  RELKIND_UNCATALOGED	  'u'		/* temporary heap */
-#define		  RELKIND_LONGVALUE		  'v'		/* moved off huge values */
+#define		  RELKIND_TOASTVALUE	  't'		/* moved off huge values */
 
 #endif	 /* PG_CLASS_H */
diff --git a/src/include/catalog/pg_type.h b/src/include/catalog/pg_type.h
index ce9ba3b474aa54878dd89e13e939703a74c8fc49..b7a41b6a72da3cdc3a10eb5550c0c3044682af30 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.89 2000/06/05 07:29:01 tgl Exp $
+ * $Id: pg_type.h,v 1.90 2000/07/03 23:10:05 wieck Exp $
  *
  * NOTES
  *	  the genbki.sh script reads this file and generates .bki
@@ -106,6 +106,18 @@ CATALOG(pg_type) BOOTSTRAP
 	 * compiler will lay out the field in a struct representing a table row.
 	 * ----------------
 	 */
+	char		typstorage;
+
+	/* ----------------
+	 * typstorage tells if the type is prepared for toasting and what
+	 * the default strategy for attributes of this type should be.
+	 *
+	 * 'p' PLAIN      type not prepared for toasting
+	 * 'e' EXTERNAL   external storage possible, don't try to compress
+	 * 'x' EXTENDED   try to compress and store external if required
+	 * 'm' MAIN       like 'x' but try to keep in main tuple
+	 * ----------------
+	 */
 	text		typdefault;		/* VARIABLE LENGTH FIELD */
 } FormData_pg_type;
 
@@ -120,7 +132,7 @@ typedef FormData_pg_type *Form_pg_type;
  *		compiler constants for pg_type
  * ----------------
  */
-#define Natts_pg_type					16
+#define Natts_pg_type					17
 #define Anum_pg_type_typname			1
 #define Anum_pg_type_typowner			2
 #define Anum_pg_type_typlen				3
@@ -136,7 +148,8 @@ typedef FormData_pg_type *Form_pg_type;
 #define Anum_pg_type_typreceive			13
 #define Anum_pg_type_typsend			14
 #define Anum_pg_type_typalign			15
-#define Anum_pg_type_typdefault			16
+#define Anum_pg_type_typstorage			16
+#define Anum_pg_type_typdefault			17
 
 /* ----------------
  *		initial contents of pg_type
@@ -151,88 +164,88 @@ typedef FormData_pg_type *Form_pg_type;
 */
 
 /* OIDS 1 - 99 */
-DATA(insert OID = 16 (	bool	   PGUID  1   1 t b t \054 0   0 boolin boolout boolin boolout c _null_ ));
+DATA(insert OID = 16 (	bool	   PGUID  1   1 t b t \054 0   0 boolin boolout boolin boolout c p _null_ ));
 DESCR("boolean, 'true'/'false'");
 #define BOOLOID			16
 
-DATA(insert OID = 17 (	bytea	   PGUID -1  -1 f b t \054 0  18 byteain byteaout byteain byteaout i _null_ ));
+DATA(insert OID = 17 (	bytea	   PGUID -1  -1 f b t \054 0  18 byteain byteaout byteain byteaout i p _null_ ));
 DESCR("variable-length string, binary values escaped");
 #define BYTEAOID		17
 
-DATA(insert OID = 18 (	char	   PGUID  1   1 t b t \054 0   0 charin charout charin charout c _null_ ));
+DATA(insert OID = 18 (	char	   PGUID  1   1 t b t \054 0   0 charin charout charin charout c p _null_ ));
 DESCR("single character");
 #define CHAROID			18
 
-DATA(insert OID = 19 (	name	   PGUID NAMEDATALEN NAMEDATALEN  f b t \054 0	18 namein nameout namein nameout i _null_ ));
+DATA(insert OID = 19 (	name	   PGUID NAMEDATALEN NAMEDATALEN  f b t \054 0	18 namein nameout namein nameout i p _null_ ));
 DESCR("31-character type for storing system identifiers");
 #define NAMEOID			19
 
-DATA(insert OID = 20 (	int8	   PGUID  8  20 f b t \054 0   0 int8in int8out int8in int8out d _null_ ));
+DATA(insert OID = 20 (	int8	   PGUID  8  20 f b t \054 0   0 int8in int8out int8in int8out d p _null_ ));
 DESCR("~18 digit integer, 8-byte storage");
 #define INT8OID			20
 
-DATA(insert OID = 21 (	int2	   PGUID  2   5 t b t \054 0   0 int2in int2out int2in int2out s _null_ ));
+DATA(insert OID = 21 (	int2	   PGUID  2   5 t b t \054 0   0 int2in int2out int2in int2out s p _null_ ));
 DESCR("-32 thousand to 32 thousand, 2-byte storage");
 #define INT2OID			21
 
-DATA(insert OID = 22 (	int2vector PGUID INDEX_MAX_KEYS*2 -1 f b t \054 0  21 int2vectorin int2vectorout int2vectorin int2vectorout i _null_ ));
+DATA(insert OID = 22 (	int2vector PGUID INDEX_MAX_KEYS*2 -1 f b t \054 0  21 int2vectorin int2vectorout int2vectorin int2vectorout i p _null_ ));
 DESCR("array of INDEX_MAX_KEYS int2 integers, used in system tables");
 #define INT2VECTOROID	22
 
-DATA(insert OID = 23 (	int4	   PGUID  4  10 t b t \054 0   0 int4in int4out int4in int4out i _null_ ));
+DATA(insert OID = 23 (	int4	   PGUID  4  10 t b t \054 0   0 int4in int4out int4in int4out i p _null_ ));
 DESCR("-2 billion to 2 billion integer, 4-byte storage");
 #define INT4OID			23
 
-DATA(insert OID = 24 (	regproc    PGUID  4  16 t b t \054 0   0 regprocin regprocout regprocin regprocout i _null_ ));
+DATA(insert OID = 24 (	regproc    PGUID  4  16 t b t \054 0   0 regprocin regprocout regprocin regprocout i p _null_ ));
 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 _null_ ));
+DATA(insert OID = 25 (	text	   PGUID -1  -1 f b t \054 0  18 textin textout textin textout i p _null_ ));
 DESCR("variable-length string, no limit specified");
 #define TEXTOID			25
 
-DATA(insert OID = 26 (	oid		   PGUID  4  10 t b t \054 0   0 oidin oidout oidin oidout i _null_ ));
+DATA(insert OID = 26 (	oid		   PGUID  4  10 t b t \054 0   0 oidin oidout oidin oidout i p _null_ ));
 DESCR("object identifier(oid), maximum 4 billion");
 #define OIDOID			26
 
-DATA(insert OID = 27 (	tid		   PGUID  6  19 f b t \054 0   0 tidin tidout tidin tidout i _null_ ));
+DATA(insert OID = 27 (	tid		   PGUID  6  19 f b t \054 0   0 tidin tidout tidin tidout i p _null_ ));
 DESCR("(Block, offset), physical location of tuple");
 #define TIDOID		27
 
-DATA(insert OID = 28 (	xid		   PGUID  4  12 t b t \054 0   0 xidin xidout xidin xidout i _null_ ));
+DATA(insert OID = 28 (	xid		   PGUID  4  12 t b t \054 0   0 xidin xidout xidin xidout i p _null_ ));
 DESCR("transaction id");
 #define XIDOID 28
 
-DATA(insert OID = 29 (	cid		   PGUID  4  10 t b t \054 0   0 cidin cidout cidin cidout i _null_ ));
+DATA(insert OID = 29 (	cid		   PGUID  4  10 t b t \054 0   0 cidin cidout cidin cidout i p _null_ ));
 DESCR("command identifier type, sequence in transaction id");
 #define CIDOID 29
 
-DATA(insert OID = 30 (	oidvector  PGUID INDEX_MAX_KEYS*4 -1 f b t \054 0  26 oidvectorin oidvectorout oidvectorin oidvectorout i _null_ ));
+DATA(insert OID = 30 (	oidvector  PGUID INDEX_MAX_KEYS*4 -1 f b t \054 0  26 oidvectorin oidvectorout oidvectorin oidvectorout i p _null_ ));
 DESCR("array of INDEX_MAX_KEYS oids, used in system tables");
 #define OIDVECTOROID	30
 
-DATA(insert OID = 32 (	SET		   PGUID -1  -1 f b t \054 0   0 textin textout textin textout i _null_ ));
+DATA(insert OID = 32 (	SET		   PGUID -1  -1 f b t \054 0   0 textin textout textin textout i p _null_ ));
 DESCR("set of tuples");
 
-DATA(insert OID = 71 (	pg_type		 PGUID 4 4 t c t \054 1247 0 int4in int4out int4in int4out i _null_));
-DATA(insert OID = 75 (	pg_attribute PGUID 4 4 t c t \054 1249 0 int4in int4out int4in int4out i _null_));
-DATA(insert OID = 81 (	pg_proc		 PGUID 4 4 t c t \054 1255 0 int4in int4out int4in int4out i _null_));
-DATA(insert OID = 83 (	pg_class	 PGUID 4 4 t c t \054 1259 0 int4in int4out int4in int4out i _null_));
-DATA(insert OID = 86 (	pg_shadow	 PGUID 4 4 t c t \054 1260 0 int4in int4out int4in int4out i _null_));
-DATA(insert OID = 87 (	pg_group	 PGUID 4 4 t c t \054 1261 0 int4in int4out int4in int4out i _null_));
-DATA(insert OID = 88 (	pg_database  PGUID 4 4 t c t \054 1262 0 int4in int4out int4in int4out i _null_));
-DATA(insert OID = 90 (	pg_variable  PGUID 4 4 t c t \054 1264 0 int4in int4out int4in int4out i _null_));
-DATA(insert OID = 99 (	pg_log		 PGUID 4 4 t c t \054 1269 0 int4in int4out int4in int4out i _null_));
+DATA(insert OID = 71 (	pg_type		 PGUID 4 4 t c t \054 1247 0 int4in int4out int4in int4out i p _null_));
+DATA(insert OID = 75 (	pg_attribute PGUID 4 4 t c t \054 1249 0 int4in int4out int4in int4out i p _null_));
+DATA(insert OID = 81 (	pg_proc		 PGUID 4 4 t c t \054 1255 0 int4in int4out int4in int4out i p _null_));
+DATA(insert OID = 83 (	pg_class	 PGUID 4 4 t c t \054 1259 0 int4in int4out int4in int4out i p _null_));
+DATA(insert OID = 86 (	pg_shadow	 PGUID 4 4 t c t \054 1260 0 int4in int4out int4in int4out i p _null_));
+DATA(insert OID = 87 (	pg_group	 PGUID 4 4 t c t \054 1261 0 int4in int4out int4in int4out i p _null_));
+DATA(insert OID = 88 (	pg_database  PGUID 4 4 t c t \054 1262 0 int4in int4out int4in int4out i p _null_));
+DATA(insert OID = 90 (	pg_variable  PGUID 4 4 t c t \054 1264 0 int4in int4out int4in int4out i p _null_));
+DATA(insert OID = 99 (	pg_log		 PGUID 4 4 t c t \054 1269 0 int4in int4out int4in int4out i p _null_));
 
 /* OIDS 100 - 199 */
 
-DATA(insert OID = 109 (  pg_attrdef  PGUID 4 4 t c t \054 1215 0 int4in int4out int4in int4out i _null_));
-DATA(insert OID = 110 (  pg_relcheck PGUID 4 4 t c t \054 1216 0 int4in int4out int4in int4out i _null_));
-DATA(insert OID = 111 (  pg_trigger  PGUID 4 4 t c t \054 1219 0 int4in int4out int4in int4out i _null_));
+DATA(insert OID = 109 (  pg_attrdef  PGUID 4 4 t c t \054 1215 0 int4in int4out int4in int4out i p _null_));
+DATA(insert OID = 110 (  pg_relcheck PGUID 4 4 t c t \054 1216 0 int4in int4out int4in int4out i p _null_));
+DATA(insert OID = 111 (  pg_trigger  PGUID 4 4 t c t \054 1219 0 int4in int4out int4in int4out i p _null_));
 
 /* OIDS 200 - 299 */
 
-DATA(insert OID = 210 (  smgr	   PGUID 2	12 t b t \054 0 0 smgrin smgrout smgrin smgrout s _null_ ));
+DATA(insert OID = 210 (  smgr	   PGUID 2	12 t b t \054 0 0 smgrin smgrout smgrin smgrout s p _null_ ));
 DESCR("storage manager");
 
 /* OIDS 300 - 399 */
@@ -242,163 +255,163 @@ DESCR("storage manager");
 /* OIDS 500 - 599 */
 
 /* OIDS 600 - 699 */
-DATA(insert OID = 600 (  point	   PGUID 16  24 f b t \054 0 701 point_in point_out point_in point_out d _null_ ));
+DATA(insert OID = 600 (  point	   PGUID 16  24 f b t \054 0 701 point_in point_out point_in point_out d p _null_ ));
 DESCR("geometric point '(x, y)'");
 #define POINTOID		600
-DATA(insert OID = 601 (  lseg	   PGUID 32  48 f b t \054 0 600 lseg_in lseg_out lseg_in lseg_out d _null_ ));
+DATA(insert OID = 601 (  lseg	   PGUID 32  48 f b t \054 0 600 lseg_in lseg_out lseg_in lseg_out d p _null_ ));
 DESCR("geometric line segment '(pt1,pt2)'");
 #define LSEGOID			601
-DATA(insert OID = 602 (  path	   PGUID -1  -1 f b t \054 0 600 path_in path_out path_in path_out d _null_ ));
+DATA(insert OID = 602 (  path	   PGUID -1  -1 f b t \054 0 600 path_in path_out path_in path_out d p _null_ ));
 DESCR("geometric path '(pt1,...)'");
 #define PATHOID			602
-DATA(insert OID = 603 (  box	   PGUID 32 100 f b t \073 0 600 box_in box_out box_in box_out d _null_ ));
+DATA(insert OID = 603 (  box	   PGUID 32 100 f b t \073 0 600 box_in box_out box_in box_out d p _null_ ));
 DESCR("geometric box '(lower left,upper right)'");
 #define BOXOID			603
-DATA(insert OID = 604 (  polygon   PGUID -1  -1 f b t \054 0   0 poly_in poly_out poly_in poly_out d _null_ ));
+DATA(insert OID = 604 (  polygon   PGUID -1  -1 f b t \054 0   0 poly_in poly_out poly_in poly_out d p _null_ ));
 DESCR("geometric polygon '(pt1,...)'");
 #define POLYGONOID		604
-DATA(insert OID = 605 (  filename  PGUID 256 -1 f b t \054 0  18 filename_in filename_out filename_in filename_out i _null_ ));
+DATA(insert OID = 605 (  filename  PGUID 256 -1 f b t \054 0  18 filename_in filename_out filename_in filename_out i p _null_ ));
 DESCR("filename used in system tables");
 
-DATA(insert OID = 628 (  line	   PGUID 32  48 f b t \054 0 701 line_in line_out line_in line_out d _null_ ));
+DATA(insert OID = 628 (  line	   PGUID 32  48 f b t \054 0 701 line_in line_out line_in line_out d p _null_ ));
 DESCR("geometric line '(pt1,pt2)'");
 #define LINEOID			628
-DATA(insert OID = 629 (  _line	   PGUID  -1 -1 f b t \054 0 628 array_in array_out array_in array_out d _null_ ));
+DATA(insert OID = 629 (  _line	   PGUID  -1 -1 f b t \054 0 628 array_in array_out array_in array_out d p _null_ ));
 DESCR("");
 
 /* OIDS 700 - 799 */
 
-DATA(insert OID = 700 (  float4    PGUID  4  12 f b t \054 0   0 float4in float4out float4in float4out i _null_ ));
+DATA(insert OID = 700 (  float4    PGUID  4  12 f b t \054 0   0 float4in float4out float4in float4out i p _null_ ));
 DESCR("single-precision floating point number, 4-byte storage");
 #define FLOAT4OID 700
-DATA(insert OID = 701 (  float8    PGUID  8  24 f b t \054 0   0 float8in float8out float8in float8out d _null_ ));
+DATA(insert OID = 701 (  float8    PGUID  8  24 f b t \054 0   0 float8in float8out float8in float8out d p _null_ ));
 DESCR("double-precision floating point number, 8-byte storage");
 #define FLOAT8OID 701
-DATA(insert OID = 702 (  abstime   PGUID  4  20 t b t \054 0   0 nabstimein nabstimeout nabstimein nabstimeout i _null_ ));
+DATA(insert OID = 702 (  abstime   PGUID  4  20 t b t \054 0   0 nabstimein nabstimeout nabstimein nabstimeout i p _null_ ));
 DESCR("absolute, limited-range date and time (Unix system time)");
 #define ABSTIMEOID		702
-DATA(insert OID = 703 (  reltime   PGUID  4  20 t b t \054 0   0 reltimein reltimeout reltimein reltimeout i _null_ ));
+DATA(insert OID = 703 (  reltime   PGUID  4  20 t b t \054 0   0 reltimein reltimeout reltimein reltimeout i p _null_ ));
 DESCR("relative, limited-range time interval (Unix delta time)");
 #define RELTIMEOID		703
-DATA(insert OID = 704 (  tinterval PGUID 12  47 f b t \054 0   0 tintervalin tintervalout tintervalin tintervalout i _null_ ));
+DATA(insert OID = 704 (  tinterval PGUID 12  47 f b t \054 0   0 tintervalin tintervalout tintervalin tintervalout i p _null_ ));
 DESCR("(abstime,abstime), time interval");
 #define TINTERVALOID	704
-DATA(insert OID = 705 (  unknown   PGUID -1  -1 f b t \054 0   18 textin textout textin textout i _null_ ));
+DATA(insert OID = 705 (  unknown   PGUID -1  -1 f b t \054 0   18 textin textout textin textout i p _null_ ));
 DESCR("");
 #define UNKNOWNOID		705
 
-DATA(insert OID = 718 (  circle    PGUID  24 47 f b t \054 0	0 circle_in circle_out circle_in circle_out d _null_ ));
+DATA(insert OID = 718 (  circle    PGUID  24 47 f b t \054 0	0 circle_in circle_out circle_in circle_out d p _null_ ));
 DESCR("geometric circle '(center,radius)'");
 #define CIRCLEOID		718
-DATA(insert OID = 719 (  _circle   PGUID  -1 -1 f b t \054 0  718 array_in array_out array_in array_out d _null_ ));
-DATA(insert OID = 790 (  money	   PGUID   4 24 f b t \054 0	0 cash_in cash_out cash_in cash_out i _null_ ));
+DATA(insert OID = 719 (  _circle   PGUID  -1 -1 f b t \054 0  718 array_in array_out array_in array_out d p _null_ ));
+DATA(insert OID = 790 (  money	   PGUID   4 24 f b t \054 0	0 cash_in cash_out cash_in cash_out i p _null_ ));
 DESCR("$d,ddd.cc, money");
 #define CASHOID 790
-DATA(insert OID = 791 (  _money    PGUID  -1 -1 f b t \054 0  790 array_in array_out array_in array_out i _null_ ));
+DATA(insert OID = 791 (  _money    PGUID  -1 -1 f b t \054 0  790 array_in array_out array_in array_out i p _null_ ));
 
 /* OIDS 800 - 899 */
-DATA(insert OID = 829 ( macaddr    PGUID  6 -1 f b t \054 0 0 macaddr_in macaddr_out macaddr_in macaddr_out i _null_ ));
+DATA(insert OID = 829 ( macaddr    PGUID  6 -1 f b t \054 0 0 macaddr_in macaddr_out macaddr_in macaddr_out i p _null_ ));
 DESCR("XX:XX:XX:XX:XX, MAC address");
-DATA(insert OID = 869 ( inet	   PGUID  -1 -1 f b t \054 0 0 inet_in inet_out inet_in inet_out i _null_ ));
+DATA(insert OID = 869 ( inet	   PGUID  -1 -1 f b t \054 0 0 inet_in inet_out inet_in inet_out i p _null_ ));
 DESCR("IP address/netmask, host address, netmask optional");
 #define INETOID 869
-DATA(insert OID = 650 ( cidr	   PGUID  -1 -1 f b t \054 0 0 cidr_in cidr_out cidr_in cidr_out i _null_ ));
+DATA(insert OID = 650 ( cidr	   PGUID  -1 -1 f b t \054 0 0 cidr_in cidr_out cidr_in cidr_out i p _null_ ));
 DESCR("network IP address/netmask, network address");
 #define CIDROID 650
 
 /* OIDS 900 - 999 */
 
 /* OIDS 1000 - 1099 */
-DATA(insert OID = 1000 (  _bool		 PGUID -1  -1 f b t \054 0	16 array_in array_out array_in array_out i _null_ ));
-DATA(insert OID = 1001 (  _bytea	 PGUID -1  -1 f b t \054 0	17 array_in array_out array_in array_out i _null_ ));
-DATA(insert OID = 1002 (  _char		 PGUID -1  -1 f b t \054 0	18 array_in array_out array_in array_out i _null_ ));
-DATA(insert OID = 1003 (  _name		 PGUID -1  -1 f b t \054 0	19 array_in array_out array_in array_out i _null_ ));
-DATA(insert OID = 1005 (  _int2		 PGUID -1  -1 f b t \054 0	21 array_in array_out array_in array_out i _null_ ));
-DATA(insert OID = 1006 (  _int2vector PGUID -1	-1 f b t \054 0 22 array_in array_out array_in array_out i _null_ ));
-DATA(insert OID = 1007 (  _int4		 PGUID -1  -1 f b t \054 0	23 array_in array_out array_in array_out i _null_ ));
-DATA(insert OID = 1008 (  _regproc	 PGUID -1  -1 f b t \054 0	24 array_in array_out array_in array_out i _null_ ));
-DATA(insert OID = 1009 (  _text		 PGUID -1  -1 f b t \054 0	25 array_in array_out array_in array_out i _null_ ));
-DATA(insert OID = 1028 (  _oid		 PGUID -1  -1 f b t \054 0	26 array_in array_out array_in array_out i _null_ ));
-DATA(insert OID = 1010 (  _tid		 PGUID -1  -1 f b t \054 0	27 array_in array_out array_in array_out i _null_ ));
-DATA(insert OID = 1011 (  _xid		 PGUID -1  -1 f b t \054 0	28 array_in array_out array_in array_out i _null_ ));
-DATA(insert OID = 1012 (  _cid		 PGUID -1  -1 f b t \054 0	29 array_in array_out array_in array_out i _null_ ));
-DATA(insert OID = 1013 (  _oidvector PGUID -1  -1 f b t \054 0	30 array_in array_out array_in array_out i _null_ ));
-DATA(insert OID = 1014 (  _bpchar	 PGUID -1  -1 f b t \054 0 1042 array_in array_out array_in array_out i _null_ ));
-DATA(insert OID = 1015 (  _varchar	 PGUID -1  -1 f b t \054 0 1043 array_in array_out array_in array_out i _null_ ));
-DATA(insert OID = 1016 (  _int8		 PGUID -1  -1 f b t \054 0	20 array_in array_out array_in array_out d _null_ ));
-DATA(insert OID = 1017 (  _point	 PGUID -1  -1 f b t \054 0 600 array_in array_out array_in array_out d _null_ ));
-DATA(insert OID = 1018 (  _lseg		 PGUID -1  -1 f b t \054 0 601 array_in array_out array_in array_out d _null_ ));
-DATA(insert OID = 1019 (  _path		 PGUID -1  -1 f b t \054 0 602 array_in array_out array_in array_out d _null_ ));
-DATA(insert OID = 1020 (  _box		 PGUID -1  -1 f b t \073 0 603 array_in array_out array_in array_out d _null_ ));
-DATA(insert OID = 1021 (  _float4	 PGUID -1  -1 f b t \054 0 700 array_in array_out array_in array_out i _null_ ));
-DATA(insert OID = 1022 (  _float8	 PGUID -1  -1 f b t \054 0 701 array_in array_out array_in array_out d _null_ ));
-DATA(insert OID = 1023 (  _abstime	 PGUID -1  -1 f b t \054 0 702 array_in array_out array_in array_out i _null_ ));
-DATA(insert OID = 1024 (  _reltime	 PGUID -1  -1 f b t \054 0 703 array_in array_out array_in array_out i _null_ ));
-DATA(insert OID = 1025 (  _tinterval PGUID -1  -1 f b t \054 0 704 array_in array_out array_in array_out i _null_ ));
-DATA(insert OID = 1026 (  _filename  PGUID -1  -1 f b t \054 0 605 array_in array_out array_in array_out i _null_ ));
-DATA(insert OID = 1027 (  _polygon	 PGUID -1  -1 f b t \054 0 604 array_in array_out array_in array_out d _null_ ));
+DATA(insert OID = 1000 (  _bool		 PGUID -1  -1 f b t \054 0	16 array_in array_out array_in array_out i p _null_ ));
+DATA(insert OID = 1001 (  _bytea	 PGUID -1  -1 f b t \054 0	17 array_in array_out array_in array_out i p _null_ ));
+DATA(insert OID = 1002 (  _char		 PGUID -1  -1 f b t \054 0	18 array_in array_out array_in array_out i p _null_ ));
+DATA(insert OID = 1003 (  _name		 PGUID -1  -1 f b t \054 0	19 array_in array_out array_in array_out i p _null_ ));
+DATA(insert OID = 1005 (  _int2		 PGUID -1  -1 f b t \054 0	21 array_in array_out array_in array_out i p _null_ ));
+DATA(insert OID = 1006 (  _int2vector PGUID -1	-1 f b t \054 0 22 array_in array_out array_in array_out i p _null_ ));
+DATA(insert OID = 1007 (  _int4		 PGUID -1  -1 f b t \054 0	23 array_in array_out array_in array_out i p _null_ ));
+DATA(insert OID = 1008 (  _regproc	 PGUID -1  -1 f b t \054 0	24 array_in array_out array_in array_out i p _null_ ));
+DATA(insert OID = 1009 (  _text		 PGUID -1  -1 f b t \054 0	25 array_in array_out array_in array_out i p _null_ ));
+DATA(insert OID = 1028 (  _oid		 PGUID -1  -1 f b t \054 0	26 array_in array_out array_in array_out i p _null_ ));
+DATA(insert OID = 1010 (  _tid		 PGUID -1  -1 f b t \054 0	27 array_in array_out array_in array_out i p _null_ ));
+DATA(insert OID = 1011 (  _xid		 PGUID -1  -1 f b t \054 0	28 array_in array_out array_in array_out i p _null_ ));
+DATA(insert OID = 1012 (  _cid		 PGUID -1  -1 f b t \054 0	29 array_in array_out array_in array_out i p _null_ ));
+DATA(insert OID = 1013 (  _oidvector PGUID -1  -1 f b t \054 0	30 array_in array_out array_in array_out i p _null_ ));
+DATA(insert OID = 1014 (  _bpchar	 PGUID -1  -1 f b t \054 0 1042 array_in array_out array_in array_out i p _null_ ));
+DATA(insert OID = 1015 (  _varchar	 PGUID -1  -1 f b t \054 0 1043 array_in array_out array_in array_out i p _null_ ));
+DATA(insert OID = 1016 (  _int8		 PGUID -1  -1 f b t \054 0	20 array_in array_out array_in array_out d p _null_ ));
+DATA(insert OID = 1017 (  _point	 PGUID -1  -1 f b t \054 0 600 array_in array_out array_in array_out d p _null_ ));
+DATA(insert OID = 1018 (  _lseg		 PGUID -1  -1 f b t \054 0 601 array_in array_out array_in array_out d p _null_ ));
+DATA(insert OID = 1019 (  _path		 PGUID -1  -1 f b t \054 0 602 array_in array_out array_in array_out d p _null_ ));
+DATA(insert OID = 1020 (  _box		 PGUID -1  -1 f b t \073 0 603 array_in array_out array_in array_out d p _null_ ));
+DATA(insert OID = 1021 (  _float4	 PGUID -1  -1 f b t \054 0 700 array_in array_out array_in array_out i p _null_ ));
+DATA(insert OID = 1022 (  _float8	 PGUID -1  -1 f b t \054 0 701 array_in array_out array_in array_out d p _null_ ));
+DATA(insert OID = 1023 (  _abstime	 PGUID -1  -1 f b t \054 0 702 array_in array_out array_in array_out i p _null_ ));
+DATA(insert OID = 1024 (  _reltime	 PGUID -1  -1 f b t \054 0 703 array_in array_out array_in array_out i p _null_ ));
+DATA(insert OID = 1025 (  _tinterval PGUID -1  -1 f b t \054 0 704 array_in array_out array_in array_out i p _null_ ));
+DATA(insert OID = 1026 (  _filename  PGUID -1  -1 f b t \054 0 605 array_in array_out array_in array_out i p _null_ ));
+DATA(insert OID = 1027 (  _polygon	 PGUID -1  -1 f b t \054 0 604 array_in array_out array_in array_out d p _null_ ));
 /*
  *	Note: the size of aclitem needs to match sizeof(AclItem) in acl.h.
  *	Thanks to some padding, this will be 8 on all platforms.
  *	We also have an Assert to make sure.
  */
 #define ACLITEMSIZE 8
-DATA(insert OID = 1033 (  aclitem	 PGUID 8   -1 f b t \054 0 0 aclitemin aclitemout aclitemin aclitemout i _null_ ));
+DATA(insert OID = 1033 (  aclitem	 PGUID 8   -1 f b t \054 0 0 aclitemin aclitemout aclitemin aclitemout i p _null_ ));
 DESCR("access control list");
-DATA(insert OID = 1034 (  _aclitem	 PGUID -1 -1 f b t \054 0 1033 array_in array_out array_in array_out i _null_ ));
-DATA(insert OID = 1040 (  _macaddr	 PGUID -1 -1 f b t \054 0  829 array_in array_out array_in array_out i _null_ ));
-DATA(insert OID = 1041 (  _inet    PGUID -1 -1 f b t \054 0  869 array_in array_out array_in array_out i _null_ ));
-DATA(insert OID = 651  (  _cidr    PGUID -1 -1 f b t \054 0  650 array_in array_out array_in array_out i _null_ ));
-DATA(insert OID = 1042 ( bpchar		 PGUID -1  -1 f b t \054 0	18 bpcharin bpcharout bpcharin bpcharout i _null_ ));
+DATA(insert OID = 1034 (  _aclitem	 PGUID -1 -1 f b t \054 0 1033 array_in array_out array_in array_out i p _null_ ));
+DATA(insert OID = 1040 (  _macaddr	 PGUID -1 -1 f b t \054 0  829 array_in array_out array_in array_out i p _null_ ));
+DATA(insert OID = 1041 (  _inet    PGUID -1 -1 f b t \054 0  869 array_in array_out array_in array_out i p _null_ ));
+DATA(insert OID = 651  (  _cidr    PGUID -1 -1 f b t \054 0  650 array_in array_out array_in array_out i p _null_ ));
+DATA(insert OID = 1042 ( bpchar		 PGUID -1  -1 f b t \054 0	18 bpcharin bpcharout bpcharin bpcharout i p _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	18 varcharin varcharout varcharin varcharout i _null_ ));
+DATA(insert OID = 1043 ( varchar	 PGUID -1  -1 f b t \054 0	18 varcharin varcharout varcharin varcharout i p _null_ ));
 DESCR("varchar(length), non-blank-padded string, variable storage length");
 #define VARCHAROID		1043
 
-DATA(insert OID = 1082 ( date		 PGUID	4  10 t b t \054 0	0 date_in date_out date_in date_out i _null_ ));
+DATA(insert OID = 1082 ( date		 PGUID	4  10 t b t \054 0	0 date_in date_out date_in date_out i p _null_ ));
 DESCR("ANSI SQL date");
 #define DATEOID			1082
-DATA(insert OID = 1083 ( time		 PGUID	8  16 f b t \054 0	0 time_in time_out time_in time_out d _null_ ));
+DATA(insert OID = 1083 ( time		 PGUID	8  16 f b t \054 0	0 time_in time_out time_in time_out d p _null_ ));
 DESCR("hh:mm:ss, ANSI SQL time");
 #define TIMEOID			1083
 
 /* OIDS 1100 - 1199 */
-DATA(insert OID = 1182 ( _date		 PGUID	-1 -1 f b t \054 0	1082 array_in array_out array_in array_out i _null_ ));
-DATA(insert OID = 1183 ( _time		 PGUID	-1 -1 f b t \054 0	1083 array_in array_out array_in array_out d _null_ ));
-DATA(insert OID = 1184 ( timestamp	 PGUID	8  47 f b t \054 0	0 timestamp_in timestamp_out timestamp_in timestamp_out d _null_ ));
+DATA(insert OID = 1182 ( _date		 PGUID	-1 -1 f b t \054 0	1082 array_in array_out array_in array_out i p _null_ ));
+DATA(insert OID = 1183 ( _time		 PGUID	-1 -1 f b t \054 0	1083 array_in array_out array_in array_out d p _null_ ));
+DATA(insert OID = 1184 ( timestamp	 PGUID	8  47 f b t \054 0	0 timestamp_in timestamp_out timestamp_in timestamp_out d p _null_ ));
 DESCR("date and time");
 #define TIMESTAMPOID	1184
-DATA(insert OID = 1185 ( _timestamp  PGUID	-1 -1 f b t \054 0	1184 array_in array_out array_in array_out d _null_ ));
-DATA(insert OID = 1186 ( interval	 PGUID 12  47 f b t \054 0	0 interval_in interval_out interval_in interval_out d _null_ ));
+DATA(insert OID = 1185 ( _timestamp  PGUID	-1 -1 f b t \054 0	1184 array_in array_out array_in array_out d p _null_ ));
+DATA(insert OID = 1186 ( interval	 PGUID 12  47 f b t \054 0	0 interval_in interval_out interval_in interval_out d p _null_ ));
 DESCR("@ <number> <units>, time interval");
 #define INTERVALOID		1186
-DATA(insert OID = 1187 ( _interval	 PGUID	-1 -1 f b t \054 0	1186 array_in array_out array_in array_out d _null_ ));
+DATA(insert OID = 1187 ( _interval	 PGUID	-1 -1 f b t \054 0	1186 array_in array_out array_in array_out d p _null_ ));
 
 /* OIDS 1200 - 1299 */
-DATA(insert OID = 1231 (  _numeric	 PGUID -1  -1 f b t \054 0	1700 array_in array_out array_in array_out i _null_ ));
-DATA(insert OID = 1266 ( timetz		 PGUID 12  22 f b t \054 0	0 timetz_in timetz_out timetz_in timetz_out d _null_ ));
+DATA(insert OID = 1231 (  _numeric	 PGUID -1  -1 f b t \054 0	1700 array_in array_out array_in array_out i p _null_ ));
+DATA(insert OID = 1266 ( timetz		 PGUID 12  22 f b t \054 0	0 timetz_in timetz_out timetz_in timetz_out d p _null_ ));
 DESCR("hh:mm:ss, ANSI SQL time");
 #define TIMETZOID		1266
-DATA(insert OID = 1270 ( _timetz	 PGUID	-1 -1 f b t \054 0	1266 array_in array_out array_in array_out d _null_ ));
+DATA(insert OID = 1270 ( _timetz	 PGUID	-1 -1 f b t \054 0	1266 array_in array_out array_in array_out d p _null_ ));
 
 /* OIDS 1500 - 1599 */
-DATA(insert OID = 1560 ( bit		 PGUID -1  -1 f b t \054 0	0 zpbit_in zpbit_out zpbit_in zpbit_out i _null_ ));
+DATA(insert OID = 1560 ( bit		 PGUID -1  -1 f b t \054 0	0 zpbit_in zpbit_out zpbit_in zpbit_out i p _null_ ));
 DESCR("fixed-length bit string");
 #define ZPBITOID	 1560
-DATA(insert OID = 1561 ( _bit		 PGUID	-1 -1 f b t \054 0	1560 array_in array_out array_in array_out i _null_ ));
-DATA(insert OID = 1562 ( varbit		 PGUID -1  -1 f b t \054 0	0 varbit_in varbit_out varbit_in varbit_out i _null_ ));
+DATA(insert OID = 1561 ( _bit		 PGUID	-1 -1 f b t \054 0	1560 array_in array_out array_in array_out i p _null_ ));
+DATA(insert OID = 1562 ( varbit		 PGUID -1  -1 f b t \054 0	0 varbit_in varbit_out varbit_in varbit_out i p _null_ ));
 DESCR("fixed-length bit string");
 #define VARBITOID	  1562
-DATA(insert OID = 1563 ( _varbit	 PGUID	-1 -1 f b t \054 0	1562 array_in array_out array_in array_out i _null_ ));
+DATA(insert OID = 1563 ( _varbit	 PGUID	-1 -1 f b t \054 0	1562 array_in array_out array_in array_out i p _null_ ));
 
 /* OIDS 1600 - 1699 */
-DATA(insert OID = 1625 ( lztext		 PGUID -1  -1 f b t \054 0	0 lztextin lztextout lztextin lztextout i _null_ ));
+DATA(insert OID = 1625 ( lztext		 PGUID -1  -1 f b t \054 0	0 lztextin lztextout lztextin lztextout i x _null_ ));
 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 _null_ ));
+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_ ));
 DESCR("numeric(precision, decimal), arbitrary precision number");
 #define NUMERICOID		1700
 
@@ -421,7 +434,8 @@ extern Oid TypeCreate(char *typeName,
 		   char *sendProcedure,
 		   char *elementTypeName,
 		   char *defaultTypeValue,
-		   bool passedByValue, char alignment);
+		   bool passedByValue, char alignment,
+		   char storage);
 extern void TypeRename(const char *oldTypeName, const char *newTypeName);
 extern char *makeArrayTypeName(char *typeName);
 
diff --git a/src/include/commands/command.h b/src/include/commands/command.h
index 8cb31889fa06eb8260eef5e41950e49f0d93512a..e870126355754f38a8228b4e5748bd75b09f9d39 100644
--- a/src/include/commands/command.h
+++ b/src/include/commands/command.h
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2000, PostgreSQL, Inc
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: command.h,v 1.19 2000/06/28 03:32:57 tgl Exp $
+ * $Id: command.h,v 1.20 2000/07/03 23:10:10 wieck Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -58,6 +58,8 @@ extern void AlterTableDropConstraint(const char *relationName,
 						 bool inh, const char *constrName,
 						 int behavior);
 
+extern void AlterTableCreateToastTable(const char *relationName);
+
 /*
  * LOCK
  */
diff --git a/src/include/postgres.h b/src/include/postgres.h
index a4a7fda1109f93b54fa69640c55b814d2afa97e0..f11e28ed9f927f1a5a46d6541ad5a7ab19bb5027 100644
--- a/src/include/postgres.h
+++ b/src/include/postgres.h
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2000, PostgreSQL, Inc
  * Portions Copyright (c) 1995, Regents of the University of California
  *
- * $Id: postgres.h,v 1.42 2000/06/28 03:32:56 tgl Exp $
+ * $Id: postgres.h,v 1.43 2000/07/03 23:09:56 wieck Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -71,8 +71,12 @@ struct varlena
 	char		vl_dat[1];
 };
 
+#define TUPLE_TOASTER_ACTIVE
+
+#ifndef TUPLE_TOASTER_ACTIVE
 #define VARSIZE(PTR)	(((struct varlena *)(PTR))->vl_len)
 #define VARDATA(PTR)	(((struct varlena *)(PTR))->vl_dat)
+#endif
 #define VARHDRSZ		((int32) sizeof(int32))
 
 /*
@@ -89,8 +93,6 @@ typedef struct varlena VarChar;	/* var-length char, ie SQL varchar(n) */
  * Proposed new layout for variable length attributes
  * DO NOT USE YET - Jan
  */
-#undef TUPLE_TOASTER_ACTIVE
-#undef TUPLE_TOASTER_ALL_TYPES
 
 #ifdef TUPLE_TOASTER_ACTIVE
 typedef struct varattrib
@@ -102,14 +104,17 @@ typedef struct varattrib
 		struct
 		{
 			int32		va_rawsize;		/* Plain data size */
+			char		va_data[1];		/* Compressed data */
 		}			va_compressed;		/* Compressed stored attribute */
 
 		struct
 		{
 			int32		va_rawsize;		/* Plain data size */
+			int32		va_extsize;		/* External saved size */
 			Oid			va_valueid;		/* Unique identifier of value */
-			Oid			va_longrelid;	/* RelID where to find chunks */
-			Oid			va_rowid;		/* Main tables row Oid */
+			Oid			va_toastrelid;	/* RelID where to find chunks */
+			Oid			va_toastidxid;	/* Main tables row Oid */
+			Oid			va_rowid;		/* Referencing row Oid */
 			int16		va_attno;		/* Main tables attno */
 		}			va_external;/* External stored attribute */
 
@@ -117,14 +122,18 @@ typedef struct varattrib
 	}			va_content;
 }			varattrib;
 
-#define VARATT_FLAG_EXTERNAL	0x8000
-#define VARATT_FLAG_COMPRESSED	0x4000
-#define VARATT_MASK_FLAGS		0xc000
-#define VARATT_MASK_SIZE		0x3fff
+#define VARATT_FLAG_EXTERNAL	0x80000000
+#define VARATT_FLAG_COMPRESSED	0x40000000
+#define VARATT_MASK_FLAGS		0xc0000000
+#define VARATT_MASK_SIZE		0x3fffffff
 
 #define VARATT_SIZEP(_PTR)	(((varattrib *)(_PTR))->va_header)
 #define VARATT_SIZE(PTR)	(VARATT_SIZEP(PTR) & VARATT_MASK_SIZE)
 #define VARATT_DATA(PTR)	(((varattrib *)(PTR))->va_content.va_data)
+#define VARATT_CDATA(PTR)	(((varattrib *)(PTR))->va_content.va_compressed.va_data)
+
+#define VARSIZE(__PTR)		VARATT_SIZE(__PTR)
+#define VARDATA(__PTR)		VARATT_DATA(__PTR)
 
 #define VARATT_IS_EXTENDED(PTR)		\
 				((VARATT_SIZEP(PTR) & VARATT_MASK_FLAGS) != 0)
@@ -142,12 +151,12 @@ typedef struct varattrib
 extern varattrib *heap_tuple_untoast_attr(varattrib * attr);
 
 #define VARATT_GETPLAIN(_ARG,_VAR) {								\
-				if (VARATTR_IS_EXTENDED(_ARG))						\
+				if (VARATT_IS_EXTENDED(_ARG))						\
 					(_VAR) = (void *)heap_tuple_untoast_attr(_ARG); \
 				else												\
-					(_VAR) = (_ARG);								\
+					(_VAR) = (void *)(_ARG);						\
 			}
-#define VARATT_FREE(_ARG,VAR) do {									\
+#define VARATT_FREE(_ARG,_VAR) do {									\
 				if ((void *)(_VAR) != (void *)(_ARG))				\
 					pfree((void *)(_VAR));							\
 			} while (0)
diff --git a/src/include/utils/lztext.h b/src/include/utils/lztext.h
index 8936ffb133d04e94432ee95f9e1213ab6444a693..be57c7478b7c3c0fb01c56d4dff379306921254f 100644
--- a/src/include/utils/lztext.h
+++ b/src/include/utils/lztext.h
@@ -1,7 +1,7 @@
 /* ----------
  * lztext.h
  *
- * $Header: /cvsroot/pgsql/src/include/utils/Attic/lztext.h,v 1.3 2000/04/12 17:16:55 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/include/utils/Attic/lztext.h,v 1.4 2000/07/03 23:10:14 wieck Exp $
  *
  *	Definitions for the lztext compressed data type
  * ----------
@@ -10,13 +10,10 @@
 #ifndef _LZTEXT_H_
 #define _LZTEXT_H_
 
-#include "utils/pg_lzcompress.h"
-
-
 /* ----------
- * The internal storage format of an LZ compressed text field
+ * The internal storage format of an LZ compressed text field is varattrib
  * ----------
  */
-typedef PGLZ_Header lztext;
+typedef varattrib lztext;
 
 #endif	 /* _LZTEXT_H_ */