Merge lp:~laurynas-biveinis/percona-server/bug1387951 into lp:percona-server/5.6

Proposed by Laurynas Biveinis on 2015-02-04
Status: Merged
Approved by: Laurynas Biveinis on 2015-02-04
Approved revision: 735
Merged at revision: 736
Proposed branch: lp:~laurynas-biveinis/percona-server/bug1387951
Merge into: lp:percona-server/5.6
Diff against target: 150 lines (+82/-6)
3 files modified
mysql-test/r/percona_statement_set.result (+29/-2)
mysql-test/t/percona_statement_set.test (+48/-2)
sql/sql_parse.cc (+5/-2)
To merge this branch: bzr merge lp:~laurynas-biveinis/percona-server/bug1387951
Reviewer Review Type Date Requested Status
Laurynas Biveinis (community) Approve on 2015-02-04
Review via email: mp+248575@code.launchpad.net

Description of the change

Fix SET STATEMENT ... FOR <statement> crashes:
1) if <statement> needs to commit implicitly and fails (bug 1418049);
2) if <statement> is RW in a RO transaction (bug 1387951);
3) if <statement> is needs to reopen a temp table and fails (bug 1412423).

All three bugs are related and caused by mysql_execute_command jumping
over to an error exit (one goto per each bug) and thus skipping
per_query_variables_backup variable initialization. But the cleanup of
restoring thd->variables from the uninitialzied variable still
happened. Fixed trivially.

This bug was also indicated by a compilation warning:

07:37:58 /home/jenkins/workspace/percona-server-5.6-debian-binary-32/label_exp/debian6-32/percona-server-5.6-5.6.22-71.0/sql/sql_parse.cc: In function 'int mysql_execute_command(THD*)':
07:37:58
/home/jenkins/workspace/percona-server-5.6-debian-binary-32/label_exp/debian6-32/percona-server-5.6-5.6.22-71.0/sql/sql_parse.cc:2609:
error: 'per_query_variables_backup' may be used uninitialized in this
function

fixing which is part of bug 1408232.

Added testcases.

http://jenkins.percona.com/job/percona-server-5.6-param/805/

