Adjust rules for search_path so that pg_catalog is never implicitly

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.
This commit is contained in:
Tom Lane 2002-04-15 22:33:21 +00:00
parent c2f1e93aeb
commit b66cbc1fa2
3 changed files with 43 additions and 36 deletions

View 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"> <Chapter Id="runtime">
@ -1231,10 +1231,8 @@ dynamic_library_path = '/usr/local/lib/postgresql:/home/my_project/lib:$libdir'
<para> <para>
When objects are created without specifying a particular target When objects are created without specifying a particular target
namespace, they will be placed in the first namespace listed namespace, they will be placed in the first namespace listed
in the search path, or in <literal>pg_catalog</> if the search in the search path. An error is reported if the search path is
path list is empty. (Note that users do not normally have empty.
permission to write in <literal>pg_catalog</>, so an empty search
path is not a very useful setting.)
</para> </para>
<para> <para>

View File

@ -13,7 +13,7 @@
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* IDENTIFICATION * 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.) * thereby making it the default creation target namespace.)
* *
* The default creation target namespace is kept equal to the first element * 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 * In bootstrap mode, the search path is set equal to 'pg_catalog', so that
* empty, so that the system namespace is the only one searched or inserted * the system namespace is the only one searched or inserted into.
* into. In multiuser mode, the default search path contains the PG_PUBLIC * The initdb script is also careful to set search_path to 'pg_catalog' for
* namespace, preceded by the user's own namespace if one exists. * 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; static List *namespaceSearchPath = NIL;
@ -67,8 +70,8 @@ static List *namespaceSearchPath = NIL;
/* this flag must be updated correctly when namespaceSearchPath is changed */ /* this flag must be updated correctly when namespaceSearchPath is changed */
static bool pathContainsSystemNamespace = false; static bool pathContainsSystemNamespace = false;
/* default place to create stuff */ /* default place to create stuff; if InvalidOid, no default */
static Oid defaultCreationNamespace = PG_CATALOG_NAMESPACE; static Oid defaultCreationNamespace = InvalidOid;
/* /*
* myTempNamespace is InvalidOid until and unless a TEMP namespace is set up * 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 */ /* use the default creation namespace */
namespaceId = defaultCreationNamespace; namespaceId = defaultCreationNamespace;
if (!OidIsValid(namespaceId))
elog(ERROR, "No namespace has been selected to create in");
} }
return namespaceId; return namespaceId;
@ -529,6 +534,8 @@ QualifiedNameGetCreationNamespace(List *names, char **objname_p)
{ {
/* use the default creation namespace */ /* use the default creation namespace */
namespaceId = defaultCreationNamespace; namespaceId = defaultCreationNamespace;
if (!OidIsValid(namespaceId))
elog(ERROR, "No namespace has been selected to create in");
} }
*objname_p = objname; *objname_p = objname;
@ -1063,7 +1070,7 @@ assign_search_path(const char *newval)
namespaceSearchPath); namespaceSearchPath);
if (namespaceSearchPath == NIL) if (namespaceSearchPath == NIL)
defaultCreationNamespace = PG_CATALOG_NAMESPACE; defaultCreationNamespace = InvalidOid;
else else
defaultCreationNamespace = (Oid) lfirsti(namespaceSearchPath); defaultCreationNamespace = (Oid) lfirsti(namespaceSearchPath);
@ -1081,26 +1088,28 @@ assign_search_path(const char *newval)
void void
InitializeSearchPath(void) InitializeSearchPath(void)
{ {
/* if (IsBootstrapProcessingMode())
* 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)
{ {
SetConfigOption("search_path", "", /*
PGC_POSTMASTER, PGC_S_DEFAULT); * 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
{
/*
* 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);
} }

View File

@ -27,7 +27,7 @@
# Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group # Portions Copyright (c) 1996-2001, PostgreSQL Global Development Group
# Portions Copyright (c) 1994, Regents of the University of California # 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 # To break an SQL command across lines in this script, backslash-escape all
# internal newlines in the command. # 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 $ECHO_N "initializing pg_shadow... "$ECHO_C