From ad78c24a20278f072017f3b0e397d01fc0ccec9f Mon Sep 17 00:00:00 2001 From: Sergey Petrunya Date: Wed, 12 Jan 2011 15:00:10 +0300 Subject: [PATCH] BUG#665669: Result differences on query re-execution - Cause: handler::in_range_check_pushed_down was not reset when a command would call handler->idx_cond_push() without later calling handler->index_end(). - Fix: reset the variable in handler->reset(), too (like we do with other Index Condition Pushdown members). --- mysql-test/r/innodb_mrr.result | 21 +++++++++++++++++++++ mysql-test/t/innodb_mrr.test | 15 +++++++++++++++ storage/maria/ha_maria.cc | 1 + storage/myisam/ha_myisam.cc | 1 + storage/xtradb/handler/ha_innodb.cc | 2 ++ 5 files changed, 40 insertions(+) diff --git a/mysql-test/r/innodb_mrr.result b/mysql-test/r/innodb_mrr.result index 76a0e0516b2..be0068571de 100644 --- a/mysql-test/r/innodb_mrr.result +++ b/mysql-test/r/innodb_mrr.result @@ -660,3 +660,24 @@ count(*) sum(table1.col_int_key*table2.pk) drop table t1,t2; set join_cache_level=@my_save_join_cache_level; set join_buffer_size=@my_save_join_buffer_size; +# +# BUG#665669: Result differences on query re-execution +# +create table t1 (pk int primary key, b int, c int default 0, index idx(b)) engine=innodb; +insert into t1(pk,b) values (3, 30), (2, 20), (9, 90), (7, 70), (4, 40), (5, 50), (10, 100), (12, 120); +set @my_save_optimizer_use_mrr=@@optimizer_use_mrr; +set optimizer_use_mrr='disable'; +explain select * from t1 where b > 1000; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 range idx idx 5 NULL 1 Using index condition +# The following two must produce indentical results: +select * from t1 where pk < 2 or pk between 3 and 4; +pk b c +3 30 0 +4 40 0 +select * from t1 where pk < 2 or pk between 3 and 4; +pk b c +3 30 0 +4 40 0 +drop table t1; +set optimizer_use_mrr = @my_save_optimizer_use_mrr; diff --git a/mysql-test/t/innodb_mrr.test b/mysql-test/t/innodb_mrr.test index 70c7c54332e..621f2abc596 100644 --- a/mysql-test/t/innodb_mrr.test +++ b/mysql-test/t/innodb_mrr.test @@ -364,3 +364,18 @@ drop table t1,t2; set join_cache_level=@my_save_join_cache_level; set join_buffer_size=@my_save_join_buffer_size; + +--echo # +--echo # BUG#665669: Result differences on query re-execution +--echo # +create table t1 (pk int primary key, b int, c int default 0, index idx(b)) engine=innodb; +insert into t1(pk,b) values (3, 30), (2, 20), (9, 90), (7, 70), (4, 40), (5, 50), (10, 100), (12, 120); +set @my_save_optimizer_use_mrr=@@optimizer_use_mrr; +set optimizer_use_mrr='disable'; +explain select * from t1 where b > 1000; +--echo # The following two must produce indentical results: +select * from t1 where pk < 2 or pk between 3 and 4; +select * from t1 where pk < 2 or pk between 3 and 4; +drop table t1; +set optimizer_use_mrr = @my_save_optimizer_use_mrr; + diff --git a/storage/maria/ha_maria.cc b/storage/maria/ha_maria.cc index 5ea8f1c9a40..7668caebd1c 100644 --- a/storage/maria/ha_maria.cc +++ b/storage/maria/ha_maria.cc @@ -2456,6 +2456,7 @@ int ha_maria::reset(void) { pushed_idx_cond= NULL; pushed_idx_cond_keyno= MAX_KEY; + in_range_check_pushed_down= FALSE; ma_set_index_cond_func(file, NULL, 0); ds_mrr.dsmrr_close(); if (file->trn) diff --git a/storage/myisam/ha_myisam.cc b/storage/myisam/ha_myisam.cc index 7ba36f3b937..c7dd4f2b943 100644 --- a/storage/myisam/ha_myisam.cc +++ b/storage/myisam/ha_myisam.cc @@ -1929,6 +1929,7 @@ int ha_myisam::reset(void) { pushed_idx_cond= NULL; pushed_idx_cond_keyno= MAX_KEY; + in_range_check_pushed_down= FALSE; mi_set_index_cond_func(file, NULL, 0); ds_mrr.dsmrr_close(); return mi_reset(file); diff --git a/storage/xtradb/handler/ha_innodb.cc b/storage/xtradb/handler/ha_innodb.cc index b630cecf86c..5de16fa3651 100644 --- a/storage/xtradb/handler/ha_innodb.cc +++ b/storage/xtradb/handler/ha_innodb.cc @@ -8865,6 +8865,7 @@ ha_innobase::extra( pushed_idx_cond= FALSE; pushed_idx_cond_keyno= MAX_KEY; prebuilt->idx_cond_func= NULL; + in_range_check_pushed_down= FALSE; break; case HA_EXTRA_NO_KEYREAD: prebuilt->read_just_key = 0; @@ -8915,6 +8916,7 @@ ha_innobase::reset() /* Reset index condition pushdown state */ pushed_idx_cond_keyno= MAX_KEY; pushed_idx_cond= NULL; + in_range_check_pushed_down= FALSE; ds_mrr.dsmrr_close(); prebuilt->idx_cond_func= NULL;