diff --git a/mysql-test/main/opt_context_replay_basic.result b/mysql-test/main/opt_context_replay_basic.result index 34f9b4d6d2271..52be62f1c26fa 100644 --- a/mysql-test/main/opt_context_replay_basic.result +++ b/mysql-test/main/opt_context_replay_basic.result @@ -272,5 +272,28 @@ set optimizer_replay_context='opt_context'; EXPLAIN SELECT MAX(a) FROM t1; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Select tables optimized away +set optimizer_replay_context=''; +drop table t1; +# +# MDEV-39440: replay context doesn't work after altering the index +# +create table t1 (btn char(10) not null, key using HASH (btn)) engine=heap; +insert into t1 values ("a"),("b"),("c"),("d"); +alter table t1 add column new_col char(1) not null, add key using HASH (btn,new_col), drop key btn; +update t1 set new_col=left(btn,1); +set optimizer_record_context=1; +explain select * from t1 where btn="a"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL btn NULL NULL NULL 4 Using where +select context into dumpfile "../../tmp/dump1.sql" +from information_schema.optimizer_context; +set optimizer_record_context=0; +drop table t1; +set optimizer_replay_context='opt_context'; +# Same query as above, must have same explain: +explain select * from t1 where btn="a"; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 ALL btn NULL NULL NULL 4 Using where +set optimizer_replay_context=''; drop table t1; drop database db1; diff --git a/mysql-test/main/opt_context_replay_basic.test b/mysql-test/main/opt_context_replay_basic.test index dcf85929c337b..095c14ae58e51 100644 --- a/mysql-test/main/opt_context_replay_basic.test +++ b/mysql-test/main/opt_context_replay_basic.test @@ -116,6 +116,34 @@ set optimizer_replay_context='opt_context'; --echo # Same query as above, must have same explain: EXPLAIN SELECT MAX(a) FROM t1; +set optimizer_replay_context=''; +--remove_file "$MYSQLTEST_VARDIR/tmp/dump1.sql" +drop table t1; + +--echo # +--echo # MDEV-39440: replay context doesn't work after altering the index +--echo # +create table t1 (btn char(10) not null, key using HASH (btn)) engine=heap; +insert into t1 values ("a"),("b"),("c"),("d"); +alter table t1 add column new_col char(1) not null, add key using HASH (btn,new_col), drop key btn; +update t1 set new_col=left(btn,1); + +set optimizer_record_context=1; +explain select * from t1 where btn="a"; +select context into dumpfile "../../tmp/dump1.sql" +from information_schema.optimizer_context; +set optimizer_record_context=0; +drop table t1; +--disable_query_log +--disable_result_log +--source "$MYSQLTEST_VARDIR/tmp/dump1.sql" +--enable_query_log +--enable_result_log +set optimizer_replay_context='opt_context'; +--echo # Same query as above, must have same explain: +explain select * from t1 where btn="a"; + +set optimizer_replay_context=''; --remove_file "$MYSQLTEST_VARDIR/tmp/dump1.sql" drop table t1; diff --git a/sql/opt_range.cc b/sql/opt_range.cc index cf9e256bd2576..ed900f607b08e 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -12471,6 +12471,13 @@ ha_rows check_quick_select(PARAM *param, uint idx, ha_rows limit, ha_rows replay_ctx_max_index_blocks; ha_rows replay_ctx_max_row_blocks; bool replay_ctx_rc; + Optimizer_context_recorder *rec; + TABLE::OPT_RANGE *range= param->table->opt_range + keynr; + if (range) + { + range->max_index_blocks= 0; + range->max_row_blocks= 0; + } DBUG_ENTER("check_quick_select"); /* Range not calculated yet */ @@ -12534,7 +12541,6 @@ ha_rows check_quick_select(PARAM *param, uint idx, ha_rows limit, param->quick_rows[keynr]= rows; if (rows != HA_POS_ERROR) { - TABLE::OPT_RANGE *range= param->table->opt_range + keynr; ha_rows table_records= param->table->stat_records(); if (rows > table_records) { @@ -12560,15 +12566,6 @@ ha_rows check_quick_select(PARAM *param, uint idx, ha_rows limit, range->max_row_blocks= MY_MIN(file->row_blocks(), rows * file->stats.block_size / IO_SIZE); - if (Optimizer_context_recorder *rec= param->thd->opt_ctx_recorder) - { - Range_print_enumerator_impl range_iter(param, idx, tree); - rec->record_multi_range_read_info_const(param->table->pos_in_table_list, - keynr, &range_iter, rows, cost, - range->max_index_blocks, - range->max_row_blocks); - } - if (update_tbl_stats) { param->table->opt_range_keys.set_bit(keynr); @@ -12597,6 +12594,14 @@ ha_rows check_quick_select(PARAM *param, uint idx, ha_rows limit, } } + if (range && (rec= param->thd->opt_ctx_recorder)) + { + Range_print_enumerator_impl range_iter(param, idx, tree); + rec->record_multi_range_read_info_const( + param->table->pos_in_table_list, keynr, &range_iter, rows, cost, + range->max_index_blocks, range->max_row_blocks); + } + /* Figure out if the key scan is ROR (returns rows in ROWID order) or not */ enum ha_key_alg key_alg= param->table->key_info[seq.real_keyno].algorithm; if ((key_alg != HA_KEY_ALG_BTREE) && (key_alg!= HA_KEY_ALG_UNDEF))