MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
query_cache_sql_prepare.inc
1 ############### include/query_cache_sql_prepare.inc ################
2 #
3 # This is to see how statements prepared via the PREPARE SQL command
4 # go into the query cache.
5 # Query cache is abbreviated as "QC"
6 #
7 # Last update:
8 # 2008-05-26 Kostja
9 # - Add test coverage for automatic statement reprepare
10 #
11 # 2007-05-03 ML - Move t/query_cache_sql_prepare.test
12 # to include/query_cache_sql_prepare.inc
13 # - Create two toplevel tests sourcing this routine
14 # - Add tests checking that
15 # - another connection gets the same amount of QC hits
16 # - statements running via ps-protocol do not hit QC results
17 # of preceding sql EXECUTEs
18 #
19 
20 --source include/have_query_cache.inc
21 # embedded can't make more than one connection, which this test needs
22 -- source include/not_embedded.inc
23 
24 --echo ---- establish connection con1 (root) ----
25 connect (con1,localhost,root,,test,$MASTER_MYPORT,);
26 --echo ---- switch to connection default ----
27 connection default;
28 
29 set @initial_query_cache_size = @@global.query_cache_size;
30 set @@global.query_cache_size=102400;
31 flush status;
32 --disable_warnings
33 drop table if exists t1;
34 --enable_warnings
35 create table t1(c1 int);
36 insert into t1 values(1),(10),(100);
37 
38 # First, prepared statements with no parameters
39 prepare stmt1 from "select * from t1 where c1=10";
40 show status like 'Qcache_hits';
41 execute stmt1;
42 show status like 'Qcache_hits';
43 execute stmt1;
44 show status like 'Qcache_hits';
45 execute stmt1;
46 show status like 'Qcache_hits';
47 # Another prepared statement (same text, same connection), should hit the QC
48 prepare stmt2 from "select * from t1 where c1=10";
49 execute stmt2;
50 show status like 'Qcache_hits';
51 execute stmt2;
52 show status like 'Qcache_hits';
53 execute stmt2;
54 show status like 'Qcache_hits';
55 # Another prepared statement (same text, other connection), should hit the QC
56 --echo ---- switch to connection con1 ----
57 connection con1;
58 prepare stmt3 from "select * from t1 where c1=10";
59 execute stmt3;
60 show status like 'Qcache_hits';
61 execute stmt3;
62 show status like 'Qcache_hits';
63 execute stmt3;
64 show status like 'Qcache_hits';
65 --echo ---- switch to connection default ----
66 connection default;
67 
68 # Mixup tests, where statements without PREPARE.../EXECUTE.... meet statements
69 # with PREPARE.../EXECUTE.... (text protocol). Both statements have the
70 # same text. QC hits occur only when both statements use the same protocol.
71 # The outcome of the test depends on the mysqltest startup options
72 # - with "--ps-protocol"
73 # Statements without PREPARE.../EXECUTE.... run as prepared statements
74 # with binary protocol. Expect to get no QC hits.
75 # - without any "--<whatever>-protocol"
76 # Statements without PREPARE.../EXECUTE run as non prepared statements
77 # with text protocol. Expect to get QC hits.
78 ############################################################################
79 #
80 # Statement with PREPARE.../EXECUTE.... first
81 let $my_stmt= SELECT * FROM t1 WHERE c1 = 100;
82 eval prepare stmt10 from "$my_stmt";
83 show status like 'Qcache_hits';
84 execute stmt10;
85 show status like 'Qcache_hits';
86 execute stmt10;
87 show status like 'Qcache_hits';
88 eval $my_stmt;
89 show status like 'Qcache_hits';
90 --echo ---- switch to connection con1 ----
91 connection con1;
92 eval $my_stmt;
93 show status like 'Qcache_hits';
94 --echo ---- switch to connection default ----
95 connection default;
96 #
97 # Statement without PREPARE.../EXECUTE.... first
98 let $my_stmt= SELECT * FROM t1 WHERE c1 = 1;
99 eval prepare stmt11 from "$my_stmt";
100 --echo ---- switch to connection con1 ----
101 connection con1;
102 eval prepare stmt12 from "$my_stmt";
103 --echo ---- switch to connection default ----
104 connection default;
105 eval $my_stmt;
106 show status like 'Qcache_hits';
107 eval $my_stmt;
108 show status like 'Qcache_hits';
109 execute stmt11;
110 show status like 'Qcache_hits';
111 --echo ---- switch to connection con1 ----
112 connection con1;
113 execute stmt12;
114 show status like 'Qcache_hits';
115 --echo ---- switch to connection default ----
116 connection default;
117 
118 # Query caching also works when statement has parameters
119 # (BUG#29318 Statements prepared with PREPARE and with one parameter don't use
120 # query cache)
121 prepare stmt1 from "select * from t1 where c1=?";
122 show status like 'Qcache_hits';
123 set @a=1;
124 execute stmt1 using @a;
125 show status like 'Qcache_hits';
126 execute stmt1 using @a;
127 show status like 'Qcache_hits';
128 --echo ---- switch to connection con1 ----
129 connection con1;
130 set @a=1;
131 prepare stmt4 from "select * from t1 where c1=?";
132 execute stmt4 using @a;
133 show status like 'Qcache_hits';
134 # verify that presence of user variables forbids caching
135 prepare stmt4 from "select @a from t1 where c1=?";
136 execute stmt4 using @a;
137 show status like 'Qcache_hits';
138 execute stmt4 using @a;
139 show status like 'Qcache_hits';
140 --echo ---- switch to connection default ----
141 connection default;
142 
143 # See if enabling/disabling the query cache between PREPARE and
144 # EXECUTE is an issue; the expected result is that the query cache
145 # will not be used.
146 # Indeed, decision to read/write the query cache is taken at PREPARE
147 # time, so if the query cache was disabled at PREPARE time then no
148 # execution of the statement will read/write the query cache.
149 # If the query cache was enabled at PREPARE time, but disabled at
150 # EXECUTE time, at EXECUTE time the query cache internal functions do
151 # nothing so again the query cache is not read/written. But if the
152 # query cache is re-enabled before another execution then that
153 # execution will read/write the query cache.
154 
155 # QC is enabled at PREPARE
156 prepare stmt1 from "select * from t1 where c1=10";
157 # then QC is disabled at EXECUTE
158 # Expect to see no additional Qcache_hits.
159 set global query_cache_size=0;
160 show status like 'Qcache_hits';
161 execute stmt1;
162 show status like 'Qcache_hits';
163 execute stmt1;
164 show status like 'Qcache_hits';
165 execute stmt1;
166 show status like 'Qcache_hits';
167 # The QC is global = affects also other connections.
168 # Expect to see no additional Qcache_hits.
169 --echo ---- switch to connection con1 ----
170 connection con1;
171 execute stmt3;
172 show status like 'Qcache_hits';
173 execute stmt3;
174 show status like 'Qcache_hits';
175 execute stmt3;
176 show status like 'Qcache_hits';
177 #
178 # then QC is re-enabled for more EXECUTE.
179 --echo ---- switch to connection default ----
180 connection default;
181 set global query_cache_size=102400;
182 # Expect to see additional Qcache_hits.
183 # The fact that the QC was temporary disabled should have no affect
184 # except that the first execute will not hit results from the
185 # beginning of the test (because QC has been emptied meanwhile by
186 # setting its size to 0).
187 execute stmt1;
188 show status like 'Qcache_hits';
189 execute stmt1;
190 show status like 'Qcache_hits';
191 execute stmt1;
192 show status like 'Qcache_hits';
193 # The QC is global = affects also other connections.
194 --echo ---- switch to connection con1 ----
195 connection con1;
196 execute stmt3;
197 show status like 'Qcache_hits';
198 execute stmt3;
199 show status like 'Qcache_hits';
200 execute stmt3;
201 show status like 'Qcache_hits';
202 --echo ---- switch to connection default ----
203 connection default;
204 #
205 # then QC is re-disabled for more EXECUTE.
206 # Expect to see no additional Qcache_hits.
207 # The fact that the QC was temporary enabled should have no affect.
208 set global query_cache_size=0;
209 show status like 'Qcache_hits';
210 execute stmt1;
211 show status like 'Qcache_hits';
212 execute stmt1;
213 show status like 'Qcache_hits';
214 execute stmt1;
215 show status like 'Qcache_hits';
216 # The QC is global = affects also other connections.
217 --echo ---- switch to connection con1 ----
218 connection con1;
219 execute stmt3;
220 show status like 'Qcache_hits';
221 execute stmt3;
222 show status like 'Qcache_hits';
223 execute stmt3;
224 show status like 'Qcache_hits';
225 #
226 
227 --echo ---- switch to connection default ----
228 connection default;
229 # QC is disabled at PREPARE
230 set global query_cache_size=0;
231 prepare stmt1 from "select * from t1 where c1=10";
232 --echo ---- switch to connection con1 ----
233 connection con1;
234 prepare stmt3 from "select * from t1 where c1=10";
235 --echo ---- switch to connection default ----
236 connection default;
237 # then QC is enabled at EXECUTE
238 set global query_cache_size=102400;
239 show status like 'Qcache_hits';
240 execute stmt1;
241 show status like 'Qcache_hits';
242 execute stmt1;
243 show status like 'Qcache_hits';
244 execute stmt1;
245 show status like 'Qcache_hits';
246 # The QC is global = affects also other connections.
247 --echo ---- switch to connection con1 ----
248 connection con1;
249 show status like 'Qcache_hits';
250 execute stmt3;
251 show status like 'Qcache_hits';
252 execute stmt3;
253 show status like 'Qcache_hits';
254 execute stmt3;
255 show status like 'Qcache_hits';
256 --echo ---- switch to connection default ----
257 connection default;
258 #
259 # QC is disabled at PREPARE
260 set global query_cache_size=0;
261 prepare stmt1 from "select * from t1 where c1=?";
262 # then QC is enabled at EXECUTE
263 set global query_cache_size=102400;
264 show status like 'Qcache_hits';
265 set @a=1;
266 execute stmt1 using @a;
267 show status like 'Qcache_hits';
268 set @a=100;
269 execute stmt1 using @a;
270 show status like 'Qcache_hits';
271 set @a=10;
272 execute stmt1 using @a;
273 show status like 'Qcache_hits';
274 
275 
276 drop table t1;
277 --echo ---- disconnect connection con1 ----
278 disconnect con1;
279 
280 #
281 # Bug #25843 Changing default database between PREPARE and EXECUTE of statement
282 # breaks binlog.
283 #
284 # There were actually two problems discovered by this bug:
285 #
286 # 1. Default (current) database is not fixed at the creation time.
287 # That leads to wrong output of DATABASE() function.
288 #
289 # 2. Database attributes (@@collation_database) are not fixed at the creation
290 # time. That leads to wrong resultset.
291 #
292 # Binlog breakage and Query Cache wrong output happened because of the first
293 # problem.
294 #
295 
296 --echo ########################################################################
297 --echo #
298 --echo # BUG#25843: Changing default database between PREPARE and EXECUTE of
299 --echo # statement breaks binlog.
300 --echo #
301 --echo ########################################################################
302 
303 ###############################################################################
304 
305 --echo
306 --echo #
307 --echo # Check that default database and its attributes are fixed at the
308 --echo # creation time.
309 --echo #
310 
311 # Prepare data structures.
312 
313 --echo
314 --disable_warnings
315 DROP DATABASE IF EXISTS mysqltest1;
316 DROP DATABASE IF EXISTS mysqltest2;
317 --enable_warnings
318 
319 --echo
320 CREATE DATABASE mysqltest1 COLLATE utf8_unicode_ci;
321 CREATE DATABASE mysqltest2 COLLATE utf8_general_ci;
322 
323 --echo
324 CREATE TABLE mysqltest1.t1(msg VARCHAR(255));
325 CREATE TABLE mysqltest2.t1(msg VARCHAR(255));
326 
327 # - Create a prepared statement with mysqltest1 as default database;
328 
329 --echo
330 
331 use mysqltest1;
332 
333 PREPARE stmt_a_1 FROM 'INSERT INTO t1 VALUES(DATABASE())';
334 PREPARE stmt_a_2 FROM 'INSERT INTO t1 VALUES(@@collation_database)';
335 
336 # - Execute on mysqltest1.
337 
338 --echo
339 
340 EXECUTE stmt_a_1;
341 EXECUTE stmt_a_2;
342 
343 # - Execute on mysqltest2.
344 
345 --echo
346 
347 use mysqltest2;
348 
349 EXECUTE stmt_a_1;
350 EXECUTE stmt_a_2;
351 
352 # - Check the results;
353 
354 --echo
355 SELECT * FROM mysqltest1.t1;
356 
357 --echo
358 SELECT * FROM mysqltest2.t1;
359 
360 # - Drop prepared statements.
361 
362 --echo
363 DROP PREPARE stmt_a_1;
364 DROP PREPARE stmt_a_2;
365 
366 ###############################################################################
367 
368 --echo
369 --echo #
370 --echo # The Query Cache test case.
371 --echo #
372 
373 --echo
374 DELETE FROM mysqltest1.t1;
375 DELETE FROM mysqltest2.t1;
376 
377 --echo
378 INSERT INTO mysqltest1.t1 VALUES('mysqltest1.t1');
379 INSERT INTO mysqltest2.t1 VALUES('mysqltest2.t1');
380 
381 --echo
382 use mysqltest1;
383 PREPARE stmt_b_1 FROM 'SELECT * FROM t1';
384 
385 --echo
386 use mysqltest2;
387 PREPARE stmt_b_2 FROM 'SELECT * FROM t1';
388 
389 --echo
390 EXECUTE stmt_b_1;
391 
392 --echo
393 EXECUTE stmt_b_2;
394 
395 --echo
396 use mysqltest1;
397 
398 --echo
399 EXECUTE stmt_b_1;
400 
401 --echo
402 EXECUTE stmt_b_2;
403 
404 --echo
405 DROP PREPARE stmt_b_1;
406 DROP PREPARE stmt_b_2;
407 
408 # Cleanup.
409 
410 --echo
411 use test;
412 
413 --echo
414 DROP DATABASE mysqltest1;
415 DROP DATABASE mysqltest2;
416 
417 ###############################################################################
418 
419 --echo
420 --echo #
421 --echo # Check that prepared statements work properly when there is no current
422 --echo # database.
423 --echo #
424 
425 --echo
426 CREATE DATABASE mysqltest1 COLLATE utf8_unicode_ci;
427 CREATE DATABASE mysqltest2 COLLATE utf8_general_ci;
428 
429 --echo
430 use mysqltest1;
431 
432 --echo
433 PREPARE stmt_c_1 FROM 'SELECT DATABASE(), @@collation_database';
434 
435 --echo
436 use mysqltest2;
437 
438 --echo
439 PREPARE stmt_c_2 FROM 'SELECT DATABASE(), @@collation_database';
440 
441 --echo
442 DROP DATABASE mysqltest2;
443 
444 --echo
445 SELECT DATABASE(), @@collation_database;
446 
447 # -- Here we have: current db: NULL; stmt db: mysqltest1;
448 --echo
449 EXECUTE stmt_c_1;
450 
451 --echo
452 SELECT DATABASE(), @@collation_database;
453 
454 # -- Here we have: current db: NULL; stmt db: mysqltest2 (non-existent);
455 --echo
456 EXECUTE stmt_c_2;
457 
458 --echo
459 SELECT DATABASE(), @@collation_database;
460 
461 # -- Create prepared statement, which has no current database.
462 
463 --echo
464 PREPARE stmt_c_3 FROM 'SELECT DATABASE(), @@collation_database';
465 
466 # -- Here we have: current db: NULL; stmt db: NULL;
467 --echo
468 EXECUTE stmt_c_3;
469 
470 --echo
471 use mysqltest1;
472 
473 # -- Here we have: current db: mysqltest1; stmt db: mysqltest2 (non-existent);
474 --echo
475 EXECUTE stmt_c_2;
476 
477 --echo
478 SELECT DATABASE(), @@collation_database;
479 
480 # -- Here we have: current db: mysqltest1; stmt db: NULL;
481 --echo
482 EXECUTE stmt_c_3;
483 
484 --echo
485 SELECT DATABASE(), @@collation_database;
486 
487 --echo
488 DROP DATABASE mysqltest1;
489 
490 --echo
491 use test;
492 
493 --echo
494 --echo ########################################################################
495 --echo #
496 --echo # Bug#27430 Crash in subquery code when in PS and table DDL changed
497 --echo # after PREPARE
498 --echo # Check the effect of automatic reprepare on query cache
499 --echo #
500 --echo ########################################################################
501 --disable_warnings
502 drop table if exists t1;
503 --enable_warnings
504 create table t1 (a varchar(255));
505 insert into t1 (a) values ("Pack my box with five dozen liquor jugs.");
506 flush status;
507 prepare stmt from "select a from t1";
508 execute stmt;
509 set @@global.query_cache_size=0;
510 alter table t1 add column b int;
511 execute stmt;
512 set @@global.query_cache_size=102400;
513 execute stmt;
514 execute stmt;
515 --echo #
516 --echo # Sic: ALTER TABLE caused an automatic reprepare
517 --echo # of the prepared statement. Since the query cache was disabled
518 --echo # at the time of reprepare, the new prepared statement doesn't
519 --echo # work with it.
520 --echo #
521 show status like 'Qcache_hits';
522 show status like 'Qcache_queries_in_cache';
523 --echo # Cleanup
524 deallocate prepare stmt;
525 drop table t1;
526 
527 ###############################################################################
528 
529 set @@global.query_cache_size=@initial_query_cache_size;
530 flush status; # reset Qcache status variables for next tests