diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml
index 2b0a4ad634905afb1c4a6650e4e7124775a19e0b..babb95a4cd98084f82d1d8305f3852f49f55dfb5 100644
--- a/doc/src/sgml/runtime.sgml
+++ b/doc/src/sgml/runtime.sgml
@@ -1,5 +1,5 @@
 <!--
-$Header: /cvsroot/pgsql/doc/src/sgml/runtime.sgml,v 1.112 2002/04/03 05:39:29 petere Exp $
+$Header: /cvsroot/pgsql/doc/src/sgml/runtime.sgml,v 1.113 2002/04/15 22:33:20 tgl Exp $
 -->
 
 <Chapter Id="runtime">
@@ -1231,10 +1231,8 @@ dynamic_library_path = '/usr/local/lib/postgresql:/home/my_project/lib:$libdir'
        <para>
         When objects are created without specifying a particular target
 	namespace, they will be placed in the first namespace listed
-	in the search path, or in <literal>pg_catalog</> if the search
-	path list is empty.  (Note that users do not normally have
-	permission to write in <literal>pg_catalog</>, so an empty search
-	path is not a very useful setting.)
+	in the search path.  An error is reported if the search path is
+	empty.
        </para>
 
        <para>
diff --git a/src/backend/catalog/namespace.c b/src/backend/catalog/namespace.c
index 84bd95e466290d2e79b35df4f0dbdeb1340f8800..77b6ceb78dbd4b7d9ecd601f73797c858c7d52f1 100644
--- a/src/backend/catalog/namespace.c
+++ b/src/backend/catalog/namespace.c
@@ -13,7 +13,7 @@
  * Portions Copyright (c) 1994, Regents of the University of California
  *
  * IDENTIFICATION
- *	  $Header: /cvsroot/pgsql/src/backend/catalog/namespace.c,v 1.8 2002/04/12 20:38:19 tgl Exp $
+ *	  $Header: /cvsroot/pgsql/src/backend/catalog/namespace.c,v 1.9 2002/04/15 22:33:21 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -54,12 +54,15 @@
  * thereby making it the default creation target namespace.)
  *
  * The default creation target namespace is kept equal to the first element
- * of the explicit list, or is the system namespace if the list is empty.
+ * of the (explicit) list.  If the list is empty, there is no default target.
  *
- * In bootstrap mode or a standalone backend, the default search path is
- * empty, so that the system namespace is the only one searched or inserted
- * into.  In multiuser mode, the default search path contains the PG_PUBLIC
- * namespace, preceded by the user's own namespace if one exists.
+ * In bootstrap mode, the search path is set equal to 'pg_catalog', so that
+ * the system namespace is the only one searched or inserted into.
+ * The initdb script is also careful to set search_path to 'pg_catalog' for
+ * its post-bootstrap standalone backend runs.  Otherwise the default search
+ * path is determined by GUC.  The factory default path contains the PUBLIC
+ * namespace (if it exists), preceded by the user's personal namespace
+ * (if one exists).
  */
 
 static List *namespaceSearchPath = NIL;
@@ -67,8 +70,8 @@ static List *namespaceSearchPath = NIL;
 /* this flag must be updated correctly when namespaceSearchPath is changed */
 static bool pathContainsSystemNamespace = false;
 
-/* default place to create stuff */
-static Oid	defaultCreationNamespace = PG_CATALOG_NAMESPACE;
+/* default place to create stuff; if InvalidOid, no default */
+static Oid	defaultCreationNamespace = InvalidOid;
 
 /*
  * myTempNamespace is InvalidOid until and unless a TEMP namespace is set up
@@ -205,6 +208,8 @@ RangeVarGetCreationNamespace(const RangeVar *newRelation)
 	{
 		/* use the default creation namespace */
 		namespaceId = defaultCreationNamespace;
+		if (!OidIsValid(namespaceId))
+			elog(ERROR, "No namespace has been selected to create in");
 	}
 
 	return namespaceId;
