mySQL 5.0.11 sources for tomato
[tomato.git] / release / src / router / mysql / storage / innobase / include / dict0dict.ic
blob5cdbdbeb03d3ea3e5eeb9380df82161693ff3683
1 /**********************************************************************
2 Data dictionary system
4 (c) 1996 Innobase Oy
6 Created 1/8/1996 Heikki Tuuri
7 ***********************************************************************/
9 #include "dict0load.h"
10 #include "trx0undo.h"
11 #include "trx0sys.h"
12 #include "rem0types.h"
13 #include "data0type.h"
15 /*************************************************************************
16 Gets the column data type. */
17 UNIV_INLINE
18 void
19 dict_col_copy_type(
20 /*===============*/
21         const dict_col_t*       col,    /* in: column */
22         dtype_t*                type)   /* out: data type */
24         ut_ad(col && type);
26         type->mtype = col->mtype;
27         type->prtype = col->prtype;
28         type->len = col->len;
29         type->mbminlen = col->mbminlen;
30         type->mbmaxlen = col->mbmaxlen;
33 #ifdef UNIV_DEBUG
34 /*************************************************************************
35 Assert that a column and a data type match. */
36 UNIV_INLINE
37 ibool
38 dict_col_type_assert_equal(
39 /*=======================*/
40                                         /* out: TRUE */
41         const dict_col_t*       col,    /* in: column */
42         const dtype_t*          type)   /* in: data type */
44         ut_ad(col);
45         ut_ad(type);
47         ut_ad(col->mtype == type->mtype);
48         ut_ad(col->prtype == type->prtype);
49         ut_ad(col->len == type->len);
50         ut_ad(col->mbminlen == type->mbminlen);
51         ut_ad(col->mbmaxlen == type->mbmaxlen);
53         return(TRUE);
55 #endif /* UNIV_DEBUG */
57 /***************************************************************************
58 Returns the minimum size of the column. */
59 UNIV_INLINE
60 ulint
61 dict_col_get_min_size(
62 /*==================*/
63                                         /* out: minimum size */
64         const dict_col_t*       col)    /* in: column */
66         return(dtype_get_min_size_low(col->mtype, col->prtype, col->len,
67                                       col->mbminlen, col->mbmaxlen));
69 /***************************************************************************
70 Returns the maximum size of the column. */
71 UNIV_INLINE
72 ulint
73 dict_col_get_max_size(
74 /*==================*/
75                                         /* out: maximum size */
76         const dict_col_t*       col)    /* in: column */
78         return(dtype_get_max_size_low(col->mtype, col->len));
80 /***************************************************************************
81 Returns the size of a fixed size column, 0 if not a fixed size column. */
82 UNIV_INLINE
83 ulint
84 dict_col_get_fixed_size(
85 /*====================*/
86                                         /* out: fixed size, or 0 */
87         const dict_col_t*       col)    /* in: column */
89         return(dtype_get_fixed_size_low(col->mtype, col->prtype, col->len,
90                                         col->mbminlen, col->mbmaxlen));
92 /***************************************************************************
93 Returns the ROW_FORMAT=REDUNDANT stored SQL NULL size of a column.
94 For fixed length types it is the fixed length of the type, otherwise 0. */
95 UNIV_INLINE
96 ulint
97 dict_col_get_sql_null_size(
98 /*=======================*/
99                                         /* out: SQL null storage size
100                                         in ROW_FORMAT=REDUNDANT */
101         const dict_col_t*       col)    /* in: column */
103         return(dict_col_get_fixed_size(col));
106 /*************************************************************************
107 Gets the column number. */
108 UNIV_INLINE
109 ulint
110 dict_col_get_no(
111 /*============*/
112         const dict_col_t*       col)
114         ut_ad(col);
116         return(col->ind);
119 /*************************************************************************
120 Gets the column position in the clustered index. */
121 UNIV_INLINE
122 ulint
123 dict_col_get_clust_pos(
124 /*===================*/
125         const dict_col_t*       col,            /* in: table column */
126         const dict_index_t*     clust_index)    /* in: clustered index */
128         ulint   i;
130         ut_ad(col);
131         ut_ad(clust_index && clust_index->type & DICT_CLUSTERED);
133         for (i = 0; i < clust_index->n_def; i++) {
134                 const dict_field_t*     field = &clust_index->fields[i];
136                 if (!field->prefix_len && field->col == col) {
137                         return(i);
138                 }
139         }
141         return(ULINT_UNDEFINED);
144 /************************************************************************
145 Gets the first index on the table (the clustered index). */
146 UNIV_INLINE
147 dict_index_t*
148 dict_table_get_first_index(
149 /*=======================*/
150                                 /* out: index, NULL if none exists */
151         dict_table_t*   table)  /* in: table */
153         ut_ad(table);
154         ut_ad(table->magic_n == DICT_TABLE_MAGIC_N);
156         return(UT_LIST_GET_FIRST(table->indexes));
159 /************************************************************************
160 Gets the next index on the table. */
161 UNIV_INLINE
162 dict_index_t*
163 dict_table_get_next_index(
164 /*======================*/
165                                 /* out: index, NULL if none left */
166         dict_index_t*   index)  /* in: index */
168         ut_ad(index);
169         ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
171         return(UT_LIST_GET_NEXT(indexes, index));
174 /************************************************************************
175 Gets the number of user-defined columns in a table in the dictionary
176 cache. */
177 UNIV_INLINE
178 ulint
179 dict_table_get_n_user_cols(
180 /*=======================*/
181                                 /* out: number of user-defined (e.g., not
182                                 ROW_ID) columns of a table */
183         dict_table_t*   table)  /* in: table */
185         ut_ad(table);
186         ut_ad(table->magic_n == DICT_TABLE_MAGIC_N);
188         return(table->n_cols - DATA_N_SYS_COLS);
191 /************************************************************************
192 Gets the number of system columns in a table in the dictionary cache. */
193 UNIV_INLINE
194 ulint
195 dict_table_get_n_sys_cols(
196 /*======================*/
197                                 /* out: number of system (e.g.,
198                                 ROW_ID) columns of a table */
199         dict_table_t*   table __attribute__((unused)))  /* in: table */
201         ut_ad(table);
202         ut_ad(table->magic_n == DICT_TABLE_MAGIC_N);
203         ut_ad(table->cached);
205         return(DATA_N_SYS_COLS);
208 /************************************************************************
209 Gets the number of all columns (also system) in a table in the dictionary
210 cache. */
211 UNIV_INLINE
212 ulint
213 dict_table_get_n_cols(
214 /*==================*/
215                                 /* out: number of columns of a table */
216         dict_table_t*   table)  /* in: table */
218         ut_ad(table);
219         ut_ad(table->magic_n == DICT_TABLE_MAGIC_N);
221         return(table->n_cols);
224 /************************************************************************
225 Gets the nth column of a table. */
226 UNIV_INLINE
227 const dict_col_t*
228 dict_table_get_nth_col(
229 /*===================*/
230                                         /* out: pointer to column object */
231         const dict_table_t*     table,  /* in: table */
232         ulint                   pos)    /* in: position of column */
234         ut_ad(table);
235         ut_ad(pos < table->n_def);
236         ut_ad(table->magic_n == DICT_TABLE_MAGIC_N);
238         return((table->cols) + pos);
241 /************************************************************************
242 Gets the given system column of a table. */
243 UNIV_INLINE
244 const dict_col_t*
245 dict_table_get_sys_col(
246 /*===================*/
247                                         /* out: pointer to column object */
248         const dict_table_t*     table,  /* in: table */
249         ulint                   sys)    /* in: DATA_ROW_ID, ... */
251         const dict_col_t*       col;
253         ut_ad(table);
254         ut_ad(sys < DATA_N_SYS_COLS);
255         ut_ad(table->magic_n == DICT_TABLE_MAGIC_N);
257         col = dict_table_get_nth_col(table, table->n_cols
258                                      - DATA_N_SYS_COLS + sys);
259         ut_ad(col->mtype == DATA_SYS);
260         ut_ad(col->prtype == (sys | DATA_NOT_NULL));
262         return(col);
265 /************************************************************************
266 Gets the given system column number of a table. */
267 UNIV_INLINE
268 ulint
269 dict_table_get_sys_col_no(
270 /*======================*/
271                                 /* out: column number */
272         dict_table_t*   table,  /* in: table */
273         ulint           sys)    /* in: DATA_ROW_ID, ... */
275         ut_ad(table);
276         ut_ad(sys < DATA_N_SYS_COLS);
277         ut_ad(table->magic_n == DICT_TABLE_MAGIC_N);
279         return(table->n_cols - DATA_N_SYS_COLS + sys);
282 /************************************************************************
283 Check whether the table uses the compact page format. */
284 UNIV_INLINE
285 ibool
286 dict_table_is_comp(
287 /*===============*/
288                                         /* out: TRUE if table uses the
289                                         compact page format */
290         const dict_table_t*     table)  /* in: table */
292         ut_ad(table);
294 #if DICT_TF_COMPACT != TRUE
295 #error
296 #endif
298         return(UNIV_LIKELY(table->flags & DICT_TF_COMPACT));
301 /*********************************************************************//**
302 Obtain exclusive locks on all index trees of the table. This is to prevent
303 accessing index trees while InnoDB is updating internal metadata for
304 operations such as truncate tables. */
305 UNIV_INLINE
306 void
307 dict_table_x_lock_indexes(
308 /*======================*/
309         dict_table_t*   table)  /* in: table */
311         dict_index_t*   index;
313         ut_a(table);
314         ut_ad(mutex_own(&(dict_sys->mutex)));
316         /* Loop through each index of the table and lock them */
317         for (index = dict_table_get_first_index(table);
318              index != NULL;
319              index = dict_table_get_next_index(index)) {
320                 rw_lock_x_lock(dict_index_get_lock(index));
321         }
324 /*********************************************************************//**
325 Release the exclusive locks on all index tree. */
326 UNIV_INLINE
327 void
328 dict_table_x_unlock_indexes(
329 /*========================*/
330         dict_table_t*   table)  /* in: table */
332         dict_index_t*   index;
334         ut_a(table);
335         ut_ad(mutex_own(&(dict_sys->mutex)));
337         for (index = dict_table_get_first_index(table);
338              index != NULL;
339              index = dict_table_get_next_index(index)) {
340                 rw_lock_x_unlock(dict_index_get_lock(index));
341         }
343 /************************************************************************
344 Gets the number of fields in the internal representation of an index,
345 including fields added by the dictionary system. */
346 UNIV_INLINE
347 ulint
348 dict_index_get_n_fields(
349 /*====================*/
350                                 /* out: number of fields */
351         dict_index_t*   index)  /* in: an internal representation of index
352                                 (in the dictionary cache) */
354         ut_ad(index);
355         ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
357         return(index->n_fields);
360 /************************************************************************
361 Gets the number of fields in the internal representation of an index
362 that uniquely determine the position of an index entry in the index, if
363 we do not take multiversioning into account: in the B-tree use the value
364 returned by dict_index_get_n_unique_in_tree. */
365 UNIV_INLINE
366 ulint
367 dict_index_get_n_unique(
368 /*====================*/
369                                 /* out: number of fields */
370         dict_index_t*   index)  /* in: an internal representation of index
371                                 (in the dictionary cache) */
373         ut_ad(index);
374         ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
375         ut_ad(index->cached);
377         return(index->n_uniq);
380 /************************************************************************
381 Gets the number of fields in the internal representation of an index
382 which uniquely determine the position of an index entry in the index, if
383 we also take multiversioning into account. */
384 UNIV_INLINE
385 ulint
386 dict_index_get_n_unique_in_tree(
387 /*============================*/
388                                 /* out: number of fields */
389         dict_index_t*   index)  /* in: an internal representation of index
390                                 (in the dictionary cache) */
392         ut_ad(index);
393         ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
394         ut_ad(index->cached);
396         if (index->type & DICT_CLUSTERED) {
398                 return(dict_index_get_n_unique(index));
399         }
401         return(dict_index_get_n_fields(index));
404 /************************************************************************
405 Gets the number of user-defined ordering fields in the index. In the internal
406 representation of clustered indexes we add the row id to the ordering fields
407 to make a clustered index unique, but this function returns the number of
408 fields the user defined in the index as ordering fields. */
409 UNIV_INLINE
410 ulint
411 dict_index_get_n_ordering_defined_by_user(
412 /*======================================*/
413                                 /* out: number of fields */
414         dict_index_t*   index)  /* in: an internal representation of index
415                                 (in the dictionary cache) */
417         return(index->n_user_defined_cols);
420 /************************************************************************
421 Gets the nth field of an index. */
422 UNIV_INLINE
423 dict_field_t*
424 dict_index_get_nth_field(
425 /*=====================*/
426                                 /* out: pointer to field object */
427         dict_index_t*   index,  /* in: index */
428         ulint           pos)    /* in: position of field */
430         ut_ad(index);
431         ut_ad(pos < index->n_def);
432         ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
434         return((index->fields) + pos);
437 /************************************************************************
438 Returns the position of a system column in an index. */
439 UNIV_INLINE
440 ulint
441 dict_index_get_sys_col_pos(
442 /*=======================*/
443                                 /* out: position, ULINT_UNDEFINED if not
444                                 contained */
445         dict_index_t*   index,  /* in: index */
446         ulint           type)   /* in: DATA_ROW_ID, ... */
448         ut_ad(index);
449         ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
450         ut_ad(!(index->type & DICT_UNIVERSAL));
452         if (index->type & DICT_CLUSTERED) {
454                 return(dict_col_get_clust_pos(
455                                dict_table_get_sys_col(index->table, type),
456                                index));
457         }
459         return(dict_index_get_nth_col_pos(
460                        index, dict_table_get_sys_col_no(index->table, type)));
463 /*************************************************************************
464 Gets the field column. */
465 UNIV_INLINE
466 const dict_col_t*
467 dict_field_get_col(
468 /*===============*/
469         const dict_field_t*     field)
471         ut_ad(field);
473         return(field->col);
476 /************************************************************************
477 Gets pointer to the nth column in an index. */
478 UNIV_INLINE
479 const dict_col_t*
480 dict_index_get_nth_col(
481 /*===================*/
482                                         /* out: column */
483         const dict_index_t*     index,  /* in: index */
484         ulint                   pos)    /* in: position of the field */
486         return(dict_field_get_col(dict_index_get_nth_field((dict_index_t*)
487                                                            index, pos)));
490 /************************************************************************
491 Gets the column number the nth field in an index. */
492 UNIV_INLINE
493 ulint
494 dict_index_get_nth_col_no(
495 /*======================*/
496                                         /* out: column number */
497         const dict_index_t*     index,  /* in: index */
498         ulint                   pos)    /* in: position of the field */
500         return(dict_col_get_no(dict_index_get_nth_col(index, pos)));
503 /*************************************************************************
504 Gets the space id of the root of the index tree. */
505 UNIV_INLINE
506 ulint
507 dict_index_get_space(
508 /*=================*/
509                                 /* out: space id */
510         dict_index_t*   index)  /* in: index */
512         ut_ad(index);
513         ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
515         return(index->space);
518 /*************************************************************************
519 Sets the space id of the root of the index tree. */
520 UNIV_INLINE
521 void
522 dict_index_set_space(
523 /*=================*/
524         dict_index_t*   index,  /* in: index */
525         ulint           space)  /* in: space id */
527         ut_ad(index);
528         ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
530         index->space = space;
533 /*************************************************************************
534 Gets the page number of the root of the index tree. */
535 UNIV_INLINE
536 ulint
537 dict_index_get_page(
538 /*================*/
539                                 /* out: page number */
540         dict_index_t*   index)  /* in: index */
542         ut_ad(index);
543         ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
545         return(index->page);
548 /*************************************************************************
549 Sets the page number of the root of index tree. */
550 UNIV_INLINE
551 void
552 dict_index_set_page(
553 /*================*/
554         dict_index_t*   index,  /* in: index */
555         ulint           page)   /* in: page number */
557         ut_ad(index);
558         ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
560         index->page = page;
563 /*************************************************************************
564 Gets the type of the index tree. */
565 UNIV_INLINE
566 ulint
567 dict_index_get_type(
568 /*================*/
569                                 /* out: type */
570         dict_index_t*   index)  /* in: index */
572         ut_ad(index);
573         ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
575         return(index->type);
578 /*************************************************************************
579 Gets the read-write lock of the index tree. */
580 UNIV_INLINE
581 rw_lock_t*
582 dict_index_get_lock(
583 /*================*/
584                                 /* out: read-write lock */
585         dict_index_t*   index)  /* in: index */
587         ut_ad(index);
588         ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
590         return(&(index->lock));
593 /************************************************************************
594 Returns free space reserved for future updates of records. This is
595 relevant only in the case of many consecutive inserts, as updates
596 which make the records bigger might fragment the index. */
597 UNIV_INLINE
598 ulint
599 dict_index_get_space_reserve(void)
600 /*==============================*/
601                                 /* out: number of free bytes on page,
602                                 reserved for updates */
604         return(UNIV_PAGE_SIZE / 16);
607 /**************************************************************************
608 Checks if a table is in the dictionary cache. */
609 UNIV_INLINE
610 dict_table_t*
611 dict_table_check_if_in_cache_low(
612 /*=============================*/
613                                         /* out: table, NULL if not found */
614         const char*     table_name)     /* in: table name */
616         dict_table_t*   table;
617         ulint           table_fold;
619         ut_ad(table_name);
620         ut_ad(mutex_own(&(dict_sys->mutex)));
622         /* Look for the table name in the hash table */
623         table_fold = ut_fold_string(table_name);
625         HASH_SEARCH(name_hash, dict_sys->table_hash, table_fold, table,
626                     ut_strcmp(table->name, table_name) == 0);
627         return(table);
630 /**************************************************************************
631 Gets a table; loads it to the dictionary cache if necessary. A low-level
632 function. */
633 UNIV_INLINE
634 dict_table_t*
635 dict_table_get_low(
636 /*===============*/
637                                         /* out: table, NULL if not found */
638         const char*     table_name)     /* in: table name */
640         dict_table_t*   table;
642         ut_ad(table_name);
643         ut_ad(mutex_own(&(dict_sys->mutex)));
645         table = dict_table_check_if_in_cache_low(table_name);
647         if (table == NULL) {
648                 table = dict_load_table(table_name);
649         }
651         return(table);
654 /**************************************************************************
655 Returns a table object based on table id. */
656 UNIV_INLINE
657 dict_table_t*
658 dict_table_get_on_id_low(
659 /*=====================*/
660                                 /* out: table, NULL if does not exist */
661         dulint  table_id)       /* in: table id */
663         dict_table_t*   table;
664         ulint           fold;
666         ut_ad(mutex_own(&(dict_sys->mutex)));
668         /* Look for the table name in the hash table */
669         fold = ut_fold_dulint(table_id);
671         HASH_SEARCH(id_hash, dict_sys->table_id_hash, fold, table,
672                     ut_dulint_cmp(table->id, table_id) == 0);
673         if (table == NULL) {
674                 table = dict_load_table_on_id(table_id);
675         }
677         /* TODO: should get the type information from MySQL */
679         return(table);
682 /**************************************************************************
683 Returns an index object. */
684 UNIV_INLINE
685 dict_index_t*
686 dict_table_get_index(
687 /*=================*/
688                                 /* out: index, NULL if does not exist */
689         dict_table_t*   table,  /* in: table */
690         const char*     name)   /* in: index name */
692         dict_index_t*   index   = NULL;
694         index = dict_table_get_first_index(table);
696         while (index != NULL) {
697                 if (ut_strcmp(name, index->name) == 0) {
699                         break;
700                 }
702                 index = dict_table_get_next_index(index);
703         }
705         return(index);