3
3
4
4
use PostgresNode;
5
5
use TestLib;
6
- use Test::More tests => 2 ;
6
+ use Test::More tests => 12 ;
7
7
8
- my $node = get_new_node(' profiling ' );
8
+ my $node = get_new_node(' test ' );
9
9
$node -> init;
10
- print " create conf" ;
11
10
12
11
$node -> append_conf(' postgresql.conf' , qq{
13
12
aqo.mode = 'disabled'
14
- aqo.profile_classes = -1
15
- aqo.profile_enable = 'true'
16
13
aqo.force_collect_stat = 'false'
17
14
log_statement = 'ddl' # reduce size of logs.
18
15
aqo.join_threshold = 0
16
+ pg_stat_statements.track = 'none'
19
17
} );
20
- # Test constants.
21
- my $TRANSACTIONS = 100;
22
- my $CLIENTS = 10;
23
- my $THREADS = 10;
24
18
my $query_id ;
25
-
26
- # General purpose variables.
27
- my $res ;
19
+ my ($res , $aqo_res );
28
20
my $total_classes ;
29
21
$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
+ } );
36
28
$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
+ " );
39
45
$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';
41
78
SELECT pg_reload_conf();
42
79
" );
43
80
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