diff --git a/src/backend/access/heap/Makefile b/src/backend/access/heap/Makefile
index 95575f8e325b8633825717af538d2e804aaf806e..352ced339292e5c74ab3a506f32da2fd2992b9b3 100644
--- a/src/backend/access/heap/Makefile
+++ b/src/backend/access/heap/Makefile
@@ -4,7 +4,7 @@
 #    Makefile for access/heap
 #
 # IDENTIFICATION
-#    $Header: /cvsroot/pgsql/src/backend/access/heap/Makefile,v 1.11 2000/08/31 16:09:33 petere Exp $
+#    $Header: /cvsroot/pgsql/src/backend/access/heap/Makefile,v 1.12 2001/11/02 16:30:29 tgl Exp $
 #
 #-------------------------------------------------------------------------
 
@@ -12,7 +12,7 @@ subdir = src/backend/access/heap
 top_builddir = ../../../..
 include $(top_builddir)/src/Makefile.global
 
-OBJS = heapam.o hio.o stats.o tuptoaster.o
+OBJS = heapam.o hio.o tuptoaster.o
 
 all: SUBSYS.o
 
diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c
index f73ca50285b5093f653b4cdd484ace04461707c9..bf7798a07dc56c02d4dde2cf7373081cf970d8bf 100644
--- a/src/backend/access/heap/heapam.c
+++ b/src/backend/access/heap/heapam.c
@@ -8,14 +8,16 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/access/heap/heapam.c,v 1.126 2001/10/25 05:49:21 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/access/heap/heapam.c,v 1.127 2001/11/02 16:30:29 tgl Exp $
  *
  *
  * INTERFACE ROUTINES
- *		heap_open		- open a heap relation by relationId
+ *		relation_open	- open any relation by relation OID
+ *		relation_openr	- open any relation by name
+ *		relation_close	- close any relation
+ *		heap_open		- open a heap relation by relation OID
  *		heap_openr		- open a heap relation by name
- *		heap_open[r]_nofail - same, but return NULL on failure instead of elog
- *		heap_close		- close a heap relation
+ *		heap_close		- (now just a macro for relation_close)
  *		heap_beginscan	- begin relation scan
  *		heap_rescan		- restart a relation scan
  *		heap_endscan	- end relation scan
