From 0d56c32c8e724f96f4aa5b15645d427f6e2ddf21 Mon Sep 17 00:00:00 2001 From: Jeff Davis Date: Mon, 7 Aug 2023 15:13:06 -0700 Subject: [PATCH] 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 --- src/backend/catalog/namespace.c | 6 +- .../isolation/expected/search-path-inval.out | 97 +++++++++++++++++++ src/test/isolation/isolation_schedule | 1 + .../isolation/specs/search-path-inval.spec | 59 +++++++++++ 4 files changed, 162 insertions(+), 1 deletion(-) create mode 100644 src/test/isolation/expected/search-path-inval.out create mode 100644 src/test/isolation/specs/search-path-inval.spec diff --git a/src/backend/catalog/namespace.c b/src/backend/catalog/namespace.c index 69ab1b8e4b..474970baf0 100644 --- a/src/backend/catalog/namespace.c +++ b/src/backend/catalog/namespace.c @@ -4396,11 +4396,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; } diff --git a/src/test/isolation/expected/search-path-inval.out b/src/test/isolation/expected/search-path-inval.out new file mode 100644 index 0000000000..e0173afdb2 --- /dev/null +++ b/src/test/isolation/expected/search-path-inval.out @@ -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; + diff --git a/src/test/isolation/isolation_schedule b/src/test/isolation/isolation_schedule index 4fc56ae99c..eab9f2243e 100644 --- a/src/test/isolation/isolation_schedule +++ b/src/test/isolation/isolation_schedule @@ -110,3 +110,4 @@ test: serializable-parallel test: serializable-parallel-2 test: serializable-parallel-3 test: matview-write-skew +test: search-path-inval \ No newline at end of file diff --git a/src/test/isolation/specs/search-path-inval.spec b/src/test/isolation/specs/search-path-inval.spec new file mode 100644 index 0000000000..08b1bba2fc --- /dev/null +++ b/src/test/isolation/specs/search-path-inval.spec @@ -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