~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to storage/innobase/include/dict0dict.ic

  • Committer: brian
  • Date: 2008-06-25 05:29:13 UTC
  • Revision ID: brian@localhost.localdomain-20080625052913-6upwo0jsrl4lnapl
clean slate

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/**********************************************************************
 
2
Data dictionary system
 
3
 
 
4
(c) 1996 Innobase Oy
 
5
 
 
6
Created 1/8/1996 Heikki Tuuri
 
7
***********************************************************************/
 
8
 
 
9
#include "dict0load.h"
 
10
#include "trx0undo.h"
 
11
#include "trx0sys.h"
 
12
#include "rem0types.h"
 
13
#include "data0type.h"
 
14
 
 
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 */
 
23
{
 
24
        ut_ad(col && type);
 
25
 
 
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;
 
31
}
 
32
 
 
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 */
 
43
{
 
44
        ut_ad(col);
 
45
        ut_ad(type);
 
46
 
 
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);
 
52
 
 
53
        return(TRUE);
 
54
}
 
55
#endif /* UNIV_DEBUG */
 
56
 
 
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 */
 
65
{
 
66
        return(dtype_get_min_size_low(col->mtype, col->prtype, col->len,
 
67
                                      col->mbminlen, col->mbmaxlen));
 
68
}
 
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 */
 
77
{
 
78
        return(dtype_get_max_size_low(col->mtype, col->len));
 
79
}
 
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 */
 
88
{
 
89
        return(dtype_get_fixed_size_low(col->mtype, col->prtype, col->len,
 
90
                                        col->mbminlen, col->mbmaxlen));
 
91
}
 
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 */
 
102
{
 
103
        return(dict_col_get_fixed_size(col));
 
104
}
 
105
 
 
106
/*************************************************************************
 
107
Gets the column number. */
 
108
UNIV_INLINE
 
109
ulint
 
110
dict_col_get_no(
 
111
/*============*/
 
112
        const dict_col_t*       col)
 
113
{
 
114
        ut_ad(col);
 
115
 
 
116
        return(col->ind);
 
117
}
 
118
 
 
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 */
 
127
{
 
128
        ulint   i;
 
129
 
 
130
        ut_ad(col);
 
131
        ut_ad(clust_index && clust_index->type & DICT_CLUSTERED);
 
132
 
 
133
        for (i = 0; i < clust_index->n_def; i++) {
 
134
                const dict_field_t*     field = &clust_index->fields[i];
 
135
 
 
136
                if (!field->prefix_len && field->col == col) {
 
137
                        return(i);
 
138
                }
 
139
        }
 
140
 
 
141
        return(ULINT_UNDEFINED);
 
142
}
 
143
 
 
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 */
 
152
{
 
153
        ut_ad(table);
 
154
        ut_ad(table->magic_n == DICT_TABLE_MAGIC_N);
 
155
 
 
156
        return(UT_LIST_GET_FIRST(table->indexes));
 
157
}
 
158
 
 
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 */
 
167
{
 
168
        ut_ad(index);
 
169
        ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
 
170
 
 
171
        return(UT_LIST_GET_NEXT(indexes, index));
 
172
}
 
173
 
 
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 */
 
184
{
 
185
        ut_ad(table);
 
186
        ut_ad(table->magic_n == DICT_TABLE_MAGIC_N);
 
187
 
 
188
        return(table->n_cols - DATA_N_SYS_COLS);
 
189
}
 
190
 
 
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 */
 
200
{
 
201
        ut_ad(table);
 
202
        ut_ad(table->magic_n == DICT_TABLE_MAGIC_N);
 
203
        ut_ad(table->cached);
 
204
 
 
205
        return(DATA_N_SYS_COLS);
 
206
}
 
207
 
 
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 */
 
217
{
 
218
        ut_ad(table);
 
219
        ut_ad(table->magic_n == DICT_TABLE_MAGIC_N);
 
220
 
 
221
        return(table->n_cols);
 
222
}
 
223
 
 
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 */
 
233
{
 
234
        ut_ad(table);
 
235
        ut_ad(pos < table->n_def);
 
236
        ut_ad(table->magic_n == DICT_TABLE_MAGIC_N);
 
237
 
 
238
        return((table->cols) + pos);
 
239
}
 
240
 
 
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, ... */
 
250
{
 
251
        const dict_col_t*       col;
 
252
 
 
253
        ut_ad(table);
 
254
        ut_ad(sys < DATA_N_SYS_COLS);
 
255
        ut_ad(table->magic_n == DICT_TABLE_MAGIC_N);
 
256
 
 
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));
 
