Skip to content

Commit 32dff21

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 de5a748 commit 32dff21

File tree

2 files changed

+184
-36
lines changed

2 files changed

+184
-36
lines changed

preprocessing.c

-1
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,6 @@
6767
#include "preprocessing.h"
6868
#include "storage.h"
6969

70-
7170
/* List of feature spaces, that are processing in this backend. */
7271
List *cur_classes = NIL;
7372

t/002_pg_stat_statements_aqo.pl

+184-35
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
use PostgreSQL::Test::Cluster;
55
use PostgreSQL::Test::Utils;
6-
use Test::More tests => 2;
6+
use Test::More tests => 12;
77
print "start";
88
my $node = PostgreSQL::Test::Cluster->new('profiling');
99

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

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

0 commit comments

Comments
 (0)