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( ...@@ -85,6 +85,7 @@ fts_config_get_value(
que_t* graph; que_t* graph;
dberr_t error; dberr_t error;
ulint name_len = strlen(name); ulint name_len = strlen(name);
char table_name[MAX_FULL_NAME_LEN];
info = pars_info_create(); info = pars_info_create();
...@@ -100,12 +101,14 @@ fts_config_get_value( ...@@ -100,12 +101,14 @@ fts_config_get_value(
pars_info_bind_varchar_literal(info, "name", (byte*) name, name_len); pars_info_bind_varchar_literal(info, "name", (byte*) name, name_len);
fts_table->suffix = "CONFIG"; 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( graph = fts_parse_sql(
fts_table, fts_table,
info, info,
"DECLARE FUNCTION my_func;\n" "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" " WHERE key = :name;\n"
"BEGIN\n" "BEGIN\n"
"" ""
...@@ -212,6 +215,7 @@ fts_config_set_value( ...@@ -212,6 +215,7 @@ fts_config_set_value(
undo_no_t undo_no; undo_no_t undo_no;
undo_no_t n_rows_updated; undo_no_t n_rows_updated;
ulint name_len = strlen(name); ulint name_len = strlen(name);
char table_name[MAX_FULL_NAME_LEN];
info = pars_info_create(); info = pars_info_create();
...@@ -220,10 +224,13 @@ fts_config_set_value( ...@@ -220,10 +224,13 @@ fts_config_set_value(
value->f_str, value->f_len); value->f_str, value->f_len);
fts_table->suffix = "CONFIG"; 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( graph = fts_parse_sql(
fts_table, info, 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"; trx->op_info = "setting FTS config value";
...@@ -245,10 +252,13 @@ fts_config_set_value( ...@@ -245,10 +252,13 @@ fts_config_set_value(
pars_info_bind_varchar_literal( pars_info_bind_varchar_literal(
info, "value", value->f_str, value->f_len); 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( graph = fts_parse_sql(
fts_table, info, fts_table, info,
"BEGIN\n" "BEGIN\n"
"INSERT INTO \"%s\" VALUES(:name, :value);"); "INSERT INTO $table_name VALUES(:name, :value);");
trx->op_info = "inserting FTS config value"; trx->op_info = "inserting FTS config value";
...@@ -465,6 +475,7 @@ fts_config_increment_value( ...@@ -465,6 +475,7 @@ fts_config_increment_value(
que_t* graph = NULL; que_t* graph = NULL;
ulint name_len = strlen(name); ulint name_len = strlen(name);
pars_info_t* info = pars_info_create(); 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 /* We set the length of value to the max bytes it can hold. This
information is used by the callback that reads the value.*/ information is used by the callback that reads the value.*/
...@@ -479,11 +490,13 @@ fts_config_increment_value( ...@@ -479,11 +490,13 @@ fts_config_increment_value(
info, "my_func", fts_config_fetch_value, &value); info, "my_func", fts_config_fetch_value, &value);
fts_table->suffix = "CONFIG"; 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( graph = fts_parse_sql(
fts_table, info, fts_table, info,
"DECLARE FUNCTION my_func;\n" "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" " WHERE key = :name FOR UPDATE;\n"
"BEGIN\n" "BEGIN\n"
"" ""
......
This diff is collapsed.
...@@ -226,27 +226,30 @@ static ulint FTS_ZIP_BLOCK_SIZE = 1024; ...@@ -226,27 +226,30 @@ static ulint FTS_ZIP_BLOCK_SIZE = 1024;
/** The amount of time optimizing in a single pass, in milliseconds. */ /** The amount of time optimizing in a single pass, in milliseconds. */
static ib_time_t fts_optimize_time_limit = 0; 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. */ /** SQL Statement for changing state of rows to be deleted from FTS Index. */
static const char* fts_init_delete_sql = static const char* fts_init_delete_sql =
"BEGIN\n" "BEGIN\n"
"\n" "\n"
"INSERT INTO \"%s_BEING_DELETED\"\n" "INSERT INTO $BEING_DELETED\n"
"SELECT doc_id FROM \"%s_DELETED\";\n" "SELECT doc_id FROM $DELETED;\n"
"\n" "\n"
"INSERT INTO \"%s_BEING_DELETED_CACHE\"\n" "INSERT INTO $BEING_DELETED_CACHE\n"
"SELECT doc_id FROM \"%s_DELETED_CACHE\";\n"; "SELECT doc_id FROM $DELETED_CACHE;\n";
static const char* fts_delete_doc_ids_sql = static const char* fts_delete_doc_ids_sql =
"BEGIN\n" "BEGIN\n"
"\n" "\n"
"DELETE FROM \"%s_DELETED\" WHERE doc_id = :doc_id1;\n" "DELETE FROM $DELETED WHERE doc_id = :doc_id1;\n"
"DELETE FROM \"%s_DELETED_CACHE\" WHERE doc_id = :doc_id2;\n"; "DELETE FROM $DELETED_CACHE WHERE doc_id = :doc_id2;\n";
static const char* fts_end_delete_sql = static const char* fts_end_delete_sql =
"BEGIN\n" "BEGIN\n"
"\n" "\n"
"DELETE FROM \"%s_BEING_DELETED\";\n" "DELETE FROM $BEING_DELETED;\n"
"DELETE FROM \"%s_BEING_DELETED_CACHE\";\n"; "DELETE FROM $BEING_DELETED_CACHE;\n";
/**********************************************************************//** /**********************************************************************//**
Initialize fts_zip_t. */ Initialize fts_zip_t. */
...@@ -477,21 +480,17 @@ fts_index_fetch_nodes( ...@@ -477,21 +480,17 @@ fts_index_fetch_nodes(
{ {
pars_info_t* info; pars_info_t* info;
dberr_t error; dberr_t error;
char table_name[MAX_FULL_NAME_LEN];
trx->op_info = "fetching FTS index nodes"; trx->op_info = "fetching FTS index nodes";
if (*graph) { if (*graph) {
info = (*graph)->info; info = (*graph)->info;
} else { } 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; ulint selected;
info = pars_info_create();
ut_a(fts_table->type == FTS_INDEX_TABLE); ut_a(fts_table->type == FTS_INDEX_TABLE);
selected = fts_select_index(fts_table->charset, selected = fts_select_index(fts_table->charset,
...@@ -499,6 +498,16 @@ fts_index_fetch_nodes( ...@@ -499,6 +498,16 @@ fts_index_fetch_nodes(
fts_table->suffix = fts_get_suffix(selected); 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( *graph = fts_parse_sql(
fts_table, fts_table,
info, info,
...@@ -506,7 +515,7 @@ fts_index_fetch_nodes( ...@@ -506,7 +515,7 @@ fts_index_fetch_nodes(
"DECLARE CURSOR c IS" "DECLARE CURSOR c IS"
" SELECT word, doc_count, first_doc_id, last_doc_id, " " SELECT word, doc_count, first_doc_id, last_doc_id, "
"ilist\n" "ilist\n"
" FROM \"%s\"\n" " FROM $table_name\n"
" WHERE word LIKE :word\n" " WHERE word LIKE :word\n"
" ORDER BY first_doc_id;\n" " ORDER BY first_doc_id;\n"
"BEGIN\n" "BEGIN\n"
...@@ -806,6 +815,8 @@ fts_index_fetch_words( ...@@ -806,6 +815,8 @@ fts_index_fetch_words(
fts_index_selector[selected].value; fts_index_selector[selected].value;
selected++) { selected++) {
char table_name[MAX_FULL_NAME_LEN];
optim->fts_index_table.suffix = fts_get_suffix(selected); optim->fts_index_table.suffix = fts_get_suffix(selected);
/* We've search all indexes. */ /* We've search all indexes. */
...@@ -821,13 +832,16 @@ fts_index_fetch_words( ...@@ -821,13 +832,16 @@ fts_index_fetch_words(
pars_info_bind_varchar_literal( pars_info_bind_varchar_literal(
info, "word", word->f_str, word->f_len); 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( graph = fts_parse_sql(
&optim->fts_index_table, &optim->fts_index_table,
info, info,
"DECLARE FUNCTION my_func;\n" "DECLARE FUNCTION my_func;\n"
"DECLARE CURSOR c IS" "DECLARE CURSOR c IS"
" SELECT word\n" " SELECT word\n"
" FROM \"%s\"\n" " FROM $table_name\n"
" WHERE word > :word\n" " WHERE word > :word\n"
" ORDER BY word;\n" " ORDER BY word;\n"
"BEGIN\n" "BEGIN\n"
...@@ -969,6 +983,7 @@ fts_table_fetch_doc_ids( ...@@ -969,6 +983,7 @@ fts_table_fetch_doc_ids(
que_t* graph; que_t* graph;
pars_info_t* info = pars_info_create(); pars_info_t* info = pars_info_create();
ibool alloc_bk_trx = FALSE; ibool alloc_bk_trx = FALSE;
char table_name[MAX_FULL_NAME_LEN];
ut_a(fts_table->suffix != NULL); ut_a(fts_table->suffix != NULL);
ut_a(fts_table->type == FTS_COMMON_TABLE); ut_a(fts_table->type == FTS_COMMON_TABLE);
...@@ -982,12 +997,15 @@ fts_table_fetch_doc_ids( ...@@ -982,12 +997,15 @@ fts_table_fetch_doc_ids(
pars_info_bind_function(info, "my_func", fts_fetch_doc_ids, 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( graph = fts_parse_sql(
fts_table, fts_table,
info, info,
"DECLARE FUNCTION my_func;\n" "DECLARE FUNCTION my_func;\n"
"DECLARE CURSOR c IS" "DECLARE CURSOR c IS"
" SELECT doc_id FROM \"%s\";\n" " SELECT doc_id FROM $table_name;\n"
"BEGIN\n" "BEGIN\n"
"\n" "\n"
"OPEN c;\n" "OPEN c;\n"
...@@ -1440,7 +1458,7 @@ fts_optimize_write_word( ...@@ -1440,7 +1458,7 @@ fts_optimize_write_word(
que_t* graph; que_t* graph;
ulint selected; ulint selected;
dberr_t error = DB_SUCCESS; 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(); info = pars_info_create();
...@@ -1458,11 +1476,13 @@ fts_optimize_write_word( ...@@ -1458,11 +1476,13 @@ fts_optimize_write_word(
word->f_str, word->f_len); word->f_str, word->f_len);
fts_table->suffix = fts_get_suffix(selected); 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( graph = fts_parse_sql(
fts_table, fts_table,
info, info,
"BEGIN DELETE FROM \"%s\" WHERE word = :word;"); "BEGIN DELETE FROM $table_name WHERE word = :word;");
error = fts_eval_sql(trx, graph); error = fts_eval_sql(trx, graph);
...@@ -1476,8 +1496,6 @@ fts_optimize_write_word( ...@@ -1476,8 +1496,6 @@ fts_optimize_write_word(
fts_que_graph_free(graph); fts_que_graph_free(graph);
graph = NULL; graph = NULL;
mem_free(table_name);
/* Even if the operation needs to be rolled back and redone, /* Even if the operation needs to be rolled back and redone,
we iterate over the nodes in order to free the ilist. */ we iterate over the nodes in order to free the ilist. */
for (i = 0; i < ib_vector_size(nodes); ++i) { for (i = 0; i < ib_vector_size(nodes); ++i) {
...@@ -1727,7 +1745,7 @@ fts_optimize_free( ...@@ -1727,7 +1745,7 @@ fts_optimize_free(
fts_doc_ids_free(optim->to_delete); fts_doc_ids_free(optim->to_delete);
fts_optimize_graph_free(&optim->graph); 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. */ /* This will free the heap from which optim itself was allocated. */
mem_heap_free(heap); mem_heap_free(heap);
...@@ -2067,9 +2085,10 @@ fts_optimize_purge_deleted_doc_ids( ...@@ -2067,9 +2085,10 @@ fts_optimize_purge_deleted_doc_ids(
pars_info_t* info; pars_info_t* info;
que_t* graph; que_t* graph;
fts_update_t* update; fts_update_t* update;
char* sql_str;
doc_id_t write_doc_id; doc_id_t write_doc_id;
dberr_t error = DB_SUCCESS; dberr_t error = DB_SUCCESS;
char deleted[MAX_FULL_NAME_LEN];
char deleted_cache[MAX_FULL_NAME_LEN];
info = pars_info_create(); info = pars_info_create();
...@@ -2086,14 +2105,17 @@ fts_optimize_purge_deleted_doc_ids( ...@@ -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_id1", &write_doc_id);
fts_bind_doc_id(info, "doc_id2", &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 /* Make sure the following two names are consistent with the name
name, we do substitution ourselves. Remember to free sql_str. */ used in the fts_delete_doc_ids_sql */
sql_str = ut_strreplace( optim->fts_common_table.suffix = fts_common_tables[3];
fts_delete_doc_ids_sql, "%s", optim->name_prefix); 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. */ /* Delete the doc ids that were copied at the start. */
for (i = 0; i < ib_vector_size(optim->to_delete->doc_ids); ++i) { for (i = 0; i < ib_vector_size(optim->to_delete->doc_ids); ++i) {
...@@ -2134,17 +2156,26 @@ fts_optimize_purge_deleted_doc_id_snapshot( ...@@ -2134,17 +2156,26 @@ fts_optimize_purge_deleted_doc_id_snapshot(
{ {
dberr_t error; dberr_t error;
que_t* graph; 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 optim->fts_common_table.suffix = fts_common_tables[1];
the full name, we do the '%s' substitution ourselves. */ fts_get_table_name(&optim->fts_common_table, being_deleted_cache);
sql_str = ut_strreplace(fts_end_delete_sql, "%s", optim->name_prefix); 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 /* Delete the doc ids that were copied to delete pending state at
the start of optimize. */ the start of optimize. */
graph = fts_parse_sql(NULL, NULL, sql_str); graph = fts_parse_sql(NULL, info, fts_end_delete_sql);
mem_free(sql_str);
error = fts_eval_sql(optim->trx, graph); error = fts_eval_sql(optim->trx, graph);
fts_que_graph_free(graph); fts_que_graph_free(graph);
...@@ -2184,16 +2215,35 @@ fts_optimize_create_deleted_doc_id_snapshot( ...@@ -2184,16 +2215,35 @@ fts_optimize_create_deleted_doc_id_snapshot(
{ {
dberr_t error; dberr_t error;
que_t* graph; 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 info = pars_info_create();
full name, we do the substitution ourselves. */
sql_str = ut_strreplace(fts_init_delete_sql, "%s", optim->name_prefix);
/* Move doc_ids that are to be deleted to state being deleted. */ /* Make sure the following four names are consistent with the name
graph = fts_parse_sql(NULL, NULL, sql_str); 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); error = fts_eval_sql(optim->trx, graph);
......
...@@ -2032,13 +2032,22 @@ fts_query_find_term( ...@@ -2032,13 +2032,22 @@ fts_query_find_term(
fts_select_t select; fts_select_t select;
doc_id_t match_doc_id; doc_id_t match_doc_id;
trx_t* trx = query->trx; trx_t* trx = query->trx;
char table_name[MAX_FULL_NAME_LEN];
trx->op_info = "fetching FTS index matching nodes"; trx->op_info = "fetching FTS index matching nodes";
if (*graph) { if (*graph) {
info = (*graph)->info; info = (*graph)->info;
} else { } else {
ulint selected;
info = pars_info_create(); 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; select.found = FALSE;
...@@ -2057,11 +2066,6 @@ fts_query_find_term( ...@@ -2057,11 +2066,6 @@ fts_query_find_term(
fts_bind_doc_id(info, "max_doc_id", &match_doc_id); fts_bind_doc_id(info, "max_doc_id", &match_doc_id);
if (!*graph) { if (!*graph) {
ulint selected;
selected = fts_select_index(*word->f_str);
query->fts_index_table.suffix = fts_get_suffix(selected);
*graph = fts_parse_sql( *graph = fts_parse_sql(
&query->fts_index_table, &query->fts_index_table,
...@@ -2069,7 +2073,7 @@ fts_query_find_term( ...@@ -2069,7 +2073,7 @@ fts_query_find_term(
"DECLARE FUNCTION my_func;\n" "DECLARE FUNCTION my_func;\n"
"DECLARE CURSOR c IS" "DECLARE CURSOR c IS"
" SELECT doc_count, ilist\n" " SELECT doc_count, ilist\n"
" FROM \"%s\"\n" " FROM $index_table_name\n"
" WHERE word LIKE :word AND " " WHERE word LIKE :word AND "
" first_doc_id <= :min_doc_id AND " " first_doc_id <= :min_doc_id AND "
" last_doc_id >= :max_doc_id\n" " last_doc_id >= :max_doc_id\n"
...@@ -2168,6 +2172,7 @@ fts_query_total_docs_containing_term( ...@@ -2168,6 +2172,7 @@ fts_query_total_docs_containing_term(
que_t* graph; que_t* graph;
ulint selected; ulint selected;
trx_t* trx = query->trx; trx_t* trx = query->trx;
char table_name[MAX_FULL_NAME_LEN]
trx->op_info = "fetching FTS index document count"; trx->op_info = "fetching FTS index document count";
...@@ -2182,13 +2187,17 @@ fts_query_total_docs_containing_term( ...@@ -2182,13 +2187,17 @@ fts_query_total_docs_containing_term(
query->fts_index_table.suffix = fts_get_suffix(selected); 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( graph = fts_parse_sql(
&query->fts_index_table, &query->fts_index_table,
info, info,
"DECLARE FUNCTION my_func;\n" "DECLARE FUNCTION my_func;\n"
"DECLARE CURSOR c IS" "DECLARE CURSOR c IS"
" SELECT doc_count\n" " SELECT doc_count\n"
" FROM %s\n" " FROM $index_table_name\n"
" WHERE word = :word " " WHERE word = :word "
" ORDER BY first_doc_id;\n" " ORDER BY first_doc_id;\n"
"BEGIN\n" "BEGIN\n"
...@@ -2247,6 +2256,7 @@ fts_query_terms_in_document( ...@@ -2247,6 +2256,7 @@ fts_query_terms_in_document(
que_t* graph; que_t* graph;
doc_id_t read_doc_id; doc_id_t read_doc_id;
trx_t* trx = query->trx; trx_t* trx = query->trx;
char table_name[MAX_FULL_NAME_LEN];
trx->op_info = "fetching FTS document term count"; trx->op_info = "fetching FTS document term count";
...@@ -2262,13 +2272,17 @@ fts_query_terms_in_document( ...@@ -2262,13 +2272,17 @@ fts_query_terms_in_document(
query->fts_index_table.suffix = "DOC_ID"; 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( graph = fts_parse_sql(
&query->fts_index_table, &query->fts_index_table,
info, info,
"DECLARE FUNCTION my_func;\n" "DECLARE FUNCTION my_func;\n"
"DECLARE CURSOR c IS" "DECLARE CURSOR c IS"
" SELECT count\n" " SELECT count\n"
" FROM \"%s\"\n" " FROM $index_table_name\n"
" WHERE doc_id = :doc_id " " WHERE doc_id = :doc_id "
"BEGIN\n" "BEGIN\n"
"\n" "\n"
......
...@@ -36,8 +36,7 @@ Created 2007-03-27 Sunny Bains ...@@ -36,8 +36,7 @@ Created 2007-03-27 Sunny Bains
#include "fts0vlc.ic" #include "fts0vlc.ic"
#endif #endif
/** SQL statements for creating the ancillary FTS tables. %s must be replaced /** SQL statements for creating the ancillary FTS tables. */
with the indexed table's id. */
/** Preamble to all SQL statements. */ /** Preamble to all SQL statements. */
static const char* fts_sql_begin= static const char* fts_sql_begin=
...@@ -96,77 +95,47 @@ fts_get_table_id( ...@@ -96,77 +95,47 @@ fts_get_table_id(
return(len); return(len);
} }
/******************************************************************//** /** Construct the name of an internal FTS table for the given table.
Construct the prefix name of an FTS table. @param[in] fts_table metadata on fulltext-indexed table
@return own: table name, must be freed with mem_free() */ @param[in] dict_locked whether dict_sys->mutex is being held
UNIV_INTERN @return the prefix, must be freed with ut_free() */
char* UNIV_INTERN char* fts_get_table_name_prefix(const fts_table_t* fts_table)
fts_get_table_name_prefix(
/*======================*/
const fts_table_t*
fts_table) /*!< in: Auxiliary table type */
{ {
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]; char table_id[FTS_AUX_MIN_TABLE_ID_LENGTH];
const size_t table_id_len = size_t(fts_get_table_id(fts_table,
#if 0 /* FIXME: protect the access to dict_table_t::name */ table_id)) + 1;
ut_ad(mutex_own(&dict_sys->mutex)); mutex_enter(&dict_sys->mutex);
#endif const char* slash = strchr(fts_table->table->name, '/');
slash = static_cast<const char*>(
strchr(fts_table->table->name, '/'));
ut_ad(slash); ut_ad(slash);
/* Print up to and including the separator. */ /* Include the separator as well. */
dbname_len = static_cast<int>(slash - fts_table->table->name) + 1; const size_t dbname_len = (slash - fts_table->table->name) + 1;
ut_ad(dbname_len > 1);
len = fts_get_table_id(fts_table, table_id); const size_t prefix_name_len = dbname_len + 4 + table_id_len;
char* prefix_name = static_cast<char*>(ut_malloc(prefix_name_len));
prefix_name_len = dbname_len + 4 + len + 1; memcpy(prefix_name, fts_table->table->name, dbname_len);
mutex_exit(&dict_sys->mutex);
prefix_name = static_cast<char*>(mem_alloc(prefix_name_len)); memcpy(prefix_name + dbname_len, "FTS_", 4);
memcpy(prefix_name + dbname_len + 4, table_id, table_id_len);
len = sprintf(prefix_name, "%.*sFTS_%s", return prefix_name;
dbname_len, fts_table->table->name, table_id);
ut_a(len > 0);
ut_a(len == prefix_name_len - 1);
return(prefix_name);
} }
/******************************************************************//** /** Construct the name of an internal FTS table for the given table.
Construct the name of an ancillary FTS table. @param[in] fts_table metadata on fulltext-indexed table
@return own: table name, must be freed with mem_free() */ @param[out] table_name a name up to MAX_FULL_NAME_LEN */
UNIV_INTERN UNIV_INTERN
char* void fts_get_table_name(const fts_table_t* fts_table, char* table_name)
fts_get_table_name(
/*===============*/
const fts_table_t* fts_table)
/*!< in: Auxiliary table type */
{ {
int len; const char* slash = strchr(fts_table->table->name, '/');
char* name; ut_ad(slash);
int name_len; /* Include the separator as well. */
char* prefix_name; const size_t dbname_len = (slash - fts_table->table->name) + 1;
ut_ad(dbname_len > 1);
prefix_name = fts_get_table_name_prefix(fts_table); memcpy(table_name, fts_table->table->name, dbname_len);
memcpy(table_name += dbname_len, "FTS_", 4);
name_len = static_cast<int>( table_name += 4;
strlen(prefix_name) + 1 + strlen(fts_table->suffix) + 1); table_name += fts_get_table_id(fts_table, table_name);
*table_name++ = '_';
name = static_cast<char*>(mem_alloc(name_len)); strcpy(table_name, fts_table->suffix);
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);
} }
/******************************************************************//** /******************************************************************//**
...@@ -182,24 +151,9 @@ fts_parse_sql( ...@@ -182,24 +151,9 @@ fts_parse_sql(
{ {
char* str; char* str;
que_t* graph; que_t* graph;
char* str_tmp;
ibool dict_locked; ibool dict_locked;
if (fts_table != NULL) { str = ut_str3cat(fts_sql_begin, sql, fts_sql_end);
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);
dict_locked = (fts_table && fts_table->table->fts dict_locked = (fts_table && fts_table->table->fts
&& (fts_table->table->fts->fts_status && (fts_table->table->fts->fts_status
...@@ -225,7 +179,7 @@ fts_parse_sql( ...@@ -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 */ @return query graph */
UNIV_INTERN UNIV_INTERN
que_t* que_t*
...@@ -237,28 +191,10 @@ fts_parse_sql_no_dict_lock( ...@@ -237,28 +191,10 @@ fts_parse_sql_no_dict_lock(
{ {
char* str; char* str;
que_t* graph; que_t* graph;
char* str_tmp = NULL;
#ifdef UNIV_DEBUG
ut_ad(mutex_own(&dict_sys->mutex)); 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); str = ut_str3cat(fts_sql_begin, sql, fts_sql_end);
}
//fprintf(stderr, "%s\n", str);
graph = pars_sql(info, str); graph = pars_sql(info, str);
ut_a(graph); ut_a(graph);
......
...@@ -3479,6 +3479,7 @@ i_s_fts_index_table_fill_selected( ...@@ -3479,6 +3479,7 @@ i_s_fts_index_table_fill_selected(
que_t* graph; que_t* graph;
dberr_t error; dberr_t error;
fts_fetch_t fetch; fts_fetch_t fetch;
char table_name[MAX_FULL_NAME_LEN];
info = pars_info_create(); info = pars_info_create();
...@@ -3499,6 +3500,8 @@ i_s_fts_index_table_fill_selected( ...@@ -3499,6 +3500,8 @@ i_s_fts_index_table_fill_selected(
FTS_INIT_INDEX_TABLE(&fts_table, fts_get_suffix(selected), FTS_INIT_INDEX_TABLE(&fts_table, fts_get_suffix(selected),
FTS_INDEX_TABLE, index); 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( graph = fts_parse_sql(
&fts_table, info, &fts_table, info,
...@@ -3506,7 +3509,7 @@ i_s_fts_index_table_fill_selected( ...@@ -3506,7 +3509,7 @@ i_s_fts_index_table_fill_selected(
"DECLARE CURSOR c IS" "DECLARE CURSOR c IS"
" SELECT word, doc_count, first_doc_id, last_doc_id, " " SELECT word, doc_count, first_doc_id, last_doc_id, "
"ilist\n" "ilist\n"
" FROM %s WHERE word >= :word;\n" " FROM $table_name WHERE word >= :word;\n"
"BEGIN\n" "BEGIN\n"
"\n" "\n"
"OPEN c;\n" "OPEN c;\n"
......
/***************************************************************************** /*****************************************************************************
Copyright (c) 2011, 2018, Oracle and/or its affiliates. All Rights Reserved. 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 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 the terms of the GNU General Public License as published by the Free Software
...@@ -132,16 +133,13 @@ fts_eval_sql( ...@@ -132,16 +133,13 @@ fts_eval_sql(
trx_t* trx, /*!< in: transaction */ trx_t* trx, /*!< in: transaction */
que_t* graph) /*!< in: Parsed statement */ que_t* graph) /*!< in: Parsed statement */
MY_ATTRIBUTE((nonnull, warn_unused_result)); MY_ATTRIBUTE((nonnull, warn_unused_result));
/******************************************************************//**
Construct the name of an ancillary FTS table for the given table. /** Construct the name of an internal FTS table for the given table.
@return own: table name, must be freed with mem_free() */ @param[in] fts_table metadata on fulltext-indexed table
@param[out] table_name a name up to MAX_FULL_NAME_LEN */
UNIV_INTERN UNIV_INTERN
char* void fts_get_table_name(const fts_table_t* fts_table, char* table_name)
fts_get_table_name( MY_ATTRIBUTE((nonnull));
/*===============*/
const fts_table_t*
fts_table) /*!< in: FTS aux table info */
MY_ATTRIBUTE((nonnull, malloc, warn_unused_result));
/******************************************************************//** /******************************************************************//**
Construct the column specification part of the SQL string for selecting the Construct the column specification part of the SQL string for selecting the
indexed FTS columns for the given table. Adds the necessary bound indexed FTS columns for the given table. Adds the necessary bound
...@@ -597,15 +595,11 @@ fts_get_table_id( ...@@ -597,15 +595,11 @@ fts_get_table_id(
FTS_AUX_MIN_TABLE_ID_LENGTH bytes FTS_AUX_MIN_TABLE_ID_LENGTH bytes
long */ long */
MY_ATTRIBUTE((nonnull, warn_unused_result)); MY_ATTRIBUTE((nonnull, warn_unused_result));
/******************************************************************//** /** Construct the name of an internal FTS table for the given table.
Construct the prefix name of an FTS table. @param[in] fts_table metadata on fulltext-indexed table
@return own: table name, must be freed with mem_free() */ @param[in] dict_locked whether dict_sys->mutex is being held
UNIV_INTERN @return the prefix, must be freed with ut_free() */
char* UNIV_INTERN char* fts_get_table_name_prefix(const fts_table_t* fts_table)
fts_get_table_name_prefix(
/*======================*/
const fts_table_t*
fts_table) /*!< in: Auxiliary table type */
MY_ATTRIBUTE((nonnull, malloc, warn_unused_result)); MY_ATTRIBUTE((nonnull, malloc, warn_unused_result));
/******************************************************************//** /******************************************************************//**
Add node positions. */ Add node positions. */
......
...@@ -85,6 +85,7 @@ fts_config_get_value( ...@@ -85,6 +85,7 @@ fts_config_get_value(
que_t* graph; que_t* graph;
dberr_t error; dberr_t error;
ulint name_len = strlen(name); ulint name_len = strlen(name);
char table_name[MAX_FULL_NAME_LEN];
info = pars_info_create(); info = pars_info_create();
...@@ -100,12 +101,14 @@ fts_config_get_value( ...@@ -100,12 +101,14 @@ fts_config_get_value(
pars_info_bind_varchar_literal(info, "name", (byte*) name, name_len); pars_info_bind_varchar_literal(info, "name", (byte*) name, name_len);
fts_table->suffix = "CONFIG"; 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( graph = fts_parse_sql(
fts_table, fts_table,
info, info,
"DECLARE FUNCTION my_func;\n" "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" " WHERE key = :name;\n"
"BEGIN\n" "BEGIN\n"
"" ""
...@@ -212,6 +215,7 @@ fts_config_set_value( ...@@ -212,6 +215,7 @@ fts_config_set_value(
undo_no_t undo_no; undo_no_t undo_no;
undo_no_t n_rows_updated; undo_no_t n_rows_updated;
ulint name_len = strlen(name); ulint name_len = strlen(name);
char table_name[MAX_FULL_NAME_LEN];
info = pars_info_create(); info = pars_info_create();
...@@ -220,10 +224,13 @@ fts_config_set_value( ...@@ -220,10 +224,13 @@ fts_config_set_value(
value->f_str, value->f_len); value->f_str, value->f_len);
fts_table->suffix = "CONFIG"; 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( graph = fts_parse_sql(
fts_table, info, 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"; trx->op_info = "setting FTS config value";
...@@ -245,10 +252,13 @@ fts_config_set_value( ...@@ -245,10 +252,13 @@ fts_config_set_value(
pars_info_bind_varchar_literal( pars_info_bind_varchar_literal(
info, "value", value->f_str, value->f_len); 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( graph = fts_parse_sql(
fts_table, info, fts_table, info,
"BEGIN\n" "BEGIN\n"
"INSERT INTO \"%s\" VALUES(:name, :value);"); "INSERT INTO $table_name VALUES(:name, :value);");
trx->op_info = "inserting FTS config value"; trx->op_info = "inserting FTS config value";
...@@ -465,6 +475,7 @@ fts_config_increment_value( ...@@ -465,6 +475,7 @@ fts_config_increment_value(
que_t* graph = NULL; que_t* graph = NULL;
ulint name_len = strlen(name); ulint name_len = strlen(name);
pars_info_t* info = pars_info_create(); 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 /* We set the length of value to the max bytes it can hold. This
information is used by the callback that reads the value.*/ information is used by the callback that reads the value.*/
...@@ -479,11 +490,13 @@ fts_config_increment_value( ...@@ -479,11 +490,13 @@ fts_config_increment_value(
info, "my_func", fts_config_fetch_value, &value); info, "my_func", fts_config_fetch_value, &value);
fts_table->suffix = "CONFIG"; 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( graph = fts_parse_sql(
fts_table, info, fts_table, info,
"DECLARE FUNCTION my_func;\n" "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" " WHERE key = :name FOR UPDATE;\n"
"BEGIN\n" "BEGIN\n"
"" ""
......
This diff is collapsed.
...@@ -226,27 +226,30 @@ static ulint FTS_ZIP_BLOCK_SIZE = 1024; ...@@ -226,27 +226,30 @@ static ulint FTS_ZIP_BLOCK_SIZE = 1024;
/** The amount of time optimizing in a single pass, in milliseconds. */ /** The amount of time optimizing in a single pass, in milliseconds. */
static ib_time_t fts_optimize_time_limit = 0; 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. */ /** SQL Statement for changing state of rows to be deleted from FTS Index. */
static const char* fts_init_delete_sql = static const char* fts_init_delete_sql =
"BEGIN\n" "BEGIN\n"
"\n" "\n"
"INSERT INTO \"%s_BEING_DELETED\"\n" "INSERT INTO $BEING_DELETED\n"
"SELECT doc_id FROM \"%s_DELETED\";\n" "SELECT doc_id FROM $DELETED;\n"
"\n" "\n"
"INSERT INTO \"%s_BEING_DELETED_CACHE\"\n" "INSERT INTO $BEING_DELETED_CACHE\n"
"SELECT doc_id FROM \"%s_DELETED_CACHE\";\n"; "SELECT doc_id FROM $DELETED_CACHE;\n";
static const char* fts_delete_doc_ids_sql = static const char* fts_delete_doc_ids_sql =
"BEGIN\n" "BEGIN\n"
"\n" "\n"
"DELETE FROM \"%s_DELETED\" WHERE doc_id = :doc_id1;\n" "DELETE FROM $DELETED WHERE doc_id = :doc_id1;\n"
"DELETE FROM \"%s_DELETED_CACHE\" WHERE doc_id = :doc_id2;\n"; "DELETE FROM $DELETED_CACHE WHERE doc_id = :doc_id2;\n";
static const char* fts_end_delete_sql = static const char* fts_end_delete_sql =
"BEGIN\n" "BEGIN\n"
"\n" "\n"
"DELETE FROM \"%s_BEING_DELETED\";\n" "DELETE FROM $BEING_DELETED;\n"
"DELETE FROM \"%s_BEING_DELETED_CACHE\";\n"; "DELETE FROM $BEING_DELETED_CACHE;\n";
/**********************************************************************//** /**********************************************************************//**
Initialize fts_zip_t. */ Initialize fts_zip_t. */
...@@ -477,21 +480,17 @@ fts_index_fetch_nodes( ...@@ -477,21 +480,17 @@ fts_index_fetch_nodes(
{ {
pars_info_t* info; pars_info_t* info;
dberr_t error; dberr_t error;
char table_name[MAX_FULL_NAME_LEN];
trx->op_info = "fetching FTS index nodes"; trx->op_info = "fetching FTS index nodes";
if (*graph) { if (*graph) {
info = (*graph)->info; info = (*graph)->info;
} else { } 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; ulint selected;
info = pars_info_create();
ut_a(fts_table->type == FTS_INDEX_TABLE); ut_a(fts_table->type == FTS_INDEX_TABLE);
selected = fts_select_index(fts_table->charset, selected = fts_select_index(fts_table->charset,
...@@ -499,6 +498,16 @@ fts_index_fetch_nodes( ...@@ -499,6 +498,16 @@ fts_index_fetch_nodes(
fts_table->suffix = fts_get_suffix(selected); 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( *graph = fts_parse_sql(
fts_table, fts_table,
info, info,
...@@ -506,7 +515,7 @@ fts_index_fetch_nodes( ...@@ -506,7 +515,7 @@ fts_index_fetch_nodes(
"DECLARE CURSOR c IS" "DECLARE CURSOR c IS"
" SELECT word, doc_count, first_doc_id, last_doc_id, " " SELECT word, doc_count, first_doc_id, last_doc_id, "
"ilist\n" "ilist\n"
" FROM \"%s\"\n" " FROM $table_name\n"
" WHERE word LIKE :word\n" " WHERE word LIKE :word\n"
" ORDER BY first_doc_id;\n" " ORDER BY first_doc_id;\n"
"BEGIN\n" "BEGIN\n"
...@@ -806,6 +815,8 @@ fts_index_fetch_words( ...@@ -806,6 +815,8 @@ fts_index_fetch_words(
fts_index_selector[selected].value; fts_index_selector[selected].value;
selected++) { selected++) {
char table_name[MAX_FULL_NAME_LEN];
optim->fts_index_table.suffix = fts_get_suffix(selected); optim->fts_index_table.suffix = fts_get_suffix(selected);
/* We've search all indexes. */ /* We've search all indexes. */
...@@ -821,13 +832,16 @@ fts_index_fetch_words( ...@@ -821,13 +832,16 @@ fts_index_fetch_words(
pars_info_bind_varchar_literal( pars_info_bind_varchar_literal(
info, "word", word->f_str, word->f_len); 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( graph = fts_parse_sql(
&optim->fts_index_table, &optim->fts_index_table,
info, info,
"DECLARE FUNCTION my_func;\n" "DECLARE FUNCTION my_func;\n"
"DECLARE CURSOR c IS" "DECLARE CURSOR c IS"
" SELECT word\n" " SELECT word\n"
" FROM \"%s\"\n" " FROM $table_name\n"
" WHERE word > :word\n" " WHERE word > :word\n"
" ORDER BY word;\n" " ORDER BY word;\n"
"BEGIN\n" "BEGIN\n"
...@@ -969,6 +983,7 @@ fts_table_fetch_doc_ids( ...@@ -969,6 +983,7 @@ fts_table_fetch_doc_ids(
que_t* graph; que_t* graph;
pars_info_t* info = pars_info_create(); pars_info_t* info = pars_info_create();
ibool alloc_bk_trx = FALSE; ibool alloc_bk_trx = FALSE;
char table_name[MAX_FULL_NAME_LEN];
ut_a(fts_table->suffix != NULL); ut_a(fts_table->suffix != NULL);
ut_a(fts_table->type == FTS_COMMON_TABLE); ut_a(fts_table->type == FTS_COMMON_TABLE);
...@@ -982,12 +997,15 @@ fts_table_fetch_doc_ids( ...@@ -982,12 +997,15 @@ fts_table_fetch_doc_ids(
pars_info_bind_function(info, "my_func", fts_fetch_doc_ids, 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( graph = fts_parse_sql(
fts_table, fts_table,
info, info,
"DECLARE FUNCTION my_func;\n" "DECLARE FUNCTION my_func;\n"
"DECLARE CURSOR c IS" "DECLARE CURSOR c IS"
" SELECT doc_id FROM \"%s\";\n" " SELECT doc_id FROM $table_name;\n"
"BEGIN\n" "BEGIN\n"
"\n" "\n"
"OPEN c;\n" "OPEN c;\n"
...@@ -1440,7 +1458,7 @@ fts_optimize_write_word( ...@@ -1440,7 +1458,7 @@ fts_optimize_write_word(
que_t* graph; que_t* graph;
ulint selected; ulint selected;
dberr_t error = DB_SUCCESS; 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(); info = pars_info_create();
...@@ -1458,11 +1476,13 @@ fts_optimize_write_word( ...@@ -1458,11 +1476,13 @@ fts_optimize_write_word(
word->f_str, word->f_len); word->f_str, word->f_len);
fts_table->suffix = fts_get_suffix(selected); 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( graph = fts_parse_sql(
fts_table, fts_table,
info, info,
"BEGIN DELETE FROM \"%s\" WHERE word = :word;"); "BEGIN DELETE FROM $table_name WHERE word = :word;");
error = fts_eval_sql(trx, graph); error = fts_eval_sql(trx, graph);
...@@ -1476,8 +1496,6 @@ fts_optimize_write_word( ...@@ -1476,8 +1496,6 @@ fts_optimize_write_word(
fts_que_graph_free(graph); fts_que_graph_free(graph);
graph = NULL; graph = NULL;
mem_free(table_name);
/* Even if the operation needs to be rolled back and redone, /* Even if the operation needs to be rolled back and redone,
we iterate over the nodes in order to free the ilist. */ we iterate over the nodes in order to free the ilist. */
for (i = 0; i < ib_vector_size(nodes); ++i) { for (i = 0; i < ib_vector_size(nodes); ++i) {
...@@ -1727,7 +1745,7 @@ fts_optimize_free( ...@@ -1727,7 +1745,7 @@ fts_optimize_free(
fts_doc_ids_free(optim->to_delete); fts_doc_ids_free(optim->to_delete);
fts_optimize_graph_free(&optim->graph); 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. */ /* This will free the heap from which optim itself was allocated. */
mem_heap_free(heap); mem_heap_free(heap);
...@@ -2067,9 +2085,10 @@ fts_optimize_purge_deleted_doc_ids( ...@@ -2067,9 +2085,10 @@ fts_optimize_purge_deleted_doc_ids(
pars_info_t* info; pars_info_t* info;
que_t* graph; que_t* graph;
fts_update_t* update; fts_update_t* update;
char* sql_str;
doc_id_t write_doc_id; doc_id_t write_doc_id;
dberr_t error = DB_SUCCESS; dberr_t error = DB_SUCCESS;
char deleted[MAX_FULL_NAME_LEN];
char deleted_cache[MAX_FULL_NAME_LEN];
info = pars_info_create(); info = pars_info_create();
...@@ -2086,14 +2105,17 @@ fts_optimize_purge_deleted_doc_ids( ...@@ -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_id1", &write_doc_id);
fts_bind_doc_id(info, "doc_id2", &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 /* Make sure the following two names are consistent with the name
name, we do substitution ourselves. Remember to free sql_str. */ used in the fts_delete_doc_ids_sql */
sql_str = ut_strreplace( optim->fts_common_table.suffix = fts_common_tables[3];
fts_delete_doc_ids_sql, "%s", optim->name_prefix); 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. */ /* Delete the doc ids that were copied at the start. */
for (i = 0; i < ib_vector_size(optim->to_delete->doc_ids); ++i) { for (i = 0; i < ib_vector_size(optim->to_delete->doc_ids); ++i) {
...@@ -2134,17 +2156,26 @@ fts_optimize_purge_deleted_doc_id_snapshot( ...@@ -2134,17 +2156,26 @@ fts_optimize_purge_deleted_doc_id_snapshot(
{ {
dberr_t error; dberr_t error;
que_t* graph; 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 optim->fts_common_table.suffix = fts_common_tables[1];
the full name, we do the '%s' substitution ourselves. */ fts_get_table_name(&optim->fts_common_table, being_deleted_cache);
sql_str = ut_strreplace(fts_end_delete_sql, "%s", optim->name_prefix); 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 /* Delete the doc ids that were copied to delete pending state at
the start of optimize. */ the start of optimize. */
graph = fts_parse_sql(NULL, NULL, sql_str); graph = fts_parse_sql(NULL, info, fts_end_delete_sql);
mem_free(sql_str);
error = fts_eval_sql(optim->trx, graph); error = fts_eval_sql(optim->trx, graph);
fts_que_graph_free(graph); fts_que_graph_free(graph);
...@@ -2184,16 +2215,35 @@ fts_optimize_create_deleted_doc_id_snapshot( ...@@ -2184,16 +2215,35 @@ fts_optimize_create_deleted_doc_id_snapshot(
{ {
dberr_t error; dberr_t error;
que_t* graph; 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 info = pars_info_create();
full name, we do the substitution ourselves. */
sql_str = ut_strreplace(fts_init_delete_sql, "%s", optim->name_prefix);
/* Move doc_ids that are to be deleted to state being deleted. */ /* Make sure the following four names are consistent with the name
graph = fts_parse_sql(NULL, NULL, sql_str); 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); error = fts_eval_sql(optim->trx, graph);
......
...@@ -2052,13 +2052,22 @@ fts_query_find_term( ...@@ -2052,13 +2052,22 @@ fts_query_find_term(
fts_select_t select; fts_select_t select;
doc_id_t match_doc_id; doc_id_t match_doc_id;
trx_t* trx = query->trx; trx_t* trx = query->trx;
char table_name[MAX_FULL_NAME_LEN];
trx->op_info = "fetching FTS index matching nodes"; trx->op_info = "fetching FTS index matching nodes";
if (*graph) { if (*graph) {
info = (*graph)->info; info = (*graph)->info;
} else { } else {
ulint selected;
info = pars_info_create(); 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; select.found = FALSE;
...@@ -2077,11 +2086,6 @@ fts_query_find_term( ...@@ -2077,11 +2086,6 @@ fts_query_find_term(
fts_bind_doc_id(info, "max_doc_id", &match_doc_id); fts_bind_doc_id(info, "max_doc_id", &match_doc_id);
if (!*graph) { if (!*graph) {
ulint selected;
selected = fts_select_index(*word->f_str);
query->fts_index_table.suffix = fts_get_suffix(selected);
*graph = fts_parse_sql( *graph = fts_parse_sql(
&query->fts_index_table, &query->fts_index_table,
...@@ -2089,7 +2093,7 @@ fts_query_find_term( ...@@ -2089,7 +2093,7 @@ fts_query_find_term(
"DECLARE FUNCTION my_func;\n" "DECLARE FUNCTION my_func;\n"
"DECLARE CURSOR c IS" "DECLARE CURSOR c IS"
" SELECT doc_count, ilist\n" " SELECT doc_count, ilist\n"
" FROM \"%s\"\n" " FROM $index_table_name\n"
" WHERE word LIKE :word AND " " WHERE word LIKE :word AND "
" first_doc_id <= :min_doc_id AND " " first_doc_id <= :min_doc_id AND "
" last_doc_id >= :max_doc_id\n" " last_doc_id >= :max_doc_id\n"
...@@ -2188,6 +2192,7 @@ fts_query_total_docs_containing_term( ...@@ -2188,6 +2192,7 @@ fts_query_total_docs_containing_term(
que_t* graph; que_t* graph;
ulint selected; ulint selected;
trx_t* trx = query->trx; trx_t* trx = query->trx;
char table_name[MAX_FULL_NAME_LEN]
trx->op_info = "fetching FTS index document count"; trx->op_info = "fetching FTS index document count";
...@@ -2202,13 +2207,17 @@ fts_query_total_docs_containing_term( ...@@ -2202,13 +2207,17 @@ fts_query_total_docs_containing_term(
query->fts_index_table.suffix = fts_get_suffix(selected); 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( graph = fts_parse_sql(
&query->fts_index_table, &query->fts_index_table,
info, info,
"DECLARE FUNCTION my_func;\n" "DECLARE FUNCTION my_func;\n"
"DECLARE CURSOR c IS" "DECLARE CURSOR c IS"
" SELECT doc_count\n" " SELECT doc_count\n"
" FROM %s\n" " FROM $index_table_name\n"
" WHERE word = :word " " WHERE word = :word "
" ORDER BY first_doc_id;\n" " ORDER BY first_doc_id;\n"
"BEGIN\n" "BEGIN\n"
...@@ -2267,6 +2276,7 @@ fts_query_terms_in_document( ...@@ -2267,6 +2276,7 @@ fts_query_terms_in_document(
que_t* graph; que_t* graph;
doc_id_t read_doc_id; doc_id_t read_doc_id;
trx_t* trx = query->trx; trx_t* trx = query->trx;
char table_name[MAX_FULL_NAME_LEN];
trx->op_info = "fetching FTS document term count"; trx->op_info = "fetching FTS document term count";
...@@ -2282,13 +2292,17 @@ fts_query_terms_in_document( ...@@ -2282,13 +2292,17 @@ fts_query_terms_in_document(
query->fts_index_table.suffix = "DOC_ID"; 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( graph = fts_parse_sql(
&query->fts_index_table, &query->fts_index_table,
info, info,
"DECLARE FUNCTION my_func;\n" "DECLARE FUNCTION my_func;\n"
"DECLARE CURSOR c IS" "DECLARE CURSOR c IS"
" SELECT count\n" " SELECT count\n"
" FROM \"%s\"\n" " FROM $index_table_name\n"
" WHERE doc_id = :doc_id " " WHERE doc_id = :doc_id "
"BEGIN\n" "BEGIN\n"
"\n" "\n"
......
...@@ -36,8 +36,7 @@ Created 2007-03-27 Sunny Bains ...@@ -36,8 +36,7 @@ Created 2007-03-27 Sunny Bains
#include "fts0vlc.ic" #include "fts0vlc.ic"
#endif #endif
/** SQL statements for creating the ancillary FTS tables. %s must be replaced /** SQL statements for creating the ancillary FTS tables. */
with the indexed table's id. */
/** Preamble to all SQL statements. */ /** Preamble to all SQL statements. */
static const char* fts_sql_begin= static const char* fts_sql_begin=
...@@ -96,77 +95,47 @@ fts_get_table_id( ...@@ -96,77 +95,47 @@ fts_get_table_id(
return(len); return(len);
} }
/******************************************************************//** /** Construct the name of an internal FTS table for the given table.
Construct the prefix name of an FTS table. @param[in] fts_table metadata on fulltext-indexed table
@return own: table name, must be freed with mem_free() */ @param[in] dict_locked whether dict_sys->mutex is being held
UNIV_INTERN @return the prefix, must be freed with ut_free() */
char* UNIV_INTERN char* fts_get_table_name_prefix(const fts_table_t* fts_table)
fts_get_table_name_prefix(
/*======================*/
const fts_table_t*
fts_table) /*!< in: Auxiliary table type */
{ {
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]; char table_id[FTS_AUX_MIN_TABLE_ID_LENGTH];
const size_t table_id_len = size_t(fts_get_table_id(fts_table,
#if 0 /* FIXME: protect the access to dict_table_t::name */ table_id)) + 1;
ut_ad(mutex_own(&dict_sys->mutex)); mutex_enter(&dict_sys->mutex);
#endif const char* slash = strchr(fts_table->table->name, '/');
slash = static_cast<const char*>(
strchr(fts_table->table->name, '/'));
ut_ad(slash); ut_ad(slash);
/* Print up to and including the separator. */ /* Include the separator as well. */
dbname_len = static_cast<int>(slash - fts_table->table->name) + 1; const size_t dbname_len = (slash - fts_table->table->name) + 1;
ut_ad(dbname_len > 1);
len = fts_get_table_id(fts_table, table_id); const size_t prefix_name_len = dbname_len + 4 + table_id_len;
char* prefix_name = static_cast<char*>(ut_malloc(prefix_name_len));
prefix_name_len = dbname_len + 4 + len + 1; memcpy(prefix_name, fts_table->table->name, dbname_len);
mutex_exit(&dict_sys->mutex);
prefix_name = static_cast<char*>(mem_alloc(prefix_name_len)); memcpy(prefix_name + dbname_len, "FTS_", 4);
memcpy(prefix_name + dbname_len + 4, table_id, table_id_len);
len = sprintf(prefix_name, "%.*sFTS_%s", return prefix_name;
dbname_len, fts_table->table->name, table_id);
ut_a(len > 0);
ut_a(len == prefix_name_len - 1);
return(prefix_name);
} }
/******************************************************************//** /** Construct the name of an internal FTS table for the given table.
Construct the name of an ancillary FTS table. @param[in] fts_table metadata on fulltext-indexed table
@return own: table name, must be freed with mem_free() */ @param[out] table_name a name up to MAX_FULL_NAME_LEN */
UNIV_INTERN UNIV_INTERN
char* void fts_get_table_name(const fts_table_t* fts_table, char* table_name)
fts_get_table_name(
/*===============*/
const fts_table_t* fts_table)
/*!< in: Auxiliary table type */
{ {
int len; const char* slash = strchr(fts_table->table->name, '/');
char* name; ut_ad(slash);
int name_len; /* Include the separator as well. */
char* prefix_name; const size_t dbname_len = (slash - fts_table->table->name) + 1;
ut_ad(dbname_len > 1);
prefix_name = fts_get_table_name_prefix(fts_table); memcpy(table_name, fts_table->table->name, dbname_len);
memcpy(table_name += dbname_len, "FTS_", 4);
name_len = static_cast<int>( table_name += 4;
strlen(prefix_name) + 1 + strlen(fts_table->suffix) + 1); table_name += fts_get_table_id(fts_table, table_name);
*table_name++ = '_';
name = static_cast<char*>(mem_alloc(name_len)); strcpy(table_name, fts_table->suffix);
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);
} }
/******************************************************************//** /******************************************************************//**
...@@ -182,24 +151,9 @@ fts_parse_sql( ...@@ -182,24 +151,9 @@ fts_parse_sql(
{ {
char* str; char* str;
que_t* graph; que_t* graph;
char* str_tmp;
ibool dict_locked; ibool dict_locked;
if (fts_table != NULL) { str = ut_str3cat(fts_sql_begin, sql, fts_sql_end);
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);
dict_locked = (fts_table && fts_table->table->fts dict_locked = (fts_table && fts_table->table->fts
&& (fts_table->table->fts->fts_status && (fts_table->table->fts->fts_status
...@@ -225,7 +179,7 @@ fts_parse_sql( ...@@ -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 */ @return query graph */
UNIV_INTERN UNIV_INTERN
que_t* que_t*
...@@ -237,28 +191,10 @@ fts_parse_sql_no_dict_lock( ...@@ -237,28 +191,10 @@ fts_parse_sql_no_dict_lock(
{ {
char* str; char* str;
que_t* graph; que_t* graph;
char* str_tmp = NULL;
#ifdef UNIV_DEBUG
ut_ad(mutex_own(&dict_sys->mutex)); 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); str = ut_str3cat(fts_sql_begin, sql, fts_sql_end);
}
//fprintf(stderr, "%s\n", str);
graph = pars_sql(info, str); graph = pars_sql(info, str);
ut_a(graph); ut_a(graph);
......
...@@ -3470,6 +3470,7 @@ i_s_fts_index_table_fill_selected( ...@@ -3470,6 +3470,7 @@ i_s_fts_index_table_fill_selected(
que_t* graph; que_t* graph;
dberr_t error; dberr_t error;
fts_fetch_t fetch; fts_fetch_t fetch;
char table_name[MAX_FULL_NAME_LEN];
info = pars_info_create(); info = pars_info_create();
...@@ -3490,6 +3491,8 @@ i_s_fts_index_table_fill_selected( ...@@ -3490,6 +3491,8 @@ i_s_fts_index_table_fill_selected(
FTS_INIT_INDEX_TABLE(&fts_table, fts_get_suffix(selected), FTS_INIT_INDEX_TABLE(&fts_table, fts_get_suffix(selected),
FTS_INDEX_TABLE, index); 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( graph = fts_parse_sql(
&fts_table, info, &fts_table, info,
...@@ -3497,7 +3500,7 @@ i_s_fts_index_table_fill_selected( ...@@ -3497,7 +3500,7 @@ i_s_fts_index_table_fill_selected(
"DECLARE CURSOR c IS" "DECLARE CURSOR c IS"
" SELECT word, doc_count, first_doc_id, last_doc_id, " " SELECT word, doc_count, first_doc_id, last_doc_id, "
"ilist\n" "ilist\n"
" FROM %s WHERE word >= :word;\n" " FROM $table_name WHERE word >= :word;\n"
"BEGIN\n" "BEGIN\n"
"\n" "\n"
"OPEN c;\n" "OPEN c;\n"
......
/***************************************************************************** /*****************************************************************************
Copyright (c) 2011, 2018, Oracle and/or its affiliates. All Rights Reserved. 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 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 the terms of the GNU General Public License as published by the Free Software
...@@ -132,16 +133,13 @@ fts_eval_sql( ...@@ -132,16 +133,13 @@ fts_eval_sql(
trx_t* trx, /*!< in: transaction */ trx_t* trx, /*!< in: transaction */
que_t* graph) /*!< in: Parsed statement */ que_t* graph) /*!< in: Parsed statement */
MY_ATTRIBUTE((nonnull, warn_unused_result)); MY_ATTRIBUTE((nonnull, warn_unused_result));
/******************************************************************//**
Construct the name of an ancillary FTS table for the given table. /** Construct the name of an internal FTS table for the given table.
@return own: table name, must be freed with mem_free() */ @param[in] fts_table metadata on fulltext-indexed table
@param[out] table_name a name up to MAX_FULL_NAME_LEN */
UNIV_INTERN UNIV_INTERN
char* void fts_get_table_name(const fts_table_t* fts_table, char* table_name)
fts_get_table_name( MY_ATTRIBUTE((nonnull));
/*===============*/
const fts_table_t*
fts_table) /*!< in: FTS aux table info */
MY_ATTRIBUTE((nonnull, malloc, warn_unused_result));
/******************************************************************//** /******************************************************************//**
Construct the column specification part of the SQL string for selecting the Construct the column specification part of the SQL string for selecting the
indexed FTS columns for the given table. Adds the necessary bound indexed FTS columns for the given table. Adds the necessary bound
...@@ -597,15 +595,11 @@ fts_get_table_id( ...@@ -597,15 +595,11 @@ fts_get_table_id(
FTS_AUX_MIN_TABLE_ID_LENGTH bytes FTS_AUX_MIN_TABLE_ID_LENGTH bytes
long */ long */
MY_ATTRIBUTE((nonnull, warn_unused_result)); MY_ATTRIBUTE((nonnull, warn_unused_result));
/******************************************************************//** /** Construct the name of an internal FTS table for the given table.
Construct the prefix name of an FTS table. @param[in] fts_table metadata on fulltext-indexed table
@return own: table name, must be freed with mem_free() */ @param[in] dict_locked whether dict_sys->mutex is being held
UNIV_INTERN @return the prefix, must be freed with ut_free() */
char* UNIV_INTERN char* fts_get_table_name_prefix(const fts_table_t* fts_table)
fts_get_table_name_prefix(
/*======================*/
const fts_table_t*
fts_table) /*!< in: Auxiliary table type */
MY_ATTRIBUTE((nonnull, malloc, warn_unused_result)); MY_ATTRIBUTE((nonnull, malloc, warn_unused_result));
/******************************************************************//** /******************************************************************//**
Add node positions. */ 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