Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 83f2061

Browse files
committed
Teach contrib/pg_stat_statements to handle multi-statement commands better.
Make use of the statement boundary info added by commit ab1f0c8 to let pg_stat_statements behave more sanely when multiple SQL queries are jammed into one query string. It now records just the relevant part of the source string, not the whole thing, for each individual query. Even when no multi-statement strings are involved, users may notice small changes in the output: leading and trailing whitespace and semicolons will be stripped from statements, which did not happen before. Also, significantly expand pg_stat_statements' regression test script. Fabien Coelho, reviewed by Craig Ringer and Kyotaro Horiguchi, some mods by me Discussion: https://postgr.es/m/alpine.DEB.2.20.1612200926310.29821@lancre
1 parent ab1f0c8 commit 83f2061

File tree

3 files changed

+606
-38
lines changed

3 files changed

+606
-38
lines changed
Lines changed: 350 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,359 @@
11
CREATE EXTENSION pg_stat_statements;
2-
CREATE TABLE test (a int, b char(20));
3-
-- test the basic functionality of pg_stat_statements
2+
--
3+
-- simple and compound statements
4+
--
5+
SET pg_stat_statements.track_utility = FALSE;
46
SELECT pg_stat_statements_reset();
57
pg_stat_statements_reset
68
--------------------------
79

810
(1 row)
911

