summaryrefslogtreecommitdiff
path: root/sql/records.cc
diff options
context:
space:
mode:
authormonty@mysql.com <>2005-11-05 01:32:55 +0200
committermonty@mysql.com <>2005-11-05 01:32:55 +0200
commita6f5375cb0cb40055f52e92d20ca04233ce70386 (patch)
tree4a7b533b6da471261f5c13c46e4e9f256ec63a0c /sql/records.cc
parent3b74bb1b03a32616818f50f59cc44644036ab711 (diff)
parent303f6b4a7a44511aeb33ccbd9ff43ea2d454aa4c (diff)
downloadmariadb-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.cc194
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;
}