MDEV-12270 Port MySQL 8.0 Bug#21141390 REMOVE UNUSED FUNCTIONS AND CONVERT GLOBAL SYMBOLS TO STATIC
InnoDB defines some functions that are not called at all. Other functions are called, but only from the same compilation unit. Remove some function declarations and definitions, and add 'static' keywords. Some symbols must be kept for separately compiled tools, such as innochecksum.
This commit is contained in:
parent
4e1116b2c6
commit
97acc4a1c3
@ -51,6 +51,7 @@ Created 6/2/1994 Heikki Tuuri
|
||||
Checks if the page in the cursor can be merged with given page.
|
||||
If necessary, re-organize the merge_page.
|
||||
@return true if possible to merge. */
|
||||
static
|
||||
bool
|
||||
btr_can_merge_with_page(
|
||||
/*====================*/
|
||||
@ -5309,6 +5310,7 @@ node_ptr_fails:
|
||||
/**************************************************************//**
|
||||
Do an index level validation of spaital index tree.
|
||||
@return true if no error found */
|
||||
static
|
||||
bool
|
||||
btr_validate_spatial_index(
|
||||
/*=======================*/
|
||||
@ -5410,6 +5412,7 @@ btr_validate_index(
|
||||
Checks if the page in the cursor can be merged with given page.
|
||||
If necessary, re-organize the merge_page.
|
||||
@return true if possible to merge. */
|
||||
static
|
||||
bool
|
||||
btr_can_merge_with_page(
|
||||
/*====================*/
|
||||
|
@ -461,6 +461,7 @@ alphabetical position of the cursor is guaranteed to be sensible on
|
||||
return, but it may happen that the cursor is not positioned on the last
|
||||
record of any page, because the structure of the tree may have changed
|
||||
during the time when the cursor had no latches. */
|
||||
static
|
||||
void
|
||||
btr_pcur_move_backward_from_page(
|
||||
/*=============================*/
|
||||
|
@ -1833,6 +1833,7 @@ buf_pool_set_sizes(void)
|
||||
/********************************************************************//**
|
||||
Initialize a buffer pool instance.
|
||||
@return DB_SUCCESS if all goes well. */
|
||||
static
|
||||
ulint
|
||||
buf_pool_init_instance(
|
||||
/*===================*/
|
||||
@ -2692,6 +2693,7 @@ buf_pool_resize_chunk_make_null(buf_chunk_t** new_chunks)
|
||||
|
||||
/** Resize the buffer pool based on srv_buf_pool_size from
|
||||
srv_buf_pool_old_size. */
|
||||
static
|
||||
void
|
||||
buf_pool_resize()
|
||||
{
|
||||
@ -3448,6 +3450,7 @@ hash_lock and reacquire it.
|
||||
@param[in] page_id page id
|
||||
@param[in,out] hash_lock hash_lock currently latched
|
||||
@return NULL if watch set, block if the page is in the buffer pool */
|
||||
static
|
||||
buf_page_t*
|
||||
buf_pool_watch_set(
|
||||
const page_id_t& page_id,
|
||||
@ -6283,6 +6286,17 @@ buf_all_freed_instance(
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
/** Refreshes the statistics used to print per-second averages.
|
||||
@param[in,out] buf_pool buffer pool instance */
|
||||
static
|
||||
void
|
||||
buf_refresh_io_stats(
|
||||
buf_pool_t* buf_pool)
|
||||
{
|
||||
buf_pool->last_printout_time = ut_time();
|
||||
buf_pool->old_stat = buf_pool->stat;
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
Invalidates file pages in one buffer pool instance */
|
||||
static
|
||||
@ -6726,6 +6740,7 @@ buf_print(void)
|
||||
/*********************************************************************//**
|
||||
Returns the number of latched pages in the buffer pool.
|
||||
@return number of latched pages */
|
||||
static
|
||||
ulint
|
||||
buf_get_latched_pages_number_instance(
|
||||
/*==================================*/
|
||||
@ -7070,6 +7085,7 @@ buf_stats_get_pool_info(
|
||||
|
||||
/*********************************************************************//**
|
||||
Prints info of the buffer i/o. */
|
||||
static
|
||||
void
|
||||
buf_print_io_instance(
|
||||
/*==================*/
|
||||
@ -7223,17 +7239,6 @@ buf_print_io(
|
||||
ut_free(pool_info);
|
||||
}
|
||||
|
||||
/**********************************************************************//**
|
||||
Refreshes the statistics used to print per-second averages. */
|
||||
void
|
||||
buf_refresh_io_stats(
|
||||
/*=================*/
|
||||
buf_pool_t* buf_pool) /*!< in: buffer pool instance */
|
||||
{
|
||||
buf_pool->last_printout_time = ut_time();
|
||||
buf_pool->old_stat = buf_pool->stat;
|
||||
}
|
||||
|
||||
/**********************************************************************//**
|
||||
Refreshes the statistics used to print per-second averages. */
|
||||
void
|
||||
|
@ -2313,29 +2313,6 @@ buf_flush_LRU_list(
|
||||
|
||||
return(n.flushed);
|
||||
}
|
||||
/*********************************************************************//**
|
||||
Clears up tail of the LRU lists:
|
||||
* Put replaceable pages at the tail of LRU to the free list
|
||||
* Flush dirty pages at the tail of LRU to the disk
|
||||
The depth to which we scan each buffer pool is controlled by dynamic
|
||||
config parameter innodb_LRU_scan_depth.
|
||||
@return total pages flushed */
|
||||
ulint
|
||||
buf_flush_LRU_lists(void)
|
||||
/*=====================*/
|
||||
{
|
||||
ulint n_flushed = 0;
|
||||
for (ulint i = 0; i < srv_buf_pool_instances; i++) {
|
||||
|
||||
n_flushed += buf_flush_LRU_list(buf_pool_from_array(i));
|
||||
}
|
||||
|
||||
if (n_flushed) {
|
||||
buf_flush_stats(0, n_flushed);
|
||||
}
|
||||
|
||||
return(n_flushed);
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
Wait for any possible LRU flushes that are in progress to end. */
|
||||
@ -3715,6 +3692,7 @@ buf_pool_get_dirty_pages_count(
|
||||
/******************************************************************//**
|
||||
Check if there are any dirty pages that belong to a space id in the flush list.
|
||||
@return number of dirty pages present in all the buffer pools */
|
||||
static
|
||||
ulint
|
||||
buf_flush_get_dirty_pages_count(
|
||||
/*============================*/
|
||||
|
@ -1648,55 +1648,6 @@ buf_unzip_LRU_add_block(
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************//**
|
||||
Adds a block to the LRU list end. Please make sure that the page_size is
|
||||
already set when invoking the function, so that we can get correct
|
||||
page_size from the buffer page when adding a block into LRU */
|
||||
static
|
||||
void
|
||||
buf_LRU_add_block_to_end_low(
|
||||
/*=========================*/
|
||||
buf_page_t* bpage) /*!< in: control block */
|
||||
{
|
||||
buf_pool_t* buf_pool = buf_pool_from_bpage(bpage);
|
||||
|
||||
ut_ad(buf_pool_mutex_own(buf_pool));
|
||||
|
||||
ut_a(buf_page_in_file(bpage));
|
||||
|
||||
ut_ad(!bpage->in_LRU_list);
|
||||
UT_LIST_ADD_LAST(buf_pool->LRU, bpage);
|
||||
ut_d(bpage->in_LRU_list = TRUE);
|
||||
|
||||
incr_LRU_size_in_bytes(bpage, buf_pool);
|
||||
|
||||
if (UT_LIST_GET_LEN(buf_pool->LRU) > BUF_LRU_OLD_MIN_LEN) {
|
||||
|
||||
ut_ad(buf_pool->LRU_old);
|
||||
|
||||
/* Adjust the length of the old block list if necessary */
|
||||
|
||||
buf_page_set_old(bpage, TRUE);
|
||||
buf_pool->LRU_old_len++;
|
||||
buf_LRU_old_adjust_len(buf_pool);
|
||||
|
||||
} else if (UT_LIST_GET_LEN(buf_pool->LRU) == BUF_LRU_OLD_MIN_LEN) {
|
||||
|
||||
/* The LRU list is now long enough for LRU_old to become
|
||||
defined: init it */
|
||||
|
||||
buf_LRU_old_init(buf_pool);
|
||||
} else {
|
||||
buf_page_set_old(bpage, buf_pool->LRU_old != NULL);
|
||||
}
|
||||
|
||||
/* If this is a zipped block with decompressed frame as well
|
||||
then put it on the unzip_LRU list */
|
||||
if (buf_page_belongs_to_unzip_LRU(bpage)) {
|
||||
buf_unzip_LRU_add_block((buf_block_t*) bpage, TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************//**
|
||||
Adds a block to the LRU list. Please make sure that the page_size is
|
||||
already set when invoking the function, so that we can get correct
|
||||
@ -1805,17 +1756,6 @@ buf_LRU_make_block_young(
|
||||
buf_LRU_add_block_low(bpage, FALSE);
|
||||
}
|
||||
|
||||
/******************************************************************//**
|
||||
Moves a block to the end of the LRU list. */
|
||||
void
|
||||
buf_LRU_make_block_old(
|
||||
/*===================*/
|
||||
buf_page_t* bpage) /*!< in: control block */
|
||||
{
|
||||
buf_LRU_remove_block(bpage);
|
||||
buf_LRU_add_block_to_end_low(bpage);
|
||||
}
|
||||
|
||||
/******************************************************************//**
|
||||
Try to free a block. If bpage is a descriptor of a compressed-only
|
||||
page, the descriptor object will be freed as well.
|
||||
@ -2702,6 +2642,7 @@ buf_LRU_validate(void)
|
||||
#if defined UNIV_DEBUG_PRINT || defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
|
||||
/**********************************************************************//**
|
||||
Prints the LRU list for one buffer pool instance. */
|
||||
static
|
||||
void
|
||||
buf_LRU_print_instance(
|
||||
/*===================*/
|
||||
|
@ -121,6 +121,7 @@ dfield_check_typed_no_assert(
|
||||
/**********************************************************//**
|
||||
Checks that a data tuple is typed.
|
||||
@return TRUE if ok */
|
||||
static
|
||||
ibool
|
||||
dtuple_check_typed_no_assert(
|
||||
/*=========================*/
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 1996, 2014, Oracle and/or its affiliates. All Rights Reserved.
|
||||
Copyright (c) 1996, 2015, Oracle and/or its affiliates. All Rights Reserved.
|
||||
Copyright (c) 2017, MariaDB Corporation.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under
|
||||
@ -157,12 +157,11 @@ dtype_validate(
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
Prints a data type structure. */
|
||||
#ifdef UNIV_DEBUG
|
||||
/** Print a data type structure.
|
||||
@param[in] type data type */
|
||||
void
|
||||
dtype_print(
|
||||
/*========*/
|
||||
const dtype_t* type) /*!< in: type */
|
||||
dtype_print(const dtype_t* type)
|
||||
{
|
||||
ulint mtype;
|
||||
ulint prtype;
|
||||
@ -274,3 +273,4 @@ dtype_print(
|
||||
|
||||
fprintf(stderr, " len %lu", (ulong) len);
|
||||
}
|
||||
#endif /* UNIV_DEBUG */
|
||||
|
@ -788,6 +788,7 @@ dict_table_autoinc_lock(
|
||||
|
||||
/** Acquire the zip_pad_mutex latch.
|
||||
@param[in,out] index the index whose zip_pad_mutex to acquire.*/
|
||||
static
|
||||
void
|
||||
dict_index_zip_pad_lock(
|
||||
dict_index_t* index)
|
||||
@ -5388,23 +5389,6 @@ try_find_index:
|
||||
goto loop;
|
||||
}
|
||||
|
||||
/**************************************************************************
|
||||
Determines whether a string starts with the specified keyword.
|
||||
@return TRUE if str starts with keyword */
|
||||
ibool
|
||||
dict_str_starts_with_keyword(
|
||||
/*=========================*/
|
||||
THD* thd, /*!< in: MySQL thread handle */
|
||||
const char* str, /*!< in: string to scan for keyword */
|
||||
const char* keyword) /*!< in: keyword to look for */
|
||||
{
|
||||
CHARSET_INFO* cs = innobase_get_charset(thd);
|
||||
ibool success;
|
||||
|
||||
dict_accept(cs, str, keyword, &success);
|
||||
return(success);
|
||||
}
|
||||
|
||||
/** Scans a table create SQL string and adds to the data dictionary
|
||||
the foreign key constraints declared in the string. This function
|
||||
should be called after the indexes for a table have been created.
|
||||
|
@ -89,22 +89,116 @@ dict_load_table_one(
|
||||
dict_err_ignore_t ignore_err,
|
||||
dict_names_t& fk_tables);
|
||||
|
||||
/** Loads a table definition from a SYS_TABLES record to dict_table_t.
|
||||
Does not load any columns or indexes.
|
||||
/** Load a table definition from a SYS_TABLES record to dict_table_t.
|
||||
Do not load any columns or indexes.
|
||||
@param[in] name Table name
|
||||
@param[in] rec SYS_TABLES record
|
||||
@param[out,own] table Table, or NULL
|
||||
@return error message, or NULL on success */
|
||||
@param[out,own] table table, or NULL
|
||||
@return error message
|
||||
@retval NULL on success */
|
||||
static
|
||||
const char*
|
||||
dict_load_table_low(
|
||||
table_name_t& name,
|
||||
const rec_t* rec,
|
||||
dict_table_t** table);
|
||||
dict_load_table_low(table_name_t& name, const rec_t* rec, dict_table_t** table)
|
||||
MY_ATTRIBUTE((nonnull, warn_unused_result));
|
||||
|
||||
/** Load an index definition from a SYS_INDEXES record to dict_index_t.
|
||||
If allocate=TRUE, we will create a dict_index_t structure and fill it
|
||||
accordingly. If allocated=FALSE, the dict_index_t will be supplied by
|
||||
the caller and filled with information read from the record.
|
||||
@return error message
|
||||
@retval NULL on success */
|
||||
static
|
||||
const char*
|
||||
dict_load_index_low(
|
||||
byte* table_id, /*!< in/out: table id (8 bytes),
|
||||
an "in" value if allocate=TRUE
|
||||
and "out" when allocate=FALSE */
|
||||
const char* table_name, /*!< in: table name */
|
||||
mem_heap_t* heap, /*!< in/out: temporary memory heap */
|
||||
const rec_t* rec, /*!< in: SYS_INDEXES record */
|
||||
ibool allocate, /*!< in: TRUE=allocate *index,
|
||||
FALSE=fill in a pre-allocated
|
||||
*index */
|
||||
dict_index_t** index); /*!< out,own: index, or NULL */
|
||||
|
||||
/** Load a table column definition from a SYS_COLUMNS record to dict_table_t.
|
||||
@return error message
|
||||
@retval NULL on success */
|
||||
static
|
||||
const char*
|
||||
dict_load_column_low(
|
||||
dict_table_t* table, /*!< in/out: table, could be NULL
|
||||
if we just populate a dict_column_t
|
||||
struct with information from
|
||||
a SYS_COLUMNS record */
|
||||
mem_heap_t* heap, /*!< in/out: memory heap
|
||||
for temporary storage */
|
||||
dict_col_t* column, /*!< out: dict_column_t to fill,
|
||||
or NULL if table != NULL */
|
||||
table_id_t* table_id, /*!< out: table id */
|
||||
const char** col_name, /*!< out: column name */
|
||||
const rec_t* rec, /*!< in: SYS_COLUMNS record */
|
||||
ulint* nth_v_col); /*!< out: if not NULL, this
|
||||
records the "n" of "nth" virtual
|
||||
column */
|
||||
|
||||
/** Load a virtual column "mapping" (to base columns) information
|
||||
from a SYS_VIRTUAL record
|
||||
@param[in,out] table table
|
||||
@param[in,out] heap memory heap
|
||||
@param[in,out] column mapped base column's dict_column_t
|
||||
@param[in,out] table_id table id
|
||||
@param[in,out] pos virtual column position
|
||||
@param[in,out] base_pos base column position
|
||||
@param[in] rec SYS_VIRTUAL record
|
||||
@return error message
|
||||
@retval NULL on success */
|
||||
static
|
||||
const char*
|
||||
dict_load_virtual_low(
|
||||
dict_table_t* table,
|
||||
mem_heap_t* heap,
|
||||
dict_col_t** column,
|
||||
table_id_t* table_id,
|
||||
ulint* pos,
|
||||
ulint* base_pos,
|
||||
const rec_t* rec);
|
||||
|
||||
/** Load an index field definition from a SYS_FIELDS record to dict_index_t.
|
||||
@return error message
|
||||
@retval NULL on success */
|
||||
static
|
||||
const char*
|
||||
dict_load_field_low(
|
||||
byte* index_id, /*!< in/out: index id (8 bytes)
|
||||
an "in" value if index != NULL
|
||||
and "out" if index == NULL */
|
||||
dict_index_t* index, /*!< in/out: index, could be NULL
|
||||
if we just populate a dict_field_t
|
||||
struct with information from
|
||||
a SYS_FIELDS record */
|
||||
dict_field_t* sys_field, /*!< out: dict_field_t to be
|
||||
filled */
|
||||
ulint* pos, /*!< out: Field position */
|
||||
byte* last_index_id, /*!< in: last index id */
|
||||
mem_heap_t* heap, /*!< in/out: memory heap
|
||||
for temporary storage */
|
||||
const rec_t* rec); /*!< in: SYS_FIELDS record */
|
||||
|
||||
/** Load a table definition from a SYS_TABLES record to dict_table_t.
|
||||
Do not load any columns or indexes.
|
||||
@param[in] name Table name
|
||||
@param[in] rec SYS_TABLES record
|
||||
@param[out,own] table table, or NULL
|
||||
@return error message
|
||||
@retval NULL on success */
|
||||
static
|
||||
const char*
|
||||
dict_load_table_low(table_name_t& name, const rec_t* rec, dict_table_t** table);
|
||||
|
||||
/* If this flag is TRUE, then we will load the cluster index's (and tables')
|
||||
metadata even if it is marked as "corrupted". */
|
||||
my_bool srv_load_corrupted = FALSE;
|
||||
my_bool srv_load_corrupted;
|
||||
|
||||
#ifdef UNIV_DEBUG
|
||||
/****************************************************************//**
|
||||
@ -424,6 +518,7 @@ dict_process_sys_virtual_rec(
|
||||
|
||||
return(err_msg);
|
||||
}
|
||||
|
||||
/********************************************************************//**
|
||||
This function parses a SYS_FIELDS record and populates a dict_field_t
|
||||
structure with the information from the record.
|
||||
@ -1312,13 +1407,12 @@ dict_check_tablespaces_and_store_max_id(
|
||||
/** Error message for a delete-marked record in dict_load_column_low() */
|
||||
static const char* dict_load_column_del = "delete-marked record in SYS_COLUMN";
|
||||
|
||||
/********************************************************************//**
|
||||
Loads a table column definition from a SYS_COLUMNS record to
|
||||
dict_table_t.
|
||||
@return error message, or NULL on success */
|
||||
/** Load a table column definition from a SYS_COLUMNS record to dict_table_t.
|
||||
@return error message
|
||||
@retval NULL on success */
|
||||
static
|
||||
const char*
|
||||
dict_load_column_low(
|
||||
/*=================*/
|
||||
dict_table_t* table, /*!< in/out: table, could be NULL
|
||||
if we just populate a dict_column_t
|
||||
struct with information from
|
||||
@ -1481,7 +1575,7 @@ err_len:
|
||||
/** Error message for a delete-marked record in dict_load_virtual_low() */
|
||||
static const char* dict_load_virtual_del = "delete-marked record in SYS_VIRTUAL";
|
||||
|
||||
/** Loads a virtual column "mapping" (to base columns) information
|
||||
/** Load a virtual column "mapping" (to base columns) information
|
||||
from a SYS_VIRTUAL record
|
||||
@param[in,out] table table
|
||||
@param[in,out] heap memory heap
|
||||
@ -1490,7 +1584,9 @@ from a SYS_VIRTUAL record
|
||||
@param[in,out] pos virtual column position
|
||||
@param[in,out] base_pos base column position
|
||||
@param[in] rec SYS_VIRTUAL record
|
||||
@return error message, or NULL on success */
|
||||
@return error message
|
||||
@retval NULL on success */
|
||||
static
|
||||
const char*
|
||||
dict_load_virtual_low(
|
||||
dict_table_t* table,
|
||||
@ -1566,6 +1662,7 @@ err_len:
|
||||
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
/********************************************************************//**
|
||||
Loads definitions for table columns. */
|
||||
static
|
||||
@ -1795,13 +1892,12 @@ dict_load_virtual(
|
||||
/** Error message for a delete-marked record in dict_load_field_low() */
|
||||
static const char* dict_load_field_del = "delete-marked record in SYS_FIELDS";
|
||||
|
||||
/********************************************************************//**
|
||||
Loads an index field definition from a SYS_FIELDS record to
|
||||
dict_index_t.
|
||||
@return error message, or NULL on success */
|
||||
/** Load an index field definition from a SYS_FIELDS record to dict_index_t.
|
||||
@return error message
|
||||
@retval NULL on success */
|
||||
static
|
||||
const char*
|
||||
dict_load_field_low(
|
||||
/*================*/
|
||||
byte* index_id, /*!< in/out: index id (8 bytes)
|
||||
an "in" value if index != NULL
|
||||
and "out" if index == NULL */
|
||||
@ -1996,15 +2092,15 @@ static const char* dict_load_index_del = "delete-marked record in SYS_INDEXES";
|
||||
/** Error message for table->id mismatch in dict_load_index_low() */
|
||||
static const char* dict_load_index_id_err = "SYS_INDEXES.TABLE_ID mismatch";
|
||||
|
||||
/********************************************************************//**
|
||||
Loads an index definition from a SYS_INDEXES record to dict_index_t.
|
||||
/** Load an index definition from a SYS_INDEXES record to dict_index_t.
|
||||
If allocate=TRUE, we will create a dict_index_t structure and fill it
|
||||
accordingly. If allocated=FALSE, the dict_index_t will be supplied by
|
||||
the caller and filled with information read from the record. @return
|
||||
error message, or NULL on success */
|
||||
the caller and filled with information read from the record.
|
||||
@return error message
|
||||
@retval NULL on success */
|
||||
static
|
||||
const char*
|
||||
dict_load_index_low(
|
||||
/*================*/
|
||||
byte* table_id, /*!< in/out: table id (8 bytes),
|
||||
an "in" value if allocate=TRUE
|
||||
and "out" when allocate=FALSE */
|
||||
@ -2419,18 +2515,16 @@ func_exit:
|
||||
return(error);
|
||||
}
|
||||
|
||||
/** Loads a table definition from a SYS_TABLES record to dict_table_t.
|
||||
Does not load any columns or indexes.
|
||||
/** Load a table definition from a SYS_TABLES record to dict_table_t.
|
||||
Do not load any columns or indexes.
|
||||
@param[in] name Table name
|
||||
@param[in] rec SYS_TABLES record
|
||||
@param[out,own] table table, or NULL
|
||||
@return error message, or NULL on success */
|
||||
@return error message
|
||||
@retval NULL on success */
|
||||
static
|
||||
const char*
|
||||
dict_load_table_low(
|
||||
table_name_t& name,
|
||||
const rec_t* rec,
|
||||
dict_table_t** table)
|
||||
dict_load_table_low(table_name_t& name, const rec_t* rec, dict_table_t** table)
|
||||
{
|
||||
table_id_t table_id;
|
||||
ulint space_id;
|
||||
@ -2468,6 +2562,7 @@ table->data_dir_path and replace the 'databasename/tablename.ibd'
|
||||
portion with 'tablename'.
|
||||
This allows SHOW CREATE TABLE to return the correct DATA DIRECTORY path.
|
||||
Make this data directory path only if it has not yet been saved. */
|
||||
static
|
||||
void
|
||||
dict_save_data_dir_path(
|
||||
/*====================*/
|
||||
|
@ -925,6 +925,7 @@ is relatively quick and is used to calculate transient statistics that
|
||||
are not saved on disk.
|
||||
This was the only way to calculate statistics before the
|
||||
Persistent Statistics feature was introduced. */
|
||||
static
|
||||
void
|
||||
dict_stats_update_transient(
|
||||
/*========================*/
|
||||
|
@ -494,6 +494,7 @@ try to add new extents to the space free list
|
||||
@param[in] page_size page size
|
||||
@param[in,out] mtr mini-transaction
|
||||
@return the extent descriptor */
|
||||
MY_ATTRIBUTE((warn_unused_result))
|
||||
static
|
||||
xdes_t*
|
||||
xdes_get_descriptor(
|
||||
@ -3528,126 +3529,6 @@ fseg_get_first_extent(
|
||||
: xdes_lst_get_descriptor(space, page_size, first, mtr));
|
||||
}
|
||||
|
||||
#ifdef UNIV_DEBUG
|
||||
/*******************************************************************//**
|
||||
Validates a segment.
|
||||
@return TRUE if ok */
|
||||
static
|
||||
ibool
|
||||
fseg_validate_low(
|
||||
/*==============*/
|
||||
fseg_inode_t* inode, /*!< in: segment inode */
|
||||
mtr_t* mtr2) /*!< in/out: mini-transaction */
|
||||
{
|
||||
ulint space_id;
|
||||
ib_id_t seg_id;
|
||||
mtr_t mtr;
|
||||
fil_addr_t node_addr;
|
||||
ulint n_used = 0;
|
||||
ulint n_used2 = 0;
|
||||
|
||||
ut_ad(mtr_memo_contains_page(mtr2, inode, MTR_MEMO_PAGE_SX_FIX));
|
||||
ut_ad(mach_read_from_4(inode + FSEG_MAGIC_N) == FSEG_MAGIC_N_VALUE);
|
||||
|
||||
space_id = page_get_space_id(page_align(inode));
|
||||
|
||||
seg_id = mach_read_from_8(inode + FSEG_ID);
|
||||
n_used = mtr_read_ulint(inode + FSEG_NOT_FULL_N_USED,
|
||||
MLOG_4BYTES, mtr2);
|
||||
flst_validate(inode + FSEG_FREE, mtr2);
|
||||
flst_validate(inode + FSEG_NOT_FULL, mtr2);
|
||||
flst_validate(inode + FSEG_FULL, mtr2);
|
||||
|
||||
/* Validate FSEG_FREE list */
|
||||
node_addr = flst_get_first(inode + FSEG_FREE, mtr2);
|
||||
|
||||
while (!fil_addr_is_null(node_addr)) {
|
||||
mtr_start(&mtr);
|
||||
const fil_space_t* space = mtr_x_lock_space(
|
||||
space_id, &mtr);
|
||||
const xdes_t* descr = xdes_lst_get_descriptor(
|
||||
space, page_size_t(space->flags), node_addr, &mtr);
|
||||
|
||||
ut_a(xdes_get_n_used(descr, &mtr) == 0);
|
||||
ut_a(xdes_get_state(descr, &mtr) == XDES_FSEG);
|
||||
ut_a(mach_read_from_8(descr + XDES_ID) == seg_id);
|
||||
|
||||
node_addr = flst_get_next_addr(descr + XDES_FLST_NODE, &mtr);
|
||||
mtr_commit(&mtr);
|
||||
}
|
||||
|
||||
/* Validate FSEG_NOT_FULL list */
|
||||
|
||||
node_addr = flst_get_first(inode + FSEG_NOT_FULL, mtr2);
|
||||
|
||||
while (!fil_addr_is_null(node_addr)) {
|
||||
mtr_start(&mtr);
|
||||
const fil_space_t* space = mtr_x_lock_space(
|
||||
space_id, &mtr);
|
||||
const xdes_t* descr = xdes_lst_get_descriptor(
|
||||
space, page_size_t(space->flags), node_addr, &mtr);
|
||||
|
||||
ut_a(xdes_get_n_used(descr, &mtr) > 0);
|
||||
ut_a(xdes_get_n_used(descr, &mtr) < FSP_EXTENT_SIZE);
|
||||
ut_a(xdes_get_state(descr, &mtr) == XDES_FSEG);
|
||||
ut_a(mach_read_from_8(descr + XDES_ID) == seg_id);
|
||||
|
||||
n_used2 += xdes_get_n_used(descr, &mtr);
|
||||
|
||||
node_addr = flst_get_next_addr(descr + XDES_FLST_NODE, &mtr);
|
||||
mtr_commit(&mtr);
|
||||
}
|
||||
|
||||
/* Validate FSEG_FULL list */
|
||||
|
||||
node_addr = flst_get_first(inode + FSEG_FULL, mtr2);
|
||||
|
||||
while (!fil_addr_is_null(node_addr)) {
|
||||
mtr_start(&mtr);
|
||||
const fil_space_t* space = mtr_x_lock_space(
|
||||
space_id, &mtr);
|
||||
const xdes_t* descr = xdes_lst_get_descriptor(
|
||||
space, page_size_t(space->flags), node_addr, &mtr);
|
||||
|
||||
ut_a(xdes_get_n_used(descr, &mtr) == FSP_EXTENT_SIZE);
|
||||
ut_a(xdes_get_state(descr, &mtr) == XDES_FSEG);
|
||||
ut_a(mach_read_from_8(descr + XDES_ID) == seg_id);
|
||||
|
||||
node_addr = flst_get_next_addr(descr + XDES_FLST_NODE, &mtr);
|
||||
mtr_commit(&mtr);
|
||||
}
|
||||
|
||||
ut_a(n_used == n_used2);
|
||||
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
/*******************************************************************//**
|
||||
Validates a segment.
|
||||
@return TRUE if ok */
|
||||
ibool
|
||||
fseg_validate(
|
||||
/*==========*/
|
||||
fseg_header_t* header, /*!< in: segment header */
|
||||
mtr_t* mtr) /*!< in/out: mini-transaction */
|
||||
{
|
||||
fseg_inode_t* inode;
|
||||
ibool ret;
|
||||
ulint space_id;
|
||||
|
||||
space_id = page_get_space_id(page_align(header));
|
||||
|
||||
const fil_space_t* space = mtr_x_lock_space(space_id, mtr);
|
||||
const page_size_t page_size(space->flags);
|
||||
|
||||
inode = fseg_inode_get(header, space_id, page_size, mtr);
|
||||
|
||||
ret = fseg_validate_low(inode, mtr);
|
||||
|
||||
return(ret);
|
||||
}
|
||||
#endif /* UNIV_DEBUG */
|
||||
|
||||
#ifdef UNIV_BTR_PRINT
|
||||
/*******************************************************************//**
|
||||
Writes info of a segment. */
|
||||
|
@ -55,6 +55,23 @@ fts_ast_node_create(void)
|
||||
return(node);
|
||||
}
|
||||
|
||||
/** Track node allocations, in case there is an error during parsing. */
|
||||
static
|
||||
void
|
||||
fts_ast_state_add_node(
|
||||
fts_ast_state_t*state, /*!< in: ast instance */
|
||||
fts_ast_node_t* node) /*!< in: node to add to ast */
|
||||
{
|
||||
if (!state->list.head) {
|
||||
ut_a(!state->list.tail);
|
||||
|
||||
state->list.head = state->list.tail = node;
|
||||
} else {
|
||||
state->list.tail->next_alloc = node;
|
||||
state->list.tail = node;
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************//**
|
||||
Create a operator fts_ast_node_t.
|
||||
@return new node */
|
||||
@ -379,25 +396,6 @@ fts_ast_add_node(
|
||||
return(node);
|
||||
}
|
||||
|
||||
/******************************************************************//**
|
||||
For tracking node allocations, in case there is an error during
|
||||
parsing. */
|
||||
void
|
||||
fts_ast_state_add_node(
|
||||
/*===================*/
|
||||
fts_ast_state_t*state, /*!< in: ast instance */
|
||||
fts_ast_node_t* node) /*!< in: node to add to ast */
|
||||
{
|
||||
if (!state->list.head) {
|
||||
ut_a(!state->list.tail);
|
||||
|
||||
state->list.head = state->list.tail = node;
|
||||
} else {
|
||||
state->list.tail->next_alloc = node;
|
||||
state->list.tail = node;
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************//**
|
||||
Set the wildcard attribute of a term. */
|
||||
void
|
||||
@ -469,6 +467,20 @@ fts_ast_state_free(
|
||||
state->root = state->list.head = state->list.tail = NULL;
|
||||
}
|
||||
|
||||
/** Print the ast string
|
||||
@param[in] str string to print */
|
||||
static
|
||||
void
|
||||
fts_ast_string_print(
|
||||
const fts_ast_string_t* ast_str)
|
||||
{
|
||||
for (ulint i = 0; i < ast_str->len; ++i) {
|
||||
printf("%c", ast_str->str[i]);
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
/******************************************************************//**
|
||||
Print an ast node recursively. */
|
||||
static
|
||||
@ -770,48 +782,7 @@ fts_ast_string_to_ul(
|
||||
NULL, base));
|
||||
}
|
||||
|
||||
/**
|
||||
Print the ast string
|
||||
@param[in] str string to print */
|
||||
void
|
||||
fts_ast_string_print(
|
||||
const fts_ast_string_t* ast_str)
|
||||
{
|
||||
for (ulint i = 0; i < ast_str->len; ++i) {
|
||||
printf("%c", ast_str->str[i]);
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
#ifdef UNIV_DEBUG
|
||||
const char*
|
||||
fts_ast_oper_name_get(fts_ast_oper_t oper)
|
||||
{
|
||||
switch(oper) {
|
||||
case FTS_NONE:
|
||||
return("FTS_NONE");
|
||||
case FTS_IGNORE:
|
||||
return("FTS_IGNORE");
|
||||
case FTS_EXIST:
|
||||
return("FTS_EXIST");
|
||||
case FTS_NEGATE:
|
||||
return("FTS_NEGATE");
|
||||
case FTS_INCR_RATING:
|
||||
return("FTS_INCR_RATING");
|
||||
case FTS_DECR_RATING:
|
||||
return("FTS_DECR_RATING");
|
||||
case FTS_DISTANCE:
|
||||
return("FTS_DISTANCE");
|
||||
case FTS_IGNORE_SKIP:
|
||||
return("FTS_IGNORE_SKIP");
|
||||
case FTS_EXIST_SKIP:
|
||||
return("FTS_EXIST_SKIP");
|
||||
}
|
||||
ut_ad(0);
|
||||
return("FTS_UNKNOWN");
|
||||
}
|
||||
|
||||
const char*
|
||||
fts_ast_node_type_get(fts_ast_type_t type)
|
||||
{
|
||||
|
@ -291,6 +291,7 @@ fts_config_set_index_value(
|
||||
return(error);
|
||||
}
|
||||
|
||||
#ifdef FTS_OPTIMIZE_DEBUG
|
||||
/******************************************************************//**
|
||||
Get an ulint value from the config table.
|
||||
@return DB_SUCCESS if all OK else error code */
|
||||
@ -362,6 +363,7 @@ fts_config_set_index_ulint(
|
||||
|
||||
return(error);
|
||||
}
|
||||
#endif /* FTS_OPTIMIZE_DEBUG */
|
||||
|
||||
/******************************************************************//**
|
||||
Get an ulint value from the config table.
|
||||
@ -434,118 +436,3 @@ fts_config_set_ulint(
|
||||
return(error);
|
||||
}
|
||||
|
||||
/******************************************************************//**
|
||||
Increment the value in the config table for column name.
|
||||
@return DB_SUCCESS or error code */
|
||||
dberr_t
|
||||
fts_config_increment_value(
|
||||
/*=======================*/
|
||||
trx_t* trx, /*!< transaction */
|
||||
fts_table_t* fts_table, /*!< in: the indexed
|
||||
FTS table */
|
||||
const char* name, /*!< in: increment config value
|
||||
for this parameter name */
|
||||
ulint delta) /*!< in: increment by this
|
||||
much */
|
||||
{
|
||||
dberr_t error;
|
||||
fts_string_t 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.*/
|
||||
value.f_len = FTS_MAX_CONFIG_VALUE_LEN;
|
||||
value.f_str = static_cast<byte*>(ut_malloc_nokey(value.f_len + 1));
|
||||
|
||||
*value.f_str = '\0';
|
||||
|
||||
pars_info_bind_varchar_literal(info, "name", (byte*) name, name_len);
|
||||
|
||||
pars_info_bind_function(
|
||||
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 $config_table"
|
||||
" WHERE key = :name FOR UPDATE;\n"
|
||||
"BEGIN\n"
|
||||
""
|
||||
"OPEN c;\n"
|
||||
"WHILE 1 = 1 LOOP\n"
|
||||
" FETCH c INTO my_func();\n"
|
||||
" IF c % NOTFOUND THEN\n"
|
||||
" EXIT;\n"
|
||||
" END IF;\n"
|
||||
"END LOOP;\n"
|
||||
"CLOSE c;");
|
||||
|
||||
trx->op_info = "read FTS config value";
|
||||
|
||||
error = fts_eval_sql(trx, graph);
|
||||
|
||||
fts_que_graph_free_check_lock(fts_table, NULL, graph);
|
||||
|
||||
if (UNIV_UNLIKELY(error == DB_SUCCESS)) {
|
||||
ulint int_value;
|
||||
|
||||
int_value = strtoul((char*) value.f_str, NULL, 10);
|
||||
|
||||
int_value += delta;
|
||||
|
||||
ut_a(FTS_MAX_CONFIG_VALUE_LEN > FTS_MAX_INT_LEN);
|
||||
|
||||
value.f_len = my_snprintf(
|
||||
(char*) value.f_str, FTS_MAX_INT_LEN, "%lu", int_value);
|
||||
|
||||
fts_config_set_value(trx, fts_table, name, &value);
|
||||
}
|
||||
|
||||
if (UNIV_UNLIKELY(error != DB_SUCCESS)) {
|
||||
|
||||
ib::error() << "(" << ut_strerr(error) << ") while"
|
||||
" incrementing " << name << ".";
|
||||
}
|
||||
|
||||
ut_free(value.f_str);
|
||||
|
||||
return(error);
|
||||
}
|
||||
|
||||
/******************************************************************//**
|
||||
Increment the per index value in the config table for column name.
|
||||
@return DB_SUCCESS or error code */
|
||||
dberr_t
|
||||
fts_config_increment_index_value(
|
||||
/*=============================*/
|
||||
trx_t* trx, /*!< transaction */
|
||||
dict_index_t* index, /*!< in: FTS index */
|
||||
const char* param, /*!< in: increment config value
|
||||
for this parameter name */
|
||||
ulint delta) /*!< in: increment by this
|
||||
much */
|
||||
{
|
||||
char* name;
|
||||
dberr_t error;
|
||||
fts_table_t fts_table;
|
||||
|
||||
FTS_INIT_FTS_TABLE(&fts_table, "CONFIG", FTS_COMMON_TABLE,
|
||||
index->table);
|
||||
|
||||
/* We are responsible for free'ing name. */
|
||||
name = fts_config_create_index_param_name(param, index);
|
||||
|
||||
error = fts_config_increment_value(trx, &fts_table, name, delta);
|
||||
|
||||
ut_free(name);
|
||||
|
||||
return(error);
|
||||
}
|
||||
|
||||
|
@ -149,20 +149,6 @@ struct fts_aux_table_t {
|
||||
char* name; /*!< Name of the table */
|
||||
};
|
||||
|
||||
#ifdef FTS_DOC_STATS_DEBUG
|
||||
/** Template for creating the FTS auxiliary index specific tables. This is
|
||||
mainly designed for the statistics work in the future */
|
||||
static const char* fts_create_index_tables_sql = {
|
||||
"BEGIN\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 $doc_id_table(doc_id);\n"
|
||||
};
|
||||
#endif
|
||||
|
||||
/** FTS auxiliary table suffixes that are common to all FT indexes. */
|
||||
const char* fts_common_tables[] = {
|
||||
"BEING_DELETED",
|
||||
@ -255,22 +241,6 @@ fts_add_doc_by_id(
|
||||
doc_id_t doc_id, /*!< in: doc id */
|
||||
ib_vector_t* fts_indexes MY_ATTRIBUTE((unused)));
|
||||
/*!< in: affected fts indexes */
|
||||
#ifdef FTS_DOC_STATS_DEBUG
|
||||
/****************************************************************//**
|
||||
Check whether a particular word (term) exists in the FTS index.
|
||||
@return DB_SUCCESS if all went fine */
|
||||
static
|
||||
dberr_t
|
||||
fts_is_word_in_index(
|
||||
/*=================*/
|
||||
trx_t* trx, /*!< in: FTS query state */
|
||||
que_t** graph, /*!< out: Query graph */
|
||||
fts_table_t* fts_table, /*!< in: table instance */
|
||||
const fts_string_t* word, /*!< in: the word to check */
|
||||
ibool* found) /*!< out: TRUE if exists */
|
||||
MY_ATTRIBUTE((nonnull, warn_unused_result));
|
||||
#endif /* FTS_DOC_STATS_DEBUG */
|
||||
|
||||
/******************************************************************//**
|
||||
Update the last document id. This function could create a new
|
||||
transaction to update the last document id.
|
||||
@ -285,6 +255,62 @@ fts_update_sync_doc_id(
|
||||
trx_t* trx) /*!< in: update trx, or NULL */
|
||||
MY_ATTRIBUTE((nonnull(1)));
|
||||
|
||||
/** Tokenize a document.
|
||||
@param[in,out] doc document to tokenize
|
||||
@param[out] result tokenization result
|
||||
@param[in] parser pluggable parser */
|
||||
static
|
||||
void
|
||||
fts_tokenize_document(
|
||||
fts_doc_t* doc,
|
||||
fts_doc_t* result,
|
||||
st_mysql_ftparser* parser);
|
||||
|
||||
/** Continue to tokenize a document.
|
||||
@param[in,out] doc document to tokenize
|
||||
@param[in] add_pos add this position to all tokens from this tokenization
|
||||
@param[out] result tokenization result
|
||||
@param[in] parser pluggable parser */
|
||||
static
|
||||
void
|
||||
fts_tokenize_document_next(
|
||||
fts_doc_t* doc,
|
||||
ulint add_pos,
|
||||
fts_doc_t* result,
|
||||
st_mysql_ftparser* parser);
|
||||
|
||||
/** Create the vector of fts_get_doc_t instances.
|
||||
@param[in,out] cache fts cache
|
||||
@return vector of fts_get_doc_t instances */
|
||||
static
|
||||
ib_vector_t*
|
||||
fts_get_docs_create(
|
||||
fts_cache_t* cache);
|
||||
|
||||
/** Free the FTS cache.
|
||||
@param[in,out] cache to be freed */
|
||||
static
|
||||
void
|
||||
fts_cache_destroy(fts_cache_t* cache)
|
||||
{
|
||||
rw_lock_free(&cache->lock);
|
||||
rw_lock_free(&cache->init_lock);
|
||||
mutex_free(&cache->optimize_lock);
|
||||
mutex_free(&cache->deleted_lock);
|
||||
mutex_free(&cache->doc_id_lock);
|
||||
os_event_destroy(cache->sync->event);
|
||||
|
||||
if (cache->stopword_info.cached_stopword) {
|
||||
rbt_free(cache->stopword_info.cached_stopword);
|
||||
}
|
||||
|
||||
if (cache->sync_heap->arg) {
|
||||
mem_heap_free(static_cast<mem_heap_t*>(cache->sync_heap->arg));
|
||||
}
|
||||
|
||||
mem_heap_free(cache->cache_heap);
|
||||
}
|
||||
|
||||
/** Get a character set based on precise type.
|
||||
@param prtype precise type
|
||||
@return the corresponding character set */
|
||||
@ -1153,31 +1179,6 @@ fts_get_index_get_doc(
|
||||
}
|
||||
#endif
|
||||
|
||||
/**********************************************************************//**
|
||||
Free the FTS cache. */
|
||||
void
|
||||
fts_cache_destroy(
|
||||
/*==============*/
|
||||
fts_cache_t* cache) /*!< in: cache*/
|
||||
{
|
||||
rw_lock_free(&cache->lock);
|
||||
rw_lock_free(&cache->init_lock);
|
||||
mutex_free(&cache->optimize_lock);
|
||||
mutex_free(&cache->deleted_lock);
|
||||
mutex_free(&cache->doc_id_lock);
|
||||
os_event_destroy(cache->sync->event);
|
||||
|
||||
if (cache->stopword_info.cached_stopword) {
|
||||
rbt_free(cache->stopword_info.cached_stopword);
|
||||
}
|
||||
|
||||
if (cache->sync_heap->arg) {
|
||||
mem_heap_free(static_cast<mem_heap_t*>(cache->sync_heap->arg));
|
||||
}
|
||||
|
||||
mem_heap_free(cache->cache_heap);
|
||||
}
|
||||
|
||||
/**********************************************************************//**
|
||||
Find an existing word, or if not found, create one and return it.
|
||||
@return specified word token */
|
||||
@ -1608,6 +1609,7 @@ fts_drop_common_tables(
|
||||
Since we do a horizontal split on the index table, we need to drop
|
||||
all the split tables.
|
||||
@return DB_SUCCESS or error code */
|
||||
static
|
||||
dberr_t
|
||||
fts_drop_index_split_tables(
|
||||
/*========================*/
|
||||
@ -1649,43 +1651,7 @@ fts_drop_index_tables(
|
||||
trx_t* trx, /*!< in: transaction */
|
||||
dict_index_t* index) /*!< in: Index to drop */
|
||||
{
|
||||
dberr_t error = DB_SUCCESS;
|
||||
|
||||
#ifdef FTS_DOC_STATS_DEBUG
|
||||
fts_table_t fts_table;
|
||||
static const char* index_tables[] = {
|
||||
"DOC_ID",
|
||||
NULL
|
||||
};
|
||||
#endif /* FTS_DOC_STATS_DEBUG */
|
||||
|
||||
dberr_t err = fts_drop_index_split_tables(trx, index);
|
||||
|
||||
/* We only return the status of the last error. */
|
||||
if (err != DB_SUCCESS) {
|
||||
error = err;
|
||||
}
|
||||
|
||||
#ifdef FTS_DOC_STATS_DEBUG
|
||||
FTS_INIT_INDEX_TABLE(&fts_table, NULL, FTS_INDEX_TABLE, index);
|
||||
|
||||
for (ulint i = 0; index_tables[i] != NULL; ++i) {
|
||||
char table_name[MAX_FULL_NAME_LEN];
|
||||
|
||||
fts_table.suffix = index_tables[i];
|
||||
|
||||
fts_get_table_name(&fts_table, table_name);
|
||||
|
||||
err = fts_drop_table(trx, table_name);
|
||||
|
||||
/* We only return the status of the last error. */
|
||||
if (err != DB_SUCCESS && err != DB_FAIL) {
|
||||
error = err;
|
||||
}
|
||||
}
|
||||
#endif /* FTS_DOC_STATS_DEBUG */
|
||||
|
||||
return(error);
|
||||
return(fts_drop_index_split_tables(trx, index));
|
||||
}
|
||||
|
||||
/****************************************************************//**
|
||||
@ -2100,23 +2066,6 @@ fts_create_index_tables_low(
|
||||
fts_table.parent = table_name;
|
||||
fts_table.table = index->table;
|
||||
|
||||
#ifdef FTS_DOC_STATS_DEBUG
|
||||
/* Create the FTS auxiliary tables that are specific
|
||||
to an FTS index. */
|
||||
info = pars_info_create();
|
||||
|
||||
fts_table.suffix = "DOC_ID";
|
||||
fts_get_table_name(&fts_table, fts_name);
|
||||
|
||||
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);
|
||||
#endif /* FTS_DOC_STATS_DEBUG */
|
||||
|
||||
/* aux_idx_tables vector is used for dropping FTS AUX INDEX
|
||||
tables on error condition. */
|
||||
std::vector<dict_table_t*> aux_idx_tables;
|
||||
@ -2648,46 +2597,6 @@ fts_get_max_cache_size(
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef FTS_DOC_STATS_DEBUG
|
||||
/*********************************************************************//**
|
||||
Get the total number of words in the FTS for a particular FTS index.
|
||||
@return DB_SUCCESS if all OK else error code */
|
||||
dberr_t
|
||||
fts_get_total_word_count(
|
||||
/*=====================*/
|
||||
trx_t* trx, /*!< in: transaction */
|
||||
dict_index_t* index, /*!< in: for this index */
|
||||
ulint* total) /* out: total words */
|
||||
{
|
||||
dberr_t error;
|
||||
fts_string_t value;
|
||||
|
||||
*total = 0;
|
||||
|
||||
/* We set the length of value to the max bytes it can hold. This
|
||||
information is used by the callback that reads the value. */
|
||||
value.f_n_char = 0;
|
||||
value.f_len = FTS_MAX_CONFIG_VALUE_LEN;
|
||||
value.f_str = static_cast<byte*>(ut_malloc_nokey(value.f_len + 1));
|
||||
|
||||
error = fts_config_get_index_value(
|
||||
trx, index, FTS_TOTAL_WORD_COUNT, &value);
|
||||
|
||||
if (error == DB_SUCCESS) {
|
||||
|
||||
value.f_str[value.f_len] = 0;
|
||||
*total = strtoul((char*) value.f_str, NULL, 10);
|
||||
} else {
|
||||
ib::error() << "(" << ut_strerr(error) << ") reading total"
|
||||
" words value from config table";
|
||||
}
|
||||
|
||||
ut_free(value.f_str);
|
||||
|
||||
return(error);
|
||||
}
|
||||
#endif /* FTS_DOC_STATS_DEBUG */
|
||||
|
||||
/*********************************************************************//**
|
||||
Update the next and last Doc ID in the CONFIG table to be the input
|
||||
"doc_id" value (+ 1). We would do so after each FTS index build or
|
||||
@ -3285,31 +3194,6 @@ fts_doc_free(
|
||||
mem_heap_free(heap);
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
Callback function for fetch that stores a row id to the location pointed.
|
||||
The column's type must be DATA_FIXBINARY, DATA_BINARY_TYPE, length = 8.
|
||||
@return always returns NULL */
|
||||
void*
|
||||
fts_fetch_row_id(
|
||||
/*=============*/
|
||||
void* row, /*!< in: sel_node_t* */
|
||||
void* user_arg) /*!< in: data pointer */
|
||||
{
|
||||
sel_node_t* node = static_cast<sel_node_t*>(row);
|
||||
|
||||
dfield_t* dfield = que_node_get_val(node->select_list);
|
||||
dtype_t* type = dfield_get_type(dfield);
|
||||
ulint len = dfield_get_len(dfield);
|
||||
|
||||
ut_a(dtype_get_mtype(type) == DATA_FIXBINARY);
|
||||
ut_a(dtype_get_prtype(type) & DATA_BINARY_TYPE);
|
||||
ut_a(len == 8);
|
||||
|
||||
memcpy(user_arg, dfield_get_data(dfield), 8);
|
||||
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
Callback function for fetch that stores the text of an FTS document,
|
||||
converting each column to UTF-16.
|
||||
@ -4053,9 +3937,6 @@ fts_sync_write_words(
|
||||
dberr_t error = DB_SUCCESS;
|
||||
ibool print_error = FALSE;
|
||||
dict_table_t* table = index_cache->index->table;
|
||||
#ifdef FTS_DOC_STATS_DEBUG
|
||||
ulint n_new_words = 0;
|
||||
#endif /* FTS_DOC_STATS_DEBUG */
|
||||
|
||||
FTS_INIT_INDEX_TABLE(
|
||||
&fts_table, NULL, FTS_INDEX_TABLE, index_cache->index);
|
||||
@ -4080,25 +3961,6 @@ fts_sync_write_words(
|
||||
|
||||
fts_table.suffix = fts_get_suffix(selected);
|
||||
|
||||
#ifdef FTS_DOC_STATS_DEBUG
|
||||
/* Check if the word exists in the FTS index and if not
|
||||
then we need to increment the total word count stats. */
|
||||
if (error == DB_SUCCESS && fts_enable_diag_print) {
|
||||
ibool found = FALSE;
|
||||
|
||||
error = fts_is_word_in_index(
|
||||
trx,
|
||||
&index_cache->sel_graph[selected],
|
||||
&fts_table,
|
||||
&word->text, &found);
|
||||
|
||||
if (error == DB_SUCCESS && !found) {
|
||||
|
||||
++n_new_words;
|
||||
}
|
||||
}
|
||||
#endif /* FTS_DOC_STATS_DEBUG */
|
||||
|
||||
/* We iterate over all the nodes even if there was an error */
|
||||
for (i = 0; i < ib_vector_size(word->nodes); ++i) {
|
||||
|
||||
@ -4147,19 +4009,6 @@ fts_sync_write_words(
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef FTS_DOC_STATS_DEBUG
|
||||
if (error == DB_SUCCESS && n_new_words > 0 && fts_enable_diag_print) {
|
||||
fts_table_t fts_table;
|
||||
|
||||
FTS_INIT_FTS_TABLE(&fts_table, NULL, FTS_COMMON_TABLE, table);
|
||||
|
||||
/* Increment the total number of words in the FTS index */
|
||||
error = fts_config_increment_index_value(
|
||||
trx, index_cache->index, FTS_TOTAL_WORD_COUNT,
|
||||
n_new_words);
|
||||
}
|
||||
#endif /* FTS_DOC_STATS_DEBUG */
|
||||
|
||||
if (fts_enable_diag_print) {
|
||||
printf("Avg number of nodes: %lf\n",
|
||||
(double) n_nodes / (double) (n_words > 1 ? n_words : 1));
|
||||
@ -4168,236 +4017,6 @@ fts_sync_write_words(
|
||||
return(error);
|
||||
}
|
||||
|
||||
#ifdef FTS_DOC_STATS_DEBUG
|
||||
/*********************************************************************//**
|
||||
Write a single documents statistics to disk.
|
||||
@return DB_SUCCESS if all went well else error code */
|
||||
static MY_ATTRIBUTE((nonnull, warn_unused_result))
|
||||
dberr_t
|
||||
fts_sync_write_doc_stat(
|
||||
/*====================*/
|
||||
trx_t* trx, /*!< in: transaction */
|
||||
dict_index_t* index, /*!< in: index */
|
||||
que_t** graph, /* out: query graph */
|
||||
const fts_doc_stats_t* doc_stat) /*!< in: doc stats to write */
|
||||
{
|
||||
pars_info_t* info;
|
||||
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;
|
||||
} else {
|
||||
info = pars_info_create();
|
||||
}
|
||||
|
||||
/* Convert to "storage" byte order. */
|
||||
mach_write_to_4((byte*) &word_count, doc_stat->word_count);
|
||||
pars_info_bind_int4_literal(
|
||||
info, "count", (const ib_uint32_t*) &word_count);
|
||||
|
||||
/* Convert to "storage" byte order. */
|
||||
fts_write_doc_id((byte*) &doc_id, doc_stat->doc_id);
|
||||
fts_bind_doc_id(info, "doc_id", &doc_id);
|
||||
|
||||
if (!*graph) {
|
||||
fts_table_t fts_table;
|
||||
|
||||
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 $doc_id_table VALUES (:doc_id, :count);");
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
error = fts_eval_sql(trx, *graph);
|
||||
|
||||
if (error == DB_SUCCESS) {
|
||||
|
||||
break; /* Exit the loop. */
|
||||
} else {
|
||||
|
||||
if (error == DB_LOCK_WAIT_TIMEOUT) {
|
||||
ib::warn() << "Lock wait timeout writing to"
|
||||
" FTS doc_id. Retrying!";
|
||||
|
||||
trx->error_state = DB_SUCCESS;
|
||||
} else {
|
||||
ib::error() << "(" << ut_strerr(error)
|
||||
<< ") while writing to FTS doc_id.";
|
||||
|
||||
break; /* Exit the loop. */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return(error);
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
Write document statistics to disk.
|
||||
@return DB_SUCCESS if all OK */
|
||||
static
|
||||
ulint
|
||||
fts_sync_write_doc_stats(
|
||||
/*=====================*/
|
||||
trx_t* trx, /*!< in: transaction */
|
||||
const fts_index_cache_t*index_cache) /*!< in: index cache */
|
||||
{
|
||||
dberr_t error = DB_SUCCESS;
|
||||
que_t* graph = NULL;
|
||||
fts_doc_stats_t* doc_stat;
|
||||
|
||||
if (ib_vector_is_empty(index_cache->doc_stats)) {
|
||||
return(DB_SUCCESS);
|
||||
}
|
||||
|
||||
doc_stat = static_cast<ts_doc_stats_t*>(
|
||||
ib_vector_pop(index_cache->doc_stats));
|
||||
|
||||
while (doc_stat) {
|
||||
error = fts_sync_write_doc_stat(
|
||||
trx, index_cache->index, &graph, doc_stat);
|
||||
|
||||
if (error != DB_SUCCESS) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (ib_vector_is_empty(index_cache->doc_stats)) {
|
||||
break;
|
||||
}
|
||||
|
||||
doc_stat = static_cast<ts_doc_stats_t*>(
|
||||
ib_vector_pop(index_cache->doc_stats));
|
||||
}
|
||||
|
||||
if (graph != NULL) {
|
||||
fts_que_graph_free_check_lock(NULL, index_cache, graph);
|
||||
}
|
||||
|
||||
return(error);
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
Callback to check the existince of a word.
|
||||
@return always return NULL */
|
||||
static
|
||||
ibool
|
||||
fts_lookup_word(
|
||||
/*============*/
|
||||
void* row, /*!< in: sel_node_t* */
|
||||
void* user_arg) /*!< in: fts_doc_t* */
|
||||
{
|
||||
|
||||
que_node_t* exp;
|
||||
sel_node_t* node = static_cast<sel_node_t*>(row);
|
||||
ibool* found = static_cast<ibool*>(user_arg);
|
||||
|
||||
exp = node->select_list;
|
||||
|
||||
while (exp) {
|
||||
dfield_t* dfield = que_node_get_val(exp);
|
||||
ulint len = dfield_get_len(dfield);
|
||||
|
||||
if (len != UNIV_SQL_NULL && len != 0) {
|
||||
*found = TRUE;
|
||||
}
|
||||
|
||||
exp = que_node_get_next(exp);
|
||||
}
|
||||
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
Check whether a particular word (term) exists in the FTS index.
|
||||
@return DB_SUCCESS if all went well else error code */
|
||||
static
|
||||
dberr_t
|
||||
fts_is_word_in_index(
|
||||
/*=================*/
|
||||
trx_t* trx, /*!< in: FTS query state */
|
||||
que_t** graph, /* out: Query graph */
|
||||
fts_table_t* fts_table, /*!< in: table instance */
|
||||
const fts_string_t*
|
||||
word, /*!< in: the word to check */
|
||||
ibool* found) /* out: TRUE if exists */
|
||||
{
|
||||
pars_info_t* info;
|
||||
dberr_t error;
|
||||
char table_name[MAX_FULL_NAME_LEN];
|
||||
|
||||
trx->op_info = "looking up word in FTS index";
|
||||
|
||||
if (*graph) {
|
||||
info = (*graph)->info;
|
||||
} else {
|
||||
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);
|
||||
|
||||
if (*graph == NULL) {
|
||||
*graph = fts_parse_sql(
|
||||
fts_table,
|
||||
info,
|
||||
"DECLARE FUNCTION my_func;\n"
|
||||
"DECLARE CURSOR c IS"
|
||||
" SELECT doc_count\n"
|
||||
" FROM $table_name\n"
|
||||
" WHERE word = :word"
|
||||
" ORDER BY first_doc_id;\n"
|
||||
"BEGIN\n"
|
||||
"\n"
|
||||
"OPEN c;\n"
|
||||
"WHILE 1 = 1 LOOP\n"
|
||||
" FETCH c INTO my_func();\n"
|
||||
" IF c % NOTFOUND THEN\n"
|
||||
" EXIT;\n"
|
||||
" END IF;\n"
|
||||
"END LOOP;\n"
|
||||
"CLOSE c;");
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
error = fts_eval_sql(trx, *graph);
|
||||
|
||||
if (error == DB_SUCCESS) {
|
||||
|
||||
break; /* Exit the loop. */
|
||||
} else {
|
||||
|
||||
if (error == DB_LOCK_WAIT_TIMEOUT) {
|
||||
ib::warn() << "Lock wait timeout reading"
|
||||
" FTS index. Retrying!";
|
||||
|
||||
trx->error_state = DB_SUCCESS;
|
||||
} else {
|
||||
ib::error() << "(" << ut_strerr(error)
|
||||
<< ") while reading FTS index.";
|
||||
|
||||
break; /* Exit the loop. */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return(error);
|
||||
}
|
||||
#endif /* FTS_DOC_STATS_DEBUG */
|
||||
|
||||
/*********************************************************************//**
|
||||
Begin Sync, create transaction, acquire locks, etc. */
|
||||
static
|
||||
@ -4435,7 +4054,6 @@ fts_sync_index(
|
||||
fts_index_cache_t* index_cache) /*!< in: index cache */
|
||||
{
|
||||
trx_t* trx = sync->trx;
|
||||
dberr_t error = DB_SUCCESS;
|
||||
|
||||
trx->op_info = "doing SYNC index";
|
||||
|
||||
@ -4445,20 +4063,7 @@ fts_sync_index(
|
||||
|
||||
ut_ad(rbt_validate(index_cache->words));
|
||||
|
||||
error = fts_sync_write_words(trx, index_cache, sync->unlock_cache);
|
||||
|
||||
#ifdef FTS_DOC_STATS_DEBUG
|
||||
/* FTS_RESOLVE: the word counter info in auxiliary table "DOC_ID"
|
||||
is not used currently for ranking. We disable fts_sync_write_doc_stats()
|
||||
for now */
|
||||
/* Write the per doc statistics that will be used for ranking. */
|
||||
if (error == DB_SUCCESS) {
|
||||
|
||||
error = fts_sync_write_doc_stats(trx, index_cache);
|
||||
}
|
||||
#endif /* FTS_DOC_STATS_DEBUG */
|
||||
|
||||
return(error);
|
||||
return(fts_sync_write_words(trx, index_cache, sync->unlock_cache));
|
||||
}
|
||||
|
||||
/** Check if index cache has been synced completely
|
||||
@ -5134,16 +4739,16 @@ fts_tokenize_by_parser(
|
||||
PARSER_DEINIT(parser, ¶m);
|
||||
}
|
||||
|
||||
/******************************************************************//**
|
||||
Tokenize a document. */
|
||||
/** Tokenize a document.
|
||||
@param[in,out] doc document to tokenize
|
||||
@param[out] result tokenization result
|
||||
@param[in] parser pluggable parser */
|
||||
static
|
||||
void
|
||||
fts_tokenize_document(
|
||||
/*==================*/
|
||||
fts_doc_t* doc, /* in/out: document to
|
||||
tokenize */
|
||||
fts_doc_t* result, /* out: if provided, save
|
||||
the result token here */
|
||||
st_mysql_ftparser* parser) /* in: plugin fts parser */
|
||||
fts_doc_t* doc,
|
||||
fts_doc_t* result,
|
||||
st_mysql_ftparser* parser)
|
||||
{
|
||||
ut_a(!doc->tokens);
|
||||
ut_a(doc->charset);
|
||||
@ -5168,18 +4773,18 @@ fts_tokenize_document(
|
||||
}
|
||||
}
|
||||
|
||||
/******************************************************************//**
|
||||
Continue to tokenize a document. */
|
||||
/** Continue to tokenize a document.
|
||||
@param[in,out] doc document to tokenize
|
||||
@param[in] add_pos add this position to all tokens from this tokenization
|
||||
@param[out] result tokenization result
|
||||
@param[in] parser pluggable parser */
|
||||
static
|
||||
void
|
||||
fts_tokenize_document_next(
|
||||
/*=======================*/
|
||||
fts_doc_t* doc, /*!< in/out: document to
|
||||
tokenize */
|
||||
ulint add_pos, /*!< in: add this position to all
|
||||
tokens from this tokenization */
|
||||
fts_doc_t* result, /*!< out: if provided, save
|
||||
the result token here */
|
||||
st_mysql_ftparser* parser) /* in: plugin fts parser */
|
||||
fts_doc_t* doc,
|
||||
ulint add_pos,
|
||||
fts_doc_t* result,
|
||||
st_mysql_ftparser* parser)
|
||||
{
|
||||
ut_a(doc->tokens);
|
||||
|
||||
@ -5200,14 +4805,13 @@ fts_tokenize_document_next(
|
||||
}
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
Create the vector of fts_get_doc_t instances. */
|
||||
/** Create the vector of fts_get_doc_t instances.
|
||||
@param[in,out] cache fts cache
|
||||
@return vector of fts_get_doc_t instances */
|
||||
static
|
||||
ib_vector_t*
|
||||
fts_get_docs_create(
|
||||
/*================*/
|
||||
/* out: vector of
|
||||
fts_get_doc_t instances */
|
||||
fts_cache_t* cache) /*!< in: fts cache */
|
||||
fts_cache_t* cache)
|
||||
{
|
||||
ib_vector_t* get_docs;
|
||||
|
||||
@ -5680,32 +5284,6 @@ fts_cache_find_word(
|
||||
return(nodes);
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
Check cache for deleted doc id.
|
||||
@return TRUE if deleted */
|
||||
ibool
|
||||
fts_cache_is_deleted_doc_id(
|
||||
/*========================*/
|
||||
const fts_cache_t* cache, /*!< in: cache ito search */
|
||||
doc_id_t doc_id) /*!< in: doc id to search for */
|
||||
{
|
||||
ut_ad(mutex_own(&cache->deleted_lock));
|
||||
|
||||
for (ulint i = 0; i < ib_vector_size(cache->deleted_doc_ids); ++i) {
|
||||
const fts_update_t* update;
|
||||
|
||||
update = static_cast<const fts_update_t*>(
|
||||
ib_vector_get_const(cache->deleted_doc_ids, i));
|
||||
|
||||
if (doc_id == update->doc_id) {
|
||||
|
||||
return(TRUE);
|
||||
}
|
||||
}
|
||||
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
Append deleted doc ids to vector. */
|
||||
void
|
||||
@ -5870,18 +5448,6 @@ fts_update_doc_id(
|
||||
return(doc_id);
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
Check if the table has an FTS index. This is the non-inline version
|
||||
of dict_table_has_fts_index().
|
||||
@return TRUE if table has an FTS index */
|
||||
ibool
|
||||
fts_dict_table_has_fts_index(
|
||||
/*=========================*/
|
||||
dict_table_t* table) /*!< in: table */
|
||||
{
|
||||
return(dict_table_has_fts_index(table));
|
||||
}
|
||||
|
||||
/** fts_t constructor.
|
||||
@param[in] table table with FTS indexes
|
||||
@param[in,out] heap memory heap where 'this' is stored */
|
||||
@ -5960,6 +5526,7 @@ fts_free(
|
||||
table->fts = NULL;
|
||||
}
|
||||
|
||||
#if 0 // TODO: Enable this in WL#6608
|
||||
/*********************************************************************//**
|
||||
Signal FTS threads to initiate shutdown. */
|
||||
void
|
||||
@ -5993,6 +5560,7 @@ fts_shutdown(
|
||||
|
||||
mutex_exit(&fts->bg_threads_mutex);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*********************************************************************//**
|
||||
Take a FTS savepoint. */
|
||||
@ -6512,6 +6080,7 @@ fts_set_hex_format(
|
||||
/*****************************************************************//**
|
||||
Update the DICT_TF2_FTS_AUX_HEX_NAME flag in SYS_TABLES.
|
||||
@return DB_SUCCESS or error code. */
|
||||
static
|
||||
dberr_t
|
||||
fts_update_hex_format_flag(
|
||||
/*=======================*/
|
||||
|
@ -338,6 +338,7 @@ fts_zip_init(
|
||||
/**********************************************************************//**
|
||||
Create a fts_optimizer_word_t instance.
|
||||
@return new instance */
|
||||
static
|
||||
fts_word_t*
|
||||
fts_word_init(
|
||||
/*==========*/
|
||||
@ -2573,8 +2574,10 @@ fts_optimize_add_table(
|
||||
ib_wqueue_add(fts_optimize_wq, msg, msg->heap);
|
||||
}
|
||||
|
||||
#if 0
|
||||
/**********************************************************************//**
|
||||
Optimize a table. */
|
||||
static
|
||||
void
|
||||
fts_optimize_do_table(
|
||||
/*==================*/
|
||||
@ -2591,6 +2594,7 @@ fts_optimize_do_table(
|
||||
|
||||
ib_wqueue_add(fts_optimize_wq, msg, msg->heap);
|
||||
}
|
||||
#endif
|
||||
|
||||
/**********************************************************************//**
|
||||
Remove the table from the OPTIMIZER's list. We do wait for
|
||||
@ -2977,6 +2981,7 @@ fts_optimize_sync_table(
|
||||
/**********************************************************************//**
|
||||
Optimize all FTS tables.
|
||||
@return Dummy return */
|
||||
static
|
||||
os_thread_ret_t
|
||||
fts_optimize_thread(
|
||||
/*================*/
|
||||
@ -3161,16 +3166,6 @@ fts_optimize_init(void)
|
||||
os_thread_create(fts_optimize_thread, fts_optimize_wq, NULL);
|
||||
}
|
||||
|
||||
/**********************************************************************//**
|
||||
Check whether the work queue is initialized.
|
||||
@return TRUE if optimze queue is initialized. */
|
||||
ibool
|
||||
fts_optimize_is_init(void)
|
||||
/*======================*/
|
||||
{
|
||||
return(fts_optimize_wq != NULL);
|
||||
}
|
||||
|
||||
/** Shutdown fts optimize thread. */
|
||||
void
|
||||
fts_optimize_shutdown()
|
||||
|
@ -108,6 +108,7 @@ Note:
|
||||
a. Parse logic refers to 'ftb_query_add_word' from ft_boolean_search.c in MYISAM;
|
||||
b. Parse node or tree refers to fts0pars.y.
|
||||
@return 0 if add successfully, or return non-zero. */
|
||||
static
|
||||
int
|
||||
fts_query_add_word_for_parser(
|
||||
/*==========================*/
|
||||
|
@ -302,6 +302,20 @@ fts_query_filter_doc_ids(
|
||||
ibool calc_doc_count);/*!< in: whether to remember doc
|
||||
count */
|
||||
|
||||
/** Process (nested) sub-expression, create a new result set to store the
|
||||
sub-expression result by processing nodes under current sub-expression
|
||||
list. Merge the sub-expression result with that of parent expression list.
|
||||
@param[in,out] node current root node
|
||||
@param[in,out] visitor callback function
|
||||
@param[in,out] arg argument for callback
|
||||
@return DB_SUCCESS if all go well */
|
||||
static
|
||||
dberr_t
|
||||
fts_ast_visit_sub_exp(
|
||||
fts_ast_node_t* node,
|
||||
fts_ast_callback visitor,
|
||||
void* arg);
|
||||
|
||||
#if 0
|
||||
/*****************************************************************//***
|
||||
Find a doc_id in a word's ilist.
|
||||
@ -3058,17 +3072,19 @@ fts_query_visitor(
|
||||
DBUG_RETURN(query->error);
|
||||
}
|
||||
|
||||
/*****************************************************************//**
|
||||
Process (nested) sub-expression, create a new result set to store the
|
||||
/** Process (nested) sub-expression, create a new result set to store the
|
||||
sub-expression result by processing nodes under current sub-expression
|
||||
list. Merge the sub-expression result with that of parent expression list.
|
||||
@param[in,out] node current root node
|
||||
@param[in,out] visitor callback function
|
||||
@param[in,out] arg argument for callback
|
||||
@return DB_SUCCESS if all go well */
|
||||
static
|
||||
dberr_t
|
||||
fts_ast_visit_sub_exp(
|
||||
/*==================*/
|
||||
fts_ast_node_t* node, /*!< in,out: current root node */
|
||||
fts_ast_callback visitor, /*!< in: callback function */
|
||||
void* arg) /*!< in,out: arg for callback */
|
||||
fts_ast_node_t* node,
|
||||
fts_ast_callback visitor,
|
||||
void* arg)
|
||||
{
|
||||
fts_ast_oper_t cur_oper;
|
||||
fts_query_t* query = static_cast<fts_query_t*>(arg);
|
||||
@ -3999,19 +4015,6 @@ fts_query(
|
||||
query.limit = limit;
|
||||
|
||||
query.n_docs = 0;
|
||||
#ifdef FTS_DOC_STATS_DEBUG
|
||||
if (ft_enable_diag_print) {
|
||||
error = fts_get_total_word_count(
|
||||
trx, query.index, &query.total_words);
|
||||
|
||||
if (error != DB_SUCCESS) {
|
||||
goto func_exit;
|
||||
}
|
||||
|
||||
ib::info() << "Total docs: " << query.total_docs
|
||||
<< " Total words: " << query.total_words;
|
||||
}
|
||||
#endif /* FTS_DOC_STATS_DEBUG */
|
||||
|
||||
query.fts_common_table.suffix = "DELETED";
|
||||
|
||||
|
@ -67,6 +67,27 @@ flst_add_to_empty(
|
||||
mlog_write_ulint(base + FLST_LEN, len + 1, MLOG_4BYTES, mtr);
|
||||
}
|
||||
|
||||
/********************************************************************//**
|
||||
Inserts a node after another in a list. */
|
||||
static
|
||||
void
|
||||
flst_insert_after(
|
||||
/*==============*/
|
||||
flst_base_node_t* base, /*!< in: pointer to base node of list */
|
||||
flst_node_t* node1, /*!< in: node to insert after */
|
||||
flst_node_t* node2, /*!< in: node to add */
|
||||
mtr_t* mtr); /*!< in: mini-transaction handle */
|
||||
/********************************************************************//**
|
||||
Inserts a node before another in a list. */
|
||||
static
|
||||
void
|
||||
flst_insert_before(
|
||||
/*===============*/
|
||||
flst_base_node_t* base, /*!< in: pointer to base node of list */
|
||||
flst_node_t* node2, /*!< in: node to insert */
|
||||
flst_node_t* node3, /*!< in: node to insert before */
|
||||
mtr_t* mtr); /*!< in: mini-transaction handle */
|
||||
|
||||
/********************************************************************//**
|
||||
Adds a node as the last node in a list. */
|
||||
void
|
||||
@ -170,6 +191,7 @@ flst_add_first(
|
||||
|
||||
/********************************************************************//**
|
||||
Inserts a node after another in a list. */
|
||||
static
|
||||
void
|
||||
flst_insert_after(
|
||||
/*==============*/
|
||||
@ -234,6 +256,7 @@ flst_insert_after(
|
||||
|
||||
/********************************************************************//**
|
||||
Inserts a node before another in a list. */
|
||||
static
|
||||
void
|
||||
flst_insert_before(
|
||||
/*===============*/
|
||||
@ -449,29 +472,3 @@ flst_validate(
|
||||
|
||||
return(TRUE);
|
||||
}
|
||||
|
||||
/********************************************************************//**
|
||||
Prints info of a file-based list. */
|
||||
void
|
||||
flst_print(
|
||||
/*=======*/
|
||||
const flst_base_node_t* base, /*!< in: pointer to base node of list */
|
||||
mtr_t* mtr) /*!< in: mtr */
|
||||
{
|
||||
const buf_frame_t* frame;
|
||||
ulint len;
|
||||
|
||||
ut_ad(base && mtr);
|
||||
ut_ad(mtr_memo_contains_page_flagged(mtr, base,
|
||||
MTR_MEMO_PAGE_X_FIX
|
||||
| MTR_MEMO_PAGE_SX_FIX));
|
||||
frame = page_align((byte*) base);
|
||||
|
||||
len = flst_get_len(base);
|
||||
|
||||
ib::info() << "FILE-BASED LIST: Base node in space "
|
||||
<< page_get_space_id(frame)
|
||||
<< "; page " << page_get_page_no(frame)
|
||||
<< "; byte offset " << page_offset(base)
|
||||
<< "; len " << len;
|
||||
}
|
||||
|
@ -803,6 +803,7 @@ This has to be done either within the same mini-transaction,
|
||||
or by invoking ibuf_reset_free_bits() before mtr_commit().
|
||||
|
||||
@return TRUE on success; FALSE on compression failure */
|
||||
static
|
||||
ibool
|
||||
rtr_split_page_move_rec_list(
|
||||
/*=========================*/
|
||||
|
@ -39,6 +39,15 @@ Created 2014/01/16 Jimmy Yang
|
||||
#include "srv0mon.h"
|
||||
#include "gis0geo.h"
|
||||
|
||||
/** Restore the stored position of a persistent cursor bufferfixing the page */
|
||||
static
|
||||
bool
|
||||
rtr_cur_restore_position(
|
||||
ulint latch_mode, /*!< in: BTR_SEARCH_LEAF, ... */
|
||||
btr_cur_t* cursor, /*!< in: detached persistent cursor */
|
||||
ulint level, /*!< in: index level */
|
||||
mtr_t* mtr); /*!< in: mtr */
|
||||
|
||||
/*************************************************************//**
|
||||
Pop out used parent path entry, until we find the parent with matching
|
||||
page number */
|
||||
@ -678,47 +687,18 @@ rtr_page_get_father(
|
||||
mem_heap_free(heap);
|
||||
}
|
||||
|
||||
/************************************************************//**
|
||||
Returns the father block to a page. It is assumed that mtr holds
|
||||
an X or SX latch on the tree.
|
||||
@return rec_get_offsets() of the node pointer record */
|
||||
ulint*
|
||||
rtr_page_get_father_block(
|
||||
/*======================*/
|
||||
ulint* offsets,/*!< in: work area for the return value */
|
||||
mem_heap_t* heap, /*!< in: memory heap to use */
|
||||
dict_index_t* index, /*!< in: b-tree index */
|
||||
buf_block_t* block, /*!< in: child page in the index */
|
||||
mtr_t* mtr, /*!< in: mtr */
|
||||
btr_cur_t* sea_cur,/*!< in: search cursor, contains information
|
||||
about parent nodes in search */
|
||||
btr_cur_t* cursor) /*!< out: cursor on node pointer record,
|
||||
its page x-latched */
|
||||
{
|
||||
|
||||
rec_t* rec = page_rec_get_next(
|
||||
page_get_infimum_rec(buf_block_get_frame(block)));
|
||||
btr_cur_position(index, rec, block, cursor);
|
||||
|
||||
return(rtr_page_get_father_node_ptr(offsets, heap, sea_cur,
|
||||
cursor, mtr));
|
||||
}
|
||||
|
||||
/************************************************************//**
|
||||
Returns the upper level node pointer to a R-Tree page. It is assumed
|
||||
that mtr holds an x-latch on the tree.
|
||||
/** Returns the upper level node pointer to a R-Tree page. It is assumed
|
||||
that mtr holds an SX-latch or X-latch on the tree.
|
||||
@return rec_get_offsets() of the node pointer record */
|
||||
static
|
||||
ulint*
|
||||
rtr_page_get_father_node_ptr_func(
|
||||
/*==============================*/
|
||||
rtr_page_get_father_node_ptr(
|
||||
ulint* offsets,/*!< in: work area for the return value */
|
||||
mem_heap_t* heap, /*!< in: memory heap to use */
|
||||
btr_cur_t* sea_cur,/*!< in: search cursor */
|
||||
btr_cur_t* cursor, /*!< in: cursor pointing to user record,
|
||||
out: cursor on node pointer record,
|
||||
its page x-latched */
|
||||
const char* file, /*!< in: file name */
|
||||
unsigned line, /*!< in: line where called */
|
||||
mtr_t* mtr) /*!< in: mtr */
|
||||
{
|
||||
dtuple_t* tuple;
|
||||
@ -800,6 +780,31 @@ rtr_page_get_father_node_ptr_func(
|
||||
return(offsets);
|
||||
}
|
||||
|
||||
/************************************************************//**
|
||||
Returns the father block to a page. It is assumed that mtr holds
|
||||
an X or SX latch on the tree.
|
||||
@return rec_get_offsets() of the node pointer record */
|
||||
ulint*
|
||||
rtr_page_get_father_block(
|
||||
/*======================*/
|
||||
ulint* offsets,/*!< in: work area for the return value */
|
||||
mem_heap_t* heap, /*!< in: memory heap to use */
|
||||
dict_index_t* index, /*!< in: b-tree index */
|
||||
buf_block_t* block, /*!< in: child page in the index */
|
||||
mtr_t* mtr, /*!< in: mtr */
|
||||
btr_cur_t* sea_cur,/*!< in: search cursor, contains information
|
||||
about parent nodes in search */
|
||||
btr_cur_t* cursor) /*!< out: cursor on node pointer record,
|
||||
its page x-latched */
|
||||
{
|
||||
rec_t* rec = page_rec_get_next(
|
||||
page_get_infimum_rec(buf_block_get_frame(block)));
|
||||
btr_cur_position(index, rec, block, cursor);
|
||||
|
||||
return(rtr_page_get_father_node_ptr(offsets, heap, sea_cur,
|
||||
cursor, mtr));
|
||||
}
|
||||
|
||||
/********************************************************************//**
|
||||
Returns the upper level node pointer to a R-Tree page. It is assumed
|
||||
that mtr holds an x-latch on the tree. */
|
||||
@ -1253,16 +1258,13 @@ rtr_check_discard_page(
|
||||
lock_mutex_exit();
|
||||
}
|
||||
|
||||
/**************************************************************//**
|
||||
Restores the stored position of a persistent cursor bufferfixing the page */
|
||||
/** Restore the stored position of a persistent cursor bufferfixing the page */
|
||||
static
|
||||
bool
|
||||
rtr_cur_restore_position_func(
|
||||
/*==========================*/
|
||||
ulint latch_mode, /*!< in: BTR_CONT_MODIFY_TREE, ... */
|
||||
rtr_cur_restore_position(
|
||||
ulint latch_mode, /*!< in: BTR_SEARCH_LEAF, ... */
|
||||
btr_cur_t* btr_cur, /*!< in: detached persistent cursor */
|
||||
ulint level, /*!< in: index level */
|
||||
const char* file, /*!< in: file name */
|
||||
unsigned line, /*!< in: line where called */
|
||||
mtr_t* mtr) /*!< in: mtr */
|
||||
{
|
||||
dict_index_t* index;
|
||||
@ -1291,8 +1293,9 @@ rtr_cur_restore_position_func(
|
||||
|
||||
if (!buf_pool_is_obsolete(r_cursor->withdraw_clock)
|
||||
&& buf_page_optimistic_get(RW_X_LATCH,
|
||||
r_cursor->block_when_stored,
|
||||
r_cursor->modify_clock, file, line, mtr)) {
|
||||
r_cursor->block_when_stored,
|
||||
r_cursor->modify_clock,
|
||||
__FILE__, __LINE__, mtr)) {
|
||||
ut_ad(r_cursor->pos_state == BTR_PCUR_IS_POSITIONED);
|
||||
|
||||
ut_ad(r_cursor->rel_pos == BTR_PCUR_ON);
|
||||
|
@ -27,160 +27,6 @@ Created 5/20/1997 Heikki Tuuri
|
||||
#include "mem0mem.h"
|
||||
#include "sync0sync.h"
|
||||
|
||||
/************************************************************//**
|
||||
Reserves the mutex for a fold value in a hash table. */
|
||||
void
|
||||
hash_mutex_enter(
|
||||
/*=============*/
|
||||
hash_table_t* table, /*!< in: hash table */
|
||||
ulint fold) /*!< in: fold */
|
||||
{
|
||||
ut_ad(table->type == HASH_TABLE_SYNC_MUTEX);
|
||||
mutex_enter(hash_get_mutex(table, fold));
|
||||
}
|
||||
|
||||
/************************************************************//**
|
||||
Releases the mutex for a fold value in a hash table. */
|
||||
void
|
||||
hash_mutex_exit(
|
||||
/*============*/
|
||||
hash_table_t* table, /*!< in: hash table */
|
||||
ulint fold) /*!< in: fold */
|
||||
{
|
||||
ut_ad(table->type == HASH_TABLE_SYNC_MUTEX);
|
||||
mutex_exit(hash_get_mutex(table, fold));
|
||||
}
|
||||
|
||||
/************************************************************//**
|
||||
Reserves all the mutexes of a hash table, in an ascending order. */
|
||||
void
|
||||
hash_mutex_enter_all(
|
||||
/*=================*/
|
||||
hash_table_t* table) /*!< in: hash table */
|
||||
{
|
||||
ut_ad(table->type == HASH_TABLE_SYNC_MUTEX);
|
||||
|
||||
for (ulint i = 0; i < table->n_sync_obj; i++) {
|
||||
|
||||
mutex_enter(table->sync_obj.mutexes + i);
|
||||
}
|
||||
}
|
||||
|
||||
/************************************************************//**
|
||||
Releases all the mutexes of a hash table. */
|
||||
void
|
||||
hash_mutex_exit_all(
|
||||
/*================*/
|
||||
hash_table_t* table) /*!< in: hash table */
|
||||
{
|
||||
ut_ad(table->type == HASH_TABLE_SYNC_MUTEX);
|
||||
|
||||
for (ulint i = 0; i < table->n_sync_obj; i++) {
|
||||
|
||||
mutex_exit(table->sync_obj.mutexes + i);
|
||||
}
|
||||
}
|
||||
|
||||
/************************************************************//**
|
||||
Releases all but the passed in mutex of a hash table. */
|
||||
void
|
||||
hash_mutex_exit_all_but(
|
||||
/*====================*/
|
||||
hash_table_t* table, /*!< in: hash table */
|
||||
ib_mutex_t* keep_mutex) /*!< in: mutex to keep */
|
||||
{
|
||||
ulint i;
|
||||
|
||||
ut_ad(table->type == HASH_TABLE_SYNC_MUTEX);
|
||||
for (i = 0; i < table->n_sync_obj; i++) {
|
||||
|
||||
ib_mutex_t* mutex = table->sync_obj.mutexes + i;
|
||||
if (keep_mutex != mutex) {
|
||||
mutex_exit(mutex);
|
||||
}
|
||||
}
|
||||
|
||||
ut_ad(mutex_own(keep_mutex));
|
||||
}
|
||||
|
||||
/************************************************************//**
|
||||
s-lock a lock for a fold value in a hash table. */
|
||||
void
|
||||
hash_lock_s(
|
||||
/*========*/
|
||||
hash_table_t* table, /*!< in: hash table */
|
||||
ulint fold) /*!< in: fold */
|
||||
{
|
||||
|
||||
rw_lock_t* lock = hash_get_lock(table, fold);
|
||||
|
||||
ut_ad(table->type == HASH_TABLE_SYNC_RW_LOCK);
|
||||
ut_ad(lock);
|
||||
|
||||
ut_ad(!rw_lock_own(lock, RW_LOCK_S));
|
||||
ut_ad(!rw_lock_own(lock, RW_LOCK_X));
|
||||
|
||||
rw_lock_s_lock(lock);
|
||||
}
|
||||
|
||||
/************************************************************//**
|
||||
x-lock a lock for a fold value in a hash table. */
|
||||
void
|
||||
hash_lock_x(
|
||||
/*========*/
|
||||
hash_table_t* table, /*!< in: hash table */
|
||||
ulint fold) /*!< in: fold */
|
||||
{
|
||||
|
||||
rw_lock_t* lock = hash_get_lock(table, fold);
|
||||
|
||||
ut_ad(table->type == HASH_TABLE_SYNC_RW_LOCK);
|
||||
ut_ad(lock);
|
||||
|
||||
ut_ad(!rw_lock_own(lock, RW_LOCK_S));
|
||||
ut_ad(!rw_lock_own(lock, RW_LOCK_X));
|
||||
|
||||
rw_lock_x_lock(lock);
|
||||
}
|
||||
|
||||
/************************************************************//**
|
||||
unlock an s-lock for a fold value in a hash table. */
|
||||
void
|
||||
hash_unlock_s(
|
||||
/*==========*/
|
||||
|
||||
hash_table_t* table, /*!< in: hash table */
|
||||
ulint fold) /*!< in: fold */
|
||||
{
|
||||
|
||||
rw_lock_t* lock = hash_get_lock(table, fold);
|
||||
|
||||
ut_ad(table->type == HASH_TABLE_SYNC_RW_LOCK);
|
||||
ut_ad(lock);
|
||||
|
||||
ut_ad(rw_lock_own(lock, RW_LOCK_S));
|
||||
|
||||
rw_lock_s_unlock(lock);
|
||||
}
|
||||
|
||||
/************************************************************//**
|
||||
unlock x-lock for a fold value in a hash table. */
|
||||
void
|
||||
hash_unlock_x(
|
||||
/*==========*/
|
||||
hash_table_t* table, /*!< in: hash table */
|
||||
ulint fold) /*!< in: fold */
|
||||
{
|
||||
rw_lock_t* lock = hash_get_lock(table, fold);
|
||||
|
||||
ut_ad(table->type == HASH_TABLE_SYNC_RW_LOCK);
|
||||
ut_ad(lock);
|
||||
|
||||
ut_ad(rw_lock_own(lock, RW_LOCK_X));
|
||||
|
||||
rw_lock_x_unlock(lock);
|
||||
}
|
||||
|
||||
/************************************************************//**
|
||||
Reserves all the locks of a hash table, in an ascending order. */
|
||||
void
|
||||
|
@ -473,6 +473,31 @@ static const char* innobase_change_buffering_values[IBUF_USE_COUNT] = {
|
||||
"all" /* IBUF_USE_ALL */
|
||||
};
|
||||
|
||||
/** Retrieve the FTS Relevance Ranking result for doc with doc_id
|
||||
of m_prebuilt->fts_doc_id
|
||||
@param[in,out] fts_hdl FTS handler
|
||||
@return the relevance ranking value */
|
||||
static
|
||||
float
|
||||
innobase_fts_retrieve_ranking(
|
||||
FT_INFO* fts_hdl);
|
||||
/** Free the memory for the FTS handler
|
||||
@param[in,out] fts_hdl FTS handler */
|
||||
static
|
||||
void
|
||||
innobase_fts_close_ranking(
|
||||
FT_INFO* fts_hdl);
|
||||
/** Find and Retrieve the FTS Relevance Ranking result for doc with doc_id
|
||||
of m_prebuilt->fts_doc_id
|
||||
@param[in,out] fts_hdl FTS handler
|
||||
@return the relevance ranking value */
|
||||
static
|
||||
float
|
||||
innobase_fts_find_ranking(
|
||||
FT_INFO* fts_hdl,
|
||||
uchar*,
|
||||
uint);
|
||||
|
||||
/* Call back function array defined by MySQL and used to
|
||||
retrieve FTS results. */
|
||||
const struct _ft_vft ft_vft_result = {NULL,
|
||||
@ -481,6 +506,50 @@ const struct _ft_vft ft_vft_result = {NULL,
|
||||
innobase_fts_retrieve_ranking,
|
||||
NULL};
|
||||
|
||||
/** @return version of the extended FTS API */
|
||||
static
|
||||
uint
|
||||
innobase_fts_get_version()
|
||||
{
|
||||
/* Currently this doesn't make much sense as returning
|
||||
HA_CAN_FULLTEXT_EXT automatically mean this version is supported.
|
||||
This supposed to ease future extensions. */
|
||||
return(2);
|
||||
}
|
||||
|
||||
/** @return Which part of the extended FTS API is supported */
|
||||
static
|
||||
ulonglong
|
||||
innobase_fts_flags()
|
||||
{
|
||||
return(FTS_ORDERED_RESULT | FTS_DOCID_IN_RESULT);
|
||||
}
|
||||
|
||||
/** Find and Retrieve the FTS doc_id for the current result row
|
||||
@param[in,out] fts_hdl FTS handler
|
||||
@return the document ID */
|
||||
static
|
||||
ulonglong
|
||||
innobase_fts_retrieve_docid(
|
||||
FT_INFO_EXT* fts_hdl);
|
||||
|
||||
/** Find and retrieve the size of the current result
|
||||
@param[in,out] fts_hdl FTS handler
|
||||
@return number of matching rows */
|
||||
static
|
||||
ulonglong
|
||||
innobase_fts_count_matches(
|
||||
FT_INFO_EXT* fts_hdl) /*!< in: FTS handler */
|
||||
{
|
||||
NEW_FT_INFO* handle = reinterpret_cast<NEW_FT_INFO*>(fts_hdl);
|
||||
|
||||
if (handle->ft_result->rankings_by_id != NULL) {
|
||||
return(rbt_size(handle->ft_result->rankings_by_id));
|
||||
} else {
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
|
||||
const struct _ft_vft_ext ft_vft_ext_result = {innobase_fts_get_version,
|
||||
innobase_fts_flags,
|
||||
innobase_fts_retrieve_docid,
|
||||
@ -1719,22 +1788,6 @@ thd_trx_priority(THD* thd)
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef UNIV_DEBUG
|
||||
/**
|
||||
Returns true if transaction should be flagged as DD attachable transaction
|
||||
@param[in] thd Thread handle
|
||||
@return true if the thd is marked as read-only */
|
||||
bool
|
||||
thd_trx_is_dd_trx(THD* thd)
|
||||
{
|
||||
/* JAN: TODO: MySQL 5.7
|
||||
ha_table_flags() & HA_ATTACHABLE_TRX_COMPATIBLE
|
||||
return(thd != NULL && thd_tx_is_dd_trx(thd));
|
||||
*/
|
||||
return false;
|
||||
}
|
||||
#endif /* UNIV_DEBUG */
|
||||
|
||||
/******************************************************************//**
|
||||
Check if the transaction is an auto-commit transaction. TRUE also
|
||||
implies that it is a SELECT (read-only) transaction.
|
||||
@ -2359,6 +2412,7 @@ innobase_strcasecmp(
|
||||
Compares NUL-terminated UTF-8 strings case insensitively. The
|
||||
second string contains wildcards.
|
||||
@return 0 if a match is found, 1 if not */
|
||||
static
|
||||
int
|
||||
innobase_wildcasecmp(
|
||||
/*=================*/
|
||||
@ -2620,6 +2674,7 @@ innobase_mysql_tmpfile(
|
||||
/*********************************************************************//**
|
||||
Wrapper around MySQL's copy_and_convert function.
|
||||
@return number of bytes copied to 'to' */
|
||||
static
|
||||
ulint
|
||||
innobase_convert_string(
|
||||
/*====================*/
|
||||
@ -3036,6 +3091,7 @@ Copy table flags from MySQL's HA_CREATE_INFO into an InnoDB table object.
|
||||
Those flags are stored in .frm file and end up in the MySQL table object,
|
||||
but are frequently used inside InnoDB so we keep their copies into the
|
||||
InnoDB table object. */
|
||||
static
|
||||
void
|
||||
innobase_copy_frm_flags_from_create_info(
|
||||
/*=====================================*/
|
||||
@ -3446,6 +3502,7 @@ and quote it.
|
||||
@param[in] idlen length of id, in bytes
|
||||
@param[in] thd MySQL connection thread, or NULL
|
||||
@return pointer to the end of buf */
|
||||
static
|
||||
char*
|
||||
innobase_convert_identifier(
|
||||
char* buf,
|
||||
@ -12090,6 +12147,7 @@ create_clustered_index_when_no_primary(
|
||||
/** Return a display name for the row format
|
||||
@param[in] row_format Row Format
|
||||
@return row format name */
|
||||
static
|
||||
const char*
|
||||
get_row_format_name(
|
||||
enum row_type row_format)
|
||||
@ -16567,11 +16625,6 @@ ha_innobase::external_lock(
|
||||
|
||||
TrxInInnoDB::begin_stmt(trx);
|
||||
|
||||
#ifdef UNIV_DEBUG
|
||||
if (thd_trx_is_dd_trx(thd)) {
|
||||
trx->is_dd_trx = true;
|
||||
}
|
||||
#endif /* UNIV_DEBUG */
|
||||
DBUG_RETURN(0);
|
||||
} else {
|
||||
|
||||
@ -16601,11 +16654,6 @@ ha_innobase::external_lock(
|
||||
if (trx_is_started(trx)) {
|
||||
|
||||
innobase_commit(ht, thd, TRUE);
|
||||
} else {
|
||||
/* Since the trx state is TRX_NOT_STARTED,
|
||||
trx_commit() will not be called. Reset
|
||||
trx->is_dd_trx here */
|
||||
ut_d(trx->is_dd_trx = false);
|
||||
}
|
||||
|
||||
} else if (trx->isolation_level <= TRX_ISO_READ_COMMITTED
|
||||
@ -17481,13 +17529,6 @@ ha_innobase::store_lock(
|
||||
++trx->will_lock;
|
||||
}
|
||||
|
||||
#ifdef UNIV_DEBUG
|
||||
if (trx->is_dd_trx) {
|
||||
ut_ad(trx->will_lock == 0
|
||||
&& m_prebuilt->select_lock_type == LOCK_NONE);
|
||||
}
|
||||
#endif /* UNIV_DEBUG */
|
||||
|
||||
return(to);
|
||||
}
|
||||
|
||||
@ -19732,14 +19773,14 @@ innobase_index_name_is_reserved(
|
||||
return(false);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
Retrieve the FTS Relevance Ranking result for doc with doc_id
|
||||
/** Retrieve the FTS Relevance Ranking result for doc with doc_id
|
||||
of m_prebuilt->fts_doc_id
|
||||
@param[in,out] fts_hdl FTS handler
|
||||
@return the relevance ranking value */
|
||||
static
|
||||
float
|
||||
innobase_fts_retrieve_ranking(
|
||||
/*============================*/
|
||||
FT_INFO * fts_hdl) /*!< in: FTS handler */
|
||||
FT_INFO* fts_hdl)
|
||||
{
|
||||
fts_result_t* result;
|
||||
row_prebuilt_t* ft_prebuilt;
|
||||
@ -19754,12 +19795,12 @@ innobase_fts_retrieve_ranking(
|
||||
return(ranking->rank);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
Free the memory for the FTS handler */
|
||||
/** Free the memory for the FTS handler
|
||||
@param[in,out] fts_hdl FTS handler */
|
||||
static
|
||||
void
|
||||
innobase_fts_close_ranking(
|
||||
/*=======================*/
|
||||
FT_INFO * fts_hdl)
|
||||
FT_INFO* fts_hdl)
|
||||
{
|
||||
fts_result_t* result;
|
||||
|
||||
@ -19768,20 +19809,15 @@ innobase_fts_close_ranking(
|
||||
fts_query_free_result(result);
|
||||
|
||||
my_free((uchar*) fts_hdl);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
Find and Retrieve the FTS Relevance Ranking result for doc with doc_id
|
||||
/** Find and Retrieve the FTS Relevance Ranking result for doc with doc_id
|
||||
of m_prebuilt->fts_doc_id
|
||||
@param[in,out] fts_hdl FTS handler
|
||||
@return the relevance ranking value */
|
||||
static
|
||||
float
|
||||
innobase_fts_find_ranking(
|
||||
/*======================*/
|
||||
FT_INFO* fts_hdl, /*!< in: FTS handler */
|
||||
uchar* record, /*!< in: Unused */
|
||||
uint len) /*!< in: Unused */
|
||||
innobase_fts_find_ranking(FT_INFO* fts_hdl, uchar*, uint)
|
||||
{
|
||||
fts_result_t* result;
|
||||
row_prebuilt_t* ft_prebuilt;
|
||||
@ -19945,35 +19981,13 @@ innodb_merge_threshold_set_all_debug_update(
|
||||
}
|
||||
#endif /* UNIV_DEBUG */
|
||||
|
||||
/***********************************************************************
|
||||
@return version of the extended FTS API */
|
||||
uint
|
||||
innobase_fts_get_version()
|
||||
/*======================*/
|
||||
{
|
||||
/* Currently this doesn't make much sense as returning
|
||||
HA_CAN_FULLTEXT_EXT automatically mean this version is supported.
|
||||
This supposed to ease future extensions. */
|
||||
return(2);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
@return Which part of the extended FTS API is supported */
|
||||
ulonglong
|
||||
innobase_fts_flags()
|
||||
/*================*/
|
||||
{
|
||||
return(FTS_ORDERED_RESULT | FTS_DOCID_IN_RESULT);
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
Find and Retrieve the FTS doc_id for the current result row
|
||||
/** Find and Retrieve the FTS doc_id for the current result row
|
||||
@param[in,out] fts_hdl FTS handler
|
||||
@return the document ID */
|
||||
static
|
||||
ulonglong
|
||||
innobase_fts_retrieve_docid(
|
||||
/*========================*/
|
||||
FT_INFO_EXT* fts_hdl) /*!< in: FTS handler */
|
||||
FT_INFO_EXT* fts_hdl)
|
||||
{
|
||||
fts_result_t* result;
|
||||
row_prebuilt_t* ft_prebuilt;
|
||||
@ -19992,23 +20006,6 @@ innobase_fts_retrieve_docid(
|
||||
return(ft_prebuilt->fts_doc_id);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
Find and retrieve the size of the current result
|
||||
@return number of matching rows */
|
||||
ulonglong
|
||||
innobase_fts_count_matches(
|
||||
/*=======================*/
|
||||
FT_INFO_EXT* fts_hdl) /*!< in: FTS handler */
|
||||
{
|
||||
NEW_FT_INFO* handle = reinterpret_cast<NEW_FT_INFO *>(fts_hdl);
|
||||
|
||||
if (handle->ft_result->rankings_by_id != 0) {
|
||||
return rbt_size(handle->ft_result->rankings_by_id);
|
||||
} else {
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
|
||||
/* These variables are never read by InnoDB or changed. They are a kind of
|
||||
dummies that are needed by the MySQL infrastructure to call
|
||||
buffer_pool_dump_now(), buffer_pool_load_now() and buffer_pool_load_abort()
|
||||
|
@ -829,30 +829,6 @@ private:
|
||||
ulint m_flags2;
|
||||
};
|
||||
|
||||
/**
|
||||
Retrieve the FTS Relevance Ranking result for doc with doc_id
|
||||
of prebuilt->fts_doc_id
|
||||
@return the relevance ranking value */
|
||||
float
|
||||
innobase_fts_retrieve_ranking(
|
||||
FT_INFO* fts_hdl); /*!< in: FTS handler */
|
||||
|
||||
/**
|
||||
Find and Retrieve the FTS Relevance Ranking result for doc with doc_id
|
||||
of prebuilt->fts_doc_id
|
||||
@return the relevance ranking value */
|
||||
float
|
||||
innobase_fts_find_ranking(
|
||||
FT_INFO* fts_hdl, /*!< in: FTS handler */
|
||||
uchar* record, /*!< in: Unused */
|
||||
uint len); /*!< in: Unused */
|
||||
|
||||
/**
|
||||
Free the memory for the FTS handler */
|
||||
void
|
||||
innobase_fts_close_ranking(
|
||||
FT_INFO* fts_hdl); /*!< in: FTS handler */
|
||||
|
||||
/**
|
||||
Initialize the table FTS stopword list
|
||||
@return TRUE if success */
|
||||
@ -895,42 +871,6 @@ innobase_fts_check_doc_id_index_in_def(
|
||||
const KEY* key_info) /*!< in: Key definitions */
|
||||
MY_ATTRIBUTE((warn_unused_result));
|
||||
|
||||
/**
|
||||
@return version of the extended FTS API */
|
||||
uint
|
||||
innobase_fts_get_version();
|
||||
|
||||
/**
|
||||
@return Which part of the extended FTS API is supported */
|
||||
ulonglong
|
||||
innobase_fts_flags();
|
||||
|
||||
/**
|
||||
Find and Retrieve the FTS doc_id for the current result row
|
||||
@return the document ID */
|
||||
ulonglong
|
||||
innobase_fts_retrieve_docid(
|
||||
/*========================*/
|
||||
FT_INFO_EXT* fts_hdl); /*!< in: FTS handler */
|
||||
|
||||
/**
|
||||
Find and retrieve the size of the current result
|
||||
@return number of matching rows */
|
||||
ulonglong
|
||||
innobase_fts_count_matches(
|
||||
/*=======================*/
|
||||
FT_INFO_EXT* fts_hdl); /*!< in: FTS handler */
|
||||
|
||||
/**
|
||||
Copy table flags from MySQL's HA_CREATE_INFO into an InnoDB table object.
|
||||
Those flags are stored in .frm file and end up in the MySQL table object,
|
||||
but are frequently used inside InnoDB so we keep their copies into the
|
||||
InnoDB table object. */
|
||||
void
|
||||
innobase_copy_frm_flags_from_create_info(
|
||||
dict_table_t* innodb_table, /*!< in/out: InnoDB table */
|
||||
const HA_CREATE_INFO* create_info); /*!< in: create info */
|
||||
|
||||
/**
|
||||
Copy table flags from MySQL's TABLE_SHARE into an InnoDB table object.
|
||||
Those flags are stored in .frm file and end up in the MySQL table object,
|
||||
|
@ -347,22 +347,6 @@ btr_pcur_move_to_next_page(
|
||||
btr_pcur_t* cursor, /*!< in: persistent cursor; must be on the
|
||||
last record of the current page */
|
||||
mtr_t* mtr); /*!< in: mtr */
|
||||
/*********************************************************//**
|
||||
Moves the persistent cursor backward if it is on the first record
|
||||
of the page. Releases the latch on the current page, and bufferunfixes
|
||||
it. Note that to prevent a possible deadlock, the operation first
|
||||
stores the position of the cursor, releases the leaf latch, acquires
|
||||
necessary latches and restores the cursor position again before returning.
|
||||
The alphabetical position of the cursor is guaranteed to be sensible
|
||||
on return, but it may happen that the cursor is not positioned on the
|
||||
last record of any page, because the structure of the tree may have
|
||||
changed while the cursor had no latches. */
|
||||
void
|
||||
btr_pcur_move_backward_from_page(
|
||||
/*=============================*/
|
||||
btr_pcur_t* cursor, /*!< in: persistent cursor, must be on the
|
||||
first record of the current page */
|
||||
mtr_t* mtr); /*!< in: mtr */
|
||||
#ifdef UNIV_DEBUG
|
||||
/*********************************************************//**
|
||||
Returns the btr cursor component of a persistent cursor.
|
||||
|
@ -382,11 +382,6 @@ buf_frame_will_withdrawn(
|
||||
buf_pool_t* buf_pool,
|
||||
const byte* ptr);
|
||||
|
||||
/** Resize the buffer pool based on srv_buf_pool_size from
|
||||
srv_buf_pool_old_size. */
|
||||
void
|
||||
buf_pool_resize();
|
||||
|
||||
/** This is the thread for resizing buffer pool. It waits for an event and
|
||||
when waked up either performs a resizing and sleeps again.
|
||||
@return this function does not return, calls os_thread_exit()
|
||||
@ -921,30 +916,18 @@ buf_stats_get_pool_info(
|
||||
ulint pool_id, /*!< in: buffer pool ID */
|
||||
buf_pool_info_t* all_pool_info); /*!< in/out: buffer pool info
|
||||
to fill */
|
||||
/*********************************************************************//**
|
||||
Returns the ratio in percents of modified pages in the buffer pool /
|
||||
/** Return the ratio in percents of modified pages in the buffer pool /
|
||||
database pages in the buffer pool.
|
||||
@return modified page percentage ratio */
|
||||
double
|
||||
buf_get_modified_ratio_pct(void);
|
||||
/*============================*/
|
||||
/**********************************************************************//**
|
||||
Refreshes the statistics used to print per-second averages. */
|
||||
void
|
||||
buf_refresh_io_stats(
|
||||
/*=================*/
|
||||
buf_pool_t* buf_pool); /*!< buffer pool instance */
|
||||
/**********************************************************************//**
|
||||
Refreshes the statistics used to print per-second averages. */
|
||||
/** Refresh the statistics used to print per-second averages. */
|
||||
void
|
||||
buf_refresh_io_stats_all(void);
|
||||
/*=================*/
|
||||
/*********************************************************************//**
|
||||
Asserts that all file pages in the buffer are in a replaceable state.
|
||||
/** Assert that all file pages in the buffer are in a replaceable state.
|
||||
@return TRUE */
|
||||
ibool
|
||||
buf_all_freed(void);
|
||||
/*===============*/
|
||||
/*********************************************************************//**
|
||||
Checks that there currently are no pending i/o-operations for the buffer
|
||||
pool.
|
||||
@ -1404,18 +1387,6 @@ buf_pool_watch_is_sentinel(
|
||||
const buf_page_t* bpage) /*!< in: block */
|
||||
MY_ATTRIBUTE((nonnull, warn_unused_result));
|
||||
|
||||
/** Add watch for the given page to be read in. Caller must have
|
||||
appropriate hash_lock for the bpage. This function may release the
|
||||
hash_lock and reacquire it.
|
||||
@param[in] page_id page id
|
||||
@param[in,out] hash_lock hash_lock currently latched
|
||||
@return NULL if watch set, block if the page is in the buffer pool */
|
||||
buf_page_t*
|
||||
buf_pool_watch_set(
|
||||
const page_id_t& page_id,
|
||||
rw_lock_t** hash_lock)
|
||||
MY_ATTRIBUTE((warn_unused_result));
|
||||
|
||||
/** Stop watching if the page has been read in.
|
||||
buf_pool_watch_set(space,offset) must have returned NULL before.
|
||||
@param[in] page_id page id */
|
||||
|
@ -252,26 +252,13 @@ DECLARE_THREAD(buf_flush_page_cleaner_worker)(
|
||||
/*==========================================*/
|
||||
void* arg); /*!< in: a dummy parameter required by
|
||||
os_thread_create */
|
||||
/******************************************************************//**
|
||||
Initialize page_cleaner. */
|
||||
/** Initialize page_cleaner. */
|
||||
void
|
||||
buf_flush_page_cleaner_init(void);
|
||||
/*=============================*/
|
||||
/*********************************************************************//**
|
||||
Clears up tail of the LRU lists:
|
||||
* Put replaceable pages at the tail of LRU to the free list
|
||||
* Flush dirty pages at the tail of LRU to the disk
|
||||
The depth to which we scan each buffer pool is controlled by dynamic
|
||||
config parameter innodb_LRU_scan_depth.
|
||||
@return total pages flushed */
|
||||
ulint
|
||||
buf_flush_LRU_lists(void);
|
||||
/*=====================*/
|
||||
/*********************************************************************//**
|
||||
Wait for any possible LRU flushes that are in progress to end. */
|
||||
|
||||
/** Wait for any possible LRU flushes that are in progress to end. */
|
||||
void
|
||||
buf_flush_wait_LRU_batch_end(void);
|
||||
/*==============================*/
|
||||
|
||||
#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
|
||||
/******************************************************************//**
|
||||
@ -333,14 +320,6 @@ buf_pool_get_dirty_pages_count(
|
||||
buf_pool_t* buf_pool, /*!< in: buffer pool */
|
||||
ulint id, /*!< in: space id to check */
|
||||
FlushObserver* observer); /*!< in: flush observer to check */
|
||||
/******************************************************************//**
|
||||
Check if there are any dirty pages that belong to a space id in the flush list.
|
||||
@return count of dirty pages present in all the buffer pools */
|
||||
ulint
|
||||
buf_flush_get_dirty_pages_count(
|
||||
/*============================*/
|
||||
ulint id, /*!< in: space id to check */
|
||||
FlushObserver* observer); /*!< in: flush observer to check */
|
||||
|
||||
/*******************************************************************//**
|
||||
Synchronously flush dirty blocks from the end of the flush list of all buffer
|
||||
|
@ -178,12 +178,6 @@ void
|
||||
buf_LRU_make_block_young(
|
||||
/*=====================*/
|
||||
buf_page_t* bpage); /*!< in: control block */
|
||||
/******************************************************************//**
|
||||
Moves a block to the end of the LRU list. */
|
||||
void
|
||||
buf_LRU_make_block_old(
|
||||
/*===================*/
|
||||
buf_page_t* bpage); /*!< in: control block */
|
||||
/**********************************************************************//**
|
||||
Updates buf_pool->LRU_old_ratio.
|
||||
@return updated old_pct */
|
||||
|
@ -472,14 +472,6 @@ dtuple_check_typed(
|
||||
/*===============*/
|
||||
const dtuple_t* tuple) /*!< in: tuple */
|
||||
MY_ATTRIBUTE((nonnull, warn_unused_result));
|
||||
/**********************************************************//**
|
||||
Checks that a data tuple is typed.
|
||||
@return TRUE if ok */
|
||||
ibool
|
||||
dtuple_check_typed_no_assert(
|
||||
/*=========================*/
|
||||
const dtuple_t* tuple) /*!< in: tuple */
|
||||
MY_ATTRIBUTE((nonnull, warn_unused_result));
|
||||
#ifdef UNIV_DEBUG
|
||||
/**********************************************************//**
|
||||
Validates the consistency of a tuple which must be complete, i.e,
|
||||
|
@ -534,12 +534,13 @@ ibool
|
||||
dtype_validate(
|
||||
/*===========*/
|
||||
const dtype_t* type); /*!< in: type struct to validate */
|
||||
/*********************************************************************//**
|
||||
Prints a data type structure. */
|
||||
#ifdef UNIV_DEBUG
|
||||
/** Print a data type structure.
|
||||
@param[in] type data type */
|
||||
void
|
||||
dtype_print(
|
||||
/*========*/
|
||||
const dtype_t* type); /*!< in: type */
|
||||
const dtype_t* type);
|
||||
#endif /* UNIV_DEBUG */
|
||||
|
||||
/* Structure for an SQL data type.
|
||||
If you add fields to this structure, be sure to initialize them everywhere.
|
||||
|
@ -498,16 +498,6 @@ dict_foreign_replace_index(
|
||||
to use table->col_names */
|
||||
const dict_index_t* index) /*!< in: index to be replaced */
|
||||
MY_ATTRIBUTE((nonnull(1,3), warn_unused_result));
|
||||
/**********************************************************************//**
|
||||
Determines whether a string starts with the specified keyword.
|
||||
@return TRUE if str starts with keyword */
|
||||
ibool
|
||||
dict_str_starts_with_keyword(
|
||||
/*=========================*/
|
||||
THD* thd, /*!< in: MySQL thread handle */
|
||||
const char* str, /*!< in: string to scan for keyword */
|
||||
const char* keyword) /*!< in: keyword to look for */
|
||||
MY_ATTRIBUTE((nonnull, warn_unused_result));
|
||||
/** Scans a table create SQL string and adds to the data dictionary
|
||||
the foreign key constraints declared in the string. This function
|
||||
should be called after the indexes for a table have been created.
|
||||
|
@ -93,98 +93,6 @@ dict_get_first_table_name_in_db(
|
||||
/*============================*/
|
||||
const char* name); /*!< in: database name which ends to '/' */
|
||||
|
||||
/********************************************************************//**
|
||||
Loads a table column definition from a SYS_COLUMNS record to
|
||||
dict_table_t.
|
||||
@return error message, or NULL on success */
|
||||
const char*
|
||||
dict_load_column_low(
|
||||
/*=================*/
|
||||
dict_table_t* table, /*!< in/out: table, could be NULL
|
||||
if we just populate a dict_column_t
|
||||
struct with information from
|
||||
a SYS_COLUMNS record */
|
||||
mem_heap_t* heap, /*!< in/out: memory heap
|
||||
for temporary storage */
|
||||
dict_col_t* column, /*!< out: dict_column_t to fill,
|
||||
or NULL if table != NULL */
|
||||
table_id_t* table_id, /*!< out: table id */
|
||||
const char** col_name, /*!< out: column name */
|
||||
const rec_t* rec, /*!< in: SYS_COLUMNS record */
|
||||
ulint* nth_v_col); /*!< out: if not NULL, this
|
||||
records the "n" of "nth" virtual
|
||||
column */
|
||||
|
||||
/** Loads a virtual column "mapping" (to base columns) information
|
||||
from a SYS_VIRTUAL record
|
||||
@param[in,out] table table
|
||||
@param[in,out] heap memory heap
|
||||
@param[in,out] column mapped base column's dict_column_t
|
||||
@param[in,out] table_id table id
|
||||
@param[in,out] pos virtual column position
|
||||
@param[in,out] base_pos base column position
|
||||
@param[in] rec SYS_VIRTUAL record
|
||||
@return error message, or NULL on success */
|
||||
const char*
|
||||
dict_load_virtual_low(
|
||||
dict_table_t* table,
|
||||
mem_heap_t* heap,
|
||||
dict_col_t** column,
|
||||
table_id_t* table_id,
|
||||
ulint* pos,
|
||||
ulint* base_pos,
|
||||
const rec_t* rec);
|
||||
/********************************************************************//**
|
||||
Loads an index definition from a SYS_INDEXES record to dict_index_t.
|
||||
If allocate=TRUE, we will create a dict_index_t structure and fill it
|
||||
accordingly. If allocated=FALSE, the dict_index_t will be supplied by
|
||||
the caller and filled with information read from the record. @return
|
||||
error message, or NULL on success */
|
||||
const char*
|
||||
dict_load_index_low(
|
||||
/*================*/
|
||||
byte* table_id, /*!< in/out: table id (8 bytes),
|
||||
an "in" value if allocate=TRUE
|
||||
and "out" when allocate=FALSE */
|
||||
const char* table_name, /*!< in: table name */
|
||||
mem_heap_t* heap, /*!< in/out: temporary memory heap */
|
||||
const rec_t* rec, /*!< in: SYS_INDEXES record */
|
||||
ibool allocate, /*!< in: TRUE=allocate *index,
|
||||
FALSE=fill in a pre-allocated
|
||||
*index */
|
||||
dict_index_t** index); /*!< out,own: index, or NULL */
|
||||
/********************************************************************//**
|
||||
Loads an index field definition from a SYS_FIELDS record to
|
||||
dict_index_t.
|
||||
@return error message, or NULL on success */
|
||||
const char*
|
||||
dict_load_field_low(
|
||||
/*================*/
|
||||
byte* index_id, /*!< in/out: index id (8 bytes)
|
||||
an "in" value if index != NULL
|
||||
and "out" if index == NULL */
|
||||
dict_index_t* index, /*!< in/out: index, could be NULL
|
||||
if we just populate a dict_field_t
|
||||
struct with information from
|
||||
a SYS_FIELDS record */
|
||||
dict_field_t* sys_field, /*!< out: dict_field_t to be
|
||||
filled */
|
||||
ulint* pos, /*!< out: Field position */
|
||||
byte* last_index_id, /*!< in: last index id */
|
||||
mem_heap_t* heap, /*!< in/out: memory heap
|
||||
for temporary storage */
|
||||
const rec_t* rec); /*!< in: SYS_FIELDS record */
|
||||
/********************************************************************//**
|
||||
Using the table->heap, copy the null-terminated filepath into
|
||||
table->data_dir_path and put a null byte before the extension.
|
||||
This allows SHOW CREATE TABLE to return the correct DATA DIRECTORY path.
|
||||
Make this data directory path only if it has not yet been saved. */
|
||||
void
|
||||
dict_save_data_dir_path(
|
||||
/*====================*/
|
||||
dict_table_t* table, /*!< in/out: table */
|
||||
char* filepath); /*!< in: filepath of tablespace */
|
||||
|
||||
/** Get the first filepath from SYS_DATAFILES for a given space_id.
|
||||
@param[in] space_id Tablespace ID
|
||||
@return First filepath (caller must invoke ut_free() on it)
|
||||
|
@ -54,17 +54,6 @@ enum dict_stats_upd_option_t {
|
||||
otherwise do nothing */
|
||||
};
|
||||
|
||||
/*********************************************************************//**
|
||||
Calculates new estimates for table and index statistics. This function
|
||||
is relatively quick and is used to calculate transient statistics that
|
||||
are not saved on disk.
|
||||
This was the only way to calculate statistics before the
|
||||
Persistent Statistics feature was introduced. */
|
||||
void
|
||||
dict_stats_update_transient(
|
||||
/*========================*/
|
||||
dict_table_t* table); /*!< in/out: table */
|
||||
|
||||
/*********************************************************************//**
|
||||
Set the persistent statistics flag for a given table. This is set only
|
||||
in the in-memory table object and is not saved on disk. It will be read
|
||||
|
@ -669,16 +669,6 @@ fsp_parse_init_file_page(
|
||||
byte* ptr, /*!< in: buffer */
|
||||
byte* end_ptr, /*!< in: buffer end */
|
||||
buf_block_t* block); /*!< in: block or NULL */
|
||||
#ifdef UNIV_DEBUG
|
||||
/*******************************************************************//**
|
||||
Validates a segment.
|
||||
@return TRUE if ok */
|
||||
ibool
|
||||
fseg_validate(
|
||||
/*==========*/
|
||||
fseg_header_t* header, /*!< in: segment header */
|
||||
mtr_t* mtr); /*!< in/out: mini-transaction */
|
||||
#endif /* UNIV_DEBUG */
|
||||
#ifdef UNIV_BTR_PRINT
|
||||
/*******************************************************************//**
|
||||
Writes info of a segment. */
|
||||
|
@ -180,14 +180,6 @@ fts_ast_node_print(
|
||||
/*===============*/
|
||||
fts_ast_node_t* node); /*!< in: ast node to print */
|
||||
/********************************************************************
|
||||
For tracking node allocations, in case there is an during parsing.*/
|
||||
extern
|
||||
void
|
||||
fts_ast_state_add_node(
|
||||
/*===================*/
|
||||
fts_ast_state_t*state, /*!< in: ast state instance */
|
||||
fts_ast_node_t* node); /*!< in: node to add to state */
|
||||
/********************************************************************
|
||||
Free node and expr allocations.*/
|
||||
extern
|
||||
void
|
||||
@ -217,18 +209,6 @@ fts_ast_visit(
|
||||
operator, currently we only
|
||||
ignore FTS_IGNORE operator */
|
||||
MY_ATTRIBUTE((nonnull, warn_unused_result));
|
||||
/*****************************************************************//**
|
||||
Process (nested) sub-expression, create a new result set to store the
|
||||
sub-expression result by processing nodes under current sub-expression
|
||||
list. Merge the sub-expression result with that of parent expression list.
|
||||
@return DB_SUCCESS if all went well */
|
||||
dberr_t
|
||||
fts_ast_visit_sub_exp(
|
||||
/*==================*/
|
||||
fts_ast_node_t* node, /*!< in: instance to traverse*/
|
||||
fts_ast_callback visitor, /*!< in: callback */
|
||||
void* arg) /*!< in: callback arg */
|
||||
MY_ATTRIBUTE((nonnull, warn_unused_result));
|
||||
/********************************************************************
|
||||
Create a lex instance.*/
|
||||
fts_lexer_t*
|
||||
@ -275,13 +255,6 @@ fts_ast_string_to_ul(
|
||||
const fts_ast_string_t* ast_str,
|
||||
int base);
|
||||
|
||||
/**
|
||||
Print the ast string
|
||||
@param[in] str string to print */
|
||||
void
|
||||
fts_ast_string_print(
|
||||
const fts_ast_string_t* ast_str);
|
||||
|
||||
/* String of length len.
|
||||
We always store the string of length len with a terminating '\0',
|
||||
regardless of there is any 0x00 in the string itself */
|
||||
@ -367,8 +340,6 @@ fts_ast_create_node_phrase_list(
|
||||
|
||||
#ifdef UNIV_DEBUG
|
||||
const char*
|
||||
fts_ast_oper_name_get(fts_ast_oper_t oper);
|
||||
const char*
|
||||
fts_ast_node_type_get(fts_ast_type_t type);
|
||||
#endif /* UNIV_DEBUG */
|
||||
|
||||
|
@ -663,6 +663,7 @@ void
|
||||
fts_startup(void);
|
||||
/*==============*/
|
||||
|
||||
#if 0 // TODO: Enable this in WL#6608
|
||||
/******************************************************************//**
|
||||
Signal FTS threads to initiate shutdown. */
|
||||
void
|
||||
@ -682,6 +683,7 @@ fts_shutdown(
|
||||
indexes */
|
||||
fts_t* fts); /*!< in: fts instance to
|
||||
shutdown */
|
||||
#endif
|
||||
|
||||
/******************************************************************//**
|
||||
Create an instance of fts_t.
|
||||
@ -714,13 +716,6 @@ void
|
||||
fts_optimize_init(void);
|
||||
/*====================*/
|
||||
|
||||
/**********************************************************************//**
|
||||
Check whether the work queue is initialized.
|
||||
@return TRUE if optimze queue is initialized. */
|
||||
ibool
|
||||
fts_optimize_is_init(void);
|
||||
/*======================*/
|
||||
|
||||
/****************************************************************//**
|
||||
Drops index ancillary tables for a FTS index
|
||||
@return DB_SUCCESS or error code */
|
||||
@ -773,13 +768,6 @@ fts_savepoint_release(
|
||||
trx_t* trx, /*!< in: transaction */
|
||||
const char* name); /*!< in: savepoint name */
|
||||
|
||||
/**********************************************************************//**
|
||||
Free the FTS cache. */
|
||||
void
|
||||
fts_cache_destroy(
|
||||
/*==============*/
|
||||
fts_cache_t* cache); /*!< in: cache*/
|
||||
|
||||
/** Clear cache.
|
||||
@param[in,out] cache fts cache */
|
||||
void
|
||||
@ -815,17 +803,6 @@ void
|
||||
fts_drop_orphaned_tables(void);
|
||||
/*==========================*/
|
||||
|
||||
/******************************************************************//**
|
||||
Since we do a horizontal split on the index table, we need to drop
|
||||
all the split tables.
|
||||
@return DB_SUCCESS or error code */
|
||||
dberr_t
|
||||
fts_drop_index_split_tables(
|
||||
/*========================*/
|
||||
trx_t* trx, /*!< in: transaction */
|
||||
dict_index_t* index) /*!< in: fts instance */
|
||||
MY_ATTRIBUTE((warn_unused_result));
|
||||
|
||||
/** Run SYNC on the table, i.e., write out data from the cache to the
|
||||
FTS auxiliary INDEX table and clear the cache at the end.
|
||||
@param[in,out] table fts table
|
||||
@ -975,14 +952,6 @@ fts_load_stopword(
|
||||
ibool reload); /*!< in: Whether it is during
|
||||
reload of FTS table */
|
||||
|
||||
/****************************************************************//**
|
||||
Create the vector of fts_get_doc_t instances.
|
||||
@return vector of fts_get_doc_t instances */
|
||||
ib_vector_t*
|
||||
fts_get_docs_create(
|
||||
/*================*/
|
||||
fts_cache_t* cache); /*!< in: fts cache */
|
||||
|
||||
/****************************************************************//**
|
||||
Read the rows from the FTS index
|
||||
@return DB_SUCCESS if OK */
|
||||
|
@ -232,30 +232,6 @@ fts_check_token(
|
||||
bool is_ngram,
|
||||
const CHARSET_INFO* cs);
|
||||
|
||||
/*******************************************************************//**
|
||||
Tokenize a document. */
|
||||
void
|
||||
fts_tokenize_document(
|
||||
/*==================*/
|
||||
fts_doc_t* doc, /*!< in/out: document to
|
||||
tokenize */
|
||||
fts_doc_t* result, /*!< out: if provided, save
|
||||
result tokens here */
|
||||
st_mysql_ftparser* parser);/* in: plugin fts parser */
|
||||
|
||||
/*******************************************************************//**
|
||||
Continue to tokenize a document. */
|
||||
void
|
||||
fts_tokenize_document_next(
|
||||
/*=======================*/
|
||||
fts_doc_t* doc, /*!< in/out: document to
|
||||
tokenize */
|
||||
ulint add_pos, /*!< in: add this position to all
|
||||
tokens from this tokenization */
|
||||
fts_doc_t* result, /*!< out: if provided, save
|
||||
result tokens here */
|
||||
st_mysql_ftparser* parser);/* in: plugin fts parser */
|
||||
|
||||
/******************************************************************//**
|
||||
Initialize a document. */
|
||||
void
|
||||
@ -302,16 +278,6 @@ fts_index_fetch_nodes(
|
||||
word, /*!< in: the word to fetch */
|
||||
fts_fetch_t* fetch); /*!< in: fetch callback.*/
|
||||
|
||||
/******************************************************************//**
|
||||
Create a fts_optimizer_word_t instance.
|
||||
@return new instance */
|
||||
fts_word_t*
|
||||
fts_word_init(
|
||||
/*==========*/
|
||||
fts_word_t* word, /*!< in: word to initialize */
|
||||
byte* utf8, /*!< in: UTF-8 string */
|
||||
ulint len); /*!< in: length of string in bytes */
|
||||
|
||||
/******************************************************************//**
|
||||
Compare two fts_trx_table_t instances, we actually compare the
|
||||
table id's here.
|
||||
@ -429,31 +395,7 @@ fts_config_set_index_value(
|
||||
config table */
|
||||
MY_ATTRIBUTE((warn_unused_result));
|
||||
|
||||
/******************************************************************//**
|
||||
Increment the value in the config table for column name.
|
||||
@return DB_SUCCESS or error code */
|
||||
dberr_t
|
||||
fts_config_increment_value(
|
||||
/*=======================*/
|
||||
trx_t* trx, /*!< transaction */
|
||||
fts_table_t* fts_table, /*!< in: the indexed FTS table */
|
||||
const char* name, /*!< in: increment config value
|
||||
for this parameter name */
|
||||
ulint delta) /*!< in: increment by this much */
|
||||
MY_ATTRIBUTE((warn_unused_result));
|
||||
|
||||
/******************************************************************//**
|
||||
Increment the per index value in the config table for column name.
|
||||
@return DB_SUCCESS or error code */
|
||||
dberr_t
|
||||
fts_config_increment_index_value(
|
||||
/*=============================*/
|
||||
trx_t* trx, /*!< transaction */
|
||||
dict_index_t* index, /*!< in: FTS index */
|
||||
const char* name, /*!< in: increment config value
|
||||
for this parameter name */
|
||||
ulint delta); /*!< in: increment by this much */
|
||||
|
||||
#ifdef FTS_OPTIMIZE_DEBUG
|
||||
/******************************************************************//**
|
||||
Get an ulint value from the config table.
|
||||
@return DB_SUCCESS or error code */
|
||||
@ -465,6 +407,7 @@ fts_config_get_index_ulint(
|
||||
const char* name, /*!< in: param name */
|
||||
ulint* int_value) /*!< out: value */
|
||||
MY_ATTRIBUTE((warn_unused_result));
|
||||
#endif /* FTS_OPTIMIZE_DEBUG */
|
||||
|
||||
/******************************************************************//**
|
||||
Set an ulint value int the config table.
|
||||
@ -501,17 +444,6 @@ fts_cache_find_word(
|
||||
text) /*!< in: word to search for */
|
||||
MY_ATTRIBUTE((warn_unused_result));
|
||||
|
||||
/******************************************************************//**
|
||||
Check cache for deleted doc id.
|
||||
@return TRUE if deleted */
|
||||
ibool
|
||||
fts_cache_is_deleted_doc_id(
|
||||
/*========================*/
|
||||
const fts_cache_t*
|
||||
cache, /*!< in: cache ito search */
|
||||
doc_id_t doc_id) /*!< in: doc id to search for */
|
||||
MY_ATTRIBUTE((warn_unused_result));
|
||||
|
||||
/******************************************************************//**
|
||||
Append deleted doc ids to vector and sort the vector. */
|
||||
void
|
||||
@ -533,18 +465,6 @@ fts_wait_for_background_thread_to_start(
|
||||
ulint max_wait); /*!< in: time in microseconds, if set
|
||||
to 0 then it disables timeout
|
||||
checking */
|
||||
#ifdef FTS_DOC_STATS_DEBUG
|
||||
/******************************************************************//**
|
||||
Get the total number of words in the FTS for a particular FTS index.
|
||||
@return DB_SUCCESS or error code */
|
||||
dberr_t
|
||||
fts_get_total_word_count(
|
||||
/*=====================*/
|
||||
trx_t* trx, /*!< in: transaction */
|
||||
dict_index_t* index, /*!< in: for this index */
|
||||
ulint* total) /*!< out: total words */
|
||||
MY_ATTRIBUTE((warn_unused_result));
|
||||
#endif
|
||||
/******************************************************************//**
|
||||
Search the index specific cache for a particular FTS index.
|
||||
@return the index specific cache else NULL */
|
||||
@ -602,13 +522,6 @@ fts_optimize_add_table(
|
||||
/*===================*/
|
||||
dict_table_t* table); /*!< in: table to add */
|
||||
|
||||
/******************************************************************//**
|
||||
Optimize a table. */
|
||||
void
|
||||
fts_optimize_do_table(
|
||||
/*==================*/
|
||||
dict_table_t* table); /*!< in: table to optimize */
|
||||
|
||||
/******************************************************************//**
|
||||
Construct the prefix name of an FTS table.
|
||||
@return own: table name, must be freed with ut_free() */
|
||||
|
@ -74,24 +74,6 @@ flst_add_first(
|
||||
flst_node_t* node, /*!< in: node to add */
|
||||
mtr_t* mtr); /*!< in: mini-transaction handle */
|
||||
/********************************************************************//**
|
||||
Inserts a node after another in a list. */
|
||||
void
|
||||
flst_insert_after(
|
||||
/*==============*/
|
||||
flst_base_node_t* base, /*!< in: pointer to base node of list */
|
||||
flst_node_t* node1, /*!< in: node to insert after */
|
||||
flst_node_t* node2, /*!< in: node to add */
|
||||
mtr_t* mtr); /*!< in: mini-transaction handle */
|
||||
/********************************************************************//**
|
||||
Inserts a node before another in a list. */
|
||||
void
|
||||
flst_insert_before(
|
||||
/*===============*/
|
||||
flst_base_node_t* base, /*!< in: pointer to base node of list */
|
||||
flst_node_t* node2, /*!< in: node to insert */
|
||||
flst_node_t* node3, /*!< in: node to insert before */
|
||||
mtr_t* mtr); /*!< in: mini-transaction handle */
|
||||
/********************************************************************//**
|
||||
Removes a node. */
|
||||
void
|
||||
flst_remove(
|
||||
@ -168,14 +150,6 @@ flst_validate(
|
||||
/*==========*/
|
||||
const flst_base_node_t* base, /*!< in: pointer to base node of list */
|
||||
mtr_t* mtr1); /*!< in: mtr */
|
||||
/********************************************************************//**
|
||||
Prints info of a file-based list. */
|
||||
void
|
||||
flst_print(
|
||||
/*=======*/
|
||||
const flst_base_node_t* base, /*!< in: pointer to base node of list */
|
||||
mtr_t* mtr); /*!< in: mtr */
|
||||
|
||||
|
||||
#include "fut0lst.ic"
|
||||
|
||||
|
@ -143,20 +143,6 @@ rtr_pcur_move_to_next(
|
||||
/*!< in: current level */
|
||||
mtr_t* mtr); /*!< in: mtr */
|
||||
|
||||
/**************************************************************//**
|
||||
Restores the stored position of a persistent cursor bufferfixing the page */
|
||||
bool
|
||||
rtr_cur_restore_position_func(
|
||||
/*==========================*/
|
||||
ulint latch_mode, /*!< in: BTR_SEARCH_LEAF, ... */
|
||||
btr_cur_t* cursor, /*!< in: detached persistent cursor */
|
||||
ulint level, /*!< in: index level */
|
||||
const char* file, /*!< in: file name */
|
||||
unsigned line, /*!< in: line where called */
|
||||
mtr_t* mtr); /*!< in: mtr */
|
||||
#define rtr_cur_restore_position(l,cur,level,mtr) \
|
||||
rtr_cur_restore_position_func(l,cur,level,__FILE__,__LINE__,mtr)
|
||||
|
||||
/****************************************************************//**
|
||||
Searches the right position in rtree for a page cursor. */
|
||||
bool
|
||||
@ -318,9 +304,6 @@ rtr_get_mbr_from_tuple(
|
||||
const dtuple_t* dtuple, /*!< in: data tuple */
|
||||
rtr_mbr* mbr); /*!< out: mbr to fill */
|
||||
|
||||
#define rtr_page_get_father_node_ptr(of,heap,sea,cur,mtr) \
|
||||
rtr_page_get_father_node_ptr_func(of,heap,sea,cur,__FILE__,__LINE__,mtr)
|
||||
|
||||
/* Get the rtree page father.
|
||||
@param[in] offsets work area for the return value
|
||||
@param[in] index rtree index
|
||||
@ -338,24 +321,6 @@ rtr_page_get_father(
|
||||
btr_cur_t* sea_cur,
|
||||
btr_cur_t* cursor);
|
||||
|
||||
/************************************************************//**
|
||||
Returns the upper level node pointer to a R-Tree page. It is assumed
|
||||
that mtr holds an x-latch on the tree.
|
||||
@return rec_get_offsets() of the node pointer record */
|
||||
ulint*
|
||||
rtr_page_get_father_node_ptr_func(
|
||||
/*==============================*/
|
||||
ulint* offsets,/*!< in: work area for the return value */
|
||||
mem_heap_t* heap, /*!< in: memory heap to use */
|
||||
btr_cur_t* sea_cur,/*!< in: search cursor */
|
||||
btr_cur_t* cursor, /*!< in: cursor pointing to user record,
|
||||
out: cursor on node pointer record,
|
||||
its page x-latched */
|
||||
const char* file, /*!< in: file name */
|
||||
unsigned line, /*!< in: line where called */
|
||||
mtr_t* mtr); /*!< in: mtr */
|
||||
|
||||
|
||||
/************************************************************//**
|
||||
Returns the father block to a page. It is assumed that mtr holds
|
||||
an X or SX latch on the tree.
|
||||
|
@ -36,9 +36,6 @@ simple headers.
|
||||
|
||||
/* Forward declarations */
|
||||
class THD;
|
||||
class Field;
|
||||
struct fts_string_t;
|
||||
//typedef struct charset_info_st CHARSET_INFO;
|
||||
|
||||
// JAN: TODO missing features:
|
||||
#undef MYSQL_57_SELECT_COUNT_OPTIMIZATION
|
||||
@ -50,23 +47,6 @@ struct fts_string_t;
|
||||
#undef MYSQL_SPATIAL_INDEX
|
||||
#undef MYSQL_STORE_FTS_DOC_ID
|
||||
|
||||
/*********************************************************************//**
|
||||
Wrapper around MySQL's copy_and_convert function.
|
||||
@return number of bytes copied to 'to' */
|
||||
ulint
|
||||
innobase_convert_string(
|
||||
/*====================*/
|
||||
void* to, /*!< out: converted string */
|
||||
ulint to_length, /*!< in: number of bytes reserved
|
||||
for the converted string */
|
||||
CHARSET_INFO* to_cs, /*!< in: character set to convert to */
|
||||
const void* from, /*!< in: string to convert */
|
||||
ulint from_length, /*!< in: number of bytes to convert */
|
||||
CHARSET_INFO* from_cs, /*!< in: character set to convert
|
||||
from */
|
||||
uint* errors); /*!< out: number of errors encountered
|
||||
during the conversion */
|
||||
|
||||
/*******************************************************************//**
|
||||
Formats the raw data in "data" (in InnoDB on-disk format) that is of
|
||||
type DATA_(CHAR|VARCHAR|MYSQL|VARMYSQL) using "charset_coll" and writes
|
||||
@ -208,16 +188,6 @@ innobase_strcasecmp(
|
||||
const char* a, /*!< in: first string to compare */
|
||||
const char* b); /*!< in: second string to compare */
|
||||
|
||||
/******************************************************************//**
|
||||
Compares NUL-terminated UTF-8 strings case insensitively. The
|
||||
second string contains wildcards.
|
||||
@return 0 if a match is found, 1 if not */
|
||||
int
|
||||
innobase_wildcasecmp(
|
||||
/*=================*/
|
||||
const char* a, /*!< in: string to compare */
|
||||
const char* b); /*!< in: wildcard string to compare */
|
||||
|
||||
/** Strip dir name from a full path name and return only the file name
|
||||
@param[in] path_name full path name
|
||||
@return file name or "null" if no file name */
|
||||
|
@ -448,68 +448,6 @@ hash_lock_x_confirm(
|
||||
ulint fold);
|
||||
|
||||
/************************************************************//**
|
||||
Reserves the mutex for a fold value in a hash table. */
|
||||
void
|
||||
hash_mutex_enter(
|
||||
/*=============*/
|
||||
hash_table_t* table, /*!< in: hash table */
|
||||
ulint fold); /*!< in: fold */
|
||||
/************************************************************//**
|
||||
Releases the mutex for a fold value in a hash table. */
|
||||
void
|
||||
hash_mutex_exit(
|
||||
/*============*/
|
||||
hash_table_t* table, /*!< in: hash table */
|
||||
ulint fold); /*!< in: fold */
|
||||
/************************************************************//**
|
||||
Reserves all the mutexes of a hash table, in an ascending order. */
|
||||
void
|
||||
hash_mutex_enter_all(
|
||||
/*=================*/
|
||||
hash_table_t* table); /*!< in: hash table */
|
||||
/************************************************************//**
|
||||
Releases all the mutexes of a hash table. */
|
||||
void
|
||||
hash_mutex_exit_all(
|
||||
/*================*/
|
||||
hash_table_t* table); /*!< in: hash table */
|
||||
/************************************************************//**
|
||||
Releases all but the passed in mutex of a hash table. */
|
||||
void
|
||||
hash_mutex_exit_all_but(
|
||||
/*====================*/
|
||||
hash_table_t* table, /*!< in: hash table */
|
||||
ib_mutex_t* keep_mutex); /*!< in: mutex to keep */
|
||||
/************************************************************//**
|
||||
s-lock a lock for a fold value in a hash table. */
|
||||
void
|
||||
hash_lock_s(
|
||||
/*========*/
|
||||
hash_table_t* table, /*!< in: hash table */
|
||||
ulint fold); /*!< in: fold */
|
||||
/************************************************************//**
|
||||
x-lock a lock for a fold value in a hash table. */
|
||||
void
|
||||
hash_lock_x(
|
||||
/*========*/
|
||||
hash_table_t* table, /*!< in: hash table */
|
||||
ulint fold); /*!< in: fold */
|
||||
/************************************************************//**
|
||||
unlock an s-lock for a fold value in a hash table. */
|
||||
void
|
||||
hash_unlock_s(
|
||||
/*==========*/
|
||||
|
||||
hash_table_t* table, /*!< in: hash table */
|
||||
ulint fold); /*!< in: fold */
|
||||
/************************************************************//**
|
||||
unlock x-lock for a fold value in a hash table. */
|
||||
void
|
||||
hash_unlock_x(
|
||||
/*==========*/
|
||||
hash_table_t* table, /*!< in: hash table */
|
||||
ulint fold); /*!< in: fold */
|
||||
/************************************************************//**
|
||||
Reserves all the locks of a hash table, in an ascending order. */
|
||||
void
|
||||
hash_lock_x_all(
|
||||
|
@ -325,55 +325,6 @@ lock_rec_enqueue_waiting(
|
||||
que_thr_t* thr, /*!< in: query thread */
|
||||
lock_prdt_t* prdt); /*!< in: Minimum Bounding Box */
|
||||
|
||||
/*************************************************************//**
|
||||
Removes a record lock request, waiting or granted, from the queue and
|
||||
grants locks to other transactions in the queue if they now are entitled
|
||||
to a lock. NOTE: all record locks contained in in_lock are removed. */
|
||||
void
|
||||
lock_rec_dequeue_from_page(
|
||||
/*=======================*/
|
||||
lock_t* in_lock); /*!< in: record lock object: all
|
||||
record locks which are contained in
|
||||
this lock object are removed;
|
||||
transactions waiting behind will
|
||||
get their lock requests granted,
|
||||
if they are now qualified to it */
|
||||
|
||||
/*************************************************************//**
|
||||
Moves the locks of a record to another record and resets the lock bits of
|
||||
the donating record. */
|
||||
UNIV_INLINE
|
||||
void
|
||||
lock_rec_move(
|
||||
/*==========*/
|
||||
const buf_block_t* receiver, /*!< in: buffer block containing
|
||||
the receiving record */
|
||||
const buf_block_t* donator, /*!< in: buffer block containing
|
||||
the donating record */
|
||||
ulint receiver_heap_no,/*!< in: heap_no of the record
|
||||
which gets the locks; there
|
||||
must be no lock requests
|
||||
on it! */
|
||||
ulint donator_heap_no);/*!< in: heap_no of the record
|
||||
which gives the locks */
|
||||
|
||||
/*************************************************************//**
|
||||
Moves the locks of a record to another record and resets the lock bits of
|
||||
the donating record. */
|
||||
void
|
||||
lock_rec_move_low(
|
||||
/*==============*/
|
||||
hash_table_t* lock_hash, /*!< in: hash table to use */
|
||||
const buf_block_t* receiver, /*!< in: buffer block containing
|
||||
the receiving record */
|
||||
const buf_block_t* donator, /*!< in: buffer block containing
|
||||
the donating record */
|
||||
ulint receiver_heap_no,/*!< in: heap_no of the record
|
||||
which gets the locks; there
|
||||
must be no lock requests
|
||||
on it! */
|
||||
ulint donator_heap_no);/*!< in: heap_no of the record
|
||||
which gives the locks */
|
||||
/*********************************************************************//**
|
||||
Checks if locks of other transactions prevent an immediate modify (update,
|
||||
delete mark, or delete unmark) of a clustered index record. If they do,
|
||||
@ -683,20 +634,6 @@ lock_report_trx_id_insanity(
|
||||
const ulint* offsets, /*!< in: rec_get_offsets(rec, index) */
|
||||
trx_id_t max_trx_id); /*!< in: trx_sys_get_max_trx_id() */
|
||||
/*********************************************************************//**
|
||||
Prints info of a table lock. */
|
||||
void
|
||||
lock_table_print(
|
||||
/*=============*/
|
||||
FILE* file, /*!< in: file where to print */
|
||||
const lock_t* lock); /*!< in: table type lock */
|
||||
/*********************************************************************//**
|
||||
Prints info of a record lock. */
|
||||
void
|
||||
lock_rec_print(
|
||||
/*===========*/
|
||||
FILE* file, /*!< in: file where to print */
|
||||
const lock_t* lock); /*!< in: record type lock */
|
||||
/*********************************************************************//**
|
||||
Prints info of locks for all transactions.
|
||||
@return FALSE if not able to obtain lock mutex and exits without
|
||||
printing info */
|
||||
|
@ -91,28 +91,6 @@ lock_get_min_heap_no(
|
||||
}
|
||||
}
|
||||
|
||||
/*************************************************************//**
|
||||
Moves the locks of a record to another record and resets the lock bits of
|
||||
the donating record. */
|
||||
UNIV_INLINE
|
||||
void
|
||||
lock_rec_move(
|
||||
/*==========*/
|
||||
const buf_block_t* receiver, /*!< in: buffer block containing
|
||||
the receiving record */
|
||||
const buf_block_t* donator, /*!< in: buffer block containing
|
||||
the donating record */
|
||||
ulint receiver_heap_no,/*!< in: heap_no of the record
|
||||
which gets the locks; there
|
||||
must be no lock requests
|
||||
on it! */
|
||||
ulint donator_heap_no)/*!< in: heap_no of the record
|
||||
which gives the locks */
|
||||
{
|
||||
lock_rec_move_low(lock_sys->rec_hash, receiver, donator,
|
||||
receiver_heap_no, donator_heap_no);
|
||||
}
|
||||
|
||||
/*************************************************************//**
|
||||
Get the lock hash table */
|
||||
UNIV_INLINE
|
||||
|
@ -65,16 +65,6 @@ lock_place_prdt_page_lock(
|
||||
dict_index_t* index, /*!< in: secondary index */
|
||||
que_thr_t* thr); /*!< in: query thread */
|
||||
|
||||
/*********************************************************************//**
|
||||
Checks two predicate locks are compatible with each other
|
||||
@return true if conflicts */
|
||||
bool
|
||||
lock_prdt_consistent(
|
||||
/*=================*/
|
||||
lock_prdt_t* prdt1, /*!< in: Predicate for the lock */
|
||||
lock_prdt_t* prdt2, /*!< in: Predicate for the lock */
|
||||
ulint op); /*!< in: Predicate comparison operator */
|
||||
|
||||
/*********************************************************************//**
|
||||
Initiate a Predicate lock from a MBR */
|
||||
void
|
||||
|
@ -52,22 +52,6 @@ typedef ulint (*log_checksum_func_t)(const byte* log_block);
|
||||
log_sys->mutex. */
|
||||
extern log_checksum_func_t log_checksum_algorithm_ptr;
|
||||
|
||||
/*******************************************************************//**
|
||||
Calculates where in log files we find a specified lsn.
|
||||
@return log file number */
|
||||
ulint
|
||||
log_calc_where_lsn_is(
|
||||
/*==================*/
|
||||
int64_t* log_file_offset, /*!< out: offset in that file
|
||||
(including the header) */
|
||||
ib_uint64_t first_header_lsn, /*!< in: first log file start
|
||||
lsn */
|
||||
ib_uint64_t lsn, /*!< in: lsn whose position to
|
||||
determine */
|
||||
ulint n_log_files, /*!< in: total number of log
|
||||
files */
|
||||
int64_t log_file_size); /*!< in: log file size
|
||||
(including the header) */
|
||||
/** Append a string to the log.
|
||||
@param[in] str string
|
||||
@param[in] len string length
|
||||
@ -281,14 +265,6 @@ log_group_set_fields(
|
||||
log_group_t* group, /*!< in/out: group */
|
||||
lsn_t lsn); /*!< in: lsn for which the values should be
|
||||
set */
|
||||
/******************************************************//**
|
||||
Calculates the data capacity of a log group, when the log file headers are not
|
||||
included.
|
||||
@return capacity in bytes */
|
||||
lsn_t
|
||||
log_group_get_capacity(
|
||||
/*===================*/
|
||||
const log_group_t* group); /*!< in: log group */
|
||||
/************************************************************//**
|
||||
Gets a log block flush bit.
|
||||
@return TRUE if this block was the first to be written in a log flush */
|
||||
|
@ -941,16 +941,6 @@ rec_print_old(
|
||||
const rec_t* rec) /*!< in: physical record */
|
||||
MY_ATTRIBUTE((nonnull));
|
||||
/***************************************************************//**
|
||||
Prints a physical record in ROW_FORMAT=COMPACT. Ignores the
|
||||
record header. */
|
||||
void
|
||||
rec_print_comp(
|
||||
/*===========*/
|
||||
FILE* file, /*!< in: file where to print */
|
||||
const rec_t* rec, /*!< in: physical record */
|
||||
const ulint* offsets)/*!< in: array returned by rec_get_offsets() */
|
||||
MY_ATTRIBUTE((nonnull));
|
||||
/***************************************************************//**
|
||||
Prints a spatial index record. */
|
||||
void
|
||||
rec_print_mbr_rec(
|
||||
|
@ -223,45 +223,18 @@ row_fts_free_pll_merge_buf(
|
||||
fts_psort_t* psort_info); /*!< in: parallel sort info */
|
||||
|
||||
/*********************************************************************//**
|
||||
Function performs parallel tokenization of the incoming doc strings.
|
||||
@return OS_THREAD_DUMMY_RETURN */
|
||||
os_thread_ret_t
|
||||
fts_parallel_tokenization(
|
||||
/*======================*/
|
||||
void* arg); /*!< in: psort_info for the thread */
|
||||
/*********************************************************************//**
|
||||
Start the parallel tokenization and parallel merge sort */
|
||||
void
|
||||
row_fts_start_psort(
|
||||
/*================*/
|
||||
fts_psort_t* psort_info); /*!< in: parallel sort info */
|
||||
/*********************************************************************//**
|
||||
Function performs the merge and insertion of the sorted records.
|
||||
@return OS_THREAD_DUMMY_RETURN */
|
||||
os_thread_ret_t
|
||||
fts_parallel_merge(
|
||||
/*===============*/
|
||||
void* arg); /*!< in: parallel merge info */
|
||||
/*********************************************************************//**
|
||||
Kick off the parallel merge and insert thread */
|
||||
void
|
||||
row_fts_start_parallel_merge(
|
||||
/*=========================*/
|
||||
fts_psort_t* merge_info); /*!< in: parallel sort info */
|
||||
/********************************************************************//**
|
||||
Read sorted FTS data files and insert data tuples to auxillary tables.
|
||||
@return DB_SUCCESS or error number */
|
||||
void
|
||||
row_fts_insert_tuple(
|
||||
/*=================*/
|
||||
fts_psort_insert_t*
|
||||
ins_ctx, /*!< in: insert context */
|
||||
fts_tokenizer_word_t* word, /*!< in: last processed
|
||||
tokenized word */
|
||||
ib_vector_t* positions, /*!< in: word position */
|
||||
doc_id_t* in_doc_id, /*!< in: last item doc id */
|
||||
dtuple_t* dtuple); /*!< in: entry to insert */
|
||||
/********************************************************************//**
|
||||
Propagate a newly added record up one level in the selection tree
|
||||
@return parent where this value propagated to */
|
||||
int
|
||||
|
@ -138,31 +138,6 @@ row_ins_index_entry_set_vals(
|
||||
dtuple_t* entry,
|
||||
const dtuple_t* row);
|
||||
|
||||
/***************************************************************//**
|
||||
Tries to insert the externally stored fields (off-page columns)
|
||||
of a clustered index entry.
|
||||
@return DB_SUCCESS or DB_OUT_OF_FILE_SPACE */
|
||||
dberr_t
|
||||
row_ins_index_entry_big_rec_func(
|
||||
/*=============================*/
|
||||
const dtuple_t* entry, /*!< in/out: index entry to insert */
|
||||
const big_rec_t* big_rec,/*!< in: externally stored fields */
|
||||
ulint* offsets,/*!< in/out: rec offsets */
|
||||
mem_heap_t** heap, /*!< in/out: memory heap */
|
||||
dict_index_t* index, /*!< in: index */
|
||||
const char* file, /*!< in: file name of caller */
|
||||
#ifndef DBUG_OFF
|
||||
const void* thd, /*!< in: connection, or NULL */
|
||||
#endif /* DBUG_OFF */
|
||||
unsigned line) /*!< in: line number of caller */
|
||||
MY_ATTRIBUTE((nonnull(1,2,3,4,5,6), warn_unused_result));
|
||||
#ifdef DBUG_OFF
|
||||
# define row_ins_index_entry_big_rec(e,big,ofs,heap,index,thd,file,line) \
|
||||
row_ins_index_entry_big_rec_func(e,big,ofs,heap,index,file,line)
|
||||
#else /* DBUG_OFF */
|
||||
# define row_ins_index_entry_big_rec(e,big,ofs,heap,index,thd,file,line) \
|
||||
row_ins_index_entry_big_rec_func(e,big,ofs,heap,index,file,thd,line)
|
||||
#endif /* DBUG_OFF */
|
||||
/***************************************************************//**
|
||||
Inserts an entry into a clustered index. Tries first optimistic,
|
||||
then pessimistic descent down the tree. If the entry matches enough
|
||||
|
@ -119,18 +119,6 @@ row_mysql_store_geometry(
|
||||
is SQL NULL this should be 0; remember
|
||||
also to set the NULL bit in the MySQL record
|
||||
header! */
|
||||
/*******************************************************************//**
|
||||
Reads a reference to a geometry data in the MySQL format.
|
||||
@return pointer to geometry data */
|
||||
const byte*
|
||||
row_mysql_read_geometry(
|
||||
/*====================*/
|
||||
ulint* len, /*!< out: geometry data length */
|
||||
const byte* ref, /*!< in: reference in the
|
||||
MySQL format */
|
||||
ulint col_len) /*!< in: BLOB reference length
|
||||
(not BLOB length) */
|
||||
MY_ATTRIBUTE((nonnull(1,2), warn_unused_result));
|
||||
/**************************************************************//**
|
||||
Pad a column with spaces. */
|
||||
void
|
||||
@ -570,17 +558,6 @@ void
|
||||
row_mysql_close(void);
|
||||
/*=================*/
|
||||
|
||||
/*********************************************************************//**
|
||||
Reassigns the table identifier of a table.
|
||||
@return error code or DB_SUCCESS */
|
||||
dberr_t
|
||||
row_mysql_table_id_reassign(
|
||||
/*========================*/
|
||||
dict_table_t* table, /*!< in/out: table */
|
||||
trx_t* trx, /*!< in/out: transaction */
|
||||
table_id_t* new_id) /*!< out: new table id */
|
||||
MY_ATTRIBUTE((nonnull, warn_unused_result));
|
||||
|
||||
/* A struct describing a place for an individual column in the MySQL
|
||||
row format which is presented to the table handler in ha_innobase.
|
||||
This template struct is used to speed up row transformations between
|
||||
|
@ -92,14 +92,6 @@ que_thr_t*
|
||||
fetch_step(
|
||||
/*=======*/
|
||||
que_thr_t* thr); /*!< in: query thread */
|
||||
/****************************************************************//**
|
||||
Sample callback function for fetch that prints each row.
|
||||
@return always returns non-NULL */
|
||||
void*
|
||||
row_fetch_print(
|
||||
/*============*/
|
||||
void* row, /*!< in: sel_node_t* */
|
||||
void* user_arg); /*!< in: not used */
|
||||
/***********************************************************//**
|
||||
Prints a row in a select result.
|
||||
@return query thread to run next or NULL */
|
||||
@ -407,9 +399,7 @@ struct fetch_node_t{
|
||||
further rows and the cursor is
|
||||
modified so (cursor % NOTFOUND) is
|
||||
true. If it returns not-NULL,
|
||||
continue normally. See
|
||||
row_fetch_print() for an example
|
||||
(and a useful debugging tool). */
|
||||
continue normally. */
|
||||
};
|
||||
|
||||
/** Open or close cursor operation type */
|
||||
|
@ -76,13 +76,6 @@ Shuts down background threads that can generate undo pages. */
|
||||
void
|
||||
srv_shutdown_bg_undo_sources(void);
|
||||
|
||||
/********************************************************************
|
||||
Signal all per-table background threads to shutdown, and wait for them to do
|
||||
so. */
|
||||
void
|
||||
srv_shutdown_table_bg_threads(void);
|
||||
/*=============================*/
|
||||
|
||||
/*************************************************************//**
|
||||
Copy the file path component of the physical file to parameter. It will
|
||||
copy up to and including the terminating path separator.
|
||||
|
@ -93,13 +93,6 @@ sync_array_print_long_waits(
|
||||
os_thread_id_t* waiter, /*!< out: longest waiting thread */
|
||||
const void** sema); /*!< out: longest-waited-for semaphore */
|
||||
|
||||
/********************************************************************//**
|
||||
Validates the integrity of the wait array. Checks
|
||||
that the number of reserved cells equals the count variable. */
|
||||
void
|
||||
sync_array_validate(
|
||||
sync_array_t* arr); /*!< in: sync wait array */
|
||||
|
||||
/**********************************************************************//**
|
||||
Prints info of the wait array. */
|
||||
void
|
||||
|
@ -537,24 +537,11 @@ rw_lock_is_locked(
|
||||
RW_LOCK_X or RW_LOCK_SX */
|
||||
#ifdef UNIV_DEBUG
|
||||
/***************************************************************//**
|
||||
Prints debug info of an rw-lock. */
|
||||
void
|
||||
rw_lock_print(
|
||||
/*==========*/
|
||||
rw_lock_t* lock); /*!< in: rw-lock */
|
||||
/***************************************************************//**
|
||||
Prints debug info of currently locked rw-locks. */
|
||||
void
|
||||
rw_lock_list_print_info(
|
||||
/*====================*/
|
||||
FILE* file); /*!< in: file where to print */
|
||||
/***************************************************************//**
|
||||
Returns the number of currently locked rw-locks.
|
||||
Works only in the debug version.
|
||||
@return number of locked rw-locks */
|
||||
ulint
|
||||
rw_lock_n_locked(void);
|
||||
/*==================*/
|
||||
|
||||
/*#####################################################################*/
|
||||
|
||||
|
@ -117,15 +117,6 @@ trx_undo_rec_get_row_ref(
|
||||
dtuple_t** ref, /*!< out, own: row reference */
|
||||
mem_heap_t* heap); /*!< in: memory heap from which the memory
|
||||
needed is allocated */
|
||||
/*******************************************************************//**
|
||||
Skips a row reference from an undo log record.
|
||||
@return pointer to remaining part of undo record */
|
||||
byte*
|
||||
trx_undo_rec_skip_row_ref(
|
||||
/*======================*/
|
||||
byte* ptr, /*!< in: remaining part in update undo log
|
||||
record, at the start of the row reference */
|
||||
dict_index_t* index); /*!< in: clustered index */
|
||||
/**********************************************************************//**
|
||||
Reads from an undo log update record the system field values of the old
|
||||
version.
|
||||
|
@ -230,16 +230,6 @@ trx_rw_is_active(
|
||||
that will be set if corrupt */
|
||||
bool do_ref_count); /*!< in: if true then increment the
|
||||
trx_t::n_ref_count */
|
||||
#ifdef UNIV_DEBUG
|
||||
/****************************************************************//**
|
||||
Checks whether a trx is in on of rw_trx_list
|
||||
@return TRUE if is in */
|
||||
bool
|
||||
trx_in_rw_trx_list(
|
||||
/*============*/
|
||||
const trx_t* in_trx) /*!< in: transaction */
|
||||
MY_ATTRIBUTE((warn_unused_result));
|
||||
#endif /* UNIV_DEBUG */
|
||||
#if defined UNIV_DEBUG || defined UNIV_BLOB_LIGHT_DEBUG
|
||||
/***********************************************************//**
|
||||
Assert that a transaction has been recovered.
|
||||
|
@ -1271,12 +1271,6 @@ struct trx_t {
|
||||
error, or empty. */
|
||||
FlushObserver* flush_observer; /*!< flush observer */
|
||||
|
||||
#ifdef UNIV_DEBUG
|
||||
bool is_dd_trx; /*!< True if the transaction is used for
|
||||
doing Non-locking Read-only Read
|
||||
Committed on DD tables */
|
||||
#endif /* UNIV_DEBUG */
|
||||
|
||||
/* Lock wait statistics */
|
||||
ulint n_rec_lock_waits;
|
||||
/*!< Number of record lock waits,
|
||||
|
@ -59,16 +59,6 @@ ib_list_t*
|
||||
ib_list_create(void);
|
||||
/*=================*/
|
||||
|
||||
|
||||
/****************************************************************//**
|
||||
Create a new list using the given heap. ib_list_free MUST NOT BE CALLED for
|
||||
lists created with this function.
|
||||
@return list */
|
||||
ib_list_t*
|
||||
ib_list_create_heap(
|
||||
/*================*/
|
||||
mem_heap_t* heap); /*!< in: memory heap to use */
|
||||
|
||||
/****************************************************************//**
|
||||
Free a list. */
|
||||
void
|
||||
@ -76,16 +66,6 @@ ib_list_free(
|
||||
/*=========*/
|
||||
ib_list_t* list); /*!< in: list */
|
||||
|
||||
/****************************************************************//**
|
||||
Add the data to the start of the list.
|
||||
@return new list node */
|
||||
ib_list_node_t*
|
||||
ib_list_add_first(
|
||||
/*==============*/
|
||||
ib_list_t* list, /*!< in: list */
|
||||
void* data, /*!< in: data */
|
||||
mem_heap_t* heap); /*!< in: memory heap to use */
|
||||
|
||||
/****************************************************************//**
|
||||
Add the data to the end of the list.
|
||||
@return new list node */
|
||||
@ -96,18 +76,6 @@ ib_list_add_last(
|
||||
void* data, /*!< in: data */
|
||||
mem_heap_t* heap); /*!< in: memory heap to use */
|
||||
|
||||
/****************************************************************//**
|
||||
Add the data after the indicated node.
|
||||
@return new list node */
|
||||
ib_list_node_t*
|
||||
ib_list_add_after(
|
||||
/*==============*/
|
||||
ib_list_t* list, /*!< in: list */
|
||||
ib_list_node_t* prev_node, /*!< in: node preceding new node (can
|
||||
be NULL) */
|
||||
void* data, /*!< in: data */
|
||||
mem_heap_t* heap); /*!< in: memory heap to use */
|
||||
|
||||
/****************************************************************//**
|
||||
Remove the node from the list. */
|
||||
void
|
||||
@ -156,8 +124,6 @@ ib_list_len(
|
||||
struct ib_list_t {
|
||||
ib_list_node_t* first; /*!< first node */
|
||||
ib_list_node_t* last; /*!< last node */
|
||||
ibool is_heap_list; /*!< TRUE if this list was
|
||||
allocated through a heap */
|
||||
};
|
||||
|
||||
/* A list node. */
|
||||
|
@ -107,27 +107,6 @@ ut_strlcpy_rev(
|
||||
const char* src, /*!< in: source buffer */
|
||||
ulint size); /*!< in: size of destination buffer */
|
||||
|
||||
/**********************************************************************//**
|
||||
Return the number of times s2 occurs in s1. Overlapping instances of s2
|
||||
are only counted once.
|
||||
@return the number of times s2 occurs in s1 */
|
||||
ulint
|
||||
ut_strcount(
|
||||
/*========*/
|
||||
const char* s1, /*!< in: string to search in */
|
||||
const char* s2); /*!< in: string to search for */
|
||||
|
||||
/**********************************************************************//**
|
||||
Replace every occurrence of s1 in str with s2. Overlapping instances of s1
|
||||
are only replaced once.
|
||||
@return own: modified string, must be freed with ut_free() */
|
||||
char*
|
||||
ut_strreplace(
|
||||
/*==========*/
|
||||
const char* str, /*!< in: string to operate on */
|
||||
const char* s1, /*!< in: string to replace */
|
||||
const char* s2); /*!< in: string to replace s1 with */
|
||||
|
||||
/********************************************************************
|
||||
Concatenate 3 strings.*/
|
||||
char*
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 2007, 2014, Oracle and/or its affiliates. All Rights Reserved.
|
||||
Copyright (c) 2007, 2015, Oracle and/or its affiliates. All Rights Reserved.
|
||||
|
||||
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
|
||||
@ -156,15 +156,6 @@ rbt_remove_node(
|
||||
because the caller has access
|
||||
only to const nodes.*/
|
||||
/**********************************************************************//**
|
||||
Return a node from the red black tree, identified by
|
||||
key, NULL if not found
|
||||
@return node if found else return NULL */
|
||||
const ib_rbt_node_t*
|
||||
rbt_lookup(
|
||||
/*=======*/
|
||||
const ib_rbt_t* tree, /*!< in: rb tree to search */
|
||||
const void* key); /*!< in: key to lookup */
|
||||
/**********************************************************************//**
|
||||
Add data to the red black tree, identified by key (no dups yet!)
|
||||
@return inserted node */
|
||||
const ib_rbt_node_t*
|
||||
@ -217,22 +208,6 @@ rbt_prev(
|
||||
const ib_rbt_node_t* /* in: current node */
|
||||
current);
|
||||
/**********************************************************************//**
|
||||
Find the node that has the lowest key that is >= key.
|
||||
@return node that satisfies the lower bound constraint or NULL */
|
||||
const ib_rbt_node_t*
|
||||
rbt_lower_bound(
|
||||
/*============*/
|
||||
const ib_rbt_t* tree, /*!< in: rb tree */
|
||||
const void* key); /*!< in: key to search */
|
||||
/**********************************************************************//**
|
||||
Find the node that has the greatest key that is <= key.
|
||||
@return node that satisifies the upper bound constraint or NULL */
|
||||
const ib_rbt_node_t*
|
||||
rbt_upper_bound(
|
||||
/*============*/
|
||||
const ib_rbt_t* tree, /*!< in: rb tree */
|
||||
const void* key); /*!< in: key to search */
|
||||
/**********************************************************************//**
|
||||
Search for the key, a node will be retuned in parent.last, whether it
|
||||
was found or not. If not found then parent.last will contain the
|
||||
parent node for the possibly new key otherwise the matching node.
|
||||
@ -259,12 +234,6 @@ rbt_search_cmp(
|
||||
arg_compare); /*!< in: fn to compare items
|
||||
with argument */
|
||||
/**********************************************************************//**
|
||||
Clear the tree, deletes (and free's) all the nodes. */
|
||||
void
|
||||
rbt_clear(
|
||||
/*======*/
|
||||
ib_rbt_t* tree); /*!< in: rb tree */
|
||||
/**********************************************************************//**
|
||||
Merge the node from dst into src. Return the number of nodes merged.
|
||||
@return no. of recs merged */
|
||||
ulint
|
||||
@ -272,18 +241,7 @@ rbt_merge_uniq(
|
||||
/*===========*/
|
||||
ib_rbt_t* dst, /*!< in: dst rb tree */
|
||||
const ib_rbt_t* src); /*!< in: src rb tree */
|
||||
/**********************************************************************//**
|
||||
Merge the node from dst into src. Return the number of nodes merged.
|
||||
Delete the nodes from src after copying node to dst. As a side effect
|
||||
the duplicates will be left untouched in the src, since we don't support
|
||||
duplicates (yet). NOTE: src and dst must be similar, the function doesn't
|
||||
check for this condition (yet).
|
||||
@return no. of recs merged */
|
||||
ulint
|
||||
rbt_merge_uniq_destructive(
|
||||
/*=======================*/
|
||||
ib_rbt_t* dst, /*!< in: dst rb tree */
|
||||
ib_rbt_t* src); /*!< in: src rb tree */
|
||||
#if defined UNIV_DEBUG || defined IB_RBT_TESTING
|
||||
/**********************************************************************//**
|
||||
Verify the integrity of the RB tree. For debugging. 0 failure else height
|
||||
of tree (in count of black nodes).
|
||||
@ -292,12 +250,6 @@ ibool
|
||||
rbt_validate(
|
||||
/*=========*/
|
||||
const ib_rbt_t* tree); /*!< in: tree to validate */
|
||||
/**********************************************************************//**
|
||||
Iterate over the tree in depth first order. */
|
||||
void
|
||||
rbt_print(
|
||||
/*======*/
|
||||
const ib_rbt_t* tree, /*!< in: tree to traverse */
|
||||
ib_rbt_print_node print); /*!< in: print function */
|
||||
#endif /* UNIV_DEBUG || IB_RBT_TESTING */
|
||||
|
||||
#endif /* INNOBASE_UT0RBT_H */
|
||||
|
@ -93,6 +93,19 @@ extern "C" int thd_need_ordering_with(const MYSQL_THD thd, const MYSQL_THD other
|
||||
|
||||
extern "C" int thd_deadlock_victim_preference(const MYSQL_THD thd1, const MYSQL_THD thd2);
|
||||
|
||||
/** Print info of a table lock.
|
||||
@param[in,out] file output stream
|
||||
@param[in] lock table lock */
|
||||
static
|
||||
void
|
||||
lock_table_print(FILE* file, const lock_t* lock);
|
||||
|
||||
/** Print info of a record lock.
|
||||
@param[in,out] file output stream
|
||||
@param[in] lock record lock */
|
||||
static
|
||||
void
|
||||
lock_rec_print(FILE* file, const lock_t* lock);
|
||||
|
||||
/** Deadlock checker. */
|
||||
class DeadlockChecker {
|
||||
@ -3077,6 +3090,7 @@ lock_grant_and_move_on_page(
|
||||
Removes a record lock request, waiting or granted, from the queue and
|
||||
grants locks to other transactions in the queue if they now are entitled
|
||||
to a lock. NOTE: all record locks contained in in_lock are removed. */
|
||||
static
|
||||
void
|
||||
lock_rec_dequeue_from_page(
|
||||
/*=======================*/
|
||||
@ -3381,6 +3395,7 @@ lock_rec_inherit_to_gap_if_gap_lock(
|
||||
/*************************************************************//**
|
||||
Moves the locks of a record to another record and resets the lock bits of
|
||||
the donating record. */
|
||||
static
|
||||
void
|
||||
lock_rec_move_low(
|
||||
/*==============*/
|
||||
@ -3464,6 +3479,28 @@ lock_move_granted_locks_to_front(
|
||||
}
|
||||
}
|
||||
|
||||
/*************************************************************//**
|
||||
Moves the locks of a record to another record and resets the lock bits of
|
||||
the donating record. */
|
||||
UNIV_INLINE
|
||||
void
|
||||
lock_rec_move(
|
||||
/*==========*/
|
||||
const buf_block_t* receiver, /*!< in: buffer block containing
|
||||
the receiving record */
|
||||
const buf_block_t* donator, /*!< in: buffer block containing
|
||||
the donating record */
|
||||
ulint receiver_heap_no,/*!< in: heap_no of the record
|
||||
which gets the locks; there
|
||||
must be no lock requests
|
||||
on it! */
|
||||
ulint donator_heap_no)/*!< in: heap_no of the record
|
||||
which gives the locks */
|
||||
{
|
||||
lock_rec_move_low(lock_sys->rec_hash, receiver, donator,
|
||||
receiver_heap_no, donator_heap_no);
|
||||
}
|
||||
|
||||
/*************************************************************//**
|
||||
Updates the lock table when we have reorganized a page. NOTE: we copy
|
||||
also the locks set on the infimum of the page; the infimum may carry
|
||||
@ -5187,7 +5224,6 @@ lock_release(
|
||||
|
||||
ut_ad(lock_mutex_own());
|
||||
ut_ad(!trx_mutex_own(trx));
|
||||
ut_ad(!trx->is_dd_trx);
|
||||
|
||||
for (lock = UT_LIST_GET_LAST(trx->lock.trx_locks);
|
||||
lock != NULL;
|
||||
@ -5482,13 +5518,12 @@ lock_remove_all_on_table(
|
||||
|
||||
/*===================== VALIDATION AND DEBUGGING ====================*/
|
||||
|
||||
/*********************************************************************//**
|
||||
Prints info of a table lock. */
|
||||
/** Print info of a table lock.
|
||||
@param[in,out] file output stream
|
||||
@param[in] lock table lock */
|
||||
static
|
||||
void
|
||||
lock_table_print(
|
||||
/*=============*/
|
||||
FILE* file, /*!< in: file where to print */
|
||||
const lock_t* lock) /*!< in: table type lock */
|
||||
lock_table_print(FILE* file, const lock_t* lock)
|
||||
{
|
||||
ut_ad(lock_mutex_own());
|
||||
ut_a(lock_get_type_low(lock) == LOCK_TABLE);
|
||||
@ -5522,13 +5557,12 @@ lock_table_print(
|
||||
putc('\n', file);
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
Prints info of a record lock. */
|
||||
/** Print info of a record lock.
|
||||
@param[in,out] file output stream
|
||||
@param[in] lock record lock */
|
||||
static
|
||||
void
|
||||
lock_rec_print(
|
||||
/*===========*/
|
||||
FILE* file, /*!< in: file where to print */
|
||||
const lock_t* lock) /*!< in: record type lock */
|
||||
lock_rec_print(FILE* file, const lock_t* lock)
|
||||
{
|
||||
ulint space;
|
||||
ulint page_no;
|
||||
|
@ -101,6 +101,58 @@ lock_prdt_set_prdt(
|
||||
memcpy(&(((byte*) &lock[1])[UNIV_WORD_SIZE]), prdt, sizeof *prdt);
|
||||
}
|
||||
|
||||
|
||||
/** Check whether two predicate locks are compatible with each other
|
||||
@param[in] prdt1 first predicate lock
|
||||
@param[in] prdt2 second predicate lock
|
||||
@param[in] op predicate comparison operator
|
||||
@return true if consistent */
|
||||
static
|
||||
bool
|
||||
lock_prdt_consistent(
|
||||
lock_prdt_t* prdt1,
|
||||
lock_prdt_t* prdt2,
|
||||
ulint op)
|
||||
{
|
||||
bool ret = false;
|
||||
rtr_mbr_t* mbr1 = prdt_get_mbr_from_prdt(prdt1);
|
||||
rtr_mbr_t* mbr2 = prdt_get_mbr_from_prdt(prdt2);
|
||||
ulint action;
|
||||
|
||||
if (op) {
|
||||
action = op;
|
||||
} else {
|
||||
if (prdt2->op != 0 && (prdt1->op != prdt2->op)) {
|
||||
return(false);
|
||||
}
|
||||
|
||||
action = prdt1->op;
|
||||
}
|
||||
|
||||
switch (action) {
|
||||
case PAGE_CUR_CONTAIN:
|
||||
ret = MBR_CONTAIN_CMP(mbr1, mbr2);
|
||||
break;
|
||||
case PAGE_CUR_DISJOINT:
|
||||
ret = MBR_DISJOINT_CMP(mbr1, mbr2);
|
||||
break;
|
||||
case PAGE_CUR_MBR_EQUAL:
|
||||
ret = MBR_EQUAL_CMP(mbr1, mbr2);
|
||||
break;
|
||||
case PAGE_CUR_INTERSECT:
|
||||
ret = MBR_INTERSECT_CMP(mbr1, mbr2);
|
||||
break;
|
||||
case PAGE_CUR_WITHIN:
|
||||
ret = MBR_WITHIN_CMP(mbr1, mbr2);
|
||||
break;
|
||||
default:
|
||||
ib::error() << "invalid operator " << action;
|
||||
ut_error;
|
||||
}
|
||||
|
||||
return(ret);
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
Checks if a predicate lock request for a new lock has to wait for
|
||||
another lock.
|
||||
@ -732,55 +784,6 @@ lock_init_prdt_from_mbr(
|
||||
prdt->op = static_cast<uint16>(mode);
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
Checks two predicate locks are compatible with each other
|
||||
@return true if consistent */
|
||||
bool
|
||||
lock_prdt_consistent(
|
||||
/*=================*/
|
||||
lock_prdt_t* prdt1, /*!< in: Predicate for the lock */
|
||||
lock_prdt_t* prdt2, /*!< in: Predicate for the lock */
|
||||
ulint op) /*!< in: Predicate comparison operator */
|
||||
{
|
||||
bool ret = false;
|
||||
rtr_mbr_t* mbr1 = prdt_get_mbr_from_prdt(prdt1);
|
||||
rtr_mbr_t* mbr2 = prdt_get_mbr_from_prdt(prdt2);
|
||||
ulint action;
|
||||
|
||||
if (op) {
|
||||
action = op;
|
||||
} else {
|
||||
if (prdt2->op != 0 && (prdt1->op != prdt2->op)) {
|
||||
return(false);
|
||||
}
|
||||
|
||||
action = prdt1->op;
|
||||
}
|
||||
|
||||
switch (action) {
|
||||
case PAGE_CUR_CONTAIN:
|
||||
ret = MBR_CONTAIN_CMP(mbr1, mbr2);
|
||||
break;
|
||||
case PAGE_CUR_DISJOINT:
|
||||
ret = MBR_DISJOINT_CMP(mbr1, mbr2);
|
||||
break;
|
||||
case PAGE_CUR_MBR_EQUAL:
|
||||
ret = MBR_EQUAL_CMP(mbr1, mbr2);
|
||||
break;
|
||||
case PAGE_CUR_INTERSECT:
|
||||
ret = MBR_INTERSECT_CMP(mbr1, mbr2);
|
||||
break;
|
||||
case PAGE_CUR_WITHIN:
|
||||
ret = MBR_WITHIN_CMP(mbr1, mbr2);
|
||||
break;
|
||||
default:
|
||||
ib::error() << "invalid operator " << action;
|
||||
ut_error;
|
||||
}
|
||||
|
||||
return(ret);
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
Acquire a predicate lock on a block
|
||||
@return DB_SUCCESS, DB_LOCK_WAIT, DB_DEADLOCK, or DB_QUE_THR_SUSPENDED */
|
||||
|
@ -557,6 +557,7 @@ function_exit:
|
||||
Calculates the data capacity of a log group, when the log file headers are not
|
||||
included.
|
||||
@return capacity in bytes */
|
||||
static
|
||||
lsn_t
|
||||
log_group_get_capacity(
|
||||
/*===================*/
|
||||
@ -655,45 +656,6 @@ log_group_calc_lsn_offset(
|
||||
|
||||
return(log_group_calc_real_offset(offset, group));
|
||||
}
|
||||
/*******************************************************************//**
|
||||
Calculates where in log files we find a specified lsn.
|
||||
@return log file number */
|
||||
ulint
|
||||
log_calc_where_lsn_is(
|
||||
/*==================*/
|
||||
int64_t* log_file_offset, /*!< out: offset in that file
|
||||
(including the header) */
|
||||
ib_uint64_t first_header_lsn, /*!< in: first log file start
|
||||
lsn */
|
||||
ib_uint64_t lsn, /*!< in: lsn whose position to
|
||||
determine */
|
||||
ulint n_log_files, /*!< in: total number of log
|
||||
files */
|
||||
int64_t log_file_size) /*!< in: log file size
|
||||
(including the header) */
|
||||
{
|
||||
int64_t capacity = log_file_size - LOG_FILE_HDR_SIZE;
|
||||
ulint file_no;
|
||||
int64_t add_this_many;
|
||||
|
||||
if (lsn < first_header_lsn) {
|
||||
add_this_many = 1 + (first_header_lsn - lsn)
|
||||
/ (capacity * static_cast<int64_t>(n_log_files));
|
||||
lsn += add_this_many
|
||||
* capacity * static_cast<int64_t>(n_log_files);
|
||||
}
|
||||
|
||||
ut_a(lsn >= first_header_lsn);
|
||||
|
||||
file_no = ((ulint)((lsn - first_header_lsn) / capacity))
|
||||
% n_log_files;
|
||||
*log_file_offset = (lsn - first_header_lsn) % capacity;
|
||||
|
||||
*log_file_offset = *log_file_offset + LOG_FILE_HDR_SIZE;
|
||||
|
||||
return(file_no);
|
||||
}
|
||||
|
||||
|
||||
/********************************************************//**
|
||||
Sets the field values in group to correspond to a given lsn. For this function
|
||||
|
@ -1043,6 +1043,7 @@ AIO::pending_io_count() const
|
||||
#ifdef UNIV_DEBUG
|
||||
/** Validates the consistency the aio system some of the time.
|
||||
@return true if ok or the check was skipped */
|
||||
static
|
||||
bool
|
||||
os_aio_validate_skip()
|
||||
{
|
||||
@ -2492,6 +2493,7 @@ os_file_fsync_posix(
|
||||
@param[out] exists true if the file exists
|
||||
@param[out] type Type of the file, if it exists
|
||||
@return true if call succeeded */
|
||||
static
|
||||
bool
|
||||
os_file_status_posix(
|
||||
const char* path,
|
||||
@ -3597,6 +3599,7 @@ os_file_punch_hole_win32(
|
||||
@param[out] exists true if the file exists
|
||||
@param[out] type Type of the file, if it exists
|
||||
@return true if call succeeded */
|
||||
static
|
||||
bool
|
||||
os_file_status_win32(
|
||||
const char* path,
|
||||
|
@ -1129,6 +1129,15 @@ opt_clust_access(
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef UNIV_SQL_DEBUG
|
||||
/** Print info of a query plan.
|
||||
@param[in,out] sel_node select node */
|
||||
static
|
||||
void
|
||||
opt_print_query_plan(
|
||||
sel_node_t* sel_node);
|
||||
#endif
|
||||
|
||||
/*******************************************************************//**
|
||||
Optimizes a select. Decides which indexes to tables to use. The tables
|
||||
are accessed in the order that they were written to the FROM part in the
|
||||
@ -1207,13 +1216,13 @@ opt_search_plan(
|
||||
#endif
|
||||
}
|
||||
|
||||
#if 1//def UNIV_SQL_DEBUG
|
||||
/********************************************************************//**
|
||||
Prints info of a query plan. */
|
||||
#ifdef UNIV_SQL_DEBUG
|
||||
/** Print info of a query plan.
|
||||
@param[in,out] sel_node select node */
|
||||
static
|
||||
void
|
||||
opt_print_query_plan(
|
||||
/*=================*/
|
||||
sel_node_t* sel_node) /*!< in: select node */
|
||||
sel_node_t* sel_node)
|
||||
{
|
||||
plan_t* plan;
|
||||
ulint n_fields;
|
||||
|
@ -1927,6 +1927,7 @@ rec_print_old(
|
||||
/***************************************************************//**
|
||||
Prints a physical record in ROW_FORMAT=COMPACT. Ignores the
|
||||
record header. */
|
||||
static
|
||||
void
|
||||
rec_print_comp(
|
||||
/*===========*/
|
||||
@ -1971,6 +1972,7 @@ rec_print_comp(
|
||||
|
||||
/***************************************************************//**
|
||||
Prints an old-style spatial index record. */
|
||||
static
|
||||
void
|
||||
rec_print_mbr_old(
|
||||
/*==============*/
|
||||
|
@ -772,6 +772,7 @@ row_merge_fts_get_next_doc_item(
|
||||
Function performs parallel tokenization of the incoming doc strings.
|
||||
It also performs the initial in memory sort of the parsed records.
|
||||
@return OS_THREAD_DUMMY_RETURN */
|
||||
static
|
||||
os_thread_ret_t
|
||||
fts_parallel_tokenization(
|
||||
/*======================*/
|
||||
@ -1115,6 +1116,7 @@ row_fts_start_psort(
|
||||
/*********************************************************************//**
|
||||
Function performs the merge and insertion of the sorted records.
|
||||
@return OS_THREAD_DUMMY_RETURN */
|
||||
static
|
||||
os_thread_ret_t
|
||||
fts_parallel_merge(
|
||||
/*===============*/
|
||||
@ -1256,6 +1258,7 @@ row_merge_write_fts_word(
|
||||
/*********************************************************************//**
|
||||
Read sorted FTS data files and insert data tuples to auxillary tables.
|
||||
@return DB_SUCCESS or error number */
|
||||
static
|
||||
void
|
||||
row_fts_insert_tuple(
|
||||
/*=================*/
|
||||
|
@ -2437,6 +2437,74 @@ row_ins_must_modify_rec(
|
||||
&& !page_rec_is_infimum(btr_cur_get_rec(cursor)));
|
||||
}
|
||||
|
||||
/** Insert the externally stored fields (off-page columns)
|
||||
of a clustered index entry.
|
||||
@param[in] entry index entry to insert
|
||||
@param[in] big_rec externally stored fields
|
||||
@param[in,out] offsets rec_get_offsets()
|
||||
@param[in,out] heap memory heap
|
||||
@param[in] thd client connection, or NULL
|
||||
@param[in] index clustered index
|
||||
@return error code
|
||||
@retval DB_SUCCESS
|
||||
@retval DB_OUT_OF_FILE_SPACE */
|
||||
static
|
||||
dberr_t
|
||||
row_ins_index_entry_big_rec(
|
||||
const dtuple_t* entry,
|
||||
const big_rec_t* big_rec,
|
||||
ulint* offsets,
|
||||
mem_heap_t** heap,
|
||||
#ifndef DBUG_OFF
|
||||
const void* thd,
|
||||
#endif /* DBUG_OFF */
|
||||
dict_index_t* index)
|
||||
{
|
||||
mtr_t mtr;
|
||||
btr_pcur_t pcur;
|
||||
rec_t* rec;
|
||||
dberr_t error;
|
||||
|
||||
ut_ad(dict_index_is_clust(index));
|
||||
|
||||
DEBUG_SYNC_C_IF_THD(thd, "before_row_ins_extern_latch");
|
||||
|
||||
mtr_start(&mtr);
|
||||
mtr.set_named_space(index->space);
|
||||
dict_disable_redo_if_temporary(index->table, &mtr);
|
||||
|
||||
btr_pcur_open(index, entry, PAGE_CUR_LE, BTR_MODIFY_TREE,
|
||||
&pcur, &mtr);
|
||||
rec = btr_pcur_get_rec(&pcur);
|
||||
offsets = rec_get_offsets(rec, index, offsets,
|
||||
ULINT_UNDEFINED, heap);
|
||||
|
||||
DEBUG_SYNC_C_IF_THD(thd, "before_row_ins_extern");
|
||||
error = btr_store_big_rec_extern_fields(
|
||||
&pcur, 0, offsets, big_rec, &mtr, BTR_STORE_INSERT);
|
||||
DEBUG_SYNC_C_IF_THD(thd, "after_row_ins_extern");
|
||||
|
||||
if (error == DB_SUCCESS
|
||||
&& dict_index_is_online_ddl(index)) {
|
||||
row_log_table_insert(btr_pcur_get_rec(&pcur), entry,
|
||||
index, offsets);
|
||||
}
|
||||
|
||||
mtr_commit(&mtr);
|
||||
|
||||
btr_pcur_close(&pcur);
|
||||
|
||||
return(error);
|
||||
}
|
||||
|
||||
#ifdef DBUG_OFF
|
||||
# define row_ins_index_entry_big_rec(e,big,ofs,heap,index,thd) \
|
||||
row_ins_index_entry_big_rec(e,big,ofs,heap,index)
|
||||
#else /* DBUG_OFF */
|
||||
# define row_ins_index_entry_big_rec(e,big,ofs,heap,index,thd) \
|
||||
row_ins_index_entry_big_rec(e,big,ofs,heap,thd,index)
|
||||
#endif /* DBUG_OFF */
|
||||
|
||||
/***************************************************************//**
|
||||
Tries to insert an entry into a clustered index, ignoring foreign key
|
||||
constraints. If a record with the same unique key is found, the other
|
||||
@ -2648,8 +2716,7 @@ err_exit:
|
||||
LSN_MAX, TRUE););
|
||||
err = row_ins_index_entry_big_rec(
|
||||
entry, big_rec, offsets, &offsets_heap, index,
|
||||
thr_get_trx(thr)->mysql_thd,
|
||||
__FILE__, __LINE__);
|
||||
thr_get_trx(thr)->mysql_thd);
|
||||
dtuple_convert_back_big_rec(index, entry, big_rec);
|
||||
} else {
|
||||
if (err == DB_SUCCESS
|
||||
@ -3065,61 +3132,6 @@ func_exit:
|
||||
DBUG_RETURN(err);
|
||||
}
|
||||
|
||||
/***************************************************************//**
|
||||
Tries to insert the externally stored fields (off-page columns)
|
||||
of a clustered index entry.
|
||||
@return DB_SUCCESS or DB_OUT_OF_FILE_SPACE */
|
||||
dberr_t
|
||||
row_ins_index_entry_big_rec_func(
|
||||
/*=============================*/
|
||||
const dtuple_t* entry, /*!< in/out: index entry to insert */
|
||||
const big_rec_t* big_rec,/*!< in: externally stored fields */
|
||||
ulint* offsets,/*!< in/out: rec offsets */
|
||||
mem_heap_t** heap, /*!< in/out: memory heap */
|
||||
dict_index_t* index, /*!< in: index */
|
||||
const char* file, /*!< in: file name of caller */
|
||||
#ifndef DBUG_OFF
|
||||
const void* thd, /*!< in: connection, or NULL */
|
||||
#endif /* DBUG_OFF */
|
||||
unsigned line) /*!< in: line number of caller */
|
||||
{
|
||||
mtr_t mtr;
|
||||
btr_pcur_t pcur;
|
||||
rec_t* rec;
|
||||
dberr_t error;
|
||||
|
||||
ut_ad(dict_index_is_clust(index));
|
||||
|
||||
DEBUG_SYNC_C_IF_THD(thd, "before_row_ins_extern_latch");
|
||||
|
||||
mtr_start(&mtr);
|
||||
mtr.set_named_space(index->space);
|
||||
dict_disable_redo_if_temporary(index->table, &mtr);
|
||||
|
||||
btr_pcur_open(index, entry, PAGE_CUR_LE, BTR_MODIFY_TREE,
|
||||
&pcur, &mtr);
|
||||
rec = btr_pcur_get_rec(&pcur);
|
||||
offsets = rec_get_offsets(rec, index, offsets,
|
||||
ULINT_UNDEFINED, heap);
|
||||
|
||||
DEBUG_SYNC_C_IF_THD(thd, "before_row_ins_extern");
|
||||
error = btr_store_big_rec_extern_fields(
|
||||
&pcur, 0, offsets, big_rec, &mtr, BTR_STORE_INSERT);
|
||||
DEBUG_SYNC_C_IF_THD(thd, "after_row_ins_extern");
|
||||
|
||||
if (error == DB_SUCCESS
|
||||
&& dict_index_is_online_ddl(index)) {
|
||||
row_log_table_insert(btr_pcur_get_rec(&pcur), entry,
|
||||
index, offsets);
|
||||
}
|
||||
|
||||
mtr_commit(&mtr);
|
||||
|
||||
btr_pcur_close(&pcur);
|
||||
|
||||
return(error);
|
||||
}
|
||||
|
||||
/***************************************************************//**
|
||||
Inserts an entry into a clustered index. Tries first optimistic,
|
||||
then pessimistic descent down the tree. If the entry matches enough
|
||||
|
@ -373,6 +373,7 @@ row_mysql_store_geometry(
|
||||
/*******************************************************************//**
|
||||
Read geometry data in the MySQL format.
|
||||
@return pointer to geometry data */
|
||||
static
|
||||
const byte*
|
||||
row_mysql_read_geometry(
|
||||
/*====================*/
|
||||
|
@ -2474,47 +2474,6 @@ fetch_step(
|
||||
return(thr);
|
||||
}
|
||||
|
||||
/****************************************************************//**
|
||||
Sample callback function for fetch that prints each row.
|
||||
@return always returns non-NULL */
|
||||
void*
|
||||
row_fetch_print(
|
||||
/*============*/
|
||||
void* row, /*!< in: sel_node_t* */
|
||||
void* user_arg) /*!< in: not used */
|
||||
{
|
||||
que_node_t* exp;
|
||||
ulint i = 0;
|
||||
sel_node_t* node = static_cast<sel_node_t*>(row);
|
||||
|
||||
UT_NOT_USED(user_arg);
|
||||
|
||||
ib::info() << "row_fetch_print: row " << row;
|
||||
|
||||
for (exp = node->select_list;
|
||||
exp != 0;
|
||||
exp = que_node_get_next(exp), i++) {
|
||||
|
||||
dfield_t* dfield = que_node_get_val(exp);
|
||||
const dtype_t* type = dfield_get_type(dfield);
|
||||
|
||||
fprintf(stderr, " column %lu:\n", (ulong) i);
|
||||
|
||||
dtype_print(type);
|
||||
putc('\n', stderr);
|
||||
|
||||
if (dfield_get_len(dfield) != UNIV_SQL_NULL) {
|
||||
ut_print_buf(stderr, dfield_get_data(dfield),
|
||||
dfield_get_len(dfield));
|
||||
putc('\n', stderr);
|
||||
} else {
|
||||
fputs(" <NULL>;\n", stderr);
|
||||
}
|
||||
}
|
||||
|
||||
return((void*)42);
|
||||
}
|
||||
|
||||
/***********************************************************//**
|
||||
Prints a row in a select result.
|
||||
@return query thread to run next or NULL */
|
||||
|
@ -3220,6 +3220,7 @@ to this node, we assume that we have a persistent cursor which was on a
|
||||
record, and the position of the cursor is stored in the cursor.
|
||||
@return DB_SUCCESS if operation successfully completed, else error
|
||||
code or DB_LOCK_WAIT */
|
||||
static
|
||||
dberr_t
|
||||
row_upd(
|
||||
/*====*/
|
||||
|
@ -2921,9 +2921,11 @@ innodb_shutdown()
|
||||
srv_start_has_been_called = FALSE;
|
||||
}
|
||||
|
||||
#if 0 // TODO: Enable this in WL#6608
|
||||
/********************************************************************
|
||||
Signal all per-table background threads to shutdown, and wait for them to do
|
||||
so. */
|
||||
static
|
||||
void
|
||||
srv_shutdown_table_bg_threads(void)
|
||||
/*===============================*/
|
||||
@ -2996,6 +2998,7 @@ srv_shutdown_table_bg_threads(void)
|
||||
table = next;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/** Get the meta-data filename from the table name for a
|
||||
single-table tablespace.
|
||||
|
@ -222,6 +222,33 @@ sync_array_t::sync_array_t(ulint num_cells)
|
||||
mutex_create(LATCH_ID_SYNC_ARRAY_MUTEX, &mutex);
|
||||
}
|
||||
|
||||
/** Validate the integrity of the wait array. Check
|
||||
that the number of reserved cells equals the count variable.
|
||||
@param[in,out] arr sync wait array */
|
||||
static
|
||||
void
|
||||
sync_array_validate(sync_array_t* arr)
|
||||
{
|
||||
ulint i;
|
||||
ulint count = 0;
|
||||
|
||||
sync_array_enter(arr);
|
||||
|
||||
for (i = 0; i < arr->n_cells; i++) {
|
||||
sync_cell_t* cell;
|
||||
|
||||
cell = sync_array_get_nth_cell(arr, i);
|
||||
|
||||
if (cell->latch.mutex != NULL) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
ut_a(count == arr->n_reserved);
|
||||
|
||||
sync_array_exit(arr);
|
||||
}
|
||||
|
||||
/** Destructor */
|
||||
sync_array_t::~sync_array_t()
|
||||
UNIV_NOTHROW
|
||||
@ -263,34 +290,6 @@ sync_array_free(
|
||||
UT_DELETE(arr);
|
||||
}
|
||||
|
||||
/********************************************************************//**
|
||||
Validates the integrity of the wait array. Checks
|
||||
that the number of reserved cells equals the count variable. */
|
||||
void
|
||||
sync_array_validate(
|
||||
/*================*/
|
||||
sync_array_t* arr) /*!< in: sync wait array */
|
||||
{
|
||||
ulint i;
|
||||
ulint count = 0;
|
||||
|
||||
sync_array_enter(arr);
|
||||
|
||||
for (i = 0; i < arr->n_cells; i++) {
|
||||
sync_cell_t* cell;
|
||||
|
||||
cell = sync_array_get_nth_cell(arr, i);
|
||||
|
||||
if (cell->latch.mutex != NULL) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
ut_a(count == arr->n_reserved);
|
||||
|
||||
sync_array_exit(arr);
|
||||
}
|
||||
|
||||
/*******************************************************************//**
|
||||
Returns the event that the thread owning the cell waits for. */
|
||||
static
|
||||
@ -691,6 +690,7 @@ Report an error to stderr.
|
||||
@param lock rw-lock instance
|
||||
@param debug rw-lock debug information
|
||||
@param cell thread context */
|
||||
static
|
||||
void
|
||||
sync_array_report_error(
|
||||
rw_lock_t* lock,
|
||||
|
@ -1171,41 +1171,6 @@ rw_lock_list_print_info(
|
||||
mutex_exit(&rw_lock_list_mutex);
|
||||
}
|
||||
|
||||
/***************************************************************//**
|
||||
Prints debug info of an rw-lock. */
|
||||
void
|
||||
rw_lock_print(
|
||||
/*==========*/
|
||||
rw_lock_t* lock) /*!< in: rw-lock */
|
||||
{
|
||||
rw_lock_debug_t* info;
|
||||
|
||||
fprintf(stderr,
|
||||
"-------------\n"
|
||||
"RW-LATCH INFO\n"
|
||||
"RW-LATCH: %p ", (void*) lock);
|
||||
|
||||
if (lock->lock_word != X_LOCK_DECR) {
|
||||
|
||||
if (lock->waiters) {
|
||||
fputs(" Waiters for the lock exist\n", stderr);
|
||||
} else {
|
||||
putc('\n', stderr);
|
||||
}
|
||||
|
||||
rw_lock_debug_mutex_enter();
|
||||
|
||||
for (info = UT_LIST_GET_FIRST(lock->debug_list);
|
||||
info != NULL;
|
||||
info = UT_LIST_GET_NEXT(list, info)) {
|
||||
|
||||
rw_lock_debug_print(stderr, info);
|
||||
}
|
||||
|
||||
rw_lock_debug_mutex_exit();
|
||||
}
|
||||
}
|
||||
|
||||
/*********************************************************************//**
|
||||
Prints info of a debug struct. */
|
||||
void
|
||||
@ -1245,32 +1210,6 @@ rw_lock_debug_print(
|
||||
fprintf(f, "\n");
|
||||
}
|
||||
|
||||
/***************************************************************//**
|
||||
Returns the number of currently locked rw-locks. Works only in the debug
|
||||
version.
|
||||
@return number of locked rw-locks */
|
||||
ulint
|
||||
rw_lock_n_locked(void)
|
||||
/*==================*/
|
||||
{
|
||||
ulint count = 0;
|
||||
|
||||
mutex_enter(&rw_lock_list_mutex);
|
||||
|
||||
for (const rw_lock_t* lock = UT_LIST_GET_FIRST(rw_lock_list);
|
||||
lock != NULL;
|
||||
lock = UT_LIST_GET_NEXT(list, lock)) {
|
||||
|
||||
if (lock->lock_word != X_LOCK_DECR) {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
mutex_exit(&rw_lock_list_mutex);
|
||||
|
||||
return(count);
|
||||
}
|
||||
|
||||
/** Print where it was locked from
|
||||
@return the string representation */
|
||||
std::string
|
||||
|
@ -666,6 +666,7 @@ trx_undo_rec_get_row_ref(
|
||||
/*******************************************************************//**
|
||||
Skips a row reference from an undo log record.
|
||||
@return pointer to remaining part of undo record */
|
||||
static
|
||||
byte*
|
||||
trx_undo_rec_skip_row_ref(
|
||||
/*======================*/
|
||||
|
@ -137,37 +137,6 @@ updated via SET GLOBAL innodb_file_format_max = 'x' or when we open
|
||||
or create a table. */
|
||||
static file_format_t file_format_max;
|
||||
|
||||
#ifdef UNIV_DEBUG
|
||||
/****************************************************************//**
|
||||
Checks whether a trx is in one of rw_trx_list
|
||||
@return true if is in */
|
||||
bool
|
||||
trx_in_rw_trx_list(
|
||||
/*============*/
|
||||
const trx_t* in_trx) /*!< in: transaction */
|
||||
{
|
||||
const trx_t* trx;
|
||||
|
||||
/* Non-locking autocommits should not hold any locks. */
|
||||
check_trx_state(in_trx);
|
||||
|
||||
ut_ad(trx_sys_mutex_own());
|
||||
|
||||
ut_ad(trx_assert_started(in_trx));
|
||||
|
||||
for (trx = UT_LIST_GET_FIRST(trx_sys->rw_trx_list);
|
||||
trx != NULL && trx != in_trx;
|
||||
trx = UT_LIST_GET_NEXT(trx_list, trx)) {
|
||||
|
||||
check_trx_state(trx);
|
||||
|
||||
ut_ad(trx->rsegs.m_redo.rseg != NULL && !trx->read_only);
|
||||
}
|
||||
|
||||
return(trx != 0);
|
||||
}
|
||||
#endif /* UNIV_DEBUG */
|
||||
|
||||
/*****************************************************************//**
|
||||
Writes the value of max_trx_id to the file based trx system header. */
|
||||
void
|
||||
|
@ -173,10 +173,6 @@ trx_init(
|
||||
|
||||
trx->internal = false;
|
||||
|
||||
#ifdef UNIV_DEBUG
|
||||
trx->is_dd_trx = false;
|
||||
#endif /* UNIV_DEBUG */
|
||||
|
||||
ut_d(trx->start_file = 0);
|
||||
|
||||
ut_d(trx->start_line = 0);
|
||||
@ -506,7 +502,6 @@ trx_free(trx_t*& trx)
|
||||
trx->mod_tables.clear();
|
||||
|
||||
ut_ad(trx->read_view == NULL);
|
||||
ut_ad(trx->is_dd_trx == false);
|
||||
|
||||
/* trx locking state should have been reset before returning trx
|
||||
to pool */
|
||||
@ -1359,15 +1354,6 @@ trx_start_low(
|
||||
trx->read_only = true;
|
||||
}
|
||||
|
||||
#ifdef UNIV_DEBUG
|
||||
/* If the transaction is DD attachable trx, it should be AC-NL-RO-RC
|
||||
(AutoCommit-NonLocking-ReadOnly-ReadCommited) trx */
|
||||
if (trx->is_dd_trx) {
|
||||
ut_ad(trx->read_only && trx->auto_commit
|
||||
&& trx->isolation_level == TRX_ISO_READ_COMMITTED);
|
||||
}
|
||||
#endif /* UNIV_DEBUG */
|
||||
|
||||
#ifdef WITH_WSREP
|
||||
memset(trx->xid, 0, sizeof(xid_t));
|
||||
trx->xid->formatID = -1;
|
||||
@ -1528,6 +1514,7 @@ trx_serialise(trx_t* trx, trx_rseg_t* rseg)
|
||||
Assign the transaction its history serialisation number and write the
|
||||
update UNDO log record to the assigned rollback segment.
|
||||
@return true if a serialisation log was written */
|
||||
static
|
||||
bool
|
||||
trx_write_serialisation_history(
|
||||
/*============================*/
|
||||
|
@ -32,35 +32,7 @@ ib_list_t*
|
||||
ib_list_create(void)
|
||||
/*=================*/
|
||||
{
|
||||
ib_list_t* list;
|
||||
|
||||
list = static_cast<ib_list_t*>(ut_malloc_nokey(sizeof(*list)));
|
||||
|
||||
list->first = NULL;
|
||||
list->last = NULL;
|
||||
list->is_heap_list = FALSE;
|
||||
|
||||
return(list);
|
||||
}
|
||||
|
||||
/****************************************************************//**
|
||||
Create a new list using the given heap. ib_list_free MUST NOT BE CALLED for
|
||||
lists created with this function.
|
||||
@return list */
|
||||
ib_list_t*
|
||||
ib_list_create_heap(
|
||||
/*================*/
|
||||
mem_heap_t* heap) /*!< in: memory heap to use */
|
||||
{
|
||||
ib_list_t* list;
|
||||
|
||||
list = static_cast<ib_list_t*>(mem_heap_alloc(heap, sizeof(*list)));
|
||||
|
||||
list->first = NULL;
|
||||
list->last = NULL;
|
||||
list->is_heap_list = TRUE;
|
||||
|
||||
return(list);
|
||||
return(static_cast<ib_list_t*>(ut_zalloc_nokey(sizeof(ib_list_t))));
|
||||
}
|
||||
|
||||
/****************************************************************//**
|
||||
@ -70,8 +42,6 @@ ib_list_free(
|
||||
/*=========*/
|
||||
ib_list_t* list) /*!< in: list */
|
||||
{
|
||||
ut_a(!list->is_heap_list);
|
||||
|
||||
/* We don't check that the list is empty because it's entirely valid
|
||||
to e.g. have all the nodes allocated from a single heap that is then
|
||||
freed after the list itself is freed. */
|
||||
@ -79,35 +49,10 @@ ib_list_free(
|
||||
ut_free(list);
|
||||
}
|
||||
|
||||
/****************************************************************//**
|
||||
Add the data to the start of the list.
|
||||
@return new list node */
|
||||
ib_list_node_t*
|
||||
ib_list_add_first(
|
||||
/*==============*/
|
||||
ib_list_t* list, /*!< in: list */
|
||||
void* data, /*!< in: data */
|
||||
mem_heap_t* heap) /*!< in: memory heap to use */
|
||||
{
|
||||
return(ib_list_add_after(list, ib_list_get_first(list), data, heap));
|
||||
}
|
||||
|
||||
/****************************************************************//**
|
||||
Add the data to the end of the list.
|
||||
@return new list node */
|
||||
ib_list_node_t*
|
||||
ib_list_add_last(
|
||||
/*=============*/
|
||||
ib_list_t* list, /*!< in: list */
|
||||
void* data, /*!< in: data */
|
||||
mem_heap_t* heap) /*!< in: memory heap to use */
|
||||
{
|
||||
return(ib_list_add_after(list, ib_list_get_last(list), data, heap));
|
||||
}
|
||||
|
||||
/****************************************************************//**
|
||||
Add the data after the indicated node.
|
||||
@return new list node */
|
||||
static
|
||||
ib_list_node_t*
|
||||
ib_list_add_after(
|
||||
/*==============*/
|
||||
@ -161,6 +106,19 @@ ib_list_add_after(
|
||||
return(node);
|
||||
}
|
||||
|
||||
/****************************************************************//**
|
||||
Add the data to the end of the list.
|
||||
@return new list node */
|
||||
ib_list_node_t*
|
||||
ib_list_add_last(
|
||||
/*=============*/
|
||||
ib_list_t* list, /*!< in: list */
|
||||
void* data, /*!< in: data */
|
||||
mem_heap_t* heap) /*!< in: memory heap to use */
|
||||
{
|
||||
return(ib_list_add_after(list, ib_list_get_last(list), data, heap));
|
||||
}
|
||||
|
||||
/****************************************************************//**
|
||||
Remove the node from the list. */
|
||||
void
|
||||
|
@ -74,39 +74,6 @@ ut_strlcpy_rev(
|
||||
return(src_size);
|
||||
}
|
||||
|
||||
/**********************************************************************//**
|
||||
Return the number of times s2 occurs in s1. Overlapping instances of s2
|
||||
are only counted once.
|
||||
@return the number of times s2 occurs in s1 */
|
||||
ulint
|
||||
ut_strcount(
|
||||
/*========*/
|
||||
const char* s1, /*!< in: string to search in */
|
||||
const char* s2) /*!< in: string to search for */
|
||||
{
|
||||
ulint count = 0;
|
||||
ulint len = strlen(s2);
|
||||
|
||||
if (len == 0) {
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
s1 = strstr(s1, s2);
|
||||
|
||||
if (!s1) {
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
count++;
|
||||
s1 += len;
|
||||
}
|
||||
|
||||
return(count);
|
||||
}
|
||||
|
||||
/********************************************************************
|
||||
Concatenate 3 strings.*/
|
||||
char*
|
||||
@ -133,61 +100,3 @@ ut_str3cat(
|
||||
|
||||
return(s);
|
||||
}
|
||||
/**********************************************************************//**
|
||||
Replace every occurrence of s1 in str with s2. Overlapping instances of s1
|
||||
are only replaced once.
|
||||
@return own: modified string, must be freed with ut_free() */
|
||||
char*
|
||||
ut_strreplace(
|
||||
/*==========*/
|
||||
const char* str, /*!< in: string to operate on */
|
||||
const char* s1, /*!< in: string to replace */
|
||||
const char* s2) /*!< in: string to replace s1 with */
|
||||
{
|
||||
char* new_str;
|
||||
char* ptr;
|
||||
const char* str_end;
|
||||
ulint str_len = strlen(str);
|
||||
ulint s1_len = strlen(s1);
|
||||
ulint s2_len = strlen(s2);
|
||||
ulint count = 0;
|
||||
int len_delta = (int) s2_len - (int) s1_len;
|
||||
|
||||
str_end = str + str_len;
|
||||
|
||||
if (len_delta <= 0) {
|
||||
len_delta = 0;
|
||||
} else {
|
||||
count = ut_strcount(str, s1);
|
||||
}
|
||||
|
||||
new_str = static_cast<char*>(
|
||||
ut_malloc_nokey(str_len + count * len_delta + 1));
|
||||
|
||||
ptr = new_str;
|
||||
|
||||
while (str) {
|
||||
const char* next = strstr(str, s1);
|
||||
|
||||
if (!next) {
|
||||
next = str_end;
|
||||
}
|
||||
|
||||
memcpy(ptr, str, next - str);
|
||||
ptr += next - str;
|
||||
|
||||
if (next == str_end) {
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
memcpy(ptr, s2, s2_len);
|
||||
ptr += s2_len;
|
||||
|
||||
str = next + s1_len;
|
||||
}
|
||||
|
||||
*ptr = '\0';
|
||||
|
||||
return(new_str);
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
/***************************************************************************//**
|
||||
|
||||
Copyright (c) 2007, 2014, Oracle and/or its affiliates. All Rights Reserved.
|
||||
Copyright (c) 2007, 2015, Oracle and/or its affiliates. All Rights Reserved.
|
||||
|
||||
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
|
||||
@ -54,24 +54,6 @@ red-black properties:
|
||||
#define ROOT(t) (t->root->left)
|
||||
#define SIZEOF_NODE(t) ((sizeof(ib_rbt_node_t) + t->sizeof_value) - 1)
|
||||
|
||||
/**********************************************************************//**
|
||||
Print out the sub-tree recursively. */
|
||||
static
|
||||
void
|
||||
rbt_print_subtree(
|
||||
/*==============*/
|
||||
const ib_rbt_t* tree, /*!< in: tree to traverse */
|
||||
const ib_rbt_node_t* node, /*!< in: node to print */
|
||||
ib_rbt_print_node print) /*!< in: print key function */
|
||||
{
|
||||
/* FIXME: Doesn't do anything yet */
|
||||
if (node != tree->nil) {
|
||||
print(node);
|
||||
rbt_print_subtree(tree, node->left, print);
|
||||
rbt_print_subtree(tree, node->right, print);
|
||||
}
|
||||
}
|
||||
|
||||
/**********************************************************************//**
|
||||
Verify that the keys are in order.
|
||||
@return TRUE of OK. FALSE if not ordered */
|
||||
@ -880,7 +862,7 @@ rbt_add_node(
|
||||
|
||||
++tree->n_nodes;
|
||||
|
||||
#if defined(IB_RBT_TESTING)
|
||||
#if defined UNIV_DEBUG || defined IB_RBT_TESTING
|
||||
ut_a(rbt_validate(tree));
|
||||
#endif
|
||||
return(node);
|
||||
@ -889,6 +871,7 @@ rbt_add_node(
|
||||
/**********************************************************************//**
|
||||
Find a matching node in the rb tree.
|
||||
@return NULL if not found else the node where key was found */
|
||||
static
|
||||
const ib_rbt_node_t*
|
||||
rbt_lookup(
|
||||
/*=======*/
|
||||
@ -965,86 +948,6 @@ rbt_remove_node(
|
||||
return((ib_rbt_node_t*) const_node);
|
||||
}
|
||||
|
||||
/**********************************************************************//**
|
||||
Find the node that has the lowest key that is >= key.
|
||||
@return node satisfying the lower bound constraint or NULL */
|
||||
const ib_rbt_node_t*
|
||||
rbt_lower_bound(
|
||||
/*============*/
|
||||
const ib_rbt_t* tree, /*!< in: rb tree */
|
||||
const void* key) /*!< in: key to search */
|
||||
{
|
||||
ib_rbt_node_t* lb_node = NULL;
|
||||
ib_rbt_node_t* current = ROOT(tree);
|
||||
|
||||
while (current != tree->nil) {
|
||||
int result;
|
||||
|
||||
if (tree->cmp_arg) {
|
||||
result = tree->compare_with_arg(
|
||||
tree->cmp_arg, key, current->value);
|
||||
} else {
|
||||
result = tree->compare(key, current->value);
|
||||
}
|
||||
|
||||
if (result > 0) {
|
||||
|
||||
current = current->right;
|
||||
|
||||
} else if (result < 0) {
|
||||
|
||||
lb_node = current;
|
||||
current = current->left;
|
||||
|
||||
} else {
|
||||
lb_node = current;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return(lb_node);
|
||||
}
|
||||
|
||||
/**********************************************************************//**
|
||||
Find the node that has the greatest key that is <= key.
|
||||
@return node satisfying the upper bound constraint or NULL */
|
||||
const ib_rbt_node_t*
|
||||
rbt_upper_bound(
|
||||
/*============*/
|
||||
const ib_rbt_t* tree, /*!< in: rb tree */
|
||||
const void* key) /*!< in: key to search */
|
||||
{
|
||||
ib_rbt_node_t* ub_node = NULL;
|
||||
ib_rbt_node_t* current = ROOT(tree);
|
||||
|
||||
while (current != tree->nil) {
|
||||
int result;
|
||||
|
||||
if (tree->cmp_arg) {
|
||||
result = tree->compare_with_arg(
|
||||
tree->cmp_arg, key, current->value);
|
||||
} else {
|
||||
result = tree->compare(key, current->value);
|
||||
}
|
||||
|
||||
if (result > 0) {
|
||||
|
||||
ub_node = current;
|
||||
current = current->right;
|
||||
|
||||
} else if (result < 0) {
|
||||
|
||||
current = current->left;
|
||||
|
||||
} else {
|
||||
ub_node = current;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return(ub_node);
|
||||
}
|
||||
|
||||
/**********************************************************************//**
|
||||
Find the node that has the greatest key that is <= key.
|
||||
@return value of result */
|
||||
@ -1191,19 +1094,6 @@ rbt_prev(
|
||||
return(current ? rbt_find_predecessor(tree, current) : NULL);
|
||||
}
|
||||
|
||||
/**********************************************************************//**
|
||||
Reset the tree. Delete all the nodes. */
|
||||
void
|
||||
rbt_clear(
|
||||
/*======*/
|
||||
ib_rbt_t* tree) /*!< in: rb tree */
|
||||
{
|
||||
rbt_free_node(ROOT(tree), tree->nil);
|
||||
|
||||
tree->n_nodes = 0;
|
||||
tree->root->left = tree->root->right = tree->nil;
|
||||
}
|
||||
|
||||
/**********************************************************************//**
|
||||
Merge the node from dst into src. Return the number of nodes merged.
|
||||
@return no. of recs merged */
|
||||
@ -1232,53 +1122,7 @@ rbt_merge_uniq(
|
||||
return(n_merged);
|
||||
}
|
||||
|
||||
/**********************************************************************//**
|
||||
Merge the node from dst into src. Return the number of nodes merged.
|
||||
Delete the nodes from src after copying node to dst. As a side effect
|
||||
the duplicates will be left untouched in the src.
|
||||
@return no. of recs merged */
|
||||
ulint
|
||||
rbt_merge_uniq_destructive(
|
||||
/*=======================*/
|
||||
ib_rbt_t* dst, /*!< in: dst rb tree */
|
||||
ib_rbt_t* src) /*!< in: src rb tree */
|
||||
{
|
||||
ib_rbt_bound_t parent;
|
||||
ib_rbt_node_t* src_node;
|
||||
ulint old_size = rbt_size(dst);
|
||||
|
||||
if (rbt_empty(src) || dst == src) {
|
||||
return(0);
|
||||
}
|
||||
|
||||
for (src_node = (ib_rbt_node_t*) rbt_first(src); src_node; /* */) {
|
||||
ib_rbt_node_t* prev = src_node;
|
||||
|
||||
src_node = (ib_rbt_node_t*) rbt_next(src, prev);
|
||||
|
||||
/* Skip duplicates. */
|
||||
if (rbt_search(dst, &parent, prev->value) != 0) {
|
||||
|
||||
/* Remove and reset the node but preserve
|
||||
the node (data) value. */
|
||||
rbt_remove_node_and_rebalance(src, prev);
|
||||
|
||||
/* The nil should be taken from the dst tree. */
|
||||
prev->parent = prev->left = prev->right = dst->nil;
|
||||
rbt_tree_add_child(dst, &parent, prev);
|
||||
rbt_balance_tree(dst, prev);
|
||||
|
||||
++dst->n_nodes;
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(IB_RBT_TESTING)
|
||||
ut_a(rbt_validate(dst));
|
||||
ut_a(rbt_validate(src));
|
||||
#endif
|
||||
return(rbt_size(dst) - old_size);
|
||||
}
|
||||
|
||||
#if defined UNIV_DEBUG || defined IB_RBT_TESTING
|
||||
/**********************************************************************//**
|
||||
Check that every path from the root to the leaves has the same count and
|
||||
the tree nodes are in order.
|
||||
@ -1294,14 +1138,4 @@ rbt_validate(
|
||||
|
||||
return(FALSE);
|
||||
}
|
||||
|
||||
/**********************************************************************//**
|
||||
Iterate over the tree in depth first order. */
|
||||
void
|
||||
rbt_print(
|
||||
/*======*/
|
||||
const ib_rbt_t* tree, /*!< in: tree to traverse */
|
||||
ib_rbt_print_node print) /*!< in: print function */
|
||||
{
|
||||
rbt_print_subtree(tree, ROOT(tree), print);
|
||||
}
|
||||
#endif /* UNIV_DEBUG || IB_RBT_TESTING */
|
||||
|
Loading…
x
Reference in New Issue
Block a user