Commit f3718a11 authored by Marko Mäkelä's avatar Marko Mäkelä

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.
parent f92749ed
......@@ -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"
""
......
This diff is collapsed.
......@@ -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);
......
......@@ -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"
......
......@@ -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);
......
......@@ -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"
......
/*****************************************************************************
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. */
......
......@@ -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"
""
......
This diff is collapsed.
......@@ -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);
......
......@@ -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"
......
......@@ -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);
......
......@@ -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"
......
/*****************************************************************************
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. */
......
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