@@ -40,7 +40,7 @@ PG_MODULE_MAGIC;
4040
4141/* Number of output arguments (columns) for various API versions */
4242#define PG_STAT_MONITOR_COLS_V1_0 52
43- #define PG_STAT_MONITOR_COLS_V2_0 64
43+ #define PG_STAT_MONITOR_COLS_V2_0 65
4444#define PG_STAT_MONITOR_COLS PG_STAT_MONITOR_COLS_V2_0 /* maximum of above */
4545
4646#define PGSM_TEXT_FILE PGSTAT_STAT_PERMANENT_DIRECTORY "pg_stat_monitor_query"
@@ -256,7 +256,8 @@ static uint64 get_query_id(JumbleState *jstate, Query *query);
256256#endif
257257
258258static char * generate_normalized_query (JumbleState * jstate , const char * query ,
259- int query_loc , int * query_len_p , int encoding );
259+ int query_loc , int * query_len_p , int encoding ,
260+ char * bind_variables , int * bind_var_len_p );
260261static void fill_in_constant_lengths (JumbleState * jstate , const char * query , int query_loc );
261262static int comp_location (const void * a , const void * b );
262263
@@ -407,6 +408,10 @@ pgsm_post_parse_analyze_internal(ParseState *pstate, Query *query, JumbleState *
407408 int norm_query_len ;
408409 int location ;
409410 int query_len ;
411+ /* custum bind_variables */
412+ char bind_variables [VAR_LEN ] = "" ;
413+ int bind_var_len = 0 ;
414+
410415
411416 /* Safety check... */
412417 if (!IsSystemInitialized ())
@@ -477,8 +482,9 @@ pgsm_post_parse_analyze_internal(ParseState *pstate, Query *query, JumbleState *
477482 query_text , /* query */
478483 location , /* query location */
479484 & norm_query_len ,
480- GetDatabaseEncoding ());
481-
485+ GetDatabaseEncoding (),
486+ & bind_variables [0 ],
487+ & bind_var_len );
482488 Assert (norm_query );
483489 }
484490
@@ -496,6 +502,10 @@ pgsm_post_parse_analyze_internal(ParseState *pstate, Query *query, JumbleState *
496502 */
497503 entry -> pgsm_query_id = get_pgsm_query_id_hash (norm_query ? norm_query : query_text , norm_query_len );
498504 entry -> counters .info .cmd_type = query -> commandType ;
505+
506+ if (bind_var_len > 0 ){
507+ _snprintf (entry -> counters .info .bind_variables , bind_variables , bind_var_len + 1 , VAR_LEN );
508+ }
499509
500510 /*
501511 * Add the query text and entry to the local list.
@@ -1776,6 +1786,10 @@ pgsm_store(pgsmEntry * entry)
17761786
17771787 pgsm = pgsm_get_ss ();
17781788
1789+ /*
1790+ * We should lock the hash table here what if the bucket is removed; e.g.
1791+ * reset is called - HAMID
1792+ */
17791793 prev_bucket_id = pg_atomic_read_u64 (& pgsm -> current_wbucket );
17801794 bucketid = get_next_wbucket (pgsm );
17811795
@@ -1878,11 +1892,6 @@ pgsm_store(pgsmEntry * entry)
18781892
18791893 if (shared_hash_entry == NULL )
18801894 {
1881- LWLockRelease (pgsm -> lock );
1882-
1883- if (DsaPointerIsValid (dsa_query_pointer ))
1884- dsa_free (query_dsa_area , dsa_query_pointer );
1885-
18861895 /*
18871896 * Out of memory; report only if the state has changed now.
18881897 * Otherwise we risk filling up the log file with these message.
@@ -1891,16 +1900,18 @@ pgsm_store(pgsmEntry * entry)
18911900 {
18921901 pgsm -> pgsm_oom = true;
18931902
1894- PGSM_DISABLE_ERROR_CAPUTRE ();
1895- {
1896- ereport (WARNING ,
1897- (errcode (ERRCODE_OUT_OF_MEMORY ),
1898- errmsg ("[pg_stat_monitor] pgsm_store: Hash table is out of memory and can no longer store queries!" ),
1899- errdetail ("You may reset the view or when the buckets are deallocated, pg_stat_monitor will resume saving " \
1900- "queries. Alternatively, try increasing the value of pg_stat_monitor.pgsm_max." )));
1901- } PGSM_END_DISABLE_ERROR_CAPTURE ();
1903+ ereport (WARNING ,
1904+ (errcode (ERRCODE_OUT_OF_MEMORY ),
1905+ errmsg ("[pg_stat_monitor] pgsm_store: Hash table is out of memory and can no longer store queries!" ),
1906+ errdetail ("You may reset the view or when the buckets are deallocated, pg_stat_monitor will resume saving " \
1907+ "queries. Alternatively, try increasing the value of pg_stat_monitor.pgsm_max." )));
19021908 }
19031909
1910+ LWLockRelease (pgsm -> lock );
1911+
1912+ if (DsaPointerIsValid (dsa_query_pointer ))
1913+ dsa_free (query_dsa_area , dsa_query_pointer );
1914+
19041915 return ;
19051916 }
19061917 else
@@ -1923,6 +1934,9 @@ pgsm_store(pgsmEntry * entry)
19231934 snprintf (shared_hash_entry -> username , sizeof (shared_hash_entry -> username ), "%s" , entry -> username );
19241935 }
19251936
1937+ if (strlen (entry -> counters .info .bind_variables ) > 0 )
1938+ strncpy (shared_hash_entry -> counters .info .bind_variables , entry -> counters .info .bind_variables , VAR_LEN );
1939+
19261940 pgsm_update_entry (shared_hash_entry , /* entry */
19271941 query , /* query */
19281942 comments , /* comments */
@@ -2232,6 +2246,12 @@ pg_stat_monitor_internal(FunctionCallInfo fcinfo,
22322246 values [i ++ ] = CStringGetTextDatum (tmp .info .application_name );
22332247 else
22342248 nulls [i ++ ] = true;
2249+
2250+ /* bind_variables at column number 48 */
2251+ if (strlen (tmp .info .bind_variables ) > 0 )
2252+ values [i ++ ] = CStringGetTextDatum (tmp .info .bind_variables );
2253+ else
2254+ nulls [i ++ ] = true;
22352255
22362256 /* relations at column number 10 */
22372257 if (tmp .info .num_relations > 0 )
@@ -3303,15 +3323,18 @@ CleanQuerytext(const char *query, int *location, int *len)
33033323 */
33043324static char *
33053325generate_normalized_query (JumbleState * jstate , const char * query ,
3306- int query_loc , int * query_len_p , int encoding )
3326+ int query_loc , int * query_len_p , int encoding ,
3327+ char * bind_variables , int * bind_var_len_p )
33073328{
33083329 char * norm_query ;
33093330 int query_len = * query_len_p ;
3331+ int bind_var_len ;
33103332 int i ,
33113333 norm_query_buflen , /* Space allowed for norm_query */
33123334 len_to_wrt , /* Length (in bytes) to write */
33133335 quer_loc = 0 , /* Source query byte location */
33143336 n_quer_loc = 0 , /* Normalized query byte location */
3337+ n_var_loc = 0 , /* bind_variables byte location */
33153338 last_off = 0 , /* Offset from start for previous tok */
33163339 last_tok_len = 0 ; /* Length (in bytes) of that tok */
33173340
@@ -3362,6 +3385,16 @@ generate_normalized_query(JumbleState *jstate, const char *query,
33623385 quer_loc = off + tok_len ;
33633386 last_off = off ;
33643387 last_tok_len = tok_len ;
3388+
3389+
3390+ if (pgsm_extract_bind_variables ){
3391+ if (n_var_loc + tok_len + 1 < VAR_LEN - 1 ){
3392+ memcpy (bind_variables + n_var_loc , query + quer_loc - tok_len , tok_len );
3393+ n_var_loc += tok_len ;
3394+ memcpy (bind_variables + n_var_loc , "|" , 1 );
3395+ n_var_loc ++ ;
3396+ }
3397+ }
33653398 }
33663399
33673400 /*
@@ -3378,6 +3411,13 @@ generate_normalized_query(JumbleState *jstate, const char *query,
33783411 norm_query [n_quer_loc ] = '\0' ;
33793412
33803413 * query_len_p = n_quer_loc ;
3414+
3415+ if (pgsm_extract_bind_variables ){
3416+ bind_var_len = n_var_loc - 1 ;
3417+ bind_variables [bind_var_len ] = '\0' ;
3418+ * bind_var_len_p = bind_var_len ;
3419+ }
3420+
33813421 return norm_query ;
33823422}
33833423
0 commit comments