summaryrefslogtreecommitdiff
path: root/sql/item_sum.cc
diff options
context:
space:
mode:
authorMichael Widenius <monty@mariadb.org>2014-09-23 13:57:29 +0300
committerMichael Widenius <monty@mariadb.org>2014-09-23 13:57:29 +0300
commitbab638d842a8a561b9287f4b32a5848069c134f3 (patch)
tree30ba324e0442800d4d9aba80e2bd866c61e3db9f /sql/item_sum.cc
parente41bca0066ddcda39b5a3eef17deae066cd113d9 (diff)
downloadmariadb-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.cc26
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;
}