List:Commits« Previous MessageNext Message »
From:Sergey Glukhov Date:October 27 2011 8:44am
Subject:bzr push into mysql-trunk branch (sergey.glukhov:3534 to 3535) Bug#11746275
View as plain text  
 3535 Sergey Glukhov	2011-10-27
      Bug#11746275 24986: CALLS TO HANDLER::RND_INIT AND HANDLER::INDEX_INIT IGNORE RETURN VALUE
      Changes in init_read_record(), init_read_record_idx functions():
      --return type is changed from void to bool
      --added error message generation when it's necessary
     @ mysql-test/r/plugin.result
        result fix
     @ mysql-test/t/plugin.test
        test fix
     @ sql/event_db_repository.cc
        added return value check
     @ sql/events.cc
        added return value check
     @ sql/opt_range.cc
        added return value check
     @ sql/records.cc
        init_read_record(), init_read_record_idx functions():
        --return type is changed from void to bool
        --added error message generation when it's necessary
     @ sql/records.h
        init_read_record(), init_read_record_idx functions():
        return type is changed from void to bool.
     @ sql/sql_acl.cc
        added return value check
     @ sql/sql_delete.cc
        added return value check
     @ sql/sql_help.cc
        added return value check
     @ sql/sql_plugin.cc
        added return value check
     @ sql/sql_select.cc
        added return value check
     @ sql/sql_servers.cc
        added return value check
     @ sql/sql_table.cc
        added return value check
     @ sql/sql_udf.cc
        added return value check
     @ sql/sql_update.cc
        added return value check

    modified:
      mysql-test/r/plugin.result
      mysql-test/t/plugin.test
      sql/event_db_repository.cc
      sql/events.cc
      sql/opt_range.cc
      sql/records.cc
      sql/records.h
      sql/sql_acl.cc
      sql/sql_delete.cc
      sql/sql_help.cc
      sql/sql_plugin.cc
      sql/sql_select.cc
      sql/sql_servers.cc
      sql/sql_table.cc
      sql/sql_udf.cc
      sql/sql_update.cc
 3534 Sergey Glukhov	2011-10-27
      Bug#11747423 32254: INDEX MERGE USED UNNECESSARILY
      There was an assumption that quick select is always faster
      than ref access for InnoDB tables. But some test cases show
      that it's not true for index merge access. In some cases
      ref access by compound single key is better than
      index merge access by several keys. The fix is to
      add a check that INDEX MERGE access is not more expensive
      than ref access.
     @ mysql-test/r/index_merge_innodb.result
        test case
     @ mysql-test/t/index_merge_innodb.test
        test case
     @ sql/sql_select.cc
        added a check that INDEX MERGE access is not more expensive
        than ref access.

    modified:
      mysql-test/r/index_merge_innodb.result
      mysql-test/t/index_merge_innodb.test
      sql/sql_select.cc
=== modified file 'mysql-test/r/plugin.result'
--- a/mysql-test/r/plugin.result	2009-12-22 11:02:52 +0000
+++ b/mysql-test/r/plugin.result	2011-10-27 08:43:56 +0000
@@ -10,7 +10,7 @@ UNINSTALL PLUGIN example;
 INSTALL PLUGIN example SONAME 'ha_example.so';
 CREATE TABLE t1(a int) ENGINE=EXAMPLE;
 SELECT * FROM t1;
-a
+ERROR HY000: Table storage engine for 't1' doesn't have this option
 DROP TABLE t1;
 set global example_ulong_var=500;
 set global example_enum_var= e1;

=== modified file 'mysql-test/t/plugin.test'
--- a/mysql-test/t/plugin.test	2011-01-11 13:27:03 +0000
+++ b/mysql-test/t/plugin.test	2011-10-27 08:43:56 +0000
@@ -17,7 +17,7 @@ eval INSTALL PLUGIN example SONAME '$EXA
 
 CREATE TABLE t1(a int) ENGINE=EXAMPLE;
 
-# Let's do some advanced ops with the example engine :)
+--error ER_ILLEGAL_HA
 SELECT * FROM t1;
 
 DROP TABLE t1;

=== modified file 'sql/event_db_repository.cc'
--- a/sql/event_db_repository.cc	2011-07-28 10:54:44 +0000
+++ b/sql/event_db_repository.cc	2011-10-27 08:43:56 +0000
@@ -490,7 +490,8 @@ Event_db_repository::table_scan_all_for_
   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, 1, FALSE))
+    DBUG_RETURN(TRUE);
 
   /*
     rr_sequential, in read_record(), returns 137==HA_ERR_END_OF_FILE,
@@ -508,7 +509,7 @@ Event_db_repository::table_scan_all_for_
   end_read_record(&read_record_info);
 
   /*  ret is guaranteed to be != 0 */
