OSDN Git Service

Adjust rules for search_path so that pg_catalog is never implicitly
authorTom Lane <tgl@sss.pgh.pa.us>
Mon, 15 Apr 2002 22:33:21 +0000 (22:33 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Mon, 15 Apr 2002 22:33:21 +0000 (22:33 +0000)
selected as the creation target namespace; to make that happen, you
must explicitly set search_path that way.  This makes initdb a hair
more complex but seems like a good safety feature.

doc/src/sgml/runtime.sgml
src/backend/catalog/namespace.c
src/bin/initdb/initdb.sh

index 2b0a4ad..babb95a 100644 (file)
@@ -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>
index 84bd95e..77b6ceb 100644 (file)
@@ -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 $
  *
  *-------------------------------------------------------------------------
  */
  * 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);
 }
index 30f7de1..03fa12a 100644 (file)
@@ -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