Handle failures from malloc

Most "new" failures fixed in the following files:
- sql_select.cc
- item.cc
- item_func.cc
- opt_subselect.cc

Other things:
- Allocate udf_handler strings in mem_root
  - Required changes in sql_string.h
- Add mem_root as argument to some new [] calls
- Mark udf_handler strings as thread specific
- Removed some comment blocks with code
This commit is contained in:
Michael Widenius 2017-11-14 07:47:58 +02:00
parent 31bd86c8df
commit 87933d5261
21 changed files with 394 additions and 210 deletions

View File

@ -1261,7 +1261,7 @@ Item *Item::safe_charset_converter(THD *thd, CHARSET_INFO *tocs)
if (!needs_charset_converter(tocs)) if (!needs_charset_converter(tocs))
return this; return this;
Item_func_conv_charset *conv= new (thd->mem_root) Item_func_conv_charset(thd, this, tocs, 1); Item_func_conv_charset *conv= new (thd->mem_root) Item_func_conv_charset(thd, this, tocs, 1);
return conv->safe ? conv : NULL; return conv && conv->safe ? conv : NULL;
} }
@ -3237,6 +3237,11 @@ table_map Item_field::all_used_tables() const
return (get_depended_from() ? OUTER_REF_TABLE_BIT : field->table->map); return (get_depended_from() ? OUTER_REF_TABLE_BIT : field->table->map);
} }
/*
@Note thd->fatal_error can be set in case of OOM
*/
void Item_field::fix_after_pullout(st_select_lex *new_parent, Item **ref, void Item_field::fix_after_pullout(st_select_lex *new_parent, Item **ref,
bool merge) bool merge)
{ {
@ -3296,6 +3301,8 @@ void Item_field::fix_after_pullout(st_select_lex *new_parent, Item **ref,
} }
Name_resolution_context *ctx= new Name_resolution_context(); Name_resolution_context *ctx= new Name_resolution_context();
if (!ctx)
return; // Fatal error set
if (context->select_lex == new_parent) if (context->select_lex == new_parent)
{ {
/* /*

View File

@ -3253,17 +3253,15 @@ udf_handler::fix_fields(THD *thd, Item_func_or_sum *func,
func->used_tables_and_const_cache_join(item); func->used_tables_and_const_cache_join(item);
f_args.arg_type[i]=item->result_type(); f_args.arg_type[i]=item->result_type();
} }
//TODO: why all following memory is not allocated with 1 thd->alloc() call? if (!(buffers=new (thd->mem_root) String[arg_count]) ||
if (!(buffers=new String[arg_count]) || !multi_alloc_root(thd->mem_root,
!(f_args.args= (char**) thd->alloc(arg_count * sizeof(char *))) || &f_args.args, arg_count * sizeof(char *),
!(f_args.lengths= (ulong*) thd->alloc(arg_count * sizeof(long))) || &f_args.lengths, arg_count * sizeof(long),
!(f_args.maybe_null= (char*) thd->alloc(arg_count * sizeof(char))) || &f_args.maybe_null, arg_count * sizeof(char),
!(num_buffer= (char*) thd->alloc(arg_count * &num_buffer, arg_count * sizeof(double),
ALIGN_SIZE(sizeof(double)))) || &f_args.attributes, arg_count * sizeof(char *),
!(f_args.attributes= (const char**) thd->alloc(arg_count * &f_args.attribute_lengths, arg_count * sizeof(long),
sizeof(char *))) || NullS))
!(f_args.attribute_lengths= (ulong*) thd->alloc(arg_count *
sizeof(long))))
{ {
free_udf(u_d); free_udf(u_d);
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
@ -3275,6 +3273,8 @@ udf_handler::fix_fields(THD *thd, Item_func_or_sum *func,
initid.const_item=func->const_item_cache; initid.const_item=func->const_item_cache;
initid.decimals=func->decimals; initid.decimals=func->decimals;
initid.ptr=0; initid.ptr=0;
for (uint i1= 0 ; i1 < arg_count ; i1++)
buffers[i1].set_thread_specific();
if (u_d->func_init) if (u_d->func_init)
{ {
@ -5299,8 +5299,8 @@ get_var_with_binlog(THD *thd, enum_sql_command sql_command,
Item_func_set_user_var(thd, name, Item_func_set_user_var(thd, name,
new (thd->mem_root) Item_null(thd))), new (thd->mem_root) Item_null(thd))),
thd->mem_root); thd->mem_root);
/* Create the variable */ /* Create the variable if the above allocations succeeded */
if (sql_set_variables(thd, &tmp_var_list, false)) if (thd->is_fatal_error || sql_set_variables(thd, &tmp_var_list, false))
{ {
thd->lex= sav_lex; thd->lex= sav_lex;
goto err; goto err;
@ -5837,20 +5837,25 @@ void Item_func_get_system_var::cleanup()
cached_strval.free(); cached_strval.free();
} }
/**
@retval
0 ok
1 OOM error
*/
void Item_func_match::init_search(THD *thd, bool no_order) bool Item_func_match::init_search(THD *thd, bool no_order)
{ {
DBUG_ENTER("Item_func_match::init_search"); DBUG_ENTER("Item_func_match::init_search");
if (!table->file->get_table()) // the handler isn't opened yet if (!table->file->get_table()) // the handler isn't opened yet
DBUG_VOID_RETURN; DBUG_RETURN(0);
/* Check if init_search() has been called before */ /* Check if init_search() has been called before */
if (ft_handler) if (ft_handler)
{ {
if (join_key) if (join_key)
table->file->ft_handler= ft_handler; table->file->ft_handler= ft_handler;
DBUG_VOID_RETURN; DBUG_RETURN(0);
} }
if (key == NO_SUCH_KEY) if (key == NO_SUCH_KEY)
@ -5862,6 +5867,8 @@ void Item_func_match::init_search(THD *thd, bool no_order)
for (uint i= 1; i < arg_count; i++) for (uint i= 1; i < arg_count; i++)
fields.push_back(args[i]); fields.push_back(args[i]);
concat_ws= new (thd->mem_root) Item_func_concat_ws(thd, fields); concat_ws= new (thd->mem_root) Item_func_concat_ws(thd, fields);
if (thd->is_fatal_error)
DBUG_RETURN(1); // OOM
/* /*
Above function used only to get value and do not need fix_fields for it: Above function used only to get value and do not need fix_fields for it:
Item_string - basic constant Item_string - basic constant
@ -5874,10 +5881,11 @@ void Item_func_match::init_search(THD *thd, bool no_order)
if (master) if (master)
{ {
join_key= master->join_key= join_key | master->join_key; join_key= master->join_key= join_key | master->join_key;
master->init_search(thd, no_order); if (master->init_search(thd, no_order))
DBUG_RETURN(1);
ft_handler= master->ft_handler; ft_handler= master->ft_handler;
join_key= master->join_key; join_key= master->join_key;
DBUG_VOID_RETURN; DBUG_RETURN(0);
} }
String *ft_tmp= 0; String *ft_tmp= 0;
@ -5892,8 +5900,9 @@ void Item_func_match::init_search(THD *thd, bool no_order)
if (ft_tmp->charset() != cmp_collation.collation) if (ft_tmp->charset() != cmp_collation.collation)
{ {
uint dummy_errors; uint dummy_errors;
search_value.copy(ft_tmp->ptr(), ft_tmp->length(), ft_tmp->charset(), if (search_value.copy(ft_tmp->ptr(), ft_tmp->length(), ft_tmp->charset(),
cmp_collation.collation, &dummy_errors); cmp_collation.collation, &dummy_errors))
DBUG_RETURN(1);
ft_tmp= &search_value; ft_tmp= &search_value;
} }
@ -5908,7 +5917,7 @@ void Item_func_match::init_search(THD *thd, bool no_order)
if (join_key) if (join_key)
table->file->ft_handler=ft_handler; table->file->ft_handler=ft_handler;
DBUG_VOID_RETURN; DBUG_RETURN(0);
} }

View File

@ -2584,7 +2584,7 @@ public:
virtual void print(String *str, enum_query_type query_type); virtual void print(String *str, enum_query_type query_type);
bool fix_index(); bool fix_index();
void init_search(THD *thd, bool no_order); bool init_search(THD *thd, bool no_order);
bool check_vcol_func_processor(void *arg) bool check_vcol_func_processor(void *arg)
{ {
return mark_unsupported_function("match ... against()", arg, VCOL_IMPOSSIBLE); return mark_unsupported_function("match ... against()", arg, VCOL_IMPOSSIBLE);

View File

@ -461,7 +461,7 @@ void best_access_path(JOIN *join, JOIN_TAB *s,
static Item *create_subq_in_equalities(THD *thd, SJ_MATERIALIZATION_INFO *sjm, static Item *create_subq_in_equalities(THD *thd, SJ_MATERIALIZATION_INFO *sjm,
Item_in_subselect *subq_pred); Item_in_subselect *subq_pred);
static void remove_sj_conds(THD *thd, Item **tree); static bool remove_sj_conds(THD *thd, Item **tree);
static bool is_cond_sj_in_equality(Item *item); static bool is_cond_sj_in_equality(Item *item);
static bool sj_table_is_included(JOIN *join, JOIN_TAB *join_tab); static bool sj_table_is_included(JOIN *join, JOIN_TAB *join_tab);
static Item *remove_additional_cond(Item* conds); static Item *remove_additional_cond(Item* conds);
@ -1750,9 +1750,9 @@ static bool convert_subq_to_sj(JOIN *parent_join, Item_in_subselect *subq_pred)
*/ */
Item_row *row= new (thd->mem_root) Item_row(thd, subq_lex->pre_fix); Item_row *row= new (thd->mem_root) Item_row(thd, subq_lex->pre_fix);
/* fix fields on subquery was call so they should be the same */ /* fix fields on subquery was call so they should be the same */
DBUG_ASSERT(subq_pred->left_expr->cols() == row->cols());
if (!row) if (!row)
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
DBUG_ASSERT(subq_pred->left_expr->cols() == row->cols());
nested_join->sj_outer_expr_list.push_back(&subq_pred->left_expr); nested_join->sj_outer_expr_list.push_back(&subq_pred->left_expr);
Item_func_eq *item_eq= Item_func_eq *item_eq=
new (thd->mem_root) Item_func_eq(thd, subq_pred->left_expr_orig, row); new (thd->mem_root) Item_func_eq(thd, subq_pred->left_expr_orig, row);
@ -1839,7 +1839,8 @@ static bool convert_subq_to_sj(JOIN *parent_join, Item_in_subselect *subq_pred)
} }
parent_lex->have_merged_subqueries= TRUE; parent_lex->have_merged_subqueries= TRUE;
DBUG_RETURN(FALSE); /* Fatal error may have been set to by fix_after_pullout() */
DBUG_RETURN(thd->is_fatal_error);
} }
@ -1880,6 +1881,7 @@ static bool convert_subq_to_jtbm(JOIN *parent_join,
bool optimization_delayed= TRUE; bool optimization_delayed= TRUE;
TABLE_LIST *jtbm; TABLE_LIST *jtbm;
char *tbl_alias; char *tbl_alias;
THD *thd= parent_join->thd;
DBUG_ENTER("convert_subq_to_jtbm"); DBUG_ENTER("convert_subq_to_jtbm");
subq_pred->set_strategy(SUBS_MATERIALIZATION); subq_pred->set_strategy(SUBS_MATERIALIZATION);
@ -1887,8 +1889,8 @@ static bool convert_subq_to_jtbm(JOIN *parent_join,
*remove_item= TRUE; *remove_item= TRUE;
if (!(tbl_alias= (char*)parent_join->thd->calloc(SUBQERY_TEMPTABLE_NAME_MAX_LEN)) || if (!(tbl_alias= (char*)thd->calloc(SUBQERY_TEMPTABLE_NAME_MAX_LEN)) ||
!(jtbm= alloc_join_nest(parent_join->thd))) //todo: this is not a join nest! !(jtbm= alloc_join_nest(thd))) //todo: this is not a join nest!
{ {
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
} }
@ -1900,13 +1902,13 @@ static bool convert_subq_to_jtbm(JOIN *parent_join,
/* Nests do not participate in those 'chains', so: */ /* Nests do not participate in those 'chains', so: */
/* jtbm->next_leaf= jtbm->next_local= jtbm->next_global == NULL*/ /* jtbm->next_leaf= jtbm->next_local= jtbm->next_global == NULL*/
emb_join_list->push_back(jtbm, parent_join->thd->mem_root); emb_join_list->push_back(jtbm, thd->mem_root);
/* /*
Inject the jtbm table into TABLE_LIST::next_leaf list, so that Inject the jtbm table into TABLE_LIST::next_leaf list, so that
make_join_statistics() and co. can find it. make_join_statistics() and co. can find it.
*/ */
parent_lex->leaf_tables.push_back(jtbm, parent_join->thd->mem_root); parent_lex->leaf_tables.push_back(jtbm, thd->mem_root);
if (subq_pred->unit->first_select()->options & OPTION_SCHEMA_TABLE) if (subq_pred->unit->first_select()->options & OPTION_SCHEMA_TABLE)
parent_lex->options |= OPTION_SCHEMA_TABLE; parent_lex->options |= OPTION_SCHEMA_TABLE;
@ -1931,7 +1933,7 @@ static bool convert_subq_to_jtbm(JOIN *parent_join,
subq_pred->unit->first_select()->select_number); subq_pred->unit->first_select()->select_number);
jtbm->alias= tbl_alias; jtbm->alias= tbl_alias;
parent_join->table_count++; parent_join->table_count++;
DBUG_RETURN(FALSE); DBUG_RETURN(thd->is_fatal_error);
} }
subselect_hash_sj_engine *hash_sj_engine= subselect_hash_sj_engine *hash_sj_engine=
((subselect_hash_sj_engine*)subq_pred->engine); ((subselect_hash_sj_engine*)subq_pred->engine);
@ -1954,27 +1956,10 @@ static bool convert_subq_to_jtbm(JOIN *parent_join,
jtbm->alias= tbl_alias; jtbm->alias= tbl_alias;
parent_lex->have_merged_subqueries= TRUE; parent_lex->have_merged_subqueries= TRUE;
#if 0
/* Inject sj_on_expr into the parent's WHERE or ON */
if (emb_tbl_nest)
{
DBUG_ASSERT(0);
/*emb_tbl_nest->on_expr= and_items(emb_tbl_nest->on_expr,
sj_nest->sj_on_expr);
emb_tbl_nest->on_expr->fix_fields(parent_join->thd, &emb_tbl_nest->on_expr);
*/
}
else
{
/* Inject into the WHERE */
parent_join->conds= and_items(parent_join->conds, conds);
parent_join->conds->fix_fields(parent_join->thd, &parent_join->conds);
parent_join->select_lex->where= parent_join->conds;
}
#endif
/* Don't unlink the child subselect, as the subquery will be used. */ /* Don't unlink the child subselect, as the subquery will be used. */
DBUG_RETURN(FALSE); DBUG_RETURN(thd->is_fatal_error);
} }
@ -1989,6 +1974,9 @@ static TABLE_LIST *alloc_join_nest(THD *thd)
return tbl; return tbl;
} }
/*
@Note thd->is_fatal_error can be set in case of OOM
*/
void fix_list_after_tbl_changes(SELECT_LEX *new_parent, List<TABLE_LIST> *tlist) void fix_list_after_tbl_changes(SELECT_LEX *new_parent, List<TABLE_LIST> *tlist)
{ {
@ -3718,6 +3706,11 @@ bool setup_sj_materialization_part1(JOIN_TAB *sjm_tab)
DBUG_RETURN(FALSE); DBUG_RETURN(FALSE);
} }
/**
@retval
FALSE ok
TRUE error
*/
bool setup_sj_materialization_part2(JOIN_TAB *sjm_tab) bool setup_sj_materialization_part2(JOIN_TAB *sjm_tab)
{ {
@ -3730,8 +3723,6 @@ bool setup_sj_materialization_part2(JOIN_TAB *sjm_tab)
SJ_MATERIALIZATION_INFO *sjm= emb_sj_nest->sj_mat_info; SJ_MATERIALIZATION_INFO *sjm= emb_sj_nest->sj_mat_info;
THD *thd= tab->join->thd; THD *thd= tab->join->thd;
uint i; uint i;
//List<Item> &item_list= emb_sj_nest->sj_subq_pred->unit->first_select()->item_list;
//List_iterator<Item> it(item_list);
if (!sjm->is_sj_scan) if (!sjm->is_sj_scan)
{ {
@ -3781,6 +3772,8 @@ bool setup_sj_materialization_part2(JOIN_TAB *sjm_tab)
null_count ? cur_ref_buff : 0, null_count ? cur_ref_buff : 0,
cur_key_part->length, tab_ref->items[i], cur_key_part->length, tab_ref->items[i],
FALSE); FALSE);
if (!*ref_key)
DBUG_RETURN(TRUE);
cur_ref_buff+= cur_key_part->store_length; cur_ref_buff+= cur_key_part->store_length;
} }
*ref_key= NULL; /* End marker. */ *ref_key= NULL; /* End marker. */
@ -3806,9 +3799,9 @@ bool setup_sj_materialization_part2(JOIN_TAB *sjm_tab)
*/ */
for (i= 0; i < sjm->tables; i++) for (i= 0; i < sjm->tables; i++)
{ {
remove_sj_conds(thd, &tab[i].select_cond); if (remove_sj_conds(thd, &tab[i].select_cond) ||
if (tab[i].select) (tab[i].select && remove_sj_conds(thd, &tab[i].select->cond)))
remove_sj_conds(thd, &tab[i].select->cond); DBUG_RETURN(TRUE);
} }
if (!(sjm->in_equality= create_subq_in_equalities(thd, sjm, if (!(sjm->in_equality= create_subq_in_equalities(thd, sjm,
emb_sj_nest->sj_subq_pred))) emb_sj_nest->sj_subq_pred)))
@ -3845,7 +3838,9 @@ bool setup_sj_materialization_part2(JOIN_TAB *sjm_tab)
temptable record, we copy its columns to their corresponding columns temptable record, we copy its columns to their corresponding columns
in the record buffers for the source tables. in the record buffers for the source tables.
*/ */
sjm->copy_field= new Copy_field[sjm->sjm_table_cols.elements]; if (!(sjm->copy_field= new Copy_field[sjm->sjm_table_cols.elements]))
DBUG_RETURN(TRUE);
//it.rewind(); //it.rewind();
Ref_ptr_array p_items= emb_sj_nest->sj_subq_pred->unit->first_select()->ref_pointer_array; Ref_ptr_array p_items= emb_sj_nest->sj_subq_pred->unit->first_select()->ref_pointer_array;
for (uint i=0; i < sjm->sjm_table_cols.elements; i++) for (uint i=0; i < sjm->sjm_table_cols.elements; i++)
@ -3972,16 +3967,20 @@ static Item *create_subq_in_equalities(THD *thd, SJ_MATERIALIZATION_INFO *sjm,
} }
/**
@retval
0 ok
1 error
*/
static bool remove_sj_conds(THD *thd, Item **tree)
static void remove_sj_conds(THD *thd, Item **tree)
{ {
if (*tree) if (*tree)
{ {
if (is_cond_sj_in_equality(*tree)) if (is_cond_sj_in_equality(*tree))
{ {
*tree= NULL; *tree= NULL;
return; return 0;
} }
else if ((*tree)->type() == Item::COND_ITEM) else if ((*tree)->type() == Item::COND_ITEM)
{ {
@ -3990,12 +3989,19 @@ static void remove_sj_conds(THD *thd, Item **tree)
while ((item= li++)) while ((item= li++))
{ {
if (is_cond_sj_in_equality(item)) if (is_cond_sj_in_equality(item))
li.replace(new (thd->mem_root) Item_int(thd, 1)); {
Item_int *tmp= new (thd->mem_root) Item_int(thd, 1);
if (!tmp)
return 1;
li.replace(tmp);
} }
} }
} }
}
return 0;
} }
/* Check if given Item was injected by semi-join equality */ /* Check if given Item was injected by semi-join equality */
static bool is_cond_sj_in_equality(Item *item) static bool is_cond_sj_in_equality(Item *item)
{ {
@ -4183,7 +4189,7 @@ SJ_TMP_TABLE::create_sj_weedout_tmp_table(THD *thd)
share->db_plugin= ha_lock_engine(0, heap_hton); share->db_plugin= ha_lock_engine(0, heap_hton);
table->file= get_new_handler(share, &table->mem_root, table->file= get_new_handler(share, &table->mem_root,
share->db_type()); share->db_type());
DBUG_ASSERT(uniq_tuple_length_arg <= table->file->max_key_length()); DBUG_ASSERT(!table->file || uniq_tuple_length_arg <= table->file->max_key_length());
} }
if (!table->file) if (!table->file)
goto err; goto err;
@ -5302,6 +5308,9 @@ TABLE *create_dummy_tmp_table(THD *thd)
sjm_table_param.field_count= 1; sjm_table_param.field_count= 1;
List<Item> sjm_table_cols; List<Item> sjm_table_cols;
Item *column_item= new (thd->mem_root) Item_int(thd, 1); Item *column_item= new (thd->mem_root) Item_int(thd, 1);
if (!column_item)
DBUG_RETURN(NULL);
sjm_table_cols.push_back(column_item, thd->mem_root); sjm_table_cols.push_back(column_item, thd->mem_root);
if (!(table= create_tmp_table(thd, &sjm_table_param, if (!(table= create_tmp_table(thd, &sjm_table_param,
sjm_table_cols, (ORDER*) 0, sjm_table_cols, (ORDER*) 0,

View File

@ -8481,7 +8481,8 @@ int init_ftfuncs(THD *thd, SELECT_LEX *select_lex, bool no_order)
DBUG_PRINT("info",("Performing FULLTEXT search")); DBUG_PRINT("info",("Performing FULLTEXT search"));
while ((ifm=li++)) while ((ifm=li++))
ifm->init_search(thd, no_order); if (ifm->init_search(thd, no_order))
return 1;
} }
return 0; return 0;
} }

View File

@ -61,6 +61,8 @@ Explain_delete* Delete_plan::save_explain_delete_data(MEM_ROOT *mem_root, THD *t
Explain_query *query= thd->lex->explain; Explain_query *query= thd->lex->explain;
Explain_delete *explain= Explain_delete *explain=
new (mem_root) Explain_delete(mem_root, thd->lex->analyze_stmt); new (mem_root) Explain_delete(mem_root, thd->lex->analyze_stmt);
if (!explain)
return 0;
if (deleting_all_rows) if (deleting_all_rows)
{ {
@ -71,8 +73,9 @@ Explain_delete* Delete_plan::save_explain_delete_data(MEM_ROOT *mem_root, THD *t
else else
{ {
explain->deleting_all_rows= false; explain->deleting_all_rows= false;
Update_plan::save_explain_data_intern(mem_root, explain, if (Update_plan::save_explain_data_intern(mem_root, explain,
thd->lex->analyze_stmt); thd->lex->analyze_stmt))
return 0;
} }
query->add_upd_del_plan(explain); query->add_upd_del_plan(explain);
@ -86,13 +89,16 @@ Update_plan::save_explain_update_data(MEM_ROOT *mem_root, THD *thd)
Explain_query *query= thd->lex->explain; Explain_query *query= thd->lex->explain;
Explain_update* explain= Explain_update* explain=
new (mem_root) Explain_update(mem_root, thd->lex->analyze_stmt); new (mem_root) Explain_update(mem_root, thd->lex->analyze_stmt);
save_explain_data_intern(mem_root, explain, thd->lex->analyze_stmt); if (!explain)
return 0;
if (save_explain_data_intern(mem_root, explain, thd->lex->analyze_stmt))
return 0;
query->add_upd_del_plan(explain); query->add_upd_del_plan(explain);
return explain; return explain;
} }
void Update_plan::save_explain_data_intern(MEM_ROOT *mem_root, bool Update_plan::save_explain_data_intern(MEM_ROOT *mem_root,
Explain_update *explain, Explain_update *explain,
bool is_analyze) bool is_analyze)
{ {
@ -105,13 +111,13 @@ void Update_plan::save_explain_data_intern(MEM_ROOT *mem_root,
if (impossible_where) if (impossible_where)
{ {
explain->impossible_where= true; explain->impossible_where= true;
return; return 0;
} }
if (no_partitions) if (no_partitions)
{ {
explain->no_partitions= true; explain->no_partitions= true;
return; return 0;
} }
if (is_analyze) if (is_analyze)
@ -162,7 +168,8 @@ void Update_plan::save_explain_data_intern(MEM_ROOT *mem_root,
explain->where_cond= select? select->cond: NULL; explain->where_cond= select? select->cond: NULL;
if (using_filesort) if (using_filesort)
explain->filesort_tracker= new (mem_root) Filesort_tracker(is_analyze); if (!(explain->filesort_tracker= new (mem_root) Filesort_tracker(is_analyze)))
return 1;
explain->using_io_buffer= using_io_buffer; explain->using_io_buffer= using_io_buffer;
append_possible_keys(mem_root, explain->possible_keys, table, append_possible_keys(mem_root, explain->possible_keys, table,
@ -211,6 +218,7 @@ void Update_plan::save_explain_data_intern(MEM_ROOT *mem_root,
if (!(unit->item && unit->item->eliminated)) if (!(unit->item && unit->item->eliminated))
explain->add_child(unit->first_select()->select_number); explain->add_child(unit->first_select()->select_number);
} }
return 0;
} }
@ -385,7 +393,8 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
query_type= THD::STMT_QUERY_TYPE; query_type= THD::STMT_QUERY_TYPE;
error= -1; error= -1;
deleted= maybe_deleted; deleted= maybe_deleted;
query_plan.save_explain_delete_data(thd->mem_root, thd); if (!query_plan.save_explain_delete_data(thd->mem_root, thd))
error= 1;
goto cleanup; goto cleanup;
} }
if (error != HA_ERR_WRONG_COMMAND) if (error != HA_ERR_WRONG_COMMAND)
@ -503,7 +512,8 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
if (thd->lex->describe) if (thd->lex->describe)
goto produce_explain_and_leave; goto produce_explain_and_leave;
explain= query_plan.save_explain_delete_data(thd->mem_root, thd); if (!(explain= query_plan.save_explain_delete_data(thd->mem_root, thd)))
goto got_error;
ANALYZE_START_TRACKING(&explain->command_tracker); ANALYZE_START_TRACKING(&explain->command_tracker);
DBUG_EXECUTE_IF("show_explain_probe_delete_exec_start", DBUG_EXECUTE_IF("show_explain_probe_delete_exec_start",
@ -555,7 +565,8 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds,
if (error) if (error)
goto got_error; goto got_error;
init_ftfuncs(thd, select_lex, 1); if (init_ftfuncs(thd, select_lex, 1))
goto got_error;
if (table->prepare_triggers_for_delete_stmt_or_event()) if (table->prepare_triggers_for_delete_stmt_or_event())
{ {
@ -766,7 +777,8 @@ produce_explain_and_leave:
We come here for various "degenerate" query plans: impossible WHERE, We come here for various "degenerate" query plans: impossible WHERE,
no-partitions-used, impossible-range, etc. no-partitions-used, impossible-range, etc.
*/ */
query_plan.save_explain_delete_data(thd->mem_root, thd); if (!(query_plan.save_explain_delete_data(thd->mem_root, thd)))
goto got_error;
send_nothing_and_leave: send_nothing_and_leave:
/* /*
@ -1066,7 +1078,7 @@ multi_delete::initialize_tables(JOIN *join)
MEM_STRIP_BUF_SIZE); MEM_STRIP_BUF_SIZE);
} }
init_ftfuncs(thd, thd->lex->current_select, 1); init_ftfuncs(thd, thd->lex->current_select, 1);
DBUG_RETURN(thd->is_fatal_error != 0); DBUG_RETURN(thd->is_fatal_error);
} }

View File

@ -1143,33 +1143,37 @@ void Explain_table_access::fill_key_len_str(String *key_len_str) const
} }
void Explain_index_use::set(MEM_ROOT *mem_root, KEY *key, uint key_len_arg) bool Explain_index_use::set(MEM_ROOT *mem_root, KEY *key, uint key_len_arg)
{ {
set_pseudo_key(mem_root, key->name.str); if (set_pseudo_key(mem_root, key->name.str))
return 1;
key_len= key_len_arg; key_len= key_len_arg;
uint len= 0; uint len= 0;
for (uint i= 0; i < key->usable_key_parts; i++) for (uint i= 0; i < key->usable_key_parts; i++)
{ {
key_parts_list.append_str(mem_root, if (!key_parts_list.append_str(mem_root,
key->key_part[i].field->field_name.str); key->key_part[i].field->field_name.str))
return 1;
len += key->key_part[i].store_length; len += key->key_part[i].store_length;
if (len >= key_len_arg) if (len >= key_len_arg)
break; break;
} }
return 0;
} }
void Explain_index_use::set_pseudo_key(MEM_ROOT *root, const char* key_name_arg) bool Explain_index_use::set_pseudo_key(MEM_ROOT *root, const char* key_name_arg)
{ {
if (key_name_arg) if (key_name_arg)
{ {
size_t name_len= strlen(key_name_arg); if (!(key_name= strdup_root(root, key_name_arg)))
if ((key_name= (char*)alloc_root(root, name_len+1))) return 1;
memcpy(key_name, key_name_arg, name_len+1);
} }
else else
key_name= NULL; key_name= NULL;
key_len= ~(uint) 0; key_len= ~(uint) 0;
return 0;
} }
@ -2450,8 +2454,11 @@ int Explain_range_checked_fer::append_possible_keys_stat(MEM_ROOT *alloc,
for (j= 0; j < table->s->keys; j++) for (j= 0; j < table->s->keys; j++)
{ {
if (possible_keys.is_set(j)) if (possible_keys.is_set(j))
keys_stat_names[j]= key_set.append_str(alloc, {
table->key_info[j].name.str); if (!(keys_stat_names[j]= key_set.append_str(alloc,
table->key_info[j].name.str)))
return 1;
}
else else
keys_stat_names[j]= NULL; keys_stat_names[j]= NULL;
} }

View File

@ -589,8 +589,8 @@ public:
key_name= NULL; key_name= NULL;
key_len= (uint)-1; key_len= (uint)-1;
} }
void set(MEM_ROOT *root, KEY *key_name, uint key_len_arg); bool set(MEM_ROOT *root, KEY *key_name, uint key_len_arg);
void set_pseudo_key(MEM_ROOT *root, const char *key_name); bool set_pseudo_key(MEM_ROOT *root, const char *key_name);
inline const char *get_key_name() const { return key_name; } inline const char *get_key_name() const { return key_name; }
inline uint get_key_len() const { return key_len; } inline uint get_key_len() const { return key_len; }

View File

@ -2571,10 +2571,11 @@ finish:
BNLH, BKA or BKAH) to the data structure BNLH, BKA or BKAH) to the data structure
RETURN VALUE RETURN VALUE
none 0 ok
1 error
*/ */
void JOIN_CACHE::save_explain_data(EXPLAIN_BKA_TYPE *explain) bool JOIN_CACHE::save_explain_data(EXPLAIN_BKA_TYPE *explain)
{ {
explain->incremental= MY_TEST(prev_cache); explain->incremental= MY_TEST(prev_cache);
@ -2596,6 +2597,7 @@ void JOIN_CACHE::save_explain_data(EXPLAIN_BKA_TYPE *explain)
default: default:
DBUG_ASSERT(0); DBUG_ASSERT(0);
} }
return 0;
} }
/** /**
@ -2608,7 +2610,7 @@ THD *JOIN_CACHE::thd()
} }
static void add_mrr_explain_info(String *str, uint mrr_mode, handler *file) static bool add_mrr_explain_info(String *str, uint mrr_mode, handler *file)
{ {
char mrr_str_buf[128]={0}; char mrr_str_buf[128]={0};
int len; int len;
@ -2617,22 +2619,30 @@ static void add_mrr_explain_info(String *str, uint mrr_mode, handler *file)
if (len > 0) if (len > 0)
{ {
if (str->length()) if (str->length())
str->append(STRING_WITH_LEN("; ")); {
str->append(mrr_str_buf, len); if (str->append(STRING_WITH_LEN("; ")))
return 1;
} }
} if (str->append(mrr_str_buf, len))
return 1;
void JOIN_CACHE_BKA::save_explain_data(EXPLAIN_BKA_TYPE *explain) }
{ return 0;
JOIN_CACHE::save_explain_data(explain);
add_mrr_explain_info(&explain->mrr_type, mrr_mode, join_tab->table->file);
} }
void JOIN_CACHE_BKAH::save_explain_data(EXPLAIN_BKA_TYPE *explain) bool JOIN_CACHE_BKA::save_explain_data(EXPLAIN_BKA_TYPE *explain)
{ {
JOIN_CACHE::save_explain_data(explain); if (JOIN_CACHE::save_explain_data(explain))
add_mrr_explain_info(&explain->mrr_type, mrr_mode, join_tab->table->file); return 1;
return add_mrr_explain_info(&explain->mrr_type, mrr_mode, join_tab->table->file);
}
bool JOIN_CACHE_BKAH::save_explain_data(EXPLAIN_BKA_TYPE *explain)
{
if (JOIN_CACHE::save_explain_data(explain))
return 1;
return add_mrr_explain_info(&explain->mrr_type, mrr_mode, join_tab->table->file);
} }

View File

@ -662,7 +662,7 @@ public:
enum_nested_loop_state join_records(bool skip_last); enum_nested_loop_state join_records(bool skip_last);
/* Add a comment on the join algorithm employed by the join cache */ /* Add a comment on the join algorithm employed by the join cache */
virtual void save_explain_data(EXPLAIN_BKA_TYPE *explain); virtual bool save_explain_data(EXPLAIN_BKA_TYPE *explain);
THD *thd(); THD *thd();
@ -1340,7 +1340,7 @@ public:
/* Check index condition of the joined table for a record from BKA cache */ /* Check index condition of the joined table for a record from BKA cache */
bool skip_index_tuple(range_id_t range_info); bool skip_index_tuple(range_id_t range_info);
void save_explain_data(EXPLAIN_BKA_TYPE *explain); bool save_explain_data(EXPLAIN_BKA_TYPE *explain);
}; };
@ -1431,5 +1431,5 @@ public:
/* Check index condition of the joined table for a record from BKAH cache */ /* Check index condition of the joined table for a record from BKAH cache */
bool skip_index_tuple(range_id_t range_info); bool skip_index_tuple(range_id_t range_info);
void save_explain_data(EXPLAIN_BKA_TYPE *explain); bool save_explain_data(EXPLAIN_BKA_TYPE *explain);
}; };

View File

@ -2588,7 +2588,7 @@ public:
Explain_update* save_explain_update_data(MEM_ROOT *mem_root, THD *thd); Explain_update* save_explain_update_data(MEM_ROOT *mem_root, THD *thd);
protected: protected:
void save_explain_data_intern(MEM_ROOT *mem_root, Explain_update *eu, bool is_analyze); bool save_explain_data_intern(MEM_ROOT *mem_root, Explain_update *eu, bool is_analyze);
public: public:
virtual ~Update_plan() {} virtual ~Update_plan() {}

View File

@ -1,5 +1,5 @@
/* Copyright (c) 2000, 2016 Oracle and/or its affiliates. /* Copyright (c) 2000, 2016 Oracle and/or its affiliates.
Copyright (c) 2009, 2016 MariaDB Copyright (c) 2009, 2016, 2017 MariaDB
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -713,7 +713,7 @@ JOIN::prepare(TABLE_LIST *tables_init,
union_part= unit_arg->is_unit_op(); union_part= unit_arg->is_unit_op();
if (select_lex->handle_derived(thd->lex, DT_PREPARE)) if (select_lex->handle_derived(thd->lex, DT_PREPARE))
DBUG_RETURN(1); DBUG_RETURN(-1);
thd->lex->current_select->context_analysis_place= NO_MATTER; thd->lex->current_select->context_analysis_place= NO_MATTER;
thd->lex->current_select->is_item_list_lookup= 1; thd->lex->current_select->is_item_list_lookup= 1;
@ -948,6 +948,8 @@ JOIN::prepare(TABLE_LIST *tables_init,
(*ord->item)->field_type() == MYSQL_TYPE_BIT) (*ord->item)->field_type() == MYSQL_TYPE_BIT)
{ {
Item_field *field= new (thd->mem_root) Item_field(thd, *(Item_field**)ord->item); Item_field *field= new (thd->mem_root) Item_field(thd, *(Item_field**)ord->item);
if (!field)
DBUG_RETURN(-1);
int el= all_fields.elements; int el= all_fields.elements;
ref_ptrs[el]= field; ref_ptrs[el]= field;
all_fields.push_front(field, thd->mem_root); all_fields.push_front(field, thd->mem_root);
@ -1080,14 +1082,16 @@ err:
DBUG_RETURN(res); /* purecov: inspected */ DBUG_RETURN(res); /* purecov: inspected */
} }
void JOIN::build_explain()
bool JOIN::build_explain()
{ {
create_explain_query_if_not_exists(thd->lex, thd->mem_root); create_explain_query_if_not_exists(thd->lex, thd->mem_root);
have_query_plan= QEP_AVAILABLE; have_query_plan= QEP_AVAILABLE;
save_explain_data(thd->lex->explain, false /* can overwrite */, if (save_explain_data(thd->lex->explain, false /* can overwrite */,
need_tmp, need_tmp,
!skip_sort_order && !no_order && (order || group_list), !skip_sort_order && !no_order && (order || group_list),
select_distinct); select_distinct))
return 1;
uint select_nr= select_lex->select_number; uint select_nr= select_lex->select_number;
JOIN_TAB *curr_tab= join_tab + exec_join_tab_cnt(); JOIN_TAB *curr_tab= join_tab + exec_join_tab_cnt();
for (uint i= 0; i < aggr_tables; i++, curr_tab++) for (uint i= 0; i < aggr_tables; i++, curr_tab++)
@ -1105,8 +1109,10 @@ void JOIN::build_explain()
get_using_temporary_read_tracker(); get_using_temporary_read_tracker();
} }
} }
return 0;
} }
int JOIN::optimize() int JOIN::optimize()
{ {
int res= 0; int res= 0;
@ -1126,7 +1132,7 @@ int JOIN::optimize()
init_state == JOIN::OPTIMIZATION_PHASE_1_DONE) init_state == JOIN::OPTIMIZATION_PHASE_1_DONE)
{ {
if (!res && have_query_plan != QEP_DELETED) if (!res && have_query_plan != QEP_DELETED)
build_explain(); res= build_explain();
optimization_state= JOIN::OPTIMIZATION_DONE; optimization_state= JOIN::OPTIMIZATION_DONE;
} }
return res; return res;
@ -1720,6 +1726,9 @@ int JOIN::optimize_stage2()
{ {
ref_item= substitute_for_best_equal_field(thd, tab, ref_item, ref_item= substitute_for_best_equal_field(thd, tab, ref_item,
equals, map2table); equals, map2table);
if (thd->is_fatal_error)
DBUG_RETURN(1);
if (first_inner) if (first_inner)
{ {
equals= first_inner->cond_equal; equals= first_inner->cond_equal;
@ -2032,7 +2041,8 @@ int JOIN::optimize_stage2()
/* Perform FULLTEXT search before all regular searches */ /* Perform FULLTEXT search before all regular searches */
if (!(select_options & SELECT_DESCRIBE)) if (!(select_options & SELECT_DESCRIBE))
init_ftfuncs(thd, select_lex, MY_TEST(order)); if (init_ftfuncs(thd, select_lex, MY_TEST(order)))
DBUG_RETURN(1);
/* /*
It's necessary to check const part of HAVING cond as It's necessary to check const part of HAVING cond as
@ -2419,7 +2429,8 @@ bool JOIN::make_aggr_tables_info()
if (gbh) if (gbh)
{ {
pushdown_query= new (thd->mem_root) Pushdown_query(select_lex, gbh); if (!(pushdown_query= new (thd->mem_root) Pushdown_query(select_lex, gbh)))
DBUG_RETURN(1);
/* /*
We must store rows in the tmp table if we need to do an ORDER BY We must store rows in the tmp table if we need to do an ORDER BY
or DISTINCT and the storage handler can't handle it. or DISTINCT and the storage handler can't handle it.
@ -2436,7 +2447,8 @@ bool JOIN::make_aggr_tables_info()
curr_tab->ref.key= -1; curr_tab->ref.key= -1;
curr_tab->join= this; curr_tab->join= this;
curr_tab->tmp_table_param= new TMP_TABLE_PARAM(tmp_table_param); if (!(curr_tab->tmp_table_param= new TMP_TABLE_PARAM(tmp_table_param)))
DBUG_RETURN(1);
TABLE* table= create_tmp_table(thd, curr_tab->tmp_table_param, TABLE* table= create_tmp_table(thd, curr_tab->tmp_table_param,
all_fields, all_fields,
NULL, query.distinct, NULL, query.distinct,
@ -2446,7 +2458,8 @@ bool JOIN::make_aggr_tables_info()
if (!table) if (!table)
DBUG_RETURN(1); DBUG_RETURN(1);
curr_tab->aggr= new (thd->mem_root) AGGR_OP(curr_tab); if (!(curr_tab->aggr= new (thd->mem_root) AGGR_OP(curr_tab)))
DBUG_RETURN(1);
curr_tab->aggr->set_write_func(::end_send); curr_tab->aggr->set_write_func(::end_send);
curr_tab->table= table; curr_tab->table= table;
/* /*
@ -2886,7 +2899,8 @@ bool JOIN::make_aggr_tables_info()
curr_tab= join_tab + exec_join_tab_cnt() + aggr_tables - 1; curr_tab= join_tab + exec_join_tab_cnt() + aggr_tables - 1;
if (select_lex->window_funcs.elements) if (select_lex->window_funcs.elements)
{ {
curr_tab->window_funcs_step= new Window_funcs_computation; if (!(curr_tab->window_funcs_step= new Window_funcs_computation))
DBUG_RETURN(true);
if (curr_tab->window_funcs_step->setup(thd, &select_lex->window_funcs, if (curr_tab->window_funcs_step->setup(thd, &select_lex->window_funcs,
curr_tab)) curr_tab))
DBUG_RETURN(true); DBUG_RETURN(true);
@ -2928,7 +2942,8 @@ JOIN::create_postjoin_aggr_table(JOIN_TAB *tab, List<Item> *table_fields,
!select_lex->with_sum_func) ? !select_lex->with_sum_func) ?
select_limit : HA_POS_ERROR; select_limit : HA_POS_ERROR;
tab->tmp_table_param= new TMP_TABLE_PARAM(tmp_table_param); if (!(tab->tmp_table_param= new TMP_TABLE_PARAM(tmp_table_param)))
DBUG_RETURN(true);
tab->tmp_table_param->skip_create_table= true; tab->tmp_table_param->skip_create_table= true;
TABLE* table= create_tmp_table(thd, tab->tmp_table_param, *table_fields, TABLE* table= create_tmp_table(thd, tab->tmp_table_param, *table_fields,
table_group, distinct, table_group, distinct,
@ -2942,8 +2957,7 @@ JOIN::create_postjoin_aggr_table(JOIN_TAB *tab, List<Item> *table_fields,
DBUG_ASSERT(tab > tab->join->join_tab || !top_join_tab_count || !tables_list); DBUG_ASSERT(tab > tab->join->join_tab || !top_join_tab_count || !tables_list);
if (tab > join_tab) if (tab > join_tab)
(tab - 1)->next_select= sub_select_postjoin_aggr; (tab - 1)->next_select= sub_select_postjoin_aggr;
tab->aggr= new (thd->mem_root) AGGR_OP(tab); if (!(tab->aggr= new (thd->mem_root) AGGR_OP(tab)))
if (!tab->aggr)
goto err; goto err;
tab->table= table; tab->table= table;
table->reginfo.join_tab= tab; table->reginfo.join_tab= tab;
@ -3093,33 +3107,42 @@ bool JOIN::setup_subquery_caches()
select_lex->expr_cache_may_be_used[IN_ON] || select_lex->expr_cache_may_be_used[IN_ON] ||
select_lex->expr_cache_may_be_used[NO_MATTER]) select_lex->expr_cache_may_be_used[NO_MATTER])
{ {
if (conds)
conds= conds->transform(thd, &Item::expr_cache_insert_transformer,
NULL);
JOIN_TAB *tab; JOIN_TAB *tab;
if (conds &&
!(conds= conds->transform(thd, &Item::expr_cache_insert_transformer,
NULL)))
DBUG_RETURN(TRUE);
for (tab= first_linear_tab(this, WITH_BUSH_ROOTS, WITHOUT_CONST_TABLES); for (tab= first_linear_tab(this, WITH_BUSH_ROOTS, WITHOUT_CONST_TABLES);
tab; tab= next_linear_tab(this, tab, WITH_BUSH_ROOTS)) tab; tab= next_linear_tab(this, tab, WITH_BUSH_ROOTS))
{ {
if (tab->select_cond) if (tab->select_cond &&
tab->select_cond= !(tab->select_cond=
tab->select_cond->transform(thd, &Item::expr_cache_insert_transformer, tab->select_cond->transform(thd,
NULL); &Item::expr_cache_insert_transformer,
NULL)))
DBUG_RETURN(TRUE);
if (tab->cache_select && tab->cache_select->cond) if (tab->cache_select && tab->cache_select->cond)
tab->cache_select->cond= if (!(tab->cache_select->cond=
tab->cache_select-> tab->cache_select->
cond->transform(thd, &Item::expr_cache_insert_transformer, cond->transform(thd, &Item::expr_cache_insert_transformer,
NULL); NULL)))
DBUG_RETURN(TRUE);
} }
if (having) if (having &&
having= having->transform(thd, &Item::expr_cache_insert_transformer, !(having= having->transform(thd,
NULL); &Item::expr_cache_insert_transformer,
NULL)))
DBUG_RETURN(TRUE);
if (tmp_having) if (tmp_having)
{ {
DBUG_ASSERT(having == NULL); DBUG_ASSERT(having == NULL);
tmp_having= tmp_having->transform(thd, &Item::expr_cache_insert_transformer, if (!(tmp_having=
NULL); tmp_having->transform(thd,
&Item::expr_cache_insert_transformer,
NULL)))
DBUG_RETURN(TRUE);
} }
} }
if (select_lex->expr_cache_may_be_used[SELECT_LIST] || if (select_lex->expr_cache_may_be_used[SELECT_LIST] ||
@ -3130,9 +3153,11 @@ bool JOIN::setup_subquery_caches()
Item *item; Item *item;
while ((item= li++)) while ((item= li++))
{ {
Item *new_item= Item *new_item;
if (!(new_item=
item->transform(thd, &Item::expr_cache_insert_transformer, item->transform(thd, &Item::expr_cache_insert_transformer,
NULL); NULL)))
DBUG_RETURN(TRUE);
if (new_item != item) if (new_item != item)
{ {
thd->change_item_tree(li.ref(), new_item); thd->change_item_tree(li.ref(), new_item);
@ -3140,18 +3165,22 @@ bool JOIN::setup_subquery_caches()
} }
for (ORDER *tmp_group= group_list; tmp_group ; tmp_group= tmp_group->next) for (ORDER *tmp_group= group_list; tmp_group ; tmp_group= tmp_group->next)
{ {
*tmp_group->item= if (!(*tmp_group->item=
(*tmp_group->item)->transform(thd, &Item::expr_cache_insert_transformer, (*tmp_group->item)->transform(thd,
NULL); &Item::expr_cache_insert_transformer,
NULL)))
DBUG_RETURN(TRUE);
} }
} }
if (select_lex->expr_cache_may_be_used[NO_MATTER]) if (select_lex->expr_cache_may_be_used[NO_MATTER])
{ {
for (ORDER *ord= order; ord; ord= ord->next) for (ORDER *ord= order; ord; ord= ord->next)
{ {
*ord->item= if (!(*ord->item=
(*ord->item)->transform(thd, &Item::expr_cache_insert_transformer, (*ord->item)->transform(thd,
NULL); &Item::expr_cache_insert_transformer,
NULL)))
DBUG_RETURN(TRUE);
} }
} }
DBUG_RETURN(FALSE); DBUG_RETURN(FALSE);
@ -3276,7 +3305,8 @@ JOIN::reinit()
} }
if (!(select_options & SELECT_DESCRIBE)) if (!(select_options & SELECT_DESCRIBE))
init_ftfuncs(thd, select_lex, MY_TEST(order)); if (init_ftfuncs(thd, select_lex, MY_TEST(order)))
DBUG_RETURN(1);
DBUG_RETURN(0); DBUG_RETURN(0);
} }
@ -3318,7 +3348,14 @@ err:
} }
void JOIN::save_explain_data(Explain_query *output, bool can_overwrite, /**
@retval
0 ok
1 error
*/
bool JOIN::save_explain_data(Explain_query *output, bool can_overwrite,
bool need_tmp_table, bool need_order, bool need_tmp_table, bool need_order,
bool distinct) bool distinct)
{ {
@ -3337,9 +3374,8 @@ void JOIN::save_explain_data(Explain_query *output, bool can_overwrite,
/* It's a degenerate join */ /* It's a degenerate join */
message= zero_result_cause ? zero_result_cause : "No tables used"; message= zero_result_cause ? zero_result_cause : "No tables used";
} }
save_explain_data_intern(thd->lex->explain, need_tmp_table, need_order, return save_explain_data_intern(thd->lex->explain, need_tmp_table, need_order,
distinct, message); distinct, message);
return;
} }
/* /*
@ -3359,11 +3395,13 @@ void JOIN::save_explain_data(Explain_query *output, bool can_overwrite,
{ {
if (join_tab[i].filesort) if (join_tab[i].filesort)
{ {
join_tab[i].filesort->tracker= if (!(join_tab[i].filesort->tracker=
new Filesort_tracker(thd->lex->analyze_stmt); new Filesort_tracker(thd->lex->analyze_stmt)))
return 1;
} }
} }
} }
return 0;
} }
@ -12241,7 +12279,8 @@ bool JOIN_TAB::preread_init()
/* init ftfuns for just initialized derived table */ /* init ftfuns for just initialized derived table */
if (table->fulltext_searched) if (table->fulltext_searched)
init_ftfuncs(join->thd, join->select_lex, MY_TEST(join->order)); if (init_ftfuncs(join->thd, join->select_lex, MY_TEST(join->order)))
return TRUE;
return FALSE; return FALSE;
} }
@ -14422,7 +14461,7 @@ static COND* substitute_for_best_equal_field(THD *thd, JOIN_TAB *context_tab,
This works OK with PS/SP re-execution as changes are made to This works OK with PS/SP re-execution as changes are made to
the arguments of AND/OR items only the arguments of AND/OR items only
*/ */
if (new_item != item) if (new_item && new_item != item)
li.replace(new_item); li.replace(new_item);
} }
@ -14501,7 +14540,9 @@ static COND* substitute_for_best_equal_field(THD *thd, JOIN_TAB *context_tab,
while((item_equal= it++)) while((item_equal= it++))
{ {
REPLACE_EQUAL_FIELD_ARG arg= {item_equal, context_tab}; REPLACE_EQUAL_FIELD_ARG arg= {item_equal, context_tab};
cond= cond->transform(thd, &Item::replace_equal_field, (uchar *) &arg); if (!(cond= cond->transform(thd, &Item::replace_equal_field,
(uchar *) &arg)))
return 0;
} }
cond_equal= cond_equal->upper_levels; cond_equal= cond_equal->upper_levels;
} }
@ -14658,6 +14699,7 @@ change_cond_ref_to_const(THD *thd, I_List<COND_CMP> *save_list,
{ {
cond->marker=1; cond->marker=1;
COND_CMP *tmp2; COND_CMP *tmp2;
/* Will work, even if malloc would fail */
if ((tmp2= new (thd->mem_root) COND_CMP(and_father, func))) if ((tmp2= new (thd->mem_root) COND_CMP(and_father, func)))
save_list->push_back(tmp2); save_list->push_back(tmp2);
} }
@ -14690,6 +14732,7 @@ change_cond_ref_to_const(THD *thd, I_List<COND_CMP> *save_list,
thd->change_item_tree(args + 1, value); thd->change_item_tree(args + 1, value);
cond->marker=1; cond->marker=1;
COND_CMP *tmp2; COND_CMP *tmp2;
/* Will work, even if malloc would fail */
if ((tmp2=new (thd->mem_root) COND_CMP(and_father, func))) if ((tmp2=new (thd->mem_root) COND_CMP(and_father, func)))
save_list->push_back(tmp2); save_list->push_back(tmp2);
} }
@ -16121,6 +16164,7 @@ Item_func_isnull::remove_eq_conds(THD *thd, Item::cond_result *cond_value,
query_cache_abort(thd, &thd->query_cache_tls); query_cache_abort(thd, &thd->query_cache_tls);
#endif #endif
COND *new_cond, *cond= this; COND *new_cond, *cond= this;
/* If this fails, we will catch it later before executing query */
if ((new_cond= new (thd->mem_root) Item_func_eq(thd, args[0], if ((new_cond= new (thd->mem_root) Item_func_eq(thd, args[0],
new (thd->mem_root) Item_int(thd, "last_insert_id()", new (thd->mem_root) Item_int(thd, "last_insert_id()",
thd->read_first_successful_insert_id_in_prev_stmt(), thd->read_first_successful_insert_id_in_prev_stmt(),
@ -16958,6 +17002,7 @@ create_tmp_table(THD *thd, TMP_TABLE_PARAM *param, List<Item> &fields,
Item *arg= sum_item->get_arg(i); Item *arg= sum_item->get_arg(i);
if (!arg->const_item()) if (!arg->const_item())
{ {
Item *tmp_item;
Field *new_field= Field *new_field=
create_tmp_field(thd, table, arg, arg->type(), &copy_func, create_tmp_field(thd, table, arg, arg->type(), &copy_func,
tmp_from_field, &default_field[fieldnr], tmp_from_field, &default_field[fieldnr],
@ -16983,7 +17028,10 @@ create_tmp_table(THD *thd, TMP_TABLE_PARAM *param, List<Item> &fields,
string_total_length+= new_field->pack_length(); string_total_length+= new_field->pack_length();
} }
thd->mem_root= mem_root_save; thd->mem_root= mem_root_save;
arg= sum_item->set_arg(i, thd, new (thd->mem_root) Item_temptable_field(thd, new_field)); if (!(tmp_item= new (thd->mem_root)
Item_temptable_field(thd, new_field)))
goto err;
arg= sum_item->set_arg(i, thd, tmp_item);
thd->mem_root= &table->mem_root; thd->mem_root= &table->mem_root;
if (param->force_not_null_cols) if (param->force_not_null_cols)
{ {
@ -22859,6 +22907,10 @@ setup_new_fields(THD *thd, List<Item> &fields,
Try to use the fields in the order given by 'order' to allow one to Try to use the fields in the order given by 'order' to allow one to
optimize away 'order by'. optimize away 'order by'.
@retval
0 OOM error if thd->is_fatal_error is set. Otherwise group was eliminated
# Pointer to new group
*/ */
ORDER * ORDER *
@ -22921,6 +22973,8 @@ create_distinct_group(THD *thd, Ref_ptr_array ref_pointer_array,
BIT type and will be returned [el]client. BIT type and will be returned [el]client.
*/ */
Item_field *new_item= new (thd->mem_root) Item_field(thd, (Item_field*)item); Item_field *new_item= new (thd->mem_root) Item_field(thd, (Item_field*)item);
if (!new_item)
return 0;
int el= all_fields.elements; int el= all_fields.elements;
orig_ref_pointer_array[el]= new_item; orig_ref_pointer_array[el]= new_item;
all_fields.push_front(new_item, thd->mem_root); all_fields.push_front(new_item, thd->mem_root);
@ -23602,7 +23656,10 @@ change_to_use_tmp_fields(THD *thd, Ref_ptr_array ref_pointer_array,
if (item->with_sum_func && item->type() != Item::SUM_FUNC_ITEM) if (item->with_sum_func && item->type() != Item::SUM_FUNC_ITEM)
item_field= item; item_field= item;
else if (item->type() == Item::FIELD_ITEM) else if (item->type() == Item::FIELD_ITEM)
item_field= item->get_tmp_table_item(thd); {
if (!(item_field= item->get_tmp_table_item(thd)))
DBUG_RETURN(true);
}
else if (item->type() == Item::FUNC_ITEM && else if (item->type() == Item::FUNC_ITEM &&
((Item_func*)item)->functype() == Item_func::SUSERVAR_FUNC) ((Item_func*)item)->functype() == Item_func::SUSERVAR_FUNC)
{ {
@ -23710,8 +23767,13 @@ change_refs_to_tmp_fields(THD *thd, Ref_ptr_array ref_pointer_array,
if (item->type() == Item::SUM_FUNC_ITEM && item->const_item()) if (item->type() == Item::SUM_FUNC_ITEM && item->const_item())
new_item= item; new_item= item;
else else
new_item= item->get_tmp_table_item(thd); {
res_all_fields.push_back(new_item, thd->mem_root); if (!(new_item= item->get_tmp_table_item(thd)))
return 1;
}
if (res_all_fields.push_back(new_item, thd->mem_root))
return 1;
ref_pointer_array[((i < border)? all_fields.elements-i-1 : i-border)]= ref_pointer_array[((i < border)? all_fields.elements-i-1 : i-border)]=
new_item; new_item;
} }
@ -24077,7 +24139,9 @@ bool JOIN::rollup_init()
*/ */
for (i= 0 ; i < send_group_parts ; i++) for (i= 0 ; i < send_group_parts ; i++)
{ {
rollup.null_items[i]= new (thd->mem_root) Item_null_result(thd); if (!(rollup.null_items[i]= new (thd->mem_root) Item_null_result(thd)))
return true;
List<Item> *rollup_fields= &rollup.fields[i]; List<Item> *rollup_fields= &rollup.fields[i];
rollup_fields->empty(); rollup_fields->empty();
rollup.ref_pointer_arrays[i]= Ref_ptr_array(ref_array, all_fields.elements); rollup.ref_pointer_arrays[i]= Ref_ptr_array(ref_array, all_fields.elements);
@ -24421,8 +24485,12 @@ void JOIN::clear()
} }
/* /**
Print an EXPLAIN line with all NULLs and given message in the 'Extra' column Print an EXPLAIN line with all NULLs and given message in the 'Extra' column
@retval
0 ok
1 OOM error or error from send_data()
*/ */
int print_explain_message_line(select_result_sink *result, int print_explain_message_line(select_result_sink *result,
@ -24481,7 +24549,7 @@ int print_explain_message_line(select_result_sink *result,
else else
item_list.push_back(item_null, mem_root); item_list.push_back(item_null, mem_root);
if (result->send_data(item_list)) if (thd->is_fatal_error || result->send_data(item_list))
return 1; return 1;
return 0; return 0;
} }
@ -24515,13 +24583,14 @@ int append_possible_keys(MEM_ROOT *alloc, String_list &list, TABLE *table,
for (j=0 ; j < table->s->keys ; j++) for (j=0 ; j < table->s->keys ; j++)
{ {
if (possible_keys.is_set(j)) if (possible_keys.is_set(j))
list.append_str(alloc, table->key_info[j].name.str); if (!(list.append_str(alloc, table->key_info[j].name.str)))
return 1;
} }
return 0; return 0;
} }
void JOIN_TAB::save_explain_data(Explain_table_access *eta, bool JOIN_TAB::save_explain_data(Explain_table_access *eta,
table_map prefix_tables, table_map prefix_tables,
bool distinct_arg, JOIN_TAB *first_top_tab) bool distinct_arg, JOIN_TAB *first_top_tab)
{ {
@ -24550,9 +24619,11 @@ void JOIN_TAB::save_explain_data(Explain_table_access *eta,
if (filesort) if (filesort)
{ {
eta->pre_join_sort= new Explain_aggr_filesort(thd->mem_root, if (!(eta->pre_join_sort=
new Explain_aggr_filesort(thd->mem_root,
thd->lex->analyze_stmt, thd->lex->analyze_stmt,
filesort); filesort)))
return 1;
} }
tracker= &eta->tracker; tracker= &eta->tracker;
@ -24649,7 +24720,8 @@ void JOIN_TAB::save_explain_data(Explain_table_access *eta,
// psergey-todo: why does this use thd MEM_ROOT??? Doesn't this // psergey-todo: why does this use thd MEM_ROOT??? Doesn't this
// break ANALYZE ? thd->mem_root will be freed, and after that we will // break ANALYZE ? thd->mem_root will be freed, and after that we will
// attempt to print the query plan? // attempt to print the query plan?
append_possible_keys(thd->mem_root, eta->possible_keys, table, keys); if (append_possible_keys(thd->mem_root, eta->possible_keys, table, keys))
return 1;
// psergey-todo: ^ check for error return code // psergey-todo: ^ check for error return code
/* Build "key", "key_len", and "ref" */ /* Build "key", "key_len", and "ref" */
@ -24670,7 +24742,8 @@ void JOIN_TAB::save_explain_data(Explain_table_access *eta,
*/ */
if (tab_select && tab_select->quick && tab_type != JT_CONST) if (tab_select && tab_select->quick && tab_type != JT_CONST)
{ {
eta->quick_info= tab_select->quick->get_explain(thd->mem_root); if (!(eta->quick_info= tab_select->quick->get_explain(thd->mem_root)))
return 1;
} }
if (key_info) /* 'index' or 'ref' access */ if (key_info) /* 'index' or 'ref' access */
@ -24683,10 +24756,14 @@ void JOIN_TAB::save_explain_data(Explain_table_access *eta,
for (uint kp= 0; kp < ref.key_parts; kp++) for (uint kp= 0; kp < ref.key_parts; kp++)
{ {
if ((key_part_map(1) << kp) & ref.const_ref_part_map) if ((key_part_map(1) << kp) & ref.const_ref_part_map)
eta->ref_list.append_str(thd->mem_root, "const"); {
if (!(eta->ref_list.append_str(thd->mem_root, "const")))
return 1;
}
else else
{ {
eta->ref_list.append_str(thd->mem_root, (*key_ref)->name()); if (!(eta->ref_list.append_str(thd->mem_root, (*key_ref)->name())))
return 1;
key_ref++; key_ref++;
} }
} }
@ -24943,7 +25020,8 @@ void JOIN_TAB::save_explain_data(Explain_table_access *eta,
if (cache) if (cache)
{ {
eta->push_extra(ET_USING_JOIN_BUFFER); eta->push_extra(ET_USING_JOIN_BUFFER);
cache->save_explain_data(&eta->bka_type); if (cache->save_explain_data(&eta->bka_type))
return 1;
} }
} }
@ -24956,15 +25034,21 @@ void JOIN_TAB::save_explain_data(Explain_table_access *eta,
/* The same for non-merged semi-joins */ /* The same for non-merged semi-joins */
eta->non_merged_sjm_number = get_non_merged_semijoin_select(); eta->non_merged_sjm_number = get_non_merged_semijoin_select();
return 0;
} }
/* /*
Walk through join->aggr_tables and save aggregation/grouping query plan into Walk through join->aggr_tables and save aggregation/grouping query plan into
an Explain_select object an Explain_select object
@retval
0 ok
1 error
*/ */
void save_agg_explain_data(JOIN *join, Explain_select *xpl_sel) bool save_agg_explain_data(JOIN *join, Explain_select *xpl_sel)
{ {
JOIN_TAB *join_tab=join->join_tab + join->exec_join_tab_cnt(); JOIN_TAB *join_tab=join->join_tab + join->exec_join_tab_cnt();
Explain_aggr_node *prev_node; Explain_aggr_node *prev_node;
@ -24976,7 +25060,8 @@ void save_agg_explain_data(JOIN *join, Explain_select *xpl_sel)
{ {
// Each aggregate means a temp.table // Each aggregate means a temp.table
prev_node= node; prev_node= node;
node= new Explain_aggr_tmp_table; if (!(node= new Explain_aggr_tmp_table))
return 1;
node->child= prev_node; node->child= prev_node;
if (join_tab->window_funcs_step) if (join_tab->window_funcs_step)
@ -24984,19 +25069,20 @@ void save_agg_explain_data(JOIN *join, Explain_select *xpl_sel)
Explain_aggr_node *new_node= Explain_aggr_node *new_node=
join_tab->window_funcs_step->save_explain_plan(thd->mem_root, join_tab->window_funcs_step->save_explain_plan(thd->mem_root,
is_analyze); is_analyze);
if (new_node) if (!new_node)
{ return 1;
prev_node=node; prev_node=node;
node= new_node; node= new_node;
node->child= prev_node; node->child= prev_node;
} }
}
/* The below matches execution in join_init_read_record() */ /* The below matches execution in join_init_read_record() */
if (join_tab->distinct) if (join_tab->distinct)
{ {
prev_node= node; prev_node= node;
node= new Explain_aggr_remove_dups; if (!(node= new Explain_aggr_remove_dups))
return 1;
node->child= prev_node; node->child= prev_node;
} }
@ -25004,20 +25090,27 @@ void save_agg_explain_data(JOIN *join, Explain_select *xpl_sel)
{ {
Explain_aggr_filesort *eaf = Explain_aggr_filesort *eaf =
new Explain_aggr_filesort(thd->mem_root, is_analyze, join_tab->filesort); new Explain_aggr_filesort(thd->mem_root, is_analyze, join_tab->filesort);
if (!eaf)
return 1;
prev_node= node; prev_node= node;
node= eaf; node= eaf;
node->child= prev_node; node->child= prev_node;
} }
} }
xpl_sel->aggr_tree= node; xpl_sel->aggr_tree= node;
return 0;
} }
/* /**
Save Query Plan Footprint Save Query Plan Footprint
@note @note
Currently, this function may be called multiple times Currently, this function may be called multiple times
@retval
0 ok
1 error
*/ */
int JOIN::save_explain_data_intern(Explain_query *output, int JOIN::save_explain_data_intern(Explain_query *output,
@ -25026,7 +25119,6 @@ int JOIN::save_explain_data_intern(Explain_query *output,
const char *message) const char *message)
{ {
JOIN *join= this; /* Legacy: this code used to be a non-member function */ JOIN *join= this; /* Legacy: this code used to be a non-member function */
int cur_error= 0;
DBUG_ENTER("JOIN::save_explain_data_intern"); DBUG_ENTER("JOIN::save_explain_data_intern");
DBUG_PRINT("info", ("Select %p, type %s, message %s", DBUG_PRINT("info", ("Select %p, type %s, message %s",
join->select_lex, join->select_lex->type, join->select_lex, join->select_lex->type,
@ -25044,8 +25136,11 @@ int JOIN::save_explain_data_intern(Explain_query *output,
if (message) if (message)
{ {
explain= new (output->mem_root) Explain_select(output->mem_root, if (!(explain= new (output->mem_root)
thd->lex->analyze_stmt); Explain_select(output->mem_root,
thd->lex->analyze_stmt)))
DBUG_RETURN(1);
join->select_lex->set_explain_type(true); join->select_lex->set_explain_type(true);
explain->select_id= join->select_lex->select_number; explain->select_id= join->select_lex->select_number;
@ -25058,13 +25153,17 @@ int JOIN::save_explain_data_intern(Explain_query *output,
if (select_lex->master_unit()->derived) if (select_lex->master_unit()->derived)
explain->connection_type= Explain_node::EXPLAIN_NODE_DERIVED; explain->connection_type= Explain_node::EXPLAIN_NODE_DERIVED;
save_agg_explain_data(this, explain); if (save_agg_explain_data(this, explain))
DBUG_RETURN(1);
output->add_node(explain); output->add_node(explain);
} }
else if (pushdown_query) else if (pushdown_query)
{ {
explain= new (output->mem_root) Explain_select(output->mem_root, if (!(explain= new (output->mem_root)
thd->lex->analyze_stmt); Explain_select(output->mem_root,
thd->lex->analyze_stmt)))
DBUG_RETURN(1);
select_lex->set_explain_type(true); select_lex->set_explain_type(true);
explain->select_id= select_lex->select_number; explain->select_id= select_lex->select_number;
@ -25084,6 +25183,9 @@ int JOIN::save_explain_data_intern(Explain_query *output,
explain= xpl_sel= explain= xpl_sel=
new (output->mem_root) Explain_select(output->mem_root, new (output->mem_root) Explain_select(output->mem_root,
thd->lex->analyze_stmt); thd->lex->analyze_stmt);
if (!explain)
DBUG_RETURN(1);
table_map used_tables=0; table_map used_tables=0;
join->select_lex->set_explain_type(true); join->select_lex->set_explain_type(true);
@ -25093,7 +25195,8 @@ int JOIN::save_explain_data_intern(Explain_query *output,
if (select_lex->master_unit()->derived) if (select_lex->master_unit()->derived)
xpl_sel->connection_type= Explain_node::EXPLAIN_NODE_DERIVED; xpl_sel->connection_type= Explain_node::EXPLAIN_NODE_DERIVED;
save_agg_explain_data(this, xpl_sel); if (save_agg_explain_data(this, xpl_sel))
DBUG_RETURN(1);
xpl_sel->exec_const_cond= exec_const_cond; xpl_sel->exec_const_cond= exec_const_cond;
xpl_sel->outer_ref_cond= outer_ref_cond; xpl_sel->outer_ref_cond= outer_ref_cond;
@ -25125,6 +25228,8 @@ int JOIN::save_explain_data_intern(Explain_query *output,
Explain_table_access *eta= (new (output->mem_root) Explain_table_access *eta= (new (output->mem_root)
Explain_table_access(output->mem_root)); Explain_table_access(output->mem_root));
if (!eta)
DBUG_RETURN(1);
if (tab->bush_root_tab != prev_bush_root_tab) if (tab->bush_root_tab != prev_bush_root_tab)
{ {
if (tab->bush_root_tab) if (tab->bush_root_tab)
@ -25132,7 +25237,9 @@ int JOIN::save_explain_data_intern(Explain_query *output,
/* /*
We've entered an SJ-Materialization nest. Create an object for it. We've entered an SJ-Materialization nest. Create an object for it.
*/ */
cur_parent= new (output->mem_root) Explain_basic_join(output->mem_root); if (!(cur_parent=
new (output->mem_root) Explain_basic_join(output->mem_root)))
DBUG_RETURN(1);
JOIN_TAB *first_child= tab->bush_root_tab->bush_children->start; JOIN_TAB *first_child= tab->bush_root_tab->bush_children->start;
cur_parent->select_id= cur_parent->select_id=
@ -25152,7 +25259,8 @@ int JOIN::save_explain_data_intern(Explain_query *output,
prev_bush_root_tab= tab->bush_root_tab; prev_bush_root_tab= tab->bush_root_tab;
cur_parent->add_table(eta, output); cur_parent->add_table(eta, output);
tab->save_explain_data(eta, used_tables, distinct_arg, first_top_tab); if (tab->save_explain_data(eta, used_tables, distinct_arg, first_top_tab))
DBUG_RETURN(1);
if (saved_join_tab) if (saved_join_tab)
tab= saved_join_tab; tab= saved_join_tab;
@ -25184,10 +25292,10 @@ int JOIN::save_explain_data_intern(Explain_query *output,
} }
} }
if (!cur_error && select_lex->is_top_level_node()) if (select_lex->is_top_level_node())
output->query_plan_ready(); output->query_plan_ready();
DBUG_RETURN(cur_error); DBUG_RETURN(0);
} }

View File

@ -608,7 +608,7 @@ typedef struct st_join_table {
void remove_redundant_bnl_scan_conds(); void remove_redundant_bnl_scan_conds();
void save_explain_data(Explain_table_access *eta, table_map prefix_tables, bool save_explain_data(Explain_table_access *eta, table_map prefix_tables,
bool distinct, struct st_join_table *first_top_tab); bool distinct, struct st_join_table *first_top_tab);
bool use_order() const; ///< Use ordering provided by chosen index? bool use_order() const; ///< Use ordering provided by chosen index?
@ -1526,7 +1526,7 @@ public:
int optimize(); int optimize();
int optimize_inner(); int optimize_inner();
int optimize_stage2(); int optimize_stage2();
void build_explain(); bool build_explain();
int reinit(); int reinit();
int init_execution(); int init_execution();
void exec(); void exec();
@ -1667,7 +1667,7 @@ public:
{ {
return (unit->item && unit->item->is_in_predicate()); return (unit->item && unit->item->is_in_predicate());
} }
void save_explain_data(Explain_query *output, bool can_overwrite, bool save_explain_data(Explain_query *output, bool can_overwrite,
bool need_tmp_table, bool need_order, bool distinct); bool need_tmp_table, bool need_order, bool distinct);
int save_explain_data_intern(Explain_query *output, bool need_tmp_table, int save_explain_data_intern(Explain_query *output, bool need_tmp_table,
bool need_order, bool distinct, bool need_order, bool distinct,

View File

@ -181,6 +181,8 @@ public:
} }
static void *operator new(size_t size, MEM_ROOT *mem_root) throw () static void *operator new(size_t size, MEM_ROOT *mem_root) throw ()
{ return (void*) alloc_root(mem_root, (uint) size); } { return (void*) alloc_root(mem_root, (uint) size); }
static void *operator new[](size_t size, MEM_ROOT *mem_root) throw ()
{ return alloc_root(mem_root, size); }
static void operator delete(void *ptr_arg, size_t size) static void operator delete(void *ptr_arg, size_t size)
{ {
(void) ptr_arg; (void) ptr_arg;
@ -189,6 +191,10 @@ public:
} }
static void operator delete(void *, MEM_ROOT *) static void operator delete(void *, MEM_ROOT *)
{ /* never called */ } { /* never called */ }
static void operator delete[](void *ptr, size_t size) { TRASH(ptr, size); }
static void operator delete[](void *ptr, MEM_ROOT *mem_root)
{ /* never called */ }
~String() { free(); } ~String() { free(); }
/* Mark variable thread specific it it's not allocated already */ /* Mark variable thread specific it it's not allocated already */

View File

@ -9697,7 +9697,7 @@ copy_data_between_tables(THD *thd, TABLE *from, TABLE *to,
if (mysql_trans_prepare_alter_copy_data(thd)) if (mysql_trans_prepare_alter_copy_data(thd))
DBUG_RETURN(-1); DBUG_RETURN(-1);
if (!(copy= new Copy_field[to->s->fields])) if (!(copy= new (thd->mem_root) Copy_field[to->s->fields]))
DBUG_RETURN(-1); /* purecov: inspected */ DBUG_RETURN(-1); /* purecov: inspected */
/* We need external lock before we can disable/enable keys */ /* We need external lock before we can disable/enable keys */

View File

@ -283,6 +283,9 @@ int table_value_constr::save_explain_data_intern(THD *thd,
explain= new (output->mem_root) Explain_select(output->mem_root, explain= new (output->mem_root) Explain_select(output->mem_root,
thd->lex->analyze_stmt); thd->lex->analyze_stmt);
if (!explain)
DBUG_RETURN(1);
select_lex->set_explain_type(true); select_lex->set_explain_type(true);
explain->select_id= select_lex->select_number; explain->select_id= select_lex->select_number;
@ -309,7 +312,7 @@ int table_value_constr::save_explain_data_intern(THD *thd,
Optimization of TVC Optimization of TVC
*/ */
void table_value_constr::optimize(THD *thd) bool table_value_constr::optimize(THD *thd)
{ {
create_explain_query_if_not_exists(thd->lex, thd->mem_root); create_explain_query_if_not_exists(thd->lex, thd->mem_root);
have_query_plan= QEP_AVAILABLE; have_query_plan= QEP_AVAILABLE;
@ -320,8 +323,9 @@ void table_value_constr::optimize(THD *thd)
thd->lex->explain && // for "SET" command in SPs. thd->lex->explain && // for "SET" command in SPs.
(!thd->lex->explain->get_select(select_lex->select_number))) (!thd->lex->explain->get_select(select_lex->select_number)))
{ {
save_explain_data_intern(thd, thd->lex->explain); return save_explain_data_intern(thd, thd->lex->explain);
} }
return 0;
} }

View File

@ -57,7 +57,7 @@ public:
int save_explain_data_intern(THD *thd_arg, int save_explain_data_intern(THD *thd_arg,
Explain_query *output); Explain_query *output);
void optimize(THD *thd_arg); bool optimize(THD *thd_arg);
bool exec(SELECT_LEX *sl); bool exec(SELECT_LEX *sl);
void print(THD *thd_arg, String *str, enum_query_type query_type); void print(THD *thd_arg, String *str, enum_query_type query_type);

View File

@ -1282,7 +1282,11 @@ bool st_select_lex_unit::optimize()
sl->tvc->select_options= sl->tvc->select_options=
(select_limit_cnt == HA_POS_ERROR || sl->braces) ? (select_limit_cnt == HA_POS_ERROR || sl->braces) ?
sl->options & ~OPTION_FOUND_ROWS : sl->options | found_rows_for_union; sl->options & ~OPTION_FOUND_ROWS : sl->options | found_rows_for_union;
sl->tvc->optimize(thd); if (sl->tvc->optimize(thd))
{
thd->lex->current_select= lex_select_save;
DBUG_RETURN(TRUE);
}
continue; continue;
} }
thd->lex->current_select= sl; thd->lex->current_select= sl;
@ -1397,7 +1401,7 @@ bool st_select_lex_unit::exec()
sl->tvc->select_options= sl->tvc->select_options=
(select_limit_cnt == HA_POS_ERROR || sl->braces) ? (select_limit_cnt == HA_POS_ERROR || sl->braces) ?
sl->options & ~OPTION_FOUND_ROWS : sl->options | found_rows_for_union; sl->options & ~OPTION_FOUND_ROWS : sl->options | found_rows_for_union;
sl->tvc->optimize(thd); saved_error= sl->tvc->optimize(thd);
} }
else else
{ {

View File

@ -451,7 +451,8 @@ int mysql_update(THD *thd,
goto err; goto err;
} }
} }
init_ftfuncs(thd, select_lex, 1); if (init_ftfuncs(thd, select_lex, 1))
goto err;
table->mark_columns_needed_for_update(); table->mark_columns_needed_for_update();
@ -522,7 +523,8 @@ int mysql_update(THD *thd,
*/ */
if (thd->lex->describe) if (thd->lex->describe)
goto produce_explain_and_leave; goto produce_explain_and_leave;
explain= query_plan.save_explain_update_data(query_plan.mem_root, thd); if (!(explain= query_plan.save_explain_update_data(query_plan.mem_root, thd)))
goto err;
ANALYZE_START_TRACKING(&explain->command_tracker); ANALYZE_START_TRACKING(&explain->command_tracker);
@ -1046,7 +1048,8 @@ produce_explain_and_leave:
We come here for various "degenerate" query plans: impossible WHERE, We come here for various "degenerate" query plans: impossible WHERE,
no-partitions-used, impossible-range, etc. no-partitions-used, impossible-range, etc.
*/ */
query_plan.save_explain_update_data(query_plan.mem_root, thd); if (!query_plan.save_explain_update_data(query_plan.mem_root, thd))
goto err;
emit_explain_and_leave: emit_explain_and_leave:
int err2= thd->lex->explain->send_explain(thd); int err2= thd->lex->explain->send_explain(thd);
@ -1776,7 +1779,7 @@ int multi_update::prepare(List<Item> &not_used_values,
switch_to_nullable_trigger_fields(*values_for_table[i], table); switch_to_nullable_trigger_fields(*values_for_table[i], table);
} }
} }
copy_field= new Copy_field[max_fields]; copy_field= new (thd->mem_root) Copy_field[max_fields];
DBUG_RETURN(thd->is_fatal_error != 0); DBUG_RETURN(thd->is_fatal_error != 0);
} }

View File

@ -3093,10 +3093,14 @@ Window_funcs_computation::save_explain_plan(MEM_ROOT *mem_root,
Explain_aggr_window_funcs *xpl= new Explain_aggr_window_funcs; Explain_aggr_window_funcs *xpl= new Explain_aggr_window_funcs;
List_iterator<Window_funcs_sort> it(win_func_sorts); List_iterator<Window_funcs_sort> it(win_func_sorts);
Window_funcs_sort *srt; Window_funcs_sort *srt;
if (!xpl)
return 0;
while ((srt = it++)) while ((srt = it++))
{ {
Explain_aggr_filesort *eaf= Explain_aggr_filesort *eaf=
new Explain_aggr_filesort(mem_root, is_analyze, srt->filesort); new Explain_aggr_filesort(mem_root, is_analyze, srt->filesort);
if (!eaf)
return 0;
xpl->sorts.push_back(eaf, mem_root); xpl->sorts.push_back(eaf, mem_root);
} }
return xpl; return xpl;

View File

@ -4290,9 +4290,9 @@ int ha_mroonga::storage_open_columns(void)
{ {
if (blob_buffers) if (blob_buffers)
{ {
delete [] blob_buffers; ::delete [] blob_buffers;
} }
if (!(blob_buffers = new String[n_columns])) if (!(blob_buffers = ::new String[n_columns]))
{ {
DBUG_RETURN(HA_ERR_OUT_OF_MEM); DBUG_RETURN(HA_ERR_OUT_OF_MEM);
} }