~drizzle-trunk/drizzle/development

« back to all changes in this revision

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

Cleanup around SAFEMALLOC

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
        const 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(index, pos)));
 
445
}
 
446
 
 
447
/************************************************************************
 
448
Gets the column number the nth field in an index. */
 
449
UNIV_INLINE
 
450
ulint
 
451
dict_index_get_nth_col_no(
 
452
/*======================*/
 
453
                                        /* out: column number */
 
454
        const dict_index_t*     index,  /* in: index */
 
455
        ulint                   pos)    /* in: position of the field */
 
456
{
 
457
        return(dict_col_get_no(dict_index_get_nth_col(index, pos)));
 
458
}
 
459
 
 
460
/*************************************************************************
 
461
Gets the space id of the root of the index tree. */
 
462
UNIV_INLINE
 
463
ulint
 
464
dict_index_get_space(
 
465
/*=================*/
 
466
                                /* out: space id */
 
467
        dict_index_t*   index)  /* in: index */
 
468
{
 
469
        ut_ad(index);
 
470
        ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
 
471
 
 
472
        return(index->space);
 
473
}
 
474
 
 
475
/*************************************************************************
 
476
Sets the space id of the root of the index tree. */
 
477
UNIV_INLINE
 
478
void
 
479
dict_index_set_space(
 
480
/*=================*/
 
481
        dict_index_t*   index,  /* in: index */
 
482
        ulint           space)  /* in: space id */
 
483
{
 
484
        ut_ad(index);
 
485
        ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
 
486
 
 
487
        index->space = space;
 
488
}
 
489
 
 
490
/*************************************************************************
 
491
Gets the page number of the root of the index tree. */
 
492
UNIV_INLINE
 
493
ulint
 
494
dict_index_get_page(
 
495
/*================*/
 
496
                                /* out: page number */
 
497
        dict_index_t*   index)  /* in: index */
 
498
{
 
499
        ut_ad(index);
 
500
        ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
 
501
 
 
502
        return(index->page);
 
503
}
 
504
 
 
505
/*************************************************************************
 
506
Sets the page number of the root of index tree. */
 
507
UNIV_INLINE
 
508
void
 
509
dict_index_set_page(
 
510
/*================*/
 
511
        dict_index_t*   index,  /* in: index */
 
512
        ulint           page)   /* in: page number */
 
513
{
 
514
        ut_ad(index);
 
515
        ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
 
516
 
 
517
        index->page = page;
 
518
}
 
519
 
 
520
/*************************************************************************
 
521
Gets the type of the index tree. */
 
522
UNIV_INLINE
 
523
ulint
 
524
dict_index_get_type(
 
525
/*================*/
 
526
                                /* out: type */
 
527
        dict_index_t*   index)  /* in: index */
 
528
{
 
529
        ut_ad(index);
 
530
        ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
 
531
 
 
532
        return(index->type);
 
533
}
 
534
 
 
535
/*************************************************************************
 
536
Gets the read-write lock of the index tree. */
 
537
UNIV_INLINE
 
538
rw_lock_t*
 
539
dict_index_get_lock(
 
540
/*================*/
 
541
                                /* out: read-write lock */
 
542
        dict_index_t*   index)  /* in: index */
 
543
{
 
544
        ut_ad(index);
 
545
        ut_ad(index->magic_n == DICT_INDEX_MAGIC_N);
 
546
 
 
547
        return(&(index->lock));
 
548
}
 
549
 
 
550
/************************************************************************
 
551
Returns free space reserved for future updates of records. This is
 
552
relevant only in the case of many consecutive inserts, as updates
 
553
which make the records bigger might fragment the index. */
 
554
UNIV_INLINE
 
555
ulint
 
556
dict_index_get_space_reserve(void)
 
557
/*==============================*/
 
558
                                /* out: number of free bytes on page,
 
559
                                reserved for updates */
 
560
{
 
561
        return(UNIV_PAGE_SIZE / 16);
 
562
}
 
563
 
 
564
/**************************************************************************
 
565
Checks if a table is in the dictionary cache. */
 
566
UNIV_INLINE
 
567
dict_table_t*
 
568
dict_table_check_if_in_cache_low(
 
569
/*=============================*/
 
570
                                        /* out: table, NULL if not found */
 
571
        const char*     table_name)     /* in: table name */
 
572
{
 
573
        dict_table_t*   table;
 
574
        ulint           table_fold;
 
575
 
 
576
        ut_ad(table_name);
 
577
        ut_ad(mutex_own(&(dict_sys->mutex)));
 
578
 
 
579
        /* Look for the table name in the hash table */
 
580
        table_fold = ut_fold_string(table_name);
 
581
 
 
582
        HASH_SEARCH(name_hash, dict_sys->table_hash, table_fold, table,
 
583
                    ut_strcmp(table->name, table_name) == 0);
 
584
        return(table);
 
585
}
 
586
 
 
587
/**************************************************************************
 
588
Gets a table; loads it to the dictionary cache if necessary. A low-level
 
589
function. */
 
590
UNIV_INLINE
 
591
dict_table_t*
 
592
dict_table_get_low(
 
593
/*===============*/
 
594
                                        /* out: table, NULL if not found */
 
595
        const char*     table_name)     /* in: table name */
 
596
{
 
597
        dict_table_t*   table;
 
598
 
 
599
        ut_ad(table_name);
 
600
        ut_ad(mutex_own(&(dict_sys->mutex)));
 
601
 
 
602
        table = dict_table_check_if_in_cache_low(table_name);
 
603
 
 
604
        if (table == NULL) {
 
605
                table = dict_load_table(table_name);
 
606
        }
 
607
 
 
608
        return(table);
 
609
}
 
610
 
 
611
/**************************************************************************
 
612
Returns a table object based on table id. */
 
613
UNIV_INLINE
 
614
dict_table_t*
 
615
dict_table_get_on_id_low(
 
616
/*=====================*/
 
617
                                /* out: table, NULL if does not exist */
 
618
        dulint  table_id)       /* in: table id */
 
619
{
 
620
        dict_table_t*   table;
 
621
        ulint           fold;
 
622
 
 
623
        ut_ad(mutex_own(&(dict_sys->mutex)));
 
624
 
 
625
        /* Look for the table name in the hash table */
 
626
        fold = ut_fold_dulint(table_id);
 
627
 
 
628
        HASH_SEARCH(id_hash, dict_sys->table_id_hash, fold, table,
 
629
                    ut_dulint_cmp(table->id, table_id) == 0);
 
630
        if (table == NULL) {
 
631
                table = dict_load_table_on_id(table_id);
 
632
        }
 
633
 
 
634
        /* TODO: should get the type information from MySQL */
 
635
 
 
636
        return(table);
 
637
}
 
638
 
 
639
/**************************************************************************
 
640
Returns an index object. */
 
641
UNIV_INLINE
 
642
dict_index_t*
 
643
dict_table_get_index(
 
644
/*=================*/
 
645
                                /* out: index, NULL if does not exist */
 
646
        dict_table_t*   table,  /* in: table */
 
647
        const char*     name)   /* in: index name */
 
648
{
 
649
        dict_index_t*   index   = NULL;
 
650
 
 
651
        index = dict_table_get_first_index(table);
 
652
 
 
653
        while (index != NULL) {
 
654
                if (ut_strcmp(name, index->name) == 0) {
 
655
 
 
656
                        break;
 
657
                }
 
658
 
 
659
                index = dict_table_get_next_index(index);
 
660
        }
 
661
 
 
662
        return(index);
 
663
}