summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
Diffstat (limited to 'sql')
-rw-r--r--sql/sql_select.cc59
-rw-r--r--sql/sql_select.h6
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;