1/*****************************************************************************
2
3Copyright (c) 1996, 2017, Oracle and/or its affiliates. All Rights Reserved.
4Copyright (c) 2012, Facebook Inc.
5Copyright (c) 2013, 2018, MariaDB Corporation.
6
7This program is free software; you can redistribute it and/or modify it under
8the terms of the GNU General Public License as published by the Free Software
9Foundation; version 2 of the License.
10
11This program is distributed in the hope that it will be useful, but WITHOUT
12ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License along with
16this program; if not, write to the Free Software Foundation, Inc.,
1751 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
18
19*****************************************************************************/
20
21/**************************************************//**
22@file include/dict0mem.h
23Data dictionary memory object creation
24
25Created 1/8/1996 Heikki Tuuri
26*******************************************************/
27
28#ifndef dict0mem_h
29#define dict0mem_h
30
31#include "univ.i"
32#include "dict0types.h"
33#include "data0type.h"
34#include "mem0mem.h"
35#include "row0types.h"
36#include "rem0types.h"
37#include "btr0types.h"
38#include "lock0types.h"
39#include "que0types.h"
40#include "sync0rw.h"
41#include "ut0mem.h"
42#include "ut0rnd.h"
43#include "ut0byte.h"
44#include "hash0hash.h"
45#include "trx0types.h"
46#include "fts0fts.h"
47#include "buf0buf.h"
48#include "gis0type.h"
49#include "os0once.h"
50#include "ut0new.h"
51#include "fil0fil.h"
52#include "fil0crypt.h"
53#include <set>
54#include <algorithm>
55#include <iterator>
56#include <ostream>
57
58/* Forward declaration. */
59struct ib_rbt_t;
60
61/** Type flags of an index: OR'ing of the flags is allowed to define a
62combination of types */
63/* @{ */
64#define DICT_CLUSTERED 1 /*!< clustered index; for other than
65 auto-generated clustered indexes,
66 also DICT_UNIQUE will be set */
67#define DICT_UNIQUE 2 /*!< unique index */
68#define DICT_IBUF 8 /*!< insert buffer tree */
69#define DICT_CORRUPT 16 /*!< bit to store the corrupted flag
70 in SYS_INDEXES.TYPE */
71#define DICT_FTS 32 /* FTS index; can't be combined with the
72 other flags */
73#define DICT_SPATIAL 64 /* SPATIAL index; can't be combined with the
74 other flags */
75#define DICT_VIRTUAL 128 /* Index on Virtual column */
76
77#define DICT_IT_BITS 8 /*!< number of bits used for
78 SYS_INDEXES.TYPE */
79/* @} */
80
81#if 0 /* not implemented, retained for history */
82/** Types for a table object */
83#define DICT_TABLE_ORDINARY 1 /*!< ordinary table */
84#define DICT_TABLE_CLUSTER_MEMBER 2
85#define DICT_TABLE_CLUSTER 3 /* this means that the table is
86 really a cluster definition */
87#endif
88
89/* Table and tablespace flags are generally not used for the Antelope file
90format except for the low order bit, which is used differently depending on
91where the flags are stored.
92
93==================== Low order flags bit =========================
94 | REDUNDANT | COMPACT | COMPRESSED and DYNAMIC
95SYS_TABLES.TYPE | 1 | 1 | 1
96dict_table_t::flags | 0 | 1 | 1
97FSP_SPACE_FLAGS | 0 | 0 | 1
98fil_space_t::flags | 0 | 0 | 1
99
100Before the 5.1 plugin, SYS_TABLES.TYPE was always DICT_TABLE_ORDINARY (1)
101and the tablespace flags field was always 0. In the 5.1 plugin, these fields
102were repurposed to identify compressed and dynamic row formats.
103
104The following types and constants describe the flags found in dict_table_t
105and SYS_TABLES.TYPE. Similar flags found in fil_space_t and FSP_SPACE_FLAGS
106are described in fsp0fsp.h. */
107
108/* @{ */
109/** dict_table_t::flags bit 0 is equal to 0 if the row format = Redundant */
110#define DICT_TF_REDUNDANT 0 /*!< Redundant row format. */
111/** dict_table_t::flags bit 0 is equal to 1 if the row format = Compact */
112#define DICT_TF_COMPACT 1U /*!< Compact row format. */
113
114/** This bitmask is used in SYS_TABLES.N_COLS to set and test whether
115the Compact page format is used, i.e ROW_FORMAT != REDUNDANT */
116#define DICT_N_COLS_COMPACT 0x80000000UL
117
118/** Width of the COMPACT flag */
119#define DICT_TF_WIDTH_COMPACT 1
120
121/** Width of the ZIP_SSIZE flag */
122#define DICT_TF_WIDTH_ZIP_SSIZE 4
123
124/** Width of the ATOMIC_BLOBS flag. The ROW_FORMAT=REDUNDANT and
125ROW_FORMAT=COMPACT broke up BLOB and TEXT fields, storing the first 768 bytes
126in the clustered index. ROW_FORMAT=DYNAMIC and ROW_FORMAT=COMPRESSED
127store the whole blob or text field off-page atomically.
128Secondary indexes are created from this external data using row_ext_t
129to cache the BLOB prefixes. */
130#define DICT_TF_WIDTH_ATOMIC_BLOBS 1
131
132/** If a table is created with the MYSQL option DATA DIRECTORY and
133innodb-file-per-table, an older engine will not be able to find that table.
134This flag prevents older engines from attempting to open the table and
135allows InnoDB to update_create_info() accordingly. */
136#define DICT_TF_WIDTH_DATA_DIR 1
137
138/**
139Width of the page compression flag
140*/
141#define DICT_TF_WIDTH_PAGE_COMPRESSION 1
142#define DICT_TF_WIDTH_PAGE_COMPRESSION_LEVEL 4
143
144/**
145The NO_ROLLBACK flag (3=yes; the values 1,2 used stand for
146ATOMIC_WRITES=ON and ATOMIC_WRITES=OFF between MariaDB 10.1.0 and 10.2.3)
147*/
148#define DICT_TF_WIDTH_NO_ROLLBACK 2
149
150/** Width of all the currently known table flags */
151#define DICT_TF_BITS (DICT_TF_WIDTH_COMPACT \
152 + DICT_TF_WIDTH_ZIP_SSIZE \
153 + DICT_TF_WIDTH_ATOMIC_BLOBS \
154 + DICT_TF_WIDTH_DATA_DIR \
155 + DICT_TF_WIDTH_PAGE_COMPRESSION \
156 + DICT_TF_WIDTH_PAGE_COMPRESSION_LEVEL \
157 + DICT_TF_WIDTH_NO_ROLLBACK)
158
159/** Zero relative shift position of the COMPACT field */
160#define DICT_TF_POS_COMPACT 0
161/** Zero relative shift position of the ZIP_SSIZE field */
162#define DICT_TF_POS_ZIP_SSIZE (DICT_TF_POS_COMPACT \
163 + DICT_TF_WIDTH_COMPACT)
164/** Zero relative shift position of the ATOMIC_BLOBS field */
165#define DICT_TF_POS_ATOMIC_BLOBS (DICT_TF_POS_ZIP_SSIZE \
166 + DICT_TF_WIDTH_ZIP_SSIZE)
167/** Zero relative shift position of the DATA_DIR field */
168#define DICT_TF_POS_DATA_DIR (DICT_TF_POS_ATOMIC_BLOBS \
169 + DICT_TF_WIDTH_ATOMIC_BLOBS)
170/** Zero relative shift position of the PAGE_COMPRESSION field */
171#define DICT_TF_POS_PAGE_COMPRESSION (DICT_TF_POS_DATA_DIR \
172 + DICT_TF_WIDTH_DATA_DIR)
173/** Zero relative shift position of the PAGE_COMPRESSION_LEVEL field */
174#define DICT_TF_POS_PAGE_COMPRESSION_LEVEL (DICT_TF_POS_PAGE_COMPRESSION \
175 + DICT_TF_WIDTH_PAGE_COMPRESSION)
176/** Zero relative shift position of the NO_ROLLBACK field */
177#define DICT_TF_POS_NO_ROLLBACK (DICT_TF_POS_PAGE_COMPRESSION_LEVEL \
178 + DICT_TF_WIDTH_PAGE_COMPRESSION_LEVEL)
179#define DICT_TF_POS_UNUSED (DICT_TF_POS_NO_ROLLBACK \
180 + DICT_TF_WIDTH_NO_ROLLBACK)
181
182/** Bit mask of the COMPACT field */
183#define DICT_TF_MASK_COMPACT \
184 ((~(~0U << DICT_TF_WIDTH_COMPACT)) \
185 << DICT_TF_POS_COMPACT)
186/** Bit mask of the ZIP_SSIZE field */
187#define DICT_TF_MASK_ZIP_SSIZE \
188 ((~(~0U << DICT_TF_WIDTH_ZIP_SSIZE)) \
189 << DICT_TF_POS_ZIP_SSIZE)
190/** Bit mask of the ATOMIC_BLOBS field */
191#define DICT_TF_MASK_ATOMIC_BLOBS \
192 ((~(~0U << DICT_TF_WIDTH_ATOMIC_BLOBS)) \
193 << DICT_TF_POS_ATOMIC_BLOBS)
194/** Bit mask of the DATA_DIR field */
195#define DICT_TF_MASK_DATA_DIR \
196 ((~(~0U << DICT_TF_WIDTH_DATA_DIR)) \
197 << DICT_TF_POS_DATA_DIR)
198/** Bit mask of the PAGE_COMPRESSION field */
199#define DICT_TF_MASK_PAGE_COMPRESSION \
200 ((~(~0U << DICT_TF_WIDTH_PAGE_COMPRESSION)) \
201 << DICT_TF_POS_PAGE_COMPRESSION)
202/** Bit mask of the PAGE_COMPRESSION_LEVEL field */
203#define DICT_TF_MASK_PAGE_COMPRESSION_LEVEL \
204 ((~(~0U << DICT_TF_WIDTH_PAGE_COMPRESSION_LEVEL)) \
205 << DICT_TF_POS_PAGE_COMPRESSION_LEVEL)
206/** Bit mask of the NO_ROLLBACK field */
207#define DICT_TF_MASK_NO_ROLLBACK \
208 ((~(~0U << DICT_TF_WIDTH_NO_ROLLBACK)) \
209 << DICT_TF_POS_NO_ROLLBACK)
210
211/** Return the value of the COMPACT field */
212#define DICT_TF_GET_COMPACT(flags) \
213 ((flags & DICT_TF_MASK_COMPACT) \
214 >> DICT_TF_POS_COMPACT)
215/** Return the value of the ZIP_SSIZE field */
216#define DICT_TF_GET_ZIP_SSIZE(flags) \
217 ((flags & DICT_TF_MASK_ZIP_SSIZE) \
218 >> DICT_TF_POS_ZIP_SSIZE)
219/** Return the value of the ATOMIC_BLOBS field */
220#define DICT_TF_HAS_ATOMIC_BLOBS(flags) \
221 ((flags & DICT_TF_MASK_ATOMIC_BLOBS) \
222 >> DICT_TF_POS_ATOMIC_BLOBS)
223/** Return the value of the DATA_DIR field */
224#define DICT_TF_HAS_DATA_DIR(flags) \
225 ((flags & DICT_TF_MASK_DATA_DIR) \
226 >> DICT_TF_POS_DATA_DIR)
227/** Return the value of the PAGE_COMPRESSION field */
228#define DICT_TF_GET_PAGE_COMPRESSION(flags) \
229 ((flags & DICT_TF_MASK_PAGE_COMPRESSION) \
230 >> DICT_TF_POS_PAGE_COMPRESSION)
231/** Return the value of the PAGE_COMPRESSION_LEVEL field */
232#define DICT_TF_GET_PAGE_COMPRESSION_LEVEL(flags) \
233 ((flags & DICT_TF_MASK_PAGE_COMPRESSION_LEVEL) \
234 >> DICT_TF_POS_PAGE_COMPRESSION_LEVEL)
235
236/* @} */
237
238/** @brief Table Flags set number 2.
239
240These flags will be stored in SYS_TABLES.MIX_LEN. All unused flags
241will be written as 0. The column may contain garbage for tables
242created with old versions of InnoDB that only implemented
243ROW_FORMAT=REDUNDANT. InnoDB engines do not check these flags
244for unknown bits in order to protect backward incompatibility. */
245/* @{ */
246/** Total number of bits in table->flags2. */
247#define DICT_TF2_BITS 7
248#define DICT_TF2_UNUSED_BIT_MASK (~0U << DICT_TF2_BITS)
249#define DICT_TF2_BIT_MASK ~DICT_TF2_UNUSED_BIT_MASK
250
251/** TEMPORARY; TRUE for tables from CREATE TEMPORARY TABLE. */
252#define DICT_TF2_TEMPORARY 1U
253
254/** The table has an internal defined DOC ID column */
255#define DICT_TF2_FTS_HAS_DOC_ID 2U
256
257/** The table has an FTS index */
258#define DICT_TF2_FTS 4U
259
260/** Need to add Doc ID column for FTS index build.
261This is a transient bit for index build */
262#define DICT_TF2_FTS_ADD_DOC_ID 8U
263
264/** This bit is used during table creation to indicate that it will
265use its own tablespace instead of the system tablespace. */
266#define DICT_TF2_USE_FILE_PER_TABLE 16U
267
268/** Set when we discard/detach the tablespace */
269#define DICT_TF2_DISCARDED 32U
270
271/** This bit is set if all aux table names (both common tables and
272index tables) of a FTS table are in HEX format. */
273#define DICT_TF2_FTS_AUX_HEX_NAME 64U
274
275/* @} */
276
277#define DICT_TF2_FLAG_SET(table, flag) \
278 (table->flags2 |= (flag))
279
280#define DICT_TF2_FLAG_IS_SET(table, flag) \
281 (table->flags2 & (flag))
282
283#define DICT_TF2_FLAG_UNSET(table, flag) \
284 (table->flags2 &= ~(flag))
285
286/** Tables could be chained together with Foreign key constraint. When
287first load the parent table, we would load all of its descedents.
288This could result in rescursive calls and out of stack error eventually.
289DICT_FK_MAX_RECURSIVE_LOAD defines the maximum number of recursive loads,
290when exceeded, the child table will not be loaded. It will be loaded when
291the foreign constraint check needs to be run. */
292#define DICT_FK_MAX_RECURSIVE_LOAD 20
293
294/** Similarly, when tables are chained together with foreign key constraints
295with on cascading delete/update clause, delete from parent table could
296result in recursive cascading calls. This defines the maximum number of
297such cascading deletes/updates allowed. When exceeded, the delete from
298parent table will fail, and user has to drop excessive foreign constraint
299before proceeds. */
300#define FK_MAX_CASCADE_DEL 15
301
302/**********************************************************************//**
303Creates a table memory object.
304@return own: table object */
305dict_table_t*
306dict_mem_table_create(
307/*==================*/
308 const char* name, /*!< in: table name */
309 fil_space_t* space, /*!< in: tablespace */
310 ulint n_cols, /*!< in: total number of columns
311 including virtual and non-virtual
312 columns */
313 ulint n_v_cols, /*!< in: number of virtual columns */
314 ulint flags, /*!< in: table flags */
315 ulint flags2); /*!< in: table flags2 */
316/****************************************************************//**
317Free a table memory object. */
318void
319dict_mem_table_free(
320/*================*/
321 dict_table_t* table); /*!< in: table */
322/**********************************************************************//**
323Adds a column definition to a table. */
324void
325dict_mem_table_add_col(
326/*===================*/
327 dict_table_t* table, /*!< in: table */
328 mem_heap_t* heap, /*!< in: temporary memory heap, or NULL */
329 const char* name, /*!< in: column name, or NULL */
330 ulint mtype, /*!< in: main datatype */
331 ulint prtype, /*!< in: precise type */
332 ulint len) /*!< in: precision */
333 MY_ATTRIBUTE((nonnull(1)));
334/** Adds a virtual column definition to a table.
335@param[in,out] table table
336@param[in] heap temporary memory heap, or NULL. It is
337 used to store name when we have not finished
338 adding all columns. When all columns are
339 added, the whole name will copy to memory from
340 table->heap
341@param[in] name column name
342@param[in] mtype main datatype
343@param[in] prtype precise type
344@param[in] len length
345@param[in] pos position in a table
346@param[in] num_base number of base columns
347@return the virtual column definition */
348dict_v_col_t*
349dict_mem_table_add_v_col(
350 dict_table_t* table,
351 mem_heap_t* heap,
352 const char* name,
353 ulint mtype,
354 ulint prtype,
355 ulint len,
356 ulint pos,
357 ulint num_base);
358
359/** Adds a stored column definition to a table.
360@param[in] table table
361@param[in] num_base number of base columns. */
362void
363dict_mem_table_add_s_col(
364 dict_table_t* table,
365 ulint num_base);
366
367/**********************************************************************//**
368Renames a column of a table in the data dictionary cache. */
369void
370dict_mem_table_col_rename(
371/*======================*/
372 dict_table_t* table, /*!< in/out: table */
373 ulint nth_col,/*!< in: column index */
374 const char* from, /*!< in: old column name */
375 const char* to, /*!< in: new column name */
376 bool is_virtual);
377 /*!< in: if this is a virtual column */
378/**********************************************************************//**
379This function populates a dict_col_t memory structure with
380supplied information. */
381void
382dict_mem_fill_column_struct(
383/*========================*/
384 dict_col_t* column, /*!< out: column struct to be
385 filled */
386 ulint col_pos, /*!< in: column position */
387 ulint mtype, /*!< in: main data type */
388 ulint prtype, /*!< in: precise type */
389 ulint col_len); /*!< in: column length */
390/**********************************************************************//**
391This function poplulates a dict_index_t index memory structure with
392supplied information. */
393UNIV_INLINE
394void
395dict_mem_fill_index_struct(
396/*=======================*/
397 dict_index_t* index, /*!< out: index to be filled */
398 mem_heap_t* heap, /*!< in: memory heap */
399 const char* index_name, /*!< in: index name */
400 ulint type, /*!< in: DICT_UNIQUE,
401 DICT_CLUSTERED, ... ORed */
402 ulint n_fields); /*!< in: number of fields */
403/**********************************************************************//**
404Creates an index memory object.
405@return own: index object */
406dict_index_t*
407dict_mem_index_create(
408/*==================*/
409 dict_table_t* table, /*!< in: table */
410 const char* index_name, /*!< in: index name */
411 ulint type, /*!< in: DICT_UNIQUE,
412 DICT_CLUSTERED, ... ORed */
413 ulint n_fields); /*!< in: number of fields */
414/**********************************************************************//**
415Adds a field definition to an index. NOTE: does not take a copy
416of the column name if the field is a column. The memory occupied
417by the column name may be released only after publishing the index. */
418void
419dict_mem_index_add_field(
420/*=====================*/
421 dict_index_t* index, /*!< in: index */
422 const char* name, /*!< in: column name */
423 ulint prefix_len); /*!< in: 0 or the column prefix length
424 in a MySQL index like
425 INDEX (textcol(25)) */
426/**********************************************************************//**
427Frees an index memory object. */
428void
429dict_mem_index_free(
430/*================*/
431 dict_index_t* index); /*!< in: index */
432/**********************************************************************//**
433Creates and initializes a foreign constraint memory object.
434@return own: foreign constraint struct */
435dict_foreign_t*
436dict_mem_foreign_create(void);
437/*=========================*/
438
439/**********************************************************************//**
440Sets the foreign_table_name_lookup pointer based on the value of
441lower_case_table_names. If that is 0 or 1, foreign_table_name_lookup
442will point to foreign_table_name. If 2, then another string is
443allocated from the heap and set to lower case. */
444void
445dict_mem_foreign_table_name_lookup_set(
446/*===================================*/
447 dict_foreign_t* foreign, /*!< in/out: foreign struct */
448 ibool do_alloc); /*!< in: is an alloc needed */
449
450/**********************************************************************//**
451Sets the referenced_table_name_lookup pointer based on the value of
452lower_case_table_names. If that is 0 or 1, referenced_table_name_lookup
453will point to referenced_table_name. If 2, then another string is
454allocated from the heap and set to lower case. */
455void
456dict_mem_referenced_table_name_lookup_set(
457/*======================================*/
458 dict_foreign_t* foreign, /*!< in/out: foreign struct */
459 ibool do_alloc); /*!< in: is an alloc needed */
460
461/** Fills the dependent virtual columns in a set.
462Reason for being dependent are
4631) FK can be present on base column of virtual columns
4642) FK can be present on column which is a part of virtual index
465@param[in,out] foreign foreign key information. */
466void
467dict_mem_foreign_fill_vcol_set(
468 dict_foreign_t* foreign);
469
470/** Fill virtual columns set in each fk constraint present in the table.
471@param[in,out] table innodb table object. */
472void
473dict_mem_table_fill_foreign_vcol_set(
474 dict_table_t* table);
475
476/** Free the vcol_set from all foreign key constraint on the table.
477@param[in,out] table innodb table object. */
478void
479dict_mem_table_free_foreign_vcol_set(
480 dict_table_t* table);
481
482/** Create a temporary tablename like "#sql-ibtid-inc where
483 tid = the Table ID
484 inc = a randomly initialized number that is incremented for each file
485The table ID is a 64 bit integer, can use up to 20 digits, and is
486initialized at bootstrap. The second number is 32 bits, can use up to 10
487digits, and is initialized at startup to a randomly distributed number.
488It is hoped that the combination of these two numbers will provide a
489reasonably unique temporary file name.
490@param[in] heap A memory heap
491@param[in] dbtab Table name in the form database/table name
492@param[in] id Table id
493@return A unique temporary tablename suitable for InnoDB use */
494char*
495dict_mem_create_temporary_tablename(
496 mem_heap_t* heap,
497 const char* dbtab,
498 table_id_t id);
499
500/** Initialize dict memory variables */
501void
502dict_mem_init(void);
503
504/** SQL identifier name wrapper for pretty-printing */
505class id_name_t
506{
507public:
508 /** Default constructor */
509 id_name_t()
510 : m_name()
511 {}
512 /** Constructor
513 @param[in] name identifier to assign */
514 explicit id_name_t(
515 const char* name)
516 : m_name(name)
517 {}
518
519 /** Assignment operator
520 @param[in] name identifier to assign */
521 id_name_t& operator=(
522 const char* name)
523 {
524 m_name = name;
525 return(*this);
526 }
527
528 /** Implicit type conversion
529 @return the name */
530 operator const char*() const
531 {
532 return(m_name);
533 }
534
535 /** Explicit type conversion
536 @return the name */
537 const char* operator()() const
538 {
539 return(m_name);
540 }
541
542private:
543 /** The name in internal representation */
544 const char* m_name;
545};
546
547/** Data structure for a column in a table */
548struct dict_col_t{
549 /*----------------------*/
550 /** The following are copied from dtype_t,
551 so that all bit-fields can be packed tightly. */
552 /* @{ */
553 unsigned prtype:32; /*!< precise type; MySQL data
554 type, charset code, flags to
555 indicate nullability,
556 signedness, whether this is a
557 binary string, whether this is
558 a true VARCHAR where MySQL
559 uses 2 bytes to store the length */
560 unsigned mtype:8; /*!< main data type */
561
562 /* the remaining fields do not affect alphabetical ordering: */
563
564 unsigned len:16; /*!< length; for MySQL data this
565 is field->pack_length(),
566 except that for a >= 5.0.3
567 type true VARCHAR this is the
568 maximum byte length of the
569 string data (in addition to
570 the string, MySQL uses 1 or 2
571 bytes to store the string length) */
572
573 unsigned mbminlen:3; /*!< minimum length of a
574 character, in bytes */
575 unsigned mbmaxlen:3; /*!< maximum length of a
576 character, in bytes */
577 /*----------------------*/
578 /* End of definitions copied from dtype_t */
579 /* @} */
580
581 unsigned ind:10; /*!< table column position
582 (starting from 0) */
583 unsigned ord_part:1; /*!< nonzero if this column
584 appears in the ordering fields
585 of an index */
586 unsigned max_prefix:12; /*!< maximum index prefix length on
587 this column. Our current max limit is
588 3072 (REC_VERSION_56_MAX_INDEX_COL_LEN)
589 bytes. */
590
591 /** Data for instantly added columns */
592 struct {
593 /** original default value of instantly added column */
594 const void* data;
595 /** len of data, or UNIV_SQL_DEFAULT if unavailable */
596 ulint len;
597 } def_val;
598
599 /** Retrieve the column name.
600 @param[in] table table name */
601 const char* name(const dict_table_t& table) const;
602
603 /** @return whether this is a virtual column */
604 bool is_virtual() const { return prtype & DATA_VIRTUAL; }
605 /** @return whether NULL is an allowed value for this column */
606 bool is_nullable() const { return !(prtype & DATA_NOT_NULL); }
607
608 /** @return whether table of this system field is TRX_ID-based */
609 bool vers_native() const
610 {
611 ut_ad(vers_sys_start() || vers_sys_end());
612 ut_ad(mtype == DATA_INT || mtype == DATA_FIXBINARY);
613 return mtype == DATA_INT;
614 }
615 /** @return whether this is system versioned */
616 bool is_versioned() const { return !(~prtype & DATA_VERSIONED); }
617 /** @return whether this is the system version start */
618 bool vers_sys_start() const
619 {
620 return (prtype & DATA_VERSIONED) == DATA_VERS_START;
621 }
622 /** @return whether this is the system version end */
623 bool vers_sys_end() const
624 {
625 return (prtype & DATA_VERSIONED) == DATA_VERS_END;
626 }
627
628 /** @return whether this is an instantly-added column */
629 bool is_instant() const
630 {
631 DBUG_ASSERT(def_val.len != UNIV_SQL_DEFAULT || !def_val.data);
632 return def_val.len != UNIV_SQL_DEFAULT;
633 }
634 /** Get the default value of an instantly-added column.
635 @param[out] len value length (in bytes), or UNIV_SQL_NULL
636 @return default value
637 @retval NULL if the default value is SQL NULL (len=UNIV_SQL_NULL) */
638 const byte* instant_value(ulint* len) const
639 {
640 DBUG_ASSERT(is_instant());
641 *len = def_val.len;
642 return static_cast<const byte*>(def_val.data);
643 }
644
645 /** Remove the 'instant ADD' status of the column */
646 void remove_instant()
647 {
648 DBUG_ASSERT(is_instant());
649 def_val.len = UNIV_SQL_DEFAULT;
650 def_val.data = NULL;
651 }
652};
653
654/** Index information put in a list of virtual column structure. Index
655id and virtual column position in the index will be logged.
656There can be multiple entries for a given index, with a different position. */
657struct dict_v_idx_t {
658 /** active index on the column */
659 dict_index_t* index;
660
661 /** position in this index */
662 ulint nth_field;
663
664 dict_v_idx_t(dict_index_t* index, ulint nth_field)
665 : index(index), nth_field(nth_field) {}
666};
667
668/** Index list to put in dict_v_col_t */
669typedef std::list<dict_v_idx_t, ut_allocator<dict_v_idx_t> > dict_v_idx_list;
670
671/** Data structure for a virtual column in a table */
672struct dict_v_col_t{
673 /** column structure */
674 dict_col_t m_col;
675
676 /** array of base column ptr */
677 dict_col_t** base_col;
678
679 /** number of base column */
680 ulint num_base;
681
682 /** column pos in table */
683 ulint v_pos;
684
685 /** Virtual index list, and column position in the index,
686 the allocated memory is not from table->heap, nor it is
687 tracked by dict_sys->size */
688 dict_v_idx_list* v_indexes;
689
690};
691
692/** Data structure for newly added virtual column in a table */
693struct dict_add_v_col_t{
694 /** number of new virtual column */
695 ulint n_v_col;
696
697 /** column structures */
698 const dict_v_col_t* v_col;
699
700 /** new col names */
701 const char** v_col_name;
702};
703
704/** Data structure for a stored column in a table. */
705struct dict_s_col_t {
706 /** Stored column ptr */
707 dict_col_t* m_col;
708 /** array of base col ptr */
709 dict_col_t** base_col;
710 /** number of base columns */
711 ulint num_base;
712 /** column pos in table */
713 ulint s_pos;
714};
715
716/** list to put stored column for create_table_info_t */
717typedef std::list<dict_s_col_t, ut_allocator<dict_s_col_t> > dict_s_col_list;
718
719/** @brief DICT_ANTELOPE_MAX_INDEX_COL_LEN is measured in bytes and
720is the maximum indexed column length (or indexed prefix length) in
721ROW_FORMAT=REDUNDANT and ROW_FORMAT=COMPACT. Also, in any format,
722any fixed-length field that is longer than this will be encoded as
723a variable-length field.
724
725It is set to 3*256, so that one can create a column prefix index on
726256 characters of a TEXT or VARCHAR column also in the UTF-8
727charset. In that charset, a character may take at most 3 bytes. This
728constant MUST NOT BE CHANGED, or the compatibility of InnoDB data
729files would be at risk! */
730#define DICT_ANTELOPE_MAX_INDEX_COL_LEN REC_ANTELOPE_MAX_INDEX_COL_LEN
731
732/** Find out maximum indexed column length by its table format.
733For ROW_FORMAT=REDUNDANT and ROW_FORMAT=COMPACT, the maximum
734field length is REC_ANTELOPE_MAX_INDEX_COL_LEN - 1 (767). For
735ROW_FORMAT=COMPRESSED and ROW_FORMAT=DYNAMIC, the length could
736be REC_VERSION_56_MAX_INDEX_COL_LEN (3072) bytes */
737#define DICT_MAX_FIELD_LEN_BY_FORMAT(table) \
738 (dict_table_has_atomic_blobs(table) \
739 ? REC_VERSION_56_MAX_INDEX_COL_LEN \
740 : REC_ANTELOPE_MAX_INDEX_COL_LEN - 1)
741
742#define DICT_MAX_FIELD_LEN_BY_FORMAT_FLAG(flags) \
743 (DICT_TF_HAS_ATOMIC_BLOBS(flags) \
744 ? REC_VERSION_56_MAX_INDEX_COL_LEN \
745 : REC_ANTELOPE_MAX_INDEX_COL_LEN - 1)
746
747/** Defines the maximum fixed length column size */
748#define DICT_MAX_FIXED_COL_LEN DICT_ANTELOPE_MAX_INDEX_COL_LEN
749
750#ifdef WITH_WSREP
751#define WSREP_MAX_SUPPORTED_KEY_LENGTH 3500
752#endif /* WITH_WSREP */
753
754/** Data structure for a field in an index */
755struct dict_field_t{
756 dict_col_t* col; /*!< pointer to the table column */
757 id_name_t name; /*!< name of the column */
758 unsigned prefix_len:12; /*!< 0 or the length of the column
759 prefix in bytes in a MySQL index of
760 type, e.g., INDEX (textcol(25));
761 must be smaller than
762 DICT_MAX_FIELD_LEN_BY_FORMAT;
763 NOTE that in the UTF-8 charset, MySQL
764 sets this to (mbmaxlen * the prefix len)
765 in UTF-8 chars */
766 unsigned fixed_len:10; /*!< 0 or the fixed length of the
767 column if smaller than
768 DICT_ANTELOPE_MAX_INDEX_COL_LEN */
769
770 /** Check whether two index fields are equivalent.
771 @param[in] old the other index field
772 @return whether the index fields are equivalent */
773 bool same(const dict_field_t& other) const
774 {
775 return(prefix_len == other.prefix_len
776 && fixed_len == other.fixed_len);
777 }
778};
779
780/**********************************************************************//**
781PADDING HEURISTIC BASED ON LINEAR INCREASE OF PADDING TO AVOID
782COMPRESSION FAILURES
783(Note: this is relevant only for compressed indexes)
784GOAL: Avoid compression failures by maintaining information about the
785compressibility of data. If data is not very compressible then leave
786some extra space 'padding' in the uncompressed page making it more
787likely that compression of less than fully packed uncompressed page will
788succeed.
789
790This padding heuristic works by increasing the pad linearly until the
791desired failure rate is reached. A "round" is a fixed number of
792compression operations.
793After each round, the compression failure rate for that round is
794computed. If the failure rate is too high, then padding is incremented
795by a fixed value, otherwise it's left intact.
796If the compression failure is lower than the desired rate for a fixed
797number of consecutive rounds, then the padding is decreased by a fixed
798value. This is done to prevent overshooting the padding value,
799and to accommodate the possible change in data compressibility. */
800
801/** Number of zip ops in one round. */
802#define ZIP_PAD_ROUND_LEN (128)
803
804/** Number of successful rounds after which the padding is decreased */
805#define ZIP_PAD_SUCCESSFUL_ROUND_LIMIT (5)
806
807/** Amount by which padding is increased. */
808#define ZIP_PAD_INCR (128)
809
810/** Percentage of compression failures that are allowed in a single
811round */
812extern ulong zip_failure_threshold_pct;
813
814/** Maximum percentage of a page that can be allowed as a pad to avoid
815compression failures */
816extern ulong zip_pad_max;
817
818/** Data structure to hold information about about how much space in
819an uncompressed page should be left as padding to avoid compression
820failures. This estimate is based on a self-adapting heuristic. */
821struct zip_pad_info_t {
822 SysMutex* mutex; /*!< mutex protecting the info */
823 ulint pad; /*!< number of bytes used as pad */
824 ulint success;/*!< successful compression ops during
825 current round */
826 ulint failure;/*!< failed compression ops during
827 current round */
828 ulint n_rounds;/*!< number of currently successful
829 rounds */
830 volatile os_once::state_t
831 mutex_created;
832 /*!< Creation state of mutex member */
833};
834
835/** Number of samples of data size kept when page compression fails for
836a certain index.*/
837#define STAT_DEFRAG_DATA_SIZE_N_SAMPLE 10
838
839/** "GEN_CLUST_INDEX" is the name reserved for InnoDB default
840system clustered index when there is no primary key. */
841const char innobase_index_reserve_name[] = "GEN_CLUST_INDEX";
842
843/* Estimated number of offsets in records (based on columns)
844to start with. */
845#define OFFS_IN_REC_NORMAL_SIZE 100
846
847/** Data structure for an index. Most fields will be
848initialized to 0, NULL or FALSE in dict_mem_index_create(). */
849struct dict_index_t{
850 index_id_t id; /*!< id of the index */
851 mem_heap_t* heap; /*!< memory heap */
852 id_name_t name; /*!< index name */
853 dict_table_t* table; /*!< back pointer to table */
854 unsigned page:32;/*!< index tree root page number */
855 unsigned merge_threshold:6;
856 /*!< In the pessimistic delete, if the page
857 data size drops below this limit in percent,
858 merging it to a neighbor is tried */
859# define DICT_INDEX_MERGE_THRESHOLD_DEFAULT 50
860 unsigned type:DICT_IT_BITS;
861 /*!< index type (DICT_CLUSTERED, DICT_UNIQUE,
862 DICT_IBUF, DICT_CORRUPT) */
863#define MAX_KEY_LENGTH_BITS 12
864 unsigned trx_id_offset:MAX_KEY_LENGTH_BITS;
865 /*!< position of the trx id column
866 in a clustered index record, if the fields
867 before it are known to be of a fixed size,
868 0 otherwise */
869#if (1<<MAX_KEY_LENGTH_BITS) < HA_MAX_KEY_LENGTH
870# error (1<<MAX_KEY_LENGTH_BITS) < HA_MAX_KEY_LENGTH
871#endif
872 unsigned n_user_defined_cols:10;
873 /*!< number of columns the user defined to
874 be in the index: in the internal
875 representation we add more columns */
876 unsigned nulls_equal:1;
877 /*!< if true, SQL NULL == SQL NULL */
878#ifdef BTR_CUR_HASH_ADAPT
879#ifdef MYSQL_INDEX_DISABLE_AHI
880 unsigned disable_ahi:1;
881 /*!< whether to disable the
882 adaptive hash index.
883 Maybe this could be disabled for
884 temporary tables? */
885#endif
886#endif /* BTR_CUR_HASH_ADAPT */
887 unsigned n_uniq:10;/*!< number of fields from the beginning
888 which are enough to determine an index
889 entry uniquely */
890 unsigned n_def:10;/*!< number of fields defined so far */
891 unsigned n_fields:10;/*!< number of fields in the index */
892 unsigned n_nullable:10;/*!< number of nullable fields */
893 unsigned n_core_fields:10;/*!< number of fields in the index
894 (before the first time of instant add columns) */
895 /** number of bytes of null bits in ROW_FORMAT!=REDUNDANT node pointer
896 records; usually equal to UT_BITS_IN_BYTES(n_nullable), but
897 can be less in clustered indexes with instant ADD COLUMN */
898 unsigned n_core_null_bytes:8;
899 /** magic value signalling that n_core_null_bytes was not
900 initialized yet */
901 static const unsigned NO_CORE_NULL_BYTES = 0xff;
902 /** The clustered index ID of the hard-coded SYS_INDEXES table. */
903 static const unsigned DICT_INDEXES_ID = 3;
904 unsigned cached:1;/*!< TRUE if the index object is in the
905 dictionary cache */
906 unsigned to_be_dropped:1;
907 /*!< TRUE if the index is to be dropped;
908 protected by dict_operation_lock */
909 unsigned online_status:2;
910 /*!< enum online_index_status.
911 Transitions from ONLINE_INDEX_COMPLETE (to
912 ONLINE_INDEX_CREATION) are protected
913 by dict_operation_lock and
914 dict_sys->mutex. Other changes are
915 protected by index->lock. */
916 unsigned uncommitted:1;
917 /*!< a flag that is set for secondary indexes
918 that have not been committed to the
919 data dictionary yet */
920
921#ifdef UNIV_DEBUG
922 /** whether this is a dummy index object */
923 bool is_dummy;
924 uint32_t magic_n;/*!< magic number */
925/** Value of dict_index_t::magic_n */
926# define DICT_INDEX_MAGIC_N 76789786
927#endif
928 dict_field_t* fields; /*!< array of field descriptions */
929 st_mysql_ftparser*
930 parser; /*!< fulltext parser plugin */
931 bool has_new_v_col;
932 /*!< whether it has a newly added virtual
933 column in ALTER */
934 bool index_fts_syncing;/*!< Whether the fts index is
935 still syncing in the background;
936 FIXME: remove this and use MDL */
937 UT_LIST_NODE_T(dict_index_t)
938 indexes;/*!< list of indexes of the table */
939#ifdef BTR_CUR_ADAPT
940 btr_search_t* search_info;
941 /*!< info used in optimistic searches */
942#endif /* BTR_CUR_ADAPT */
943 row_log_t* online_log;
944 /*!< the log of modifications
945 during online index creation;
946 valid when online_status is
947 ONLINE_INDEX_CREATION */
948 /*----------------------*/
949 /** Statistics for query optimization */
950 /* @{ */
951 ib_uint64_t* stat_n_diff_key_vals;
952 /*!< approximate number of different
953 key values for this index, for each
954 n-column prefix where 1 <= n <=
955 dict_get_n_unique(index) (the array is
956 indexed from 0 to n_uniq-1); we
957 periodically calculate new
958 estimates */
959 ib_uint64_t* stat_n_sample_sizes;
960 /*!< number of pages that were sampled
961 to calculate each of stat_n_diff_key_vals[],
962 e.g. stat_n_sample_sizes[3] pages were sampled
963 to get the number stat_n_diff_key_vals[3]. */
964 ib_uint64_t* stat_n_non_null_key_vals;
965 /* approximate number of non-null key values
966 for this index, for each column where
967 1 <= n <= dict_get_n_unique(index) (the array
968 is indexed from 0 to n_uniq-1); This
969 is used when innodb_stats_method is
970 "nulls_ignored". */
971 ulint stat_index_size;
972 /*!< approximate index size in
973 database pages */
974 ulint stat_n_leaf_pages;
975 /*!< approximate number of leaf pages in the
976 index tree */
977 bool stats_error_printed;
978 /*!< has persistent statistics error printed
979 for this index ? */
980 /* @} */
981 /** Statistics for defragmentation, these numbers are estimations and
982 could be very inaccurate at certain times, e.g. right after restart,
983 during defragmentation, etc. */
984 /* @{ */
985 ulint stat_defrag_modified_counter;
986 ulint stat_defrag_n_pages_freed;
987 /* number of pages freed by defragmentation. */
988 ulint stat_defrag_n_page_split;
989 /* number of page splits since last full index
990 defragmentation. */
991 ulint stat_defrag_data_size_sample[STAT_DEFRAG_DATA_SIZE_N_SAMPLE];
992 /* data size when compression failure happened
993 the most recent 10 times. */
994 ulint stat_defrag_sample_next_slot;
995 /* in which slot the next sample should be
996 saved. */
997 /* @} */
998 rtr_ssn_t rtr_ssn;/*!< Node sequence number for RTree */
999 rtr_info_track_t*
1000 rtr_track;/*!< tracking all R-Tree search cursors */
1001 trx_id_t trx_id; /*!< id of the transaction that created this
1002 index, or 0 if the index existed
1003 when InnoDB was started up */
1004 zip_pad_info_t zip_pad;/*!< Information about state of
1005 compression failures and successes */
1006 rw_lock_t lock; /*!< read-write lock protecting the
1007 upper levels of the index tree */
1008
1009 /** Determine if the index has been committed to the
1010 data dictionary.
1011 @return whether the index definition has been committed */
1012 bool is_committed() const
1013 {
1014 ut_ad(!uncommitted || !(type & DICT_CLUSTERED));
1015 return(UNIV_LIKELY(!uncommitted));
1016 }
1017
1018 /** Flag an index committed or uncommitted.
1019 @param[in] committed whether the index is committed */
1020 void set_committed(bool committed)
1021 {
1022 ut_ad(!to_be_dropped);
1023 ut_ad(committed || !(type & DICT_CLUSTERED));
1024 uncommitted = !committed;
1025 }
1026
1027 /** Notify that the index pages are going to be modified.
1028 @param[in,out] mtr mini-transaction */
1029 inline void set_modified(mtr_t& mtr) const;
1030
1031 /** @return whether this index is readable
1032 @retval true normally
1033 @retval false if this is a single-table tablespace
1034 and the .ibd file is missing, or a
1035 page cannot be read or decrypted */
1036 inline bool is_readable() const;
1037
1038 /** @return whether instant ADD COLUMN is in effect */
1039 inline bool is_instant() const;
1040
1041 /** @return whether the index is the primary key index
1042 (not the clustered index of the change buffer) */
1043 bool is_primary() const
1044 {
1045 return DICT_CLUSTERED == (type & (DICT_CLUSTERED | DICT_IBUF));
1046 }
1047
1048 /** @return whether the index is corrupted */
1049 inline bool is_corrupted() const;
1050
1051 /** Determine how many fields of a given prefix can be set NULL.
1052 @param[in] n_prefix number of fields in the prefix
1053 @return number of fields 0..n_prefix-1 that can be set NULL */
1054 unsigned get_n_nullable(ulint n_prefix) const
1055 {
1056 DBUG_ASSERT(n_prefix > 0);
1057 DBUG_ASSERT(n_prefix <= n_fields);
1058 unsigned n = n_nullable;
1059 for (; n_prefix < n_fields; n_prefix++) {
1060 const dict_col_t* col = fields[n_prefix].col;
1061 DBUG_ASSERT(!col->is_virtual());
1062 n -= col->is_nullable();
1063 }
1064 DBUG_ASSERT(n < n_def);
1065 return n;
1066 }
1067
1068 /** Get the default value of an instantly-added clustered index field.
1069 @param[in] n instantly added field position
1070 @param[out] len value length (in bytes), or UNIV_SQL_NULL
1071 @return default value
1072 @retval NULL if the default value is SQL NULL (len=UNIV_SQL_NULL) */
1073 const byte* instant_field_value(ulint n, ulint* len) const
1074 {
1075 DBUG_ASSERT(is_instant() || id == DICT_INDEXES_ID);
1076 DBUG_ASSERT(n + (id == DICT_INDEXES_ID) >= n_core_fields);
1077 DBUG_ASSERT(n < n_fields);
1078 return fields[n].col->instant_value(len);
1079 }
1080
1081 /** Adjust clustered index metadata for instant ADD COLUMN.
1082 @param[in] clustered index definition after instant ADD COLUMN */
1083 void instant_add_field(const dict_index_t& instant);
1084
1085 /** Remove the 'instant ADD' status of a clustered index.
1086 Protected by index root page x-latch or table X-lock. */
1087 void remove_instant()
1088 {
1089 DBUG_ASSERT(is_primary());
1090 if (!is_instant()) {
1091 return;
1092 }
1093 for (unsigned i = n_core_fields; i < n_fields; i++) {
1094 fields[i].col->remove_instant();
1095 }
1096 n_core_fields = n_fields;
1097 n_core_null_bytes = UT_BITS_IN_BYTES(unsigned(n_nullable));
1098 }
1099
1100 /** Check if record in clustered index is historical row.
1101 @param[in] rec clustered row
1102 @param[in] offsets offsets
1103 @return true if row is historical */
1104 bool
1105 vers_history_row(const rec_t* rec, const ulint* offsets);
1106
1107 /** Check if record in secondary index is historical row.
1108 @param[in] rec record in a secondary index
1109 @param[out] history_row true if row is historical
1110 @return true on error */
1111 bool
1112 vers_history_row(const rec_t* rec, bool &history_row);
1113};
1114
1115/** The status of online index creation */
1116enum online_index_status {
1117 /** the index is complete and ready for access */
1118 ONLINE_INDEX_COMPLETE = 0,
1119 /** the index is being created, online
1120 (allowing concurrent modifications) */
1121 ONLINE_INDEX_CREATION,
1122 /** secondary index creation was aborted and the index
1123 should be dropped as soon as index->table->n_ref_count reaches 0,
1124 or online table rebuild was aborted and the clustered index
1125 of the original table should soon be restored to
1126 ONLINE_INDEX_COMPLETE */
1127 ONLINE_INDEX_ABORTED,
1128 /** the online index creation was aborted, the index was
1129 dropped from the data dictionary and the tablespace, and it
1130 should be dropped from the data dictionary cache as soon as
1131 index->table->n_ref_count reaches 0. */
1132 ONLINE_INDEX_ABORTED_DROPPED
1133};
1134
1135/** Set to store the virtual columns which are affected by Foreign
1136key constraint. */
1137typedef std::set<dict_v_col_t*, std::less<dict_v_col_t*>,
1138 ut_allocator<dict_v_col_t*> > dict_vcol_set;
1139
1140/** Data structure for a foreign key constraint; an example:
1141FOREIGN KEY (A, B) REFERENCES TABLE2 (C, D). Most fields will be
1142initialized to 0, NULL or FALSE in dict_mem_foreign_create(). */
1143struct dict_foreign_t{
1144 mem_heap_t* heap; /*!< this object is allocated from
1145 this memory heap */
1146 char* id; /*!< id of the constraint as a
1147 null-terminated string */
1148 unsigned n_fields:10; /*!< number of indexes' first fields
1149 for which the foreign key
1150 constraint is defined: we allow the
1151 indexes to contain more fields than
1152 mentioned in the constraint, as long
1153 as the first fields are as mentioned */
1154 unsigned type:6; /*!< 0 or DICT_FOREIGN_ON_DELETE_CASCADE
1155 or DICT_FOREIGN_ON_DELETE_SET_NULL */
1156 char* foreign_table_name;/*!< foreign table name */
1157 char* foreign_table_name_lookup;
1158 /*!< foreign table name used for dict lookup */
1159 dict_table_t* foreign_table; /*!< table where the foreign key is */
1160 const char** foreign_col_names;/*!< names of the columns in the
1161 foreign key */
1162 char* referenced_table_name;/*!< referenced table name */
1163 char* referenced_table_name_lookup;
1164 /*!< referenced table name for dict lookup*/
1165 dict_table_t* referenced_table;/*!< table where the referenced key
1166 is */
1167 const char** referenced_col_names;/*!< names of the referenced
1168 columns in the referenced table */
1169 dict_index_t* foreign_index; /*!< foreign index; we require that
1170 both tables contain explicitly defined
1171 indexes for the constraint: InnoDB
1172 does not generate new indexes
1173 implicitly */
1174 dict_index_t* referenced_index;/*!< referenced index */
1175
1176 dict_vcol_set* v_cols; /*!< set of virtual columns affected
1177 by foreign key constraint. */
1178};
1179
1180std::ostream&
1181operator<< (std::ostream& out, const dict_foreign_t& foreign);
1182
1183struct dict_foreign_print {
1184
1185 dict_foreign_print(std::ostream& out)
1186 : m_out(out)
1187 {}
1188
1189 void operator()(const dict_foreign_t* foreign) {
1190 m_out << *foreign;
1191 }
1192private:
1193 std::ostream& m_out;
1194};
1195
1196/** Compare two dict_foreign_t objects using their ids. Used in the ordering
1197of dict_table_t::foreign_set and dict_table_t::referenced_set. It returns
1198true if the first argument is considered to go before the second in the
1199strict weak ordering it defines, and false otherwise. */
1200struct dict_foreign_compare {
1201
1202 bool operator()(
1203 const dict_foreign_t* lhs,
1204 const dict_foreign_t* rhs) const
1205 {
1206 return(ut_strcmp(lhs->id, rhs->id) < 0);
1207 }
1208};
1209
1210/** A function object to find a foreign key with the given index as the
1211referenced index. Return the foreign key with matching criteria or NULL */
1212struct dict_foreign_with_index {
1213
1214 dict_foreign_with_index(const dict_index_t* index)
1215 : m_index(index)
1216 {}
1217
1218 bool operator()(const dict_foreign_t* foreign) const
1219 {
1220 return(foreign->referenced_index == m_index);
1221 }
1222
1223 const dict_index_t* m_index;
1224};
1225
1226#ifdef WITH_WSREP
1227/** A function object to find a foreign key with the given index as the
1228foreign index. Return the foreign key with matching criteria or NULL */
1229struct dict_foreign_with_foreign_index {
1230
1231 dict_foreign_with_foreign_index(const dict_index_t* index)
1232 : m_index(index)
1233 {}
1234
1235 bool operator()(const dict_foreign_t* foreign) const
1236 {
1237 return(foreign->foreign_index == m_index);
1238 }
1239
1240 const dict_index_t* m_index;
1241};
1242#endif
1243
1244/* A function object to check if the foreign constraint is between different
1245tables. Returns true if foreign key constraint is between different tables,
1246false otherwise. */
1247struct dict_foreign_different_tables {
1248
1249 bool operator()(const dict_foreign_t* foreign) const
1250 {
1251 return(foreign->foreign_table != foreign->referenced_table);
1252 }
1253};
1254
1255/** A function object to check if the foreign key constraint has the same
1256name as given. If the full name of the foreign key constraint doesn't match,
1257then, check if removing the database name from the foreign key constraint
1258matches. Return true if it matches, false otherwise. */
1259struct dict_foreign_matches_id {
1260
1261 dict_foreign_matches_id(const char* id)
1262 : m_id(id)
1263 {}
1264
1265 bool operator()(const dict_foreign_t* foreign) const
1266 {
1267 if (0 == innobase_strcasecmp(foreign->id, m_id)) {
1268 return(true);
1269 }
1270 if (const char* pos = strchr(foreign->id, '/')) {
1271 if (0 == innobase_strcasecmp(m_id, pos + 1)) {
1272 return(true);
1273 }
1274 }
1275 return(false);
1276 }
1277
1278 const char* m_id;
1279};
1280
1281typedef std::set<
1282 dict_foreign_t*,
1283 dict_foreign_compare,
1284 ut_allocator<dict_foreign_t*> > dict_foreign_set;
1285
1286std::ostream&
1287operator<< (std::ostream& out, const dict_foreign_set& fk_set);
1288
1289/** Function object to check if a foreign key object is there
1290in the given foreign key set or not. It returns true if the
1291foreign key is not found, false otherwise */
1292struct dict_foreign_not_exists {
1293 dict_foreign_not_exists(const dict_foreign_set& obj_)
1294 : m_foreigns(obj_)
1295 {}
1296
1297 /* Return true if the given foreign key is not found */
1298 bool operator()(dict_foreign_t* const & foreign) const {
1299 return(m_foreigns.find(foreign) == m_foreigns.end());
1300 }
1301private:
1302 const dict_foreign_set& m_foreigns;
1303};
1304
1305/** Validate the search order in the foreign key set.
1306@param[in] fk_set the foreign key set to be validated
1307@return true if search order is fine in the set, false otherwise. */
1308bool
1309dict_foreign_set_validate(
1310 const dict_foreign_set& fk_set);
1311
1312/** Validate the search order in the foreign key sets of the table
1313(foreign_set and referenced_set).
1314@param[in] table table whose foreign key sets are to be validated
1315@return true if foreign key sets are fine, false otherwise. */
1316bool
1317dict_foreign_set_validate(
1318 const dict_table_t& table);
1319
1320/*********************************************************************//**
1321Frees a foreign key struct. */
1322inline
1323void
1324dict_foreign_free(
1325/*==============*/
1326 dict_foreign_t* foreign) /*!< in, own: foreign key struct */
1327{
1328 if (foreign->v_cols != NULL) {
1329 UT_DELETE(foreign->v_cols);
1330 }
1331
1332 mem_heap_free(foreign->heap);
1333}
1334
1335/** The destructor will free all the foreign key constraints in the set
1336by calling dict_foreign_free() on each of the foreign key constraints.
1337This is used to free the allocated memory when a local set goes out
1338of scope. */
1339struct dict_foreign_set_free {
1340
1341 dict_foreign_set_free(const dict_foreign_set& foreign_set)
1342 : m_foreign_set(foreign_set)
1343 {}
1344
1345 ~dict_foreign_set_free()
1346 {
1347 std::for_each(m_foreign_set.begin(),
1348 m_foreign_set.end(),
1349 dict_foreign_free);
1350 }
1351
1352 const dict_foreign_set& m_foreign_set;
1353};
1354
1355/** The flags for ON_UPDATE and ON_DELETE can be ORed; the default is that
1356a foreign key constraint is enforced, therefore RESTRICT just means no flag */
1357/* @{ */
1358#define DICT_FOREIGN_ON_DELETE_CASCADE 1U /*!< ON DELETE CASCADE */
1359#define DICT_FOREIGN_ON_DELETE_SET_NULL 2U /*!< ON UPDATE SET NULL */
1360#define DICT_FOREIGN_ON_UPDATE_CASCADE 4U /*!< ON DELETE CASCADE */
1361#define DICT_FOREIGN_ON_UPDATE_SET_NULL 8U /*!< ON UPDATE SET NULL */
1362#define DICT_FOREIGN_ON_DELETE_NO_ACTION 16U /*!< ON DELETE NO ACTION */
1363#define DICT_FOREIGN_ON_UPDATE_NO_ACTION 32U /*!< ON UPDATE NO ACTION */
1364/* @} */
1365
1366/** Display an identifier.
1367@param[in,out] s output stream
1368@param[in] id_name SQL identifier (other than table name)
1369@return the output stream */
1370std::ostream&
1371operator<<(
1372 std::ostream& s,
1373 const id_name_t& id_name);
1374
1375/** Display a table name.
1376@param[in,out] s output stream
1377@param[in] table_name table name
1378@return the output stream */
1379std::ostream&
1380operator<<(
1381 std::ostream& s,
1382 const table_name_t& table_name);
1383
1384/** List of locks that different transactions have acquired on a table. This
1385list has a list node that is embedded in a nested union/structure. We have to
1386generate a specific template for it. */
1387
1388typedef ut_list_base<lock_t, ut_list_node<lock_t> lock_table_t::*>
1389 table_lock_list_t;
1390
1391/** mysql template structure defined in row0mysql.cc */
1392struct mysql_row_templ_t;
1393
1394/** Structure defines template related to virtual columns and
1395their base columns */
1396struct dict_vcol_templ_t {
1397 /** number of regular columns */
1398 ulint n_col;
1399
1400 /** number of virtual columns */
1401 ulint n_v_col;
1402
1403 /** array of templates for virtual col and their base columns */
1404 mysql_row_templ_t** vtempl;
1405
1406 /** table's database name */
1407 std::string db_name;
1408
1409 /** table name */
1410 std::string tb_name;
1411
1412 /** MySQL record length */
1413 ulint rec_len;
1414
1415 /** default column value if any */
1416 byte* default_rec;
1417
1418 /** cached MySQL TABLE object */
1419 TABLE* mysql_table;
1420
1421 /** when mysql_table was cached */
1422 uint64_t mysql_table_query_id;
1423
1424 dict_vcol_templ_t() : vtempl(0), mysql_table_query_id(~0ULL) {}
1425};
1426
1427/** These are used when MySQL FRM and InnoDB data dictionary are
1428in inconsistent state. */
1429typedef enum {
1430 DICT_FRM_CONSISTENT = 0, /*!< Consistent state */
1431 DICT_FRM_NO_PK = 1, /*!< MySQL has no primary key
1432 but InnoDB dictionary has
1433 non-generated one. */
1434 DICT_NO_PK_FRM_HAS = 2, /*!< MySQL has primary key but
1435 InnoDB dictionary has not. */
1436 DICT_FRM_INCONSISTENT_KEYS = 3 /*!< Key count mismatch */
1437} dict_frm_t;
1438
1439/** Data structure for a database table. Most fields will be
1440initialized to 0, NULL or FALSE in dict_mem_table_create(). */
1441struct dict_table_t {
1442
1443 /** Get reference count.
1444 @return current value of n_ref_count */
1445 inline ulint get_ref_count() const;
1446
1447 /** Acquire the table handle. */
1448 inline void acquire();
1449
1450 /** Release the table handle.
1451 @return whether the last handle was released */
1452 inline bool release();
1453
1454 /** @return whether the table supports transactions */
1455 bool no_rollback() const
1456 {
1457 return !(~unsigned(flags) & DICT_TF_MASK_NO_ROLLBACK);
1458 }
1459 /** @return whether this is a temporary table */
1460 bool is_temporary() const
1461 {
1462 return flags2 & DICT_TF2_TEMPORARY;
1463 }
1464
1465 /** @return whether this table is readable
1466 @retval true normally
1467 @retval false if this is a single-table tablespace
1468 and the .ibd file is missing, or a
1469 page cannot be read or decrypted */
1470 bool is_readable() const
1471 {
1472 ut_ad(file_unreadable || space);
1473 return(UNIV_LIKELY(!file_unreadable));
1474 }
1475
1476 /** @return whether instant ADD COLUMN is in effect */
1477 bool is_instant() const
1478 {
1479 return(UT_LIST_GET_FIRST(indexes)->is_instant());
1480 }
1481
1482 /** @return whether the table supports instant ADD COLUMN */
1483 bool supports_instant() const
1484 {
1485 return(!(flags & DICT_TF_MASK_ZIP_SSIZE));
1486 }
1487
1488 /** Adjust metadata for instant ADD COLUMN.
1489 @param[in] table table definition after instant ADD COLUMN */
1490 void instant_add_column(const dict_table_t& table);
1491
1492 /** Roll back instant_add_column().
1493 @param[in] old_n_cols original n_cols
1494 @param[in] old_cols original cols
1495 @param[in] old_col_names original col_names */
1496 void rollback_instant(
1497 unsigned old_n_cols,
1498 dict_col_t* old_cols,
1499 const char* old_col_names);
1500
1501 /** Trim the instantly added columns when an insert into SYS_COLUMNS
1502 is rolled back during ALTER TABLE or recovery.
1503 @param[in] n number of surviving non-system columns */
1504 void rollback_instant(unsigned n);
1505
1506 /** Add the table definition to the data dictionary cache */
1507 void add_to_cache();
1508
1509 bool versioned() const { return vers_start || vers_end; }
1510 bool versioned_by_id() const
1511 {
1512 return vers_start && cols[vers_start].mtype == DATA_INT;
1513 }
1514
1515 void inc_fk_checks()
1516 {
1517#ifdef UNIV_DEBUG
1518 lint fk_checks= (lint)
1519#endif
1520 my_atomic_addlint(&n_foreign_key_checks_running, 1);
1521 ut_ad(fk_checks >= 0);
1522 }
1523 void dec_fk_checks()
1524 {
1525#ifdef UNIV_DEBUG
1526 lint fk_checks= (lint)
1527#endif
1528 my_atomic_addlint(&n_foreign_key_checks_running, ulint(-1));
1529 ut_ad(fk_checks > 0);
1530 }
1531
1532 /** Id of the table. */
1533 table_id_t id;
1534
1535 /** Memory heap. If you allocate from this heap after the table has
1536 been created then be sure to account the allocation into
1537 dict_sys->size. When closing the table we do something like
1538 dict_sys->size -= mem_heap_get_size(table->heap) and if that is going
1539 to become negative then we would assert. Something like this should do:
1540 old_size = mem_heap_get_size()
1541 mem_heap_alloc()
1542 new_size = mem_heap_get_size()
1543 dict_sys->size += new_size - old_size. */
1544 mem_heap_t* heap;
1545
1546 /** Table name. */
1547 table_name_t name;
1548
1549 /** NULL or the directory path specified by DATA DIRECTORY. */
1550 char* data_dir_path;
1551
1552 /** The tablespace of the table */
1553 fil_space_t* space;
1554 /** Tablespace ID */
1555 ulint space_id;
1556
1557 /** Stores information about:
1558 1 row format (redundant or compact),
1559 2 compressed page size (zip shift size),
1560 3 whether using atomic blobs,
1561 4 whether the table has been created with the option DATA DIRECTORY.
1562 Use DICT_TF_GET_COMPACT(), DICT_TF_GET_ZIP_SSIZE(),
1563 DICT_TF_HAS_ATOMIC_BLOBS() and DICT_TF_HAS_DATA_DIR() to parse this
1564 flag. */
1565 unsigned flags:DICT_TF_BITS;
1566
1567 /** Stores information about:
1568 1 whether the table has been created using CREATE TEMPORARY TABLE,
1569 2 whether the table has an internally defined DOC ID column,
1570 3 whether the table has a FTS index,
1571 4 whether DOC ID column need to be added to the FTS index,
1572 5 whether the table is being created its own tablespace,
1573 6 whether the table has been DISCARDed,
1574 7 whether the aux FTS tables names are in hex.
1575 Use DICT_TF2_FLAG_IS_SET() to parse this flag. */
1576 unsigned flags2:DICT_TF2_BITS;
1577
1578 /** TRUE if the table is an intermediate table during copy alter
1579 operation or a partition/subpartition which is required for copying
1580 data and skip the undo log for insertion of row in the table.
1581 This variable will be set and unset during extra(), or during the
1582 process of altering partitions */
1583 unsigned skip_alter_undo:1;
1584
1585 /*!< whether this is in a single-table tablespace and the .ibd
1586 file is missing or page decryption failed and page is corrupted */
1587 unsigned file_unreadable:1;
1588
1589 /** TRUE if the table object has been added to the dictionary cache. */
1590 unsigned cached:1;
1591
1592 /** TRUE if the table is to be dropped, but not yet actually dropped
1593 (could in the background drop list). It is turned on at the beginning
1594 of row_drop_table_for_mysql() and turned off just before we start to
1595 update system tables for the drop. It is protected by
1596 dict_operation_lock. */
1597 unsigned to_be_dropped:1;
1598
1599 /** Number of non-virtual columns defined so far. */
1600 unsigned n_def:10;
1601
1602 /** Number of non-virtual columns. */
1603 unsigned n_cols:10;
1604
1605 /** Number of total columns (inlcude virtual and non-virtual) */
1606 unsigned n_t_cols:10;
1607
1608 /** Number of total columns defined so far. */
1609 unsigned n_t_def:10;
1610
1611 /** Number of virtual columns defined so far. */
1612 unsigned n_v_def:10;
1613
1614 /** Number of virtual columns. */
1615 unsigned n_v_cols:10;
1616
1617 /** 1 + the position of autoinc counter field in clustered
1618 index, or 0 if there is no persistent AUTO_INCREMENT column in
1619 the table. */
1620 unsigned persistent_autoinc:10;
1621
1622 /** TRUE if it's not an InnoDB system table or a table that has no FK
1623 relationships. */
1624 unsigned can_be_evicted:1;
1625
1626 /** TRUE if table is corrupted. */
1627 unsigned corrupted:1;
1628
1629 /** TRUE if some indexes should be dropped after ONLINE_INDEX_ABORTED
1630 or ONLINE_INDEX_ABORTED_DROPPED. */
1631 unsigned drop_aborted:1;
1632
1633 /** Array of column descriptions. */
1634 dict_col_t* cols;
1635
1636 /** Array of virtual column descriptions. */
1637 dict_v_col_t* v_cols;
1638
1639 /** List of stored column descriptions. It is used only for foreign key
1640 check during create table and copy alter operations.
1641 During copy alter, s_cols list is filled during create table operation
1642 and need to preserve till rename table operation. That is the
1643 reason s_cols is a part of dict_table_t */
1644 dict_s_col_list* s_cols;
1645
1646 /** Column names packed in a character string
1647 "name1\0name2\0...nameN\0". Until the string contains n_cols, it will
1648 be allocated from a temporary heap. The final string will be allocated
1649 from table->heap. */
1650 const char* col_names;
1651
1652 /** Virtual column names */
1653 const char* v_col_names;
1654 unsigned vers_start:10;
1655 /*!< System Versioning: row start col index */
1656 unsigned vers_end:10;
1657 /*!< System Versioning: row end col index */
1658 bool is_system_db;
1659 /*!< True if the table belongs to a system
1660 database (mysql, information_schema or
1661 performance_schema) */
1662 dict_frm_t dict_frm_mismatch;
1663 /*!< !DICT_FRM_CONSISTENT==0 if data
1664 dictionary information and
1665 MySQL FRM information mismatch. */
1666 /** Hash chain node. */
1667 hash_node_t name_hash;
1668
1669 /** Hash chain node. */
1670 hash_node_t id_hash;
1671
1672 /** The FTS_DOC_ID_INDEX, or NULL if no fulltext indexes exist */
1673 dict_index_t* fts_doc_id_index;
1674
1675 /** List of indexes of the table. */
1676 UT_LIST_BASE_NODE_T(dict_index_t) indexes;
1677
1678 /** List of foreign key constraints in the table. These refer to
1679 columns in other tables. */
1680 UT_LIST_BASE_NODE_T(dict_foreign_t) foreign_list;
1681
1682 /** List of foreign key constraints which refer to this table. */
1683 UT_LIST_BASE_NODE_T(dict_foreign_t) referenced_list;
1684
1685 /** Node of the LRU list of tables. */
1686 UT_LIST_NODE_T(dict_table_t) table_LRU;
1687
1688 /** Maximum recursive level we support when loading tables chained
1689 together with FK constraints. If exceeds this level, we will stop
1690 loading child table into memory along with its parent table. */
1691 unsigned fk_max_recusive_level:8;
1692
1693 /** Count of how many foreign key check operations are currently being
1694 performed on the table. We cannot drop the table while there are
1695 foreign key checks running on it. */
1696 ulint n_foreign_key_checks_running;
1697
1698 /** Transactions whose view low limit is greater than this number are
1699 not allowed to store to the MySQL query cache or retrieve from it.
1700 When a trx with undo logs commits, it sets this to the value of the
1701 current time. */
1702 trx_id_t query_cache_inv_id;
1703
1704 /** Transaction id that last touched the table definition. Either when
1705 loading the definition or CREATE TABLE, or ALTER TABLE (prepare,
1706 commit, and rollback phases). */
1707 trx_id_t def_trx_id;
1708
1709 /*!< set of foreign key constraints in the table; these refer to
1710 columns in other tables */
1711 dict_foreign_set foreign_set;
1712
1713 /*!< set of foreign key constraints which refer to this table */
1714 dict_foreign_set referenced_set;
1715
1716 /** Statistics for query optimization. @{ */
1717
1718 /** Creation state of 'stats_latch'. */
1719 volatile os_once::state_t stats_latch_created;
1720
1721 /** This latch protects:
1722 dict_table_t::stat_initialized,
1723 dict_table_t::stat_n_rows (*),
1724 dict_table_t::stat_clustered_index_size,
1725 dict_table_t::stat_sum_of_other_index_sizes,
1726 dict_table_t::stat_modified_counter (*),
1727 dict_table_t::indexes*::stat_n_diff_key_vals[],
1728 dict_table_t::indexes*::stat_index_size,
1729 dict_table_t::indexes*::stat_n_leaf_pages.
1730 (*) Those are not always protected for
1731 performance reasons. */
1732 rw_lock_t* stats_latch;
1733
1734 /** TRUE if statistics have been calculated the first time after
1735 database startup or table creation. */
1736 unsigned stat_initialized:1;
1737
1738 /** Timestamp of last recalc of the stats. */
1739 ib_time_t stats_last_recalc;
1740
1741 /** The two bits below are set in the 'stat_persistent' member. They
1742 have the following meaning:
1743 1. _ON=0, _OFF=0, no explicit persistent stats setting for this table,
1744 the value of the global srv_stats_persistent is used to determine
1745 whether the table has persistent stats enabled or not
1746 2. _ON=0, _OFF=1, persistent stats are explicitly disabled for this
1747 table, regardless of the value of the global srv_stats_persistent
1748 3. _ON=1, _OFF=0, persistent stats are explicitly enabled for this
1749 table, regardless of the value of the global srv_stats_persistent
1750 4. _ON=1, _OFF=1, not allowed, we assert if this ever happens. */
1751 #define DICT_STATS_PERSISTENT_ON (1 << 1)
1752 #define DICT_STATS_PERSISTENT_OFF (1 << 2)
1753
1754 /** Indicates whether the table uses persistent stats or not. See
1755 DICT_STATS_PERSISTENT_ON and DICT_STATS_PERSISTENT_OFF. */
1756 ib_uint32_t stat_persistent;
1757
1758 /** The two bits below are set in the 'stats_auto_recalc' member. They
1759 have the following meaning:
1760 1. _ON=0, _OFF=0, no explicit auto recalc setting for this table, the
1761 value of the global srv_stats_persistent_auto_recalc is used to
1762 determine whether the table has auto recalc enabled or not
1763 2. _ON=0, _OFF=1, auto recalc is explicitly disabled for this table,
1764 regardless of the value of the global srv_stats_persistent_auto_recalc
1765 3. _ON=1, _OFF=0, auto recalc is explicitly enabled for this table,
1766 regardless of the value of the global srv_stats_persistent_auto_recalc
1767 4. _ON=1, _OFF=1, not allowed, we assert if this ever happens. */
1768 #define DICT_STATS_AUTO_RECALC_ON (1 << 1)
1769 #define DICT_STATS_AUTO_RECALC_OFF (1 << 2)
1770
1771 /** Indicates whether the table uses automatic recalc for persistent
1772 stats or not. See DICT_STATS_AUTO_RECALC_ON and
1773 DICT_STATS_AUTO_RECALC_OFF. */
1774 ib_uint32_t stats_auto_recalc;
1775
1776 /** The number of pages to sample for this table during persistent
1777 stats estimation. If this is 0, then the value of the global
1778 srv_stats_persistent_sample_pages will be used instead. */
1779 ulint stats_sample_pages;
1780
1781 /** Approximate number of rows in the table. We periodically calculate
1782 new estimates. */
1783 ib_uint64_t stat_n_rows;
1784
1785 /** Approximate clustered index size in database pages. */
1786 ulint stat_clustered_index_size;
1787
1788 /** Approximate size of other indexes in database pages. */
1789 ulint stat_sum_of_other_index_sizes;
1790
1791 /** How many rows are modified since last stats recalc. When a row is
1792 inserted, updated, or deleted, we add 1 to this number; we calculate
1793 new estimates for the table and the indexes if the table has changed
1794 too much, see dict_stats_update_if_needed(). The counter is reset
1795 to zero at statistics calculation. This counter is not protected by
1796 any latch, because this is only used for heuristics. */
1797 ib_uint64_t stat_modified_counter;
1798
1799 /** Background stats thread is not working on this table. */
1800 #define BG_STAT_NONE 0
1801
1802 /** Set in 'stats_bg_flag' when the background stats code is working
1803 on this table. The DROP TABLE code waits for this to be cleared before
1804 proceeding. */
1805 #define BG_STAT_IN_PROGRESS (1 << 0)
1806
1807 /** Set in 'stats_bg_flag' when DROP TABLE starts waiting on
1808 BG_STAT_IN_PROGRESS to be cleared. The background stats thread will
1809 detect this and will eventually quit sooner. */
1810 #define BG_STAT_SHOULD_QUIT (1 << 1)
1811
1812 /** The state of the background stats thread wrt this table.
1813 See BG_STAT_NONE, BG_STAT_IN_PROGRESS and BG_STAT_SHOULD_QUIT.
1814 Writes are covered by dict_sys->mutex. Dirty reads are possible. */
1815
1816 #define BG_SCRUB_IN_PROGRESS ((byte)(1 << 2))
1817 /*!< BG_SCRUB_IN_PROGRESS is set in
1818 stats_bg_flag when the background
1819 scrub code is working on this table. The DROP
1820 TABLE code waits for this to be cleared
1821 before proceeding. */
1822
1823 #define BG_STAT_SHOULD_QUIT (1 << 1)
1824
1825 #define BG_IN_PROGRESS (BG_STAT_IN_PROGRESS | BG_SCRUB_IN_PROGRESS)
1826
1827
1828 /** The state of the background stats thread wrt this table.
1829 See BG_STAT_NONE, BG_STAT_IN_PROGRESS and BG_STAT_SHOULD_QUIT.
1830 Writes are covered by dict_sys->mutex. Dirty reads are possible. */
1831 byte stats_bg_flag;
1832
1833 bool stats_error_printed;
1834 /*!< Has persistent stats error beein
1835 already printed for this table ? */
1836 /* @} */
1837
1838 /** AUTOINC related members. @{ */
1839
1840 /* The actual collection of tables locked during AUTOINC read/write is
1841 kept in trx_t. In order to quickly determine whether a transaction has
1842 locked the AUTOINC lock we keep a pointer to the transaction here in
1843 the 'autoinc_trx' member. This is to avoid acquiring the
1844 lock_sys_t::mutex and scanning the vector in trx_t.
1845 When an AUTOINC lock has to wait, the corresponding lock instance is
1846 created on the trx lock heap rather than use the pre-allocated instance
1847 in autoinc_lock below. */
1848
1849 /** A buffer for an AUTOINC lock for this table. We allocate the
1850 memory here so that individual transactions can get it and release it
1851 without a need to allocate space from the lock heap of the trx:
1852 otherwise the lock heap would grow rapidly if we do a large insert
1853 from a select. */
1854 lock_t* autoinc_lock;
1855
1856 /** Creation state of autoinc_mutex member */
1857 volatile os_once::state_t autoinc_mutex_created;
1858
1859 /** Mutex protecting the autoincrement counter. */
1860 ib_mutex_t* autoinc_mutex;
1861
1862 /** Autoinc counter value to give to the next inserted row. */
1863 ib_uint64_t autoinc;
1864
1865 /** This counter is used to track the number of granted and pending
1866 autoinc locks on this table. This value is set after acquiring the
1867 lock_sys_t::mutex but we peek the contents to determine whether other
1868 transactions have acquired the AUTOINC lock or not. Of course only one
1869 transaction can be granted the lock but there can be multiple
1870 waiters. */
1871 ulong n_waiting_or_granted_auto_inc_locks;
1872
1873 /** The transaction that currently holds the the AUTOINC lock on this
1874 table. Protected by lock_sys.mutex. */
1875 const trx_t* autoinc_trx;
1876
1877 /* @} */
1878
1879 /** FTS specific state variables. */
1880 fts_t* fts;
1881
1882 /** Quiescing states, protected by the dict_index_t::lock. ie. we can
1883 only change the state if we acquire all the latches (dict_index_t::lock)
1884 in X mode of this table's indexes. */
1885 ib_quiesce_t quiesce;
1886
1887 /** Count of the number of record locks on this table. We use this to
1888 determine whether we can evict the table from the dictionary cache.
1889 It is protected by lock_sys.mutex. */
1890 ulint n_rec_locks;
1891
1892#ifndef DBUG_ASSERT_EXISTS
1893private:
1894#endif
1895 /** Count of how many handles are opened to this table. Dropping of the
1896 table is NOT allowed until this count gets to zero. MySQL does NOT
1897 itself check the number of open handles at DROP. */
1898 ulint n_ref_count;
1899
1900public:
1901 /** List of locks on the table. Protected by lock_sys.mutex. */
1902 table_lock_list_t locks;
1903
1904 /** Timestamp of the last modification of this table. */
1905 time_t update_time;
1906
1907#ifdef UNIV_DEBUG
1908 /** Value of 'magic_n'. */
1909 #define DICT_TABLE_MAGIC_N 76333786
1910
1911 /** Magic number. */
1912 ulint magic_n;
1913#endif /* UNIV_DEBUG */
1914 /** mysql_row_templ_t for base columns used for compute the virtual
1915 columns */
1916 dict_vcol_templ_t* vc_templ;
1917};
1918
1919inline void dict_index_t::set_modified(mtr_t& mtr) const
1920{
1921 mtr.set_named_space(table->space);
1922}
1923
1924inline bool dict_index_t::is_readable() const { return table->is_readable(); }
1925
1926inline bool dict_index_t::is_instant() const
1927{
1928 ut_ad(n_core_fields > 0);
1929 ut_ad(n_core_fields <= n_fields);
1930 ut_ad(n_core_fields == n_fields
1931 || (type & ~(DICT_UNIQUE | DICT_CORRUPT)) == DICT_CLUSTERED);
1932 ut_ad(n_core_fields == n_fields || table->supports_instant());
1933 ut_ad(n_core_fields == n_fields || !table->is_temporary());
1934 return(n_core_fields != n_fields);
1935}
1936
1937inline bool dict_index_t::is_corrupted() const
1938{
1939 return UNIV_UNLIKELY(online_status >= ONLINE_INDEX_ABORTED
1940 || (type & DICT_CORRUPT)
1941 || (table && table->corrupted));
1942}
1943
1944/*******************************************************************//**
1945Initialise the table lock list. */
1946void
1947lock_table_lock_list_init(
1948/*======================*/
1949 table_lock_list_t* locks); /*!< List to initialise */
1950
1951/** A function object to add the foreign key constraint to the referenced set
1952of the referenced table, if it exists in the dictionary cache. */
1953struct dict_foreign_add_to_referenced_table {
1954 void operator()(dict_foreign_t* foreign) const
1955 {
1956 if (dict_table_t* table = foreign->referenced_table) {
1957 std::pair<dict_foreign_set::iterator, bool> ret
1958 = table->referenced_set.insert(foreign);
1959 ut_a(ret.second);
1960 }
1961 }
1962};
1963
1964/** Destroy the autoinc latch of the given table.
1965This function is only called from either single threaded environment
1966or from a thread that has not shared the table object with other threads.
1967@param[in,out] table table whose stats latch to destroy */
1968inline
1969void
1970dict_table_autoinc_destroy(
1971 dict_table_t* table)
1972{
1973 if (table->autoinc_mutex_created == os_once::DONE
1974 && table->autoinc_mutex != NULL) {
1975 mutex_free(table->autoinc_mutex);
1976 UT_DELETE(table->autoinc_mutex);
1977 }
1978}
1979
1980/** Request for lazy creation of the autoinc latch of a given table.
1981This function is only called from either single threaded environment
1982or from a thread that has not shared the table object with other threads.
1983@param[in,out] table table whose autoinc latch is to be created. */
1984inline
1985void
1986dict_table_autoinc_create_lazy(
1987 dict_table_t* table)
1988{
1989 table->autoinc_mutex = NULL;
1990 table->autoinc_mutex_created = os_once::NEVER_DONE;
1991}
1992
1993/** Request a lazy creation of dict_index_t::zip_pad::mutex.
1994This function is only called from either single threaded environment
1995or from a thread that has not shared the table object with other threads.
1996@param[in,out] index index whose zip_pad mutex is to be created */
1997inline
1998void
1999dict_index_zip_pad_mutex_create_lazy(
2000 dict_index_t* index)
2001{
2002 index->zip_pad.mutex = NULL;
2003 index->zip_pad.mutex_created = os_once::NEVER_DONE;
2004}
2005
2006/** Destroy the zip_pad_mutex of the given index.
2007This function is only called from either single threaded environment
2008or from a thread that has not shared the table object with other threads.
2009@param[in,out] table table whose stats latch to destroy */
2010inline
2011void
2012dict_index_zip_pad_mutex_destroy(
2013 dict_index_t* index)
2014{
2015 if (index->zip_pad.mutex_created == os_once::DONE
2016 && index->zip_pad.mutex != NULL) {
2017 mutex_free(index->zip_pad.mutex);
2018 UT_DELETE(index->zip_pad.mutex);
2019 }
2020}
2021
2022/** Release the zip_pad_mutex of a given index.
2023@param[in,out] index index whose zip_pad_mutex is to be released */
2024inline
2025void
2026dict_index_zip_pad_unlock(
2027 dict_index_t* index)
2028{
2029 mutex_exit(index->zip_pad.mutex);
2030}
2031
2032#ifdef UNIV_DEBUG
2033/** Check if the current thread owns the autoinc_mutex of a given table.
2034@param[in] table the autoinc_mutex belongs to this table
2035@return true, if the current thread owns the autoinc_mutex, false otherwise.*/
2036inline
2037bool
2038dict_table_autoinc_own(
2039 const dict_table_t* table)
2040{
2041 return(mutex_own(table->autoinc_mutex));
2042}
2043#endif /* UNIV_DEBUG */
2044
2045/** Check whether the col is used in spatial index or regular index.
2046@param[in] col column to check
2047@return spatial status */
2048inline
2049spatial_status_t
2050dict_col_get_spatial_status(
2051 const dict_col_t* col)
2052{
2053 spatial_status_t spatial_status = SPATIAL_NONE;
2054
2055 /* Column is not a part of any index. */
2056 if (!col->ord_part) {
2057 return(spatial_status);
2058 }
2059
2060 if (DATA_GEOMETRY_MTYPE(col->mtype)) {
2061 if (col->max_prefix == 0) {
2062 spatial_status = SPATIAL_ONLY;
2063 } else {
2064 /* Any regular index on a geometry column
2065 should have a prefix. */
2066 spatial_status = SPATIAL_MIXED;
2067 }
2068 }
2069
2070 return(spatial_status);
2071}
2072
2073/** Clear defragmentation summary. */
2074inline void dict_stats_empty_defrag_summary(dict_index_t* index)
2075{
2076 index->stat_defrag_n_pages_freed = 0;
2077}
2078
2079/** Clear defragmentation related index stats. */
2080inline void dict_stats_empty_defrag_stats(dict_index_t* index)
2081{
2082 index->stat_defrag_modified_counter = 0;
2083 index->stat_defrag_n_page_split = 0;
2084}
2085
2086#include "dict0mem.ic"
2087
2088#endif /* dict0mem_h */
2089