Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 880bfc3

Browse files
committed
Silently ignore any nonexistent schemas that are listed in search_path.
Previously we attempted to throw an error or at least warning for missing schemas, but this was done inconsistently because of implementation restrictions (in many cases, GUC settings are applied outside transactions so that we can't do system catalog lookups). Furthermore, there were exceptions to the rule even in the beginning, and we'd been poking more and more holes in it as time went on, because it turns out that there are lots of use-cases for having some irrelevant items in a common search_path value. It seems better to just adopt a philosophy similar to what's always been done with Unix PATH settings, wherein nonexistent or unreadable directories are silently ignored. This commit also fixes the documentation to point out that schemas for which the user lacks USAGE privilege are silently ignored. That's always been true but was previously not documented. This is mostly in response to Robert Haas' complaint that 9.1 started to throw errors or warnings for missing schemas in cases where prior releases had not. We won't adopt such a significant behavioral change in a back branch, so something different will be needed in 9.1.
1 parent b035cb9 commit 880bfc3

File tree

4 files changed

+62
-69
lines changed

4 files changed

+62
-69
lines changed

doc/src/sgml/config.sgml

+16-10
Original file line numberDiff line numberDiff line change
@@ -4670,10 +4670,17 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv;
46704670

46714671
<para>
46724672
The value for <varname>search_path</varname> must be a comma-separated
4673-
list of schema names. If one of the list items is
4674-
the special value <literal>$user</literal>, then the schema
4675-
having the name returned by <function>SESSION_USER</> is substituted, if there
4676-
is such a schema. (If not, <literal>$user</literal> is ignored.)
4673+
list of schema names. Any name that is not an existing schema, or is
4674+
a schema for which the user does not have <literal>USAGE</>
4675+
permission, is silently ignored.
4676+
</para>
4677+
4678+
<para>
4679+
If one of the list items is the special name
4680+
<literal>$user</literal>, then the schema having the name returned by
4681+
<function>SESSION_USER</> is substituted, if there is such a schema
4682+
and the user has <literal>USAGE</> permission for it.
4683+
(If not, <literal>$user</literal> is ignored.)
46774684
</para>
46784685

46794686
<para>
@@ -4697,16 +4704,15 @@ COPY postgres_log FROM '/full/path/to/logfile.csv' WITH csv;
46974704

46984705
<para>
46994706
When objects are created without specifying a particular target
4700-
schema, they will be placed in the first schema listed
4701-
in the search path. An error is reported if the search path is
4702-
empty.
4707+
schema, they will be placed in the first valid schema named in
4708+
<varname>search_path</varname>. An error is reported if the search
4709+
path is empty.
47034710
</para>
47044711

47054712
<para>
47064713
The default value for this parameter is
4707-
<literal>'"$user", public'</literal> (where the second part will be
4708-
ignored if there is no schema named <literal>public</>).
4709-
This supports shared use of a database (where no users
4714+
<literal>"$user", public</literal>.
4715+
This setting supports shared use of a database (where no users
47104716
have private schemas, and all share use of <literal>public</>),
47114717
private per-user schemas, and combinations of these. Other
47124718
effects can be obtained by altering the default search path

src/backend/catalog/namespace.c

+7-44
Original file line numberDiff line numberDiff line change
@@ -3773,14 +3773,12 @@ ResetTempTableNamespace(void)
37733773
* Routines for handling the GUC variable 'search_path'.
37743774
*/
37753775

3776-
/* check_hook: validate new search_path, if possible */
3776+
/* check_hook: validate new search_path value */
37773777
bool
37783778
check_search_path(char **newval, void **extra, GucSource source)
37793779
{
3780-
bool result = true;
37813780
char *rawname;
37823781
List *namelist;
3783-
ListCell *l;
37843782

37853783
/* Need a modifiable copy of string */
37863784
rawname = pstrdup(*newval);
@@ -3796,52 +3794,17 @@ check_search_path(char **newval, void **extra, GucSource source)
37963794
}
37973795

37983796
/*
3799-
* If we aren't inside a transaction, we cannot do database access so
3800-
* cannot verify the individual names. Must accept the list on faith.
3797+
* We used to try to check that the named schemas exist, but there are
3798+
* many valid use-cases for having search_path settings that include
3799+
* schemas that don't exist; and often, we are not inside a transaction
3800+
* here and so can't consult the system catalogs anyway. So now, the only
3801+
* requirement is syntactic validity of the identifier list.
38013802
*/
3802-
if (IsTransactionState())
3803-
{
3804-
/*
3805-
* Verify that all the names are either valid namespace names or
3806-
* "$user" or "pg_temp". We do not require $user to correspond to a
3807-
* valid namespace, and pg_temp might not exist yet. We do not check
3808-
* for USAGE rights, either; should we?
3809-
*
3810-
* When source == PGC_S_TEST, we are checking the argument of an ALTER
3811-
* DATABASE SET or ALTER USER SET command. It could be that the
3812-
* intended use of the search path is for some other database, so we
3813-
* should not error out if it mentions schemas not present in the
3814-
* current database. We issue a NOTICE instead.
3815-
*/
3816-
foreach(l, namelist)
3817-
{
3818-
char *curname = (char *) lfirst(l);
3819-
3820-
if (strcmp(curname, "$user") == 0)
3821-
continue;
3822-
if (strcmp(curname, "pg_temp") == 0)
3823-
continue;
3824-
if (!SearchSysCacheExists1(NAMESPACENAME,
3825-
CStringGetDatum(curname)))
3826-
{
3827-
if (source == PGC_S_TEST)
3828-
ereport(NOTICE,
3829-
(errcode(ERRCODE_UNDEFINED_SCHEMA),
3830-
errmsg("schema \"%s\" does not exist", curname)));
3831-
else
3832-
{
3833-
GUC_check_errdetail("schema \"%s\" does not exist", curname);
3834-
result = false;
3835-
break;
3836-
}
3837-
}
3838-
}
3839-
}
38403803

38413804
pfree(rawname);
38423805
list_free(namelist);
38433806

3844-
return result;
3807+
return true;
38453808
}
38463809

38473810
/* assign_hook: do extra actions as needed */

src/test/regress/expected/guc.out

+26-8
Original file line numberDiff line numberDiff line change
@@ -605,6 +605,31 @@ SELECT current_user = 'temp_reset_user';
605605

606606
DROP ROLE temp_reset_user;
607607
--
608+
-- search_path should react to changes in pg_namespace
609+
--
610+
set search_path = foo, public, not_there_initially;
611+
select current_schemas(false);
612+
current_schemas
613+
-----------------
614+
{public}
615+
(1 row)
616+
617+
create schema not_there_initially;
618+
select current_schemas(false);
619+
current_schemas
620+
------------------------------
621+
{public,not_there_initially}
622+
(1 row)
623+
624+
drop schema not_there_initially;
625+
select current_schemas(false);
626+
current_schemas
627+
-----------------
628+
{public}
629+
(1 row)
630+
631+
reset search_path;
632+
--
608633
-- Tests for function-local GUC settings
609634
--
610635
set work_mem = '3MB';
@@ -617,14 +642,7 @@ select report_guc('work_mem'), current_setting('work_mem');
617642
1MB | 3MB
618643
(1 row)
619644

620-
-- this should draw only a warning
621-
alter function report_guc(text) set search_path = no_such_schema;
622-
NOTICE: schema "no_such_schema" does not exist
623-
-- with error occurring here
624-
select report_guc('work_mem'), current_setting('work_mem');
625-
ERROR: invalid value for parameter "search_path": "no_such_schema"
626-
DETAIL: schema "no_such_schema" does not exist
627-
alter function report_guc(text) reset search_path set work_mem = '2MB';
645+
alter function report_guc(text) set work_mem = '2MB';
628646
select report_guc('work_mem'), current_setting('work_mem');
629647
report_guc | current_setting
630648
------------+-----------------

src/test/regress/sql/guc.sql

+13-7
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,18 @@ SELECT relname from pg_class where relname = 'tmp_foo';
182182
SELECT current_user = 'temp_reset_user';
183183
DROP ROLE temp_reset_user;
184184

185+
--
186+
-- search_path should react to changes in pg_namespace
187+
--
188+
189+
set search_path = foo, public, not_there_initially;
190+
select current_schemas(false);
191+
create schema not_there_initially;
192+
select current_schemas(false);
193+
drop schema not_there_initially;
194+
select current_schemas(false);
195+
reset search_path;
196+
185197
--
186198
-- Tests for function-local GUC settings
187199
--
@@ -194,13 +206,7 @@ set work_mem = '1MB';
194206

195207
select report_guc('work_mem'), current_setting('work_mem');
196208

197-
-- this should draw only a warning
198-
alter function report_guc(text) set search_path = no_such_schema;
199-
200-
-- with error occurring here
201-
select report_guc('work_mem'), current_setting('work_mem');
202-
203-
alter function report_guc(text) reset search_path set work_mem = '2MB';
209+
alter function report_guc(text) set work_mem = '2MB';
204210

205211
select report_guc('work_mem'), current_setting('work_mem');
206212

0 commit comments

Comments
 (0)