diff options
author | Annamalai Gurusami <annamalai.gurusami@oracle.com> | 2012-10-08 19:40:30 +0530 |
---|---|---|
committer | Annamalai Gurusami <annamalai.gurusami@oracle.com> | 2012-10-08 19:40:30 +0530 |
commit | bd7c9815cee8f9bcf6ebd7d87cce6ee045732e42 (patch) | |
tree | f4b66e0e1aa0556afbaf7190a833dc54c0792585 | |
parent | 5d9e863faf9867bc4639af77e73767ac856fe3ed (diff) | |
download | mariadb-git-bd7c9815cee8f9bcf6ebd7d87cce6ee045732e42.tar.gz |
Bug #14036214 MYSQLD CRASHES WHEN EXECUTING UPDATE IN TRX WITH
CONSISTENT SNAPSHOT OPTION
A transaction is started with a consistent snapshot. After
the transaction is started new indexes are added to the
table. Now when we issue an update statement, the optimizer
chooses an index. When the index scan is being initialized
via ha_innobase::change_active_index(), InnoDB reports
the error code HA_ERR_TABLE_DEF_CHANGED, with message
stating that "insufficient history for index".
This error message is propagated up to the SQL layer. But
the my_error() api is never called. The statement level
diagnostics area is not updated with the correct error
status (it remains in Diagnostics_area::DA_EMPTY).
Hence the following check in the Protocol::end_statement()
fails.
516 case Diagnostics_area::DA_EMPTY:
517 default:
518 DBUG_ASSERT(0);
519 error= send_ok(thd->server_status, 0, 0, 0, NULL);
520 break;
The fix is to backport the fix of bugs 14365043, 11761652
and 11746399.
14365043 PROTOCOL::END_STATEMENT(): ASSERTION `0' FAILED
11761652 HA_RND_INIT() RESULT CODE NOT CHECKED
11746399 RETURN VALUES OF HA_INDEX_INIT() AND INDEX_INIT() IGNORED
rb://1227 approved by guilhem and mattiasj.
-rw-r--r-- | mysql-test/suite/innodb/r/innodb_corrupt_bit.result | 8 | ||||
-rw-r--r-- | mysql-test/suite/innodb/t/innodb_corrupt_bit.test | 6 | ||||
-rw-r--r-- | sql/event_db_repository.cc | 10 | ||||
-rw-r--r-- | sql/filesort.cc | 8 | ||||
-rw-r--r-- | sql/handler.cc | 47 | ||||
-rw-r--r-- | sql/handler.h | 2 | ||||
-rw-r--r-- | sql/item_subselect.cc | 31 | ||||
-rw-r--r-- | sql/log_event.cc | 12 | ||||
-rw-r--r-- | sql/log_event_old.cc | 36 | ||||
-rw-r--r-- | sql/opt_range.cc | 32 | ||||
-rw-r--r-- | sql/opt_sum.cc | 9 | ||||
-rw-r--r-- | sql/records.cc | 10 | ||||
-rw-r--r-- | sql/sp.cc | 17 | ||||
-rw-r--r-- | sql/sql_acl.cc | 38 | ||||
-rw-r--r-- | sql/sql_handler.cc | 25 | ||||
-rw-r--r-- | sql/sql_help.cc | 10 | ||||
-rw-r--r-- | sql/sql_select.cc | 68 | ||||
-rw-r--r-- | sql/sql_show.cc | 12 | ||||
-rw-r--r-- | sql/sql_update.cc | 14 | ||||
-rw-r--r-- | sql/tztime.cc | 32 | ||||
-rw-r--r-- | storage/innobase/handler/ha_innodb.cc | 4 |
21 files changed, 313 insertions, 118 deletions
diff --git a/mysql-test/suite/innodb/r/innodb_corrupt_bit.result b/mysql-test/suite/innodb/r/innodb_corrupt_bit.result index c88e1ed2504..7e8792bb5b4 100644 --- a/mysql-test/suite/innodb/r/innodb_corrupt_bit.result +++ b/mysql-test/suite/innodb/r/innodb_corrupt_bit.result @@ -40,13 +40,13 @@ test.corrupt_bit_test_ā check Warning InnoDB: The B-tree of index "idxā" is co test.corrupt_bit_test_ā check Warning InnoDB: The B-tree of index "idxē" is corrupted. test.corrupt_bit_test_ā check error Corrupt select c from corrupt_bit_test_ā; -ERROR HY000: Incorrect key file for table 'corrupt_bit_test_ā'; try to repair it +ERROR HY000: Index corrupt_bit_test_ā is corrupted select z from corrupt_bit_test_ā; -ERROR HY000: Incorrect key file for table 'corrupt_bit_test_ā'; try to repair it +ERROR HY000: Index corrupt_bit_test_ā is corrupted show warnings; Level Code Message Warning 179 InnoDB: Index "idxē" for table "test"."corrupt_bit_test_ā" is marked as corrupted -Error 1034 Incorrect key file for table 'corrupt_bit_test_ā'; try to repair it +Error 1712 Index corrupt_bit_test_ā is corrupted insert into corrupt_bit_test_ā values (10001, "a", 20001, 20001); select * from corrupt_bit_test_ā use index(primary) where a = 10001; a b c z @@ -63,7 +63,7 @@ test.corrupt_bit_test_ā check Warning InnoDB: Index "idxē" is marked as corrup test.corrupt_bit_test_ā check error Corrupt set names utf8; select z from corrupt_bit_test_ā; -ERROR HY000: Incorrect key file for table 'corrupt_bit_test_ā'; try to repair it +ERROR HY000: Index corrupt_bit_test_ā is corrupted drop index idxē on corrupt_bit_test_ā; select z from corrupt_bit_test_ā limit 10; z diff --git a/mysql-test/suite/innodb/t/innodb_corrupt_bit.test b/mysql-test/suite/innodb/t/innodb_corrupt_bit.test index 7c4ea00afec..b8d19ddfcee 100644 --- a/mysql-test/suite/innodb/t/innodb_corrupt_bit.test +++ b/mysql-test/suite/innodb/t/innodb_corrupt_bit.test @@ -79,10 +79,10 @@ CREATE INDEX idx4 ON corrupt_bit_test_ā(b, z); check table corrupt_bit_test_ā; # This selection intend to use the corrupted index. Expect to fail --- error ER_NOT_KEYFILE +-- error ER_INDEX_CORRUPT select c from corrupt_bit_test_ā; --- error ER_NOT_KEYFILE +-- error ER_INDEX_CORRUPT select z from corrupt_bit_test_ā; show warnings; @@ -108,7 +108,7 @@ check table corrupt_bit_test_ā; set names utf8; --- error ER_NOT_KEYFILE +-- error ER_INDEX_CORRUPT select z from corrupt_bit_test_ā; # Drop the corrupted index diff --git a/sql/event_db_repository.cc b/sql/event_db_repository.cc index 59d168e01b5..74da4d8f587 100644 --- a/sql/event_db_repository.cc +++ b/sql/event_db_repository.cc @@ -406,7 +406,6 @@ Event_db_repository::index_read_for_db_for_i_s(THD *thd, TABLE *schema_table, TABLE *event_table, const char *db) { - int ret=0; CHARSET_INFO *scs= system_charset_info; KEY *key_info; uint key_len; @@ -416,7 +415,14 @@ Event_db_repository::index_read_for_db_for_i_s(THD *thd, TABLE *schema_table, DBUG_ENTER("Event_db_repository::index_read_for_db_for_i_s"); DBUG_PRINT("info", ("Using prefix scanning on PK")); - event_table->file->ha_index_init(0, 1); + + int ret= event_table->file->ha_index_init(0, 1); + if (ret) + { + event_table->file->print_error(ret, MYF(0)); + DBUG_RETURN(true); + } + key_info= event_table->key_info; if (key_info->key_parts == 0 || diff --git a/sql/filesort.cc b/sql/filesort.cc index a11be501991..b64f5221606 100644 --- a/sql/filesort.cc +++ b/sql/filesort.cc @@ -567,7 +567,13 @@ static ha_rows find_all_keys(SORTPARAM *param, SQL_SELECT *select, if (!quick_select) { next_pos=(uchar*) 0; /* Find records in sequence */ - file->ha_rnd_init(1); + DBUG_EXECUTE_IF("bug14365043_1", + DBUG_SET("+d,ha_rnd_init_fail");); + if ((error= file->ha_rnd_init(1))) + { + file->print_error(error, MYF(0)); + DBUG_RETURN(HA_POS_ERROR); + } file->extra_opt(HA_EXTRA_CACHE, current_thd->variables.read_buff_size); } diff --git a/sql/handler.cc b/sql/handler.cc index 27309a4b1d7..f4eb89912e9 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -2291,16 +2291,25 @@ int handler::read_first_row(uchar * buf, uint primary_key) if (stats.deleted < 10 || primary_key >= MAX_KEY || !(index_flags(primary_key, 0, 0) & HA_READ_ORDER)) { - (void) ha_rnd_init(1); - while ((error= rnd_next(buf)) == HA_ERR_RECORD_DELETED) ; - (void) ha_rnd_end(); + if (!(error= ha_rnd_init(1))) + { + while ((error= rnd_next(buf)) == HA_ERR_RECORD_DELETED) + /* skip deleted row */; + const int end_error= ha_rnd_end(); + if (!error) + error= end_error; + } } else { /* Find the first row through the primary key */ - (void) ha_index_init(primary_key, 0); - error=index_first(buf); - (void) ha_index_end(); + if (!(error= ha_index_init(primary_key, 0))) + { + error= index_first(buf); + const int end_error= ha_index_end(); + if (!error) + error= end_error; + } } DBUG_RETURN(error); } @@ -2695,7 +2704,15 @@ void handler::get_auto_increment(ulonglong offset, ulonglong increment, table->mark_columns_used_by_index_no_reset(table->s->next_number_index, table->read_set); column_bitmaps_signal(); - index_init(table->s->next_number_index, 1); + + if (ha_index_init(table->s->next_number_index, 1)) + { + /* This should never happen, assert in debug, and fail in release build */ + DBUG_ASSERT(0); + *first_value= ULONGLONG_MAX; + return; + } + if (table->s->next_number_keypart == 0) { // Autoincrement at key-start error=index_last(table->record[1]); @@ -2725,13 +2742,25 @@ void handler::get_auto_increment(ulonglong offset, ulonglong increment, } if (error) - nr=1; + { + if (error == HA_ERR_END_OF_FILE || error == HA_ERR_KEY_NOT_FOUND) + { + /* No entry found, start with 1. */ + nr= 1; + } + else + { + DBUG_ASSERT(0); + nr= ULONGLONG_MAX; + } + } else nr= ((ulonglong) table->next_number_field-> val_int_offset(table->s->rec_buff_length)+1); - index_end(); + ha_index_end(); (void) extra(HA_EXTRA_NO_KEYREAD); *first_value= nr; + return; } diff --git a/sql/handler.h b/sql/handler.h index 0b970a1349d..5eb2d6b440a 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -1351,6 +1351,7 @@ public: int ha_open(TABLE *table, const char *name, int mode, int test_if_locked); int ha_index_init(uint idx, bool sorted) { + DBUG_EXECUTE_IF("ha_index_init_fail", return HA_ERR_TABLE_DEF_CHANGED;); int result; DBUG_ENTER("ha_index_init"); DBUG_ASSERT(inited==NONE); @@ -1367,6 +1368,7 @@ public: } int ha_rnd_init(bool scan) { + DBUG_EXECUTE_IF("ha_rnd_init_fail", return HA_ERR_TABLE_DEF_CHANGED;); int result; DBUG_ENTER("ha_rnd_init"); DBUG_ASSERT(inited==NONE || (inited==RND && scan)); diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index bc81e5b01c1..d3b06f5983a 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -2058,10 +2058,14 @@ int subselect_uniquesubquery_engine::scan_table() TABLE *table= tab->table; DBUG_ENTER("subselect_uniquesubquery_engine::scan_table"); - if (table->file->inited) - table->file->ha_index_end(); - - table->file->ha_rnd_init(1); + if ((table->file->inited && + (error= table->file->ha_index_end())) || + (error= table->file->ha_rnd_init(1))) + { + (void) report_error(table, error); + DBUG_RETURN(true); + } + table->file->extra_opt(HA_EXTRA_CACHE, current_thd->variables.read_buff_size); table->null_row= 0; @@ -2238,9 +2242,14 @@ int subselect_uniquesubquery_engine::exec() if (null_keypart) DBUG_RETURN(scan_table()); - - if (!table->file->inited) - table->file->ha_index_init(tab->ref.key, 0); + + if (!table->file->inited && + (error= table->file->ha_index_init(tab->ref.key, 0))) + { + (void) report_error(table, error); + DBUG_RETURN(true); + } + error= table->file->index_read_map(table->record[0], tab->ref.key_buff, make_prev_keypart_map(tab->ref.key_parts), @@ -2360,8 +2369,12 @@ int subselect_indexsubquery_engine::exec() if (null_keypart) DBUG_RETURN(scan_table()); - if (!table->file->inited) - table->file->ha_index_init(tab->ref.key, 1); + if (!table->file->inited && + (error= table->file->ha_index_init(tab->ref.key, 1))) + { + (void) report_error(table, error); + DBUG_RETURN(true); + } error= table->file->index_read_map(table->record[0], tab->ref.key_buff, make_prev_keypart_map(tab->ref.key_parts), diff --git a/sql/log_event.cc b/sql/log_event.cc index c4a6ebb9a71..a31e5f71c37 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -9777,19 +9777,25 @@ int Rows_log_event::find_row(const Relay_log_info *rli) case HA_ERR_END_OF_FILE: if (++restart_count < 2) - table->file->ha_rnd_init(1); + { + if ((error= table->file->ha_rnd_init(1))) + { + table->file->print_error(error, MYF(0)); + goto err; + } + } break; default: DBUG_PRINT("info", ("Failed to get next record" " (rnd_next returns %d)",error)); table->file->print_error(error, MYF(0)); - table->file->ha_rnd_end(); + (void) table->file->ha_rnd_end(); goto err; } } while (restart_count < 2 && record_compare(table)); - + /* Note: above record_compare will take into accout all record fields which might be incorrect in case a partial row was given in the event diff --git a/sql/log_event_old.cc b/sql/log_event_old.cc index d68c474d00a..55d8d72ec5d 100644 --- a/sql/log_event_old.cc +++ b/sql/log_event_old.cc @@ -725,7 +725,10 @@ static int find_and_fetch_row(TABLE *table, uchar *key) int error; /* We have a key: search the table using the index */ if (!table->file->inited && (error= table->file->ha_index_init(0, FALSE))) + { + table->file->print_error(error, MYF(0)); DBUG_RETURN(error); + } /* Don't print debug messages when running valgrind since they can @@ -823,7 +826,10 @@ static int find_and_fetch_row(TABLE *table, uchar *key) /* We don't have a key: search the table using rnd_next() */ if ((error= table->file->ha_rnd_init(1))) - return error; + { + table->file->print_error(error, MYF(0)); + DBUG_RETURN(error); + } /* Continue until we find the right record or have made a full loop */ do @@ -846,15 +852,21 @@ static int find_and_fetch_row(TABLE *table, uchar *key) goto restart_rnd_next; case HA_ERR_END_OF_FILE: - if (++restart_count < 2) - table->file->ha_rnd_init(1); - break; + if (++restart_count < 2) + { + if ((error= table->file->ha_rnd_init(1))) + { + table->file->print_error(error, MYF(0)); + DBUG_RETURN(error); + } + } + break; default: - table->file->print_error(error, MYF(0)); + table->file->print_error(error, MYF(0)); DBUG_PRINT("info", ("Record not found")); - table->file->ha_rnd_end(); - DBUG_RETURN(error); + (void) table->file->ha_rnd_end(); + DBUG_RETURN(error); } } while (restart_count < 2 && record_compare(table)); @@ -2417,7 +2429,7 @@ int Old_rows_log_event::find_row(const Relay_log_info *rli) continue; DBUG_PRINT("info",("no record matching the given row found")); table->file->print_error(error, MYF(0)); - table->file->ha_index_end(); + (void) table->file->ha_index_end(); DBUG_RETURN(error); } } @@ -2458,7 +2470,13 @@ int Old_rows_log_event::find_row(const Relay_log_info *rli) case HA_ERR_END_OF_FILE: if (++restart_count < 2) - table->file->ha_rnd_init(1); + { + if ((error= table->file->ha_rnd_init(1))) + { + table->file->print_error(error, MYF(0)); + DBUG_RETURN(error); + } + } break; default: diff --git a/sql/opt_range.cc b/sql/opt_range.cc index ce48a8da958..ffd66253eaa 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -1183,7 +1183,7 @@ int QUICK_RANGE_SELECT::init() { DBUG_ENTER("QUICK_RANGE_SELECT::init"); - if (file->inited != handler::NONE) + if (file->inited) file->ha_index_or_rnd_end(); DBUG_RETURN(FALSE); } @@ -1191,7 +1191,7 @@ int QUICK_RANGE_SELECT::init() void QUICK_RANGE_SELECT::range_end() { - if (file->inited != handler::NONE) + if (file->inited) file->ha_index_or_rnd_end(); } @@ -1450,8 +1450,9 @@ int QUICK_ROR_INTERSECT_SELECT::init_ror_merged_scan(bool reuse_handler) There is no use of this->file. Use it for the first of merged range selects. */ - if (quick->init_ror_merged_scan(TRUE)) - DBUG_RETURN(1); + int error= quick->init_ror_merged_scan(TRUE); + if (error) + DBUG_RETURN(error); quick->file->extra(HA_EXTRA_KEYREAD_PRESERVE_FIELDS); } while ((quick= quick_it++)) @@ -1522,7 +1523,7 @@ QUICK_ROR_INTERSECT_SELECT::~QUICK_ROR_INTERSECT_SELECT() quick_selects.delete_elements(); delete cpk_quick; free_root(&alloc,MYF(0)); - if (need_to_fetch_row && head->file->inited != handler::NONE) + if (need_to_fetch_row && head->file->inited) head->file->ha_rnd_end(); DBUG_VOID_RETURN; } @@ -1626,8 +1627,8 @@ int QUICK_ROR_UNION_SELECT::reset() List_iterator_fast<QUICK_SELECT_I> it(quick_selects); while ((quick= it++)) { - if (quick->reset()) - DBUG_RETURN(1); + if ((error= quick->reset())) + DBUG_RETURN(error); if ((error= quick->get_next())) { if (error == HA_ERR_END_OF_FILE) @@ -1638,10 +1639,10 @@ int QUICK_ROR_UNION_SELECT::reset() queue_insert(&queue, (uchar*)quick); } - if (head->file->ha_rnd_init(1)) + if ((error= head->file->ha_rnd_init(1))) { DBUG_PRINT("error", ("ROR index_merge rnd_init call failed")); - DBUG_RETURN(1); + DBUG_RETURN(error); } DBUG_RETURN(0); @@ -1659,7 +1660,7 @@ QUICK_ROR_UNION_SELECT::~QUICK_ROR_UNION_SELECT() DBUG_ENTER("QUICK_ROR_UNION_SELECT::~QUICK_ROR_UNION_SELECT"); delete_queue(&queue); quick_selects.delete_elements(); - if (head->file->inited != handler::NONE) + if (head->file->inited) head->file->ha_rnd_end(); free_root(&alloc,MYF(0)); DBUG_VOID_RETURN; @@ -8316,7 +8317,7 @@ int QUICK_INDEX_MERGE_SELECT::read_keys_and_merge() if (!cur_quick) break; - if (cur_quick->file->inited != handler::NONE) + if (cur_quick->file->inited) cur_quick->file->ha_index_end(); if (cur_quick->init() || cur_quick->reset()) DBUG_RETURN(1); @@ -8568,8 +8569,14 @@ int QUICK_RANGE_SELECT::reset() { if (in_ror_merged_scan) head->column_bitmaps_set_no_signal(&column_bitmap, &column_bitmap); + + DBUG_EXECUTE_IF("bug14365043_2", + DBUG_SET("+d,ha_index_init_fail");); if ((error= file->ha_index_init(index,1))) + { + file->print_error(error, MYF(0)); DBUG_RETURN(error); + } } /* Do not allocate the buffers twice. */ @@ -10783,7 +10790,10 @@ int QUICK_GROUP_MIN_MAX_SELECT::reset(void) head->set_keyread(TRUE); /* We need only the key attributes */ if ((result= file->ha_index_init(index,1))) + { + head->file->print_error(result, MYF(0)); DBUG_RETURN(result); + } if (quick_prefix_select && quick_prefix_select->reset()) DBUG_RETURN(1); result= file->index_last(record); diff --git a/sql/opt_sum.cc b/sql/opt_sum.cc index e187cf19917..aaf279395dc 100644 --- a/sql/opt_sum.cc +++ b/sql/opt_sum.cc @@ -380,9 +380,14 @@ int opt_sum_query(THD *thd, const_result= 0; break; } - table->file->ha_index_init((uint) ref.key, 1); + if ((error= table->file->ha_index_init((uint) ref.key, 1))) + { + table->file->print_error(error, MYF(0)); + table->set_keyread(FALSE); + DBUG_RETURN(error); + } - error= is_max ? + error= is_max ? get_index_max_value(table, &ref, range_fl) : get_index_min_value(table, &ref, item_field, range_fl, prefix_len); diff --git a/sql/records.cc b/sql/records.cc index 55859e05f29..7f74b84b2d7 100644 --- a/sql/records.cc +++ b/sql/records.cc @@ -67,6 +67,7 @@ static int rr_index_desc(READ_RECORD *info); void init_read_record_idx(READ_RECORD *info, THD *thd, TABLE *table, bool print_error, uint idx, bool reverse) { + int error; empty_record(table); bzero((char*) info,sizeof(*info)); info->thd= thd; @@ -77,8 +78,13 @@ void init_read_record_idx(READ_RECORD *info, THD *thd, TABLE *table, info->unlock_row= rr_unlock_row; table->status=0; /* And it's always found */ - if (!table->file->inited) - table->file->ha_index_init(idx, 1); + if (!table->file->inited && + (error= table->file->ha_index_init(idx, 1))) + { + if (print_error) + table->file->print_error(error, MYF(0)); + } + /* read_record will be changed to rr_index in rr_index_first */ info->read_record= reverse ? rr_index_last : rr_index_first; } diff --git a/sql/sp.cc b/sql/sp.cc index b257e23c8c7..6300329398d 100644 --- a/sql/sp.cc +++ b/sql/sp.cc @@ -1442,7 +1442,6 @@ bool lock_db_routines(THD *thd, char *db) { TABLE *table; uint key_len; - int nxtres= 0; Open_tables_backup open_tables_state_backup; MDL_request_list mdl_requests; Lock_db_routines_error_handler err_handler; @@ -1468,7 +1467,13 @@ bool lock_db_routines(THD *thd, char *db) table->field[MYSQL_PROC_FIELD_DB]->store(db, strlen(db), system_charset_info); key_len= table->key_info->key_part[0].store_length; - table->file->ha_index_init(0, 1); + int nxtres= table->file->ha_index_init(0, 1); + if (nxtres) + { + table->file->print_error(nxtres, MYF(0)); + close_system_tables(thd, &open_tables_state_backup); + DBUG_RETURN(true); + } if (! table->file->index_read_map(table->record[0], table->field[MYSQL_PROC_FIELD_DB]->ptr, @@ -1532,7 +1537,12 @@ sp_drop_db_routines(THD *thd, char *db) key_len= table->key_info->key_part[0].store_length; ret= SP_OK; - table->file->ha_index_init(0, 1); + if (table->file->ha_index_init(0, 1)) + { + ret= SP_KEY_NOT_FOUND; + goto err_idx_init; + } + if (! table->file->index_read_map(table->record[0], (uchar *)table->field[MYSQL_PROC_FIELD_DB]->ptr, (key_part_map)1, HA_READ_KEY_EXACT)) @@ -1560,6 +1570,7 @@ sp_drop_db_routines(THD *thd, char *db) } table->file->ha_index_end(); +err_idx_init: close_thread_tables(thd); /* Make sure to only release the MDL lock on mysql.proc, not other diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 201335f16b5..5c4a144247f 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -2659,7 +2659,13 @@ replace_proxies_priv_table(THD *thd, TABLE *table, const LEX_USER *user, get_grantor(thd, grantor); - table->file->ha_index_init(0, 1); + if ((error= table->file->ha_index_init(0, 1))) + { + table->file->print_error(error, MYF(0)); + DBUG_PRINT("info", ("ha_index_init error")); + DBUG_RETURN(-1); + } + if (table->file->index_read_map(table->record[0], user_key, HA_WHOLE_KEY, HA_READ_KEY_EXACT)) @@ -2901,7 +2907,12 @@ GRANT_TABLE::GRANT_TABLE(TABLE *form, TABLE *col_privs) key_copy(key, col_privs->record[0], col_privs->key_info, key_prefix_len); col_privs->field[4]->store("",0, &my_charset_latin1); - col_privs->file->ha_index_init(0, 1); + if (col_privs->file->ha_index_init(0, 1)) + { + cols= 0; + return; + } + if (col_privs->file->index_read_map(col_privs->record[0], (uchar*) key, (key_part_map)15, HA_READ_KEY_EXACT)) { @@ -3032,7 +3043,7 @@ static int replace_column_table(GRANT_TABLE *g_t, const char *db, const char *table_name, ulong rights, bool revoke_grant) { - int error=0,result=0; + int result=0; uchar key[MAX_KEY_LENGTH]; uint key_prefix_length; KEY_PART_INFO *key_part= table->key_info->key_part; @@ -3059,7 +3070,13 @@ static int replace_column_table(GRANT_TABLE *g_t, List_iterator <LEX_COLUMN> iter(columns); class LEX_COLUMN *column; - table->file->ha_index_init(0, 1); + int error= table->file->ha_index_init(0, 1); + if (error) + { + table->file->print_error(error, MYF(0)); + DBUG_RETURN(-1); + } + while ((column= iter++)) { ulong privileges= column->rights; @@ -4180,7 +4197,10 @@ static my_bool grant_load_procs_priv(TABLE *p_table) (void) my_hash_init(&func_priv_hash, &my_charset_utf8_bin, 0,0,0, (my_hash_get_key) get_grant_table, 0,0); - p_table->file->ha_index_init(0, 1); + + if (p_table->file->ha_index_init(0, 1)) + DBUG_RETURN(TRUE); + p_table->use_all_columns(); if (!p_table->file->index_first(p_table->record[0])) @@ -4281,7 +4301,10 @@ static my_bool grant_load(THD *thd, TABLE_LIST *tables) t_table = tables[0].table; c_table = tables[1].table; - t_table->file->ha_index_init(0, 1); + + if (t_table->file->ha_index_init(0, 1)) + goto end_index_init; + t_table->use_all_columns(); c_table->use_all_columns(); @@ -4326,9 +4349,10 @@ static my_bool grant_load(THD *thd, TABLE_LIST *tables) return_val=0; // Return ok end_unlock: - thd->variables.sql_mode= old_sql_mode; t_table->file->ha_index_end(); my_pthread_setspecific_ptr(THR_MALLOC, save_mem_root_ptr); +end_index_init: + thd->variables.sql_mode= old_sql_mode; DBUG_RETURN(return_val); } diff --git a/sql/sql_handler.cc b/sql/sql_handler.cc index 4435dfab9ea..e7973850194 100644 --- a/sql/sql_handler.cc +++ b/sql/sql_handler.cc @@ -665,14 +665,14 @@ retry: case RFIRST: if (keyname) { - table->file->ha_index_or_rnd_end(); - table->file->ha_index_init(keyno, 1); - error= table->file->index_first(table->record[0]); + if (!(error= table->file->ha_index_or_rnd_end()) && + !(error= table->file->ha_index_init(keyno, 1))) + error= table->file->index_first(table->record[0]); } else { - table->file->ha_index_or_rnd_end(); - if (!(error= table->file->ha_rnd_init(1))) + if (!(error= table->file->ha_index_or_rnd_end()) && + !(error= table->file->ha_rnd_init(1))) error= table->file->rnd_next(table->record[0]); } mode=RNEXT; @@ -689,9 +689,9 @@ retry: /* else fall through */ case RLAST: DBUG_ASSERT(keyname != 0); - table->file->ha_index_or_rnd_end(); - table->file->ha_index_init(keyno, 1); - error= table->file->index_last(table->record[0]); + if (!(error= table->file->ha_index_or_rnd_end()) && + !(error= table->file->ha_index_init(keyno, 1))) + error= table->file->index_last(table->record[0]); mode=RPREV; break; case RNEXT_SAME: @@ -734,11 +734,12 @@ retry: if (!(key= (uchar*) thd->calloc(ALIGN_SIZE(key_len)))) goto err; - table->file->ha_index_or_rnd_end(); - table->file->ha_index_init(keyno, 1); + if ((error= table->file->ha_index_or_rnd_end())) + break; key_copy(key, table->record[0], table->key_info + keyno, key_len); - error= table->file->index_read_map(table->record[0], - key, keypart_map, ha_rkey_mode); + if (!(error= table->file->ha_index_init(keyno, 1))) + error= table->file->index_read_map(table->record[0], + key, keypart_map, ha_rkey_mode); mode=rkey_to_rnext[(int)ha_rkey_mode]; break; } diff --git a/sql/sql_help.cc b/sql/sql_help.cc index 99203ef98ba..0dca1f6a75a 100644 --- a/sql/sql_help.cc +++ b/sql/sql_help.cc @@ -297,8 +297,14 @@ int get_topics_for_keyword(THD *thd, TABLE *topics, TABLE *relations, rtopic_id= find_fields[help_relation_help_topic_id].field; rkey_id= find_fields[help_relation_help_keyword_id].field; - topics->file->ha_index_init(iindex_topic,1); - relations->file->ha_index_init(iindex_relations,1); + if (topics->file->ha_index_init(iindex_topic,1) || + relations->file->ha_index_init(iindex_relations,1)) + { + if (topics->file->inited) + topics->file->ha_index_end(); + my_message(ER_CORRUPT_HELP_DB, ER(ER_CORRUPT_HELP_DB), MYF(0)); + DBUG_RETURN(-1); + } rkey_id->store((longlong) key_id, TRUE); rkey_id->get_key_image(buff, rkey_id->pack_length(), Field::itRAW); diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 3bde5aa8f6a..5c216a44d70 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -11466,7 +11466,14 @@ do_select(JOIN *join,List<Item> *fields,TABLE *table,Procedure *procedure) empty_record(table); if (table->group && join->tmp_table_param.sum_func_count && table->s->keys && !table->file->inited) - table->file->ha_index_init(0, 0); + { + rc= table->file->ha_index_init(0, 0); + if (rc) + { + table->file->print_error(rc, MYF(0)); + DBUG_RETURN(rc); + } + } } /* Set up select_end */ Next_select_func end_select= setup_end_select_func(join); @@ -12286,8 +12293,13 @@ join_read_key(JOIN_TAB *tab) if (!table->file->inited) { - table->file->ha_index_init(tab->ref.key, tab->sorted); + if ((error= table->file->ha_index_init(tab->ref.key, tab->sorted))) + { + (void) report_error(table, error); + return 1; + } } + if (cmp_buffer_with_ref(tab) || (table->status & (STATUS_GARBAGE | STATUS_NO_PARENT | STATUS_NULL_ROW))) { @@ -12371,8 +12383,12 @@ join_read_always_key(JOIN_TAB *tab) TABLE *table= tab->table; /* Initialize the index first */ - if (!table->file->inited) - table->file->ha_index_init(tab->ref.key, tab->sorted); + if (!table->file->inited && + (error= table->file->ha_index_init(tab->ref.key, tab->sorted))) + { + (void) report_error(table, error); + return 1; + } /* Perform "Late NULLs Filtering" (see internals manual for explanations) */ for (uint i= 0 ; i < tab->ref.key_parts ; i++) @@ -12407,8 +12423,13 @@ join_read_last_key(JOIN_TAB *tab) int error; TABLE *table= tab->table; - if (!table->file->inited) - table->file->ha_index_init(tab->ref.key, tab->sorted); + if (!table->file->inited && + (error= table->file->ha_index_init(tab->ref.key, tab->sorted))) + { + (void) report_error(table, error); + return 1; + } + if (cp_buffer_from_ref(tab->join->thd, table, &tab->ref)) return -1; if ((error=table->file->index_read_last_map(table->record[0], @@ -12520,8 +12541,14 @@ join_read_first(JOIN_TAB *tab) tab->read_record.file=table->file; tab->read_record.index=tab->index; tab->read_record.record=table->record[0]; - if (!table->file->inited) - table->file->ha_index_init(tab->index, tab->sorted); + + if (!table->file->inited && + (error= table->file->ha_index_init(tab->index, tab->sorted))) + { + (void) report_error(table, error); + return 1; + } + if ((error=tab->table->file->index_first(tab->table->record[0]))) { if (error != HA_ERR_KEY_NOT_FOUND && error != HA_ERR_END_OF_FILE) @@ -12555,8 +12582,13 @@ join_read_last(JOIN_TAB *tab) tab->read_record.file=table->file; tab->read_record.index=tab->index; tab->read_record.record=table->record[0]; - if (!table->file->inited) - table->file->ha_index_init(tab->index, 1); + if (!table->file->inited && + (error= table->file->ha_index_init(tab->index, 1))) + { + (void) report_error(table, error); + return 1; + } + if ((error= tab->table->file->index_last(tab->table->record[0]))) return report_error(table, error); return 0; @@ -12579,8 +12611,13 @@ join_ft_read_first(JOIN_TAB *tab) int error; TABLE *table= tab->table; - if (!table->file->inited) - table->file->ha_index_init(tab->ref.key, 1); + if (!table->file->inited && + (error= table->file->ha_index_init(tab->ref.key, 1))) + { + (void) report_error(table, error); + return 1; + } + table->file->ft_init(); if ((error= table->file->ft_read(table->record[0]))) @@ -12973,7 +13010,12 @@ end_update(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)), error, 0)) DBUG_RETURN(NESTED_LOOP_ERROR); // Not a table_is_full error /* Change method to update rows */ - table->file->ha_index_init(0, 0); + if ((error= table->file->ha_index_init(0, 0))) + { + table->file->print_error(error, MYF(0)); + DBUG_RETURN(NESTED_LOOP_ERROR); + } + join->join_tab[join->tables-1].next_select=end_unique_update; } join->send_records++; diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 81e18ccd6c3..b921b2c782e 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -4925,7 +4925,13 @@ int fill_schema_proc(THD *thd, TABLE_LIST *tables, COND *cond) { DBUG_RETURN(1); } - proc_table->file->ha_index_init(0, 1); + + if (proc_table->file->ha_index_init(0, 1)) + { + res= 1; + goto err; + } + if ((res= proc_table->file->index_first(proc_table->record[0]))) { res= (res == HA_ERR_END_OF_FILE) ? 0 : 1; @@ -4951,7 +4957,9 @@ int fill_schema_proc(THD *thd, TABLE_LIST *tables, COND *cond) } err: - proc_table->file->ha_index_end(); + if (proc_table->file->inited) + (void) proc_table->file->ha_index_end(); + close_system_tables(thd, &open_tables_state_backup); DBUG_RETURN(res); } diff --git a/sql/sql_update.cc b/sql/sql_update.cc index c4a95edcfc2..222b3d9470a 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -2038,7 +2038,8 @@ int multi_update::do_updates() org_updated= updated; tmp_table= tmp_tables[cur_table->shared]; tmp_table->file->extra(HA_EXTRA_CACHE); // Change to read cache - (void) table->file->ha_rnd_init(0); + if (local_error= table->file->ha_rnd_init(0)) + goto err; table->file->extra(HA_EXTRA_NO_CACHE); check_opt_it.rewind(); @@ -2163,11 +2164,16 @@ err: } err2: - (void) table->file->ha_rnd_end(); - (void) tmp_table->file->ha_rnd_end(); + if (table->file->inited) + (void) table->file->ha_rnd_end(); + if (tmp_table->file->inited) + (void) tmp_table->file->ha_rnd_end(); check_opt_it.rewind(); while (TABLE *tbl= check_opt_it++) - tbl->file->ha_rnd_end(); + { + if (tbl->file->inited) + (void) tbl->file->ha_rnd_end(); + } if (updated != org_updated) { diff --git a/sql/tztime.cc b/sql/tztime.cc index f245b736f52..72898ccc706 100644 --- a/sql/tztime.cc +++ b/sql/tztime.cc @@ -1706,14 +1706,11 @@ my_tz_init(THD *org_thd, const char *default_tzname, my_bool bootstrap) } table= tz_tables[0].table; - /* - It is OK to ignore ha_index_init()/ha_index_end() return values since - mysql.time_zone* tables are MyISAM and these operations always succeed - for MyISAM. - */ - (void)table->file->ha_index_init(0, 1); - table->use_all_columns(); + if (table->file->ha_index_init(0, 1)) + goto end_with_close; + + table->use_all_columns(); tz_leapcnt= 0; res= table->file->index_first(table->record[0]); @@ -1899,12 +1896,8 @@ tz_load_from_open_tables(const String *tz_name, TABLE_LIST *tz_tables) tz_tables= tz_tables->next_local; table->field[0]->store(tz_name->ptr(), tz_name->length(), &my_charset_latin1); - /* - It is OK to ignore ha_index_init()/ha_index_end() return values since - mysql.time_zone* tables are MyISAM and these operations always succeed - for MyISAM. - */ - (void)table->file->ha_index_init(0, 1); + if (table->file->ha_index_init(0, 1)) + goto end; if (table->file->index_read_map(table->record[0], table->field[0]->ptr, HA_WHOLE_KEY, HA_READ_KEY_EXACT)) @@ -1932,7 +1925,8 @@ tz_load_from_open_tables(const String *tz_name, TABLE_LIST *tz_tables) table= tz_tables->table; tz_tables= tz_tables->next_local; table->field[0]->store((longlong) tzid, TRUE); - (void)table->file->ha_index_init(0, 1); + if (table->file->ha_index_init(0, 1)) + goto end; if (table->file->index_read_map(table->record[0], table->field[0]->ptr, HA_WHOLE_KEY, HA_READ_KEY_EXACT)) @@ -1959,7 +1953,8 @@ tz_load_from_open_tables(const String *tz_name, TABLE_LIST *tz_tables) table= tz_tables->table; tz_tables= tz_tables->next_local; table->field[0]->store((longlong) tzid, TRUE); - (void)table->file->ha_index_init(0, 1); + if (table->file->ha_index_init(0, 1)) + goto end; res= table->file->index_read_map(table->record[0], table->field[0]->ptr, (key_part_map)1, HA_READ_KEY_EXACT); @@ -2030,7 +2025,8 @@ tz_load_from_open_tables(const String *tz_name, TABLE_LIST *tz_tables) */ table= tz_tables->table; table->field[0]->store((longlong) tzid, TRUE); - (void)table->file->ha_index_init(0, 1); + if (table->file->ha_index_init(0, 1)) + goto end; res= table->file->index_read_map(table->record[0], table->field[0]->ptr, (key_part_map)1, HA_READ_KEY_EXACT); @@ -2165,8 +2161,8 @@ tz_load_from_open_tables(const String *tz_name, TABLE_LIST *tz_tables) end: - if (table) - (void)table->file->ha_index_end(); + if (table && table->file->inited) + (void) table->file->ha_index_end(); DBUG_RETURN(return_val); } diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 9c77179c188..12c4b5a0e40 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -6110,7 +6110,7 @@ ha_innobase::change_active_index( "InnoDB: Index %s for table %s is" " marked as corrupted", index_name, table_name); - DBUG_RETURN(1); + DBUG_RETURN(HA_ERR_INDEX_CORRUPT); } else { push_warning_printf( user_thd, MYSQL_ERROR::WARN_LEVEL_WARN, @@ -6121,7 +6121,7 @@ ha_innobase::change_active_index( /* The caller seems to ignore this. Thus, we must check this again in row_search_for_mysql(). */ - DBUG_RETURN(2); + DBUG_RETURN(HA_ERR_TABLE_DEF_CHANGED); } ut_a(prebuilt->search_tuple != 0); |