3
3
4
4
use PostgreSQL::Test::Cluster;
5
5
use PostgreSQL::Test::Utils;
6
- use Test::More tests => 2 ;
6
+ use Test::More tests => 12 ;
7
7
print " start" ;
8
8
my $node = PostgreSQL::Test::Cluster-> new(' profiling' );
9
9
16
16
aqo.join_threshold = 0
17
17
pg_stat_statements.track = 'none'
18
18
} );
19
- # Test constants.
20
- my $TRANSACTIONS = 100;
21
- my $CLIENTS = 10;
22
- my $THREADS = 10;
23
19
my $query_id ;
24
-
25
- # General purpose variables.
26
- my $res ;
20
+ my ($res , $aqo_res );
27
21
my $total_classes ;
28
22
$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
+ } );
35
29
$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
+ " );
38
46
$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';
40
79
SELECT pg_reload_conf();
41
80
" );
42
81
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