search_path_no_check.patch
text/x-patch
Filename: search_path_no_check.patch
Type: text/x-patch
Part: 0
Message:
Re: invalid search_path complaints
Patch
Same data as JSON:
GET /api/v1/attachments/:id/patch
the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes.
API reference →
Format: unified
| File | + | − |
|---|---|---|
| doc/src/sgml/config.sgml | 0 | 0 |
| src/backend/catalog/namespace.c | 0 | 0 |
| src/test/regress/expected/guc.out | 0 | 0 |
| src/test/regress/sql/guc.sql | 0 | 0 |
diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml
index 640defde860d57a81d0671f2957b99ded15a3566..361ad7b99a52bbbcec570b639800c175d3c19ab7 100644
*** a/doc/src/sgml/config.sgml
--- b/doc/src/sgml/config.sgml
*************** COPY postgres_log FROM '/full/path/to/lo
*** 4670,4679 ****
<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.)
</para>
<para>
--- 4670,4686 ----
<para>
The value for <varname>search_path</varname> must be a comma-separated
! 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>
*************** COPY postgres_log FROM '/full/path/to/lo
*** 4697,4712 ****
<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.
</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
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
--- 4704,4718 ----
<para>
When objects are created without specifying a particular target
! 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>.
! 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
diff --git a/src/backend/catalog/namespace.c b/src/backend/catalog/namespace.c
index dc8f8eaf3f3f60f51fd8b59aa78ccfc36e1b23f9..e92efd863ed74fb77425333d772c194c3d36851b 100644
*** a/src/backend/catalog/namespace.c
--- b/src/backend/catalog/namespace.c
*************** ResetTempTableNamespace(void)
*** 3773,3786 ****
* Routines for handling the GUC variable 'search_path'.
*/
! /* check_hook: validate new search_path, if possible */
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);
--- 3773,3784 ----
* Routines for handling the GUC variable 'search_path'.
*/
! /* check_hook: validate new search_path value */
bool
check_search_path(char **newval, void **extra, GucSource source)
{
char *rawname;
List *namelist;
/* Need a modifiable copy of string */
rawname = pstrdup(*newval);
*************** check_search_path(char **newval, void **
*** 3796,3847 ****
}
/*
! * If we aren't inside a transaction, we cannot do database access so
! * cannot verify the individual names. Must accept the list on faith.
*/
- 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;
}
/* assign_hook: do extra actions as needed */
--- 3794,3810 ----
}
/*
! * 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.
*/
pfree(rawname);
list_free(namelist);
! 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 d324862049955574a9fda42799e6cb66248688d8..271706d31e9301147ffa85065ff260db2b60730d 100644
*** a/src/test/regress/expected/guc.out
--- b/src/test/regress/expected/guc.out
*************** SELECT current_user = 'temp_reset_user';
*** 605,610 ****
--- 605,635 ----
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';
*************** select report_guc('work_mem'), current_s
*** 617,630 ****
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';
select report_guc('work_mem'), current_setting('work_mem');
report_guc | current_setting
------------+-----------------
--- 642,648 ----
1MB | 3MB
(1 row)
! 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 21ed86f26ba259e7258e6b69afa8f8e80e2a2442..0c217923814893d0aacc2c83d548fe778eeaded7 100644
*** a/src/test/regress/sql/guc.sql
--- b/src/test/regress/sql/guc.sql
*************** SELECT current_user = 'temp_reset_user';
*** 183,188 ****
--- 183,200 ----
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
--
*************** set work_mem = '1MB';
*** 194,206 ****
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';
select report_guc('work_mem'), current_setting('work_mem');
--- 206,212 ----
select report_guc('work_mem'), current_setting('work_mem');
! alter function report_guc(text) set work_mem = '2MB';
select report_guc('work_mem'), current_setting('work_mem');