22 * pg_wait_sampling.c
33 * Track information about wait events.
44 *
5- * Copyright (c) 2015-2025 , Postgres Professional
5+ * Copyright (c) 2015-2026 , Postgres Professional
66 *
77 * IDENTIFICATION
88 * contrib/pg_wait_sampling/pg_wait_sampling.c
@@ -75,9 +75,7 @@ static shmem_request_hook_type prev_shmem_request_hook = NULL;
7575static shmem_startup_hook_type prev_shmem_startup_hook = NULL ;
7676static PGPROC * search_proc (int backendPid );
7777static PlannedStmt * pgws_planner_hook (Query * parse ,
78- #if PG_VERSION_NUM >= 130000
7978 const char * query_string ,
80- #endif
8179 int cursorOptions , ParamListInfo boundParams
8280#if PG_VERSION_NUM >= 190000
8381 , ExplainState * es
@@ -87,26 +85,20 @@ static void pgws_ExecutorStart(QueryDesc *queryDesc, int eflags);
8785static void pgws_ExecutorRun (QueryDesc * queryDesc ,
8886 ScanDirection direction ,
8987 uint64 count
90- #if PG_VERSION_NUM >= 100000 && PG_VERSION_NUM < 180000
88+ #if PG_VERSION_NUM < 180000
9189 ,bool execute_once
9290#endif
9391);
9492static void pgws_ExecutorFinish (QueryDesc * queryDesc );
9593static void pgws_ExecutorEnd (QueryDesc * queryDesc );
9694static void pgws_ProcessUtility (PlannedStmt * pstmt ,
9795 const char * queryString ,
98- #if PG_VERSION_NUM >= 140000
9996 bool readOnlyTree ,
100- #endif
10197 ProcessUtilityContext context ,
10298 ParamListInfo params ,
10399 QueryEnvironment * queryEnv ,
104100 DestReceiver * dest ,
105- #if PG_VERSION_NUM >= 130000
106101 QueryCompletion * qc
107- #else
108- char * completionTag
109- #endif
110102);
111103
112104/*---- GUC variables ----*/
@@ -654,6 +646,16 @@ receive_array(SHMRequest request, Size item_size, Size *count)
654646 char * ptr ;
655647 MemoryContext oldctx ;
656648
649+ /* Check that the collector was started to avoid NULL pointer dereference */
650+ if (!pgws_collector_hdr -> latch )
651+ ereport (ERROR , (errcode (ERRCODE_INTERNAL_ERROR ),
652+ errmsg ("pg_wait_sampling collector wasn't started" )));
653+
654+ /* Check that the collector exists to avoid getting stuck in shm_mq_receive */
655+ if (pgws_collector_hdr -> latch -> owner_pid == 0 )
656+ ereport (ERROR , (errcode (ERRCODE_INTERNAL_ERROR ),
657+ errmsg ("pg_wait_sampling collector doesn't exist" )));
658+
657659 /* Ensure nobody else trying to send request to queue */
658660 pgws_init_lock_tag (& queueTag , PGWS_QUEUE_LOCK );
659661 LockAcquire (& queueTag , ExclusiveLock , false, false);
@@ -664,19 +666,6 @@ receive_array(SHMRequest request, Size item_size, Size *count)
664666 pgws_collector_hdr -> request = request ;
665667 LockRelease (& collectorTag , ExclusiveLock , false);
666668
667- /*
668- * Check that the collector was started to avoid NULL
669- * pointer dereference.
670- */
671- if (!pgws_collector_hdr -> latch )
672- ereport (ERROR , (errcode (ERRCODE_INTERNAL_ERROR ),
673- errmsg ("pg_wait_sampling collector wasn't started" )));
674-
675- /* Check that the collector exists to avoid getting stuck in shm_mq_receive */
676- if (pgws_collector_hdr -> latch -> owner_pid == 0 )
677- ereport (ERROR , (errcode (ERRCODE_INTERNAL_ERROR ),
678- errmsg ("pg_wait_sampling collector doesn't exist" )));
679-
680669 SetLatch (pgws_collector_hdr -> latch );
681670
682671 shm_mq_set_receiver (recv_mq , MyProc );
@@ -837,6 +826,16 @@ pg_wait_sampling_reset_profile(PG_FUNCTION_ARGS)
837826
838827 check_shmem ();
839828
829+ /* Check that the collector was started to avoid NULL pointer dereference */
830+ if (!pgws_collector_hdr -> latch )
831+ ereport (ERROR , (errcode (ERRCODE_INTERNAL_ERROR ),
832+ errmsg ("pg_wait_sampling collector wasn't started" )));
833+
834+ /* Check that the collector exists to avoid setting pgws_collector_hdr->request */
835+ if (pgws_collector_hdr -> latch -> owner_pid == 0 )
836+ ereport (ERROR , (errcode (ERRCODE_INTERNAL_ERROR ),
837+ errmsg ("pg_wait_sampling collector doesn't exist" )));
838+
840839 pgws_init_lock_tag (& queueTag , PGWS_QUEUE_LOCK );
841840
842841 LockAcquire (& queueTag , ExclusiveLock , false, false);
@@ -846,14 +845,6 @@ pg_wait_sampling_reset_profile(PG_FUNCTION_ARGS)
846845 pgws_collector_hdr -> request = PROFILE_RESET ;
847846 LockRelease (& collectorTag , ExclusiveLock , false);
848847
849- /*
850- * Check that the collector was started to avoid NULL
851- * pointer dereference.
852- */
853- if (!pgws_collector_hdr -> latch )
854- ereport (ERROR , (errcode (ERRCODE_INTERNAL_ERROR ),
855- errmsg ("pg_wait_sampling collector wasn't started" )));
856-
857848 SetLatch (pgws_collector_hdr -> latch );
858849
859850 LockRelease (& queueTag , ExclusiveLock , false);
@@ -959,9 +950,7 @@ pg_wait_sampling_get_history(PG_FUNCTION_ARGS)
959950 */
960951static PlannedStmt *
961952pgws_planner_hook (Query * parse ,
962- #if PG_VERSION_NUM >= 130000
963953 const char * query_string ,
964- #endif
965954 int cursorOptions ,
966955 ParamListInfo boundParams
967956#if PG_VERSION_NUM >= 190000
@@ -985,19 +974,15 @@ pgws_planner_hook(Query *parse,
985974 /* Invoke original hook if needed */
986975 if (planner_hook_next )
987976 result = planner_hook_next (parse ,
988- #if PG_VERSION_NUM >= 130000
989977 query_string ,
990- #endif
991978 cursorOptions , boundParams
992979#if PG_VERSION_NUM >= 190000
993980 , es
994981#endif
995982 );
996983 else
997984 result = standard_planner (parse ,
998- #if PG_VERSION_NUM >= 130000
999985 query_string ,
1000- #endif
1001986 cursorOptions , boundParams
1002987#if PG_VERSION_NUM >= 190000
1003988 , es
@@ -1043,7 +1028,7 @@ static void
10431028pgws_ExecutorRun (QueryDesc * queryDesc ,
10441029 ScanDirection direction ,
10451030 uint64 count
1046- #if PG_VERSION_NUM >= 100000 && PG_VERSION_NUM < 180000
1031+ #if PG_VERSION_NUM < 180000
10471032 ,bool execute_once
10481033#endif
10491034)
@@ -1055,16 +1040,16 @@ pgws_ExecutorRun(QueryDesc *queryDesc,
10551040 PG_TRY ();
10561041 {
10571042 if (prev_ExecutorRun )
1058- #if PG_VERSION_NUM >= 100000 && PG_VERSION_NUM < 180000
1059- prev_ExecutorRun (queryDesc , direction , count , execute_once );
1060- #else
1043+ #if PG_VERSION_NUM >= 180000
10611044 prev_ExecutorRun (queryDesc , direction , count );
1045+ #else
1046+ prev_ExecutorRun (queryDesc , direction , count , execute_once );
10621047#endif
10631048 else
1064- #if PG_VERSION_NUM >= 100000 && PG_VERSION_NUM < 180000
1065- standard_ExecutorRun (queryDesc , direction , count , execute_once );
1066- #else
1049+ #if PG_VERSION_NUM >= 180000
10671050 standard_ExecutorRun (queryDesc , direction , count );
1051+ #else
1052+ standard_ExecutorRun (queryDesc , direction , count , execute_once );
10681053#endif
10691054 nesting_level -- ;
10701055 if (nesting_level == 0 )
@@ -1132,18 +1117,12 @@ pgws_ExecutorEnd(QueryDesc *queryDesc)
11321117static void
11331118pgws_ProcessUtility (PlannedStmt * pstmt ,
11341119 const char * queryString ,
1135- #if PG_VERSION_NUM >= 140000
11361120 bool readOnlyTree ,
1137- #endif
11381121 ProcessUtilityContext context ,
11391122 ParamListInfo params ,
11401123 QueryEnvironment * queryEnv ,
11411124 DestReceiver * dest ,
1142- #if PG_VERSION_NUM >= 130000
11431125 QueryCompletion * qc
1144- #else
1145- char * completionTag
1146- #endif
11471126)
11481127{
11491128 int i = MyProc - ProcGlobal -> allProcs ;
@@ -1160,30 +1139,16 @@ pgws_ProcessUtility(PlannedStmt *pstmt,
11601139 {
11611140 if (prev_ProcessUtility )
11621141 prev_ProcessUtility (pstmt , queryString ,
1163- #if PG_VERSION_NUM >= 140000
11641142 readOnlyTree ,
1165- #endif
11661143 context , params , queryEnv ,
11671144 dest ,
1168- #if PG_VERSION_NUM >= 130000
1169- qc
1170- #else
1171- completionTag
1172- #endif
1173- );
1145+ qc );
11741146 else
11751147 standard_ProcessUtility (pstmt , queryString ,
1176- #if PG_VERSION_NUM >= 140000
11771148 readOnlyTree ,
1178- #endif
11791149 context , params , queryEnv ,
11801150 dest ,
1181- #if PG_VERSION_NUM >= 130000
1182- qc
1183- #else
1184- completionTag
1185- #endif
1186- );
1151+ qc );
11871152 nesting_level -- ;
11881153 if (nesting_level == 0 )
11891154 pgws_proc_queryids [i ] = UINT64CONST (0 );
0 commit comments