261
 
 
262
        return(col);
 
263
}
 
264
 
 
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, ... */
 
274
{
 
275
        ut_ad(table);
 
276
        ut_ad(sys < DATA_N_SYS_COLS);
 
277
        ut_ad(table->magic_n == DICT_TABLE_MAGIC_N);
 
278
 
 
279
        return(table->n_cols - DATA_N_SYS_COLS + sys);
 
280
}
 
281
 
 
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 */
 
291
{
 
292
        ut_ad(table);
 
293
 
 
294
#if DICT_TF_COMPACT != TRUE
 
295
#error
 
296
#endif
 
297
 
 
298
        return(UNIV_LIKELY(table->flags & DICT_TF_COMPACT));
 
299
}
 
300
 
 
301
/************************************************************************
 
302
Gets the number of fields in the internal representation of an index,
 
303
including fields added by the dictionary system. */
 
304
UNIV_INLINE
 
305
ulint
 
306
dict_index_get_n_fields(
 
307
/*====================*/
 
308
                                /* out: number of fields */
 
309
        dict_index_t*   index)  /* in: an internal representation of index
 
310
                                (in the dictionary cache) */
 
311
{
 
312
        ut_ad(index);
 
313
        ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
 
314
 
 
315
        return(index->n_fields);
 
316
}
 
317
 
 
318
/************************************************************************
 
319
Gets the number of fields in the internal representation of an index
 
320
that uniquely determine the position of an index entry in the index, if
 
321
we do not take multiversioning into account: in the B-tree use the value
 
322
returned by dict_index_get_n_unique_in_tree. */
 
323
UNIV_INLINE
 
324
ulint
 
325
dict_index_get_n_unique(
 
326
/*====================*/
 
327
                                /* out: number of fields */
 
328
        dict_index_t*   index)  /* in: an internal representation of index
 
329
                                (in the dictionary cache) */
 
330
{
 
331
        ut_ad(index);
 
332
        ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
 
333
        ut_ad(index->cached);
 
334
 
 
335
        return(index->n_uniq);
 
336
}
 
337
 
 
338
/************************************************************************
 
339
Gets the number of fields in the internal representation of an index
 
340
which uniquely determine the position of an index entry in the index, if
 
341
we also take multiversioning into account. */
 
342
UNIV_INLINE
 
343
ulint
 
344
dict_index_get_n_unique_in_tree(
 
345
/*============================*/
 
346
                                /* out: number of fields */
 
347
        dict_index_t*   index)  /* in: an internal representation of index
 
348
                                (in the dictionary cache) */
 
349
{
 
350
        ut_ad(index);
 
351
        ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
 
352
        ut_ad(index->cached);
 
353
 
 
354
        if (index->type & DICT_CLUSTERED) {
 
355
 
 
356
                return(dict_index_get_n_unique(index));
 
357
        }
 
358
 
 
359
        return(dict_index_get_n_fields(index));
 
360
}
 
361
 
 
362
/************************************************************************
 
363
Gets the number of user-defined ordering fields in the index. In the internal
 
364
representation of clustered indexes we add the row id to the ordering fields
 
365
to make a clustered index unique, but this function returns the number of
 
366
fields the user defined in the index as ordering fields. */
 
367
UNIV_INLINE
 
368
ulint
 
369
dict_index_get_n_ordering_defined_by_user(
 
370
/*======================================*/
 
371
                                /* out: number of fields */
 
372
        dict_index_t*   index)  /* in: an internal representation of index
 
373
                                (in the dictionary cache) */
 
374
{
 
375
        return(index->n_user_defined_cols);
 
376
}
 
377
 
 
378
/************************************************************************
 
379
Gets the nth field of an index. */
 
380
UNIV_INLINE
 
381
dict_field_t*
 
382
dict_index_get_nth_field(
 
383
/*=====================*/
 
384
                                /* out: pointer to field object */
 
385
        dict_index_t*   index,  /* in: index */
 
386
        ulint           pos)    /* in: position of field */
 
387
{
 
388
        ut_ad(index);
 
389
        ut_ad(pos < index->n_def);
 
390
        ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
 
391
 
 
392
        return((index->fields) + pos);
 
393
}
 
394
 
 
395
/************************************************************************
 
396
Returns the position of a system column in an index. */
 
397
UNIV_INLINE
 
398
ulint
 
