diff --git a/contrib/dbsize/dbsize.c b/contrib/dbsize/dbsize.c
index b072a86912f484d9602f2934fe72409d6200076c..44699aa69363011daccf3360d3b784aa927f4aea 100644
--- a/contrib/dbsize/dbsize.c
+++ b/contrib/dbsize/dbsize.c
@@ -65,7 +65,7 @@ database_size(PG_FUNCTION_ARGS)
 	if (!HeapTupleIsValid(tuple))
 		elog(ERROR, "database %s does not exist", NameStr(*dbname));
 
-	dbid = tuple->t_data->t_oid;
+	dbid = HeapTupleGetOid(tuple);
 	if (dbid == InvalidOid)
 		elog(ERROR, "invalid database id");
 
diff --git a/contrib/fulltextindex/fti.c b/contrib/fulltextindex/fti.c
index aabb2caf9f915b5629cbdce1d4e248cd444051bf..8050f2a9d72603a00de68f0afe952a33d9d5514a 100644
--- a/contrib/fulltextindex/fti.c
+++ b/contrib/fulltextindex/fti.c
@@ -190,7 +190,7 @@ fti(PG_FUNCTION_ARGS)
 	tupdesc = rel->rd_att;		/* what the tuple looks like (?) */
 
 	/* get oid of current tuple, needed by all, so place here */
-	oid = rettuple->t_data->t_oid;
+	oid = rel->rd_rel->relhasoids ? HeapTupleGetOid(rettuple) : InvalidOid;
 	if (!OidIsValid(oid))
 		elog(ERROR, "Full Text Indexing: Oid of current tuple is invalid");
 
diff --git a/contrib/rserv/rserv.c b/contrib/rserv/rserv.c
index 401cc5fd9cc0b4aa50b996325e649e663268dea7..54da14a69616685287237a338930434287415add 100644
--- a/contrib/rserv/rserv.c
+++ b/contrib/rserv/rserv.c
@@ -102,7 +102,9 @@ _rserv_log_()
 
 	if (keynum == ObjectIdAttributeNumber)
 	{
-		sprintf(oidbuf, "%u", tuple->t_data->t_oid);
+		sprintf(oidbuf, "%u", rel->rd_rel->relhasoids
+		                      ? HeapTupleGetOid(tuple)
+		                      : InvalidOid);
 		key = oidbuf;
 	}
 	else
diff --git a/src/backend/access/common/heaptuple.c b/src/backend/access/common/heaptuple.c
index adad245c64343f6bce5f9bb76e411421cdabc46c..19e02dee67e310495210637919c258c3b96e06ca 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.77 2002/06/20 20:29:24 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/access/common/heaptuple.c,v 1.78 2002/07/20 05:16:56 momjian Exp $
  *
  * NOTES
  *	  The old interface functions have been converted to macros
@@ -436,7 +436,7 @@ heap_getsysattr(HeapTuple tup, int attnum, bool *isnull)
 			result = PointerGetDatum(&(tup->t_self));
 			break;
 		case ObjectIdAttributeNumber:
-			result = ObjectIdGetDatum(tup->t_data->t_oid);
+			result = ObjectIdGetDatum(HeapTupleGetOid(tup));
 			break;
 		case MinTransactionIdAttributeNumber:
 			result = TransactionIdGetDatum(HeapTupleHeaderGetXmin(tup->t_data));
