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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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 ...@@ -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)), ...@@ -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)), ...@@ -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() ...@@ -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 @@ class Item_sum_udf_str :public Item_sum_num ...@@ -631,12 +631,14 @@ class Item_sum_udf_str :public Item_sum_num
#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 @@ class MYSQL_ERROR: public Sql_alloc ...@@ -301,17 +301,14 @@ class MYSQL_ERROR: public Sql_alloc
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 ...@@ -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
...@@ -91,7 +104,7 @@ MYSQL_ERROR *push_warning(THD *thd, MYSQL_ERROR::enum_warning_level level, ...@@ -91,7 +104,7 @@ MYSQL_ERROR *push_warning(THD *thd, MYSQL_ERROR::enum_warning_level level,
if (thd->query_id != thd->warn_id) if (thd->query_id != thd->warn_id)
mysql_reset_errors(thd); mysql_reset_errors(thd);
MYSQL_ERROR *err = NULL; MYSQL_ERROR *err= NULL;
if (thd->warn_list.elements < thd->variables.max_error_count) 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, ...@@ -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, ...) ...@@ -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);
......
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