Commit 4a483805 authored by monty@narttu.mysql.fi's avatar monty@narttu.mysql.fi

Fixed bug in warning handling (Memory was allocated from wrong MEM_ROOT)

parent 22075460
......@@ -1344,7 +1344,8 @@ String *Item_sum_udf_str::val_str(String *str)
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;
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);
/*
if key1 and key2 is not equal than field->key_cmp return offset. This function
must return value 1 for this case.
if key1 and key2 is not equal than field->key_cmp return offset. This
function must return value 1 for this case.
*/
if (res)
return 1;
......@@ -1367,6 +1368,7 @@ static int group_concat_key_cmp_with_distinct(void* arg, byte* key1, byte* key2)
return 0;
}
/*
function of sort for syntax:
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;
}
/*
function of sort for syntax:
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));
}
/*
create result
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;
}
/*
Constructor of Item_func_group_concat
is_distinct - distinct
......@@ -1476,17 +1481,13 @@ static int dump_leaf_key(byte* key, uint32 count __attribute__((unused)),
is_separator - string value of separator
*/
Item_func_group_concat::Item_func_group_concat(int is_distinct,List<Item> *is_select,
SQL_LIST *is_order,String *is_separator):
Item_sum(),
tmp_table_param(0),
warning_available(false),
separator(is_separator),
tree(&tree_base),
table(0),
distinct(is_distinct),
tree_mode(0),
count_cut_values(0)
Item_func_group_concat::Item_func_group_concat(int is_distinct,
List<Item> *is_select,
SQL_LIST *is_order,
String *is_separator)
:Item_sum(), tmp_table_param(0), warning_available(false),
separator(is_separator), tree(&tree_base), table(0), distinct(is_distinct),
tree_mode(0), count_cut_values(0)
{
original= 0;
quick_group= 0;
......@@ -1551,14 +1552,15 @@ Item_func_group_concat::~Item_func_group_concat()
*/
if (!original)
{
THD *thd= current_thd;
if (warning_available)
{
char warn_buff[MYSQL_ERRMSG_SIZE];
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)
free_tmp_table(current_thd, table);
free_tmp_table(thd, table);
if (tmp_table_param)
delete tmp_table_param;
if (tree_mode)
......
......@@ -631,12 +631,14 @@ public:
#endif /* HAVE_DLOPEN */
class MYSQL_ERROR;
class Item_func_group_concat : public Item_sum
{
THD *item_thd;
TMP_TABLE_PARAM *tmp_table_param;
uint max_elements_in_tree;
void *warning;
MYSQL_ERROR *warning;
bool warning_available;
public:
String result;
......
......@@ -301,17 +301,14 @@ public:
enum_warning_level level;
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)
:code(code_arg), level(level_arg)
{
if (msg_arg)
msg=sql_strdup(msg_arg);
}
inline void set_msg(const char *msg_arg)
{
msg=sql_strdup(msg_arg);
set_msg(thd, 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"
/*
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
......@@ -91,7 +104,7 @@ MYSQL_ERROR *push_warning(THD *thd, MYSQL_ERROR::enum_warning_level level,
if (thd->query_id != thd->warn_id)
mysql_reset_errors(thd);
MYSQL_ERROR *err = NULL;
MYSQL_ERROR *err= NULL;
if (thd->warn_list.elements < thd->variables.max_error_count)
{
......@@ -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);
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)
thd->warn_list.push_back(err);
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;
va_list args;
int result;
va_start(args,fmt);
result= my_vsnprintf(to, n, fmt, args);
va_end(args);
......
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