399
dict_index_get_sys_col_pos(
 
400
/*=======================*/
 
401
                                /* out: position, ULINT_UNDEFINED if not
 
402
                                contained */
 
403
        dict_index_t*   index,  /* in: index */
 
404
        ulint           type)   /* in: DATA_ROW_ID, ... */
 
405
{
 
406
        ut_ad(index);
 
407
        ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
 
408
        ut_ad(!(index->type & DICT_UNIVERSAL));
 
409
 
 
410
        if (index->type & DICT_CLUSTERED) {
 
411
 
 
412
                return(dict_col_get_clust_pos(
 
413
                               dict_table_get_sys_col(index->table, type),
 
414
                               index));
 
415
        }
 
416
 
 
417
        return(dict_index_get_nth_col_pos(
 
418
                       index, dict_table_get_sys_col_no(index->table, type)));
 
419
}
 
420
 
 
421
/*************************************************************************
 
422
Gets the field column. */
 
423
UNIV_INLINE
 
424
const dict_col_t*
 
425
dict_field_get_col(
 
426
/*===============*/
 
427
        const dict_field_t*     field)
 
428
{
 
429
        ut_ad(field);
 
430
 
 
431
        return(field->col);
 
432
}
 
433
 
 
434
/************************************************************************
 
435
Gets pointer to the nth column in an index. */
 
436
UNIV_INLINE
 
437
const dict_col_t*
 
438
dict_index_get_nth_col(
 
439
/*===================*/
 
440
                                        /* out: column */
 
441
        const dict_index_t*     index,  /* in: index */
 
442
        ulint                   pos)    /* in: position of the field */
 
443
{
 
444
        return(dict_field_get_col(dict_index_get_nth_field((dict_index_t*)
 
445
                                                           index, pos)));
 
446
}
 
447
 
 
448
/************************************************************************
 
449
Gets the column number the nth field in an index. */
 
450
UNIV_INLINE
 
451
ulint
 
452
dict_index_get_nth_col_no(
 
453
/*======================*/
 
454
                                        /* out: column number */
 
455
        const dict_index_t*     index,  /* in: index */
 
456
        ulint                   pos)    /* in: position of the field */
 
457
{
 
458
        return(dict_col_get_no(dict_index_get_nth_col(index, pos)));
 
459
}
 
460
 
 
461
/*************************************************************************
 
462
Gets the space id of the root of the index tree. */
 
463
UNIV_INLINE
 
464
ulint
 
465
dict_index_get_space(
 
466
/*=================*/
 
467
                                /* out: space id */
 
468
        dict_index_t*   index)  /* in: index */
 
469
{
 
470
        ut_ad(index);
 
471
        ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
 
472
 
 
473
        return(index->space);
 
474
}
 
475
 
 
476
/*************************************************************************
 
477
Sets the space id of the root of the index tree. */
 
478
UNIV_INLINE
 
479
void
 
480
dict_index_set_space(
 
481
/*=================*/
 
482
        dict_index_t*   index,  /* in: index */
 
483
        ulint           space)  /* in: space id */
 
484
{
 
485
        ut_ad(index);
 
486
        ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
 
487
 
 
488
        index->space = space;
 
489
}
 
490
 
 
491
/*************************************************************************
 
492
Gets the page number of the root of the index tree. */
 
493
UNIV_INLINE
 
494
ulint
 
495
dict_index_get_page(
 
496
/*================*/
 
497
                                /* out: page number */
 
498
        dict_index_t*   index)  /* in: index */
 
499
{
 
500
        ut_ad(index);
 
501
        ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
 
502
 
 
503
        return(index->page);
 
504
}
 
505
 
 
506
/*************************************************************************
 
507
Sets the page number of the root of index tree. */
 
508
UNIV_INLINE
 
509
void
 
510
dict_index_set_page(
 
511
/*================*/
 
512
        dict_index_t*   index,  /* in: index */
 
513
        ulint           page)   /* in: page number */
 
514
{
 
515
        ut_ad(index);
 
516
        ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
 
517
 
 
518
        index->page = page;
 
519
}
 
520
 
 
521
/*************************************************************************
 
522
Gets the type of the index tree. */
 
523
UNIV_INLINE
 
524
ulint
 
525
dict_index_get_type(
 
526
/*================*/
 
527
                                /* out: type */
 
528
        dict_index_t*   index)  /* in: index */
 
529
{
 
530
        ut_ad(index);
 
531
        ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
 
532
 
 
533
        return(index->type);
 
534
}
 
535
 
 
536
/*************************************************************************
 
537
Gets the read-write lock of the index tree. */
 
538
UNIV_INLINE
 
