From 809a805251f45d81a6026049944f14b9db60b81d Mon Sep 17 00:00:00 2001 From: Sergey Petrunya Date: Tue, 22 Mar 2011 00:39:27 +0300 Subject: [PATCH] MWL#90: Address review feedback part #4 --- sql/opt_subselect.cc | 46 ++++++++++++++++++++++++++++++-------------- sql/sql_base.cc | 2 +- sql/sql_select.cc | 32 +++++++++--------------------- sql/sql_show.cc | 2 -- 4 files changed, 42 insertions(+), 40 deletions(-) diff --git a/sql/opt_subselect.cc b/sql/opt_subselect.cc index 05a0367c346..a4d5578f3cf 100644 --- a/sql/opt_subselect.cc +++ b/sql/opt_subselect.cc @@ -687,18 +687,22 @@ bool convert_join_subqueries_to_semijoins(JOIN *join) arena= thd->activate_stmt_arena_if_needed(&backup); for (in_subq= join->sj_subselects.front(); - in_subq != in_subq_end && - join->tables + (*in_subq)->unit->first_select()->join->tables < MAX_TABLES; + in_subq != in_subq_end; in_subq++) { bool remove_item= TRUE; if ((*in_subq)->is_flattenable_semijoin) { + if (join->tables + + (*in_subq)->unit->first_select()->join->tables >= MAX_TABLES) + break; if (convert_subq_to_sj(join, *in_subq)) DBUG_RETURN(TRUE); } else { + if (join->tables + 1 >= MAX_TABLES) + break; if (convert_subq_to_jtbm(join, *in_subq, &remove_item)) DBUG_RETURN(TRUE); } @@ -1211,6 +1215,17 @@ static bool convert_subq_to_sj(JOIN *parent_join, Item_in_subselect *subq_pred) } +const int SUBQERY_TEMPTABLE_NAME_MAX_LEN= 20; + +static void create_subquery_temptable_name(char *to, uint number) +{ + DBUG_ASSERT(number < 10000); + to= strmov(to, "engine->engine_type() != subselect_engine::HASH_SJ_ENGINE) { *remove_item= FALSE; - make_in_exists_conversion(parent_join->thd, parent_join, subq_pred); - DBUG_RETURN(FALSE); + bool res; + res= make_in_exists_conversion(parent_join->thd, parent_join, subq_pred); + DBUG_RETURN(res); } *remove_item= TRUE; TABLE_LIST *jtbm; char *tbl_alias; - const char alias_mask[]=""; - if (!(tbl_alias= (char*)parent_join->thd->calloc(sizeof(alias_mask)+5)) || + if (!(tbl_alias= (char*)parent_join->thd->calloc(SUBQERY_TEMPTABLE_NAME_MAX_LEN)) || !(jtbm= alloc_join_nest(parent_join->thd))) //todo: this is not a join nest! { DBUG_RETURN(TRUE); @@ -1268,7 +1283,8 @@ static bool convert_subq_to_jtbm(JOIN *parent_join, Inject the jtbm table into TABLE_LIST::next_leaf list, so that make_join_statistics() and co. can find it. */ - for (tl= parent_lex->leaf_tables; tl->next_leaf; tl= tl->next_leaf) ; + for (tl= parent_lex->leaf_tables; tl->next_leaf; tl= tl->next_leaf) + {} tl->next_leaf= jtbm; /* @@ -1276,7 +1292,8 @@ static bool convert_subq_to_jtbm(JOIN *parent_join, (a theory: a next_local chain always starts with ::leaf_tables because view's tables are inserted after the view) */ - for (tl= parent_lex->leaf_tables; tl->next_local; tl= tl->next_local) ; + for (tl= parent_lex->leaf_tables; tl->next_local; tl= tl->next_local) + {} tl->next_local= jtbm; /* A theory: no need to re-connect the next_global chain */ @@ -1289,15 +1306,16 @@ static bool convert_subq_to_jtbm(JOIN *parent_join, jtbm->table->map= table_map(1) << (parent_join->tables); parent_join->tables++; + DBUG_ASSERT(parent_join->tables < MAX_TABLES); Item *conds= hash_sj_engine->semi_join_conds; conds->fix_after_pullout(parent_lex, &conds); DBUG_EXECUTE("where", print_where(conds,"SJ-EXPR", QT_ORDINARY);); - my_snprintf(tbl_alias, sizeof(alias_mask)+5, alias_mask, - hash_sj_engine->materialize_join->select_lex->select_number); - jtbm->alias= tbl_alias; + create_subquery_temptable_name(tbl_alias, hash_sj_engine->materialize_join-> + select_lex->select_number); + jtbm->alias= tbl_alias; /* Inject sj_on_expr into the parent's WHERE or ON */ if (emb_tbl_nest) @@ -4017,13 +4035,13 @@ enum_nested_loop_state join_tab_execution_startup(JOIN_TAB *tab) { /* It's a merged SJM nest */ enum_nested_loop_state rc; - JOIN *join= tab->join; SJ_MATERIALIZATION_INFO *sjm= tab->bush_children->start->emb_sj_nest->sj_mat_info; - JOIN_TAB *join_tab= tab->bush_children->start; - JOIN_TAB *save_return_tab= join->return_tab; if (!sjm->materialized) { + JOIN *join= tab->join; + JOIN_TAB *join_tab= tab->bush_children->start; + JOIN_TAB *save_return_tab= join->return_tab; /* Now run the join for the inner tables. The first call is to run the join, the second one is to signal EOF (this is essential for some diff --git a/sql/sql_base.cc b/sql/sql_base.cc index ed08e20340d..cd6d2f40dba 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -7784,7 +7784,7 @@ bool setup_tables(THD *thd, Name_resolution_context *context, Item *item= table_list->jtbm_subselect; if (item->fix_fields(thd, &item)) { - my_error(ER_TOO_MANY_TABLES,MYF(0),MAX_TABLES); + my_error(ER_TOO_MANY_TABLES,MYF(0),MAX_TABLES); /* psergey-todo: WHY ER_TOO_MANY_TABLES ???*/ DBUG_RETURN(1); } DBUG_ASSERT(item == table_list->jtbm_subselect); diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 812188fa9e9..d443fbc802d 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -6991,9 +6991,8 @@ JOIN::make_simple_join(JOIN *parent, TABLE *temp_table) join_tab= parent->join_tab_reexec; table= &parent->table_reexec[0]; parent->table_reexec[0]= temp_table; - top_jtrange_tables= 1; + tables= top_jtrange_tables= 1; - tables= 1; const_tables= 0; const_table_map= 0; eliminated_tables= 0; @@ -8417,11 +8416,8 @@ no_join_cache: void check_join_cache_usage_for_tables(JOIN *join, ulonglong options, uint no_jbuf_after) { - //JOIN_TAB *first_sjm_table= NULL; - //JOIN_TAB *last_sjm_table= NULL; JOIN_TAB *tab; - //for (uint i= join->const_tables; i < join->tables; i++) for (tab= first_linear_tab(join, TRUE); tab; tab= next_linear_tab(join, tab, TRUE)) @@ -8429,23 +8425,10 @@ void check_join_cache_usage_for_tables(JOIN *join, ulonglong options, tab->used_join_cache_level= join->max_allowed_join_cache_level; } - //for (uint i= join->const_tables; i < join->tables; i++) for (tab= first_linear_tab(join, TRUE); tab; tab= next_linear_tab(join, tab, TRUE)) { -#if 0 - if (sj_is_materialize_strategy(join->best_positions[i].sj_strategy)) - { - first_sjm_table= tab; - last_sjm_table= tab + join->best_positions[i].n_sj_tables; - for (JOIN_TAB *sjm_tab= first_sjm_table; - sjm_tab != last_sjm_table; sjm_tab++) - sjm_tab->first_sjm_sibling= first_sjm_table; - } - if (!(tab >= first_sjm_table && tab < last_sjm_table)) - tab->first_sjm_sibling= NULL; -#endif JOIN_TAB *prev_tab; restart: tab->icp_other_tables_ok= TRUE; @@ -8471,10 +8454,6 @@ restart: we can first allocate a join buffer, then decide not to use it and free it. */ - /* - if (join->return_tab) - i= join->return_tab-join->join_tab-1; // always >= 0 - */ if (join->return_tab) { tab= join->return_tab; @@ -19617,12 +19596,19 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order, examined_rows= tab->limit; else { - //tab->table->file->info(HA_STATUS_VARIABLE); if (!tab->table->pos_in_table_list || tab->table->is_filled_at_execution()) // temporary, is_filled_at_execution + { examined_rows= tab->records; + } else + { + /* + handler->info(HA_STATUS_VARIABLE) has been called in + make_join_statistics() + */ examined_rows= tab->table->file->stats.records; + } } } else diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 1cc69ff1517..be2b1657882 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -6600,14 +6600,12 @@ int make_schema_select(THD *thd, SELECT_LEX *sel, bool get_schema_tables_result(JOIN *join, enum enum_schema_table_state executed_place) { - //JOIN_TAB *tmp_join_tab= join->join_tab+join->tables; THD *thd= join->thd; LEX *lex= thd->lex; bool result= 0; DBUG_ENTER("get_schema_tables_result"); thd->no_warnings_for_error= 1; - //for (JOIN_TAB *tab= join->join_tab; tab < tmp_join_tab; tab++) for (JOIN_TAB *tab= first_linear_tab(join, FALSE); tab; tab= next_linear_tab(join, tab, FALSE))