Browse Source
BUG#11762751: UPDATE STATEMENT THROWS AN ERROR, BUT STILL
BUG#11762751: UPDATE STATEMENT THROWS AN ERROR, BUT STILL
UPDATES THE TABLE ENTRIES (formerly 55385)
BUG#11764529: MULTI UPDATE+INNODB REPORTS ER_KEY_NOT_FOUND
IF A TABLE IS UPDATED TWICE (formerly 57373)
If multiple-table update updates a row through two aliases and
the first update physically moves the row, the second update will
fail to locate the row. This results in different errors
depending on storage engine:
* MyISAM: Got error 134 from storage engine
* InnoDB: Can't find record in 'tbl'
None of these errors accurately describe the problem.
Furthermore, since MyISAM is non-transactional, the update
executed first will be performed while the second will not.
In addition, for two equal multiple-table update statements,
one could succeed and the other fail based on whether or not
the record actually moved or not. This was inconsistent.
Two update operations may physically move a row:
1) Update of a column in a clustered primary key
2) Update of a column used to calculate which partition the
row belongs to
BUG#11764529 is about case 1) above, BUG#11762751 was about case 2).
The fix for these bugs is to return with an error if multiple-table
update is about to:
a) Update a table through multiple aliases, and
b) Perform an update that may physically more the row
in at least one of these aliases
This avoids
* partial updates as described for MyISAM above,
* provides the same error message that describes the actual problem
for all SEs
* inconsistent behavior where a statement fails or succeeds based on
e.g. the partitioning algorithm of the table.
mysql-test/r/multi_update.result:
Add test for bug#57373
mysql-test/r/multi_update_innodb.result:
Add test for bug#57373
mysql-test/r/partition.result:
Add test for bug#55385
mysql-test/t/multi_update.test:
Add test for bug#57373
mysql-test/t/multi_update_innodb.test:
Add test for bug#57373
mysql-test/t/partition.test:
Add test for bug#55385
sql/handler.cc:
Translate handler error HA_ERR_RECORD_DELETED to server error
sql/share/errmsg-utf8.txt:
New error message for multi-table update where the same table is updated multiple times.
sql/sql_update.cc:
Add function unsafe_key_update()
pull/374/head
9 changed files with 298 additions and 1 deletions
-
17mysql-test/r/multi_update.result
-
29mysql-test/r/multi_update_innodb.result
-
48mysql-test/r/partition.result
-
20mysql-test/t/multi_update.test
-
33mysql-test/t/multi_update_innodb.test
-
50mysql-test/t/partition.test
-
1sql/handler.cc
-
3sql/share/errmsg-utf8.txt
-
98sql/sql_update.cc
@ -0,0 +1,29 @@ |
|||
# |
|||
# BUG#57373: Multi update+InnoDB reports ER_KEY_NOT_FOUND if a |
|||
# table is updated twice |
|||
# |
|||
CREATE TABLE t1( |
|||
pk INT, |
|||
a INT, |
|||
b INT, |
|||
PRIMARY KEY (pk) |
|||
) ENGINE=InnoDB; |
|||
INSERT INTO t1 VALUES (0,0,0); |
|||
UPDATE t1 AS A, t1 AS B SET A.pk = 1, B.a = 2; |
|||
ERROR HY000: Primary key/partition key update is not allowed since the table is updated both as 'A' and 'B'. |
|||
SELECT * FROM t1; |
|||
pk a b |
|||
0 0 0 |
|||
CREATE VIEW v1 AS SELECT * FROM t1; |
|||
UPDATE v1 AS A, t1 AS B SET A.pk = 1, B.a = 2; |
|||
ERROR HY000: Primary key/partition key update is not allowed since the table is updated both as 'A' and 'B'. |
|||
SELECT * FROM t1; |
|||
pk a b |
|||
0 0 0 |
|||
UPDATE t1 AS A, t1 AS B SET A.a = 1, B.b = 2; |
|||
# Should be (0,1,2) |
|||
SELECT * FROM t1; |
|||
pk a b |
|||
0 1 2 |
|||
DROP VIEW v1; |
|||
DROP TABLE t1; |
|||
@ -0,0 +1,33 @@ |
|||
--source include/have_innodb.inc |
|||
|
|||
--echo # |
|||
--echo # BUG#57373: Multi update+InnoDB reports ER_KEY_NOT_FOUND if a |
|||
--echo # table is updated twice |
|||
--echo # |
|||
|
|||
# Results differ between storage engines. |
|||
# See multi_update.test for the MyISAM variant of this test |
|||
CREATE TABLE t1( |
|||
pk INT, |
|||
a INT, |
|||
b INT, |
|||
PRIMARY KEY (pk) |
|||
) ENGINE=InnoDB; |
|||
|
|||
INSERT INTO t1 VALUES (0,0,0); |
|||
--error ER_MULTI_UPDATE_KEY_CONFLICT |
|||
UPDATE t1 AS A, t1 AS B SET A.pk = 1, B.a = 2; |
|||
SELECT * FROM t1; |
|||
|
|||
CREATE VIEW v1 AS SELECT * FROM t1; |
|||
--error ER_MULTI_UPDATE_KEY_CONFLICT |
|||
UPDATE v1 AS A, t1 AS B SET A.pk = 1, B.a = 2; |
|||
SELECT * FROM t1; |
|||
|
|||
UPDATE t1 AS A, t1 AS B SET A.a = 1, B.b = 2; |
|||
--echo # Should be (0,1,2) |
|||
SELECT * FROM t1; |
|||
|
|||
DROP VIEW v1; |
|||
DROP TABLE t1; |
|||
|
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue