From cba6bbfbd4dd4f7e6312dfc82c7ae847adc57aff Mon Sep 17 00:00:00 2001 From: Ibrar Ahmed Date: Thu, 11 Feb 2021 19:07:39 +0000 Subject: [PATCH] PG-177: Error in Histogram ranges. --- docs/USER_GUIDE.md | 26 +++++++++++++------------- pg_stat_monitor.c | 45 ++++++++++++--------------------------------- pg_stat_monitor.h | 1 - 3 files changed, 25 insertions(+), 47 deletions(-) diff --git a/docs/USER_GUIDE.md b/docs/USER_GUIDE.md index 855ca5b..9490e2e 100644 --- a/docs/USER_GUIDE.md +++ b/docs/USER_GUIDE.md @@ -284,19 +284,19 @@ SELECT resp_calls, query FROM pg_stat_monitor; {3," 0"," 0"," 0"," 0"," 0"," 0"," 0"," 0"," 1"} | select * from pg_stat_monitor_reset() {3," 0"," 0"," 0"," 0"," 0"," 0"," 0"," 0"," 1"} | SELECT * FROM foo -SELECT * FROM histogram(4, '4B64EE85C83D9AAC') AS a(range TEXT, freq INT, bar TEXT); - range | freq | bar ------------+------+-------------------------------- - (0 - 1)} | 692 | ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ - (1 - 1)} | 0 | - (1 - 1)} | 0 | - (1 - 2)} | 572 | ■■■■■■■■■■■■■■■■■■■■■■■■■ - (2 - 3)} | 74 | ■■■ - (3 - 3)} | 0 | - (3 - 5)} | 9 | - (5 - 6)} | 1 | - (6 - 7)} | 1 | - (7 - 10)} | 1 | +postgres=# SELECT * FROM histogram(0, 'F44CD1B4B33A47AF') AS a(range TEXT, freq INT, bar TEXT); + range | freq | bar +--------------------+------+-------------------------------- + (0 - 3)} | 2 | ■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ + (3 - 10)} | 0 | + (10 - 31)} | 1 | ■■■■■■■■■■■■■■■ + (31 - 100)} | 0 | + (100 - 316)} | 0 | + (316 - 1000)} | 0 | + (1000 - 3162)} | 0 | + (3162 - 10000)} | 0 | + (10000 - 31622)} | 0 | + (31622 - 100000)} | 0 | (10 rows) ``` diff --git a/pg_stat_monitor.c b/pg_stat_monitor.c index e0b3653..fccfbf6 100644 --- a/pg_stat_monitor.c +++ b/pg_stat_monitor.c @@ -103,7 +103,6 @@ PG_FUNCTION_INFO_V1(get_histogram_timings); static uint pg_get_client_addr(void); static int pg_get_application_name(char* application_name); static PgBackendStatus *pg_get_backend_status(void); -static Datum textarray_get_datum(char **arr, int arr_len, int str_len); static Datum intarray_get_datum(int32 arr[], int len); #if PG_VERSION_NUM >= 130000 @@ -2263,35 +2262,6 @@ comp_location(const void *a, const void *b) } #define MAX_STRING_LEN 1024 -/* Convert array into Text dataum */ -static Datum -textarray_get_datum(char **arr, int arr_len, int str_len) -{ - int j; - char *text_str = palloc0(MAX_STRING_LEN); - bool first = true; - - /* Sanity check */ - if (arr == NULL || str_len >= MAX_STRING_LEN) - return 0; - - /* Need to calculate the actual size, and avoid unnessary memory usage */ - for (j = 0; j < arr_len; j++) - { - if (arr[j] == NULL || strlen(arr[j]) == 0) - continue; - if (first) - { - snprintf(text_str, MAX_STRING_LEN, "%s", arr[j]); - first = false; - continue; - } - snprintf(text_str, MAX_STRING_LEN, "%s,%s", text_str, arr[j]); - } - return CStringGetTextDatum(text_str); - -} - /* Convert array into Text dataum */ static Datum intarray_get_datum(int32 arr[], int len) @@ -2759,7 +2729,8 @@ get_histogram_timings(PG_FUNCTION_ARGS) double b_max; double b_min; double bucket_size; - char range[50][1024] = {0}; + bool first = true; + char *text_str = palloc0(MAX_STRING_LEN); b_max = log(q_max - q_min); b_min = 0; @@ -2768,8 +2739,16 @@ get_histogram_timings(PG_FUNCTION_ARGS) { int64 b_start = (index == 1)? 0 : exp(bucket_size * (index - 1)); int64 b_end = exp(bucket_size * index); - sprintf(range[index-1], "(%ld - %ld)}", b_start, b_end); + if (first) + { + sprintf(text_str, "(%ld - %ld)}", b_start, b_end); + first = false; + } + else + { + sprintf(text_str, "%s, (%ld - %ld)}", text_str, b_start, b_end); + } } - return TextArrayGetTextDatum((char**)range, b_count, 1023); + return CStringGetTextDatum(text_str); } diff --git a/pg_stat_monitor.h b/pg_stat_monitor.h index 407b8a1..4a62e32 100644 --- a/pg_stat_monitor.h +++ b/pg_stat_monitor.h @@ -54,7 +54,6 @@ #include "utils/guc.h" #define MAX_BACKEND_PROCESES (MaxBackends + NUM_AUXILIARY_PROCS + max_prepared_xacts) -#define TextArrayGetTextDatum(x,y,z) textarray_get_datum(x,y,z) #define IntArrayGetTextDatum(x,y) intarray_get_datum(x,y) /* XXX: Should USAGE_EXEC reflect execution time and/or buffer usage? */