1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-27 18:02:13 +03:00

Fixed LP bug #802860.

This crashing bug could manifest itself at execution of join queries
over materialized derived tables with IN subquery predicates in the
where clause. If for such a query the optimizer chose to use duplicate
weed-out with duplicates in a materialized derived table and chose to
employ join cache the the execution could cause a crash of the server.
It happened because the JOIN_CACHE::init method assumed  that the value
of TABLE::file::ref is set at the moment when the method was called 
for the employed join cache. It's true for regular tables, but it's 
not true for materialized derived tables that are filled now at the
first access to them, i.e. after the JOIN_CACHE::init has done its job.

To fix this problem for any ROWID field of materialized derived table
the procedure that copies fields from record buffers into the employed
join buffer first checks whether the value of TABLE::file::ref has 
been set for the table, and if it's not so the procedure sets this value.
This commit is contained in:
Igor Babaev
2011-06-28 18:31:54 -07:00
parent 5ce5e8db92
commit 31edda66fd
4 changed files with 94 additions and 5 deletions

View File

@ -609,8 +609,15 @@ void JOIN_CACHE::create_remaining_fields()
if (tab->keep_current_rowid)
{
copy->str= table->file->ref;
copy->length= table->file->ref_length;
copy->type= 0;
if (copy->str)
copy->length= table->file->ref_length;
else
{
/* This may happen only for materialized derived tables and views */
copy->length= 0;
copy->str= (uchar *) table;
}
copy->type= CACHE_ROWID;
copy->field= 0;
copy->referenced_field_no= 0;
length+= copy->length;
@ -1325,8 +1332,7 @@ uint JOIN_CACHE::write_record_data(uchar * link, bool *is_full)
{
Field *field= copy->field;
if (field && field->maybe_null() && field->is_null())
{
/* Do not copy a field if its value is null */
{
if (copy->referenced_field_no)
copy->offset= 0;
continue;
@ -1386,6 +1392,18 @@ uint JOIN_CACHE::write_record_data(uchar * link, bool *is_full)
cp+= len+2;
break;
}
case CACHE_ROWID:
if (!copy->length)
{
/*
This may happen only for ROWID fields of materialized
derived tables and views.
*/
TABLE *table= (TABLE *) copy->str;
copy->str= table->file->ref;
copy->length= table->file->ref_length;
}
/* fall through */
default:
/* Copy the entire image of the field from the record buffer */
memcpy(cp, copy->str, copy->length);
@ -1455,7 +1473,6 @@ uint JOIN_CACHE::write_record_data(uchar * link, bool *is_full)
RETURN VALUE
none
*/
void JOIN_CACHE::reset(bool for_writing)
{
pos= buff;