@@ -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
0 commit comments