Bug #41348 | INSERT INTO tbl SELECT * FROM temp_tbl overwrites locking type of temp table | ||
---|---|---|---|
Submitted: | 10 Dec 2008 2:38 | Modified: | 29 Jan 2009 5:00 |
Reporter: | Jonathon Coombes | Email Updates: | |
Status: | Closed | Impact on me: | |
Category: | MySQL Server: Locking | Severity: | S2 (Serious) |
Version: | 5.1.30 | OS: | Any |
Assigned to: | Davi Arnaut | CPU Architecture: | Any |
Tags: | functions, locking, prepared statements, regression |
[10 Dec 2008 2:38]
Jonathon Coombes
[10 Dec 2008 7:37]
Valeriy Kravchuk
Thank you for a problem report. Sorry, but I can not repeat the behaviour described: C:\Program Files\MySQL\MySQL Server 5.0\bin>mysql -uroot -proot -P3310 test Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 12 Server version: 5.1.30-enterprise-gpl-advanced MySQL Enterprise Server - Advance d Edition (GPL) Type 'help;' or '\h' for help. Type '\c' to clear the buffer. mysql> DROP TABLE IF EXISTS trac; Query OK, 0 rows affected (0.11 sec) mysql> CREATE TABLE trac ( -> NODEID VARCHAR(20), -> PARENTID VARCHAR(20), -> try VARCHAR(20) -> ) ENGINE=INNODB; Query OK, 0 rows affected (0.13 sec) mysql> INSERT INTO trac VALUES ('a','top',NULL),('b','a',NULL),('c','b',NULL); Query OK, 3 rows affected (0.03 sec) Records: 3 Duplicates: 0 Warnings: 0 mysql> DELIMITER $$ mysql> drop FUNCTION if exists try$$ Query OK, 0 rows affected (0.19 sec) mysql> CREATE FUNCTION try() RETURNS VARCHAR(250) -> BEGIN -> return 'hhhhhhh' ; -> END; -> $$ Query OK, 0 rows affected (0.03 sec) mysql> DELIMITER ; mysql> DROP TEMPORARY TABLE IF EXISTS TMPRESULTGRP; Query OK, 0 rows affected, 1 warning (0.00 sec) mysql> DROP TEMPORARY TABLE IF EXISTS __b; Query OK, 0 rows affected, 1 warning (0.00 sec) mysql> mysql> CREATE TEMPORARY TABLE __b ( -> lvl INT, -> nodeid VARCHAR(20), -> parentid VARCHAR(20), -> try varchar(20) -> ) ENGINE=INNODB; Query OK, 0 rows affected (0.06 sec) mysql> CREATE TEMPORARY TABLE TMPRESULTGRP LIKE __b; Query OK, 0 rows affected (0.13 sec) mysql> mysql> SET @stmt := CONCAT('insert into __b select @lvl, tnt.nodeid, tnt.parenti d, try()', -> ' FROM trac tnt '); Query OK, 0 rows affected (0.00 sec) mysql> PREPARE stmt_sp_insert_b FROM @stmt; Query OK, 0 rows affected (0.13 sec) Statement prepared mysql> EXECUTE stmt_sp_insert_b; Query OK, 3 rows affected (0.09 sec) Records: 3 Duplicates: 0 Warnings: 0 mysql> select * from __b; +------+--------+----------+---------+ | lvl | nodeid | parentid | try | +------+--------+----------+---------+ | NULL | a | top | hhhhhhh | | NULL | b | a | hhhhhhh | | NULL | c | b | hhhhhhh | +------+--------+----------+---------+ 3 rows in set (0.00 sec) What I am doing wrong?
[10 Dec 2008 12:20]
Valeriy Kravchuk
Correct test case is: DROP TABLE IF EXISTS trac; CREATE TABLE trac ( NODEID VARCHAR(20), PARENTID VARCHAR(20), try VARCHAR(20) ) ENGINE=INNODB; INSERT INTO trac VALUES ('a','top',NULL),('b','a',NULL),('c','b',NULL); DELIMITER $$ drop FUNCTION if exists try$$ CREATE FUNCTION try() RETURNS VARCHAR(250) BEGIN return 'hhhhhhh' ; END; $$ DELIMITER ; DROP TEMPORARY TABLE IF EXISTS TMPRESULTGRP; DROP TEMPORARY TABLE IF EXISTS __b; CREATE TEMPORARY TABLE __b ( lvl INT, nodeid VARCHAR(20), parentid VARCHAR(20), try varchar(20) ) ENGINE=INNODB; CREATE TEMPORARY TABLE TMPRESULTGRP LIKE __b; SET @lvl := 1; SET @stmt := CONCAT('insert into __b select @lvl, tnt.nodeid, tnt.parentid, try()', ' FROM trac tnt '); PREPARE stmt_sp_insert_b FROM @stmt; SET @stmt := CONCAT('INSERT INTO TMPRESULTGRP', ' SELECT * FROM __b'); PREPARE stmt_sp_insert_res_tbl FROM @stmt; EXECUTE stmt_sp_insert_res_tbl; DEALLOCATE PREPARE stmt_sp_insert_res_tbl; EXECUTE stmt_sp_insert_b; In 5.1.30 I've got: C:\Program Files\MySQL\MySQL Server 5.0\bin>mysql -uroot -proot -P3310 test Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 15 Server version: 5.1.30-enterprise-gpl-advanced MySQL Enterprise Server - Advance d Edition (GPL) Type 'help;' or '\h' for help. Type '\c' to clear the buffer. mysql> DROP TABLE IF EXISTS trac; Query OK, 0 rows affected (0.05 sec) mysql> mysql> CREATE TABLE trac ( -> NODEID VARCHAR(20), -> PARENTID VARCHAR(20), -> try VARCHAR(20) -> ) ENGINE=INNODB; Query OK, 0 rows affected (0.08 sec) mysql> mysql> INSERT INTO trac VALUES ('a','top',NULL),('b','a',NULL),('c','b',NULL); Query OK, 3 rows affected (0.02 sec) Records: 3 Duplicates: 0 Warnings: 0 mysql> mysql> DELIMITER $$ mysql> drop FUNCTION if exists try$$ Query OK, 0 rows affected (0.00 sec) mysql> CREATE FUNCTION try() RETURNS VARCHAR(250) -> BEGIN -> return 'hhhhhhh' ; -> END; -> $$ Query OK, 0 rows affected (0.03 sec) mysql> mysql> DELIMITER ; mysql> mysql> DROP TEMPORARY TABLE IF EXISTS TMPRESULTGRP; Query OK, 0 rows affected, 1 warning (0.00 sec) mysql> DROP TEMPORARY TABLE IF EXISTS __b; Query OK, 0 rows affected, 1 warning (0.00 sec) mysql> mysql> CREATE TEMPORARY TABLE __b ( -> lvl INT, -> nodeid VARCHAR(20), -> parentid VARCHAR(20), -> try varchar(20) -> ) ENGINE=INNODB; Query OK, 0 rows affected (0.03 sec) mysql> CREATE TEMPORARY TABLE TMPRESULTGRP LIKE __b; Query OK, 0 rows affected (0.06 sec) mysql> mysql> SET @lvl := 1; Query OK, 0 rows affected (0.00 sec) mysql> mysql> SET @stmt := CONCAT('insert into __b select @lvl, tnt.nodeid, tnt.parenti d, try()', -> ' FROM trac tnt '); Query OK, 0 rows affected (0.00 sec) mysql> PREPARE stmt_sp_insert_b FROM @stmt; Query OK, 0 rows affected (0.00 sec) Statement prepared mysql> mysql> SET @stmt := CONCAT('INSERT INTO TMPRESULTGRP', ' SELECT * FROM __b'); Query OK, 0 rows affected (0.00 sec) mysql> PREPARE stmt_sp_insert_res_tbl FROM @stmt; Query OK, 0 rows affected (0.00 sec) Statement prepared mysql> EXECUTE stmt_sp_insert_res_tbl; Query OK, 0 rows affected (0.00 sec) Records: 0 Duplicates: 0 Warnings: 0 mysql> DEALLOCATE PREPARE stmt_sp_insert_res_tbl; Query OK, 0 rows affected (0.00 sec) mysql> mysql> EXECUTE stmt_sp_insert_b; ERROR 1099 (HY000): Table '__b' was locked with a READ lock and can't be updated In 5.0.72 it works as expected. This is a regression bug.
[15 Dec 2008 19:55]
Davi Arnaut
Reduced test case: DELIMITER |; CREATE FUNCTION f1() RETURNS VARCHAR(250) BEGIN return 'hhhhhhh' ; END| DELIMITER ;| CREATE TEMPORARY TABLE t1 (a VARCHAR(20)); CREATE TEMPORARY TABLE t2 LIKE t1; PREPARE ps1 FROM "INSERT INTO t2 SELECT * FROM t1"; INSERT INTO t1 SELECT f1(); Initial analysis: A statement prepare (ps1) can inadvertently overwrite the locking type of a temporary table to a read lock.
[16 Dec 2008 13:05]
Davi Arnaut
DELIMITER |; CREATE FUNCTION f1() RETURNS VARCHAR(250) BEGIN return 'hhhhhhh' ; END| DELIMITER ;| CREATE TEMPORARY TABLE t1 (a VARCHAR(20)); CREATE TABLE t2 LIKE t1; INSERT INTO t2 SELECT * FROM t1; INSERT INTO t1 SELECT f1();
[16 Dec 2008 16:34]
Bugs System
A patch for this bug has been committed. After review, it may be pushed to the relevant source trees for release in the next version. You can access the patch from: http://lists.mysql.com/commits/61787 2739 Davi Arnaut 2008-12-16 Bug#41348: INSERT INTO tbl SELECT * FROM temp_tbl overwrites locking type of temp table The problem is that INSERT INTO .. SELECT FROM .. and CREATE TABLE .. SELECT FROM a temporary table could inadvertently overwrite the locking type of the temporary table. The lock type of temporary tables must always be a write lock. The solution is to ensure that the lock type of temporary tables is never overwritten and that its always a write lock.
[17 Dec 2008 11:29]
Davi Arnaut
Another manifestation of this problem can be triggered with a UPDATE statement: CREATE FUNCTION f1() RETURNS INT BEGIN return 1 ; END| DELIMITER ;| CREATE TEMPORARY TABLE t1 (a INT); CREATE TEMPORARY TABLE t2 (a INT); UPDATE t1,t2 SET t1.a = t2.a; INSERT INTO t2 SELECT f1(); The general problem also affects MySQL 5.0.
[17 Dec 2008 11:38]
Bugs System
A patch for this bug has been committed. After review, it may be pushed to the relevant source trees for release in the next version. You can access the patch from: http://lists.mysql.com/commits/61853 2739 Davi Arnaut 2008-12-17 Bug#41348: INSERT INTO tbl SELECT * FROM temp_tbl overwrites locking type of temp table The problem is that INSERT INTO .. SELECT FROM .. and CREATE TABLE .. SELECT FROM a temporary table could inadvertently overwrite the locking type of the temporary table. The lock type of temporary tables should be a write lock by default. The solution is to reset the lock type of temporary tables back to its default value after they are used in a statement.
[7 Jan 2009 12:12]
Bugs System
A patch for this bug has been committed. After review, it may be pushed to the relevant source trees for release in the next version. You can access the patch from: http://lists.mysql.com/commits/62588 2728 Davi Arnaut 2009-01-07 Bug#41348: INSERT INTO tbl SELECT * FROM temp_tbl overwrites locking type of temp table The problem is that INSERT INTO .. SELECT FROM .. and CREATE TABLE .. SELECT FROM a temporary table could inadvertently overwrite the locking type of the temporary table. The lock type of temporary tables should be a write lock by default. The solution is to reset the lock type of temporary tables back to its default value after they are used in a statement.
[8 Jan 2009 18:30]
Davi Arnaut
Queued to 5.1-bugteam
[14 Jan 2009 9:33]
Bugs System
A patch for this bug has been committed. After review, it may be pushed to the relevant source trees for release in the next version. You can access the patch from: http://lists.mysql.com/commits/63197 2748 He Zhenxing 2009-01-14 [merge] Auto merge
[15 Jan 2009 6:32]
Bugs System
Pushed into 5.1.31 (revid:joro@sun.com-20090115053147-tx1oapthnzgvs1ro) (version source revid:davi.arnaut@sun.com-20090113150631-y84w12o2zmh7j3qd) (merge vers: 5.1.31) (pib:6)
[19 Jan 2009 11:26]
Bugs System
Pushed into 5.1.31-ndb-6.2.17 (revid:tomas.ulin@sun.com-20090119095303-uwwvxiibtr38djii) (version source revid:tomas.ulin@sun.com-20090115073240-1wanl85vlvw2she1) (merge vers: 5.1.31-ndb-6.2.17) (pib:6)
[19 Jan 2009 13:04]
Bugs System
Pushed into 5.1.31-ndb-6.3.21 (revid:tomas.ulin@sun.com-20090119104956-guxz190n2kh31fxl) (version source revid:tomas.ulin@sun.com-20090119104956-guxz190n2kh31fxl) (merge vers: 5.1.31-ndb-6.3.21) (pib:6)
[19 Jan 2009 16:10]
Bugs System
Pushed into 5.1.31-ndb-6.4.1 (revid:tomas.ulin@sun.com-20090119144033-4aylstx5czzz88i5) (version source revid:tomas.ulin@sun.com-20090119144033-4aylstx5czzz88i5) (merge vers: 5.1.31-ndb-6.4.1) (pib:6)
[20 Jan 2009 18:56]
Bugs System
Pushed into 6.0.10-alpha (revid:joro@sun.com-20090119171328-2hemf2ndc1dxl0et) (version source revid:davi.arnaut@sun.com-20090108185343-ccylwxgk2rm6plku) (merge vers: 6.0.10-alpha) (pib:6)
[29 Jan 2009 5:00]
Paul DuBois
Noted in 5.1.31, 6.0.10 changelogs. INSERT INTO .. SELECT ... FROM and CREATE TABLE ... SELECT ... FROM a TEMPORARY table could inadvertently change the locking type of the temporary table from a write lock to a read lock, causing statement failure.