1call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT");
2set sql_mode=no_engine_substitution;
3set default_storage_engine = InnoDB;
4set autocommit=1;
5drop table if exists t1;
6drop table if exists t2;
7drop table if exists t3;
8drop function if exists f2;
9drop procedure if exists bug12713_call;
10drop procedure if exists bug12713_dump_spvars;
11drop procedure if exists dummy;
12create table t1 (a int);
13create table t2 (a int unique);
14create table t3 (a int);
15set sql_mode=default;
16insert into t1 (a) values (1), (2);
17insert into t3 (a) values (1), (2);
18create function f2(x int) returns int
19begin
20insert into t2 (a) values (x);
21insert into t2 (a) values (x);
22return x;
23end|
24set autocommit=0;
25flush status;
26insert into t2 (a) values (1001);
27insert into t1 (a) values (f2(1));
28ERROR 23000: Duplicate entry '1' for key 'a'
29select * from t2;
30a
311001
32rollback;
33select * from t2;
34a
35insert into t2 (a) values (1002);
36insert into t3 (a) select f2(2) from t1;
37ERROR 23000: Duplicate entry '2' for key 'a'
38select * from t2;
39a
401002
41rollback;
42select * from t2;
43a
44insert into t2 (a) values (1003);
45update t1 set a= a + f2(3);
46ERROR 23000: Duplicate entry '3' for key 'a'
47select * from t2;
48a
491003
50rollback;
51select * from t2;
52a
53insert into t2 (a) values (1004);
54update t1, t3 set t1.a = 0, t3.a = 0 where (f2(4) = 4) and (t1.a = t3.a);
55ERROR 23000: Duplicate entry '4' for key 'a'
56select * from t2;
57a
581004
59rollback;
60select * from t2;
61a
62insert into t2 (a) values (1005);
63delete from t1 where (a = f2(5));
64ERROR 23000: Duplicate entry '5' for key 'a'
65select * from t2;
66a
671005
68rollback;
69select * from t2;
70a
71insert into t2 (a) values (1006);
72delete from t1, t3 using t1, t3 where (f2(6) = 6) ;
73ERROR 23000: Duplicate entry '6' for key 'a'
74select * from t2;
75a
761006
77rollback;
78select * from t2;
79a
80insert into t2 (a) values (1007);
81replace t1 values (f2(7));
82ERROR 23000: Duplicate entry '7' for key 'a'
83select * from t2;
84a
851007
86rollback;
87select * from t2;
88a
89insert into t2 (a) values (1008);
90replace into t3 (a) select f2(8) from t1;
91ERROR 23000: Duplicate entry '8' for key 'a'
92select * from t2;
93a
941008
95rollback;
96select * from t2;
97a
98insert into t2 (a) values (1009);
99select f2(9) from t1 ;
100ERROR 23000: Duplicate entry '9' for key 'a'
101select * from t2;
102a
1031009
104rollback;
105select * from t2;
106a
107insert into t2 (a) values (1010);
108show databases where (f2(10) = 10);
109ERROR 23000: Duplicate entry '10' for key 'a'
110select * from t2;
111a
1121010
113rollback;
114select * from t2;
115a
116insert into t2 (a) values (1011);
117show tables where (f2(11) = 11);
118ERROR 23000: Duplicate entry '11' for key 'a'
119select * from t2;
120a
1211011
122rollback;
123select * from t2;
124a
125insert into t2 (a) values (1012);
126show triggers where (f2(12) = 12);
127ERROR 23000: Duplicate entry '12' for key 'a'
128select * from t2;
129a
1301012
131rollback;
132select * from t2;
133a
134insert into t2 (a) values (1013);
135show table status where (f2(13) = 13);
136ERROR 23000: Duplicate entry '13' for key 'a'
137select * from t2;
138a
1391013
140rollback;
141select * from t2;
142a
143insert into t2 (a) values (1014);
144show open tables where (f2(14) = 14);
145ERROR 23000: Duplicate entry '14' for key 'a'
146select * from t2;
147a
1481014
149rollback;
150select * from t2;
151a
152insert into t2 (a) values (1015);
153show columns in mysql.proc where (f2(15) = 15);
154ERROR 23000: Duplicate entry '15' for key 'a'
155select * from t2;
156a
1571015
158rollback;
159select * from t2;
160a
161insert into t2 (a) values (1016);
162show status where (f2(16) = 16);
163ERROR 23000: Duplicate entry '16' for key 'a'
164select * from t2;
165a
1661016
167rollback;
168select * from t2;
169a
170insert into t2 (a) values (1017);
171show variables where (f2(17) = 17);
172ERROR 23000: Duplicate entry '17' for key 'a'
173select * from t2;
174a
1751017
176rollback;
177select * from t2;
178a
179insert into t2 (a) values (1018);
180show charset where (f2(18) = 18);
181ERROR 23000: Duplicate entry '18' for key 'a'
182select * from t2;
183a
1841018
185rollback;
186select * from t2;
187a
188insert into t2 (a) values (1019);
189show collation where (f2(19) = 19);
190ERROR 23000: Duplicate entry '19' for key 'a'
191select * from t2;
192a
1931019
194rollback;
195select * from t2;
196a
197# We need at least one procedure to make sure the WHERE clause is
198# evaluated
199create procedure dummy() begin end;
200insert into t2 (a) values (1020);
201show procedure status where (f2(20) = 20);
202ERROR 23000: Duplicate entry '20' for key 'a'
203select * from t2;
204a
2051020
206rollback;
207select * from t2;
208a
209drop procedure dummy;
210insert into t2 (a) values (1021);
211show function status where (f2(21) = 21);
212ERROR 23000: Duplicate entry '21' for key 'a'
213select * from t2;
214a
2151021
216rollback;
217select * from t2;
218a
219insert into t2 (a) values (1022);
220prepare stmt from "insert into t1 (a) values (f2(22))";
221execute stmt;
222ERROR 23000: Duplicate entry '22' for key 'a'
223select * from t2;
224a
2251022
226rollback;
227select * from t2;
228a
229insert into t2 (a) values (1023);
230do (f2(23));
231Warnings:
232Error	1062	Duplicate entry '23' for key 'a'
233Note	4094	At line 4 in test.f2
234select * from t2;
235a
2361023
237rollback;
238select * from t2;
239a
240create procedure bug12713_call ()
241begin
242insert into t2 (a) values (24);
243insert into t2 (a) values (24);
244end|
245insert into t2 (a) values (1024);
246call bug12713_call();
247ERROR 23000: Duplicate entry '24' for key 'a'
248select * from t2;
249a
25024
2511024
252rollback;
253select * from t2;
254a
255=======================================================================
256Testing select_to_file
257=======================================================================
258insert into t2 (a) values (1025);
259select f2(25) into outfile "../tmp/dml.out" from t1;
260ERROR 23000: Duplicate entry '25' for key 'a'
261select * from t2;
262a
2631025
264rollback;
265select * from t2;
266a
267insert into t2 (a) values (1026);
268load data infile "../../std_data/words.dat" ignore into table t1 (a) set a:=f2(26);
269ERROR 23000: Duplicate entry '26' for key 'a'
270select * from t2;
271a
2721026
273rollback;
274select * from t2;
275a
276=======================================================================
277Testing select_dumpvar
278=======================================================================
279insert into t2 (a) values (1027);
280select f2(27) into @foo;
281ERROR 23000: Duplicate entry '27' for key 'a'
282select * from t2;
283a
2841027
285rollback;
286select * from t2;
287a
288=======================================================================
289Testing Select_fetch_into_spvars
290=======================================================================
291create procedure bug12713_dump_spvars ()
292begin
293declare foo int;
294declare continue handler for sqlexception
295begin
296select "Exception trapped";
297end;
298select f2(28) into foo;
299select * from t2;
300end|
301insert into t2 (a) values (1028);
302call bug12713_dump_spvars ();
303Exception trapped
304Exception trapped
305a
3061028
307rollback;
308select * from t2;
309a
310=======================================================================
311Cleanup
312=======================================================================
313set autocommit=default;
314drop table t1;
315drop table t2;
316drop table t3;
317drop function f2;
318drop procedure bug12713_call;
319drop procedure bug12713_dump_spvars;
320#
321# Bug#12713 Error in a stored function called from a SELECT doesn't
322# cause ROLLBACK of statem
323#
324# Verify that two-phase commit is not issued for read-only
325# transactions.
326#
327# Verify that two-phase commit is issued for read-write transactions,
328# even if the change is done inside a stored function called from
329# SELECT or SHOW statement.
330#
331set autocommit=0;
332drop table if exists t1;
333drop table if exists t2;
334drop function if exists f1;
335drop procedure if exists p_verify_status_increment;
336set @binlog_format=@@global.binlog_format;
337set sql_mode=no_engine_substitution;
338create table t1 (a int unique);
339create table t2 (a int) engine=myisam;
340set sql_mode=default;
341#
342# An auxiliary procedure to track Handler_prepare and Handler_commit
343# statistics.
344#
345create procedure
346p_verify_status_increment(commit_inc_mixed int, prepare_inc_mixed int,
347commit_inc_row int, prepare_inc_row int)
348begin
349declare commit_inc int;
350declare prepare_inc int;
351declare old_commit_count int default ifnull(@commit_count, 0);
352declare old_prepare_count int default ifnull(@prepare_count, 0);
353declare c_res int;
354# Use a cursor to have just one access to I_S instead of 2, it is very slow
355# and amounts for over 90% of test CPU time
356declare c cursor for
357select variable_value
358from information_schema.session_status
359where variable_name='Handler_commit' or variable_name='Handler_prepare'
360     order by variable_name;
361if @binlog_format = 'ROW' then
362set commit_inc= commit_inc_row;
363set prepare_inc= prepare_inc_row;
364else
365set commit_inc= commit_inc_mixed;
366set prepare_inc= prepare_inc_mixed;
367end if;
368open c;
369fetch c into c_res;
370set @commit_count=c_res;
371fetch c into c_res;
372set @prepare_count=c_res;
373close c;
374if old_commit_count + commit_inc <> @commit_count then
375select concat("Expected commit increment: ", commit_inc,
376" actual: ", @commit_count - old_commit_count)
377as 'ERROR';
378elseif old_prepare_count + prepare_inc <> @prepare_count then
379select concat("Expected prepare increment: ", prepare_inc,
380" actual: ", @prepare_count - old_prepare_count)
381as 'ERROR';
382else
383select '' as 'SUCCESS';
384end if;
385end|
386# Reset Handler_commit and Handler_prepare counters
387flush status;
388#
389# Count of reading of p_verify_status_increment() from mysql.proc
390call p_verify_status_increment(2, 0, 2, 0);
391SUCCESS
392
393#
394# 1. Read-only statement: SELECT
395#
396select * from t1;
397a
398call p_verify_status_increment(1, 0, 1, 0);
399SUCCESS
400
401commit;
402call p_verify_status_increment(1, 0, 1, 0);
403SUCCESS
404
405# 2. Read-write statement: INSERT, insert 1 row.
406#
407insert into t1 (a) values (1);
408call p_verify_status_increment(2, 2, 2, 2);
409SUCCESS
410
411commit;
412call p_verify_status_increment(2, 2, 2, 2);
413SUCCESS
414
415# 3. Read-write statement: UPDATE, update 1 row.
416#
417update t1 set a=2;
418call p_verify_status_increment(2, 2, 2, 2);
419SUCCESS
420
421commit;
422call p_verify_status_increment(2, 2, 2, 2);
423SUCCESS
424
425# 4. Read-write statement: UPDATE, update 0 rows, 1 row matches WHERE
426#
427update t1 set a=2;
428call p_verify_status_increment(2, 0, 1, 0);
429SUCCESS
430
431commit;
432call p_verify_status_increment(2, 0, 1, 0);
433SUCCESS
434
435# 5. Read-write statement: UPDATE, update 0 rows, 0 rows match WHERE
436#
437# In mixed replication mode, there is a read-only transaction
438# in InnoDB and also the statement is written to the binary log.
439# So we have two commits but no 2pc, since the first engine's
440# transaction is read-only.
441# In the row level replication mode, we only have the read-only
442# transaction in InnoDB and nothing is written to the binary log.
443#
444update t1 set a=3 where a=1;
445call p_verify_status_increment(2, 0, 1, 0);
446SUCCESS
447
448commit;
449call p_verify_status_increment(2, 0, 1, 0);
450SUCCESS
451
452# 6. Read-write statement: DELETE, delete 0 rows.
453#
454delete from t1 where a=1;
455call p_verify_status_increment(2, 0, 1, 0);
456SUCCESS
457
458commit;
459call p_verify_status_increment(2, 0, 1, 0);
460SUCCESS
461
462# 7. Read-write statement: DELETE, delete 1 row.
463#
464delete from t1 where a=2;
465call p_verify_status_increment(2, 2, 2, 2);
466SUCCESS
467
468commit;
469call p_verify_status_increment(2, 2, 2, 2);
470SUCCESS
471
472# 8. Read-write statement: unqualified DELETE
473#
474# In statement or mixed replication mode, we call
475# handler::ha_delete_all_rows() and write statement text
476# to the binary log. This results in two read-write transactions.
477# In row level replication mode, we do not call
478# handler::ha_delete_all_rows(), but delete rows one by one.
479# Since there are no rows, nothing is written to the binary log.
480# Thus we have just one read-only transaction in InnoDB.
481delete from t1;
482call p_verify_status_increment(2, 2, 1, 0);
483SUCCESS
484
485commit;
486call p_verify_status_increment(2, 2, 1, 0);
487SUCCESS
488
489# 9. Read-write statement: REPLACE, change 1 row.
490#
491replace t1 set a=1;
492call p_verify_status_increment(2, 2, 2, 2);
493SUCCESS
494
495commit;
496call p_verify_status_increment(2, 2, 2, 2);
497SUCCESS
498
499# 10. Read-write statement: REPLACE, change 0 rows.
500#
501replace t1 set a=1;
502call p_verify_status_increment(2, 2, 1, 0);
503SUCCESS
504
505commit;
506call p_verify_status_increment(2, 2, 1, 0);
507SUCCESS
508
509# 11. Read-write statement: IODKU, change 1 row.
510#
511insert t1 set a=1 on duplicate key update a=a+1;
512call p_verify_status_increment(2, 2, 2, 2);
513SUCCESS
514
515select * from t1;
516a
5172
518call p_verify_status_increment(1, 0, 1, 0);
519SUCCESS
520
521commit;
522call p_verify_status_increment(2, 2, 2, 2);
523SUCCESS
524
525# 12. Read-write statement: IODKU, change 0 rows.
526#
527insert t1 set a=2 on duplicate key update a=2;
528call p_verify_status_increment(2, 2, 1, 0);
529SUCCESS
530
531commit;
532call p_verify_status_increment(2, 2, 1, 0);
533SUCCESS
534
535# 13. Read-write statement: INSERT IGNORE, change 0 rows.
536#
537insert ignore t1 set a=2;
538Warnings:
539Warning	1062	Duplicate entry '2' for key 'a'
540call p_verify_status_increment(2, 2, 1, 0);
541SUCCESS
542
543commit;
544call p_verify_status_increment(2, 2, 1, 0);
545SUCCESS
546
547# 14. Read-write statement: INSERT IGNORE, change 1 row.
548#
549insert ignore t1 set a=1;
550call p_verify_status_increment(2, 2, 2, 2);
551SUCCESS
552
553commit;
554call p_verify_status_increment(2, 2, 2, 2);
555SUCCESS
556
557# 15. Read-write statement: UPDATE IGNORE, change 0 rows.
558#
559update ignore t1 set a=2 where a=1;
560SUCCESS
561
562commit;
563SUCCESS
564
565#
566# Create a stored function that modifies a
567# non-transactional table. Demonstrate that changes in
568# non-transactional tables do not affect the two phase commit
569# algorithm.
570#
571create function f1() returns int
572begin
573insert t2 set a=2;
574return 2;
575end|
576call p_verify_status_increment(4, 0, 4, 0);
577SUCCESS
578
579# 16. A function changes non-trans-table.
580#
581# For row-based logging, there is an extra commit for the
582# non-transactional changes saved in the transaction cache to
583# the binary log.
584#
585select f1();
586f1()
5872
588call p_verify_status_increment(3, 0, 3, 0);
589SUCCESS
590
591commit;
592call p_verify_status_increment(1, 0, 1, 0);
593SUCCESS
594
595# 17. Read-only statement, a function changes non-trans-table.
596#
597# For row-based logging, there is an extra commit for the
598# non-transactional changes saved in the transaction cache to
599# the binary log.
600#
601select f1() from t1;
602f1()
6032
6042
605call p_verify_status_increment(2, 0, 2, 0);
606SUCCESS
607
608commit;
609call p_verify_status_increment(2, 0, 2, 0);
610SUCCESS
611
612# 18. Read-write statement: UPDATE, change 0 (transactional) rows.
613#
614select count(*) from t2;
615count(*)
6163
617update t1 set a=2 where a=f1()+10;
618select count(*) from t2;
619count(*)
6205
621call p_verify_status_increment(2, 0, 2, 0);
622SUCCESS
623
624commit;
625call p_verify_status_increment(2, 0, 2, 0);
626SUCCESS
627
628#
629# Replace the non-transactional table with a temporary
630# transactional table. Demonstrate that a change to a temporary
631# transactional table does not provoke 2-phase commit, although
632# does trigger a commit and a binlog write (in statement mode).
633#
634drop table t2;
635set sql_mode=no_engine_substitution;
636create temporary table t2 (a int);
637call p_verify_status_increment(1, 0, 0, 0);
638SUCCESS
639
640set sql_mode=default;
641# 19. A function changes temp-trans-table.
642#
643select f1();
644f1()
6452
646# Two commits because a binary log record is written
647call p_verify_status_increment(2, 0, 1, 0);
648SUCCESS
649
650commit;
651call p_verify_status_increment(2, 0, 1, 0);
652SUCCESS
653
654# 20. Read-only statement, a function changes non-trans-table.
655#
656select f1() from t1;
657f1()
6582
6592
660# Two commits because a binary log record is written
661call p_verify_status_increment(2, 0, 1, 0);
662SUCCESS
663
664commit;
665call p_verify_status_increment(2, 0, 1, 0);
666SUCCESS
667
668# 21. Read-write statement: UPDATE, change 0 (transactional) rows.
669#
670update t1 set a=2 where a=f1()+10;
671call p_verify_status_increment(2, 0, 1, 0);
672SUCCESS
673
674commit;
675call p_verify_status_increment(2, 0, 1, 0);
676SUCCESS
677
678# 22. DDL: ALTER TEMPORARY TABLE, should not cause a 2pc
679#
680alter table t2 add column b int default 5;
681# A commit is done internally by ALTER.
682call p_verify_status_increment(2, 0, 2, 0);
683SUCCESS
684
685commit;
686# There is nothing left to commit
687call p_verify_status_increment(0, 0, 0, 0);
688SUCCESS
689
690# 23. DDL: RENAME TEMPORARY TABLE, does not start a transaction
691
692# No test because of Bug#8729 "rename table fails on temporary table"
693# 24. DDL: TRUNCATE TEMPORARY TABLE
694
695truncate table t2;
696call p_verify_status_increment(2, 0, 2, 0);
697SUCCESS
698
699commit;
700# There is nothing left to commit
701call p_verify_status_increment(0, 0, 0, 0);
702SUCCESS
703
704# 25. Read-write statement: unqualified DELETE
705
706delete from t2;
707call p_verify_status_increment(2, 0, 1, 0);
708SUCCESS
709
710commit;
711# There is nothing left to commit
712call p_verify_status_increment(2, 0, 1, 0);
713SUCCESS
714
715# 25. DDL: DROP TEMPORARY TABLE, does not start a transaction
716#
717drop temporary table t2;
718call p_verify_status_increment(1, 0, 1, 0);
719SUCCESS
720
721commit;
722call p_verify_status_increment(1, 0, 1, 0);
723SUCCESS
724
725# 26. Verify that SET AUTOCOMMIT issues an implicit commit
726#
727insert t1 set a=3;
728call p_verify_status_increment(2, 2, 2, 2);
729SUCCESS
730
731set autocommit=1;
732call p_verify_status_increment(2, 2, 2, 2);
733SUCCESS
734
735rollback;
736select a from t1 where a=3;
737a
7383
739call p_verify_status_increment(1, 0, 1, 0);
740SUCCESS
741
742delete from t1 where a=3;
743call p_verify_status_increment(2, 2, 2, 2);
744SUCCESS
745
746commit;
747call p_verify_status_increment(0, 0, 0, 0);
748SUCCESS
749
750set autocommit=0;
751call p_verify_status_increment(0, 0, 0, 0);
752SUCCESS
753
754insert t1 set a=3;
755call p_verify_status_increment(2, 2, 2, 2);
756SUCCESS
757
758# Sic: not actually changing the value of autocommit
759set autocommit=0;
760call p_verify_status_increment(0, 0, 0, 0);
761SUCCESS
762
763rollback;
764select a from t1 where a=3;
765a
766call p_verify_status_increment(1, 0, 1, 0);
767SUCCESS
768
769# 27. Savepoint management
770#
771insert t1 set a=3;
772call p_verify_status_increment(2, 2, 2, 2);
773SUCCESS
774
775savepoint a;
776call p_verify_status_increment(1, 0, 1, 0);
777SUCCESS
778
779insert t1 set a=4;
780call p_verify_status_increment(2, 2, 2, 2);
781SUCCESS
782
783release savepoint a;
784rollback;
785call p_verify_status_increment(0, 0, 0, 0);
786SUCCESS
787
788select a from t1 where a=3;
789a
790call p_verify_status_increment(1, 0, 1, 0);
791SUCCESS
792
793commit;
794call p_verify_status_increment(1, 0, 1, 0);
795SUCCESS
796
797# 28. Read-write statement: DO
798#
799create table t2 (a int);
800call p_verify_status_increment(0, 0, 0, 0);
801SUCCESS
802
803do (select f1() from t1 where a=2);
804call p_verify_status_increment(2, 2, 2, 2);
805SUCCESS
806
807commit;
808call p_verify_status_increment(2, 2, 2, 2);
809SUCCESS
810
811# 29. Read-write statement: MULTI-DELETE
812#
813delete t1, t2 from t1 join t2 on (t1.a=t2.a) where t1.a=2;
814commit;
815call p_verify_status_increment(4, 4, 4, 4);
816SUCCESS
817
818# 30. Read-write statement: INSERT-SELECT, MULTI-UPDATE, REPLACE-SELECT
819#
820insert into t2 select a from t1;
821commit;
822replace into t2 select a from t1;
823commit;
824call p_verify_status_increment(8, 8, 8, 8);
825SUCCESS
826
827update t1, t2 set t1.a=4, t2.a=8 where t1.a=t2.a and t1.a=1;
828commit;
829call p_verify_status_increment(4, 4, 4, 4);
830SUCCESS
831
832# 31. DDL: various DDL with transactional tables
833#
834# Sic: no table is created.
835create table if not exists t2 (a int) select 6 union select 7;
836Warnings:
837Note	1050	Table 't2' already exists
838# Sic: first commits the statement, and then the transaction.
839call p_verify_status_increment(0, 0, 0, 0);
840SUCCESS
841
842create table t3 select a from t2;
843call p_verify_status_increment(2, 0, 4, 4);
844SUCCESS
845
846alter table t3 add column (b int);
847call p_verify_status_increment(2, 0, 2, 0);
848SUCCESS
849
850alter table t3 rename t4;
851call p_verify_status_increment(0, 0, 0, 0);
852SUCCESS
853
854rename table t4 to t3;
855call p_verify_status_increment(0, 0, 0, 0);
856SUCCESS
857
858truncate table t3;
859call p_verify_status_increment(2, 0, 2, 0);
860SUCCESS
861
862create view v1 as select * from t2;
863call p_verify_status_increment(4, 0, 4, 0);
864SUCCESS
865
866check table t1;
867Table	Op	Msg_type	Msg_text
868test.t1	check	status	OK
869call p_verify_status_increment(2, 0, 2, 0);
870SUCCESS
871
872# Sic: after this bug is fixed, CHECK leaves no pending transaction
873commit;
874call p_verify_status_increment(0, 0, 0, 0);
875SUCCESS
876
877check table t1, t2, t3;
878Table	Op	Msg_type	Msg_text
879test.t1	check	status	OK
880test.t2	check	status	OK
881test.t3	check	status	OK
882call p_verify_status_increment(4, 0, 4, 0);
883SUCCESS
884
885commit;
886call p_verify_status_increment(0, 0, 0, 0);
887SUCCESS
888
889drop view v1;
890call p_verify_status_increment(2, 0, 2, 0);
891SUCCESS
892
893#
894# Cleanup
895#
896drop table t1, t2, t3;
897drop procedure p_verify_status_increment;
898drop function f1;
899