Commit 94819da8 authored by unknown's avatar unknown

Fix for bug #5730 (Query cache crashes mysql)

here i deleted the recursion from the querycache's memory allocation


sql/sql_cache.cc:
  Query_cache::allocate_data_chain rewritten with no recursion
parent 01f39787
......@@ -1953,55 +1953,55 @@ my_bool Query_cache::allocate_data_chain(Query_cache_block **result_block,
{
ulong all_headers_len = (ALIGN_SIZE(sizeof(Query_cache_block)) +
ALIGN_SIZE(sizeof(Query_cache_result)));
ulong len= data_len + all_headers_len;
ulong align_len= ALIGN_SIZE(len);
DBUG_ENTER("Query_cache::allocate_data_chain");
DBUG_PRINT("qcache", ("data_len %lu, all_headers_len %lu",
data_len, all_headers_len));
ulong min_size = (first_block_arg ?
get_min_first_result_data_size():
get_min_append_result_data_size());
*result_block = allocate_block(max(min_size, align_len),
min_result_data_size == 0,
all_headers_len + min_result_data_size,
1);
my_bool success = (*result_block != 0);
if (success)
Query_cache_block *prev_block= NULL;
Query_cache_block *new_block;
DBUG_ENTER("Query_cache::allocate_data_chain");
DBUG_PRINT("qcache", ("data_len %lu, all_headers_len %lu",
data_len, all_headers_len));
do
{
Query_cache_block *new_block= *result_block;
ulong len= data_len + all_headers_len;
ulong align_len= ALIGN_SIZE(len);
if (!(new_block= allocate_block(max(min_size, align_len),
min_result_data_size == 0,
all_headers_len + min_result_data_size,
1)))
{
DBUG_PRINT("warning", ("Can't allocate block for results"));
DBUG_RETURN(FALSE);
}
new_block->n_tables = 0;
new_block->used = 0;
new_block->used = min(len, new_block->length);
new_block->type = Query_cache_block::RES_INCOMPLETE;
new_block->next = new_block->prev = new_block;
Query_cache_result *header = new_block->result();
header->parent(query_block);
if (new_block->length < len)
{
/*
We got less memory then we need (no big memory blocks) =>
Continue to allocated more blocks until we got everything we need.
*/
Query_cache_block *next_block;
if ((success = allocate_data_chain(&next_block,
len - new_block->length,
query_block, first_block_arg)))
double_linked_list_join(new_block, next_block);
}
if (success)
{
new_block->used = min(len, new_block->length);
DBUG_PRINT("qcache", ("Block len %lu used %lu",
DBUG_PRINT("qcache", ("Block len %lu used %lu",
new_block->length, new_block->used));
}
if (prev_block)
double_linked_list_join(prev_block, new_block);
else
DBUG_PRINT("warning", ("Can't allocate block for continue"));
}
else
DBUG_PRINT("warning", ("Can't allocate block for results"));
DBUG_RETURN(success);
*result_block= new_block;
if (new_block->length >= len)
break;
/*
We got less memory then we need (no big memory blocks) =>
Continue to allocated more blocks until we got everything we need.
*/
data_len= len - new_block->length;
prev_block= new_block;
} while(1);
DBUG_RETURN(TRUE);
}
/*****************************************************************************
......
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