diff options
Diffstat (limited to 'storage/xtradb/include/dict0dict.ic')
-rw-r--r-- | storage/xtradb/include/dict0dict.ic | 1588 |
1 files changed, 0 insertions, 1588 deletions
diff --git a/storage/xtradb/include/dict0dict.ic b/storage/xtradb/include/dict0dict.ic deleted file mode 100644 index f68d4e176da..00000000000 --- a/storage/xtradb/include/dict0dict.ic +++ /dev/null @@ -1,1588 +0,0 @@ -/***************************************************************************** - -Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2013, 2017, MariaDB Corporation. - -This program is free software; you can redistribute it and/or modify it under -the terms of the GNU General Public License as published by the Free Software -Foundation; version 2 of the License. - -This program is distributed in the hope that it will be useful, but WITHOUT -ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS -FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License along with -this program; if not, write to the Free Software Foundation, Inc., -51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA - -*****************************************************************************/ - -/******************************************************************//** -@file include/dict0dict.ic -Data dictionary system - -Created 1/8/1996 Heikki Tuuri -***********************************************************************/ - -#include "data0type.h" -#ifndef UNIV_HOTBACKUP -#include "dict0load.h" -#include "rem0types.h" -#include "fsp0fsp.h" -#include "srv0srv.h" -#include "sync0rw.h" /* RW_S_LATCH */ - -/*********************************************************************//** -Gets the minimum number of bytes per character. -@return minimum multi-byte char size, in bytes */ -UNIV_INLINE -ulint -dict_col_get_mbminlen( -/*==================*/ - const dict_col_t* col) /*!< in: column */ -{ - return(DATA_MBMINLEN(col->mbminmaxlen)); -} -/*********************************************************************//** -Gets the maximum number of bytes per character. -@return maximum multi-byte char size, in bytes */ -UNIV_INLINE -ulint -dict_col_get_mbmaxlen( -/*==================*/ - const dict_col_t* col) /*!< in: column */ -{ - return(DATA_MBMAXLEN(col->mbminmaxlen)); -} -/*********************************************************************//** -Sets the minimum and maximum number of bytes per character. */ -UNIV_INLINE -void -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 - character size, in bytes */ -{ - ut_ad(mbminlen < DATA_MBMAX); - ut_ad(mbmaxlen < DATA_MBMAX); - ut_ad(mbminlen <= mbmaxlen); - - col->mbminmaxlen = DATA_MBMINMAXLEN(mbminlen, mbmaxlen); -} -/*********************************************************************//** -Gets the column data type. */ -UNIV_INLINE -void -dict_col_copy_type( -/*===============*/ - const dict_col_t* col, /*!< in: column */ - dtype_t* type) /*!< out: data type */ -{ - ut_ad(col != NULL); - ut_ad(type != NULL); - - type->mtype = col->mtype; - type->prtype = col->prtype; - type->len = col->len; - type->mbminmaxlen = col->mbminmaxlen; -} -#endif /* !UNIV_HOTBACKUP */ - -#ifdef UNIV_DEBUG -/*********************************************************************//** -Assert that a column and a data type match. -@return TRUE */ -UNIV_INLINE -ibool -dict_col_type_assert_equal( -/*=======================*/ - const dict_col_t* col, /*!< in: column */ - const dtype_t* type) /*!< in: data type */ -{ - ut_ad(col); - ut_ad(type); - - ut_ad(col->mtype == type->mtype); - ut_ad(col->prtype == type->prtype); - //ut_ad(col->len == type->len); -# ifndef UNIV_HOTBACKUP - ut_ad(col->mbminmaxlen == type->mbminmaxlen); -# endif /* !UNIV_HOTBACKUP */ - - return(TRUE); -} -#endif /* UNIV_DEBUG */ - -#ifndef UNIV_HOTBACKUP -/***********************************************************************//** -Returns the minimum size of the column. -@return minimum size */ -UNIV_INLINE -ulint -dict_col_get_min_size( -/*==================*/ - const dict_col_t* col) /*!< in: column */ -{ - return(dtype_get_min_size_low(col->mtype, col->prtype, col->len, - col->mbminmaxlen)); -} -/***********************************************************************//** -Returns the maximum size of the column. -@return maximum size */ -UNIV_INLINE -ulint -dict_col_get_max_size( -/*==================*/ - const dict_col_t* col) /*!< in: column */ -{ - return(dtype_get_max_size_low(col->mtype, col->len)); -} -#endif /* !UNIV_HOTBACKUP */ -/***********************************************************************//** -Returns the size of a fixed size column, 0 if not a fixed size column. -@return fixed size, or 0 */ -UNIV_INLINE -ulint -dict_col_get_fixed_size( -/*====================*/ - const dict_col_t* col, /*!< in: column */ - ulint comp) /*!< in: nonzero=ROW_FORMAT=COMPACT */ -{ - return(dtype_get_fixed_size_low(col->mtype, col->prtype, col->len, - col->mbminmaxlen, comp)); -} -/***********************************************************************//** -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. -@return SQL null storage size in ROW_FORMAT=REDUNDANT */ -UNIV_INLINE -ulint -dict_col_get_sql_null_size( -/*=======================*/ - const dict_col_t* col, /*!< in: column */ - ulint comp) /*!< in: nonzero=ROW_FORMAT=COMPACT */ -{ - return(dict_col_get_fixed_size(col, comp)); -} - -/*********************************************************************//** -Gets the column number. -@return col->ind, table column position (starting from 0) */ -UNIV_INLINE -ulint -dict_col_get_no( -/*============*/ - const dict_col_t* col) /*!< in: column */ -{ - ut_ad(col); - - return(col->ind); -} - -/*********************************************************************//** -Gets the column position in the clustered index. */ -UNIV_INLINE -ulint -dict_col_get_clust_pos( -/*===================*/ - const dict_col_t* col, /*!< in: table column */ - const dict_index_t* clust_index) /*!< in: clustered index */ -{ - ulint i; - - ut_ad(col); - ut_ad(clust_index); - ut_ad(dict_index_is_clust(clust_index)); - - for (i = 0; i < clust_index->n_def; i++) { - const dict_field_t* field = &clust_index->fields[i]; - - if (!field->prefix_len && field->col == col) { - return(i); - } - } - - return(ULINT_UNDEFINED); -} - -#ifndef UNIV_HOTBACKUP -#ifdef UNIV_DEBUG -/********************************************************************//** -Gets the first index on the table (the clustered index). -@return index, NULL if none exists */ -UNIV_INLINE -dict_index_t* -dict_table_get_first_index( -/*=======================*/ - const dict_table_t* table) /*!< in: table */ -{ - ut_ad(table); - ut_ad(table->magic_n == DICT_TABLE_MAGIC_N); - - return(UT_LIST_GET_FIRST(((dict_table_t*) table)->indexes)); -} - -/********************************************************************//** -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 */ -{ - ut_ad(table); - ut_ad(table->magic_n == DICT_TABLE_MAGIC_N); - - return(UT_LIST_GET_LAST((const_cast<dict_table_t*>(table)) - ->indexes)); -} - -/********************************************************************//** -Gets the next index on the table. -@return index, NULL if none left */ -UNIV_INLINE -dict_index_t* -dict_table_get_next_index( -/*======================*/ - const dict_index_t* index) /*!< in: index */ -{ - ut_ad(index); - ut_ad(index->magic_n == DICT_INDEX_MAGIC_N); - - return(UT_LIST_GET_NEXT(indexes, (dict_index_t*) index)); -} -#endif /* UNIV_DEBUG */ -#endif /* !UNIV_HOTBACKUP */ - -/********************************************************************//** -Check whether the index is the clustered index. -@return nonzero for clustered index, zero for other indexes */ -UNIV_INLINE -ulint -dict_index_is_clust( -/*================*/ - const dict_index_t* index) /*!< in: index */ -{ - ut_ad(index->magic_n == DICT_INDEX_MAGIC_N); - - return(index->type & DICT_CLUSTERED); -} -/********************************************************************//** -Check whether the index is unique. -@return nonzero for unique index, zero for other indexes */ -UNIV_INLINE -ulint -dict_index_is_unique( -/*=================*/ - const dict_index_t* index) /*!< in: index */ -{ - ut_ad(index->magic_n == DICT_INDEX_MAGIC_N); - - return(index->type & DICT_UNIQUE); -} - -/********************************************************************//** -Check whether the index is the insert buffer tree. -@return nonzero for insert buffer, zero for other indexes */ -UNIV_INLINE -ulint -dict_index_is_ibuf( -/*===============*/ - const dict_index_t* index) /*!< in: index */ -{ - ut_ad(index->magic_n == DICT_INDEX_MAGIC_N); - - return(index->type & DICT_IBUF); -} - -/********************************************************************//** -Check whether the index is an universal index tree. -@return nonzero for universal tree, zero for other indexes */ -UNIV_INLINE -ulint -dict_index_is_univ( -/*===============*/ - const dict_index_t* index) /*!< in: index */ -{ - ut_ad(index); - ut_ad(index->magic_n == DICT_INDEX_MAGIC_N); - - return(index->type & DICT_UNIVERSAL); -} - -/********************************************************************//** -Check whether the index is a secondary index or the insert buffer tree. -@return nonzero for insert buffer, zero for other indexes */ -UNIV_INLINE -ulint -dict_index_is_sec_or_ibuf( -/*======================*/ - const dict_index_t* index) /*!< in: index */ -{ - ulint type; - - ut_ad(index->magic_n == DICT_INDEX_MAGIC_N); - - type = index->type; - - return(!(type & DICT_CLUSTERED) || (type & DICT_IBUF)); -} - -/********************************************************************//** -Gets the number of user-defined columns in a table in the dictionary -cache. -@return number of user-defined (e.g., not ROW_ID) columns of a table */ -UNIV_INLINE -ulint -dict_table_get_n_user_cols( -/*=======================*/ - const dict_table_t* table) /*!< in: table */ -{ - ut_ad(table->magic_n == DICT_TABLE_MAGIC_N); - - return(table->n_cols - DATA_N_SYS_COLS); -} - -/********************************************************************//** -Gets the number of system columns in a table in the dictionary cache. -@return number of system (e.g., ROW_ID) columns of a table */ -UNIV_INLINE -ulint -dict_table_get_n_sys_cols( -/*======================*/ - const dict_table_t* table MY_ATTRIBUTE((unused))) /*!< in: table */ -{ - ut_ad(table); - ut_ad(table->magic_n == DICT_TABLE_MAGIC_N); - ut_ad(table->cached); - - return(DATA_N_SYS_COLS); -} - -/********************************************************************//** -Gets the number of all columns (also system) in a table in the dictionary -cache. -@return number of columns of a table */ -UNIV_INLINE -ulint -dict_table_get_n_cols( -/*==================*/ - const dict_table_t* table) /*!< in: table */ -{ - ut_ad(table->magic_n == DICT_TABLE_MAGIC_N); - - return(table->n_cols); -} - -/********************************************************************//** -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 */ -{ - ut_ad(table->stat_initialized); - - return(table->stat_n_rows); -} - -/********************************************************************//** -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 */ -{ - if (table->stat_initialized) { - ib_uint64_t n_rows = table->stat_n_rows; - if (n_rows < 0xFFFFFFFFFFFFFFFFULL) { - table->stat_n_rows = n_rows + 1; - } - } -} - -/********************************************************************//** -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 */ -{ - if (table->stat_initialized) { - ib_uint64_t n_rows = table->stat_n_rows; - if (n_rows > 0) { - table->stat_n_rows = n_rows - 1; - } - } -} - -#ifdef UNIV_DEBUG -/********************************************************************//** -Gets the nth column of a table. -@return pointer to column object */ -UNIV_INLINE -dict_col_t* -dict_table_get_nth_col( -/*===================*/ - const dict_table_t* table, /*!< in: table */ - ulint pos) /*!< in: position of column */ -{ - ut_ad(table); - ut_ad(pos < table->n_def); - ut_ad(table->magic_n == DICT_TABLE_MAGIC_N); - - return((dict_col_t*) (table->cols) + pos); -} - -/********************************************************************//** -Gets the given system column of a table. -@return pointer to column object */ -UNIV_INLINE -dict_col_t* -dict_table_get_sys_col( -/*===================*/ - const dict_table_t* table, /*!< in: table */ - ulint sys) /*!< in: DATA_ROW_ID, ... */ -{ - dict_col_t* col; - - ut_ad(table); - ut_ad(sys < DATA_N_SYS_COLS); - ut_ad(table->magic_n == DICT_TABLE_MAGIC_N); - - col = dict_table_get_nth_col(table, table->n_cols - - DATA_N_SYS_COLS + sys); - ut_ad(col->mtype == DATA_SYS); - ut_ad(col->prtype == (sys | DATA_NOT_NULL)); - - return(col); -} -#endif /* UNIV_DEBUG */ - -/********************************************************************//** -Gets the given system column number of a table. -@return column number */ -UNIV_INLINE -ulint -dict_table_get_sys_col_no( -/*======================*/ - const dict_table_t* table, /*!< in: table */ - ulint sys) /*!< in: DATA_ROW_ID, ... */ -{ - ut_ad(table); - ut_ad(sys < DATA_N_SYS_COLS); - ut_ad(table->magic_n == DICT_TABLE_MAGIC_N); - - return(table->n_cols - DATA_N_SYS_COLS + sys); -} - -/********************************************************************//** -Check whether the table uses the compact page format. -@return TRUE if table uses the compact page format */ -UNIV_INLINE -ibool -dict_table_is_comp( -/*===============*/ - const dict_table_t* table) /*!< in: table */ -{ - ut_ad(table); - -#if DICT_TF_COMPACT != 1 -#error "DICT_TF_COMPACT must be 1" -#endif - - return(table->flags & DICT_TF_COMPACT); -} - -/************************************************************************ -Check if the table has an FTS index. */ -UNIV_INLINE -ibool -dict_table_has_fts_index( -/*=====================*/ - /* out: TRUE if table has an FTS index */ - dict_table_t* table) /* in: table */ -{ - ut_ad(table); - - return(DICT_TF2_FLAG_IS_SET(table, DICT_TF2_FTS)); -} - -/********************************************************************//** -Validate the table flags. -@return true if valid. */ -UNIV_INLINE -bool -dict_tf_is_valid( -/*=============*/ - ulint flags) /*!< in: table flags */ -{ - ulint compact = DICT_TF_GET_COMPACT(flags); - ulint zip_ssize = DICT_TF_GET_ZIP_SSIZE(flags); - ulint atomic_blobs = DICT_TF_HAS_ATOMIC_BLOBS(flags); - ulint unused = DICT_TF_GET_UNUSED(flags); - ulint page_compression = DICT_TF_GET_PAGE_COMPRESSION(flags); - ulint page_compression_level = DICT_TF_GET_PAGE_COMPRESSION_LEVEL(flags); - ulint data_dir = DICT_TF_HAS_DATA_DIR(flags); - ulint atomic_writes = DICT_TF_GET_ATOMIC_WRITES(flags); - - /* Make sure there are no bits that we do not know about. */ - if (unused != 0) { - fprintf(stderr, - "InnoDB: Error: table unused flags are " ULINTPF - " in the data dictionary and are corrupted\n" - "InnoDB: Error: data dictionary flags are\n" - "InnoDB: compact " ULINTPF " atomic_blobs " ULINTPF - "\nInnoDB: unused " ULINTPF " data_dir " ULINTPF - " zip_ssize " ULINTPF - "\nInnoDB: page_compression " ULINTPF - " page_compression_level " ULINTPF - "\nInnoDB: atomic_writes " ULINTPF "\n", - unused, - compact, atomic_blobs, unused, data_dir, zip_ssize, - page_compression, page_compression_level, atomic_writes - ); - - return(false); - - } else if (atomic_blobs) { - /* Barracuda row formats COMPRESSED and DYNAMIC build on - the page structure introduced for the COMPACT row format - by allowing keys in secondary indexes to be made from - data stored off-page in the clustered index. */ - - if (!compact) { - fprintf(stderr, - "InnoDB: Error: table compact flags are " - ULINTPF - " in the data dictionary and are corrupted\n" - "InnoDB: Error: data dictionary flags are\n" - "InnoDB: compact " ULINTPF - " atomic_blobs " ULINTPF "\n" - "InnoDB: unused " ULINTPF - " data_dir " ULINTPF " zip_ssize " ULINTPF - "\nInnoDB: page_compression " ULINTPF - " page_compression_level " ULINTPF - "\nInnoDB: atomic_writes " ULINTPF "\n", - compact, compact, atomic_blobs, unused, data_dir, zip_ssize, - page_compression, page_compression_level, atomic_writes - ); - return(false); - } - - } else if (zip_ssize) { - - /* Antelope does not support COMPRESSED row format. */ - fprintf(stderr, - "InnoDB: Error: table flags are " ULINTPF - " in the data dictionary and are corrupted\n" - "InnoDB: Error: data dictionary flags are\n" - "InnoDB: compact " ULINTPF " atomic_blobs " ULINTPF - "\nInnoDB: unused " ULINTPF " data_dir " ULINTPF - " zip_ssize " ULINTPF - "\nInnoDB: page_compression " ULINTPF - " page_compression_level " ULINTPF - "\nInnoDB: atomic_writes " ULINTPF "\n", - flags, compact, atomic_blobs, unused, data_dir, zip_ssize, - page_compression, page_compression_level, atomic_writes - ); - return(false); - } - - if (zip_ssize) { - - /* COMPRESSED row format must have compact and atomic_blobs - bits set and validate the number is within allowed range. */ - - if (!compact - || !atomic_blobs - || zip_ssize > PAGE_ZIP_SSIZE_MAX) { - - fprintf(stderr, - "InnoDB: Error: table compact flags are " - ULINTPF - " in the data dictionary and are corrupted\n" - "InnoDB: Error: data dictionary flags are\n" - "InnoDB: compact " ULINTPF - " atomic_blobs " ULINTPF "\n" - "InnoDB: unused " ULINTPF - " data_dir " ULINTPF " zip_ssize " ULINTPF - "\nInnoDB: page_compression " ULINTPF - " page_compression_level " ULINTPF - "\nInnoDB: atomic_writes " ULINTPF "\n", - flags, - compact, atomic_blobs, unused, data_dir, zip_ssize, - page_compression, page_compression_level, atomic_writes - - ); - return(false); - } - } - - if (page_compression || page_compression_level) { - /* Page compression format must have compact and - atomic_blobs and page_compression_level requires - page_compression */ - if (!compact - || !page_compression - || !atomic_blobs) { - - fprintf(stderr, - "InnoDB: Error: table flags are " ULINTPF - " in the data dictionary and are corrupted\n" - "InnoDB: Error: data dictionary flags are\n" - "InnoDB: compact " ULINTPF - " atomic_blobs " ULINTPF "\n" - "InnoDB: unused " ULINTPF - " data_dir " ULINTPF " zip_ssize " ULINTPF - "\nInnoDB: page_compression " ULINTPF - " page_compression_level " ULINTPF - "\nInnoDB: atomic_writes " ULINTPF "\n", - flags, compact, atomic_blobs, unused, data_dir, zip_ssize, - page_compression, page_compression_level, atomic_writes - ); - return(false); - } - } - - if (atomic_writes) { - - if(atomic_writes > ATOMIC_WRITES_OFF) { - - fprintf(stderr, - "InnoDB: Error: table flags are " ULINTPF - " in the data dictionary and are corrupted\n" - "InnoDB: Error: data dictionary flags are\n" - "InnoDB: compact " ULINTPF - " atomic_blobs " ULINTPF "\n" - "InnoDB: unused " ULINTPF - " data_dir " ULINTPF " zip_ssize " ULINTPF - "\nInnoDB: page_compression " ULINTPF - " page_compression_level " ULINTPF - "\nInnoDB: atomic_writes " ULINTPF "\n", - flags, compact, atomic_blobs, unused, data_dir, zip_ssize, - page_compression, page_compression_level, atomic_writes - ); - return(false); - } - } - - /* CREATE TABLE ... DATA DIRECTORY is supported for any row format, - so the DATA_DIR flag is compatible with all other table flags. */ - - return(true); -} - -/********************************************************************//** -Validate a SYS_TABLES TYPE field and return it. -@return Same as input after validating it as a SYS_TABLES TYPE field. -If there is an error, return ULINT_UNDEFINED. */ -UNIV_INLINE -ulint -dict_sys_tables_type_validate( -/*==========================*/ - ulint type, /*!< in: SYS_TABLES.TYPE */ - ulint n_cols) /*!< in: SYS_TABLES.N_COLS */ -{ - ulint low_order_bit = DICT_TF_GET_COMPACT(type); - ulint redundant = !(n_cols & DICT_N_COLS_COMPACT); - ulint zip_ssize = DICT_TF_GET_ZIP_SSIZE(type); - ulint atomic_blobs = DICT_TF_HAS_ATOMIC_BLOBS(type); - ulint unused = DICT_TF_GET_UNUSED(type); - ulint page_compression = DICT_TF_GET_PAGE_COMPRESSION(type); - ulint page_compression_level = DICT_TF_GET_PAGE_COMPRESSION_LEVEL(type); - ulint atomic_writes = DICT_TF_GET_ATOMIC_WRITES(type); - - /* The low order bit of SYS_TABLES.TYPE is always set to 1. - If the format is UNIV_FORMAT_B or higher, this field is the same - as dict_table_t::flags. Zero is not allowed here. */ - if (!low_order_bit) { - return(ULINT_UNDEFINED); - } - - if (redundant) { - if (zip_ssize || atomic_blobs) { - return(ULINT_UNDEFINED); - } - } - - /* Make sure there are no bits that we do not know about. */ - if (unused) { - return(ULINT_UNDEFINED); - } - - if (atomic_blobs) { - /* Barracuda row formats COMPRESSED and DYNAMIC build on - the page structure introduced for the COMPACT row format - by allowing keys in secondary indexes to be made from - data stored off-page in the clustered index. - - The DICT_N_COLS_COMPACT flag should be in N_COLS, - but we already know that. */ - } else if (zip_ssize) { - /* Antelope does not support COMPRESSED format. */ - return(ULINT_UNDEFINED); - } - - if (zip_ssize) { - /* COMPRESSED row format must have low_order_bit and - atomic_blobs bits set and the DICT_N_COLS_COMPACT flag - should be in N_COLS, but we already know about the - low_order_bit and DICT_N_COLS_COMPACT flags. */ - if (!atomic_blobs) { - return(ULINT_UNDEFINED); - } - - /* Validate that the number is within allowed range. */ - if (zip_ssize > PAGE_ZIP_SSIZE_MAX) { - return(ULINT_UNDEFINED); - } - } - - /* There is nothing to validate for the data_dir field. - CREATE TABLE ... DATA DIRECTORY is supported for any row - format, so the DATA_DIR flag is compatible with any other - table flags. However, it is not used with TEMPORARY tables.*/ - - if (page_compression || page_compression_level) { - /* page compressed row format must have low_order_bit and - atomic_blobs bits set and the DICT_N_COLS_COMPACT flag - should be in N_COLS, but we already know about the - low_order_bit and DICT_N_COLS_COMPACT flags. */ - - if (!atomic_blobs || !page_compression) { - return(ULINT_UNDEFINED); - } - } - - /* Validate that the atomic writes number is within allowed range. */ - if (atomic_writes > ATOMIC_WRITES_OFF) { - return(ULINT_UNDEFINED); - } - - /* Return the validated SYS_TABLES.TYPE. */ - return(type); -} - -/********************************************************************//** -Determine the file format from dict_table_t::flags -The low order bit will be zero for REDUNDANT and 1 for COMPACT. For any -other row_format, file_format is > 0 and DICT_TF_COMPACT will also be set. -@return file format version */ -UNIV_INLINE -rec_format_t -dict_tf_get_rec_format( -/*===================*/ - ulint flags) /*!< in: dict_table_t::flags */ -{ - ut_a(dict_tf_is_valid(flags)); - - if (!DICT_TF_GET_COMPACT(flags)) { - return(REC_FORMAT_REDUNDANT); - } - - if (!DICT_TF_HAS_ATOMIC_BLOBS(flags)) { - return(REC_FORMAT_COMPACT); - } - - if (DICT_TF_GET_ZIP_SSIZE(flags)) { - return(REC_FORMAT_COMPRESSED); - } - - return(REC_FORMAT_DYNAMIC); -} - -/********************************************************************//** -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 */ -{ - if (DICT_TF_HAS_ATOMIC_BLOBS(flags)) { - return(UNIV_FORMAT_B); - } - - return(UNIV_FORMAT_A); -} - -/********************************************************************//** -Determine the file format of a table. -@return file format version */ -UNIV_INLINE -ulint -dict_table_get_format( -/*==================*/ - const dict_table_t* table) /*!< in: table */ -{ - ut_ad(table); - - return(dict_tf_get_format(table->flags)); -} - -/********************************************************************//** -Set the file format and zip size in a dict_table_t::flags. If zip size -is not needed, it should be 0. */ -UNIV_INLINE -void -dict_tf_set( -/*========*/ - ulint* flags, /*!< in/out: table flags */ - rec_format_t format, /*!< in: file format */ - ulint zip_ssize, /*!< in: zip shift size */ - bool use_data_dir, /*!< in: table uses DATA DIRECTORY - */ - bool page_compressed,/*!< in: table uses page compressed - pages */ - ulint page_compression_level, /*!< in: table page compression - level */ - ulint atomic_writes) /*!< in: table atomic writes setup */ -{ - atomic_writes_t awrites = (atomic_writes_t)atomic_writes; - - switch (format) { - case REC_FORMAT_REDUNDANT: - *flags = 0; - ut_ad(zip_ssize == 0); - break; - case REC_FORMAT_COMPACT: - *flags = DICT_TF_COMPACT; - ut_ad(zip_ssize == 0); - break; - case REC_FORMAT_COMPRESSED: - *flags = DICT_TF_COMPACT - | (1 << DICT_TF_POS_ATOMIC_BLOBS) - | (zip_ssize << DICT_TF_POS_ZIP_SSIZE); - break; - case REC_FORMAT_DYNAMIC: - *flags = DICT_TF_COMPACT - | (1 << DICT_TF_POS_ATOMIC_BLOBS); - ut_ad(zip_ssize == 0); - break; - } - - if (use_data_dir) { - *flags |= (1 << DICT_TF_POS_DATA_DIR); - } - - if (page_compressed) { - *flags |= (1 << DICT_TF_POS_ATOMIC_BLOBS) - | (1 << DICT_TF_POS_PAGE_COMPRESSION) - | (page_compression_level << DICT_TF_POS_PAGE_COMPRESSION_LEVEL); - - ut_ad(zip_ssize == 0); - ut_ad(dict_tf_get_page_compression(*flags) == TRUE); - ut_ad(dict_tf_get_page_compression_level(*flags) == page_compression_level); - } - - *flags |= (atomic_writes << DICT_TF_POS_ATOMIC_WRITES); - ut_a(dict_tf_get_atomic_writes(*flags) == awrites); -} - -/********************************************************************//** -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 table_flags) /*!< in: dict_table_t::flags */ -{ - ulint fsp_flags; - ulint page_compression_level = DICT_TF_GET_PAGE_COMPRESSION_LEVEL( - table_flags); - ulint atomic_writes = DICT_TF_GET_ATOMIC_WRITES(table_flags); - - ut_ad((DICT_TF_GET_PAGE_COMPRESSION(table_flags) == 0) - == (page_compression_level == 0)); - - DBUG_EXECUTE_IF("dict_tf_to_fsp_flags_failure", - return(ULINT_UNDEFINED);); - - /* Adjust bit zero. */ - fsp_flags = DICT_TF_HAS_ATOMIC_BLOBS(table_flags) ? 1 : 0; - - /* ZIP_SSIZE and ATOMIC_BLOBS are at the same position. */ - fsp_flags |= table_flags - & (DICT_TF_MASK_ZIP_SSIZE | DICT_TF_MASK_ATOMIC_BLOBS); - - fsp_flags |= FSP_FLAGS_PAGE_SSIZE(); - - if (page_compression_level) { - fsp_flags |= FSP_FLAGS_MASK_PAGE_COMPRESSION; - } - - ut_a(fsp_flags_is_valid(fsp_flags)); - - if (DICT_TF_HAS_DATA_DIR(table_flags)) { - fsp_flags |= 1U << FSP_FLAGS_MEM_DATA_DIR; - } - - fsp_flags |= atomic_writes << FSP_FLAGS_MEM_ATOMIC_WRITES; - fsp_flags |= page_compression_level << FSP_FLAGS_MEM_COMPRESSION_LEVEL; - - return(fsp_flags); -} - -/********************************************************************//** -Convert a 32 bit integer from SYS_TABLES.TYPE to dict_table_t::flags -The following chart shows the translation of the low order bit. -Other bits are the same. -========================= Low order bit ========================== - | REDUNDANT | COMPACT | COMPRESSED and DYNAMIC -SYS_TABLES.TYPE | 1 | 1 | 1 -dict_table_t::flags | 0 | 1 | 1 -================================================================== -@return ulint containing SYS_TABLES.TYPE */ -UNIV_INLINE -ulint -dict_sys_tables_type_to_tf( -/*=======================*/ - ulint type, /*!< in: SYS_TABLES.TYPE field */ - ulint n_cols) /*!< in: SYS_TABLES.N_COLS field */ -{ - ulint flags; - ulint redundant = !(n_cols & DICT_N_COLS_COMPACT); - - /* Adjust bit zero. */ - flags = redundant ? 0 : 1; - - /* ZIP_SSIZE, ATOMIC_BLOBS, DATA_DIR, PAGE_COMPRESSION, - PAGE_COMPRESSION_LEVEL, ATOMIC_WRITES are the same. */ - flags |= type & (DICT_TF_MASK_ZIP_SSIZE - | DICT_TF_MASK_ATOMIC_BLOBS - | DICT_TF_MASK_DATA_DIR - | DICT_TF_MASK_PAGE_COMPRESSION - | DICT_TF_MASK_PAGE_COMPRESSION_LEVEL - | DICT_TF_MASK_ATOMIC_WRITES - - ); - - return(flags); -} - -/********************************************************************//** -Convert a 32 bit integer table flags to the 32bit integer that is written -to a SYS_TABLES.TYPE field. The following chart shows the translation of -the low order bit. Other bits are the same. -========================= Low order bit ========================== - | REDUNDANT | COMPACT | COMPRESSED and DYNAMIC -dict_table_t::flags | 0 | 1 | 1 -SYS_TABLES.TYPE | 1 | 1 | 1 -================================================================== -@return ulint containing SYS_TABLES.TYPE */ -UNIV_INLINE -ulint -dict_tf_to_sys_tables_type( -/*=======================*/ - ulint flags) /*!< in: dict_table_t::flags */ -{ - ulint type; - - ut_a(dict_tf_is_valid(flags)); - - /* Adjust bit zero. It is always 1 in SYS_TABLES.TYPE */ - type = 1; - - /* ZIP_SSIZE, ATOMIC_BLOBS, DATA_DIR, PAGE_COMPRESSION, - PAGE_COMPRESSION_LEVEL, ATOMIC_WRITES are the same. */ - type |= flags & (DICT_TF_MASK_ZIP_SSIZE - | DICT_TF_MASK_ATOMIC_BLOBS - | DICT_TF_MASK_DATA_DIR - | DICT_TF_MASK_PAGE_COMPRESSION - | DICT_TF_MASK_PAGE_COMPRESSION_LEVEL - | DICT_TF_MASK_ATOMIC_WRITES); - - return(type); -} - -/********************************************************************//** -Extract the compressed page size from dict_table_t::flags. -These flags are in memory, so assert that they are valid. -@return compressed page size, or 0 if not compressed */ -UNIV_INLINE -ulint -dict_tf_get_zip_size( -/*=================*/ - ulint flags) /*!< in: flags */ -{ - ulint zip_ssize = DICT_TF_GET_ZIP_SSIZE(flags); - ulint zip_size = (zip_ssize - ? (UNIV_ZIP_SIZE_MIN >> 1) << zip_ssize - : 0); - - ut_ad(zip_size <= UNIV_ZIP_SIZE_MAX); - - return(zip_size); -} - -/********************************************************************//** -Check whether the table uses the compressed compact page format. -@return compressed page size, or 0 if not compressed */ -UNIV_INLINE -ulint -dict_table_zip_size( -/*================*/ - const dict_table_t* table) /*!< in: table */ -{ - ut_ad(table); - - return(dict_tf_get_zip_size(table->flags)); -} - -#ifndef UNIV_HOTBACKUP -/*********************************************************************//** -Obtain exclusive locks on all index trees of the table. This is to prevent -accessing index trees while InnoDB is updating internal metadata for -operations such as truncate tables. */ -UNIV_INLINE -void -dict_table_x_lock_indexes( -/*======================*/ - dict_table_t* table) /*!< in: table */ -{ - dict_index_t* index; - - ut_a(table); - ut_ad(mutex_own(&(dict_sys->mutex))); - - /* Loop through each index of the table and lock them */ - for (index = dict_table_get_first_index(table); - index != NULL; - index = dict_table_get_next_index(index)) { - rw_lock_x_lock(dict_index_get_lock(index)); - } -} - -/*********************************************************************//** -Release the exclusive locks on all index tree. */ -UNIV_INLINE -void -dict_table_x_unlock_indexes( -/*========================*/ - dict_table_t* table) /*!< in: table */ -{ - dict_index_t* index; - - ut_a(table); - ut_ad(mutex_own(&(dict_sys->mutex))); - - for (index = dict_table_get_first_index(table); - index != NULL; - index = dict_table_get_next_index(index)) { - rw_lock_x_unlock(dict_index_get_lock(index)); - } -} -#endif /* !UNIV_HOTBACKUP */ - -/********************************************************************//** -Gets the number of fields in the internal representation of an index, -including fields added by the dictionary system. -@return number of fields */ -UNIV_INLINE -ulint -dict_index_get_n_fields( -/*====================*/ - const dict_index_t* index) /*!< in: an internal - representation of index (in - the dictionary cache) */ -{ - ut_ad(index); - ut_ad(index->magic_n == DICT_INDEX_MAGIC_N); - - return(index->n_fields); -} - -/********************************************************************//** -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 -we do not take multiversioning into account: in the B-tree use the value -returned by dict_index_get_n_unique_in_tree. -@return number of fields */ -UNIV_INLINE -ulint -dict_index_get_n_unique( -/*====================*/ - const dict_index_t* index) /*!< in: an internal representation - of index (in the dictionary cache) */ -{ - ut_ad(index); - ut_ad(index->magic_n == DICT_INDEX_MAGIC_N); - ut_ad(index->cached); - - return(index->n_uniq); -} - -/********************************************************************//** -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 -we also take multiversioning into account. -@return number of fields */ -UNIV_INLINE -ulint -dict_index_get_n_unique_in_tree( -/*============================*/ - const dict_index_t* index) /*!< in: an internal representation - of index (in the dictionary cache) */ -{ - ut_ad(index); - ut_ad(index->magic_n == DICT_INDEX_MAGIC_N); - ut_ad(index->cached); - - if (dict_index_is_clust(index)) { - - return(dict_index_get_n_unique(index)); - } - - return(dict_index_get_n_fields(index)); -} - -/********************************************************************//** -Gets the number of user-defined ordering fields in the index. In the internal -representation of clustered indexes we add the row id to the ordering fields -to make a clustered index unique, but this function returns the number of -fields the user defined in the index as ordering fields. -@return number of fields */ -UNIV_INLINE -ulint -dict_index_get_n_ordering_defined_by_user( -/*======================================*/ - const dict_index_t* index) /*!< in: an internal representation - of index (in the dictionary cache) */ -{ - return(index->n_user_defined_cols); -} - -#ifdef UNIV_DEBUG -/********************************************************************//** -Gets the nth field of an index. -@return pointer to field object */ -UNIV_INLINE -dict_field_t* -dict_index_get_nth_field( -/*=====================*/ - const dict_index_t* index, /*!< in: index */ - ulint pos) /*!< in: position of field */ -{ - ut_ad(index); - ut_ad(pos < index->n_def); - ut_ad(index->magic_n == DICT_INDEX_MAGIC_N); - - return((dict_field_t*) (index->fields) + pos); -} -#endif /* UNIV_DEBUG */ - -/********************************************************************//** -Returns the position of a system column in an index. -@return position, ULINT_UNDEFINED if not contained */ -UNIV_INLINE -ulint -dict_index_get_sys_col_pos( -/*=======================*/ - const dict_index_t* index, /*!< in: index */ - ulint type) /*!< in: DATA_ROW_ID, ... */ -{ - ut_ad(index); - ut_ad(index->magic_n == DICT_INDEX_MAGIC_N); - ut_ad(!dict_index_is_univ(index)); - - if (dict_index_is_clust(index)) { - - return(dict_col_get_clust_pos( - dict_table_get_sys_col(index->table, type), - index)); - } - - return(dict_index_get_nth_col_pos( - index, dict_table_get_sys_col_no(index->table, type), - NULL)); -} - -/*********************************************************************//** -Gets the field column. -@return field->col, pointer to the table column */ -UNIV_INLINE -const dict_col_t* -dict_field_get_col( -/*===============*/ - const dict_field_t* field) /*!< in: index field */ -{ - ut_ad(field); - - return(field->col); -} - -/********************************************************************//** -Gets pointer to the nth column in an index. -@return column */ -UNIV_INLINE -const dict_col_t* -dict_index_get_nth_col( -/*===================*/ - const dict_index_t* index, /*!< in: index */ - ulint pos) /*!< in: position of the field */ -{ - return(dict_field_get_col(dict_index_get_nth_field(index, pos))); -} - -/********************************************************************//** -Gets the column number the nth field in an index. -@return column number */ -UNIV_INLINE -ulint -dict_index_get_nth_col_no( -/*======================*/ - const dict_index_t* index, /*!< in: index */ - ulint pos) /*!< in: position of the field */ -{ - return(dict_col_get_no(dict_index_get_nth_col(index, pos))); -} - -/********************************************************************//** -Looks for column n in an index. -@return position in internal representation of the index; -ULINT_UNDEFINED if not contained */ -UNIV_INLINE -ulint -dict_index_get_nth_col_pos( -/*=======================*/ - const dict_index_t* index, /*!< in: index */ - ulint n, /*!< in: column number */ - ulint* prefix_col_pos) /*!< out: col num if prefix */ -{ - return(dict_index_get_nth_col_or_prefix_pos(index, n, FALSE, - prefix_col_pos)); -} - -#ifndef UNIV_HOTBACKUP -/********************************************************************//** -Returns the minimum data size of an index record. -@return minimum data size in bytes */ -UNIV_INLINE -ulint -dict_index_get_min_size( -/*====================*/ - const dict_index_t* index) /*!< in: index */ -{ - ulint n = dict_index_get_n_fields(index); - ulint size = 0; - - while (n--) { - size += dict_col_get_min_size(dict_index_get_nth_col(index, - n)); - } - - return(size); -} - -/*********************************************************************//** -Gets the space id of the root of the index tree. -@return space id */ -UNIV_INLINE -ulint -dict_index_get_space( -/*=================*/ - const dict_index_t* index) /*!< in: index */ -{ - ut_ad(index); - ut_ad(index->magic_n == DICT_INDEX_MAGIC_N); - - return(index->space); -} - -/*********************************************************************//** -Sets the space id of the root of the index tree. */ -UNIV_INLINE -void -dict_index_set_space( -/*=================*/ - dict_index_t* index, /*!< in/out: index */ - ulint space) /*!< in: space id */ -{ - ut_ad(index); - ut_ad(index->magic_n == DICT_INDEX_MAGIC_N); - - index->space = space; -} - -/*********************************************************************//** -Gets the page number of the root of the index tree. -@return page number */ -UNIV_INLINE -ulint -dict_index_get_page( -/*================*/ - const dict_index_t* index) /*!< in: index */ -{ - ut_ad(index); - ut_ad(index->magic_n == DICT_INDEX_MAGIC_N); - - return(index->page); -} - -/*********************************************************************//** -Gets the read-write lock of the index tree. -@return read-write lock */ -UNIV_INLINE -prio_rw_lock_t* -dict_index_get_lock( -/*================*/ - dict_index_t* index) /*!< in: index */ -{ - ut_ad(index); - ut_ad(index->magic_n == DICT_INDEX_MAGIC_N); - - return(&(index->lock)); -} - -/********************************************************************//** -Returns free space reserved for future updates of records. This is -relevant only in the case of many consecutive inserts, as updates -which make the records bigger might fragment the index. -@return number of free bytes on page, reserved for updates */ -UNIV_INLINE -ulint -dict_index_get_space_reserve(void) -/*==============================*/ -{ - return(UNIV_PAGE_SIZE / 16); -} - -/********************************************************************//** -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 */ -{ - enum online_index_status status; - - status = (enum online_index_status) index->online_status; - - /* Without the index->lock protection, the online - status can change from ONLINE_INDEX_CREATION to - ONLINE_INDEX_COMPLETE (or ONLINE_INDEX_ABORTED) in - row_log_apply() once log application is done. So to make - sure the status is ONLINE_INDEX_CREATION or ONLINE_INDEX_COMPLETE - you should always do the recheck after acquiring index->lock */ - -#ifdef UNIV_DEBUG - switch (status) { - case ONLINE_INDEX_COMPLETE: - case ONLINE_INDEX_CREATION: - case ONLINE_INDEX_ABORTED: - case ONLINE_INDEX_ABORTED_DROPPED: - return(status); - } - ut_error; -#endif /* UNIV_DEBUG */ - return(status); -} - -/********************************************************************//** -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 */ -{ - ut_ad(!(index->type & DICT_FTS)); -#ifdef UNIV_SYNC_DEBUG - ut_ad(rw_lock_own(dict_index_get_lock(index), RW_LOCK_EX)); -#endif /* UNIV_SYNC_DEBUG */ -#ifdef UNIV_DEBUG - switch (dict_index_get_online_status(index)) { - case ONLINE_INDEX_COMPLETE: - case ONLINE_INDEX_CREATION: - break; - case ONLINE_INDEX_ABORTED: - ut_ad(status == ONLINE_INDEX_ABORTED_DROPPED); - break; - case ONLINE_INDEX_ABORTED_DROPPED: - ut_error; - } -#endif /* UNIV_DEBUG */ - - index->online_status = status; - ut_ad(dict_index_get_online_status(index) == status); -} - -/********************************************************************//** -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 */ -{ -#ifdef UNIV_DEBUG - if (dict_index_is_clust(index)) { - switch (dict_index_get_online_status(index)) { - case ONLINE_INDEX_CREATION: - return(true); - case ONLINE_INDEX_COMPLETE: - return(false); - case ONLINE_INDEX_ABORTED: - case ONLINE_INDEX_ABORTED_DROPPED: - break; - } - ut_ad(0); - return(false); - } -#endif /* UNIV_DEBUG */ - - return(UNIV_UNLIKELY(dict_index_get_online_status(index) - != ONLINE_INDEX_COMPLETE)); -} - -/**********************************************************************//** -Check whether a column exists in an FTS index. -@return ULINT_UNDEFINED if no match else the offset within the vector */ -UNIV_INLINE -ulint -dict_table_is_fts_column( -/*=====================*/ - ib_vector_t* indexes,/*!< in: vector containing only FTS indexes */ - ulint col_no) /*!< in: col number to search for */ - -{ - ulint i; - - for (i = 0; i < ib_vector_size(indexes); ++i) { - dict_index_t* index; - - index = (dict_index_t*) ib_vector_getp(indexes, i); - - if (dict_index_contains_col_or_prefix(index, col_no)) { - - return(i); - } - } - - return(ULINT_UNDEFINED); -} - -/**********************************************************************//** -Determine bytes of column prefix to be stored in the undo log. Please -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 -ulint -dict_max_field_len_store_undo( -/*==========================*/ - dict_table_t* table, /*!< in: table */ - const dict_col_t* col) /*!< in: column which index prefix - is based on */ -{ - ulint prefix_len = 0; - - if (dict_table_get_format(table) >= UNIV_FORMAT_B) - { - prefix_len = col->max_prefix - ? col->max_prefix - : DICT_MAX_FIELD_LEN_BY_FORMAT(table); - } - - return(prefix_len); -} - -/********************************************************************//** -Check whether the index is corrupted. -@return nonzero for corrupted index, zero for valid indexes */ -UNIV_INLINE -ulint -dict_index_is_corrupted( -/*====================*/ - const dict_index_t* index) /*!< in: index */ -{ - ut_ad(index->magic_n == DICT_INDEX_MAGIC_N); - - return((index->type & DICT_CORRUPT) - || (index->table && index->table->corrupted)); -} - -/********************************************************************//** -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 */ -{ - return(DICT_TF2_FLAG_IS_SET(table, DICT_TF2_DISCARDED)); -} - -/********************************************************************//** -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 */ -{ - return(DICT_TF2_FLAG_IS_SET(table, DICT_TF2_TEMPORARY)); -} - -/**********************************************************************//** -Get index by first field of the index -@return index which is having first field matches -with the field present in field_index position of table */ -UNIV_INLINE -dict_index_t* -dict_table_get_index_on_first_col( -/*==============================*/ - const dict_table_t* table, /*!< in: table */ - ulint col_index) /*!< in: position of column - in table */ -{ - ut_ad(col_index < table->n_cols); - - dict_col_t* column = dict_table_get_nth_col(table, col_index); - - for (dict_index_t* index = dict_table_get_first_index(table); - index != NULL; index = dict_table_get_next_index(index)) { - - if (index->fields[0].col == column) { - return(index); - } - } - ut_error; - return(0); -} - -#endif /* !UNIV_HOTBACKUP */ |