Commit 542f3264 authored by Marko Mäkelä's avatar Marko Mäkelä

MDEV-18220: race condition in fts_get_table_name()

fts_get_table_name(): Add the parameter bool dict_locked=false.
parent f3718a11
/*****************************************************************************
Copyright (c) 2007, 2013, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2017, 2019, 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
......@@ -223,8 +224,11 @@ fts_config_set_value(
pars_info_bind_varchar_literal(info, "value",
value->f_str, value->f_len);
const bool dict_locked = fts_table->table->fts->fts_status
& TABLE_DICT_LOCKED;
fts_table->suffix = "CONFIG";
fts_get_table_name(fts_table, table_name);
fts_get_table_name(fts_table, table_name, dict_locked);
pars_info_bind_id(info, true, "table_name", table_name);
graph = fts_parse_sql(
......@@ -252,7 +256,7 @@ fts_config_set_value(
pars_info_bind_varchar_literal(
info, "value", value->f_str, value->f_len);
fts_get_table_name(fts_table, table_name);
fts_get_table_name(fts_table, table_name, dict_locked);
pars_info_bind_id(info, true, "table_name", table_name);
graph = fts_parse_sql(
......
......@@ -1593,7 +1593,7 @@ fts_rename_aux_tables(
for (i = 0; fts_common_tables[i] != NULL; ++i) {
fts_table.suffix = fts_common_tables[i];
fts_get_table_name(&fts_table, old_table_name);
fts_get_table_name(&fts_table, old_table_name, true);
err = fts_rename_one_aux_table(new_name, old_table_name, trx);
......@@ -1616,7 +1616,7 @@ fts_rename_aux_tables(
for (ulint j = 0; fts_index_selector[j].value; ++j) {
fts_table.suffix = fts_get_suffix(j);
fts_get_table_name(&fts_table, old_table_name);
fts_get_table_name(&fts_table, old_table_name, true);
err = fts_rename_one_aux_table(
new_name, old_table_name, trx);
......@@ -1656,7 +1656,7 @@ fts_drop_common_tables(
fts_table->suffix = fts_common_tables[i];
fts_get_table_name(fts_table, table_name);
fts_get_table_name(fts_table, table_name, true);
err = fts_drop_table(trx, table_name);
......@@ -1693,7 +1693,7 @@ fts_drop_index_split_tables(
fts_table.suffix = fts_get_suffix(i);
fts_get_table_name(&fts_table, table_name);
fts_get_table_name(&fts_table, table_name, true);
err = fts_drop_table(trx, table_name);
......@@ -1741,7 +1741,7 @@ fts_drop_index_tables(
fts_table.suffix = index_tables[i];
fts_get_table_name(&fts_table, table_name);
fts_get_table_name(&fts_table, table_name, true);
err = fts_drop_table(trx, table_name);
......@@ -1856,7 +1856,7 @@ fts_create_common_tables(
for (i = 0; fts_common_tables[i] != NULL; ++i) {
fts_table.suffix = fts_common_tables[i];
fts_get_table_name(&fts_table, full_name[i]);
fts_get_table_name(&fts_table, full_name[i], true);
pars_info_bind_id(info, true,
fts_common_tables[i], full_name[i]);
......@@ -1878,7 +1878,7 @@ fts_create_common_tables(
info = pars_info_create();
fts_table.suffix = "CONFIG";
fts_get_table_name(&fts_table, fts_name);
fts_get_table_name(&fts_table, fts_name, true);
pars_info_bind_id(info, true, "config_table", fts_name);
graph = fts_parse_sql_no_dict_lock(
......@@ -1957,7 +1957,7 @@ fts_create_one_index_table(
ut_ad(index->type & DICT_FTS);
fts_get_table_name(fts_table, table_name);
fts_get_table_name(fts_table, table_name, true);
if (srv_file_per_table) {
flags2 = DICT_TF2_USE_TABLESPACE;
......@@ -2039,7 +2039,7 @@ fts_create_index_tables_low(
info = pars_info_create();
fts_table.suffix = "DOC_ID";
fts_get_table_name(&fts_table, fts_name);
fts_get_table_name(&fts_table, fts_name, true);
pars_info_bind_id(info, true, "doc_id_table", fts_name);
......@@ -2068,7 +2068,7 @@ fts_create_index_tables_low(
break;
}
fts_get_table_name(&fts_table, fts_name);
fts_get_table_name(&fts_table, fts_name, true);
pars_info_bind_id(info, true, "table", fts_name);
......@@ -2835,7 +2835,8 @@ fts_update_sync_doc_id(
pars_info_bind_varchar_literal(info, "doc_id", id, id_len);
fts_get_table_name(&fts_table, fts_name);
fts_get_table_name(&fts_table, fts_name,
table->fts->fts_status & TABLE_DICT_LOCKED);
pars_info_bind_id(info, true, "table_name", fts_name);
graph = fts_parse_sql(
......
......@@ -121,16 +121,25 @@ UNIV_INTERN char* fts_get_table_name_prefix(const fts_table_t* fts_table)
/** Construct the name of an internal FTS table for the given table.
@param[in] fts_table metadata on fulltext-indexed table
@param[out] table_name a name up to MAX_FULL_NAME_LEN */
@param[out] table_name a name up to MAX_FULL_NAME_LEN
@param[in] dict_locked whether dict_sys->mutex is being held */
UNIV_INTERN
void fts_get_table_name(const fts_table_t* fts_table, char* table_name)
void fts_get_table_name(const fts_table_t* fts_table, char* table_name,
bool dict_locked)
{
if (!dict_locked) {
mutex_enter(&dict_sys->mutex);
}
ut_ad(mutex_own(&dict_sys->mutex));
const char* slash = strchr(fts_table->table->name, '/');
ut_ad(slash);
/* Include the separator as well. */
const size_t dbname_len = (slash - fts_table->table->name) + 1;
ut_ad(dbname_len > 1);
memcpy(table_name, fts_table->table->name, dbname_len);
if (!dict_locked) {
mutex_exit(&dict_sys->mutex);
}
memcpy(table_name += dbname_len, "FTS_", 4);
table_name += 4;
table_name += fts_get_table_id(fts_table, table_name);
......
......@@ -136,9 +136,11 @@ fts_eval_sql(
/** Construct the name of an internal FTS table for the given table.
@param[in] fts_table metadata on fulltext-indexed table
@param[out] table_name a name up to MAX_FULL_NAME_LEN */
@param[out] table_name a name up to MAX_FULL_NAME_LEN
@param[in] dict_locked whether dict_sys->mutex is being held */
UNIV_INTERN
void fts_get_table_name(const fts_table_t* fts_table, char* table_name)
void fts_get_table_name(const fts_table_t* fts_table, char* table_name,
bool dict_locked = false)
MY_ATTRIBUTE((nonnull));
/******************************************************************//**
Construct the column specification part of the SQL string for selecting the
......
/*****************************************************************************
Copyright (c) 2007, 2013, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2017, 2019, 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
......@@ -223,8 +224,11 @@ fts_config_set_value(
pars_info_bind_varchar_literal(info, "value",
value->f_str, value->f_len);
const bool dict_locked = fts_table->table->fts->fts_status
& TABLE_DICT_LOCKED;
fts_table->suffix = "CONFIG";
fts_get_table_name(fts_table, table_name);
fts_get_table_name(fts_table, table_name, dict_locked);
pars_info_bind_id(info, true, "table_name", table_name);
graph = fts_parse_sql(
......@@ -252,7 +256,7 @@ fts_config_set_value(
pars_info_bind_varchar_literal(
info, "value", value->f_str, value->f_len);
fts_get_table_name(fts_table, table_name);
fts_get_table_name(fts_table, table_name, dict_locked);
pars_info_bind_id(info, true, "table_name", table_name);
graph = fts_parse_sql(
......
......@@ -1593,7 +1593,7 @@ fts_rename_aux_tables(
for (i = 0; fts_common_tables[i] != NULL; ++i) {
fts_table.suffix = fts_common_tables[i];
fts_get_table_name(&fts_table, old_table_name);
fts_get_table_name(&fts_table, old_table_name, true);
err = fts_rename_one_aux_table(new_name, old_table_name, trx);
......@@ -1616,7 +1616,7 @@ fts_rename_aux_tables(
for (ulint j = 0; fts_index_selector[j].value; ++j) {
fts_table.suffix = fts_get_suffix(j);
fts_get_table_name(&fts_table, old_table_name);
fts_get_table_name(&fts_table, old_table_name, true);
err = fts_rename_one_aux_table(
new_name, old_table_name, trx);
......@@ -1656,7 +1656,7 @@ fts_drop_common_tables(
fts_table->suffix = fts_common_tables[i];
fts_get_table_name(fts_table, table_name);
fts_get_table_name(fts_table, table_name, true);
err = fts_drop_table(trx, table_name);
......@@ -1693,7 +1693,7 @@ fts_drop_index_split_tables(
fts_table.suffix = fts_get_suffix(i);
fts_get_table_name(&fts_table, table_name);
fts_get_table_name(&fts_table, table_name, true);
err = fts_drop_table(trx, table_name);
......@@ -1741,7 +1741,7 @@ fts_drop_index_tables(
fts_table.suffix = index_tables[i];
fts_get_table_name(&fts_table, table_name);
fts_get_table_name(&fts_table, table_name, true);
err = fts_drop_table(trx, table_name);
......@@ -1856,7 +1856,7 @@ fts_create_common_tables(
for (i = 0; fts_common_tables[i] != NULL; ++i) {
fts_table.suffix = fts_common_tables[i];
fts_get_table_name(&fts_table, full_name[i]);
fts_get_table_name(&fts_table, full_name[i], true);
pars_info_bind_id(info, true,
fts_common_tables[i], full_name[i]);
......@@ -1878,7 +1878,7 @@ fts_create_common_tables(
info = pars_info_create();
fts_table.suffix = "CONFIG";
fts_get_table_name(&fts_table, fts_name);
fts_get_table_name(&fts_table, fts_name, true);
pars_info_bind_id(info, true, "config_table", fts_name);
graph = fts_parse_sql_no_dict_lock(
......@@ -1957,7 +1957,7 @@ fts_create_one_index_table(
ut_ad(index->type & DICT_FTS);
fts_get_table_name(fts_table, table_name);
fts_get_table_name(fts_table, table_name, true);
if (srv_file_per_table) {
flags2 = DICT_TF2_USE_TABLESPACE;
......@@ -2039,7 +2039,7 @@ fts_create_index_tables_low(
info = pars_info_create();
fts_table.suffix = "DOC_ID";
fts_get_table_name(&fts_table, fts_name);
fts_get_table_name(&fts_table, fts_name, true);
pars_info_bind_id(info, true, "doc_id_table", fts_name);
......@@ -2068,7 +2068,7 @@ fts_create_index_tables_low(
break;
}
fts_get_table_name(&fts_table, fts_name);
fts_get_table_name(&fts_table, fts_name, true);
pars_info_bind_id(info, true, "table", fts_name);
......@@ -2835,7 +2835,8 @@ fts_update_sync_doc_id(
pars_info_bind_varchar_literal(info, "doc_id", id, id_len);
fts_get_table_name(&fts_table, fts_name);
fts_get_table_name(&fts_table, fts_name,
table->fts->fts_status & TABLE_DICT_LOCKED);
pars_info_bind_id(info, true, "table_name", fts_name);
graph = fts_parse_sql(
......
......@@ -121,16 +121,25 @@ UNIV_INTERN char* fts_get_table_name_prefix(const fts_table_t* fts_table)
/** Construct the name of an internal FTS table for the given table.
@param[in] fts_table metadata on fulltext-indexed table
@param[out] table_name a name up to MAX_FULL_NAME_LEN */
@param[out] table_name a name up to MAX_FULL_NAME_LEN
@param[in] dict_locked whether dict_sys->mutex is being held */
UNIV_INTERN
void fts_get_table_name(const fts_table_t* fts_table, char* table_name)
void fts_get_table_name(const fts_table_t* fts_table, char* table_name,
bool dict_locked)
{
if (!dict_locked) {
mutex_enter(&dict_sys->mutex);
}
ut_ad(mutex_own(&dict_sys->mutex));
const char* slash = strchr(fts_table->table->name, '/');
ut_ad(slash);
/* Include the separator as well. */
const size_t dbname_len = (slash - fts_table->table->name) + 1;
ut_ad(dbname_len > 1);
memcpy(table_name, fts_table->table->name, dbname_len);
if (!dict_locked) {
mutex_exit(&dict_sys->mutex);
}
memcpy(table_name += dbname_len, "FTS_", 4);
table_name += 4;
table_name += fts_get_table_id(fts_table, table_name);
......
......@@ -136,9 +136,11 @@ fts_eval_sql(
/** Construct the name of an internal FTS table for the given table.
@param[in] fts_table metadata on fulltext-indexed table
@param[out] table_name a name up to MAX_FULL_NAME_LEN */
@param[out] table_name a name up to MAX_FULL_NAME_LEN
@param[in] dict_locked whether dict_sys->mutex is being held */
UNIV_INTERN
void fts_get_table_name(const fts_table_t* fts_table, char* table_name)
void fts_get_table_name(const fts_table_t* fts_table, char* table_name,
bool dict_locked = false)
MY_ATTRIBUTE((nonnull));
/******************************************************************//**
Construct the column specification part of the SQL string for selecting the
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment