diff options
author | Michael Widenius <monty@mariadb.org> | 2014-09-23 13:57:29 +0300 |
---|---|---|
committer | Michael Widenius <monty@mariadb.org> | 2014-09-23 13:57:29 +0300 |
commit | bab638d842a8a561b9287f4b32a5848069c134f3 (patch) | |
tree | 30ba324e0442800d4d9aba80e2bd866c61e3db9f /sql/item_sum.cc | |
parent | e41bca0066ddcda39b5a3eef17deae066cd113d9 (diff) | |
download | mariadb-git-bab638d842a8a561b9287f4b32a5848069c134f3.tar.gz |
MDEV-6743 crash in GROUP_CONCAT(IF () ORDER BY 1)
mysql-test/r/func_group.result:
Test case
mysql-test/t/func_group.test:
Test case
sql/item_sum.cc:
Restore ORDER for prepared statements
Diffstat (limited to 'sql/item_sum.cc')
-rw-r--r-- | sql/item_sum.cc | 26 |
1 files changed, 18 insertions, 8 deletions
diff --git a/sql/item_sum.cc b/sql/item_sum.cc index 0395c856817..d6ecba4a754 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -3181,19 +3181,13 @@ Item_func_group_concat(Name_resolution_context *context_arg, /* We need to allocate: args - arg_count_field+arg_count_order - (for possible order items in temporare tables) + (for possible order items in temporary tables) order - arg_count_order */ - if (!(args= (Item**) sql_alloc(sizeof(Item*) * arg_count + + if (!(args= (Item**) sql_alloc(sizeof(Item*) * arg_count * 2 + sizeof(ORDER*)*arg_count_order))) return; - if (!(orig_args= (Item **) sql_alloc(sizeof(Item *) * arg_count))) - { - args= NULL; - return; - } - order= (ORDER**)(args + arg_count); /* fill args items of show and sort */ @@ -3214,6 +3208,9 @@ Item_func_group_concat(Name_resolution_context *context_arg, order_item->item= arg_ptr++; } } + + /* orig_args is only used for print() */ + orig_args= (Item**) (order + arg_count_order); memcpy(orig_args, args, sizeof(Item*) * arg_count); } @@ -3297,6 +3294,19 @@ void Item_func_group_concat::cleanup() } DBUG_ASSERT(tree == 0); } + + /* + For prepared statements we have to restore pointers for ORDER BY as + they may point to areas that are freed at cleanup(). + */ + if (!current_thd->stmt_arena->is_conventional() && arg_count_order) + { + memcpy(args + arg_count_field, orig_args + arg_count_field, + sizeof(Item*) * arg_count_order); + + for (uint i= 0 ; i < arg_count_order ; i++) + order[i]->item = args + arg_count_field + i; + } DBUG_VOID_RETURN; } |