From 0c9bae6e8e194d5a332bcc1f99eb86a0e03e7f7c Mon Sep 17 00:00:00 2001 From: unknown Date: Wed, 10 Nov 2004 14:36:21 +0400 Subject: [PATCH] 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(). --- mysql-test/r/count_distinct.result | 7 +++++ mysql-test/r/func_gconcat.result | 7 +++++ mysql-test/t/count_distinct.test | 8 ++++++ mysql-test/t/func_gconcat.test | 9 ++++++ sql/sql_select.cc | 44 ++++++++++++++++++++++-------- 5 files changed, 64 insertions(+), 11 deletions(-) diff --git a/mysql-test/r/count_distinct.result b/mysql-test/r/count_distinct.result index 16460580d6c..1bc1ad6a31e 100644 --- a/mysql-test/r/count_distinct.result +++ b/mysql-test/r/count_distinct.result @@ -53,3 +53,10 @@ select count(distinct f) from t1; count(distinct f) 0 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; diff --git a/mysql-test/r/func_gconcat.result b/mysql-test/r/func_gconcat.result index 22868aa03c4..dfaf5758699 100644 --- a/mysql-test/r/func_gconcat.result +++ b/mysql-test/r/func_gconcat.result @@ -457,3 +457,10 @@ group_concat(distinct b order by b) Warnings: Warning 1260 2 line(s) were cut by GROUP_CONCAT() 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; diff --git a/mysql-test/t/count_distinct.test b/mysql-test/t/count_distinct.test index 1f0404876cb..73c6951e78f 100644 --- a/mysql-test/t/count_distinct.test +++ b/mysql-test/t/count_distinct.test @@ -55,3 +55,11 @@ create table t1 (f int); select count(distinct f) from 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; diff --git a/mysql-test/t/func_gconcat.test b/mysql-test/t/func_gconcat.test index e0737a42221..c5147dc381e 100644 --- a/mysql-test/t/func_gconcat.test +++ b/mysql-test/t/func_gconcat.test @@ -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; 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; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 18ffb7079c8..b2da617ca1f 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -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 copy_sum_funcs(Item_sum **func_ptr); 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 update_sum_func(Item_sum **func); static void select_describe(JOIN *join, bool need_tmp_table,bool need_order, @@ -990,13 +991,15 @@ JOIN::optimize() if (create_sort_index(thd, this, group_list, HA_POS_ERROR, HA_POS_ERROR) || 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); group_list=0; } 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); if (!group_list && ! exec_tmp_table1->distinct && order && simple_order) { @@ -1372,6 +1375,7 @@ JOIN::exec() } if (curr_join->make_sum_func_list(*curr_all_fields, *curr_fields_list, 1, TRUE) || + setup_sum_funcs(curr_join->thd, curr_join->sum_funcs) || (tmp_error= do_select(curr_join, (List *) 0, curr_tmp_table, 0))) { @@ -1459,7 +1463,9 @@ JOIN::exec() set_items_ref_array(items3); 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; } if (curr_join->group_list || curr_join->order) @@ -11794,9 +11800,6 @@ bool JOIN::alloc_func_list() before_group_by Set to 1 if this is called before GROUP BY handling recompute Set to TRUE if sum_funcs must be recomputed - NOTES - Calls ::setup() for all item_sum objects in field_list - RETURN 0 ok 1 error @@ -11817,12 +11820,7 @@ bool JOIN::make_sum_func_list(List &field_list, List &send_fields, while ((item=it++)) { if (item->type() == Item::SUM_FUNC_ITEM && !item->const_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) { @@ -11967,6 +11965,30 @@ change_refs_to_tmp_fields(THD *thd, Item **ref_pointer_array, 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 init_tmptable_sum_functions(Item_sum **func_ptr) {