diff options
author | Marko Mäkelä <marko.makela@mariadb.com> | 2020-04-28 14:51:25 +0300 |
---|---|---|
committer | Marko Mäkelä <marko.makela@mariadb.com> | 2020-04-28 16:09:07 +0300 |
commit | 704180747658019aa52173e44e99229b8ae56efa (patch) | |
tree | 99d3256ba9302fccc89217a404328750a766e43b /storage | |
parent | cce1b6e245a7ee30e6ebfcd45556e8caa6e754c2 (diff) | |
download | mariadb-git-704180747658019aa52173e44e99229b8ae56efa.tar.gz |
MDEV-22393 Corruption for SET GLOBAL innodb_ string variables
Several MYSQL_SYSVAR_STR parameters that employ both a validate
function callback fail to copy the string for saving the
validated value. The affected variables include the following:
innodb_ft_aux_table
innodb_ft_server_stopword_table
innodb_ft_user_stopword_table
innodb_buffer_pool_filename
The test case is an enhanced version of
mysql/mysql-server@0b0c30641fd66336e87394ac28587e40864f8af9
and the code changes are inspired by their fixes.
We are also importing and adjusting the test innodb_fts.stopword
to get coverage for the variable innodb_ft_user_stopword_table.
buf_dump(), buf_load(): Protect srv_buf_dump_filename with
LOCK_global_system_variables.
fts_load_user_stopword(): Minor cleanup
fts_load_stopword(): Remove the parameter global_stopword_table.
innobase_fts_load_stopword(): Protect innodb_server_stopword_table
against concurrent SET GLOBAL.
Diffstat (limited to 'storage')
-rw-r--r-- | storage/innobase/buf/buf0dump.cc | 8 | ||||
-rw-r--r-- | storage/innobase/fts/fts0fts.cc | 81 | ||||
-rw-r--r-- | storage/innobase/handler/ha_innodb.cc | 119 | ||||
-rw-r--r-- | storage/innobase/include/fts0fts.h | 12 | ||||
-rw-r--r-- | storage/xtradb/buf/buf0dump.cc | 8 | ||||
-rw-r--r-- | storage/xtradb/fts/fts0fts.cc | 81 | ||||
-rw-r--r-- | storage/xtradb/handler/ha_innodb.cc | 119 | ||||
-rw-r--r-- | storage/xtradb/include/fts0fts.h | 12 |
8 files changed, 226 insertions, 214 deletions
diff --git a/storage/innobase/buf/buf0dump.cc b/storage/innobase/buf/buf0dump.cc index eabc554036a..a45a37a4b3c 100644 --- a/storage/innobase/buf/buf0dump.cc +++ b/storage/innobase/buf/buf0dump.cc @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 2011, 2017, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2017, 2018, MariaDB Corporation. +Copyright (c) 2017, 2020, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -176,7 +176,7 @@ get_buf_dump_dir() /* The dump file should be created in the default data directory if innodb_data_home_dir is set as an empty string. */ - if (strcmp(srv_data_home, "") == 0) { + if (!*srv_data_home) { dump_dir = fil_path_to_mysql_datadir; } else { dump_dir = srv_data_home; @@ -207,9 +207,11 @@ buf_dump( ulint i; int ret; + mysql_mutex_lock(&LOCK_global_system_variables); ut_snprintf(full_filename, sizeof(full_filename), "%s%c%s", get_buf_dump_dir(), SRV_PATH_SEPARATOR, srv_buf_dump_filename); + mysql_mutex_unlock(&LOCK_global_system_variables); ut_snprintf(tmp_filename, sizeof(tmp_filename), "%s.incomplete", full_filename); @@ -513,9 +515,11 @@ buf_load() /* Ignore any leftovers from before */ buf_load_abort_flag = FALSE; + mysql_mutex_lock(&LOCK_global_system_variables); ut_snprintf(full_filename, sizeof(full_filename), "%s%c%s", get_buf_dump_dir(), SRV_PATH_SEPARATOR, srv_buf_dump_filename); + mysql_mutex_unlock(&LOCK_global_system_variables); buf_load_status(STATUS_NOTICE, "Loading buffer pool(s) from %s", full_filename); diff --git a/storage/innobase/fts/fts0fts.cc b/storage/innobase/fts/fts0fts.cc index 6dbe5e0e2a0..54cf2f11884 100644 --- a/storage/innobase/fts/fts0fts.cc +++ b/storage/innobase/fts/fts0fts.cc @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 2011, 2018, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2016, 2019, MariaDB Corporation. +Copyright (c) 2016, 2020, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -443,9 +443,9 @@ fts_read_stopword( /******************************************************************//** Load user defined stopword from designated user table -@return TRUE if load operation is successful */ +@return whether the operation is successful */ static -ibool +bool fts_load_user_stopword( /*===================*/ fts_t* fts, /*!< in: FTS struct */ @@ -453,27 +453,26 @@ fts_load_user_stopword( name */ fts_stopword_t* stopword_info) /*!< in: Stopword info */ { - pars_info_t* info; - que_t* graph; - dberr_t error = DB_SUCCESS; - ibool ret = TRUE; - trx_t* trx; - ibool has_lock = fts->dict_locked; - - trx = trx_allocate_for_background(); - trx->op_info = "Load user stopword table into FTS cache"; - - if (!has_lock) { + if (!fts->dict_locked) { mutex_enter(&dict_sys->mutex); } - /* Validate the user table existence and in the right - format */ + /* Validate the user table existence in the right format */ + bool ret= false; stopword_info->charset = fts_valid_stopword_table(stopword_table_name); if (!stopword_info->charset) { - ret = FALSE; - goto cleanup; - } else if (!stopword_info->cached_stopword) { +cleanup: + if (!fts->dict_locked) { + mutex_exit(&dict_sys->mutex); + } + + return ret; + } + + trx_t* trx = trx_allocate_for_background(); + trx->op_info = "Load user stopword table into FTS cache"; + + if (!stopword_info->cached_stopword) { /* Create the stopword RB tree with the stopword column charset. All comparison will use this charset */ stopword_info->cached_stopword = rbt_create_arg_cmp( @@ -482,14 +481,14 @@ fts_load_user_stopword( } - info = pars_info_create(); + pars_info_t* info = pars_info_create(); pars_info_bind_id(info, TRUE, "table_stopword", stopword_table_name); pars_info_bind_function(info, "my_func", fts_read_stopword, stopword_info); - graph = fts_parse_sql_no_dict_lock( + que_t* graph = fts_parse_sql_no_dict_lock( NULL, info, "DECLARE FUNCTION my_func;\n" @@ -508,14 +507,13 @@ fts_load_user_stopword( "CLOSE c;"); for (;;) { - error = fts_eval_sql(trx, graph); + dberr_t error = fts_eval_sql(trx, graph); if (error == DB_SUCCESS) { fts_sql_commit(trx); stopword_info->status = STOPWORD_USER_TABLE; break; } else { - fts_sql_rollback(trx); ut_print_timestamp(stderr); @@ -537,14 +535,9 @@ fts_load_user_stopword( } que_graph_free(graph); - -cleanup: - if (!has_lock) { - mutex_exit(&dict_sys->mutex); - } - trx_free_for_background(trx); - return(ret); + ret = true; + goto cleanup; } /******************************************************************//** @@ -3495,8 +3488,8 @@ fts_add_doc_by_id( if (table->fts->cache->stopword_info.status & STOPWORD_NOT_INIT) { - fts_load_stopword(table, NULL, NULL, - NULL, TRUE, TRUE); + fts_load_stopword(table, NULL, + NULL, true, true); } fts_cache_add_doc( @@ -7244,21 +7237,19 @@ This function loads the stopword into the FTS cache. It also records/fetches stopword configuration to/from FTS configure table, depending on whether we are creating or reloading the FTS. -@return TRUE if load operation is successful */ +@return true if load operation is successful */ UNIV_INTERN -ibool +bool fts_load_stopword( /*==============*/ const dict_table_t* table, /*!< in: Table with FTS */ trx_t* trx, /*!< in: Transactions */ - const char* global_stopword_table, /*!< in: Global stopword table - name */ const char* session_stopword_table, /*!< in: Session stopword table name */ - ibool stopword_is_on, /*!< in: Whether stopword + bool stopword_is_on, /*!< in: Whether stopword option is turned on/off */ - ibool reload) /*!< in: Whether it is + bool reload) /*!< in: Whether it is for reloading FTS table */ { fts_table_t fts_table; @@ -7274,9 +7265,8 @@ fts_load_stopword( cache = table->fts->cache; - if (!reload && !(cache->stopword_info.status - & STOPWORD_NOT_INIT)) { - return(TRUE); + if (!reload && !(cache->stopword_info.status & STOPWORD_NOT_INIT)) { + return true; } if (!trx) { @@ -7321,12 +7311,11 @@ fts_load_stopword( goto cleanup; } - if (strlen((char*) str.f_str) > 0) { + if (*str.f_str) { stopword_to_use = (const char*) str.f_str; } } else { - stopword_to_use = (session_stopword_table) - ? session_stopword_table : global_stopword_table; + stopword_to_use = session_stopword_table; } if (stopword_to_use @@ -7363,7 +7352,7 @@ cleanup: sizeof(fts_tokenizer_word_t), fts_utf8_string_cmp); } - return(error == DB_SUCCESS); + return error == DB_SUCCESS; } /**********************************************************************//** @@ -7569,7 +7558,7 @@ fts_init_index( } else { if (table->fts->cache->stopword_info.status & STOPWORD_NOT_INIT) { - fts_load_stopword(table, NULL, NULL, NULL, TRUE, TRUE); + fts_load_stopword(table, NULL, NULL, true, true); } for (ulint i = 0; i < ib_vector_size(cache->get_docs); ++i) { diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index a1505eecd29..c54dae220ae 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -11508,10 +11508,17 @@ innobase_fts_load_stopword( trx_t* trx, /*!< in: transaction */ THD* thd) /*!< in: current thread */ { - return(fts_load_stopword(table, trx, - innobase_server_stopword_table, - THDVAR(thd, ft_user_stopword_table), - THDVAR(thd, ft_enable_stopword), FALSE)); + const char *stopword_table= THDVAR(thd, ft_user_stopword_table); + if (!stopword_table) + { + mysql_mutex_lock(&LOCK_global_system_variables); + if (innobase_server_stopword_table) + stopword_table= thd_strdup(thd, innobase_server_stopword_table); + mysql_mutex_unlock(&LOCK_global_system_variables); + } + + return fts_load_stopword(table, trx, stopword_table, + THDVAR(thd, ft_enable_stopword), false); } /*****************************************************************//** @@ -17054,7 +17061,6 @@ innodb_stopword_table_validate( char buff[STRING_BUFFER_USUAL_SIZE]; int len = sizeof(buff); trx_t* trx; - int ret = 1; ut_a(save != NULL); ut_a(value != NULL); @@ -17067,14 +17073,22 @@ innodb_stopword_table_validate( /* Validate the stopword table's (if supplied) existence and of the right format */ - if (!stopword_table_name - || fts_valid_stopword_table(stopword_table_name)) { - *static_cast<const char**>(save) = stopword_table_name; - ret = 0; - } + int ret = stopword_table_name && !fts_valid_stopword_table( + stopword_table_name); row_mysql_unlock_data_dictionary(trx); + if (!ret) { + if (stopword_table_name == buff) { + ut_ad(static_cast<size_t>(len) < sizeof buff); + stopword_table_name = thd_strmake(thd, + stopword_table_name, + len); + } + + *static_cast<const char**>(save) = stopword_table_name; + } + return(ret); } @@ -17082,9 +17096,10 @@ innodb_stopword_table_validate( static char* innodb_ft_aux_table; /** Update innodb_ft_aux_table_id on SET GLOBAL innodb_ft_aux_table. +@param[in,out] thd connection @param[out] save new value of innodb_ft_aux_table @param[in] value user-specified value */ -static int innodb_ft_aux_table_validate(THD*, st_mysql_sys_var*, +static int innodb_ft_aux_table_validate(THD *thd, st_mysql_sys_var*, void* save, st_mysql_value* value) { char buf[STRING_BUFFER_USUAL_SIZE]; @@ -17098,6 +17113,15 @@ static int innodb_ft_aux_table_validate(THD*, st_mysql_sys_var*, dict_table_close(table, FALSE, FALSE); if (id) { innodb_ft_aux_table_id = id; + if (table_name == buf) { + ut_ad(static_cast<size_t>(len) + < sizeof buf); + table_name = thd_strmake(thd, + table_name, + len); + } + + *static_cast<const char**>(save) = table_name; return 0; } @@ -17796,52 +17820,43 @@ exit: return; } -#ifdef __WIN__ -/*************************************************************//** -Validate if passed-in "value" is a valid value for -innodb_buffer_pool_filename. On Windows, file names with colon (:) -are not allowed. - +/** Validate SET GLOBAL innodb_buffer_pool_filename. +On Windows, file names with colon (:) are not allowed. +@param thd connection +@param save &srv_buf_dump_filename +@param value new value to be validated @return 0 for valid name */ -static -int -innodb_srv_buf_dump_filename_validate( -/*==================================*/ - THD* thd, /*!< in: thread handle */ - struct st_mysql_sys_var* var, /*!< in: pointer to system - variable */ - void* save, /*!< out: immediate result - for update function */ - struct st_mysql_value* value) /*!< in: incoming string */ +static int innodb_srv_buf_dump_filename_validate(THD *thd, st_mysql_sys_var*, + void *save, + st_mysql_value *value) { - const char* buf_name; - char buff[OS_FILE_MAX_PATH]; - int len= sizeof(buff); - - ut_a(save != NULL); - ut_a(value != NULL); + char buff[OS_FILE_MAX_PATH]; + int len= sizeof buff; - buf_name = value->val_str(value, buff, &len); - - if (buf_name) { - if (is_filename_allowed(buf_name, len, FALSE)){ - *static_cast<const char**>(save) = buf_name; - return(0); - } else { - push_warning_printf(thd, - Sql_condition::WARN_LEVEL_WARN, - ER_WRONG_ARGUMENTS, - "InnoDB: innodb_buffer_pool_filename " - "cannot have colon (:) in the file name."); - - } - } + if (const char *buf_name= value->val_str(value, buff, &len)) + { +#ifdef __WIN__ + if (!is_filename_allowed(buf_name, len, FALSE)) + { + push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, + ER_WRONG_ARGUMENTS, + "InnoDB: innodb_buffer_pool_filename " + "cannot have colon (:) in the file name."); + return 1; + } +#endif /* __WIN__ */ + if (buf_name == buff) + { + ut_ad(static_cast<size_t>(len) < sizeof buff); + buf_name= thd_strmake(thd, buf_name, len); + } + + *static_cast<const char**>(save)= buf_name; + return 0; + } - return(1); + return 1; } -#else /* __WIN__ */ -# define innodb_srv_buf_dump_filename_validate NULL -#endif /* __WIN__ */ #ifdef UNIV_DEBUG static char* srv_buffer_pool_evict; diff --git a/storage/innobase/include/fts0fts.h b/storage/innobase/include/fts0fts.h index 3beddd68722..886ac257f01 100644 --- a/storage/innobase/include/fts0fts.h +++ b/storage/innobase/include/fts0fts.h @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 2011, 2018, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2016, 2019, MariaDB Corporation. +Copyright (c) 2016, 2020, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -899,21 +899,19 @@ fts_valid_stopword_table( name */ /****************************************************************//** This function loads specified stopword into FTS cache -@return TRUE if success */ +@return true if success */ UNIV_INTERN -ibool +bool fts_load_stopword( /*==============*/ const dict_table_t* table, /*!< in: Table with FTS */ trx_t* trx, /*!< in: Transaction */ - const char* global_stopword_table, /*!< in: Global stopword table - name */ const char* session_stopword_table, /*!< in: Session stopword table name */ - ibool stopword_is_on, /*!< in: Whether stopword + bool stopword_is_on, /*!< in: Whether stopword option is turned on/off */ - ibool reload); /*!< in: Whether it is during + bool reload); /*!< in: Whether it is during reload of FTS table */ /****************************************************************//** diff --git a/storage/xtradb/buf/buf0dump.cc b/storage/xtradb/buf/buf0dump.cc index 349e7d45ab8..20dec30d106 100644 --- a/storage/xtradb/buf/buf0dump.cc +++ b/storage/xtradb/buf/buf0dump.cc @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 2011, 2017, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2017, 2018, MariaDB Corporation. +Copyright (c) 2017, 2020, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -176,7 +176,7 @@ get_buf_dump_dir() /* The dump file should be created in the default data directory if innodb_data_home_dir is set as an empty string. */ - if (strcmp(srv_data_home, "") == 0) { + if (!*srv_data_home) { dump_dir = fil_path_to_mysql_datadir; } else { dump_dir = srv_data_home; @@ -208,9 +208,11 @@ buf_dump( ulint i; int ret; + mysql_mutex_lock(&LOCK_global_system_variables); ut_snprintf(full_filename, sizeof(full_filename), "%s%c%s", get_buf_dump_dir(), SRV_PATH_SEPARATOR, srv_buf_dump_filename); + mysql_mutex_unlock(&LOCK_global_system_variables); ut_snprintf(tmp_filename, sizeof(tmp_filename), format_name, full_filename); @@ -514,9 +516,11 @@ buf_load() /* Ignore any leftovers from before */ buf_load_abort_flag = FALSE; + mysql_mutex_lock(&LOCK_global_system_variables); ut_snprintf(full_filename, sizeof(full_filename), "%s%c%s", get_buf_dump_dir(), SRV_PATH_SEPARATOR, srv_buf_dump_filename); + mysql_mutex_unlock(&LOCK_global_system_variables); buf_load_status(STATUS_NOTICE, "Loading buffer pool(s) from %s", full_filename); diff --git a/storage/xtradb/fts/fts0fts.cc b/storage/xtradb/fts/fts0fts.cc index 6dbe5e0e2a0..54cf2f11884 100644 --- a/storage/xtradb/fts/fts0fts.cc +++ b/storage/xtradb/fts/fts0fts.cc @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 2011, 2018, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2016, 2019, MariaDB Corporation. +Copyright (c) 2016, 2020, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -443,9 +443,9 @@ fts_read_stopword( /******************************************************************//** Load user defined stopword from designated user table -@return TRUE if load operation is successful */ +@return whether the operation is successful */ static -ibool +bool fts_load_user_stopword( /*===================*/ fts_t* fts, /*!< in: FTS struct */ @@ -453,27 +453,26 @@ fts_load_user_stopword( name */ fts_stopword_t* stopword_info) /*!< in: Stopword info */ { - pars_info_t* info; - que_t* graph; - dberr_t error = DB_SUCCESS; - ibool ret = TRUE; - trx_t* trx; - ibool has_lock = fts->dict_locked; - - trx = trx_allocate_for_background(); - trx->op_info = "Load user stopword table into FTS cache"; - - if (!has_lock) { + if (!fts->dict_locked) { mutex_enter(&dict_sys->mutex); } - /* Validate the user table existence and in the right - format */ + /* Validate the user table existence in the right format */ + bool ret= false; stopword_info->charset = fts_valid_stopword_table(stopword_table_name); if (!stopword_info->charset) { - ret = FALSE; - goto cleanup; - } else if (!stopword_info->cached_stopword) { +cleanup: + if (!fts->dict_locked) { + mutex_exit(&dict_sys->mutex); + } + + return ret; + } + + trx_t* trx = trx_allocate_for_background(); + trx->op_info = "Load user stopword table into FTS cache"; + + if (!stopword_info->cached_stopword) { /* Create the stopword RB tree with the stopword column charset. All comparison will use this charset */ stopword_info->cached_stopword = rbt_create_arg_cmp( @@ -482,14 +481,14 @@ fts_load_user_stopword( } - info = pars_info_create(); + pars_info_t* info = pars_info_create(); pars_info_bind_id(info, TRUE, "table_stopword", stopword_table_name); pars_info_bind_function(info, "my_func", fts_read_stopword, stopword_info); - graph = fts_parse_sql_no_dict_lock( + que_t* graph = fts_parse_sql_no_dict_lock( NULL, info, "DECLARE FUNCTION my_func;\n" @@ -508,14 +507,13 @@ fts_load_user_stopword( "CLOSE c;"); for (;;) { - error = fts_eval_sql(trx, graph); + dberr_t error = fts_eval_sql(trx, graph); if (error == DB_SUCCESS) { fts_sql_commit(trx); stopword_info->status = STOPWORD_USER_TABLE; break; } else { - fts_sql_rollback(trx); ut_print_timestamp(stderr); @@ -537,14 +535,9 @@ fts_load_user_stopword( } que_graph_free(graph); - -cleanup: - if (!has_lock) { - mutex_exit(&dict_sys->mutex); - } - trx_free_for_background(trx); - return(ret); + ret = true; + goto cleanup; } /******************************************************************//** @@ -3495,8 +3488,8 @@ fts_add_doc_by_id( if (table->fts->cache->stopword_info.status & STOPWORD_NOT_INIT) { - fts_load_stopword(table, NULL, NULL, - NULL, TRUE, TRUE); + fts_load_stopword(table, NULL, + NULL, true, true); } fts_cache_add_doc( @@ -7244,21 +7237,19 @@ This function loads the stopword into the FTS cache. It also records/fetches stopword configuration to/from FTS configure table, depending on whether we are creating or reloading the FTS. -@return TRUE if load operation is successful */ +@return true if load operation is successful */ UNIV_INTERN -ibool +bool fts_load_stopword( /*==============*/ const dict_table_t* table, /*!< in: Table with FTS */ trx_t* trx, /*!< in: Transactions */ - const char* global_stopword_table, /*!< in: Global stopword table - name */ const char* session_stopword_table, /*!< in: Session stopword table name */ - ibool stopword_is_on, /*!< in: Whether stopword + bool stopword_is_on, /*!< in: Whether stopword option is turned on/off */ - ibool reload) /*!< in: Whether it is + bool reload) /*!< in: Whether it is for reloading FTS table */ { fts_table_t fts_table; @@ -7274,9 +7265,8 @@ fts_load_stopword( cache = table->fts->cache; - if (!reload && !(cache->stopword_info.status - & STOPWORD_NOT_INIT)) { - return(TRUE); + if (!reload && !(cache->stopword_info.status & STOPWORD_NOT_INIT)) { + return true; } if (!trx) { @@ -7321,12 +7311,11 @@ fts_load_stopword( goto cleanup; } - if (strlen((char*) str.f_str) > 0) { + if (*str.f_str) { stopword_to_use = (const char*) str.f_str; } } else { - stopword_to_use = (session_stopword_table) - ? session_stopword_table : global_stopword_table; + stopword_to_use = session_stopword_table; } if (stopword_to_use @@ -7363,7 +7352,7 @@ cleanup: sizeof(fts_tokenizer_word_t), fts_utf8_string_cmp); } - return(error == DB_SUCCESS); + return error == DB_SUCCESS; } /**********************************************************************//** @@ -7569,7 +7558,7 @@ fts_init_index( } else { if (table->fts->cache->stopword_info.status & STOPWORD_NOT_INIT) { - fts_load_stopword(table, NULL, NULL, NULL, TRUE, TRUE); + fts_load_stopword(table, NULL, NULL, true, true); } for (ulint i = 0; i < ib_vector_size(cache->get_docs); ++i) { diff --git a/storage/xtradb/handler/ha_innodb.cc b/storage/xtradb/handler/ha_innodb.cc index 1593bf8ab46..c57870915dc 100644 --- a/storage/xtradb/handler/ha_innodb.cc +++ b/storage/xtradb/handler/ha_innodb.cc @@ -12056,10 +12056,17 @@ innobase_fts_load_stopword( trx_t* trx, /*!< in: transaction */ THD* thd) /*!< in: current thread */ { - return(fts_load_stopword(table, trx, - innobase_server_stopword_table, - THDVAR(thd, ft_user_stopword_table), - THDVAR(thd, ft_enable_stopword), FALSE)); + const char *stopword_table= THDVAR(thd, ft_user_stopword_table); + if (!stopword_table) + { + mysql_mutex_lock(&LOCK_global_system_variables); + if (innobase_server_stopword_table) + stopword_table= thd_strdup(thd, innobase_server_stopword_table); + mysql_mutex_unlock(&LOCK_global_system_variables); + } + + return fts_load_stopword(table, trx, stopword_table, + THDVAR(thd, ft_enable_stopword), false); } /*****************************************************************//** @@ -17766,7 +17773,6 @@ innodb_stopword_table_validate( char buff[STRING_BUFFER_USUAL_SIZE]; int len = sizeof(buff); trx_t* trx; - int ret = 1; ut_a(save != NULL); ut_a(value != NULL); @@ -17779,14 +17785,22 @@ innodb_stopword_table_validate( /* Validate the stopword table's (if supplied) existence and of the right format */ - if (!stopword_table_name - || fts_valid_stopword_table(stopword_table_name)) { - *static_cast<const char**>(save) = stopword_table_name; - ret = 0; - } + int ret = stopword_table_name && !fts_valid_stopword_table( + stopword_table_name); row_mysql_unlock_data_dictionary(trx); + if (!ret) { + if (stopword_table_name == buff) { + ut_ad(static_cast<size_t>(len) < sizeof buff); + stopword_table_name = thd_strmake(thd, + stopword_table_name, + len); + } + + *static_cast<const char**>(save) = stopword_table_name; + } + return(ret); } @@ -17794,9 +17808,10 @@ innodb_stopword_table_validate( static char* innodb_ft_aux_table; /** Update innodb_ft_aux_table_id on SET GLOBAL innodb_ft_aux_table. +@param[in,out] thd connection @param[out] save new value of innodb_ft_aux_table @param[in] value user-specified value */ -static int innodb_ft_aux_table_validate(THD*, st_mysql_sys_var*, +static int innodb_ft_aux_table_validate(THD *thd, st_mysql_sys_var*, void* save, st_mysql_value* value) { char buf[STRING_BUFFER_USUAL_SIZE]; @@ -17810,6 +17825,15 @@ static int innodb_ft_aux_table_validate(THD*, st_mysql_sys_var*, dict_table_close(table, FALSE, FALSE); if (id) { innodb_ft_aux_table_id = id; + if (table_name == buf) { + ut_ad(static_cast<size_t>(len) + < sizeof buf); + table_name = thd_strmake(thd, + table_name, + len); + } + + *static_cast<const char**>(save) = table_name; return 0; } @@ -18508,52 +18532,43 @@ exit: return; } -#ifdef __WIN__ -/*************************************************************//** -Validate if passed-in "value" is a valid value for -innodb_buffer_pool_filename. On Windows, file names with colon (:) -are not allowed. - +/** Validate SET GLOBAL innodb_buffer_pool_filename. +On Windows, file names with colon (:) are not allowed. +@param thd connection +@param save &srv_buf_dump_filename +@param value new value to be validated @return 0 for valid name */ -static -int -innodb_srv_buf_dump_filename_validate( -/*==================================*/ - THD* thd, /*!< in: thread handle */ - struct st_mysql_sys_var* var, /*!< in: pointer to system - variable */ - void* save, /*!< out: immediate result - for update function */ - struct st_mysql_value* value) /*!< in: incoming string */ +static int innodb_srv_buf_dump_filename_validate(THD *thd, st_mysql_sys_var*, + void *save, + st_mysql_value *value) { - const char* buf_name; - char buff[OS_FILE_MAX_PATH]; - int len= sizeof(buff); - - ut_a(save != NULL); - ut_a(value != NULL); + char buff[OS_FILE_MAX_PATH]; + int len= sizeof buff; - buf_name = value->val_str(value, buff, &len); - - if (buf_name) { - if (is_filename_allowed(buf_name, len, FALSE)){ - *static_cast<const char**>(save) = buf_name; - return(0); - } else { - push_warning_printf(thd, - Sql_condition::WARN_LEVEL_WARN, - ER_WRONG_ARGUMENTS, - "InnoDB: innodb_buffer_pool_filename " - "cannot have colon (:) in the file name."); - - } - } + if (const char *buf_name= value->val_str(value, buff, &len)) + { +#ifdef __WIN__ + if (!is_filename_allowed(buf_name, len, FALSE)) + { + push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN, + ER_WRONG_ARGUMENTS, + "InnoDB: innodb_buffer_pool_filename " + "cannot have colon (:) in the file name."); + return 1; + } +#endif /* __WIN__ */ + if (buf_name == buff) + { + ut_ad(static_cast<size_t>(len) < sizeof buff); + buf_name= thd_strmake(thd, buf_name, len); + } + + *static_cast<const char**>(save)= buf_name; + return 0; + } - return(1); + return 1; } -#else /* __WIN__ */ -# define innodb_srv_buf_dump_filename_validate NULL -#endif /* __WIN__ */ #ifdef UNIV_DEBUG static char* srv_buffer_pool_evict; diff --git a/storage/xtradb/include/fts0fts.h b/storage/xtradb/include/fts0fts.h index 714f811db27..4d07ac1612f 100644 --- a/storage/xtradb/include/fts0fts.h +++ b/storage/xtradb/include/fts0fts.h @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 2011, 2018, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2016, 2019, MariaDB Corporation. +Copyright (c) 2016, 2020, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -899,21 +899,19 @@ fts_valid_stopword_table( name */ /****************************************************************//** This function loads specified stopword into FTS cache -@return TRUE if success */ +@return true if success */ UNIV_INTERN -ibool +bool fts_load_stopword( /*==============*/ const dict_table_t* table, /*!< in: Table with FTS */ trx_t* trx, /*!< in: Transaction */ - const char* global_stopword_table, /*!< in: Global stopword table - name */ const char* session_stopword_table, /*!< in: Session stopword table name */ - ibool stopword_is_on, /*!< in: Whether stopword + bool stopword_is_on, /*!< in: Whether stopword option is turned on/off */ - ibool reload); /*!< in: Whether it is during + bool reload); /*!< in: Whether it is during reload of FTS table */ /****************************************************************//** |