diff options
Diffstat (limited to 'sql')
-rw-r--r-- | sql/sql_select.cc | 59 | ||||
-rw-r--r-- | sql/sql_select.h | 6 |
2 files changed, 59 insertions, 6 deletions
diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 78ba3027d91..67299dc47c3 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, @@ -1136,12 +1137,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; } @@ -1150,6 +1151,20 @@ JOIN::exec() thd->proc_info="Copying to group table"; tmp_error= -1; + if (curr_join != this) + { + if (sum_funcs2) + { + curr_join->sum_funcs= sum_funcs2; + curr_join->sum_funcs_end= sum_funcs_end2; + } + else + { + curr_join->alloc_func_list(); + sum_funcs2= curr_join->sum_funcs; + sum_funcs_end2= curr_join->sum_funcs_end; + } + } if (curr_join->make_sum_func_list(*curr_all_fields, *curr_fields_list, 1) || (tmp_error= do_select(curr_join, (List<Item> *) 0, curr_tmp_table, @@ -1208,7 +1223,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) @@ -7670,6 +7688,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 @@ -7696,6 +7745,7 @@ alloc_group_fields(JOIN *join,ORDER *group) static int test_if_group_changed(List<Item_buff> &list) { + DBUG_ENTER("test_if_group_changed"); List_iterator<Item_buff> li(list); int idx= -1,i; Item_buff *buff; @@ -7705,7 +7755,8 @@ test_if_group_changed(List<Item_buff> &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 a4554183312..40a097c10ad 100644 --- a/sql/sql_select.h +++ b/sql/sql_select.h @@ -140,12 +140,14 @@ class JOIN :public Sql_alloc POSITION positions[MAX_TABLES+1],best_positions[MAX_TABLES+1]; double best_read; List<Item> *fields; - List<Item_buff> group_fields; + List<Item_buff> group_fields, group_fields_cache; TABLE *tmp_table; // used to store 2 possible tmp table of SELECT TABLE *exec_tmp_table1, *exec_tmp_table2; THD *thd; Item_sum **sum_funcs, ***sum_funcs_end; + /* second copy of sumfuncs (for queries with 2 temporary tables */ + Item_sum **sum_funcs2, ***sum_funcs_end2; Procedure *procedure; Item *having; Item *tmp_having; // To store Having when processed temporary table @@ -212,7 +214,7 @@ class JOIN :public Sql_alloc exec_tmp_table1= 0; exec_tmp_table2= 0; thd= thd_arg; - sum_funcs= 0; + sum_funcs= sum_funcs2= 0; procedure= 0; having= 0; tmp_having= 0; |