@@ -440,15 +442,21 @@ fastgetattr(HeapTuple tup, int attnum, TupleDesc tupleDesc,
  */
 
 /* ----------------
- *		heap_open - open a heap relation by relationId
+ *		relation_open - open any relation by relation OID
  *
  *		If lockmode is not "NoLock", the specified kind of lock is
- *		obtained on the relation.
+ *		obtained on the relation.  (Generally, NoLock should only be
+ *		used if the caller knows it has some appropriate lock on the
+ *		relation already.)
+ *
  *		An error is raised if the relation does not exist.
+ *
+ *		NB: a "relation" is anything with a pg_class entry.  The caller is
+ *		expected to check whether the relkind is something it can handle.
  * ----------------
  */
 Relation
-heap_open(Oid relationId, LOCKMODE lockmode)
+relation_open(Oid relationId, LOCKMODE lockmode)
 {
 	Relation	r;
 
@@ -466,10 +474,6 @@ heap_open(Oid relationId, LOCKMODE lockmode)
 	if (!RelationIsValid(r))
 		elog(ERROR, "Relation %u does not exist", relationId);
 
-	/* Under no circumstances will we return an index as a relation. */
-	if (r->rd_rel->relkind == RELKIND_INDEX)
-		elog(ERROR, "%s is an index relation", RelationGetRelationName(r));
-
 	if (lockmode != NoLock)
 		LockRelation(r, lockmode);
 
@@ -477,15 +481,13 @@ heap_open(Oid relationId, LOCKMODE lockmode)
 }
 
 /* ----------------
- *		heap_openr - open a heap relation by name
+ *		relation_openr - open any relation by name
  *
- *		If lockmode is not "NoLock", the specified kind of lock is
- *		obtained on the relation.
- *		An error is raised if the relation does not exist.
+ *		As above, but lookup by name instead of OID.
  * ----------------
  */
 Relation
-heap_openr(const char *relationName, LOCKMODE lockmode)
+relation_openr(const char *relationName, LOCKMODE lockmode)
 {
 	Relation	r;
 
@@ -497,116 +499,111 @@ heap_openr(const char *relationName, LOCKMODE lockmode)
 	IncrHeapAccessStat(local_openr);
 	IncrHeapAccessStat(global_openr);
 
+	/*
+	 * Check for shared-cache-inval messages before trying to open the
+	 * relation.  This is needed to cover the case where the name identifies
+	 * a rel that has been dropped and recreated since the start of our
+	 * transaction: if we don't flush the old relcache entry then we'll
+	 * latch onto that entry and suffer an error when we do LockRelation.
+	 * Note that relation_open does not need to do this, since a relation's
+	 * OID never changes.
+	 *
+	 * We skip this if asked for NoLock, on the assumption that the caller
+	 * has already ensured some appropriate lock is held.
+	 */
+	if (lockmode != NoLock)
+		AcceptInvalidationMessages();
+
 	/* The relcache does all the real work... */
 	r = RelationNameGetRelation(relationName);
 
 	if (!RelationIsValid(r))
-		elog(ERROR, "Relation '%s' does not exist", relationName);
-
-	/* Under no circumstances will we return an index as a relation. */
-	if (r->rd_rel->relkind == RELKIND_INDEX)
-		elog(ERROR, "%s is an index relation", RelationGetRelationName(r));
+		elog(ERROR, "Relation \"%s\" does not exist", relationName);
 
 	if (lockmode != NoLock)
 		LockRelation(r, lockmode);
 
-	pgstat_initstats(&r->pgstat_info, r);
-
-	pgstat_initstats(&r->pgstat_info, r);
-
 	return r;
 }
 
 /* ----------------
- *		heap_open_nofail - open a heap relation by relationId,
- *				do not raise error on failure
+ *		relation_close - close any relation
+ *
+ *		If lockmode is not "NoLock", we first release the specified lock.
  *
- *		The caller must check for a NULL return value indicating
- *		that no such relation exists.
- *		No lock is obtained on the relation, either.
+ *		Note that it is often sensible to hold a lock beyond relation_close;
+ *		in that case, the lock is released automatically at xact end.
  * ----------------
  */
-Relation
-heap_open_nofail(Oid relationId)
+void
+relation_close(Relation relation, LOCKMODE lockmode)
 {
-	Relation	r;
+	Assert(lockmode >= NoLock && lockmode < MAX_LOCKMODES);
 
 	/*
 	 * increment access statistics
 	 */
-	IncrHeapAccessStat(local_open);
-	IncrHeapAccessStat(global_open);
-
-	/* The relcache does all the real work... */
-	r = RelationIdGetRelation(relationId);
+	IncrHeapAccessStat(local_close);
+	IncrHeapAccessStat(global_close);
 
-	/* Under no circumstances will we return an index as a relation. */
-	if (RelationIsValid(r) && r->rd_rel->relkind == RELKIND_INDEX)
-		elog(ERROR, "%s is an index relation", RelationGetRelationName(r));
+	if (lockmode != NoLock)
+		UnlockRelation(relation, lockmode);
 
-	return r;
+	/* The relcache does the real work... */
+	RelationClose(relation);
 }
 
+
 /* ----------------
- *		heap_openr_nofail - open a heap relation by name,
- *				do not raise error on failure
+ *		heap_open - open a heap relation by relation OID
  *
- *		The caller must check for a NULL return value indicating
- *		that no such relation exists.
- *		No lock is obtained on the relation, either.
+ *		This is essentially relation_open plus check that the relation
+ *		is not an index or special relation.  (The caller should also check
+ *		that it's not a view before assuming it has storage.)
  * ----------------
  */
 Relation
-heap_openr_nofail(const char *relationName)
+heap_open(Oid relationId, LOCKMODE lockmode)
 {
 	Relation	r;
 
-	/*
-	 * increment access statistics
-	 */
-	IncrHeapAccessStat(local_openr);
-	IncrHeapAccessStat(global_openr);
+	r = relation_open(relationId, lockmode);
 
-	/* The relcache does all the real work... */
-	r = RelationNameGetRelation(relationName);
-
-	/* Under no circumstances will we return an index as a relation. */
-	if (RelationIsValid(r) && r->rd_rel->relkind == RELKIND_INDEX)
-		elog(ERROR, "%s is an index relation", RelationGetRelationName(r));
-
-	if (RelationIsValid(r))
-		pgstat_initstats(&r->pgstat_info, r);
+	if (r->rd_rel->relkind == RELKIND_INDEX)
+		elog(ERROR, "%s is an index relation",
+			 RelationGetRelationName(r));
+	else if (r->rd_rel->relkind == RELKIND_SPECIAL)
+		elog(ERROR, "%s is a special relation",
+			 RelationGetRelationName(r));
 
-	if (RelationIsValid(r))
-		pgstat_initstats(&r->pgstat_info, r);
+	pgstat_initstats(&r->pgstat_info, r);
 
 	return r;
 }
 
 /* ----------------
- *		heap_close - close a heap relation
+ *		heap_openr - open a heap relation by name
  *
- *		If lockmode is not "NoLock", we first release the specified lock.
- *		Note that it is often sensible to hold a lock beyond heap_close;
- *		in that case, the lock is released automatically at xact end.
+ *		As above, but lookup by name instead of OID.
  * ----------------
  */
-void
-heap_close(Relation relation, LOCKMODE lockmode)
+Relation
+heap_openr(const char *relationName, LOCKMODE lockmode)
 {
-	Assert(lockmode >= NoLock && lockmode < MAX_LOCKMODES);
+	Relation	r;
 
-	/*
-	 * increment access statistics
-	 */
-	IncrHeapAccessStat(local_close);
-	IncrHeapAccessStat(global_close);
+	r = relation_openr(relationName, lockmode);
 
-	if (lockmode != NoLock)
-		UnlockRelation(relation, lockmode);
+	if (r->rd_rel->relkind == RELKIND_INDEX)
+		elog(ERROR, "%s is an index relation",
+			 RelationGetRelationName(r));
+	else if (r->rd_rel->relkind == RELKIND_SPECIAL)
+		elog(ERROR, "%s is a special relation",
+			 RelationGetRelationName(r));
 
-	/* The relcache does the real work... */
-	RelationClose(relation);
+	pgstat_initstats(&r->pgstat_info, r);
+
+	return r;
 }
 
 
@@ -2332,8 +2329,7 @@ newsame:;
 	}
 
 	/* undo */
-	if (XLByteLT(PageGetLSN(page), lsn))		/* changes are not applied
-												 * ?! */
+	if (XLByteLT(PageGetLSN(page), lsn))		/* changes not applied?! */
 		elog(STOP, "heap_update_undo: bad new tuple page LSN");
 
 	elog(STOP, "heap_update_undo: unimplemented");
