From 42944557d8bbfb376051bd0c4822da503c4482af Mon Sep 17 00:00:00 2001 From: kmoppel Date: Mon, 29 Jun 2026 15:47:27 +0300 Subject: [PATCH 1/9] Add a new optional --query-id flag To include pg_stat_activity.query_id in processlist output. Column available since v14, depending on compute_query_id server parameter though. --- pgactivity/cli.py | 13 +- pgactivity/config.py | 7 +- pgactivity/data.py | 12 +- pgactivity/queries/get_blocking_oldest.sql | 3 +- .../queries/get_blocking_post_090200.sql | 3 +- .../queries/get_blocking_post_090600.sql | 3 +- .../queries/get_blocking_post_140000.sql | 130 ++++++++++++++++++ pgactivity/queries/get_pg_activity_oldest.sql | 3 +- .../queries/get_pg_activity_post_090200.sql | 3 +- .../queries/get_pg_activity_post_090400.sql | 3 +- .../queries/get_pg_activity_post_090600.sql | 3 +- .../queries/get_pg_activity_post_100000.sql | 3 +- .../queries/get_pg_activity_post_110000.sql | 3 +- .../queries/get_pg_activity_post_130000.sql | 3 +- .../queries/get_pg_activity_post_140000.sql | 32 +++++ .../queries/get_waiting_post_140000.sql | 31 +++++ pgactivity/types.py | 15 ++ tests/data/local-processes-input.json | 39 ++++++ tests/test_cli.py | 4 +- tests/test_cli_help.txt | 2 + tests/test_cli_help_py312.txt | 2 + tests/test_config.py | 4 + tests/test_ui.txt | 1 + tests/test_views.py | 39 ++++++ tests/test_views.txt | 13 +- 25 files changed, 351 insertions(+), 23 deletions(-) create mode 100644 pgactivity/queries/get_blocking_post_140000.sql create mode 100644 pgactivity/queries/get_pg_activity_post_140000.sql create mode 100644 pgactivity/queries/get_waiting_post_140000.sql diff --git a/pgactivity/cli.py b/pgactivity/cli.py index 000e01b4..8b894851 100755 --- a/pgactivity/cli.py +++ b/pgactivity/cli.py @@ -45,14 +45,21 @@ def configure_logger(debug_file: str | None = None) -> StringIO: return memory_string -def flag(p: Any, spec: str, *, dest: str, feature: str) -> None: +def flag( + p: Any, + spec: str, + *, + dest: str, + feature: str, + default: bool | None = None, +) -> None: assert not spec.startswith("--no-") and spec.startswith("--"), spec p.add_argument( spec, dest=dest, help=f"Enable/disable {feature}.", action=argparse.BooleanOptionalAction, - default=None, + default=default, ) @@ -240,6 +247,8 @@ def get_parser(prog: str | None = None) -> argparse.ArgumentParser: flag(group, "--time", dest="time", feature="TIME+") flag(group, "--wait", dest="wait", feature="W") flag(group, "--app-name", dest="appname", feature="APP") + # QUERYID is opt-in to avoid widening the process table by default. + flag(group, "--query-id", dest="queryid", feature="QUERYID", default=False) group = parser.add_argument_group("Header display options") group.add_argument( diff --git a/pgactivity/config.py b/pgactivity/config.py index 234e1390..5b487c68 100644 --- a/pgactivity/config.py +++ b/pgactivity/config.py @@ -62,9 +62,9 @@ class Flag(enum.Flag): """Column flag. >>> Flag.names() - ['database', 'appname', 'client', 'user', 'cpu', 'mem', 'read', 'write', 'time', 'wait', 'relation', 'type', 'mode', 'iowait', 'pid', 'xmin'] + ['database', 'appname', 'client', 'user', 'cpu', 'mem', 'read', 'write', 'time', 'wait', 'relation', 'type', 'mode', 'iowait', 'pid', 'xmin', 'queryid'] >>> Flag.all() # doctest: +ELLIPSIS - + """ DATABASE = enum.auto() @@ -83,6 +83,7 @@ class Flag(enum.Flag): IOWAIT = enum.auto() PID = enum.auto() XMIN = enum.auto() + QUERYID = enum.auto() @classmethod def names(cls) -> list[str]: @@ -127,6 +128,7 @@ def load( database: bool | None, mem: bool | None, pid: bool | None, + queryid: bool | None, read: bool | None, time: bool | None, user: bool | None, @@ -147,6 +149,7 @@ def load( (database, cls.DATABASE), (mem, cls.MEM), (pid, cls.PID), + (queryid, cls.QUERYID), (read, cls.READ), (time, cls.TIME), (user, cls.USER), diff --git a/pgactivity/data.py b/pgactivity/data.py index cf236ee9..73430517 100644 --- a/pgactivity/data.py +++ b/pgactivity/data.py @@ -392,7 +392,9 @@ def pg_get_activities(self, duration_mode: int = 1) -> list[RunningProcess]: """ Get activity from pg_stat_activity view. """ - if self.pg_num_version >= 130000: + if self.pg_num_version >= 140000: + qs = queries.get("get_pg_activity_post_140000") + elif self.pg_num_version >= 130000: qs = queries.get("get_pg_activity_post_130000") elif self.pg_num_version >= 110000: qs = queries.get("get_pg_activity_post_110000") @@ -427,7 +429,9 @@ def pg_get_waiting(self, duration_mode: int = 1) -> list[WaitingProcess]: """ Get waiting queries. """ - if self.pg_num_version >= 90200: + if self.pg_num_version >= 140000: + qs = queries.get("get_waiting_post_140000") + elif self.pg_num_version >= 90200: qs = queries.get("get_waiting_post_090200") else: qs = queries.get("get_waiting_oldest") @@ -454,7 +458,9 @@ def pg_get_blocking(self, duration_mode: int = 1) -> list[BlockingProcess]: """ Get blocking queries """ - if self.pg_num_version >= 90600: + if self.pg_num_version >= 140000: + qs = queries.get("get_blocking_post_140000") + elif self.pg_num_version >= 90600: qs = queries.get("get_blocking_post_090600") elif self.pg_num_version >= 90200: qs = queries.get("get_blocking_post_090200") diff --git a/pgactivity/queries/get_blocking_oldest.sql b/pgactivity/queries/get_blocking_oldest.sql index b238f262..f477aa71 100644 --- a/pgactivity/queries/get_blocking_oldest.sql +++ b/pgactivity/queries/get_blocking_oldest.sql @@ -20,7 +20,8 @@ SELECT ELSE sq.query END AS query, pg_catalog.pg_encoding_to_char(b.encoding) AS encoding, - waiting AS wait + waiting AS wait, + NULL::int8 AS query_id FROM ( -- Transaction id lock diff --git a/pgactivity/queries/get_blocking_post_090200.sql b/pgactivity/queries/get_blocking_post_090200.sql index 7baf9cc4..1e82daae 100644 --- a/pgactivity/queries/get_blocking_post_090200.sql +++ b/pgactivity/queries/get_blocking_post_090200.sql @@ -15,7 +15,8 @@ SELECT state, sq.query AS query, pg_catalog.pg_encoding_to_char(b.encoding) AS encoding, - waiting as wait + waiting as wait, + NULL::int8 AS query_id FROM ( -- Transaction id lock diff --git a/pgactivity/queries/get_blocking_post_090600.sql b/pgactivity/queries/get_blocking_post_090600.sql index 1d82b131..ac6c4628 100644 --- a/pgactivity/queries/get_blocking_post_090600.sql +++ b/pgactivity/queries/get_blocking_post_090600.sql @@ -13,7 +13,8 @@ SELECT state, sq.query AS query, pg_catalog.pg_encoding_to_char(b.encoding) AS encoding, - wait_event as wait + wait_event as wait, + NULL::int8 AS query_id FROM ( -- Transaction id lock diff --git a/pgactivity/queries/get_blocking_post_140000.sql b/pgactivity/queries/get_blocking_post_140000.sql new file mode 100644 index 00000000..b2eba98c --- /dev/null +++ b/pgactivity/queries/get_blocking_post_140000.sql @@ -0,0 +1,130 @@ +-- Get blocking queries >= 14 +SELECT + pid, + application_name, + sq.datname AS database, + usename AS user, + client, + relation, + mode, + locktype AS type, + duration, + state, + sq.query AS query, + pg_catalog.pg_encoding_to_char(b.encoding) AS encoding, + wait_event as wait, + query_id + FROM + ( + -- Transaction id lock + SELECT + blocking.pid, + pg_stat_activity.application_name, + pg_stat_activity.query, + blocking.mode, + pg_stat_activity.datname, + pg_stat_activity.datid, + pg_stat_activity.usename, + pg_stat_activity.client_addr AS client, + blocking.locktype, + EXTRACT(epoch FROM (NOW() - pg_stat_activity.{duration_column})) AS duration, + pg_stat_activity.state as state, + blocking.relation::regclass AS relation, + pg_stat_activity.wait_event, + pg_stat_activity.query_id + FROM + pg_locks AS blocking + JOIN pg_locks AS blocked ON (blocking.transactionid = blocked.transactionid AND blocking.locktype = blocked.locktype) + JOIN pg_stat_activity ON (blocking.pid = pg_stat_activity.pid) + WHERE + blocking.granted + AND NOT blocked.granted + AND CASE WHEN {min_duration} = 0 + THEN true + ELSE extract(epoch from now() - {duration_column}) > %(min_duration)s + END + AND CASE WHEN {dbname_filter} IS NULL THEN true + ELSE datname ~* %(dbname_filter)s + END + UNION ALL + -- VirtualXid Lock + SELECT + blocking.pid, + pg_stat_activity.application_name, + pg_stat_activity.query, + blocking.mode, + pg_stat_activity.datname, + pg_stat_activity.datid, + pg_stat_activity.usename, + pg_stat_activity.client_addr AS client, + blocking.locktype, + EXTRACT(epoch FROM (NOW() - pg_stat_activity.{duration_column})) AS duration, + pg_stat_activity.state as state, + blocking.relation::regclass AS relation, + pg_stat_activity.wait_event, + pg_stat_activity.query_id + FROM + pg_locks AS blocking + JOIN pg_locks AS blocked ON (blocking.virtualxid = blocked.virtualxid AND blocking.locktype = blocked.locktype) + JOIN pg_stat_activity ON (blocking.pid = pg_stat_activity.pid) + WHERE + blocking.granted + AND NOT blocked.granted + AND CASE WHEN {min_duration} = 0 + THEN true + ELSE extract(epoch from now() - {duration_column}) > %(min_duration)s + END + AND CASE WHEN {dbname_filter} IS NULL THEN true + ELSE datname ~* %(dbname_filter)s + END + UNION ALL + -- Relation or tuple Lock + SELECT + blocking.pid, + pg_stat_activity.application_name, + pg_stat_activity.query, + blocking.mode, + pg_stat_activity.datname, + pg_stat_activity.datid, + pg_stat_activity.usename, + pg_stat_activity.client_addr AS client, + blocking.locktype, + EXTRACT(epoch FROM (NOW() - pg_stat_activity.{duration_column})) AS duration, + pg_stat_activity.state as state, + blocking.relation::regclass AS relation, + pg_stat_activity.wait_event, + pg_stat_activity.query_id + FROM + pg_locks AS blocking + JOIN pg_locks AS blocked ON (blocking.database = blocked.database AND blocking.relation = blocked.relation AND blocking.locktype = blocked.locktype) + JOIN pg_stat_activity ON (blocking.pid = pg_stat_activity.pid) + WHERE + blocking.granted + AND NOT blocked.granted + AND blocked.relation IS NOT NULL + AND CASE WHEN {min_duration} = 0 + THEN true + ELSE extract(epoch from now() - {duration_column}) > %(min_duration)s + END + AND CASE WHEN {dbname_filter} IS NULL THEN true + ELSE datname ~* %(dbname_filter)s + END + ) AS sq + LEFT OUTER JOIN pg_database b ON sq.datid = b.oid +GROUP BY + pid, + application_name, + database, + usename, + client, + relation, + mode, + locktype, + duration, + state, + query, + encoding, + wait_event, + query_id +ORDER BY + duration DESC; diff --git a/pgactivity/queries/get_pg_activity_oldest.sql b/pgactivity/queries/get_pg_activity_oldest.sql index bcfdd41e..b6dd9795 100644 --- a/pgactivity/queries/get_pg_activity_oldest.sql +++ b/pgactivity/queries/get_pg_activity_oldest.sql @@ -20,7 +20,8 @@ SELECT END AS query, pg_catalog.pg_encoding_to_char(b.encoding) AS encoding, NULL AS query_leader_pid, - false AS is_parallel_worker + false AS is_parallel_worker, + NULL::int8 AS query_id FROM pg_stat_activity a LEFT OUTER JOIN pg_database b ON a.datid = b.oid diff --git a/pgactivity/queries/get_pg_activity_post_090200.sql b/pgactivity/queries/get_pg_activity_post_090200.sql index 4aaf8924..af51b0d8 100644 --- a/pgactivity/queries/get_pg_activity_post_090200.sql +++ b/pgactivity/queries/get_pg_activity_post_090200.sql @@ -14,7 +14,8 @@ SELECT a.query AS query, pg_catalog.pg_encoding_to_char(b.encoding) AS encoding, NULL AS query_leader_pid, - false AS is_parallel_worker + false AS is_parallel_worker, + NULL::int8 AS query_id FROM pg_stat_activity a LEFT OUTER JOIN pg_database b ON a.datid = b.oid diff --git a/pgactivity/queries/get_pg_activity_post_090400.sql b/pgactivity/queries/get_pg_activity_post_090400.sql index 8076814b..4891ec5f 100644 --- a/pgactivity/queries/get_pg_activity_post_090400.sql +++ b/pgactivity/queries/get_pg_activity_post_090400.sql @@ -13,7 +13,8 @@ SELECT a.query AS query, pg_catalog.pg_encoding_to_char(b.encoding) AS encoding, NULL AS query_leader_pid, - false AS is_parallel_worker + false AS is_parallel_worker, + NULL::int8 AS query_id FROM pg_stat_activity a LEFT OUTER JOIN pg_database b ON a.datid = b.oid diff --git a/pgactivity/queries/get_pg_activity_post_090600.sql b/pgactivity/queries/get_pg_activity_post_090600.sql index e4f44e28..155209e5 100644 --- a/pgactivity/queries/get_pg_activity_post_090600.sql +++ b/pgactivity/queries/get_pg_activity_post_090600.sql @@ -14,7 +14,8 @@ SELECT a.query AS query, pg_catalog.pg_encoding_to_char(b.encoding) AS encoding, NULL AS query_leader_pid, - false AS is_parallel_worker + false AS is_parallel_worker, + NULL::int8 AS query_id FROM pg_stat_activity a LEFT OUTER JOIN pg_database b ON a.datid = b.oid diff --git a/pgactivity/queries/get_pg_activity_post_100000.sql b/pgactivity/queries/get_pg_activity_post_100000.sql index f032a544..53688adb 100644 --- a/pgactivity/queries/get_pg_activity_post_100000.sql +++ b/pgactivity/queries/get_pg_activity_post_100000.sql @@ -16,7 +16,8 @@ SELECT NULL AS query_leader_pid, ( a.backend_type = 'background worker' AND a.query IS NOT NULL - ) AS is_parallel_worker + ) AS is_parallel_worker, + NULL::int8 AS query_id FROM pg_stat_activity a LEFT OUTER JOIN pg_database b ON a.datid = b.oid diff --git a/pgactivity/queries/get_pg_activity_post_110000.sql b/pgactivity/queries/get_pg_activity_post_110000.sql index 77831e8a..9ab8796a 100644 --- a/pgactivity/queries/get_pg_activity_post_110000.sql +++ b/pgactivity/queries/get_pg_activity_post_110000.sql @@ -13,7 +13,8 @@ SELECT a.query AS query, pg_catalog.pg_encoding_to_char(b.encoding) AS encoding, NULL AS query_leader_pid, - a.backend_type = 'parallel worker' AS is_parallel_worker + a.backend_type = 'parallel worker' AS is_parallel_worker, + NULL::int8 AS query_id FROM pg_stat_activity a LEFT OUTER JOIN pg_database b ON a.datid = b.oid diff --git a/pgactivity/queries/get_pg_activity_post_130000.sql b/pgactivity/queries/get_pg_activity_post_130000.sql index f62d4715..a55747ea 100644 --- a/pgactivity/queries/get_pg_activity_post_130000.sql +++ b/pgactivity/queries/get_pg_activity_post_130000.sql @@ -13,7 +13,8 @@ SELECT a.query AS query, pg_catalog.pg_encoding_to_char(b.encoding) AS encoding, coalesce(a.leader_pid, a.pid) AS query_leader_pid, - a.backend_type = 'parallel worker' AS is_parallel_worker + a.backend_type = 'parallel worker' AS is_parallel_worker, + NULL::int8 AS query_id FROM pg_stat_activity a LEFT OUTER JOIN pg_database b ON a.datid = b.oid diff --git a/pgactivity/queries/get_pg_activity_post_140000.sql b/pgactivity/queries/get_pg_activity_post_140000.sql new file mode 100644 index 00000000..cad1d5ff --- /dev/null +++ b/pgactivity/queries/get_pg_activity_post_140000.sql @@ -0,0 +1,32 @@ +-- Get data from pg_activity since pg 13 +-- NEW pg_activity.leader_pid +SELECT + a.pid AS pid, + a.backend_xmin AS xmin, + a.application_name AS application_name, + a.datname AS database, + a.client_addr AS client, + EXTRACT(epoch FROM (NOW() - a.{duration_column})) AS duration, + a.wait_event AS wait, + a.usename AS user, + a.state AS state, + a.query AS query, + pg_catalog.pg_encoding_to_char(b.encoding) AS encoding, + coalesce(a.leader_pid, a.pid) AS query_leader_pid, + a.backend_type = 'parallel worker' AS is_parallel_worker, + a.query_id + FROM + pg_stat_activity a + LEFT OUTER JOIN pg_database b ON a.datid = b.oid + WHERE + a.state <> 'idle' + AND a.pid <> pg_catalog.pg_backend_pid() + AND CASE WHEN {min_duration} = 0 + THEN true + ELSE extract(epoch from now() - {duration_column}) > %(min_duration)s + END + AND CASE WHEN {dbname_filter} IS NULL THEN true + ELSE a.datname ~* %(dbname_filter)s + END +ORDER BY + EXTRACT(epoch FROM (NOW() - a.{duration_column})) DESC; diff --git a/pgactivity/queries/get_waiting_post_140000.sql b/pgactivity/queries/get_waiting_post_140000.sql new file mode 100644 index 00000000..13dd3134 --- /dev/null +++ b/pgactivity/queries/get_waiting_post_140000.sql @@ -0,0 +1,31 @@ +-- Get waiting queries for versions >= 14 +SELECT + pg_locks.pid AS pid, + a.application_name AS application_name, + a.datname AS database, + a.usename AS user, + a.client_addr AS client, + pg_locks.mode AS mode, + pg_locks.locktype AS type, + pg_locks.relation::regclass AS relation, + EXTRACT(epoch FROM (NOW() - a.{duration_column})) AS duration, + a.state as state, + a.query AS query, + pg_catalog.pg_encoding_to_char(b.encoding) AS encoding, + a.query_id + FROM + pg_catalog.pg_locks + JOIN pg_catalog.pg_stat_activity a ON(pg_catalog.pg_locks.pid = a.pid) + LEFT OUTER JOIN pg_database b ON a.datid = b.oid + WHERE + NOT pg_catalog.pg_locks.granted + AND a.pid <> pg_backend_pid() + AND CASE WHEN {min_duration} = 0 + THEN true + ELSE extract(epoch from now() - {duration_column}) > %(min_duration)s + END + AND CASE WHEN {dbname_filter} IS NULL THEN true + ELSE a.datname ~* %(dbname_filter)s + END +ORDER BY + EXTRACT(epoch FROM (NOW() - a.{duration_column})) DESC; diff --git a/pgactivity/types.py b/pgactivity/types.py index 40e543be..217c5691 100644 --- a/pgactivity/types.py +++ b/pgactivity/types.py @@ -393,6 +393,15 @@ def add_column( min_width=6, default_color="cyan", ) + add_column( + Flag.QUERYID, + key="query_id", + name="QUERYID", + min_width=20, + max_width=20, + justify="right", + default_color="cyan", + ) add_column( "query", key="query", @@ -489,6 +498,7 @@ def add_column( "wait", "io_wait", "state", + "query_id", "query", ], QueryMode.waiting: [ @@ -502,6 +512,7 @@ def add_column( "mode", "duration", "state", + "query_id", "query", ], QueryMode.blocking: [ @@ -516,6 +527,7 @@ def add_column( "duration", "wait", "state", + "query_id", "query", ], } @@ -926,6 +938,7 @@ class RunningProcess(BaseProcess): wait: bool | None | str query_leader_pid: int | None is_parallel_worker: bool + query_id: int | None = attr.ib(default=None, kw_only=True) @attr.s(auto_attribs=True, frozen=True, slots=True) @@ -941,6 +954,7 @@ class WaitingProcess(BaseProcess): # TODO: update queries to select/compute these column. query_leader_pid: int | None = attr.ib(default=None, init=False) is_parallel_worker: bool = attr.ib(default=False, init=False) + query_id: int | None = None @attr.s(auto_attribs=True, frozen=True, slots=True) @@ -957,6 +971,7 @@ class BlockingProcess(BaseProcess): # TODO: update queries to select/compute these column. query_leader_pid: int | None = attr.ib(default=None, init=False) is_parallel_worker: bool = attr.ib(default=False, init=False) + query_id: int | None = None @attr.s(auto_attribs=True, frozen=True, slots=True) diff --git a/tests/data/local-processes-input.json b/tests/data/local-processes-input.json index 69a6f205..f82333c3 100644 --- a/tests/data/local-processes-input.json +++ b/tests/data/local-processes-input.json @@ -48,6 +48,7 @@ "mem": null, "pid": 6221, "query": "END;", + "query_id": null, "encoding": "UTF-8", "read": null, "state": "active", @@ -102,6 +103,7 @@ "mem": null, "pid": 6222, "query": "SELECT abalance FROM pgbench_accounts WHERE aid = 883793;", + "query_id": null, "encoding": "UTF-8", "read": null, "state": "active", @@ -156,6 +158,7 @@ "mem": null, "pid": 6223, "query": "END;", + "query_id": null, "encoding": "UTF-8", "read": null, "state": "active", @@ -210,6 +213,7 @@ "mem": null, "pid": 6224, "query": "END;", + "query_id": null, "encoding": "UTF-8", "read": null, "state": "active", @@ -264,6 +268,7 @@ "mem": null, "pid": 6225, "query": "END;", + "query_id": null, "encoding": "UTF-8", "read": null, "state": "active", @@ -318,6 +323,7 @@ "mem": null, "pid": 6226, "query": "END;", + "query_id": null, "encoding": "UTF-8", "read": null, "state": "active", @@ -372,6 +378,7 @@ "mem": null, "pid": 6227, "query": "UPDATE pgbench_branches SET bbalance = bbalance + -1015 WHERE bid = 77;", + "query_id": null, "encoding": "UTF-8", "read": null, "state": "active", @@ -426,6 +433,7 @@ "mem": null, "pid": 6228, "query": "UPDATE pgbench_accounts SET abalance = abalance + 3062 WHERE aid = 7289374;", + "query_id": null, "encoding": "UTF-8", "read": null, "state": "active", @@ -480,6 +488,7 @@ "mem": null, "pid": 6229, "query": "END;", + "query_id": null, "encoding": "UTF-8", "read": null, "state": "active", @@ -534,6 +543,7 @@ "mem": null, "pid": 6230, "query": "END;", + "query_id": null, "encoding": "UTF-8", "read": null, "state": "active", @@ -588,6 +598,7 @@ "mem": null, "pid": 6231, "query": "UPDATE pgbench_accounts SET abalance = abalance + 157 WHERE aid = 4244124;", + "query_id": null, "encoding": "UTF-8", "read": null, "state": "active", @@ -642,6 +653,7 @@ "mem": null, "pid": 6232, "query": "END;", + "query_id": null, "encoding": "UTF-8", "read": null, "state": "active", @@ -696,6 +708,7 @@ "mem": null, "pid": 6233, "query": "END;", + "query_id": null, "encoding": "UTF-8", "read": null, "state": "active", @@ -750,6 +763,7 @@ "mem": null, "pid": 6234, "query": "END;", + "query_id": null, "encoding": "UTF-8", "read": null, "state": "active", @@ -804,6 +818,7 @@ "mem": null, "pid": 6235, "query": "END;", + "query_id": null, "encoding": "UTF-8", "read": null, "state": "active", @@ -858,6 +873,7 @@ "mem": null, "pid": 6237, "query": "UPDATE pgbench_tellers SET tbalance = tbalance + 566 WHERE tid = 733;", + "query_id": null, "encoding": "UTF-8", "read": null, "state": "active", @@ -912,6 +928,7 @@ "mem": null, "pid": 6238, "query": "UPDATE pgbench_accounts SET abalance = abalance + -3113 WHERE aid = 8943851;", + "query_id": null, "encoding": "UTF-8", "read": null, "state": "active", @@ -966,6 +983,7 @@ "mem": null, "pid": 6239, "query": "UPDATE pgbench_accounts SET abalance = abalance + 141 WHERE aid = 1932841;", + "query_id": null, "encoding": "UTF-8", "read": null, "state": "idle in transaction", @@ -1020,6 +1038,7 @@ "mem": null, "pid": 6240, "query": "END;", + "query_id": null, "encoding": "UTF-8", "read": null, "state": "active", @@ -1076,6 +1095,7 @@ "mem": null, "pid": 6221, "query": "END;", + "query_id": null, "encoding": "UTF-8", "read": null, "state": "active", @@ -1130,6 +1150,7 @@ "mem": null, "pid": 6222, "query": "UPDATE pgbench_branches SET bbalance = bbalance + 1107 WHERE bid = 84;", + "query_id": null, "encoding": "UTF-8", "read": null, "state": "idle in transaction", @@ -1184,6 +1205,7 @@ "mem": null, "pid": 6223, "query": "END;", + "query_id": null, "encoding": "UTF-8", "read": null, "state": "active", @@ -1238,6 +1260,7 @@ "mem": null, "pid": 6224, "query": "UPDATE pgbench_tellers SET tbalance = tbalance + -4335 WHERE tid = 682;", + "query_id": null, "encoding": "UTF-8", "read": null, "state": "idle in transaction", @@ -1292,6 +1315,7 @@ "mem": null, "pid": 6225, "query": "INSERT INTO pgbench_history (tid, bid, aid, delta, mtime) VALUES (297, 63, 5970520, -2396, CURRENT_TIMESTAMP);", + "query_id": null, "encoding": "UTF-8", "read": null, "state": "idle in transaction", @@ -1346,6 +1370,7 @@ "mem": null, "pid": 6226, "query": "SELECT abalance FROM pgbench_accounts WHERE aid = 518562;", + "query_id": null, "encoding": "UTF-8", "read": null, "state": "idle in transaction", @@ -1400,6 +1425,7 @@ "mem": null, "pid": 6227, "query": "UPDATE pgbench_branches SET bbalance = bbalance + 4427 WHERE bid = 28;", + "query_id": null, "encoding": "UTF-8", "read": null, "state": "idle in transaction", @@ -1454,6 +1480,7 @@ "mem": null, "pid": 6228, "query": "SELECT abalance FROM pgbench_accounts WHERE aid = 2514784;", + "query_id": null, "encoding": "UTF-8", "read": null, "state": "active", @@ -1508,6 +1535,7 @@ "mem": null, "pid": 6229, "query": "END;", + "query_id": null, "encoding": "UTF-8", "read": null, "state": "active", @@ -1562,6 +1590,7 @@ "mem": null, "pid": 6230, "query": "END;", + "query_id": null, "encoding": "UTF-8", "read": null, "state": "active", @@ -1616,6 +1645,7 @@ "mem": null, "pid": 6231, "query": "UPDATE pgbench_branches SET bbalance = bbalance + 3357 WHERE bid = 6;", + "query_id": null, "encoding": "UTF-8", "read": null, "state": "idle in transaction", @@ -1670,6 +1700,7 @@ "mem": null, "pid": 6232, "query": "END;", + "query_id": null, "encoding": "UTF-8", "read": null, "state": "active", @@ -1724,6 +1755,7 @@ "mem": null, "pid": 6233, "query": "UPDATE pgbench_accounts SET abalance = abalance + -1917 WHERE aid = 9235835;", + "query_id": null, "encoding": "UTF-8", "read": null, "state": "active", @@ -1778,6 +1810,7 @@ "mem": null, "pid": 6234, "query": "SELECT abalance FROM pgbench_accounts WHERE aid = 4511601;", + "query_id": null, "encoding": "UTF-8", "read": null, "state": "idle in transaction", @@ -1832,6 +1865,7 @@ "mem": null, "pid": 6235, "query": "UPDATE pgbench_accounts SET abalance = abalance + -3841 WHERE aid = 1460066;", + "query_id": null, "encoding": "UTF-8", "read": null, "state": "idle in transaction", @@ -1886,6 +1920,7 @@ "mem": null, "pid": 6236, "query": "UPDATE pgbench_branches SET bbalance = bbalance + -1147 WHERE bid = 26;", + "query_id": null, "encoding": "UTF-8", "read": null, "state": "active", @@ -1940,6 +1975,7 @@ "mem": null, "pid": 6237, "query": "END;", + "query_id": null, "encoding": "UTF-8", "read": null, "state": "active", @@ -1994,6 +2030,7 @@ "mem": null, "pid": 6238, "query": "END;", + "query_id": null, "encoding": "UTF-8", "read": null, "state": "active", @@ -2048,6 +2085,7 @@ "mem": null, "pid": 6239, "query": "END;", + "query_id": null, "encoding": "UTF-8", "read": null, "state": "active", @@ -2102,6 +2140,7 @@ "mem": null, "pid": 6240, "query": "END;", + "query_id": null, "encoding": "UTF-8", "read": null, "state": "active", diff --git a/tests/test_cli.py b/tests/test_cli.py index d725591c..46374faf 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -27,6 +27,7 @@ def test_parser() -> None: "username": None, "dbname": None, "pid": False, + "queryid": False, "database": None, "user": None, "client": None, @@ -48,8 +49,9 @@ def test_parser() -> None: def test_parser_flag_on() -> None: parser = cli.get_parser() - ns = parser.parse_args(["--pid", "--no-app-name"]) + ns = parser.parse_args(["--pid", "--query-id", "--no-app-name"]) assert ns.pid is True + assert ns.queryid is True assert ns.appname is False assert ns.wait is None diff --git a/tests/test_cli_help.txt b/tests/test_cli_help.txt index f4c64b3f..004ddfee 100644 --- a/tests/test_cli_help.txt +++ b/tests/test_cli_help.txt @@ -73,6 +73,8 @@ Process table display options: --wait, --no-wait Enable/disable W. --app-name, --no-app-name Enable/disable APP. + --query-id, --no-query-id + Enable/disable QUERYID. Header display options: --no-inst-info Hide instance information. diff --git a/tests/test_cli_help_py312.txt b/tests/test_cli_help_py312.txt index 4a49943e..be214a00 100644 --- a/tests/test_cli_help_py312.txt +++ b/tests/test_cli_help_py312.txt @@ -75,6 +75,8 @@ Process table display options: --wait, --no-wait Enable/disable W. --app-name, --no-app-name Enable/disable APP. + --query-id, --no-query-id + Enable/disable QUERYID. Header display options: --no-inst-info Hide instance information. diff --git a/tests/test_config.py b/tests/test_config.py index 79ee3498..486eec69 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -25,6 +25,7 @@ def test_flag_load() -> None: "database": True, "mem": True, "pid": None, + "queryid": True, "read": True, "relation": True, "time": True, @@ -51,6 +52,7 @@ def test_flag_load() -> None: | Flag.CLIENT | Flag.APPNAME | Flag.DATABASE + | Flag.QUERYID | Flag.XMIN ) cfg = Configuration( @@ -73,11 +75,13 @@ def test_flag_load() -> None: | Flag.CLIENT | Flag.APPNAME | Flag.DATABASE + | Flag.QUERYID | Flag.XMIN ) options["database"] = False options["time"] = False options["pid"] = False + options["queryid"] = False cfg = Configuration( name="test", values=dict(database=UISection(hidden=False), relation=UISection(hidden=True)), diff --git a/tests/test_ui.txt b/tests/test_ui.txt index af0963c0..7965e667 100644 --- a/tests/test_ui.txt +++ b/tests/test_ui.txt @@ -51,6 +51,7 @@ Default CLI options, passed to ui.main(): ... "header_show_instance": True, ... "header_show_workers": True, ... "header_show_system": True, +... "queryid": False, ... } >>> options = argparse.Namespace(**defaults) diff --git a/tests/test_views.py b/tests/test_views.py index b0e3779c..914da365 100644 --- a/tests/test_views.py +++ b/tests/test_views.py @@ -85,3 +85,42 @@ def test_format_query_strip_comments( ) == expected ) + + +@pytest.mark.parametrize( + "query_mode, flags", + [ + (QueryMode.activities, Flag.PID | Flag.QUERYID), + ( + QueryMode.waiting, + Flag.PID + | Flag.QUERYID + | Flag.DATABASE + | Flag.APPNAME + | Flag.CLIENT + | Flag.USER + | Flag.RELATION + | Flag.TYPE + | Flag.MODE, + ), + ( + QueryMode.blocking, + Flag.PID + | Flag.QUERYID + | Flag.DATABASE + | Flag.APPNAME + | Flag.CLIENT + | Flag.USER + | Flag.RELATION + | Flag.TYPE + | Flag.MODE + | Flag.WAIT, + ), + ], + ids=["activities", "waiting", "blocking"], +) +def test_columns_header_queryid(capsys, term, query_mode, flags): + ui = UI.make(query_mode=query_mode, flag=flags) + views.columns_header(term, ui, width=200) + out = capsys.readouterr()[0] + assert "QUERYID" in out diff --git a/tests/test_views.txt b/tests/test_views.txt index fff067a5..6a37645f 100644 --- a/tests/test_views.txt +++ b/tests/test_views.txt @@ -227,6 +227,7 @@ Tests for processes_rows() ... io_wait=False, ... query_leader_pid=6239, ... is_parallel_worker=False, +... query_id=-1, ... ), ... LocalRunningProcess( ... pid="6228", @@ -247,6 +248,7 @@ Tests for processes_rows() ... io_wait=True, ... query_leader_pid=6239, ... is_parallel_worker=True, +... query_id=-1, ... ), ... LocalRunningProcess( ... pid="1234", @@ -267,6 +269,7 @@ Tests for processes_rows() ... io_wait=False, ... query_leader_pid=1234, ... is_parallel_worker=False, +... query_id=-1, ... ), ... ] @@ -304,9 +307,9 @@ Tests for processes_rows() Terminal is too narrow given selected flags, we switch to wrap_noindent mode (TODO: this is buggy, the first line should be wrapped as well if too long) >>> processes_rows(term, ui, SelectableProcesses(processes1), 100, width=250) -6239 1 pgbench pgbench postgres local 0.1 1.0 7B 12B 0.000000 N N idle in trans UPDATE pgbench_accounts SET abalance = abalance + 141 WHERE aid = 1932841; -6228 2 pgbench pgbench postgres local 0.2 1.0 0B 1.08M 0.000413 Y active \_ UPDATE pgbench_accounts SET abalance = abalance + 141 WHERE aid = 1932841; -1234 3 business accounting bob local 2.4 1.0 9.42M 1.21K 20:34.00 BackendRandomLoc N active SELECT product_id, p.name FROM products p LEFT JOIN sales s USING (product_id) WHERE +6239 1 pgbench pgbench postgres local 0.1 1.0 7B 12B 0.000000 N N idle in trans -1 UPDATE pgbench_accounts SET abalance = abalance + 141 WHERE aid +6228 2 pgbench pgbench postgres local 0.2 1.0 0B 1.08M 0.000413 Y active -1 \_ UPDATE pgbench_accounts SET abalance = abalance + 141 WHERE a +1234 3 business accounting bob local 2.4 1.0 9.42M 1.21K 20:34.00 BackendRandomLoc N active -1 SELECT product_id, p.name FROM products p LEFT JOIN sales s USIN >>> ui = UI.make(flag=Flag.PID|Flag.DATABASE, wrap_query=False) >>> processes_rows(term, ui, SelectableProcesses(processes1), 100) @@ -369,8 +372,8 @@ Terminal is too narrow given selected flags, we switch to wrap_noindent mode = bbalance + 1788 WHERE bid = 68; >>> ui = UI.make(query_mode=QueryMode.blocking, flag=allflags) >>> processes_rows(term, ui, SelectableProcesses(processes2), 100, width=250) -6239 pgbench pgbench postgres 1.2.3.4 None transactionid ExclusiveLock 11:06.00 Client Read active END; -6228 pgbench pgbench postgres 2001:4f8:3:ba:2e ahah tuple RowExclusiveLock 0.000413 Client Read idle in trans UPDATE pgbench_branches SET bbalance = bbalance + 1788 WHERE bid = 68; +6239 pgbench pgbench postgres 1.2.3.4 None transactionid ExclusiveLock 11:06.00 Client Read active END; +6228 pgbench pgbench postgres 2001:4f8:3:ba:2e ahah tuple RowExclusiveLock 0.000413 Client Read idle in trans UPDATE pgbench_branches SET bbalance = bbalance + 1788 WHERE bid >>> processes1b = [ ... RunningProcess( From f10ec1e28ffb64883d4b8c116303084df7332da3 Mon Sep 17 00:00:00 2001 From: kmoppel Date: Mon, 29 Jun 2026 15:57:03 +0300 Subject: [PATCH 2/9] Adjust manpages for the new --query-id flag FYI: Copilot generated - not sure how to validate the end output... --- docs/man/pg_activity.1 | 11 +++++++++++ docs/man/pg_activity.pod | 10 ++++++++++ 2 files changed, 21 insertions(+) diff --git a/docs/man/pg_activity.1 b/docs/man/pg_activity.1 index 3b0e5896..0899788a 100644 --- a/docs/man/pg_activity.1 +++ b/docs/man/pg_activity.1 @@ -206,6 +206,8 @@ The running queries panel shows all running queries, transactions or backends .IX Item "- IOW: boolean indicating that the process is waiting for IO as reported by the psutil library;" .IP "\- \fBstate\fR: state of the backend;" 2 .IX Item "- state: state of the backend;" +.IP "\- \fBQUERYID\fR: query identifier for the statement;" 2 +.IX Item "- QUERYID: query identifier for the statement;" .IP "\- \fBQuery\fR: the query." 2 .IX Item "- Query: the query." .PD @@ -234,6 +236,8 @@ shows the following information: .IX Item "- TIME+: the duration of the query, transaction or session depending on the DURATION_MODE setting;" .IP "\- \fBstate\fR: the state of the transaction;" 2 .IX Item "- state: the state of the transaction;" +.IP "\- \fBQUERYID\fR: query identifier for the statement;" 2 +.IX Item "- QUERYID: query identifier for the statement;" .IP "\- \fBQuery\fR: the query." 2 .IX Item "- Query: the query." .PD @@ -264,6 +268,8 @@ required by another session. It shows following information: .IX Item "- Waiting: for PostgreSQL 9.6+: a specific wait event or nothing. Otherwise, a boolean indicating if we are waiting for a Lock;" .IP "\- \fBstate\fR: the state of the transaction;" 2 .IX Item "- state: the state of the transaction;" +.IP "\- \fBQUERYID\fR: query identifier for the statement;" 2 +.IX Item "- QUERYID: query identifier for the statement;" .IP "\- \fBQuery\fR: the query." 2 .IX Item "- Query: the query." .PD @@ -419,6 +425,11 @@ required by another session. It shows following information: .Vb 1 \& Enable/disable APP. .Ve +.IP "\fB\-\-query\-id\fR, \fB\-\-no\-query\-id\fR" 2 +.IX Item "--query-id, --no-query-id" +.Vb 1 +\& Enable/disable QUERYID. +.Ve .SS "HEADER DISPLAY OPTIONS" .IX Subsection "HEADER DISPLAY OPTIONS" .IP \fB\-\-no\-inst\-info\fR 2 diff --git a/docs/man/pg_activity.pod b/docs/man/pg_activity.pod index dda9bca2..5bc0487c 100644 --- a/docs/man/pg_activity.pod +++ b/docs/man/pg_activity.pod @@ -160,6 +160,8 @@ B seconds. It displays the following information: =item - B: state of the backend; +=item - B: query identifier for the statement; + =item - B: the query. =back @@ -191,6 +193,8 @@ shows the following information: =item - B: the state of the transaction; +=item - B: query identifier for the statement; + =item - B: the query. =back @@ -224,6 +228,8 @@ required by another session. It shows following information: =item - B: the state of the transaction; +=item - B: query identifier for the statement; + =item - B: the query. =back @@ -370,6 +376,10 @@ required by another session. It shows following information: Enable/disable APP. +=item B<--query-id>, B<--no-query-id> + + Enable/disable QUERYID. + =back =head2 HEADER DISPLAY OPTIONS From acf73f57b69136107c56439f9e043bd8029257df Mon Sep 17 00:00:00 2001 From: kmoppel Date: Mon, 29 Jun 2026 16:10:00 +0300 Subject: [PATCH 3/9] Make codespell to ignore "USIN" USING -> USIN due to viewport shrinkage --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 3fb4420c..48083768 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -40,6 +40,6 @@ repos: exclude: tests - id: codespell name: codespell - entry: codespell + entry: codespell --ignore-words-list USIN language: system types: [file] From 797f11b3a57abab6f87c1e759209059d77fe5817 Mon Sep 17 00:00:00 2001 From: kmoppel Date: Mon, 29 Jun 2026 16:19:50 +0300 Subject: [PATCH 4/9] Remove superfluous comment --- pgactivity/cli.py | 1 - 1 file changed, 1 deletion(-) diff --git a/pgactivity/cli.py b/pgactivity/cli.py index 8b894851..9a99f230 100755 --- a/pgactivity/cli.py +++ b/pgactivity/cli.py @@ -247,7 +247,6 @@ def get_parser(prog: str | None = None) -> argparse.ArgumentParser: flag(group, "--time", dest="time", feature="TIME+") flag(group, "--wait", dest="wait", feature="W") flag(group, "--app-name", dest="appname", feature="APP") - # QUERYID is opt-in to avoid widening the process table by default. flag(group, "--query-id", dest="queryid", feature="QUERYID", default=False) group = parser.add_argument_group("Header display options") From 0d2fdcd3ab32d7fbaaa97d15bd58e0a38768de3d Mon Sep 17 00:00:00 2001 From: kmoppel Date: Mon, 29 Jun 2026 16:32:29 +0300 Subject: [PATCH 5/9] Move the new "query_id" column after "database" column --- pgactivity/types.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pgactivity/types.py b/pgactivity/types.py index 217c5691..3d99b782 100644 --- a/pgactivity/types.py +++ b/pgactivity/types.py @@ -487,6 +487,7 @@ def add_column( "pid", "xmin", "database", + "query_id", "application_name", "user", "client", @@ -498,12 +499,12 @@ def add_column( "wait", "io_wait", "state", - "query_id", "query", ], QueryMode.waiting: [ "pid", "database", + "query_id", "application_name", "user", "client", @@ -512,12 +513,12 @@ def add_column( "mode", "duration", "state", - "query_id", "query", ], QueryMode.blocking: [ "pid", "database", + "query_id", "application_name", "user", "client", @@ -527,7 +528,6 @@ def add_column( "duration", "wait", "state", - "query_id", "query", ], } From 450fe74fbd611b54bededae373811ba43431e205 Mon Sep 17 00:00:00 2001 From: kmoppel Date: Mon, 29 Jun 2026 16:34:05 +0300 Subject: [PATCH 6/9] Update codespell invoke in tox.ini --- tox.ini | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tox.ini b/tox.ini index 7351fe16..7763afdd 100644 --- a/tox.ini +++ b/tox.ini @@ -30,7 +30,7 @@ deps = pre-commit pyupgrade commands = - codespell {toxinidir} + codespell --ignore-words-list USIN {toxinidir} black --check --diff {toxinidir} flake8 {toxinidir} isort --check --diff {toxinidir} From 60b66f6f7ab8665a41e0d1b1a4d713b63260730f Mon Sep 17 00:00:00 2001 From: kmoppel Date: Mon, 29 Jun 2026 16:54:21 +0300 Subject: [PATCH 7/9] Fix tests related to --query-id --- pgactivity/cli.py | 2 +- tests/test_cli.py | 2 +- tests/test_views.txt | 10 +++++----- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/pgactivity/cli.py b/pgactivity/cli.py index 9a99f230..9ba4d5d2 100755 --- a/pgactivity/cli.py +++ b/pgactivity/cli.py @@ -247,7 +247,7 @@ def get_parser(prog: str | None = None) -> argparse.ArgumentParser: flag(group, "--time", dest="time", feature="TIME+") flag(group, "--wait", dest="wait", feature="W") flag(group, "--app-name", dest="appname", feature="APP") - flag(group, "--query-id", dest="queryid", feature="QUERYID", default=False) + flag(group, "--query-id", dest="queryid", feature="QUERYID") group = parser.add_argument_group("Header display options") group.add_argument( diff --git a/tests/test_cli.py b/tests/test_cli.py index 46374faf..8cbd31b0 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -27,7 +27,7 @@ def test_parser() -> None: "username": None, "dbname": None, "pid": False, - "queryid": False, + "queryid": None, "database": None, "user": None, "client": None, diff --git a/tests/test_views.txt b/tests/test_views.txt index 6a37645f..74d120a7 100644 --- a/tests/test_views.txt +++ b/tests/test_views.txt @@ -307,9 +307,9 @@ Tests for processes_rows() Terminal is too narrow given selected flags, we switch to wrap_noindent mode (TODO: this is buggy, the first line should be wrapped as well if too long) >>> processes_rows(term, ui, SelectableProcesses(processes1), 100, width=250) -6239 1 pgbench pgbench postgres local 0.1 1.0 7B 12B 0.000000 N N idle in trans -1 UPDATE pgbench_accounts SET abalance = abalance + 141 WHERE aid -6228 2 pgbench pgbench postgres local 0.2 1.0 0B 1.08M 0.000413 Y active -1 \_ UPDATE pgbench_accounts SET abalance = abalance + 141 WHERE a -1234 3 business accounting bob local 2.4 1.0 9.42M 1.21K 20:34.00 BackendRandomLoc N active -1 SELECT product_id, p.name FROM products p LEFT JOIN sales s USIN +6239 1 pgbench -1 pgbench postgres local 0.1 1.0 7B 12B 0.000000 N N idle in trans UPDATE pgbench_accounts SET abalance = abalance + 141 WHERE aid +6228 2 pgbench -1 pgbench postgres local 0.2 1.0 0B 1.08M 0.000413 Y active \_ UPDATE pgbench_accounts SET abalance = abalance + 141 WHERE a +1234 3 business -1 accounting bob local 2.4 1.0 9.42M 1.21K 20:34.00 BackendRandomLoc N active SELECT product_id, p.name FROM products p LEFT JOIN sales s USIN >>> ui = UI.make(flag=Flag.PID|Flag.DATABASE, wrap_query=False) >>> processes_rows(term, ui, SelectableProcesses(processes1), 100) @@ -372,8 +372,8 @@ Terminal is too narrow given selected flags, we switch to wrap_noindent mode = bbalance + 1788 WHERE bid = 68; >>> ui = UI.make(query_mode=QueryMode.blocking, flag=allflags) >>> processes_rows(term, ui, SelectableProcesses(processes2), 100, width=250) -6239 pgbench pgbench postgres 1.2.3.4 None transactionid ExclusiveLock 11:06.00 Client Read active END; -6228 pgbench pgbench postgres 2001:4f8:3:ba:2e ahah tuple RowExclusiveLock 0.000413 Client Read idle in trans UPDATE pgbench_branches SET bbalance = bbalance + 1788 WHERE bid +6239 pgbench pgbench postgres 1.2.3.4 None transactionid ExclusiveLock 11:06.00 Client Read active END; +6228 pgbench pgbench postgres 2001:4f8:3:ba:2e ahah tuple RowExclusiveLock 0.000413 Client Read idle in trans UPDATE pgbench_branches SET bbalance = bbalance + 1788 WHERE bid >>> processes1b = [ ... RunningProcess( From 3612f916db899a9dcf581556f1fc04a6b2fd94bf Mon Sep 17 00:00:00 2001 From: kmoppel Date: Mon, 29 Jun 2026 17:06:55 +0300 Subject: [PATCH 8/9] Reflect in Manpages that QUERYID now comes after DATABASE --- docs/man/pg_activity.1 | 12 ++++++------ docs/man/pg_activity.pod | 12 ++++++------ pgactivity/cli.py | 2 +- tests/test_cli.py | 2 +- 4 files changed, 14 insertions(+), 14 deletions(-) diff --git a/docs/man/pg_activity.1 b/docs/man/pg_activity.1 index 0899788a..3787bf4c 100644 --- a/docs/man/pg_activity.1 +++ b/docs/man/pg_activity.1 @@ -184,6 +184,8 @@ The running queries panel shows all running queries, transactions or backends .IX Item "- XMIN: xmin horizon of the backend;" .IP "\- \fBDATABASE\fR: database specified in the connection string;" 2 .IX Item "- DATABASE: database specified in the connection string;" +.IP "\- \fBQUERYID\fR: query identifier for the statement;" 2 +.IX Item "- QUERYID: query identifier for the statement;" .IP "\- \fBAPP\fR: application name specified in the connection string;" 2 .IX Item "- APP: application name specified in the connection string;" .IP "\- \fBUSER\fR: user name specified in the connection string;" 2 @@ -206,8 +208,6 @@ The running queries panel shows all running queries, transactions or backends .IX Item "- IOW: boolean indicating that the process is waiting for IO as reported by the psutil library;" .IP "\- \fBstate\fR: state of the backend;" 2 .IX Item "- state: state of the backend;" -.IP "\- \fBQUERYID\fR: query identifier for the statement;" 2 -.IX Item "- QUERYID: query identifier for the statement;" .IP "\- \fBQuery\fR: the query." 2 .IX Item "- Query: the query." .PD @@ -220,6 +220,8 @@ shows the following information: .PD 0 .IP "\- \fBDATABASE\fR: database specified in the connection string;" 2 .IX Item "- DATABASE: database specified in the connection string;" +.IP "\- \fBQUERYID\fR: query identifier for the statement;" 2 +.IX Item "- QUERYID: query identifier for the statement;" .IP "\- \fBAPP\fR: application name specified in the connection string;" 2 .IX Item "- APP: application name specified in the connection string;" .IP "\- \fBUSER\fR: user name specified in the connection string;" 2 @@ -236,8 +238,6 @@ shows the following information: .IX Item "- TIME+: the duration of the query, transaction or session depending on the DURATION_MODE setting;" .IP "\- \fBstate\fR: the state of the transaction;" 2 .IX Item "- state: the state of the transaction;" -.IP "\- \fBQUERYID\fR: query identifier for the statement;" 2 -.IX Item "- QUERYID: query identifier for the statement;" .IP "\- \fBQuery\fR: the query." 2 .IX Item "- Query: the query." .PD @@ -250,6 +250,8 @@ required by another session. It shows following information: .PD 0 .IP "\- \fBDATABASE\fR: database specified in the connection string;" 2 .IX Item "- DATABASE: database specified in the connection string;" +.IP "\- \fBQUERYID\fR: query identifier for the statement;" 2 +.IX Item "- QUERYID: query identifier for the statement;" .IP "\- \fBAPP\fR: application name specified in the connection string;" 2 .IX Item "- APP: application name specified in the connection string;" .IP "\- \fBUSER\fR: user name specified in the connection string;" 2 @@ -268,8 +270,6 @@ required by another session. It shows following information: .IX Item "- Waiting: for PostgreSQL 9.6+: a specific wait event or nothing. Otherwise, a boolean indicating if we are waiting for a Lock;" .IP "\- \fBstate\fR: the state of the transaction;" 2 .IX Item "- state: the state of the transaction;" -.IP "\- \fBQUERYID\fR: query identifier for the statement;" 2 -.IX Item "- QUERYID: query identifier for the statement;" .IP "\- \fBQuery\fR: the query." 2 .IX Item "- Query: the query." .PD diff --git a/docs/man/pg_activity.pod b/docs/man/pg_activity.pod index 5bc0487c..28c7a552 100644 --- a/docs/man/pg_activity.pod +++ b/docs/man/pg_activity.pod @@ -138,6 +138,8 @@ B seconds. It displays the following information: =item - B: database specified in the connection string; +=item - B: query identifier for the statement; + =item - B: application name specified in the connection string; =item - B: user name specified in the connection string; @@ -160,8 +162,6 @@ B seconds. It displays the following information: =item - B: state of the backend; -=item - B: query identifier for the statement; - =item - B: the query. =back @@ -177,6 +177,8 @@ shows the following information: =item - B: database specified in the connection string; +=item - B: query identifier for the statement; + =item - B: application name specified in the connection string; =item - B: user name specified in the connection string; @@ -193,8 +195,6 @@ shows the following information: =item - B: the state of the transaction; -=item - B: query identifier for the statement; - =item - B: the query. =back @@ -210,6 +210,8 @@ required by another session. It shows following information: =item - B: database specified in the connection string; +=item - B: query identifier for the statement; + =item - B: application name specified in the connection string; =item - B: user name specified in the connection string; @@ -228,8 +230,6 @@ required by another session. It shows following information: =item - B: the state of the transaction; -=item - B: query identifier for the statement; - =item - B: the query. =back diff --git a/pgactivity/cli.py b/pgactivity/cli.py index 9ba4d5d2..9a99f230 100755 --- a/pgactivity/cli.py +++ b/pgactivity/cli.py @@ -247,7 +247,7 @@ def get_parser(prog: str | None = None) -> argparse.ArgumentParser: flag(group, "--time", dest="time", feature="TIME+") flag(group, "--wait", dest="wait", feature="W") flag(group, "--app-name", dest="appname", feature="APP") - flag(group, "--query-id", dest="queryid", feature="QUERYID") + flag(group, "--query-id", dest="queryid", feature="QUERYID", default=False) group = parser.add_argument_group("Header display options") group.add_argument( diff --git a/tests/test_cli.py b/tests/test_cli.py index 8cbd31b0..46374faf 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -27,7 +27,7 @@ def test_parser() -> None: "username": None, "dbname": None, "pid": False, - "queryid": None, + "queryid": False, "database": None, "user": None, "client": None, From 070561cee9dfd1fc0fbaf1acae8d543b46e6fc9c Mon Sep 17 00:00:00 2001 From: kmoppel Date: Mon, 29 Jun 2026 17:09:29 +0300 Subject: [PATCH 9/9] Fix some Python 3.12 quirk on --help display --- tests/test_cli_help_py312.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_cli_help_py312.txt b/tests/test_cli_help_py312.txt index be214a00..2bed4254 100644 --- a/tests/test_cli_help_py312.txt +++ b/tests/test_cli_help_py312.txt @@ -76,7 +76,7 @@ Process table display options: --app-name, --no-app-name Enable/disable APP. --query-id, --no-query-id - Enable/disable QUERYID. + Enable/disable QUERYID. (default: False) Header display options: --no-inst-info Hide instance information.