diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c
index 379d0ecc5526ce515acc8064eaa209cce4548591..1e22c0304620ef9dc873c555e61b36eed34a5708 100644
--- a/src/backend/access/heap/heapam.c
+++ b/src/backend/access/heap/heapam.c
@@ -8,13 +8,14 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/access/heap/heapam.c,v 1.82 2000/07/22 11:18:46 wieck Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/access/heap/heapam.c,v 1.83 2000/08/03 19:18:54 tgl Exp $
  *
  *
  * INTERFACE ROUTINES
  *		heapgettup		- fetch next heap tuple from a scan
  *		heap_open		- open a heap relation by relationId
  *		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_beginscan	- begin relation scan
  *		heap_rescan		- restart a relation scan
@@ -560,19 +561,17 @@ fastgetattr(HeapTuple tup, int attnum, TupleDesc tupleDesc,
 #endif /* defined(DISABLE_COMPLEX_MACRO)*/
 
 
-
 /* ----------------------------------------------------------------
  *					 heap access method interface
  * ----------------------------------------------------------------
  */
+
 /* ----------------
  *		heap_open - open a heap relation by relationId
  *
- *		If lockmode is "NoLock", no lock is obtained on the relation,
- *		and the caller must check for a NULL return value indicating
- *		that no such relation exists.
- *		Otherwise, an error is raised if the relation does not exist,
- *		and the specified kind of lock is obtained on the relation.
+ *		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.
  * ----------------
  */
 Relation
@@ -592,17 +591,15 @@ heap_open(Oid relationId, LOCKMODE lockmode)
 	/* The relcache does all the real work... */
 	r = RelationIdGetRelation(relationId);
 
-	/* 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)
-		return r;				/* caller must check RelationIsValid! */
-
 	if (!RelationIsValid(r))
 		elog(ERROR, "Relation %u does not exist", relationId);
 
-	LockRelation(r, lockmode);
+	/* 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);
 
 	return r;
 }
@@ -610,11 +607,9 @@ heap_open(Oid relationId, LOCKMODE lockmode)
 /* ----------------
  *		heap_openr - open a heap relation by name
  *
- *		If lockmode is "NoLock", no lock is obtained on the relation,
- *		and the caller must check for a NULL return value indicating
- *		that no such relation exists.
- *		Otherwise, an error is raised if the relation does not exist,
- *		and the specified kind of lock is obtained on the relation.
+ *		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.
  * ----------------
  */
 Relation
@@ -624,7 +619,6 @@ heap_openr(const char *relationName, LOCKMODE lockmode)
 
 	Assert(lockmode >= NoLock && lockmode < MAX_LOCKMODES);
 
-
 	/* ----------------
 	 *	increment access statistics
 	 * ----------------
@@ -635,17 +629,77 @@ heap_openr(const char *relationName, LOCKMODE lockmode)
 	/* 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));
+
+	if (lockmode != NoLock)
+		LockRelation(r, lockmode);
+
+	return r;
+}
+
+/* ----------------
+ *		heap_open_nofail - open a heap relation by relationId,
+ *				do not raise error on failure
+ *
+ *		The caller must check for a NULL return value indicating
+ *		that no such relation exists.
+ *		No lock is obtained on the relation, either.
+ * ----------------
+ */
+Relation
+heap_open_nofail(Oid relationId)
+{
+	Relation	r;
+
+	/* ----------------
+	 *	increment access statistics
+	 * ----------------
+	 */
+	IncrHeapAccessStat(local_open);
+	IncrHeapAccessStat(global_open);
+
+	/* The relcache does all the real work... */
+	r = RelationIdGetRelation(relationId);
+
 	/* 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)
-		return r;				/* caller must check RelationIsValid! */
+	return r;
+}
 
-	if (!RelationIsValid(r))
-		elog(ERROR, "Relation '%s' does not exist", relationName);
+/* ----------------
+ *		heap_openr_nofail - open a heap relation by name,
+ *				do not raise error on failure
+ *
+ *		The caller must check for a NULL return value indicating
+ *		that no such relation exists.
+ *		No lock is obtained on the relation, either.
+ * ----------------
+ */
+Relation
+heap_openr_nofail(const char *relationName)
+{
+	Relation	r;
 
-	LockRelation(r, lockmode);
+	/* ----------------
+	 *	increment access statistics
+	 * ----------------
+	 */
+	IncrHeapAccessStat(local_openr);
+	IncrHeapAccessStat(global_openr);
+
+	/* 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));
 
 	return r;
 }
diff --git a/src/backend/access/transam/transam.c b/src/backend/access/transam/transam.c
index acca4a901a2f16083d1eff601ec4647046d1b527..52a3906ba6989dd0537aa0b5d18f12f22930722c 100644
--- a/src/backend/access/transam/transam.c
+++ b/src/backend/access/transam/transam.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/access/transam/transam.c,v 1.34 2000/04/12 17:14:52 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/access/transam/transam.c,v 1.35 2000/08/03 19:18:55 tgl Exp $
  *
  * NOTES
  *	  This file contains the high level access-method interface to the
@@ -408,9 +408,7 @@ InitializeTransactionLog(void)
 	 * ----------------
 	 */
 	logRelation = heap_openr(LogRelationName, NoLock);
-	Assert(logRelation != NULL);
 	VariableRelation = heap_openr(VariableRelationName, NoLock);
-	Assert(VariableRelation != NULL);
 
 	/* ----------------
 	 *	 XXX TransactionLogUpdate requires that LogRelation
diff --git a/src/backend/bootstrap/bootstrap.c b/src/backend/bootstrap/bootstrap.c
index c3cf93717241ec962fb10b37c19dcc9f9319d48a..2eacad23dc3133ac55b7d6337548c965008dad45 100644
--- a/src/backend/bootstrap/bootstrap.c
+++ b/src/backend/bootstrap/bootstrap.c
@@ -8,7 +8,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/bootstrap/bootstrap.c,v 1.91 2000/07/14 22:17:38 tgl Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/bootstrap/bootstrap.c,v 1.92 2000/08/03 19:19:06 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -430,7 +430,6 @@ boot_openrel(char *relname)
 	if (Typ == (struct typmap **) NULL)
 	{
 		rel = heap_openr(TypeRelationName, NoLock);
-		Assert(rel);
 		scan = heap_beginscan(rel, 0, SnapshotNow, 0, (ScanKey) NULL);
 		i = 0;
 		while (HeapTupleIsValid(tup = heap_getnext(scan, 0)))
@@ -462,7 +461,6 @@ boot_openrel(char *relname)
 			   (int) ATTRIBUTE_TUPLE_SIZE);
 
 	reldesc = heap_openr(relname, NoLock);
-	Assert(reldesc);
 	numattr = reldesc->rd_rel->relnatts;
 	for (i = 0; i < numattr; i++)
 	{
@@ -822,7 +820,6 @@ gettype(char *type)
 		if (DebugMode)
 			printf("bootstrap.c: External Type: %s\n", type);
 		rel = heap_openr(TypeRelationName, NoLock);
-		Assert(rel);
 		scan = heap_beginscan(rel, 0, SnapshotNow, 0, (ScanKey) NULL);
 		i = 0;
 		while (HeapTupleIsValid(tup = heap_getnext(scan, 0)))
@@ -1116,9 +1113,7 @@ build_indices()
 		Relation	ind;
 
 		heap = heap_openr(ILHead->il_heap, NoLock);
-		Assert(heap);
 		ind = index_openr(ILHead->il_ind);
-		Assert(ind);
 		index_build(heap, ind, ILHead->il_info, NULL);
 
 		/*
diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 6c8c95563f2d38123677ecf9e63de7bed0a8c8df..cf4b86e2e82cca3dfe0df06020584ccb2bb01b54 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.141 2000/08/03 16:33:52 tgl Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.142 2000/08/03 19:19:08 tgl Exp $
  *
  *
  * INTERFACE ROUTINES
@@ -1134,7 +1134,6 @@ RelationTruncateIndexes(Relation heapRelation)
 		 * by heap_truncate.
 		 */
 		heapRelation = heap_open(heapId, NoLock);
-		Assert(heapRelation != NULL);
 	}
 
 	/* Complete the scan and close pg_index */
diff --git a/src/backend/commands/command.c b/src/backend/commands/command.c
index 3deea360e0a19485cc206e28e1a6737d8fc5c3fe..de2597bd266016ea9a3b58aaf0c39605fcf8f5f0 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.92 2000/08/03 16:34:01 tgl Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/commands/Attic/command.c,v 1.93 2000/08/03 19:19:18 tgl Exp $
  *
  * NOTES
  *	  The PerformAddAttribute() code, like most of the relation
@@ -1614,8 +1614,6 @@ LockTableCommand(LockStmt *lockstmt)
 	int			aclresult;
 
 	rel = heap_openr(lockstmt->relname, NoLock);
-	if (!RelationIsValid(rel))
-		elog(ERROR, "Relation '%s' does not exist", lockstmt->relname);
 
 	if (lockstmt->mode == AccessShareLock)
 		aclresult = pg_aclcheck(lockstmt->relname, GetPgUserName(), ACL_RD);
diff --git a/src/backend/commands/trigger.c b/src/backend/commands/trigger.c
index 17e61a379fb6a9ca5fe74565878f45d6025b8c8b..a03f140b64f87e218f2e2a524bc866377ce744c6 100644
--- a/src/backend/commands/trigger.c
+++ b/src/backend/commands/trigger.c
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/commands/trigger.c,v 1.74 2000/08/03 16:34:01 tgl Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/commands/trigger.c,v 1.75 2000/08/03 19:19:18 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -92,9 +92,6 @@ CreateTrigger(CreateTrigStmt *stmt)
 			 * interested in getting the relation's OID...
 			 */
 			rel = heap_openr(stmt->constrrelname, NoLock);
-			if (rel == NULL)
-				elog(ERROR, "table \"%s\" does not exist",
-					 stmt->constrrelname);
 			constrrelid = rel->rd_id;
 			heap_close(rel, NoLock);
 		}
