diff options
author | monty@mysql.com <> | 2005-11-05 01:32:55 +0200 |
---|---|---|
committer | monty@mysql.com <> | 2005-11-05 01:32:55 +0200 |
commit | a6f5375cb0cb40055f52e92d20ca04233ce70386 (patch) | |
tree | 4a7b533b6da471261f5c13c46e4e9f256ec63a0c /sql/records.cc | |
parent | 3b74bb1b03a32616818f50f59cc44644036ab711 (diff) | |
parent | 303f6b4a7a44511aeb33ccbd9ff43ea2d454aa4c (diff) | |
download | mariadb-git-a6f5375cb0cb40055f52e92d20ca04233ce70386.tar.gz |
Merge mysql.com:/home/my/mysql-5.0
into mysql.com:/home/my/mysql-5.1
Diffstat (limited to 'sql/records.cc')
-rw-r--r-- | sql/records.cc | 194 |
1 files changed, 141 insertions, 53 deletions
diff --git a/sql/records.cc b/sql/records.cc index b3610cf1bbf..4958e39a5a0 100644 --- a/sql/records.cc +++ b/sql/records.cc @@ -28,8 +28,50 @@ static int rr_from_pointers(READ_RECORD *info); 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); +static int rr_index_first(READ_RECORD *info); +static int rr_index(READ_RECORD *info); + + +/* + Initialize READ_RECORD structure to perform full index scan + + SYNOPSIS + init_read_record_idx() + info READ_RECORD structure to initialize. + thd Thread handle + table Table to be accessed + print_error If true, call table->file->print_error() if an error + occurs (except for end-of-records error) + idx index to scan + + DESCRIPTION + Initialize READ_RECORD structure to perform full index scan (in forward + direction) using read_record.read_record() interface. + + This function has been added at late stage and is used only by + UPDATE/DELETE. Other statements perform index scans using + join_read_first/next functions. +*/ + +void init_read_record_idx(READ_RECORD *info, THD *thd, TABLE *table, + bool print_error, uint idx) +{ + 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); + table->file->extra(HA_EXTRA_RETRIEVE_PRIMARY_KEY); + } + /* read_record will be changed to rr_index in rr_index_first */ + info->read_record= rr_index_first; +} - /* init struct for read with info->read_record */ /* init_read_record is used to scan by using a number of different methods. @@ -225,6 +267,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) @@ -239,15 +296,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; } } @@ -255,6 +304,57 @@ static int rr_quick(READ_RECORD *info) } +/* + 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() + info Scan info + + DESCRIPTION + Read the next index record (in forward direction) and translate return + value. + + RETURN + 0 Ok + -1 End of records + 1 Error +*/ + + +static int rr_index(READ_RECORD *info) +{ + 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; @@ -265,17 +365,13 @@ static int rr_sequential(READ_RECORD *info) info->thd->send_kill_message(); 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; } } @@ -286,23 +382,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 */ @@ -340,26 +431,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; } |