summaryrefslogtreecommitdiff
path: root/sql/item_sum.cc
diff options
context:
space:
mode:
authorSergei Golubchik <serg@mariadb.org>2015-07-31 22:09:46 +0200
committerSergei Golubchik <serg@mariadb.org>2015-07-31 22:09:46 +0200
commit96badb16afcf8a6ae3d03918419fc51ace4be236 (patch)
tree86469f7d770524acbca2ac44e1300ae46296224a /sql/item_sum.cc
parent409709ec7edc0dd6eb725e766f0d4c52192accfc (diff)
downloadmariadb-git-96badb16afcf8a6ae3d03918419fc51ace4be236.tar.gz
MDEV-7821 Server crashes in Item_func_group_concat::fix_fields on 2nd execution of PS
Correct fix for this bug. The problem was that Item_func_group_concat() was calling setup_order(), passing args as the second argument, ref_pointer_array. While ref_pointer_array should have free space at the end, as setup_order() can append elements to it. In this particular case args[] elements were overwritten when setup_order() was pushing new elements into ref_pointer_array.
Diffstat (limited to 'sql/item_sum.cc')
-rw-r--r--sql/item_sum.cc16
1 files changed, 10 insertions, 6 deletions
diff --git a/sql/item_sum.cc b/sql/item_sum.cc
index a24307b131b..9000289fd33 100644
--- a/sql/item_sum.cc
+++ b/sql/item_sum.cc
@@ -3300,8 +3300,6 @@ void Item_func_group_concat::cleanup()
from Item_func_group_concat::setup() to point to runtime
created objects, we need to reset them back to the original
arguments of the function.
-
- The very same applies to args array.
*/
ORDER **order_ptr= order;
for (uint i= 0; i < arg_count_order; i++)
@@ -3309,7 +3307,6 @@ void Item_func_group_concat::cleanup()
(*order_ptr)->item= &args[arg_count_field + i];
order_ptr++;
}
- memcpy(args, orig_args, sizeof(Item *) * arg_count);
DBUG_VOID_RETURN;
}
@@ -3517,9 +3514,16 @@ bool Item_func_group_concat::setup(THD *thd)
"all_fields". The resulting field list is used as input to create
tmp table columns.
*/
- if (arg_count_order &&
- setup_order(thd, args, context->table_list, list, all_fields, *order))
- DBUG_RETURN(TRUE);
+ if (arg_count_order)
+ {
+ uint n_elems= arg_count_order + all_fields.elements;
+ ref_pointer_array= static_cast<Item**>(thd->alloc(sizeof(Item*) * n_elems));
+ memcpy(ref_pointer_array, args, arg_count * sizeof(Item*));
+ if (!ref_pointer_array ||
+ setup_order(thd, ref_pointer_array, context->table_list, list,
+ all_fields, *order))
+ DBUG_RETURN(TRUE);
+ }
count_field_types(select_lex, tmp_table_param, all_fields, 0);
tmp_table_param->force_copy_fields= force_copy_fields;