-  DBUG_RETURN(ret == -1? FALSE:TRUE);
+  DBUG_RETURN(ret == -1 ? FALSE : TRUE);
 }
 
 
@@ -994,7 +995,8 @@ Event_db_repository::drop_schema_events(
     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, 1, FALSE))
+    DBUG_VOID_RETURN;
   while (!ret && !(read_record_info.read_record(&read_record_info)) )
   {
     char *et_field= get_field(thd->mem_root, table->field[field]);

=== modified file 'sql/events.cc'
--- a/sql/events.cc	2011-08-19 13:04:28 +0000
+++ b/sql/events.cc	2011-10-27 08:43:56 +0000
@@ -1100,7 +1100,11 @@ 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))
+  {
+    sql_print_error("Event Scheduler: Error while starting read of mysql.event");
+    DBUG_RETURN(TRUE);
+  }
   while (!(read_record_info.read_record(&read_record_info)))
   {
     Event_queue_element *et;

=== modified file 'sql/opt_range.cc'
--- a/sql/opt_range.cc	2011-10-12 12:09:14 +0000
+++ b/sql/opt_range.cc	2011-10-27 08:43:56 +0000
@@ -9350,7 +9350,8 @@ int QUICK_INDEX_MERGE_SELECT::read_keys_
   doing_pk_scan= FALSE;
   /* index_merge currently doesn't support "using index" at all */
   head->set_keyread(FALSE);
-  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))
+    DBUG_RETURN(1);
   DBUG_RETURN(result);
 }
 

=== modified file 'sql/records.cc'
--- a/sql/records.cc	2011-08-26 08:55:54 +0000
+++ b/sql/records.cc	2011-10-27 08:43:56 +0000
@@ -58,11 +58,15 @@ static int rr_index_desc(READ_RECORD *in
                       occurs (except for end-of-records error)
   @param idx          index to scan
   @param reverse      Scan in the reverse direction
+
+  @retval true   error
+  @retval false  success
 */
 
-void init_read_record_idx(READ_RECORD *info, THD *thd, TABLE *table,
+bool init_read_record_idx(READ_RECORD *info, THD *thd, TABLE *table,
                           bool print_error, uint idx, bool reverse)
 {
+  int error;
   empty_record(table);
   memset(info, 0, sizeof(*info));
   info->thd= thd;
@@ -72,10 +76,17 @@ void init_read_record_idx(READ_RECORD *i
   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));
+    return true;
+  }
+
   /* read_record will be changed to rr_index in rr_index_first */
   info->read_record= reverse ? rr_index_last : rr_index_first;
+  return false;
 }
 
 
@@ -163,12 +174,16 @@ void init_read_record_idx(READ_RECORD *i
   --------------
     This is the most basic access method of a table using rnd_init,
     ha_rnd_next and rnd_end. No indexes are used.
+
+  @retval true   error
+  @retval false  success
 */
-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)
 {
+  int error= 0;
   IO_CACHE *tempfile;
   DBUG_ENTER("init_read_record");
 
@@ -219,8 +234,9 @@ void init_read_record(READ_RECORD *info,
     info->io_cache=tempfile;
     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->inited &&
+        (error= table->file->ha_rnd_init(0)))
+      goto err;
 
     /*
       table->sort.addon_field is checked because if we use addon fields,
@@ -242,11 +258,10 @@ void init_read_record(READ_RECORD *info,
 	!table->s->blob_fields &&
         info->ref_length <= MAX_REFLENGTH)
     {
-      if (! init_rr_cache(thd, info))
-      {
-	DBUG_PRINT("info",("using rr_from_cache"));
-	info->read_record=rr_from_cache;
-      }
+      if (init_rr_cache(thd, info))
+        DBUG_RETURN(true);
+      DBUG_PRINT("info",("using rr_from_cache"));
+      info->read_record=rr_from_cache;
     }
   }
   else if (select && select->quick)
@@ -257,7 +272,8 @@ void init_read_record(READ_RECORD *info,
   else if (table->sort.record_pointers)
   {
     DBUG_PRINT("info",("using record_pointers"));
-    table->file->ha_rnd_init(0);
+    if ((error= table->file->ha_rnd_init(0)))
+      goto err;
     info->cache_pos=table->sort.record_pointers;
     info->cache_end=info->cache_pos+ 
                     table->sort.found_records*info->ref_length;
@@ -268,7 +284,8 @@ void init_read_record(READ_RECORD *info,
   {
     DBUG_PRINT("info",("using rr_sequential"));
     info->read_record=rr_sequential;
-    table->file->ha_rnd_init(1);
+    if ((error= table->file->ha_rnd_init(1)))
+      goto err;
     /* We can use record cache if we don't update dynamic length tables */
     if (!table->no_cache &&
 	(use_record_cache > 0 ||
@@ -290,7 +307,12 @@ void init_read_record(READ_RECORD *info,
       !table->file->pushed_cond)
     table->file->cond_push(select->cond);
 
-  DBUG_VOID_RETURN;
+  DBUG_RETURN(false);
+
+err:
+  if (print_error)
+    table->file->print_error(error, MYF(0));     
+  DBUG_RETURN(true);
 } /* init_read_record */
 
 

=== modified file 'sql/records.h'
--- a/sql/records.h	2011-07-28 12:53:50 +0000
+++ b/sql/records.h	2011-10-27 08:43:56 +0000
@@ -28,13 +28,16 @@ class SQL_SELECT;
   index read, scan, etc, use of cache, etc.
 
   Use by:
+@code
   READ_RECORD read_record;
-  init_read_record(&read_record, ...);
+  if (init_read_record(&read_record, ...))
+    return TRUE;
   while (read_record.read_record())
   {
     ...
   }
   end_read_record();
+@endcode
 */
 
 class Copy_field;
@@ -70,10 +73,10 @@ public:
   READ_RECORD() {}
 };
 
-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,
+bool init_read_record_idx(READ_RECORD *info, THD *thd, TABLE *table,
                           bool print_error, uint idx, bool reverse);
 void end_read_record(READ_RECORD *info);
 

=== modified file 'sql/sql_acl.cc'
--- a/sql/sql_acl.cc	2011-09-21 11:49:00 +0000
+++ b/sql/sql_acl.cc	2011-10-27 08:43:56 +0000
@@ -713,8 +713,9 @@ static my_bool acl_load(THD *thd, TABLE_
   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, 1, 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)))
@@ -763,7 +764,9 @@ static my_bool acl_load(THD *thd, TABLE_
   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, 1, 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 /
@@ -968,7 +971,9 @@ static my_bool acl_load(THD *thd, TABLE_
   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, 1, 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)))
