diff options
author | Michael Widenius <monty@askmonty.org> | 2010-07-17 01:41:44 +0300 |
---|---|---|
committer | Michael Widenius <monty@askmonty.org> | 2010-07-17 01:41:44 +0300 |
commit | e9166ca1527fb2f450584712056d081daf36517f (patch) | |
tree | a0d76e2429c63d9abafd376b00d7ea12466ee8a8 | |
parent | 683154d1fa6249a8bfcde4bb9227570c452ea802 (diff) | |
download | mariadb-git-e9166ca1527fb2f450584712056d081daf36517f.tar.gz |
Fix for LP#588251: doStartTableScan() result not checked.
The issue was that we didn't always check result of ha_rnd_init() which caused a problem for handlers that returned an error in this code.
- Changed prototype of ha_rnd_init() to ensure that we get a compile warning if result is not checked.
- Added ha_rnd_init_with_error() that prints error on failure.
- Checked all usage of ha_rnd_init() and ensure we generate an error message on failures.
- Changed init_read_record() to return 1 on failure.
sql/create_options.cc:
Fixed wrong printf
sql/event_db_repository.cc:
Check result from init_read_record()
sql/events.cc:
Check result from init_read_record()
sql/filesort.cc:
Check result from ha_rnd_init()
sql/ha_partition.cc:
Check result from ha_rnd_init()
sql/ha_partition.h:
Fixed compiler warning
sql/handler.cc:
Added ha_rnd_init_with_error()
Check result from ha_rnd_init()
sql/handler.h:
Added ha_rnd_init_with_error()
Changed prototype of ha_rnd_init() to ensure that we get a compile warning if result is not checked
sql/item_subselect.cc:
Check result from ha_rnd_init()
sql/log.cc:
Check result from ha_rnd_init()
sql/log_event.cc:
Check result from ha_rnd_init()
sql/log_event_old.cc:
Check result from ha_rnd_init()
sql/mysql_priv.h:
init_read_record() now returns error code on failure
sql/opt_range.cc:
Check result from ha_rnd_init()
sql/records.cc:
init_read_record() now returns error code on failure
Check result from ha_rnd_init()
sql/sql_acl.cc:
Check result from init_read_record()
sql/sql_cursor.cc:
Print error if ha_rnd_init() fails
sql/sql_delete.cc:
Check result from init_read_record()
sql/sql_help.cc:
Check result from init_read_record()
sql/sql_plugin.cc:
Check result from init_read_record()
sql/sql_select.cc:
Check result from ha_rnd_init()
Print error if ha_rnd_init() fails.
sql/sql_servers.cc:
Check result from init_read_record()
sql/sql_table.cc:
Check result from init_read_record()
sql/sql_udf.cc:
Check result from init_read_record()
sql/sql_update.cc:
Check result from init_read_record()
storage/example/ha_example.cc:
Don't return error on rnd_init()
storage/ibmdb2i/ha_ibmdb2i.cc:
Removed not relevant comment
-rw-r--r-- | sql/create_options.cc | 4 | ||||
-rw-r--r-- | sql/event_db_repository.cc | 10 | ||||
-rw-r--r-- | sql/events.cc | 7 | ||||
-rw-r--r-- | sql/filesort.cc | 3 | ||||
-rw-r--r-- | sql/ha_partition.cc | 2 | ||||
-rw-r--r-- | sql/ha_partition.h | 2 | ||||
-rw-r--r-- | sql/handler.cc | 20 | ||||
-rw-r--r-- | sql/handler.h | 3 | ||||
-rw-r--r-- | sql/item_subselect.cc | 3 | ||||
-rw-r--r-- | sql/log.cc | 4 | ||||
-rw-r--r-- | sql/log_event.cc | 20 | ||||
-rw-r--r-- | sql/log_event_old.cc | 25 | ||||
-rw-r--r-- | sql/mysql_priv.h | 2 | ||||
-rw-r--r-- | sql/opt_range.cc | 7 | ||||
-rw-r--r-- | sql/records.cc | 14 | ||||
-rw-r--r-- | sql/sql_acl.cc | 16 | ||||
-rw-r--r-- | sql/sql_cursor.cc | 2 | ||||
-rw-r--r-- | sql/sql_delete.cc | 14 | ||||
-rw-r--r-- | sql/sql_help.cc | 29 | ||||
-rw-r--r-- | sql/sql_plugin.cc | 7 | ||||
-rw-r--r-- | sql/sql_select.cc | 18 | ||||
-rw-r--r-- | sql/sql_servers.cc | 5 | ||||
-rw-r--r-- | sql/sql_table.cc | 3 | ||||
-rw-r--r-- | sql/sql_udf.cc | 8 | ||||
-rw-r--r-- | sql/sql_update.cc | 43 | ||||
-rw-r--r-- | storage/example/ha_example.cc | 2 | ||||
-rw-r--r-- | storage/ibmdb2i/ha_ibmdb2i.cc | 4 |
27 files changed, 196 insertions, 81 deletions
diff --git a/sql/create_options.cc b/sql/create_options.cc index c7ede1b2331..6d682853ae6 100644 --- a/sql/create_options.cc +++ b/sql/create_options.cc @@ -583,9 +583,9 @@ my_bool engine_table_options_frm_read(const uchar *buff, uint length, } if (buff < buff_end) - sql_print_warning("Table %`s was created in a later MariaDB version - " + sql_print_warning("Table '%s' was created in a later MariaDB version - " "unknown table attributes were ignored", - share->table_name); + share->table_name.str); DBUG_RETURN(buff > buff_end); } diff --git a/sql/event_db_repository.cc b/sql/event_db_repository.cc index 82f9d354888..1349f6b5cba 100644 --- a/sql/event_db_repository.cc +++ b/sql/event_db_repository.cc @@ -474,7 +474,8 @@ Event_db_repository::table_scan_all_for_i_s(THD *thd, TABLE *schema_table, READ_RECORD read_record_info; DBUG_ENTER("Event_db_repository::table_scan_all_for_i_s"); - init_read_record(&read_record_info, thd, event_table, NULL, 1, 0, FALSE); + if (init_read_record(&read_record_info, thd, event_table, NULL, 1, 0, FALSE)) + DBUG_RETURN(TRUE); /* rr_sequential, in read_record(), returns 137==HA_ERR_END_OF_FILE, @@ -960,7 +961,9 @@ Event_db_repository::drop_events_by_field(THD *thd, DBUG_VOID_RETURN; /* only enabled events are in memory, so we go now and delete the rest */ - init_read_record(&read_record_info, thd, table, NULL, 1, 0, FALSE); + if (init_read_record(&read_record_info, thd, table, NULL, 1, 0, FALSE)) + goto end; + while (!ret && !(read_record_info.read_record(&read_record_info)) ) { char *et_field= get_field(thd->mem_root, table->field[field]); @@ -982,8 +985,9 @@ Event_db_repository::drop_events_by_field(THD *thd, } } end_read_record(&read_record_info); - close_thread_tables(thd); +end: + close_thread_tables(thd); DBUG_VOID_RETURN; } diff --git a/sql/events.cc b/sql/events.cc index 0f3fc8eee4a..8bb7406b615 100644 --- a/sql/events.cc +++ b/sql/events.cc @@ -1214,7 +1214,12 @@ Events::load_events_from_db(THD *thd) DBUG_RETURN(TRUE); } - init_read_record(&read_record_info, thd, table, NULL, 0, 1, FALSE); + if (init_read_record(&read_record_info, thd, table, NULL, 0, 1, FALSE)) + { + close_thread_tables(thd); + DBUG_RETURN(TRUE); + } + while (!(read_record_info.read_record(&read_record_info))) { Event_queue_element *et; diff --git a/sql/filesort.cc b/sql/filesort.cc index 270f0f1ac37..257e721041a 100644 --- a/sql/filesort.cc +++ b/sql/filesort.cc @@ -537,7 +537,8 @@ static ha_rows find_all_keys(SORTPARAM *param, SQL_SELECT *select, if (! indexfile && ! quick_select) { next_pos=(uchar*) 0; /* Find records in sequence */ - file->ha_rnd_init(1); + if (file->ha_rnd_init_with_error(1)) + DBUG_RETURN(HA_POS_ERROR); file->extra_opt(HA_EXTRA_CACHE, current_thd->variables.read_buff_size); } diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc index 1b430275d59..9026a901671 100644 --- a/sql/ha_partition.cc +++ b/sql/ha_partition.cc @@ -1661,7 +1661,7 @@ int ha_partition::copy_partitions(ulonglong * const copied, uint32 new_part; late_extra_cache(reorg_part); - if ((result= file->ha_rnd_init(1))) + if ((result= file->ha_rnd_init_with_error(1))) goto error; while (TRUE) { diff --git a/sql/ha_partition.h b/sql/ha_partition.h index 7fc33b46b16..e1339abc081 100644 --- a/sql/ha_partition.h +++ b/sql/ha_partition.h @@ -1129,7 +1129,7 @@ public: virtual handlerton *partition_ht() const { handlerton *h= m_file[0]->ht; - for (int i=1; i < m_tot_parts; i++) + for (uint i=1; i < m_tot_parts; i++) DBUG_ASSERT(h == m_file[i]->ht); return h; } diff --git a/sql/handler.cc b/sql/handler.cc index b8714009c4e..2b931b6f5c1 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -2114,6 +2114,18 @@ int handler::ha_open(TABLE *table_arg, const char *name, int mode, } +/* Initialize handler for random reading, with error handling */ + +int handler::ha_rnd_init_with_error(bool scan) +{ + int error; + if (!(error= ha_rnd_init(scan))) + return 0; + table->file->print_error(error, MYF(0)); + return error; +} + + /** Read first row (only) from a table. @@ -2133,9 +2145,11 @@ 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= ha_rnd_next(buf)) == HA_ERR_RECORD_DELETED) ; - (void) ha_rnd_end(); + if ((!(error= ha_rnd_init(1)))) + { + while ((error= ha_rnd_next(buf)) == HA_ERR_RECORD_DELETED) ; + (void) ha_rnd_end(); + } } else { diff --git a/sql/handler.h b/sql/handler.h index 5f94e9adbb0..502b962a851 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -1327,7 +1327,7 @@ public: } /* This is called after index_init() if we need to do a index scan */ virtual int prepare_index_scan() { return 0; } - int ha_rnd_init(bool scan) + int ha_rnd_init(bool scan) __attribute__ ((warn_unused_result)) { int result; DBUG_ENTER("ha_rnd_init"); @@ -1342,6 +1342,7 @@ public: inited=NONE; DBUG_RETURN(rnd_end()); } + int ha_rnd_init_with_error(bool scan) __attribute__ ((warn_unused_result)); int ha_reset(); /* Tell handler (not storage engine) this is start of a new statement */ void ha_start_of_new_statement() diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index 000d4591a27..82bb02f362e 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -2070,7 +2070,8 @@ int subselect_uniquesubquery_engine::scan_table() if (table->file->inited) table->file->ha_index_end(); - table->file->ha_rnd_init(1); + if (table->file->ha_rnd_init_with_error(1)) + DBUG_RETURN(1); table->file->extra_opt(HA_EXTRA_CACHE, current_thd->variables.read_buff_size); table->null_row= 0; diff --git a/sql/log.cc b/sql/log.cc index 59e466f42b6..6094836c031 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -412,7 +412,7 @@ bool Log_to_csv_event_handler:: need_close= TRUE; if (table->file->extra(HA_EXTRA_MARK_AS_LOG_TABLE) || - table->file->ha_rnd_init(0)) + table->file->ha_rnd_init_with_error(0)) goto err; need_rnd_end= TRUE; @@ -563,7 +563,7 @@ bool Log_to_csv_event_handler:: need_close= TRUE; if (table->file->extra(HA_EXTRA_MARK_AS_LOG_TABLE) || - table->file->ha_rnd_init(0)) + table->file->ha_rnd_init_with_error(0)) goto err; need_rnd_end= TRUE; diff --git a/sql/log_event.cc b/sql/log_event.cc index 06fcdf5003c..568e6cbf815 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -8920,10 +8920,10 @@ record_compare_exit: /** Locate the current row in event's table. - The current row is pointed by @c m_curr_row. Member @c m_width tells how many - columns are there in the row (this can be differnet from the number of columns - in the table). It is assumed that event's table is already open and pointed - by @c m_table. + The current row is pointed by @c m_curr_row. Member @c m_width tells + how many columns are there in the row (this can be differnet from + the number of columns in the table). It is assumed that event's + table is already open and pointed by @c m_table. If a corresponding record is found in the table it is stored in @c m_table->record[0]. Note that when record is located based on a primary @@ -9139,11 +9139,10 @@ int Rows_log_event::find_row(const Relay_log_info *rli) int restart_count= 0; // Number of times scanning has restarted from top /* We don't have a key: search the table using rnd_next() */ - if ((error= table->file->ha_rnd_init(1))) + if ((error= table->file->ha_rnd_init_with_error(1))) { DBUG_PRINT("info",("error initializing table scan" " (ha_rnd_init returns %d)",error)); - table->file->print_error(error, MYF(0)); goto err; } @@ -9168,7 +9167,14 @@ 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); + { + int error2; + if ((error2= table->file->ha_rnd_init_with_error(1))) + { + error= error2; + goto err; + } + } break; default: diff --git a/sql/log_event_old.cc b/sql/log_event_old.cc index cf358bd757d..96fcff66d19 100644 --- a/sql/log_event_old.cc +++ b/sql/log_event_old.cc @@ -816,7 +816,7 @@ static int find_and_fetch_row(TABLE *table, uchar *key) int error; /* We don't have a key: search the table using rnd_next() */ - if ((error= table->file->ha_rnd_init(1))) + if ((error= table->file->ha_rnd_init_with_error(1))) return error; /* Continue until we find the right record or have made a full loop */ @@ -840,15 +840,19 @@ 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) + { + int error2; + if ((error2= table->file->ha_rnd_init_with_error(1))) + DBUG_RETURN(error2); + } + 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); + DBUG_RETURN(error); } } while (restart_count < 2 && record_compare(table)); @@ -2461,11 +2465,10 @@ int Old_rows_log_event::find_row(const Relay_log_info *rli) int restart_count= 0; // Number of times scanning has restarted from top /* We don't have a key: search the table using rnd_next() */ - if ((error= table->file->ha_rnd_init(1))) + if ((error= table->file->ha_rnd_init_with_error(1))) { DBUG_PRINT("info",("error initializing table scan" " (ha_rnd_init returns %d)",error)); - table->file->print_error(error, MYF(0)); DBUG_RETURN(error); } @@ -2485,7 +2488,11 @@ 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); + { + int error2; + if ((error2= table->file->ha_rnd_init_with_error(1))) + DBUG_RETURN(error2); + } break; default: diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 299222e4c95..cbaa5fad5b9 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -2303,7 +2303,7 @@ longlong get_datetime_value(THD *thd, Item ***item_arg, Item **cache_arg, int test_if_number(char *str,int *res,bool allow_wildcards); void change_byte(uchar *,uint,char,char); -void init_read_record(READ_RECORD *info, THD *thd, TABLE *reg_form, +bool init_read_record(READ_RECORD *info, THD *thd, TABLE *reg_form, SQL_SELECT *select, int use_record_cache, bool print_errors, bool disable_rr_cache); void init_read_record_idx(READ_RECORD *info, THD *thd, TABLE *table, diff --git a/sql/opt_range.cc b/sql/opt_range.cc index d13a2e6a0af..ad404a100e3 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -1431,7 +1431,7 @@ int QUICK_ROR_INTERSECT_SELECT::init_ror_merged_scan(bool reuse_handler) quick->record= head->record[0]; } - if (need_to_fetch_row && head->file->ha_rnd_init(1)) + if (need_to_fetch_row && head->file->ha_rnd_init_with_error(1)) { DBUG_PRINT("error", ("ROR index_merge rnd_init call failed")); DBUG_RETURN(1); @@ -1602,7 +1602,7 @@ int QUICK_ROR_UNION_SELECT::reset() queue_insert(&queue, (uchar*)quick); } - if (head->file->ha_rnd_init(1)) + if (head->file->ha_rnd_init_with_error(1)) { DBUG_PRINT("error", ("ROR index_merge rnd_init call failed")); DBUG_RETURN(1); @@ -8199,7 +8199,8 @@ int QUICK_INDEX_MERGE_SELECT::read_keys_and_merge() index_merge currently doesn't support "using index" at all */ head->disable_keyread(); - init_read_record(&read_record, thd, head, (SQL_SELECT*) 0, 1 , 1, TRUE); + if (init_read_record(&read_record, thd, head, (SQL_SELECT*) 0, 1 , 1, TRUE)) + result= 1; DBUG_RETURN(result); err: diff --git a/sql/records.cc b/sql/records.cc index e2a1ea9b4af..3342c7db685 100644 --- a/sql/records.cc +++ b/sql/records.cc @@ -157,7 +157,8 @@ void init_read_record_idx(READ_RECORD *info, THD *thd, TABLE *table, This is the most basic access method of a table using rnd_init, rnd_next and rnd_end. No indexes are used. */ -void init_read_record(READ_RECORD *info,THD *thd, TABLE *table, + +bool init_read_record(READ_RECORD *info,THD *thd, TABLE *table, SQL_SELECT *select, int use_record_cache, bool print_error, bool disable_rr_cache) @@ -205,7 +206,8 @@ void init_read_record(READ_RECORD *info,THD *thd, TABLE *table, reinit_io_cache(info->io_cache,READ_CACHE,0L,0,0); info->ref_pos=table->file->ref; if (!table->file->inited) - table->file->ha_rnd_init(0); + if (table->file->ha_rnd_init_with_error(0)) + DBUG_RETURN(1); /* table->sort.addon_field is checked because if we use addon fields, @@ -242,7 +244,8 @@ void init_read_record(READ_RECORD *info,THD *thd, TABLE *table, else if (table->sort.record_pointers) { DBUG_PRINT("info",("using record_pointers")); - table->file->ha_rnd_init(0); + if (table->file->ha_rnd_init_with_error(0)) + DBUG_RETURN(1); info->cache_pos=table->sort.record_pointers; info->cache_end=info->cache_pos+ table->sort.found_records*info->ref_length; @@ -253,7 +256,8 @@ void init_read_record(READ_RECORD *info,THD *thd, TABLE *table, { DBUG_PRINT("info",("using rr_sequential")); info->read_record=rr_sequential; - table->file->ha_rnd_init(1); + if (table->file->ha_rnd_init_with_error(1)) + DBUG_RETURN(1); /* We can use record cache if we don't update dynamic length tables */ if (!table->no_cache && (use_record_cache > 0 || @@ -271,7 +275,7 @@ void init_read_record(READ_RECORD *info,THD *thd, TABLE *table, !table->file->pushed_cond) table->file->cond_push(select->cond); - DBUG_VOID_RETURN; + DBUG_RETURN(0); } /* init_read_record */ diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index db20782037e..3f4400b4687 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -477,8 +477,10 @@ static my_bool acl_load(THD *thd, TABLE_LIST *tables) acl_cache->clear(1); // Clear locked hostname cache init_sql_alloc(&mem, ACL_ALLOC_BLOCK_SIZE, 0); - init_read_record(&read_record_info,thd,table= tables[0].table,NULL,1,0, - FALSE); + if (init_read_record(&read_record_info,thd,table= tables[0].table,NULL,1,0, + FALSE)) + goto end; + table->use_all_columns(); VOID(my_init_dynamic_array(&acl_hosts,sizeof(ACL_HOST),20,50)); while (!(read_record_info.read_record(&read_record_info))) @@ -527,7 +529,10 @@ static my_bool acl_load(THD *thd, TABLE_LIST *tables) end_read_record(&read_record_info); freeze_size(&acl_hosts); - init_read_record(&read_record_info,thd,table=tables[1].table,NULL,1,0,FALSE); + if (init_read_record(&read_record_info,thd,table=tables[1].table,NULL,1,0, + FALSE)) + goto end; + table->use_all_columns(); VOID(my_init_dynamic_array(&acl_users,sizeof(ACL_USER),50,100)); password_length= table->field[2]->field_length / @@ -748,7 +753,10 @@ static my_bool acl_load(THD *thd, TABLE_LIST *tables) end_read_record(&read_record_info); freeze_size(&acl_users); - init_read_record(&read_record_info,thd,table=tables[2].table,NULL,1,0,FALSE); + if (init_read_record(&read_record_info,thd,table=tables[2].table,NULL,1,0, + FALSE)) + goto end; + table->use_all_columns(); VOID(my_init_dynamic_array(&acl_dbs,sizeof(ACL_DB),50,100)); while (!(read_record_info.read_record(&read_record_info))) diff --git a/sql/sql_cursor.cc b/sql/sql_cursor.cc index 71c28f425d4..e9ef5ef0cf3 100644 --- a/sql/sql_cursor.cc +++ b/sql/sql_cursor.cc @@ -608,7 +608,7 @@ int Materialized_cursor::open(JOIN *join __attribute__((unused))) thd->set_n_backup_active_arena(this, &backup_arena); /* Create a list of fields and start sequential scan */ rc= result->prepare(item_list, &fake_unit); - if (!rc && !(rc= table->file->ha_rnd_init(TRUE))) + if (!rc && !(rc= table->file->ha_rnd_init_with_error(TRUE))) is_rnd_inited= 1; thd->restore_active_arena(this, &backup_arena); diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc index eb05077f17a..8fba48f54cc 100644 --- a/sql/sql_delete.cc +++ b/sql/sql_delete.cc @@ -266,7 +266,14 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, DBUG_RETURN(TRUE); } if (usable_index==MAX_KEY) - init_read_record(&info, thd, table, select, 1, 1, FALSE); + { + if (init_read_record(&info, thd, table, select, 1, 1, FALSE)) + { + delete select; + free_underlaid_joins(thd, select_lex); + DBUG_RETURN(TRUE); + } + } else init_read_record_idx(&info, thd, table, 1, usable_index); @@ -944,7 +951,10 @@ int multi_delete::do_table_deletes(TABLE *table, bool ignore) READ_RECORD info; ha_rows last_deleted= deleted; DBUG_ENTER("do_deletes_for_table"); - init_read_record(&info, thd, table, NULL, 0, 1, FALSE); + + if (init_read_record(&info, thd, table, NULL, 0, 1, FALSE)) + DBUG_RETURN(1); + /* Ignore any rows not found in reference tables as they may already have been deleted by foreign key handling diff --git a/sql/sql_help.cc b/sql/sql_help.cc index 5658a3578ab..916557a46c4 100644 --- a/sql/sql_help.cc +++ b/sql/sql_help.cc @@ -182,11 +182,14 @@ int search_topics(THD *thd, TABLE *topics, struct st_find_field *find_fields, SQL_SELECT *select, List<String> *names, String *name, String *description, String *example) { - DBUG_ENTER("search_topics"); int count= 0; - READ_RECORD read_record_info; - init_read_record(&read_record_info, thd, topics, select, 1, 0, FALSE); + DBUG_ENTER("search_topics"); + + /* Should never happen. As this is part of help, we can ignore this */ + if (init_read_record(&read_record_info, thd, topics, select, 1, 0, FALSE)) + DBUG_RETURN(0); + while (!read_record_info.read_record(&read_record_info)) { if (!select->cond->val_int()) // Doesn't match like @@ -222,11 +225,13 @@ int search_topics(THD *thd, TABLE *topics, struct st_find_field *find_fields, int search_keyword(THD *thd, TABLE *keywords, struct st_find_field *find_fields, SQL_SELECT *select, int *key_id) { - DBUG_ENTER("search_keyword"); int count= 0; - READ_RECORD read_record_info; - init_read_record(&read_record_info, thd, keywords, select, 1, 0, FALSE); + DBUG_ENTER("search_keyword"); + /* Should never happen. As this is part of help, we can ignore this */ + if (init_read_record(&read_record_info, thd, keywords, select, 1, 0, FALSE)) + DBUG_RETURN(0); + while (!read_record_info.read_record(&read_record_info) && count<2) { if (!select->cond->val_int()) // Dosn't match like @@ -347,10 +352,11 @@ int search_categories(THD *thd, TABLE *categories, Field *pcat_id= find_fields[help_category_help_category_id].field; int count= 0; READ_RECORD read_record_info; - DBUG_ENTER("search_categories"); - init_read_record(&read_record_info, thd, categories, select,1,0,FALSE); + /* Should never happen. As this is part of help, we can ignore this */ + if (init_read_record(&read_record_info, thd, categories, select,1,0,FALSE)) + DBUG_RETURN(0); while (!read_record_info.read_record(&read_record_info)) { if (select && !select->cond->val_int()) @@ -381,10 +387,13 @@ int search_categories(THD *thd, TABLE *categories, void get_all_items_for_category(THD *thd, TABLE *items, Field *pfname, SQL_SELECT *select, List<String> *res) { + READ_RECORD read_record_info; DBUG_ENTER("get_all_items_for_category"); - READ_RECORD read_record_info; - init_read_record(&read_record_info, thd, items, select,1,0,FALSE); + /* Should never happen. As this is part of help, we can ignore this */ + if (init_read_record(&read_record_info, thd, items, select,1,0,FALSE)) + DBUG_VOID_RETURN; + while (!read_record_info.read_record(&read_record_info)) { if (!select->cond->val_int()) diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc index 71c735fee66..7c5bbf60b53 100644 --- a/sql/sql_plugin.cc +++ b/sql/sql_plugin.cc @@ -1621,7 +1621,12 @@ static void plugin_load(MEM_ROOT *tmp_root, int *argc, char **argv) goto end; } table= tables.table; - init_read_record(&read_record_info, new_thd, table, NULL, 1, 0, FALSE); + if (init_read_record(&read_record_info, new_thd, table, NULL, 1, 0, FALSE)) + { + sql_print_error("Could not initialize init_read_record; Plugins not " + "loaded"); + goto end; + } table->use_all_columns(); /* there're no other threads running yet, so we don't need a mutex. diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 8df5e4f697f..024edf01e42 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -11069,7 +11069,8 @@ create_internal_tmp_table_from_heap2(THD *thd, TABLE *table, if (table->file->indexes_are_disabled()) new_table.file->ha_disable_indexes(HA_KEY_SWITCH_ALL); table->file->ha_index_or_rnd_end(); - table->file->ha_rnd_init(1); + if (table->file->ha_rnd_init_with_error(1)) + DBUG_RETURN(1); if (table->no_rows) { new_table.file->extra(HA_EXTRA_NO_ROWS); @@ -12322,7 +12323,7 @@ int rr_sequential(READ_RECORD *info); int init_read_record_seq(JOIN_TAB *tab) { tab->read_record.read_record= rr_sequential; - if (tab->read_record.file->ha_rnd_init(1)) + if (tab->read_record.file->ha_rnd_init_with_error(1)) return 1; return (*tab->read_record.read_record)(&tab->read_record); } @@ -12342,8 +12343,9 @@ join_init_read_record(JOIN_TAB *tab) { if (tab->select && tab->select->quick && tab->select->quick->reset()) return 1; - init_read_record(&tab->read_record, tab->join->thd, tab->table, - tab->select,1,1, FALSE); + if (init_read_record(&tab->read_record, tab->join->thd, tab->table, + tab->select,1,1, FALSE)) + return 1; return (*tab->read_record.read_record)(&tab->read_record); } @@ -14264,7 +14266,9 @@ static int remove_dup_with_compare(THD *thd, TABLE *table, Field **first_field, org_record=(char*) (record=table->record[0])+offset; new_record=(char*) table->record[1]+offset; - file->ha_rnd_init(1); + if (file->ha_rnd_init_with_error(1)) + DBUG_RETURN(1); + error= file->ha_rnd_next(record); for (;;) { @@ -14393,7 +14397,9 @@ static int remove_dup_with_hash_index(THD *thd, TABLE *table, DBUG_RETURN(1); } - file->ha_rnd_init(1); + if ((error= file->ha_rnd_init(1))) + goto err; + key_pos=key_buffer; for (;;) { diff --git a/sql/sql_servers.cc b/sql/sql_servers.cc index b88320ed2bf..ba4dbaacbb9 100644 --- a/sql/sql_servers.cc +++ b/sql/sql_servers.cc @@ -182,8 +182,9 @@ static bool servers_load(THD *thd, TABLE_LIST *tables) free_root(&mem, MYF(0)); init_alloc_root(&mem, ACL_ALLOC_BLOCK_SIZE, 0); - init_read_record(&read_record_info,thd,table=tables[0].table,NULL,1,0, - FALSE); + if (init_read_record(&read_record_info,thd,table=tables[0].table,NULL,1,0, + FALSE)) + DBUG_RETURN(1); while (!(read_record_info.read_record(&read_record_info))) { /* return_val is already TRUE, so no need to set */ diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 624aab93e33..3ad574a7978 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -7877,7 +7877,8 @@ copy_data_between_tables(TABLE *from,TABLE *to, /* Tell handler that we have values for all columns in the to table */ to->use_all_columns(); to->mark_virtual_columns_for_write(); - init_read_record(&info, thd, from, (SQL_SELECT *) 0, 1, 1, FALSE); + if (init_read_record(&info, thd, from, (SQL_SELECT *) 0, 1, 1, FALSE)) + goto err; errpos= 4; if (ignore) to->file->extra(HA_EXTRA_IGNORE_DUP_KEY); diff --git a/sql/sql_udf.cc b/sql/sql_udf.cc index b18f0c28bdf..7aa7571d5ee 100644 --- a/sql/sql_udf.cc +++ b/sql/sql_udf.cc @@ -152,7 +152,13 @@ void udf_init() } table= tables.table; - init_read_record(&read_record_info, new_thd, table, NULL,1,0,FALSE); + if (init_read_record(&read_record_info, new_thd, table, NULL,1,0,FALSE)) + { + sql_print_error("Could not initialize init_read_record; udf's not " + "loaded"); + goto end; + } + table->use_all_columns(); while (!(error= read_record_info.read_record(&read_record_info))) { diff --git a/sql/sql_update.cc b/sql/sql_update.cc index e260310206a..61e93e7c5b1 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -459,7 +459,10 @@ int mysql_update(THD *thd, */ if (used_index == MAX_KEY || (select && select->quick)) - init_read_record(&info, thd, table, select, 0, 1, FALSE); + { + if (init_read_record(&info, thd, table, select, 0, 1, FALSE)) + goto err; + } else init_read_record_idx(&info, thd, table, 1, used_index); @@ -527,7 +530,8 @@ int mysql_update(THD *thd, if (select && select->quick && select->quick->reset()) goto err; table->file->try_semi_consistent_read(1); - init_read_record(&info, thd, table, select, 0, 1, FALSE); + if (init_read_record(&info, thd, table, select, 0, 1, FALSE)) + goto err; updated= found= 0; /* @@ -1954,7 +1958,7 @@ int multi_update::do_updates() TABLE_LIST *cur_table; int local_error= 0; ha_rows org_updated; - TABLE *table, *tmp_table; + TABLE *table, *tmp_table, *err_table; List_iterator_fast<TABLE> check_opt_it(unupdated_check_opt_tables); DBUG_ENTER("multi_update::do_updates"); @@ -1972,14 +1976,21 @@ 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))) + { + err_table= table; + goto err; + } table->file->extra(HA_EXTRA_NO_CACHE); check_opt_it.rewind(); while(TABLE *tbl= check_opt_it++) { - if (tbl->file->ha_rnd_init(1)) + if ((local_error= tbl->file->ha_rnd_init(1))) + { + err_table= tbl; goto err; + } tbl->file->extra(HA_EXTRA_CACHE); } @@ -1997,8 +2008,11 @@ int multi_update::do_updates() } copy_field_end=copy_field_ptr; - if ((local_error = tmp_table->file->ha_rnd_init(1))) + if ((local_error= tmp_table->file->ha_rnd_init(1))) + { + err_table= tmp_table; goto err; + } can_compare_record= (!(table->file->ha_table_flags() & HA_PARTIAL_COLUMN_READ) || @@ -2008,13 +2022,17 @@ int multi_update::do_updates() for (;;) { if (thd->killed && trans_safe) - goto err; + { + thd->fatal_error(); + goto err2; + } if ((local_error= tmp_table->file->ha_rnd_next(tmp_table->record[0]))) { if (local_error == HA_ERR_END_OF_FILE) break; if (local_error == HA_ERR_RECORD_DELETED) continue; // May happen on dup key + err_table= tmp_table; goto err; } @@ -2027,7 +2045,10 @@ int multi_update::do_updates() if ((local_error= tbl->file->ha_rnd_pos(tbl->record[0], (uchar*) tmp_table->field[field_num]->ptr))) + { + err_table= tbl; goto err; + } field_num++; } while ((tbl= check_opt_it++)); @@ -2054,7 +2075,10 @@ int multi_update::do_updates() if (error == VIEW_CHECK_SKIP) continue; else if (error == VIEW_CHECK_ERROR) - goto err; + { + thd->fatal_error(); + goto err2; + } } if ((local_error=table->file->ha_update_row(table->record[1], table->record[0])) && @@ -2062,7 +2086,10 @@ int multi_update::do_updates() { if (!ignore || table->file->is_fatal_error(local_error, HA_CHECK_DUP_KEY)) + { + err_table= table; goto err; + } } if (local_error != HA_ERR_RECORD_IS_THE_SAME) updated++; diff --git a/storage/example/ha_example.cc b/storage/example/ha_example.cc index 5059c729ae9..6b9725dfde4 100644 --- a/storage/example/ha_example.cc +++ b/storage/example/ha_example.cc @@ -588,7 +588,7 @@ int ha_example::index_last(uchar *buf) int ha_example::rnd_init(bool scan) { DBUG_ENTER("ha_example::rnd_init"); - DBUG_RETURN(HA_ERR_WRONG_COMMAND); + DBUG_RETURN(0); } int ha_example::rnd_end() diff --git a/storage/ibmdb2i/ha_ibmdb2i.cc b/storage/ibmdb2i/ha_ibmdb2i.cc index c007cbaf3e3..f77927421d2 100644 --- a/storage/ibmdb2i/ha_ibmdb2i.cc +++ b/storage/ibmdb2i/ha_ibmdb2i.cc @@ -1158,9 +1158,7 @@ int ha_ibmdb2i::rnd_init(bool scan) rrnAssocHandle= 0; - DBUG_RETURN(0); // MySQL sometimes does not check the return code, causing - // an assert in ha_rnd_end later on if we return a non-zero - // value here. + DBUG_RETURN(0); } int ha_ibmdb2i::rnd_end() |