Commit c3b1a575 authored by Konstantin Osipov's avatar Konstantin Osipov

Salvage comments added by Ingo while working on

Bug#52114 and Bug#50788.
The bugs themselves are regressions that are introduced
by an incomplete fix for Bug#36171 and will not be pushed.
parent 52f361ec
......@@ -455,7 +455,9 @@ my_bool reinit_io_cache(IO_CACHE *info, enum cache_type type,
RETURN
0 we succeeded in reading all data
1 Error: can't read requested characters
1 Error: couldn't read requested characters. In this case:
If info->error == -1, we got a read error.
Otherwise info->error contains the number of bytes in Buffer.
*/
int _my_b_read(register IO_CACHE *info, uchar *Buffer, size_t Count)
......@@ -464,6 +466,7 @@ int _my_b_read(register IO_CACHE *info, uchar *Buffer, size_t Count)
my_off_t pos_in_file;
DBUG_ENTER("_my_b_read");
/* If the buffer is not empty yet, copy what is available. */
if ((left_length= (size_t) (info->read_end-info->read_pos)))
{
DBUG_ASSERT(Count >= left_length); /* User is not using my_b_read() */
......@@ -475,7 +478,7 @@ int _my_b_read(register IO_CACHE *info, uchar *Buffer, size_t Count)
/* pos_in_file always point on where info->buffer was read */
pos_in_file=info->pos_in_file+ (size_t) (info->read_end - info->buffer);
/*
/*
Whenever a function which operates on IO_CACHE flushes/writes
some part of the IO_CACHE to disk it will set the property
"seek_not_done" to indicate this to other functions operating
......@@ -502,19 +505,38 @@ int _my_b_read(register IO_CACHE *info, uchar *Buffer, size_t Count)
}
}
/*
Calculate, how much we are within a IO_SIZE block. Ideally this
should be zero.
*/
diff_length= (size_t) (pos_in_file & (IO_SIZE-1));
/*
If more than a block plus the rest of the current block is wanted,
we do read directly, without filling the buffer.
*/
if (Count >= (size_t) (IO_SIZE+(IO_SIZE-diff_length)))
{ /* Fill first intern buffer */
size_t read_length;
if (info->end_of_file <= pos_in_file)
{ /* End of file */
{
/* End of file. Return, what we did copy from the buffer. */
info->error= (int) left_length;
DBUG_RETURN(1);
}
/*
Crop the wanted count to a multiple of IO_SIZE and subtract,
what we did already read from a block. That way, the read will
end aligned with a block.
*/
length=(Count & (size_t) ~(IO_SIZE-1))-diff_length;
if ((read_length= my_read(info->file,Buffer, length, info->myflags))
!= length)
{
/*
If we didn't get, what we wanted, we either return -1 for a read
error, or (it's end of file), how much we got in total.
*/
info->error= (read_length == (size_t) -1 ? -1 :
(int) (read_length+left_length));
DBUG_RETURN(1);
......@@ -526,15 +548,27 @@ int _my_b_read(register IO_CACHE *info, uchar *Buffer, size_t Count)
diff_length=0;
}
/*
At this point, we want less than one and a partial block.
We will read a full cache, minus the number of bytes, we are
within a block already. So we will reach new alignment.
*/
max_length= info->read_length-diff_length;
/* We will not read past end of file. */
if (info->type != READ_FIFO &&
max_length > (info->end_of_file - pos_in_file))
max_length= (size_t) (info->end_of_file - pos_in_file);
/*
If there is nothing left to read,
we either are done, or we failed to fulfill the request.
Otherwise, we read max_length into the cache.
*/
if (!max_length)
{
if (Count)
{
info->error= left_length; /* We only got this many char */
/* We couldn't fulfil the request. Return, how much we got. */
info->error= left_length;
DBUG_RETURN(1);
}
length=0; /* Didn't read any chars */
......@@ -543,13 +577,23 @@ int _my_b_read(register IO_CACHE *info, uchar *Buffer, size_t Count)
info->myflags)) < Count ||
length == (size_t) -1)
{
/*
We got an read error, or less than requested (end of file).
If not a read error, copy, what we got.
*/
if (length != (size_t) -1)
memcpy(Buffer, info->buffer, length);
info->pos_in_file= pos_in_file;
/* For a read error, return -1, otherwise, what we got in total. */
info->error= length == (size_t) -1 ? -1 : (int) (length+left_length);
info->read_pos=info->read_end=info->buffer;
DBUG_RETURN(1);
}
/*
Count is the remaining number of bytes requested.
length is the amount of data in the cache.
Read Count bytes from the cache.
*/
info->read_pos=info->buffer+Count;
info->read_end=info->buffer+length;
info->pos_in_file=pos_in_file;
......
......@@ -1931,7 +1931,6 @@ TABLE_LIST *find_table_in_list(TABLE_LIST *table,
}
/**
Test that table is unique (It's only exists once in the table list)
......@@ -2054,6 +2053,11 @@ next:
or (in case of MyISAMMRG) one of its children are not used later
in the query.
For MyISAMMRG tables, it is assumed that all the underlying
tables of @c table (if any) are listed right after it and that
their @c parent_l field points at the main table.
@retval non-NULL The table list element for the table that
represents the duplicate.
@retval NULL No duplicates found.
......
......@@ -273,7 +273,12 @@ int _mi_read_rnd_static_record(MI_INFO *info, uchar *buf,
DBUG_RETURN(error);
}
/* Read record with cacheing */
/*
Read record with caching. If my_b_read() returns TRUE, less than the
requested bytes have been read. In this case rec_cache.error is
either -1 for a read error, or contains the number of bytes copied
into the buffer.
*/
error=my_b_read(&info->rec_cache,(uchar*) buf,share->base.reclength);
if (info->s->base.pack_reclength != info->s->base.reclength && !error)
{
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment