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