summaryrefslogtreecommitdiff
path: root/storage
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2020-04-28 14:51:25 +0300
committerMarko Mäkelä <marko.makela@mariadb.com>2020-04-28 16:09:07 +0300
commit704180747658019aa52173e44e99229b8ae56efa (patch)
tree99d3256ba9302fccc89217a404328750a766e43b /storage
parentcce1b6e245a7ee30e6ebfcd45556e8caa6e754c2 (diff)
downloadmariadb-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.cc8
-rw-r--r--storage/innobase/fts/fts0fts.cc81
-rw-r--r--storage/innobase/handler/ha_innodb.cc119
-rw-r--r--storage/innobase/include/fts0fts.h12
-rw-r--r--storage/xtradb/buf/buf0dump.cc8
-rw-r--r--storage/xtradb/fts/fts0fts.cc81
-rw-r--r--storage/xtradb/handler/ha_innodb.cc119
-rw-r--r--storage/xtradb/include/fts0fts.h12
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 */
/****************************************************************//**