@@ -40,7 +40,7 @@ PG_MODULE_MAGIC;
40
40
41
41
/* Number of output arguments (columns) for various API versions */
42
42
#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
44
44
#define PG_STAT_MONITOR_COLS PG_STAT_MONITOR_COLS_V2_0 /* maximum of above */
45
45
46
46
#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);
256
256
#endif
257
257
258
258
static 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 );
260
261
static void fill_in_constant_lengths (JumbleState * jstate , const char * query , int query_loc );
261
262
static int comp_location (const void * a , const void * b );
262
263
@@ -407,6 +408,10 @@ pgsm_post_parse_analyze_internal(ParseState *pstate, Query *query, JumbleState *
407
408
int norm_query_len ;
408
409
int location ;
409
410
int query_len ;
411
+ /* custum bind_variables */
412
+ char bind_variables [VAR_LEN ] = "" ;
413
+ int bind_var_len = 0 ;
414
+
410
415
411
416
/* Safety check... */
412
417
if (!IsSystemInitialized ())
@@ -477,8 +482,9 @@ pgsm_post_parse_analyze_internal(ParseState *pstate, Query *query, JumbleState *
477
482
query_text , /* query */
478
483
location , /* query location */
479
484
& norm_query_len ,
480
- GetDatabaseEncoding ());
481
-
485
+ GetDatabaseEncoding (),
486
+ & bind_variables [0 ],
487
+ & bind_var_len );
482
488
Assert (norm_query );
483
489
}
484
490
@@ -496,6 +502,10 @@ pgsm_post_parse_analyze_internal(ParseState *pstate, Query *query, JumbleState *
496
502
*/
497
503
entry -> pgsm_query_id = get_pgsm_query_id_hash (norm_query ? norm_query : query_text , norm_query_len );
498
504
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
+ }
499
509
500
510
/*
501
511
* Add the query text and entry to the local list.
@@ -1776,6 +1786,10 @@ pgsm_store(pgsmEntry * entry)
1776
1786
1777
1787
pgsm = pgsm_get_ss ();
1778
1788
1789
+ /*
1790
+ * We should lock the hash table here what if the bucket is removed; e.g.
1791
+ * reset is called - HAMID
1792
+ */
1779
1793
prev_bucket_id = pg_atomic_read_u64 (& pgsm -> current_wbucket );
1780
1794
bucketid = get_next_wbucket (pgsm );
1781
1795
@@ -1878,11 +1892,6 @@ pgsm_store(pgsmEntry * entry)
1878
1892
1879
1893
if (shared_hash_entry == NULL )
1880
1894
{
1881
- LWLockRelease (pgsm -> lock );
1882
-
1883
- if (DsaPointerIsValid (dsa_query_pointer ))
1884
- dsa_free (query_dsa_area , dsa_query_pointer );
1885
-
1886
1895
/*
1887
1896
* Out of memory; report only if the state has changed now.
1888
1897
* Otherwise we risk filling up the log file with these message.
@@ -1891,16 +1900,18 @@ pgsm_store(pgsmEntry * entry)
1891
1900
{
1892
1901
pgsm -> pgsm_oom = true;
1893
1902
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." )));
1902
1908
}
1903
1909
1910
+ LWLockRelease (pgsm -> lock );
1911
+
1912
+ if (DsaPointerIsValid (dsa_query_pointer ))
1913
+ dsa_free (query_dsa_area , dsa_query_pointer );
1914
+
1904
1915
return ;
1905
1916
}
1906
1917
else
@@ -1923,6 +1934,9 @@ pgsm_store(pgsmEntry * entry)
1923
1934
snprintf (shared_hash_entry -> username , sizeof (shared_hash_entry -> username ), "%s" , entry -> username );
1924
1935
}
1925
1936
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
+
1926
1940
pgsm_update_entry (shared_hash_entry , /* entry */
1927
1941
query , /* query */
1928
1942
comments , /* comments */
@@ -2232,6 +2246,12 @@ pg_stat_monitor_internal(FunctionCallInfo fcinfo,
2232
2246
values [i ++ ] = CStringGetTextDatum (tmp .info .application_name );
2233
2247
else
2234
2248
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;
2235
2255
2236
2256
/* relations at column number 10 */
2237
2257
if (tmp .info .num_relations > 0 )
@@ -3303,15 +3323,18 @@ CleanQuerytext(const char *query, int *location, int *len)
3303
3323
*/
3304
3324
static char *
3305
3325
generate_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 )
3307
3328
{
3308
3329
char * norm_query ;
3309
3330
int query_len = * query_len_p ;
3331
+ int bind_var_len ;
3310
3332
int i ,
3311
3333
norm_query_buflen , /* Space allowed for norm_query */
3312
3334
len_to_wrt , /* Length (in bytes) to write */
3313
3335
quer_loc = 0 , /* Source query byte location */
3314
3336
n_quer_loc = 0 , /* Normalized query byte location */
3337
+ n_var_loc = 0 , /* bind_variables byte location */
3315
3338
last_off = 0 , /* Offset from start for previous tok */
3316
3339
last_tok_len = 0 ; /* Length (in bytes) of that tok */
3317
3340
@@ -3362,6 +3385,16 @@ generate_normalized_query(JumbleState *jstate, const char *query,
3362
3385
quer_loc = off + tok_len ;
3363
3386
last_off = off ;
3364
3387
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
+ }
3365
3398
}
3366
3399
3367
3400
/*
@@ -3378,6 +3411,13 @@ generate_normalized_query(JumbleState *jstate, const char *query,
3378
3411
norm_query [n_quer_loc ] = '\0' ;
3379
3412
3380
3413
* 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
+
3381
3421
return norm_query ;
3382
3422
}
3383
3423
0 commit comments