Recalculate search_path after ALTER ROLE.

Renaming a role can affect the meaning of the special string $user, so
must cause search_path to be recalculated.

Discussion: https://postgr.es/m/186761d32c0255debbdf50b6310b581b9c973e6c.camel@j-davis.com
Reviewed-by: Nathan Bossart, Michael Paquier
Backpatch-through: 11
This commit is contained in:
Jeff Davis 2023-08-07 15:12:33 -07:00
parent 86648dcdae
commit 00953f1e23
4 changed files with 162 additions and 1 deletions

View File

@ -4399,11 +4399,15 @@ InitializeSearchPath(void)
{
/*
* In normal mode, arrange for a callback on any syscache invalidation
* of pg_namespace rows.
* of pg_namespace or pg_authid rows. (Changing a role name may affect
* the meaning of the special string $user.)
*/
CacheRegisterSyscacheCallback(NAMESPACEOID,
NamespaceCallback,
(Datum) 0);
CacheRegisterSyscacheCallback(AUTHOID,
NamespaceCallback,
(Datum) 0);
/* Force search path to be recomputed on next use */
baseSearchPathValid = false;
}

View File

@ -0,0 +1,97 @@
Parsed test spec with 3 sessions
starting permutation: s1a s2a s1a s2b
step s1a:
SELECT CURRENT_USER;
SHOW search_path;
SELECT t FROM x;
current_user
----------------
regress_sp_user1
(1 row)
search_path
--------------------------
"$user", regress_sp_public
(1 row)
t
--------------------------
data in regress_sp_user1.x
(1 row)
step s2a:
ALTER ROLE regress_sp_user1 RENAME TO regress_sp_user2;
step s1a:
SELECT CURRENT_USER;
SHOW search_path;
SELECT t FROM x;
current_user
----------------
regress_sp_user2
(1 row)
search_path
--------------------------
"$user", regress_sp_public
(1 row)
t
---------------------------
data in regress_sp_public.x
(1 row)
step s2b:
ALTER ROLE regress_sp_user2 RENAME TO regress_sp_user1;
starting permutation: s1a s3a s1a s3b
step s1a:
SELECT CURRENT_USER;
SHOW search_path;
SELECT t FROM x;
current_user
----------------
regress_sp_user1
(1 row)
search_path
--------------------------
"$user", regress_sp_public
(1 row)
t
--------------------------
data in regress_sp_user1.x
(1 row)
step s3a:
ALTER SCHEMA regress_sp_user1 RENAME TO regress_sp_user2;
step s1a:
SELECT CURRENT_USER;
SHOW search_path;
SELECT t FROM x;
current_user
----------------
regress_sp_user1
(1 row)
search_path
--------------------------
"$user", regress_sp_public
(1 row)
t
---------------------------
data in regress_sp_public.x
(1 row)
step s3b:
ALTER SCHEMA regress_sp_user2 RENAME TO regress_sp_user1;

View File

@ -100,3 +100,4 @@ test: truncate-conflict
test: serializable-parallel
test: serializable-parallel-2
test: serializable-parallel-3
test: search-path-inval

View File

@ -0,0 +1,59 @@
# Test search_path invalidation.
setup
{
CREATE USER regress_sp_user1;
CREATE SCHEMA regress_sp_user1 AUTHORIZATION regress_sp_user1;
CREATE SCHEMA regress_sp_public;
GRANT ALL PRIVILEGES ON SCHEMA regress_sp_public TO regress_sp_user1;
}
teardown
{
DROP SCHEMA regress_sp_public CASCADE;
DROP SCHEMA regress_sp_user1 CASCADE;
DROP USER regress_sp_user1;
}
session s1
setup
{
SET search_path = "$user", regress_sp_public;
SET SESSION AUTHORIZATION regress_sp_user1;
CREATE TABLE regress_sp_user1.x(t) AS SELECT 'data in regress_sp_user1.x';
CREATE TABLE regress_sp_public.x(t) AS SELECT 'data in regress_sp_public.x';
}
step s1a
{
SELECT CURRENT_USER;
SHOW search_path;
SELECT t FROM x;
}
session s2
step s2a
{
ALTER ROLE regress_sp_user1 RENAME TO regress_sp_user2;
}
step s2b
{
ALTER ROLE regress_sp_user2 RENAME TO regress_sp_user1;
}
session s3
step s3a
{
ALTER SCHEMA regress_sp_user1 RENAME TO regress_sp_user2;
}
step s3b
{
ALTER SCHEMA regress_sp_user2 RENAME TO regress_sp_user1;
}
# s1's search_path is invalidated by role name change in s2a, and
# falls back to regress_sp_public.x
permutation s1a s2a s1a s2b
# s1's search_path is invalidated by schema name change in s2b, and
# falls back to regress_sp_public.x
permutation s1a s3a s1a s3b