@@ -202,18 +202,9 @@ static void pgsm_add_to_list(pgsmEntry *entry, char *query_text, int query_len);
202202static void pgsm_delete_entry (uint64 queryid );
203203static pgsmEntry * pgsm_get_entry_for_query (int64 queryid , PlanInfo * plan_info , const char * query_text , int query_len , bool create , CmdType cmd_type );
204204static int64 get_pgsm_query_id_hash (const char * norm_query , int len );
205-
206- static void pgsm_cleanup_callback (void * arg );
205+ static void pgsm_cleanup_memory (void );
207206static void pgsm_store_error (const char * query , ErrorData * edata );
208207
209- /*---- Local variables ----*/
210- static MemoryContextCallback mem_cxt_reset_callback =
211- {
212- .func = pgsm_cleanup_callback ,
213- .arg = NULL
214- };
215- static volatile bool callback_setup = false;
216-
217208static void pgsm_update_entry (pgsmEntry * entry ,
218209 const char * query ,
219210 char * comments ,
@@ -389,19 +380,6 @@ pgsm_post_parse_analyze_internal(ParseState *pstate, Query *query, JumbleState *
389380 if (!IsSystemInitialized ())
390381 return ;
391382
392- if (callback_setup == false)
393- {
394- /*
395- * If MessageContext is valid setup a callback to cleanup our local
396- * stats list when the MessagContext gets reset
397- */
398- if (MemoryContextIsValid (MessageContext ))
399- {
400- MemoryContextRegisterResetCallback (MessageContext , & mem_cxt_reset_callback );
401- callback_setup = true;
402- }
403- }
404-
405383 if (!pgsm_enabled (nesting_level ))
406384 return ;
407385
@@ -757,6 +735,15 @@ pgsm_ExecutorEnd(QueryDesc *queryDesc)
757735 pgsm_delete_entry (queryDesc -> plannedstmt -> queryId );
758736
759737 num_relations = 0 ;
738+
739+ #if PG_VERSION_NUM >= 170000
740+ if (nesting_level == 0 )
741+ #else
742+ if ((nesting_level + plan_nested_level ) == 0 )
743+ #endif
744+ {
745+ pgsm_cleanup_memory ();
746+ }
760747}
761748
762749static bool
@@ -1013,175 +1000,192 @@ pgsm_ProcessUtility(PlannedStmt *pstmt, const char *queryString,
10131000 *
10141001 * Likewise, we don't track execution of DEALLOCATE.
10151002 */
1016- if (enabled &&
1017- !IsA (parsetree , ExecuteStmt ) &&
1018- !IsA (parsetree , PrepareStmt ) &&
1019- !IsA (parsetree , DeallocateStmt ))
1003+ PG_TRY ();
10201004 {
1021- pgsmEntry * entry ;
1022- char * query_text ;
1023- int location ;
1024- int query_len ;
1025- instr_time start ;
1026- instr_time duration ;
1027- uint64 rows ;
1028- SysInfo sys_info ;
1029- BufferUsage bufusage ;
1030- BufferUsage bufusage_start = pgBufferUsage ;
1031- WalUsage walusage ;
1032- WalUsage walusage_start = pgWalUsage ;
1033-
1034- if (getrusage (RUSAGE_SELF , & rusage_start ) != 0 )
1035- elog (DEBUG1 , "[pg_stat_monitor] pgsm_ProcessUtility: Failed to execute getrusage." );
1036-
1037- INSTR_TIME_SET_CURRENT (start );
1038- nesting_level ++ ;
1039-
1040- PG_TRY ();
1005+ if (enabled &&
1006+ !IsA (parsetree , ExecuteStmt ) &&
1007+ !IsA (parsetree , PrepareStmt ) &&
1008+ !IsA (parsetree , DeallocateStmt ))
10411009 {
1042- if (prev_ProcessUtility )
1043- prev_ProcessUtility (pstmt , queryString ,
1044- readOnlyTree ,
1045- context , params , queryEnv ,
1046- dest ,
1047- qc );
1048- else
1049- standard_ProcessUtility (pstmt , queryString ,
1010+ pgsmEntry * entry ;
1011+ char * query_text ;
1012+ int location ;
1013+ int query_len ;
1014+ instr_time start ;
1015+ instr_time duration ;
1016+ uint64 rows ;
1017+ SysInfo sys_info ;
1018+ BufferUsage bufusage ;
1019+ BufferUsage bufusage_start = pgBufferUsage ;
1020+ WalUsage walusage ;
1021+ WalUsage walusage_start = pgWalUsage ;
1022+
1023+ if (getrusage (RUSAGE_SELF , & rusage_start ) != 0 )
1024+ elog (DEBUG1 , "[pg_stat_monitor] pgsm_ProcessUtility: Failed to execute getrusage." );
1025+
1026+ INSTR_TIME_SET_CURRENT (start );
1027+ nesting_level ++ ;
1028+
1029+ PG_TRY (1 );
1030+ {
1031+ if (prev_ProcessUtility )
1032+ prev_ProcessUtility (pstmt , queryString ,
10501033 readOnlyTree ,
10511034 context , params , queryEnv ,
10521035 dest ,
10531036 qc );
1054- nesting_level -- ;
1055- }
1056- PG_CATCH ();
1057- {
1058- nesting_level -- ;
1059- PG_RE_THROW ();
1060- }
1037+ else
1038+ standard_ProcessUtility (pstmt , queryString ,
1039+ readOnlyTree ,
1040+ context , params , queryEnv ,
1041+ dest ,
1042+ qc );
1043+ nesting_level -- ;
1044+ }
1045+ PG_CATCH (1 );
1046+ {
1047+ nesting_level -- ;
1048+ PG_RE_THROW ();
1049+ }
10611050
1062- sys_info .utime = 0 ;
1063- sys_info .stime = 0 ;
1051+ sys_info .utime = 0 ;
1052+ sys_info .stime = 0 ;
10641053
1065- PG_END_TRY ();
1054+ PG_END_TRY (1 );
10661055
1067- if (getrusage (RUSAGE_SELF , & rusage_end ) != 0 )
1068- elog (DEBUG1 , "[pg_stat_monitor] pgsm_ProcessUtility: Failed to execute getrusage." );
1069- else
1070- {
1071- sys_info .utime = time_diff (rusage_end .ru_utime , rusage_start .ru_utime );
1072- sys_info .stime = time_diff (rusage_end .ru_stime , rusage_start .ru_stime );
1073- }
1056+ if (getrusage (RUSAGE_SELF , & rusage_end ) != 0 )
1057+ elog (DEBUG1 , "[pg_stat_monitor] pgsm_ProcessUtility: Failed to execute getrusage." );
1058+ else
1059+ {
1060+ sys_info .utime = time_diff (rusage_end .ru_utime , rusage_start .ru_utime );
1061+ sys_info .stime = time_diff (rusage_end .ru_stime , rusage_start .ru_stime );
1062+ }
10741063
1075- INSTR_TIME_SET_CURRENT (duration );
1076- INSTR_TIME_SUBTRACT (duration , start );
1064+ INSTR_TIME_SET_CURRENT (duration );
1065+ INSTR_TIME_SUBTRACT (duration , start );
10771066
1078- rows = (qc && (qc -> commandTag == CMDTAG_COPY ||
1079- qc -> commandTag == CMDTAG_FETCH ||
1080- qc -> commandTag == CMDTAG_SELECT ||
1081- qc -> commandTag == CMDTAG_REFRESH_MATERIALIZED_VIEW ))
1082- ? qc -> nprocessed
1083- : 0 ;
1067+ rows = (qc && (qc -> commandTag == CMDTAG_COPY ||
1068+ qc -> commandTag == CMDTAG_FETCH ||
1069+ qc -> commandTag == CMDTAG_SELECT ||
1070+ qc -> commandTag == CMDTAG_REFRESH_MATERIALIZED_VIEW ))
1071+ ? qc -> nprocessed
1072+ : 0 ;
10841073
1085- /* calc differences of WAL counters. */
1086- memset (& walusage , 0 , sizeof (WalUsage ));
1087- WalUsageAccumDiff (& walusage , & pgWalUsage , & walusage_start );
1074+ /* calc differences of WAL counters. */
1075+ memset (& walusage , 0 , sizeof (WalUsage ));
1076+ WalUsageAccumDiff (& walusage , & pgWalUsage , & walusage_start );
10881077
1089- /* calc differences of buffer counters. */
1090- memset (& bufusage , 0 , sizeof (BufferUsage ));
1091- BufferUsageAccumDiff (& bufusage , & pgBufferUsage , & bufusage_start );
1078+ /* calc differences of buffer counters. */
1079+ memset (& bufusage , 0 , sizeof (BufferUsage ));
1080+ BufferUsageAccumDiff (& bufusage , & pgBufferUsage , & bufusage_start );
10921081
1093- /* Create an entry for this query */
1094- entry = pgsm_create_hash_entry (0 , queryId , NULL );
1082+ /* Create an entry for this query */
1083+ entry = pgsm_create_hash_entry (0 , queryId , NULL );
10951084
1096- location = pstmt -> stmt_location ;
1097- query_len = pstmt -> stmt_len ;
1098- query_text = (char * ) CleanQuerytext (queryString , & location , & query_len );
1085+ location = pstmt -> stmt_location ;
1086+ query_len = pstmt -> stmt_len ;
1087+ query_text = (char * ) CleanQuerytext (queryString , & location , & query_len );
10991088
1100- entry -> pgsm_query_id = get_pgsm_query_id_hash (query_text , query_len );
1101- entry -> counters .info .cmd_type = pstmt -> commandType ;
1089+ entry -> pgsm_query_id = get_pgsm_query_id_hash (query_text , query_len );
1090+ entry -> counters .info .cmd_type = pstmt -> commandType ;
11021091
1103- pgsm_add_to_list (entry , query_text , query_len );
1092+ pgsm_add_to_list (entry , query_text , query_len );
11041093
1105- /* Check that we've not exceeded max_stack_depth */
1106- Assert (list_length (lentries ) <= max_stack_depth );
1094+ /* Check that we've not exceeded max_stack_depth */
1095+ Assert (list_length (lentries ) <= max_stack_depth );
11071096
1108- /* The plan details are captured when the query finishes */
1109- pgsm_update_entry (entry , /* entry */
1110- (char * ) query_text , /* query */
1111- NULL , /* comments */
1112- 0 , /* comments length */
1113- NULL , /* PlanInfo */
1114- & sys_info , /* SysInfo */
1115- NULL , /* ErrorInfo */
1116- 0 , /* plan_total_time */
1117- INSTR_TIME_GET_MILLISEC (duration ), /* exec_total_time */
1118- rows , /* rows */
1119- & bufusage , /* bufusage */
1120- & walusage , /* walusage */
1121- NULL , /* jitusage */
1122- 0 , /* parallel_workers_to_launch */
1123- 0 , /* parallel_workers_launched */
1124- false, /* reset */
1125- PGSM_EXEC ); /* kind */
1097+ /* The plan details are captured when the query finishes */
1098+ pgsm_update_entry (entry , /* entry */
1099+ (char * ) query_text , /* query */
1100+ NULL , /* comments */
1101+ 0 , /* comments length */
1102+ NULL , /* PlanInfo */
1103+ & sys_info , /* SysInfo */
1104+ NULL , /* ErrorInfo */
1105+ 0 , /* plan_total_time */
1106+ INSTR_TIME_GET_MILLISEC (duration ), /* exec_total_time */
1107+ rows , /* rows */
1108+ & bufusage , /* bufusage */
1109+ & walusage , /* walusage */
1110+ NULL , /* jitusage */
1111+ 0 , /* parallel_workers_to_launch */
1112+ 0 , /* parallel_workers_launched */
1113+ false, /* reset */
1114+ PGSM_EXEC ); /* kind */
11261115
1127- pgsm_store (entry );
1128- }
1129- else
1130- {
1131- /*
1132- * Even though we're not tracking execution time for this statement,
1133- * we must still increment the nesting level, to ensure that functions
1134- * evaluated within it are not seen as top-level calls. But don't do
1135- * so for EXECUTE; that way, when control reaches pgss_planner or
1136- * pgss_ExecutorStart, we will treat the costs as top-level if
1137- * appropriate. Likewise, don't bump for PREPARE, so that parse
1138- * analysis will treat the statement as top-level if appropriate.
1139- *
1140- * Likewise, we don't track execution of DEALLOCATE.
1141- *
1142- * To be absolutely certain we don't mess up the nesting level,
1143- * evaluate the bump_level condition just once.
1144- */
1116+ pgsm_store (entry );
1117+ }
1118+ else
1119+ {
1120+ /*
1121+ * Even though we're not tracking execution time for this
1122+ * statement, we must still increment the nesting level, to ensure
1123+ * that functions evaluated within it are not seen as top-level
1124+ * calls. But don't do so for EXECUTE; that way, when control
1125+ * reaches pgss_planner or pgss_ExecutorStart, we will treat the
1126+ * costs as top-level if appropriate. Likewise, don't bump for
1127+ * PREPARE, so that parse analysis will treat the statement as
1128+ * top-level if appropriate.
1129+ *
1130+ *
1131+ * Likewise, we don't track execution of DEALLOCATE.
1132+ *
1133+ * To be absolutely certain we don't mess up the nesting level,
1134+ * evaluate the bump_level condition just once.
1135+ */
11451136
11461137#if PG_VERSION_NUM >= 170000
1147- bool bump_level =
1148- !IsA (parsetree , ExecuteStmt ) &&
1149- !IsA (parsetree , PrepareStmt ) &&
1150- !IsA (parsetree , DeallocateStmt );
1138+ bool bump_level =
1139+ !IsA (parsetree , ExecuteStmt ) &&
1140+ !IsA (parsetree , PrepareStmt ) &&
1141+ !IsA (parsetree , DeallocateStmt );
11511142
1152- if (bump_level )
1153- nesting_level ++ ;
1143+ if (bump_level )
1144+ nesting_level ++ ;
11541145
1155- PG_TRY ();
1156- {
1146+ PG_TRY (2 );
1147+ {
11571148#endif
1158- if (prev_ProcessUtility )
1159- prev_ProcessUtility (pstmt , queryString ,
1160- readOnlyTree ,
1161- context , params , queryEnv ,
1162- dest ,
1163- qc );
1164- else
1165- standard_ProcessUtility (pstmt , queryString ,
1149+ if (prev_ProcessUtility )
1150+ prev_ProcessUtility (pstmt , queryString ,
11661151 readOnlyTree ,
11671152 context , params , queryEnv ,
11681153 dest ,
11691154 qc );
1155+ else
1156+ standard_ProcessUtility (pstmt , queryString ,
1157+ readOnlyTree ,
1158+ context , params , queryEnv ,
1159+ dest ,
1160+ qc );
11701161
11711162#if PG_VERSION_NUM >= 170000
1172- if (bump_level )
1173- nesting_level -- ;
1163+ if (bump_level )
1164+ nesting_level -- ;
1165+ }
1166+ PG_CATCH (2 );
1167+ {
1168+ if (bump_level )
1169+ nesting_level -- ;
1170+ PG_RE_THROW ();
1171+ }
1172+ PG_END_TRY (2 );
1173+ #endif
11741174 }
1175- PG_CATCH ();
1175+ pgsm_delete_entry (pstmt -> queryId );
1176+ }
1177+ PG_FINALLY ();
1178+ {
1179+ #if PG_VERSION_NUM >= 170000
1180+ if (nesting_level == 0 )
1181+ #else
1182+ if ((nesting_level + plan_nested_level ) == 0 )
1183+ #endif
11761184 {
1177- if (bump_level )
1178- nesting_level -- ;
1179- PG_RE_THROW ();
1185+ pgsm_cleanup_memory ();
11801186 }
1181- PG_END_TRY ();
1182- #endif
11831187 }
1184- pgsm_delete_entry ( pstmt -> queryId );
1188+ PG_END_TRY ( );
11851189}
11861190
11871191/*
@@ -1678,13 +1682,12 @@ pgsm_get_entry_for_query(int64 queryid, PlanInfo *plan_info, const char *query_t
16781682}
16791683
16801684static void
1681- pgsm_cleanup_callback ( void * arg )
1685+ pgsm_cleanup_memory ( )
16821686{
16831687 /* Reset the memory context holding the list */
16841688 MemoryContextReset (GetPgsmMemoryContext ());
16851689
16861690 lentries = NIL ;
1687- callback_setup = false;
16881691}
16891692
16901693/*
0 commit comments