@@ -529,6 +534,8 @@ QualifiedNameGetCreationNamespace(List *names, char **objname_p)
 	{
 		/* use the default creation namespace */
 		namespaceId = defaultCreationNamespace;
+		if (!OidIsValid(namespaceId))
+			elog(ERROR, "No namespace has been selected to create in");
 	}
 
 	*objname_p = objname;
@@ -1063,7 +1070,7 @@ assign_search_path(const char *newval)
 											namespaceSearchPath);
 
 	if (namespaceSearchPath == NIL)
-		defaultCreationNamespace = PG_CATALOG_NAMESPACE;
+		defaultCreationNamespace = InvalidOid;
 	else
 		defaultCreationNamespace = (Oid) lfirsti(namespaceSearchPath);
 
@@ -1081,26 +1088,28 @@ assign_search_path(const char *newval)
 void
 InitializeSearchPath(void)
 {
-	/*
-	 * In normal multi-user mode, we want the default search path to be
-	 * '$user,public' (or as much of that as exists, anyway; see the
-	 * error handling in assign_search_path); which is what guc.c has as
-	 * the wired-in default value.  But in bootstrap or standalone-backend
-	 * mode, the default search path must be empty so that initdb correctly
-	 * creates everything in PG_CATALOG_NAMESPACE.  Accordingly, adjust the
-	 * default setting if we are not running under postmaster.  (If a
-	 * non-default setting has been supplied, this will not overwrite it.)
-	 */
-	if (!IsUnderPostmaster)
+	if (IsBootstrapProcessingMode())
+	{
+		/*
+		 * In bootstrap mode, the search path must be 'pg_catalog' so that
+		 * tables are created in the proper namespace; ignore the GUC setting.
+		 */
+		MemoryContext oldcxt;
+
+		oldcxt = MemoryContextSwitchTo(TopMemoryContext);
+		namespaceSearchPath = makeListi1(PG_CATALOG_NAMESPACE);
+		MemoryContextSwitchTo(oldcxt);
+		pathContainsSystemNamespace = true;
+		defaultCreationNamespace = PG_CATALOG_NAMESPACE;
+	}
+	else
 	{
-		SetConfigOption("search_path", "",
-						PGC_POSTMASTER, PGC_S_DEFAULT);
+		/*
+		 * If a search path setting was provided before we were able to
+		 * execute lookups, establish the internal search path now.
+		 */
+		if (namespace_search_path && *namespace_search_path &&
+			namespaceSearchPath == NIL)
+			assign_search_path(namespace_search_path);
 	}
-	/*
-	 * If a search path setting was provided before we were able to execute
-	 * lookups, establish the internal search path now.
-	 */
-	if (namespace_search_path && *namespace_search_path &&
-		namespaceSearchPath == NIL)
-		assign_search_path(namespace_search_path);
 }
diff --git a/src/bin/initdb/initdb.sh b/src/bin/initdb/initdb.sh
index 30f7de1f201668d7a30986023961b8209fb0d447..03fa12a8462c7e9d91900f6e89471e7f0e2ee53e 100644
--- a/src/bin/initdb/initdb.sh
+++ b/src/bin/initdb/initdb.sh
@@ -27,7 +27,7 @@
 # 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.147 2002/04/04 04:25:50 momjian Exp $
+# $Header: /cvsroot/pgsql/src/bin/initdb/Attic/initdb.sh,v 1.148 2002/04/15 22:33:21 tgl Exp $
 #
 #-------------------------------------------------------------------------
 
@@ -597,7 +597,7 @@ echo "ok"
 # To break an SQL command across lines in this script, backslash-escape all
 # internal newlines in the command.
 
-PGSQL_OPT="$PGSQL_OPT -O"
+PGSQL_OPT="$PGSQL_OPT -O --search_path=pg_catalog"
 
 $ECHO_N "initializing pg_shadow... "$ECHO_C