Commit bab638d8 authored by Michael Widenius's avatar Michael Widenius

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
parent e41bca00
drop table if exists t1,t2; drop table if exists t1,t2,t3,t4,t5,t6;
set @sav_dpi= @@div_precision_increment; set @sav_dpi= @@div_precision_increment;
set div_precision_increment= 5; set div_precision_increment= 5;
show variables like 'div_precision_increment'; show variables like 'div_precision_increment';
...@@ -2239,3 +2239,34 @@ explain select MIN(b) from t1 where b >= inet_aton('192.168.119.32'); ...@@ -2239,3 +2239,34 @@ explain select MIN(b) from t1 where b >= inet_aton('192.168.119.32');
id select_type table type possible_keys key key_len ref rows Extra id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Select tables optimized away 1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Select tables optimized away
DROP TABLE t1; DROP TABLE t1;
#
# MDEV-6743 crash in GROUP_CONCAT(IF () ORDER BY 1)
#
CREATE TABLE t1 (pk INT, t2_id INT, t5_id INT, PRIMARY KEY (pk));
INSERT INTO t1 VALUES (1,3,12),(2,3,15);
CREATE TABLE t2 (pk INT, PRIMARY KEY (pk));
INSERT INTO t2 VALUES (4),(5);
CREATE TABLE t3 (t2_id INT, t4_id INT);
INSERT INTO t3 VALUES (6,11),(7,12);
CREATE TABLE t4 (id INT);
INSERT INTO t4 VALUES (13),(14);
CREATE TABLE t5 (pk INT, f VARCHAR(50), t6_id INT, PRIMARY KEY (pk));
INSERT INTO t5 VALUES (9,'FOO',NULL);
CREATE TABLE t6 (pk INT, f VARCHAR(120), b TINYINT(4), PRIMARY KEY (pk));
PREPARE stmt FROM "
SELECT t1.t2_id, GROUP_CONCAT(IF (t6.b, t6.f, t5.f) ORDER BY 1)
FROM t1
JOIN t2 ON t1.t2_id = t2.pk
JOIN t3 ON t2.pk = t3.t2_id
JOIN t4 ON t4.id = t3.t4_id
JOIN t5 ON t1.t5_id = t5.pk
LEFT JOIN t6 ON t6.pk = t5.t6_id
GROUP BY t1.t2_id
";
EXECUTE stmt;
t2_id GROUP_CONCAT(IF (t6.b, t6.f, t5.f) ORDER BY 1)
EXECUTE stmt;
t2_id GROUP_CONCAT(IF (t6.b, t6.f, t5.f) ORDER BY 1)
EXECUTE stmt;
t2_id GROUP_CONCAT(IF (t6.b, t6.f, t5.f) ORDER BY 1)
DROP TABLE t1,t2,t3,t4,t5,t6;
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
# #
--disable_warnings --disable_warnings
drop table if exists t1,t2; drop table if exists t1,t2,t3,t4,t5,t6;
--enable_warnings --enable_warnings
set @sav_dpi= @@div_precision_increment; set @sav_dpi= @@div_precision_increment;
...@@ -1528,3 +1528,40 @@ insert into t1 (b) values (INET_ATON('192.168.200.200')); ...@@ -1528,3 +1528,40 @@ insert into t1 (b) values (INET_ATON('192.168.200.200'));
explain select MIN(b) from t1 where b >= inet_aton('192.168.119.32'); explain select MIN(b) from t1 where b >= inet_aton('192.168.119.32');
DROP TABLE t1; DROP TABLE t1;
--echo #
--echo # MDEV-6743 crash in GROUP_CONCAT(IF () ORDER BY 1)
--echo #
CREATE TABLE t1 (pk INT, t2_id INT, t5_id INT, PRIMARY KEY (pk));
INSERT INTO t1 VALUES (1,3,12),(2,3,15);
CREATE TABLE t2 (pk INT, PRIMARY KEY (pk));
INSERT INTO t2 VALUES (4),(5);
CREATE TABLE t3 (t2_id INT, t4_id INT);
INSERT INTO t3 VALUES (6,11),(7,12);
CREATE TABLE t4 (id INT);
INSERT INTO t4 VALUES (13),(14);
CREATE TABLE t5 (pk INT, f VARCHAR(50), t6_id INT, PRIMARY KEY (pk));
INSERT INTO t5 VALUES (9,'FOO',NULL);
CREATE TABLE t6 (pk INT, f VARCHAR(120), b TINYINT(4), PRIMARY KEY (pk));
PREPARE stmt FROM "
SELECT t1.t2_id, GROUP_CONCAT(IF (t6.b, t6.f, t5.f) ORDER BY 1)
FROM t1
JOIN t2 ON t1.t2_id = t2.pk
JOIN t3 ON t2.pk = t3.t2_id
JOIN t4 ON t4.id = t3.t4_id
JOIN t5 ON t1.t5_id = t5.pk
LEFT JOIN t6 ON t6.pk = t5.t6_id
GROUP BY t1.t2_id
";
EXECUTE stmt;
EXECUTE stmt;
EXECUTE stmt;
DROP TABLE t1,t2,t3,t4,t5,t6;
...@@ -3181,19 +3181,13 @@ Item_func_group_concat(Name_resolution_context *context_arg, ...@@ -3181,19 +3181,13 @@ Item_func_group_concat(Name_resolution_context *context_arg,
/* /*
We need to allocate: We need to allocate:
args - arg_count_field+arg_count_order 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 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))) sizeof(ORDER*)*arg_count_order)))
return; return;
if (!(orig_args= (Item **) sql_alloc(sizeof(Item *) * arg_count)))
{
args= NULL;
return;
}
order= (ORDER**)(args + arg_count); order= (ORDER**)(args + arg_count);
/* fill args items of show and sort */ /* fill args items of show and sort */
...@@ -3214,6 +3208,9 @@ Item_func_group_concat(Name_resolution_context *context_arg, ...@@ -3214,6 +3208,9 @@ Item_func_group_concat(Name_resolution_context *context_arg,
order_item->item= arg_ptr++; 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); memcpy(orig_args, args, sizeof(Item*) * arg_count);
} }
...@@ -3297,6 +3294,19 @@ void Item_func_group_concat::cleanup() ...@@ -3297,6 +3294,19 @@ void Item_func_group_concat::cleanup()
} }
DBUG_ASSERT(tree == 0); 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; DBUG_VOID_RETURN;
} }
......
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