diff options
author | Sergey Petrunya <psergey@askmonty.org> | 2012-06-02 16:13:05 +0400 |
---|---|---|
committer | Sergey Petrunya <psergey@askmonty.org> | 2012-06-02 16:13:05 +0400 |
commit | 25ada13db06d06050f0361bc434fe2b58303b5f2 (patch) | |
tree | fbfd3c789aab53ed73965c9d14a50c6c24f5cc7a | |
parent | 4d8d7912788747762031508e0c787313a9d1a0a2 (diff) | |
parent | c17216eed83f6fa790dc5a4f8c040bcd428b6374 (diff) | |
download | mariadb-git-25ada13db06d06050f0361bc434fe2b58303b5f2.tar.gz |
Merge
-rw-r--r-- | mysql-test/r/index_merge_innodb.result | 32 | ||||
-rw-r--r-- | mysql-test/t/index_merge_innodb.test | 33 | ||||
-rw-r--r-- | sql/opt_range.cc | 17 |
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); |