summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Petrunya <psergey@askmonty.org>2012-06-02 16:13:05 +0400
committerSergey Petrunya <psergey@askmonty.org>2012-06-02 16:13:05 +0400
commit25ada13db06d06050f0361bc434fe2b58303b5f2 (patch)
treefbfd3c789aab53ed73965c9d14a50c6c24f5cc7a
parent4d8d7912788747762031508e0c787313a9d1a0a2 (diff)
parentc17216eed83f6fa790dc5a4f8c040bcd428b6374 (diff)
downloadmariadb-git-25ada13db06d06050f0361bc434fe2b58303b5f2.tar.gz
Merge
-rw-r--r--mysql-test/r/index_merge_innodb.result32
-rw-r--r--mysql-test/t/index_merge_innodb.test33
-rw-r--r--sql/opt_range.cc17
3 files changed, 82 insertions, 0 deletions
diff --git a/mysql-test/r/index_merge_innodb.result b/mysql-test/r/index_merge_innodb.result
index 50b0147b6ad..e5025acc998 100644
--- a/mysql-test/r/index_merge_innodb.result
+++ b/mysql-test/r/index_merge_innodb.result
@@ -745,4 +745,36 @@ WHERE v1 IN ('f', 'd', 'h', 'u' ) AND i = 2;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ref i,v i 5 const 2 Using where
DROP TABLE t1;
+#
+# BUG#1006164: Multi-table DELETE that uses innodb + index_merge/intersect may fail to delete rows
+#
+create table t0(a int);
+insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+create table t1 (
+pk int auto_increment,
+zone_id int,
+modified tinyint,
+primary key(pk),
+key (zone_id),
+key (modified)
+) engine=innodb;
+insert into t1 (zone_id, modified) select 0,0 from t0 A, t0 B, t0 C, t0 D;
+update t1 set zone_id=487, modified=9 where pk=7259;
+update t1 set zone_id=487, modified=9 where pk=7260;
+update t1 set zone_id=830, modified=9 where pk=8434;
+update t1 set zone_id=830, modified=9 where pk=8435;
+update t1 set zone_id=830, modified=9 where pk=8436;
+update t1 set zone_id=830, modified=9 where pk=8437;
+select * from t1 where t1.zone_id=830 AND modified=9;
+pk zone_id modified
+8434 830 9
+8435 830 9
+8436 830 9
+8437 830 9
+begin;
+DELETE t1 FROM t1 WHERE t1.zone_id=830 AND modified=9;
+commit;
+select * from t1 where t1.zone_id=830 AND modified=9;
+pk zone_id modified
+drop table t0, t1;
set optimizer_switch= @optimizer_switch_save;
diff --git a/mysql-test/t/index_merge_innodb.test b/mysql-test/t/index_merge_innodb.test
index ae568c5b5d9..8ca36b14490 100644
--- a/mysql-test/t/index_merge_innodb.test
+++ b/mysql-test/t/index_merge_innodb.test
@@ -125,5 +125,38 @@ WHERE v1 IN ('f', 'd', 'h', 'u' ) AND i = 2;
DROP TABLE t1;
+--echo #
+--echo # BUG#1006164: Multi-table DELETE that uses innodb + index_merge/intersect may fail to delete rows
+--echo #
+
+create table t0(a int);
+insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
+
+create table t1 (
+ pk int auto_increment,
+ zone_id int,
+ modified tinyint,
+ primary key(pk),
+ key (zone_id),
+ key (modified)
+) engine=innodb;
+
+insert into t1 (zone_id, modified) select 0,0 from t0 A, t0 B, t0 C, t0 D;
+update t1 set zone_id=487, modified=9 where pk=7259;
+update t1 set zone_id=487, modified=9 where pk=7260;
+update t1 set zone_id=830, modified=9 where pk=8434;
+update t1 set zone_id=830, modified=9 where pk=8435;
+update t1 set zone_id=830, modified=9 where pk=8436;
+update t1 set zone_id=830, modified=9 where pk=8437;
+
+select * from t1 where t1.zone_id=830 AND modified=9;
+begin;
+DELETE t1 FROM t1 WHERE t1.zone_id=830 AND modified=9;
+commit;
+select * from t1 where t1.zone_id=830 AND modified=9;
+
+drop table t0, t1;
+
+
set optimizer_switch= @optimizer_switch_save;
diff --git a/sql/opt_range.cc b/sql/opt_range.cc
index b449cdae0c7..3cad647ba1c 100644
--- a/sql/opt_range.cc
+++ b/sql/opt_range.cc
@@ -2041,7 +2041,24 @@ end:
doing_key_read= 1;
head->mark_columns_used_by_index(index);
}
+
head->prepare_for_position();
+
+ if (head->no_keyread)
+ {
+ /*
+ We can get here when doing multi-table delete and having index_merge
+ condition on a table that we're deleting from. It probably doesn't make
+ sense to use index_merge, but de-facto it is used.
+
+ When it is used, we need to index columns to be read (before maria-5.3,
+ read_multi_range_first() would set it).
+ We shouldn't call mark_columns_used_by_index(), because it calls
+ enable_keyread(), which is not allowed.
+ */
+ head->mark_columns_used_by_index_no_reset(index, head->read_set);
+ }
+
head->file= org_file;
head->key_read= org_key_read;
bitmap_copy(&column_bitmap, head->read_set);