PG-456: Running pgindent to make source PostgreSQL compatible. (#269)

PG-456: Running pgindent to make source indentation/spacing PostgreSQLCompatible.

PostgreSQL uses pgindent from time to time to make source code PostgreSQL
style guide compatible, it is a very long time since we have not done that.
Commit fixes a lot of indentation and spacing issues.

Co-authored-by: Hamid Akhtar <hamid.akhtar@gmail.com>
pull/276/head
Ibrar Ahmed 2022-06-29 00:42:40 +05:00 committed by GitHub
parent 926eade1eb
commit a9187117f9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 1287 additions and 1151 deletions

320
guc.c
View File

@ -19,10 +19,10 @@
#include "pg_stat_monitor.h" #include "pg_stat_monitor.h"
GucVariable conf[MAX_SETTINGS]; GucVariable conf[MAX_SETTINGS];
static void DefineIntGUC(GucVariable *conf); static void DefineIntGUC(GucVariable * conf);
static void DefineIntGUCWithCheck(GucVariable *conf, GucIntCheckHook check); static void DefineIntGUCWithCheck(GucVariable * conf, GucIntCheckHook check);
static void DefineBoolGUC(GucVariable *conf); static void DefineBoolGUC(GucVariable * conf);
static void DefineEnumGUC(GucVariable *conf, const struct config_enum_entry *options); static void DefineEnumGUC(GucVariable * conf, const struct config_enum_entry *options);
/* Check hooks to ensure histogram_min < histogram_max */ /* Check hooks to ensure histogram_min < histogram_max */
static bool check_histogram_min(int *newval, void **extra, GucSource source); static bool check_histogram_min(int *newval, void **extra, GucSource source);
@ -34,196 +34,214 @@ static bool check_histogram_max(int *newval, void **extra, GucSource source);
void void
init_guc(void) init_guc(void)
{ {
int i = 0, j; int i = 0,
j;
conf[i] = (GucVariable) { conf[i] = (GucVariable)
{
.guc_name = "pg_stat_monitor.pgsm_max", .guc_name = "pg_stat_monitor.pgsm_max",
.guc_desc = "Sets the maximum size of shared memory in (MB) used for statement's metadata tracked by pg_stat_monitor.", .guc_desc = "Sets the maximum size of shared memory in (MB) used for statement's metadata tracked by pg_stat_monitor.",
.guc_default = 100, .guc_default = 100,
.guc_min = 1, .guc_min = 1,
.guc_max = 1000, .guc_max = 1000,
.guc_restart = true, .guc_restart = true,
.guc_unit = GUC_UNIT_MB, .guc_unit = GUC_UNIT_MB,
.guc_value = &PGSM_MAX .guc_value = &PGSM_MAX
}; };
DefineIntGUC(&conf[i++]); DefineIntGUC(&conf[i++]);
conf[i] = (GucVariable) { conf[i] = (GucVariable)
{
.guc_name = "pg_stat_monitor.pgsm_query_max_len", .guc_name = "pg_stat_monitor.pgsm_query_max_len",
.guc_desc = "Sets the maximum length of query.", .guc_desc = "Sets the maximum length of query.",
.guc_default = 2048, .guc_default = 2048,
.guc_min = 1024, .guc_min = 1024,
.guc_max = INT_MAX, .guc_max = INT_MAX,
.guc_unit = 0, .guc_unit = 0,
.guc_restart = true, .guc_restart = true,
.guc_value = &PGSM_QUERY_MAX_LEN .guc_value = &PGSM_QUERY_MAX_LEN
}; };
DefineIntGUC(&conf[i++]); DefineIntGUC(&conf[i++]);
conf[i] = (GucVariable) { conf[i] = (GucVariable)
{
.guc_name = "pg_stat_monitor.pgsm_track_utility", .guc_name = "pg_stat_monitor.pgsm_track_utility",
.guc_desc = "Selects whether utility commands are tracked.", .guc_desc = "Selects whether utility commands are tracked.",
.guc_default = 1, .guc_default = 1,
.guc_min = 0, .guc_min = 0,
.guc_max = 0, .guc_max = 0,
.guc_restart = false, .guc_restart = false,
.guc_unit = 0, .guc_unit = 0,
.guc_value = &PGSM_TRACK_UTILITY .guc_value = &PGSM_TRACK_UTILITY
}; };
DefineBoolGUC(&conf[i++]); DefineBoolGUC(&conf[i++]);
conf[i] = (GucVariable) { conf[i] = (GucVariable)
{
.guc_name = "pg_stat_monitor.pgsm_normalized_query", .guc_name = "pg_stat_monitor.pgsm_normalized_query",
.guc_desc = "Selects whether save query in normalized format.", .guc_desc = "Selects whether save query in normalized format.",
.guc_default = 0, .guc_default = 0,
.guc_min = 0, .guc_min = 0,
.guc_max = 0, .guc_max = 0,
.guc_restart = false, .guc_restart = false,
.guc_unit = 0, .guc_unit = 0,
.guc_value = &PGSM_NORMALIZED_QUERY .guc_value = &PGSM_NORMALIZED_QUERY
}; };
DefineBoolGUC(&conf[i++]); DefineBoolGUC(&conf[i++]);
conf[i] = (GucVariable) { conf[i] = (GucVariable)
{
.guc_name = "pg_stat_monitor.pgsm_max_buckets", .guc_name = "pg_stat_monitor.pgsm_max_buckets",
.guc_desc = "Sets the maximum number of buckets.", .guc_desc = "Sets the maximum number of buckets.",
.guc_default = 10, .guc_default = 10,
.guc_min = 1, .guc_min = 1,
.guc_max = 10, .guc_max = 10,
.guc_restart = true, .guc_restart = true,
.guc_unit = 0, .guc_unit = 0,
.guc_value = &PGSM_MAX_BUCKETS .guc_value = &PGSM_MAX_BUCKETS
}; };
DefineIntGUC(&conf[i++]); DefineIntGUC(&conf[i++]);
conf[i] = (GucVariable) { conf[i] = (GucVariable)
{
.guc_name = "pg_stat_monitor.pgsm_bucket_time", .guc_name = "pg_stat_monitor.pgsm_bucket_time",
.guc_desc = "Sets the time in seconds per bucket.", .guc_desc = "Sets the time in seconds per bucket.",
.guc_default = 60, .guc_default = 60,
.guc_min = 1, .guc_min = 1,
.guc_max = INT_MAX, .guc_max = INT_MAX,
.guc_restart = true, .guc_restart = true,
.guc_unit = 0, .guc_unit = 0,
.guc_value = &PGSM_BUCKET_TIME .guc_value = &PGSM_BUCKET_TIME
}; };
DefineIntGUC(&conf[i++]); DefineIntGUC(&conf[i++]);
conf[i] = (GucVariable) { conf[i] = (GucVariable)
{
.guc_name = "pg_stat_monitor.pgsm_histogram_min", .guc_name = "pg_stat_monitor.pgsm_histogram_min",
.guc_desc = "Sets the time in millisecond.", .guc_desc = "Sets the time in millisecond.",
.guc_default = 0, .guc_default = 0,
.guc_min = 0, .guc_min = 0,
.guc_max = INT_MAX, .guc_max = INT_MAX,
.guc_restart = true, .guc_restart = true,
.guc_unit = 0, .guc_unit = 0,
.guc_value = &PGSM_HISTOGRAM_MIN .guc_value = &PGSM_HISTOGRAM_MIN
}; };
DefineIntGUCWithCheck(&conf[i++], check_histogram_min); DefineIntGUCWithCheck(&conf[i++], check_histogram_min);
conf[i] = (GucVariable) { conf[i] = (GucVariable)
{
.guc_name = "pg_stat_monitor.pgsm_histogram_max", .guc_name = "pg_stat_monitor.pgsm_histogram_max",
.guc_desc = "Sets the time in millisecond.", .guc_desc = "Sets the time in millisecond.",
.guc_default = 100000, .guc_default = 100000,
.guc_min = 10, .guc_min = 10,
.guc_max = INT_MAX, .guc_max = INT_MAX,
.guc_restart = true, .guc_restart = true,
.guc_unit = 0, .guc_unit = 0,
.guc_value = &PGSM_HISTOGRAM_MAX .guc_value = &PGSM_HISTOGRAM_MAX
}; };
DefineIntGUCWithCheck(&conf[i++], check_histogram_max); DefineIntGUCWithCheck(&conf[i++], check_histogram_max);
conf[i] = (GucVariable) { conf[i] = (GucVariable)
{
.guc_name = "pg_stat_monitor.pgsm_histogram_buckets", .guc_name = "pg_stat_monitor.pgsm_histogram_buckets",
.guc_desc = "Sets the maximum number of histogram buckets", .guc_desc = "Sets the maximum number of histogram buckets",
.guc_default = 10, .guc_default = 10,
.guc_min = 2, .guc_min = 2,
.guc_max = MAX_RESPONSE_BUCKET, .guc_max = MAX_RESPONSE_BUCKET,
.guc_restart = true, .guc_restart = true,
.guc_unit = 0, .guc_unit = 0,
.guc_value = &PGSM_HISTOGRAM_BUCKETS .guc_value = &PGSM_HISTOGRAM_BUCKETS
}; };
DefineIntGUC(&conf[i++]); DefineIntGUC(&conf[i++]);
conf[i] = (GucVariable) { conf[i] = (GucVariable)
{
.guc_name = "pg_stat_monitor.pgsm_query_shared_buffer", .guc_name = "pg_stat_monitor.pgsm_query_shared_buffer",
.guc_desc = "Sets the maximum size of shared memory in (MB) used for query tracked by pg_stat_monitor.", .guc_desc = "Sets the maximum size of shared memory in (MB) used for query tracked by pg_stat_monitor.",
.guc_default = 20, .guc_default = 20,
.guc_min = 1, .guc_min = 1,
.guc_max = 10000, .guc_max = 10000,
.guc_restart = true, .guc_restart = true,
.guc_unit = GUC_UNIT_MB, .guc_unit = GUC_UNIT_MB,
.guc_value = &PGSM_QUERY_SHARED_BUFFER .guc_value = &PGSM_QUERY_SHARED_BUFFER
}; };
DefineIntGUC(&conf[i++]); DefineIntGUC(&conf[i++]);
conf[i] = (GucVariable) { conf[i] = (GucVariable)
{
.guc_name = "pg_stat_monitor.pgsm_overflow_target", .guc_name = "pg_stat_monitor.pgsm_overflow_target",
.guc_desc = "Sets the overflow target for pg_stat_monitor", .guc_desc = "Sets the overflow target for pg_stat_monitor",
.guc_default = 1, .guc_default = 1,
.guc_min = 0, .guc_min = 0,
.guc_max = 1, .guc_max = 1,
.guc_restart = true, .guc_restart = true,
.guc_unit = 0, .guc_unit = 0,
.guc_value = &PGSM_OVERFLOW_TARGET .guc_value = &PGSM_OVERFLOW_TARGET
}; };
DefineIntGUC(&conf[i++]); DefineIntGUC(&conf[i++]);
conf[i] = (GucVariable) { conf[i] = (GucVariable)
{
.guc_name = "pg_stat_monitor.pgsm_enable_query_plan", .guc_name = "pg_stat_monitor.pgsm_enable_query_plan",
.guc_desc = "Enable/Disable query plan monitoring", .guc_desc = "Enable/Disable query plan monitoring",
.guc_default = 0, .guc_default = 0,
.guc_min = 0, .guc_min = 0,
.guc_max = 0, .guc_max = 0,
.guc_restart = false, .guc_restart = false,
.guc_unit = 0, .guc_unit = 0,
.guc_value = &PGSM_QUERY_PLAN .guc_value = &PGSM_QUERY_PLAN
}; };
DefineBoolGUC(&conf[i++]); DefineBoolGUC(&conf[i++]);
conf[i] = (GucVariable) { conf[i] = (GucVariable)
{
.guc_name = "pg_stat_monitor.pgsm_track", .guc_name = "pg_stat_monitor.pgsm_track",
.guc_desc = "Selects which statements are tracked by pg_stat_monitor.", .guc_desc = "Selects which statements are tracked by pg_stat_monitor.",
.n_options = 3, .n_options = 3,
.guc_default = PGSM_TRACK_TOP, .guc_default = PGSM_TRACK_TOP,
.guc_min = PSGM_TRACK_NONE, .guc_min = PSGM_TRACK_NONE,
.guc_max = PGSM_TRACK_ALL, .guc_max = PGSM_TRACK_ALL,
.guc_restart = false, .guc_restart = false,
.guc_unit = 0, .guc_unit = 0,
.guc_value = &PGSM_TRACK .guc_value = &PGSM_TRACK
}; };
for (j = 0; j < conf[i].n_options; ++j) { for (j = 0; j < conf[i].n_options; ++j)
{
strlcpy(conf[i].guc_options[j], track_options[j].name, sizeof(conf[i].guc_options[j])); strlcpy(conf[i].guc_options[j], track_options[j].name, sizeof(conf[i].guc_options[j]));
} }
DefineEnumGUC(&conf[i++], track_options); DefineEnumGUC(&conf[i++], track_options);
conf[i] = (GucVariable) { conf[i] = (GucVariable)
{
.guc_name = "pg_stat_monitor.pgsm_extract_comments", .guc_name = "pg_stat_monitor.pgsm_extract_comments",
.guc_desc = "Enable/Disable extracting comments from queries.", .guc_desc = "Enable/Disable extracting comments from queries.",
.guc_default = 0, .guc_default = 0,
.guc_min = 0, .guc_min = 0,
.guc_max = 0, .guc_max = 0,
.guc_restart = false, .guc_restart = false,
.guc_unit = 0, .guc_unit = 0,
.guc_value = &PGSM_EXTRACT_COMMENTS .guc_value = &PGSM_EXTRACT_COMMENTS
}; };
DefineBoolGUC(&conf[i++]); DefineBoolGUC(&conf[i++]);
#if PG_VERSION_NUM >= 130000 #if PG_VERSION_NUM >= 130000
conf[i] = (GucVariable) { conf[i] = (GucVariable)
{
.guc_name = "pg_stat_monitor.pgsm_track_planning", .guc_name = "pg_stat_monitor.pgsm_track_planning",
.guc_desc = "Selects whether planning statistics are tracked.", .guc_desc = "Selects whether planning statistics are tracked.",
.guc_default = 0, .guc_default = 0,
.guc_min = 0, .guc_min = 0,
.guc_max = 0, .guc_max = 0,
.guc_restart = false, .guc_restart = false,
.guc_unit = 0, .guc_unit = 0,
.guc_value = &PGSM_TRACK_PLANNING .guc_value = &PGSM_TRACK_PLANNING
}; };
DefineBoolGUC(&conf[i++]); DefineBoolGUC(&conf[i++]);
#endif #endif
} }
static void DefineIntGUCWithCheck(GucVariable *conf, GucIntCheckHook check) static void
DefineIntGUCWithCheck(GucVariable * conf, GucIntCheckHook check)
{ {
conf->type = PGC_INT; conf->type = PGC_INT;
DefineCustomIntVariable(conf->guc_name, DefineCustomIntVariable(conf->guc_name,
@ -241,21 +259,21 @@ static void DefineIntGUCWithCheck(GucVariable *conf, GucIntCheckHook check)
} }
static void static void
DefineIntGUC(GucVariable *conf) DefineIntGUC(GucVariable * conf)
{ {
DefineIntGUCWithCheck(conf, NULL); DefineIntGUCWithCheck(conf, NULL);
} }
static void static void
DefineBoolGUC(GucVariable *conf) DefineBoolGUC(GucVariable * conf)
{ {
conf->type = PGC_BOOL; conf->type = PGC_BOOL;
DefineCustomBoolVariable(conf->guc_name, DefineCustomBoolVariable(conf->guc_name,
conf->guc_desc, conf->guc_desc,
NULL, NULL,
(bool*)conf->guc_value, (bool *) conf->guc_value,
conf->guc_default, conf->guc_default,
conf->guc_restart ? PGC_POSTMASTER : PGC_USERSET, conf->guc_restart ? PGC_POSTMASTER : PGC_USERSET,
0, 0,
NULL, NULL,
NULL, NULL,
@ -263,29 +281,30 @@ DefineBoolGUC(GucVariable *conf)
} }
static void static void
DefineEnumGUC(GucVariable *conf, const struct config_enum_entry *options) DefineEnumGUC(GucVariable * conf, const struct config_enum_entry *options)
{ {
conf->type = PGC_ENUM; conf->type = PGC_ENUM;
DefineCustomEnumVariable(conf->guc_name, DefineCustomEnumVariable(conf->guc_name,
conf->guc_desc, conf->guc_desc,
NULL, NULL,
conf->guc_value, conf->guc_value,
conf->guc_default, conf->guc_default,
options, options,
conf->guc_restart ? PGC_POSTMASTER : PGC_USERSET, conf->guc_restart ? PGC_POSTMASTER : PGC_USERSET,
0, 0,
NULL, NULL,
NULL, NULL,
NULL); NULL);
} }
GucVariable* GucVariable *
get_conf(int i) get_conf(int i)
{ {
return &conf[i]; return &conf[i];
} }
static bool check_histogram_min(int *newval, void **extra, GucSource source) static bool
check_histogram_min(int *newval, void **extra, GucSource source)
{ {
/* /*
* During module initialization PGSM_HISTOGRAM_MIN is initialized before * During module initialization PGSM_HISTOGRAM_MIN is initialized before
@ -294,7 +313,8 @@ static bool check_histogram_min(int *newval, void **extra, GucSource source)
return (PGSM_HISTOGRAM_MAX == 0 || *newval < PGSM_HISTOGRAM_MAX); return (PGSM_HISTOGRAM_MAX == 0 || *newval < PGSM_HISTOGRAM_MAX);
} }
static bool check_histogram_max(int *newval, void **extra, GucSource source) static bool
check_histogram_max(int *newval, void **extra, GucSource source)
{ {
return (*newval > PGSM_HISTOGRAM_MIN); return (*newval > PGSM_HISTOGRAM_MIN);
} }

View File

@ -25,10 +25,11 @@ static HTAB *pgss_hash;
static HTAB *pgss_query_hash; static HTAB *pgss_query_hash;
static HTAB* static HTAB *
hash_init(const char *hash_name, int key_size, int entry_size, int hash_size) hash_init(const char *hash_name, int key_size, int entry_size, int hash_size)
{ {
HASHCTL info; HASHCTL info;
memset(&info, 0, sizeof(info)); memset(&info, 0, sizeof(info));
info.keysize = key_size; info.keysize = key_size;
info.entrysize = entry_size; info.entrysize = entry_size;
@ -46,8 +47,8 @@ pgss_startup(void)
pgss_hash = NULL; pgss_hash = NULL;
/* /*
* Create or attach to the shared memory state, including hash table * Create or attach to the shared memory state, including hash table
*/ */
LWLockAcquire(AddinShmemInitLock, LW_EXCLUSIVE); LWLockAcquire(AddinShmemInitLock, LW_EXCLUSIVE);
pgss = ShmemInitStruct("pg_stat_monitor", sizeof(pgssSharedState), &found); pgss = ShmemInitStruct("pg_stat_monitor", sizeof(pgssSharedState), &found);
@ -63,7 +64,7 @@ pgss_startup(void)
init_hook_stats(); init_hook_stats();
#endif #endif
set_qbuf((unsigned char *)ShmemAlloc(MAX_QUERY_BUF)); set_qbuf((unsigned char *) ShmemAlloc(MAX_QUERY_BUF));
pgss_hash = hash_init("pg_stat_monitor: bucket hashtable", sizeof(pgssHashKey), sizeof(pgssEntry), MAX_BUCKET_ENTRIES); pgss_hash = hash_init("pg_stat_monitor: bucket hashtable", sizeof(pgssHashKey), sizeof(pgssEntry), MAX_BUCKET_ENTRIES);
pgss_query_hash = hash_init("pg_stat_monitor: queryID hashtable", sizeof(uint64), sizeof(pgssQueryEntry), MAX_BUCKET_ENTRIES); pgss_query_hash = hash_init("pg_stat_monitor: queryID hashtable", sizeof(uint64), sizeof(pgssQueryEntry), MAX_BUCKET_ENTRIES);
@ -77,19 +78,19 @@ pgss_startup(void)
on_shmem_exit(pgss_shmem_shutdown, (Datum) 0); on_shmem_exit(pgss_shmem_shutdown, (Datum) 0);
} }
pgssSharedState* pgssSharedState *
pgsm_get_ss(void) pgsm_get_ss(void)
{ {
return pgss; return pgss;
} }
HTAB* HTAB *
pgsm_get_hash(void) pgsm_get_hash(void)
{ {
return pgss_hash; return pgss_hash;
} }
HTAB* HTAB *
pgsm_get_query_hash(void) pgsm_get_query_hash(void)
{ {
return pgss_query_hash; return pgss_query_hash;
@ -117,7 +118,7 @@ pgss_shmem_shutdown(int code, Datum arg)
Size Size
hash_memsize(void) hash_memsize(void)
{ {
Size size; Size size;
size = MAXALIGN(sizeof(pgssSharedState)); size = MAXALIGN(sizeof(pgssSharedState));
size += MAXALIGN(MAX_QUERY_BUF); size += MAXALIGN(MAX_QUERY_BUF);
@ -130,7 +131,7 @@ hash_memsize(void)
pgssEntry * pgssEntry *
hash_entry_alloc(pgssSharedState *pgss, pgssHashKey *key, int encoding) hash_entry_alloc(pgssSharedState *pgss, pgssHashKey *key, int encoding)
{ {
pgssEntry *entry = NULL; pgssEntry *entry = NULL;
bool found = false; bool found = false;
if (hash_get_num_entries(pgss_hash) >= MAX_BUCKET_ENTRIES) if (hash_get_num_entries(pgss_hash) >= MAX_BUCKET_ENTRIES)
@ -174,26 +175,30 @@ void
hash_entry_dealloc(int new_bucket_id, int old_bucket_id, unsigned char *query_buffer) hash_entry_dealloc(int new_bucket_id, int old_bucket_id, unsigned char *query_buffer)
{ {
HASH_SEQ_STATUS hash_seq; HASH_SEQ_STATUS hash_seq;
pgssEntry *entry = NULL; pgssEntry *entry = NULL;
/* Store pending query ids from the previous bucket. */ /* Store pending query ids from the previous bucket. */
List *pending_entries = NIL; List *pending_entries = NIL;
ListCell *pending_entry; ListCell *pending_entry;
/* Iterate over the hash table. */ /* Iterate over the hash table. */
hash_seq_init(&hash_seq, pgss_hash); hash_seq_init(&hash_seq, pgss_hash);
while ((entry = hash_seq_search(&hash_seq)) != NULL) while ((entry = hash_seq_search(&hash_seq)) != NULL)
{ {
/* /*
* Remove all entries if new_bucket_id == -1. * Remove all entries if new_bucket_id == -1. Otherwise remove entry
* Otherwise remove entry in new_bucket_id if it has finished already. * in new_bucket_id if it has finished already.
*/ */
if (new_bucket_id < 0 || if (new_bucket_id < 0 ||
(entry->key.bucket_id == new_bucket_id && (entry->key.bucket_id == new_bucket_id &&
(entry->counters.state == PGSS_FINISHED || entry->counters.state == PGSS_ERROR))) (entry->counters.state == PGSS_FINISHED || entry->counters.state == PGSS_ERROR)))
{ {
if (new_bucket_id == -1) { if (new_bucket_id == -1)
/* pg_stat_monitor_reset(), remove entry from query hash table too. */ {
/*
* pg_stat_monitor_reset(), remove entry from query hash table
* too.
*/
hash_search(pgss_query_hash, &(entry->key.queryid), HASH_REMOVE, NULL); hash_search(pgss_query_hash, &(entry->key.queryid), HASH_REMOVE, NULL);
} }
@ -201,11 +206,10 @@ hash_entry_dealloc(int new_bucket_id, int old_bucket_id, unsigned char *query_bu
} }
/* /*
* If we detect a pending query residing in the previous bucket id, * If we detect a pending query residing in the previous bucket id, we
* we add it to a list of pending elements to be moved to the new * add it to a list of pending elements to be moved to the new bucket
* bucket id. * id. Can't update the hash table while iterating it inside this
* Can't update the hash table while iterating it inside this loop, * loop, as this may introduce all sort of problems.
* as this may introduce all sort of problems.
*/ */
if (old_bucket_id != -1 && entry->key.bucket_id == old_bucket_id) if (old_bucket_id != -1 && entry->key.bucket_id == old_bucket_id)
{ {
@ -213,19 +217,23 @@ hash_entry_dealloc(int new_bucket_id, int old_bucket_id, unsigned char *query_bu
entry->counters.state == PGSS_PLAN || entry->counters.state == PGSS_PLAN ||
entry->counters.state == PGSS_EXEC) entry->counters.state == PGSS_EXEC)
{ {
pgssEntry *bkp_entry = malloc(sizeof(pgssEntry)); pgssEntry *bkp_entry = malloc(sizeof(pgssEntry));
if (!bkp_entry) if (!bkp_entry)
{ {
elog(DEBUG1, "hash_entry_dealloc: out of memory"); elog(DEBUG1, "hash_entry_dealloc: out of memory");
/* /*
* No memory, If the entry has calls > 1 then we change the state to finished, * No memory, If the entry has calls > 1 then we change
* as the pending query will likely finish execution during the new bucket * the state to finished, as the pending query will likely
* time window. The pending query will vanish in this case, can't list it * finish execution during the new bucket time window. The
* pending query will vanish in this case, can't list it
* until it completes. * until it completes.
* *
* If there is only one call to the query and it's pending, remove the * If there is only one call to the query and it's
* entry from the previous bucket and allow it to finish in the new bucket, * pending, remove the entry from the previous bucket and
* in order to avoid the query living in the old bucket forever. * allow it to finish in the new bucket, in order to avoid
* the query living in the old bucket forever.
*/ */
if (entry->counters.calls.calls > 1) if (entry->counters.calls.calls > 1)
entry->counters.state = PGSS_FINISHED; entry->counters.state = PGSS_FINISHED;
@ -244,14 +252,16 @@ hash_entry_dealloc(int new_bucket_id, int old_bucket_id, unsigned char *query_bu
pending_entries = lappend(pending_entries, bkp_entry); pending_entries = lappend(pending_entries, bkp_entry);
/* /*
* If the entry has calls > 1 then we change the state to finished in * If the entry has calls > 1 then we change the state to
* the previous bucket, as the pending query will likely finish execution * finished in the previous bucket, as the pending query will
* during the new bucket time window. Can't remove it from the previous bucket * likely finish execution during the new bucket time window.
* as it may have many calls and we would lose the query statistics. * Can't remove it from the previous bucket as it may have
* many calls and we would lose the query statistics.
* *
* If there is only one call to the query and it's pending, remove the entry * If there is only one call to the query and it's pending,
* from the previous bucket and allow it to finish in the new bucket, * remove the entry from the previous bucket and allow it to
* in order to avoid the query living in the old bucket forever. * finish in the new bucket, in order to avoid the query
* living in the old bucket forever.
*/ */
if (entry->counters.calls.calls > 1) if (entry->counters.calls.calls > 1)
entry->counters.state = PGSS_FINISHED; entry->counters.state = PGSS_FINISHED;
@ -262,13 +272,14 @@ hash_entry_dealloc(int new_bucket_id, int old_bucket_id, unsigned char *query_bu
} }
/* /*
* Iterate over the list of pending queries in order * Iterate over the list of pending queries in order to add them back to
* to add them back to the hash table with the updated bucket id. * the hash table with the updated bucket id.
*/ */
foreach (pending_entry, pending_entries) { foreach(pending_entry, pending_entries)
bool found = false; {
pgssEntry *new_entry; bool found = false;
pgssEntry *old_entry = (pgssEntry *) lfirst(pending_entry); pgssEntry *new_entry;
pgssEntry *old_entry = (pgssEntry *) lfirst(pending_entry);
new_entry = (pgssEntry *) hash_search(pgss_hash, &old_entry->key, HASH_ENTER_NULL, &found); new_entry = (pgssEntry *) hash_search(pgss_hash, &old_entry->key, HASH_ENTER_NULL, &found);
if (new_entry == NULL) if (new_entry == NULL)
@ -294,9 +305,9 @@ hash_entry_dealloc(int new_bucket_id, int old_bucket_id, unsigned char *query_bu
void void
hash_entry_reset() hash_entry_reset()
{ {
pgssSharedState *pgss = pgsm_get_ss(); pgssSharedState *pgss = pgsm_get_ss();
HASH_SEQ_STATUS hash_seq; HASH_SEQ_STATUS hash_seq;
pgssEntry *entry; pgssEntry *entry;
LWLockAcquire(pgss->lock, LW_EXCLUSIVE); LWLockAcquire(pgss->lock, LW_EXCLUSIVE);

File diff suppressed because it is too large Load Diff

View File

@ -104,27 +104,28 @@
#define MAX_ENUM_OPTIONS 6 #define MAX_ENUM_OPTIONS 6
typedef struct GucVariables typedef struct GucVariables
{ {
enum config_type type; /* PGC_BOOL, PGC_INT, PGC_REAL, PGC_STRING, PGC_ENUM */ enum config_type type; /* PGC_BOOL, PGC_INT, PGC_REAL, PGC_STRING,
int guc_variable; * PGC_ENUM */
char guc_name[TEXT_LEN]; int guc_variable;
char guc_desc[TEXT_LEN]; char guc_name[TEXT_LEN];
int guc_default; char guc_desc[TEXT_LEN];
int guc_min; int guc_default;
int guc_max; int guc_min;
int guc_unit; int guc_max;
int *guc_value; int guc_unit;
bool guc_restart; int *guc_value;
int n_options; bool guc_restart;
char guc_options[MAX_ENUM_OPTIONS][32]; int n_options;
} GucVariable; char guc_options[MAX_ENUM_OPTIONS][32];
} GucVariable;
#if PG_VERSION_NUM < 130000 #if PG_VERSION_NUM < 130000
typedef struct WalUsage typedef struct WalUsage
{ {
long wal_records; /* # of WAL records produced */ long wal_records; /* # of WAL records produced */
long wal_fpi; /* # of WAL full page images produced */ long wal_fpi; /* # of WAL full page images produced */
uint64 wal_bytes; /* size of WAL records produced */ uint64 wal_bytes; /* size of WAL records produced */
} WalUsage; } WalUsage;
#endif #endif
@ -132,7 +133,7 @@ typedef enum OVERFLOW_TARGET
{ {
OVERFLOW_TARGET_NONE = 0, OVERFLOW_TARGET_NONE = 0,
OVERFLOW_TARGET_DISK OVERFLOW_TARGET_DISK
} OVERFLOW_TARGET; } OVERFLOW_TARGET;
typedef enum pgssStoreKind typedef enum pgssStoreKind
{ {
@ -163,19 +164,19 @@ typedef enum AGG_KEY
AGG_KEY_DATABASE = 0, AGG_KEY_DATABASE = 0,
AGG_KEY_USER, AGG_KEY_USER,
AGG_KEY_HOST AGG_KEY_HOST
} AGG_KEY; } AGG_KEY;
#define MAX_QUERY_LEN 1024 #define MAX_QUERY_LEN 1024
/* shared memory storage for the query */ /* shared memory storage for the query */
typedef struct CallTime typedef struct CallTime
{ {
double total_time; /* total execution time, in msec */ double total_time; /* total execution time, in msec */
double min_time; /* minimum execution time in msec */ double min_time; /* minimum execution time in msec */
double max_time; /* maximum execution time in msec */ double max_time; /* maximum execution time in msec */
double mean_time; /* mean execution time in msec */ double mean_time; /* mean execution time in msec */
double sum_var_time; /* sum of variances in execution time in msec */ double sum_var_time; /* sum of variances in execution time in msec */
} CallTime; } CallTime;
/* /*
* Entry type for queries hash table (query ID). * Entry type for queries hash table (query ID).
@ -188,16 +189,16 @@ typedef struct CallTime
*/ */
typedef struct pgssQueryEntry typedef struct pgssQueryEntry
{ {
uint64 queryid; /* query identifier, also the key. */ uint64 queryid; /* query identifier, also the key. */
size_t query_pos; /* query location within query buffer */ size_t query_pos; /* query location within query buffer */
} pgssQueryEntry; } pgssQueryEntry;
typedef struct PlanInfo typedef struct PlanInfo
{ {
uint64 planid; /* plan identifier */ uint64 planid; /* plan identifier */
char plan_text[PLAN_TEXT_LEN]; /* plan text */ char plan_text[PLAN_TEXT_LEN]; /* plan text */
size_t plan_len; /* strlen(plan_text) */ size_t plan_len; /* strlen(plan_text) */
} PlanInfo; } PlanInfo;
typedef struct pgssHashKey typedef struct pgssHashKey
{ {
@ -208,63 +209,66 @@ typedef struct pgssHashKey
uint64 ip; /* client ip address */ uint64 ip; /* client ip address */
uint64 planid; /* plan identifier */ uint64 planid; /* plan identifier */
uint64 appid; /* hash of application name */ uint64 appid; /* hash of application name */
uint64 toplevel; /* query executed at top level */ uint64 toplevel; /* query executed at top level */
} pgssHashKey; } pgssHashKey;
typedef struct QueryInfo typedef struct QueryInfo
{ {
uint64 parentid; /* parent queryid of current query*/ uint64 parentid; /* parent queryid of current query */
int64 type; /* type of query, options are query, info, warning, error, fatal */ int64 type; /* type of query, options are query, info,
* warning, error, fatal */
char application_name[APPLICATIONNAME_LEN]; char application_name[APPLICATIONNAME_LEN];
char comments[COMMENTS_LEN]; char comments[COMMENTS_LEN];
char relations[REL_LST][REL_LEN]; /* List of relation involved in the query */ char relations[REL_LST][REL_LEN]; /* List of relation involved
int num_relations; /* Number of relation in the query */ * in the query */
CmdType cmd_type; /* query command type SELECT/UPDATE/DELETE/INSERT */ int num_relations; /* Number of relation in the query */
CmdType cmd_type; /* query command type
* SELECT/UPDATE/DELETE/INSERT */
} QueryInfo; } QueryInfo;
typedef struct ErrorInfo typedef struct ErrorInfo
{ {
int64 elevel; /* error elevel */ int64 elevel; /* error elevel */
char sqlcode[SQLCODE_LEN]; /* error sqlcode */ char sqlcode[SQLCODE_LEN]; /* error sqlcode */
char message[ERROR_MESSAGE_LEN]; /* error message text */ char message[ERROR_MESSAGE_LEN]; /* error message text */
} ErrorInfo; } ErrorInfo;
typedef struct Calls typedef struct Calls
{ {
int64 calls; /* # of times executed */ int64 calls; /* # of times executed */
int64 rows; /* total # of retrieved or affected rows */ int64 rows; /* total # of retrieved or affected rows */
double usage; /* usage factor */ double usage; /* usage factor */
} Calls; } Calls;
typedef struct Blocks typedef struct Blocks
{ {
int64 shared_blks_hit; /* # of shared buffer hits */ int64 shared_blks_hit; /* # of shared buffer hits */
int64 shared_blks_read; /* # of shared disk blocks read */ int64 shared_blks_read; /* # of shared disk blocks read */
int64 shared_blks_dirtied; /* # of shared disk blocks dirtied */ int64 shared_blks_dirtied; /* # of shared disk blocks dirtied */
int64 shared_blks_written; /* # of shared disk blocks written */ int64 shared_blks_written; /* # of shared disk blocks written */
int64 local_blks_hit; /* # of local buffer hits */ int64 local_blks_hit; /* # of local buffer hits */
int64 local_blks_read; /* # of local disk blocks read */ int64 local_blks_read; /* # of local disk blocks read */
int64 local_blks_dirtied; /* # of local disk blocks dirtied */ int64 local_blks_dirtied; /* # of local disk blocks dirtied */
int64 local_blks_written; /* # of local disk blocks written */ int64 local_blks_written; /* # of local disk blocks written */
int64 temp_blks_read; /* # of temp blocks read */ int64 temp_blks_read; /* # of temp blocks read */
int64 temp_blks_written; /* # of temp blocks written */ int64 temp_blks_written; /* # of temp blocks written */
double blk_read_time; /* time spent reading, in msec */ double blk_read_time; /* time spent reading, in msec */
double blk_write_time; /* time spent writing, in msec */ double blk_write_time; /* time spent writing, in msec */
} Blocks; } Blocks;
typedef struct SysInfo typedef struct SysInfo
{ {
float utime; /* user cpu time */ float utime; /* user cpu time */
float stime; /* system cpu time */ float stime; /* system cpu time */
} SysInfo; } SysInfo;
typedef struct Wal_Usage typedef struct Wal_Usage
{ {
int64 wal_records; /* # of WAL records generated */ int64 wal_records; /* # of WAL records generated */
int64 wal_fpi; /* # of WAL full page images generated */ int64 wal_fpi; /* # of WAL full page images generated */
uint64 wal_bytes; /* total amount of WAL bytes generated */ uint64 wal_bytes; /* total amount of WAL bytes generated */
} Wal_Usage; } Wal_Usage;
typedef struct Counters typedef struct Counters
{ {
@ -275,14 +279,15 @@ typedef struct Counters
Calls plancalls; Calls plancalls;
CallTime plantime; CallTime plantime;
PlanInfo planinfo; PlanInfo planinfo;
Blocks blocks; Blocks blocks;
SysInfo sysinfo; SysInfo sysinfo;
ErrorInfo error; ErrorInfo error;
Wal_Usage walusage; Wal_Usage walusage;
int resp_calls[MAX_RESPONSE_BUCKET]; /* execution time's in msec */ int resp_calls[MAX_RESPONSE_BUCKET]; /* execution time's in
uint64 state; /* query state */ * msec */
uint64 state; /* query state */
} Counters; } Counters;
/* Some global structure to get the cpu usage, really don't like the idea of global variable */ /* Some global structure to get the cpu usage, really don't like the idea of global variable */
@ -292,11 +297,11 @@ typedef struct Counters
*/ */
typedef struct pgssEntry typedef struct pgssEntry
{ {
pgssHashKey key; /* hash key of entry - MUST BE FIRST */ pgssHashKey key; /* hash key of entry - MUST BE FIRST */
Counters counters; /* the statistics for this query */ Counters counters; /* the statistics for this query */
int encoding; /* query text encoding */ int encoding; /* query text encoding */
slock_t mutex; /* protects the counters only */ slock_t mutex; /* protects the counters only */
size_t query_pos; /* query location within query buffer */ size_t query_pos; /* query location within query buffer */
} pgssEntry; } pgssEntry;
/* /*
@ -304,30 +309,33 @@ typedef struct pgssEntry
*/ */
typedef struct pgssSharedState typedef struct pgssSharedState
{ {
LWLock *lock; /* protects hashtable search/modification */ LWLock *lock; /* protects hashtable search/modification */
double cur_median_usage; /* current median usage in hashtable */ double cur_median_usage; /* current median usage in hashtable */
slock_t mutex; /* protects following fields only: */ slock_t mutex; /* protects following fields only: */
Size extent; /* current extent of query file */ Size extent; /* current extent of query file */
int64 n_writers; /* number of active writers to query file */ int64 n_writers; /* number of active writers to query file */
pg_atomic_uint64 current_wbucket; pg_atomic_uint64 current_wbucket;
pg_atomic_uint64 prev_bucket_sec; pg_atomic_uint64 prev_bucket_sec;
uint64 bucket_entry[MAX_BUCKETS]; uint64 bucket_entry[MAX_BUCKETS];
char bucket_start_time[MAX_BUCKETS][60]; /* start time of the bucket */ char bucket_start_time[MAX_BUCKETS][60]; /* start time of the
LWLock *errors_lock; /* protects errors hashtable search/modification */ * bucket */
LWLock *errors_lock; /* protects errors hashtable
* search/modification */
/* /*
* These variables are used when pgsm_overflow_target is ON. * These variables are used when pgsm_overflow_target is ON.
* *
* overflow is set to true when the query buffer overflows. * overflow is set to true when the query buffer overflows.
* *
* n_bucket_cycles counts the number of times we changed bucket * n_bucket_cycles counts the number of times we changed bucket since the
* since the query buffer overflowed. When it reaches pgsm_max_buckets * query buffer overflowed. When it reaches pgsm_max_buckets we remove the
* we remove the dump file, also reset the counter. * dump file, also reset the counter.
* *
* This allows us to avoid having a large file on disk that would also * This allows us to avoid having a large file on disk that would also
* slowdown queries to the pg_stat_monitor view. * slowdown queries to the pg_stat_monitor view.
*/ */
bool overflow; bool overflow;
size_t n_bucket_cycles; size_t n_bucket_cycles;
} pgssSharedState; } pgssSharedState;
#define ResetSharedState(x) \ #define ResetSharedState(x) \
@ -350,6 +358,7 @@ typedef struct LocationLen
int location; /* start offset in query text */ int location; /* start offset in query text */
int length; /* length in bytes, or -1 to ignore */ int length; /* length in bytes, or -1 to ignore */
} LocationLen; } LocationLen;
/* /*
* Working state for computing a query jumble and producing a normalized * Working state for computing a query jumble and producing a normalized
* query string * query string
@ -378,54 +387,56 @@ typedef struct JumbleState
/* Links to shared memory state */ /* Links to shared memory state */
bool SaveQueryText(uint64 bucketid, bool SaveQueryText(uint64 bucketid,
uint64 queryid, uint64 queryid,
unsigned char *buf, unsigned char *buf,
const char *query, const char *query,
uint64 query_len, uint64 query_len,
size_t *query_pos); size_t *query_pos);
/* guc.c */ /* guc.c */
void init_guc(void); void init_guc(void);
GucVariable *get_conf(int i); GucVariable *get_conf(int i);
/* hash_create.c */ /* hash_create.c */
bool IsHashInitialize(void); bool IsHashInitialize(void);
void pgss_shmem_startup(void); void pgss_shmem_startup(void);
void pgss_shmem_shutdown(int code, Datum arg); void pgss_shmem_shutdown(int code, Datum arg);
int pgsm_get_bucket_size(void); int pgsm_get_bucket_size(void);
pgssSharedState* pgsm_get_ss(void); pgssSharedState *pgsm_get_ss(void);
HTAB *pgsm_get_plan_hash(void); HTAB *pgsm_get_plan_hash(void);
HTAB *pgsm_get_hash(void); HTAB *pgsm_get_hash(void);
HTAB *pgsm_get_query_hash(void); HTAB *pgsm_get_query_hash(void);
HTAB *pgsm_get_plan_hash(void); HTAB *pgsm_get_plan_hash(void);
void hash_entry_reset(void); void hash_entry_reset(void);
void hash_query_entryies_reset(void); void hash_query_entryies_reset(void);
void hash_query_entries(); void hash_query_entries();
void hash_query_entry_dealloc(int new_bucket_id, int old_bucket_id, unsigned char *query_buffer[]); void hash_query_entry_dealloc(int new_bucket_id, int old_bucket_id, unsigned char *query_buffer[]);
void hash_entry_dealloc(int new_bucket_id, int old_bucket_id, unsigned char *query_buffer); void hash_entry_dealloc(int new_bucket_id, int old_bucket_id, unsigned char *query_buffer);
pgssEntry* hash_entry_alloc(pgssSharedState *pgss, pgssHashKey *key, int encoding); pgssEntry *hash_entry_alloc(pgssSharedState *pgss, pgssHashKey *key, int encoding);
Size hash_memsize(void); Size hash_memsize(void);
int read_query_buffer(int bucket_id, uint64 queryid, char *query_txt, size_t pos); int read_query_buffer(int bucket_id, uint64 queryid, char *query_txt, size_t pos);
uint64 read_query(unsigned char *buf, uint64 queryid, char * query, size_t pos); uint64 read_query(unsigned char *buf, uint64 queryid, char *query, size_t pos);
void pgss_startup(void); void pgss_startup(void);
void set_qbuf(unsigned char *); void set_qbuf(unsigned char *);
/* hash_query.c */ /* hash_query.c */
void pgss_startup(void); void pgss_startup(void);
/*---- GUC variables ----*/ /*---- GUC variables ----*/
typedef enum { typedef enum
PSGM_TRACK_NONE = 0, /* track no statements */ {
PGSM_TRACK_TOP, /* only top level statements */ PSGM_TRACK_NONE = 0, /* track no statements */
PGSM_TRACK_ALL /* all statements, including nested ones */ PGSM_TRACK_TOP, /* only top level statements */
} PGSMTrackLevel; PGSM_TRACK_ALL /* all statements, including nested ones */
} PGSMTrackLevel;
static const struct config_enum_entry track_options[] = static const struct config_enum_entry track_options[] =
{ {
{"none", PSGM_TRACK_NONE, false}, {"none", PSGM_TRACK_NONE, false},
{"top", PGSM_TRACK_TOP, false}, {"top", PGSM_TRACK_TOP, false},
{"all", PGSM_TRACK_ALL, false}, {"all", PGSM_TRACK_ALL, false},
{NULL, 0, false} {NULL, 0, false}
}; };
#define PGSM_MAX get_conf(0)->guc_variable #define PGSM_MAX get_conf(0)->guc_variable
@ -452,7 +463,8 @@ static const struct config_enum_entry track_options[] =
* STATS_START and STATS_END are used only to delimit the range. * STATS_START and STATS_END are used only to delimit the range.
* STATS_END is also the length of the valid items in the enum. * STATS_END is also the length of the valid items in the enum.
*/ */
enum pg_hook_stats_id { enum pg_hook_stats_id
{
STATS_START = -1, STATS_START = -1,
STATS_PGSS_POST_PARSE_ANALYZE, STATS_PGSS_POST_PARSE_ANALYZE,
STATS_PGSS_EXECUTORSTART, STATS_PGSS_EXECUTORSTART,
@ -469,21 +481,22 @@ enum pg_hook_stats_id {
}; };
/* Hold time to execute statistics for a hook. */ /* Hold time to execute statistics for a hook. */
struct pg_hook_stats_t { struct pg_hook_stats_t
char hook_name[64]; {
double min_time; char hook_name[64];
double max_time; double min_time;
double total_time; double max_time;
uint64 ncalls; double total_time;
uint64 ncalls;
}; };
#define HOOK_STATS_SIZE MAXALIGN((size_t)STATS_END * sizeof(struct pg_hook_stats_t)) #define HOOK_STATS_SIZE MAXALIGN((size_t)STATS_END * sizeof(struct pg_hook_stats_t))
/* Allocate a pg_hook_stats_t array of size HOOK_STATS_SIZE on shared memory. */ /* Allocate a pg_hook_stats_t array of size HOOK_STATS_SIZE on shared memory. */
void init_hook_stats(void); void init_hook_stats(void);
/* Update hook time execution statistics. */ /* Update hook time execution statistics. */
void update_hook_stats(enum pg_hook_stats_id hook_id, double time_elapsed); void update_hook_stats(enum pg_hook_stats_id hook_id, double time_elapsed);
/* /*
* Macro used to declare a hook function: * Macro used to declare a hook function:
@ -509,7 +522,7 @@ void update_hook_stats(enum pg_hook_stats_id hook_id, double time_elapsed);
*/ */
#define HOOK(name) name##_benchmark #define HOOK(name) name##_benchmark
#else /* #ifdef BENCHMARK */ #else /* #ifdef BENCHMARK */
#define DECLARE_HOOK(hook, ...) \ #define DECLARE_HOOK(hook, ...) \
static hook(__VA_ARGS__); static hook(__VA_ARGS__);

View File

@ -44,13 +44,14 @@ PG_FUNCTION_INFO_V1(pg_stat_monitor_reset_errors);
static HTAB *pgsm_errors_ht = NULL; static HTAB *pgsm_errors_ht = NULL;
void psgm_errors_init(void) void
psgm_errors_init(void)
{ {
HASHCTL info; HASHCTL info;
#if PG_VERSION_NUM >= 140000 #if PG_VERSION_NUM >= 140000
int flags = HASH_ELEM | HASH_STRINGS; int flags = HASH_ELEM | HASH_STRINGS;
#else #else
int flags = HASH_ELEM | HASH_BLOBS; int flags = HASH_ELEM | HASH_BLOBS;
#endif #endif
@ -58,26 +59,28 @@ void psgm_errors_init(void)
info.keysize = ERROR_MSG_MAX_LEN; info.keysize = ERROR_MSG_MAX_LEN;
info.entrysize = sizeof(ErrorEntry); info.entrysize = sizeof(ErrorEntry);
pgsm_errors_ht = ShmemInitHash("pg_stat_monitor: errors hashtable", pgsm_errors_ht = ShmemInitHash("pg_stat_monitor: errors hashtable",
PSGM_ERRORS_MAX, /* initial size */ PSGM_ERRORS_MAX, /* initial size */
PSGM_ERRORS_MAX, /* maximum size */ PSGM_ERRORS_MAX, /* maximum size */
&info, &info,
flags); flags);
} }
size_t pgsm_errors_size(void) size_t
pgsm_errors_size(void)
{ {
return hash_estimate_size(PSGM_ERRORS_MAX, sizeof(ErrorEntry)); return hash_estimate_size(PSGM_ERRORS_MAX, sizeof(ErrorEntry));
} }
void pgsm_log(PgsmLogSeverity severity, const char *format, ...) void
pgsm_log(PgsmLogSeverity severity, const char *format,...)
{ {
char key[ERROR_MSG_MAX_LEN]; char key[ERROR_MSG_MAX_LEN];
ErrorEntry *entry; ErrorEntry *entry;
bool found = false; bool found = false;
va_list ap; va_list ap;
int n; int n;
struct timeval tv; struct timeval tv;
struct tm *lt; struct tm *lt;
pgssSharedState *pgss; pgssSharedState *pgss;
va_start(ap, format); va_start(ap, format);
@ -94,9 +97,10 @@ void pgsm_log(PgsmLogSeverity severity, const char *format, ...)
if (!entry) if (!entry)
{ {
LWLockRelease(pgss->errors_lock); LWLockRelease(pgss->errors_lock);
/* /*
* We're out of memory, can't track this error message. * We're out of memory, can't track this error message.
*/ */
return; return;
} }
@ -110,13 +114,13 @@ void pgsm_log(PgsmLogSeverity severity, const char *format, ...)
gettimeofday(&tv, NULL); gettimeofday(&tv, NULL);
lt = localtime(&tv.tv_sec); lt = localtime(&tv.tv_sec);
snprintf(entry->time, sizeof(entry->time), snprintf(entry->time, sizeof(entry->time),
"%04d-%02d-%02d %02d:%02d:%02d", "%04d-%02d-%02d %02d:%02d:%02d",
lt->tm_year + 1900, lt->tm_year + 1900,
lt->tm_mon + 1, lt->tm_mon + 1,
lt->tm_mday, lt->tm_mday,
lt->tm_hour, lt->tm_hour,
lt->tm_min, lt->tm_min,
lt->tm_sec); lt->tm_sec);
entry->calls++; entry->calls++;
@ -129,15 +133,15 @@ void pgsm_log(PgsmLogSeverity severity, const char *format, ...)
Datum Datum
pg_stat_monitor_reset_errors(PG_FUNCTION_ARGS) pg_stat_monitor_reset_errors(PG_FUNCTION_ARGS)
{ {
HASH_SEQ_STATUS hash_seq; HASH_SEQ_STATUS hash_seq;
ErrorEntry *entry; ErrorEntry *entry;
pgssSharedState *pgss = pgsm_get_ss(); pgssSharedState *pgss = pgsm_get_ss();
/* Safety check... */ /* Safety check... */
if (!IsSystemInitialized()) if (!IsSystemInitialized())
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
errmsg("pg_stat_monitor: must be loaded via shared_preload_libraries"))); errmsg("pg_stat_monitor: must be loaded via shared_preload_libraries")));
LWLockAcquire(pgss->errors_lock, LW_EXCLUSIVE); LWLockAcquire(pgss->errors_lock, LW_EXCLUSIVE);
@ -157,26 +161,26 @@ pg_stat_monitor_reset_errors(PG_FUNCTION_ARGS)
Datum Datum
pg_stat_monitor_errors(PG_FUNCTION_ARGS) pg_stat_monitor_errors(PG_FUNCTION_ARGS)
{ {
ReturnSetInfo *rsinfo = (ReturnSetInfo *) fcinfo->resultinfo; ReturnSetInfo *rsinfo = (ReturnSetInfo *) fcinfo->resultinfo;
TupleDesc tupdesc; TupleDesc tupdesc;
Tuplestorestate *tupstore; Tuplestorestate *tupstore;
MemoryContext per_query_ctx; MemoryContext per_query_ctx;
MemoryContext oldcontext; MemoryContext oldcontext;
HASH_SEQ_STATUS hash_seq; HASH_SEQ_STATUS hash_seq;
ErrorEntry *error_entry; ErrorEntry *error_entry;
pgssSharedState *pgss = pgsm_get_ss(); pgssSharedState *pgss = pgsm_get_ss();
/* Safety check... */ /* Safety check... */
if (!IsSystemInitialized()) if (!IsSystemInitialized())
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
errmsg("pg_stat_monitor: must be loaded via shared_preload_libraries"))); errmsg("pg_stat_monitor: must be loaded via shared_preload_libraries")));
/* check to see if caller supports us returning a tuplestore */ /* check to see if caller supports us returning a tuplestore */
if (rsinfo == NULL || !IsA(rsinfo, ReturnSetInfo)) if (rsinfo == NULL || !IsA(rsinfo, ReturnSetInfo))
ereport(ERROR, ereport(ERROR,
(errcode(ERRCODE_FEATURE_NOT_SUPPORTED), (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
errmsg("pg_stat_monitor: set-valued function called in context that cannot accept a set"))); errmsg("pg_stat_monitor: set-valued function called in context that cannot accept a set")));
/* Switch into long-lived context to construct returned data structures */ /* Switch into long-lived context to construct returned data structures */
per_query_ctx = rsinfo->econtext->ecxt_per_query_memory; per_query_ctx = rsinfo->econtext->ecxt_per_query_memory;
@ -204,6 +208,7 @@ pg_stat_monitor_errors(PG_FUNCTION_ARGS)
Datum values[4]; Datum values[4];
bool nulls[4]; bool nulls[4];
int i = 0; int i = 0;
memset(values, 0, sizeof(values)); memset(values, 0, sizeof(values));
memset(nulls, 0, sizeof(nulls)); memset(nulls, 0, sizeof(nulls));
@ -219,5 +224,5 @@ pg_stat_monitor_errors(PG_FUNCTION_ARGS)
/* clean up and return the tuplestore */ /* clean up and return the tuplestore */
tuplestore_donestoring(tupstore); tuplestore_donestoring(tupstore);
return (Datum)0; return (Datum) 0;
} }