Below is the list of changes that have just been committed into a local
5.0 repository of kaa. When kaa does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html
ChangeSet@stripped, 2007-11-20 16:59:10+03:00, kaa@polly.(none) +6 -0
Fix for bug #28837: MyISAM storage engine error (134) doing delete with
self-join
When doing DELETE with self-join on a MyISAM or MERGE table, it could
happen that a record being retrieved in join_read_next_same() has
already been deleted by previous iterations. That caused the engine's
index_next_same() method to fail with HA_ERR_RECORD_DELETED error and
the whole DELETE query to be aborted with an error.
Fixed by suppressing the HA_ERR_RECORD_DELETED error in
hy_myisam::index_next_same() and ha_myisammrg::index_next_same(). Since
HA_ERR_RECORD_DELETED can only be returned by MyISAM, there is no point
in filtering this error in the SQL layer.
mysql-test/r/merge.result@stripped, 2007-11-20 16:59:05+03:00, kaa@polly.(none) +37 -0
Added a test case for bug #28837.
mysql-test/r/myisam.result@stripped, 2007-11-20 16:59:05+03:00, kaa@polly.(none) +22 -0
Added a test case for bug #28837.
mysql-test/t/merge.test@stripped, 2007-11-20 16:59:05+03:00, kaa@polly.(none) +22 -0
Added a test case for bug #28837.
mysql-test/t/myisam.test@stripped, 2007-11-20 16:59:05+03:00, kaa@polly.(none) +17 -0
Added a test case for bug #28837.
sql/ha_myisam.cc@stripped, 2007-11-20 16:59:05+03:00, kaa@polly.(none) +7 -3
Skip HA_ERR_RECORD_DELETED silently when calling mi_rnext_same().
sql/ha_myisammrg.cc@stripped, 2007-11-20 16:59:05+03:00, kaa@polly.(none) +7 -3
Skip HA_ERR_RECORD_DELETED silently when calling mi_rnext_same().
diff -Nrup a/mysql-test/r/merge.result b/mysql-test/r/merge.result
--- a/mysql-test/r/merge.result 2007-06-14 15:18:00 +04:00
+++ b/mysql-test/r/merge.result 2007-11-20 16:59:05 +03:00
@@ -876,4 +876,41 @@ CHECK TABLE tm1;
Table Op Msg_type Msg_text
test.tm1 check status OK
DROP TABLE tm1, t1, t2;
+CREATE TABLE t1 (id INT NOT NULL, ref INT NOT NULL, INDEX (id)) ENGINE=MyISAM;
+CREATE TABLE t2 LIKE t1;
+INSERT INTO t2 (id, ref) VALUES (1,3), (2,1), (3,2), (4,5), (4,4);
+INSERT INTO t1 SELECT * FROM t2;
+INSERT INTO t1 SELECT * FROM t2;
+CREATE TABLE t3 (id INT NOT NULL, ref INT NOT NULL, INDEX (id)) ENGINE=MERGE
+UNION(t1);
+SELECT * FROM t3 AS a INNER JOIN t3 AS b USING (id) WHERE a.ref < b.ref;
+id ref ref
+4 4 5
+4 4 5
+4 4 5
+4 4 5
+SELECT * FROM t3;
+id ref
+1 3
+2 1
+3 2
+4 5
+4 4
+1 3
+2 1
+3 2
+4 5
+4 4
+DELETE FROM a USING t3 AS a INNER JOIN t3 AS b USING (id) WHERE a.ref < b.ref;
+SELECT * FROM t3;
+id ref
+1 3
+2 1
+3 2
+4 5
+1 3
+2 1
+3 2
+4 5
+DROP TABLE t1, t2, t3;
End of 5.0 tests
diff -Nrup a/mysql-test/r/myisam.result b/mysql-test/r/myisam.result
--- a/mysql-test/r/myisam.result 2007-05-22 16:58:29 +04:00
+++ b/mysql-test/r/myisam.result 2007-11-20 16:59:05 +03:00
@@ -1806,4 +1806,26 @@ SELECT a FROM t1 FORCE INDEX (inx) WHERE
a
1
DROP TABLE t1;
+CREATE TABLE t1 (id int NOT NULL, ref int NOT NULL, INDEX (id)) ENGINE=MyISAM;
+CREATE TABLE t2 LIKE t1;
+INSERT INTO t2 (id, ref) VALUES (1,3), (2,1), (3,2), (4,5), (4,4);
+INSERT INTO t1 SELECT * FROM t2;
+SELECT * FROM t1 AS a INNER JOIN t1 AS b USING (id) WHERE a.ref < b.ref;
+id ref ref
+4 4 5
+SELECT * FROM t1;
+id ref
+1 3
+2 1
+3 2
+4 5
+4 4
+DELETE FROM a USING t1 AS a INNER JOIN t1 AS b USING (id) WHERE a.ref < b.ref;
+SELECT * FROM t1;
+id ref
+1 3
+2 1
+3 2
+4 5
+DROP TABLE t1, t2;
End of 5.0 tests
diff -Nrup a/mysql-test/t/merge.test b/mysql-test/t/merge.test
--- a/mysql-test/t/merge.test 2007-06-06 03:42:39 +04:00
+++ b/mysql-test/t/merge.test 2007-11-20 16:59:05 +03:00
@@ -507,4 +507,26 @@ SELECT * FROM tm1;
CHECK TABLE tm1;
DROP TABLE tm1, t1, t2;
+#
+# Bug #28837: MyISAM storage engine error (134) doing delete with self-join
+#
+
+CREATE TABLE t1 (id INT NOT NULL, ref INT NOT NULL, INDEX (id)) ENGINE=MyISAM;
+CREATE TABLE t2 LIKE t1;
+
+INSERT INTO t2 (id, ref) VALUES (1,3), (2,1), (3,2), (4,5), (4,4);
+INSERT INTO t1 SELECT * FROM t2;
+INSERT INTO t1 SELECT * FROM t2;
+
+CREATE TABLE t3 (id INT NOT NULL, ref INT NOT NULL, INDEX (id)) ENGINE=MERGE
+ UNION(t1);
+
+SELECT * FROM t3 AS a INNER JOIN t3 AS b USING (id) WHERE a.ref < b.ref;
+SELECT * FROM t3;
+DELETE FROM a USING t3 AS a INNER JOIN t3 AS b USING (id) WHERE a.ref < b.ref;
+SELECT * FROM t3;
+
+DROP TABLE t1, t2, t3;
+
+
--echo End of 5.0 tests
diff -Nrup a/mysql-test/t/myisam.test b/mysql-test/t/myisam.test
--- a/mysql-test/t/myisam.test 2007-08-29 16:44:21 +04:00
+++ b/mysql-test/t/myisam.test 2007-11-20 16:59:05 +03:00
@@ -1161,4 +1161,21 @@ ALTER TABLE t1 ENABLE KEYS;
SELECT a FROM t1 FORCE INDEX (inx) WHERE a=1;
DROP TABLE t1;
+#
+# Bug#28837: MyISAM storage engine error (134) doing delete with self-join
+#
+
+CREATE TABLE t1 (id int NOT NULL, ref int NOT NULL, INDEX (id)) ENGINE=MyISAM;
+CREATE TABLE t2 LIKE t1;
+
+INSERT INTO t2 (id, ref) VALUES (1,3), (2,1), (3,2), (4,5), (4,4);
+INSERT INTO t1 SELECT * FROM t2;
+
+SELECT * FROM t1 AS a INNER JOIN t1 AS b USING (id) WHERE a.ref < b.ref;
+SELECT * FROM t1;
+DELETE FROM a USING t1 AS a INNER JOIN t1 AS b USING (id) WHERE a.ref < b.ref;
+SELECT * FROM t1;
+
+DROP TABLE t1, t2;
+
--echo End of 5.0 tests
diff -Nrup a/sql/ha_myisam.cc b/sql/ha_myisam.cc
--- a/sql/ha_myisam.cc 2007-07-19 18:57:48 +04:00
+++ b/sql/ha_myisam.cc 2007-11-20 16:59:05 +03:00
@@ -1602,10 +1602,14 @@ int ha_myisam::index_next_same(byte * bu
const byte *key __attribute__((unused)),
uint length __attribute__((unused)))
{
+ int error;
DBUG_ASSERT(inited==INDEX);
- statistic_increment(table->in_use->status_var.ha_read_next_count,
- &LOCK_status);
- int error=mi_rnext_same(file,buf);
+ do
+ {
+ statistic_increment(table->in_use->status_var.ha_read_next_count,
+ &LOCK_status);
+ error= mi_rnext_same(file,buf);
+ } while (error == HA_ERR_RECORD_DELETED);
table->status=error ? STATUS_NOT_FOUND: 0;
return error;
}
diff -Nrup a/sql/ha_myisammrg.cc b/sql/ha_myisammrg.cc
--- a/sql/ha_myisammrg.cc 2007-06-14 15:18:00 +04:00
+++ b/sql/ha_myisammrg.cc 2007-11-20 16:59:05 +03:00
@@ -294,9 +294,13 @@ int ha_myisammrg::index_next_same(byte *
const byte *key __attribute__((unused)),
uint length __attribute__((unused)))
{
- statistic_increment(table->in_use->status_var.ha_read_next_count,
- &LOCK_status);
- int error=myrg_rnext_same(file,buf);
+ int error;
+ do
+ {
+ statistic_increment(table->in_use->status_var.ha_read_next_count,
+ &LOCK_status);
+ error= myrg_rnext_same(file,buf);
+ } while (error == HA_ERR_RECORD_DELETED);
table->status=error ? STATUS_NOT_FOUND: 0;
return error;
}