From b66cbc1fa26aebfcfecbfff7c92d804d083af843 Mon Sep 17 00:00:00 2001 From: Tom Lane Date: Mon, 15 Apr 2002 22:33:21 +0000 Subject: [PATCH] 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. --- doc/src/sgml/runtime.sgml | 8 ++-- src/backend/catalog/namespace.c | 67 +++++++++++++++++++-------------- src/bin/initdb/initdb.sh | 4 +- 3 files changed, 43 insertions(+), 36 deletions(-) diff --git a/doc/src/sgml/runtime.sgml b/doc/src/sgml/runtime.sgml index 2b0a4ad634..babb95a4cd 100644 --- a/doc/src/sgml/runtime.sgml +++ b/doc/src/sgml/runtime.sgml @@ -1,5 +1,5 @@ @@ -1231,10 +1231,8 @@ dynamic_library_path = '/usr/local/lib/postgresql:/home/my_project/lib:$libdir' 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 pg_catalog if the search - path list is empty. (Note that users do not normally have - permission to write in 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. diff --git a/src/backend/catalog/namespace.c b/src/backend/catalog/namespace.c index 84bd95e466..77b6ceb78d 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()) { - 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); } diff --git a/src/bin/initdb/initdb.sh b/src/bin/initdb/initdb.sh index 30f7de1f20..03fa12a846 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