diff --git a/src/backend/access/heap/stats.c b/src/backend/access/heap/stats.c
deleted file mode 100644
index 6f5dfbea1412801ae784a68e84942a223b1fb588..0000000000000000000000000000000000000000
--- a/src/backend/access/heap/stats.c
+++ /dev/null
@@ -1,333 +0,0 @@
-/*-------------------------------------------------------------------------
- *
- * stats.c
- *	  heap access method debugging statistic collection routines
- *
- * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
- * Portions Copyright (c) 1994, Regents of the University of California
- *
- *
- * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/access/heap/Attic/stats.c,v 1.25 2001/10/25 05:49:21 momjian Exp $
- *
- * NOTES
- *	  initam should be moved someplace else.
- *
- *-------------------------------------------------------------------------
- */
-
-#include <time.h>
-
-#include "postgres.h"
-
-#include "access/heapam.h"
-
-
-static void InitHeapAccessStatistics(void);
-
-/* ----------------
- *		InitHeapAccessStatistics
- * ----------------
- */
-HeapAccessStatistics heap_access_stats = (HeapAccessStatistics) NULL;
-
-static void
-InitHeapAccessStatistics()
-{
-	MemoryContext oldContext;
-	HeapAccessStatistics stats;
-
-	/*
-	 * make sure we don't initialize things twice
-	 */
-	if (heap_access_stats != NULL)
-		return;
-
-	/*
-	 * allocate statistics structure from the top memory context
-	 */
-	oldContext = MemoryContextSwitchTo(TopMemoryContext);
-
-	stats = (HeapAccessStatistics)
-		palloc(sizeof(HeapAccessStatisticsData));
-
-	/*
-	 * initialize fields to default values
-	 */
-	stats->global_open = 0;
-	stats->global_openr = 0;
-	stats->global_close = 0;
-	stats->global_beginscan = 0;
-	stats->global_rescan = 0;
-	stats->global_endscan = 0;
-	stats->global_getnext = 0;
-	stats->global_fetch = 0;
-	stats->global_insert = 0;
-	stats->global_delete = 0;
-	stats->global_replace = 0;
-	stats->global_mark4update = 0;
-	stats->global_markpos = 0;
-	stats->global_restrpos = 0;
-	stats->global_BufferGetRelation = 0;
-	stats->global_RelationIdGetRelation = 0;
-	stats->global_RelationIdGetRelation_Buf = 0;
-	stats->global_getreldesc = 0;
-	stats->global_heapgettup = 0;
-	stats->global_RelationPutHeapTuple = 0;
-	stats->global_RelationPutLongHeapTuple = 0;
-
-	stats->local_open = 0;
-	stats->local_openr = 0;
-	stats->local_close = 0;
-	stats->local_beginscan = 0;
-	stats->local_rescan = 0;
-	stats->local_endscan = 0;
-	stats->local_getnext = 0;
-	stats->local_fetch = 0;
-	stats->local_insert = 0;
-	stats->local_delete = 0;
-	stats->local_replace = 0;
-	stats->local_mark4update = 0;
-	stats->local_markpos = 0;
-	stats->local_restrpos = 0;
-	stats->local_BufferGetRelation = 0;
-	stats->local_RelationIdGetRelation = 0;
-	stats->local_RelationIdGetRelation_Buf = 0;
-	stats->local_getreldesc = 0;
-	stats->local_heapgettup = 0;
-	stats->local_RelationPutHeapTuple = 0;
-	stats->local_RelationPutLongHeapTuple = 0;
-	stats->local_RelationNameGetRelation = 0;
-	stats->global_RelationNameGetRelation = 0;
-
-	/*
-	 * record init times
-	 */
-	time(&stats->init_global_timestamp);
-	time(&stats->local_reset_timestamp);
-	time(&stats->last_request_timestamp);
-
-	/*
-	 * return to old memory context
-	 */
-	MemoryContextSwitchTo(oldContext);
-
-	heap_access_stats = stats;
-}
-
-#ifdef NOT_USED
-/* ----------------
- *		ResetHeapAccessStatistics
- * ----------------
- */
-void
-ResetHeapAccessStatistics()
-{
-	HeapAccessStatistics stats;
-
-	/*
-	 * do nothing if stats aren't initialized
-	 */
-	if (heap_access_stats == NULL)
-		return;
-
-	stats = heap_access_stats;
-
-	/*
-	 * reset local counts
-	 */
-	stats->local_open = 0;
-	stats->local_openr = 0;
-	stats->local_close = 0;
-	stats->local_beginscan = 0;
-	stats->local_rescan = 0;
-	stats->local_endscan = 0;
-	stats->local_getnext = 0;
-	stats->local_fetch = 0;
-	stats->local_insert = 0;
-	stats->local_delete = 0;
-	stats->local_replace = 0;
-	stats->local_mark4update = 0;
-	stats->local_markpos = 0;
-	stats->local_restrpos = 0;
-	stats->local_BufferGetRelation = 0;
-	stats->local_RelationIdGetRelation = 0;
-	stats->local_RelationIdGetRelation_Buf = 0;
-	stats->local_getreldesc = 0;
-	stats->local_heapgettup = 0;
-	stats->local_RelationPutHeapTuple = 0;
-	stats->local_RelationPutLongHeapTuple = 0;
-
-	/*
-	 * reset local timestamps
-	 */
-	time(&stats->local_reset_timestamp);
-	time(&stats->last_request_timestamp);
-}
-#endif
-
-#ifdef NOT_USED
-/* ----------------
- *		GetHeapAccessStatistics
- * ----------------
- */
-HeapAccessStatistics
-GetHeapAccessStatistics()
-{
-	HeapAccessStatistics stats;
-
-	/*
-	 * return nothing if stats aren't initialized
-	 */
-	if (heap_access_stats == NULL)
-		return NULL;
-
-	/*
-	 * record the current request time
-	 */
-	time(&heap_access_stats->last_request_timestamp);
-
-	/*
-	 * allocate a copy of the stats and return it to the caller.
-	 */
-	stats = (HeapAccessStatistics)
-		palloc(sizeof(HeapAccessStatisticsData));
-
-	memmove(stats,
-			heap_access_stats,
-			sizeof(HeapAccessStatisticsData));
-
-	return stats;
-}
-#endif
-
-#ifdef NOT_USED
-/* ----------------
- *		PrintHeapAccessStatistics
- * ----------------
- */
-void
-PrintHeapAccessStatistics(HeapAccessStatistics stats)
-{
-	/*
-	 * return nothing if stats aren't valid
-	 */
-	if (stats == NULL)
-		return;
-
-	printf("======== heap am statistics ========\n");
-	printf("init_global_timestamp:      %s",
-		   ctime(&(stats->init_global_timestamp)));
-
-	printf("local_reset_timestamp:      %s",
-		   ctime(&(stats->local_reset_timestamp)));
-
-	printf("last_request_timestamp:     %s",
-		   ctime(&(stats->last_request_timestamp)));
-
-	printf("local/global_open:                        %6d/%6d\n",
-		   stats->local_open, stats->global_open);
-
-	printf("local/global_openr:                       %6d/%6d\n",
-		   stats->local_openr, stats->global_openr);
-
-	printf("local/global_close:                       %6d/%6d\n",
-		   stats->local_close, stats->global_close);
-
-	printf("local/global_beginscan:                   %6d/%6d\n",
-		   stats->local_beginscan, stats->global_beginscan);
-
-	printf("local/global_rescan:                      %6d/%6d\n",
-		   stats->local_rescan, stats->global_rescan);
-
-	printf("local/global_endscan:                     %6d/%6d\n",
-		   stats->local_endscan, stats->global_endscan);
-
-	printf("local/global_getnext:                     %6d/%6d\n",
-		   stats->local_getnext, stats->global_getnext);
-
-	printf("local/global_fetch:                       %6d/%6d\n",
-		   stats->local_fetch, stats->global_fetch);
-
-	printf("local/global_insert:                      %6d/%6d\n",
-		   stats->local_insert, stats->global_insert);
-
-	printf("local/global_delete:                      %6d/%6d\n",
-		   stats->local_delete, stats->global_delete);
-
-	printf("local/global_replace:                     %6d/%6d\n",
-		   stats->local_replace, stats->global_replace);
-
-	printf("local/global_mark4update:                     %6d/%6d\n",
-		   stats->local_mark4update, stats->global_mark4update);
-
-	printf("local/global_markpos:                     %6d/%6d\n",
-		   stats->local_markpos, stats->global_markpos);
-
-	printf("local/global_restrpos:                    %6d/%6d\n",
-		   stats->local_restrpos, stats->global_restrpos);
-
-	printf("================\n");
-
-	printf("local/global_BufferGetRelation:             %6d/%6d\n",
-		   stats->local_BufferGetRelation,
-		   stats->global_BufferGetRelation);
-
-	printf("local/global_RelationIdGetRelation:         %6d/%6d\n",
-		   stats->local_RelationIdGetRelation,
-		   stats->global_RelationIdGetRelation);
-
-	printf("local/global_RelationIdGetRelation_Buf:     %6d/%6d\n",
-		   stats->local_RelationIdGetRelation_Buf,
-		   stats->global_RelationIdGetRelation_Buf);
-
-	printf("local/global_getreldesc:                    %6d/%6d\n",
-		   stats->local_getreldesc, stats->global_getreldesc);
-
-	printf("local/global_heapgettup:                    %6d/%6d\n",
-		   stats->local_heapgettup, stats->global_heapgettup);
-
-	printf("local/global_RelationPutHeapTuple:          %6d/%6d\n",
-		   stats->local_RelationPutHeapTuple,
-		   stats->global_RelationPutHeapTuple);
-
-	printf("local/global_RelationPutLongHeapTuple:      %6d/%6d\n",
-		   stats->local_RelationPutLongHeapTuple,
-		   stats->global_RelationPutLongHeapTuple);
-
-	printf("===================================\n");
-
-	printf("\n");
-}
-#endif
-
-#ifdef NOT_USED
-/* ----------------
- *		PrintAndFreeHeapAccessStatistics
- * ----------------
- */
-void
-PrintAndFreeHeapAccessStatistics(HeapAccessStatistics stats)
-{
-	PrintHeapAccessStatistics(stats);
-	if (stats != NULL)
-		pfree(stats);
-}
-#endif
-
-/* ----------------------------------------------------------------
- *					access method initialization
- * ----------------------------------------------------------------
- */
-/* ----------------
- *		initam should someday be moved someplace else.
- * ----------------
- */
-void
-initam(void)
-{
-	/*
-	 * initialize heap statistics.
-	 */
-	InitHeapAccessStatistics();
-}
diff --git a/src/backend/access/index/indexam.c b/src/backend/access/index/indexam.c
index 8e1d5b87332a1de5acfc1a8c9be91e9344925c63..523349ebdb566d9f34576682152b0c07545a6644 100644
--- a/src/backend/access/index/indexam.c
+++ b/src/backend/access/index/indexam.c
@@ -8,12 +8,12 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/access/index/indexam.c,v 1.54 2001/10/25 05:49:21 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/access/index/indexam.c,v 1.55 2001/11/02 16:30:29 tgl Exp $
  *
  * INTERFACE ROUTINES