539
rw_lock_t*
 
540
dict_index_get_lock(
 
541
/*================*/
 
542
                                /* out: read-write lock */
 
543
        dict_index_t*   index)  /* in: index */
 
544
{
 
545
        ut_ad(index);
 
546
        ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
 
547
 
 
548
        return(&(index->lock));
 
549
}
 
550
 
 
551
/************************************************************************
 
552
Returns free space reserved for future updates of records. This is
 
553
relevant only in the case of many consecutive inserts, as updates
 
554
which make the records bigger might fragment the index. */
 
555
UNIV_INLINE
 
556
ulint
 
557
dict_index_get_space_reserve(void)
 
558
/*==============================*/
 
559
                                /* out: number of free bytes on page,
 
560
                                reserved for updates */
 
561
{
 
562
        return(UNIV_PAGE_SIZE / 16);
 
563
}
 
564
 
 
565
/**************************************************************************
 
566
Checks if a table is in the dictionary cache. */
 
567
UNIV_INLINE
 
568
dict_table_t*
 
569
dict_table_check_if_in_cache_low(
 
570
/*=============================*/
 
571
                                        /* out: table, NULL if not found */
 
572
        const char*     table_name)     /* in: table name */
 
573
{
 
574
        dict_table_t*   table;
 
575
        ulint           table_fold;
 
576
 
 
577
        ut_ad(table_name);
 
578
        ut_ad(mutex_own(&(dict_sys->mutex)));
 
579
 
 
580
        /* Look for the table name in the hash table */
 
581
        table_fold = ut_fold_string(table_name);
 
582
 
 
583
        HASH_SEARCH(name_hash, dict_sys->table_hash, table_fold, table,
 
584
                    ut_strcmp(table->name, table_name) == 0);
 
585
        return(table);
 
586
}
 
587
 
 
588
/**************************************************************************
 
589
Gets a table; loads it to the dictionary cache if necessary. A low-level
 
590
function. */
 
591
UNIV_INLINE
 
592
dict_table_t*
 
593
dict_table_get_low(
 
594
/*===============*/
 
595
                                        /* out: table, NULL if not found */
 
596
        const char*     table_name)     /* in: table name */
 
597
{
 
598
        dict_table_t*   table;
 
599
 
 
600
        ut_ad(table_name);
 
601
        ut_ad(mutex_own(&(dict_sys->mutex)));
 
602
 
 
603
        table = dict_table_check_if_in_cache_low(table_name);
 
604
 
 
605
        if (table == NULL) {
 
606
                table = dict_load_table(table_name);
 
607
        }
 
608
 
 
609
        return(table);
 
610
}
 
611
 
 
612
/**************************************************************************
 
613
Returns a table object based on table id. */
 
614
UNIV_INLINE
 
615
dict_table_t*
 
616
dict_table_get_on_id_low(
 
617
/*=====================*/
 
618
                                /* out: table, NULL if does not exist */
 
619
        dulint  table_id)       /* in: table id */
 
620
{
 
621
        dict_table_t*   table;
 
622
        ulint           fold;
 
623
 
 
624
        ut_ad(mutex_own(&(dict_sys->mutex)));
 
625
 
 
626
        /* Look for the table name in the hash table */
 
627
        fold = ut_fold_dulint(table_id);
 
628
 
 
629
        HASH_SEARCH(id_hash, dict_sys->table_id_hash, fold, table,
 
630
                    ut_dulint_cmp(table->id, table_id) == 0);
 
631
        if (table == NULL) {
 
632
                table = dict_load_table_on_id(table_id);
 
633
        }
 
634
 
 
635
        /* TODO: should get the type information from MySQL */
 
636
 
 
637
        return(table);
 
638
}
 
639
 
 
640
/**************************************************************************
 
641
Returns an index object. */
 
642
UNIV_INLINE
 
643
dict_index_t*
 
644
dict_table_get_index(
 
645
/*=================*/
 
646
                                /* out: index, NULL if does not exist */
 
647
        dict_table_t*   table,  /* in: table */
 
648
        const char*     name)   /* in: index name */
 
649
{
 
650
        dict_index_t*   index   = NULL;
 
651
 
 
652
        index = dict_table_get_first_index(table);
 
653
 
 
654
        while (index != NULL) {
 
655
                if (ut_strcmp(name, index->name) == 0) {
 
656
 
 
657
                        break;
 
658
                }
 
659
 
 
660
                index = dict_table_get_next_index(index);
 
661
        }
 
662
 
 
663
        return(index);
 
664
}