Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 76db9cb

Browse files
committed
Fix some issues with tracking nesting level in pg_stat_statements.
When we decide that we don't want to track execution time of a specific planner or ProcessUtility call, we still have to increment the nesting depth, or we'll make the wrong determination of whether we are at top level when considering nested statements. (PREPARE and EXECUTE are exceptions, for reasons explained in the code.) Counting planner nesting depth separately from executor nesting depth was a mistake: it causes us to make the wrong determination of whether we are at top level when considering nested statements that get executed during planning (as a result of constant-folding of functions, for example). Merge those counters into one. In passing, get rid of the PGSS_HANDLED_UTILITY macro in favor of explicitly listing statement types. It seems somewhat coincidental that PREPARE and EXECUTE are handled alike in each of the places where that was used: the reasoning tends to be different for each one. Thus, the macro seems as likely to encourage future bugs as prevent them, since it's quite unclear whether any future statement type that might need special-casing here would also need the same choices at each spot. Sergei Kornilov, Julien Rouhaud, and Tom Lane, per bug #17552 from Maxim Boguk. This is pretty clearly a bug fix, but it's also a behavioral change that might surprise somebody, so no back-patch. Discussion: https://postgr.es/m/[email protected]
1 parent 1a5594b commit 76db9cb

File tree

3 files changed

+242
-47
lines changed

3 files changed

+242
-47
lines changed

contrib/pg_stat_statements/expected/level_tracking.out

+109-1
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,61 @@ SELECT toplevel, calls, query FROM pg_stat_statements
6767
t | 1 | SET pg_stat_statements.track = 'all'
6868
(7 rows)
6969

70+
-- DO block - top-level tracking without utility.
71+
SET pg_stat_statements.track = 'top';
72+
SET pg_stat_statements.track_utility = FALSE;
73+
SELECT pg_stat_statements_reset();
74+
pg_stat_statements_reset
75+
--------------------------
76+
77+
(1 row)
78+
79+
DELETE FROM stats_track_tab;
80+
DO $$
81+
BEGIN
82+
DELETE FROM stats_track_tab;
83+
END; $$;
84+
DO LANGUAGE plpgsql $$
85+
BEGIN
86+
-- this is a SELECT
87+
PERFORM 'hello world'::TEXT;
88+
END; $$;
89+
SELECT toplevel, calls, query FROM pg_stat_statements
90+
ORDER BY query COLLATE "C", toplevel;
91+
toplevel | calls | query
92+
----------+-------+-----------------------------------
93+
t | 1 | DELETE FROM stats_track_tab
94+
t | 1 | SELECT pg_stat_statements_reset()
95+
(2 rows)
96+
97+
-- DO block - all-level tracking without utility.
98+
SET pg_stat_statements.track = 'all';
99+
SELECT pg_stat_statements_reset();
100+
pg_stat_statements_reset
101+
--------------------------
102+
103+
(1 row)
104+
105+
DELETE FROM stats_track_tab;
106+
DO $$
107+
BEGIN
108+
DELETE FROM stats_track_tab;
109+
END; $$;
110+
DO LANGUAGE plpgsql $$
111+
BEGIN
112+
-- this is a SELECT
113+
PERFORM 'hello world'::TEXT;
114+
END; $$;
115+
SELECT toplevel, calls, query FROM pg_stat_statements
116+
ORDER BY query COLLATE "C", toplevel;
117+
toplevel | calls | query
118+
----------+-------+-----------------------------------
119+
f | 1 | DELETE FROM stats_track_tab
120+
t | 1 | DELETE FROM stats_track_tab
121+
f | 1 | SELECT $1::TEXT
122+
t | 1 | SELECT pg_stat_statements_reset()
123+
(4 rows)
124+
70125
-- PL/pgSQL function - top-level tracking.
71126
SET pg_stat_statements.track = 'top';
72127
SET pg_stat_statements.track_utility = FALSE;
@@ -118,6 +173,31 @@ SELECT calls, rows, query FROM pg_stat_statements ORDER BY query COLLATE "C";
118173
1 | 1 | SELECT pg_stat_statements_reset()
119174
(3 rows)
120175