- *		index_open		- open an index relation by relationId
- *		index_openr		- open a index relation by name
- *		index_close		- close a index relation
+ *		index_open		- open an index relation by relation OID
+ *		index_openr		- open an index relation by name
+ *		index_close		- close an index relation
  *		index_beginscan - start a scan of an index
  *		index_rescan	- restart a scan of an index
  *		index_endscan	- end a scan
@@ -106,15 +106,17 @@
  *				   index_ interface functions
  * ----------------------------------------------------------------
  */
+
 /* ----------------
- *		index_open - open an index relation by relationId
- *
- *		presently the relcache routines do all the work we need
- *		to open/close index relations.	However, callers of index_open
- *		expect it to succeed, so we need to check for a failure return.
+ *		index_open - open an index relation by relation OID
  *
  *		Note: we acquire no lock on the index.	An AccessShareLock is
  *		acquired by index_beginscan (and released by index_endscan).
+ *		Generally, the caller should already hold some type of lock on
+ *		the parent relation to ensure that the index doesn't disappear.
+ *
+ *		This is a convenience routine adapted for indexscan use.
+ *		Some callers may prefer to use relation_open directly.
  * ----------------
  */
 Relation
@@ -122,13 +124,11 @@ index_open(Oid relationId)
 {
 	Relation	r;
 
-	r = RelationIdGetRelation(relationId);
-
-	if (!RelationIsValid(r))
-		elog(ERROR, "Index %u does not exist", relationId);
+	r = relation_open(relationId, NoLock);
 
 	if (r->rd_rel->relkind != RELKIND_INDEX)
-		elog(ERROR, "%s is not an index relation", RelationGetRelationName(r));
+		elog(ERROR, "%s is not an index relation",
+			 RelationGetRelationName(r));
 
 	pgstat_initstats(&r->pgstat_info, r);
 
@@ -136,23 +136,21 @@ index_open(Oid relationId)
 }
 
 /* ----------------
- *		index_openr - open a index relation by name
+ *		index_openr - open an index relation by name
  *
  *		As above, but lookup by name instead of OID.
  * ----------------
  */
 Relation
-index_openr(char *relationName)
+index_openr(const char *relationName)
 {
 	Relation	r;
 
-	r = RelationNameGetRelation(relationName);
-
-	if (!RelationIsValid(r))
-		elog(ERROR, "Index '%s' does not exist", relationName);
+	r = relation_openr(relationName, NoLock);
 
 	if (r->rd_rel->relkind != RELKIND_INDEX)
-		elog(ERROR, "%s is not an index relation", RelationGetRelationName(r));
+		elog(ERROR, "%s is not an index relation",
+			 RelationGetRelationName(r));
 
 	pgstat_initstats(&r->pgstat_info, r);
 
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 4e338b0eb21c137868075e507b61fc0fceb699cc..b5c25516cd1f1e1654ca2f5d49585c5aaff0884a 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.167 2001/10/25 20:37:30 tgl Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/catalog/index.c,v 1.168 2001/11/02 16:30:29 tgl Exp $
  *
  *
  * INTERFACE ROUTINES
@@ -1417,15 +1417,9 @@ UpdateStats(Oid relid, double reltuples)
 	 */
 
 	/*
-	 * Can't use heap_open here since we don't know if it's an index...
+	 * Grabbing lock here is probably redundant ...
 	 */
-	whichRel = RelationIdGetRelation(relid);
-
-	if (!RelationIsValid(whichRel))
-		elog(ERROR, "UpdateStats: cannot open relation id %u", relid);
-
-	/* Grab lock to be held till end of xact (probably redundant...) */
-	LockRelation(whichRel, ShareLock);
+	whichRel = relation_open(relid, ShareLock);
 
 	/*
 	 * Find the RELATION relation tuple for the given relation.
@@ -1553,8 +1547,7 @@ UpdateStats(Oid relid, double reltuples)
 		heap_endscan(pg_class_scan);
 
 	heap_close(pg_class, RowExclusiveLock);
-	/* Cheating a little bit since we didn't open it with heap_open... */
-	heap_close(whichRel, NoLock);
+	relation_close(whichRel, NoLock);
 }
 
 
diff --git a/src/backend/commands/command.c b/src/backend/commands/command.c
index b9cfee96e4f2642be77626373a2227535ec0e833..93c52e1b3340e1ae9a2631a609b5ddeff937f208 100644
--- a/src/backend/commands/command.c
+++ b/src/backend/commands/command.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/commands/Attic/command.c,v 1.148 2001/10/31 04:49:43 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/commands/Attic/command.c,v 1.149 2001/11/02 16:30:29 tgl Exp $
  *
  * NOTES
  *	  The PerformAddAttribute() code, like most of the relation
@@ -55,7 +55,6 @@
 
 static void drop_default(Oid relid, int16 attnum);
 static bool needs_toast_table(Relation rel);
-static bool is_relation(char *name);
 
 
 /* --------------------------------
@@ -554,9 +553,11 @@ AlterTableAlterColumnDefault(const char *relationName,
 #endif
 
 	rel = heap_openr(relationName, AccessExclusiveLock);
+
 	if (rel->rd_rel->relkind != RELKIND_RELATION)
 		elog(ERROR, "ALTER TABLE: relation \"%s\" is not a table",
 			 relationName);
+
 	myrelid = RelationGetRelid(rel);
 	heap_close(rel, NoLock);
 
@@ -721,9 +722,11 @@ AlterTableAlterColumnStatistics(const char *relationName,
 #endif
 
 	rel = heap_openr(relationName, AccessExclusiveLock);
+
 	if (rel->rd_rel->relkind != RELKIND_RELATION)
 		elog(ERROR, "ALTER TABLE: relation \"%s\" is not a table",
 			 relationName);
+
 	myrelid = RelationGetRelid(rel);
 	heap_close(rel, NoLock);	/* close rel, but keep lock! */
 
