@@ -99,14 +99,13 @@ typedef struct
9999}trace_request ;
100100
101101static void SendCurrentUserId (void );
102- Oid GetRemoteBackendUserId (PGPROC * proc , int * error_code );
102+ Oid GetRemoteBackendUserId (PGPROC * proc );
103103static void SendWorkerPids (void );
104104List * GetRemoteBackendWorkers (PGPROC * proc ,int * error_code );
105105
106106/* Shared memory variables */
107107shm_toc * toc = NULL ;
108- user_data * caller = NULL ;
109- pg_qs_params * params = NULL ;
108+ pg_qs_params * params = NULL ;
110109trace_request * trace_req = NULL ;
111110shm_mq * mq = NULL ;
112111
@@ -122,11 +121,10 @@ pg_qs_shmem_size()
122121
123122shm_toc_initialize_estimator (& e );
124123
125- nkeys = 4 ;
124+ nkeys = 3 ;
126125
127- shm_toc_estimate_chunk (& e ,sizeof (user_data ));
128- shm_toc_estimate_chunk (& e ,sizeof (pg_qs_params ));
129126shm_toc_estimate_chunk (& e ,sizeof (trace_request ));
127+ shm_toc_estimate_chunk (& e ,sizeof (pg_qs_params ));
130128shm_toc_estimate_chunk (& e , (Size )QUEUE_SIZE );
131129
132130shm_toc_estimate_keys (& e ,nkeys );
@@ -144,30 +142,28 @@ pg_qs_shmem_startup(void)
144142bool found ;
145143Size shmem_size = pg_qs_shmem_size ();
146144void * shmem ;
145+ int num_toc = 0 ;
147146
148147shmem = ShmemInitStruct ("pg_query_state" ,shmem_size ,& found );
149148if (!found )
150149{
151150toc = shm_toc_create (PG_QS_MODULE_KEY ,shmem ,shmem_size );
152151
153- caller = shm_toc_allocate (toc ,sizeof (user_data ));
154- shm_toc_insert (toc ,0 ,caller );
155152params = shm_toc_allocate (toc ,sizeof (pg_qs_params ));
156- shm_toc_insert (toc ,1 ,params );
153+ shm_toc_insert (toc ,num_toc ++ ,params );
157154trace_req = shm_toc_allocate (toc ,sizeof (trace_request ));
158- shm_toc_insert (toc ,2 ,trace_req );
155+ shm_toc_insert (toc ,num_toc ++ ,trace_req );
159156MemSet (trace_req ,0 ,sizeof (trace_request ));
160157mq = shm_toc_allocate (toc ,QUEUE_SIZE );
161- shm_toc_insert (toc ,3 ,mq );
158+ shm_toc_insert (toc ,num_toc ++ ,mq );
162159}
163160else
164161{
165162toc = shm_toc_attach (PG_QS_MODULE_KEY ,shmem );
166163
167- caller = shm_toc_lookup (toc ,0 );
168- params = shm_toc_lookup (toc ,1 );
169- trace_req = shm_toc_lookup (toc ,2 );
170- mq = shm_toc_lookup (toc ,3 );
164+ params = shm_toc_lookup (toc ,num_toc ++ );
165+ trace_req = shm_toc_lookup (toc ,num_toc ++ );
166+ mq = shm_toc_lookup (toc ,num_toc ++ );
171167}
172168
173169if (prev_shmem_startup_hook )
@@ -282,27 +278,6 @@ _PG_fini(void)
282278postExecProcNode_hook = prev_postExecProcNode ;
283279}
284280
285- /*
286- * Find PGPROC entry
287- */
288- static PGPROC *
289- search_proc (int pid )
290- {
291- int i ;
292-
293- if (pid <=0 )
294- return NULL ;
295-
296- for (i = 0 ;i < ProcGlobal -> allProcCount ;i ++ )
297- {
298- PGPROC * proc = & ProcGlobal -> allProcs [i ];
299- if (proc -> pid == pid )
300- return proc ;
301- }
302-
303- return NULL ;
304- }
305-
306281/*
307282 * In trace mode suspend query execution until other backend resumes it
308283 */
@@ -314,7 +289,7 @@ suspend_traceable_query()
314289/* Check whether current backend is traced */
315290if (MyProcPid == trace_req -> traceable )
316291{
317- PGPROC * tracer = search_proc (trace_req -> tracer );
292+ PGPROC * tracer = BackendPidGetProc (trace_req -> tracer );
318293
319294Assert (tracer != NULL );
320295
@@ -587,6 +562,7 @@ pg_query_state(PG_FUNCTION_ARGS)
587562text * format_text = PG_GETARG_TEXT_P (6 );
588563ExplainFormat format ;
589564PGPROC * proc ;
565+ Oid counterpart_user_id ;
590566shm_mq_handle * mqh ;
591567shm_mq_result mq_receive_result ;
592568int send_signal_result ;
@@ -601,7 +577,7 @@ pg_query_state(PG_FUNCTION_ARGS)
601577ereport (ERROR , (errcode (ERRCODE_INVALID_PARAMETER_VALUE ),
602578errmsg ("attempt to extract state of current process" )));
603579
604- proc = search_proc (pid );
580+ proc = BackendPidGetProc (pid );
605581if (!proc || proc -> backendId == InvalidBackendId )
606582ereport (ERROR , (errcode (ERRCODE_INVALID_PARAMETER_VALUE ),
607583errmsg ("backend with pid=%d not found" ,pid )));
@@ -624,9 +600,10 @@ pg_query_state(PG_FUNCTION_ARGS)
624600init_lock_tag (& tag ,PG_QUERY_STATE_KEY );
625601LockAcquire (& tag ,ExclusiveLock , false, false);
626602
627- /* fill in caller's user data */
628- caller -> user_id = GetUserId ();
629- caller -> superuser = superuser ();
603+ counterpart_user_id = GetRemoteBackendUserId (proc );
604+ if (!(superuser ()|| GetUserId ()== counterpart_user_id ))
605+ ereport (ERROR , (errcode (ERRCODE_INSUFFICIENT_PRIVILEGE ),
606+ errmsg ("permission denied" )));
630607
631608/* fill in parameters of query state request */
632609params -> verbose = verbose ;
@@ -673,9 +650,6 @@ pg_query_state(PG_FUNCTION_ARGS)
673650LockRelease (& tag ,ExclusiveLock , false);
674651SRF_RETURN_DONE (funcctx );
675652}
676- case PERM_DENIED :
677- ereport (ERROR , (errcode (ERRCODE_INSUFFICIENT_PRIVILEGE ),
678- errmsg ("permission denied" )));
679653case STAT_DISABLED :
680654elog (INFO ,"query execution statistics disabled" );
681655LockRelease (& tag ,ExclusiveLock , false);
@@ -769,7 +743,7 @@ exec_trace_cmd(pid_t pid, trace_cmd cmd)
769743ereport (ERROR , (errcode (ERRCODE_INVALID_PARAMETER_VALUE ),
770744errmsg ("attempt to trace self process" )));
771745
772- proc = search_proc (pid );
746+ proc = BackendPidGetProc (pid );
773747if (!proc || proc -> backendId == InvalidBackendId )
774748ereport (ERROR , (errcode (ERRCODE_INVALID_PARAMETER_VALUE ),
775749errmsg ("backend with pid=%d not found" ,pid )));
@@ -872,39 +846,35 @@ SendCurrentUserId(void)
872846#define COULD_NOT_SEND_SIGNAL 2
873847#define INVALID_MQ_READ 3
874848
849+ /*
850+ * Extract effective user id of external backend session
851+ * Assume `proc` is valid backend and doesn't point to current process
852+ */
875853Oid
876- GetRemoteBackendUserId (PGPROC * proc , int * error_code )
854+ GetRemoteBackendUserId (PGPROC * proc )
877855{
878856int sig_result ;
879857shm_mq_handle * mqh ;
880858shm_mq_result mq_receive_result ;
881859Oid * result ;
882860Size res_len ;
883861
884- if (proc -> backendId == InvalidBackendId )
885- {
886- * error_code = NOT_BACKEND_PROCESS ;
887- return InvalidOid ;
888- }
862+ Assert (proc && proc != MyProc && proc -> backendId != InvalidBackendId );
889863
890864mq = shm_mq_create (mq ,QUEUE_SIZE );
891865shm_mq_set_sender (mq ,proc );
892866shm_mq_set_receiver (mq ,MyProc );
893867
894868sig_result = SendProcSignal (proc -> pid ,RolePollReason ,proc -> backendId );
895869if (sig_result == -1 )
896- {
897- * error_code = COULD_NOT_SEND_SIGNAL ;
898- return InvalidOid ;
899- }
870+ ereport (ERROR , (errcode (ERRCODE_INTERNAL_ERROR ),
871+ errmsg ("invalid send signal" )));
900872
901873mqh = shm_mq_attach (mq ,NULL ,NULL );
902874mq_receive_result = shm_mq_receive_with_timeout (mqh ,& res_len , (void * * )& result ,1000 );
903875if (mq_receive_result != SHM_MQ_SUCCESS )
904- {
905- * error_code = INVALID_MQ_READ ;
906- return InvalidOid ;
907- }
876+ ereport (ERROR , (errcode (ERRCODE_INTERNAL_ERROR ),
877+ errmsg ("invalid read from message queue" )));
908878
909879shm_mq_detach (mq );
910880
@@ -991,7 +961,7 @@ GetRemoteBackendWorkers(PGPROC *proc, int *error_code)
991961if (proc -> backendId == InvalidBackendId )
992962{
993963* error_code = NOT_BACKEND_PROCESS ;
994- return InvalidOid ;
964+ return NIL ;
995965}
996966
997967mq = shm_mq_create (mq ,QUEUE_SIZE );
@@ -1002,15 +972,15 @@ GetRemoteBackendWorkers(PGPROC *proc, int *error_code)
1002972if (sig_result == -1 )
1003973{
1004974* error_code = COULD_NOT_SEND_SIGNAL ;
1005- return InvalidOid ;
975+ return NIL ;
1006976}
1007977
1008978mqh = shm_mq_attach (mq ,NULL ,NULL );
1009979mq_receive_result = shm_mq_receive_with_timeout (mqh ,& msg_len , (void * * )& msg ,1000 );
1010980if (mq_receive_result != SHM_MQ_SUCCESS )
1011981{
1012982* error_code = INVALID_MQ_READ ;
1013- return InvalidOid ;
983+ return NIL ;
1014984}
1015985
1016986for (i = 0 ;i < msg -> num ;i ++ )