summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mysql-test/r/merge.result37
-rw-r--r--mysql-test/r/myisam.result22
-rw-r--r--mysql-test/t/merge.test22
-rw-r--r--mysql-test/t/myisam.test17
-rw-r--r--sql/ha_myisam.cc8
-rw-r--r--sql/ha_myisammrg.cc8
6 files changed, 110 insertions, 4 deletions
diff --git a/mysql-test/r/merge.result b/mysql-test/r/merge.result
index 24a56fbf575..2ceae95dfca 100644
--- a/mysql-test/r/merge.result
+++ b/mysql-test/r/merge.result
@@ -881,4 +881,41 @@ CREATE TABLE t2 (c1 INT) ENGINE=MERGE UNION=(t1) INSERT_METHOD=FIRST;
CREATE TABLE IF NOT EXISTS t1 SELECT * FROM t2;
ERROR HY000: You can't specify target table 't1' for update in FROM clause
DROP TABLE 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 --git a/mysql-test/r/myisam.result b/mysql-test/r/myisam.result
index 176d0e97012..c7d4effcc35 100644
--- a/mysql-test/r/myisam.result
+++ b/mysql-test/r/myisam.result
@@ -1831,4 +1831,26 @@ SHOW TABLE STATUS LIKE 't1';
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment
t1 MyISAM 10 Fixed 1 # # # 3072 # # # # # # #
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 --git a/mysql-test/t/merge.test b/mysql-test/t/merge.test
index b5c1a01fe8e..29020159d9e 100644
--- a/mysql-test/t/merge.test
+++ b/mysql-test/t/merge.test
@@ -521,4 +521,26 @@ CREATE TABLE t2 (c1 INT) ENGINE=MERGE UNION=(t1) INSERT_METHOD=FIRST;
CREATE TABLE IF NOT EXISTS t1 SELECT * FROM t2;
DROP TABLE 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 --git a/mysql-test/t/myisam.test b/mysql-test/t/myisam.test
index ad223dc2664..ae646bd7659 100644
--- a/mysql-test/t/myisam.test
+++ b/mysql-test/t/myisam.test
@@ -1187,4 +1187,21 @@ SHOW TABLE STATUS LIKE 't1';
#--exec myisamchk -iev var/master-data/test/t1.MYI
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 --git a/sql/ha_myisam.cc b/sql/ha_myisam.cc
index ae0284fb202..1a0cbf61da2 100644
--- a/sql/ha_myisam.cc
+++ b/sql/ha_myisam.cc
@@ -1602,10 +1602,14 @@ int ha_myisam::index_next_same(byte * buf,
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);
+ &LOCK_status);
+ do
+ {
+ error= mi_rnext_same(file,buf);
+ } while (error == HA_ERR_RECORD_DELETED);
table->status=error ? STATUS_NOT_FOUND: 0;
return error;
}
diff --git a/sql/ha_myisammrg.cc b/sql/ha_myisammrg.cc
index 60aa4bd6adc..78492d2843d 100644
--- a/sql/ha_myisammrg.cc
+++ b/sql/ha_myisammrg.cc
@@ -294,9 +294,13 @@ int ha_myisammrg::index_next_same(byte * buf,
const byte *key __attribute__((unused)),
uint length __attribute__((unused)))
{
+ int error;
statistic_increment(table->in_use->status_var.ha_read_next_count,
- &LOCK_status);
- int error=myrg_rnext_same(file,buf);
+ &LOCK_status);
+ do
+ {
+ error= myrg_rnext_same(file,buf);
+ } while (error == HA_ERR_RECORD_DELETED);
table->status=error ? STATUS_NOT_FOUND: 0;
return error;
}