@@ -1192,12 +1195,16 @@ AlterTableAddConstraint(char *relationName,
 		elog(ERROR, "ALTER TABLE: permission denied");
 #endif
 
-	/* Disallow ADD CONSTRAINT on views, indexes, sequences, etc */
-	if (!is_relation(relationName))
-		elog(ERROR, "ALTER TABLE ADD CONSTRAINT: %s is not a table",
+	/*
+	 * Grab an exclusive lock on the target table, which we will NOT
+	 * release until end of transaction.
+	 */
+	rel = heap_openr(relationName, AccessExclusiveLock);
+
+	if (rel->rd_rel->relkind != RELKIND_RELATION)
+		elog(ERROR, "ALTER TABLE: relation \"%s\" is not a table",
 			 relationName);
 
-	rel = heap_openr(relationName, AccessExclusiveLock);
 	myrelid = RelationGetRelid(rel);
 
 	if (inh)
@@ -1686,7 +1693,7 @@ AlterTableDropConstraint(const char *relationName,
 
 	/* Disallow DROP CONSTRAINT on views, indexes, sequences, etc */
 	if (rel->rd_rel->relkind != RELKIND_RELATION)
-		elog(ERROR, "ALTER TABLE / DROP CONSTRAINT: %s is not a table",
+		elog(ERROR, "ALTER TABLE: relation \"%s\" is not a table",
 			 relationName);
 
 	/*
@@ -2053,7 +2060,6 @@ void
 LockTableCommand(LockStmt *lockstmt)
 {
 	List	   *p;
-	Relation	rel;
 
 	/*
 	 * Iterate over the list and open, lock, and close the relations one
@@ -2064,12 +2070,7 @@ LockTableCommand(LockStmt *lockstmt)
 	{
 		char	   *relname = strVal(lfirst(p));
 		int			aclresult;
-
-		rel = heap_openr(relname, NoLock);
-
-		if (rel->rd_rel->relkind != RELKIND_RELATION)
-			elog(ERROR, "LOCK TABLE: %s is not a table",
-				 relname);
+		Relation	rel;
 
 		if (lockstmt->mode == AccessShareLock)
 			aclresult = pg_aclcheck(relname, GetUserId(),
@@ -2081,21 +2082,13 @@ LockTableCommand(LockStmt *lockstmt)
 		if (aclresult != ACLCHECK_OK)
 			elog(ERROR, "LOCK TABLE: permission denied");
 
-		LockRelation(rel, lockstmt->mode);
-
-		heap_close(rel, NoLock);	/* close rel, keep lock */
-	}
-}
-
-
-static bool
-is_relation(char *name)
-{
-	Relation	rel = heap_openr(name, NoLock);
+		rel = relation_openr(relname, lockstmt->mode);
 
-	bool		retval = (rel->rd_rel->relkind == RELKIND_RELATION);
-
-	heap_close(rel, NoLock);
+		/* Currently, we only allow plain tables to be locked */
+		if (rel->rd_rel->relkind != RELKIND_RELATION)
+			elog(ERROR, "LOCK TABLE: %s is not a table",
+				 relname);
 
-	return retval;
+		relation_close(rel, NoLock);	/* close rel, keep lock */
+	}
 }
diff --git a/src/backend/commands/comment.c b/src/backend/commands/comment.c
index 647cb55b7e7d217c3a06ed5ffa5e5381b22b5df2..baeff0c172d240032826b5b81f269a74ad59b8c4 100644
--- a/src/backend/commands/comment.c
+++ b/src/backend/commands/comment.c
@@ -7,7 +7,7 @@
  * Copyright (c) 1999-2001, PostgreSQL Global Development Group
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/commands/comment.c,v 1.34 2001/10/25 05:49:24 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/commands/comment.c,v 1.35 2001/11/02 16:30:29 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -336,16 +336,8 @@ CommentRelation(int reltype, char *relname, char *comment)
 	 * ensures no one else drops the relation before we commit.  (If they
 	 * did, they'd fail to remove the entry we are about to make in
 	 * pg_description.)
-	 *
-	 * heap_openr will complain if it's an index, so we must do this:
 	 */
-	if (reltype != INDEX)
-		relation = heap_openr(relname, AccessShareLock);
-	else
-	{
-		relation = index_openr(relname);
-		LockRelation(relation, AccessShareLock);
-	}
+	relation = relation_openr(relname, AccessShareLock);
 
 	/* Next, verify that the relation type matches the intent */
 
@@ -374,11 +366,7 @@ CommentRelation(int reltype, char *relname, char *comment)
 	CreateComments(RelationGetRelid(relation), RelOid_pg_class, 0, comment);
 
 	/* Done, but hold lock until commit */
-
-	if (reltype != INDEX)
-		heap_close(relation, NoLock);
-	else
-		index_close(relation);
+	relation_close(relation, NoLock);
 }
 
 /*------------------------------------------------------------------
diff --git a/src/backend/commands/rename.c b/src/backend/commands/rename.c
index c65cfcc5519ed7c8d88d77e0e44e9dc7041c2e8b..42abe24f1387aa8940c3dc58dfe34ceac13245d4 100644
--- a/src/backend/commands/rename.c
+++ b/src/backend/commands/rename.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/commands/Attic/rename.c,v 1.59 2001/10/25 05:49:25 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/commands/Attic/rename.c,v 1.60 2001/11/02 16:30:29 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -258,19 +258,10 @@ renamerel(const char *oldrelname, const char *newrelname)
 		return;					/* all done... */
 
 	/*
-	 * Instead of using heap_openr(), do it the hard way, so that we can
-	 * rename indexes as well as regular relations.
-	 */
-	targetrelation = RelationNameGetRelation(oldrelname);
-
-	if (!RelationIsValid(targetrelation))
-		elog(ERROR, "Relation \"%s\" does not exist", oldrelname);
-
-	/*
-	 * Grab an exclusive lock on the target table, which we will NOT
+	 * Grab an exclusive lock on the target table or index, which we will NOT
 	 * release until end of transaction.
 	 */