176+
-- immutable SQL function --- can be executed at plan time
177+
CREATE FUNCTION PLUS_THREE(i INTEGER) RETURNS INTEGER AS
178+
$$ SELECT i + 3 LIMIT 1 $$ IMMUTABLE LANGUAGE SQL;
179+
SELECT PLUS_THREE(8);
180+
plus_three
181+
------------
182+
11
183+
(1 row)
184+
185+
SELECT PLUS_THREE(10);
186+
plus_three
187+
------------
188+
13
189+
(1 row)
190+
191+
SELECT toplevel, calls, rows, query FROM pg_stat_statements ORDER BY query COLLATE "C";
192+
toplevel | calls | rows | query
193+
----------+-------+------+------------------------------------------------------------------------------
194+
t | 2 | 2 | SELECT PLUS_ONE($1)
195+
t | 2 | 2 | SELECT PLUS_THREE($1)
196+
t | 2 | 2 | SELECT PLUS_TWO($1)
197+
t | 1 | 3 | SELECT calls, rows, query FROM pg_stat_statements ORDER BY query COLLATE "C"
198+
t | 1 | 1 | SELECT pg_stat_statements_reset()
199+
(5 rows)
200+
121201
-- PL/pgSQL function - all-level tracking.
122202
SET pg_stat_statements.track = 'all';
123203
SELECT pg_stat_statements_reset();
@@ -129,6 +209,7 @@ SELECT pg_stat_statements_reset();
129209
-- we drop and recreate the functions to avoid any caching funnies
130210
DROP FUNCTION PLUS_ONE(INTEGER);
131211
DROP FUNCTION PLUS_TWO(INTEGER);
212+
DROP FUNCTION PLUS_THREE(INTEGER);
132213
-- PL/pgSQL function
133214
CREATE FUNCTION PLUS_TWO(i INTEGER) RETURNS INTEGER AS $$
134215
DECLARE
@@ -174,7 +255,34 @@ SELECT calls, rows, query FROM pg_stat_statements ORDER BY query COLLATE "C";
174255
1 | 1 | SELECT pg_stat_statements_reset()
175256
(5 rows)
176257

177-
DROP FUNCTION PLUS_ONE(INTEGER);
258+
-- immutable SQL function --- can be executed at plan time
259+
CREATE FUNCTION PLUS_THREE(i INTEGER) RETURNS INTEGER AS
260+
$$ SELECT i + 3 LIMIT 1 $$ IMMUTABLE LANGUAGE SQL;
261+
SELECT PLUS_THREE(8);
262+
plus_three
263+
------------
264+
11
265+
(1 row)
266+
267+
SELECT PLUS_THREE(10);
268+
plus_three
269+
------------
270+
13
271+
(1 row)
272+
273+
SELECT toplevel, calls, rows, query FROM pg_stat_statements ORDER BY query COLLATE "C";
274+
toplevel | calls | rows | query
275+
----------+-------+------+------------------------------------------------------------------------------
276+
f | 2 | 2 | SELECT (i + $2 + $3)::INTEGER
277+
f | 2 | 2 | SELECT (i + $2)::INTEGER LIMIT $3
278+
t | 2 | 2 | SELECT PLUS_ONE($1)
279+
t | 2 | 2 | SELECT PLUS_THREE($1)
280+
t | 2 | 2 | SELECT PLUS_TWO($1)
281+
t | 1 | 5 | SELECT calls, rows, query FROM pg_stat_statements ORDER BY query COLLATE "C"
282+
f | 2 | 2 | SELECT i + $2 LIMIT $3
283+
t | 1 | 1 | SELECT pg_stat_statements_reset()
284+
(8 rows)
285+
178286
--
179287
-- pg_stat_statements.track = none
180288
--

0 commit comments

Comments
 (0)