1 /*****************************************************************************
2 
3 Copyright (c) 1996, 2020, Oracle and/or its affiliates. All Rights Reserved.
4 Copyright (c) 2012, Facebook Inc.
5 
6 This program is free software; you can redistribute it and/or modify it under
7 the terms of the GNU General Public License, version 2.0, as published by the
8 Free Software Foundation.
9 
10 This program is also distributed with certain software (including but not
11 limited to OpenSSL) that is licensed under separate terms, as designated in a
12 particular file or component or in included license documentation. The authors
13 of MySQL hereby grant you an additional permission to link the program and
14 your derivative works with the separately licensed software that they have
15 included with MySQL.
16 
17 This program is distributed in the hope that it will be useful, but WITHOUT
18 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
19 FOR A PARTICULAR PURPOSE. See the GNU General Public License, version 2.0,
20 for more details.
21 
22 You should have received a copy of the GNU General Public License along with
23 this program; if not, write to the Free Software Foundation, Inc.,
24 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
25 
26 *****************************************************************************/
27 
28 /** @file include/dict0mem.h
29  Data dictionary memory object creation
30 
31  Created 1/8/1996 Heikki Tuuri
32  *******************************************************/
33 
34 #ifndef dict0mem_h
35 #define dict0mem_h
36 
37 #include "sql/dd/object_id.h"
38 #include "sql/dd/types/column.h"
39 #include "univ.i"
40 #ifdef UNIV_HOTBACKUP
41 #include "sql/dd/types/spatial_reference_system.h"
42 #endif /* UNIV_HOTBACKUP */
43 #include "btr0types.h"
44 #include "data0type.h"
45 #include "dict0types.h"
46 #include "mem0mem.h"
47 #include "rem0types.h"
48 #include "row0types.h"
49 #ifndef UNIV_HOTBACKUP
50 #include "lock0types.h"
51 #include "que0types.h"
52 #endif /* !UNIV_HOTBACKUP */
53 #include "hash0hash.h"
54 #include "sync0rw.h"
55 #include "trx0types.h"
56 #include "ut0byte.h"
57 #include "ut0mem.h"
58 #include "ut0rnd.h"
59 #ifndef UNIV_HOTBACKUP
60 #include "fts0fts.h"
61 #endif /* !UNIV_HOTBACKUP */
62 #include "buf0buf.h"
63 #include "gis0type.h"
64 #ifndef UNIV_HOTBACKUP
65 #include "os0once.h"
66 #endif /* !UNIV_HOTBACKUP */
67 #include "dict/mem.h"
68 #include "ut0new.h"
69 
70 #include "sql/sql_const.h" /* MAX_KEY_LENGTH */
71 
72 #include <algorithm>
73 #include <iterator>
74 #include <memory> /* std::unique_ptr */
75 #include <set>
76 #include <string>
77 #include <vector>
78 
79 /* Forward declaration. */
80 struct ib_rbt_t;
81 
82 /** Type flags of an index: OR'ing of the flags is allowed to define a
83 combination of types */
84 /* @{ */
85 #define DICT_CLUSTERED                                     \
86   1                   /*!< clustered index; for other than \
87                       auto-generated clustered indexes,    \
88                       also DICT_UNIQUE will be set */
89 #define DICT_UNIQUE 2 /*!< unique index */
90 #define DICT_IBUF 8   /*!< insert buffer tree */
91 #define DICT_CORRUPT                      \
92   16 /*!< bit to store the corrupted flag \
93      in SYS_INDEXES.TYPE */
94 #define DICT_FTS                              \
95   32 /* FTS index; can't be combined with the \
96      other flags */
97 #define DICT_SPATIAL                                                  \
98   64                     /* SPATIAL index; can't be combined with the \
99                          other flags */
100 #define DICT_VIRTUAL 128 /* Index on Virtual column */
101 
102 #define DICT_SDI                                                         \
103   256                        /* Tablespace dictionary Index. Set only in \
104                              in-memory index structure. */
105 #define DICT_MULTI_VALUE 512 /* Multi-value index */
106 
107 #define DICT_IT_BITS              \
108   10 /*!< number of bits used for \
109      SYS_INDEXES.TYPE */
110 /* @} */
111 
112 #if 0                         /* not implemented, retained for history */
113 /** Types for a table object */
114 #define DICT_TABLE_ORDINARY 1 /*!< ordinary table */
115 #define DICT_TABLE_CLUSTER_MEMBER 2
116 #define DICT_TABLE_CLUSTER          \
117   3 /* this means that the table is \
118     really a cluster definition */
119 #endif
120 
121 /* Table and tablespace flags are generally not used for the Antelope file
122 format except for the low order bit, which is used differently depending on
123 where the flags are stored.
124 
125 ==================== Low order flags bit =========================
126                     | REDUNDANT | COMPACT | COMPRESSED and DYNAMIC
127 SYS_TABLES.TYPE     |     1     |    1    |     1
128 dict_table_t::flags |     0     |    1    |     1
129 FSP_SPACE_FLAGS     |     0     |    0    |     1
130 fil_space_t::flags  |     0     |    0    |     1
131 
132 Before the 5.1 plugin, SYS_TABLES.TYPE was always DICT_TABLE_ORDINARY (1)
133 and the tablespace flags field was always 0. In the 5.1 plugin, these fields
134 were repurposed to identify compressed and dynamic row formats.
135 
136 The following types and constants describe the flags found in dict_table_t
137 and SYS_TABLES.TYPE.  Similar flags found in fil_space_t and FSP_SPACE_FLAGS
138 are described in fsp0fsp.h. */
139 
140 /* @{ */
141 /** dict_table_t::flags bit 0 is equal to 0 if the row format = Redundant */
142 #define DICT_TF_REDUNDANT 0 /*!< Redundant row format. */
143 /** dict_table_t::flags bit 0 is equal to 1 if the row format = Compact */
144 #define DICT_TF_COMPACT 1 /*!< Compact row format. */
145 
146 /** This bitmask is used in SYS_TABLES.N_COLS to set and test whether
147 the Compact page format is used, i.e ROW_FORMAT != REDUNDANT */
148 #define DICT_N_COLS_COMPACT 0x80000000UL
149 
150 /** Width of the COMPACT flag */
151 #define DICT_TF_WIDTH_COMPACT 1
152 
153 /** Width of the ZIP_SSIZE flag */
154 #define DICT_TF_WIDTH_ZIP_SSIZE 4
155 
156 /** Width of the ATOMIC_BLOBS flag.  The ROW_FORMAT=REDUNDANT and
157 ROW_FORMAT=COMPACT broke up BLOB and TEXT fields, storing the first 768 bytes
158 in the clustered index. ROW_FORMAT=DYNAMIC and ROW_FORMAT=COMPRESSED
159 store the whole blob or text field off-page atomically.
160 Secondary indexes are created from this external data using row_ext_t
161 to cache the BLOB prefixes. */
162 #define DICT_TF_WIDTH_ATOMIC_BLOBS 1
163 
164 /** If a table is created with the MYSQL option DATA DIRECTORY and
165 innodb-file-per-table, an older engine will not be able to find that table.
166 This flag prevents older engines from attempting to open the table and
167 allows InnoDB to update_create_info() accordingly. */
168 #define DICT_TF_WIDTH_DATA_DIR 1
169 
170 /** Width of the SHARED tablespace flag.
171 It is used to identify tables that exist inside a shared general tablespace.
172 If a table is created with the TABLESPACE=tsname option, an older engine will
173 not be able to find that table. This flag prevents older engines from attempting
174 to open the table and allows InnoDB to quickly find the tablespace. */
175 
176 #define DICT_TF_WIDTH_SHARED_SPACE 1
177 
178 /** Width of all the currently known table flags */
179 #define DICT_TF_BITS                                     \
180   (DICT_TF_WIDTH_COMPACT + DICT_TF_WIDTH_ZIP_SSIZE +     \
181    DICT_TF_WIDTH_ATOMIC_BLOBS + DICT_TF_WIDTH_DATA_DIR + \
182    DICT_TF_WIDTH_SHARED_SPACE)
183 
184 /** A mask of all the known/used bits in table flags */
185 #define DICT_TF_BIT_MASK (~(~0 << DICT_TF_BITS))
186 
187 /** Zero relative shift position of the COMPACT field */
188 #define DICT_TF_POS_COMPACT 0
189 /** Zero relative shift position of the ZIP_SSIZE field */
190 #define DICT_TF_POS_ZIP_SSIZE (DICT_TF_POS_COMPACT + DICT_TF_WIDTH_COMPACT)
191 /** Zero relative shift position of the ATOMIC_BLOBS field */
192 #define DICT_TF_POS_ATOMIC_BLOBS \
193   (DICT_TF_POS_ZIP_SSIZE + DICT_TF_WIDTH_ZIP_SSIZE)
194 /** Zero relative shift position of the DATA_DIR field */
195 #define DICT_TF_POS_DATA_DIR \
196   (DICT_TF_POS_ATOMIC_BLOBS + DICT_TF_WIDTH_ATOMIC_BLOBS)
197 /** Zero relative shift position of the SHARED TABLESPACE field */
198 #define DICT_TF_POS_SHARED_SPACE (DICT_TF_POS_DATA_DIR + DICT_TF_WIDTH_DATA_DIR)
199 /** Zero relative shift position of the start of the UNUSED bits */
200 #define DICT_TF_POS_UNUSED \
201   (DICT_TF_POS_SHARED_SPACE + DICT_TF_WIDTH_SHARED_SPACE)
202 
203 /** Bit mask of the COMPACT field */
204 #define DICT_TF_MASK_COMPACT \
205   ((~(~0U << DICT_TF_WIDTH_COMPACT)) << DICT_TF_POS_COMPACT)
206 /** Bit mask of the ZIP_SSIZE field */
207 #define DICT_TF_MASK_ZIP_SSIZE \
208   ((~(~0U << DICT_TF_WIDTH_ZIP_SSIZE)) << DICT_TF_POS_ZIP_SSIZE)
209 /** Bit mask of the ATOMIC_BLOBS field */
210 #define DICT_TF_MASK_ATOMIC_BLOBS \
211   ((~(~0U << DICT_TF_WIDTH_ATOMIC_BLOBS)) << DICT_TF_POS_ATOMIC_BLOBS)
212 /** Bit mask of the DATA_DIR field */
213 #define DICT_TF_MASK_DATA_DIR \
214   ((~(~0U << DICT_TF_WIDTH_DATA_DIR)) << DICT_TF_POS_DATA_DIR)
215 /** Bit mask of the SHARED_SPACE field */
216 #define DICT_TF_MASK_SHARED_SPACE \
217   ((~(~0U << DICT_TF_WIDTH_SHARED_SPACE)) << DICT_TF_POS_SHARED_SPACE)
218 
219 /** Return the value of the COMPACT field */
220 #define DICT_TF_GET_COMPACT(flags) \
221   ((flags & DICT_TF_MASK_COMPACT) >> DICT_TF_POS_COMPACT)
222 /** Return the value of the ZIP_SSIZE field */
223 #define DICT_TF_GET_ZIP_SSIZE(flags) \
224   ((flags & DICT_TF_MASK_ZIP_SSIZE) >> DICT_TF_POS_ZIP_SSIZE)
225 /** Return the value of the ATOMIC_BLOBS field */
226 #define DICT_TF_HAS_ATOMIC_BLOBS(flags) \
227   ((flags & DICT_TF_MASK_ATOMIC_BLOBS) >> DICT_TF_POS_ATOMIC_BLOBS)
228 /** Return the value of the DATA_DIR field */
229 #define DICT_TF_HAS_DATA_DIR(flags) \
230   ((flags & DICT_TF_MASK_DATA_DIR) >> DICT_TF_POS_DATA_DIR)
231 /** Return the value of the SHARED_SPACE field */
232 #define DICT_TF_HAS_SHARED_SPACE(flags) \
233   ((flags & DICT_TF_MASK_SHARED_SPACE) >> DICT_TF_POS_SHARED_SPACE)
234 /** Return the contents of the UNUSED bits */
235 #define DICT_TF_GET_UNUSED(flags) (flags >> DICT_TF_POS_UNUSED)
236 /* @} */
237 
238 /** @brief Table Flags set number 2.
239 
240 These flags will be stored in SYS_TABLES.MIX_LEN.  All unused flags
241 will be written as 0.  The column may contain garbage for tables
242 created with old versions of InnoDB that only implemented
243 ROW_FORMAT=REDUNDANT.  InnoDB engines do not check these flags
244 for unknown bits in order to protect backward incompatibility. */
245 /* @{ */
246 /** Total number of bits in table->flags2. */
247 #define DICT_TF2_BITS 11
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 1
253 
254 /** The table has an internal defined DOC ID column */
255 #define DICT_TF2_FTS_HAS_DOC_ID 2
256 
257 /** The table has an FTS index */
258 #define DICT_TF2_FTS 4
259 
260 /** Need to add Doc ID column for FTS index build.
261 This is a transient bit for index build */
262 #define DICT_TF2_FTS_ADD_DOC_ID 8
263 
264 /** This bit is used during table creation to indicate that it will
265 use its own tablespace instead of the system tablespace. */
266 #define DICT_TF2_USE_FILE_PER_TABLE 16
267 
268 /** Set when we discard/detach the tablespace */
269 #define DICT_TF2_DISCARDED 32
270 
271 /** Intrinsic table bit
272 Intrinsic table is table created internally by MySQL modules viz. Optimizer,
273 FTS, etc.... Intrinsic table has all the properties of the normal table except
274 it is not created by user and so not visible to end-user. */
275 #define DICT_TF2_INTRINSIC 128
276 
277 /** Encryption table bit for innodb_file-per-table only. */
278 #define DICT_TF2_ENCRYPTION_FILE_PER_TABLE 256
279 
280 /** FTS AUX hidden table bit. */
281 #define DICT_TF2_AUX 512
282 
283 /** Table is opened by resurrected trx during crash recovery. */
284 #define DICT_TF2_RESURRECT_PREPARED 1024
285 /* @} */
286 
287 #define DICT_TF2_FLAG_SET(table, flag) (table->flags2 |= (flag))
288 
289 #define DICT_TF2_FLAG_IS_SET(table, flag) (table->flags2 & (flag))
290 
291 #define DICT_TF2_FLAG_UNSET(table, flag) (table->flags2 &= ~(flag))
292 
293 /** Tables could be chained together with Foreign key constraint. When
294 first load the parent table, we would load all of its descedents.
295 This could result in rescursive calls and out of stack error eventually.
296 DICT_FK_MAX_RECURSIVE_LOAD defines the maximum number of recursive loads,
297 when exceeded, the child table will not be loaded. It will be loaded when
298 the foreign constraint check needs to be run. */
299 #define DICT_FK_MAX_RECURSIVE_LOAD 20
300 
301 /** Similarly, when tables are chained together with foreign key constraints
302 with on cascading delete/update clause, delete from parent table could
303 result in recursive cascading calls. This defines the maximum number of
304 such cascading deletes/updates allowed. When exceeded, the delete from
305 parent table will fail, and user has to drop excessive foreign constraint
306 before proceeds. */
307 #define FK_MAX_CASCADE_DEL 15
308 
309 /** Adds a virtual column definition to a table.
310 @param[in,out]	table		table
311 @param[in]	heap		temporary memory heap, or NULL. It is
312                                 used to store name when we have not finished
313                                 adding all columns. When all columns are
314                                 added, the whole name will copy to memory from
315                                 table->heap
316 @param[in]	name		column name
317 @param[in]	mtype		main datatype
318 @param[in]	prtype		precise type
319 @param[in]	len		length
320 @param[in]	pos		position in a table
321 @param[in]	num_base	number of base columns
322 @param[in]	is_visible	True if virtual column is visible to user
323 @return the virtual column definition */
324 dict_v_col_t *dict_mem_table_add_v_col(dict_table_t *table, mem_heap_t *heap,
325                                        const char *name, ulint mtype,
326                                        ulint prtype, ulint len, ulint pos,
327                                        ulint num_base, bool is_visible);
328 
329 /** Adds a stored column definition to a table.
330 @param[in,out]	table		table
331 @param[in]	num_base	number of base columns. */
332 void dict_mem_table_add_s_col(dict_table_t *table, ulint num_base);
333 
334 /** Renames a column of a table in the data dictionary cache. */
335 void dict_mem_table_col_rename(dict_table_t *table, /*!< in/out: table */
336                                ulint nth_col,       /*!< in: column index */
337                                const char *from,    /*!< in: old column name */
338                                const char *to,      /*!< in: new column name */
339                                bool is_virtual);
340 /*!< in: if this is a virtual column */
341 
342 /** This function poplulates a dict_index_t index memory structure with
343 supplied information.
344 @param[out]	index		index to be filled
345 @param[in]	heap		memory heap
346 @param[in]	table_name	table name
347 @param[in]	index_name	index name
348 @param[in]	space		space where the index tree is placed, the
349                                 clustered type ignored if the index is of the
350                                 clustered type
351 @param[in]	type		DICT_UNIQUE, DICT_CLUSTERED, ... ORed
352 @param[in]	n_fields	number of fields */
353 UNIV_INLINE
354 void dict_mem_fill_index_struct(dict_index_t *index, mem_heap_t *heap,
355                                 const char *table_name, const char *index_name,
356                                 ulint space, ulint type, ulint n_fields);
357 
358 /** Frees an index memory object. */
359 void dict_mem_index_free(dict_index_t *index); /*!< in: index */
360 /** Creates and initializes a foreign constraint memory object.
361  @return own: foreign constraint struct */
362 dict_foreign_t *dict_mem_foreign_create(void);
363 
364 /** Sets the foreign_table_name_lookup pointer based on the value of
365  lower_case_table_names.  If that is 0 or 1, foreign_table_name_lookup
366  will point to foreign_table_name.  If 2, then another string is
367  allocated from the heap and set to lower case. */
368 void dict_mem_foreign_table_name_lookup_set(
369     dict_foreign_t *foreign, /*!< in/out: foreign struct */
370     ibool do_alloc);         /*!< in: is an alloc needed */
371 
372 /** Sets the referenced_table_name_lookup pointer based on the value of
373  lower_case_table_names.  If that is 0 or 1, referenced_table_name_lookup
374  will point to referenced_table_name.  If 2, then another string is
375  allocated from the heap and set to lower case. */
376 void dict_mem_referenced_table_name_lookup_set(
377     dict_foreign_t *foreign, /*!< in/out: foreign struct */
378     ibool do_alloc);         /*!< in: is an alloc needed */
379 
380 /** Fills the dependent virtual columns in a set.
381 Reason for being dependent are
382 1) FK can be present on base column of virtual columns
383 2) FK can be present on column which is a part of virtual index
384 @param[in,out]	foreign	foreign key information. */
385 void dict_mem_foreign_fill_vcol_set(dict_foreign_t *foreign);
386 
387 /** Fill virtual columns set in each fk constraint present in the table.
388 @param[in,out]	table	innodb table object. */
389 void dict_mem_table_fill_foreign_vcol_set(dict_table_t *table);
390 
391 /** Free the vcol_set from all foreign key constraint on the table.
392 @param[in,out]	table	innodb table object. */
393 void dict_mem_table_free_foreign_vcol_set(dict_table_t *table);
394 
395 /** Create a temporary tablename like "#sql-ibtid-inc" where
396   tid = the Table ID
397   inc = a randomly initialized number that is incremented for each file
398 The table ID is a 64 bit integer, can use up to 20 digits, and is
399 initialized at bootstrap. The second number is 32 bits, can use up to 10
400 digits, and is initialized at startup to a randomly distributed number.
401 It is hoped that the combination of these two numbers will provide a
402 reasonably unique temporary file name.
403 @param[in]	heap	A memory heap
404 @param[in]	dbtab	Table name in the form database/table name
405 @param[in]	id	Table id
406 @return A unique temporary tablename suitable for InnoDB use */
407 char *dict_mem_create_temporary_tablename(mem_heap_t *heap, const char *dbtab,
408                                           table_id_t id);
409 
410 /** Initialize dict memory variables */
411 void dict_mem_init(void);
412 
413 /** SQL identifier name wrapper for pretty-printing */
414 class id_name_t {
415  public:
416   /** Default constructor */
id_name_t()417   id_name_t() : m_name() {}
418   /** Constructor
419   @param[in]	name	identifier to assign */
id_name_t(const char * name)420   explicit id_name_t(const char *name) : m_name(name) {}
421 
422   /** Assignment operator
423   @param[in]	name	identifier to assign */
424   id_name_t &operator=(const char *name) {
425     m_name = name;
426     return (*this);
427   }
428 
429   /** Implicit type conversion
430   @return the name */
431   operator const char *() const { return (m_name); }
432 
433   /** Explicit type conversion
434   @return the name */
operator()435   const char *operator()() const { return (m_name); }
436 
437  private:
438   /** The name in internal representation */
439   const char *m_name;
440 };
441 
442 /** Table name wrapper for pretty-printing */
443 struct table_name_t {
444   /** The name in internal representation */
445   char *m_name;
446 };
447 
448 /** Data structure for default value of a column in a table */
449 struct dict_col_default_t {
450   /** Pointer to the column itself */
451   dict_col_t *col;
452   /** Default value in bytes */
453   byte *value;
454   /** Length of default value */
455   size_t len;
456 
457   bool operator==(const dict_col_default_t &other);
458   bool operator!=(const dict_col_default_t &other);
459 };
460 
461 /** Data structure for a column in a table */
462 struct dict_col_t {
463   /*----------------------*/
464   /** The following are copied from dtype_t,
465   so that all bit-fields can be packed tightly. */
466   /* @{ */
467 
468   /** Default value when this column was added instantly.
469   If this is not a instantly added column then this is nullptr. */
470   dict_col_default_t *instant_default;
471 
472   unsigned prtype : 32; /*!< precise type; MySQL data
473                         type, charset code, flags to
474                         indicate nullability,
475                         signedness, whether this is a
476                         binary string, whether this is
477                         a true VARCHAR where MySQL
478                         uses 2 bytes to store the length */
479   unsigned mtype : 8;   /*!< main data type */
480 
481   /* the remaining fields do not affect alphabetical ordering: */
482 
483   unsigned len : 16; /*!< length; for MySQL data this
484                      is field->pack_length(),
485                      except that for a >= 5.0.3
486                      type true VARCHAR this is the
487                      maximum byte length of the
488                      string data (in addition to
489                      the string, MySQL uses 1 or 2
490                      bytes to store the string length) */
491 
492   unsigned mbminmaxlen : 5; /*!< minimum and maximum length of a
493                             character, in bytes;
494                             DATA_MBMINMAXLEN(mbminlen,mbmaxlen);
495                             mbminlen=DATA_MBMINLEN(mbminmaxlen);
496                             mbmaxlen=DATA_MBMINLEN(mbminmaxlen) */
497   /*----------------------*/
498   /* End of definitions copied from dtype_t */
499   /* @} */
500 
501   unsigned ind : 10;        /*!< table column position
502                             (starting from 0) */
503   unsigned ord_part : 1;    /*!< nonzero if this column
504                             appears in the ordering fields
505                             of an index */
506   unsigned max_prefix : 12; /*!< maximum index prefix length on
507                             this column. Our current max limit is
508                             3072 (REC_VERSION_56_MAX_INDEX_COL_LEN)
509                             bytes. */
510 
511   /* True, if the column is visible */
512   bool is_visible;
513 
514   /** Returns the minimum size of the column.
515   @return minimum size */
get_min_sizedict_col_t516   ulint get_min_size() const {
517     return (dtype_get_min_size_low(mtype, prtype, len, mbminmaxlen));
518   }
519 
520   /** Returns the maximum size of the column.
521   @return maximum size */
get_max_sizedict_col_t522   ulint get_max_size() const { return (dtype_get_max_size_low(mtype, len)); }
523 
524   /** Check if a column is a virtual column
525   @return true if it is a virtual column, false otherwise */
is_virtualdict_col_t526   bool is_virtual() const { return (prtype & DATA_VIRTUAL); }
527 
528   /** Check if a column is a multi-value virtual column
529   @return true if it is a multi-value virtual column, false otherwise */
is_multi_valuedict_col_t530   bool is_multi_value() const { return ((prtype & DATA_MULTI_VALUE) != 0); }
531 
532   /** Check if a column is nullable
533   @return true if it is nullable, otherwise false */
is_nullabledict_col_t534   bool is_nullable() const { return ((prtype & DATA_NOT_NULL) == 0); }
535 
536   /** Gets the column data type.
537   @param[out] type	data type */
copy_typedict_col_t538   void copy_type(dtype_t *type) const {
539     ut_ad(type != nullptr);
540 
541     type->mtype = mtype;
542     type->prtype = prtype;
543     type->len = len;
544     type->mbminmaxlen = mbminmaxlen;
545   }
546 
547   /** Gets the minimum number of bytes per character.
548   @return minimum multi-byte char size, in bytes */
get_mbminlendict_col_t549   ulint get_mbminlen() const { return (DATA_MBMINLEN(mbminmaxlen)); }
550 
551   /** Gets the maximum number of bytes per character.
552   @return maximum multi-byte char size, in bytes */
get_mbmaxlendict_col_t553   ulint get_mbmaxlen() const { return (DATA_MBMAXLEN(mbminmaxlen)); }
554 
555   /** Sets the minimum and maximum number of bytes per character.
556   @param[in] mbminlen	minimum multi byte character size, in bytes
557   @param[in] mbmaxlen	mAXimum multi-byte character size, in bytes */
set_mbminmaxlendict_col_t558   void set_mbminmaxlen(ulint mbminlen, ulint mbmaxlen) {
559     ut_ad(mbminlen < DATA_MBMAX);
560     ut_ad(mbmaxlen < DATA_MBMAX);
561     ut_ad(mbminlen <= mbmaxlen);
562 
563     mbminmaxlen = DATA_MBMINMAXLEN(mbminlen, mbmaxlen);
564   }
565 
566   /** Returns the size of a fixed size column, 0 if not a fixed size column.
567   @param[in] comp		nonzero=ROW_FORMAT=COMPACT
568   @return fixed size, or 0 */
get_fixed_sizedict_col_t569   ulint get_fixed_size(ulint comp) const {
570     return (dtype_get_fixed_size_low(mtype, prtype, len, mbminmaxlen, comp));
571   }
572 
573   /** Returns the ROW_FORMAT=REDUNDANT stored SQL NULL size of a column.
574   For fixed length types it is the fixed length of the type, otherwise 0.
575   @param[in] comp		nonzero=ROW_FORMAT=COMPACT
576   @return SQL null storage size in ROW_FORMAT=REDUNDANT */
get_null_sizedict_col_t577   ulint get_null_size(ulint comp) const { return (get_fixed_size(comp)); }
578 
579   /** Check whether the col is used in spatial index or regular index.
580   @return spatial status */
get_spatial_statusdict_col_t581   spatial_status_t get_spatial_status() const {
582     spatial_status_t spatial_status = SPATIAL_NONE;
583 
584     /* Column is not a part of any index. */
585     if (!ord_part) {
586       return (spatial_status);
587     }
588 
589     if (DATA_GEOMETRY_MTYPE(mtype)) {
590       if (max_prefix == 0) {
591         spatial_status = SPATIAL_ONLY;
592       } else {
593         /* Any regular index on a geometry column
594         should have a prefix. */
595         spatial_status = SPATIAL_MIXED;
596       }
597     }
598 
599     return (spatial_status);
600   }
601 
602   /** Set default value
603   @param[in]	value	Default value
604   @param[in]	length	Default value length
605   @param[in,out]	heap	Heap to allocate memory */
606   void set_default(const byte *value, size_t length, mem_heap_t *heap);
607 
608 #ifdef UNIV_DEBUG
609   /** Assert that a column and a data type match.
610   param[in] type		data type
611   @return true */
assert_equaldict_col_t612   bool assert_equal(const dtype_t *type) const {
613     ut_ad(type);
614 
615     ut_ad(mtype == type->mtype);
616     ut_ad(prtype == type->prtype);
617     // ut_ad(col->len == type->len);
618 #ifndef UNIV_HOTBACKUP
619     ut_ad(mbminmaxlen == type->mbminmaxlen);
620 #endif /* !UNIV_HOTBACKUP */
621 
622     return true;
623   }
624 #endif /* UNIV_DEBUG */
625 };
626 
627 /** Index information put in a list of virtual column structure. Index
628 id and virtual column position in the index will be logged.
629 There can be multiple entries for a given index, with a different position. */
630 struct dict_v_idx_t {
631   /** active index on the column */
632   dict_index_t *index;
633 
634   /** position in this index */
635   ulint nth_field;
636 };
637 
638 /** Index list to put in dict_v_col_t */
639 typedef std::list<dict_v_idx_t, ut_allocator<dict_v_idx_t>> dict_v_idx_list;
640 
641 /** Data structure for a virtual column in a table */
642 struct dict_v_col_t {
643   /** column structure */
644   dict_col_t m_col;
645 
646   /** array of base column ptr */
647   dict_col_t **base_col;
648 
649   /** number of base columns */
650   ulint num_base;
651 
652   /** column pos in table */
653   ulint v_pos;
654 
655   /** Virtual index list, and column position in the index,
656   the allocated memory is not from table->heap, nor it is
657   tracked by dict_sys->size */
658   dict_v_idx_list *v_indexes;
659 };
660 
661 /** Data structure for newly added virtual column in a table */
662 struct dict_add_v_col_t {
663   /** number of new virtual column */
664   ulint n_v_col;
665 
666   /** column structures */
667   const dict_v_col_t *v_col;
668 
669   /** new col names */
670   const char **v_col_name;
671 };
672 
673 /** Data structure for a stored column in a table. */
674 struct dict_s_col_t {
675   /** Stored column ptr */
676   dict_col_t *m_col;
677   /** array of base col ptr */
678   dict_col_t **base_col;
679   /** number of base columns */
680   ulint num_base;
681   /** column pos in table */
682   ulint s_pos;
683 };
684 
685 /** list to put stored column for dict_table_t */
686 typedef std::list<dict_s_col_t, ut_allocator<dict_s_col_t>> dict_s_col_list;
687 
688 /** @brief DICT_ANTELOPE_MAX_INDEX_COL_LEN is measured in bytes and
689 is the maximum indexed column length (or indexed prefix length) in
690 ROW_FORMAT=REDUNDANT and ROW_FORMAT=COMPACT. Also, in any format,
691 any fixed-length field that is longer than this will be encoded as
692 a variable-length field.
693 
694 It is set to 3*256, so that one can create a column prefix index on
695 256 characters of a TEXT or VARCHAR column also in the UTF-8
696 charset. In that charset, a character may take at most 3 bytes.  This
697 constant MUST NOT BE CHANGED, or the compatibility of InnoDB data
698 files would be at risk! */
699 #define DICT_ANTELOPE_MAX_INDEX_COL_LEN REC_ANTELOPE_MAX_INDEX_COL_LEN
700 
701 /** Find out maximum indexed column length by its table format.
702 For ROW_FORMAT=REDUNDANT and ROW_FORMAT=COMPACT, the maximum
703 field length is REC_ANTELOPE_MAX_INDEX_COL_LEN - 1 (767). For
704 ROW_FORMAT=COMPRESSED and ROW_FORMAT=DYNAMIC, the length could
705 be REC_VERSION_56_MAX_INDEX_COL_LEN (3072) bytes */
706 #define DICT_MAX_FIELD_LEN_BY_FORMAT(table)                              \
707   (dict_table_has_atomic_blobs(table) ? REC_VERSION_56_MAX_INDEX_COL_LEN \
708                                       : REC_ANTELOPE_MAX_INDEX_COL_LEN - 1)
709 
710 #define DICT_MAX_FIELD_LEN_BY_FORMAT_FLAG(flags)                      \
711   (DICT_TF_HAS_ATOMIC_BLOBS(flags) ? REC_VERSION_56_MAX_INDEX_COL_LEN \
712                                    : REC_ANTELOPE_MAX_INDEX_COL_LEN - 1)
713 
714 /** Defines the maximum fixed length column size */
715 #define DICT_MAX_FIXED_COL_LEN DICT_ANTELOPE_MAX_INDEX_COL_LEN
716 
717 /** Data structure for a field in an index */
718 struct dict_field_t {
dict_field_tdict_field_t719   dict_field_t() : col(nullptr), prefix_len(0), fixed_len(0), is_ascending(0) {}
720 
721   dict_col_t *col;           /*!< pointer to the table column */
722   id_name_t name;            /*!< name of the column */
723   unsigned prefix_len : 12;  /*!< 0 or the length of the column
724                              prefix in bytes in a MySQL index of
725                              type, e.g., INDEX (textcol(25));
726                              must be smaller than
727                              DICT_MAX_FIELD_LEN_BY_FORMAT;
728                              NOTE that in the UTF-8 charset, MySQL
729                              sets this to (mbmaxlen * the prefix len)
730                              in UTF-8 chars */
731   unsigned fixed_len : 10;   /*!< 0 or the fixed length of the
732                              column if smaller than
733                              DICT_ANTELOPE_MAX_INDEX_COL_LEN */
734   unsigned is_ascending : 1; /*!< 0=DESC, 1=ASC */
735 };
736 
737 /** PADDING HEURISTIC BASED ON LINEAR INCREASE OF PADDING TO AVOID
738  COMPRESSION FAILURES
739  (Note: this is relevant only for compressed indexes)
740  GOAL: Avoid compression failures by maintaining information about the
741  compressibility of data. If data is not very compressible then leave
742  some extra space 'padding' in the uncompressed page making it more
743  likely that compression of less than fully packed uncompressed page will
744  succeed.
745 
746  This padding heuristic works by increasing the pad linearly until the
747  desired failure rate is reached. A "round" is a fixed number of
748  compression operations.
749  After each round, the compression failure rate for that round is
750  computed. If the failure rate is too high, then padding is incremented
751  by a fixed value, otherwise it's left intact.
752  If the compression failure is lower than the desired rate for a fixed
753  number of consecutive rounds, then the padding is decreased by a fixed
754  value. This is done to prevent overshooting the padding value,
755  and to accommodate the possible change in data compressibility. */
756 
757 /** Number of zip ops in one round. */
758 #define ZIP_PAD_ROUND_LEN (128)
759 
760 /** Number of successful rounds after which the padding is decreased */
761 #define ZIP_PAD_SUCCESSFUL_ROUND_LIMIT (5)
762 
763 /** Amount by which padding is increased. */
764 #define ZIP_PAD_INCR (128)
765 
766 /** Percentage of compression failures that are allowed in a single
767 round */
768 extern ulong zip_failure_threshold_pct;
769 
770 /** Maximum percentage of a page that can be allowed as a pad to avoid
771 compression failures */
772 extern ulong zip_pad_max;
773 
774 /** Data structure to hold information about about how much space in
775 an uncompressed page should be left as padding to avoid compression
776 failures. This estimate is based on a self-adapting heuristic. */
777 struct zip_pad_info_t {
778   SysMutex *mutex; /*!< mutex protecting the info */
779   ulint pad;       /*!< number of bytes used as pad */
780   ulint success;   /*!< successful compression ops during
781                    current round */
782   ulint failure;   /*!< failed compression ops during
783                    current round */
784   ulint n_rounds;  /*!< number of currently successful
785                   rounds */
786 #ifndef UNIV_HOTBACKUP
787   volatile os_once::state_t mutex_created;
788   /*!< Creation state of mutex member */
789 #endif /* !UNIV_HOTBACKUP */
790 };
791 
792 /** If key is fixed length key then cache the record offsets on first
793 computation. This will help save computation cycle that generate same
794 redundant data. */
795 class rec_cache_t {
796  public:
797   /** Constructor */
rec_cache_t()798   rec_cache_t()
799       : rec_size(),
800         offsets(),
801         sz_of_offsets(),
802         fixed_len_key(),
803         offsets_cached(),
804         key_has_null_cols() {
805     /* Do Nothing. */
806   }
807 
808  public:
809   /** Record size. (for fixed length key record size is constant) */
810   ulint rec_size;
811 
812   /** Holds reference to cached offsets for record. */
813   ulint *offsets;
814 
815   /** Size of offset array */
816   uint32_t sz_of_offsets;
817 
818   /** If true, then key is fixed length key. */
819   bool fixed_len_key;
820 
821   /** If true, then offset has been cached for re-use. */
822   bool offsets_cached;
823 
824   /** If true, then key part can have columns that can take
825   NULL values. */
826   bool key_has_null_cols;
827 };
828 
829 /** Cache position of last inserted or selected record by caching record
830 and holding reference to the block where record resides.
831 Note: We don't commit mtr and hold it beyond a transaction lifetime as this is
832 a special case (intrinsic table) that are not shared accross connection. */
833 class last_ops_cur_t {
834  public:
835   /** Constructor */
last_ops_cur_t()836   last_ops_cur_t() : rec(), block(), mtr(), disable_caching(), invalid() {
837     /* Do Nothing. */
838   }
839 
840   /* Commit mtr and re-initialize cache record and block to NULL. */
release()841   void release() {
842     if (mtr.is_active()) {
843       mtr_commit(&mtr);
844     }
845     rec = nullptr;
846     block = nullptr;
847     invalid = false;
848   }
849 
850  public:
851   /** last inserted/selected record. */
852   rec_t *rec;
853 
854   /** block where record reside. */
855   buf_block_t *block;
856 
857   /** active mtr that will be re-used for next insert/select. */
858   mtr_t mtr;
859 
860   /** disable caching. (disabled when table involves blob/text.) */
861   bool disable_caching;
862 
863   /** If index structure is undergoing structural change viz.
864   split then invalidate the cached position as it would be no more
865   remain valid. Will be re-cached on post-split insert. */
866   bool invalid;
867 };
868 
869 /** "GEN_CLUST_INDEX" is the name reserved for InnoDB default
870 system clustered index when there is no primary key. */
871 const char innobase_index_reserve_name[] = "GEN_CLUST_INDEX";
872 
873 namespace dd {
874 class Spatial_reference_system;
875 }
876 
877 /** Data structure for an index.  Most fields will be
878 initialized to 0, NULL or FALSE in dict_mem_index_create(). */
879 struct dict_index_t {
880   space_index_t id;       /*!< id of the index */
881   mem_heap_t *heap;       /*!< memory heap */
882   id_name_t name;         /*!< index name */
883   const char *table_name; /*!< table name */
884   dict_table_t *table;    /*!< back pointer to table */
885   unsigned space : 32;
886   /*!< space where the index tree is placed */
887   unsigned page : 32; /*!< index tree root page number */
888   unsigned merge_threshold : 6;
889   /*!< In the pessimistic delete, if the page
890   data size drops below this limit in percent,
891   merging it to a neighbor is tried */
892 #define DICT_INDEX_MERGE_THRESHOLD_DEFAULT 50
893   unsigned type : DICT_IT_BITS;
894   /*!< index type (DICT_CLUSTERED, DICT_UNIQUE,
895   DICT_IBUF, DICT_CORRUPT) */
896 #define MAX_KEY_LENGTH_BITS 12
897   unsigned trx_id_offset : MAX_KEY_LENGTH_BITS;
898   /*!< position of the trx id column
899   in a clustered index record, if the fields
900   before it are known to be of a fixed size,
901   0 otherwise */
902 #if (1 << MAX_KEY_LENGTH_BITS) < MAX_KEY_LENGTH
903 #error(1<<MAX_KEY_LENGTH_BITS) < MAX_KEY_LENGTH
904 #endif
905   unsigned n_user_defined_cols : 10;
906   /*!< number of columns the user defined to
907   be in the index: in the internal
908   representation we add more columns */
909   unsigned allow_duplicates : 1;
910   /*!< if true, allow duplicate values
911   even if index is created with unique
912   constraint */
913   unsigned nulls_equal : 1;
914   /*!< if true, SQL NULL == SQL NULL */
915   unsigned disable_ahi : 1;
916   /*!< if true, then disable AHI. Currently
917   limited to intrinsic temporary table and SDI
918   table as index id is not unique for such table
919   which is one of the validation criterion for
920   ahi. */
921   unsigned n_uniq : 10;     /*!< number of fields from the beginning
922                           which are enough to determine an index
923                           entry uniquely */
924   unsigned n_def : 10;      /*!< number of fields defined so far */
925   unsigned n_fields : 10;   /*!< number of fields in the index */
926   unsigned n_nullable : 10; /*!< number of nullable fields */
927   unsigned n_instant_nullable : 10;
928   /*!< number of nullable fields before first
929   instant ADD COLUMN applied to this table.
930   This is valid only when has_instant_cols() is true */
931   unsigned cached : 1; /*!< TRUE if the index object is in the
932                       dictionary cache */
933   unsigned to_be_dropped : 1;
934   /*!< TRUE if the index is to be dropped;
935   protected by dict_operation_lock */
936   unsigned online_status : 2;
937   /*!< enum online_index_status.
938   Transitions from ONLINE_INDEX_COMPLETE (to
939   ONLINE_INDEX_CREATION) are protected
940   by dict_operation_lock and
941   dict_sys->mutex. Other changes are
942   protected by index->lock. */
943   unsigned uncommitted : 1;
944   /*!< a flag that is set for secondary indexes
945   that have not been committed to the
946   data dictionary yet */
947   unsigned instant_cols : 1;
948   /*!< TRUE if the index is clustered index and it has some
949   instant columns */
950   uint32_t srid; /* spatial reference id */
951   bool srid_is_valid;
952   /* says whether SRID is valid - it cane be
953   undefined */
954   std::unique_ptr<dd::Spatial_reference_system> rtr_srs;
955   /*!< Cached spatial reference system dictionary
956   entry used by R-tree indexes. */
957 
958 #ifdef UNIV_DEBUG
959   uint32_t magic_n; /*!< magic number */
960 /** Value of dict_index_t::magic_n */
961 #define DICT_INDEX_MAGIC_N 76789786
962 #endif
963   dict_field_t *fields; /*!< array of field descriptions */
964 #ifndef UNIV_HOTBACKUP
965   st_mysql_ftparser *parser; /*!< fulltext parser plugin */
966   bool is_ngram;
967   /*!< true if it's ngram parser */
968   bool has_new_v_col;
969   /*!< whether it has a newly added virtual
970   column in ALTER */
971   bool hidden; /*!< if the index is an hidden index */
972 #endif         /* !UNIV_HOTBACKUP */
973   UT_LIST_NODE_T(dict_index_t)
974   indexes; /*!< list of indexes of the table */
975   btr_search_t *search_info;
976   /*!< info used in optimistic searches */
977 #ifndef UNIV_HOTBACKUP
978   row_log_t *online_log;
979   /*!< the log of modifications
980   during online index creation;
981   valid when online_status is
982   ONLINE_INDEX_CREATION */
983   /*----------------------*/
984   /** Statistics for query optimization */
985   /* @{ */
986   ib_uint64_t *stat_n_diff_key_vals;
987   /*!< approximate number of different
988   key values for this index, for each
989   n-column prefix where 1 <= n <=
990   dict_get_n_unique(index) (the array is
991   indexed from 0 to n_uniq-1); we
992   periodically calculate new
993   estimates */
994   ib_uint64_t *stat_n_sample_sizes;
995   /*!< number of pages that were sampled
996   to calculate each of stat_n_diff_key_vals[],
997   e.g. stat_n_sample_sizes[3] pages were sampled
998   to get the number stat_n_diff_key_vals[3]. */
999   ib_uint64_t *stat_n_non_null_key_vals;
1000   /* approximate number of non-null key values
1001   for this index, for each column where
1002   1 <= n <= dict_get_n_unique(index) (the array
1003   is indexed from 0 to n_uniq-1); This
1004   is used when innodb_stats_method is
1005   "nulls_ignored". */
1006   ulint stat_index_size;
1007   /*!< approximate index size in
1008   database pages */
1009 #endif /* !UNIV_HOTBACKUP */
1010   ulint stat_n_leaf_pages;
1011   /*!< approximate number of leaf pages in the
1012   index tree */
1013   /* @} */
1014   last_ops_cur_t *last_ins_cur;
1015   /*!< cache the last insert position.
1016   Currently limited to auto-generated
1017   clustered index on intrinsic table only. */
1018   last_ops_cur_t *last_sel_cur;
1019   /*!< cache the last selected position
1020   Currently limited to intrinsic table only. */
1021   rec_cache_t rec_cache;
1022   /*!< cache the field that needs to be
1023   re-computed on each insert.
1024   Limited to intrinsic table as this is common
1025   share and can't be used without protection
1026   if table is accessible to multiple-threads. */
1027   rtr_ssn_t rtr_ssn;           /*!< Node sequence number for RTree */
1028   rtr_info_track_t *rtr_track; /*!< tracking all R-Tree search cursors */
1029   trx_id_t trx_id;             /*!< id of the transaction that created this
1030                                index, or 0 if the index existed
1031                                when InnoDB was started up */
1032   zip_pad_info_t zip_pad;      /*!< Information about state of
1033                                compression failures and successes */
1034   rw_lock_t lock;              /*!< read-write lock protecting the
1035                                upper levels of the index tree */
1036   bool fill_dd;                /*!< Flag whether need to fill dd tables
1037                                when it's a fulltext index. */
1038 
1039   /** Determine if the index has been committed to the
1040   data dictionary.
1041   @return whether the index definition has been committed */
is_committeddict_index_t1042   bool is_committed() const {
1043     ut_ad(!uncommitted || !(type & DICT_CLUSTERED));
1044     return (UNIV_LIKELY(!uncommitted));
1045   }
1046 
1047   /** Flag an index committed or uncommitted.
1048   @param[in]	committed	whether the index is committed */
set_committeddict_index_t1049   void set_committed(bool committed) {
1050     ut_ad(!to_be_dropped);
1051     ut_ad(committed || !(type & DICT_CLUSTERED));
1052     uncommitted = !committed;
1053   }
1054 
1055   /** Get the next index.
1056   @return	next index
1057   @retval	NULL	if this was the last index */
nextdict_index_t1058   const dict_index_t *next() const {
1059     const dict_index_t *next = UT_LIST_GET_NEXT(indexes, this);
1060     ut_ad(magic_n == DICT_INDEX_MAGIC_N);
1061     return (next);
1062   }
1063   /** Get the next index.
1064   @return	next index
1065   @retval	NULL	if this was the last index */
nextdict_index_t1066   dict_index_t *next() {
1067     return (const_cast<dict_index_t *>(
1068         const_cast<const dict_index_t *>(this)->next()));
1069   }
1070 
1071   /** Check whether the index is corrupted.
1072   @return true if index is corrupted, otherwise false */
is_corrupteddict_index_t1073   bool is_corrupted() const {
1074     ut_ad(magic_n == DICT_INDEX_MAGIC_N);
1075 
1076     return (type & DICT_CORRUPT);
1077   }
1078 
1079   /* Check whether the index is the clustered index
1080   @return nonzero for clustered index, zero for other indexes */
1081 
is_clustereddict_index_t1082   bool is_clustered() const {
1083     ut_ad(magic_n == DICT_INDEX_MAGIC_N);
1084 
1085     return (type & DICT_CLUSTERED);
1086   }
1087 
1088   /** Check whether the index is the multi-value index
1089   @return nonzero for multi-value index, zero for other indexes */
is_multi_valuedict_index_t1090   bool is_multi_value() const {
1091     ut_ad(magic_n == DICT_INDEX_MAGIC_N);
1092 
1093     return (type & DICT_MULTI_VALUE);
1094   }
1095 
1096   /** Returns the minimum data size of an index record.
1097   @return minimum data size in bytes */
get_min_sizedict_index_t1098   ulint get_min_size() const {
1099     ulint size = 0;
1100 
1101     for (unsigned i = 0; i < n_fields; i++) {
1102       size += get_col(i)->get_min_size();
1103     }
1104 
1105     return (size);
1106   }
1107 
1108   /** Check whether index can be used by transaction
1109   @param[in] trx		transaction*/
1110   bool is_usable(const trx_t *trx) const;
1111 
1112   /** Check whether index has any instantly added columns
1113   @return true if this is instant affected, otherwise false */
has_instant_colsdict_index_t1114   bool has_instant_cols() const { return (instant_cols); }
1115 
1116   /** Returns the number of nullable fields before specified
1117   nth field
1118   @param[in]	nth	nth field to check */
get_n_nullable_beforedict_index_t1119   uint32_t get_n_nullable_before(uint32_t nth) const {
1120     uint32_t nullable = n_nullable;
1121 
1122     ut_ad(nth <= n_fields);
1123 
1124     for (uint32_t i = nth; i < n_fields; ++i) {
1125       if (get_field(i)->col->is_nullable()) {
1126         --nullable;
1127       }
1128     }
1129 
1130     return (nullable);
1131   }
1132 
1133   /** Returns the number of fields before first instant ADD COLUMN */
1134   uint32_t get_instant_fields() const;
1135 
1136   /** Adds a field definition to an index. NOTE: does not take a copy
1137   of the column name if the field is a column. The memory occupied
1138   by the column name may be released only after publishing the index.
1139   @param[in] name_arg	column name
1140   @param[in] prefix_len	0 or the column prefix length in a MySQL index
1141                           like INDEX (textcol(25))
1142   @param[in] is_ascending	true=ASC, false=DESC */
add_fielddict_index_t1143   void add_field(const char *name_arg, ulint prefix_len, bool is_ascending) {
1144     dict_field_t *field;
1145 
1146     ut_ad(magic_n == DICT_INDEX_MAGIC_N);
1147 
1148     n_def++;
1149 
1150     field = get_field(n_def - 1);
1151 
1152     field->name = name_arg;
1153     field->prefix_len = (unsigned int)prefix_len;
1154     field->is_ascending = is_ascending;
1155   }
1156 
1157   /** Gets the nth field of an index.
1158   @param[in] pos	position of field
1159   @return pointer to field object */
get_fielddict_index_t1160   dict_field_t *get_field(ulint pos) const {
1161     ut_ad(pos < n_def);
1162     ut_ad(magic_n == DICT_INDEX_MAGIC_N);
1163 
1164     return (fields + pos);
1165   }
1166 
1167   /** Gets pointer to the nth column in an index.
1168   @param[in] pos	position of the field
1169   @return column */
get_coldict_index_t1170   const dict_col_t *get_col(ulint pos) const { return (get_field(pos)->col); }
1171 
1172   /** Gets the column number the nth field in an index.
1173   @param[in] pos	position of the field
1174   @return column number */
1175   ulint get_col_no(ulint pos) const;
1176 
1177   /** Returns the position of a system column in an index.
1178   @param[in] type		DATA_ROW_ID, ...
1179   @return position, ULINT_UNDEFINED if not contained */
1180   ulint get_sys_col_pos(ulint type) const;
1181 
1182   /** Looks for column n in an index.
1183   @param[in]	n		column number
1184   @param[in]	inc_prefix	true=consider column prefixes too
1185   @param[in]	is_virtual	true==virtual column
1186   @return position in internal representation of the index;
1187   ULINT_UNDEFINED if not contained */
1188   ulint get_col_pos(ulint n, bool inc_prefix = false,
1189                     bool is_virtual = false) const;
1190 
1191   /** Get the default value of nth field and its length if exists.
1192   If not exists, both the return value is nullptr and length is 0.
1193   @param[in]	nth	nth field to get
1194   @param[in,out]	length	length of the default value
1195   @return	the default value data of nth field */
get_nth_defaultdict_index_t1196   const byte *get_nth_default(ulint nth, ulint *length) const {
1197     ut_ad(nth < n_fields);
1198     ut_ad(get_instant_fields() <= nth);
1199     const dict_col_t *col = get_col(nth);
1200     if (col->instant_default == nullptr) {
1201       *length = 0;
1202       return (nullptr);
1203     }
1204 
1205     *length = col->instant_default->len;
1206     ut_ad(*length == 0 || *length == UNIV_SQL_NULL ||
1207           col->instant_default->value != nullptr);
1208     return (col->instant_default->value);
1209   }
1210 
1211   /** Sets srid and srid_is_valid values
1212   @param[in]	srid_value		value of SRID, may be garbage
1213                                           if srid_is_valid_value = false
1214   @param[in]	srid_is_valid_value	value of srid_is_valid */
fill_srid_valuedict_index_t1215   void fill_srid_value(uint32_t srid_value, bool srid_is_valid_value) {
1216     srid_is_valid = srid_is_valid_value;
1217     srid = srid_value;
1218   }
1219 
1220   /** Check if the underlying table is compressed.
1221   @return true if compressed, false otherwise. */
1222   bool is_compressed() const;
1223 
1224   /** Check if a multi-value index is built on specified multi-value
1225   virtual column. Please note that there could be only one multi-value
1226   virtual column on the multi-value index, but not necessary the first
1227   field of the index.
1228   @param[in]	mv_col	multi-value virtual column
1229   @return non-zero means the column is on the index and this is the
1230   nth position of the column, zero means it's not on the index */
has_multi_value_coldict_index_t1231   uint32_t has_multi_value_col(const dict_v_col_t *mv_col) const {
1232     ut_ad(is_multi_value());
1233     for (uint32_t i = 0; i < n_fields; ++i) {
1234       const dict_col_t *col = get_col(i);
1235       if (mv_col->m_col.ind == col->ind) {
1236         return (i + 1);
1237       }
1238 
1239       /* Only one multi-value field, if not match then no match. */
1240       if (col->is_multi_value()) {
1241         break;
1242       }
1243     }
1244 
1245     return (0);
1246   }
1247 
1248  public:
1249   /** Get the page size of the tablespace to which this index belongs.
1250   @return the page size. */
1251   page_size_t get_page_size() const;
1252 
1253   /** Get the space id of the tablespace to which this index belongs.
1254   @return the space id. */
space_iddict_index_t1255   space_id_t space_id() const { return space; }
1256 };
1257 
1258 /** The status of online index creation */
1259 enum online_index_status {
1260   /** the index is complete and ready for access */
1261   ONLINE_INDEX_COMPLETE = 0,
1262   /** the index is being created, online
1263   (allowing concurrent modifications) */
1264   ONLINE_INDEX_CREATION,
1265   /** secondary index creation was aborted and the index
1266   should be dropped as soon as index->table->n_ref_count reaches 0,
1267   or online table rebuild was aborted and the clustered index
1268   of the original table should soon be restored to
1269   ONLINE_INDEX_COMPLETE */
1270   ONLINE_INDEX_ABORTED,
1271   /** the online index creation was aborted, the index was
1272   dropped from the data dictionary and the tablespace, and it
1273   should be dropped from the data dictionary cache as soon as
1274   index->table->n_ref_count reaches 0. */
1275   ONLINE_INDEX_ABORTED_DROPPED
1276 };
1277 
1278 /** Set to store the virtual columns which are affected by Foreign
1279 key constraint. */
1280 typedef std::set<dict_v_col_t *, std::less<dict_v_col_t *>,
1281                  ut_allocator<dict_v_col_t *>>
1282     dict_vcol_set;
1283 
1284 /** Data structure for a foreign key constraint; an example:
1285 FOREIGN KEY (A, B) REFERENCES TABLE2 (C, D).  Most fields will be
1286 initialized to 0, NULL or FALSE in dict_mem_foreign_create(). */
1287 struct dict_foreign_t {
1288   mem_heap_t *heap;         /*!< this object is allocated from
1289                             this memory heap */
1290   char *id;                 /*!< id of the constraint as a
1291                             null-terminated string */
1292   unsigned n_fields : 10;   /*!< number of indexes' first fields
1293                             for which the foreign key
1294                             constraint is defined: we allow the
1295                             indexes to contain more fields than
1296                             mentioned in the constraint, as long
1297                             as the first fields are as mentioned */
1298   unsigned type : 6;        /*!< 0 or DICT_FOREIGN_ON_DELETE_CASCADE
1299                             or DICT_FOREIGN_ON_DELETE_SET_NULL */
1300   char *foreign_table_name; /*!< foreign table name */
1301   char *foreign_table_name_lookup;
1302   /*!< foreign table name used for dict lookup */
1303   dict_table_t *foreign_table;    /*!< table where the foreign key is */
1304   const char **foreign_col_names; /*!< names of the columns in the
1305                                 foreign key */
1306   char *referenced_table_name;    /*!< referenced table name */
1307   char *referenced_table_name_lookup;
1308   /*!< referenced table name for dict lookup*/
1309   dict_table_t *referenced_table;    /*!< table where the referenced key
1310                                     is */
1311   const char **referenced_col_names; /*!< names of the referenced
1312                                 columns in the referenced table */
1313   dict_index_t *foreign_index;       /*!< foreign index; we require that
1314                                      both tables contain explicitly defined
1315                                      indexes for the constraint: InnoDB
1316                                      does not generate new indexes
1317                                      implicitly */
1318   dict_index_t *referenced_index;    /*!< referenced index */
1319 
1320   dict_vcol_set *v_cols; /*!< set of virtual columns affected
1321                          by foreign key constraint. */
1322 };
1323 
1324 std::ostream &operator<<(std::ostream &out, const dict_foreign_t &foreign);
1325 
1326 struct dict_foreign_print {
dict_foreign_printdict_foreign_print1327   dict_foreign_print(std::ostream &out) : m_out(out) {}
1328 
operatordict_foreign_print1329   void operator()(const dict_foreign_t *foreign) { m_out << *foreign; }
1330 
1331  private:
1332   std::ostream &m_out;
1333 };
1334 
1335 /** Compare two dict_foreign_t objects using their ids. Used in the ordering
1336 of dict_table_t::foreign_set and dict_table_t::referenced_set.  It returns
1337 true if the first argument is considered to go before the second in the
1338 strict weak ordering it defines, and false otherwise. */
1339 struct dict_foreign_compare {
operatordict_foreign_compare1340   bool operator()(const dict_foreign_t *lhs, const dict_foreign_t *rhs) const {
1341     return (ut_strcmp(lhs->id, rhs->id) < 0);
1342   }
1343 };
1344 
1345 /** A function object to find a foreign key with the given index as the
1346 referenced index. Return the foreign key with matching criteria or NULL */
1347 struct dict_foreign_with_index {
dict_foreign_with_indexdict_foreign_with_index1348   dict_foreign_with_index(const dict_index_t *index) : m_index(index) {}
1349 
operatordict_foreign_with_index1350   bool operator()(const dict_foreign_t *foreign) const {
1351     return (foreign->referenced_index == m_index);
1352   }
1353 
1354   const dict_index_t *m_index;
1355 };
1356 
1357 /* A function object to check if the foreign constraint is between different
1358 tables.  Returns true if foreign key constraint is between different tables,
1359 false otherwise. */
1360 struct dict_foreign_different_tables {
operatordict_foreign_different_tables1361   bool operator()(const dict_foreign_t *foreign) const {
1362     return (foreign->foreign_table != foreign->referenced_table);
1363   }
1364 };
1365 
1366 typedef std::set<dict_foreign_t *, dict_foreign_compare,
1367                  ut_allocator<dict_foreign_t *>>
1368     dict_foreign_set;
1369 
1370 std::ostream &operator<<(std::ostream &out, const dict_foreign_set &fk_set);
1371 
1372 /** Function object to check if a foreign key object is there
1373 in the given foreign key set or not.  It returns true if the
1374 foreign key is not found, false otherwise */
1375 struct dict_foreign_not_exists {
dict_foreign_not_existsdict_foreign_not_exists1376   dict_foreign_not_exists(const dict_foreign_set &obj_) : m_foreigns(obj_) {}
1377 
1378   /* Return true if the given foreign key is not found */
operatordict_foreign_not_exists1379   bool operator()(dict_foreign_t *const &foreign) const {
1380     return (m_foreigns.find(foreign) == m_foreigns.end());
1381   }
1382 
1383  private:
1384   const dict_foreign_set &m_foreigns;
1385 };
1386 
1387 /** Validate the search order in the foreign key set.
1388 @param[in]	fk_set	the foreign key set to be validated
1389 @return true if search order is fine in the set, false otherwise. */
1390 bool dict_foreign_set_validate(const dict_foreign_set &fk_set);
1391 
1392 /** Validate the search order in the foreign key sets of the table
1393 (foreign_set and referenced_set).
1394 @param[in]	table	table whose foreign key sets are to be validated
1395 @return true if foreign key sets are fine, false otherwise. */
1396 bool dict_foreign_set_validate(const dict_table_t &table);
1397 
1398 /** Frees a foreign key struct. */
dict_foreign_free(dict_foreign_t * foreign)1399 inline void dict_foreign_free(
1400     dict_foreign_t *foreign) /*!< in, own: foreign key struct */
1401 {
1402   if (foreign->v_cols != nullptr) {
1403     UT_DELETE(foreign->v_cols);
1404   }
1405 
1406   mem_heap_free(foreign->heap);
1407 }
1408 
1409 /** The destructor will free all the foreign key constraints in the set
1410 by calling dict_foreign_free() on each of the foreign key constraints.
1411 This is used to free the allocated memory when a local set goes out
1412 of scope. */
1413 struct dict_foreign_set_free {
dict_foreign_set_freedict_foreign_set_free1414   dict_foreign_set_free(const dict_foreign_set &foreign_set)
1415       : m_foreign_set(foreign_set) {}
1416 
~dict_foreign_set_freedict_foreign_set_free1417   ~dict_foreign_set_free() {
1418     std::for_each(m_foreign_set.begin(), m_foreign_set.end(),
1419                   dict_foreign_free);
1420   }
1421 
1422   const dict_foreign_set &m_foreign_set;
1423 };
1424 
1425 /** The flags for ON_UPDATE and ON_DELETE can be ORed; the default is that
1426 a foreign key constraint is enforced, therefore RESTRICT just means no flag */
1427 /* @{ */
1428 #define DICT_FOREIGN_ON_DELETE_CASCADE 1    /*!< ON DELETE CASCADE */
1429 #define DICT_FOREIGN_ON_DELETE_SET_NULL 2   /*!< ON DELETE SET NULL */
1430 #define DICT_FOREIGN_ON_UPDATE_CASCADE 4    /*!< ON UPDATE CASCADE */
1431 #define DICT_FOREIGN_ON_UPDATE_SET_NULL 8   /*!< ON UPDATE SET NULL */
1432 #define DICT_FOREIGN_ON_DELETE_NO_ACTION 16 /*!< ON DELETE NO ACTION */
1433 #define DICT_FOREIGN_ON_UPDATE_NO_ACTION 32 /*!< ON UPDATE NO ACTION */
1434 /* @} */
1435 
1436 /** Display an identifier.
1437 @param[in,out]	s	output stream
1438 @param[in]	id_name	SQL identifier (other than table name)
1439 @return the output stream */
1440 std::ostream &operator<<(std::ostream &s, const id_name_t &id_name);
1441 
1442 /** Display a table name.
1443 @param[in,out]	s		output stream
1444 @param[in]	table_name	table name
1445 @return the output stream */
1446 std::ostream &operator<<(std::ostream &s, const table_name_t &table_name);
1447 
1448 #ifndef UNIV_HOTBACKUP
1449 /** List of locks that different transactions have acquired on a table. This
1450 list has a list node that is embedded in a nested union/structure. We have to
1451 generate a specific template for it. */
1452 
1453 typedef ut_list_base<lock_t, ut_list_node<lock_t> lock_table_t::*>
1454     table_lock_list_t;
1455 #endif /* !UNIV_HOTBACKUP */
1456 
1457 /** mysql template structure defined in row0mysql.cc */
1458 struct mysql_row_templ_t;
1459 
1460 /** Structure defines template related to virtual columns and
1461 their base columns */
1462 struct dict_vcol_templ_t {
1463   /** number of regular columns */
1464   ulint n_col;
1465 
1466   /** number of virtual columns */
1467   ulint n_v_col;
1468 
1469   /** array of templates for virtual col and their base columns */
1470   mysql_row_templ_t **vtempl;
1471 
1472   /** table's database name */
1473   std::string db_name;
1474 
1475   /** table name */
1476   std::string tb_name;
1477 
1478   /** share->table_name */
1479   std::string share_name;
1480 
1481   /** MySQL record length */
1482   ulint rec_len;
1483 
1484   /** default column value if any */
1485   byte *default_rec;
1486 };
1487 
1488 /** The dirty status of tables, used to indicate if a table has some
1489 dynamic metadata changed to be written back */
1490 enum table_dirty_status {
1491   /** Some persistent metadata is now dirty in memory, need to be
1492   written back to DDTableBuffer table and(or directly to) DD table.
1493   There could be some exceptions, when it's marked as dirty, but
1494   the metadata has already been written back to DDTableBuffer.
1495   For example, if a corrupted index is found and marked as corrupted,
1496   then it gets dropped. At this time, the dirty_status is still of
1497   this dirty value. Also a concurrent checkpoint make this bit
1498   out-of-date for other working threads, which still think the
1499   status is dirty and write-back is necessary.
1500   There could be either one row or no row for this table in
1501   DDTableBuffer table */
1502   METADATA_DIRTY = 0,
1503   /** Some persistent metadata is buffered in DDTableBuffer table,
1504   need to be written back to DD table. There is must be one row in
1505   DDTableBuffer table for this table */
1506   METADATA_BUFFERED,
1507   /** All persistent metadata are up to date. There is no row
1508   for this table in DDTableBuffer table */
1509   METADATA_CLEAN
1510 };
1511 
1512 #ifndef UNIV_HOTBACKUP
1513 /** A vector to collect prebuilt from different readers working on the same
1514 temp table */
1515 typedef std::vector<row_prebuilt_t *> temp_prebuilt_vec;
1516 #endif /* !UNIV_HOTBACKUP */
1517 
1518 /** Data structure for a database table.  Most fields will be
1519 initialized to 0, NULL or FALSE in dict_mem_table_create(). */
1520 struct dict_table_t {
1521   /** Check if the table is compressed.
1522   @return true if compressed, false otherwise. */
is_compresseddict_table_t1523   bool is_compressed() const { return (DICT_TF_GET_ZIP_SSIZE(flags) != 0); }
1524 
1525   /** Get reference count.
1526   @return current value of n_ref_count */
1527   inline uint64_t get_ref_count() const;
1528 
1529   /** Acquire the table handle. */
1530   inline void acquire();
1531 
1532   /** Acquire the table handle, with lock() and unlock() the table.
1533   This function needs to be called for opening table when the table
1534   is in memory and later the stats information would be initialized */
1535   inline void acquire_with_lock();
1536 
1537   /** Release the table handle. */
1538   inline void release();
1539 
1540   /** Lock the table handle. */
1541   inline void lock();
1542 
1543   /** Unlock the table handle. */
1544   inline void unlock();
1545 
1546 #ifndef UNIV_HOTBACKUP
1547   /** Get schema and table name in system character set.
1548   @param[out]	schema	schema name
1549   @param[out]	table	table name */
1550   void get_table_name(std::string &schema, std::string &table);
1551 
1552   /** Mutex of the table for concurrency access. */
1553   ib_mutex_t *mutex;
1554 
1555   /** Creation state of mutex. */
1556   volatile os_once::state_t mutex_created;
1557 #endif /* !UNIV_HOTBACKUP */
1558 
1559   /** Id of the table. */
1560   table_id_t id;
1561 
1562   /** Memory heap. If you allocate from this heap after the table has
1563   been created then be sure to account the allocation into
1564   dict_sys->size. When closing the table we do something like
1565   dict_sys->size -= mem_heap_get_size(table->heap) and if that is going
1566   to become negative then we would assert. Something like this should do:
1567   old_size = mem_heap_get_size()
1568   mem_heap_alloc()
1569   new_size = mem_heap_get_size()
1570   dict_sys->size += new_size - old_size. */
1571   mem_heap_t *heap;
1572 
1573   /** Table name. */
1574   table_name_t name;
1575 
1576   /** Truncate name. */
1577   table_name_t trunc_name;
1578 
1579   /** NULL or the directory path specified by DATA DIRECTORY. */
1580   char *data_dir_path;
1581 
1582   /** NULL or the tablespace name that this table is assigned to,
1583   specified by the TABLESPACE option.*/
1584   id_name_t tablespace;
1585 
1586   /** Space where the clustered index of the table is placed. */
1587   space_id_t space;
1588 
1589   /** dd::Tablespace::id of the table */
1590   dd::Object_id dd_space_id;
1591 
1592   /** Stores information about:
1593   1 row format (redundant or compact),
1594   2 compressed page size (zip shift size),
1595   3 whether using atomic blobs,
1596   4 whether the table has been created with the option DATA DIRECTORY.
1597   Use DICT_TF_GET_COMPACT(), DICT_TF_GET_ZIP_SSIZE(),
1598   DICT_TF_HAS_ATOMIC_BLOBS() and DICT_TF_HAS_DATA_DIR() to parse this
1599   flag. */
1600   unsigned flags : DICT_TF_BITS;
1601 
1602   /** Stores information about:
1603   1 whether the table has been created using CREATE TEMPORARY TABLE,
1604   2 whether the table has an internally defined DOC ID column,
1605   3 whether the table has a FTS index,
1606   4 whether DOC ID column need to be added to the FTS index,
1607   5 whether the table is being created its own tablespace,
1608   6 whether the table has been DISCARDed,
1609   7 whether the aux FTS tables names are in hex.
1610   8 whether the table is instinc table.
1611   9 whether the table has encryption setting.
1612   Use DICT_TF2_FLAG_IS_SET() to parse this flag. */
1613   unsigned flags2 : DICT_TF2_BITS;
1614 
1615   /** TRUE if the table is an intermediate table during copy alter
1616   operation or a partition/subpartition which is required for copying
1617   data and skip the undo log for insertion of row in the table.
1618   This variable will be set and unset during extra(), or during the
1619   process of altering partitions */
1620   unsigned skip_alter_undo : 1;
1621 
1622   /** TRUE if this is in a single-table tablespace and the .ibd file is
1623   missing. Then we must return in ha_innodb.cc an error if the user
1624   tries to query such an orphaned table. */
1625   unsigned ibd_file_missing : 1;
1626 
1627   /** TRUE if the table object has been added to the dictionary cache. */
1628   unsigned cached : 1;
1629 
1630   /** TRUE if the table is to be dropped, but not yet actually dropped
1631   (could in the background drop list). It is turned on at the beginning
1632   of row_drop_table_for_mysql() and turned off just before we start to
1633   update system tables for the drop. It is protected by
1634   dict_operation_lock. */
1635   unsigned to_be_dropped : 1;
1636 
1637   /** Number of non-virtual columns defined so far. */
1638   unsigned n_def : 10;
1639 
1640   /** Number of non-virtual columns. */
1641   unsigned n_cols : 10;
1642 
1643   /** Number of non-virtual columns before first instant ADD COLUMN,
1644   including the system columns like n_cols. */
1645   unsigned n_instant_cols : 10;
1646 
1647   /** Number of total columns (inlcude virtual and non-virtual) */
1648   unsigned n_t_cols : 10;
1649 
1650   /** Number of total columns defined so far. */
1651   unsigned n_t_def : 10;
1652 
1653   /** Number of virtual columns defined so far. */
1654   unsigned n_v_def : 10;
1655 
1656   /** Number of virtual columns. */
1657   unsigned n_v_cols : 10;
1658 
1659   /** Number of multi-value virtual columns. */
1660   unsigned n_m_v_cols : 10;
1661 
1662   /** TRUE if this table is expected to be kept in memory. This table
1663   could be a table that has FK relationships or is undergoing DDL */
1664   unsigned can_be_evicted : 1;
1665 
1666   /** TRUE if this table is not evictable(can_be_evicted) and this is
1667   because of DDL operation */
1668   unsigned ddl_not_evictable : 1;
1669 
1670   /** TRUE if some indexes should be dropped after ONLINE_INDEX_ABORTED
1671   or ONLINE_INDEX_ABORTED_DROPPED. */
1672   unsigned drop_aborted : 1;
1673 
1674   /** Array of column descriptions. */
1675   dict_col_t *cols;
1676 
1677   /** Array of virtual column descriptions. */
1678   dict_v_col_t *v_cols;
1679 
1680   /** List of stored column descriptions. It is used only for foreign key
1681   check during create table and copy alter operations.
1682   During copy alter, s_cols list is filled during create table operation
1683   and need to preserve till rename table operation. That is the
1684   reason s_cols is a part of dict_table_t */
1685   dict_s_col_list *s_cols;
1686 
1687   /** Column names packed in a character string
1688   "name1\0name2\0...nameN\0". Until the string contains n_cols, it will
1689   be allocated from a temporary heap. The final string will be allocated
1690   from table->heap. */
1691   const char *col_names;
1692 
1693   /** Virtual column names */
1694   const char *v_col_names;
1695 
1696   /** True if the table belongs to a system database (mysql, information_schema
1697   or performance_schema) */
1698   bool is_system_table;
1699 
1700   /** Hash chain node. */
1701   hash_node_t name_hash;
1702 
1703   /** Hash chain node. */
1704   hash_node_t id_hash;
1705 
1706   /** The FTS_DOC_ID_INDEX, or NULL if no fulltext indexes exist */
1707   dict_index_t *fts_doc_id_index;
1708 
1709   /** List of indexes of the table. */
1710   UT_LIST_BASE_NODE_T(dict_index_t) indexes;
1711 
1712   /** List of foreign key constraints in the table. These refer to
1713   columns in other tables. */
1714   UT_LIST_BASE_NODE_T(dict_foreign_t) foreign_list;
1715 
1716   /** List of foreign key constraints which refer to this table. */
1717   UT_LIST_BASE_NODE_T(dict_foreign_t) referenced_list;
1718 
1719   /** Node of the LRU list of tables. */
1720   UT_LIST_NODE_T(dict_table_t) table_LRU;
1721 
1722   /** metadata version number of dd::Table::se_private_data() */
1723   uint64_t version;
1724 
1725   /** table dynamic metadata status, protected by dict_persist->mutex */
1726   std::atomic<table_dirty_status> dirty_status;
1727 
1728 #ifndef UNIV_HOTBACKUP
1729   /** Node of the dirty table list of tables, which is protected
1730   by dict_persist->mutex */
1731   UT_LIST_NODE_T(dict_table_t) dirty_dict_tables;
1732 #endif /* !UNIV_HOTBACKUP */
1733 
1734 #ifdef UNIV_DEBUG
1735   /** This field is used to mark if a table is in the
1736   dirty_dict_tables_list. if the dirty_status is not of
1737   METADATA_CLEAN, the table should be in the list, otherwise not.
1738   This field should be protected by dict_persist->mutex too. */
1739   bool in_dirty_dict_tables_list;
1740 #endif /* UNIV_DEBUG */
1741 
1742   /** Maximum recursive level we support when loading tables chained
1743   together with FK constraints. If exceeds this level, we will stop
1744   loading child table into memory along with its parent table. */
1745   unsigned fk_max_recusive_level : 8;
1746 
1747   /** Count of how many foreign key check operations are currently being
1748   performed on the table. We cannot drop the table while there are
1749   foreign key checks running on it. */
1750   ulint n_foreign_key_checks_running;
1751 
1752   /** Transaction id that last touched the table definition. Either when
1753   loading the definition or CREATE TABLE, or ALTER TABLE (prepare,
1754   commit, and rollback phases). */
1755   trx_id_t def_trx_id;
1756 
1757   /*!< set of foreign key constraints in the table; these refer to
1758   columns in other tables */
1759   dict_foreign_set foreign_set;
1760 
1761   /*!< set of foreign key constraints which refer to this table */
1762   dict_foreign_set referenced_set;
1763 
1764 #ifdef UNIV_DEBUG
1765   /** This field is used to specify in simulations tables which are so
1766   big that disk should be accessed. Disk access is simulated by putting
1767   the thread to sleep for a while. NOTE that this flag is not stored to
1768   the data dictionary on disk, and the database will forget about value
1769   TRUE if it has to reload the table definition from disk. */
1770   ibool does_not_fit_in_memory;
1771 #endif /* UNIV_DEBUG */
1772 
1773   /** TRUE if the maximum length of a single row exceeds BIG_ROW_SIZE.
1774   Initialized in dict_table_add_to_cache(). */
1775   unsigned big_rows : 1;
1776 
1777 #ifndef UNIV_HOTBACKUP
1778   /** Statistics for query optimization. @{ */
1779 
1780   /** Creation state of 'stats_latch'. */
1781   volatile os_once::state_t stats_latch_created;
1782 
1783   /** This latch protects:
1784   "dict_table_t::stat_initialized",
1785   "dict_table_t::stat_n_rows (*)",
1786   "dict_table_t::stat_clustered_index_size",
1787   "dict_table_t::stat_sum_of_other_index_sizes",
1788   "dict_table_t::stat_modified_counter (*)",
1789   "dict_table_t::indexes*::stat_n_diff_key_vals[]",
1790   "dict_table_t::indexes*::stat_index_size",
1791   "dict_table_t::indexes*::stat_n_leaf_pages".
1792   (*) Those are not always protected for
1793   performance reasons. */
1794   rw_lock_t *stats_latch;
1795 
1796   /** TRUE if statistics have been calculated the first time after
1797   database startup or table creation. */
1798   unsigned stat_initialized : 1;
1799 
1800   /** Timestamp of last recalc of the stats. */
1801   ib_time_monotonic_t stats_last_recalc;
1802 
1803 /** The two bits below are set in the 'stat_persistent' member. They
1804 have the following meaning:
1805 1. _ON=0, _OFF=0, no explicit persistent stats setting for this table,
1806 the value of the global srv_stats_persistent is used to determine
1807 whether the table has persistent stats enabled or not
1808 2. _ON=0, _OFF=1, persistent stats are explicitly disabled for this
1809 table, regardless of the value of the global srv_stats_persistent
1810 3. _ON=1, _OFF=0, persistent stats are explicitly enabled for this
1811 table, regardless of the value of the global srv_stats_persistent
1812 4. _ON=1, _OFF=1, not allowed, we assert if this ever happens. */
1813 #define DICT_STATS_PERSISTENT_ON (1 << 1)
1814 #define DICT_STATS_PERSISTENT_OFF (1 << 2)
1815 
1816   /** Indicates whether the table uses persistent stats or not. See
1817   DICT_STATS_PERSISTENT_ON and DICT_STATS_PERSISTENT_OFF. */
1818   ib_uint32_t stat_persistent;
1819 
1820 /** The two bits below are set in the 'stats_auto_recalc' member. They
1821 have the following meaning:
1822 1. _ON=0, _OFF=0, no explicit auto recalc setting for this table, the
1823 value of the global srv_stats_persistent_auto_recalc is used to
1824 determine whether the table has auto recalc enabled or not
1825 2. _ON=0, _OFF=1, auto recalc is explicitly disabled for this table,
1826 regardless of the value of the global srv_stats_persistent_auto_recalc
1827 3. _ON=1, _OFF=0, auto recalc is explicitly enabled for this table,
1828 regardless of the value of the global srv_stats_persistent_auto_recalc
1829 4. _ON=1, _OFF=1, not allowed, we assert if this ever happens. */
1830 #define DICT_STATS_AUTO_RECALC_ON (1 << 1)
1831 #define DICT_STATS_AUTO_RECALC_OFF (1 << 2)
1832 
1833   /** Indicates whether the table uses automatic recalc for persistent
1834   stats or not. See DICT_STATS_AUTO_RECALC_ON and
1835   DICT_STATS_AUTO_RECALC_OFF. */
1836   ib_uint32_t stats_auto_recalc;
1837 
1838   /** The number of pages to sample for this table during persistent
1839   stats estimation. If this is 0, then the value of the global
1840   srv_stats_persistent_sample_pages will be used instead. */
1841   ulint stats_sample_pages;
1842 
1843   /** Approximate number of rows in the table. We periodically calculate
1844   new estimates. */
1845   ib_uint64_t stat_n_rows;
1846 
1847   /** Approximate clustered index size in database pages. */
1848   ulint stat_clustered_index_size;
1849 
1850   /** Approximate size of other indexes in database pages. */
1851   ulint stat_sum_of_other_index_sizes;
1852 
1853   /** If FTS AUX table, parent table id */
1854   table_id_t parent_id;
1855 
1856   /** How many rows are modified since last stats recalc. When a row is
1857   inserted, updated, or deleted, we add 1 to this number; we calculate
1858   new estimates for the table and the indexes if the table has changed
1859   too much, see row_update_statistics_if_needed(). The counter is reset
1860   to zero at statistics calculation. This counter is not protected by
1861   any latch, because this is only used for heuristics. */
1862   ib_uint64_t stat_modified_counter;
1863 
1864 /** Background stats thread is not working on this table. */
1865 #define BG_STAT_NONE 0
1866 
1867 /** Set in 'stats_bg_flag' when the background stats code is working
1868 on this table. The DROP TABLE code waits for this to be cleared before
1869 proceeding. */
1870 #define BG_STAT_IN_PROGRESS (1 << 0)
1871 
1872 /** Set in 'stats_bg_flag' when DROP TABLE starts waiting on
1873 BG_STAT_IN_PROGRESS to be cleared. The background stats thread will
1874 detect this and will eventually quit sooner. */
1875 #define BG_STAT_SHOULD_QUIT (1 << 1)
1876 
1877   /** The state of the background stats thread wrt this table.
1878   See BG_STAT_NONE, BG_STAT_IN_PROGRESS and BG_STAT_SHOULD_QUIT.
1879   Writes are covered by dict_sys->mutex. Dirty reads are possible. */
1880   byte stats_bg_flag;
1881 
1882   /* @} */
1883 #endif /* !UNIV_HOTBACKUP */
1884 
1885   /** AUTOINC related members. @{ */
1886 
1887   /* The actual collection of tables locked during AUTOINC read/write is
1888   kept in trx_t. In order to quickly determine whether a transaction has
1889   locked the AUTOINC lock we keep a pointer to the transaction here in
1890   the 'autoinc_trx' member. This is to avoid acquiring lock_sys latches and
1891   scanning the vector in trx_t.
1892   When an AUTOINC lock has to wait, the corresponding lock instance is
1893   created on the trx lock heap rather than use the pre-allocated instance
1894   in autoinc_lock below. */
1895 
1896   /** A buffer for an AUTOINC lock for this table. We allocate the
1897   memory here so that individual transactions can get it and release it
1898   without a need to allocate space from the lock heap of the trx:
1899   otherwise the lock heap would grow rapidly if we do a large insert
1900   from a select. */
1901 #ifndef UNIV_HOTBACKUP
1902   lock_t *autoinc_lock;
1903 
1904   /** Creation state of autoinc_mutex member */
1905   volatile os_once::state_t autoinc_mutex_created;
1906 #endif /* !UNIV_HOTBACKUP */
1907 
1908   /** Mutex protecting the autoincrement counter. */
1909   ib_mutex_t *autoinc_mutex;
1910 
1911   /** Autoinc counter value to give to the next inserted row. */
1912   ib_uint64_t autoinc;
1913 
1914   /** Mutex protecting the persisted autoincrement counter. */
1915   ib_mutex_t *autoinc_persisted_mutex;
1916 
1917   /** Autoinc counter value that has been persisted in redo logs or
1918   DDTableBuffer. It's mainly used when we want to write counter back
1919   to DDTableBuffer.
1920   This is different from the 'autoinc' above, which could be bigger
1921   than this one, because 'autoinc' will get updated right after
1922   some counters are allocated, but we will write the counter to redo
1923   logs and update this counter later. Once all allocated counters
1924   have been written to redo logs, 'autoinc' should be exact the next
1925   counter of this persisted one.
1926   We want this counter because when we need to write the counter back
1927   to DDTableBuffer, we had better keep it consistency with the counter
1928   that has been written to redo logs. Besides, we can't read the 'autoinc'
1929   directly easily, because the autoinc_lock is required and there could
1930   be a deadlock.
1931   This variable is protected by autoinc_persisted_mutex. */
1932   ib_uint64_t autoinc_persisted;
1933 
1934   /** The position of autoinc counter field in clustered index. This would
1935   be set when CREATE/ALTER/OPEN TABLE and IMPORT TABLESPACE, and used in
1936   modifications to clustered index, such as INSERT/UPDATE. There should
1937   be no conflict to access it, so no protection is needed. */
1938   ulint autoinc_field_no;
1939 
1940   /** The transaction that currently holds the the AUTOINC lock on this table.
1941   Protected by lock_sys table shard latch. To "peek" the current value one
1942   can read it without any latch, understanding that in general it may change.
1943   Such access pattern is correct if trx thread wants to check if it has the lock
1944   granted, as the field can only change to other value when lock is released,
1945   which can not happen concurrently to thread executing the trx. */
1946   std::atomic<const trx_t *> autoinc_trx;
1947 
1948   /* @} */
1949 
1950 #ifndef UNIV_HOTBACKUP
1951   /** FTS specific state variables. */
1952   fts_t *fts;
1953 #endif /* !UNIV_HOTBACKUP */
1954 
1955   /** Quiescing states, protected by the dict_index_t::lock. ie. we can
1956   only change the state if we acquire all the latches (dict_index_t::lock)
1957   in X mode of this table's indexes. */
1958   ib_quiesce_t quiesce;
1959 
1960   /** Count of the number of record locks on this table. We use this to
1961   determine whether we can evict the table from the dictionary cache.
1962   Writes (atomic increments and decrements) are performed when holding a shared
1963   latch on lock_sys. (Note that this the table's shard latch is NOT required,
1964   as this is field counts *record* locks, so a page shard is latched instead)
1965   Reads should be performed when holding exclusive lock_sys latch, however:
1966   - Some places assert this field is zero without holding any latch.
1967   - Some places assert this field is positive holding only shared latch. */
1968   std::atomic<size_t> n_rec_locks;
1969 
1970 #ifndef UNIV_DEBUG
1971  private:
1972 #endif
1973   /** Count of how many handles are opened to this table. Dropping of the
1974   table is NOT allowed until this count gets to zero. MySQL does NOT
1975   itself check the number of open handles at DROP. */
1976   std::atomic<uint64_t> n_ref_count;
1977 
1978  public:
1979 #ifndef UNIV_HOTBACKUP
1980   /** List of locks on the table. Protected by lock_sys shard latch. */
1981   table_lock_list_t locks;
1982   /** count_by_mode[M] = number of locks in this->locks with
1983   lock->type_mode&LOCK_MODE_MASK == M.
1984   Used to quickly verify that there are no LOCK_S or LOCK_X, which are the only
1985   modes incompatible with LOCK_IS and LOCK_IX, to avoid costly iteration over
1986   this->locks when adding LOCK_IS or LOCK_IX.
1987   We use count_by_mode[LOCK_AUTO_INC] to track the number of granted and pending
1988   autoinc locks on this table. This value is set after acquiring the lock_sys
1989   table shard latch, but we peek the contents to determine whether other
1990   transactions have acquired the AUTOINC lock or not. Of course only one
1991   transaction can be granted the lock but there can be multiple
1992   waiters.
1993   Protected by lock_sys table shard latch. */
1994   ulong count_by_mode[LOCK_NUM];
1995 #endif /* !UNIV_HOTBACKUP */
1996 
1997   /** Timestamp of the last modification of this table. */
1998   time_t update_time;
1999 
2000   /** row-id counter for use by intrinsic table for getting row-id.
2001   Given intrinsic table semantics, row-id can be locally maintained
2002   instead of getting it from central generator which involves mutex
2003   locking. */
2004   ib_uint64_t sess_row_id;
2005 
2006   /** trx_id counter for use by intrinsic table for getting trx-id.
2007   Intrinsic table are not shared so don't need a central trx-id
2008   but just need a increased counter to track consistent view while
2009   proceeding SELECT as part of UPDATE. */
2010   ib_uint64_t sess_trx_id;
2011 
2012 #ifdef UNIV_DEBUG
2013 /** Value of 'magic_n'. */
2014 #define DICT_TABLE_MAGIC_N 76333786
2015 
2016   /** Magic number. */
2017   ulint magic_n;
2018 #endif /* UNIV_DEBUG */
2019   /** mysql_row_templ_t for base columns used for compute the virtual
2020   columns */
2021   dict_vcol_templ_t *vc_templ;
2022 
2023   /** encryption key, it's only for export/import */
2024   byte *encryption_key;
2025 
2026   /** encryption iv, it's only for export/import */
2027   byte *encryption_iv;
2028 
2029   /** remove the dict_table_t from cache after DDL operation */
2030   bool discard_after_ddl;
2031 
2032   /** refresh/reload FK info */
2033   bool refresh_fk;
2034 
2035 #ifndef UNIV_HOTBACKUP
2036   /** multiple cursors can be active on this temporary table */
2037   temp_prebuilt_vec *temp_prebuilt;
2038 #endif /* !UNIV_HOTBACKUP */
2039 
2040   /** TRUE only for dictionary tables like mysql/tables,
2041   mysql/columns, mysql/tablespaces, etc. This flag is used
2042   to do non-locking reads on DD tables. */
2043   bool is_dd_table;
2044 
2045   /** true if this table is explicitly put to non-LRU list
2046   during table creation */
2047   bool explicitly_non_lru;
2048 
2049   /** @return the clustered index */
first_indexdict_table_t2050   const dict_index_t *first_index() const {
2051     ut_ad(magic_n == DICT_TABLE_MAGIC_N);
2052     const dict_index_t *first = UT_LIST_GET_FIRST(indexes);
2053     return (first);
2054   }
2055   /** @return the clustered index */
first_indexdict_table_t2056   dict_index_t *first_index() {
2057     return (const_cast<dict_index_t *>(
2058         const_cast<const dict_table_t *>(this)->first_index()));
2059   }
2060 
2061   /** @return if there was any instantly added column.
2062   This will be true after one or more instant ADD COLUMN, however,
2063   it would become false after ALTER TABLE which rebuilds or copies
2064   the old table.
2065   If this is true, all instantly added columns should have default
2066   values, and records in the table may have REC_INFO_INSTANT_FLAG set. */
has_instant_colsdict_table_t2067   bool has_instant_cols() const {
2068     ut_ad(n_instant_cols <= n_cols);
2069 
2070     return (n_instant_cols < n_cols);
2071   }
2072 
2073   /** Set the number of columns when the first instant ADD COLUMN happens.
2074   @param[in]	instant_cols	number of fields when first instant
2075                                   ADD COLUMN happens, without system
2076                                   columns */
set_instant_colsdict_table_t2077   void set_instant_cols(uint16_t instant_cols) {
2078     n_instant_cols = static_cast<unsigned>(instant_cols) + get_n_sys_cols();
2079   }
2080 
2081   /** Get the number of user columns when the first instant ADD COLUMN
2082   happens.
2083   @return	the number of user columns as described above */
get_instant_colsdict_table_t2084   uint16_t get_instant_cols() const {
2085     return static_cast<uint16_t>(n_instant_cols - get_n_sys_cols());
2086   }
2087 
2088   /** Check whether the table is corrupted.
2089   @return true if the table is corrupted, otherwise false */
is_corrupteddict_table_t2090   bool is_corrupted() const {
2091     ut_ad(magic_n == DICT_TABLE_MAGIC_N);
2092 
2093     const dict_index_t *index = first_index();
2094 
2095     /* It is possible that this table is only half created, in which case
2096     the clustered index may be NULL.  If the clustered index is corrupted,
2097     the table is corrupt.  We do not consider the table corrupt if only
2098     a secondary index is corrupt. */
2099     ut_ad(index == nullptr || index->is_clustered());
2100 
2101     return (index != nullptr && index->type & DICT_CORRUPT);
2102   }
2103 
2104   /** Returns a column's name.
2105   @param[in] col_nr	column number
2106   @return column name. NOTE: not guaranteed to stay valid if table is
2107   modified in any way (columns added, etc.). */
get_col_namedict_table_t2108   const char *get_col_name(ulint col_nr) const {
2109     ut_ad(col_nr < n_def);
2110     ut_ad(magic_n == DICT_TABLE_MAGIC_N);
2111 
2112     const char *s = col_names;
2113     if (s) {
2114       for (ulint i = 0; i < col_nr; i++) {
2115         s += strlen(s) + 1;
2116       }
2117     }
2118 
2119     return (s);
2120   }
2121 
field_numberdict_table_t2122   int field_number(const char *field_name) const {
2123     for (int i = 0; i < n_def; ++i) {
2124       if (strcmp(field_name, get_col_name(i)) == 0) {
2125         return i;
2126       }
2127     }
2128     ut_a(0);
2129   }
2130 
2131   /**Gets the nth column of a table.
2132   @param[in] pos	position of column
2133   @return pointer to column object */
get_coldict_table_t2134   dict_col_t *get_col(ulint pos) const {
2135     ut_ad(pos < n_def);
2136     ut_ad(magic_n == DICT_TABLE_MAGIC_N);
2137 
2138     return (cols + pos);
2139   }
2140 
2141   /** Gets the number of user-defined non-virtual columns in a table
2142   in the dictionary cache.
2143   @return number of user-defined (e.g., not ROW_ID) non-virtual columns
2144   of a table */
get_n_user_colsdict_table_t2145   uint16_t get_n_user_cols() const {
2146     ut_ad(magic_n == DICT_TABLE_MAGIC_N);
2147 
2148     return (static_cast<uint16_t>(n_cols) - get_n_sys_cols());
2149   }
2150 
2151   /** Gets the number of system columns in a table.
2152   For intrinsic table on ROW_ID column is added for all other
2153   tables TRX_ID and ROLL_PTR are all also appeneded.
2154   @return number of system (e.g., ROW_ID) columns of a table */
get_n_sys_colsdict_table_t2155   uint16_t get_n_sys_cols() const {
2156     ut_ad(magic_n == DICT_TABLE_MAGIC_N);
2157 
2158     return (is_intrinsic() ? DATA_ITT_N_SYS_COLS : DATA_N_SYS_COLS);
2159   }
2160 
2161   /** Gets the number of all non-virtual columns (also system) in a table
2162   in the dictionary cache.
2163   @return number of non-virtual columns of a table */
get_n_colsdict_table_t2164   ulint get_n_cols() const {
2165     ut_ad(magic_n == DICT_TABLE_MAGIC_N);
2166 
2167     return (n_cols);
2168   }
2169 
2170   /** Gets the given system column of a table.
2171   @param[in] sys DATA_ROW_ID, ...
2172   @return pointer to column object */
get_sys_coldict_table_t2173   dict_col_t *get_sys_col(ulint sys) const {
2174     dict_col_t *col;
2175 
2176     ut_ad(sys < get_n_sys_cols());
2177     ut_ad(magic_n == DICT_TABLE_MAGIC_N);
2178 
2179     col = get_col(n_cols - get_n_sys_cols() + sys);
2180     ut_ad(col->mtype == DATA_SYS);
2181     ut_ad(col->prtype == (sys | DATA_NOT_NULL));
2182 
2183     return (col);
2184   }
2185 
2186   /** Determine if this is a temporary table. */
is_temporarydict_table_t2187   bool is_temporary() const {
2188     ut_ad(magic_n == DICT_TABLE_MAGIC_N);
2189     return (flags2 & DICT_TF2_TEMPORARY);
2190   }
2191 
2192   /** Determine if this is a FTS AUX table. */
is_fts_auxdict_table_t2193   bool is_fts_aux() const {
2194     ut_ad(magic_n == DICT_TABLE_MAGIC_N);
2195     return (flags2 & DICT_TF2_AUX);
2196   }
2197 
2198   /** Determine whether the table is intrinsic.
2199   An intrinsic table is a special kind of temporary table that
2200   is invisible to the end user. It can be created internally by InnoDB,
2201   the MySQL server layer or other modules connected to InnoDB in order
2202   to gather and use data as part of a larger task. Since access to it
2203   must be as fast as possible, it does not need UNDO semantics, system
2204   fields DB_TRX_ID & DB_ROLL_PTR, doublewrite, checksum, insert buffer,
2205   use of the shared data dictionary, locking, or even a transaction.
2206   In short, these are not ACID tables at all, just temporary data stored
2207   and manipulated during a larger process.*/
is_intrinsicdict_table_t2208   bool is_intrinsic() const {
2209     if (flags2 & DICT_TF2_INTRINSIC) {
2210       ut_ad(is_temporary());
2211       return (true);
2212     }
2213 
2214     return (false);
2215   }
2216 
2217   /* GAP locks are skipped for DD tables and SDI tables
2218   @return true if table is DD table or SDI table, else false */
2219   inline bool skip_gap_locks() const;
2220 
2221   /** Determine if the table can support instant ADD COLUMN */
2222   inline bool support_instant_add() const;
2223 };
2224 
is_compressed()2225 inline bool dict_index_t::is_compressed() const {
2226   return (table->is_compressed());
2227 }
2228 
2229 /** Persistent dynamic metadata type, there should be 1 to 1
2230 relationship between the metadata and the type. Please keep them in order
2231 so that we can iterate over it */
2232 enum persistent_type_t {
2233   /** The smallest type, which should be 1 less than the first
2234   true type */
2235   PM_SMALLEST_TYPE = 0,
2236 
2237   /** Persistent Metadata type for corrupted indexes */
2238   PM_INDEX_CORRUPTED = 1,
2239 
2240   /** Persistent Metadata type for autoinc counter */
2241   PM_TABLE_AUTO_INC = 2,
2242 
2243   /* TODO: Will add following types
2244   PM_TABLE_UPDATE_TIME = 3,
2245   Maybe something tablespace related
2246   PM_TABLESPACE_SIZE = 4,
2247   PM_TABLESPACE_MAX_TRX_ID = 5, */
2248 
2249   /** The biggest type, which should be 1 bigger than the last
2250   true type */
2251   PM_BIGGEST_TYPE = 3
2252 };
2253 
2254 typedef std::vector<index_id_t, ut_allocator<index_id_t>> corrupted_ids_t;
2255 
2256 /** Persistent dynamic metadata for a table */
2257 class PersistentTableMetadata {
2258  public:
2259   /** Constructor
2260   @param[in]	id	table id
2261   @param[in]	version	table dynamic metadata version */
PersistentTableMetadata(table_id_t id,uint64 version)2262   PersistentTableMetadata(table_id_t id, uint64 version)
2263       : m_id(id), m_version(version), m_corrupted_ids(), m_autoinc(0) {}
2264 
2265   /** Get the corrupted indexes' IDs
2266   @return the vector of indexes' IDs */
get_corrupted_indexes()2267   const corrupted_ids_t &get_corrupted_indexes() const {
2268     return (m_corrupted_ids);
2269   }
2270 
2271   /** Add a corrupted index id and space id
2272   @param[in]	id	corrupted index id */
add_corrupted_index(const index_id_t id)2273   void add_corrupted_index(const index_id_t id) {
2274     m_corrupted_ids.push_back(id);
2275   }
2276 
2277   /** Set the dynamic metadata version.
2278   @param[in]	version		dynamic metadata version */
set_version(uint64_t version)2279   void set_version(uint64_t version) { m_version = version; }
2280 
2281   /** Get the dynamic metadata version */
get_version()2282   uint64_t get_version() const { return (m_version); }
2283 
2284   /** Get the table id of the metadata
2285   @return table id */
get_table_id()2286   table_id_t get_table_id() const { return (m_id); }
2287 
2288   /** Set the autoinc counter of the table if it's bigger
2289   @param[in]	autoinc	autoinc counter */
set_autoinc_if_bigger(uint64_t autoinc)2290   void set_autoinc_if_bigger(uint64_t autoinc) {
2291     /* We only set the biggest autoinc counter. Callers don't
2292     guarantee passing a bigger number in. */
2293     if (autoinc > m_autoinc) {
2294       m_autoinc = autoinc;
2295     }
2296   }
2297 
2298   /** Set the autoinc counter of the table
2299   @param[in]	autoinc	autoinc counter */
set_autoinc(uint64_t autoinc)2300   void set_autoinc(uint64_t autoinc) { m_autoinc = autoinc; }
2301 
2302   /** Get the autoinc counter of the table
2303   @return the autoinc counter */
get_autoinc()2304   uint64_t get_autoinc() const { return (m_autoinc); }
2305 
2306  private:
2307   /** Table ID which this metadata belongs to */
2308   table_id_t m_id;
2309 
2310   /** Table dynamic metadata version of the change */
2311   uint64_t m_version;
2312 
2313   /** Storing the corrupted indexes' ID if exist, or else empty */
2314   corrupted_ids_t m_corrupted_ids;
2315 
2316   /** Autoinc counter of the table */
2317   uint64_t m_autoinc;
2318 
2319   /* TODO: We will add update_time, etc. here and APIs accordingly */
2320 };
2321 
2322 /** Interface for persistent dynamic table metadata. */
2323 class Persister {
2324  public:
2325   /** Virtual desctructor */
~Persister()2326   virtual ~Persister() {}
2327 
2328   /** Write the dynamic metadata of a table, we can pre-calculate
2329   the size by calling get_write_size()
2330   @param[in]	metadata	persistent data
2331   @param[out]	buffer		write buffer
2332   @param[in]	size		size of write buffer, should be
2333                                   at least get_write_size()
2334   @return the length of bytes written */
2335   virtual ulint write(const PersistentTableMetadata &metadata, byte *buffer,
2336                       ulint size) const = 0;
2337 
2338   /** Pre-calculate the size of metadata to be written
2339   @param[in]	metadata	metadata to be written
2340   @return the size of metadata */
2341   virtual ulint get_write_size(
2342       const PersistentTableMetadata &metadata) const = 0;
2343 
2344   /** Read the dynamic metadata from buffer, and store them to
2345   metadata object
2346   @param[out]	metadata	metadata where we store the read data
2347   @param[in]	buffer		buffer to read
2348   @param[in]	size		size of buffer
2349   @param[out]	corrupt		true if we found something wrong in
2350                                   the buffer except incomplete buffer,
2351                                   otherwise false
2352   @return the bytes we read from the buffer if the buffer data
2353   is complete and we get everything, 0 if the buffer is incompleted */
2354   virtual ulint read(PersistentTableMetadata &metadata, const byte *buffer,
2355                      ulint size, bool *corrupt) const = 0;
2356 
2357   /** Write MLOG_TABLE_DYNAMIC_META for persistent dynamic
2358   metadata of table
2359   @param[in]	id		table id
2360   @param[in]	metadata	metadata used to write the log
2361   @param[in,out]	mtr		mini-transaction */
2362   void write_log(table_id_t id, const PersistentTableMetadata &metadata,
2363                  mtr_t *mtr) const;
2364 };
2365 
2366 /** Persister used for corrupted indexes */
2367 class CorruptedIndexPersister : public Persister {
2368  public:
2369   /** Write the corrupted indexes of a table, we can pre-calculate
2370   the size by calling get_write_size()
2371   @param[in]	metadata	persistent metadata
2372   @param[out]	buffer		write buffer
2373   @param[in]	size		size of write buffer, should be
2374                                   at least get_write_size()
2375   @return the length of bytes written */
2376   ulint write(const PersistentTableMetadata &metadata, byte *buffer,
2377               ulint size) const;
2378 
2379   /** Pre-calculate the size of metadata to be written
2380   @param[in]	metadata	metadata to be written
2381   @return the size of metadata */
2382   ulint get_write_size(const PersistentTableMetadata &metadata) const;
2383 
2384   /** Read the corrupted indexes from buffer, and store them to
2385   metadata object
2386   @param[out]	metadata	metadata where we store the read data
2387   @param[in]	buffer		buffer to read
2388   @param[in]	size		size of buffer
2389   @param[out]	corrupt		true if we found something wrong in
2390                                   the buffer except incomplete buffer,
2391                                   otherwise false
2392   @return the bytes we read from the buffer if the buffer data
2393   is complete and we get everything, 0 if the buffer is incomplete */
2394   ulint read(PersistentTableMetadata &metadata, const byte *buffer, ulint size,
2395              bool *corrupt) const;
2396 
2397  private:
2398   /** The length of index_id_t we will write */
2399   static const size_t INDEX_ID_LENGTH = 12;
2400 };
2401 
2402 /** Persister used for autoinc counters */
2403 class AutoIncPersister : public Persister {
2404  public:
2405   /** Write the autoinc counter of a table, we can pre-calculate
2406   the size by calling get_write_size()
2407   @param[in]	metadata	persistent metadata
2408   @param[out]	buffer		write buffer
2409   @param[in]	size		size of write buffer, should be
2410                                   at least get_write_size()
2411   @return the length of bytes written */
2412   ulint write(const PersistentTableMetadata &metadata, byte *buffer,
2413               ulint size) const;
2414 
2415   /** Pre-calculate the size of metadata to be written
2416   @param[in]	metadata	metadata to be written
2417   @return the size of metadata */
get_write_size(const PersistentTableMetadata & metadata)2418   inline ulint get_write_size(const PersistentTableMetadata &metadata) const {
2419     /* We just return the max possible size that would be used
2420     if the counter exists, so we don't calculate every time.
2421     Here we need 1 byte for dynamic metadata type and 11 bytes
2422     for the max possible size of counter. */
2423     return (12);
2424   }
2425 
2426   /** Read the autoinc counter from buffer, and store them to
2427   metadata object
2428   @param[out]	metadata	metadata where we store the read data
2429   @param[in]	buffer		buffer to read
2430   @param[in]	size		size of buffer
2431   @param[out]	corrupt		true if we found something wrong in
2432                                   the buffer except incomplete buffer,
2433                                   otherwise false
2434   @return the bytes we read from the buffer if the buffer data
2435   is complete and we get everything, 0 if the buffer is incomplete */
2436   ulint read(PersistentTableMetadata &metadata, const byte *buffer, ulint size,
2437              bool *corrupt) const;
2438 };
2439 
2440 /** Container of persisters used in the system. Currently we don't need
2441 to protect this object since we only initialize it at very beginning and
2442 destroy it in the end. During the server running, we only get the persisters */
2443 class Persisters {
2444   typedef std::map<
2445       persistent_type_t, Persister *, std::less<persistent_type_t>,
2446       ut_allocator<std::pair<const persistent_type_t, Persister *>>>
2447       persisters_t;
2448 
2449  public:
2450   /** Constructor */
Persisters()2451   Persisters() : m_persisters() {}
2452 
2453   /** Destructor */
2454   ~Persisters();
2455 
2456   /** Get the persister object with specified type
2457   @param[in]	type	persister type
2458   @return Persister object required or NULL if not found */
2459   Persister *get(persistent_type_t type) const;
2460 
2461   /** Add a specified persister of type, we will allocate the Persister
2462   if there is no such persister exist, otherwise do nothing and return
2463   the existing one
2464   @param[in]	type	persister type
2465   @return the persister of type */
2466   Persister *add(persistent_type_t type);
2467 
2468   /** Remove a specified persister of type, we will free the Persister
2469   @param[in]	type	persister type */
2470   void remove(persistent_type_t type);
2471 
2472   /** Serialize the metadata to a buffer
2473   @param[in]	metadata	metadata to serialize
2474   @param[out]	buffer		buffer to store the serialized metadata
2475   @return the length of serialized metadata */
2476   size_t write(PersistentTableMetadata &metadata, byte *buffer);
2477 
2478  private:
2479   /** A map to store all persisters needed */
2480   persisters_t m_persisters;
2481 };
2482 
2483 #ifndef UNIV_HOTBACKUP
2484 /** Initialise the table lock list. */
2485 void lock_table_lock_list_init(
2486     table_lock_list_t *locks); /*!< List to initialise */
2487 
2488 /** A function object to add the foreign key constraint to the referenced set
2489 of the referenced table, if it exists in the dictionary cache. */
2490 struct dict_foreign_add_to_referenced_table {
operatordict_foreign_add_to_referenced_table2491   void operator()(dict_foreign_t *foreign) const {
2492     if (dict_table_t *table = foreign->referenced_table) {
2493       std::pair<dict_foreign_set::iterator, bool> ret =
2494           table->referenced_set.insert(foreign);
2495       ut_a(ret.second);
2496     }
2497   }
2498 };
2499 
2500 /** Request for lazy creation of the mutex of a given table.
2501 This function is only called from either single threaded environment
2502 or from a thread that has not shared the table object with other threads.
2503 @param[in,out]	table	table whose mutex is to be created */
dict_table_mutex_create_lazy(dict_table_t * table)2504 inline void dict_table_mutex_create_lazy(dict_table_t *table) {
2505   table->mutex = nullptr;
2506   table->mutex_created = os_once::NEVER_DONE;
2507 }
2508 
2509 /** Destroy the mutex of a given table.
2510 This function is only called from either single threaded environment
2511 or from a thread that has not shared the table object with other threads.
2512 @param[in,out]	table	table whose mutex is to be created */
dict_table_mutex_destroy(dict_table_t * table)2513 inline void dict_table_mutex_destroy(dict_table_t *table) {
2514   if (table->mutex_created == os_once::DONE) {
2515     if (table->mutex != nullptr) {
2516       mutex_free(table->mutex);
2517       UT_DELETE(table->mutex);
2518     }
2519   }
2520 }
2521 
2522 /** Destroy the autoinc latch of the given table.
2523 This function is only called from either single threaded environment
2524 or from a thread that has not shared the table object with other threads.
2525 @param[in,out]	table	table whose stats latch to destroy */
dict_table_autoinc_destroy(dict_table_t * table)2526 inline void dict_table_autoinc_destroy(dict_table_t *table) {
2527   if (table->autoinc_mutex_created == os_once::DONE) {
2528     if (table->autoinc_mutex != nullptr) {
2529       mutex_free(table->autoinc_mutex);
2530       UT_DELETE(table->autoinc_mutex);
2531     }
2532 
2533     if (table->autoinc_persisted_mutex != nullptr) {
2534       mutex_free(table->autoinc_persisted_mutex);
2535       UT_DELETE(table->autoinc_persisted_mutex);
2536     }
2537   }
2538 }
2539 
2540 /** Request for lazy creation of the autoinc latch of a given table.
2541 This function is only called from either single threaded environment
2542 or from a thread that has not shared the table object with other threads.
2543 @param[in,out]	table	table whose autoinc latch is to be created. */
dict_table_autoinc_create_lazy(dict_table_t * table)2544 inline void dict_table_autoinc_create_lazy(dict_table_t *table) {
2545   table->autoinc_mutex = nullptr;
2546   table->autoinc_persisted_mutex = nullptr;
2547   table->autoinc_mutex_created = os_once::NEVER_DONE;
2548 }
2549 
2550 /** Request a lazy creation of dict_index_t::zip_pad::mutex.
2551 This function is only called from either single threaded environment
2552 or from a thread that has not shared the table object with other threads.
2553 @param[in,out]	index	index whose zip_pad mutex is to be created */
dict_index_zip_pad_mutex_create_lazy(dict_index_t * index)2554 inline void dict_index_zip_pad_mutex_create_lazy(dict_index_t *index) {
2555   index->zip_pad.mutex = nullptr;
2556   index->zip_pad.mutex_created = os_once::NEVER_DONE;
2557 }
2558 
2559 /** Destroy the zip_pad_mutex of the given index.
2560 This function is only called from either single threaded environment
2561 or from a thread that has not shared the table object with other threads.
2562 @param[in,out]	index	index whose stats latch to destroy */
dict_index_zip_pad_mutex_destroy(dict_index_t * index)2563 inline void dict_index_zip_pad_mutex_destroy(dict_index_t *index) {
2564   if (index->zip_pad.mutex_created == os_once::DONE &&
2565       index->zip_pad.mutex != nullptr) {
2566     mutex_free(index->zip_pad.mutex);
2567     UT_DELETE(index->zip_pad.mutex);
2568   }
2569 }
2570 #endif /* !UNIV_HOTBACKUP */
2571 
2572 /** Release the zip_pad_mutex of a given index.
2573 @param[in,out]	index	index whose zip_pad_mutex is to be released */
dict_index_zip_pad_unlock(dict_index_t * index)2574 inline void dict_index_zip_pad_unlock(dict_index_t *index) {
2575 #ifndef UNIV_HOTBACKUP
2576   mutex_exit(index->zip_pad.mutex);
2577 #endif /* !UNIV_HOTBACKUP */
2578 }
2579 
2580 #ifdef UNIV_DEBUG
2581 /** Check if the current thread owns the autoinc_mutex of a given table.
2582 @param[in]	table	the autoinc_mutex belongs to this table
2583 @return true, if the current thread owns the autoinc_mutex, false otherwise.*/
dict_table_autoinc_own(const dict_table_t * table)2584 inline bool dict_table_autoinc_own(const dict_table_t *table) {
2585   return (mutex_own(table->autoinc_mutex));
2586 }
2587 #endif /* UNIV_DEBUG */
2588 
2589 #include "dict0mem.ic"
2590 
2591 #endif /* dict0mem_h */
2592