diff --git a/Makefile b/Makefile index 6f0096c4..dab62736 100644 --- a/Makefile +++ b/Makefile @@ -29,6 +29,7 @@ REGRESS = basic \ squashing \ tags \ user \ + rollback \ level_tracking \ decode_error_level \ parallel \ diff --git a/pg_stat_monitor.c b/pg_stat_monitor.c index dcdee2fb..6223c05f 100644 --- a/pg_stat_monitor.c +++ b/pg_stat_monitor.c @@ -1743,19 +1743,16 @@ pgsm_create_hash_entry(uint64 bucket_id, int64 queryid, PlanInfo *plan_info) { datname = get_database_name(entry->key.dbid); username = GetUserNameFromId(entry->key.userid, true); - } - - if (!datname) - datname = pnstrdup("", sizeof(entry->datname) - 1); - if (!username) - username = pnstrdup("", sizeof(entry->username) - 1); + snprintf(entry->datname, sizeof(entry->datname), "%s", datname); + snprintf(entry->username, sizeof(entry->username), "%s", username); - snprintf(entry->datname, sizeof(entry->datname), "%s", datname); - snprintf(entry->username, sizeof(entry->username), "%s", username); + if (datname) + pfree(datname); - pfree(datname); - pfree(username); + if (username) + pfree(username); + } MemoryContextSwitchTo(oldctx); diff --git a/regression/expected/rollback.out b/regression/expected/rollback.out new file mode 100644 index 00000000..9505591c --- /dev/null +++ b/regression/expected/rollback.out @@ -0,0 +1,72 @@ +CREATE EXTENSION pg_stat_monitor; +CREATE USER u WITH SUPERUSER; +SET ROLE u; +CREATE TABLE t (a int PRIMARY KEY) ; +SELECT pg_stat_monitor_reset(); + pg_stat_monitor_reset +----------------------- + +(1 row) + +BEGIN; +INSERT INTO t VALUES (1); +COMMIT; +SELECT query, username, datname FROM pg_stat_monitor ORDER BY query COLLATE "C"; + query | username | datname +--------------------------------+----------+-------------------- + BEGIN | u | contrib_regression + COMMIT | u | contrib_regression + INSERT INTO t VALUES (1) | u | contrib_regression + SELECT pg_stat_monitor_reset() | u | contrib_regression +(4 rows) + +SELECT pg_stat_monitor_reset(); + pg_stat_monitor_reset +----------------------- + +(1 row) + +-- During manual rollback we will be able to get username and datname of the query that was rolled back. +BEGIN; +INSERT INTO t VALUES (2); +ROLLBACK; +SELECT query, username, datname FROM pg_stat_monitor ORDER BY query COLLATE "C"; + query | username | datname +--------------------------------+----------+-------------------- + BEGIN | u | contrib_regression + INSERT INTO t VALUES (2) | u | contrib_regression + ROLLBACK | u | contrib_regression + SELECT pg_stat_monitor_reset() | u | contrib_regression +(4 rows) + +SELECT pg_stat_monitor_reset(); + pg_stat_monitor_reset +----------------------- + +(1 row) + +-- If transaction is rolled back due an error, we won't be able to get username and datname of the query that was rolled back. +BEGIN; +INSERT INTO t VALUES (1); +ERROR: duplicate key value violates unique constraint "t_pkey" +DETAIL: Key (a)=(1) already exists. +ROLLBACK; +SELECT query, username, datname FROM pg_stat_monitor ORDER BY query COLLATE "C"; + query | username | datname +--------------------------------+----------+-------------------- + BEGIN | u | contrib_regression + INSERT INTO t VALUES (1); | u | contrib_regression + ROLLBACK | | + SELECT pg_stat_monitor_reset() | u | contrib_regression +(4 rows) + +SELECT pg_stat_monitor_reset(); + pg_stat_monitor_reset +----------------------- + +(1 row) + +DROP TABLE t; +SET ROLE NONE; +DROP USER u; +DROP EXTENSION pg_stat_monitor; diff --git a/regression/sql/rollback.sql b/regression/sql/rollback.sql new file mode 100644 index 00000000..b1f9d2cd --- /dev/null +++ b/regression/sql/rollback.sql @@ -0,0 +1,36 @@ +CREATE EXTENSION pg_stat_monitor; + +CREATE USER u WITH SUPERUSER; +SET ROLE u; +CREATE TABLE t (a int PRIMARY KEY) ; + +SELECT pg_stat_monitor_reset(); + +BEGIN; +INSERT INTO t VALUES (1); +COMMIT; + +SELECT query, username, datname FROM pg_stat_monitor ORDER BY query COLLATE "C"; +SELECT pg_stat_monitor_reset(); + +-- During manual rollback we will be able to get username and datname of the query that was rolled back. +BEGIN; +INSERT INTO t VALUES (2); +ROLLBACK; + +SELECT query, username, datname FROM pg_stat_monitor ORDER BY query COLLATE "C"; +SELECT pg_stat_monitor_reset(); + +-- If transaction is rolled back due an error, we won't be able to get username and datname of the query that was rolled back. +BEGIN; +INSERT INTO t VALUES (1); +ROLLBACK; + +SELECT query, username, datname FROM pg_stat_monitor ORDER BY query COLLATE "C"; +SELECT pg_stat_monitor_reset(); + +DROP TABLE t; +SET ROLE NONE; +DROP USER u; + +DROP EXTENSION pg_stat_monitor;