1
/*****************************************************************************
3
Copyright (C) 1996, 2009, Innobase Oy. All Rights Reserved.
5
This program is free software; you can redistribute it and/or modify it under
6
the terms of the GNU General Public License as published by the Free Software
7
Foundation; version 2 of the License.
9
This program is distributed in the hope that it will be useful, but WITHOUT
10
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
13
You should have received a copy of the GNU General Public License along with
14
this program; if not, write to the Free Software Foundation, Inc., 51 Franklin
15
St, Fifth Floor, Boston, MA 02110-1301 USA
17
*****************************************************************************/
19
/**************************************************//**
20
@file include/dict0dict.h
21
Data dictionary system
23
Created 1/8/1996 Heikki Tuuri
24
*******************************************************/
30
#include "dict0types.h"
32
#include "data0type.h"
33
#include "data0data.h"
35
#include "rem0types.h"
38
#include "hash0hash.h"
41
#include "trx0types.h"
43
#ifndef UNIV_HOTBACKUP
44
# include "sync0sync.h"
46
/******************************************************************//**
47
Makes all characters in a NUL-terminated UTF-8 string lower case. */
52
char* a); /*!< in/out: string to put in lower case */
53
/********************************************************************//**
54
Get the database name length in a table name.
55
@return database name length */
60
const char* name); /*!< in: table name in the form
61
dbname '/' tablename */
62
/********************************************************************//**
63
Return the end of table name where we have removed dbname and '/'.
69
const char* name); /*!< in: table name in the form
70
dbname '/' tablename */
71
/**********************************************************************//**
72
Returns a table object based on table id.
73
@return table, NULL if does not exist */
78
table_id_t table_id, /*!< in: table id */
79
trx_t* trx); /*!< in: transaction handle */
80
/********************************************************************//**
81
Decrements the count of open MySQL handles to a table. */
84
dict_table_decrement_handle_count(
85
/*==============================*/
86
dict_table_t* table, /*!< in/out: table */
87
ibool dict_locked); /*!< in: TRUE=data dictionary locked */
88
/**********************************************************************//**
89
Inits the data dictionary module. */
94
/********************************************************************//**
95
Gets the space id of every table of the data dictionary and makes a linear
96
list and a hash table of them to the data dictionary cache. This function
97
can be called at database startup if we did not need to do a crash recovery.
98
In crash recovery we must scan the space id's from the .ibd files in MySQL
99
database directories. */
102
dict_load_space_id_list(void);
103
/*=========================*/
104
/*********************************************************************//**
105
Gets the minimum number of bytes per character.
106
@return minimum multi-byte char size, in bytes */
109
dict_col_get_mbminlen(
110
/*==================*/
111
const dict_col_t* col); /*!< in: column */
112
/*********************************************************************//**
113
Gets the maximum number of bytes per character.
114
@return maximum multi-byte char size, in bytes */
117
dict_col_get_mbmaxlen(
118
/*==================*/
119
const dict_col_t* col); /*!< in: column */
120
/*********************************************************************//**
121
Sets the minimum and maximum number of bytes per character. */
124
dict_col_set_mbminmaxlen(
125
/*=====================*/
126
dict_col_t* col, /*!< in/out: column */
127
ulint mbminlen, /*!< in: minimum multi-byte
128
character size, in bytes */
129
ulint mbmaxlen); /*!< in: minimum multi-byte
130
character size, in bytes */
131
/*********************************************************************//**
132
Gets the column data type. */
137
const dict_col_t* col, /*!< in: column */
138
dtype_t* type); /*!< out: data type */
139
#endif /* !UNIV_HOTBACKUP */
141
/*********************************************************************//**
142
Assert that a column and a data type match.
146
dict_col_type_assert_equal(
147
/*=======================*/
148
const dict_col_t* col, /*!< in: column */
149
const dtype_t* type); /*!< in: data type */
150
#endif /* UNIV_DEBUG */
151
#ifndef UNIV_HOTBACKUP
152
/***********************************************************************//**
153
Returns the minimum size of the column.
154
@return minimum size */
157
dict_col_get_min_size(
158
/*==================*/
159
const dict_col_t* col); /*!< in: column */
160
/***********************************************************************//**
161
Returns the maximum size of the column.
162
@return maximum size */
165
dict_col_get_max_size(
166
/*==================*/
167
const dict_col_t* col); /*!< in: column */
168
/***********************************************************************//**
169
Returns the size of a fixed size column, 0 if not a fixed size column.
170
@return fixed size, or 0 */
173
dict_col_get_fixed_size(
174
/*====================*/
175
const dict_col_t* col, /*!< in: column */
176
ulint comp); /*!< in: nonzero=ROW_FORMAT=COMPACT */
177
/***********************************************************************//**
178
Returns the ROW_FORMAT=REDUNDANT stored SQL NULL size of a column.
179
For fixed length types it is the fixed length of the type, otherwise 0.
180
@return SQL null storage size in ROW_FORMAT=REDUNDANT */
183
dict_col_get_sql_null_size(
184
/*=======================*/
185
const dict_col_t* col, /*!< in: column */
186
ulint comp); /*!< in: nonzero=ROW_FORMAT=COMPACT */
188
/*********************************************************************//**
189
Gets the column number.
190
@return col->ind, table column position (starting from 0) */
195
const dict_col_t* col); /*!< in: column */
196
/*********************************************************************//**
197
Gets the column position in the clustered index. */
200
dict_col_get_clust_pos(
201
/*===================*/
202
const dict_col_t* col, /*!< in: table column */
203
const dict_index_t* clust_index); /*!< in: clustered index */
204
/****************************************************************//**
205
If the given column name is reserved for InnoDB system columns, return
207
@return TRUE if name is reserved */
210
dict_col_name_is_reserved(
211
/*======================*/
212
const char* name); /*!< in: column name */
213
/********************************************************************//**
214
Acquire the autoinc lock. */
217
dict_table_autoinc_lock(
218
/*====================*/
219
dict_table_t* table); /*!< in/out: table */
220
/********************************************************************//**
221
Unconditionally set the autoinc counter. */
224
dict_table_autoinc_initialize(
225
/*==========================*/
226
dict_table_t* table, /*!< in/out: table */
227
ib_uint64_t value); /*!< in: next value to assign to a row */
228
/********************************************************************//**
229
Reads the next autoinc value (== autoinc counter value), 0 if not yet
231
@return value for a new row, or 0 */
234
dict_table_autoinc_read(
235
/*====================*/
236
const dict_table_t* table); /*!< in: table */
237
/********************************************************************//**
238
Updates the autoinc counter if the value supplied is greater than the
242
dict_table_autoinc_update_if_greater(
243
/*=================================*/
245
dict_table_t* table, /*!< in/out: table */
246
ib_uint64_t value); /*!< in: value which was assigned to a row */
247
/********************************************************************//**
248
Release the autoinc lock. */
251
dict_table_autoinc_unlock(
252
/*======================*/
253
dict_table_t* table); /*!< in/out: table */
254
#endif /* !UNIV_HOTBACKUP */
255
/**********************************************************************//**
256
Adds system columns to a table object. */
259
dict_table_add_system_columns(
260
/*==========================*/
261
dict_table_t* table, /*!< in/out: table */
262
mem_heap_t* heap); /*!< in: temporary heap */
263
#ifndef UNIV_HOTBACKUP
264
/**********************************************************************//**
265
Adds a table object to the dictionary cache. */
268
dict_table_add_to_cache(
269
/*====================*/
270
dict_table_t* table, /*!< in: table */
271
mem_heap_t* heap); /*!< in: temporary heap */
272
/**********************************************************************//**
273
Removes a table object from the dictionary cache. */
276
dict_table_remove_from_cache(
277
/*=========================*/
278
dict_table_t* table); /*!< in, own: table */
279
/**********************************************************************//**
280
Renames a table object.
281
@return TRUE if success */
284
dict_table_rename_in_cache(
285
/*=======================*/
286
dict_table_t* table, /*!< in/out: table */
287
const char* new_name, /*!< in: new name */
288
ibool rename_also_foreigns);/*!< in: in ALTER TABLE we want
289
to preserve the original table name
290
in constraints which reference it */
291
/**********************************************************************//**
292
Change the id of a table object in the dictionary cache. This is used in
293
DISCARD TABLESPACE. */
296
dict_table_change_id_in_cache(
297
/*==========================*/
298
dict_table_t* table, /*!< in/out: table object already in cache */
299
table_id_t new_id);/*!< in: new id to set */
300
/**********************************************************************//**
301
Adds a foreign key constraint object to the dictionary cache. May free
302
the object if there already is an object with the same identifier in.
303
At least one of foreign table or referenced table must already be in
304
the dictionary cache!
305
@return DB_SUCCESS or error code */
308
dict_foreign_add_to_cache(
309
/*======================*/
310
dict_foreign_t* foreign, /*!< in, own: foreign key constraint */
311
ibool check_charsets);/*!< in: TRUE=check charset
313
/*********************************************************************//**
314
Check if the index is referenced by a foreign key, if TRUE return the
315
matching instance NULL otherwise.
316
@return pointer to foreign key struct if index is defined for foreign
317
key, otherwise NULL */
320
dict_table_get_referenced_constraint(
321
/*=================================*/
322
dict_table_t* table, /*!< in: InnoDB table */
323
dict_index_t* index); /*!< in: InnoDB index */
324
/*********************************************************************//**
325
Checks if a table is referenced by foreign keys.
326
@return TRUE if table is referenced by a foreign key */
329
dict_table_is_referenced_by_foreign_key(
330
/*====================================*/
331
const dict_table_t* table); /*!< in: InnoDB table */
332
/**********************************************************************//**
333
Replace the index in the foreign key list that matches this index's
334
definition with an equivalent index. */
337
dict_table_replace_index_in_foreign_list(
338
/*=====================================*/
339
dict_table_t* table, /*!< in/out: table */
340
dict_index_t* index, /*!< in: index to be replaced */
341
const trx_t* trx); /*!< in: transaction handle */
342
/*********************************************************************//**
343
Checks if a index is defined for a foreign key constraint. Index is a part
344
of a foreign key constraint if the index is referenced by foreign key
345
or index is a foreign key index
346
@return pointer to foreign key struct if index is defined for foreign
347
key, otherwise NULL */
350
dict_table_get_foreign_constraint(
351
/*==============================*/
352
dict_table_t* table, /*!< in: InnoDB table */
353
dict_index_t* index); /*!< in: InnoDB index */
354
/*********************************************************************//**
355
Scans a table create SQL string and adds to the data dictionary
356
the foreign key constraints declared in the string. This function
357
should be called after the indexes for a table have been created.
358
Each foreign key constraint must be accompanied with indexes in
359
bot participating tables. The indexes are allowed to contain more
360
fields than mentioned in the constraint.
361
@return error code or DB_SUCCESS */
364
dict_create_foreign_constraints(
365
/*============================*/
366
trx_t* trx, /*!< in: transaction */
367
const char* sql_string, /*!< in: table create statement where
368
foreign keys are declared like:
369
FOREIGN KEY (a, b) REFERENCES
370
table2(c, d), table2 can be written
371
also with the database
372
name before it: test.table2; the
373
default database id the database of
375
size_t sql_length, /*!< in: length of sql_string */
376
const char* name, /*!< in: table full name in the
378
database_name/table_name */
379
ibool reject_fks); /*!< in: if TRUE, fail with error
380
code DB_CANNOT_ADD_CONSTRAINT if
381
any foreign keys are found. */
382
/**********************************************************************//**
383
Parses the CONSTRAINT id's to be dropped in an ALTER TABLE statement.
384
@return DB_SUCCESS or DB_CANNOT_DROP_CONSTRAINT if syntax error or the
385
constraint id does not match */
388
dict_foreign_parse_drop_constraints(
389
/*================================*/
390
mem_heap_t* heap, /*!< in: heap from which we can
392
trx_t* trx, /*!< in: transaction */
393
dict_table_t* table, /*!< in: table */
394
ulint* n, /*!< out: number of constraints
396
const char*** constraints_to_drop); /*!< out: id's of the
397
constraints to drop */
398
/**********************************************************************//**
399
Returns a table object and optionally increment its MySQL open handle count.
400
NOTE! This is a high-level function to be used mainly from outside the
401
'dict' directory. Inside this directory dict_table_get_low is usually the
402
appropriate function.
403
@return table, NULL if does not exist */
408
const char* table_name, /*!< in: table name */
409
ibool inc_mysql_count);
410
/*!< in: whether to increment the open
411
handle count on the table */
412
/**********************************************************************//**
413
Returns a index object, based on table and index id, and memoryfixes it.
414
@return index, NULL if does not exist */
417
dict_index_get_on_id_low(
418
/*=====================*/
419
dict_table_t* table, /*!< in: table */
420
index_id_t index_id); /*!< in: index id */
421
/**********************************************************************//**
422
Checks if a table is in the dictionary cache.
423
@return table, NULL if not found */
427
dict_table_check_if_in_cache_low(
428
/*=============================*/
429
const char* table_name); /*!< in: table name */
430
/**********************************************************************//**
431
Gets a table; loads it to the dictionary cache if necessary. A low-level
433
@return table, NULL if not found */
438
const char* table_name); /*!< in: table name */
439
/**********************************************************************//**
440
Returns a table object based on table id.
441
@return table, NULL if does not exist */
444
dict_table_get_on_id_low(
445
/*=====================*/
446
table_id_t table_id); /*!< in: table id */
447
/**********************************************************************//**
448
Find an index that is equivalent to the one passed in and is not marked
450
@return index equivalent to foreign->foreign_index, or NULL */
453
dict_foreign_find_equiv_index(
454
/*==========================*/
455
dict_foreign_t* foreign);/*!< in: foreign key */
456
/**********************************************************************//**
457
Returns an index object by matching on the name and column names and
458
if more than one index matches return the index with the max id
459
@return matching index, NULL if not found */
462
dict_table_get_index_by_max_id(
463
/*===========================*/
464
dict_table_t* table, /*!< in: table */
465
const char* name, /*!< in: the index name to find */
466
const char** columns,/*!< in: array of column names */
467
ulint n_cols);/*!< in: number of columns */
468
/**********************************************************************//**
469
Returns a column's name.
470
@return column name. NOTE: not guaranteed to stay valid if table is
471
modified in any way (columns added, etc.). */
474
dict_table_get_col_name(
475
/*====================*/
476
const dict_table_t* table, /*!< in: table */
477
ulint col_nr);/*!< in: column number */
479
/**********************************************************************//**
480
Prints a table definition. */
485
dict_table_t* table); /*!< in: table */
486
/**********************************************************************//**
487
Prints a table data. */
490
dict_table_print_low(
491
/*=================*/
492
dict_table_t* table); /*!< in: table */
493
/**********************************************************************//**
494
Prints a table data when we know the table name. */
497
dict_table_print_by_name(
498
/*=====================*/
499
const char* name); /*!< in: table name */
500
/**********************************************************************//**
501
Outputs info on foreign keys of a table. */
504
dict_print_info_on_foreign_keys(
505
/*============================*/
506
ibool create_table_format, /*!< in: if TRUE then print in
507
a format suitable to be inserted into
508
a CREATE TABLE, otherwise in the format
509
of SHOW TABLE STATUS */
510
FILE* file, /*!< in: file where to print */
511
trx_t* trx, /*!< in: transaction */
512
dict_table_t* table); /*!< in: table */
513
/**********************************************************************//**
514
Outputs info on a foreign key of a table in a format suitable for
518
dict_print_info_on_foreign_key_in_create_format(
519
/*============================================*/
520
FILE* file, /*!< in: file where to print */
521
trx_t* trx, /*!< in: transaction */
522
dict_foreign_t* foreign, /*!< in: foreign key constraint */
523
ibool add_newline); /*!< in: whether to add a newline */
524
/********************************************************************//**
525
Displays the names of the index and the table. */
528
dict_index_name_print(
529
/*==================*/
530
FILE* file, /*!< in: output stream */
531
trx_t* trx, /*!< in: transaction */
532
const dict_index_t* index); /*!< in: index to print */
534
/********************************************************************//**
535
Gets the first index on the table (the clustered index).
536
@return index, NULL if none exists */
539
dict_table_get_first_index(
540
/*=======================*/
541
const dict_table_t* table); /*!< in: table */
542
/********************************************************************//**
543
Gets the next index on the table.
544
@return index, NULL if none left */
547
dict_table_get_next_index(
548
/*======================*/
549
const dict_index_t* index); /*!< in: index */
550
#else /* UNIV_DEBUG */
551
# define dict_table_get_first_index(table) UT_LIST_GET_FIRST((table)->indexes)
552
# define dict_table_get_next_index(index) UT_LIST_GET_NEXT(indexes, index)
553
#endif /* UNIV_DEBUG */
554
#endif /* !UNIV_HOTBACKUP */
555
/********************************************************************//**
556
Check whether the index is the clustered index.
557
@return nonzero for clustered index, zero for other indexes */
562
const dict_index_t* index) /*!< in: index */
563
__attribute__((pure));
564
/********************************************************************//**
565
Check whether the index is unique.
566
@return nonzero for unique index, zero for other indexes */
569
dict_index_is_unique(
570
/*=================*/
571
const dict_index_t* index) /*!< in: index */
572
__attribute__((pure));
573
/********************************************************************//**
574
Check whether the index is the insert buffer tree.
575
@return nonzero for insert buffer, zero for other indexes */
580
const dict_index_t* index) /*!< in: index */
581
__attribute__((pure));
582
/********************************************************************//**
583
Check whether the index is a secondary index or the insert buffer tree.
584
@return nonzero for insert buffer, zero for other indexes */
587
dict_index_is_sec_or_ibuf(
588
/*======================*/
589
const dict_index_t* index) /*!< in: index */
590
__attribute__((pure));
592
/********************************************************************//**
593
Gets the number of user-defined columns in a table in the dictionary
595
@return number of user-defined (e.g., not ROW_ID) columns of a table */
598
dict_table_get_n_user_cols(
599
/*=======================*/
600
const dict_table_t* table); /*!< in: table */
601
/********************************************************************//**
602
Gets the number of system columns in a table in the dictionary cache.
603
@return number of system (e.g., ROW_ID) columns of a table */
606
dict_table_get_n_sys_cols(
607
/*======================*/
608
const dict_table_t* table); /*!< in: table */
609
/********************************************************************//**
610
Gets the number of all columns (also system) in a table in the dictionary
612
@return number of columns of a table */
615
dict_table_get_n_cols(
616
/*==================*/
617
const dict_table_t* table); /*!< in: table */
619
/********************************************************************//**
620
Gets the nth column of a table.
621
@return pointer to column object */
624
dict_table_get_nth_col(
625
/*===================*/
626
const dict_table_t* table, /*!< in: table */
627
ulint pos); /*!< in: position of column */
628
/********************************************************************//**
629
Gets the given system column of a table.
630
@return pointer to column object */
633
dict_table_get_sys_col(
634
/*===================*/
635
const dict_table_t* table, /*!< in: table */
636
ulint sys); /*!< in: DATA_ROW_ID, ... */
637
#else /* UNIV_DEBUG */
638
#define dict_table_get_nth_col(table, pos) \
639
((table)->cols + (pos))
640
#define dict_table_get_sys_col(table, sys) \
641
((table)->cols + (table)->n_cols + (sys) - DATA_N_SYS_COLS)
642
#endif /* UNIV_DEBUG */
643
/********************************************************************//**
644
Gets the given system column number of a table.
645
@return column number */
648
dict_table_get_sys_col_no(
649
/*======================*/
650
const dict_table_t* table, /*!< in: table */
651
ulint sys); /*!< in: DATA_ROW_ID, ... */
652
#ifndef UNIV_HOTBACKUP
653
/********************************************************************//**
654
Returns the minimum data size of an index record.
655
@return minimum data size in bytes */
658
dict_index_get_min_size(
659
/*====================*/
660
const dict_index_t* index); /*!< in: index */
661
#endif /* !UNIV_HOTBACKUP */
662
/********************************************************************//**
663
Check whether the table uses the compact page format.
664
@return TRUE if table uses the compact page format */
669
const dict_table_t* table); /*!< in: table */
670
/********************************************************************//**
671
Determine the file format of a table.
672
@return file format version */
675
dict_table_get_format(
676
/*==================*/
677
const dict_table_t* table); /*!< in: table */
678
/********************************************************************//**
679
Set the file format of a table. */
682
dict_table_set_format(
683
/*==================*/
684
dict_table_t* table, /*!< in/out: table */
685
ulint format);/*!< in: file format version */
686
/********************************************************************//**
687
Extract the compressed page size from table flags.
688
@return compressed page size, or 0 if not compressed */
691
dict_table_flags_to_zip_size(
692
/*=========================*/
693
ulint flags) /*!< in: flags */
694
__attribute__((const));
695
/********************************************************************//**
696
Check whether the table uses the compressed compact page format.
697
@return compressed page size, or 0 if not compressed */
702
const dict_table_t* table); /*!< in: table */
703
/*********************************************************************//**
704
Obtain exclusive locks on all index trees of the table. This is to prevent
705
accessing index trees while InnoDB is updating internal metadata for
706
operations such as truncate tables. */
709
dict_table_x_lock_indexes(
710
/*======================*/
711
dict_table_t* table); /*!< in: table */
712
/*********************************************************************//**
713
Release the exclusive locks on all index tree. */
716
dict_table_x_unlock_indexes(
717
/*========================*/
718
dict_table_t* table); /*!< in: table */
719
/********************************************************************//**
720
Checks if a column is in the ordering columns of the clustered index of a
721
table. Column prefixes are treated like whole columns.
722
@return TRUE if the column, or its prefix, is in the clustered key */
725
dict_table_col_in_clustered_key(
726
/*============================*/
727
const dict_table_t* table, /*!< in: table */
728
ulint n); /*!< in: column number */
729
#ifndef UNIV_HOTBACKUP
730
/*******************************************************************//**
731
Copies types of columns contained in table to tuple and sets all
732
fields of the tuple to the SQL NULL value. This function should
733
be called right after dtuple_create(). */
736
dict_table_copy_types(
737
/*==================*/
738
dtuple_t* tuple, /*!< in/out: data tuple */
739
const dict_table_t* table); /*!< in: table */
740
/**********************************************************************//**
741
Looks for an index with the given id. NOTE that we do not reserve
742
the dictionary mutex: this function is for emergency purposes like
743
printing info of a corrupt database page!
744
@return index or NULL if not found from cache */
747
dict_index_find_on_id_low(
748
/*======================*/
749
index_id_t id); /*!< in: index id */
750
/**********************************************************************//**
751
Adds an index to the dictionary cache.
752
@return DB_SUCCESS, DB_TOO_BIG_RECORD, or DB_CORRUPTION */
755
dict_index_add_to_cache(
756
/*====================*/
757
dict_table_t* table, /*!< in: table on which the index is */
758
dict_index_t* index, /*!< in, own: index; NOTE! The index memory
759
object is freed in this function! */
760
ulint page_no,/*!< in: root page number of the index */
761
ibool strict);/*!< in: TRUE=refuse to create the index
762
if records could be too big to fit in
764
#endif /* !UNIV_HOTBACKUP */
765
/********************************************************************//**
766
Gets the number of fields in the internal representation of an index,
767
including fields added by the dictionary system.
768
@return number of fields */
771
dict_index_get_n_fields(
772
/*====================*/
773
const dict_index_t* index); /*!< in: an internal
774
representation of index (in
775
the dictionary cache) */
776
/********************************************************************//**
777
Gets the number of fields in the internal representation of an index
778
that uniquely determine the position of an index entry in the index, if
779
we do not take multiversioning into account: in the B-tree use the value
780
returned by dict_index_get_n_unique_in_tree.
781
@return number of fields */
784
dict_index_get_n_unique(
785
/*====================*/
786
const dict_index_t* index); /*!< in: an internal representation
787
of index (in the dictionary cache) */
788
/********************************************************************//**
789
Gets the number of fields in the internal representation of an index
790
which uniquely determine the position of an index entry in the index, if
791
we also take multiversioning into account.
792
@return number of fields */
795
dict_index_get_n_unique_in_tree(
796
/*============================*/
797
const dict_index_t* index); /*!< in: an internal representation
798
of index (in the dictionary cache) */
799
/********************************************************************//**
800
Gets the number of user-defined ordering fields in the index. In the internal
801
representation we add the row id to the ordering fields to make all indexes
802
unique, but this function returns the number of fields the user defined
803
in the index as ordering fields.
804
@return number of fields */
807
dict_index_get_n_ordering_defined_by_user(
808
/*======================================*/
809
const dict_index_t* index); /*!< in: an internal representation
810
of index (in the dictionary cache) */
812
/********************************************************************//**
813
Gets the nth field of an index.
814
@return pointer to field object */
817
dict_index_get_nth_field(
818
/*=====================*/
819
const dict_index_t* index, /*!< in: index */
820
ulint pos); /*!< in: position of field */
821
#else /* UNIV_DEBUG */
822
# define dict_index_get_nth_field(index, pos) ((index)->fields + (pos))
823
#endif /* UNIV_DEBUG */
824
/********************************************************************//**
825
Gets pointer to the nth column in an index.
829
dict_index_get_nth_col(
830
/*===================*/
831
const dict_index_t* index, /*!< in: index */
832
ulint pos); /*!< in: position of the field */
833
/********************************************************************//**
834
Gets the column number of the nth field in an index.
835
@return column number */
838
dict_index_get_nth_col_no(
839
/*======================*/
840
const dict_index_t* index, /*!< in: index */
841
ulint pos); /*!< in: position of the field */
842
/********************************************************************//**
843
Looks for column n in an index.
844
@return position in internal representation of the index;
845
ULINT_UNDEFINED if not contained */
848
dict_index_get_nth_col_pos(
849
/*=======================*/
850
const dict_index_t* index, /*!< in: index */
851
ulint n); /*!< in: column number */
852
/********************************************************************//**
853
Returns TRUE if the index contains a column or a prefix of that column.
854
@return TRUE if contains the column or its prefix */
857
dict_index_contains_col_or_prefix(
858
/*==============================*/
859
const dict_index_t* index, /*!< in: index */
860
ulint n); /*!< in: column number */
861
/********************************************************************//**
862
Looks for a matching field in an index. The column has to be the same. The
863
column in index must be complete, or must contain a prefix longer than the
864
column in index2. That is, we must be able to construct the prefix in index2
865
from the prefix in index.
866
@return position in internal representation of the index;
867
ULINT_UNDEFINED if not contained */
870
dict_index_get_nth_field_pos(
871
/*=========================*/
872
const dict_index_t* index, /*!< in: index from which to search */
873
const dict_index_t* index2, /*!< in: index */
874
ulint n); /*!< in: field number in index2 */
875
/********************************************************************//**
876
Looks for column n position in the clustered index.
877
@return position in internal representation of the clustered index */
880
dict_table_get_nth_col_pos(
881
/*=======================*/
882
const dict_table_t* table, /*!< in: table */
883
ulint n); /*!< in: column number */
884
/********************************************************************//**
885
Returns the position of a system column in an index.
886
@return position, ULINT_UNDEFINED if not contained */
889
dict_index_get_sys_col_pos(
890
/*=======================*/
891
const dict_index_t* index, /*!< in: index */
892
ulint type); /*!< in: DATA_ROW_ID, ... */
893
/*******************************************************************//**
894
Adds a column to index. */
899
dict_index_t* index, /*!< in/out: index */
900
const dict_table_t* table, /*!< in: table */
901
dict_col_t* col, /*!< in: column */
902
ulint prefix_len); /*!< in: column prefix length */
903
#ifndef UNIV_HOTBACKUP
904
/*******************************************************************//**
905
Copies types of fields contained in index to tuple. */
908
dict_index_copy_types(
909
/*==================*/
910
dtuple_t* tuple, /*!< in/out: data tuple */
911
const dict_index_t* index, /*!< in: index */
912
ulint n_fields); /*!< in: number of
913
field types to copy */
914
#endif /* !UNIV_HOTBACKUP */
915
/*********************************************************************//**
916
Gets the field column.
917
@return field->col, pointer to the table column */
922
const dict_field_t* field); /*!< in: index field */
923
#ifndef UNIV_HOTBACKUP
924
/**********************************************************************//**
925
Returns an index object if it is found in the dictionary cache.
926
Assumes that dict_sys->mutex is already being held.
927
@return index, NULL if not found */
930
dict_index_get_if_in_cache_low(
931
/*===========================*/
932
index_id_t index_id); /*!< in: index id */
933
#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
934
/**********************************************************************//**
935
Returns an index object if it is found in the dictionary cache.
936
@return index, NULL if not found */
939
dict_index_get_if_in_cache(
940
/*=======================*/
941
index_id_t index_id); /*!< in: index id */
942
#endif /* UNIV_DEBUG || UNIV_BUF_DEBUG */
944
/**********************************************************************//**
945
Checks that a tuple has n_fields_cmp value in a sensible range, so that
946
no comparison can occur with the page number field in a node pointer.
947
@return TRUE if ok */
950
dict_index_check_search_tuple(
951
/*==========================*/
952
const dict_index_t* index, /*!< in: index tree */
953
const dtuple_t* tuple); /*!< in: tuple used in a search */
954
/**********************************************************************//**
955
Check for duplicate index entries in a table [using the index name] */
958
dict_table_check_for_dup_indexes(
959
/*=============================*/
960
const dict_table_t* table, /*!< in: Check for dup indexes
962
ibool tmp_ok);/*!< in: TRUE=allow temporary
964
#endif /* UNIV_DEBUG */
965
/**********************************************************************//**
966
Builds a node pointer out of a physical record and a page number.
967
@return own: node pointer */
970
dict_index_build_node_ptr(
971
/*======================*/
972
const dict_index_t* index, /*!< in: index */
973
const rec_t* rec, /*!< in: record for which to build node
975
ulint page_no,/*!< in: page number to put in node
977
mem_heap_t* heap, /*!< in: memory heap where pointer
979
ulint level); /*!< in: level of rec in tree:
980
0 means leaf level */
981
/**********************************************************************//**
982
Copies an initial segment of a physical record, long enough to specify an
983
index entry uniquely.
984
@return pointer to the prefix record */
987
dict_index_copy_rec_order_prefix(
988
/*=============================*/
989
const dict_index_t* index, /*!< in: index */
990
const rec_t* rec, /*!< in: record for which to
992
ulint* n_fields,/*!< out: number of fields copied */
993
byte** buf, /*!< in/out: memory buffer for the
994
copied prefix, or NULL */
995
ulint* buf_size);/*!< in/out: buffer size */
996
/**********************************************************************//**
997
Builds a typed data tuple out of a physical record.
998
@return own: data tuple */
1001
dict_index_build_data_tuple(
1002
/*========================*/
1003
dict_index_t* index, /*!< in: index */
1004
rec_t* rec, /*!< in: record for which to build data tuple */
1005
ulint n_fields,/*!< in: number of data fields */
1006
mem_heap_t* heap); /*!< in: memory heap where tuple created */
1007
/*********************************************************************//**
1008
Gets the space id of the root of the index tree.
1012
dict_index_get_space(
1013
/*=================*/
1014
const dict_index_t* index); /*!< in: index */
1015
/*********************************************************************//**
1016
Sets the space id of the root of the index tree. */
1019
dict_index_set_space(
1020
/*=================*/
1021
dict_index_t* index, /*!< in/out: index */
1022
ulint space); /*!< in: space id */
1023
/*********************************************************************//**
1024
Gets the page number of the root of the index tree.
1025
@return page number */
1028
dict_index_get_page(
1029
/*================*/
1030
const dict_index_t* tree); /*!< in: index */
1031
/*********************************************************************//**
1032
Sets the page number of the root of index tree. */
1035
dict_index_set_page(
1036
/*================*/
1037
dict_index_t* index, /*!< in/out: index */
1038
ulint page); /*!< in: page number */
1039
/*********************************************************************//**
1040
Gets the read-write lock of the index tree.
1041
@return read-write lock */
1044
dict_index_get_lock(
1045
/*================*/
1046
dict_index_t* index); /*!< in: index */
1047
/********************************************************************//**
1048
Returns free space reserved for future updates of records. This is
1049
relevant only in the case of many consecutive inserts, as updates
1050
which make the records bigger might fragment the index.
1051
@return number of free bytes on page, reserved for updates */
1054
dict_index_get_space_reserve(void);
1055
/*==============================*/
1056
/*********************************************************************//**
1057
Calculates the minimum record length in an index. */
1060
dict_index_calc_min_rec_len(
1061
/*========================*/
1062
const dict_index_t* index); /*!< in: index */
1063
/*********************************************************************//**
1064
Calculates new estimates for table and index statistics. The statistics
1065
are used in query optimization. */
1068
dict_update_statistics(
1069
/*===================*/
1070
dict_table_t* table, /*!< in/out: table */
1071
ibool only_calc_if_missing_stats);/*!< in: only
1072
update/recalc the stats if they have
1073
not been initialized yet, otherwise
1075
/********************************************************************//**
1076
Reserves the dictionary system mutex for MySQL. */
1079
dict_mutex_enter_for_mysql(void);
1080
/*============================*/
1081
/********************************************************************//**
1082
Releases the dictionary system mutex for MySQL. */
1085
dict_mutex_exit_for_mysql(void);
1086
/*===========================*/
1087
/**********************************************************************//**
1088
Lock the appropriate latch to protect a given table's statistics.
1089
table->id is used to pick the corresponding latch from a global array of
1093
dict_table_stats_lock(
1094
/*==================*/
1095
const dict_table_t* table, /*!< in: table */
1096
ulint latch_mode); /*!< in: RW_S_LATCH or
1098
/**********************************************************************//**
1099
Unlock the latch that has been locked by dict_table_stats_lock() */
1102
dict_table_stats_unlock(
1103
/*====================*/
1104
const dict_table_t* table, /*!< in: table */
1105
ulint latch_mode); /*!< in: RW_S_LATCH or
1107
/********************************************************************//**
1108
Checks if the database name in two table names is the same.
1109
@return TRUE if same db name */
1112
dict_tables_have_same_db(
1113
/*=====================*/
1114
const char* name1, /*!< in: table name in the form
1115
dbname '/' tablename */
1116
const char* name2); /*!< in: table name in the form
1117
dbname '/' tablename */
1118
/*********************************************************************//**
1119
Removes an index from the cache */
1122
dict_index_remove_from_cache(
1123
/*=========================*/
1124
dict_table_t* table, /*!< in/out: table */
1125
dict_index_t* index); /*!< in, own: index */
1126
/**********************************************************************//**
1128
@return index, NULL if does not exist */
1131
dict_table_get_index_on_name(
1132
/*=========================*/
1133
dict_table_t* table, /*!< in: table */
1134
const char* name); /*!< in: name of the index to find */
1135
/**********************************************************************//**
1136
In case there is more than one index with the same name return the index
1138
@return index, NULL if does not exist */
1141
dict_table_get_index_on_name_and_min_id(
1142
/*====================================*/
1143
dict_table_t* table, /*!< in: table */
1144
const char* name); /*!< in: name of the index to find */
1145
/* Buffers for storing detailed information about the latest foreign key
1146
and unique key errors */
1147
extern FILE* dict_foreign_err_file;
1148
extern mutex_t dict_foreign_err_mutex; /* mutex protecting the buffers */
1150
/** the dictionary system */
1151
extern dict_sys_t* dict_sys;
1152
/** the data dictionary rw-latch protecting dict_sys */
1153
extern rw_lock_t dict_operation_lock;
1155
/* Dictionary system struct */
1156
struct dict_sys_struct{
1157
mutex_t mutex; /*!< mutex protecting the data
1158
dictionary; protects also the
1159
disk-based dictionary system tables;
1160
this mutex serializes CREATE TABLE
1161
and DROP TABLE, as well as reading
1162
the dictionary data for a table from
1164
row_id_t row_id; /*!< the next row id to assign;
1165
NOTE that at a checkpoint this
1166
must be written to the dict system
1167
header and flushed to a file; in
1168
recovery this must be derived from
1170
hash_table_t* table_hash; /*!< hash table of the tables, based
1172
hash_table_t* table_id_hash; /*!< hash table of the tables, based
1174
UT_LIST_BASE_NODE_T(dict_table_t)
1175
table_LRU; /*!< LRU list of tables */
1176
ulint size; /*!< varying space in bytes occupied
1177
by the data dictionary table and
1179
dict_table_t* sys_tables; /*!< SYS_TABLES table */
1180
dict_table_t* sys_columns; /*!< SYS_COLUMNS table */
1181
dict_table_t* sys_indexes; /*!< SYS_INDEXES table */
1182
dict_table_t* sys_fields; /*!< SYS_FIELDS table */
1184
#endif /* !UNIV_HOTBACKUP */
1186
/** dummy index for ROW_FORMAT=REDUNDANT supremum and infimum records */
1187
extern dict_index_t* dict_ind_redundant;
1188
/** dummy index for ROW_FORMAT=COMPACT supremum and infimum records */
1189
extern dict_index_t* dict_ind_compact;
1191
/**********************************************************************//**
1192
Inits dict_ind_redundant and dict_ind_compact. */
1195
dict_ind_init(void);
1198
/**********************************************************************//**
1199
Closes the data dictionary module. */
1206
#include "dict0dict.ic"