1
/*****************************************************************************
3
Copyright (C) 1996, 2010, 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 dict/dict0crea.c
1
/******************************************************
21
2
Database object creation
23
6
Created 1/8/1996 Heikki Tuuri
24
7
*******************************************************/
43
26
#include "usr0sess.h"
44
27
#include "ut0vec.h"
46
/*****************************************************************//**
29
/*********************************************************************
47
30
Based on a table object, this function builds the entry to be inserted
48
in the SYS_TABLES system table.
49
@return the tuple which should be inserted */
31
in the SYS_TABLES system table. */
52
34
dict_create_sys_tables_tuple(
53
35
/*=========================*/
54
const dict_table_t* table, /*!< in: table */
55
mem_heap_t* heap) /*!< in: memory heap from
56
which the memory for the built
36
/* out: the tuple which should be inserted */
37
dict_table_t* table, /* in: table */
38
mem_heap_t* heap) /* in: memory heap from which the memory for
39
the built tuple is allocated */
59
41
dict_table_t* sys_tables;
67
48
sys_tables = dict_sys->sys_tables;
71
52
dict_table_copy_types(entry, sys_tables);
73
54
/* 0: NAME -----------------------------*/
74
dfield = dtuple_get_nth_field(entry, 0/*NAME*/);
55
dfield = dtuple_get_nth_field(entry, 0);
76
57
dfield_set_data(dfield, table->name, ut_strlen(table->name));
77
58
/* 3: ID -------------------------------*/
78
dfield = dtuple_get_nth_field(entry, 1/*ID*/);
59
dfield = dtuple_get_nth_field(entry, 1);
80
ptr = static_cast<unsigned char *>(mem_heap_alloc(heap, 8));
61
ptr = mem_heap_alloc(heap, 8);
81
62
mach_write_to_8(ptr, table->id);
83
64
dfield_set_data(dfield, ptr, 8);
84
65
/* 4: N_COLS ---------------------------*/
85
dfield = dtuple_get_nth_field(entry, 2/*N_COLS*/);
66
dfield = dtuple_get_nth_field(entry, 2);
87
68
#if DICT_TF_COMPACT != 1
91
ptr = static_cast<unsigned char *>(mem_heap_alloc(heap, 4));
72
ptr = mem_heap_alloc(heap, 4);
92
73
mach_write_to_4(ptr, table->n_def
93
74
| ((table->flags & DICT_TF_COMPACT) << 31));
94
75
dfield_set_data(dfield, ptr, 4);
95
76
/* 5: TYPE -----------------------------*/
96
dfield = dtuple_get_nth_field(entry, 3/*TYPE*/);
77
dfield = dtuple_get_nth_field(entry, 3);
98
ptr = static_cast<unsigned char *>(mem_heap_alloc(heap, 4));
99
if (table->flags & (~DICT_TF_COMPACT & ~(~0 << DICT_TF_BITS))) {
79
ptr = mem_heap_alloc(heap, 4);
80
if (table->flags & ~DICT_TF_COMPACT) {
100
81
ut_a(table->flags & DICT_TF_COMPACT);
101
82
ut_a(dict_table_get_format(table) >= DICT_TF_FORMAT_ZIP);
102
83
ut_a((table->flags & DICT_TF_ZSSIZE_MASK)
103
84
<= (DICT_TF_ZSSIZE_MAX << DICT_TF_ZSSIZE_SHIFT));
104
ut_a(!(table->flags & (~0 << DICT_TF2_BITS)));
105
mach_write_to_4(ptr, table->flags & ~(~0 << DICT_TF_BITS));
85
ut_a(!(table->flags & (~0 << DICT_TF_BITS)));
86
mach_write_to_4(ptr, table->flags);
107
88
mach_write_to_4(ptr, DICT_TABLE_ORDINARY);
110
91
dfield_set_data(dfield, ptr, 4);
111
92
/* 6: MIX_ID (obsolete) ---------------------------*/
112
dfield = dtuple_get_nth_field(entry, 4/*MIX_ID*/);
93
dfield = dtuple_get_nth_field(entry, 4);
114
ptr = static_cast<unsigned char *>(mem_heap_zalloc(heap, 8));
95
ptr = mem_heap_zalloc(heap, 8);
116
97
dfield_set_data(dfield, ptr, 8);
117
/* 7: MIX_LEN (additional flags) --------------------------*/
119
dfield = dtuple_get_nth_field(entry, 5/*MIX_LEN*/);
121
ptr = static_cast<unsigned char *>(mem_heap_alloc(heap, 4));
122
mach_write_to_4(ptr, table->flags >> DICT_TF2_SHIFT);
98
/* 7: MIX_LEN (obsolete) --------------------------*/
100
dfield = dtuple_get_nth_field(entry, 5);
102
ptr = mem_heap_zalloc(heap, 4);
124
104
dfield_set_data(dfield, ptr, 4);
125
105
/* 8: CLUSTER_NAME ---------------------*/
126
dfield = dtuple_get_nth_field(entry, 6/*CLUSTER_NAME*/);
106
dfield = dtuple_get_nth_field(entry, 6);
127
107
dfield_set_null(dfield); /* not supported */
129
109
/* 9: SPACE ----------------------------*/
130
dfield = dtuple_get_nth_field(entry, 7/*SPACE*/);
110
dfield = dtuple_get_nth_field(entry, 7);
132
ptr = static_cast<unsigned char *>(mem_heap_alloc(heap, 4));
112
ptr = mem_heap_alloc(heap, 4);
133
113
mach_write_to_4(ptr, table->space);
135
115
dfield_set_data(dfield, ptr, 4);
141
/*****************************************************************//**
121
/*********************************************************************
142
122
Based on a table object, this function builds the entry to be inserted
143
in the SYS_COLUMNS system table.
144
@return the tuple which should be inserted */
123
in the SYS_COLUMNS system table. */
147
126
dict_create_sys_columns_tuple(
148
127
/*==========================*/
149
const dict_table_t* table, /*!< in: table */
150
ulint i, /*!< in: column number */
151
mem_heap_t* heap) /*!< in: memory heap from
152
which the memory for the built
153
tuple is allocated */
128
/* out: the tuple which should be inserted */
129
dict_table_t* table, /* in: table */
130
ulint i, /* in: column number */
131
mem_heap_t* heap) /* in: memory heap from which the memory for
132
the built tuple is allocated */
155
134
dict_table_t* sys_columns;
157
136
const dict_col_t* column;
158
137
dfield_t* dfield;
160
const char* col_name;
139
const char* col_name;
141
ut_ad(table && heap);
165
143
column = dict_table_get_nth_col(table, i);
171
149
dict_table_copy_types(entry, sys_columns);
173
151
/* 0: TABLE_ID -----------------------*/
174
dfield = dtuple_get_nth_field(entry, 0/*TABLE_ID*/);
152
dfield = dtuple_get_nth_field(entry, 0);
176
ptr = static_cast<unsigned char *>(mem_heap_alloc(heap, 8));
154
ptr = mem_heap_alloc(heap, 8);
177
155
mach_write_to_8(ptr, table->id);
179
157
dfield_set_data(dfield, ptr, 8);
180
158
/* 1: POS ----------------------------*/
181
dfield = dtuple_get_nth_field(entry, 1/*POS*/);
159
dfield = dtuple_get_nth_field(entry, 1);
183
ptr = static_cast<unsigned char *>(mem_heap_alloc(heap, 4));
161
ptr = mem_heap_alloc(heap, 4);
184
162
mach_write_to_4(ptr, i);
186
164
dfield_set_data(dfield, ptr, 4);
187
165
/* 4: NAME ---------------------------*/
188
dfield = dtuple_get_nth_field(entry, 2/*NAME*/);
166
dfield = dtuple_get_nth_field(entry, 2);
190
168
col_name = dict_table_get_col_name(table, i);
191
169
dfield_set_data(dfield, col_name, ut_strlen(col_name));
192
170
/* 5: MTYPE --------------------------*/
193
dfield = dtuple_get_nth_field(entry, 3/*MTYPE*/);
171
dfield = dtuple_get_nth_field(entry, 3);
195
ptr = static_cast<unsigned char *>(mem_heap_alloc(heap, 4));
173
ptr = mem_heap_alloc(heap, 4);
196
174
mach_write_to_4(ptr, column->mtype);
198
176
dfield_set_data(dfield, ptr, 4);
199
177
/* 6: PRTYPE -------------------------*/
200
dfield = dtuple_get_nth_field(entry, 4/*PRTYPE*/);
178
dfield = dtuple_get_nth_field(entry, 4);
202
ptr = static_cast<unsigned char *>(mem_heap_alloc(heap, 4));
180
ptr = mem_heap_alloc(heap, 4);
203
181
mach_write_to_4(ptr, column->prtype);
205
183
dfield_set_data(dfield, ptr, 4);
206
184
/* 7: LEN ----------------------------*/
207
dfield = dtuple_get_nth_field(entry, 5/*LEN*/);
185
dfield = dtuple_get_nth_field(entry, 5);
209
ptr = static_cast<unsigned char *>(mem_heap_alloc(heap, 4));
187
ptr = mem_heap_alloc(heap, 4);
210
188
mach_write_to_4(ptr, column->len);
212
190
dfield_set_data(dfield, ptr, 4);
213
191
/* 8: PREC ---------------------------*/
214
dfield = dtuple_get_nth_field(entry, 6/*PREC*/);
192
dfield = dtuple_get_nth_field(entry, 6);
216
ptr = static_cast<unsigned char *>(mem_heap_alloc(heap, 4));
194
ptr = mem_heap_alloc(heap, 4);
217
195
mach_write_to_4(ptr, 0/* unused */);
219
197
dfield_set_data(dfield, ptr, 4);
225
/***************************************************************//**
226
Builds a table definition to insert.
227
@return DB_SUCCESS or error code */
203
/*******************************************************************
204
Builds a table definition to insert. */
230
207
dict_build_table_def_step(
231
208
/*======================*/
232
que_thr_t* thr, /*!< in: query thread */
233
tab_node_t* node) /*!< in: table create node */
209
/* out: DB_SUCCESS or error code */
210
que_thr_t* thr, /* in: query thread */
211
tab_node_t* node) /* in: table create node */
235
213
dict_table_t* table;
239
216
const char* path_or_name;
243
ibool file_per_table;
245
220
ut_ad(mutex_own(&(dict_sys->mutex)));
247
222
table = node->table;
249
/* Cache the global variable "srv_file_per_table" to
250
a local variable before using it. Please note
251
"srv_file_per_table" is not under dict_sys mutex
252
protection, and could be changed while executing
253
this function. So better to cache the current value
254
to a local variable, and all future reference to
255
"srv_file_per_table" should use this local variable. */
256
file_per_table = srv_file_per_table;
258
dict_hdr_get_new_id(&table->id, NULL, NULL);
224
table->id = dict_hdr_get_new_id(DICT_HDR_TABLE_ID);
260
226
thr_get_trx(thr)->table_id = table->id;
262
if (file_per_table) {
263
/* Get a new space id if srv_file_per_table is set */
264
dict_hdr_get_new_id(NULL, NULL, &space);
266
if (UNIV_UNLIKELY(space == ULINT_UNDEFINED)) {
228
if (srv_file_per_table) {
270
229
/* We create a new single-table tablespace for the table.
271
230
We initially let it be 4 pages:
272
231
- page 0 is the fsp header and an extent descriptor page,
337
297
return(DB_SUCCESS);
340
/*****************************************************************//**
300
/*********************************************************************
341
301
Based on an index object, this function builds the entry to be inserted
342
in the SYS_INDEXES system table.
343
@return the tuple which should be inserted */
302
in the SYS_INDEXES system table. */
346
305
dict_create_sys_indexes_tuple(
347
306
/*==========================*/
348
const dict_index_t* index, /*!< in: index */
349
mem_heap_t* heap) /*!< in: memory heap from
350
which the memory for the built
351
tuple is allocated */
307
/* out: the tuple which should be inserted */
308
dict_index_t* index, /* in: index */
309
mem_heap_t* heap) /* in: memory heap from which the memory for
310
the built tuple is allocated */
353
312
dict_table_t* sys_indexes;
354
313
dict_table_t* table;
369
327
dict_table_copy_types(entry, sys_indexes);
371
329
/* 0: TABLE_ID -----------------------*/
372
dfield = dtuple_get_nth_field(entry, 0/*TABLE_ID*/);
330
dfield = dtuple_get_nth_field(entry, 0);
374
ptr = static_cast<unsigned char *>(mem_heap_alloc(heap, 8));
332
ptr = mem_heap_alloc(heap, 8);
375
333
mach_write_to_8(ptr, table->id);
377
335
dfield_set_data(dfield, ptr, 8);
378
336
/* 1: ID ----------------------------*/
379
dfield = dtuple_get_nth_field(entry, 1/*ID*/);
337
dfield = dtuple_get_nth_field(entry, 1);
381
ptr = static_cast<unsigned char *>(mem_heap_alloc(heap, 8));
339
ptr = mem_heap_alloc(heap, 8);
382
340
mach_write_to_8(ptr, index->id);
384
342
dfield_set_data(dfield, ptr, 8);
385
343
/* 4: NAME --------------------------*/
386
dfield = dtuple_get_nth_field(entry, 2/*NAME*/);
344
dfield = dtuple_get_nth_field(entry, 2);
388
346
dfield_set_data(dfield, index->name, ut_strlen(index->name));
389
347
/* 5: N_FIELDS ----------------------*/
390
dfield = dtuple_get_nth_field(entry, 3/*N_FIELDS*/);
348
dfield = dtuple_get_nth_field(entry, 3);
392
ptr = static_cast<unsigned char *>(mem_heap_alloc(heap, 4));
350
ptr = mem_heap_alloc(heap, 4);
393
351
mach_write_to_4(ptr, index->n_fields);
395
353
dfield_set_data(dfield, ptr, 4);
396
354
/* 6: TYPE --------------------------*/
397
dfield = dtuple_get_nth_field(entry, 4/*TYPE*/);
355
dfield = dtuple_get_nth_field(entry, 4);
399
ptr = static_cast<unsigned char *>(mem_heap_alloc(heap, 4));
357
ptr = mem_heap_alloc(heap, 4);
400
358
mach_write_to_4(ptr, index->type);
402
360
dfield_set_data(dfield, ptr, 4);
432
/*****************************************************************//**
390
/*********************************************************************
433
391
Based on an index object, this function builds the entry to be inserted
434
in the SYS_FIELDS system table.
435
@return the tuple which should be inserted */
392
in the SYS_FIELDS system table. */
438
395
dict_create_sys_fields_tuple(
439
396
/*=========================*/
440
const dict_index_t* index, /*!< in: index */
441
ulint i, /*!< in: field number */
442
mem_heap_t* heap) /*!< in: memory heap from
443
which the memory for the built
444
tuple is allocated */
397
/* out: the tuple which should be inserted */
398
dict_index_t* index, /* in: index */
399
ulint i, /* in: field number */
400
mem_heap_t* heap) /* in: memory heap from which the memory for
401
the built tuple is allocated */
446
403
dict_table_t* sys_fields;
470
426
dict_table_copy_types(entry, sys_fields);
472
428
/* 0: INDEX_ID -----------------------*/
473
dfield = dtuple_get_nth_field(entry, 0/*INDEX_ID*/);
429
dfield = dtuple_get_nth_field(entry, 0);
475
ptr = static_cast<unsigned char *>(mem_heap_alloc(heap, 8));
431
ptr = mem_heap_alloc(heap, 8);
476
432
mach_write_to_8(ptr, index->id);
478
434
dfield_set_data(dfield, ptr, 8);
479
435
/* 1: POS + PREFIX LENGTH ----------------------------*/
481
dfield = dtuple_get_nth_field(entry, 1/*POS*/);
437
dfield = dtuple_get_nth_field(entry, 1);
483
ptr = static_cast<unsigned char *>(mem_heap_alloc(heap, 4));
439
ptr = mem_heap_alloc(heap, 4);
485
441
if (index_contains_column_prefix_field) {
486
442
/* If there are column prefix fields in the index, then
510
/*****************************************************************//**
466
/*********************************************************************
511
467
Creates the tuple with which the index entry is searched for writing the index
512
tree root page number, if such a tree is created.
513
@return the tuple for search */
468
tree root page number, if such a tree is created. */
516
471
dict_create_search_tuple(
517
472
/*=====================*/
518
const dtuple_t* tuple, /*!< in: the tuple inserted in the SYS_INDEXES
473
/* out: the tuple for search */
474
const dtuple_t* tuple, /* in: the tuple inserted in the SYS_INDEXES
520
mem_heap_t* heap) /*!< in: memory heap from which the memory for
476
mem_heap_t* heap) /* in: memory heap from which the memory for
521
477
the built tuple is allocated */
523
479
dtuple_t* search_tuple;
739
/*******************************************************************//**
740
Truncates the index tree associated with a row in SYS_INDEXES table.
741
@return new root page number, or FIL_NULL on failure */
697
/***********************************************************************
698
Truncates the index tree associated with a row in SYS_INDEXES table. */
744
701
dict_truncate_index_tree(
745
702
/*=====================*/
746
dict_table_t* table, /*!< in: the table the index belongs to */
747
ulint space, /*!< in: 0=truncate,
703
/* out: new root page number, or
704
FIL_NULL on failure */
705
dict_table_t* table, /* in: the table the index belongs to */
706
ulint space, /* in: 0=truncate,
748
707
nonzero=create the index tree in the
749
708
given tablespace */
750
btr_pcur_t* pcur, /*!< in/out: persistent cursor pointing to
709
btr_pcur_t* pcur, /* in/out: persistent cursor pointing to
751
710
record in the clustered index of
752
711
SYS_INDEXES table. The cursor may be
753
712
repositioned in this call. */
754
mtr_t* mtr) /*!< in: mtr having the latch
713
mtr_t* mtr) /* in: mtr having the latch
755
714
on the record page. The mtr may be
756
715
committed and restarted in this call. */
863
822
ut_print_timestamp(stderr);
865
" InnoDB: Index %llu of table %s is missing\n"
824
" InnoDB: Index %lu %lu of table %s is missing\n"
866
825
"InnoDB: from the data dictionary during TRUNCATE!\n",
826
ut_dulint_get_high(index_id),
827
ut_dulint_get_low(index_id),
870
830
return(FIL_NULL);
873
/*********************************************************************//**
874
Creates a table create graph.
875
@return own: table create node */
833
/*************************************************************************
834
Creates a table create graph. */
878
837
tab_create_graph_create(
879
838
/*====================*/
880
dict_table_t* table, /*!< in: table to create, built as a memory data
839
/* out, own: table create node */
840
dict_table_t* table, /* in: table to create, built as a memory data
882
mem_heap_t* heap) /*!< in: heap where created */
842
mem_heap_t* heap) /* in: heap where created */
884
844
tab_node_t* node;
886
node = static_cast<tab_node_t *>(mem_heap_alloc(heap, sizeof(tab_node_t)));
846
node = mem_heap_alloc(heap, sizeof(tab_node_t));
888
848
node->common.type = QUE_NODE_CREATE_TABLE;
909
/*********************************************************************//**
910
Creates an index create graph.
911
@return own: index create node */
869
/*************************************************************************
870
Creates an index create graph. */
914
873
ind_create_graph_create(
915
874
/*====================*/
916
dict_index_t* index, /*!< in: index to create, built as a memory data
875
/* out, own: index create node */
876
dict_index_t* index, /* in: index to create, built as a memory data
918
mem_heap_t* heap) /*!< in: heap where created */
878
mem_heap_t* heap) /* in: heap where created */
920
880
ind_node_t* node;
922
node = static_cast<ind_node_t *>(mem_heap_alloc(heap, sizeof(ind_node_t)));
882
node = mem_heap_alloc(heap, sizeof(ind_node_t));
924
884
node->common.type = QUE_NODE_CREATE_INDEX;
1308
/****************************************************************//**
1309
Evaluate the given foreign key SQL statement.
1310
@return error code or DB_SUCCESS */
1265
/********************************************************************
1266
Evaluate the given foreign key SQL statement. */
1313
1269
dict_foreign_eval_sql(
1314
1270
/*==================*/
1315
pars_info_t* info, /*!< in: info struct, or NULL */
1316
const char* sql, /*!< in: SQL string to evaluate */
1317
dict_table_t* table, /*!< in: table */
1318
dict_foreign_t* foreign,/*!< in: foreign */
1319
trx_t* trx) /*!< in: transaction */
1271
/* out: error code or DB_SUCCESS */
1272
pars_info_t* info, /* in: info struct, or NULL */
1273
const char* sql, /* in: SQL string to evaluate */
1274
dict_table_t* table, /* in: table */
1275
dict_foreign_t* foreign,/* in: foreign */
1276
trx_t* trx) /* in: transaction */
1322
1279
FILE* ef = dict_foreign_err_file;
1370
1327
return(DB_SUCCESS);
1373
/********************************************************************//**
1330
/************************************************************************
1374
1331
Add a single foreign key field definition to the data dictionary tables in
1376
@return error code or DB_SUCCESS */
1379
1335
dict_create_add_foreign_field_to_dictionary(
1380
1336
/*========================================*/
1381
ulint field_nr, /*!< in: foreign field number */
1382
dict_table_t* table, /*!< in: table */
1383
dict_foreign_t* foreign, /*!< in: foreign */
1384
trx_t* trx) /*!< in: transaction */
1337
/* out: error code or DB_SUCCESS */
1338
ulint field_nr, /* in: foreign field number */
1339
dict_table_t* table, /* in: table */
1340
dict_foreign_t* foreign, /* in: foreign */
1341
trx_t* trx) /* in: transaction */
1386
1343
pars_info_t* info = pars_info_create();
1405
1362
table, foreign, trx));
1408
/********************************************************************//**
1365
/************************************************************************
1409
1366
Add a single foreign key definition to the data dictionary tables in the
1410
1367
database. We also generate names to constraints that were not named by the
1411
1368
user. A generated constraint has a name of the format
1412
1369
databasename/tablename_ibfk_<number>, where the numbers start from 1, and
1413
1370
are given locally for this table, that is, the number is not global, as in
1414
the old format constraints < 4.0.18 it used to be.
1415
@return error code or DB_SUCCESS */
1371
the old format constraints < 4.0.18 it used to be. */
1418
1374
dict_create_add_foreign_to_dictionary(
1419
1375
/*==================================*/
1420
ulint* id_nr, /*!< in/out: number to use in id generation;
1376
/* out: error code or DB_SUCCESS */
1377
ulint* id_nr, /* in/out: number to use in id generation;
1421
1378
incremented if used */
1422
dict_table_t* table, /*!< in: table */
1423
dict_foreign_t* foreign,/*!< in: foreign */
1424
trx_t* trx) /*!< in: transaction */
1379
dict_table_t* table, /* in: table */
1380
dict_foreign_t* foreign,/* in: foreign */
1381
trx_t* trx) /* in: transaction */
1483
/********************************************************************//**
1484
Adds foreign key definitions to data dictionary tables in the database.
1485
@return error code or DB_SUCCESS */
1440
/************************************************************************
1441
Adds foreign key definitions to data dictionary tables in the database. */
1488
1444
dict_create_add_foreigns_to_dictionary(
1489
1445
/*===================================*/
1490
ulint start_id,/*!< in: if we are actually doing ALTER TABLE
1446
/* out: error code or DB_SUCCESS */
1447
ulint start_id,/* in: if we are actually doing ALTER TABLE
1491
1448
ADD CONSTRAINT, we want to generate constraint
1492
1449
numbers which are bigger than in the table so
1493
1450
far; we number the constraints from