Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitf74f871

Browse files
committed
Fix problems with the "role" GUC and parallel query.
Without this fix, dropping a role can sometimes result in parallelquery failures in sessions that have used "SET ROLE" to assume thedropped role, even if that setting isn't active any more.Report by Pavan Deolasee. Patch by Amit Kapila, reviewed by me.Discussion:http://postgr.es/m/CABOikdOomRcZsLsLK+Z+qENM1zxyaWnAvFh3MJZzZnnKiF+REg@mail.gmail.com
1 parent21daada commitf74f871

File tree

5 files changed

+43
-16
lines changed

5 files changed

+43
-16
lines changed

‎src/backend/access/transam/parallel.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,9 +70,11 @@ typedef struct FixedParallelState
7070
Oiddatabase_id;
7171
Oidauthenticated_user_id;
7272
Oidcurrent_user_id;
73+
Oidouter_user_id;
7374
Oidtemp_namespace_id;
7475
Oidtemp_toast_namespace_id;
7576
intsec_context;
77+
boolis_superuser;
7678
PGPROC*parallel_master_pgproc;
7779
pid_tparallel_master_pid;
7880
BackendIdparallel_master_backend_id;
@@ -310,6 +312,8 @@ InitializeParallelDSM(ParallelContext *pcxt)
310312
shm_toc_allocate(pcxt->toc,sizeof(FixedParallelState));
311313
fps->database_id=MyDatabaseId;
312314
fps->authenticated_user_id=GetAuthenticatedUserId();
315+
fps->outer_user_id=GetCurrentRoleId();
316+
fps->is_superuser=session_auth_is_superuser;
313317
GetUserIdAndSecContext(&fps->current_user_id,&fps->sec_context);
314318
GetTempNamespaceState(&fps->temp_namespace_id,
315319
&fps->temp_toast_namespace_id);
@@ -1126,6 +1130,13 @@ ParallelWorkerMain(Datum main_arg)
11261130
*/
11271131
InvalidateSystemCaches();
11281132

1133+
/*
1134+
* Restore current role id. Skip verifying whether session user is
1135+
* allowed to become this role and blindly restore the leader's state for
1136+
* current role.
1137+
*/
1138+
SetCurrentRoleId(fps->outer_user_id,fps->is_superuser);
1139+
11291140
/* Restore user ID and security context. */
11301141
SetUserIdAndSecContext(fps->current_user_id,fps->sec_context);
11311142

‎src/backend/utils/misc/guc.c

Lines changed: 9 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -424,6 +424,7 @@ booldefault_with_oids = false;
424424
boolSQL_inheritance= true;
425425

426426
boolPassword_encryption= true;
427+
boolsession_auth_is_superuser;
427428

428429
intlog_min_error_statement=ERROR;
429430
intlog_min_messages=WARNING;
@@ -470,7 +471,6 @@ inthuge_pages;
470471
* and is kept in sync by assign_hooks.
471472
*/
472473
staticchar*syslog_ident_str;
473-
staticboolsession_auth_is_superuser;
474474
staticdoublephony_random_seed;
475475
staticchar*client_encoding_string;
476476
staticchar*datestyle_string;
@@ -8873,12 +8873,18 @@ read_nondefault_variables(void)
88738873
* constants; a few, like server_encoding and lc_ctype, are handled specially
88748874
* outside the serialize/restore procedure. Therefore, SerializeGUCState()
88758875
* never sends these, and RestoreGUCState() never changes them.
8876+
*
8877+
* Role is a special variable in the sense that its current value can be an
8878+
* invalid value and there are multiple ways by which that can happen (like
8879+
* after setting the role, someone drops it). So we handle it outside of
8880+
* serialize/restore machinery.
88768881
*/
88778882
staticbool
88788883
can_skip_gucvar(structconfig_generic*gconf)
88798884
{
88808885
returngconf->context==PGC_POSTMASTER||
8881-
gconf->context==PGC_INTERNAL||gconf->source==PGC_S_DEFAULT;
8886+
gconf->context==PGC_INTERNAL||gconf->source==PGC_S_DEFAULT||
8887+
strcmp(gconf->name,"role")==0;
88828888
}
88838889

88848890
/*
@@ -9139,27 +9145,14 @@ SerializeGUCState(Size maxsize, char *start_address)
91399145
Sizeactual_size;
91409146
Sizebytes_left;
91419147
inti;
9142-
inti_role=-1;
91439148

91449149
/* Reserve space for saving the actual size of the guc state */
91459150
Assert(maxsize>sizeof(actual_size));
91469151
curptr=start_address+sizeof(actual_size);
91479152
bytes_left=maxsize-sizeof(actual_size);
91489153

91499154
for (i=0;i<num_guc_variables;i++)
9150-
{
9151-
/*
9152-
* It's pretty ugly, but we've got to force "role" to be initialized
9153-
* after "session_authorization"; otherwise, the latter will override
9154-
* the former.
9155-
*/
9156-
if (strcmp(guc_variables[i]->name,"role")==0)
9157-
i_role=i;
9158-
else
9159-
serialize_variable(&curptr,&bytes_left,guc_variables[i]);
9160-
}
9161-
if (i_role >=0)
9162-
serialize_variable(&curptr,&bytes_left,guc_variables[i_role]);
9155+
serialize_variable(&curptr,&bytes_left,guc_variables[i]);
91639156

91649157
/* Store actual size without assuming alignment of start_address. */
91659158
actual_size=maxsize-bytes_left-sizeof(actual_size);

‎src/include/utils/guc.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,7 @@ extern bool log_btree_build_stats;
245245
externPGDLLIMPORTboolcheck_function_bodies;
246246
externbooldefault_with_oids;
247247
externboolSQL_inheritance;
248+
externboolsession_auth_is_superuser;
248249

249250
externintlog_min_error_statement;
250251
externintlog_min_messages;

‎src/test/regress/expected/select_parallel.out

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,21 @@ explain (costs off)
9999
-> Index Only Scan using tenk1_unique1 on tenk1
100100
(3 rows)
101101

102+
-- test the sanity of parallel query after the active role is dropped.
102103
set force_parallel_mode=1;
104+
drop role if exists regress_parallel_worker;
105+
NOTICE: role "regress_parallel_worker" does not exist, skipping
106+
create role regress_parallel_worker;
107+
set role regress_parallel_worker;
108+
reset session authorization;
109+
drop role regress_parallel_worker;
110+
select count(*) from tenk1;
111+
count
112+
-------
113+
10000
114+
(1 row)
115+
116+
reset role;
103117
explain (costs off)
104118
select stringu1::int2 from tenk1 where unique1 = 1;
105119
QUERY PLAN

‎src/test/regress/sql/select_parallel.sql

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,15 @@ explain (costs off)
3939
selectsum(parallel_restricted(unique1))from tenk1
4040
group by(parallel_restricted(unique1));
4141

42+
-- test the sanity of parallel query after the active role is dropped.
4243
set force_parallel_mode=1;
44+
drop role if exists regress_parallel_worker;
45+
create role regress_parallel_worker;
46+
set role regress_parallel_worker;
47+
reset session authorization;
48+
drop role regress_parallel_worker;
49+
selectcount(*)from tenk1;
50+
reset role;
4351

4452
explain (costs off)
4553
select stringu1::int2from tenk1where unique1=1;

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp