Skip to content

Commit 8dff1aa

Browse files
committed
bug: move one_storage_engine checking loop
down to the point where all tables are already known (and subqueries converted to joins, if needed)
1 parent c93ac0a commit 8dff1aa

File tree

2 files changed

+96
-100
lines changed

2 files changed

+96
-100
lines changed

sql/sql_select.cc

Lines changed: 96 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -759,12 +759,6 @@ JOIN::prepare(Item ***rref_pointer_array,
759759

760760
TABLE_LIST *tbl;
761761
List_iterator_fast<TABLE_LIST> li(select_lex->leaf_tables);
762-
/*
763-
If all tables comes from the same storage engine, one_storage_engine will
764-
be set to point to the handlerton of this engine.
765-
*/
766-
one_storage_engine= 0;
767-
uint table_loop_count= 0;
768762
while ((tbl= li++))
769763
{
770764
/*
@@ -776,17 +770,8 @@ JOIN::prepare(Item ***rref_pointer_array,
776770
Note: this loop doesn't touch tables inside merged semi-joins, because
777771
subquery-to-semijoin conversion has not been done yet. This is intended.
778772
*/
779-
if (tbl->table)
780-
{
781-
if (mixed_implicit_grouping)
782-
tbl->table->maybe_null= 1;
783-
if (!table_loop_count++)
784-
one_storage_engine= tbl->table->file->ht;
785-
else if (one_storage_engine != tbl->table->file->ht)
786-
one_storage_engine= 0;
787-
}
788-
else
789-
one_storage_engine= 0;
773+
if (mixed_implicit_grouping && tbl->table)
774+
tbl->table->maybe_null= 1;
790775
}
791776

792777
if ((wild_num && setup_wild(thd, tables_list, fields_list, &all_fields,
@@ -1914,92 +1899,106 @@ JOIN::optimize_inner()
19141899
group by handler to evaluate the group by
19151900
*/
19161901

1917-
if ((tmp_table_param.sum_func_count || group_list) && !procedure &&
1918-
(one_storage_engine && one_storage_engine->create_group_by))
1902+
if ((tmp_table_param.sum_func_count || group_list) && !procedure)
19191903
{
1920-
/* Check if the storage engine can intercept the query */
1921-
group_by_handler *gbh= one_storage_engine->create_group_by(thd, &all_fields,
1922-
tables_list, group_list, order, conds, having);
1923-
if (gbh)
1904+
/*
1905+
At the moment we only support push down for queries where
1906+
all tables are in the same storage engine
1907+
*/
1908+
TABLE_LIST *tbl= tables_list;
1909+
handlerton *ht= tbl && tbl->table ? tbl->table->file->ht : 0;
1910+
for (tbl= tbl->next_local; ht && tbl; tbl= tbl->next_local)
19241911
{
1925-
pushdown_query= new (thd->mem_root) Pushdown_query(select_lex, gbh);
1926-
uint handler_flags= gbh->flags();
1927-
int err;
1912+
if (!tbl->table || tbl->table->file->ht != ht)
1913+
ht= 0;
1914+
}
19281915

1929-
/*
1930-
We must store rows in the tmp table if we need to do an ORDER BY
1931-
or DISTINCT and the storage handler can't handle it.
1932-
*/
1933-
need_tmp= ((!(handler_flags & GROUP_BY_ORDER_BY) &&
1934-
(order || group_list)) ||
1935-
(!(handler_flags & GROUP_BY_DISTINCT) && select_distinct));
1936-
tmp_table_param.hidden_field_count= (all_fields.elements -
1937-
fields_list.elements);
1938-
if (!(exec_tmp_table1=
1939-
create_tmp_table(thd, &tmp_table_param, all_fields,
1940-
0, handler_flags & GROUP_BY_DISTINCT ?
1941-
0 : select_distinct, 1,
1942-
select_options, HA_POS_ERROR, "",
1943-
!need_tmp,
1944-
(!order ||
1945-
(handler_flags & GROUP_BY_ORDER_BY)))))
1946-
DBUG_RETURN(1);
1916+
if (ht && ht->create_group_by)
1917+
{
1918+
/* Check if the storage engine can intercept the query */
1919+
group_by_handler *gbh= ht->create_group_by(thd, &all_fields,
1920+
tables_list, group_list, order, conds, having);
1921+
if (gbh)
1922+
{
1923+
pushdown_query= new (thd->mem_root) Pushdown_query(select_lex, gbh);
1924+
uint handler_flags= gbh->flags();
1925+
int err;
19471926

1948-
/*
1949-
Setup reference fields, used by summary functions and group by fields,
1950-
to point to the temporary table.
1951-
The actual switching to the temporary tables fields for HAVING
1952-
and ORDER BY is done in do_select() by calling
1953-
set_items_ref_array(items1).
1954-
*/
1955-
init_items_ref_array();
1956-
items1= items0 + all_fields.elements;
1957-
if (change_to_use_tmp_fields(thd, items1,
1958-
tmp_fields_list1, tmp_all_fields1,
1959-
fields_list.elements, all_fields))
1960-
DBUG_RETURN(1);
1927+
/*
1928+
We must store rows in the tmp table if we need to do an ORDER BY
1929+
or DISTINCT and the storage handler can't handle it.
1930+
*/
1931+
need_tmp= ((!(handler_flags & GROUP_BY_ORDER_BY) &&
1932+
(order || group_list)) ||
1933+
(!(handler_flags & GROUP_BY_DISTINCT) && select_distinct));
1934+
tmp_table_param.hidden_field_count= (all_fields.elements -
1935+
fields_list.elements);
1936+
if (!(exec_tmp_table1=
1937+
create_tmp_table(thd, &tmp_table_param, all_fields, 0,
1938+
handler_flags & GROUP_BY_DISTINCT ?
1939+
0 : select_distinct, 1,
1940+
select_options, HA_POS_ERROR, "",
1941+
!need_tmp,
1942+
(!order ||
1943+
(handler_flags & GROUP_BY_ORDER_BY)))))
1944+
DBUG_RETURN(1);
19611945

1962-
/* Give storage engine access to temporary table */
1963-
if ((err= gbh->ha_init(exec_tmp_table1, having, order)))
1964-
{
1965-
gbh->print_error(err, MYF(0));
1966-
DBUG_RETURN(1);
1946+
/*
1947+
Setup reference fields, used by summary functions and group by fields,
1948+
to point to the temporary table.
1949+
The actual switching to the temporary tables fields for HAVING
1950+
and ORDER BY is done in do_select() by calling
1951+
set_items_ref_array(items1).
1952+
*/
1953+
init_items_ref_array();
1954+
items1= items0 + all_fields.elements;
1955+
if (change_to_use_tmp_fields(thd, items1,
1956+
tmp_fields_list1, tmp_all_fields1,
1957+
fields_list.elements, all_fields))
1958+
DBUG_RETURN(1);
1959+
1960+
/* Give storage engine access to temporary table */
1961+
if ((err= gbh->ha_init(exec_tmp_table1, having, order)))
1962+
{
1963+
gbh->print_error(err, MYF(0));
1964+
DBUG_RETURN(1);
1965+
}
1966+
pushdown_query->store_data_in_temp_table= need_tmp;
1967+
pushdown_query->having= having;
1968+
/*
1969+
If no ORDER BY clause was specified explicitly, we should sort things
1970+
according to the group_by
1971+
*/
1972+
if (!order)
1973+
order= group_list;
1974+
/*
1975+
Group by and having is calculated by the group_by handler.
1976+
Reset the group by and having
1977+
*/
1978+
group= 0; group_list= 0;
1979+
having= tmp_having= 0;
1980+
/*
1981+
Select distinct is handled by handler or by creating an unique index
1982+
over all fields in the temporary table
1983+
*/
1984+
select_distinct= 0;
1985+
if (handler_flags & GROUP_BY_ORDER_BY)
1986+
order= 0;
1987+
tmp_table_param.field_count+= tmp_table_param.sum_func_count;
1988+
tmp_table_param.sum_func_count= 0;
1989+
1990+
/* Remember information about the original join */
1991+
original_join_tab= join_tab;
1992+
original_table_count= table_count;
1993+
1994+
/* Set up one join tab to get sorting to work */
1995+
const_tables= 0;
1996+
table_count= 1;
1997+
join_tab= (JOIN_TAB*) thd->calloc(sizeof(JOIN_TAB));
1998+
join_tab[0].table= exec_tmp_table1;
1999+
2000+
DBUG_RETURN(thd->is_fatal_error);
19672001
}
1968-
pushdown_query->store_data_in_temp_table= need_tmp;
1969-
pushdown_query->having= having;
1970-
/*
1971-
If no ORDER BY clause was specified explicitly, we should sort things
1972-
according to the group_by
1973-
*/
1974-
if (!order)
1975-
order= group_list;
1976-
/*
1977-
Group by and having is calculated by the group_by handler.
1978-
Reset the group by and having
1979-
*/
1980-
group= 0; group_list= 0;
1981-
having= tmp_having= 0;
1982-
/*
1983-
Select distinct is handled by handler or by creating an unique index
1984-
over all fields in the temporary table
1985-
*/
1986-
select_distinct= 0;
1987-
if (handler_flags & GROUP_BY_ORDER_BY)
1988-
order= 0;
1989-
tmp_table_param.field_count+= tmp_table_param.sum_func_count;
1990-
tmp_table_param.sum_func_count= 0;
1991-
1992-
/* Remember information about the original join */
1993-
original_join_tab= join_tab;
1994-
original_table_count= table_count;
1995-
1996-
/* Set up one join tab to get sorting to work */
1997-
const_tables= 0;
1998-
table_count= 1;
1999-
join_tab= (JOIN_TAB*) thd->calloc(sizeof(JOIN_TAB));
2000-
join_tab[0].table= exec_tmp_table1;
2001-
2002-
DBUG_RETURN(thd->is_fatal_error);
20032002
}
20042003
}
20052004

sql/sql_select.h

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1087,8 +1087,6 @@ class JOIN :public Sql_alloc
10871087
/* Finally picked QEP. This is result of join optimization */
10881088
POSITION *best_positions;
10891089

1090-
/* points to a storage engine if all tables comes from the storage engine */
1091-
handlerton *one_storage_engine;
10921090
Pushdown_query *pushdown_query;
10931091
JOIN_TAB *original_join_tab;
10941092
uint original_table_count;
@@ -1391,7 +1389,6 @@ class JOIN :public Sql_alloc
13911389
group_optimized_away= 0;
13921390
no_rows_in_result_called= 0;
13931391
positions= best_positions= 0;
1394-
one_storage_engine= 0;
13951392
pushdown_query= 0;
13961393
original_join_tab= 0;
13971394
do_select_call_count= 0;

0 commit comments

Comments
 (0)