@@ -1031,8 +1036,9 @@ static my_bool acl_load(THD *thd, TABLE_
                                50, 100);
   if (tables[3].table)
   {
-    init_read_record(&read_record_info, thd, table= tables[3].table, NULL, 1, 
-                     0, FALSE);
+    if (init_read_record(&read_record_info, thd, table= tables[3].table,
+                         NULL, 1, 1, FALSE))
+      goto end;
     table->use_all_columns();
     while (!(read_record_info.read_record(&read_record_info)))
     {

=== modified file 'sql/sql_delete.cc'
--- a/sql/sql_delete.cc	2011-07-20 10:29:12 +0000
+++ b/sql/sql_delete.cc	2011-10-27 08:43:56 +0000
@@ -311,10 +311,22 @@ bool mysql_delete(THD *thd, TABLE_LIST *
     free_underlaid_joins(thd, select_lex);
     DBUG_RETURN(TRUE);
   }
+
   if (usable_index==MAX_KEY || (select && select->quick))
-    init_read_record(&info, thd, table, select, 1, 1, FALSE);
+    error= init_read_record(&info, thd, table, select, 1, 1, FALSE);
   else
-    init_read_record_idx(&info, thd, table, 1, usable_index, reverse);
+    error= init_read_record_idx(&info, thd, table, 1, usable_index, reverse);
+
+  if (error)
+  {
+    if (select)
+    {
+      delete select;
+      select= 0;
+    }
+    free_underlaid_joins(thd, select_lex);
+    DBUG_RETURN(TRUE);
+  }
 
   init_ftfuncs(thd, select_lex, 1);
   THD_STAGE_INFO(thd, stage_updating);
@@ -935,7 +947,8 @@ int multi_delete::do_table_deletes(TABLE
   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

=== modified file 'sql/sql_help.cc'
--- a/sql/sql_help.cc	2011-07-19 15:11:15 +0000
+++ b/sql/sql_help.cc	2011-10-27 08:43:56 +0000
@@ -189,11 +189,13 @@ int search_topics(THD *thd, TABLE *topic
 		  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");
+
+  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
@@ -229,11 +231,13 @@ int search_topics(THD *thd, TABLE *topic
 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");
+
+  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
@@ -359,7 +363,10 @@ int search_categories(THD *thd, TABLE *c
 
   DBUG_ENTER("search_categories");
 
-  init_read_record(&read_record_info, thd, categories, select,1,0,FALSE);
+  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())
@@ -390,10 +397,12 @@ int search_categories(THD *thd, TABLE *c
 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);
+  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())

=== modified file 'sql/sql_plugin.cc'
--- a/sql/sql_plugin.cc	2011-09-21 11:01:41 +0000
+++ b/sql/sql_plugin.cc	2011-10-27 08:43:56 +0000
@@ -1493,7 +1493,8 @@ static void plugin_load(MEM_ROOT *tmp_ro
     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, 1, FALSE))
+    goto end;
   table->use_all_columns();
   /*
     there're no other threads running yet, so we don't need a mutex.

=== modified file 'sql/sql_select.cc'
--- a/sql/sql_select.cc	2011-10-27 08:40:40 +0000
+++ b/sql/sql_select.cc	2011-10-27 08:43:56 +0000
@@ -18839,8 +18839,9 @@ sub_select_sjm(JOIN *join, JOIN_TAB *joi
     const READ_RECORD::Setup_func saved_rfr= last_tab->read_first_record;
 
     // Initialize full scan
-    init_read_record(&last_tab->read_record, join->thd,
-                     sjm->table, NULL, TRUE, TRUE, FALSE);
+    if (init_read_record(&last_tab->read_record, join->thd,
+                         sjm->table, NULL, TRUE, TRUE, FALSE))
+      DBUG_RETURN(NESTED_LOOP_ERROR);
 
     last_tab->read_first_record= join_read_record_no_init;
     last_tab->read_record.copy_field= sjm->copy_field;
@@ -20082,8 +20083,9 @@ int join_init_read_record(JOIN_TAB *tab)
     report_error(tab->table, error);
     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);
 }
 

=== modified file 'sql/sql_servers.cc'
--- a/sql/sql_servers.cc	2011-07-28 10:54:44 +0000
+++ b/sql/sql_servers.cc	2011-10-27 08:43:56 +0000
@@ -208,8 +208,10 @@ static bool servers_load(THD *thd, TABLE
   free_root(&mem, MYF(0));
   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, 1, FALSE))
+    DBUG_RETURN(TRUE);
+
   while (!(read_record_info.read_record(&read_record_info)))
   {
     /* return_val is already TRUE, so no need to set */

=== modified file 'sql/sql_table.cc'
--- a/sql/sql_table.cc	2011-10-07 14:20:21 +0000
+++ b/sql/sql_table.cc	2011-10-27 08:43:56 +0000
@@ -7367,7 +7367,11 @@ copy_data_between_tables(TABLE *from,TAB
 
   /* Tell handler that we have values for all columns in the to table */
   to->use_all_columns();
-  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))
+  {
+    error= 1;
+    goto err;
+  }
   if (ignore)
     to->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
   thd->get_stmt_da()->reset_current_row_for_warning();

=== modified file 'sql/sql_udf.cc'
--- a/sql/sql_udf.cc	2011-06-30 15:50:45 +0000
+++ b/sql/sql_udf.cc	2011-10-27 08:43:56 +0000
@@ -171,7 +171,8 @@ 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, 1, FALSE))
+    goto end;
   table->use_all_columns();
   while (!(error= read_record_info.read_record(&read_record_info)))
   {

=== modified file 'sql/sql_update.cc'
--- a/sql/sql_update.cc	2011-09-14 15:03:55 +0000
+++ b/sql/sql_update.cc	2011-10-27 08:43:56 +0000
@@ -567,9 +567,12 @@ int mysql_update(THD *thd,
       */
 
       if (used_index == MAX_KEY || (select && select->quick))
-        init_read_record(&info, thd, table, select, 0, 1, FALSE);
+        error= init_read_record(&info, thd, table, select, 0, 1, FALSE);
       else
-        init_read_record_idx(&info, thd, table, 1, used_index, reverse);
+        error= init_read_record_idx(&info, thd, table, 1, used_index, reverse);
+
+      if (error)
+        goto exit_without_my_ok;
 
       THD_STAGE_INFO(thd, stage_searching_rows_for_update);
       ha_rows tmp_limit= limit;
@@ -640,7 +643,8 @@ int mysql_update(THD *thd,
   if (select && select->quick && select->quick->reset())
     goto exit_without_my_ok;
   table->file->try_semi_consistent_read(1);
-  init_read_record(&info, thd, table, select, 0, 1, FALSE);
+  if ((error= init_read_record(&info, thd, table, select, 0, 1, FALSE)))
+    goto exit_without_my_ok;
 
   updated= found= 0;
   /*

No bundle (reason: useless for push emails).
Thread
bzr push into mysql-trunk branch (sergey.glukhov:3534 to 3535) Bug#11746275Sergey Glukhov27 Oct