1
0
mirror of https://github.com/postgres/postgres.git synced 2026-01-26 09:41:40 +03:00

pg_stat_statements: Add more tests for level tracking

This commit adds tests to verify the computation of the nesting level
for two code paths: the planner hook and the ExecutorFinish() hook.  The
nesting level is essential to save a correct "toplevel" status for the
added PGSS entries.

The author has noticed that removing the manipulations of nesting_level
in these two code paths did not cause the tests to complain, meaning
that we never had coverage for the assumptions taken by the code.

Author: Sami Imseih <samimseih@gmail.com>
Discussion: https://postgr.es/m/CAA5RZ0uK1PSrgf52bWCtDpzaqbWt04o6ZA7zBm6UQyv7vyvf9w@mail.gmail.com
This commit is contained in:
Michael Paquier
2026-01-21 18:18:15 +09:00
parent b4555cb070
commit 1572ea96e6
2 changed files with 104 additions and 0 deletions

View File

@@ -1535,6 +1535,72 @@ SELECT toplevel, calls, rows, query FROM pg_stat_statements ORDER BY query COLLA
t | 1 | 1 | SELECT pg_stat_statements_reset() IS NOT NULL AS t
(8 rows)
SELECT pg_stat_statements_reset() IS NOT NULL AS t;
t
---
t
(1 row)
-- planner - all-level tracking.
SET pg_stat_statements.track_planning = TRUE;
SELECT PLUS_THREE(8);
plus_three
------------
11
(1 row)
SELECT PLUS_THREE(10);
plus_three
------------
13
(1 row)
SELECT toplevel, calls, rows, plans, query FROM pg_stat_statements
ORDER BY query COLLATE "C";
toplevel | calls | rows | plans | query
----------+-------+------+-------+--------------------------------------------------------------------
t | 2 | 2 | 2 | SELECT PLUS_THREE($1)
f | 2 | 2 | 2 | SELECT i + 3 LIMIT 1
t | 1 | 1 | 0 | SELECT pg_stat_statements_reset() IS NOT NULL AS t
t | 0 | 0 | 1 | SELECT toplevel, calls, rows, plans, query FROM pg_stat_statements+
| | | | ORDER BY query COLLATE "C"
(4 rows)
RESET pg_stat_statements.track_planning;
-- AFTER trigger SQL (ExecutorFinish) - all-level tracking.
SET pg_stat_statements.track = 'all';
SELECT pg_stat_statements_reset() IS NOT NULL AS t;
t
---
t
(1 row)
CREATE TABLE test_trigger (id int, name text);
CREATE TABLE audit_table (table_name text, action text, row_id int);
CREATE OR REPLACE FUNCTION audit_trigger_func()
RETURNS TRIGGER AS $$
BEGIN
INSERT INTO audit_table VALUES ('test_trigger', TG_OP, NEW.id);
RETURN NULL;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER audit_after_trigger
AFTER INSERT ON test_trigger
FOR EACH ROW EXECUTE FUNCTION audit_trigger_func();
INSERT INTO test_trigger VALUES (1, 'test1');
INSERT INTO test_trigger VALUES (2, 'test2');
SELECT toplevel, calls, rows, plans, query FROM pg_stat_statements
ORDER BY query COLLATE "C";
toplevel | calls | rows | plans | query
----------+-------+------+-------+-----------------------------------------------------
f | 2 | 2 | 0 | INSERT INTO audit_table VALUES ($15, TG_OP, NEW.id)
t | 2 | 2 | 0 | INSERT INTO test_trigger VALUES ($1, $2)
t | 1 | 1 | 0 | SELECT pg_stat_statements_reset() IS NOT NULL AS t
(3 rows)
DROP TRIGGER audit_after_trigger ON test_trigger;
DROP FUNCTION audit_trigger_func();
DROP TABLE audit_table, test_trigger;
--
-- pg_stat_statements.track = none
--

View File

@@ -431,6 +431,44 @@ SELECT PLUS_THREE(8);
SELECT PLUS_THREE(10);
SELECT toplevel, calls, rows, query FROM pg_stat_statements ORDER BY query COLLATE "C";
SELECT pg_stat_statements_reset() IS NOT NULL AS t;
-- planner - all-level tracking.
SET pg_stat_statements.track_planning = TRUE;
SELECT PLUS_THREE(8);
SELECT PLUS_THREE(10);
SELECT toplevel, calls, rows, plans, query FROM pg_stat_statements
ORDER BY query COLLATE "C";
RESET pg_stat_statements.track_planning;
-- AFTER trigger SQL (ExecutorFinish) - all-level tracking.
SET pg_stat_statements.track = 'all';
SELECT pg_stat_statements_reset() IS NOT NULL AS t;
CREATE TABLE test_trigger (id int, name text);
CREATE TABLE audit_table (table_name text, action text, row_id int);
CREATE OR REPLACE FUNCTION audit_trigger_func()
RETURNS TRIGGER AS $$
BEGIN
INSERT INTO audit_table VALUES ('test_trigger', TG_OP, NEW.id);
RETURN NULL;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER audit_after_trigger
AFTER INSERT ON test_trigger
FOR EACH ROW EXECUTE FUNCTION audit_trigger_func();
INSERT INTO test_trigger VALUES (1, 'test1');
INSERT INTO test_trigger VALUES (2, 'test2');
SELECT toplevel, calls, rows, plans, query FROM pg_stat_statements
ORDER BY query COLLATE "C";
DROP TRIGGER audit_after_trigger ON test_trigger;
DROP FUNCTION audit_trigger_func();
DROP TABLE audit_table, test_trigger;
--
-- pg_stat_statements.track = none