diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml
index 640defde86..361ad7b99a 100644
--- a/doc/src/sgml/config.sgml
+++ b/doc/src/sgml/config.sgml
@@ -4670,10 +4670,17 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv;
The value for search_path must be a comma-separated
- list of schema names. If one of the list items is
- the special value $user, then the schema
- having the name returned by SESSION_USER> is substituted, if there
- is such a schema. (If not, $user is ignored.)
+ list of schema names. Any name that is not an existing schema, or is
+ a schema for which the user does not have USAGE>
+ permission, is silently ignored.
+
+
+
+ If one of the list items is the special name
+ $user, then the schema having the name returned by
+ SESSION_USER> is substituted, if there is such a schema
+ and the user has USAGE> permission for it.
+ (If not, $user is ignored.)
@@ -4697,16 +4704,15 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv;
When objects are created without specifying a particular target
- schema, they will be placed in the first schema listed
- in the search path. An error is reported if the search path is
- empty.
+ schema, they will be placed in the first valid schema named in
+ search_path. An error is reported if the search
+ path is empty.
The default value for this parameter is
- '"$user", public' (where the second part will be
- ignored if there is no schema named public>).
- This supports shared use of a database (where no users
+ "$user", public.
+ This setting supports shared use of a database (where no users
have private schemas, and all share use of public>),
private per-user schemas, and combinations of these. Other
effects can be obtained by altering the default search path
diff --git a/src/backend/catalog/namespace.c b/src/backend/catalog/namespace.c
index dc8f8eaf3f..e92efd863e 100644
--- a/src/backend/catalog/namespace.c
+++ b/src/backend/catalog/namespace.c
@@ -3773,14 +3773,12 @@ ResetTempTableNamespace(void)
* Routines for handling the GUC variable 'search_path'.
*/
-/* check_hook: validate new search_path, if possible */
+/* check_hook: validate new search_path value */
bool
check_search_path(char **newval, void **extra, GucSource source)
{
- bool result = true;
char *rawname;
List *namelist;
- ListCell *l;
/* Need a modifiable copy of string */
rawname = pstrdup(*newval);
@@ -3796,52 +3794,17 @@ check_search_path(char **newval, void **extra, GucSource source)
}
/*
- * If we aren't inside a transaction, we cannot do database access so
- * cannot verify the individual names. Must accept the list on faith.
+ * We used to try to check that the named schemas exist, but there are
+ * many valid use-cases for having search_path settings that include
+ * schemas that don't exist; and often, we are not inside a transaction
+ * here and so can't consult the system catalogs anyway. So now, the only
+ * requirement is syntactic validity of the identifier list.
*/
- if (IsTransactionState())
- {
- /*
- * Verify that all the names are either valid namespace names or
- * "$user" or "pg_temp". We do not require $user to correspond to a
- * valid namespace, and pg_temp might not exist yet. We do not check
- * for USAGE rights, either; should we?
- *
- * When source == PGC_S_TEST, we are checking the argument of an ALTER
- * DATABASE SET or ALTER USER SET command. It could be that the
- * intended use of the search path is for some other database, so we
- * should not error out if it mentions schemas not present in the
- * current database. We issue a NOTICE instead.
- */
- foreach(l, namelist)
- {
- char *curname = (char *) lfirst(l);
-
- if (strcmp(curname, "$user") == 0)
- continue;
- if (strcmp(curname, "pg_temp") == 0)
- continue;
- if (!SearchSysCacheExists1(NAMESPACENAME,
- CStringGetDatum(curname)))
- {
- if (source == PGC_S_TEST)
- ereport(NOTICE,
- (errcode(ERRCODE_UNDEFINED_SCHEMA),
- errmsg("schema \"%s\" does not exist", curname)));
- else
- {
- GUC_check_errdetail("schema \"%s\" does not exist", curname);
- result = false;
- break;
- }
- }
- }
- }
pfree(rawname);
list_free(namelist);
- return result;
+ return true;
}
/* assign_hook: do extra actions as needed */
diff --git a/src/test/regress/expected/guc.out b/src/test/regress/expected/guc.out
index d324862049..271706d31e 100644
--- a/src/test/regress/expected/guc.out
+++ b/src/test/regress/expected/guc.out
@@ -605,6 +605,31 @@ SELECT current_user = 'temp_reset_user';
DROP ROLE temp_reset_user;
--
+-- search_path should react to changes in pg_namespace
+--
+set search_path = foo, public, not_there_initially;
+select current_schemas(false);
+ current_schemas
+-----------------
+ {public}
+(1 row)
+
+create schema not_there_initially;
+select current_schemas(false);
+ current_schemas
+------------------------------
+ {public,not_there_initially}
+(1 row)
+
+drop schema not_there_initially;
+select current_schemas(false);
+ current_schemas
+-----------------
+ {public}
+(1 row)
+
+reset search_path;
+--
-- Tests for function-local GUC settings
--
set work_mem = '3MB';
@@ -617,14 +642,7 @@ select report_guc('work_mem'), current_setting('work_mem');
1MB | 3MB
(1 row)
--- this should draw only a warning
-alter function report_guc(text) set search_path = no_such_schema;
-NOTICE: schema "no_such_schema" does not exist
--- with error occurring here
-select report_guc('work_mem'), current_setting('work_mem');
-ERROR: invalid value for parameter "search_path": "no_such_schema"
-DETAIL: schema "no_such_schema" does not exist
-alter function report_guc(text) reset search_path set work_mem = '2MB';
+alter function report_guc(text) set work_mem = '2MB';
select report_guc('work_mem'), current_setting('work_mem');
report_guc | current_setting
------------+-----------------
diff --git a/src/test/regress/sql/guc.sql b/src/test/regress/sql/guc.sql
index 21ed86f26b..0c21792381 100644
--- a/src/test/regress/sql/guc.sql
+++ b/src/test/regress/sql/guc.sql
@@ -182,6 +182,18 @@ SELECT relname from pg_class where relname = 'tmp_foo';
SELECT current_user = 'temp_reset_user';
DROP ROLE temp_reset_user;
+--
+-- search_path should react to changes in pg_namespace
+--
+
+set search_path = foo, public, not_there_initially;
+select current_schemas(false);
+create schema not_there_initially;
+select current_schemas(false);
+drop schema not_there_initially;
+select current_schemas(false);
+reset search_path;
+
--
-- Tests for function-local GUC settings
--
@@ -194,13 +206,7 @@ set work_mem = '1MB';
select report_guc('work_mem'), current_setting('work_mem');
--- this should draw only a warning
-alter function report_guc(text) set search_path = no_such_schema;
-
--- with error occurring here
-select report_guc('work_mem'), current_setting('work_mem');
-
-alter function report_guc(text) reset search_path set work_mem = '2MB';
+alter function report_guc(text) set work_mem = '2MB';
select report_guc('work_mem'), current_setting('work_mem');