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

Commit69125c8

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 parent291a31c commit69125c8

File tree

5 files changed

+48
-16
lines changed

5 files changed

+48
-16
lines changed

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

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,9 +71,11 @@ typedef struct FixedParallelState
7171
Oiddatabase_id;
7272
Oidauthenticated_user_id;
7373
Oidcurrent_user_id;
74+
Oidouter_user_id;
7475
Oidtemp_namespace_id;
7576
Oidtemp_toast_namespace_id;
7677
intsec_context;
78+
boolis_superuser;
7779
PGPROC*parallel_master_pgproc;
7880
pid_tparallel_master_pid;
7981
BackendIdparallel_master_backend_id;
@@ -275,6 +277,8 @@ InitializeParallelDSM(ParallelContext *pcxt)
275277
shm_toc_allocate(pcxt->toc,sizeof(FixedParallelState));
276278
fps->database_id=MyDatabaseId;
277279
fps->authenticated_user_id=GetAuthenticatedUserId();
280+
fps->outer_user_id=GetCurrentRoleId();
281+
fps->is_superuser=session_auth_is_superuser;
278282
GetUserIdAndSecContext(&fps->current_user_id,&fps->sec_context);
279283
GetTempNamespaceState(&fps->temp_namespace_id,
280284
&fps->temp_toast_namespace_id);
@@ -1079,6 +1083,13 @@ ParallelWorkerMain(Datum main_arg)
10791083
*/
10801084
InvalidateSystemCaches();
10811085

1086+
/*
1087+
* Restore current role id. Skip verifying whether session user is
1088+
* allowed to become this role and blindly restore the leader's state for
1089+
* current role.
1090+
*/
1091+
SetCurrentRoleId(fps->outer_user_id,fps->is_superuser);
1092+
10821093
/* Restore user ID and security context. */
10831094
SetUserIdAndSecContext(fps->current_user_id,fps->sec_context);
10841095

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

Lines changed: 9 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -446,6 +446,7 @@ char *event_source;
446446
boolrow_security;
447447
boolcheck_function_bodies= true;
448448
booldefault_with_oids= false;
449+
boolsession_auth_is_superuser;
449450

450451
intlog_min_error_statement=ERROR;
451452
intlog_min_messages=WARNING;
@@ -492,7 +493,6 @@ inthuge_pages;
492493
* and is kept in sync by assign_hooks.
493494
*/
494495
staticchar*syslog_ident_str;
495-
staticboolsession_auth_is_superuser;
496496
staticdoublephony_random_seed;
497497
staticchar*client_encoding_string;
498498
staticchar*datestyle_string;
@@ -8986,12 +8986,18 @@ read_nondefault_variables(void)
89868986
* constants; a few, like server_encoding and lc_ctype, are handled specially
89878987
* outside the serialize/restore procedure. Therefore, SerializeGUCState()
89888988
* never sends these, and RestoreGUCState() never changes them.
8989+
*
8990+
* Role is a special variable in the sense that its current value can be an
8991+
* invalid value and there are multiple ways by which that can happen (like
8992+
* after setting the role, someone drops it). So we handle it outside of
8993+
* serialize/restore machinery.
89898994
*/
89908995
staticbool
89918996
can_skip_gucvar(structconfig_generic*gconf)
89928997
{
89938998
returngconf->context==PGC_POSTMASTER||
8994-
gconf->context==PGC_INTERNAL||gconf->source==PGC_S_DEFAULT;
8999+
gconf->context==PGC_INTERNAL||gconf->source==PGC_S_DEFAULT||
9000+
strcmp(gconf->name,"role")==0;
89959001
}
89969002

89979003
/*
@@ -9252,27 +9258,14 @@ SerializeGUCState(Size maxsize, char *start_address)
92529258
Sizeactual_size;
92539259
Sizebytes_left;
92549260
inti;
9255-
inti_role=-1;
92569261

92579262
/* Reserve space for saving the actual size of the guc state */
92589263
Assert(maxsize>sizeof(actual_size));
92599264
curptr=start_address+sizeof(actual_size);
92609265
bytes_left=maxsize-sizeof(actual_size);
92619266

92629267
for (i=0;i<num_guc_variables;i++)
9263-
{
9264-
/*
9265-
* It's pretty ugly, but we've got to force "role" to be initialized
9266-
* after "session_authorization"; otherwise, the latter will override
9267-
* the former.
9268-
*/
9269-
if (strcmp(guc_variables[i]->name,"role")==0)
9270-
i_role=i;
9271-
else
9272-
serialize_variable(&curptr,&bytes_left,guc_variables[i]);
9273-
}
9274-
if (i_role >=0)
9275-
serialize_variable(&curptr,&bytes_left,guc_variables[i_role]);
9268+
serialize_variable(&curptr,&bytes_left,guc_variables[i]);
92769269

92779270
/* Store actual size without assuming alignment of start_address. */
92789271
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
@@ -244,6 +244,7 @@ extern bool log_btree_build_stats;
244244

245245
externPGDLLIMPORTboolcheck_function_bodies;
246246
externbooldefault_with_oids;
247+
externboolsession_auth_is_superuser;
247248

248249
externintlog_min_error_statement;
249250
externintlog_min_messages;

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

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -424,6 +424,22 @@ select string4 from tenk1 order by string4 limit 5;
424424

425425
reset max_parallel_workers;
426426
reset enable_hashagg;
427+
-- test the sanity of parallel query after the active role is dropped.
428+
drop role if exists regress_parallel_worker;
429+
NOTICE: role "regress_parallel_worker" does not exist, skipping
430+
create role regress_parallel_worker;
431+
set role regress_parallel_worker;
432+
reset session authorization;
433+
drop role regress_parallel_worker;
434+
set force_parallel_mode = 1;
435+
select count(*) from tenk1;
436+
count
437+
-------
438+
10000
439+
(1 row)
440+
441+
reset force_parallel_mode;
442+
reset role;
427443
set force_parallel_mode=1;
428444
explain (costs off)
429445
select stringu1::int2 from tenk1 where unique1 = 1;

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

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -162,6 +162,17 @@ select string4 from tenk1 order by string4 limit 5;
162162
reset max_parallel_workers;
163163
reset enable_hashagg;
164164

165+
-- test the sanity of parallel query after the active role is dropped.
166+
drop role if exists regress_parallel_worker;
167+
create role regress_parallel_worker;
168+
set role regress_parallel_worker;
169+
reset session authorization;
170+
drop role regress_parallel_worker;
171+
set force_parallel_mode=1;
172+
selectcount(*)from tenk1;
173+
reset force_parallel_mode;
174+
reset role;
175+
165176
set force_parallel_mode=1;
166177

167178
explain (costs off)

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp