summaryrefslogtreecommitdiff
path: root/storage
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2019-05-09 09:31:30 +0300
committerMarko Mäkelä <marko.makela@mariadb.com>2019-05-10 07:57:01 +0300
commitf3718a112a9b29caca1cba35ddaa6cf62f15ed99 (patch)
treeca689652075b39f349f4c042940a6f829d973133 /storage
parentf92749ed36e02342abfc82d2c354c73e188ff718 (diff)
downloadmariadb-git-f3718a112a9b29caca1cba35ddaa6cf62f15ed99.tar.gz
MDEV-18220: Backport some code from MariaDB 10.2
fts_get_table_name(): Output to a caller-allocated buffer. fts_get_table_name_prefix(): Use the lower-overhead allocation ut_malloc() instead of mem_alloc(). This is based on mysql/mysql-server@d1584b9f38ff0bcf609d181db35f74108e022168 in MySQL 5.7.4.
Diffstat (limited to 'storage')
-rw-r--r--storage/innobase/fts/fts0config.cc21
-rw-r--r--storage/innobase/fts/fts0fts.cc210
-rw-r--r--storage/innobase/fts/fts0opt.cc138
-rw-r--r--storage/innobase/fts/fts0que.cc30
-rw-r--r--storage/innobase/fts/fts0sql.cc140
-rw-r--r--storage/innobase/handler/i_s.cc5
-rw-r--r--storage/innobase/include/fts0priv.h30
-rw-r--r--storage/xtradb/fts/fts0config.cc21
-rw-r--r--storage/xtradb/fts/fts0fts.cc210
-rw-r--r--storage/xtradb/fts/fts0opt.cc138
-rw-r--r--storage/xtradb/fts/fts0que.cc30
-rw-r--r--storage/xtradb/fts/fts0sql.cc140
-rw-r--r--storage/xtradb/handler/i_s.cc5
-rw-r--r--storage/xtradb/include/fts0priv.h30
14 files changed, 612 insertions, 536 deletions
diff --git a/storage/innobase/fts/fts0config.cc b/storage/innobase/fts/fts0config.cc
index 5b4ae5c39f7..889f4a074b9 100644
--- a/storage/innobase/fts/fts0config.cc
+++ b/storage/innobase/fts/fts0config.cc
@@ -85,6 +85,7 @@ fts_config_get_value(
que_t* graph;
dberr_t error;
ulint name_len = strlen(name);
+ char table_name[MAX_FULL_NAME_LEN];
info = pars_info_create();
@@ -100,12 +101,14 @@ fts_config_get_value(
pars_info_bind_varchar_literal(info, "name", (byte*) name, name_len);
fts_table->suffix = "CONFIG";
+ fts_get_table_name(fts_table, table_name);
+ pars_info_bind_id(info, true, "table_name", table_name);
graph = fts_parse_sql(
fts_table,
info,
"DECLARE FUNCTION my_func;\n"
- "DECLARE CURSOR c IS SELECT value FROM \"%s\""
+ "DECLARE CURSOR c IS SELECT value FROM $table_name"
" WHERE key = :name;\n"
"BEGIN\n"
""
@@ -212,6 +215,7 @@ fts_config_set_value(
undo_no_t undo_no;
undo_no_t n_rows_updated;
ulint name_len = strlen(name);
+ char table_name[MAX_FULL_NAME_LEN];
info = pars_info_create();
@@ -220,10 +224,13 @@ fts_config_set_value(
value->f_str, value->f_len);
fts_table->suffix = "CONFIG";
+ fts_get_table_name(fts_table, table_name);
+ pars_info_bind_id(info, true, "table_name", table_name);
graph = fts_parse_sql(
fts_table, info,
- "BEGIN UPDATE \"%s\" SET value = :value WHERE key = :name;");
+ "BEGIN UPDATE $table_name SET value = :value "
+ "WHERE key = :name;");
trx->op_info = "setting FTS config value";
@@ -245,10 +252,13 @@ 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);
+ pars_info_bind_id(info, true, "table_name", table_name);
+
graph = fts_parse_sql(
fts_table, info,
"BEGIN\n"
- "INSERT INTO \"%s\" VALUES(:name, :value);");
+ "INSERT INTO $table_name VALUES(:name, :value);");
trx->op_info = "inserting FTS config value";
@@ -465,6 +475,7 @@ fts_config_increment_value(
que_t* graph = NULL;
ulint name_len = strlen(name);
pars_info_t* info = pars_info_create();
+ char table_name[MAX_FULL_NAME_LEN];
/* We set the length of value to the max bytes it can hold. This
information is used by the callback that reads the value.*/
@@ -479,11 +490,13 @@ fts_config_increment_value(
info, "my_func", fts_config_fetch_value, &value);
fts_table->suffix = "CONFIG";
+ fts_get_table_name(fts_table, table_name);
+ pars_info_bind_id(info, true, "config_table", table_name);
graph = fts_parse_sql(
fts_table, info,
"DECLARE FUNCTION my_func;\n"
- "DECLARE CURSOR c IS SELECT value FROM \"%s\""
+ "DECLARE CURSOR c IS SELECT value FROM $config_table"
" WHERE key = :name FOR UPDATE;\n"
"BEGIN\n"
""
diff --git a/storage/innobase/fts/fts0fts.cc b/storage/innobase/fts/fts0fts.cc
index 9c90ec91ce7..0dea97b6e20 100644
--- a/storage/innobase/fts/fts0fts.cc
+++ b/storage/innobase/fts/fts0fts.cc
@@ -167,38 +167,39 @@ struct fts_aux_table_t {
char* name; /*!< Name of the table */
};
-/** SQL statements for creating the ancillary common FTS tables. */
+/** SQL statements for creating the ancillary common FTS tables.
+The table name here shall be consistent with fts_common_tables. */
static const char* fts_create_common_tables_sql = {
"BEGIN\n"
""
- "CREATE TABLE \"%s_DELETED\" (\n"
+ "CREATE TABLE $DELETED (\n"
" doc_id BIGINT UNSIGNED\n"
") COMPACT;\n"
- "CREATE UNIQUE CLUSTERED INDEX IND ON \"%s_DELETED\"(doc_id);\n"
+ "CREATE UNIQUE CLUSTERED INDEX IND ON $DELETED (doc_id);\n"
""
- "CREATE TABLE \"%s_DELETED_CACHE\" (\n"
+ "CREATE TABLE $DELETED_CACHE (\n"
" doc_id BIGINT UNSIGNED\n"
") COMPACT;\n"
"CREATE UNIQUE CLUSTERED INDEX IND "
- "ON \"%s_DELETED_CACHE\"(doc_id);\n"
+ "ON $DELETED_CACHE(doc_id);\n"
""
- "CREATE TABLE \"%s_BEING_DELETED\" (\n"
+ "CREATE TABLE $BEING_DELETED (\n"
" doc_id BIGINT UNSIGNED\n"
") COMPACT;\n"
"CREATE UNIQUE CLUSTERED INDEX IND "
- "ON \"%s_BEING_DELETED\"(doc_id);\n"
+ "ON $BEING_DELETED(doc_id);\n"
""
- "CREATE TABLE \"%s_BEING_DELETED_CACHE\" (\n"
+ "CREATE TABLE $BEING_DELETED_CACHE (\n"
" doc_id BIGINT UNSIGNED\n"
") COMPACT;\n"
"CREATE UNIQUE CLUSTERED INDEX IND "
- "ON \"%s_BEING_DELETED_CACHE\"(doc_id);\n"
+ "ON $BEING_DELETED_CACHE(doc_id);\n"
""
- "CREATE TABLE \"%s_CONFIG\" (\n"
+ "CREATE TABLE $CONFIG (\n"
" key CHAR(50),\n"
" value CHAR(200) NOT NULL\n"
") COMPACT;\n"
- "CREATE UNIQUE CLUSTERED INDEX IND ON \"%s_CONFIG\"(key);\n"
+ "CREATE UNIQUE CLUSTERED INDEX IND ON $CONFIG(key);\n"
};
#ifdef FTS_DOC_STATS_DEBUG
@@ -207,11 +208,11 @@ mainly designed for the statistics work in the future */
static const char* fts_create_index_tables_sql = {
"BEGIN\n"
""
- "CREATE TABLE \"%s_DOC_ID\" (\n"
+ "CREATE TABLE $doc_id_table (\n"
" doc_id BIGINT UNSIGNED,\n"
" word_count INTEGER UNSIGNED NOT NULL\n"
") COMPACT;\n"
- "CREATE UNIQUE CLUSTERED INDEX IND ON \"%s_DOC_ID\"(doc_id);\n"
+ "CREATE UNIQUE CLUSTERED INDEX IND ON $doc_id_table(doc_id);\n"
};
#endif
@@ -220,11 +221,11 @@ static const char* fts_create_index_sql = {
"BEGIN\n"
""
"CREATE UNIQUE CLUSTERED INDEX FTS_INDEX_TABLE_IND "
- "ON \"%s\"(word, first_doc_id);\n"
+ "ON $table (word, first_doc_id);\n"
};
/** FTS auxiliary table suffixes that are common to all FT indexes. */
-static const char* fts_common_tables[] = {
+const char* fts_common_tables[] = {
"BEING_DELETED",
"BEING_DELETED_CACHE",
"CONFIG",
@@ -248,19 +249,19 @@ const fts_index_selector_t fts_index_selector[] = {
static const char* fts_config_table_insert_values_sql =
"BEGIN\n"
"\n"
- "INSERT INTO \"%s\" VALUES('"
+ "INSERT INTO $config_table VALUES('"
FTS_MAX_CACHE_SIZE_IN_MB "', '256');\n"
""
- "INSERT INTO \"%s\" VALUES('"
+ "INSERT INTO $config_table VALUES('"
FTS_OPTIMIZE_LIMIT_IN_SECS "', '180');\n"
""
- "INSERT INTO \"%s\" VALUES ('"
+ "INSERT INTO $config_table VALUES ('"
FTS_SYNCED_DOC_ID "', '0');\n"
""
- "INSERT INTO \"%s\" VALUES ('"
+ "INSERT INTO $config_table VALUES ('"
FTS_TOTAL_DELETED_COUNT "', '0');\n"
"" /* Note: 0 == FTS_TABLE_STATE_RUNNING */
- "INSERT INTO \"%s\" VALUES ('"
+ "INSERT INTO $config_table VALUES ('"
FTS_TABLE_STATE "', '0');\n";
/** Run SYNC on the table, i.e., write out data from the cache to the
@@ -1585,19 +1586,17 @@ fts_rename_aux_tables(
FTS_INIT_FTS_TABLE(&fts_table, NULL, FTS_COMMON_TABLE, table);
+ dberr_t err = DB_SUCCESS;
+ char old_table_name[MAX_FULL_NAME_LEN];
+
/* Rename common auxiliary tables */
for (i = 0; fts_common_tables[i] != NULL; ++i) {
- char* old_table_name;
- dberr_t err = DB_SUCCESS;
-
fts_table.suffix = fts_common_tables[i];
- old_table_name = fts_get_table_name(&fts_table);
+ fts_get_table_name(&fts_table, old_table_name);
err = fts_rename_one_aux_table(new_name, old_table_name, trx);
- mem_free(old_table_name);
-
if (err != DB_SUCCESS) {
return(err);
}
@@ -1616,12 +1615,8 @@ fts_rename_aux_tables(
FTS_INIT_INDEX_TABLE(&fts_table, NULL, FTS_INDEX_TABLE, index);
for (ulint j = 0; fts_index_selector[j].value; ++j) {
- dberr_t err;
- char* old_table_name;
-
fts_table.suffix = fts_get_suffix(j);
-
- old_table_name = fts_get_table_name(&fts_table);
+ fts_get_table_name(&fts_table, old_table_name);
err = fts_rename_one_aux_table(
new_name, old_table_name, trx);
@@ -1630,8 +1625,6 @@ fts_rename_aux_tables(
err = DB_DEADLOCK;
fts_sql_rollback(trx););
- mem_free(old_table_name);
-
if (err != DB_SUCCESS) {
return(err);
}
@@ -1659,11 +1652,11 @@ fts_drop_common_tables(
for (i = 0; fts_common_tables[i] != NULL; ++i) {
dberr_t err;
- char* table_name;
+ char table_name[MAX_FULL_NAME_LEN];
fts_table->suffix = fts_common_tables[i];
- table_name = fts_get_table_name(fts_table);
+ fts_get_table_name(fts_table, table_name);
err = fts_drop_table(trx, table_name);
@@ -1671,8 +1664,6 @@ fts_drop_common_tables(
if (err != DB_SUCCESS && err != DB_FAIL) {
error = err;
}
-
- mem_free(table_name);
}
return(error);
@@ -1698,11 +1689,11 @@ fts_drop_index_split_tables(
for (i = 0; fts_index_selector[i].value; ++i) {
dberr_t err;
- char* table_name;
+ char table_name[MAX_FULL_NAME_LEN];
fts_table.suffix = fts_get_suffix(i);
- table_name = fts_get_table_name(&fts_table);
+ fts_get_table_name(&fts_table, table_name);
err = fts_drop_table(trx, table_name);
@@ -1710,8 +1701,6 @@ fts_drop_index_split_tables(
if (err != DB_SUCCESS && err != DB_FAIL) {
error = err;
}
-
- mem_free(table_name);
}
return(error);
@@ -1748,11 +1737,11 @@ fts_drop_index_tables(
FTS_INIT_INDEX_TABLE(&fts_table, NULL, FTS_INDEX_TABLE, index);
for (ulint i = 0; index_tables[i] != NULL; ++i) {
- char* table_name;
+ char table_name[MAX_FULL_NAME_LEN];
fts_table.suffix = index_tables[i];
- table_name = fts_get_table_name(&fts_table);
+ fts_get_table_name(&fts_table, table_name);
err = fts_drop_table(trx, table_name);
@@ -1760,8 +1749,6 @@ fts_drop_index_tables(
if (err != DB_SUCCESS && err != DB_FAIL) {
error = err;
}
-
- mem_free(table_name);
}
#endif /* FTS_DOC_STATS_DEBUG */
@@ -1831,26 +1818,6 @@ fts_drop_tables(
}
/*********************************************************************//**
-Prepare the SQL, so that all '%s' are replaced by the common prefix.
-@return sql string, use mem_free() to free the memory */
-static
-char*
-fts_prepare_sql(
-/*============*/
- fts_table_t* fts_table, /*!< in: table name info */
- const char* my_template) /*!< in: sql template */
-{
- char* sql;
- char* name_prefix;
-
- name_prefix = fts_get_table_name_prefix(fts_table);
- sql = ut_strreplace(my_template, "%s", name_prefix);
- mem_free(name_prefix);
-
- return(sql);
-}
-
-/*********************************************************************//**
Creates the common ancillary tables needed for supporting an FTS index
on the given table. row_mysql_lock_data_dictionary must have been called
before this.
@@ -1864,12 +1831,15 @@ fts_create_common_tables(
const char* name, /*!< in: table name normalized.*/
bool skip_doc_id_index)/*!< in: Skip index on doc id */
{
- char* sql;
dberr_t error;
que_t* graph;
fts_table_t fts_table;
mem_heap_t* heap = mem_heap_create(1024);
pars_info_t* info;
+ char fts_name[MAX_FULL_NAME_LEN];
+ char full_name[sizeof(fts_common_tables) / sizeof(char*)]
+ [MAX_FULL_NAME_LEN];
+ ulint i;
FTS_INIT_FTS_TABLE(&fts_table, NULL, FTS_COMMON_TABLE, table);
@@ -1881,9 +1851,19 @@ fts_create_common_tables(
}
/* Create the FTS tables that are common to an FTS index. */
- sql = fts_prepare_sql(&fts_table, fts_create_common_tables_sql);
- graph = fts_parse_sql_no_dict_lock(NULL, NULL, sql);
- mem_free(sql);
+ info = pars_info_create();
+
+ 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]);
+
+ pars_info_bind_id(info, true,
+ fts_common_tables[i], full_name[i]);
+ }
+
+ graph = fts_parse_sql_no_dict_lock(NULL, info,
+ fts_create_common_tables_sql);
error = fts_eval_sql(trx, graph);
@@ -1895,9 +1875,14 @@ fts_create_common_tables(
}
/* Write the default settings to the config table. */
+ info = pars_info_create();
+
fts_table.suffix = "CONFIG";
+ fts_get_table_name(&fts_table, fts_name);
+ pars_info_bind_id(info, true, "config_table", fts_name);
+
graph = fts_parse_sql_no_dict_lock(
- &fts_table, NULL, fts_config_table_insert_values_sql);
+ &fts_table, info, fts_config_table_insert_values_sql);
error = fts_eval_sql(trx, graph);
@@ -1965,13 +1950,15 @@ fts_create_one_index_table(
{
dict_field_t* field;
dict_table_t* new_table = NULL;
- char* table_name = fts_get_table_name(fts_table);
+ char table_name[MAX_FULL_NAME_LEN];
dberr_t error;
CHARSET_INFO* charset;
ulint flags2 = 0;
ut_ad(index->type & DICT_FTS);
+ fts_get_table_name(fts_table, table_name);
+
if (srv_file_per_table) {
flags2 = DICT_TF2_USE_TABLESPACE;
}
@@ -2015,8 +2002,6 @@ fts_create_one_index_table(
"Fail to create FTS index table %s", table_name);
}
- mem_free(table_name);
-
return(new_table);
}
@@ -2039,7 +2024,9 @@ fts_create_index_tables_low(
que_t* graph;
fts_table_t fts_table;
dberr_t error = DB_SUCCESS;
+ pars_info_t* info;
mem_heap_t* heap = mem_heap_create(1024);
+ char fts_name[MAX_FULL_NAME_LEN];
fts_table.type = FTS_INDEX_TABLE;
fts_table.index_id = index->id;
@@ -2047,14 +2034,17 @@ fts_create_index_tables_low(
fts_table.table = index->table;
#ifdef FTS_DOC_STATS_DEBUG
- char* sql;
-
/* Create the FTS auxiliary tables that are specific
to an FTS index. */
- sql = fts_prepare_sql(&fts_table, fts_create_index_tables_sql);
+ info = pars_info_create();
+
+ fts_table.suffix = "DOC_ID";
+ fts_get_table_name(&fts_table, fts_name);
- graph = fts_parse_sql_no_dict_lock(NULL, NULL, sql);
- mem_free(sql);
+ pars_info_bind_id(info, true, "doc_id_table", fts_name);
+
+ graph = fts_parse_sql_no_dict_lock(NULL, info,
+ fts_create_index_tables_sql);
error = fts_eval_sql(trx, graph);
que_graph_free(graph);
@@ -2063,6 +2053,8 @@ fts_create_index_tables_low(
for (i = 0; fts_index_selector[i].value && error == DB_SUCCESS; ++i) {
dict_table_t* new_table;
+ info = pars_info_create();
+
/* Create the FTS auxiliary tables that are specific
to an FTS index. We need to preserve the table_id %s
which fts_parse_sql_no_dict_lock() will fill in for us. */
@@ -2076,8 +2068,12 @@ fts_create_index_tables_low(
break;
}
+ fts_get_table_name(&fts_table, fts_name);
+
+ pars_info_bind_id(info, true, "table", fts_name);
+
graph = fts_parse_sql_no_dict_lock(
- &fts_table, NULL, fts_create_index_sql);
+ &fts_table, info, fts_create_index_sql);
error = fts_eval_sql(trx, graph);
que_graph_free(graph);
@@ -2701,6 +2697,7 @@ fts_cmp_set_sync_doc_id(
fts_table_t fts_table;
que_t* graph = NULL;
fts_cache_t* cache = table->fts->cache;
+ char table_name[MAX_FULL_NAME_LEN];
retry:
ut_a(table->fts->doc_col != ULINT_UNDEFINED);
@@ -2718,10 +2715,13 @@ retry:
pars_info_bind_function(
info, "my_func", fts_fetch_store_doc_id, doc_id);
+ fts_get_table_name(&fts_table, table_name);
+ pars_info_bind_id(info, true, "config_table", table_name);
+
graph = fts_parse_sql(
&fts_table, info,
"DECLARE FUNCTION my_func;\n"
- "DECLARE CURSOR c IS SELECT value FROM \"%s\""
+ "DECLARE CURSOR c IS SELECT value FROM $config_table"
" WHERE key = 'synced_doc_id' FOR UPDATE;\n"
"BEGIN\n"
""
@@ -2814,6 +2814,7 @@ fts_update_sync_doc_id(
dberr_t error;
ibool local_trx = FALSE;
fts_cache_t* cache = table->fts->cache;
+ char fts_name[MAX_FULL_NAME_LEN];
fts_table.suffix = "CONFIG";
fts_table.table_id = table->id;
@@ -2834,10 +2835,13 @@ fts_update_sync_doc_id(
pars_info_bind_varchar_literal(info, "doc_id", id, id_len);
+ fts_get_table_name(&fts_table, fts_name);
+ pars_info_bind_id(info, true, "table_name", fts_name);
+
graph = fts_parse_sql(
&fts_table, info,
"BEGIN "
- "UPDATE \"%s\" SET value = :doc_id"
+ "UPDATE $table_name SET value = :doc_id"
" WHERE key = 'synced_doc_id';");
error = fts_eval_sql(trx, graph);
@@ -2984,6 +2988,7 @@ fts_delete(
/* Note the deleted document for OPTIMIZE to purge. */
if (error == DB_SUCCESS) {
+ char table_name[MAX_FULL_NAME_LEN];
trx->op_info = "adding doc id to FTS DELETED";
@@ -2991,10 +2996,13 @@ fts_delete(
fts_table.suffix = "DELETED";
+ fts_get_table_name(&fts_table, table_name);
+ pars_info_bind_id(info, true, "deleted", table_name);
+
graph = fts_parse_sql(
&fts_table,
info,
- "BEGIN INSERT INTO \"%s\" VALUES (:doc_id);");
+ "BEGIN INSERT INTO $deleted VALUES (:doc_id);");
error = fts_eval_sql(trx, graph);
@@ -3813,11 +3821,15 @@ fts_write_node(
ib_time_t start_time;
doc_id_t last_doc_id;
doc_id_t first_doc_id;
+ char table_name[MAX_FULL_NAME_LEN];
if (*graph) {
info = (*graph)->info;
} else {
info = pars_info_create();
+
+ fts_get_table_name(fts_table, table_name);
+ pars_info_bind_id(info, true, "index_table_name", table_name);
}
pars_info_bind_varchar_literal(info, "token", word->f_str, word->f_len);
@@ -3843,11 +3855,12 @@ fts_write_node(
DATA_BLOB, DATA_BINARY_TYPE);
if (!*graph) {
+
*graph = fts_parse_sql(
fts_table,
info,
"BEGIN\n"
- "INSERT INTO \"%s\" VALUES "
+ "INSERT INTO $index_table_name VALUES "
"(:token, :first_doc_id,"
" :last_doc_id, :doc_count, :ilist);");
}
@@ -3874,6 +3887,7 @@ fts_sync_add_deleted_cache(
pars_info_t* info;
que_t* graph;
fts_table_t fts_table;
+ char table_name[MAX_FULL_NAME_LEN];
doc_id_t dummy = 0;
dberr_t error = DB_SUCCESS;
ulint n_elems = ib_vector_size(doc_ids);
@@ -3889,10 +3903,13 @@ fts_sync_add_deleted_cache(
FTS_INIT_FTS_TABLE(
&fts_table, "DELETED_CACHE", FTS_COMMON_TABLE, sync->table);
+ fts_get_table_name(&fts_table, table_name);
+ pars_info_bind_id(info, true, "table_name", table_name);
+
graph = fts_parse_sql(
&fts_table,
info,
- "BEGIN INSERT INTO \"%s\" VALUES (:doc_id);");
+ "BEGIN INSERT INTO $table_name VALUES (:doc_id);");
for (i = 0; i < n_elems && error == DB_SUCCESS; ++i) {
fts_update_t* update;
@@ -4069,6 +4086,7 @@ fts_sync_write_doc_stat(
doc_id_t doc_id;
dberr_t error = DB_SUCCESS;
ib_uint32_t word_count;
+ char table_name[MAX_FULL_NAME_LEN];
if (*graph) {
info = (*graph)->info;
@@ -4091,10 +4109,15 @@ fts_sync_write_doc_stat(
FTS_INIT_INDEX_TABLE(
&fts_table, "DOC_ID", FTS_INDEX_TABLE, index);
+ fts_get_table_name(&fts_table, table_name);
+
+ pars_info_bind_id(info, true, "doc_id_table", table_name);
+
*graph = fts_parse_sql(
&fts_table,
info,
- "BEGIN INSERT INTO \"%s\" VALUES (:doc_id, :count);");
+ "BEGIN "
+ "INSERT INTO $doc_id_table VALUES (:doc_id, :count);");
}
for (;;) {
@@ -4216,6 +4239,7 @@ fts_is_word_in_index(
{
pars_info_t* info;
dberr_t error;
+ char table_name[MAX_FULL_NAME_LEN];
trx->op_info = "looking up word in FTS index";
@@ -4225,6 +4249,8 @@ fts_is_word_in_index(
info = pars_info_create();
}
+ fts_get_table_name(fts_table, table_name);
+ pars_info_bind_id(info, true, "table_name", table_name);
pars_info_bind_function(info, "my_func", fts_lookup_word, found);
pars_info_bind_varchar_literal(info, "word", word->f_str, word->f_len);
@@ -4235,7 +4261,7 @@ fts_is_word_in_index(
"DECLARE FUNCTION my_func;\n"
"DECLARE CURSOR c IS"
" SELECT doc_count\n"
- " FROM \"%s\"\n"
+ " FROM $table_name\n"
" WHERE word = :word "
" ORDER BY first_doc_id;\n"
"BEGIN\n"
@@ -4984,6 +5010,7 @@ fts_get_rows_count(
que_t* graph;
dberr_t error;
ulint count = 0;
+ char table_name[MAX_FULL_NAME_LEN];
trx = trx_allocate_for_background();
@@ -4993,13 +5020,16 @@ fts_get_rows_count(
pars_info_bind_function(info, "my_func", fts_read_ulint, &count);
+ fts_get_table_name(fts_table, table_name);
+ pars_info_bind_id(info, true, "table_name", table_name);
+
graph = fts_parse_sql(
fts_table,
info,
"DECLARE FUNCTION my_func;\n"
"DECLARE CURSOR c IS"
" SELECT COUNT(*) "
- " FROM \"%s\";\n"
+ " FROM $table_name;\n"
"BEGIN\n"
"\n"
"OPEN c;\n"
@@ -6208,7 +6238,7 @@ fts_rename_one_aux_table_to_hex_format(
{
const char* ptr;
fts_table_t fts_table;
- char* new_name;
+ char new_name[MAX_FULL_NAME_LEN];
dberr_t error;
ptr = strchr(aux_table->name, '/');
@@ -6253,7 +6283,7 @@ fts_rename_one_aux_table_to_hex_format(
fts_table.index_id = aux_table->index_id;
fts_table.table = parent_table;
- new_name = fts_get_table_name(&fts_table);
+ fts_get_table_name(&fts_table, new_name);
ut_ad(strcmp(new_name, aux_table->name) != 0);
if (trx_get_dict_operation(trx) == TRX_DICT_OP_NONE) {
@@ -6274,8 +6304,6 @@ fts_rename_one_aux_table_to_hex_format(
aux_table->name, new_name);
}
- mem_free(new_name);
-
return (error);
}
diff --git a/storage/innobase/fts/fts0opt.cc b/storage/innobase/fts/fts0opt.cc
index ad64f6d1d37..0d5185cc5fb 100644
--- a/storage/innobase/fts/fts0opt.cc
+++ b/storage/innobase/fts/fts0opt.cc
@@ -226,27 +226,30 @@ static ulint FTS_ZIP_BLOCK_SIZE = 1024;
/** The amount of time optimizing in a single pass, in milliseconds. */
static ib_time_t fts_optimize_time_limit = 0;
+/** It's defined in fts0fts.cc */
+extern const char* fts_common_tables[];
+
/** SQL Statement for changing state of rows to be deleted from FTS Index. */
static const char* fts_init_delete_sql =
"BEGIN\n"
"\n"
- "INSERT INTO \"%s_BEING_DELETED\"\n"
- "SELECT doc_id FROM \"%s_DELETED\";\n"
+ "INSERT INTO $BEING_DELETED\n"
+ "SELECT doc_id FROM $DELETED;\n"
"\n"
- "INSERT INTO \"%s_BEING_DELETED_CACHE\"\n"
- "SELECT doc_id FROM \"%s_DELETED_CACHE\";\n";
+ "INSERT INTO $BEING_DELETED_CACHE\n"
+ "SELECT doc_id FROM $DELETED_CACHE;\n";
static const char* fts_delete_doc_ids_sql =
"BEGIN\n"
"\n"
- "DELETE FROM \"%s_DELETED\" WHERE doc_id = :doc_id1;\n"
- "DELETE FROM \"%s_DELETED_CACHE\" WHERE doc_id = :doc_id2;\n";
+ "DELETE FROM $DELETED WHERE doc_id = :doc_id1;\n"
+ "DELETE FROM $DELETED_CACHE WHERE doc_id = :doc_id2;\n";
static const char* fts_end_delete_sql =
"BEGIN\n"
"\n"
- "DELETE FROM \"%s_BEING_DELETED\";\n"
- "DELETE FROM \"%s_BEING_DELETED_CACHE\";\n";
+ "DELETE FROM $BEING_DELETED;\n"
+ "DELETE FROM $BEING_DELETED_CACHE;\n";
/**********************************************************************//**
Initialize fts_zip_t. */
@@ -477,21 +480,17 @@ fts_index_fetch_nodes(
{
pars_info_t* info;
dberr_t error;
+ char table_name[MAX_FULL_NAME_LEN];
trx->op_info = "fetching FTS index nodes";
if (*graph) {
info = (*graph)->info;
} else {
- info = pars_info_create();
- }
-
- pars_info_bind_function(info, "my_func", fetch->read_record, fetch);
- pars_info_bind_varchar_literal(info, "word", word->f_str, word->f_len);
-
- if (!*graph) {
ulint selected;
+ info = pars_info_create();
+
ut_a(fts_table->type == FTS_INDEX_TABLE);
selected = fts_select_index(fts_table->charset,
@@ -499,6 +498,16 @@ fts_index_fetch_nodes(
fts_table->suffix = fts_get_suffix(selected);
+ fts_get_table_name(fts_table, table_name);
+
+ pars_info_bind_id(info, true, "table_name", table_name);
+ }
+
+ pars_info_bind_function(info, "my_func", fetch->read_record, fetch);
+ pars_info_bind_varchar_literal(info, "word", word->f_str, word->f_len);
+
+ if (!*graph) {
+
*graph = fts_parse_sql(
fts_table,
info,
@@ -506,7 +515,7 @@ fts_index_fetch_nodes(
"DECLARE CURSOR c IS"
" SELECT word, doc_count, first_doc_id, last_doc_id, "
"ilist\n"
- " FROM \"%s\"\n"
+ " FROM $table_name\n"
" WHERE word LIKE :word\n"
" ORDER BY first_doc_id;\n"
"BEGIN\n"
@@ -806,6 +815,8 @@ fts_index_fetch_words(
fts_index_selector[selected].value;
selected++) {
+ char table_name[MAX_FULL_NAME_LEN];
+
optim->fts_index_table.suffix = fts_get_suffix(selected);
/* We've search all indexes. */
@@ -821,13 +832,16 @@ fts_index_fetch_words(
pars_info_bind_varchar_literal(
info, "word", word->f_str, word->f_len);
+ fts_get_table_name(&optim->fts_index_table, table_name);
+ pars_info_bind_id(info, true, "table_name", table_name);
+
graph = fts_parse_sql(
&optim->fts_index_table,
info,
"DECLARE FUNCTION my_func;\n"
"DECLARE CURSOR c IS"
" SELECT word\n"
- " FROM \"%s\"\n"
+ " FROM $table_name\n"
" WHERE word > :word\n"
" ORDER BY word;\n"
"BEGIN\n"
@@ -969,6 +983,7 @@ fts_table_fetch_doc_ids(
que_t* graph;
pars_info_t* info = pars_info_create();
ibool alloc_bk_trx = FALSE;
+ char table_name[MAX_FULL_NAME_LEN];
ut_a(fts_table->suffix != NULL);
ut_a(fts_table->type == FTS_COMMON_TABLE);
@@ -982,12 +997,15 @@ fts_table_fetch_doc_ids(
pars_info_bind_function(info, "my_func", fts_fetch_doc_ids, doc_ids);
+ fts_get_table_name(fts_table, table_name);
+ pars_info_bind_id(info, true, "table_name", table_name);
+
graph = fts_parse_sql(
fts_table,
info,
"DECLARE FUNCTION my_func;\n"
"DECLARE CURSOR c IS"
- " SELECT doc_id FROM \"%s\";\n"
+ " SELECT doc_id FROM $table_name;\n"
"BEGIN\n"
"\n"
"OPEN c;\n"
@@ -1440,7 +1458,7 @@ fts_optimize_write_word(
que_t* graph;
ulint selected;
dberr_t error = DB_SUCCESS;
- char* table_name = fts_get_table_name(fts_table);
+ char table_name[MAX_FULL_NAME_LEN];
info = pars_info_create();
@@ -1458,11 +1476,13 @@ fts_optimize_write_word(
word->f_str, word->f_len);
fts_table->suffix = fts_get_suffix(selected);
+ fts_get_table_name(fts_table, table_name);
+ pars_info_bind_id(info, true, "table_name", table_name);
graph = fts_parse_sql(
fts_table,
info,
- "BEGIN DELETE FROM \"%s\" WHERE word = :word;");
+ "BEGIN DELETE FROM $table_name WHERE word = :word;");
error = fts_eval_sql(trx, graph);
@@ -1476,8 +1496,6 @@ fts_optimize_write_word(
fts_que_graph_free(graph);
graph = NULL;
- mem_free(table_name);
-
/* Even if the operation needs to be rolled back and redone,
we iterate over the nodes in order to free the ilist. */
for (i = 0; i < ib_vector_size(nodes); ++i) {
@@ -1727,7 +1745,7 @@ fts_optimize_free(
fts_doc_ids_free(optim->to_delete);
fts_optimize_graph_free(&optim->graph);
- mem_free(optim->name_prefix);
+ ut_free(optim->name_prefix);
/* This will free the heap from which optim itself was allocated. */
mem_heap_free(heap);
@@ -2067,9 +2085,10 @@ fts_optimize_purge_deleted_doc_ids(
pars_info_t* info;
que_t* graph;
fts_update_t* update;
- char* sql_str;
doc_id_t write_doc_id;
dberr_t error = DB_SUCCESS;
+ char deleted[MAX_FULL_NAME_LEN];
+ char deleted_cache[MAX_FULL_NAME_LEN];
info = pars_info_create();
@@ -2086,14 +2105,17 @@ fts_optimize_purge_deleted_doc_ids(
fts_bind_doc_id(info, "doc_id1", &write_doc_id);
fts_bind_doc_id(info, "doc_id2", &write_doc_id);
- /* Since we only replace the table_id and don't construct the full
- name, we do substitution ourselves. Remember to free sql_str. */
- sql_str = ut_strreplace(
- fts_delete_doc_ids_sql, "%s", optim->name_prefix);
+ /* Make sure the following two names are consistent with the name
+ used in the fts_delete_doc_ids_sql */
+ optim->fts_common_table.suffix = fts_common_tables[3];
+ fts_get_table_name(&optim->fts_common_table, deleted);
+ pars_info_bind_id(info, true, fts_common_tables[3], deleted);
- graph = fts_parse_sql(NULL, info, sql_str);
+ optim->fts_common_table.suffix = fts_common_tables[4];
+ fts_get_table_name(&optim->fts_common_table, deleted_cache);
+ pars_info_bind_id(info, true, fts_common_tables[4], deleted_cache);
- mem_free(sql_str);
+ graph = fts_parse_sql(NULL, info, fts_delete_doc_ids_sql);
/* Delete the doc ids that were copied at the start. */
for (i = 0; i < ib_vector_size(optim->to_delete->doc_ids); ++i) {
@@ -2134,17 +2156,26 @@ fts_optimize_purge_deleted_doc_id_snapshot(
{
dberr_t error;
que_t* graph;
- char* sql_str;
+ pars_info_t* info;
+ char being_deleted[MAX_FULL_NAME_LEN];
+ char being_deleted_cache[MAX_FULL_NAME_LEN];
+
+ info = pars_info_create();
+
+ /* Make sure the following two names are consistent with the name
+ used in the fts_end_delete_sql */
+ optim->fts_common_table.suffix = fts_common_tables[0];
+ fts_get_table_name(&optim->fts_common_table, being_deleted);
+ pars_info_bind_id(info, true, fts_common_tables[0], being_deleted);
- /* Since we only replace the table_id and don't construct
- the full name, we do the '%s' substitution ourselves. */
- sql_str = ut_strreplace(fts_end_delete_sql, "%s", optim->name_prefix);
+ optim->fts_common_table.suffix = fts_common_tables[1];
+ fts_get_table_name(&optim->fts_common_table, being_deleted_cache);
+ pars_info_bind_id(info, true, fts_common_tables[1],
+ being_deleted_cache);
/* Delete the doc ids that were copied to delete pending state at
the start of optimize. */
- graph = fts_parse_sql(NULL, NULL, sql_str);
-
- mem_free(sql_str);
+ graph = fts_parse_sql(NULL, info, fts_end_delete_sql);
error = fts_eval_sql(optim->trx, graph);
fts_que_graph_free(graph);
@@ -2184,16 +2215,35 @@ fts_optimize_create_deleted_doc_id_snapshot(
{
dberr_t error;
que_t* graph;
- char* sql_str;
+ pars_info_t* info;
+ char being_deleted[MAX_FULL_NAME_LEN];
+ char deleted[MAX_FULL_NAME_LEN];
+ char being_deleted_cache[MAX_FULL_NAME_LEN];
+ char deleted_cache[MAX_FULL_NAME_LEN];
- /* Since we only replace the table_id and don't construct the
- full name, we do the substitution ourselves. */
- sql_str = ut_strreplace(fts_init_delete_sql, "%s", optim->name_prefix);
+ info = pars_info_create();
- /* Move doc_ids that are to be deleted to state being deleted. */
- graph = fts_parse_sql(NULL, NULL, sql_str);
+ /* Make sure the following four names are consistent with the name
+ used in the fts_init_delete_sql */
+ optim->fts_common_table.suffix = fts_common_tables[0];
+ fts_get_table_name(&optim->fts_common_table, being_deleted);
+ pars_info_bind_id(info, true, fts_common_tables[0], being_deleted);
- mem_free(sql_str);
+ optim->fts_common_table.suffix = fts_common_tables[3];
+ fts_get_table_name(&optim->fts_common_table, deleted);
+ pars_info_bind_id(info, true, fts_common_tables[3], deleted);
+
+ optim->fts_common_table.suffix = fts_common_tables[1];
+ fts_get_table_name(&optim->fts_common_table, being_deleted_cache);
+ pars_info_bind_id(info, true, fts_common_tables[1],
+ being_deleted_cache);
+
+ optim->fts_common_table.suffix = fts_common_tables[4];
+ fts_get_table_name(&optim->fts_common_table, deleted_cache);
+ pars_info_bind_id(info, true, fts_common_tables[4], deleted_cache);
+
+ /* Move doc_ids that are to be deleted to state being deleted. */
+ graph = fts_parse_sql(NULL, info, fts_init_delete_sql);
error = fts_eval_sql(optim->trx, graph);
diff --git a/storage/innobase/fts/fts0que.cc b/storage/innobase/fts/fts0que.cc
index 8cb0a4a341c..a1167fa8ba9 100644
--- a/storage/innobase/fts/fts0que.cc
+++ b/storage/innobase/fts/fts0que.cc
@@ -2032,13 +2032,22 @@ fts_query_find_term(
fts_select_t select;
doc_id_t match_doc_id;
trx_t* trx = query->trx;
+ char table_name[MAX_FULL_NAME_LEN];
trx->op_info = "fetching FTS index matching nodes";
if (*graph) {
info = (*graph)->info;
} else {
+ ulint selected;
+
info = pars_info_create();
+
+ selected = fts_select_index(*word->f_str);
+ query->fts_index_table.suffix = fts_get_suffix(selected);
+
+ fts_get_table_name(&query->fts_index_table, table_name);
+ pars_info_bind_id(info, true, "index_table_name", table_name);
}
select.found = FALSE;
@@ -2057,11 +2066,6 @@ fts_query_find_term(
fts_bind_doc_id(info, "max_doc_id", &match_doc_id);
if (!*graph) {
- ulint selected;
-
- selected = fts_select_index(*word->f_str);
-
- query->fts_index_table.suffix = fts_get_suffix(selected);
*graph = fts_parse_sql(
&query->fts_index_table,
@@ -2069,7 +2073,7 @@ fts_query_find_term(
"DECLARE FUNCTION my_func;\n"
"DECLARE CURSOR c IS"
" SELECT doc_count, ilist\n"
- " FROM \"%s\"\n"
+ " FROM $index_table_name\n"
" WHERE word LIKE :word AND "
" first_doc_id <= :min_doc_id AND "
" last_doc_id >= :max_doc_id\n"
@@ -2168,6 +2172,7 @@ fts_query_total_docs_containing_term(
que_t* graph;
ulint selected;
trx_t* trx = query->trx;
+ char table_name[MAX_FULL_NAME_LEN]
trx->op_info = "fetching FTS index document count";
@@ -2182,13 +2187,17 @@ fts_query_total_docs_containing_term(
query->fts_index_table.suffix = fts_get_suffix(selected);
+ fts_get_table_name(&query->fts_index_table, table_name);
+
+ pars_info_bind_id(info, true, "index_table_name", table_name);
+
graph = fts_parse_sql(
&query->fts_index_table,
info,
"DECLARE FUNCTION my_func;\n"
"DECLARE CURSOR c IS"
" SELECT doc_count\n"
- " FROM %s\n"
+ " FROM $index_table_name\n"
" WHERE word = :word "
" ORDER BY first_doc_id;\n"
"BEGIN\n"
@@ -2247,6 +2256,7 @@ fts_query_terms_in_document(
que_t* graph;
doc_id_t read_doc_id;
trx_t* trx = query->trx;
+ char table_name[MAX_FULL_NAME_LEN];
trx->op_info = "fetching FTS document term count";
@@ -2262,13 +2272,17 @@ fts_query_terms_in_document(
query->fts_index_table.suffix = "DOC_ID";
+ fts_get_table_name(&query->fts_index_table, table_name);
+
+ pars_info_bind_id(info, true, "index_table_name", table_name);
+
graph = fts_parse_sql(
&query->fts_index_table,
info,
"DECLARE FUNCTION my_func;\n"
"DECLARE CURSOR c IS"
" SELECT count\n"
- " FROM \"%s\"\n"
+ " FROM $index_table_name\n"
" WHERE doc_id = :doc_id "
"BEGIN\n"
"\n"
diff --git a/storage/innobase/fts/fts0sql.cc b/storage/innobase/fts/fts0sql.cc
index dcc1e4c97e9..853312ab2ea 100644
--- a/storage/innobase/fts/fts0sql.cc
+++ b/storage/innobase/fts/fts0sql.cc
@@ -36,8 +36,7 @@ Created 2007-03-27 Sunny Bains
#include "fts0vlc.ic"
#endif
-/** SQL statements for creating the ancillary FTS tables. %s must be replaced
-with the indexed table's id. */
+/** SQL statements for creating the ancillary FTS tables. */
/** Preamble to all SQL statements. */
static const char* fts_sql_begin=
@@ -96,77 +95,47 @@ fts_get_table_id(
return(len);
}
-/******************************************************************//**
-Construct the prefix name of an FTS table.
-@return own: table name, must be freed with mem_free() */
-UNIV_INTERN
-char*
-fts_get_table_name_prefix(
-/*======================*/
- const fts_table_t*
- fts_table) /*!< in: Auxiliary table type */
+/** Construct the name of an internal FTS table for the given table.
+@param[in] fts_table metadata on fulltext-indexed table
+@param[in] dict_locked whether dict_sys->mutex is being held
+@return the prefix, must be freed with ut_free() */
+UNIV_INTERN char* fts_get_table_name_prefix(const fts_table_t* fts_table)
{
- int len;
- const char* slash;
- char* prefix_name;
- int dbname_len = 0;
- int prefix_name_len;
char table_id[FTS_AUX_MIN_TABLE_ID_LENGTH];
-
-#if 0 /* FIXME: protect the access to dict_table_t::name */
- ut_ad(mutex_own(&dict_sys->mutex));
-#endif
- slash = static_cast<const char*>(
- strchr(fts_table->table->name, '/'));
+ const size_t table_id_len = size_t(fts_get_table_id(fts_table,
+ table_id)) + 1;
+ mutex_enter(&dict_sys->mutex);
+ const char* slash = strchr(fts_table->table->name, '/');
ut_ad(slash);
- /* Print up to and including the separator. */
- dbname_len = static_cast<int>(slash - fts_table->table->name) + 1;
-
- len = fts_get_table_id(fts_table, table_id);
-
- prefix_name_len = dbname_len + 4 + len + 1;
-
- prefix_name = static_cast<char*>(mem_alloc(prefix_name_len));
-
- len = sprintf(prefix_name, "%.*sFTS_%s",
- dbname_len, fts_table->table->name, table_id);
-
- ut_a(len > 0);
- ut_a(len == prefix_name_len - 1);
-
- return(prefix_name);
+ /* Include the separator as well. */
+ const size_t dbname_len = (slash - fts_table->table->name) + 1;
+ ut_ad(dbname_len > 1);
+ const size_t prefix_name_len = dbname_len + 4 + table_id_len;
+ char* prefix_name = static_cast<char*>(ut_malloc(prefix_name_len));
+ memcpy(prefix_name, fts_table->table->name, dbname_len);
+ mutex_exit(&dict_sys->mutex);
+ memcpy(prefix_name + dbname_len, "FTS_", 4);
+ memcpy(prefix_name + dbname_len + 4, table_id, table_id_len);
+ return prefix_name;
}
-/******************************************************************//**
-Construct the name of an ancillary FTS table.
-@return own: table name, must be freed with mem_free() */
+/** 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 */
UNIV_INTERN
-char*
-fts_get_table_name(
-/*===============*/
- const fts_table_t* fts_table)
- /*!< in: Auxiliary table type */
+void fts_get_table_name(const fts_table_t* fts_table, char* table_name)
{
- int len;
- char* name;
- int name_len;
- char* prefix_name;
-
- prefix_name = fts_get_table_name_prefix(fts_table);
-
- name_len = static_cast<int>(
- strlen(prefix_name) + 1 + strlen(fts_table->suffix) + 1);
-
- name = static_cast<char*>(mem_alloc(name_len));
-
- len = sprintf(name, "%s_%s", prefix_name, fts_table->suffix);
-
- ut_a(len > 0);
- ut_a(len == name_len - 1);
-
- mem_free(prefix_name);
-
- return(name);
+ 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);
+ memcpy(table_name += dbname_len, "FTS_", 4);
+ table_name += 4;
+ table_name += fts_get_table_id(fts_table, table_name);
+ *table_name++ = '_';
+ strcpy(table_name, fts_table->suffix);
}
/******************************************************************//**
@@ -182,24 +151,9 @@ fts_parse_sql(
{
char* str;
que_t* graph;
- char* str_tmp;
ibool dict_locked;
- if (fts_table != NULL) {
- char* table_name;
-
- table_name = fts_get_table_name(fts_table);
- str_tmp = ut_strreplace(sql, "%s", table_name);
- mem_free(table_name);
- } else {
- ulint sql_len = strlen(sql) + 1;
-
- str_tmp = static_cast<char*>(mem_alloc(sql_len));
- strcpy(str_tmp, sql);
- }
-
- str = ut_str3cat(fts_sql_begin, str_tmp, fts_sql_end);
- mem_free(str_tmp);
+ str = ut_str3cat(fts_sql_begin, sql, fts_sql_end);
dict_locked = (fts_table && fts_table->table->fts
&& (fts_table->table->fts->fts_status
@@ -225,7 +179,7 @@ fts_parse_sql(
}
/******************************************************************//**
-Parse an SQL string. %s is replaced with the table's id.
+Parse an SQL string.
@return query graph */
UNIV_INTERN
que_t*
@@ -237,28 +191,10 @@ fts_parse_sql_no_dict_lock(
{
char* str;
que_t* graph;
- char* str_tmp = NULL;
-#ifdef UNIV_DEBUG
ut_ad(mutex_own(&dict_sys->mutex));
-#endif
-
- if (fts_table != NULL) {
- char* table_name;
-
- table_name = fts_get_table_name(fts_table);
- str_tmp = ut_strreplace(sql, "%s", table_name);
- mem_free(table_name);
- }
-
- if (str_tmp != NULL) {
- str = ut_str3cat(fts_sql_begin, str_tmp, fts_sql_end);
- mem_free(str_tmp);
- } else {
- str = ut_str3cat(fts_sql_begin, sql, fts_sql_end);
- }
- //fprintf(stderr, "%s\n", str);
+ str = ut_str3cat(fts_sql_begin, sql, fts_sql_end);
graph = pars_sql(info, str);
ut_a(graph);
diff --git a/storage/innobase/handler/i_s.cc b/storage/innobase/handler/i_s.cc
index 8ea6fca63a4..b94d6d80773 100644
--- a/storage/innobase/handler/i_s.cc
+++ b/storage/innobase/handler/i_s.cc
@@ -3479,6 +3479,7 @@ i_s_fts_index_table_fill_selected(
que_t* graph;
dberr_t error;
fts_fetch_t fetch;
+ char table_name[MAX_FULL_NAME_LEN];
info = pars_info_create();
@@ -3499,6 +3500,8 @@ i_s_fts_index_table_fill_selected(
FTS_INIT_INDEX_TABLE(&fts_table, fts_get_suffix(selected),
FTS_INDEX_TABLE, index);
+ fts_get_table_name(&fts_table, table_name);
+ pars_info_bind_id(info, true, "table_name", table_name);
graph = fts_parse_sql(
&fts_table, info,
@@ -3506,7 +3509,7 @@ i_s_fts_index_table_fill_selected(
"DECLARE CURSOR c IS"
" SELECT word, doc_count, first_doc_id, last_doc_id, "
"ilist\n"
- " FROM %s WHERE word >= :word;\n"
+ " FROM $table_name WHERE word >= :word;\n"
"BEGIN\n"
"\n"
"OPEN c;\n"
diff --git a/storage/innobase/include/fts0priv.h b/storage/innobase/include/fts0priv.h
index a3936f54a48..4ae90f59dda 100644
--- a/storage/innobase/include/fts0priv.h
+++ b/storage/innobase/include/fts0priv.h
@@ -1,6 +1,7 @@
/*****************************************************************************
Copyright (c) 2011, 2018, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 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
@@ -132,16 +133,13 @@ fts_eval_sql(
trx_t* trx, /*!< in: transaction */
que_t* graph) /*!< in: Parsed statement */
MY_ATTRIBUTE((nonnull, warn_unused_result));
-/******************************************************************//**
-Construct the name of an ancillary FTS table for the given table.
-@return own: table name, must be freed with mem_free() */
+
+/** 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 */
UNIV_INTERN
-char*
-fts_get_table_name(
-/*===============*/
- const fts_table_t*
- fts_table) /*!< in: FTS aux table info */
- MY_ATTRIBUTE((nonnull, malloc, warn_unused_result));
+void fts_get_table_name(const fts_table_t* fts_table, char* table_name)
+ MY_ATTRIBUTE((nonnull));
/******************************************************************//**
Construct the column specification part of the SQL string for selecting the
indexed FTS columns for the given table. Adds the necessary bound
@@ -597,15 +595,11 @@ fts_get_table_id(
FTS_AUX_MIN_TABLE_ID_LENGTH bytes
long */
MY_ATTRIBUTE((nonnull, warn_unused_result));
-/******************************************************************//**
-Construct the prefix name of an FTS table.
-@return own: table name, must be freed with mem_free() */
-UNIV_INTERN
-char*
-fts_get_table_name_prefix(
-/*======================*/
- const fts_table_t*
- fts_table) /*!< in: Auxiliary table type */
+/** Construct the name of an internal FTS table for the given table.
+@param[in] fts_table metadata on fulltext-indexed table
+@param[in] dict_locked whether dict_sys->mutex is being held
+@return the prefix, must be freed with ut_free() */
+UNIV_INTERN char* fts_get_table_name_prefix(const fts_table_t* fts_table)
MY_ATTRIBUTE((nonnull, malloc, warn_unused_result));
/******************************************************************//**
Add node positions. */
diff --git a/storage/xtradb/fts/fts0config.cc b/storage/xtradb/fts/fts0config.cc
index 5b4ae5c39f7..889f4a074b9 100644
--- a/storage/xtradb/fts/fts0config.cc
+++ b/storage/xtradb/fts/fts0config.cc
@@ -85,6 +85,7 @@ fts_config_get_value(
que_t* graph;
dberr_t error;
ulint name_len = strlen(name);
+ char table_name[MAX_FULL_NAME_LEN];
info = pars_info_create();
@@ -100,12 +101,14 @@ fts_config_get_value(
pars_info_bind_varchar_literal(info, "name", (byte*) name, name_len);
fts_table->suffix = "CONFIG";
+ fts_get_table_name(fts_table, table_name);
+ pars_info_bind_id(info, true, "table_name", table_name);
graph = fts_parse_sql(
fts_table,
info,
"DECLARE FUNCTION my_func;\n"
- "DECLARE CURSOR c IS SELECT value FROM \"%s\""
+ "DECLARE CURSOR c IS SELECT value FROM $table_name"
" WHERE key = :name;\n"
"BEGIN\n"
""
@@ -212,6 +215,7 @@ fts_config_set_value(
undo_no_t undo_no;
undo_no_t n_rows_updated;
ulint name_len = strlen(name);
+ char table_name[MAX_FULL_NAME_LEN];
info = pars_info_create();
@@ -220,10 +224,13 @@ fts_config_set_value(
value->f_str, value->f_len);
fts_table->suffix = "CONFIG";
+ fts_get_table_name(fts_table, table_name);
+ pars_info_bind_id(info, true, "table_name", table_name);
graph = fts_parse_sql(
fts_table, info,
- "BEGIN UPDATE \"%s\" SET value = :value WHERE key = :name;");
+ "BEGIN UPDATE $table_name SET value = :value "
+ "WHERE key = :name;");
trx->op_info = "setting FTS config value";
@@ -245,10 +252,13 @@ 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);
+ pars_info_bind_id(info, true, "table_name", table_name);
+
graph = fts_parse_sql(
fts_table, info,
"BEGIN\n"
- "INSERT INTO \"%s\" VALUES(:name, :value);");
+ "INSERT INTO $table_name VALUES(:name, :value);");
trx->op_info = "inserting FTS config value";
@@ -465,6 +475,7 @@ fts_config_increment_value(
que_t* graph = NULL;
ulint name_len = strlen(name);
pars_info_t* info = pars_info_create();
+ char table_name[MAX_FULL_NAME_LEN];
/* We set the length of value to the max bytes it can hold. This
information is used by the callback that reads the value.*/
@@ -479,11 +490,13 @@ fts_config_increment_value(
info, "my_func", fts_config_fetch_value, &value);
fts_table->suffix = "CONFIG";
+ fts_get_table_name(fts_table, table_name);
+ pars_info_bind_id(info, true, "config_table", table_name);
graph = fts_parse_sql(
fts_table, info,
"DECLARE FUNCTION my_func;\n"
- "DECLARE CURSOR c IS SELECT value FROM \"%s\""
+ "DECLARE CURSOR c IS SELECT value FROM $config_table"
" WHERE key = :name FOR UPDATE;\n"
"BEGIN\n"
""
diff --git a/storage/xtradb/fts/fts0fts.cc b/storage/xtradb/fts/fts0fts.cc
index 9c90ec91ce7..0dea97b6e20 100644
--- a/storage/xtradb/fts/fts0fts.cc
+++ b/storage/xtradb/fts/fts0fts.cc
@@ -167,38 +167,39 @@ struct fts_aux_table_t {
char* name; /*!< Name of the table */
};
-/** SQL statements for creating the ancillary common FTS tables. */
+/** SQL statements for creating the ancillary common FTS tables.
+The table name here shall be consistent with fts_common_tables. */
static const char* fts_create_common_tables_sql = {
"BEGIN\n"
""
- "CREATE TABLE \"%s_DELETED\" (\n"
+ "CREATE TABLE $DELETED (\n"
" doc_id BIGINT UNSIGNED\n"
") COMPACT;\n"
- "CREATE UNIQUE CLUSTERED INDEX IND ON \"%s_DELETED\"(doc_id);\n"
+ "CREATE UNIQUE CLUSTERED INDEX IND ON $DELETED (doc_id);\n"
""
- "CREATE TABLE \"%s_DELETED_CACHE\" (\n"
+ "CREATE TABLE $DELETED_CACHE (\n"
" doc_id BIGINT UNSIGNED\n"
") COMPACT;\n"
"CREATE UNIQUE CLUSTERED INDEX IND "
- "ON \"%s_DELETED_CACHE\"(doc_id);\n"
+ "ON $DELETED_CACHE(doc_id);\n"
""
- "CREATE TABLE \"%s_BEING_DELETED\" (\n"
+ "CREATE TABLE $BEING_DELETED (\n"
" doc_id BIGINT UNSIGNED\n"
") COMPACT;\n"
"CREATE UNIQUE CLUSTERED INDEX IND "
- "ON \"%s_BEING_DELETED\"(doc_id);\n"
+ "ON $BEING_DELETED(doc_id);\n"
""
- "CREATE TABLE \"%s_BEING_DELETED_CACHE\" (\n"
+ "CREATE TABLE $BEING_DELETED_CACHE (\n"
" doc_id BIGINT UNSIGNED\n"
") COMPACT;\n"
"CREATE UNIQUE CLUSTERED INDEX IND "
- "ON \"%s_BEING_DELETED_CACHE\"(doc_id);\n"
+ "ON $BEING_DELETED_CACHE(doc_id);\n"
""
- "CREATE TABLE \"%s_CONFIG\" (\n"
+ "CREATE TABLE $CONFIG (\n"
" key CHAR(50),\n"
" value CHAR(200) NOT NULL\n"
") COMPACT;\n"
- "CREATE UNIQUE CLUSTERED INDEX IND ON \"%s_CONFIG\"(key);\n"
+ "CREATE UNIQUE CLUSTERED INDEX IND ON $CONFIG(key);\n"
};
#ifdef FTS_DOC_STATS_DEBUG
@@ -207,11 +208,11 @@ mainly designed for the statistics work in the future */
static const char* fts_create_index_tables_sql = {
"BEGIN\n"
""
- "CREATE TABLE \"%s_DOC_ID\" (\n"
+ "CREATE TABLE $doc_id_table (\n"
" doc_id BIGINT UNSIGNED,\n"
" word_count INTEGER UNSIGNED NOT NULL\n"
") COMPACT;\n"
- "CREATE UNIQUE CLUSTERED INDEX IND ON \"%s_DOC_ID\"(doc_id);\n"
+ "CREATE UNIQUE CLUSTERED INDEX IND ON $doc_id_table(doc_id);\n"
};
#endif
@@ -220,11 +221,11 @@ static const char* fts_create_index_sql = {
"BEGIN\n"
""
"CREATE UNIQUE CLUSTERED INDEX FTS_INDEX_TABLE_IND "
- "ON \"%s\"(word, first_doc_id);\n"
+ "ON $table (word, first_doc_id);\n"
};
/** FTS auxiliary table suffixes that are common to all FT indexes. */
-static const char* fts_common_tables[] = {
+const char* fts_common_tables[] = {
"BEING_DELETED",
"BEING_DELETED_CACHE",
"CONFIG",
@@ -248,19 +249,19 @@ const fts_index_selector_t fts_index_selector[] = {
static const char* fts_config_table_insert_values_sql =
"BEGIN\n"
"\n"
- "INSERT INTO \"%s\" VALUES('"
+ "INSERT INTO $config_table VALUES('"
FTS_MAX_CACHE_SIZE_IN_MB "', '256');\n"
""
- "INSERT INTO \"%s\" VALUES('"
+ "INSERT INTO $config_table VALUES('"
FTS_OPTIMIZE_LIMIT_IN_SECS "', '180');\n"
""
- "INSERT INTO \"%s\" VALUES ('"
+ "INSERT INTO $config_table VALUES ('"
FTS_SYNCED_DOC_ID "', '0');\n"
""
- "INSERT INTO \"%s\" VALUES ('"
+ "INSERT INTO $config_table VALUES ('"
FTS_TOTAL_DELETED_COUNT "', '0');\n"
"" /* Note: 0 == FTS_TABLE_STATE_RUNNING */
- "INSERT INTO \"%s\" VALUES ('"
+ "INSERT INTO $config_table VALUES ('"
FTS_TABLE_STATE "', '0');\n";
/** Run SYNC on the table, i.e., write out data from the cache to the
@@ -1585,19 +1586,17 @@ fts_rename_aux_tables(
FTS_INIT_FTS_TABLE(&fts_table, NULL, FTS_COMMON_TABLE, table);
+ dberr_t err = DB_SUCCESS;
+ char old_table_name[MAX_FULL_NAME_LEN];
+
/* Rename common auxiliary tables */
for (i = 0; fts_common_tables[i] != NULL; ++i) {
- char* old_table_name;
- dberr_t err = DB_SUCCESS;
-
fts_table.suffix = fts_common_tables[i];
- old_table_name = fts_get_table_name(&fts_table);
+ fts_get_table_name(&fts_table, old_table_name);
err = fts_rename_one_aux_table(new_name, old_table_name, trx);
- mem_free(old_table_name);
-
if (err != DB_SUCCESS) {
return(err);
}
@@ -1616,12 +1615,8 @@ fts_rename_aux_tables(
FTS_INIT_INDEX_TABLE(&fts_table, NULL, FTS_INDEX_TABLE, index);
for (ulint j = 0; fts_index_selector[j].value; ++j) {
- dberr_t err;
- char* old_table_name;
-
fts_table.suffix = fts_get_suffix(j);
-
- old_table_name = fts_get_table_name(&fts_table);
+ fts_get_table_name(&fts_table, old_table_name);
err = fts_rename_one_aux_table(
new_name, old_table_name, trx);
@@ -1630,8 +1625,6 @@ fts_rename_aux_tables(
err = DB_DEADLOCK;
fts_sql_rollback(trx););
- mem_free(old_table_name);
-
if (err != DB_SUCCESS) {
return(err);
}
@@ -1659,11 +1652,11 @@ fts_drop_common_tables(
for (i = 0; fts_common_tables[i] != NULL; ++i) {
dberr_t err;
- char* table_name;
+ char table_name[MAX_FULL_NAME_LEN];
fts_table->suffix = fts_common_tables[i];
- table_name = fts_get_table_name(fts_table);
+ fts_get_table_name(fts_table, table_name);
err = fts_drop_table(trx, table_name);
@@ -1671,8 +1664,6 @@ fts_drop_common_tables(
if (err != DB_SUCCESS && err != DB_FAIL) {
error = err;
}
-
- mem_free(table_name);
}
return(error);
@@ -1698,11 +1689,11 @@ fts_drop_index_split_tables(
for (i = 0; fts_index_selector[i].value; ++i) {
dberr_t err;
- char* table_name;
+ char table_name[MAX_FULL_NAME_LEN];
fts_table.suffix = fts_get_suffix(i);
- table_name = fts_get_table_name(&fts_table);
+ fts_get_table_name(&fts_table, table_name);
err = fts_drop_table(trx, table_name);
@@ -1710,8 +1701,6 @@ fts_drop_index_split_tables(
if (err != DB_SUCCESS && err != DB_FAIL) {
error = err;
}
-
- mem_free(table_name);
}
return(error);
@@ -1748,11 +1737,11 @@ fts_drop_index_tables(
FTS_INIT_INDEX_TABLE(&fts_table, NULL, FTS_INDEX_TABLE, index);
for (ulint i = 0; index_tables[i] != NULL; ++i) {
- char* table_name;
+ char table_name[MAX_FULL_NAME_LEN];
fts_table.suffix = index_tables[i];
- table_name = fts_get_table_name(&fts_table);
+ fts_get_table_name(&fts_table, table_name);
err = fts_drop_table(trx, table_name);
@@ -1760,8 +1749,6 @@ fts_drop_index_tables(
if (err != DB_SUCCESS && err != DB_FAIL) {
error = err;
}
-
- mem_free(table_name);
}
#endif /* FTS_DOC_STATS_DEBUG */
@@ -1831,26 +1818,6 @@ fts_drop_tables(
}
/*********************************************************************//**
-Prepare the SQL, so that all '%s' are replaced by the common prefix.
-@return sql string, use mem_free() to free the memory */
-static
-char*
-fts_prepare_sql(
-/*============*/
- fts_table_t* fts_table, /*!< in: table name info */
- const char* my_template) /*!< in: sql template */
-{
- char* sql;
- char* name_prefix;
-
- name_prefix = fts_get_table_name_prefix(fts_table);
- sql = ut_strreplace(my_template, "%s", name_prefix);
- mem_free(name_prefix);
-
- return(sql);
-}
-
-/*********************************************************************//**
Creates the common ancillary tables needed for supporting an FTS index
on the given table. row_mysql_lock_data_dictionary must have been called
before this.
@@ -1864,12 +1831,15 @@ fts_create_common_tables(
const char* name, /*!< in: table name normalized.*/
bool skip_doc_id_index)/*!< in: Skip index on doc id */
{
- char* sql;
dberr_t error;
que_t* graph;
fts_table_t fts_table;
mem_heap_t* heap = mem_heap_create(1024);
pars_info_t* info;
+ char fts_name[MAX_FULL_NAME_LEN];
+ char full_name[sizeof(fts_common_tables) / sizeof(char*)]
+ [MAX_FULL_NAME_LEN];
+ ulint i;
FTS_INIT_FTS_TABLE(&fts_table, NULL, FTS_COMMON_TABLE, table);
@@ -1881,9 +1851,19 @@ fts_create_common_tables(
}
/* Create the FTS tables that are common to an FTS index. */
- sql = fts_prepare_sql(&fts_table, fts_create_common_tables_sql);
- graph = fts_parse_sql_no_dict_lock(NULL, NULL, sql);
- mem_free(sql);
+ info = pars_info_create();
+
+ 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]);
+
+ pars_info_bind_id(info, true,
+ fts_common_tables[i], full_name[i]);
+ }
+
+ graph = fts_parse_sql_no_dict_lock(NULL, info,
+ fts_create_common_tables_sql);
error = fts_eval_sql(trx, graph);
@@ -1895,9 +1875,14 @@ fts_create_common_tables(
}
/* Write the default settings to the config table. */
+ info = pars_info_create();
+
fts_table.suffix = "CONFIG";
+ fts_get_table_name(&fts_table, fts_name);
+ pars_info_bind_id(info, true, "config_table", fts_name);
+
graph = fts_parse_sql_no_dict_lock(
- &fts_table, NULL, fts_config_table_insert_values_sql);
+ &fts_table, info, fts_config_table_insert_values_sql);
error = fts_eval_sql(trx, graph);
@@ -1965,13 +1950,15 @@ fts_create_one_index_table(
{
dict_field_t* field;
dict_table_t* new_table = NULL;
- char* table_name = fts_get_table_name(fts_table);
+ char table_name[MAX_FULL_NAME_LEN];
dberr_t error;
CHARSET_INFO* charset;
ulint flags2 = 0;
ut_ad(index->type & DICT_FTS);
+ fts_get_table_name(fts_table, table_name);
+
if (srv_file_per_table) {
flags2 = DICT_TF2_USE_TABLESPACE;
}
@@ -2015,8 +2002,6 @@ fts_create_one_index_table(
"Fail to create FTS index table %s", table_name);
}
- mem_free(table_name);
-
return(new_table);
}
@@ -2039,7 +2024,9 @@ fts_create_index_tables_low(
que_t* graph;
fts_table_t fts_table;
dberr_t error = DB_SUCCESS;
+ pars_info_t* info;
mem_heap_t* heap = mem_heap_create(1024);
+ char fts_name[MAX_FULL_NAME_LEN];
fts_table.type = FTS_INDEX_TABLE;
fts_table.index_id = index->id;
@@ -2047,14 +2034,17 @@ fts_create_index_tables_low(
fts_table.table = index->table;
#ifdef FTS_DOC_STATS_DEBUG
- char* sql;
-
/* Create the FTS auxiliary tables that are specific
to an FTS index. */
- sql = fts_prepare_sql(&fts_table, fts_create_index_tables_sql);
+ info = pars_info_create();
+
+ fts_table.suffix = "DOC_ID";
+ fts_get_table_name(&fts_table, fts_name);
- graph = fts_parse_sql_no_dict_lock(NULL, NULL, sql);
- mem_free(sql);
+ pars_info_bind_id(info, true, "doc_id_table", fts_name);
+
+ graph = fts_parse_sql_no_dict_lock(NULL, info,
+ fts_create_index_tables_sql);
error = fts_eval_sql(trx, graph);
que_graph_free(graph);
@@ -2063,6 +2053,8 @@ fts_create_index_tables_low(
for (i = 0; fts_index_selector[i].value && error == DB_SUCCESS; ++i) {
dict_table_t* new_table;
+ info = pars_info_create();
+
/* Create the FTS auxiliary tables that are specific
to an FTS index. We need to preserve the table_id %s
which fts_parse_sql_no_dict_lock() will fill in for us. */
@@ -2076,8 +2068,12 @@ fts_create_index_tables_low(
break;
}
+ fts_get_table_name(&fts_table, fts_name);
+
+ pars_info_bind_id(info, true, "table", fts_name);
+
graph = fts_parse_sql_no_dict_lock(
- &fts_table, NULL, fts_create_index_sql);
+ &fts_table, info, fts_create_index_sql);
error = fts_eval_sql(trx, graph);
que_graph_free(graph);
@@ -2701,6 +2697,7 @@ fts_cmp_set_sync_doc_id(
fts_table_t fts_table;
que_t* graph = NULL;
fts_cache_t* cache = table->fts->cache;
+ char table_name[MAX_FULL_NAME_LEN];
retry:
ut_a(table->fts->doc_col != ULINT_UNDEFINED);
@@ -2718,10 +2715,13 @@ retry:
pars_info_bind_function(
info, "my_func", fts_fetch_store_doc_id, doc_id);
+ fts_get_table_name(&fts_table, table_name);
+ pars_info_bind_id(info, true, "config_table", table_name);
+
graph = fts_parse_sql(
&fts_table, info,
"DECLARE FUNCTION my_func;\n"
- "DECLARE CURSOR c IS SELECT value FROM \"%s\""
+ "DECLARE CURSOR c IS SELECT value FROM $config_table"
" WHERE key = 'synced_doc_id' FOR UPDATE;\n"
"BEGIN\n"
""
@@ -2814,6 +2814,7 @@ fts_update_sync_doc_id(
dberr_t error;
ibool local_trx = FALSE;
fts_cache_t* cache = table->fts->cache;
+ char fts_name[MAX_FULL_NAME_LEN];
fts_table.suffix = "CONFIG";
fts_table.table_id = table->id;
@@ -2834,10 +2835,13 @@ fts_update_sync_doc_id(
pars_info_bind_varchar_literal(info, "doc_id", id, id_len);
+ fts_get_table_name(&fts_table, fts_name);
+ pars_info_bind_id(info, true, "table_name", fts_name);
+
graph = fts_parse_sql(
&fts_table, info,
"BEGIN "
- "UPDATE \"%s\" SET value = :doc_id"
+ "UPDATE $table_name SET value = :doc_id"
" WHERE key = 'synced_doc_id';");
error = fts_eval_sql(trx, graph);
@@ -2984,6 +2988,7 @@ fts_delete(
/* Note the deleted document for OPTIMIZE to purge. */
if (error == DB_SUCCESS) {
+ char table_name[MAX_FULL_NAME_LEN];
trx->op_info = "adding doc id to FTS DELETED";
@@ -2991,10 +2996,13 @@ fts_delete(
fts_table.suffix = "DELETED";
+ fts_get_table_name(&fts_table, table_name);
+ pars_info_bind_id(info, true, "deleted", table_name);
+
graph = fts_parse_sql(
&fts_table,
info,
- "BEGIN INSERT INTO \"%s\" VALUES (:doc_id);");
+ "BEGIN INSERT INTO $deleted VALUES (:doc_id);");
error = fts_eval_sql(trx, graph);
@@ -3813,11 +3821,15 @@ fts_write_node(
ib_time_t start_time;
doc_id_t last_doc_id;
doc_id_t first_doc_id;
+ char table_name[MAX_FULL_NAME_LEN];
if (*graph) {
info = (*graph)->info;
} else {
info = pars_info_create();
+
+ fts_get_table_name(fts_table, table_name);
+ pars_info_bind_id(info, true, "index_table_name", table_name);
}
pars_info_bind_varchar_literal(info, "token", word->f_str, word->f_len);
@@ -3843,11 +3855,12 @@ fts_write_node(
DATA_BLOB, DATA_BINARY_TYPE);
if (!*graph) {
+
*graph = fts_parse_sql(
fts_table,
info,
"BEGIN\n"
- "INSERT INTO \"%s\" VALUES "
+ "INSERT INTO $index_table_name VALUES "
"(:token, :first_doc_id,"
" :last_doc_id, :doc_count, :ilist);");
}
@@ -3874,6 +3887,7 @@ fts_sync_add_deleted_cache(
pars_info_t* info;
que_t* graph;
fts_table_t fts_table;
+ char table_name[MAX_FULL_NAME_LEN];
doc_id_t dummy = 0;
dberr_t error = DB_SUCCESS;
ulint n_elems = ib_vector_size(doc_ids);
@@ -3889,10 +3903,13 @@ fts_sync_add_deleted_cache(
FTS_INIT_FTS_TABLE(
&fts_table, "DELETED_CACHE", FTS_COMMON_TABLE, sync->table);
+ fts_get_table_name(&fts_table, table_name);
+ pars_info_bind_id(info, true, "table_name", table_name);
+
graph = fts_parse_sql(
&fts_table,
info,
- "BEGIN INSERT INTO \"%s\" VALUES (:doc_id);");
+ "BEGIN INSERT INTO $table_name VALUES (:doc_id);");
for (i = 0; i < n_elems && error == DB_SUCCESS; ++i) {
fts_update_t* update;
@@ -4069,6 +4086,7 @@ fts_sync_write_doc_stat(
doc_id_t doc_id;
dberr_t error = DB_SUCCESS;
ib_uint32_t word_count;
+ char table_name[MAX_FULL_NAME_LEN];
if (*graph) {
info = (*graph)->info;
@@ -4091,10 +4109,15 @@ fts_sync_write_doc_stat(
FTS_INIT_INDEX_TABLE(
&fts_table, "DOC_ID", FTS_INDEX_TABLE, index);
+ fts_get_table_name(&fts_table, table_name);
+
+ pars_info_bind_id(info, true, "doc_id_table", table_name);
+
*graph = fts_parse_sql(
&fts_table,
info,
- "BEGIN INSERT INTO \"%s\" VALUES (:doc_id, :count);");
+ "BEGIN "
+ "INSERT INTO $doc_id_table VALUES (:doc_id, :count);");
}
for (;;) {
@@ -4216,6 +4239,7 @@ fts_is_word_in_index(
{
pars_info_t* info;
dberr_t error;
+ char table_name[MAX_FULL_NAME_LEN];
trx->op_info = "looking up word in FTS index";
@@ -4225,6 +4249,8 @@ fts_is_word_in_index(
info = pars_info_create();
}
+ fts_get_table_name(fts_table, table_name);
+ pars_info_bind_id(info, true, "table_name", table_name);
pars_info_bind_function(info, "my_func", fts_lookup_word, found);
pars_info_bind_varchar_literal(info, "word", word->f_str, word->f_len);
@@ -4235,7 +4261,7 @@ fts_is_word_in_index(
"DECLARE FUNCTION my_func;\n"
"DECLARE CURSOR c IS"
" SELECT doc_count\n"
- " FROM \"%s\"\n"
+ " FROM $table_name\n"
" WHERE word = :word "
" ORDER BY first_doc_id;\n"
"BEGIN\n"
@@ -4984,6 +5010,7 @@ fts_get_rows_count(
que_t* graph;
dberr_t error;
ulint count = 0;
+ char table_name[MAX_FULL_NAME_LEN];
trx = trx_allocate_for_background();
@@ -4993,13 +5020,16 @@ fts_get_rows_count(
pars_info_bind_function(info, "my_func", fts_read_ulint, &count);
+ fts_get_table_name(fts_table, table_name);
+ pars_info_bind_id(info, true, "table_name", table_name);
+
graph = fts_parse_sql(
fts_table,
info,
"DECLARE FUNCTION my_func;\n"
"DECLARE CURSOR c IS"
" SELECT COUNT(*) "
- " FROM \"%s\";\n"
+ " FROM $table_name;\n"
"BEGIN\n"
"\n"
"OPEN c;\n"
@@ -6208,7 +6238,7 @@ fts_rename_one_aux_table_to_hex_format(
{
const char* ptr;
fts_table_t fts_table;
- char* new_name;
+ char new_name[MAX_FULL_NAME_LEN];
dberr_t error;
ptr = strchr(aux_table->name, '/');
@@ -6253,7 +6283,7 @@ fts_rename_one_aux_table_to_hex_format(
fts_table.index_id = aux_table->index_id;
fts_table.table = parent_table;
- new_name = fts_get_table_name(&fts_table);
+ fts_get_table_name(&fts_table, new_name);
ut_ad(strcmp(new_name, aux_table->name) != 0);
if (trx_get_dict_operation(trx) == TRX_DICT_OP_NONE) {
@@ -6274,8 +6304,6 @@ fts_rename_one_aux_table_to_hex_format(
aux_table->name, new_name);
}
- mem_free(new_name);
-
return (error);
}
diff --git a/storage/xtradb/fts/fts0opt.cc b/storage/xtradb/fts/fts0opt.cc
index ad64f6d1d37..0d5185cc5fb 100644
--- a/storage/xtradb/fts/fts0opt.cc
+++ b/storage/xtradb/fts/fts0opt.cc
@@ -226,27 +226,30 @@ static ulint FTS_ZIP_BLOCK_SIZE = 1024;
/** The amount of time optimizing in a single pass, in milliseconds. */
static ib_time_t fts_optimize_time_limit = 0;
+/** It's defined in fts0fts.cc */
+extern const char* fts_common_tables[];
+
/** SQL Statement for changing state of rows to be deleted from FTS Index. */
static const char* fts_init_delete_sql =
"BEGIN\n"
"\n"
- "INSERT INTO \"%s_BEING_DELETED\"\n"
- "SELECT doc_id FROM \"%s_DELETED\";\n"
+ "INSERT INTO $BEING_DELETED\n"
+ "SELECT doc_id FROM $DELETED;\n"
"\n"
- "INSERT INTO \"%s_BEING_DELETED_CACHE\"\n"
- "SELECT doc_id FROM \"%s_DELETED_CACHE\";\n";
+ "INSERT INTO $BEING_DELETED_CACHE\n"
+ "SELECT doc_id FROM $DELETED_CACHE;\n";
static const char* fts_delete_doc_ids_sql =
"BEGIN\n"
"\n"
- "DELETE FROM \"%s_DELETED\" WHERE doc_id = :doc_id1;\n"
- "DELETE FROM \"%s_DELETED_CACHE\" WHERE doc_id = :doc_id2;\n";
+ "DELETE FROM $DELETED WHERE doc_id = :doc_id1;\n"
+ "DELETE FROM $DELETED_CACHE WHERE doc_id = :doc_id2;\n";
static const char* fts_end_delete_sql =
"BEGIN\n"
"\n"
- "DELETE FROM \"%s_BEING_DELETED\";\n"
- "DELETE FROM \"%s_BEING_DELETED_CACHE\";\n";
+ "DELETE FROM $BEING_DELETED;\n"
+ "DELETE FROM $BEING_DELETED_CACHE;\n";
/**********************************************************************//**
Initialize fts_zip_t. */
@@ -477,21 +480,17 @@ fts_index_fetch_nodes(
{
pars_info_t* info;
dberr_t error;
+ char table_name[MAX_FULL_NAME_LEN];
trx->op_info = "fetching FTS index nodes";
if (*graph) {
info = (*graph)->info;
} else {
- info = pars_info_create();
- }
-
- pars_info_bind_function(info, "my_func", fetch->read_record, fetch);
- pars_info_bind_varchar_literal(info, "word", word->f_str, word->f_len);
-
- if (!*graph) {
ulint selected;
+ info = pars_info_create();
+
ut_a(fts_table->type == FTS_INDEX_TABLE);
selected = fts_select_index(fts_table->charset,
@@ -499,6 +498,16 @@ fts_index_fetch_nodes(
fts_table->suffix = fts_get_suffix(selected);
+ fts_get_table_name(fts_table, table_name);
+
+ pars_info_bind_id(info, true, "table_name", table_name);
+ }
+
+ pars_info_bind_function(info, "my_func", fetch->read_record, fetch);
+ pars_info_bind_varchar_literal(info, "word", word->f_str, word->f_len);
+
+ if (!*graph) {
+
*graph = fts_parse_sql(
fts_table,
info,
@@ -506,7 +515,7 @@ fts_index_fetch_nodes(
"DECLARE CURSOR c IS"
" SELECT word, doc_count, first_doc_id, last_doc_id, "
"ilist\n"
- " FROM \"%s\"\n"
+ " FROM $table_name\n"
" WHERE word LIKE :word\n"
" ORDER BY first_doc_id;\n"
"BEGIN\n"
@@ -806,6 +815,8 @@ fts_index_fetch_words(
fts_index_selector[selected].value;
selected++) {
+ char table_name[MAX_FULL_NAME_LEN];
+
optim->fts_index_table.suffix = fts_get_suffix(selected);
/* We've search all indexes. */
@@ -821,13 +832,16 @@ fts_index_fetch_words(
pars_info_bind_varchar_literal(
info, "word", word->f_str, word->f_len);
+ fts_get_table_name(&optim->fts_index_table, table_name);
+ pars_info_bind_id(info, true, "table_name", table_name);
+
graph = fts_parse_sql(
&optim->fts_index_table,
info,
"DECLARE FUNCTION my_func;\n"
"DECLARE CURSOR c IS"
" SELECT word\n"
- " FROM \"%s\"\n"
+ " FROM $table_name\n"
" WHERE word > :word\n"
" ORDER BY word;\n"
"BEGIN\n"
@@ -969,6 +983,7 @@ fts_table_fetch_doc_ids(
que_t* graph;
pars_info_t* info = pars_info_create();
ibool alloc_bk_trx = FALSE;
+ char table_name[MAX_FULL_NAME_LEN];
ut_a(fts_table->suffix != NULL);
ut_a(fts_table->type == FTS_COMMON_TABLE);
@@ -982,12 +997,15 @@ fts_table_fetch_doc_ids(
pars_info_bind_function(info, "my_func", fts_fetch_doc_ids, doc_ids);
+ fts_get_table_name(fts_table, table_name);
+ pars_info_bind_id(info, true, "table_name", table_name);
+
graph = fts_parse_sql(
fts_table,
info,
"DECLARE FUNCTION my_func;\n"
"DECLARE CURSOR c IS"
- " SELECT doc_id FROM \"%s\";\n"
+ " SELECT doc_id FROM $table_name;\n"
"BEGIN\n"
"\n"
"OPEN c;\n"
@@ -1440,7 +1458,7 @@ fts_optimize_write_word(
que_t* graph;
ulint selected;
dberr_t error = DB_SUCCESS;
- char* table_name = fts_get_table_name(fts_table);
+ char table_name[MAX_FULL_NAME_LEN];
info = pars_info_create();
@@ -1458,11 +1476,13 @@ fts_optimize_write_word(
word->f_str, word->f_len);
fts_table->suffix = fts_get_suffix(selected);
+ fts_get_table_name(fts_table, table_name);
+ pars_info_bind_id(info, true, "table_name", table_name);
graph = fts_parse_sql(
fts_table,
info,
- "BEGIN DELETE FROM \"%s\" WHERE word = :word;");
+ "BEGIN DELETE FROM $table_name WHERE word = :word;");
error = fts_eval_sql(trx, graph);
@@ -1476,8 +1496,6 @@ fts_optimize_write_word(
fts_que_graph_free(graph);
graph = NULL;
- mem_free(table_name);
-
/* Even if the operation needs to be rolled back and redone,
we iterate over the nodes in order to free the ilist. */
for (i = 0; i < ib_vector_size(nodes); ++i) {
@@ -1727,7 +1745,7 @@ fts_optimize_free(
fts_doc_ids_free(optim->to_delete);
fts_optimize_graph_free(&optim->graph);
- mem_free(optim->name_prefix);
+ ut_free(optim->name_prefix);
/* This will free the heap from which optim itself was allocated. */
mem_heap_free(heap);
@@ -2067,9 +2085,10 @@ fts_optimize_purge_deleted_doc_ids(
pars_info_t* info;
que_t* graph;
fts_update_t* update;
- char* sql_str;
doc_id_t write_doc_id;
dberr_t error = DB_SUCCESS;
+ char deleted[MAX_FULL_NAME_LEN];
+ char deleted_cache[MAX_FULL_NAME_LEN];
info = pars_info_create();
@@ -2086,14 +2105,17 @@ fts_optimize_purge_deleted_doc_ids(
fts_bind_doc_id(info, "doc_id1", &write_doc_id);
fts_bind_doc_id(info, "doc_id2", &write_doc_id);
- /* Since we only replace the table_id and don't construct the full
- name, we do substitution ourselves. Remember to free sql_str. */
- sql_str = ut_strreplace(
- fts_delete_doc_ids_sql, "%s", optim->name_prefix);
+ /* Make sure the following two names are consistent with the name
+ used in the fts_delete_doc_ids_sql */
+ optim->fts_common_table.suffix = fts_common_tables[3];
+ fts_get_table_name(&optim->fts_common_table, deleted);
+ pars_info_bind_id(info, true, fts_common_tables[3], deleted);
- graph = fts_parse_sql(NULL, info, sql_str);
+ optim->fts_common_table.suffix = fts_common_tables[4];
+ fts_get_table_name(&optim->fts_common_table, deleted_cache);
+ pars_info_bind_id(info, true, fts_common_tables[4], deleted_cache);
- mem_free(sql_str);
+ graph = fts_parse_sql(NULL, info, fts_delete_doc_ids_sql);
/* Delete the doc ids that were copied at the start. */
for (i = 0; i < ib_vector_size(optim->to_delete->doc_ids); ++i) {
@@ -2134,17 +2156,26 @@ fts_optimize_purge_deleted_doc_id_snapshot(
{
dberr_t error;
que_t* graph;
- char* sql_str;
+ pars_info_t* info;
+ char being_deleted[MAX_FULL_NAME_LEN];
+ char being_deleted_cache[MAX_FULL_NAME_LEN];
+
+ info = pars_info_create();
+
+ /* Make sure the following two names are consistent with the name
+ used in the fts_end_delete_sql */
+ optim->fts_common_table.suffix = fts_common_tables[0];
+ fts_get_table_name(&optim->fts_common_table, being_deleted);
+ pars_info_bind_id(info, true, fts_common_tables[0], being_deleted);
- /* Since we only replace the table_id and don't construct
- the full name, we do the '%s' substitution ourselves. */
- sql_str = ut_strreplace(fts_end_delete_sql, "%s", optim->name_prefix);
+ optim->fts_common_table.suffix = fts_common_tables[1];
+ fts_get_table_name(&optim->fts_common_table, being_deleted_cache);
+ pars_info_bind_id(info, true, fts_common_tables[1],
+ being_deleted_cache);
/* Delete the doc ids that were copied to delete pending state at
the start of optimize. */
- graph = fts_parse_sql(NULL, NULL, sql_str);
-
- mem_free(sql_str);
+ graph = fts_parse_sql(NULL, info, fts_end_delete_sql);
error = fts_eval_sql(optim->trx, graph);
fts_que_graph_free(graph);
@@ -2184,16 +2215,35 @@ fts_optimize_create_deleted_doc_id_snapshot(
{
dberr_t error;
que_t* graph;
- char* sql_str;
+ pars_info_t* info;
+ char being_deleted[MAX_FULL_NAME_LEN];
+ char deleted[MAX_FULL_NAME_LEN];
+ char being_deleted_cache[MAX_FULL_NAME_LEN];
+ char deleted_cache[MAX_FULL_NAME_LEN];
- /* Since we only replace the table_id and don't construct the
- full name, we do the substitution ourselves. */
- sql_str = ut_strreplace(fts_init_delete_sql, "%s", optim->name_prefix);
+ info = pars_info_create();
- /* Move doc_ids that are to be deleted to state being deleted. */
- graph = fts_parse_sql(NULL, NULL, sql_str);
+ /* Make sure the following four names are consistent with the name
+ used in the fts_init_delete_sql */
+ optim->fts_common_table.suffix = fts_common_tables[0];
+ fts_get_table_name(&optim->fts_common_table, being_deleted);
+ pars_info_bind_id(info, true, fts_common_tables[0], being_deleted);
- mem_free(sql_str);
+ optim->fts_common_table.suffix = fts_common_tables[3];
+ fts_get_table_name(&optim->fts_common_table, deleted);
+ pars_info_bind_id(info, true, fts_common_tables[3], deleted);
+
+ optim->fts_common_table.suffix = fts_common_tables[1];
+ fts_get_table_name(&optim->fts_common_table, being_deleted_cache);
+ pars_info_bind_id(info, true, fts_common_tables[1],
+ being_deleted_cache);
+
+ optim->fts_common_table.suffix = fts_common_tables[4];
+ fts_get_table_name(&optim->fts_common_table, deleted_cache);
+ pars_info_bind_id(info, true, fts_common_tables[4], deleted_cache);
+
+ /* Move doc_ids that are to be deleted to state being deleted. */
+ graph = fts_parse_sql(NULL, info, fts_init_delete_sql);
error = fts_eval_sql(optim->trx, graph);
diff --git a/storage/xtradb/fts/fts0que.cc b/storage/xtradb/fts/fts0que.cc
index fa91771a7b2..3419a1bd7ab 100644
--- a/storage/xtradb/fts/fts0que.cc
+++ b/storage/xtradb/fts/fts0que.cc
@@ -2052,13 +2052,22 @@ fts_query_find_term(
fts_select_t select;
doc_id_t match_doc_id;
trx_t* trx = query->trx;
+ char table_name[MAX_FULL_NAME_LEN];
trx->op_info = "fetching FTS index matching nodes";
if (*graph) {
info = (*graph)->info;
} else {
+ ulint selected;
+
info = pars_info_create();
+
+ selected = fts_select_index(*word->f_str);
+ query->fts_index_table.suffix = fts_get_suffix(selected);
+
+ fts_get_table_name(&query->fts_index_table, table_name);
+ pars_info_bind_id(info, true, "index_table_name", table_name);
}
select.found = FALSE;
@@ -2077,11 +2086,6 @@ fts_query_find_term(
fts_bind_doc_id(info, "max_doc_id", &match_doc_id);
if (!*graph) {
- ulint selected;
-
- selected = fts_select_index(*word->f_str);
-
- query->fts_index_table.suffix = fts_get_suffix(selected);
*graph = fts_parse_sql(
&query->fts_index_table,
@@ -2089,7 +2093,7 @@ fts_query_find_term(
"DECLARE FUNCTION my_func;\n"
"DECLARE CURSOR c IS"
" SELECT doc_count, ilist\n"
- " FROM \"%s\"\n"
+ " FROM $index_table_name\n"
" WHERE word LIKE :word AND "
" first_doc_id <= :min_doc_id AND "
" last_doc_id >= :max_doc_id\n"
@@ -2188,6 +2192,7 @@ fts_query_total_docs_containing_term(
que_t* graph;
ulint selected;
trx_t* trx = query->trx;
+ char table_name[MAX_FULL_NAME_LEN]
trx->op_info = "fetching FTS index document count";
@@ -2202,13 +2207,17 @@ fts_query_total_docs_containing_term(
query->fts_index_table.suffix = fts_get_suffix(selected);
+ fts_get_table_name(&query->fts_index_table, table_name);
+
+ pars_info_bind_id(info, true, "index_table_name", table_name);
+
graph = fts_parse_sql(
&query->fts_index_table,
info,
"DECLARE FUNCTION my_func;\n"
"DECLARE CURSOR c IS"
" SELECT doc_count\n"
- " FROM %s\n"
+ " FROM $index_table_name\n"
" WHERE word = :word "
" ORDER BY first_doc_id;\n"
"BEGIN\n"
@@ -2267,6 +2276,7 @@ fts_query_terms_in_document(
que_t* graph;
doc_id_t read_doc_id;
trx_t* trx = query->trx;
+ char table_name[MAX_FULL_NAME_LEN];
trx->op_info = "fetching FTS document term count";
@@ -2282,13 +2292,17 @@ fts_query_terms_in_document(
query->fts_index_table.suffix = "DOC_ID";
+ fts_get_table_name(&query->fts_index_table, table_name);
+
+ pars_info_bind_id(info, true, "index_table_name", table_name);
+
graph = fts_parse_sql(
&query->fts_index_table,
info,
"DECLARE FUNCTION my_func;\n"
"DECLARE CURSOR c IS"
" SELECT count\n"
- " FROM \"%s\"\n"
+ " FROM $index_table_name\n"
" WHERE doc_id = :doc_id "
"BEGIN\n"
"\n"
diff --git a/storage/xtradb/fts/fts0sql.cc b/storage/xtradb/fts/fts0sql.cc
index dcc1e4c97e9..853312ab2ea 100644
--- a/storage/xtradb/fts/fts0sql.cc
+++ b/storage/xtradb/fts/fts0sql.cc
@@ -36,8 +36,7 @@ Created 2007-03-27 Sunny Bains
#include "fts0vlc.ic"
#endif
-/** SQL statements for creating the ancillary FTS tables. %s must be replaced
-with the indexed table's id. */
+/** SQL statements for creating the ancillary FTS tables. */
/** Preamble to all SQL statements. */
static const char* fts_sql_begin=
@@ -96,77 +95,47 @@ fts_get_table_id(
return(len);
}
-/******************************************************************//**
-Construct the prefix name of an FTS table.
-@return own: table name, must be freed with mem_free() */
-UNIV_INTERN
-char*
-fts_get_table_name_prefix(
-/*======================*/
- const fts_table_t*
- fts_table) /*!< in: Auxiliary table type */
+/** Construct the name of an internal FTS table for the given table.
+@param[in] fts_table metadata on fulltext-indexed table
+@param[in] dict_locked whether dict_sys->mutex is being held
+@return the prefix, must be freed with ut_free() */
+UNIV_INTERN char* fts_get_table_name_prefix(const fts_table_t* fts_table)
{
- int len;
- const char* slash;
- char* prefix_name;
- int dbname_len = 0;
- int prefix_name_len;
char table_id[FTS_AUX_MIN_TABLE_ID_LENGTH];
-
-#if 0 /* FIXME: protect the access to dict_table_t::name */
- ut_ad(mutex_own(&dict_sys->mutex));
-#endif
- slash = static_cast<const char*>(
- strchr(fts_table->table->name, '/'));
+ const size_t table_id_len = size_t(fts_get_table_id(fts_table,
+ table_id)) + 1;
+ mutex_enter(&dict_sys->mutex);
+ const char* slash = strchr(fts_table->table->name, '/');
ut_ad(slash);
- /* Print up to and including the separator. */
- dbname_len = static_cast<int>(slash - fts_table->table->name) + 1;
-
- len = fts_get_table_id(fts_table, table_id);
-
- prefix_name_len = dbname_len + 4 + len + 1;
-
- prefix_name = static_cast<char*>(mem_alloc(prefix_name_len));
-
- len = sprintf(prefix_name, "%.*sFTS_%s",
- dbname_len, fts_table->table->name, table_id);
-
- ut_a(len > 0);
- ut_a(len == prefix_name_len - 1);
-
- return(prefix_name);
+ /* Include the separator as well. */
+ const size_t dbname_len = (slash - fts_table->table->name) + 1;
+ ut_ad(dbname_len > 1);
+ const size_t prefix_name_len = dbname_len + 4 + table_id_len;
+ char* prefix_name = static_cast<char*>(ut_malloc(prefix_name_len));
+ memcpy(prefix_name, fts_table->table->name, dbname_len);
+ mutex_exit(&dict_sys->mutex);
+ memcpy(prefix_name + dbname_len, "FTS_", 4);
+ memcpy(prefix_name + dbname_len + 4, table_id, table_id_len);
+ return prefix_name;
}
-/******************************************************************//**
-Construct the name of an ancillary FTS table.
-@return own: table name, must be freed with mem_free() */
+/** 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 */
UNIV_INTERN
-char*
-fts_get_table_name(
-/*===============*/
- const fts_table_t* fts_table)
- /*!< in: Auxiliary table type */
+void fts_get_table_name(const fts_table_t* fts_table, char* table_name)
{
- int len;
- char* name;
- int name_len;
- char* prefix_name;
-
- prefix_name = fts_get_table_name_prefix(fts_table);
-
- name_len = static_cast<int>(
- strlen(prefix_name) + 1 + strlen(fts_table->suffix) + 1);
-
- name = static_cast<char*>(mem_alloc(name_len));
-
- len = sprintf(name, "%s_%s", prefix_name, fts_table->suffix);
-
- ut_a(len > 0);
- ut_a(len == name_len - 1);
-
- mem_free(prefix_name);
-
- return(name);
+ 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);
+ memcpy(table_name += dbname_len, "FTS_", 4);
+ table_name += 4;
+ table_name += fts_get_table_id(fts_table, table_name);
+ *table_name++ = '_';
+ strcpy(table_name, fts_table->suffix);
}
/******************************************************************//**
@@ -182,24 +151,9 @@ fts_parse_sql(
{
char* str;
que_t* graph;
- char* str_tmp;
ibool dict_locked;
- if (fts_table != NULL) {
- char* table_name;
-
- table_name = fts_get_table_name(fts_table);
- str_tmp = ut_strreplace(sql, "%s", table_name);
- mem_free(table_name);
- } else {
- ulint sql_len = strlen(sql) + 1;
-
- str_tmp = static_cast<char*>(mem_alloc(sql_len));
- strcpy(str_tmp, sql);
- }
-
- str = ut_str3cat(fts_sql_begin, str_tmp, fts_sql_end);
- mem_free(str_tmp);
+ str = ut_str3cat(fts_sql_begin, sql, fts_sql_end);
dict_locked = (fts_table && fts_table->table->fts
&& (fts_table->table->fts->fts_status
@@ -225,7 +179,7 @@ fts_parse_sql(
}
/******************************************************************//**
-Parse an SQL string. %s is replaced with the table's id.
+Parse an SQL string.
@return query graph */
UNIV_INTERN
que_t*
@@ -237,28 +191,10 @@ fts_parse_sql_no_dict_lock(
{
char* str;
que_t* graph;
- char* str_tmp = NULL;
-#ifdef UNIV_DEBUG
ut_ad(mutex_own(&dict_sys->mutex));
-#endif
-
- if (fts_table != NULL) {
- char* table_name;
-
- table_name = fts_get_table_name(fts_table);
- str_tmp = ut_strreplace(sql, "%s", table_name);
- mem_free(table_name);
- }
-
- if (str_tmp != NULL) {
- str = ut_str3cat(fts_sql_begin, str_tmp, fts_sql_end);
- mem_free(str_tmp);
- } else {
- str = ut_str3cat(fts_sql_begin, sql, fts_sql_end);
- }
- //fprintf(stderr, "%s\n", str);
+ str = ut_str3cat(fts_sql_begin, sql, fts_sql_end);
graph = pars_sql(info, str);
ut_a(graph);
diff --git a/storage/xtradb/handler/i_s.cc b/storage/xtradb/handler/i_s.cc
index 5c2d65e5799..105c5573ae9 100644
--- a/storage/xtradb/handler/i_s.cc
+++ b/storage/xtradb/handler/i_s.cc
@@ -3470,6 +3470,7 @@ i_s_fts_index_table_fill_selected(
que_t* graph;
dberr_t error;
fts_fetch_t fetch;
+ char table_name[MAX_FULL_NAME_LEN];
info = pars_info_create();
@@ -3490,6 +3491,8 @@ i_s_fts_index_table_fill_selected(
FTS_INIT_INDEX_TABLE(&fts_table, fts_get_suffix(selected),
FTS_INDEX_TABLE, index);
+ fts_get_table_name(&fts_table, table_name);
+ pars_info_bind_id(info, true, "table_name", table_name);
graph = fts_parse_sql(
&fts_table, info,
@@ -3497,7 +3500,7 @@ i_s_fts_index_table_fill_selected(
"DECLARE CURSOR c IS"
" SELECT word, doc_count, first_doc_id, last_doc_id, "
"ilist\n"
- " FROM %s WHERE word >= :word;\n"
+ " FROM $table_name WHERE word >= :word;\n"
"BEGIN\n"
"\n"
"OPEN c;\n"
diff --git a/storage/xtradb/include/fts0priv.h b/storage/xtradb/include/fts0priv.h
index a3936f54a48..4ae90f59dda 100644
--- a/storage/xtradb/include/fts0priv.h
+++ b/storage/xtradb/include/fts0priv.h
@@ -1,6 +1,7 @@
/*****************************************************************************
Copyright (c) 2011, 2018, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 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
@@ -132,16 +133,13 @@ fts_eval_sql(
trx_t* trx, /*!< in: transaction */
que_t* graph) /*!< in: Parsed statement */
MY_ATTRIBUTE((nonnull, warn_unused_result));
-/******************************************************************//**
-Construct the name of an ancillary FTS table for the given table.
-@return own: table name, must be freed with mem_free() */
+
+/** 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 */
UNIV_INTERN
-char*
-fts_get_table_name(
-/*===============*/
- const fts_table_t*
- fts_table) /*!< in: FTS aux table info */
- MY_ATTRIBUTE((nonnull, malloc, warn_unused_result));
+void fts_get_table_name(const fts_table_t* fts_table, char* table_name)
+ MY_ATTRIBUTE((nonnull));
/******************************************************************//**
Construct the column specification part of the SQL string for selecting the
indexed FTS columns for the given table. Adds the necessary bound
@@ -597,15 +595,11 @@ fts_get_table_id(
FTS_AUX_MIN_TABLE_ID_LENGTH bytes
long */
MY_ATTRIBUTE((nonnull, warn_unused_result));
-/******************************************************************//**
-Construct the prefix name of an FTS table.
-@return own: table name, must be freed with mem_free() */
-UNIV_INTERN
-char*
-fts_get_table_name_prefix(
-/*======================*/
- const fts_table_t*
- fts_table) /*!< in: Auxiliary table type */
+/** Construct the name of an internal FTS table for the given table.
+@param[in] fts_table metadata on fulltext-indexed table
+@param[in] dict_locked whether dict_sys->mutex is being held
+@return the prefix, must be freed with ut_free() */
+UNIV_INTERN char* fts_get_table_name_prefix(const fts_table_t* fts_table)
MY_ATTRIBUTE((nonnull, malloc, warn_unused_result));
/******************************************************************//**
Add node positions. */