Skip to content

Commit 21a0291

Browse files
committed
MDEV-8646: Re-engineer the code for post-join operations
Make query pushdown work in the post-refactored code. This fixes sequence.group_by test.
1 parent 93f2371 commit 21a0291

File tree

2 files changed

+91
-28
lines changed

2 files changed

+91
-28
lines changed

sql/sql_select.cc

Lines changed: 91 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2100,13 +2100,22 @@ bool JOIN::make_aggr_tables_info()
21002100

21012101
sort_and_group_aggr_tab= NULL;
21022102

2103-
/*
2103+
2104+
/*
2105+
Setup last table to provide fields and all_fields lists to the next
2106+
node in the plan.
2107+
*/
2108+
if (join_tab)
2109+
{
2110+
join_tab[top_join_tab_count - 1].fields= &fields_list;
2111+
join_tab[top_join_tab_count - 1].all_fields= &all_fields;
2112+
}
2113+
2114+
/*
21042115
All optimization is done. Check if we can use the storage engines
21052116
group by handler to evaluate the group by
21062117
*/
2107-
21082118
group_by_handler *gbh= NULL;
2109-
#if 0
21102119
if ((tmp_table_param.sum_func_count || group_list) && !procedure)
21112120
{
21122121
/*
@@ -2127,10 +2136,10 @@ bool JOIN::make_aggr_tables_info()
21272136
Query query= {&all_fields, select_distinct, tables_list, conds,
21282137
group_list, order ? order : group_list, having};
21292138
group_by_handler *gbh= ht->create_group_by(thd, &query);
2139+
21302140
if (gbh)
21312141
{
21322142
pushdown_query= new (thd->mem_root) Pushdown_query(select_lex, gbh);
2133-
21342143
/*
21352144
We must store rows in the tmp table if we need to do an ORDER BY
21362145
or DISTINCT and the storage handler can't handle it.
@@ -2139,31 +2148,75 @@ bool JOIN::make_aggr_tables_info()
21392148
distinct= query.distinct;
21402149
keep_row_order= query.order_by || query.group_by;
21412150

2151+
order= query.order_by;
2152+
2153+
aggr_tables++;
2154+
curr_tab= join_tab + top_join_tab_count;
2155+
bzero(curr_tab, sizeof(JOIN_TAB));
2156+
curr_tab->ref.key= -1;
2157+
curr_tab->join= this;
2158+
2159+
curr_tab->tmp_table_param= new TMP_TABLE_PARAM(tmp_table_param);
2160+
TABLE* table= create_tmp_table(thd, curr_tab->tmp_table_param,
2161+
all_fields,
2162+
NULL, query.distinct,
2163+
TRUE, select_options, HA_POS_ERROR,
2164+
"", !need_tmp,
2165+
query.order_by || query.group_by);
2166+
if (!table)
2167+
DBUG_RETURN(1);
2168+
2169+
curr_tab->aggr= new (thd->mem_root) AGGR_OP(curr_tab);
2170+
curr_tab->aggr->set_write_func(::end_send);
2171+
curr_tab->table= table;
2172+
/*
2173+
Setup reference fields, used by summary functions and group by fields,
2174+
to point to the temporary table.
2175+
The actual switching to the temporary tables fields for HAVING
2176+
and ORDER BY is done in do_select() by calling
2177+
set_items_ref_array(items1).
2178+
*/
2179+
init_items_ref_array();
2180+
items1= ref_ptr_array_slice(2);
2181+
//items1= items0 + all_fields.elements;
2182+
if (change_to_use_tmp_fields(thd, items1,
2183+
tmp_fields_list1, tmp_all_fields1,
2184+
fields_list.elements, all_fields))
2185+
DBUG_RETURN(1);
2186+
2187+
/* Give storage engine access to temporary table */
2188+
gbh->table= table;
21422189
pushdown_query->store_data_in_temp_table= need_tmp;
21432190
pushdown_query->having= having;
2191+
21442192
/*
21452193
Group by and having is calculated by the group_by handler.
21462194
Reset the group by and having
21472195
*/
21482196
DBUG_ASSERT(query.group_by == NULL);
21492197
group= 0; group_list= 0;
21502198
having= tmp_having= 0;
2151-
2199+
/*
2200+
Select distinct is handled by handler or by creating an unique index
2201+
over all fields in the temporary table
2202+
*/
2203+
select_distinct= 0;
21522204
order= query.order_by;
2205+
tmp_table_param.field_count+= tmp_table_param.sum_func_count;
2206+
tmp_table_param.sum_func_count= 0;
2207+
2208+
fields= curr_fields_list;
2209+
2210+
//todo: new:
2211+
curr_tab->ref_array= &items1;
2212+
curr_tab->all_fields= &tmp_all_fields1;
2213+
curr_tab->fields= &tmp_fields_list1;
2214+
2215+
DBUG_RETURN(thd->is_fatal_error);
21532216
}
21542217
}
21552218
}
2156-
#endif
21572219

2158-
/*
2159-
Setup last table to provide fields and all_fields lists to the next
2160-
node in the plan.
2161-
*/
2162-
if (join_tab)
2163-
{
2164-
join_tab[top_join_tab_count - 1].fields= &fields_list;
2165-
join_tab[top_join_tab_count - 1].all_fields= &all_fields;
2166-
}
21672220

21682221
/*
21692222
The loose index scan access method guarantees that all grouping or
@@ -3206,8 +3259,6 @@ void JOIN::exec_inner()
32063259

32073260
if (select_options & SELECT_DESCRIBE)
32083261
{
3209-
do_select_call_count= 0;
3210-
32113262
select_describe(this, need_tmp,
32123263
order != 0 && !skip_sort_order,
32133264
select_distinct,
@@ -8495,6 +8546,9 @@ bool JOIN::get_best_combination()
84958546
(order ? 1 : 0) +
84968547
(select_options & (SELECT_BIG_RESULT | OPTION_BUFFER_RESULT) ? 1 : 0) ;
84978548

8549+
if (aggr_tables == 0)
8550+
aggr_tables= 1; /* For group by pushdown */
8551+
84988552
if (select_lex->window_specs.elements)
84998553
aggr_tables++;
85008554

@@ -17613,16 +17667,33 @@ do_select(JOIN *join, Procedure *procedure)
1761317667
enum_nested_loop_state error= NESTED_LOOP_OK;
1761417668
DBUG_ENTER("do_select");
1761517669

17616-
join->do_select_call_count++;
17617-
17618-
if (join->pushdown_query && join->do_select_call_count == 1)
17670+
if (join->pushdown_query)
1761917671
{
1762017672
/* Select fields are in the temporary table */
1762117673
join->fields= &join->tmp_fields_list1;
1762217674
/* Setup HAVING to work with fields in temporary table */
1762317675
join->set_items_ref_array(join->items1);
1762417676
/* The storage engine will take care of the group by query result */
1762517677
int res= join->pushdown_query->execute(join);
17678+
17679+
if (res)
17680+
DBUG_RETURN(res);
17681+
17682+
if (join->pushdown_query->store_data_in_temp_table)
17683+
{
17684+
JOIN_TAB *last_tab= join->join_tab + join->table_count;
17685+
last_tab->next_select= end_send;
17686+
17687+
enum_nested_loop_state state= last_tab->aggr->end_send();
17688+
if (state >= NESTED_LOOP_OK)
17689+
state= sub_select(join, last_tab, true);
17690+
17691+
if (state < NESTED_LOOP_OK)
17692+
res= 1;
17693+
17694+
if (join->result->send_eof())
17695+
res= 1;
17696+
}
1762617697
DBUG_RETURN(res);
1762717698
}
1762817699

sql/sql_select.h

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1090,12 +1090,6 @@ class JOIN :public Sql_alloc
10901090
uint top_join_tab_count;
10911091
uint aggr_tables; ///< Number of post-join tmp tables
10921092
uint send_group_parts;
1093-
/*
1094-
This counts how many times do_select() was invoked for this JOIN.
1095-
It's used to restrict Pushdown_query::execute() only to the first
1096-
do_select() invocation.
1097-
*/
1098-
uint do_select_call_count;
10991093
/*
11001094
True if the query has GROUP BY.
11011095
(that is, if group_by != NULL. when DISTINCT is converted into GROUP BY, it
@@ -1463,8 +1457,6 @@ class JOIN :public Sql_alloc
14631457
positions= best_positions= 0;
14641458
pushdown_query= 0;
14651459
original_join_tab= 0;
1466-
do_select_call_count= 0;
1467-
14681460
explain= NULL;
14691461

14701462
all_fields= fields_arg;

0 commit comments

Comments
 (0)