<para>
The value for <varname>search_path</varname> must be a comma-separated
- list of schema names. If one of the list items is
- the special value <literal>$user</literal>, then the schema
- having the name returned by <function>SESSION_USER</> is substituted, if there
- is such a schema. (If not, <literal>$user</literal> 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 <literal>USAGE</>
+ permission, is silently ignored.
+ </para>
+
+ <para>
+ If one of the list items is the special name
+ <literal>$user</literal>, then the schema having the name returned by
+ <function>SESSION_USER</> is substituted, if there is such a schema
+ and the user has <literal>USAGE</> permission for it.
+ (If not, <literal>$user</literal> is ignored.)
</para>
<para>
<para>
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
+ <varname>search_path</varname>. An error is reported if the search
+ path is empty.
</para>
<para>
The default value for this parameter is
- <literal>'"$user", public'</literal> (where the second part will be
- ignored if there is no schema named <literal>public</>).
- This supports shared use of a database (where no users
+ <literal>"$user", public</literal>.
+ This setting supports shared use of a database (where no users
have private schemas, and all share use of <literal>public</>),
private per-user schemas, and combinations of these. Other
effects can be obtained by altering the default search path
* 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);
}
/*
- * 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 */
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';
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
------------+-----------------
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
--
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');