1
0
mirror of https://github.com/MariaDB/server.git synced 2025-08-05 13:16:09 +03:00

Fixed LP bug #675922.

The bug happened when BKA join algorithm used an incremental buffer
and some of the fields over which access keys were constructed
- were allocated in the previous join buffers
- were non-nullable
- belonged to inner tables of outer joins.
For such fields an offset to the field value in the record is saved
in the postfix of the record, and a zero offset indicates that the value 
is null. Before the key using the field value is constructed the
value is read into the corresponding field of the record buffer and
the null bit is set for the field if the offset is 0. However if
the field is non-nullable the table->null_row must be set to 1
for null values and to 0 for non-null values  to ensure proper reading
of the value from the record buffer.
This commit is contained in:
Igor Babaev
2010-11-19 07:38:02 -08:00
parent 0a3922fca8
commit ae4b5a32a6
3 changed files with 113 additions and 3 deletions

View File

@@ -1776,7 +1776,13 @@ uint JOIN_CACHE::read_record_field(CACHE_FIELD *copy, bool blob_in_rec_buff)
If the value of *len is 0 then the function sets it to the total
length of the record fields including possible trailing offset
values. Otherwise *len is supposed to provide this value that
has been obtained earlier.
has been obtained earlier.
NOTE
If the value of the referenced field is null then the offset
for the value is set to 0. If the value of a field can be null
then the value of flag_fields is always positive. So the offset
for any non-null value cannot be 0 in this case.
RETURN VALUE
TRUE 'copy' points to a data descriptor of this join cache
@@ -1805,14 +1811,21 @@ bool JOIN_CACHE::read_referenced_field(CACHE_FIELD *copy,
size_of_fld_ofs*
(referenced_fields+1-copy->referenced_field_no));
bool is_null= FALSE;
Field *field= copy->field;
if (offset == 0 && flag_fields)
is_null= TRUE;
if (is_null)
copy->field->set_null();
{
field->set_null();
if (!field->real_maybe_null())
field->table->null_row= 1;
}
else
{
uchar *save_pos= pos;
copy->field->set_notnull();
field->set_notnull();
if (!field->real_maybe_null())
field->table->null_row= 0;
pos= rec_ptr+offset;
read_record_field(copy, blob_data_is_in_rec_buff(rec_ptr));
pos= save_pos;