summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sql/item.cc9
-rw-r--r--sql/item_func.cc51
-rw-r--r--sql/item_func.h2
-rw-r--r--sql/opt_subselect.cc85
-rw-r--r--sql/sql_base.cc3
-rw-r--r--sql/sql_delete.cc36
-rw-r--r--sql/sql_explain.cc27
-rw-r--r--sql/sql_explain.h4
-rw-r--r--sql/sql_join_cache.cc32
-rw-r--r--sql/sql_join_cache.h6
-rw-r--r--sql/sql_lex.h2
-rw-r--r--sql/sql_select.cc290
-rw-r--r--sql/sql_select.h6
-rw-r--r--sql/sql_string.h6
-rw-r--r--sql/sql_table.cc2
-rw-r--r--sql/sql_tvc.cc8
-rw-r--r--sql/sql_tvc.h2
-rw-r--r--sql/sql_union.cc8
-rw-r--r--sql/sql_update.cc11
-rw-r--r--sql/sql_window.cc4
-rw-r--r--storage/mroonga/ha_mroonga.cpp4
21 files changed, 391 insertions, 207 deletions
diff --git a/sql/item.cc b/sql/item.cc
index 2285ae28041..fb620aa84d9 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -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)
{
/*
diff --git a/sql/item_func.cc b/sql/item_func.cc
index 0d32fdf1824..659ec29e452 100644
--- a/sql/item_func.cc
+++ b/sql/item_func.cc
@@ -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);
}
diff --git a/sql/item_func.h b/sql/item_func.h
index 3ba2ebf9d86..c3a717614fb 100644
--- a/sql/item_func.h
+++ b/sql/item_func.h
@@ -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);
diff --git a/sql/opt_subselect.cc b/sql/opt_subselect.cc
index b6378685268..72da68816ad 100644
--- a/sql/opt_subselect.cc
+++ b/sql/opt_subselect.cc
@@ -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,
diff --git a/sql/sql_base.cc b/sql/sql_base.cc
index 7fd6599df51..0a84dc2b351 100644
--- a/sql/sql_base.cc
+++ b/sql/sql_base.cc
@@ -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;
}
diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc
index d0fc422c2f9..0d4bed836b8 100644
--- a/sql/sql_delete.cc
+++ b/sql/sql_delete.cc
@@ -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);
}
diff --git a/sql/sql_explain.cc b/sql/sql_explain.cc
index 05df9a21572..660d68427d1 100644
--- a/sql/sql_explain.cc
+++ b/sql/sql_explain.cc
@@ -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;
}
diff --git a/sql/sql_explain.h b/sql/sql_explain.h
index 154769fe289..895c059f1b0 100644
--- a/sql/sql_explain.h
+++ b/sql/sql_explain.h
@@ -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; }
diff --git a/sql/sql_join_cache.cc b/sql/sql_join_cache.cc
index 2f1a81cc2ec..6df92f13585 100644
--- a/sql/sql_join_cache.cc
+++ b/sql/sql_join_cache.cc
@@ -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;
}
+ return 0;
}
-void JOIN_CACHE_BKA::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);
}
-void JOIN_CACHE_BKAH::save_explain_data(EXPLAIN_BKA_TYPE *explain)
+bool JOIN_CACHE_BKAH::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);
}
diff --git a/sql/sql_join_cache.h b/sql/sql_join_cache.h
index 4ae843ebfc2..f6894c6727d 100644
--- a/sql/sql_join_cache.h
+++ b/sql/sql_join_cache.h
@@ -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);
};
diff --git a/sql/sql_lex.h b/sql/sql_lex.h
index 3cec59193ff..d4e438ab98c 100644
--- a/sql/sql_lex.h
+++ b/sql/sql_lex.h
@@ -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() {}
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index abbf2616537..28600088153 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -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(), &copy_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);
}
diff --git a/sql/sql_select.h b/sql/sql_select.h
index cc52cae02da..c1e5a9f95ce 100644
--- a/sql/sql_select.h
+++ b/sql/sql_select.h
@@ -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,
diff --git a/sql/sql_string.h b/sql/sql_string.h
index c88c58b1b40..41d31dc33c2 100644
--- a/sql/sql_string.h
+++ b/sql/sql_string.h
@@ -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 */
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 58a6666b219..b021844427c 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -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 */
diff --git a/sql/sql_tvc.cc b/sql/sql_tvc.cc
index 8c8e132746e..79e894f5a7f 100644
--- a/sql/sql_tvc.cc
+++ b/sql/sql_tvc.cc
@@ -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;
}
diff --git a/sql/sql_tvc.h b/sql/sql_tvc.h
index b4fca78262b..7861f6fd16b 100644
--- a/sql/sql_tvc.h
+++ b/sql/sql_tvc.h
@@ -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);
diff --git a/sql/sql_union.cc b/sql/sql_union.cc
index 8cce7f33057..40f4f984e0a 100644
--- a/sql/sql_union.cc
+++ b/sql/sql_union.cc
@@ -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
{
diff --git a/sql/sql_update.cc b/sql/sql_update.cc
index 47ec8b89d48..bd577426483 100644
--- a/sql/sql_update.cc
+++ b/sql/sql_update.cc
@@ -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> &not_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);
}
diff --git a/sql/sql_window.cc b/sql/sql_window.cc
index 4bcdca3ca11..bf393ab1c4d 100644
--- a/sql/sql_window.cc
+++ b/sql/sql_window.cc
@@ -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;
diff --git a/storage/mroonga/ha_mroonga.cpp b/storage/mroonga/ha_mroonga.cpp
index 963f657d735..96fe2b05ee7 100644
--- a/storage/mroonga/ha_mroonga.cpp
+++ b/storage/mroonga/ha_mroonga.cpp
@@ -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);
}