#At file:///opt/local/work/mysql-6.0-records/
2700 Konstantin Osipov 2008-08-16
WL#3288, work in progress.
modified:
BUILD/SETUP.sh
mysql-test/include/mix1.inc
sql/event_db_repository.cc
sql/events.cc
sql/item_subselect.cc
sql/mysql_priv.h
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_select.h
sql/sql_servers.cc
sql/sql_table.cc
sql/sql_udf.cc
sql/sql_update.cc
=== modified file 'BUILD/SETUP.sh'
--- a/BUILD/SETUP.sh 2008-07-25 17:21:55 +0000
+++ b/BUILD/SETUP.sh 2008-08-16 19:36:24 +0000
@@ -105,7 +105,7 @@ if [ "x$warning_mode" != "xpedantic" ];
cxx_warnings="$cxx_warnings -Wreorder"
cxx_warnings="$cxx_warnings -Wctor-dtor-privacy -Wnon-virtual-dtor"
# Added unless --with-debug=full
- debug_extra_cflags="-O1 -Wuninitialized"
+ debug_extra_cflags="-O0"
else
warnings="-W -Wall -ansi -pedantic -Wno-long-long -Wno-unused -D_POSIX_SOURCE"
c_warnings="$warnings"
=== modified file 'mysql-test/include/mix1.inc'
--- a/mysql-test/include/mix1.inc 2008-07-17 19:55:18 +0000
+++ b/mysql-test/include/mix1.inc 2008-08-16 19:36:24 +0000
@@ -941,7 +941,7 @@ drop table t1;
#
# Bug #28570: handler::index_read() is called with different find_flag when
-# ORDER BY is used
+# ORDER BY is use
#
CREATE TABLE t1 (
=== modified file 'sql/event_db_repository.cc'
--- a/sql/event_db_repository.cc 2008-07-17 19:55:18 +0000
+++ b/sql/event_db_repository.cc 2008-08-16 19:36:24 +0000
@@ -452,7 +452,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, 0, FALSE))
+ DBUG_RETURN(TRUE);
/*
rr_sequential, in read_record(), returns 137==HA_ERR_END_OF_FILE,
@@ -461,7 +462,7 @@ Event_db_repository::table_scan_all_for_
*/
do
{
- ret= read_record_info.read_record(&read_record_info);
+ ret= read_record_info.read_record();
if (ret == 0)
ret= copy_event_to_schema_table(thd, schema_table, event_table);
} while (ret == 0);
@@ -925,9 +926,11 @@ Event_db_repository::drop_events_by_fiel
if (open_event_table(thd, TL_WRITE, &table))
DBUG_VOID_RETURN;
+ if (init_read_record(&read_record_info, thd, table, NULL, 1, 0, FALSE))
+ DBUG_VOID_RETURN; /* Out of resources. */
+
/* 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);
- while (!ret && !(read_record_info.read_record(&read_record_info)) )
+ while (!ret && !(read_record_info.read_record()) )
{
char *et_field= get_field(thd->mem_root, table->field[field]);
=== modified file 'sql/events.cc'
--- a/sql/events.cc 2008-08-07 17:52:43 +0000
+++ b/sql/events.cc 2008-08-16 19:36:24 +0000
@@ -1118,8 +1118,9 @@ Events::load_events_from_db(THD *thd)
DBUG_RETURN(TRUE);
}
- init_read_record(&read_record_info, thd, table, NULL, 0, 1, FALSE);
- while (!(read_record_info.read_record(&read_record_info)))
+ if (init_read_record(&read_record_info, thd, table, NULL, 0, 1, FALSE))
+ DBUG_RETURN(TRUE); /* Out of resources. */
+ while (!(read_record_info.read_record()))
{
Event_queue_element *et;
bool created;
=== modified file 'sql/item_subselect.cc'
--- a/sql/item_subselect.cc 2008-07-24 10:00:56 +0000
+++ b/sql/item_subselect.cc 2008-08-16 19:36:24 +0000
@@ -2283,17 +2283,20 @@ int subselect_single_select_engine::exec
{
for (uint i= 0; i < tab->ref.key_parts; i++)
{
- bool *cond_guard= tab->ref.cond_guards[i];
+ bool *cond_guard= tab->ref.cond_guard.guard_list[i];
if (cond_guard && !*cond_guard)
{
- /* Change the access method to full table scan */
- tab->save_read_first_record= tab->read_first_record;
- tab->save_read_record= tab->read_record.read_record;
- tab->read_record.read_record= rr_sequential;
+ READ_RECORD *full_scan_info= &tab->ref.cond_guard.full_scan_info;
+ if (! full_scan_info->is_initialized())
+ {
+ full_scan_info->set_read_record_func(tab->table, rr_sequential);
+ full_scan_info->ref_length= tab->table->file->ref_length;
+ full_scan_info->print_error= tab->read_record.print_error;
+ tab->ref.cond_guard.save_read_first_record= tab->read_first_record;
+ }
tab->read_first_record= read_first_record_seq;
- tab->read_record.record= tab->table->record[0];
- tab->read_record.thd= join->thd;
- tab->read_record.ref_length= tab->table->file->ref_length;
+ full_scan_info->swap(tab->read_record);
+
*(last_changed_tab++)= tab;
break;
}
@@ -2301,17 +2304,15 @@ int subselect_single_select_engine::exec
}
}
}
-
+
join->exec();
/* Enable the optimizations back */
for (JOIN_TAB **ptab= changed_tabs; ptab != last_changed_tab; ptab++)
{
JOIN_TAB *tab= *ptab;
- tab->read_record.record= 0;
- tab->read_record.ref_length= 0;
- tab->read_first_record= tab->save_read_first_record;
- tab->read_record.read_record= tab->save_read_record;
+ tab->read_record.swap(tab->ref.cond_guard.full_scan_info);
+ tab->read_first_record= tab->ref.cond_guard.save_read_first_record;
}
executed= 1;
thd->where= save_where;
=== modified file 'sql/mysql_priv.h'
--- a/sql/mysql_priv.h 2008-08-11 12:40:09 +0000
+++ b/sql/mysql_priv.h 2008-08-16 19:36:24 +0000
@@ -2267,12 +2267,6 @@ ulonglong get_datetime_value(THD *thd, I
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,
- 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 print_error, uint idx);
-void end_read_record(READ_RECORD *info);
ha_rows filesort(THD *thd, TABLE *form,struct st_sort_field *sortorder,
uint s_length, SQL_SELECT *select,
ha_rows max_rows, bool sort_positions,
=== modified file 'sql/opt_range.cc'
--- a/sql/opt_range.cc 2008-07-17 19:55:18 +0000
+++ b/sql/opt_range.cc 2008-08-16 19:36:24 +0000
@@ -1177,7 +1177,6 @@ QUICK_INDEX_MERGE_SELECT::QUICK_INDEX_ME
DBUG_ENTER("QUICK_INDEX_MERGE_SELECT::QUICK_INDEX_MERGE_SELECT");
index= MAX_KEY;
head= table;
- bzero(&read_record, sizeof(read_record));
init_sql_alloc(&alloc, thd->variables.range_alloc_block_size, 0);
DBUG_VOID_RETURN;
}
@@ -1215,6 +1214,7 @@ QUICK_INDEX_MERGE_SELECT::~QUICK_INDEX_M
QUICK_RANGE_SELECT* quick;
DBUG_ENTER("QUICK_INDEX_MERGE_SELECT::~QUICK_INDEX_MERGE_SELECT");
quick_it.rewind();
+ end_read_record(&read_record);
while ((quick= quick_it++))
quick->file= NULL;
quick_selects.delete_elements();
@@ -8109,7 +8109,8 @@ int QUICK_INDEX_MERGE_SELECT::read_keys_
doing_pk_scan= FALSE;
/* index_merge currently doesn't support "using index" at all */
file->extra(HA_EXTRA_NO_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))
+ DBUG_RETURN(1);
DBUG_RETURN(result);
}
@@ -8131,7 +8132,7 @@ int QUICK_INDEX_MERGE_SELECT::get_next()
if (doing_pk_scan)
DBUG_RETURN(pk_quick_select->get_next());
- if ((result= read_record.read_record(&read_record)) == -1)
+ if ((result= read_record.read_record()) == -1)
{
result= HA_ERR_END_OF_FILE;
end_read_record(&read_record);
=== modified file 'sql/records.cc'
--- a/sql/records.cc 2008-08-11 12:40:09 +0000
+++ b/sql/records.cc 2008-08-16 19:36:24 +0000
@@ -25,8 +25,34 @@
*/
#include "records.h"
+
#include "mysql_priv.h"
+void READ_RECORD::clear_read_record()
+{
+ bzero(this, sizeof(*this));
+}
+
+
+void READ_RECORD::set_read_record_func(TABLE *table_arg, Read_func read_func)
+{
+ DBUG_ASSERT(m_is_initialized == FALSE);
+ table= table_arg;
+ file= table->file;
+ record= table->record[0];
+ thd= table->in_use;
+ m_read_record= read_func;
+ m_is_initialized= TRUE;
+}
+
+
+void READ_RECORD::swap(READ_RECORD &other)
+{
+ READ_RECORD tmp(other);
+ other= *this;
+ *this= tmp;
+ tmp.m_is_initialized= FALSE; /* prevent the assert */
+}
static int rr_quick(READ_RECORD *info);
int rr_sequential(READ_RECORD *info);
@@ -34,9 +60,11 @@ static int rr_from_tempfile(READ_RECORD
static int rr_unpack_from_tempfile(READ_RECORD *info);
static int rr_unpack_from_buffer(READ_RECORD *info);
static int rr_from_pointers(READ_RECORD *info);
+#ifdef NOT_USED
static int rr_from_cache(READ_RECORD *info);
static int init_rr_cache(THD *thd, READ_RECORD *info);
static int rr_cmp(uchar *a,uchar *b);
+#endif
static int rr_index_first(READ_RECORD *info);
static int rr_index(READ_RECORD *info);
@@ -57,21 +85,19 @@ static int rr_index(READ_RECORD *info);
@param idx index to scan
*/
-void init_read_record_idx(READ_RECORD *info, THD *thd, TABLE *table,
- bool print_error, uint idx)
+bool
+init_read_record_idx(READ_RECORD *info, THD *thd, TABLE *table,
+ bool print_error, uint idx)
{
empty_record(table);
- bzero((char*) info,sizeof(*info));
- info->table= table;
- info->file= table->file;
- info->record= table->record[0];
info->print_error= print_error;
table->status=0; /* And it's always found */
if (!table->file->inited)
table->file->ha_index_init(idx, 1);
/* read_record will be changed to rr_index in rr_index_first */
- info->read_record= rr_index_first;
+ info->set_read_record_func(table, rr_index_first);
+ return FALSE;
}
@@ -160,7 +186,9 @@ void init_read_record_idx(READ_RECORD *i
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)
@@ -168,16 +196,10 @@ void init_read_record(READ_RECORD *info,
IO_CACHE *tempfile;
DBUG_ENTER("init_read_record");
- bzero((char*) info,sizeof(*info));
- info->thd=thd;
- info->table=table;
- info->file= table->file;
- info->forms= &info->table; /* Only one table */
-
if (table->s->tmp_table == NON_TRANSACTIONAL_TMP_TABLE &&
!table->sort.addon_field)
(void) table->file->extra(HA_EXTRA_MMAP);
-
+
if (table->sort.addon_field)
{
info->rec_buf= table->sort.addon_buf;
@@ -186,10 +208,8 @@ void init_read_record(READ_RECORD *info,
else
{
empty_record(table);
- info->record= table->record[0];
info->ref_length= table->file->ref_length;
}
- info->select=select;
info->print_error=print_error;
info->ignore_not_found_rows= 0;
table->status=0; /* And it's always found */
@@ -201,8 +221,9 @@ void init_read_record(READ_RECORD *info,
if (tempfile && my_b_inited(tempfile)) // Test if ref-records was used
{
DBUG_PRINT("info",("using rr_from_tempfile"));
- info->read_record= (table->sort.addon_field ?
- rr_unpack_from_tempfile : rr_from_tempfile);
+ info->set_read_record_func(table,
+ table->sort.addon_field ?
+ rr_unpack_from_tempfile : rr_from_tempfile);
info->io_cache=tempfile;
reinit_io_cache(info->io_cache,READ_CACHE,0L,0,0);
info->ref_pos=table->file->ref;
@@ -229,17 +250,24 @@ void init_read_record(READ_RECORD *info,
!table->s->blob_fields &&
info->ref_length <= MAX_REFLENGTH)
{
+ DBUG_ASSERT(0); /* The condition above is impossible. */
+ /* Leave the read type unchanged in production. */
+#ifdef NOT_USED
if (! init_rr_cache(thd, info))
{
DBUG_PRINT("info",("using rr_from_cache"));
- info->read_record=rr_from_cache;
+ info->set_read_record_func(table, rr_from_cache);
}
+#endif
}
}
else if (select && select->quick)
{
DBUG_PRINT("info",("using rr_quick"));
- info->read_record=rr_quick;
+ if (select->quick->reset())
+ DBUG_RETURN(TRUE);
+ info->select= select;
+ info->set_read_record_func(table, rr_quick);
}
else if (table->sort.record_pointers)
{
@@ -248,13 +276,14 @@ void init_read_record(READ_RECORD *info,
info->cache_pos=table->sort.record_pointers;
info->cache_end=info->cache_pos+
table->sort.found_records*info->ref_length;
- info->read_record= (table->sort.addon_field ?
- rr_unpack_from_buffer : rr_from_pointers);
+ info->set_read_record_func(table,
+ table->sort.addon_field ?
+ rr_unpack_from_buffer : rr_from_pointers);
}
else
{
DBUG_PRINT("info",("using rr_sequential"));
- info->read_record=rr_sequential;
+ info->set_read_record_func(table, rr_sequential);
table->file->ha_rnd_init(1);
/* We can use record cache if we don't update dynamic length tables */
if (!table->no_cache &&
@@ -277,10 +306,46 @@ void init_read_record(READ_RECORD *info,
!table->file->pushed_cond)
table->file->cond_push(select->cond);
- DBUG_VOID_RETURN;
+ DBUG_RETURN(FALSE);
} /* init_read_record */
+/**
+ Reset READ_RECORD structure between two sweeps of the nested join
+ loop.
+*/
+
+bool
+reset_read_record(READ_RECORD *info)
+{
+ TABLE *table= info->table;
+ SQL_SELECT *select= info->select;
+ DBUG_ENTER("reset_read_record");
+
+ empty_record(table);
+ table->status=0;
+
+ if (info->io_cache && my_b_inited(info->io_cache))
+ {
+ reinit_io_cache(info->io_cache,READ_CACHE,0L,0,0);
+ }
+ else if (select && select->quick)
+ {
+ if (select->quick->reset())
+ DBUG_RETURN(TRUE);
+ }
+ else if (table->sort.record_pointers)
+ {
+ info->cache_pos= table->sort.record_pointers;
+ }
+ else
+ {
+ table->file->ha_index_or_rnd_end();
+ table->file->ha_rnd_init(1);
+ }
+ DBUG_RETURN(FALSE);
+}
+
void end_read_record(READ_RECORD *info)
{ /* free cache if used */
@@ -293,10 +358,10 @@ void end_read_record(READ_RECORD *info)
{
filesort_free_buffers(info->table,0);
(void) info->file->extra(HA_EXTRA_NO_CACHE);
- if (info->read_record != rr_quick) // otherwise quick_range does it
- (void) info->file->ha_index_or_rnd_end();
+ (void) info->file->ha_index_or_rnd_end();
info->table=0;
}
+ info->clear_read_record();
}
static int rr_handle_error(READ_RECORD *info, int error)
@@ -351,10 +416,14 @@ static int rr_quick(READ_RECORD *info)
static int rr_index_first(READ_RECORD *info)
{
+ READ_RECORD backup= *info;
int tmp= info->file->index_first(info->record);
- info->read_record= rr_index;
if (tmp)
tmp= rr_handle_error(info, tmp);
+ info->clear_read_record();
+ info->set_read_record_func(backup.table, rr_index);
+ info->print_error= backup.print_error;
+ backup.clear_read_record();
return tmp;
}
@@ -505,6 +574,9 @@ static int rr_unpack_from_buffer(READ_RE
return 0;
}
+
+
+#ifdef NOT_USED
/* cacheing of records from a database */
static int init_rr_cache(THD *thd, READ_RECORD *info)
@@ -636,3 +708,4 @@ static int rr_cmp(uchar *a,uchar *b)
return (int) a[7] - (int) b[7];
#endif
}
+#endif /* NOT_USED */
=== modified file 'sql/records.h'
--- a/sql/records.h 2008-08-11 12:40:09 +0000
+++ b/sql/records.h 2008-08-16 19:36:24 +0000
@@ -47,30 +47,47 @@ struct READ_RECORD
TABLE *table; /* Head-form */
handler *file;
- TABLE **forms; /* head and ref forms */
- Read_func read_record;
THD *thd;
SQL_SELECT *select;
- uint cache_records;
- uint ref_length,struct_length,reclength,rec_cache_size,error_offset;
+ uint ref_length;
+#ifdef NOT_USED
+ uint cache_records,struct_length,reclength,rec_cache_size,error_offset;
+#endif
uint index;
uchar *ref_pos; /* pointer to form->refpos */
uchar *record;
uchar *rec_buf; /* to read field values after filesort */
- uchar *cache,*cache_pos,*cache_end,*read_positions;
+ uchar *cache,*cache_pos,*cache_end;
+#ifdef NOT_USED
+ uchar *read_positions;
+#endif
struct st_io_cache *io_cache;
bool print_error, ignore_not_found_rows;
struct st_join_table *do_insideout_scan;
-
public:
- READ_RECORD() {}
+ READ_RECORD() { clear_read_record(); }
+ ~READ_RECORD() { DBUG_ASSERT(is_initialized() == FALSE); }
+
+ void clear_read_record();
+
+ void set_read_record_func(TABLE *table, Read_func read_func);
+ int read_record() { return m_read_record(this); }
+ bool is_initialized() const { return m_is_initialized; }
+
+ void swap(READ_RECORD &rhs);
+private:
+ bool m_is_initialized;
+ Read_func m_read_record;
};
-void 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(READ_RECORD *info, THD *thd, TABLE *reg_form,
+ SQL_SELECT *select, int use_record_cache,
+ bool print_errors, bool disable_rr_cache);
+
+bool init_read_record_idx(READ_RECORD *info, THD *thd, TABLE *table,
bool print_error, uint idx);
void end_read_record(READ_RECORD *info);
+bool reset_read_record(READ_RECORD *info);
#endif /* SQL_RECORDS_H */
=== modified file 'sql/sql_acl.cc'
--- a/sql/sql_acl.cc 2008-08-07 17:52:43 +0000
+++ b/sql/sql_acl.cc 2008-08-16 19:36:24 +0000
@@ -324,11 +324,12 @@ 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,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)))
+ while (!(read_record_info.read_record()))
{
ACL_HOST host;
update_hostname(&host.host,get_field(&mem, table->field[0]));
@@ -374,7 +375,8 @@ 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,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 /
@@ -419,7 +421,7 @@ static my_bool acl_load(THD *thd, TABLE_
}
allow_all_hosts=0;
- while (!(read_record_info.read_record(&read_record_info)))
+ while (!(read_record_info.read_record()))
{
ACL_USER user;
update_hostname(&user.host, get_field(&mem, table->field[0]));
@@ -562,10 +564,11 @@ 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,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)))
+ while (!(read_record_info.read_record()))
{
ACL_DB db;
update_hostname(&db.host,get_field(&mem,
table->field[MYSQL_DB_FIELD_HOST]));
=== modified file 'sql/sql_delete.cc'
--- a/sql/sql_delete.cc 2008-07-26 16:38:20 +0000
+++ b/sql/sql_delete.cc 2008-08-16 19:36:24 +0000
@@ -239,17 +239,17 @@ bool mysql_delete(THD *thd, TABLE_LIST *
}
}
- /* If quick select is used, initialize it before retrieving rows. */
- if (select && select->quick && select->quick->reset())
+ if (usable_index==MAX_KEY)
+ error= init_read_record(&info, thd, table, select, 1, 1, FALSE);
+ else
+ error= init_read_record_idx(&info, thd, table, 1, usable_index);
+
+ if (error)
{
delete select;
free_underlaid_joins(thd, select_lex);
goto err;
}
- if (usable_index==MAX_KEY)
- init_read_record(&info, thd, table, select, 1, 1, FALSE);
- else
- init_read_record_idx(&info, thd, table, 1, usable_index);
init_ftfuncs(thd, select_lex, 1);
thd_proc_info(thd, "updating");
@@ -277,8 +277,7 @@ bool mysql_delete(THD *thd, TABLE_LIST *
table->mark_columns_needed_for_delete();
- while (!(error=info.read_record(&info)) && !thd->killed &&
- ! thd->is_error())
+ while (!(error= info.read_record()) && !thd->killed && !
thd->is_error())
{
// thd->is_error() is tested to disallow delete row on error
if (!(select && select->skip_record())&& ! thd->is_error() )
@@ -837,21 +836,26 @@ int multi_delete::do_deletes()
{
ha_rows last_deleted= deleted;
TABLE *table = table_being_deleted->table;
+ READ_RECORD info;
+
if (tempfiles[counter]->get(table))
{
local_error=1;
break;
}
- READ_RECORD info;
- init_read_record(&info, thd, table, NULL, 0, 1, FALSE);
+ if (init_read_record(&info, thd, table, NULL, 0, 1, FALSE))
+ {
+ local_error= 1;
+ break;
+ }
/*
Ignore any rows not found in reference tables as they may already have
been deleted by foreign key handling
*/
info.ignore_not_found_rows= 1;
will_batch= !table->file->start_bulk_delete();
- while (!(local_error=info.read_record(&info)) && !thd->killed)
+ while (!(local_error= info.read_record()) && !thd->killed)
{
if (table->triggers &&
table->triggers->process_triggers(thd, TRG_EVENT_DELETE,
=== modified file 'sql/sql_help.cc'
--- a/sql/sql_help.cc 2008-08-07 17:52:43 +0000
+++ b/sql/sql_help.cc 2008-08-16 19:36:24 +0000
@@ -186,8 +186,9 @@ int search_topics(THD *thd, TABLE *topic
int count= 0;
READ_RECORD read_record_info;
- init_read_record(&read_record_info, thd, topics, select, 1, 0, FALSE);
- while (!read_record_info.read_record(&read_record_info))
+ if (init_read_record(&read_record_info, thd, topics, select, 1, 0, FALSE))
+ DBUG_RETURN(0); /* Out of resources. */
+ while (!read_record_info.read_record())
{
if (!select->cond->val_int()) // Doesn't match like
continue;
@@ -226,8 +227,9 @@ int search_keyword(THD *thd, TABLE *keyw
int count= 0;
READ_RECORD read_record_info;
- init_read_record(&read_record_info, thd, keywords, select, 1, 0, FALSE);
- while (!read_record_info.read_record(&read_record_info) && count<2)
+ if (init_read_record(&read_record_info, thd, keywords, select, 1, 0, FALSE))
+ DBUG_RETURN(0); /* Out of resources. */
+ while (!read_record_info.read_record() && count<2)
{
if (!select->cond->val_int()) // Dosn't match like
continue;
@@ -350,8 +352,9 @@ int search_categories(THD *thd, TABLE *c
DBUG_ENTER("search_categories");
- init_read_record(&read_record_info, thd, categories, select,1,0,FALSE);
- while (!read_record_info.read_record(&read_record_info))
+ if (init_read_record(&read_record_info, thd, categories, select,1,0,FALSE))
+ DBUG_RETURN(0); /* Out of resources */
+ while (!read_record_info.read_record())
{
if (select && !select->cond->val_int())
continue;
@@ -384,8 +387,9 @@ void get_all_items_for_category(THD *thd
DBUG_ENTER("get_all_items_for_category");
READ_RECORD read_record_info;
- init_read_record(&read_record_info, thd, items, select,1,0,FALSE);
- while (!read_record_info.read_record(&read_record_info))
+ if (init_read_record(&read_record_info, thd, items, select,1,0,FALSE))
+ DBUG_VOID_RETURN; /* Do nothing if out of resources. */
+ while (!read_record_info.read_record())
{
if (!select->cond->val_int())
continue;
@@ -559,6 +563,7 @@ int send_variant_2_list(MEM_ROOT *mem_ro
# created SQL_SELECT
*/
+static
SQL_SELECT *prepare_simple_select(THD *thd, Item *cond,
TABLE *table, int *error)
{
@@ -569,8 +574,7 @@ SQL_SELECT *prepare_simple_select(THD *t
table->covering_keys.clear_all();
SQL_SELECT *res= make_select(table, 0, 0, cond, 0, error);
- if (*error || (res && res->check_quick(thd, 0, HA_POS_ERROR)) ||
- (res && res->quick && res->quick->reset()))
+ if (*error || (res && res->check_quick(thd, 0, HA_POS_ERROR)))
{
delete res;
res=0;
=== modified file 'sql/sql_plugin.cc'
--- a/sql/sql_plugin.cc 2008-07-17 19:55:18 +0000
+++ b/sql/sql_plugin.cc 2008-08-16 19:36:24 +0000
@@ -1367,7 +1367,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, 0, FALSE))
+ goto end;
table->use_all_columns();
/*
there're no other threads running yet, so we don't need a mutex.
@@ -1376,7 +1377,7 @@ static void plugin_load(MEM_ROOT *tmp_ro
the mutex here to satisfy the assert
*/
pthread_mutex_lock(&LOCK_plugin);
- while (!(error= read_record_info.read_record(&read_record_info)))
+ while (!(error= read_record_info.read_record()))
{
DBUG_PRINT("info", ("init plugin record"));
String str_name, str_dl;
=== modified file 'sql/sql_select.cc'
--- a/sql/sql_select.cc 2008-08-07 17:52:43 +0000
+++ b/sql/sql_select.cc 2008-08-16 19:36:24 +0000
@@ -883,7 +883,7 @@ static void save_index_subquery_explain_
join_tab->packed_info |= TAB_INFO_USING_WHERE;
for (uint i = 0; i < join_tab->ref.key_parts; i++)
{
- if (join_tab->ref.cond_guards[i])
+ if (join_tab->ref.cond_guard.guard_list[i])
{
join_tab->packed_info |= TAB_INFO_FULL_SCAN_ON_NULL;
break;
@@ -7033,7 +7033,7 @@ static bool create_ref_for_key(JOIN *joi
!(j->ref.key_copy= (store_key**) thd->alloc((sizeof(store_key*) *
(keyparts+1)))) ||
!(j->ref.items= (Item**) thd->alloc(sizeof(Item*)*keyparts)) ||
- !(j->ref.cond_guards= (bool**) thd->alloc(sizeof(uint*)*keyparts)))
+ !(j->ref.cond_guard.guard_list= (bool**) thd->alloc(sizeof(bool*)*keyparts)))
{
DBUG_RETURN(TRUE);
}
@@ -7050,7 +7050,7 @@ static bool create_ref_for_key(JOIN *joi
{
j->ref.items[0]=((Item_func*)(keyuse->val))->key_item();
/* Predicates pushed down into subquery can't be used FT access */
- j->ref.cond_guards[0]= NULL;
+ j->ref.cond_guard.guard_list[0]= NULL;
if (keyuse->used_tables)
DBUG_RETURN(TRUE); // not supported yet. SerG
@@ -7067,7 +7067,7 @@ static bool create_ref_for_key(JOIN *joi
uint maybe_null= test(keyinfo->key_part[i].null_bit);
j->ref.items[i]=keyuse->val; // Save for cond removal
- j->ref.cond_guards[i]= keyuse->cond_guard;
+ j->ref.cond_guard.guard_list[i]= keyuse->cond_guard;
if (keyuse->null_rejecting)
j->ref.null_rejecting |= 1 << i;
keyuse_uses_no_tables= keyuse_uses_no_tables && !keyuse->used_tables;
@@ -7214,7 +7214,7 @@ make_simple_join(JOIN *join,TABLE *tmp_t
if (!join->join_tab_reexec)
{
if (!(join->join_tab_reexec=
- (JOIN_TAB*) join->thd->alloc(sizeof(JOIN_TAB))))
+ (JOIN_TAB*) join->thd->calloc(sizeof(JOIN_TAB))))
DBUG_RETURN(TRUE); /* purecov: inspected */
if (join->tmp_join)
join->tmp_join->join_tab_reexec= join->join_tab_reexec;
@@ -7255,7 +7255,9 @@ make_simple_join(JOIN *join,TABLE *tmp_t
join_tab->ref.key_parts= 0;
join_tab->flush_weedout_table= join_tab->check_weed_out_table= NULL;
join_tab->do_firstmatch= NULL;
- bzero((char*) &join_tab->read_record,sizeof(join_tab->read_record));
+ DBUG_ASSERT(join_tab->read_record.is_initialized() == FALSE);
+ /* Don't take chances in production */
+ join_tab->read_record.clear_read_record();
tmp_table->status=0;
tmp_table->null_row=0;
DBUG_RETURN(FALSE);
@@ -8277,8 +8279,6 @@ make_join_readinfo(JOIN *join, ulonglong
JOIN_TAB *tab=join->join_tab+i;
TABLE *table=tab->table;
bool using_join_cache;
- tab->read_record.table= table;
- tab->read_record.file=table->file;
tab->next_select=sub_select; /* normal select */
/*
TODO: don't always instruct first table's ref/range access method to
@@ -8297,12 +8297,12 @@ make_join_readinfo(JOIN *join, ulonglong
case JT_SYSTEM: // Only happens with left join
table->status=STATUS_NO_RECORD;
tab->read_first_record= join_read_system;
- tab->read_record.read_record= join_no_more_records;
+ tab->read_record.set_read_record_func(table, join_no_more_records);
break;
case JT_CONST: // Only happens with left join
table->status=STATUS_NO_RECORD;
tab->read_first_record= join_read_const;
- tab->read_record.read_record= join_no_more_records;
+ tab->read_record.set_read_record_func(table, join_no_more_records);
if (table->covering_keys.is_set(tab->ref.key) &&
!table->no_keyread)
{
@@ -8320,7 +8320,7 @@ make_join_readinfo(JOIN *join, ulonglong
delete tab->quick;
tab->quick=0;
tab->read_first_record= join_read_key;
- tab->read_record.read_record= join_no_more_records;
+ tab->read_record.set_read_record_func(table, join_no_more_records);
if (table->covering_keys.is_set(tab->ref.key) &&
!table->no_keyread)
{
@@ -8351,19 +8351,23 @@ make_join_readinfo(JOIN *join, ulonglong
if (tab->type == JT_REF)
{
tab->read_first_record= join_read_always_key;
- tab->read_record.read_record= tab->insideout_match_tab?
- join_read_next_same_diff : join_read_next_same;
+ tab->read_record.
+ set_read_record_func(table,
+ tab->insideout_match_tab?
+ join_read_next_same_diff : join_read_next_same);
}
else
{
tab->read_first_record= join_read_always_key_or_null;
- tab->read_record.read_record= join_read_next_same_or_null;
+ tab->read_record.set_read_record_func(table,
+ join_read_next_same_or_null);
}
break;
case JT_FT:
table->status=STATUS_NO_RECORD;
tab->read_first_record= join_ft_read_first;
- tab->read_record.read_record= join_ft_read_next;
+ tab->read_record.set_read_record_func(table,
+ join_ft_read_next);
break;
case JT_ALL:
/*
@@ -8531,6 +8535,7 @@ void JOIN_TAB::cleanup()
table->reginfo.join_tab= 0;
}
end_read_record(&read_record);
+ end_read_record(&ref.cond_guard.full_scan_info);
}
@@ -13646,7 +13651,7 @@ sub_select(JOIN *join,JOIN_TAB *join_tab
*/
while (rc == NESTED_LOOP_OK && join->return_tab >= join_tab)
{
- error= info->read_record(info);
+ error= info->read_record();
rc= evaluate_join_record(join, join_tab, error);
}
@@ -14032,7 +14037,7 @@ flush_cached_records(JOIN *join,JOIN_TAB
}
}
}
- } while (!(error=info->read_record(info)));
+ } while (!(error=info->read_record()));
if (skip_last)
read_cached_record(join_tab); // Restore current record
@@ -14448,9 +14453,20 @@ join_read_prev_same(READ_RECORD *info)
static int
join_init_quick_read_record(JOIN_TAB *tab)
{
- if (test_if_quick_select(tab) == -1)
+ delete tab->select->quick;
+ tab->select->quick=0;
+ if (tab->read_record.is_initialized())
+ end_read_record(&tab->read_record);
+
+ if (tab->select->test_quick_select(tab->join->thd, tab->keys,
+ (table_map) 0, HA_POS_ERROR, 0,
+ FALSE) == -1)
return -1; /* No possible records */
- return join_init_read_record(tab);
+
+ if (init_read_record(&tab->read_record, tab->join->thd, tab->table,
+ tab->select,1,1, FALSE))
+ return 1; /* Out of resources. */
+ return tab->read_record.read_record();
}
@@ -14458,7 +14474,7 @@ int read_first_record_seq(JOIN_TAB *tab)
{
if (tab->read_record.file->ha_rnd_init(1))
return 1;
- return (*tab->read_record.read_record)(&tab->read_record);
+ return tab->read_record.read_record();
}
static int
@@ -14475,11 +14491,19 @@ test_if_quick_select(JOIN_TAB *tab)
static int
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);
- return (*tab->read_record.read_record)(&tab->read_record);
+ if (! tab->read_record.is_initialized())
+ {
+ if (init_read_record(&tab->read_record, tab->join->thd, tab->table,
+ tab->select,1,1, FALSE))
+ return 1; /* Out of resources. */
+ }
+ else
+ {
+ if (reset_read_record(&tab->read_record))
+ return 1; /* Out of resources. */
+ }
+
+ return tab->read_record.read_record();
}
@@ -14487,7 +14511,11 @@ static int
join_read_first(JOIN_TAB *tab)
{
int error;
- TABLE *table=tab->table;
+ TABLE *table= tab->table;
+
+ if (tab->read_record.is_initialized())
+ goto read;
+
if (!table->key_read && table->covering_keys.is_set(tab->index)
&&
!table->no_keyread)
{
@@ -14495,23 +14523,27 @@ join_read_first(JOIN_TAB *tab)
table->file->extra(HA_EXTRA_KEYREAD);
}
tab->table->status=0;
- tab->read_record.table=table;
- tab->read_record.file=table->file;
tab->read_record.index=tab->index;
- tab->read_record.record=table->record[0];
if (tab->insideout_match_tab)
{
tab->read_record.do_insideout_scan= tab;
- tab->read_record.read_record=join_read_next_different;
+ tab->read_record.set_read_record_func(table, join_read_next_different);
tab->insideout_match_tab->found_match= 0;
}
else
{
- tab->read_record.read_record=join_read_next;
+ tab->read_record.set_read_record_func(table, join_read_next);
tab->read_record.do_insideout_scan= 0;
}
- if (!table->file->inited)
+ DBUG_ASSERT( !table->file->inited);
+read:
+ /*
+ In case of a correlated subquery, we may have inited= false,
+ m_initialied= TRUE. In case of a nested iteration of a join
+ loop, we may have both true.
+ */
+ if (! table->file->inited)
table->file->ha_index_init(tab->index, tab->sorted);
if ((error=tab->table->file->index_first(tab->table->record[0])))
{
@@ -14564,21 +14596,24 @@ join_read_last(JOIN_TAB *tab)
{
TABLE *table=tab->table;
int error;
+
+ if (tab->read_record.is_initialized())
+ goto read;
+
if (!table->key_read && table->covering_keys.is_set(tab->index)
&&
!table->no_keyread)
{
table->key_read=1;
table->file->extra(HA_EXTRA_KEYREAD);
}
- tab->table->status=0;
- tab->read_record.read_record=join_read_prev;
- tab->read_record.table=table;
- tab->read_record.file=table->file;
+ tab->read_record.set_read_record_func(table, join_read_prev);
tab->read_record.index=tab->index;
- tab->read_record.record=table->record[0];
- if (!table->file->inited)
+ DBUG_ASSERT (!table->file->inited);
+read:
+ table->status=0;
+ if (! table->file->inited)
table->file->ha_index_init(tab->index, 1);
- if ((error= tab->table->file->index_last(tab->table->record[0])))
+ if ((error= table->file->index_last(table->record[0])))
return report_error(table, error);
return 0;
}
@@ -15406,7 +15441,7 @@ part_of_refkey(TABLE *table,Field *field
for (part=0 ; part < ref_parts ; part++)
{
- if (table->reginfo.join_tab->ref.cond_guards[part])
+ if (table->reginfo.join_tab->ref.cond_guard.guard_list[part])
return 0;
}
@@ -16137,6 +16172,8 @@ test_if_skip_sort_order(JOIN_TAB *tab,OR
{
if (!quick_created)
{
+ table->file->ha_index_or_rnd_end();
+ end_read_record(&tab->read_record);
tab->index= best_key;
tab->read_first_record= best_key_direction > 0 ?
join_read_first:join_read_last;
@@ -16151,7 +16188,6 @@ test_if_skip_sort_order(JOIN_TAB *tab,OR
table->key_read=1;
table->file->extra(HA_EXTRA_KEYREAD);
}
- table->file->ha_index_or_rnd_end();
if (join->select_options & SELECT_DESCRIBE)
{
tab->ref.key= -1;
@@ -16172,6 +16208,7 @@ test_if_skip_sort_order(JOIN_TAB *tab,OR
tab->use_quick=1;
tab->ref.key= -1;
tab->ref.key_parts=0; // Don't use ref key.
+ end_read_record(&tab->read_record);
tab->read_first_record= join_init_read_record;
if (tab->is_using_loose_index_scan())
join->tmp_table_param.precomputed_group_by= TRUE;
@@ -16227,6 +16264,7 @@ check_reverse_order:
else if (tab->type != JT_NEXT &&
tab->ref.key >= 0 && tab->ref.key_parts <=
used_key_parts)
{
+ end_read_record(&tab->read_record);
/*
SELECT * FROM t1 WHERE a=1 ORDER BY a DESC,b DESC
@@ -16234,7 +16272,7 @@ check_reverse_order:
with key part (A) and then traverse the index backwards.
*/
tab->read_first_record= join_read_last_key;
- tab->read_record.read_record= join_read_prev_same;
+ tab->read_record.set_read_record_func(table, join_read_prev_same);
}
}
else if (select && select->quick)
@@ -16355,6 +16393,7 @@ create_sort_index(THD *thd, JOIN *join,
get_schema_tables_result(join, PROCESSED_BY_CREATE_SORT_INDEX))
goto err;
+ end_read_record(&tab->read_record);
if (table->s->tmp_table)
table->file->info(HA_STATUS_VARIABLE); // Get record count
table->sort.found_records=filesort(thd, table,join->sortorder, length,
@@ -19286,7 +19325,7 @@ void select_describe(JOIN *join, bool ne
for (uint part= 0; part < tab->ref.key_parts; part++)
{
- if (tab->ref.cond_guards[part])
+ if (tab->ref.cond_guard.guard_list[part])
{
extra.append(STRING_WITH_LEN("; Full scan on NULL key"));
break;
=== modified file 'sql/sql_select.h'
--- a/sql/sql_select.h 2008-08-11 12:40:09 +0000
+++ b/sql/sql_select.h 2008-08-16 19:36:24 +0000
@@ -64,6 +64,47 @@ typedef struct keyuse_t {
class store_key;
+/**
+ Represents an array of pointers to trigger variables.
+ Some/all of the pointers may be NULL. The array is stored in JOIN_TAB.
+
+ The ref access can be used iff
+
+ for each used key part i, (!cond_guards[i] || *cond_guards[i])
+
+ An instance of this class is a member of TABLE_REF and is used by
+ subquery code. The subquery code may inject triggered conditions, i.e.
+ conditions that can be 'switched off'. A ref access created from such
+ condition is not valid when at least one of the underlying conditions is
+ switched off (see subquery code for more details).
+
+ If, to evaluate a subquery with the attached disabled condition we
+ originally intended to use an index access method, we also must replace it
+ with a full scan. READ_RECORD information for the full scan is in that
+ case stored in "full_scan_info" member.
+*/
+
+struct Cond_guard
+{
+ /** A pointer to a boolean variable which indicates whether
+ the condition is switched off or not. The condition
+ may only be switched off if it returns NULL. Therefore, this
+ points to "is_null" member of the associated condition item,
+ or the pointer is set to zero if the item is not nullable.
+ */
+ bool **guard_list;
+ /** May point to a READ_RECORD structure for full scan access. */
+ READ_RECORD full_scan_info;
+ /*
+ The following field is used only for a [NOT] IN
+ subquery if it is executed by an alternative full table scan
+ when the left operand of the subquery predicate is evaluated
+ to NULL.
+ */
+ READ_RECORD::Setup_func save_read_first_record;/* to save read_first_record */
+};
+
+
typedef struct st_table_ref
{
bool key_err;
@@ -74,18 +115,7 @@ typedef struct st_table_ref
uchar *key_buff2; ///< key_buff+key_length
store_key **key_copy; //
Item **items; ///< val()'s for each keypart
- /*
- Array of pointers to trigger variables. Some/all of the pointers may be
- NULL. The ref access can be used iff
-
- for each used key part i, (!cond_guards[i] || *cond_guards[i])
-
- This array is used by subquery code. The subquery code may inject
- triggered conditions, i.e. conditions that can be 'switched off'. A ref
- access created from such condition is not valid when at least one of the
- underlying conditions is switched off (see subquery code for more details)
- */
- bool **cond_guards;
+ Cond_guard cond_guard;
/**
(null_rejecting & (1<<i)) means the condition is '=' and no matching
rows will be produced if items[i] IS NULL (see add_not_null_conds())
@@ -212,13 +242,6 @@ typedef struct st_join_table {
READ_RECORD::Setup_func read_first_record;
Next_select_func next_select;
READ_RECORD read_record;
- /*
- Currently the following two fields are used only for a [NOT] IN subquery
- if it is executed by an alternative full table scan when the left operand of
- the subquery predicate is evaluated to NULL.
- */
- READ_RECORD::Setup_func save_read_first_record;/* to save read_first_record */
- READ_RECORD::Read_func save_read_record;/* to save read_record.read_record */
double worst_seeks;
key_map const_keys; /**< Keys with constant part */
key_map checked_keys; /**< Keys checked in find_best */
=== modified file 'sql/sql_servers.cc'
--- a/sql/sql_servers.cc 2008-07-17 19:55:18 +0000
+++ b/sql/sql_servers.cc 2008-08-16 19:36:24 +0000
@@ -182,9 +182,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);
- while (!(read_record_info.read_record(&read_record_info)))
+ if (init_read_record(&read_record_info,thd,table=tables[0].table,NULL,1,0,
+ FALSE))
+ DBUG_RETURN(TRUE);
+ while (!(read_record_info.read_record()))
{
/* return_val is already TRUE, so no need to set */
if ((get_server_from_table_to_cache(table)))
=== modified file 'sql/sql_table.cc'
--- a/sql/sql_table.cc 2008-08-08 01:39:23 +0000
+++ b/sql/sql_table.cc 2008-08-16 19:36:24 +0000
@@ -7307,13 +7307,14 @@ 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))
+ goto err;
errpos= 4;
if (ignore)
to->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
thd->row_count= 0;
restore_record(to, s->default_values); // Create empty record
- while (!(error=info.read_record(&info)))
+ while (!(error=info.read_record()))
{
if (thd->killed)
{
=== modified file 'sql/sql_udf.cc'
--- a/sql/sql_udf.cc 2008-07-17 19:55:18 +0000
+++ b/sql/sql_udf.cc 2008-08-16 19:36:24 +0000
@@ -153,9 +153,10 @@ 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))
+ goto end;
table->use_all_columns();
- while (!(error= read_record_info.read_record(&read_record_info)))
+ while (!(error= read_record_info.read_record()))
{
DBUG_PRINT("info",("init udf record"));
LEX_STRING name;
=== modified file 'sql/sql_update.cc'
--- a/sql/sql_update.cc 2008-07-17 19:55:18 +0000
+++ b/sql/sql_update.cc 2008-08-16 19:36:24 +0000
@@ -442,10 +442,6 @@ int mysql_update(THD *thd,
DISK_BUFFER_SIZE, MYF(MY_WME)))
goto err;
- /* If quick select is used, initialize it before retrieving rows. */
- if (select && select->quick && select->quick->reset())
- goto err;
- table->file->try_semi_consistent_read(1);
/*
When we get here, we have one of the following options:
@@ -459,14 +455,19 @@ 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);
+ error= init_read_record_idx(&info, thd, table, 1, used_index);
+
+ if (error)
+ goto err;
+
+ table->file->try_semi_consistent_read(1);
thd_proc_info(thd, "Searching rows for update");
ha_rows tmp_limit= limit;
- while (!(error=info.read_record(&info)) && !thd->killed)
+ while (!(error= info.read_record()) && !thd->killed)
{
if (!(select && select->skip_record()))
{
@@ -521,11 +522,10 @@ int mysql_update(THD *thd,
if (ignore)
table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
-
- 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 ((error= init_read_record(&info, thd, table, select, 0, 1, FALSE)))
+ goto err;
updated= found= 0;
/* Generate an error when trying to set a NOT NULL field to NULL. */
@@ -570,7 +570,7 @@ int mysql_update(THD *thd,
HA_PARTIAL_COLUMN_READ) ||
bitmap_is_subset(table->write_set, table->read_set));
- while (!(error=info.read_record(&info)) && !thd->killed)
+ while (!(error= info.read_record()) && !thd->killed)
{
if (!(select && select->skip_record()))
{
| Thread |
|---|
| • bzr commit into mysql-6.0-runtime branch (konstantin:2700) WL#3288 | Konstantin Osipov | 16 Aug |