summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mysql-test/r/func_gconcat.result21
-rw-r--r--mysql-test/t/func_gconcat.test16
-rw-r--r--sql/item_sum.cc19
-rw-r--r--sql/table.h1
4 files changed, 53 insertions, 4 deletions
diff --git a/mysql-test/r/func_gconcat.result b/mysql-test/r/func_gconcat.result
index 766f3b6bfaa..ae48eb1e0ff 100644
--- a/mysql-test/r/func_gconcat.result
+++ b/mysql-test/r/func_gconcat.result
@@ -995,6 +995,7 @@ SELECT 1 FROM
1
1
DROP TABLE t1;
+End of 5.0 tests
#
# Bug #52397: another crash with explain extended and group_concat
#
@@ -1010,4 +1011,22 @@ id select_type table type possible_keys key key_len ref rows filtered Extra
Warnings:
Note 1003 select 1 AS `1` from (select group_concat(`test`.`t1`.`a` order by `test`.`t1`.`a` ASC separator ',') AS `GROUP_CONCAT(t1.a ORDER BY t1.a ASC)` from `test`.`t1` `t2` join `test`.`t1` group by `test`.`t1`.`a`) `d`
DROP TABLE t1;
-End of 5.0 tests
+#
+# Bug #54476: crash when group_concat and 'with rollup' in prepared statements
+#
+CREATE TABLE t1 (a INT);
+INSERT INTO t1 VALUES (1), (2);
+PREPARE stmt FROM "SELECT GROUP_CONCAT(t1.a ORDER BY t1.a) FROM t1 JOIN t1 t2 GROUP BY t1.a WITH ROLLUP";
+EXECUTE stmt;
+GROUP_CONCAT(t1.a ORDER BY t1.a)
+1,1
+2,2
+1,1,2,2
+EXECUTE stmt;
+GROUP_CONCAT(t1.a ORDER BY t1.a)
+1,1
+2,2
+1,1,2,2
+DEALLOCATE PREPARE stmt;
+DROP TABLE t1;
+End of 5.1 tests
diff --git a/mysql-test/t/func_gconcat.test b/mysql-test/t/func_gconcat.test
index e832ea316eb..926c1f92855 100644
--- a/mysql-test/t/func_gconcat.test
+++ b/mysql-test/t/func_gconcat.test
@@ -708,6 +708,7 @@ SELECT 1 FROM
DROP TABLE t1;
+--echo End of 5.0 tests
--echo #
--echo # Bug #52397: another crash with explain extended and group_concat
@@ -719,5 +720,18 @@ EXPLAIN EXTENDED SELECT 1 FROM
t1 t2, t1 GROUP BY t1.a) AS d;
DROP TABLE t1;
+--echo #
+--echo # Bug #54476: crash when group_concat and 'with rollup' in prepared statements
+--echo #
---echo End of 5.0 tests
+CREATE TABLE t1 (a INT);
+INSERT INTO t1 VALUES (1), (2);
+
+PREPARE stmt FROM "SELECT GROUP_CONCAT(t1.a ORDER BY t1.a) FROM t1 JOIN t1 t2 GROUP BY t1.a WITH ROLLUP";
+EXECUTE stmt;
+EXECUTE stmt;
+
+DEALLOCATE PREPARE stmt;
+DROP TABLE t1;
+
+--echo End of 5.1 tests
diff --git a/sql/item_sum.cc b/sql/item_sum.cc
index 228e36fc9f9..1048bd3d6ff 100644
--- a/sql/item_sum.cc
+++ b/sql/item_sum.cc
@@ -3034,7 +3034,6 @@ Item_func_group_concat::Item_func_group_concat(THD *thd,
tree(item->tree),
unique_filter(item->unique_filter),
table(item->table),
- order(item->order),
context(item->context),
arg_count_order(item->arg_count_order),
arg_count_field(item->arg_count_field),
@@ -3047,6 +3046,24 @@ Item_func_group_concat::Item_func_group_concat(THD *thd,
{
quick_group= item->quick_group;
result.set_charset(collation.collation);
+
+ /*
+ Since the ORDER structures pointed to by the elements of the 'order' array
+ may be modified in find_order_in_list() called from
+ Item_func_group_concat::setup(), create a copy of those structures so that
+ such modifications done in this object would not have any effect on the
+ object being copied.
+ */
+ ORDER *tmp;
+ if (!(order= (ORDER **) thd->alloc(sizeof(ORDER *) * arg_count_order +
+ sizeof(ORDER) * arg_count_order)))
+ return;
+ tmp= (ORDER *)(order + arg_count_order);
+ for (uint i= 0; i < arg_count_order; i++, tmp++)
+ {
+ memcpy(tmp, item->order[i], sizeof(ORDER));
+ order[i]= tmp;
+ }
}
diff --git a/sql/table.h b/sql/table.h
index 3ef3c5e0cb2..9088b3b6965 100644
--- a/sql/table.h
+++ b/sql/table.h
@@ -55,7 +55,6 @@ typedef struct st_order {
struct st_order *next;
Item **item; /* Point at item in select fields */
Item *item_ptr; /* Storage for initial item */
- Item **item_copy; /* For SPs; the original item ptr */
int counter; /* position in SELECT list, correct
only if counter_used is true*/
bool asc; /* true if ascending */