diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result index 08954d00c34..bba86ff8891 100644 --- a/mysql-test/r/subselect.result +++ b/mysql-test/r/subselect.result @@ -1213,3 +1213,15 @@ SELECT 'c373e9f5ad0791a0dab5444553544200' IN(SELECT t1.FOLDERID FROM t1 WHERE t1 'c373e9f5ad0791a0dab5444553544200' IN(SELECT t1.FOLDERID FROM t1 WHERE t1.PARENTID='2f6161e879db43c1a5b82c21ddc49089' AND t1.FOLDERNAME = 'Level1') 0 drop table t1; +create table t1 (a int, b int); +create table t2 (a int, b int); +create table t3 (a int, b int); +insert into t1 values (0,100),(1,2), (1,3), (2,2), (2,7), (2,-1), (3,10); +insert into t2 values (0,0), (1,1), (2,1), (3,1), (4,1); +insert into t3 values (3,3), (2,2), (1,1); +select a,(select count(distinct t1.b) as sum from t1,t2 where t1.a=t2.a and t2.b > 0 and t1.a <= t3.b group by t1.a order by sum limit 1) from t3; +a (select count(distinct t1.b) as sum from t1,t2 where t1.a=t2.a and t2.b > 0 and t1.a <= t3.b group by t1.a order by sum limit 1) +3 1 +2 2 +1 2 +drop table t1,t2,t3; diff --git a/mysql-test/t/subselect.test b/mysql-test/t/subselect.test index 17738ae0c16..e4b61244556 100644 --- a/mysql-test/t/subselect.test +++ b/mysql-test/t/subselect.test @@ -805,3 +805,14 @@ INSERT INTO t1 VALUES("2f6161e879db43c1a5b82c21ddc49089", "Default", "System", " INSERT INTO t1 VALUES("c373e9f5ad0791724315444553544200", "AddDocumentTest", "admin", "2003-06-09 10:51:25", "Movie Reviews", "0", "2003-06-09 10:51:25", "admin", "0", "2f6161e879db43c1a5b82c21ddc49089", "03eea05112b845949f3fd03278b5fe43", NULL); SELECT 'c373e9f5ad0791a0dab5444553544200' IN(SELECT t1.FOLDERID FROM t1 WHERE t1.PARENTID='2f6161e879db43c1a5b82c21ddc49089' AND t1.FOLDERNAME = 'Level1'); drop table t1; +# +# alloc_group_fields() working +# +create table t1 (a int, b int); +create table t2 (a int, b int); +create table t3 (a int, b int); +insert into t1 values (0,100),(1,2), (1,3), (2,2), (2,7), (2,-1), (3,10); +insert into t2 values (0,0), (1,1), (2,1), (3,1), (4,1); +insert into t3 values (3,3), (2,2), (1,1); +select a,(select count(distinct t1.b) as sum from t1,t2 where t1.a=t2.a and t2.b > 0 and t1.a <= t3.b group by t1.a order by sum limit 1) from t3; +drop table t1,t2,t3;s diff --git a/sql/sql_select.cc b/sql/sql_select.cc index a5f6cfeb4fb..e45e9e64f94 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -142,6 +142,7 @@ static ORDER *create_distinct_group(THD *thd, ORDER *order, static bool test_if_subpart(ORDER *a,ORDER *b); static TABLE *get_sort_by_table(ORDER *a,ORDER *b,TABLE_LIST *tables); static void calc_group_buffer(JOIN *join,ORDER *group); +static bool make_group_fields(JOIN *main_join, JOIN *curr_join); static bool alloc_group_fields(JOIN *join,ORDER *group); // Create list for using with tempory table static bool change_to_use_tmp_fields(THD *thd, Item **ref_pointer_array, @@ -1122,12 +1123,12 @@ JOIN::exec() DBUG_VOID_RETURN; curr_join->exec_tmp_table2= exec_tmp_table2; } - if (group_list) + if (curr_join->group_list) { thd->proc_info= "Creating sort index"; if (create_sort_index(thd, curr_join->join_tab, curr_join->group_list, HA_POS_ERROR, HA_POS_ERROR) || - alloc_group_fields(curr_join, curr_join->group_list)) + make_group_fields(this, curr_join)) { DBUG_VOID_RETURN; } @@ -1194,7 +1195,10 @@ JOIN::exec() if (curr_join->group || curr_join->tmp_table_param.sum_func_count || (procedure && (procedure->flags & PROC_GROUP))) { - alloc_group_fields(curr_join, curr_join->group_list); + if (make_group_fields(this, curr_join)) + { + DBUG_VOID_RETURN; + } if (!items3) { if (!items0) @@ -7651,6 +7655,37 @@ calc_group_buffer(JOIN *join,ORDER *group) join->tmp_table_param.group_null_parts=null_parts; } +/* + alloc group fields or take prepared (chached) + + SYNOPSYS + make_group_fields() + main_join - join of current select + curr_join - current join (join of current select or temporary copy of it) + + RETURN + 0 - ok + 1 - failed +*/ + +static bool +make_group_fields(JOIN *main_join, JOIN *curr_join) +{ + if (main_join->group_fields_cache.elements) + { + curr_join->group_fields= main_join->group_fields_cache; + curr_join->sort_and_group= 1; + } + else + { + if (alloc_group_fields(curr_join, curr_join->group_list)) + { + return (1); + } + main_join->group_fields_cache= curr_join->group_fields; + } + return (0); +} /* Get a list of buffers for saveing last group @@ -7677,6 +7712,7 @@ alloc_group_fields(JOIN *join,ORDER *group) static int test_if_group_changed(List &list) { + DBUG_ENTER("test_if_group_changed"); List_iterator li(list); int idx= -1,i; Item_buff *buff; @@ -7686,7 +7722,8 @@ test_if_group_changed(List &list) if (buff->cmp()) idx=i; } - return idx; + DBUG_PRINT("info", ("idx: %d", idx)); + DBUG_RETURN(idx); } diff --git a/sql/sql_select.h b/sql/sql_select.h index f29729fb5b3..aa08c5c1725 100644 --- a/sql/sql_select.h +++ b/sql/sql_select.h @@ -140,7 +140,7 @@ class JOIN :public Sql_alloc POSITION positions[MAX_TABLES+1],best_positions[MAX_TABLES+1]; double best_read; List *fields; - List group_fields; + List group_fields, group_fields_cache; TABLE *tmp_table; // used to store 2 possible tmp table of SELECT TABLE *exec_tmp_table1, *exec_tmp_table2;