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