From b22959903b89e798f8804ec9a815c88f75915cd9 Mon Sep 17 00:00:00 2001 From: Sergey Vojtovich Date: Wed, 22 Apr 2015 13:29:56 +0400 Subject: MDEV-7943 - pthread_getspecific() takes 0.76% in OLTP RO Added THD argument to select_result and all derivative classes. This reduces number of pthread_getspecific calls from 796 to 776 per OLTP RO transaction. --- sql/item_subselect.cc | 32 +++++++++++++----------- sql/item_subselect.h | 11 +++++---- sql/opt_subselect.cc | 7 +++--- sql/sp_head.cc | 2 +- sql/sp_rcontext.cc | 9 ++++--- sql/sp_rcontext.h | 6 ++--- sql/sql_class.cc | 11 --------- sql/sql_class.h | 67 ++++++++++++++++++++++++++++++--------------------- sql/sql_cursor.cc | 6 ++--- sql/sql_delete.cc | 4 +-- sql/sql_derived.cc | 2 +- sql/sql_explain.cc | 2 +- sql/sql_insert.cc | 12 +++++---- sql/sql_parse.cc | 57 +++++++++++++++++++++++-------------------- sql/sql_prepare.cc | 8 +++--- sql/sql_union.cc | 7 ++++-- sql/sql_update.cc | 9 ++++--- sql/sql_yacc.yy | 24 ++++++++++-------- 18 files changed, 149 insertions(+), 127 deletions(-) diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index b8a829a500f..be8a878aa00 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -922,11 +922,12 @@ void Item_subselect::print(String *str, enum_query_type query_type) } -Item_singlerow_subselect::Item_singlerow_subselect(st_select_lex *select_lex) +Item_singlerow_subselect::Item_singlerow_subselect(THD *thd_arg, st_select_lex *select_lex) :Item_subselect(), value(0) { DBUG_ENTER("Item_singlerow_subselect::Item_singlerow_subselect"); - init(select_lex, new select_singlerow_subselect(this)); + init(select_lex, new (thd_arg->mem_root) select_singlerow_subselect(thd_arg, + this)); maybe_null= 1; max_columns= UINT_MAX; DBUG_VOID_RETURN; @@ -961,9 +962,8 @@ Item_maxmin_subselect::Item_maxmin_subselect(THD *thd_param, DBUG_ENTER("Item_maxmin_subselect::Item_maxmin_subselect"); max= max_arg; init(select_lex, - new select_max_min_finder_subselect(this, max_arg, - parent->substype() == - Item_subselect::ALL_SUBS)); + new (thd_param->mem_root) select_max_min_finder_subselect(thd_param, + this, max_arg, parent->substype() == Item_subselect::ALL_SUBS)); max_columns= 1; maybe_null= 1; max_columns= 1; @@ -1345,12 +1345,13 @@ bool Item_singlerow_subselect::get_date(MYSQL_TIME *ltime,ulonglong fuzzydate) } -Item_exists_subselect::Item_exists_subselect(st_select_lex *select_lex): +Item_exists_subselect::Item_exists_subselect(THD *thd_arg, + st_select_lex *select_lex): Item_subselect(), upper_not(NULL), abort_on_null(0), emb_on_expr_nest(NULL), optimizer(0), exists_transformed(0) { DBUG_ENTER("Item_exists_subselect::Item_exists_subselect"); - init(select_lex, new select_exists_subselect(this)); + init(select_lex, new (thd_arg->mem_root) select_exists_subselect(thd_arg, this)); max_columns= UINT_MAX; null_value= FALSE; //can't be NULL maybe_null= 0; //can't be NULL @@ -1381,7 +1382,7 @@ bool Item_in_subselect::test_limit(st_select_lex_unit *unit_arg) return(0); } -Item_in_subselect::Item_in_subselect(Item * left_exp, +Item_in_subselect::Item_in_subselect(THD *thd_arg, Item * left_exp, st_select_lex *select_lex): Item_exists_subselect(), left_expr_cache(0), first_execution(TRUE), in_strategy(SUBS_NOT_TRANSFORMED), @@ -1393,7 +1394,8 @@ Item_in_subselect::Item_in_subselect(Item * left_exp, DBUG_PRINT("info", ("in_strategy: %u", (uint)in_strategy)); left_expr= left_exp; func= &eq_creator; - init(select_lex, new select_exists_subselect(this)); + init(select_lex, new (thd_arg->mem_root) select_exists_subselect(thd_arg, + this)); max_columns= UINT_MAX; maybe_null= 1; reset(); @@ -1407,7 +1409,7 @@ int Item_in_subselect::get_identifier() return engine->get_identifier(); } -Item_allany_subselect::Item_allany_subselect(Item * left_exp, +Item_allany_subselect::Item_allany_subselect(THD *thd_arg, Item * left_exp, chooser_compare_func_creator fc, st_select_lex *select_lex, bool all_arg) @@ -1416,7 +1418,8 @@ Item_allany_subselect::Item_allany_subselect(Item * left_exp, DBUG_ENTER("Item_allany_subselect::Item_allany_subselect"); left_expr= left_exp; func= func_creator(all_arg); - init(select_lex, new select_exists_subselect(this)); + init(select_lex, new (thd_arg->mem_root) select_exists_subselect(thd_arg, + this)); max_columns= 1; abort_on_null= 0; reset(); @@ -1921,7 +1924,7 @@ bool Item_allany_subselect::transform_into_max_min(JOIN *join) 0); if (join->prepare_stage2()) DBUG_RETURN(true); - subs= new Item_singlerow_subselect(select_lex); + subs= new (thd->mem_root) Item_singlerow_subselect(thd, select_lex); /* Remove other strategies if any (we already changed the query and @@ -2846,7 +2849,8 @@ bool Item_exists_subselect::exists2in_processor(uchar *opt_arg) set_exists_transformed(); first_select->select_limit= NULL; - if (!(in_subs= new Item_in_subselect(left_exp, first_select))) + if (!(in_subs= new (thd->mem_root) Item_in_subselect(thd, left_exp, + first_select))) { res= TRUE; goto out; @@ -4774,7 +4778,7 @@ bool subselect_hash_sj_engine::init(List *tmp_columns, uint subquery_id) DBUG_RETURN(TRUE); } */ - if (!(result_sink= new select_materialize_with_stats)) + if (!(result_sink= new (thd->mem_root) select_materialize_with_stats(thd))) DBUG_RETURN(TRUE); char buf[32]; diff --git a/sql/item_subselect.h b/sql/item_subselect.h index 47a143e172a..6628a1bf86b 100644 --- a/sql/item_subselect.h +++ b/sql/item_subselect.h @@ -265,7 +265,7 @@ class Item_singlerow_subselect :public Item_subselect protected: Item_cache *value, **row; public: - Item_singlerow_subselect(st_select_lex *select_lex); + Item_singlerow_subselect(THD *thd_arg, st_select_lex *select_lex); Item_singlerow_subselect() :Item_subselect(), value(0), row (0) {} @@ -360,7 +360,7 @@ public: /* true if we got this from EXISTS or to IN */ bool exists_transformed; - Item_exists_subselect(st_select_lex *select_lex); + Item_exists_subselect(THD *thd_arg, st_select_lex *select_lex); Item_exists_subselect() :Item_subselect(), upper_not(NULL),abort_on_null(0), emb_on_expr_nest(NULL), optimizer(0), exists_transformed(0) @@ -566,7 +566,7 @@ public: Item_func_not_all *upper_item; // point on NOT/NOP before ALL/SOME subquery - Item_in_subselect(Item * left_expr, st_select_lex *select_lex); + Item_in_subselect(THD *thd_arg, Item * left_expr, st_select_lex *select_lex); Item_in_subselect() :Item_exists_subselect(), left_expr_cache(0), first_execution(TRUE), in_strategy(SUBS_NOT_TRANSFORMED), @@ -708,7 +708,8 @@ public: chooser_compare_func_creator func_creator; bool all; - Item_allany_subselect(Item * left_expr, chooser_compare_func_creator fc, + Item_allany_subselect(THD *thd_arg, Item * left_expr, + chooser_compare_func_creator fc, st_select_lex *select_lex, bool all); void cleanup(); @@ -982,7 +983,7 @@ public: This function is actually defined in sql_parse.cc, but it depends on chooser_compare_func_creator defined in this file. */ -Item * all_any_subquery_creator(Item *left_expr, +Item * all_any_subquery_creator(THD *thd, Item *left_expr, chooser_compare_func_creator cmp, bool all, SELECT_LEX *select_lex); diff --git a/sql/opt_subselect.cc b/sql/opt_subselect.cc index 9804254b35f..167194df785 100644 --- a/sql/opt_subselect.cc +++ b/sql/opt_subselect.cc @@ -5104,8 +5104,8 @@ TABLE *create_dummy_tmp_table(THD *thd) class select_value_catcher :public select_subselect { public: - select_value_catcher(Item_subselect *item_arg) - :select_subselect(item_arg) + select_value_catcher(THD *thd_arg, Item_subselect *item_arg): + select_subselect(thd_arg, item_arg) {} int send_data(List &items); int setup(List *items); @@ -5216,7 +5216,8 @@ bool setup_jtbm_semi_joins(JOIN *join, List *join_list, subselect_single_select_engine *engine= (subselect_single_select_engine*)subq_pred->engine; select_value_catcher *new_sink; - if (!(new_sink= new select_value_catcher(subq_pred))) + if (!(new_sink= + new (join->thd->mem_root) select_value_catcher(join->thd, subq_pred))) DBUG_RETURN(TRUE); if (new_sink->setup(&engine->select_lex->join->fields_list) || engine->select_lex->join->change_result(new_sink, NULL) || diff --git a/sql/sp_head.cc b/sql/sp_head.cc index 8efeeab01ec..a039543c33c 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -3613,7 +3613,7 @@ sp_instr_cpush::execute(THD *thd, uint *nextp) { DBUG_ENTER("sp_instr_cpush::execute"); - int ret= thd->spcont->push_cursor(&m_lex_keeper, this); + int ret= thd->spcont->push_cursor(thd, &m_lex_keeper, this); *nextp= m_ip+1; diff --git a/sql/sp_rcontext.cc b/sql/sp_rcontext.cc index a5a6a61f73c..08aedc3b780 100644 --- a/sql/sp_rcontext.cc +++ b/sql/sp_rcontext.cc @@ -155,14 +155,14 @@ bool sp_rcontext::set_return_value(THD *thd, Item **return_value_item) } -bool sp_rcontext::push_cursor(sp_lex_keeper *lex_keeper, +bool sp_rcontext::push_cursor(THD *thd, sp_lex_keeper *lex_keeper, sp_instr_cpush *i) { /* We should create cursors in the callers arena, as it could be (and usually is) used in several instructions. */ - sp_cursor *c= new (callers_arena->mem_root) sp_cursor(lex_keeper, i); + sp_cursor *c= new (callers_arena->mem_root) sp_cursor(thd, lex_keeper, i); if (c == NULL) return true; @@ -421,8 +421,9 @@ bool sp_rcontext::set_case_expr(THD *thd, int case_expr_id, /////////////////////////////////////////////////////////////////////////// -sp_cursor::sp_cursor(sp_lex_keeper *lex_keeper, sp_instr_cpush *i) - :m_lex_keeper(lex_keeper), +sp_cursor::sp_cursor(THD *thd_arg, sp_lex_keeper *lex_keeper, sp_instr_cpush *i): + result(thd_arg), + m_lex_keeper(lex_keeper), server_side_cursor(NULL), m_i(i) { diff --git a/sql/sp_rcontext.h b/sql/sp_rcontext.h index c48025da93d..2640490fefa 100644 --- a/sql/sp_rcontext.h +++ b/sql/sp_rcontext.h @@ -281,7 +281,7 @@ public: /// @return error flag. /// @retval false on success. /// @retval true on error. - bool push_cursor(sp_lex_keeper *lex_keeper, sp_instr_cpush *i); + bool push_cursor(THD *thd, sp_lex_keeper *lex_keeper, sp_instr_cpush *i); /// Pop and delete given number of sp_cursor instance from the cursor stack. /// @@ -428,7 +428,7 @@ private: List *spvar_list; uint field_count; public: - Select_fetch_into_spvars() {} /* Remove gcc warning */ + Select_fetch_into_spvars(THD *thd_arg): select_result_interceptor(thd_arg) {} uint get_field_count() { return field_count; } void set_spvar_list(List *vars) { spvar_list= vars; } @@ -438,7 +438,7 @@ private: }; public: - sp_cursor(sp_lex_keeper *lex_keeper, sp_instr_cpush *i); + sp_cursor(THD *thd_arg, sp_lex_keeper *lex_keeper, sp_instr_cpush *i); virtual ~sp_cursor() { destroy(); } diff --git a/sql/sql_class.cc b/sql/sql_class.cc index a32cfdb9f3a..5c6c45e2cbe 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -2628,11 +2628,6 @@ void THD::rollback_item_tree_changes() ** Functions to provide a interface to select results *****************************************************************************/ -select_result::select_result() -{ - thd=current_thd; -} - void select_result::cleanup() { /* do nothing */ @@ -3290,12 +3285,6 @@ err: } -select_subselect::select_subselect(Item_subselect *item_arg) -{ - item= item_arg; -} - - int select_singlerow_subselect::send_data(List &items) { DBUG_ENTER("select_singlerow_subselect::send_data"); diff --git a/sql/sql_class.h b/sql/sql_class.h index 357558cf54b..ca532ae50b7 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -4074,7 +4074,7 @@ protected: SELECT_LEX_UNIT *unit; /* Something used only by the parser: */ public: - select_result(); + select_result(THD *thd_arg): thd(thd_arg) {} virtual ~select_result() {}; /** Change wrapped select_result. @@ -4203,7 +4203,8 @@ private: class select_result_interceptor: public select_result { public: - select_result_interceptor() : suppress_my_ok(false) + select_result_interceptor(THD *thd_arg): + select_result(thd_arg), suppress_my_ok(false) { DBUG_ENTER("select_result_interceptor::select_result_interceptor"); DBUG_PRINT("enter", ("this 0x%lx", (ulong) this)); @@ -4231,7 +4232,8 @@ class select_send :public select_result { */ bool is_result_set_started; public: - select_send() :is_result_set_started(FALSE) {} + select_send(THD *thd_arg): + select_result(thd_arg), is_result_set_started(FALSE) {} bool send_result_set_metadata(List &list, uint flags); int send_data(List &items); bool send_eof(); @@ -4253,6 +4255,8 @@ class select_send_analyze : public select_send bool send_result_set_metadata(List &list, uint flags) { return 0; } bool send_eof() { return 0; } void abort_result_set() {} +public: + select_send_analyze(THD *thd_arg): select_send(thd_arg) {} }; @@ -4265,7 +4269,8 @@ protected: char path[FN_REFLEN]; public: - select_to_file(sql_exchange *ex) :exchange(ex), file(-1),row_count(0L) + select_to_file(THD *thd_arg, sql_exchange *ex): + select_result_interceptor(thd_arg), exchange(ex), file(-1),row_count(0L) { path[0]=0; } ~select_to_file(); bool send_eof(); @@ -4307,7 +4312,7 @@ class select_export :public select_to_file { bool fixed_row_size; CHARSET_INFO *write_cs; // output charset public: - select_export(sql_exchange *ex) :select_to_file(ex) {} + select_export(THD *thd_arg, sql_exchange *ex): select_to_file(thd_arg, ex) {} ~select_export(); int prepare(List &list, SELECT_LEX_UNIT *u); int send_data(List &items); @@ -4316,7 +4321,7 @@ public: class select_dump :public select_to_file { public: - select_dump(sql_exchange *ex) :select_to_file(ex) {} + select_dump(THD *thd_arg, sql_exchange *ex): select_to_file(thd_arg, ex) {} int prepare(List &list, SELECT_LEX_UNIT *u); int send_data(List &items); }; @@ -4330,7 +4335,7 @@ class select_insert :public select_result_interceptor { ulonglong autoinc_value_of_last_inserted_row; // autogenerated or not COPY_INFO info; bool insert_into_view; - select_insert(TABLE_LIST *table_list_par, + select_insert(THD *thd_arg, TABLE_LIST *table_list_par, TABLE *table_par, List *fields_par, List *update_fields, List *update_values, enum_duplicates duplic, bool ignore); @@ -4361,12 +4366,12 @@ class select_create: public select_insert { bool exit_done; public: - select_create (TABLE_LIST *table_arg, - Table_specification_st *create_info_par, - Alter_info *alter_info_arg, - List &select_fields,enum_duplicates duplic, bool ignore, - TABLE_LIST *select_tables_arg) - :select_insert (NULL, NULL, &select_fields, 0, 0, duplic, ignore), + select_create(THD *thd_arg, TABLE_LIST *table_arg, + Table_specification_st *create_info_par, + Alter_info *alter_info_arg, + List &select_fields,enum_duplicates duplic, bool ignore, + TABLE_LIST *select_tables_arg): + select_insert(thd_arg, NULL, NULL, &select_fields, 0, 0, duplic, ignore), create_table(table_arg), create_info(create_info_par), select_tables(select_tables_arg), @@ -4518,7 +4523,9 @@ public: TABLE *table; ha_rows records; - select_union() :write_err(0), table(0), records(0) { tmp_table_param.init(); } + select_union(THD *thd_arg): + select_result_interceptor(thd_arg), write_err(0), table(0), records(0) + { tmp_table_param.init(); } int prepare(List &list, SELECT_LEX_UNIT *u); /** Do prepare() and prepare2() if they have been postponed until @@ -4581,8 +4588,9 @@ private: public: /* Number of rows in the union */ ha_rows send_records; - select_union_direct(select_result *result, SELECT_LEX *last_select_lex) - :result(result), last_select_lex(last_select_lex), + select_union_direct(THD *thd_arg, select_result *result, + SELECT_LEX *last_select_lex): + select_union(thd_arg), result(result), last_select_lex(last_select_lex), done_send_result_set_metadata(false), done_initialize_tables(false), limit_found_rows(0) { send_records= 0; } @@ -4641,7 +4649,8 @@ class select_subselect :public select_result_interceptor protected: Item_subselect *item; public: - select_subselect(Item_subselect *item); + select_subselect(THD *thd_arg, Item_subselect *item_arg): + select_result_interceptor(thd_arg), item(item_arg) {} int send_data(List &items)=0; bool send_eof() { return 0; }; }; @@ -4650,8 +4659,8 @@ public: class select_singlerow_subselect :public select_subselect { public: - select_singlerow_subselect(Item_subselect *item_arg) - :select_subselect(item_arg) + select_singlerow_subselect(THD *thd_arg, Item_subselect *item_arg): + select_subselect(thd_arg, item_arg) {} int send_data(List &items); }; @@ -4696,7 +4705,8 @@ protected: void reset(); public: - select_materialize_with_stats() { tmp_table_param.init(); } + select_materialize_with_stats(THD *thd_arg): select_union(thd_arg) + { tmp_table_param.init(); } bool create_result_table(THD *thd, List *column_types, bool is_distinct, ulonglong options, const char *alias, @@ -4733,9 +4743,9 @@ class select_max_min_finder_subselect :public select_subselect bool fmax; bool is_all; public: - select_max_min_finder_subselect(Item_subselect *item_arg, bool mx, - bool all) - :select_subselect(item_arg), cache(0), fmax(mx), is_all(all) + select_max_min_finder_subselect(THD *thd_arg, Item_subselect *item_arg, + bool mx, bool all): + select_subselect(thd_arg, item_arg), cache(0), fmax(mx), is_all(all) {} void cleanup(); int send_data(List &items); @@ -4749,8 +4759,8 @@ public: class select_exists_subselect :public select_subselect { public: - select_exists_subselect(Item_subselect *item_arg) - :select_subselect(item_arg){} + select_exists_subselect(THD *thd_arg, Item_subselect *item_arg): + select_subselect(thd_arg, item_arg) {} int send_data(List &items); }; @@ -5001,7 +5011,7 @@ class multi_delete :public select_result_interceptor bool error_handled; public: - multi_delete(TABLE_LIST *dt, uint num_of_tables); + multi_delete(THD *thd_arg, TABLE_LIST *dt, uint num_of_tables); ~multi_delete(); int prepare(List &list, SELECT_LEX_UNIT *u); int send_data(List &items); @@ -5048,7 +5058,7 @@ class multi_update :public select_result_interceptor /* Need this to protect against multiple prepare() calls */ bool prepared; public: - multi_update(TABLE_LIST *ut, List *leaves_list, + multi_update(THD *thd_arg, TABLE_LIST *ut, List *leaves_list, List *fields, List *values, enum_duplicates handle_duplicates, bool ignore); ~multi_update(); @@ -5106,7 +5116,8 @@ class select_dumpvar :public select_result_interceptor { ha_rows row_count; public: List var_list; - select_dumpvar() { var_list.empty(); row_count= 0;} + select_dumpvar(THD *thd_arg): select_result_interceptor(thd_arg) + { var_list.empty(); row_count= 0; } ~select_dumpvar() {} int prepare(List &list, SELECT_LEX_UNIT *u); int send_data(List &items); diff --git a/sql/sql_cursor.cc b/sql/sql_cursor.cc index a7dcc77f26c..912f6d97519 100644 --- a/sql/sql_cursor.cc +++ b/sql/sql_cursor.cc @@ -71,8 +71,8 @@ class Select_materialize: public select_union select_result *result; /**< the result object of the caller (PS or SP) */ public: Materialized_cursor *materialized_cursor; - Select_materialize(select_result *result_arg) - :result(result_arg), materialized_cursor(0) {} + Select_materialize(THD *thd_arg, select_result *result_arg): + select_union(thd_arg), result(result_arg), materialized_cursor(0) {} virtual bool send_result_set_metadata(List &list, uint flags); }; @@ -104,7 +104,7 @@ int mysql_open_cursor(THD *thd, select_result *result, LEX *lex= thd->lex; int rc; - if (! (result_materialize= new (thd->mem_root) Select_materialize(result))) + if (!(result_materialize= new (thd->mem_root) Select_materialize(thd, result))) return 1; save_result= lex->result; diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc index fa647679e23..a9470dd2b6c 100644 --- a/sql/sql_delete.cc +++ b/sql/sql_delete.cc @@ -901,8 +901,8 @@ int mysql_multi_delete_prepare(THD *thd) } -multi_delete::multi_delete(TABLE_LIST *dt, uint num_of_tables_arg) - : delete_tables(dt), deleted(0), found(0), +multi_delete::multi_delete(THD *thd_arg, TABLE_LIST *dt, uint num_of_tables_arg): + select_result_interceptor(thd_arg), delete_tables(dt), deleted(0), found(0), num_of_tables(num_of_tables_arg), error(0), do_delete(0), transactional_tables(0), normal_tables(0), error_handled(0) { diff --git a/sql/sql_derived.cc b/sql/sql_derived.cc index 60e49fc2756..704d031329d 100644 --- a/sql/sql_derived.cc +++ b/sql/sql_derived.cc @@ -660,7 +660,7 @@ bool mysql_derived_prepare(THD *thd, LEX *lex, TABLE_LIST *derived) unit->derived= derived; - if (!(derived->derived_result= new select_union)) + if (!(derived->derived_result= new (thd->mem_root) select_union(thd))) DBUG_RETURN(TRUE); // out of memory lex->context_analysis_only|= CONTEXT_ANALYSIS_ONLY_DERIVED; diff --git a/sql/sql_explain.cc b/sql/sql_explain.cc index 1cfaeaa27ec..92f221513f2 100644 --- a/sql/sql_explain.cc +++ b/sql/sql_explain.cc @@ -156,7 +156,7 @@ int Explain_query::send_explain(THD *thd) select_result *result; LEX *lex= thd->lex; - if (!(result= new (thd->mem_root) select_send()) || + if (!(result= new (thd->mem_root) select_send(thd)) || thd->send_explain_fields(result, lex->describe, lex->analyze_stmt)) return 1; diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 24d75d97ee4..aaaf7b998b0 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -3348,15 +3348,17 @@ bool mysql_insert_select_prepare(THD *thd) } -select_insert::select_insert(TABLE_LIST *table_list_par, TABLE *table_par, +select_insert::select_insert(THD *thd_arg, TABLE_LIST *table_list_par, + TABLE *table_par, List *fields_par, List *update_fields, List *update_values, enum_duplicates duplic, - bool ignore_check_option_errors) - :table_list(table_list_par), table(table_par), fields(fields_par), - autoinc_value_of_last_inserted_row(0), - insert_into_view(table_list_par && table_list_par->view != 0) + bool ignore_check_option_errors): + select_result_interceptor(thd_arg), + table_list(table_list_par), table(table_par), fields(fields_par), + autoinc_value_of_last_inserted_row(0), + insert_into_view(table_list_par && table_list_par->view != 0) { bzero((char*) &info,sizeof(info)); info.handle_duplicates= duplic; diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 65f8372394b..1386dcce4d9 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -3364,13 +3364,13 @@ mysql_execute_command(THD *thd) select_create is currently not re-execution friendly and needs to be created for every execution of a PS/SP. */ - if ((result= new select_create(create_table, - &create_info, - &alter_info, - select_lex->item_list, - lex->duplicates, - lex->ignore, - select_tables))) + if ((result= new (thd->mem_root) select_create(thd, create_table, + &create_info, + &alter_info, + select_lex->item_list, + lex->duplicates, + lex->ignore, + select_tables))) { /* CREATE from SELECT give its SELECT_LEX for SELECT, @@ -3934,13 +3934,14 @@ end_with_restore_list: select_lex->context.table_list= select_lex->context.first_name_resolution_table= second_table; res= mysql_insert_select_prepare(thd); - if (!res && (sel_result= new select_insert(first_table, - first_table->table, - &lex->field_list, - &lex->update_list, - &lex->value_list, - lex->duplicates, - lex->ignore))) + if (!res && (sel_result= new (thd->mem_root) select_insert(thd, + first_table, + first_table->table, + &lex->field_list, + &lex->update_list, + &lex->value_list, + lex->duplicates, + lex->ignore))) { if (lex->analyze_stmt) ((select_result_interceptor*)sel_result)->disable_my_ok_calls(); @@ -4009,14 +4010,15 @@ end_with_restore_list: Actually, it is ANALYZE .. DELETE .. RETURNING. We need to produce output and then discard it. */ - sel_result= new select_send_analyze(); + sel_result= new (thd->mem_root) select_send_analyze(thd); replaced_protocol= true; save_protocol= thd->protocol; thd->protocol= new Protocol_discard(thd); } else { - if (!(sel_result= lex->result) && !(sel_result= new select_send())) + if (!(sel_result= lex->result) && + !(sel_result= new (thd->mem_root) select_send(thd))) return 1; } } @@ -4073,7 +4075,8 @@ end_with_restore_list: if (!thd->is_fatal_error) { - result= new multi_delete(aux_tables, lex->table_count); + result= new (thd->mem_root) multi_delete(thd, aux_tables, + lex->table_count); if (result) { res= mysql_select(thd, &select_lex->ref_pointer_array, @@ -5710,7 +5713,7 @@ static bool execute_sqlcom_select(THD *thd, TABLE_LIST *all_tables) to prepend EXPLAIN to any query and receive output for it, even if the query itself redirects the output. */ - if (!(result= new select_send())) + if (!(result= new (thd->mem_root) select_send(thd))) return 1; /* purecov: inspected */ thd->send_explain_fields(result, lex->describe, lex->analyze_stmt); @@ -5768,14 +5771,14 @@ static bool execute_sqlcom_select(THD *thd, TABLE_LIST *all_tables) else { DBUG_ASSERT(thd->protocol); - result= new select_send_analyze(); + result= new (thd->mem_root) select_send_analyze(thd); save_protocol= thd->protocol; thd->protocol= new Protocol_discard(thd); } } else { - if (!result && !(result= new (thd->mem_root) select_send())) + if (!result && !(result= new (thd->mem_root) select_send(thd))) return 1; /* purecov: inspected */ } query_cache_store_query(thd, all_tables); @@ -8222,23 +8225,25 @@ Comp_creator *comp_ne_creator(bool invert) @return constructed Item (or 0 if out of memory) */ -Item * all_any_subquery_creator(Item *left_expr, +Item * all_any_subquery_creator(THD *thd, Item *left_expr, chooser_compare_func_creator cmp, bool all, SELECT_LEX *select_lex) { if ((cmp == &comp_eq_creator) && !all) // = ANY <=> IN - return new Item_in_subselect(left_expr, select_lex); + return new (thd->mem_root) Item_in_subselect(thd, left_expr, select_lex); if ((cmp == &comp_ne_creator) && all) // <> ALL <=> NOT IN - return new Item_func_not(new Item_in_subselect(left_expr, select_lex)); + return new (thd->mem_root) Item_func_not( + new (thd->mem_root) Item_in_subselect(thd, left_expr, select_lex)); Item_allany_subselect *it= - new Item_allany_subselect(left_expr, cmp, select_lex, all); + new (thd->mem_root) Item_allany_subselect(thd, left_expr, cmp, select_lex, + all); if (all) - return it->upper_item= new Item_func_not_all(it); /* ALL */ + return it->upper_item= new (thd->mem_root) Item_func_not_all(it); /* ALL */ - return it->upper_item= new Item_func_nop_all(it); /* ANY/SOME */ + return it->upper_item= new (thd->mem_root) Item_func_nop_all(it); /* ANY/SOME */ } diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index 31a352f3455..ea16b862b11 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -1516,7 +1516,7 @@ static int mysql_test_select(Prepared_statement *stmt, else if (check_access(thd, privilege, any_db, NULL, NULL, 0, 0)) goto error; - if (!lex->result && !(lex->result= new (stmt->mem_root) select_send)) + if (!lex->result && !(lex->result= new (stmt->mem_root) select_send(thd))) { my_error(ER_OUTOFMEMORY, MYF(ME_FATALERROR), static_cast(sizeof(select_send))); @@ -2024,7 +2024,7 @@ static int mysql_test_handler_read(Prepared_statement *stmt, if (!stmt->is_sql_prepare()) { - if (!lex->result && !(lex->result= new (stmt->mem_root) select_send)) + if (!lex->result && !(lex->result= new (stmt->mem_root) select_send(thd))) { my_error(ER_OUTOFMEMORY, MYF(0), sizeof(select_send)); DBUG_RETURN(1); @@ -3035,8 +3035,8 @@ void mysql_stmt_get_longdata(THD *thd, char *packet, ulong packet_length) Select_fetch_protocol_binary ****************************************************************************/ -Select_fetch_protocol_binary::Select_fetch_protocol_binary(THD *thd_arg) - :protocol(thd_arg) +Select_fetch_protocol_binary::Select_fetch_protocol_binary(THD *thd_arg): + select_send(thd_arg), protocol(thd_arg) {} bool Select_fetch_protocol_binary::send_result_set_metadata(List &list, uint flags) diff --git a/sql/sql_union.cc b/sql/sql_union.cc index 2ac83773c34..f7df0fd1538 100644 --- a/sql/sql_union.cc +++ b/sql/sql_union.cc @@ -395,14 +395,17 @@ bool st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result, SELECT_LEX *last= first_select(); while (last->next_select()) last= last->next_select(); - if (!(tmp_result= union_result= new select_union_direct(sel_result, last))) + if (!(tmp_result= union_result= + new (thd_arg->mem_root) select_union_direct(thd_arg, sel_result, + last))) goto err; /* purecov: inspected */ fake_select_lex= NULL; instantiate_tmp_table= false; } else { - if (!(tmp_result= union_result= new select_union())) + if (!(tmp_result= union_result= + new (thd_arg->mem_root) select_union(thd_arg))) goto err; /* purecov: inspected */ instantiate_tmp_table= true; } diff --git a/sql/sql_update.cc b/sql/sql_update.cc index 890e72f3314..37ad416f910 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -1571,7 +1571,7 @@ bool mysql_multi_update(THD *thd, bool res; DBUG_ENTER("mysql_multi_update"); - if (!(*result= new multi_update(table_list, + if (!(*result= new (thd->mem_root) multi_update(thd, table_list, &thd->lex->select_lex.leaf_tables, fields, values, handle_duplicates, ignore))) @@ -1605,12 +1605,13 @@ bool mysql_multi_update(THD *thd, } -multi_update::multi_update(TABLE_LIST *table_list, +multi_update::multi_update(THD *thd_arg, TABLE_LIST *table_list, List *leaves_list, List *field_list, List *value_list, enum enum_duplicates handle_duplicates_arg, - bool ignore_arg) - :all_tables(table_list), leaves(leaves_list), update_tables(0), + bool ignore_arg): + select_result_interceptor(thd_arg), + all_tables(table_list), leaves(leaves_list), update_tables(0), tmp_tables(0), updated(0), found(0), fields(field_list), values(value_list), table_count(0), copy_field(0), handle_duplicates(handle_duplicates_arg), do_update(1), trans_safe(1), diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 72b8ef76ea3..dc9ce95b8e3 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -612,7 +612,7 @@ Item* handle_sql2003_note184_exception(THD *thd, Item* left, bool equal, Item_in_subselect(left, subselect) */ subselect= expr3->invalidate_and_restore_select_lex(); - result= new (thd->mem_root) Item_in_subselect(left, subselect); + result= new (thd->mem_root) Item_in_subselect(thd, left, subselect); if (! equal) result = negate_expression(thd, result); @@ -8803,7 +8803,7 @@ bool_pri: } | bool_pri comp_op all_or_any '(' subselect ')' %prec EQ { - $$= all_any_subquery_creator($1, $2, $3, $5); + $$= all_any_subquery_creator(thd, $1, $2, $3, $5); if ($$ == NULL) MYSQL_YYABORT; } @@ -8813,13 +8813,13 @@ bool_pri: predicate: bit_expr IN_SYM '(' subselect ')' { - $$= new (thd->mem_root) Item_in_subselect($1, $4); + $$= new (thd->mem_root) Item_in_subselect(thd, $1, $4); if ($$ == NULL) MYSQL_YYABORT; } | bit_expr not IN_SYM '(' subselect ')' { - Item *item= new (thd->mem_root) Item_in_subselect($1, $5); + Item *item= new (thd->mem_root) Item_in_subselect(thd, $1, $5); if (item == NULL) MYSQL_YYABORT; $$= negate_expression(thd, item); @@ -9217,7 +9217,7 @@ simple_expr: } | '(' subselect ')' { - $$= new (thd->mem_root) Item_singlerow_subselect($2); + $$= new (thd->mem_root) Item_singlerow_subselect(thd, $2); if ($$ == NULL) MYSQL_YYABORT; } @@ -9239,7 +9239,7 @@ simple_expr: } | EXISTS '(' subselect ')' { - $$= new (thd->mem_root) Item_exists_subselect($3); + $$= new (thd->mem_root) Item_exists_subselect(thd, $3); if ($$ == NULL) MYSQL_YYABORT; } @@ -11621,7 +11621,8 @@ procedure_item: select_var_list_init: { LEX *lex=Lex; - if (!lex->describe && (!(lex->result= new select_dumpvar()))) + if (!lex->describe && + (!(lex->result= new (thd->mem_root) select_dumpvar(thd)))) MYSQL_YYABORT; } select_var_list @@ -11688,8 +11689,10 @@ into_destination: { LEX *lex= Lex; lex->uncacheable(UNCACHEABLE_SIDEEFFECT); - if (!(lex->exchange= new sql_exchange($2.str, 0)) || - !(lex->result= new select_export(lex->exchange))) + if (!(lex->exchange= + new (thd->mem_root) sql_exchange($2.str, 0)) || + !(lex->result= + new (thd->mem_root) select_export(thd, lex->exchange))) MYSQL_YYABORT; } opt_load_data_charset @@ -11703,7 +11706,8 @@ into_destination: lex->uncacheable(UNCACHEABLE_SIDEEFFECT); if (!(lex->exchange= new sql_exchange($2.str,1))) MYSQL_YYABORT; - if (!(lex->result= new select_dump(lex->exchange))) + if (!(lex->result= + new (thd->mem_root) select_dump(thd, lex->exchange))) MYSQL_YYABORT; } } -- cgit v1.2.1