From 726c3854cb133b7121c86347cefeb017c1f85226 Mon Sep 17 00:00:00 2001
From: Bruce Momjian <bruce@momjian.us>
Date: Sat, 31 Jan 1998 04:39:26 +0000
Subject: [PATCH] Inline fastgetattr and others so data access does not use
 function calls.

---
 src/backend/access/common/heaptuple.c      |  57 ++++++----
 src/backend/access/common/indextuple.c     | 117 ++++++++-------------
 src/backend/access/common/printtup.c       |  12 +--
 src/backend/access/index/indexam.c         |   5 +-
 src/backend/catalog/aclchk.c               |  12 +--
 src/backend/commands/async.c               |  14 +--
 src/backend/commands/copy.c                |   8 +-
 src/backend/commands/dbcommands.c          |   6 +-
 src/backend/commands/user.c                |  14 +--
 src/backend/commands/vacuum.c              |  10 +-
 src/backend/executor/execJunk.c            |   6 +-
 src/backend/executor/execQual.c            |   5 +-
 src/backend/executor/functions.c           |   4 +-
 src/backend/executor/nodeAgg.c             |   1 -
 src/backend/executor/nodeGroup.c           |   4 +-
 src/backend/executor/nodeUnique.c          |   6 +-
 src/backend/executor/spi.c                 |   6 +-
 src/backend/libpq/be-dumpdata.c            |   4 +-
 src/backend/rewrite/rewriteRemove.c        |   4 +-
 src/backend/rewrite/rewriteSupport.c       |   7 +-
 src/backend/storage/large_object/inv_api.c |  12 +--
 src/backend/utils/adt/not_in.c             |   3 +-
 src/backend/utils/adt/regproc.c            |   7 +-
 src/backend/utils/adt/selfuncs.c           |   4 +-
 src/backend/utils/cache/relcache.c         |  12 +--
 src/backend/utils/cache/syscache.c         |   3 +-
 src/backend/utils/fmgr/dfmgr.c             |   4 +-
 src/backend/utils/misc/database.c          |   6 +-
 src/backend/utils/sort/lselect.c           |   6 +-
 src/backend/utils/sort/psort.c             |   6 +-
 src/include/access/heapam.h                | 105 ++++++++++++++++--
 src/include/access/htup.h                  |   4 +-
 src/include/access/itup.h                  |  84 ++++++++++++++-
 src/include/access/valid.h                 |   4 +-
 src/include/parser/parse_node.h            |   3 +-
 35 files changed, 350 insertions(+), 215 deletions(-)

diff --git a/src/backend/access/common/heaptuple.c b/src/backend/access/common/heaptuple.c
index 76c2b1d1dba..a1ce78fa911 100644
--- a/src/backend/access/common/heaptuple.c
+++ b/src/backend/access/common/heaptuple.c
@@ -1,4 +1,4 @@
-/*-------------------------------------------------------------------------
+ /*-------------------------------------------------------------------------
  *
  * heaptuple.c--
  *	  This file contains heap tuple accessor and mutator routines, as well
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/access/common/heaptuple.c,v 1.30 1998/01/07 21:00:40 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/access/common/heaptuple.c,v 1.31 1998/01/31 04:38:02 momjian Exp $
  *
  * NOTES
  *	  The old interface functions have been converted to macros
@@ -32,6 +32,16 @@
 #include <string.h>
 #endif
 
+/* Used by heap_getattr() macro, for speed */
+long heap_sysoffset[] = {
+/* Only the first one is pass-by-ref, and is handled specially in the macro */
+		offsetof(HeapTupleData, t_ctid),		
+		offsetof(HeapTupleData, t_oid),
+		offsetof(HeapTupleData, t_xmin),
+		offsetof(HeapTupleData, t_cmin),
+		offsetof(HeapTupleData, t_xmax),
+		offsetof(HeapTupleData, t_cmax)
+};
 
 /* this is so the sparcstation debugger works */
 
@@ -345,7 +355,7 @@ heap_getsysattr(HeapTuple tup, Buffer b, int attnum)
 {
 	switch (attnum)
 	{
-		case SelfItemPointerAttributeNumber:
+		case  SelfItemPointerAttributeNumber:
 			return ((Datum) &tup->t_ctid);
 		case ObjectIdAttributeNumber:
 			return ((Datum) (long) tup->t_oid);
@@ -364,10 +374,12 @@ heap_getsysattr(HeapTuple tup, Buffer b, int attnum)
 }
 
 /* ----------------
- *		fastgetattr
+ *		nocachegetattr
+ *
+ *		This only gets called from fastgetattr() macro, in cases where
+ *		we can't use a cacheoffset and the value is not null.
  *
- *		This is a newer version of fastgetattr which attempts to be
- *		faster by caching attribute offsets in the attribute descriptor.
+ *		This caches attribute offsets in the attribute descriptor.
  *
  *		an alternate way to speed things up would be to cache offsets
  *		with the tuple, but that seems more difficult unless you take
@@ -381,7 +393,7 @@ heap_getsysattr(HeapTuple tup, Buffer b, int attnum)
  * ----------------
  */
 Datum
-fastgetattr(HeapTuple tup,
+nocachegetattr(HeapTuple tup,
 			int attnum,
 			TupleDesc tupleDesc,
 			bool *isnull)
@@ -391,13 +403,15 @@ fastgetattr(HeapTuple tup,
 	int			slow;			/* do we have to walk nulls? */
 	AttributeTupleForm *att = tupleDesc->attrs;
 
-	/* ----------------
-	 *	sanity checks
-	 * ----------------
-	 */
-
+	
+#if IN_MACRO
+/* This is handled in the macro */
 	Assert(attnum > 0);
 
+	if (isnull)
+		*isnull = false;
+#endif
+
 	/* ----------------
 	 *	 Three cases:
 	 *
@@ -407,12 +421,12 @@ fastgetattr(HeapTuple tup,
 	 * ----------------
 	 */
 
-	if (isnull)
-		*isnull = false;
-
 	if (HeapTupleNoNulls(tup))
 	{
 		attnum--;
+
+#if IN_MACRO
+/* This is handled in the macro */
 		if (att[attnum]->attcacheoff > 0)
 		{
 			return (Datum)
@@ -427,6 +441,7 @@ fastgetattr(HeapTuple tup,
 			 */
 			return ((Datum) fetchatt(&(att[0]), (char *) tup + tup->t_hoff));
 		}
+#endif
 
 		tp = (char *) tup + tup->t_hoff;
 
@@ -449,12 +464,15 @@ fastgetattr(HeapTuple tup,
 		 * ----------------
 		 */
 
+#if IN_MACRO
+/* This is handled in the macro */
 		if (att_isnull(attnum, bp))
 		{
 			if (isnull)
 				*isnull = true;
 			return (Datum) NULL;
 		}
+#endif
 
 		/* ----------------
 		 *		Now check to see if any preceeding bits are null...
@@ -539,7 +557,7 @@ fastgetattr(HeapTuple tup,
 					if (att[j]->attlen < sizeof(int32))
 					{
 						elog(ERROR,
-							 "fastgetattr: attribute %d has len %d",
+							 "nocachegetattr: attribute %d has len %d",
 							 j, att[j]->attlen);
 					}
 					if (att[j]->attalign == 'd')
@@ -599,7 +617,7 @@ fastgetattr(HeapTuple tup,
 				default:
 					if (att[i]->attlen < sizeof(int32))
 						elog(ERROR,
-							 "fastgetattr2: attribute %d has len %d",
+							 "nocachegetattr2: attribute %d has len %d",
 							 i, att[i]->attlen);
 					if (att[i]->attalign == 'd')
 						off = DOUBLEALIGN(off);
@@ -657,7 +675,7 @@ fastgetattr(HeapTuple tup,
 				break;
 			default:
 				if (att[attnum]->attlen < sizeof(int32))
-					elog(ERROR, "fastgetattr3: attribute %d has len %d",
+					elog(ERROR, "nocachegetattr3: attribute %d has len %d",
 						 attnum, att[attnum]->attlen);
 				if (att[attnum]->attalign == 'd')
 					off = DOUBLEALIGN(off);
@@ -719,7 +737,6 @@ heap_deformtuple(HeapTuple tuple,
 		bool		isnull;
 
 		values[i] = heap_getattr(tuple,
-								 InvalidBuffer,
 								 i + 1,
 								 tdesc,
 								 &isnull);
@@ -874,7 +891,6 @@ heap_modifytuple(HeapTuple tuple,
 		{
 			value[attoff] =
 				heap_getattr(tuple,
-							 InvalidBuffer,
 							 AttrOffsetGetAttrNumber(attoff),
 							 RelationGetTupleDescriptor(relation),
 							 &isNull);
@@ -959,3 +975,4 @@ heap_addheader(uint32 natts,	/* max domain index */
 
 	return (tup);
 }
+
diff --git a/src/backend/access/common/indextuple.c b/src/backend/access/common/indextuple.c
index 4941a60214d..eed1799ef15 100644
--- a/src/backend/access/common/indextuple.c
+++ b/src/backend/access/common/indextuple.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/access/common/indextuple.c,v 1.22 1998/01/07 21:00:43 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/access/common/indextuple.c,v 1.23 1998/01/31 04:38:03 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -26,11 +26,6 @@
 #include <string.h>
 #endif
 
-static Size IndexInfoFindDataOffset(unsigned short t_info);
-static char *
-fastgetiattr(IndexTuple tup, int attnum,
-			 TupleDesc att, bool *isnull);
-
 /* ----------------------------------------------------------------
  *				  index_ tuple interface routines
  * ----------------------------------------------------------------
@@ -117,10 +112,12 @@ index_formtuple(TupleDesc tupleDescriptor,
 }
 
 /* ----------------
- *		fastgetiattr
+ *		nocache_index_getattr
+ *
+ *		This gets called from index_getattr() macro, and only in cases
+ *		where we can't use cacheoffset and the value is not null.
  *
- *		This is a newer version of fastgetiattr which attempts to be
- *		faster by caching attribute offsets in the attribute descriptor.
+ *		This caches attribute offsets in the attribute descriptor.
  *
  *		an alternate way to speed things up would be to cache offsets
  *		with the tuple, but that seems more difficult unless you take
@@ -133,8 +130,8 @@ index_formtuple(TupleDesc tupleDescriptor,
  *		the same attribute descriptor will go much quicker. -cim 5/4/91
  * ----------------
  */
-static char *
-fastgetiattr(IndexTuple tup,
+Datum
+nocache_index_getattr(IndexTuple tup,
 			 int attnum,
 			 TupleDesc tupleDesc,
 			 bool *isnull)
@@ -150,9 +147,6 @@ fastgetiattr(IndexTuple tup,
 	 * ----------------
 	 */
 
-	Assert(PointerIsValid(isnull));
-	Assert(attnum > 0);
-
 	/* ----------------
 	 *	 Three cases:
 	 *
@@ -162,27 +156,37 @@ fastgetiattr(IndexTuple tup,
 	 * ----------------
 	 */
 
+#ifdef IN_MACRO
+/* This is handled in the macro */
+	Assert(PointerIsValid(isnull));
+	Assert(attnum > 0);
+
 	*isnull = false;
+#endif
+
 	data_off = IndexTupleHasMinHeader(tup) ? sizeof *tup :
 		IndexInfoFindDataOffset(tup->t_info);
 
 	if (IndexTupleNoNulls(tup))
 	{
+		attnum--;
 
+#ifdef IN_MACRO
+/* This is handled in the macro */
+	
 		/* first attribute is always at position zero */
 
 		if (attnum == 1)
 		{
-			return (fetchatt(&(att[0]), (char *) tup + data_off));
+			return (Datum) fetchatt(&(att[0]), (char *) tup + data_off);
 		}
-		attnum--;
-
 		if (att[attnum]->attcacheoff > 0)
 		{
-			return (fetchatt(&(att[attnum]),
+			return (Datum) fetchatt(&(att[attnum]),
 							 (char *) tup + data_off +
-							 att[attnum]->attcacheoff));
+							 att[attnum]->attcacheoff);
 		}
+#endif
 
 		tp = (char *) tup + data_off;
 
@@ -191,8 +195,6 @@ fastgetiattr(IndexTuple tup,
 	else
 	{							/* there's a null somewhere in the tuple */
 
-		bp = (char *) tup + sizeof(*tup);		/* "knows" t_bits are
-												 * here! */
 		slow = 0;
 		/* ----------------
 		 *		check to see if desired att is null
@@ -200,13 +202,19 @@ fastgetiattr(IndexTuple tup,
 		 */
 
 		attnum--;
+
+		bp = (char *) tup + sizeof(*tup);		/* "knows" t_bits are
+												 * here! */
+#ifdef IN_MACRO
+/* This is handled in the macro */
+		
+		if (att_isnull(attnum, bp))
 		{
-			if (att_isnull(attnum, bp))
-			{
-				*isnull = true;
-				return NULL;
-			}
+			*isnull = true;
+			return (Datum)NULL;
 		}
+#endif
+
 		/* ----------------
 		 *		Now check to see if any preceeding bits are null...
 		 * ----------------
@@ -251,8 +259,8 @@ fastgetiattr(IndexTuple tup,
 	{
 		if (att[attnum]->attcacheoff > 0)
 		{
-			return (fetchatt(&(att[attnum]),
-							 tp + att[attnum]->attcacheoff));
+			return (Datum) fetchatt(&(att[attnum]),
+							 tp + att[attnum]->attcacheoff);
 		}
 		else if (!IndexTupleAllFixed(tup))
 		{
@@ -314,7 +322,7 @@ fastgetiattr(IndexTuple tup,
 						off = (att[j]->attalign == 'd') ?
 							DOUBLEALIGN(off) : LONGALIGN(off);
 					else
-						elog(ERROR, "fastgetiattr: attribute %d has len %d",
+						elog(ERROR, "nocache_index_getattr: attribute %d has len %d",
 							 j, att[j]->attlen);
 					break;
 
@@ -324,8 +332,8 @@ fastgetiattr(IndexTuple tup,
 			off += att[j]->attlen;
 		}
 
-		return (fetchatt(&(att[attnum]),
-						 tp + att[attnum]->attcacheoff));
+		return (Datum) fetchatt(&(att[attnum]),
+						 tp + att[attnum]->attcacheoff);
 	}
 	else
 	{
@@ -382,7 +390,7 @@ fastgetiattr(IndexTuple tup,
 							DOUBLEALIGN(off) + att[i]->attlen :
 							LONGALIGN(off) + att[i]->attlen;
 					else
-						elog(ERROR, "fastgetiattr2: attribute %d has len %d",
+						elog(ERROR, "nocache_index_getattr2: attribute %d has len %d",
 							 i, att[i]->attlen);
 
 					break;
@@ -391,7 +399,7 @@ fastgetiattr(IndexTuple tup,
 
 		/*
 		 * I don't know why this code was missed here! I've got it from
-		 * heaptuple.c:fastgetattr(). - vadim 06/12/97
+		 * heaptuple.c:nocachegetattr(). - vadim 06/12/97
 		 */
 		switch (att[attnum]->attlen)
 		{
@@ -409,7 +417,7 @@ fastgetiattr(IndexTuple tup,
 				break;
 			default:
 				if (att[attnum]->attlen < sizeof(int32))
-					elog(ERROR, "fastgetattr3: attribute %d has len %d",
+					elog(ERROR, "nocache_index_getattr: attribute %d has len %d",
 						 attnum, att[attnum]->attlen);
 				if (att[attnum]->attalign == 'd')
 					off = DOUBLEALIGN(off);
@@ -418,26 +426,10 @@ fastgetiattr(IndexTuple tup,
 				break;
 		}
 
-		return (fetchatt(&att[attnum], tp + off));
+		return (Datum) fetchatt(&att[attnum], tp + off);
 	}
 }
 
-/* ----------------
- *		index_getattr
- * ----------------
- */
-Datum
-index_getattr(IndexTuple tuple,
-			  AttrNumber attNum,
-			  TupleDesc tupDesc,
-			  bool *isNullOutP)
-{
-	Assert(attNum > 0);
-
-	return (Datum)
-		fastgetiattr(tuple, attNum, tupDesc, isNullOutP);
-}
-
 RetrieveIndexResult
 FormRetrieveIndexResult(ItemPointer indexItemPointer,
 						ItemPointer heapItemPointer)
@@ -455,29 +447,6 @@ FormRetrieveIndexResult(ItemPointer indexItemPointer,
 	return (result);
 }
 
-/*
- * Takes an infomask as argument (primarily because this needs to be usable
- * at index_formtuple time so enough space is allocated).
- *
- * Change me if adding an attribute to IndexTuples!!!!!!!!!!!
- */
-static Size
-IndexInfoFindDataOffset(unsigned short t_info)
-{
-	if (!(t_info & INDEX_NULL_MASK))
-		return ((Size) sizeof(IndexTupleData));
-	else
-	{
-		Size		size = sizeof(IndexTupleData);
-
-		if (t_info & INDEX_NULL_MASK)
-		{
-			size += sizeof(IndexAttributeBitMapData);
-		}
-		return DOUBLEALIGN(size);		/* be conservative */
-	}
-}
-
 /*
  * Copies source into target.  If *target == NULL, we palloc space; otherwise
  * we assume we have space that is already palloc'ed.
diff --git a/src/backend/access/common/printtup.c b/src/backend/access/common/printtup.c
index 2a93e221589..fcedc3adf29 100644
--- a/src/backend/access/common/printtup.c
+++ b/src/backend/access/common/printtup.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/access/common/printtup.c,v 1.22 1998/01/07 21:00:44 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/access/common/printtup.c,v 1.23 1998/01/31 04:38:03 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -97,7 +97,7 @@ printtup(HeapTuple tuple, TupleDesc typeinfo)
 	{
 		i++;					/* heap_getattr is a macro, so no
 								 * increment */
-		attr = heap_getattr(tuple, InvalidBuffer, i, typeinfo, &isnull);
+		attr = heap_getattr(tuple, i, typeinfo, &isnull);
 		if (!isnull)
 			j |= k;
 		k >>= 1;
@@ -117,7 +117,7 @@ printtup(HeapTuple tuple, TupleDesc typeinfo)
 	 */
 	for (i = 0; i < tuple->t_natts; ++i)
 	{
-		attr = heap_getattr(tuple, InvalidBuffer, i + 1, typeinfo, &isnull);
+		attr = heap_getattr(tuple, i + 1, typeinfo, &isnull);
 		typoutput = typtoout((Oid) typeinfo->attrs[i]->atttypid);
 
 		if (!isnull && OidIsValid(typoutput))
@@ -183,7 +183,7 @@ debugtup(HeapTuple tuple, TupleDesc typeinfo)
 
 	for (i = 0; i < tuple->t_natts; ++i)
 	{
-		attr = heap_getattr(tuple, InvalidBuffer, i + 1, typeinfo, &isnull);
+		attr = heap_getattr(tuple, i + 1, typeinfo, &isnull);
 		typoutput = typtoout((Oid) typeinfo->attrs[i]->atttypid);
 
 		if (!isnull && OidIsValid(typoutput))
@@ -231,7 +231,7 @@ printtup_internal(HeapTuple tuple, TupleDesc typeinfo)
 	{
 		i++;					/* heap_getattr is a macro, so no
 								 * increment */
-		attr = heap_getattr(tuple, InvalidBuffer, i, typeinfo, &isnull);
+		attr = heap_getattr(tuple, i, typeinfo, &isnull);
 		if (!isnull)
 			j |= k;
 		k >>= 1;
@@ -256,7 +256,7 @@ printtup_internal(HeapTuple tuple, TupleDesc typeinfo)
 	{
 		int32		len = typeinfo->attrs[i]->attlen;
 
-		attr = heap_getattr(tuple, InvalidBuffer, i + 1, typeinfo, &isnull);
+		attr = heap_getattr(tuple, i + 1, typeinfo, &isnull);
 		if (!isnull)
 		{
 			/* # of bytes, and opaque data */
diff --git a/src/backend/access/index/indexam.c b/src/backend/access/index/indexam.c
index e023ef62a85..51cf2034fbc 100644
--- a/src/backend/access/index/indexam.c
+++ b/src/backend/access/index/indexam.c
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/access/index/indexam.c,v 1.19 1998/01/07 21:01:42 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/access/index/indexam.c,v 1.20 1998/01/31 04:38:06 momjian Exp $
  *
  * INTERFACE ROUTINES
  *		index_open		- open an index relation by relationId
@@ -386,7 +386,6 @@ GetIndexValue(HeapTuple tuple,
 		for (i = 0; i < FIgetnArgs(fInfo); i++)
 		{
 			attData[i] = heap_getattr(tuple,
-									  buffer,
 									  attrNums[i],
 									  hTupDesc,
 									  attNull);
@@ -400,7 +399,7 @@ GetIndexValue(HeapTuple tuple,
 	}
 	else
 	{
-		returnVal = heap_getattr(tuple, buffer, attrNums[attOff],
+		returnVal = heap_getattr(tuple, attrNums[attOff],
 								 hTupDesc, attNull);
 	}
 	return returnVal;
diff --git a/src/backend/catalog/aclchk.c b/src/backend/catalog/aclchk.c
index b61bc044905..966d94a1561 100644
--- a/src/backend/catalog/aclchk.c
+++ b/src/backend/catalog/aclchk.c
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/catalog/aclchk.c,v 1.3 1998/01/15 19:42:26 pgsql Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/catalog/aclchk.c,v 1.4 1998/01/31 04:38:11 momjian Exp $
  *
  * NOTES
  *	  See acl.h.
@@ -140,7 +140,7 @@ ChangeAcl(char *relname,
 		return;
 	}
 	if (!heap_attisnull(htp, Anum_pg_class_relacl))
-		old_acl = (Acl *) heap_getattr(htp, buffer,
+		old_acl = (Acl *) heap_getattr(htp,
 									   Anum_pg_class_relacl,
 									RelationGetTupleDescriptor(relation),
 									   (bool *) NULL);
@@ -253,7 +253,7 @@ in_group(AclId uid, AclId gid)
 	if (HeapTupleIsValid(htp) &&
 		!heap_attisnull(htp, Anum_pg_group_grolist))
 	{
-		tmp = (IdList *) heap_getattr(htp, InvalidBuffer,
+		tmp = (IdList *) heap_getattr(htp,
 									  Anum_pg_group_grolist,
 									RelationGetTupleDescriptor(relation),
 									  (bool *) NULL);
@@ -453,7 +453,7 @@ pg_aclcheck(char *relname, char *usename, AclMode mode)
 	if (!heap_attisnull(htp, Anum_pg_class_relacl))
 	{
 		relation = heap_openr(RelationRelationName);
-		tmp = (Acl *) heap_getattr(htp, InvalidBuffer,
+		tmp = (Acl *) heap_getattr(htp,
 								   Anum_pg_class_relacl,
 								   RelationGetTupleDescriptor(relation),
 								   (bool *) NULL);
@@ -471,7 +471,7 @@ pg_aclcheck(char *relname, char *usename, AclMode mode)
 		Oid			ownerId;
 
 		relation = heap_openr(RelationRelationName);
-		ownerId = (Oid) heap_getattr(htp, InvalidBuffer,
+		ownerId = (Oid) heap_getattr(htp,
 									 Anum_pg_class_relowner,
 									 RelationGetTupleDescriptor(relation),
 									 (bool *) NULL);
@@ -500,7 +500,7 @@ pg_aclcheck(char *relname, char *usename, AclMode mode)
 		if (HeapTupleIsValid(htp) &&
 			!heap_attisnull(htp, Anum_pg_class_relacl))
 		{
-			tmp = (Acl *) heap_getattr(htp, InvalidBuffer,
+			tmp = (Acl *) heap_getattr(htp,
 									   Anum_pg_class_relacl,
 									RelationGetTupleDescriptor(relation),
 									   (bool *) NULL);
diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c
index 3ef9c913052..ea3058e9e04 100644
--- a/src/backend/commands/async.c
+++ b/src/backend/commands/async.c
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/commands/async.c,v 1.27 1998/01/25 05:12:54 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/commands/async.c,v 1.28 1998/01/31 04:38:17 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -219,7 +219,7 @@ Async_Notify(char *relname)
 
 	while (HeapTupleIsValid(lTuple = heap_getnext(sRel, 0, &b)))
 	{
-		d = heap_getattr(lTuple, b, Anum_pg_listener_notify,
+		d = heap_getattr(lTuple, Anum_pg_listener_notify,
 						 tdesc, &isnull);
 		if (!DatumGetInt32(d))
 		{
@@ -294,12 +294,12 @@ Async_NotifyAtCommit()
 
 			while (HeapTupleIsValid(lTuple = heap_getnext(sRel, 0, &b)))
 			{
-				d = heap_getattr(lTuple, b, Anum_pg_listener_relname,
+				d = heap_getattr(lTuple, Anum_pg_listener_relname,
 								 tdesc, &isnull);
 
 				if (AsyncExistsPendingNotify((char *) DatumGetPointer(d)))
 				{
-					d = heap_getattr(lTuple, b, Anum_pg_listener_pid,
+					d = heap_getattr(lTuple, Anum_pg_listener_pid,
 									 tdesc, &isnull);
 
 					if (MyProcPid == DatumGetInt32(d))
@@ -444,12 +444,12 @@ Async_Listen(char *relname, int pid)
 	s = heap_beginscan(lDesc, 0, false, 0, (ScanKey) NULL);
 	while (HeapTupleIsValid(htup = heap_getnext(s, 0, &b)))
 	{
-		d = heap_getattr(htup, b, Anum_pg_listener_relname, tdesc,
+		d = heap_getattr(htup, Anum_pg_listener_relname, tdesc,
 						 &isnull);
 		relnamei = DatumGetPointer(d);
 		if (!strncmp(relnamei, relname, NAMEDATALEN))
 		{
-			d = heap_getattr(htup, b, Anum_pg_listener_pid, tdesc, &isnull);
+			d = heap_getattr(htup, Anum_pg_listener_pid, tdesc, &isnull);
 			pid = DatumGetInt32(d);
 			if (pid == MyProcPid)
 			{
@@ -607,7 +607,7 @@ Async_NotifyFrontEnd()
 
 	while (HeapTupleIsValid(lTuple = heap_getnext(sRel, 0, &b)))
 	{
-		d = heap_getattr(lTuple, b, Anum_pg_listener_relname,
+		d = heap_getattr(lTuple, Anum_pg_listener_relname,
 						 tdesc, &isnull);
 		rTuple = heap_modifytuple(lTuple, b, lRel, value, nulls, repl);
 		heap_replace(lRel, &lTuple->t_ctid, rTuple);
diff --git a/src/backend/commands/copy.c b/src/backend/commands/copy.c
index b3017dcd74f..d1dfa31dc5b 100644
--- a/src/backend/commands/copy.c
+++ b/src/backend/commands/copy.c
@@ -6,7 +6,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/commands/copy.c,v 1.39 1998/01/16 23:19:40 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/commands/copy.c,v 1.40 1998/01/31 04:38:18 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -266,7 +266,7 @@ CopyTo(Relation rel, bool binary, bool oids, FILE *fp, char *delim)
 
 		for (i = 0; i < attr_count; i++)
 		{
-			value = heap_getattr(tuple, InvalidBuffer, i + 1, tupDesc, &isnull);
+			value = heap_getattr(tuple, i + 1, tupDesc, &isnull);
 			if (!binary)
 			{
 				if (!isnull)
@@ -921,12 +921,12 @@ GetIndexRelations(Oid main_relation_oid,
 	{
 
 		index_relation_oid =
-			(Oid) DatumGetInt32(heap_getattr(tuple, InvalidBuffer, 2,
+			(Oid) DatumGetInt32(heap_getattr(tuple, 2,
 											 tupDesc, &isnull));
 		if (index_relation_oid == main_relation_oid)
 		{
 			scan->index_rel_oid =
-				(Oid) DatumGetInt32(heap_getattr(tuple, InvalidBuffer,
+				(Oid) DatumGetInt32(heap_getattr(tuple,
 												 Anum_pg_index_indexrelid,
 												 tupDesc, &isnull));
 			(*n_indices)++;
diff --git a/src/backend/commands/dbcommands.c b/src/backend/commands/dbcommands.c
index 42932588b6b..2bebaba587e 100644
--- a/src/backend/commands/dbcommands.c
+++ b/src/backend/commands/dbcommands.c
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/commands/dbcommands.c,v 1.5 1998/01/05 16:38:51 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/commands/dbcommands.c,v 1.6 1998/01/31 04:38:19 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -258,12 +258,12 @@ check_permissions(char *command,
 
 	if (dbfound)
 	{
-		dbowner = (Oid) heap_getattr(dbtup, InvalidBuffer,
+		dbowner = (Oid) heap_getattr(dbtup,
 									 Anum_pg_database_datdba,
 									 RelationGetTupleDescriptor(dbrel),
 									 (char *) NULL);
 		*dbIdP = dbtup->t_oid;
-		dbtext = (text *) heap_getattr(dbtup, InvalidBuffer,
+		dbtext = (text *) heap_getattr(dbtup,
 								 Anum_pg_database_datpath,
 								 RelationGetTupleDescriptor(dbrel),
 								 (char *) NULL);
diff --git a/src/backend/commands/user.c b/src/backend/commands/user.c
index b0763bd7a5d..c1fc7389848 100644
--- a/src/backend/commands/user.c
+++ b/src/backend/commands/user.c
@@ -118,12 +118,12 @@ void DefineUser(CreateUserStmt *stmt) {
 
   scan = heap_beginscan(pg_user_rel, false, false, 0, NULL);
   while (HeapTupleIsValid(tuple = heap_getnext(scan, 0, &buffer))) {
-    datum = heap_getattr(tuple, buffer, Anum_pg_user_usename, pg_user_dsc, &n);
+    datum = heap_getattr(tuple, Anum_pg_user_usename, pg_user_dsc, &n);
 
     if (!exists && !strncmp((char*)datum, stmt->user, strlen(stmt->user)))
       exists = true;
 
-    datum = heap_getattr(tuple, buffer, Anum_pg_user_usesysid, pg_user_dsc, &n);
+    datum = heap_getattr(tuple, Anum_pg_user_usesysid, pg_user_dsc, &n);
     if ((int)datum > max_id)
       max_id = (int)datum;
 
@@ -229,7 +229,7 @@ extern void AlterUser(AlterUserStmt *stmt) {
 
   scan = heap_beginscan(pg_user_rel, false, false, 0, NULL);
   while (HeapTupleIsValid(tuple = heap_getnext(scan, 0, &buffer))) {
-    datum = heap_getattr(tuple, buffer, Anum_pg_user_usename, pg_user_dsc, &n);
+    datum = heap_getattr(tuple, Anum_pg_user_usename, pg_user_dsc, &n);
 
     if (!strncmp((char*)datum, stmt->user, strlen(stmt->user))) {
       exists = true;
@@ -340,10 +340,10 @@ extern void RemoveUser(char* user) {
 
   scan = heap_beginscan(pg_user_rel, false, false, 0, NULL);
   while (HeapTupleIsValid(tuple = heap_getnext(scan, 0, &buffer))) {
-    datum = heap_getattr(tuple, buffer, Anum_pg_user_usename, pg_dsc, &n);
+    datum = heap_getattr(tuple, Anum_pg_user_usename, pg_dsc, &n);
 
     if (!strncmp((char*)datum, user, strlen(user))) {
-      usesysid = (int)heap_getattr(tuple, buffer, Anum_pg_user_usesysid, pg_dsc, &n);
+      usesysid = (int)heap_getattr(tuple, Anum_pg_user_usesysid, pg_dsc, &n);
       ReleaseBuffer(buffer);
       break;
     }
@@ -367,10 +367,10 @@ extern void RemoveUser(char* user) {
 
   scan = heap_beginscan(pg_rel, false, false, 0, NULL);
   while (HeapTupleIsValid(tuple = heap_getnext(scan, 0, &buffer))) {
-    datum = heap_getattr(tuple, buffer, Anum_pg_database_datdba, pg_dsc, &n);
+    datum = heap_getattr(tuple, Anum_pg_database_datdba, pg_dsc, &n);
 
     if ((int)datum == usesysid) {
-      datum = heap_getattr(tuple, buffer, Anum_pg_database_datname, pg_dsc, &n);
+      datum = heap_getattr(tuple, Anum_pg_database_datname, pg_dsc, &n);
       if (memcmp((void*)datum, "template1", 9)) {
         dbase = (char**)realloc((void*)dbase, sizeof(char*) * (ndbase + 1));
         dbase[ndbase] = (char*)malloc(NAMEDATALEN + 1);
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index 0d19eb51999..52158c75e6c 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/commands/vacuum.c,v 1.58 1998/01/15 19:42:40 pgsql Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/commands/vacuum.c,v 1.59 1998/01/31 04:38:21 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -299,7 +299,7 @@ vc_getrels(NameData *VacRelP)
 
 		found = true;
 
-		d = heap_getattr(pgctup, buf, Anum_pg_class_relname, pgcdesc, &n);
+		d = heap_getattr(pgctup, Anum_pg_class_relname, pgcdesc, &n);
 		rname = (char *) d;
 
 		/*
@@ -317,7 +317,7 @@ vc_getrels(NameData *VacRelP)
 			continue;
 		}
 
-		d = heap_getattr(pgctup, buf, Anum_pg_class_relkind, pgcdesc, &n);
+		d = heap_getattr(pgctup, Anum_pg_class_relkind, pgcdesc, &n);
 
 		rkind = DatumGetChar(d);
 
@@ -1637,7 +1637,7 @@ vc_attrstats(Relation onerel, VRelStats *vacrelstats, HeapTuple htup)
 		VacAttrStats *stats = &vacattrstats[i];
 		bool		value_hit = true;
 
-		value = heap_getattr(htup, InvalidBuffer,
+		value = heap_getattr(htup,
 							 stats->attr->attnum, tupDesc, &isnull);
 
 		if (!VacAttrStatsEqValid(stats))
@@ -2166,7 +2166,7 @@ vc_getindices(Oid relid, int *nindices, Relation **Irel)
 
 	while (HeapTupleIsValid(pgitup = heap_getnext(pgiscan, 0, NULL)))
 	{
-		d = heap_getattr(pgitup, InvalidBuffer, Anum_pg_index_indexrelid,
+		d = heap_getattr(pgitup, Anum_pg_index_indexrelid,
 						 pgidesc, &n);
 		i++;
 		if (i % 10 == 0)
diff --git a/src/backend/executor/execJunk.c b/src/backend/executor/execJunk.c
index e3e0623b957..75aa8de7097 100644
--- a/src/backend/executor/execJunk.c
+++ b/src/backend/executor/execJunk.c
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/executor/execJunk.c,v 1.9 1997/09/12 04:07:33 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/executor/execJunk.c,v 1.10 1998/01/31 04:38:24 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -315,7 +315,7 @@ ExecGetJunkAttribute(JunkFilter *junkfilter,
 	tuple = slot->val;
 	tupType = (TupleDesc) junkfilter->jf_tupType;
 
-	*value = heap_getattr(tuple, InvalidBuffer, resno, tupType, isNull);
+	*value = heap_getattr(tuple, resno, tupType, isNull);
 
 	return true;
 }
@@ -391,7 +391,7 @@ ExecRemoveJunk(JunkFilter *junkfilter, TupleTableSlot *slot)
 	for (i = 0; i < cleanLength; i++)
 	{
 		values[i] =
-			heap_getattr(tuple, InvalidBuffer, cleanMap[i], tupType, &isNull);
+			heap_getattr(tuple, cleanMap[i], tupType, &isNull);
 
 		if (isNull)
 			nulls[i] = 'n';
diff --git a/src/backend/executor/execQual.c b/src/backend/executor/execQual.c
index a5bb7b893bf..98a8042cc3d 100644
--- a/src/backend/executor/execQual.c
+++ b/src/backend/executor/execQual.c
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/executor/execQual.c,v 1.23 1998/01/15 19:44:24 pgsql Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/executor/execQual.c,v 1.24 1998/01/31 04:38:27 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -301,7 +301,6 @@ ExecEvalVar(Var *variable, ExprContext *econtext, bool *isNull)
 	}
 
 	result = heap_getattr(heapTuple, /* tuple containing attribute */
-						  buffer,	/* buffer associated with tuple */
 						  attnum,	/* attribute number of desired attribute */
 					 	  tuple_type,/* tuple descriptor of tuple */
 						  isNull);	/* return: is attribute null? */
@@ -525,7 +524,6 @@ GetAttributeByNum(TupleTableSlot *slot,
 	}
 
 	retval = heap_getattr(slot->val,
-						  slot->ttc_buffer,
 						  attrno,
 						  slot->ttc_tupleDescriptor,
 						  isNull);
@@ -587,7 +585,6 @@ GetAttributeByName(TupleTableSlot *slot, char *attname, bool *isNull)
 		elog(ERROR, "GetAttributeByName: attribute %s not found", attname);
 
 	retval = heap_getattr(slot->val,
-						  slot->ttc_buffer,
 						  attrno,
 						  tupdesc,
 						  isNull);
diff --git a/src/backend/executor/functions.c b/src/backend/executor/functions.c
index f19c3d361cd..2cd62e39c0c 100644
--- a/src/backend/executor/functions.c
+++ b/src/backend/executor/functions.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/executor/functions.c,v 1.14 1997/12/11 17:36:16 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/executor/functions.c,v 1.15 1998/01/31 04:38:28 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -82,7 +82,7 @@ ProjectAttribute(TupleDesc TD,
 	AttrNumber	attrno = attrVar->varattno;
 
 
-	val = heap_getattr(tup, InvalidBuffer, attrno, TD, isnullP);
+	val = heap_getattr(tup, attrno, TD, isnullP);
 	if (*isnullP)
 		return (Datum) NULL;
 
diff --git a/src/backend/executor/nodeAgg.c b/src/backend/executor/nodeAgg.c
index a319f9d6cf2..444a5bc9db6 100644
--- a/src/backend/executor/nodeAgg.c
+++ b/src/backend/executor/nodeAgg.c
@@ -663,7 +663,6 @@ aggGetAttr(TupleTableSlot *slot,
 
 	result = 
 		heap_getattr(heapTuple, /* tuple containing attribute */
-					 buffer,	/* buffer associated with tuple */
 					 attnum,	/* attribute number of desired attribute */
 					 tuple_type,/* tuple descriptor of tuple */
 					 isNull);	/* return: is attribute null? */
diff --git a/src/backend/executor/nodeGroup.c b/src/backend/executor/nodeGroup.c
index a0c9725c2f6..516cd624bfc 100644
--- a/src/backend/executor/nodeGroup.c
+++ b/src/backend/executor/nodeGroup.c
@@ -13,7 +13,7 @@
  *	  columns. (ie. tuples from the same group are consecutive)
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/executor/nodeGroup.c,v 1.13 1998/01/27 15:41:32 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/executor/nodeGroup.c,v 1.14 1998/01/31 04:38:29 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -402,13 +402,11 @@ sameGroup(TupleTableSlot *oldslot,
 		typoutput = typtoout((Oid) tupdesc->attrs[att - 1]->atttypid);
 
 		attr1 = heap_getattr(oldslot->val,
-							 InvalidBuffer,
 							 att,
 							 tupdesc,
 							 &isNull1);
 
 		attr2 = heap_getattr(newslot->val,
-							 InvalidBuffer,
 							 att,
 							 tupdesc,
 							 &isNull2);
diff --git a/src/backend/executor/nodeUnique.c b/src/backend/executor/nodeUnique.c
index 74ed561d411..ddb8d6ea660 100644
--- a/src/backend/executor/nodeUnique.c
+++ b/src/backend/executor/nodeUnique.c
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/executor/nodeUnique.c,v 1.11 1997/09/12 04:07:44 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/executor/nodeUnique.c,v 1.12 1998/01/31 04:38:31 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -187,9 +187,9 @@ ExecUnique(Unique *node)
 			char	   *val1,
 					   *val2;
 
-			attr1 = heap_getattr(slot->val, InvalidBuffer,
+			attr1 = heap_getattr(slot->val, 
 								 uniqueAttrNum, tupDesc, &isNull1);
-			attr2 = heap_getattr(resultTupleSlot->val, InvalidBuffer,
+			attr2 = heap_getattr(resultTupleSlot->val,
 								 uniqueAttrNum, tupDesc, &isNull2);
 
 			if (isNull1 == isNull2)
diff --git a/src/backend/executor/spi.c b/src/backend/executor/spi.c
index 696f77e1ec4..cd898a1c209 100644
--- a/src/backend/executor/spi.c
+++ b/src/backend/executor/spi.c
@@ -341,7 +341,7 @@ SPI_modifytuple(Relation rel, HeapTuple tuple, int natts, int *attnum,
 	/* fetch old values and nulls */
 	for (i = 0; i < numberOfAttributes; i++)
 	{
-		v[i] = heap_getattr(tuple, InvalidBuffer, i + 1, rel->rd_att, &isnull);
+		v[i] = heap_getattr(tuple, i + 1, rel->rd_att, &isnull);
 		n[i] = (isnull) ? 'n' : ' ';
 	}
 
@@ -420,7 +420,7 @@ SPI_getvalue(HeapTuple tuple, TupleDesc tupdesc, int fnumber)
 		return (NULL);
 	}
 
-	val = heap_getattr(tuple, InvalidBuffer, fnumber, tupdesc, &isnull);
+	val = heap_getattr(tuple, fnumber, tupdesc, &isnull);
 	if (isnull)
 		return (NULL);
 	foutoid = typtoout((Oid) tupdesc->attrs[fnumber - 1]->atttypid);
@@ -446,7 +446,7 @@ SPI_getbinval(HeapTuple tuple, TupleDesc tupdesc, int fnumber, bool * isnull)
 		return ((Datum) NULL);
 	}
 
-	val = heap_getattr(tuple, InvalidBuffer, fnumber, tupdesc, isnull);
+	val = heap_getattr(tuple, fnumber, tupdesc, isnull);
 
 	return (val);
 }
diff --git a/src/backend/libpq/be-dumpdata.c b/src/backend/libpq/be-dumpdata.c
index 7a20e26e543..13c826cb078 100644
--- a/src/backend/libpq/be-dumpdata.c
+++ b/src/backend/libpq/be-dumpdata.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/libpq/Attic/be-dumpdata.c,v 1.10 1998/01/26 01:41:05 scrappy Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/libpq/Attic/be-dumpdata.c,v 1.11 1998/01/31 04:38:34 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -299,7 +299,7 @@ be_printtup(HeapTuple tuple, TupleDesc typeinfo)
 
 	for (i = 0; i < tuple->t_natts; i++)
 	{
-		attr = heap_getattr(tuple, InvalidBuffer, i + 1, typeinfo, &isnull);
+		attr = heap_getattr(tuple, i + 1, typeinfo, &isnull);
 		typoutput = typtoout((Oid) typeinfo->attrs[i]->atttypid);
 
 		lengths[i] = typeinfo->attrs[i]->attlen;
diff --git a/src/backend/rewrite/rewriteRemove.c b/src/backend/rewrite/rewriteRemove.c
index 10ca1e82e0b..f7dea7cdf38 100644
--- a/src/backend/rewrite/rewriteRemove.c
+++ b/src/backend/rewrite/rewriteRemove.c
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteRemove.c,v 1.9 1998/01/07 21:04:41 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteRemove.c,v 1.10 1998/01/31 04:38:38 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -75,7 +75,6 @@ RemoveRewriteRule(char *ruleName)
 	Oid			ruleId = (Oid) 0;
 	Oid			eventRelationOid = (Oid) NULL;
 	Datum		eventRelationOidDatum = (Datum) NULL;
-	Buffer		buffer = (Buffer) NULL;
 	bool		isNull = false;
 
 	/*
@@ -109,7 +108,6 @@ RemoveRewriteRule(char *ruleName)
 	ruleId = tuple->t_oid;
 	eventRelationOidDatum =
 		heap_getattr(tuple,
-					 buffer,
 					 Anum_pg_rewrite_ev_class,
 					 RelationGetTupleDescriptor(RewriteRelation),
 					 &isNull);
diff --git a/src/backend/rewrite/rewriteSupport.c b/src/backend/rewrite/rewriteSupport.c
index d5c6c13c4bb..bf8d6977d19 100644
--- a/src/backend/rewrite/rewriteSupport.c
+++ b/src/backend/rewrite/rewriteSupport.c
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteSupport.c,v 1.14 1998/01/07 21:04:42 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/rewrite/rewriteSupport.c,v 1.15 1998/01/31 04:38:39 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -59,14 +59,13 @@ RuleIdGetActionInfo(Oid ruleoid, bool *instead_flag, Query **parseTrees)
 		elog(ERROR, "rule %u isn't in rewrite system relation", ruleoid);
 
 	ruleaction = (char *)heap_getattr(ruletuple,
-									  InvalidBuffer,
 									  Anum_pg_rewrite_ev_action,
 									  ruleTupdesc,
 									  &action_is_null);
-	rule_evqual_string = (char *)heap_getattr(ruletuple, InvalidBuffer,
+	rule_evqual_string = (char *)heap_getattr(ruletuple,
 											  Anum_pg_rewrite_ev_qual,
 											  ruleTupdesc, &action_is_null);
-	*instead_flag = !!heap_getattr(ruletuple, InvalidBuffer,
+	*instead_flag = !!heap_getattr(ruletuple,
 								   Anum_pg_rewrite_is_instead,
 								   ruleTupdesc, &instead_is_null);
 
diff --git a/src/backend/storage/large_object/inv_api.c b/src/backend/storage/large_object/inv_api.c
index e63816e89c2..93f581807d6 100644
--- a/src/backend/storage/large_object/inv_api.c
+++ b/src/backend/storage/large_object/inv_api.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/storage/large_object/inv_api.c,v 1.26 1998/01/07 21:05:17 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/storage/large_object/inv_api.c,v 1.27 1998/01/31 04:38:42 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -461,7 +461,7 @@ inv_read(LargeObjectDesc *obj_desc, char *buf, int nbytes)
 		}
 
 		/* copy the data from this block into the buffer */
-		d = heap_getattr(htup, b, 2, obj_desc->hdesc, &isNull);
+		d = heap_getattr(htup, 2, obj_desc->hdesc, &isNull);
 		fsblock = (struct varlena *) DatumGetPointer(d);
 
 		off = obj_desc->offset - obj_desc->lowbyte;
@@ -637,9 +637,9 @@ inv_fetchtup(LargeObjectDesc *obj_desc, Buffer *bufP)
 	 * return the tuple.
 	 */
 
-	d = heap_getattr(htup, *bufP, 1, obj_desc->hdesc, &isNull);
+	d = heap_getattr(htup, 1, obj_desc->hdesc, &isNull);
 	lastbyte = (int32) DatumGetInt32(d);
-	d = heap_getattr(htup, *bufP, 2, obj_desc->hdesc, &isNull);
+	d = heap_getattr(htup, 2, obj_desc->hdesc, &isNull);
 	fsblock = (struct varlena *) DatumGetPointer(d);
 
 	/*
@@ -807,7 +807,7 @@ inv_wrold(LargeObjectDesc *obj_desc,
 	newpage = BufferGetPage(newbuf);
 	hr = obj_desc->heap_r;
 	freespc = IFREESPC(page);
-	d = heap_getattr(htup, buffer, 2, obj_desc->hdesc, &isNull);
+	d = heap_getattr(htup, 2, obj_desc->hdesc, &isNull);
 	fsblock = (struct varlena *) DatumGetPointer(d);
 	tupbytes = fsblock->vl_len - sizeof(fsblock->vl_len);
 
@@ -1202,7 +1202,7 @@ _inv_getsize(Relation hreln, TupleDesc hdesc, Relation ireln)
 	index_endscan(iscan);
 
 	/* get olastbyte attribute */
-	d = heap_getattr(htup, buf, 1, hdesc, &isNull);
+	d = heap_getattr(htup, 1, hdesc, &isNull);
 	size = DatumGetInt32(d) + 1;
 
 	/* wei hates it if you forget to do this */
diff --git a/src/backend/utils/adt/not_in.c b/src/backend/utils/adt/not_in.c
index 06492652aef..66f5f83b5ee 100644
--- a/src/backend/utils/adt/not_in.c
+++ b/src/backend/utils/adt/not_in.c
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/utils/adt/Attic/not_in.c,v 1.7 1997/11/20 23:22:57 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/utils/adt/Attic/not_in.c,v 1.8 1998/01/31 04:38:45 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -83,7 +83,6 @@ int4notin(int16 not_in_arg, char *relation_and_attr)
 		 current_tuple = heap_getnext(scan_descriptor, 0, NULL))
 	{
 		value = heap_getattr(current_tuple,
-							 InvalidBuffer,
 							 (AttrNumber) attrid,
 							 RelationGetTupleDescriptor(relation_to_scan),
 							 &dummy);
diff --git a/src/backend/utils/adt/regproc.c b/src/backend/utils/adt/regproc.c
index 18d93d4a825..b0b3f462e70 100644
--- a/src/backend/utils/adt/regproc.c
+++ b/src/backend/utils/adt/regproc.c
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/utils/adt/regproc.c,v 1.12 1998/01/05 16:40:12 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/utils/adt/regproc.c,v 1.13 1998/01/31 04:38:46 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -68,7 +68,6 @@ regprocin(char *proname)
 	{
 		case 1:
 			result = (RegProcedure) heap_getattr(proctup,
-												 InvalidBuffer,
 												 ObjectIdAttributeNumber,
 										RelationGetTupleDescriptor(proc),
 												 &isnull);
@@ -129,7 +128,7 @@ regprocout(RegProcedure proid)
 			bool		isnull;
 
 		case 1:
-			s = (char *) heap_getattr(proctup, InvalidBuffer, 1,
+			s = (char *) heap_getattr(proctup, 1,
 							  RelationGetTupleDescriptor(proc), &isnull);
 			if (!isnull)
 			{
@@ -206,7 +205,7 @@ oid8types(Oid (*oidArray)[])
 				char	   *s;
 				bool		isnull;
 	
-				s = (char *) heap_getattr(typetup, InvalidBuffer, 1,
+				s = (char *) heap_getattr(typetup, 1,
 								  RelationGetTupleDescriptor(type), &isnull);
 				if (!isnull)
 				{
diff --git a/src/backend/utils/adt/selfuncs.c b/src/backend/utils/adt/selfuncs.c
index 3c55fdbed6c..6f02981f2b1 100644
--- a/src/backend/utils/adt/selfuncs.c
+++ b/src/backend/utils/adt/selfuncs.c
@@ -12,7 +12,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/utils/adt/selfuncs.c,v 1.14 1998/01/05 16:40:15 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/utils/adt/selfuncs.c,v 1.15 1998/01/31 04:38:49 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -364,7 +364,6 @@ gethilokey(Oid relid,
 	}
 	*high = textout((struct varlena *)
 					heap_getattr(tuple,
-								 InvalidBuffer,
 								 Anum_pg_statistic_stahikey,
 								 RelationGetTupleDescriptor(rdesc),
 								 &isnull));
@@ -372,7 +371,6 @@ gethilokey(Oid relid,
 		elog(DEBUG, "gethilokey: high key is null");
 	*low = textout((struct varlena *)
 				   heap_getattr(tuple,
-								InvalidBuffer,
 								Anum_pg_statistic_stalokey,
 								RelationGetTupleDescriptor(rdesc),
 								&isnull));
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index 9e706e4bf3f..28d9848f7b5 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/utils/cache/relcache.c,v 1.34 1998/01/15 19:45:31 pgsql Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/utils/cache/relcache.c,v 1.35 1998/01/31 04:38:52 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -744,24 +744,24 @@ RelationBuildRuleLock(Relation relation)
 		rule->ruleId = pg_rewrite_tuple->t_oid;
 
 		rule->event =
-			(int) heap_getattr(pg_rewrite_tuple, InvalidBuffer,
+			(int) heap_getattr(pg_rewrite_tuple,
 							 Anum_pg_rewrite_ev_type, pg_rewrite_tupdesc,
 							   &isnull) - 48;
 		rule->attrno =
-			(int) heap_getattr(pg_rewrite_tuple, InvalidBuffer,
+			(int) heap_getattr(pg_rewrite_tuple,
 							 Anum_pg_rewrite_ev_attr, pg_rewrite_tupdesc,
 							   &isnull);
 		rule->isInstead =
-			!!heap_getattr(pg_rewrite_tuple, InvalidBuffer,
+			!!heap_getattr(pg_rewrite_tuple,
 						   Anum_pg_rewrite_is_instead, pg_rewrite_tupdesc,
 						   &isnull);
 
 		ruleaction =
-			heap_getattr(pg_rewrite_tuple, InvalidBuffer,
+			heap_getattr(pg_rewrite_tuple,
 						 Anum_pg_rewrite_ev_action, pg_rewrite_tupdesc,
 						 &isnull);
 		rule_evqual_string =
-			heap_getattr(pg_rewrite_tuple, InvalidBuffer,
+			heap_getattr(pg_rewrite_tuple,
 						 Anum_pg_rewrite_ev_qual, pg_rewrite_tupdesc,
 						 &isnull);
 
diff --git a/src/backend/utils/cache/syscache.c b/src/backend/utils/cache/syscache.c
index 91daad237a0..3d80da1659b 100644
--- a/src/backend/utils/cache/syscache.c
+++ b/src/backend/utils/cache/syscache.c
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/utils/cache/syscache.c,v 1.12 1998/01/07 21:06:15 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/utils/cache/syscache.c,v 1.13 1998/01/31 04:38:54 momjian Exp $
  *
  * NOTES
  *	  These routines allow the parser/planner/executor to perform
@@ -544,7 +544,6 @@ SearchSysCacheGetAttribute(int cacheId,
 	}
 
 	attributeValue = heap_getattr(tp,
-								  (Buffer) 0,
 								  attributeNumber,
 								  RelationGetTupleDescriptor(relation),
 								  &isNull);
diff --git a/src/backend/utils/fmgr/dfmgr.c b/src/backend/utils/fmgr/dfmgr.c
index dae7f92557d..1611cd1a966 100644
--- a/src/backend/utils/fmgr/dfmgr.c
+++ b/src/backend/utils/fmgr/dfmgr.c
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/utils/fmgr/dfmgr.c,v 1.16 1998/01/07 21:06:26 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/utils/fmgr/dfmgr.c,v 1.17 1998/01/31 04:38:57 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -99,7 +99,7 @@ fmgr_dynamic(Oid procedureId, int *pronargs)
 			 ProcedureRelationName);
 		return ((func_ptr) NULL);
 	}
-	probinattr = heap_getattr(procedureTuple, (Buffer) 0,
+	probinattr = heap_getattr(procedureTuple,
 							  Anum_pg_proc_probin,
 							  RelationGetTupleDescriptor(rdesc), &isnull);
 	if (!PointerIsValid(probinattr) /* || isnull */ )
diff --git a/src/backend/utils/misc/database.c b/src/backend/utils/misc/database.c
index 0a3224ebfb9..24087cdafa6 100644
--- a/src/backend/utils/misc/database.c
+++ b/src/backend/utils/misc/database.c
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/utils/misc/Attic/database.c,v 1.5 1998/01/07 21:06:31 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/utils/misc/Attic/database.c,v 1.6 1998/01/31 04:39:07 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -85,13 +85,13 @@ GetDatabaseInfo(char *name, Oid *owner, char *path)
 		return TRUE;
 	}
 
-	dbowner = (Oid) heap_getattr(dbtup, InvalidBuffer,
+	dbowner = (Oid) heap_getattr(dbtup,
 									Anum_pg_database_datdba,
 									RelationGetTupleDescriptor(dbrel),
 									(char *) NULL);
 	dbid = dbtup->t_oid;
  
-	dbtext = (text *) heap_getattr(dbtup, InvalidBuffer,
+	dbtext = (text *) heap_getattr(dbtup,
 									Anum_pg_database_datpath,
 									RelationGetTupleDescriptor(dbrel),
 									(char *) NULL);
diff --git a/src/backend/utils/sort/lselect.c b/src/backend/utils/sort/lselect.c
index c5ee02e7e9c..28e18fd05d3 100644
--- a/src/backend/utils/sort/lselect.c
+++ b/src/backend/utils/sort/lselect.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/utils/sort/Attic/lselect.c,v 1.10 1998/01/15 19:46:08 pgsql Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/utils/sort/Attic/lselect.c,v 1.11 1998/01/31 04:39:12 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -198,12 +198,12 @@ tuplecmp(HeapTuple ltup, HeapTuple rtup, LeftistContext context)
 		return (1);
 	while (nkey < context->nKeys && !result)
 	{
-		lattr = heap_getattr(ltup, InvalidBuffer,
+		lattr = heap_getattr(ltup,
 							 context->scanKeys[nkey].sk_attno,
 							 context->tupDesc, &isnull);
 		if (isnull)
 			return (0);
-		rattr = heap_getattr(rtup, InvalidBuffer,
+		rattr = heap_getattr(rtup,
 							 context->scanKeys[nkey].sk_attno,
 							 context->tupDesc,
 							 &isnull);
diff --git a/src/backend/utils/sort/psort.c b/src/backend/utils/sort/psort.c
index d6b53a54ffe..c30e13e0463 100644
--- a/src/backend/utils/sort/psort.c
+++ b/src/backend/utils/sort/psort.c
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/utils/sort/Attic/psort.c,v 1.34 1998/01/25 05:18:34 scrappy Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/utils/sort/Attic/psort.c,v 1.35 1998/01/31 04:39:13 momjian Exp $
  *
  * NOTES
  *		Sorts the first relation into the second relation.
@@ -1096,11 +1096,11 @@ _psort_cmp (HeapTuple *ltup, HeapTuple *rtup)
     
     for (nkey = 0; nkey < PsortNkeys && !result; nkey++ )
     {
-		lattr = heap_getattr(*ltup, InvalidBuffer,
+		lattr = heap_getattr(*ltup,
 				     PsortKeys[nkey].sk_attno, 
 				     PsortTupDesc,
 			    	 &isnull1);
-		rattr = heap_getattr(*rtup, InvalidBuffer,
+		rattr = heap_getattr(*rtup,
 				     PsortKeys[nkey].sk_attno, 
 				     PsortTupDesc,
 				     &isnull2);
diff --git a/src/include/access/heapam.h b/src/include/access/heapam.h
index f3c7c55bda6..4e5fe7ca5b7 100644
--- a/src/include/access/heapam.h
+++ b/src/include/access/heapam.h
@@ -6,13 +6,14 @@
  *
  * Copyright (c) 1994, Regents of the University of California
  *
- * $Id: heapam.h,v 1.26 1998/01/27 15:57:41 momjian Exp $
+ * $Id: heapam.h,v 1.27 1998/01/31 04:39:21 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
 #ifndef HEAPAM_H
 #define HEAPAM_H
 
+#include <access/tupmacs.h>
 #include <access/htup.h>
 #include <access/relscan.h>
 #include <storage/block.h>
@@ -79,6 +80,59 @@ typedef HeapAccessStatisticsData *HeapAccessStatistics;
 #define IncrHeapAccessStat(x) \
 	(heap_access_stats == NULL ? 0 : (heap_access_stats->x)++)
 
+/* ----------------
+ *		fastgetattr
+ *
+ *		This gets called many times, so we macro the cacheable and NULL
+ *		lookups, and call noncachegetattr() for the rest.
+ *
+ * ----------------
+ */
+#define fastgetattr(tup, attnum, tupleDesc, isnull) \
+( \
+	AssertMacro((attnum) > 0) ? \
+	( \
+		((isnull) ? (*(isnull) = false) : (dummyret)NULL), \
+		HeapTupleNoNulls(tup) ? \
+		( \
+			((tupleDesc)->attrs[(attnum)-1]->attcacheoff > 0) ? \
+			( \
+				(Datum)fetchatt(&((tupleDesc)->attrs[(attnum)-1]), \
+			  	  (char *) (tup) + (tup)->t_hoff + (tupleDesc)->attrs[(attnum)-1]->attcacheoff) \
+			) \
+			: \
+			( \
+				((attnum)-1 == 0) ? \
+				( \
+					(Datum)fetchatt(&((tupleDesc)->attrs[0]), (char *) (tup) + (tup)->t_hoff) \
+				) \
+				: \
+				( \
+					nocachegetattr((tup), (attnum), (tupleDesc), (isnull)) \
+				) \
+			) \
+		) \
+		: \
+		( \
+			att_isnull((attnum)-1, (tup)->t_bits) ? \
+			( \
+				((isnull) ? (*(isnull) = true) : (dummyret)NULL), \
+				(Datum)NULL \
+			) \
+			: \
+			( \
+				nocachegetattr((tup), (attnum), (tupleDesc), (isnull)) \
+			) \
+		) \
+	) \
+	: \
+	( \
+		 (Datum)NULL \
+	) \
+)
+
+
+	
 /* ----------------
  *		heap_getattr
  *
@@ -97,15 +151,46 @@ typedef HeapAccessStatisticsData *HeapAccessStatistics;
  *		Because this macro is often called with constants, it generates
  *		compiler warnings about 'left-hand comma expression has no effect.
  *
- * ---------------- */
-#define heap_getattr(tup, b, attnum, tupleDesc, isnull) \
-	(AssertMacro((tup) != NULL) ? \
+ * ----------------
+ */
+#define heap_getattr(tup, attnum, tupleDesc, isnull) \
+( \
+	AssertMacro((tup) != NULL && \
+		(attnum) > FirstLowInvalidHeapAttributeNumber && \
+		(attnum) != 0) ? \
+	( \
 		((attnum) > (int) (tup)->t_natts) ? \
-			(((isnull) ? (*(isnull) = true) : (dummyret)NULL), (Datum)NULL) : \
-		((attnum) > 0) ? \
-			fastgetattr((tup), (attnum), (tupleDesc), (isnull)) : \
-		(((isnull) ? (*(isnull) = false) : (dummyret)NULL), heap_getsysattr((tup), (b), (attnum))) : \
-	(Datum)NULL)
+		( \
+			((isnull) ? (*(isnull) = true) : (dummyret)NULL), \
+			(Datum)NULL \
+		) \
+		: \
+		( \
+			((attnum) > 0) ? \
+			( \
+				fastgetattr((tup), (attnum), (tupleDesc), (isnull)) \
+			) \
+			: \
+			( \
+				((isnull) ? (*(isnull) = false) : (dummyret)NULL), \
+				((attnum) == SelfItemPointerAttributeNumber) ? \
+				( \
+					(Datum)((char *)(tup) + \
+						heap_sysoffset[-SelfItemPointerAttributeNumber-1]) \
+				) \
+				: \
+				( \
+					(Datum)*(unsigned int *) \
+						((char *)(tup) + heap_sysoffset[-(attnum)-1]) \
+				) \
+			) \
+		) \
+	) \
+	: \
+	( \
+		 (Datum)NULL \
+	) \
+)
 
 extern HeapAccessStatistics heap_access_stats;	/* in stats.c */
 
@@ -143,7 +228,7 @@ extern int	heap_attisnull(HeapTuple tup, int attnum);
 extern int	heap_sysattrlen(AttrNumber attno);
 extern bool heap_sysattrbyval(AttrNumber attno);
 extern Datum heap_getsysattr(HeapTuple tup, Buffer b, int attnum);
-extern Datum fastgetattr(HeapTuple tup, int attnum,
+extern Datum nocachegetattr(HeapTuple tup, int attnum,
 						 TupleDesc att, bool *isnull);
 extern HeapTuple heap_copytuple(HeapTuple tuple);
 extern HeapTuple heap_formtuple(TupleDesc tupleDescriptor,
diff --git a/src/include/access/htup.h b/src/include/access/htup.h
index 72fb5a8d314..6e7674ea7c8 100644
--- a/src/include/access/htup.h
+++ b/src/include/access/htup.h
@@ -6,7 +6,7 @@
  *
  * Copyright (c) 1994, Regents of the University of California
  *
- * $Id: htup.h,v 1.7 1997/11/02 15:26:42 vadim Exp $
+ * $Id: htup.h,v 1.8 1998/01/31 04:39:22 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -63,6 +63,8 @@ typedef HeapTupleData *HeapTuple;
 #define MaxCommandIdAttributeNumber				(-6)
 #define FirstLowInvalidHeapAttributeNumber		(-7)
 
+/* If you make any changes above, the order off offsets in this must change */
+extern long heap_sysoffset[];
 
 /* ----------------
  *		support macros
diff --git a/src/include/access/itup.h b/src/include/access/itup.h
index 362dcce1fc2..1ace51fa44f 100644
--- a/src/include/access/itup.h
+++ b/src/include/access/itup.h
@@ -6,15 +6,18 @@
  *
  * Copyright (c) 1994, Regents of the University of California
  *
- * $Id: itup.h,v 1.9 1998/01/24 22:48:06 momjian Exp $
+ * $Id: itup.h,v 1.10 1998/01/31 04:39:23 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
 #ifndef ITUP_H
 #define ITUP_H
 
+#include <access/ibit.h>
+#include <access/tupmacs.h>
 #include <access/tupdesc.h>
 #include <storage/itemptr.h>
+#include <utils/memutils.h>
 
 #define MaxIndexAttributeNumber 7
 
@@ -87,12 +90,87 @@ typedef struct PredInfo
 
 #define IndexTupleHasMinHeader(itup) (IndexTupleNoNulls(itup))
 
+/*
+ * Takes an infomask as argument (primarily because this needs to be usable
+ * at index_formtuple time so enough space is allocated).
+ *
+ * Change me if adding an attribute to IndexTuples!!!!!!!!!!!
+ */
+#define IndexInfoFindDataOffset(t_info) \
+( \
+	(!((unsigned short)(t_info) & INDEX_NULL_MASK)) ? \
+	( \
+		(Size)sizeof(IndexTupleData) \
+	) \
+	: \
+	( \
+		(Size)DOUBLEALIGN(sizeof(IndexTupleData) + sizeof(IndexAttributeBitMapData)) \
+	) \
+)
 
+/* ----------------
+ *		index_getattr
+ *
+ *		This gets called many times, so we macro the cacheable and NULL
+ *		lookups, and call noncachegetattr() for the rest.
+ *
+ * ----------------
+ */
+#define index_getattr(tup, attnum, tupleDesc, isnull) \
+( \
+	AssertMacro(PointerIsValid(isnull) && (attnum) > 0) ? \
+	( \
+		*(isnull) = false, \
+		IndexTupleNoNulls(tup) ? \
+		( \
+			((tupleDesc)->attrs[(attnum)-1]->attcacheoff > 0) ? \
+			( \
+				(Datum)fetchatt(&((tupleDesc)->attrs[(attnum)-1]), \
+			  	  (char *) (tup) + \
+					(IndexTupleHasMinHeader(tup) ? sizeof (*(tup)) : \
+					 IndexInfoFindDataOffset((tup)->t_info)) + \
+					(tupleDesc)->attrs[(attnum)-1]->attcacheoff) \
+			) \
+			: \
+			( \
+				((attnum)-1 == 0) ? \
+				( \
+					(Datum)fetchatt(&((tupleDesc)->attrs[0]), \
+						(char *) (tup) + \
+						(IndexTupleHasMinHeader(tup) ? sizeof (*(tup)) : \
+					 	 IndexInfoFindDataOffset((tup)->t_info))) \
+				) \
+				: \
+				( \
+					nocache_index_getattr((tup), (attnum), (tupleDesc), (isnull)) \
+				) \
+			) \
+		) \
+		: \
+		( \
+			(att_isnull((attnum)-1, (char *)(tup) + sizeof(*(tup)))) ? \
+			( \
+				*(isnull) = true, \
+				(Datum)NULL \
+			) \
+			: \
+			( \
+				nocache_index_getattr((tup), (attnum), (tupleDesc), (isnull)) \
+			) \
+		) \
+	) \
+	: \
+	( \
+		 (Datum)NULL \
+	) \
+)
+
+	
 /* indextuple.h */
 extern IndexTuple index_formtuple(TupleDesc tupleDescriptor,
 				Datum value[], char null[]);
-extern Datum index_getattr(IndexTuple tuple, AttrNumber attNum,
-			  TupleDesc tupDesc, bool *isNullOutP);
+extern Datum nocache_index_getattr(IndexTuple tup, int attnum,
+			  TupleDesc tupleDesc, bool *isnull);
 extern RetrieveIndexResult FormRetrieveIndexResult(ItemPointer indexItemPointer,
 						ItemPointer heapItemPointer);
 extern void CopyIndexTuple(IndexTuple source, IndexTuple *target);
diff --git a/src/include/access/valid.h b/src/include/access/valid.h
index 9a95d9c3329..fe874512694 100644
--- a/src/include/access/valid.h
+++ b/src/include/access/valid.h
@@ -6,7 +6,7 @@
  *
  * Copyright (c) 1994, Regents of the University of California
  *
- * $Id: valid.h,v 1.12 1998/01/15 19:46:18 pgsql Exp $
+ * $Id: valid.h,v 1.13 1998/01/31 04:39:24 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -53,7 +53,7 @@ do \
 	(result) = true; /* may change */ \
 	for (; __cur_nkeys--; __cur_keys++) \
 	{ \
-		__atp = heap_getattr((tuple), InvalidBuffer, \
+		__atp = heap_getattr((tuple), \
 						   __cur_keys->sk_attno, \
 						   (tupdesc), \
 						   &__isnull); \
diff --git a/src/include/parser/parse_node.h b/src/include/parser/parse_node.h
index 50580f10366..c92c2861816 100644
--- a/src/include/parser/parse_node.h
+++ b/src/include/parser/parse_node.h
@@ -5,7 +5,7 @@
  *
  * Copyright (c) 1994, Regents of the University of California
  *
- * $Id: parse_node.h,v 1.7 1998/01/20 22:12:16 momjian Exp $
+ * $Id: parse_node.h,v 1.8 1998/01/31 04:39:26 momjian Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -28,7 +28,6 @@ typedef struct QueryTreeList
 /* state information used during parse analysis */
 typedef struct ParseState
 {
-	struct 		ParseState;
 	int			p_last_resno;
 	List	   *p_rtable;
 	List	   *p_insert_columns;
-- 
GitLab