From 3058f4a136a40d829b4f89fbc26f8639608f3437 Mon Sep 17 00:00:00 2001 From: Ramil Kalimullin Date: Wed, 9 Jun 2010 14:45:04 +0400 Subject: Fix for bug #54007: assert in ha_myisam::index_next, HANDLER Problem: the server missed the fact that one can read from 2 indexes alternately using HANDLER interface. Fix: check if the same (initialized) index is involved reading next/prev values from the index. --- mysql-test/r/handler_myisam.result | 93 ++++++++++++++++++++++++++++++++++++++ mysql-test/t/handler_myisam.test | 49 ++++++++++++++++++++ sql/sql_handler.cc | 23 ++++++++-- 3 files changed, 162 insertions(+), 3 deletions(-) diff --git a/mysql-test/r/handler_myisam.result b/mysql-test/r/handler_myisam.result index a970e20a2c0..b20b8dbb138 100644 --- a/mysql-test/r/handler_myisam.result +++ b/mysql-test/r/handler_myisam.result @@ -769,4 +769,97 @@ a 1 HANDLER t1 CLOSE; DROP TABLE t1; +# +# Bug #54007: assert in ha_myisam::index_next , HANDLER +# +CREATE TABLE t1(a INT, b INT, PRIMARY KEY(a), KEY b(b), KEY ab(a, b)); +HANDLER t1 OPEN; +HANDLER t1 READ FIRST; +a b +HANDLER t1 READ `PRIMARY` NEXT; +a b +HANDLER t1 READ ab NEXT; +a b +HANDLER t1 READ b NEXT; +a b +HANDLER t1 READ NEXT; +a b +HANDLER t1 CLOSE; +INSERT INTO t1 VALUES (2, 20), (1, 10), (4, 40), (3, 30); +HANDLER t1 OPEN; +HANDLER t1 READ FIRST; +a b +2 20 +HANDLER t1 READ NEXT; +a b +1 10 +HANDLER t1 READ `PRIMARY` NEXT; +a b +1 10 +HANDLER t1 READ `PRIMARY` NEXT; +a b +2 20 +HANDLER t1 READ ab NEXT; +a b +1 10 +HANDLER t1 READ ab NEXT; +a b +2 20 +HANDLER t1 READ b NEXT; +a b +1 10 +HANDLER t1 READ b NEXT; +a b +2 20 +HANDLER t1 READ b NEXT; +a b +3 30 +HANDLER t1 READ b NEXT; +a b +4 40 +HANDLER t1 READ b NEXT; +a b +HANDLER t1 READ NEXT; +a b +4 40 +HANDLER t1 READ NEXT; +a b +3 30 +HANDLER t1 READ NEXT; +a b +HANDLER t1 CLOSE; +HANDLER t1 OPEN; +HANDLER t1 READ FIRST; +a b +2 20 +HANDLER t1 READ `PRIMARY` PREV; +a b +4 40 +HANDLER t1 READ `PRIMARY` PREV; +a b +3 30 +HANDLER t1 READ b PREV; +a b +4 40 +HANDLER t1 READ b PREV; +a b +3 30 +HANDLER t1 CLOSE; +HANDLER t1 OPEN; +HANDLER t1 READ FIRST; +a b +2 20 +HANDLER t1 READ `PRIMARY` PREV LIMIT 3; +a b +4 40 +3 30 +2 20 +HANDLER t1 READ b NEXT LIMIT 5; +a b +1 10 +2 20 +3 30 +4 40 +HANDLER t1 CLOSE; +DROP TABLE t1; End of 5.1 tests diff --git a/mysql-test/t/handler_myisam.test b/mysql-test/t/handler_myisam.test index 868ba14480a..e78072ef8a0 100644 --- a/mysql-test/t/handler_myisam.test +++ b/mysql-test/t/handler_myisam.test @@ -48,4 +48,53 @@ HANDLER t1 READ a NEXT; HANDLER t1 CLOSE; DROP TABLE t1; + +--echo # +--echo # Bug #54007: assert in ha_myisam::index_next , HANDLER +--echo # +CREATE TABLE t1(a INT, b INT, PRIMARY KEY(a), KEY b(b), KEY ab(a, b)); + +HANDLER t1 OPEN; +HANDLER t1 READ FIRST; +HANDLER t1 READ `PRIMARY` NEXT; +HANDLER t1 READ ab NEXT; +HANDLER t1 READ b NEXT; +HANDLER t1 READ NEXT; +HANDLER t1 CLOSE; + +INSERT INTO t1 VALUES (2, 20), (1, 10), (4, 40), (3, 30); +HANDLER t1 OPEN; +HANDLER t1 READ FIRST; +HANDLER t1 READ NEXT; +HANDLER t1 READ `PRIMARY` NEXT; +HANDLER t1 READ `PRIMARY` NEXT; +HANDLER t1 READ ab NEXT; +HANDLER t1 READ ab NEXT; +HANDLER t1 READ b NEXT; +HANDLER t1 READ b NEXT; +HANDLER t1 READ b NEXT; +HANDLER t1 READ b NEXT; +HANDLER t1 READ b NEXT; +HANDLER t1 READ NEXT; +HANDLER t1 READ NEXT; +HANDLER t1 READ NEXT; +HANDLER t1 CLOSE; + +HANDLER t1 OPEN; +HANDLER t1 READ FIRST; +HANDLER t1 READ `PRIMARY` PREV; +HANDLER t1 READ `PRIMARY` PREV; +HANDLER t1 READ b PREV; +HANDLER t1 READ b PREV; +HANDLER t1 CLOSE; + +HANDLER t1 OPEN; +HANDLER t1 READ FIRST; +HANDLER t1 READ `PRIMARY` PREV LIMIT 3; +HANDLER t1 READ b NEXT LIMIT 5; +HANDLER t1 CLOSE; + +DROP TABLE t1; + + --echo End of 5.1 tests diff --git a/sql/sql_handler.cc b/sql/sql_handler.cc index 3bbf4b78d07..bbc3d0b27a4 100644 --- a/sql/sql_handler.cc +++ b/sql/sql_handler.cc @@ -539,6 +539,14 @@ retry: my_error(ER_KEY_DOES_NOT_EXITS, MYF(0), keyname, tables->alias); goto err; } + /* Check if the same index involved. */ + if ((uint) keyno != table->file->get_index()) + { + if (mode == RNEXT) + mode= RFIRST; + else if (mode == RPREV) + mode= RLAST; + } } if (insert_fields(thd, &thd->lex->select_lex.context, @@ -561,9 +569,16 @@ retry: case RNEXT: if (table->file->inited != handler::NONE) { - error=keyname ? - table->file->index_next(table->record[0]) : - table->file->rnd_next(table->record[0]); + if (keyname) + { + /* Check if we read from the same index. */ + DBUG_ASSERT((uint) keyno == table->file->get_index()); + error= table->file->index_next(table->record[0]); + } + else + { + error= table->file->rnd_next(table->record[0]); + } break; } /* else fall through */ @@ -584,6 +599,8 @@ retry: break; case RPREV: DBUG_ASSERT(keyname != 0); + /* Check if we read from the same index. */ + DBUG_ASSERT((uint) keyno == table->file->get_index()); if (table->file->inited != handler::NONE) { error=table->file->index_prev(table->record[0]); -- cgit v1.2.1