-	LockRelation(targetrelation, AccessExclusiveLock);
+	targetrelation = relation_openr(oldrelname, AccessExclusiveLock);
 
 	reloid = RelationGetRelid(targetrelation);
 	relkind = targetrelation->rd_rel->relkind;
@@ -278,7 +269,7 @@ renamerel(const char *oldrelname, const char *newrelname)
 	/*
 	 * Close rel, but keep exclusive lock!
 	 */
-	heap_close(targetrelation, NoLock);
+	relation_close(targetrelation, NoLock);
 
 	/*
 	 * Flush the relcache entry (easier than trying to change it at
diff --git a/src/backend/parser/parse_func.c b/src/backend/parser/parse_func.c
index f6d94e5c552e456154e9354e387f9d813fb5668d..1f2887031e489add21960c553f8ab02a7029ab2b 100644
--- a/src/backend/parser/parse_func.c
+++ b/src/backend/parser/parse_func.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/parser/parse_func.c,v 1.112 2001/10/25 05:49:39 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/parser/parse_func.c,v 1.113 2001/11/02 16:30:29 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -131,7 +131,6 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs,
 	List	   *i = NIL;
 	Node	   *first_arg = NULL;
 	char	   *refname;
-	Relation	rd;
 	int			nargs = length(fargs);
 	int			argn;
 	Func	   *funcnode;
@@ -200,13 +199,10 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs,
 			if (attisset)
 			{
 				toid = exprType(first_arg);
-				rd = heap_openr_nofail(typeidTypeName(toid));
-				if (RelationIsValid(rd))
-					heap_close(rd, NoLock);
-				else
+				argrelid = typeidTypeRelid(toid);
+				if (argrelid == InvalidOid)
 					elog(ERROR, "Type '%s' is not a relation type",
 						 typeidTypeName(toid));
-				argrelid = typeidTypeRelid(toid);
 
 				/*
 				 * A projection must match an attribute name of the rel.
diff --git a/src/backend/utils/init/postinit.c b/src/backend/utils/init/postinit.c
index 3dc6deb0cb4704eacfb23c2494eed4f8d0ea502b..3a48b133bfe8aeb3bf50de83fc858b740d51dd67 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.96 2001/10/28 06:25:54 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/utils/init/postinit.c,v 1.97 2001/11/02 16:30:29 tgl Exp $
  *
  *
  *-------------------------------------------------------------------------
@@ -292,12 +292,6 @@ InitPostgres(const char *dbname, const char *username)
 	 */
 	RelationCacheInitialize();
 
-	/*
-	 * Initialize the access methods. Does not touch files (?) - thomas
-	 * 1997-11-01
-	 */
-	initam();
-
 	/*
 	 * Initialize all the system catalog caches.
 	 *
diff --git a/src/include/access/genam.h b/src/include/access/genam.h
index 88c1c06699b5c89e92dd348e65d513dff31520c6..dbef1a6cdad74fe6164ca291757f90028ee6f7d6 100644
--- a/src/include/access/genam.h
+++ b/src/include/access/genam.h
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: genam.h,v 1.29 2001/10/28 06:25:59 momjian Exp $
+ * $Id: genam.h,v 1.30 2001/11/02 16:30:29 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -36,7 +36,7 @@ typedef bool (*IndexBulkDeleteCallback) (ItemPointer itemptr, void *state);
  * ----------------
  */
 extern Relation index_open(Oid relationId);
