Commit 1f28ee88 authored by Evgeny Potemkin's avatar Evgeny Potemkin
Browse files

Bug#38195: Incorrect handling of aggregate functions when loose index scan is

used causes server crash.
      
When the loose index scan access method is used values of aggregated functions
are precomputed by it. Aggregation of such functions shouldn't be performed
in this case and functions should be treated as normal ones.
The create_tmp_table function wasn't taking this into account and this led to
a crash if a query has MIN/MAX aggregate functions and employs temporary table
and loose index scan.
Now the JOIN::exec and the create_tmp_table functions treat MIN/MAX aggregate
functions as normal ones when the loose index scan is used.
parent 6677947a
Loading
Loading
Loading
Loading
+76 −0
Original line number Diff line number Diff line
@@ -2353,3 +2353,79 @@ a MIN(b) MAX(b) AVG(b)
2	1	3	2.0000
1	1	3	2.0000
DROP TABLE t1;
create table t1 (a int, b int, primary key (a,b), key `index` (a,b)) engine=MyISAM;
insert into  t1 (a,b) values 
(0,0),(0,1),(0,2),(0,3),(0,4),(0,5),(0,6),
(0,7),(0,8),(0,9),(0,10),(0,11),(0,12),(0,13),
(1,0),(1,1),(1,2),(1,3),(1,4),(1,5),(1,6),
(1,7),(1,8),(1,9),(1,10),(1,11),(1,12),(1,13),
(2,0),(2,1),(2,2),(2,3),(2,4),(2,5),(2,6),
(2,7),(2,8),(2,9),(2,10),(2,11),(2,12),(2,13),
(3,0),(3,1),(3,2),(3,3),(3,4),(3,5),(3,6),
(3,7),(3,8),(3,9),(3,10),(3,11),(3,12),(3,13);
insert into t1 (a,b) select a, max(b)+1 from t1 where a = 0 group by a;
select * from t1;
a	b
0	0
0	1
0	2
0	3
0	4
0	5
0	6
0	7
0	8
0	9
0	10
0	11
0	12
0	13
0	14
1	0
1	1
1	2
1	3
1	4
1	5
1	6
1	7
1	8
1	9
1	10
1	11
1	12
1	13
2	0
2	1
2	2
2	3
2	4
2	5
2	6
2	7
2	8
2	9
2	10
2	11
2	12
2	13
3	0
3	1
3	2
3	3
3	4
3	5
3	6
3	7
3	8
3	9
3	10
3	11
3	12
3	13
explain extended select sql_buffer_result a, max(b)+1 from t1 where a = 0 group by a;
id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
1	SIMPLE	t1	range	PRIMARY,index	PRIMARY	4	NULL	3	Using where; Using index for group-by; Using temporary
Warnings:
Note	1003	select sql_buffer_result `test`.`t1`.`a` AS `a`,(max(`test`.`t1`.`b`) + 1) AS `max(b)+1` from `test`.`t1` where (`test`.`t1`.`a` = 0) group by `test`.`t1`.`a`
drop table t1;
+19 −0
Original line number Diff line number Diff line
@@ -916,3 +916,22 @@ SELECT a, MIN(b), MAX(b), AVG(b) FROM t1 GROUP BY a ORDER BY a DESC;
SELECT a, MIN(b), MAX(b), AVG(b) FROM t1 GROUP BY a ORDER BY a DESC;

DROP TABLE t1;

#
# Bug#38195: Incorrect handling of aggregate functions when loose index scan is
#            used causes server crash.
#
create table t1 (a int, b int, primary key (a,b), key `index` (a,b)) engine=MyISAM;
insert into  t1 (a,b) values 
(0,0),(0,1),(0,2),(0,3),(0,4),(0,5),(0,6),
  (0,7),(0,8),(0,9),(0,10),(0,11),(0,12),(0,13),
(1,0),(1,1),(1,2),(1,3),(1,4),(1,5),(1,6),
  (1,7),(1,8),(1,9),(1,10),(1,11),(1,12),(1,13),
(2,0),(2,1),(2,2),(2,3),(2,4),(2,5),(2,6),
  (2,7),(2,8),(2,9),(2,10),(2,11),(2,12),(2,13),
(3,0),(3,1),(3,2),(3,3),(3,4),(3,5),(3,6),
  (3,7),(3,8),(3,9),(3,10),(3,11),(3,12),(3,13);
insert into t1 (a,b) select a, max(b)+1 from t1 where a = 0 group by a;
select * from t1;
explain extended select sql_buffer_result a, max(b)+1 from t1 where a = 0 group by a;
drop table t1;
+4 −1
Original line number Diff line number Diff line
@@ -1724,7 +1724,8 @@ JOIN::exec()
    if (!items1)
    {
      items1= items0 + all_fields.elements;
      if (sort_and_group || curr_tmp_table->group)
      if (sort_and_group || curr_tmp_table->group ||
          tmp_table_param.precomputed_group_by)
      {
	if (change_to_use_tmp_fields(thd, items1,
				     tmp_fields_list1, tmp_all_fields1,
@@ -9259,6 +9260,8 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
  MI_COLUMNDEF *recinfo;
  uint total_uneven_bit_length= 0;
  bool force_copy_fields= param->force_copy_fields;
  /* Treat sum functions as normal ones when loose index scan is used. */
  save_sum_fields|= param->precomputed_group_by;
  DBUG_ENTER("create_tmp_table");
  DBUG_PRINT("enter",("distinct: %d  save_sum_fields: %d  rows_limit: %lu  group: %d",
		      (int) distinct, (int) save_sum_fields,