diff --git a/doc/src/sgml/bki.sgml b/doc/src/sgml/bki.sgml
index 2e4b12f91b33fb28dddb723796769ca11f1b593e..2b90f048e3b21b4474bf122f795865d79462c59b 100644
--- a/doc/src/sgml/bki.sgml
+++ b/doc/src/sgml/bki.sgml
@@ -1,4 +1,6 @@
-<!-- $Header: /cvsroot/pgsql/doc/src/sgml/bki.sgml,v 1.6 2000/12/23 16:24:29 petere Exp $ -->
+<!--
+$Header: /cvsroot/pgsql/doc/src/sgml/bki.sgml,v 1.7 2001/06/12 05:55:48 tgl Exp $
+ -->
 
 <chapter id="bki">
  <title><acronym>BKI</acronym> Backend Interface</title>
@@ -15,16 +17,14 @@
  </para>
 
  <para>
-  <application>initdb</application> uses <acronym>BKI</acronym> files
+  <application>initdb</application> uses a <acronym>BKI</acronym> file
   to do part of its job when creating a new database cluster.  The
-  input files used by <application>initbd</application> are created as
+  input file used by <application>initdb</application> is created as
   part of building and installing <productname>Postgres</productname>
   by a program named <filename>genbki.sh</filename> from some
   specially formatted C header files in the source tree.  The created
-  BKI files are called <filename>global.bki</filename> (for global
-  catalogs) and <filename>template1.bki</filename> (for the catalogs
-  initially stored in the template1 database and then duplicated in
-  every created database) and are normally installed in the
+  BKI file is called <filename>postgres.bki</filename> and is
+  normally installed in the
   <filename>share</filename> subdirectory of the installation tree.
  </para>
 
@@ -39,7 +39,7 @@
   <para>
    This section describes how the <productname>Postgres</productname>
    backend interprets <acronym>BKI</acronym> files.  This description
-   will be easier to understand if the <filename>global.bki</filename>
+   will be easier to understand if the <filename>postgres.bki</filename>
    file is at hand as an example.  You should also study the source
    code of <application>initdb</application> to get an idea of how the
    backend is invoked.
@@ -49,7 +49,7 @@
    BKI input consists of a sequence of commands.  Commands are made up
    of a number of tokens, depending on the syntax of the command.
    Tokens are usually separated by whitespace, but need not be if
-   there is no ambiguity.  There is not special command separator; the
+   there is no ambiguity.  There is no special command separator; the
    next token that syntactically cannot belong to the preceeding
    command starts a new one.  (Usually you would put a new command on
    a new line, for clarity.)  Tokens can be certain key words, special
@@ -155,13 +155,13 @@
       values and <replaceable
       class="parameter">oid_value</replaceable> for its OID.  If
       <replaceable class="parameter">oid_value</replaceable> is zero
-      (0) or the clause is ommitted, then the next available OID is
+      (0) or the clause is omitted, then the next available OID is
       used.
      </para>
 
      <para>
       NULL values can be specified using the special key word
-      <literal>_null_</literal>.  Values containing spaces should be
+      <literal>_null_</literal>.  Values containing spaces must be
       double quoted.
      </para>
     </listitem>
diff --git a/doc/src/sgml/catalogs.sgml b/doc/src/sgml/catalogs.sgml
index 27b8314518ab17bb9853da0b62ac2707edd732e5..9c3814820dc9fc4bf052a73be7506356353a9d2e 100644
--- a/doc/src/sgml/catalogs.sgml
+++ b/doc/src/sgml/catalogs.sgml
@@ -1,6 +1,6 @@
 <!--
  Documentation of the system catalogs, directed toward PostgreSQL developers
- $Header: /cvsroot/pgsql/doc/src/sgml/catalogs.sgml,v 2.17 2001/05/14 20:30:19 momjian Exp $
+ $Header: /cvsroot/pgsql/doc/src/sgml/catalogs.sgml,v 2.18 2001/06/12 05:55:48 tgl Exp $
  -->
 
 <chapter id="catalogs">
@@ -645,7 +645,8 @@
       <entry>relisshared</entry>
       <entry><type>bool</type></entry>
       <entry></entry>
-      <entry>XXX (This is not what it seems to be.)</entry>
+      <entry>True if this table is shared across all databases in the
+      cluster.</entry>
      </row>
 
      <row>
diff --git a/src/backend/access/common/heaptuple.c b/src/backend/access/common/heaptuple.c
index 1f9622e39ba8c26e9a1bb0407cabd2022ad1ba22..faaf33c50965ac11ad0c5d4045b5c4139134506a 100644
--- a/src/backend/access/common/heaptuple.c
+++ b/src/backend/access/common/heaptuple.c
@@ -9,7 +9,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/access/common/heaptuple.c,v 1.71 2001/03/22 06:16:06 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/access/common/heaptuple.c,v 1.72 2001/06/12 05:55:49 tgl Exp $
  *
  * NOTES
  *	  The old interface functions have been converted to macros
@@ -738,44 +738,46 @@ heap_freetuple(HeapTuple htup)
 }
 
 
-/* ----------------------------------------------------------------
- *						other misc functions
- * ----------------------------------------------------------------
+/* ----------------
+ *		heap_addheader
+ *
+ * This routine forms a HeapTuple by copying the given structure (tuple
+ * data) and adding a generic header.  Note that the tuple data is
+ * presumed to contain no null fields.  It is typically only useful
+ * for null-free system tables.
+ * ----------------
  */
-
 HeapTuple
-heap_addheader(uint32 natts,	/* max domain index */
-			   int structlen,	/* its length */
-			   char *structure) /* pointer to the struct */
+heap_addheader(int natts,		/* max domain index */
+			   Size structlen,	/* its length */
+			   void *structure) /* pointer to the struct */
 {
 	HeapTuple	tuple;
-	HeapTupleHeader td;			/* tuple data */
-	unsigned long len;
+	HeapTupleHeader td;
+	Size		len;
 	int			hoff;
 
 	AssertArg(natts > 0);
 
-	len = offsetof(HeapTupleHeaderData, t_bits);
+	/* header needs no null bitmap */
+	hoff = MAXALIGN(offsetof(HeapTupleHeaderData, t_bits));
+	len = hoff + structlen;
 
-	hoff = len = MAXALIGN(len); /* be conservative */
-	len += structlen;
 	tuple = (HeapTuple) palloc(HEAPTUPLESIZE + len);
-	tuple->t_datamcxt = CurrentMemoryContext;
-	td = tuple->t_data = (HeapTupleHeader) ((char *) tuple + HEAPTUPLESIZE);
 
 	tuple->t_len = len;
 	ItemPointerSetInvalid(&(tuple->t_self));
 	tuple->t_tableOid = InvalidOid;
+	tuple->t_datamcxt = CurrentMemoryContext;
+	tuple->t_data = td = (HeapTupleHeader) ((char *) tuple + HEAPTUPLESIZE);
 
 	MemSet((char *) td, 0, len);
 
 	td->t_hoff = hoff;
 	td->t_natts = natts;
-	td->t_infomask = 0;
-	td->t_infomask |= HEAP_XMAX_INVALID;
+	td->t_infomask = HEAP_XMAX_INVALID;	/* XXX sufficient? */
 
-	if (structlen > 0)
-		memcpy((char *) td + hoff, structure, (size_t) structlen);
+	memcpy((char *) td + hoff, structure, structlen);
 
 	return tuple;
 }
diff --git a/src/backend/catalog/Makefile b/src/backend/catalog/Makefile
index 51a1aecca1141e3849d547c2543eb63a83cdbdc1..07801c9a14ee35e3e2b49318c8533b9b8313806c 100644
--- a/src/backend/catalog/Makefile
+++ b/src/backend/catalog/Makefile
@@ -2,7 +2,7 @@
 #
 # Makefile for catalog
 #
-# $Header: /cvsroot/pgsql/src/backend/catalog/Makefile,v 1.34 2001/05/14 21:58:10 momjian Exp $
+# $Header: /cvsroot/pgsql/src/backend/catalog/Makefile,v 1.35 2001/06/12 05:55:49 tgl Exp $
 #
 #-------------------------------------------------------------------------
 
@@ -14,42 +14,36 @@ OBJS = catalog.o heap.o index.o indexing.o aclchk.o \
        pg_aggregate.o pg_largeobject.o pg_operator.o pg_proc.o \
        pg_type.o
 
-BKIFILES = global.bki template1.bki global.description template1.description
+BKIFILES = postgres.bki postgres.description
 
 all: SUBSYS.o $(BKIFILES)
 
 SUBSYS.o: $(OBJS)
 	$(LD) $(LDREL) $(LDOUT) SUBSYS.o $(OBJS)
 
+# Note: there are some undocumented dependencies on the ordering in which
+# the catalog header files are assembled into postgres.bki.  In particular,
+# indexing.h had better be last.
 
