diff options
Diffstat (limited to 'storage/xtradb/include/dict0dict.h')
-rw-r--r-- | storage/xtradb/include/dict0dict.h | 988 |
1 files changed, 723 insertions, 265 deletions
diff --git a/storage/xtradb/include/dict0dict.h b/storage/xtradb/include/dict0dict.h index 8c6620b94b3..6669f60b95a 100644 --- a/storage/xtradb/include/dict0dict.h +++ b/storage/xtradb/include/dict0dict.h @@ -1,6 +1,7 @@ /***************************************************************************** Copyright (c) 1996, 2013, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2012, Facebook Inc. 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 @@ -27,6 +28,7 @@ Created 1/8/1996 Heikki Tuuri #define dict0dict_h #include "univ.i" +#include "db0err.h" #include "dict0types.h" #include "dict0mem.h" #include "data0type.h" @@ -39,6 +41,7 @@ Created 1/8/1996 Heikki Tuuri #include "ut0rnd.h" #include "ut0byte.h" #include "trx0types.h" +#include "row0types.h" #ifndef UNIV_HOTBACKUP # include "sync0sync.h" @@ -49,7 +52,8 @@ UNIV_INTERN void dict_casedn_str( /*============*/ - char* a); /*!< in/out: string to put in lower case */ + char* a) /*!< in/out: string to put in lower case */ + __attribute__((nonnull)); /********************************************************************//** Get the database name length in a table name. @return database name length */ @@ -57,34 +61,88 @@ UNIV_INTERN ulint dict_get_db_name_len( /*=================*/ - const char* name); /*!< in: table name in the form + const char* name) /*!< in: table name in the form dbname '/' tablename */ + __attribute__((nonnull, warn_unused_result)); +/*********************************************************************//** +Open a table from its database and table name, this is currently used by +foreign constraint parser to get the referenced table. +@return complete table name with database and table name, allocated from +heap memory passed in */ +UNIV_INTERN +char* +dict_get_referenced_table( +/*======================*/ + const char* name, /*!< in: foreign key table name */ + const char* database_name, /*!< in: table db name */ + ulint database_name_len,/*!< in: db name length */ + const char* table_name, /*!< in: table name */ + ulint table_name_len, /*!< in: table name length */ + dict_table_t** table, /*!< out: table object or NULL */ + mem_heap_t* heap); /*!< in: heap memory */ +/*********************************************************************//** +Frees a foreign key struct. */ +UNIV_INTERN +void +dict_foreign_free( +/*==============*/ + dict_foreign_t* foreign); /*!< in, own: foreign key struct */ +/*********************************************************************//** +Finds the highest [number] for foreign key constraints of the table. Looks +only at the >= 4.0.18-format id's, which are of the form +databasename/tablename_ibfk_[number]. +@return highest number, 0 if table has no new format foreign key constraints */ +UNIV_INTERN +ulint +dict_table_get_highest_foreign_id( +/*==============================*/ + dict_table_t* table); /*!< in: table in the dictionary + memory cache */ /********************************************************************//** Return the end of table name where we have removed dbname and '/'. @return table name */ - +UNIV_INTERN const char* dict_remove_db_name( /*================*/ - const char* name); /*!< in: table name in the form + const char* name) /*!< in: table name in the form dbname '/' tablename */ + __attribute__((nonnull, warn_unused_result)); + +/** Operation to perform when opening a table */ +enum dict_table_op_t { + /** Expect the tablespace to exist. */ + DICT_TABLE_OP_NORMAL = 0, + /** Drop any orphan indexes after an aborted online index creation */ + DICT_TABLE_OP_DROP_ORPHAN, + /** Silently load the tablespace if it does not exist, + and do not load the definitions of incomplete indexes. */ + DICT_TABLE_OP_LOAD_TABLESPACE +}; + /**********************************************************************//** Returns a table object based on table id. @return table, NULL if does not exist */ UNIV_INTERN dict_table_t* -dict_table_get_on_id( -/*=================*/ - table_id_t table_id, /*!< in: table id */ - trx_t* trx); /*!< in: transaction handle */ +dict_table_open_on_id( +/*==================*/ + table_id_t table_id, /*!< in: table id */ + ibool dict_locked, /*!< in: TRUE=data dictionary locked */ + dict_table_op_t table_op) /*!< in: operation to perform */ + __attribute__((warn_unused_result)); /********************************************************************//** -Decrements the count of open MySQL handles to a table. */ +Decrements the count of open handles to a table. */ UNIV_INTERN void -dict_table_decrement_handle_count( -/*==============================*/ +dict_table_close( +/*=============*/ dict_table_t* table, /*!< in/out: table */ - ibool dict_locked); /*!< in: TRUE=data dictionary locked */ + ibool dict_locked, /*!< in: TRUE=data dictionary locked */ + ibool try_drop) /*!< in: TRUE=try to drop any orphan + indexes after an aborted online + index creation */ + __attribute__((nonnull)); /**********************************************************************//** Inits the data dictionary module. */ UNIV_INTERN @@ -108,7 +166,8 @@ UNIV_INLINE ulint dict_col_get_mbminlen( /*==================*/ - const dict_col_t* col); /*!< in: column */ + const dict_col_t* col) /*!< in: column */ + __attribute__((nonnull, warn_unused_result)); /*********************************************************************//** Gets the maximum number of bytes per character. @return maximum multi-byte char size, in bytes */ @@ -116,7 +175,8 @@ UNIV_INLINE ulint dict_col_get_mbmaxlen( /*==================*/ - const dict_col_t* col); /*!< in: column */ + const dict_col_t* col) /*!< in: column */ + __attribute__((nonnull, warn_unused_result)); /*********************************************************************//** Sets the minimum and maximum number of bytes per character. */ UNIV_INLINE @@ -126,8 +186,9 @@ dict_col_set_mbminmaxlen( dict_col_t* col, /*!< in/out: column */ ulint mbminlen, /*!< in: minimum multi-byte character size, in bytes */ - ulint mbmaxlen); /*!< in: minimum multi-byte + ulint mbmaxlen) /*!< in: minimum multi-byte character size, in bytes */ + __attribute__((nonnull)); /*********************************************************************//** Gets the column data type. */ UNIV_INLINE @@ -135,10 +196,11 @@ void dict_col_copy_type( /*===============*/ const dict_col_t* col, /*!< in: column */ - dtype_t* type); /*!< out: data type */ + dtype_t* type) /*!< out: data type */ + __attribute__((nonnull)); /**********************************************************************//** Determine bytes of column prefix to be stored in the undo log. Please -note if the table format is UNIV_FORMAT_A (< DICT_TF_FORMAT_ZIP), no prefix +note if the table format is UNIV_FORMAT_A (< UNIV_FORMAT_B), no prefix needs to be stored in the undo log. @return bytes of column prefix to be stored in the undo log */ UNIV_INLINE @@ -146,9 +208,9 @@ ulint dict_max_field_len_store_undo( /*==========================*/ dict_table_t* table, /*!< in: table */ - const dict_col_t* col); /*!< in: column which index prefix + const dict_col_t* col) /*!< in: column which index prefix is based on */ - + __attribute__((nonnull, warn_unused_result)); #endif /* !UNIV_HOTBACKUP */ #ifdef UNIV_DEBUG /*********************************************************************//** @@ -159,7 +221,8 @@ ibool dict_col_type_assert_equal( /*=======================*/ const dict_col_t* col, /*!< in: column */ - const dtype_t* type); /*!< in: data type */ + const dtype_t* type) /*!< in: data type */ + __attribute__((nonnull, warn_unused_result)); #endif /* UNIV_DEBUG */ #ifndef UNIV_HOTBACKUP /***********************************************************************//** @@ -169,7 +232,8 @@ UNIV_INLINE ulint dict_col_get_min_size( /*==================*/ - const dict_col_t* col); /*!< in: column */ + const dict_col_t* col) /*!< in: column */ + __attribute__((nonnull, warn_unused_result)); /***********************************************************************//** Returns the maximum size of the column. @return maximum size */ @@ -177,7 +241,8 @@ UNIV_INLINE ulint dict_col_get_max_size( /*==================*/ - const dict_col_t* col); /*!< in: column */ + const dict_col_t* col) /*!< in: column */ + __attribute__((nonnull, warn_unused_result)); /***********************************************************************//** Returns the size of a fixed size column, 0 if not a fixed size column. @return fixed size, or 0 */ @@ -186,7 +251,8 @@ ulint dict_col_get_fixed_size( /*====================*/ const dict_col_t* col, /*!< in: column */ - ulint comp); /*!< in: nonzero=ROW_FORMAT=COMPACT */ + ulint comp) /*!< in: nonzero=ROW_FORMAT=COMPACT */ + __attribute__((nonnull, warn_unused_result)); /***********************************************************************//** Returns the ROW_FORMAT=REDUNDANT stored SQL NULL size of a column. For fixed length types it is the fixed length of the type, otherwise 0. @@ -196,8 +262,8 @@ ulint dict_col_get_sql_null_size( /*=======================*/ const dict_col_t* col, /*!< in: column */ - ulint comp); /*!< in: nonzero=ROW_FORMAT=COMPACT */ - + ulint comp) /*!< in: nonzero=ROW_FORMAT=COMPACT */ + __attribute__((nonnull, warn_unused_result)); /*********************************************************************//** Gets the column number. @return col->ind, table column position (starting from 0) */ @@ -205,7 +271,8 @@ UNIV_INLINE ulint dict_col_get_no( /*============*/ - const dict_col_t* col); /*!< in: column */ + const dict_col_t* col) /*!< in: column */ + __attribute__((nonnull, warn_unused_result)); /*********************************************************************//** Gets the column position in the clustered index. */ UNIV_INLINE @@ -213,7 +280,8 @@ ulint dict_col_get_clust_pos( /*===================*/ const dict_col_t* col, /*!< in: table column */ - const dict_index_t* clust_index); /*!< in: clustered index */ + const dict_index_t* clust_index) /*!< in: clustered index */ + __attribute__((nonnull, warn_unused_result)); /****************************************************************//** If the given column name is reserved for InnoDB system columns, return TRUE. @@ -222,14 +290,16 @@ UNIV_INTERN ibool dict_col_name_is_reserved( /*======================*/ - const char* name); /*!< in: column name */ + const char* name) /*!< in: column name */ + __attribute__((nonnull, warn_unused_result)); /********************************************************************//** Acquire the autoinc lock. */ UNIV_INTERN void dict_table_autoinc_lock( /*====================*/ - dict_table_t* table); /*!< in/out: table */ + dict_table_t* table) /*!< in/out: table */ + __attribute__((nonnull)); /********************************************************************//** Unconditionally set the autoinc counter. */ UNIV_INTERN @@ -237,7 +307,8 @@ void dict_table_autoinc_initialize( /*==========================*/ dict_table_t* table, /*!< in/out: table */ - ib_uint64_t value); /*!< in: next value to assign to a row */ + ib_uint64_t value) /*!< in: next value to assign to a row */ + __attribute__((nonnull)); /********************************************************************//** Reads the next autoinc value (== autoinc counter value), 0 if not yet initialized. @@ -246,7 +317,8 @@ UNIV_INTERN ib_uint64_t dict_table_autoinc_read( /*====================*/ - const dict_table_t* table); /*!< in: table */ + const dict_table_t* table) /*!< in: table */ + __attribute__((nonnull, warn_unused_result)); /********************************************************************//** Updates the autoinc counter if the value supplied is greater than the current value. */ @@ -256,14 +328,16 @@ dict_table_autoinc_update_if_greater( /*=================================*/ dict_table_t* table, /*!< in/out: table */ - ib_uint64_t value); /*!< in: value which was assigned to a row */ + ib_uint64_t value) /*!< in: value which was assigned to a row */ + __attribute__((nonnull)); /********************************************************************//** Release the autoinc lock. */ UNIV_INTERN void dict_table_autoinc_unlock( /*======================*/ - dict_table_t* table); /*!< in/out: table */ + dict_table_t* table) /*!< in/out: table */ + __attribute__((nonnull)); #endif /* !UNIV_HOTBACKUP */ /**********************************************************************//** Adds system columns to a table object. */ @@ -272,7 +346,8 @@ void dict_table_add_system_columns( /*==========================*/ dict_table_t* table, /*!< in/out: table */ - mem_heap_t* heap); /*!< in: temporary heap */ + mem_heap_t* heap) /*!< in: temporary heap */ + __attribute__((nonnull)); #ifndef UNIV_HOTBACKUP /**********************************************************************//** Adds a table object to the dictionary cache. */ @@ -280,27 +355,32 @@ UNIV_INTERN void dict_table_add_to_cache( /*====================*/ - dict_table_t* table, /*!< in: table */ - mem_heap_t* heap); /*!< in: temporary heap */ + dict_table_t* table, /*!< in: table */ + ibool can_be_evicted, /*!< in: TRUE if can be evicted*/ + mem_heap_t* heap) /*!< in: temporary heap */ + __attribute__((nonnull)); /**********************************************************************//** Removes a table object from the dictionary cache. */ UNIV_INTERN void dict_table_remove_from_cache( /*=========================*/ - dict_table_t* table); /*!< in, own: table */ + dict_table_t* table) /*!< in, own: table */ + __attribute__((nonnull)); /**********************************************************************//** Renames a table object. @return TRUE if success */ UNIV_INTERN -ibool +dberr_t dict_table_rename_in_cache( /*=======================*/ dict_table_t* table, /*!< in/out: table */ const char* new_name, /*!< in: new name */ - ibool rename_also_foreigns);/*!< in: in ALTER TABLE we want + ibool rename_also_foreigns) + /*!< in: in ALTER TABLE we want to preserve the original table name in constraints which reference it */ + __attribute__((nonnull, warn_unused_result)); /**********************************************************************//** Removes an index from the dictionary cache. */ UNIV_INTERN @@ -308,7 +388,8 @@ void dict_index_remove_from_cache( /*=========================*/ dict_table_t* table, /*!< in/out: table */ - dict_index_t* index); /*!< in, own: index */ + dict_index_t* index) /*!< in, own: index */ + __attribute__((nonnull)); /**********************************************************************//** Change the id of a table object in the dictionary cache. This is used in DISCARD TABLESPACE. */ @@ -317,7 +398,16 @@ void dict_table_change_id_in_cache( /*==========================*/ dict_table_t* table, /*!< in/out: table object already in cache */ - table_id_t new_id);/*!< in: new id to set */ + table_id_t new_id) /*!< in: new id to set */ + __attribute__((nonnull)); +/**********************************************************************//** +Removes a foreign constraint struct from the dictionary cache. */ +UNIV_INTERN +void +dict_foreign_remove_from_cache( +/*===========================*/ + dict_foreign_t* foreign) /*!< in, own: foreign constraint */ + __attribute__((nonnull)); /**********************************************************************//** Adds a foreign key constraint object to the dictionary cache. May free the object if there already is an object with the same identifier in. @@ -325,14 +415,20 @@ At least one of foreign table or referenced table must already be in the dictionary cache! @return DB_SUCCESS or error code */ UNIV_INTERN -ulint +dberr_t dict_foreign_add_to_cache( /*======================*/ - dict_foreign_t* foreign, /*!< in, own: foreign key - constraint */ - ibool check_charsets, /*!< in: TRUE=check charset - compatibility */ - dict_err_ignore_t ignore_err); /*!< in: error to be ignored */ + dict_foreign_t* foreign, + /*!< in, own: foreign key constraint */ + const char** col_names, + /*!< in: column names, or NULL to use + foreign->foreign_table->col_names */ + bool check_charsets, + /*!< in: whether to check charset + compatibility */ + dict_err_ignore_t ignore_err) + /*!< in: error to be ignored */ + __attribute__((nonnull(1), warn_unused_result)); /*********************************************************************//** Check if the index is referenced by a foreign key, if TRUE return the matching instance NULL otherwise. @@ -343,7 +439,8 @@ dict_foreign_t* dict_table_get_referenced_constraint( /*=================================*/ dict_table_t* table, /*!< in: InnoDB table */ - dict_index_t* index); /*!< in: InnoDB index */ + dict_index_t* index) /*!< in: InnoDB index */ + __attribute__((nonnull, warn_unused_result)); /*********************************************************************//** Checks if a table is referenced by foreign keys. @return TRUE if table is referenced by a foreign key */ @@ -351,17 +448,33 @@ UNIV_INTERN ibool dict_table_is_referenced_by_foreign_key( /*====================================*/ - const dict_table_t* table); /*!< in: InnoDB table */ + const dict_table_t* table) /*!< in: InnoDB table */ + __attribute__((nonnull, warn_unused_result)); /**********************************************************************//** -Replace the index in the foreign key list that matches this index's -definition with an equivalent index. */ +Replace the index passed in with another equivalent index in the +foreign key lists of the table. +@return whether all replacements were found */ UNIV_INTERN -void -dict_table_replace_index_in_foreign_list( -/*=====================================*/ - dict_table_t* table, /*!< in/out: table */ - dict_index_t* index, /*!< in: index to be replaced */ - const trx_t* trx); /*!< in: transaction handle */ +bool +dict_foreign_replace_index( +/*=======================*/ + dict_table_t* table, /*!< in/out: table */ + const char** col_names, + /*!< in: column names, or NULL + to use table->col_names */ + const dict_index_t* index) /*!< in: index to be replaced */ + __attribute__((nonnull(1,3), warn_unused_result)); +/**********************************************************************//** +Determines whether a string starts with the specified keyword. +@return TRUE if str starts with keyword */ +UNIV_INTERN +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 */ + __attribute__((nonnull, warn_unused_result)); /*********************************************************************//** Checks if a index is defined for a foreign key constraint. Index is a part of a foreign key constraint if the index is referenced by foreign key @@ -373,7 +486,8 @@ dict_foreign_t* dict_table_get_foreign_constraint( /*==============================*/ dict_table_t* table, /*!< in: InnoDB table */ - dict_index_t* index); /*!< in: InnoDB index */ + dict_index_t* index) /*!< in: InnoDB index */ + __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 @@ -383,7 +497,7 @@ bot participating tables. The indexes are allowed to contain more fields than mentioned in the constraint. @return error code or DB_SUCCESS */ UNIV_INTERN -ulint +dberr_t dict_create_foreign_constraints( /*============================*/ trx_t* trx, /*!< in: transaction */ @@ -399,15 +513,16 @@ dict_create_foreign_constraints( const char* name, /*!< in: table full name in the normalized form database_name/table_name */ - ibool reject_fks); /*!< in: if TRUE, fail with error + ibool reject_fks) /*!< in: if TRUE, fail with error code DB_CANNOT_ADD_CONSTRAINT if any foreign keys are found. */ + __attribute__((nonnull, warn_unused_result)); /**********************************************************************//** Parses the CONSTRAINT id's to be dropped in an ALTER TABLE statement. @return DB_SUCCESS or DB_CANNOT_DROP_CONSTRAINT if syntax error or the constraint id does not match */ UNIV_INTERN -ulint +dberr_t dict_foreign_parse_drop_constraints( /*================================*/ mem_heap_t* heap, /*!< in: heap from which we can @@ -416,85 +531,57 @@ dict_foreign_parse_drop_constraints( dict_table_t* table, /*!< in: table */ ulint* n, /*!< out: number of constraints to drop */ - const char*** constraints_to_drop); /*!< out: id's of the + const char*** constraints_to_drop) /*!< out: id's of the constraints to drop */ + __attribute__((nonnull, warn_unused_result)); /**********************************************************************//** -Returns a table object and optionally increment its MySQL open handle count. +Returns a table object and increments its open handle count. NOTE! This is a high-level function to be used mainly from outside the -'dict' directory. Inside this directory dict_table_get_low is usually the -appropriate function. +'dict' directory. Inside this directory dict_table_get_low +is usually the appropriate function. @return table, NULL if does not exist */ UNIV_INTERN dict_table_t* -dict_table_get( -/*===========*/ - const char* table_name, - /*!< in: table name */ - ibool inc_mysql_count, - /*!< in: whether to increment the open - handle count on the table */ - dict_err_ignore_t ignore_err); - /*!< in: errors to ignore when loading - the table */ -/**********************************************************************//** -Returns a index object, based on table and index id, and memoryfixes it. -@return index, NULL if does not exist */ -UNIV_INTERN -dict_index_t* -dict_index_get_on_id_low( -/*=====================*/ - dict_table_t* table, /*!< in: table */ - index_id_t index_id); /*!< in: index id */ -/**********************************************************************//** -Checks if a table is in the dictionary cache. -@return table, NULL if not found */ - -UNIV_INLINE -dict_table_t* -dict_table_check_if_in_cache_low( -/*=============================*/ - const char* table_name); /*!< in: table name */ -/**********************************************************************//** -Gets a table; loads it to the dictionary cache if necessary. A low-level -function. -@return table, NULL if not found */ -UNIV_INLINE -dict_table_t* -dict_table_get_low( -/*===============*/ +dict_table_open_on_name( +/*====================*/ const char* table_name, /*!< in: table name */ + ibool dict_locked, /*!< in: TRUE=data dictionary locked */ + ibool try_drop, /*!< in: TRUE=try to drop any orphan + indexes after an aborted online + index creation */ dict_err_ignore_t - ignore_err); /*!< in: error to be ignored when - loading a table definition */ -/**********************************************************************//** -Returns a table object based on table id. -@return table, NULL if does not exist */ -UNIV_INLINE -dict_table_t* -dict_table_get_on_id_low( -/*=====================*/ - table_id_t table_id); /*!< in: table id */ -/**********************************************************************//** -Find an index that is equivalent to the one passed in and is not marked -for deletion. -@return index equivalent to foreign->foreign_index, or NULL */ -UNIV_INTERN -dict_index_t* -dict_foreign_find_equiv_index( -/*==========================*/ - dict_foreign_t* foreign);/*!< in: foreign key */ -/**********************************************************************//** -Returns an index object by matching on the name and column names and -if more than one index matches return the index with the max id + ignore_err) /*!< in: error to be ignored when + loading the table */ + __attribute__((nonnull, warn_unused_result)); + +/*********************************************************************//** +Tries to find an index whose first fields are the columns in the array, +in the same order and is not marked for deletion and is not the same +as types_idx. @return matching index, NULL if not found */ UNIV_INTERN dict_index_t* -dict_table_get_index_by_max_id( -/*===========================*/ - dict_table_t* table, /*!< in: table */ - const char* name, /*!< in: the index name to find */ - const char** columns,/*!< in: array of column names */ - ulint n_cols);/*!< in: number of columns */ +dict_foreign_find_index( +/*====================*/ + const dict_table_t* table, /*!< in: table */ + const char** col_names, + /*!< in: column names, or NULL + to use table->col_names */ + const char** columns,/*!< in: array of column names */ + ulint n_cols, /*!< in: number of columns */ + const dict_index_t* types_idx, + /*!< in: NULL or an index + whose types the column types + must match */ + bool check_charsets, + /*!< in: whether to check + charsets. only has an effect + if types_idx != NULL */ + ulint check_null) + /*!< in: nonzero if none of + the columns must be declared + NOT NULL */ + __attribute__((nonnull(1,3), warn_unused_result)); /**********************************************************************//** Returns a column's name. @return column name. NOTE: not guaranteed to stay valid if table is @@ -504,29 +591,16 @@ const char* dict_table_get_col_name( /*====================*/ const dict_table_t* table, /*!< in: table */ - ulint col_nr);/*!< in: column number */ - + ulint col_nr) /*!< in: column number */ + __attribute__((nonnull, warn_unused_result)); /**********************************************************************//** -Prints a table definition. */ +Prints a table data. */ UNIV_INTERN void dict_table_print( /*=============*/ - dict_table_t* table); /*!< in: table */ -/**********************************************************************//** -Prints a table data. */ -UNIV_INTERN -void -dict_table_print_low( -/*=================*/ - dict_table_t* table); /*!< in: table */ -/**********************************************************************//** -Prints a table data when we know the table name. */ -UNIV_INTERN -void -dict_table_print_by_name( -/*=====================*/ - const char* name); /*!< in: table name */ + dict_table_t* table) /*!< in: table */ + __attribute__((nonnull)); /**********************************************************************//** Outputs info on foreign keys of a table. */ UNIV_INTERN @@ -539,7 +613,8 @@ dict_print_info_on_foreign_keys( of SHOW TABLE STATUS */ FILE* file, /*!< in: file where to print */ trx_t* trx, /*!< in: transaction */ - dict_table_t* table); /*!< in: table */ + dict_table_t* table) /*!< in: table */ + __attribute__((nonnull)); /**********************************************************************//** Outputs info on a foreign key of a table in a format suitable for CREATE TABLE. */ @@ -550,7 +625,8 @@ dict_print_info_on_foreign_key_in_create_format( FILE* file, /*!< in: file where to print */ trx_t* trx, /*!< in: transaction */ dict_foreign_t* foreign, /*!< in: foreign key constraint */ - ibool add_newline); /*!< in: whether to add a newline */ + ibool add_newline) /*!< in: whether to add a newline */ + __attribute__((nonnull(1,3))); /********************************************************************//** Displays the names of the index and the table. */ UNIV_INTERN @@ -558,8 +634,38 @@ void dict_index_name_print( /*==================*/ FILE* file, /*!< in: output stream */ - trx_t* trx, /*!< in: transaction */ - const dict_index_t* index); /*!< in: index to print */ + const trx_t* trx, /*!< in: transaction */ + const dict_index_t* index) /*!< in: index to print */ + __attribute__((nonnull(1,3))); +/*********************************************************************//** +Tries to find an index whose first fields are the columns in the array, +in the same order and is not marked for deletion and is not the same +as types_idx. +@return matching index, NULL if not found */ +UNIV_INTERN +bool +dict_foreign_qualify_index( +/*====================*/ + const dict_table_t* table, /*!< in: table */ + const char** col_names, + /*!< in: column names, or NULL + to use table->col_names */ + const char** columns,/*!< in: array of column names */ + ulint n_cols, /*!< in: number of columns */ + const dict_index_t* index, /*!< in: index to check */ + const dict_index_t* types_idx, + /*!< in: NULL or an index + whose types the column types + must match */ + bool check_charsets, + /*!< in: whether to check + charsets. only has an effect + if types_idx != NULL */ + ulint check_null) + /*!< in: nonzero if none of + the columns must be declared + NOT NULL */ + __attribute__((nonnull(1,3), warn_unused_result)); #ifdef UNIV_DEBUG /********************************************************************//** Gets the first index on the table (the clustered index). @@ -568,7 +674,17 @@ UNIV_INLINE dict_index_t* dict_table_get_first_index( /*=======================*/ - const dict_table_t* table); /*!< in: table */ + const dict_table_t* table) /*!< in: table */ + __attribute__((nonnull, warn_unused_result)); +/********************************************************************//** +Gets the last index on the table. +@return index, NULL if none exists */ +UNIV_INLINE +dict_index_t* +dict_table_get_last_index( +/*=======================*/ + const dict_table_t* table) /*!< in: table */ + __attribute__((nonnull, warn_unused_result)); /********************************************************************//** Gets the next index on the table. @return index, NULL if none left */ @@ -576,9 +692,11 @@ UNIV_INLINE dict_index_t* dict_table_get_next_index( /*======================*/ - const dict_index_t* index); /*!< in: index */ + const dict_index_t* index) /*!< in: index */ + __attribute__((nonnull, warn_unused_result)); #else /* UNIV_DEBUG */ # define dict_table_get_first_index(table) UT_LIST_GET_FIRST((table)->indexes) +# define dict_table_get_last_index(table) UT_LIST_GET_LAST((table)->indexes) # define dict_table_get_next_index(index) UT_LIST_GET_NEXT(indexes, index) #endif /* UNIV_DEBUG */ #endif /* !UNIV_HOTBACKUP */ @@ -633,6 +751,17 @@ dict_index_is_sec_or_ibuf( const dict_index_t* index) /*!< in: index */ __attribute__((nonnull, pure, warn_unused_result)); +/************************************************************************ +Gets the all the FTS indexes for the table. NOTE: must not be called for +tables which do not have an FTS-index. */ +UNIV_INTERN +ulint +dict_table_get_all_fts_indexes( +/*===========================*/ + /* out: number of indexes collected */ + dict_table_t* table, /* in: table */ + ib_vector_t* indexes)/* out: vector for collecting FTS indexes */ + __attribute__((nonnull)); /********************************************************************//** Gets the number of user-defined columns in a table in the dictionary cache. @@ -662,6 +791,35 @@ dict_table_get_n_cols( /*==================*/ const dict_table_t* table) /*!< in: table */ __attribute__((nonnull, pure, warn_unused_result)); +/********************************************************************//** +Gets the approximately estimated number of rows in the table. +@return estimated number of rows */ +UNIV_INLINE +ib_uint64_t +dict_table_get_n_rows( +/*==================*/ + const dict_table_t* table) /*!< in: table */ + __attribute__((nonnull, warn_unused_result)); +/********************************************************************//** +Increment the number of rows in the table by one. +Notice that this operation is not protected by any latch, the number is +approximate. */ +UNIV_INLINE +void +dict_table_n_rows_inc( +/*==================*/ + dict_table_t* table) /*!< in/out: table */ + __attribute__((nonnull)); +/********************************************************************//** +Decrement the number of rows in the table by one. +Notice that this operation is not protected by any latch, the number is +approximate. */ +UNIV_INLINE +void +dict_table_n_rows_dec( +/*==================*/ + dict_table_t* table) /*!< in/out: table */ + __attribute__((nonnull)); #ifdef UNIV_DEBUG /********************************************************************//** Gets the nth column of a table. @@ -671,7 +829,8 @@ dict_col_t* dict_table_get_nth_col( /*===================*/ const dict_table_t* table, /*!< in: table */ - ulint pos); /*!< in: position of column */ + ulint pos) /*!< in: position of column */ + __attribute__((nonnull, warn_unused_result)); /********************************************************************//** Gets the given system column of a table. @return pointer to column object */ @@ -680,7 +839,8 @@ dict_col_t* dict_table_get_sys_col( /*===================*/ const dict_table_t* table, /*!< in: table */ - ulint sys); /*!< in: DATA_ROW_ID, ... */ + ulint sys) /*!< in: DATA_ROW_ID, ... */ + __attribute__((nonnull, warn_unused_result)); #else /* UNIV_DEBUG */ #define dict_table_get_nth_col(table, pos) \ ((table)->cols + (pos)) @@ -695,7 +855,8 @@ ulint dict_table_get_sys_col_no( /*======================*/ const dict_table_t* table, /*!< in: table */ - ulint sys); /*!< in: DATA_ROW_ID, ... */ + ulint sys) /*!< in: DATA_ROW_ID, ... */ + __attribute__((nonnull, warn_unused_result)); #ifndef UNIV_HOTBACKUP /********************************************************************//** Returns the minimum data size of an index record. @@ -704,7 +865,8 @@ UNIV_INLINE ulint dict_index_get_min_size( /*====================*/ - const dict_index_t* index); /*!< in: index */ + const dict_index_t* index) /*!< in: index */ + __attribute__((nonnull, warn_unused_result)); #endif /* !UNIV_HOTBACKUP */ /********************************************************************//** Check whether the table uses the compact page format. @@ -713,7 +875,8 @@ UNIV_INLINE ibool dict_table_is_comp( /*===============*/ - const dict_table_t* table); /*!< in: table */ + const dict_table_t* table) /*!< in: table */ + __attribute__((nonnull, warn_unused_result)); /********************************************************************//** Determine the file format of a table. @return file format version */ @@ -721,23 +884,53 @@ UNIV_INLINE ulint dict_table_get_format( /*==================*/ - const dict_table_t* table); /*!< in: table */ + const dict_table_t* table) /*!< in: table */ + __attribute__((nonnull, warn_unused_result)); +/********************************************************************//** +Determine the file format from a dict_table_t::flags. +@return file format version */ +UNIV_INLINE +ulint +dict_tf_get_format( +/*===============*/ + ulint flags) /*!< in: dict_table_t::flags */ + __attribute__((warn_unused_result)); /********************************************************************//** -Set the file format of a table. */ +Set the various values in a dict_table_t::flags pointer. */ UNIV_INLINE void -dict_table_set_format( -/*==================*/ - dict_table_t* table, /*!< in/out: table */ - ulint format);/*!< in: file format version */ +dict_tf_set( +/*========*/ + ulint* flags, /*!< in/out: table */ + rec_format_t format, /*!< in: file format */ + ulint zip_ssize, /*!< in: zip shift size */ + bool remote_path) /*!< in: table uses DATA DIRECTORY */ + __attribute__((nonnull)); +/********************************************************************//** +Convert a 32 bit integer table flags to the 32 bit integer that is +written into the tablespace header at the offset FSP_SPACE_FLAGS and is +also stored in the fil_space_t::flags field. The following chart shows +the translation of the low order bit. Other bits are the same. +========================= Low order bit ========================== + | REDUNDANT | COMPACT | COMPRESSED | DYNAMIC +dict_table_t::flags | 0 | 1 | 1 | 1 +fil_space_t::flags | 0 | 0 | 1 | 1 +================================================================== +@return tablespace flags (fil_space_t::flags) */ +UNIV_INLINE +ulint +dict_tf_to_fsp_flags( +/*=================*/ + ulint flags) /*!< in: dict_table_t::flags */ + __attribute__((const)); /********************************************************************//** Extract the compressed page size from table flags. @return compressed page size, or 0 if not compressed */ UNIV_INLINE ulint -dict_table_flags_to_zip_size( -/*=========================*/ - ulint flags) /*!< in: flags */ +dict_tf_get_zip_size( +/*=================*/ + ulint flags) /*!< in: flags */ __attribute__((const)); /********************************************************************//** Check whether the table uses the compressed compact page format. @@ -746,7 +939,8 @@ UNIV_INLINE ulint dict_table_zip_size( /*================*/ - const dict_table_t* table); /*!< in: table */ + const dict_table_t* table) /*!< in: table */ + __attribute__((nonnull, warn_unused_result)); #ifndef UNIV_HOTBACKUP /*********************************************************************//** Obtain exclusive locks on all index trees of the table. This is to prevent @@ -756,15 +950,16 @@ UNIV_INLINE void dict_table_x_lock_indexes( /*======================*/ - dict_table_t* table); /*!< in: table */ + dict_table_t* table) /*!< in: table */ + __attribute__((nonnull)); /*********************************************************************//** Release the exclusive locks on all index tree. */ UNIV_INLINE void dict_table_x_unlock_indexes( /*========================*/ - dict_table_t* table); /*!< in: table */ -#endif /* !UNIV_HOTBACKUP */ + dict_table_t* table) /*!< in: table */ + __attribute__((nonnull)); /********************************************************************//** Checks if a column is in the ordering columns of the clustered index of a table. Column prefixes are treated like whole columns. @@ -774,8 +969,17 @@ ibool dict_table_col_in_clustered_key( /*============================*/ const dict_table_t* table, /*!< in: table */ - ulint n); /*!< in: column number */ -#ifndef UNIV_HOTBACKUP + ulint n) /*!< in: column number */ + __attribute__((nonnull, warn_unused_result)); +/*******************************************************************//** +Check if the table has an FTS index. +@return TRUE if table has an FTS index */ +UNIV_INLINE +ibool +dict_table_has_fts_index( +/*=====================*/ + dict_table_t* table) /*!< in: table */ + __attribute__((nonnull, warn_unused_result)); /*******************************************************************//** Copies types of columns contained in table to tuple and sets all fields of the tuple to the SQL NULL value. This function should @@ -785,7 +989,20 @@ void dict_table_copy_types( /*==================*/ dtuple_t* tuple, /*!< in/out: data tuple */ - const dict_table_t* table); /*!< in: table */ + const dict_table_t* table) /*!< in: table */ + __attribute__((nonnull)); +/******************************************************************** +Wait until all the background threads of the given table have exited, i.e., +bg_threads == 0. Note: bg_threads_mutex must be reserved when +calling this. */ +UNIV_INTERN +void +dict_table_wait_for_bg_threads_to_exit( +/*===================================*/ + dict_table_t* table, /* in: table */ + ulint delay) /* in: time in microseconds to wait between + checks of bg_threads. */ + __attribute__((nonnull)); /**********************************************************************//** Looks for an index with the given id. NOTE that we do not reserve the dictionary mutex: this function is for emergency purposes like @@ -795,21 +1012,34 @@ UNIV_INTERN dict_index_t* dict_index_find_on_id_low( /*======================*/ - index_id_t id); /*!< in: index id */ + index_id_t id) /*!< in: index id */ + __attribute__((warn_unused_result)); +/**********************************************************************//** +Make room in the table cache by evicting an unused table. The unused table +should not be part of FK relationship and currently not used in any user +transaction. There is no guarantee that it will remove a table. +@return number of tables evicted. */ +UNIV_INTERN +ulint +dict_make_room_in_cache( +/*====================*/ + ulint max_tables, /*!< in: max tables allowed in cache */ + ulint pct_check); /*!< in: max percent to check */ /**********************************************************************//** Adds an index to the dictionary cache. @return DB_SUCCESS, DB_TOO_BIG_RECORD, or DB_CORRUPTION */ UNIV_INTERN -ulint +dberr_t dict_index_add_to_cache( /*====================*/ dict_table_t* table, /*!< in: table on which the index is */ dict_index_t* index, /*!< in, own: index; NOTE! The index memory object is freed in this function! */ ulint page_no,/*!< in: root page number of the index */ - ibool strict);/*!< in: TRUE=refuse to create the index + ibool strict) /*!< in: TRUE=refuse to create the index if records could be too big to fit in an B-tree page */ + __attribute__((nonnull, warn_unused_result)); /**********************************************************************//** Removes an index from the dictionary cache. */ UNIV_INTERN @@ -817,7 +1047,8 @@ void dict_index_remove_from_cache( /*=========================*/ dict_table_t* table, /*!< in/out: table */ - dict_index_t* index); /*!< in, own: index */ + dict_index_t* index) /*!< in, own: index */ + __attribute__((nonnull)); #endif /* !UNIV_HOTBACKUP */ /********************************************************************//** Gets the number of fields in the internal representation of an index, @@ -827,9 +1058,10 @@ UNIV_INLINE ulint dict_index_get_n_fields( /*====================*/ - const dict_index_t* index); /*!< in: an internal + const dict_index_t* index) /*!< in: an internal representation of index (in the dictionary cache) */ + __attribute__((nonnull, warn_unused_result)); /********************************************************************//** Gets the number of fields in the internal representation of an index that uniquely determine the position of an index entry in the index, if @@ -840,8 +1072,9 @@ UNIV_INLINE ulint dict_index_get_n_unique( /*====================*/ - const dict_index_t* index); /*!< in: an internal representation + const dict_index_t* index) /*!< in: an internal representation of index (in the dictionary cache) */ + __attribute__((nonnull, warn_unused_result)); /********************************************************************//** Gets the number of fields in the internal representation of an index which uniquely determine the position of an index entry in the index, if @@ -851,8 +1084,9 @@ UNIV_INLINE ulint dict_index_get_n_unique_in_tree( /*============================*/ - const dict_index_t* index); /*!< in: an internal representation + const dict_index_t* index) /*!< in: an internal representation of index (in the dictionary cache) */ + __attribute__((nonnull, warn_unused_result)); /********************************************************************//** Gets the number of user-defined ordering fields in the index. In the internal representation we add the row id to the ordering fields to make all indexes @@ -863,8 +1097,9 @@ UNIV_INLINE ulint dict_index_get_n_ordering_defined_by_user( /*======================================*/ - const dict_index_t* index); /*!< in: an internal representation + const dict_index_t* index) /*!< in: an internal representation of index (in the dictionary cache) */ + __attribute__((nonnull, warn_unused_result)); #ifdef UNIV_DEBUG /********************************************************************//** Gets the nth field of an index. @@ -874,7 +1109,8 @@ dict_field_t* dict_index_get_nth_field( /*=====================*/ const dict_index_t* index, /*!< in: index */ - ulint pos); /*!< in: position of field */ + ulint pos) /*!< in: position of field */ + __attribute__((nonnull, warn_unused_result)); #else /* UNIV_DEBUG */ # define dict_index_get_nth_field(index, pos) ((index)->fields + (pos)) #endif /* UNIV_DEBUG */ @@ -886,7 +1122,8 @@ const dict_col_t* dict_index_get_nth_col( /*===================*/ const dict_index_t* index, /*!< in: index */ - ulint pos); /*!< in: position of the field */ + ulint pos) /*!< in: position of the field */ + __attribute__((nonnull, warn_unused_result)); /********************************************************************//** Gets the column number of the nth field in an index. @return column number */ @@ -895,17 +1132,19 @@ ulint dict_index_get_nth_col_no( /*======================*/ const dict_index_t* index, /*!< in: index */ - ulint pos); /*!< in: position of the field */ + ulint pos) /*!< in: position of the field */ + __attribute__((nonnull, warn_unused_result)); /********************************************************************//** Looks for column n in an index. @return position in internal representation of the index; ULINT_UNDEFINED if not contained */ -UNIV_INTERN +UNIV_INLINE ulint dict_index_get_nth_col_pos( /*=======================*/ const dict_index_t* index, /*!< in: index */ - ulint n); /*!< in: column number */ + ulint n) /*!< in: column number */ + __attribute__((nonnull, warn_unused_result)); /********************************************************************//** Looks for column n in an index. @return position in internal representation of the index; @@ -916,8 +1155,9 @@ dict_index_get_nth_col_or_prefix_pos( /*=================================*/ const dict_index_t* index, /*!< in: index */ ulint n, /*!< in: column number */ - ibool inc_prefix); /*!< in: TRUE=consider + ibool inc_prefix) /*!< in: TRUE=consider column prefixes too */ + __attribute__((nonnull, warn_unused_result)); /********************************************************************//** Returns TRUE if the index contains a column or a prefix of that column. @return TRUE if contains the column or its prefix */ @@ -926,7 +1166,8 @@ ibool dict_index_contains_col_or_prefix( /*==============================*/ const dict_index_t* index, /*!< in: index */ - ulint n); /*!< in: column number */ + ulint n) /*!< in: column number */ + __attribute__((nonnull, warn_unused_result)); /********************************************************************//** Looks for a matching field in an index. The column has to be the same. The column in index must be complete, or must contain a prefix longer than the @@ -940,7 +1181,8 @@ dict_index_get_nth_field_pos( /*=========================*/ const dict_index_t* index, /*!< in: index from which to search */ const dict_index_t* index2, /*!< in: index */ - ulint n); /*!< in: field number in index2 */ + ulint n) /*!< in: field number in index2 */ + __attribute__((nonnull, warn_unused_result)); /********************************************************************//** Looks for column n position in the clustered index. @return position in internal representation of the clustered index */ @@ -949,7 +1191,8 @@ ulint dict_table_get_nth_col_pos( /*=======================*/ const dict_table_t* table, /*!< in: table */ - ulint n); /*!< in: column number */ + ulint n) /*!< in: column number */ + __attribute__((nonnull, warn_unused_result)); /********************************************************************//** Returns the position of a system column in an index. @return position, ULINT_UNDEFINED if not contained */ @@ -958,7 +1201,8 @@ ulint dict_index_get_sys_col_pos( /*=======================*/ const dict_index_t* index, /*!< in: index */ - ulint type); /*!< in: DATA_ROW_ID, ... */ + ulint type) /*!< in: DATA_ROW_ID, ... */ + __attribute__((nonnull, warn_unused_result)); /*******************************************************************//** Adds a column to index. */ UNIV_INTERN @@ -968,7 +1212,8 @@ dict_index_add_col( dict_index_t* index, /*!< in/out: index */ const dict_table_t* table, /*!< in: table */ dict_col_t* col, /*!< in: column */ - ulint prefix_len); /*!< in: column prefix length */ + ulint prefix_len) /*!< in: column prefix length */ + __attribute__((nonnull)); #ifndef UNIV_HOTBACKUP /*******************************************************************//** Copies types of fields contained in index to tuple. */ @@ -978,8 +1223,9 @@ dict_index_copy_types( /*==================*/ dtuple_t* tuple, /*!< in/out: data tuple */ const dict_index_t* index, /*!< in: index */ - ulint n_fields); /*!< in: number of + ulint n_fields) /*!< in: number of field types to copy */ + __attribute__((nonnull)); #endif /* !UNIV_HOTBACKUP */ /*********************************************************************//** Gets the field column. @@ -988,7 +1234,8 @@ UNIV_INLINE const dict_col_t* dict_field_get_col( /*===============*/ - const dict_field_t* field); /*!< in: index field */ + const dict_field_t* field) /*!< in: index field */ + __attribute__((nonnull, warn_unused_result)); #ifndef UNIV_HOTBACKUP /**********************************************************************//** Returns an index object if it is found in the dictionary cache. @@ -998,7 +1245,8 @@ UNIV_INTERN dict_index_t* dict_index_get_if_in_cache_low( /*===========================*/ - index_id_t index_id); /*!< in: index id */ + index_id_t index_id) /*!< in: index id */ + __attribute__((warn_unused_result)); #if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG /**********************************************************************//** Returns an index object if it is found in the dictionary cache. @@ -1007,7 +1255,8 @@ UNIV_INTERN dict_index_t* dict_index_get_if_in_cache( /*=======================*/ - index_id_t index_id); /*!< in: index id */ + index_id_t index_id) /*!< in: index id */ + __attribute__((warn_unused_result)); #endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */ #ifdef UNIV_DEBUG /**********************************************************************//** @@ -1019,7 +1268,17 @@ ibool dict_index_check_search_tuple( /*==========================*/ const dict_index_t* index, /*!< in: index tree */ - const dtuple_t* tuple); /*!< in: tuple used in a search */ + const dtuple_t* tuple) /*!< in: tuple used in a search */ + __attribute__((nonnull, warn_unused_result)); +/** Whether and when to allow temporary index names */ +enum check_name { + /** Require all indexes to be complete. */ + CHECK_ALL_COMPLETE, + /** Allow aborted online index creation. */ + CHECK_ABORTED_OK, + /** Allow partial indexes to exist. */ + CHECK_PARTIAL_OK +}; /**********************************************************************//** Check for duplicate index entries in a table [using the index name] */ UNIV_INTERN @@ -1028,8 +1287,9 @@ dict_table_check_for_dup_indexes( /*=============================*/ const dict_table_t* table, /*!< in: Check for dup indexes in this table */ - ibool tmp_ok);/*!< in: TRUE=allow temporary - index names */ + enum check_name check) /*!< in: whether and when to allow + temporary index names */ + __attribute__((nonnull)); #endif /* UNIV_DEBUG */ /**********************************************************************//** Builds a node pointer out of a physical record and a page number. @@ -1045,8 +1305,9 @@ dict_index_build_node_ptr( pointer */ mem_heap_t* heap, /*!< in: memory heap where pointer created */ - ulint level); /*!< in: level of rec in tree: + ulint level) /*!< in: level of rec in tree: 0 means leaf level */ + __attribute__((nonnull, warn_unused_result)); /**********************************************************************//** Copies an initial segment of a physical record, long enough to specify an index entry uniquely. @@ -1061,7 +1322,8 @@ dict_index_copy_rec_order_prefix( ulint* n_fields,/*!< out: number of fields copied */ byte** buf, /*!< in/out: memory buffer for the copied prefix, or NULL */ - ulint* buf_size);/*!< in/out: buffer size */ + ulint* buf_size)/*!< in/out: buffer size */ + __attribute__((nonnull, warn_unused_result)); /**********************************************************************//** Builds a typed data tuple out of a physical record. @return own: data tuple */ @@ -1072,7 +1334,8 @@ dict_index_build_data_tuple( dict_index_t* index, /*!< in: index */ rec_t* rec, /*!< in: record for which to build data tuple */ ulint n_fields,/*!< in: number of data fields */ - mem_heap_t* heap); /*!< in: memory heap where tuple created */ + mem_heap_t* heap) /*!< in: memory heap where tuple created */ + __attribute__((nonnull, warn_unused_result)); /*********************************************************************//** Gets the space id of the root of the index tree. @return space id */ @@ -1080,7 +1343,8 @@ UNIV_INLINE ulint dict_index_get_space( /*=================*/ - const dict_index_t* index); /*!< in: index */ + const dict_index_t* index) /*!< in: index */ + __attribute__((nonnull, warn_unused_result)); /*********************************************************************//** Sets the space id of the root of the index tree. */ UNIV_INLINE @@ -1088,7 +1352,8 @@ void dict_index_set_space( /*=================*/ dict_index_t* index, /*!< in/out: index */ - ulint space); /*!< in: space id */ + ulint space) /*!< in: space id */ + __attribute__((nonnull)); /*********************************************************************//** Gets the page number of the root of the index tree. @return page number */ @@ -1096,15 +1361,17 @@ UNIV_INLINE ulint dict_index_get_page( /*================*/ - const dict_index_t* tree); /*!< in: index */ + const dict_index_t* tree) /*!< in: index */ + __attribute__((nonnull, warn_unused_result)); /*********************************************************************//** Gets the read-write lock of the index tree. @return read-write lock */ UNIV_INLINE -rw_lock_t* +prio_rw_lock_t* dict_index_get_lock( /*================*/ - dict_index_t* index); /*!< in: index */ + dict_index_t* index) /*!< in: index */ + __attribute__((nonnull, warn_unused_result)); /********************************************************************//** Returns free space reserved for future updates of records. This is relevant only in the case of many consecutive inserts, as updates @@ -1114,49 +1381,48 @@ UNIV_INLINE ulint dict_index_get_space_reserve(void); /*==============================*/ + +/* Online index creation @{ */ +/********************************************************************//** +Gets the status of online index creation. +@return the status */ +UNIV_INLINE +enum online_index_status +dict_index_get_online_status( +/*=========================*/ + const dict_index_t* index) /*!< in: secondary index */ + __attribute__((nonnull, warn_unused_result)); +/********************************************************************//** +Sets the status of online index creation. */ +UNIV_INLINE +void +dict_index_set_online_status( +/*=========================*/ + dict_index_t* index, /*!< in/out: index */ + enum online_index_status status) /*!< in: status */ + __attribute__((nonnull)); +/********************************************************************//** +Determines if a secondary index is being or has been created online, +or if the table is being rebuilt online, allowing concurrent modifications +to the table. +@retval true if the index is being or has been built online, or +if this is a clustered index and the table is being or has been rebuilt online +@retval false if the index has been created or the table has been +rebuilt completely */ +UNIV_INLINE +bool +dict_index_is_online_ddl( +/*=====================*/ + const dict_index_t* index) /*!< in: index */ + __attribute__((nonnull, warn_unused_result)); /*********************************************************************//** Calculates the minimum record length in an index. */ UNIV_INTERN ulint dict_index_calc_min_rec_len( /*========================*/ - const dict_index_t* index); /*!< in: index */ - -/** Calculate new statistics if 1 / 16 of table has been modified -since the last time a statistics batch was run. -We calculate statistics at most every 16th round, since we may have -a counter table which is very small and updated very often. -@param t table -@return true if the table has changed too much and stats need to be -recalculated -*/ -#define DICT_TABLE_CHANGED_TOO_MUCH(t) \ - ((ib_int64_t) (t)->stat_modified_counter > 16 + (t)->stat_n_rows / 16) - -/*********************************************************************//** -Calculates new estimates for table and index statistics. The statistics -are used in query optimization. */ -UNIV_INTERN -void -dict_update_statistics( -/*===================*/ - dict_table_t* table, /*!< in/out: table */ - ibool only_calc_if_missing_stats,/*!< in: only - update/recalc the stats if they have - not been initialized yet, otherwise - do nothing */ - ibool sync, - ibool only_calc_if_changed_too_much);/*!< in: only - update/recalc the stats if the table - has been changed too much since the - last stats update/recalc */ -/*********************************************************************//** -*/ -UNIV_INTERN -ibool -dict_is_older_statistics( -/*=====================*/ - dict_index_t* index); + const dict_index_t* index) /*!< in: index */ + __attribute__((nonnull, warn_unused_result)); /********************************************************************//** Reserves the dictionary system mutex for MySQL. */ UNIV_INTERN @@ -1178,8 +1444,9 @@ void dict_table_stats_lock( /*==================*/ const dict_table_t* table, /*!< in: table */ - ulint latch_mode); /*!< in: RW_S_LATCH or + ulint latch_mode) /*!< in: RW_S_LATCH or RW_X_LATCH */ + __attribute__((nonnull)); /**********************************************************************//** Unlock the latch that has been locked by dict_table_stats_lock() */ UNIV_INTERN @@ -1187,8 +1454,9 @@ void dict_table_stats_unlock( /*====================*/ const dict_table_t* table, /*!< in: table */ - ulint latch_mode); /*!< in: RW_S_LATCH or + ulint latch_mode) /*!< in: RW_S_LATCH or RW_X_LATCH */ + __attribute__((nonnull)); /********************************************************************//** Checks if the database name in two table names is the same. @return TRUE if same db name */ @@ -1198,8 +1466,9 @@ dict_tables_have_same_db( /*=====================*/ const char* name1, /*!< in: table name in the form dbname '/' tablename */ - const char* name2); /*!< in: table name in the form + const char* name2) /*!< in: table name in the form dbname '/' tablename */ + __attribute__((nonnull, warn_unused_result)); /*********************************************************************//** Removes an index from the cache */ UNIV_INTERN @@ -1207,7 +1476,8 @@ void dict_index_remove_from_cache( /*=========================*/ dict_table_t* table, /*!< in/out: table */ - dict_index_t* index); /*!< in, own: index */ + dict_index_t* index) /*!< in, own: index */ + __attribute__((nonnull)); /**********************************************************************//** Get index by name @return index, NULL if does not exist */ @@ -1216,7 +1486,8 @@ dict_index_t* dict_table_get_index_on_name( /*=========================*/ dict_table_t* table, /*!< in: table */ - const char* name); /*!< in: name of the index to find */ + const char* name) /*!< in: name of the index to find */ + __attribute__((nonnull, warn_unused_result)); /**********************************************************************//** In case there is more than one index with the same name return the index with the min(id). @@ -1226,17 +1497,53 @@ dict_index_t* dict_table_get_index_on_name_and_min_id( /*====================================*/ dict_table_t* table, /*!< in: table */ - const char* name); /*!< in: name of the index to find */ - + const char* name) /*!< in: name of the index to find */ + __attribute__((nonnull, warn_unused_result)); +/*************************************************************** +Check whether a column exists in an FTS index. */ +UNIV_INLINE +ulint +dict_table_is_fts_column( +/*=====================*/ + /* out: ULINT_UNDEFINED if no match else + the offset within the vector */ + ib_vector_t* indexes,/* in: vector containing only FTS indexes */ + ulint col_no) /* in: col number to search for */ + __attribute__((nonnull, warn_unused_result)); +/**********************************************************************//** +Move a table to the non LRU end of the LRU list. */ UNIV_INTERN void -dict_table_LRU_trim( -/*================*/ - dict_table_t* self); +dict_table_move_from_lru_to_non_lru( +/*================================*/ + dict_table_t* table) /*!< in: table to move from LRU to non-LRU */ + __attribute__((nonnull)); +/**********************************************************************//** +Move a table to the LRU list from the non-LRU list. */ +UNIV_INTERN +void +dict_table_move_from_non_lru_to_lru( +/*================================*/ + dict_table_t* table) /*!< in: table to move from non-LRU to LRU */ + __attribute__((nonnull)); +/**********************************************************************//** +Move to the most recently used segment of the LRU list. */ +UNIV_INTERN +void +dict_move_to_mru( +/*=============*/ + dict_table_t* table) /*!< in: table to move to MRU */ + __attribute__((nonnull)); + +/** Maximum number of columns in a foreign key constraint. Please Note MySQL +has a much lower limit on the number of columns allowed in a foreign key +constraint */ +#define MAX_NUM_FK_COLUMNS 500 + /* Buffers for storing detailed information about the latest foreign key and unique key errors */ extern FILE* dict_foreign_err_file; -extern mutex_t dict_foreign_err_mutex; /* mutex protecting the buffers */ +extern ib_mutex_t dict_foreign_err_mutex; /* mutex protecting the buffers */ /** the dictionary system */ extern dict_sys_t* dict_sys; @@ -1244,8 +1551,8 @@ extern dict_sys_t* dict_sys; extern rw_lock_t dict_operation_lock; /* Dictionary system struct */ -struct dict_sys_struct{ - mutex_t mutex; /*!< mutex protecting the data +struct dict_sys_t{ + ib_prio_mutex_t mutex; /*!< mutex protecting the data dictionary; protects also the disk-based dictionary system tables; this mutex serializes CREATE TABLE @@ -1262,8 +1569,6 @@ struct dict_sys_struct{ on name */ hash_table_t* table_id_hash; /*!< hash table of the tables, based on id */ - UT_LIST_BASE_NODE_T(dict_table_t) - table_LRU; /*!< LRU list of tables */ ulint size; /*!< varying space in bytes occupied by the data dictionary table and index objects */ @@ -1271,7 +1576,14 @@ struct dict_sys_struct{ dict_table_t* sys_columns; /*!< SYS_COLUMNS table */ dict_table_t* sys_indexes; /*!< SYS_INDEXES table */ dict_table_t* sys_fields; /*!< SYS_FIELDS table */ - dict_table_t* sys_stats; /*!< SYS_STATS table */ + + /*=============================*/ + UT_LIST_BASE_NODE_T(dict_table_t) + table_LRU; /*!< List of tables that can be evicted + from the cache */ + UT_LIST_BASE_NODE_T(dict_table_t) + table_non_LRU; /*!< List of tables that can't be + evicted from the cache */ }; #endif /* !UNIV_HOTBACKUP */ @@ -1287,6 +1599,80 @@ void dict_ind_init(void); /*===============*/ +/* Auxiliary structs for checking a table definition @{ */ + +/* This struct is used to specify the name and type that a column must +have when checking a table's schema. */ +struct dict_col_meta_t { + const char* name; /* column name */ + ulint mtype; /* required column main type */ + ulint prtype_mask; /* required column precise type mask; + if this is non-zero then all the + bits it has set must also be set + in the column's prtype */ + ulint len; /* required column length */ +}; + +/* This struct is used for checking whether a given table exists and +whether it has a predefined schema (number of columns and columns names +and types) */ +struct dict_table_schema_t { + const char* table_name; /* the name of the table whose + structure we are checking */ + ulint n_cols; /* the number of columns the + table must have */ + dict_col_meta_t* columns; /* metadata for the columns; + this array has n_cols + elements */ + ulint n_foreign; /* number of foreign keys this + table has, pointing to other + tables (where this table is + FK child) */ + ulint n_referenced; /* number of foreign keys other + tables have, pointing to this + table (where this table is + parent) */ +}; +/* @} */ + +/*********************************************************************//** +Checks whether a table exists and whether it has the given structure. +The table must have the same number of columns with the same names and +types. The order of the columns does not matter. +The caller must own the dictionary mutex. +dict_table_schema_check() @{ +@return DB_SUCCESS if the table exists and contains the necessary columns */ +UNIV_INTERN +dberr_t +dict_table_schema_check( +/*====================*/ + dict_table_schema_t* req_schema, /*!< in/out: required table + schema */ + char* errstr, /*!< out: human readable error + message if != DB_SUCCESS and + != DB_TABLE_NOT_FOUND is + returned */ + size_t errstr_sz) /*!< in: errstr size */ + __attribute__((nonnull, warn_unused_result)); +/* @} */ + +/*********************************************************************//** +Converts a database and table name from filesystem encoding +(e.g. d@i1b/a@q1b@1Kc, same format as used in dict_table_t::name) in two +strings in UTF8 encoding (e.g. dцb and aюbØc). The output buffers must be +at least MAX_DB_UTF8_LEN and MAX_TABLE_UTF8_LEN bytes. */ +UNIV_INTERN +void +dict_fs2utf8( +/*=========*/ + const char* db_and_table, /*!< in: database and table names, + e.g. d@i1b/a@q1b@1Kc */ + char* db_utf8, /*!< out: database name, e.g. dцb */ + size_t db_utf8_size, /*!< in: dbname_utf8 size */ + char* table_utf8, /*!< out: table name, e.g. aюbØc */ + size_t table_utf8_size)/*!< in: table_utf8 size */ + __attribute__((nonnull)); + /**********************************************************************//** Closes the data dictionary module. */ UNIV_INTERN @@ -1302,7 +1688,7 @@ ulint dict_table_is_corrupted( /*====================*/ const dict_table_t* table) /*!< in: table */ - __attribute__((nonnull, pure, warn_unused_result)); + __attribute__((nonnull, warn_unused_result)); /**********************************************************************//** Check whether the index is corrupted. @@ -1312,7 +1698,7 @@ ulint dict_index_is_corrupted( /*====================*/ const dict_index_t* index) /*!< in: index */ - __attribute__((nonnull, pure, warn_unused_result)); + __attribute__((nonnull, warn_unused_result)); #endif /* !UNIV_HOTBACKUP */ /**********************************************************************//** @@ -1322,7 +1708,9 @@ UNIV_INTERN void dict_set_corrupted( /*===============*/ - dict_index_t* index) /*!< in/out: index */ + dict_index_t* index, /*!< in/out: index */ + trx_t* trx, /*!< in/out: transaction */ + const char* ctx) /*!< in: context */ UNIV_COLD __attribute__((nonnull)); /**********************************************************************//** @@ -1334,7 +1722,8 @@ void dict_set_corrupted_index_cache_only( /*================================*/ dict_index_t* index, /*!< in/out: index */ - dict_table_t* table); /*!< in/out: table */ + dict_table_t* table) /*!< in/out: table */ + __attribute__((nonnull)); /**********************************************************************//** Flags a table with specified space_id corrupted in the table dictionary @@ -1346,6 +1735,75 @@ dict_set_corrupted_by_space( /*========================*/ ulint space_id); /*!< in: space ID */ +/********************************************************************//** +Validate the table flags. +@return true if valid. */ +UNIV_INLINE +bool +dict_tf_is_valid( +/*=============*/ + ulint flags) /*!< in: table flags */ + __attribute__((warn_unused_result)); + +/********************************************************************//** +Check if the tablespace for the table has been discarded. +@return true if the tablespace has been discarded. */ +UNIV_INLINE +bool +dict_table_is_discarded( +/*====================*/ + const dict_table_t* table) /*!< in: table to check */ + __attribute__((nonnull, pure, warn_unused_result)); + +/********************************************************************//** +Check if it is a temporary table. +@return true if temporary table flag is set. */ +UNIV_INLINE +bool +dict_table_is_temporary( +/*====================*/ + const dict_table_t* table) /*!< in: table to check */ + __attribute__((nonnull, pure, warn_unused_result)); + +#ifndef UNIV_HOTBACKUP +/*********************************************************************//** +This function should be called whenever a page is successfully +compressed. Updates the compression padding information. */ +UNIV_INTERN +void +dict_index_zip_success( +/*===================*/ + dict_index_t* index) /*!< in/out: index to be updated. */ + __attribute__((nonnull)); +/*********************************************************************//** +This function should be called whenever a page compression attempt +fails. Updates the compression padding information. */ +UNIV_INTERN +void +dict_index_zip_failure( +/*===================*/ + dict_index_t* index) /*!< in/out: index to be updated. */ + __attribute__((nonnull)); +/*********************************************************************//** +Return the optimal page size, for which page will likely compress. +@return page size beyond which page may not compress*/ +UNIV_INTERN +ulint +dict_index_zip_pad_optimal_page_size( +/*=================================*/ + dict_index_t* index) /*!< in: index for which page size + is requested */ + __attribute__((nonnull, warn_unused_result)); +/*************************************************************//** +Convert table flag to row format string. +@return row format name */ +UNIV_INTERN +const char* +dict_tf_to_row_format_string( +/*=========================*/ + ulint table_flag); /*!< in: row format setting */ + +#endif /* !UNIV_HOTBACKUP */ /************************************************************************* set is_corrupt flag by space_id*/ |