summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Widenius <monty@askmonty.org>2010-07-17 01:41:44 +0300
committerMichael Widenius <monty@askmonty.org>2010-07-17 01:41:44 +0300
commite9166ca1527fb2f450584712056d081daf36517f (patch)
treea0d76e2429c63d9abafd376b00d7ea12466ee8a8
parent683154d1fa6249a8bfcde4bb9227570c452ea802 (diff)
downloadmariadb-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.cc4
-rw-r--r--sql/event_db_repository.cc10
-rw-r--r--sql/events.cc7
-rw-r--r--sql/filesort.cc3
-rw-r--r--sql/ha_partition.cc2
-rw-r--r--sql/ha_partition.h2
-rw-r--r--sql/handler.cc20
-rw-r--r--sql/handler.h3
-rw-r--r--sql/item_subselect.cc3
-rw-r--r--sql/log.cc4
-rw-r--r--sql/log_event.cc20
-rw-r--r--sql/log_event_old.cc25
-rw-r--r--sql/mysql_priv.h2
-rw-r--r--sql/opt_range.cc7
-rw-r--r--sql/records.cc14
-rw-r--r--sql/sql_acl.cc16
-rw-r--r--sql/sql_cursor.cc2
-rw-r--r--sql/sql_delete.cc14
-rw-r--r--sql/sql_help.cc29
-rw-r--r--sql/sql_plugin.cc7
-rw-r--r--sql/sql_select.cc18
-rw-r--r--sql/sql_servers.cc5
-rw-r--r--sql/sql_table.cc3
-rw-r--r--sql/sql_udf.cc8
-rw-r--r--sql/sql_update.cc43
-rw-r--r--storage/example/ha_example.cc2
-rw-r--r--storage/ibmdb2i/ha_ibmdb2i.cc4
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()