mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
Fixed bug in warning handling (Memory was allocated from wrong MEM_ROOT)
sql/item_sum.cc: Fixed bug in warning handling. sql/item_sum.h: Fixed bug in warning handling. sql/sql_class.h: Fixed bug in warning handling. sql/sql_error.cc: Fixed bug in warning handling. strings/my_vsnprintf.c: After merge fix
This commit is contained in:
@ -1344,7 +1344,8 @@ String *Item_sum_udf_str::val_str(String *str)
|
|||||||
GROUP_CONCAT(DISTINCT expr,...)
|
GROUP_CONCAT(DISTINCT expr,...)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static int group_concat_key_cmp_with_distinct(void* arg, byte* key1, byte* key2)
|
static int group_concat_key_cmp_with_distinct(void* arg, byte* key1,
|
||||||
|
byte* key2)
|
||||||
{
|
{
|
||||||
Item_func_group_concat* item= (Item_func_group_concat*)arg;
|
Item_func_group_concat* item= (Item_func_group_concat*)arg;
|
||||||
for (int i= 0; i<item->arg_count_field; i++)
|
for (int i= 0; i<item->arg_count_field; i++)
|
||||||
@ -1357,8 +1358,8 @@ static int group_concat_key_cmp_with_distinct(void* arg, byte* key1, byte* key2)
|
|||||||
|
|
||||||
int res= field->key_cmp(key1 + offset, key2 + offset);
|
int res= field->key_cmp(key1 + offset, key2 + offset);
|
||||||
/*
|
/*
|
||||||
if key1 and key2 is not equal than field->key_cmp return offset. This function
|
if key1 and key2 is not equal than field->key_cmp return offset. This
|
||||||
must return value 1 for this case.
|
function must return value 1 for this case.
|
||||||
*/
|
*/
|
||||||
if (res)
|
if (res)
|
||||||
return 1;
|
return 1;
|
||||||
@ -1367,6 +1368,7 @@ static int group_concat_key_cmp_with_distinct(void* arg, byte* key1, byte* key2)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
function of sort for syntax:
|
function of sort for syntax:
|
||||||
GROUP_CONCAT(expr,... ORDER BY col,... )
|
GROUP_CONCAT(expr,... ORDER BY col,... )
|
||||||
@ -1391,11 +1393,12 @@ static int group_concat_key_cmp_with_order(void* arg, byte* key1, byte* key2)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
We can't return 0 becouse tree class remove this item as dubl value.
|
We can't return 0 because tree class remove this item as double value.
|
||||||
*/
|
*/
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
function of sort for syntax:
|
function of sort for syntax:
|
||||||
GROUP_CONCAT(DISTINCT expr,... ORDER BY col,... )
|
GROUP_CONCAT(DISTINCT expr,... ORDER BY col,... )
|
||||||
@ -1409,6 +1412,7 @@ static int group_concat_key_cmp_with_distinct_and_order(void* arg, byte* key1, b
|
|||||||
return(group_concat_key_cmp_with_order(arg,key1,key2));
|
return(group_concat_key_cmp_with_order(arg,key1,key2));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
create result
|
create result
|
||||||
item is pointer to Item_func_group_concat
|
item is pointer to Item_func_group_concat
|
||||||
@ -1468,6 +1472,7 @@ static int dump_leaf_key(byte* key, uint32 count __attribute__((unused)),
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Constructor of Item_func_group_concat
|
Constructor of Item_func_group_concat
|
||||||
is_distinct - distinct
|
is_distinct - distinct
|
||||||
@ -1476,17 +1481,13 @@ static int dump_leaf_key(byte* key, uint32 count __attribute__((unused)),
|
|||||||
is_separator - string value of separator
|
is_separator - string value of separator
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Item_func_group_concat::Item_func_group_concat(int is_distinct,List<Item> *is_select,
|
Item_func_group_concat::Item_func_group_concat(int is_distinct,
|
||||||
SQL_LIST *is_order,String *is_separator):
|
List<Item> *is_select,
|
||||||
Item_sum(),
|
SQL_LIST *is_order,
|
||||||
tmp_table_param(0),
|
String *is_separator)
|
||||||
warning_available(false),
|
:Item_sum(), tmp_table_param(0), warning_available(false),
|
||||||
separator(is_separator),
|
separator(is_separator), tree(&tree_base), table(0), distinct(is_distinct),
|
||||||
tree(&tree_base),
|
tree_mode(0), count_cut_values(0)
|
||||||
table(0),
|
|
||||||
distinct(is_distinct),
|
|
||||||
tree_mode(0),
|
|
||||||
count_cut_values(0)
|
|
||||||
{
|
{
|
||||||
original= 0;
|
original= 0;
|
||||||
quick_group= 0;
|
quick_group= 0;
|
||||||
@ -1551,14 +1552,15 @@ Item_func_group_concat::~Item_func_group_concat()
|
|||||||
*/
|
*/
|
||||||
if (!original)
|
if (!original)
|
||||||
{
|
{
|
||||||
|
THD *thd= current_thd;
|
||||||
if (warning_available)
|
if (warning_available)
|
||||||
{
|
{
|
||||||
char warn_buff[MYSQL_ERRMSG_SIZE];
|
char warn_buff[MYSQL_ERRMSG_SIZE];
|
||||||
sprintf(warn_buff, ER(ER_CUT_VALUE_GROUP_CONCAT), count_cut_values);
|
sprintf(warn_buff, ER(ER_CUT_VALUE_GROUP_CONCAT), count_cut_values);
|
||||||
((MYSQL_ERROR *)warning)->set_msg((char *)&warn_buff);
|
warning->set_msg(thd, warn_buff);
|
||||||
}
|
}
|
||||||
if (table)
|
if (table)
|
||||||
free_tmp_table(current_thd, table);
|
free_tmp_table(thd, table);
|
||||||
if (tmp_table_param)
|
if (tmp_table_param)
|
||||||
delete tmp_table_param;
|
delete tmp_table_param;
|
||||||
if (tree_mode)
|
if (tree_mode)
|
||||||
|
@ -631,12 +631,14 @@ public:
|
|||||||
|
|
||||||
#endif /* HAVE_DLOPEN */
|
#endif /* HAVE_DLOPEN */
|
||||||
|
|
||||||
|
class MYSQL_ERROR;
|
||||||
|
|
||||||
class Item_func_group_concat : public Item_sum
|
class Item_func_group_concat : public Item_sum
|
||||||
{
|
{
|
||||||
THD *item_thd;
|
THD *item_thd;
|
||||||
TMP_TABLE_PARAM *tmp_table_param;
|
TMP_TABLE_PARAM *tmp_table_param;
|
||||||
uint max_elements_in_tree;
|
uint max_elements_in_tree;
|
||||||
void *warning;
|
MYSQL_ERROR *warning;
|
||||||
bool warning_available;
|
bool warning_available;
|
||||||
public:
|
public:
|
||||||
String result;
|
String result;
|
||||||
|
@ -301,17 +301,14 @@ public:
|
|||||||
enum_warning_level level;
|
enum_warning_level level;
|
||||||
char *msg;
|
char *msg;
|
||||||
|
|
||||||
MYSQL_ERROR(uint code_arg, enum_warning_level level_arg,
|
MYSQL_ERROR(THD *thd, uint code_arg, enum_warning_level level_arg,
|
||||||
const char *msg_arg)
|
const char *msg_arg)
|
||||||
:code(code_arg), level(level_arg)
|
:code(code_arg), level(level_arg)
|
||||||
{
|
{
|
||||||
if (msg_arg)
|
if (msg_arg)
|
||||||
msg=sql_strdup(msg_arg);
|
set_msg(thd, msg_arg);
|
||||||
}
|
|
||||||
inline void set_msg(const char *msg_arg)
|
|
||||||
{
|
|
||||||
msg=sql_strdup(msg_arg);
|
|
||||||
}
|
}
|
||||||
|
void set_msg(THD *thd, const char *msg_arg);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -44,6 +44,19 @@ This file contains the implementation of error and warnings related
|
|||||||
|
|
||||||
#include "mysql_priv.h"
|
#include "mysql_priv.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
Store a new message in an error object
|
||||||
|
|
||||||
|
This is used to in group_concat() to register how many warnings we actually
|
||||||
|
got after the query has been executed.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void MYSQL_ERROR::set_msg(THD *thd, const char *msg_arg)
|
||||||
|
{
|
||||||
|
msg= strdup_root(&thd->warn_root, msg_arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Reset all warnings for the thread
|
Reset all warnings for the thread
|
||||||
|
|
||||||
@ -101,7 +114,7 @@ MYSQL_ERROR *push_warning(THD *thd, MYSQL_ERROR::enum_warning_level level,
|
|||||||
*/
|
*/
|
||||||
MEM_ROOT *old_root=my_pthread_getspecific_ptr(MEM_ROOT*,THR_MALLOC);
|
MEM_ROOT *old_root=my_pthread_getspecific_ptr(MEM_ROOT*,THR_MALLOC);
|
||||||
my_pthread_setspecific_ptr(THR_MALLOC, &thd->warn_root);
|
my_pthread_setspecific_ptr(THR_MALLOC, &thd->warn_root);
|
||||||
err = new MYSQL_ERROR(code, level, msg);
|
err= new MYSQL_ERROR(thd, code, level, msg);
|
||||||
if (err)
|
if (err)
|
||||||
thd->warn_list.push_back(err);
|
thd->warn_list.push_back(err);
|
||||||
my_pthread_setspecific_ptr(THR_MALLOC, old_root);
|
my_pthread_setspecific_ptr(THR_MALLOC, old_root);
|
||||||
|
@ -37,7 +37,6 @@ int my_snprintf(char* to, size_t n, const char* fmt, ...)
|
|||||||
{
|
{
|
||||||
int result;
|
int result;
|
||||||
va_list args;
|
va_list args;
|
||||||
int result;
|
|
||||||
va_start(args,fmt);
|
va_start(args,fmt);
|
||||||
result= my_vsnprintf(to, n, fmt, args);
|
result= my_vsnprintf(to, n, fmt, args);
|
||||||
va_end(args);
|
va_end(args);
|
||||||
|
Reference in New Issue
Block a user