diff options
author | unknown <monty@mysql.com> | 2005-10-25 02:27:40 +0300 |
---|---|---|
committer | unknown <monty@mysql.com> | 2005-10-25 02:27:40 +0300 |
commit | 8d6634c9e0c43b2d4ed2b0cc9f90b66c850855ab (patch) | |
tree | 56b86b67bce65a21ff4ffd27cd2dd139b110b622 /sql | |
parent | 3c02a0534d4b5450b2a5126bbf84428595c4a803 (diff) | |
download | mariadb-git-8d6634c9e0c43b2d4ed2b0cc9f90b66c850855ab.tar.gz |
Added more tests for new UPDATE ... ORDER BY ... LIMIT optimization
heap/_check.c:
Change arguments to ha_key_cmp
heap/hp_create.c:
Change arguments to ha_key_cmp
include/my_base.h:
Remove SEARCH_RETURN_B_POS and instead always send an array to ha_key_cmp() as last argument
myisam/mi_check.c:
Change arguments to ha_key_cmp
myisam/mi_rnext_same.c:
Change arguments to ha_key_cmp
myisam/mi_search.c:
Change arguments to ha_key_cmp
myisam/mi_write.c:
Change arguments to ha_key_cmp
myisammrg/myrg_queue.c:
Change arguments to ha_key_cmp
mysys/my_handler.c:
Remove SEARCH_RETURN_B_POS and instead always send an array to ha_key_cmp() as last argument
(This removes an if in a loop at the expensive of an int on the stack)
sql/records.cc:
Simplify new rr_index() code
Create common error handling function for rr_() functions.
Remove loop from rr_index() as handler::index_next() can never return HA_ERR_RECORD_DELETED
sql/sql_load.cc:
Simplify
sql/sql_update.cc:
Simplify code
Fixed bug when one is updating an index column that could be used with ORDER BY
sql/structs.h:
Removed not needed structure element
Diffstat (limited to 'sql')
-rw-r--r-- | sql/records.cc | 182 | ||||
-rw-r--r-- | sql/sql_load.cc | 7 | ||||
-rw-r--r-- | sql/sql_update.cc | 24 | ||||
-rw-r--r-- | sql/structs.h | 1 |
4 files changed, 96 insertions, 118 deletions
diff --git a/sql/records.cc b/sql/records.cc index 9150024d4b8..7e4a808f0c3 100644 --- a/sql/records.cc +++ b/sql/records.cc @@ -28,11 +28,10 @@ static int rr_from_pointers(READ_RECORD *info); static int rr_from_cache(READ_RECORD *info); static int init_rr_cache(READ_RECORD *info); static int rr_cmp(uchar *a,uchar *b); - +static int rr_index_first(READ_RECORD *info); static int rr_index(READ_RECORD *info); - /* Initialize READ_RECORD structure to perform full index scan @@ -58,26 +57,19 @@ void init_read_record_idx(READ_RECORD *info, THD *thd, TABLE *table, bool print_error, uint idx) { bzero((char*) info,sizeof(*info)); - info->thd=thd; - info->table=table; - info->file= table->file; - info->forms= &info->table; /* Only one table */ - + info->table= table; + info->file= table->file; info->record= table->record[0]; - info->ref_length= table->file->ref_length; + info->print_error= print_error; - info->select=NULL; - info->print_error=print_error; - info->ignore_not_found_rows= 0; table->status=0; /* And it's always found */ - if (!table->file->inited) { table->file->ha_index_init(idx); table->file->extra(HA_EXTRA_RETRIEVE_PRIMARY_KEY); } - info->read_record= rr_index; - info->first= TRUE; + /* read_record will be changed to rr_index in rr_index_first */ + info->read_record= rr_index_first; } @@ -204,6 +196,21 @@ void end_read_record(READ_RECORD *info) } } +static int rr_handle_error(READ_RECORD *info, int error) +{ + if (error == HA_ERR_END_OF_FILE) + error= -1; + else + { + if (info->print_error) + info->table->file->print_error(error, MYF(0)); + if (error < 0) // Fix negative BDB errno + error= 1; + } + return error; +} + + /* Read a record from head-database */ static int rr_quick(READ_RECORD *info) @@ -218,15 +225,7 @@ static int rr_quick(READ_RECORD *info) } if (tmp != HA_ERR_RECORD_DELETED) { - if (tmp == HA_ERR_END_OF_FILE) - tmp= -1; - else - { - if (info->print_error) - info->file->print_error(tmp,MYF(0)); - if (tmp < 0) // Fix negative BDB errno - tmp=1; - } + tmp= rr_handle_error(info, tmp); break; } } @@ -235,7 +234,31 @@ static int rr_quick(READ_RECORD *info) /* - A READ_RECORD::read_record implementation that reads index sequentially + Reads first row in an index scan + + SYNOPSIS + rr_index_first() + info Scan info + + RETURN + 0 Ok + -1 End of records + 1 Error +*/ + + +static int rr_index_first(READ_RECORD *info) +{ + int tmp= info->file->index_first(info->record); + info->read_record= rr_index; + if (tmp) + tmp= rr_handle_error(info, tmp); + return tmp; +} + + +/* + Reads index sequentially after first row SYNOPSIS rr_index() @@ -251,43 +274,16 @@ static int rr_quick(READ_RECORD *info) 1 Error */ + static int rr_index(READ_RECORD *info) { - int tmp; - while (1) - { - if (info->first) - { - info->first= FALSE; - tmp= info->file->index_first(info->record); - } - else - tmp= info->file->index_next(info->record); - - if (!tmp) - break; - if (info->thd->killed) - { - my_error(ER_SERVER_SHUTDOWN,MYF(0)); - return 1; - } - if (tmp != HA_ERR_RECORD_DELETED) - { - if (tmp == HA_ERR_END_OF_FILE) - tmp= -1; - else - { - if (info->print_error) - info->table->file->print_error(tmp,MYF(0)); - if (tmp < 0) // Fix negative BDB errno - tmp=1; - } - break; - } - } + int tmp= info->file->index_next(info->record); + if (tmp) + tmp= rr_handle_error(info, tmp); return tmp; } + static int rr_sequential(READ_RECORD *info) { int tmp; @@ -298,17 +294,13 @@ static int rr_sequential(READ_RECORD *info) my_error(ER_SERVER_SHUTDOWN,MYF(0)); return 1; } + /* + rnd_next can return RECORD_DELETED for MyISAM when one thread is + reading and another deleting without locks. + */ if (tmp != HA_ERR_RECORD_DELETED) { - if (tmp == HA_ERR_END_OF_FILE) - tmp= -1; - else - { - if (info->print_error) - info->table->file->print_error(tmp,MYF(0)); - if (tmp < 0) // Fix negative BDB errno - tmp=1; - } + tmp= rr_handle_error(info, tmp); break; } } @@ -319,23 +311,18 @@ static int rr_sequential(READ_RECORD *info) static int rr_from_tempfile(READ_RECORD *info) { int tmp; -tryNext: - if (my_b_read(info->io_cache,info->ref_pos,info->ref_length)) - return -1; /* End of file */ - if ((tmp=info->file->rnd_pos(info->record,info->ref_pos))) + for (;;) { - if (tmp == HA_ERR_END_OF_FILE) - tmp= -1; - else if (tmp == HA_ERR_RECORD_DELETED || - (tmp == HA_ERR_KEY_NOT_FOUND && info->ignore_not_found_rows)) - goto tryNext; - else - { - if (info->print_error) - info->file->print_error(tmp,MYF(0)); - if (tmp < 0) // Fix negative BDB errno - tmp=1; - } + if (my_b_read(info->io_cache,info->ref_pos,info->ref_length)) + return -1; /* End of file */ + if (!(tmp=info->file->rnd_pos(info->record,info->ref_pos))) + break; + /* The following is extremely unlikely to happen */ + if (tmp == HA_ERR_RECORD_DELETED || + (tmp == HA_ERR_KEY_NOT_FOUND && info->ignore_not_found_rows)) + continue; + tmp= rr_handle_error(info, tmp); + break; } return tmp; } /* rr_from_tempfile */ @@ -373,26 +360,23 @@ static int rr_from_pointers(READ_RECORD *info) { int tmp; byte *cache_pos; -tryNext: - if (info->cache_pos == info->cache_end) - return -1; /* End of file */ - cache_pos=info->cache_pos; - info->cache_pos+=info->ref_length; - if ((tmp=info->file->rnd_pos(info->record,cache_pos))) + for (;;) { - if (tmp == HA_ERR_END_OF_FILE) - tmp= -1; - else if (tmp == HA_ERR_RECORD_DELETED || - (tmp == HA_ERR_KEY_NOT_FOUND && info->ignore_not_found_rows)) - goto tryNext; - else - { - if (info->print_error) - info->file->print_error(tmp,MYF(0)); - if (tmp < 0) // Fix negative BDB errno - tmp=1; - } + if (info->cache_pos == info->cache_end) + return -1; /* End of file */ + cache_pos= info->cache_pos; + info->cache_pos+= info->ref_length; + + if (!(tmp=info->file->rnd_pos(info->record,cache_pos))) + break; + + /* The following is extremely unlikely to happen */ + if (tmp == HA_ERR_RECORD_DELETED || + (tmp == HA_ERR_KEY_NOT_FOUND && info->ignore_not_found_rows)) + continue; + tmp= rr_handle_error(info, tmp); + break; } return tmp; } diff --git a/sql/sql_load.cc b/sql/sql_load.cc index 3b7c6608aef..aa4ea3e6c8c 100644 --- a/sql/sql_load.cc +++ b/sql/sql_load.cc @@ -818,11 +818,8 @@ int READ_INFO::read_field() *to++ = (byte) unescape((char) chr); continue; } - else - { - PUSH(chr); - chr= escape_char; - } + PUSH(chr); + chr= escape_char; } #ifdef ALLOW_LINESEPARATOR_IN_STRINGS if (chr == line_term_char) diff --git a/sql/sql_update.cc b/sql/sql_update.cc index c30749677d6..b6bce800b0e 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -148,7 +148,7 @@ int mysql_update(THD *thd, } if (!select && limit != HA_POS_ERROR) { - if (MAX_KEY != (used_index= get_index_for_order(table, order, limit))) + if ((used_index= get_index_for_order(table, order, limit)) != MAX_KEY) need_sort= FALSE; } /* If running in safe sql mode, don't allow updates without keys */ @@ -171,14 +171,14 @@ int mysql_update(THD *thd, used_key_is_modified= (!select->quick->unique_key_range() && check_if_key_used(table, used_index, fields)); } - else if (used_index != MAX_KEY) + else { - used_key_is_modified= check_if_key_used(table, used_index, fields); + used_key_is_modified= 0; + if (used_index == MAX_KEY) // no index for sort order + used_index= table->file->key_used_on_scan; + if (used_index != MAX_KEY) + used_key_is_modified= check_if_key_used(table, used_index, fields); } - else if ((used_index=table->file->key_used_on_scan) < MAX_KEY) - used_key_is_modified=check_if_key_used(table, used_index, fields); - else - used_key_is_modified=0; if (used_key_is_modified || order) { @@ -190,11 +190,11 @@ int mysql_update(THD *thd, if (used_index < MAX_KEY && old_used_keys.is_set(used_index)) { table->key_read=1; - table->file->extra(HA_EXTRA_KEYREAD); //todo: psergey: check + table->file->extra(HA_EXTRA_KEYREAD); } /* note: can actually avoid sorting below.. */ - if (order && need_sort) + if (order && (need_sort || used_key_is_modified)) { /* Doing an ORDER BY; Let filesort find and sort the rows we are going @@ -204,6 +204,7 @@ int mysql_update(THD *thd, SORT_FIELD *sortorder; ha_rows examined_rows; + used_index= MAX_KEY; // For call to init_read_record() table->sort.io_cache = (IO_CACHE *) my_malloc(sizeof(IO_CACHE), MYF(MY_FAE | MY_ZEROFILL)); if (!(sortorder=make_unireg_sortorder(order, &length)) || @@ -265,10 +266,7 @@ int mysql_update(THD *thd, error= 1; // Aborted limit= tmp_limit; end_read_record(&info); - - /* if we got here we must not use index in the main update loop below */ - used_index= MAX_KEY; - + /* Change select to use tempfile */ if (select) { diff --git a/sql/structs.h b/sql/structs.h index 4a88a17cdd0..081ada88bf7 100644 --- a/sql/structs.h +++ b/sql/structs.h @@ -132,7 +132,6 @@ typedef struct st_read_record { /* Parameter to read_record */ byte *cache,*cache_pos,*cache_end,*read_positions; IO_CACHE *io_cache; bool print_error, ignore_not_found_rows; - bool first; /* used only with rr_index_read */ } READ_RECORD; |