-GLOBAL_BKI_SRCS := $(addprefix $(top_srcdir)/src/include/catalog/,\
-	pg_database.h pg_shadow.h pg_group.h pg_log.h \
-    )
-
-TEMPLATE1_BKI_SRCS := $(addprefix $(top_srcdir)/src/include/catalog/,\
+POSTGRES_BKI_SRCS := $(addprefix $(top_srcdir)/src/include/catalog/,\
 	pg_proc.h pg_type.h pg_attribute.h pg_class.h \
-	pg_inherits.h pg_index.h pg_statistic.h \
+	pg_attrdef.h pg_relcheck.h pg_inherits.h pg_index.h \
 	pg_operator.h pg_opclass.h pg_am.h pg_amop.h pg_amproc.h \
-	pg_language.h pg_largeobject.h pg_aggregate.h \
-	pg_rewrite.h pg_listener.h pg_description.h indexing.h \
+	pg_language.h pg_largeobject.h pg_aggregate.h pg_statistic.h \
+	pg_rewrite.h pg_trigger.h pg_listener.h pg_description.h \
+	pg_database.h pg_shadow.h pg_group.h pg_log.h indexing.h \
     )
 
 pg_includes := $(sort -I$(top_srcdir)/src/include -I$(top_builddir)/src/include)
 
-global.bki global.description: genbki.sh $(GLOBAL_BKI_SRCS) $(top_srcdir)/src/include/catalog/indexing.h \
-    $(top_srcdir)/src/include/postgres_ext.h $(top_builddir)/src/include/config.h
-	CPP='$(CPP)' AWK='$(AWK)' $(SHELL) $< $(BKIOPTS) -o global $(pg_includes) $(GLOBAL_BKI_SRCS) --set-version=$(VERSION)
-
-template1.bki template1.description: genbki.sh $(TEMPLATE1_BKI_SRCS) \
+postgres.bki postgres.description: genbki.sh $(POSTGRES_BKI_SRCS) \
     $(top_srcdir)/src/include/postgres_ext.h $(top_builddir)/src/include/config.h
-	CPP='$(CPP)' AWK='$(AWK)' $(SHELL) $< $(BKIOPTS) -o template1 $(pg_includes) $(TEMPLATE1_BKI_SRCS) --set-version=$(VERSION)
+	CPP='$(CPP)' AWK='$(AWK)' $(SHELL) $< $(BKIOPTS) -o postgres $(pg_includes) $(POSTGRES_BKI_SRCS) --set-version=$(VERSION)
 
 .PHONY: install-bki
 install-bki: $(BKIFILES) installdirs
-	$(INSTALL_DATA) global.bki            $(DESTDIR)$(datadir)/global.bki
-	$(INSTALL_DATA) global.description    $(DESTDIR)$(datadir)/global.description
-	$(INSTALL_DATA) template1.bki         $(DESTDIR)$(datadir)/template1.bki
-	$(INSTALL_DATA) template1.description $(DESTDIR)$(datadir)/template1.description
+	$(INSTALL_DATA) postgres.bki         $(DESTDIR)$(datadir)/postgres.bki
+	$(INSTALL_DATA) postgres.description $(DESTDIR)$(datadir)/postgres.description
 
 installdirs:
 	$(mkinstalldirs) $(DESTDIR)$(datadir)
diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index 0675cd766a5f1e17373bc7f3be20e925aed964bd..0a9d6ce6bb3c20bd8567138b81c1f4055d05b915 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.166 2001/05/30 12:57:36 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/catalog/heap.c,v 1.167 2001/06/12 05:55:49 tgl Exp $
  *
  *
  * INTERFACE ROUTINES
@@ -218,8 +218,9 @@ heap_create(char *relname,
 	}
 
 	/*
-	 * real ugly stuff to assign the proper relid in the relation
-	 * descriptor follows.
+	 * Real ugly stuff to assign the proper relid in the relation
+	 * descriptor follows.  Note that only "bootstrapped" relations
+	 * whose OIDs are hard-coded in pg_class.h need be listed here.
 	 */
 	if (relname && IsSystemRelationName(relname))
 	{
@@ -263,12 +264,6 @@ heap_create(char *relname,
 			tblNode = InvalidOid;
 			relid = RelOid_pg_log;
 		}
-		else if (strcmp(AttrDefaultRelationName, relname) == 0)
-			relid = RelOid_pg_attrdef;
-		else if (strcmp(RelCheckRelationName, relname) == 0)
-			relid = RelOid_pg_relcheck;
-		else if (strcmp(TriggerRelationName, relname) == 0)
-			relid = RelOid_pg_trigger;
 		else
 		{
 			relid = newoid();
@@ -566,7 +561,7 @@ AddNewAttributeTuples(Oid new_rel_oid,
 
 		tup = heap_addheader(Natts_pg_attribute,
 							 ATTRIBUTE_TUPLE_SIZE,
-							 (char *) *dpp);
+							 (void *) *dpp);
 
 		heap_insert(rel, tup);
 
@@ -583,16 +578,18 @@ AddNewAttributeTuples(Oid new_rel_oid,
 	dpp = SysAtt;
 	for (i = 0; i < -1 - FirstLowInvalidHeapAttributeNumber; i++)
 	{
-		/* Fill in the correct relation OID */
-		/* HACK: we are writing on static data here */
-		(*dpp)->attrelid = new_rel_oid;
-		/* Unneeded since they should be OK in the constant data anyway */
-		/* (*dpp)->attstattarget = 0; */
-		/* (*dpp)->attcacheoff = -1; */
+		Form_pg_attribute attStruct;
 
 		tup = heap_addheader(Natts_pg_attribute,
 							 ATTRIBUTE_TUPLE_SIZE,
-							 (char *) *dpp);
+							 (void *) *dpp);
+
+		/* Fill in the correct relation OID in the copied tuple */
+		attStruct = (Form_pg_attribute) GETSTRUCT(tup);
+		attStruct->attrelid = new_rel_oid;
+		/* Unneeded since they should be OK in the constant data anyway */
+		/* attStruct->attstattarget = 0; */
+		/* attStruct->attcacheoff = -1; */
 
 		heap_insert(rel, tup);
 
@@ -603,13 +600,13 @@ AddNewAttributeTuples(Oid new_rel_oid,
 		dpp++;
 	}
 
-	heap_close(rel, RowExclusiveLock);
-
 	/*
 	 * close pg_attribute indices
 	 */
 	if (hasindex)
 		CatalogCloseIndices(Num_pg_attr_indices, idescs);
+
+	heap_close(rel, RowExclusiveLock);
 }
 
 /* --------------------------------
@@ -686,7 +683,7 @@ AddNewRelationTuple(Relation pg_class_desc,
 	 */
 	tup = heap_addheader(Natts_pg_class_fixed,
 						 CLASS_TUPLE_SIZE,
-						 (char *) new_rel_reltup);
+						 (void *) new_rel_reltup);
 
 	/* force tuple to have the desired OID */
 	tup->t_data->t_oid = new_rel_oid;
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 9b98bd75e9ee1585581620257f09a00967370bed..8046e4229678ec937e4fdd82fc78b423f2d7c430 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.153 2001/06/01 02:41:35 tgl Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/catalog/index.c,v 1.154 2001/06/12 05:55:49 tgl Exp $
  *
  *
  * INTERFACE ROUTINES
@@ -343,17 +343,19 @@ AccessMethodObjectIdGetForm(Oid accessMethodObjectId,
 static void
 ConstructIndexReldesc(Relation indexRelation, Oid amoid)
 {
+	/*
+	 * Fill in a copy of relevant pg_am entry
+	 */
 	indexRelation->rd_am = AccessMethodObjectIdGetForm(amoid,
-													 CacheMemoryContext);
-
+													   CacheMemoryContext);
 	/*
-	 * XXX missing the initialization of some other fields
+	 * Set up some additional fields of the index' pg_class entry.
+	 * In particular, initialize knowledge of whether the index is shared.
 	 */
-
 	indexRelation->rd_rel->relowner = GetUserId();
-
 	indexRelation->rd_rel->relam = amoid;
-	indexRelation->rd_rel->reltuples = 1;		/* XXX */
+	indexRelation->rd_rel->relisshared = 
+		IsSharedSystemRelationName(RelationGetPhysicalRelationName(indexRelation));
 	indexRelation->rd_rel->relkind = RELKIND_INDEX;
 }
 
@@ -374,7 +376,7 @@ UpdateRelationRelation(Relation indexRelation, char *temp_relname)
 	/* XXX Natts_pg_class_fixed is a hack - see pg_class.h */
 	tuple = heap_addheader(Natts_pg_class_fixed,
 						   CLASS_TUPLE_SIZE,
-						   (char *) indexRelation->rd_rel);
+						   (void *) indexRelation->rd_rel);
 
 	/*
 	 * the new tuple must have the same oid as the relcache entry for the
@@ -428,23 +430,16 @@ InitializeAttributeOids(Relation indexRelation,
 
 /* ----------------------------------------------------------------
  *		AppendAttributeTuples
- *
- *		XXX For now, only change the ATTNUM attribute value
  * ----------------------------------------------------------------
  */
 static void
 AppendAttributeTuples(Relation indexRelation, int numatts)
 {
 	Relation	pg_attribute;
-	HeapTuple	init_tuple,
-				cur_tuple = NULL,
-				new_tuple;
 	bool		hasind;
 	Relation	idescs[Num_pg_attr_indices];
-	Datum		value[Natts_pg_attribute];
-	char		nullv[Natts_pg_attribute];
-	char		replace[Natts_pg_attribute];
 	TupleDesc	indexTupDesc;
+	HeapTuple	new_tuple;
 	int			i;
 
 	/*
@@ -452,27 +447,6 @@ AppendAttributeTuples(Relation indexRelation, int numatts)
 	 */
 	pg_attribute = heap_openr(AttributeRelationName, RowExclusiveLock);
 
-	/*
-	 * initialize *null, *replace and *value
-	 */
-	MemSet(nullv, ' ', Natts_pg_attribute);
-	MemSet(replace, ' ', Natts_pg_attribute);
-
-	/* ----------
-	 *	create the first attribute tuple.
-	 *	XXX For now, only change the ATTNUM attribute value
-	 * ----------
-	 */
-	replace[Anum_pg_attribute_attnum - 1] = 'r';
-	replace[Anum_pg_attribute_attcacheoff - 1] = 'r';
-
-	value[Anum_pg_attribute_attnum - 1] = Int16GetDatum(1);
-	value[Anum_pg_attribute_attcacheoff - 1] = Int32GetDatum(-1);
-
-	init_tuple = heap_addheader(Natts_pg_attribute,
-								ATTRIBUTE_TUPLE_SIZE,
-							 (char *) (indexRelation->rd_att->attrs[0]));
-
 	hasind = false;
 	if (!IsIgnoringSystemIndexes() && pg_attribute->rd_rel->relhasindex)
 	{
@@ -481,60 +455,35 @@ AppendAttributeTuples(Relation indexRelation, int numatts)
 	}
 
 	/*
-	 * insert the first attribute tuple.
-	 */
-	cur_tuple = heap_modifytuple(init_tuple,
-								 pg_attribute,
-								 value,
-								 nullv,
-								 replace);
-	heap_freetuple(init_tuple);
-
-	heap_insert(pg_attribute, cur_tuple);
-	if (hasind)
-		CatalogIndexInsert(idescs, Num_pg_attr_indices, pg_attribute, cur_tuple);
-
-	/*
-	 * now we use the information in the index cur_tuple descriptor to
-	 * form the remaining attribute tuples.
+	 * insert data from new index's tupdesc into pg_attribute
 	 */
 	indexTupDesc = RelationGetDescr(indexRelation);
 
-	for (i = 1; i < numatts; i += 1)
+	for (i = 0; i < numatts; i++)
 	{
-
 		/*
-		 * process the remaining attributes...
+		 * There used to be very grotty code here to set these fields,
+		 * but I think it's unnecessary.  They should be set already.
 		 */
-		memmove(GETSTRUCT(cur_tuple),
-				(char *) indexTupDesc->attrs[i],
-				ATTRIBUTE_TUPLE_SIZE);
-
-		value[Anum_pg_attribute_attnum - 1] = Int16GetDatum(i + 1);
+		Assert(indexTupDesc->attrs[i]->attnum == i+1);
+		Assert(indexTupDesc->attrs[i]->attcacheoff == -1);
 
-		new_tuple = heap_modifytuple(cur_tuple,
-									 pg_attribute,
-									 value,
-									 nullv,
-									 replace);
-		heap_freetuple(cur_tuple);
+		new_tuple = heap_addheader(Natts_pg_attribute,
+								   ATTRIBUTE_TUPLE_SIZE,
+								   (void *) indexTupDesc->attrs[i]);
 
 		heap_insert(pg_attribute, new_tuple);
+
 		if (hasind)
 			CatalogIndexInsert(idescs, Num_pg_attr_indices, pg_attribute, new_tuple);
 
-		/*
-		 * ModifyHeapTuple returns a new copy of a cur_tuple so we free
-		 * the original and use the copy..
-		 */
-		cur_tuple = new_tuple;
+		heap_freetuple(new_tuple);
 	}
 
-	if (cur_tuple)
-		heap_freetuple(cur_tuple);
-	heap_close(pg_attribute, RowExclusiveLock);
 	if (hasind)
 		CatalogCloseIndices(Num_pg_attr_indices, idescs);
+
+	heap_close(pg_attribute, RowExclusiveLock);
 }
 
 /* ----------------------------------------------------------------
@@ -613,7 +562,7 @@ UpdateIndexRelation(Oid indexoid,
 	 */
 	tuple = heap_addheader(Natts_pg_index,
 						   itupLen,
-						   (char *) indexForm);
+						   (void *) indexForm);
 
 	/*
 	 * insert the tuple into the pg_index
@@ -1994,7 +1943,7 @@ reindex_index(Oid indexId, bool force, bool inplace)
 
 	if (!inplace)
 	{
-		inplace = IsSharedSystemRelationName(NameStr(iRel->rd_rel->relname));
+		inplace = iRel->rd_rel->relisshared;
 		if (!inplace)
 			setNewRelfilenode(iRel);
 	}
@@ -2114,7 +2063,7 @@ reindex_relation(Oid relid, bool force)
 	 * Shared system indexes must be overwritten because it's impossible
 	 * to update pg_class tuples of all databases.
 	 */
