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 "emb_qcache.h"
|
||||||
#include "embedded_priv.h"
|
#include "embedded_priv.h"
|
||||||
|
|
||||||
void Querycache_stream::store_char(char c)
|
void Querycache_stream::store_uchar(uchar c)
|
||||||
{
|
{
|
||||||
if (data_end == cur_data)
|
if (data_end == cur_data)
|
||||||
use_next_block(TRUE);
|
use_next_block(TRUE);
|
||||||
@ -142,7 +142,7 @@ void Querycache_stream::store_safe_str(const char *str, uint str_len)
|
|||||||
store_int(0);
|
store_int(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
char Querycache_stream::load_char()
|
uchar Querycache_stream::load_uchar()
|
||||||
{
|
{
|
||||||
if (cur_data == data_end)
|
if (cur_data == data_end)
|
||||||
use_next_block(FALSE);
|
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
|
*data->embedded_info->prev_ptr= NULL; // this marks the last record
|
||||||
cur_row= data->data;
|
cur_row= data->data;
|
||||||
n_rows= data->rows;
|
n_rows= data->rows;
|
||||||
/* n_fields + n_rows + (field_info + strlen * n_rows) * n_fields */
|
/* n_fields + n_rows + field_info * n_fields */
|
||||||
result+= (uint) (4+8 + (42 + 4*n_rows)*data->fields);
|
result+= (uint) (4+8 + 42*data->fields);
|
||||||
|
|
||||||
for(; field < field_end; field++)
|
for(; field < field_end; field++)
|
||||||
{
|
{
|
||||||
@ -313,13 +313,23 @@ uint emb_count_querycache_size(THD *thd)
|
|||||||
result+= field->def_length;
|
result+= field->def_length;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (; cur_row; cur_row=cur_row->next)
|
if (thd->protocol == &thd->protocol_binary)
|
||||||
{
|
{
|
||||||
MYSQL_ROW col= cur_row->data;
|
result+= (uint) (4*n_rows);
|
||||||
MYSQL_ROW col_end= col + data->fields;
|
for (; cur_row; cur_row=cur_row->next)
|
||||||
for (; col < col_end; col++)
|
result+= cur_row->length;
|
||||||
if (*col)
|
}
|
||||||
result+= *(uint *)((*col) - sizeof(uint));
|
else
|
||||||
|
{
|
||||||
|
result+= (uint) (4*n_rows*data->fields);
|
||||||
|
for (; cur_row; cur_row=cur_row->next)
|
||||||
|
{
|
||||||
|
MYSQL_ROW col= cur_row->data;
|
||||||
|
MYSQL_ROW col_end= col + data->fields;
|
||||||
|
for (; col < col_end; col++)
|
||||||
|
if (*col)
|
||||||
|
result+= *(uint *)((*col) - sizeof(uint));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return result;
|
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->length);
|
||||||
dst->store_int((uint)field->max_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->flags);
|
||||||
dst->store_short((ushort)field->charsetnr);
|
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->name, field->name_length);
|
||||||
dst->store_str(field->table, field->table_length);
|
dst->store_str(field->table, field->table_length);
|
||||||
dst->store_str(field->org_name, field->org_name_length);
|
dst->store_str(field->org_name, field->org_name_length);
|
||||||
@ -366,14 +376,22 @@ void emb_store_querycache_result(Querycache_stream *dst, THD *thd)
|
|||||||
dst->store_safe_str(field->def, field->def_length);
|
dst->store_safe_str(field->def, field->def_length);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (; cur_row; cur_row=cur_row->next)
|
if (thd->protocol == &thd->protocol_binary)
|
||||||
{
|
{
|
||||||
MYSQL_ROW col= cur_row->data;
|
for (; cur_row; cur_row=cur_row->next)
|
||||||
MYSQL_ROW col_end= col + data->fields;
|
dst->store_str((char *) cur_row->data, cur_row->length);
|
||||||
for (; col < col_end; col++)
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (; cur_row; cur_row=cur_row->next)
|
||||||
{
|
{
|
||||||
uint len= *col ? *(uint *)((*col) - sizeof(uint)) : 0;
|
MYSQL_ROW col= cur_row->data;
|
||||||
dst->store_safe_str(*col, len);
|
MYSQL_ROW col_end= col + data->fields;
|
||||||
|
for (; col < col_end; col++)
|
||||||
|
{
|
||||||
|
uint len= *col ? *(uint *)((*col) - sizeof(uint)) : 0;
|
||||||
|
dst->store_safe_str(*col, len);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
DBUG_ASSERT(emb_count_querycache_size(thd) == dst->stored_size);
|
DBUG_ASSERT(emb_count_querycache_size(thd) == dst->stored_size);
|
||||||
@ -408,10 +426,10 @@ int emb_load_querycache_result(THD *thd, Querycache_stream *src)
|
|||||||
{
|
{
|
||||||
field->length= src->load_int();
|
field->length= src->load_int();
|
||||||
field->max_length= (unsigned int)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->flags= (unsigned int)src->load_short();
|
||||||
field->charsetnr= (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)) ||
|
if (!(field->name= src->load_str(f_alloc, &field->name_length)) ||
|
||||||
!(field->table= src->load_str(f_alloc,&field->table_length)) ||
|
!(field->table= src->load_str(f_alloc,&field->table_length)) ||
|
||||||
@ -423,26 +441,43 @@ int emb_load_querycache_result(THD *thd, Querycache_stream *src)
|
|||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
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->rows= rows;
|
||||||
data->data= row;
|
|
||||||
if (!rows)
|
if (!rows)
|
||||||
goto return_ok;
|
goto return_ok;
|
||||||
|
if (thd->protocol == &thd->protocol_binary)
|
||||||
for (prev_row= &row->next; row < end_row; prev_row= &row->next, row++)
|
|
||||||
{
|
{
|
||||||
*prev_row= row;
|
uint length;
|
||||||
row->data= columns;
|
row= (MYSQL_ROWS *)alloc_root(&data->alloc, rows * sizeof(MYSQL_ROWS));
|
||||||
MYSQL_ROW col_end= columns + data->fields;
|
end_row= row + rows;
|
||||||
for (; columns < col_end; columns++)
|
data->data= row;
|
||||||
src->load_column(&data->alloc, columns);
|
|
||||||
|
|
||||||
*(columns++)= NULL;
|
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->data= row;
|
||||||
|
|
||||||
|
for (prev_row= &row->next; row < end_row; prev_row= &row->next, row++)
|
||||||
|
{
|
||||||
|
*prev_row= row;
|
||||||
|
row->data= columns;
|
||||||
|
MYSQL_ROW col_end= columns + data->fields;
|
||||||
|
for (; columns < col_end; columns++)
|
||||||
|
src->load_column(&data->alloc, columns);
|
||||||
|
|
||||||
|
*(columns++)= NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
*prev_row= NULL;
|
*prev_row= NULL;
|
||||||
data->embedded_info->prev_ptr= prev_row;
|
data->embedded_info->prev_ptr= prev_row;
|
||||||
|
@ -58,7 +58,7 @@ public:
|
|||||||
data_end= cur_data + (block->used-headers_len);
|
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_short(ushort s);
|
||||||
void store_int(uint i);
|
void store_int(uint i);
|
||||||
void store_ll(ulonglong ll);
|
void store_ll(ulonglong ll);
|
||||||
@ -66,7 +66,7 @@ public:
|
|||||||
void store_str(const char *str, uint str_len);
|
void store_str(const char *str, uint str_len);
|
||||||
void store_safe_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();
|
ushort load_short();
|
||||||
uint load_int();
|
uint load_int();
|
||||||
ulonglong load_ll();
|
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);
|
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)
|
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
|
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
|
--disable_warnings
|
||||||
DROP TABLE IF EXISTS t1;
|
DROP TABLE IF EXISTS t1, t2;
|
||||||
--enable_warnings
|
--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);
|
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