From e300f0c9612559bc5c80830f9b98e46bb010d7d1 Mon Sep 17 00:00:00 2001 From: Monty Date: Tue, 30 Jan 2018 21:32:19 +0200 Subject: [PATCH 1/7] MDEV-15133 array bound (bulk) parameters of NULL propagate on next rows null_value was not properly reset when setting parameter value --- sql/item.cc | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/sql/item.cc b/sql/item.cc index 98d66df4682..f8f4b9fc5eb 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -3781,6 +3781,7 @@ void Item_param::set_int(longlong i, uint32 max_length_arg) max_length= max_length_arg; decimals= 0; maybe_null= 0; + null_value= 0; fix_type(Item::INT_ITEM); DBUG_VOID_RETURN; } @@ -3795,6 +3796,7 @@ void Item_param::set_double(double d) max_length= DBL_DIG + 8; decimals= NOT_FIXED_DEC; maybe_null= 0; + null_value= 0; fix_type(Item::REAL_ITEM); DBUG_VOID_RETURN; } @@ -3827,6 +3829,7 @@ void Item_param::set_decimal(const char *str, ulong length) my_decimal_precision_to_length_no_truncation(value.m_decimal.precision(), decimals, unsigned_flag); maybe_null= 0; + null_value= 0; fix_type(Item::DECIMAL_ITEM); DBUG_VOID_RETURN; } @@ -3843,6 +3846,7 @@ void Item_param::set_decimal(const my_decimal *dv, bool unsigned_arg) unsigned_flag= unsigned_arg; max_length= my_decimal_precision_to_length(value.m_decimal.intg + decimals, decimals, unsigned_flag); + null_value= 0; fix_type(Item::DECIMAL_ITEM); } @@ -3862,6 +3866,7 @@ void Item_param::set_time(const MYSQL_TIME *tm, { DBUG_ASSERT(value.type_handler()->cmp_type() == TIME_RESULT); value.time= *tm; + null_value= 0; fix_temporal(max_length_arg, decimals_arg); } @@ -3896,6 +3901,7 @@ void Item_param::set_time(MYSQL_TIME *tm, timestamp_type time_type, set_zero_time(&value.time, MYSQL_TIMESTAMP_ERROR); } maybe_null= 0; + null_value= 0; fix_temporal(max_length_arg, tm->second_part > 0 ? TIME_SECOND_PART_DIGITS : 0); DBUG_VOID_RETURN; @@ -3932,6 +3938,7 @@ bool Item_param::set_str(const char *str, ulong length, collation.set(tocs, DERIVATION_COERCIBLE); max_length= length; maybe_null= 0; + null_value= 0; /* max_length and decimals are set after charset conversion */ /* sic: str may be not null-terminated, don't add DBUG_PRINT here */ fix_type(Item::STRING_ITEM); @@ -3967,6 +3974,7 @@ bool Item_param::set_longdata(const char *str, ulong length) DBUG_RETURN(TRUE); state= LONG_DATA_VALUE; maybe_null= 0; + null_value= 0; fix_type(Item::STRING_ITEM); DBUG_RETURN(FALSE); From df2d67824811516fabcfb09dacd6d147f8f71d54 Mon Sep 17 00:00:00 2001 From: Oleksandr Byelkin Date: Wed, 31 Jan 2018 11:37:02 +0100 Subject: [PATCH 2/7] MDEV-15133: array bound (bulk) parameters of NULL propagate on next rows Setting non_null value drops null_value flag. Part 2 of 3. Part 1 was 10.2 fix. Part 3 is test for Connector C. --- mysql-test/r/ps.result | 32 ++++++++++++++++---------------- sql/item.cc | 13 +++++++++++-- 2 files changed, 27 insertions(+), 18 deletions(-) diff --git a/mysql-test/r/ps.result b/mysql-test/r/ps.result index c92b303f104..49214083e59 100644 --- a/mysql-test/r/ps.result +++ b/mysql-test/r/ps.result @@ -1738,7 +1738,7 @@ execute stmt using @a; show create table t1; Table Create Table t1 CREATE TABLE `t1` ( - `?` decimal(2,1) DEFAULT NULL + `?` decimal(2,1) NOT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 drop table t1; drop table if exists t1; @@ -4432,7 +4432,7 @@ EXECUTE stmt USING 10.123; SHOW CREATE TABLE t1; Table Create Table t1 CREATE TABLE `t1` ( - `c1` decimal(5,3) DEFAULT NULL + `c1` decimal(5,3) NOT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 DROP TABLE t1; EXECUTE stmt USING 10.123e0; @@ -4446,49 +4446,49 @@ EXECUTE stmt USING CURRENT_DATE; SHOW CREATE TABLE t1; Table Create Table t1 CREATE TABLE `t1` ( - `c1` date DEFAULT NULL + `c1` date NOT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 DROP TABLE t1; EXECUTE stmt USING CURRENT_TIMESTAMP; SHOW CREATE TABLE t1; Table Create Table t1 CREATE TABLE `t1` ( - `c1` datetime DEFAULT NULL + `c1` datetime NOT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 DROP TABLE t1; EXECUTE stmt USING CURRENT_TIMESTAMP(3); SHOW CREATE TABLE t1; Table Create Table t1 CREATE TABLE `t1` ( - `c1` datetime(3) DEFAULT NULL + `c1` datetime(3) NOT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 DROP TABLE t1; EXECUTE stmt USING CURRENT_TIMESTAMP(6); SHOW CREATE TABLE t1; Table Create Table t1 CREATE TABLE `t1` ( - `c1` datetime(6) DEFAULT NULL + `c1` datetime(6) NOT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 DROP TABLE t1; EXECUTE stmt USING CURRENT_TIME; SHOW CREATE TABLE t1; Table Create Table t1 CREATE TABLE `t1` ( - `c1` time DEFAULT NULL + `c1` time NOT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 DROP TABLE t1; EXECUTE stmt USING CURRENT_TIME(3); SHOW CREATE TABLE t1; Table Create Table t1 CREATE TABLE `t1` ( - `c1` time(3) DEFAULT NULL + `c1` time(3) NOT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 DROP TABLE t1; EXECUTE stmt USING CURRENT_TIME(6); SHOW CREATE TABLE t1; Table Create Table t1 CREATE TABLE `t1` ( - `c1` time(6) DEFAULT NULL + `c1` time(6) NOT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 DROP TABLE t1; DEALLOCATE PREPARE stmt; @@ -4633,7 +4633,7 @@ SHOW CREATE TABLE t1; Table Create Table t1 CREATE TABLE `t1` ( `a` bigint(20) NOT NULL, - `b` decimal(3,1) DEFAULT NULL, + `b` decimal(3,1) NOT NULL, `c` double NOT NULL, `d` tinytext NOT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 @@ -4645,7 +4645,7 @@ SHOW CREATE TABLE t1; Table Create Table t1 CREATE TABLE `t1` ( `a` int(2) NOT NULL, - `b` decimal(3,1) DEFAULT NULL, + `b` decimal(3,1) NOT NULL, `c` double NOT NULL, `d` varchar(3) NOT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 @@ -4660,11 +4660,11 @@ TIMESTAMP'2001-01-01 10:20:30.123'; SHOW CREATE TABLE t1; Table Create Table t1 CREATE TABLE `t1` ( - `t1` time DEFAULT NULL, - `t2` time(3) DEFAULT NULL, - `d1` date DEFAULT NULL, - `dt1` datetime DEFAULT NULL, - `dt2` datetime(3) DEFAULT NULL + `t1` time NOT NULL, + `t2` time(3) NOT NULL, + `d1` date NOT NULL, + `dt1` datetime NOT NULL, + `dt2` datetime(3) NOT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 DROP TABLE t1; # diff --git a/sql/item.cc b/sql/item.cc index f8f4b9fc5eb..3668278d4c7 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -3757,7 +3757,10 @@ Item_param::Item_param(THD *thd, const LEX_CSTRING *name_arg, void Item_param::set_null() { DBUG_ENTER("Item_param::set_null"); - /* These are cleared after each execution by reset() method */ + /* + These are cleared after each execution by reset() method or by setting + other value. + */ null_value= 1; /* Because of NULL and string values we need to set max_length for each new @@ -3846,6 +3849,7 @@ void Item_param::set_decimal(const my_decimal *dv, bool unsigned_arg) unsigned_flag= unsigned_arg; max_length= my_decimal_precision_to_length(value.m_decimal.intg + decimals, decimals, unsigned_flag); + maybe_null= 0; null_value= 0; fix_type(Item::DECIMAL_ITEM); } @@ -3857,6 +3861,8 @@ void Item_param::fix_temporal(uint32 max_length_arg, uint decimals_arg) collation.set_numeric(); max_length= max_length_arg; decimals= decimals_arg; + maybe_null= 0; + null_value= 0; fix_type(Item::DATE_ITEM); } @@ -3866,6 +3872,7 @@ void Item_param::set_time(const MYSQL_TIME *tm, { DBUG_ASSERT(value.type_handler()->cmp_type() == TIME_RESULT); value.time= *tm; + maybe_null= 0; null_value= 0; fix_temporal(max_length_arg, decimals_arg); } @@ -4634,7 +4641,9 @@ Item_param::set_value(THD *thd, sp_rcontext *ctx, Item **it) set_null(); return false; } - return null_value= false; + /* It is wrapper => other set_* shoud set null_value */ + DBUG_ASSERT(null_value == false); + return false; } From 1e5e3d562b867ae83c3fbb003465e1596c748690 Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Wed, 31 Jan 2018 19:49:48 +0400 Subject: [PATCH 3/7] A cleanup in sp_rcontext, as requested by Monty - Changing sp_rcontext::m_var_items from list of Item to list of Item_field - Renaming sp_rcontext::get_item() to get_variable() and changing its return type from Item* to Item_field * - Adding sp_rcontext::get_parameter() and sp_rcontext::set_parameter(), wrappers for get_variable() and set_variable() with extra DBUG_ASSERT. Using new methods instead of get_variable()/set_variable() in relevant places. --- sql/item.cc | 18 +++++++++--------- sql/sp_head.cc | 14 +++++++------- sql/sp_rcontext.cc | 12 ++++++------ sql/sp_rcontext.h | 26 ++++++++++++++++++++++---- sql/sql_class.cc | 2 +- 5 files changed, 45 insertions(+), 27 deletions(-) diff --git a/sql/item.cc b/sql/item.cc index 3668278d4c7..d4da3f866d0 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -1788,7 +1788,7 @@ Item_splocal::Item_splocal(THD *thd, const LEX_CSTRING *sp_var_name, bool Item_splocal::fix_fields(THD *thd, Item **ref) { - Item *item= thd->spcont->get_item(m_var_idx); + Item_field *item= thd->spcont->get_variable(m_var_idx); set_handler(item->type_handler()); return fix_fields_from_item(thd, ref, item); } @@ -1799,7 +1799,7 @@ Item_splocal::this_item() { DBUG_ASSERT(m_sp == m_thd->spcont->m_sp); DBUG_ASSERT(fixed); - return m_thd->spcont->get_item(m_var_idx); + return m_thd->spcont->get_variable(m_var_idx); } const Item * @@ -1807,7 +1807,7 @@ Item_splocal::this_item() const { DBUG_ASSERT(m_sp == m_thd->spcont->m_sp); DBUG_ASSERT(fixed); - return m_thd->spcont->get_item(m_var_idx); + return m_thd->spcont->get_variable(m_var_idx); } @@ -1816,7 +1816,7 @@ Item_splocal::this_item_addr(THD *thd, Item **) { DBUG_ASSERT(m_sp == thd->spcont->m_sp); DBUG_ASSERT(fixed); - return thd->spcont->get_item_addr(m_var_idx); + return thd->spcont->get_variable_addr(m_var_idx); } @@ -1913,7 +1913,7 @@ bool Item_splocal::check_cols(uint n) bool Item_splocal_row_field::fix_fields(THD *thd, Item **ref) { - Item *item= thd->spcont->get_item(m_var_idx)->element_index(m_field_idx); + Item *item= thd->spcont->get_variable(m_var_idx)->element_index(m_field_idx); return fix_fields_from_item(thd, ref, item); } @@ -1923,7 +1923,7 @@ Item_splocal_row_field::this_item() { DBUG_ASSERT(m_sp == m_thd->spcont->m_sp); DBUG_ASSERT(fixed); - return m_thd->spcont->get_item(m_var_idx)->element_index(m_field_idx); + return m_thd->spcont->get_variable(m_var_idx)->element_index(m_field_idx); } @@ -1932,7 +1932,7 @@ Item_splocal_row_field::this_item() const { DBUG_ASSERT(m_sp == m_thd->spcont->m_sp); DBUG_ASSERT(fixed); - return m_thd->spcont->get_item(m_var_idx)->element_index(m_field_idx); + return m_thd->spcont->get_variable(m_var_idx)->element_index(m_field_idx); } @@ -1941,7 +1941,7 @@ Item_splocal_row_field::this_item_addr(THD *thd, Item **) { DBUG_ASSERT(m_sp == thd->spcont->m_sp); DBUG_ASSERT(fixed); - return thd->spcont->get_item(m_var_idx)->addr(m_field_idx); + return thd->spcont->get_variable(m_var_idx)->addr(m_field_idx); } @@ -1972,7 +1972,7 @@ bool Item_splocal_row_field_by_name::fix_fields(THD *thd, Item **it) m_var_idx, m_field_name)) return true; - Item *item= thd->spcont->get_item(m_var_idx)->element_index(m_field_idx); + Item *item= thd->spcont->get_variable(m_var_idx)->element_index(m_field_idx); set_handler(item->type_handler()); return fix_fields_from_item(thd, it, item); } diff --git a/sql/sp_head.cc b/sql/sp_head.cc index ead04368acd..9351babdab5 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -1700,7 +1700,7 @@ sp_head::execute_function(THD *thd, Item **argp, uint argcount, /* Arguments must be fixed in Item_func_sp::fix_fields */ DBUG_ASSERT(argp[arg_no]->fixed); - if ((err_status= nctx->set_variable(thd, arg_no, &(argp[arg_no])))) + if ((err_status= nctx->set_parameter(thd, arg_no, &(argp[arg_no])))) goto err_with_cleanup; } @@ -1732,7 +1732,7 @@ sp_head::execute_function(THD *thd, Item **argp, uint argcount, if (arg_no) binlog_buf.append(','); - Item *item= nctx->get_item(arg_no); + Item_field *item= nctx->get_parameter(arg_no); str_value= item->type_handler()->print_item_value(thd, item, &str_value_holder); if (str_value) @@ -1948,7 +1948,7 @@ sp_head::execute_procedure(THD *thd, List *args) Item *tmp_item= null_item; if (!null_item || - nctx->set_variable(thd, i, &tmp_item)) + nctx->set_parameter(thd, i, &tmp_item)) { DBUG_PRINT("error", ("set variable failed")); err_status= TRUE; @@ -1957,7 +1957,7 @@ sp_head::execute_procedure(THD *thd, List *args) } else { - if (nctx->set_variable(thd, i, it_args.ref())) + if (nctx->set_parameter(thd, i, it_args.ref())) { DBUG_PRINT("error", ("set variable 2 failed")); err_status= TRUE; @@ -2065,7 +2065,7 @@ sp_head::execute_procedure(THD *thd, List *args) DBUG_ASSERT(srp); - if (srp->set_value(thd, octx, nctx->get_item_addr(i))) + if (srp->set_value(thd, octx, nctx->get_variable_addr(i))) { DBUG_PRINT("error", ("set value failed")); err_status= TRUE; @@ -2073,7 +2073,7 @@ sp_head::execute_procedure(THD *thd, List *args) } Send_field *out_param_info= new (thd->mem_root) Send_field(); - nctx->get_item(i)->make_field(thd, out_param_info); + nctx->get_parameter(i)->make_field(thd, out_param_info); out_param_info->db_name= m_db.str; out_param_info->table_name= m_name.str; out_param_info->org_table_name= m_name.str; @@ -4116,7 +4116,7 @@ sp_instr_cursor_copy_struct::exec_core(THD *thd, uint *nextp) { DBUG_ENTER("sp_instr_cursor_copy_struct::exec_core"); int ret= 0; - Item_field_row *row= (Item_field_row*) thd->spcont->get_item(m_var); + Item_field_row *row= (Item_field_row*) thd->spcont->get_variable(m_var); DBUG_ASSERT(row->type_handler() == &type_handler_row); /* diff --git a/sql/sp_rcontext.cc b/sql/sp_rcontext.cc index 43d033ad83e..159a25e7594 100644 --- a/sql/sp_rcontext.cc +++ b/sql/sp_rcontext.cc @@ -317,7 +317,7 @@ bool sp_rcontext::init_var_items(THD *thd, uint num_vars= m_root_parsing_ctx->max_var_index(); m_var_items.reset( - static_cast ( + static_cast ( thd->alloc(num_vars * sizeof (Item *))), num_vars); @@ -634,7 +634,7 @@ int sp_rcontext::set_variable_row_field_by_name(THD *thd, uint var_idx, int sp_rcontext::set_variable_row(THD *thd, uint var_idx, List &items) { DBUG_ENTER("sp_rcontext::set_variable_row"); - DBUG_ASSERT(get_item(var_idx)->cols() == items.elements); + DBUG_ASSERT(get_variable(var_idx)->cols() == items.elements); Virtual_tmp_table *vtable= virtual_tmp_table_for_row(var_idx); Sp_eval_expr_state state(thd); DBUG_RETURN(vtable->sp_set_all_fields_from_item_list(thd, items)); @@ -643,8 +643,8 @@ int sp_rcontext::set_variable_row(THD *thd, uint var_idx, List &items) Virtual_tmp_table *sp_rcontext::virtual_tmp_table_for_row(uint var_idx) { - DBUG_ASSERT(get_item(var_idx)->type() == Item::FIELD_ITEM); - DBUG_ASSERT(get_item(var_idx)->cmp_type() == ROW_RESULT); + DBUG_ASSERT(get_variable(var_idx)->type() == Item::FIELD_ITEM); + DBUG_ASSERT(get_variable(var_idx)->cmp_type() == ROW_RESULT); Field *field= m_var_table->field[var_idx]; Virtual_tmp_table **ptable= field->virtual_tmp_table_addr(); DBUG_ASSERT(ptable); @@ -809,7 +809,7 @@ int sp_cursor::fetch(THD *thd, List *vars, bool error_on_no_data) if (vars->elements != result.get_field_count() && (vars->elements != 1 || result.get_field_count() != - thd->spcont->get_item(vars->head()->offset)->cols())) + thd->spcont->get_variable(vars->head()->offset)->cols())) { my_message(ER_SP_WRONG_NO_OF_FETCH_ARGS, ER_THD(thd, ER_SP_WRONG_NO_OF_FETCH_ARGS), MYF(0)); @@ -907,7 +907,7 @@ int sp_cursor::Select_fetch_into_spvars::send_data(List &items) on attempt to assign a scalar value to a ROW variable. */ return spvar_list->elements == 1 && - (item= thd->spcont->get_item(spvar_list->head()->offset)) && + (item= thd->spcont->get_variable(spvar_list->head()->offset)) && item->type_handler() == &type_handler_row && item->cols() == items.elements ? thd->spcont->set_variable_row(thd, spvar_list->head()->offset, items) : diff --git a/sql/sp_rcontext.h b/sql/sp_rcontext.h index ca438107593..00816b5ea8a 100644 --- a/sql/sp_rcontext.h +++ b/sql/sp_rcontext.h @@ -189,6 +189,11 @@ public: // SP-variables. ///////////////////////////////////////////////////////////////////////// + uint argument_count() const + { + return m_root_parsing_ctx->context_var_count(); + } + int set_variable(THD *thd, uint var_idx, Item **value); int set_variable_row_field(THD *thd, uint var_idx, uint field_idx, Item **value); @@ -196,11 +201,24 @@ public: const LEX_CSTRING &field_name, Item **value); int set_variable_row(THD *thd, uint var_idx, List &items); - Item *get_item(uint var_idx) const + + int set_parameter(THD *thd, uint var_idx, Item **value) + { + DBUG_ASSERT(var_idx < argument_count()); + return set_variable(thd, var_idx, value); + } + + Item_field *get_variable(uint var_idx) const { return m_var_items[var_idx]; } - Item **get_item_addr(uint var_idx) const - { return m_var_items.array() + var_idx; } + Item **get_variable_addr(uint var_idx) const + { return ((Item **) m_var_items.array()) + var_idx; } + + Item_field *get_parameter(uint var_idx) const + { + DBUG_ASSERT(var_idx < argument_count()); + return get_variable(var_idx); + } bool find_row_field_by_name_or_error(uint *field_idx, uint var_idx, const LEX_CSTRING &field_name); @@ -379,7 +397,7 @@ private: /// Collection of Item_field proxies, each of them points to the /// corresponding field in m_var_table. - Bounds_checked_array m_var_items; + Bounds_checked_array m_var_items; /// This is a pointer to a field, which should contain return value for /// stored functions (only). For stored procedures, this pointer is NULL. diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 147f4d6eddf..0b776a2e2fe 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -3631,7 +3631,7 @@ int select_dumpvar::prepare(List &list, SELECT_LEX_UNIT *u) mvsp->type_handler() == &type_handler_row) { // SELECT INTO row_type_sp_variable - if (thd->spcont->get_item(mvsp->offset)->cols() != list.elements) + if (thd->spcont->get_variable(mvsp->offset)->cols() != list.elements) goto error; m_var_sp_row= mvsp; return 0; From d69642deddf4f8d51f8c6807361576451334f1f9 Mon Sep 17 00:00:00 2001 From: Monty Date: Fri, 2 Feb 2018 11:08:36 +0200 Subject: [PATCH 4/7] Added name to MEM_ROOT for esier debugging This will make it easier to how memory allocation is done when debugging with either DBUG or gdb. Will especially help when debugging stored procedures Main change is a name argument as second argument to init_alloc_root() init_sql_alloc() Other things: - Added DBUG_ENTER/EXIT to some Virtual_tmp_table functions --- client/completion_hash.cc | 2 +- client/mysql.cc | 2 +- client/mysqldump.c | 2 +- client/mysqltest.cc | 2 +- include/my_alloc.h | 1 + include/my_sys.h | 5 +++-- include/mysql.h.pp | 1 + libmysqld/emb_qcache.cc | 2 +- libmysqld/lib_sql.cc | 4 ++-- libmysqld/libmysql.c | 7 ++++--- mysys/my_alloc.c | 19 +++++++++++++------ mysys/my_default.c | 4 ++-- mysys/my_lib.c | 4 ++-- mysys/tree.c | 3 ++- sql-common/client.c | 4 ++-- sql-common/client_plugin.c | 2 +- sql/event_data_objects.cc | 2 +- sql/ha_partition.cc | 6 +++--- sql/log.cc | 3 ++- sql/mysqld.cc | 4 ++-- sql/opt_range.cc | 24 ++++++++++++++++-------- sql/opt_subselect.cc | 3 ++- sql/rpl_handler.h | 2 +- sql/rpl_tblmap.cc | 3 ++- sql/sp_head.cc | 13 ++++++++----- sql/sql_acl.cc | 6 +++--- sql/sql_class.cc | 4 ++-- sql/sql_class.h | 6 ++++-- sql/sql_error.cc | 2 +- sql/sql_handler.cc | 3 ++- sql/sql_lex.cc | 4 ++-- sql/sql_plugin.cc | 8 ++++---- sql/sql_prepare.cc | 9 ++++++--- sql/sql_repl.cc | 5 +++-- sql/sql_select.cc | 17 ++++++++++------- sql/sql_servers.cc | 5 +++-- sql/sql_show.cc | 7 ++++--- sql/sql_table.cc | 3 ++- sql/sql_trigger.cc | 10 ++++++---- sql/sql_udf.cc | 2 +- sql/table.cc | 12 +++++++----- sql/table.h | 3 ++- sql/table_cache.cc | 3 ++- sql/thr_malloc.cc | 7 ++++--- sql/thr_malloc.h | 4 ++-- sql/tztime.cc | 9 +++++---- storage/cassandra/ha_cassandra.cc | 2 +- storage/csv/ha_tina.cc | 4 ++-- storage/federated/ha_federated.cc | 2 +- storage/federatedx/ha_federatedx.cc | 4 ++-- storage/maria/ma_check.c | 5 +++-- storage/maria/ma_ft_boolean_search.c | 2 +- storage/maria/ma_ft_parser.c | 3 ++- storage/mroonga/mrn_mysql_compat.h | 13 +++++++++++-- storage/myisam/ft_boolean_search.c | 2 +- storage/myisam/ft_parser.c | 3 ++- storage/myisam/mi_check.c | 5 +++-- storage/myisammrg/ha_myisammrg.cc | 2 +- storage/oqgraph/ha_oqgraph.cc | 2 +- storage/spider/hs_client/hs_compat.h | 7 ++++++- 60 files changed, 187 insertions(+), 122 deletions(-) diff --git a/client/completion_hash.cc b/client/completion_hash.cc index c170b69de2d..be89dd41441 100644 --- a/client/completion_hash.cc +++ b/client/completion_hash.cc @@ -49,7 +49,7 @@ int completion_hash_init(HashTable *ht, uint nSize) ht->initialized = 0; return FAILURE; } - init_alloc_root(&ht->mem_root, 8192, 0, MYF(0)); + init_alloc_root(&ht->mem_root, "completion_hash", 8192, 0, MYF(0)); ht->pHashFunction = hashpjw; ht->nTableSize = nSize; ht->initialized = 1; diff --git a/client/mysql.cc b/client/mysql.cc index 2efa46a571d..929fba73ab5 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -1207,7 +1207,7 @@ int main(int argc,char *argv[]) } glob_buffer.realloc(512); completion_hash_init(&ht, 128); - init_alloc_root(&hash_mem_root, 16384, 0, MYF(0)); + init_alloc_root(&hash_mem_root, "hash", 16384, 0, MYF(0)); if (sql_connect(current_host,current_db,current_user,opt_password, opt_silent)) { diff --git a/client/mysqldump.c b/client/mysqldump.c index 57d087b331b..9087cdcdccd 100644 --- a/client/mysqldump.c +++ b/client/mysqldump.c @@ -4938,7 +4938,7 @@ static int dump_selected_tables(char *db, char **table_names, int tables) if (init_dumping(db, init_dumping_tables)) DBUG_RETURN(1); - init_alloc_root(&glob_root, 8192, 0, MYF(0)); + init_alloc_root(&glob_root, "glob_root", 8192, 0, MYF(0)); if (!(dump_tables= pos= (char**) alloc_root(&glob_root, tables * sizeof(char *)))) die(EX_EOM, "alloc_root failure."); diff --git a/client/mysqltest.cc b/client/mysqltest.cc index 6fcd44580a4..da959f48652 100644 --- a/client/mysqltest.cc +++ b/client/mysqltest.cc @@ -9117,7 +9117,7 @@ int main(int argc, char **argv) #endif init_dynamic_string(&ds_res, "", 2048, 2048); - init_alloc_root(&require_file_root, 1024, 1024, MYF(0)); + init_alloc_root(&require_file_root, "require_file", 1024, 1024, MYF(0)); parse_args(argc, argv); diff --git a/include/my_alloc.h b/include/my_alloc.h index b461065eb7c..3ba8a02fc48 100644 --- a/include/my_alloc.h +++ b/include/my_alloc.h @@ -52,6 +52,7 @@ typedef struct st_mem_root unsigned int first_block_usage; void (*error_handler)(void); + const char *name; } MEM_ROOT; #ifdef __cplusplus diff --git a/include/my_sys.h b/include/my_sys.h index 99c1dacfcaa..537be951e26 100644 --- a/include/my_sys.h +++ b/include/my_sys.h @@ -894,8 +894,9 @@ extern void my_free_lock(void *ptr); #define alloc_root_inited(A) ((A)->min_malloc != 0) #define ALLOC_ROOT_MIN_BLOCK_SIZE (MALLOC_OVERHEAD + sizeof(USED_MEM) + 8) #define clear_alloc_root(A) do { (A)->free= (A)->used= (A)->pre_alloc= 0; (A)->min_malloc=0;} while(0) -extern void init_alloc_root(MEM_ROOT *mem_root, size_t block_size, - size_t pre_alloc_size, myf my_flags); +extern void init_alloc_root(MEM_ROOT *mem_root, const char *name, + size_t block_size, size_t pre_alloc_size, + myf my_flags); extern void *alloc_root(MEM_ROOT *mem_root, size_t Size); extern void *multi_alloc_root(MEM_ROOT *mem_root, ...); extern void free_root(MEM_ROOT *root, myf MyFLAGS); diff --git a/include/mysql.h.pp b/include/mysql.h.pp index 0284eb2b3ca..51e2e655a56 100644 --- a/include/mysql.h.pp +++ b/include/mysql.h.pp @@ -240,6 +240,7 @@ typedef struct st_mem_root unsigned int block_num; unsigned int first_block_usage; void (*error_handler)(void); + const char *name; } MEM_ROOT; typedef struct st_typelib { unsigned int count; diff --git a/libmysqld/emb_qcache.cc b/libmysqld/emb_qcache.cc index 429b16b2dee..5b990ddf8d0 100644 --- a/libmysqld/emb_qcache.cc +++ b/libmysqld/emb_qcache.cc @@ -418,7 +418,7 @@ int emb_load_querycache_result(THD *thd, Querycache_stream *src) if (!data) goto err; - init_alloc_root(&data->alloc, 8192,0,MYF(0)); + init_alloc_root(&data->alloc, "embedded_query_cache", 8192,0,MYF(0)); f_alloc= &data->alloc; data->fields= src->load_int(); diff --git a/libmysqld/lib_sql.cc b/libmysqld/lib_sql.cc index 25ef6e9b18e..e715836b6ac 100644 --- a/libmysqld/lib_sql.cc +++ b/libmysqld/lib_sql.cc @@ -655,7 +655,7 @@ void init_embedded_mysql(MYSQL *mysql, int client_flag) thd->mysql= mysql; mysql->server_version= server_version; mysql->client_flag= client_flag; - init_alloc_root(&mysql->field_alloc, 8192, 0, MYF(0)); + init_alloc_root(&mysql->field_alloc, "fields", 8192, 0, MYF(0)); } /** @@ -972,7 +972,7 @@ int Protocol::begin_dataset() return 1; alloc= &data->alloc; /* Assume rowlength < 8192 */ - init_alloc_root(alloc, 8192, 0, MYF(0)); + init_alloc_root(alloc, "protocol", 8192, 0, MYF(0)); alloc->min_malloc= sizeof(MYSQL_ROWS); return 0; } diff --git a/libmysqld/libmysql.c b/libmysqld/libmysql.c index 767afed06b1..5aaa7e01fc9 100644 --- a/libmysqld/libmysql.c +++ b/libmysqld/libmysql.c @@ -1533,8 +1533,9 @@ mysql_stmt_init(MYSQL *mysql) DBUG_RETURN(NULL); } - init_alloc_root(&stmt->mem_root, 2048,2048, MYF(MY_THREAD_SPECIFIC)); - init_alloc_root(&stmt->result.alloc, 4096, 4096, MYF(MY_THREAD_SPECIFIC)); + init_alloc_root(&stmt->mem_root, "stmt", 2048,2048, MYF(MY_THREAD_SPECIFIC)); + init_alloc_root(&stmt->result.alloc, "result", 4096, 4096, + MYF(MY_THREAD_SPECIFIC)); stmt->result.alloc.min_malloc= sizeof(MYSQL_ROWS); mysql->stmts= list_add(mysql->stmts, &stmt->list); stmt->list.data= stmt; @@ -1545,7 +1546,7 @@ mysql_stmt_init(MYSQL *mysql) strmov(stmt->sqlstate, not_error_sqlstate); /* The rest of statement members was bzeroed inside malloc */ - init_alloc_root(&stmt->extension->fields_mem_root, 2048, 0, + init_alloc_root(&stmt->extension->fields_mem_root, "extension", 2048, 0, MYF(MY_THREAD_SPECIFIC)); DBUG_RETURN(stmt); diff --git a/mysys/my_alloc.c b/mysys/my_alloc.c index b2a1264bd2b..0dbd571c7fd 100644 --- a/mysys/my_alloc.c +++ b/mysys/my_alloc.c @@ -32,6 +32,7 @@ SYNOPSIS init_alloc_root() mem_root - memory root to initialize + name - name of memroot (for debugging) block_size - size of chunks (blocks) used for memory allocation (It is external size of chunk i.e. it should include memory required for internal structures, thus it @@ -51,13 +52,13 @@ Because of this, we store in MY_THREAD_SPECIFIC as bit 1 in block_size */ -void init_alloc_root(MEM_ROOT *mem_root, size_t block_size, +void init_alloc_root(MEM_ROOT *mem_root, const char *name, size_t block_size, size_t pre_alloc_size __attribute__((unused)), myf my_flags) { DBUG_ENTER("init_alloc_root"); - DBUG_PRINT("enter",("root: %p prealloc: %zu", mem_root, - pre_alloc_size)); + DBUG_PRINT("enter",("root: %p name: %s prealloc: %zu", mem_root, + name, pre_alloc_size)); mem_root->free= mem_root->used= mem_root->pre_alloc= 0; mem_root->min_malloc= 32; @@ -69,6 +70,7 @@ void init_alloc_root(MEM_ROOT *mem_root, size_t block_size, mem_root->block_num= 4; /* We shift this with >>2 */ mem_root->first_block_usage= 0; mem_root->total_alloc= 0; + mem_root->name= name; #if !(defined(HAVE_valgrind) && defined(EXTRA_DEBUG)) if (pre_alloc_size) @@ -172,7 +174,7 @@ void *alloc_root(MEM_ROOT *mem_root, size_t length) #if defined(HAVE_valgrind) && defined(EXTRA_DEBUG) reg1 USED_MEM *next; DBUG_ENTER("alloc_root"); - DBUG_PRINT("enter",("root: %p", mem_root)); + DBUG_PRINT("enter",("root: %p name: %s", mem_root, mem_root->name)); DBUG_ASSERT(alloc_root_inited(mem_root)); @@ -207,7 +209,7 @@ void *alloc_root(MEM_ROOT *mem_root, size_t length) reg1 USED_MEM *next= 0; reg2 USED_MEM **prev; DBUG_ENTER("alloc_root"); - DBUG_PRINT("enter",("root: %p", mem_root)); + DBUG_PRINT("enter",("root: %p name: %s", mem_root, mem_root->name)); DBUG_ASSERT(alloc_root_inited(mem_root)); DBUG_EXECUTE_IF("simulate_out_of_memory", @@ -298,6 +300,10 @@ void *multi_alloc_root(MEM_ROOT *root, ...) char **ptr, *start, *res; size_t tot_length, length; DBUG_ENTER("multi_alloc_root"); + /* + We don't need to do DBUG_PRINT here as it will be done when alloc_root + is called + */ va_start(args, root); tot_length= 0; @@ -382,7 +388,8 @@ void free_root(MEM_ROOT *root, myf MyFlags) { reg1 USED_MEM *next,*old; DBUG_ENTER("free_root"); - DBUG_PRINT("enter",("root: %p flags: %u", root, (uint) MyFlags)); + DBUG_PRINT("enter",("root: %p name: %s flags: %u", root, root->name, + (uint) MyFlags)); #if !(defined(HAVE_valgrind) && defined(EXTRA_DEBUG)) /* diff --git a/mysys/my_default.c b/mysys/my_default.c index 1c8e976d8dc..eed87341d8e 100644 --- a/mysys/my_default.c +++ b/mysys/my_default.c @@ -518,7 +518,7 @@ int my_load_defaults(const char *conf_file, const char **groups, uint args_sep= my_getopt_use_args_separator ? 1 : 0; DBUG_ENTER("load_defaults"); - init_alloc_root(&alloc, 512, 0, MYF(0)); + init_alloc_root(&alloc, "my_load_defaults", 512, 0, MYF(0)); if ((dirs= init_default_directories(&alloc)) == NULL) goto err; /* @@ -1041,7 +1041,7 @@ void my_print_default_files(const char *conf_file) { const char **dirs; MEM_ROOT alloc; - init_alloc_root(&alloc, 512, 0, MYF(0)); + init_alloc_root(&alloc, "my_print_defaults", 512, 0, MYF(0)); if ((dirs= init_default_directories(&alloc)) == NULL) { diff --git a/mysys/my_lib.c b/mysys/my_lib.c index d5f54f00b85..9c465fd5e68 100644 --- a/mysys/my_lib.c +++ b/mysys/my_lib.c @@ -136,7 +136,7 @@ MY_DIR *my_dir(const char *path, myf MyFlags) MYF(MyFlags))) goto error; - init_alloc_root(&dirh->root, NAMES_START_SIZE, NAMES_START_SIZE, + init_alloc_root(&dirh->root, "dir", NAMES_START_SIZE, NAMES_START_SIZE, MYF(MyFlags)); dp= (struct dirent*) dirent_tmp; @@ -245,7 +245,7 @@ MY_DIR *my_dir(const char *path, myf MyFlags) MYF(MyFlags))) goto error; - init_alloc_root(&dirh->root, NAMES_START_SIZE, NAMES_START_SIZE, + init_alloc_root(&dirh->root, "dir", NAMES_START_SIZE, NAMES_START_SIZE, MYF(MyFlags)); if ((handle=_findfirst(tmp_path,&find)) == -1L) diff --git a/mysys/tree.c b/mysys/tree.c index c71925df7db..0dc57b6fffa 100644 --- a/mysys/tree.c +++ b/mysys/tree.c @@ -130,7 +130,8 @@ void init_tree(TREE *tree, size_t default_alloc_size, size_t memory_limit, } if (!(tree->with_delete= MY_TEST(my_flags & MY_TREE_WITH_DELETE))) { - init_alloc_root(&tree->mem_root, default_alloc_size, 0, MYF(my_flags)); + init_alloc_root(&tree->mem_root, "tree", default_alloc_size, 0, + MYF(my_flags)); tree->mem_root.min_malloc= sizeof(TREE_ELEMENT)+tree->size_of_element; } DBUG_VOID_RETURN; diff --git a/sql-common/client.c b/sql-common/client.c index 163589a3978..b7a23e722f4 100644 --- a/sql-common/client.c +++ b/sql-common/client.c @@ -740,7 +740,7 @@ void free_old_query(MYSQL *mysql) if (mysql->fields) free_root(&mysql->field_alloc,MYF(0)); /* Assume rowlength < 8192 */ - init_alloc_root(&mysql->field_alloc, 8192, 0, + init_alloc_root(&mysql->field_alloc, "fields", 8192, 0, MYF(mysql->options.use_thread_specific_memory ? MY_THREAD_SPECIFIC : 0)); mysql->fields= 0; @@ -1464,7 +1464,7 @@ MYSQL_DATA *cli_read_rows(MYSQL *mysql,MYSQL_FIELD *mysql_fields, DBUG_RETURN(0); } /* Assume rowlength < 8192 */ - init_alloc_root(&result->alloc, 8192, 0, + init_alloc_root(&result->alloc, "result", 8192, 0, MYF(mysql->options.use_thread_specific_memory ? MY_THREAD_SPECIFIC : 0)); result->alloc.min_malloc=sizeof(MYSQL_ROWS); diff --git a/sql-common/client_plugin.c b/sql-common/client_plugin.c index f93e50125c5..f81660f8986 100644 --- a/sql-common/client_plugin.c +++ b/sql-common/client_plugin.c @@ -251,7 +251,7 @@ int mysql_client_plugin_init() bzero(&mysql, sizeof(mysql)); /* dummy mysql for set_mysql_extended_error */ mysql_mutex_init(0, &LOCK_load_client_plugin, MY_MUTEX_INIT_SLOW); - init_alloc_root(&mem_root, 128, 128, MYF(0)); + init_alloc_root(&mem_root, "client_plugin", 128, 128, MYF(0)); bzero(&plugin_list, sizeof(plugin_list)); diff --git a/sql/event_data_objects.cc b/sql/event_data_objects.cc index ef334233085..d42a503e9d2 100644 --- a/sql/event_data_objects.cc +++ b/sql/event_data_objects.cc @@ -209,7 +209,7 @@ Event_basic::Event_basic() { DBUG_ENTER("Event_basic::Event_basic"); /* init memory root */ - init_sql_alloc(&mem_root, 256, 512, MYF(0)); + init_sql_alloc(&mem_root, "Event_basic", 256, 512, MYF(0)); dbname.str= name.str= NULL; dbname.length= name.length= 0; time_zone= NULL; diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc index 4a40e0c1fc4..e0e4418ab22 100644 --- a/sql/ha_partition.cc +++ b/sql/ha_partition.cc @@ -249,7 +249,7 @@ ha_partition::ha_partition(handlerton *hton, TABLE_SHARE *share) :handler(hton, share) { DBUG_ENTER("ha_partition::ha_partition(table)"); - init_alloc_root(&m_mem_root, 512, 512, MYF(0)); + init_alloc_root(&m_mem_root, "ha_partition", 512, 512, MYF(0)); init_handler_variables(); DBUG_VOID_RETURN; } @@ -271,7 +271,7 @@ ha_partition::ha_partition(handlerton *hton, partition_info *part_info) { DBUG_ENTER("ha_partition::ha_partition(part_info)"); DBUG_ASSERT(part_info); - init_alloc_root(&m_mem_root, 512, 512, MYF(0)); + init_alloc_root(&m_mem_root, "ha_partition", 512, 512, MYF(0)); init_handler_variables(); m_part_info= part_info; m_create_handler= TRUE; @@ -298,7 +298,7 @@ ha_partition::ha_partition(handlerton *hton, TABLE_SHARE *share, :handler(hton, share) { DBUG_ENTER("ha_partition::ha_partition(clone)"); - init_alloc_root(&m_mem_root, 512, 512, MYF(0)); + init_alloc_root(&m_mem_root, "ha_partition", 512, 512, MYF(0)); init_handler_variables(); m_part_info= part_info_arg; m_create_handler= TRUE; diff --git a/sql/log.cc b/sql/log.cc index 62d98b9c0da..b6867bf6566 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -10012,7 +10012,8 @@ int TC_LOG_BINLOG::recover(LOG_INFO *linfo, const char *last_log_name, goto err1; if (do_xa) - init_alloc_root(&mem_root, TC_LOG_PAGE_SIZE, TC_LOG_PAGE_SIZE, MYF(0)); + init_alloc_root(&mem_root, "TC_LOG_BINLOG", TC_LOG_PAGE_SIZE, + TC_LOG_PAGE_SIZE, MYF(0)); fdle->flags&= ~LOG_EVENT_BINLOG_IN_USE_F; // abort on the first error diff --git a/sql/mysqld.cc b/sql/mysqld.cc index a53a031eca7..831b7b4be5d 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -1347,7 +1347,7 @@ private: void Buffered_logs::init() { - init_alloc_root(&m_root, 1024, 0, MYF(0)); + init_alloc_root(&m_root, "Buffered_logs", 1024, 0, MYF(0)); } void Buffered_logs::cleanup() @@ -8614,7 +8614,7 @@ static int option_cmp(my_option *a, my_option *b) static void print_help() { MEM_ROOT mem_root; - init_alloc_root(&mem_root, 4096, 4096, MYF(0)); + init_alloc_root(&mem_root, "help", 4096, 4096, MYF(0)); pop_dynamic(&all_options); add_many_options(&all_options, pfs_early_options, diff --git a/sql/opt_range.cc b/sql/opt_range.cc index 3294b8f11f9..9c5dbc1c470 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -1253,7 +1253,8 @@ QUICK_RANGE_SELECT::QUICK_RANGE_SELECT(THD *thd, TABLE *table, uint key_nr, if (!no_alloc && !parent_alloc) { // Allocates everything through the internal memroot - init_sql_alloc(&alloc, thd->variables.range_alloc_block_size, 0, + init_sql_alloc(&alloc, "QUICK_RANGE_SELECT", + thd->variables.range_alloc_block_size, 0, MYF(MY_THREAD_SPECIFIC)); thd->mem_root= &alloc; } @@ -1350,7 +1351,8 @@ QUICK_INDEX_SORT_SELECT::QUICK_INDEX_SORT_SELECT(THD *thd_param, index= MAX_KEY; head= table; bzero(&read_record, sizeof(read_record)); - init_sql_alloc(&alloc, thd->variables.range_alloc_block_size, 0, + init_sql_alloc(&alloc, "QUICK_INDEX_SORT_SELECT", + thd->variables.range_alloc_block_size, 0, MYF(MY_THREAD_SPECIFIC)); DBUG_VOID_RETURN; } @@ -1421,7 +1423,8 @@ QUICK_ROR_INTERSECT_SELECT::QUICK_ROR_INTERSECT_SELECT(THD *thd_param, head= table; record= head->record[0]; if (!parent_alloc) - init_sql_alloc(&alloc, thd->variables.range_alloc_block_size, 0, + init_sql_alloc(&alloc, "QUICK_ROR_INTERSECT_SELECT", + thd->variables.range_alloc_block_size, 0, MYF(MY_THREAD_SPECIFIC)); else bzero(&alloc, sizeof(MEM_ROOT)); @@ -1697,7 +1700,8 @@ QUICK_ROR_UNION_SELECT::QUICK_ROR_UNION_SELECT(THD *thd_param, head= table; rowid_length= table->file->ref_length; record= head->record[0]; - init_sql_alloc(&alloc, thd->variables.range_alloc_block_size, 0, + init_sql_alloc(&alloc, "QUICK_ROR_UNION_SELECT", + thd->variables.range_alloc_block_size, 0, MYF(MY_THREAD_SPECIFIC)); thd_param->mem_root= &alloc; } @@ -2452,7 +2456,8 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use, param.possible_keys.clear_all(); thd->no_errors=1; // Don't warn about NULL - init_sql_alloc(&alloc, thd->variables.range_alloc_block_size, 0, + init_sql_alloc(&alloc, "test_quick_select", + thd->variables.range_alloc_block_size, 0, MYF(MY_THREAD_SPECIFIC)); if (!(param.key_parts= (KEY_PART*) alloc_root(&alloc, @@ -3026,7 +3031,8 @@ bool calculate_cond_selectivity_for_table(THD *thd, TABLE *table, Item **cond) SEL_TREE *tree; double rows; - init_sql_alloc(&alloc, thd->variables.range_alloc_block_size, 0, + init_sql_alloc(&alloc, "calculate_cond_selectivity_for_table", + thd->variables.range_alloc_block_size, 0, MYF(MY_THREAD_SPECIFIC)); param.thd= thd; param.mem_root= &alloc; @@ -3443,7 +3449,8 @@ bool prune_partitions(THD *thd, TABLE *table, Item *pprune_cond) my_bitmap_map *old_sets[2]; prune_param.part_info= part_info; - init_sql_alloc(&alloc, thd->variables.range_alloc_block_size, 0, + init_sql_alloc(&alloc, "prune_partitions", + thd->variables.range_alloc_block_size, 0, MYF(MY_THREAD_SPECIFIC)); range_par->mem_root= &alloc; range_par->old_root= thd->mem_root; @@ -13611,7 +13618,8 @@ QUICK_GROUP_MIN_MAX_SELECT(TABLE *table, JOIN *join_arg, bool have_min_arg, DBUG_ASSERT(!parent_alloc); if (!parent_alloc) { - init_sql_alloc(&alloc, join->thd->variables.range_alloc_block_size, 0, + init_sql_alloc(&alloc, "QUICK_GROUP_MIN_MAX_SELECT", + join->thd->variables.range_alloc_block_size, 0, MYF(MY_THREAD_SPECIFIC)); join->thd->mem_root= &alloc; } diff --git a/sql/opt_subselect.cc b/sql/opt_subselect.cc index b11fc34c428..3b98b650f8f 100644 --- a/sql/opt_subselect.cc +++ b/sql/opt_subselect.cc @@ -4118,7 +4118,8 @@ SJ_TMP_TABLE::create_sj_weedout_tmp_table(THD *thd) using_unique_constraint= TRUE; /* STEP 3: Allocate memory for temptable description */ - init_sql_alloc(&own_root, TABLE_ALLOC_BLOCK_SIZE, 0, MYF(MY_THREAD_SPECIFIC)); + init_sql_alloc(&own_root, "SJ_TMP_TABLE", + TABLE_ALLOC_BLOCK_SIZE, 0, MYF(MY_THREAD_SPECIFIC)); if (!multi_alloc_root(&own_root, &table, sizeof(*table), &share, sizeof(*share), diff --git a/sql/rpl_handler.h b/sql/rpl_handler.h index afcfd9d55b1..71550f0a577 100644 --- a/sql/rpl_handler.h +++ b/sql/rpl_handler.h @@ -121,7 +121,7 @@ public: inited= FALSE; if (my_rwlock_init(&lock, NULL)) return; - init_sql_alloc(&memroot, 1024, 0, MYF(0)); + init_sql_alloc(&memroot, "Delegate", 1024, 0, MYF(0)); inited= TRUE; } ~Delegate() diff --git a/sql/rpl_tblmap.cc b/sql/rpl_tblmap.cc index 48111bc5d0a..06e1d19d0c8 100644 --- a/sql/rpl_tblmap.cc +++ b/sql/rpl_tblmap.cc @@ -46,7 +46,8 @@ table_mapping::table_mapping() offsetof(entry,table_id),sizeof(ulong), 0,0,0); /* We don't preallocate any block, this is consistent with m_free=0 above */ - init_alloc_root(&m_mem_root, TABLE_ID_HASH_SIZE*sizeof(entry), 0, MYF(0)); + init_alloc_root(&m_mem_root, "table_mapping", + TABLE_ID_HASH_SIZE*sizeof(entry), 0, MYF(0)); DBUG_VOID_RETURN; } diff --git a/sql/sp_head.cc b/sql/sp_head.cc index 9351babdab5..6a4e274d00a 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -471,7 +471,8 @@ sp_head::operator new(size_t size) throw() MEM_ROOT own_root; sp_head *sp; - init_sql_alloc(&own_root, MEM_ROOT_BLOCK_SIZE, MEM_ROOT_PREALLOC, MYF(0)); + init_sql_alloc(&own_root, "sp_head", + MEM_ROOT_BLOCK_SIZE, MEM_ROOT_PREALLOC, MYF(0)); sp= (sp_head *) alloc_root(&own_root, size); if (sp == NULL) DBUG_RETURN(NULL); @@ -993,7 +994,8 @@ sp_head::execute(THD *thd, bool merge_da_on_success) thd->select_number+= m_select_number; /* init per-instruction memroot */ - init_sql_alloc(&execute_mem_root, MEM_ROOT_BLOCK_SIZE, 0, MYF(0)); + init_sql_alloc(&execute_mem_root, "per_instruction_memroot", + MEM_ROOT_BLOCK_SIZE, 0, MYF(0)); DBUG_ASSERT(!(m_flags & IS_INVOKED)); m_flags|= IS_INVOKED; @@ -1507,7 +1509,6 @@ sp_head::execute_trigger(THD *thd, MEM_ROOT call_mem_root; Query_arena call_arena(&call_mem_root, Query_arena::STMT_INITIALIZED_FOR_SP); Query_arena backup_arena; - DBUG_ENTER("sp_head::execute_trigger"); DBUG_PRINT("info", ("trigger %s", m_name.str)); @@ -1563,7 +1564,8 @@ sp_head::execute_trigger(THD *thd, TODO: we should create sp_rcontext once per command and reuse it on subsequent executions of a trigger. */ - init_sql_alloc(&call_mem_root, MEM_ROOT_BLOCK_SIZE, 0, MYF(0)); + init_sql_alloc(&call_mem_root, "execute_trigger", MEM_ROOT_BLOCK_SIZE, 0, + MYF(0)); thd->set_n_backup_active_arena(&call_arena, &backup_arena); Row_definition_list defs; @@ -1676,7 +1678,8 @@ sp_head::execute_function(THD *thd, Item **argp, uint argcount, TODO: we should create sp_rcontext once per command and reuse it on subsequent executions of a function/trigger. */ - init_sql_alloc(&call_mem_root, MEM_ROOT_BLOCK_SIZE, 0, MYF(0)); + init_sql_alloc(&call_mem_root, "execute_function", MEM_ROOT_BLOCK_SIZE, 0, + MYF(0)); thd->set_n_backup_active_arena(&call_arena, &backup_arena); if (!(nctx= rcontext_create(thd, return_value_fld, argp, argcount))) diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 6d8506a8e43..b62e3ae74d2 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -1827,7 +1827,7 @@ static bool acl_load(THD *thd, const Grant_tables& tables) grant_version++; /* Privileges updated */ const Host_table& host_table= tables.host_table(); - init_sql_alloc(&acl_memroot, ACL_ALLOC_BLOCK_SIZE, 0, MYF(0)); + init_sql_alloc(&acl_memroot, "ACL", ACL_ALLOC_BLOCK_SIZE, 0, MYF(0)); if (host_table.table_exists()) // "host" table may not exist (e.g. in MySQL 5.6.7+) { if (host_table.init_read_record(&read_record_info, thd)) @@ -2243,7 +2243,7 @@ static bool acl_load(THD *thd, const Grant_tables& tables) DBUG_RETURN(TRUE); MEM_ROOT temp_root; - init_alloc_root(&temp_root, ACL_ALLOC_BLOCK_SIZE, 0, MYF(0)); + init_alloc_root(&temp_root, "ACL_tmp", ACL_ALLOC_BLOCK_SIZE, 0, MYF(0)); while (!(read_record_info.read_record(&read_record_info))) { char *hostname= safe_str(get_field(&temp_root, roles_mapping_table.host())); @@ -7310,7 +7310,7 @@ static bool grant_load(THD *thd, 0,0,0, (my_hash_get_key) get_grant_table, 0,0); (void) my_hash_init(&func_priv_hash, &my_charset_utf8_bin, 0,0,0, (my_hash_get_key) get_grant_table, 0,0); - init_sql_alloc(&grant_memroot, ACL_ALLOC_BLOCK_SIZE, 0, MYF(0)); + init_sql_alloc(&grant_memroot, "GRANT", ACL_ALLOC_BLOCK_SIZE, 0, MYF(0)); t_table= tables_priv.table(); c_table= columns_priv.table(); diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 0b776a2e2fe..c5c29e4efbc 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -782,8 +782,8 @@ THD::THD(my_thread_id id, bool is_wsrep_applier) the destructor works OK in case of an error. The main_mem_root will be re-initialized in init_for_queries(). */ - init_sql_alloc(&main_mem_root, ALLOC_ROOT_MIN_BLOCK_SIZE, 0, - MYF(MY_THREAD_SPECIFIC)); + init_sql_alloc(&main_mem_root, "THD::main_mem_root", + ALLOC_ROOT_MIN_BLOCK_SIZE, 0, MYF(MY_THREAD_SPECIFIC)); stmt_arena= this; thread_stack= 0; diff --git a/sql/sql_class.h b/sql/sql_class.h index 70a57fa22f7..cbd4b26f135 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -1791,7 +1791,8 @@ public: m_reopen_array(NULL), m_locked_tables_count(0) { - init_sql_alloc(&m_locked_tables_root, MEM_ROOT_BLOCK_SIZE, 0, + init_sql_alloc(&m_locked_tables_root, "Locked_tables_list", + MEM_ROOT_BLOCK_SIZE, 0, MYF(MY_THREAD_SPECIFIC)); } void unlock_locked_tables(THD *thd); @@ -2540,7 +2541,8 @@ public: { bzero((char*)this, sizeof(*this)); xid_state.xid.null(); - init_sql_alloc(&mem_root, ALLOC_ROOT_MIN_BLOCK_SIZE, 0, + init_sql_alloc(&mem_root, "THD::transactions", + ALLOC_ROOT_MIN_BLOCK_SIZE, 0, MYF(MY_THREAD_SPECIFIC)); } } transaction; diff --git a/sql/sql_error.cc b/sql/sql_error.cc index 144cf9d4a30..5d70a543771 100644 --- a/sql/sql_error.cc +++ b/sql/sql_error.cc @@ -506,7 +506,7 @@ void Warning_info::init() { /* Initialize sub structures */ DBUG_ASSERT(initialized == 0); - init_sql_alloc(&m_warn_root, WARN_ALLOC_BLOCK_SIZE, + init_sql_alloc(&m_warn_root, "Warning_info", WARN_ALLOC_BLOCK_SIZE, WARN_ALLOC_PREALLOC_SIZE, MYF(MY_THREAD_SPECIFIC)); initialized= 1; } diff --git a/sql/sql_handler.cc b/sql/sql_handler.cc index babb09a1267..a2b53045815 100644 --- a/sql/sql_handler.cc +++ b/sql/sql_handler.cc @@ -324,7 +324,8 @@ bool mysql_ha_open(THD *thd, TABLE_LIST *tables, SQL_HANDLER *reopen) /* copy data to sql_handler */ if (!(sql_handler= new SQL_HANDLER(thd))) goto err; - init_alloc_root(&sql_handler->mem_root, 1024, 0, MYF(MY_THREAD_SPECIFIC)); + init_alloc_root(&sql_handler->mem_root, "sql_handler", 1024, 0, + MYF(MY_THREAD_SPECIFIC)); sql_handler->db.length= strlen(tables->db); sql_handler->table_name.length= strlen(tables->table_name); diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index aed04842c90..b8245ce0a09 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -4810,8 +4810,8 @@ bool LEX::set_arena_for_set_stmt(Query_arena *backup) mem_root_for_set_stmt= new MEM_ROOT(); if (!(mem_root_for_set_stmt)) DBUG_RETURN(1); - init_sql_alloc(mem_root_for_set_stmt, ALLOC_ROOT_SET, ALLOC_ROOT_SET, - MYF(MY_THREAD_SPECIFIC)); + init_sql_alloc(mem_root_for_set_stmt, "set_stmt", + ALLOC_ROOT_SET, ALLOC_ROOT_SET, MYF(MY_THREAD_SPECIFIC)); } if (!(arena_for_set_stmt= new(mem_root_for_set_stmt) Query_arena_memroot(mem_root_for_set_stmt, diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc index be57c433b65..2b3ee37213a 100644 --- a/sql/sql_plugin.cc +++ b/sql/sql_plugin.cc @@ -1152,7 +1152,7 @@ static bool plugin_add(MEM_ROOT *tmp_root, goto err; if (my_hash_insert(&plugin_hash[plugin->type], (uchar*)tmp_plugin_ptr)) tmp_plugin_ptr->state= PLUGIN_IS_FREED; - init_alloc_root(&tmp_plugin_ptr->mem_root, 4096, 4096, MYF(0)); + init_alloc_root(&tmp_plugin_ptr->mem_root, "plugin", 4096, 4096, MYF(0)); if (name->str) DBUG_RETURN(FALSE); // all done @@ -1542,9 +1542,9 @@ int plugin_init(int *argc, char **argv, int flags) dlopen_count =0; - init_alloc_root(&plugin_mem_root, 4096, 4096, MYF(0)); - init_alloc_root(&plugin_vars_mem_root, 4096, 4096, MYF(0)); - init_alloc_root(&tmp_root, 4096, 4096, MYF(0)); + init_alloc_root(&plugin_mem_root, "plugin", 4096, 4096, MYF(0)); + init_alloc_root(&plugin_vars_mem_root, "plugin_vars", 4096, 4096, MYF(0)); + init_alloc_root(&tmp_root, "plugin_tmp", 4096, 4096, MYF(0)); if (my_hash_init(&bookmark_hash, &my_charset_bin, 32, 0, 0, get_bookmark_hash_key, NULL, HASH_UNIQUE)) diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index 33a7ee7f78f..2fd0f9c0531 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -3699,8 +3699,10 @@ Prepared_statement::Prepared_statement(THD *thd_arg) read_types(0), m_sql_mode(thd->variables.sql_mode) { - init_sql_alloc(&main_mem_root, thd_arg->variables.query_alloc_block_size, - thd_arg->variables.query_prealloc_size, MYF(MY_THREAD_SPECIFIC)); + init_sql_alloc(&main_mem_root, "Prepared_statement", + thd_arg->variables.query_alloc_block_size, + thd_arg->variables.query_prealloc_size, + MYF(MY_THREAD_SPECIFIC)); *last_error= '\0'; } @@ -5362,7 +5364,8 @@ bool Protocol_local::send_result_set_metadata(List *columns, uint) { DBUG_ASSERT(m_rset == 0 && !alloc_root_inited(&m_rset_root)); - init_sql_alloc(&m_rset_root, MEM_ROOT_BLOCK_SIZE, 0, MYF(MY_THREAD_SPECIFIC)); + init_sql_alloc(&m_rset_root, "send_result_set_metadata", + MEM_ROOT_BLOCK_SIZE, 0, MYF(MY_THREAD_SPECIFIC)); if (! (m_rset= new (&m_rset_root) List)) return TRUE; diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc index 91931b46771..11b9296c865 100644 --- a/sql/sql_repl.cc +++ b/sql/sql_repl.cc @@ -1196,8 +1196,9 @@ gtid_find_binlog_file(slave_connection_state *state, char *out_name, const char *errormsg= NULL; char buf[FN_REFLEN]; - init_alloc_root(&memroot, 10*(FN_REFLEN+sizeof(binlog_file_entry)), 0, - MYF(MY_THREAD_SPECIFIC)); + init_alloc_root(&memroot, "gtid_find_binlog_file", + 10*(FN_REFLEN+sizeof(binlog_file_entry)), + 0, MYF(MY_THREAD_SPECIFIC)); if (!(list= get_binlog_list(&memroot))) { errormsg= "Out of memory while looking for GTID position in binlog"; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 2784938b654..f88db1048ad 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -16890,7 +16890,8 @@ create_tmp_table(THD *thd, TMP_TABLE_PARAM *param, List &fields, if (param->precomputed_group_by) copy_func_count+= param->sum_func_count; - init_sql_alloc(&own_root, TABLE_ALLOC_BLOCK_SIZE, 0, MYF(MY_THREAD_SPECIFIC)); + init_sql_alloc(&own_root, "tmp_table", TABLE_ALLOC_BLOCK_SIZE, 0, + MYF(MY_THREAD_SPECIFIC)); if (!multi_alloc_root(&own_root, &table, sizeof(*table), @@ -17641,18 +17642,19 @@ bool Virtual_tmp_table::init(uint field_count) { uint *blob_field; uchar *bitmaps; + DBUG_ENTER("Virtual_tmp_table::init"); if (!multi_alloc_root(in_use->mem_root, &s, sizeof(*s), &field, (field_count + 1) * sizeof(Field*), &blob_field, (field_count + 1) * sizeof(uint), &bitmaps, bitmap_buffer_size(field_count) * 6, NullS)) - return true; + DBUG_RETURN(true); bzero(s, sizeof(*s)); s->blob_field= blob_field; setup_tmp_table_column_bitmaps(this, bitmaps, field_count); m_alloced_field_count= field_count; - return false; + DBUG_RETURN(false); }; @@ -17661,17 +17663,18 @@ bool Virtual_tmp_table::add(List &field_list) /* Create all fields and calculate the total length of record */ Spvar_definition *cdef; /* column definition */ List_iterator_fast it(field_list); - for ( ; (cdef= it++); ) + DBUG_ENTER("Virtual_tmp_table::add"); + while ((cdef= it++)) { Field *tmp; if (!(tmp= cdef->make_field(s, in_use->mem_root, 0, (uchar*) (f_maybe_null(cdef->pack_flag) ? "" : 0), f_maybe_null(cdef->pack_flag) ? 1 : 0, &cdef->field_name))) - return true; - add(tmp); + DBUG_RETURN(true); + add(tmp); } - return false; + DBUG_RETURN(false); } diff --git a/sql/sql_servers.cc b/sql/sql_servers.cc index 5e826dff2e0..58c5bb7dd78 100644 --- a/sql/sql_servers.cc +++ b/sql/sql_servers.cc @@ -154,7 +154,8 @@ bool servers_init(bool dont_read_servers_table) } /* Initialize the mem root for data */ - init_sql_alloc(&mem, ACL_ALLOC_BLOCK_SIZE, 0, MYF(MY_THREAD_SPECIFIC)); + init_sql_alloc(&mem, "servers", ACL_ALLOC_BLOCK_SIZE, 0, + MYF(MY_THREAD_SPECIFIC)); if (dont_read_servers_table) goto end; @@ -203,7 +204,7 @@ static bool servers_load(THD *thd, TABLE_LIST *tables) my_hash_reset(&servers_cache); free_root(&mem, MYF(0)); - init_sql_alloc(&mem, ACL_ALLOC_BLOCK_SIZE, 0, MYF(0)); + init_sql_alloc(&mem, "servers_load", ACL_ALLOC_BLOCK_SIZE, 0, MYF(0)); if (init_read_record(&read_record_info,thd,table=tables[0].table, NULL, NULL, 1,0, FALSE)) diff --git a/sql/sql_show.cc b/sql/sql_show.cc index e29e8658ae4..919e2871b40 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -4800,7 +4800,8 @@ static int fill_schema_table_from_frm(THD *thd, TABLE *table, if (schema_table->i_s_requested_object & OPEN_TRIGGER_ONLY) { - init_sql_alloc(&tbl.mem_root, TABLE_ALLOC_BLOCK_SIZE, 0, MYF(0)); + init_sql_alloc(&tbl.mem_root, "fill_schema_table_from_frm", + TABLE_ALLOC_BLOCK_SIZE, 0, MYF(0)); if (!Table_triggers_list::check_n_load(thd, db_name->str, table_name->str, &tbl, 1)) { @@ -5033,8 +5034,8 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond) goto err; /* Use tmp_mem_root to allocate data for opened tables */ - init_alloc_root(&tmp_mem_root, SHOW_ALLOC_BLOCK_SIZE, SHOW_ALLOC_BLOCK_SIZE, - MY_THREAD_SPECIFIC); + init_alloc_root(&tmp_mem_root, "get_all_tables", SHOW_ALLOC_BLOCK_SIZE, + SHOW_ALLOC_BLOCK_SIZE, MY_THREAD_SPECIFIC); for (size_t i=0; i < db_names.elements(); i++) { diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 9aa9b7becdb..44d507412ec 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -1112,7 +1112,8 @@ static int execute_ddl_log_action(THD *thd, DDL_LOG_ENTRY *ddl_log_entry) ddl_log_entry->tmp_name)); handler_name.str= (char*)ddl_log_entry->handler_name; handler_name.length= strlen(ddl_log_entry->handler_name); - init_sql_alloc(&mem_root, TABLE_ALLOC_BLOCK_SIZE, 0, MYF(MY_THREAD_SPECIFIC)); + init_sql_alloc(&mem_root, "execute_ddl_log_action", TABLE_ALLOC_BLOCK_SIZE, + 0, MYF(MY_THREAD_SPECIFIC)); if (!strcmp(ddl_log_entry->handler_name, reg_ext)) frm_action= TRUE; else diff --git a/sql/sql_trigger.cc b/sql/sql_trigger.cc index e7e7dd9589d..ebc5b28f598 100644 --- a/sql/sql_trigger.cc +++ b/sql/sql_trigger.cc @@ -1789,10 +1789,11 @@ bool Table_triggers_list::drop_all_triggers(THD *thd, const char *db, TABLE table; char path[FN_REFLEN]; bool result= 0; - DBUG_ENTER("drop_all_triggers"); + DBUG_ENTER("Triggers::drop_all_triggers"); bzero(&table, sizeof(table)); - init_sql_alloc(&table.mem_root, 8192, 0, MYF(0)); + init_sql_alloc(&table.mem_root, "Triggers::drop_all_triggers", 8192, 0, + MYF(0)); if (Table_triggers_list::check_n_load(thd, db, name, &table, 1)) { @@ -2038,10 +2039,11 @@ bool Table_triggers_list::change_table_name(THD *thd, const char *db, bool result= 0; bool upgrading50to51= FALSE; Trigger *err_trigger; - DBUG_ENTER("change_table_name"); + DBUG_ENTER("Triggers::change_table_name"); bzero(&table, sizeof(table)); - init_sql_alloc(&table.mem_root, 8192, 0, MYF(0)); + init_sql_alloc(&table.mem_root, "Triggers::change_table_name", 8192, 0, + MYF(0)); /* This method interfaces the mysql server code protected by diff --git a/sql/sql_udf.cc b/sql/sql_udf.cc index 612cc97f6a2..70da4d1160b 100644 --- a/sql/sql_udf.cc +++ b/sql/sql_udf.cc @@ -153,7 +153,7 @@ void udf_init() mysql_rwlock_init(key_rwlock_THR_LOCK_udf, &THR_LOCK_udf); - init_sql_alloc(&mem, UDF_ALLOC_BLOCK_SIZE, 0, MYF(0)); + init_sql_alloc(&mem, "udf", UDF_ALLOC_BLOCK_SIZE, 0, MYF(0)); THD *new_thd = new THD(0); if (!new_thd || my_hash_init(&udf_hash,system_charset_info,32,0,0,get_hash_key, NULL, 0)) diff --git a/sql/table.cc b/sql/table.cc index 1e0099cbe4f..afd6b14079f 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -310,7 +310,7 @@ TABLE_SHARE *alloc_table_share(const char *db, const char *table_name, path_length= build_table_filename(path, sizeof(path) - 1, db, table_name, "", 0); - init_sql_alloc(&mem_root, TABLE_ALLOC_BLOCK_SIZE, 0, MYF(0)); + init_sql_alloc(&mem_root, "table_share", TABLE_ALLOC_BLOCK_SIZE, 0, MYF(0)); if (multi_alloc_root(&mem_root, &share, sizeof(*share), &key_buff, key_length, @@ -331,7 +331,8 @@ TABLE_SHARE *alloc_table_share(const char *db, const char *table_name, /* The following will be fixed in open_table_from_share */ share->cached_row_logging_check= 1; - init_sql_alloc(&share->stats_cb.mem_root, TABLE_ALLOC_BLOCK_SIZE, 0, MYF(0)); + init_sql_alloc(&share->stats_cb.mem_root, "share_stats", + TABLE_ALLOC_BLOCK_SIZE, 0, MYF(0)); memcpy((char*) &share->mem_root, (char*) &mem_root, sizeof(mem_root)); mysql_mutex_init(key_TABLE_SHARE_LOCK_share, @@ -388,8 +389,8 @@ void init_tmp_table_share(THD *thd, TABLE_SHARE *share, const char *key, This can't be MY_THREAD_SPECIFIC for slaves as they are freed during cleanup() from Relay_log_info::close_temporary_tables() */ - init_sql_alloc(&share->mem_root, TABLE_ALLOC_BLOCK_SIZE, 0, - MYF(thd->slave_thread ? 0 : MY_THREAD_SPECIFIC)); + init_sql_alloc(&share->mem_root, "tmp_table_share", TABLE_ALLOC_BLOCK_SIZE, + 0, MYF(thd->slave_thread ? 0 : MY_THREAD_SPECIFIC)); share->table_category= TABLE_CATEGORY_TEMPORARY; share->tmp_table= INTERNAL_TMP_TABLE; share->db.str= (char*) key; @@ -3040,7 +3041,8 @@ enum open_frm_error open_table_from_share(THD *thd, TABLE_SHARE *share, error= OPEN_FRM_NEEDS_REBUILD; goto err; } - init_sql_alloc(&outparam->mem_root, TABLE_ALLOC_BLOCK_SIZE, 0, MYF(0)); + init_sql_alloc(&outparam->mem_root, "table", TABLE_ALLOC_BLOCK_SIZE, 0, + MYF(0)); if (outparam->alias.copy(alias, strlen(alias), table_alias_charset)) goto err; diff --git a/sql/table.h b/sql/table.h index 8f83bfc5ef2..83a1e8702b7 100644 --- a/sql/table.h +++ b/sql/table.h @@ -979,7 +979,8 @@ private: public: Blob_mem_storage() :truncated_value(false) { - init_alloc_root(&storage, MAX_FIELD_VARCHARLENGTH, 0, MYF(0)); + init_alloc_root(&storage, "Blob_mem_storage", MAX_FIELD_VARCHARLENGTH, 0, + MYF(0)); } ~ Blob_mem_storage() { diff --git a/sql/table_cache.cc b/sql/table_cache.cc index be990543757..393fe931a82 100644 --- a/sql/table_cache.cc +++ b/sql/table_cache.cc @@ -1284,7 +1284,8 @@ int tdc_iterate(THD *thd, my_hash_walk_action action, void *argument, if (no_dups) { - init_alloc_root(&no_dups_argument.root, 4096, 4096, MYF(alloc_flags)); + init_alloc_root(&no_dups_argument.root, "no_dups", 4096, 4096, + MYF(alloc_flags)); my_hash_init(&no_dups_argument.hash, &my_charset_bin, tdc_records(), 0, 0, eliminate_duplicates_get_key, 0, hash_flags); no_dups_argument.action= action; diff --git a/sql/thr_malloc.cc b/sql/thr_malloc.cc index cbed769a424..94ae1a4431c 100644 --- a/sql/thr_malloc.cc +++ b/sql/thr_malloc.cc @@ -58,10 +58,11 @@ extern "C" { } } -void init_sql_alloc(MEM_ROOT *mem_root, uint block_size, uint pre_alloc, - myf my_flags) +void init_sql_alloc(MEM_ROOT *mem_root, + const char *area_name __attribute__((unused)), + uint block_size, uint pre_alloc, myf my_flags) { - init_alloc_root(mem_root, block_size, pre_alloc, my_flags); + init_alloc_root(mem_root, area_name, block_size, pre_alloc, my_flags); mem_root->error_handler=sql_alloc_error_handler; } diff --git a/sql/thr_malloc.h b/sql/thr_malloc.h index fc23c87c9fd..a36059b97b2 100644 --- a/sql/thr_malloc.h +++ b/sql/thr_malloc.h @@ -20,8 +20,8 @@ typedef struct st_mem_root MEM_ROOT; -void init_sql_alloc(MEM_ROOT *root, uint block_size, uint pre_alloc_size, - myf my_flags); +void init_sql_alloc(MEM_ROOT *root, const char *area_name, uint block_size, + uint pre_alloc_size, myf my_flags); char *sql_strmake_with_convert(THD *thd, const char *str, size_t arg_length, CHARSET_INFO *from_cs, size_t max_res_length, diff --git a/sql/tztime.cc b/sql/tztime.cc index a9db91668bb..45af8f24943 100644 --- a/sql/tztime.cc +++ b/sql/tztime.cc @@ -1639,7 +1639,7 @@ my_tz_init(THD *org_thd, const char *default_tzname, my_bool bootstrap) my_hash_free(&tz_names); goto end; } - init_sql_alloc(&tz_storage, 32 * 1024, 0, MYF(0)); + init_sql_alloc(&tz_storage, "timezone_storage", 32 * 1024, 0, MYF(0)); mysql_mutex_init(key_tz_LOCK, &tz_LOCK, MY_MUTEX_INIT_FAST); tz_inited= 1; @@ -2565,7 +2565,8 @@ scan_tz_dir(char * name_end, uint symlink_recursion_level, uint verbose) } else if (MY_S_ISREG(cur_dir->dir_entry[i].mystat->st_mode)) { - init_alloc_root(&tz_storage, 32768, 0, MYF(MY_THREAD_SPECIFIC)); + init_alloc_root(&tz_storage, "timezone_storage", 32768, 0, + MYF(MY_THREAD_SPECIFIC)); if (!tz_load(fullname, &tz_info, &tz_storage)) print_tz_as_sql(root_name_end + 1, &tz_info); else @@ -2739,7 +2740,7 @@ main(int argc, char **argv) First argument is timezonefile. The second is timezonename if opt_leap is not given */ - init_alloc_root(&tz_storage, 32768, 0, MYF(0)); + init_alloc_root(&tz_storage, "timezone_storage", 32768, 0, MYF(0)); if (tz_load(argv[0], &tz_info, &tz_storage)) { @@ -2813,7 +2814,7 @@ main(int argc, char **argv) MY_INIT(argv[0]); - init_alloc_root(&tz_storage, 32768, MYF(0)); + init_alloc_root(&tz_storage, "timezone_storage", 32768, MYF(0)); /* let us set some well known timezone */ setenv("TZ", "MET", 1); diff --git a/storage/cassandra/ha_cassandra.cc b/storage/cassandra/ha_cassandra.cc index ff758a57872..c55e9976ede 100644 --- a/storage/cassandra/ha_cassandra.cc +++ b/storage/cassandra/ha_cassandra.cc @@ -866,7 +866,7 @@ static void alloc_strings_memroot(MEM_ROOT *mem_root) The mem_root used to allocate UUID (of length 36 + \0) so make appropriate allocated size */ - init_alloc_root(mem_root, + init_alloc_root(mem_root, "cassandra", (36 + 1 + ALIGN_SIZE(sizeof(USED_MEM))) * 10 + ALLOC_ROOT_MIN_BLOCK_SIZE, (36 + 1 + ALIGN_SIZE(sizeof(USED_MEM))) * 10 + diff --git a/storage/csv/ha_tina.cc b/storage/csv/ha_tina.cc index f00fe0e201f..f465ee2e947 100644 --- a/storage/csv/ha_tina.cc +++ b/storage/csv/ha_tina.cc @@ -514,7 +514,7 @@ ha_tina::ha_tina(handlerton *hton, TABLE_SHARE *table_arg) buffer.set((char*)byte_buffer, IO_SIZE, &my_charset_bin); chain= chain_buffer; file_buff= new Transparent_file(); - init_alloc_root(&blobroot, BLOB_MEMROOT_ALLOC_SIZE, 0, MYF(0)); + init_alloc_root(&blobroot, "ha_tina", BLOB_MEMROOT_ALLOC_SIZE, 0, MYF(0)); } @@ -976,7 +976,7 @@ int ha_tina::open(const char *name, int mode, uint open_options) */ thr_lock_data_init(&share->lock, &lock, (void*) this); ref_length= sizeof(my_off_t); - init_alloc_root(&blobroot, BLOB_MEMROOT_ALLOC_SIZE, 0, MYF(0)); + init_alloc_root(&blobroot, "ha_tina", BLOB_MEMROOT_ALLOC_SIZE, 0, MYF(0)); share->lock.get_status= tina_get_status; share->lock.update_status= tina_update_status; diff --git a/storage/federated/ha_federated.cc b/storage/federated/ha_federated.cc index e6fbceb4af2..98d4ef4d7f9 100644 --- a/storage/federated/ha_federated.cc +++ b/storage/federated/ha_federated.cc @@ -1517,7 +1517,7 @@ static FEDERATED_SHARE *get_share(const char *table_name, TABLE *table) */ query.length(0); - init_alloc_root(&mem_root, 256, 0, MYF(0)); + init_alloc_root(&mem_root, "federated_share", 256, 0, MYF(0)); mysql_mutex_lock(&federated_mutex); diff --git a/storage/federatedx/ha_federatedx.cc b/storage/federatedx/ha_federatedx.cc index a761c635305..8d5eee99476 100644 --- a/storage/federatedx/ha_federatedx.cc +++ b/storage/federatedx/ha_federatedx.cc @@ -1520,7 +1520,7 @@ static FEDERATEDX_SERVER *get_server(FEDERATEDX_SHARE *share, TABLE *table) mysql_mutex_assert_owner(&federatedx_mutex); - init_alloc_root(&mem_root, 4096, 4096, MYF(0)); + init_alloc_root(&mem_root, "federated", 4096, 4096, MYF(0)); fill_server(&mem_root, &tmp_server, share, table ? table->s->table_charset : 0); @@ -1578,7 +1578,7 @@ static FEDERATEDX_SHARE *get_share(const char *table_name, TABLE *table) query.length(0); bzero(&tmp_share, sizeof(tmp_share)); - init_alloc_root(&mem_root, 256, 0, MYF(0)); + init_alloc_root(&mem_root, "federated", 256, 0, MYF(0)); mysql_mutex_lock(&federatedx_mutex); diff --git a/storage/maria/ma_check.c b/storage/maria/ma_check.c index 7caec1fd834..0e7777ee855 100644 --- a/storage/maria/ma_check.c +++ b/storage/maria/ma_check.c @@ -3783,7 +3783,7 @@ int maria_repair_by_sort(HA_CHECK *param, register MARIA_HA *info, param->read_cache.end_of_file= sort_info.filelength; sort_param.wordlist=NULL; - init_alloc_root(&sort_param.wordroot, FTPARSER_MEMROOT_ALLOC_SIZE, 0, + init_alloc_root(&sort_param.wordroot, "sort", FTPARSER_MEMROOT_ALLOC_SIZE, 0, MYF(param->malloc_flags)); sort_param.key_cmp=sort_key_cmp; @@ -4431,7 +4431,8 @@ int maria_repair_parallel(HA_CHECK *param, register MARIA_HA *info, (FT_MAX_WORD_LEN_FOR_SORT * sort_param[i].keyinfo->seg->charset->mbmaxlen); sort_param[i].key_length+=ft_max_word_len_for_sort-HA_FT_MAXBYTELEN; - init_alloc_root(&sort_param[i].wordroot, FTPARSER_MEMROOT_ALLOC_SIZE, 0, + init_alloc_root(&sort_param[i].wordroot, "sort", + FTPARSER_MEMROOT_ALLOC_SIZE, 0, MYF(param->malloc_flags)); } } diff --git a/storage/maria/ma_ft_boolean_search.c b/storage/maria/ma_ft_boolean_search.c index a37a1322ad0..03f84e086b1 100644 --- a/storage/maria/ma_ft_boolean_search.c +++ b/storage/maria/ma_ft_boolean_search.c @@ -574,7 +574,7 @@ FT_INFO * maria_ft_init_boolean_search(MARIA_HA *info, uint keynr, bzero(& ftb->no_dupes, sizeof(TREE)); ftb->last_word= 0; - init_alloc_root(&ftb->mem_root, 1024, 1024, 0); + init_alloc_root(&ftb->mem_root, "fulltext", 1024, 1024, 0); ftb->queue.max_elements= 0; if (!(ftbe=(FTB_EXPR *)alloc_root(&ftb->mem_root, sizeof(FTB_EXPR)))) goto err; diff --git a/storage/maria/ma_ft_parser.c b/storage/maria/ma_ft_parser.c index f0a2e1e1425..d868b66dfbe 100644 --- a/storage/maria/ma_ft_parser.c +++ b/storage/maria/ma_ft_parser.c @@ -348,7 +348,8 @@ MYSQL_FTPARSER_PARAM* maria_ftparser_alloc_param(MARIA_HA *info) info->ftparser_param= (MYSQL_FTPARSER_PARAM *) my_malloc(MAX_PARAM_NR * sizeof(MYSQL_FTPARSER_PARAM) * info->s->ftkeys, MYF(MY_WME | MY_ZEROFILL)); - init_alloc_root(&info->ft_memroot, FTPARSER_MEMROOT_ALLOC_SIZE, 0, MYF(0)); + init_alloc_root(&info->ft_memroot, "fulltext_parser", + FTPARSER_MEMROOT_ALLOC_SIZE, 0, MYF(0)); } return info->ftparser_param; } diff --git a/storage/mroonga/mrn_mysql_compat.h b/storage/mroonga/mrn_mysql_compat.h index d33a8c88d87..aac16d3c7bd 100644 --- a/storage/mroonga/mrn_mysql_compat.h +++ b/storage/mroonga/mrn_mysql_compat.h @@ -60,7 +60,10 @@ # define KEY_N_KEY_PARTS(key) (key)->key_parts #endif -#if defined(MRN_MARIADB_P) && MYSQL_VERSION_ID >= 100000 +#if defined(MRN_MARIADB_P) && MYSQL_VERSION_ID >= 100213 +# define mrn_init_alloc_root(PTR, SZ1, SZ2, FLAG) \ + init_alloc_root(PTR, "mroonga", SZ1, SZ2, FLAG) +#elif defined(MRN_MARIADB_P) && MYSQL_VERSION_ID >= 100000 # define mrn_init_alloc_root(PTR, SZ1, SZ2, FLAG) \ init_alloc_root(PTR, SZ1, SZ2, FLAG) #elif MYSQL_VERSION_ID >= 50706 @@ -238,7 +241,13 @@ #endif #if defined(MRN_MARIADB_P) && MYSQL_VERSION_ID >= 100000 -# if MYSQL_VERSION_ID >= 100104 +# if MYSQL_VERSION_ID >= 100213 +# define mrn_init_sql_alloc(thd, mem_root) \ + init_sql_alloc(mem_root, "Mroonga", \ + TABLE_ALLOC_BLOCK_SIZE, \ + 0, \ + MYF(thd->slave_thread ? 0 : MY_THREAD_SPECIFIC)) +#elif MYSQL_VERSION_ID >= 100104 # define mrn_init_sql_alloc(thd, mem_root) \ init_sql_alloc(mem_root, \ TABLE_ALLOC_BLOCK_SIZE, \ diff --git a/storage/myisam/ft_boolean_search.c b/storage/myisam/ft_boolean_search.c index a44e24c9db1..129384245bf 100644 --- a/storage/myisam/ft_boolean_search.c +++ b/storage/myisam/ft_boolean_search.c @@ -579,7 +579,7 @@ FT_INFO * ft_init_boolean_search(MI_INFO *info, uint keynr, uchar *query, bzero(& ftb->no_dupes, sizeof(TREE)); ftb->last_word= 0; - init_alloc_root(&ftb->mem_root, 1024, 1024, MYF(0)); + init_alloc_root(&ftb->mem_root, "fulltext", 1024, 1024, MYF(0)); ftb->queue.max_elements= 0; if (!(ftbe=(FTB_EXPR *)alloc_root(&ftb->mem_root, sizeof(FTB_EXPR)))) goto err; diff --git a/storage/myisam/ft_parser.c b/storage/myisam/ft_parser.c index c8d99b68e8a..78ddb0af4fe 100644 --- a/storage/myisam/ft_parser.c +++ b/storage/myisam/ft_parser.c @@ -342,7 +342,8 @@ MYSQL_FTPARSER_PARAM* ftparser_alloc_param(MI_INFO *info) info->ftparser_param= (MYSQL_FTPARSER_PARAM *) my_malloc(MAX_PARAM_NR * sizeof(MYSQL_FTPARSER_PARAM) * info->s->ftkeys, MYF(MY_WME | MY_ZEROFILL)); - init_alloc_root(&info->ft_memroot, FTPARSER_MEMROOT_ALLOC_SIZE, 0, MYF(0)); + init_alloc_root(&info->ft_memroot, "fulltext_parser", + FTPARSER_MEMROOT_ALLOC_SIZE, 0, MYF(0)); } return info->ftparser_param; } diff --git a/storage/myisam/mi_check.c b/storage/myisam/mi_check.c index 917e142af91..372acc52fae 100644 --- a/storage/myisam/mi_check.c +++ b/storage/myisam/mi_check.c @@ -2292,7 +2292,7 @@ int mi_repair_by_sort(HA_CHECK *param, register MI_INFO *info, mysql_file_seek(param->read_cache.file, 0L, MY_SEEK_END, MYF(0)); sort_param.wordlist=NULL; - init_alloc_root(&sort_param.wordroot, FTPARSER_MEMROOT_ALLOC_SIZE, 0, + init_alloc_root(&sort_param.wordroot, "sort", FTPARSER_MEMROOT_ALLOC_SIZE, 0, MYF(param->malloc_flags)); if (share->data_file_type == DYNAMIC_RECORD) @@ -2870,7 +2870,8 @@ int mi_repair_parallel(HA_CHECK *param, register MI_INFO *info, uint ft_max_word_len_for_sort=FT_MAX_WORD_LEN_FOR_SORT* sort_param[i].keyinfo->seg->charset->mbmaxlen; sort_param[i].key_length+=ft_max_word_len_for_sort-HA_FT_MAXBYTELEN; - init_alloc_root(&sort_param[i].wordroot, FTPARSER_MEMROOT_ALLOC_SIZE, 0, + init_alloc_root(&sort_param[i].wordroot, "sort", + FTPARSER_MEMROOT_ALLOC_SIZE, 0, MYF(param->malloc_flags)); } } diff --git a/storage/myisammrg/ha_myisammrg.cc b/storage/myisammrg/ha_myisammrg.cc index 0cf8305463b..da7d7fe0240 100644 --- a/storage/myisammrg/ha_myisammrg.cc +++ b/storage/myisammrg/ha_myisammrg.cc @@ -120,7 +120,7 @@ static handler *myisammrg_create_handler(handlerton *hton, ha_myisammrg::ha_myisammrg(handlerton *hton, TABLE_SHARE *table_arg) :handler(hton, table_arg), file(0), is_cloned(0) { - init_sql_alloc(&children_mem_root, + init_sql_alloc(&children_mem_root, "ha_myisammrg", FN_REFLEN + ALLOC_ROOT_MIN_BLOCK_SIZE, 0, MYF(0)); } diff --git a/storage/oqgraph/ha_oqgraph.cc b/storage/oqgraph/ha_oqgraph.cc index 4b858d468f5..4d13cc111c0 100644 --- a/storage/oqgraph/ha_oqgraph.cc +++ b/storage/oqgraph/ha_oqgraph.cc @@ -562,7 +562,7 @@ int ha_oqgraph::open(const char *name, int mode, uint test_if_locked) init_tmp_table_share( thd, share, table->s->db.str, table->s->db.length, options->table_name, ""); // because of that, we need to reinitialize the memroot (to reset MY_THREAD_SPECIFIC flag) DBUG_ASSERT(share->mem_root.used == NULL); // it's still empty - init_sql_alloc(&share->mem_root, TABLE_ALLOC_BLOCK_SIZE, 0, MYF(0)); + init_sql_alloc(&share->mem_root, "share", TABLE_ALLOC_BLOCK_SIZE, 0, MYF(0)); // What I think this code is doing: // * Our OQGRAPH table is `database_blah/name` diff --git a/storage/spider/hs_client/hs_compat.h b/storage/spider/hs_client/hs_compat.h index a26dd18e481..22497d85200 100644 --- a/storage/spider/hs_client/hs_compat.h +++ b/storage/spider/hs_client/hs_compat.h @@ -16,7 +16,12 @@ #ifndef HS_COMPAT_H #define HS_COMPAT_H -#if defined(MARIADB_BASE_VERSION) && MYSQL_VERSION_ID >= 100000 +#if defined(MARIADB_BASE_VERSION) && MYSQL_VERSION_ID >= 100213 +#define SPD_INIT_DYNAMIC_ARRAY2(A, B, C, D, E, F) \ + my_init_dynamic_array2(A, B, C, D, E, F) +#define SPD_INIT_ALLOC_ROOT(A, B, C, D) \ + init_alloc_root(A, "spider", B, C, D) +#elif defined(MARIADB_BASE_VERSION) && MYSQL_VERSION_ID >= 100000 #define SPD_INIT_DYNAMIC_ARRAY2(A, B, C, D, E, F) \ my_init_dynamic_array2(A, B, C, D, E, F) #define SPD_INIT_ALLOC_ROOT(A, B, C, D) \ From 705283f7e3e2a3bf962381b77c2f47b393f25d2e Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Fri, 2 Feb 2018 15:38:15 +0400 Subject: [PATCH 5/7] Setting Field::field_index for Virtual_tmp_table fields Virtial_tmp_table did not set the "field_index" member for its Fields. Fixing Virtual_tmp_table::add() to set "field_index" to the Field's ordinal position inside the table, like a normal TABLE does, for consistency. Although, this flaw did not seem to cause any bugs, having field_index properly set is helpful for debugging purposes. --- sql/sql_select.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql/sql_select.h b/sql/sql_select.h index 7cfc35a3b7d..3f1fdac96cb 100644 --- a/sql/sql_select.h +++ b/sql/sql_select.h @@ -2104,7 +2104,7 @@ public: DBUG_ASSERT(s->blob_fields <= m_alloced_field_count); s->blob_field[s->blob_fields - 1]= s->fields; } - s->fields++; + new_field->field_index= s->fields++; return false; } From 2ecf2f9b2a2c2126b9c9bd0ba8b58280331f5849 Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Sat, 3 Feb 2018 17:27:43 +0400 Subject: [PATCH 6/7] Adding "const" qualifier to the MYSQL_TIME* argument of Field::store_time_dec() --- sql/field.cc | 16 ++++++++-------- sql/field.h | 18 +++++++++--------- 2 files changed, 17 insertions(+), 17 deletions(-) diff --git a/sql/field.cc b/sql/field.cc index 3fd76591117..e954ac5b431 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -2196,7 +2196,7 @@ bool Field::get_date(MYSQL_TIME *ltime,ulonglong fuzzydate) Needs to be changed if/when we want to support different time formats. */ -int Field::store_time_dec(MYSQL_TIME *ltime, uint dec) +int Field::store_time_dec(const MYSQL_TIME *ltime, uint dec) { ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; char buff[MAX_DATE_STRING_REP_LENGTH]; @@ -3241,7 +3241,7 @@ int Field_new_decimal::store_decimal(const my_decimal *decimal_value) } -int Field_new_decimal::store_time_dec(MYSQL_TIME *ltime, uint dec_arg) +int Field_new_decimal::store_time_dec(const MYSQL_TIME *ltime, uint dec_arg) { my_decimal decimal_value; return store_value(date2my_decimal(ltime, &decimal_value)); @@ -3480,7 +3480,7 @@ Item *Field_new_decimal::get_equal_const_item(THD *thd, const Context &ctx, } -int Field_num::store_time_dec(MYSQL_TIME *ltime, uint dec_arg) +int Field_num::store_time_dec(const MYSQL_TIME *ltime, uint dec_arg) { longlong v= TIME_to_ulonglong(ltime); if (ltime->neg == 0) @@ -4734,7 +4734,7 @@ int Field_real::store_decimal(const my_decimal *dm) return store(dbl); } -int Field_real::store_time_dec(MYSQL_TIME *ltime, uint dec_arg) +int Field_real::store_time_dec(const MYSQL_TIME *ltime, uint dec_arg) { return store(TIME_to_double(ltime)); } @@ -5016,7 +5016,7 @@ copy_or_convert_to_datetime(THD *thd, const MYSQL_TIME *from, MYSQL_TIME *to) } -int Field_timestamp::store_time_dec(MYSQL_TIME *ltime, uint dec) +int Field_timestamp::store_time_dec(const MYSQL_TIME *ltime, uint dec) { int unused; ErrConvTime str(ltime); @@ -5582,7 +5582,7 @@ int Field_temporal_with_date::store(longlong nr, bool unsigned_val) } -int Field_temporal_with_date::store_time_dec(MYSQL_TIME *ltime, uint dec) +int Field_temporal_with_date::store_time_dec(const MYSQL_TIME *ltime, uint dec) { int error= 0, have_smth_to_conv= 1; ErrConvTime str(ltime); @@ -5774,7 +5774,7 @@ static void calc_datetime_days_diff(MYSQL_TIME *ltime, long days) } -int Field_time::store_time_dec(MYSQL_TIME *ltime, uint dec) +int Field_time::store_time_dec(const MYSQL_TIME *ltime, uint dec) { MYSQL_TIME l_time= *ltime; ErrConvTime str(ltime); @@ -6234,7 +6234,7 @@ int Field_year::store(longlong nr, bool unsigned_val) } -int Field_year::store_time_dec(MYSQL_TIME *ltime, uint dec_arg) +int Field_year::store_time_dec(const MYSQL_TIME *ltime, uint dec_arg) { ErrConvTime str(ltime); if (Field_year::store(ltime->year, 0)) diff --git a/sql/field.h b/sql/field.h index 287837ee1e7..f225b6269d3 100644 --- a/sql/field.h +++ b/sql/field.h @@ -815,9 +815,9 @@ public: virtual int store(double nr)=0; virtual int store(longlong nr, bool unsigned_val)=0; virtual int store_decimal(const my_decimal *d)=0; - virtual int store_time_dec(MYSQL_TIME *ltime, uint dec); + virtual int store_time_dec(const MYSQL_TIME *ltime, uint dec); virtual int store_timestamp(my_time_t timestamp, ulong sec_part); - int store_time(MYSQL_TIME *ltime) + int store_time(const MYSQL_TIME *ltime) { return store_time_dec(ltime, TIME_SECOND_PART_DIGITS); } int store(const char *to, uint length, CHARSET_INFO *cs, enum_check_fields check_level); @@ -1673,7 +1673,7 @@ public: field_metadata, length)); return length; } - int store_time_dec(MYSQL_TIME *ltime, uint dec); + int store_time_dec(const MYSQL_TIME *ltime, uint dec); double pos_in_interval(Field *min, Field *max) { return pos_in_interval_val_real(min, max); @@ -1813,7 +1813,7 @@ public: field_length >= from->field_length; } int store_decimal(const my_decimal *); - int store_time_dec(MYSQL_TIME *ltime, uint dec); + int store_time_dec(const MYSQL_TIME *ltime, uint dec); bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate); my_decimal *val_decimal(my_decimal *); bool val_bool() { return val_real() != 0e0; } @@ -1903,7 +1903,7 @@ public: int store(const char *to, uint length, CHARSET_INFO *charset); int store(double nr); int store(longlong nr, bool unsigned_val); - int store_time_dec(MYSQL_TIME *ltime, uint dec); + int store_time_dec(const MYSQL_TIME *ltime, uint dec); int store_decimal(const my_decimal *); double val_real(void); longlong val_int(void); @@ -2382,7 +2382,7 @@ public: int store(const char *to, uint length, CHARSET_INFO *charset); int store(double nr); int store(longlong nr, bool unsigned_val); - int store_time_dec(MYSQL_TIME *ltime, uint dec); + int store_time_dec(const MYSQL_TIME *ltime, uint dec); int store_decimal(const my_decimal *); bool validate_value_in_record(THD *thd, const uchar *record) const; }; @@ -2404,7 +2404,7 @@ public: int store(const char *to,uint length,CHARSET_INFO *charset); int store(double nr); int store(longlong nr, bool unsigned_val); - int store_time_dec(MYSQL_TIME *ltime, uint dec); + int store_time_dec(const MYSQL_TIME *ltime, uint dec); int store_decimal(const my_decimal *); int store_timestamp(my_time_t timestamp, ulong sec_part); int save_in_field(Field *to); @@ -2601,7 +2601,7 @@ public: int store(const char *to,uint length,CHARSET_INFO *charset); int store(double nr); int store(longlong nr, bool unsigned_val); - int store_time_dec(MYSQL_TIME *ltime, uint dec); + int store_time_dec(const MYSQL_TIME *ltime, uint dec); double val_real(void); longlong val_int(void); String *val_str(String*,String *); @@ -2711,7 +2711,7 @@ public: return real_type() == from->real_type() && decimals() == from->decimals(); } - int store_time_dec(MYSQL_TIME *ltime, uint dec); + int store_time_dec(const MYSQL_TIME *ltime, uint dec); int store(const char *to,uint length,CHARSET_INFO *charset); int store(double nr); int store(longlong nr, bool unsigned_val); From 28d4cf0c1b3366c6471866d144ef28fced1e5390 Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Sun, 4 Feb 2018 16:43:02 +0400 Subject: [PATCH 7/7] MDEV-15176 Storing DATETIME-alike VARCHAR data into TIME produces wrong results When storing '0001-01-01 10:20:30x', execution went throw the last code branch in Field_time::store_TIME_with_warning(), around the test for (ltime->year || ltime->month). This then resulted into wrong results because: 1. Field_time::store_TIME() does not check YYYYMM against zero. It assumes that ltime->days and ltime->hours are already properly set. So it mixed days to hours, even when YYYYMM was not zero. 2. Field_time_hires::store_TIME() does not check YYYYMM against zero. It assumes that ltime->year, ltime->month, ltime->days and ltime->hours are already properly set. So it always mixed days and even months(!) and years(!) to hours, using pack_time(). This gave even worse results comparing to #2. 3. Field_timef::store_TIME() did not check the entire YYYYMM for being zero. It only checked MM, but did not check YYYY. In case of a zero MM, it mixed days to hours, even if YYYY was not zero. The wrong code was in TIME_to_longlong_time_packed(). In the new reduction Field_time::store_TIME_with_warning() is responsible to prepare the YYYYYMMDD part properly in all code branches (with trailing garbage like 'x' and without trailing garbage). It was reorganized into a more straightforward style. Field_time:store_TIME(), Field_time_hires::store_TIME() and TIME_to_longlong_time_packed() were fixed to do a DBUG_ASSERT on non-zero ltime->year or ltime->month. The code testing ltime->month was removed from TIME_to_longlong_time_packed(), as it's now properly done on the caller level. Truncation was moved from Field_timef::store_TIME() to Field_time::store_TIME_with_warning(). So now all thee methods Field_time*::store_TIME() assume a properly set input value: - Only zero ltime->year and ltime->month are allowed. - The value must be already properly truncated according to decimals() (this will help to add rounding soon, see MDEV-8894) A "const" qualifier was added to the argument of Field_time*::store_TIME(). --- mysql-test/r/type_time.result | 129 ++++++++++++++++++++++++++++++++++ mysql-test/t/type_time.test | 38 ++++++++++ sql/compat56.cc | 6 +- sql/field.cc | 41 ++++++----- sql/field.h | 11 ++- 5 files changed, 202 insertions(+), 23 deletions(-) diff --git a/mysql-test/r/type_time.result b/mysql-test/r/type_time.result index 89718ea8363..a9fd5e3f79b 100644 --- a/mysql-test/r/type_time.result +++ b/mysql-test/r/type_time.result @@ -1283,3 +1283,132 @@ a 10:20:32 DROP TABLE t1; SET timestamp=DEFAULT; +# +# MDEV-15176 Storing DATETIME-alike VARCHAR data into TIME produces wrong results +# +SET sql_mode=''; +CREATE OR REPLACE TABLE t0 (d VARCHAR(64)); +INSERT INTO t0 VALUES ('0000-00-00 10:20:30'); +INSERT INTO t0 VALUES ('0000-00-01 10:20:30'); +INSERT INTO t0 VALUES ('0000-01-00 10:20:30'); +INSERT INTO t0 VALUES ('0000-01-01 10:20:30'); +INSERT INTO t0 VALUES ('0001-00-00 10:20:30'); +INSERT INTO t0 VALUES ('0001-00-01 10:20:30'); +INSERT INTO t0 VALUES ('0001-01-00 10:20:30'); +INSERT INTO t0 VALUES ('0001-01-01 10:20:30'); +SET @@global.mysql56_temporal_format=false; +CREATE OR REPLACE TABLE t1 (d VARCHAR(64), t0 TIME(0), t1 TIME(1)); +INSERT INTO t1 SELECT d,d,d FROM t0; +Warnings: +Note 1265 Data truncated for column 't0' at row 3 +Note 1265 Data truncated for column 't1' at row 3 +Note 1265 Data truncated for column 't0' at row 4 +Note 1265 Data truncated for column 't1' at row 4 +Note 1265 Data truncated for column 't0' at row 5 +Note 1265 Data truncated for column 't1' at row 5 +Note 1265 Data truncated for column 't0' at row 6 +Note 1265 Data truncated for column 't1' at row 6 +Note 1265 Data truncated for column 't0' at row 7 +Note 1265 Data truncated for column 't1' at row 7 +Note 1265 Data truncated for column 't0' at row 8 +Note 1265 Data truncated for column 't1' at row 8 +SELECT * FROM t1 ORDER BY d; +d t0 t1 +0000-00-00 10:20:30 10:20:30 10:20:30.0 +0000-00-01 10:20:30 34:20:30 34:20:30.0 +0000-01-00 10:20:30 10:20:30 10:20:30.0 +0000-01-01 10:20:30 10:20:30 10:20:30.0 +0001-00-00 10:20:30 10:20:30 10:20:30.0 +0001-00-01 10:20:30 10:20:30 10:20:30.0 +0001-01-00 10:20:30 10:20:30 10:20:30.0 +0001-01-01 10:20:30 10:20:30 10:20:30.0 +DROP TABLE t1; +CREATE OR REPLACE TABLE t1 (d VARCHAR(64), t0 TIME(0), t1 TIME(1)); +INSERT INTO t1 SELECT CONCAT(d,'x'),CONCAT(d,'x'),CONCAT(d,'x') FROM t0; +Warnings: +Warning 1265 Data truncated for column 't0' at row 1 +Warning 1265 Data truncated for column 't1' at row 1 +Warning 1265 Data truncated for column 't0' at row 2 +Warning 1265 Data truncated for column 't1' at row 2 +Warning 1265 Data truncated for column 't0' at row 3 +Warning 1265 Data truncated for column 't1' at row 3 +Warning 1265 Data truncated for column 't0' at row 4 +Warning 1265 Data truncated for column 't1' at row 4 +Warning 1265 Data truncated for column 't0' at row 5 +Warning 1265 Data truncated for column 't1' at row 5 +Warning 1265 Data truncated for column 't0' at row 6 +Warning 1265 Data truncated for column 't1' at row 6 +Warning 1265 Data truncated for column 't0' at row 7 +Warning 1265 Data truncated for column 't1' at row 7 +Warning 1265 Data truncated for column 't0' at row 8 +Warning 1265 Data truncated for column 't1' at row 8 +SELECT * FROM t1; +d t0 t1 +0000-00-00 10:20:30x 10:20:30 10:20:30.0 +0000-00-01 10:20:30x 34:20:30 34:20:30.0 +0000-01-00 10:20:30x 10:20:30 10:20:30.0 +0000-01-01 10:20:30x 10:20:30 10:20:30.0 +0001-00-00 10:20:30x 10:20:30 10:20:30.0 +0001-00-01 10:20:30x 10:20:30 10:20:30.0 +0001-01-00 10:20:30x 10:20:30 10:20:30.0 +0001-01-01 10:20:30x 10:20:30 10:20:30.0 +DROP TABLE t1; +SET @@global.mysql56_temporal_format=true; +CREATE OR REPLACE TABLE t1 (d VARCHAR(64), t0 TIME(0), t1 TIME(1)); +INSERT INTO t1 SELECT d,d,d FROM t0; +Warnings: +Note 1265 Data truncated for column 't0' at row 3 +Note 1265 Data truncated for column 't1' at row 3 +Note 1265 Data truncated for column 't0' at row 4 +Note 1265 Data truncated for column 't1' at row 4 +Note 1265 Data truncated for column 't0' at row 5 +Note 1265 Data truncated for column 't1' at row 5 +Note 1265 Data truncated for column 't0' at row 6 +Note 1265 Data truncated for column 't1' at row 6 +Note 1265 Data truncated for column 't0' at row 7 +Note 1265 Data truncated for column 't1' at row 7 +Note 1265 Data truncated for column 't0' at row 8 +Note 1265 Data truncated for column 't1' at row 8 +SELECT * FROM t1; +d t0 t1 +0000-00-00 10:20:30 10:20:30 10:20:30.0 +0000-00-01 10:20:30 34:20:30 34:20:30.0 +0000-01-00 10:20:30 10:20:30 10:20:30.0 +0000-01-01 10:20:30 10:20:30 10:20:30.0 +0001-00-00 10:20:30 10:20:30 10:20:30.0 +0001-00-01 10:20:30 10:20:30 10:20:30.0 +0001-01-00 10:20:30 10:20:30 10:20:30.0 +0001-01-01 10:20:30 10:20:30 10:20:30.0 +DROP TABLE t1; +CREATE OR REPLACE TABLE t1 (d VARCHAR(64), t0 TIME(0), t1 TIME(1)); +INSERT INTO t1 SELECT CONCAT(d,'x'),CONCAT(d,'x'),CONCAT(d,'x') FROM t0; +Warnings: +Warning 1265 Data truncated for column 't0' at row 1 +Warning 1265 Data truncated for column 't1' at row 1 +Warning 1265 Data truncated for column 't0' at row 2 +Warning 1265 Data truncated for column 't1' at row 2 +Warning 1265 Data truncated for column 't0' at row 3 +Warning 1265 Data truncated for column 't1' at row 3 +Warning 1265 Data truncated for column 't0' at row 4 +Warning 1265 Data truncated for column 't1' at row 4 +Warning 1265 Data truncated for column 't0' at row 5 +Warning 1265 Data truncated for column 't1' at row 5 +Warning 1265 Data truncated for column 't0' at row 6 +Warning 1265 Data truncated for column 't1' at row 6 +Warning 1265 Data truncated for column 't0' at row 7 +Warning 1265 Data truncated for column 't1' at row 7 +Warning 1265 Data truncated for column 't0' at row 8 +Warning 1265 Data truncated for column 't1' at row 8 +SELECT * FROM t1 ORDER BY d; +d t0 t1 +0000-00-00 10:20:30x 10:20:30 10:20:30.0 +0000-00-01 10:20:30x 34:20:30 34:20:30.0 +0000-01-00 10:20:30x 10:20:30 10:20:30.0 +0000-01-01 10:20:30x 10:20:30 10:20:30.0 +0001-00-00 10:20:30x 10:20:30 10:20:30.0 +0001-00-01 10:20:30x 10:20:30 10:20:30.0 +0001-01-00 10:20:30x 10:20:30 10:20:30.0 +0001-01-01 10:20:30x 10:20:30 10:20:30.0 +DROP TABLE t1; +DROP TABLE t0; +SET sql_mode=DEFAULT; diff --git a/mysql-test/t/type_time.test b/mysql-test/t/type_time.test index 5f3f58df166..e872889ed0f 100644 --- a/mysql-test/t/type_time.test +++ b/mysql-test/t/type_time.test @@ -776,3 +776,41 @@ INSERT INTO t1 VALUES ('10:20:30'),('10:20:31'),('10:20:32'); SELECT a FROM t1 WHERE a IN (102030,TIME'10:20:31',TIMESTAMP'2001-01-01 10:20:32') ORDER BY a; DROP TABLE t1; SET timestamp=DEFAULT; + +--echo # +--echo # MDEV-15176 Storing DATETIME-alike VARCHAR data into TIME produces wrong results +--echo # + +SET sql_mode=''; +CREATE OR REPLACE TABLE t0 (d VARCHAR(64)); +INSERT INTO t0 VALUES ('0000-00-00 10:20:30'); +INSERT INTO t0 VALUES ('0000-00-01 10:20:30'); +INSERT INTO t0 VALUES ('0000-01-00 10:20:30'); +INSERT INTO t0 VALUES ('0000-01-01 10:20:30'); +INSERT INTO t0 VALUES ('0001-00-00 10:20:30'); +INSERT INTO t0 VALUES ('0001-00-01 10:20:30'); +INSERT INTO t0 VALUES ('0001-01-00 10:20:30'); +INSERT INTO t0 VALUES ('0001-01-01 10:20:30'); + +SET @@global.mysql56_temporal_format=false; +CREATE OR REPLACE TABLE t1 (d VARCHAR(64), t0 TIME(0), t1 TIME(1)); +INSERT INTO t1 SELECT d,d,d FROM t0; +SELECT * FROM t1 ORDER BY d; +DROP TABLE t1; +CREATE OR REPLACE TABLE t1 (d VARCHAR(64), t0 TIME(0), t1 TIME(1)); +INSERT INTO t1 SELECT CONCAT(d,'x'),CONCAT(d,'x'),CONCAT(d,'x') FROM t0; +SELECT * FROM t1; +DROP TABLE t1; + +SET @@global.mysql56_temporal_format=true; +CREATE OR REPLACE TABLE t1 (d VARCHAR(64), t0 TIME(0), t1 TIME(1)); +INSERT INTO t1 SELECT d,d,d FROM t0; +SELECT * FROM t1; +DROP TABLE t1; +CREATE OR REPLACE TABLE t1 (d VARCHAR(64), t0 TIME(0), t1 TIME(1)); +INSERT INTO t1 SELECT CONCAT(d,'x'),CONCAT(d,'x'),CONCAT(d,'x') FROM t0; +SELECT * FROM t1 ORDER BY d; +DROP TABLE t1; + +DROP TABLE t0; +SET sql_mode=DEFAULT; diff --git a/sql/compat56.cc b/sql/compat56.cc index 704d1db9a98..be54a8760aa 100644 --- a/sql/compat56.cc +++ b/sql/compat56.cc @@ -45,8 +45,10 @@ */ longlong TIME_to_longlong_time_packed(const MYSQL_TIME *ltime) { - /* If month is 0, we mix day with hours: "1 00:10:10" -> "24:00:10" */ - long hms= (((ltime->month ? 0 : ltime->day * 24) + ltime->hour) << 12) | + DBUG_ASSERT(ltime->year == 0); + DBUG_ASSERT(ltime->month == 0); + // Mix days with hours: "1 00:10:10" -> "24:00:10" + long hms= ((ltime->day * 24 + ltime->hour) << 12) | (ltime->minute << 6) | ltime->second; longlong tmp= MY_PACKED_TIME_MAKE(hms, ltime->second_part); return ltime->neg ? -tmp : tmp; diff --git a/sql/field.cc b/sql/field.cc index e954ac5b431..f6c48d7792b 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -5699,34 +5699,38 @@ int Field_time::store_TIME_with_warning(MYSQL_TIME *ltime, int was_cut, int have_smth_to_conv) { - Sql_condition::enum_warning_level trunc_level= Sql_condition::WARN_LEVEL_WARN; - int ret= 2; ASSERT_COLUMN_MARKED_FOR_WRITE_OR_COMPUTED; if (!have_smth_to_conv) { bzero(ltime, sizeof(*ltime)); - was_cut= MYSQL_TIME_WARN_TRUNCATED; - ret= 1; + store_TIME(ltime); + set_warnings(Sql_condition::WARN_LEVEL_WARN, str, MYSQL_TIME_WARN_TRUNCATED); + return 1; } - else if (!MYSQL_TIME_WARN_HAVE_WARNINGS(was_cut) && - ((ltime->year || ltime->month) || - MYSQL_TIME_WARN_HAVE_NOTES(was_cut))) + if (ltime->year != 0 || ltime->month != 0) { - if (ltime->year || ltime->month) - ltime->year= ltime->month= ltime->day= 0; - trunc_level= Sql_condition::WARN_LEVEL_NOTE; - was_cut|= MYSQL_TIME_WARN_TRUNCATED; - ret= 3; + ltime->year= ltime->month= ltime->day= 0; + was_cut|= MYSQL_TIME_NOTE_TRUNCATED; } - set_warnings(trunc_level, str, was_cut, MYSQL_TIMESTAMP_TIME); + my_time_trunc(ltime, decimals()); store_TIME(ltime); - return was_cut ? ret : 0; + if (!MYSQL_TIME_WARN_HAVE_WARNINGS(was_cut) && + MYSQL_TIME_WARN_HAVE_NOTES(was_cut)) + { + set_warnings(Sql_condition::WARN_LEVEL_NOTE, str, + was_cut | MYSQL_TIME_WARN_TRUNCATED); + return 3; + } + set_warnings(Sql_condition::WARN_LEVEL_WARN, str, was_cut); + return was_cut ? 2 : 0; } -void Field_time::store_TIME(MYSQL_TIME *ltime) +void Field_time::store_TIME(const MYSQL_TIME *ltime) { + DBUG_ASSERT(ltime->year == 0); + DBUG_ASSERT(ltime->month == 0); long tmp= (ltime->day*24L+ltime->hour)*10000L + (ltime->minute*100+ltime->second); if (ltime->neg) @@ -5960,8 +5964,10 @@ int Field_time_hires::reset() } -void Field_time_hires::store_TIME(MYSQL_TIME *ltime) +void Field_time_hires::store_TIME(const MYSQL_TIME *ltime) { + DBUG_ASSERT(ltime->year == 0); + DBUG_ASSERT(ltime->month == 0); ulonglong packed= sec_part_shift(pack_time(ltime), dec) + zero_point; store_bigendian(packed, ptr, Field_time_hires::pack_length()); } @@ -6143,9 +6149,8 @@ int Field_timef::reset() return 0; } -void Field_timef::store_TIME(MYSQL_TIME *ltime) +void Field_timef::store_TIME(const MYSQL_TIME *ltime) { - my_time_trunc(ltime, decimals()); longlong tmp= TIME_to_longlong_time_packed(ltime); my_time_packed_to_binary(tmp, ptr, dec); } diff --git a/sql/field.h b/sql/field.h index f225b6269d3..281e95c31bb 100644 --- a/sql/field.h +++ b/sql/field.h @@ -2682,9 +2682,14 @@ class Field_time :public Field_temporal { */ long curdays; protected: - virtual void store_TIME(MYSQL_TIME *ltime); + virtual void store_TIME(const MYSQL_TIME *ltime); int store_TIME_with_warning(MYSQL_TIME *ltime, const ErrConv *str, int was_cut, int have_smth_to_conv); + void set_warnings(Sql_condition::enum_warning_level level, + const ErrConv *str, int was_cut) + { + Field_temporal::set_warnings(level, str, was_cut, MYSQL_TIMESTAMP_TIME); + } bool check_zero_in_date_with_warn(ulonglong fuzzydate); static void do_field_time(Copy_field *copy); public: @@ -2766,7 +2771,7 @@ public: */ class Field_time_hires :public Field_time_with_dec { longlong zero_point; - void store_TIME(MYSQL_TIME *ltime); + void store_TIME(const MYSQL_TIME *); public: Field_time_hires(uchar *ptr_arg, uchar *null_ptr_arg, uchar null_bit_arg, enum utype unireg_check_arg, const LEX_CSTRING *field_name_arg, @@ -2792,7 +2797,7 @@ public: TIME(0..6) - MySQL56 version */ class Field_timef :public Field_time_with_dec { - void store_TIME(MYSQL_TIME *ltime); + void store_TIME(const MYSQL_TIME *); int do_save_field_metadata(uchar *metadata_ptr) { *metadata_ptr= (uchar) decimals();