-	if (IsSharedSystemRelationName(NameStr(rel->rd_rel->relname)))
+	if (rel->rd_rel->relisshared)
 	{
 		if (IsIgnoringSystemIndexes())
 		{
diff --git a/src/backend/catalog/indexing.c b/src/backend/catalog/indexing.c
index 8261e9dcfcb63f82720bddbe0025b59e2cb17936..a9e6322580092c4a992f7d5163874799cc918064 100644
--- a/src/backend/catalog/indexing.c
+++ b/src/backend/catalog/indexing.c
@@ -9,7 +9,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/catalog/indexing.c,v 1.77 2001/03/22 03:59:20 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/catalog/indexing.c,v 1.78 2001/06/12 05:55:49 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -28,21 +28,25 @@
 #include "utils/syscache.h"
 
 /*
- * Names of indices - they match all system caches
+ * Names of indices for each system catalog.
  */
 
 char	   *Name_pg_aggregate_indices[Num_pg_aggregate_indices] =
 {AggregateNameTypeIndex};
 char	   *Name_pg_am_indices[Num_pg_am_indices] =
-{AmNameIndex};
+{AmNameIndex, AmOidIndex};
 char	   *Name_pg_amop_indices[Num_pg_amop_indices] =
 {AccessMethodOpidIndex, AccessMethodStrategyIndex};
+char	   *Name_pg_amproc_indices[Num_pg_amproc_indices] =
+{AccessProcedureIndex};
 char	   *Name_pg_attr_indices[Num_pg_attr_indices] =
 {AttributeRelidNameIndex, AttributeRelidNumIndex};
 char	   *Name_pg_attrdef_indices[Num_pg_attrdef_indices] =
 {AttrDefaultIndex};
 char	   *Name_pg_class_indices[Num_pg_class_indices] =
 {ClassNameIndex, ClassOidIndex};
+char	   *Name_pg_database_indices[Num_pg_database_indices] =
+{DatabaseNameIndex, DatabaseOidIndex};
 char	   *Name_pg_group_indices[Num_pg_group_indices] =
 {GroupNameIndex, GroupSysidIndex};
 char	   *Name_pg_index_indices[Num_pg_index_indices] =
@@ -53,10 +57,8 @@ char	   *Name_pg_language_indices[Num_pg_language_indices] =
 {LanguageOidIndex, LanguageNameIndex};
 char	   *Name_pg_largeobject_indices[Num_pg_largeobject_indices] =
 {LargeObjectLOidPNIndex};
-char	   *Name_pg_listener_indices[Num_pg_listener_indices] =
-{ListenerPidRelnameIndex};
 char	   *Name_pg_opclass_indices[Num_pg_opclass_indices] =
-{OpclassNameIndex, OpclassDeftypeIndex};
+{OpclassDeftypeIndex, OpclassNameIndex, OpclassOidIndex};
 char	   *Name_pg_operator_indices[Num_pg_operator_indices] =
 {OperatorOidIndex, OperatorNameIndex};
 char	   *Name_pg_proc_indices[Num_pg_proc_indices] =
@@ -64,7 +66,7 @@ char	   *Name_pg_proc_indices[Num_pg_proc_indices] =
 char	   *Name_pg_relcheck_indices[Num_pg_relcheck_indices] =
 {RelCheckIndex};
 char	   *Name_pg_rewrite_indices[Num_pg_rewrite_indices] =
-{RewriteOidIndex, RewriteRulenameIndex};
+{RewriteRulenameIndex};
 char	   *Name_pg_shadow_indices[Num_pg_shadow_indices] =
 {ShadowNameIndex, ShadowSysidIndex};
 char	   *Name_pg_statistic_indices[Num_pg_statistic_indices] =
diff --git a/src/backend/commands/async.c b/src/backend/commands/async.c
index 1eb29dcc99a624b7aed0e7dbf065b631da1e4886..5fda53d02c6c65244fe1eeb4f35eff8335609370 100644
--- a/src/backend/commands/async.c
+++ b/src/backend/commands/async.c
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/commands/async.c,v 1.77 2001/03/22 03:59:21 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/commands/async.c,v 1.78 2001/06/12 05:55:49 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -80,7 +80,6 @@
 
 #include "access/heapam.h"
 #include "catalog/catname.h"
-#include "catalog/indexing.h"
 #include "catalog/pg_listener.h"
 #include "commands/async.h"
 #include "lib/dllist.h"
@@ -195,11 +194,12 @@ void
 Async_Listen(char *relname, int pid)
 {
 	Relation	lRel;
+	HeapScanDesc scan;
 	HeapTuple	tuple;
 	Datum		values[Natts_pg_listener];
 	char		nulls[Natts_pg_listener];
 	int			i;
-	TupleDesc	tupDesc;
+	bool		alreadyListener = false;
 
 	if (Trace_notify)
 		elog(DEBUG, "Async_Listen: %s", relname);
@@ -207,12 +207,23 @@ Async_Listen(char *relname, int pid)
 	lRel = heap_openr(ListenerRelationName, AccessExclusiveLock);
 
 	/* Detect whether we are already listening on this relname */
-	if (SearchSysCacheExists(LISTENREL,
-							 Int32GetDatum(pid),
-							 PointerGetDatum(relname),
-							 0, 0))
+	scan = heap_beginscan(lRel, 0, SnapshotNow, 0, (ScanKey) NULL);
+	while (HeapTupleIsValid(tuple = heap_getnext(scan, 0)))
+	{
+		Form_pg_listener listener = (Form_pg_listener) GETSTRUCT(tuple);
+
+		if (listener->listenerpid == pid &&
+			strncmp(NameStr(listener->relname), relname, NAMEDATALEN) == 0)
+		{
+			alreadyListener = true;
+			/* No need to scan the rest of the table */
+			break;
+		}
+	}
+	heap_endscan(scan);
+
+	if (alreadyListener)
 	{
-		/* No need to scan the rest of the table */
 		heap_close(lRel, AccessExclusiveLock);
 		elog(NOTICE, "Async_Listen: We are already listening on %s", relname);
 		return;
@@ -233,9 +244,10 @@ Async_Listen(char *relname, int pid)
 	values[i++] = (Datum) pid;
 	values[i++] = (Datum) 0;	/* no notifies pending */
 
-	tupDesc = lRel->rd_att;
-	tuple = heap_formtuple(tupDesc, values, nulls);
+	tuple = heap_formtuple(RelationGetDescr(lRel), values, nulls);
 	heap_insert(lRel, tuple);
+
+#ifdef NOT_USED					/* currently there are no indexes */
 	if (RelationGetForm(lRel)->relhasindex)
 	{
 		Relation	idescs[Num_pg_listener_indices];
@@ -244,6 +256,7 @@ Async_Listen(char *relname, int pid)
 		CatalogIndexInsert(idescs, Num_pg_listener_indices, lRel, tuple);
 		CatalogCloseIndices(Num_pg_listener_indices, idescs);
 	}
+#endif
 
 	heap_freetuple(tuple);
 
@@ -280,7 +293,8 @@ void
 Async_Unlisten(char *relname, int pid)
 {
 	Relation	lRel;
-	HeapTuple	lTuple;
+	HeapScanDesc scan;
+	HeapTuple	tuple;
 
 	/* Handle specially the `unlisten "*"' command */
 	if ((!relname) || (*relname == '\0') || (strcmp(relname, "*") == 0))
@@ -293,16 +307,26 @@ Async_Unlisten(char *relname, int pid)
 		elog(DEBUG, "Async_Unlisten %s", relname);
 
 	lRel = heap_openr(ListenerRelationName, AccessExclusiveLock);
-	/* Note we assume there can be only one matching tuple. */
-	lTuple = SearchSysCache(LISTENREL,
-							Int32GetDatum(pid),
-							PointerGetDatum(relname),
-							0, 0);
-	if (HeapTupleIsValid(lTuple))
+
+	scan = heap_beginscan(lRel, 0, SnapshotNow, 0, (ScanKey) NULL);
+	while (HeapTupleIsValid(tuple = heap_getnext(scan, 0)))
 	{
-		simple_heap_delete(lRel, &lTuple->t_self);
-		ReleaseSysCache(lTuple);
+		Form_pg_listener listener = (Form_pg_listener) GETSTRUCT(tuple);
+
+		if (listener->listenerpid == pid &&
+			strncmp(NameStr(listener->relname), relname, NAMEDATALEN) == 0)
+		{
+			/* Found the matching tuple, delete it */
+			simple_heap_delete(lRel, &tuple->t_self);
+			/*
+			 * We assume there can be only one match, so no need
+			 * to scan the rest of the table
+			 */
+			break;
+		}
 	}
+	heap_endscan(scan);
+
 	heap_close(lRel, AccessExclusiveLock);
 
 	/*
@@ -332,7 +356,7 @@ Async_UnlistenAll()
 {
 	Relation	lRel;
 	TupleDesc	tdesc;
-	HeapScanDesc sRel;
+	HeapScanDesc scan;
 	HeapTuple	lTuple;
 	ScanKeyData key[1];
 
@@ -347,12 +371,12 @@ Async_UnlistenAll()
 						   Anum_pg_listener_pid,
 						   F_INT4EQ,
 						   Int32GetDatum(MyProcPid));
-	sRel = heap_beginscan(lRel, 0, SnapshotNow, 1, key);
+	scan = heap_beginscan(lRel, 0, SnapshotNow, 1, key);
 
-	while (HeapTupleIsValid(lTuple = heap_getnext(sRel, 0)))
+	while (HeapTupleIsValid(lTuple = heap_getnext(scan, 0)))
 		simple_heap_delete(lRel, &lTuple->t_self);
 
-	heap_endscan(sRel);
+	heap_endscan(scan);
 	heap_close(lRel, AccessExclusiveLock);
 }
 
@@ -418,16 +442,12 @@ AtCommit_Notify()
 {
 	Relation	lRel;
 	TupleDesc	tdesc;
-	HeapScanDesc sRel;
+	HeapScanDesc scan;
 	HeapTuple	lTuple,
 				rTuple;
-	Datum		d,
-				value[Natts_pg_listener];
+	Datum		value[Natts_pg_listener];
 	char		repl[Natts_pg_listener],
 				nulls[Natts_pg_listener];
-	bool		isnull;
-	char	   *relname;
-	int32		listenerPID;
 
 	if (!pendingNotifies)
 		return;					/* no NOTIFY statements in this
@@ -446,10 +466,6 @@ AtCommit_Notify()
 	if (Trace_notify)
 		elog(DEBUG, "AtCommit_Notify");
 
-	lRel = heap_openr(ListenerRelationName, AccessExclusiveLock);
-	tdesc = RelationGetDescr(lRel);
-	sRel = heap_beginscan(lRel, 0, SnapshotNow, 0, (ScanKey) NULL);
-
 	/* preset data to update notify column to MyProcPid */
 	nulls[0] = nulls[1] = nulls[2] = ' ';
 	repl[0] = repl[1] = repl[2] = ' ';
@@ -457,83 +473,81 @@ AtCommit_Notify()
 	value[0] = value[1] = value[2] = (Datum) 0;
 	value[Anum_pg_listener_notify - 1] = Int32GetDatum(MyProcPid);
 
-	while (HeapTupleIsValid(lTuple = heap_getnext(sRel, 0)))
+	lRel = heap_openr(ListenerRelationName, AccessExclusiveLock);
+	tdesc = RelationGetDescr(lRel);
+	scan = heap_beginscan(lRel, 0, SnapshotNow, 0, (ScanKey) NULL);
+
+	while (HeapTupleIsValid(lTuple = heap_getnext(scan, 0)))
 	{
-		d = heap_getattr(lTuple, Anum_pg_listener_relname, tdesc, &isnull);
-		relname = (char *) DatumGetPointer(d);
+		Form_pg_listener listener = (Form_pg_listener) GETSTRUCT(lTuple);
+		char	   *relname = NameStr(listener->relname);
+		int32		listenerPID = listener->listenerpid;
 
-		if (AsyncExistsPendingNotify(relname))
+		if (! AsyncExistsPendingNotify(relname))
+			continue;
+
+		if (listenerPID == MyProcPid)
 		{
-			d = heap_getattr(lTuple, Anum_pg_listener_pid, tdesc, &isnull);
-			listenerPID = DatumGetInt32(d);
+			/*
+			 * Self-notify: no need to bother with table update.
+			 * Indeed, we *must not* clear the notification field in
+			 * this path, or we could lose an outside notify, which'd
+			 * be bad for applications that ignore self-notify messages.
+			 */
 
-			if (listenerPID == MyProcPid)
-			{
+			if (Trace_notify)
+				elog(DEBUG, "AtCommit_Notify: notifying self");
 
+			NotifyMyFrontEnd(relname, listenerPID);
+		}
+		else
+		{
+			if (Trace_notify)
+				elog(DEBUG, "AtCommit_Notify: notifying pid %d",
+					 listenerPID);
+
+			/*
+			 * If someone has already notified this listener, we don't
+			 * bother modifying the table, but we do still send a
+			 * SIGUSR2 signal, just in case that backend missed the
+			 * earlier signal for some reason.	It's OK to send the
+			 * signal first, because the other guy can't read
+			 * pg_listener until we unlock it.
+			 */
+			if (kill(listenerPID, SIGUSR2) < 0)
+			{
 				/*
-				 * Self-notify: no need to bother with table update.
-				 * Indeed, we *must not* clear the notification field in
-				 * this path, or we could lose an outside notify, which'd
-				 * be bad for applications that ignore self-notify
-				 * messages.
+				 * Get rid of pg_listener entry if it refers to a PID
+				 * that no longer exists.  Presumably, that backend
+				 * crashed without deleting its pg_listener entries.
+				 * This code used to only delete the entry if
+				 * errno==ESRCH, but as far as I can see we should
+				 * just do it for any failure (certainly at least for
+				 * EPERM too...)
 				 */
-
-				if (Trace_notify)
-					elog(DEBUG, "AtCommit_Notify: notifying self");
-
-				NotifyMyFrontEnd(relname, listenerPID);
+				simple_heap_delete(lRel, &lTuple->t_self);
 			}
-			else
+			else if (listener->notification == 0)
 			{
-				if (Trace_notify)
-					elog(DEBUG, "AtCommit_Notify: notifying pid %d", listenerPID);
+				rTuple = heap_modifytuple(lTuple, lRel,
+										  value, nulls, repl);
+				simple_heap_update(lRel, &lTuple->t_self, rTuple);
 
-				/*
-				 * If someone has already notified this listener, we don't
-				 * bother modifying the table, but we do still send a
-				 * SIGUSR2 signal, just in case that backend missed the
-				 * earlier signal for some reason.	It's OK to send the
-				 * signal first, because the other guy can't read
-				 * pg_listener until we unlock it.
-				 */
-				if (kill(listenerPID, SIGUSR2) < 0)
+#ifdef NOT_USED					/* currently there are no indexes */
+				if (RelationGetForm(lRel)->relhasindex)
 				{
+					Relation	idescs[Num_pg_listener_indices];
 
-					/*
-					 * Get rid of pg_listener entry if it refers to a PID
-					 * that no longer exists.  Presumably, that backend
-					 * crashed without deleting its pg_listener entries.
-					 * This code used to only delete the entry if
-					 * errno==ESRCH, but as far as I can see we should
-					 * just do it for any failure (certainly at least for
-					 * EPERM too...)
-					 */
-					simple_heap_delete(lRel, &lTuple->t_self);
-				}
-				else
-				{
-					d = heap_getattr(lTuple, Anum_pg_listener_notify,
-									 tdesc, &isnull);
-					if (DatumGetInt32(d) == 0)
-					{
-						rTuple = heap_modifytuple(lTuple, lRel,
-												  value, nulls, repl);
-						simple_heap_update(lRel, &lTuple->t_self, rTuple);
-						if (RelationGetForm(lRel)->relhasindex)
-						{
-							Relation	idescs[Num_pg_listener_indices];
-
-							CatalogOpenIndices(Num_pg_listener_indices, Name_pg_listener_indices, idescs);
-							CatalogIndexInsert(idescs, Num_pg_listener_indices, lRel, rTuple);
-							CatalogCloseIndices(Num_pg_listener_indices, idescs);
-						}
-					}
+					CatalogOpenIndices(Num_pg_listener_indices, Name_pg_listener_indices, idescs);
+					CatalogIndexInsert(idescs, Num_pg_listener_indices, lRel, rTuple);
+					CatalogCloseIndices(Num_pg_listener_indices, idescs);
 				}
+#endif
 			}
 		}
 	}
 
-	heap_endscan(sRel);
+	heap_endscan(scan);
 
 	/*
 	 * We do NOT release the lock on pg_listener here; we need to hold it
@@ -745,16 +759,12 @@ ProcessIncomingNotify(void)
 	Relation	lRel;
 	TupleDesc	tdesc;
 	ScanKeyData key[1];
-	HeapScanDesc sRel;
+	HeapScanDesc scan;
 	HeapTuple	lTuple,
 				rTuple;
-	Datum		d,
-				value[Natts_pg_listener];
+	Datum		value[Natts_pg_listener];
 	char		repl[Natts_pg_listener],
 				nulls[Natts_pg_listener];
-	bool		isnull;
-	char	   *relname;
-	int32		sourcePID;
 
 	if (Trace_notify)
 		elog(DEBUG, "ProcessIncomingNotify");
@@ -773,7 +783,7 @@ ProcessIncomingNotify(void)
 						   Anum_pg_listener_pid,
 						   F_INT4EQ,
 						   Int32GetDatum(MyProcPid));
-	sRel = heap_beginscan(lRel, 0, SnapshotNow, 1, key);
+	scan = heap_beginscan(lRel, 0, SnapshotNow, 1, key);
 
 	/* Prepare data for rewriting 0 into notification field */
 	nulls[0] = nulls[1] = nulls[2] = ' ';
@@ -782,14 +792,14 @@ ProcessIncomingNotify(void)
 	value[0] = value[1] = value[2] = (Datum) 0;
 	value[Anum_pg_listener_notify - 1] = Int32GetDatum(0);
 
-	while (HeapTupleIsValid(lTuple = heap_getnext(sRel, 0)))
+	while (HeapTupleIsValid(lTuple = heap_getnext(scan, 0)))
 	{
-		d = heap_getattr(lTuple, Anum_pg_listener_notify, tdesc, &isnull);
-		sourcePID = DatumGetInt32(d);
+		Form_pg_listener listener = (Form_pg_listener) GETSTRUCT(lTuple);
+		char	   *relname = NameStr(listener->relname);
+		int32		sourcePID = listener->notification;
+
 		if (sourcePID != 0)
 		{
-			d = heap_getattr(lTuple, Anum_pg_listener_relname, tdesc, &isnull);
-			relname = (char *) DatumGetPointer(d);
 			/* Notify the frontend */
 
 			if (Trace_notify)
@@ -800,6 +810,8 @@ ProcessIncomingNotify(void)
 			/* Rewrite the tuple with 0 in notification column */
 			rTuple = heap_modifytuple(lTuple, lRel, value, nulls, repl);
 			simple_heap_update(lRel, &lTuple->t_self, rTuple);
+
+#ifdef NOT_USED					/* currently there are no indexes */
 			if (RelationGetForm(lRel)->relhasindex)
 			{
 				Relation	idescs[Num_pg_listener_indices];
@@ -808,9 +820,10 @@ ProcessIncomingNotify(void)
 				CatalogIndexInsert(idescs, Num_pg_listener_indices, lRel, rTuple);
 				CatalogCloseIndices(Num_pg_listener_indices, idescs);
 			}
+#endif
 		}
 	}
-	heap_endscan(sRel);
+	heap_endscan(scan);
 
 	/*
 	 * We do NOT release the lock on pg_listener here; we need to hold it
@@ -876,7 +889,7 @@ AsyncExistsPendingNotify(char *relname)
 		 p = DLGetSucc(p))
 	{
 		/* Use NAMEDATALEN for relname comparison.	  DZ - 26-08-1996 */
-		if (!strncmp((const char *) DLE_VAL(p), relname, NAMEDATALEN))
+		if (strncmp((const char *) DLE_VAL(p), relname, NAMEDATALEN) == 0)
 			return 1;
 	}
 
diff --git a/src/backend/commands/command.c b/src/backend/commands/command.c
index e50b9407b7eaafac7b36fa78afe6f5584b8e60dd..2a56a6573a4e117383d1459797d0af940ca8128b 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.132 2001/06/07 00:09:28 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/commands/Attic/command.c,v 1.133 2001/06/12 05:55:49 tgl Exp $
  *
  * NOTES
  *	  The PerformAddAttribute() code, like most of the relation
@@ -411,8 +411,8 @@ AlterTableAddColumn(const char *relationName,
 	attributeD.attrelid = reltup->t_data->t_oid;
 
 	attributeTuple = heap_addheader(Natts_pg_attribute,
-									sizeof attributeD,
-									(char *) &attributeD);
+									ATTRIBUTE_TUPLE_SIZE,
+									(void *) &attributeD);
 
 	attribute = (Form_pg_attribute) GETSTRUCT(attributeTuple);
 
@@ -481,7 +481,7 @@ AlterTableAddColumn(const char *relationName,
 	if (hasindex)
 		CatalogCloseIndices(Num_pg_attr_indices, idescs);
 
-	heap_close(attrdesc, RowExclusiveLock);
+	heap_close(attrdesc, NoLock);
 
 	/*
 	 * Update number of attributes in pg_class tuple
@@ -580,17 +580,15 @@ AlterTableAlterColumnDefault(const char *relationName,
 						   PointerGetDatum(colName),
 						   0, 0);
 	if (!HeapTupleIsValid(tuple))
-	{
-		heap_close(rel, AccessExclusiveLock);
 		elog(ERROR, "ALTER TABLE: relation \"%s\" has no column \"%s\"",
 			 relationName, colName);
-	}
 
 	attnum = ((Form_pg_attribute) GETSTRUCT(tuple))->attnum;
 	ReleaseSysCache(tuple);
 
-	if (newDefault)				/* SET DEFAULT */
+	if (newDefault)
 	{
+		/* SET DEFAULT */
 		List	   *rawDefaults = NIL;
 		RawColumnDefault *rawEnt;
 
@@ -608,15 +606,14 @@ AlterTableAlterColumnDefault(const char *relationName,
 		 */
 		AddRelationRawConstraints(rel, rawDefaults, NIL);
 	}
-
 	else
-/* DROP DEFAULT */
 	{
+		/* DROP DEFAULT */
 		Relation	attr_rel;
 		ScanKeyData scankeys[3];
 		HeapScanDesc scan;
 
-		attr_rel = heap_openr(AttributeRelationName, AccessExclusiveLock);
+		attr_rel = heap_openr(AttributeRelationName, RowExclusiveLock);
 		ScanKeyEntryInitialize(&scankeys[0], 0x0,
 							   Anum_pg_attribute_attrelid, F_OIDEQ,
 							   ObjectIdGetDatum(myrelid));
@@ -665,7 +662,7 @@ drop_default(Oid relid, int16 attnum)
 	Relation	attrdef_rel;
 	HeapTuple	tuple;
 
-	attrdef_rel = heap_openr(AttrDefaultRelationName, AccessExclusiveLock);
+	attrdef_rel = heap_openr(AttrDefaultRelationName, RowExclusiveLock);
 	ScanKeyEntryInitialize(&scankeys[0], 0x0,
 						   Anum_pg_attrdef_adrelid, F_OIDEQ,
 						   ObjectIdGetDatum(relid));
@@ -778,7 +775,7 @@ AlterTableAlterColumnStatistics(const char *relationName,
 	}
 
 	heap_freetuple(tuple);
-	heap_close(attrelation, RowExclusiveLock);
+	heap_close(attrelation, NoLock);
 }
 
 
@@ -1010,8 +1007,7 @@ AlterTableDropColumn(const char *relationName,
 {
 #ifdef	_DROP_COLUMN_HACK__
 	Relation	rel,
-				attrdesc,
-				adrel;
+				attrdesc;
 	Oid			myrelid,
 				attoid;
 	HeapTuple	reltup;
@@ -1023,8 +1019,6 @@ AlterTableDropColumn(const char *relationName,
 	int			attnum;
 	bool		hasindex;
 	char		dropColname[32];
-	void	   *sysscan;
-	ScanKeyData scankeys[2];
 
 	if (inh)
 		elog(ERROR, "ALTER TABLE / DROP COLUMN with inherit option is not supported yet");
@@ -1136,30 +1130,9 @@ AlterTableDropColumn(const char *relationName,
 
 	/* delete comments */
 	DeleteComments(attoid);
-	/* delete attrdef */
-	adrel = heap_openr(AttrDefaultRelationName, RowExclusiveLock);
-	ScanKeyEntryInitialize(&scankeys[0], 0x0, Anum_pg_attrdef_adrelid,
-						   F_OIDEQ, ObjectIdGetDatum(myrelid));
 
-	/*--------
-	 * Oops pg_attrdef doesn't have (adrelid,adnum) index
-	 *
-	 *	ScanKeyEntryInitialize(&scankeys[1], 0x0, Anum_pg_attrdef_adnum,
-	 * 								F_INT2EQ, Int16GetDatum(attnum));
-	 *	sysscan = systable_beginscan(adrel, AttrDefaultIndex, 2, scankeys);
-	 *--------
-	 */
-	sysscan = systable_beginscan(adrel, AttrDefaultIndex, 1, scankeys);
-	while (HeapTupleIsValid(tup = systable_getnext(sysscan)))
-	{
-		if (((Form_pg_attrdef) GETSTRUCT(tup))->adnum == attnum)
-		{
-			simple_heap_delete(adrel, &tup->t_self);
-			break;
-		}
-	}
-	systable_endscan(sysscan);
-	heap_close(adrel, NoLock);
+	/* delete attrdef */
+	drop_default(myrelid, attnum);
 
 	/*
 	 * Remove objects which reference this column
@@ -1318,10 +1291,7 @@ AlterTableAddConstraint(char *relationName,
 							heap_endscan(scan);
 
 							if (!successful)
-							{
-								heap_close(rel, NoLock);
 								elog(ERROR, "AlterTableAddConstraint: rejected due to CHECK constraint %s", name);
-							}
 
 							/*
 							 * Call AddRelationRawConstraints to do the
@@ -1768,7 +1738,7 @@ AlterTableOwner(const char *relationName, const char *newOwnerName)
 	 * unlock everything and return
 	 */
 	heap_freetuple(tuple);
-	heap_close(class_rel, RowExclusiveLock);
+	heap_close(class_rel, NoLock);
 }
 
 
diff --git a/src/backend/commands/dbcommands.c b/src/backend/commands/dbcommands.c
index cd409781b2bd238c1ce726776b2c5e12cffe9c69..424c9665f74fc051282b75ac00a28a328ff935fb 100644
--- a/src/backend/commands/dbcommands.c
+++ b/src/backend/commands/dbcommands.c
@@ -1,6 +1,7 @@
 /*-------------------------------------------------------------------------
  *
  * dbcommands.c
+ *		Database management commands (create/drop database).
  *
  *
  * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
@@ -8,7 +9,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/commands/dbcommands.c,v 1.74 2001/03/22 03:59:22 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/commands/dbcommands.c,v 1.75 2001/06/12 05:55:49 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -25,6 +26,7 @@
 #include "catalog/catalog.h"
 #include "catalog/pg_database.h"
 #include "catalog/pg_shadow.h"
+#include "catalog/indexing.h"
 #include "commands/comment.h"
 #include "commands/dbcommands.h"
 #include "miscadmin.h"
@@ -241,9 +243,8 @@ createdb(const char *dbname, const char *dbpath,
 	heap_insert(pg_database_rel, tuple);
 
 	/*
-	 * Update indexes (there aren't any currently)
+	 * Update indexes
 	 */
-#ifdef Num_pg_database_indices
 	if (RelationGetForm(pg_database_rel)->relhasindex)
 	{
 		Relation	idescs[Num_pg_database_indices];
@@ -254,7 +255,6 @@ createdb(const char *dbname, const char *dbpath,
 						   tuple);
 		CatalogCloseIndices(Num_pg_database_indices, idescs);
 	}
-#endif
 
 	/* Close pg_database, but keep lock till commit */
 	heap_close(pg_database_rel, NoLock);
@@ -333,7 +333,7 @@ dropdb(const char *dbname)
 		elog(ERROR, "DROP DATABASE: database \"%s\" is being accessed by other users", dbname);
 
 	/*
-	 * Find the database's tuple by OID (should be unique, we trust).
+	 * Find the database's tuple by OID (should be unique).
 	 */
 	ScanKeyEntryInitialize(&key, 0, ObjectIdAttributeNumber,
 						   F_OIDEQ, ObjectIdGetDatum(db_id));
@@ -343,7 +343,6 @@ dropdb(const char *dbname)
 	tup = heap_getnext(pgdbscan, 0);
 	if (!HeapTupleIsValid(tup))
 	{
-
 		/*
 		 * This error should never come up since the existence of the
 		 * database is checked earlier
diff --git a/src/backend/commands/user.c b/src/backend/commands/user.c
index cb4290815216abbf7be62a23a2a24c1f76b47d21..74990ce1b92c1c54eeb8481e7253801b9dfacc50 100644
--- a/src/backend/commands/user.c
+++ b/src/backend/commands/user.c
@@ -6,17 +6,17 @@
  * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Header: /cvsroot/pgsql/src/backend/commands/user.c,v 1.75 2001/03/22 06:16:12 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/commands/user.c,v 1.76 2001/06/12 05:55:49 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
+#include "postgres.h"
+
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <fcntl.h>
 #include <unistd.h>
 
-#include "postgres.h"
-
 #include "access/heapam.h"
 #include "catalog/catname.h"
 #include "catalog/pg_database.h"
@@ -31,9 +31,9 @@
 #include "utils/fmgroids.h"
 #include "utils/syscache.h"
 
+
 static void CheckPgUserAclNotNull(void);
 
-#define SQL_LENGTH	512
 
 /*---------------------------------------------------------------------
  * write_password_file / update_pg_pwd
@@ -121,8 +121,7 @@ write_password_file(Relation rel)
 				"%s"
 				CRYPT_PWD_FILE_SEPSTR
 				"%s\n",
-				DatumGetCString(DirectFunctionCall1(nameout,
-								   NameGetDatum(DatumGetName(datum_n)))),
+				DatumGetCString(DirectFunctionCall1(nameout, datum_n)),
 				null_p ? "" :
 				DatumGetCString(DirectFunctionCall1(textout, datum_p)),
 				null_v ? "\\N" :
@@ -168,10 +167,16 @@ write_password_file(Relation rel)
 Datum
 update_pg_pwd(PG_FUNCTION_ARGS)
 {
-	Relation	rel = heap_openr(ShadowRelationName, AccessExclusiveLock);
+	/*
+	 * ExclusiveLock ensures no one modifies pg_shadow while we read it,
+	 * and that only one backend rewrites the flat file at a time.  It's
+	 * OK to allow normal reads of pg_shadow in parallel, however.
+	 */
+	Relation	rel = heap_openr(ShadowRelationName, ExclusiveLock);
 
 	write_password_file(rel);
-	heap_close(rel, AccessExclusiveLock);
+	/* OK to release lock, since we did not modify the relation */
+	heap_close(rel, ExclusiveLock);
 	return PointerGetDatum(NULL);
 }
 
@@ -210,39 +215,41 @@ CreateUser(CreateUserStmt *stmt)
 	 * to be sure of what the next usesysid should be, and we need to
 	 * protect our update of the flat password file.
 	 */
-	pg_shadow_rel = heap_openr(ShadowRelationName, AccessExclusiveLock);
+	pg_shadow_rel = heap_openr(ShadowRelationName, ExclusiveLock);
 	pg_shadow_dsc = RelationGetDescr(pg_shadow_rel);
 
 	scan = heap_beginscan(pg_shadow_rel, false, SnapshotNow, 0, NULL);
-	while (!user_exists && !sysid_exists && HeapTupleIsValid(tuple = heap_getnext(scan, 0)))
+	while (!user_exists && !sysid_exists &&
+		   HeapTupleIsValid(tuple = heap_getnext(scan, 0)))
 	{
 		Datum		datum;
 		bool		null;
 
-		datum = heap_getattr(tuple, Anum_pg_shadow_usename, pg_shadow_dsc, &null);
-		user_exists = datum && !null && (strcmp((char *) datum, stmt->user) == 0);
+		datum = heap_getattr(tuple, Anum_pg_shadow_usename,
+							 pg_shadow_dsc, &null);
+		Assert(!null);
+		user_exists = (strcmp((char *) DatumGetName(datum), stmt->user) == 0);
 
-		datum = heap_getattr(tuple, Anum_pg_shadow_usesysid, pg_shadow_dsc, &null);
+		datum = heap_getattr(tuple, Anum_pg_shadow_usesysid,
+							 pg_shadow_dsc, &null);
+		Assert(!null);
 		if (havesysid)			/* customized id wanted */
-			sysid_exists = datum && !null && ((int) datum == stmt->sysid);
+			sysid_exists = (DatumGetInt32(datum) == stmt->sysid);
 		else
-/* pick 1 + max */
 		{
-			if ((int) datum > max_id)
-				max_id = (int) datum;
+			/* pick 1 + max */
+			if (DatumGetInt32(datum) > max_id)
+				max_id = DatumGetInt32(datum);
 		}
 	}
 	heap_endscan(scan);
 
-	if (user_exists || sysid_exists)
-	{
-		heap_close(pg_shadow_rel, AccessExclusiveLock);
-		if (user_exists)
-			elog(ERROR, "CREATE USER: user name \"%s\" already exists", stmt->user);
-		else
-			elog(ERROR, "CREATE USER: sysid %d is already assigned", stmt->sysid);
-		return;
-	}
+	if (user_exists)
+		elog(ERROR, "CREATE USER: user name \"%s\" already exists",
+			 stmt->user);
+	if (sysid_exists)
+		elog(ERROR, "CREATE USER: sysid %d is already assigned",
+			 stmt->sysid);
 
 	/*
 	 * Build a tuple to insert
@@ -252,12 +259,12 @@ CreateUser(CreateUserStmt *stmt)
 	new_record[Anum_pg_shadow_usesysid - 1] = Int32GetDatum(havesysid ? stmt->sysid : max_id + 1);
 
 	AssertState(BoolIsValid(stmt->createdb));
-	new_record[Anum_pg_shadow_usecreatedb - 1] = (Datum) (stmt->createdb);
-	new_record[Anum_pg_shadow_usetrace - 1] = (Datum) (false);
+	new_record[Anum_pg_shadow_usecreatedb - 1] = BoolGetDatum(stmt->createdb);
+	new_record[Anum_pg_shadow_usetrace - 1] = BoolGetDatum(false);
 	AssertState(BoolIsValid(stmt->createuser));
-	new_record[Anum_pg_shadow_usesuper - 1] = (Datum) (stmt->createuser);
+	new_record[Anum_pg_shadow_usesuper - 1] = BoolGetDatum(stmt->createuser);
 	/* superuser gets catupd right by default */
-	new_record[Anum_pg_shadow_usecatupd - 1] = (Datum) (stmt->createuser);
+	new_record[Anum_pg_shadow_usecatupd - 1] = BoolGetDatum(stmt->createuser);
 
 	if (stmt->password)
 		new_record[Anum_pg_shadow_passwd - 1] =
@@ -278,13 +285,11 @@ CreateUser(CreateUserStmt *stmt)
 	new_record_nulls[Anum_pg_shadow_valuntil - 1] = stmt->validUntil ? ' ' : 'n';
 
 	tuple = heap_formtuple(pg_shadow_dsc, new_record, new_record_nulls);
-	Assert(tuple);
 
 	/*
-	 * Insert a new record in the pg_shadow table
+	 * Insert new record in the pg_shadow table
 	 */
-	if (heap_insert(pg_shadow_rel, tuple) == InvalidOid)
-		elog(ERROR, "CREATE USER: heap_insert failed");
+	heap_insert(pg_shadow_rel, tuple);
 
 	/*
 	 * Update indexes
@@ -322,9 +327,9 @@ CreateUser(CreateUserStmt *stmt)
 	write_password_file(pg_shadow_rel);
 
 	/*
-	 * Now we can clean up.
+	 * Now we can clean up; but keep lock until commit.
 	 */
-	heap_close(pg_shadow_rel, AccessExclusiveLock);
+	heap_close(pg_shadow_rel, NoLock);
 }
 
 
@@ -348,8 +353,11 @@ AlterUser(AlterUserStmt *stmt)
 
 	/* must be superuser or just want to change your own password */
 	if (!superuser() &&
-	  !(stmt->createdb == 0 && stmt->createuser == 0 && !stmt->validUntil
-		&& stmt->password && strcmp(GetUserName(GetUserId()), stmt->user) == 0))
+		!(stmt->createdb == 0 &&
+		  stmt->createuser == 0 &&
+		  !stmt->validUntil &&
+		  stmt->password &&
+		  strcmp(GetUserName(GetUserId()), stmt->user) == 0))
 		elog(ERROR, "ALTER USER: permission denied");
 
 	/* changes to the flat password file cannot be rolled back */
@@ -361,17 +369,14 @@ AlterUser(AlterUserStmt *stmt)
 	 * secure exclusive lock to protect our update of the flat password
 	 * file.
 	 */
-	pg_shadow_rel = heap_openr(ShadowRelationName, AccessExclusiveLock);
+	pg_shadow_rel = heap_openr(ShadowRelationName, ExclusiveLock);
 	pg_shadow_dsc = RelationGetDescr(pg_shadow_rel);
 
 	tuple = SearchSysCache(SHADOWNAME,
 						   PointerGetDatum(stmt->user),
 						   0, 0, 0);
 	if (!HeapTupleIsValid(tuple))
-	{
-		heap_close(pg_shadow_rel, AccessExclusiveLock);
 		elog(ERROR, "ALTER USER: user \"%s\" does not exist", stmt->user);
-	}
 
 	/*
 	 * Build a tuple to update, perusing the information just obtained
@@ -483,8 +488,7 @@ AlterUser(AlterUserStmt *stmt)
 	/*
 	 * Now we can clean up.
 	 */
-	heap_close(pg_shadow_rel, AccessExclusiveLock);
-
+	heap_close(pg_shadow_rel, NoLock);
 }
 
 
@@ -510,7 +514,7 @@ DropUser(DropUserStmt *stmt)
 	 * deleted.  Note we secure exclusive lock, because we need to protect
 	 * our update of the flat password file.
 	 */
-	pg_shadow_rel = heap_openr(ShadowRelationName, AccessExclusiveLock);
+	pg_shadow_rel = heap_openr(ShadowRelationName, ExclusiveLock);
 	pg_shadow_dsc = RelationGetDescr(pg_shadow_rel);
 
 	foreach(item, stmt->users)
@@ -530,11 +534,8 @@ DropUser(DropUserStmt *stmt)
 							   PointerGetDatum(user),
 							   0, 0, 0);
 		if (!HeapTupleIsValid(tuple))
-		{
-			heap_close(pg_shadow_rel, AccessExclusiveLock);
 			elog(ERROR, "DROP USER: user \"%s\" does not exist%s", user,
 				 (length(stmt->users) > 1) ? " (no users removed)" : "");
-		}
 
 		usesysid = DatumGetInt32(heap_getattr(tuple, Anum_pg_shadow_usesysid, pg_shadow_dsc, &null));
 
@@ -546,28 +547,30 @@ DropUser(DropUserStmt *stmt)
 		 * don't read the manual, it doesn't seem to be the behaviour one
 		 * would expect either.) -- petere 2000/01/14)
 		 */
-		pg_rel = heap_openr(DatabaseRelationName, AccessExclusiveLock);
+		pg_rel = heap_openr(DatabaseRelationName, AccessShareLock);
 		pg_dsc = RelationGetDescr(pg_rel);
 
-		ScanKeyEntryInitialize(&scankey, 0x0, Anum_pg_database_datdba, F_INT4EQ,
+		ScanKeyEntryInitialize(&scankey, 0x0,
+							   Anum_pg_database_datdba, F_INT4EQ,
 							   Int32GetDatum(usesysid));
 
 		scan = heap_beginscan(pg_rel, false, SnapshotNow, 1, &scankey);
 
 		if (HeapTupleIsValid(tmp_tuple = heap_getnext(scan, 0)))
 		{
-			datum = heap_getattr(tmp_tuple, Anum_pg_database_datname, pg_dsc, &null);
-			heap_close(pg_shadow_rel, AccessExclusiveLock);
+			char   *dbname;
+
+			datum = heap_getattr(tmp_tuple, Anum_pg_database_datname,
+								 pg_dsc, &null);
+			Assert(!null);
+			dbname = DatumGetCString(DirectFunctionCall1(nameout, datum));
 			elog(ERROR, "DROP USER: user \"%s\" owns database \"%s\", cannot be removed%s",
-				 user,
-				 DatumGetCString(DirectFunctionCall1(nameout,
-									 NameGetDatum(DatumGetName(datum)))),
-				 (length(stmt->users) > 1) ? " (no users removed)" : ""
-				);
+				 user, dbname,
+				 (length(stmt->users) > 1) ? " (no users removed)" : "");
 		}
 
 		heap_endscan(scan);
-		heap_close(pg_rel, AccessExclusiveLock);
+		heap_close(pg_rel, AccessShareLock);
 
 		/*
 		 * Somehow we'd have to check for tables, views, etc. owned by the
@@ -587,7 +590,7 @@ DropUser(DropUserStmt *stmt)
 		 *
 		 * try calling alter group drop user for every group
 		 */
-		pg_rel = heap_openr(GroupRelationName, AccessExclusiveLock);
+		pg_rel = heap_openr(GroupRelationName, ExclusiveLock);
 		pg_dsc = RelationGetDescr(pg_rel);
 		scan = heap_beginscan(pg_rel, false, SnapshotNow, 0, NULL);
 		while (HeapTupleIsValid(tmp_tuple = heap_getnext(scan, 0)))
@@ -602,7 +605,7 @@ DropUser(DropUserStmt *stmt)
 			AlterGroup(&ags, "DROP USER");
 		}
 		heap_endscan(scan);
-		heap_close(pg_rel, AccessExclusiveLock);
+		heap_close(pg_rel, ExclusiveLock);
 
 		/*
 		 * Advance command counter so that later iterations of this loop
@@ -622,7 +625,7 @@ DropUser(DropUserStmt *stmt)
 	/*
 	 * Now we can clean up.
 	 */
-	heap_close(pg_shadow_rel, AccessExclusiveLock);
+	heap_close(pg_shadow_rel, NoLock);
 }
 
 
@@ -681,38 +684,41 @@ CreateGroup(CreateGroupStmt *stmt)
 	if (!superuser())
 		elog(ERROR, "CREATE GROUP: permission denied");
 
-	pg_group_rel = heap_openr(GroupRelationName, AccessExclusiveLock);
+	pg_group_rel = heap_openr(GroupRelationName, ExclusiveLock);
 	pg_group_dsc = RelationGetDescr(pg_group_rel);
 
 	scan = heap_beginscan(pg_group_rel, false, SnapshotNow, 0, NULL);
-	while (!group_exists && !sysid_exists && HeapTupleIsValid(tuple = heap_getnext(scan, false)))
+	while (!group_exists && !sysid_exists &&
+		   HeapTupleIsValid(tuple = heap_getnext(scan, false)))
 	{
 		Datum		datum;
 		bool		null;
 
-		datum = heap_getattr(tuple, Anum_pg_group_groname, pg_group_dsc, &null);
-		group_exists = datum && !null && (strcmp((char *) datum, stmt->name) == 0);
+		datum = heap_getattr(tuple, Anum_pg_group_groname,
+							 pg_group_dsc, &null);
+		Assert(!null);
+		group_exists = (strcmp((char *) DatumGetName(datum), stmt->name) == 0);
 
-		datum = heap_getattr(tuple, Anum_pg_group_grosysid, pg_group_dsc, &null);
+		datum = heap_getattr(tuple, Anum_pg_group_grosysid,
+							 pg_group_dsc, &null);
+		Assert(!null);
 		if (stmt->sysid >= 0)	/* customized id wanted */
-			sysid_exists = datum && !null && ((int) datum == stmt->sysid);
+			sysid_exists = (DatumGetInt32(datum) == stmt->sysid);
 		else
-/* pick 1 + max */
 		{
-			if ((int) datum > max_id)
-				max_id = (int) datum;
+			/* pick 1 + max */
+			if (DatumGetInt32(datum) > max_id)
+				max_id = DatumGetInt32(datum);
 		}
 	}
 	heap_endscan(scan);
 
-	if (group_exists || sysid_exists)
-	{
-		heap_close(pg_group_rel, AccessExclusiveLock);
-		if (group_exists)
-			elog(ERROR, "CREATE GROUP: group name \"%s\" already exists", stmt->name);
-		else
-			elog(ERROR, "CREATE GROUP: group sysid %d is already assigned", stmt->sysid);
-	}
+	if (group_exists)
+		elog(ERROR, "CREATE GROUP: group name \"%s\" already exists",
+			 stmt->name);
+	if (sysid_exists)
+		elog(ERROR, "CREATE GROUP: group sysid %d is already assigned",
+			 stmt->sysid);
 
 	/*
 	 * Translate the given user names to ids
@@ -790,7 +796,7 @@ CreateGroup(CreateGroupStmt *stmt)
 		CatalogCloseIndices(Num_pg_group_indices, idescs);
 	}
 
-	heap_close(pg_group_rel, AccessExclusiveLock);
+	heap_close(pg_group_rel, NoLock);
 }
 
 
@@ -811,7 +817,7 @@ AlterGroup(AlterGroupStmt *stmt, const char *tag)
 	if (!superuser())
 		elog(ERROR, "%s: permission denied", tag);
 
-	pg_group_rel = heap_openr(GroupRelationName, AccessExclusiveLock);
+	pg_group_rel = heap_openr(GroupRelationName, ExclusiveLock);
 	pg_group_dsc = RelationGetDescr(pg_group_rel);
 
 	/*
@@ -1052,7 +1058,7 @@ AlterGroup(AlterGroupStmt *stmt, const char *tag)
 
 	ReleaseSysCache(group_tuple);
 
-	heap_close(pg_group_rel, AccessExclusiveLock);
+	heap_close(pg_group_rel, NoLock);
 }
 
 
@@ -1078,7 +1084,7 @@ DropGroup(DropGroupStmt *stmt)
 	/*
 	 * Scan the pg_group table and delete all matching groups.
 	 */
-	pg_group_rel = heap_openr(GroupRelationName, AccessExclusiveLock);
+	pg_group_rel = heap_openr(GroupRelationName, ExclusiveLock);
 	pg_group_dsc = RelationGetDescr(pg_group_rel);
 	scan = heap_beginscan(pg_group_rel, false, SnapshotNow, 0, NULL);
 
@@ -1087,8 +1093,9 @@ DropGroup(DropGroupStmt *stmt)
 		Datum		datum;
 		bool		null;
 
-		datum = heap_getattr(tuple, Anum_pg_group_groname, pg_group_dsc, &null);
-		if (datum && !null && strcmp((char *) datum, stmt->name) == 0)
+		datum = heap_getattr(tuple, Anum_pg_group_groname,
+							 pg_group_dsc, &null);
+		if (!null && strcmp((char *) DatumGetName(datum), stmt->name) == 0)
 		{
 			gro_exists = true;
 			simple_heap_delete(pg_group_rel, &tuple->t_self);
@@ -1101,10 +1108,7 @@ DropGroup(DropGroupStmt *stmt)
 	 * Did we find any?
 	 */
 	if (!gro_exists)
-	{
-		heap_close(pg_group_rel, AccessExclusiveLock);
 		elog(ERROR, "DROP GROUP: group \"%s\" does not exist", stmt->name);
-	}
 
-	heap_close(pg_group_rel, AccessExclusiveLock);
+	heap_close(pg_group_rel, NoLock);
 }
diff --git a/src/backend/storage/lmgr/lmgr.c b/src/backend/storage/lmgr/lmgr.c
index c06f76bfcdba3f6cb0fab4191a53b9d3c393ff65..515b92c57022055cbc5b5db5299313f2f6950a81 100644
--- a/src/backend/storage/lmgr/lmgr.c
+++ b/src/backend/storage/lmgr/lmgr.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/storage/lmgr/lmgr.c,v 1.45 2001/03/22 03:59:46 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/storage/lmgr/lmgr.c,v 1.46 2001/06/12 05:55:49 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -107,16 +107,12 @@ InitLockTable(int maxBackends)
 void
 RelationInitLockInfo(Relation relation)
 {
-	char	   *relname;
-
 	Assert(RelationIsValid(relation));
 	Assert(OidIsValid(RelationGetRelid(relation)));
 
-	relname = (char *) RelationGetPhysicalRelationName(relation);
-
 	relation->rd_lockInfo.lockRelId.relId = RelationGetRelid(relation);
 
-	if (IsSharedSystemRelationName(relname))
+	if (relation->rd_rel->relisshared)
 		relation->rd_lockInfo.lockRelId.dbId = InvalidOid;
 	else
 		relation->rd_lockInfo.lockRelId.dbId = MyDatabaseId;
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index 6431bd9382e7bd6480e0af733dd0dde57fc97838..4c8c3c4398cf218518178c1b3b732d98902829ad 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/utils/cache/relcache.c,v 1.136 2001/06/01 02:41:36 tgl Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/utils/cache/relcache.c,v 1.137 2001/06/12 05:55:49 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -1116,7 +1116,7 @@ RelationBuildDesc(RelationBuildDescInfo buildinfo,
 	 */
 	RelationInitLockInfo(relation);		/* see lmgr.c */
 
-	if (IsSharedSystemRelationName(NameStr(relation->rd_rel->relname)))
+	if (relation->rd_rel->relisshared)
 		relation->rd_node.tblNode = InvalidOid;
 	else
 		relation->rd_node.tblNode = MyDatabaseId;
@@ -1201,7 +1201,6 @@ IndexedAccessMethodInitialize(Relation relation)
  *		catalogs...
  *
  * NOTE: we assume we are already switched into CacheMemoryContext.
- *
  */
 static void
 formrdesc(char *relationName,
@@ -1245,15 +1244,10 @@ formrdesc(char *relationName,
 	strcpy(RelationGetPhysicalRelationName(relation), relationName);
 
 	/*
-	 * For debugging purposes, it's important to distinguish between
-	 * shared and non-shared relations, even at bootstrap time.  There's
-	 * code in the buffer manager that traces allocations that has to know
-	 * about this.
+	 * It's important to distinguish between shared and non-shared relations,
+	 * even at bootstrap time, to make sure we know where they are stored.
 	 */
-	if (IsSystemRelationName(relationName))
-		relation->rd_rel->relisshared = IsSharedSystemRelationName(relationName);
-	else
-		relation->rd_rel->relisshared = false;
+	relation->rd_rel->relisshared = IsSharedSystemRelationName(relationName);
 
 	relation->rd_rel->relpages = 1;
 	relation->rd_rel->reltuples = 1;
@@ -1286,7 +1280,7 @@ formrdesc(char *relationName,
 	 */
 	RelationInitLockInfo(relation);		/* see lmgr.c */
 
-	if (IsSharedSystemRelationName(relationName))
+	if (relation->rd_rel->relisshared)
 		relation->rd_node.tblNode = InvalidOid;
 	else
 		relation->rd_node.tblNode = MyDatabaseId;
@@ -1301,14 +1295,15 @@ formrdesc(char *relationName,
 	/* In bootstrap mode, we have no indexes */
 	if (!IsBootstrapProcessingMode())
 	{
-		for (i = 0; IndexedCatalogNames[i] != NULL; i++)
-		{
-			if (strcmp(IndexedCatalogNames[i], relationName) == 0)
-			{
-				relation->rd_rel->relhasindex = true;
-				break;
-			}
-		}
+		/*
+		 * This list is incomplete, but it only has to work for the
+		 * set of rels that formrdesc is used for ...
+		 */
+		if (strcmp(relationName, RelationRelationName) == 0 ||
+			strcmp(relationName, AttributeRelationName) == 0 ||
+			strcmp(relationName, ProcedureRelationName) == 0 ||
+			strcmp(relationName, TypeRelationName) == 0)
+			relation->rd_rel->relhasindex = true;
 	}
 
 	/*
@@ -1323,7 +1318,6 @@ formrdesc(char *relationName,
  *
  *		Update the phony data inserted by formrdesc() with real info
  *		from pg_class.
- *
  */
 static void
 fixrdesc(char *relationName)
diff --git a/src/backend/utils/cache/syscache.c b/src/backend/utils/cache/syscache.c
index 4e35b3fb35ba67aa78d337e6bdb39149c6256f8c..222650fcbea5b45098293202aaa6ff6c91cdd7f4 100644
--- a/src/backend/utils/cache/syscache.c
+++ b/src/backend/utils/cache/syscache.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/utils/cache/syscache.c,v 1.61 2001/05/07 00:43:24 tgl Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/utils/cache/syscache.c,v 1.62 2001/06/12 05:55:49 tgl Exp $
  *
  * NOTES
  *	  These routines allow the parser/planner/executor to perform
@@ -31,7 +31,6 @@
 #include "catalog/pg_index.h"
 #include "catalog/pg_inherits.h"
 #include "catalog/pg_language.h"
-#include "catalog/pg_listener.h"
 #include "catalog/pg_opclass.h"
 #include "catalog/pg_operator.h"
 #include "catalog/pg_proc.h"
@@ -214,15 +213,6 @@ static struct cachedesc cacheinfo[] = {
 			0,
 			0
 	}},
-	{ListenerRelationName,		/* LISTENREL */
-		ListenerPidRelnameIndex,
-		2,
-		{
-			Anum_pg_listener_pid,
-			Anum_pg_listener_relname,
-			0,
-			0
-	}},
 	{OperatorRelationName,		/* OPERNAME */
 		OperatorNameIndex,
 		4,
@@ -277,7 +267,7 @@ static struct cachedesc cacheinfo[] = {
 			0,
 			0
 	}},
-	{RewriteRelationName,		/* REWRITENAME */
+	{RewriteRelationName,		/* RULENAME */
 		RewriteRulenameIndex,
 		1,
 		{
@@ -286,15 +276,6 @@ static struct cachedesc cacheinfo[] = {
 			0,
 			0
 	}},
-	{RewriteRelationName,		/* RULEOID */
-		RewriteOidIndex,
-		1,
-		{
-			ObjectIdAttributeNumber,
-			0,
-			0,
-			0
-	}},
 	{ShadowRelationName,		/* SHADOWNAME */
 		ShadowNameIndex,
 		1,
diff --git a/src/backend/utils/init/globals.c b/src/backend/utils/init/globals.c
index 3efb52fcb9a3360b78a92ba76ac798ca04b7a260..7dff67bffbc46e6fdf5b12f5e2719574a93b9518 100644
--- a/src/backend/utils/init/globals.c
+++ b/src/backend/utils/init/globals.c
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/utils/init/globals.c,v 1.57 2001/05/14 20:30:21 momjian Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/utils/init/globals.c,v 1.58 2001/06/12 05:55:50 tgl Exp $
  *
  * NOTES
  *	  Globals used all over the place should be declared here and not
@@ -30,6 +30,7 @@
 #include "miscadmin.h"
 #include "storage/backendid.h"
 
+
 ProtocolVersion FrontendProtocol = PG_PROTOCOL_LATEST;
 
 bool		Noversion = false;
@@ -84,36 +85,26 @@ int			SortMem = 512;
 int			NBuffers = DEF_NBUFFERS;
 
 
-char	   *IndexedCatalogNames[] = {
-	AttributeRelationName,
-	ProcedureRelationName,
-	TypeRelationName,
-	RelationRelationName,
-	0
-};
-
-
 /* ----------------
- * we just do a linear search now so there's no requirement that the list
+ * List of relations that are shared across all databases in an installation.
+ *
+ * This used to be binary-searched, requiring that it be kept in sorted order.
+ * We just do a linear search now so there's no requirement that the list
  * be ordered.	The list is so small it shouldn't make much difference.
  * make sure the list is null-terminated
  *				- jolly 8/19/95
- *
- * OLD COMMENT
- *		WARNING  WARNING  WARNING  WARNING	WARNING  WARNING
- *
- *		keep SharedSystemRelationNames[] in SORTED order!  A binary search
- *		is done on it in catalog.c!
- *
- *		XXX this is a serious hack which should be fixed -cim 1/26/90
  * ----------------
  */
 char	   *SharedSystemRelationNames[] = {
 	DatabaseRelationName,
+	DatabaseNameIndex,
+	DatabaseOidIndex,
 	GroupRelationName,
 	GroupNameIndex,
 	GroupSysidIndex,
 	LogRelationName,
 	ShadowRelationName,
-	0
+	ShadowNameIndex,
+	ShadowSysidIndex,
+	NULL
 };
diff --git a/src/bin/initdb/initdb.sh b/src/bin/initdb/initdb.sh
index de81152e24d93b354135208634fd51e6800c2952..c14f185cd286aa328bf66c401d90fcbeb017304a 100644
--- a/src/bin/initdb/initdb.sh
+++ b/src/bin/initdb/initdb.sh
@@ -15,15 +15,19 @@
 # changed to add site-local standard data.  Either one can be copied
 # to produce a new database.
 #
-# To create template1, we run the postgres (backend) program and
-# feed it data from the bki files that were installed.  template0 is
-# made just by copying the completed template1.
+# To create template1, we run the postgres (backend) program in bootstrap
+# mode and feed it data from the postgres.bki library file.  After this
+# initial bootstrap phase, some additional stuff is created by normal
+# SQL commands fed to a standalone backend.  Those commands are just
+# embedded into this script (yeah, it's ugly).
+#
+# template0 is made just by copying the completed template1.
 #
 #
 # Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
 # Portions Copyright (c) 1994, Regents of the University of California
 #
-# $Header: /cvsroot/pgsql/src/bin/initdb/Attic/initdb.sh,v 1.125 2001/05/12 01:48:49 petere Exp $
+# $Header: /cvsroot/pgsql/src/bin/initdb/Attic/initdb.sh,v 1.126 2001/06/12 05:55:50 tgl Exp $
 #
 #-------------------------------------------------------------------------
 
@@ -338,11 +342,8 @@ fi
 # Find the input files
 #-------------------------------------------------------------------------
 
-TEMPLATE1_BKI="$datadir"/template1.bki
-GLOBAL_BKI="$datadir"/global.bki
-
-TEMPLATE1_DESCR="$datadir"/template1.description
-GLOBAL_DESCR="$datadir"/global.description
+POSTGRES_BKI="$datadir"/postgres.bki
+POSTGRES_DESCR="$datadir"/postgres.description
 
 PG_HBA_SAMPLE="$datadir"/pg_hba.conf.sample
 PG_IDENT_SAMPLE="$datadir"/pg_ident.conf.sample
@@ -353,8 +354,8 @@ then
     echo
     echo "Initdb variables:"
     for var in PGDATA datadir PGPATH TEMPFILE MULTIBYTE MULTIBYTEID \
-        POSTGRES_SUPERUSERNAME POSTGRES_SUPERUSERID TEMPLATE1_BKI GLOBAL_BKI \
-        TEMPLATE1_DESCR GLOBAL_DESCR POSTGRESQL_CONF_SAMPLE \
+        POSTGRES_SUPERUSERNAME POSTGRES_SUPERUSERID POSTGRES_BKI \
+        POSTGRES_DESCR POSTGRESQL_CONF_SAMPLE \
 	PG_HBA_SAMPLE PG_IDENT_SAMPLE ; do
         eval "echo '  '$var=\$$var"
     done
@@ -364,8 +365,8 @@ if [ "$show_setting" = yes ] ; then
     exit 0
 fi
 
-for PREREQ_FILE in "$TEMPLATE1_BKI" "$GLOBAL_BKI" "$PG_HBA_SAMPLE" \
-    "$PG_IDENT_SAMPLE"
+for PREREQ_FILE in "$POSTGRES_BKI" "$POSTGRES_DESCR" \
+    "$PG_HBA_SAMPLE" "$PG_IDENT_SAMPLE" "$POSTGRESQL_CONF_SAMPLE"
 do
     if [ ! -f "$PREREQ_FILE" ] ; then
       (
@@ -377,7 +378,8 @@ do
     fi
 done
 
-for file in "$TEMPLATE1_BKI" "$GLOBAL_BKI"; do
+for file in "$POSTGRES_BKI"
+do
      if [ x"`sed 1q $file`" != x"# PostgreSQL $short_version" ]; then
        (
          echo "The input file '$file' needed by $CMDNAME does not"
@@ -445,7 +447,7 @@ fi
 
 ##########################################################################
 #
-# CREATE TEMPLATE1 DATABASE
+# RUN BKI SCRIPT IN BOOTSTRAP MODE TO CREATE TEMPLATE1
 
 rm -rf "$PGDATA"/base/1 || exit_nicely
 mkdir "$PGDATA"/base/1 || exit_nicely
@@ -455,35 +457,23 @@ then
     BACKEND_TALK_ARG="-d"
 fi
 
-BACKENDARGS="-boot -F -D$PGDATA $BACKEND_TALK_ARG"
 FIRSTRUN="-boot -x1 -F -D$PGDATA $BACKEND_TALK_ARG"
 
 echo "Creating template1 database in $PGDATA/base/1"
 [ "$debug" = yes ] && echo "Running: $PGPATH/postgres $FIRSTRUN template1"
 
-cat "$TEMPLATE1_BKI" \
-| sed -e "s/PGUID/$POSTGRES_SUPERUSERID/g" \
+cat "$POSTGRES_BKI" \
+| sed -e "s/POSTGRES/$POSTGRES_SUPERUSERNAME/g" \
+      -e "s/PGUID/$POSTGRES_SUPERUSERID/g" \
+      -e "s/ENCODING/$MULTIBYTEID/g" \
 | "$PGPATH"/postgres $FIRSTRUN template1 \
 || exit_nicely
 
 echo $short_version > "$PGDATA"/base/1/PG_VERSION || exit_nicely
 
-
 ##########################################################################
 #
-# CREATE GLOBAL TABLES
-#
-
-echo "Creating global relations in $PGDATA/global"
-
-[ "$debug" = yes ] && echo "Running: $PGPATH/postgres $BACKENDARGS template1"
-
-cat "$GLOBAL_BKI" \
-| sed -e "s/POSTGRES/$POSTGRES_SUPERUSERNAME/g" \
-      -e "s/PGUID/$POSTGRES_SUPERUSERID/g" \
-      -e "s/ENCODING/$MULTIBYTEID/g" \
-| "$PGPATH"/postgres $BACKENDARGS template1 \
-|| exit_nicely
+# CREATE CONFIG FILES
 
 echo $short_version > "$PGDATA/PG_VERSION" || exit_nicely
 
@@ -493,7 +483,6 @@ cp "$POSTGRESQL_CONF_SAMPLE" "$PGDATA"/postgresql.conf || exit_nicely
 chmod 0600 "$PGDATA"/pg_hba.conf "$PGDATA"/pg_ident.conf \
 	"$PGDATA"/postgresql.conf
 
-
 ##########################################################################
 #
 # CREATE VIEWS and other things
@@ -614,8 +603,7 @@ echo "CREATE VIEW pg_indexes AS \
 
 echo "Loading pg_description."
 echo "COPY pg_description FROM STDIN" > $TEMPFILE
-cat "$TEMPLATE1_DESCR" >> $TEMPFILE
-cat "$GLOBAL_DESCR" >> $TEMPFILE
+cat "$POSTGRES_DESCR" >> $TEMPFILE
 
 cat $TEMPFILE \
 	| "$PGPATH"/postgres $PGSQL_OPT template1 > /dev/null || exit_nicely
diff --git a/src/include/access/heapam.h b/src/include/access/heapam.h
index 4c499151b3e3e62fc1767db20972a12fb814d9bb..9e2d1d427b74dacb5b2ca1cc5710d01bc2ab99e2 100644
--- a/src/include/access/heapam.h
+++ b/src/include/access/heapam.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: heapam.h,v 1.63 2001/03/22 04:00:27 momjian Exp $
+ * $Id: heapam.h,v 1.64 2001/06/12 05:55:50 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -234,7 +234,7 @@ extern HeapTuple heap_formtuple(TupleDesc tupleDescriptor,
 extern HeapTuple heap_modifytuple(HeapTuple tuple,
 		Relation relation, Datum *replValue, char *replNull, char *repl);
 extern void heap_freetuple(HeapTuple tuple);
-HeapTuple	heap_addheader(uint32 natts, int structlen, char *structure);
+extern HeapTuple heap_addheader(int natts, Size structlen, void *structure);
 
 /* in common/heap/stats.c */
 extern void PrintHeapAccessStatistics(HeapAccessStatistics stats);
diff --git a/src/include/catalog/catversion.h b/src/include/catalog/catversion.h
index c38f27c955e1090218cfc196588927d18ff489d1..6fcd0f1c1ccbecbef2a5e076111e54a52b92b984 100644
--- a/src/include/catalog/catversion.h
+++ b/src/include/catalog/catversion.h
@@ -37,7 +37,7 @@
  * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: catversion.h,v 1.81 2001/05/22 16:37:16 petere Exp $
+ * $Id: catversion.h,v 1.82 2001/06/12 05:55:50 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -53,6 +53,6 @@
  */
 
 /*							yyyymmddN */
-#define CATALOG_VERSION_NO	200105221
+#define CATALOG_VERSION_NO	200106111
 
 #endif
diff --git a/src/include/catalog/indexing.h b/src/include/catalog/indexing.h
index cc155cf1bbb314f4cb54a41c23a3a2ed5e1fd5d8..496ba4eaa3cc7471be0b2e48b19653ab9478666a 100644
--- a/src/include/catalog/indexing.h
+++ b/src/include/catalog/indexing.h
@@ -8,7 +8,7 @@
  * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: indexing.h,v 1.49 2001/05/07 00:43:24 tgl Exp $
+ * $Id: indexing.h,v 1.50 2001/06/12 05:55:50 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -21,23 +21,24 @@
  * Number of indices that exist for each system catalog
  */
 #define Num_pg_aggregate_indices	1
-#define Num_pg_am_indices			1
+#define Num_pg_am_indices			2
 #define Num_pg_amop_indices			2
+#define Num_pg_amproc_indices		1
 #define Num_pg_attr_indices			2
 #define Num_pg_attrdef_indices		1
 #define Num_pg_class_indices		2
+#define Num_pg_database_indices		2
 #define Num_pg_description_indices	1
 #define Num_pg_group_indices		2
 #define Num_pg_index_indices		2
 #define Num_pg_inherits_indices		1
 #define Num_pg_language_indices		2
 #define Num_pg_largeobject_indices	1
-#define Num_pg_listener_indices		1
-#define Num_pg_opclass_indices		2
+#define Num_pg_opclass_indices		3
 #define Num_pg_operator_indices		2
 #define Num_pg_proc_indices			2
 #define Num_pg_relcheck_indices		1
-#define Num_pg_rewrite_indices		2
+#define Num_pg_rewrite_indices		1
 #define Num_pg_shadow_indices		2
 #define Num_pg_statistic_indices	1
 #define Num_pg_trigger_indices		3
@@ -48,13 +49,17 @@
  */
 #define AccessMethodOpidIndex		"pg_amop_opid_index"
 #define AccessMethodStrategyIndex	"pg_amop_strategy_index"
+#define AccessProcedureIndex		"pg_amproc_am_opcl_procnum_index"
 #define AggregateNameTypeIndex		"pg_aggregate_name_type_index"
 #define AmNameIndex					"pg_am_name_index"
-#define AttrDefaultIndex			"pg_attrdef_adrelid_index"
+#define AmOidIndex					"pg_am_oid_index"
+#define AttrDefaultIndex			"pg_attrdef_adrelid_adnum_index"
 #define AttributeRelidNameIndex		"pg_attribute_relid_attnam_index"
 #define AttributeRelidNumIndex		"pg_attribute_relid_attnum_index"
 #define ClassNameIndex				"pg_class_relname_index"
 #define ClassOidIndex				"pg_class_oid_index"
+#define DatabaseNameIndex			"pg_database_datname_index"
+#define DatabaseOidIndex			"pg_database_oid_index"
 #define DescriptionObjIndex			"pg_description_objoid_index"
 #define GroupNameIndex				"pg_group_name_index"
 #define GroupSysidIndex				"pg_group_sysid_index"
@@ -64,18 +69,17 @@
 #define LanguageNameIndex			"pg_language_name_index"
 #define LanguageOidIndex			"pg_language_oid_index"
 #define LargeObjectLOidPNIndex		"pg_largeobject_loid_pn_index"
-#define ListenerPidRelnameIndex		"pg_listener_pid_relname_index"
 #define OpclassDeftypeIndex			"pg_opclass_deftype_index"
 #define OpclassNameIndex			"pg_opclass_name_index"
+#define OpclassOidIndex				"pg_opclass_oid_index"
 #define OperatorNameIndex			"pg_operator_oprname_l_r_k_index"
 #define OperatorOidIndex			"pg_operator_oid_index"
 #define ProcedureNameIndex			"pg_proc_proname_narg_type_index"
 #define ProcedureOidIndex			"pg_proc_oid_index"
 #define RelCheckIndex				"pg_relcheck_rcrelid_index"
-#define RewriteOidIndex				"pg_rewrite_oid_index"
 #define RewriteRulenameIndex		"pg_rewrite_rulename_index"
-#define ShadowNameIndex				"pg_shadow_name_index"
-#define ShadowSysidIndex			"pg_shadow_sysid_index"
+#define ShadowNameIndex				"pg_shadow_usename_index"
+#define ShadowSysidIndex			"pg_shadow_usesysid_index"
 #define StatisticRelidAttnumIndex	"pg_statistic_relid_att_index"
 #define TriggerConstrNameIndex		"pg_trigger_tgconstrname_index"
 #define TriggerConstrRelidIndex		"pg_trigger_tgconstrrelid_index"
@@ -83,19 +87,21 @@
 #define TypeNameIndex				"pg_type_typname_index"
 #define TypeOidIndex				"pg_type_oid_index"
 
+/* Arrays of names of indices for each system catalog */
 extern char *Name_pg_aggregate_indices[];
 extern char *Name_pg_am_indices[];
 extern char *Name_pg_amop_indices[];
+extern char *Name_pg_amproc_indices[];
 extern char *Name_pg_attr_indices[];
 extern char *Name_pg_attrdef_indices[];
 extern char *Name_pg_class_indices[];
+extern char *Name_pg_database_indices[];
 extern char *Name_pg_description_indices[];
 extern char *Name_pg_group_indices[];
 extern char *Name_pg_index_indices[];
 extern char *Name_pg_inherits_indices[];
 extern char *Name_pg_language_indices[];
 extern char *Name_pg_largeobject_indices[];
-extern char *Name_pg_listener_indices[];
 extern char *Name_pg_opclass_indices[];
 extern char *Name_pg_operator_indices[];
 extern char *Name_pg_proc_indices[];
@@ -107,8 +113,6 @@ extern char *Name_pg_trigger_indices[];
 extern char *Name_pg_type_indices[];
 
 
-extern char *IndexedCatalogNames[];
-
 /*
  * indexing.c prototypes
  */
@@ -127,24 +131,36 @@ extern HeapTuple ClassNameIndexScan(Relation heapRelation, Datum relName);
 extern HeapTuple ClassOidIndexScan(Relation heapRelation, Datum relId);
 
 
+/*
+ * These macros are just to keep the C compiler from spitting up on the
+ * upcoming commands for genbki.sh.
+ */
+#define DECLARE_INDEX(x) extern int errno
+#define DECLARE_UNIQUE_INDEX(x) extern int errno
+#define BUILD_INDICES
+
+
 /*
  * What follows are lines processed by genbki.sh to create the statements
  * the bootstrap parser will turn into DefineIndex commands.
  *
- * The keyword is DECLARE_INDEX every thing after that is just like in a
- * normal specification of the 'define index' POSTQUEL command.
+ * The keyword is DECLARE_INDEX or DECLARE_UNIQUE_INDEX.  Everything after
+ * that is just like in a normal 'create index' SQL command.
  */
 
 DECLARE_UNIQUE_INDEX(pg_aggregate_name_type_index on pg_aggregate using btree(aggname name_ops, aggbasetype oid_ops));
 DECLARE_UNIQUE_INDEX(pg_am_name_index on pg_am using btree(amname name_ops));
+DECLARE_UNIQUE_INDEX(pg_am_oid_index on pg_am using btree(oid oid_ops));
 DECLARE_UNIQUE_INDEX(pg_amop_opid_index on pg_amop using btree(amopclaid oid_ops, amopopr oid_ops, amopid oid_ops));
 DECLARE_UNIQUE_INDEX(pg_amop_strategy_index on pg_amop using btree(amopid oid_ops, amopclaid oid_ops, amopstrategy int2_ops));
-/* This following index is not used for a cache and is not unique */
-DECLARE_INDEX(pg_attrdef_adrelid_index on pg_attrdef using btree(adrelid oid_ops));
+DECLARE_UNIQUE_INDEX(pg_amproc_am_opcl_procnum_index on pg_amproc using btree(amid oid_ops, amopclaid oid_ops, amprocnum int2_ops));
+DECLARE_UNIQUE_INDEX(pg_attrdef_adrelid_adnum_index on pg_attrdef using btree(adrelid oid_ops, adnum int2_ops));
 DECLARE_UNIQUE_INDEX(pg_attribute_relid_attnam_index on pg_attribute using btree(attrelid oid_ops, attname name_ops));
 DECLARE_UNIQUE_INDEX(pg_attribute_relid_attnum_index on pg_attribute using btree(attrelid oid_ops, attnum int2_ops));
 DECLARE_UNIQUE_INDEX(pg_class_oid_index on pg_class using btree(oid oid_ops));
 DECLARE_UNIQUE_INDEX(pg_class_relname_index on pg_class using btree(relname name_ops));
+DECLARE_UNIQUE_INDEX(pg_database_datname_index on pg_database using btree(datname name_ops));
+DECLARE_UNIQUE_INDEX(pg_database_oid_index on pg_database using btree(oid oid_ops));
 DECLARE_UNIQUE_INDEX(pg_description_objoid_index on pg_description using btree(objoid oid_ops));
 DECLARE_UNIQUE_INDEX(pg_group_name_index on pg_group using btree(groname name_ops));
 DECLARE_UNIQUE_INDEX(pg_group_sysid_index on pg_group using btree(grosysid int4_ops));
@@ -155,22 +171,19 @@ DECLARE_UNIQUE_INDEX(pg_inherits_relid_seqno_index on pg_inherits using btree(in
 DECLARE_UNIQUE_INDEX(pg_language_name_index on pg_language using btree(lanname name_ops));
 DECLARE_UNIQUE_INDEX(pg_language_oid_index on pg_language using btree(oid oid_ops));
 DECLARE_UNIQUE_INDEX(pg_largeobject_loid_pn_index on pg_largeobject using btree(loid oid_ops, pageno int4_ops));
-DECLARE_UNIQUE_INDEX(pg_listener_pid_relname_index on pg_listener using btree(listenerpid int4_ops, relname name_ops));
 /* This column needs to allow multiple zero entries, but is in the cache */
 DECLARE_INDEX(pg_opclass_deftype_index on pg_opclass using btree(opcdeftype oid_ops));
 DECLARE_UNIQUE_INDEX(pg_opclass_name_index on pg_opclass using btree(opcname name_ops));
+DECLARE_UNIQUE_INDEX(pg_opclass_oid_index on pg_opclass using btree(oid oid_ops));
 DECLARE_UNIQUE_INDEX(pg_operator_oid_index on pg_operator using btree(oid oid_ops));
 DECLARE_UNIQUE_INDEX(pg_operator_oprname_l_r_k_index on pg_operator using btree(oprname name_ops, oprleft oid_ops, oprright oid_ops, oprkind char_ops));
 DECLARE_UNIQUE_INDEX(pg_proc_oid_index on pg_proc using btree(oid oid_ops));
 DECLARE_UNIQUE_INDEX(pg_proc_proname_narg_type_index on pg_proc using btree(proname name_ops, pronargs int2_ops, proargtypes oidvector_ops));
 /* This following index is not used for a cache and is not unique */
 DECLARE_INDEX(pg_relcheck_rcrelid_index on pg_relcheck using btree(rcrelid oid_ops));
-DECLARE_UNIQUE_INDEX(pg_rewrite_oid_index on pg_rewrite using btree(oid oid_ops));
 DECLARE_UNIQUE_INDEX(pg_rewrite_rulename_index on pg_rewrite using btree(rulename name_ops));
-/*
-xDECLARE_UNIQUE_INDEX(pg_shadow_name_index on pg_shadow using btree(usename name_ops));
-xDECLARE_UNIQUE_INDEX(pg_shadow_sysid_index on pg_shadow using btree(usesysid int4_ops));
-*/
+DECLARE_UNIQUE_INDEX(pg_shadow_usename_index on pg_shadow using btree(usename name_ops));
+DECLARE_UNIQUE_INDEX(pg_shadow_usesysid_index on pg_shadow using btree(usesysid int4_ops));
 DECLARE_UNIQUE_INDEX(pg_statistic_relid_att_index on pg_statistic using btree(starelid oid_ops, staattnum int2_ops));
 DECLARE_INDEX(pg_trigger_tgconstrname_index on pg_trigger using btree(tgconstrname name_ops));
 DECLARE_INDEX(pg_trigger_tgconstrrelid_index on pg_trigger using btree(tgconstrrelid oid_ops));
@@ -178,7 +191,7 @@ DECLARE_INDEX(pg_trigger_tgrelid_index on pg_trigger using btree(tgrelid oid_ops
 DECLARE_UNIQUE_INDEX(pg_type_oid_index on pg_type using btree(oid oid_ops));
 DECLARE_UNIQUE_INDEX(pg_type_typname_index on pg_type using btree(typname name_ops));
 
-/* now build indices in the initialization scripts */
+/* last step of initialization script: build the indices declared above */
 BUILD_INDICES
 
 #endif	 /* INDEXING_H */
diff --git a/src/include/catalog/pg_attrdef.h b/src/include/catalog/pg_attrdef.h
index 35c9c2c07b434912fd744ea14fe3a6c3e3f6a4d0..713776375c6bc4010df3f5653e62b2af53b7f247 100644
--- a/src/include/catalog/pg_attrdef.h
+++ b/src/include/catalog/pg_attrdef.h
@@ -27,7 +27,7 @@
  *		typedef struct FormData_pg_attrdef
  * ----------------
  */
-CATALOG(pg_attrdef) BOOTSTRAP
+CATALOG(pg_attrdef)
 {
 	Oid			adrelid;
 	int2		adnum;
diff --git a/src/include/catalog/pg_attribute.h b/src/include/catalog/pg_attribute.h
index c74dc33f74dd7137bd87ac19902bf619619ce2f0..95bd2569f4661a671f60dcabf1b6acb6cf99425a 100644
--- a/src/include/catalog/pg_attribute.h
+++ b/src/include/catalog/pg_attribute.h
@@ -8,7 +8,7 @@
  * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: pg_attribute.h,v 1.72 2001/05/14 21:58:10 momjian Exp $
+ * $Id: pg_attribute.h,v 1.73 2001/06/12 05:55:50 tgl Exp $
  *
  * NOTES
  *	  the genbki.sh script reads this file and generates .bki
@@ -213,6 +213,8 @@ typedef FormData_pg_attribute *Form_pg_attribute;
 
 /* ----------------
  *		initial contents of pg_attribute
+ *
+ * NOTE: only "bootstrapped" relations need to be declared here.
  * ----------------
  */
 
@@ -469,64 +471,6 @@ DATA(insert OID = 0 ( 1259 xmax				28 0  4  -5 0 -1 -1 t p f i f f));
 DATA(insert OID = 0 ( 1259 cmax				29 0  4  -6 0 -1 -1 t p f i f f));
 DATA(insert OID = 0 ( 1259 tableoid			26 0  4  -7 0 -1 -1 t p f i f f));
 
-/* ----------------
- *		pg_attrdef
- * ----------------
- */
-DATA(insert OID = 0 ( 1215 adrelid			26 0  4   1 0 -1 -1 t p f i f f));
-DATA(insert OID = 0 ( 1215 adnum			21 0  2   2 0 -1 -1 t p f s f f));
-DATA(insert OID = 0 ( 1215 adbin			25 0 -1   3 0 -1 -1 f x f i f f));
-DATA(insert OID = 0 ( 1215 adsrc			25 0 -1   4 0 -1 -1 f x f i f f));
-DATA(insert OID = 0 ( 1215 ctid				27 0  6  -1 0 -1 -1 f p f i f f));
-DATA(insert OID = 0 ( 1215 oid				26 0  4  -2 0 -1 -1 t p f i f f));
-DATA(insert OID = 0 ( 1215 xmin				28 0  4  -3 0 -1 -1 t p f i f f));
-DATA(insert OID = 0 ( 1215 cmin				29 0  4  -4 0 -1 -1 t p f i f f));
-DATA(insert OID = 0 ( 1215 xmax				28 0  4  -5 0 -1 -1 t p f i f f));
-DATA(insert OID = 0 ( 1215 cmax				29 0  4  -6 0 -1 -1 t p f i f f));
-DATA(insert OID = 0 ( 1215 tableoid			26 0  4  -7 0 -1 -1 t p f i f f));
-
-/* ----------------
- *		pg_relcheck
- * ----------------
- */
-DATA(insert OID = 0 ( 1216 rcrelid			26 0  4   1 0 -1 -1 t p f i f f));
-DATA(insert OID = 0 ( 1216 rcname			19 0  NAMEDATALEN  2 0 -1 -1 f p f i f f));
-DATA(insert OID = 0 ( 1216 rcbin			25 0 -1   3 0 -1 -1 f x f i f f));
-DATA(insert OID = 0 ( 1216 rcsrc			25 0 -1   4 0 -1 -1 f x f i f f));
-DATA(insert OID = 0 ( 1216 ctid				27 0  6  -1 0 -1 -1 f p f i f f));
-DATA(insert OID = 0 ( 1216 oid				26 0  4  -2 0 -1 -1 t p f i f f));
-DATA(insert OID = 0 ( 1216 xmin				28 0  4  -3 0 -1 -1 t p f i f f));
-DATA(insert OID = 0 ( 1216 cmin				29 0  4  -4 0 -1 -1 t p f i f f));
-DATA(insert OID = 0 ( 1216 xmax				28 0  4  -5 0 -1 -1 t p f i f f));
-DATA(insert OID = 0 ( 1216 cmax				29 0  4  -6 0 -1 -1 t p f i f f));
-DATA(insert OID = 0 ( 1216 tableoid			26 0  4  -7 0 -1 -1 t p f i f f));
-
-/* ----------------
- *		pg_trigger
- * ----------------
- */
-DATA(insert OID = 0 ( 1219 tgrelid			26 0  4   1 0 -1 -1 t p f i f f));
-DATA(insert OID = 0 ( 1219 tgname			19 0  NAMEDATALEN  2 0 -1 -1 f p f i f f));
-DATA(insert OID = 0 ( 1219 tgfoid			26 0  4   3 0 -1 -1 t p f i f f));
-DATA(insert OID = 0 ( 1219 tgtype			21 0  2   4 0 -1 -1 t p f s f f));
-DATA(insert OID = 0 ( 1219 tgenabled		16 0  1   5 0 -1 -1 t p f c f f));
-DATA(insert OID = 0 ( 1219 tgisconstraint	16 0  1   6 0 -1 -1 t p f c f f));
-DATA(insert OID = 0 ( 1219 tgconstrname		19 0  NAMEDATALEN  7 0 -1 -1 f p f i f f));
-DATA(insert OID = 0 ( 1219 tgconstrrelid	26 0  4   8 0 -1 -1 t p f i f f));
-
-DATA(insert OID = 0 ( 1219 tgdeferrable		16 0  1   9 0 -1 -1 t p f c f f));
-DATA(insert OID = 0 ( 1219 tginitdeferred	16 0  1   10 0 -1 -1 t p f c f f));
-DATA(insert OID = 0 ( 1219 tgnargs			21 0  2   11 0 -1 -1 t p f s f f));
-DATA(insert OID = 0 ( 1219 tgattr			22 0  INDEX_MAX_KEYS*2	12 0 -1 -1 f p f i f f));
-DATA(insert OID = 0 ( 1219 tgargs			17 0 -1   13 0 -1 -1 f x f i f f));
-DATA(insert OID = 0 ( 1219 ctid				27 0  6  -1 0 -1 -1 f p f i f f));
-DATA(insert OID = 0 ( 1219 oid				26 0  4  -2 0 -1 -1 t p f i f f));
-DATA(insert OID = 0 ( 1219 xmin				28 0  4  -3 0 -1 -1 t p f i f f));
-DATA(insert OID = 0 ( 1219 cmin				29 0  4  -4 0 -1 -1 t p f i f f));
-DATA(insert OID = 0 ( 1219 xmax				28 0  4  -5 0 -1 -1 t p f i f f));
-DATA(insert OID = 0 ( 1219 cmax				29 0  4  -6 0 -1 -1 t p f i f f));
-DATA(insert OID = 0 ( 1219 tableoid			26 0  4  -7 0 -1 -1 t p f i f f));
-
 /* ----------------
  *		pg_log - this relation is modified by special purpose access
  *				  method code.	The following is garbage but is needed
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index 0ff37a5093e5f89e29f882fa7241ca4aa8450eaa..f908c4a9cc26ec65055ded0e6e77edacd0910b2f 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -8,7 +8,7 @@
  * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: pg_class.h,v 1.50 2001/05/30 14:40:13 momjian Exp $
+ * $Id: pg_class.h,v 1.51 2001/06/12 05:55:50 tgl Exp $
  *
  * NOTES
  *	  the genbki.sh script reads this file and generates .bki
@@ -29,10 +29,6 @@
 /* ----------------
  *		pg_class definition.  cpp turns this into
  *		typedef struct FormData_pg_class
- *
- *		Note: the #if 0, #endif around the BKI_BEGIN.. END block
- *			  below keeps cpp from seeing what is meant for the
- *			  genbki script
  * ----------------
  */
 
@@ -59,7 +55,6 @@ CATALOG(pg_class) BOOTSTRAP
 	bool		relisshared;
 	char		relkind;
 	int2		relnatts;
-
 	/*
 	 * relnatts is the number of user attributes this class has.  There
 	 * must be exactly this many instances in Class pg_attribute for this
@@ -73,7 +68,6 @@ CATALOG(pg_class) BOOTSTRAP
 	bool		relhaspkey;		/* has PRIMARY KEY (not used) */
 	bool		relhasrules;	/* has associated rules */
 	bool		relhassubclass; /* has derived classes */
-
 	/*
 	 * relacl may or may not be present, see note above!
 	 */
@@ -129,6 +123,8 @@ typedef FormData_pg_class *Form_pg_class;
 
 /* ----------------
  *		initial contents of pg_class
+ *
+ * NOTE: only "bootstrapped" relations need to be declared here.
  * ----------------
  */
 
@@ -150,12 +146,6 @@ DATA(insert OID = 1269 (  pg_log  99		  PGUID 0 1269 0 0 0 0 f t s 1	0 0 0 0 0 f
 DESCR("");
 DATA(insert OID = 376  (  pg_xactlock  0	  PGUID 0	 0 0 0 0 0 f t s 1	0 0 0 0 0 f f f _null_ ));
 DESCR("");
-DATA(insert OID = 1215 (  pg_attrdef 109	  PGUID 0 1215 0 0 0 0 t t r 4	0 0 0 0 0 f f f _null_ ));
-DESCR("");
-DATA(insert OID = 1216 (  pg_relcheck 110	  PGUID 0 1216 0 0 0 0 t t r 4	0 0 0 0 0 f f f _null_ ));
-DESCR("");
-DATA(insert OID = 1219 (  pg_trigger 111	  PGUID 0 1219 0 0 0 0 t t r 13  0 0 0 0 0 f f f _null_ ));
-DESCR("");
 
 #define RelOid_pg_type			1247
 #define RelOid_pg_attribute		1249
@@ -165,9 +155,6 @@ DESCR("");
 #define RelOid_pg_group			1261
 #define RelOid_pg_database		1262
 #define RelOid_pg_log			1269
-#define RelOid_pg_attrdef		1215
-#define RelOid_pg_relcheck		1216
-#define RelOid_pg_trigger		1219
 
 /* Xact lock pseudo-table */
 #define XactLockTableId			376
diff --git a/src/include/catalog/pg_listener.h b/src/include/catalog/pg_listener.h
index c5eddbad34ded4339dda5f8e371326398f833020..47b77bfab2e65de1d293c986ddc45b70add143f2 100644
--- a/src/include/catalog/pg_listener.h
+++ b/src/include/catalog/pg_listener.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: pg_listener.h,v 1.8 2001/01/24 19:43:21 momjian Exp $
+ * $Id: pg_listener.h,v 1.9 2001/06/12 05:55:50 tgl Exp $
  *
  * NOTES
  *	  the genbki.sh script reads this file and generates .bki
@@ -39,6 +39,13 @@ CATALOG(pg_listener)
 	int4		notification;
 } FormData_pg_listener;
 
+/* ----------------
+ *		Form_pg_listener corresponds to a pointer to a tuple with
+ *		the format of pg_listener relation.
+ * ----------------
+ */
+typedef FormData_pg_listener *Form_pg_listener;
+
 /* ----------------
  *		compiler constants for pg_listener
  * ----------------
diff --git a/src/include/catalog/pg_relcheck.h b/src/include/catalog/pg_relcheck.h
index cfe072f32fd4faca1d69e3132486348ac134ecf9..7c7cd11447577cfe8ed44a159614d0ffd3de5f59 100644
--- a/src/include/catalog/pg_relcheck.h
+++ b/src/include/catalog/pg_relcheck.h
@@ -27,7 +27,7 @@
  *		typedef struct FormData_pg_relcheck
  * ----------------
  */
-CATALOG(pg_relcheck) BOOTSTRAP
+CATALOG(pg_relcheck)
 {
 	Oid			rcrelid;
 	NameData	rcname;
diff --git a/src/include/catalog/pg_trigger.h b/src/include/catalog/pg_trigger.h
index 1df6f3b95345b4ed05d6e6d4e3bdbd55f80f1714..220c32f1198f9a6535a53e8d86fe1cc44db51897 100644
--- a/src/include/catalog/pg_trigger.h
+++ b/src/include/catalog/pg_trigger.h
@@ -27,7 +27,7 @@
  *		typedef struct FormData_pg_trigger
  * ----------------
  */
-CATALOG(pg_trigger) BOOTSTRAP
+CATALOG(pg_trigger)
 {
 	Oid			tgrelid;		/* triggered relation */
 	NameData	tgname;			/* trigger' name */
diff --git a/src/include/catalog/pg_type.h b/src/include/catalog/pg_type.h
index 4e877a159cee4ce8c5358f6bb9b55bdabd8e2ad4..ffad5a7fe05452d5d0f9cdc2fa48f5b0bc275941 100644
--- a/src/include/catalog/pg_type.h
+++ b/src/include/catalog/pg_type.h
@@ -8,7 +8,7 @@
  * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: pg_type.h,v 1.108 2001/06/09 21:41:42 tgl Exp $
+ * $Id: pg_type.h,v 1.109 2001/06/12 05:55:50 tgl Exp $
  *
  * NOTES
  *	  the genbki.sh script reads this file and generates .bki
@@ -243,10 +243,6 @@ DATA(insert OID = 99 (	pg_log		 PGUID 4 4 t c t \054 1269 0 int4in int4out int4i
 
 /* OIDS 100 - 199 */
 
-DATA(insert OID = 109 (  pg_attrdef  PGUID 4 4 t c t \054 1215 0 int4in int4out int4in int4out i p _null_));
-DATA(insert OID = 110 (  pg_relcheck PGUID 4 4 t c t \054 1216 0 int4in int4out int4in int4out i p _null_));
-DATA(insert OID = 111 (  pg_trigger  PGUID 4 4 t c t \054 1219 0 int4in int4out int4in int4out i p _null_));
-
 /* OIDS 200 - 299 */
 
 DATA(insert OID = 210 (  smgr	   PGUID 2	12 t b t \054 0 0 smgrin smgrout smgrin smgrout s p _null_ ));
diff --git a/src/include/postgres.h b/src/include/postgres.h
index 7af72a791e9fab2b5289127ad2ad94223ee2b554..e4e959d70fca195cf9b95c66261bb1e4b9d73366 100644
--- a/src/include/postgres.h
+++ b/src/include/postgres.h
@@ -10,7 +10,7 @@
  * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
  * Portions Copyright (c) 1995, Regents of the University of California
  *
- * $Id: postgres.h,v 1.48 2001/03/23 18:26:01 tgl Exp $
+ * $Id: postgres.h,v 1.49 2001/06/12 05:55:50 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -569,18 +569,14 @@ extern int	assertTest(int val);
  *				Section 4: genbki macros used by catalog/pg_xxx.h files
  * ----------------------------------------------------------------
  */
-#define CATALOG(x) \
-	typedef struct CppConcat(FormData_,x)
+#define CATALOG(x)  typedef struct CppConcat(FormData_,x)
 
-/* Huh? */
-#define DATA(x) extern int errno
-#define DESCR(x) extern int errno
-#define DECLARE_INDEX(x) extern int errno
-#define DECLARE_UNIQUE_INDEX(x) extern int errno
-
-#define BUILD_INDICES
 #define BOOTSTRAP
 
+/* these need to expand into some harmless, repeatable declaration */
+#define DATA(x)   extern int errno
+#define DESCR(x)  extern int errno
+
 #define BKI_BEGIN
 #define BKI_END
 
diff --git a/src/include/utils/syscache.h b/src/include/utils/syscache.h
index 342f7bf8a566b73e4f8393553ccb332ed067ed06..c98bee3f30fa00c0823647c2128ce40677ea91b3 100644
--- a/src/include/utils/syscache.h
+++ b/src/include/utils/syscache.h
@@ -9,7 +9,7 @@
  * Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Id: syscache.h,v 1.30 2001/05/07 00:43:26 tgl Exp $
+ * $Id: syscache.h,v 1.31 2001/06/12 05:55:50 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -42,20 +42,18 @@
 #define INHRELID		11
 #define LANGNAME		12
 #define LANGOID			13
-#define LISTENREL		14
-#define OPERNAME		15
-#define OPEROID			16
-#define PROCNAME		17
-#define PROCOID			18
-#define RELNAME			19
-#define RELOID			20
-#define RULENAME		21
-#define RULEOID			22
-#define SHADOWNAME		23
-#define SHADOWSYSID		24
-#define STATRELATT		25
-#define TYPENAME		26
-#define TYPEOID			27
+#define OPERNAME		14
+#define OPEROID			15
+#define PROCNAME		16
+#define PROCOID			17
+#define RELNAME			18
+#define RELOID			19
+#define RULENAME		20
+#define SHADOWNAME		21
+#define SHADOWSYSID		22
+#define STATRELATT		23
+#define TYPENAME		24
+#define TYPEOID			25
 
 extern void InitCatalogCache(void);
 
diff --git a/src/test/regress/expected/opr_sanity.out b/src/test/regress/expected/opr_sanity.out
index cc71f44d1d798d084838ddb1004fc4255a898d26..41328c53b1d26f0348b3261b51cc065994af30be 100644
--- a/src/test/regress/expected/opr_sanity.out
+++ b/src/test/regress/expected/opr_sanity.out
@@ -480,8 +480,8 @@ WHERE p1.aggtransfn = p2.oid AND
           (p2.pronargs = 1 AND p1.aggbasetype = 0)));
   oid  | aggname | oid |   proname   
 -------+---------+-----+-------------
- 17009 | max     | 768 | int4larger
- 17023 | min     | 769 | int4smaller
+ 16963 | max     | 768 | int4larger
+ 16977 | min     | 769 | int4smaller
 (2 rows)
 
 -- Cross-check finalfn (if present) against its entry in pg_proc.
diff --git a/src/test/regress/expected/sanity_check.out b/src/test/regress/expected/sanity_check.out
index f2412386d176bfb5b99971396772a9ccf6d64bbc..5f5911c09c632f1739587cea276eb46b77dc6b67 100644
--- a/src/test/regress/expected/sanity_check.out
+++ b/src/test/regress/expected/sanity_check.out
@@ -32,21 +32,23 @@ SELECT relname, relhasindex
  pg_aggregate        | t
  pg_am               | t
  pg_amop             | t
+ pg_amproc           | t
  pg_attrdef          | t
  pg_attribute        | t
  pg_class            | t
+ pg_database         | t
  pg_description      | t
  pg_group            | t
  pg_index            | t
  pg_inherits         | t
  pg_language         | t
  pg_largeobject      | t
- pg_listener         | t
  pg_opclass          | t
  pg_operator         | t
  pg_proc             | t
  pg_relcheck         | t
  pg_rewrite          | t
+ pg_shadow           | t
  pg_statistic        | t
  pg_trigger          | t
  pg_type             | t
@@ -55,5 +57,5 @@ SELECT relname, relhasindex
  shighway            | t
  tenk1               | t
  tenk2               | t
-(45 rows)
+(47 rows)