To post a comment you must log in.
review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'mysql-test/r/percona_statement_set.result'
2--- mysql-test/r/percona_statement_set.result 2013-09-27 17:47:04 +0000
3+++ mysql-test/r/percona_statement_set.result 2015-02-04 16:26:16 +0000
4@@ -8,7 +8,7 @@
5 DROP PROCEDURE IF EXISTS p5;
6 DROP TABLE IF EXISTS STATEMENT;
7 '# Setup database'
8-CREATE TABLE t1 (v1 INT, v2 INT);
9+CREATE TABLE t1 (v1 INT, v2 INT) ENGINE=MyISAM;
10 INSERT INTO t1 VALUES (1,2);
11 INSERT INTO t1 VALUES (3,4);
12 ''
13@@ -852,9 +852,36 @@
14 '#------------------Test 22-----------------------#'
15 CREATE TABLE STATEMENT(a INT);
16 DROP TABLE STATEMENT;
17+Test for bug 1418049: SET STATEMENT ... FOR <statement> crashes server
18+if <statement> needs to commit implicitly and fails
19+CREATE TABLE t2 (a INT PRIMARY KEY) ENGINE=InnoDB;
20+SET @old_lock_wait_timeout = @@session.lock_wait_timeout;
21+SET SESSION lock_wait_timeout = 1;
22+BEGIN;
23+INSERT INTO t2 VALUES (5);
24+FLUSH TABLES WITH READ LOCK;
25+SET STATEMENT max_join_size = 0 FOR DROP TABLE t2;
26+ERROR HY000: Lock wait timeout exceeded; try restarting transaction
27+UNLOCK TABLES;
28+COMMIT;
29+SET SESSION lock_wait_timeout = @old_lock_wait_timeout;
30+Test for bug 1387951: SET STATEMENT ... FOR <statement> crashes server
31+if <statement> is RW in a RO transaction
32+SET @old_tx_read_only = @@session.tx_read_only;
33+SET SESSION tx_read_only = TRUE;
34+SET STATEMENT myisam_repair_threads=0 FOR OPTIMIZE TABLE t0;
35+ERROR 25006: Cannot execute statement in a READ ONLY transaction.
36+SET SESSION tx_read_only = @old_tx_read_only;
37+Test for bug 1412423: SET STATEMENT ... FOR <statement> crashes server
38+if <statement> needs to re-open a temp table and fails
39+CREATE TEMPORARY TABLE t3 (a INT PRIMARY KEY) ENGINE=InnoDB;
40+HANDLER t3 OPEN;
41+SET STATEMENT max_join_size=1000 FOR SELECT * FROM t3;
42+ERROR HY000: Can't reopen table: 't3'
43+DROP TABLE t3;
44 ''
45 '# Cleanup'
46-DROP TABLE t1;
47+DROP TABLE t1, t2;
48 DROP PROCEDURE p1;
49 DROP PROCEDURE p2;
50 DROP PROCEDURE p3;
51
52=== modified file 'mysql-test/t/percona_statement_set.test'
53--- mysql-test/t/percona_statement_set.test 2013-09-27 17:47:04 +0000
54+++ mysql-test/t/percona_statement_set.test 2015-02-04 16:26:16 +0000
55@@ -1,3 +1,5 @@
56+--source include/have_innodb.inc
57+--source include/count_sessions.inc
58 --echo '# SET STATEMENT ..... FOR .... TEST'
59 ############################ STATEMENT_SET #############################
60 # #
61@@ -28,7 +30,7 @@
62 #Set up current database
63 ####################################################################
64 --echo '# Setup database'
65-CREATE TABLE t1 (v1 INT, v2 INT);
66+CREATE TABLE t1 (v1 INT, v2 INT) ENGINE=MyISAM;
67 INSERT INTO t1 VALUES (1,2);
68 INSERT INTO t1 VALUES (3,4);
69 --echo ''
70@@ -820,11 +822,55 @@
71 CREATE TABLE STATEMENT(a INT);
72 DROP TABLE STATEMENT;
73
74+--echo Test for bug 1418049: SET STATEMENT ... FOR <statement> crashes server
75+--echo if <statement> needs to commit implicitly and fails
76+
77+CREATE TABLE t2 (a INT PRIMARY KEY) ENGINE=InnoDB;
78+
79+SET @old_lock_wait_timeout = @@session.lock_wait_timeout;
80+SET SESSION lock_wait_timeout = 1;
81+
82+BEGIN;
83+INSERT INTO t2 VALUES (5);
84+
85+--connect(con1,localhost,root,,)
86+--connection con1
87+FLUSH TABLES WITH READ LOCK;
88+
89+--connection default
90+--error ER_LOCK_WAIT_TIMEOUT
91+SET STATEMENT max_join_size = 0 FOR DROP TABLE t2;
92+
93+--connection con1
94+UNLOCK TABLES;
95+--disconnect con1
96+--connection default
97+COMMIT;
98+SET SESSION lock_wait_timeout = @old_lock_wait_timeout;
99+
100+--echo Test for bug 1387951: SET STATEMENT ... FOR <statement> crashes server
101+--echo if <statement> is RW in a RO transaction
102+SET @old_tx_read_only = @@session.tx_read_only;
103+SET SESSION tx_read_only = TRUE;
104+--error ER_CANT_EXECUTE_IN_READ_ONLY_TRANSACTION
105+SET STATEMENT myisam_repair_threads=0 FOR OPTIMIZE TABLE t0;
106+SET SESSION tx_read_only = @old_tx_read_only;
107+
108+--echo Test for bug 1412423: SET STATEMENT ... FOR <statement> crashes server
109+--echo if <statement> needs to re-open a temp table and fails
110+CREATE TEMPORARY TABLE t3 (a INT PRIMARY KEY) ENGINE=InnoDB;
111+HANDLER t3 OPEN;
112+--error ER_CANT_REOPEN_TABLE
113+SET STATEMENT max_join_size=1000 FOR SELECT * FROM t3;
114+DROP TABLE t3;
115+
116 --echo ''
117 --echo '# Cleanup'
118-DROP TABLE t1;
119+DROP TABLE t1, t2;
120 DROP PROCEDURE p1;
121 DROP PROCEDURE p2;
122 DROP PROCEDURE p3;
123 DROP PROCEDURE p4;
124 DROP PROCEDURE p5;
125+
126+--source include/wait_until_count_sessions.inc
127
128=== modified file 'sql/sql_parse.cc'
129--- sql/sql_parse.cc 2015-01-13 09:38:11 +0000
130+++ sql/sql_parse.cc 2015-02-04 16:26:16 +0000
131@@ -2606,7 +2606,7 @@
132 /* have table map for update for multi-update statement (BUG#37051) */
133 bool have_table_map_for_update= FALSE;
134 #endif
135- struct system_variables *per_query_variables_backup;
136+ struct system_variables *per_query_variables_backup= NULL;
137 bool reset_timer= false;
138
139 DBUG_ENTER("mysql_execute_command");
140@@ -5490,7 +5490,10 @@
141 if (reset_timer)
142 reset_statement_timer(thd);
143
144- if (lex->set_statement && !lex->var_list.is_empty()) {
145+ if (per_query_variables_backup) {
146+ DBUG_ASSERT(lex->set_statement);
147+ DBUG_ASSERT(!lex->var_list.is_empty());
148+
149 List_iterator_fast<set_var_base> it(thd->lex->var_list);
150 set_var *var;
151

Subscribers

People subscribed via source and target branches