mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
Bug #30430 crash:./mtr --embedded-server --ps-protocol cache_innodb func_misc...
PS-protocol data is stored in different format - the MYSQL_RECORDS->data contains the link to the record content, not to array of the links to the field's contents. So we have to handle it separately for embedded-server query cache.
This commit is contained in:
@ -19,7 +19,7 @@
|
||||
#include "emb_qcache.h"
|
||||
#include "embedded_priv.h"
|
||||
|
||||
void Querycache_stream::store_char(char c)
|
||||
void Querycache_stream::store_uchar(uchar c)
|
||||
{
|
||||
if (data_end == cur_data)
|
||||
use_next_block(TRUE);
|
||||
@ -142,7 +142,7 @@ void Querycache_stream::store_safe_str(const char *str, uint str_len)
|
||||
store_int(0);
|
||||
}
|
||||
|
||||
char Querycache_stream::load_char()
|
||||
uchar Querycache_stream::load_uchar()
|
||||
{
|
||||
if (cur_data == data_end)
|
||||
use_next_block(FALSE);
|
||||
@ -301,8 +301,8 @@ uint emb_count_querycache_size(THD *thd)
|
||||
*data->embedded_info->prev_ptr= NULL; // this marks the last record
|
||||
cur_row= data->data;
|
||||
n_rows= data->rows;
|
||||
/* n_fields + n_rows + (field_info + strlen * n_rows) * n_fields */
|
||||
result+= (uint) (4+8 + (42 + 4*n_rows)*data->fields);
|
||||
/* n_fields + n_rows + field_info * n_fields */
|
||||
result+= (uint) (4+8 + 42*data->fields);
|
||||
|
||||
for(; field < field_end; field++)
|
||||
{
|
||||
@ -313,6 +313,15 @@ uint emb_count_querycache_size(THD *thd)
|
||||
result+= field->def_length;
|
||||
}
|
||||
|
||||
if (thd->protocol == &thd->protocol_binary)
|
||||
{
|
||||
result+= (uint) (4*n_rows);
|
||||
for (; cur_row; cur_row=cur_row->next)
|
||||
result+= cur_row->length;
|
||||
}
|
||||
else
|
||||
{
|
||||
result+= (uint) (4*n_rows*data->fields);
|
||||
for (; cur_row; cur_row=cur_row->next)
|
||||
{
|
||||
MYSQL_ROW col= cur_row->data;
|
||||
@ -321,6 +330,7 @@ uint emb_count_querycache_size(THD *thd)
|
||||
if (*col)
|
||||
result+= *(uint *)((*col) - sizeof(uint));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -353,10 +363,10 @@ void emb_store_querycache_result(Querycache_stream *dst, THD *thd)
|
||||
{
|
||||
dst->store_int((uint)field->length);
|
||||
dst->store_int((uint)field->max_length);
|
||||
dst->store_char((char)field->type);
|
||||
dst->store_uchar((uchar)field->type);
|
||||
dst->store_short((ushort)field->flags);
|
||||
dst->store_short((ushort)field->charsetnr);
|
||||
dst->store_char((char)field->decimals);
|
||||
dst->store_uchar((uchar)field->decimals);
|
||||
dst->store_str(field->name, field->name_length);
|
||||
dst->store_str(field->table, field->table_length);
|
||||
dst->store_str(field->org_name, field->org_name_length);
|
||||
@ -366,6 +376,13 @@ void emb_store_querycache_result(Querycache_stream *dst, THD *thd)
|
||||
dst->store_safe_str(field->def, field->def_length);
|
||||
}
|
||||
|
||||
if (thd->protocol == &thd->protocol_binary)
|
||||
{
|
||||
for (; cur_row; cur_row=cur_row->next)
|
||||
dst->store_str((char *) cur_row->data, cur_row->length);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (; cur_row; cur_row=cur_row->next)
|
||||
{
|
||||
MYSQL_ROW col= cur_row->data;
|
||||
@ -376,6 +393,7 @@ void emb_store_querycache_result(Querycache_stream *dst, THD *thd)
|
||||
dst->store_safe_str(*col, len);
|
||||
}
|
||||
}
|
||||
}
|
||||
DBUG_ASSERT(emb_count_querycache_size(thd) == dst->stored_size);
|
||||
DBUG_VOID_RETURN;
|
||||
}
|
||||
@ -408,10 +426,10 @@ int emb_load_querycache_result(THD *thd, Querycache_stream *src)
|
||||
{
|
||||
field->length= src->load_int();
|
||||
field->max_length= (unsigned int)src->load_int();
|
||||
field->type= (enum enum_field_types)src->load_char();
|
||||
field->type= (enum enum_field_types)src->load_uchar();
|
||||
field->flags= (unsigned int)src->load_short();
|
||||
field->charsetnr= (unsigned int)src->load_short();
|
||||
field->decimals= (unsigned int)src->load_char();
|
||||
field->decimals= src->load_uchar();
|
||||
|
||||
if (!(field->name= src->load_str(f_alloc, &field->name_length)) ||
|
||||
!(field->table= src->load_str(f_alloc,&field->table_length)) ||
|
||||
@ -423,16 +441,32 @@ int emb_load_querycache_result(THD *thd, Querycache_stream *src)
|
||||
goto err;
|
||||
}
|
||||
|
||||
data->rows= rows;
|
||||
if (!rows)
|
||||
goto return_ok;
|
||||
if (thd->protocol == &thd->protocol_binary)
|
||||
{
|
||||
uint length;
|
||||
row= (MYSQL_ROWS *)alloc_root(&data->alloc, rows * sizeof(MYSQL_ROWS));
|
||||
end_row= row + rows;
|
||||
data->data= row;
|
||||
|
||||
for (prev_row= &row->next; row < end_row; prev_row= &row->next, row++)
|
||||
{
|
||||
*prev_row= row;
|
||||
row->data= (MYSQL_ROW) src->load_str(&data->alloc, &length);
|
||||
row->length= length;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
row= (MYSQL_ROWS *)alloc_root(&data->alloc,
|
||||
(uint) (rows * sizeof(MYSQL_ROWS) +
|
||||
rows*(data->fields+1)*sizeof(char*)));
|
||||
end_row= row + rows;
|
||||
columns= (MYSQL_ROW)end_row;
|
||||
|
||||
data->rows= rows;
|
||||
data->data= row;
|
||||
if (!rows)
|
||||
goto return_ok;
|
||||
|
||||
for (prev_row= &row->next; row < end_row; prev_row= &row->next, row++)
|
||||
{
|
||||
@ -444,6 +478,7 @@ int emb_load_querycache_result(THD *thd, Querycache_stream *src)
|
||||
|
||||
*(columns++)= NULL;
|
||||
}
|
||||
}
|
||||
*prev_row= NULL;
|
||||
data->embedded_info->prev_ptr= prev_row;
|
||||
return_ok:
|
||||
|
@ -58,7 +58,7 @@ public:
|
||||
data_end= cur_data + (block->used-headers_len);
|
||||
}
|
||||
|
||||
void store_char(char c);
|
||||
void store_uchar(uchar c);
|
||||
void store_short(ushort s);
|
||||
void store_int(uint i);
|
||||
void store_ll(ulonglong ll);
|
||||
@ -66,7 +66,7 @@ public:
|
||||
void store_str(const char *str, uint str_len);
|
||||
void store_safe_str(const char *str, uint str_len);
|
||||
|
||||
char load_char();
|
||||
uchar load_uchar();
|
||||
ushort load_short();
|
||||
uint load_int();
|
||||
ulonglong load_ll();
|
||||
|
@ -1,4 +1,4 @@
|
||||
DROP TABLE IF EXISTS t1;
|
||||
DROP TABLE IF EXISTS t1, t2;
|
||||
select format(1.5555,0),format(123.5555,1),format(1234.5555,2),format(12345.55555,3),format(123456.5555,4),format(1234567.5555,5),format("12345.2399",2);
|
||||
format(1.5555,0) format(123.5555,1) format(1234.5555,2) format(12345.55555,3) format(123456.5555,4) format(1234567.5555,5) format("12345.2399",2)
|
||||
2 123.6 1,234.56 12,345.556 123,456.5555 1,234,567.55550 12,345.24
|
||||
|
@ -3,7 +3,7 @@
|
||||
#
|
||||
|
||||
--disable_warnings
|
||||
DROP TABLE IF EXISTS t1;
|
||||
DROP TABLE IF EXISTS t1, t2;
|
||||
--enable_warnings
|
||||
|
||||
select format(1.5555,0),format(123.5555,1),format(1234.5555,2),format(12345.55555,3),format(123456.5555,4),format(1234567.5555,5),format("12345.2399",2);
|
||||
|
Reference in New Issue
Block a user