diff --git a/mysql-test/r/innodb_handler.result b/mysql-test/r/innodb_handler.result index 7f4960ffa35..7e853a55e37 100644 --- a/mysql-test/r/innodb_handler.result +++ b/mysql-test/r/innodb_handler.result @@ -132,6 +132,22 @@ a b handler t2 read last; ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 1 handler t2 close; +handler t1 open; +handler t1 read a next; +a b +14 aaa +handler t1 read a next; +a b +15 bbb +handler t1 close; +handler t1 open; +handler t1 read a prev; +a b +22 iii +handler t1 read a prev; +a b +21 hhh +handler t1 close; handler t1 open as t2; handler t2 read first; a b diff --git a/mysql-test/t/innodb_handler.test b/mysql-test/t/innodb_handler.test index e8c486caf66..65728519e7b 100644 --- a/mysql-test/t/innodb_handler.test +++ b/mysql-test/t/innodb_handler.test @@ -69,6 +69,16 @@ handler t2 read next; handler t2 read last; handler t2 close; +handler t1 open; +handler t1 read a next; # this used to crash as a bug#5373 +handler t1 read a next; +handler t1 close; + +handler t1 open; +handler t1 read a prev; # this used to crash as a bug#5373 +handler t1 read a prev; +handler t1 close; + handler t1 open as t2; handler t2 read first; alter table t1 engine=innodb; diff --git a/sql/sql_handler.cc b/sql/sql_handler.cc index aa791276404..491b82c1c1d 100644 --- a/sql/sql_handler.cc +++ b/sql/sql_handler.cc @@ -429,12 +429,10 @@ int mysql_ha_read(THD *thd, TABLE_LIST *tables, } tables->table=table; - if (cond && ((!cond->fixed && + if (cond && ((!cond->fixed && cond->fix_fields(thd, tables, &cond)) || cond->check_cols(1))) goto err0; - table->file->init_table_handle_for_HANDLER(); // Only InnoDB requires it - if (keyname) { if ((keyno=find_type(keyname, &table->keynames, 1+2)-1)<0) @@ -443,8 +441,6 @@ int mysql_ha_read(THD *thd, TABLE_LIST *tables, keyname,tables->alias); goto err0; } - table->file->ha_index_or_rnd_end(); - table->file->ha_index_init(keyno); } if (insert_fields(thd,tables,tables->db,tables->alias,&it)) @@ -471,9 +467,22 @@ int mysql_ha_read(THD *thd, TABLE_LIST *tables, for (num_rows=0; num_rows < select_limit; ) { switch (mode) { + case RNEXT: + if (table->file->inited != handler::NONE) + { + err=keyname ? + table->file->index_next(table->record[0]) : + table->file->rnd_next(table->record[0]); + break; + } + /* else fall through */ case RFIRST: if (keyname) + { + table->file->ha_index_or_rnd_end(); + table->file->ha_index_init(keyno); err=table->file->index_first(table->record[0]); + } else { table->file->ha_index_or_rnd_end(); @@ -482,19 +491,20 @@ int mysql_ha_read(THD *thd, TABLE_LIST *tables, } mode=RNEXT; break; - case RLAST: - DBUG_ASSERT(keyname != 0); - err=table->file->index_last(table->record[0]); - mode=RPREV; - break; - case RNEXT: - err=keyname ? - table->file->index_next(table->record[0]) : - table->file->rnd_next(table->record[0]); - break; case RPREV: DBUG_ASSERT(keyname != 0); - err=table->file->index_prev(table->record[0]); + if (table->file->inited != handler::NONE) + { + err=table->file->index_prev(table->record[0]); + break; + } + /* else fall through */ + case RLAST: + DBUG_ASSERT(keyname != 0); + table->file->ha_index_or_rnd_end(); + table->file->ha_index_init(keyno); + err=table->file->index_last(table->record[0]); + mode=RPREV; break; case RNEXT_SAME: /* Continue scan on "(keypart1,keypart2,...)=(c1, c2, ...) */ @@ -517,7 +527,7 @@ int mysql_ha_read(THD *thd, TABLE_LIST *tables, for (key_len=0 ; (item=it_ke++) ; key_part++) { // 'item' can be changed by fix_fields() call - if ((!item->fixed && + if ((!item->fixed && item->fix_fields(thd, tables, it_ke.ref())) || (item= *it_ke.ref())->check_cols(1)) goto err; @@ -535,6 +545,8 @@ int mysql_ha_read(THD *thd, TABLE_LIST *tables, goto err; } key_copy(key, table, keyno, key_len); + table->file->ha_index_or_rnd_end(); + table->file->ha_index_init(keyno); err=table->file->index_read(table->record[0], key,key_len,ha_rkey_mode); mode=rkey_to_rnext[(int)ha_rkey_mode];