Bug #36676 | UPDATE on TEXT column using LEFT JOIN doesn't update all rows | ||
---|---|---|---|
Submitted: | 12 May 2008 22:05 | Modified: | 22 May 2008 12:41 |
Reporter: | Todd Farmer (OCA) | Email Updates: | |
Status: | Closed | Impact on me: | |
Category: | MySQL Server: DML | Severity: | S2 (Serious) |
Version: | 5.0.58 | OS: | Any |
Assigned to: | Gleb Shchepa | CPU Architecture: | Any |
[12 May 2008 22:05]
Todd Farmer
[17 May 2008 23:41]
Gleb Shchepa
This bug also can appear in a weird error message: ERROR 1022 (23000): Can't write; duplicate key in table '' even if updating table has no blobs (TEXTs). How to repeat: 1. set max hash table size to small value (to experiment with not very large tables): --max_heap_table_size=1 ../sql/mysqld --no-defaults --basedir=. --datadir=./var/master-data --language=../sql/share/english/ --character-sets-dir=../sql/share/charsets/ --gdb --skip-grant-tables --max_heap_table_size=1 2. CREATE TABLE one (id INT NOT NULL AUTO_INCREMENT PRIMARY KEY); CREATE TABLE two (id INT, s1 CHAR(255)); # insert [1..64] into table `one` INSERT INTO one VALUES (0), (0), (0), (0), (0), (0), (0), (0); INSERT INTO one (SELECT 0 FROM one); INSERT INTO one (SELECT 0 FROM one); INSERT INTO one (SELECT 0 FROM one); INSERT INTO two (SELECT ID, 'a' FROM one); UPDATE one LEFT JOIN two USING(id) SET s1 = 'b'; ======================================================== Server version: 5.0.62-debug Source distribution Type 'help;' or '\h' for help. Type '\c' to clear the buffer. mysql> CREATE TABLE one (id INT NOT NULL AUTO_INCREMENT PRIMARY KEY); Query OK, 0 rows affected (0.01 sec) mysql> CREATE TABLE two (id INT, s1 CHAR(255)); Query OK, 0 rows affected (0.00 sec) mysql> mysql> # insert [1..64] into table `one` mysql> INSERT INTO one VALUES (0), (0), (0), (0), (0), (0), (0), (0); Query OK, 8 rows affected (0.00 sec) Records: 8 Duplicates: 0 Warnings: 0 [skip] mysql> INSERT INTO one (SELECT 0 FROM one); Query OK, 32 rows affected (0.00 sec) Records: 32 Duplicates: 0 Warnings: 0 mysql> mysql> INSERT INTO two (SELECT ID, 'a' FROM one); Query OK, 64 rows affected (0.00 sec) Records: 64 Duplicates: 0 Warnings: 0 mysql> UPDATE one LEFT JOIN two USING(id) SET s1 = 'b'; ERROR 1022 (23000): Can't write; duplicate key in table '' ########################################################## # At the same time: ########################################################## mysql> DELETE FROM two WHERE id>50; Query OK, 13 rows affected (0.00 sec) mysql> UPDATE one LEFT JOIN two USING(id) SET s1 = 'b'; Query OK, 50 rows affected (0.01 sec) Rows matched: 50 Changed: 50 Warnings: 0
[18 May 2008 0:37]
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/46808 ChangeSet@1.2625, 2008-05-18 05:36:20+05:00, gshchepa@host.loc +4 -0 Fixed bug#36676: multiupdate using LEFT JOIN updates only first row or fails with an error: ERROR 1022 (23000): Can't write; duplicate key in table '' The server uses intermediate temporary table to store updated row data. The first column of this table contains rowid. Current server implementation doesn't reset NULL flag of that column even if the server fills a column with rowid. To keep each rowid unique, there is an unique index. An insertion into an unique index takes into account NULL flag of key value and ignores real data if NULL flag is set. So, insertion of actually different rowids may lead to two kind of problems. Visible effect of each of these problems depends on an initial engine type of temporary table: 1. If multiupdate initially creates temporary table as a MyISAM table (a table contains blob columns, and the create_tmp_table function assumes, that this table is large), it inserts only one single row and updates only rows with one corresponding rowid. Other rows are silently ignored. 2. If multiupdate initially creates MEMORY temporary table, fills it with data and reaches size limit for MEMORY tables (max_heap_table_size), multiupdate converts MEMORY table into MyISAM table and fails with and error; ERROR 1022 (23000): Can't write; duplicate key in table '' Multiupdate has been fixed to update the NULL flag of a temporary table rowid columns.
[18 May 2008 8: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/46811 ChangeSet@1.2625, 2008-05-18 13:32:50+05:00, gshchepa@host.loc +4 -0 Fixed bug#36676: multiupdate using LEFT JOIN updates only first row or fails with an error: ERROR 1022 (23000): Can't write; duplicate key in table '' The server uses intermediate temporary table to store updated row data. The first column of this table contains rowid. Current server implementation doesn't reset NULL flag of that column even if the server fills a column with rowid. To keep each rowid unique, there is an unique index. An insertion into an unique index takes into account NULL flag of key value and ignores real data if NULL flag is set. So, insertion of actually different rowids may lead to two kind of problems. Visible effect of each of these problems depends on an initial engine type of temporary table: 1. If multiupdate initially creates temporary table as a MyISAM table (a table contains blob columns, and the create_tmp_table function assumes, that this table is large), it inserts only one single row and updates only rows with one corresponding rowid. Other rows are silently ignored. 2. If multiupdate initially creates MEMORY temporary table, fills it with data and reaches size limit for MEMORY tables (max_heap_table_size), multiupdate converts MEMORY table into MyISAM table and fails with an error: ERROR 1022 (23000): Can't write; duplicate key in table '' Multiupdate has been fixed to update the NULL flag of temporary table rowid columns.
[18 May 2008 9:22]
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/46812 ChangeSet@1.2625, 2008-05-18 14:21:25+05:00, gshchepa@host.loc +4 -0 Fixed bug#36676: multiupdate using LEFT JOIN updates only first row or fails with an error: ERROR 1022 (23000): Can't write; duplicate key in table '' The server uses intermediate temporary table to store updated row data. The first column of this table contains rowid. Current server implementation doesn't reset NULL flag of that column even if the server fills a column with rowid. To keep each rowid unique, there is an unique index. An insertion into an unique index takes into account NULL flag of key value and ignores real data if NULL flag is set. So, insertion of actually different rowids may lead to two kind of problems. Visible effect of each of these problems depends on an initial engine type of temporary table: 1. If multiupdate initially creates temporary table as a MyISAM table (a table contains blob columns, and the create_tmp_table function assumes, that this table is large), it inserts only one single row and updates only rows with one corresponding rowid. Other rows are silently ignored. 2. If multiupdate initially creates MEMORY temporary table, fills it with data and reaches size limit for MEMORY tables (max_heap_table_size), multiupdate converts MEMORY table into MyISAM table and fails with an error: ERROR 1022 (23000): Can't write; duplicate key in table '' Multiupdate has been fixed to update the NULL flag of temporary table rowid columns.
[18 May 2008 10:01]
Georgi Kodinov
pushed in -bugteam
[19 May 2008 8:24]
Bugs System
Pushed into 5.0.64
[19 May 2008 8:25]
Bugs System
Pushed into 5.1.25-rc
[19 May 2008 19:50]
Sergey Petrunya
See also BUG#31379
[19 May 2008 19:56]
Gleb Shchepa
Also UPDATE of VIEW with OUTER-joined tables is affected by this bug.
[20 May 2008 0:31]
Paul DuBois
Noted in 5.0.64, 5.1.25 changelogs. Multiple-table UPDATE statements that used a temporary table could fail to update all qualifying rows or fail with a spurious duplicate-key error. Setting report to Need Doc Info pending push into 6.0.x.
[22 May 2008 9:50]
Bugs System
Pushed into 6.0.6-alpha
[22 May 2008 12:41]
Paul DuBois
Noted in 6.0.6 changelog.
[28 May 2008 14:20]
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/47145
[28 Jul 2008 13:49]
Bugs System
Pushed into 5.0.64 (revid:sp1r-gshchepa/uchum@host.loc-20080518092717-10710) (pib:2) (Retry automatic marking, to ensure nothing is missed. cm01)
[28 Jul 2008 16:54]
Bugs System
Pushed into 5.1.25-rc (revid:sp1r-gshchepa/uchum@host.loc-20080518092744-14339) (version source revid:sp1r-gshchepa/uchum@host.loc-20080518092744-14339) (pib:3)