12+
SELECT 1 AS "int";
13+
int
14+
-----
15+
1
16+
(1 row)
17+
18+
SELECT 'hello'
19+
-- multiline
20+
AS "text";
21+
text
22+
-------
23+
hello
24+
(1 row)
25+
26+
SELECT 'world' AS "text";
27+
text
28+
-------
29+
world
30+
(1 row)
31+
32+
-- transaction
33+
BEGIN;
34+
SELECT 1 AS "int";
35+
int
36+
-----
37+
1
38+
(1 row)
39+
40+
SELECT 'hello' AS "text";
41+
text
42+
-------
43+
hello
44+
(1 row)
45+
46+
COMMIT;
47+
-- compound transaction
48+
BEGIN \;
49+
SELECT 2.0 AS "float" \;
50+
SELECT 'world' AS "text" \;
51+
COMMIT;
52+
-- compound with empty statements and spurious leading spacing
53+
\;\; SELECT 3 + 3 \;\;\; SELECT ' ' || ' !' \;\; SELECT 1 + 4 \;;
54+
?column?
55+
----------
56+
5
57+
(1 row)
58+
59+
-- non ;-terminated statements
60+
SELECT 1 + 1 + 1 AS "add" \gset
61+
SELECT :add + 1 + 1 AS "add" \;
62+
SELECT :add + 1 + 1 AS "add" \gset
63+
-- set operator
64+
SELECT 1 AS i UNION SELECT 2 ORDER BY i;
65+
i
66+
---
67+
1
68+
2
69+
(2 rows)
70+
71+
-- cte
72+
WITH t(f) AS (
73+
VALUES (1.0), (2.0)
74+
)
75+
SELECT f FROM t ORDER BY f;
76+
f
77+
-----
78+
1.0
79+
2.0
80+
(2 rows)
81+
82+
SELECT query, calls, rows FROM pg_stat_statements ORDER BY query COLLATE "C";
83+
query | calls | rows
84+
-----------------------------------------+-------+------
85+
SELECT ? +| 4 | 4
86+
+| |
87+
AS "text" | |
88+
SELECT ? + ? | 2 | 2
89+
SELECT ? + ? + ? AS "add" | 3 | 3
90+
SELECT ? AS "float" | 1 | 1
91+
SELECT ? AS "int" | 2 | 2
92+
SELECT ? AS i UNION SELECT ? ORDER BY i | 1 | 2
93+
SELECT ? || ? | 1 | 1
94+
SELECT pg_stat_statements_reset() | 1 | 1
95+
WITH t(f) AS ( +| 1 | 2
96+
VALUES (?), (?) +| |
97+
) +| |
98+
SELECT f FROM t ORDER BY f | |
99+
(9 rows)
100+
101+
--
102+
-- CRUD: INSERT SELECT UPDATE DELETE on test table
103+
--
104+
SELECT pg_stat_statements_reset();
105+
pg_stat_statements_reset
106+
--------------------------
107+
108+
(1 row)
109+
110+
-- utility "create table" should not be shown
111+
CREATE TABLE test (a int, b char(20));
10112
INSERT INTO test VALUES(generate_series(1, 10), 'aaa');
11-
UPDATE test SET b = 'bbb' WHERE a > 5;
12-
SELECT query, calls, rows from pg_stat_statements ORDER BY rows;
13-
query | calls | rows
14-
----------------------------------------------------+-------+------
15-
SELECT pg_stat_statements_reset(); | 1 | 1
16-
UPDATE test SET b = ? WHERE a > ?; | 1 | 5
17-
INSERT INTO test VALUES(generate_series(?, ?), ?); | 1 | 10
18-
(3 rows)
19-
20-
DROP TABLE test;
113+
UPDATE test SET b = 'bbb' WHERE a > 7;
114+
DELETE FROM test WHERE a > 9;
115+
-- explicit transaction
116+
BEGIN;
117+
UPDATE test SET b = '111' WHERE a = 1 ;
118+
COMMIT;
119+
BEGIN \;
120+
UPDATE test SET b = '222' WHERE a = 2 \;
121+
COMMIT ;
122+
UPDATE test SET b = '333' WHERE a = 3 \;
123+
UPDATE test SET b = '444' WHERE a = 4 ;
124+
BEGIN \;
125+
UPDATE test SET b = '555' WHERE a = 5 \;
126+
UPDATE test SET b = '666' WHERE a = 6 \;
127+
COMMIT ;
128+
-- SELECT with constants
129+
SELECT * FROM test WHERE a > 5 ORDER BY a ;
130+
a | b
131+
---+----------------------
132+
6 | 666
133+
7 | aaa
134+
8 | bbb
135+
9 | bbb
136+
(4 rows)
137+
138+
SELECT *
139+
FROM test
140+
WHERE a > 9
141+
ORDER BY a ;
142+
a | b
143+
---+---
144+
(0 rows)
145+
146+
-- SELECT without constants
147+
SELECT * FROM test ORDER BY a;
148+
a | b
149+
---+----------------------
150+
1 | 111
151+
2 | 222
152+
3 | 333
153+
4 | 444
154+
5 | 555
155+
6 | 666
156+
7 | aaa
157+
8 | bbb
158+
9 | bbb
159+
(9 rows)
160+
161+
SELECT query, calls, rows FROM pg_stat_statements ORDER BY query COLLATE "C";
162+
query | calls | rows
163+
---------------------------------------------------+-------+------
164+
DELETE FROM test WHERE a > ? | 1 | 1
165+
INSERT INTO test VALUES(generate_series(?, ?), ?) | 1 | 10
166+
SELECT * FROM test ORDER BY a | 1 | 9
167+
SELECT * FROM test WHERE a > ? ORDER BY a | 2 | 4
168+
SELECT pg_stat_statements_reset() | 1 | 1
169+
UPDATE test SET b = ? WHERE a = ? | 6 | 6
170+
UPDATE test SET b = ? WHERE a > ? | 1 | 3
171+
(7 rows)
172+
173+
--
174+
-- pg_stat_statements.track = none
175+
--
176+
SET pg_stat_statements.track = 'none';
177+
SELECT pg_stat_statements_reset();
178+
pg_stat_statements_reset
179+
--------------------------
180+
181+
(1 row)
182+
183+
SELECT 1 AS "one";
184+
one
185+
-----
186+
1
187+
(1 row)
188+
189+
SELECT 1 + 1 AS "two";
190+
two
191+
-----
192+
2
193+
(1 row)
194+
195+
SELECT query, calls, rows FROM pg_stat_statements ORDER BY query COLLATE "C";
196+
query | calls | rows
197+
-------+-------+------
198+
(0 rows)
199+
200+
--
201+
-- pg_stat_statements.track = top
202+
--
203+
SET pg_stat_statements.track = 'top';
204+
SELECT pg_stat_statements_reset();
205+
pg_stat_statements_reset
206+
--------------------------
207+
208+
(1 row)
209+
210+
DO LANGUAGE plpgsql $$
211+
BEGIN
212+
-- this is a SELECT
213+
PERFORM 'hello world'::TEXT;
214+
END;
215+
$$;
216+
-- PL/pgSQL function
217+
CREATE FUNCTION PLUS_TWO(i INTEGER) RETURNS INTEGER AS $$
218+
DECLARE
219+
r INTEGER;
220+
BEGIN
221+
SELECT (i + 1 + 1.0)::INTEGER INTO r;
222+
RETURN r;
223+
END; $$ LANGUAGE plpgsql;
224+
SELECT PLUS_TWO(3);
225+
plus_two
226+
----------
227+
5
228+
(1 row)
229+
230+
SELECT PLUS_TWO(7);
231+
plus_two
232+
----------
233+
9
234+
(1 row)
235+
236+
-- SQL function --- use LIMIT to keep it from being inlined
237+
CREATE FUNCTION PLUS_ONE(i INTEGER) RETURNS INTEGER AS
238+
$$ SELECT (i + 1.0)::INTEGER LIMIT 1 $$ LANGUAGE SQL;
239+
SELECT PLUS_ONE(8);
240+
plus_one
241+
----------
242+
9
243+
(1 row)
244+
245+
SELECT PLUS_ONE(10);
246+
plus_one
247+
----------
248+
11
249+
(1 row)
250+
251+
SELECT query, calls, rows FROM pg_stat_statements ORDER BY query COLLATE "C";
252+
query | calls | rows
253+
-----------------------------------+-------+------
254+
SELECT ?::TEXT | 1 | 1
255+
SELECT PLUS_ONE(?) | 2 | 2
256+
SELECT PLUS_TWO(?) | 2 | 2
257+
SELECT pg_stat_statements_reset() | 1 | 1
258+
(4 rows)
259+
260+
--
261+
-- pg_stat_statements.track = all
262+
--
263+
SET pg_stat_statements.track = 'all';
264+
SELECT pg_stat_statements_reset();
265+
pg_stat_statements_reset
266+
--------------------------
267+
268+
(1 row)
269+
270+
-- we drop and recreate the functions to avoid any caching funnies
271+
DROP FUNCTION PLUS_ONE(INTEGER);
272+
DROP FUNCTION PLUS_TWO(INTEGER);
273+
-- PL/pgSQL function
274+
CREATE FUNCTION PLUS_TWO(i INTEGER) RETURNS INTEGER AS $$
275+
DECLARE
276+
r INTEGER;
277+
BEGIN
278+
SELECT (i + 1 + 1.0)::INTEGER INTO r;
279+
RETURN r;
280+
END; $$ LANGUAGE plpgsql;
281+
SELECT PLUS_TWO(-1);
282+
plus_two
283+
----------
284+
1
285+
(1 row)
286+
287+
SELECT PLUS_TWO(2);
288+
plus_two
289+
----------
290+
4
291+
(1 row)
292+
293+
-- SQL function --- use LIMIT to keep it from being inlined
294+
CREATE FUNCTION PLUS_ONE(i INTEGER) RETURNS INTEGER AS
295+
$$ SELECT (i + 1.0)::INTEGER LIMIT 1 $$ LANGUAGE SQL;
296+
SELECT PLUS_ONE(3);
297+
plus_one
298+
----------
299+
4
300+
(1 row)
301+
302+
SELECT PLUS_ONE(1);
303+
plus_one
304+
----------
305+
2
306+
(1 row)
307+
308+
SELECT query, calls, rows FROM pg_stat_statements ORDER BY query COLLATE "C";
309+
query | calls | rows
310+
-----------------------------------+-------+------
311+
SELECT (i + ? + ?)::INTEGER | 2 | 2
312+
SELECT (i + ?)::INTEGER LIMIT ? | 2 | 2
313+
SELECT PLUS_ONE(?) | 2 | 2
314+
SELECT PLUS_TWO(?) | 2 | 2
315+
SELECT pg_stat_statements_reset() | 1 | 1
316+
(5 rows)
317+
318+
--
319+
-- utility commands
320+
--
321+
SET pg_stat_statements.track_utility = TRUE;
322+
SELECT pg_stat_statements_reset();
323+
pg_stat_statements_reset
324+
--------------------------
325+
326+
(1 row)
327+
328+
SELECT 1;
329+
?column?
330+
----------
331+
1
332+
(1 row)
333+
334+
CREATE INDEX test_b ON test(b);
335+
DROP TABLE test \;
336+
DROP TABLE IF EXISTS test \;
337+
DROP FUNCTION PLUS_ONE(INTEGER);
338+
NOTICE: table "test" does not exist, skipping
339+
DROP TABLE IF EXISTS test \;
340+
DROP TABLE IF EXISTS test \;
341+
DROP FUNCTION IF EXISTS PLUS_ONE(INTEGER);
342+
NOTICE: table "test" does not exist, skipping
343+
NOTICE: table "test" does not exist, skipping
344+
NOTICE: function plus_one(pg_catalog.int4) does not exist, skipping
345+
DROP FUNCTION PLUS_TWO(INTEGER);
346+
SELECT query, calls, rows FROM pg_stat_statements ORDER BY query COLLATE "C";
347+
query | calls | rows
348+
-------------------------------------------+-------+------
349+
CREATE INDEX test_b ON test(b) | 1 | 0
350+
DROP FUNCTION IF EXISTS PLUS_ONE(INTEGER) | 1 | 0
351+
DROP FUNCTION PLUS_ONE(INTEGER) | 1 | 0
352+
DROP FUNCTION PLUS_TWO(INTEGER) | 1 | 0
353+
DROP TABLE IF EXISTS test | 3 | 0
354+
DROP TABLE test | 1 | 0
355+
SELECT ? | 1 | 1
356+
SELECT pg_stat_statements_reset() | 1 | 1
357+
(8 rows)
358+
21359
DROP EXTENSION pg_stat_statements;

0 commit comments

Comments
 (0)