@@ -149,6 +149,111 @@ get_next_observation(History *observations)
149149return result ;
150150}
151151
152+ static void
153+ fill_dimensions (SamplingDimensions * dimensions ,PGPROC * proc ,
154+ int pid ,uint32 wait_event_info ,uint64 queryId ,
155+ int dimensions_mask )
156+ {
157+ Oid role_id = proc -> roleId ;
158+ Oid database_id = proc -> databaseId ;
159+ PGPROC * lockGroupLeader = proc -> lockGroupLeader ;
160+ bool is_regular_backend = proc -> isRegularBackend ;
161+
162+ dimensions -> pid = pid ;
163+
164+ dimensions -> wait_event_info = wait_event_info ;
165+
166+ if (pgws_profileQueries )
167+ dimensions -> queryId = queryId ;
168+
169+ /* Copy everything we need from PGPROC */
170+ if (dimensions_mask & PGWS_DIMENSIONS_ROLE_ID )
171+ dimensions -> role_id = role_id ;
172+
173+ if (dimensions_mask & PGWS_DIMENSIONS_DB_ID )
174+ dimensions -> database_id = database_id ;
175+
176+ if (dimensions_mask & PGWS_DIMENSIONS_PARALLEL_LEADER_PID )
177+ dimensions -> parallel_leader_pid = (lockGroupLeader ?
178+ lockGroupLeader -> pid :
179+ 0 );
180+
181+ if (dimensions_mask & PGWS_DIMENSIONS_IS_REGULAR_BE )
182+ dimensions -> is_regular_backend = is_regular_backend ;
183+
184+ /* Look into BackendStatus only if necessary */
185+ if (check_bestatus_dimensions (dimensions_mask ))
186+ {
187+ #if PG_VERSION_NUM >=170000
188+ PgBackendStatus * bestatus = pgstat_get_beentry_by_proc_number (GetNumberFromPGProc (proc ));
189+ #else
190+ PgBackendStatus * bestatus = get_beentry_by_procpid (proc -> pid );
191+ #endif
192+ /* Copy everything we need from BackendStatus */
193+ if (bestatus )
194+ {
195+ if (dimensions_mask & PGWS_DIMENSIONS_BE_TYPE )
196+ dimensions -> backend_type = bestatus -> st_backendType ;
197+
198+ if (dimensions_mask & PGWS_DIMENSIONS_BE_STATE )
199+ dimensions -> backend_state = bestatus -> st_state ;
200+
201+ if (dimensions_mask & PGWS_DIMENSIONS_BE_START_TIME )
202+ dimensions -> proc_start = bestatus -> st_proc_start_timestamp ;
203+
204+ if (dimensions_mask & PGWS_DIMENSIONS_CLIENT_ADDR )
205+ dimensions -> client_addr = bestatus -> st_clientaddr ;
206+
207+ if (dimensions_mask & PGWS_DIMENSIONS_CLIENT_HOSTNAME )
208+ strcpy (dimensions -> client_hostname ,bestatus -> st_clienthostname );
209+
210+ if (dimensions_mask & PGWS_DIMENSIONS_APPNAME )
211+ strcpy (dimensions -> appname ,bestatus -> st_appname );
212+ }
213+ }
214+ }
215+
216+ static void
217+ copy_dimensions (SamplingDimensions * dst ,SamplingDimensions * src ,
218+ int dst_dimensions_mask )
219+ {
220+ dst -> pid = src -> pid ;
221+
222+ dst -> wait_event_info = src -> wait_event_info ;
223+
224+ dst -> queryId = src -> queryId ;
225+
226+ if (dst_dimensions_mask & PGWS_DIMENSIONS_ROLE_ID )
227+ dst -> role_id = src -> role_id ;
228+
229+ if (dst_dimensions_mask & PGWS_DIMENSIONS_DB_ID )
230+ dst -> database_id = src -> database_id ;
231+
232+ if (dst_dimensions_mask & PGWS_DIMENSIONS_PARALLEL_LEADER_PID )
233+ dst -> parallel_leader_pid = src -> parallel_leader_pid ;
234+
235+ if (dst_dimensions_mask & PGWS_DIMENSIONS_IS_REGULAR_BE )
236+ dst -> is_regular_backend = src -> is_regular_backend ;
237+
238+ if (dst_dimensions_mask & PGWS_DIMENSIONS_BE_TYPE )
239+ dst -> backend_type = src -> backend_type ;
240+
241+ if (dst_dimensions_mask & PGWS_DIMENSIONS_BE_STATE )
242+ dst -> backend_state = src -> backend_state ;
243+
244+ if (dst_dimensions_mask & PGWS_DIMENSIONS_BE_START_TIME )
245+ dst -> proc_start = src -> proc_start ;
246+
247+ if (dst_dimensions_mask & PGWS_DIMENSIONS_CLIENT_ADDR )
248+ dst -> client_addr = src -> client_addr ;
249+
250+ if (dst_dimensions_mask & PGWS_DIMENSIONS_CLIENT_HOSTNAME )
251+ strcpy (dst -> client_hostname ,src -> client_hostname );
252+
253+ if (dst_dimensions_mask & PGWS_DIMENSIONS_APPNAME )
254+ strcpy (dst -> appname ,src -> appname );
255+ }
256+
152257/*
153258 * Read current waits from backends and write them to history array
154259 * and/or profile hash.
@@ -176,92 +281,34 @@ probe_waits(History *observations, HTAB *profile_hash,
176281PGPROC * proc = & ProcGlobal -> allProcs [i ];
177282int pid ;
178283uint32 wait_event_info ;
284+ SamplingDimensions common_dimensions ;
285+ int dimensions_mask_common = pgws_history_dimensions |
286+ pgws_profile_dimensions ;
179287
180288/* Check if we need to sample this process */
181289if (!pgws_should_sample_proc (proc ,& pid ,& wait_event_info ))
182290continue ;
183291
184- /* We zero whole HistoryItem to avoid doing it field-by-field */
292+ /*
293+ * We zero items and dimensions with memset
294+ * to avoid doing it field-by-field
295+ */
185296memset (& item_history ,0 ,sizeof (HistoryItem ));
186297memset (& item_profile ,0 ,sizeof (ProfileItem ));
298+ memset (& common_dimensions ,0 ,sizeof (SamplingDimensions ));
187299
188- item_history . pid = pid ;
189- item_profile . pid = pid ;
300+ fill_dimensions ( & common_dimensions , proc , pid , wait_event_info ,
301+ pgws_proc_queryids [ i ], dimensions_mask_common ) ;
190302
191- item_history .wait_event_info = wait_event_info ;
192- item_profile .wait_event_info = wait_event_info ;
193-
194- if (pgws_profileQueries )
195- {
196- item_history .queryId = pgws_proc_queryids [i ];
197- item_profile .queryId = pgws_proc_queryids [i ];
198- }
303+ copy_dimensions (& item_history .dimensions ,
304+ & common_dimensions ,
305+ pgws_history_dimensions );
306+ copy_dimensions (& item_history .dimensions ,
307+ & common_dimensions ,
308+ pgws_profile_dimensions );
199309
200310item_history .ts = ts ;
201311
202- /* Copy everything we need from PGPROC */
203- if (pgws_history_dimensions & PGWS_DIMENSIONS_ROLE_ID )
204- item_history .role_id = proc -> roleId ;
205- if (pgws_profile_dimensions & PGWS_DIMENSIONS_ROLE_ID )
206- item_profile .role_id = proc -> roleId ;
207-
208- if (pgws_history_dimensions & PGWS_DIMENSIONS_DB_ID )
209- item_history .database_id = proc -> databaseId ;
210- if (pgws_profile_dimensions & PGWS_DIMENSIONS_DB_ID )
211- item_profile .database_id = proc -> databaseId ;
212-
213- if (pgws_history_dimensions & PGWS_DIMENSIONS_PARALLEL_LEADER_PID )
214- item_history .parallel_leader_pid = (proc -> lockGroupLeader ?
215- proc -> lockGroupLeader -> pid :
216- 0 );
217- if (pgws_profile_dimensions & PGWS_DIMENSIONS_PARALLEL_LEADER_PID )
218- item_profile .parallel_leader_pid = (proc -> lockGroupLeader ?
219- proc -> lockGroupLeader -> pid :
220- 0 );
221- /* Look into BackendStatus only if necessary */
222- if (check_bestatus_dimensions (pgws_history_dimensions )||
223- check_bestatus_dimensions (pgws_profile_dimensions ))
224- {
225- #if PG_VERSION_NUM >=170000
226- PgBackendStatus * bestatus = pgstat_get_beentry_by_proc_number (GetNumberFromPGProc (proc ));
227- #else
228- PgBackendStatus * bestatus = get_beentry_by_procpid (proc -> pid );
229- #endif
230- /* Copy everything we need from BackendStatus */
231- if (bestatus )
232- {
233- if (pgws_history_dimensions & PGWS_DIMENSIONS_BE_TYPE )
234- item_history .backend_type = bestatus -> st_backendType ;
235- if (pgws_profile_dimensions & PGWS_DIMENSIONS_BE_TYPE )
236- item_profile .backend_type = bestatus -> st_backendType ;
237-
238- if (pgws_history_dimensions & PGWS_DIMENSIONS_BE_STATE )
239- item_history .backend_state = bestatus -> st_state ;
240- if (pgws_profile_dimensions & PGWS_DIMENSIONS_BE_STATE )
241- item_profile .backend_state = bestatus -> st_state ;
242-
243- if (pgws_history_dimensions & PGWS_DIMENSIONS_BE_START_TIME )
244- item_history .proc_start = bestatus -> st_proc_start_timestamp ;
245- if (pgws_profile_dimensions & PGWS_DIMENSIONS_BE_START_TIME )
246- item_profile .proc_start = bestatus -> st_proc_start_timestamp ;
247-
248- if (pgws_history_dimensions & PGWS_DIMENSIONS_CLIENT_ADDR )
249- item_history .client_addr = bestatus -> st_clientaddr ;
250- if (pgws_profile_dimensions & PGWS_DIMENSIONS_CLIENT_ADDR )
251- item_profile .client_addr = bestatus -> st_clientaddr ;
252-
253- if (pgws_history_dimensions & PGWS_DIMENSIONS_CLIENT_HOSTNAME )
254- strcpy (item_history .client_hostname ,bestatus -> st_clienthostname );
255- if (pgws_profile_dimensions & PGWS_DIMENSIONS_CLIENT_HOSTNAME )
256- strcpy (item_profile .client_hostname ,bestatus -> st_clienthostname );
257-
258- if (pgws_history_dimensions & PGWS_DIMENSIONS_APPNAME )
259- strcpy (item_history .appname ,bestatus -> st_appname );
260- if (pgws_profile_dimensions & PGWS_DIMENSIONS_APPNAME )
261- strcpy (item_profile .appname ,bestatus -> st_appname );
262- }
263- }
264-
265312/* Write to the history if needed */
266313if (write_history )
267314{
@@ -276,9 +323,10 @@ probe_waits(History *observations, HTAB *profile_hash,
276323bool found ;
277324
278325if (!profile_pid )
279- item_profile .pid = 0 ;
326+ item_profile .dimensions . pid = 0 ;
280327
281- profileItem = (ProfileItem * )hash_search (profile_hash ,& item_profile ,HASH_ENTER ,& found );
328+ profileItem = (ProfileItem * )hash_search (profile_hash ,& item_profile ,
329+ HASH_ENTER ,& found );
282330if (found )
283331profileItem -> count ++ ;
284332else
@@ -379,11 +427,11 @@ make_profile_hash()
379427HASHCTL hash_ctl ;
380428
381429/*
382- * Since adding additional dimensions weinclude everyting except count
383- *into hashtable key. This is fine for cases when some fields are 0 since
430+ * Since adding additional dimensions weuse SamplingDimensions as
431+ * hashtable key. This is fine for cases when some fields are 0 since
384432 * it doesn't impede our ability to search the hash table for entries
385433 */
386- hash_ctl .keysize = offsetof( ProfileItem , count );
434+ hash_ctl .keysize = sizeof ( SamplingDimensions );
387435
388436hash_ctl .entrysize = sizeof (ProfileItem );
389437return hash_create ("Waits profile hash" ,1024 ,& hash_ctl ,