@@ -440,12 +437,12 @@ RelationRemoveTriggers(Relation rel)
 		pg_trigger = (Form_pg_trigger) GETSTRUCT(tup);
 
 		refrel = heap_open(pg_trigger->tgrelid, NoLock);
-
 		stmt.relname = pstrdup(RelationGetRelationName(refrel));
+		heap_close(refrel, NoLock);
+
 		stmt.trigname = DatumGetCString(DirectFunctionCall1(nameout,
 						NameGetDatum(&pg_trigger->tgname)));
 
-		heap_close(refrel, NoLock);
 
 		elog(NOTICE, "DROP TABLE implicitly drops referential integrity trigger from table \"%s\"", stmt.relname);
 
diff --git a/src/backend/executor/execAmi.c b/src/backend/executor/execAmi.c
index c3cb019c89d679459e0cf7b08b2a8b45756d2baf..99d6b7b27be110963439d41d73323e163e3c8b86 100644
--- a/src/backend/executor/execAmi.c
+++ b/src/backend/executor/execAmi.c
@@ -6,7 +6,7 @@
  * Portions Copyright (c) 1996-2000, PostgreSQL, Inc
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- *	$Id: execAmi.c,v 1.50 2000/07/25 23:43:38 tgl Exp $
+ *	$Id: execAmi.c,v 1.51 2000/08/03 19:19:30 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -98,9 +98,6 @@ ExecOpenScanR(Oid relOid,
 	else
 		relation = heap_open(relOid, NoLock);
 
-	if (relation == NULL)
-		elog(ERROR, "ExecOpenScanR: failed to open relation %u", relOid);
-
 	scanDesc = ExecBeginScan(relation,
 							 nkeys,
 							 skeys,
diff --git a/src/backend/executor/nodeTidscan.c b/src/backend/executor/nodeTidscan.c
index 824ead5ec6b0de25f818a8efef8aaca09d0b3273..ac6511dcbfb5a0a4688bbc51a06738c7fa5834fe 100644
--- a/src/backend/executor/nodeTidscan.c
+++ b/src/backend/executor/nodeTidscan.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/executor/nodeTidscan.c,v 1.10 2000/07/12 02:37:04 tgl Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/executor/nodeTidscan.c,v 1.11 2000/08/03 19:19:30 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -481,8 +481,6 @@ ExecInitTidScan(TidScan *node, EState *estate, Plan *parent)
 	reloid = rtentry->relid;
 
 	currentRelation = heap_open(reloid, AccessShareLock);
-	if (currentRelation == NULL)
-		elog(ERROR, "ExecInitTidScan heap_open failed.");
 	scanstate->css_currentRelation = currentRelation;
 	scanstate->css_currentScanDesc = 0;
 
diff --git a/src/backend/parser/parse_func.c b/src/backend/parser/parse_func.c
index 1ff6b5344472b9b2b0a496e360f1573f2d1d476d..d1a5e44f8735a2ab88f22a921ab189022091e0a3 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.85 2000/06/15 04:09:54 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/parser/parse_func.c,v 1.86 2000/08/03 19:19:34 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -382,7 +382,7 @@ ParseFuncOrColumn(ParseState *pstate, char *funcname, List *fargs,
 			if (attisset)
 			{
 				toid = exprType(first_arg);
-				rd = heap_openr(typeidTypeName(toid), NoLock);
+				rd = heap_openr_nofail(typeidTypeName(toid));
 				if (RelationIsValid(rd))
 				{
 					relname = RelationGetRelationName(rd);
@@ -1376,8 +1376,6 @@ find_inheritors(Oid relid, Oid **supervec)
 
 			relid = lfirsti(elt);
 			rd = heap_open(relid, NoLock);
-			if (!RelationIsValid(rd))
-				elog(ERROR, "Relid %u does not exist", relid);
 			trelid = typeTypeId(typenameType(RelationGetRelationName(rd)));
 			heap_close(rd, NoLock);
 			*relidvec++ = trelid;
@@ -1627,7 +1625,7 @@ ParseComplexProjection(ParseState *pstate,
 					 */
 
 					/* add a tlist to the func node and return the Iter */
-					rd = heap_openr(typeidTypeName(argtype), NoLock);
+					rd = heap_openr_nofail(typeidTypeName(argtype));
 					if (RelationIsValid(rd))
 					{
 						relid = RelationGetRelid(rd);
@@ -1679,29 +1677,24 @@ ParseComplexProjection(ParseState *pstate,
 					(attnum = get_attnum(argrelid, funcname))
 					!= InvalidAttrNumber)
 				{
+					Expr	   *newexpr;
 
 					/* add a tlist to the func node */
 					rd = heap_openr(typeidTypeName(argtype), NoLock);
-					if (RelationIsValid(rd))
-					{
-						Expr	   *newexpr;
-
-						relid = RelationGetRelid(rd);
-						funcnode->func_tlist = setup_tlist(funcname, argrelid);
-						funcnode->functype = attnumTypeId(rd, attnum);
 
-						newexpr = makeNode(Expr);
-						newexpr->typeOid = funcnode->functype;
-						newexpr->opType = FUNC_EXPR;
-						newexpr->oper = (Node *) funcnode;
-						newexpr->args = expr->args;
+					relid = RelationGetRelid(rd);
+					funcnode->func_tlist = setup_tlist(funcname, argrelid);
+					funcnode->functype = attnumTypeId(rd, attnum);
 
-						heap_close(rd, NoLock);
+					newexpr = makeNode(Expr);
+					newexpr->typeOid = funcnode->functype;
+					newexpr->opType = FUNC_EXPR;
+					newexpr->oper = (Node *) funcnode;
+					newexpr->args = expr->args;
 
-						return (Node *) newexpr;
-					}
-					/* XXX why not an error condition if it's not there? */
+					heap_close(rd, NoLock);
 
+					return (Node *) newexpr;
 				}
 
 				break;
@@ -1714,7 +1707,7 @@ ParseComplexProjection(ParseState *pstate,
 				 * If the Param is a complex type, this could be a
 				 * projection
 				 */
-				rd = heap_openr(typeidTypeName(param->paramtype), NoLock);
+				rd = heap_openr_nofail(typeidTypeName(param->paramtype));
 				if (RelationIsValid(rd))
 				{
 					relid = RelationGetRelid(rd);
diff --git a/src/include/access/heapam.h b/src/include/access/heapam.h
index c716ab239265b3c1e1d44e974b6550f39d65bfb4..d110759cb621e283fec0a18023493757d55267c5 100644
--- a/src/include/access/heapam.h
+++ b/src/include/access/heapam.h
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2000, PostgreSQL, Inc
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: heapam.h,v 1.55 2000/07/02 22:01:00 momjian Exp $
+ * $Id: heapam.h,v 1.56 2000/08/03 19:19:38 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -216,6 +216,8 @@ extern HeapAccessStatistics heap_access_stats;	/* in stats.c */
 
 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);
 extern HeapScanDesc heap_beginscan(Relation relation, int atend,
 			   Snapshot snapshot, unsigned nkeys, ScanKey key);