Commit 0dbe92b4 authored by unknown's avatar unknown

A fix (bug #6475: Another server crash in 5.0.2

       bug #6515: count(distinct...) crashes the server)


mysql-test/r/count_distinct.result:
  A test case (bug #6515: count(distinct...) crashes the server)
mysql-test/r/func_gconcat.result:
  A test case (bug #6475: Another server crash in 5.0.2)
mysql-test/t/count_distinct.test:
  A test case (bug #6515: count(distinct...) crashes the server)
mysql-test/t/func_gconcat.test:
  A test case (bug #6475: Another server crash in 5.0.2)
sql/sql_select.cc:
  A fix (bug #6475: Another server crash in 5.0.2
         bug #6515: count(distinct...) crashes the server)
  In order to prevent repeated setup() call in the JOIN::make_sum_func_list(),
  the code was splitted: new setup_sum_funcs() was introduced.
  Note: we don't call setup_sum_funcs() in the opt_range.cc:get_best_group_min_max().
parent 04ff81ae
...@@ -53,3 +53,10 @@ select count(distinct f) from t1; ...@@ -53,3 +53,10 @@ select count(distinct f) from t1;
count(distinct f) count(distinct f)
0 0
drop table t1; drop table t1;
create table t1 (a char(3), b char(20), primary key (a, b));
insert into t1 values ('ABW', 'Dutch'), ('ABW', 'English');
select count(distinct a) from t1 group by b;
count(distinct a)
1
1
drop table t1;
...@@ -457,3 +457,10 @@ group_concat(distinct b order by b) ...@@ -457,3 +457,10 @@ group_concat(distinct b order by b)
Warnings: Warnings:
Warning 1260 2 line(s) were cut by GROUP_CONCAT() Warning 1260 2 line(s) were cut by GROUP_CONCAT()
drop table t1; drop table t1;
create table t1 (a char(3), b char(20), primary key (a, b));
insert into t1 values ('ABW', 'Dutch'), ('ABW', 'English');
select group_concat(a) from t1 group by b;
group_concat(a)
ABW
ABW
drop table t1;
...@@ -55,3 +55,11 @@ create table t1 (f int); ...@@ -55,3 +55,11 @@ create table t1 (f int);
select count(distinct f) from t1; select count(distinct f) from t1;
drop table t1; drop table t1;
#
# Bug #6515
#
create table t1 (a char(3), b char(20), primary key (a, b));
insert into t1 values ('ABW', 'Dutch'), ('ABW', 'English');
select count(distinct a) from t1 group by b;
drop table t1;
...@@ -277,3 +277,12 @@ select group_concat(b order by b) from t1 group by a; ...@@ -277,3 +277,12 @@ select group_concat(b order by b) from t1 group by a;
select group_concat(distinct b order by b) from t1 group by a; select group_concat(distinct b order by b) from t1 group by a;
drop table t1; drop table t1;
#
# Bug #6475
#
create table t1 (a char(3), b char(20), primary key (a, b));
insert into t1 values ('ABW', 'Dutch'), ('ABW', 'English');
select group_concat(a) from t1 group by b;
drop table t1;
...@@ -192,6 +192,7 @@ static void init_tmptable_sum_functions(Item_sum **func); ...@@ -192,6 +192,7 @@ static void init_tmptable_sum_functions(Item_sum **func);
static void update_tmptable_sum_func(Item_sum **func,TABLE *tmp_table); static void update_tmptable_sum_func(Item_sum **func,TABLE *tmp_table);
static void copy_sum_funcs(Item_sum **func_ptr); static void copy_sum_funcs(Item_sum **func_ptr);
static bool add_ref_to_table_cond(THD *thd, JOIN_TAB *join_tab); static bool add_ref_to_table_cond(THD *thd, JOIN_TAB *join_tab);
static bool setup_sum_funcs(THD *thd, Item_sum **func_ptr);
static bool init_sum_functions(Item_sum **func, Item_sum **end); static bool init_sum_functions(Item_sum **func, Item_sum **end);
static bool update_sum_func(Item_sum **func); static bool update_sum_func(Item_sum **func);
static void select_describe(JOIN *join, bool need_tmp_table,bool need_order, static void select_describe(JOIN *join, bool need_tmp_table,bool need_order,
...@@ -990,13 +991,15 @@ JOIN::optimize() ...@@ -990,13 +991,15 @@ JOIN::optimize()
if (create_sort_index(thd, this, group_list, if (create_sort_index(thd, this, group_list,
HA_POS_ERROR, HA_POS_ERROR) || HA_POS_ERROR, HA_POS_ERROR) ||
alloc_group_fields(this, group_list) || alloc_group_fields(this, group_list) ||
make_sum_func_list(all_fields, fields_list, 1)) make_sum_func_list(all_fields, fields_list, 1) ||
setup_sum_funcs(thd, sum_funcs))
DBUG_RETURN(1); DBUG_RETURN(1);
group_list=0; group_list=0;
} }
else else
{ {
if (make_sum_func_list(all_fields, fields_list, 0)) if (make_sum_func_list(all_fields, fields_list, 0) ||
setup_sum_funcs(thd, sum_funcs))
DBUG_RETURN(1); DBUG_RETURN(1);
if (!group_list && ! exec_tmp_table1->distinct && order && simple_order) if (!group_list && ! exec_tmp_table1->distinct && order && simple_order)
{ {
...@@ -1372,6 +1375,7 @@ JOIN::exec() ...@@ -1372,6 +1375,7 @@ JOIN::exec()
} }
if (curr_join->make_sum_func_list(*curr_all_fields, *curr_fields_list, if (curr_join->make_sum_func_list(*curr_all_fields, *curr_fields_list,
1, TRUE) || 1, TRUE) ||
setup_sum_funcs(curr_join->thd, curr_join->sum_funcs) ||
(tmp_error= do_select(curr_join, (List<Item> *) 0, curr_tmp_table, (tmp_error= do_select(curr_join, (List<Item> *) 0, curr_tmp_table,
0))) 0)))
{ {
...@@ -1459,7 +1463,9 @@ JOIN::exec() ...@@ -1459,7 +1463,9 @@ JOIN::exec()
set_items_ref_array(items3); set_items_ref_array(items3);
if (curr_join->make_sum_func_list(*curr_all_fields, *curr_fields_list, if (curr_join->make_sum_func_list(*curr_all_fields, *curr_fields_list,
1, TRUE) || thd->is_fatal_error) 1, TRUE) ||
setup_sum_funcs(curr_join->thd, curr_join->sum_funcs) ||
thd->is_fatal_error)
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
} }
if (curr_join->group_list || curr_join->order) if (curr_join->group_list || curr_join->order)
...@@ -11794,9 +11800,6 @@ bool JOIN::alloc_func_list() ...@@ -11794,9 +11800,6 @@ bool JOIN::alloc_func_list()
before_group_by Set to 1 if this is called before GROUP BY handling before_group_by Set to 1 if this is called before GROUP BY handling
recompute Set to TRUE if sum_funcs must be recomputed recompute Set to TRUE if sum_funcs must be recomputed
NOTES
Calls ::setup() for all item_sum objects in field_list
RETURN RETURN
0 ok 0 ok
1 error 1 error
...@@ -11817,12 +11820,7 @@ bool JOIN::make_sum_func_list(List<Item> &field_list, List<Item> &send_fields, ...@@ -11817,12 +11820,7 @@ bool JOIN::make_sum_func_list(List<Item> &field_list, List<Item> &send_fields,
while ((item=it++)) while ((item=it++))
{ {
if (item->type() == Item::SUM_FUNC_ITEM && !item->const_item()) if (item->type() == Item::SUM_FUNC_ITEM && !item->const_item())
{
*func++= (Item_sum*) item; *func++= (Item_sum*) item;
/* let COUNT(DISTINCT) create the temporary table */
if (((Item_sum*) item)->setup(thd))
DBUG_RETURN(TRUE);
}
} }
if (before_group_by && rollup.state == ROLLUP::STATE_INITED) if (before_group_by && rollup.state == ROLLUP::STATE_INITED)
{ {
...@@ -11967,6 +11965,30 @@ change_refs_to_tmp_fields(THD *thd, Item **ref_pointer_array, ...@@ -11967,6 +11965,30 @@ change_refs_to_tmp_fields(THD *thd, Item **ref_pointer_array,
Code for calculating functions Code for calculating functions
******************************************************************************/ ******************************************************************************/
/*
Call ::setup for all sum functions
SYNOPSIS
setup_sum_funcs()
thd thread handler
func_ptr sum function list
RETURN
FALSE ok
TRUE error
*/
static bool setup_sum_funcs(THD *thd, Item_sum **func_ptr)
{
Item_sum *func;
while ((func= *(func_ptr++)))
if (func->setup(thd))
return TRUE;
return FALSE;
}
static void static void
init_tmptable_sum_functions(Item_sum **func_ptr) init_tmptable_sum_functions(Item_sum **func_ptr)
{ {
......
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