-extern Relation index_openr(char *relationName);
+extern Relation index_openr(const char *relationName);
 extern void index_close(Relation relation);
 extern InsertIndexResult index_insert(Relation relation,
 			 Datum *datum, char *nulls,
diff --git a/src/include/access/heapam.h b/src/include/access/heapam.h
index 61fa3afea5660a68e837fe8865cadeed08d17177..b0124ed31cdd343d61b39cfb8c1d22940fa91de0 100644
--- a/src/include/access/heapam.h
+++ b/src/include/access/heapam.h
@@ -7,15 +7,13 @@
  * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: heapam.h,v 1.70 2001/10/28 06:25:59 momjian Exp $
+ * $Id: heapam.h,v 1.71 2001/11/02 16:30:29 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
 #ifndef HEAPAM_H
 #define HEAPAM_H
 
-#include <time.h>
-
 #include "access/htup.h"
 #include "access/relscan.h"
 #include "access/tupmacs.h"
@@ -26,67 +24,11 @@
 #include "utils/tqual.h"
 
 /* ----------------------------------------------------------------
- *				heap access method statistics
+ *				leftover cruft from old statistics code
  * ----------------------------------------------------------------
  */
 
-typedef struct HeapAccessStatisticsData
-{
-	time_t		init_global_timestamp;	/* time global statistics started */
-	time_t		local_reset_timestamp;	/* last time local reset was done */
-	time_t		last_request_timestamp; /* last time stats were requested */
-
-	int			global_open;
-	int			global_openr;
-	int			global_close;
-	int			global_beginscan;
-	int			global_rescan;
-	int			global_endscan;
-	int			global_getnext;
-	int			global_fetch;
-	int			global_insert;
-	int			global_delete;
-	int			global_replace;
-	int			global_mark4update;
-	int			global_markpos;
-	int			global_restrpos;
-	int			global_BufferGetRelation;
-	int			global_RelationIdGetRelation;
-	int			global_RelationIdGetRelation_Buf;
-	int			global_RelationNameGetRelation;
-	int			global_getreldesc;
-	int			global_heapgettup;
-	int			global_RelationPutHeapTuple;
-	int			global_RelationPutLongHeapTuple;
-
-	int			local_open;
-	int			local_openr;
-	int			local_close;
-	int			local_beginscan;
-	int			local_rescan;
-	int			local_endscan;
-	int			local_getnext;
-	int			local_fetch;
-	int			local_insert;
-	int			local_delete;
-	int			local_replace;
-	int			local_mark4update;
-	int			local_markpos;
-	int			local_restrpos;
-	int			local_BufferGetRelation;
-	int			local_RelationIdGetRelation;
-	int			local_RelationIdGetRelation_Buf;
-	int			local_RelationNameGetRelation;
-	int			local_getreldesc;
-	int			local_heapgettup;
-	int			local_RelationPutHeapTuple;
-	int			local_RelationPutLongHeapTuple;
-} HeapAccessStatisticsData;
-
-typedef HeapAccessStatisticsData *HeapAccessStatistics;
-
-#define IncrHeapAccessStat(x) \
-	(heap_access_stats == NULL ? 0 : (heap_access_stats->x)++)
+#define IncrHeapAccessStat(x)	((void) 0)
 
 /* ----------------
  *		fastgetattr
@@ -180,7 +122,6 @@ extern Datum fastgetattr(HeapTuple tup, int attnum, TupleDesc tupleDesc,
 
 extern Datum heap_getsysattr(HeapTuple tup, int attnum, bool *isnull);
 
-extern HeapAccessStatistics heap_access_stats;	/* in stats.c */
 
 /* ----------------
  *		function prototypes for heap access method
@@ -192,11 +133,14 @@ extern HeapAccessStatistics heap_access_stats;	/* in stats.c */
 
 /* heapam.c */
 
+extern Relation relation_open(Oid relationId, LOCKMODE lockmode);
+extern Relation relation_openr(const char *relationName, LOCKMODE lockmode);
+extern void relation_close(Relation relation, LOCKMODE lockmode);
+
 extern Relation heap_open(Oid relationId, LOCKMODE lockmode);
 extern Relation heap_openr(const char *relationName, LOCKMODE lockmode);
-extern Relation heap_open_nofail(Oid relationId);
-extern Relation heap_openr_nofail(const char *relationName);
-extern void heap_close(Relation relation, LOCKMODE lockmode);
+#define heap_close(r,l)  relation_close(r,l)
+
 extern HeapScanDesc heap_beginscan(Relation relation, int atend,
 			   Snapshot snapshot, unsigned nkeys, ScanKey key);
 extern void heap_rescan(HeapScanDesc scan, bool scanFromEnd, ScanKey key);
@@ -242,8 +186,4 @@ extern HeapTuple heap_modifytuple(HeapTuple tuple,
 extern void heap_freetuple(HeapTuple tuple);
 extern HeapTuple heap_addheader(int natts, Size structlen, void *structure);
 
-/* in common/heap/stats.c */
-extern void PrintHeapAccessStatistics(HeapAccessStatistics stats);
-extern void initam(void);
-
 #endif	 /* HEAPAM_H */
diff --git a/src/test/regress/expected/errors.out b/src/test/regress/expected/errors.out
index f652fb1eb0544e36e36fb64e4ab501a3e09353ba..8a4344fe1ec4d6837c0baa71ea61a11fbe678498 100644
--- a/src/test/regress/expected/errors.out
+++ b/src/test/regress/expected/errors.out
@@ -43,7 +43,7 @@ delete from;
 ERROR:  parser: parse error at or near ";"
 -- no such relation 
 delete from nonesuch;
-ERROR:  Relation 'nonesuch' does not exist
+ERROR:  Relation "nonesuch" does not exist
 --
 -- DESTROY
  
@@ -78,7 +78,7 @@ ERROR:  renamerel: relation "stud_emp" exists
 -- attribute renaming 
 -- no such relation 
 alter table nonesuchrel rename column nonesuchatt to newnonesuchatt;
-ERROR:  Relation 'nonesuchrel' does not exist
+ERROR:  Relation "nonesuchrel" does not exist
 -- no such attribute 
 alter table emp rename column nonesuchatt to newnonesuchatt;
 ERROR:  renameatt: attribute "nonesuchatt" does not exist
diff --git a/src/test/regress/expected/temp.out b/src/test/regress/expected/temp.out
index 7d085de85bcd7aa30cec934074e55b628f931b51..a3a583ec624a71a6fd46e0c3bc14cbb33b78a85b 100644
--- a/src/test/regress/expected/temp.out
+++ b/src/test/regress/expected/temp.out
@@ -34,4 +34,4 @@ CREATE TEMP TABLE temptest(col int);
 -- test temp table deletion
 \c regression
 SELECT * FROM temptest;
-ERROR:  Relation 'temptest' does not exist
+ERROR:  Relation "temptest" does not exist