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