diff options
Diffstat (limited to 'sql')
-rw-r--r-- | sql/item_cmpfunc.cc | 13 | ||||
-rw-r--r-- | sql/item_func.cc | 2 | ||||
-rw-r--r-- | sql/sql_delete.cc | 4 | ||||
-rw-r--r-- | sql/sql_lex.cc | 7 | ||||
-rw-r--r-- | sql/sql_select.cc | 23 | ||||
-rw-r--r-- | sql/sql_select.h | 1 |
6 files changed, 45 insertions, 5 deletions
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 8461de9cd36..429d2ad4dc7 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -318,7 +318,18 @@ static bool convert_const_to_int(THD *thd, Item_field *field_item, field_item->field_type() != MYSQL_TYPE_YEAR) return 1; - if ((*item)->const_item() && !(*item)->is_expensive()) + /* + Replace (*item) with its value if the item can be computed. + + Do not replace items that contain aggregate functions: + There can be such items that are constants, e.g. COLLATION(AVG(123)), + but this function is called at Name Resolution phase. + Removing aggregate functions may confuse query plan generation code, e.g. + the optimizer might conclude that the query doesn't need to do grouping + at all. + */ + if ((*item)->const_item() && !(*item)->is_expensive() && + !(*item)->with_sum_func()) { TABLE *table= field->table; Sql_mode_save sql_mode(thd); diff --git a/sql/item_func.cc b/sql/item_func.cc index 659df67adaf..1da220d7276 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -6209,6 +6209,8 @@ bool Item_func_match::init_search(THD *thd, bool no_order) ft_handler= table->file->ft_init_ext(flags, key, ft_tmp); + if (!ft_handler) + DBUG_RETURN(1); if (join_key) table->file->ft_handler=ft_handler; diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc index 0fe6037e88b..4c359955dbe 100644 --- a/sql/sql_delete.cc +++ b/sql/sql_delete.cc @@ -1292,7 +1292,9 @@ multi_delete::initialize_tables(JOIN *join) table->file->ref_length, MEM_STRIP_BUF_SIZE); } - init_ftfuncs(thd, thd->lex->current_select, 1); + if (init_ftfuncs(thd, thd->lex->current_select, 1)) + DBUG_RETURN(true); + DBUG_RETURN(thd->is_fatal_error); } diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 7088a9c447b..1d160bd9a65 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -3154,6 +3154,7 @@ void st_select_lex_node::fast_exclude() for (; slave; slave= slave->next) slave->fast_exclude(); + prev= NULL; // to ensure correct behavior of st_select_lex_unit::is_excluded() } @@ -3228,9 +3229,7 @@ void st_select_lex_node::exclude_from_tree() */ void st_select_lex_node::exclude() { - /* exclude from global list */ - fast_exclude(); - /* exclude from other structures */ + /* exclude the node from the tree */ exclude_from_tree(); /* We do not need following statements, because prev pointer of first @@ -3238,6 +3237,8 @@ void st_select_lex_node::exclude() if (master->slave == this) master->slave= next; */ + /* exclude all nodes under this excluded node */ + fast_exclude(); } diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 1f32c784248..81c4991e801 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -1851,6 +1851,9 @@ JOIN::optimize_inner() DEBUG_SYNC(thd, "before_join_optimize"); THD_STAGE_INFO(thd, stage_optimizing); +#ifndef DBUG_OFF + dbug_join_tab_array_size= 0; +#endif set_allowed_join_cache_types(); need_distinct= TRUE; @@ -3100,6 +3103,9 @@ setup_subq_exit: { if (!(join_tab= (JOIN_TAB*) thd->alloc(sizeof(JOIN_TAB)))) DBUG_RETURN(1); +#ifndef DBUG_OFF + dbug_join_tab_array_size= 1; +#endif need_tmp= 1; } if (make_aggr_tables_info()) @@ -3414,6 +3420,7 @@ bool JOIN::make_aggr_tables_info() { aggr_tables++; curr_tab= join_tab + exec_join_tab_cnt(); + DBUG_ASSERT(curr_tab - join_tab < dbug_join_tab_array_size); bzero((void*)curr_tab, sizeof(JOIN_TAB)); curr_tab->ref.key= -1; if (only_const_tables()) @@ -3542,6 +3549,7 @@ bool JOIN::make_aggr_tables_info() curr_tab++; aggr_tables++; + DBUG_ASSERT(curr_tab - join_tab < dbug_join_tab_array_size); bzero((void*)curr_tab, sizeof(JOIN_TAB)); curr_tab->ref.key= -1; @@ -10539,6 +10547,21 @@ bool JOIN::get_best_combination() fix_semijoin_strategies_for_picked_join_order(this); top_join_tab_count= get_number_of_tables_at_top_level(this); +#ifndef DBUG_OFF + dbug_join_tab_array_size= top_join_tab_count + aggr_tables; +#endif + /* + NOTE: The above computation of aggr_tables can produce wrong result because some + of the variables it uses may change their values after we leave this function. + Known examples: + - Dangerous: using_outer_summary_function=false at this point. Added + DBUG_ASSERT below to demonstrate. Can this cause us to allocate less + space than we would need? + - Not dangerous: select_distinct can be true here but be assigned false + afterwards. + */ + aggr_tables= 2; + DBUG_ASSERT(!tmp_table_param.using_outer_summary_function); if (!(join_tab= (JOIN_TAB*) thd->alloc(sizeof(JOIN_TAB)* (top_join_tab_count + aggr_tables)))) DBUG_RETURN(TRUE); diff --git a/sql/sql_select.h b/sql/sql_select.h index d43737fbd40..4ada816692e 100644 --- a/sql/sql_select.h +++ b/sql/sql_select.h @@ -1301,6 +1301,7 @@ public: #ifndef DBUG_OFF void dbug_verify_sj_inner_tables(uint n_positions) const; + uint dbug_join_tab_array_size; #endif /* We also maintain a stack of join optimization states in * join->positions[] */ |