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