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, ...@@ -455,7 +455,9 @@ my_bool reinit_io_cache(IO_CACHE *info, enum cache_type type,
RETURN RETURN
0 we succeeded in reading all data 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) 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) ...@@ -464,6 +466,7 @@ int _my_b_read(register IO_CACHE *info, uchar *Buffer, size_t Count)
my_off_t pos_in_file; my_off_t pos_in_file;
DBUG_ENTER("_my_b_read"); 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))) if ((left_length= (size_t) (info->read_end-info->read_pos)))
{ {
DBUG_ASSERT(Count >= left_length); /* User is not using my_b_read() */ 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) ...@@ -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 always point on where info->buffer was read */
pos_in_file=info->pos_in_file+ (size_t) (info->read_end - info->buffer); pos_in_file=info->pos_in_file+ (size_t) (info->read_end - info->buffer);
/* /*
Whenever a function which operates on IO_CACHE flushes/writes Whenever a function which operates on IO_CACHE flushes/writes
some part of the IO_CACHE to disk it will set the property some part of the IO_CACHE to disk it will set the property
"seek_not_done" to indicate this to other functions operating "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) ...@@ -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)); 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))) if (Count >= (size_t) (IO_SIZE+(IO_SIZE-diff_length)))
{ /* Fill first intern buffer */ { /* Fill first intern buffer */
size_t read_length; size_t read_length;
if (info->end_of_file <= pos_in_file) 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; info->error= (int) left_length;
DBUG_RETURN(1); 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; length=(Count & (size_t) ~(IO_SIZE-1))-diff_length;
if ((read_length= my_read(info->file,Buffer, length, info->myflags)) if ((read_length= my_read(info->file,Buffer, length, info->myflags))
!= length) != 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 : info->error= (read_length == (size_t) -1 ? -1 :
(int) (read_length+left_length)); (int) (read_length+left_length));
DBUG_RETURN(1); DBUG_RETURN(1);
...@@ -526,15 +548,27 @@ int _my_b_read(register IO_CACHE *info, uchar *Buffer, size_t Count) ...@@ -526,15 +548,27 @@ int _my_b_read(register IO_CACHE *info, uchar *Buffer, size_t Count)
diff_length=0; 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; max_length= info->read_length-diff_length;
/* We will not read past end of file. */
if (info->type != READ_FIFO && if (info->type != READ_FIFO &&
max_length > (info->end_of_file - pos_in_file)) max_length > (info->end_of_file - pos_in_file))
max_length= (size_t) (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 (!max_length)
{ {
if (Count) 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); DBUG_RETURN(1);
} }
length=0; /* Didn't read any chars */ length=0; /* Didn't read any chars */
...@@ -543,13 +577,23 @@ int _my_b_read(register IO_CACHE *info, uchar *Buffer, size_t Count) ...@@ -543,13 +577,23 @@ int _my_b_read(register IO_CACHE *info, uchar *Buffer, size_t Count)
info->myflags)) < Count || info->myflags)) < Count ||
length == (size_t) -1) 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) if (length != (size_t) -1)
memcpy(Buffer, info->buffer, length); memcpy(Buffer, info->buffer, length);
info->pos_in_file= pos_in_file; 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->error= length == (size_t) -1 ? -1 : (int) (length+left_length);
info->read_pos=info->read_end=info->buffer; info->read_pos=info->read_end=info->buffer;
DBUG_RETURN(1); 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_pos=info->buffer+Count;
info->read_end=info->buffer+length; info->read_end=info->buffer+length;
info->pos_in_file=pos_in_file; info->pos_in_file=pos_in_file;
......
...@@ -1931,7 +1931,6 @@ TABLE_LIST *find_table_in_list(TABLE_LIST *table, ...@@ -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) Test that table is unique (It's only exists once in the table list)
...@@ -2054,6 +2053,11 @@ next: ...@@ -2054,6 +2053,11 @@ next:
or (in case of MyISAMMRG) one of its children are not used later or (in case of MyISAMMRG) one of its children are not used later
in the query. 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 @retval non-NULL The table list element for the table that
represents the duplicate. represents the duplicate.
@retval NULL No duplicates found. @retval NULL No duplicates found.
......
...@@ -273,7 +273,12 @@ int _mi_read_rnd_static_record(MI_INFO *info, uchar *buf, ...@@ -273,7 +273,12 @@ int _mi_read_rnd_static_record(MI_INFO *info, uchar *buf,
DBUG_RETURN(error); 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); error=my_b_read(&info->rec_cache,(uchar*) buf,share->base.reclength);
if (info->s->base.pack_reclength != info->s->base.reclength && !error) 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