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:
parent
31bd86c8df
commit
87933d5261
@ -1261,7 +1261,7 @@ Item *Item::safe_charset_converter(THD *thd, CHARSET_INFO *tocs)
|
||||
if (!needs_charset_converter(tocs))
|
||||
return this;
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
@Note thd->fatal_error can be set in case of OOM
|
||||
*/
|
||||
|
||||
void Item_field::fix_after_pullout(st_select_lex *new_parent, Item **ref,
|
||||
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();
|
||||
if (!ctx)
|
||||
return; // Fatal error set
|
||||
if (context->select_lex == new_parent)
|
||||
{
|
||||
/*
|
||||
|
@ -3253,17 +3253,15 @@ udf_handler::fix_fields(THD *thd, Item_func_or_sum *func,
|
||||
func->used_tables_and_const_cache_join(item);
|
||||
f_args.arg_type[i]=item->result_type();
|
||||
}
|
||||
//TODO: why all following memory is not allocated with 1 thd->alloc() call?
|
||||
if (!(buffers=new String[arg_count]) ||
|
||||
!(f_args.args= (char**) thd->alloc(arg_count * sizeof(char *))) ||
|
||||
!(f_args.lengths= (ulong*) thd->alloc(arg_count * sizeof(long))) ||
|
||||
!(f_args.maybe_null= (char*) thd->alloc(arg_count * sizeof(char))) ||
|
||||
!(num_buffer= (char*) thd->alloc(arg_count *
|
||||
ALIGN_SIZE(sizeof(double)))) ||
|
||||
!(f_args.attributes= (const char**) thd->alloc(arg_count *
|
||||
sizeof(char *))) ||
|
||||
!(f_args.attribute_lengths= (ulong*) thd->alloc(arg_count *
|
||||
sizeof(long))))
|
||||
if (!(buffers=new (thd->mem_root) String[arg_count]) ||
|
||||
!multi_alloc_root(thd->mem_root,
|
||||
&f_args.args, arg_count * sizeof(char *),
|
||||
&f_args.lengths, arg_count * sizeof(long),
|
||||
&f_args.maybe_null, arg_count * sizeof(char),
|
||||
&num_buffer, arg_count * sizeof(double),
|
||||
&f_args.attributes, arg_count * sizeof(char *),
|
||||
&f_args.attribute_lengths, arg_count * sizeof(long),
|
||||
NullS))
|
||||
{
|
||||
free_udf(u_d);
|
||||
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.decimals=func->decimals;
|
||||
initid.ptr=0;
|
||||
for (uint i1= 0 ; i1 < arg_count ; i1++)
|
||||
buffers[i1].set_thread_specific();
|
||||
|
||||
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,
|
||||
new (thd->mem_root) Item_null(thd))),
|
||||
thd->mem_root);
|
||||
/* Create the variable */
|
||||
if (sql_set_variables(thd, &tmp_var_list, false))
|
||||
/* Create the variable if the above allocations succeeded */
|
||||
if (thd->is_fatal_error || sql_set_variables(thd, &tmp_var_list, false))
|
||||
{
|
||||
thd->lex= sav_lex;
|
||||
goto err;
|
||||
@ -5837,20 +5837,25 @@ void Item_func_get_system_var::cleanup()
|
||||
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");
|
||||
|
||||
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 */
|
||||
if (ft_handler)
|
||||
{
|
||||
if (join_key)
|
||||
table->file->ft_handler= ft_handler;
|
||||
DBUG_VOID_RETURN;
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
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++)
|
||||
fields.push_back(args[i]);
|
||||
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:
|
||||
Item_string - basic constant
|
||||
@ -5874,10 +5881,11 @@ void Item_func_match::init_search(THD *thd, bool no_order)
|
||||
if (master)
|
||||
{
|
||||
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;
|
||||
join_key= master->join_key;
|
||||
DBUG_VOID_RETURN;
|
||||
DBUG_RETURN(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)
|
||||
{
|
||||
uint dummy_errors;
|
||||
search_value.copy(ft_tmp->ptr(), ft_tmp->length(), ft_tmp->charset(),
|
||||
cmp_collation.collation, &dummy_errors);
|
||||
if (search_value.copy(ft_tmp->ptr(), ft_tmp->length(), ft_tmp->charset(),
|
||||
cmp_collation.collation, &dummy_errors))
|
||||
DBUG_RETURN(1);
|
||||
ft_tmp= &search_value;
|
||||
}
|
||||
|
||||
@ -5908,7 +5917,7 @@ void Item_func_match::init_search(THD *thd, bool no_order)
|
||||
if (join_key)
|
||||
table->file->ft_handler=ft_handler;
|
||||
|
||||
DBUG_VOID_RETURN;
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
|
||||
|
@ -2584,7 +2584,7 @@ public:
|
||||
virtual void print(String *str, enum_query_type query_type);
|
||||
|
||||
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)
|
||||
{
|
||||
return mark_unsupported_function("match ... against()", arg, VCOL_IMPOSSIBLE);
|
||||
|
@ -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,
|
||||
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 sj_table_is_included(JOIN *join, JOIN_TAB *join_tab);
|
||||
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);
|
||||
/* fix fields on subquery was call so they should be the same */
|
||||
DBUG_ASSERT(subq_pred->left_expr->cols() == row->cols());
|
||||
if (!row)
|
||||
DBUG_RETURN(TRUE);
|
||||
DBUG_ASSERT(subq_pred->left_expr->cols() == row->cols());
|
||||
nested_join->sj_outer_expr_list.push_back(&subq_pred->left_expr);
|
||||
Item_func_eq *item_eq=
|
||||
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;
|
||||
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;
|
||||
TABLE_LIST *jtbm;
|
||||
char *tbl_alias;
|
||||
THD *thd= parent_join->thd;
|
||||
DBUG_ENTER("convert_subq_to_jtbm");
|
||||
|
||||
subq_pred->set_strategy(SUBS_MATERIALIZATION);
|
||||
@ -1887,8 +1889,8 @@ static bool convert_subq_to_jtbm(JOIN *parent_join,
|
||||
|
||||
*remove_item= TRUE;
|
||||
|
||||
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!
|
||||
if (!(tbl_alias= (char*)thd->calloc(SUBQERY_TEMPTABLE_NAME_MAX_LEN)) ||
|
||||
!(jtbm= alloc_join_nest(thd))) //todo: this is not a join nest!
|
||||
{
|
||||
DBUG_RETURN(TRUE);
|
||||
}
|
||||
@ -1900,13 +1902,13 @@ static bool convert_subq_to_jtbm(JOIN *parent_join,
|
||||
|
||||
/* Nests do not participate in those 'chains', so: */
|
||||
/* 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
|
||||
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)
|
||||
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);
|
||||
jtbm->alias= tbl_alias;
|
||||
parent_join->table_count++;
|
||||
DBUG_RETURN(FALSE);
|
||||
DBUG_RETURN(thd->is_fatal_error);
|
||||
}
|
||||
subselect_hash_sj_engine *hash_sj_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;
|
||||
|
||||
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. */
|
||||
|
||||
DBUG_RETURN(FALSE);
|
||||
DBUG_RETURN(thd->is_fatal_error);
|
||||
}
|
||||
|
||||
|
||||
@ -1989,6 +1974,9 @@ static TABLE_LIST *alloc_join_nest(THD *thd)
|
||||
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)
|
||||
{
|
||||
@ -3718,6 +3706,11 @@ bool setup_sj_materialization_part1(JOIN_TAB *sjm_tab)
|
||||
DBUG_RETURN(FALSE);
|
||||
}
|
||||
|
||||
/**
|
||||
@retval
|
||||
FALSE ok
|
||||
TRUE error
|
||||
*/
|
||||
|
||||
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;
|
||||
THD *thd= tab->join->thd;
|
||||
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)
|
||||
{
|
||||
@ -3781,6 +3772,8 @@ bool setup_sj_materialization_part2(JOIN_TAB *sjm_tab)
|
||||
null_count ? cur_ref_buff : 0,
|
||||
cur_key_part->length, tab_ref->items[i],
|
||||
FALSE);
|
||||
if (!*ref_key)
|
||||
DBUG_RETURN(TRUE);
|
||||
cur_ref_buff+= cur_key_part->store_length;
|
||||
}
|
||||
*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++)
|
||||
{
|
||||
remove_sj_conds(thd, &tab[i].select_cond);
|
||||
if (tab[i].select)
|
||||
remove_sj_conds(thd, &tab[i].select->cond);
|
||||
if (remove_sj_conds(thd, &tab[i].select_cond) ||
|
||||
(tab[i].select && remove_sj_conds(thd, &tab[i].select->cond)))
|
||||
DBUG_RETURN(TRUE);
|
||||
}
|
||||
if (!(sjm->in_equality= create_subq_in_equalities(thd, sjm,
|
||||
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
|
||||
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();
|
||||
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++)
|
||||
@ -3972,16 +3967,20 @@ static Item *create_subq_in_equalities(THD *thd, SJ_MATERIALIZATION_INFO *sjm,
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
@retval
|
||||
0 ok
|
||||
1 error
|
||||
*/
|
||||
|
||||
|
||||
static void remove_sj_conds(THD *thd, Item **tree)
|
||||
static bool remove_sj_conds(THD *thd, Item **tree)
|
||||
{
|
||||
if (*tree)
|
||||
{
|
||||
if (is_cond_sj_in_equality(*tree))
|
||||
{
|
||||
*tree= NULL;
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
else if ((*tree)->type() == Item::COND_ITEM)
|
||||
{
|
||||
@ -3990,12 +3989,19 @@ static void remove_sj_conds(THD *thd, Item **tree)
|
||||
while ((item= li++))
|
||||
{
|
||||
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 */
|
||||
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);
|
||||
table->file= get_new_handler(share, &table->mem_root,
|
||||
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)
|
||||
goto err;
|
||||
@ -5302,6 +5308,9 @@ TABLE *create_dummy_tmp_table(THD *thd)
|
||||
sjm_table_param.field_count= 1;
|
||||
List<Item> sjm_table_cols;
|
||||
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);
|
||||
if (!(table= create_tmp_table(thd, &sjm_table_param,
|
||||
sjm_table_cols, (ORDER*) 0,
|
||||
|
@ -8481,7 +8481,8 @@ int init_ftfuncs(THD *thd, SELECT_LEX *select_lex, bool no_order)
|
||||
DBUG_PRINT("info",("Performing FULLTEXT search"));
|
||||
|
||||
while ((ifm=li++))
|
||||
ifm->init_search(thd, no_order);
|
||||
if (ifm->init_search(thd, no_order))
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -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_delete *explain=
|
||||
new (mem_root) Explain_delete(mem_root, thd->lex->analyze_stmt);
|
||||
if (!explain)
|
||||
return 0;
|
||||
|
||||
if (deleting_all_rows)
|
||||
{
|
||||
@ -71,8 +73,9 @@ Explain_delete* Delete_plan::save_explain_delete_data(MEM_ROOT *mem_root, THD *t
|
||||
else
|
||||
{
|
||||
explain->deleting_all_rows= false;
|
||||
Update_plan::save_explain_data_intern(mem_root, explain,
|
||||
thd->lex->analyze_stmt);
|
||||
if (Update_plan::save_explain_data_intern(mem_root, explain,
|
||||
thd->lex->analyze_stmt))
|
||||
return 0;
|
||||
}
|
||||
|
||||
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_update* explain=
|
||||
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);
|
||||
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,
|
||||
bool is_analyze)
|
||||
{
|
||||
@ -105,13 +111,13 @@ void Update_plan::save_explain_data_intern(MEM_ROOT *mem_root,
|
||||
if (impossible_where)
|
||||
{
|
||||
explain->impossible_where= true;
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (no_partitions)
|
||||
{
|
||||
explain->no_partitions= true;
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
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))
|
||||
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;
|
||||
error= -1;
|
||||
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;
|
||||
}
|
||||
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)
|
||||
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);
|
||||
|
||||
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)
|
||||
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())
|
||||
{
|
||||
@ -766,7 +777,8 @@ produce_explain_and_leave:
|
||||
We come here for various "degenerate" query plans: impossible WHERE,
|
||||
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:
|
||||
/*
|
||||
@ -1066,7 +1078,7 @@ multi_delete::initialize_tables(JOIN *join)
|
||||
MEM_STRIP_BUF_SIZE);
|
||||
}
|
||||
init_ftfuncs(thd, thd->lex->current_select, 1);
|
||||
DBUG_RETURN(thd->is_fatal_error != 0);
|
||||
DBUG_RETURN(thd->is_fatal_error);
|
||||
}
|
||||
|
||||
|
||||
|
@ -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;
|
||||
uint len= 0;
|
||||
for (uint i= 0; i < key->usable_key_parts; i++)
|
||||
{
|
||||
key_parts_list.append_str(mem_root,
|
||||
key->key_part[i].field->field_name.str);
|
||||
if (!key_parts_list.append_str(mem_root,
|
||||
key->key_part[i].field->field_name.str))
|
||||
return 1;
|
||||
len += key->key_part[i].store_length;
|
||||
if (len >= key_len_arg)
|
||||
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)
|
||||
{
|
||||
size_t name_len= strlen(key_name_arg);
|
||||
if ((key_name= (char*)alloc_root(root, name_len+1)))
|
||||
memcpy(key_name, key_name_arg, name_len+1);
|
||||
if (!(key_name= strdup_root(root, key_name_arg)))
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
key_name= NULL;
|
||||
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++)
|
||||
{
|
||||
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
|
||||
keys_stat_names[j]= NULL;
|
||||
}
|
||||
|
@ -589,8 +589,8 @@ public:
|
||||
key_name= NULL;
|
||||
key_len= (uint)-1;
|
||||
}
|
||||
void set(MEM_ROOT *root, KEY *key_name, uint key_len_arg);
|
||||
void set_pseudo_key(MEM_ROOT *root, const char *key_name);
|
||||
bool set(MEM_ROOT *root, KEY *key_name, uint key_len_arg);
|
||||
bool set_pseudo_key(MEM_ROOT *root, const char *key_name);
|
||||
|
||||
inline const char *get_key_name() const { return key_name; }
|
||||
inline uint get_key_len() const { return key_len; }
|
||||
|
@ -2571,10 +2571,11 @@ finish:
|
||||
BNLH, BKA or BKAH) to the data structure
|
||||
|
||||
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);
|
||||
|
||||
@ -2596,6 +2597,7 @@ void JOIN_CACHE::save_explain_data(EXPLAIN_BKA_TYPE *explain)
|
||||
default:
|
||||
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};
|
||||
int len;
|
||||
@ -2617,22 +2619,30 @@ static void add_mrr_explain_info(String *str, uint mrr_mode, handler *file)
|
||||
if (len > 0)
|
||||
{
|
||||
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)
|
||||
{
|
||||
JOIN_CACHE::save_explain_data(explain);
|
||||
add_mrr_explain_info(&explain->mrr_type, mrr_mode, join_tab->table->file);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
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);
|
||||
add_mrr_explain_info(&explain->mrr_type, mrr_mode, join_tab->table->file);
|
||||
if (JOIN_CACHE::save_explain_data(explain))
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
|
@ -662,7 +662,7 @@ public:
|
||||
enum_nested_loop_state join_records(bool skip_last);
|
||||
|
||||
/* 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();
|
||||
|
||||
@ -1340,7 +1340,7 @@ public:
|
||||
/* Check index condition of the joined table for a record from BKA cache */
|
||||
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 */
|
||||
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);
|
||||
};
|
||||
|
@ -2588,7 +2588,7 @@ public:
|
||||
|
||||
Explain_update* save_explain_update_data(MEM_ROOT *mem_root, THD *thd);
|
||||
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:
|
||||
virtual ~Update_plan() {}
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* 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
|
||||
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();
|
||||
|
||||
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->is_item_list_lookup= 1;
|
||||
@ -948,6 +948,8 @@ JOIN::prepare(TABLE_LIST *tables_init,
|
||||
(*ord->item)->field_type() == MYSQL_TYPE_BIT)
|
||||
{
|
||||
Item_field *field= new (thd->mem_root) Item_field(thd, *(Item_field**)ord->item);
|
||||
if (!field)
|
||||
DBUG_RETURN(-1);
|
||||
int el= all_fields.elements;
|
||||
ref_ptrs[el]= field;
|
||||
all_fields.push_front(field, thd->mem_root);
|
||||
@ -1080,14 +1082,16 @@ err:
|
||||
DBUG_RETURN(res); /* purecov: inspected */
|
||||
}
|
||||
|
||||
void JOIN::build_explain()
|
||||
|
||||
bool JOIN::build_explain()
|
||||
{
|
||||
create_explain_query_if_not_exists(thd->lex, thd->mem_root);
|
||||
have_query_plan= QEP_AVAILABLE;
|
||||
save_explain_data(thd->lex->explain, false /* can overwrite */,
|
||||
need_tmp,
|
||||
!skip_sort_order && !no_order && (order || group_list),
|
||||
select_distinct);
|
||||
if (save_explain_data(thd->lex->explain, false /* can overwrite */,
|
||||
need_tmp,
|
||||
!skip_sort_order && !no_order && (order || group_list),
|
||||
select_distinct))
|
||||
return 1;
|
||||
uint select_nr= select_lex->select_number;
|
||||
JOIN_TAB *curr_tab= join_tab + exec_join_tab_cnt();
|
||||
for (uint i= 0; i < aggr_tables; i++, curr_tab++)
|
||||
@ -1105,8 +1109,10 @@ void JOIN::build_explain()
|
||||
get_using_temporary_read_tracker();
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int JOIN::optimize()
|
||||
{
|
||||
int res= 0;
|
||||
@ -1126,7 +1132,7 @@ int JOIN::optimize()
|
||||
init_state == JOIN::OPTIMIZATION_PHASE_1_DONE)
|
||||
{
|
||||
if (!res && have_query_plan != QEP_DELETED)
|
||||
build_explain();
|
||||
res= build_explain();
|
||||
optimization_state= JOIN::OPTIMIZATION_DONE;
|
||||
}
|
||||
return res;
|
||||
@ -1720,6 +1726,9 @@ int JOIN::optimize_stage2()
|
||||
{
|
||||
ref_item= substitute_for_best_equal_field(thd, tab, ref_item,
|
||||
equals, map2table);
|
||||
if (thd->is_fatal_error)
|
||||
DBUG_RETURN(1);
|
||||
|
||||
if (first_inner)
|
||||
{
|
||||
equals= first_inner->cond_equal;
|
||||
@ -2032,7 +2041,8 @@ int JOIN::optimize_stage2()
|
||||
|
||||
/* Perform FULLTEXT search before all regular searches */
|
||||
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
|
||||
@ -2419,7 +2429,8 @@ bool JOIN::make_aggr_tables_info()
|
||||
|
||||
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
|
||||
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->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,
|
||||
all_fields,
|
||||
NULL, query.distinct,
|
||||
@ -2446,7 +2458,8 @@ bool JOIN::make_aggr_tables_info()
|
||||
if (!table)
|
||||
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->table= table;
|
||||
/*
|
||||
@ -2886,7 +2899,8 @@ bool JOIN::make_aggr_tables_info()
|
||||
curr_tab= join_tab + exec_join_tab_cnt() + aggr_tables - 1;
|
||||
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,
|
||||
curr_tab))
|
||||
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_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;
|
||||
TABLE* table= create_tmp_table(thd, tab->tmp_table_param, *table_fields,
|
||||
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);
|
||||
if (tab > join_tab)
|
||||
(tab - 1)->next_select= sub_select_postjoin_aggr;
|
||||
tab->aggr= new (thd->mem_root) AGGR_OP(tab);
|
||||
if (!tab->aggr)
|
||||
if (!(tab->aggr= new (thd->mem_root) AGGR_OP(tab)))
|
||||
goto err;
|
||||
tab->table= table;
|
||||
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[NO_MATTER])
|
||||
{
|
||||
if (conds)
|
||||
conds= conds->transform(thd, &Item::expr_cache_insert_transformer,
|
||||
NULL);
|
||||
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);
|
||||
tab; tab= next_linear_tab(this, tab, WITH_BUSH_ROOTS))
|
||||
{
|
||||
if (tab->select_cond)
|
||||
tab->select_cond=
|
||||
tab->select_cond->transform(thd, &Item::expr_cache_insert_transformer,
|
||||
NULL);
|
||||
if (tab->select_cond &&
|
||||
!(tab->select_cond=
|
||||
tab->select_cond->transform(thd,
|
||||
&Item::expr_cache_insert_transformer,
|
||||
NULL)))
|
||||
DBUG_RETURN(TRUE);
|
||||
if (tab->cache_select && tab->cache_select->cond)
|
||||
tab->cache_select->cond=
|
||||
tab->cache_select->
|
||||
cond->transform(thd, &Item::expr_cache_insert_transformer,
|
||||
NULL);
|
||||
|
||||
if (!(tab->cache_select->cond=
|
||||
tab->cache_select->
|
||||
cond->transform(thd, &Item::expr_cache_insert_transformer,
|
||||
NULL)))
|
||||
DBUG_RETURN(TRUE);
|
||||
}
|
||||
|
||||
if (having)
|
||||
having= having->transform(thd, &Item::expr_cache_insert_transformer,
|
||||
NULL);
|
||||
if (having &&
|
||||
!(having= having->transform(thd,
|
||||
&Item::expr_cache_insert_transformer,
|
||||
NULL)))
|
||||
DBUG_RETURN(TRUE);
|
||||
|
||||
if (tmp_having)
|
||||
{
|
||||
DBUG_ASSERT(having == NULL);
|
||||
tmp_having= tmp_having->transform(thd, &Item::expr_cache_insert_transformer,
|
||||
NULL);
|
||||
if (!(tmp_having=
|
||||
tmp_having->transform(thd,
|
||||
&Item::expr_cache_insert_transformer,
|
||||
NULL)))
|
||||
DBUG_RETURN(TRUE);
|
||||
}
|
||||
}
|
||||
if (select_lex->expr_cache_may_be_used[SELECT_LIST] ||
|
||||
@ -3130,9 +3153,11 @@ bool JOIN::setup_subquery_caches()
|
||||
Item *item;
|
||||
while ((item= li++))
|
||||
{
|
||||
Item *new_item=
|
||||
item->transform(thd, &Item::expr_cache_insert_transformer,
|
||||
NULL);
|
||||
Item *new_item;
|
||||
if (!(new_item=
|
||||
item->transform(thd, &Item::expr_cache_insert_transformer,
|
||||
NULL)))
|
||||
DBUG_RETURN(TRUE);
|
||||
if (new_item != 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)
|
||||
{
|
||||
*tmp_group->item=
|
||||
(*tmp_group->item)->transform(thd, &Item::expr_cache_insert_transformer,
|
||||
NULL);
|
||||
if (!(*tmp_group->item=
|
||||
(*tmp_group->item)->transform(thd,
|
||||
&Item::expr_cache_insert_transformer,
|
||||
NULL)))
|
||||
DBUG_RETURN(TRUE);
|
||||
}
|
||||
}
|
||||
if (select_lex->expr_cache_may_be_used[NO_MATTER])
|
||||
{
|
||||
for (ORDER *ord= order; ord; ord= ord->next)
|
||||
{
|
||||
*ord->item=
|
||||
(*ord->item)->transform(thd, &Item::expr_cache_insert_transformer,
|
||||
NULL);
|
||||
if (!(*ord->item=
|
||||
(*ord->item)->transform(thd,
|
||||
&Item::expr_cache_insert_transformer,
|
||||
NULL)))
|
||||
DBUG_RETURN(TRUE);
|
||||
}
|
||||
}
|
||||
DBUG_RETURN(FALSE);
|
||||
@ -3276,7 +3305,8 @@ JOIN::reinit()
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
@ -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 distinct)
|
||||
{
|
||||
@ -3337,9 +3374,8 @@ void JOIN::save_explain_data(Explain_query *output, bool can_overwrite,
|
||||
/* It's a degenerate join */
|
||||
message= zero_result_cause ? zero_result_cause : "No tables used";
|
||||
}
|
||||
save_explain_data_intern(thd->lex->explain, need_tmp_table, need_order,
|
||||
distinct, message);
|
||||
return;
|
||||
return save_explain_data_intern(thd->lex->explain, need_tmp_table, need_order,
|
||||
distinct, message);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -3359,11 +3395,13 @@ void JOIN::save_explain_data(Explain_query *output, bool can_overwrite,
|
||||
{
|
||||
if (join_tab[i].filesort)
|
||||
{
|
||||
join_tab[i].filesort->tracker=
|
||||
new Filesort_tracker(thd->lex->analyze_stmt);
|
||||
if (!(join_tab[i].filesort->tracker=
|
||||
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 */
|
||||
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;
|
||||
}
|
||||
@ -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
|
||||
the arguments of AND/OR items only
|
||||
*/
|
||||
if (new_item != item)
|
||||
if (new_item && new_item != 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++))
|
||||
{
|
||||
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;
|
||||
}
|
||||
@ -14658,6 +14699,7 @@ change_cond_ref_to_const(THD *thd, I_List<COND_CMP> *save_list,
|
||||
{
|
||||
cond->marker=1;
|
||||
COND_CMP *tmp2;
|
||||
/* Will work, even if malloc would fail */
|
||||
if ((tmp2= new (thd->mem_root) COND_CMP(and_father, func)))
|
||||
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);
|
||||
cond->marker=1;
|
||||
COND_CMP *tmp2;
|
||||
/* Will work, even if malloc would fail */
|
||||
if ((tmp2=new (thd->mem_root) COND_CMP(and_father, func)))
|
||||
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);
|
||||
#endif
|
||||
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],
|
||||
new (thd->mem_root) Item_int(thd, "last_insert_id()",
|
||||
thd->read_first_successful_insert_id_in_prev_stmt(),
|
||||
@ -16958,7 +17002,8 @@ create_tmp_table(THD *thd, TMP_TABLE_PARAM *param, List<Item> &fields,
|
||||
Item *arg= sum_item->get_arg(i);
|
||||
if (!arg->const_item())
|
||||
{
|
||||
Field *new_field=
|
||||
Item *tmp_item;
|
||||
Field *new_field=
|
||||
create_tmp_field(thd, table, arg, arg->type(), ©_func,
|
||||
tmp_from_field, &default_field[fieldnr],
|
||||
group != 0,not_all_columns,
|
||||
@ -16983,7 +17028,10 @@ create_tmp_table(THD *thd, TMP_TABLE_PARAM *param, List<Item> &fields,
|
||||
string_total_length+= new_field->pack_length();
|
||||
}
|
||||
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;
|
||||
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
|
||||
optimize away 'order by'.
|
||||
|
||||
@retval
|
||||
0 OOM error if thd->is_fatal_error is set. Otherwise group was eliminated
|
||||
# Pointer to new group
|
||||
*/
|
||||
|
||||
ORDER *
|
||||
@ -22921,6 +22973,8 @@ create_distinct_group(THD *thd, Ref_ptr_array ref_pointer_array,
|
||||
BIT type and will be returned [el]client.
|
||||
*/
|
||||
Item_field *new_item= new (thd->mem_root) Item_field(thd, (Item_field*)item);
|
||||
if (!new_item)
|
||||
return 0;
|
||||
int el= all_fields.elements;
|
||||
orig_ref_pointer_array[el]= new_item;
|
||||
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)
|
||||
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 &&
|
||||
((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())
|
||||
new_item= item;
|
||||
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)]=
|
||||
new_item;
|
||||
}
|
||||
@ -24077,7 +24139,9 @@ bool JOIN::rollup_init()
|
||||
*/
|
||||
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];
|
||||
rollup_fields->empty();
|
||||
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
|
||||
|
||||
@retval
|
||||
0 ok
|
||||
1 OOM error or error from send_data()
|
||||
*/
|
||||
|
||||
int print_explain_message_line(select_result_sink *result,
|
||||
@ -24481,7 +24549,7 @@ int print_explain_message_line(select_result_sink *result,
|
||||
else
|
||||
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 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++)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
void JOIN_TAB::save_explain_data(Explain_table_access *eta,
|
||||
bool JOIN_TAB::save_explain_data(Explain_table_access *eta,
|
||||
table_map prefix_tables,
|
||||
bool distinct_arg, JOIN_TAB *first_top_tab)
|
||||
{
|
||||
@ -24550,9 +24619,11 @@ void JOIN_TAB::save_explain_data(Explain_table_access *eta,
|
||||
|
||||
if (filesort)
|
||||
{
|
||||
eta->pre_join_sort= new Explain_aggr_filesort(thd->mem_root,
|
||||
thd->lex->analyze_stmt,
|
||||
filesort);
|
||||
if (!(eta->pre_join_sort=
|
||||
new Explain_aggr_filesort(thd->mem_root,
|
||||
thd->lex->analyze_stmt,
|
||||
filesort)))
|
||||
return 1;
|
||||
}
|
||||
|
||||
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
|
||||
// break ANALYZE ? thd->mem_root will be freed, and after that we will
|
||||
// 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
|
||||
|
||||
/* 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)
|
||||
{
|
||||
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 */
|
||||
@ -24683,10 +24756,14 @@ void JOIN_TAB::save_explain_data(Explain_table_access *eta,
|
||||
for (uint kp= 0; kp < ref.key_parts; kp++)
|
||||
{
|
||||
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
|
||||
{
|
||||
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++;
|
||||
}
|
||||
}
|
||||
@ -24943,7 +25020,8 @@ void JOIN_TAB::save_explain_data(Explain_table_access *eta,
|
||||
if (cache)
|
||||
{
|
||||
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 */
|
||||
eta->non_merged_sjm_number = get_non_merged_semijoin_select();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Walk through join->aggr_tables and save aggregation/grouping query plan into
|
||||
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();
|
||||
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
|
||||
prev_node= node;
|
||||
node= new Explain_aggr_tmp_table;
|
||||
if (!(node= new Explain_aggr_tmp_table))
|
||||
return 1;
|
||||
node->child= prev_node;
|
||||
|
||||
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=
|
||||
join_tab->window_funcs_step->save_explain_plan(thd->mem_root,
|
||||
is_analyze);
|
||||
if (new_node)
|
||||
{
|
||||
prev_node=node;
|
||||
node= new_node;
|
||||
node->child= prev_node;
|
||||
}
|
||||
if (!new_node)
|
||||
return 1;
|
||||
|
||||
prev_node=node;
|
||||
node= new_node;
|
||||
node->child= prev_node;
|
||||
}
|
||||
|
||||
/* The below matches execution in join_init_read_record() */
|
||||
if (join_tab->distinct)
|
||||
{
|
||||
prev_node= node;
|
||||
node= new Explain_aggr_remove_dups;
|
||||
if (!(node= new Explain_aggr_remove_dups))
|
||||
return 1;
|
||||
node->child= prev_node;
|
||||
}
|
||||
|
||||
@ -25004,20 +25090,27 @@ void save_agg_explain_data(JOIN *join, Explain_select *xpl_sel)
|
||||
{
|
||||
Explain_aggr_filesort *eaf =
|
||||
new Explain_aggr_filesort(thd->mem_root, is_analyze, join_tab->filesort);
|
||||
if (!eaf)
|
||||
return 1;
|
||||
prev_node= node;
|
||||
node= eaf;
|
||||
node->child= prev_node;
|
||||
}
|
||||
}
|
||||
xpl_sel->aggr_tree= node;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
/**
|
||||
Save Query Plan Footprint
|
||||
|
||||
@note
|
||||
Currently, this function may be called multiple times
|
||||
|
||||
@retval
|
||||
0 ok
|
||||
1 error
|
||||
*/
|
||||
|
||||
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)
|
||||
{
|
||||
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_PRINT("info", ("Select %p, type %s, message %s",
|
||||
join->select_lex, join->select_lex->type,
|
||||
@ -25044,8 +25136,11 @@ int JOIN::save_explain_data_intern(Explain_query *output,
|
||||
|
||||
if (message)
|
||||
{
|
||||
explain= new (output->mem_root) Explain_select(output->mem_root,
|
||||
thd->lex->analyze_stmt);
|
||||
if (!(explain= new (output->mem_root)
|
||||
Explain_select(output->mem_root,
|
||||
thd->lex->analyze_stmt)))
|
||||
DBUG_RETURN(1);
|
||||
|
||||
join->select_lex->set_explain_type(true);
|
||||
|
||||
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)
|
||||
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);
|
||||
}
|
||||
else if (pushdown_query)
|
||||
{
|
||||
explain= new (output->mem_root) Explain_select(output->mem_root,
|
||||
thd->lex->analyze_stmt);
|
||||
if (!(explain= new (output->mem_root)
|
||||
Explain_select(output->mem_root,
|
||||
thd->lex->analyze_stmt)))
|
||||
DBUG_RETURN(1);
|
||||
select_lex->set_explain_type(true);
|
||||
|
||||
explain->select_id= select_lex->select_number;
|
||||
@ -25084,6 +25183,9 @@ int JOIN::save_explain_data_intern(Explain_query *output,
|
||||
explain= xpl_sel=
|
||||
new (output->mem_root) Explain_select(output->mem_root,
|
||||
thd->lex->analyze_stmt);
|
||||
if (!explain)
|
||||
DBUG_RETURN(1);
|
||||
|
||||
table_map used_tables=0;
|
||||
|
||||
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)
|
||||
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->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(output->mem_root));
|
||||
|
||||
if (!eta)
|
||||
DBUG_RETURN(1);
|
||||
if (tab->bush_root_tab != prev_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.
|
||||
*/
|
||||
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;
|
||||
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;
|
||||
|
||||
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)
|
||||
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();
|
||||
|
||||
DBUG_RETURN(cur_error);
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
|
||||
|
@ -608,7 +608,7 @@ typedef struct st_join_table {
|
||||
|
||||
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 use_order() const; ///< Use ordering provided by chosen index?
|
||||
@ -1526,7 +1526,7 @@ public:
|
||||
int optimize();
|
||||
int optimize_inner();
|
||||
int optimize_stage2();
|
||||
void build_explain();
|
||||
bool build_explain();
|
||||
int reinit();
|
||||
int init_execution();
|
||||
void exec();
|
||||
@ -1667,7 +1667,7 @@ public:
|
||||
{
|
||||
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);
|
||||
int save_explain_data_intern(Explain_query *output, bool need_tmp_table,
|
||||
bool need_order, bool distinct,
|
||||
|
@ -181,6 +181,8 @@ public:
|
||||
}
|
||||
static void *operator new(size_t size, MEM_ROOT *mem_root) throw ()
|
||||
{ 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)
|
||||
{
|
||||
(void) ptr_arg;
|
||||
@ -189,6 +191,10 @@ public:
|
||||
}
|
||||
static void operator delete(void *, MEM_ROOT *)
|
||||
{ /* 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(); }
|
||||
|
||||
/* Mark variable thread specific it it's not allocated already */
|
||||
|
@ -9697,7 +9697,7 @@ copy_data_between_tables(THD *thd, TABLE *from, TABLE *to,
|
||||
if (mysql_trans_prepare_alter_copy_data(thd))
|
||||
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 */
|
||||
|
||||
/* We need external lock before we can disable/enable keys */
|
||||
|
@ -283,6 +283,9 @@ int table_value_constr::save_explain_data_intern(THD *thd,
|
||||
|
||||
explain= new (output->mem_root) Explain_select(output->mem_root,
|
||||
thd->lex->analyze_stmt);
|
||||
if (!explain)
|
||||
DBUG_RETURN(1);
|
||||
|
||||
select_lex->set_explain_type(true);
|
||||
|
||||
explain->select_id= select_lex->select_number;
|
||||
@ -309,7 +312,7 @@ int table_value_constr::save_explain_data_intern(THD *thd,
|
||||
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);
|
||||
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->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;
|
||||
}
|
||||
|
||||
|
||||
|
@ -57,7 +57,7 @@ public:
|
||||
|
||||
int save_explain_data_intern(THD *thd_arg,
|
||||
Explain_query *output);
|
||||
void optimize(THD *thd_arg);
|
||||
bool optimize(THD *thd_arg);
|
||||
bool exec(SELECT_LEX *sl);
|
||||
|
||||
void print(THD *thd_arg, String *str, enum_query_type query_type);
|
||||
|
@ -1282,7 +1282,11 @@ bool st_select_lex_unit::optimize()
|
||||
sl->tvc->select_options=
|
||||
(select_limit_cnt == HA_POS_ERROR || sl->braces) ?
|
||||
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;
|
||||
}
|
||||
thd->lex->current_select= sl;
|
||||
@ -1397,7 +1401,7 @@ bool st_select_lex_unit::exec()
|
||||
sl->tvc->select_options=
|
||||
(select_limit_cnt == HA_POS_ERROR || sl->braces) ?
|
||||
sl->options & ~OPTION_FOUND_ROWS : sl->options | found_rows_for_union;
|
||||
sl->tvc->optimize(thd);
|
||||
saved_error= sl->tvc->optimize(thd);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -451,7 +451,8 @@ int mysql_update(THD *thd,
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
init_ftfuncs(thd, select_lex, 1);
|
||||
if (init_ftfuncs(thd, select_lex, 1))
|
||||
goto err;
|
||||
|
||||
table->mark_columns_needed_for_update();
|
||||
|
||||
@ -522,7 +523,8 @@ int mysql_update(THD *thd,
|
||||
*/
|
||||
if (thd->lex->describe)
|
||||
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);
|
||||
|
||||
@ -1046,7 +1048,8 @@ produce_explain_and_leave:
|
||||
We come here for various "degenerate" query plans: impossible WHERE,
|
||||
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:
|
||||
int err2= thd->lex->explain->send_explain(thd);
|
||||
@ -1776,7 +1779,7 @@ int multi_update::prepare(List<Item> ¬_used_values,
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -3093,10 +3093,14 @@ Window_funcs_computation::save_explain_plan(MEM_ROOT *mem_root,
|
||||
Explain_aggr_window_funcs *xpl= new Explain_aggr_window_funcs;
|
||||
List_iterator<Window_funcs_sort> it(win_func_sorts);
|
||||
Window_funcs_sort *srt;
|
||||
if (!xpl)
|
||||
return 0;
|
||||
while ((srt = it++))
|
||||
{
|
||||
Explain_aggr_filesort *eaf=
|
||||
new Explain_aggr_filesort(mem_root, is_analyze, srt->filesort);
|
||||
if (!eaf)
|
||||
return 0;
|
||||
xpl->sorts.push_back(eaf, mem_root);
|
||||
}
|
||||
return xpl;
|
||||
|
@ -4290,9 +4290,9 @@ int ha_mroonga::storage_open_columns(void)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user