1
/**********************************************************************
6
Created 1/8/1996 Heikki Tuuri
7
***********************************************************************/
10
#include "rem0types.h"
11
#include "data0type.h"
13
/*************************************************************************
14
Gets the column data type. */
19
const dict_col_t* col, /* in: column */
20
dtype_t* type) /* out: data type */
24
type->mtype = col->mtype;
25
type->prtype = col->prtype;
27
type->mbminlen = col->mbminlen;
28
type->mbmaxlen = col->mbmaxlen;
32
/*************************************************************************
33
Assert that a column and a data type match. */
36
dict_col_type_assert_equal(
37
/*=======================*/
39
const dict_col_t* col, /* in: column */
40
const dtype_t* type) /* in: data type */
45
ut_ad(col->mtype == type->mtype);
46
ut_ad(col->prtype == type->prtype);
47
ut_ad(col->len == type->len);
48
ut_ad(col->mbminlen == type->mbminlen);
49
ut_ad(col->mbmaxlen == type->mbmaxlen);
53
#endif /* UNIV_DEBUG */
55
/***************************************************************************
56
Returns the minimum size of the column. */
59
dict_col_get_min_size(
60
/*==================*/
61
/* out: minimum size */
62
const dict_col_t* col) /* in: column */
64
return(dtype_get_min_size_low(col->mtype, col->prtype, col->len,
65
col->mbminlen, col->mbmaxlen));
67
/***************************************************************************
68
Returns the maximum size of the column. */
71
dict_col_get_max_size(
72
/*==================*/
73
/* out: maximum size */
74
const dict_col_t* col) /* in: column */
76
return(dtype_get_max_size_low(col->mtype, col->len));
78
/***************************************************************************
79
Returns the size of a fixed size column, 0 if not a fixed size column. */
82
dict_col_get_fixed_size(
83
/*====================*/
84
/* out: fixed size, or 0 */
85
const dict_col_t* col) /* in: column */
87
return(dtype_get_fixed_size_low(col->mtype, col->prtype, col->len,
88
col->mbminlen, col->mbmaxlen));
90
/***************************************************************************
91
Returns the ROW_FORMAT=REDUNDANT stored SQL NULL size of a column.
92
For fixed length types it is the fixed length of the type, otherwise 0. */
95
dict_col_get_sql_null_size(
96
/*=======================*/
97
/* out: SQL null storage size
98
in ROW_FORMAT=REDUNDANT */
99
const dict_col_t* col) /* in: column */
101
return(dict_col_get_fixed_size(col));
104
/*************************************************************************
105
Gets the column number. */
110
const dict_col_t* col)
117
/*************************************************************************
118
Gets the column position in the clustered index. */
121
dict_col_get_clust_pos(
122
/*===================*/
123
const dict_col_t* col, /* in: table column */
124
const dict_index_t* clust_index) /* in: clustered index */
130
ut_ad(dict_index_is_clust(clust_index));
132
for (i = 0; i < clust_index->n_def; i++) {
133
const dict_field_t* field = &clust_index->fields[i];
135
if (!field->prefix_len && field->col == col) {
140
return(ULINT_UNDEFINED);
144
/************************************************************************
145
Gets the first index on the table (the clustered index). */
148
dict_table_get_first_index(
149
/*=======================*/
150
/* out: index, NULL if none exists */
151
const dict_table_t* table) /* in: table */
154
ut_ad(table->magic_n == DICT_TABLE_MAGIC_N);
156
return(UT_LIST_GET_FIRST(((dict_table_t*) table)->indexes));
159
/************************************************************************
160
Gets the next index on the table. */
163
dict_table_get_next_index(
164
/*======================*/
165
/* out: index, NULL if none left */
166
const dict_index_t* index) /* in: index */
169
ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
171
return(UT_LIST_GET_NEXT(indexes, (dict_index_t*) index));
173
#endif /* UNIV_DEBUG */
175
/************************************************************************
176
Check whether the index is the clustered index. */
181
/* out: nonzero for clustered index,
182
zero for other indexes */
183
const dict_index_t* index) /* in: index */
186
ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
188
return(UNIV_UNLIKELY(index->type & DICT_CLUSTERED));
190
/************************************************************************
191
Check whether the index is unique. */
194
dict_index_is_unique(
195
/*=================*/
196
/* out: nonzero for unique index,
197
zero for other indexes */
198
const dict_index_t* index) /* in: index */
201
ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
203
return(UNIV_UNLIKELY(index->type & DICT_UNIQUE));
206
/************************************************************************
207
Check whether the index is the insert buffer tree. */
212
/* out: nonzero for insert buffer,
213
zero for other indexes */
214
const dict_index_t* index) /* in: index */
217
ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
219
return(UNIV_UNLIKELY(index->type & DICT_IBUF));
222
/************************************************************************
223
Gets the number of user-defined columns in a table in the dictionary
227
dict_table_get_n_user_cols(
228
/*=======================*/
229
/* out: number of user-defined
231
columns of a table */
232
const dict_table_t* table) /* in: table */
235
ut_ad(table->magic_n == DICT_TABLE_MAGIC_N);
237
return(table->n_cols - DATA_N_SYS_COLS);
240
/************************************************************************
241
Gets the number of system columns in a table in the dictionary cache. */
244
dict_table_get_n_sys_cols(
245
/*======================*/
246
/* out: number of system (e.g.,
247
ROW_ID) columns of a table */
248
const dict_table_t* table __attribute__((unused))) /* in: table */
251
ut_ad(table->magic_n == DICT_TABLE_MAGIC_N);
252
ut_ad(table->cached);
254
return(DATA_N_SYS_COLS);
257
/************************************************************************
258
Gets the number of all columns (also system) in a table in the dictionary
262
dict_table_get_n_cols(
263
/*==================*/
264
/* out: number of columns of a table */
265
const dict_table_t* table) /* in: table */
268
ut_ad(table->magic_n == DICT_TABLE_MAGIC_N);
270
return(table->n_cols);
274
/************************************************************************
275
Gets the nth column of a table. */
278
dict_table_get_nth_col(
279
/*===================*/
280
/* out: pointer to column object */
281
const dict_table_t* table, /* in: table */
282
ulint pos) /* in: position of column */
285
ut_ad(pos < table->n_def);
286
ut_ad(table->magic_n == DICT_TABLE_MAGIC_N);
288
return((dict_col_t*) (table->cols) + pos);
291
/************************************************************************
292
Gets the given system column of a table. */
295
dict_table_get_sys_col(
296
/*===================*/
297
/* out: pointer to column object */
298
const dict_table_t* table, /* in: table */
299
ulint sys) /* in: DATA_ROW_ID, ... */
304
ut_ad(sys < DATA_N_SYS_COLS);
305
ut_ad(table->magic_n == DICT_TABLE_MAGIC_N);
307
col = dict_table_get_nth_col(table, table->n_cols
308
- DATA_N_SYS_COLS + sys);
309
ut_ad(col->mtype == DATA_SYS);
310
ut_ad(col->prtype == (sys | DATA_NOT_NULL));
314
#endif /* UNIV_DEBUG */
316
/************************************************************************
317
Gets the given system column number of a table. */
320
dict_table_get_sys_col_no(
321
/*======================*/
322
/* out: column number */
323
const dict_table_t* table, /* in: table */
324
ulint sys) /* in: DATA_ROW_ID, ... */
327
ut_ad(sys < DATA_N_SYS_COLS);
328
ut_ad(table->magic_n == DICT_TABLE_MAGIC_N);
330
return(table->n_cols - DATA_N_SYS_COLS + sys);
333
/************************************************************************
334
Check whether the table uses the compact page format. */
339
/* out: TRUE if table uses the
340
compact page format */
341
const dict_table_t* table) /* in: table */
345
#if DICT_TF_COMPACT != TRUE
349
return(UNIV_LIKELY(table->flags & DICT_TF_COMPACT));
352
/************************************************************************
353
Determine the file format of a table. */
356
dict_table_get_format(
357
/*==================*/
358
/* out: file format version */
359
const dict_table_t* table) /* in: table */
363
return((table->flags & DICT_TF_FORMAT_MASK) >> DICT_TF_FORMAT_SHIFT);
366
/************************************************************************
367
Determine the file format of a table. */
370
dict_table_set_format(
371
/*==================*/
372
dict_table_t* table, /* in/out: table */
373
ulint format) /* in: file format version */
377
table->flags = (table->flags & ~DICT_TF_FORMAT_MASK)
378
| (format << DICT_TF_FORMAT_SHIFT);
381
/************************************************************************
382
Extract the compressed page size from table flags. */
385
dict_table_flags_to_zip_size(
386
/*=========================*/
387
/* out: compressed page size,
388
or 0 if not compressed */
389
ulint flags) /* in: flags */
391
ulint zip_size = flags & DICT_TF_ZSSIZE_MASK;
393
if (UNIV_UNLIKELY(zip_size)) {
394
zip_size = ((PAGE_ZIP_MIN_SIZE >> 1)
395
<< (zip_size >> DICT_TF_ZSSIZE_SHIFT));
397
ut_ad(zip_size <= UNIV_PAGE_SIZE);
403
/************************************************************************
404
Check whether the table uses the compressed compact page format. */
409
/* out: compressed page size,
410
or 0 if not compressed */
411
const dict_table_t* table) /* in: table */
415
return(dict_table_flags_to_zip_size(table->flags));
418
/************************************************************************
419
Gets the number of fields in the internal representation of an index,
420
including fields added by the dictionary system. */
423
dict_index_get_n_fields(
424
/*====================*/
425
/* out: number of fields */
426
const dict_index_t* index) /* in: an internal
427
representation of index (in
428
the dictionary cache) */
431
ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
433
return(index->n_fields);
436
/************************************************************************
437
Gets the number of fields in the internal representation of an index
438
that uniquely determine the position of an index entry in the index, if
439
we do not take multiversioning into account: in the B-tree use the value
440
returned by dict_index_get_n_unique_in_tree. */
443
dict_index_get_n_unique(
444
/*====================*/
445
/* out: number of fields */
446
const dict_index_t* index) /* in: an internal representation
447
of index (in the dictionary cache) */
450
ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
451
ut_ad(index->cached);
453
return(index->n_uniq);
456
/************************************************************************
457
Gets the number of fields in the internal representation of an index
458
which uniquely determine the position of an index entry in the index, if
459
we also take multiversioning into account. */
462
dict_index_get_n_unique_in_tree(
463
/*============================*/
464
/* out: number of fields */
465
const dict_index_t* index) /* in: an internal representation
466
of index (in the dictionary cache) */
469
ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
470
ut_ad(index->cached);
472
if (dict_index_is_clust(index)) {
474
return(dict_index_get_n_unique(index));
477
return(dict_index_get_n_fields(index));
480
/************************************************************************
481
Gets the number of user-defined ordering fields in the index. In the internal
482
representation of clustered indexes we add the row id to the ordering fields
483
to make a clustered index unique, but this function returns the number of
484
fields the user defined in the index as ordering fields. */
487
dict_index_get_n_ordering_defined_by_user(
488
/*======================================*/
489
/* out: number of fields */
490
const dict_index_t* index) /* in: an internal representation
491
of index (in the dictionary cache) */
493
return(index->n_user_defined_cols);
497
/************************************************************************
498
Gets the nth field of an index. */
501
dict_index_get_nth_field(
502
/*=====================*/
503
/* out: pointer to field object */
504
const dict_index_t* index, /* in: index */
505
ulint pos) /* in: position of field */
508
ut_ad(pos < index->n_def);
509
ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
511
return((dict_field_t*) (index->fields) + pos);
513
#endif /* UNIV_DEBUG */
515
/************************************************************************
516
Returns the position of a system column in an index. */
519
dict_index_get_sys_col_pos(
520
/*=======================*/
522
ULINT_UNDEFINED if not contained */
523
const dict_index_t* index, /* in: index */
524
ulint type) /* in: DATA_ROW_ID, ... */
527
ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
528
ut_ad(!(index->type & DICT_UNIVERSAL));
530
if (dict_index_is_clust(index)) {
532
return(dict_col_get_clust_pos(
533
dict_table_get_sys_col(index->table, type),
537
return(dict_index_get_nth_col_pos(
538
index, dict_table_get_sys_col_no(index->table, type)));
541
/*************************************************************************
542
Gets the field column. */
547
const dict_field_t* field)
554
/************************************************************************
555
Gets pointer to the nth column in an index. */
558
dict_index_get_nth_col(
559
/*===================*/
561
const dict_index_t* index, /* in: index */
562
ulint pos) /* in: position of the field */
564
return(dict_field_get_col(dict_index_get_nth_field(index, pos)));
567
/************************************************************************
568
Gets the column number the nth field in an index. */
571
dict_index_get_nth_col_no(
572
/*======================*/
573
/* out: column number */
574
const dict_index_t* index, /* in: index */
575
ulint pos) /* in: position of the field */
577
return(dict_col_get_no(dict_index_get_nth_col(index, pos)));
580
/************************************************************************
581
Returns the minimum data size of an index record. */
584
dict_index_get_min_size(
585
/*====================*/
586
/* out: minimum data size in bytes */
587
const dict_index_t* index) /* in: index */
589
ulint n = dict_index_get_n_fields(index);
593
size += dict_col_get_min_size(dict_index_get_nth_col(index,
600
/*************************************************************************
601
Gets the space id of the root of the index tree. */
604
dict_index_get_space(
605
/*=================*/
607
const dict_index_t* index) /* in: index */
610
ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
612
return(index->space);
615
/*************************************************************************
616
Sets the space id of the root of the index tree. */
619
dict_index_set_space(
620
/*=================*/
621
dict_index_t* index, /* in/out: index */
622
ulint space) /* in: space id */
625
ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
627
index->space = space;
630
/*************************************************************************
631
Gets the page number of the root of the index tree. */
636
/* out: page number */
637
const dict_index_t* index) /* in: index */
640
ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
645
/*************************************************************************
646
Sets the page number of the root of index tree. */
651
dict_index_t* index, /* in/out: index */
652
ulint page) /* in: page number */
655
ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
660
/*************************************************************************
661
Gets the type of the index tree. */
667
const dict_index_t* index) /* in: index */
670
ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
675
/*************************************************************************
676
Gets the read-write lock of the index tree. */
681
/* out: read-write lock */
682
dict_index_t* index) /* in: index */
685
ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
687
return(&(index->lock));
690
/************************************************************************
691
Returns free space reserved for future updates of records. This is
692
relevant only in the case of many consecutive inserts, as updates
693
which make the records bigger might fragment the index. */
696
dict_index_get_space_reserve(void)
697
/*==============================*/
698
/* out: number of free bytes on page,
699
reserved for updates */
701
return(UNIV_PAGE_SIZE / 16);
704
/**************************************************************************
705
Checks if a table is in the dictionary cache. */
708
dict_table_check_if_in_cache_low(
709
/*=============================*/
710
/* out: table, NULL if not found */
711
const char* table_name) /* in: table name */
717
ut_ad(mutex_own(&(dict_sys->mutex)));
719
/* Look for the table name in the hash table */
720
table_fold = ut_fold_string(table_name);
722
HASH_SEARCH(name_hash, dict_sys->table_hash, table_fold,
723
dict_table_t*, table, !strcmp(table->name, table_name));
727
/**************************************************************************
728
Gets a table; loads it to the dictionary cache if necessary. A low-level
734
/* out: table, NULL if not found */
735
const char* table_name) /* in: table name */
740
ut_ad(mutex_own(&(dict_sys->mutex)));
742
table = dict_table_check_if_in_cache_low(table_name);
745
table = dict_load_table(table_name);
751
/**************************************************************************
752
Returns a table object based on table id. */
755
dict_table_get_on_id_low(
756
/*=====================*/
757
/* out: table, NULL if does not exist */
758
dulint table_id) /* in: table id */
763
ut_ad(mutex_own(&(dict_sys->mutex)));
765
/* Look for the table name in the hash table */
766
fold = ut_fold_dulint(table_id);
768
HASH_SEARCH(id_hash, dict_sys->table_id_hash, fold,
769
dict_table_t*, table, !ut_dulint_cmp(table->id, table_id));
771
table = dict_load_table_on_id(table_id);
774
/* TODO: should get the type information from MySQL */