@@ -581,6 +581,8 @@ heap_formtuple(TupleDesc tupleDescriptor,
 		elog(ERROR, "heap_formtuple: numberOfAttributes %d exceeds limit %d",
 			 numberOfAttributes, MaxTupleAttributeNumber);
 
+	AssertTupleDescHasOidIsValid(tupleDescriptor);
+
 	for (i = 0; i < numberOfAttributes; i++)
 	{
 		if (nulls[i] != ' ')
@@ -595,6 +597,9 @@ heap_formtuple(TupleDesc tupleDescriptor,
 	if (hasnull)
 		len += BITMAPLEN(numberOfAttributes);
 
+	if (tupleDescriptor->tdhasoid == WITHOID)
+		len += sizeof(Oid);
+
 	hoff = len = MAXALIGN(len); /* align user data safely */
 
 	len += ComputeDataSize(tupleDescriptor, value, nulls);
@@ -698,14 +703,18 @@ heap_modifytuple(HeapTuple tuple,
 	 * t_infomask
 	 */
 	infomask = newTuple->t_data->t_infomask;
-	memmove((char *) &newTuple->t_data->t_oid,	/* XXX */
-			(char *) &tuple->t_data->t_oid,
-			((char *) &tuple->t_data->t_hoff -
-			 (char *) &tuple->t_data->t_oid));	/* XXX */
+	/*
+	 * copy t_xmin, t_cid, t_xmax, t_ctid, t_natts, t_infomask
+	 */
+	memmove((char *) newTuple->t_data,	/* XXX */
+			(char *) tuple->t_data,
+			offsetof(HeapTupleHeaderData, t_hoff));	/* XXX */
 	newTuple->t_data->t_infomask = infomask;
 	newTuple->t_data->t_natts = numberOfAttributes;
 	newTuple->t_self = tuple->t_self;
 	newTuple->t_tableOid = tuple->t_tableOid;
+	if (relation->rd_rel->relhasoids)
+		HeapTupleSetOid(newTuple, HeapTupleGetOid(tuple));
 
 	return newTuple;
 }
@@ -738,6 +747,7 @@ heap_freetuple(HeapTuple htup)
  */
 HeapTuple
 heap_addheader(int natts,		/* max domain index */
+			   bool withoid,	/* reserve space for oid */
 			   Size structlen,	/* its length */
 			   void *structure) /* pointer to the struct */
 {
@@ -749,7 +759,10 @@ heap_addheader(int natts,		/* max domain index */
 	AssertArg(natts > 0);
 
 	/* header needs no null bitmap */
-	hoff = MAXALIGN(offsetof(HeapTupleHeaderData, t_bits));
+	hoff = offsetof(HeapTupleHeaderData, t_bits);
+	if (withoid)
+		hoff += sizeof(Oid);
+	hoff = MAXALIGN(hoff);
 	len = hoff + structlen;
 
 	tuple = (HeapTuple) palloc(HEAPTUPLESIZE + len);
diff --git a/src/backend/access/common/tupdesc.c b/src/backend/access/common/tupdesc.c
index af73941369e68ae8629ebc40f1c47ba8fade29d8..24f33fac4beec8b30b08a5193cc6ffbb1d7ce3bb 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.80 2002/06/20 20:29:24 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/access/common/tupdesc.c,v 1.81 2002/07/20 05:16:56 momjian Exp $
  *
  * NOTES
  *	  some of the executor utility code such as "ExecTypeFromTL" should be
@@ -36,7 +36,7 @@
  * ----------------------------------------------------------------
  */
 TupleDesc
-CreateTemplateTupleDesc(int natts)
+CreateTemplateTupleDesc(int natts, hasoid_t withoid)
 {
 	uint32		size;
 	TupleDesc	desc;
@@ -58,6 +58,7 @@ CreateTemplateTupleDesc(int natts)
 	MemSet(desc->attrs, 0, size);
 
 	desc->natts = natts;
+	desc->tdhasoid = withoid;
 
 	return desc;
 }
@@ -82,6 +83,7 @@ CreateTupleDesc(int natts, Form_pg_attribute *attrs)
 	desc->attrs = attrs;
 	desc->natts = natts;
 	desc->constr = NULL;
+	desc->tdhasoid = UNDEFOID;
 
 	return desc;
 }
@@ -116,6 +118,7 @@ CreateTupleDescCopy(TupleDesc tupdesc)
 		desc->attrs[i]->atthasdef = false;
 	}
 	desc->constr = NULL;
+	desc->tdhasoid = tupdesc->tdhasoid;
 
 	return desc;
 }
@@ -182,6 +185,7 @@ CreateTupleDescCopyConstr(TupleDesc tupdesc)
 	else
 		desc->constr = NULL;
 
+	desc->tdhasoid = tupdesc->tdhasoid;
 	return desc;
 }
 
@@ -235,6 +239,8 @@ equalTupleDescs(TupleDesc tupdesc1, TupleDesc tupdesc2)
 
 	if (tupdesc1->natts != tupdesc2->natts)
 		return false;
+	if (tupdesc1->tdhasoid != tupdesc2->tdhasoid)
+		return false;
 	for (i = 0; i < tupdesc1->natts; i++)
 	{
 		Form_pg_attribute attr1 = tupdesc1->attrs[i];
@@ -392,7 +398,7 @@ TupleDescInitEntry(TupleDesc desc,
 	 */
 	typeForm = (Form_pg_type) GETSTRUCT(tuple);
 
-	att->atttypid = tuple->t_data->t_oid;
+	att->atttypid = HeapTupleGetOid(tuple);
 
 	/*
 	 * There are a couple of cases where we must override the information
@@ -479,7 +485,7 @@ BuildDescForRelation(List *schema)
 	 * allocate a new tuple descriptor
 	 */
 	natts = length(schema);
-	desc = CreateTemplateTupleDesc(natts);
+	desc = CreateTemplateTupleDesc(natts, UNDEFOID);
 	constr->has_not_null = false;
 
 	attnum = 0;
@@ -646,7 +652,7 @@ TypeGetTupleDesc(Oid typeoid, List *colaliases)
 		/* OK, get the column alias */
 		attname = strVal(lfirst(colaliases));
 
-		tupdesc = CreateTemplateTupleDesc(1);
+		tupdesc = CreateTemplateTupleDesc(1, WITHOUTOID);
 		TupleDescInitEntry(tupdesc,
 						   (AttrNumber) 1,
 						   attname,
diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c
index 9a6a0b074006e7a387a81564a14797d3234e8cad..35249188135ce6d1feb2b5b5b78593ddea92c3ef 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.141 2002/07/02 05:48:44 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/access/heap/heapam.c,v 1.142 2002/07/20 05:16:56 momjian Exp $
  *
  *
  * INTERFACE ROUTINES
@@ -1116,10 +1116,11 @@ heap_insert(Relation relation, HeapTuple tup, CommandId cid)
 		 * to support a persistent object store (objects need to contain
 		 * pointers to one another).
 		 */
-		if (!OidIsValid(tup->t_data->t_oid))
-			tup->t_data->t_oid = newoid();
+		AssertTupleDescHasOid(relation->rd_att);
+		if (!OidIsValid(HeapTupleGetOid(tup)))
+			HeapTupleSetOid(tup, newoid());
 		else
-			CheckMaxObjectId(tup->t_data->t_oid);
+			CheckMaxObjectId(HeapTupleGetOid(tup));
 	}
 
 	HeapTupleHeaderSetXmin(tup->t_data, GetCurrentTransactionId());
@@ -1166,7 +1167,13 @@ heap_insert(Relation relation, HeapTuple tup, CommandId cid)
 		rdata[0].len = SizeOfHeapInsert;
 		rdata[0].next = &(rdata[1]);
 
-		xlhdr.t_oid = tup->t_data->t_oid;
+		if (relation->rd_rel->relhasoids)
+		{
+			AssertTupleDescHasOid(relation->rd_att);
+			xlhdr.t_oid = HeapTupleGetOid(tup);
+		}
+		else
+			xlhdr.t_oid = InvalidOid;
 		xlhdr.t_natts = tup->t_data->t_natts;
 		xlhdr.t_hoff = tup->t_data->t_hoff;
 		xlhdr.mask = tup->t_data->t_infomask;
@@ -1176,6 +1183,7 @@ heap_insert(Relation relation, HeapTuple tup, CommandId cid)
 		rdata[1].next = &(rdata[2]);
 
 		rdata[2].buffer = buffer;
+		/* PG73FORMAT: write bitmap [+ padding] [+ oid] + data */
 		rdata[2].data = (char *) tup->t_data + offsetof(HeapTupleHeaderData, t_bits);
 		rdata[2].len = tup->t_len - offsetof(HeapTupleHeaderData, t_bits);
 		rdata[2].next = NULL;
@@ -1206,7 +1214,11 @@ heap_insert(Relation relation, HeapTuple tup, CommandId cid)
 	 */
 	CacheInvalidateHeapTuple(relation, tup);
 
-	return tup->t_data->t_oid;
+	if (!relation->rd_rel->relhasoids)
+		return InvalidOid;
+		
+	AssertTupleDescHasOid(relation->rd_att);
+	return HeapTupleGetOid(tup);
 }
 
 /*
@@ -1499,7 +1511,11 @@ l2:
 	}
 
 	/* Fill in OID and transaction status data for newtup */
-	newtup->t_data->t_oid = oldtup.t_data->t_oid;
+	if (relation->rd_rel->relhasoids)
+	{
+		AssertTupleDescHasOid(relation->rd_att);
+		HeapTupleSetOid(newtup, HeapTupleGetOid(&oldtup));
+	}
 	newtup->t_data->t_infomask &= ~(HEAP_XACT_MASK);
 	newtup->t_data->t_infomask |= (HEAP_XMAX_INVALID | HEAP_UPDATED);
 	HeapTupleHeaderSetXmin(newtup->t_data, GetCurrentTransactionId());
@@ -1972,24 +1988,28 @@ log_heap_update(Relation reln, Buffer oldbuf, ItemPointerData from,
 	rdata[1].len = 0;
 	rdata[1].next = &(rdata[2]);
 
-	xlhdr.hdr.t_oid = newtup->t_data->t_oid;
+	if (reln->rd_rel->relhasoids)
+	{
+		AssertTupleDescHasOid(reln->rd_att);
+		xlhdr.hdr.t_oid = HeapTupleGetOid(newtup);
+	}
+	else
+		xlhdr.hdr.t_oid = InvalidOid;
 	xlhdr.hdr.t_natts = newtup->t_data->t_natts;
 	xlhdr.hdr.t_hoff = newtup->t_data->t_hoff;
 	xlhdr.hdr.mask = newtup->t_data->t_infomask;
 	if (move)					/* remember xmin & xmax */
 	{
-		TransactionId xmax;
-		TransactionId xmin;
+		TransactionId xid[2];   /* xmax, xmin */
 
-		if (newtup->t_data->t_infomask & HEAP_XMAX_INVALID ||
-			newtup->t_data->t_infomask & HEAP_MARKED_FOR_UPDATE)
-			xmax = InvalidTransactionId;
+		if (newtup->t_data->t_infomask & (HEAP_XMAX_INVALID |
+		                                  HEAP_MARKED_FOR_UPDATE))
+			xid[0] = InvalidTransactionId;
 		else
-			xmax = HeapTupleHeaderGetXmax(newtup->t_data);
-		xmin = HeapTupleHeaderGetXmin(newtup->t_data);
-		memcpy((char *) &xlhdr + hsize, &xmax, sizeof(TransactionId));
-		memcpy((char *) &xlhdr + hsize + sizeof(TransactionId),
-			   &xmin, sizeof(TransactionId));
+			xid[0] = HeapTupleHeaderGetXmax(newtup->t_data);
+		xid[1] = HeapTupleHeaderGetXmin(newtup->t_data);
+		memcpy((char *) &xlhdr + hsize,
+		       (char *) xid,            2 * sizeof(TransactionId));
 		hsize += 2 * sizeof(TransactionId);
 	}
 	rdata[2].buffer = newbuf;
@@ -1998,6 +2018,7 @@ log_heap_update(Relation reln, Buffer oldbuf, ItemPointerData from,
 	rdata[2].next = &(rdata[3]);
 
 	rdata[3].buffer = newbuf;
+	/* PG73FORMAT: write bitmap [+ padding] [+ oid] + data */
 	rdata[3].data = (char *) newtup->t_data + offsetof(HeapTupleHeaderData, t_bits);
 	rdata[3].len = newtup->t_len - offsetof(HeapTupleHeaderData, t_bits);
 	rdata[3].next = NULL;
@@ -2193,12 +2214,13 @@ heap_xlog_insert(bool redo, XLogRecPtr lsn, XLogRecord *record)
 		memcpy((char *) &xlhdr,
 			   (char *) xlrec + SizeOfHeapInsert,
 			   SizeOfHeapHeader);
+		htup = &tbuf.hdr;
+		MemSet((char *) htup, 0, sizeof(HeapTupleHeaderData));
+		/* PG73FORMAT: get bitmap [+ padding] [+ oid] + data */
 		memcpy((char *) &tbuf + offsetof(HeapTupleHeaderData, t_bits),
 			   (char *) xlrec + SizeOfHeapInsert + SizeOfHeapHeader,
 			   newlen);
 		newlen += offsetof(HeapTupleHeaderData, t_bits);
-		htup = &tbuf.hdr;
-		htup->t_oid = xlhdr.t_oid;
 		htup->t_natts = xlhdr.t_natts;
 		htup->t_hoff = xlhdr.t_hoff;
 		htup->t_infomask = HEAP_XMAX_INVALID | xlhdr.mask;
@@ -2206,6 +2228,11 @@ heap_xlog_insert(bool redo, XLogRecPtr lsn, XLogRecord *record)
 		HeapTupleHeaderSetCmin(htup, FirstCommandId);
 		HeapTupleHeaderSetXmaxInvalid(htup);
 		HeapTupleHeaderSetCmax(htup, FirstCommandId);
+		if (reln->rd_rel->relhasoids)
+		{
+			AssertTupleDescHasOid(reln->rd_att);
+			HeapTupleHeaderSetOid(htup, xlhdr.t_oid);
+		}
 
 		offnum = PageAddItem(page, (Item) htup, newlen, offnum,
 							 LP_USED | OverwritePageMode);
@@ -2362,28 +2389,33 @@ newsame:;
 		memcpy((char *) &xlhdr,
 			   (char *) xlrec + SizeOfHeapUpdate,
 			   SizeOfHeapHeader);
+		htup = &tbuf.hdr;
+		MemSet((char *) htup, 0, sizeof(HeapTupleHeaderData));
+		/* PG73FORMAT: get bitmap [+ padding] [+ oid] + data */
 		memcpy((char *) &tbuf + offsetof(HeapTupleHeaderData, t_bits),
 			   (char *) xlrec + hsize,
 			   newlen);
 		newlen += offsetof(HeapTupleHeaderData, t_bits);
-		htup = &tbuf.hdr;
-		htup->t_oid = xlhdr.t_oid;
 		htup->t_natts = xlhdr.t_natts;
 		htup->t_hoff = xlhdr.t_hoff;
+		if (reln->rd_rel->relhasoids)
+		{
+			AssertTupleDescHasOid(reln->rd_att);
+			HeapTupleHeaderSetOid(htup, xlhdr.t_oid);
+		}
 		if (move)
 		{
-			TransactionId xmax;
-			TransactionId xmin;
+			TransactionId xid[2];   /* xmax, xmin */
 			
 			hsize = SizeOfHeapUpdate + SizeOfHeapHeader;
-			memcpy(&xmax, (char *) xlrec + hsize, sizeof(TransactionId));
-			memcpy(&xmin, (char *) xlrec + hsize + sizeof(TransactionId), sizeof(TransactionId));
+			memcpy((char *) xid,
+			       (char *) xlrec + hsize, 2 * sizeof(TransactionId));
 			htup->t_infomask = xlhdr.mask;
 			htup->t_infomask &= ~(HEAP_XMIN_COMMITTED |
 								  HEAP_XMIN_INVALID | HEAP_MOVED_OFF);
 			htup->t_infomask |= HEAP_MOVED_IN;
-			HeapTupleHeaderSetXmin(htup, xmin);
-			HeapTupleHeaderSetXmax(htup, xmax);
+			HeapTupleHeaderSetXmin(htup, xid[1]);
+			HeapTupleHeaderSetXmax(htup, xid[0]);
 			HeapTupleHeaderSetXvac(htup, record->xl_xid);
 		}
 		else
diff --git a/src/backend/access/heap/tuptoaster.c b/src/backend/access/heap/tuptoaster.c
index 3c66aed1db13881730aefe1ffc4e57462d17f1b5..2945cf3458cb567ba7dedb522bb0ccf41c9c8bcd 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.32 2002/05/27 19:53:33 tgl Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/access/heap/tuptoaster.c,v 1.33 2002/07/20 05:16:56 momjian Exp $
  *
  *
  * INTERFACE ROUTINES
@@ -726,6 +726,8 @@ toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup)
 		new_len = offsetof(HeapTupleHeaderData, t_bits);
 		if (has_nulls)
 			new_len += BITMAPLEN(numAttrs);
+		if (rel->rd_rel->relhasoids)
+			new_len += sizeof(Oid);
 		new_len = MAXALIGN(new_len);
 		Assert(new_len == olddata->t_hoff);
 		new_len += ComputeDataSize(tupleDesc, toast_values, toast_nulls);
diff --git a/src/backend/bootstrap/bootparse.y b/src/backend/bootstrap/bootparse.y
index 705a2b1fe80e98544f7d40f0d3b08cafcb0b5f7f..f2d31356d9c73a9f9d25ca22d3ce6d944abbb5b5 100644
--- a/src/backend/bootstrap/bootparse.y
+++ b/src/backend/bootstrap/bootparse.y
@@ -9,7 +9,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/bootstrap/bootparse.y,v 1.49 2002/07/12 18:43:13 tgl Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/bootstrap/bootparse.y,v 1.50 2002/07/20 05:16:56 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -179,13 +179,13 @@ Boot_CreateStmt:
 						}
 
 						tupdesc = CreateTupleDesc(numattr, attrtypes);
+						tupdesc->tdhasoid = BoolToHasOid(! ($4));
 						boot_reldesc = heap_create(LexIDStr($5),
 												   PG_CATALOG_NAMESPACE,
 												   tupdesc,
 												   $3,
 												   true,
 												   true);
-						boot_reldesc->rd_rel->relhasoids = ! ($4);
 						elog(DEBUG3, "bootstrap relation created");
 					}
 					else
diff --git a/src/backend/bootstrap/bootstrap.c b/src/backend/bootstrap/bootstrap.c
index bd2f823f1a69847364820c8761d67f5122ad6f01..4300c0211dae279c4c59eb7c882258f4e1fa239d 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.132 2002/06/20 20:29:26 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/bootstrap/bootstrap.c,v 1.133 2002/07/20 05:16:56 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -495,7 +495,8 @@ boot_openrel(char *relname)
 		app = Typ;
 		while ((tup = heap_getnext(scan, ForwardScanDirection)) != NULL)
 		{
-			(*app)->am_oid = tup->t_data->t_oid;
+			AssertTupleDescHasOid(rel->rd_att);
+			(*app)->am_oid = HeapTupleGetOid(tup);
 			memcpy((char *) &(*app)->am_typ,
 				   (char *) GETSTRUCT(tup),
 				   sizeof((*app)->am_typ));
@@ -675,11 +676,15 @@ InsertOneTuple(Oid objectid)
 	elog(DEBUG3, "inserting row oid %u, %d columns", objectid, numattr);
 
 	tupDesc = CreateTupleDesc(numattr, attrtypes);
+	tupDesc->tdhasoid = BoolToHasOid(RelationGetForm(boot_reldesc)->relhasoids);
 	tuple = heap_formtuple(tupDesc, values, Blanks);
-	pfree(tupDesc);				/* just free's tupDesc, not the attrtypes */
 
 	if (objectid != (Oid) 0)
-		tuple->t_data->t_oid = objectid;
+	{
+		AssertTupleDescHasOid(tupDesc);
+		HeapTupleSetOid(tuple, objectid);
+	}
+	pfree(tupDesc);				/* just free's tupDesc, not the attrtypes */
 	simple_heap_insert(boot_reldesc, tuple);
 	heap_freetuple(tuple);
 	elog(DEBUG3, "row inserted");
@@ -871,7 +876,8 @@ gettype(char *type)
 		app = Typ;
 		while ((tup = heap_getnext(scan, ForwardScanDirection)) != NULL)
 		{
-			(*app)->am_oid = tup->t_data->t_oid;
+			AssertTupleDescHasOid(rel->rd_att);
+			(*app)->am_oid = HeapTupleGetOid(tup);
 			memmove((char *) &(*app++)->am_typ,
 					(char *) GETSTRUCT(tup),
 					sizeof((*app)->am_typ));
diff --git a/src/backend/catalog/aclchk.c b/src/backend/catalog/aclchk.c
index 2a0495b8e6f95c0dad92e91769ae03e485fac5ff..5827915d8a50f8d85fd669f003fc618e0d42d3d3 100644
--- a/src/backend/catalog/aclchk.c
+++ b/src/backend/catalog/aclchk.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/catalog/aclchk.c,v 1.70 2002/07/18 04:50:10 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/catalog/aclchk.c,v 1.71 2002/07/20 05:16:56 momjian Exp $
  *
  * NOTES
  *	  See acl.h.
@@ -592,7 +592,8 @@ ExecuteGrantStmt_Namespace(GrantStmt *stmt)
 			elog(ERROR, "namespace \"%s\" not found", nspname);
 		pg_namespace_tuple = (Form_pg_namespace) GETSTRUCT(tuple);
 
-		if (!pg_namespace_ownercheck(tuple->t_data->t_oid, GetUserId()))
+		AssertTupleDescHasOid(relation->rd_att);
+		if (!pg_namespace_ownercheck(HeapTupleGetOid(tuple), GetUserId()))
 			aclcheck_error(ACLCHECK_NOT_OWNER, nspname);
 
 		/*
diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 930abe00f853d88c6f5fcbe9c584a6bd6b90226b..86651c6053eb1ebaa1ff081eb5e4bf4067d422d9 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.211 2002/07/19 22:21:17 tgl Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.212 2002/07/20 05:16:56 momjian Exp $
  *
  *
  * INTERFACE ROUTINES
@@ -65,7 +65,7 @@
 static void AddNewRelationTuple(Relation pg_class_desc,
 					Relation new_rel_desc,
 					Oid new_rel_oid, Oid new_type_oid,
-					char relkind, bool relhasoids);
+					char relkind);
 static void AddNewRelationType(const char *typeName,
 							   Oid typeNamespace,
 							   Oid new_rel_oid,
@@ -445,6 +445,7 @@ AddNewAttributeTuples(Oid new_rel_oid,
 		(*dpp)->attcacheoff = -1;
 
 		tup = heap_addheader(Natts_pg_attribute,
+		                     false,
 							 ATTRIBUTE_TUPLE_SIZE,
 							 (void *) *dpp);
 
@@ -481,6 +482,7 @@ AddNewAttributeTuples(Oid new_rel_oid,
 				Form_pg_attribute attStruct;
 
 				tup = heap_addheader(Natts_pg_attribute,
+				                     false,
 									 ATTRIBUTE_TUPLE_SIZE,
 									 (void *) *dpp);
 
@@ -527,8 +529,7 @@ AddNewRelationTuple(Relation pg_class_desc,
 					Relation new_rel_desc,
 					Oid new_rel_oid,
 					Oid new_type_oid,
-					char relkind,
-					bool relhasoids)
+					char relkind)
 {
 	Form_pg_class new_rel_reltup;
 	HeapTuple	tup;
@@ -579,7 +580,6 @@ AddNewRelationTuple(Relation pg_class_desc,
 	new_rel_reltup->relowner = GetUserId();
 	new_rel_reltup->reltype = new_type_oid;
 	new_rel_reltup->relkind = relkind;
-	new_rel_reltup->relhasoids = relhasoids;
 
 	/* ----------------
 	 *	now form a tuple to add to pg_class
@@ -587,11 +587,13 @@ AddNewRelationTuple(Relation pg_class_desc,
 	 * ----------------
 	 */
 	tup = heap_addheader(Natts_pg_class_fixed,
+	                     true,
 						 CLASS_TUPLE_SIZE,
 						 (void *) new_rel_reltup);
 
 	/* force tuple to have the desired OID */
-	tup->t_data->t_oid = new_rel_oid;
+	AssertTupleDescHasOid(pg_class_desc->rd_att);
+	HeapTupleSetOid(tup, new_rel_oid);
 
 	/*
 	 * finally insert the new tuple and free it.
@@ -691,6 +693,8 @@ heap_create_with_catalog(const char *relname,
 	if (get_relname_relid(relname, relnamespace))
 		elog(ERROR, "Relation '%s' already exists", relname);
 
+	tupdesc->tdhasoid = BoolToHasOid(relhasoids);
+	
 	/*
 	 * Tell heap_create not to create a physical file; we'll do that below
 	 * after all our catalog updates are done.	(This isn't really
@@ -723,8 +727,7 @@ heap_create_with_catalog(const char *relname,
 						new_rel_desc,
 						new_rel_oid,
 						new_type_oid,
-						relkind,
-						relhasoids);
+						relkind);
 
 	/*
 	 * since defining a relation also defines a complex type, we add a new
@@ -920,13 +923,14 @@ RemoveAttrDefault(Oid relid, AttrNumber attnum,
 	scan = systable_beginscan(attrdef_rel, AttrDefaultIndex, true,
 							  SnapshotNow, 2, scankeys);
 
+	AssertTupleDescHasOid(attrdef_rel->rd_att);
 	/* There should be at most one matching tuple, but we loop anyway */
 	while (HeapTupleIsValid(tuple = systable_getnext(scan)))
 	{
 		ObjectAddress	object;
 
 		object.classId = RelationGetRelid(attrdef_rel);
-		object.objectId = tuple->t_data->t_oid;
+		object.objectId = HeapTupleGetOid(tuple);
 		object.objectSubId = 0;
 
 		performDeletion(&object, behavior);
@@ -1711,6 +1715,7 @@ RemoveRelConstraints(Relation rel, const char *constrName,
 	conscan = systable_beginscan(conrel, ConstraintRelidIndex, true,
 								 SnapshotNow, 1, key);
 
+	AssertTupleDescHasOid(conrel->rd_att);
 	/*
 	 * Scan over the result set, removing any matching entries.
 	 */
@@ -1723,7 +1728,7 @@ RemoveRelConstraints(Relation rel, const char *constrName,
 			ObjectAddress	conobj;
 
 			conobj.classId = RelationGetRelid(conrel);
-			conobj.objectId = contup->t_data->t_oid;
+			conobj.objectId = HeapTupleGetOid(contup);
 			conobj.objectSubId = 0;
 
 			performDeletion(&conobj, behavior);
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 92d4d361a5bdf28826a4ea35559085d4c2375016..0937367957c60b688962c72aa4e63f3c5a9620c0 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/catalog/index.c,v 1.185 2002/07/18 16:47:23 tgl Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/catalog/index.c,v 1.186 2002/07/20 05:16:56 momjian Exp $
  *
  *
  * INTERFACE ROUTINES
@@ -111,7 +111,7 @@ BuildFuncTupleDesc(Oid funcOid,
 	/*
 	 * Allocate and zero a tuple descriptor for a one-column tuple.
 	 */
-	funcTupDesc = CreateTemplateTupleDesc(1);
+	funcTupDesc = CreateTemplateTupleDesc(1, UNDEFOID);
 	funcTupDesc->attrs[0] = (Form_pg_attribute) palloc(ATTRIBUTE_TUPLE_SIZE);
 	MemSet(funcTupDesc->attrs[0], 0, ATTRIBUTE_TUPLE_SIZE);
 
@@ -199,7 +199,7 @@ ConstructTupleDescriptor(Relation heapRelation,
 	 * allocate the new tuple descriptor
 	 */
 
-	indexTupDesc = CreateTemplateTupleDesc(numatts);
+	indexTupDesc = CreateTemplateTupleDesc(numatts, WITHOUTOID);
 
 	/* ----------------
 	 *	  for each attribute we are indexing, obtain its attribute
@@ -320,6 +320,7 @@ UpdateRelationRelation(Relation indexRelation)
 
 	/* XXX Natts_pg_class_fixed is a hack - see pg_class.h */
 	tuple = heap_addheader(Natts_pg_class_fixed,
+	                       true,
 						   CLASS_TUPLE_SIZE,
 						   (void *) indexRelation->rd_rel);
 
@@ -327,7 +328,8 @@ UpdateRelationRelation(Relation indexRelation)
 	 * the new tuple must have the oid already chosen for the index.
 	 * sure would be embarrassing to do this sort of thing in polite company.
 	 */
-	tuple->t_data->t_oid = RelationGetRelid(indexRelation);
+	AssertTupleDescHasOid(pg_class->rd_att);
+	HeapTupleSetOid(tuple, RelationGetRelid(indexRelation));
 	simple_heap_insert(pg_class, tuple);
 
 	/*
@@ -406,6 +408,7 @@ AppendAttributeTuples(Relation indexRelation, int numatts)
 		Assert(indexTupDesc->attrs[i]->attcacheoff == -1);
 
 		new_tuple = heap_addheader(Natts_pg_attribute,
+		                           false,
 								   ATTRIBUTE_TUPLE_SIZE,
 								   (void *) indexTupDesc->attrs[i]);
 
@@ -495,6 +498,7 @@ UpdateIndexRelation(Oid indexoid,
 	 * form a tuple to insert into pg_index
 	 */
 	tuple = heap_addheader(Natts_pg_index,
+	                       false,
 						   itupLen,
 						   (void *) indexForm);
 
@@ -599,6 +603,7 @@ index_create(Oid heapRelationId,
 											indexInfo->ii_KeyAttrNumbers,
 												classObjectId);
 
+	indexTupDesc->tdhasoid = WITHOUTOID;
 	/*
 	 * create the index relation (but don't create storage yet)
 	 */
@@ -626,7 +631,7 @@ index_create(Oid heapRelationId,
 	indexRelation->rd_rel->relowner = GetUserId();
 	indexRelation->rd_rel->relam = accessMethodObjectId;
 	indexRelation->rd_rel->relkind = RELKIND_INDEX;
-	indexRelation->rd_rel->relhasoids = false;
+	indexRelation->rd_rel->relhasoids = false;  /* WITHOUTOID! */
 
 	/*
 	 * store index's pg_class entry
diff --git a/src/backend/catalog/namespace.c b/src/backend/catalog/namespace.c
index e78bde1d7bb7443892772527484acc1ecbf0805a..f02789fa807295840902fa48e0a5f0b3242b07d6 100644
--- a/src/backend/catalog/namespace.c
+++ b/src/backend/catalog/namespace.c
@@ -13,7 +13,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/catalog/namespace.c,v 1.25 2002/07/16 06:58:14 ishii Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/catalog/namespace.c,v 1.26 2002/07/20 05:16:56 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -571,7 +571,7 @@ FuncnameGetCandidates(List *names, int nargs)
 						continue; /* keep previous result */
 					/* replace previous result */
 					prevResult->pathpos = pathpos;
-					prevResult->oid = proctup->t_data->t_oid;
+					prevResult->oid = HeapTupleGetOid(proctup);
 					continue;	/* args are same, of course */
 				}
 			}
@@ -584,7 +584,7 @@ FuncnameGetCandidates(List *names, int nargs)
 			palloc(sizeof(struct _FuncCandidateList) - sizeof(Oid)
 				   + nargs * sizeof(Oid));
 		newResult->pathpos = pathpos;
-		newResult->oid = proctup->t_data->t_oid;
+		newResult->oid = HeapTupleGetOid(proctup);
 		newResult->nargs = nargs;
 		memcpy(newResult->args, procform->proargtypes, nargs * sizeof(Oid));
 
@@ -818,7 +818,7 @@ OpernameGetCandidates(List *names, char oprkind)
 						continue; /* keep previous result */
 					/* replace previous result */
 					prevResult->pathpos = pathpos;
-					prevResult->oid = opertup->t_data->t_oid;
+					prevResult->oid = HeapTupleGetOid(opertup);
 					continue;	/* args are same, of course */
 				}
 			}
@@ -830,7 +830,7 @@ OpernameGetCandidates(List *names, char oprkind)
 		newResult = (FuncCandidateList)
 			palloc(sizeof(struct _FuncCandidateList) + sizeof(Oid));
 		newResult->pathpos = pathpos;
-		newResult->oid = opertup->t_data->t_oid;
+		newResult->oid = HeapTupleGetOid(opertup);
 		newResult->nargs = 2;
 		newResult->args[0] = operform->oprleft;
 		newResult->args[1] = operform->oprright;
@@ -994,7 +994,7 @@ OpclassGetCandidates(Oid amid)
 				/* replace previous result */
 				prevResult->opcname_tmp = NameStr(opcform->opcname);
 				prevResult->pathpos = pathpos;
-				prevResult->oid = opctup->t_data->t_oid;
+				prevResult->oid = HeapTupleGetOid(opctup);
 				prevResult->opcintype = opcform->opcintype;
 				prevResult->opcdefault = opcform->opcdefault;
 				prevResult->opckeytype = opcform->opckeytype;
@@ -1009,7 +1009,7 @@ OpclassGetCandidates(Oid amid)
 			palloc(sizeof(struct _OpclassCandidateList));
 		newResult->opcname_tmp = NameStr(opcform->opcname);
 		newResult->pathpos = pathpos;
-		newResult->oid = opctup->t_data->t_oid;
+		newResult->oid = HeapTupleGetOid(opctup);
 		newResult->opcintype = opcform->opcintype;
 		newResult->opcdefault = opcform->opcdefault;
 		newResult->opckeytype = opcform->opckeytype;
@@ -1572,8 +1572,9 @@ RemoveTempRelations(Oid tempNamespaceId)
 			case RELKIND_RELATION:
 			case RELKIND_SEQUENCE:
 			case RELKIND_VIEW:
+				AssertTupleDescHasOid(pgclass->rd_att);
 				object.classId = RelOid_pg_class;
-				object.objectId = tuple->t_data->t_oid;
+				object.objectId = HeapTupleGetOid(tuple);
 				object.objectSubId = 0;
 				performDeletion(&object, DROP_CASCADE);
 				break;
diff --git a/src/backend/catalog/pg_operator.c b/src/backend/catalog/pg_operator.c
index a2a591f1e627cf61367341ad369a5c102fa88eca..768c0237f9b57c40099d7bafb96d7676565f8e65 100644
--- a/src/backend/catalog/pg_operator.c
+++ b/src/backend/catalog/pg_operator.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/catalog/pg_operator.c,v 1.72 2002/07/18 16:47:23 tgl Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/catalog/pg_operator.c,v 1.73 2002/07/20 05:16:56 momjian Exp $
  *
  * NOTES
  *	  these routines moved here from commands/define.c and somewhat cleaned up.
@@ -144,7 +144,7 @@ OperatorGet(const char *operatorName,
 	{
 		RegProcedure oprcode = ((Form_pg_operator) GETSTRUCT(tup))->oprcode;
 
-		operatorObjectId = tup->t_data->t_oid;
+		operatorObjectId = HeapTupleGetOid(tup);
 		*defined = RegProcedureIsValid(oprcode);
 		ReleaseSysCache(tup);
 	}
@@ -918,7 +918,7 @@ makeOperatorDependencies(HeapTuple tuple, Oid pg_operator_relid)
 					referenced;
 
 	myself.classId = pg_operator_relid;
-	myself.objectId = tuple->t_data->t_oid;
+	myself.objectId = HeapTupleGetOid(tuple);
 	myself.objectSubId = 0;
 
 	/* In case we are updating a shell, delete any existing entries */
diff --git a/src/backend/catalog/pg_proc.c b/src/backend/catalog/pg_proc.c
index 29cfbb9b46e4312148314b4b4fcfea2e69848ce0..d0f19968a1c07edee45e8a0ff1a8def088165e44 100644
--- a/src/backend/catalog/pg_proc.c
+++ b/src/backend/catalog/pg_proc.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/catalog/pg_proc.c,v 1.79 2002/07/18 23:11:27 petere Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/catalog/pg_proc.c,v 1.80 2002/07/20 05:16:57 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -239,6 +239,7 @@ ProcedureCreate(const char *procedureName,
 		/* start out with empty permissions */
 		nulls[Anum_pg_proc_proacl-1] = 'n';
 
+		AssertTupleDescHasOid(tupDesc);
 		tup = heap_formtuple(tupDesc, values, nulls);
 		simple_heap_insert(rel, tup);
 		is_update = false;
@@ -254,7 +255,8 @@ ProcedureCreate(const char *procedureName,
 		CatalogCloseIndices(Num_pg_proc_indices, idescs);
 	}
 
-	retval = tup->t_data->t_oid;
+	AssertTupleDescHasOid(tupDesc);
+	retval = HeapTupleGetOid(tup);
 
 	/*
 	 * Create dependencies for the new function.  If we are updating an
diff --git a/src/backend/catalog/pg_type.c b/src/backend/catalog/pg_type.c
index 5cd5d291d7e6e150193ba262d26dd1e5697497ce..b911ecacc5d9914c5edfc7fa8cc4a69efaa8e805 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.74 2002/07/18 16:47:23 tgl Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/catalog/pg_type.c,v 1.75 2002/07/20 05:16:57 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -274,7 +274,8 @@ TypeCreate(const char *typeName,
 
 		simple_heap_update(pg_type_desc, &tup->t_self, tup);
 
-		typeObjectId = tup->t_data->t_oid;
+		AssertTupleDescHasOid(pg_type_desc->rd_att);
+		typeObjectId = HeapTupleGetOid(tup);
 	}
 	else
 	{
@@ -285,7 +286,8 @@ TypeCreate(const char *typeName,
 							 nulls);
 
 		/* preassign tuple Oid, if one was given */
-		tup->t_data->t_oid = assignedTypeOid;
+		AssertTupleDescHasOid(tupDesc);
+		HeapTupleSetOid(tup, assignedTypeOid);
 
 		typeObjectId = simple_heap_insert(pg_type_desc, tup);
 	}
diff --git a/src/backend/commands/comment.c b/src/backend/commands/comment.c
index aede51e0c98641dda059861935898c0cf5c57fea..83b8af7e6bfd1d0fd1aa464f52df445d6f0ffd7e 100644
--- a/src/backend/commands/comment.c
+++ b/src/backend/commands/comment.c
@@ -7,7 +7,7 @@
  * Copyright (c) 1996-2001, PostgreSQL Global Development Group
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/commands/comment.c,v 1.51 2002/07/14 23:38:13 tgl Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/commands/comment.c,v 1.52 2002/07/20 05:16:57 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -435,7 +435,8 @@ CommentDatabase(List *qualname, char *comment)
 
 	if (!HeapTupleIsValid(dbtuple))
 		elog(ERROR, "database \"%s\" does not exist", database);
-	oid = dbtuple->t_data->t_oid;
+	AssertTupleDescHasOid(pg_database->rd_att);
+	oid = HeapTupleGetOid(dbtuple);
 
 	/* Allow if the user matches the database dba or is a superuser */
 
@@ -481,7 +482,8 @@ CommentNamespace(List *qualname, char *comment)
 		elog(ERROR, "CommentSchema: Schema \"%s\" could not be found",
 			 namespace);
 
-	oid = tp->t_data->t_oid;
+	/* no TupleDesc here to Assert(...->tdhasoid); */
+	oid = HeapTupleGetOid(tp);
 
 	/* Check object security */
 	if (!pg_namespace_ownercheck(oid, GetUserId()))
@@ -552,7 +554,8 @@ CommentRule(List *qualname, char *comment)
 		if (HeapTupleIsValid(tuple))
 		{
 			reloid = ((Form_pg_rewrite) GETSTRUCT(tuple))->ev_class;
-			ruleoid = tuple->t_data->t_oid;
+			AssertTupleDescHasOid(RewriteRelation->rd_att);
+			ruleoid = HeapTupleGetOid(tuple);
 		}
 		else
 		{
@@ -592,7 +595,8 @@ CommentRule(List *qualname, char *comment)
 		if (!HeapTupleIsValid(tuple))
 			elog(ERROR, "rule \"%s\" does not exist", rulename);
 		Assert(reloid == ((Form_pg_rewrite) GETSTRUCT(tuple))->ev_class);
-		ruleoid = tuple->t_data->t_oid;
+		AssertTupleDescHasOid(relation->rd_att);
+		ruleoid = HeapTupleGetOid(tuple);
 		ReleaseSysCache(tuple);
 	}
 
@@ -805,7 +809,8 @@ CommentTrigger(List *qualname, char *comment)
 		elog(ERROR, "trigger \"%s\" for relation \"%s\" does not exist",
 			 trigname, RelationGetRelationName(relation));
 
-	oid = triggertuple->t_data->t_oid;
+	AssertTupleDescHasOid(pg_trigger->rd_att);
+	oid = HeapTupleGetOid(triggertuple);
 
 	systable_endscan(scan);
 
@@ -880,7 +885,7 @@ CommentConstraint(List *qualname, char *comment)
 			if (OidIsValid(conOid))
 				elog(ERROR, "Relation \"%s\" has multiple constraints named \"%s\"",
 					 RelationGetRelationName(relation), conName);
-			conOid = tuple->t_data->t_oid;
+			conOid = HeapTupleGetOid(tuple);
 		}
 	}
 
diff --git a/src/backend/commands/copy.c b/src/backend/commands/copy.c
index 438126a3e1809735552239602a2bf94912cbc58a..272e45d384e02a54a539bac3580a2146fff01a20 100644
--- a/src/backend/commands/copy.c
+++ b/src/backend/commands/copy.c
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/commands/copy.c,v 1.159 2002/07/18 04:43:50 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/commands/copy.c,v 1.160 2002/07/20 05:16:57 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -614,9 +614,13 @@ CopyTo(Relation rel, List *attlist, bool binary, bool oids,
 			/* Send OID if wanted --- note fld_count doesn't include it */
 			if (oids)
 			{
+				Oid oid;
+				
+				AssertTupleDescHasOid(tupDesc);
+				oid = HeapTupleGetOid(tuple);
 				fld_size = sizeof(Oid);
 				CopySendData(&fld_size, sizeof(int16), fp);
-				CopySendData(&tuple->t_data->t_oid, sizeof(Oid), fp);
+				CopySendData(&oid, sizeof(Oid), fp);
 			}
 		}
 		else
@@ -624,8 +628,9 @@ CopyTo(Relation rel, List *attlist, bool binary, bool oids,
 			/* Text format has no per-tuple header, but send OID if wanted */
 			if (oids)
 			{
+				AssertTupleDescHasOid(tupDesc);
 				string = DatumGetCString(DirectFunctionCall1(oidout,
-								ObjectIdGetDatum(tuple->t_data->t_oid)));
+								ObjectIdGetDatum(HeapTupleGetOid(tuple))));
 				CopySendString(string, fp);
 				pfree(string);
 				need_delim = true;
@@ -1069,7 +1074,7 @@ CopyFrom(Relation rel, List *attlist, bool binary, bool oids,
 		tuple = heap_formtuple(tupDesc, values, nulls);
   	
 		if (oids && file_has_oids)
-			tuple->t_data->t_oid = loaded_oid;
+			HeapTupleSetOid(tuple, loaded_oid);
 
 		skip_tuple = false;
 
diff --git a/src/backend/commands/dbcommands.c b/src/backend/commands/dbcommands.c
index c6bbb37186098cb49da25b13e1f9d32881e1edf6..2c401a6dbdc1cccb2df79765260500c0117ad1f0 100644
--- a/src/backend/commands/dbcommands.c
+++ b/src/backend/commands/dbcommands.c
@@ -9,7 +9,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/commands/dbcommands.c,v 1.96 2002/07/12 18:43:15 tgl Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/commands/dbcommands.c,v 1.97 2002/07/20 05:16:57 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -341,7 +341,8 @@ createdb(const CreatedbStmt *stmt)
 
 	tuple = heap_formtuple(pg_database_dsc, new_record, new_record_nulls);
 
-	tuple->t_data->t_oid = dboid;		/* override heap_insert's OID
+	AssertTupleDescHasOid(pg_database_dsc);
+	HeapTupleSetOid(tuple, dboid);		/* override heap_insert's OID
 										 * selection */
 
 	simple_heap_insert(pg_database_rel, tuple);
@@ -616,7 +617,10 @@ get_db_info(const char *name, Oid *dbIdP, int4 *ownerIdP,
 
 		/* oid of the database */
 		if (dbIdP)
-			*dbIdP = tuple->t_data->t_oid;
+		{
+			AssertTupleDescHasOid(relation->rd_att);
+			*dbIdP = HeapTupleGetOid(tuple);
+		}
 		/* sysid of the owner */
 		if (ownerIdP)
 			*ownerIdP = dbform->datdba;
diff --git a/src/backend/commands/explain.c b/src/backend/commands/explain.c
index b14ae4274f66c639fc08623b82369b6d59b9f52d..2c90df205afcc1e9aee8adcc448634ee0f3c071d 100644
--- a/src/backend/commands/explain.c
+++ b/src/backend/commands/explain.c
@@ -5,7 +5,7 @@
  * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994-5, Regents of the University of California
  *
- * $Header: /cvsroot/pgsql/src/backend/commands/explain.c,v 1.80 2002/06/20 20:29:27 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/commands/explain.c,v 1.81 2002/07/20 05:16:57 momjian Exp $
  *
  */
 
@@ -855,7 +855,7 @@ begin_text_output(CommandDest dest, char *title)
 	tstate = (TextOutputState *) palloc(sizeof(TextOutputState));
 
 	/* need a tuple descriptor representing a single TEXT column */
-	tupdesc = CreateTemplateTupleDesc(1);
+	tupdesc = CreateTemplateTupleDesc(1, WITHOUTOID);
 	TupleDescInitEntry(tupdesc, (AttrNumber) 1, title,
 					   TEXTOID, -1, 0, false);
 
diff --git a/src/backend/commands/functioncmds.c b/src/backend/commands/functioncmds.c
index 2ed9581b665d7c0c2fbf22f6ffe84b986e40d7bb..e4e89a8d755c2367be33ed5e1153c0373d619de4 100644
--- a/src/backend/commands/functioncmds.c
+++ b/src/backend/commands/functioncmds.c
@@ -9,7 +9,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/commands/functioncmds.c,v 1.9 2002/07/18 23:11:27 petere Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/commands/functioncmds.c,v 1.10 2002/07/20 05:16:57 momjian Exp $
  *
  * DESCRIPTION
  *	  These routines take the parse tree and pick out the
@@ -425,7 +425,7 @@ CreateFunction(CreateFunctionStmt *stmt)
 	if (!HeapTupleIsValid(languageTuple))
 		elog(ERROR, "language \"%s\" does not exist", languageName);
 
-	languageOid = languageTuple->t_data->t_oid;
+	languageOid = HeapTupleGetOid(languageTuple);
 	languageStruct = (Form_pg_language) GETSTRUCT(languageTuple);
 
 	if (languageStruct->lanpltrusted)
diff --git a/src/backend/commands/indexcmds.c b/src/backend/commands/indexcmds.c
index 5cf03bd11aa4262c2665fcd54e671f6e79f978ea..f36bad8ada17fdd7fa6f347dda6fa8a27be76ba4 100644
--- a/src/backend/commands/indexcmds.c
+++ b/src/backend/commands/indexcmds.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/commands/indexcmds.c,v 1.77 2002/07/12 18:43:16 tgl Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/commands/indexcmds.c,v 1.78 2002/07/20 05:16:57 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -141,7 +141,7 @@ DefineIndex(RangeVar *heapRelation,
 	if (!HeapTupleIsValid(tuple))
 		elog(ERROR, "DefineIndex: access method \"%s\" not found",
 			 accessMethodName);
-	accessMethodId = tuple->t_data->t_oid;
+	accessMethodId = HeapTupleGetOid(tuple);
 	accessMethodForm = (Form_pg_am) GETSTRUCT(tuple);
 
 	if (unique && !accessMethodForm->amcanunique)
@@ -496,7 +496,7 @@ GetAttrOpClass(IndexElem *attribute, Oid attrType,
 	 * Verify that the index operator class accepts this
 	 * datatype.  Note we will accept binary compatibility.
 	 */
-	opClassId = tuple->t_data->t_oid;
+	opClassId = HeapTupleGetOid(tuple);
 	opInputType = ((Form_pg_opclass) GETSTRUCT(tuple))->opcintype;
 
 	if (!IsBinaryCompatible(attrType, opInputType))
@@ -761,7 +761,7 @@ ReindexDatabase(const char *dbname, bool force, bool all)
 				relids = repalloc(relids, sizeof(Oid) * relalc);
 			}
 			MemoryContextSwitchTo(old);
-			relids[relcnt] = tuple->t_data->t_oid;
+			relids[relcnt] = HeapTupleGetOid(tuple);
 			relcnt++;
 		}
 	}
diff --git a/src/backend/commands/proclang.c b/src/backend/commands/proclang.c
index 98b613242625b11126c5d8a4208cd0132651edab..5dd70e9e55f009ccc7e94a59b5db25c4d4e4b9db 100644
--- a/src/backend/commands/proclang.c
+++ b/src/backend/commands/proclang.c
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/commands/proclang.c,v 1.36 2002/07/16 22:12:19 tgl Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/commands/proclang.c,v 1.37 2002/07/20 05:16:57 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -134,7 +134,7 @@ CreateProceduralLanguage(CreatePLangStmt *stmt)
 	 * Create dependencies for language
 	 */
 	myself.classId = RelationGetRelid(rel);
-	myself.objectId = tup->t_data->t_oid;
+	myself.objectId = HeapTupleGetOid(tup);
 	myself.objectSubId = 0;
 
 	/* dependency on the PL handler function */
@@ -191,7 +191,7 @@ DropProceduralLanguage(DropPLangStmt *stmt)
 			 languageName);
 
 	object.classId = get_system_catalog_relid(LanguageRelationName);
-	object.objectId = langTup->t_data->t_oid;
+	object.objectId = HeapTupleGetOid(langTup);
 	object.objectSubId = 0;
 
 	ReleaseSysCache(langTup);
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index 391adb042254ab7962ead36f1d25ee1f50353fc6..6b943723bb838a19c6143a8b013b32ad85f54b19 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/commands/tablecmds.c,v 1.23 2002/07/16 22:12:19 tgl Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/commands/tablecmds.c,v 1.24 2002/07/20 05:16:57 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -149,6 +149,7 @@ DefineRelation(CreateStmt *stmt, char relkind)
 	 * have to copy inherited constraints here.)
 	 */
 	descriptor = BuildDescForRelation(schema);
+	descriptor->tdhasoid = BoolToHasOid(stmt->hasoids || parentHasOids);
 
 	if (old_constraints != NIL)
 	{
@@ -1658,6 +1659,7 @@ AlterTableAddColumn(Oid myrelid,
 	tform = (Form_pg_type) GETSTRUCT(typeTuple);
 
 	attributeTuple = heap_addheader(Natts_pg_attribute,
+	                                false,
 									ATTRIBUTE_TUPLE_SIZE,
 									(void *) &attributeD);
 
@@ -1665,7 +1667,7 @@ AlterTableAddColumn(Oid myrelid,
 
 	attribute->attrelid = myrelid;
 	namestrcpy(&(attribute->attname), colDef->colname);
-	attribute->atttypid = typeTuple->t_data->t_oid;
+	attribute->atttypid = HeapTupleGetOid(typeTuple);
 	attribute->attstattarget = DEFAULT_ATTSTATTARGET;
 	attribute->attlen = tform->typlen;
 	attribute->attcacheoff = -1;
@@ -1682,6 +1684,7 @@ AlterTableAddColumn(Oid myrelid,
 
 	ReleaseSysCache(typeTuple);
 
+	AssertTupleDescHasNoOid(attrdesc->rd_att);
 	simple_heap_insert(attrdesc, attributeTuple);
 
 	/* Update indexes on pg_attribute */
@@ -1702,6 +1705,7 @@ AlterTableAddColumn(Oid myrelid,
 	newreltup = heap_copytuple(reltup);
 
 	((Form_pg_class) GETSTRUCT(newreltup))->relnatts = maxatts;
+	AssertTupleDescHasOid(pgclass->rd_att);
 	simple_heap_update(pgclass, &newreltup->t_self, newreltup);
 
 	/* keep catalog indices current */
@@ -3299,7 +3303,7 @@ AlterTableCreateToastTable(Oid relOid, bool silent)
 	sprintf(toast_idxname, "pg_toast_%u_index", relOid);
 
 	/* this is pretty painful...  need a tuple descriptor */
-	tupdesc = CreateTemplateTupleDesc(3);
+	tupdesc = CreateTemplateTupleDesc(3, WITHOUTOID);
 	TupleDescInitEntry(tupdesc, (AttrNumber) 1,
 					   "chunk_id",
 					   OIDOID,
diff --git a/src/backend/commands/trigger.c b/src/backend/commands/trigger.c
index b27dd0f4380f5aa56b1ab2c9a450e90f4dc53306..4c2ee626fe0422194360311f67d17ab0a03c0c3e 100644
--- a/src/backend/commands/trigger.c
+++ b/src/backend/commands/trigger.c
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/commands/trigger.c,v 1.121 2002/07/12 18:43:16 tgl Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/commands/trigger.c,v 1.122 2002/07/20 05:16:57 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -400,8 +400,9 @@ DropTrigger(Oid relid, const char *trigname, DropBehavior behavior)
 	if (!pg_class_ownercheck(relid, GetUserId()))
 		aclcheck_error(ACLCHECK_NOT_OWNER, get_rel_name(relid));
 
+	AssertTupleDescHasOid(tgrel->rd_att);
 	object.classId = RelationGetRelid(tgrel);
-	object.objectId = tup->t_data->t_oid;
+	object.objectId = HeapTupleGetOid(tup);
 	object.objectSubId = 0;
 
 	systable_endscan(tgscan);
@@ -671,7 +672,8 @@ RelationBuildTriggers(Relation relation)
 				 RelationGetRelationName(relation));
 		build = &(triggers[found]);
 
-		build->tgoid = htup->t_data->t_oid;
+		AssertTupleDescHasOid(tgrel->rd_att);
+		build->tgoid = HeapTupleGetOid(htup);
 		build->tgname = MemoryContextStrdup(CacheMemoryContext,
 							 DatumGetCString(DirectFunctionCall1(nameout,
 									NameGetDatum(&pg_trigger->tgname))));
@@ -1932,7 +1934,8 @@ DeferredTriggerSetState(ConstraintsSetStmt *stmt)
 				elog(ERROR, "Constraint '%s' is not deferrable",
 					 cname);
 
-			constr_oid = htup->t_data->t_oid;
+			AssertTupleDescHasOid(tgrel->rd_att);
+			constr_oid = HeapTupleGetOid(htup);
 			loid = lappendi(loid, constr_oid);
 			found = true;
 		}
diff --git a/src/backend/commands/typecmds.c b/src/backend/commands/typecmds.c
index c94b67883be030428ae32e91a543395b43dc5aa2..d387e17d5bb05031f7f2ad57a540b9bce4b26187 100644
--- a/src/backend/commands/typecmds.c
+++ b/src/backend/commands/typecmds.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/commands/typecmds.c,v 1.6 2002/07/16 22:12:19 tgl Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/commands/typecmds.c,v 1.7 2002/07/20 05:16:57 momjian Exp $
  *
  * DESCRIPTION
  *	  The "DefineFoo" routines take the parse tree and pick out the
@@ -396,7 +396,7 @@ DefineDomain(CreateDomainStmt *stmt)
 	typeTup = typenameType(stmt->typename);
 
 	baseType = (Form_pg_type) GETSTRUCT(typeTup);
-	basetypeoid = typeTup->t_data->t_oid;
+	basetypeoid = HeapTupleGetOid(typeTup);
 
 	/*
 	 * What we really don't want is domains of domains.  This could cause all sorts
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 1809981486f6781430c15b910104bb066b05dabe..c893ea86a09faef3d2fa15ddd048d3a74708c495 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -13,7 +13,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/commands/vacuum.c,v 1.231 2002/07/20 04:57:13 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/commands/vacuum.c,v 1.232 2002/07/20 05:16:57 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -392,7 +392,8 @@ getrels(const RangeVar *vacrel, const char *stmttype)
 		{
 			/* Make a relation list entry for this guy */
 			oldcontext = MemoryContextSwitchTo(vac_context);
-			vrl = lappendi(vrl, tuple->t_data->t_oid);
+			AssertTupleDescHasOid(pgclass->rd_att);
+			vrl = lappendi(vrl, HeapTupleGetOid(tuple));
 			MemoryContextSwitchTo(oldcontext);
 		}
 
@@ -1172,8 +1173,8 @@ scan_heap(VRelStats *vacrelstats, Relation onerel,
 			/*
 			 * Other checks...
 			 */
-			if (!OidIsValid(tuple.t_data->t_oid) &&
-				onerel->rd_rel->relhasoids)
+			if (onerel->rd_rel->relhasoids &&
+				!OidIsValid(HeapTupleGetOid(&tuple)))
 				elog(WARNING, "Rel %s: TID %u/%u: OID IS INVALID. TUPGONE %d.",
 					 relname, blkno, offnum, (int) tupgone);
 
diff --git a/src/backend/commands/vacuumlazy.c b/src/backend/commands/vacuumlazy.c
index 7e3b82fdd74a877d6f300a1cebf406e2d93215a3..bbf9e39ae80496038633a64b44af52d58358c58b 100644
--- a/src/backend/commands/vacuumlazy.c
+++ b/src/backend/commands/vacuumlazy.c
@@ -31,7 +31,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/commands/vacuumlazy.c,v 1.16 2002/06/20 20:29:27 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/commands/vacuumlazy.c,v 1.17 2002/07/20 05:16:57 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -368,8 +368,8 @@ lazy_scan_heap(Relation onerel, LVRelStats *vacrelstats,
 			/*
 			 * Other checks...
 			 */
-			if (!OidIsValid(tuple.t_data->t_oid) &&
-				onerel->rd_rel->relhasoids)
+			if (onerel->rd_rel->relhasoids &&
+				!OidIsValid(HeapTupleGetOid(&tuple)))
 				elog(WARNING, "Rel %s: TID %u/%u: OID IS INVALID. TUPGONE %d.",
 					 relname, blkno, offnum, (int) tupgone);
 
diff --git a/src/backend/executor/execJunk.c b/src/backend/executor/execJunk.c
index 94c375012e106a01eec194f4a30950161d1545dc..d808b85337afbb1081ff664d632a544a151a5b6a 100644
--- a/src/backend/executor/execJunk.c
+++ b/src/backend/executor/execJunk.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/executor/execJunk.c,v 1.30 2002/06/20 20:29:27 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/executor/execJunk.c,v 1.31 2002/07/20 05:16:57 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -170,7 +170,7 @@ ExecInitJunkFilter(List *targetList, TupleDesc tupType,
 	 * Now calculate the tuple type for the cleaned tuple (we were already
 	 * given the type for the original targetlist).
 	 */
-	cleanTupType = ExecTypeFromTL(cleanTargetList);
+	cleanTupType = ExecTypeFromTL(cleanTargetList, tupType->tdhasoid);
 
 	len = ExecTargetListLength(targetList);
 	cleanLength = ExecTargetListLength(cleanTargetList);
@@ -383,8 +383,8 @@ ExecRemoveJunk(JunkFilter *junkfilter, TupleTableSlot *slot)
 	 * information for the new "clean" tuple.
 	 *
 	 * Note: we use memory on the stack to optimize things when we are
-	 * dealing with a small number of tuples. for large tuples we just use
-	 * palloc.
+	 * dealing with a small number of attributes. for large tuples we
+	 * just use palloc.
 	 */
 	if (cleanLength > 64)
 	{
diff --git a/src/backend/executor/execMain.c b/src/backend/executor/execMain.c
index df7f3b42ae0ab3d40147c55f9711e6f86e17d26f..ce6d6794d268b3561be23208890ac5953f3ced91 100644
--- a/src/backend/executor/execMain.c
+++ b/src/backend/executor/execMain.c
@@ -27,7 +27,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/executor/execMain.c,v 1.170 2002/07/11 21:36:20 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/executor/execMain.c,v 1.171 2002/07/20 05:16:57 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -716,6 +716,10 @@ InitPlan(CmdType operation, Query *parseTree, Plan *plan, EState *estate)
 									   get_namespace_name(namespaceId));
 				}
 
+				/*
+				 * new "INTO" table is created WITH OIDS
+				 */
+				tupType->tdhasoid = WITHOID;
 				/*
 				 * have to copy tupType to get rid of constraints
 				 */
diff --git a/src/backend/executor/execQual.c b/src/backend/executor/execQual.c
index 63e5bab6ee911e369fcaa8d3d531b1d9831aab79..f74f8f1b41bd97bca49cbb717b70fa0138e390da 100644
--- a/src/backend/executor/execQual.c
+++ b/src/backend/executor/execQual.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/executor/execQual.c,v 1.99 2002/07/18 17:14:19 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/executor/execQual.c,v 1.100 2002/07/20 05:16:57 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -1770,7 +1770,10 @@ ExecTargetList(List *targetlist,
 	 * natts = 0 to deal with it.
 	 */
 	if (targettype == NULL)
+	{
 		targettype = &NullTupleDesc;
+		targettype->tdhasoid = WITHOUTOID;
+	}
 
 	/*
 	 * allocate an array of char's to hold the "null" information only if
diff --git a/src/backend/executor/execTuples.c b/src/backend/executor/execTuples.c
index 4f234f62b94d81884da6cf1f56c7015c3ceb0062..5124bd023fb826e8c63407d9ba1320901bf02e9d 100644
--- a/src/backend/executor/execTuples.c
+++ b/src/backend/executor/execTuples.c
@@ -15,7 +15,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/executor/execTuples.c,v 1.54 2002/07/18 04:40:30 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/executor/execTuples.c,v 1.55 2002/07/20 05:16:57 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -540,6 +540,7 @@ ExecInitNullTupleSlot(EState *estate, TupleDesc tupType)
 
 	ExecSetSlotDescriptor(slot, tupType, false);
 
+	NullTupleDesc.tdhasoid = WITHOUTOID;
 	nullTuple = heap_formtuple(&NullTupleDesc, values, nulls);
 
 	return ExecStoreTuple(nullTuple, slot, InvalidBuffer, true);
@@ -557,7 +558,7 @@ ExecInitNullTupleSlot(EState *estate, TupleDesc tupType)
  * ----------------------------------------------------------------
  */
 TupleDesc
-ExecTypeFromTL(List *targetList)
+ExecTypeFromTL(List *targetList, hasoid_t withoid)
 {
 	List	   *tlitem;
 	TupleDesc	typeInfo;
@@ -576,7 +577,7 @@ ExecTypeFromTL(List *targetList)
 	/*
 	 * allocate a new typeInfo
 	 */
-	typeInfo = CreateTemplateTupleDesc(len);
+	typeInfo = CreateTemplateTupleDesc(len, withoid);
 
 	/*
 	 * scan list, generate type info for each entry
diff --git a/src/backend/executor/execUtils.c b/src/backend/executor/execUtils.c
index 7799ed4d9353122c7b5643e8a9869120ab427a52..c2bd2de48abe47931c1d062f1d18f7fe23414d84 100644
--- a/src/backend/executor/execUtils.c
+++ b/src/backend/executor/execUtils.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/executor/execUtils.c,v 1.86 2002/06/26 21:58:56 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/executor/execUtils.c,v 1.87 2002/07/20 05:16:58 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -290,9 +290,23 @@ ExecAssignResultTypeFromOuterPlan(Plan *node, CommonState *commonstate)
 void
 ExecAssignResultTypeFromTL(Plan *node, CommonState *commonstate)
 {
+	ResultRelInfo *ri;
+	Relation	rel;
+	hasoid_t	withoid;
 	TupleDesc	tupDesc;
 
-	tupDesc = ExecTypeFromTL(node->targetlist);
+	ri = node->state->es_result_relation_info;
+	if (ri != NULL)
+		rel = ri->ri_RelationDesc;
+	else
+		rel = node->state->es_into_relation_descriptor;
+
+	if (rel != NULL)
+		withoid = BoolToHasOid(rel->rd_rel->relhasoids);
+	else
+		withoid = WITHOUTOID;
+		
+	tupDesc = ExecTypeFromTL(node->targetlist, withoid);
 	ExecAssignResultType(commonstate, tupDesc, true);
 }
 
diff --git a/src/backend/executor/nodeFunctionscan.c b/src/backend/executor/nodeFunctionscan.c
index 3645a188334b676955cc902c3119b97f990d95b0..d87f8e6fe887abb7c696ab9454a19e19c90d5980 100644
--- a/src/backend/executor/nodeFunctionscan.c
+++ b/src/backend/executor/nodeFunctionscan.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/executor/nodeFunctionscan.c,v 1.2 2002/06/20 20:29:28 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/executor/nodeFunctionscan.c,v 1.3 2002/07/20 05:16:58 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -234,7 +234,7 @@ ExecInitFunctionScan(FunctionScan *node, EState *estate, Plan *parent)
 		 */
 		char	   *attname = strVal(lfirst(rte->eref->colnames));
 
-		tupdesc = CreateTemplateTupleDesc(1);
+		tupdesc = CreateTemplateTupleDesc(1, WITHOUTOID);
 		TupleDescInitEntry(tupdesc,
 						   (AttrNumber) 1,
 						   attname,
diff --git a/src/backend/executor/spi.c b/src/backend/executor/spi.c
index 60b39768d53541e981226a962f366a185e33ad24..8535d875328ff0ff02ce4c27bce0092efc32b54c 100644
--- a/src/backend/executor/spi.c
+++ b/src/backend/executor/spi.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/executor/spi.c,v 1.71 2002/06/20 20:29:28 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/executor/spi.c,v 1.72 2002/07/20 05:16:58 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -435,11 +435,15 @@ SPI_modifytuple(Relation rel, HeapTuple tuple, int natts, int *attnum,
 	{
 		mtuple = heap_formtuple(rel->rd_att, v, n);
 		infomask = mtuple->t_data->t_infomask;
-		memmove(&(mtuple->t_data->t_oid), &(tuple->t_data->t_oid),
-				((char *) &(tuple->t_data->t_hoff) -
-				 (char *) &(tuple->t_data->t_oid)));
+		/*
+		 * copy t_xmin, t_cid, t_xmax, t_ctid, t_natts, t_infomask
+		 */
+		memmove((char *)mtuple->t_data, (char *)tuple->t_data,
+				offsetof(HeapTupleHeaderData, t_hoff));
 		mtuple->t_data->t_infomask = infomask;
 		mtuple->t_data->t_natts = numberOfAttributes;
+		if (rel->rd_rel->relhasoids)
+			HeapTupleSetOid(mtuple, HeapTupleGetOid(tuple));
 	}
 	else
 	{
diff --git a/src/backend/optimizer/util/clauses.c b/src/backend/optimizer/util/clauses.c
index f7dfb9e9298505cf8180e768011d1a3d7dabd9ca..9e8372139efc2f55410e68934c540fb117d729c5 100644
--- a/src/backend/optimizer/util/clauses.c
+++ b/src/backend/optimizer/util/clauses.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/optimizer/util/clauses.c,v 1.105 2002/07/18 17:14:19 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/optimizer/util/clauses.c,v 1.106 2002/07/20 05:16:58 momjian Exp $
  *
  * HISTORY
  *	  AUTHOR			DATE			MAJOR EVENT
@@ -1071,7 +1071,7 @@ CommuteClause(Expr *clause)
 
 	commuTup = (Form_pg_operator) GETSTRUCT(optup);
 
-	commu = makeOper(optup->t_data->t_oid,
+	commu = makeOper(HeapTupleGetOid(optup),
 					 commuTup->oprcode,
 					 commuTup->oprresult,
 					 ((Oper *) clause->oper)->opretset);
diff --git a/src/backend/parser/parse_oper.c b/src/backend/parser/parse_oper.c
index 663e83831b3de3e14485bbec9356573b797ee5a3..78128b4f698e60c3a5eb761dd92241b904cc1ae3 100644
--- a/src/backend/parser/parse_oper.c
+++ b/src/backend/parser/parse_oper.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/parser/parse_oper.c,v 1.57 2002/06/20 20:29:33 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/parser/parse_oper.c,v 1.58 2002/07/20 05:16:58 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -150,7 +150,7 @@ any_ordering_op(Oid argtype)
 Oid
 oprid(Operator op)
 {
-	return op->t_data->t_oid;
+	return HeapTupleGetOid(op);
 }
 
 /* given operator tuple, return the underlying function's OID */
diff --git a/src/backend/parser/parse_type.c b/src/backend/parser/parse_type.c
index 14510a69b1b565a7dac09239450a16ca7ade83d5..7eafe3e7c84bdef8a2b04263b45b7d9b63938474 100644
--- a/src/backend/parser/parse_type.c
+++ b/src/backend/parser/parse_type.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/parser/parse_type.c,v 1.44 2002/07/06 20:16:36 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/parser/parse_type.c,v 1.45 2002/07/20 05:16:58 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -283,7 +283,7 @@ typeTypeId(Type tp)
 {
 	if (tp == NULL)
 		elog(ERROR, "typeTypeId() called with NULL type struct");
-	return tp->t_data->t_oid;
+	return HeapTupleGetOid(tp);
 }
 
 /* given type (as type struct), return the length of type */
diff --git a/src/backend/postmaster/pgstat.c b/src/backend/postmaster/pgstat.c
index b578305b4c5d04084bc70461ba84341704221821..58bd1ef69b92657d6ad32dbbad36bf685d10f35b 100644
--- a/src/backend/postmaster/pgstat.c
+++ b/src/backend/postmaster/pgstat.c
@@ -16,7 +16,7 @@
  *
  *	Copyright (c) 2001, PostgreSQL Global Development Group
  *
- *	$Header: /cvsroot/pgsql/src/backend/postmaster/pgstat.c,v 1.21 2002/05/20 23:51:43 tgl Exp $
+ *	$Header: /cvsroot/pgsql/src/backend/postmaster/pgstat.c,v 1.22 2002/07/20 05:16:58 momjian Exp $
  * ----------
  */
 #include "postgres.h"
@@ -628,7 +628,8 @@ pgstat_vacuum_tabstat(void)
 			dbidlist = (Oid *) repalloc((char *) dbidlist,
 										sizeof(Oid) * dbidalloc);
 		}
-		dbidlist[dbidused++] = dbtup->t_data->t_oid;
+		AssertTupleDescHasOid(dbrel->rd_att);
+		dbidlist[dbidused++] = HeapTupleGetOid(dbtup);
 	}
 	heap_endscan(dbscan);
 	heap_close(dbrel, AccessShareLock);
diff --git a/src/backend/rewrite/rewriteRemove.c b/src/backend/rewrite/rewriteRemove.c
index 4ce9f3f2b908aa605648cf31746ae57404eaf0ed..1fd5f36ce55851b43889540844e17b6a020424a1 100644
--- a/src/backend/rewrite/rewriteRemove.c
+++ b/src/backend/rewrite/rewriteRemove.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteRemove.c,v 1.51 2002/07/12 18:43:17 tgl Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteRemove.c,v 1.52 2002/07/20 05:16:58 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -69,7 +69,7 @@ RemoveRewriteRule(Oid owningRel, const char *ruleName, DropBehavior behavior)
 	 * Do the deletion
 	 */
 	object.classId = get_system_catalog_relid(RewriteRelationName);
-	object.objectId = tuple->t_data->t_oid;
+	object.objectId = HeapTupleGetOid(tuple);
 	object.objectSubId = 0;
 
 	ReleaseSysCache(tuple);
diff --git a/src/backend/utils/adt/regproc.c b/src/backend/utils/adt/regproc.c
index 18569e5479b0365a2f25b7626e30d327df6959aa..7dfd26d2db12c452d72d97ec15caa531e131ecff 100644
--- a/src/backend/utils/adt/regproc.c
+++ b/src/backend/utils/adt/regproc.c
@@ -13,7 +13,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/utils/adt/regproc.c,v 1.70 2002/06/20 20:29:38 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/utils/adt/regproc.c,v 1.71 2002/07/20 05:16:58 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -110,7 +110,8 @@ regprocin(PG_FUNCTION_ARGS)
 
 		while (HeapTupleIsValid(tuple = systable_getnext(sysscan)))
 		{
-			result = (RegProcedure) tuple->t_data->t_oid;
+			AssertTupleDescHasOid(hdesc->rd_att);
+			result = (RegProcedure) HeapTupleGetOid(tuple);
 			if (++matches > 1)
 				break;
 		}
@@ -414,7 +415,8 @@ regoperin(PG_FUNCTION_ARGS)
 
 		while (HeapTupleIsValid(tuple = systable_getnext(sysscan)))
 		{
-			result = tuple->t_data->t_oid;
+			AssertTupleDescHasOid(hdesc->rd_att);
+			result = HeapTupleGetOid(tuple);
 			if (++matches > 1)
 				break;
 		}
@@ -731,7 +733,10 @@ regclassin(PG_FUNCTION_ARGS)
 									 SnapshotNow, 1, skey);
 
 		if (HeapTupleIsValid(tuple = systable_getnext(sysscan)))
-			result = tuple->t_data->t_oid;
+		{
+			AssertTupleDescHasOid(hdesc->rd_att);
+			result = HeapTupleGetOid(tuple);
+		}
 		else
 			elog(ERROR, "No class with name %s", class_name_or_oid);
 
@@ -884,7 +889,10 @@ regtypein(PG_FUNCTION_ARGS)
 									 SnapshotNow, 1, skey);
 
 		if (HeapTupleIsValid(tuple = systable_getnext(sysscan)))
-			result = tuple->t_data->t_oid;
+		{
+			AssertTupleDescHasOid(hdesc->rd_att);
+			result = HeapTupleGetOid(tuple);
+		}
 		else
 			elog(ERROR, "No type with name %s", typ_name_or_oid);
 
diff --git a/src/backend/utils/adt/sets.c b/src/backend/utils/adt/sets.c
index d03fd88e4df0c8fd26c26975f960491cc77a5fe9..0a378c472885c15e9c57b2d170b2284eb09f7154 100644
--- a/src/backend/utils/adt/sets.c
+++ b/src/backend/utils/adt/sets.c
@@ -10,7 +10,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/utils/adt/Attic/sets.c,v 1.47 2002/07/18 23:11:29 petere Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/utils/adt/Attic/sets.c,v 1.48 2002/07/20 05:16:58 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -119,7 +119,8 @@ SetDefine(char *querystr, Oid elemType)
 
 		simple_heap_update(procrel, &newtup->t_self, newtup);
 
-		setoid = newtup->t_data->t_oid;
+		AssertTupleDescHasOid(procrel->rd_att);
+		setoid = HeapTupleGetOid(newtup);
 
 		if (RelationGetForm(procrel)->relhasindex)
 		{
diff --git a/src/backend/utils/cache/catcache.c b/src/backend/utils/cache/catcache.c
index a4f05a7d117e79ad1df5de44e8e5bd82d49f5398..21f1e01dabb9829aadbaa94afa3af2464c410c3f 100644
--- a/src/backend/utils/cache/catcache.c
+++ b/src/backend/utils/cache/catcache.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/utils/cache/catcache.c,v 1.96 2002/06/20 20:29:39 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/utils/cache/catcache.c,v 1.97 2002/07/20 05:16:58 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -218,7 +218,7 @@ CatalogCacheComputeTupleHashValue(CatCache *cache, HeapTuple tuple)
 		case 4:
 			cur_skey[3].sk_argument =
 				(cache->cc_key[3] == ObjectIdAttributeNumber)
-				? ObjectIdGetDatum(tuple->t_data->t_oid)
+				? ObjectIdGetDatum(HeapTupleGetOid(tuple))
 				: fastgetattr(tuple,
 							  cache->cc_key[3],
 							  cache->cc_tupdesc,
@@ -228,7 +228,7 @@ CatalogCacheComputeTupleHashValue(CatCache *cache, HeapTuple tuple)
 		case 3:
 			cur_skey[2].sk_argument =
 				(cache->cc_key[2] == ObjectIdAttributeNumber)
-				? ObjectIdGetDatum(tuple->t_data->t_oid)
+				? ObjectIdGetDatum(HeapTupleGetOid(tuple))
 				: fastgetattr(tuple,
 							  cache->cc_key[2],
 							  cache->cc_tupdesc,
@@ -238,7 +238,7 @@ CatalogCacheComputeTupleHashValue(CatCache *cache, HeapTuple tuple)
 		case 2:
 			cur_skey[1].sk_argument =
 				(cache->cc_key[1] == ObjectIdAttributeNumber)
-				? ObjectIdGetDatum(tuple->t_data->t_oid)
+				? ObjectIdGetDatum(HeapTupleGetOid(tuple))
 				: fastgetattr(tuple,
 							  cache->cc_key[1],
 							  cache->cc_tupdesc,
@@ -248,7 +248,7 @@ CatalogCacheComputeTupleHashValue(CatCache *cache, HeapTuple tuple)
 		case 1:
 			cur_skey[0].sk_argument =
 				(cache->cc_key[0] == ObjectIdAttributeNumber)
-				? ObjectIdGetDatum(tuple->t_data->t_oid)
+				? ObjectIdGetDatum(HeapTupleGetOid(tuple))
 				: fastgetattr(tuple,
 							  cache->cc_key[0],
 							  cache->cc_tupdesc,
@@ -572,7 +572,7 @@ AtEOXact_CatCache(bool isCommit)
 			if (isCommit)
 				elog(WARNING, "Cache reference leak: cache %s (%d), tuple %u has count %d",
 					 ct->my_cache->cc_relname, ct->my_cache->id,
-					 ct->tuple.t_data->t_oid,
+					 HeapTupleGetOid(&ct->tuple),
 					 ct->refcount);
 			ct->refcount = 0;
 		}
@@ -717,7 +717,7 @@ CatalogCacheFlushRelation(Oid relId)
 					continue;
 
 				if (cache->cc_reloidattr == ObjectIdAttributeNumber)
-					tupRelid = ct->tuple.t_data->t_oid;
+					tupRelid = HeapTupleGetOid(&ct->tuple);
 				else
 				{
 					bool		isNull;
@@ -907,6 +907,7 @@ CatalogCacheInitializeCache(CatCache *cache)
 	 * copy the relcache's tuple descriptor to permanent cache storage
 	 */
 	tupdesc = CreateTupleDescCopyConstr(RelationGetDescr(relation));
+	AssertTupleDescHasOidIsValid(tupdesc);
 
 	/*
 	 * get the relation's OID and relisshared flag, too
@@ -1685,7 +1686,11 @@ build_dummy_tuple(CatCache *cache, int nkeys, ScanKey skeys)
 	}
 
 	ntp = heap_formtuple(tupDesc, values, nulls);
-	ntp->t_data->t_oid = tupOid;
+	if (tupOid != InvalidOid)
+	{
+		AssertTupleDescHasOid(tupDesc);
+		HeapTupleSetOid(ntp, tupOid);
+	}
 
 	pfree(values);
 	pfree(nulls);
diff --git a/src/backend/utils/cache/inval.c b/src/backend/utils/cache/inval.c
index 02a6d8f8ddc8300775c3241982e2877bea823fec..c292926238171082c7481e6400a047b3bba228c1 100644
--- a/src/backend/utils/cache/inval.c
+++ b/src/backend/utils/cache/inval.c
@@ -74,7 +74,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/utils/cache/inval.c,v 1.52 2002/06/20 20:29:39 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/utils/cache/inval.c,v 1.53 2002/07/20 05:16:58 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -525,7 +525,10 @@ PrepareForTupleInvalidation(Relation relation, HeapTuple tuple,
 	tupleRelId = RelationGetRelid(relation);
 
 	if (tupleRelId == RelOid_pg_class)
-		relationId = tuple->t_data->t_oid;
+	{
+		AssertTupleDescHasOid(relation->rd_att);
+		relationId = HeapTupleGetOid(tuple);
+	}
 	else if (tupleRelId == RelOid_pg_attribute)
 		relationId = ((Form_pg_attribute) GETSTRUCT(tuple))->attrelid;
 	else
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index 532c68f7b3a8f718f10c79bc67c384212636041a..d7fd83775b1b77d19ee00d2c8caf360849dd726c 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/utils/cache/relcache.c,v 1.167 2002/07/15 01:57:51 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/utils/cache/relcache.c,v 1.168 2002/07/20 05:16:58 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -440,7 +440,7 @@ AllocateRelationDesc(Relation relation, Form_pg_class relp)
 	relation->rd_rel = relationForm;
 
 	/* and allocate attribute tuple form storage */
-	relation->rd_att = CreateTemplateTupleDesc(relationForm->relnatts);
+	relation->rd_att = CreateTemplateTupleDesc(relationForm->relnatts, BoolToHasOid(relationForm->relhasoids));
 
 	MemoryContextSwitchTo(oldcxt);
 
@@ -701,7 +701,8 @@ RelationBuildRuleLock(Relation relation)
 		rule = (RewriteRule *) MemoryContextAlloc(rulescxt,
 												  sizeof(RewriteRule));
 
-		rule->ruleId = rewrite_tuple->t_data->t_oid;
+		AssertTupleDescHasOid(rewrite_tupdesc);
+		rule->ruleId = HeapTupleGetOid(rewrite_tuple);
 
 		rule->event = rewrite_form->ev_type - '0';
 		rule->attrno = rewrite_form->ev_attr;
@@ -839,7 +840,7 @@ RelationBuildDesc(RelationBuildDescInfo buildinfo,
 	/*
 	 * get information from the pg_class_tuple
 	 */
-	relid = pg_class_tuple->t_data->t_oid;
+	relid = HeapTupleGetOid(pg_class_tuple);
 	relp = (Form_pg_class) GETSTRUCT(pg_class_tuple);
 
 	/*
@@ -872,6 +873,7 @@ RelationBuildDesc(RelationBuildDescInfo buildinfo,
 	 * initialize the tuple descriptor (relation->rd_att).
 	 */
 	RelationBuildTupleDesc(buildinfo, relation);
+	RelationGetDescr(relation)->tdhasoid = BoolToHasOid(RelationGetForm(relation)->relhasoids);
 
 	/*
 	 * Fetch rules and triggers that affect this relation
@@ -1395,7 +1397,7 @@ formrdesc(const char *relationName,
 	 * right because it will never be replaced.  The input values must be
 	 * correctly defined by macros in src/include/catalog/ headers.
 	 */
-	relation->rd_att = CreateTemplateTupleDesc(natts);
+	relation->rd_att = CreateTemplateTupleDesc(natts, BoolToHasOid(relation->rd_rel->relhasoids));
 
 	/*
 	 * initialize tuple desc info
@@ -2067,7 +2069,7 @@ RelationBuildLocalRelation(const char *relname,
 	rel->rd_rel->relnamespace = relnamespace;
 
 	rel->rd_rel->relkind = RELKIND_UNCATALOGED;
-	rel->rd_rel->relhasoids = true;
+	rel->rd_rel->relhasoids = (rel->rd_att->tdhasoid == WITHOID);
 	rel->rd_rel->relnatts = natts;
 	rel->rd_rel->reltype = InvalidOid;
 
@@ -2313,6 +2315,7 @@ RelationCacheInitializePhase2(void)
 			 */
 			Assert(relation->rd_rel != NULL);
 			memcpy((char *) relation->rd_rel, (char *) relp, CLASS_TUPLE_SIZE);
+			relation->rd_att->tdhasoid = BoolToHasOid(relp->relhasoids);
 
 			ReleaseSysCache(htup);
 		}
@@ -2774,7 +2777,7 @@ load_relcache_init_file(void)
 		rel->rd_rel = relform;
 
 		/* initialize attribute tuple forms */
-		rel->rd_att = CreateTemplateTupleDesc(relform->relnatts);
+		rel->rd_att = CreateTemplateTupleDesc(relform->relnatts, BoolToHasOid(relform->relhasoids));
 
 		/* next read all the attribute tuple form data entries */
 		for (i = 0; i < relform->relnatts; i++)
diff --git a/src/backend/utils/cache/syscache.c b/src/backend/utils/cache/syscache.c
index 5f0be16b75a8f20f50d8ee6887d36fe7f0489b2c..9966a8d881f0e523da8ef9f96ae2d14dc4dd3dd8 100644
--- a/src/backend/utils/cache/syscache.c
+++ b/src/backend/utils/cache/syscache.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/utils/cache/syscache.c,v 1.82 2002/07/18 23:11:29 petere Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/utils/cache/syscache.c,v 1.83 2002/07/20 05:16:58 momjian Exp $
  *
  * NOTES
  *	  These routines allow the parser/planner/executor to perform
@@ -597,7 +597,7 @@ GetSysCacheOid(int cacheId,
 	tuple = SearchSysCache(cacheId, key1, key2, key3, key4);
 	if (!HeapTupleIsValid(tuple))
 		return InvalidOid;
-	result = tuple->t_data->t_oid;
+	result = HeapTupleGetOid(tuple);
 	ReleaseSysCache(tuple);
 	return result;
 }
diff --git a/src/backend/utils/init/postinit.c b/src/backend/utils/init/postinit.c
index 04e33b9b1981003ae1ecd1616735985113716eb3..433b9a5ed052ac3df12627949299e73bfe75eae9 100644
--- a/src/backend/utils/init/postinit.c
+++ b/src/backend/utils/init/postinit.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/utils/init/postinit.c,v 1.108 2002/06/20 20:29:40 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/utils/init/postinit.c,v 1.109 2002/07/20 05:16:59 momjian Exp $
  *
  *
  *-------------------------------------------------------------------------
@@ -98,8 +98,9 @@ ReverifyMyDatabase(const char *name)
 	pgdbscan = heap_beginscan(pgdbrel, SnapshotNow, 1, &key);
 
 	tup = heap_getnext(pgdbscan, ForwardScanDirection);
+	AssertTupleDescHasOid(pgdbrel->rd_att);
 	if (!HeapTupleIsValid(tup) ||
-		tup->t_data->t_oid != MyDatabaseId)
+		HeapTupleGetOid(tup) != MyDatabaseId)
 	{
 		/* OOPS */
 		heap_close(pgdbrel, AccessShareLock);
diff --git a/src/backend/utils/misc/database.c b/src/backend/utils/misc/database.c
index 9b2cb49022fa21e3e50eeb507ce9226f0899b930..fd80b23bb897396341fa9adc5176ce433f2073eb 100644
--- a/src/backend/utils/misc/database.c
+++ b/src/backend/utils/misc/database.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/utils/misc/Attic/database.c,v 1.51 2002/06/20 20:29:40 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/utils/misc/Attic/database.c,v 1.52 2002/07/20 05:16:59 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -220,7 +220,7 @@ GetRawDatabaseInfo(const char *name, Oid *db_id, char *path)
 			if (strcmp(name, NameStr(tup_db->datname)) == 0)
 			{
 				/* Found it; extract the OID and the database path. */
-				*db_id = tup.t_data->t_oid;
+				*db_id = HeapTupleGetOid(&tup);
 				pathlen = VARSIZE(&(tup_db->datpath)) - VARHDRSZ;
 				if (pathlen < 0)
 					pathlen = 0;				/* pure paranoia */
diff --git a/src/include/access/heapam.h b/src/include/access/heapam.h
index eafa322457261a229f966198067732687e66a4be..b0e32214adff841d8c35f64cb924b2954d20582d 100644
--- a/src/include/access/heapam.h
+++ b/src/include/access/heapam.h
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: heapam.h,v 1.77 2002/06/20 20:29:43 momjian Exp $
+ * $Id: heapam.h,v 1.78 2002/07/20 05:16:59 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -200,6 +200,6 @@ extern HeapTuple heap_formtuple(TupleDesc tupleDescriptor,
 extern HeapTuple heap_modifytuple(HeapTuple tuple,
 		Relation relation, Datum *replValue, char *replNull, char *repl);
 extern void heap_freetuple(HeapTuple tuple);
-extern HeapTuple heap_addheader(int natts, Size structlen, void *structure);
+extern HeapTuple heap_addheader(int natts, bool withoid, Size structlen, void *structure);
 
 #endif   /* HEAPAM_H */
diff --git a/src/include/access/htup.h b/src/include/access/htup.h
index 87f1727f9e4075674044bccd5a8214f1dda23418..5da1c3608ed98e5d00cc0c1d973d804f901b1598 100644
--- a/src/include/access/htup.h
+++ b/src/include/access/htup.h
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: htup.h,v 1.56 2002/07/08 01:52:23 momjian Exp $
+ * $Id: htup.h,v 1.57 2002/07/20 05:16:59 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -70,8 +70,6 @@
 */
 typedef struct HeapTupleHeaderData
 {
-	Oid			t_oid;			/* OID of this tuple -- 4 bytes */
-
 	TransactionId t_xmin;		/* Xmin -- 4 bytes each */
 	TransactionId t_cid;		/* Cmin, Cmax, Xvac */
 	TransactionId t_xmax;		/* Xmax, Cmax */
@@ -84,7 +82,7 @@ typedef struct HeapTupleHeaderData
 
 	uint8		t_hoff;			/* sizeof header incl. bitmap, padding */
 
-	/* ^ - 27 bytes - ^ */
+	/* ^ - 23 bytes - ^ */
 
 	bits8		t_bits[1];		/* bitmap of NULLs -- VARIABLE LENGTH */
 
@@ -123,10 +121,42 @@ typedef HeapTupleHeaderData *HeapTupleHeader;
 
 #define HEAP_XACT_MASK			0xFFF0	/* visibility-related bits */
 
+/* paranoid checking */
+
+#ifdef DEBUG_TUPLE_ACCESS
+
+#define HeapTupleHeaderExpectedLen(tup, withoid) \
+	MAXALIGN(offsetof(HeapTupleHeaderData, t_bits) + \
+	         (((tup)->t_infomask & HEAP_HASNULL) \
+	          ? BITMAPLEN((tup)->t_natts) : 0) + \
+		     ((withoid) ? sizeof(Oid) : 0) \
+	        ) 
+
+#define AssertHeapTupleHeaderHoffIsValid(tup, withoid) \
+	AssertMacro((tup)->t_hoff == HeapTupleHeaderExpectedLen(tup, withoid))
+
+#else
+
+#define AssertHeapTupleHeaderHoffIsValid(tup, withoid) ((void)true)
+
+#endif  /* DEBUG_TUPLE_ACCESS */
 
 
 /* HeapTupleHeader accessor macros */
 
+#define HeapTupleHeaderGetOid(tup) \
+( \
+	AssertHeapTupleHeaderHoffIsValid(tup, true), \
+	*((Oid *)((char *)(tup) + (tup)->t_hoff - sizeof(Oid))) \
+)
+
+#define HeapTupleHeaderSetOid(tup, oid) \
+( \
+	AssertHeapTupleHeaderHoffIsValid(tup, true), \
+	*((Oid *)((char *)(tup) + (tup)->t_hoff - sizeof(Oid))) = (oid) \
+)
+		
+
 #define HeapTupleHeaderGetXmin(tup) \
 ( \
 	(tup)->t_xmin \
@@ -406,4 +436,10 @@ typedef HeapTupleData *HeapTuple;
 #define HeapTupleHasExtended(tuple) \
 		((((HeapTuple)(tuple))->t_data->t_infomask & HEAP_HASEXTENDED) != 0)
 
+#define HeapTupleGetOid(tuple) \
+		HeapTupleHeaderGetOid(((HeapTuple)(tuple))->t_data)
+
+#define HeapTupleSetOid(tuple, oid) \
+		HeapTupleHeaderSetOid(((HeapTuple)(tuple))->t_data, (oid))
+
 #endif   /* HTUP_H */
diff --git a/src/include/access/tupdesc.h b/src/include/access/tupdesc.h
index 0f277d1c9e8ebaa859a4c8710c347c30930d00ef..c8c9839985e454f3e47d19acf2dcf8ed9ed56835 100644
--- a/src/include/access/tupdesc.h
+++ b/src/include/access/tupdesc.h
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: tupdesc.h,v 1.36 2002/07/12 18:43:19 tgl Exp $
+ * $Id: tupdesc.h,v 1.37 2002/07/20 05:16:59 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -41,6 +41,11 @@ typedef struct tupleConstr
 	bool		has_not_null;
 } TupleConstr;
 
+typedef char hasoid_t;
+#define WITHOID 'C'
+#define WITHOUTOID 'S'
+#define UNDEFOID '?'
+#define BoolToHasOid(b) ((b) ? WITHOID : WITHOUTOID)
 /*
  * This structure contains all information (i.e. from Classes
  * pg_attribute, pg_attrdef, pg_constraint) for a tuple.
@@ -51,9 +56,27 @@ typedef struct tupleDesc
 	Form_pg_attribute *attrs;
 	/* attrs[N] is a pointer to the description of Attribute Number N+1.  */
 	TupleConstr *constr;
+	hasoid_t	tdhasoid;		/* Tuple has an oid attribute in its header */
 }	*TupleDesc;
 
-extern TupleDesc CreateTemplateTupleDesc(int natts);
+#ifdef DEBUG_TUPLE_ACCESS
+
+#define AssertTupleDescHasOidIsValid(td) \
+	Assert(((td)->tdhasoid == WITHOID) || ((td)->tdhasoid == WITHOUTOID))
+#define AssertTupleDescHasOid(td) \
+	Assert((td)->tdhasoid == WITHOID)
+#define AssertTupleDescHasNoOid(td) \
+	Assert((td)->tdhasoid == WITHOUTOID)
+
+#else
+
+#define AssertTupleDescHasOidIsValid(td)
+#define AssertTupleDescHasOid(td)
+#define AssertTupleDescHasNoOid(td)
+
+#endif
+
+extern TupleDesc CreateTemplateTupleDesc(int natts, hasoid_t withoid);
 
 extern TupleDesc CreateTupleDesc(int natts, Form_pg_attribute *attrs);
 
diff --git a/src/include/executor/executor.h b/src/include/executor/executor.h
index ee399f9b3a8bae02eeec703bc9853551d95eaa8a..427c146a574c0caa1bbe7e0843c62364bf789a39 100644
--- a/src/include/executor/executor.h
+++ b/src/include/executor/executor.h
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: executor.h,v 1.69 2002/06/26 21:58:56 momjian Exp $
+ * $Id: executor.h,v 1.70 2002/07/20 05:16:59 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -118,7 +118,7 @@ extern void ExecInitScanTupleSlot(EState *estate,
 extern TupleTableSlot *ExecInitExtraTupleSlot(EState *estate);
 extern TupleTableSlot *ExecInitNullTupleSlot(EState *estate,
 					  TupleDesc tupType);
-extern TupleDesc ExecTypeFromTL(List *targetList);
+extern TupleDesc ExecTypeFromTL(List *targetList, hasoid_t withoid);
 extern void SetChangedParamList(Plan *node, List *newchg);
 
 /*
diff --git a/src/include/pg_config.h.in b/src/include/pg_config.h.in
index b3a5b8d6e1b9e849a464f892fb6cee5a6263be65..7a616440cf47f08b7e6386e6a6975a8b400bede3 100644
--- a/src/include/pg_config.h.in
+++ b/src/include/pg_config.h.in
@@ -8,7 +8,7 @@
  * or in pg_config.h afterwards.  Of course, if you edit pg_config.h, then your
  * changes will be overwritten the next time you run configure.
  *
- * $Id: pg_config.h.in,v 1.24 2002/05/05 00:03:29 tgl Exp $
+ * $Id: pg_config.h.in,v 1.25 2002/07/20 05:16:59 momjian Exp $
  */
 
 #ifndef PG_CONFIG_H
@@ -311,6 +311,12 @@
 /* #define ACLDEBUG */
 /* #define RTDEBUG */
 /* #define GISTDEBUG */
+/*
+ * DEBUG_TUPLE_ACCESS enables paranoid assertions during
+ * elimination of oids from the fixed sized part of HeapTupleHeader.
+ * This is expected to be undef'd after v7.3 release at the latest.
+ */
+#define DEBUG_TUPLE_ACCESS
 
 /*
  * defining unsafe floats will make float4 and float8 ops faster
diff --git a/src/pl/plpython/plpython.c b/src/pl/plpython/plpython.c
index 4c88d93153520e4a24460fa165674617adbaca7c..6d26cc75ddb73399d22294ac5620a7309e89b070 100644
--- a/src/pl/plpython/plpython.c
+++ b/src/pl/plpython/plpython.c
@@ -29,7 +29,7 @@
  * MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
  *
  * IDENTIFICATION
- *	$Header: /cvsroot/pgsql/src/pl/plpython/plpython.c,v 1.18 2002/06/15 19:54:24 momjian Exp $
+ *	$Header: /cvsroot/pgsql/src/pl/plpython/plpython.c,v 1.19 2002/07/20 05:16:59 momjian Exp $
  *
  *********************************************************************
  */
@@ -2091,7 +2091,7 @@ PLy_spi_prepare(PyObject * self, PyObject * args)
 				Py_DECREF(optr);
 				optr = NULL;	/* this is important */
 
-				plan->types[i] = typeTup->t_data->t_oid;
+				plan->types[i] = HeapTupleGetOid(typeTup);
 				typeStruct = (Form_pg_type) GETSTRUCT(typeTup);
 				if (typeStruct->typrelid == InvalidOid)
 					PLy_output_datum_func(&plan->args[i], typeStruct);
diff --git a/src/pl/tcl/pltcl.c b/src/pl/tcl/pltcl.c
index 2888f4d9aaae88e28c9da4b9e3a7405b947c29cb..6f2080b1a433498b7ad12988ae02e51ed993f212 100644
--- a/src/pl/tcl/pltcl.c
+++ b/src/pl/tcl/pltcl.c
@@ -31,7 +31,7 @@
  *	  ENHANCEMENTS, OR MODIFICATIONS.
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/pl/tcl/pltcl.c,v 1.58 2002/07/18 05:07:30 ishii Exp $
+ *	  $Header: /cvsroot/pgsql/src/pl/tcl/pltcl.c,v 1.59 2002/07/20 05:16:59 momjian Exp $
  *
  **********************************************************************/
 
@@ -1743,7 +1743,7 @@ pltcl_SPI_prepare(ClientData cdata, Tcl_Interp *interp,
 	{
 		/* XXX should extend this to allow qualified type names */
 		typeTup = typenameType(makeTypeName(args[i]));
-		qdesc->argtypes[i] = typeTup->t_data->t_oid;
+		qdesc->argtypes[i] = HeapTupleGetOid(typeTup);
 		perm_fmgr_info(((Form_pg_type) GETSTRUCT(typeTup))->typinput,
 					   &(qdesc->arginfuncs[i]));
 		qdesc->argtypelems[i] = ((Form_pg_type) GETSTRUCT(typeTup))->typelem;
diff --git a/src/test/regress/parallel_schedule b/src/test/regress/parallel_schedule
index 218a5bd14d98ab308549a55f244e72d6b907ec13..fd9ae6c89a194d1ad616c7168dcadf8b2ab2712b 100644
--- a/src/test/regress/parallel_schedule
+++ b/src/test/regress/parallel_schedule
@@ -75,3 +75,6 @@ test: select_views alter_table portals_p2 rules foreign_key
 # ----------
 # "plpgsql" cannot run concurrently with "rules"
 test: limit plpgsql temp domain rangefuncs copy2
+
+test: without_oid
+
diff --git a/src/test/regress/serial_schedule b/src/test/regress/serial_schedule
index 3e79a9c307316e048dbd7ca834a8a8253fba68b0..566b39622998bb8f0a7c983c7511e6215bcdd146 100644
--- a/src/test/regress/serial_schedule
+++ b/src/test/regress/serial_schedule
@@ -1,4 +1,4 @@
-# $Header: /cvsroot/pgsql/src/test/regress/serial_schedule,v 1.12 2002/07/20 04:57:13 momjian Exp $
+# $Header: /cvsroot/pgsql/src/test/regress/serial_schedule,v 1.13 2002/07/20 05:16:59 momjian Exp $
 # This should probably be in an order similar to parallel_schedule.
 test: boolean
 test: char
@@ -85,3 +85,4 @@ test: copy2
 test: temp
 test: domain
 test: rangefuncs
+test: without_oid