Skip to content

Commit 6d364a8

Browse files
committed
Add more TAP tests on joint usage of query_id machinery by AQO and PGSS
extensions. Some minor inconsistencies were detected (see issue #71). Authors: A.Kazarinov, A.Lepikhov
1 parent 03f09f1 commit 6d364a8

File tree

1 file changed

+186
-39
lines changed

1 file changed

+186
-39
lines changed

t/002_pg_stat_statements_aqo.pl

+186-39
Original file line numberDiff line numberDiff line change
@@ -3,59 +3,206 @@
33

44
use PostgresNode;
55
use TestLib;
6-
use Test::More tests => 2;
6+
use Test::More tests => 12;
77

8-
my $node = get_new_node('profiling');
8+
my $node = get_new_node('test');
99
$node->init;
10-
print "create conf";
1110

1211
$node->append_conf('postgresql.conf', qq{
1312
aqo.mode = 'disabled'
14-
aqo.profile_classes = -1
15-
aqo.profile_enable = 'true'
1613
aqo.force_collect_stat = 'false'
1714
log_statement = 'ddl' # reduce size of logs.
1815
aqo.join_threshold = 0
16+
pg_stat_statements.track = 'none'
1917
});
20-
# Test constants.
21-
my $TRANSACTIONS = 100;
22-
my $CLIENTS = 10;
23-
my $THREADS = 10;
2418
my $query_id;
25-
26-
# General purpose variables.
27-
my $res;
19+
my ($res, $aqo_res);
2820
my $total_classes;
2921
$node->start();
30-
# ERROR: AQO allow to load library only on startup
31-
print "Create extension aqo";
32-
$node->psql('postgres', "CREATE EXTENSION aqo");
33-
$node->psql('postgres', "CREATE EXTENSION pg_stat_statements");
34-
print "create preload libraries";
35-
$node->append_conf('postgresql.conf', qq{shared_preload_libraries = 'aqo, pg_stat_statements'});
22+
23+
$node->psql('postgres', "CREATE EXTENSION aqo"); # Error
24+
$node->append_conf('postgresql.conf', qq{
25+
shared_preload_libraries = 'aqo, pg_stat_statements'
26+
aqo.mode = 'disabled' # disable AQO on schema creation
27+
});
3628
$node->restart();
37-
$node->psql('postgres', "CREATE EXTENSION aqo");
38-
$node->psql('postgres', "CREATE EXTENSION pg_stat_statements");
29+
$node->safe_psql('postgres', "
30+
CREATE EXTENSION aqo;
31+
CREATE EXTENSION pg_stat_statements;
32+
");
33+
34+
# Execute test DDL
35+
$node->psql('postgres', "
36+
CREATE TABLE aqo_test0(a int, b int, c int, d int);
37+
WITH RECURSIVE t(a, b, c, d) AS (
38+
VALUES (0, 0, 0, 0)
39+
UNION ALL
40+
SELECT t.a + 1, t.b + 1, t.c + 1, t.d + 1 FROM t WHERE t.a < 2000
41+
) INSERT INTO aqo_test0 (SELECT * FROM t);
42+
CREATE INDEX aqo_test0_idx_a ON aqo_test0 (a);
43+
ANALYZE aqo_test0;
44+
");
3945
$node->psql('postgres', "
40-
ALTER SYSTEM SET aqo.profile_enable = 'true';
46+
CREATE TABLE trig(
47+
x double precision,
48+
sinx double precision,
49+
cosx double precision);
50+
WITH RECURSIVE t(a, b, c) AS (
51+
VALUES (0.0::double precision, 0.0::double precision, 1.0::double precision)
52+
UNION ALL
53+
SELECT t.a + pi() / 50, sin(t.a + pi() / 50), cos(t.a + pi() / 50)
54+
FROM t WHERE t.a < 2 * pi()
55+
) INSERT INTO trig (SELECT * FROM t);
56+
CREATE INDEX trig_idx_x ON trig (x);
57+
ANALYZE trig;
58+
");
59+
$node->psql('postgres', "
60+
CREATE TABLE department(
61+
DepartmentID INT PRIMARY KEY NOT NULL,
62+
DepartmentName VARCHAR(20)
63+
);
64+
CREATE TABLE employee (
65+
LastName VARCHAR(20),
66+
DepartmentID INT REFERENCES department(DepartmentID)
67+
);
68+
INSERT INTO department
69+
VALUES (31, 'Sales'), (33, 'Engineering'), (34, 'Clerical'),
70+
(35, 'Marketing');
71+
INSERT INTO employee
72+
VALUES ('Rafferty', 31), ('Jones', 33), ('Heisenberg', 33),
73+
('Robinson', 34), ('Smith', 34), ('Williams', NULL);
74+
");
75+
$node->psql('postgres', "
76+
ALTER SYSTEM SET aqo.mode = 'learn';
77+
ALTER SYSTEM SET pg_stat_statements.track = 'all';
4178
SELECT pg_reload_conf();
4279
");
4380

44-
$node->psql('postgres', "CREATE TABLE aqo_test0(a int, b int, c int, d int);
45-
WITH RECURSIVE t(a, b, c, d)
46-
AS (
47-
VALUES (0, 0, 0, 0)
48-
UNION ALL
49-
SELECT t.a + 1, t.b + 1, t.c + 1, t.d + 1 FROM t WHERE t.a < 2000
50-
) INSERT INTO aqo_test0 (SELECT * FROM t);
51-
CREATE INDEX aqo_test0_idx_a ON aqo_test0 (a);
52-
ANALYZE aqo_test0;");
53-
$node->psql('postgres', "
54-
ALTER SYSTEM SET aqo.mode = 'controlled';
55-
");
56-
$res = $node->safe_psql('postgres', "SELECT * FROM aqo_test0");
57-
$res = $node->safe_psql('postgres', "SELECT count(*) FROM pg_stat_statements where query = 'SELECT * FROM aqo_test0'");
58-
is($res, 1); # The same query add in pg_stat_statements
59-
$res = $node->safe_psql('postgres', "SELECT count(*) from aqo_query_texts where query_text = 'SELECT * FROM aqo_test0'");
60-
is($res, 0); # The same query isn't added into aqo_query_texts
61-
$node->stop();
81+
# Trivial query without any clauses/parameters
82+
$node->safe_psql('postgres', "SELECT * FROM aqo_test0");
83+
$res = $node->safe_psql('postgres', "
84+
SELECT query FROM pg_stat_statements
85+
JOIN aqo_queries USING(queryid)
86+
"); # Both extensions have the same QueryID for the query above
87+
is($res, "SELECT * FROM aqo_test0");
88+
89+
# Check number of queries which logged in both extensions.
90+
$aqo_res = $node->safe_psql('postgres', "
91+
SELECT count(*) FROM aqo_query_texts
92+
"); # 2 - Common fs and trivial select.
93+
$res = $node->safe_psql('postgres', "
94+
SELECT count(*) FROM pg_stat_statements
95+
"); # 3 - trivial select and two utility queries above.
96+
is($res - $aqo_res, 1);
97+
98+
$res = $node->safe_psql('postgres', "
99+
SELECT count(*) FROM pg_stat_statements
100+
WHERE queryid NOT IN (SELECT queryid FROM aqo_query_texts)
101+
"); # Trivial select and utility query to pg_stat_statements
102+
is($res, 2);
103+
104+
$node->safe_psql('postgres', "
105+
SELECT * FROM trig WHERE sinx < 0.5 and cosx > -0.5
106+
"); # Log query with two constants
107+
$node->safe_psql('postgres', "
108+
SELECT count(*) FROM pg_stat_statements
109+
WHERE query = 'SELECT * FROM trig WHERE sinx < 0.5 and cosx > -0.5'
110+
"); # The pg_stat_statements utility queries are logged too
111+
$res = $node->safe_psql('postgres', "
112+
SELECT count(*) FROM aqo_query_texts aqt, pg_stat_statements pgss
113+
WHERE aqt.queryid = pgss.queryid
114+
");
115+
is($res, 4);
116+
117+
$res = $node->safe_psql('postgres', "
118+
SELECT count(*) FROM pg_stat_statements
119+
WHERE queryid NOT IN (SELECT queryid FROM aqo_query_texts)
120+
"); # pgss logs queries to AQO tables these AQO are skip
121+
is($res, 4);
122+
$res = $node->safe_psql('postgres', "
123+
SELECT count(*) FROM aqo_queries
124+
WHERE queryid NOT IN (SELECT queryid FROM pg_stat_statements)
125+
"); # PGSS have logged all queries that AQO logged, expect common fs.
126+
is($res, 1);
127+
128+
# ############################################################################ #
129+
#
130+
# Complex queries with meaningful tables
131+
#
132+
# ############################################################################ #
133+
134+
$node->safe_psql('postgres', "
135+
SELECT employee.LastName, employee.DepartmentID, department.DepartmentName
136+
FROM employee
137+
INNER JOIN department ON employee.DepartmentID = department.DepartmentID;
138+
"); # Log query with a JOIN and a join clause
139+
$node->safe_psql('postgres', "
140+
EXPLAIN ANALYZE
141+
SELECT ee.LastName, ee.DepartmentID, dpt.DepartmentName
142+
FROM employee ee
143+
INNER JOIN department dpt ON (ee.DepartmentID = dpt.DepartmentID)
144+
WHERE ee.LastName NOT LIKE 'Wi%';
145+
"); # Use a table aliases, EXPLAIN ANALYZE mode and WHERE clause.
146+
$node->safe_psql('postgres', "
147+
SELECT ee.LastName, ee.DepartmentID, dpt.DepartmentName
148+
FROM employee ee
149+
INNER JOIN department dpt ON (ee.DepartmentID = dpt.DepartmentID)
150+
WHERE ee.LastName NOT LIKE 'Wi%';
151+
"); # Without EXPLAIN ANALYZE option
152+
$node->safe_psql('postgres', "
153+
WITH smth AS (
154+
SELECT a FROM aqo_test0
155+
) SELECT * FROM employee ee, department dpt, smth
156+
WHERE (ee.DepartmentID = dpt.DepartmentID)
157+
AND (ee.LastName NOT LIKE 'Wi%')
158+
AND (ee.DepartmentID < smth.a);
159+
"); # Use CTE
160+
$res = $node->safe_psql('postgres', "
161+
SELECT count(*) FROM aqo_query_texts aqt, pg_stat_statements pgss
162+
WHERE aqt.queryid = pgss.queryid
163+
"); # Check, both extensions added the query with the same query ID.
164+
is($res, 8);
165+
166+
# Check query texts identity.
167+
# TODO: Maybe AQO should use parameterized query text too?
168+
$res = $node->safe_psql('postgres', "
169+
SELECT count(*)
170+
FROM aqo_query_texts aqt, pg_stat_statements pgss
171+
WHERE aqt.queryid = pgss.queryid AND aqt.query_text != pgss.query
172+
"); # PGSS processes a query and generalizes it. So, some queries is diferent
173+
is($res, 6);
174+
$res = $node->safe_psql('postgres', "
175+
SELECT count(*)
176+
FROM aqo_query_texts aqt, pg_stat_statements pgss
177+
WHERE aqt.queryid = pgss.queryid AND aqt.query_text = pgss.query
178+
"); # Non-parameterized queries (without constants in a body of query) will have the same query text.
179+
is($res, 2);
180+
181+
# Check queries hasn't logged by another extension
182+
183+
$res = $node->safe_psql('postgres', "
184+
SELECT count(*) FROM pg_stat_statements
185+
WHERE queryid NOT IN (SELECT queryid FROM aqo_queries)
186+
AND query NOT LIKE '%aqo_quer%'
187+
"); # PGSS logs all the same except queries with AQO-related objects.
188+
is($res, 1); # allow to find shifts in PGSS logic
189+
190+
# TODO: why queries in EXPLAIN ANALYZE mode have different query ID in AQO
191+
# and PGSS extensions?
192+
193+
$res = $node->safe_psql('postgres', "
194+
SELECT count(*) FROM aqo_queries
195+
WHERE queryid NOT IN (SELECT queryid FROM pg_stat_statements)
196+
");
197+
is($res, 1);
198+
199+
# only first entry in aqo_query_texts has zero hash
200+
$res = $node->safe_psql('postgres', "
201+
SELECT count(*) FROM aqo_query_texts
202+
WHERE queryid = 0
203+
");
204+
is($res, 1);
205+
206+
# TODO: check queries with queries in stored procedures
207+
208+
$node->stop();

0 commit comments

Comments
 (0)